From 064f602b1a0e25a694f1d34fb9e37be6bfdab549 Mon Sep 17 00:00:00 2001 From: Saturneic Date: Thu, 25 Oct 2018 23:33:07 +0800 Subject: [PATCH] Add. --- .idea/dataSources.xml | 14 + .idea/misc.xml | 7 + .idea/modules.xml | 8 + .idea/untitled.iml | 16 + .idea/vcs.xml | 6 + bin/activate | 76 + bin/activate.csh | 37 + bin/activate.fish | 75 + bin/easy_install | 12 + bin/easy_install-3.7 | 12 + bin/pip | 12 + bin/pip3 | 12 + bin/pip3.7 | 12 + bin/python | Bin 0 -> 13620 bytes bin/python3 | Bin 0 -> 13620 bytes lib/python3.7/site-packages/easy-install.pth | 2 + .../pip-10.0.1-py3.7.egg/EGG-INFO/PKG-INFO | 69 + .../pip-10.0.1-py3.7.egg/EGG-INFO/SOURCES.txt | 347 + .../EGG-INFO/dependency_links.txt | 1 + .../EGG-INFO/entry_points.txt | 5 + .../EGG-INFO/not-zip-safe | 1 + .../EGG-INFO/requires.txt | 8 + .../EGG-INFO/top_level.txt | 1 + .../pip-10.0.1-py3.7.egg/pip/__init__.py | 1 + .../pip-10.0.1-py3.7.egg/pip/__main__.py | 19 + .../pip/_internal/__init__.py | 246 + .../pip/_internal/basecommand.py | 373 + .../pip/_internal/baseparser.py | 240 + .../pip/_internal/build_env.py | 92 + .../pip/_internal/cache.py | 202 + .../pip/_internal/cmdoptions.py | 609 + .../pip/_internal/commands/__init__.py | 79 + .../pip/_internal/commands/check.py | 42 + .../pip/_internal/commands/completion.py | 94 + .../pip/_internal/commands/configuration.py | 227 + .../pip/_internal/commands/download.py | 233 + .../pip/_internal/commands/freeze.py | 96 + .../pip/_internal/commands/hash.py | 57 + .../pip/_internal/commands/help.py | 36 + .../pip/_internal/commands/install.py | 502 + .../pip/_internal/commands/list.py | 343 + .../pip/_internal/commands/search.py | 135 + .../pip/_internal/commands/show.py | 164 + .../pip/_internal/commands/uninstall.py | 71 + .../pip/_internal/commands/wheel.py | 179 + .../pip/_internal/compat.py | 235 + .../pip/_internal/configuration.py | 378 + .../pip/_internal/download.py | 922 + .../pip/_internal/exceptions.py | 249 + .../pip/_internal/index.py | 1117 + .../pip/_internal/locations.py | 194 + .../pip/_internal/models/__init__.py | 4 + .../pip/_internal/models/index.py | 15 + .../pip/_internal/operations/__init__.py | 0 .../pip/_internal/operations/check.py | 106 + .../pip/_internal/operations/freeze.py | 252 + .../pip/_internal/operations/prepare.py | 380 + .../pip/_internal/pep425tags.py | 317 + .../pip/_internal/req/__init__.py | 69 + .../pip/_internal/req/req_file.py | 338 + .../pip/_internal/req/req_install.py | 1115 + .../pip/_internal/req/req_set.py | 164 + .../pip/_internal/req/req_uninstall.py | 455 + .../pip/_internal/resolve.py | 354 + .../pip/_internal/status_codes.py | 8 + .../pip/_internal/utils/__init__.py | 0 .../pip/_internal/utils/appdirs.py | 258 + .../pip/_internal/utils/deprecation.py | 77 + .../pip/_internal/utils/encoding.py | 33 + .../pip/_internal/utils/filesystem.py | 28 + .../pip/_internal/utils/glibc.py | 84 + .../pip/_internal/utils/hashes.py | 94 + .../pip/_internal/utils/logging.py | 132 + .../pip/_internal/utils/misc.py | 851 + .../pip/_internal/utils/outdated.py | 163 + .../pip/_internal/utils/packaging.py | 70 + .../pip/_internal/utils/setuptools_build.py | 8 + .../pip/_internal/utils/temp_dir.py | 82 + .../pip/_internal/utils/typing.py | 29 + .../pip/_internal/utils/ui.py | 421 + .../pip/_internal/vcs/__init__.py | 471 + .../pip/_internal/vcs/bazaar.py | 113 + .../pip/_internal/vcs/git.py | 311 + .../pip/_internal/vcs/mercurial.py | 105 + .../pip/_internal/vcs/subversion.py | 271 + .../pip/_internal/wheel.py | 817 + .../pip/_vendor/__init__.py | 109 + .../pip/_vendor/appdirs.py | 604 + .../pip/_vendor/cachecontrol/__init__.py | 11 + .../pip/_vendor/cachecontrol/_cmd.py | 60 + .../pip/_vendor/cachecontrol/adapter.py | 134 + .../pip/_vendor/cachecontrol/cache.py | 39 + .../_vendor/cachecontrol/caches/__init__.py | 2 + .../_vendor/cachecontrol/caches/file_cache.py | 133 + .../cachecontrol/caches/redis_cache.py | 43 + .../pip/_vendor/cachecontrol/compat.py | 29 + .../pip/_vendor/cachecontrol/controller.py | 373 + .../pip/_vendor/cachecontrol/filewrapper.py | 78 + .../pip/_vendor/cachecontrol/heuristics.py | 138 + .../pip/_vendor/cachecontrol/serialize.py | 194 + .../pip/_vendor/cachecontrol/wrapper.py | 27 + .../pip/_vendor/certifi/__init__.py | 3 + .../pip/_vendor/certifi/__main__.py | 2 + .../pip/_vendor/certifi/cacert.pem | 4433 +++ .../pip/_vendor/certifi/core.py | 37 + .../pip/_vendor/chardet/__init__.py | 39 + .../pip/_vendor/chardet/big5freq.py | 386 + .../pip/_vendor/chardet/big5prober.py | 47 + .../pip/_vendor/chardet/chardistribution.py | 233 + .../pip/_vendor/chardet/charsetgroupprober.py | 106 + .../pip/_vendor/chardet/charsetprober.py | 145 + .../pip/_vendor/chardet/cli/__init__.py | 1 + .../pip/_vendor/chardet/cli/chardetect.py | 85 + .../pip/_vendor/chardet/codingstatemachine.py | 88 + .../pip/_vendor/chardet/compat.py | 34 + .../pip/_vendor/chardet/cp949prober.py | 49 + .../pip/_vendor/chardet/enums.py | 76 + .../pip/_vendor/chardet/escprober.py | 101 + .../pip/_vendor/chardet/escsm.py | 246 + .../pip/_vendor/chardet/eucjpprober.py | 92 + .../pip/_vendor/chardet/euckrfreq.py | 195 + .../pip/_vendor/chardet/euckrprober.py | 47 + .../pip/_vendor/chardet/euctwfreq.py | 387 + .../pip/_vendor/chardet/euctwprober.py | 46 + .../pip/_vendor/chardet/gb2312freq.py | 283 + .../pip/_vendor/chardet/gb2312prober.py | 46 + .../pip/_vendor/chardet/hebrewprober.py | 292 + .../pip/_vendor/chardet/jisfreq.py | 325 + .../pip/_vendor/chardet/jpcntx.py | 233 + .../pip/_vendor/chardet/langbulgarianmodel.py | 228 + .../pip/_vendor/chardet/langcyrillicmodel.py | 333 + .../pip/_vendor/chardet/langgreekmodel.py | 225 + .../pip/_vendor/chardet/langhebrewmodel.py | 200 + .../pip/_vendor/chardet/langhungarianmodel.py | 225 + .../pip/_vendor/chardet/langthaimodel.py | 199 + .../pip/_vendor/chardet/langturkishmodel.py | 193 + .../pip/_vendor/chardet/latin1prober.py | 145 + .../pip/_vendor/chardet/mbcharsetprober.py | 91 + .../pip/_vendor/chardet/mbcsgroupprober.py | 54 + .../pip/_vendor/chardet/mbcssm.py | 572 + .../pip/_vendor/chardet/sbcharsetprober.py | 132 + .../pip/_vendor/chardet/sbcsgroupprober.py | 73 + .../pip/_vendor/chardet/sjisprober.py | 92 + .../pip/_vendor/chardet/universaldetector.py | 286 + .../pip/_vendor/chardet/utf8prober.py | 82 + .../pip/_vendor/chardet/version.py | 9 + .../pip/_vendor/colorama/__init__.py | 7 + .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansitowin32.py | 236 + .../pip/_vendor/colorama/initialise.py | 82 + .../pip/_vendor/colorama/win32.py | 156 + .../pip/_vendor/colorama/winterm.py | 162 + .../pip/_vendor/distlib/__init__.py | 23 + .../pip/_vendor/distlib/_backport/__init__.py | 6 + .../pip/_vendor/distlib/_backport/misc.py | 41 + .../pip/_vendor/distlib/_backport/shutil.py | 761 + .../_vendor/distlib/_backport/sysconfig.cfg | 84 + .../_vendor/distlib/_backport/sysconfig.py | 788 + .../pip/_vendor/distlib/_backport/tarfile.py | 2607 ++ .../pip/_vendor/distlib/compat.py | 1120 + .../pip/_vendor/distlib/database.py | 1336 + .../pip/_vendor/distlib/index.py | 516 + .../pip/_vendor/distlib/locators.py | 1292 + .../pip/_vendor/distlib/manifest.py | 393 + .../pip/_vendor/distlib/markers.py | 131 + .../pip/_vendor/distlib/metadata.py | 1091 + .../pip/_vendor/distlib/resources.py | 355 + .../pip/_vendor/distlib/scripts.py | 415 + .../pip/_vendor/distlib/t32.exe | Bin 0 -> 92672 bytes .../pip/_vendor/distlib/t64.exe | Bin 0 -> 102400 bytes .../pip/_vendor/distlib/util.py | 1755 ++ .../pip/_vendor/distlib/version.py | 736 + .../pip/_vendor/distlib/w32.exe | Bin 0 -> 89088 bytes .../pip/_vendor/distlib/w64.exe | Bin 0 -> 99328 bytes .../pip/_vendor/distlib/wheel.py | 984 + .../pip/_vendor/distro.py | 1104 + .../pip/_vendor/html5lib/__init__.py | 35 + .../pip/_vendor/html5lib/_ihatexml.py | 288 + .../pip/_vendor/html5lib/_inputstream.py | 923 + .../pip/_vendor/html5lib/_tokenizer.py | 1721 ++ .../pip/_vendor/html5lib/_trie/__init__.py | 14 + .../pip/_vendor/html5lib/_trie/_base.py | 37 + .../pip/_vendor/html5lib/_trie/datrie.py | 44 + .../pip/_vendor/html5lib/_trie/py.py | 67 + .../pip/_vendor/html5lib/_utils.py | 124 + .../pip/_vendor/html5lib/constants.py | 2947 ++ .../pip/_vendor/html5lib/filters/__init__.py | 0 .../filters/alphabeticalattributes.py | 29 + .../pip/_vendor/html5lib/filters/base.py | 12 + .../html5lib/filters/inject_meta_charset.py | 73 + .../pip/_vendor/html5lib/filters/lint.py | 93 + .../_vendor/html5lib/filters/optionaltags.py | 207 + .../pip/_vendor/html5lib/filters/sanitizer.py | 896 + .../_vendor/html5lib/filters/whitespace.py | 38 + .../pip/_vendor/html5lib/html5parser.py | 2791 ++ .../pip/_vendor/html5lib/serializer.py | 409 + .../_vendor/html5lib/treeadapters/__init__.py | 30 + .../_vendor/html5lib/treeadapters/genshi.py | 54 + .../pip/_vendor/html5lib/treeadapters/sax.py | 50 + .../_vendor/html5lib/treebuilders/__init__.py | 88 + .../pip/_vendor/html5lib/treebuilders/base.py | 417 + .../pip/_vendor/html5lib/treebuilders/dom.py | 236 + .../_vendor/html5lib/treebuilders/etree.py | 340 + .../html5lib/treebuilders/etree_lxml.py | 366 + .../_vendor/html5lib/treewalkers/__init__.py | 154 + .../pip/_vendor/html5lib/treewalkers/base.py | 252 + .../pip/_vendor/html5lib/treewalkers/dom.py | 43 + .../pip/_vendor/html5lib/treewalkers/etree.py | 130 + .../html5lib/treewalkers/etree_lxml.py | 213 + .../_vendor/html5lib/treewalkers/genshi.py | 69 + .../pip/_vendor/idna/__init__.py | 2 + .../pip/_vendor/idna/codec.py | 118 + .../pip/_vendor/idna/compat.py | 12 + .../pip/_vendor/idna/core.py | 387 + .../pip/_vendor/idna/idnadata.py | 1585 + .../pip/_vendor/idna/intranges.py | 53 + .../pip/_vendor/idna/package_data.py | 2 + .../pip/_vendor/idna/uts46data.py | 7634 +++++ .../pip/_vendor/ipaddress.py | 2419 ++ .../pip/_vendor/lockfile/__init__.py | 347 + .../pip/_vendor/lockfile/linklockfile.py | 73 + .../pip/_vendor/lockfile/mkdirlockfile.py | 84 + .../pip/_vendor/lockfile/pidlockfile.py | 190 + .../pip/_vendor/lockfile/sqlitelockfile.py | 156 + .../pip/_vendor/lockfile/symlinklockfile.py | 70 + .../pip/_vendor/msgpack/__init__.py | 66 + .../pip/_vendor/msgpack/_version.py | 1 + .../pip/_vendor/msgpack/exceptions.py | 41 + .../pip/_vendor/msgpack/fallback.py | 977 + .../pip/_vendor/packaging/__about__.py | 21 + .../pip/_vendor/packaging/__init__.py | 14 + .../pip/_vendor/packaging/_compat.py | 30 + .../pip/_vendor/packaging/_structures.py | 70 + .../pip/_vendor/packaging/markers.py | 301 + .../pip/_vendor/packaging/requirements.py | 130 + .../pip/_vendor/packaging/specifiers.py | 774 + .../pip/_vendor/packaging/utils.py | 63 + .../pip/_vendor/packaging/version.py | 441 + .../pip/_vendor/pkg_resources/__init__.py | 3125 ++ .../pip/_vendor/pkg_resources/py31compat.py | 22 + .../pip/_vendor/progress/__init__.py | 127 + .../pip/_vendor/progress/bar.py | 88 + .../pip/_vendor/progress/counter.py | 48 + .../pip/_vendor/progress/helpers.py | 91 + .../pip/_vendor/progress/spinner.py | 44 + .../pip/_vendor/pyparsing.py | 5720 ++++ .../pip/_vendor/pytoml/__init__.py | 3 + .../pip/_vendor/pytoml/core.py | 13 + .../pip/_vendor/pytoml/parser.py | 374 + .../pip/_vendor/pytoml/writer.py | 127 + .../pip/_vendor/requests/__init__.py | 123 + .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 42 + .../pip/_vendor/requests/adapters.py | 525 + .../pip/_vendor/requests/api.py | 152 + .../pip/_vendor/requests/auth.py | 293 + .../pip/_vendor/requests/certs.py | 18 + .../pip/_vendor/requests/compat.py | 73 + .../pip/_vendor/requests/cookies.py | 542 + .../pip/_vendor/requests/exceptions.py | 122 + .../pip/_vendor/requests/help.py | 120 + .../pip/_vendor/requests/hooks.py | 34 + .../pip/_vendor/requests/models.py | 948 + .../pip/_vendor/requests/packages.py | 16 + .../pip/_vendor/requests/sessions.py | 737 + .../pip/_vendor/requests/status_codes.py | 91 + .../pip/_vendor/requests/structures.py | 105 + .../pip/_vendor/requests/utils.py | 904 + .../pip/_vendor/retrying.py | 267 + .../pip-10.0.1-py3.7.egg/pip/_vendor/six.py | 891 + .../pip/_vendor/urllib3/__init__.py | 97 + .../pip/_vendor/urllib3/_collections.py | 319 + .../pip/_vendor/urllib3/connection.py | 373 + .../pip/_vendor/urllib3/connectionpool.py | 905 + .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../contrib/_securetransport/__init__.py | 0 .../contrib/_securetransport/bindings.py | 593 + .../contrib/_securetransport/low_level.py | 343 + .../pip/_vendor/urllib3/contrib/appengine.py | 296 + .../pip/_vendor/urllib3/contrib/ntlmpool.py | 112 + .../pip/_vendor/urllib3/contrib/pyopenssl.py | 455 + .../urllib3/contrib/securetransport.py | 810 + .../pip/_vendor/urllib3/contrib/socks.py | 188 + .../pip/_vendor/urllib3/exceptions.py | 246 + .../pip/_vendor/urllib3/fields.py | 178 + .../pip/_vendor/urllib3/filepost.py | 94 + .../pip/_vendor/urllib3/packages/__init__.py | 5 + .../urllib3/packages/backports/__init__.py | 0 .../urllib3/packages/backports/makefile.py | 53 + .../_vendor/urllib3/packages/ordered_dict.py | 259 + .../pip/_vendor/urllib3/packages/six.py | 868 + .../packages/ssl_match_hostname/__init__.py | 19 + .../ssl_match_hostname/_implementation.py | 157 + .../pip/_vendor/urllib3/poolmanager.py | 440 + .../pip/_vendor/urllib3/request.py | 148 + .../pip/_vendor/urllib3/response.py | 626 + .../pip/_vendor/urllib3/util/__init__.py | 54 + .../pip/_vendor/urllib3/util/connection.py | 130 + .../pip/_vendor/urllib3/util/request.py | 118 + .../pip/_vendor/urllib3/util/response.py | 81 + .../pip/_vendor/urllib3/util/retry.py | 401 + .../pip/_vendor/urllib3/util/selectors.py | 581 + .../pip/_vendor/urllib3/util/ssl_.py | 341 + .../pip/_vendor/urllib3/util/timeout.py | 242 + .../pip/_vendor/urllib3/util/url.py | 230 + .../pip/_vendor/urllib3/util/wait.py | 40 + .../pip/_vendor/webencodings/__init__.py | 342 + .../pip/_vendor/webencodings/labels.py | 231 + .../pip/_vendor/webencodings/mklabels.py | 59 + .../pip/_vendor/webencodings/tests.py | 153 + .../_vendor/webencodings/x_user_defined.py | 325 + .../site-packages/setuptools-39.1.0-py3.7.egg | Bin 0 -> 563197 bytes lib/python3.7/site-packages/setuptools.pth | 1 + pyvenv.cfg | 3 + web2py/CHANGELOG | 1726 ++ web2py/LICENSE | 118 + web2py/MANIFEST.in | 1 + web2py/README.markdown | 100 + web2py/VERSION | 1 + web2py/anyserver.py | 365 + web2py/applications/SP/ABOUT | 2 + web2py/applications/SP/LICENSE | 4 + web2py/applications/SP/__init__.py | 1 + .../applications/SP/controllers/appadmin.py | 863 + web2py/applications/SP/controllers/default.py | 132 + web2py/applications/SP/cron/crontab | 1 + web2py/applications/SP/cron/crontab.example | 1 + ...9d15150d7109e5f7ab36744a5b7_auth_cas.table | Bin 0 -> 684 bytes ...15150d7109e5f7ab36744a5b7_auth_event.table | Bin 0 -> 694 bytes ...15150d7109e5f7ab36744a5b7_auth_group.table | Bin 0 -> 361 bytes ...d7109e5f7ab36744a5b7_auth_membership.table | Bin 0 -> 492 bytes ...d7109e5f7ab36744a5b7_auth_permission.table | Bin 0 -> 601 bytes ...d15150d7109e5f7ab36744a5b7_auth_user.table | Bin 0 -> 1160 bytes ...181b96a99be45f5a23f4277867ce_history.table | Bin 0 -> 545 bytes ...b87181b96a99be45f5a23f4277867ce_task.table | Bin 0 -> 1167 bytes ...1b96a99be45f5a23f4277867ce_user_info.table | Bin 0 -> 645 bytes web2py/applications/SP/databases/sql.log | 3696 +++ web2py/applications/SP/databases/storage.db | Bin 0 -> 20480 bytes .../applications/SP/databases/storage.sqlite | Bin 0 -> 40960 bytes ...19-16.eb57736d-d461-4d86-8577-c7454f82f56b | Bin 0 -> 60558 bytes ...54-12.04660296-7ce3-4dc0-ba16-8b688a41df11 | Bin 0 -> 38394 bytes ...54-21.5c142673-7f02-4f59-becd-f8a8458197b8 | Bin 0 -> 38394 bytes ...59-27.f2e76b1c-d22b-469f-a693-39b6af0b0fcc | Bin 0 -> 40135 bytes ...01-43.8f7a6d8f-112e-49d0-b426-5391c93f8986 | Bin 0 -> 41287 bytes ...02-44.e5d30aa7-20da-4772-b99b-9c0f6fef9a98 | Bin 0 -> 38737 bytes ...04-32.75533ba0-3cde-4ff1-8c00-9bbb2d28d8c8 | Bin 0 -> 38729 bytes ...36-18.ffba9911-051f-4f00-8da7-a20a9d5a754b | Bin 0 -> 1696 bytes ...36-24.36e7b540-e50e-4572-a869-d16cab440b1d | Bin 0 -> 1696 bytes ...04-11.b47795e9-b7d8-46a9-ae91-efc4733dca39 | Bin 0 -> 44055 bytes ...27-29.a5c546a7-8774-4128-a2ae-519ed5135e08 | Bin 0 -> 42290 bytes ...28-35.6fcf7282-da2c-4ef5-a851-7a8615d2f238 | Bin 0 -> 49293 bytes ...28-41.f7e5dabb-dc3e-4608-9610-42173d36f15d | Bin 0 -> 49293 bytes ...28-42.556f96b6-7809-4d22-826f-b68d99f4657b | Bin 0 -> 49293 bytes ...43-49.91a5a50d-8533-4e3f-9930-9752252ca014 | Bin 0 -> 57383 bytes ...44-13.f096514b-1984-4004-a4c7-7357441b2e56 | Bin 0 -> 55247 bytes ...44-24.8b339ad9-121a-463b-bb42-ab39db214d4b | Bin 0 -> 55239 bytes ...44-34.64fe6b5c-294f-4773-9d30-846867a15716 | Bin 0 -> 75882 bytes ...45-14.00ff237f-e9cc-45de-841a-06797fb7be10 | Bin 0 -> 56669 bytes ...45-14.fd8a6a99-18e3-4527-aaca-41237dadadfc | Bin 0 -> 56669 bytes ...46-48.4c0a2f29-52b9-4bc3-977e-1c0a9ee7fbef | Bin 0 -> 54897 bytes ...46-49.9783d6ab-e408-4aba-b29c-86a5d5ef3cc7 | Bin 0 -> 54897 bytes ...47-30.81ec9fb0-adcd-47f6-9fb5-4185913ed1bf | Bin 0 -> 56669 bytes ...47-53.ec10d560-0784-42a2-a0fe-bdc477d9543b | Bin 0 -> 56667 bytes ...48-08.f52ea77b-61b3-4c5f-afc8-f5c7d7fc7967 | Bin 0 -> 56667 bytes ...48-13.4c033311-3c6a-4e28-b43b-3ab4b0113751 | Bin 0 -> 56669 bytes ...49-21.e9d59f2b-d9ff-456e-b69f-6285fd2b696d | Bin 0 -> 56669 bytes ...49-22.57c52698-0974-40c8-8da5-11c393e0cb95 | Bin 0 -> 56669 bytes ...49-28.b53d2050-8e27-4d65-bdb0-4a1b51017307 | Bin 0 -> 56669 bytes ...49-52.7dd8f18e-944d-4deb-959c-ba8634d43f2a | Bin 0 -> 56666 bytes ...54-10.3fcf7b45-3ff9-4842-86ff-dad45dc4e871 | Bin 0 -> 48778 bytes ...55-46.19a4455f-b08f-4716-88e3-98cf0d4856eb | Bin 0 -> 48157 bytes ...55-58.09ce167e-6a0a-4e67-976d-f3dccbda7f15 | Bin 0 -> 47450 bytes ...56-46.7d37504e-8bed-49bc-9490-f5fd8fb3b2d6 | Bin 0 -> 49068 bytes ...59-23.cbd147d7-275d-49c8-bb62-f5710fa6b182 | Bin 0 -> 56669 bytes ...59-23.e413e2b4-dab0-46b3-b1bc-6ab7fd342cdc | Bin 0 -> 56669 bytes ...01-15.0cd2182e-7b39-417a-84a8-250066cf9933 | Bin 0 -> 39573 bytes ...01-55.64367cde-c27f-4b2a-bda0-a84ef1b4d4bd | Bin 0 -> 45592 bytes ...02-09.5dce232c-a705-443a-b8b5-58d38143b62b | Bin 0 -> 46066 bytes ...02-36.a04ceeb1-5428-4d88-b3e6-0249fd5788c4 | Bin 0 -> 39555 bytes ...04-41.7845f5bf-3033-4ccd-8e10-6b6ec04f9eff | Bin 0 -> 54894 bytes ...05-40.b7856e30-d3cd-43a1-bcf7-e6a4d3896509 | Bin 0 -> 56501 bytes ...05-40.e2f6d53f-6653-4115-810c-e3f4420d4879 | Bin 0 -> 56504 bytes ...05-57.6f691dd5-7b64-4b52-aec9-2e810baea65e | Bin 0 -> 56666 bytes ...25-42.13ccbdf1-f384-4c6f-9aea-a4faf099756b | Bin 0 -> 61699 bytes ...26-10.47595aed-16ca-4978-96c5-ae56ae864a4b | Bin 0 -> 61698 bytes ...48-18.80a55e8c-2eb7-4457-85eb-3a997bc501fa | Bin 0 -> 42512 bytes ...59-05.36baa7de-e574-4590-bb7f-c26ebf50e515 | Bin 0 -> 60433 bytes ...03-27.189a68a0-fc12-4f03-9cb7-e1029c150c54 | Bin 0 -> 56445 bytes ...05-50.b676e5f7-60ef-4992-b0b7-fb392b0fab28 | Bin 0 -> 46283 bytes ...10-03.b76dcefe-bb84-428b-bd3b-928234f99a7e | Bin 0 -> 42885 bytes ...11-50.c3b53257-9058-4328-9baa-b1492fe0229f | Bin 0 -> 46266 bytes ...24-59.3ec330fb-a77c-491e-9a69-03899200aed8 | Bin 0 -> 46088 bytes ...23-38.cb988dbf-e441-49c9-aa7d-ef4ea39edc8f | Bin 0 -> 40867 bytes ...28-47.eb0b29f6-b68c-43b8-94a3-5a91137462fc | Bin 0 -> 45991 bytes ...02-02.0b9ba78e-4c73-4ed1-b359-6c4a418425e7 | Bin 0 -> 5534 bytes ...02-07.fd4ace61-2bd0-41c6-99ae-c2700d2b078a | Bin 0 -> 5534 bytes ...03-36.59e9c8bd-1146-4be6-9401-294912f73db5 | Bin 0 -> 5789 bytes ...07-02.01e76216-c3bb-4665-85e7-5e6e9f39340d | Bin 0 -> 5535 bytes ...15-12.b3c35513-a088-42d2-ba59-6e7b9c782316 | Bin 0 -> 5534 bytes ...20-13.c387dc8d-1ab5-4c8a-adf0-5c8d3995af73 | Bin 0 -> 5534 bytes ...21-18.2de1bbbf-d96a-4478-be19-d65c64d8d855 | Bin 0 -> 5538 bytes ...23-48.ba3ca114-2052-4345-8bb5-91f4d94b1752 | Bin 0 -> 5534 bytes ...24-23.9f96565e-6e8c-47f5-ba6a-5778d179287c | Bin 0 -> 5536 bytes ...26-19.bbd61739-7ba5-4a26-904b-d4538eb0ab77 | Bin 0 -> 42132 bytes ...29-04.a76c77d4-350b-49ac-8234-514173e08b4d | Bin 0 -> 42130 bytes ...29-41.b0b49118-b1bd-4c60-99d7-6adcd31bab06 | Bin 0 -> 42157 bytes ...30-06.52b5a733-2ee0-4f9e-8085-56c589e0e428 | Bin 0 -> 42155 bytes ...34-58.2919a1e8-b4f0-4b65-8545-3348930435bd | Bin 0 -> 44790 bytes ...41-13.a240c4ba-af3f-496b-b49f-edc5be6ca5f6 | Bin 0 -> 42608 bytes ...41-51.0aca82ca-19f5-477e-bb53-231cd0676262 | Bin 0 -> 42927 bytes ...44-19.6909fe36-2c71-4e6b-801b-4b10c6639104 | Bin 0 -> 42912 bytes ...58-28.cc9c6866-9411-43a0-bfd3-f5c184e91df2 | Bin 0 -> 41960 bytes ...59-26.5cda7368-af7e-4821-9551-e4a63c66515c | Bin 0 -> 42247 bytes ...59-58.c999da0e-6456-442d-8965-cc2de92f0a24 | Bin 0 -> 43499 bytes ...00-32.059eb584-594d-442d-aa10-39e01d88bd38 | Bin 0 -> 55507 bytes ...05-37.47604380-9ee5-49b0-9cf3-91702816db8b | Bin 0 -> 67083 bytes ...06-39.dacbe8e8-e39b-4bfa-9402-ad6667d992a9 | Bin 0 -> 60710 bytes ...06-54.01d228ed-55a4-482f-9d85-799e46d8f496 | Bin 0 -> 55382 bytes ...07-24.9e28c885-9705-42f7-a586-8e8bf33058fe | Bin 0 -> 45865 bytes ...07-40.0bf85b3c-af57-41b9-aec6-32821fa6b25d | Bin 0 -> 56404 bytes ...07-53.849ed3c0-87a0-417c-8c75-9df7f330e7b5 | Bin 0 -> 60671 bytes ...08-05.1b7ec789-952e-4ecf-bcc8-60b1631f8b81 | Bin 0 -> 67129 bytes ...30-57.f4714898-671c-4f2c-8b8e-7a6b8c5f06ae | Bin 0 -> 45128 bytes ...38-42.099ed67b-9672-41ae-a0c5-0fe251bf11a9 | Bin 0 -> 45044 bytes ...41-04.1f8690ed-aac3-4a21-b1fc-57791e303d19 | Bin 0 -> 45044 bytes ...15-41.ea6d2041-094b-49ef-bc93-33ecdcc3e79b | Bin 0 -> 42021 bytes ...19-32.6fbe9345-a360-411f-8c29-b534cd8690e0 | Bin 0 -> 78770 bytes ...22-40.023ae398-07f4-4b3f-90a1-481b3c4b3c00 | Bin 0 -> 81567 bytes ...24-42.f7b373a3-4254-4f43-895e-c6ec34004a4a | Bin 0 -> 44056 bytes ...29-03.1c9b8f34-d7c2-49a8-b5b5-0e2895e4db4e | Bin 0 -> 82313 bytes ...32-42.0762d17c-76e0-468d-83bb-acbedd3e0e39 | Bin 0 -> 82478 bytes ...38-19.d804f946-3776-428e-ab85-8abe4747f2bd | Bin 0 -> 82341 bytes ...38-46.857a877d-3dee-4bcd-a2fa-d0d3eb6988e3 | Bin 0 -> 82349 bytes ...10-54.00af0054-046e-4db4-90e7-bdec8baaea3c | Bin 0 -> 58035 bytes ...11-20.4528f3cf-8a45-4a61-8537-1f8323b876c0 | Bin 0 -> 54584 bytes ...13-46.d8b4b653-2531-42c0-aea9-ae7d45b688b8 | Bin 0 -> 54219 bytes ...17-05.4d34eeca-bbf3-4340-aa15-b4fbc1f327f7 | Bin 0 -> 54630 bytes ...18-26.80b9fe72-c085-4a2e-aad2-3d3782b91f71 | Bin 0 -> 83984 bytes ...18-43.5d399fbd-6813-4f00-a84f-8b4848e0f3ac | Bin 0 -> 76657 bytes ...19-03.79712761-a6ab-4d7f-93ef-8fd908e91c55 | Bin 0 -> 44825 bytes ...19-22.f20443f6-2c6a-44df-93b2-30984320c7d8 | Bin 0 -> 44783 bytes ...19-30.e188909e-d416-4a0f-83f7-24b5b8b446f1 | Bin 0 -> 44783 bytes ...19-55.f3486e48-a46b-4b1d-9766-322d984ab403 | Bin 0 -> 82689 bytes ...20-59.a438a8ee-87fb-4c00-b300-5785e2b34fc5 | Bin 0 -> 42426 bytes ...21-13.c8881e31-9041-40b3-9b56-75af994d315e | Bin 0 -> 42426 bytes ...22-50.6ca44238-476a-4e60-a011-a3957354ae63 | Bin 0 -> 42432 bytes ...25-18.a7715c2e-8aea-43ca-a2bb-1a1bc2abf4ec | Bin 0 -> 45476 bytes ...25-33.c08338aa-9678-448b-a0c6-4a3857eb7a5e | Bin 0 -> 45506 bytes ...37-26.91dd915f-96bc-4e97-ac3f-631b5e47fc97 | Bin 0 -> 44551 bytes ...39-46.60f70d02-7dd2-4150-9fb4-7bbf66d37dc4 | Bin 0 -> 48950 bytes ...56-48.779ad15d-f9cb-4edb-9c0b-56a9a8f12acc | Bin 0 -> 84887 bytes ...57-42.e1353019-1e13-4c2f-90c4-19bbc31e04e4 | Bin 0 -> 84917 bytes ...01-01.038b136a-cea0-412b-88c7-467ec747a1c2 | Bin 0 -> 77669 bytes ...04-47.4e2bcd0c-1a67-4cf1-a142-cdef04d5394f | Bin 0 -> 43955 bytes ...04-52.8b0edbf8-188e-4ef2-8bee-e2997d063642 | Bin 0 -> 43955 bytes ...28-30.3fa30d1c-a386-4198-84b5-8c1ea0872793 | Bin 0 -> 87274 bytes ...39-36.c4c9a367-eb3e-4ad6-a8e1-6174d152c58b | Bin 0 -> 43905 bytes ...44-24.ecb2667a-270f-492f-904c-5790ffeea5fd | Bin 0 -> 80481 bytes ...48-35.fde81767-cf3d-48f8-9b83-0fa821b65225 | Bin 0 -> 80185 bytes ...49-34.a9415e50-a09f-4afd-8480-a16f11b976d8 | Bin 0 -> 80481 bytes ...51-52.823fdac2-9f46-4212-beda-f01da85617ee | Bin 0 -> 44604 bytes ...56-00.fe65e955-02bd-4cdc-83c0-2738da8552bd | Bin 0 -> 44952 bytes ...12-54.90b0fa07-b98f-448d-a5b9-4f162df1c934 | Bin 0 -> 45168 bytes ...15-02.7fe4a98f-554e-40ec-95d8-0a89969062a6 | Bin 0 -> 47267 bytes ...21-19.f45f242f-db32-41fd-a6d2-49fbbc3db4bb | Bin 0 -> 45166 bytes ...22-43.f236fc4a-5ffc-4951-8b09-fc87b13aa493 | Bin 0 -> 45220 bytes ...37-46.8ff165c3-169b-4fe0-8943-33268bac342e | Bin 0 -> 44788 bytes ...38-27.9e9533f3-2040-4380-896a-f07d12be3ad1 | Bin 0 -> 44976 bytes ...39-48.cb629b5b-b6e0-4981-865e-08e1ce2d7144 | Bin 0 -> 44824 bytes ...57-02.84349f26-13d3-414a-abed-4f41b121c461 | Bin 0 -> 3714 bytes ...58-40.02fe98af-d9a8-45f8-8043-639a1cd6f2fa | Bin 0 -> 3714 bytes ...00-27.613a119a-0ba5-453a-9a33-57e1c58e2a45 | Bin 0 -> 3714 bytes ...01-44.9e59b647-658d-4421-ae22-a190c64bfe1b | Bin 0 -> 43454 bytes ...02-37.c1142121-3382-4594-83bc-a3b9308934fc | Bin 0 -> 42185 bytes ...03-42.3c3cd596-1ccb-4f9c-8c32-cd19025ffd4f | Bin 0 -> 46799 bytes ...03-43.d0b4f48a-9dd9-44ba-a63c-64bb97ba554a | Bin 0 -> 46458 bytes ...03-45.33a89a0c-4c2a-48ec-b408-2510e4955953 | Bin 0 -> 46799 bytes ...03-50.6269acaa-fd38-4447-9e73-6069412873f0 | Bin 0 -> 46718 bytes ...11-05.73b365fe-f13f-4c3f-b11d-e53a45441ddb | Bin 0 -> 63749 bytes ...11-48.01e44a61-c972-484b-b3aa-f74d6e69e3f4 | Bin 0 -> 88804 bytes ...16-50.3e136a9b-0940-4a33-974f-2f92641aa949 | Bin 0 -> 42538 bytes ...16-57.436c807c-5074-4991-9b08-f749854a201a | Bin 0 -> 42242 bytes ...23-55.ef12ccd5-6a87-4915-a2e6-6311dff79d62 | Bin 0 -> 40159 bytes ...24-12.f06cfd75-143b-4067-af17-9d7bd3f2ffff | Bin 0 -> 40159 bytes ...35-54.b4ea48c0-9572-44ab-a2bd-5835208e72d4 | Bin 0 -> 86771 bytes ...44-42.762a4cbe-9fd4-429b-ad90-65afd6cfa2f7 | Bin 0 -> 81320 bytes ...44-51.5f6b97d4-f2db-44ff-b5a0-c0f44a7ae176 | Bin 0 -> 81394 bytes ...47-26.cea36215-6c4f-4c24-b68a-9fa628c4095a | Bin 0 -> 88904 bytes ...47-53.8099e445-0191-4ba0-893c-0386f0015323 | Bin 0 -> 88930 bytes ...49-20.f6ac2903-4ac8-494a-a317-8d9a12efd0ca | Bin 0 -> 81569 bytes ...58-55.3ec51b6c-4923-461a-a237-f93384d4a5dd | Bin 0 -> 42313 bytes ...05-32.31f8dead-8462-4aa9-8261-8282ab1ab771 | Bin 0 -> 41986 bytes ...27-09.2797c058-322a-4512-b0de-38cf90383715 | Bin 0 -> 85450 bytes ...36-42.e8767d84-83ff-4302-ae92-1614609e7f6a | Bin 0 -> 85186 bytes ...42-19.091ca44b-ec9b-43b0-bc59-d7f510cb7196 | Bin 0 -> 85486 bytes ...43-25.aaba2dbc-357e-47ec-b9f2-3edea03a9b11 | Bin 0 -> 85782 bytes ...44-19.84f7abe3-18fe-4f9b-a4b7-d8596f94e745 | Bin 0 -> 49169 bytes ...44-24.a3cc5eb0-12d6-42cb-9edb-1dd1ea099be4 | Bin 0 -> 49167 bytes ...39-52.78464803-e59b-4281-abde-3d9d9ba30b48 | Bin 0 -> 46667 bytes ...45-28.d03a6dea-77d5-4c23-968b-10584836bcfe | Bin 0 -> 45566 bytes ...46-03.06370395-4251-4ae6-9451-f4f0c8a8360c | Bin 0 -> 44574 bytes ...55-43.353ebf99-44a3-4394-b8c0-d124d53b7261 | Bin 0 -> 44936 bytes ...12-59.611f4e4c-c450-49a6-94ae-2d5da784db45 | Bin 0 -> 49715 bytes ...13-29.ede170a4-af38-44b8-84f2-1dacf2e878cf | Bin 0 -> 49532 bytes ...14-39.315150f0-6b1c-45a7-87d6-a7392658336b | Bin 0 -> 56588 bytes ...02-25.d6a63215-ff4c-4e8d-b71f-0659e31a4c51 | Bin 0 -> 47485 bytes ...03-10.8ae61366-bacc-4809-b5b5-baf0e30a7fe3 | Bin 0 -> 47484 bytes ...03-19.7a82fece-b4ca-4815-a7ce-11eae326b3a6 | Bin 0 -> 47484 bytes ...05-05.23021373-02eb-419f-bd2e-c7b583f6a8d2 | Bin 0 -> 49391 bytes ...05-08.7916431d-3acb-4a7a-a60c-32e78a641411 | Bin 0 -> 49391 bytes ...06-10.4ac1637e-5f02-429d-88d8-578007e1888c | Bin 0 -> 48436 bytes ...07-16.553808ae-96e0-4aae-9dcf-e20697568be5 | Bin 0 -> 48724 bytes ...08-05.00e6160b-f867-439d-afee-21f5a2a5fc8e | Bin 0 -> 43465 bytes ...08-57.98ec4506-1d72-4711-bd06-e340a7e0c79a | Bin 0 -> 48808 bytes ...09-22.8caf72a1-2f42-4991-bf4d-bd33bba63c59 | Bin 0 -> 48770 bytes ...09-34.afec10d7-3824-499d-bbaf-276de70b3d87 | Bin 0 -> 48480 bytes ...09-41.832aeb08-c4dc-41bc-9391-8de5b0317053 | Bin 0 -> 48480 bytes ...10-09.6bcc0e58-a110-47a4-b9b6-cb7946f4f502 | Bin 0 -> 49683 bytes ...13-41.476ab4ad-3c08-47ce-9ece-15c067a40fff | Bin 0 -> 48791 bytes ...14-30.69b37db6-d641-46a7-aa9e-244648ac1286 | Bin 0 -> 48725 bytes ...15-40.c8b163ae-744e-4d7c-a430-61bdc80ebd87 | Bin 0 -> 48701 bytes ...16-49.4a4fd7fe-cd96-40c0-8553-ebe34c5adff7 | Bin 0 -> 46477 bytes ...27-50.a2c2c6c9-43ff-407c-a879-470acd711175 | Bin 0 -> 43147 bytes ...42-41.91d05dfd-c594-47aa-ad9b-272756af2f28 | Bin 0 -> 46582 bytes ...43-33.3f9c933e-96cb-487b-9057-731ef99df91d | Bin 0 -> 61820 bytes ...53-29.38843298-d223-4ae2-957e-6bd410bbaaa4 | Bin 0 -> 42941 bytes ...58-56.60d0f3ea-7fbb-4b9a-90fe-751f620d8048 | Bin 0 -> 44583 bytes ...02-59.39add73b-deca-4b57-b448-9aeba108bb41 | Bin 0 -> 63224 bytes ...04-31.aaa03c9b-657e-4f8c-a933-ad5582570937 | Bin 0 -> 63419 bytes ...05-02.fa395f45-73e8-4ca2-8e4c-48209c73d459 | Bin 0 -> 63415 bytes ...06-15.77652992-fce3-4e80-945b-c735eb163038 | Bin 0 -> 63401 bytes ...07-12.132807a5-f507-428f-8605-fbd5fbcdfbec | Bin 0 -> 63397 bytes ...09-28.2a653b8a-d7ab-41d3-b51b-c1f0187e093d | Bin 0 -> 63555 bytes ...09-31.953fa082-038a-4d3d-9991-e2244f844fd8 | Bin 0 -> 63555 bytes ...10-43.f904246c-b69a-4c66-a870-bae6abc2eefc | Bin 0 -> 63525 bytes ...12-33.f82834a1-af69-409c-b737-c8c4945ecc19 | Bin 0 -> 63506 bytes ...12-49.00ad86af-27cb-406f-8205-b6c4888e0488 | Bin 0 -> 63506 bytes ...13-22.93478285-44ba-461a-b0f2-82323013df66 | Bin 0 -> 63341 bytes ...14-29.d2c0dc37-32a3-4f4e-ae26-ac6e1a57f559 | Bin 0 -> 44724 bytes ...19-55.dc2245da-3bc3-4942-a146-6e8e0881cd6f | Bin 0 -> 44785 bytes ...20-21.ad008041-2415-4d80-844f-3877e2b95366 | Bin 0 -> 44790 bytes ...20-45.98aaf16b-b5b2-46ce-a976-183c7c2db441 | Bin 0 -> 44821 bytes ...33-54.f26cedfa-f99e-4e59-89fc-d9f540d46be6 | Bin 0 -> 43236 bytes ...34-43.ab9f45de-b3cf-4f84-968e-db929cbf8d4f | Bin 0 -> 43228 bytes ...35-10.df605b80-98e0-475b-9cc6-734e4bda05ef | Bin 0 -> 46912 bytes ...35-38.6031b2a4-afbd-4526-9954-b90f5726a2b3 | Bin 0 -> 46914 bytes ...22-49.5bf3d5d5-8470-4062-b60c-430b0a9324d5 | Bin 0 -> 93474 bytes ...25-27.fddcdc13-fbc1-4ea9-b973-7ad52f72e5e2 | Bin 0 -> 93503 bytes ...25-40.b26b714d-b34a-469f-9711-71bbc4b4c87f | Bin 0 -> 93503 bytes ...25-52.f4ce8ead-bf69-44d7-ad4c-d37e82b27262 | Bin 0 -> 93474 bytes ...27-08.37769d06-1bd1-4ed2-8261-01021011a4ce | Bin 0 -> 86162 bytes ...28-46.a83d25c8-3c52-4de7-8161-7b3458958b62 | Bin 0 -> 86143 bytes ...29-11.42987dac-81f9-425a-95fb-f1480209eec7 | Bin 0 -> 86206 bytes ...31-09.9ba3c512-1afe-4804-bce8-7f3045cbb1ec | Bin 0 -> 87277 bytes ...31-28.b65aad29-b9c7-4d94-8f3e-e1e85df927a1 | Bin 0 -> 93910 bytes ...33-13.e9cae406-ac2c-452f-a3b0-410ed9627864 | Bin 0 -> 93733 bytes ...35-13.70c4b5df-9b5b-4a0e-879b-30a4c10a50b3 | Bin 0 -> 85859 bytes ...35-32.d61a4243-a147-4607-952c-33ff8a7c3c1b | Bin 0 -> 93670 bytes ...35-53.9396c4f0-dcb1-4bb5-86e0-651b9c426f64 | Bin 0 -> 93763 bytes ...36-10.4b60b067-1e28-4f1f-89cb-c85be3ad678e | Bin 0 -> 93763 bytes ...45-21.a77fcd2f-d2d4-4d68-ab0c-5b9ac8334211 | Bin 0 -> 62701 bytes ...47-24.5c391f77-5c16-44ef-8ef1-cccaf2d7e509 | Bin 0 -> 55382 bytes ...49-26.d3b60944-aa93-47c6-912e-c41ac302479e | Bin 0 -> 62831 bytes ...49-53.b975ddf0-d822-4e87-8b62-0cf6f40e56e3 | Bin 0 -> 62575 bytes ...50-18.41b82968-5b82-4c33-8b97-5f0e8e543e30 | Bin 0 -> 62575 bytes ...51-00.b0142219-1bc4-417e-aa09-7995210816dd | Bin 0 -> 44404 bytes ...51-12.f46779db-4627-4bc1-bd17-988a79ce4bc8 | Bin 0 -> 62497 bytes web2py/applications/SP/languages/ar.py | 215 + web2py/applications/SP/languages/ca.py | 512 + web2py/applications/SP/languages/cs.py | 516 + web2py/applications/SP/languages/de.py | 218 + web2py/applications/SP/languages/en.py | 157 + web2py/applications/SP/languages/es.py | 468 + web2py/applications/SP/languages/fr-ca.py | 244 + web2py/applications/SP/languages/fr.py | 243 + web2py/applications/SP/languages/hi.py | 187 + web2py/applications/SP/languages/hu.py | 199 + web2py/applications/SP/languages/id.py | 357 + web2py/applications/SP/languages/it.py | 286 + web2py/applications/SP/languages/my-mm.py | 299 + web2py/applications/SP/languages/my.py | 309 + web2py/applications/SP/languages/nl.py | 413 + web2py/applications/SP/languages/pl.py | 208 + web2py/applications/SP/languages/plural-cs.py | 19 + web2py/applications/SP/languages/plural-en.py | 14 + web2py/applications/SP/languages/plural-es.py | 7 + web2py/applications/SP/languages/plural-ru.py | 15 + web2py/applications/SP/languages/plural-uk.py | 16 + web2py/applications/SP/languages/pt-br.py | 218 + web2py/applications/SP/languages/pt.py | 238 + web2py/applications/SP/languages/ro.py | 410 + web2py/applications/SP/languages/ru.py | 232 + web2py/applications/SP/languages/sk.py | 208 + web2py/applications/SP/languages/tr.py | 232 + web2py/applications/SP/languages/uk.py | 260 + web2py/applications/SP/languages/zh-cn.py | 341 + web2py/applications/SP/languages/zh-tw.py | 281 + web2py/applications/SP/languages/zh.py | 268 + web2py/applications/SP/models/db.py | 184 + web2py/applications/SP/models/menu.py | 26 + web2py/applications/SP/models/user.py | 65 + web2py/applications/SP/modules/__init__.py | 1 + web2py/applications/SP/private/appconfig.ini | 34 + web2py/applications/SP/routes.example.py | 41 + ...0.0.1-3a55a2c1-03d7-4d77-a0f0-7c5167c6ffaf | Bin 0 -> 193 bytes ...0.0.1-c5e4640f-cd25-49f7-a9b4-ec61b28e19fb | Bin 0 -> 2266 bytes ...0.0.1-8f845cf0-8676-4057-ac7e-9c22692bdee9 | Bin 0 -> 2086 bytes ...0.0.1-33e760f6-e988-4855-bc05-acaa70a2a64b | Bin 0 -> 153 bytes ...0.0.1-eda8a93c-17b3-4956-83d4-6145f10125d9 | Bin 0 -> 487 bytes ...0.0.1-f08a2093-f7db-4845-b460-0836a90b02c4 | Bin 0 -> 117 bytes ...0.0.1-1f01e76d-a832-47ba-b184-eebd13ddb4cc | Bin 0 -> 225 bytes ...0.0.1-144c5c8d-bf7d-440c-b952-879db22d2a07 | Bin 0 -> 299 bytes ...0.0.1-f7b40c44-2670-4091-809e-f8e292d361d8 | Bin 0 -> 292 bytes ...0.0.1-a4b375ce-9ef2-4cb8-b721-1eaff15515ba | Bin 0 -> 331 bytes ...0.0.1-64331f4a-020d-4190-a0cd-db51c3091d10 | Bin 0 -> 1895 bytes ...0.0.1-d444ca1d-5c94-4268-b5d4-f84120a0f1c2 | Bin 0 -> 193 bytes ...0.0.1-bdb65a41-a01f-4d6a-b6b2-37f998787c20 | Bin 0 -> 107 bytes ...0.0.1-d684f46e-042a-42ba-92cd-3d4a5fd5e6e5 | Bin 0 -> 58 bytes ...0.0.1-3992ba2e-ef94-4ddc-8768-75f185e714c5 | Bin 0 -> 256 bytes ...0.0.1-03f20c11-1674-436d-9256-7d3cdf2e9c6b | Bin 0 -> 1486 bytes ...0.0.1-da5509be-5e08-4d6e-8704-82183b494f1e | Bin 0 -> 756 bytes ...0.0.1-7fdbcdd4-97a7-4348-b7ac-df2372d0a84c | Bin 0 -> 721 bytes ...0.0.1-df1a50b7-edf5-446c-a054-b101a381e7ee | Bin 0 -> 2014 bytes ...0.0.1-540d2395-25f8-4a5a-b8cd-00b5d5a08207 | Bin 0 -> 153 bytes ...0.0.1-317bc46a-dbc3-4a32-93ea-e8b53f02ae19 | Bin 0 -> 1161 bytes ...0.0.1-efdbf1a4-bdcc-4cb9-9117-a756917f9703 | Bin 0 -> 331 bytes ...0.0.1-b33d3d8c-220e-4e99-ac6e-1d9d4b7eebdc | Bin 0 -> 479 bytes web2py/applications/SP/static/403.html | 1 + web2py/applications/SP/static/404.html | 1 + web2py/applications/SP/static/500.html | 1 + web2py/applications/SP/static/503.html | 1 + .../SP/static/css/bootstrap.min.css | 7 + .../SP/static/css/bootstrap.min.css.map | 1 + .../applications/SP/static/css/calendar.css | 7 + .../SP/static/css/web2py-bootstrap4.css | 350 + web2py/applications/SP/static/css/web2py.css | 313 + .../SP/static/images/facebook.png | Bin 0 -> 991 bytes .../applications/SP/static/images/favicon.ico | Bin 0 -> 198 bytes .../applications/SP/static/images/favicon.png | Bin 0 -> 323 bytes .../SP/static/images/gplus-32.png | Bin 0 -> 1513 bytes .../applications/SP/static/images/twitter.png | Bin 0 -> 1120 bytes .../SP/static/js/analytics.min.js | 8 + .../SP/static/js/bootstrap.bundle.min.js | 7 + .../SP/static/js/bootstrap.bundle.min.js.map | 1 + web2py/applications/SP/static/js/calendar.js | 29 + web2py/applications/SP/static/js/jquery.js | 4 + .../SP/static/js/modernizr-2.8.3.min.js | 4 + .../SP/static/js/web2py-bootstrap4.js | 82 + web2py/applications/SP/static/js/web2py.js | 828 + web2py/applications/SP/views/__init__.py | 1 + .../SP/views/appadmin/appadmin.html | 449 + .../SP/views/appadmin/change_userinfo.html | 3 + .../SP/views/default/change_settings.html | 8 + .../applications/SP/views/default/index.html | 51 + .../SP/views/default/monitorctl.html | 38 + .../SP/views/default/myclass.html | 29 + .../applications/SP/views/default/myhome.html | 16 + .../applications/SP/views/default/task.html | 34 + .../applications/SP/views/default/user.html | 33 + web2py/applications/SP/views/generic.html | 13 + web2py/applications/SP/views/generic.ics | 17 + web2py/applications/SP/views/generic.json | 1 + web2py/applications/SP/views/generic.jsonp | 23 + web2py/applications/SP/views/generic.load | 30 + web2py/applications/SP/views/generic.map | 69 + web2py/applications/SP/views/generic.pdf | 11 + web2py/applications/SP/views/generic.rss | 10 + web2py/applications/SP/views/generic.xml | 1 + web2py/applications/SP/views/layout.html | 128 + web2py/applications/SP/views/web2py_ajax.html | 18 + web2py/applications/__init__.py | 1 + web2py/applications/admin/ABOUT | 6 + web2py/applications/admin/LICENSE | 118 + web2py/applications/admin/__init__.py | 1 + .../admin/controllers/appadmin.py | 693 + .../applications/admin/controllers/debug.py | 237 + .../applications/admin/controllers/default.py | 2003 ++ web2py/applications/admin/controllers/gae.py | 105 + .../admin/controllers/mercurial.py | 85 + .../admin/controllers/openshift.py | 69 + .../admin/controllers/plugin_jqmobile.py | 10 + .../admin/controllers/pythonanywhere.py | 99 + .../applications/admin/controllers/toolbar.py | 31 + .../admin/controllers/webservices.py | 127 + .../applications/admin/controllers/wizard.py | 607 + web2py/applications/admin/cron/crontab | 2 + .../admin/cron/expire_sessions.py | 28 + ...10-57.651cbadf-fbcf-432a-b809-60471a5a6391 | Bin 0 -> 42608 bytes ...12-47.2de91eb7-be71-4410-8c6f-f0addca46ccd | Bin 0 -> 42625 bytes web2py/applications/admin/languages/af.py | 582 + web2py/applications/admin/languages/bg.py | 640 + web2py/applications/admin/languages/cs.py | 716 + web2py/applications/admin/languages/de.py | 714 + web2py/applications/admin/languages/en.py | 574 + web2py/applications/admin/languages/es.py | 694 + web2py/applications/admin/languages/fr.py | 649 + web2py/applications/admin/languages/he.py | 622 + web2py/applications/admin/languages/it.py | 649 + web2py/applications/admin/languages/ja.py | 586 + web2py/applications/admin/languages/my-mm.py | 660 + web2py/applications/admin/languages/nl.py | 655 + web2py/applications/admin/languages/pl.py | 640 + .../applications/admin/languages/plural-en.py | 6 + .../applications/admin/languages/plural-ru.py | 6 + .../applications/admin/languages/plural-uk.py | 8 + web2py/applications/admin/languages/pt-br.py | 664 + web2py/applications/admin/languages/pt.py | 670 + web2py/applications/admin/languages/ro.py | 788 + web2py/applications/admin/languages/ru.py | 708 + web2py/applications/admin/languages/sl.py | 707 + web2py/applications/admin/languages/sr-cr.py | 595 + web2py/applications/admin/languages/sr-lt.py | 596 + web2py/applications/admin/languages/tr.py | 646 + web2py/applications/admin/languages/uk.py | 660 + web2py/applications/admin/languages/zh-tw.py | 682 + web2py/applications/admin/languages/zh.py | 667 + web2py/applications/admin/models/0.py | 50 + web2py/applications/admin/models/0_imports.py | 30 + web2py/applications/admin/models/access.py | 190 + web2py/applications/admin/models/buttons.py | 40 + web2py/applications/admin/models/db.py | 42 + web2py/applications/admin/models/menu.py | 36 + .../admin/models/plugin_multiselect.py | 4 + .../admin/models/plugin_statebutton.py | 16 + web2py/applications/admin/modules/__init__.py | 1 + web2py/applications/admin/private/hosts.deny | 0 ...0.0.1-1c8a258c-88c4-42f9-b14c-8f5ca542f25b | Bin 0 -> 347 bytes ...0.0.1-81403135-39d2-41f5-b406-83f384553319 | Bin 0 -> 917 bytes ...0.0.1-d4a94174-7f7f-434d-a74d-a7246b977b53 | Bin 0 -> 1013 bytes ...0.0.1-0f21193f-ae22-4031-8fd5-7502aeac37b7 | Bin 0 -> 603 bytes ...0.0.1-35682bd4-e9cf-4132-a1ee-1a04633eae7e | Bin 0 -> 761 bytes ...0.0.1-0f21193f-ae22-4031-8fd5-7502aeac37b7 | Bin 0 -> 693 bytes ...0.0.1-35682bd4-e9cf-4132-a1ee-1a04633eae7e | Bin 0 -> 995 bytes ...0.0.1-7d4172c5-b4c3-41ec-a61b-eb366480f74d | Bin 0 -> 603 bytes ...0.0.1-d4a94174-7f7f-434d-a74d-a7246b977b53 | Bin 0 -> 1147 bytes ...0.0.1-dfc090b6-f2b7-41a3-88e4-1e2f94a9ee5f | Bin 0 -> 612 bytes ...0.0.1-dfc090b6-f2b7-41a3-88e4-1e2f94a9ee5f | Bin 0 -> 461 bytes ...0.0.1-7d4172c5-b4c3-41ec-a61b-eb366480f74d | Bin 0 -> 461 bytes ...0.0.1-0e0da4c9-9dc5-4402-9af8-3f8637da4614 | Bin 0 -> 683 bytes web2py/applications/admin/settings.cfg | 10 + .../codemirror/addon/comment/comment.js | 183 + .../addon/comment/continuecomment.js | 85 + .../static/codemirror/addon/dialog/dialog.css | 32 + .../static/codemirror/addon/dialog/dialog.js | 155 + .../codemirror/addon/display/fullscreen.css | 6 + .../codemirror/addon/display/fullscreen.js | 41 + .../static/codemirror/addon/display/panel.js | 94 + .../codemirror/addon/display/placeholder.js | 58 + .../static/codemirror/addon/display/rulers.js | 64 + .../codemirror/addon/edit/closebrackets.js | 161 + .../static/codemirror/addon/edit/closetag.js | 166 + .../codemirror/addon/edit/continuelist.js | 51 + .../codemirror/addon/edit/matchbrackets.js | 120 + .../static/codemirror/addon/edit/matchtags.js | 66 + .../codemirror/addon/edit/trailingspace.js | 27 + .../codemirror/addon/fold/brace-fold.js | 105 + .../codemirror/addon/fold/comment-fold.js | 57 + .../static/codemirror/addon/fold/foldcode.js | 149 + .../codemirror/addon/fold/foldgutter.css | 20 + .../codemirror/addon/fold/foldgutter.js | 144 + .../codemirror/addon/fold/indent-fold.js | 44 + .../codemirror/addon/fold/markdown-fold.js | 49 + .../static/codemirror/addon/fold/xml-fold.js | 182 + .../codemirror/addon/hint/anyword-hint.js | 41 + .../static/codemirror/addon/hint/css-hint.js | 56 + .../static/codemirror/addon/hint/html-hint.js | 348 + .../codemirror/addon/hint/javascript-hint.js | 146 + .../codemirror/addon/hint/python-hint.js | 99 + .../codemirror/addon/hint/show-hint.css | 38 + .../static/codemirror/addon/hint/show-hint.js | 394 + .../static/codemirror/addon/hint/sql-hint.js | 240 + .../static/codemirror/addon/hint/xml-hint.js | 110 + .../static/codemirror/addon/mode/loadmode.js | 64 + .../static/codemirror/addon/mode/multiplex.js | 118 + .../codemirror/addon/mode/multiplex_test.js | 33 + .../static/codemirror/addon/mode/overlay.js | 85 + .../static/codemirror/addon/mode/simple.js | 213 + .../addon/search/match-highlighter.js | 128 + .../addon/search/matchesonscrollbar.css | 8 + .../addon/search/matchesonscrollbar.js | 95 + .../static/codemirror/addon/search/search.js | 164 + .../codemirror/addon/search/searchcursor.js | 189 + .../codemirror/addon/selection/active-line.js | 71 + .../addon/selection/mark-selection.js | 118 + .../addon/selection/selection-pointer.js | 98 + .../admin/static/codemirror/emmet.min.js | 304 + .../admin/static/codemirror/keymap/emacs.js | 412 + .../admin/static/codemirror/keymap/sublime.js | 540 + .../admin/static/codemirror/keymap/vim.js | 4959 +++ .../static/codemirror/lib/codemirror.css | 309 + .../admin/static/codemirror/lib/codemirror.js | 8068 +++++ .../admin/static/codemirror/mode/css/css.js | 766 + .../static/codemirror/mode/css/less_test.js | 51 + .../static/codemirror/mode/css/scss_test.js | 110 + .../admin/static/codemirror/mode/css/test.js | 195 + .../codemirror/mode/htmlmixed/htmlmixed.js | 121 + .../codemirror/mode/javascript/javascript.js | 692 + .../static/codemirror/mode/javascript/test.js | 200 + .../static/codemirror/mode/python/python.js | 359 + .../admin/static/codemirror/mode/xml/test.js | 51 + .../admin/static/codemirror/mode/xml/xml.js | 384 + .../static/codemirror/theme/3024-day.css | 38 + .../static/codemirror/theme/3024-night.css | 37 + .../codemirror/theme/ambiance-mobile.css | 5 + .../static/codemirror/theme/ambiance.css | 77 + .../static/codemirror/theme/base16-dark.css | 36 + .../static/codemirror/theme/base16-light.css | 36 + .../static/codemirror/theme/blackboard.css | 30 + .../admin/static/codemirror/theme/cobalt.css | 23 + .../static/codemirror/theme/colorforth.css | 33 + .../admin/static/codemirror/theme/eclipse.css | 23 + .../admin/static/codemirror/theme/elegant.css | 13 + .../static/codemirror/theme/erlang-dark.css | 32 + .../static/codemirror/theme/lesser-dark.css | 45 + .../admin/static/codemirror/theme/mbo.css | 35 + .../static/codemirror/theme/mdn-like.css | 44 + .../static/codemirror/theme/midnight.css | 45 + .../admin/static/codemirror/theme/monokai.css | 31 + .../admin/static/codemirror/theme/neat.css | 12 + .../admin/static/codemirror/theme/neo.css | 43 + .../admin/static/codemirror/theme/night.css | 26 + .../static/codemirror/theme/paraiso-dark.css | 36 + .../static/codemirror/theme/paraiso-light.css | 36 + .../codemirror/theme/pastel-on-dark.css | 50 + .../static/codemirror/theme/rubyblue.css | 23 + .../static/codemirror/theme/solarized.css | 165 + .../static/codemirror/theme/the-matrix.css | 28 + .../theme/tomorrow-night-bright.css | 35 + .../theme/tomorrow-night-eighties.css | 36 + .../static/codemirror/theme/twilight.css | 30 + .../static/codemirror/theme/vibrant-ink.css | 32 + .../admin/static/codemirror/theme/web2py.css | 36 + .../admin/static/codemirror/theme/xq-dark.css | 51 + .../static/codemirror/theme/xq-light.css | 43 + .../admin/static/codemirror/theme/zenburn.css | 37 + .../static/css/bootstrap-responsive.min.css | 9 + .../admin/static/css/bootstrap.min.css | 9 + .../admin/static/css/bootstrap_essentials.css | 1047 + .../admin/static/css/calendar.css | 7 + .../admin/static/css/d3_graph.css | 33 + .../admin/static/css/jqueryMultiSelect.css | 47 + .../static/css/typeahead.js-bootstrap.css | 74 + .../admin/static/css/web2py-codemirror.css | 66 + .../applications/admin/static/images/chat.png | Bin 0 -> 4719 bytes .../admin/static/images/delete_icon.png | Bin 0 -> 855 bytes .../admin/static/images/dim_bullet.gif | Bin 0 -> 424 bytes .../admin/static/images/embossed.png | Bin 0 -> 310 bytes .../admin/static/images/files_toggle.png | Bin 0 -> 1315 bytes .../admin/static/images/folder.png | Bin 0 -> 823 bytes .../admin/static/images/folder_locked.png | Bin 0 -> 932 bytes .../admin/static/images/folder_sm.png | Bin 0 -> 764 bytes .../images/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes .../static/images/glyphicons-halflings.png | Bin 0 -> 12799 bytes .../admin/static/images/header_bg.png | Bin 0 -> 149 bytes .../admin/static/images/header_shadow.png | Bin 0 -> 143 bytes .../applications/admin/static/images/help.png | Bin 0 -> 450 bytes .../applications/admin/static/images/menu.png | Bin 0 -> 1395 bytes .../admin/static/images/menu_responsive.png | Bin 0 -> 1566 bytes .../admin/static/images/questions.png | Bin 0 -> 5036 bytes .../admin/static/images/red_bullet.gif | Bin 0 -> 630 bytes .../admin/static/images/save_icon.png | Bin 0 -> 762 bytes .../admin/static/images/search.png | Bin 0 -> 688 bytes .../admin/static/images/section_bullet.png | Bin 0 -> 718 bytes .../static/images/sidebar_background.jpg | Bin 0 -> 430 bytes .../admin/static/images/sidebar_bullet.gif | Bin 0 -> 426 bytes .../admin/static/images/small_button.png | Bin 0 -> 1371 bytes .../static/images/small_special_button.png | Bin 0 -> 1398 bytes .../admin/static/images/spinner.gif | Bin 0 -> 158630 bytes .../admin/static/images/start.png | Bin 0 -> 5498 bytes .../admin/static/images/test_icon.png | Bin 0 -> 879 bytes .../admin/static/images/ticket_section.png | Bin 0 -> 718 bytes .../admin/static/js/ajax_editor.js | 283 + .../admin/static/js/analytics.min.js | 4 + .../admin/static/js/autoscroll.js | 63 + .../admin/static/js/bootstrap.min.js | 6 + .../applications/admin/static/js/calendar.js | 42 + web2py/applications/admin/static/js/d3.min.js | 8 + .../applications/admin/static/js/d3_graph.js | 181 + .../admin/static/js/dd_belatedpng.js | 13 + .../admin/static/js/hogan-2.0.0.js | 15 + .../admin/static/js/jquery.flot.js | 2599 ++ .../admin/static/js/jquery.flot.resize.js | 60 + .../admin/static/js/jquery.hotkeys.js | 245 + web2py/applications/admin/static/js/jquery.js | 4 + .../admin/static/js/jqueryMultiSelect.js | 267 + .../admin/static/js/modernizr.custom.js | 4 + web2py/applications/admin/static/js/share.js | 44 + .../admin/static/js/typeahead.min.js | 7 + web2py/applications/admin/static/js/web2py.js | 828 + .../admin/static/js/web2py_bootstrap.js | 33 + .../static/plugin_jqmobile/dd_belatedpng.js | 13 + .../plugin_jqmobile/images/ajax-loader.png | Bin 0 -> 366 bytes .../plugin_jqmobile/images/icons-18-black.png | Bin 0 -> 2152 bytes .../plugin_jqmobile/images/icons-18-white.png | Bin 0 -> 1958 bytes .../plugin_jqmobile/images/icons-36-black.png | Bin 0 -> 4260 bytes .../plugin_jqmobile/images/icons-36-white.png | Bin 0 -> 3746 bytes .../static/plugin_jqmobile/images/iphone.jpg | Bin 0 -> 99964 bytes .../jquery.mobile-1.2.0.min.css | 2 + .../jquery.mobile-1.2.0.min.js | 2 + .../jquery.mobile-1.3.1.min.css | 3 + .../jquery.mobile-1.3.1.min.js | 7 + .../plugin_multiselect/jquery.multi-select.js | 321 + .../plugin_multiselect/multi-select.css | 91 + .../admin/static/plugin_multiselect/start.js | 1 + .../static/plugin_multiselect/switch.png | Bin 0 -> 3080 bytes .../css/bootstrap-switch.css | 408 + .../plugin_statebutton/js/bootstrap-switch.js | 382 + web2py/applications/admin/views/appadmin.html | 279 + .../admin/views/debug/breakpoints.html | 137 + .../applications/admin/views/debug/index.html | 162 + .../admin/views/debug/interact.html | 191 + .../admin/views/default.mobile/about.html | 13 + .../views/default.mobile/change_password.html | 10 + .../admin/views/default.mobile/delete.html | 9 + .../views/default.mobile/delete_plugin.html | 10 + .../admin/views/default.mobile/design.html | 253 + .../default.mobile/downgrade_web2py.html | 14 + .../admin/views/default.mobile/edit.html | 41 + .../views/default.mobile/edit_language.html | 19 + .../admin/views/default.mobile/errors.html | 145 + .../admin/views/default.mobile/git_pull.html | 15 + .../admin/views/default.mobile/git_push.html | 15 + .../admin/views/default.mobile/index.html | 19 + .../admin/views/default.mobile/layout.html | 119 + .../admin/views/default.mobile/peek.html | 17 + .../admin/views/default.mobile/plugin.html | 207 + .../admin/views/default.mobile/resolve.html | 25 + .../admin/views/default.mobile/site.html | 47 + .../admin/views/default.mobile/test.html | 21 + .../admin/views/default.mobile/ticket.html | 132 + .../admin/views/default.mobile/ticket.load | 130 + .../admin/views/default.mobile/uninstall.html | 10 + .../views/default.mobile/upgrade_web2py.html | 14 + .../admin/views/default.mobile/user.html | 20 + .../admin/views/default/about.html | 26 + .../admin/views/default/bulk_register.html | 20 + .../admin/views/default/change_password.html | 22 + .../admin/views/default/delete.html | 16 + .../admin/views/default/delete_plugin.html | 16 + .../admin/views/default/design.html | 494 + .../admin/views/default/edit.html | 348 + .../admin/views/default/edit_js.html | 158 + .../admin/views/default/edit_language.html | 26 + .../admin/views/default/edit_plurals.html | 15 + .../admin/views/default/editor_sessions.html | 11 + .../admin/views/default/editor_settings.html | 53 + .../admin/views/default/editor_shortcuts.html | 17 + .../admin/views/default/errors.html | 124 + .../admin/views/default/files_menu.html | 3 + .../admin/views/default/git_pull.html | 15 + .../admin/views/default/git_push.html | 13 + .../admin/views/default/index.html | 23 + .../admin/views/default/install_plugin.html | 9 + .../admin/views/default/manage_students.html | 163 + .../admin/views/default/pack_custom.html | 33 + .../admin/views/default/peek.html | 16 + .../admin/views/default/plugin.html | 223 + .../admin/views/default/plugins.html | 21 + .../admin/views/default/resolve.html | 21 + .../admin/views/default/site.html | 160 + .../admin/views/default/test.html | 27 + .../admin/views/default/ticket.html | 139 + .../admin/views/default/ticket.load | 130 + .../admin/views/default/todolist.load | 18 + .../admin/views/default/twitter.load | 43 + .../admin/views/default/uninstall.html | 7 + .../admin/views/default/upgrade_web2py.html | 17 + .../admin/views/default/user.html | 67 + .../applications/admin/views/gae/deploy.html | 31 + web2py/applications/admin/views/generic.html | 16 + web2py/applications/admin/views/layout.html | 114 + .../admin/views/mercurial/commit.html | 32 + .../admin/views/mercurial/revision.html | 18 + .../admin/views/openshift/deploy.html | 32 + .../admin/views/plugin_jqmobile/about.html | 71 + .../admin/views/plugin_jqmobile/index.html | 34 + .../admin/views/plugin_jqmobile/layout.html | 119 + .../admin/views/pythonanywhere/deploy.html | 176 + .../admin/views/toolbar/index.html | 18 + .../applications/admin/views/web2py_ajax.html | 18 + .../admin/views/wizard/generated.html | 15 + .../applications/admin/views/wizard/step.html | 183 + web2py/applications/examples/ABOUT | 6 + web2py/applications/examples/DISABLED | 0 web2py/applications/examples/LICENSE | 137 + web2py/applications/examples/__init__.py | 1 + .../examples/controllers/ajax_examples.py | 21 + .../examples/controllers/appadmin.py | 693 + .../examples/controllers/cache_examples.py | 49 + .../examples/controllers/default.py | 95 + .../examples/controllers/form_examples.py | 22 + .../examples/controllers/global.py | 52 + .../examples/controllers/layout_examples.py | 22 + .../examples/controllers/session_examples.py | 7 + .../examples/controllers/simple_examples.py | 124 + .../examples/controllers/soap_examples.py | 73 + .../examples/controllers/spreadsheet.py | 10 + .../examples/controllers/template_examples.py | 30 + web2py/applications/examples/cron/crontab | 1 + web2py/applications/examples/languages/README | 1 + .../examples/models/feeds_reader.py | 44 + .../applications/examples/models/markmin.py | 42 + web2py/applications/examples/models/menu.py | 45 + .../applications/examples/models/session.py | 3 + .../default/documentation/community.markmin | 6 + .../en/default/documentation/main.markmin | 4 + .../en/default/documentation/more.markmin | 27 + .../en/default/documentation/official.markmin | 10 + .../en/default/index/maincontent.markmin | 7 + .../en/default/index/whyweb2py.markmin | 89 + .../en/default/usergroups/grouplist.markmin | 46 + .../content/en/default/what/whyweb2py.markmin | 73 + web2py/applications/examples/static/403.html | 1 + web2py/applications/examples/static/404.html | 1 + web2py/applications/examples/static/500.html | 1 + web2py/applications/examples/static/503.html | 1 + .../examples/static/artwork.tar.gz | Bin 0 -> 1883628 bytes .../examples/static/css/artwork.css | 141 + .../examples/static/css/calendar.css | 11 + .../examples/static/css/examples.css | 69 + .../examples/static/css/stupid.css | 375 + .../examples/static/css/web2py.css | 204 + .../applications/examples/static/favicon.ico | Bin 0 -> 1150 bytes .../examples/static/images/Stickers1.png | Bin 0 -> 4131 bytes .../examples/static/images/Stickers2.png | Bin 0 -> 4150 bytes .../examples/static/images/Stickers3.png | Bin 0 -> 3713 bytes .../examples/static/images/Stickers4.png | Bin 0 -> 3358 bytes .../examples/static/images/Stickers5.png | Bin 0 -> 3211 bytes .../examples/static/images/Stickers6.png | Bin 0 -> 3300 bytes .../examples/static/images/Stickers7.png | Bin 0 -> 3565 bytes .../examples/static/images/Stickers8.png | Bin 0 -> 3358 bytes .../examples/static/images/book-4th.png | Bin 0 -> 18385 bytes .../examples/static/images/book-5th.png | Bin 0 -> 29483 bytes .../examples/static/images/book-recipes.png | Bin 0 -> 34389 bytes .../examples/static/images/facebook.png | Bin 0 -> 991 bytes .../examples/static/images/favicon.ico | Bin 0 -> 198 bytes .../examples/static/images/favicon.png | Bin 0 -> 323 bytes .../examples/static/images/gplus-32.png | Bin 0 -> 1513 bytes .../examples/static/images/infoworld2012.jpeg | Bin 0 -> 25202 bytes .../examples/static/images/logo_bw.png | Bin 0 -> 152096 bytes .../examples/static/images/logo_db.png | Bin 0 -> 237373 bytes .../examples/static/images/logo_lb.png | Bin 0 -> 216964 bytes .../examples/static/images/menu.png | Bin 0 -> 162 bytes .../examples/static/images/poweredby.png | Bin 0 -> 4150 bytes .../examples/static/images/questions.png | Bin 0 -> 5811 bytes .../examples/static/images/shadow-bottom.png | Bin 0 -> 9677 bytes .../examples/static/images/stripes.png | Bin 0 -> 79322 bytes .../static/images/tag-cloud-color-small.png | Bin 0 -> 59563 bytes .../examples/static/images/twitter.png | Bin 0 -> 1120 bytes .../examples/static/images/videos.png | Bin 0 -> 28931 bytes .../examples/static/images/web2py_logo.png | Bin 0 -> 9966 bytes .../examples/static/js/analytics.min.js | 4 + .../examples/static/js/calendar.js | 29 + .../applications/examples/static/js/jquery.js | 4 + .../applications/examples/static/js/share.js | 44 + .../applications/examples/static/js/web2py.js | 828 + .../applications/examples/static/markmin.html | 96 + .../applications/examples/static/robots.txt | 4 + web2py/applications/examples/static/title.png | Bin 0 -> 10937 bytes .../examples/static/web2py_cheatsheet.pdf | Bin 0 -> 126651 bytes .../static/web2py_contributor_agreement.pdf | Bin 0 -> 38724 bytes .../examples/static/web2py_logo.png | Bin 0 -> 9966 bytes .../examples/views/ajax_examples/fade.html | 8 + .../examples/views/ajax_examples/index.html | 13 + .../applications/examples/views/appadmin.html | 279 + .../views/cache_examples/generic.html | 3 + .../examples/views/database_examples/buy.html | 7 + .../views/database_examples/register_dog.html | 7 + .../database_examples/register_person.html | 7 + .../database_examples/register_product.html | 7 + .../examples/views/default/changelog.html | 6 + .../examples/views/default/documentation.html | 14 + .../examples/views/default/download.html | 121 + .../examples/views/default/examples.html | 665 + .../examples/views/default/index.html | 69 + .../examples/views/default/license.html | 8 + .../examples/views/default/support.html | 43 + .../examples/views/default/usergroups.html | 10 + .../examples/views/default/videos.html | 17 + .../examples/views/default/what.html | 30 + .../examples/views/default/who.html | 175 + .../examples/views/form_examples/form.html | 9 + .../applications/examples/views/generic.html | 16 + .../applications/examples/views/generic.json | 15 + .../applications/examples/views/generic.load | 1 + .../applications/examples/views/generic.rss | 20 + .../applications/examples/views/generic.xml | 1 + .../examples/views/global/vars.html | 54 + .../examples/views/images_examples/index.html | 5 + .../applications/examples/views/layout.html | 67 + .../examples/views/layout_examples/basic.html | 3 + .../views/layout_examples/civilized.html | 3 + .../layout_examples/layout_civilized.html | 291 + .../views/layout_examples/layout_sleek.html | 253 + .../examples/views/layout_examples/slick.html | 3 + .../views/session_examples/counter.html | 8 + .../views/simple_examples/ajaxwiki.html | 4 + .../views/simple_examples/hello3.html | 3 + .../examples/views/soap_examples/generic.html | 8 + .../examples/views/spreadsheet/index.html | 12 + .../views/template_examples/beautify.html | 5 + .../views/template_examples/escape.html | 5 + .../views/template_examples/test_def.html | 7 + .../views/template_examples/test_for.html | 7 + .../views/template_examples/test_if.html | 11 + .../views/template_examples/test_try.html | 8 + .../views/template_examples/variables.html | 4 + .../examples/views/template_examples/xml.html | 5 + .../examples/views/web2py_ajax.html | 17 + web2py/applications/welcome/ABOUT | 2 + web2py/applications/welcome/DISABLED | 0 web2py/applications/welcome/LICENSE | 4 + web2py/applications/welcome/__init__.py | 1 + .../welcome/controllers/appadmin.py | 693 + .../welcome/controllers/default.py | 58 + web2py/applications/welcome/cron/crontab | 1 + .../applications/welcome/cron/crontab.example | 1 + ...9d15150d7109e5f7ab36744a5b7_auth_cas.table | Bin 0 -> 684 bytes ...15150d7109e5f7ab36744a5b7_auth_event.table | Bin 0 -> 694 bytes ...15150d7109e5f7ab36744a5b7_auth_group.table | Bin 0 -> 361 bytes ...d7109e5f7ab36744a5b7_auth_membership.table | Bin 0 -> 492 bytes ...d7109e5f7ab36744a5b7_auth_permission.table | Bin 0 -> 601 bytes ...d15150d7109e5f7ab36744a5b7_auth_user.table | Bin 0 -> 807 bytes web2py/applications/welcome/databases/sql.log | 55 + .../welcome/databases/storage.sqlite | Bin 0 -> 32768 bytes ...56-32.fefc955a-9a46-4bc3-8ca4-d5816b0a2c0d | Bin 0 -> 48100 bytes ...59-09.7f029417-0967-4557-a5a7-2731685f4fed | Bin 0 -> 48096 bytes ...59-22.e4fdb3d9-eee4-4157-9821-43eb9f5eaff7 | Bin 0 -> 48262 bytes web2py/applications/welcome/languages/ar.py | 215 + web2py/applications/welcome/languages/ca.py | 512 + web2py/applications/welcome/languages/cs.py | 516 + web2py/applications/welcome/languages/de.py | 218 + web2py/applications/welcome/languages/en.py | 157 + web2py/applications/welcome/languages/es.py | 468 + .../applications/welcome/languages/fr-ca.py | 244 + web2py/applications/welcome/languages/fr.py | 243 + web2py/applications/welcome/languages/hi.py | 187 + web2py/applications/welcome/languages/hu.py | 199 + web2py/applications/welcome/languages/id.py | 357 + web2py/applications/welcome/languages/it.py | 286 + .../applications/welcome/languages/my-mm.py | 299 + web2py/applications/welcome/languages/my.py | 309 + web2py/applications/welcome/languages/nl.py | 413 + web2py/applications/welcome/languages/pl.py | 208 + .../welcome/languages/plural-cs.py | 19 + .../welcome/languages/plural-en.py | 14 + .../welcome/languages/plural-es.py | 7 + .../welcome/languages/plural-ru.py | 15 + .../welcome/languages/plural-uk.py | 16 + .../applications/welcome/languages/pt-br.py | 218 + web2py/applications/welcome/languages/pt.py | 238 + web2py/applications/welcome/languages/ro.py | 410 + web2py/applications/welcome/languages/ru.py | 232 + web2py/applications/welcome/languages/sk.py | 208 + web2py/applications/welcome/languages/tr.py | 232 + web2py/applications/welcome/languages/uk.py | 260 + .../applications/welcome/languages/zh-cn.py | 291 + .../applications/welcome/languages/zh-tw.py | 281 + web2py/applications/welcome/languages/zh.py | 268 + web2py/applications/welcome/models/db.py | 155 + web2py/applications/welcome/models/menu.py | 110 + .../applications/welcome/modules/__init__.py | 1 + .../welcome/private/appconfig.ini | 34 + web2py/applications/welcome/routes.example.py | 41 + ...0.0.1-bb450c25-c189-45ee-a78a-980f495ebe13 | Bin 0 -> 217 bytes ...0.0.1-62ae636e-3c30-4565-ba01-0ccb6df89d2f | Bin 0 -> 147 bytes ...0.0.1-c29755d4-0fe8-482f-ac05-b9a9e8f6c069 | Bin 0 -> 171 bytes web2py/applications/welcome/static/403.html | 1 + web2py/applications/welcome/static/404.html | 1 + web2py/applications/welcome/static/500.html | 1 + web2py/applications/welcome/static/503.html | 1 + .../welcome/static/css/bootstrap.min.css | 7 + .../welcome/static/css/bootstrap.min.css.map | 1 + .../welcome/static/css/calendar.css | 7 + .../welcome/static/css/web2py-bootstrap4.css | 350 + .../welcome/static/css/web2py.css | 313 + .../welcome/static/images/facebook.png | Bin 0 -> 991 bytes .../welcome/static/images/favicon.ico | Bin 0 -> 198 bytes .../welcome/static/images/favicon.png | Bin 0 -> 323 bytes .../welcome/static/images/gplus-32.png | Bin 0 -> 1513 bytes .../welcome/static/images/twitter.png | Bin 0 -> 1120 bytes .../welcome/static/js/analytics.min.js | 8 + .../welcome/static/js/bootstrap.bundle.min.js | 7 + .../static/js/bootstrap.bundle.min.js.map | 1 + .../welcome/static/js/calendar.js | 29 + .../applications/welcome/static/js/jquery.js | 4 + .../welcome/static/js/modernizr-2.8.3.min.js | 4 + .../welcome/static/js/web2py-bootstrap4.js | 82 + .../applications/welcome/static/js/web2py.js | 828 + web2py/applications/welcome/views/__init__.py | 1 + .../applications/welcome/views/appadmin.html | 279 + .../welcome/views/default/index.html | 51 + .../welcome/views/default/user.html | 33 + .../applications/welcome/views/generic.html | 13 + web2py/applications/welcome/views/generic.ics | 17 + .../applications/welcome/views/generic.json | 1 + .../applications/welcome/views/generic.jsonp | 23 + .../applications/welcome/views/generic.load | 30 + web2py/applications/welcome/views/generic.map | 69 + web2py/applications/welcome/views/generic.pdf | 11 + web2py/applications/welcome/views/generic.rss | 10 + web2py/applications/welcome/views/generic.xml | 1 + web2py/applications/welcome/views/layout.html | 131 + .../welcome/views/web2py_ajax.html | 18 + web2py/examples/README | 2 + web2py/examples/app.example.yaml | 90 + web2py/examples/appengine_config.example.py | 4 + web2py/examples/logging.example.conf | 145 + web2py/examples/options_std.py | 33 + web2py/examples/queue.example.yaml | 8 + web2py/examples/routes.parametric.example.py | 213 + web2py/examples/routes.patterns.example.py | 199 + web2py/examples/web.config | 46 + web2py/extras/build_web2py/README | 2 + web2py/extras/build_web2py/setup_app.py | 160 + web2py/extras/build_web2py/setup_exe.conf | 27 + web2py/extras/build_web2py/setup_exe.py | 232 + web2py/extras/icons/splashlogo.gif | Bin 0 -> 9093 bytes web2py/extras/icons/web2py.gif | Bin 0 -> 4386 bytes web2py/extras/icons/web2py.icns | Bin 0 -> 39379 bytes web2py/extras/icons/web2py.ico | Bin 0 -> 113846 bytes web2py/fabfile.py | 177 + web2py/gluon/__init__.py | 63 + web2py/gluon/_compat.py | 163 + web2py/gluon/admin.py | 478 + web2py/gluon/authapi.py | 1057 + web2py/gluon/cache.py | 746 + web2py/gluon/cfs.py | 54 + web2py/gluon/compileapp.py | 755 + web2py/gluon/contenttype.py | 855 + web2py/gluon/contrib/AuthorizeNet.py | 271 + web2py/gluon/contrib/DowCommerce.py | 245 + web2py/gluon/contrib/__init__.py | 0 web2py/gluon/contrib/appconfig.py | 142 + web2py/gluon/contrib/autolinks.py | 222 + web2py/gluon/contrib/dbg.py | 1121 + web2py/gluon/contrib/feedparser.py | 4007 +++ web2py/gluon/contrib/fpdf/__init__.py | 16 + web2py/gluon/contrib/fpdf/fonts.py | 156 + web2py/gluon/contrib/fpdf/fpdf.py | 2059 ++ web2py/gluon/contrib/fpdf/html.py | 402 + web2py/gluon/contrib/fpdf/php.py | 54 + web2py/gluon/contrib/fpdf/py3k.py | 83 + web2py/gluon/contrib/fpdf/template.py | 229 + web2py/gluon/contrib/fpdf/ttfonts.py | 1075 + web2py/gluon/contrib/gae_memcache.py | 74 + web2py/gluon/contrib/gae_retry.py | 89 + web2py/gluon/contrib/gateways/__init__.py | 2 + web2py/gluon/contrib/gateways/fcgi.py | 1331 + web2py/gluon/contrib/generics.py | 76 + web2py/gluon/contrib/google_wallet.py | 15 + web2py/gluon/contrib/heroku.py | 28 + web2py/gluon/contrib/hypermedia.py | 341 + web2py/gluon/contrib/imageutils.py | 73 + web2py/gluon/contrib/ipaddress.py | 2425 ++ .../gluon/contrib/login_methods/__init__.py | 1 + .../gluon/contrib/login_methods/basic_auth.py | 24 + .../login_methods/browserid_account.py | 95 + .../gluon/contrib/login_methods/cas_auth.py | 148 + .../contrib/login_methods/dropbox_account.py | 129 + .../gluon/contrib/login_methods/email_auth.py | 46 + .../login_methods/extended_login_form.py | 105 + .../login_methods/gae_google_account.py | 41 + .../contrib/login_methods/janrain_account.py | 141 + .../gluon/contrib/login_methods/ldap_auth.py | 716 + .../contrib/login_methods/linkedin_account.py | 51 + .../login_methods/loginradius_account.py | 96 + web2py/gluon/contrib/login_methods/loginza.py | 115 + .../gluon/contrib/login_methods/motp_auth.py | 111 + .../contrib/login_methods/oauth10a_account.py | 184 + .../contrib/login_methods/oauth20_account.py | 303 + .../contrib/login_methods/oneall_account.py | 106 + .../contrib/login_methods/openid_auth.py | 653 + .../gluon/contrib/login_methods/pam_auth.py | 22 + .../contrib/login_methods/rpx_account.py | 136 + .../gluon/contrib/login_methods/saml2_auth.py | 208 + .../gluon/contrib/login_methods/x509_auth.py | 99 + web2py/gluon/contrib/markdown/LICENSE | 1 + web2py/gluon/contrib/markdown/__init__.py | 17 + web2py/gluon/contrib/markdown/markdown2.py | 2459 ++ web2py/gluon/contrib/markmin/__init__.py | 2 + web2py/gluon/contrib/markmin/markmin.html | 92 + web2py/gluon/contrib/markmin/markmin.pdf | Bin 0 -> 116299 bytes web2py/gluon/contrib/markmin/markmin2html.py | 1564 + web2py/gluon/contrib/markmin/markmin2latex.py | 313 + web2py/gluon/contrib/markmin/markmin2pdf.py | 132 + web2py/gluon/contrib/memcache/ChangeLog | 362 + web2py/gluon/contrib/memcache/PKG-INFO | 10 + web2py/gluon/contrib/memcache/README | 8 + web2py/gluon/contrib/memcache/__init__.py | 114 + web2py/gluon/contrib/memcache/memcache.py | 1578 + web2py/gluon/contrib/memdb.py | 905 + web2py/gluon/contrib/minify/__init__.py | 0 web2py/gluon/contrib/minify/cssmin.py | 234 + web2py/gluon/contrib/minify/htmlmin.py | 15 + web2py/gluon/contrib/minify/jsmin.py | 391 + web2py/gluon/contrib/minify/minify.py | 153 + web2py/gluon/contrib/ordereddict.py | 7 + web2py/gluon/contrib/pam.py | 129 + web2py/gluon/contrib/paymentech.py | 342 + web2py/gluon/contrib/pbkdf2.py | 130 + web2py/gluon/contrib/pbkdf2_ctypes.py | 194 + web2py/gluon/contrib/pdfinvoice.py | 162 + web2py/gluon/contrib/plural_rules/__init__.py | 1 + web2py/gluon/contrib/plural_rules/af.py | 17 + web2py/gluon/contrib/plural_rules/ar.py | 3 + web2py/gluon/contrib/plural_rules/bg.py | 17 + web2py/gluon/contrib/plural_rules/ca.py | 23 + web2py/gluon/contrib/plural_rules/cs.py | 19 + web2py/gluon/contrib/plural_rules/de.py | 17 + web2py/gluon/contrib/plural_rules/en.py | 20 + web2py/gluon/contrib/plural_rules/es.py | 20 + web2py/gluon/contrib/plural_rules/fr.py | 69 + web2py/gluon/contrib/plural_rules/he.py | 17 + web2py/gluon/contrib/plural_rules/hi.py | 17 + web2py/gluon/contrib/plural_rules/hu.py | 17 + web2py/gluon/contrib/plural_rules/id.py | 17 + web2py/gluon/contrib/plural_rules/it.py | 17 + web2py/gluon/contrib/plural_rules/ja.py | 14 + web2py/gluon/contrib/plural_rules/lt.py | 19 + web2py/gluon/contrib/plural_rules/my.py | 17 + web2py/gluon/contrib/plural_rules/nl.py | 17 + web2py/gluon/contrib/plural_rules/pl.py | 19 + web2py/gluon/contrib/plural_rules/pt.py | 17 + web2py/gluon/contrib/plural_rules/ro.py | 17 + web2py/gluon/contrib/plural_rules/ru.py | 20 + web2py/gluon/contrib/plural_rules/sk.py | 20 + web2py/gluon/contrib/plural_rules/sl.py | 20 + web2py/gluon/contrib/plural_rules/tr.py | 14 + web2py/gluon/contrib/plural_rules/uk.py | 21 + web2py/gluon/contrib/plural_rules/zh.py | 14 + web2py/gluon/contrib/populate.py | 274 + web2py/gluon/contrib/pyaes/LICENSE.txt | 22 + web2py/gluon/contrib/pyaes/README.md | 363 + web2py/gluon/contrib/pyaes/__init__.py | 53 + web2py/gluon/contrib/pyaes/aes.py | 589 + web2py/gluon/contrib/pyaes/blockfeeder.py | 227 + web2py/gluon/contrib/pyaes/util.py | 60 + web2py/gluon/contrib/pyfpdf.py | 11 + web2py/gluon/contrib/pymysql/CHANGELOG | 37 + web2py/gluon/contrib/pymysql/LICENSE | 19 + web2py/gluon/contrib/pymysql/README.rst | 41 + web2py/gluon/contrib/pymysql/__init__.py | 134 + web2py/gluon/contrib/pymysql/_compat.py | 21 + web2py/gluon/contrib/pymysql/_socketio.py | 134 + web2py/gluon/contrib/pymysql/charset.py | 270 + web2py/gluon/contrib/pymysql/connections.py | 1499 + .../gluon/contrib/pymysql/constants/CLIENT.py | 31 + .../contrib/pymysql/constants/COMMAND.py | 33 + web2py/gluon/contrib/pymysql/constants/CR.py | 68 + web2py/gluon/contrib/pymysql/constants/ER.py | 472 + .../contrib/pymysql/constants/FIELD_TYPE.py | 33 + .../gluon/contrib/pymysql/constants/FLAG.py | 15 + .../pymysql/constants/SERVER_STATUS.py | 11 + .../contrib/pymysql/constants/__init__.py | 0 web2py/gluon/contrib/pymysql/converters.py | 419 + web2py/gluon/contrib/pymysql/cursors.py | 519 + web2py/gluon/contrib/pymysql/err.py | 107 + web2py/gluon/contrib/pymysql/optionfile.py | 20 + .../gluon/contrib/pymysql/tests/__init__.py | 18 + web2py/gluon/contrib/pymysql/tests/base.py | 86 + .../pymysql/tests/data/load_local_data.txt | 22749 ++++++++++++++ .../tests/data/load_local_warn_data.txt | 50 + .../contrib/pymysql/tests/test_DictCursor.py | 119 + .../contrib/pymysql/tests/test_SSCursor.py | 110 + .../gluon/contrib/pymysql/tests/test_basic.py | 379 + .../contrib/pymysql/tests/test_connection.py | 576 + .../contrib/pymysql/tests/test_converters.py | 67 + .../contrib/pymysql/tests/test_cursor.py | 104 + .../gluon/contrib/pymysql/tests/test_err.py | 21 + .../contrib/pymysql/tests/test_example.py | 32 + .../contrib/pymysql/tests/test_issues.py | 515 + .../contrib/pymysql/tests/test_load_local.py | 93 + .../contrib/pymysql/tests/test_nextset.py | 68 + .../contrib/pymysql/tests/test_optionfile.py | 32 + .../pymysql/tests/thirdparty/__init__.py | 8 + .../tests/thirdparty/test_MySQLdb/__init__.py | 7 + .../thirdparty/test_MySQLdb/capabilities.py | 298 + .../tests/thirdparty/test_MySQLdb/dbapi20.py | 856 + .../test_MySQLdb/test_MySQLdb_capabilities.py | 109 + .../test_MySQLdb/test_MySQLdb_dbapi20.py | 210 + .../test_MySQLdb/test_MySQLdb_nonstandard.py | 101 + web2py/gluon/contrib/pymysql/times.py | 20 + web2py/gluon/contrib/pymysql/util.py | 22 + web2py/gluon/contrib/pypyodbc.py | 2810 ++ web2py/gluon/contrib/pyrtf/Constants.py | 158 + web2py/gluon/contrib/pyrtf/Elements.py | 757 + web2py/gluon/contrib/pyrtf/PropertySets.py | 489 + web2py/gluon/contrib/pyrtf/README | 19 + web2py/gluon/contrib/pyrtf/Renderer.py | 639 + web2py/gluon/contrib/pyrtf/Styles.py | 94 + web2py/gluon/contrib/pyrtf/__init__.py | 12 + web2py/gluon/contrib/pysimplesoap/__init__.py | 16 + web2py/gluon/contrib/pysimplesoap/c14n.py | 433 + web2py/gluon/contrib/pysimplesoap/client.py | 962 + web2py/gluon/contrib/pysimplesoap/helpers.py | 706 + web2py/gluon/contrib/pysimplesoap/plugins.py | 39 + web2py/gluon/contrib/pysimplesoap/server.py | 624 + .../gluon/contrib/pysimplesoap/simplexml.py | 532 + .../gluon/contrib/pysimplesoap/transport.py | 281 + web2py/gluon/contrib/pysimplesoap/wsse.py | 215 + web2py/gluon/contrib/pysimplesoap/xmlsec.py | 220 + web2py/gluon/contrib/pyuca/LICENSE | 19 + web2py/gluon/contrib/pyuca/README.markmin | 43 + web2py/gluon/contrib/pyuca/__init__.py | 10 + web2py/gluon/contrib/pyuca/allkeys.txt | 25141 ++++++++++++++++ web2py/gluon/contrib/pyuca/pyuca.py | 144 + web2py/gluon/contrib/redis_cache.py | 285 + web2py/gluon/contrib/redis_scheduler.py | 800 + web2py/gluon/contrib/redis_session.py | 254 + web2py/gluon/contrib/redis_utils.py | 70 + web2py/gluon/contrib/rss2.py | 522 + web2py/gluon/contrib/shell.py | 269 + web2py/gluon/contrib/simplejson.py | 10 + web2py/gluon/contrib/simplejsonrpc.py | 155 + web2py/gluon/contrib/sms_utils.py | 115 + web2py/gluon/contrib/spreadsheet.py | 904 + web2py/gluon/contrib/stripe.py | 252 + web2py/gluon/contrib/taskbar_widget.py | 244 + web2py/gluon/contrib/timecollect.py | 103 + web2py/gluon/contrib/user_agent_parser.py | 695 + web2py/gluon/contrib/webclient.py | 223 + web2py/gluon/contrib/websocket_messaging.py | 242 + web2py/gluon/custom_import.py | 208 + web2py/gluon/dal.py | 143 + web2py/gluon/debug.py | 196 + web2py/gluon/decoder.py | 79 + web2py/gluon/fileutils.py | 482 + web2py/gluon/globals.py | 1287 + web2py/gluon/highlight.py | 342 + web2py/gluon/html.py | 2847 ++ web2py/gluon/http.py | 187 + web2py/gluon/import_all.py | 98 + web2py/gluon/languages.py | 1094 + web2py/gluon/main.py | 796 + web2py/gluon/messageboxhandler.py | 35 + web2py/gluon/myregex.py | 33 + web2py/gluon/newcron.py | 386 + web2py/gluon/packages/dal/.codecov.yml | 13 + web2py/gluon/packages/dal/.coveragerc | 29 + web2py/gluon/packages/dal/.travis.yml | 82 + web2py/gluon/packages/dal/AUTHORS | 10 + web2py/gluon/packages/dal/CHANGES | 276 + web2py/gluon/packages/dal/LICENSE | 36 + web2py/gluon/packages/dal/MANIFEST.in | 7 + web2py/gluon/packages/dal/README.md | 70 + web2py/gluon/packages/dal/appveyor.yml | 55 + web2py/gluon/packages/dal/docs/Makefile | 177 + web2py/gluon/packages/dal/docs/conf.py | 244 + web2py/gluon/packages/dal/docs/index.rst | 59 + .../packages/dal/docs/pydal.adapters.rst | 147 + .../gluon/packages/dal/docs/pydal.helpers.rst | 38 + .../gluon/packages/dal/docs/requirements.txt | 1 + web2py/gluon/packages/dal/pydal/__init__.py | 6 + web2py/gluon/packages/dal/pydal/_compat.py | 111 + web2py/gluon/packages/dal/pydal/_gae.py | 12 + web2py/gluon/packages/dal/pydal/_globals.py | 10 + web2py/gluon/packages/dal/pydal/_load.py | 15 + .../packages/dal/pydal/adapters/__init__.py | 87 + .../gluon/packages/dal/pydal/adapters/base.py | 965 + .../packages/dal/pydal/adapters/couchdb.py | 148 + .../gluon/packages/dal/pydal/adapters/db2.py | 58 + .../packages/dal/pydal/adapters/firebird.py | 92 + .../packages/dal/pydal/adapters/google.py | 460 + .../packages/dal/pydal/adapters/informix.py | 64 + .../packages/dal/pydal/adapters/ingres.py | 51 + .../packages/dal/pydal/adapters/mongo.py | 950 + .../packages/dal/pydal/adapters/mssql.py | 184 + .../packages/dal/pydal/adapters/mysql.py | 82 + .../packages/dal/pydal/adapters/oracle.py | 161 + .../packages/dal/pydal/adapters/postgres.py | 284 + .../gluon/packages/dal/pydal/adapters/sap.py | 49 + .../packages/dal/pydal/adapters/sqlite.py | 123 + .../packages/dal/pydal/adapters/teradata.py | 28 + web2py/gluon/packages/dal/pydal/base.py | 898 + web2py/gluon/packages/dal/pydal/connection.py | 174 + .../packages/dal/pydal/contrib/__init__.py | 0 .../dal/pydal/contrib/imap_adapter.py | 1053 + .../packages/dal/pydal/contrib/mockimaplib.py | 255 + .../packages/dal/pydal/contrib/ordereddict.py | 128 + .../packages/dal/pydal/contrib/portalocker.py | 227 + .../pydal/contrib/reserved_sql_keywords.py | 1724 ++ .../packages/dal/pydal/dialects/__init__.py | 115 + .../gluon/packages/dal/pydal/dialects/base.py | 582 + .../packages/dal/pydal/dialects/couchdb.py | 32 + .../gluon/packages/dal/pydal/dialects/db2.py | 86 + .../packages/dal/pydal/dialects/firebird.py | 114 + .../packages/dal/pydal/dialects/google.py | 190 + .../packages/dal/pydal/dialects/informix.py | 79 + .../packages/dal/pydal/dialects/ingres.py | 117 + .../packages/dal/pydal/dialects/mongo.py | 524 + .../packages/dal/pydal/dialects/mssql.py | 425 + .../packages/dal/pydal/dialects/mysql.py | 100 + .../packages/dal/pydal/dialects/oracle.py | 120 + .../packages/dal/pydal/dialects/postgre.py | 307 + .../gluon/packages/dal/pydal/dialects/sap.py | 78 + .../packages/dal/pydal/dialects/sqlite.py | 107 + .../packages/dal/pydal/dialects/teradata.py | 100 + web2py/gluon/packages/dal/pydal/drivers.py | 161 + web2py/gluon/packages/dal/pydal/exceptions.py | 16 + .../packages/dal/pydal/helpers/__init__.py | 0 .../packages/dal/pydal/helpers/_internals.py | 35 + .../packages/dal/pydal/helpers/classes.py | 591 + .../gluon/packages/dal/pydal/helpers/gae.py | 36 + .../packages/dal/pydal/helpers/methods.py | 437 + .../gluon/packages/dal/pydal/helpers/regex.py | 23 + .../gluon/packages/dal/pydal/helpers/rest.py | 316 + .../packages/dal/pydal/helpers/serializers.py | 57 + web2py/gluon/packages/dal/pydal/migrator.py | 527 + web2py/gluon/packages/dal/pydal/objects.py | 3122 ++ .../packages/dal/pydal/parsers/__init__.py | 110 + .../gluon/packages/dal/pydal/parsers/base.py | 161 + .../packages/dal/pydal/parsers/google.py | 14 + .../gluon/packages/dal/pydal/parsers/mongo.py | 54 + .../packages/dal/pydal/parsers/postgre.py | 36 + .../packages/dal/pydal/parsers/sqlite.py | 33 + .../dal/pydal/representers/__init__.py | 267 + .../packages/dal/pydal/representers/base.py | 288 + .../dal/pydal/representers/couchdb.py | 42 + .../packages/dal/pydal/representers/db2.py | 20 + .../packages/dal/pydal/representers/google.py | 42 + .../dal/pydal/representers/informix.py | 24 + .../packages/dal/pydal/representers/mongo.py | 51 + .../packages/dal/pydal/representers/mssql.py | 28 + .../packages/dal/pydal/representers/mysql.py | 8 + .../packages/dal/pydal/representers/oracle.py | 28 + .../dal/pydal/representers/postgre.py | 41 + .../packages/dal/pydal/representers/sqlite.py | 24 + web2py/gluon/packages/dal/pydal/utils.py | 44 + web2py/gluon/packages/dal/setup.cfg | 5 + web2py/gluon/packages/dal/setup.py | 59 + web2py/gluon/packages/dal/tests/__init__.py | 13 + web2py/gluon/packages/dal/tests/_adapt.py | 32 + web2py/gluon/packages/dal/tests/_compat.py | 6 + web2py/gluon/packages/dal/tests/_helpers.py | 25 + web2py/gluon/packages/dal/tests/base.py | 188 + web2py/gluon/packages/dal/tests/caching.py | 78 + web2py/gluon/packages/dal/tests/contribs.py | 158 + web2py/gluon/packages/dal/tests/indexes.py | 59 + web2py/gluon/packages/dal/tests/nosql.py | 2317 ++ .../gluon/packages/dal/tests/smart_query.py | 324 + web2py/gluon/packages/dal/tests/sql.py | 3013 ++ web2py/gluon/packages/dal/tests/validation.py | 86 + web2py/gluon/packages/dal/tox.ini | 31 + web2py/gluon/recfile.py | 65 + web2py/gluon/restricted.py | 331 + web2py/gluon/rewrite.py | 1372 + web2py/gluon/rocket.py | 1897 ++ web2py/gluon/rocket.py.footer | 52 + web2py/gluon/sanitizer.py | 219 + web2py/gluon/scheduler.py | 1716 ++ web2py/gluon/serializers.py | 210 + web2py/gluon/settings.py | 45 + web2py/gluon/shell.py | 505 + web2py/gluon/sql.py | 29 + web2py/gluon/sqlhtml.py | 3809 +++ web2py/gluon/storage.py | 323 + web2py/gluon/streamer.py | 132 + web2py/gluon/template.py | 938 + web2py/gluon/tests/__init__.py | 30 + web2py/gluon/tests/coverage.ini | 31 + web2py/gluon/tests/fix_path.py | 30 + web2py/gluon/tests/test_appadmin.py | 199 + web2py/gluon/tests/test_authapi.py | 174 + web2py/gluon/tests/test_cache.py | 145 + web2py/gluon/tests/test_compileapp.py | 58 + web2py/gluon/tests/test_contenttype.py | 37 + web2py/gluon/tests/test_contribs.py | 67 + web2py/gluon/tests/test_cron.py | 24 + web2py/gluon/tests/test_dal.py | 109 + web2py/gluon/tests/test_fileutils.py | 28 + web2py/gluon/tests/test_globals.py | 243 + web2py/gluon/tests/test_html.py | 746 + web2py/gluon/tests/test_http.py | 37 + web2py/gluon/tests/test_is_url.py | 692 + web2py/gluon/tests/test_languages.py | 367 + web2py/gluon/tests/test_old_doctests.py | 28 + web2py/gluon/tests/test_recfile.py | 74 + web2py/gluon/tests/test_rocket.py | 3 + web2py/gluon/tests/test_router.py | 1558 + web2py/gluon/tests/test_routes.py | 452 + web2py/gluon/tests/test_scheduler.py | 896 + web2py/gluon/tests/test_serializers.py | 61 + web2py/gluon/tests/test_sqlhtml.py | 441 + web2py/gluon/tests/test_storage.py | 151 + web2py/gluon/tests/test_template.py | 135 + web2py/gluon/tests/test_tools.py | 1390 + web2py/gluon/tests/test_utils.py | 179 + web2py/gluon/tests/test_validators.py | 1199 + web2py/gluon/tests/test_web.py | 158 + web2py/gluon/tools.py | 6430 ++++ web2py/gluon/utf8.py | 758 + web2py/gluon/utils.py | 464 + web2py/gluon/validators.py | 3919 +++ web2py/gluon/widget.py | 1332 + web2py/gluon/xmlrpc.py | 21 + web2py/handlers/README | 3 + web2py/handlers/cgihandler.py | 67 + web2py/handlers/fcgihandler.py | 57 + web2py/handlers/gaehandler.py | 112 + web2py/handlers/isapiwsgihandler.py | 39 + web2py/handlers/modpythonhandler.py | 228 + web2py/handlers/scgihandler.py | 78 + web2py/handlers/web2py_on_gevent.py | 112 + web2py/handlers/wsgihandler.py | 40 + web2py/httpserver.log | 4173 +++ web2py/parameters_8000.py | 1 + web2py/scripts/autoroutes.py | 150 + web2py/scripts/check_lang_progress.py | 38 + web2py/scripts/contentparser.py | 132 + web2py/scripts/cpdb.py | 685 + web2py/scripts/cpplugin.py | 32 + web2py/scripts/dict_diff.py | 128 + web2py/scripts/drop-pgsql-tables.sh | 14 + web2py/scripts/extract_mssql_models.py | 328 + web2py/scripts/extract_mysql_models.py | 120 + web2py/scripts/extract_oracle_models.py | 312 + web2py/scripts/extract_pgsql_models.py | 286 + web2py/scripts/extract_sqlite_models.py | 113 + web2py/scripts/fixws.py | 27 + web2py/scripts/import_static.py | 103 + web2py/scripts/lang_update_from_langfile.py | 44 + web2py/scripts/make_min_web2py.py | 97 + web2py/scripts/parse_top_level_domains.py | 41 + web2py/scripts/rmorphans.py | 25 + web2py/scripts/sessions2trash.py | 259 + web2py/scripts/setup-scheduler-centos.sh | 66 + web2py/scripts/setup-web2py-centos7.sh | 302 + web2py/scripts/setup-web2py-cloudfoundry.sh | 6 + web2py/scripts/setup-web2py-debian-sid.sh | 162 + web2py/scripts/setup-web2py-fedora-ami.sh | 402 + web2py/scripts/setup-web2py-fedora.sh | 405 + web2py/scripts/setup-web2py-heroku.sh | 16 + .../setup-web2py-nginx-uwsgi-centos64.sh | 215 + .../setup-web2py-nginx-uwsgi-centos7.sh | 235 + .../setup-web2py-nginx-uwsgi-on-centos.sh | 354 + .../setup-web2py-nginx-uwsgi-opensuse.sh | 224 + .../setup-web2py-nginx-uwsgi-ubuntu.sh | 233 + web2py/scripts/setup-web2py-ubuntu.sh | 167 + web2py/scripts/standalone_exe_cxfreeze.py | 64 + web2py/scripts/sync_languages.py | 77 + web2py/scripts/tickets2db.py | 51 + web2py/scripts/tickets2email.py | 49 + web2py/scripts/tickets2slack.py | 78 + web2py/scripts/update-web2py.sh | 58 + web2py/scripts/update_languages.py | 82 + web2py/scripts/web2py-lock.sh | 11 + web2py/scripts/web2py.archlinux.sh | 57 + web2py/scripts/web2py.fedora.sh | 81 + web2py/scripts/web2py.ubuntu.sh | 222 + web2py/scripts/zip_static_files.py | 49 + web2py/site-packages/__init__.py | 1 + web2py/web2py.py | 33 + web2py/welcome.w2p | Bin 0 -> 419730 bytes 1654 files changed, 377476 insertions(+) create mode 100644 .idea/dataSources.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/untitled.iml create mode 100644 .idea/vcs.xml create mode 100644 bin/activate create mode 100644 bin/activate.csh create mode 100644 bin/activate.fish create mode 100755 bin/easy_install create mode 100755 bin/easy_install-3.7 create mode 100755 bin/pip create mode 100755 bin/pip3 create mode 100755 bin/pip3.7 create mode 100755 bin/python create mode 100755 bin/python3 create mode 100644 lib/python3.7/site-packages/easy-install.pth create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/PKG-INFO create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/SOURCES.txt create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/dependency_links.txt create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/entry_points.txt create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/not-zip-safe create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/requires.txt create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/top_level.txt create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/__main__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/basecommand.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/baseparser.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/build_env.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/cache.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/cmdoptions.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/check.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/completion.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/configuration.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/download.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/freeze.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/hash.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/help.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/install.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/list.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/search.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/show.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/uninstall.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/wheel.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/compat.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/configuration.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/download.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/exceptions.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/index.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/locations.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/index.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/check.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/freeze.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/prepare.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/pep425tags.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_file.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_install.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_set.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_uninstall.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/resolve.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/status_codes.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/appdirs.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/deprecation.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/encoding.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/filesystem.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/glibc.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/hashes.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/logging.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/misc.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/outdated.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/packaging.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/setuptools_build.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/temp_dir.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/typing.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/ui.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/bazaar.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/git.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/mercurial.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/subversion.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/wheel.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/appdirs.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/_cmd.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/adapter.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/cache.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/compat.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/controller.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/heuristics.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/serialize.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/wrapper.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__main__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/cacert.pem create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/core.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/big5freq.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/big5prober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/chardistribution.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/charsetgroupprober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/charsetprober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cli/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cli/chardetect.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/codingstatemachine.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/compat.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cp949prober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/enums.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/escprober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/escsm.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/eucjpprober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euckrfreq.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euckrprober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euctwfreq.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euctwprober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/gb2312freq.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/gb2312prober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/hebrewprober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/jisfreq.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/jpcntx.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langbulgarianmodel.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langcyrillicmodel.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langgreekmodel.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langhebrewmodel.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langhungarianmodel.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langthaimodel.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langturkishmodel.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/latin1prober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcharsetprober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcsgroupprober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcssm.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sbcharsetprober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sbcsgroupprober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sjisprober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/universaldetector.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/utf8prober.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/version.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/ansi.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/ansitowin32.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/initialise.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/win32.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/winterm.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/misc.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/shutil.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.cfg create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/tarfile.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/compat.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/database.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/index.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/locators.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/manifest.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/markers.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/metadata.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/resources.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/scripts.py create mode 100755 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/t32.exe create mode 100755 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/t64.exe create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/util.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/version.py create mode 100755 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/w32.exe create mode 100755 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/w64.exe create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/wheel.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distro.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_ihatexml.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_inputstream.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_tokenizer.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/_base.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/datrie.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/py.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_utils.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/constants.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/alphabeticalattributes.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/base.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/inject_meta_charset.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/lint.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/optionaltags.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/sanitizer.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/whitespace.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/html5parser.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/serializer.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/genshi.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/sax.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/base.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/dom.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/base.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/dom.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree_lxml.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/genshi.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/codec.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/compat.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/core.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/idnadata.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/intranges.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/package_data.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/uts46data.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/ipaddress.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/linklockfile.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/mkdirlockfile.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/sqlitelockfile.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/symlinklockfile.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/_version.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/exceptions.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/fallback.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__about__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_compat.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_structures.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/markers.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/requirements.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/specifiers.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/utils.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/version.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/py31compat.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/bar.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/counter.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/helpers.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/spinner.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pyparsing.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/core.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/parser.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/writer.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__version__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/_internal_utils.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/adapters.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/api.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/auth.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/certs.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/compat.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/cookies.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/exceptions.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/help.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/hooks.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/models.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/packages.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/sessions.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/status_codes.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/structures.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/utils.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/retrying.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/six.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/_collections.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/connection.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/connectionpool.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/socks.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/exceptions.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/fields.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/filepost.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ordered_dict.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/six.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/poolmanager.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/request.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/response.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/connection.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/request.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/response.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/retry.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/selectors.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/ssl_.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/timeout.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/url.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/wait.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/__init__.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/labels.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/mklabels.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/tests.py create mode 100644 lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/x_user_defined.py create mode 100644 lib/python3.7/site-packages/setuptools-39.1.0-py3.7.egg create mode 100644 lib/python3.7/site-packages/setuptools.pth create mode 100644 pyvenv.cfg create mode 100644 web2py/CHANGELOG create mode 100644 web2py/LICENSE create mode 100644 web2py/MANIFEST.in create mode 100644 web2py/README.markdown create mode 100644 web2py/VERSION create mode 100644 web2py/anyserver.py create mode 100644 web2py/applications/SP/ABOUT create mode 100644 web2py/applications/SP/LICENSE create mode 100644 web2py/applications/SP/__init__.py create mode 100644 web2py/applications/SP/controllers/appadmin.py create mode 100644 web2py/applications/SP/controllers/default.py create mode 100644 web2py/applications/SP/cron/crontab create mode 100644 web2py/applications/SP/cron/crontab.example create mode 100644 web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_cas.table create mode 100644 web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_event.table create mode 100644 web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_group.table create mode 100644 web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_membership.table create mode 100644 web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_permission.table create mode 100644 web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_user.table create mode 100644 web2py/applications/SP/databases/fb87181b96a99be45f5a23f4277867ce_history.table create mode 100644 web2py/applications/SP/databases/fb87181b96a99be45f5a23f4277867ce_task.table create mode 100644 web2py/applications/SP/databases/fb87181b96a99be45f5a23f4277867ce_user_info.table create mode 100644 web2py/applications/SP/databases/sql.log create mode 100644 web2py/applications/SP/databases/storage.db create mode 100644 web2py/applications/SP/databases/storage.sqlite create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-22.18-19-16.eb57736d-d461-4d86-8577-c7454f82f56b create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.13-54-12.04660296-7ce3-4dc0-ba16-8b688a41df11 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.13-54-21.5c142673-7f02-4f59-becd-f8a8458197b8 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.13-59-27.f2e76b1c-d22b-469f-a693-39b6af0b0fcc create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.14-01-43.8f7a6d8f-112e-49d0-b426-5391c93f8986 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.14-02-44.e5d30aa7-20da-4772-b99b-9c0f6fef9a98 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.14-04-32.75533ba0-3cde-4ff1-8c00-9bbb2d28d8c8 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.14-36-18.ffba9911-051f-4f00-8da7-a20a9d5a754b create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.14-36-24.36e7b540-e50e-4572-a869-d16cab440b1d create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-04-11.b47795e9-b7d8-46a9-ae91-efc4733dca39 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-27-29.a5c546a7-8774-4128-a2ae-519ed5135e08 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-28-35.6fcf7282-da2c-4ef5-a851-7a8615d2f238 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-28-41.f7e5dabb-dc3e-4608-9610-42173d36f15d create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-28-42.556f96b6-7809-4d22-826f-b68d99f4657b create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-43-49.91a5a50d-8533-4e3f-9930-9752252ca014 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-44-13.f096514b-1984-4004-a4c7-7357441b2e56 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-44-24.8b339ad9-121a-463b-bb42-ab39db214d4b create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-44-34.64fe6b5c-294f-4773-9d30-846867a15716 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-45-14.00ff237f-e9cc-45de-841a-06797fb7be10 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-45-14.fd8a6a99-18e3-4527-aaca-41237dadadfc create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-46-48.4c0a2f29-52b9-4bc3-977e-1c0a9ee7fbef create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-46-49.9783d6ab-e408-4aba-b29c-86a5d5ef3cc7 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-47-30.81ec9fb0-adcd-47f6-9fb5-4185913ed1bf create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-47-53.ec10d560-0784-42a2-a0fe-bdc477d9543b create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-48-08.f52ea77b-61b3-4c5f-afc8-f5c7d7fc7967 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-48-13.4c033311-3c6a-4e28-b43b-3ab4b0113751 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-49-21.e9d59f2b-d9ff-456e-b69f-6285fd2b696d create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-49-22.57c52698-0974-40c8-8da5-11c393e0cb95 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-49-28.b53d2050-8e27-4d65-bdb0-4a1b51017307 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-49-52.7dd8f18e-944d-4deb-959c-ba8634d43f2a create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-54-10.3fcf7b45-3ff9-4842-86ff-dad45dc4e871 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-55-46.19a4455f-b08f-4716-88e3-98cf0d4856eb create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-55-58.09ce167e-6a0a-4e67-976d-f3dccbda7f15 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-56-46.7d37504e-8bed-49bc-9490-f5fd8fb3b2d6 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-59-23.cbd147d7-275d-49c8-bb62-f5710fa6b182 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-59-23.e413e2b4-dab0-46b3-b1bc-6ab7fd342cdc create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-01-15.0cd2182e-7b39-417a-84a8-250066cf9933 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-01-55.64367cde-c27f-4b2a-bda0-a84ef1b4d4bd create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-02-09.5dce232c-a705-443a-b8b5-58d38143b62b create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-02-36.a04ceeb1-5428-4d88-b3e6-0249fd5788c4 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-04-41.7845f5bf-3033-4ccd-8e10-6b6ec04f9eff create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-05-40.b7856e30-d3cd-43a1-bcf7-e6a4d3896509 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-05-40.e2f6d53f-6653-4115-810c-e3f4420d4879 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-05-57.6f691dd5-7b64-4b52-aec9-2e810baea65e create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-25-42.13ccbdf1-f384-4c6f-9aea-a4faf099756b create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-26-10.47595aed-16ca-4978-96c5-ae56ae864a4b create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-48-18.80a55e8c-2eb7-4457-85eb-3a997bc501fa create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-59-05.36baa7de-e574-4590-bb7f-c26ebf50e515 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.17-03-27.189a68a0-fc12-4f03-9cb7-e1029c150c54 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.17-05-50.b676e5f7-60ef-4992-b0b7-fb392b0fab28 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.17-10-03.b76dcefe-bb84-428b-bd3b-928234f99a7e create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.17-11-50.c3b53257-9058-4328-9baa-b1492fe0229f create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.17-24-59.3ec330fb-a77c-491e-9a69-03899200aed8 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.20-23-38.cb988dbf-e441-49c9-aa7d-ef4ea39edc8f create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.20-28-47.eb0b29f6-b68c-43b8-94a3-5a91137462fc create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-02-02.0b9ba78e-4c73-4ed1-b359-6c4a418425e7 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-02-07.fd4ace61-2bd0-41c6-99ae-c2700d2b078a create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-03-36.59e9c8bd-1146-4be6-9401-294912f73db5 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-07-02.01e76216-c3bb-4665-85e7-5e6e9f39340d create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-15-12.b3c35513-a088-42d2-ba59-6e7b9c782316 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-20-13.c387dc8d-1ab5-4c8a-adf0-5c8d3995af73 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-21-18.2de1bbbf-d96a-4478-be19-d65c64d8d855 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-23-48.ba3ca114-2052-4345-8bb5-91f4d94b1752 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-24-23.9f96565e-6e8c-47f5-ba6a-5778d179287c create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-26-19.bbd61739-7ba5-4a26-904b-d4538eb0ab77 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-29-04.a76c77d4-350b-49ac-8234-514173e08b4d create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-29-41.b0b49118-b1bd-4c60-99d7-6adcd31bab06 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-30-06.52b5a733-2ee0-4f9e-8085-56c589e0e428 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-34-58.2919a1e8-b4f0-4b65-8545-3348930435bd create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-41-13.a240c4ba-af3f-496b-b49f-edc5be6ca5f6 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-41-51.0aca82ca-19f5-477e-bb53-231cd0676262 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-44-19.6909fe36-2c71-4e6b-801b-4b10c6639104 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-58-28.cc9c6866-9411-43a0-bfd3-f5c184e91df2 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-59-26.5cda7368-af7e-4821-9551-e4a63c66515c create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-59-58.c999da0e-6456-442d-8965-cc2de92f0a24 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-00-32.059eb584-594d-442d-aa10-39e01d88bd38 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-05-37.47604380-9ee5-49b0-9cf3-91702816db8b create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-06-39.dacbe8e8-e39b-4bfa-9402-ad6667d992a9 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-06-54.01d228ed-55a4-482f-9d85-799e46d8f496 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-07-24.9e28c885-9705-42f7-a586-8e8bf33058fe create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-07-40.0bf85b3c-af57-41b9-aec6-32821fa6b25d create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-07-53.849ed3c0-87a0-417c-8c75-9df7f330e7b5 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-08-05.1b7ec789-952e-4ecf-bcc8-60b1631f8b81 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.07-30-57.f4714898-671c-4f2c-8b8e-7a6b8c5f06ae create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.07-38-42.099ed67b-9672-41ae-a0c5-0fe251bf11a9 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.07-41-04.1f8690ed-aac3-4a21-b1fc-57791e303d19 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-15-41.ea6d2041-094b-49ef-bc93-33ecdcc3e79b create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-19-32.6fbe9345-a360-411f-8c29-b534cd8690e0 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-22-40.023ae398-07f4-4b3f-90a1-481b3c4b3c00 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-24-42.f7b373a3-4254-4f43-895e-c6ec34004a4a create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-29-03.1c9b8f34-d7c2-49a8-b5b5-0e2895e4db4e create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-32-42.0762d17c-76e0-468d-83bb-acbedd3e0e39 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-38-19.d804f946-3776-428e-ab85-8abe4747f2bd create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-38-46.857a877d-3dee-4bcd-a2fa-d0d3eb6988e3 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-10-54.00af0054-046e-4db4-90e7-bdec8baaea3c create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-11-20.4528f3cf-8a45-4a61-8537-1f8323b876c0 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-13-46.d8b4b653-2531-42c0-aea9-ae7d45b688b8 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-17-05.4d34eeca-bbf3-4340-aa15-b4fbc1f327f7 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-18-26.80b9fe72-c085-4a2e-aad2-3d3782b91f71 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-18-43.5d399fbd-6813-4f00-a84f-8b4848e0f3ac create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-19-03.79712761-a6ab-4d7f-93ef-8fd908e91c55 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-19-22.f20443f6-2c6a-44df-93b2-30984320c7d8 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-19-30.e188909e-d416-4a0f-83f7-24b5b8b446f1 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-19-55.f3486e48-a46b-4b1d-9766-322d984ab403 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-20-59.a438a8ee-87fb-4c00-b300-5785e2b34fc5 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-21-13.c8881e31-9041-40b3-9b56-75af994d315e create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-22-50.6ca44238-476a-4e60-a011-a3957354ae63 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-25-18.a7715c2e-8aea-43ca-a2bb-1a1bc2abf4ec create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-25-33.c08338aa-9678-448b-a0c6-4a3857eb7a5e create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-37-26.91dd915f-96bc-4e97-ac3f-631b5e47fc97 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-39-46.60f70d02-7dd2-4150-9fb4-7bbf66d37dc4 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-56-48.779ad15d-f9cb-4edb-9c0b-56a9a8f12acc create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-57-42.e1353019-1e13-4c2f-90c4-19bbc31e04e4 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-01-01.038b136a-cea0-412b-88c7-467ec747a1c2 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-04-47.4e2bcd0c-1a67-4cf1-a142-cdef04d5394f create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-04-52.8b0edbf8-188e-4ef2-8bee-e2997d063642 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-28-30.3fa30d1c-a386-4198-84b5-8c1ea0872793 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-39-36.c4c9a367-eb3e-4ad6-a8e1-6174d152c58b create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-44-24.ecb2667a-270f-492f-904c-5790ffeea5fd create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-48-35.fde81767-cf3d-48f8-9b83-0fa821b65225 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-49-34.a9415e50-a09f-4afd-8480-a16f11b976d8 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-51-52.823fdac2-9f46-4212-beda-f01da85617ee create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-56-00.fe65e955-02bd-4cdc-83c0-2738da8552bd create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-12-54.90b0fa07-b98f-448d-a5b9-4f162df1c934 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-15-02.7fe4a98f-554e-40ec-95d8-0a89969062a6 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-21-19.f45f242f-db32-41fd-a6d2-49fbbc3db4bb create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-22-43.f236fc4a-5ffc-4951-8b09-fc87b13aa493 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-37-46.8ff165c3-169b-4fe0-8943-33268bac342e create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-38-27.9e9533f3-2040-4380-896a-f07d12be3ad1 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-39-48.cb629b5b-b6e0-4981-865e-08e1ce2d7144 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-57-02.84349f26-13d3-414a-abed-4f41b121c461 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-58-40.02fe98af-d9a8-45f8-8043-639a1cd6f2fa create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-00-27.613a119a-0ba5-453a-9a33-57e1c58e2a45 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-01-44.9e59b647-658d-4421-ae22-a190c64bfe1b create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-02-37.c1142121-3382-4594-83bc-a3b9308934fc create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-03-42.3c3cd596-1ccb-4f9c-8c32-cd19025ffd4f create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-03-43.d0b4f48a-9dd9-44ba-a63c-64bb97ba554a create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-03-45.33a89a0c-4c2a-48ec-b408-2510e4955953 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-03-50.6269acaa-fd38-4447-9e73-6069412873f0 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-11-05.73b365fe-f13f-4c3f-b11d-e53a45441ddb create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-11-48.01e44a61-c972-484b-b3aa-f74d6e69e3f4 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-16-50.3e136a9b-0940-4a33-974f-2f92641aa949 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-16-57.436c807c-5074-4991-9b08-f749854a201a create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-23-55.ef12ccd5-6a87-4915-a2e6-6311dff79d62 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-24-12.f06cfd75-143b-4067-af17-9d7bd3f2ffff create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-35-54.b4ea48c0-9572-44ab-a2bd-5835208e72d4 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-44-42.762a4cbe-9fd4-429b-ad90-65afd6cfa2f7 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-44-51.5f6b97d4-f2db-44ff-b5a0-c0f44a7ae176 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-47-26.cea36215-6c4f-4c24-b68a-9fa628c4095a create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-47-53.8099e445-0191-4ba0-893c-0386f0015323 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-49-20.f6ac2903-4ac8-494a-a317-8d9a12efd0ca create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-58-55.3ec51b6c-4923-461a-a237-f93384d4a5dd create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-05-32.31f8dead-8462-4aa9-8261-8282ab1ab771 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-27-09.2797c058-322a-4512-b0de-38cf90383715 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-36-42.e8767d84-83ff-4302-ae92-1614609e7f6a create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-42-19.091ca44b-ec9b-43b0-bc59-d7f510cb7196 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-43-25.aaba2dbc-357e-47ec-b9f2-3edea03a9b11 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-44-19.84f7abe3-18fe-4f9b-a4b7-d8596f94e745 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-44-24.a3cc5eb0-12d6-42cb-9edb-1dd1ea099be4 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.15-39-52.78464803-e59b-4281-abde-3d9d9ba30b48 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.15-45-28.d03a6dea-77d5-4c23-968b-10584836bcfe create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.15-46-03.06370395-4251-4ae6-9451-f4f0c8a8360c create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.15-55-43.353ebf99-44a3-4394-b8c0-d124d53b7261 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.16-12-59.611f4e4c-c450-49a6-94ae-2d5da784db45 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.16-13-29.ede170a4-af38-44b8-84f2-1dacf2e878cf create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-24.16-14-39.315150f0-6b1c-45a7-87d6-a7392658336b create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-02-25.d6a63215-ff4c-4e8d-b71f-0659e31a4c51 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-03-10.8ae61366-bacc-4809-b5b5-baf0e30a7fe3 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-03-19.7a82fece-b4ca-4815-a7ce-11eae326b3a6 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-05-05.23021373-02eb-419f-bd2e-c7b583f6a8d2 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-05-08.7916431d-3acb-4a7a-a60c-32e78a641411 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-06-10.4ac1637e-5f02-429d-88d8-578007e1888c create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-07-16.553808ae-96e0-4aae-9dcf-e20697568be5 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-08-05.00e6160b-f867-439d-afee-21f5a2a5fc8e create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-08-57.98ec4506-1d72-4711-bd06-e340a7e0c79a create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-09-22.8caf72a1-2f42-4991-bf4d-bd33bba63c59 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-09-34.afec10d7-3824-499d-bbaf-276de70b3d87 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-09-41.832aeb08-c4dc-41bc-9391-8de5b0317053 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-10-09.6bcc0e58-a110-47a4-b9b6-cb7946f4f502 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-13-41.476ab4ad-3c08-47ce-9ece-15c067a40fff create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-14-30.69b37db6-d641-46a7-aa9e-244648ac1286 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-15-40.c8b163ae-744e-4d7c-a430-61bdc80ebd87 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-16-49.4a4fd7fe-cd96-40c0-8553-ebe34c5adff7 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-27-50.a2c2c6c9-43ff-407c-a879-470acd711175 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-42-41.91d05dfd-c594-47aa-ad9b-272756af2f28 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-43-33.3f9c933e-96cb-487b-9057-731ef99df91d create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-53-29.38843298-d223-4ae2-957e-6bd410bbaaa4 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-58-56.60d0f3ea-7fbb-4b9a-90fe-751f620d8048 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-02-59.39add73b-deca-4b57-b448-9aeba108bb41 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-04-31.aaa03c9b-657e-4f8c-a933-ad5582570937 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-05-02.fa395f45-73e8-4ca2-8e4c-48209c73d459 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-06-15.77652992-fce3-4e80-945b-c735eb163038 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-07-12.132807a5-f507-428f-8605-fbd5fbcdfbec create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-09-28.2a653b8a-d7ab-41d3-b51b-c1f0187e093d create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-09-31.953fa082-038a-4d3d-9991-e2244f844fd8 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-10-43.f904246c-b69a-4c66-a870-bae6abc2eefc create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-12-33.f82834a1-af69-409c-b737-c8c4945ecc19 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-12-49.00ad86af-27cb-406f-8205-b6c4888e0488 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-13-22.93478285-44ba-461a-b0f2-82323013df66 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-14-29.d2c0dc37-32a3-4f4e-ae26-ac6e1a57f559 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-19-55.dc2245da-3bc3-4942-a146-6e8e0881cd6f create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-20-21.ad008041-2415-4d80-844f-3877e2b95366 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-20-45.98aaf16b-b5b2-46ce-a976-183c7c2db441 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-33-54.f26cedfa-f99e-4e59-89fc-d9f540d46be6 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-34-43.ab9f45de-b3cf-4f84-968e-db929cbf8d4f create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-35-10.df605b80-98e0-475b-9cc6-734e4bda05ef create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-35-38.6031b2a4-afbd-4526-9954-b90f5726a2b3 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-22-49.5bf3d5d5-8470-4062-b60c-430b0a9324d5 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-25-27.fddcdc13-fbc1-4ea9-b973-7ad52f72e5e2 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-25-40.b26b714d-b34a-469f-9711-71bbc4b4c87f create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-25-52.f4ce8ead-bf69-44d7-ad4c-d37e82b27262 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-27-08.37769d06-1bd1-4ed2-8261-01021011a4ce create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-28-46.a83d25c8-3c52-4de7-8161-7b3458958b62 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-29-11.42987dac-81f9-425a-95fb-f1480209eec7 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-31-09.9ba3c512-1afe-4804-bce8-7f3045cbb1ec create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-31-28.b65aad29-b9c7-4d94-8f3e-e1e85df927a1 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-33-13.e9cae406-ac2c-452f-a3b0-410ed9627864 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-35-13.70c4b5df-9b5b-4a0e-879b-30a4c10a50b3 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-35-32.d61a4243-a147-4607-952c-33ff8a7c3c1b create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-35-53.9396c4f0-dcb1-4bb5-86e0-651b9c426f64 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-36-10.4b60b067-1e28-4f1f-89cb-c85be3ad678e create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-45-21.a77fcd2f-d2d4-4d68-ab0c-5b9ac8334211 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-47-24.5c391f77-5c16-44ef-8ef1-cccaf2d7e509 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-49-26.d3b60944-aa93-47c6-912e-c41ac302479e create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-49-53.b975ddf0-d822-4e87-8b62-0cf6f40e56e3 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-50-18.41b82968-5b82-4c33-8b97-5f0e8e543e30 create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-51-00.b0142219-1bc4-417e-aa09-7995210816dd create mode 100644 web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-51-12.f46779db-4627-4bc1-bd17-988a79ce4bc8 create mode 100644 web2py/applications/SP/languages/ar.py create mode 100644 web2py/applications/SP/languages/ca.py create mode 100644 web2py/applications/SP/languages/cs.py create mode 100644 web2py/applications/SP/languages/de.py create mode 100644 web2py/applications/SP/languages/en.py create mode 100644 web2py/applications/SP/languages/es.py create mode 100644 web2py/applications/SP/languages/fr-ca.py create mode 100644 web2py/applications/SP/languages/fr.py create mode 100644 web2py/applications/SP/languages/hi.py create mode 100644 web2py/applications/SP/languages/hu.py create mode 100644 web2py/applications/SP/languages/id.py create mode 100644 web2py/applications/SP/languages/it.py create mode 100644 web2py/applications/SP/languages/my-mm.py create mode 100644 web2py/applications/SP/languages/my.py create mode 100644 web2py/applications/SP/languages/nl.py create mode 100644 web2py/applications/SP/languages/pl.py create mode 100644 web2py/applications/SP/languages/plural-cs.py create mode 100644 web2py/applications/SP/languages/plural-en.py create mode 100644 web2py/applications/SP/languages/plural-es.py create mode 100644 web2py/applications/SP/languages/plural-ru.py create mode 100644 web2py/applications/SP/languages/plural-uk.py create mode 100644 web2py/applications/SP/languages/pt-br.py create mode 100644 web2py/applications/SP/languages/pt.py create mode 100644 web2py/applications/SP/languages/ro.py create mode 100644 web2py/applications/SP/languages/ru.py create mode 100644 web2py/applications/SP/languages/sk.py create mode 100644 web2py/applications/SP/languages/tr.py create mode 100644 web2py/applications/SP/languages/uk.py create mode 100644 web2py/applications/SP/languages/zh-cn.py create mode 100644 web2py/applications/SP/languages/zh-tw.py create mode 100644 web2py/applications/SP/languages/zh.py create mode 100644 web2py/applications/SP/models/db.py create mode 100644 web2py/applications/SP/models/menu.py create mode 100644 web2py/applications/SP/models/user.py create mode 100644 web2py/applications/SP/modules/__init__.py create mode 100644 web2py/applications/SP/private/appconfig.ini create mode 100644 web2py/applications/SP/routes.example.py create mode 100644 web2py/applications/SP/sessions/00c/0e7/127.0.0.1-3a55a2c1-03d7-4d77-a0f0-7c5167c6ffaf create mode 100644 web2py/applications/SP/sessions/00d/0f4/127.0.0.1-c5e4640f-cd25-49f7-a9b4-ec61b28e19fb create mode 100644 web2py/applications/SP/sessions/05a/1f5/127.0.0.1-8f845cf0-8676-4057-ac7e-9c22692bdee9 create mode 100644 web2py/applications/SP/sessions/078/122/127.0.0.1-33e760f6-e988-4855-bc05-acaa70a2a64b create mode 100644 web2py/applications/SP/sessions/0e4/1ba/127.0.0.1-eda8a93c-17b3-4956-83d4-6145f10125d9 create mode 100644 web2py/applications/SP/sessions/10d/091/127.0.0.1-f08a2093-f7db-4845-b460-0836a90b02c4 create mode 100644 web2py/applications/SP/sessions/124/0ee/127.0.0.1-1f01e76d-a832-47ba-b184-eebd13ddb4cc create mode 100644 web2py/applications/SP/sessions/127/192/127.0.0.1-144c5c8d-bf7d-440c-b952-879db22d2a07 create mode 100644 web2py/applications/SP/sessions/130/151/127.0.0.1-f7b40c44-2670-4091-809e-f8e292d361d8 create mode 100644 web2py/applications/SP/sessions/13e/046/127.0.0.1-a4b375ce-9ef2-4cb8-b721-1eaff15515ba create mode 100644 web2py/applications/SP/sessions/156/086/127.0.0.1-64331f4a-020d-4190-a0cd-db51c3091d10 create mode 100644 web2py/applications/SP/sessions/15a/0e7/127.0.0.1-d444ca1d-5c94-4268-b5d4-f84120a0f1c2 create mode 100644 web2py/applications/SP/sessions/15d/1ba/127.0.0.1-bdb65a41-a01f-4d6a-b6b2-37f998787c20 create mode 100644 web2py/applications/SP/sessions/15e/1f6/127.0.0.1-d684f46e-042a-42ba-92cd-3d4a5fd5e6e5 create mode 100644 web2py/applications/SP/sessions/163/02a/127.0.0.1-3992ba2e-ef94-4ddc-8768-75f185e714c5 create mode 100644 web2py/applications/SP/sessions/176/091/127.0.0.1-03f20c11-1674-436d-9256-7d3cdf2e9c6b create mode 100644 web2py/applications/SP/sessions/17c/0b9/127.0.0.1-da5509be-5e08-4d6e-8704-82183b494f1e create mode 100644 web2py/applications/SP/sessions/187/11f/127.0.0.1-7fdbcdd4-97a7-4348-b7ac-df2372d0a84c create mode 100644 web2py/applications/SP/sessions/18b/0eb/127.0.0.1-df1a50b7-edf5-446c-a054-b101a381e7ee create mode 100644 web2py/applications/SP/sessions/18d/0e8/127.0.0.1-540d2395-25f8-4a5a-b8cd-00b5d5a08207 create mode 100644 web2py/applications/SP/sessions/18e/0e6/127.0.0.1-317bc46a-dbc3-4a32-93ea-e8b53f02ae19 create mode 100644 web2py/applications/SP/sessions/190/0ef/127.0.0.1-efdbf1a4-bdcc-4cb9-9117-a756917f9703 create mode 100644 web2py/applications/SP/sessions/1d2/1c9/127.0.0.1-b33d3d8c-220e-4e99-ac6e-1d9d4b7eebdc create mode 100644 web2py/applications/SP/static/403.html create mode 100644 web2py/applications/SP/static/404.html create mode 100644 web2py/applications/SP/static/500.html create mode 100644 web2py/applications/SP/static/503.html create mode 100644 web2py/applications/SP/static/css/bootstrap.min.css create mode 100644 web2py/applications/SP/static/css/bootstrap.min.css.map create mode 100644 web2py/applications/SP/static/css/calendar.css create mode 100644 web2py/applications/SP/static/css/web2py-bootstrap4.css create mode 100644 web2py/applications/SP/static/css/web2py.css create mode 100644 web2py/applications/SP/static/images/facebook.png create mode 100644 web2py/applications/SP/static/images/favicon.ico create mode 100644 web2py/applications/SP/static/images/favicon.png create mode 100644 web2py/applications/SP/static/images/gplus-32.png create mode 100644 web2py/applications/SP/static/images/twitter.png create mode 100644 web2py/applications/SP/static/js/analytics.min.js create mode 100644 web2py/applications/SP/static/js/bootstrap.bundle.min.js create mode 100644 web2py/applications/SP/static/js/bootstrap.bundle.min.js.map create mode 100644 web2py/applications/SP/static/js/calendar.js create mode 100644 web2py/applications/SP/static/js/jquery.js create mode 100644 web2py/applications/SP/static/js/modernizr-2.8.3.min.js create mode 100644 web2py/applications/SP/static/js/web2py-bootstrap4.js create mode 100644 web2py/applications/SP/static/js/web2py.js create mode 100644 web2py/applications/SP/views/__init__.py create mode 100644 web2py/applications/SP/views/appadmin/appadmin.html create mode 100644 web2py/applications/SP/views/appadmin/change_userinfo.html create mode 100644 web2py/applications/SP/views/default/change_settings.html create mode 100644 web2py/applications/SP/views/default/index.html create mode 100644 web2py/applications/SP/views/default/monitorctl.html create mode 100644 web2py/applications/SP/views/default/myclass.html create mode 100644 web2py/applications/SP/views/default/myhome.html create mode 100644 web2py/applications/SP/views/default/task.html create mode 100644 web2py/applications/SP/views/default/user.html create mode 100644 web2py/applications/SP/views/generic.html create mode 100644 web2py/applications/SP/views/generic.ics create mode 100644 web2py/applications/SP/views/generic.json create mode 100644 web2py/applications/SP/views/generic.jsonp create mode 100644 web2py/applications/SP/views/generic.load create mode 100644 web2py/applications/SP/views/generic.map create mode 100644 web2py/applications/SP/views/generic.pdf create mode 100644 web2py/applications/SP/views/generic.rss create mode 100644 web2py/applications/SP/views/generic.xml create mode 100644 web2py/applications/SP/views/layout.html create mode 100644 web2py/applications/SP/views/web2py_ajax.html create mode 100644 web2py/applications/__init__.py create mode 100644 web2py/applications/admin/ABOUT create mode 100644 web2py/applications/admin/LICENSE create mode 100644 web2py/applications/admin/__init__.py create mode 100644 web2py/applications/admin/controllers/appadmin.py create mode 100644 web2py/applications/admin/controllers/debug.py create mode 100644 web2py/applications/admin/controllers/default.py create mode 100644 web2py/applications/admin/controllers/gae.py create mode 100644 web2py/applications/admin/controllers/mercurial.py create mode 100644 web2py/applications/admin/controllers/openshift.py create mode 100644 web2py/applications/admin/controllers/plugin_jqmobile.py create mode 100644 web2py/applications/admin/controllers/pythonanywhere.py create mode 100644 web2py/applications/admin/controllers/toolbar.py create mode 100644 web2py/applications/admin/controllers/webservices.py create mode 100644 web2py/applications/admin/controllers/wizard.py create mode 100644 web2py/applications/admin/cron/crontab create mode 100644 web2py/applications/admin/cron/expire_sessions.py create mode 100644 web2py/applications/admin/errors/127.0.0.1.2018-09-22.18-10-57.651cbadf-fbcf-432a-b809-60471a5a6391 create mode 100644 web2py/applications/admin/errors/127.0.0.1.2018-09-22.18-12-47.2de91eb7-be71-4410-8c6f-f0addca46ccd create mode 100644 web2py/applications/admin/languages/af.py create mode 100644 web2py/applications/admin/languages/bg.py create mode 100644 web2py/applications/admin/languages/cs.py create mode 100644 web2py/applications/admin/languages/de.py create mode 100644 web2py/applications/admin/languages/en.py create mode 100644 web2py/applications/admin/languages/es.py create mode 100644 web2py/applications/admin/languages/fr.py create mode 100644 web2py/applications/admin/languages/he.py create mode 100644 web2py/applications/admin/languages/it.py create mode 100644 web2py/applications/admin/languages/ja.py create mode 100644 web2py/applications/admin/languages/my-mm.py create mode 100644 web2py/applications/admin/languages/nl.py create mode 100644 web2py/applications/admin/languages/pl.py create mode 100644 web2py/applications/admin/languages/plural-en.py create mode 100644 web2py/applications/admin/languages/plural-ru.py create mode 100644 web2py/applications/admin/languages/plural-uk.py create mode 100644 web2py/applications/admin/languages/pt-br.py create mode 100644 web2py/applications/admin/languages/pt.py create mode 100644 web2py/applications/admin/languages/ro.py create mode 100644 web2py/applications/admin/languages/ru.py create mode 100644 web2py/applications/admin/languages/sl.py create mode 100644 web2py/applications/admin/languages/sr-cr.py create mode 100644 web2py/applications/admin/languages/sr-lt.py create mode 100644 web2py/applications/admin/languages/tr.py create mode 100644 web2py/applications/admin/languages/uk.py create mode 100644 web2py/applications/admin/languages/zh-tw.py create mode 100644 web2py/applications/admin/languages/zh.py create mode 100644 web2py/applications/admin/models/0.py create mode 100644 web2py/applications/admin/models/0_imports.py create mode 100644 web2py/applications/admin/models/access.py create mode 100644 web2py/applications/admin/models/buttons.py create mode 100644 web2py/applications/admin/models/db.py create mode 100644 web2py/applications/admin/models/menu.py create mode 100644 web2py/applications/admin/models/plugin_multiselect.py create mode 100644 web2py/applications/admin/models/plugin_statebutton.py create mode 100644 web2py/applications/admin/modules/__init__.py create mode 100644 web2py/applications/admin/private/hosts.deny create mode 100644 web2py/applications/admin/sessions/037/09c/127.0.0.1-1c8a258c-88c4-42f9-b14c-8f5ca542f25b create mode 100644 web2py/applications/admin/sessions/05c/195/127.0.0.1-81403135-39d2-41f5-b406-83f384553319 create mode 100644 web2py/applications/admin/sessions/0c9/0f5/127.0.0.1-d4a94174-7f7f-434d-a74d-a7246b977b53 create mode 100644 web2py/applications/admin/sessions/0dc/1e5/127.0.0.1-0f21193f-ae22-4031-8fd5-7502aeac37b7 create mode 100644 web2py/applications/admin/sessions/10d/1c5/127.0.0.1-35682bd4-e9cf-4132-a1ee-1a04633eae7e create mode 100644 web2py/applications/admin/sessions/127.0.0.1-0f21193f-ae22-4031-8fd5-7502aeac37b7 create mode 100644 web2py/applications/admin/sessions/127.0.0.1-35682bd4-e9cf-4132-a1ee-1a04633eae7e create mode 100644 web2py/applications/admin/sessions/127.0.0.1-7d4172c5-b4c3-41ec-a61b-eb366480f74d create mode 100644 web2py/applications/admin/sessions/127.0.0.1-d4a94174-7f7f-434d-a74d-a7246b977b53 create mode 100644 web2py/applications/admin/sessions/127.0.0.1-dfc090b6-f2b7-41a3-88e4-1e2f94a9ee5f create mode 100644 web2py/applications/admin/sessions/179/0e6/127.0.0.1-dfc090b6-f2b7-41a3-88e4-1e2f94a9ee5f create mode 100644 web2py/applications/admin/sessions/1f0/1bf/127.0.0.1-7d4172c5-b4c3-41ec-a61b-eb366480f74d create mode 100644 web2py/applications/admin/sessions/1fa/0ef/127.0.0.1-0e0da4c9-9dc5-4402-9af8-3f8637da4614 create mode 100644 web2py/applications/admin/settings.cfg create mode 100644 web2py/applications/admin/static/codemirror/addon/comment/comment.js create mode 100644 web2py/applications/admin/static/codemirror/addon/comment/continuecomment.js create mode 100644 web2py/applications/admin/static/codemirror/addon/dialog/dialog.css create mode 100644 web2py/applications/admin/static/codemirror/addon/dialog/dialog.js create mode 100644 web2py/applications/admin/static/codemirror/addon/display/fullscreen.css create mode 100644 web2py/applications/admin/static/codemirror/addon/display/fullscreen.js create mode 100644 web2py/applications/admin/static/codemirror/addon/display/panel.js create mode 100644 web2py/applications/admin/static/codemirror/addon/display/placeholder.js create mode 100644 web2py/applications/admin/static/codemirror/addon/display/rulers.js create mode 100644 web2py/applications/admin/static/codemirror/addon/edit/closebrackets.js create mode 100644 web2py/applications/admin/static/codemirror/addon/edit/closetag.js create mode 100644 web2py/applications/admin/static/codemirror/addon/edit/continuelist.js create mode 100644 web2py/applications/admin/static/codemirror/addon/edit/matchbrackets.js create mode 100644 web2py/applications/admin/static/codemirror/addon/edit/matchtags.js create mode 100644 web2py/applications/admin/static/codemirror/addon/edit/trailingspace.js create mode 100644 web2py/applications/admin/static/codemirror/addon/fold/brace-fold.js create mode 100644 web2py/applications/admin/static/codemirror/addon/fold/comment-fold.js create mode 100644 web2py/applications/admin/static/codemirror/addon/fold/foldcode.js create mode 100644 web2py/applications/admin/static/codemirror/addon/fold/foldgutter.css create mode 100644 web2py/applications/admin/static/codemirror/addon/fold/foldgutter.js create mode 100644 web2py/applications/admin/static/codemirror/addon/fold/indent-fold.js create mode 100644 web2py/applications/admin/static/codemirror/addon/fold/markdown-fold.js create mode 100644 web2py/applications/admin/static/codemirror/addon/fold/xml-fold.js create mode 100644 web2py/applications/admin/static/codemirror/addon/hint/anyword-hint.js create mode 100644 web2py/applications/admin/static/codemirror/addon/hint/css-hint.js create mode 100644 web2py/applications/admin/static/codemirror/addon/hint/html-hint.js create mode 100644 web2py/applications/admin/static/codemirror/addon/hint/javascript-hint.js create mode 100644 web2py/applications/admin/static/codemirror/addon/hint/python-hint.js create mode 100644 web2py/applications/admin/static/codemirror/addon/hint/show-hint.css create mode 100644 web2py/applications/admin/static/codemirror/addon/hint/show-hint.js create mode 100644 web2py/applications/admin/static/codemirror/addon/hint/sql-hint.js create mode 100644 web2py/applications/admin/static/codemirror/addon/hint/xml-hint.js create mode 100644 web2py/applications/admin/static/codemirror/addon/mode/loadmode.js create mode 100644 web2py/applications/admin/static/codemirror/addon/mode/multiplex.js create mode 100644 web2py/applications/admin/static/codemirror/addon/mode/multiplex_test.js create mode 100644 web2py/applications/admin/static/codemirror/addon/mode/overlay.js create mode 100644 web2py/applications/admin/static/codemirror/addon/mode/simple.js create mode 100644 web2py/applications/admin/static/codemirror/addon/search/match-highlighter.js create mode 100644 web2py/applications/admin/static/codemirror/addon/search/matchesonscrollbar.css create mode 100644 web2py/applications/admin/static/codemirror/addon/search/matchesonscrollbar.js create mode 100644 web2py/applications/admin/static/codemirror/addon/search/search.js create mode 100644 web2py/applications/admin/static/codemirror/addon/search/searchcursor.js create mode 100644 web2py/applications/admin/static/codemirror/addon/selection/active-line.js create mode 100644 web2py/applications/admin/static/codemirror/addon/selection/mark-selection.js create mode 100644 web2py/applications/admin/static/codemirror/addon/selection/selection-pointer.js create mode 100644 web2py/applications/admin/static/codemirror/emmet.min.js create mode 100644 web2py/applications/admin/static/codemirror/keymap/emacs.js create mode 100644 web2py/applications/admin/static/codemirror/keymap/sublime.js create mode 100644 web2py/applications/admin/static/codemirror/keymap/vim.js create mode 100644 web2py/applications/admin/static/codemirror/lib/codemirror.css create mode 100644 web2py/applications/admin/static/codemirror/lib/codemirror.js create mode 100644 web2py/applications/admin/static/codemirror/mode/css/css.js create mode 100644 web2py/applications/admin/static/codemirror/mode/css/less_test.js create mode 100644 web2py/applications/admin/static/codemirror/mode/css/scss_test.js create mode 100644 web2py/applications/admin/static/codemirror/mode/css/test.js create mode 100644 web2py/applications/admin/static/codemirror/mode/htmlmixed/htmlmixed.js create mode 100644 web2py/applications/admin/static/codemirror/mode/javascript/javascript.js create mode 100644 web2py/applications/admin/static/codemirror/mode/javascript/test.js create mode 100644 web2py/applications/admin/static/codemirror/mode/python/python.js create mode 100644 web2py/applications/admin/static/codemirror/mode/xml/test.js create mode 100644 web2py/applications/admin/static/codemirror/mode/xml/xml.js create mode 100644 web2py/applications/admin/static/codemirror/theme/3024-day.css create mode 100644 web2py/applications/admin/static/codemirror/theme/3024-night.css create mode 100644 web2py/applications/admin/static/codemirror/theme/ambiance-mobile.css create mode 100644 web2py/applications/admin/static/codemirror/theme/ambiance.css create mode 100644 web2py/applications/admin/static/codemirror/theme/base16-dark.css create mode 100644 web2py/applications/admin/static/codemirror/theme/base16-light.css create mode 100644 web2py/applications/admin/static/codemirror/theme/blackboard.css create mode 100644 web2py/applications/admin/static/codemirror/theme/cobalt.css create mode 100644 web2py/applications/admin/static/codemirror/theme/colorforth.css create mode 100644 web2py/applications/admin/static/codemirror/theme/eclipse.css create mode 100644 web2py/applications/admin/static/codemirror/theme/elegant.css create mode 100644 web2py/applications/admin/static/codemirror/theme/erlang-dark.css create mode 100644 web2py/applications/admin/static/codemirror/theme/lesser-dark.css create mode 100644 web2py/applications/admin/static/codemirror/theme/mbo.css create mode 100644 web2py/applications/admin/static/codemirror/theme/mdn-like.css create mode 100644 web2py/applications/admin/static/codemirror/theme/midnight.css create mode 100644 web2py/applications/admin/static/codemirror/theme/monokai.css create mode 100644 web2py/applications/admin/static/codemirror/theme/neat.css create mode 100644 web2py/applications/admin/static/codemirror/theme/neo.css create mode 100644 web2py/applications/admin/static/codemirror/theme/night.css create mode 100644 web2py/applications/admin/static/codemirror/theme/paraiso-dark.css create mode 100644 web2py/applications/admin/static/codemirror/theme/paraiso-light.css create mode 100644 web2py/applications/admin/static/codemirror/theme/pastel-on-dark.css create mode 100644 web2py/applications/admin/static/codemirror/theme/rubyblue.css create mode 100644 web2py/applications/admin/static/codemirror/theme/solarized.css create mode 100644 web2py/applications/admin/static/codemirror/theme/the-matrix.css create mode 100644 web2py/applications/admin/static/codemirror/theme/tomorrow-night-bright.css create mode 100644 web2py/applications/admin/static/codemirror/theme/tomorrow-night-eighties.css create mode 100644 web2py/applications/admin/static/codemirror/theme/twilight.css create mode 100644 web2py/applications/admin/static/codemirror/theme/vibrant-ink.css create mode 100644 web2py/applications/admin/static/codemirror/theme/web2py.css create mode 100644 web2py/applications/admin/static/codemirror/theme/xq-dark.css create mode 100644 web2py/applications/admin/static/codemirror/theme/xq-light.css create mode 100644 web2py/applications/admin/static/codemirror/theme/zenburn.css create mode 100644 web2py/applications/admin/static/css/bootstrap-responsive.min.css create mode 100644 web2py/applications/admin/static/css/bootstrap.min.css create mode 100644 web2py/applications/admin/static/css/bootstrap_essentials.css create mode 100644 web2py/applications/admin/static/css/calendar.css create mode 100644 web2py/applications/admin/static/css/d3_graph.css create mode 100644 web2py/applications/admin/static/css/jqueryMultiSelect.css create mode 100644 web2py/applications/admin/static/css/typeahead.js-bootstrap.css create mode 100644 web2py/applications/admin/static/css/web2py-codemirror.css create mode 100644 web2py/applications/admin/static/images/chat.png create mode 100644 web2py/applications/admin/static/images/delete_icon.png create mode 100644 web2py/applications/admin/static/images/dim_bullet.gif create mode 100644 web2py/applications/admin/static/images/embossed.png create mode 100644 web2py/applications/admin/static/images/files_toggle.png create mode 100644 web2py/applications/admin/static/images/folder.png create mode 100644 web2py/applications/admin/static/images/folder_locked.png create mode 100644 web2py/applications/admin/static/images/folder_sm.png create mode 100644 web2py/applications/admin/static/images/glyphicons-halflings-white.png create mode 100644 web2py/applications/admin/static/images/glyphicons-halflings.png create mode 100644 web2py/applications/admin/static/images/header_bg.png create mode 100644 web2py/applications/admin/static/images/header_shadow.png create mode 100644 web2py/applications/admin/static/images/help.png create mode 100644 web2py/applications/admin/static/images/menu.png create mode 100644 web2py/applications/admin/static/images/menu_responsive.png create mode 100644 web2py/applications/admin/static/images/questions.png create mode 100644 web2py/applications/admin/static/images/red_bullet.gif create mode 100644 web2py/applications/admin/static/images/save_icon.png create mode 100644 web2py/applications/admin/static/images/search.png create mode 100644 web2py/applications/admin/static/images/section_bullet.png create mode 100644 web2py/applications/admin/static/images/sidebar_background.jpg create mode 100644 web2py/applications/admin/static/images/sidebar_bullet.gif create mode 100644 web2py/applications/admin/static/images/small_button.png create mode 100644 web2py/applications/admin/static/images/small_special_button.png create mode 100644 web2py/applications/admin/static/images/spinner.gif create mode 100644 web2py/applications/admin/static/images/start.png create mode 100644 web2py/applications/admin/static/images/test_icon.png create mode 100644 web2py/applications/admin/static/images/ticket_section.png create mode 100644 web2py/applications/admin/static/js/ajax_editor.js create mode 100644 web2py/applications/admin/static/js/analytics.min.js create mode 100644 web2py/applications/admin/static/js/autoscroll.js create mode 100644 web2py/applications/admin/static/js/bootstrap.min.js create mode 100644 web2py/applications/admin/static/js/calendar.js create mode 100644 web2py/applications/admin/static/js/d3.min.js create mode 100644 web2py/applications/admin/static/js/d3_graph.js create mode 100644 web2py/applications/admin/static/js/dd_belatedpng.js create mode 100644 web2py/applications/admin/static/js/hogan-2.0.0.js create mode 100644 web2py/applications/admin/static/js/jquery.flot.js create mode 100644 web2py/applications/admin/static/js/jquery.flot.resize.js create mode 100644 web2py/applications/admin/static/js/jquery.hotkeys.js create mode 100644 web2py/applications/admin/static/js/jquery.js create mode 100644 web2py/applications/admin/static/js/jqueryMultiSelect.js create mode 100644 web2py/applications/admin/static/js/modernizr.custom.js create mode 100644 web2py/applications/admin/static/js/share.js create mode 100644 web2py/applications/admin/static/js/typeahead.min.js create mode 100644 web2py/applications/admin/static/js/web2py.js create mode 100644 web2py/applications/admin/static/js/web2py_bootstrap.js create mode 100644 web2py/applications/admin/static/plugin_jqmobile/dd_belatedpng.js create mode 100644 web2py/applications/admin/static/plugin_jqmobile/images/ajax-loader.png create mode 100644 web2py/applications/admin/static/plugin_jqmobile/images/icons-18-black.png create mode 100644 web2py/applications/admin/static/plugin_jqmobile/images/icons-18-white.png create mode 100644 web2py/applications/admin/static/plugin_jqmobile/images/icons-36-black.png create mode 100644 web2py/applications/admin/static/plugin_jqmobile/images/icons-36-white.png create mode 100644 web2py/applications/admin/static/plugin_jqmobile/images/iphone.jpg create mode 100644 web2py/applications/admin/static/plugin_jqmobile/jquery.mobile-1.2.0.min.css create mode 100644 web2py/applications/admin/static/plugin_jqmobile/jquery.mobile-1.2.0.min.js create mode 100644 web2py/applications/admin/static/plugin_jqmobile/jquery.mobile-1.3.1.min.css create mode 100644 web2py/applications/admin/static/plugin_jqmobile/jquery.mobile-1.3.1.min.js create mode 100644 web2py/applications/admin/static/plugin_multiselect/jquery.multi-select.js create mode 100644 web2py/applications/admin/static/plugin_multiselect/multi-select.css create mode 100644 web2py/applications/admin/static/plugin_multiselect/start.js create mode 100644 web2py/applications/admin/static/plugin_multiselect/switch.png create mode 100644 web2py/applications/admin/static/plugin_statebutton/css/bootstrap-switch.css create mode 100644 web2py/applications/admin/static/plugin_statebutton/js/bootstrap-switch.js create mode 100644 web2py/applications/admin/views/appadmin.html create mode 100644 web2py/applications/admin/views/debug/breakpoints.html create mode 100644 web2py/applications/admin/views/debug/index.html create mode 100644 web2py/applications/admin/views/debug/interact.html create mode 100644 web2py/applications/admin/views/default.mobile/about.html create mode 100644 web2py/applications/admin/views/default.mobile/change_password.html create mode 100644 web2py/applications/admin/views/default.mobile/delete.html create mode 100644 web2py/applications/admin/views/default.mobile/delete_plugin.html create mode 100644 web2py/applications/admin/views/default.mobile/design.html create mode 100644 web2py/applications/admin/views/default.mobile/downgrade_web2py.html create mode 100644 web2py/applications/admin/views/default.mobile/edit.html create mode 100644 web2py/applications/admin/views/default.mobile/edit_language.html create mode 100644 web2py/applications/admin/views/default.mobile/errors.html create mode 100644 web2py/applications/admin/views/default.mobile/git_pull.html create mode 100644 web2py/applications/admin/views/default.mobile/git_push.html create mode 100644 web2py/applications/admin/views/default.mobile/index.html create mode 100644 web2py/applications/admin/views/default.mobile/layout.html create mode 100644 web2py/applications/admin/views/default.mobile/peek.html create mode 100644 web2py/applications/admin/views/default.mobile/plugin.html create mode 100644 web2py/applications/admin/views/default.mobile/resolve.html create mode 100644 web2py/applications/admin/views/default.mobile/site.html create mode 100644 web2py/applications/admin/views/default.mobile/test.html create mode 100644 web2py/applications/admin/views/default.mobile/ticket.html create mode 100644 web2py/applications/admin/views/default.mobile/ticket.load create mode 100644 web2py/applications/admin/views/default.mobile/uninstall.html create mode 100644 web2py/applications/admin/views/default.mobile/upgrade_web2py.html create mode 100644 web2py/applications/admin/views/default.mobile/user.html create mode 100644 web2py/applications/admin/views/default/about.html create mode 100644 web2py/applications/admin/views/default/bulk_register.html create mode 100644 web2py/applications/admin/views/default/change_password.html create mode 100644 web2py/applications/admin/views/default/delete.html create mode 100644 web2py/applications/admin/views/default/delete_plugin.html create mode 100644 web2py/applications/admin/views/default/design.html create mode 100644 web2py/applications/admin/views/default/edit.html create mode 100644 web2py/applications/admin/views/default/edit_js.html create mode 100644 web2py/applications/admin/views/default/edit_language.html create mode 100644 web2py/applications/admin/views/default/edit_plurals.html create mode 100644 web2py/applications/admin/views/default/editor_sessions.html create mode 100644 web2py/applications/admin/views/default/editor_settings.html create mode 100644 web2py/applications/admin/views/default/editor_shortcuts.html create mode 100644 web2py/applications/admin/views/default/errors.html create mode 100644 web2py/applications/admin/views/default/files_menu.html create mode 100644 web2py/applications/admin/views/default/git_pull.html create mode 100644 web2py/applications/admin/views/default/git_push.html create mode 100644 web2py/applications/admin/views/default/index.html create mode 100644 web2py/applications/admin/views/default/install_plugin.html create mode 100644 web2py/applications/admin/views/default/manage_students.html create mode 100644 web2py/applications/admin/views/default/pack_custom.html create mode 100644 web2py/applications/admin/views/default/peek.html create mode 100644 web2py/applications/admin/views/default/plugin.html create mode 100644 web2py/applications/admin/views/default/plugins.html create mode 100644 web2py/applications/admin/views/default/resolve.html create mode 100644 web2py/applications/admin/views/default/site.html create mode 100644 web2py/applications/admin/views/default/test.html create mode 100644 web2py/applications/admin/views/default/ticket.html create mode 100644 web2py/applications/admin/views/default/ticket.load create mode 100644 web2py/applications/admin/views/default/todolist.load create mode 100644 web2py/applications/admin/views/default/twitter.load create mode 100644 web2py/applications/admin/views/default/uninstall.html create mode 100644 web2py/applications/admin/views/default/upgrade_web2py.html create mode 100644 web2py/applications/admin/views/default/user.html create mode 100644 web2py/applications/admin/views/gae/deploy.html create mode 100644 web2py/applications/admin/views/generic.html create mode 100644 web2py/applications/admin/views/layout.html create mode 100644 web2py/applications/admin/views/mercurial/commit.html create mode 100644 web2py/applications/admin/views/mercurial/revision.html create mode 100644 web2py/applications/admin/views/openshift/deploy.html create mode 100644 web2py/applications/admin/views/plugin_jqmobile/about.html create mode 100644 web2py/applications/admin/views/plugin_jqmobile/index.html create mode 100644 web2py/applications/admin/views/plugin_jqmobile/layout.html create mode 100644 web2py/applications/admin/views/pythonanywhere/deploy.html create mode 100644 web2py/applications/admin/views/toolbar/index.html create mode 100644 web2py/applications/admin/views/web2py_ajax.html create mode 100644 web2py/applications/admin/views/wizard/generated.html create mode 100644 web2py/applications/admin/views/wizard/step.html create mode 100644 web2py/applications/examples/ABOUT create mode 100644 web2py/applications/examples/DISABLED create mode 100644 web2py/applications/examples/LICENSE create mode 100644 web2py/applications/examples/__init__.py create mode 100644 web2py/applications/examples/controllers/ajax_examples.py create mode 100644 web2py/applications/examples/controllers/appadmin.py create mode 100644 web2py/applications/examples/controllers/cache_examples.py create mode 100644 web2py/applications/examples/controllers/default.py create mode 100644 web2py/applications/examples/controllers/form_examples.py create mode 100644 web2py/applications/examples/controllers/global.py create mode 100644 web2py/applications/examples/controllers/layout_examples.py create mode 100644 web2py/applications/examples/controllers/session_examples.py create mode 100644 web2py/applications/examples/controllers/simple_examples.py create mode 100644 web2py/applications/examples/controllers/soap_examples.py create mode 100644 web2py/applications/examples/controllers/spreadsheet.py create mode 100644 web2py/applications/examples/controllers/template_examples.py create mode 100644 web2py/applications/examples/cron/crontab create mode 100644 web2py/applications/examples/languages/README create mode 100644 web2py/applications/examples/models/feeds_reader.py create mode 100644 web2py/applications/examples/models/markmin.py create mode 100644 web2py/applications/examples/models/menu.py create mode 100644 web2py/applications/examples/models/session.py create mode 100644 web2py/applications/examples/private/content/en/default/documentation/community.markmin create mode 100644 web2py/applications/examples/private/content/en/default/documentation/main.markmin create mode 100644 web2py/applications/examples/private/content/en/default/documentation/more.markmin create mode 100644 web2py/applications/examples/private/content/en/default/documentation/official.markmin create mode 100644 web2py/applications/examples/private/content/en/default/index/maincontent.markmin create mode 100644 web2py/applications/examples/private/content/en/default/index/whyweb2py.markmin create mode 100644 web2py/applications/examples/private/content/en/default/usergroups/grouplist.markmin create mode 100644 web2py/applications/examples/private/content/en/default/what/whyweb2py.markmin create mode 100644 web2py/applications/examples/static/403.html create mode 100644 web2py/applications/examples/static/404.html create mode 100644 web2py/applications/examples/static/500.html create mode 100644 web2py/applications/examples/static/503.html create mode 100644 web2py/applications/examples/static/artwork.tar.gz create mode 100644 web2py/applications/examples/static/css/artwork.css create mode 100644 web2py/applications/examples/static/css/calendar.css create mode 100644 web2py/applications/examples/static/css/examples.css create mode 100644 web2py/applications/examples/static/css/stupid.css create mode 100644 web2py/applications/examples/static/css/web2py.css create mode 100644 web2py/applications/examples/static/favicon.ico create mode 100644 web2py/applications/examples/static/images/Stickers1.png create mode 100644 web2py/applications/examples/static/images/Stickers2.png create mode 100644 web2py/applications/examples/static/images/Stickers3.png create mode 100644 web2py/applications/examples/static/images/Stickers4.png create mode 100644 web2py/applications/examples/static/images/Stickers5.png create mode 100644 web2py/applications/examples/static/images/Stickers6.png create mode 100644 web2py/applications/examples/static/images/Stickers7.png create mode 100644 web2py/applications/examples/static/images/Stickers8.png create mode 100644 web2py/applications/examples/static/images/book-4th.png create mode 100644 web2py/applications/examples/static/images/book-5th.png create mode 100644 web2py/applications/examples/static/images/book-recipes.png create mode 100644 web2py/applications/examples/static/images/facebook.png create mode 100644 web2py/applications/examples/static/images/favicon.ico create mode 100644 web2py/applications/examples/static/images/favicon.png create mode 100644 web2py/applications/examples/static/images/gplus-32.png create mode 100644 web2py/applications/examples/static/images/infoworld2012.jpeg create mode 100644 web2py/applications/examples/static/images/logo_bw.png create mode 100644 web2py/applications/examples/static/images/logo_db.png create mode 100644 web2py/applications/examples/static/images/logo_lb.png create mode 100644 web2py/applications/examples/static/images/menu.png create mode 100644 web2py/applications/examples/static/images/poweredby.png create mode 100644 web2py/applications/examples/static/images/questions.png create mode 100644 web2py/applications/examples/static/images/shadow-bottom.png create mode 100644 web2py/applications/examples/static/images/stripes.png create mode 100644 web2py/applications/examples/static/images/tag-cloud-color-small.png create mode 100644 web2py/applications/examples/static/images/twitter.png create mode 100644 web2py/applications/examples/static/images/videos.png create mode 100644 web2py/applications/examples/static/images/web2py_logo.png create mode 100644 web2py/applications/examples/static/js/analytics.min.js create mode 100644 web2py/applications/examples/static/js/calendar.js create mode 100644 web2py/applications/examples/static/js/jquery.js create mode 100644 web2py/applications/examples/static/js/share.js create mode 100644 web2py/applications/examples/static/js/web2py.js create mode 100644 web2py/applications/examples/static/markmin.html create mode 100644 web2py/applications/examples/static/robots.txt create mode 100644 web2py/applications/examples/static/title.png create mode 100644 web2py/applications/examples/static/web2py_cheatsheet.pdf create mode 100644 web2py/applications/examples/static/web2py_contributor_agreement.pdf create mode 100644 web2py/applications/examples/static/web2py_logo.png create mode 100644 web2py/applications/examples/views/ajax_examples/fade.html create mode 100644 web2py/applications/examples/views/ajax_examples/index.html create mode 100644 web2py/applications/examples/views/appadmin.html create mode 100644 web2py/applications/examples/views/cache_examples/generic.html create mode 100644 web2py/applications/examples/views/database_examples/buy.html create mode 100644 web2py/applications/examples/views/database_examples/register_dog.html create mode 100644 web2py/applications/examples/views/database_examples/register_person.html create mode 100644 web2py/applications/examples/views/database_examples/register_product.html create mode 100644 web2py/applications/examples/views/default/changelog.html create mode 100644 web2py/applications/examples/views/default/documentation.html create mode 100644 web2py/applications/examples/views/default/download.html create mode 100644 web2py/applications/examples/views/default/examples.html create mode 100644 web2py/applications/examples/views/default/index.html create mode 100644 web2py/applications/examples/views/default/license.html create mode 100644 web2py/applications/examples/views/default/support.html create mode 100644 web2py/applications/examples/views/default/usergroups.html create mode 100644 web2py/applications/examples/views/default/videos.html create mode 100644 web2py/applications/examples/views/default/what.html create mode 100644 web2py/applications/examples/views/default/who.html create mode 100644 web2py/applications/examples/views/form_examples/form.html create mode 100644 web2py/applications/examples/views/generic.html create mode 100644 web2py/applications/examples/views/generic.json create mode 100644 web2py/applications/examples/views/generic.load create mode 100644 web2py/applications/examples/views/generic.rss create mode 100644 web2py/applications/examples/views/generic.xml create mode 100644 web2py/applications/examples/views/global/vars.html create mode 100644 web2py/applications/examples/views/images_examples/index.html create mode 100644 web2py/applications/examples/views/layout.html create mode 100644 web2py/applications/examples/views/layout_examples/basic.html create mode 100644 web2py/applications/examples/views/layout_examples/civilized.html create mode 100644 web2py/applications/examples/views/layout_examples/layout_civilized.html create mode 100644 web2py/applications/examples/views/layout_examples/layout_sleek.html create mode 100644 web2py/applications/examples/views/layout_examples/slick.html create mode 100644 web2py/applications/examples/views/session_examples/counter.html create mode 100644 web2py/applications/examples/views/simple_examples/ajaxwiki.html create mode 100644 web2py/applications/examples/views/simple_examples/hello3.html create mode 100644 web2py/applications/examples/views/soap_examples/generic.html create mode 100644 web2py/applications/examples/views/spreadsheet/index.html create mode 100644 web2py/applications/examples/views/template_examples/beautify.html create mode 100644 web2py/applications/examples/views/template_examples/escape.html create mode 100644 web2py/applications/examples/views/template_examples/test_def.html create mode 100644 web2py/applications/examples/views/template_examples/test_for.html create mode 100644 web2py/applications/examples/views/template_examples/test_if.html create mode 100644 web2py/applications/examples/views/template_examples/test_try.html create mode 100644 web2py/applications/examples/views/template_examples/variables.html create mode 100644 web2py/applications/examples/views/template_examples/xml.html create mode 100644 web2py/applications/examples/views/web2py_ajax.html create mode 100644 web2py/applications/welcome/ABOUT create mode 100644 web2py/applications/welcome/DISABLED create mode 100644 web2py/applications/welcome/LICENSE create mode 100644 web2py/applications/welcome/__init__.py create mode 100644 web2py/applications/welcome/controllers/appadmin.py create mode 100644 web2py/applications/welcome/controllers/default.py create mode 100644 web2py/applications/welcome/cron/crontab create mode 100644 web2py/applications/welcome/cron/crontab.example create mode 100644 web2py/applications/welcome/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_cas.table create mode 100644 web2py/applications/welcome/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_event.table create mode 100644 web2py/applications/welcome/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_group.table create mode 100644 web2py/applications/welcome/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_membership.table create mode 100644 web2py/applications/welcome/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_permission.table create mode 100644 web2py/applications/welcome/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_user.table create mode 100644 web2py/applications/welcome/databases/sql.log create mode 100644 web2py/applications/welcome/databases/storage.sqlite create mode 100644 web2py/applications/welcome/errors/127.0.0.1.2018-09-23.15-56-32.fefc955a-9a46-4bc3-8ca4-d5816b0a2c0d create mode 100644 web2py/applications/welcome/errors/127.0.0.1.2018-09-23.15-59-09.7f029417-0967-4557-a5a7-2731685f4fed create mode 100644 web2py/applications/welcome/errors/127.0.0.1.2018-09-23.15-59-22.e4fdb3d9-eee4-4157-9821-43eb9f5eaff7 create mode 100644 web2py/applications/welcome/languages/ar.py create mode 100644 web2py/applications/welcome/languages/ca.py create mode 100644 web2py/applications/welcome/languages/cs.py create mode 100644 web2py/applications/welcome/languages/de.py create mode 100644 web2py/applications/welcome/languages/en.py create mode 100644 web2py/applications/welcome/languages/es.py create mode 100644 web2py/applications/welcome/languages/fr-ca.py create mode 100644 web2py/applications/welcome/languages/fr.py create mode 100644 web2py/applications/welcome/languages/hi.py create mode 100644 web2py/applications/welcome/languages/hu.py create mode 100644 web2py/applications/welcome/languages/id.py create mode 100644 web2py/applications/welcome/languages/it.py create mode 100644 web2py/applications/welcome/languages/my-mm.py create mode 100644 web2py/applications/welcome/languages/my.py create mode 100644 web2py/applications/welcome/languages/nl.py create mode 100644 web2py/applications/welcome/languages/pl.py create mode 100644 web2py/applications/welcome/languages/plural-cs.py create mode 100644 web2py/applications/welcome/languages/plural-en.py create mode 100644 web2py/applications/welcome/languages/plural-es.py create mode 100644 web2py/applications/welcome/languages/plural-ru.py create mode 100644 web2py/applications/welcome/languages/plural-uk.py create mode 100644 web2py/applications/welcome/languages/pt-br.py create mode 100644 web2py/applications/welcome/languages/pt.py create mode 100644 web2py/applications/welcome/languages/ro.py create mode 100644 web2py/applications/welcome/languages/ru.py create mode 100644 web2py/applications/welcome/languages/sk.py create mode 100644 web2py/applications/welcome/languages/tr.py create mode 100644 web2py/applications/welcome/languages/uk.py create mode 100644 web2py/applications/welcome/languages/zh-cn.py create mode 100644 web2py/applications/welcome/languages/zh-tw.py create mode 100644 web2py/applications/welcome/languages/zh.py create mode 100644 web2py/applications/welcome/models/db.py create mode 100644 web2py/applications/welcome/models/menu.py create mode 100644 web2py/applications/welcome/modules/__init__.py create mode 100644 web2py/applications/welcome/private/appconfig.ini create mode 100644 web2py/applications/welcome/routes.example.py create mode 100644 web2py/applications/welcome/sessions/079/081/127.0.0.1-bb450c25-c189-45ee-a78a-980f495ebe13 create mode 100644 web2py/applications/welcome/sessions/0a8/119/127.0.0.1-62ae636e-3c30-4565-ba01-0ccb6df89d2f create mode 100644 web2py/applications/welcome/sessions/0e7/028/127.0.0.1-c29755d4-0fe8-482f-ac05-b9a9e8f6c069 create mode 100644 web2py/applications/welcome/static/403.html create mode 100644 web2py/applications/welcome/static/404.html create mode 100644 web2py/applications/welcome/static/500.html create mode 100644 web2py/applications/welcome/static/503.html create mode 100644 web2py/applications/welcome/static/css/bootstrap.min.css create mode 100644 web2py/applications/welcome/static/css/bootstrap.min.css.map create mode 100644 web2py/applications/welcome/static/css/calendar.css create mode 100644 web2py/applications/welcome/static/css/web2py-bootstrap4.css create mode 100644 web2py/applications/welcome/static/css/web2py.css create mode 100644 web2py/applications/welcome/static/images/facebook.png create mode 100644 web2py/applications/welcome/static/images/favicon.ico create mode 100644 web2py/applications/welcome/static/images/favicon.png create mode 100644 web2py/applications/welcome/static/images/gplus-32.png create mode 100644 web2py/applications/welcome/static/images/twitter.png create mode 100644 web2py/applications/welcome/static/js/analytics.min.js create mode 100644 web2py/applications/welcome/static/js/bootstrap.bundle.min.js create mode 100644 web2py/applications/welcome/static/js/bootstrap.bundle.min.js.map create mode 100644 web2py/applications/welcome/static/js/calendar.js create mode 100644 web2py/applications/welcome/static/js/jquery.js create mode 100644 web2py/applications/welcome/static/js/modernizr-2.8.3.min.js create mode 100644 web2py/applications/welcome/static/js/web2py-bootstrap4.js create mode 100644 web2py/applications/welcome/static/js/web2py.js create mode 100644 web2py/applications/welcome/views/__init__.py create mode 100644 web2py/applications/welcome/views/appadmin.html create mode 100644 web2py/applications/welcome/views/default/index.html create mode 100644 web2py/applications/welcome/views/default/user.html create mode 100644 web2py/applications/welcome/views/generic.html create mode 100644 web2py/applications/welcome/views/generic.ics create mode 100644 web2py/applications/welcome/views/generic.json create mode 100644 web2py/applications/welcome/views/generic.jsonp create mode 100644 web2py/applications/welcome/views/generic.load create mode 100644 web2py/applications/welcome/views/generic.map create mode 100644 web2py/applications/welcome/views/generic.pdf create mode 100644 web2py/applications/welcome/views/generic.rss create mode 100644 web2py/applications/welcome/views/generic.xml create mode 100644 web2py/applications/welcome/views/layout.html create mode 100644 web2py/applications/welcome/views/web2py_ajax.html create mode 100644 web2py/examples/README create mode 100644 web2py/examples/app.example.yaml create mode 100644 web2py/examples/appengine_config.example.py create mode 100644 web2py/examples/logging.example.conf create mode 100644 web2py/examples/options_std.py create mode 100644 web2py/examples/queue.example.yaml create mode 100644 web2py/examples/routes.parametric.example.py create mode 100644 web2py/examples/routes.patterns.example.py create mode 100644 web2py/examples/web.config create mode 100644 web2py/extras/build_web2py/README create mode 100644 web2py/extras/build_web2py/setup_app.py create mode 100644 web2py/extras/build_web2py/setup_exe.conf create mode 100644 web2py/extras/build_web2py/setup_exe.py create mode 100644 web2py/extras/icons/splashlogo.gif create mode 100644 web2py/extras/icons/web2py.gif create mode 100644 web2py/extras/icons/web2py.icns create mode 100644 web2py/extras/icons/web2py.ico create mode 100644 web2py/fabfile.py create mode 100644 web2py/gluon/__init__.py create mode 100644 web2py/gluon/_compat.py create mode 100644 web2py/gluon/admin.py create mode 100644 web2py/gluon/authapi.py create mode 100644 web2py/gluon/cache.py create mode 100644 web2py/gluon/cfs.py create mode 100644 web2py/gluon/compileapp.py create mode 100644 web2py/gluon/contenttype.py create mode 100644 web2py/gluon/contrib/AuthorizeNet.py create mode 100644 web2py/gluon/contrib/DowCommerce.py create mode 100644 web2py/gluon/contrib/__init__.py create mode 100644 web2py/gluon/contrib/appconfig.py create mode 100644 web2py/gluon/contrib/autolinks.py create mode 100644 web2py/gluon/contrib/dbg.py create mode 100644 web2py/gluon/contrib/feedparser.py create mode 100644 web2py/gluon/contrib/fpdf/__init__.py create mode 100644 web2py/gluon/contrib/fpdf/fonts.py create mode 100644 web2py/gluon/contrib/fpdf/fpdf.py create mode 100644 web2py/gluon/contrib/fpdf/html.py create mode 100644 web2py/gluon/contrib/fpdf/php.py create mode 100644 web2py/gluon/contrib/fpdf/py3k.py create mode 100644 web2py/gluon/contrib/fpdf/template.py create mode 100644 web2py/gluon/contrib/fpdf/ttfonts.py create mode 100644 web2py/gluon/contrib/gae_memcache.py create mode 100644 web2py/gluon/contrib/gae_retry.py create mode 100644 web2py/gluon/contrib/gateways/__init__.py create mode 100644 web2py/gluon/contrib/gateways/fcgi.py create mode 100644 web2py/gluon/contrib/generics.py create mode 100644 web2py/gluon/contrib/google_wallet.py create mode 100644 web2py/gluon/contrib/heroku.py create mode 100644 web2py/gluon/contrib/hypermedia.py create mode 100644 web2py/gluon/contrib/imageutils.py create mode 100644 web2py/gluon/contrib/ipaddress.py create mode 100644 web2py/gluon/contrib/login_methods/__init__.py create mode 100644 web2py/gluon/contrib/login_methods/basic_auth.py create mode 100644 web2py/gluon/contrib/login_methods/browserid_account.py create mode 100644 web2py/gluon/contrib/login_methods/cas_auth.py create mode 100644 web2py/gluon/contrib/login_methods/dropbox_account.py create mode 100644 web2py/gluon/contrib/login_methods/email_auth.py create mode 100644 web2py/gluon/contrib/login_methods/extended_login_form.py create mode 100644 web2py/gluon/contrib/login_methods/gae_google_account.py create mode 100644 web2py/gluon/contrib/login_methods/janrain_account.py create mode 100644 web2py/gluon/contrib/login_methods/ldap_auth.py create mode 100644 web2py/gluon/contrib/login_methods/linkedin_account.py create mode 100644 web2py/gluon/contrib/login_methods/loginradius_account.py create mode 100644 web2py/gluon/contrib/login_methods/loginza.py create mode 100644 web2py/gluon/contrib/login_methods/motp_auth.py create mode 100644 web2py/gluon/contrib/login_methods/oauth10a_account.py create mode 100644 web2py/gluon/contrib/login_methods/oauth20_account.py create mode 100644 web2py/gluon/contrib/login_methods/oneall_account.py create mode 100644 web2py/gluon/contrib/login_methods/openid_auth.py create mode 100644 web2py/gluon/contrib/login_methods/pam_auth.py create mode 100644 web2py/gluon/contrib/login_methods/rpx_account.py create mode 100644 web2py/gluon/contrib/login_methods/saml2_auth.py create mode 100644 web2py/gluon/contrib/login_methods/x509_auth.py create mode 100644 web2py/gluon/contrib/markdown/LICENSE create mode 100644 web2py/gluon/contrib/markdown/__init__.py create mode 100644 web2py/gluon/contrib/markdown/markdown2.py create mode 100644 web2py/gluon/contrib/markmin/__init__.py create mode 100644 web2py/gluon/contrib/markmin/markmin.html create mode 100644 web2py/gluon/contrib/markmin/markmin.pdf create mode 100644 web2py/gluon/contrib/markmin/markmin2html.py create mode 100644 web2py/gluon/contrib/markmin/markmin2latex.py create mode 100644 web2py/gluon/contrib/markmin/markmin2pdf.py create mode 100644 web2py/gluon/contrib/memcache/ChangeLog create mode 100644 web2py/gluon/contrib/memcache/PKG-INFO create mode 100644 web2py/gluon/contrib/memcache/README create mode 100644 web2py/gluon/contrib/memcache/__init__.py create mode 100644 web2py/gluon/contrib/memcache/memcache.py create mode 100644 web2py/gluon/contrib/memdb.py create mode 100644 web2py/gluon/contrib/minify/__init__.py create mode 100644 web2py/gluon/contrib/minify/cssmin.py create mode 100644 web2py/gluon/contrib/minify/htmlmin.py create mode 100644 web2py/gluon/contrib/minify/jsmin.py create mode 100644 web2py/gluon/contrib/minify/minify.py create mode 100644 web2py/gluon/contrib/ordereddict.py create mode 100644 web2py/gluon/contrib/pam.py create mode 100644 web2py/gluon/contrib/paymentech.py create mode 100644 web2py/gluon/contrib/pbkdf2.py create mode 100644 web2py/gluon/contrib/pbkdf2_ctypes.py create mode 100644 web2py/gluon/contrib/pdfinvoice.py create mode 100644 web2py/gluon/contrib/plural_rules/__init__.py create mode 100644 web2py/gluon/contrib/plural_rules/af.py create mode 100644 web2py/gluon/contrib/plural_rules/ar.py create mode 100644 web2py/gluon/contrib/plural_rules/bg.py create mode 100644 web2py/gluon/contrib/plural_rules/ca.py create mode 100644 web2py/gluon/contrib/plural_rules/cs.py create mode 100644 web2py/gluon/contrib/plural_rules/de.py create mode 100644 web2py/gluon/contrib/plural_rules/en.py create mode 100644 web2py/gluon/contrib/plural_rules/es.py create mode 100644 web2py/gluon/contrib/plural_rules/fr.py create mode 100644 web2py/gluon/contrib/plural_rules/he.py create mode 100644 web2py/gluon/contrib/plural_rules/hi.py create mode 100644 web2py/gluon/contrib/plural_rules/hu.py create mode 100644 web2py/gluon/contrib/plural_rules/id.py create mode 100644 web2py/gluon/contrib/plural_rules/it.py create mode 100644 web2py/gluon/contrib/plural_rules/ja.py create mode 100644 web2py/gluon/contrib/plural_rules/lt.py create mode 100644 web2py/gluon/contrib/plural_rules/my.py create mode 100644 web2py/gluon/contrib/plural_rules/nl.py create mode 100644 web2py/gluon/contrib/plural_rules/pl.py create mode 100644 web2py/gluon/contrib/plural_rules/pt.py create mode 100644 web2py/gluon/contrib/plural_rules/ro.py create mode 100644 web2py/gluon/contrib/plural_rules/ru.py create mode 100644 web2py/gluon/contrib/plural_rules/sk.py create mode 100644 web2py/gluon/contrib/plural_rules/sl.py create mode 100644 web2py/gluon/contrib/plural_rules/tr.py create mode 100644 web2py/gluon/contrib/plural_rules/uk.py create mode 100644 web2py/gluon/contrib/plural_rules/zh.py create mode 100644 web2py/gluon/contrib/populate.py create mode 100644 web2py/gluon/contrib/pyaes/LICENSE.txt create mode 100644 web2py/gluon/contrib/pyaes/README.md create mode 100644 web2py/gluon/contrib/pyaes/__init__.py create mode 100644 web2py/gluon/contrib/pyaes/aes.py create mode 100644 web2py/gluon/contrib/pyaes/blockfeeder.py create mode 100644 web2py/gluon/contrib/pyaes/util.py create mode 100644 web2py/gluon/contrib/pyfpdf.py create mode 100644 web2py/gluon/contrib/pymysql/CHANGELOG create mode 100644 web2py/gluon/contrib/pymysql/LICENSE create mode 100644 web2py/gluon/contrib/pymysql/README.rst create mode 100644 web2py/gluon/contrib/pymysql/__init__.py create mode 100644 web2py/gluon/contrib/pymysql/_compat.py create mode 100644 web2py/gluon/contrib/pymysql/_socketio.py create mode 100644 web2py/gluon/contrib/pymysql/charset.py create mode 100644 web2py/gluon/contrib/pymysql/connections.py create mode 100644 web2py/gluon/contrib/pymysql/constants/CLIENT.py create mode 100644 web2py/gluon/contrib/pymysql/constants/COMMAND.py create mode 100644 web2py/gluon/contrib/pymysql/constants/CR.py create mode 100644 web2py/gluon/contrib/pymysql/constants/ER.py create mode 100644 web2py/gluon/contrib/pymysql/constants/FIELD_TYPE.py create mode 100644 web2py/gluon/contrib/pymysql/constants/FLAG.py create mode 100644 web2py/gluon/contrib/pymysql/constants/SERVER_STATUS.py create mode 100644 web2py/gluon/contrib/pymysql/constants/__init__.py create mode 100644 web2py/gluon/contrib/pymysql/converters.py create mode 100644 web2py/gluon/contrib/pymysql/cursors.py create mode 100644 web2py/gluon/contrib/pymysql/err.py create mode 100644 web2py/gluon/contrib/pymysql/optionfile.py create mode 100644 web2py/gluon/contrib/pymysql/tests/__init__.py create mode 100644 web2py/gluon/contrib/pymysql/tests/base.py create mode 100644 web2py/gluon/contrib/pymysql/tests/data/load_local_data.txt create mode 100644 web2py/gluon/contrib/pymysql/tests/data/load_local_warn_data.txt create mode 100644 web2py/gluon/contrib/pymysql/tests/test_DictCursor.py create mode 100644 web2py/gluon/contrib/pymysql/tests/test_SSCursor.py create mode 100644 web2py/gluon/contrib/pymysql/tests/test_basic.py create mode 100644 web2py/gluon/contrib/pymysql/tests/test_connection.py create mode 100644 web2py/gluon/contrib/pymysql/tests/test_converters.py create mode 100644 web2py/gluon/contrib/pymysql/tests/test_cursor.py create mode 100644 web2py/gluon/contrib/pymysql/tests/test_err.py create mode 100644 web2py/gluon/contrib/pymysql/tests/test_example.py create mode 100644 web2py/gluon/contrib/pymysql/tests/test_issues.py create mode 100644 web2py/gluon/contrib/pymysql/tests/test_load_local.py create mode 100644 web2py/gluon/contrib/pymysql/tests/test_nextset.py create mode 100644 web2py/gluon/contrib/pymysql/tests/test_optionfile.py create mode 100644 web2py/gluon/contrib/pymysql/tests/thirdparty/__init__.py create mode 100644 web2py/gluon/contrib/pymysql/tests/thirdparty/test_MySQLdb/__init__.py create mode 100644 web2py/gluon/contrib/pymysql/tests/thirdparty/test_MySQLdb/capabilities.py create mode 100644 web2py/gluon/contrib/pymysql/tests/thirdparty/test_MySQLdb/dbapi20.py create mode 100644 web2py/gluon/contrib/pymysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_capabilities.py create mode 100644 web2py/gluon/contrib/pymysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_dbapi20.py create mode 100644 web2py/gluon/contrib/pymysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_nonstandard.py create mode 100644 web2py/gluon/contrib/pymysql/times.py create mode 100644 web2py/gluon/contrib/pymysql/util.py create mode 100644 web2py/gluon/contrib/pypyodbc.py create mode 100644 web2py/gluon/contrib/pyrtf/Constants.py create mode 100644 web2py/gluon/contrib/pyrtf/Elements.py create mode 100644 web2py/gluon/contrib/pyrtf/PropertySets.py create mode 100644 web2py/gluon/contrib/pyrtf/README create mode 100644 web2py/gluon/contrib/pyrtf/Renderer.py create mode 100644 web2py/gluon/contrib/pyrtf/Styles.py create mode 100644 web2py/gluon/contrib/pyrtf/__init__.py create mode 100644 web2py/gluon/contrib/pysimplesoap/__init__.py create mode 100644 web2py/gluon/contrib/pysimplesoap/c14n.py create mode 100644 web2py/gluon/contrib/pysimplesoap/client.py create mode 100644 web2py/gluon/contrib/pysimplesoap/helpers.py create mode 100644 web2py/gluon/contrib/pysimplesoap/plugins.py create mode 100644 web2py/gluon/contrib/pysimplesoap/server.py create mode 100644 web2py/gluon/contrib/pysimplesoap/simplexml.py create mode 100644 web2py/gluon/contrib/pysimplesoap/transport.py create mode 100644 web2py/gluon/contrib/pysimplesoap/wsse.py create mode 100644 web2py/gluon/contrib/pysimplesoap/xmlsec.py create mode 100644 web2py/gluon/contrib/pyuca/LICENSE create mode 100644 web2py/gluon/contrib/pyuca/README.markmin create mode 100644 web2py/gluon/contrib/pyuca/__init__.py create mode 100644 web2py/gluon/contrib/pyuca/allkeys.txt create mode 100644 web2py/gluon/contrib/pyuca/pyuca.py create mode 100644 web2py/gluon/contrib/redis_cache.py create mode 100644 web2py/gluon/contrib/redis_scheduler.py create mode 100644 web2py/gluon/contrib/redis_session.py create mode 100644 web2py/gluon/contrib/redis_utils.py create mode 100644 web2py/gluon/contrib/rss2.py create mode 100644 web2py/gluon/contrib/shell.py create mode 100644 web2py/gluon/contrib/simplejson.py create mode 100644 web2py/gluon/contrib/simplejsonrpc.py create mode 100644 web2py/gluon/contrib/sms_utils.py create mode 100644 web2py/gluon/contrib/spreadsheet.py create mode 100644 web2py/gluon/contrib/stripe.py create mode 100644 web2py/gluon/contrib/taskbar_widget.py create mode 100644 web2py/gluon/contrib/timecollect.py create mode 100644 web2py/gluon/contrib/user_agent_parser.py create mode 100644 web2py/gluon/contrib/webclient.py create mode 100644 web2py/gluon/contrib/websocket_messaging.py create mode 100644 web2py/gluon/custom_import.py create mode 100644 web2py/gluon/dal.py create mode 100644 web2py/gluon/debug.py create mode 100644 web2py/gluon/decoder.py create mode 100644 web2py/gluon/fileutils.py create mode 100644 web2py/gluon/globals.py create mode 100644 web2py/gluon/highlight.py create mode 100644 web2py/gluon/html.py create mode 100644 web2py/gluon/http.py create mode 100644 web2py/gluon/import_all.py create mode 100644 web2py/gluon/languages.py create mode 100644 web2py/gluon/main.py create mode 100644 web2py/gluon/messageboxhandler.py create mode 100644 web2py/gluon/myregex.py create mode 100644 web2py/gluon/newcron.py create mode 100644 web2py/gluon/packages/dal/.codecov.yml create mode 100644 web2py/gluon/packages/dal/.coveragerc create mode 100644 web2py/gluon/packages/dal/.travis.yml create mode 100644 web2py/gluon/packages/dal/AUTHORS create mode 100644 web2py/gluon/packages/dal/CHANGES create mode 100644 web2py/gluon/packages/dal/LICENSE create mode 100644 web2py/gluon/packages/dal/MANIFEST.in create mode 100644 web2py/gluon/packages/dal/README.md create mode 100644 web2py/gluon/packages/dal/appveyor.yml create mode 100644 web2py/gluon/packages/dal/docs/Makefile create mode 100644 web2py/gluon/packages/dal/docs/conf.py create mode 100644 web2py/gluon/packages/dal/docs/index.rst create mode 100644 web2py/gluon/packages/dal/docs/pydal.adapters.rst create mode 100644 web2py/gluon/packages/dal/docs/pydal.helpers.rst create mode 100644 web2py/gluon/packages/dal/docs/requirements.txt create mode 100644 web2py/gluon/packages/dal/pydal/__init__.py create mode 100644 web2py/gluon/packages/dal/pydal/_compat.py create mode 100644 web2py/gluon/packages/dal/pydal/_gae.py create mode 100644 web2py/gluon/packages/dal/pydal/_globals.py create mode 100644 web2py/gluon/packages/dal/pydal/_load.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/__init__.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/base.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/couchdb.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/db2.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/firebird.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/google.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/informix.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/ingres.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/mongo.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/mssql.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/mysql.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/oracle.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/postgres.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/sap.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/sqlite.py create mode 100644 web2py/gluon/packages/dal/pydal/adapters/teradata.py create mode 100644 web2py/gluon/packages/dal/pydal/base.py create mode 100644 web2py/gluon/packages/dal/pydal/connection.py create mode 100644 web2py/gluon/packages/dal/pydal/contrib/__init__.py create mode 100644 web2py/gluon/packages/dal/pydal/contrib/imap_adapter.py create mode 100644 web2py/gluon/packages/dal/pydal/contrib/mockimaplib.py create mode 100644 web2py/gluon/packages/dal/pydal/contrib/ordereddict.py create mode 100644 web2py/gluon/packages/dal/pydal/contrib/portalocker.py create mode 100644 web2py/gluon/packages/dal/pydal/contrib/reserved_sql_keywords.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/__init__.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/base.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/couchdb.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/db2.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/firebird.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/google.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/informix.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/ingres.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/mongo.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/mssql.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/mysql.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/oracle.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/postgre.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/sap.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/sqlite.py create mode 100644 web2py/gluon/packages/dal/pydal/dialects/teradata.py create mode 100644 web2py/gluon/packages/dal/pydal/drivers.py create mode 100644 web2py/gluon/packages/dal/pydal/exceptions.py create mode 100644 web2py/gluon/packages/dal/pydal/helpers/__init__.py create mode 100644 web2py/gluon/packages/dal/pydal/helpers/_internals.py create mode 100644 web2py/gluon/packages/dal/pydal/helpers/classes.py create mode 100644 web2py/gluon/packages/dal/pydal/helpers/gae.py create mode 100644 web2py/gluon/packages/dal/pydal/helpers/methods.py create mode 100644 web2py/gluon/packages/dal/pydal/helpers/regex.py create mode 100644 web2py/gluon/packages/dal/pydal/helpers/rest.py create mode 100644 web2py/gluon/packages/dal/pydal/helpers/serializers.py create mode 100644 web2py/gluon/packages/dal/pydal/migrator.py create mode 100644 web2py/gluon/packages/dal/pydal/objects.py create mode 100644 web2py/gluon/packages/dal/pydal/parsers/__init__.py create mode 100644 web2py/gluon/packages/dal/pydal/parsers/base.py create mode 100644 web2py/gluon/packages/dal/pydal/parsers/google.py create mode 100644 web2py/gluon/packages/dal/pydal/parsers/mongo.py create mode 100644 web2py/gluon/packages/dal/pydal/parsers/postgre.py create mode 100644 web2py/gluon/packages/dal/pydal/parsers/sqlite.py create mode 100644 web2py/gluon/packages/dal/pydal/representers/__init__.py create mode 100644 web2py/gluon/packages/dal/pydal/representers/base.py create mode 100644 web2py/gluon/packages/dal/pydal/representers/couchdb.py create mode 100644 web2py/gluon/packages/dal/pydal/representers/db2.py create mode 100644 web2py/gluon/packages/dal/pydal/representers/google.py create mode 100644 web2py/gluon/packages/dal/pydal/representers/informix.py create mode 100644 web2py/gluon/packages/dal/pydal/representers/mongo.py create mode 100644 web2py/gluon/packages/dal/pydal/representers/mssql.py create mode 100644 web2py/gluon/packages/dal/pydal/representers/mysql.py create mode 100644 web2py/gluon/packages/dal/pydal/representers/oracle.py create mode 100644 web2py/gluon/packages/dal/pydal/representers/postgre.py create mode 100644 web2py/gluon/packages/dal/pydal/representers/sqlite.py create mode 100644 web2py/gluon/packages/dal/pydal/utils.py create mode 100644 web2py/gluon/packages/dal/setup.cfg create mode 100644 web2py/gluon/packages/dal/setup.py create mode 100644 web2py/gluon/packages/dal/tests/__init__.py create mode 100644 web2py/gluon/packages/dal/tests/_adapt.py create mode 100644 web2py/gluon/packages/dal/tests/_compat.py create mode 100644 web2py/gluon/packages/dal/tests/_helpers.py create mode 100644 web2py/gluon/packages/dal/tests/base.py create mode 100644 web2py/gluon/packages/dal/tests/caching.py create mode 100644 web2py/gluon/packages/dal/tests/contribs.py create mode 100644 web2py/gluon/packages/dal/tests/indexes.py create mode 100644 web2py/gluon/packages/dal/tests/nosql.py create mode 100644 web2py/gluon/packages/dal/tests/smart_query.py create mode 100644 web2py/gluon/packages/dal/tests/sql.py create mode 100644 web2py/gluon/packages/dal/tests/validation.py create mode 100644 web2py/gluon/packages/dal/tox.ini create mode 100644 web2py/gluon/recfile.py create mode 100644 web2py/gluon/restricted.py create mode 100644 web2py/gluon/rewrite.py create mode 100644 web2py/gluon/rocket.py create mode 100644 web2py/gluon/rocket.py.footer create mode 100644 web2py/gluon/sanitizer.py create mode 100644 web2py/gluon/scheduler.py create mode 100644 web2py/gluon/serializers.py create mode 100644 web2py/gluon/settings.py create mode 100644 web2py/gluon/shell.py create mode 100644 web2py/gluon/sql.py create mode 100644 web2py/gluon/sqlhtml.py create mode 100644 web2py/gluon/storage.py create mode 100644 web2py/gluon/streamer.py create mode 100644 web2py/gluon/template.py create mode 100644 web2py/gluon/tests/__init__.py create mode 100644 web2py/gluon/tests/coverage.ini create mode 100644 web2py/gluon/tests/fix_path.py create mode 100644 web2py/gluon/tests/test_appadmin.py create mode 100644 web2py/gluon/tests/test_authapi.py create mode 100644 web2py/gluon/tests/test_cache.py create mode 100644 web2py/gluon/tests/test_compileapp.py create mode 100644 web2py/gluon/tests/test_contenttype.py create mode 100644 web2py/gluon/tests/test_contribs.py create mode 100644 web2py/gluon/tests/test_cron.py create mode 100644 web2py/gluon/tests/test_dal.py create mode 100644 web2py/gluon/tests/test_fileutils.py create mode 100644 web2py/gluon/tests/test_globals.py create mode 100644 web2py/gluon/tests/test_html.py create mode 100644 web2py/gluon/tests/test_http.py create mode 100644 web2py/gluon/tests/test_is_url.py create mode 100644 web2py/gluon/tests/test_languages.py create mode 100644 web2py/gluon/tests/test_old_doctests.py create mode 100644 web2py/gluon/tests/test_recfile.py create mode 100644 web2py/gluon/tests/test_rocket.py create mode 100644 web2py/gluon/tests/test_router.py create mode 100644 web2py/gluon/tests/test_routes.py create mode 100644 web2py/gluon/tests/test_scheduler.py create mode 100644 web2py/gluon/tests/test_serializers.py create mode 100644 web2py/gluon/tests/test_sqlhtml.py create mode 100644 web2py/gluon/tests/test_storage.py create mode 100644 web2py/gluon/tests/test_template.py create mode 100644 web2py/gluon/tests/test_tools.py create mode 100644 web2py/gluon/tests/test_utils.py create mode 100644 web2py/gluon/tests/test_validators.py create mode 100644 web2py/gluon/tests/test_web.py create mode 100644 web2py/gluon/tools.py create mode 100644 web2py/gluon/utf8.py create mode 100644 web2py/gluon/utils.py create mode 100644 web2py/gluon/validators.py create mode 100644 web2py/gluon/widget.py create mode 100644 web2py/gluon/xmlrpc.py create mode 100644 web2py/handlers/README create mode 100644 web2py/handlers/cgihandler.py create mode 100644 web2py/handlers/fcgihandler.py create mode 100644 web2py/handlers/gaehandler.py create mode 100644 web2py/handlers/isapiwsgihandler.py create mode 100644 web2py/handlers/modpythonhandler.py create mode 100644 web2py/handlers/scgihandler.py create mode 100644 web2py/handlers/web2py_on_gevent.py create mode 100644 web2py/handlers/wsgihandler.py create mode 100644 web2py/httpserver.log create mode 100644 web2py/parameters_8000.py create mode 100644 web2py/scripts/autoroutes.py create mode 100644 web2py/scripts/check_lang_progress.py create mode 100644 web2py/scripts/contentparser.py create mode 100644 web2py/scripts/cpdb.py create mode 100644 web2py/scripts/cpplugin.py create mode 100644 web2py/scripts/dict_diff.py create mode 100644 web2py/scripts/drop-pgsql-tables.sh create mode 100644 web2py/scripts/extract_mssql_models.py create mode 100644 web2py/scripts/extract_mysql_models.py create mode 100644 web2py/scripts/extract_oracle_models.py create mode 100644 web2py/scripts/extract_pgsql_models.py create mode 100644 web2py/scripts/extract_sqlite_models.py create mode 100644 web2py/scripts/fixws.py create mode 100644 web2py/scripts/import_static.py create mode 100644 web2py/scripts/lang_update_from_langfile.py create mode 100644 web2py/scripts/make_min_web2py.py create mode 100644 web2py/scripts/parse_top_level_domains.py create mode 100644 web2py/scripts/rmorphans.py create mode 100644 web2py/scripts/sessions2trash.py create mode 100644 web2py/scripts/setup-scheduler-centos.sh create mode 100644 web2py/scripts/setup-web2py-centos7.sh create mode 100644 web2py/scripts/setup-web2py-cloudfoundry.sh create mode 100644 web2py/scripts/setup-web2py-debian-sid.sh create mode 100644 web2py/scripts/setup-web2py-fedora-ami.sh create mode 100644 web2py/scripts/setup-web2py-fedora.sh create mode 100644 web2py/scripts/setup-web2py-heroku.sh create mode 100644 web2py/scripts/setup-web2py-nginx-uwsgi-centos64.sh create mode 100644 web2py/scripts/setup-web2py-nginx-uwsgi-centos7.sh create mode 100644 web2py/scripts/setup-web2py-nginx-uwsgi-on-centos.sh create mode 100644 web2py/scripts/setup-web2py-nginx-uwsgi-opensuse.sh create mode 100644 web2py/scripts/setup-web2py-nginx-uwsgi-ubuntu.sh create mode 100644 web2py/scripts/setup-web2py-ubuntu.sh create mode 100644 web2py/scripts/standalone_exe_cxfreeze.py create mode 100644 web2py/scripts/sync_languages.py create mode 100644 web2py/scripts/tickets2db.py create mode 100644 web2py/scripts/tickets2email.py create mode 100644 web2py/scripts/tickets2slack.py create mode 100644 web2py/scripts/update-web2py.sh create mode 100644 web2py/scripts/update_languages.py create mode 100644 web2py/scripts/web2py-lock.sh create mode 100644 web2py/scripts/web2py.archlinux.sh create mode 100644 web2py/scripts/web2py.fedora.sh create mode 100644 web2py/scripts/web2py.ubuntu.sh create mode 100644 web2py/scripts/zip_static_files.py create mode 100644 web2py/site-packages/__init__.py create mode 100644 web2py/web2py.py create mode 100644 web2py/welcome.w2p diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..dff6863 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,14 @@ + + + + + sqlite.xerial + true + org.sqlite.JDBC + jdbc:sqlite:$PROJECT_DIR$/web2py/applications/welcome/databases/storage.sqlite + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..aafd885 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..aeb7613 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/untitled.iml b/.idea/untitled.iml new file mode 100644 index 0000000..8fcf25e --- /dev/null +++ b/.idea/untitled.iml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/bin/activate b/bin/activate new file mode 100644 index 0000000..f364337 --- /dev/null +++ b/bin/activate @@ -0,0 +1,76 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r + fi + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + if [ ! "$1" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="/Users/huyibing/PycharmProjects/untitled" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + if [ "x(untitled) " != x ] ; then + PS1="(untitled) ${PS1:-}" + else + if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" + else + PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" + fi + fi + export PS1 +fi + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r +fi diff --git a/bin/activate.csh b/bin/activate.csh new file mode 100644 index 0000000..f108a84 --- /dev/null +++ b/bin/activate.csh @@ -0,0 +1,37 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/Users/huyibing/PycharmProjects/untitled" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + if ("untitled" != "") then + set env_name = "untitled" + else + if (`basename "VIRTUAL_ENV"` == "__") then + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` + else + set env_name = `basename "$VIRTUAL_ENV"` + endif + endif + set prompt = "[$env_name] $prompt" + unset env_name +endif + +alias pydoc python -m pydoc + +rehash diff --git a/bin/activate.fish b/bin/activate.fish new file mode 100644 index 0000000..5f2aaf9 --- /dev/null +++ b/bin/activate.fish @@ -0,0 +1,75 @@ +# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) +# you cannot run it directly + +function deactivate -d "Exit virtualenv and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + functions -e fish_prompt + set -e _OLD_FISH_PROMPT_OVERRIDE + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + + set -e VIRTUAL_ENV + if test "$argv[1]" != "nondestructive" + # Self destruct! + functions -e deactivate + end +end + +# unset irrelevant variables +deactivate nondestructive + +set -gx VIRTUAL_ENV "/Users/huyibing/PycharmProjects/untitled" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# unset PYTHONHOME if set +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # save the current fish_prompt function as the function _old_fish_prompt + functions -c fish_prompt _old_fish_prompt + + # with the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command + set -l old_status $status + + # Prompt override? + if test -n "(untitled) " + printf "%s%s" "(untitled) " (set_color normal) + else + # ...Otherwise, prepend env + set -l _checkbase (basename "$VIRTUAL_ENV") + if test $_checkbase = "__" + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) + else + printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) + end + end + + # Restore the return status of the previous command. + echo "exit $old_status" | . + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" +end diff --git a/bin/easy_install b/bin/easy_install new file mode 100755 index 0000000..a4af548 --- /dev/null +++ b/bin/easy_install @@ -0,0 +1,12 @@ +#!/Users/huyibing/PycharmProjects/untitled/bin/python +# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==39.1.0','console_scripts','easy_install' +__requires__ = 'setuptools==39.1.0' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('setuptools==39.1.0', 'console_scripts', 'easy_install')() + ) diff --git a/bin/easy_install-3.7 b/bin/easy_install-3.7 new file mode 100755 index 0000000..61ee2bb --- /dev/null +++ b/bin/easy_install-3.7 @@ -0,0 +1,12 @@ +#!/Users/huyibing/PycharmProjects/untitled/bin/python +# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==39.1.0','console_scripts','easy_install-3.7' +__requires__ = 'setuptools==39.1.0' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('setuptools==39.1.0', 'console_scripts', 'easy_install-3.7')() + ) diff --git a/bin/pip b/bin/pip new file mode 100755 index 0000000..fa9ba14 --- /dev/null +++ b/bin/pip @@ -0,0 +1,12 @@ +#!/Users/huyibing/PycharmProjects/untitled/bin/python +# EASY-INSTALL-ENTRY-SCRIPT: 'pip==10.0.1','console_scripts','pip' +__requires__ = 'pip==10.0.1' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('pip==10.0.1', 'console_scripts', 'pip')() + ) diff --git a/bin/pip3 b/bin/pip3 new file mode 100755 index 0000000..6f9bbb6 --- /dev/null +++ b/bin/pip3 @@ -0,0 +1,12 @@ +#!/Users/huyibing/PycharmProjects/untitled/bin/python +# EASY-INSTALL-ENTRY-SCRIPT: 'pip==10.0.1','console_scripts','pip3' +__requires__ = 'pip==10.0.1' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('pip==10.0.1', 'console_scripts', 'pip3')() + ) diff --git a/bin/pip3.7 b/bin/pip3.7 new file mode 100755 index 0000000..ead0c40 --- /dev/null +++ b/bin/pip3.7 @@ -0,0 +1,12 @@ +#!/Users/huyibing/PycharmProjects/untitled/bin/python +# EASY-INSTALL-ENTRY-SCRIPT: 'pip==10.0.1','console_scripts','pip3.7' +__requires__ = 'pip==10.0.1' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('pip==10.0.1', 'console_scripts', 'pip3.7')() + ) diff --git a/bin/python b/bin/python new file mode 100755 index 0000000000000000000000000000000000000000..41d2f67bf6582de5993b9eb42dea08a00f393deb GIT binary patch literal 13620 zcmeHOZ){uD6~AU_8=x!+f0ph~sRe{(MT?WtZUHsJZsYPIoDiBc4Ip&$Vn5f07u$P& zP7~ImY;B}?skLZAXlRo_`!E4tW=%}XDlJs&L>Nebx=qV8HdSovUc~+hO{nSw-tXLZ zUu?e^gtU*lSGxC{-#O==d+&Mg_`|u+Z(RBN2iq76e1fsLs~BUg=*wFen`c3AjC~qi zL+5-ra&PpZ=;8ZGTHgZoupuHpYcS+|G&(+7ZzARg>t%9zhP^RtM|85_+%{%x;@sx< zckweg3{-E^VbBQIwI()Ki#gBRg~|Me$nWpxJ6(TCY2jgSLbLR@RSH~xJY|?U!-CB3 zuk&Wt-&tu-SZ>voY}#KuZ(Hfiu?_$A@q1hP`<2uau5ER`q2RobIiAiWcsi5J3S94R zd6&CCdgjy!`+c|?cckaKAf9V~WHeHv3A%o~=eR-X1w*6fig%7R5kTWSWAgm$)MVD= zIokqm>`zW-H6G{^-1)B86<6Pv)y{9r>?6Z#gLAw{hTVtjGneRokk08XFk8FWNug# zo$PNy|FAZW`JZo~{3K*S^zG=OLf#6Q>B&%H)=U6X`z$)`qw~Ozrx(Awr~PL~Z+_~< zXPQE{LDq`SuDeF`-5w?xS|`p+^ZdUPv`z}0bmINrhNp?{uAPnRX6T?{nz|Lr&DyDK zCUj@lm%F+{hb(={IG(j0%ZG-AyesKRLSu%NPiHfEGL>5QJiRsRH0}8_QX)`2BhEQ8 zo41Xrt^-{-Z+a5OXt$%&xh^8^^qjsRF+B&>R0LE6R0LE6R0LE6R0LE6R0LE6R0LE6 zR0LE6R0LE6R0LE6R0RGXB5*`2{v~oWG8P#f(N6uXd!YE9w%FH>Vz^c+l${GG?arTT zIb8;gEgI!m@vqKS6neGdd9C!d{m!e94-{7i=PNCz&yY>A5-VPE{y^eV|E@~xuFG~? zWbVYSO31!itGuS2`cI(n&sg!Y7Fg3tT41iXOKXX~qAkbo9}y*Atr!Vv%eIlR^Pxc< zXot4krRQ>?gV_vFtG4VFj)9uB<-TEA@I&U*eM-m{`ZB4p?IHQY2Qy!-FCJUPlx}OJL&rnLiZNL zXUX?ZX>eYEXRR*)HqYVUq-!*d1*%5x^!9%<9(eg+fYyE(D!3V?C7!3r^XKgD{)Kn| zx_cn3PSc8ibne@5Z*@4m0ITAb1P-ENt2b?jyO$tmJ?EU=WL)ao?;he^Trr#_jiX^4 zEPh2Rom|sa=|Y1!J0U8bcP@c1?!e){sFjYqxq20p*ayr?gXI-5_X;ddU9J>%VaY>q zy#6!<;BN>25<0E>BNClDSq>D2X!1%J*jdGZ6;2bO6&}$Rx4eM~vBhS1U+by#T!^@Mw<0dT_HxyzmZkLr9U2vM}B zvi|P-l}e>!0zN7olVVJWF)7BB7#|g*DaMQ#b7Hi_Xp3=Lj5A_pQ1 z-5u=6vo03GRon1`W6_~89*Z0qI;cetbIx+ve0qlGbNca&u=DcH%SJCpz0CFUIh(1S zs@t}Oi&cA*EN|G8=}gWtk{_W8CiS#wB!YG}7|-TruW4kOH1%WR+7PE>6nJX26pu>W zW$gu}ejfMN)QG41$nCgWY8AI}xG%l7iQIgw)+_Is4@er5bWG9-NgtKemh=fp7bN|* zq~DYD2a=X0JuB%iBz;}dHAz3#W|fhOfQo>MfQo>MfQo>MfQo>MfQo>MfQo>MfQmp} z1ln%toM?ljEzE~!`9LOZr*$*^xWOKX5bNZe=VOUmS1+n{WHht#|lZ|>1eS;0K;kVC+5Bcx|K0M*WR4=Uc_f;RB_TdvgOm)`U`Dc8X z%C@!oANug?KJ55##fP`SS*^boA8z;Ipbt~6jbcpyOQ4eU)#&&FU3?dhDmc3ioxW*r zL8qrcIe0z#4d^$b(>L<+{{mrp2=vfUgcmiu|J5(tpa{D8E%N;WG)`aqBDjfL^V1;M zYW8}0yYYJ=QrAsdFI~MvtxM5bP)*KF()zS)q;~W1LlV);K>U7*)FVncM^q%+rXM#; SPgr+{Li@hdvv=R#J?y_xV|arA literal 0 HcmV?d00001 diff --git a/bin/python3 b/bin/python3 new file mode 100755 index 0000000000000000000000000000000000000000..41d2f67bf6582de5993b9eb42dea08a00f393deb GIT binary patch literal 13620 zcmeHOZ){uD6~AU_8=x!+f0ph~sRe{(MT?WtZUHsJZsYPIoDiBc4Ip&$Vn5f07u$P& zP7~ImY;B}?skLZAXlRo_`!E4tW=%}XDlJs&L>Nebx=qV8HdSovUc~+hO{nSw-tXLZ zUu?e^gtU*lSGxC{-#O==d+&Mg_`|u+Z(RBN2iq76e1fsLs~BUg=*wFen`c3AjC~qi zL+5-ra&PpZ=;8ZGTHgZoupuHpYcS+|G&(+7ZzARg>t%9zhP^RtM|85_+%{%x;@sx< zckweg3{-E^VbBQIwI()Ki#gBRg~|Me$nWpxJ6(TCY2jgSLbLR@RSH~xJY|?U!-CB3 zuk&Wt-&tu-SZ>voY}#KuZ(Hfiu?_$A@q1hP`<2uau5ER`q2RobIiAiWcsi5J3S94R zd6&CCdgjy!`+c|?cckaKAf9V~WHeHv3A%o~=eR-X1w*6fig%7R5kTWSWAgm$)MVD= zIokqm>`zW-H6G{^-1)B86<6Pv)y{9r>?6Z#gLAw{hTVtjGneRokk08XFk8FWNug# zo$PNy|FAZW`JZo~{3K*S^zG=OLf#6Q>B&%H)=U6X`z$)`qw~Ozrx(Awr~PL~Z+_~< zXPQE{LDq`SuDeF`-5w?xS|`p+^ZdUPv`z}0bmINrhNp?{uAPnRX6T?{nz|Lr&DyDK zCUj@lm%F+{hb(={IG(j0%ZG-AyesKRLSu%NPiHfEGL>5QJiRsRH0}8_QX)`2BhEQ8 zo41Xrt^-{-Z+a5OXt$%&xh^8^^qjsRF+B&>R0LE6R0LE6R0LE6R0LE6R0LE6R0LE6 zR0LE6R0LE6R0LE6R0RGXB5*`2{v~oWG8P#f(N6uXd!YE9w%FH>Vz^c+l${GG?arTT zIb8;gEgI!m@vqKS6neGdd9C!d{m!e94-{7i=PNCz&yY>A5-VPE{y^eV|E@~xuFG~? zWbVYSO31!itGuS2`cI(n&sg!Y7Fg3tT41iXOKXX~qAkbo9}y*Atr!Vv%eIlR^Pxc< zXot4krRQ>?gV_vFtG4VFj)9uB<-TEA@I&U*eM-m{`ZB4p?IHQY2Qy!-FCJUPlx}OJL&rnLiZNL zXUX?ZX>eYEXRR*)HqYVUq-!*d1*%5x^!9%<9(eg+fYyE(D!3V?C7!3r^XKgD{)Kn| zx_cn3PSc8ibne@5Z*@4m0ITAb1P-ENt2b?jyO$tmJ?EU=WL)ao?;he^Trr#_jiX^4 zEPh2Rom|sa=|Y1!J0U8bcP@c1?!e){sFjYqxq20p*ayr?gXI-5_X;ddU9J>%VaY>q zy#6!<;BN>25<0E>BNClDSq>D2X!1%J*jdGZ6;2bO6&}$Rx4eM~vBhS1U+by#T!^@Mw<0dT_HxyzmZkLr9U2vM}B zvi|P-l}e>!0zN7olVVJWF)7BB7#|g*DaMQ#b7Hi_Xp3=Lj5A_pQ1 z-5u=6vo03GRon1`W6_~89*Z0qI;cetbIx+ve0qlGbNca&u=DcH%SJCpz0CFUIh(1S zs@t}Oi&cA*EN|G8=}gWtk{_W8CiS#wB!YG}7|-TruW4kOH1%WR+7PE>6nJX26pu>W zW$gu}ejfMN)QG41$nCgWY8AI}xG%l7iQIgw)+_Is4@er5bWG9-NgtKemh=fp7bN|* zq~DYD2a=X0JuB%iBz;}dHAz3#W|fhOfQo>MfQo>MfQo>MfQo>MfQo>MfQo>MfQmp} z1ln%toM?ljEzE~!`9LOZr*$*^xWOKX5bNZe=VOUmS1+n{WHht#|lZ|>1eS;0K;kVC+5Bcx|K0M*WR4=Uc_f;RB_TdvgOm)`U`Dc8X z%C@!oANug?KJ55##fP`SS*^boA8z;Ipbt~6jbcpyOQ4eU)#&&FU3?dhDmc3ioxW*r zL8qrcIe0z#4d^$b(>L<+{{mrp2=vfUgcmiu|J5(tpa{D8E%N;WG)`aqBDjfL^V1;M zYW8}0yYYJ=QrAsdFI~MvtxM5bP)*KF()zS)q;~W1LlV);K>U7*)FVncM^q%+rXM#; SPgr+{Li@hdvv=R#J?y_xV|arA literal 0 HcmV?d00001 diff --git a/lib/python3.7/site-packages/easy-install.pth b/lib/python3.7/site-packages/easy-install.pth new file mode 100644 index 0000000..7cfbf40 --- /dev/null +++ b/lib/python3.7/site-packages/easy-install.pth @@ -0,0 +1,2 @@ +./setuptools-39.1.0-py3.7.egg +./pip-10.0.1-py3.7.egg diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/PKG-INFO b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/PKG-INFO new file mode 100644 index 0000000..c91d709 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/PKG-INFO @@ -0,0 +1,69 @@ +Metadata-Version: 2.1 +Name: pip +Version: 10.0.1 +Summary: The PyPA recommended tool for installing Python packages. +Home-page: https://pip.pypa.io/ +Author: The pip developers +Author-email: python-virtualenv@groups.google.com +License: MIT +Description: pip + === + + The `PyPA recommended`_ tool for installing Python packages. + + .. image:: https://img.shields.io/pypi/v/pip.svg + :target: https://pypi.org/project/pip/ + + .. image:: https://img.shields.io/travis/pypa/pip/master.svg + :target: http://travis-ci.org/pypa/pip + + .. image:: https://img.shields.io/appveyor/ci/pypa/pip.svg + :target: https://ci.appveyor.com/project/pypa/pip/history + + .. image:: https://readthedocs.org/projects/pip/badge/?version=latest + :target: https://pip.pypa.io/en/latest + + * `Installation`_ + * `Documentation`_ + * `Changelog`_ + * `GitHub Page`_ + * `Issue Tracking`_ + * `User mailing list`_ + * `Dev mailing list`_ + * User IRC: #pypa on Freenode. + * Dev IRC: #pypa-dev on Freenode. + + Code of Conduct + --------------- + + Everyone interacting in the pip project's codebases, issue trackers, chat + rooms and mailing lists is expected to follow the `PyPA Code of Conduct`_. + + .. _PyPA recommended: https://packaging.python.org/en/latest/current/ + .. _Installation: https://pip.pypa.io/en/stable/installing.html + .. _Documentation: https://pip.pypa.io/en/stable/ + .. _Changelog: https://pip.pypa.io/en/stable/news.html + .. _GitHub Page: https://github.com/pypa/pip + .. _Issue Tracking: https://github.com/pypa/pip/issues + .. _User mailing list: http://groups.google.com/group/python-virtualenv + .. _Dev mailing list: http://groups.google.com/group/pypa-dev + .. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ + +Keywords: easy_install distutils setuptools egg virtualenv +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Topic :: Software Development :: Build Tools +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.* +Provides-Extra: testing diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/SOURCES.txt b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/SOURCES.txt new file mode 100644 index 0000000..5a15329 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/SOURCES.txt @@ -0,0 +1,347 @@ +AUTHORS.txt +LICENSE.txt +MANIFEST.in +NEWS.rst +README.rst +pyproject.toml +setup.cfg +setup.py +docs/Makefile +docs/__init__.py +docs/conf.py +docs/configuration.rst +docs/cookbook.rst +docs/development.rst +docs/docutils.conf +docs/index.rst +docs/installing.rst +docs/logic.rst +docs/make.bat +docs/news.rst +docs/pipext.py +docs/quickstart.rst +docs/usage.rst +docs/user_guide.rst +docs/man/pip.rst +docs/man/commands/check.rst +docs/man/commands/config.rst +docs/man/commands/download.rst +docs/man/commands/freeze.rst +docs/man/commands/hash.rst +docs/man/commands/help.rst +docs/man/commands/install.rst +docs/man/commands/list.rst +docs/man/commands/search.rst +docs/man/commands/show.rst +docs/man/commands/uninstall.rst +docs/man/commands/wheel.rst +docs/reference/index.rst +docs/reference/pip.rst +docs/reference/pip_check.rst +docs/reference/pip_config.rst +docs/reference/pip_download.rst +docs/reference/pip_freeze.rst +docs/reference/pip_hash.rst +docs/reference/pip_install.rst +docs/reference/pip_list.rst +docs/reference/pip_search.rst +docs/reference/pip_show.rst +docs/reference/pip_uninstall.rst +docs/reference/pip_wheel.rst +src/pip/__init__.py +src/pip/__main__.py +src/pip.egg-info/PKG-INFO +src/pip.egg-info/SOURCES.txt +src/pip.egg-info/dependency_links.txt +src/pip.egg-info/entry_points.txt +src/pip.egg-info/not-zip-safe +src/pip.egg-info/requires.txt +src/pip.egg-info/top_level.txt +src/pip/_internal/__init__.py +src/pip/_internal/basecommand.py +src/pip/_internal/baseparser.py +src/pip/_internal/build_env.py +src/pip/_internal/cache.py +src/pip/_internal/cmdoptions.py +src/pip/_internal/compat.py +src/pip/_internal/configuration.py +src/pip/_internal/download.py +src/pip/_internal/exceptions.py +src/pip/_internal/index.py +src/pip/_internal/locations.py +src/pip/_internal/pep425tags.py +src/pip/_internal/resolve.py +src/pip/_internal/status_codes.py +src/pip/_internal/wheel.py +src/pip/_internal/commands/__init__.py +src/pip/_internal/commands/check.py +src/pip/_internal/commands/completion.py +src/pip/_internal/commands/configuration.py +src/pip/_internal/commands/download.py +src/pip/_internal/commands/freeze.py +src/pip/_internal/commands/hash.py +src/pip/_internal/commands/help.py +src/pip/_internal/commands/install.py +src/pip/_internal/commands/list.py +src/pip/_internal/commands/search.py +src/pip/_internal/commands/show.py +src/pip/_internal/commands/uninstall.py +src/pip/_internal/commands/wheel.py +src/pip/_internal/models/__init__.py +src/pip/_internal/models/index.py +src/pip/_internal/operations/__init__.py +src/pip/_internal/operations/check.py +src/pip/_internal/operations/freeze.py +src/pip/_internal/operations/prepare.py +src/pip/_internal/req/__init__.py +src/pip/_internal/req/req_file.py +src/pip/_internal/req/req_install.py +src/pip/_internal/req/req_set.py +src/pip/_internal/req/req_uninstall.py +src/pip/_internal/utils/__init__.py +src/pip/_internal/utils/appdirs.py +src/pip/_internal/utils/deprecation.py +src/pip/_internal/utils/encoding.py +src/pip/_internal/utils/filesystem.py +src/pip/_internal/utils/glibc.py +src/pip/_internal/utils/hashes.py +src/pip/_internal/utils/logging.py +src/pip/_internal/utils/misc.py +src/pip/_internal/utils/outdated.py +src/pip/_internal/utils/packaging.py +src/pip/_internal/utils/setuptools_build.py +src/pip/_internal/utils/temp_dir.py +src/pip/_internal/utils/typing.py +src/pip/_internal/utils/ui.py +src/pip/_internal/vcs/__init__.py +src/pip/_internal/vcs/bazaar.py +src/pip/_internal/vcs/git.py +src/pip/_internal/vcs/mercurial.py +src/pip/_internal/vcs/subversion.py +src/pip/_vendor/README.rst +src/pip/_vendor/__init__.py +src/pip/_vendor/appdirs.py +src/pip/_vendor/distro.py +src/pip/_vendor/ipaddress.py +src/pip/_vendor/pyparsing.py +src/pip/_vendor/retrying.py +src/pip/_vendor/six.py +src/pip/_vendor/vendor.txt +src/pip/_vendor/cachecontrol/__init__.py +src/pip/_vendor/cachecontrol/_cmd.py +src/pip/_vendor/cachecontrol/adapter.py +src/pip/_vendor/cachecontrol/cache.py +src/pip/_vendor/cachecontrol/compat.py +src/pip/_vendor/cachecontrol/controller.py +src/pip/_vendor/cachecontrol/filewrapper.py +src/pip/_vendor/cachecontrol/heuristics.py +src/pip/_vendor/cachecontrol/serialize.py +src/pip/_vendor/cachecontrol/wrapper.py +src/pip/_vendor/cachecontrol/caches/__init__.py +src/pip/_vendor/cachecontrol/caches/file_cache.py +src/pip/_vendor/cachecontrol/caches/redis_cache.py +src/pip/_vendor/certifi/__init__.py +src/pip/_vendor/certifi/__main__.py +src/pip/_vendor/certifi/cacert.pem +src/pip/_vendor/certifi/core.py +src/pip/_vendor/chardet/__init__.py +src/pip/_vendor/chardet/big5freq.py +src/pip/_vendor/chardet/big5prober.py +src/pip/_vendor/chardet/chardistribution.py +src/pip/_vendor/chardet/charsetgroupprober.py +src/pip/_vendor/chardet/charsetprober.py +src/pip/_vendor/chardet/codingstatemachine.py +src/pip/_vendor/chardet/compat.py +src/pip/_vendor/chardet/cp949prober.py +src/pip/_vendor/chardet/enums.py +src/pip/_vendor/chardet/escprober.py +src/pip/_vendor/chardet/escsm.py +src/pip/_vendor/chardet/eucjpprober.py +src/pip/_vendor/chardet/euckrfreq.py +src/pip/_vendor/chardet/euckrprober.py +src/pip/_vendor/chardet/euctwfreq.py +src/pip/_vendor/chardet/euctwprober.py +src/pip/_vendor/chardet/gb2312freq.py +src/pip/_vendor/chardet/gb2312prober.py +src/pip/_vendor/chardet/hebrewprober.py +src/pip/_vendor/chardet/jisfreq.py +src/pip/_vendor/chardet/jpcntx.py +src/pip/_vendor/chardet/langbulgarianmodel.py +src/pip/_vendor/chardet/langcyrillicmodel.py +src/pip/_vendor/chardet/langgreekmodel.py +src/pip/_vendor/chardet/langhebrewmodel.py +src/pip/_vendor/chardet/langhungarianmodel.py +src/pip/_vendor/chardet/langthaimodel.py +src/pip/_vendor/chardet/langturkishmodel.py +src/pip/_vendor/chardet/latin1prober.py +src/pip/_vendor/chardet/mbcharsetprober.py +src/pip/_vendor/chardet/mbcsgroupprober.py +src/pip/_vendor/chardet/mbcssm.py +src/pip/_vendor/chardet/sbcharsetprober.py +src/pip/_vendor/chardet/sbcsgroupprober.py +src/pip/_vendor/chardet/sjisprober.py +src/pip/_vendor/chardet/universaldetector.py +src/pip/_vendor/chardet/utf8prober.py +src/pip/_vendor/chardet/version.py +src/pip/_vendor/chardet/cli/__init__.py +src/pip/_vendor/chardet/cli/chardetect.py +src/pip/_vendor/colorama/__init__.py +src/pip/_vendor/colorama/ansi.py +src/pip/_vendor/colorama/ansitowin32.py +src/pip/_vendor/colorama/initialise.py +src/pip/_vendor/colorama/win32.py +src/pip/_vendor/colorama/winterm.py +src/pip/_vendor/distlib/__init__.py +src/pip/_vendor/distlib/compat.py +src/pip/_vendor/distlib/database.py +src/pip/_vendor/distlib/index.py +src/pip/_vendor/distlib/locators.py +src/pip/_vendor/distlib/manifest.py +src/pip/_vendor/distlib/markers.py +src/pip/_vendor/distlib/metadata.py +src/pip/_vendor/distlib/resources.py +src/pip/_vendor/distlib/scripts.py +src/pip/_vendor/distlib/t32.exe +src/pip/_vendor/distlib/t64.exe +src/pip/_vendor/distlib/util.py +src/pip/_vendor/distlib/version.py +src/pip/_vendor/distlib/w32.exe +src/pip/_vendor/distlib/w64.exe +src/pip/_vendor/distlib/wheel.py +src/pip/_vendor/distlib/_backport/__init__.py +src/pip/_vendor/distlib/_backport/misc.py +src/pip/_vendor/distlib/_backport/shutil.py +src/pip/_vendor/distlib/_backport/sysconfig.cfg +src/pip/_vendor/distlib/_backport/sysconfig.py +src/pip/_vendor/distlib/_backport/tarfile.py +src/pip/_vendor/html5lib/__init__.py +src/pip/_vendor/html5lib/_ihatexml.py +src/pip/_vendor/html5lib/_inputstream.py +src/pip/_vendor/html5lib/_tokenizer.py +src/pip/_vendor/html5lib/_utils.py +src/pip/_vendor/html5lib/constants.py +src/pip/_vendor/html5lib/html5parser.py +src/pip/_vendor/html5lib/serializer.py +src/pip/_vendor/html5lib/_trie/__init__.py +src/pip/_vendor/html5lib/_trie/_base.py +src/pip/_vendor/html5lib/_trie/datrie.py +src/pip/_vendor/html5lib/_trie/py.py +src/pip/_vendor/html5lib/filters/__init__.py +src/pip/_vendor/html5lib/filters/alphabeticalattributes.py +src/pip/_vendor/html5lib/filters/base.py +src/pip/_vendor/html5lib/filters/inject_meta_charset.py +src/pip/_vendor/html5lib/filters/lint.py +src/pip/_vendor/html5lib/filters/optionaltags.py +src/pip/_vendor/html5lib/filters/sanitizer.py +src/pip/_vendor/html5lib/filters/whitespace.py +src/pip/_vendor/html5lib/treeadapters/__init__.py +src/pip/_vendor/html5lib/treeadapters/genshi.py +src/pip/_vendor/html5lib/treeadapters/sax.py +src/pip/_vendor/html5lib/treebuilders/__init__.py +src/pip/_vendor/html5lib/treebuilders/base.py +src/pip/_vendor/html5lib/treebuilders/dom.py +src/pip/_vendor/html5lib/treebuilders/etree.py +src/pip/_vendor/html5lib/treebuilders/etree_lxml.py +src/pip/_vendor/html5lib/treewalkers/__init__.py +src/pip/_vendor/html5lib/treewalkers/base.py +src/pip/_vendor/html5lib/treewalkers/dom.py +src/pip/_vendor/html5lib/treewalkers/etree.py +src/pip/_vendor/html5lib/treewalkers/etree_lxml.py +src/pip/_vendor/html5lib/treewalkers/genshi.py +src/pip/_vendor/idna/__init__.py +src/pip/_vendor/idna/codec.py +src/pip/_vendor/idna/compat.py +src/pip/_vendor/idna/core.py +src/pip/_vendor/idna/idnadata.py +src/pip/_vendor/idna/intranges.py +src/pip/_vendor/idna/package_data.py +src/pip/_vendor/idna/uts46data.py +src/pip/_vendor/lockfile/__init__.py +src/pip/_vendor/lockfile/linklockfile.py +src/pip/_vendor/lockfile/mkdirlockfile.py +src/pip/_vendor/lockfile/pidlockfile.py +src/pip/_vendor/lockfile/sqlitelockfile.py +src/pip/_vendor/lockfile/symlinklockfile.py +src/pip/_vendor/msgpack/__init__.py +src/pip/_vendor/msgpack/_version.py +src/pip/_vendor/msgpack/exceptions.py +src/pip/_vendor/msgpack/fallback.py +src/pip/_vendor/packaging/__about__.py +src/pip/_vendor/packaging/__init__.py +src/pip/_vendor/packaging/_compat.py +src/pip/_vendor/packaging/_structures.py +src/pip/_vendor/packaging/markers.py +src/pip/_vendor/packaging/requirements.py +src/pip/_vendor/packaging/specifiers.py +src/pip/_vendor/packaging/utils.py +src/pip/_vendor/packaging/version.py +src/pip/_vendor/pkg_resources/__init__.py +src/pip/_vendor/pkg_resources/py31compat.py +src/pip/_vendor/progress/__init__.py +src/pip/_vendor/progress/bar.py +src/pip/_vendor/progress/counter.py +src/pip/_vendor/progress/helpers.py +src/pip/_vendor/progress/spinner.py +src/pip/_vendor/pytoml/__init__.py +src/pip/_vendor/pytoml/core.py +src/pip/_vendor/pytoml/parser.py +src/pip/_vendor/pytoml/writer.py +src/pip/_vendor/requests/__init__.py +src/pip/_vendor/requests/__version__.py +src/pip/_vendor/requests/_internal_utils.py +src/pip/_vendor/requests/adapters.py +src/pip/_vendor/requests/api.py +src/pip/_vendor/requests/auth.py +src/pip/_vendor/requests/certs.py +src/pip/_vendor/requests/compat.py +src/pip/_vendor/requests/cookies.py +src/pip/_vendor/requests/exceptions.py +src/pip/_vendor/requests/help.py +src/pip/_vendor/requests/hooks.py +src/pip/_vendor/requests/models.py +src/pip/_vendor/requests/packages.py +src/pip/_vendor/requests/sessions.py +src/pip/_vendor/requests/status_codes.py +src/pip/_vendor/requests/structures.py +src/pip/_vendor/requests/utils.py +src/pip/_vendor/urllib3/__init__.py +src/pip/_vendor/urllib3/_collections.py +src/pip/_vendor/urllib3/connection.py +src/pip/_vendor/urllib3/connectionpool.py +src/pip/_vendor/urllib3/exceptions.py +src/pip/_vendor/urllib3/fields.py +src/pip/_vendor/urllib3/filepost.py +src/pip/_vendor/urllib3/poolmanager.py +src/pip/_vendor/urllib3/request.py +src/pip/_vendor/urllib3/response.py +src/pip/_vendor/urllib3/contrib/__init__.py +src/pip/_vendor/urllib3/contrib/appengine.py +src/pip/_vendor/urllib3/contrib/ntlmpool.py +src/pip/_vendor/urllib3/contrib/pyopenssl.py +src/pip/_vendor/urllib3/contrib/securetransport.py +src/pip/_vendor/urllib3/contrib/socks.py +src/pip/_vendor/urllib3/contrib/_securetransport/__init__.py +src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py +src/pip/_vendor/urllib3/contrib/_securetransport/low_level.py +src/pip/_vendor/urllib3/packages/__init__.py +src/pip/_vendor/urllib3/packages/ordered_dict.py +src/pip/_vendor/urllib3/packages/six.py +src/pip/_vendor/urllib3/packages/backports/__init__.py +src/pip/_vendor/urllib3/packages/backports/makefile.py +src/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py +src/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py +src/pip/_vendor/urllib3/util/__init__.py +src/pip/_vendor/urllib3/util/connection.py +src/pip/_vendor/urllib3/util/request.py +src/pip/_vendor/urllib3/util/response.py +src/pip/_vendor/urllib3/util/retry.py +src/pip/_vendor/urllib3/util/selectors.py +src/pip/_vendor/urllib3/util/ssl_.py +src/pip/_vendor/urllib3/util/timeout.py +src/pip/_vendor/urllib3/util/url.py +src/pip/_vendor/urllib3/util/wait.py +src/pip/_vendor/webencodings/__init__.py +src/pip/_vendor/webencodings/labels.py +src/pip/_vendor/webencodings/mklabels.py +src/pip/_vendor/webencodings/tests.py +src/pip/_vendor/webencodings/x_user_defined.py \ No newline at end of file diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/dependency_links.txt b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/entry_points.txt b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/entry_points.txt new file mode 100644 index 0000000..f5809cb --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/entry_points.txt @@ -0,0 +1,5 @@ +[console_scripts] +pip = pip._internal:main +pip3 = pip._internal:main +pip3.7 = pip._internal:main + diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/not-zip-safe b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/not-zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/not-zip-safe @@ -0,0 +1 @@ + diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/requires.txt b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/requires.txt new file mode 100644 index 0000000..fdea1b5 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/requires.txt @@ -0,0 +1,8 @@ + +[testing] +pytest +mock +pretend +scripttest>=1.3 +virtualenv>=1.10 +freezegun diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/top_level.txt b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/top_level.txt new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/top_level.txt @@ -0,0 +1 @@ +pip diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/__init__.py new file mode 100644 index 0000000..ab64964 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/__init__.py @@ -0,0 +1 @@ +__version__ = "10.0.1" diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/__main__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/__main__.py new file mode 100644 index 0000000..4609582 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/__main__.py @@ -0,0 +1,19 @@ +from __future__ import absolute_import + +import os +import sys + +# If we are running from a wheel, add the wheel to sys.path +# This allows the usage python pip-*.whl/pip install pip-*.whl +if __package__ == '': + # __file__ is pip-*.whl/pip/__main__.py + # first dirname call strips of '/__main__.py', second strips off '/pip' + # Resulting path is the name of the wheel itself + # Add that to sys.path so we can import pip + path = os.path.dirname(os.path.dirname(__file__)) + sys.path.insert(0, path) + +from pip._internal import main as _main # noqa + +if __name__ == '__main__': + sys.exit(_main()) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__init__.py new file mode 100644 index 0000000..865d9ec --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__init__.py @@ -0,0 +1,246 @@ +#!/usr/bin/env python +from __future__ import absolute_import + +import locale +import logging +import os +import optparse +import warnings + +import sys + +# 2016-06-17 barry@debian.org: urllib3 1.14 added optional support for socks, +# but if invoked (i.e. imported), it will issue a warning to stderr if socks +# isn't available. requests unconditionally imports urllib3's socks contrib +# module, triggering this warning. The warning breaks DEP-8 tests (because of +# the stderr output) and is just plain annoying in normal usage. I don't want +# to add socks as yet another dependency for pip, nor do I want to allow-stder +# in the DEP-8 tests, so just suppress the warning. pdb tells me this has to +# be done before the import of pip.vcs. +from pip._vendor.urllib3.exceptions import DependencyWarning +warnings.filterwarnings("ignore", category=DependencyWarning) # noqa + +# We want to inject the use of SecureTransport as early as possible so that any +# references or sessions or what have you are ensured to have it, however we +# only want to do this in the case that we're running on macOS and the linked +# OpenSSL is too old to handle TLSv1.2 +try: + import ssl +except ImportError: + pass +else: + # Checks for OpenSSL 1.0.1 on MacOS + if sys.platform == "darwin" and ssl.OPENSSL_VERSION_NUMBER < 0x1000100f: + try: + from pip._vendor.urllib3.contrib import securetransport + except (ImportError, OSError): + pass + else: + securetransport.inject_into_urllib3() + +from pip import __version__ +from pip._internal import cmdoptions +from pip._internal.exceptions import CommandError, PipError +from pip._internal.utils.misc import get_installed_distributions, get_prog +from pip._internal.utils import deprecation +from pip._internal.vcs import git, mercurial, subversion, bazaar # noqa +from pip._internal.baseparser import ( + ConfigOptionParser, UpdatingDefaultsHelpFormatter, +) +from pip._internal.commands import get_summaries, get_similar_commands +from pip._internal.commands import commands_dict +from pip._vendor.urllib3.exceptions import InsecureRequestWarning + +logger = logging.getLogger(__name__) + +# Hide the InsecureRequestWarning from urllib3 +warnings.filterwarnings("ignore", category=InsecureRequestWarning) + + +def autocomplete(): + """Command and option completion for the main option parser (and options) + and its subcommands (and options). + + Enable by sourcing one of the completion shell scripts (bash, zsh or fish). + """ + # Don't complete if user hasn't sourced bash_completion file. + if 'PIP_AUTO_COMPLETE' not in os.environ: + return + cwords = os.environ['COMP_WORDS'].split()[1:] + cword = int(os.environ['COMP_CWORD']) + try: + current = cwords[cword - 1] + except IndexError: + current = '' + + subcommands = [cmd for cmd, summary in get_summaries()] + options = [] + # subcommand + try: + subcommand_name = [w for w in cwords if w in subcommands][0] + except IndexError: + subcommand_name = None + + parser = create_main_parser() + # subcommand options + if subcommand_name: + # special case: 'help' subcommand has no options + if subcommand_name == 'help': + sys.exit(1) + # special case: list locally installed dists for show and uninstall + should_list_installed = ( + subcommand_name in ['show', 'uninstall'] and + not current.startswith('-') + ) + if should_list_installed: + installed = [] + lc = current.lower() + for dist in get_installed_distributions(local_only=True): + if dist.key.startswith(lc) and dist.key not in cwords[1:]: + installed.append(dist.key) + # if there are no dists installed, fall back to option completion + if installed: + for dist in installed: + print(dist) + sys.exit(1) + + subcommand = commands_dict[subcommand_name]() + + for opt in subcommand.parser.option_list_all: + if opt.help != optparse.SUPPRESS_HELP: + for opt_str in opt._long_opts + opt._short_opts: + options.append((opt_str, opt.nargs)) + + # filter out previously specified options from available options + prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]] + options = [(x, v) for (x, v) in options if x not in prev_opts] + # filter options by current input + options = [(k, v) for k, v in options if k.startswith(current)] + for option in options: + opt_label = option[0] + # append '=' to options which require args + if option[1] and option[0][:2] == "--": + opt_label += '=' + print(opt_label) + else: + # show main parser options only when necessary + if current.startswith('-') or current.startswith('--'): + opts = [i.option_list for i in parser.option_groups] + opts.append(parser.option_list) + opts = (o for it in opts for o in it) + + for opt in opts: + if opt.help != optparse.SUPPRESS_HELP: + subcommands += opt._long_opts + opt._short_opts + + print(' '.join([x for x in subcommands if x.startswith(current)])) + sys.exit(1) + + +def create_main_parser(): + parser_kw = { + 'usage': '\n%prog [options]', + 'add_help_option': False, + 'formatter': UpdatingDefaultsHelpFormatter(), + 'name': 'global', + 'prog': get_prog(), + } + + parser = ConfigOptionParser(**parser_kw) + parser.disable_interspersed_args() + + pip_pkg_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + parser.version = 'pip %s from %s (python %s)' % ( + __version__, pip_pkg_dir, sys.version[:3], + ) + + # add the general options + gen_opts = cmdoptions.make_option_group(cmdoptions.general_group, parser) + parser.add_option_group(gen_opts) + + parser.main = True # so the help formatter knows + + # create command listing for description + command_summaries = get_summaries() + description = [''] + ['%-27s %s' % (i, j) for i, j in command_summaries] + parser.description = '\n'.join(description) + + return parser + + +def parseopts(args): + parser = create_main_parser() + + # Note: parser calls disable_interspersed_args(), so the result of this + # call is to split the initial args into the general options before the + # subcommand and everything else. + # For example: + # args: ['--timeout=5', 'install', '--user', 'INITools'] + # general_options: ['--timeout==5'] + # args_else: ['install', '--user', 'INITools'] + general_options, args_else = parser.parse_args(args) + + # --version + if general_options.version: + sys.stdout.write(parser.version) + sys.stdout.write(os.linesep) + sys.exit() + + # pip || pip help -> print_help() + if not args_else or (args_else[0] == 'help' and len(args_else) == 1): + parser.print_help() + sys.exit() + + # the subcommand name + cmd_name = args_else[0] + + if cmd_name not in commands_dict: + guess = get_similar_commands(cmd_name) + + msg = ['unknown command "%s"' % cmd_name] + if guess: + msg.append('maybe you meant "%s"' % guess) + + raise CommandError(' - '.join(msg)) + + # all the args without the subcommand + cmd_args = args[:] + cmd_args.remove(cmd_name) + + return cmd_name, cmd_args + + +def check_isolated(args): + isolated = False + + if "--isolated" in args: + isolated = True + + return isolated + + +def main(args=None): + if args is None: + args = sys.argv[1:] + + # Configure our deprecation warnings to be sent through loggers + deprecation.install_warning_logger() + + autocomplete() + + try: + cmd_name, cmd_args = parseopts(args) + except PipError as exc: + sys.stderr.write("ERROR: %s" % exc) + sys.stderr.write(os.linesep) + sys.exit(1) + + # Needed for locale.getpreferredencoding(False) to work + # in pip._internal.utils.encoding.auto_decode + try: + locale.setlocale(locale.LC_ALL, '') + except locale.Error as e: + # setlocale can apparently crash if locale are uninitialized + logger.debug("Ignoring error %s when setting locale", e) + command = commands_dict[cmd_name](isolated=check_isolated(cmd_args)) + return command.main(cmd_args) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/basecommand.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/basecommand.py new file mode 100644 index 0000000..2503f36 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/basecommand.py @@ -0,0 +1,373 @@ +"""Base Command class, and related routines""" +from __future__ import absolute_import + +import logging +import logging.config +import optparse +import os +import sys +import warnings + +from pip._internal import cmdoptions +from pip._internal.baseparser import ( + ConfigOptionParser, UpdatingDefaultsHelpFormatter, +) +from pip._internal.compat import WINDOWS +from pip._internal.download import PipSession +from pip._internal.exceptions import ( + BadCommand, CommandError, InstallationError, PreviousBuildDirError, + UninstallationError, +) +from pip._internal.index import PackageFinder +from pip._internal.locations import running_under_virtualenv +from pip._internal.req.req_file import parse_requirements +from pip._internal.req.req_install import InstallRequirement +from pip._internal.status_codes import ( + ERROR, PREVIOUS_BUILD_DIR_ERROR, SUCCESS, UNKNOWN_ERROR, + VIRTUALENV_NOT_FOUND, +) +from pip._internal.utils import deprecation +from pip._internal.utils.logging import IndentingFormatter +from pip._internal.utils.misc import get_prog, normalize_path +from pip._internal.utils.outdated import pip_version_check +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional + +__all__ = ['Command'] + +logger = logging.getLogger(__name__) + + +class Command(object): + name = None # type: Optional[str] + usage = None # type: Optional[str] + hidden = False # type: bool + ignore_require_venv = False # type: bool + log_streams = ("ext://sys.stdout", "ext://sys.stderr") + + def __init__(self, isolated=False): + parser_kw = { + 'usage': self.usage, + 'prog': '%s %s' % (get_prog(), self.name), + 'formatter': UpdatingDefaultsHelpFormatter(), + 'add_help_option': False, + 'name': self.name, + 'description': self.__doc__, + 'isolated': isolated, + } + + self.parser = ConfigOptionParser(**parser_kw) + + # Commands should add options to this option group + optgroup_name = '%s Options' % self.name.capitalize() + self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name) + + # Add the general options + gen_opts = cmdoptions.make_option_group( + cmdoptions.general_group, + self.parser, + ) + self.parser.add_option_group(gen_opts) + + def _build_session(self, options, retries=None, timeout=None): + session = PipSession( + cache=( + normalize_path(os.path.join(options.cache_dir, "http")) + if options.cache_dir else None + ), + retries=retries if retries is not None else options.retries, + insecure_hosts=options.trusted_hosts, + ) + + # Handle custom ca-bundles from the user + if options.cert: + session.verify = options.cert + + # Handle SSL client certificate + if options.client_cert: + session.cert = options.client_cert + + # Handle timeouts + if options.timeout or timeout: + session.timeout = ( + timeout if timeout is not None else options.timeout + ) + + # Handle configured proxies + if options.proxy: + session.proxies = { + "http": options.proxy, + "https": options.proxy, + } + + # Determine if we can prompt the user for authentication or not + session.auth.prompting = not options.no_input + + return session + + def parse_args(self, args): + # factored out for testability + return self.parser.parse_args(args) + + def main(self, args): + options, args = self.parse_args(args) + + # Set verbosity so that it can be used elsewhere. + self.verbosity = options.verbose - options.quiet + + if self.verbosity >= 1: + level = "DEBUG" + elif self.verbosity == -1: + level = "WARNING" + elif self.verbosity == -2: + level = "ERROR" + elif self.verbosity <= -3: + level = "CRITICAL" + else: + level = "INFO" + + # The root logger should match the "console" level *unless* we + # specified "--log" to send debug logs to a file. + root_level = level + if options.log: + root_level = "DEBUG" + + logger_class = "pip._internal.utils.logging.ColorizedStreamHandler" + handler_class = "pip._internal.utils.logging.BetterRotatingFileHandler" + + logging.config.dictConfig({ + "version": 1, + "disable_existing_loggers": False, + "filters": { + "exclude_warnings": { + "()": "pip._internal.utils.logging.MaxLevelFilter", + "level": logging.WARNING, + }, + }, + "formatters": { + "indent": { + "()": IndentingFormatter, + "format": "%(message)s", + }, + }, + "handlers": { + "console": { + "level": level, + "class": logger_class, + "no_color": options.no_color, + "stream": self.log_streams[0], + "filters": ["exclude_warnings"], + "formatter": "indent", + }, + "console_errors": { + "level": "WARNING", + "class": logger_class, + "no_color": options.no_color, + "stream": self.log_streams[1], + "formatter": "indent", + }, + "user_log": { + "level": "DEBUG", + "class": handler_class, + "filename": options.log or "/dev/null", + "delay": True, + "formatter": "indent", + }, + }, + "root": { + "level": root_level, + "handlers": list(filter(None, [ + "console", + "console_errors", + "user_log" if options.log else None, + ])), + }, + # Disable any logging besides WARNING unless we have DEBUG level + # logging enabled. These use both pip._vendor and the bare names + # for the case where someone unbundles our libraries. + "loggers": { + name: { + "level": ( + "WARNING" if level in ["INFO", "ERROR"] else "DEBUG" + ) + } for name in [ + "pip._vendor", "distlib", "requests", "urllib3" + ] + }, + }) + + if sys.version_info[:2] == (3, 3): + warnings.warn( + "Python 3.3 supported has been deprecated and support for it " + "will be dropped in the future. Please upgrade your Python.", + deprecation.RemovedInPip11Warning, + ) + + # TODO: try to get these passing down from the command? + # without resorting to os.environ to hold these. + + if options.no_input: + os.environ['PIP_NO_INPUT'] = '1' + + if options.exists_action: + os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action) + + if options.require_venv and not self.ignore_require_venv: + # If a venv is required check if it can really be found + if not running_under_virtualenv(): + logger.critical( + 'Could not find an activated virtualenv (required).' + ) + sys.exit(VIRTUALENV_NOT_FOUND) + + original_root_handlers = set(logging.root.handlers) + + try: + status = self.run(options, args) + # FIXME: all commands should return an exit status + # and when it is done, isinstance is not needed anymore + if isinstance(status, int): + return status + except PreviousBuildDirError as exc: + logger.critical(str(exc)) + logger.debug('Exception information:', exc_info=True) + + return PREVIOUS_BUILD_DIR_ERROR + except (InstallationError, UninstallationError, BadCommand) as exc: + logger.critical(str(exc)) + logger.debug('Exception information:', exc_info=True) + + return ERROR + except CommandError as exc: + logger.critical('ERROR: %s', exc) + logger.debug('Exception information:', exc_info=True) + + return ERROR + except KeyboardInterrupt: + logger.critical('Operation cancelled by user') + logger.debug('Exception information:', exc_info=True) + + return ERROR + except: + logger.critical('Exception:', exc_info=True) + + return UNKNOWN_ERROR + finally: + # Check if we're using the latest version of pip available + if (not options.disable_pip_version_check and not + getattr(options, "no_index", False)): + with self._build_session( + options, + retries=0, + timeout=min(5, options.timeout)) as session: + pip_version_check(session, options) + # Avoid leaking loggers + for handler in set(logging.root.handlers) - original_root_handlers: + # this method benefit from the Logger class internal lock + logging.root.removeHandler(handler) + + return SUCCESS + + +class RequirementCommand(Command): + + @staticmethod + def populate_requirement_set(requirement_set, args, options, finder, + session, name, wheel_cache): + """ + Marshal cmd line args into a requirement set. + """ + # NOTE: As a side-effect, options.require_hashes and + # requirement_set.require_hashes may be updated + + for filename in options.constraints: + for req_to_add in parse_requirements( + filename, + constraint=True, finder=finder, options=options, + session=session, wheel_cache=wheel_cache): + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + + for req in args: + req_to_add = InstallRequirement.from_line( + req, None, isolated=options.isolated_mode, + wheel_cache=wheel_cache + ) + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + + for req in options.editables: + req_to_add = InstallRequirement.from_editable( + req, + isolated=options.isolated_mode, + wheel_cache=wheel_cache + ) + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + + for filename in options.requirements: + for req_to_add in parse_requirements( + filename, + finder=finder, options=options, session=session, + wheel_cache=wheel_cache): + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + # If --require-hashes was a line in a requirements file, tell + # RequirementSet about it: + requirement_set.require_hashes = options.require_hashes + + if not (args or options.editables or options.requirements): + opts = {'name': name} + if options.find_links: + raise CommandError( + 'You must give at least one requirement to %(name)s ' + '(maybe you meant "pip %(name)s %(links)s"?)' % + dict(opts, links=' '.join(options.find_links))) + else: + raise CommandError( + 'You must give at least one requirement to %(name)s ' + '(see "pip help %(name)s")' % opts) + + # On Windows, any operation modifying pip should be run as: + # python -m pip ... + # See https://github.com/pypa/pip/issues/1299 for more discussion + should_show_use_python_msg = ( + WINDOWS and + requirement_set.has_requirement("pip") and + os.path.basename(sys.argv[0]).startswith("pip") + ) + if should_show_use_python_msg: + new_command = [ + sys.executable, "-m", "pip" + ] + sys.argv[1:] + raise CommandError( + 'To modify pip, please run the following command:\n{}' + .format(" ".join(new_command)) + ) + + def _build_package_finder(self, options, session, + platform=None, python_versions=None, + abi=None, implementation=None): + """ + Create a package finder appropriate to this requirement command. + """ + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.debug('Ignoring indexes: %s', ','.join(index_urls)) + index_urls = [] + + return PackageFinder( + find_links=options.find_links, + format_control=options.format_control, + index_urls=index_urls, + trusted_hosts=options.trusted_hosts, + allow_all_prereleases=options.pre, + process_dependency_links=options.process_dependency_links, + session=session, + platform=platform, + versions=python_versions, + abi=abi, + implementation=implementation, + ) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/baseparser.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/baseparser.py new file mode 100644 index 0000000..9a8d129 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/baseparser.py @@ -0,0 +1,240 @@ +"""Base option parser setup""" +from __future__ import absolute_import + +import logging +import optparse +import sys +import textwrap +from distutils.util import strtobool + +from pip._vendor.six import string_types + +from pip._internal.compat import get_terminal_size +from pip._internal.configuration import Configuration, ConfigurationError + +logger = logging.getLogger(__name__) + + +class PrettyHelpFormatter(optparse.IndentedHelpFormatter): + """A prettier/less verbose help formatter for optparse.""" + + def __init__(self, *args, **kwargs): + # help position must be aligned with __init__.parseopts.description + kwargs['max_help_position'] = 30 + kwargs['indent_increment'] = 1 + kwargs['width'] = get_terminal_size()[0] - 2 + optparse.IndentedHelpFormatter.__init__(self, *args, **kwargs) + + def format_option_strings(self, option): + return self._format_option_strings(option, ' <%s>', ', ') + + def _format_option_strings(self, option, mvarfmt=' <%s>', optsep=', '): + """ + Return a comma-separated list of option strings and metavars. + + :param option: tuple of (short opt, long opt), e.g: ('-f', '--format') + :param mvarfmt: metavar format string - evaluated as mvarfmt % metavar + :param optsep: separator + """ + opts = [] + + if option._short_opts: + opts.append(option._short_opts[0]) + if option._long_opts: + opts.append(option._long_opts[0]) + if len(opts) > 1: + opts.insert(1, optsep) + + if option.takes_value(): + metavar = option.metavar or option.dest.lower() + opts.append(mvarfmt % metavar.lower()) + + return ''.join(opts) + + def format_heading(self, heading): + if heading == 'Options': + return '' + return heading + ':\n' + + def format_usage(self, usage): + """ + Ensure there is only one newline between usage and the first heading + if there is no description. + """ + msg = '\nUsage: %s\n' % self.indent_lines(textwrap.dedent(usage), " ") + return msg + + def format_description(self, description): + # leave full control over description to us + if description: + if hasattr(self.parser, 'main'): + label = 'Commands' + else: + label = 'Description' + # some doc strings have initial newlines, some don't + description = description.lstrip('\n') + # some doc strings have final newlines and spaces, some don't + description = description.rstrip() + # dedent, then reindent + description = self.indent_lines(textwrap.dedent(description), " ") + description = '%s:\n%s\n' % (label, description) + return description + else: + return '' + + def format_epilog(self, epilog): + # leave full control over epilog to us + if epilog: + return epilog + else: + return '' + + def indent_lines(self, text, indent): + new_lines = [indent + line for line in text.split('\n')] + return "\n".join(new_lines) + + +class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter): + """Custom help formatter for use in ConfigOptionParser. + + This is updates the defaults before expanding them, allowing + them to show up correctly in the help listing. + """ + + def expand_default(self, option): + if self.parser is not None: + self.parser._update_defaults(self.parser.defaults) + return optparse.IndentedHelpFormatter.expand_default(self, option) + + +class CustomOptionParser(optparse.OptionParser): + + def insert_option_group(self, idx, *args, **kwargs): + """Insert an OptionGroup at a given position.""" + group = self.add_option_group(*args, **kwargs) + + self.option_groups.pop() + self.option_groups.insert(idx, group) + + return group + + @property + def option_list_all(self): + """Get a list of all options, including those in option groups.""" + res = self.option_list[:] + for i in self.option_groups: + res.extend(i.option_list) + + return res + + +class ConfigOptionParser(CustomOptionParser): + """Custom option parser which updates its defaults by checking the + configuration files and environmental variables""" + + def __init__(self, *args, **kwargs): + self.name = kwargs.pop('name') + + isolated = kwargs.pop("isolated", False) + self.config = Configuration(isolated) + + assert self.name + optparse.OptionParser.__init__(self, *args, **kwargs) + + def check_default(self, option, key, val): + try: + return option.check_value(key, val) + except optparse.OptionValueError as exc: + print("An error occurred during configuration: %s" % exc) + sys.exit(3) + + def _get_ordered_configuration_items(self): + # Configuration gives keys in an unordered manner. Order them. + override_order = ["global", self.name, ":env:"] + + # Pool the options into different groups + section_items = {name: [] for name in override_order} + for section_key, val in self.config.items(): + # ignore empty values + if not val: + logger.debug( + "Ignoring configuration key '%s' as it's value is empty.", + section_key + ) + continue + + section, key = section_key.split(".", 1) + if section in override_order: + section_items[section].append((key, val)) + + # Yield each group in their override order + for section in override_order: + for key, val in section_items[section]: + yield key, val + + def _update_defaults(self, defaults): + """Updates the given defaults with values from the config files and + the environ. Does a little special handling for certain types of + options (lists).""" + + # Accumulate complex default state. + self.values = optparse.Values(self.defaults) + late_eval = set() + # Then set the options with those values + for key, val in self._get_ordered_configuration_items(): + # '--' because configuration supports only long names + option = self.get_option('--' + key) + + # Ignore options not present in this parser. E.g. non-globals put + # in [global] by users that want them to apply to all applicable + # commands. + if option is None: + continue + + if option.action in ('store_true', 'store_false', 'count'): + val = strtobool(val) + elif option.action == 'append': + val = val.split() + val = [self.check_default(option, key, v) for v in val] + elif option.action == 'callback': + late_eval.add(option.dest) + opt_str = option.get_opt_string() + val = option.convert_value(opt_str, val) + # From take_action + args = option.callback_args or () + kwargs = option.callback_kwargs or {} + option.callback(option, opt_str, val, self, *args, **kwargs) + else: + val = self.check_default(option, key, val) + + defaults[option.dest] = val + + for key in late_eval: + defaults[key] = getattr(self.values, key) + self.values = None + return defaults + + def get_default_values(self): + """Overriding to make updating the defaults after instantiation of + the option parser possible, _update_defaults() does the dirty work.""" + if not self.process_default_values: + # Old, pre-Optik 1.5 behaviour. + return optparse.Values(self.defaults) + + # Load the configuration, or error out in case of an error + try: + self.config.load() + except ConfigurationError as err: + self.exit(2, err.args[0]) + + defaults = self._update_defaults(self.defaults.copy()) # ours + for option in self._get_all_options(): + default = defaults.get(option.dest) + if isinstance(default, string_types): + opt_str = option.get_opt_string() + defaults[option.dest] = option.check_value(opt_str, default) + return optparse.Values(defaults) + + def error(self, msg): + self.print_usage(sys.stderr) + self.exit(2, "%s\n" % msg) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/build_env.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/build_env.py new file mode 100644 index 0000000..791d734 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/build_env.py @@ -0,0 +1,92 @@ +"""Build Environment used for isolation during sdist building +""" + +import os +from distutils.sysconfig import get_python_lib +from sysconfig import get_paths + +from pip._internal.utils.temp_dir import TempDirectory + + +class BuildEnvironment(object): + """Creates and manages an isolated environment to install build deps + """ + + def __init__(self, no_clean): + self._temp_dir = TempDirectory(kind="build-env") + self._no_clean = no_clean + + @property + def path(self): + return self._temp_dir.path + + def __enter__(self): + self._temp_dir.create() + + self.save_path = os.environ.get('PATH', None) + self.save_pythonpath = os.environ.get('PYTHONPATH', None) + self.save_nousersite = os.environ.get('PYTHONNOUSERSITE', None) + + install_scheme = 'nt' if (os.name == 'nt') else 'posix_prefix' + install_dirs = get_paths(install_scheme, vars={ + 'base': self.path, + 'platbase': self.path, + }) + + scripts = install_dirs['scripts'] + if self.save_path: + os.environ['PATH'] = scripts + os.pathsep + self.save_path + else: + os.environ['PATH'] = scripts + os.pathsep + os.defpath + + # Note: prefer distutils' sysconfig to get the + # library paths so PyPy is correctly supported. + purelib = get_python_lib(plat_specific=0, prefix=self.path) + platlib = get_python_lib(plat_specific=1, prefix=self.path) + if purelib == platlib: + lib_dirs = purelib + else: + lib_dirs = purelib + os.pathsep + platlib + if self.save_pythonpath: + os.environ['PYTHONPATH'] = lib_dirs + os.pathsep + \ + self.save_pythonpath + else: + os.environ['PYTHONPATH'] = lib_dirs + + os.environ['PYTHONNOUSERSITE'] = '1' + + return self.path + + def __exit__(self, exc_type, exc_val, exc_tb): + if not self._no_clean: + self._temp_dir.cleanup() + + def restore_var(varname, old_value): + if old_value is None: + os.environ.pop(varname, None) + else: + os.environ[varname] = old_value + + restore_var('PATH', self.save_path) + restore_var('PYTHONPATH', self.save_pythonpath) + restore_var('PYTHONNOUSERSITE', self.save_nousersite) + + def cleanup(self): + self._temp_dir.cleanup() + + +class NoOpBuildEnvironment(BuildEnvironment): + """A no-op drop-in replacement for BuildEnvironment + """ + + def __init__(self, no_clean): + pass + + def __enter__(self): + pass + + def __exit__(self, exc_type, exc_val, exc_tb): + pass + + def cleanup(self): + pass diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/cache.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/cache.py new file mode 100644 index 0000000..1aa17aa --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/cache.py @@ -0,0 +1,202 @@ +"""Cache Management +""" + +import errno +import hashlib +import logging +import os + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal import index +from pip._internal.compat import expanduser +from pip._internal.download import path_to_url +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.wheel import InvalidWheelFilename, Wheel + +logger = logging.getLogger(__name__) + + +class Cache(object): + """An abstract class - provides cache directories for data from links + + + :param cache_dir: The root of the cache. + :param format_control: A pip.index.FormatControl object to limit + binaries being read from the cache. + :param allowed_formats: which formats of files the cache should store. + ('binary' and 'source' are the only allowed values) + """ + + def __init__(self, cache_dir, format_control, allowed_formats): + super(Cache, self).__init__() + self.cache_dir = expanduser(cache_dir) if cache_dir else None + self.format_control = format_control + self.allowed_formats = allowed_formats + + _valid_formats = {"source", "binary"} + assert self.allowed_formats.union(_valid_formats) == _valid_formats + + def _get_cache_path_parts(self, link): + """Get parts of part that must be os.path.joined with cache_dir + """ + + # We want to generate an url to use as our cache key, we don't want to + # just re-use the URL because it might have other items in the fragment + # and we don't care about those. + key_parts = [link.url_without_fragment] + if link.hash_name is not None and link.hash is not None: + key_parts.append("=".join([link.hash_name, link.hash])) + key_url = "#".join(key_parts) + + # Encode our key url with sha224, we'll use this because it has similar + # security properties to sha256, but with a shorter total output (and + # thus less secure). However the differences don't make a lot of + # difference for our use case here. + hashed = hashlib.sha224(key_url.encode()).hexdigest() + + # We want to nest the directories some to prevent having a ton of top + # level directories where we might run out of sub directories on some + # FS. + parts = [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]] + + return parts + + def _get_candidates(self, link, package_name): + can_not_cache = ( + not self.cache_dir or + not package_name or + not link + ) + if can_not_cache: + return [] + + canonical_name = canonicalize_name(package_name) + formats = index.fmt_ctl_formats( + self.format_control, canonical_name + ) + if not self.allowed_formats.intersection(formats): + return [] + + root = self.get_path_for_link(link) + try: + return os.listdir(root) + except OSError as err: + if err.errno in {errno.ENOENT, errno.ENOTDIR}: + return [] + raise + + def get_path_for_link(self, link): + """Return a directory to store cached items in for link. + """ + raise NotImplementedError() + + def get(self, link, package_name): + """Returns a link to a cached item if it exists, otherwise returns the + passed link. + """ + raise NotImplementedError() + + def _link_for_candidate(self, link, candidate): + root = self.get_path_for_link(link) + path = os.path.join(root, candidate) + + return index.Link(path_to_url(path)) + + def cleanup(self): + pass + + +class SimpleWheelCache(Cache): + """A cache of wheels for future installs. + """ + + def __init__(self, cache_dir, format_control): + super(SimpleWheelCache, self).__init__( + cache_dir, format_control, {"binary"} + ) + + def get_path_for_link(self, link): + """Return a directory to store cached wheels for link + + Because there are M wheels for any one sdist, we provide a directory + to cache them in, and then consult that directory when looking up + cache hits. + + We only insert things into the cache if they have plausible version + numbers, so that we don't contaminate the cache with things that were + not unique. E.g. ./package might have dozens of installs done for it + and build a version of 0.0...and if we built and cached a wheel, we'd + end up using the same wheel even if the source has been edited. + + :param link: The link of the sdist for which this will cache wheels. + """ + parts = self._get_cache_path_parts(link) + + # Store wheels within the root cache_dir + return os.path.join(self.cache_dir, "wheels", *parts) + + def get(self, link, package_name): + candidates = [] + + for wheel_name in self._get_candidates(link, package_name): + try: + wheel = Wheel(wheel_name) + except InvalidWheelFilename: + continue + if not wheel.supported(): + # Built for a different python/arch/etc + continue + candidates.append((wheel.support_index_min(), wheel_name)) + + if not candidates: + return link + + return self._link_for_candidate(link, min(candidates)[1]) + + +class EphemWheelCache(SimpleWheelCache): + """A SimpleWheelCache that creates it's own temporary cache directory + """ + + def __init__(self, format_control): + self._temp_dir = TempDirectory(kind="ephem-wheel-cache") + self._temp_dir.create() + + super(EphemWheelCache, self).__init__( + self._temp_dir.path, format_control + ) + + def cleanup(self): + self._temp_dir.cleanup() + + +class WheelCache(Cache): + """Wraps EphemWheelCache and SimpleWheelCache into a single Cache + + This Cache allows for gracefully degradation, using the ephem wheel cache + when a certain link is not found in the simple wheel cache first. + """ + + def __init__(self, cache_dir, format_control): + super(WheelCache, self).__init__( + cache_dir, format_control, {'binary'} + ) + self._wheel_cache = SimpleWheelCache(cache_dir, format_control) + self._ephem_cache = EphemWheelCache(format_control) + + def get_path_for_link(self, link): + return self._wheel_cache.get_path_for_link(link) + + def get_ephem_path_for_link(self, link): + return self._ephem_cache.get_path_for_link(link) + + def get(self, link, package_name): + retval = self._wheel_cache.get(link, package_name) + if retval is link: + retval = self._ephem_cache.get(link, package_name) + return retval + + def cleanup(self): + self._wheel_cache.cleanup() + self._ephem_cache.cleanup() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/cmdoptions.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/cmdoptions.py new file mode 100644 index 0000000..6319995 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/cmdoptions.py @@ -0,0 +1,609 @@ +""" +shared options and groups + +The principle here is to define options once, but *not* instantiate them +globally. One reason being that options with action='append' can carry state +between parses. pip parses general options twice internally, and shouldn't +pass on state. To be consistent, all options will follow this design. + +""" +from __future__ import absolute_import + +import warnings +from functools import partial +from optparse import SUPPRESS_HELP, Option, OptionGroup + +from pip._internal.index import ( + FormatControl, fmt_ctl_handle_mutual_exclude, fmt_ctl_no_binary, +) +from pip._internal.locations import USER_CACHE_DIR, src_prefix +from pip._internal.models import PyPI +from pip._internal.utils.hashes import STRONG_HASHES +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.ui import BAR_TYPES + +if MYPY_CHECK_RUNNING: + from typing import Any + + +def make_option_group(group, parser): + """ + Return an OptionGroup object + group -- assumed to be dict with 'name' and 'options' keys + parser -- an optparse Parser + """ + option_group = OptionGroup(parser, group['name']) + for option in group['options']: + option_group.add_option(option()) + return option_group + + +def check_install_build_global(options, check_options=None): + """Disable wheels if per-setup.py call options are set. + + :param options: The OptionParser options to update. + :param check_options: The options to check, if not supplied defaults to + options. + """ + if check_options is None: + check_options = options + + def getname(n): + return getattr(check_options, n, None) + names = ["build_options", "global_options", "install_options"] + if any(map(getname, names)): + control = options.format_control + fmt_ctl_no_binary(control) + warnings.warn( + 'Disabling all use of wheels due to the use of --build-options ' + '/ --global-options / --install-options.', stacklevel=2, + ) + + +########### +# options # +########### + +help_ = partial( + Option, + '-h', '--help', + dest='help', + action='help', + help='Show help.', +) # type: Any + +isolated_mode = partial( + Option, + "--isolated", + dest="isolated_mode", + action="store_true", + default=False, + help=( + "Run pip in an isolated mode, ignoring environment variables and user " + "configuration." + ), +) + +require_virtualenv = partial( + Option, + # Run only if inside a virtualenv, bail if not. + '--require-virtualenv', '--require-venv', + dest='require_venv', + action='store_true', + default=False, + help=SUPPRESS_HELP +) # type: Any + +verbose = partial( + Option, + '-v', '--verbose', + dest='verbose', + action='count', + default=0, + help='Give more output. Option is additive, and can be used up to 3 times.' +) + +no_color = partial( + Option, + '--no-color', + dest='no_color', + action='store_true', + default=False, + help="Suppress colored output", +) + +version = partial( + Option, + '-V', '--version', + dest='version', + action='store_true', + help='Show version and exit.', +) # type: Any + +quiet = partial( + Option, + '-q', '--quiet', + dest='quiet', + action='count', + default=0, + help=( + 'Give less output. Option is additive, and can be used up to 3' + ' times (corresponding to WARNING, ERROR, and CRITICAL logging' + ' levels).' + ), +) # type: Any + +progress_bar = partial( + Option, + '--progress-bar', + dest='progress_bar', + type='choice', + choices=list(BAR_TYPES.keys()), + default='on', + help=( + 'Specify type of progress to be displayed [' + + '|'.join(BAR_TYPES.keys()) + '] (default: %default)' + ), +) # type: Any + +log = partial( + Option, + "--log", "--log-file", "--local-log", + dest="log", + metavar="path", + help="Path to a verbose appending log." +) # type: Any + +no_input = partial( + Option, + # Don't ask for input + '--no-input', + dest='no_input', + action='store_true', + default=False, + help=SUPPRESS_HELP +) # type: Any + +proxy = partial( + Option, + '--proxy', + dest='proxy', + type='str', + default='', + help="Specify a proxy in the form [user:passwd@]proxy.server:port." +) # type: Any + +retries = partial( + Option, + '--retries', + dest='retries', + type='int', + default=5, + help="Maximum number of retries each connection should attempt " + "(default %default times).", +) # type: Any + +timeout = partial( + Option, + '--timeout', '--default-timeout', + metavar='sec', + dest='timeout', + type='float', + default=15, + help='Set the socket timeout (default %default seconds).', +) # type: Any + +skip_requirements_regex = partial( + Option, + # A regex to be used to skip requirements + '--skip-requirements-regex', + dest='skip_requirements_regex', + type='str', + default='', + help=SUPPRESS_HELP, +) # type: Any + + +def exists_action(): + return Option( + # Option when path already exist + '--exists-action', + dest='exists_action', + type='choice', + choices=['s', 'i', 'w', 'b', 'a'], + default=[], + action='append', + metavar='action', + help="Default action when a path already exists: " + "(s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort).", + ) + + +cert = partial( + Option, + '--cert', + dest='cert', + type='str', + metavar='path', + help="Path to alternate CA bundle.", +) # type: Any + +client_cert = partial( + Option, + '--client-cert', + dest='client_cert', + type='str', + default=None, + metavar='path', + help="Path to SSL client certificate, a single file containing the " + "private key and the certificate in PEM format.", +) # type: Any + +index_url = partial( + Option, + '-i', '--index-url', '--pypi-url', + dest='index_url', + metavar='URL', + default=PyPI.simple_url, + help="Base URL of Python Package Index (default %default). " + "This should point to a repository compliant with PEP 503 " + "(the simple repository API) or a local directory laid out " + "in the same format.", +) # type: Any + + +def extra_index_url(): + return Option( + '--extra-index-url', + dest='extra_index_urls', + metavar='URL', + action='append', + default=[], + help="Extra URLs of package indexes to use in addition to " + "--index-url. Should follow the same rules as " + "--index-url.", + ) + + +no_index = partial( + Option, + '--no-index', + dest='no_index', + action='store_true', + default=False, + help='Ignore package index (only looking at --find-links URLs instead).', +) # type: Any + + +def find_links(): + return Option( + '-f', '--find-links', + dest='find_links', + action='append', + default=[], + metavar='url', + help="If a url or path to an html file, then parse for links to " + "archives. If a local path or file:// url that's a directory, " + "then look for archives in the directory listing.", + ) + + +def trusted_host(): + return Option( + "--trusted-host", + dest="trusted_hosts", + action="append", + metavar="HOSTNAME", + default=[], + help="Mark this host as trusted, even though it does not have valid " + "or any HTTPS.", + ) + + +# Remove after 1.5 +process_dependency_links = partial( + Option, + "--process-dependency-links", + dest="process_dependency_links", + action="store_true", + default=False, + help="Enable the processing of dependency links.", +) # type: Any + + +def constraints(): + return Option( + '-c', '--constraint', + dest='constraints', + action='append', + default=[], + metavar='file', + help='Constrain versions using the given constraints file. ' + 'This option can be used multiple times.' + ) + + +def requirements(): + return Option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help='Install from the given requirements file. ' + 'This option can be used multiple times.' + ) + + +def editable(): + return Option( + '-e', '--editable', + dest='editables', + action='append', + default=[], + metavar='path/url', + help=('Install a project in editable mode (i.e. setuptools ' + '"develop mode") from a local project path or a VCS url.'), + ) + + +src = partial( + Option, + '--src', '--source', '--source-dir', '--source-directory', + dest='src_dir', + metavar='dir', + default=src_prefix, + help='Directory to check out editable projects into. ' + 'The default in a virtualenv is "/src". ' + 'The default for global installs is "/src".' +) # type: Any + + +def _get_format_control(values, option): + """Get a format_control object.""" + return getattr(values, option.dest) + + +def _handle_no_binary(option, opt_str, value, parser): + existing = getattr(parser.values, option.dest) + fmt_ctl_handle_mutual_exclude( + value, existing.no_binary, existing.only_binary, + ) + + +def _handle_only_binary(option, opt_str, value, parser): + existing = getattr(parser.values, option.dest) + fmt_ctl_handle_mutual_exclude( + value, existing.only_binary, existing.no_binary, + ) + + +def no_binary(): + return Option( + "--no-binary", dest="format_control", action="callback", + callback=_handle_no_binary, type="str", + default=FormatControl(set(), set()), + help="Do not use binary packages. Can be supplied multiple times, and " + "each time adds to the existing value. Accepts either :all: to " + "disable all binary packages, :none: to empty the set, or one or " + "more package names with commas between them. Note that some " + "packages are tricky to compile and may fail to install when " + "this option is used on them.", + ) + + +def only_binary(): + return Option( + "--only-binary", dest="format_control", action="callback", + callback=_handle_only_binary, type="str", + default=FormatControl(set(), set()), + help="Do not use source packages. Can be supplied multiple times, and " + "each time adds to the existing value. Accepts either :all: to " + "disable all source packages, :none: to empty the set, or one or " + "more package names with commas between them. Packages without " + "binary distributions will fail to install when this option is " + "used on them.", + ) + + +cache_dir = partial( + Option, + "--cache-dir", + dest="cache_dir", + default=USER_CACHE_DIR, + metavar="dir", + help="Store the cache data in ." +) + +no_cache = partial( + Option, + "--no-cache-dir", + dest="cache_dir", + action="store_false", + help="Disable the cache.", +) + +no_deps = partial( + Option, + '--no-deps', '--no-dependencies', + dest='ignore_dependencies', + action='store_true', + default=False, + help="Don't install package dependencies.", +) # type: Any + +build_dir = partial( + Option, + '-b', '--build', '--build-dir', '--build-directory', + dest='build_dir', + metavar='dir', + help='Directory to unpack packages into and build in. Note that ' + 'an initial build still takes place in a temporary directory. ' + 'The location of temporary directories can be controlled by setting ' + 'the TMPDIR environment variable (TEMP on Windows) appropriately. ' + 'When passed, build directories are not cleaned in case of failures.' +) # type: Any + +ignore_requires_python = partial( + Option, + '--ignore-requires-python', + dest='ignore_requires_python', + action='store_true', + help='Ignore the Requires-Python information.' +) # type: Any + +no_build_isolation = partial( + Option, + '--no-build-isolation', + dest='build_isolation', + action='store_false', + default=True, + help='Disable isolation when building a modern source distribution. ' + 'Build dependencies specified by PEP 518 must be already installed ' + 'if this option is used.' +) # type: Any + +install_options = partial( + Option, + '--install-option', + dest='install_options', + action='append', + metavar='options', + help="Extra arguments to be supplied to the setup.py install " + "command (use like --install-option=\"--install-scripts=/usr/local/" + "bin\"). Use multiple --install-option options to pass multiple " + "options to setup.py install. If you are using an option with a " + "directory path, be sure to use absolute path.", +) # type: Any + +global_options = partial( + Option, + '--global-option', + dest='global_options', + action='append', + metavar='options', + help="Extra global options to be supplied to the setup.py " + "call before the install command.", +) # type: Any + +no_clean = partial( + Option, + '--no-clean', + action='store_true', + default=False, + help="Don't clean up build directories)." +) # type: Any + +pre = partial( + Option, + '--pre', + action='store_true', + default=False, + help="Include pre-release and development versions. By default, " + "pip only finds stable versions.", +) # type: Any + +disable_pip_version_check = partial( + Option, + "--disable-pip-version-check", + dest="disable_pip_version_check", + action="store_true", + default=False, + help="Don't periodically check PyPI to determine whether a new version " + "of pip is available for download. Implied with --no-index.", +) # type: Any + + +# Deprecated, Remove later +always_unzip = partial( + Option, + '-Z', '--always-unzip', + dest='always_unzip', + action='store_true', + help=SUPPRESS_HELP, +) # type: Any + + +def _merge_hash(option, opt_str, value, parser): + """Given a value spelled "algo:digest", append the digest to a list + pointed to in a dict by the algo name.""" + if not parser.values.hashes: + parser.values.hashes = {} + try: + algo, digest = value.split(':', 1) + except ValueError: + parser.error('Arguments to %s must be a hash name ' + 'followed by a value, like --hash=sha256:abcde...' % + opt_str) + if algo not in STRONG_HASHES: + parser.error('Allowed hash algorithms for %s are %s.' % + (opt_str, ', '.join(STRONG_HASHES))) + parser.values.hashes.setdefault(algo, []).append(digest) + + +hash = partial( + Option, + '--hash', + # Hash values eventually end up in InstallRequirement.hashes due to + # __dict__ copying in process_line(). + dest='hashes', + action='callback', + callback=_merge_hash, + type='string', + help="Verify that the package's archive matches this " + 'hash before installing. Example: --hash=sha256:abcdef...', +) # type: Any + + +require_hashes = partial( + Option, + '--require-hashes', + dest='require_hashes', + action='store_true', + default=False, + help='Require a hash to check each requirement against, for ' + 'repeatable installs. This option is implied when any package in a ' + 'requirements file has a --hash option.', +) # type: Any + + +########## +# groups # +########## + +general_group = { + 'name': 'General Options', + 'options': [ + help_, + isolated_mode, + require_virtualenv, + verbose, + version, + quiet, + log, + no_input, + proxy, + retries, + timeout, + skip_requirements_regex, + exists_action, + trusted_host, + cert, + client_cert, + cache_dir, + no_cache, + disable_pip_version_check, + no_color, + ] +} + +index_group = { + 'name': 'Package Index Options', + 'options': [ + index_url, + extra_index_url, + no_index, + find_links, + process_dependency_links, + ] +} diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__init__.py new file mode 100644 index 0000000..d79c48e --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__init__.py @@ -0,0 +1,79 @@ +""" +Package containing all pip commands +""" +from __future__ import absolute_import + +from pip._internal.commands.completion import CompletionCommand +from pip._internal.commands.configuration import ConfigurationCommand +from pip._internal.commands.download import DownloadCommand +from pip._internal.commands.freeze import FreezeCommand +from pip._internal.commands.hash import HashCommand +from pip._internal.commands.help import HelpCommand +from pip._internal.commands.list import ListCommand +from pip._internal.commands.check import CheckCommand +from pip._internal.commands.search import SearchCommand +from pip._internal.commands.show import ShowCommand +from pip._internal.commands.install import InstallCommand +from pip._internal.commands.uninstall import UninstallCommand +from pip._internal.commands.wheel import WheelCommand + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Type + from pip._internal.basecommand import Command + +commands_order = [ + InstallCommand, + DownloadCommand, + UninstallCommand, + FreezeCommand, + ListCommand, + ShowCommand, + CheckCommand, + ConfigurationCommand, + SearchCommand, + WheelCommand, + HashCommand, + CompletionCommand, + HelpCommand, +] # type: List[Type[Command]] + +commands_dict = {c.name: c for c in commands_order} + + +def get_summaries(ordered=True): + """Yields sorted (command name, command summary) tuples.""" + + if ordered: + cmditems = _sort_commands(commands_dict, commands_order) + else: + cmditems = commands_dict.items() + + for name, command_class in cmditems: + yield (name, command_class.summary) + + +def get_similar_commands(name): + """Command name auto-correct.""" + from difflib import get_close_matches + + name = name.lower() + + close_commands = get_close_matches(name, commands_dict.keys()) + + if close_commands: + return close_commands[0] + else: + return False + + +def _sort_commands(cmddict, order): + def keyfn(key): + try: + return order.index(key[1]) + except ValueError: + # unordered items should come last + return 0xff + + return sorted(cmddict.items(), key=keyfn) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/check.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/check.py new file mode 100644 index 0000000..88db510 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/check.py @@ -0,0 +1,42 @@ +import logging + +from pip._internal.basecommand import Command +from pip._internal.operations.check import ( + check_package_set, create_package_set_from_installed, +) +from pip._internal.utils.misc import get_installed_distributions + +logger = logging.getLogger(__name__) + + +class CheckCommand(Command): + """Verify installed packages have compatible dependencies.""" + name = 'check' + usage = """ + %prog [options]""" + summary = 'Verify installed packages have compatible dependencies.' + + def run(self, options, args): + package_set = create_package_set_from_installed() + missing, conflicting = check_package_set(package_set) + + for project_name in missing: + version = package_set[project_name].version + for dependency in missing[project_name]: + logger.info( + "%s %s requires %s, which is not installed.", + project_name, version, dependency[0], + ) + + for project_name in conflicting: + version = package_set[project_name].version + for dep_name, dep_version, req in conflicting[project_name]: + logger.info( + "%s %s has requirement %s, but you have %s %s.", + project_name, version, req, dep_name, dep_version, + ) + + if missing or conflicting: + return 1 + else: + logger.info("No broken requirements found.") diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/completion.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/completion.py new file mode 100644 index 0000000..c4b3873 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/completion.py @@ -0,0 +1,94 @@ +from __future__ import absolute_import + +import sys +import textwrap + +from pip._internal.basecommand import Command +from pip._internal.utils.misc import get_prog + +BASE_COMPLETION = """ +# pip %(shell)s completion start%(script)s# pip %(shell)s completion end +""" + +COMPLETION_SCRIPTS = { + 'bash': """ + _pip_completion() + { + COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \\ + COMP_CWORD=$COMP_CWORD \\ + PIP_AUTO_COMPLETE=1 $1 ) ) + } + complete -o default -F _pip_completion %(prog)s + """, + 'zsh': """ + function _pip_completion { + local words cword + read -Ac words + read -cn cword + reply=( $( COMP_WORDS="$words[*]" \\ + COMP_CWORD=$(( cword-1 )) \\ + PIP_AUTO_COMPLETE=1 $words[1] ) ) + } + compctl -K _pip_completion %(prog)s + """, + 'fish': """ + function __fish_complete_pip + set -lx COMP_WORDS (commandline -o) "" + set -lx COMP_CWORD ( \\ + math (contains -i -- (commandline -t) $COMP_WORDS)-1 \\ + ) + set -lx PIP_AUTO_COMPLETE 1 + string split \\ -- (eval $COMP_WORDS[1]) + end + complete -fa "(__fish_complete_pip)" -c %(prog)s + """, +} + + +class CompletionCommand(Command): + """A helper command to be used for command completion.""" + name = 'completion' + summary = 'A helper command used for command completion.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(CompletionCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option( + '--bash', '-b', + action='store_const', + const='bash', + dest='shell', + help='Emit completion code for bash') + cmd_opts.add_option( + '--zsh', '-z', + action='store_const', + const='zsh', + dest='shell', + help='Emit completion code for zsh') + cmd_opts.add_option( + '--fish', '-f', + action='store_const', + const='fish', + dest='shell', + help='Emit completion code for fish') + + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + """Prints the completion code of the given shell""" + shells = COMPLETION_SCRIPTS.keys() + shell_options = ['--' + shell for shell in sorted(shells)] + if options.shell in shells: + script = textwrap.dedent( + COMPLETION_SCRIPTS.get(options.shell, '') % { + 'prog': get_prog(), + } + ) + print(BASE_COMPLETION % {'script': script, 'shell': options.shell}) + else: + sys.stderr.write( + 'ERROR: You must pass %s\n' % ' or '.join(shell_options) + ) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/configuration.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/configuration.py new file mode 100644 index 0000000..57448cb --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/configuration.py @@ -0,0 +1,227 @@ +import logging +import os +import subprocess + +from pip._internal.basecommand import Command +from pip._internal.configuration import Configuration, kinds +from pip._internal.exceptions import PipError +from pip._internal.locations import venv_config_file +from pip._internal.status_codes import ERROR, SUCCESS +from pip._internal.utils.misc import get_prog + +logger = logging.getLogger(__name__) + + +class ConfigurationCommand(Command): + """Manage local and global configuration. + + Subcommands: + + list: List the active configuration (or from the file specified) + edit: Edit the configuration file in an editor + get: Get the value associated with name + set: Set the name=value + unset: Unset the value associated with name + + If none of --user, --global and --venv are passed, a virtual + environment configuration file is used if one is active and the file + exists. Otherwise, all modifications happen on the to the user file by + default. + """ + + name = 'config' + usage = """ + %prog [] list + %prog [] [--editor ] edit + + %prog [] get name + %prog [] set name value + %prog [] unset name + """ + + summary = "Manage local and global configuration." + + def __init__(self, *args, **kwargs): + super(ConfigurationCommand, self).__init__(*args, **kwargs) + + self.configuration = None + + self.cmd_opts.add_option( + '--editor', + dest='editor', + action='store', + default=None, + help=( + 'Editor to use to edit the file. Uses VISUAL or EDITOR ' + 'environment variables if not provided.' + ) + ) + + self.cmd_opts.add_option( + '--global', + dest='global_file', + action='store_true', + default=False, + help='Use the system-wide configuration file only' + ) + + self.cmd_opts.add_option( + '--user', + dest='user_file', + action='store_true', + default=False, + help='Use the user configuration file only' + ) + + self.cmd_opts.add_option( + '--venv', + dest='venv_file', + action='store_true', + default=False, + help='Use the virtualenv configuration file only' + ) + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + handlers = { + "list": self.list_values, + "edit": self.open_in_editor, + "get": self.get_name, + "set": self.set_name_value, + "unset": self.unset_name + } + + # Determine action + if not args or args[0] not in handlers: + logger.error("Need an action ({}) to perform.".format( + ", ".join(sorted(handlers))) + ) + return ERROR + + action = args[0] + + # Determine which configuration files are to be loaded + # Depends on whether the command is modifying. + try: + load_only = self._determine_file( + options, need_value=(action in ["get", "set", "unset", "edit"]) + ) + except PipError as e: + logger.error(e.args[0]) + return ERROR + + # Load a new configuration + self.configuration = Configuration( + isolated=options.isolated_mode, load_only=load_only + ) + self.configuration.load() + + # Error handling happens here, not in the action-handlers. + try: + handlers[action](options, args[1:]) + except PipError as e: + logger.error(e.args[0]) + return ERROR + + return SUCCESS + + def _determine_file(self, options, need_value): + file_options = { + kinds.USER: options.user_file, + kinds.GLOBAL: options.global_file, + kinds.VENV: options.venv_file + } + + if sum(file_options.values()) == 0: + if not need_value: + return None + # Default to user, unless there's a virtualenv file. + elif os.path.exists(venv_config_file): + return kinds.VENV + else: + return kinds.USER + elif sum(file_options.values()) == 1: + # There's probably a better expression for this. + return [key for key in file_options if file_options[key]][0] + + raise PipError( + "Need exactly one file to operate upon " + "(--user, --venv, --global) to perform." + ) + + def list_values(self, options, args): + self._get_n_args(args, "list", n=0) + + for key, value in sorted(self.configuration.items()): + logger.info("%s=%r", key, value) + + def get_name(self, options, args): + key = self._get_n_args(args, "get [name]", n=1) + value = self.configuration.get_value(key) + + logger.info("%s", value) + + def set_name_value(self, options, args): + key, value = self._get_n_args(args, "set [name] [value]", n=2) + self.configuration.set_value(key, value) + + self._save_configuration() + + def unset_name(self, options, args): + key = self._get_n_args(args, "unset [name]", n=1) + self.configuration.unset_value(key) + + self._save_configuration() + + def open_in_editor(self, options, args): + editor = self._determine_editor(options) + + fname = self.configuration.get_file_to_edit() + if fname is None: + raise PipError("Could not determine appropriate file.") + + try: + subprocess.check_call([editor, fname]) + except subprocess.CalledProcessError as e: + raise PipError( + "Editor Subprocess exited with exit code {}" + .format(e.returncode) + ) + + def _get_n_args(self, args, example, n): + """Helper to make sure the command got the right number of arguments + """ + if len(args) != n: + msg = ( + 'Got unexpected number of arguments, expected {}. ' + '(example: "{} config {}")' + ).format(n, get_prog(), example) + raise PipError(msg) + + if n == 1: + return args[0] + else: + return args + + def _save_configuration(self): + # We successfully ran a modifying command. Need to save the + # configuration. + try: + self.configuration.save() + except Exception: + logger.error( + "Unable to save configuration. Please report this as a bug.", + exc_info=1 + ) + raise PipError("Internal Error.") + + def _determine_editor(self, options): + if options.editor is not None: + return options.editor + elif "VISUAL" in os.environ: + return os.environ["VISUAL"] + elif "EDITOR" in os.environ: + return os.environ["EDITOR"] + else: + raise PipError("Could not determine editor to use.") diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/download.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/download.py new file mode 100644 index 0000000..5713d07 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/download.py @@ -0,0 +1,233 @@ +from __future__ import absolute_import + +import logging +import os + +from pip._internal import cmdoptions +from pip._internal.basecommand import RequirementCommand +from pip._internal.exceptions import CommandError +from pip._internal.index import FormatControl +from pip._internal.operations.prepare import RequirementPreparer +from pip._internal.req import RequirementSet +from pip._internal.resolve import Resolver +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.misc import ensure_dir, normalize_path +from pip._internal.utils.temp_dir import TempDirectory + +logger = logging.getLogger(__name__) + + +class DownloadCommand(RequirementCommand): + """ + Download packages from: + + - PyPI (and other indexes) using requirement specifiers. + - VCS project urls. + - Local project directories. + - Local or remote source archives. + + pip also supports downloading from "requirements files", which provide + an easy way to specify a whole environment to be downloaded. + """ + name = 'download' + + usage = """ + %prog [options] [package-index-options] ... + %prog [options] -r [package-index-options] ... + %prog [options] ... + %prog [options] ... + %prog [options] ...""" + + summary = 'Download packages.' + + def __init__(self, *args, **kw): + super(DownloadCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option(cmdoptions.constraints()) + cmd_opts.add_option(cmdoptions.requirements()) + cmd_opts.add_option(cmdoptions.build_dir()) + cmd_opts.add_option(cmdoptions.no_deps()) + cmd_opts.add_option(cmdoptions.global_options()) + cmd_opts.add_option(cmdoptions.no_binary()) + cmd_opts.add_option(cmdoptions.only_binary()) + cmd_opts.add_option(cmdoptions.src()) + cmd_opts.add_option(cmdoptions.pre()) + cmd_opts.add_option(cmdoptions.no_clean()) + cmd_opts.add_option(cmdoptions.require_hashes()) + cmd_opts.add_option(cmdoptions.progress_bar()) + cmd_opts.add_option(cmdoptions.no_build_isolation()) + + cmd_opts.add_option( + '-d', '--dest', '--destination-dir', '--destination-directory', + dest='download_dir', + metavar='dir', + default=os.curdir, + help=("Download packages into ."), + ) + + cmd_opts.add_option( + '--platform', + dest='platform', + metavar='platform', + default=None, + help=("Only download wheels compatible with . " + "Defaults to the platform of the running system."), + ) + + cmd_opts.add_option( + '--python-version', + dest='python_version', + metavar='python_version', + default=None, + help=("Only download wheels compatible with Python " + "interpreter version . If not specified, then the " + "current system interpreter minor version is used. A major " + "version (e.g. '2') can be specified to match all " + "minor revs of that major version. A minor version " + "(e.g. '34') can also be specified."), + ) + + cmd_opts.add_option( + '--implementation', + dest='implementation', + metavar='implementation', + default=None, + help=("Only download wheels compatible with Python " + "implementation , e.g. 'pp', 'jy', 'cp', " + " or 'ip'. If not specified, then the current " + "interpreter implementation is used. Use 'py' to force " + "implementation-agnostic wheels."), + ) + + cmd_opts.add_option( + '--abi', + dest='abi', + metavar='abi', + default=None, + help=("Only download wheels compatible with Python " + "abi , e.g. 'pypy_41'. If not specified, then the " + "current interpreter abi tag is used. Generally " + "you will need to specify --implementation, " + "--platform, and --python-version when using " + "this option."), + ) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + options.ignore_installed = True + # editable doesn't really make sense for `pip download`, but the bowels + # of the RequirementSet code require that property. + options.editables = [] + + if options.python_version: + python_versions = [options.python_version] + else: + python_versions = None + + dist_restriction_set = any([ + options.python_version, + options.platform, + options.abi, + options.implementation, + ]) + binary_only = FormatControl(set(), {':all:'}) + no_sdist_dependencies = ( + options.format_control != binary_only and + not options.ignore_dependencies + ) + if dist_restriction_set and no_sdist_dependencies: + raise CommandError( + "When restricting platform and interpreter constraints using " + "--python-version, --platform, --abi, or --implementation, " + "either --no-deps must be set, or --only-binary=:all: must be " + "set and --no-binary must not be set (or must be set to " + ":none:)." + ) + + options.src_dir = os.path.abspath(options.src_dir) + options.download_dir = normalize_path(options.download_dir) + + ensure_dir(options.download_dir) + + with self._build_session(options) as session: + finder = self._build_package_finder( + options=options, + session=session, + platform=options.platform, + python_versions=python_versions, + abi=options.abi, + implementation=options.implementation, + ) + build_delete = (not (options.no_clean or options.build_dir)) + if options.cache_dir and not check_path_owner(options.cache_dir): + logger.warning( + "The directory '%s' or its parent directory is not owned " + "by the current user and caching wheels has been " + "disabled. check the permissions and owner of that " + "directory. If executing pip with sudo, you may want " + "sudo's -H flag.", + options.cache_dir, + ) + options.cache_dir = None + + with TempDirectory( + options.build_dir, delete=build_delete, kind="download" + ) as directory: + + requirement_set = RequirementSet( + require_hashes=options.require_hashes, + ) + self.populate_requirement_set( + requirement_set, + args, + options, + finder, + session, + self.name, + None + ) + + preparer = RequirementPreparer( + build_dir=directory.path, + src_dir=options.src_dir, + download_dir=options.download_dir, + wheel_download_dir=None, + progress_bar=options.progress_bar, + build_isolation=options.build_isolation, + ) + + resolver = Resolver( + preparer=preparer, + finder=finder, + session=session, + wheel_cache=None, + use_user_site=False, + upgrade_strategy="to-satisfy-only", + force_reinstall=False, + ignore_dependencies=options.ignore_dependencies, + ignore_requires_python=False, + ignore_installed=True, + isolated=options.isolated_mode, + ) + resolver.resolve(requirement_set) + + downloaded = ' '.join([ + req.name for req in requirement_set.successfully_downloaded + ]) + if downloaded: + logger.info('Successfully downloaded %s', downloaded) + + # Clean up + if not options.no_clean: + requirement_set.cleanup_files() + + return requirement_set diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/freeze.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/freeze.py new file mode 100644 index 0000000..0d3d4ae --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/freeze.py @@ -0,0 +1,96 @@ +from __future__ import absolute_import + +import sys + +from pip._internal import index +from pip._internal.basecommand import Command +from pip._internal.cache import WheelCache +from pip._internal.compat import stdlib_pkgs +from pip._internal.operations.freeze import freeze + +DEV_PKGS = {'pip', 'setuptools', 'distribute', 'wheel'} + + +class FreezeCommand(Command): + """ + Output installed packages in requirements format. + + packages are listed in a case-insensitive sorted order. + """ + name = 'freeze' + usage = """ + %prog [options]""" + summary = 'Output installed packages in requirements format.' + log_streams = ("ext://sys.stderr", "ext://sys.stderr") + + def __init__(self, *args, **kw): + super(FreezeCommand, self).__init__(*args, **kw) + + self.cmd_opts.add_option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help="Use the order in the given requirements file and its " + "comments when generating output. This option can be " + "used multiple times.") + self.cmd_opts.add_option( + '-f', '--find-links', + dest='find_links', + action='append', + default=[], + metavar='URL', + help='URL for finding packages, which will be added to the ' + 'output.') + self.cmd_opts.add_option( + '-l', '--local', + dest='local', + action='store_true', + default=False, + help='If in a virtualenv that has global access, do not output ' + 'globally-installed packages.') + self.cmd_opts.add_option( + '--user', + dest='user', + action='store_true', + default=False, + help='Only output packages installed in user-site.') + self.cmd_opts.add_option( + '--all', + dest='freeze_all', + action='store_true', + help='Do not skip these packages in the output:' + ' %s' % ', '.join(DEV_PKGS)) + self.cmd_opts.add_option( + '--exclude-editable', + dest='exclude_editable', + action='store_true', + help='Exclude editable package from output.') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + format_control = index.FormatControl(set(), set()) + wheel_cache = WheelCache(options.cache_dir, format_control) + skip = set(stdlib_pkgs) + if not options.freeze_all: + skip.update(DEV_PKGS) + + freeze_kwargs = dict( + requirement=options.requirements, + find_links=options.find_links, + local_only=options.local, + user_only=options.user, + skip_regex=options.skip_requirements_regex, + isolated=options.isolated_mode, + wheel_cache=wheel_cache, + skip=skip, + exclude_editable=options.exclude_editable, + ) + + try: + for line in freeze(**freeze_kwargs): + sys.stdout.write(line + '\n') + finally: + wheel_cache.cleanup() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/hash.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/hash.py new file mode 100644 index 0000000..95353b0 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/hash.py @@ -0,0 +1,57 @@ +from __future__ import absolute_import + +import hashlib +import logging +import sys + +from pip._internal.basecommand import Command +from pip._internal.status_codes import ERROR +from pip._internal.utils.hashes import FAVORITE_HASH, STRONG_HASHES +from pip._internal.utils.misc import read_chunks + +logger = logging.getLogger(__name__) + + +class HashCommand(Command): + """ + Compute a hash of a local package archive. + + These can be used with --hash in a requirements file to do repeatable + installs. + + """ + name = 'hash' + usage = '%prog [options] ...' + summary = 'Compute hashes of package archives.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(HashCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-a', '--algorithm', + dest='algorithm', + choices=STRONG_HASHES, + action='store', + default=FAVORITE_HASH, + help='The hash algorithm to use: one of %s' % + ', '.join(STRONG_HASHES)) + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + self.parser.print_usage(sys.stderr) + return ERROR + + algorithm = options.algorithm + for path in args: + logger.info('%s:\n--hash=%s:%s', + path, algorithm, _hash_of_file(path, algorithm)) + + +def _hash_of_file(path, algorithm): + """Return the hash digest of a file.""" + with open(path, 'rb') as archive: + hash = hashlib.new(algorithm) + for chunk in read_chunks(archive): + hash.update(chunk) + return hash.hexdigest() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/help.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/help.py new file mode 100644 index 0000000..06ca2c1 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/help.py @@ -0,0 +1,36 @@ +from __future__ import absolute_import + +from pip._internal.basecommand import SUCCESS, Command +from pip._internal.exceptions import CommandError + + +class HelpCommand(Command): + """Show help for commands""" + name = 'help' + usage = """ + %prog """ + summary = 'Show help for commands.' + ignore_require_venv = True + + def run(self, options, args): + from pip._internal.commands import commands_dict, get_similar_commands + + try: + # 'pip help' with no args is handled by pip.__init__.parseopt() + cmd_name = args[0] # the command we need help for + except IndexError: + return SUCCESS + + if cmd_name not in commands_dict: + guess = get_similar_commands(cmd_name) + + msg = ['unknown command "%s"' % cmd_name] + if guess: + msg.append('maybe you meant "%s"' % guess) + + raise CommandError(' - '.join(msg)) + + command = commands_dict[cmd_name]() + command.parser.print_help() + + return SUCCESS diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/install.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/install.py new file mode 100644 index 0000000..9138683 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/install.py @@ -0,0 +1,502 @@ +from __future__ import absolute_import + +import errno +import logging +import operator +import os +import shutil +from optparse import SUPPRESS_HELP + +from pip._internal import cmdoptions +from pip._internal.basecommand import RequirementCommand +from pip._internal.cache import WheelCache +from pip._internal.exceptions import ( + CommandError, InstallationError, PreviousBuildDirError, +) +from pip._internal.locations import distutils_scheme, virtualenv_no_global +from pip._internal.operations.check import check_install_conflicts +from pip._internal.operations.prepare import RequirementPreparer +from pip._internal.req import RequirementSet, install_given_reqs +from pip._internal.resolve import Resolver +from pip._internal.status_codes import ERROR +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.misc import ensure_dir, get_installed_version +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.wheel import WheelBuilder + +try: + import wheel +except ImportError: + wheel = None + + +logger = logging.getLogger(__name__) + + +class InstallCommand(RequirementCommand): + """ + Install packages from: + + - PyPI (and other indexes) using requirement specifiers. + - VCS project urls. + - Local project directories. + - Local or remote source archives. + + pip also supports installing from "requirements files", which provide + an easy way to specify a whole environment to be installed. + """ + name = 'install' + + usage = """ + %prog [options] [package-index-options] ... + %prog [options] -r [package-index-options] ... + %prog [options] [-e] ... + %prog [options] [-e] ... + %prog [options] ...""" + + summary = 'Install packages.' + + def __init__(self, *args, **kw): + super(InstallCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option(cmdoptions.requirements()) + cmd_opts.add_option(cmdoptions.constraints()) + cmd_opts.add_option(cmdoptions.no_deps()) + cmd_opts.add_option(cmdoptions.pre()) + + cmd_opts.add_option(cmdoptions.editable()) + cmd_opts.add_option( + '-t', '--target', + dest='target_dir', + metavar='dir', + default=None, + help='Install packages into . ' + 'By default this will not replace existing files/folders in ' + '. Use --upgrade to replace existing packages in ' + 'with new versions.' + ) + cmd_opts.add_option( + '--user', + dest='use_user_site', + action='store_true', + help="Install to the Python user install directory for your " + "platform. Typically ~/.local/, or %APPDATA%\\Python on " + "Windows. (See the Python documentation for site.USER_BASE " + "for full details.)") + cmd_opts.add_option( + '--no-user', + dest='use_user_site', + action='store_false', + help=SUPPRESS_HELP) + cmd_opts.add_option( + '--root', + dest='root_path', + metavar='dir', + default=None, + help="Install everything relative to this alternate root " + "directory.") + cmd_opts.add_option( + '--prefix', + dest='prefix_path', + metavar='dir', + default=None, + help="Installation prefix where lib, bin and other top-level " + "folders are placed") + + cmd_opts.add_option(cmdoptions.build_dir()) + + cmd_opts.add_option(cmdoptions.src()) + + cmd_opts.add_option( + '-U', '--upgrade', + dest='upgrade', + action='store_true', + help='Upgrade all specified packages to the newest available ' + 'version. The handling of dependencies depends on the ' + 'upgrade-strategy used.' + ) + + cmd_opts.add_option( + '--upgrade-strategy', + dest='upgrade_strategy', + default='only-if-needed', + choices=['only-if-needed', 'eager'], + help='Determines how dependency upgrading should be handled ' + '[default: %default]. ' + '"eager" - dependencies are upgraded regardless of ' + 'whether the currently installed version satisfies the ' + 'requirements of the upgraded package(s). ' + '"only-if-needed" - are upgraded only when they do not ' + 'satisfy the requirements of the upgraded package(s).' + ) + + cmd_opts.add_option( + '--force-reinstall', + dest='force_reinstall', + action='store_true', + help='Reinstall all packages even if they are already ' + 'up-to-date.') + + cmd_opts.add_option( + '-I', '--ignore-installed', + dest='ignore_installed', + action='store_true', + help='Ignore the installed packages (reinstalling instead).') + + cmd_opts.add_option(cmdoptions.ignore_requires_python()) + cmd_opts.add_option(cmdoptions.no_build_isolation()) + + cmd_opts.add_option(cmdoptions.install_options()) + cmd_opts.add_option(cmdoptions.global_options()) + + cmd_opts.add_option( + "--compile", + action="store_true", + dest="compile", + default=True, + help="Compile Python source files to bytecode", + ) + + cmd_opts.add_option( + "--no-compile", + action="store_false", + dest="compile", + help="Do not compile Python source files to bytecode", + ) + + cmd_opts.add_option( + "--no-warn-script-location", + action="store_false", + dest="warn_script_location", + default=True, + help="Do not warn when installing scripts outside PATH", + ) + cmd_opts.add_option( + "--no-warn-conflicts", + action="store_false", + dest="warn_about_conflicts", + default=True, + help="Do not warn about broken dependencies", + ) + + cmd_opts.add_option(cmdoptions.no_binary()) + cmd_opts.add_option(cmdoptions.only_binary()) + cmd_opts.add_option(cmdoptions.no_clean()) + cmd_opts.add_option(cmdoptions.require_hashes()) + cmd_opts.add_option(cmdoptions.progress_bar()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + cmdoptions.check_install_build_global(options) + + upgrade_strategy = "to-satisfy-only" + if options.upgrade: + upgrade_strategy = options.upgrade_strategy + + if options.build_dir: + options.build_dir = os.path.abspath(options.build_dir) + + options.src_dir = os.path.abspath(options.src_dir) + install_options = options.install_options or [] + if options.use_user_site: + if options.prefix_path: + raise CommandError( + "Can not combine '--user' and '--prefix' as they imply " + "different installation locations" + ) + if virtualenv_no_global(): + raise InstallationError( + "Can not perform a '--user' install. User site-packages " + "are not visible in this virtualenv." + ) + install_options.append('--user') + install_options.append('--prefix=') + + target_temp_dir = TempDirectory(kind="target") + if options.target_dir: + options.ignore_installed = True + options.target_dir = os.path.abspath(options.target_dir) + if (os.path.exists(options.target_dir) and not + os.path.isdir(options.target_dir)): + raise CommandError( + "Target path exists but is not a directory, will not " + "continue." + ) + + # Create a target directory for using with the target option + target_temp_dir.create() + install_options.append('--home=' + target_temp_dir.path) + + global_options = options.global_options or [] + + with self._build_session(options) as session: + finder = self._build_package_finder(options, session) + build_delete = (not (options.no_clean or options.build_dir)) + wheel_cache = WheelCache(options.cache_dir, options.format_control) + + if options.cache_dir and not check_path_owner(options.cache_dir): + logger.warning( + "The directory '%s' or its parent directory is not owned " + "by the current user and caching wheels has been " + "disabled. check the permissions and owner of that " + "directory. If executing pip with sudo, you may want " + "sudo's -H flag.", + options.cache_dir, + ) + options.cache_dir = None + + with TempDirectory( + options.build_dir, delete=build_delete, kind="install" + ) as directory: + requirement_set = RequirementSet( + require_hashes=options.require_hashes, + ) + + try: + self.populate_requirement_set( + requirement_set, args, options, finder, session, + self.name, wheel_cache + ) + preparer = RequirementPreparer( + build_dir=directory.path, + src_dir=options.src_dir, + download_dir=None, + wheel_download_dir=None, + progress_bar=options.progress_bar, + build_isolation=options.build_isolation, + ) + + resolver = Resolver( + preparer=preparer, + finder=finder, + session=session, + wheel_cache=wheel_cache, + use_user_site=options.use_user_site, + upgrade_strategy=upgrade_strategy, + force_reinstall=options.force_reinstall, + ignore_dependencies=options.ignore_dependencies, + ignore_requires_python=options.ignore_requires_python, + ignore_installed=options.ignore_installed, + isolated=options.isolated_mode, + ) + resolver.resolve(requirement_set) + + # If caching is disabled or wheel is not installed don't + # try to build wheels. + if wheel and options.cache_dir: + # build wheels before install. + wb = WheelBuilder( + finder, preparer, wheel_cache, + build_options=[], global_options=[], + ) + # Ignore the result: a failed wheel will be + # installed from the sdist/vcs whatever. + wb.build( + requirement_set.requirements.values(), + session=session, autobuilding=True + ) + + to_install = resolver.get_installation_order( + requirement_set + ) + + # Consistency Checking of the package set we're installing. + should_warn_about_conflicts = ( + not options.ignore_dependencies and + options.warn_about_conflicts + ) + if should_warn_about_conflicts: + self._warn_about_conflicts(to_install) + + # Don't warn about script install locations if + # --target has been specified + warn_script_location = options.warn_script_location + if options.target_dir: + warn_script_location = False + + installed = install_given_reqs( + to_install, + install_options, + global_options, + root=options.root_path, + home=target_temp_dir.path, + prefix=options.prefix_path, + pycompile=options.compile, + warn_script_location=warn_script_location, + use_user_site=options.use_user_site, + ) + + possible_lib_locations = get_lib_location_guesses( + user=options.use_user_site, + home=target_temp_dir.path, + root=options.root_path, + prefix=options.prefix_path, + isolated=options.isolated_mode, + ) + reqs = sorted(installed, key=operator.attrgetter('name')) + items = [] + for req in reqs: + item = req.name + try: + installed_version = get_installed_version( + req.name, possible_lib_locations + ) + if installed_version: + item += '-' + installed_version + except Exception: + pass + items.append(item) + installed = ' '.join(items) + if installed: + logger.info('Successfully installed %s', installed) + except EnvironmentError as error: + show_traceback = (self.verbosity >= 1) + + message = create_env_error_message( + error, show_traceback, options.use_user_site, + ) + logger.error(message, exc_info=show_traceback) + + return ERROR + except PreviousBuildDirError: + options.no_clean = True + raise + finally: + # Clean up + if not options.no_clean: + requirement_set.cleanup_files() + wheel_cache.cleanup() + + if options.target_dir: + self._handle_target_dir( + options.target_dir, target_temp_dir, options.upgrade + ) + return requirement_set + + def _handle_target_dir(self, target_dir, target_temp_dir, upgrade): + ensure_dir(target_dir) + + # Checking both purelib and platlib directories for installed + # packages to be moved to target directory + lib_dir_list = [] + + with target_temp_dir: + # Checking both purelib and platlib directories for installed + # packages to be moved to target directory + scheme = distutils_scheme('', home=target_temp_dir.path) + purelib_dir = scheme['purelib'] + platlib_dir = scheme['platlib'] + data_dir = scheme['data'] + + if os.path.exists(purelib_dir): + lib_dir_list.append(purelib_dir) + if os.path.exists(platlib_dir) and platlib_dir != purelib_dir: + lib_dir_list.append(platlib_dir) + if os.path.exists(data_dir): + lib_dir_list.append(data_dir) + + for lib_dir in lib_dir_list: + for item in os.listdir(lib_dir): + if lib_dir == data_dir: + ddir = os.path.join(data_dir, item) + if any(s.startswith(ddir) for s in lib_dir_list[:-1]): + continue + target_item_dir = os.path.join(target_dir, item) + if os.path.exists(target_item_dir): + if not upgrade: + logger.warning( + 'Target directory %s already exists. Specify ' + '--upgrade to force replacement.', + target_item_dir + ) + continue + if os.path.islink(target_item_dir): + logger.warning( + 'Target directory %s already exists and is ' + 'a link. Pip will not automatically replace ' + 'links, please remove if replacement is ' + 'desired.', + target_item_dir + ) + continue + if os.path.isdir(target_item_dir): + shutil.rmtree(target_item_dir) + else: + os.remove(target_item_dir) + + shutil.move( + os.path.join(lib_dir, item), + target_item_dir + ) + + def _warn_about_conflicts(self, to_install): + package_set, _dep_info = check_install_conflicts(to_install) + missing, conflicting = _dep_info + + # NOTE: There is some duplication here from pip check + for project_name in missing: + version = package_set[project_name][0] + for dependency in missing[project_name]: + logger.critical( + "%s %s requires %s, which is not installed.", + project_name, version, dependency[1], + ) + + for project_name in conflicting: + version = package_set[project_name][0] + for dep_name, dep_version, req in conflicting[project_name]: + logger.critical( + "%s %s has requirement %s, but you'll have %s %s which is " + "incompatible.", + project_name, version, req, dep_name, dep_version, + ) + + +def get_lib_location_guesses(*args, **kwargs): + scheme = distutils_scheme('', *args, **kwargs) + return [scheme['purelib'], scheme['platlib']] + + +def create_env_error_message(error, show_traceback, using_user_site): + """Format an error message for an EnvironmentError + + It may occur anytime during the execution of the install command. + """ + parts = [] + + # Mention the error if we are not going to show a traceback + parts.append("Could not install packages due to an EnvironmentError") + if not show_traceback: + parts.append(": ") + parts.append(str(error)) + else: + parts.append(".") + + # Spilt the error indication from a helper message (if any) + parts[-1] += "\n" + + # Suggest useful actions to the user: + # (1) using user site-packages or (2) verifying the permissions + if error.errno == errno.EACCES: + user_option_part = "Consider using the `--user` option" + permissions_part = "Check the permissions" + + if not using_user_site: + parts.extend([ + user_option_part, " or ", + permissions_part.lower(), + ]) + else: + parts.append(permissions_part) + parts.append(".\n") + + return "".join(parts).strip() + "\n" diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/list.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/list.py new file mode 100644 index 0000000..09f633f --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/list.py @@ -0,0 +1,343 @@ +from __future__ import absolute_import + +import json +import logging +import warnings + +from pip._vendor import six +from pip._vendor.six.moves import zip_longest + +from pip._internal.basecommand import Command +from pip._internal.cmdoptions import index_group, make_option_group +from pip._internal.exceptions import CommandError +from pip._internal.index import PackageFinder +from pip._internal.utils.deprecation import RemovedInPip11Warning +from pip._internal.utils.misc import ( + dist_is_editable, get_installed_distributions, +) +from pip._internal.utils.packaging import get_installer + +logger = logging.getLogger(__name__) + + +class ListCommand(Command): + """ + List installed packages, including editables. + + Packages are listed in a case-insensitive sorted order. + """ + name = 'list' + usage = """ + %prog [options]""" + summary = 'List installed packages.' + + def __init__(self, *args, **kw): + super(ListCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option( + '-o', '--outdated', + action='store_true', + default=False, + help='List outdated packages') + cmd_opts.add_option( + '-u', '--uptodate', + action='store_true', + default=False, + help='List uptodate packages') + cmd_opts.add_option( + '-e', '--editable', + action='store_true', + default=False, + help='List editable projects.') + cmd_opts.add_option( + '-l', '--local', + action='store_true', + default=False, + help=('If in a virtualenv that has global access, do not list ' + 'globally-installed packages.'), + ) + self.cmd_opts.add_option( + '--user', + dest='user', + action='store_true', + default=False, + help='Only output packages installed in user-site.') + + cmd_opts.add_option( + '--pre', + action='store_true', + default=False, + help=("Include pre-release and development versions. By default, " + "pip only finds stable versions."), + ) + + cmd_opts.add_option( + '--format', + action='store', + dest='list_format', + default="columns", + choices=('legacy', 'columns', 'freeze', 'json'), + help="Select the output format among: columns (default), freeze, " + "json, or legacy.", + ) + + cmd_opts.add_option( + '--not-required', + action='store_true', + dest='not_required', + help="List packages that are not dependencies of " + "installed packages.", + ) + + cmd_opts.add_option( + '--exclude-editable', + action='store_false', + dest='include_editable', + help='Exclude editable package from output.', + ) + cmd_opts.add_option( + '--include-editable', + action='store_true', + dest='include_editable', + help='Include editable package from output.', + default=True, + ) + index_opts = make_option_group(index_group, self.parser) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def _build_package_finder(self, options, index_urls, session): + """ + Create a package finder appropriate to this list command. + """ + return PackageFinder( + find_links=options.find_links, + index_urls=index_urls, + allow_all_prereleases=options.pre, + trusted_hosts=options.trusted_hosts, + process_dependency_links=options.process_dependency_links, + session=session, + ) + + def run(self, options, args): + if options.list_format == "legacy": + warnings.warn( + "The legacy format has been deprecated and will be removed " + "in the future.", + RemovedInPip11Warning, + ) + + if options.outdated and options.uptodate: + raise CommandError( + "Options --outdated and --uptodate cannot be combined.") + + packages = get_installed_distributions( + local_only=options.local, + user_only=options.user, + editables_only=options.editable, + include_editables=options.include_editable, + ) + + if options.outdated: + packages = self.get_outdated(packages, options) + elif options.uptodate: + packages = self.get_uptodate(packages, options) + + if options.not_required: + packages = self.get_not_required(packages, options) + + self.output_package_listing(packages, options) + + def get_outdated(self, packages, options): + return [ + dist for dist in self.iter_packages_latest_infos(packages, options) + if dist.latest_version > dist.parsed_version + ] + + def get_uptodate(self, packages, options): + return [ + dist for dist in self.iter_packages_latest_infos(packages, options) + if dist.latest_version == dist.parsed_version + ] + + def get_not_required(self, packages, options): + dep_keys = set() + for dist in packages: + dep_keys.update(requirement.key for requirement in dist.requires()) + return {pkg for pkg in packages if pkg.key not in dep_keys} + + def iter_packages_latest_infos(self, packages, options): + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.debug('Ignoring indexes: %s', ','.join(index_urls)) + index_urls = [] + + dependency_links = [] + for dist in packages: + if dist.has_metadata('dependency_links.txt'): + dependency_links.extend( + dist.get_metadata_lines('dependency_links.txt'), + ) + + with self._build_session(options) as session: + finder = self._build_package_finder(options, index_urls, session) + finder.add_dependency_links(dependency_links) + + for dist in packages: + typ = 'unknown' + all_candidates = finder.find_all_candidates(dist.key) + if not options.pre: + # Remove prereleases + all_candidates = [candidate for candidate in all_candidates + if not candidate.version.is_prerelease] + + if not all_candidates: + continue + best_candidate = max(all_candidates, + key=finder._candidate_sort_key) + remote_version = best_candidate.version + if best_candidate.location.is_wheel: + typ = 'wheel' + else: + typ = 'sdist' + # This is dirty but makes the rest of the code much cleaner + dist.latest_version = remote_version + dist.latest_filetype = typ + yield dist + + def output_legacy(self, dist, options): + if options.verbose >= 1: + return '%s (%s, %s, %s)' % ( + dist.project_name, + dist.version, + dist.location, + get_installer(dist), + ) + elif dist_is_editable(dist): + return '%s (%s, %s)' % ( + dist.project_name, + dist.version, + dist.location, + ) + else: + return '%s (%s)' % (dist.project_name, dist.version) + + def output_legacy_latest(self, dist, options): + return '%s - Latest: %s [%s]' % ( + self.output_legacy(dist, options), + dist.latest_version, + dist.latest_filetype, + ) + + def output_package_listing(self, packages, options): + packages = sorted( + packages, + key=lambda dist: dist.project_name.lower(), + ) + if options.list_format == 'columns' and packages: + data, header = format_for_columns(packages, options) + self.output_package_listing_columns(data, header) + elif options.list_format == 'freeze': + for dist in packages: + if options.verbose >= 1: + logger.info("%s==%s (%s)", dist.project_name, + dist.version, dist.location) + else: + logger.info("%s==%s", dist.project_name, dist.version) + elif options.list_format == 'json': + logger.info(format_for_json(packages, options)) + elif options.list_format == "legacy": + for dist in packages: + if options.outdated: + logger.info(self.output_legacy_latest(dist, options)) + else: + logger.info(self.output_legacy(dist, options)) + + def output_package_listing_columns(self, data, header): + # insert the header first: we need to know the size of column names + if len(data) > 0: + data.insert(0, header) + + pkg_strings, sizes = tabulate(data) + + # Create and add a separator. + if len(data) > 0: + pkg_strings.insert(1, " ".join(map(lambda x: '-' * x, sizes))) + + for val in pkg_strings: + logger.info(val) + + +def tabulate(vals): + # From pfmoore on GitHub: + # https://github.com/pypa/pip/issues/3651#issuecomment-216932564 + assert len(vals) > 0 + + sizes = [0] * max(len(x) for x in vals) + for row in vals: + sizes = [max(s, len(str(c))) for s, c in zip_longest(sizes, row)] + + result = [] + for row in vals: + display = " ".join([str(c).ljust(s) if c is not None else '' + for s, c in zip_longest(sizes, row)]) + result.append(display) + + return result, sizes + + +def format_for_columns(pkgs, options): + """ + Convert the package data into something usable + by output_package_listing_columns. + """ + running_outdated = options.outdated + # Adjust the header for the `pip list --outdated` case. + if running_outdated: + header = ["Package", "Version", "Latest", "Type"] + else: + header = ["Package", "Version"] + + data = [] + if options.verbose >= 1 or any(dist_is_editable(x) for x in pkgs): + header.append("Location") + if options.verbose >= 1: + header.append("Installer") + + for proj in pkgs: + # if we're working on the 'outdated' list, separate out the + # latest_version and type + row = [proj.project_name, proj.version] + + if running_outdated: + row.append(proj.latest_version) + row.append(proj.latest_filetype) + + if options.verbose >= 1 or dist_is_editable(proj): + row.append(proj.location) + if options.verbose >= 1: + row.append(get_installer(proj)) + + data.append(row) + + return data, header + + +def format_for_json(packages, options): + data = [] + for dist in packages: + info = { + 'name': dist.project_name, + 'version': six.text_type(dist.version), + } + if options.verbose >= 1: + info['location'] = dist.location + info['installer'] = get_installer(dist) + if options.outdated: + info['latest_version'] = six.text_type(dist.latest_version) + info['latest_filetype'] = dist.latest_filetype + data.append(info) + return json.dumps(data) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/search.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/search.py new file mode 100644 index 0000000..3abdf59 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/search.py @@ -0,0 +1,135 @@ +from __future__ import absolute_import + +import logging +import sys +import textwrap +from collections import OrderedDict + +from pip._vendor import pkg_resources +from pip._vendor.packaging.version import parse as parse_version +# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import +from pip._vendor.six.moves import xmlrpc_client # type: ignore + +from pip._internal.basecommand import SUCCESS, Command +from pip._internal.compat import get_terminal_size +from pip._internal.download import PipXmlrpcTransport +from pip._internal.exceptions import CommandError +from pip._internal.models import PyPI +from pip._internal.status_codes import NO_MATCHES_FOUND +from pip._internal.utils.logging import indent_log + +logger = logging.getLogger(__name__) + + +class SearchCommand(Command): + """Search for PyPI packages whose name or summary contains .""" + name = 'search' + usage = """ + %prog [options] """ + summary = 'Search PyPI for packages.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(SearchCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-i', '--index', + dest='index', + metavar='URL', + default=PyPI.pypi_url, + help='Base URL of Python Package Index (default %default)') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + raise CommandError('Missing required argument (search query).') + query = args + pypi_hits = self.search(query, options) + hits = transform_hits(pypi_hits) + + terminal_width = None + if sys.stdout.isatty(): + terminal_width = get_terminal_size()[0] + + print_results(hits, terminal_width=terminal_width) + if pypi_hits: + return SUCCESS + return NO_MATCHES_FOUND + + def search(self, query, options): + index_url = options.index + with self._build_session(options) as session: + transport = PipXmlrpcTransport(index_url, session) + pypi = xmlrpc_client.ServerProxy(index_url, transport) + hits = pypi.search({'name': query, 'summary': query}, 'or') + return hits + + +def transform_hits(hits): + """ + The list from pypi is really a list of versions. We want a list of + packages with the list of versions stored inline. This converts the + list from pypi into one we can use. + """ + packages = OrderedDict() + for hit in hits: + name = hit['name'] + summary = hit['summary'] + version = hit['version'] + + if name not in packages.keys(): + packages[name] = { + 'name': name, + 'summary': summary, + 'versions': [version], + } + else: + packages[name]['versions'].append(version) + + # if this is the highest version, replace summary and score + if version == highest_version(packages[name]['versions']): + packages[name]['summary'] = summary + + return list(packages.values()) + + +def print_results(hits, name_column_width=None, terminal_width=None): + if not hits: + return + if name_column_width is None: + name_column_width = max([ + len(hit['name']) + len(highest_version(hit.get('versions', ['-']))) + for hit in hits + ]) + 4 + + installed_packages = [p.project_name for p in pkg_resources.working_set] + for hit in hits: + name = hit['name'] + summary = hit['summary'] or '' + latest = highest_version(hit.get('versions', ['-'])) + if terminal_width is not None: + target_width = terminal_width - name_column_width - 5 + if target_width > 10: + # wrap and indent summary to fit terminal + summary = textwrap.wrap(summary, target_width) + summary = ('\n' + ' ' * (name_column_width + 3)).join(summary) + + line = '%-*s - %s' % (name_column_width, + '%s (%s)' % (name, latest), summary) + try: + logger.info(line) + if name in installed_packages: + dist = pkg_resources.get_distribution(name) + with indent_log(): + if dist.version == latest: + logger.info('INSTALLED: %s (latest)', dist.version) + else: + logger.info('INSTALLED: %s', dist.version) + logger.info('LATEST: %s', latest) + except UnicodeEncodeError: + pass + + +def highest_version(versions): + return max(versions, key=parse_version) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/show.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/show.py new file mode 100644 index 0000000..1a8d968 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/show.py @@ -0,0 +1,164 @@ +from __future__ import absolute_import + +import logging +import os +from email.parser import FeedParser # type: ignore + +from pip._vendor import pkg_resources +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.basecommand import Command +from pip._internal.status_codes import ERROR, SUCCESS + +logger = logging.getLogger(__name__) + + +class ShowCommand(Command): + """Show information about one or more installed packages.""" + name = 'show' + usage = """ + %prog [options] ...""" + summary = 'Show information about installed packages.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(ShowCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-f', '--files', + dest='files', + action='store_true', + default=False, + help='Show the full list of installed files for each package.') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + logger.warning('ERROR: Please provide a package name or names.') + return ERROR + query = args + + results = search_packages_info(query) + if not print_results( + results, list_files=options.files, verbose=options.verbose): + return ERROR + return SUCCESS + + +def search_packages_info(query): + """ + Gather details from installed distributions. Print distribution name, + version, location, and installed files. Installed files requires a + pip generated 'installed-files.txt' in the distributions '.egg-info' + directory. + """ + installed = {} + for p in pkg_resources.working_set: + installed[canonicalize_name(p.project_name)] = p + + query_names = [canonicalize_name(name) for name in query] + + for dist in [installed[pkg] for pkg in query_names if pkg in installed]: + package = { + 'name': dist.project_name, + 'version': dist.version, + 'location': dist.location, + 'requires': [dep.project_name for dep in dist.requires()], + } + file_list = None + metadata = None + if isinstance(dist, pkg_resources.DistInfoDistribution): + # RECORDs should be part of .dist-info metadatas + if dist.has_metadata('RECORD'): + lines = dist.get_metadata_lines('RECORD') + paths = [l.split(',')[0] for l in lines] + paths = [os.path.join(dist.location, p) for p in paths] + file_list = [os.path.relpath(p, dist.location) for p in paths] + + if dist.has_metadata('METADATA'): + metadata = dist.get_metadata('METADATA') + else: + # Otherwise use pip's log for .egg-info's + if dist.has_metadata('installed-files.txt'): + paths = dist.get_metadata_lines('installed-files.txt') + paths = [os.path.join(dist.egg_info, p) for p in paths] + file_list = [os.path.relpath(p, dist.location) for p in paths] + + if dist.has_metadata('PKG-INFO'): + metadata = dist.get_metadata('PKG-INFO') + + if dist.has_metadata('entry_points.txt'): + entry_points = dist.get_metadata_lines('entry_points.txt') + package['entry_points'] = entry_points + + if dist.has_metadata('INSTALLER'): + for line in dist.get_metadata_lines('INSTALLER'): + if line.strip(): + package['installer'] = line.strip() + break + + # @todo: Should pkg_resources.Distribution have a + # `get_pkg_info` method? + feed_parser = FeedParser() + feed_parser.feed(metadata) + pkg_info_dict = feed_parser.close() + for key in ('metadata-version', 'summary', + 'home-page', 'author', 'author-email', 'license'): + package[key] = pkg_info_dict.get(key) + + # It looks like FeedParser cannot deal with repeated headers + classifiers = [] + for line in metadata.splitlines(): + if line.startswith('Classifier: '): + classifiers.append(line[len('Classifier: '):]) + package['classifiers'] = classifiers + + if file_list: + package['files'] = sorted(file_list) + yield package + + +def print_results(distributions, list_files=False, verbose=False): + """ + Print the informations from installed distributions found. + """ + results_printed = False + for i, dist in enumerate(distributions): + results_printed = True + if i > 0: + logger.info("---") + + name = dist.get('name', '') + required_by = [ + pkg.project_name for pkg in pkg_resources.working_set + if name in [required.name for required in pkg.requires()] + ] + + logger.info("Name: %s", name) + logger.info("Version: %s", dist.get('version', '')) + logger.info("Summary: %s", dist.get('summary', '')) + logger.info("Home-page: %s", dist.get('home-page', '')) + logger.info("Author: %s", dist.get('author', '')) + logger.info("Author-email: %s", dist.get('author-email', '')) + logger.info("License: %s", dist.get('license', '')) + logger.info("Location: %s", dist.get('location', '')) + logger.info("Requires: %s", ', '.join(dist.get('requires', []))) + logger.info("Required-by: %s", ', '.join(required_by)) + + if verbose: + logger.info("Metadata-Version: %s", + dist.get('metadata-version', '')) + logger.info("Installer: %s", dist.get('installer', '')) + logger.info("Classifiers:") + for classifier in dist.get('classifiers', []): + logger.info(" %s", classifier) + logger.info("Entry-points:") + for entry in dist.get('entry_points', []): + logger.info(" %s", entry.strip()) + if list_files: + logger.info("Files:") + for line in dist.get('files', []): + logger.info(" %s", line.strip()) + if "files" not in dist: + logger.info("Cannot locate installed-files.txt") + return results_printed diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/uninstall.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/uninstall.py new file mode 100644 index 0000000..7476fa6 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/uninstall.py @@ -0,0 +1,71 @@ +from __future__ import absolute_import + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.basecommand import Command +from pip._internal.exceptions import InstallationError +from pip._internal.req import InstallRequirement, parse_requirements + + +class UninstallCommand(Command): + """ + Uninstall packages. + + pip is able to uninstall most installed packages. Known exceptions are: + + - Pure distutils packages installed with ``python setup.py install``, which + leave behind no metadata to determine what files were installed. + - Script wrappers installed by ``python setup.py develop``. + """ + name = 'uninstall' + usage = """ + %prog [options] ... + %prog [options] -r ...""" + summary = 'Uninstall packages.' + + def __init__(self, *args, **kw): + super(UninstallCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help='Uninstall all the packages listed in the given requirements ' + 'file. This option can be used multiple times.', + ) + self.cmd_opts.add_option( + '-y', '--yes', + dest='yes', + action='store_true', + help="Don't ask for confirmation of uninstall deletions.") + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + with self._build_session(options) as session: + reqs_to_uninstall = {} + for name in args: + req = InstallRequirement.from_line( + name, isolated=options.isolated_mode, + ) + if req.name: + reqs_to_uninstall[canonicalize_name(req.name)] = req + for filename in options.requirements: + for req in parse_requirements( + filename, + options=options, + session=session): + if req.name: + reqs_to_uninstall[canonicalize_name(req.name)] = req + if not reqs_to_uninstall: + raise InstallationError( + 'You must give at least one requirement to %(name)s (see ' + '"pip help %(name)s")' % dict(name=self.name) + ) + for req in reqs_to_uninstall.values(): + uninstall_pathset = req.uninstall( + auto_confirm=options.yes, verbose=self.verbosity > 0, + ) + if uninstall_pathset: + uninstall_pathset.commit() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/wheel.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/wheel.py new file mode 100644 index 0000000..ac55f91 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/wheel.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import logging +import os + +from pip._internal import cmdoptions +from pip._internal.basecommand import RequirementCommand +from pip._internal.cache import WheelCache +from pip._internal.exceptions import CommandError, PreviousBuildDirError +from pip._internal.operations.prepare import RequirementPreparer +from pip._internal.req import RequirementSet +from pip._internal.resolve import Resolver +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.wheel import WheelBuilder + +logger = logging.getLogger(__name__) + + +class WheelCommand(RequirementCommand): + """ + Build Wheel archives for your requirements and dependencies. + + Wheel is a built-package format, and offers the advantage of not + recompiling your software during every install. For more details, see the + wheel docs: https://wheel.readthedocs.io/en/latest/ + + Requirements: setuptools>=0.8, and wheel. + + 'pip wheel' uses the bdist_wheel setuptools extension from the wheel + package to build individual wheels. + + """ + + name = 'wheel' + usage = """ + %prog [options] ... + %prog [options] -r ... + %prog [options] [-e] ... + %prog [options] [-e] ... + %prog [options] ...""" + + summary = 'Build wheels from your requirements.' + + def __init__(self, *args, **kw): + super(WheelCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option( + '-w', '--wheel-dir', + dest='wheel_dir', + metavar='dir', + default=os.curdir, + help=("Build wheels into , where the default is the " + "current working directory."), + ) + cmd_opts.add_option(cmdoptions.no_binary()) + cmd_opts.add_option(cmdoptions.only_binary()) + cmd_opts.add_option( + '--build-option', + dest='build_options', + metavar='options', + action='append', + help="Extra arguments to be supplied to 'setup.py bdist_wheel'.", + ) + cmd_opts.add_option(cmdoptions.no_build_isolation()) + cmd_opts.add_option(cmdoptions.constraints()) + cmd_opts.add_option(cmdoptions.editable()) + cmd_opts.add_option(cmdoptions.requirements()) + cmd_opts.add_option(cmdoptions.src()) + cmd_opts.add_option(cmdoptions.ignore_requires_python()) + cmd_opts.add_option(cmdoptions.no_deps()) + cmd_opts.add_option(cmdoptions.build_dir()) + cmd_opts.add_option(cmdoptions.progress_bar()) + + cmd_opts.add_option( + '--global-option', + dest='global_options', + action='append', + metavar='options', + help="Extra global options to be supplied to the setup.py " + "call before the 'bdist_wheel' command.") + + cmd_opts.add_option( + '--pre', + action='store_true', + default=False, + help=("Include pre-release and development versions. By default, " + "pip only finds stable versions."), + ) + + cmd_opts.add_option(cmdoptions.no_clean()) + cmd_opts.add_option(cmdoptions.require_hashes()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + cmdoptions.check_install_build_global(options) + + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.debug('Ignoring indexes: %s', ','.join(index_urls)) + index_urls = [] + + if options.build_dir: + options.build_dir = os.path.abspath(options.build_dir) + + options.src_dir = os.path.abspath(options.src_dir) + + with self._build_session(options) as session: + finder = self._build_package_finder(options, session) + build_delete = (not (options.no_clean or options.build_dir)) + wheel_cache = WheelCache(options.cache_dir, options.format_control) + + with TempDirectory( + options.build_dir, delete=build_delete, kind="wheel" + ) as directory: + requirement_set = RequirementSet( + require_hashes=options.require_hashes, + ) + + try: + self.populate_requirement_set( + requirement_set, args, options, finder, session, + self.name, wheel_cache + ) + + preparer = RequirementPreparer( + build_dir=directory.path, + src_dir=options.src_dir, + download_dir=None, + wheel_download_dir=options.wheel_dir, + progress_bar=options.progress_bar, + build_isolation=options.build_isolation, + ) + + resolver = Resolver( + preparer=preparer, + finder=finder, + session=session, + wheel_cache=wheel_cache, + use_user_site=False, + upgrade_strategy="to-satisfy-only", + force_reinstall=False, + ignore_dependencies=options.ignore_dependencies, + ignore_requires_python=options.ignore_requires_python, + ignore_installed=True, + isolated=options.isolated_mode, + ) + resolver.resolve(requirement_set) + + # build wheels + wb = WheelBuilder( + finder, preparer, wheel_cache, + build_options=options.build_options or [], + global_options=options.global_options or [], + no_clean=options.no_clean, + ) + wheels_built_successfully = wb.build( + requirement_set.requirements.values(), session=session, + ) + if not wheels_built_successfully: + raise CommandError( + "Failed to build one or more wheels" + ) + except PreviousBuildDirError: + options.no_clean = True + raise + finally: + if not options.no_clean: + requirement_set.cleanup_files() + wheel_cache.cleanup() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/compat.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/compat.py new file mode 100644 index 0000000..4aefd58 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/compat.py @@ -0,0 +1,235 @@ +"""Stuff that differs in different Python versions and platform +distributions.""" +from __future__ import absolute_import, division + +import codecs +import locale +import logging +import os +import shutil +import sys + +from pip._vendor.six import text_type + +try: + import ipaddress +except ImportError: + try: + from pip._vendor import ipaddress # type: ignore + except ImportError: + import ipaddr as ipaddress # type: ignore + ipaddress.ip_address = ipaddress.IPAddress + ipaddress.ip_network = ipaddress.IPNetwork + + +__all__ = [ + "ipaddress", "uses_pycache", "console_to_str", "native_str", + "get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile", "get_terminal_size", +] + + +logger = logging.getLogger(__name__) + +if sys.version_info >= (3, 4): + uses_pycache = True + from importlib.util import cache_from_source +else: + import imp + + try: + cache_from_source = imp.cache_from_source # type: ignore + except AttributeError: + # does not use __pycache__ + cache_from_source = None + + uses_pycache = cache_from_source is not None + + +if sys.version_info >= (3, 5): + backslashreplace_decode = "backslashreplace" +else: + # In version 3.4 and older, backslashreplace exists + # but does not support use for decoding. + # We implement our own replace handler for this + # situation, so that we can consistently use + # backslash replacement for all versions. + def backslashreplace_decode_fn(err): + raw_bytes = (err.object[i] for i in range(err.start, err.end)) + if sys.version_info[0] == 2: + # Python 2 gave us characters - convert to numeric bytes + raw_bytes = (ord(b) for b in raw_bytes) + return u"".join(u"\\x%x" % c for c in raw_bytes), err.end + codecs.register_error( + "backslashreplace_decode", + backslashreplace_decode_fn, + ) + backslashreplace_decode = "backslashreplace_decode" + + +def console_to_str(data): + """Return a string, safe for output, of subprocess output. + + We assume the data is in the locale preferred encoding. + If it won't decode properly, we warn the user but decode as + best we can. + + We also ensure that the output can be safely written to + standard output without encoding errors. + """ + + # First, get the encoding we assume. This is the preferred + # encoding for the locale, unless that is not found, or + # it is ASCII, in which case assume UTF-8 + encoding = locale.getpreferredencoding() + if (not encoding) or codecs.lookup(encoding).name == "ascii": + encoding = "utf-8" + + # Now try to decode the data - if we fail, warn the user and + # decode with replacement. + try: + s = data.decode(encoding) + except UnicodeDecodeError: + logger.warning( + "Subprocess output does not appear to be encoded as %s", + encoding, + ) + s = data.decode(encoding, errors=backslashreplace_decode) + + # Make sure we can print the output, by encoding it to the output + # encoding with replacement of unencodable characters, and then + # decoding again. + # We use stderr's encoding because it's less likely to be + # redirected and if we don't find an encoding we skip this + # step (on the assumption that output is wrapped by something + # that won't fail). + # The double getattr is to deal with the possibility that we're + # being called in a situation where sys.__stderr__ doesn't exist, + # or doesn't have an encoding attribute. Neither of these cases + # should occur in normal pip use, but there's no harm in checking + # in case people use pip in (unsupported) unusual situations. + output_encoding = getattr(getattr(sys, "__stderr__", None), + "encoding", None) + + if output_encoding: + s = s.encode(output_encoding, errors="backslashreplace") + s = s.decode(output_encoding) + + return s + + +if sys.version_info >= (3,): + def native_str(s, replace=False): + if isinstance(s, bytes): + return s.decode('utf-8', 'replace' if replace else 'strict') + return s + +else: + def native_str(s, replace=False): + # Replace is ignored -- unicode to UTF-8 can't fail + if isinstance(s, text_type): + return s.encode('utf-8') + return s + + +def get_path_uid(path): + """ + Return path's uid. + + Does not follow symlinks: + https://github.com/pypa/pip/pull/935#discussion_r5307003 + + Placed this function in compat due to differences on AIX and + Jython, that should eventually go away. + + :raises OSError: When path is a symlink or can't be read. + """ + if hasattr(os, 'O_NOFOLLOW'): + fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW) + file_uid = os.fstat(fd).st_uid + os.close(fd) + else: # AIX and Jython + # WARNING: time of check vulnerability, but best we can do w/o NOFOLLOW + if not os.path.islink(path): + # older versions of Jython don't have `os.fstat` + file_uid = os.stat(path).st_uid + else: + # raise OSError for parity with os.O_NOFOLLOW above + raise OSError( + "%s is a symlink; Will not return uid for symlinks" % path + ) + return file_uid + + +def expanduser(path): + """ + Expand ~ and ~user constructions. + + Includes a workaround for http://bugs.python.org/issue14768 + """ + expanded = os.path.expanduser(path) + if path.startswith('~/') and expanded.startswith('//'): + expanded = expanded[1:] + return expanded + + +# packages in the stdlib that may have installation metadata, but should not be +# considered 'installed'. this theoretically could be determined based on +# dist.location (py27:`sysconfig.get_paths()['stdlib']`, +# py26:sysconfig.get_config_vars('LIBDEST')), but fear platform variation may +# make this ineffective, so hard-coding +stdlib_pkgs = {"python", "wsgiref", "argparse"} + + +# windows detection, covers cpython and ironpython +WINDOWS = (sys.platform.startswith("win") or + (sys.platform == 'cli' and os.name == 'nt')) + + +def samefile(file1, file2): + """Provide an alternative for os.path.samefile on Windows/Python2""" + if hasattr(os.path, 'samefile'): + return os.path.samefile(file1, file2) + else: + path1 = os.path.normcase(os.path.abspath(file1)) + path2 = os.path.normcase(os.path.abspath(file2)) + return path1 == path2 + + +if hasattr(shutil, 'get_terminal_size'): + def get_terminal_size(): + """ + Returns a tuple (x, y) representing the width(x) and the height(y) + in characters of the terminal window. + """ + return tuple(shutil.get_terminal_size()) +else: + def get_terminal_size(): + """ + Returns a tuple (x, y) representing the width(x) and the height(y) + in characters of the terminal window. + """ + def ioctl_GWINSZ(fd): + try: + import fcntl + import termios + import struct + cr = struct.unpack_from( + 'hh', + fcntl.ioctl(fd, termios.TIOCGWINSZ, '12345678') + ) + except: + return None + if cr == (0, 0): + return None + return cr + cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) + if not cr: + try: + fd = os.open(os.ctermid(), os.O_RDONLY) + cr = ioctl_GWINSZ(fd) + os.close(fd) + except: + pass + if not cr: + cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80)) + return int(cr[1]), int(cr[0]) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/configuration.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/configuration.py new file mode 100644 index 0000000..b15e3d5 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/configuration.py @@ -0,0 +1,378 @@ +"""Configuration management setup + +Some terminology: +- name + As written in config files. +- value + Value associated with a name +- key + Name combined with it's section (section.name) +- variant + A single word describing where the configuration key-value pair came from +""" + +import locale +import logging +import os + +from pip._vendor import six +from pip._vendor.six.moves import configparser + +from pip._internal.exceptions import ConfigurationError +from pip._internal.locations import ( + legacy_config_file, new_config_file, running_under_virtualenv, + site_config_files, venv_config_file, +) +from pip._internal.utils.misc import ensure_dir, enum +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Dict, Iterable, List, NewType, Optional, Tuple + + RawConfigParser = configparser.RawConfigParser # Shorthand + Kind = NewType("Kind", str) + +logger = logging.getLogger(__name__) + + +# NOTE: Maybe use the optionx attribute to normalize keynames. +def _normalize_name(name): + # type: (str) -> str + """Make a name consistent regardless of source (environment or file) + """ + name = name.lower().replace('_', '-') + if name.startswith('--'): + name = name[2:] # only prefer long opts + return name + + +def _disassemble_key(name): + # type: (str) -> List[str] + return name.split(".", 1) + + +# The kinds of configurations there are. +kinds = enum( + USER="user", # User Specific + GLOBAL="global", # System Wide + VENV="venv", # Virtual Environment Specific + ENV="env", # from PIP_CONFIG_FILE + ENV_VAR="env-var", # from Environment Variables +) + + +class Configuration(object): + """Handles management of configuration. + + Provides an interface to accessing and managing configuration files. + + This class converts provides an API that takes "section.key-name" style + keys and stores the value associated with it as "key-name" under the + section "section". + + This allows for a clean interface wherein the both the section and the + key-name are preserved in an easy to manage form in the configuration files + and the data stored is also nice. + """ + + def __init__(self, isolated, load_only=None): + # type: (bool, Kind) -> None + super(Configuration, self).__init__() + + _valid_load_only = [kinds.USER, kinds.GLOBAL, kinds.VENV, None] + if load_only not in _valid_load_only: + raise ConfigurationError( + "Got invalid value for load_only - should be one of {}".format( + ", ".join(map(repr, _valid_load_only[:-1])) + ) + ) + self.isolated = isolated # type: bool + self.load_only = load_only # type: Optional[Kind] + + # The order here determines the override order. + self._override_order = [ + kinds.GLOBAL, kinds.USER, kinds.VENV, kinds.ENV, kinds.ENV_VAR + ] + + self._ignore_env_names = ["version", "help"] + + # Because we keep track of where we got the data from + self._parsers = { + variant: [] for variant in self._override_order + } # type: Dict[Kind, List[Tuple[str, RawConfigParser]]] + self._config = { + variant: {} for variant in self._override_order + } # type: Dict[Kind, Dict[str, Any]] + self._modified_parsers = [] # type: List[Tuple[str, RawConfigParser]] + + def load(self): + # type: () -> None + """Loads configuration from configuration files and environment + """ + self._load_config_files() + if not self.isolated: + self._load_environment_vars() + + def get_file_to_edit(self): + # type: () -> Optional[str] + """Returns the file with highest priority in configuration + """ + assert self.load_only is not None, \ + "Need to be specified a file to be editing" + + try: + return self._get_parser_to_modify()[0] + except IndexError: + return None + + def items(self): + # type: () -> Iterable[Tuple[str, Any]] + """Returns key-value pairs like dict.items() representing the loaded + configuration + """ + return self._dictionary.items() + + def get_value(self, key): + # type: (str) -> Any + """Get a value from the configuration. + """ + try: + return self._dictionary[key] + except KeyError: + raise ConfigurationError("No such key - {}".format(key)) + + def set_value(self, key, value): + # type: (str, Any) -> None + """Modify a value in the configuration. + """ + self._ensure_have_load_only() + + fname, parser = self._get_parser_to_modify() + + if parser is not None: + section, name = _disassemble_key(key) + + # Modify the parser and the configuration + if not parser.has_section(section): + parser.add_section(section) + parser.set(section, name, value) + + self._config[self.load_only][key] = value + self._mark_as_modified(fname, parser) + + def unset_value(self, key): + # type: (str) -> None + """Unset a value in the configuration. + """ + self._ensure_have_load_only() + + if key not in self._config[self.load_only]: + raise ConfigurationError("No such key - {}".format(key)) + + fname, parser = self._get_parser_to_modify() + + if parser is not None: + section, name = _disassemble_key(key) + + # Remove the key in the parser + modified_something = False + if parser.has_section(section): + # Returns whether the option was removed or not + modified_something = parser.remove_option(section, name) + + if modified_something: + # name removed from parser, section may now be empty + section_iter = iter(parser.items(section)) + try: + val = six.next(section_iter) + except StopIteration: + val = None + + if val is None: + parser.remove_section(section) + + self._mark_as_modified(fname, parser) + else: + raise ConfigurationError( + "Fatal Internal error [id=1]. Please report as a bug." + ) + + del self._config[self.load_only][key] + + def save(self): + # type: () -> None + """Save the currentin-memory state. + """ + self._ensure_have_load_only() + + for fname, parser in self._modified_parsers: + logger.info("Writing to %s", fname) + + # Ensure directory exists. + ensure_dir(os.path.dirname(fname)) + + with open(fname, "w") as f: + parser.write(f) # type: ignore + + # + # Private routines + # + + def _ensure_have_load_only(self): + # type: () -> None + if self.load_only is None: + raise ConfigurationError("Needed a specific file to be modifying.") + logger.debug("Will be working with %s variant only", self.load_only) + + @property + def _dictionary(self): + # type: () -> Dict[str, Any] + """A dictionary representing the loaded configuration. + """ + # NOTE: Dictionaries are not populated if not loaded. So, conditionals + # are not needed here. + retval = {} + + for variant in self._override_order: + retval.update(self._config[variant]) + + return retval + + def _load_config_files(self): + # type: () -> None + """Loads configuration from configuration files + """ + config_files = dict(self._iter_config_files()) + if config_files[kinds.ENV][0:1] == [os.devnull]: + logger.debug( + "Skipping loading configuration files due to " + "environment's PIP_CONFIG_FILE being os.devnull" + ) + return + + for variant, files in config_files.items(): + for fname in files: + # If there's specific variant set in `load_only`, load only + # that variant, not the others. + if self.load_only is not None and variant != self.load_only: + logger.debug( + "Skipping file '%s' (variant: %s)", fname, variant + ) + continue + + parser = self._load_file(variant, fname) + + # Keeping track of the parsers used + self._parsers[variant].append((fname, parser)) + + def _load_file(self, variant, fname): + # type: (Kind, str) -> RawConfigParser + logger.debug("For variant '%s', will try loading '%s'", variant, fname) + parser = self._construct_parser(fname) + + for section in parser.sections(): + items = parser.items(section) + self._config[variant].update(self._normalized_keys(section, items)) + + return parser + + def _construct_parser(self, fname): + # type: (str) -> RawConfigParser + parser = configparser.RawConfigParser() + # If there is no such file, don't bother reading it but create the + # parser anyway, to hold the data. + # Doing this is useful when modifying and saving files, where we don't + # need to construct a parser. + if os.path.exists(fname): + try: + parser.read(fname) + except UnicodeDecodeError: + raise ConfigurationError(( + "ERROR: " + "Configuration file contains invalid %s characters.\n" + "Please fix your configuration, located at %s\n" + ) % (locale.getpreferredencoding(False), fname)) + return parser + + def _load_environment_vars(self): + # type: () -> None + """Loads configuration from environment variables + """ + self._config[kinds.ENV_VAR].update( + self._normalized_keys(":env:", self._get_environ_vars()) + ) + + def _normalized_keys(self, section, items): + # type: (str, Iterable[Tuple[str, Any]]) -> Dict[str, Any] + """Normalizes items to construct a dictionary with normalized keys. + + This routine is where the names become keys and are made the same + regardless of source - configuration files or environment. + """ + normalized = {} + for name, val in items: + key = section + "." + _normalize_name(name) + normalized[key] = val + return normalized + + def _get_environ_vars(self): + # type: () -> Iterable[Tuple[str, str]] + """Returns a generator with all environmental vars with prefix PIP_""" + for key, val in os.environ.items(): + should_be_yielded = ( + key.startswith("PIP_") and + key[4:].lower() not in self._ignore_env_names + ) + if should_be_yielded: + yield key[4:].lower(), val + + # XXX: This is patched in the tests. + def _iter_config_files(self): + # type: () -> Iterable[Tuple[Kind, List[str]]] + """Yields variant and configuration files associated with it. + + This should be treated like items of a dictionary. + """ + # SMELL: Move the conditions out of this function + + # environment variables have the lowest priority + config_file = os.environ.get('PIP_CONFIG_FILE', None) + if config_file is not None: + yield kinds.ENV, [config_file] + else: + yield kinds.ENV, [] + + # at the base we have any global configuration + yield kinds.GLOBAL, list(site_config_files) + + # per-user configuration next + should_load_user_config = not self.isolated and not ( + config_file and os.path.exists(config_file) + ) + if should_load_user_config: + # The legacy config file is overridden by the new config file + yield kinds.USER, [legacy_config_file, new_config_file] + + # finally virtualenv configuration first trumping others + if running_under_virtualenv(): + yield kinds.VENV, [venv_config_file] + + def _get_parser_to_modify(self): + # type: () -> Tuple[str, RawConfigParser] + # Determine which parser to modify + parsers = self._parsers[self.load_only] + if not parsers: + # This should not happen if everything works correctly. + raise ConfigurationError( + "Fatal Internal error [id=2]. Please report as a bug." + ) + + # Use the highest priority parser. + return parsers[-1] + + # XXX: This is patched in the tests. + def _mark_as_modified(self, fname, parser): + # type: (str, RawConfigParser) -> None + file_parser_tuple = (fname, parser) + if file_parser_tuple not in self._modified_parsers: + self._modified_parsers.append(file_parser_tuple) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/download.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/download.py new file mode 100644 index 0000000..06d7201 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/download.py @@ -0,0 +1,922 @@ +from __future__ import absolute_import + +import cgi +import email.utils +import getpass +import json +import logging +import mimetypes +import os +import platform +import re +import shutil +import sys + +from pip._vendor import requests, six, urllib3 +from pip._vendor.cachecontrol import CacheControlAdapter +from pip._vendor.cachecontrol.caches import FileCache +from pip._vendor.lockfile import LockError +from pip._vendor.requests.adapters import BaseAdapter, HTTPAdapter +from pip._vendor.requests.auth import AuthBase, HTTPBasicAuth +from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response +from pip._vendor.requests.structures import CaseInsensitiveDict +from pip._vendor.requests.utils import get_netrc_auth +# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import +from pip._vendor.six.moves import xmlrpc_client # type: ignore +from pip._vendor.six.moves.urllib import parse as urllib_parse +from pip._vendor.six.moves.urllib import request as urllib_request +from pip._vendor.six.moves.urllib.parse import unquote as urllib_unquote +from pip._vendor.urllib3.util import IS_PYOPENSSL + +import pip +from pip._internal.compat import WINDOWS +from pip._internal.exceptions import HashMismatch, InstallationError +from pip._internal.locations import write_delete_marker_file +from pip._internal.models import PyPI +from pip._internal.utils.encoding import auto_decode +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.glibc import libc_ver +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + ARCHIVE_EXTENSIONS, ask_path_exists, backup_dir, call_subprocess, consume, + display_path, format_size, get_installed_version, rmtree, splitext, + unpack_file, +) +from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.ui import DownloadProgressProvider +from pip._internal.vcs import vcs + +try: + import ssl # noqa +except ImportError: + ssl = None + +HAS_TLS = (ssl is not None) or IS_PYOPENSSL + +__all__ = ['get_file_content', + 'is_url', 'url_to_path', 'path_to_url', + 'is_archive_file', 'unpack_vcs_link', + 'unpack_file_url', 'is_vcs_url', 'is_file_url', + 'unpack_http_url', 'unpack_url'] + + +logger = logging.getLogger(__name__) + + +def user_agent(): + """ + Return a string representing the user agent. + """ + data = { + "installer": {"name": "pip", "version": pip.__version__}, + "python": platform.python_version(), + "implementation": { + "name": platform.python_implementation(), + }, + } + + if data["implementation"]["name"] == 'CPython': + data["implementation"]["version"] = platform.python_version() + elif data["implementation"]["name"] == 'PyPy': + if sys.pypy_version_info.releaselevel == 'final': + pypy_version_info = sys.pypy_version_info[:3] + else: + pypy_version_info = sys.pypy_version_info + data["implementation"]["version"] = ".".join( + [str(x) for x in pypy_version_info] + ) + elif data["implementation"]["name"] == 'Jython': + # Complete Guess + data["implementation"]["version"] = platform.python_version() + elif data["implementation"]["name"] == 'IronPython': + # Complete Guess + data["implementation"]["version"] = platform.python_version() + + if sys.platform.startswith("linux"): + from pip._vendor import distro + distro_infos = dict(filter( + lambda x: x[1], + zip(["name", "version", "id"], distro.linux_distribution()), + )) + libc = dict(filter( + lambda x: x[1], + zip(["lib", "version"], libc_ver()), + )) + if libc: + distro_infos["libc"] = libc + if distro_infos: + data["distro"] = distro_infos + + if sys.platform.startswith("darwin") and platform.mac_ver()[0]: + data["distro"] = {"name": "macOS", "version": platform.mac_ver()[0]} + + if platform.system(): + data.setdefault("system", {})["name"] = platform.system() + + if platform.release(): + data.setdefault("system", {})["release"] = platform.release() + + if platform.machine(): + data["cpu"] = platform.machine() + + if HAS_TLS: + data["openssl_version"] = ssl.OPENSSL_VERSION + + setuptools_version = get_installed_version("setuptools") + if setuptools_version is not None: + data["setuptools_version"] = setuptools_version + + return "{data[installer][name]}/{data[installer][version]} {json}".format( + data=data, + json=json.dumps(data, separators=(",", ":"), sort_keys=True), + ) + + +class MultiDomainBasicAuth(AuthBase): + + def __init__(self, prompting=True): + self.prompting = prompting + self.passwords = {} + + def __call__(self, req): + parsed = urllib_parse.urlparse(req.url) + + # Get the netloc without any embedded credentials + netloc = parsed.netloc.rsplit("@", 1)[-1] + + # Set the url of the request to the url without any credentials + req.url = urllib_parse.urlunparse(parsed[:1] + (netloc,) + parsed[2:]) + + # Use any stored credentials that we have for this netloc + username, password = self.passwords.get(netloc, (None, None)) + + # Extract credentials embedded in the url if we have none stored + if username is None: + username, password = self.parse_credentials(parsed.netloc) + + # Get creds from netrc if we still don't have them + if username is None and password is None: + netrc_auth = get_netrc_auth(req.url) + username, password = netrc_auth if netrc_auth else (None, None) + + if username or password: + # Store the username and password + self.passwords[netloc] = (username, password) + + # Send the basic auth with this request + req = HTTPBasicAuth(username or "", password or "")(req) + + # Attach a hook to handle 401 responses + req.register_hook("response", self.handle_401) + + return req + + def handle_401(self, resp, **kwargs): + # We only care about 401 responses, anything else we want to just + # pass through the actual response + if resp.status_code != 401: + return resp + + # We are not able to prompt the user so simply return the response + if not self.prompting: + return resp + + parsed = urllib_parse.urlparse(resp.url) + + # Prompt the user for a new username and password + username = six.moves.input("User for %s: " % parsed.netloc) + password = getpass.getpass("Password: ") + + # Store the new username and password to use for future requests + if username or password: + self.passwords[parsed.netloc] = (username, password) + + # Consume content and release the original connection to allow our new + # request to reuse the same one. + resp.content + resp.raw.release_conn() + + # Add our new username and password to the request + req = HTTPBasicAuth(username or "", password or "")(resp.request) + + # Send our new request + new_resp = resp.connection.send(req, **kwargs) + new_resp.history.append(resp) + + return new_resp + + def parse_credentials(self, netloc): + if "@" in netloc: + userinfo = netloc.rsplit("@", 1)[0] + if ":" in userinfo: + user, pwd = userinfo.split(":", 1) + return (urllib_unquote(user), urllib_unquote(pwd)) + return urllib_unquote(userinfo), None + return None, None + + +class LocalFSAdapter(BaseAdapter): + + def send(self, request, stream=None, timeout=None, verify=None, cert=None, + proxies=None): + pathname = url_to_path(request.url) + + resp = Response() + resp.status_code = 200 + resp.url = request.url + + try: + stats = os.stat(pathname) + except OSError as exc: + resp.status_code = 404 + resp.raw = exc + else: + modified = email.utils.formatdate(stats.st_mtime, usegmt=True) + content_type = mimetypes.guess_type(pathname)[0] or "text/plain" + resp.headers = CaseInsensitiveDict({ + "Content-Type": content_type, + "Content-Length": stats.st_size, + "Last-Modified": modified, + }) + + resp.raw = open(pathname, "rb") + resp.close = resp.raw.close + + return resp + + def close(self): + pass + + +class SafeFileCache(FileCache): + """ + A file based cache which is safe to use even when the target directory may + not be accessible or writable. + """ + + def __init__(self, *args, **kwargs): + super(SafeFileCache, self).__init__(*args, **kwargs) + + # Check to ensure that the directory containing our cache directory + # is owned by the user current executing pip. If it does not exist + # we will check the parent directory until we find one that does exist. + # If it is not owned by the user executing pip then we will disable + # the cache and log a warning. + if not check_path_owner(self.directory): + logger.warning( + "The directory '%s' or its parent directory is not owned by " + "the current user and the cache has been disabled. Please " + "check the permissions and owner of that directory. If " + "executing pip with sudo, you may want sudo's -H flag.", + self.directory, + ) + + # Set our directory to None to disable the Cache + self.directory = None + + def get(self, *args, **kwargs): + # If we don't have a directory, then the cache should be a no-op. + if self.directory is None: + return + + try: + return super(SafeFileCache, self).get(*args, **kwargs) + except (LockError, OSError, IOError): + # We intentionally silence this error, if we can't access the cache + # then we can just skip caching and process the request as if + # caching wasn't enabled. + pass + + def set(self, *args, **kwargs): + # If we don't have a directory, then the cache should be a no-op. + if self.directory is None: + return + + try: + return super(SafeFileCache, self).set(*args, **kwargs) + except (LockError, OSError, IOError): + # We intentionally silence this error, if we can't access the cache + # then we can just skip caching and process the request as if + # caching wasn't enabled. + pass + + def delete(self, *args, **kwargs): + # If we don't have a directory, then the cache should be a no-op. + if self.directory is None: + return + + try: + return super(SafeFileCache, self).delete(*args, **kwargs) + except (LockError, OSError, IOError): + # We intentionally silence this error, if we can't access the cache + # then we can just skip caching and process the request as if + # caching wasn't enabled. + pass + + +class InsecureHTTPAdapter(HTTPAdapter): + + def cert_verify(self, conn, url, verify, cert): + conn.cert_reqs = 'CERT_NONE' + conn.ca_certs = None + + +class PipSession(requests.Session): + + timeout = None + + def __init__(self, *args, **kwargs): + retries = kwargs.pop("retries", 0) + cache = kwargs.pop("cache", None) + insecure_hosts = kwargs.pop("insecure_hosts", []) + + super(PipSession, self).__init__(*args, **kwargs) + + # Attach our User Agent to the request + self.headers["User-Agent"] = user_agent() + + # Attach our Authentication handler to the session + self.auth = MultiDomainBasicAuth() + + # Create our urllib3.Retry instance which will allow us to customize + # how we handle retries. + retries = urllib3.Retry( + # Set the total number of retries that a particular request can + # have. + total=retries, + + # A 503 error from PyPI typically means that the Fastly -> Origin + # connection got interrupted in some way. A 503 error in general + # is typically considered a transient error so we'll go ahead and + # retry it. + # A 500 may indicate transient error in Amazon S3 + # A 520 or 527 - may indicate transient error in CloudFlare + status_forcelist=[500, 503, 520, 527], + + # Add a small amount of back off between failed requests in + # order to prevent hammering the service. + backoff_factor=0.25, + ) + + # We want to _only_ cache responses on securely fetched origins. We do + # this because we can't validate the response of an insecurely fetched + # origin, and we don't want someone to be able to poison the cache and + # require manual eviction from the cache to fix it. + if cache: + secure_adapter = CacheControlAdapter( + cache=SafeFileCache(cache, use_dir_lock=True), + max_retries=retries, + ) + else: + secure_adapter = HTTPAdapter(max_retries=retries) + + # Our Insecure HTTPAdapter disables HTTPS validation. It does not + # support caching (see above) so we'll use it for all http:// URLs as + # well as any https:// host that we've marked as ignoring TLS errors + # for. + insecure_adapter = InsecureHTTPAdapter(max_retries=retries) + + self.mount("https://", secure_adapter) + self.mount("http://", insecure_adapter) + + # Enable file:// urls + self.mount("file://", LocalFSAdapter()) + + # We want to use a non-validating adapter for any requests which are + # deemed insecure. + for host in insecure_hosts: + self.mount("https://{}/".format(host), insecure_adapter) + + def request(self, method, url, *args, **kwargs): + # Allow setting a default timeout on a session + kwargs.setdefault("timeout", self.timeout) + + # Dispatch the actual request + return super(PipSession, self).request(method, url, *args, **kwargs) + + +def get_file_content(url, comes_from=None, session=None): + """Gets the content of a file; it may be a filename, file: URL, or + http: URL. Returns (location, content). Content is unicode. + + :param url: File path or url. + :param comes_from: Origin description of requirements. + :param session: Instance of pip.download.PipSession. + """ + if session is None: + raise TypeError( + "get_file_content() missing 1 required keyword argument: 'session'" + ) + + match = _scheme_re.search(url) + if match: + scheme = match.group(1).lower() + if (scheme == 'file' and comes_from and + comes_from.startswith('http')): + raise InstallationError( + 'Requirements file %s references URL %s, which is local' + % (comes_from, url)) + if scheme == 'file': + path = url.split(':', 1)[1] + path = path.replace('\\', '/') + match = _url_slash_drive_re.match(path) + if match: + path = match.group(1) + ':' + path.split('|', 1)[1] + path = urllib_parse.unquote(path) + if path.startswith('/'): + path = '/' + path.lstrip('/') + url = path + else: + # FIXME: catch some errors + resp = session.get(url) + resp.raise_for_status() + return resp.url, resp.text + try: + with open(url, 'rb') as f: + content = auto_decode(f.read()) + except IOError as exc: + raise InstallationError( + 'Could not open requirements file: %s' % str(exc) + ) + return url, content + + +_scheme_re = re.compile(r'^(http|https|file):', re.I) +_url_slash_drive_re = re.compile(r'/*([a-z])\|', re.I) + + +def is_url(name): + """Returns true if the name looks like a URL""" + if ':' not in name: + return False + scheme = name.split(':', 1)[0].lower() + return scheme in ['http', 'https', 'file', 'ftp'] + vcs.all_schemes + + +def url_to_path(url): + """ + Convert a file: URL to a path. + """ + assert url.startswith('file:'), ( + "You can only turn file: urls into filenames (not %r)" % url) + + _, netloc, path, _, _ = urllib_parse.urlsplit(url) + + # if we have a UNC path, prepend UNC share notation + if netloc: + netloc = '\\\\' + netloc + + path = urllib_request.url2pathname(netloc + path) + return path + + +def path_to_url(path): + """ + Convert a path to a file: URL. The path will be made absolute and have + quoted path parts. + """ + path = os.path.normpath(os.path.abspath(path)) + url = urllib_parse.urljoin('file:', urllib_request.pathname2url(path)) + return url + + +def is_archive_file(name): + """Return True if `name` is a considered as an archive file.""" + ext = splitext(name)[1].lower() + if ext in ARCHIVE_EXTENSIONS: + return True + return False + + +def unpack_vcs_link(link, location): + vcs_backend = _get_used_vcs_backend(link) + vcs_backend.unpack(location) + + +def _get_used_vcs_backend(link): + for backend in vcs.backends: + if link.scheme in backend.schemes: + vcs_backend = backend(link.url) + return vcs_backend + + +def is_vcs_url(link): + return bool(_get_used_vcs_backend(link)) + + +def is_file_url(link): + return link.url.lower().startswith('file:') + + +def is_dir_url(link): + """Return whether a file:// Link points to a directory. + + ``link`` must not have any other scheme but file://. Call is_file_url() + first. + + """ + link_path = url_to_path(link.url_without_fragment) + return os.path.isdir(link_path) + + +def _progress_indicator(iterable, *args, **kwargs): + return iterable + + +def _download_url(resp, link, content_file, hashes, progress_bar): + try: + total_length = int(resp.headers['content-length']) + except (ValueError, KeyError, TypeError): + total_length = 0 + + cached_resp = getattr(resp, "from_cache", False) + if logger.getEffectiveLevel() > logging.INFO: + show_progress = False + elif cached_resp: + show_progress = False + elif total_length > (40 * 1000): + show_progress = True + elif not total_length: + show_progress = True + else: + show_progress = False + + show_url = link.show_url + + def resp_read(chunk_size): + try: + # Special case for urllib3. + for chunk in resp.raw.stream( + chunk_size, + # We use decode_content=False here because we don't + # want urllib3 to mess with the raw bytes we get + # from the server. If we decompress inside of + # urllib3 then we cannot verify the checksum + # because the checksum will be of the compressed + # file. This breakage will only occur if the + # server adds a Content-Encoding header, which + # depends on how the server was configured: + # - Some servers will notice that the file isn't a + # compressible file and will leave the file alone + # and with an empty Content-Encoding + # - Some servers will notice that the file is + # already compressed and will leave the file + # alone and will add a Content-Encoding: gzip + # header + # - Some servers won't notice anything at all and + # will take a file that's already been compressed + # and compress it again and set the + # Content-Encoding: gzip header + # + # By setting this not to decode automatically we + # hope to eliminate problems with the second case. + decode_content=False): + yield chunk + except AttributeError: + # Standard file-like object. + while True: + chunk = resp.raw.read(chunk_size) + if not chunk: + break + yield chunk + + def written_chunks(chunks): + for chunk in chunks: + content_file.write(chunk) + yield chunk + + progress_indicator = _progress_indicator + + if link.netloc == PyPI.netloc: + url = show_url + else: + url = link.url_without_fragment + + if show_progress: # We don't show progress on cached responses + progress_indicator = DownloadProgressProvider(progress_bar, + max=total_length) + if total_length: + logger.info("Downloading %s (%s)", url, format_size(total_length)) + else: + logger.info("Downloading %s", url) + elif cached_resp: + logger.info("Using cached %s", url) + else: + logger.info("Downloading %s", url) + + logger.debug('Downloading from URL %s', link) + + downloaded_chunks = written_chunks( + progress_indicator( + resp_read(CONTENT_CHUNK_SIZE), + CONTENT_CHUNK_SIZE + ) + ) + if hashes: + hashes.check_against_chunks(downloaded_chunks) + else: + consume(downloaded_chunks) + + +def _copy_file(filename, location, link): + copy = True + download_location = os.path.join(location, link.filename) + if os.path.exists(download_location): + response = ask_path_exists( + 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)abort' % + display_path(download_location), ('i', 'w', 'b', 'a')) + if response == 'i': + copy = False + elif response == 'w': + logger.warning('Deleting %s', display_path(download_location)) + os.remove(download_location) + elif response == 'b': + dest_file = backup_dir(download_location) + logger.warning( + 'Backing up %s to %s', + display_path(download_location), + display_path(dest_file), + ) + shutil.move(download_location, dest_file) + elif response == 'a': + sys.exit(-1) + if copy: + shutil.copy(filename, download_location) + logger.info('Saved %s', display_path(download_location)) + + +def unpack_http_url(link, location, download_dir=None, + session=None, hashes=None, progress_bar="on"): + if session is None: + raise TypeError( + "unpack_http_url() missing 1 required keyword argument: 'session'" + ) + + with TempDirectory(kind="unpack") as temp_dir: + # If a download dir is specified, is the file already downloaded there? + already_downloaded_path = None + if download_dir: + already_downloaded_path = _check_download_dir(link, + download_dir, + hashes) + + if already_downloaded_path: + from_path = already_downloaded_path + content_type = mimetypes.guess_type(from_path)[0] + else: + # let's download to a tmp dir + from_path, content_type = _download_http_url(link, + session, + temp_dir.path, + hashes, + progress_bar) + + # unpack the archive to the build dir location. even when only + # downloading archives, they have to be unpacked to parse dependencies + unpack_file(from_path, location, content_type, link) + + # a download dir is specified; let's copy the archive there + if download_dir and not already_downloaded_path: + _copy_file(from_path, download_dir, link) + + if not already_downloaded_path: + os.unlink(from_path) + + +def unpack_file_url(link, location, download_dir=None, hashes=None): + """Unpack link into location. + + If download_dir is provided and link points to a file, make a copy + of the link file inside download_dir. + """ + link_path = url_to_path(link.url_without_fragment) + + # If it's a url to a local directory + if is_dir_url(link): + if os.path.isdir(location): + rmtree(location) + shutil.copytree(link_path, location, symlinks=True) + if download_dir: + logger.info('Link is a directory, ignoring download_dir') + return + + # If --require-hashes is off, `hashes` is either empty, the + # link's embedded hash, or MissingHashes; it is required to + # match. If --require-hashes is on, we are satisfied by any + # hash in `hashes` matching: a URL-based or an option-based + # one; no internet-sourced hash will be in `hashes`. + if hashes: + hashes.check_against_path(link_path) + + # If a download dir is specified, is the file already there and valid? + already_downloaded_path = None + if download_dir: + already_downloaded_path = _check_download_dir(link, + download_dir, + hashes) + + if already_downloaded_path: + from_path = already_downloaded_path + else: + from_path = link_path + + content_type = mimetypes.guess_type(from_path)[0] + + # unpack the archive to the build dir location. even when only downloading + # archives, they have to be unpacked to parse dependencies + unpack_file(from_path, location, content_type, link) + + # a download dir is specified and not already downloaded + if download_dir and not already_downloaded_path: + _copy_file(from_path, download_dir, link) + + +def _copy_dist_from_dir(link_path, location): + """Copy distribution files in `link_path` to `location`. + + Invoked when user requests to install a local directory. E.g.: + + pip install . + pip install ~/dev/git-repos/python-prompt-toolkit + + """ + + # Note: This is currently VERY SLOW if you have a lot of data in the + # directory, because it copies everything with `shutil.copytree`. + # What it should really do is build an sdist and install that. + # See https://github.com/pypa/pip/issues/2195 + + if os.path.isdir(location): + rmtree(location) + + # build an sdist + setup_py = 'setup.py' + sdist_args = [sys.executable] + sdist_args.append('-c') + sdist_args.append(SETUPTOOLS_SHIM % setup_py) + sdist_args.append('sdist') + sdist_args += ['--dist-dir', location] + logger.info('Running setup.py sdist for %s', link_path) + + with indent_log(): + call_subprocess(sdist_args, cwd=link_path, show_stdout=False) + + # unpack sdist into `location` + sdist = os.path.join(location, os.listdir(location)[0]) + logger.info('Unpacking sdist %s into %s', sdist, location) + unpack_file(sdist, location, content_type=None, link=None) + + +class PipXmlrpcTransport(xmlrpc_client.Transport): + """Provide a `xmlrpclib.Transport` implementation via a `PipSession` + object. + """ + + def __init__(self, index_url, session, use_datetime=False): + xmlrpc_client.Transport.__init__(self, use_datetime) + index_parts = urllib_parse.urlparse(index_url) + self._scheme = index_parts.scheme + self._session = session + + def request(self, host, handler, request_body, verbose=False): + parts = (self._scheme, host, handler, None, None, None) + url = urllib_parse.urlunparse(parts) + try: + headers = {'Content-Type': 'text/xml'} + response = self._session.post(url, data=request_body, + headers=headers, stream=True) + response.raise_for_status() + self.verbose = verbose + return self.parse_response(response.raw) + except requests.HTTPError as exc: + logger.critical( + "HTTP error %s while getting %s", + exc.response.status_code, url, + ) + raise + + +def unpack_url(link, location, download_dir=None, + only_download=False, session=None, hashes=None, + progress_bar="on"): + """Unpack link. + If link is a VCS link: + if only_download, export into download_dir and ignore location + else unpack into location + for other types of link: + - unpack into location + - if download_dir, copy the file into download_dir + - if only_download, mark location for deletion + + :param hashes: A Hashes object, one of whose embedded hashes must match, + or HashMismatch will be raised. If the Hashes is empty, no matches are + required, and unhashable types of requirements (like VCS ones, which + would ordinarily raise HashUnsupported) are allowed. + """ + # non-editable vcs urls + if is_vcs_url(link): + unpack_vcs_link(link, location) + + # file urls + elif is_file_url(link): + unpack_file_url(link, location, download_dir, hashes=hashes) + + # http urls + else: + if session is None: + session = PipSession() + + unpack_http_url( + link, + location, + download_dir, + session, + hashes=hashes, + progress_bar=progress_bar + ) + if only_download: + write_delete_marker_file(location) + + +def _download_http_url(link, session, temp_dir, hashes, progress_bar): + """Download link url into temp_dir using provided session""" + target_url = link.url.split('#', 1)[0] + try: + resp = session.get( + target_url, + # We use Accept-Encoding: identity here because requests + # defaults to accepting compressed responses. This breaks in + # a variety of ways depending on how the server is configured. + # - Some servers will notice that the file isn't a compressible + # file and will leave the file alone and with an empty + # Content-Encoding + # - Some servers will notice that the file is already + # compressed and will leave the file alone and will add a + # Content-Encoding: gzip header + # - Some servers won't notice anything at all and will take + # a file that's already been compressed and compress it again + # and set the Content-Encoding: gzip header + # By setting this to request only the identity encoding We're + # hoping to eliminate the third case. Hopefully there does not + # exist a server which when given a file will notice it is + # already compressed and that you're not asking for a + # compressed file and will then decompress it before sending + # because if that's the case I don't think it'll ever be + # possible to make this work. + headers={"Accept-Encoding": "identity"}, + stream=True, + ) + resp.raise_for_status() + except requests.HTTPError as exc: + logger.critical( + "HTTP error %s while getting %s", exc.response.status_code, link, + ) + raise + + content_type = resp.headers.get('content-type', '') + filename = link.filename # fallback + # Have a look at the Content-Disposition header for a better guess + content_disposition = resp.headers.get('content-disposition') + if content_disposition: + type, params = cgi.parse_header(content_disposition) + # We use ``or`` here because we don't want to use an "empty" value + # from the filename param. + filename = params.get('filename') or filename + ext = splitext(filename)[1] + if not ext: + ext = mimetypes.guess_extension(content_type) + if ext: + filename += ext + if not ext and link.url != resp.url: + ext = os.path.splitext(resp.url)[1] + if ext: + filename += ext + file_path = os.path.join(temp_dir, filename) + with open(file_path, 'wb') as content_file: + _download_url(resp, link, content_file, hashes, progress_bar) + return file_path, content_type + + +def _check_download_dir(link, download_dir, hashes): + """ Check download_dir for previously downloaded file with correct hash + If a correct file is found return its path else None + """ + download_path = os.path.join(download_dir, link.filename) + if os.path.exists(download_path): + # If already downloaded, does its hash match? + logger.info('File was already downloaded %s', download_path) + if hashes: + try: + hashes.check_against_path(download_path) + except HashMismatch: + logger.warning( + 'Previously-downloaded file %s has bad hash. ' + 'Re-downloading.', + download_path + ) + os.unlink(download_path) + return None + return download_path + return None diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/exceptions.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/exceptions.py new file mode 100644 index 0000000..ad6f412 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/exceptions.py @@ -0,0 +1,249 @@ +"""Exceptions used throughout package""" +from __future__ import absolute_import + +from itertools import chain, groupby, repeat + +from pip._vendor.six import iteritems + + +class PipError(Exception): + """Base pip exception""" + + +class ConfigurationError(PipError): + """General exception in configuration""" + + +class InstallationError(PipError): + """General exception during installation""" + + +class UninstallationError(PipError): + """General exception during uninstallation""" + + +class DistributionNotFound(InstallationError): + """Raised when a distribution cannot be found to satisfy a requirement""" + + +class RequirementsFileParseError(InstallationError): + """Raised when a general error occurs parsing a requirements file line.""" + + +class BestVersionAlreadyInstalled(PipError): + """Raised when the most up-to-date version of a package is already + installed.""" + + +class BadCommand(PipError): + """Raised when virtualenv or a command is not found""" + + +class CommandError(PipError): + """Raised when there is an error in command-line arguments""" + + +class PreviousBuildDirError(PipError): + """Raised when there's a previous conflicting build directory""" + + +class InvalidWheelFilename(InstallationError): + """Invalid wheel filename.""" + + +class UnsupportedWheel(InstallationError): + """Unsupported wheel.""" + + +class HashErrors(InstallationError): + """Multiple HashError instances rolled into one for reporting""" + + def __init__(self): + self.errors = [] + + def append(self, error): + self.errors.append(error) + + def __str__(self): + lines = [] + self.errors.sort(key=lambda e: e.order) + for cls, errors_of_cls in groupby(self.errors, lambda e: e.__class__): + lines.append(cls.head) + lines.extend(e.body() for e in errors_of_cls) + if lines: + return '\n'.join(lines) + + def __nonzero__(self): + return bool(self.errors) + + def __bool__(self): + return self.__nonzero__() + + +class HashError(InstallationError): + """ + A failure to verify a package against known-good hashes + + :cvar order: An int sorting hash exception classes by difficulty of + recovery (lower being harder), so the user doesn't bother fretting + about unpinned packages when he has deeper issues, like VCS + dependencies, to deal with. Also keeps error reports in a + deterministic order. + :cvar head: A section heading for display above potentially many + exceptions of this kind + :ivar req: The InstallRequirement that triggered this error. This is + pasted on after the exception is instantiated, because it's not + typically available earlier. + + """ + req = None + head = '' + + def body(self): + """Return a summary of me for display under the heading. + + This default implementation simply prints a description of the + triggering requirement. + + :param req: The InstallRequirement that provoked this error, with + populate_link() having already been called + + """ + return ' %s' % self._requirement_name() + + def __str__(self): + return '%s\n%s' % (self.head, self.body()) + + def _requirement_name(self): + """Return a description of the requirement that triggered me. + + This default implementation returns long description of the req, with + line numbers + + """ + return str(self.req) if self.req else 'unknown package' + + +class VcsHashUnsupported(HashError): + """A hash was provided for a version-control-system-based requirement, but + we don't have a method for hashing those.""" + + order = 0 + head = ("Can't verify hashes for these requirements because we don't " + "have a way to hash version control repositories:") + + +class DirectoryUrlHashUnsupported(HashError): + """A hash was provided for a version-control-system-based requirement, but + we don't have a method for hashing those.""" + + order = 1 + head = ("Can't verify hashes for these file:// requirements because they " + "point to directories:") + + +class HashMissing(HashError): + """A hash was needed for a requirement but is absent.""" + + order = 2 + head = ('Hashes are required in --require-hashes mode, but they are ' + 'missing from some requirements. Here is a list of those ' + 'requirements along with the hashes their downloaded archives ' + 'actually had. Add lines like these to your requirements files to ' + 'prevent tampering. (If you did not enable --require-hashes ' + 'manually, note that it turns on automatically when any package ' + 'has a hash.)') + + def __init__(self, gotten_hash): + """ + :param gotten_hash: The hash of the (possibly malicious) archive we + just downloaded + """ + self.gotten_hash = gotten_hash + + def body(self): + # Dodge circular import. + from pip._internal.utils.hashes import FAVORITE_HASH + + package = None + if self.req: + # In the case of URL-based requirements, display the original URL + # seen in the requirements file rather than the package name, + # so the output can be directly copied into the requirements file. + package = (self.req.original_link if self.req.original_link + # In case someone feeds something downright stupid + # to InstallRequirement's constructor. + else getattr(self.req, 'req', None)) + return ' %s --hash=%s:%s' % (package or 'unknown package', + FAVORITE_HASH, + self.gotten_hash) + + +class HashUnpinned(HashError): + """A requirement had a hash specified but was not pinned to a specific + version.""" + + order = 3 + head = ('In --require-hashes mode, all requirements must have their ' + 'versions pinned with ==. These do not:') + + +class HashMismatch(HashError): + """ + Distribution file hash values don't match. + + :ivar package_name: The name of the package that triggered the hash + mismatch. Feel free to write to this after the exception is raise to + improve its error message. + + """ + order = 4 + head = ('THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS ' + 'FILE. If you have updated the package versions, please update ' + 'the hashes. Otherwise, examine the package contents carefully; ' + 'someone may have tampered with them.') + + def __init__(self, allowed, gots): + """ + :param allowed: A dict of algorithm names pointing to lists of allowed + hex digests + :param gots: A dict of algorithm names pointing to hashes we + actually got from the files under suspicion + """ + self.allowed = allowed + self.gots = gots + + def body(self): + return ' %s:\n%s' % (self._requirement_name(), + self._hash_comparison()) + + def _hash_comparison(self): + """ + Return a comparison of actual and expected hash values. + + Example:: + + Expected sha256 abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde + or 123451234512345123451234512345123451234512345 + Got bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef + + """ + def hash_then_or(hash_name): + # For now, all the decent hashes have 6-char names, so we can get + # away with hard-coding space literals. + return chain([hash_name], repeat(' or')) + + lines = [] + for hash_name, expecteds in iteritems(self.allowed): + prefix = hash_then_or(hash_name) + lines.extend((' Expected %s %s' % (next(prefix), e)) + for e in expecteds) + lines.append(' Got %s\n' % + self.gots[hash_name].hexdigest()) + prefix = ' or' + return '\n'.join(lines) + + +class UnsupportedPythonVersion(InstallationError): + """Unsupported python version according to Requires-Python package + metadata.""" diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/index.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/index.py new file mode 100644 index 0000000..3c3a92b --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/index.py @@ -0,0 +1,1117 @@ +"""Routines related to PyPI, indexes""" +from __future__ import absolute_import + +import cgi +import itertools +import logging +import mimetypes +import os +import posixpath +import re +import sys +import warnings +from collections import namedtuple + +from pip._vendor import html5lib, requests, six +from pip._vendor.distlib.compat import unescape +from pip._vendor.packaging import specifiers +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.packaging.version import parse as parse_version +from pip._vendor.requests.exceptions import SSLError +from pip._vendor.six.moves.urllib import parse as urllib_parse +from pip._vendor.six.moves.urllib import request as urllib_request + +from pip._internal.compat import ipaddress +from pip._internal.download import HAS_TLS, is_url, path_to_url, url_to_path +from pip._internal.exceptions import ( + BestVersionAlreadyInstalled, DistributionNotFound, InvalidWheelFilename, + UnsupportedWheel, +) +from pip._internal.models import PyPI +from pip._internal.pep425tags import get_supported +from pip._internal.utils.deprecation import RemovedInPip11Warning +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + ARCHIVE_EXTENSIONS, SUPPORTED_EXTENSIONS, cached_property, normalize_path, + splitext, +) +from pip._internal.utils.packaging import check_requires_python +from pip._internal.wheel import Wheel, wheel_ext + +__all__ = ['FormatControl', 'fmt_ctl_handle_mutual_exclude', 'PackageFinder'] + + +SECURE_ORIGINS = [ + # protocol, hostname, port + # Taken from Chrome's list of secure origins (See: http://bit.ly/1qrySKC) + ("https", "*", "*"), + ("*", "localhost", "*"), + ("*", "127.0.0.0/8", "*"), + ("*", "::1/128", "*"), + ("file", "*", None), + # ssh is always secure. + ("ssh", "*", "*"), +] + + +logger = logging.getLogger(__name__) + + +class InstallationCandidate(object): + + def __init__(self, project, version, location): + self.project = project + self.version = parse_version(version) + self.location = location + self._key = (self.project, self.version, self.location) + + def __repr__(self): + return "".format( + self.project, self.version, self.location, + ) + + def __hash__(self): + return hash(self._key) + + def __lt__(self, other): + return self._compare(other, lambda s, o: s < o) + + def __le__(self, other): + return self._compare(other, lambda s, o: s <= o) + + def __eq__(self, other): + return self._compare(other, lambda s, o: s == o) + + def __ge__(self, other): + return self._compare(other, lambda s, o: s >= o) + + def __gt__(self, other): + return self._compare(other, lambda s, o: s > o) + + def __ne__(self, other): + return self._compare(other, lambda s, o: s != o) + + def _compare(self, other, method): + if not isinstance(other, InstallationCandidate): + return NotImplemented + + return method(self._key, other._key) + + +class PackageFinder(object): + """This finds packages. + + This is meant to match easy_install's technique for looking for + packages, by reading pages and looking for appropriate links. + """ + + def __init__(self, find_links, index_urls, allow_all_prereleases=False, + trusted_hosts=None, process_dependency_links=False, + session=None, format_control=None, platform=None, + versions=None, abi=None, implementation=None): + """Create a PackageFinder. + + :param format_control: A FormatControl object or None. Used to control + the selection of source packages / binary packages when consulting + the index and links. + :param platform: A string or None. If None, searches for packages + that are supported by the current system. Otherwise, will find + packages that can be built on the platform passed in. These + packages will only be downloaded for distribution: they will + not be built locally. + :param versions: A list of strings or None. This is passed directly + to pep425tags.py in the get_supported() method. + :param abi: A string or None. This is passed directly + to pep425tags.py in the get_supported() method. + :param implementation: A string or None. This is passed directly + to pep425tags.py in the get_supported() method. + """ + if session is None: + raise TypeError( + "PackageFinder() missing 1 required keyword argument: " + "'session'" + ) + + # Build find_links. If an argument starts with ~, it may be + # a local file relative to a home directory. So try normalizing + # it and if it exists, use the normalized version. + # This is deliberately conservative - it might be fine just to + # blindly normalize anything starting with a ~... + self.find_links = [] + for link in find_links: + if link.startswith('~'): + new_link = normalize_path(link) + if os.path.exists(new_link): + link = new_link + self.find_links.append(link) + + self.index_urls = index_urls + self.dependency_links = [] + + # These are boring links that have already been logged somehow: + self.logged_links = set() + + self.format_control = format_control or FormatControl(set(), set()) + + # Domains that we won't emit warnings for when not using HTTPS + self.secure_origins = [ + ("*", host, "*") + for host in (trusted_hosts if trusted_hosts else []) + ] + + # Do we want to allow _all_ pre-releases? + self.allow_all_prereleases = allow_all_prereleases + + # Do we process dependency links? + self.process_dependency_links = process_dependency_links + + # The Session we'll use to make requests + self.session = session + + # The valid tags to check potential found wheel candidates against + self.valid_tags = get_supported( + versions=versions, + platform=platform, + abi=abi, + impl=implementation, + ) + + # If we don't have TLS enabled, then WARN if anyplace we're looking + # relies on TLS. + if not HAS_TLS: + for link in itertools.chain(self.index_urls, self.find_links): + parsed = urllib_parse.urlparse(link) + if parsed.scheme == "https": + logger.warning( + "pip is configured with locations that require " + "TLS/SSL, however the ssl module in Python is not " + "available." + ) + break + + def get_formatted_locations(self): + lines = [] + if self.index_urls and self.index_urls != [PyPI.simple_url]: + lines.append( + "Looking in indexes: {}".format(", ".join(self.index_urls)) + ) + if self.find_links: + lines.append( + "Looking in links: {}".format(", ".join(self.find_links)) + ) + return "\n".join(lines) + + def add_dependency_links(self, links): + # # FIXME: this shouldn't be global list this, it should only + # # apply to requirements of the package that specifies the + # # dependency_links value + # # FIXME: also, we should track comes_from (i.e., use Link) + if self.process_dependency_links: + warnings.warn( + "Dependency Links processing has been deprecated and will be " + "removed in a future release.", + RemovedInPip11Warning, + ) + self.dependency_links.extend(links) + + @staticmethod + def _sort_locations(locations, expand_dir=False): + """ + Sort locations into "files" (archives) and "urls", and return + a pair of lists (files,urls) + """ + files = [] + urls = [] + + # puts the url for the given file path into the appropriate list + def sort_path(path): + url = path_to_url(path) + if mimetypes.guess_type(url, strict=False)[0] == 'text/html': + urls.append(url) + else: + files.append(url) + + for url in locations: + + is_local_path = os.path.exists(url) + is_file_url = url.startswith('file:') + + if is_local_path or is_file_url: + if is_local_path: + path = url + else: + path = url_to_path(url) + if os.path.isdir(path): + if expand_dir: + path = os.path.realpath(path) + for item in os.listdir(path): + sort_path(os.path.join(path, item)) + elif is_file_url: + urls.append(url) + elif os.path.isfile(path): + sort_path(path) + else: + logger.warning( + "Url '%s' is ignored: it is neither a file " + "nor a directory.", url, + ) + elif is_url(url): + # Only add url with clear scheme + urls.append(url) + else: + logger.warning( + "Url '%s' is ignored. It is either a non-existing " + "path or lacks a specific scheme.", url, + ) + + return files, urls + + def _candidate_sort_key(self, candidate): + """ + Function used to generate link sort key for link tuples. + The greater the return value, the more preferred it is. + If not finding wheels, then sorted by version only. + If finding wheels, then the sort order is by version, then: + 1. existing installs + 2. wheels ordered via Wheel.support_index_min(self.valid_tags) + 3. source archives + Note: it was considered to embed this logic into the Link + comparison operators, but then different sdist links + with the same version, would have to be considered equal + """ + support_num = len(self.valid_tags) + build_tag = tuple() + if candidate.location.is_wheel: + # can raise InvalidWheelFilename + wheel = Wheel(candidate.location.filename) + if not wheel.supported(self.valid_tags): + raise UnsupportedWheel( + "%s is not a supported wheel for this platform. It " + "can't be sorted." % wheel.filename + ) + pri = -(wheel.support_index_min(self.valid_tags)) + if wheel.build_tag is not None: + match = re.match(r'^(\d+)(.*)$', wheel.build_tag) + build_tag_groups = match.groups() + build_tag = (int(build_tag_groups[0]), build_tag_groups[1]) + else: # sdist + pri = -(support_num) + return (candidate.version, build_tag, pri) + + def _validate_secure_origin(self, logger, location): + # Determine if this url used a secure transport mechanism + parsed = urllib_parse.urlparse(str(location)) + origin = (parsed.scheme, parsed.hostname, parsed.port) + + # The protocol to use to see if the protocol matches. + # Don't count the repository type as part of the protocol: in + # cases such as "git+ssh", only use "ssh". (I.e., Only verify against + # the last scheme.) + protocol = origin[0].rsplit('+', 1)[-1] + + # Determine if our origin is a secure origin by looking through our + # hardcoded list of secure origins, as well as any additional ones + # configured on this PackageFinder instance. + for secure_origin in (SECURE_ORIGINS + self.secure_origins): + if protocol != secure_origin[0] and secure_origin[0] != "*": + continue + + try: + # We need to do this decode dance to ensure that we have a + # unicode object, even on Python 2.x. + addr = ipaddress.ip_address( + origin[1] + if ( + isinstance(origin[1], six.text_type) or + origin[1] is None + ) + else origin[1].decode("utf8") + ) + network = ipaddress.ip_network( + secure_origin[1] + if isinstance(secure_origin[1], six.text_type) + else secure_origin[1].decode("utf8") + ) + except ValueError: + # We don't have both a valid address or a valid network, so + # we'll check this origin against hostnames. + if (origin[1] and + origin[1].lower() != secure_origin[1].lower() and + secure_origin[1] != "*"): + continue + else: + # We have a valid address and network, so see if the address + # is contained within the network. + if addr not in network: + continue + + # Check to see if the port patches + if (origin[2] != secure_origin[2] and + secure_origin[2] != "*" and + secure_origin[2] is not None): + continue + + # If we've gotten here, then this origin matches the current + # secure origin and we should return True + return True + + # If we've gotten to this point, then the origin isn't secure and we + # will not accept it as a valid location to search. We will however + # log a warning that we are ignoring it. + logger.warning( + "The repository located at %s is not a trusted or secure host and " + "is being ignored. If this repository is available via HTTPS we " + "recommend you use HTTPS instead, otherwise you may silence " + "this warning and allow it anyway with '--trusted-host %s'.", + parsed.hostname, + parsed.hostname, + ) + + return False + + def _get_index_urls_locations(self, project_name): + """Returns the locations found via self.index_urls + + Checks the url_name on the main (first in the list) index and + use this url_name to produce all locations + """ + + def mkurl_pypi_url(url): + loc = posixpath.join( + url, + urllib_parse.quote(canonicalize_name(project_name))) + # For maximum compatibility with easy_install, ensure the path + # ends in a trailing slash. Although this isn't in the spec + # (and PyPI can handle it without the slash) some other index + # implementations might break if they relied on easy_install's + # behavior. + if not loc.endswith('/'): + loc = loc + '/' + return loc + + return [mkurl_pypi_url(url) for url in self.index_urls] + + def find_all_candidates(self, project_name): + """Find all available InstallationCandidate for project_name + + This checks index_urls, find_links and dependency_links. + All versions found are returned as an InstallationCandidate list. + + See _link_package_versions for details on which files are accepted + """ + index_locations = self._get_index_urls_locations(project_name) + index_file_loc, index_url_loc = self._sort_locations(index_locations) + fl_file_loc, fl_url_loc = self._sort_locations( + self.find_links, expand_dir=True, + ) + dep_file_loc, dep_url_loc = self._sort_locations(self.dependency_links) + + file_locations = (Link(url) for url in itertools.chain( + index_file_loc, fl_file_loc, dep_file_loc, + )) + + # We trust every url that the user has given us whether it was given + # via --index-url or --find-links + # We explicitly do not trust links that came from dependency_links + # We want to filter out any thing which does not have a secure origin. + url_locations = [ + link for link in itertools.chain( + (Link(url) for url in index_url_loc), + (Link(url) for url in fl_url_loc), + (Link(url) for url in dep_url_loc), + ) + if self._validate_secure_origin(logger, link) + ] + + logger.debug('%d location(s) to search for versions of %s:', + len(url_locations), project_name) + + for location in url_locations: + logger.debug('* %s', location) + + canonical_name = canonicalize_name(project_name) + formats = fmt_ctl_formats(self.format_control, canonical_name) + search = Search(project_name, canonical_name, formats) + find_links_versions = self._package_versions( + # We trust every directly linked archive in find_links + (Link(url, '-f') for url in self.find_links), + search + ) + + page_versions = [] + for page in self._get_pages(url_locations, project_name): + logger.debug('Analyzing links from page %s', page.url) + with indent_log(): + page_versions.extend( + self._package_versions(page.links, search) + ) + + dependency_versions = self._package_versions( + (Link(url) for url in self.dependency_links), search + ) + if dependency_versions: + logger.debug( + 'dependency_links found: %s', + ', '.join([ + version.location.url for version in dependency_versions + ]) + ) + + file_versions = self._package_versions(file_locations, search) + if file_versions: + file_versions.sort(reverse=True) + logger.debug( + 'Local files found: %s', + ', '.join([ + url_to_path(candidate.location.url) + for candidate in file_versions + ]) + ) + + # This is an intentional priority ordering + return ( + file_versions + find_links_versions + page_versions + + dependency_versions + ) + + def find_requirement(self, req, upgrade): + """Try to find a Link matching req + + Expects req, an InstallRequirement and upgrade, a boolean + Returns a Link if found, + Raises DistributionNotFound or BestVersionAlreadyInstalled otherwise + """ + all_candidates = self.find_all_candidates(req.name) + + # Filter out anything which doesn't match our specifier + compatible_versions = set( + req.specifier.filter( + # We turn the version object into a str here because otherwise + # when we're debundled but setuptools isn't, Python will see + # packaging.version.Version and + # pkg_resources._vendor.packaging.version.Version as different + # types. This way we'll use a str as a common data interchange + # format. If we stop using the pkg_resources provided specifier + # and start using our own, we can drop the cast to str(). + [str(c.version) for c in all_candidates], + prereleases=( + self.allow_all_prereleases + if self.allow_all_prereleases else None + ), + ) + ) + applicable_candidates = [ + # Again, converting to str to deal with debundling. + c for c in all_candidates if str(c.version) in compatible_versions + ] + + if applicable_candidates: + best_candidate = max(applicable_candidates, + key=self._candidate_sort_key) + else: + best_candidate = None + + if req.satisfied_by is not None: + installed_version = parse_version(req.satisfied_by.version) + else: + installed_version = None + + if installed_version is None and best_candidate is None: + logger.critical( + 'Could not find a version that satisfies the requirement %s ' + '(from versions: %s)', + req, + ', '.join( + sorted( + {str(c.version) for c in all_candidates}, + key=parse_version, + ) + ) + ) + + raise DistributionNotFound( + 'No matching distribution found for %s' % req + ) + + best_installed = False + if installed_version and ( + best_candidate is None or + best_candidate.version <= installed_version): + best_installed = True + + if not upgrade and installed_version is not None: + if best_installed: + logger.debug( + 'Existing installed version (%s) is most up-to-date and ' + 'satisfies requirement', + installed_version, + ) + else: + logger.debug( + 'Existing installed version (%s) satisfies requirement ' + '(most up-to-date version is %s)', + installed_version, + best_candidate.version, + ) + return None + + if best_installed: + # We have an existing version, and its the best version + logger.debug( + 'Installed version (%s) is most up-to-date (past versions: ' + '%s)', + installed_version, + ', '.join(sorted(compatible_versions, key=parse_version)) or + "none", + ) + raise BestVersionAlreadyInstalled + + logger.debug( + 'Using version %s (newest of versions: %s)', + best_candidate.version, + ', '.join(sorted(compatible_versions, key=parse_version)) + ) + return best_candidate.location + + def _get_pages(self, locations, project_name): + """ + Yields (page, page_url) from the given locations, skipping + locations that have errors. + """ + seen = set() + for location in locations: + if location in seen: + continue + seen.add(location) + + page = self._get_page(location) + if page is None: + continue + + yield page + + _py_version_re = re.compile(r'-py([123]\.?[0-9]?)$') + + def _sort_links(self, links): + """ + Returns elements of links in order, non-egg links first, egg links + second, while eliminating duplicates + """ + eggs, no_eggs = [], [] + seen = set() + for link in links: + if link not in seen: + seen.add(link) + if link.egg_fragment: + eggs.append(link) + else: + no_eggs.append(link) + return no_eggs + eggs + + def _package_versions(self, links, search): + result = [] + for link in self._sort_links(links): + v = self._link_package_versions(link, search) + if v is not None: + result.append(v) + return result + + def _log_skipped_link(self, link, reason): + if link not in self.logged_links: + logger.debug('Skipping link %s; %s', link, reason) + self.logged_links.add(link) + + def _link_package_versions(self, link, search): + """Return an InstallationCandidate or None""" + version = None + if link.egg_fragment: + egg_info = link.egg_fragment + ext = link.ext + else: + egg_info, ext = link.splitext() + if not ext: + self._log_skipped_link(link, 'not a file') + return + if ext not in SUPPORTED_EXTENSIONS: + self._log_skipped_link( + link, 'unsupported archive format: %s' % ext, + ) + return + if "binary" not in search.formats and ext == wheel_ext: + self._log_skipped_link( + link, 'No binaries permitted for %s' % search.supplied, + ) + return + if "macosx10" in link.path and ext == '.zip': + self._log_skipped_link(link, 'macosx10 one') + return + if ext == wheel_ext: + try: + wheel = Wheel(link.filename) + except InvalidWheelFilename: + self._log_skipped_link(link, 'invalid wheel filename') + return + if canonicalize_name(wheel.name) != search.canonical: + self._log_skipped_link( + link, 'wrong project name (not %s)' % search.supplied) + return + + if not wheel.supported(self.valid_tags): + self._log_skipped_link( + link, 'it is not compatible with this Python') + return + + version = wheel.version + + # This should be up by the search.ok_binary check, but see issue 2700. + if "source" not in search.formats and ext != wheel_ext: + self._log_skipped_link( + link, 'No sources permitted for %s' % search.supplied, + ) + return + + if not version: + version = egg_info_matches(egg_info, search.supplied, link) + if version is None: + self._log_skipped_link( + link, 'wrong project name (not %s)' % search.supplied) + return + + match = self._py_version_re.search(version) + if match: + version = version[:match.start()] + py_version = match.group(1) + if py_version != sys.version[:3]: + self._log_skipped_link( + link, 'Python version is incorrect') + return + try: + support_this_python = check_requires_python(link.requires_python) + except specifiers.InvalidSpecifier: + logger.debug("Package %s has an invalid Requires-Python entry: %s", + link.filename, link.requires_python) + support_this_python = True + + if not support_this_python: + logger.debug("The package %s is incompatible with the python" + "version in use. Acceptable python versions are:%s", + link, link.requires_python) + return + logger.debug('Found link %s, version: %s', link, version) + + return InstallationCandidate(search.supplied, version, link) + + def _get_page(self, link): + return HTMLPage.get_page(link, session=self.session) + + +def egg_info_matches( + egg_info, search_name, link, + _egg_info_re=re.compile(r'([a-z0-9_.]+)-([a-z0-9_.!+-]+)', re.I)): + """Pull the version part out of a string. + + :param egg_info: The string to parse. E.g. foo-2.1 + :param search_name: The name of the package this belongs to. None to + infer the name. Note that this cannot unambiguously parse strings + like foo-2-2 which might be foo, 2-2 or foo-2, 2. + :param link: The link the string came from, for logging on failure. + """ + match = _egg_info_re.search(egg_info) + if not match: + logger.debug('Could not parse version from link: %s', link) + return None + if search_name is None: + full_match = match.group(0) + return full_match[full_match.index('-'):] + name = match.group(0).lower() + # To match the "safe" name that pkg_resources creates: + name = name.replace('_', '-') + # project name and version must be separated by a dash + look_for = search_name.lower() + "-" + if name.startswith(look_for): + return match.group(0)[len(look_for):] + else: + return None + + +class HTMLPage(object): + """Represents one page, along with its URL""" + + def __init__(self, content, url, headers=None): + # Determine if we have any encoding information in our headers + encoding = None + if headers and "Content-Type" in headers: + content_type, params = cgi.parse_header(headers["Content-Type"]) + + if "charset" in params: + encoding = params['charset'] + + self.content = content + self.parsed = html5lib.parse( + self.content, + transport_encoding=encoding, + namespaceHTMLElements=False, + ) + self.url = url + self.headers = headers + + def __str__(self): + return self.url + + @classmethod + def get_page(cls, link, skip_archives=True, session=None): + if session is None: + raise TypeError( + "get_page() missing 1 required keyword argument: 'session'" + ) + + url = link.url + url = url.split('#', 1)[0] + + # Check for VCS schemes that do not support lookup as web pages. + from pip._internal.vcs import VcsSupport + for scheme in VcsSupport.schemes: + if url.lower().startswith(scheme) and url[len(scheme)] in '+:': + logger.debug('Cannot look at %s URL %s', scheme, link) + return None + + try: + if skip_archives: + filename = link.filename + for bad_ext in ARCHIVE_EXTENSIONS: + if filename.endswith(bad_ext): + content_type = cls._get_content_type( + url, session=session, + ) + if content_type.lower().startswith('text/html'): + break + else: + logger.debug( + 'Skipping page %s because of Content-Type: %s', + link, + content_type, + ) + return + + logger.debug('Getting page %s', url) + + # Tack index.html onto file:// URLs that point to directories + (scheme, netloc, path, params, query, fragment) = \ + urllib_parse.urlparse(url) + if (scheme == 'file' and + os.path.isdir(urllib_request.url2pathname(path))): + # add trailing slash if not present so urljoin doesn't trim + # final segment + if not url.endswith('/'): + url += '/' + url = urllib_parse.urljoin(url, 'index.html') + logger.debug(' file: URL is directory, getting %s', url) + + resp = session.get( + url, + headers={ + "Accept": "text/html", + "Cache-Control": "max-age=600", + }, + ) + resp.raise_for_status() + + # The check for archives above only works if the url ends with + # something that looks like an archive. However that is not a + # requirement of an url. Unless we issue a HEAD request on every + # url we cannot know ahead of time for sure if something is HTML + # or not. However we can check after we've downloaded it. + content_type = resp.headers.get('Content-Type', 'unknown') + if not content_type.lower().startswith("text/html"): + logger.debug( + 'Skipping page %s because of Content-Type: %s', + link, + content_type, + ) + return + + inst = cls(resp.content, resp.url, resp.headers) + except requests.HTTPError as exc: + cls._handle_fail(link, exc, url) + except SSLError as exc: + reason = "There was a problem confirming the ssl certificate: " + reason += str(exc) + cls._handle_fail(link, reason, url, meth=logger.info) + except requests.ConnectionError as exc: + cls._handle_fail(link, "connection error: %s" % exc, url) + except requests.Timeout: + cls._handle_fail(link, "timed out", url) + else: + return inst + + @staticmethod + def _handle_fail(link, reason, url, meth=None): + if meth is None: + meth = logger.debug + + meth("Could not fetch URL %s: %s - skipping", link, reason) + + @staticmethod + def _get_content_type(url, session): + """Get the Content-Type of the given url, using a HEAD request""" + scheme, netloc, path, query, fragment = urllib_parse.urlsplit(url) + if scheme not in {'http', 'https'}: + # FIXME: some warning or something? + # assertion error? + return '' + + resp = session.head(url, allow_redirects=True) + resp.raise_for_status() + + return resp.headers.get("Content-Type", "") + + @cached_property + def base_url(self): + bases = [ + x for x in self.parsed.findall(".//base") + if x.get("href") is not None + ] + if bases and bases[0].get("href"): + return bases[0].get("href") + else: + return self.url + + @property + def links(self): + """Yields all links in the page""" + for anchor in self.parsed.findall(".//a"): + if anchor.get("href"): + href = anchor.get("href") + url = self.clean_link( + urllib_parse.urljoin(self.base_url, href) + ) + pyrequire = anchor.get('data-requires-python') + pyrequire = unescape(pyrequire) if pyrequire else None + yield Link(url, self, requires_python=pyrequire) + + _clean_re = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) + + def clean_link(self, url): + """Makes sure a link is fully encoded. That is, if a ' ' shows up in + the link, it will be rewritten to %20 (while not over-quoting + % or other characters).""" + return self._clean_re.sub( + lambda match: '%%%2x' % ord(match.group(0)), url) + + +class Link(object): + + def __init__(self, url, comes_from=None, requires_python=None): + """ + Object representing a parsed link from https://pypi.org/simple/* + + url: + url of the resource pointed to (href of the link) + comes_from: + instance of HTMLPage where the link was found, or string. + requires_python: + String containing the `Requires-Python` metadata field, specified + in PEP 345. This may be specified by a data-requires-python + attribute in the HTML link tag, as described in PEP 503. + """ + + # url can be a UNC windows share + if url.startswith('\\\\'): + url = path_to_url(url) + + self.url = url + self.comes_from = comes_from + self.requires_python = requires_python if requires_python else None + + def __str__(self): + if self.requires_python: + rp = ' (requires-python:%s)' % self.requires_python + else: + rp = '' + if self.comes_from: + return '%s (from %s)%s' % (self.url, self.comes_from, rp) + else: + return str(self.url) + + def __repr__(self): + return '' % self + + def __eq__(self, other): + if not isinstance(other, Link): + return NotImplemented + return self.url == other.url + + def __ne__(self, other): + if not isinstance(other, Link): + return NotImplemented + return self.url != other.url + + def __lt__(self, other): + if not isinstance(other, Link): + return NotImplemented + return self.url < other.url + + def __le__(self, other): + if not isinstance(other, Link): + return NotImplemented + return self.url <= other.url + + def __gt__(self, other): + if not isinstance(other, Link): + return NotImplemented + return self.url > other.url + + def __ge__(self, other): + if not isinstance(other, Link): + return NotImplemented + return self.url >= other.url + + def __hash__(self): + return hash(self.url) + + @property + def filename(self): + _, netloc, path, _, _ = urllib_parse.urlsplit(self.url) + name = posixpath.basename(path.rstrip('/')) or netloc + name = urllib_parse.unquote(name) + assert name, ('URL %r produced no filename' % self.url) + return name + + @property + def scheme(self): + return urllib_parse.urlsplit(self.url)[0] + + @property + def netloc(self): + return urllib_parse.urlsplit(self.url)[1] + + @property + def path(self): + return urllib_parse.unquote(urllib_parse.urlsplit(self.url)[2]) + + def splitext(self): + return splitext(posixpath.basename(self.path.rstrip('/'))) + + @property + def ext(self): + return self.splitext()[1] + + @property + def url_without_fragment(self): + scheme, netloc, path, query, fragment = urllib_parse.urlsplit(self.url) + return urllib_parse.urlunsplit((scheme, netloc, path, query, None)) + + _egg_fragment_re = re.compile(r'[#&]egg=([^&]*)') + + @property + def egg_fragment(self): + match = self._egg_fragment_re.search(self.url) + if not match: + return None + return match.group(1) + + _subdirectory_fragment_re = re.compile(r'[#&]subdirectory=([^&]*)') + + @property + def subdirectory_fragment(self): + match = self._subdirectory_fragment_re.search(self.url) + if not match: + return None + return match.group(1) + + _hash_re = re.compile( + r'(sha1|sha224|sha384|sha256|sha512|md5)=([a-f0-9]+)' + ) + + @property + def hash(self): + match = self._hash_re.search(self.url) + if match: + return match.group(2) + return None + + @property + def hash_name(self): + match = self._hash_re.search(self.url) + if match: + return match.group(1) + return None + + @property + def show_url(self): + return posixpath.basename(self.url.split('#', 1)[0].split('?', 1)[0]) + + @property + def is_wheel(self): + return self.ext == wheel_ext + + @property + def is_artifact(self): + """ + Determines if this points to an actual artifact (e.g. a tarball) or if + it points to an "abstract" thing like a path or a VCS location. + """ + from pip._internal.vcs import vcs + + if self.scheme in vcs.all_schemes: + return False + + return True + + +FormatControl = namedtuple('FormatControl', 'no_binary only_binary') +"""This object has two fields, no_binary and only_binary. + +If a field is falsy, it isn't set. If it is {':all:'}, it should match all +packages except those listed in the other field. Only one field can be set +to {':all:'} at a time. The rest of the time exact package name matches +are listed, with any given package only showing up in one field at a time. +""" + + +def fmt_ctl_handle_mutual_exclude(value, target, other): + new = value.split(',') + while ':all:' in new: + other.clear() + target.clear() + target.add(':all:') + del new[:new.index(':all:') + 1] + if ':none:' not in new: + # Without a none, we want to discard everything as :all: covers it + return + for name in new: + if name == ':none:': + target.clear() + continue + name = canonicalize_name(name) + other.discard(name) + target.add(name) + + +def fmt_ctl_formats(fmt_ctl, canonical_name): + result = {"binary", "source"} + if canonical_name in fmt_ctl.only_binary: + result.discard('source') + elif canonical_name in fmt_ctl.no_binary: + result.discard('binary') + elif ':all:' in fmt_ctl.only_binary: + result.discard('source') + elif ':all:' in fmt_ctl.no_binary: + result.discard('binary') + return frozenset(result) + + +def fmt_ctl_no_binary(fmt_ctl): + fmt_ctl_handle_mutual_exclude( + ':all:', fmt_ctl.no_binary, fmt_ctl.only_binary, + ) + + +Search = namedtuple('Search', 'supplied canonical formats') +"""Capture key aspects of a search. + +:attribute supplied: The user supplied package. +:attribute canonical: The canonical package name. +:attribute formats: The formats allowed for this package. Should be a set + with 'binary' or 'source' or both in it. +""" diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/locations.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/locations.py new file mode 100644 index 0000000..5a20c92 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/locations.py @@ -0,0 +1,194 @@ +"""Locations where we look for configs, install stuff, etc""" +from __future__ import absolute_import + +import os +import os.path +import platform +import site +import sys +import sysconfig +from distutils import sysconfig as distutils_sysconfig +from distutils.command.install import SCHEME_KEYS, install # type: ignore + +from pip._internal.compat import WINDOWS, expanduser +from pip._internal.utils import appdirs + +# Application Directories +USER_CACHE_DIR = appdirs.user_cache_dir("pip") + + +DELETE_MARKER_MESSAGE = '''\ +This file is placed here by pip to indicate the source was put +here by pip. + +Once this package is successfully installed this source code will be +deleted (unless you remove this file). +''' +PIP_DELETE_MARKER_FILENAME = 'pip-delete-this-directory.txt' + + +def write_delete_marker_file(directory): + """ + Write the pip delete marker file into this directory. + """ + filepath = os.path.join(directory, PIP_DELETE_MARKER_FILENAME) + with open(filepath, 'w') as marker_fp: + marker_fp.write(DELETE_MARKER_MESSAGE) + + +def running_under_virtualenv(): + """ + Return True if we're running inside a virtualenv, False otherwise. + + """ + if hasattr(sys, 'real_prefix'): + return True + elif sys.prefix != getattr(sys, "base_prefix", sys.prefix): + return True + + return False + + +def virtualenv_no_global(): + """ + Return True if in a venv and no system site packages. + """ + # this mirrors the logic in virtualenv.py for locating the + # no-global-site-packages.txt file + site_mod_dir = os.path.dirname(os.path.abspath(site.__file__)) + no_global_file = os.path.join(site_mod_dir, 'no-global-site-packages.txt') + if running_under_virtualenv() and os.path.isfile(no_global_file): + return True + + +if running_under_virtualenv(): + src_prefix = os.path.join(sys.prefix, 'src') +else: + # FIXME: keep src in cwd for now (it is not a temporary folder) + try: + src_prefix = os.path.join(os.getcwd(), 'src') + except OSError: + # In case the current working directory has been renamed or deleted + sys.exit( + "The folder you are executing pip from can no longer be found." + ) + +# under macOS + virtualenv sys.prefix is not properly resolved +# it is something like /path/to/python/bin/.. +# Note: using realpath due to tmp dirs on OSX being symlinks +src_prefix = os.path.abspath(src_prefix) + +# FIXME doesn't account for venv linked to global site-packages + +site_packages = sysconfig.get_path("purelib") +# This is because of a bug in PyPy's sysconfig module, see +# https://bitbucket.org/pypy/pypy/issues/2506/sysconfig-returns-incorrect-paths +# for more information. +if platform.python_implementation().lower() == "pypy": + site_packages = distutils_sysconfig.get_python_lib() +try: + # Use getusersitepackages if this is present, as it ensures that the + # value is initialised properly. + user_site = site.getusersitepackages() +except AttributeError: + user_site = site.USER_SITE +user_dir = expanduser('~') +if WINDOWS: + bin_py = os.path.join(sys.prefix, 'Scripts') + bin_user = os.path.join(user_site, 'Scripts') + # buildout uses 'bin' on Windows too? + if not os.path.exists(bin_py): + bin_py = os.path.join(sys.prefix, 'bin') + bin_user = os.path.join(user_site, 'bin') + + config_basename = 'pip.ini' + + legacy_storage_dir = os.path.join(user_dir, 'pip') + legacy_config_file = os.path.join( + legacy_storage_dir, + config_basename, + ) +else: + bin_py = os.path.join(sys.prefix, 'bin') + bin_user = os.path.join(user_site, 'bin') + + config_basename = 'pip.conf' + + legacy_storage_dir = os.path.join(user_dir, '.pip') + legacy_config_file = os.path.join( + legacy_storage_dir, + config_basename, + ) + # Forcing to use /usr/local/bin for standard macOS framework installs + # Also log to ~/Library/Logs/ for use with the Console.app log viewer + if sys.platform[:6] == 'darwin' and sys.prefix[:16] == '/System/Library/': + bin_py = '/usr/local/bin' + +site_config_files = [ + os.path.join(path, config_basename) + for path in appdirs.site_config_dirs('pip') +] + +venv_config_file = os.path.join(sys.prefix, config_basename) +new_config_file = os.path.join(appdirs.user_config_dir("pip"), config_basename) + + +def distutils_scheme(dist_name, user=False, home=None, root=None, + isolated=False, prefix=None): + """ + Return a distutils install scheme + """ + from distutils.dist import Distribution + + scheme = {} + + if isolated: + extra_dist_args = {"script_args": ["--no-user-cfg"]} + else: + extra_dist_args = {} + dist_args = {'name': dist_name} + dist_args.update(extra_dist_args) + + d = Distribution(dist_args) + d.parse_config_files() + i = d.get_command_obj('install', create=True) + # NOTE: setting user or home has the side-effect of creating the home dir + # or user base for installations during finalize_options() + # ideally, we'd prefer a scheme class that has no side-effects. + assert not (user and prefix), "user={} prefix={}".format(user, prefix) + i.user = user or i.user + if user: + i.prefix = "" + i.prefix = prefix or i.prefix + i.home = home or i.home + i.root = root or i.root + i.finalize_options() + for key in SCHEME_KEYS: + scheme[key] = getattr(i, 'install_' + key) + + # install_lib specified in setup.cfg should install *everything* + # into there (i.e. it takes precedence over both purelib and + # platlib). Note, i.install_lib is *always* set after + # finalize_options(); we only want to override here if the user + # has explicitly requested it hence going back to the config + if 'install_lib' in d.get_option_dict('install'): + scheme.update(dict(purelib=i.install_lib, platlib=i.install_lib)) + + if running_under_virtualenv(): + scheme['headers'] = os.path.join( + sys.prefix, + 'include', + 'site', + 'python' + sys.version[:3], + dist_name, + ) + + if root is not None: + path_no_drive = os.path.splitdrive( + os.path.abspath(scheme["headers"]))[1] + scheme["headers"] = os.path.join( + root, + path_no_drive[1:], + ) + + return scheme diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/__init__.py new file mode 100644 index 0000000..505d92c --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/__init__.py @@ -0,0 +1,4 @@ +from pip._internal.models.index import Index, PyPI + + +__all__ = ["Index", "PyPI"] diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/index.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/index.py new file mode 100644 index 0000000..a7f10c8 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/index.py @@ -0,0 +1,15 @@ +from pip._vendor.six.moves.urllib import parse as urllib_parse + + +class Index(object): + def __init__(self, url): + self.url = url + self.netloc = urllib_parse.urlsplit(url).netloc + self.simple_url = self.url_to_path('simple') + self.pypi_url = self.url_to_path('pypi') + + def url_to_path(self, path): + return urllib_parse.urljoin(self.url, path) + + +PyPI = Index('https://pypi.org/') diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/check.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/check.py new file mode 100644 index 0000000..b1ad5b6 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/check.py @@ -0,0 +1,106 @@ +"""Validation of dependencies of packages +""" + +from collections import namedtuple + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.operations.prepare import make_abstract_dist + +from pip._internal.utils.misc import get_installed_distributions +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from pip._internal.req.req_install import InstallRequirement + from typing import Any, Dict, Iterator, Set, Tuple, List + + # Shorthands + PackageSet = Dict[str, 'PackageDetails'] + Missing = Tuple[str, Any] + Conflicting = Tuple[str, str, Any] + + MissingDict = Dict[str, List[Missing]] + ConflictingDict = Dict[str, List[Conflicting]] + CheckResult = Tuple[MissingDict, ConflictingDict] + +PackageDetails = namedtuple('PackageDetails', ['version', 'requires']) + + +def create_package_set_from_installed(**kwargs): + # type: (**Any) -> PackageSet + """Converts a list of distributions into a PackageSet. + """ + # Default to using all packages installed on the system + if kwargs == {}: + kwargs = {"local_only": False, "skip": ()} + retval = {} + for dist in get_installed_distributions(**kwargs): + name = canonicalize_name(dist.project_name) + retval[name] = PackageDetails(dist.version, dist.requires()) + return retval + + +def check_package_set(package_set): + # type: (PackageSet) -> CheckResult + """Check if a package set is consistent + """ + missing = dict() + conflicting = dict() + + for package_name in package_set: + # Info about dependencies of package_name + missing_deps = set() # type: Set[Missing] + conflicting_deps = set() # type: Set[Conflicting] + + for req in package_set[package_name].requires: + name = canonicalize_name(req.project_name) # type: str + + # Check if it's missing + if name not in package_set: + missed = True + if req.marker is not None: + missed = req.marker.evaluate() + if missed: + missing_deps.add((name, req)) + continue + + # Check if there's a conflict + version = package_set[name].version # type: str + if not req.specifier.contains(version, prereleases=True): + conflicting_deps.add((name, version, req)) + + def str_key(x): + return str(x) + + if missing_deps: + missing[package_name] = sorted(missing_deps, key=str_key) + if conflicting_deps: + conflicting[package_name] = sorted(conflicting_deps, key=str_key) + + return missing, conflicting + + +def check_install_conflicts(to_install): + # type: (List[InstallRequirement]) -> Tuple[PackageSet, CheckResult] + """For checking if the dependency graph would be consistent after \ + installing given requirements + """ + # Start from the current state + state = create_package_set_from_installed() + _simulate_installation_of(to_install, state) + return state, check_package_set(state) + + +# NOTE from @pradyunsg +# This required a minor update in dependency link handling logic over at +# operations.prepare.IsSDist.dist() to get it working +def _simulate_installation_of(to_install, state): + # type: (List[InstallRequirement], PackageSet) -> None + """Computes the version of packages after installing to_install. + """ + + # Modify it as installing requirement_set would (assuming no errors) + for inst_req in to_install: + dist = make_abstract_dist(inst_req).dist(finder=None) + name = canonicalize_name(dist.key) + state[name] = PackageDetails(dist.version, dist.requires()) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/freeze.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/freeze.py new file mode 100644 index 0000000..b6821c0 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/freeze.py @@ -0,0 +1,252 @@ +from __future__ import absolute_import + +import collections +import logging +import os +import re +import warnings + +from pip._vendor import pkg_resources, six +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.pkg_resources import RequirementParseError + +from pip._internal.exceptions import InstallationError +from pip._internal.req import InstallRequirement +from pip._internal.req.req_file import COMMENT_RE +from pip._internal.utils.deprecation import RemovedInPip11Warning +from pip._internal.utils.misc import ( + dist_is_editable, get_installed_distributions, +) + +logger = logging.getLogger(__name__) + + +def freeze( + requirement=None, + find_links=None, local_only=None, user_only=None, skip_regex=None, + isolated=False, + wheel_cache=None, + exclude_editable=False, + skip=()): + find_links = find_links or [] + skip_match = None + + if skip_regex: + skip_match = re.compile(skip_regex).search + + dependency_links = [] + + for dist in pkg_resources.working_set: + if dist.has_metadata('dependency_links.txt'): + dependency_links.extend( + dist.get_metadata_lines('dependency_links.txt') + ) + for link in find_links: + if '#egg=' in link: + dependency_links.append(link) + for link in find_links: + yield '-f %s' % link + installations = {} + for dist in get_installed_distributions(local_only=local_only, + skip=(), + user_only=user_only): + try: + req = FrozenRequirement.from_dist( + dist, + dependency_links + ) + except RequirementParseError: + logger.warning( + "Could not parse requirement: %s", + dist.project_name + ) + continue + if exclude_editable and req.editable: + continue + installations[req.name] = req + + if requirement: + # the options that don't get turned into an InstallRequirement + # should only be emitted once, even if the same option is in multiple + # requirements files, so we need to keep track of what has been emitted + # so that we don't emit it again if it's seen again + emitted_options = set() + # keep track of which files a requirement is in so that we can + # give an accurate warning if a requirement appears multiple times. + req_files = collections.defaultdict(list) + for req_file_path in requirement: + with open(req_file_path) as req_file: + for line in req_file: + if (not line.strip() or + line.strip().startswith('#') or + (skip_match and skip_match(line)) or + line.startswith(( + '-r', '--requirement', + '-Z', '--always-unzip', + '-f', '--find-links', + '-i', '--index-url', + '--pre', + '--trusted-host', + '--process-dependency-links', + '--extra-index-url'))): + line = line.rstrip() + if line not in emitted_options: + emitted_options.add(line) + yield line + continue + + if line.startswith('-e') or line.startswith('--editable'): + if line.startswith('-e'): + line = line[2:].strip() + else: + line = line[len('--editable'):].strip().lstrip('=') + line_req = InstallRequirement.from_editable( + line, + isolated=isolated, + wheel_cache=wheel_cache, + ) + else: + line_req = InstallRequirement.from_line( + COMMENT_RE.sub('', line).strip(), + isolated=isolated, + wheel_cache=wheel_cache, + ) + + if not line_req.name: + logger.info( + "Skipping line in requirement file [%s] because " + "it's not clear what it would install: %s", + req_file_path, line.strip(), + ) + logger.info( + " (add #egg=PackageName to the URL to avoid" + " this warning)" + ) + elif line_req.name not in installations: + # either it's not installed, or it is installed + # but has been processed already + if not req_files[line_req.name]: + logger.warning( + "Requirement file [%s] contains %s, but that " + "package is not installed", + req_file_path, + COMMENT_RE.sub('', line).strip(), + ) + else: + req_files[line_req.name].append(req_file_path) + else: + yield str(installations[line_req.name]).rstrip() + del installations[line_req.name] + req_files[line_req.name].append(req_file_path) + + # Warn about requirements that were included multiple times (in a + # single requirements file or in different requirements files). + for name, files in six.iteritems(req_files): + if len(files) > 1: + logger.warning("Requirement %s included multiple times [%s]", + name, ', '.join(sorted(set(files)))) + + yield( + '## The following requirements were added by ' + 'pip freeze:' + ) + for installation in sorted( + installations.values(), key=lambda x: x.name.lower()): + if canonicalize_name(installation.name) not in skip: + yield str(installation).rstrip() + + +class FrozenRequirement(object): + def __init__(self, name, req, editable, comments=()): + self.name = name + self.req = req + self.editable = editable + self.comments = comments + + _rev_re = re.compile(r'-r(\d+)$') + _date_re = re.compile(r'-(20\d\d\d\d\d\d)$') + + @classmethod + def from_dist(cls, dist, dependency_links): + location = os.path.normcase(os.path.abspath(dist.location)) + comments = [] + from pip._internal.vcs import vcs, get_src_requirement + if dist_is_editable(dist) and vcs.get_backend_name(location): + editable = True + try: + req = get_src_requirement(dist, location) + except InstallationError as exc: + logger.warning( + "Error when trying to get requirement for VCS system %s, " + "falling back to uneditable format", exc + ) + req = None + if req is None: + logger.warning( + 'Could not determine repository location of %s', location + ) + comments.append( + '## !! Could not determine repository location' + ) + req = dist.as_requirement() + editable = False + else: + editable = False + req = dist.as_requirement() + specs = req.specs + assert len(specs) == 1 and specs[0][0] in ["==", "==="], \ + 'Expected 1 spec with == or ===; specs = %r; dist = %r' % \ + (specs, dist) + version = specs[0][1] + ver_match = cls._rev_re.search(version) + date_match = cls._date_re.search(version) + if ver_match or date_match: + svn_backend = vcs.get_backend('svn') + if svn_backend: + svn_location = svn_backend().get_location( + dist, + dependency_links, + ) + if not svn_location: + logger.warning( + 'Warning: cannot find svn location for %s', req, + ) + comments.append( + '## FIXME: could not find svn URL in dependency_links ' + 'for this package:' + ) + else: + warnings.warn( + "SVN editable detection based on dependency links " + "will be dropped in the future.", + RemovedInPip11Warning, + ) + comments.append( + '# Installing as editable to satisfy requirement %s:' % + req + ) + if ver_match: + rev = ver_match.group(1) + else: + rev = '{%s}' % date_match.group(1) + editable = True + req = '%s@%s#egg=%s' % ( + svn_location, + rev, + cls.egg_name(dist) + ) + return cls(dist.project_name, req, editable, comments) + + @staticmethod + def egg_name(dist): + name = dist.egg_name() + match = re.search(r'-py\d\.\d$', name) + if match: + name = name[:match.start()] + return name + + def __str__(self): + req = self.req + if self.editable: + req = '-e %s' % req + return '\n'.join(list(self.comments) + [str(req)]) + '\n' diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/prepare.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/prepare.py new file mode 100644 index 0000000..27e3a5d --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/prepare.py @@ -0,0 +1,380 @@ +"""Prepares a distribution for installation +""" + +import itertools +import logging +import os +import sys +from copy import copy + +from pip._vendor import pkg_resources, requests + +from pip._internal.build_env import NoOpBuildEnvironment +from pip._internal.compat import expanduser +from pip._internal.download import ( + is_dir_url, is_file_url, is_vcs_url, unpack_url, url_to_path, +) +from pip._internal.exceptions import ( + DirectoryUrlHashUnsupported, HashUnpinned, InstallationError, + PreviousBuildDirError, VcsHashUnsupported, +) +from pip._internal.index import FormatControl +from pip._internal.req.req_install import InstallRequirement +from pip._internal.utils.hashes import MissingHashes +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + call_subprocess, display_path, normalize_path, +) +from pip._internal.utils.ui import open_spinner +from pip._internal.vcs import vcs + +logger = logging.getLogger(__name__) + + +def make_abstract_dist(req): + """Factory to make an abstract dist object. + + Preconditions: Either an editable req with a source_dir, or satisfied_by or + a wheel link, or a non-editable req with a source_dir. + + :return: A concrete DistAbstraction. + """ + if req.editable: + return IsSDist(req) + elif req.link and req.link.is_wheel: + return IsWheel(req) + else: + return IsSDist(req) + + +def _install_build_reqs(finder, prefix, build_requirements): + # NOTE: What follows is not a very good thing. + # Eventually, this should move into the BuildEnvironment class and + # that should handle all the isolation and sub-process invocation. + finder = copy(finder) + finder.format_control = FormatControl(set(), set([":all:"])) + urls = [ + finder.find_requirement( + InstallRequirement.from_line(r), upgrade=False).url + for r in build_requirements + ] + args = [ + sys.executable, '-m', 'pip', 'install', '--ignore-installed', + '--no-user', '--prefix', prefix, + ] + list(urls) + + with open_spinner("Installing build dependencies") as spinner: + call_subprocess(args, show_stdout=False, spinner=spinner) + + +class DistAbstraction(object): + """Abstracts out the wheel vs non-wheel Resolver.resolve() logic. + + The requirements for anything installable are as follows: + - we must be able to determine the requirement name + (or we can't correctly handle the non-upgrade case). + - we must be able to generate a list of run-time dependencies + without installing any additional packages (or we would + have to either burn time by doing temporary isolated installs + or alternatively violate pips 'don't start installing unless + all requirements are available' rule - neither of which are + desirable). + - for packages with setup requirements, we must also be able + to determine their requirements without installing additional + packages (for the same reason as run-time dependencies) + - we must be able to create a Distribution object exposing the + above metadata. + """ + + def __init__(self, req): + self.req = req + + def dist(self, finder): + """Return a setuptools Dist object.""" + raise NotImplementedError(self.dist) + + def prep_for_dist(self, finder): + """Ensure that we can get a Dist for this requirement.""" + raise NotImplementedError(self.dist) + + +class IsWheel(DistAbstraction): + + def dist(self, finder): + return list(pkg_resources.find_distributions( + self.req.source_dir))[0] + + def prep_for_dist(self, finder, build_isolation): + # FIXME:https://github.com/pypa/pip/issues/1112 + pass + + +class IsSDist(DistAbstraction): + + def dist(self, finder): + dist = self.req.get_dist() + # FIXME: shouldn't be globally added. + if finder and dist.has_metadata('dependency_links.txt'): + finder.add_dependency_links( + dist.get_metadata_lines('dependency_links.txt') + ) + return dist + + def prep_for_dist(self, finder, build_isolation): + # Before calling "setup.py egg_info", we need to set-up the build + # environment. + build_requirements, isolate = self.req.get_pep_518_info() + should_isolate = build_isolation and isolate + + minimum_requirements = ('setuptools', 'wheel') + missing_requirements = set(minimum_requirements) - set( + pkg_resources.Requirement(r).key + for r in build_requirements + ) + if missing_requirements: + def format_reqs(rs): + return ' and '.join(map(repr, sorted(rs))) + logger.warning( + "Missing build time requirements in pyproject.toml for %s: " + "%s.", self.req, format_reqs(missing_requirements) + ) + logger.warning( + "This version of pip does not implement PEP 517 so it cannot " + "build a wheel without %s.", format_reqs(minimum_requirements) + ) + + if should_isolate: + with self.req.build_env: + pass + _install_build_reqs(finder, self.req.build_env.path, + build_requirements) + else: + self.req.build_env = NoOpBuildEnvironment(no_clean=False) + + self.req.run_egg_info() + self.req.assert_source_matches_version() + + +class Installed(DistAbstraction): + + def dist(self, finder): + return self.req.satisfied_by + + def prep_for_dist(self, finder): + pass + + +class RequirementPreparer(object): + """Prepares a Requirement + """ + + def __init__(self, build_dir, download_dir, src_dir, wheel_download_dir, + progress_bar, build_isolation): + super(RequirementPreparer, self).__init__() + + self.src_dir = src_dir + self.build_dir = build_dir + + # Where still packed archives should be written to. If None, they are + # not saved, and are deleted immediately after unpacking. + self.download_dir = download_dir + + # Where still-packed .whl files should be written to. If None, they are + # written to the download_dir parameter. Separate to download_dir to + # permit only keeping wheel archives for pip wheel. + if wheel_download_dir: + wheel_download_dir = normalize_path(wheel_download_dir) + self.wheel_download_dir = wheel_download_dir + + # NOTE + # download_dir and wheel_download_dir overlap semantically and may + # be combined if we're willing to have non-wheel archives present in + # the wheelhouse output by 'pip wheel'. + + self.progress_bar = progress_bar + + # Is build isolation allowed? + self.build_isolation = build_isolation + + @property + def _download_should_save(self): + # TODO: Modify to reduce indentation needed + if self.download_dir: + self.download_dir = expanduser(self.download_dir) + if os.path.exists(self.download_dir): + return True + else: + logger.critical('Could not find download directory') + raise InstallationError( + "Could not find or access download directory '%s'" + % display_path(self.download_dir)) + return False + + def prepare_linked_requirement(self, req, session, finder, + upgrade_allowed, require_hashes): + """Prepare a requirement that would be obtained from req.link + """ + # TODO: Breakup into smaller functions + if req.link and req.link.scheme == 'file': + path = url_to_path(req.link.url) + logger.info('Processing %s', display_path(path)) + else: + logger.info('Collecting %s', req) + + with indent_log(): + # @@ if filesystem packages are not marked + # editable in a req, a non deterministic error + # occurs when the script attempts to unpack the + # build directory + req.ensure_has_source_dir(self.build_dir) + # If a checkout exists, it's unwise to keep going. version + # inconsistencies are logged later, but do not fail the + # installation. + # FIXME: this won't upgrade when there's an existing + # package unpacked in `req.source_dir` + # package unpacked in `req.source_dir` + if os.path.exists(os.path.join(req.source_dir, 'setup.py')): + raise PreviousBuildDirError( + "pip can't proceed with requirements '%s' due to a" + " pre-existing build directory (%s). This is " + "likely due to a previous installation that failed" + ". pip is being responsible and not assuming it " + "can delete this. Please delete it and try again." + % (req, req.source_dir) + ) + req.populate_link(finder, upgrade_allowed, require_hashes) + + # We can't hit this spot and have populate_link return None. + # req.satisfied_by is None here (because we're + # guarded) and upgrade has no impact except when satisfied_by + # is not None. + # Then inside find_requirement existing_applicable -> False + # If no new versions are found, DistributionNotFound is raised, + # otherwise a result is guaranteed. + assert req.link + link = req.link + + # Now that we have the real link, we can tell what kind of + # requirements we have and raise some more informative errors + # than otherwise. (For example, we can raise VcsHashUnsupported + # for a VCS URL rather than HashMissing.) + if require_hashes: + # We could check these first 2 conditions inside + # unpack_url and save repetition of conditions, but then + # we would report less-useful error messages for + # unhashable requirements, complaining that there's no + # hash provided. + if is_vcs_url(link): + raise VcsHashUnsupported() + elif is_file_url(link) and is_dir_url(link): + raise DirectoryUrlHashUnsupported() + if not req.original_link and not req.is_pinned: + # Unpinned packages are asking for trouble when a new + # version is uploaded. This isn't a security check, but + # it saves users a surprising hash mismatch in the + # future. + # + # file:/// URLs aren't pinnable, so don't complain + # about them not being pinned. + raise HashUnpinned() + + hashes = req.hashes(trust_internet=not require_hashes) + if require_hashes and not hashes: + # Known-good hashes are missing for this requirement, so + # shim it with a facade object that will provoke hash + # computation and then raise a HashMissing exception + # showing the user what the hash should be. + hashes = MissingHashes() + + try: + download_dir = self.download_dir + # We always delete unpacked sdists after pip ran. + autodelete_unpacked = True + if req.link.is_wheel and self.wheel_download_dir: + # when doing 'pip wheel` we download wheels to a + # dedicated dir. + download_dir = self.wheel_download_dir + if req.link.is_wheel: + if download_dir: + # When downloading, we only unpack wheels to get + # metadata. + autodelete_unpacked = True + else: + # When installing a wheel, we use the unpacked + # wheel. + autodelete_unpacked = False + unpack_url( + req.link, req.source_dir, + download_dir, autodelete_unpacked, + session=session, hashes=hashes, + progress_bar=self.progress_bar + ) + except requests.HTTPError as exc: + logger.critical( + 'Could not install requirement %s because of error %s', + req, + exc, + ) + raise InstallationError( + 'Could not install requirement %s because of HTTP ' + 'error %s for URL %s' % + (req, exc, req.link) + ) + abstract_dist = make_abstract_dist(req) + abstract_dist.prep_for_dist(finder, self.build_isolation) + if self._download_should_save: + # Make a .zip of the source_dir we already created. + if req.link.scheme in vcs.all_schemes: + req.archive(self.download_dir) + return abstract_dist + + def prepare_editable_requirement(self, req, require_hashes, use_user_site, + finder): + """Prepare an editable requirement + """ + assert req.editable, "cannot prepare a non-editable req as editable" + + logger.info('Obtaining %s', req) + + with indent_log(): + if require_hashes: + raise InstallationError( + 'The editable requirement %s cannot be installed when ' + 'requiring hashes, because there is no single file to ' + 'hash.' % req + ) + req.ensure_has_source_dir(self.src_dir) + req.update_editable(not self._download_should_save) + + abstract_dist = make_abstract_dist(req) + abstract_dist.prep_for_dist(finder, self.build_isolation) + + if self._download_should_save: + req.archive(self.download_dir) + req.check_if_exists(use_user_site) + + return abstract_dist + + def prepare_installed_requirement(self, req, require_hashes, skip_reason): + """Prepare an already-installed requirement + """ + assert req.satisfied_by, "req should have been satisfied but isn't" + assert skip_reason is not None, ( + "did not get skip reason skipped but req.satisfied_by " + "is set to %r" % (req.satisfied_by,) + ) + logger.info( + 'Requirement %s: %s (%s)', + skip_reason, req, req.satisfied_by.version + ) + with indent_log(): + if require_hashes: + logger.debug( + 'Since it is already installed, we are trusting this ' + 'package without checking its hash. To ensure a ' + 'completely repeatable environment, install into an ' + 'empty virtualenv.' + ) + abstract_dist = Installed(req) + + return abstract_dist diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/pep425tags.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/pep425tags.py new file mode 100644 index 0000000..0b5c783 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/pep425tags.py @@ -0,0 +1,317 @@ +"""Generate and work with PEP 425 Compatibility Tags.""" +from __future__ import absolute_import + +import distutils.util +import logging +import platform +import re +import sys +import sysconfig +import warnings +from collections import OrderedDict + +import pip._internal.utils.glibc + +logger = logging.getLogger(__name__) + +_osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)') + + +def get_config_var(var): + try: + return sysconfig.get_config_var(var) + except IOError as e: # Issue #1074 + warnings.warn("{}".format(e), RuntimeWarning) + return None + + +def get_abbr_impl(): + """Return abbreviated implementation name.""" + if hasattr(sys, 'pypy_version_info'): + pyimpl = 'pp' + elif sys.platform.startswith('java'): + pyimpl = 'jy' + elif sys.platform == 'cli': + pyimpl = 'ip' + else: + pyimpl = 'cp' + return pyimpl + + +def get_impl_ver(): + """Return implementation version.""" + impl_ver = get_config_var("py_version_nodot") + if not impl_ver or get_abbr_impl() == 'pp': + impl_ver = ''.join(map(str, get_impl_version_info())) + return impl_ver + + +def get_impl_version_info(): + """Return sys.version_info-like tuple for use in decrementing the minor + version.""" + if get_abbr_impl() == 'pp': + # as per https://github.com/pypa/pip/issues/2882 + return (sys.version_info[0], sys.pypy_version_info.major, + sys.pypy_version_info.minor) + else: + return sys.version_info[0], sys.version_info[1] + + +def get_impl_tag(): + """ + Returns the Tag for this specific implementation. + """ + return "{}{}".format(get_abbr_impl(), get_impl_ver()) + + +def get_flag(var, fallback, expected=True, warn=True): + """Use a fallback method for determining SOABI flags if the needed config + var is unset or unavailable.""" + val = get_config_var(var) + if val is None: + if warn: + logger.debug("Config variable '%s' is unset, Python ABI tag may " + "be incorrect", var) + return fallback() + return val == expected + + +def get_abi_tag(): + """Return the ABI tag based on SOABI (if available) or emulate SOABI + (CPython 2, PyPy).""" + soabi = get_config_var('SOABI') + impl = get_abbr_impl() + if not soabi and impl in {'cp', 'pp'} and hasattr(sys, 'maxunicode'): + d = '' + m = '' + u = '' + if get_flag('Py_DEBUG', + lambda: hasattr(sys, 'gettotalrefcount'), + warn=(impl == 'cp')): + d = 'd' + if get_flag('WITH_PYMALLOC', + lambda: impl == 'cp', + warn=(impl == 'cp')): + m = 'm' + if get_flag('Py_UNICODE_SIZE', + lambda: sys.maxunicode == 0x10ffff, + expected=4, + warn=(impl == 'cp' and + sys.version_info < (3, 3))) \ + and sys.version_info < (3, 3): + u = 'u' + abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u) + elif soabi and soabi.startswith('cpython-'): + abi = 'cp' + soabi.split('-')[1] + elif soabi: + abi = soabi.replace('.', '_').replace('-', '_') + else: + abi = None + return abi + + +def _is_running_32bit(): + return sys.maxsize == 2147483647 + + +def get_platform(): + """Return our platform name 'win32', 'linux_x86_64'""" + if sys.platform == 'darwin': + # distutils.util.get_platform() returns the release based on the value + # of MACOSX_DEPLOYMENT_TARGET on which Python was built, which may + # be significantly older than the user's current machine. + release, _, machine = platform.mac_ver() + split_ver = release.split('.') + + if machine == "x86_64" and _is_running_32bit(): + machine = "i386" + elif machine == "ppc64" and _is_running_32bit(): + machine = "ppc" + + return 'macosx_{}_{}_{}'.format(split_ver[0], split_ver[1], machine) + + # XXX remove distutils dependency + result = distutils.util.get_platform().replace('.', '_').replace('-', '_') + if result == "linux_x86_64" and _is_running_32bit(): + # 32 bit Python program (running on a 64 bit Linux): pip should only + # install and run 32 bit compiled extensions in that case. + result = "linux_i686" + + return result + + +def is_manylinux1_compatible(): + # Only Linux, and only x86-64 / i686 + if get_platform() not in {"linux_x86_64", "linux_i686"}: + return False + + # Check for presence of _manylinux module + try: + import _manylinux + return bool(_manylinux.manylinux1_compatible) + except (ImportError, AttributeError): + # Fall through to heuristic check below + pass + + # Check glibc version. CentOS 5 uses glibc 2.5. + return pip._internal.utils.glibc.have_compatible_glibc(2, 5) + + +def get_darwin_arches(major, minor, machine): + """Return a list of supported arches (including group arches) for + the given major, minor and machine architecture of an macOS machine. + """ + arches = [] + + def _supports_arch(major, minor, arch): + # Looking at the application support for macOS versions in the chart + # provided by https://en.wikipedia.org/wiki/OS_X#Versions it appears + # our timeline looks roughly like: + # + # 10.0 - Introduces ppc support. + # 10.4 - Introduces ppc64, i386, and x86_64 support, however the ppc64 + # and x86_64 support is CLI only, and cannot be used for GUI + # applications. + # 10.5 - Extends ppc64 and x86_64 support to cover GUI applications. + # 10.6 - Drops support for ppc64 + # 10.7 - Drops support for ppc + # + # Given that we do not know if we're installing a CLI or a GUI + # application, we must be conservative and assume it might be a GUI + # application and behave as if ppc64 and x86_64 support did not occur + # until 10.5. + # + # Note: The above information is taken from the "Application support" + # column in the chart not the "Processor support" since I believe + # that we care about what instruction sets an application can use + # not which processors the OS supports. + if arch == 'ppc': + return (major, minor) <= (10, 5) + if arch == 'ppc64': + return (major, minor) == (10, 5) + if arch == 'i386': + return (major, minor) >= (10, 4) + if arch == 'x86_64': + return (major, minor) >= (10, 5) + if arch in groups: + for garch in groups[arch]: + if _supports_arch(major, minor, garch): + return True + return False + + groups = OrderedDict([ + ("fat", ("i386", "ppc")), + ("intel", ("x86_64", "i386")), + ("fat64", ("x86_64", "ppc64")), + ("fat32", ("x86_64", "i386", "ppc")), + ]) + + if _supports_arch(major, minor, machine): + arches.append(machine) + + for garch in groups: + if machine in groups[garch] and _supports_arch(major, minor, garch): + arches.append(garch) + + arches.append('universal') + + return arches + + +def get_supported(versions=None, noarch=False, platform=None, + impl=None, abi=None): + """Return a list of supported tags for each version specified in + `versions`. + + :param versions: a list of string versions, of the form ["33", "32"], + or None. The first version will be assumed to support our ABI. + :param platform: specify the exact platform you want valid + tags for, or None. If None, use the local system platform. + :param impl: specify the exact implementation you want valid + tags for, or None. If None, use the local interpreter impl. + :param abi: specify the exact abi you want valid + tags for, or None. If None, use the local interpreter abi. + """ + supported = [] + + # Versions must be given with respect to the preference + if versions is None: + versions = [] + version_info = get_impl_version_info() + major = version_info[:-1] + # Support all previous minor Python versions. + for minor in range(version_info[-1], -1, -1): + versions.append(''.join(map(str, major + (minor,)))) + + impl = impl or get_abbr_impl() + + abis = [] + + abi = abi or get_abi_tag() + if abi: + abis[0:0] = [abi] + + abi3s = set() + import imp + for suffix in imp.get_suffixes(): + if suffix[0].startswith('.abi'): + abi3s.add(suffix[0].split('.', 2)[1]) + + abis.extend(sorted(list(abi3s))) + + abis.append('none') + + if not noarch: + arch = platform or get_platform() + if arch.startswith('macosx'): + # support macosx-10.6-intel on macosx-10.9-x86_64 + match = _osx_arch_pat.match(arch) + if match: + name, major, minor, actual_arch = match.groups() + tpl = '{}_{}_%i_%s'.format(name, major) + arches = [] + for m in reversed(range(int(minor) + 1)): + for a in get_darwin_arches(int(major), m, actual_arch): + arches.append(tpl % (m, a)) + else: + # arch pattern didn't match (?!) + arches = [arch] + elif platform is None and is_manylinux1_compatible(): + arches = [arch.replace('linux', 'manylinux1'), arch] + else: + arches = [arch] + + # Current version, current API (built specifically for our Python): + for abi in abis: + for arch in arches: + supported.append(('%s%s' % (impl, versions[0]), abi, arch)) + + # abi3 modules compatible with older version of Python + for version in versions[1:]: + # abi3 was introduced in Python 3.2 + if version in {'31', '30'}: + break + for abi in abi3s: # empty set if not Python 3 + for arch in arches: + supported.append(("%s%s" % (impl, version), abi, arch)) + + # Has binaries, does not use the Python API: + for arch in arches: + supported.append(('py%s' % (versions[0][0]), 'none', arch)) + + # No abi / arch, but requires our implementation: + supported.append(('%s%s' % (impl, versions[0]), 'none', 'any')) + # Tagged specifically as being cross-version compatible + # (with just the major version specified) + supported.append(('%s%s' % (impl, versions[0][0]), 'none', 'any')) + + # No abi / arch, generic Python + for i, version in enumerate(versions): + supported.append(('py%s' % (version,), 'none', 'any')) + if i == 0: + supported.append(('py%s' % (version[0]), 'none', 'any')) + + return supported + + +implementation_tag = get_impl_tag() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__init__.py new file mode 100644 index 0000000..c9b4c3c --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__init__.py @@ -0,0 +1,69 @@ +from __future__ import absolute_import + +import logging + +from .req_install import InstallRequirement +from .req_set import RequirementSet +from .req_file import parse_requirements +from pip._internal.utils.logging import indent_log + + +__all__ = [ + "RequirementSet", "InstallRequirement", + "parse_requirements", "install_given_reqs", +] + +logger = logging.getLogger(__name__) + + +def install_given_reqs(to_install, install_options, global_options=(), + *args, **kwargs): + """ + Install everything in the given list. + + (to be called after having downloaded and unpacked the packages) + """ + + if to_install: + logger.info( + 'Installing collected packages: %s', + ', '.join([req.name for req in to_install]), + ) + + with indent_log(): + for requirement in to_install: + if requirement.conflicts_with: + logger.info( + 'Found existing installation: %s', + requirement.conflicts_with, + ) + with indent_log(): + uninstalled_pathset = requirement.uninstall( + auto_confirm=True + ) + try: + requirement.install( + install_options, + global_options, + *args, + **kwargs + ) + except: + should_rollback = ( + requirement.conflicts_with and + not requirement.install_succeeded + ) + # if install did not succeed, rollback previous uninstall + if should_rollback: + uninstalled_pathset.rollback() + raise + else: + should_commit = ( + requirement.conflicts_with and + requirement.install_succeeded + ) + if should_commit: + uninstalled_pathset.commit() + requirement.remove_temporary_source() + + return to_install diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_file.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_file.py new file mode 100644 index 0000000..f868497 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_file.py @@ -0,0 +1,338 @@ +""" +Requirements file parsing +""" + +from __future__ import absolute_import + +import optparse +import os +import re +import shlex +import sys + +from pip._vendor.six.moves import filterfalse +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal import cmdoptions +from pip._internal.download import get_file_content +from pip._internal.exceptions import RequirementsFileParseError +from pip._internal.req.req_install import InstallRequirement + +__all__ = ['parse_requirements'] + +SCHEME_RE = re.compile(r'^(http|https|file):', re.I) +COMMENT_RE = re.compile(r'(^|\s)+#.*$') + +# Matches environment variable-style values in '${MY_VARIABLE_1}' with the +# variable name consisting of only uppercase letters, digits or the '_' +# (underscore). This follows the POSIX standard defined in IEEE Std 1003.1, +# 2013 Edition. +ENV_VAR_RE = re.compile(r'(?P\$\{(?P[A-Z0-9_]+)\})') + +SUPPORTED_OPTIONS = [ + cmdoptions.constraints, + cmdoptions.editable, + cmdoptions.requirements, + cmdoptions.no_index, + cmdoptions.index_url, + cmdoptions.find_links, + cmdoptions.extra_index_url, + cmdoptions.always_unzip, + cmdoptions.no_binary, + cmdoptions.only_binary, + cmdoptions.pre, + cmdoptions.process_dependency_links, + cmdoptions.trusted_host, + cmdoptions.require_hashes, +] + +# options to be passed to requirements +SUPPORTED_OPTIONS_REQ = [ + cmdoptions.install_options, + cmdoptions.global_options, + cmdoptions.hash, +] + +# the 'dest' string values +SUPPORTED_OPTIONS_REQ_DEST = [o().dest for o in SUPPORTED_OPTIONS_REQ] + + +def parse_requirements(filename, finder=None, comes_from=None, options=None, + session=None, constraint=False, wheel_cache=None): + """Parse a requirements file and yield InstallRequirement instances. + + :param filename: Path or url of requirements file. + :param finder: Instance of pip.index.PackageFinder. + :param comes_from: Origin description of requirements. + :param options: cli options. + :param session: Instance of pip.download.PipSession. + :param constraint: If true, parsing a constraint file rather than + requirements file. + :param wheel_cache: Instance of pip.wheel.WheelCache + """ + if session is None: + raise TypeError( + "parse_requirements() missing 1 required keyword argument: " + "'session'" + ) + + _, content = get_file_content( + filename, comes_from=comes_from, session=session + ) + + lines_enum = preprocess(content, options) + + for line_number, line in lines_enum: + req_iter = process_line(line, filename, line_number, finder, + comes_from, options, session, wheel_cache, + constraint=constraint) + for req in req_iter: + yield req + + +def preprocess(content, options): + """Split, filter, and join lines, and return a line iterator + + :param content: the content of the requirements file + :param options: cli options + """ + lines_enum = enumerate(content.splitlines(), start=1) + lines_enum = join_lines(lines_enum) + lines_enum = ignore_comments(lines_enum) + lines_enum = skip_regex(lines_enum, options) + lines_enum = expand_env_variables(lines_enum) + return lines_enum + + +def process_line(line, filename, line_number, finder=None, comes_from=None, + options=None, session=None, wheel_cache=None, + constraint=False): + """Process a single requirements line; This can result in creating/yielding + requirements, or updating the finder. + + For lines that contain requirements, the only options that have an effect + are from SUPPORTED_OPTIONS_REQ, and they are scoped to the + requirement. Other options from SUPPORTED_OPTIONS may be present, but are + ignored. + + For lines that do not contain requirements, the only options that have an + effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may + be present, but are ignored. These lines may contain multiple options + (although our docs imply only one is supported), and all our parsed and + affect the finder. + + :param constraint: If True, parsing a constraints file. + :param options: OptionParser options that we may update + """ + parser = build_parser(line) + defaults = parser.get_default_values() + defaults.index_url = None + if finder: + # `finder.format_control` will be updated during parsing + defaults.format_control = finder.format_control + args_str, options_str = break_args_options(line) + if sys.version_info < (2, 7, 3): + # Prior to 2.7.3, shlex cannot deal with unicode entries + options_str = options_str.encode('utf8') + opts, _ = parser.parse_args(shlex.split(options_str), defaults) + + # preserve for the nested code path + line_comes_from = '%s %s (line %s)' % ( + '-c' if constraint else '-r', filename, line_number, + ) + + # yield a line requirement + if args_str: + isolated = options.isolated_mode if options else False + if options: + cmdoptions.check_install_build_global(options, opts) + # get the options that apply to requirements + req_options = {} + for dest in SUPPORTED_OPTIONS_REQ_DEST: + if dest in opts.__dict__ and opts.__dict__[dest]: + req_options[dest] = opts.__dict__[dest] + yield InstallRequirement.from_line( + args_str, line_comes_from, constraint=constraint, + isolated=isolated, options=req_options, wheel_cache=wheel_cache + ) + + # yield an editable requirement + elif opts.editables: + isolated = options.isolated_mode if options else False + yield InstallRequirement.from_editable( + opts.editables[0], comes_from=line_comes_from, + constraint=constraint, isolated=isolated, wheel_cache=wheel_cache + ) + + # parse a nested requirements file + elif opts.requirements or opts.constraints: + if opts.requirements: + req_path = opts.requirements[0] + nested_constraint = False + else: + req_path = opts.constraints[0] + nested_constraint = True + # original file is over http + if SCHEME_RE.search(filename): + # do a url join so relative paths work + req_path = urllib_parse.urljoin(filename, req_path) + # original file and nested file are paths + elif not SCHEME_RE.search(req_path): + # do a join so relative paths work + req_path = os.path.join(os.path.dirname(filename), req_path) + # TODO: Why not use `comes_from='-r {} (line {})'` here as well? + parser = parse_requirements( + req_path, finder, comes_from, options, session, + constraint=nested_constraint, wheel_cache=wheel_cache + ) + for req in parser: + yield req + + # percolate hash-checking option upward + elif opts.require_hashes: + options.require_hashes = opts.require_hashes + + # set finder options + elif finder: + if opts.index_url: + finder.index_urls = [opts.index_url] + if opts.no_index is True: + finder.index_urls = [] + if opts.extra_index_urls: + finder.index_urls.extend(opts.extra_index_urls) + if opts.find_links: + # FIXME: it would be nice to keep track of the source + # of the find_links: support a find-links local path + # relative to a requirements file. + value = opts.find_links[0] + req_dir = os.path.dirname(os.path.abspath(filename)) + relative_to_reqs_file = os.path.join(req_dir, value) + if os.path.exists(relative_to_reqs_file): + value = relative_to_reqs_file + finder.find_links.append(value) + if opts.pre: + finder.allow_all_prereleases = True + if opts.process_dependency_links: + finder.process_dependency_links = True + if opts.trusted_hosts: + finder.secure_origins.extend( + ("*", host, "*") for host in opts.trusted_hosts) + + +def break_args_options(line): + """Break up the line into an args and options string. We only want to shlex + (and then optparse) the options, not the args. args can contain markers + which are corrupted by shlex. + """ + tokens = line.split(' ') + args = [] + options = tokens[:] + for token in tokens: + if token.startswith('-') or token.startswith('--'): + break + else: + args.append(token) + options.pop(0) + return ' '.join(args), ' '.join(options) + + +def build_parser(line): + """ + Return a parser for parsing requirement lines + """ + parser = optparse.OptionParser(add_help_option=False) + + option_factories = SUPPORTED_OPTIONS + SUPPORTED_OPTIONS_REQ + for option_factory in option_factories: + option = option_factory() + parser.add_option(option) + + # By default optparse sys.exits on parsing errors. We want to wrap + # that in our own exception. + def parser_exit(self, msg): + # add offending line + msg = 'Invalid requirement: %s\n%s' % (line, msg) + raise RequirementsFileParseError(msg) + parser.exit = parser_exit + + return parser + + +def join_lines(lines_enum): + """Joins a line ending in '\' with the previous line (except when following + comments). The joined line takes on the index of the first line. + """ + primary_line_number = None + new_line = [] + for line_number, line in lines_enum: + if not line.endswith('\\') or COMMENT_RE.match(line): + if COMMENT_RE.match(line): + # this ensures comments are always matched later + line = ' ' + line + if new_line: + new_line.append(line) + yield primary_line_number, ''.join(new_line) + new_line = [] + else: + yield line_number, line + else: + if not new_line: + primary_line_number = line_number + new_line.append(line.strip('\\')) + + # last line contains \ + if new_line: + yield primary_line_number, ''.join(new_line) + + # TODO: handle space after '\'. + + +def ignore_comments(lines_enum): + """ + Strips comments and filter empty lines. + """ + for line_number, line in lines_enum: + line = COMMENT_RE.sub('', line) + line = line.strip() + if line: + yield line_number, line + + +def skip_regex(lines_enum, options): + """ + Skip lines that match '--skip-requirements-regex' pattern + + Note: the regex pattern is only built once + """ + skip_regex = options.skip_requirements_regex if options else None + if skip_regex: + pattern = re.compile(skip_regex) + lines_enum = filterfalse(lambda e: pattern.search(e[1]), lines_enum) + return lines_enum + + +def expand_env_variables(lines_enum): + """Replace all environment variables that can be retrieved via `os.getenv`. + + The only allowed format for environment variables defined in the + requirement file is `${MY_VARIABLE_1}` to ensure two things: + + 1. Strings that contain a `$` aren't accidentally (partially) expanded. + 2. Ensure consistency across platforms for requirement files. + + These points are the result of a discusssion on the `github pull + request #3514 `_. + + Valid characters in variable names follow the `POSIX standard + `_ and are limited + to uppercase letter, digits and the `_` (underscore). + """ + for line_number, line in lines_enum: + for env_var, var_name in ENV_VAR_RE.findall(line): + value = os.getenv(var_name) + if not value: + continue + + line = line.replace(env_var, value) + + yield line_number, line diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_install.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_install.py new file mode 100644 index 0000000..ddd167c --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_install.py @@ -0,0 +1,1115 @@ +from __future__ import absolute_import + +import logging +import os +import re +import shutil +import sys +import sysconfig +import traceback +import warnings +import zipfile +from distutils.util import change_root +from email.parser import FeedParser # type: ignore + +from pip._vendor import pkg_resources, pytoml, six +from pip._vendor.packaging import specifiers +from pip._vendor.packaging.markers import Marker +from pip._vendor.packaging.requirements import InvalidRequirement, Requirement +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.packaging.version import parse as parse_version +from pip._vendor.packaging.version import Version +from pip._vendor.pkg_resources import RequirementParseError, parse_requirements + +from pip._internal import wheel +from pip._internal.build_env import BuildEnvironment +from pip._internal.compat import native_str +from pip._internal.download import ( + is_archive_file, is_url, path_to_url, url_to_path, +) +from pip._internal.exceptions import InstallationError, UninstallationError +from pip._internal.locations import ( + PIP_DELETE_MARKER_FILENAME, running_under_virtualenv, +) +from pip._internal.req.req_uninstall import UninstallPathSet +from pip._internal.utils.deprecation import RemovedInPip11Warning +from pip._internal.utils.hashes import Hashes +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + _make_build_dir, ask_path_exists, backup_dir, call_subprocess, + display_path, dist_in_site_packages, dist_in_usersite, ensure_dir, + get_installed_version, is_installable_dir, read_text_file, rmtree, +) +from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.ui import open_spinner +from pip._internal.vcs import vcs +from pip._internal.wheel import Wheel, move_wheel_files + +logger = logging.getLogger(__name__) + +operators = specifiers.Specifier._operators.keys() + + +def _strip_extras(path): + m = re.match(r'^(.+)(\[[^\]]+\])$', path) + extras = None + if m: + path_no_extras = m.group(1) + extras = m.group(2) + else: + path_no_extras = path + + return path_no_extras, extras + + +class InstallRequirement(object): + """ + Represents something that may be installed later on, may have information + about where to fetch the relavant requirement and also contains logic for + installing the said requirement. + """ + + def __init__(self, req, comes_from, source_dir=None, editable=False, + link=None, update=True, markers=None, + isolated=False, options=None, wheel_cache=None, + constraint=False, extras=()): + assert req is None or isinstance(req, Requirement), req + self.req = req + self.comes_from = comes_from + self.constraint = constraint + if source_dir is not None: + self.source_dir = os.path.normpath(os.path.abspath(source_dir)) + else: + self.source_dir = None + self.editable = editable + + self._wheel_cache = wheel_cache + if link is not None: + self.link = self.original_link = link + else: + from pip._internal.index import Link + self.link = self.original_link = req and req.url and Link(req.url) + + if extras: + self.extras = extras + elif req: + self.extras = { + pkg_resources.safe_extra(extra) for extra in req.extras + } + else: + self.extras = set() + if markers is not None: + self.markers = markers + else: + self.markers = req and req.marker + self._egg_info_path = None + # This holds the pkg_resources.Distribution object if this requirement + # is already available: + self.satisfied_by = None + # This hold the pkg_resources.Distribution object if this requirement + # conflicts with another installed distribution: + self.conflicts_with = None + # Temporary build location + self._temp_build_dir = TempDirectory(kind="req-build") + # Used to store the global directory where the _temp_build_dir should + # have been created. Cf _correct_build_location method. + self._ideal_build_dir = None + # True if the editable should be updated: + self.update = update + # Set to True after successful installation + self.install_succeeded = None + # UninstallPathSet of uninstalled distribution (for possible rollback) + self.uninstalled_pathset = None + self.options = options if options else {} + # Set to True after successful preparation of this requirement + self.prepared = False + self.is_direct = False + + self.isolated = isolated + self.build_env = BuildEnvironment(no_clean=True) + + @classmethod + def from_editable(cls, editable_req, comes_from=None, isolated=False, + options=None, wheel_cache=None, constraint=False): + from pip._internal.index import Link + + name, url, extras_override = parse_editable(editable_req) + if url.startswith('file:'): + source_dir = url_to_path(url) + else: + source_dir = None + + if name is not None: + try: + req = Requirement(name) + except InvalidRequirement: + raise InstallationError("Invalid requirement: '%s'" % name) + else: + req = None + return cls( + req, comes_from, source_dir=source_dir, + editable=True, + link=Link(url), + constraint=constraint, + isolated=isolated, + options=options if options else {}, + wheel_cache=wheel_cache, + extras=extras_override or (), + ) + + @classmethod + def from_req(cls, req, comes_from=None, isolated=False, wheel_cache=None): + try: + req = Requirement(req) + except InvalidRequirement: + raise InstallationError("Invalid requirement: '%s'" % req) + if req.url: + raise InstallationError( + "Direct url requirement (like %s) are not allowed for " + "dependencies" % req + ) + return cls(req, comes_from, isolated=isolated, wheel_cache=wheel_cache) + + @classmethod + def from_line( + cls, name, comes_from=None, isolated=False, options=None, + wheel_cache=None, constraint=False): + """Creates an InstallRequirement from a name, which might be a + requirement, directory containing 'setup.py', filename, or URL. + """ + from pip._internal.index import Link + + if is_url(name): + marker_sep = '; ' + else: + marker_sep = ';' + if marker_sep in name: + name, markers = name.split(marker_sep, 1) + markers = markers.strip() + if not markers: + markers = None + else: + markers = Marker(markers) + else: + markers = None + name = name.strip() + req = None + path = os.path.normpath(os.path.abspath(name)) + link = None + extras = None + + if is_url(name): + link = Link(name) + else: + p, extras = _strip_extras(path) + looks_like_dir = os.path.isdir(p) and ( + os.path.sep in name or + (os.path.altsep is not None and os.path.altsep in name) or + name.startswith('.') + ) + if looks_like_dir: + if not is_installable_dir(p): + raise InstallationError( + "Directory %r is not installable. File 'setup.py' " + "not found." % name + ) + link = Link(path_to_url(p)) + elif is_archive_file(p): + if not os.path.isfile(p): + logger.warning( + 'Requirement %r looks like a filename, but the ' + 'file does not exist', + name + ) + link = Link(path_to_url(p)) + + # it's a local file, dir, or url + if link: + # Handle relative file URLs + if link.scheme == 'file' and re.search(r'\.\./', link.url): + link = Link( + path_to_url(os.path.normpath(os.path.abspath(link.path)))) + # wheel file + if link.is_wheel: + wheel = Wheel(link.filename) # can raise InvalidWheelFilename + req = "%s==%s" % (wheel.name, wheel.version) + else: + # set the req to the egg fragment. when it's not there, this + # will become an 'unnamed' requirement + req = link.egg_fragment + + # a requirement specifier + else: + req = name + + if extras: + extras = Requirement("placeholder" + extras.lower()).extras + else: + extras = () + if req is not None: + try: + req = Requirement(req) + except InvalidRequirement: + if os.path.sep in req: + add_msg = "It looks like a path." + add_msg += deduce_helpful_msg(req) + elif '=' in req and not any(op in req for op in operators): + add_msg = "= is not a valid operator. Did you mean == ?" + else: + add_msg = traceback.format_exc() + raise InstallationError( + "Invalid requirement: '%s'\n%s" % (req, add_msg)) + return cls( + req, comes_from, link=link, markers=markers, + isolated=isolated, + options=options if options else {}, + wheel_cache=wheel_cache, + constraint=constraint, + extras=extras, + ) + + def __str__(self): + if self.req: + s = str(self.req) + if self.link: + s += ' from %s' % self.link.url + else: + s = self.link.url if self.link else None + if self.satisfied_by is not None: + s += ' in %s' % display_path(self.satisfied_by.location) + if self.comes_from: + if isinstance(self.comes_from, six.string_types): + comes_from = self.comes_from + else: + comes_from = self.comes_from.from_path() + if comes_from: + s += ' (from %s)' % comes_from + return s + + def __repr__(self): + return '<%s object: %s editable=%r>' % ( + self.__class__.__name__, str(self), self.editable) + + def populate_link(self, finder, upgrade, require_hashes): + """Ensure that if a link can be found for this, that it is found. + + Note that self.link may still be None - if Upgrade is False and the + requirement is already installed. + + If require_hashes is True, don't use the wheel cache, because cached + wheels, always built locally, have different hashes than the files + downloaded from the index server and thus throw false hash mismatches. + Furthermore, cached wheels at present have undeterministic contents due + to file modification times. + """ + if self.link is None: + self.link = finder.find_requirement(self, upgrade) + if self._wheel_cache is not None and not require_hashes: + old_link = self.link + self.link = self._wheel_cache.get(self.link, self.name) + if old_link != self.link: + logger.debug('Using cached wheel link: %s', self.link) + + @property + def specifier(self): + return self.req.specifier + + @property + def is_pinned(self): + """Return whether I am pinned to an exact version. + + For example, some-package==1.2 is pinned; some-package>1.2 is not. + """ + specifiers = self.specifier + return (len(specifiers) == 1 and + next(iter(specifiers)).operator in {'==', '==='}) + + def from_path(self): + if self.req is None: + return None + s = str(self.req) + if self.comes_from: + if isinstance(self.comes_from, six.string_types): + comes_from = self.comes_from + else: + comes_from = self.comes_from.from_path() + if comes_from: + s += '->' + comes_from + return s + + def build_location(self, build_dir): + assert build_dir is not None + if self._temp_build_dir.path is not None: + return self._temp_build_dir.path + if self.req is None: + # for requirement via a path to a directory: the name of the + # package is not available yet so we create a temp directory + # Once run_egg_info will have run, we'll be able + # to fix it via _correct_build_location + # Some systems have /tmp as a symlink which confuses custom + # builds (such as numpy). Thus, we ensure that the real path + # is returned. + self._temp_build_dir.create() + self._ideal_build_dir = build_dir + + return self._temp_build_dir.path + if self.editable: + name = self.name.lower() + else: + name = self.name + # FIXME: Is there a better place to create the build_dir? (hg and bzr + # need this) + if not os.path.exists(build_dir): + logger.debug('Creating directory %s', build_dir) + _make_build_dir(build_dir) + return os.path.join(build_dir, name) + + def _correct_build_location(self): + """Move self._temp_build_dir to self._ideal_build_dir/self.req.name + + For some requirements (e.g. a path to a directory), the name of the + package is not available until we run egg_info, so the build_location + will return a temporary directory and store the _ideal_build_dir. + + This is only called by self.egg_info_path to fix the temporary build + directory. + """ + if self.source_dir is not None: + return + assert self.req is not None + assert self._temp_build_dir.path + assert self._ideal_build_dir.path + old_location = self._temp_build_dir.path + self._temp_build_dir.path = None + + new_location = self.build_location(self._ideal_build_dir) + if os.path.exists(new_location): + raise InstallationError( + 'A package already exists in %s; please remove it to continue' + % display_path(new_location)) + logger.debug( + 'Moving package %s from %s to new location %s', + self, display_path(old_location), display_path(new_location), + ) + shutil.move(old_location, new_location) + self._temp_build_dir.path = new_location + self._ideal_build_dir = None + self.source_dir = os.path.normpath(os.path.abspath(new_location)) + self._egg_info_path = None + + @property + def name(self): + if self.req is None: + return None + return native_str(pkg_resources.safe_name(self.req.name)) + + @property + def setup_py_dir(self): + return os.path.join( + self.source_dir, + self.link and self.link.subdirectory_fragment or '') + + @property + def setup_py(self): + assert self.source_dir, "No source dir for %s" % self + + setup_py = os.path.join(self.setup_py_dir, 'setup.py') + + # Python2 __file__ should not be unicode + if six.PY2 and isinstance(setup_py, six.text_type): + setup_py = setup_py.encode(sys.getfilesystemencoding()) + + return setup_py + + @property + def pyproject_toml(self): + assert self.source_dir, "No source dir for %s" % self + + pp_toml = os.path.join(self.setup_py_dir, 'pyproject.toml') + + # Python2 __file__ should not be unicode + if six.PY2 and isinstance(pp_toml, six.text_type): + pp_toml = pp_toml.encode(sys.getfilesystemencoding()) + + return pp_toml + + def get_pep_518_info(self): + """Get a list of the packages required to build the project, if any, + and a flag indicating whether pyproject.toml is present, indicating + that the build should be isolated. + + Build requirements can be specified in a pyproject.toml, as described + in PEP 518. If this file exists but doesn't specify build + requirements, pip will default to installing setuptools and wheel. + """ + if os.path.isfile(self.pyproject_toml): + with open(self.pyproject_toml) as f: + pp_toml = pytoml.load(f) + build_sys = pp_toml.get('build-system', {}) + return (build_sys.get('requires', ['setuptools', 'wheel']), True) + return (['setuptools', 'wheel'], False) + + def run_egg_info(self): + assert self.source_dir + if self.name: + logger.debug( + 'Running setup.py (path:%s) egg_info for package %s', + self.setup_py, self.name, + ) + else: + logger.debug( + 'Running setup.py (path:%s) egg_info for package from %s', + self.setup_py, self.link, + ) + + with indent_log(): + script = SETUPTOOLS_SHIM % self.setup_py + base_cmd = [sys.executable, '-c', script] + if self.isolated: + base_cmd += ["--no-user-cfg"] + egg_info_cmd = base_cmd + ['egg_info'] + # We can't put the .egg-info files at the root, because then the + # source code will be mistaken for an installed egg, causing + # problems + if self.editable: + egg_base_option = [] + else: + egg_info_dir = os.path.join(self.setup_py_dir, 'pip-egg-info') + ensure_dir(egg_info_dir) + egg_base_option = ['--egg-base', 'pip-egg-info'] + with self.build_env: + call_subprocess( + egg_info_cmd + egg_base_option, + cwd=self.setup_py_dir, + show_stdout=False, + command_desc='python setup.py egg_info') + + if not self.req: + if isinstance(parse_version(self.pkg_info()["Version"]), Version): + op = "==" + else: + op = "===" + self.req = Requirement( + "".join([ + self.pkg_info()["Name"], + op, + self.pkg_info()["Version"], + ]) + ) + self._correct_build_location() + else: + metadata_name = canonicalize_name(self.pkg_info()["Name"]) + if canonicalize_name(self.req.name) != metadata_name: + logger.warning( + 'Running setup.py (path:%s) egg_info for package %s ' + 'produced metadata for project name %s. Fix your ' + '#egg=%s fragments.', + self.setup_py, self.name, metadata_name, self.name + ) + self.req = Requirement(metadata_name) + + def egg_info_data(self, filename): + if self.satisfied_by is not None: + if not self.satisfied_by.has_metadata(filename): + return None + return self.satisfied_by.get_metadata(filename) + assert self.source_dir + filename = self.egg_info_path(filename) + if not os.path.exists(filename): + return None + data = read_text_file(filename) + return data + + def egg_info_path(self, filename): + if self._egg_info_path is None: + if self.editable: + base = self.source_dir + else: + base = os.path.join(self.setup_py_dir, 'pip-egg-info') + filenames = os.listdir(base) + if self.editable: + filenames = [] + for root, dirs, files in os.walk(base): + for dir in vcs.dirnames: + if dir in dirs: + dirs.remove(dir) + # Iterate over a copy of ``dirs``, since mutating + # a list while iterating over it can cause trouble. + # (See https://github.com/pypa/pip/pull/462.) + for dir in list(dirs): + # Don't search in anything that looks like a virtualenv + # environment + if ( + os.path.lexists( + os.path.join(root, dir, 'bin', 'python') + ) or + os.path.exists( + os.path.join( + root, dir, 'Scripts', 'Python.exe' + ) + )): + dirs.remove(dir) + # Also don't search through tests + elif dir == 'test' or dir == 'tests': + dirs.remove(dir) + filenames.extend([os.path.join(root, dir) + for dir in dirs]) + filenames = [f for f in filenames if f.endswith('.egg-info')] + + if not filenames: + raise InstallationError( + 'No files/directories in %s (from %s)' % (base, filename) + ) + assert filenames, \ + "No files/directories in %s (from %s)" % (base, filename) + + # if we have more than one match, we pick the toplevel one. This + # can easily be the case if there is a dist folder which contains + # an extracted tarball for testing purposes. + if len(filenames) > 1: + filenames.sort( + key=lambda x: x.count(os.path.sep) + + (os.path.altsep and x.count(os.path.altsep) or 0) + ) + self._egg_info_path = os.path.join(base, filenames[0]) + return os.path.join(self._egg_info_path, filename) + + def pkg_info(self): + p = FeedParser() + data = self.egg_info_data('PKG-INFO') + if not data: + logger.warning( + 'No PKG-INFO file found in %s', + display_path(self.egg_info_path('PKG-INFO')), + ) + p.feed(data or '') + return p.close() + + _requirements_section_re = re.compile(r'\[(.*?)\]') + + @property + def installed_version(self): + return get_installed_version(self.name) + + def assert_source_matches_version(self): + assert self.source_dir + version = self.pkg_info()['version'] + if self.req.specifier and version not in self.req.specifier: + logger.warning( + 'Requested %s, but installing version %s', + self, + version, + ) + else: + logger.debug( + 'Source in %s has version %s, which satisfies requirement %s', + display_path(self.source_dir), + version, + self, + ) + + def update_editable(self, obtain=True): + if not self.link: + logger.debug( + "Cannot update repository at %s; repository location is " + "unknown", + self.source_dir, + ) + return + assert self.editable + assert self.source_dir + if self.link.scheme == 'file': + # Static paths don't get updated + return + assert '+' in self.link.url, "bad url: %r" % self.link.url + if not self.update: + return + vc_type, url = self.link.url.split('+', 1) + backend = vcs.get_backend(vc_type) + if backend: + vcs_backend = backend(self.link.url) + if obtain: + vcs_backend.obtain(self.source_dir) + else: + vcs_backend.export(self.source_dir) + else: + assert 0, ( + 'Unexpected version control type (in %s): %s' + % (self.link, vc_type)) + + def uninstall(self, auto_confirm=False, verbose=False, + use_user_site=False): + """ + Uninstall the distribution currently satisfying this requirement. + + Prompts before removing or modifying files unless + ``auto_confirm`` is True. + + Refuses to delete or modify files outside of ``sys.prefix`` - + thus uninstallation within a virtual environment can only + modify that virtual environment, even if the virtualenv is + linked to global site-packages. + + """ + if not self.check_if_exists(use_user_site): + logger.warning("Skipping %s as it is not installed.", self.name) + return + dist = self.satisfied_by or self.conflicts_with + + uninstalled_pathset = UninstallPathSet.from_dist(dist) + uninstalled_pathset.remove(auto_confirm, verbose) + return uninstalled_pathset + + def archive(self, build_dir): + assert self.source_dir + create_archive = True + archive_name = '%s-%s.zip' % (self.name, self.pkg_info()["version"]) + archive_path = os.path.join(build_dir, archive_name) + if os.path.exists(archive_path): + response = ask_path_exists( + 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)bort ' % + display_path(archive_path), ('i', 'w', 'b', 'a')) + if response == 'i': + create_archive = False + elif response == 'w': + logger.warning('Deleting %s', display_path(archive_path)) + os.remove(archive_path) + elif response == 'b': + dest_file = backup_dir(archive_path) + logger.warning( + 'Backing up %s to %s', + display_path(archive_path), + display_path(dest_file), + ) + shutil.move(archive_path, dest_file) + elif response == 'a': + sys.exit(-1) + if create_archive: + zip = zipfile.ZipFile( + archive_path, 'w', zipfile.ZIP_DEFLATED, + allowZip64=True + ) + dir = os.path.normcase(os.path.abspath(self.setup_py_dir)) + for dirpath, dirnames, filenames in os.walk(dir): + if 'pip-egg-info' in dirnames: + dirnames.remove('pip-egg-info') + for dirname in dirnames: + dirname = os.path.join(dirpath, dirname) + name = self._clean_zip_name(dirname, dir) + zipdir = zipfile.ZipInfo(self.name + '/' + name + '/') + zipdir.external_attr = 0x1ED << 16 # 0o755 + zip.writestr(zipdir, '') + for filename in filenames: + if filename == PIP_DELETE_MARKER_FILENAME: + continue + filename = os.path.join(dirpath, filename) + name = self._clean_zip_name(filename, dir) + zip.write(filename, self.name + '/' + name) + zip.close() + logger.info('Saved %s', display_path(archive_path)) + + def _clean_zip_name(self, name, prefix): + assert name.startswith(prefix + os.path.sep), ( + "name %r doesn't start with prefix %r" % (name, prefix) + ) + name = name[len(prefix) + 1:] + name = name.replace(os.path.sep, '/') + return name + + def match_markers(self, extras_requested=None): + if not extras_requested: + # Provide an extra to safely evaluate the markers + # without matching any extra + extras_requested = ('',) + if self.markers is not None: + return any( + self.markers.evaluate({'extra': extra}) + for extra in extras_requested) + else: + return True + + def install(self, install_options, global_options=None, root=None, + home=None, prefix=None, warn_script_location=True, + use_user_site=False, pycompile=True): + global_options = global_options if global_options is not None else [] + if self.editable: + self.install_editable( + install_options, global_options, prefix=prefix, + ) + return + if self.is_wheel: + version = wheel.wheel_version(self.source_dir) + wheel.check_compatibility(version, self.name) + + self.move_wheel_files( + self.source_dir, root=root, prefix=prefix, home=home, + warn_script_location=warn_script_location, + use_user_site=use_user_site, pycompile=pycompile, + ) + self.install_succeeded = True + return + + # Extend the list of global and install options passed on to + # the setup.py call with the ones from the requirements file. + # Options specified in requirements file override those + # specified on the command line, since the last option given + # to setup.py is the one that is used. + global_options = list(global_options) + \ + self.options.get('global_options', []) + install_options = list(install_options) + \ + self.options.get('install_options', []) + + if self.isolated: + global_options = global_options + ["--no-user-cfg"] + + with TempDirectory(kind="record") as temp_dir: + record_filename = os.path.join(temp_dir.path, 'install-record.txt') + install_args = self.get_install_args( + global_options, record_filename, root, prefix, pycompile, + ) + msg = 'Running setup.py install for %s' % (self.name,) + with open_spinner(msg) as spinner: + with indent_log(): + with self.build_env: + call_subprocess( + install_args + install_options, + cwd=self.setup_py_dir, + show_stdout=False, + spinner=spinner, + ) + + if not os.path.exists(record_filename): + logger.debug('Record file %s not found', record_filename) + return + self.install_succeeded = True + + def prepend_root(path): + if root is None or not os.path.isabs(path): + return path + else: + return change_root(root, path) + + with open(record_filename) as f: + for line in f: + directory = os.path.dirname(line) + if directory.endswith('.egg-info'): + egg_info_dir = prepend_root(directory) + break + else: + logger.warning( + 'Could not find .egg-info directory in install record' + ' for %s', + self, + ) + # FIXME: put the record somewhere + # FIXME: should this be an error? + return + new_lines = [] + with open(record_filename) as f: + for line in f: + filename = line.strip() + if os.path.isdir(filename): + filename += os.path.sep + new_lines.append( + os.path.relpath(prepend_root(filename), egg_info_dir) + ) + new_lines.sort() + ensure_dir(egg_info_dir) + inst_files_path = os.path.join(egg_info_dir, 'installed-files.txt') + with open(inst_files_path, 'w') as f: + f.write('\n'.join(new_lines) + '\n') + + def ensure_has_source_dir(self, parent_dir): + """Ensure that a source_dir is set. + + This will create a temporary build dir if the name of the requirement + isn't known yet. + + :param parent_dir: The ideal pip parent_dir for the source_dir. + Generally src_dir for editables and build_dir for sdists. + :return: self.source_dir + """ + if self.source_dir is None: + self.source_dir = self.build_location(parent_dir) + return self.source_dir + + def get_install_args(self, global_options, record_filename, root, prefix, + pycompile): + install_args = [sys.executable, "-u"] + install_args.append('-c') + install_args.append(SETUPTOOLS_SHIM % self.setup_py) + install_args += list(global_options) + \ + ['install', '--record', record_filename] + install_args += ['--single-version-externally-managed'] + + if root is not None: + install_args += ['--root', root] + if prefix is not None: + install_args += ['--prefix', prefix] + + if pycompile: + install_args += ["--compile"] + else: + install_args += ["--no-compile"] + + if running_under_virtualenv(): + py_ver_str = 'python' + sysconfig.get_python_version() + install_args += ['--install-headers', + os.path.join(sys.prefix, 'include', 'site', + py_ver_str, self.name)] + + return install_args + + def remove_temporary_source(self): + """Remove the source files from this requirement, if they are marked + for deletion""" + if self.source_dir and os.path.exists( + os.path.join(self.source_dir, PIP_DELETE_MARKER_FILENAME)): + logger.debug('Removing source in %s', self.source_dir) + rmtree(self.source_dir) + self.source_dir = None + self._temp_build_dir.cleanup() + self.build_env.cleanup() + + def install_editable(self, install_options, + global_options=(), prefix=None): + logger.info('Running setup.py develop for %s', self.name) + + if self.isolated: + global_options = list(global_options) + ["--no-user-cfg"] + + if prefix: + prefix_param = ['--prefix={}'.format(prefix)] + install_options = list(install_options) + prefix_param + + with indent_log(): + # FIXME: should we do --install-headers here too? + with self.build_env: + call_subprocess( + [ + sys.executable, + '-c', + SETUPTOOLS_SHIM % self.setup_py + ] + + list(global_options) + + ['develop', '--no-deps'] + + list(install_options), + + cwd=self.setup_py_dir, + show_stdout=False, + ) + + self.install_succeeded = True + + def check_if_exists(self, use_user_site): + """Find an installed distribution that satisfies or conflicts + with this requirement, and set self.satisfied_by or + self.conflicts_with appropriately. + """ + if self.req is None: + return False + try: + # get_distribution() will resolve the entire list of requirements + # anyway, and we've already determined that we need the requirement + # in question, so strip the marker so that we don't try to + # evaluate it. + no_marker = Requirement(str(self.req)) + no_marker.marker = None + self.satisfied_by = pkg_resources.get_distribution(str(no_marker)) + if self.editable and self.satisfied_by: + self.conflicts_with = self.satisfied_by + # when installing editables, nothing pre-existing should ever + # satisfy + self.satisfied_by = None + return True + except pkg_resources.DistributionNotFound: + return False + except pkg_resources.VersionConflict: + existing_dist = pkg_resources.get_distribution( + self.req.name + ) + if use_user_site: + if dist_in_usersite(existing_dist): + self.conflicts_with = existing_dist + elif (running_under_virtualenv() and + dist_in_site_packages(existing_dist)): + raise InstallationError( + "Will not install to the user site because it will " + "lack sys.path precedence to %s in %s" % + (existing_dist.project_name, existing_dist.location) + ) + else: + self.conflicts_with = existing_dist + return True + + @property + def is_wheel(self): + return self.link and self.link.is_wheel + + def move_wheel_files(self, wheeldir, root=None, home=None, prefix=None, + warn_script_location=True, use_user_site=False, + pycompile=True): + move_wheel_files( + self.name, self.req, wheeldir, + user=use_user_site, + home=home, + root=root, + prefix=prefix, + pycompile=pycompile, + isolated=self.isolated, + warn_script_location=warn_script_location, + ) + + def get_dist(self): + """Return a pkg_resources.Distribution built from self.egg_info_path""" + egg_info = self.egg_info_path('').rstrip(os.path.sep) + base_dir = os.path.dirname(egg_info) + metadata = pkg_resources.PathMetadata(base_dir, egg_info) + dist_name = os.path.splitext(os.path.basename(egg_info))[0] + return pkg_resources.Distribution( + os.path.dirname(egg_info), + project_name=dist_name, + metadata=metadata, + ) + + @property + def has_hash_options(self): + """Return whether any known-good hashes are specified as options. + + These activate --require-hashes mode; hashes specified as part of a + URL do not. + + """ + return bool(self.options.get('hashes', {})) + + def hashes(self, trust_internet=True): + """Return a hash-comparer that considers my option- and URL-based + hashes to be known-good. + + Hashes in URLs--ones embedded in the requirements file, not ones + downloaded from an index server--are almost peers with ones from + flags. They satisfy --require-hashes (whether it was implicitly or + explicitly activated) but do not activate it. md5 and sha224 are not + allowed in flags, which should nudge people toward good algos. We + always OR all hashes together, even ones from URLs. + + :param trust_internet: Whether to trust URL-based (#md5=...) hashes + downloaded from the internet, as by populate_link() + + """ + good_hashes = self.options.get('hashes', {}).copy() + link = self.link if trust_internet else self.original_link + if link and link.hash: + good_hashes.setdefault(link.hash_name, []).append(link.hash) + return Hashes(good_hashes) + + +def _strip_postfix(req): + """ + Strip req postfix ( -dev, 0.2, etc ) + """ + # FIXME: use package_to_requirement? + match = re.search(r'^(.*?)(?:-dev|-\d.*)$', req) + if match: + # Strip off -dev, -0.2, etc. + warnings.warn( + "#egg cleanup for editable urls will be dropped in the future", + RemovedInPip11Warning, + ) + req = match.group(1) + return req + + +def parse_editable(editable_req): + """Parses an editable requirement into: + - a requirement name + - an URL + - extras + - editable options + Accepted requirements: + svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir + .[some_extra] + """ + + from pip._internal.index import Link + + url = editable_req + + # If a file path is specified with extras, strip off the extras. + url_no_extras, extras = _strip_extras(url) + + if os.path.isdir(url_no_extras): + if not os.path.exists(os.path.join(url_no_extras, 'setup.py')): + raise InstallationError( + "Directory %r is not installable. File 'setup.py' not found." % + url_no_extras + ) + # Treating it as code that has already been checked out + url_no_extras = path_to_url(url_no_extras) + + if url_no_extras.lower().startswith('file:'): + package_name = Link(url_no_extras).egg_fragment + if extras: + return ( + package_name, + url_no_extras, + Requirement("placeholder" + extras.lower()).extras, + ) + else: + return package_name, url_no_extras, None + + for version_control in vcs: + if url.lower().startswith('%s:' % version_control): + url = '%s+%s' % (version_control, url) + break + + if '+' not in url: + raise InstallationError( + '%s should either be a path to a local project or a VCS url ' + 'beginning with svn+, git+, hg+, or bzr+' % + editable_req + ) + + vc_type = url.split('+', 1)[0].lower() + + if not vcs.get_backend(vc_type): + error_message = 'For --editable=%s only ' % editable_req + \ + ', '.join([backend.name + '+URL' for backend in vcs.backends]) + \ + ' is currently supported' + raise InstallationError(error_message) + + package_name = Link(url).egg_fragment + if not package_name: + raise InstallationError( + "Could not detect requirement name for '%s', please specify one " + "with #egg=your_package_name" % editable_req + ) + return _strip_postfix(package_name), url, None + + +def deduce_helpful_msg(req): + """Returns helpful msg in case requirements file does not exist, + or cannot be parsed. + + :params req: Requirements file path + """ + msg = "" + if os.path.exists(req): + msg = " It does exist." + # Try to parse and check if it is a requirements file. + try: + with open(req, 'r') as fp: + # parse first line only + next(parse_requirements(fp.read())) + msg += " The argument you provided " + \ + "(%s) appears to be a" % (req) + \ + " requirements file. If that is the" + \ + " case, use the '-r' flag to install" + \ + " the packages specified within it." + except RequirementParseError: + logger.debug("Cannot parse '%s' as requirements \ + file" % (req), exc_info=1) + else: + msg += " File '%s' does not exist." % (req) + return msg diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_set.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_set.py new file mode 100644 index 0000000..b2b55f8 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_set.py @@ -0,0 +1,164 @@ +from __future__ import absolute_import + +import logging +from collections import OrderedDict + +from pip._internal.exceptions import InstallationError +from pip._internal.utils.logging import indent_log +from pip._internal.wheel import Wheel + +logger = logging.getLogger(__name__) + + +class RequirementSet(object): + + def __init__(self, require_hashes=False): + """Create a RequirementSet. + + :param wheel_cache: The pip wheel cache, for passing to + InstallRequirement. + """ + + self.requirements = OrderedDict() + self.require_hashes = require_hashes + + # Mapping of alias: real_name + self.requirement_aliases = {} + self.unnamed_requirements = [] + self.successfully_downloaded = [] + self.reqs_to_cleanup = [] + + def __str__(self): + reqs = [req for req in self.requirements.values() + if not req.comes_from] + reqs.sort(key=lambda req: req.name.lower()) + return ' '.join([str(req.req) for req in reqs]) + + def __repr__(self): + reqs = [req for req in self.requirements.values()] + reqs.sort(key=lambda req: req.name.lower()) + reqs_str = ', '.join([str(req.req) for req in reqs]) + return ('<%s object; %d requirement(s): %s>' + % (self.__class__.__name__, len(reqs), reqs_str)) + + def add_requirement(self, install_req, parent_req_name=None, + extras_requested=None): + """Add install_req as a requirement to install. + + :param parent_req_name: The name of the requirement that needed this + added. The name is used because when multiple unnamed requirements + resolve to the same name, we could otherwise end up with dependency + links that point outside the Requirements set. parent_req must + already be added. Note that None implies that this is a user + supplied requirement, vs an inferred one. + :param extras_requested: an iterable of extras used to evaluate the + environment markers. + :return: Additional requirements to scan. That is either [] if + the requirement is not applicable, or [install_req] if the + requirement is applicable and has just been added. + """ + name = install_req.name + if not install_req.match_markers(extras_requested): + logger.info("Ignoring %s: markers '%s' don't match your " + "environment", install_req.name, + install_req.markers) + return [], None + + # This check has to come after we filter requirements with the + # environment markers. + if install_req.link and install_req.link.is_wheel: + wheel = Wheel(install_req.link.filename) + if not wheel.supported(): + raise InstallationError( + "%s is not a supported wheel on this platform." % + wheel.filename + ) + + # This next bit is really a sanity check. + assert install_req.is_direct == (parent_req_name is None), ( + "a direct req shouldn't have a parent and also, " + "a non direct req should have a parent" + ) + + if not name: + # url or path requirement w/o an egg fragment + self.unnamed_requirements.append(install_req) + return [install_req], None + else: + try: + existing_req = self.get_requirement(name) + except KeyError: + existing_req = None + if (parent_req_name is None and existing_req and not + existing_req.constraint and + existing_req.extras == install_req.extras and not + existing_req.req.specifier == install_req.req.specifier): + raise InstallationError( + 'Double requirement given: %s (already in %s, name=%r)' + % (install_req, existing_req, name)) + if not existing_req: + # Add requirement + self.requirements[name] = install_req + # FIXME: what about other normalizations? E.g., _ vs. -? + if name.lower() != name: + self.requirement_aliases[name.lower()] = name + result = [install_req] + else: + # Assume there's no need to scan, and that we've already + # encountered this for scanning. + result = [] + if not install_req.constraint and existing_req.constraint: + if (install_req.link and not (existing_req.link and + install_req.link.path == existing_req.link.path)): + self.reqs_to_cleanup.append(install_req) + raise InstallationError( + "Could not satisfy constraints for '%s': " + "installation from path or url cannot be " + "constrained to a version" % name, + ) + # If we're now installing a constraint, mark the existing + # object for real installation. + existing_req.constraint = False + existing_req.extras = tuple( + sorted(set(existing_req.extras).union( + set(install_req.extras)))) + logger.debug("Setting %s extras to: %s", + existing_req, existing_req.extras) + # And now we need to scan this. + result = [existing_req] + # Canonicalise to the already-added object for the backref + # check below. + install_req = existing_req + + # We return install_req here to allow for the caller to add it to + # the dependency information for the parent package. + return result, install_req + + def has_requirement(self, project_name): + name = project_name.lower() + if (name in self.requirements and + not self.requirements[name].constraint or + name in self.requirement_aliases and + not self.requirements[self.requirement_aliases[name]].constraint): + return True + return False + + @property + def has_requirements(self): + return list(req for req in self.requirements.values() if not + req.constraint) or self.unnamed_requirements + + def get_requirement(self, project_name): + for name in project_name, project_name.lower(): + if name in self.requirements: + return self.requirements[name] + if name in self.requirement_aliases: + return self.requirements[self.requirement_aliases[name]] + raise KeyError("No project with the name %r" % project_name) + + def cleanup_files(self): + """Clean up files, remove builds.""" + logger.debug('Cleaning up...') + with indent_log(): + for req in self.reqs_to_cleanup: + req.remove_temporary_source() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_uninstall.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_uninstall.py new file mode 100644 index 0000000..a3cc7bf --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_uninstall.py @@ -0,0 +1,455 @@ +from __future__ import absolute_import + +import csv +import functools +import logging +import os +import sys +import sysconfig + +from pip._vendor import pkg_resources + +from pip._internal.compat import WINDOWS, cache_from_source, uses_pycache +from pip._internal.exceptions import UninstallationError +from pip._internal.locations import bin_py, bin_user +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + FakeFile, ask, dist_in_usersite, dist_is_local, egg_link_path, is_local, + normalize_path, renames, +) +from pip._internal.utils.temp_dir import TempDirectory + +logger = logging.getLogger(__name__) + + +def _script_names(dist, script_name, is_gui): + """Create the fully qualified name of the files created by + {console,gui}_scripts for the given ``dist``. + Returns the list of file names + """ + if dist_in_usersite(dist): + bin_dir = bin_user + else: + bin_dir = bin_py + exe_name = os.path.join(bin_dir, script_name) + paths_to_remove = [exe_name] + if WINDOWS: + paths_to_remove.append(exe_name + '.exe') + paths_to_remove.append(exe_name + '.exe.manifest') + if is_gui: + paths_to_remove.append(exe_name + '-script.pyw') + else: + paths_to_remove.append(exe_name + '-script.py') + return paths_to_remove + + +def _unique(fn): + @functools.wraps(fn) + def unique(*args, **kw): + seen = set() + for item in fn(*args, **kw): + if item not in seen: + seen.add(item) + yield item + return unique + + +@_unique +def uninstallation_paths(dist): + """ + Yield all the uninstallation paths for dist based on RECORD-without-.pyc + + Yield paths to all the files in RECORD. For each .py file in RECORD, add + the .pyc in the same directory. + + UninstallPathSet.add() takes care of the __pycache__ .pyc. + """ + r = csv.reader(FakeFile(dist.get_metadata_lines('RECORD'))) + for row in r: + path = os.path.join(dist.location, row[0]) + yield path + if path.endswith('.py'): + dn, fn = os.path.split(path) + base = fn[:-3] + path = os.path.join(dn, base + '.pyc') + yield path + + +def compact(paths): + """Compact a path set to contain the minimal number of paths + necessary to contain all paths in the set. If /a/path/ and + /a/path/to/a/file.txt are both in the set, leave only the + shorter path.""" + + sep = os.path.sep + short_paths = set() + for path in sorted(paths, key=len): + should_add = any( + path.startswith(shortpath.rstrip("*")) and + path[len(shortpath.rstrip("*").rstrip(sep))] == sep + for shortpath in short_paths + ) + if not should_add: + short_paths.add(path) + return short_paths + + +def compress_for_output_listing(paths): + """Returns a tuple of 2 sets of which paths to display to user + + The first set contains paths that would be deleted. Files of a package + are not added and the top-level directory of the package has a '*' added + at the end - to signify that all it's contents are removed. + + The second set contains files that would have been skipped in the above + folders. + """ + + will_remove = list(paths) + will_skip = set() + + # Determine folders and files + folders = set() + files = set() + for path in will_remove: + if path.endswith(".pyc"): + continue + if path.endswith("__init__.py") or ".dist-info" in path: + folders.add(os.path.dirname(path)) + files.add(path) + + folders = compact(folders) + + # This walks the tree using os.walk to not miss extra folders + # that might get added. + for folder in folders: + for dirpath, _, dirfiles in os.walk(folder): + for fname in dirfiles: + if fname.endswith(".pyc"): + continue + + file_ = os.path.normcase(os.path.join(dirpath, fname)) + if os.path.isfile(file_) and file_ not in files: + # We are skipping this file. Add it to the set. + will_skip.add(file_) + + will_remove = files | { + os.path.join(folder, "*") for folder in folders + } + + return will_remove, will_skip + + +class UninstallPathSet(object): + """A set of file paths to be removed in the uninstallation of a + requirement.""" + def __init__(self, dist): + self.paths = set() + self._refuse = set() + self.pth = {} + self.dist = dist + self.save_dir = TempDirectory(kind="uninstall") + self._moved_paths = [] + + def _permitted(self, path): + """ + Return True if the given path is one we are permitted to + remove/modify, False otherwise. + + """ + return is_local(path) + + def add(self, path): + head, tail = os.path.split(path) + + # we normalize the head to resolve parent directory symlinks, but not + # the tail, since we only want to uninstall symlinks, not their targets + path = os.path.join(normalize_path(head), os.path.normcase(tail)) + + if not os.path.exists(path): + return + if self._permitted(path): + self.paths.add(path) + else: + self._refuse.add(path) + + # __pycache__ files can show up after 'installed-files.txt' is created, + # due to imports + if os.path.splitext(path)[1] == '.py' and uses_pycache: + self.add(cache_from_source(path)) + + def add_pth(self, pth_file, entry): + pth_file = normalize_path(pth_file) + if self._permitted(pth_file): + if pth_file not in self.pth: + self.pth[pth_file] = UninstallPthEntries(pth_file) + self.pth[pth_file].add(entry) + else: + self._refuse.add(pth_file) + + def _stash(self, path): + return os.path.join( + self.save_dir.path, os.path.splitdrive(path)[1].lstrip(os.path.sep) + ) + + def remove(self, auto_confirm=False, verbose=False): + """Remove paths in ``self.paths`` with confirmation (unless + ``auto_confirm`` is True).""" + + if not self.paths: + logger.info( + "Can't uninstall '%s'. No files were found to uninstall.", + self.dist.project_name, + ) + return + + dist_name_version = ( + self.dist.project_name + "-" + self.dist.version + ) + logger.info('Uninstalling %s:', dist_name_version) + + with indent_log(): + if auto_confirm or self._allowed_to_proceed(verbose): + self.save_dir.create() + + for path in sorted(compact(self.paths)): + new_path = self._stash(path) + logger.debug('Removing file or directory %s', path) + self._moved_paths.append(path) + renames(path, new_path) + for pth in self.pth.values(): + pth.remove() + + logger.info('Successfully uninstalled %s', dist_name_version) + + def _allowed_to_proceed(self, verbose): + """Display which files would be deleted and prompt for confirmation + """ + + def _display(msg, paths): + if not paths: + return + + logger.info(msg) + with indent_log(): + for path in sorted(compact(paths)): + logger.info(path) + + if not verbose: + will_remove, will_skip = compress_for_output_listing(self.paths) + else: + # In verbose mode, display all the files that are going to be + # deleted. + will_remove = list(self.paths) + will_skip = set() + + _display('Would remove:', will_remove) + _display('Would not remove (might be manually added):', will_skip) + _display('Would not remove (outside of prefix):', self._refuse) + + return ask('Proceed (y/n)? ', ('y', 'n')) == 'y' + + def rollback(self): + """Rollback the changes previously made by remove().""" + if self.save_dir.path is None: + logger.error( + "Can't roll back %s; was not uninstalled", + self.dist.project_name, + ) + return False + logger.info('Rolling back uninstall of %s', self.dist.project_name) + for path in self._moved_paths: + tmp_path = self._stash(path) + logger.debug('Replacing %s', path) + renames(tmp_path, path) + for pth in self.pth.values(): + pth.rollback() + + def commit(self): + """Remove temporary save dir: rollback will no longer be possible.""" + self.save_dir.cleanup() + self._moved_paths = [] + + @classmethod + def from_dist(cls, dist): + dist_path = normalize_path(dist.location) + if not dist_is_local(dist): + logger.info( + "Not uninstalling %s at %s, outside environment %s", + dist.key, + dist_path, + sys.prefix, + ) + return cls(dist) + + if dist_path in {p for p in {sysconfig.get_path("stdlib"), + sysconfig.get_path("platstdlib")} + if p}: + logger.info( + "Not uninstalling %s at %s, as it is in the standard library.", + dist.key, + dist_path, + ) + return cls(dist) + + paths_to_remove = cls(dist) + develop_egg_link = egg_link_path(dist) + develop_egg_link_egg_info = '{}.egg-info'.format( + pkg_resources.to_filename(dist.project_name)) + egg_info_exists = dist.egg_info and os.path.exists(dist.egg_info) + # Special case for distutils installed package + distutils_egg_info = getattr(dist._provider, 'path', None) + + # Uninstall cases order do matter as in the case of 2 installs of the + # same package, pip needs to uninstall the currently detected version + if (egg_info_exists and dist.egg_info.endswith('.egg-info') and + not dist.egg_info.endswith(develop_egg_link_egg_info)): + # if dist.egg_info.endswith(develop_egg_link_egg_info), we + # are in fact in the develop_egg_link case + paths_to_remove.add(dist.egg_info) + if dist.has_metadata('installed-files.txt'): + for installed_file in dist.get_metadata( + 'installed-files.txt').splitlines(): + path = os.path.normpath( + os.path.join(dist.egg_info, installed_file) + ) + paths_to_remove.add(path) + # FIXME: need a test for this elif block + # occurs with --single-version-externally-managed/--record outside + # of pip + elif dist.has_metadata('top_level.txt'): + if dist.has_metadata('namespace_packages.txt'): + namespaces = dist.get_metadata('namespace_packages.txt') + else: + namespaces = [] + for top_level_pkg in [ + p for p + in dist.get_metadata('top_level.txt').splitlines() + if p and p not in namespaces]: + path = os.path.join(dist.location, top_level_pkg) + paths_to_remove.add(path) + paths_to_remove.add(path + '.py') + paths_to_remove.add(path + '.pyc') + paths_to_remove.add(path + '.pyo') + + elif distutils_egg_info: + raise UninstallationError( + "Cannot uninstall {!r}. It is a distutils installed project " + "and thus we cannot accurately determine which files belong " + "to it which would lead to only a partial uninstall.".format( + dist.project_name, + ) + ) + + elif dist.location.endswith('.egg'): + # package installed by easy_install + # We cannot match on dist.egg_name because it can slightly vary + # i.e. setuptools-0.6c11-py2.6.egg vs setuptools-0.6rc11-py2.6.egg + paths_to_remove.add(dist.location) + easy_install_egg = os.path.split(dist.location)[1] + easy_install_pth = os.path.join(os.path.dirname(dist.location), + 'easy-install.pth') + paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg) + + elif egg_info_exists and dist.egg_info.endswith('.dist-info'): + for path in uninstallation_paths(dist): + paths_to_remove.add(path) + + elif develop_egg_link: + # develop egg + with open(develop_egg_link, 'r') as fh: + link_pointer = os.path.normcase(fh.readline().strip()) + assert (link_pointer == dist.location), ( + 'Egg-link %s does not match installed location of %s ' + '(at %s)' % (link_pointer, dist.project_name, dist.location) + ) + paths_to_remove.add(develop_egg_link) + easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), + 'easy-install.pth') + paths_to_remove.add_pth(easy_install_pth, dist.location) + + else: + logger.debug( + 'Not sure how to uninstall: %s - Check: %s', + dist, dist.location, + ) + + # find distutils scripts= scripts + if dist.has_metadata('scripts') and dist.metadata_isdir('scripts'): + for script in dist.metadata_listdir('scripts'): + if dist_in_usersite(dist): + bin_dir = bin_user + else: + bin_dir = bin_py + paths_to_remove.add(os.path.join(bin_dir, script)) + if WINDOWS: + paths_to_remove.add(os.path.join(bin_dir, script) + '.bat') + + # find console_scripts + _scripts_to_remove = [] + console_scripts = dist.get_entry_map(group='console_scripts') + for name in console_scripts.keys(): + _scripts_to_remove.extend(_script_names(dist, name, False)) + # find gui_scripts + gui_scripts = dist.get_entry_map(group='gui_scripts') + for name in gui_scripts.keys(): + _scripts_to_remove.extend(_script_names(dist, name, True)) + + for s in _scripts_to_remove: + paths_to_remove.add(s) + + return paths_to_remove + + +class UninstallPthEntries(object): + def __init__(self, pth_file): + if not os.path.isfile(pth_file): + raise UninstallationError( + "Cannot remove entries from nonexistent file %s" % pth_file + ) + self.file = pth_file + self.entries = set() + self._saved_lines = None + + def add(self, entry): + entry = os.path.normcase(entry) + # On Windows, os.path.normcase converts the entry to use + # backslashes. This is correct for entries that describe absolute + # paths outside of site-packages, but all the others use forward + # slashes. + if WINDOWS and not os.path.splitdrive(entry)[0]: + entry = entry.replace('\\', '/') + self.entries.add(entry) + + def remove(self): + logger.debug('Removing pth entries from %s:', self.file) + with open(self.file, 'rb') as fh: + # windows uses '\r\n' with py3k, but uses '\n' with py2.x + lines = fh.readlines() + self._saved_lines = lines + if any(b'\r\n' in line for line in lines): + endline = '\r\n' + else: + endline = '\n' + # handle missing trailing newline + if lines and not lines[-1].endswith(endline.encode("utf-8")): + lines[-1] = lines[-1] + endline.encode("utf-8") + for entry in self.entries: + try: + logger.debug('Removing entry: %s', entry) + lines.remove((entry + endline).encode("utf-8")) + except ValueError: + pass + with open(self.file, 'wb') as fh: + fh.writelines(lines) + + def rollback(self): + if self._saved_lines is None: + logger.error( + 'Cannot roll back changes to %s, none were made', self.file + ) + return False + logger.debug('Rolling %s back to previous state', self.file) + with open(self.file, 'wb') as fh: + fh.writelines(self._saved_lines) + return True diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/resolve.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/resolve.py new file mode 100644 index 0000000..3200fca --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/resolve.py @@ -0,0 +1,354 @@ +"""Dependency Resolution + +The dependency resolution in pip is performed as follows: + +for top-level requirements: + a. only one spec allowed per project, regardless of conflicts or not. + otherwise a "double requirement" exception is raised + b. they override sub-dependency requirements. +for sub-dependencies + a. "first found, wins" (where the order is breadth first) +""" + +import logging +from collections import defaultdict +from itertools import chain + +from pip._internal.exceptions import ( + BestVersionAlreadyInstalled, DistributionNotFound, HashError, HashErrors, + UnsupportedPythonVersion, +) + +from pip._internal.req.req_install import InstallRequirement +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import dist_in_usersite, ensure_dir +from pip._internal.utils.packaging import check_dist_requires_python + +logger = logging.getLogger(__name__) + + +class Resolver(object): + """Resolves which packages need to be installed/uninstalled to perform \ + the requested operation without breaking the requirements of any package. + """ + + _allowed_strategies = {"eager", "only-if-needed", "to-satisfy-only"} + + def __init__(self, preparer, session, finder, wheel_cache, use_user_site, + ignore_dependencies, ignore_installed, ignore_requires_python, + force_reinstall, isolated, upgrade_strategy): + super(Resolver, self).__init__() + assert upgrade_strategy in self._allowed_strategies + + self.preparer = preparer + self.finder = finder + self.session = session + + # NOTE: This would eventually be replaced with a cache that can give + # information about both sdist and wheels transparently. + self.wheel_cache = wheel_cache + + self.require_hashes = None # This is set in resolve + + self.upgrade_strategy = upgrade_strategy + self.force_reinstall = force_reinstall + self.isolated = isolated + self.ignore_dependencies = ignore_dependencies + self.ignore_installed = ignore_installed + self.ignore_requires_python = ignore_requires_python + self.use_user_site = use_user_site + + self._discovered_dependencies = defaultdict(list) + + def resolve(self, requirement_set): + """Resolve what operations need to be done + + As a side-effect of this method, the packages (and their dependencies) + are downloaded, unpacked and prepared for installation. This + preparation is done by ``pip.operations.prepare``. + + Once PyPI has static dependency metadata available, it would be + possible to move the preparation to become a step separated from + dependency resolution. + """ + # make the wheelhouse + if self.preparer.wheel_download_dir: + ensure_dir(self.preparer.wheel_download_dir) + + # If any top-level requirement has a hash specified, enter + # hash-checking mode, which requires hashes from all. + root_reqs = ( + requirement_set.unnamed_requirements + + list(requirement_set.requirements.values()) + ) + self.require_hashes = ( + requirement_set.require_hashes or + any(req.has_hash_options for req in root_reqs) + ) + + # Display where finder is looking for packages + locations = self.finder.get_formatted_locations() + if locations: + logger.info(locations) + + # Actually prepare the files, and collect any exceptions. Most hash + # exceptions cannot be checked ahead of time, because + # req.populate_link() needs to be called before we can make decisions + # based on link type. + discovered_reqs = [] + hash_errors = HashErrors() + for req in chain(root_reqs, discovered_reqs): + try: + discovered_reqs.extend( + self._resolve_one(requirement_set, req) + ) + except HashError as exc: + exc.req = req + hash_errors.append(exc) + + if hash_errors: + raise hash_errors + + def _is_upgrade_allowed(self, req): + if self.upgrade_strategy == "to-satisfy-only": + return False + elif self.upgrade_strategy == "eager": + return True + else: + assert self.upgrade_strategy == "only-if-needed" + return req.is_direct + + def _set_req_to_reinstall(self, req): + """ + Set a requirement to be installed. + """ + # Don't uninstall the conflict if doing a user install and the + # conflict is not a user install. + if not self.use_user_site or dist_in_usersite(req.satisfied_by): + req.conflicts_with = req.satisfied_by + req.satisfied_by = None + + # XXX: Stop passing requirement_set for options + def _check_skip_installed(self, req_to_install): + """Check if req_to_install should be skipped. + + This will check if the req is installed, and whether we should upgrade + or reinstall it, taking into account all the relevant user options. + + After calling this req_to_install will only have satisfied_by set to + None if the req_to_install is to be upgraded/reinstalled etc. Any + other value will be a dist recording the current thing installed that + satisfies the requirement. + + Note that for vcs urls and the like we can't assess skipping in this + routine - we simply identify that we need to pull the thing down, + then later on it is pulled down and introspected to assess upgrade/ + reinstalls etc. + + :return: A text reason for why it was skipped, or None. + """ + if self.ignore_installed: + return None + + req_to_install.check_if_exists(self.use_user_site) + if not req_to_install.satisfied_by: + return None + + if self.force_reinstall: + self._set_req_to_reinstall(req_to_install) + return None + + if not self._is_upgrade_allowed(req_to_install): + if self.upgrade_strategy == "only-if-needed": + return 'not upgraded as not directly required' + return 'already satisfied' + + # Check for the possibility of an upgrade. For link-based + # requirements we have to pull the tree down and inspect to assess + # the version #, so it's handled way down. + if not req_to_install.link: + try: + self.finder.find_requirement(req_to_install, upgrade=True) + except BestVersionAlreadyInstalled: + # Then the best version is installed. + return 'already up-to-date' + except DistributionNotFound: + # No distribution found, so we squash the error. It will + # be raised later when we re-try later to do the install. + # Why don't we just raise here? + pass + + self._set_req_to_reinstall(req_to_install) + return None + + def _get_abstract_dist_for(self, req): + """Takes a InstallRequirement and returns a single AbstractDist \ + representing a prepared variant of the same. + """ + assert self.require_hashes is not None, ( + "require_hashes should have been set in Resolver.resolve()" + ) + + if req.editable: + return self.preparer.prepare_editable_requirement( + req, self.require_hashes, self.use_user_site, self.finder, + ) + + # satisfied_by is only evaluated by calling _check_skip_installed, + # so it must be None here. + assert req.satisfied_by is None + skip_reason = self._check_skip_installed(req) + + if req.satisfied_by: + return self.preparer.prepare_installed_requirement( + req, self.require_hashes, skip_reason + ) + + upgrade_allowed = self._is_upgrade_allowed(req) + abstract_dist = self.preparer.prepare_linked_requirement( + req, self.session, self.finder, upgrade_allowed, + self.require_hashes + ) + + # NOTE + # The following portion is for determining if a certain package is + # going to be re-installed/upgraded or not and reporting to the user. + # This should probably get cleaned up in a future refactor. + + # req.req is only avail after unpack for URL + # pkgs repeat check_if_exists to uninstall-on-upgrade + # (#14) + if not self.ignore_installed: + req.check_if_exists(self.use_user_site) + + if req.satisfied_by: + should_modify = ( + self.upgrade_strategy != "to-satisfy-only" or + self.force_reinstall or + self.ignore_installed or + req.link.scheme == 'file' + ) + if should_modify: + self._set_req_to_reinstall(req) + else: + logger.info( + 'Requirement already satisfied (use --upgrade to upgrade):' + ' %s', req, + ) + + return abstract_dist + + def _resolve_one(self, requirement_set, req_to_install): + """Prepare a single requirements file. + + :return: A list of additional InstallRequirements to also install. + """ + # Tell user what we are doing for this requirement: + # obtain (editable), skipping, processing (local url), collecting + # (remote url or package name) + if req_to_install.constraint or req_to_install.prepared: + return [] + + req_to_install.prepared = True + + # register tmp src for cleanup in case something goes wrong + requirement_set.reqs_to_cleanup.append(req_to_install) + + abstract_dist = self._get_abstract_dist_for(req_to_install) + + # Parse and return dependencies + dist = abstract_dist.dist(self.finder) + try: + check_dist_requires_python(dist) + except UnsupportedPythonVersion as err: + if self.ignore_requires_python: + logger.warning(err.args[0]) + else: + raise + + more_reqs = [] + + def add_req(subreq, extras_requested): + sub_install_req = InstallRequirement.from_req( + str(subreq), + req_to_install, + isolated=self.isolated, + wheel_cache=self.wheel_cache, + ) + parent_req_name = req_to_install.name + to_scan_again, add_to_parent = requirement_set.add_requirement( + sub_install_req, + parent_req_name=parent_req_name, + extras_requested=extras_requested, + ) + if parent_req_name and add_to_parent: + self._discovered_dependencies[parent_req_name].append( + add_to_parent + ) + more_reqs.extend(to_scan_again) + + with indent_log(): + # We add req_to_install before its dependencies, so that we + # can refer to it when adding dependencies. + if not requirement_set.has_requirement(req_to_install.name): + # 'unnamed' requirements will get added here + req_to_install.is_direct = True + requirement_set.add_requirement( + req_to_install, parent_req_name=None, + ) + + if not self.ignore_dependencies: + if req_to_install.extras: + logger.debug( + "Installing extra requirements: %r", + ','.join(req_to_install.extras), + ) + missing_requested = sorted( + set(req_to_install.extras) - set(dist.extras) + ) + for missing in missing_requested: + logger.warning( + '%s does not provide the extra \'%s\'', + dist, missing + ) + + available_requested = sorted( + set(dist.extras) & set(req_to_install.extras) + ) + for subreq in dist.requires(available_requested): + add_req(subreq, extras_requested=available_requested) + + if not req_to_install.editable and not req_to_install.satisfied_by: + # XXX: --no-install leads this to report 'Successfully + # downloaded' for only non-editable reqs, even though we took + # action on them. + requirement_set.successfully_downloaded.append(req_to_install) + + return more_reqs + + def get_installation_order(self, req_set): + """Create the installation order. + + The installation order is topological - requirements are installed + before the requiring thing. We break cycles at an arbitrary point, + and make no other guarantees. + """ + # The current implementation, which we may change at any point + # installs the user specified things in the order given, except when + # dependencies must come earlier to achieve topological order. + order = [] + ordered_reqs = set() + + def schedule(req): + if req.satisfied_by or req in ordered_reqs: + return + if req.constraint: + return + ordered_reqs.add(req) + for dep in self._discovered_dependencies[req.name]: + schedule(dep) + order.append(req) + + for install_req in req_set.requirements.values(): + schedule(install_req) + return order diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/status_codes.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/status_codes.py new file mode 100644 index 0000000..275360a --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/status_codes.py @@ -0,0 +1,8 @@ +from __future__ import absolute_import + +SUCCESS = 0 +ERROR = 1 +UNKNOWN_ERROR = 2 +VIRTUALENV_NOT_FOUND = 3 +PREVIOUS_BUILD_DIR_ERROR = 4 +NO_MATCHES_FOUND = 23 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/appdirs.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/appdirs.py new file mode 100644 index 0000000..28c5d4b --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/appdirs.py @@ -0,0 +1,258 @@ +""" +This code was taken from https://github.com/ActiveState/appdirs and modified +to suit our purposes. +""" +from __future__ import absolute_import + +import os +import sys + +from pip._vendor.six import PY2, text_type + +from pip._internal.compat import WINDOWS, expanduser + + +def user_cache_dir(appname): + r""" + Return full path to the user-specific cache dir for this application. + + "appname" is the name of application. + + Typical user cache directories are: + macOS: ~/Library/Caches/ + Unix: ~/.cache/ (XDG default) + Windows: C:\Users\\AppData\Local\\Cache + + On Windows the only suggestion in the MSDN docs is that local settings go + in the `CSIDL_LOCAL_APPDATA` directory. This is identical to the + non-roaming app data dir (the default returned by `user_data_dir`). Apps + typically put cache data somewhere *under* the given dir here. Some + examples: + ...\Mozilla\Firefox\Profiles\\Cache + ...\Acme\SuperApp\Cache\1.0 + + OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. + """ + if WINDOWS: + # Get the base path + path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) + + # When using Python 2, return paths as bytes on Windows like we do on + # other operating systems. See helper function docs for more details. + if PY2 and isinstance(path, text_type): + path = _win_path_to_bytes(path) + + # Add our app name and Cache directory to it + path = os.path.join(path, appname, "Cache") + elif sys.platform == "darwin": + # Get the base path + path = expanduser("~/Library/Caches") + + # Add our app name to it + path = os.path.join(path, appname) + else: + # Get the base path + path = os.getenv("XDG_CACHE_HOME", expanduser("~/.cache")) + + # Add our app name to it + path = os.path.join(path, appname) + + return path + + +def user_data_dir(appname, roaming=False): + r""" + Return full path to the user-specific data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + + for a discussion of issues. + + Typical user data directories are: + macOS: ~/Library/Application Support/ + if it exists, else ~/.config/ + Unix: ~/.local/share/ # or in + $XDG_DATA_HOME, if defined + Win XP (not roaming): C:\Documents and Settings\\ ... + ...Application Data\ + Win XP (roaming): C:\Documents and Settings\\Local ... + ...Settings\Application Data\ + Win 7 (not roaming): C:\\Users\\AppData\Local\ + Win 7 (roaming): C:\\Users\\AppData\Roaming\ + + For Unix, we follow the XDG spec and support $XDG_DATA_HOME. + That means, by default "~/.local/share/". + """ + if WINDOWS: + const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" + path = os.path.join(os.path.normpath(_get_win_folder(const)), appname) + elif sys.platform == "darwin": + path = os.path.join( + expanduser('~/Library/Application Support/'), + appname, + ) if os.path.isdir(os.path.join( + expanduser('~/Library/Application Support/'), + appname, + ) + ) else os.path.join( + expanduser('~/.config/'), + appname, + ) + else: + path = os.path.join( + os.getenv('XDG_DATA_HOME', expanduser("~/.local/share")), + appname, + ) + + return path + + +def user_config_dir(appname, roaming=True): + """Return full path to the user-specific config dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "roaming" (boolean, default True) can be set False to not use the + Windows roaming appdata directory. That means that for users on a + Windows network setup for roaming profiles, this user data will be + sync'd on login. See + + for a discussion of issues. + + Typical user data directories are: + macOS: same as user_data_dir + Unix: ~/.config/ + Win *: same as user_data_dir + + For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. + That means, by default "~/.config/". + """ + if WINDOWS: + path = user_data_dir(appname, roaming=roaming) + elif sys.platform == "darwin": + path = user_data_dir(appname) + else: + path = os.getenv('XDG_CONFIG_HOME', expanduser("~/.config")) + path = os.path.join(path, appname) + + return path + + +# for the discussion regarding site_config_dirs locations +# see +def site_config_dirs(appname): + r"""Return a list of potential user-shared config dirs for this application. + + "appname" is the name of application. + + Typical user config directories are: + macOS: /Library/Application Support// + Unix: /etc or $XDG_CONFIG_DIRS[i]// for each value in + $XDG_CONFIG_DIRS + Win XP: C:\Documents and Settings\All Users\Application ... + ...Data\\ + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory + on Vista.) + Win 7: Hidden, but writeable on Win 7: + C:\ProgramData\\ + """ + if WINDOWS: + path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) + pathlist = [os.path.join(path, appname)] + elif sys.platform == 'darwin': + pathlist = [os.path.join('/Library/Application Support', appname)] + else: + # try looking in $XDG_CONFIG_DIRS + xdg_config_dirs = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') + if xdg_config_dirs: + pathlist = [ + os.path.join(expanduser(x), appname) + for x in xdg_config_dirs.split(os.pathsep) + ] + else: + pathlist = [] + + # always look in /etc directly as well + pathlist.append('/etc') + + return pathlist + + +# -- Windows support functions -- + +def _get_win_folder_from_registry(csidl_name): + """ + This is a fallback technique at best. I'm not sure if using the + registry for this guarantees us the correct answer for all CSIDL_* + names. + """ + import _winreg + + shell_folder_name = { + "CSIDL_APPDATA": "AppData", + "CSIDL_COMMON_APPDATA": "Common AppData", + "CSIDL_LOCAL_APPDATA": "Local AppData", + }[csidl_name] + + key = _winreg.OpenKey( + _winreg.HKEY_CURRENT_USER, + r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" + ) + directory, _type = _winreg.QueryValueEx(key, shell_folder_name) + return directory + + +def _get_win_folder_with_ctypes(csidl_name): + csidl_const = { + "CSIDL_APPDATA": 26, + "CSIDL_COMMON_APPDATA": 35, + "CSIDL_LOCAL_APPDATA": 28, + }[csidl_name] + + buf = ctypes.create_unicode_buffer(1024) + ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) + + # Downgrade to short path name if have highbit chars. See + # . + has_high_char = False + for c in buf: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf2 = ctypes.create_unicode_buffer(1024) + if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): + buf = buf2 + + return buf.value + + +if WINDOWS: + try: + import ctypes + _get_win_folder = _get_win_folder_with_ctypes + except ImportError: + _get_win_folder = _get_win_folder_from_registry + + +def _win_path_to_bytes(path): + """Encode Windows paths to bytes. Only used on Python 2. + + Motivation is to be consistent with other operating systems where paths + are also returned as bytes. This avoids problems mixing bytes and Unicode + elsewhere in the codebase. For more details and discussion see + . + + If encoding using ASCII and MBCS fails, return the original Unicode path. + """ + for encoding in ('ASCII', 'MBCS'): + try: + return path.encode(encoding) + except (UnicodeEncodeError, LookupError): + pass + return path diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/deprecation.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/deprecation.py new file mode 100644 index 0000000..a907172 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/deprecation.py @@ -0,0 +1,77 @@ +""" +A module that implements tooling to enable easy warnings about deprecations. +""" +from __future__ import absolute_import + +import logging +import warnings + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any + + +class PipDeprecationWarning(Warning): + pass + + +class Pending(object): + pass + + +class RemovedInPip11Warning(PipDeprecationWarning): + pass + + +class RemovedInPip12Warning(PipDeprecationWarning, Pending): + pass + + +# Warnings <-> Logging Integration + + +_warnings_showwarning = None # type: Any + + +def _showwarning(message, category, filename, lineno, file=None, line=None): + if file is not None: + if _warnings_showwarning is not None: + _warnings_showwarning( + message, category, filename, lineno, file, line, + ) + else: + if issubclass(category, PipDeprecationWarning): + # We use a specially named logger which will handle all of the + # deprecation messages for pip. + logger = logging.getLogger("pip._internal.deprecations") + + # This is purposely using the % formatter here instead of letting + # the logging module handle the interpolation. This is because we + # want it to appear as if someone typed this entire message out. + log_message = "DEPRECATION: %s" % message + + # PipDeprecationWarnings that are Pending still have at least 2 + # versions to go until they are removed so they can just be + # warnings. Otherwise, they will be removed in the very next + # version of pip. We want these to be more obvious so we use the + # ERROR logging level. + if issubclass(category, Pending): + logger.warning(log_message) + else: + logger.error(log_message) + else: + _warnings_showwarning( + message, category, filename, lineno, file, line, + ) + + +def install_warning_logger(): + # Enable our Deprecation Warnings + warnings.simplefilter("default", PipDeprecationWarning, append=True) + + global _warnings_showwarning + + if _warnings_showwarning is None: + _warnings_showwarning = warnings.showwarning + warnings.showwarning = _showwarning diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/encoding.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/encoding.py new file mode 100644 index 0000000..56f6036 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/encoding.py @@ -0,0 +1,33 @@ +import codecs +import locale +import re +import sys + +BOMS = [ + (codecs.BOM_UTF8, 'utf8'), + (codecs.BOM_UTF16, 'utf16'), + (codecs.BOM_UTF16_BE, 'utf16-be'), + (codecs.BOM_UTF16_LE, 'utf16-le'), + (codecs.BOM_UTF32, 'utf32'), + (codecs.BOM_UTF32_BE, 'utf32-be'), + (codecs.BOM_UTF32_LE, 'utf32-le'), +] + +ENCODING_RE = re.compile(br'coding[:=]\s*([-\w.]+)') + + +def auto_decode(data): + """Check a bytes string for a BOM to correctly detect the encoding + + Fallback to locale.getpreferredencoding(False) like open() on Python3""" + for bom, encoding in BOMS: + if data.startswith(bom): + return data[len(bom):].decode(encoding) + # Lets check the first two lines as in PEP263 + for line in data.split(b'\n')[:2]: + if line[0:1] == b'#' and ENCODING_RE.search(line): + encoding = ENCODING_RE.search(line).groups()[0].decode('ascii') + return data.decode(encoding) + return data.decode( + locale.getpreferredencoding(False) or sys.getdefaultencoding(), + ) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/filesystem.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/filesystem.py new file mode 100644 index 0000000..ee45501 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/filesystem.py @@ -0,0 +1,28 @@ +import os +import os.path + +from pip._internal.compat import get_path_uid + + +def check_path_owner(path): + # If we don't have a way to check the effective uid of this process, then + # we'll just assume that we own the directory. + if not hasattr(os, "geteuid"): + return True + + previous = None + while path != previous: + if os.path.lexists(path): + # Check if path is writable by current user. + if os.geteuid() == 0: + # Special handling for root user in order to handle properly + # cases where users use sudo without -H flag. + try: + path_uid = get_path_uid(path) + except OSError: + return False + return path_uid == 0 + else: + return os.access(path, os.W_OK) + else: + previous, path = path, os.path.dirname(path) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/glibc.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/glibc.py new file mode 100644 index 0000000..ebcfc5b --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/glibc.py @@ -0,0 +1,84 @@ +from __future__ import absolute_import + +import ctypes +import re +import warnings + + +def glibc_version_string(): + "Returns glibc version string, or None if not using glibc." + + # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen + # manpage says, "If filename is NULL, then the returned handle is for the + # main program". This way we can let the linker do the work to figure out + # which libc our process is actually using. + process_namespace = ctypes.CDLL(None) + try: + gnu_get_libc_version = process_namespace.gnu_get_libc_version + except AttributeError: + # Symbol doesn't exist -> therefore, we are not linked to + # glibc. + return None + + # Call gnu_get_libc_version, which returns a string like "2.5" + gnu_get_libc_version.restype = ctypes.c_char_p + version_str = gnu_get_libc_version() + # py2 / py3 compatibility: + if not isinstance(version_str, str): + version_str = version_str.decode("ascii") + + return version_str + + +# Separated out from have_compatible_glibc for easier unit testing +def check_glibc_version(version_str, required_major, minimum_minor): + # Parse string and check against requested version. + # + # We use a regexp instead of str.split because we want to discard any + # random junk that might come after the minor version -- this might happen + # in patched/forked versions of glibc (e.g. Linaro's version of glibc + # uses version strings like "2.20-2014.11"). See gh-3588. + m = re.match(r"(?P[0-9]+)\.(?P[0-9]+)", version_str) + if not m: + warnings.warn("Expected glibc version with 2 components major.minor," + " got: %s" % version_str, RuntimeWarning) + return False + return (int(m.group("major")) == required_major and + int(m.group("minor")) >= minimum_minor) + + +def have_compatible_glibc(required_major, minimum_minor): + version_str = glibc_version_string() + if version_str is None: + return False + return check_glibc_version(version_str, required_major, minimum_minor) + + +# platform.libc_ver regularly returns completely nonsensical glibc +# versions. E.g. on my computer, platform says: +# +# ~$ python2.7 -c 'import platform; print(platform.libc_ver())' +# ('glibc', '2.7') +# ~$ python3.5 -c 'import platform; print(platform.libc_ver())' +# ('glibc', '2.9') +# +# But the truth is: +# +# ~$ ldd --version +# ldd (Debian GLIBC 2.22-11) 2.22 +# +# This is unfortunate, because it means that the linehaul data on libc +# versions that was generated by pip 8.1.2 and earlier is useless and +# misleading. Solution: instead of using platform, use our code that actually +# works. +def libc_ver(): + """Try to determine the glibc version + + Returns a tuple of strings (lib, version) which default to empty strings + in case the lookup fails. + """ + glibc_version = glibc_version_string() + if glibc_version is None: + return ("", "") + else: + return ("glibc", glibc_version) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/hashes.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/hashes.py new file mode 100644 index 0000000..8b909ba --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/hashes.py @@ -0,0 +1,94 @@ +from __future__ import absolute_import + +import hashlib + +from pip._vendor.six import iteritems, iterkeys, itervalues + +from pip._internal.exceptions import ( + HashMismatch, HashMissing, InstallationError, +) +from pip._internal.utils.misc import read_chunks + +# The recommended hash algo of the moment. Change this whenever the state of +# the art changes; it won't hurt backward compatibility. +FAVORITE_HASH = 'sha256' + + +# Names of hashlib algorithms allowed by the --hash option and ``pip hash`` +# Currently, those are the ones at least as collision-resistant as sha256. +STRONG_HASHES = ['sha256', 'sha384', 'sha512'] + + +class Hashes(object): + """A wrapper that builds multiple hashes at once and checks them against + known-good values + + """ + def __init__(self, hashes=None): + """ + :param hashes: A dict of algorithm names pointing to lists of allowed + hex digests + """ + self._allowed = {} if hashes is None else hashes + + def check_against_chunks(self, chunks): + """Check good hashes against ones built from iterable of chunks of + data. + + Raise HashMismatch if none match. + + """ + gots = {} + for hash_name in iterkeys(self._allowed): + try: + gots[hash_name] = hashlib.new(hash_name) + except (ValueError, TypeError): + raise InstallationError('Unknown hash name: %s' % hash_name) + + for chunk in chunks: + for hash in itervalues(gots): + hash.update(chunk) + + for hash_name, got in iteritems(gots): + if got.hexdigest() in self._allowed[hash_name]: + return + self._raise(gots) + + def _raise(self, gots): + raise HashMismatch(self._allowed, gots) + + def check_against_file(self, file): + """Check good hashes against a file-like object + + Raise HashMismatch if none match. + + """ + return self.check_against_chunks(read_chunks(file)) + + def check_against_path(self, path): + with open(path, 'rb') as file: + return self.check_against_file(file) + + def __nonzero__(self): + """Return whether I know any known-good hashes.""" + return bool(self._allowed) + + def __bool__(self): + return self.__nonzero__() + + +class MissingHashes(Hashes): + """A workalike for Hashes used when we're missing a hash for a requirement + + It computes the actual hash of the requirement and raises a HashMissing + exception showing it to the user. + + """ + def __init__(self): + """Don't offer the ``hashes`` kwarg.""" + # Pass our favorite hash in to generate a "gotten hash". With the + # empty list, it will never match, so an error will always raise. + super(MissingHashes, self).__init__(hashes={FAVORITE_HASH: []}) + + def _raise(self, gots): + raise HashMissing(gots[FAVORITE_HASH].hexdigest()) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/logging.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/logging.py new file mode 100644 index 0000000..5a5a7d7 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/logging.py @@ -0,0 +1,132 @@ +from __future__ import absolute_import + +import contextlib +import logging +import logging.handlers +import os + +from pip._internal.compat import WINDOWS +from pip._internal.utils.misc import ensure_dir + +try: + import threading +except ImportError: + import dummy_threading as threading # type: ignore + + +try: + from pip._vendor import colorama +# Lots of different errors can come from this, including SystemError and +# ImportError. +except Exception: + colorama = None + + +_log_state = threading.local() +_log_state.indentation = 0 + + +@contextlib.contextmanager +def indent_log(num=2): + """ + A context manager which will cause the log output to be indented for any + log messages emitted inside it. + """ + _log_state.indentation += num + try: + yield + finally: + _log_state.indentation -= num + + +def get_indentation(): + return getattr(_log_state, 'indentation', 0) + + +class IndentingFormatter(logging.Formatter): + + def format(self, record): + """ + Calls the standard formatter, but will indent all of the log messages + by our current indentation level. + """ + formatted = logging.Formatter.format(self, record) + formatted = "".join([ + (" " * get_indentation()) + line + for line in formatted.splitlines(True) + ]) + return formatted + + +def _color_wrap(*colors): + def wrapped(inp): + return "".join(list(colors) + [inp, colorama.Style.RESET_ALL]) + return wrapped + + +class ColorizedStreamHandler(logging.StreamHandler): + + # Don't build up a list of colors if we don't have colorama + if colorama: + COLORS = [ + # This needs to be in order from highest logging level to lowest. + (logging.ERROR, _color_wrap(colorama.Fore.RED)), + (logging.WARNING, _color_wrap(colorama.Fore.YELLOW)), + ] + else: + COLORS = [] + + def __init__(self, stream=None, no_color=None): + logging.StreamHandler.__init__(self, stream) + self._no_color = no_color + + if WINDOWS and colorama: + self.stream = colorama.AnsiToWin32(self.stream) + + def should_color(self): + # Don't colorize things if we do not have colorama or if told not to + if not colorama or self._no_color: + return False + + real_stream = ( + self.stream if not isinstance(self.stream, colorama.AnsiToWin32) + else self.stream.wrapped + ) + + # If the stream is a tty we should color it + if hasattr(real_stream, "isatty") and real_stream.isatty(): + return True + + # If we have an ASNI term we should color it + if os.environ.get("TERM") == "ANSI": + return True + + # If anything else we should not color it + return False + + def format(self, record): + msg = logging.StreamHandler.format(self, record) + + if self.should_color(): + for level, color in self.COLORS: + if record.levelno >= level: + msg = color(msg) + break + + return msg + + +class BetterRotatingFileHandler(logging.handlers.RotatingFileHandler): + + def _open(self): + ensure_dir(os.path.dirname(self.baseFilename)) + return logging.handlers.RotatingFileHandler._open(self) + + +class MaxLevelFilter(logging.Filter): + + def __init__(self, level): + self.level = level + + def filter(self, record): + return record.levelno < self.level diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/misc.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/misc.py new file mode 100644 index 0000000..9d4c9b1 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/misc.py @@ -0,0 +1,851 @@ +from __future__ import absolute_import + +import contextlib +import errno +import io +import locale +# we have a submodule named 'logging' which would shadow this if we used the +# regular name: +import logging as std_logging +import os +import posixpath +import re +import shutil +import stat +import subprocess +import sys +import tarfile +import zipfile +from collections import deque + +from pip._vendor import pkg_resources +# NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import. +from pip._vendor.retrying import retry # type: ignore +from pip._vendor.six import PY2 +from pip._vendor.six.moves import input + +from pip._internal.compat import console_to_str, expanduser, stdlib_pkgs +from pip._internal.exceptions import InstallationError +from pip._internal.locations import ( + running_under_virtualenv, site_packages, user_site, virtualenv_no_global, + write_delete_marker_file, +) + +if PY2: + from io import BytesIO as StringIO +else: + from io import StringIO + +__all__ = ['rmtree', 'display_path', 'backup_dir', + 'ask', 'splitext', + 'format_size', 'is_installable_dir', + 'is_svn_page', 'file_contents', + 'split_leading_dir', 'has_leading_dir', + 'normalize_path', + 'renames', 'get_prog', + 'unzip_file', 'untar_file', 'unpack_file', 'call_subprocess', + 'captured_stdout', 'ensure_dir', + 'ARCHIVE_EXTENSIONS', 'SUPPORTED_EXTENSIONS', + 'get_installed_version'] + + +logger = std_logging.getLogger(__name__) + +BZ2_EXTENSIONS = ('.tar.bz2', '.tbz') +XZ_EXTENSIONS = ('.tar.xz', '.txz', '.tlz', '.tar.lz', '.tar.lzma') +ZIP_EXTENSIONS = ('.zip', '.whl') +TAR_EXTENSIONS = ('.tar.gz', '.tgz', '.tar') +ARCHIVE_EXTENSIONS = ( + ZIP_EXTENSIONS + BZ2_EXTENSIONS + TAR_EXTENSIONS + XZ_EXTENSIONS) +SUPPORTED_EXTENSIONS = ZIP_EXTENSIONS + TAR_EXTENSIONS +try: + import bz2 # noqa + SUPPORTED_EXTENSIONS += BZ2_EXTENSIONS +except ImportError: + logger.debug('bz2 module is not available') + +try: + # Only for Python 3.3+ + import lzma # noqa + SUPPORTED_EXTENSIONS += XZ_EXTENSIONS +except ImportError: + logger.debug('lzma module is not available') + + +def import_or_raise(pkg_or_module_string, ExceptionType, *args, **kwargs): + try: + return __import__(pkg_or_module_string) + except ImportError: + raise ExceptionType(*args, **kwargs) + + +def ensure_dir(path): + """os.path.makedirs without EEXIST.""" + try: + os.makedirs(path) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + +def get_prog(): + try: + prog = os.path.basename(sys.argv[0]) + if prog in ('__main__.py', '-c'): + return "%s -m pip" % sys.executable + else: + return prog + except (AttributeError, TypeError, IndexError): + pass + return 'pip' + + +# Retry every half second for up to 3 seconds +@retry(stop_max_delay=3000, wait_fixed=500) +def rmtree(dir, ignore_errors=False): + shutil.rmtree(dir, ignore_errors=ignore_errors, + onerror=rmtree_errorhandler) + + +def rmtree_errorhandler(func, path, exc_info): + """On Windows, the files in .svn are read-only, so when rmtree() tries to + remove them, an exception is thrown. We catch that here, remove the + read-only attribute, and hopefully continue without problems.""" + # if file type currently read only + if os.stat(path).st_mode & stat.S_IREAD: + # convert to read/write + os.chmod(path, stat.S_IWRITE) + # use the original function to repeat the operation + func(path) + return + else: + raise + + +def display_path(path): + """Gives the display value for a given path, making it relative to cwd + if possible.""" + path = os.path.normcase(os.path.abspath(path)) + if sys.version_info[0] == 2: + path = path.decode(sys.getfilesystemencoding(), 'replace') + path = path.encode(sys.getdefaultencoding(), 'replace') + if path.startswith(os.getcwd() + os.path.sep): + path = '.' + path[len(os.getcwd()):] + return path + + +def backup_dir(dir, ext='.bak'): + """Figure out the name of a directory to back up the given dir to + (adding .bak, .bak2, etc)""" + n = 1 + extension = ext + while os.path.exists(dir + extension): + n += 1 + extension = ext + str(n) + return dir + extension + + +def ask_path_exists(message, options): + for action in os.environ.get('PIP_EXISTS_ACTION', '').split(): + if action in options: + return action + return ask(message, options) + + +def ask(message, options): + """Ask the message interactively, with the given possible responses""" + while 1: + if os.environ.get('PIP_NO_INPUT'): + raise Exception( + 'No input was expected ($PIP_NO_INPUT set); question: %s' % + message + ) + response = input(message) + response = response.strip().lower() + if response not in options: + print( + 'Your response (%r) was not one of the expected responses: ' + '%s' % (response, ', '.join(options)) + ) + else: + return response + + +def format_size(bytes): + if bytes > 1000 * 1000: + return '%.1fMB' % (bytes / 1000.0 / 1000) + elif bytes > 10 * 1000: + return '%ikB' % (bytes / 1000) + elif bytes > 1000: + return '%.1fkB' % (bytes / 1000.0) + else: + return '%ibytes' % bytes + + +def is_installable_dir(path): + """Return True if `path` is a directory containing a setup.py file.""" + if not os.path.isdir(path): + return False + setup_py = os.path.join(path, 'setup.py') + if os.path.isfile(setup_py): + return True + return False + + +def is_svn_page(html): + """ + Returns true if the page appears to be the index page of an svn repository + """ + return (re.search(r'[^<]*Revision \d+:', html) and + re.search(r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I)) + + +def file_contents(filename): + with open(filename, 'rb') as fp: + return fp.read().decode('utf-8') + + +def read_chunks(file, size=io.DEFAULT_BUFFER_SIZE): + """Yield pieces of data from a file-like object until EOF.""" + while True: + chunk = file.read(size) + if not chunk: + break + yield chunk + + +def split_leading_dir(path): + path = path.lstrip('/').lstrip('\\') + if '/' in path and (('\\' in path and path.find('/') < path.find('\\')) or + '\\' not in path): + return path.split('/', 1) + elif '\\' in path: + return path.split('\\', 1) + else: + return path, '' + + +def has_leading_dir(paths): + """Returns true if all the paths have the same leading path name + (i.e., everything is in one subdirectory in an archive)""" + common_prefix = None + for path in paths: + prefix, rest = split_leading_dir(path) + if not prefix: + return False + elif common_prefix is None: + common_prefix = prefix + elif prefix != common_prefix: + return False + return True + + +def normalize_path(path, resolve_symlinks=True): + """ + Convert a path to its canonical, case-normalized, absolute version. + + """ + path = expanduser(path) + if resolve_symlinks: + path = os.path.realpath(path) + else: + path = os.path.abspath(path) + return os.path.normcase(path) + + +def splitext(path): + """Like os.path.splitext, but take off .tar too""" + base, ext = posixpath.splitext(path) + if base.lower().endswith('.tar'): + ext = base[-4:] + ext + base = base[:-4] + return base, ext + + +def renames(old, new): + """Like os.renames(), but handles renaming across devices.""" + # Implementation borrowed from os.renames(). + head, tail = os.path.split(new) + if head and tail and not os.path.exists(head): + os.makedirs(head) + + shutil.move(old, new) + + head, tail = os.path.split(old) + if head and tail: + try: + os.removedirs(head) + except OSError: + pass + + +def is_local(path): + """ + Return True if path is within sys.prefix, if we're running in a virtualenv. + + If we're not in a virtualenv, all paths are considered "local." + + """ + if not running_under_virtualenv(): + return True + return normalize_path(path).startswith(normalize_path(sys.prefix)) + + +def dist_is_local(dist): + """ + Return True if given Distribution object is installed locally + (i.e. within current virtualenv). + + Always True if we're not in a virtualenv. + + """ + return is_local(dist_location(dist)) + + +def dist_in_usersite(dist): + """ + Return True if given Distribution is installed in user site. + """ + norm_path = normalize_path(dist_location(dist)) + return norm_path.startswith(normalize_path(user_site)) + + +def dist_in_site_packages(dist): + """ + Return True if given Distribution is installed in + sysconfig.get_python_lib(). + """ + return normalize_path( + dist_location(dist) + ).startswith(normalize_path(site_packages)) + + +def dist_is_editable(dist): + """Is distribution an editable install?""" + for path_item in sys.path: + egg_link = os.path.join(path_item, dist.project_name + '.egg-link') + if os.path.isfile(egg_link): + return True + return False + + +def get_installed_distributions(local_only=True, + skip=stdlib_pkgs, + include_editables=True, + editables_only=False, + user_only=False): + """ + Return a list of installed Distribution objects. + + If ``local_only`` is True (default), only return installations + local to the current virtualenv, if in a virtualenv. + + ``skip`` argument is an iterable of lower-case project names to + ignore; defaults to stdlib_pkgs + + If ``include_editables`` is False, don't report editables. + + If ``editables_only`` is True , only report editables. + + If ``user_only`` is True , only report installations in the user + site directory. + + """ + if local_only: + local_test = dist_is_local + else: + def local_test(d): + return True + + if include_editables: + def editable_test(d): + return True + else: + def editable_test(d): + return not dist_is_editable(d) + + if editables_only: + def editables_only_test(d): + return dist_is_editable(d) + else: + def editables_only_test(d): + return True + + if user_only: + user_test = dist_in_usersite + else: + def user_test(d): + return True + + return [d for d in pkg_resources.working_set + if local_test(d) and + d.key not in skip and + editable_test(d) and + editables_only_test(d) and + user_test(d) + ] + + +def egg_link_path(dist): + """ + Return the path for the .egg-link file if it exists, otherwise, None. + + There's 3 scenarios: + 1) not in a virtualenv + try to find in site.USER_SITE, then site_packages + 2) in a no-global virtualenv + try to find in site_packages + 3) in a yes-global virtualenv + try to find in site_packages, then site.USER_SITE + (don't look in global location) + + For #1 and #3, there could be odd cases, where there's an egg-link in 2 + locations. + + This method will just return the first one found. + """ + sites = [] + if running_under_virtualenv(): + if virtualenv_no_global(): + sites.append(site_packages) + else: + sites.append(site_packages) + if user_site: + sites.append(user_site) + else: + if user_site: + sites.append(user_site) + sites.append(site_packages) + + for site in sites: + egglink = os.path.join(site, dist.project_name) + '.egg-link' + if os.path.isfile(egglink): + return egglink + + +def dist_location(dist): + """ + Get the site-packages location of this distribution. Generally + this is dist.location, except in the case of develop-installed + packages, where dist.location is the source code location, and we + want to know where the egg-link file is. + + """ + egg_link = egg_link_path(dist) + if egg_link: + return egg_link + return dist.location + + +def current_umask(): + """Get the current umask which involves having to set it temporarily.""" + mask = os.umask(0) + os.umask(mask) + return mask + + +def unzip_file(filename, location, flatten=True): + """ + Unzip the file (with path `filename`) to the destination `location`. All + files are written based on system defaults and umask (i.e. permissions are + not preserved), except that regular file members with any execute + permissions (user, group, or world) have "chmod +x" applied after being + written. Note that for windows, any execute changes using os.chmod are + no-ops per the python docs. + """ + ensure_dir(location) + zipfp = open(filename, 'rb') + try: + zip = zipfile.ZipFile(zipfp, allowZip64=True) + leading = has_leading_dir(zip.namelist()) and flatten + for info in zip.infolist(): + name = info.filename + data = zip.read(name) + fn = name + if leading: + fn = split_leading_dir(name)[1] + fn = os.path.join(location, fn) + dir = os.path.dirname(fn) + if fn.endswith('/') or fn.endswith('\\'): + # A directory + ensure_dir(fn) + else: + ensure_dir(dir) + fp = open(fn, 'wb') + try: + fp.write(data) + finally: + fp.close() + mode = info.external_attr >> 16 + # if mode and regular file and any execute permissions for + # user/group/world? + if mode and stat.S_ISREG(mode) and mode & 0o111: + # make dest file have execute for user/group/world + # (chmod +x) no-op on windows per python docs + os.chmod(fn, (0o777 - current_umask() | 0o111)) + finally: + zipfp.close() + + +def untar_file(filename, location): + """ + Untar the file (with path `filename`) to the destination `location`. + All files are written based on system defaults and umask (i.e. permissions + are not preserved), except that regular file members with any execute + permissions (user, group, or world) have "chmod +x" applied after being + written. Note that for windows, any execute changes using os.chmod are + no-ops per the python docs. + """ + ensure_dir(location) + if filename.lower().endswith('.gz') or filename.lower().endswith('.tgz'): + mode = 'r:gz' + elif filename.lower().endswith(BZ2_EXTENSIONS): + mode = 'r:bz2' + elif filename.lower().endswith(XZ_EXTENSIONS): + mode = 'r:xz' + elif filename.lower().endswith('.tar'): + mode = 'r' + else: + logger.warning( + 'Cannot determine compression type for file %s', filename, + ) + mode = 'r:*' + tar = tarfile.open(filename, mode) + try: + # note: python<=2.5 doesn't seem to know about pax headers, filter them + leading = has_leading_dir([ + member.name for member in tar.getmembers() + if member.name != 'pax_global_header' + ]) + for member in tar.getmembers(): + fn = member.name + if fn == 'pax_global_header': + continue + if leading: + fn = split_leading_dir(fn)[1] + path = os.path.join(location, fn) + if member.isdir(): + ensure_dir(path) + elif member.issym(): + try: + tar._extract_member(member, path) + except Exception as exc: + # Some corrupt tar files seem to produce this + # (specifically bad symlinks) + logger.warning( + 'In the tar file %s the member %s is invalid: %s', + filename, member.name, exc, + ) + continue + else: + try: + fp = tar.extractfile(member) + except (KeyError, AttributeError) as exc: + # Some corrupt tar files seem to produce this + # (specifically bad symlinks) + logger.warning( + 'In the tar file %s the member %s is invalid: %s', + filename, member.name, exc, + ) + continue + ensure_dir(os.path.dirname(path)) + with open(path, 'wb') as destfp: + shutil.copyfileobj(fp, destfp) + fp.close() + # Update the timestamp (useful for cython compiled files) + tar.utime(member, path) + # member have any execute permissions for user/group/world? + if member.mode & 0o111: + # make dest file have execute for user/group/world + # no-op on windows per python docs + os.chmod(path, (0o777 - current_umask() | 0o111)) + finally: + tar.close() + + +def unpack_file(filename, location, content_type, link): + filename = os.path.realpath(filename) + if (content_type == 'application/zip' or + filename.lower().endswith(ZIP_EXTENSIONS) or + zipfile.is_zipfile(filename)): + unzip_file( + filename, + location, + flatten=not filename.endswith('.whl') + ) + elif (content_type == 'application/x-gzip' or + tarfile.is_tarfile(filename) or + filename.lower().endswith( + TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS)): + untar_file(filename, location) + elif (content_type and content_type.startswith('text/html') and + is_svn_page(file_contents(filename))): + # We don't really care about this + from pip._internal.vcs.subversion import Subversion + Subversion('svn+' + link.url).unpack(location) + else: + # FIXME: handle? + # FIXME: magic signatures? + logger.critical( + 'Cannot unpack file %s (downloaded from %s, content-type: %s); ' + 'cannot detect archive format', + filename, location, content_type, + ) + raise InstallationError( + 'Cannot determine archive format of %s' % location + ) + + +def call_subprocess(cmd, show_stdout=True, cwd=None, + on_returncode='raise', + command_desc=None, + extra_environ=None, unset_environ=None, spinner=None): + """ + Args: + unset_environ: an iterable of environment variable names to unset + prior to calling subprocess.Popen(). + """ + if unset_environ is None: + unset_environ = [] + # This function's handling of subprocess output is confusing and I + # previously broke it terribly, so as penance I will write a long comment + # explaining things. + # + # The obvious thing that affects output is the show_stdout= + # kwarg. show_stdout=True means, let the subprocess write directly to our + # stdout. Even though it is nominally the default, it is almost never used + # inside pip (and should not be used in new code without a very good + # reason); as of 2016-02-22 it is only used in a few places inside the VCS + # wrapper code. Ideally we should get rid of it entirely, because it + # creates a lot of complexity here for a rarely used feature. + # + # Most places in pip set show_stdout=False. What this means is: + # - We connect the child stdout to a pipe, which we read. + # - By default, we hide the output but show a spinner -- unless the + # subprocess exits with an error, in which case we show the output. + # - If the --verbose option was passed (= loglevel is DEBUG), then we show + # the output unconditionally. (But in this case we don't want to show + # the output a second time if it turns out that there was an error.) + # + # stderr is always merged with stdout (even if show_stdout=True). + if show_stdout: + stdout = None + else: + stdout = subprocess.PIPE + if command_desc is None: + cmd_parts = [] + for part in cmd: + if ' ' in part or '\n' in part or '"' in part or "'" in part: + part = '"%s"' % part.replace('"', '\\"') + cmd_parts.append(part) + command_desc = ' '.join(cmd_parts) + logger.debug("Running command %s", command_desc) + env = os.environ.copy() + if extra_environ: + env.update(extra_environ) + for name in unset_environ: + env.pop(name, None) + try: + proc = subprocess.Popen( + cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, + stdout=stdout, cwd=cwd, env=env, + ) + proc.stdin.close() + except Exception as exc: + logger.critical( + "Error %s while executing command %s", exc, command_desc, + ) + raise + all_output = [] + if stdout is not None: + while True: + line = console_to_str(proc.stdout.readline()) + if not line: + break + line = line.rstrip() + all_output.append(line + '\n') + if logger.getEffectiveLevel() <= std_logging.DEBUG: + # Show the line immediately + logger.debug(line) + else: + # Update the spinner + if spinner is not None: + spinner.spin() + try: + proc.wait() + finally: + if proc.stdout: + proc.stdout.close() + if spinner is not None: + if proc.returncode: + spinner.finish("error") + else: + spinner.finish("done") + if proc.returncode: + if on_returncode == 'raise': + if (logger.getEffectiveLevel() > std_logging.DEBUG and + not show_stdout): + logger.info( + 'Complete output from command %s:', command_desc, + ) + logger.info( + ''.join(all_output) + + '\n----------------------------------------' + ) + raise InstallationError( + 'Command "%s" failed with error code %s in %s' + % (command_desc, proc.returncode, cwd)) + elif on_returncode == 'warn': + logger.warning( + 'Command "%s" had error code %s in %s', + command_desc, proc.returncode, cwd, + ) + elif on_returncode == 'ignore': + pass + else: + raise ValueError('Invalid value: on_returncode=%s' % + repr(on_returncode)) + if not show_stdout: + return ''.join(all_output) + + +def read_text_file(filename): + """Return the contents of *filename*. + + Try to decode the file contents with utf-8, the preferred system encoding + (e.g., cp1252 on some Windows machines), and latin1, in that order. + Decoding a byte string with latin1 will never raise an error. In the worst + case, the returned string will contain some garbage characters. + + """ + with open(filename, 'rb') as fp: + data = fp.read() + + encodings = ['utf-8', locale.getpreferredencoding(False), 'latin1'] + for enc in encodings: + try: + data = data.decode(enc) + except UnicodeDecodeError: + continue + break + + assert type(data) != bytes # Latin1 should have worked. + return data + + +def _make_build_dir(build_dir): + os.makedirs(build_dir) + write_delete_marker_file(build_dir) + + +class FakeFile(object): + """Wrap a list of lines in an object with readline() to make + ConfigParser happy.""" + def __init__(self, lines): + self._gen = (l for l in lines) + + def readline(self): + try: + try: + return next(self._gen) + except NameError: + return self._gen.next() + except StopIteration: + return '' + + def __iter__(self): + return self._gen + + +class StreamWrapper(StringIO): + + @classmethod + def from_stream(cls, orig_stream): + cls.orig_stream = orig_stream + return cls() + + # compileall.compile_dir() needs stdout.encoding to print to stdout + @property + def encoding(self): + return self.orig_stream.encoding + + +@contextlib.contextmanager +def captured_output(stream_name): + """Return a context manager used by captured_stdout/stdin/stderr + that temporarily replaces the sys stream *stream_name* with a StringIO. + + Taken from Lib/support/__init__.py in the CPython repo. + """ + orig_stdout = getattr(sys, stream_name) + setattr(sys, stream_name, StreamWrapper.from_stream(orig_stdout)) + try: + yield getattr(sys, stream_name) + finally: + setattr(sys, stream_name, orig_stdout) + + +def captured_stdout(): + """Capture the output of sys.stdout: + + with captured_stdout() as stdout: + print('hello') + self.assertEqual(stdout.getvalue(), 'hello\n') + + Taken from Lib/support/__init__.py in the CPython repo. + """ + return captured_output('stdout') + + +class cached_property(object): + """A property that is only computed once per instance and then replaces + itself with an ordinary attribute. Deleting the attribute resets the + property. + + Source: https://github.com/bottlepy/bottle/blob/0.11.5/bottle.py#L175 + """ + + def __init__(self, func): + self.__doc__ = getattr(func, '__doc__') + self.func = func + + def __get__(self, obj, cls): + if obj is None: + # We're being accessed from the class itself, not from an object + return self + value = obj.__dict__[self.func.__name__] = self.func(obj) + return value + + +def get_installed_version(dist_name, lookup_dirs=None): + """Get the installed version of dist_name avoiding pkg_resources cache""" + # Create a requirement that we'll look for inside of setuptools. + req = pkg_resources.Requirement.parse(dist_name) + + # We want to avoid having this cached, so we need to construct a new + # working set each time. + if lookup_dirs is None: + working_set = pkg_resources.WorkingSet() + else: + working_set = pkg_resources.WorkingSet(lookup_dirs) + + # Get the installed distribution from our working set + dist = working_set.find(req) + + # Check to see if we got an installed distribution or not, if we did + # we want to return it's version. + return dist.version if dist else None + + +def consume(iterator): + """Consume an iterable at C speed.""" + deque(iterator, maxlen=0) + + +# Simulates an enum +def enum(*sequential, **named): + enums = dict(zip(sequential, range(len(sequential))), **named) + reverse = {value: key for key, value in enums.items()} + enums['reverse_mapping'] = reverse + return type('Enum', (), enums) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/outdated.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/outdated.py new file mode 100644 index 0000000..f8f6466 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/outdated.py @@ -0,0 +1,163 @@ +from __future__ import absolute_import + +import datetime +import json +import logging +import os.path +import sys + +from pip._vendor import lockfile +from pip._vendor.packaging import version as packaging_version + +from pip._internal.compat import WINDOWS +from pip._internal.index import PackageFinder +from pip._internal.locations import USER_CACHE_DIR, running_under_virtualenv +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.misc import ensure_dir, get_installed_version + +SELFCHECK_DATE_FMT = "%Y-%m-%dT%H:%M:%SZ" + + +logger = logging.getLogger(__name__) + + +class VirtualenvSelfCheckState(object): + def __init__(self): + self.statefile_path = os.path.join(sys.prefix, "pip-selfcheck.json") + + # Load the existing state + try: + with open(self.statefile_path) as statefile: + self.state = json.load(statefile) + except (IOError, ValueError): + self.state = {} + + def save(self, pypi_version, current_time): + # Attempt to write out our version check file + with open(self.statefile_path, "w") as statefile: + json.dump( + { + "last_check": current_time.strftime(SELFCHECK_DATE_FMT), + "pypi_version": pypi_version, + }, + statefile, + sort_keys=True, + separators=(",", ":") + ) + + +class GlobalSelfCheckState(object): + def __init__(self): + self.statefile_path = os.path.join(USER_CACHE_DIR, "selfcheck.json") + + # Load the existing state + try: + with open(self.statefile_path) as statefile: + self.state = json.load(statefile)[sys.prefix] + except (IOError, ValueError, KeyError): + self.state = {} + + def save(self, pypi_version, current_time): + # Check to make sure that we own the directory + if not check_path_owner(os.path.dirname(self.statefile_path)): + return + + # Now that we've ensured the directory is owned by this user, we'll go + # ahead and make sure that all our directories are created. + ensure_dir(os.path.dirname(self.statefile_path)) + + # Attempt to write out our version check file + with lockfile.LockFile(self.statefile_path): + if os.path.exists(self.statefile_path): + with open(self.statefile_path) as statefile: + state = json.load(statefile) + else: + state = {} + + state[sys.prefix] = { + "last_check": current_time.strftime(SELFCHECK_DATE_FMT), + "pypi_version": pypi_version, + } + + with open(self.statefile_path, "w") as statefile: + json.dump(state, statefile, sort_keys=True, + separators=(",", ":")) + + +def load_selfcheck_statefile(): + if running_under_virtualenv(): + return VirtualenvSelfCheckState() + else: + return GlobalSelfCheckState() + + +def pip_version_check(session, options): + """Check for an update for pip. + + Limit the frequency of checks to once per week. State is stored either in + the active virtualenv or in the user's USER_CACHE_DIR keyed off the prefix + of the pip script path. + """ + installed_version = get_installed_version("pip") + if not installed_version: + return + + pip_version = packaging_version.parse(installed_version) + pypi_version = None + + try: + state = load_selfcheck_statefile() + + current_time = datetime.datetime.utcnow() + # Determine if we need to refresh the state + if "last_check" in state.state and "pypi_version" in state.state: + last_check = datetime.datetime.strptime( + state.state["last_check"], + SELFCHECK_DATE_FMT + ) + if (current_time - last_check).total_seconds() < 7 * 24 * 60 * 60: + pypi_version = state.state["pypi_version"] + + # Refresh the version if we need to or just see if we need to warn + if pypi_version is None: + # Lets use PackageFinder to see what the latest pip version is + finder = PackageFinder( + find_links=options.find_links, + index_urls=[options.index_url] + options.extra_index_urls, + allow_all_prereleases=False, # Explicitly set to False + trusted_hosts=options.trusted_hosts, + process_dependency_links=options.process_dependency_links, + session=session, + ) + all_candidates = finder.find_all_candidates("pip") + if not all_candidates: + return + pypi_version = str( + max(all_candidates, key=lambda c: c.version).version + ) + + # save that we've performed a check + state.save(pypi_version, current_time) + + remote_version = packaging_version.parse(pypi_version) + + # Determine if our pypi_version is older + if (pip_version < remote_version and + pip_version.base_version != remote_version.base_version): + # Advise "python -m pip" on Windows to avoid issues + # with overwriting pip.exe. + if WINDOWS: + pip_cmd = "python -m pip" + else: + pip_cmd = "pip" + logger.warning( + "You are using pip version %s, however version %s is " + "available.\nYou should consider upgrading via the " + "'%s install --upgrade pip' command.", + pip_version, pypi_version, pip_cmd + ) + except Exception: + logger.debug( + "There was an error checking the latest version of pip", + exc_info=True, + ) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/packaging.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/packaging.py new file mode 100644 index 0000000..5f9bb93 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/packaging.py @@ -0,0 +1,70 @@ +from __future__ import absolute_import + +import logging +import sys +from email.parser import FeedParser # type: ignore + +from pip._vendor import pkg_resources +from pip._vendor.packaging import specifiers, version + +from pip._internal import exceptions + +logger = logging.getLogger(__name__) + + +def check_requires_python(requires_python): + """ + Check if the python version in use match the `requires_python` specifier. + + Returns `True` if the version of python in use matches the requirement. + Returns `False` if the version of python in use does not matches the + requirement. + + Raises an InvalidSpecifier if `requires_python` have an invalid format. + """ + if requires_python is None: + # The package provides no information + return True + requires_python_specifier = specifiers.SpecifierSet(requires_python) + + # We only use major.minor.micro + python_version = version.parse('.'.join(map(str, sys.version_info[:3]))) + return python_version in requires_python_specifier + + +def get_metadata(dist): + if (isinstance(dist, pkg_resources.DistInfoDistribution) and + dist.has_metadata('METADATA')): + return dist.get_metadata('METADATA') + elif dist.has_metadata('PKG-INFO'): + return dist.get_metadata('PKG-INFO') + + +def check_dist_requires_python(dist): + metadata = get_metadata(dist) + feed_parser = FeedParser() + feed_parser.feed(metadata) + pkg_info_dict = feed_parser.close() + requires_python = pkg_info_dict.get('Requires-Python') + try: + if not check_requires_python(requires_python): + raise exceptions.UnsupportedPythonVersion( + "%s requires Python '%s' but the running Python is %s" % ( + dist.project_name, + requires_python, + '.'.join(map(str, sys.version_info[:3])),) + ) + except specifiers.InvalidSpecifier as e: + logger.warning( + "Package %s has an invalid Requires-Python entry %s - %s", + dist.project_name, requires_python, e, + ) + return + + +def get_installer(dist): + if dist.has_metadata('INSTALLER'): + for line in dist.get_metadata_lines('INSTALLER'): + if line.strip(): + return line.strip() + return '' diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/setuptools_build.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/setuptools_build.py new file mode 100644 index 0000000..03973e9 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/setuptools_build.py @@ -0,0 +1,8 @@ +# Shim to wrap setup.py invocation with setuptools +SETUPTOOLS_SHIM = ( + "import setuptools, tokenize;__file__=%r;" + "f=getattr(tokenize, 'open', open)(__file__);" + "code=f.read().replace('\\r\\n', '\\n');" + "f.close();" + "exec(compile(code, __file__, 'exec'))" +) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/temp_dir.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/temp_dir.py new file mode 100644 index 0000000..edc506b --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/temp_dir.py @@ -0,0 +1,82 @@ +from __future__ import absolute_import + +import logging +import os.path +import tempfile + +from pip._internal.utils.misc import rmtree + +logger = logging.getLogger(__name__) + + +class TempDirectory(object): + """Helper class that owns and cleans up a temporary directory. + + This class can be used as a context manager or as an OO representation of a + temporary directory. + + Attributes: + path + Location to the created temporary directory or None + delete + Whether the directory should be deleted when exiting + (when used as a contextmanager) + + Methods: + create() + Creates a temporary directory and stores its path in the path + attribute. + cleanup() + Deletes the temporary directory and sets path attribute to None + + When used as a context manager, a temporary directory is created on + entering the context and, if the delete attribute is True, on exiting the + context the created directory is deleted. + """ + + def __init__(self, path=None, delete=None, kind="temp"): + super(TempDirectory, self).__init__() + + if path is None and delete is None: + # If we were not given an explicit directory, and we were not given + # an explicit delete option, then we'll default to deleting. + delete = True + + self.path = path + self.delete = delete + self.kind = kind + + def __repr__(self): + return "<{} {!r}>".format(self.__class__.__name__, self.path) + + def __enter__(self): + self.create() + return self + + def __exit__(self, exc, value, tb): + if self.delete: + self.cleanup() + + def create(self): + """Create a temporary directory and store it's path in self.path + """ + if self.path is not None: + logger.debug( + "Skipped creation of temporary directory: {}".format(self.path) + ) + return + # We realpath here because some systems have their default tmpdir + # symlinked to another directory. This tends to confuse build + # scripts, so we canonicalize the path by traversing potential + # symlinks here. + self.path = os.path.realpath( + tempfile.mkdtemp(prefix="pip-{}-".format(self.kind)) + ) + logger.debug("Created temporary directory: {}".format(self.path)) + + def cleanup(self): + """Remove the temporary directory created and reset state + """ + if self.path is not None and os.path.exists(self.path): + rmtree(self.path) + self.path = None diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/typing.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/typing.py new file mode 100644 index 0000000..cb57f8f --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/typing.py @@ -0,0 +1,29 @@ +"""For neatly implementing static typing in pip. + +`mypy` - the static type analysis tool we use - uses the `typing` module, which +provides core functionality fundamental to mypy's functioning. + +Generally, `typing` would be imported at runtime and used in that fashion - +it acts as a no-op at runtime and does not have any run-time overhead by +design. + +As it turns out, `typing` is not vendorable - it uses separate sources for +Python 2/Python 3. Thus, this codebase can not expect it to be present. +To work around this, mypy allows the typing import to be behind a False-y +optional to prevent it from running at runtime and type-comments can be used +to remove the need for the types to be accessible directly during runtime. + +This module provides the False-y guard in a nicely named fashion so that a +curious maintainer can reach here to read this. + +In pip, all static-typing related imports should be guarded as follows: + + from pip.utils.typing import MYPY_CHECK_RUNNING + + if MYPY_CHECK_RUNNING: + from typing import ... + +Ref: https://github.com/python/mypy/issues/3216 +""" + +MYPY_CHECK_RUNNING = False diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/ui.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/ui.py new file mode 100644 index 0000000..8ade1e2 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/ui.py @@ -0,0 +1,421 @@ +from __future__ import absolute_import, division + +import contextlib +import itertools +import logging +import sys +import time +from signal import SIGINT, default_int_handler, signal + +from pip._vendor import six +from pip._vendor.progress.bar import ( + Bar, ChargingBar, FillingCirclesBar, FillingSquaresBar, IncrementalBar, + ShadyBar, +) +from pip._vendor.progress.helpers import HIDE_CURSOR, SHOW_CURSOR, WritelnMixin +from pip._vendor.progress.spinner import Spinner + +from pip._internal.compat import WINDOWS +from pip._internal.utils.logging import get_indentation +from pip._internal.utils.misc import format_size +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any + +try: + from pip._vendor import colorama +# Lots of different errors can come from this, including SystemError and +# ImportError. +except Exception: + colorama = None + +logger = logging.getLogger(__name__) + + +def _select_progress_class(preferred, fallback): + encoding = getattr(preferred.file, "encoding", None) + + # If we don't know what encoding this file is in, then we'll just assume + # that it doesn't support unicode and use the ASCII bar. + if not encoding: + return fallback + + # Collect all of the possible characters we want to use with the preferred + # bar. + characters = [ + getattr(preferred, "empty_fill", six.text_type()), + getattr(preferred, "fill", six.text_type()), + ] + characters += list(getattr(preferred, "phases", [])) + + # Try to decode the characters we're using for the bar using the encoding + # of the given file, if this works then we'll assume that we can use the + # fancier bar and if not we'll fall back to the plaintext bar. + try: + six.text_type().join(characters).encode(encoding) + except UnicodeEncodeError: + return fallback + else: + return preferred + + +_BaseBar = _select_progress_class(IncrementalBar, Bar) # type: Any + + +class InterruptibleMixin(object): + """ + Helper to ensure that self.finish() gets called on keyboard interrupt. + + This allows downloads to be interrupted without leaving temporary state + (like hidden cursors) behind. + + This class is similar to the progress library's existing SigIntMixin + helper, but as of version 1.2, that helper has the following problems: + + 1. It calls sys.exit(). + 2. It discards the existing SIGINT handler completely. + 3. It leaves its own handler in place even after an uninterrupted finish, + which will have unexpected delayed effects if the user triggers an + unrelated keyboard interrupt some time after a progress-displaying + download has already completed, for example. + """ + + def __init__(self, *args, **kwargs): + """ + Save the original SIGINT handler for later. + """ + super(InterruptibleMixin, self).__init__(*args, **kwargs) + + self.original_handler = signal(SIGINT, self.handle_sigint) + + # If signal() returns None, the previous handler was not installed from + # Python, and we cannot restore it. This probably should not happen, + # but if it does, we must restore something sensible instead, at least. + # The least bad option should be Python's default SIGINT handler, which + # just raises KeyboardInterrupt. + if self.original_handler is None: + self.original_handler = default_int_handler + + def finish(self): + """ + Restore the original SIGINT handler after finishing. + + This should happen regardless of whether the progress display finishes + normally, or gets interrupted. + """ + super(InterruptibleMixin, self).finish() + signal(SIGINT, self.original_handler) + + def handle_sigint(self, signum, frame): + """ + Call self.finish() before delegating to the original SIGINT handler. + + This handler should only be in place while the progress display is + active. + """ + self.finish() + self.original_handler(signum, frame) + + +class SilentBar(Bar): + + def update(self): + pass + + +class BlueEmojiBar(IncrementalBar): + + suffix = "%(percent)d%%" + bar_prefix = " " + bar_suffix = " " + phases = (u"\U0001F539", u"\U0001F537", u"\U0001F535") # type: Any + + +class DownloadProgressMixin(object): + + def __init__(self, *args, **kwargs): + super(DownloadProgressMixin, self).__init__(*args, **kwargs) + self.message = (" " * (get_indentation() + 2)) + self.message + + @property + def downloaded(self): + return format_size(self.index) + + @property + def download_speed(self): + # Avoid zero division errors... + if self.avg == 0.0: + return "..." + return format_size(1 / self.avg) + "/s" + + @property + def pretty_eta(self): + if self.eta: + return "eta %s" % self.eta_td + return "" + + def iter(self, it, n=1): + for x in it: + yield x + self.next(n) + self.finish() + + +class WindowsMixin(object): + + def __init__(self, *args, **kwargs): + # The Windows terminal does not support the hide/show cursor ANSI codes + # even with colorama. So we'll ensure that hide_cursor is False on + # Windows. + # This call neds to go before the super() call, so that hide_cursor + # is set in time. The base progress bar class writes the "hide cursor" + # code to the terminal in its init, so if we don't set this soon + # enough, we get a "hide" with no corresponding "show"... + if WINDOWS and self.hide_cursor: + self.hide_cursor = False + + super(WindowsMixin, self).__init__(*args, **kwargs) + + # Check if we are running on Windows and we have the colorama module, + # if we do then wrap our file with it. + if WINDOWS and colorama: + self.file = colorama.AnsiToWin32(self.file) + # The progress code expects to be able to call self.file.isatty() + # but the colorama.AnsiToWin32() object doesn't have that, so we'll + # add it. + self.file.isatty = lambda: self.file.wrapped.isatty() + # The progress code expects to be able to call self.file.flush() + # but the colorama.AnsiToWin32() object doesn't have that, so we'll + # add it. + self.file.flush = lambda: self.file.wrapped.flush() + + +class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin, + DownloadProgressMixin): + + file = sys.stdout + message = "%(percent)d%%" + suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s" + +# NOTE: The "type: ignore" comments on the following classes are there to +# work around https://github.com/python/typing/issues/241 + + +class DefaultDownloadProgressBar(BaseDownloadProgressBar, + _BaseBar): # type: ignore + pass + + +class DownloadSilentBar(BaseDownloadProgressBar, SilentBar): # type: ignore + pass + + +class DownloadIncrementalBar(BaseDownloadProgressBar, # type: ignore + IncrementalBar): + pass + + +class DownloadChargingBar(BaseDownloadProgressBar, # type: ignore + ChargingBar): + pass + + +class DownloadShadyBar(BaseDownloadProgressBar, ShadyBar): # type: ignore + pass + + +class DownloadFillingSquaresBar(BaseDownloadProgressBar, # type: ignore + FillingSquaresBar): + pass + + +class DownloadFillingCirclesBar(BaseDownloadProgressBar, # type: ignore + FillingCirclesBar): + pass + + +class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar, # type: ignore + BlueEmojiBar): + pass + + +class DownloadProgressSpinner(WindowsMixin, InterruptibleMixin, + DownloadProgressMixin, WritelnMixin, Spinner): + + file = sys.stdout + suffix = "%(downloaded)s %(download_speed)s" + + def next_phase(self): + if not hasattr(self, "_phaser"): + self._phaser = itertools.cycle(self.phases) + return next(self._phaser) + + def update(self): + message = self.message % self + phase = self.next_phase() + suffix = self.suffix % self + line = ''.join([ + message, + " " if message else "", + phase, + " " if suffix else "", + suffix, + ]) + + self.writeln(line) + + +BAR_TYPES = { + "off": (DownloadSilentBar, DownloadSilentBar), + "on": (DefaultDownloadProgressBar, DownloadProgressSpinner), + "ascii": (DownloadIncrementalBar, DownloadProgressSpinner), + "pretty": (DownloadFillingCirclesBar, DownloadProgressSpinner), + "emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner) +} + + +def DownloadProgressProvider(progress_bar, max=None): + if max is None or max == 0: + return BAR_TYPES[progress_bar][1]().iter + else: + return BAR_TYPES[progress_bar][0](max=max).iter + + +################################################################ +# Generic "something is happening" spinners +# +# We don't even try using progress.spinner.Spinner here because it's actually +# simpler to reimplement from scratch than to coerce their code into doing +# what we need. +################################################################ + +@contextlib.contextmanager +def hidden_cursor(file): + # The Windows terminal does not support the hide/show cursor ANSI codes, + # even via colorama. So don't even try. + if WINDOWS: + yield + # We don't want to clutter the output with control characters if we're + # writing to a file, or if the user is running with --quiet. + # See https://github.com/pypa/pip/issues/3418 + elif not file.isatty() or logger.getEffectiveLevel() > logging.INFO: + yield + else: + file.write(HIDE_CURSOR) + try: + yield + finally: + file.write(SHOW_CURSOR) + + +class RateLimiter(object): + def __init__(self, min_update_interval_seconds): + self._min_update_interval_seconds = min_update_interval_seconds + self._last_update = 0 + + def ready(self): + now = time.time() + delta = now - self._last_update + return delta >= self._min_update_interval_seconds + + def reset(self): + self._last_update = time.time() + + +class InteractiveSpinner(object): + def __init__(self, message, file=None, spin_chars="-\\|/", + # Empirically, 8 updates/second looks nice + min_update_interval_seconds=0.125): + self._message = message + if file is None: + file = sys.stdout + self._file = file + self._rate_limiter = RateLimiter(min_update_interval_seconds) + self._finished = False + + self._spin_cycle = itertools.cycle(spin_chars) + + self._file.write(" " * get_indentation() + self._message + " ... ") + self._width = 0 + + def _write(self, status): + assert not self._finished + # Erase what we wrote before by backspacing to the beginning, writing + # spaces to overwrite the old text, and then backspacing again + backup = "\b" * self._width + self._file.write(backup + " " * self._width + backup) + # Now we have a blank slate to add our status + self._file.write(status) + self._width = len(status) + self._file.flush() + self._rate_limiter.reset() + + def spin(self): + if self._finished: + return + if not self._rate_limiter.ready(): + return + self._write(next(self._spin_cycle)) + + def finish(self, final_status): + if self._finished: + return + self._write(final_status) + self._file.write("\n") + self._file.flush() + self._finished = True + + +# Used for dumb terminals, non-interactive installs (no tty), etc. +# We still print updates occasionally (once every 60 seconds by default) to +# act as a keep-alive for systems like Travis-CI that take lack-of-output as +# an indication that a task has frozen. +class NonInteractiveSpinner(object): + def __init__(self, message, min_update_interval_seconds=60): + self._message = message + self._finished = False + self._rate_limiter = RateLimiter(min_update_interval_seconds) + self._update("started") + + def _update(self, status): + assert not self._finished + self._rate_limiter.reset() + logger.info("%s: %s", self._message, status) + + def spin(self): + if self._finished: + return + if not self._rate_limiter.ready(): + return + self._update("still running...") + + def finish(self, final_status): + if self._finished: + return + self._update("finished with status '%s'" % (final_status,)) + self._finished = True + + +@contextlib.contextmanager +def open_spinner(message): + # Interactive spinner goes directly to sys.stdout rather than being routed + # through the logging system, but it acts like it has level INFO, + # i.e. it's only displayed if we're at level INFO or better. + # Non-interactive spinner goes through the logging system, so it is always + # in sync with logging configuration. + if sys.stdout.isatty() and logger.getEffectiveLevel() <= logging.INFO: + spinner = InteractiveSpinner(message) + else: + spinner = NonInteractiveSpinner(message) + try: + with hidden_cursor(sys.stdout): + yield spinner + except KeyboardInterrupt: + spinner.finish("canceled") + raise + except Exception: + spinner.finish("error") + raise + else: + spinner.finish("done") diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__init__.py new file mode 100644 index 0000000..8b159cb --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__init__.py @@ -0,0 +1,471 @@ +"""Handles all VCS (version control) support""" +from __future__ import absolute_import + +import copy +import errno +import logging +import os +import shutil +import sys + +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.exceptions import BadCommand +from pip._internal.utils.misc import ( + display_path, backup_dir, call_subprocess, rmtree, ask_path_exists, +) +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Dict, Optional, Tuple + from pip._internal.basecommand import Command + +__all__ = ['vcs', 'get_src_requirement'] + + +logger = logging.getLogger(__name__) + + +class RevOptions(object): + + """ + Encapsulates a VCS-specific revision to install, along with any VCS + install options. + + Instances of this class should be treated as if immutable. + """ + + def __init__(self, vcs, rev=None, extra_args=None): + """ + Args: + vcs: a VersionControl object. + rev: the name of the revision to install. + extra_args: a list of extra options. + """ + if extra_args is None: + extra_args = [] + + self.extra_args = extra_args + self.rev = rev + self.vcs = vcs + + def __repr__(self): + return '<RevOptions {}: rev={!r}>'.format(self.vcs.name, self.rev) + + @property + def arg_rev(self): + if self.rev is None: + return self.vcs.default_arg_rev + + return self.rev + + def to_args(self): + """ + Return the VCS-specific command arguments. + """ + args = [] + rev = self.arg_rev + if rev is not None: + args += self.vcs.get_base_rev_args(rev) + args += self.extra_args + + return args + + def to_display(self): + if not self.rev: + return '' + + return ' (to revision {})'.format(self.rev) + + def make_new(self, rev): + """ + Make a copy of the current instance, but with a new rev. + + Args: + rev: the name of the revision for the new object. + """ + return self.vcs.make_rev_options(rev, extra_args=self.extra_args) + + +class VcsSupport(object): + _registry = {} # type: Dict[str, Command] + schemes = ['ssh', 'git', 'hg', 'bzr', 'sftp', 'svn'] + + def __init__(self): + # Register more schemes with urlparse for various version control + # systems + urllib_parse.uses_netloc.extend(self.schemes) + # Python >= 2.7.4, 3.3 doesn't have uses_fragment + if getattr(urllib_parse, 'uses_fragment', None): + urllib_parse.uses_fragment.extend(self.schemes) + super(VcsSupport, self).__init__() + + def __iter__(self): + return self._registry.__iter__() + + @property + def backends(self): + return list(self._registry.values()) + + @property + def dirnames(self): + return [backend.dirname for backend in self.backends] + + @property + def all_schemes(self): + schemes = [] + for backend in self.backends: + schemes.extend(backend.schemes) + return schemes + + def register(self, cls): + if not hasattr(cls, 'name'): + logger.warning('Cannot register VCS %s', cls.__name__) + return + if cls.name not in self._registry: + self._registry[cls.name] = cls + logger.debug('Registered VCS backend: %s', cls.name) + + def unregister(self, cls=None, name=None): + if name in self._registry: + del self._registry[name] + elif cls in self._registry.values(): + del self._registry[cls.name] + else: + logger.warning('Cannot unregister because no class or name given') + + def get_backend_name(self, location): + """ + Return the name of the version control backend if found at given + location, e.g. vcs.get_backend_name('/path/to/vcs/checkout') + """ + for vc_type in self._registry.values(): + if vc_type.controls_location(location): + logger.debug('Determine that %s uses VCS: %s', + location, vc_type.name) + return vc_type.name + return None + + def get_backend(self, name): + name = name.lower() + if name in self._registry: + return self._registry[name] + + def get_backend_from_location(self, location): + vc_type = self.get_backend_name(location) + if vc_type: + return self.get_backend(vc_type) + return None + + +vcs = VcsSupport() + + +class VersionControl(object): + name = '' + dirname = '' + # List of supported schemes for this Version Control + schemes = () # type: Tuple[str, ...] + # Iterable of environment variable names to pass to call_subprocess(). + unset_environ = () # type: Tuple[str, ...] + default_arg_rev = None # type: Optional[str] + + def __init__(self, url=None, *args, **kwargs): + self.url = url + super(VersionControl, self).__init__(*args, **kwargs) + + def get_base_rev_args(self, rev): + """ + Return the base revision arguments for a vcs command. + + Args: + rev: the name of a revision to install. Cannot be None. + """ + raise NotImplementedError + + def make_rev_options(self, rev=None, extra_args=None): + """ + Return a RevOptions object. + + Args: + rev: the name of a revision to install. + extra_args: a list of extra options. + """ + return RevOptions(self, rev, extra_args=extra_args) + + def _is_local_repository(self, repo): + """ + posix absolute paths start with os.path.sep, + win32 ones start with drive (like c:\\folder) + """ + drive, tail = os.path.splitdrive(repo) + return repo.startswith(os.path.sep) or drive + + # See issue #1083 for why this method was introduced: + # https://github.com/pypa/pip/issues/1083 + def translate_egg_surname(self, surname): + # For example, Django has branches of the form "stable/1.7.x". + return surname.replace('/', '_') + + def export(self, location): + """ + Export the repository at the url to the destination location + i.e. only download the files, without vcs informations + """ + raise NotImplementedError + + def get_url_rev(self): + """ + Returns the correct repository URL and revision by parsing the given + repository URL + """ + error_message = ( + "Sorry, '%s' is a malformed VCS url. " + "The format is <vcs>+<protocol>://<url>, " + "e.g. svn+http://myrepo/svn/MyApp#egg=MyApp" + ) + assert '+' in self.url, error_message % self.url + url = self.url.split('+', 1)[1] + scheme, netloc, path, query, frag = urllib_parse.urlsplit(url) + rev = None + if '@' in path: + path, rev = path.rsplit('@', 1) + url = urllib_parse.urlunsplit((scheme, netloc, path, query, '')) + return url, rev + + def get_info(self, location): + """ + Returns (url, revision), where both are strings + """ + assert not location.rstrip('/').endswith(self.dirname), \ + 'Bad directory: %s' % location + return self.get_url(location), self.get_revision(location) + + def normalize_url(self, url): + """ + Normalize a URL for comparison by unquoting it and removing any + trailing slash. + """ + return urllib_parse.unquote(url).rstrip('/') + + def compare_urls(self, url1, url2): + """ + Compare two repo URLs for identity, ignoring incidental differences. + """ + return (self.normalize_url(url1) == self.normalize_url(url2)) + + def obtain(self, dest): + """ + Called when installing or updating an editable package, takes the + source path of the checkout. + """ + raise NotImplementedError + + def switch(self, dest, url, rev_options): + """ + Switch the repo at ``dest`` to point to ``URL``. + + Args: + rev_options: a RevOptions object. + """ + raise NotImplementedError + + def update(self, dest, rev_options): + """ + Update an already-existing repo to the given ``rev_options``. + + Args: + rev_options: a RevOptions object. + """ + raise NotImplementedError + + def is_commit_id_equal(self, dest, name): + """ + Return whether the id of the current commit equals the given name. + + Args: + dest: the repository directory. + name: a string name. + """ + raise NotImplementedError + + def check_destination(self, dest, url, rev_options): + """ + Prepare a location to receive a checkout/clone. + + Return True if the location is ready for (and requires) a + checkout/clone, False otherwise. + + Args: + rev_options: a RevOptions object. + """ + checkout = True + prompt = False + rev_display = rev_options.to_display() + if os.path.exists(dest): + checkout = False + if os.path.exists(os.path.join(dest, self.dirname)): + existing_url = self.get_url(dest) + if self.compare_urls(existing_url, url): + logger.debug( + '%s in %s exists, and has correct URL (%s)', + self.repo_name.title(), + display_path(dest), + url, + ) + if not self.is_commit_id_equal(dest, rev_options.rev): + logger.info( + 'Updating %s %s%s', + display_path(dest), + self.repo_name, + rev_display, + ) + self.update(dest, rev_options) + else: + logger.info( + 'Skipping because already up-to-date.') + else: + logger.warning( + '%s %s in %s exists with URL %s', + self.name, + self.repo_name, + display_path(dest), + existing_url, + ) + prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', + ('s', 'i', 'w', 'b')) + else: + logger.warning( + 'Directory %s already exists, and is not a %s %s.', + dest, + self.name, + self.repo_name, + ) + prompt = ('(i)gnore, (w)ipe, (b)ackup ', ('i', 'w', 'b')) + if prompt: + logger.warning( + 'The plan is to install the %s repository %s', + self.name, + url, + ) + response = ask_path_exists('What to do? %s' % prompt[0], + prompt[1]) + + if response == 's': + logger.info( + 'Switching %s %s to %s%s', + self.repo_name, + display_path(dest), + url, + rev_display, + ) + self.switch(dest, url, rev_options) + elif response == 'i': + # do nothing + pass + elif response == 'w': + logger.warning('Deleting %s', display_path(dest)) + rmtree(dest) + checkout = True + elif response == 'b': + dest_dir = backup_dir(dest) + logger.warning( + 'Backing up %s to %s', display_path(dest), dest_dir, + ) + shutil.move(dest, dest_dir) + checkout = True + elif response == 'a': + sys.exit(-1) + return checkout + + def unpack(self, location): + """ + Clean up current location and download the url repository + (and vcs infos) into location + """ + if os.path.exists(location): + rmtree(location) + self.obtain(location) + + def get_src_requirement(self, dist, location): + """ + Return a string representing the requirement needed to + redownload the files currently present in location, something + like: + {repository_url}@{revision}#egg={project_name}-{version_identifier} + """ + raise NotImplementedError + + def get_url(self, location): + """ + Return the url used at location + Used in get_info or check_destination + """ + raise NotImplementedError + + def get_revision(self, location): + """ + Return the current commit id of the files at the given location. + """ + raise NotImplementedError + + def run_command(self, cmd, show_stdout=True, cwd=None, + on_returncode='raise', + command_desc=None, + extra_environ=None, spinner=None): + """ + Run a VCS subcommand + This is simply a wrapper around call_subprocess that adds the VCS + command name, and checks that the VCS is available + """ + cmd = [self.name] + cmd + try: + return call_subprocess(cmd, show_stdout, cwd, + on_returncode, + command_desc, extra_environ, + unset_environ=self.unset_environ, + spinner=spinner) + except OSError as e: + # errno.ENOENT = no such file or directory + # In other words, the VCS executable isn't available + if e.errno == errno.ENOENT: + raise BadCommand( + 'Cannot find command %r - do you have ' + '%r installed and in your ' + 'PATH?' % (self.name, self.name)) + else: + raise # re-raise exception if a different error occurred + + @classmethod + def controls_location(cls, location): + """ + Check if a location is controlled by the vcs. + It is meant to be overridden to implement smarter detection + mechanisms for specific vcs. + """ + logger.debug('Checking in %s for %s (%s)...', + location, cls.dirname, cls.name) + path = os.path.join(location, cls.dirname) + return os.path.exists(path) + + +def get_src_requirement(dist, location): + version_control = vcs.get_backend_from_location(location) + if version_control: + try: + return version_control().get_src_requirement(dist, + location) + except BadCommand: + logger.warning( + 'cannot determine version of editable source in %s ' + '(%s command not found in path)', + location, + version_control.name, + ) + return dist.as_requirement() + logger.warning( + 'cannot determine version of editable source in %s (is not SVN ' + 'checkout, Git clone, Mercurial clone or Bazaar branch)', + location, + ) + return dist.as_requirement() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/bazaar.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/bazaar.py new file mode 100644 index 0000000..b4e46e0 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/bazaar.py @@ -0,0 +1,113 @@ +from __future__ import absolute_import + +import logging +import os + +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.download import path_to_url +from pip._internal.utils.misc import display_path, rmtree +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.vcs import VersionControl, vcs + +logger = logging.getLogger(__name__) + + +class Bazaar(VersionControl): + name = 'bzr' + dirname = '.bzr' + repo_name = 'branch' + schemes = ( + 'bzr', 'bzr+http', 'bzr+https', 'bzr+ssh', 'bzr+sftp', 'bzr+ftp', + 'bzr+lp', + ) + + def __init__(self, url=None, *args, **kwargs): + super(Bazaar, self).__init__(url, *args, **kwargs) + # This is only needed for python <2.7.5 + # Register lp but do not expose as a scheme to support bzr+lp. + if getattr(urllib_parse, 'uses_fragment', None): + urllib_parse.uses_fragment.extend(['lp']) + + def get_base_rev_args(self, rev): + return ['-r', rev] + + def export(self, location): + """ + Export the Bazaar repository at the url to the destination location + """ + # Remove the location to make sure Bazaar can export it correctly + if os.path.exists(location): + rmtree(location) + + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path) + + self.run_command( + ['export', location], + cwd=temp_dir.path, show_stdout=False, + ) + + def switch(self, dest, url, rev_options): + self.run_command(['switch', url], cwd=dest) + + def update(self, dest, rev_options): + cmd_args = ['pull', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def obtain(self, dest): + url, rev = self.get_url_rev() + rev_options = self.make_rev_options(rev) + if self.check_destination(dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Checking out %s%s to %s', + url, + rev_display, + display_path(dest), + ) + cmd_args = ['branch', '-q'] + rev_options.to_args() + [url, dest] + self.run_command(cmd_args) + + def get_url_rev(self): + # hotfix the URL scheme after removing bzr+ from bzr+ssh:// readd it + url, rev = super(Bazaar, self).get_url_rev() + if url.startswith('ssh://'): + url = 'bzr+' + url + return url, rev + + def get_url(self, location): + urls = self.run_command(['info'], show_stdout=False, cwd=location) + for line in urls.splitlines(): + line = line.strip() + for x in ('checkout of branch: ', + 'parent branch: '): + if line.startswith(x): + repo = line.split(x)[1] + if self._is_local_repository(repo): + return path_to_url(repo) + return repo + return None + + def get_revision(self, location): + revision = self.run_command( + ['revno'], show_stdout=False, cwd=location, + ) + return revision.splitlines()[-1] + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if not repo: + return None + if not repo.lower().startswith('bzr:'): + repo = 'bzr+' + repo + egg_project_name = dist.egg_name().split('-', 1)[0] + current_rev = self.get_revision(location) + return '%s@%s#egg=%s' % (repo, current_rev, egg_project_name) + + def is_commit_id_equal(self, dest, name): + """Always assume the versions don't match""" + return False + + +vcs.register(Bazaar) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/git.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/git.py new file mode 100644 index 0000000..33c6806 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/git.py @@ -0,0 +1,311 @@ +from __future__ import absolute_import + +import logging +import os.path +import re + +from pip._vendor.packaging.version import parse as parse_version +from pip._vendor.six.moves.urllib import parse as urllib_parse +from pip._vendor.six.moves.urllib import request as urllib_request + +from pip._internal.compat import samefile +from pip._internal.exceptions import BadCommand +from pip._internal.utils.misc import display_path +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.vcs import VersionControl, vcs + +urlsplit = urllib_parse.urlsplit +urlunsplit = urllib_parse.urlunsplit + + +logger = logging.getLogger(__name__) + + +HASH_REGEX = re.compile('[a-fA-F0-9]{40}') + + +def looks_like_hash(sha): + return bool(HASH_REGEX.match(sha)) + + +class Git(VersionControl): + name = 'git' + dirname = '.git' + repo_name = 'clone' + schemes = ( + 'git', 'git+http', 'git+https', 'git+ssh', 'git+git', 'git+file', + ) + # Prevent the user's environment variables from interfering with pip: + # https://github.com/pypa/pip/issues/1130 + unset_environ = ('GIT_DIR', 'GIT_WORK_TREE') + default_arg_rev = 'HEAD' + + def __init__(self, url=None, *args, **kwargs): + + # Works around an apparent Git bug + # (see http://article.gmane.org/gmane.comp.version-control.git/146500) + if url: + scheme, netloc, path, query, fragment = urlsplit(url) + if scheme.endswith('file'): + initial_slashes = path[:-len(path.lstrip('/'))] + newpath = ( + initial_slashes + + urllib_request.url2pathname(path) + .replace('\\', '/').lstrip('/') + ) + url = urlunsplit((scheme, netloc, newpath, query, fragment)) + after_plus = scheme.find('+') + 1 + url = scheme[:after_plus] + urlunsplit( + (scheme[after_plus:], netloc, newpath, query, fragment), + ) + + super(Git, self).__init__(url, *args, **kwargs) + + def get_base_rev_args(self, rev): + return [rev] + + def get_git_version(self): + VERSION_PFX = 'git version ' + version = self.run_command(['version'], show_stdout=False) + if version.startswith(VERSION_PFX): + version = version[len(VERSION_PFX):].split()[0] + else: + version = '' + # get first 3 positions of the git version becasue + # on windows it is x.y.z.windows.t, and this parses as + # LegacyVersion which always smaller than a Version. + version = '.'.join(version.split('.')[:3]) + return parse_version(version) + + def export(self, location): + """Export the Git repository at the url to the destination location""" + if not location.endswith('/'): + location = location + '/' + + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path) + self.run_command( + ['checkout-index', '-a', '-f', '--prefix', location], + show_stdout=False, cwd=temp_dir.path + ) + + def get_revision_sha(self, dest, rev): + """ + Return a commit hash for the given revision if it names a remote + branch or tag. Otherwise, return None. + + Args: + dest: the repository directory. + rev: the revision name. + """ + # Pass rev to pre-filter the list. + output = self.run_command(['show-ref', rev], cwd=dest, + show_stdout=False, on_returncode='ignore') + refs = {} + for line in output.strip().splitlines(): + try: + sha, ref = line.split() + except ValueError: + # Include the offending line to simplify troubleshooting if + # this error ever occurs. + raise ValueError('unexpected show-ref line: {!r}'.format(line)) + + refs[ref] = sha + + branch_ref = 'refs/remotes/origin/{}'.format(rev) + tag_ref = 'refs/tags/{}'.format(rev) + + return refs.get(branch_ref) or refs.get(tag_ref) + + def check_rev_options(self, dest, rev_options): + """Check the revision options before checkout. + + Returns a new RevOptions object for the SHA1 of the branch or tag + if found. + + Args: + rev_options: a RevOptions object. + """ + rev = rev_options.arg_rev + sha = self.get_revision_sha(dest, rev) + + if sha is not None: + return rev_options.make_new(sha) + + # Do not show a warning for the common case of something that has + # the form of a Git commit hash. + if not looks_like_hash(rev): + logger.warning( + "Did not find branch or tag '%s', assuming revision or ref.", + rev, + ) + return rev_options + + def is_commit_id_equal(self, dest, name): + """ + Return whether the current commit hash equals the given name. + + Args: + dest: the repository directory. + name: a string name. + """ + if not name: + # Then avoid an unnecessary subprocess call. + return False + + return self.get_revision(dest) == name + + def switch(self, dest, url, rev_options): + self.run_command(['config', 'remote.origin.url', url], cwd=dest) + cmd_args = ['checkout', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + self.update_submodules(dest) + + def update(self, dest, rev_options): + # First fetch changes from the default remote + if self.get_git_version() >= parse_version('1.9.0'): + # fetch tags in addition to everything else + self.run_command(['fetch', '-q', '--tags'], cwd=dest) + else: + self.run_command(['fetch', '-q'], cwd=dest) + # Then reset to wanted revision (maybe even origin/master) + rev_options = self.check_rev_options(dest, rev_options) + cmd_args = ['reset', '--hard', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + #: update submodules + self.update_submodules(dest) + + def obtain(self, dest): + url, rev = self.get_url_rev() + rev_options = self.make_rev_options(rev) + if self.check_destination(dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Cloning %s%s to %s', url, rev_display, display_path(dest), + ) + self.run_command(['clone', '-q', url, dest]) + + if rev: + rev_options = self.check_rev_options(dest, rev_options) + # Only do a checkout if the current commit id doesn't match + # the requested revision. + if not self.is_commit_id_equal(dest, rev_options.rev): + rev = rev_options.rev + # Only fetch the revision if it's a ref + if rev.startswith('refs/'): + self.run_command( + ['fetch', '-q', url] + rev_options.to_args(), + cwd=dest, + ) + # Change the revision to the SHA of the ref we fetched + rev = 'FETCH_HEAD' + self.run_command(['checkout', '-q', rev], cwd=dest) + + #: repo may contain submodules + self.update_submodules(dest) + + def get_url(self, location): + """Return URL of the first remote encountered.""" + remotes = self.run_command( + ['config', '--get-regexp', r'remote\..*\.url'], + show_stdout=False, cwd=location, + ) + remotes = remotes.splitlines() + found_remote = remotes[0] + for remote in remotes: + if remote.startswith('remote.origin.url '): + found_remote = remote + break + url = found_remote.split(' ')[1] + return url.strip() + + def get_revision(self, location): + current_rev = self.run_command( + ['rev-parse', 'HEAD'], show_stdout=False, cwd=location, + ) + return current_rev.strip() + + def _get_subdirectory(self, location): + """Return the relative path of setup.py to the git repo root.""" + # find the repo root + git_dir = self.run_command(['rev-parse', '--git-dir'], + show_stdout=False, cwd=location).strip() + if not os.path.isabs(git_dir): + git_dir = os.path.join(location, git_dir) + root_dir = os.path.join(git_dir, '..') + # find setup.py + orig_location = location + while not os.path.exists(os.path.join(location, 'setup.py')): + last_location = location + location = os.path.dirname(location) + if location == last_location: + # We've traversed up to the root of the filesystem without + # finding setup.py + logger.warning( + "Could not find setup.py for directory %s (tried all " + "parent directories)", + orig_location, + ) + return None + # relative path of setup.py to repo root + if samefile(root_dir, location): + return None + return os.path.relpath(location, root_dir) + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if not repo.lower().startswith('git:'): + repo = 'git+' + repo + egg_project_name = dist.egg_name().split('-', 1)[0] + if not repo: + return None + current_rev = self.get_revision(location) + req = '%s@%s#egg=%s' % (repo, current_rev, egg_project_name) + subdirectory = self._get_subdirectory(location) + if subdirectory: + req += '&subdirectory=' + subdirectory + return req + + def get_url_rev(self): + """ + Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'. + That's required because although they use SSH they sometimes doesn't + work with a ssh:// scheme (e.g. Github). But we need a scheme for + parsing. Hence we remove it again afterwards and return it as a stub. + """ + if '://' not in self.url: + assert 'file:' not in self.url + self.url = self.url.replace('git+', 'git+ssh://') + url, rev = super(Git, self).get_url_rev() + url = url.replace('ssh://', '') + else: + url, rev = super(Git, self).get_url_rev() + + return url, rev + + def update_submodules(self, location): + if not os.path.exists(os.path.join(location, '.gitmodules')): + return + self.run_command( + ['submodule', 'update', '--init', '--recursive', '-q'], + cwd=location, + ) + + @classmethod + def controls_location(cls, location): + if super(Git, cls).controls_location(location): + return True + try: + r = cls().run_command(['rev-parse'], + cwd=location, + show_stdout=False, + on_returncode='ignore') + return not r + except BadCommand: + logger.debug("could not determine if %s is under git control " + "because git is not available", location) + return False + + +vcs.register(Git) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/mercurial.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/mercurial.py new file mode 100644 index 0000000..52a1cce --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/mercurial.py @@ -0,0 +1,105 @@ +from __future__ import absolute_import + +import logging +import os + +from pip._vendor.six.moves import configparser + +from pip._internal.download import path_to_url +from pip._internal.utils.misc import display_path +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.vcs import VersionControl, vcs + +logger = logging.getLogger(__name__) + + +class Mercurial(VersionControl): + name = 'hg' + dirname = '.hg' + repo_name = 'clone' + schemes = ('hg', 'hg+http', 'hg+https', 'hg+ssh', 'hg+static-http') + + def get_base_rev_args(self, rev): + return [rev] + + def export(self, location): + """Export the Hg repository at the url to the destination location""" + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path) + + self.run_command( + ['archive', location], show_stdout=False, cwd=temp_dir.path + ) + + def switch(self, dest, url, rev_options): + repo_config = os.path.join(dest, self.dirname, 'hgrc') + config = configparser.SafeConfigParser() + try: + config.read(repo_config) + config.set('paths', 'default', url) + with open(repo_config, 'w') as config_file: + config.write(config_file) + except (OSError, configparser.NoSectionError) as exc: + logger.warning( + 'Could not switch Mercurial repository to %s: %s', url, exc, + ) + else: + cmd_args = ['update', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def update(self, dest, rev_options): + self.run_command(['pull', '-q'], cwd=dest) + cmd_args = ['update', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def obtain(self, dest): + url, rev = self.get_url_rev() + rev_options = self.make_rev_options(rev) + if self.check_destination(dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Cloning hg %s%s to %s', + url, + rev_display, + display_path(dest), + ) + self.run_command(['clone', '--noupdate', '-q', url, dest]) + cmd_args = ['update', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def get_url(self, location): + url = self.run_command( + ['showconfig', 'paths.default'], + show_stdout=False, cwd=location).strip() + if self._is_local_repository(url): + url = path_to_url(url) + return url.strip() + + def get_revision(self, location): + current_revision = self.run_command( + ['parents', '--template={rev}'], + show_stdout=False, cwd=location).strip() + return current_revision + + def get_revision_hash(self, location): + current_rev_hash = self.run_command( + ['parents', '--template={node}'], + show_stdout=False, cwd=location).strip() + return current_rev_hash + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if not repo.lower().startswith('hg:'): + repo = 'hg+' + repo + egg_project_name = dist.egg_name().split('-', 1)[0] + if not repo: + return None + current_rev_hash = self.get_revision_hash(location) + return '%s@%s#egg=%s' % (repo, current_rev_hash, egg_project_name) + + def is_commit_id_equal(self, dest, name): + """Always assume the versions don't match""" + return False + + +vcs.register(Mercurial) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/subversion.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/subversion.py new file mode 100644 index 0000000..7f369ef --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/subversion.py @@ -0,0 +1,271 @@ +from __future__ import absolute_import + +import logging +import os +import re + +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.index import Link +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import display_path, rmtree +from pip._internal.vcs import VersionControl, vcs + +_svn_xml_url_re = re.compile('url="([^"]+)"') +_svn_rev_re = re.compile(r'committed-rev="(\d+)"') +_svn_url_re = re.compile(r'URL: (.+)') +_svn_revision_re = re.compile(r'Revision: (.+)') +_svn_info_xml_rev_re = re.compile(r'\s*revision="(\d+)"') +_svn_info_xml_url_re = re.compile(r'<url>(.*)</url>') + + +logger = logging.getLogger(__name__) + + +class Subversion(VersionControl): + name = 'svn' + dirname = '.svn' + repo_name = 'checkout' + schemes = ('svn', 'svn+ssh', 'svn+http', 'svn+https', 'svn+svn') + + def get_base_rev_args(self, rev): + return ['-r', rev] + + def get_info(self, location): + """Returns (url, revision), where both are strings""" + assert not location.rstrip('/').endswith(self.dirname), \ + 'Bad directory: %s' % location + output = self.run_command( + ['info', location], + show_stdout=False, + extra_environ={'LANG': 'C'}, + ) + match = _svn_url_re.search(output) + if not match: + logger.warning( + 'Cannot determine URL of svn checkout %s', + display_path(location), + ) + logger.debug('Output that cannot be parsed: \n%s', output) + return None, None + url = match.group(1).strip() + match = _svn_revision_re.search(output) + if not match: + logger.warning( + 'Cannot determine revision of svn checkout %s', + display_path(location), + ) + logger.debug('Output that cannot be parsed: \n%s', output) + return url, None + return url, match.group(1) + + def export(self, location): + """Export the svn repository at the url to the destination location""" + url, rev = self.get_url_rev() + rev_options = get_rev_options(self, url, rev) + url = self.remove_auth_from_url(url) + logger.info('Exporting svn repository %s to %s', url, location) + with indent_log(): + if os.path.exists(location): + # Subversion doesn't like to check out over an existing + # directory --force fixes this, but was only added in svn 1.5 + rmtree(location) + cmd_args = ['export'] + rev_options.to_args() + [url, location] + self.run_command(cmd_args, show_stdout=False) + + def switch(self, dest, url, rev_options): + cmd_args = ['switch'] + rev_options.to_args() + [url, dest] + self.run_command(cmd_args) + + def update(self, dest, rev_options): + cmd_args = ['update'] + rev_options.to_args() + [dest] + self.run_command(cmd_args) + + def obtain(self, dest): + url, rev = self.get_url_rev() + rev_options = get_rev_options(self, url, rev) + url = self.remove_auth_from_url(url) + if self.check_destination(dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Checking out %s%s to %s', + url, + rev_display, + display_path(dest), + ) + cmd_args = ['checkout', '-q'] + rev_options.to_args() + [url, dest] + self.run_command(cmd_args) + + def get_location(self, dist, dependency_links): + for url in dependency_links: + egg_fragment = Link(url).egg_fragment + if not egg_fragment: + continue + if '-' in egg_fragment: + # FIXME: will this work when a package has - in the name? + key = '-'.join(egg_fragment.split('-')[:-1]).lower() + else: + key = egg_fragment + if key == dist.key: + return url.split('#', 1)[0] + return None + + def get_revision(self, location): + """ + Return the maximum revision for all files under a given location + """ + # Note: taken from setuptools.command.egg_info + revision = 0 + + for base, dirs, files in os.walk(location): + if self.dirname not in dirs: + dirs[:] = [] + continue # no sense walking uncontrolled subdirs + dirs.remove(self.dirname) + entries_fn = os.path.join(base, self.dirname, 'entries') + if not os.path.exists(entries_fn): + # FIXME: should we warn? + continue + + dirurl, localrev = self._get_svn_url_rev(base) + + if base == location: + base = dirurl + '/' # save the root url + elif not dirurl or not dirurl.startswith(base): + dirs[:] = [] + continue # not part of the same svn tree, skip it + revision = max(revision, localrev) + return revision + + def get_url_rev(self): + # hotfix the URL scheme after removing svn+ from svn+ssh:// readd it + url, rev = super(Subversion, self).get_url_rev() + if url.startswith('ssh://'): + url = 'svn+' + url + return url, rev + + def get_url(self, location): + # In cases where the source is in a subdirectory, not alongside + # setup.py we have to look up in the location until we find a real + # setup.py + orig_location = location + while not os.path.exists(os.path.join(location, 'setup.py')): + last_location = location + location = os.path.dirname(location) + if location == last_location: + # We've traversed up to the root of the filesystem without + # finding setup.py + logger.warning( + "Could not find setup.py for directory %s (tried all " + "parent directories)", + orig_location, + ) + return None + + return self._get_svn_url_rev(location)[0] + + def _get_svn_url_rev(self, location): + from pip._internal.exceptions import InstallationError + + entries_path = os.path.join(location, self.dirname, 'entries') + if os.path.exists(entries_path): + with open(entries_path) as f: + data = f.read() + else: # subversion >= 1.7 does not have the 'entries' file + data = '' + + if (data.startswith('8') or + data.startswith('9') or + data.startswith('10')): + data = list(map(str.splitlines, data.split('\n\x0c\n'))) + del data[0][0] # get rid of the '8' + url = data[0][3] + revs = [int(d[9]) for d in data if len(d) > 9 and d[9]] + [0] + elif data.startswith('<?xml'): + match = _svn_xml_url_re.search(data) + if not match: + raise ValueError('Badly formatted data: %r' % data) + url = match.group(1) # get repository URL + revs = [int(m.group(1)) for m in _svn_rev_re.finditer(data)] + [0] + else: + try: + # subversion >= 1.7 + xml = self.run_command( + ['info', '--xml', location], + show_stdout=False, + ) + url = _svn_info_xml_url_re.search(xml).group(1) + revs = [ + int(m.group(1)) for m in _svn_info_xml_rev_re.finditer(xml) + ] + except InstallationError: + url, revs = None, [] + + if revs: + rev = max(revs) + else: + rev = 0 + + return url, rev + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if repo is None: + return None + # FIXME: why not project name? + egg_project_name = dist.egg_name().split('-', 1)[0] + rev = self.get_revision(location) + return 'svn+%s@%s#egg=%s' % (repo, rev, egg_project_name) + + def is_commit_id_equal(self, dest, name): + """Always assume the versions don't match""" + return False + + @staticmethod + def remove_auth_from_url(url): + # Return a copy of url with 'username:password@' removed. + # username/pass params are passed to subversion through flags + # and are not recognized in the url. + + # parsed url + purl = urllib_parse.urlsplit(url) + stripped_netloc = \ + purl.netloc.split('@')[-1] + + # stripped url + url_pieces = ( + purl.scheme, stripped_netloc, purl.path, purl.query, purl.fragment + ) + surl = urllib_parse.urlunsplit(url_pieces) + return surl + + +def get_rev_options(vcs, url, rev): + """ + Return a RevOptions object. + """ + r = urllib_parse.urlsplit(url) + if hasattr(r, 'username'): + # >= Python-2.5 + username, password = r.username, r.password + else: + netloc = r[1] + if '@' in netloc: + auth = netloc.split('@')[0] + if ':' in auth: + username, password = auth.split(':', 1) + else: + username, password = auth, None + else: + username, password = None, None + + extra_args = [] + if username: + extra_args += ['--username', username] + if password: + extra_args += ['--password', password] + + return vcs.make_rev_options(rev, extra_args=extra_args) + + +vcs.register(Subversion) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/wheel.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/wheel.py new file mode 100644 index 0000000..c71f17d --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/wheel.py @@ -0,0 +1,817 @@ +""" +Support for installing and building the "wheel" binary package format. +""" +from __future__ import absolute_import + +import collections +import compileall +import copy +import csv +import hashlib +import logging +import os.path +import re +import shutil +import stat +import sys +import warnings +from base64 import urlsafe_b64encode +from email.parser import Parser + +from pip._vendor import pkg_resources +from pip._vendor.distlib.scripts import ScriptMaker +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.six import StringIO + +from pip._internal import pep425tags +from pip._internal.build_env import BuildEnvironment +from pip._internal.download import path_to_url, unpack_url +from pip._internal.exceptions import ( + InstallationError, InvalidWheelFilename, UnsupportedWheel, +) +from pip._internal.locations import ( + PIP_DELETE_MARKER_FILENAME, distutils_scheme, +) +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + call_subprocess, captured_stdout, ensure_dir, read_chunks, +) +from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.ui import open_spinner + +if MYPY_CHECK_RUNNING: + from typing import Dict, List, Optional + +wheel_ext = '.whl' + +VERSION_COMPATIBLE = (1, 0) + + +logger = logging.getLogger(__name__) + + +def rehash(path, algo='sha256', blocksize=1 << 20): + """Return (hash, length) for path using hashlib.new(algo)""" + h = hashlib.new(algo) + length = 0 + with open(path, 'rb') as f: + for block in read_chunks(f, size=blocksize): + length += len(block) + h.update(block) + digest = 'sha256=' + urlsafe_b64encode( + h.digest() + ).decode('latin1').rstrip('=') + return (digest, length) + + +def open_for_csv(name, mode): + if sys.version_info[0] < 3: + nl = {} + bin = 'b' + else: + nl = {'newline': ''} + bin = '' + return open(name, mode + bin, **nl) + + +def fix_script(path): + """Replace #!python with #!/path/to/python + Return True if file was changed.""" + # XXX RECORD hashes will need to be updated + if os.path.isfile(path): + with open(path, 'rb') as script: + firstline = script.readline() + if not firstline.startswith(b'#!python'): + return False + exename = sys.executable.encode(sys.getfilesystemencoding()) + firstline = b'#!' + exename + os.linesep.encode("ascii") + rest = script.read() + with open(path, 'wb') as script: + script.write(firstline) + script.write(rest) + return True + + +dist_info_re = re.compile(r"""^(?P<namever>(?P<name>.+?)(-(?P<ver>.+?))?) + \.dist-info$""", re.VERBOSE) + + +def root_is_purelib(name, wheeldir): + """ + Return True if the extracted wheel in wheeldir should go into purelib. + """ + name_folded = name.replace("-", "_") + for item in os.listdir(wheeldir): + match = dist_info_re.match(item) + if match and match.group('name') == name_folded: + with open(os.path.join(wheeldir, item, 'WHEEL')) as wheel: + for line in wheel: + line = line.lower().rstrip() + if line == "root-is-purelib: true": + return True + return False + + +def get_entrypoints(filename): + if not os.path.exists(filename): + return {}, {} + + # This is done because you can pass a string to entry_points wrappers which + # means that they may or may not be valid INI files. The attempt here is to + # strip leading and trailing whitespace in order to make them valid INI + # files. + with open(filename) as fp: + data = StringIO() + for line in fp: + data.write(line.strip()) + data.write("\n") + data.seek(0) + + # get the entry points and then the script names + entry_points = pkg_resources.EntryPoint.parse_map(data) + console = entry_points.get('console_scripts', {}) + gui = entry_points.get('gui_scripts', {}) + + def _split_ep(s): + """get the string representation of EntryPoint, remove space and split + on '='""" + return str(s).replace(" ", "").split("=") + + # convert the EntryPoint objects into strings with module:function + console = dict(_split_ep(v) for v in console.values()) + gui = dict(_split_ep(v) for v in gui.values()) + return console, gui + + +def message_about_scripts_not_on_PATH(scripts): + # type: (List[str]) -> Optional[str] + """Determine if any scripts are not on PATH and format a warning. + + Returns a warning message if one or more scripts are not on PATH, + otherwise None. + """ + if not scripts: + return None + + # Group scripts by the path they were installed in + grouped_by_dir = collections.defaultdict(set) # type: Dict[str, set] + for destfile in scripts: + parent_dir = os.path.dirname(destfile) + script_name = os.path.basename(destfile) + grouped_by_dir[parent_dir].add(script_name) + + # We don't want to warn for directories that are on PATH. + not_warn_dirs = [ + os.path.normcase(i) for i in os.environ["PATH"].split(os.pathsep) + ] + # If an executable sits with sys.executable, we don't warn for it. + # This covers the case of venv invocations without activating the venv. + not_warn_dirs.append(os.path.normcase(os.path.dirname(sys.executable))) + warn_for = { + parent_dir: scripts for parent_dir, scripts in grouped_by_dir.items() + if os.path.normcase(parent_dir) not in not_warn_dirs + } + if not warn_for: + return None + + # Format a message + msg_lines = [] + for parent_dir, scripts in warn_for.items(): + scripts = sorted(scripts) + if len(scripts) == 1: + start_text = "script {} is".format(scripts[0]) + else: + start_text = "scripts {} are".format( + ", ".join(scripts[:-1]) + " and " + scripts[-1] + ) + + msg_lines.append( + "The {} installed in '{}' which is not on PATH." + .format(start_text, parent_dir) + ) + + last_line_fmt = ( + "Consider adding {} to PATH or, if you prefer " + "to suppress this warning, use --no-warn-script-location." + ) + if len(msg_lines) == 1: + msg_lines.append(last_line_fmt.format("this directory")) + else: + msg_lines.append(last_line_fmt.format("these directories")) + + # Returns the formatted multiline message + return "\n".join(msg_lines) + + +def move_wheel_files(name, req, wheeldir, user=False, home=None, root=None, + pycompile=True, scheme=None, isolated=False, prefix=None, + warn_script_location=True): + """Install a wheel""" + + if not scheme: + scheme = distutils_scheme( + name, user=user, home=home, root=root, isolated=isolated, + prefix=prefix, + ) + + if root_is_purelib(name, wheeldir): + lib_dir = scheme['purelib'] + else: + lib_dir = scheme['platlib'] + + info_dir = [] + data_dirs = [] + source = wheeldir.rstrip(os.path.sep) + os.path.sep + + # Record details of the files moved + # installed = files copied from the wheel to the destination + # changed = files changed while installing (scripts #! line typically) + # generated = files newly generated during the install (script wrappers) + installed = {} + changed = set() + generated = [] + + # Compile all of the pyc files that we're going to be installing + if pycompile: + with captured_stdout() as stdout: + with warnings.catch_warnings(): + warnings.filterwarnings('ignore') + compileall.compile_dir(source, force=True, quiet=True) + logger.debug(stdout.getvalue()) + + def normpath(src, p): + return os.path.relpath(src, p).replace(os.path.sep, '/') + + def record_installed(srcfile, destfile, modified=False): + """Map archive RECORD paths to installation RECORD paths.""" + oldpath = normpath(srcfile, wheeldir) + newpath = normpath(destfile, lib_dir) + installed[oldpath] = newpath + if modified: + changed.add(destfile) + + def clobber(source, dest, is_base, fixer=None, filter=None): + ensure_dir(dest) # common for the 'include' path + + for dir, subdirs, files in os.walk(source): + basedir = dir[len(source):].lstrip(os.path.sep) + destdir = os.path.join(dest, basedir) + if is_base and basedir.split(os.path.sep, 1)[0].endswith('.data'): + continue + for s in subdirs: + destsubdir = os.path.join(dest, basedir, s) + if is_base and basedir == '' and destsubdir.endswith('.data'): + data_dirs.append(s) + continue + elif (is_base and + s.endswith('.dist-info') and + canonicalize_name(s).startswith( + canonicalize_name(req.name))): + assert not info_dir, ('Multiple .dist-info directories: ' + + destsubdir + ', ' + + ', '.join(info_dir)) + info_dir.append(destsubdir) + for f in files: + # Skip unwanted files + if filter and filter(f): + continue + srcfile = os.path.join(dir, f) + destfile = os.path.join(dest, basedir, f) + # directory creation is lazy and after the file filtering above + # to ensure we don't install empty dirs; empty dirs can't be + # uninstalled. + ensure_dir(destdir) + + # We use copyfile (not move, copy, or copy2) to be extra sure + # that we are not moving directories over (copyfile fails for + # directories) as well as to ensure that we are not copying + # over any metadata because we want more control over what + # metadata we actually copy over. + shutil.copyfile(srcfile, destfile) + + # Copy over the metadata for the file, currently this only + # includes the atime and mtime. + st = os.stat(srcfile) + if hasattr(os, "utime"): + os.utime(destfile, (st.st_atime, st.st_mtime)) + + # If our file is executable, then make our destination file + # executable. + if os.access(srcfile, os.X_OK): + st = os.stat(srcfile) + permissions = ( + st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH + ) + os.chmod(destfile, permissions) + + changed = False + if fixer: + changed = fixer(destfile) + record_installed(srcfile, destfile, changed) + + clobber(source, lib_dir, True) + + assert info_dir, "%s .dist-info directory not found" % req + + # Get the defined entry points + ep_file = os.path.join(info_dir[0], 'entry_points.txt') + console, gui = get_entrypoints(ep_file) + + def is_entrypoint_wrapper(name): + # EP, EP.exe and EP-script.py are scripts generated for + # entry point EP by setuptools + if name.lower().endswith('.exe'): + matchname = name[:-4] + elif name.lower().endswith('-script.py'): + matchname = name[:-10] + elif name.lower().endswith(".pya"): + matchname = name[:-4] + else: + matchname = name + # Ignore setuptools-generated scripts + return (matchname in console or matchname in gui) + + for datadir in data_dirs: + fixer = None + filter = None + for subdir in os.listdir(os.path.join(wheeldir, datadir)): + fixer = None + if subdir == 'scripts': + fixer = fix_script + filter = is_entrypoint_wrapper + source = os.path.join(wheeldir, datadir, subdir) + dest = scheme[subdir] + clobber(source, dest, False, fixer=fixer, filter=filter) + + maker = ScriptMaker(None, scheme['scripts']) + + # Ensure old scripts are overwritten. + # See https://github.com/pypa/pip/issues/1800 + maker.clobber = True + + # Ensure we don't generate any variants for scripts because this is almost + # never what somebody wants. + # See https://bitbucket.org/pypa/distlib/issue/35/ + maker.variants = {''} + + # This is required because otherwise distlib creates scripts that are not + # executable. + # See https://bitbucket.org/pypa/distlib/issue/32/ + maker.set_mode = True + + # Simplify the script and fix the fact that the default script swallows + # every single stack trace. + # See https://bitbucket.org/pypa/distlib/issue/34/ + # See https://bitbucket.org/pypa/distlib/issue/33/ + def _get_script_text(entry): + if entry.suffix is None: + raise InstallationError( + "Invalid script entry point: %s for req: %s - A callable " + "suffix is required. Cf https://packaging.python.org/en/" + "latest/distributing.html#console-scripts for more " + "information." % (entry, req) + ) + return maker.script_template % { + "module": entry.prefix, + "import_name": entry.suffix.split(".")[0], + "func": entry.suffix, + } + + maker._get_script_text = _get_script_text + maker.script_template = r"""# -*- coding: utf-8 -*- +import re +import sys + +from %(module)s import %(import_name)s + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(%(func)s()) +""" + + # Special case pip and setuptools to generate versioned wrappers + # + # The issue is that some projects (specifically, pip and setuptools) use + # code in setup.py to create "versioned" entry points - pip2.7 on Python + # 2.7, pip3.3 on Python 3.3, etc. But these entry points are baked into + # the wheel metadata at build time, and so if the wheel is installed with + # a *different* version of Python the entry points will be wrong. The + # correct fix for this is to enhance the metadata to be able to describe + # such versioned entry points, but that won't happen till Metadata 2.0 is + # available. + # In the meantime, projects using versioned entry points will either have + # incorrect versioned entry points, or they will not be able to distribute + # "universal" wheels (i.e., they will need a wheel per Python version). + # + # Because setuptools and pip are bundled with _ensurepip and virtualenv, + # we need to use universal wheels. So, as a stopgap until Metadata 2.0, we + # override the versioned entry points in the wheel and generate the + # correct ones. This code is purely a short-term measure until Metadata 2.0 + # is available. + # + # To add the level of hack in this section of code, in order to support + # ensurepip this code will look for an ``ENSUREPIP_OPTIONS`` environment + # variable which will control which version scripts get installed. + # + # ENSUREPIP_OPTIONS=altinstall + # - Only pipX.Y and easy_install-X.Y will be generated and installed + # ENSUREPIP_OPTIONS=install + # - pipX.Y, pipX, easy_install-X.Y will be generated and installed. Note + # that this option is technically if ENSUREPIP_OPTIONS is set and is + # not altinstall + # DEFAULT + # - The default behavior is to install pip, pipX, pipX.Y, easy_install + # and easy_install-X.Y. + pip_script = console.pop('pip', None) + if pip_script: + if "ENSUREPIP_OPTIONS" not in os.environ: + spec = 'pip = ' + pip_script + generated.extend(maker.make(spec)) + + if os.environ.get("ENSUREPIP_OPTIONS", "") != "altinstall": + spec = 'pip%s = %s' % (sys.version[:1], pip_script) + generated.extend(maker.make(spec)) + + spec = 'pip%s = %s' % (sys.version[:3], pip_script) + generated.extend(maker.make(spec)) + # Delete any other versioned pip entry points + pip_ep = [k for k in console if re.match(r'pip(\d(\.\d)?)?$', k)] + for k in pip_ep: + del console[k] + easy_install_script = console.pop('easy_install', None) + if easy_install_script: + if "ENSUREPIP_OPTIONS" not in os.environ: + spec = 'easy_install = ' + easy_install_script + generated.extend(maker.make(spec)) + + spec = 'easy_install-%s = %s' % (sys.version[:3], easy_install_script) + generated.extend(maker.make(spec)) + # Delete any other versioned easy_install entry points + easy_install_ep = [ + k for k in console if re.match(r'easy_install(-\d\.\d)?$', k) + ] + for k in easy_install_ep: + del console[k] + + # Generate the console and GUI entry points specified in the wheel + if len(console) > 0: + generated_console_scripts = maker.make_multiple( + ['%s = %s' % kv for kv in console.items()] + ) + generated.extend(generated_console_scripts) + + if warn_script_location: + msg = message_about_scripts_not_on_PATH(generated_console_scripts) + if msg is not None: + logger.warn(msg) + + if len(gui) > 0: + generated.extend( + maker.make_multiple( + ['%s = %s' % kv for kv in gui.items()], + {'gui': True} + ) + ) + + # Record pip as the installer + installer = os.path.join(info_dir[0], 'INSTALLER') + temp_installer = os.path.join(info_dir[0], 'INSTALLER.pip') + with open(temp_installer, 'wb') as installer_file: + installer_file.write(b'pip\n') + shutil.move(temp_installer, installer) + generated.append(installer) + + # Record details of all files installed + record = os.path.join(info_dir[0], 'RECORD') + temp_record = os.path.join(info_dir[0], 'RECORD.pip') + with open_for_csv(record, 'r') as record_in: + with open_for_csv(temp_record, 'w+') as record_out: + reader = csv.reader(record_in) + writer = csv.writer(record_out) + for row in reader: + row[0] = installed.pop(row[0], row[0]) + if row[0] in changed: + row[1], row[2] = rehash(row[0]) + writer.writerow(row) + for f in generated: + h, l = rehash(f) + writer.writerow((normpath(f, lib_dir), h, l)) + for f in installed: + writer.writerow((installed[f], '', '')) + shutil.move(temp_record, record) + + +def wheel_version(source_dir): + """ + Return the Wheel-Version of an extracted wheel, if possible. + + Otherwise, return False if we couldn't parse / extract it. + """ + try: + dist = [d for d in pkg_resources.find_on_path(None, source_dir)][0] + + wheel_data = dist.get_metadata('WHEEL') + wheel_data = Parser().parsestr(wheel_data) + + version = wheel_data['Wheel-Version'].strip() + version = tuple(map(int, version.split('.'))) + return version + except: + return False + + +def check_compatibility(version, name): + """ + Raises errors or warns if called with an incompatible Wheel-Version. + + Pip should refuse to install a Wheel-Version that's a major series + ahead of what it's compatible with (e.g 2.0 > 1.1); and warn when + installing a version only minor version ahead (e.g 1.2 > 1.1). + + version: a 2-tuple representing a Wheel-Version (Major, Minor) + name: name of wheel or package to raise exception about + + :raises UnsupportedWheel: when an incompatible Wheel-Version is given + """ + if not version: + raise UnsupportedWheel( + "%s is in an unsupported or invalid wheel" % name + ) + if version[0] > VERSION_COMPATIBLE[0]: + raise UnsupportedWheel( + "%s's Wheel-Version (%s) is not compatible with this version " + "of pip" % (name, '.'.join(map(str, version))) + ) + elif version > VERSION_COMPATIBLE: + logger.warning( + 'Installing from a newer Wheel-Version (%s)', + '.'.join(map(str, version)), + ) + + +class Wheel(object): + """A wheel file""" + + # TODO: maybe move the install code into this class + + wheel_file_re = re.compile( + r"""^(?P<namever>(?P<name>.+?)-(?P<ver>.*?)) + ((-(?P<build>\d[^-]*?))?-(?P<pyver>.+?)-(?P<abi>.+?)-(?P<plat>.+?) + \.whl|\.dist-info)$""", + re.VERBOSE + ) + + def __init__(self, filename): + """ + :raises InvalidWheelFilename: when the filename is invalid for a wheel + """ + wheel_info = self.wheel_file_re.match(filename) + if not wheel_info: + raise InvalidWheelFilename( + "%s is not a valid wheel filename." % filename + ) + self.filename = filename + self.name = wheel_info.group('name').replace('_', '-') + # we'll assume "_" means "-" due to wheel naming scheme + # (https://github.com/pypa/pip/issues/1150) + self.version = wheel_info.group('ver').replace('_', '-') + self.build_tag = wheel_info.group('build') + self.pyversions = wheel_info.group('pyver').split('.') + self.abis = wheel_info.group('abi').split('.') + self.plats = wheel_info.group('plat').split('.') + + # All the tag combinations from this file + self.file_tags = { + (x, y, z) for x in self.pyversions + for y in self.abis for z in self.plats + } + + def support_index_min(self, tags=None): + """ + Return the lowest index that one of the wheel's file_tag combinations + achieves in the supported_tags list e.g. if there are 8 supported tags, + and one of the file tags is first in the list, then return 0. Returns + None is the wheel is not supported. + """ + if tags is None: # for mock + tags = pep425tags.get_supported() + indexes = [tags.index(c) for c in self.file_tags if c in tags] + return min(indexes) if indexes else None + + def supported(self, tags=None): + """Is this wheel supported on this system?""" + if tags is None: # for mock + tags = pep425tags.get_supported() + return bool(set(tags).intersection(self.file_tags)) + + +class WheelBuilder(object): + """Build wheels from a RequirementSet.""" + + def __init__(self, finder, preparer, wheel_cache, + build_options=None, global_options=None, no_clean=False): + self.finder = finder + self.preparer = preparer + self.wheel_cache = wheel_cache + + self._wheel_dir = preparer.wheel_download_dir + + self.build_options = build_options or [] + self.global_options = global_options or [] + self.no_clean = no_clean + + def _build_one(self, req, output_dir, python_tag=None): + """Build one wheel. + + :return: The filename of the built wheel, or None if the build failed. + """ + # Install build deps into temporary directory (PEP 518) + with req.build_env: + return self._build_one_inside_env(req, output_dir, + python_tag=python_tag) + + def _build_one_inside_env(self, req, output_dir, python_tag=None): + with TempDirectory(kind="wheel") as temp_dir: + if self.__build_one(req, temp_dir.path, python_tag=python_tag): + try: + wheel_name = os.listdir(temp_dir.path)[0] + wheel_path = os.path.join(output_dir, wheel_name) + shutil.move( + os.path.join(temp_dir.path, wheel_name), wheel_path + ) + logger.info('Stored in directory: %s', output_dir) + return wheel_path + except: + pass + # Ignore return, we can't do anything else useful. + self._clean_one(req) + return None + + def _base_setup_args(self, req): + # NOTE: Eventually, we'd want to also -S to the flags here, when we're + # isolating. Currently, it breaks Python in virtualenvs, because it + # relies on site.py to find parts of the standard library outside the + # virtualenv. + return [ + sys.executable, '-u', '-c', + SETUPTOOLS_SHIM % req.setup_py + ] + list(self.global_options) + + def __build_one(self, req, tempd, python_tag=None): + base_args = self._base_setup_args(req) + + spin_message = 'Running setup.py bdist_wheel for %s' % (req.name,) + with open_spinner(spin_message) as spinner: + logger.debug('Destination directory: %s', tempd) + wheel_args = base_args + ['bdist_wheel', '-d', tempd] \ + + self.build_options + + if python_tag is not None: + wheel_args += ["--python-tag", python_tag] + + try: + call_subprocess(wheel_args, cwd=req.setup_py_dir, + show_stdout=False, spinner=spinner) + return True + except: + spinner.finish("error") + logger.error('Failed building wheel for %s', req.name) + return False + + def _clean_one(self, req): + base_args = self._base_setup_args(req) + + logger.info('Running setup.py clean for %s', req.name) + clean_args = base_args + ['clean', '--all'] + try: + call_subprocess(clean_args, cwd=req.source_dir, show_stdout=False) + return True + except: + logger.error('Failed cleaning build dir for %s', req.name) + return False + + def build(self, requirements, session, autobuilding=False): + """Build wheels. + + :param unpack: If True, replace the sdist we built from with the + newly built wheel, in preparation for installation. + :return: True if all the wheels built correctly. + """ + from pip._internal import index + + building_is_possible = self._wheel_dir or ( + autobuilding and self.wheel_cache.cache_dir + ) + assert building_is_possible + + buildset = [] + for req in requirements: + if req.constraint: + continue + if req.is_wheel: + if not autobuilding: + logger.info( + 'Skipping %s, due to already being wheel.', req.name, + ) + elif autobuilding and req.editable: + pass + elif autobuilding and not req.source_dir: + pass + elif autobuilding and req.link and not req.link.is_artifact: + # VCS checkout. Build wheel just for this run. + buildset.append((req, True)) + else: + ephem_cache = False + if autobuilding: + link = req.link + base, ext = link.splitext() + if index.egg_info_matches(base, None, link) is None: + # E.g. local directory. Build wheel just for this run. + ephem_cache = True + if "binary" not in index.fmt_ctl_formats( + self.finder.format_control, + canonicalize_name(req.name)): + logger.info( + "Skipping bdist_wheel for %s, due to binaries " + "being disabled for it.", req.name, + ) + continue + buildset.append((req, ephem_cache)) + + if not buildset: + return True + + # Build the wheels. + logger.info( + 'Building wheels for collected packages: %s', + ', '.join([req.name for (req, _) in buildset]), + ) + _cache = self.wheel_cache # shorter name + with indent_log(): + build_success, build_failure = [], [] + for req, ephem in buildset: + python_tag = None + if autobuilding: + python_tag = pep425tags.implementation_tag + if ephem: + output_dir = _cache.get_ephem_path_for_link(req.link) + else: + output_dir = _cache.get_path_for_link(req.link) + try: + ensure_dir(output_dir) + except OSError as e: + logger.warning("Building wheel for %s failed: %s", + req.name, e) + build_failure.append(req) + continue + else: + output_dir = self._wheel_dir + wheel_file = self._build_one( + req, output_dir, + python_tag=python_tag, + ) + if wheel_file: + build_success.append(req) + if autobuilding: + # XXX: This is mildly duplicative with prepare_files, + # but not close enough to pull out to a single common + # method. + # The code below assumes temporary source dirs - + # prevent it doing bad things. + if req.source_dir and not os.path.exists(os.path.join( + req.source_dir, PIP_DELETE_MARKER_FILENAME)): + raise AssertionError( + "bad source dir - missing marker") + # Delete the source we built the wheel from + req.remove_temporary_source() + # set the build directory again - name is known from + # the work prepare_files did. + req.source_dir = req.build_location( + self.preparer.build_dir + ) + # Update the link for this. + req.link = index.Link(path_to_url(wheel_file)) + assert req.link.is_wheel + # extract the wheel into the dir + unpack_url( + req.link, req.source_dir, None, False, + session=session, + ) + else: + build_failure.append(req) + + # notify success/failure + if build_success: + logger.info( + 'Successfully built %s', + ' '.join([req.name for req in build_success]), + ) + if build_failure: + logger.info( + 'Failed to build %s', + ' '.join([req.name for req in build_failure]), + ) + # Return True if all builds were successful + return len(build_failure) == 0 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__init__.py new file mode 100644 index 0000000..1387dba --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__init__.py @@ -0,0 +1,109 @@ +""" +pip._vendor is for vendoring dependencies of pip to prevent needing pip to +depend on something external. + +Files inside of pip._vendor should be considered immutable and should only be +updated to versions from upstream. +""" +from __future__ import absolute_import + +import glob +import os.path +import sys + +# Downstream redistributors which have debundled our dependencies should also +# patch this value to be true. This will trigger the additional patching +# to cause things like "six" to be available as pip. +DEBUNDLED = False + +# By default, look in this directory for a bunch of .whl files which we will +# add to the beginning of sys.path before attempting to import anything. This +# is done to support downstream re-distributors like Debian and Fedora who +# wish to create their own Wheels for our dependencies to aid in debundling. +WHEEL_DIR = os.path.abspath(os.path.dirname(__file__)) + + +# Define a small helper function to alias our vendored modules to the real ones +# if the vendored ones do not exist. This idea of this was taken from +# https://github.com/kennethreitz/requests/pull/2567. +def vendored(modulename): + vendored_name = "{0}.{1}".format(__name__, modulename) + + try: + __import__(vendored_name, globals(), locals(), level=0) + except ImportError: + try: + __import__(modulename, globals(), locals(), level=0) + except ImportError: + # We can just silently allow import failures to pass here. If we + # got to this point it means that ``import pip._vendor.whatever`` + # failed and so did ``import whatever``. Since we're importing this + # upfront in an attempt to alias imports, not erroring here will + # just mean we get a regular import error whenever pip *actually* + # tries to import one of these modules to use it, which actually + # gives us a better error message than we would have otherwise + # gotten. + pass + else: + sys.modules[vendored_name] = sys.modules[modulename] + base, head = vendored_name.rsplit(".", 1) + setattr(sys.modules[base], head, sys.modules[modulename]) + + +# If we're operating in a debundled setup, then we want to go ahead and trigger +# the aliasing of our vendored libraries as well as looking for wheels to add +# to our sys.path. This will cause all of this code to be a no-op typically +# however downstream redistributors can enable it in a consistent way across +# all platforms. +if DEBUNDLED: + # Actually look inside of WHEEL_DIR to find .whl files and add them to the + # front of our sys.path. + sys.path[:] = glob.glob(os.path.join(WHEEL_DIR, "*.whl")) + sys.path + + # Actually alias all of our vendored dependencies. + vendored("cachecontrol") + vendored("colorama") + vendored("distlib") + vendored("distro") + vendored("html5lib") + vendored("lockfile") + vendored("six") + vendored("six.moves") + vendored("six.moves.urllib") + vendored("six.moves.urllib.parse") + vendored("packaging") + vendored("packaging.version") + vendored("packaging.specifiers") + vendored("pkg_resources") + vendored("progress") + vendored("pytoml") + vendored("retrying") + vendored("requests") + vendored("requests.packages") + vendored("requests.packages.urllib3") + vendored("requests.packages.urllib3._collections") + vendored("requests.packages.urllib3.connection") + vendored("requests.packages.urllib3.connectionpool") + vendored("requests.packages.urllib3.contrib") + vendored("requests.packages.urllib3.contrib.ntlmpool") + vendored("requests.packages.urllib3.contrib.pyopenssl") + vendored("requests.packages.urllib3.exceptions") + vendored("requests.packages.urllib3.fields") + vendored("requests.packages.urllib3.filepost") + vendored("requests.packages.urllib3.packages") + vendored("requests.packages.urllib3.packages.ordered_dict") + vendored("requests.packages.urllib3.packages.six") + vendored("requests.packages.urllib3.packages.ssl_match_hostname") + vendored("requests.packages.urllib3.packages.ssl_match_hostname." + "_implementation") + vendored("requests.packages.urllib3.poolmanager") + vendored("requests.packages.urllib3.request") + vendored("requests.packages.urllib3.response") + vendored("requests.packages.urllib3.util") + vendored("requests.packages.urllib3.util.connection") + vendored("requests.packages.urllib3.util.request") + vendored("requests.packages.urllib3.util.response") + vendored("requests.packages.urllib3.util.retry") + vendored("requests.packages.urllib3.util.ssl_") + vendored("requests.packages.urllib3.util.timeout") + vendored("requests.packages.urllib3.util.url") diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/appdirs.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/appdirs.py new file mode 100644 index 0000000..2bd3911 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/appdirs.py @@ -0,0 +1,604 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2005-2010 ActiveState Software Inc. +# Copyright (c) 2013 Eddy Petrișor + +"""Utilities for determining application-specific dirs. + +See <http://github.com/ActiveState/appdirs> for details and usage. +""" +# Dev Notes: +# - MSDN on where to store app data files: +# http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120 +# - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html +# - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + +__version_info__ = (1, 4, 3) +__version__ = '.'.join(map(str, __version_info__)) + + +import sys +import os + +PY3 = sys.version_info[0] == 3 + +if PY3: + unicode = str + +if sys.platform.startswith('java'): + import platform + os_name = platform.java_ver()[3][0] + if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc. + system = 'win32' + elif os_name.startswith('Mac'): # "Mac OS X", etc. + system = 'darwin' + else: # "Linux", "SunOS", "FreeBSD", etc. + # Setting this to "linux2" is not ideal, but only Windows or Mac + # are actually checked for and the rest of the module expects + # *sys.platform* style strings. + system = 'linux2' +else: + system = sys.platform + + + +def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> + for a discussion of issues. + + Typical user data directories are: + Mac OS X: ~/Library/Application Support/<AppName> + Unix: ~/.local/share/<AppName> # or in $XDG_DATA_HOME, if defined + Win XP (not roaming): C:\Documents and Settings\<username>\Application Data\<AppAuthor>\<AppName> + Win XP (roaming): C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName> + Win 7 (not roaming): C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName> + Win 7 (roaming): C:\Users\<username>\AppData\Roaming\<AppAuthor>\<AppName> + + For Unix, we follow the XDG spec and support $XDG_DATA_HOME. + That means, by default "~/.local/share/<AppName>". + """ + if system == "win32": + if appauthor is None: + appauthor = appname + const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" + path = os.path.normpath(_get_win_folder(const)) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('~/Library/Application Support/') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): + r"""Return full path to the user-shared data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of data dirs should be + returned. By default, the first item from XDG_DATA_DIRS is + returned, or '/usr/local/share/<AppName>', + if XDG_DATA_DIRS is not set + + Typical site data directories are: + Mac OS X: /Library/Application Support/<AppName> + Unix: /usr/local/share/<AppName> or /usr/share/<AppName> + Win XP: C:\Documents and Settings\All Users\Application Data\<AppAuthor>\<AppName> + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + Win 7: C:\ProgramData\<AppAuthor>\<AppName> # Hidden, but writeable on Win 7. + + For Unix, this is using the $XDG_DATA_DIRS[0] default. + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('/Library/Application Support') + if appname: + path = os.path.join(path, appname) + else: + # XDG default for $XDG_DATA_DIRS + # only first, if multipath is False + path = os.getenv('XDG_DATA_DIRS', + os.pathsep.join(['/usr/local/share', '/usr/share'])) + pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.sep.join([x, appname]) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + if appname and version: + path = os.path.join(path, version) + return path + + +def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific config dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> + for a discussion of issues. + + Typical user config directories are: + Mac OS X: same as user_data_dir + Unix: ~/.config/<AppName> # or in $XDG_CONFIG_HOME, if defined + Win *: same as user_data_dir + + For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. + That means, by default "~/.config/<AppName>". + """ + if system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def site_config_dir(appname=None, appauthor=None, version=None, multipath=False): + r"""Return full path to the user-shared data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of config dirs should be + returned. By default, the first item from XDG_CONFIG_DIRS is + returned, or '/etc/xdg/<AppName>', if XDG_CONFIG_DIRS is not set + + Typical site config directories are: + Mac OS X: same as site_data_dir + Unix: /etc/xdg/<AppName> or $XDG_CONFIG_DIRS[i]/<AppName> for each value in + $XDG_CONFIG_DIRS + Win *: same as site_data_dir + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + + For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system in ["win32", "darwin"]: + path = site_data_dir(appname, appauthor) + if appname and version: + path = os.path.join(path, version) + else: + # XDG default for $XDG_CONFIG_DIRS + # only first, if multipath is False + path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') + pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.sep.join([x, appname]) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + +def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific cache dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Cache" to the base app data dir for Windows. See + discussion below. + + Typical user cache directories are: + Mac OS X: ~/Library/Caches/<AppName> + Unix: ~/.cache/<AppName> (XDG default) + Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Cache + Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Cache + + On Windows the only suggestion in the MSDN docs is that local settings go in + the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming + app data dir (the default returned by `user_data_dir` above). Apps typically + put cache data somewhere *under* the given dir here. Some examples: + ...\Mozilla\Firefox\Profiles\<ProfileName>\Cache + ...\Acme\SuperApp\Cache\1.0 + OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. + This can be disabled with the `opinion=False` option. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + if opinion: + path = os.path.join(path, "Cache") + elif system == 'darwin': + path = os.path.expanduser('~/Library/Caches') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache')) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_state_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific state dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> + for a discussion of issues. + + Typical user state directories are: + Mac OS X: same as user_data_dir + Unix: ~/.local/state/<AppName> # or in $XDG_STATE_HOME, if defined + Win *: same as user_data_dir + + For Unix, we follow this Debian proposal <https://wiki.debian.org/XDGBaseDirectorySpecification#state> + to extend the XDG spec and support $XDG_STATE_HOME. + + That means, by default "~/.local/state/<AppName>". + """ + if system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_log_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific log dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Logs" to the base app data dir for Windows, and "log" to the + base cache dir for Unix. See discussion below. + + Typical user log directories are: + Mac OS X: ~/Library/Logs/<AppName> + Unix: ~/.cache/<AppName>/log # or under $XDG_CACHE_HOME if defined + Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Logs + Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Logs + + On Windows the only suggestion in the MSDN docs is that local settings + go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in + examples of what some windows apps use for a logs dir.) + + OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA` + value for Windows and appends "log" to the user cache dir for Unix. + This can be disabled with the `opinion=False` option. + """ + if system == "darwin": + path = os.path.join( + os.path.expanduser('~/Library/Logs'), + appname) + elif system == "win32": + path = user_data_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "Logs") + else: + path = user_cache_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "log") + if appname and version: + path = os.path.join(path, version) + return path + + +class AppDirs(object): + """Convenience wrapper for getting application dirs.""" + def __init__(self, appname=None, appauthor=None, version=None, + roaming=False, multipath=False): + self.appname = appname + self.appauthor = appauthor + self.version = version + self.roaming = roaming + self.multipath = multipath + + @property + def user_data_dir(self): + return user_data_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_data_dir(self): + return site_data_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_config_dir(self): + return user_config_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_config_dir(self): + return site_config_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_cache_dir(self): + return user_cache_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_state_dir(self): + return user_state_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_log_dir(self): + return user_log_dir(self.appname, self.appauthor, + version=self.version) + + +#---- internal support stuff + +def _get_win_folder_from_registry(csidl_name): + """This is a fallback technique at best. I'm not sure if using the + registry for this guarantees us the correct answer for all CSIDL_* + names. + """ + if PY3: + import winreg as _winreg + else: + import _winreg + + shell_folder_name = { + "CSIDL_APPDATA": "AppData", + "CSIDL_COMMON_APPDATA": "Common AppData", + "CSIDL_LOCAL_APPDATA": "Local AppData", + }[csidl_name] + + key = _winreg.OpenKey( + _winreg.HKEY_CURRENT_USER, + r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" + ) + dir, type = _winreg.QueryValueEx(key, shell_folder_name) + return dir + + +def _get_win_folder_with_pywin32(csidl_name): + from win32com.shell import shellcon, shell + dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0) + # Try to make this a unicode path because SHGetFolderPath does + # not return unicode strings when there is unicode data in the + # path. + try: + dir = unicode(dir) + + # Downgrade to short path name if have highbit chars. See + # <http://bugs.activestate.com/show_bug.cgi?id=85099>. + has_high_char = False + for c in dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + try: + import win32api + dir = win32api.GetShortPathName(dir) + except ImportError: + pass + except UnicodeError: + pass + return dir + + +def _get_win_folder_with_ctypes(csidl_name): + import ctypes + + csidl_const = { + "CSIDL_APPDATA": 26, + "CSIDL_COMMON_APPDATA": 35, + "CSIDL_LOCAL_APPDATA": 28, + }[csidl_name] + + buf = ctypes.create_unicode_buffer(1024) + ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) + + # Downgrade to short path name if have highbit chars. See + # <http://bugs.activestate.com/show_bug.cgi?id=85099>. + has_high_char = False + for c in buf: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf2 = ctypes.create_unicode_buffer(1024) + if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): + buf = buf2 + + return buf.value + +def _get_win_folder_with_jna(csidl_name): + import array + from com.sun import jna + from com.sun.jna.platform import win32 + + buf_size = win32.WinDef.MAX_PATH * 2 + buf = array.zeros('c', buf_size) + shell = win32.Shell32.INSTANCE + shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf) + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + # Downgrade to short path name if have highbit chars. See + # <http://bugs.activestate.com/show_bug.cgi?id=85099>. + has_high_char = False + for c in dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf = array.zeros('c', buf_size) + kernel = win32.Kernel32.INSTANCE + if kernel.GetShortPathName(dir, buf, buf_size): + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + return dir + +if system == "win32": + try: + from ctypes import windll + _get_win_folder = _get_win_folder_with_ctypes + except ImportError: + try: + import com.sun.jna + _get_win_folder = _get_win_folder_with_jna + except ImportError: + _get_win_folder = _get_win_folder_from_registry + + +#---- self test code + +if __name__ == "__main__": + appname = "MyApp" + appauthor = "MyCompany" + + props = ("user_data_dir", + "user_config_dir", + "user_cache_dir", + "user_state_dir", + "user_log_dir", + "site_data_dir", + "site_config_dir") + + print("-- app dirs %s --" % __version__) + + print("-- app dirs (with optional 'version')") + dirs = AppDirs(appname, appauthor, version="1.0") + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'version')") + dirs = AppDirs(appname, appauthor) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'appauthor')") + dirs = AppDirs(appname) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (with disabled 'appauthor')") + dirs = AppDirs(appname, appauthor=False) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__init__.py new file mode 100644 index 0000000..f386d49 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__init__.py @@ -0,0 +1,11 @@ +"""CacheControl import Interface. + +Make it easy to import from cachecontrol without long namespaces. +""" +__author__ = 'Eric Larson' +__email__ = 'eric@ionrock.org' +__version__ = '0.12.4' + +from .wrapper import CacheControl +from .adapter import CacheControlAdapter +from .controller import CacheController diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/_cmd.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/_cmd.py new file mode 100644 index 0000000..afdcc88 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/_cmd.py @@ -0,0 +1,60 @@ +import logging + +from pip._vendor import requests + +from pip._vendor.cachecontrol.adapter import CacheControlAdapter +from pip._vendor.cachecontrol.cache import DictCache +from pip._vendor.cachecontrol.controller import logger + +from argparse import ArgumentParser + + +def setup_logging(): + logger.setLevel(logging.DEBUG) + handler = logging.StreamHandler() + logger.addHandler(handler) + + +def get_session(): + adapter = CacheControlAdapter( + DictCache(), + cache_etags=True, + serializer=None, + heuristic=None, + ) + sess = requests.Session() + sess.mount('http://', adapter) + sess.mount('https://', adapter) + + sess.cache_controller = adapter.controller + return sess + + +def get_args(): + parser = ArgumentParser() + parser.add_argument('url', help='The URL to try and cache') + return parser.parse_args() + + +def main(args=None): + args = get_args() + sess = get_session() + + # Make a request to get a response + resp = sess.get(args.url) + + # Turn on logging + setup_logging() + + # try setting the cache + sess.cache_controller.cache_response(resp.request, resp.raw) + + # Now try to get it + if sess.cache_controller.cached_request(resp.request): + print('Cached!') + else: + print('Not cached :(') + + +if __name__ == '__main__': + main() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/adapter.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/adapter.py new file mode 100644 index 0000000..ecb34a6 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/adapter.py @@ -0,0 +1,134 @@ +import types +import functools +import zlib + +from pip._vendor.requests.adapters import HTTPAdapter + +from .controller import CacheController +from .cache import DictCache +from .filewrapper import CallbackFileWrapper + + +class CacheControlAdapter(HTTPAdapter): + invalidating_methods = set(['PUT', 'DELETE']) + + def __init__(self, cache=None, + cache_etags=True, + controller_class=None, + serializer=None, + heuristic=None, + cacheable_methods=None, + *args, **kw): + super(CacheControlAdapter, self).__init__(*args, **kw) + self.cache = cache or DictCache() + self.heuristic = heuristic + self.cacheable_methods = cacheable_methods or ('GET',) + + controller_factory = controller_class or CacheController + self.controller = controller_factory( + self.cache, + cache_etags=cache_etags, + serializer=serializer, + ) + + def send(self, request, cacheable_methods=None, **kw): + """ + Send a request. Use the request information to see if it + exists in the cache and cache the response if we need to and can. + """ + cacheable = cacheable_methods or self.cacheable_methods + if request.method in cacheable: + try: + cached_response = self.controller.cached_request(request) + except zlib.error: + cached_response = None + if cached_response: + return self.build_response(request, cached_response, + from_cache=True) + + # check for etags and add headers if appropriate + request.headers.update( + self.controller.conditional_headers(request) + ) + + resp = super(CacheControlAdapter, self).send(request, **kw) + + return resp + + def build_response(self, request, response, from_cache=False, + cacheable_methods=None): + """ + Build a response by making a request or using the cache. + + This will end up calling send and returning a potentially + cached response + """ + cacheable = cacheable_methods or self.cacheable_methods + if not from_cache and request.method in cacheable: + # Check for any heuristics that might update headers + # before trying to cache. + if self.heuristic: + response = self.heuristic.apply(response) + + # apply any expiration heuristics + if response.status == 304: + # We must have sent an ETag request. This could mean + # that we've been expired already or that we simply + # have an etag. In either case, we want to try and + # update the cache if that is the case. + cached_response = self.controller.update_cached_response( + request, response + ) + + if cached_response is not response: + from_cache = True + + # We are done with the server response, read a + # possible response body (compliant servers will + # not return one, but we cannot be 100% sure) and + # release the connection back to the pool. + response.read(decode_content=False) + response.release_conn() + + response = cached_response + + # We always cache the 301 responses + elif response.status == 301: + self.controller.cache_response(request, response) + else: + # Wrap the response file with a wrapper that will cache the + # response when the stream has been consumed. + response._fp = CallbackFileWrapper( + response._fp, + functools.partial( + self.controller.cache_response, + request, + response, + ) + ) + if response.chunked: + super_update_chunk_length = response._update_chunk_length + + def _update_chunk_length(self): + super_update_chunk_length() + if self.chunk_left == 0: + self._fp._close() + response._update_chunk_length = types.MethodType(_update_chunk_length, response) + + resp = super(CacheControlAdapter, self).build_response( + request, response + ) + + # See if we should invalidate the cache. + if request.method in self.invalidating_methods and resp.ok: + cache_url = self.controller.cache_url(request.url) + self.cache.delete(cache_url) + + # Give the request a from_cache attr to let people use it + resp.from_cache = from_cache + + return resp + + def close(self): + self.cache.close() + super(CacheControlAdapter, self).close() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/cache.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/cache.py new file mode 100644 index 0000000..7389a73 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/cache.py @@ -0,0 +1,39 @@ +""" +The cache object API for implementing caches. The default is a thread +safe in-memory dictionary. +""" +from threading import Lock + + +class BaseCache(object): + + def get(self, key): + raise NotImplemented() + + def set(self, key, value): + raise NotImplemented() + + def delete(self, key): + raise NotImplemented() + + def close(self): + pass + + +class DictCache(BaseCache): + + def __init__(self, init_dict=None): + self.lock = Lock() + self.data = init_dict or {} + + def get(self, key): + return self.data.get(key, None) + + def set(self, key, value): + with self.lock: + self.data.update({key: value}) + + def delete(self, key): + with self.lock: + if key in self.data: + self.data.pop(key) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__init__.py new file mode 100644 index 0000000..0e1658f --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__init__.py @@ -0,0 +1,2 @@ +from .file_cache import FileCache # noqa +from .redis_cache import RedisCache # noqa diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/file_cache.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/file_cache.py new file mode 100644 index 0000000..885c8a6 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/file_cache.py @@ -0,0 +1,133 @@ +import hashlib +import os +from textwrap import dedent + +from ..cache import BaseCache +from ..controller import CacheController + +try: + FileNotFoundError +except NameError: + # py2.X + FileNotFoundError = OSError + + +def _secure_open_write(filename, fmode): + # We only want to write to this file, so open it in write only mode + flags = os.O_WRONLY + + # os.O_CREAT | os.O_EXCL will fail if the file already exists, so we only + # will open *new* files. + # We specify this because we want to ensure that the mode we pass is the + # mode of the file. + flags |= os.O_CREAT | os.O_EXCL + + # Do not follow symlinks to prevent someone from making a symlink that + # we follow and insecurely open a cache file. + if hasattr(os, "O_NOFOLLOW"): + flags |= os.O_NOFOLLOW + + # On Windows we'll mark this file as binary + if hasattr(os, "O_BINARY"): + flags |= os.O_BINARY + + # Before we open our file, we want to delete any existing file that is + # there + try: + os.remove(filename) + except (IOError, OSError): + # The file must not exist already, so we can just skip ahead to opening + pass + + # Open our file, the use of os.O_CREAT | os.O_EXCL will ensure that if a + # race condition happens between the os.remove and this line, that an + # error will be raised. Because we utilize a lockfile this should only + # happen if someone is attempting to attack us. + fd = os.open(filename, flags, fmode) + try: + return os.fdopen(fd, "wb") + except: + # An error occurred wrapping our FD in a file object + os.close(fd) + raise + + +class FileCache(BaseCache): + def __init__(self, directory, forever=False, filemode=0o0600, + dirmode=0o0700, use_dir_lock=None, lock_class=None): + + if use_dir_lock is not None and lock_class is not None: + raise ValueError("Cannot use use_dir_lock and lock_class together") + + try: + from pip._vendor.lockfile import LockFile + from pip._vendor.lockfile.mkdirlockfile import MkdirLockFile + except ImportError: + notice = dedent(""" + NOTE: In order to use the FileCache you must have + lockfile installed. You can install it via pip: + pip install lockfile + """) + raise ImportError(notice) + else: + if use_dir_lock: + lock_class = MkdirLockFile + + elif lock_class is None: + lock_class = LockFile + + self.directory = directory + self.forever = forever + self.filemode = filemode + self.dirmode = dirmode + self.lock_class = lock_class + + @staticmethod + def encode(x): + return hashlib.sha224(x.encode()).hexdigest() + + def _fn(self, name): + # NOTE: This method should not change as some may depend on it. + # See: https://github.com/ionrock/cachecontrol/issues/63 + hashed = self.encode(name) + parts = list(hashed[:5]) + [hashed] + return os.path.join(self.directory, *parts) + + def get(self, key): + name = self._fn(key) + if not os.path.exists(name): + return None + + with open(name, 'rb') as fh: + return fh.read() + + def set(self, key, value): + name = self._fn(key) + + # Make sure the directory exists + try: + os.makedirs(os.path.dirname(name), self.dirmode) + except (IOError, OSError): + pass + + with self.lock_class(name) as lock: + # Write our actual file + with _secure_open_write(lock.path, self.filemode) as fh: + fh.write(value) + + def delete(self, key): + name = self._fn(key) + if not self.forever: + try: + os.remove(name) + except FileNotFoundError: + pass + + +def url_to_file_path(url, filecache): + """Return the file cache path based on the URL. + + This does not ensure the file exists! + """ + key = CacheController.cache_url(url) + return filecache._fn(key) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/redis_cache.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/redis_cache.py new file mode 100644 index 0000000..b6285e9 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/redis_cache.py @@ -0,0 +1,43 @@ +from __future__ import division + +from datetime import datetime +from pip._vendor.cachecontrol.cache import BaseCache + + +def total_seconds(td): + """Python 2.6 compatability""" + if hasattr(td, 'total_seconds'): + return int(td.total_seconds()) + + ms = td.microseconds + secs = (td.seconds + td.days * 24 * 3600) + return int((ms + secs * 10**6) / 10**6) + + +class RedisCache(BaseCache): + + def __init__(self, conn): + self.conn = conn + + def get(self, key): + return self.conn.get(key) + + def set(self, key, value, expires=None): + if not expires: + self.conn.set(key, value) + else: + expires = expires - datetime.utcnow() + self.conn.setex(key, total_seconds(expires), value) + + def delete(self, key): + self.conn.delete(key) + + def clear(self): + """Helper for clearing all the keys in a database. Use with + caution!""" + for key in self.conn.keys(): + self.conn.delete(key) + + def close(self): + """Redis uses connection pooling, no need to close the connection.""" + pass diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/compat.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/compat.py new file mode 100644 index 0000000..33b5aed --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/compat.py @@ -0,0 +1,29 @@ +try: + from urllib.parse import urljoin +except ImportError: + from urlparse import urljoin + + +try: + import cPickle as pickle +except ImportError: + import pickle + + +# Handle the case where the requests module has been patched to not have +# urllib3 bundled as part of its source. +try: + from pip._vendor.requests.packages.urllib3.response import HTTPResponse +except ImportError: + from pip._vendor.urllib3.response import HTTPResponse + +try: + from pip._vendor.requests.packages.urllib3.util import is_fp_closed +except ImportError: + from pip._vendor.urllib3.util import is_fp_closed + +# Replicate some six behaviour +try: + text_type = unicode +except NameError: + text_type = str diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/controller.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/controller.py new file mode 100644 index 0000000..0e2eb3c --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/controller.py @@ -0,0 +1,373 @@ +""" +The httplib2 algorithms ported for use with requests. +""" +import logging +import re +import calendar +import time +from email.utils import parsedate_tz + +from pip._vendor.requests.structures import CaseInsensitiveDict + +from .cache import DictCache +from .serialize import Serializer + + +logger = logging.getLogger(__name__) + +URI = re.compile(r"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?") + + +def parse_uri(uri): + """Parses a URI using the regex given in Appendix B of RFC 3986. + + (scheme, authority, path, query, fragment) = parse_uri(uri) + """ + groups = URI.match(uri).groups() + return (groups[1], groups[3], groups[4], groups[6], groups[8]) + + +class CacheController(object): + """An interface to see if request should cached or not. + """ + def __init__(self, cache=None, cache_etags=True, serializer=None, + status_codes=None): + self.cache = cache or DictCache() + self.cache_etags = cache_etags + self.serializer = serializer or Serializer() + self.cacheable_status_codes = status_codes or (200, 203, 300, 301) + + @classmethod + def _urlnorm(cls, uri): + """Normalize the URL to create a safe key for the cache""" + (scheme, authority, path, query, fragment) = parse_uri(uri) + if not scheme or not authority: + raise Exception("Only absolute URIs are allowed. uri = %s" % uri) + + scheme = scheme.lower() + authority = authority.lower() + + if not path: + path = "/" + + # Could do syntax based normalization of the URI before + # computing the digest. See Section 6.2.2 of Std 66. + request_uri = query and "?".join([path, query]) or path + defrag_uri = scheme + "://" + authority + request_uri + + return defrag_uri + + @classmethod + def cache_url(cls, uri): + return cls._urlnorm(uri) + + def parse_cache_control(self, headers): + known_directives = { + # https://tools.ietf.org/html/rfc7234#section-5.2 + 'max-age': (int, True,), + 'max-stale': (int, False,), + 'min-fresh': (int, True,), + 'no-cache': (None, False,), + 'no-store': (None, False,), + 'no-transform': (None, False,), + 'only-if-cached' : (None, False,), + 'must-revalidate': (None, False,), + 'public': (None, False,), + 'private': (None, False,), + 'proxy-revalidate': (None, False,), + 's-maxage': (int, True,) + } + + cc_headers = headers.get('cache-control', + headers.get('Cache-Control', '')) + + retval = {} + + for cc_directive in cc_headers.split(','): + parts = cc_directive.split('=', 1) + directive = parts[0].strip() + + try: + typ, required = known_directives[directive] + except KeyError: + logger.debug('Ignoring unknown cache-control directive: %s', + directive) + continue + + if not typ or not required: + retval[directive] = None + if typ: + try: + retval[directive] = typ(parts[1].strip()) + except IndexError: + if required: + logger.debug('Missing value for cache-control ' + 'directive: %s', directive) + except ValueError: + logger.debug('Invalid value for cache-control directive ' + '%s, must be %s', directive, typ.__name__) + + return retval + + def cached_request(self, request): + """ + Return a cached response if it exists in the cache, otherwise + return False. + """ + cache_url = self.cache_url(request.url) + logger.debug('Looking up "%s" in the cache', cache_url) + cc = self.parse_cache_control(request.headers) + + # Bail out if the request insists on fresh data + if 'no-cache' in cc: + logger.debug('Request header has "no-cache", cache bypassed') + return False + + if 'max-age' in cc and cc['max-age'] == 0: + logger.debug('Request header has "max_age" as 0, cache bypassed') + return False + + # Request allows serving from the cache, let's see if we find something + cache_data = self.cache.get(cache_url) + if cache_data is None: + logger.debug('No cache entry available') + return False + + # Check whether it can be deserialized + resp = self.serializer.loads(request, cache_data) + if not resp: + logger.warning('Cache entry deserialization failed, entry ignored') + return False + + # If we have a cached 301, return it immediately. We don't + # need to test our response for other headers b/c it is + # intrinsically "cacheable" as it is Permanent. + # See: + # https://tools.ietf.org/html/rfc7231#section-6.4.2 + # + # Client can try to refresh the value by repeating the request + # with cache busting headers as usual (ie no-cache). + if resp.status == 301: + msg = ('Returning cached "301 Moved Permanently" response ' + '(ignoring date and etag information)') + logger.debug(msg) + return resp + + headers = CaseInsensitiveDict(resp.headers) + if not headers or 'date' not in headers: + if 'etag' not in headers: + # Without date or etag, the cached response can never be used + # and should be deleted. + logger.debug('Purging cached response: no date or etag') + self.cache.delete(cache_url) + logger.debug('Ignoring cached response: no date') + return False + + now = time.time() + date = calendar.timegm( + parsedate_tz(headers['date']) + ) + current_age = max(0, now - date) + logger.debug('Current age based on date: %i', current_age) + + # TODO: There is an assumption that the result will be a + # urllib3 response object. This may not be best since we + # could probably avoid instantiating or constructing the + # response until we know we need it. + resp_cc = self.parse_cache_control(headers) + + # determine freshness + freshness_lifetime = 0 + + # Check the max-age pragma in the cache control header + if 'max-age' in resp_cc: + freshness_lifetime = resp_cc['max-age'] + logger.debug('Freshness lifetime from max-age: %i', + freshness_lifetime) + + # If there isn't a max-age, check for an expires header + elif 'expires' in headers: + expires = parsedate_tz(headers['expires']) + if expires is not None: + expire_time = calendar.timegm(expires) - date + freshness_lifetime = max(0, expire_time) + logger.debug("Freshness lifetime from expires: %i", + freshness_lifetime) + + # Determine if we are setting freshness limit in the + # request. Note, this overrides what was in the response. + if 'max-age' in cc: + freshness_lifetime = cc['max-age'] + logger.debug('Freshness lifetime from request max-age: %i', + freshness_lifetime) + + if 'min-fresh' in cc: + min_fresh = cc['min-fresh'] + # adjust our current age by our min fresh + current_age += min_fresh + logger.debug('Adjusted current age from min-fresh: %i', + current_age) + + # Return entry if it is fresh enough + if freshness_lifetime > current_age: + logger.debug('The response is "fresh", returning cached response') + logger.debug('%i > %i', freshness_lifetime, current_age) + return resp + + # we're not fresh. If we don't have an Etag, clear it out + if 'etag' not in headers: + logger.debug( + 'The cached response is "stale" with no etag, purging' + ) + self.cache.delete(cache_url) + + # return the original handler + return False + + def conditional_headers(self, request): + cache_url = self.cache_url(request.url) + resp = self.serializer.loads(request, self.cache.get(cache_url)) + new_headers = {} + + if resp: + headers = CaseInsensitiveDict(resp.headers) + + if 'etag' in headers: + new_headers['If-None-Match'] = headers['ETag'] + + if 'last-modified' in headers: + new_headers['If-Modified-Since'] = headers['Last-Modified'] + + return new_headers + + def cache_response(self, request, response, body=None, + status_codes=None): + """ + Algorithm for caching requests. + + This assumes a requests Response object. + """ + # From httplib2: Don't cache 206's since we aren't going to + # handle byte range requests + cacheable_status_codes = status_codes or self.cacheable_status_codes + if response.status not in cacheable_status_codes: + logger.debug( + 'Status code %s not in %s', + response.status, + cacheable_status_codes + ) + return + + response_headers = CaseInsensitiveDict(response.headers) + + # If we've been given a body, our response has a Content-Length, that + # Content-Length is valid then we can check to see if the body we've + # been given matches the expected size, and if it doesn't we'll just + # skip trying to cache it. + if (body is not None and + "content-length" in response_headers and + response_headers["content-length"].isdigit() and + int(response_headers["content-length"]) != len(body)): + return + + cc_req = self.parse_cache_control(request.headers) + cc = self.parse_cache_control(response_headers) + + cache_url = self.cache_url(request.url) + logger.debug('Updating cache with response from "%s"', cache_url) + + # Delete it from the cache if we happen to have it stored there + no_store = False + if 'no-store' in cc: + no_store = True + logger.debug('Response header has "no-store"') + if 'no-store' in cc_req: + no_store = True + logger.debug('Request header has "no-store"') + if no_store and self.cache.get(cache_url): + logger.debug('Purging existing cache entry to honor "no-store"') + self.cache.delete(cache_url) + + # If we've been given an etag, then keep the response + if self.cache_etags and 'etag' in response_headers: + logger.debug('Caching due to etag') + self.cache.set( + cache_url, + self.serializer.dumps(request, response, body=body), + ) + + # Add to the cache any 301s. We do this before looking that + # the Date headers. + elif response.status == 301: + logger.debug('Caching permanant redirect') + self.cache.set( + cache_url, + self.serializer.dumps(request, response) + ) + + # Add to the cache if the response headers demand it. If there + # is no date header then we can't do anything about expiring + # the cache. + elif 'date' in response_headers: + # cache when there is a max-age > 0 + if 'max-age' in cc and cc['max-age'] > 0: + logger.debug('Caching b/c date exists and max-age > 0') + self.cache.set( + cache_url, + self.serializer.dumps(request, response, body=body), + ) + + # If the request can expire, it means we should cache it + # in the meantime. + elif 'expires' in response_headers: + if response_headers['expires']: + logger.debug('Caching b/c of expires header') + self.cache.set( + cache_url, + self.serializer.dumps(request, response, body=body), + ) + + def update_cached_response(self, request, response): + """On a 304 we will get a new set of headers that we want to + update our cached value with, assuming we have one. + + This should only ever be called when we've sent an ETag and + gotten a 304 as the response. + """ + cache_url = self.cache_url(request.url) + + cached_response = self.serializer.loads( + request, + self.cache.get(cache_url) + ) + + if not cached_response: + # we didn't have a cached response + return response + + # Lets update our headers with the headers from the new request: + # http://tools.ietf.org/html/draft-ietf-httpbis-p4-conditional-26#section-4.1 + # + # The server isn't supposed to send headers that would make + # the cached body invalid. But... just in case, we'll be sure + # to strip out ones we know that might be problmatic due to + # typical assumptions. + excluded_headers = [ + "content-length", + ] + + cached_response.headers.update( + dict((k, v) for k, v in response.headers.items() + if k.lower() not in excluded_headers) + ) + + # we want a 200 b/c we have content via the cache + cached_response.status = 200 + + # update our cache + self.cache.set( + cache_url, + self.serializer.dumps(request, cached_response), + ) + + return cached_response diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/filewrapper.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/filewrapper.py new file mode 100644 index 0000000..f1e1ce0 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/filewrapper.py @@ -0,0 +1,78 @@ +from io import BytesIO + + +class CallbackFileWrapper(object): + """ + Small wrapper around a fp object which will tee everything read into a + buffer, and when that file is closed it will execute a callback with the + contents of that buffer. + + All attributes are proxied to the underlying file object. + + This class uses members with a double underscore (__) leading prefix so as + not to accidentally shadow an attribute. + """ + + def __init__(self, fp, callback): + self.__buf = BytesIO() + self.__fp = fp + self.__callback = callback + + def __getattr__(self, name): + # The vaguaries of garbage collection means that self.__fp is + # not always set. By using __getattribute__ and the private + # name[0] allows looking up the attribute value and raising an + # AttributeError when it doesn't exist. This stop thigns from + # infinitely recursing calls to getattr in the case where + # self.__fp hasn't been set. + # + # [0] https://docs.python.org/2/reference/expressions.html#atom-identifiers + fp = self.__getattribute__('_CallbackFileWrapper__fp') + return getattr(fp, name) + + def __is_fp_closed(self): + try: + return self.__fp.fp is None + except AttributeError: + pass + + try: + return self.__fp.closed + except AttributeError: + pass + + # We just don't cache it then. + # TODO: Add some logging here... + return False + + def _close(self): + if self.__callback: + self.__callback(self.__buf.getvalue()) + + # We assign this to None here, because otherwise we can get into + # really tricky problems where the CPython interpreter dead locks + # because the callback is holding a reference to something which + # has a __del__ method. Setting this to None breaks the cycle + # and allows the garbage collector to do it's thing normally. + self.__callback = None + + def read(self, amt=None): + data = self.__fp.read(amt) + self.__buf.write(data) + if self.__is_fp_closed(): + self._close() + + return data + + def _safe_read(self, amt): + data = self.__fp._safe_read(amt) + if amt == 2 and data == b'\r\n': + # urllib executes this read to toss the CRLF at the end + # of the chunk. + return data + + self.__buf.write(data) + if self.__is_fp_closed(): + self._close() + + return data diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/heuristics.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/heuristics.py new file mode 100644 index 0000000..f182ff0 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/heuristics.py @@ -0,0 +1,138 @@ +import calendar +import time + +from email.utils import formatdate, parsedate, parsedate_tz + +from datetime import datetime, timedelta + +TIME_FMT = "%a, %d %b %Y %H:%M:%S GMT" + + +def expire_after(delta, date=None): + date = date or datetime.utcnow() + return date + delta + + +def datetime_to_header(dt): + return formatdate(calendar.timegm(dt.timetuple())) + + +class BaseHeuristic(object): + + def warning(self, response): + """ + Return a valid 1xx warning header value describing the cache + adjustments. + + The response is provided too allow warnings like 113 + http://tools.ietf.org/html/rfc7234#section-5.5.4 where we need + to explicitly say response is over 24 hours old. + """ + return '110 - "Response is Stale"' + + def update_headers(self, response): + """Update the response headers with any new headers. + + NOTE: This SHOULD always include some Warning header to + signify that the response was cached by the client, not + by way of the provided headers. + """ + return {} + + def apply(self, response): + updated_headers = self.update_headers(response) + + if updated_headers: + response.headers.update(updated_headers) + warning_header_value = self.warning(response) + if warning_header_value is not None: + response.headers.update({'Warning': warning_header_value}) + + return response + + +class OneDayCache(BaseHeuristic): + """ + Cache the response by providing an expires 1 day in the + future. + """ + def update_headers(self, response): + headers = {} + + if 'expires' not in response.headers: + date = parsedate(response.headers['date']) + expires = expire_after(timedelta(days=1), + date=datetime(*date[:6])) + headers['expires'] = datetime_to_header(expires) + headers['cache-control'] = 'public' + return headers + + +class ExpiresAfter(BaseHeuristic): + """ + Cache **all** requests for a defined time period. + """ + + def __init__(self, **kw): + self.delta = timedelta(**kw) + + def update_headers(self, response): + expires = expire_after(self.delta) + return { + 'expires': datetime_to_header(expires), + 'cache-control': 'public', + } + + def warning(self, response): + tmpl = '110 - Automatically cached for %s. Response might be stale' + return tmpl % self.delta + + +class LastModified(BaseHeuristic): + """ + If there is no Expires header already, fall back on Last-Modified + using the heuristic from + http://tools.ietf.org/html/rfc7234#section-4.2.2 + to calculate a reasonable value. + + Firefox also does something like this per + https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching_FAQ + http://lxr.mozilla.org/mozilla-release/source/netwerk/protocol/http/nsHttpResponseHead.cpp#397 + Unlike mozilla we limit this to 24-hr. + """ + cacheable_by_default_statuses = set([ + 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501 + ]) + + def update_headers(self, resp): + headers = resp.headers + + if 'expires' in headers: + return {} + + if 'cache-control' in headers and headers['cache-control'] != 'public': + return {} + + if resp.status not in self.cacheable_by_default_statuses: + return {} + + if 'date' not in headers or 'last-modified' not in headers: + return {} + + date = calendar.timegm(parsedate_tz(headers['date'])) + last_modified = parsedate(headers['last-modified']) + if date is None or last_modified is None: + return {} + + now = time.time() + current_age = max(0, now - date) + delta = date - calendar.timegm(last_modified) + freshness_lifetime = max(0, min(delta / 10, 24 * 3600)) + if freshness_lifetime <= current_age: + return {} + + expires = date + freshness_lifetime + return {'expires': time.strftime(TIME_FMT, time.gmtime(expires))} + + def warning(self, resp): + return None diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/serialize.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/serialize.py new file mode 100644 index 0000000..05b6e24 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/serialize.py @@ -0,0 +1,194 @@ +import base64 +import io +import json +import zlib + +from pip._vendor import msgpack +from pip._vendor.requests.structures import CaseInsensitiveDict + +from .compat import HTTPResponse, pickle, text_type + + +def _b64_decode_bytes(b): + return base64.b64decode(b.encode("ascii")) + + +def _b64_decode_str(s): + return _b64_decode_bytes(s).decode("utf8") + + +class Serializer(object): + + def dumps(self, request, response, body=None): + response_headers = CaseInsensitiveDict(response.headers) + + if body is None: + body = response.read(decode_content=False) + + # NOTE: 99% sure this is dead code. I'm only leaving it + # here b/c I don't have a test yet to prove + # it. Basically, before using + # `cachecontrol.filewrapper.CallbackFileWrapper`, + # this made an effort to reset the file handle. The + # `CallbackFileWrapper` short circuits this code by + # setting the body as the content is consumed, the + # result being a `body` argument is *always* passed + # into cache_response, and in turn, + # `Serializer.dump`. + response._fp = io.BytesIO(body) + + # NOTE: This is all a bit weird, but it's really important that on + # Python 2.x these objects are unicode and not str, even when + # they contain only ascii. The problem here is that msgpack + # understands the difference between unicode and bytes and we + # have it set to differentiate between them, however Python 2 + # doesn't know the difference. Forcing these to unicode will be + # enough to have msgpack know the difference. + data = { + u"response": { + u"body": body, + u"headers": dict( + (text_type(k), text_type(v)) + for k, v in response.headers.items() + ), + u"status": response.status, + u"version": response.version, + u"reason": text_type(response.reason), + u"strict": response.strict, + u"decode_content": response.decode_content, + }, + } + + # Construct our vary headers + data[u"vary"] = {} + if u"vary" in response_headers: + varied_headers = response_headers[u'vary'].split(',') + for header in varied_headers: + header = header.strip() + header_value = request.headers.get(header, None) + if header_value is not None: + header_value = text_type(header_value) + data[u"vary"][header] = header_value + + return b",".join([b"cc=4", msgpack.dumps(data, use_bin_type=True)]) + + def loads(self, request, data): + # Short circuit if we've been given an empty set of data + if not data: + return + + # Determine what version of the serializer the data was serialized + # with + try: + ver, data = data.split(b",", 1) + except ValueError: + ver = b"cc=0" + + # Make sure that our "ver" is actually a version and isn't a false + # positive from a , being in the data stream. + if ver[:3] != b"cc=": + data = ver + data + ver = b"cc=0" + + # Get the version number out of the cc=N + ver = ver.split(b"=", 1)[-1].decode("ascii") + + # Dispatch to the actual load method for the given version + try: + return getattr(self, "_loads_v{0}".format(ver))(request, data) + except AttributeError: + # This is a version we don't have a loads function for, so we'll + # just treat it as a miss and return None + return + + def prepare_response(self, request, cached): + """Verify our vary headers match and construct a real urllib3 + HTTPResponse object. + """ + # Special case the '*' Vary value as it means we cannot actually + # determine if the cached response is suitable for this request. + if "*" in cached.get("vary", {}): + return + + # Ensure that the Vary headers for the cached response match our + # request + for header, value in cached.get("vary", {}).items(): + if request.headers.get(header, None) != value: + return + + body_raw = cached["response"].pop("body") + + headers = CaseInsensitiveDict(data=cached['response']['headers']) + if headers.get('transfer-encoding', '') == 'chunked': + headers.pop('transfer-encoding') + + cached['response']['headers'] = headers + + try: + body = io.BytesIO(body_raw) + except TypeError: + # This can happen if cachecontrol serialized to v1 format (pickle) + # using Python 2. A Python 2 str(byte string) will be unpickled as + # a Python 3 str (unicode string), which will cause the above to + # fail with: + # + # TypeError: 'str' does not support the buffer interface + body = io.BytesIO(body_raw.encode('utf8')) + + return HTTPResponse( + body=body, + preload_content=False, + **cached["response"] + ) + + def _loads_v0(self, request, data): + # The original legacy cache data. This doesn't contain enough + # information to construct everything we need, so we'll treat this as + # a miss. + return + + def _loads_v1(self, request, data): + try: + cached = pickle.loads(data) + except ValueError: + return + + return self.prepare_response(request, cached) + + def _loads_v2(self, request, data): + try: + cached = json.loads(zlib.decompress(data).decode("utf8")) + except (ValueError, zlib.error): + return + + # We need to decode the items that we've base64 encoded + cached["response"]["body"] = _b64_decode_bytes( + cached["response"]["body"] + ) + cached["response"]["headers"] = dict( + (_b64_decode_str(k), _b64_decode_str(v)) + for k, v in cached["response"]["headers"].items() + ) + cached["response"]["reason"] = _b64_decode_str( + cached["response"]["reason"], + ) + cached["vary"] = dict( + (_b64_decode_str(k), _b64_decode_str(v) if v is not None else v) + for k, v in cached["vary"].items() + ) + + return self.prepare_response(request, cached) + + def _loads_v3(self, request, data): + # Due to Python 2 encoding issues, it's impossible to know for sure + # exactly how to load v3 entries, thus we'll treat these as a miss so + # that they get rewritten out as v4 entries. + return + + def _loads_v4(self, request, data): + try: + cached = msgpack.loads(data, encoding='utf-8') + except ValueError: + return + + return self.prepare_response(request, cached) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/wrapper.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/wrapper.py new file mode 100644 index 0000000..b50a6e2 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/wrapper.py @@ -0,0 +1,27 @@ +from .adapter import CacheControlAdapter +from .cache import DictCache + + +def CacheControl(sess, + cache=None, + cache_etags=True, + serializer=None, + heuristic=None, + controller_class=None, + adapter_class=None, + cacheable_methods=None): + + cache = cache or DictCache() + adapter_class = adapter_class or CacheControlAdapter + adapter = adapter_class( + cache, + cache_etags=cache_etags, + serializer=serializer, + heuristic=heuristic, + controller_class=controller_class, + cacheable_methods=cacheable_methods + ) + sess.mount('http://', adapter) + sess.mount('https://', adapter) + + return sess diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__init__.py new file mode 100644 index 0000000..556193c --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__init__.py @@ -0,0 +1,3 @@ +from .core import where, old_where + +__version__ = "2018.01.18" diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__main__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__main__.py new file mode 100644 index 0000000..5f1da0d --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__main__.py @@ -0,0 +1,2 @@ +from certifi import where +print(where()) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/cacert.pem b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/cacert.pem new file mode 100644 index 0000000..101ac98 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/cacert.pem @@ -0,0 +1,4433 @@ + +# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Label: "GlobalSign Root CA" +# Serial: 4835703278459707669005204 +# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a +# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c +# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99 +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 +# Label: "GlobalSign Root CA - R2" +# Serial: 4835703278459682885658125 +# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30 +# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe +# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 +MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL +v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 +eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq +tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd +C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa +zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB +mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH +V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n +bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG +3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs +J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO +291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS +ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd +AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only +# Label: "Verisign Class 3 Public Primary Certification Authority - G3" +# Serial: 206684696279472310254277870180966723415 +# MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09 +# SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6 +# SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44 +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b +N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t +KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu +kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm +CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ +Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu +imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te +2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe +DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p +F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt +TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Label: "Entrust.net Premium 2048 Secure Server CA" +# Serial: 946069240 +# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90 +# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31 +# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77 +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Label: "Baltimore CyberTrust Root" +# Serial: 33554617 +# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4 +# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74 +# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +# Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network +# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network +# Label: "AddTrust External Root" +# Serial: 1 +# MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f +# SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68 +# SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2 +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs +IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 +MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h +bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt +H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 +uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX +mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX +a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN +E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 +WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD +VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 +Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU +cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx +IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN +AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH +YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC +Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX +c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a +mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Label: "Entrust Root Certification Authority" +# Serial: 1164660820 +# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4 +# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9 +# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Global CA O=GeoTrust Inc. +# Subject: CN=GeoTrust Global CA O=GeoTrust Inc. +# Label: "GeoTrust Global CA" +# Serial: 144470 +# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5 +# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12 +# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg +R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 +9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq +fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv +iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU +1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ +bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW +MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA +ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l +uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn +Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS +tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF +PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un +hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV +5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc. +# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc. +# Label: "GeoTrust Universal CA" +# Serial: 1 +# MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48 +# SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79 +# SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12 +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy +c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0 +IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV +VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8 +cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT +QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh +F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v +c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w +mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd +VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX +teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ +f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe +Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+ +nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB +/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY +MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG +9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX +IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn +ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z +uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN +Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja +QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW +koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9 +ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt +DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm +bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. +# Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. +# Label: "GeoTrust Universal CA 2" +# Serial: 1 +# MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7 +# SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79 +# SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy +c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD +VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1 +c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81 +WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG +FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq +XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL +se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb +KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd +IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73 +y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt +hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc +QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4 +Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV +HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ +KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ +L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr +Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo +ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY +T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz +GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m +1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV +OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH +6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX +QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----END CERTIFICATE----- + +# Issuer: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association +# Subject: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association +# Label: "Visa eCommerce Root" +# Serial: 25952180776285836048024890241505565794 +# MD5 Fingerprint: fc:11:b8:d8:08:93:30:00:6d:23:f9:7e:eb:52:1e:02 +# SHA1 Fingerprint: 70:17:9b:86:8c:00:a4:fa:60:91:52:22:3f:9f:3e:32:bd:e0:05:62 +# SHA256 Fingerprint: 69:fa:c9:bd:55:fb:0a:c7:8d:53:bb:ee:5c:f1:d5:97:98:9f:d0:aa:ab:20:a2:51:51:bd:f1:73:3e:e7:d1:22 +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr +MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl +cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv +bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw +CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h +dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l +cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h +2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E +lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV +ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq +299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t +vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL +dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF +AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR +zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3 +LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd +7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw +++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt +398znM/jra6O1I7mT1GvFpLgXPYHDw== +-----END CERTIFICATE----- + +# Issuer: CN=AAA Certificate Services O=Comodo CA Limited +# Subject: CN=AAA Certificate Services O=Comodo CA Limited +# Label: "Comodo AAA Services root" +# Serial: 1 +# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0 +# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49 +# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4 +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority +# Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority +# Label: "QuoVadis Root CA" +# Serial: 985026699 +# MD5 Fingerprint: 27:de:36:fe:72:b7:00:03:00:9d:f4:f0:1e:6c:04:24 +# SHA1 Fingerprint: de:3f:40:bd:50:93:d3:9b:6c:60:f6:da:bc:07:62:01:00:89:76:c9 +# SHA256 Fingerprint: a4:5e:de:3b:bb:f0:9c:8a:e1:5c:72:ef:c0:72:68:d6:93:a2:1c:99:6f:d5:1e:67:ca:07:94:60:fd:6d:88:73 +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz +MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw +IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR +dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp +li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D +rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ +WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug +F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU +xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC +Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv +dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw +ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl +IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh +c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy +ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI +KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T +KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq +y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p +dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD +VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk +fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 +7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R +cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y +mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW +xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK +SnQ2+Q== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2" +# Serial: 1289 +# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b +# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7 +# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86 +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3" +# Serial: 1478 +# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf +# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85 +# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35 +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1 +# Subject: O=SECOM Trust.net OU=Security Communication RootCA1 +# Label: "Security Communication Root CA" +# Serial: 0 +# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a +# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7 +# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY +MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t +dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 +WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD +VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 +9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ +DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 +Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N +QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ +xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G +A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG +kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr +Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 +Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU +JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot +RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== +-----END CERTIFICATE----- + +# Issuer: CN=Sonera Class2 CA O=Sonera +# Subject: CN=Sonera Class2 CA O=Sonera +# Label: "Sonera Class 2 Root CA" +# Serial: 29 +# MD5 Fingerprint: a3:ec:75:0f:2e:88:df:fa:48:01:4e:0b:5c:48:6f:fb +# SHA1 Fingerprint: 37:f7:6d:e6:07:7c:90:c5:b1:3e:93:1a:b7:41:10:b4:f2:e4:9a:27 +# SHA256 Fingerprint: 79:08:b4:03:14:c1:38:10:0b:51:8d:07:35:80:7f:fb:fc:f8:51:8a:00:95:33:71:05:ba:38:6b:15:3d:d9:27 +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP +MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx +MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV +BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o +Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt +5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s +3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej +vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu +8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw +DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil +zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ +3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD +FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 +Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 +ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M +-----END CERTIFICATE----- + +# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Label: "XRamp Global CA Root" +# Serial: 107108908803651509692980124233745014957 +# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1 +# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6 +# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2 +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Label: "Go Daddy Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67 +# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4 +# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4 +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- + +# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Label: "Starfield Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24 +# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a +# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58 +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +# Issuer: O=Government Root Certification Authority +# Subject: O=Government Root Certification Authority +# Label: "Taiwan GRCA" +# Serial: 42023070807708724159991140556527066870 +# MD5 Fingerprint: 37:85:44:53:32:45:1f:20:f0:f3:95:e1:25:c4:43:4e +# SHA1 Fingerprint: f4:8b:11:bf:de:ab:be:94:54:20:71:e6:41:de:6b:be:88:2b:40:b9 +# SHA256 Fingerprint: 76:00:29:5e:ef:e8:5b:9e:1f:d6:24:db:76:06:2a:aa:ae:59:81:8a:54:d2:77:4c:d4:c0:b2:c0:11:31:e1:b3 +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/ +MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow +PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR +IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q +gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy +yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts +F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2 +jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx +ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC +VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK +YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH +EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN +Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud +DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE +MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK +UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ +TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf +qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK +ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE +JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7 +hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1 +EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm +nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX +udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz +ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe +LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl +pYYsfPQS +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root CA" +# Serial: 17154717934120587862167794914071425081 +# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 +# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 +# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root CA" +# Serial: 10944719598952040374951832963794454346 +# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e +# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36 +# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61 +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert High Assurance EV Root CA" +# Serial: 3553400076410547919724730734378100087 +# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a +# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25 +# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- + +# Issuer: CN=Class 2 Primary CA O=Certplus +# Subject: CN=Class 2 Primary CA O=Certplus +# Label: "Certplus Class 2 Primary CA" +# Serial: 177770208045934040241468760488327595043 +# MD5 Fingerprint: 88:2c:8c:52:b8:a2:3c:f3:f7:bb:03:ea:ae:ac:42:0b +# SHA1 Fingerprint: 74:20:74:41:72:9c:dd:92:ec:79:31:d8:23:10:8d:c2:81:92:e2:bb +# SHA256 Fingerprint: 0f:99:3c:8a:ef:97:ba:af:56:87:14:0e:d5:9a:d1:82:1b:b4:af:ac:f0:aa:9a:58:b5:d5:7a:33:8a:3a:fb:cb +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw +PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz +cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 +MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz +IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ +ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR +VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL +kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd +EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas +H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 +HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud +DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 +QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu +Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ +AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 +yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR +FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA +ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB +kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- + +# Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co. +# Subject: CN=DST Root CA X3 O=Digital Signature Trust Co. +# Label: "DST Root CA X3" +# Serial: 91299735575339953335919266965803778155 +# MD5 Fingerprint: 41:03:52:dc:0f:f7:50:1b:16:f0:02:8e:ba:6f:45:c5 +# SHA1 Fingerprint: da:c9:02:4f:54:d8:f6:df:94:93:5f:b1:73:26:38:ca:6a:d7:7c:13 +# SHA256 Fingerprint: 06:87:26:03:31:a7:24:03:d9:09:f1:05:e6:9b:cf:0d:32:e1:bd:24:93:ff:c6:d9:20:6d:11:bc:d6:77:07:39 +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow +PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O +rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq +OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b +xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw +7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD +aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG +SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 +ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr +AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz +R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 +JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo +Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Label: "SwissSign Gold CA - G2" +# Serial: 13492815561806991280 +# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93 +# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61 +# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Label: "SwissSign Silver CA - G2" +# Serial: 5700383053117599563 +# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13 +# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb +# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. +# Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. +# Label: "GeoTrust Primary Certification Authority" +# Serial: 32798226551256963324313806436981982369 +# MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf +# SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96 +# SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY +MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo +R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx +MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 +AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA +ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 +7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W +kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI +mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ +KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 +6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl +4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K +oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj +UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU +AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA" +# Serial: 69529181992039203566298953787712940909 +# MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12 +# SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81 +# SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw +NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j +LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG +A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs +W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta +3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk +6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 +Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J +NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP +r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU +DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz +YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 +/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ +LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 +jVaMaA== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Class 3 Public Primary Certification Authority - G5" +# Serial: 33037644167568058970164719475676101450 +# MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c +# SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5 +# SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 +nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex +t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz +SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG +BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ +rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ +NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH +BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv +MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE +p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y +5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK +WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ +4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N +hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- + +# Issuer: CN=SecureTrust CA O=SecureTrust Corporation +# Subject: CN=SecureTrust CA O=SecureTrust Corporation +# Label: "SecureTrust CA" +# Serial: 17199774589125277788362757014266862032 +# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1 +# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11 +# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73 +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +# Issuer: CN=Secure Global CA O=SecureTrust Corporation +# Subject: CN=Secure Global CA O=SecureTrust Corporation +# Label: "Secure Global CA" +# Serial: 9751836167731051554232119481456978597 +# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de +# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b +# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69 +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO Certification Authority O=COMODO CA Limited +# Label: "COMODO Certification Authority" +# Serial: 104350513648249232941998508985834464573 +# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75 +# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b +# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66 +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- + +# Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. +# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. +# Label: "Network Solutions Certificate Authority" +# Serial: 116697915152937497490437556386812487904 +# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e +# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce +# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi +MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV +UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO +ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz +c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP +OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl +mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF +BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 +qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw +gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu +bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp +dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 +6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ +h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH +/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN +pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Label: "COMODO ECC Certification Authority" +# Serial: 41578283867086692638256921589707938090 +# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 +# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 +# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GA CA" +# Serial: 86718877871133159090080555911823548314 +# MD5 Fingerprint: bc:6c:51:33:a7:e9:d3:66:63:54:15:72:1b:21:92:93 +# SHA1 Fingerprint: 59:22:a1:e1:5a:ea:16:35:21:f8:98:39:6a:46:46:b0:44:1b:0f:a9 +# SHA256 Fingerprint: 41:c9:23:86:6a:b4:ca:d6:b7:ad:57:80:81:58:2e:02:07:97:a6:cb:df:4f:ff:78:ce:83:96:b3:89:37:d7:f5 +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB +ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly +aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl +ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w +NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G +A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD +VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX +SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR +VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2 +w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF +mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg +4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9 +4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw +EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx +SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2 +ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8 +vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa +hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi +Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ +/L7fCg0= +-----END CERTIFICATE----- + +# Issuer: CN=Certigna O=Dhimyotis +# Subject: CN=Certigna O=Dhimyotis +# Label: "Certigna" +# Serial: 18364802974209362175 +# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff +# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97 +# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w +t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +# Issuer: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center +# Subject: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center +# Label: "Deutsche Telekom Root CA 2" +# Serial: 38 +# MD5 Fingerprint: 74:01:4a:91:b1:08:c4:58:ce:47:cd:f0:dd:11:53:08 +# SHA1 Fingerprint: 85:a4:08:c0:9c:19:3e:5d:51:58:7d:cd:d6:13:30:fd:8c:de:37:bf +# SHA256 Fingerprint: b6:19:1a:50:d0:c3:97:7f:7d:a9:9b:cd:aa:c8:6a:22:7d:ae:b9:67:9e:c7:0b:a3:b0:c9:d9:22:71:c1:70:d3 +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc +MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj +IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB +IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE +RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl +U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290 +IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU +ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC +QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr +rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S +NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc +QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH +txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP +BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC +AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp +tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa +IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl +6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+ +xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- + +# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc +# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc +# Label: "Cybertrust Global Root" +# Serial: 4835703278459682877484360 +# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1 +# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6 +# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3 +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG +A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh +bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE +ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS +b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 +7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS +J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y +HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP +t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz +FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY +XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ +MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw +hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js +MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA +A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj +Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx +XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o +omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc +A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- + +# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Label: "ePKI Root Certification Authority" +# Serial: 28956088682735189655030529057352760477 +# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3 +# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0 +# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5 +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +# Issuer: O=certSIGN OU=certSIGN ROOT CA +# Subject: O=certSIGN OU=certSIGN ROOT CA +# Label: "certSIGN ROOT CA" +# Serial: 35210227249154 +# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17 +# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b +# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN +9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only +# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only +# Label: "GeoTrust Primary Certification Authority - G3" +# Serial: 28809105769928564313984085209975885599 +# MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05 +# SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd +# SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4 +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB +mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT +MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ +BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 +BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz ++uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm +hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn +5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W +JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL +DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC +huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw +HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB +AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB +zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN +kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH +SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G +spki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA - G2" +# Serial: 71758320672825410020661621085256472406 +# MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f +# SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12 +# SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57 +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp +IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi +BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw +MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig +YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v +dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/ +BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6 +papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K +DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 +KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox +XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA - G3" +# Serial: 127614157056681299805556476275995414779 +# MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31 +# SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2 +# SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB +rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV +BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa +Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl +LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u +MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm +gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 +YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf +b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 +9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S +zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk +OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA +2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW +oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c +KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM +m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu +MdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only +# Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only +# Label: "GeoTrust Primary Certification Authority - G2" +# Serial: 80682863203381065782177908751794619243 +# MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a +# SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0 +# SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66 +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +rD6ogRLQy7rQkgu2npaqBA+K +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Universal Root Certification Authority" +# Serial: 85209574734084581917763752644031726877 +# MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19 +# SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54 +# SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB +vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W +ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 +IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y +IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh +bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF +9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH +H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H +LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN +/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT +rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw +WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs +exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 +sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ +seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz +4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ +BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR +lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 +7M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Class 3 Public Primary Certification Authority - G4" +# Serial: 63143484348153506665311985501458640051 +# MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41 +# SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a +# SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79 +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp +U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg +SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln +biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm +GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve +fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ +aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj +aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW +kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC +4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga +FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----END CERTIFICATE----- + +# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny" +# Serial: 80544274841616 +# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 +# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 +# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden +# Label: "Staat der Nederlanden Root CA - G2" +# Serial: 10000012 +# MD5 Fingerprint: 7c:a5:0f:f8:5b:9a:7d:6d:30:ae:54:5a:e3:42:a2:8a +# SHA1 Fingerprint: 59:af:82:79:91:86:c7:b4:75:07:cb:cf:03:57:46:eb:04:dd:b7:16 +# SHA256 Fingerprint: 66:8c:83:94:7d:a6:3b:72:4b:ec:e1:74:3c:31:a0:e6:ae:d0:db:8e:c5:b3:1b:e3:77:bb:78:4f:91:b6:71:6f +-----BEGIN CERTIFICATE----- +MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX +DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291 +qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp +uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU +Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE +pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp +5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M +UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN +GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy +5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv +6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK +eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6 +B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/ +BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov +L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG +SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS +CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen +5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897 +IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK +gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL ++63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL +vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm +bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk +N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC +Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z +ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ== +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post +# Label: "Hongkong Post Root CA 1" +# Serial: 1000 +# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca +# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58 +# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2 +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx +FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg +Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG +A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr +b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ +jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn +PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh +ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 +nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h +q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED +MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC +mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 +7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB +oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs +EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO +fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi +AmvZWg== +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Label: "SecureSign RootCA11" +# Serial: 1 +# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26 +# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3 +# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12 +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr +MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG +A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 +MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp +Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD +QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz +i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 +h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV +MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 +UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni +8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC +h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm +KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ +X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr +QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 +pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN +QSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Label: "Microsec e-Szigno Root CA 2009" +# Serial: 14014712776195784473 +# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 +# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e +# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Label: "GlobalSign Root CA - R3" +# Serial: 4835703278459759426209954 +# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 +# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad +# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 6047274297262753887 +# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3 +# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa +# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy +MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD +VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv +ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl +AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF +661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 +am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 +ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 +PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS +3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k +SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF +3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM +ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g +StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz +Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB +jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +# Issuer: CN=Izenpe.com O=IZENPE S.A. +# Subject: CN=Izenpe.com O=IZENPE S.A. +# Label: "Izenpe.com" +# Serial: 917563065490389241595536686991402621 +# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 +# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 +# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. +# Subject: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. +# Label: "Chambers of Commerce Root - 2008" +# Serial: 11806822484801597146 +# MD5 Fingerprint: 5e:80:9e:84:5a:0e:65:0b:17:02:f3:55:18:2a:3e:d7 +# SHA1 Fingerprint: 78:6a:74:ac:76:ab:14:7f:9c:6a:30:50:ba:9e:a8:7e:fe:9a:ce:3c +# SHA256 Fingerprint: 06:3e:4a:fa:c4:91:df:d3:32:f3:08:9b:85:42:e9:46:17:d8:93:d7:fe:94:4e:10:a7:93:7e:e2:9d:96:93:c0 +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz +IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz +MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj +dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw +EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp +MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 +28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq +VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q +DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR +5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL +ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a +Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl +UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s ++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 +Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx +hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV +HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 ++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN +YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t +L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy +ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt +IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV +HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w +DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW +PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF +5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 +glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH +FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 +pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD +xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG +tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq +jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De +fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ +d0jQ +-----END CERTIFICATE----- + +# Issuer: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. +# Subject: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. +# Label: "Global Chambersign Root - 2008" +# Serial: 14541511773111788494 +# MD5 Fingerprint: 9e:80:ff:78:01:0c:2e:c1:36:bd:fe:96:90:6e:08:f3 +# SHA1 Fingerprint: 4a:bd:ee:ec:95:0d:35:9c:89:ae:c7:52:a1:2c:5b:29:f6:d6:aa:0c +# SHA256 Fingerprint: 13:63:35:43:93:34:a7:69:80:16:a0:d3:24:de:72:28:4e:07:9d:7b:52:20:bb:8f:bd:74:78:16:ee:be:ba:ca +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx +MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy +cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG +A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl +BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed +KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 +G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 +zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 +ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG +HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 +Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V +yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e +beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r +6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog +zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW +BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr +ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp +ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk +cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt +YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC +CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow +KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI +hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ +UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz +X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x +fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz +a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd +Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd +SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O +AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso +M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge +v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- + +# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Label: "Go Daddy Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 +# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b +# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 +# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e +# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Services Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 +# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f +# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Commercial O=AffirmTrust +# Subject: CN=AffirmTrust Commercial O=AffirmTrust +# Label: "AffirmTrust Commercial" +# Serial: 8608355977964138876 +# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7 +# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7 +# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7 +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Networking O=AffirmTrust +# Subject: CN=AffirmTrust Networking O=AffirmTrust +# Label: "AffirmTrust Networking" +# Serial: 8957382827206547757 +# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f +# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f +# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium O=AffirmTrust +# Subject: CN=AffirmTrust Premium O=AffirmTrust +# Label: "AffirmTrust Premium" +# Serial: 7893706540734352110 +# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57 +# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27 +# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust +# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust +# Label: "AffirmTrust Premium ECC" +# Serial: 8401224907861490260 +# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d +# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb +# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23 +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA" +# Serial: 279744 +# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 +# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e +# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Label: "TWCA Root Certification Authority" +# Serial: 1 +# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 +# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 +# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Label: "Security Communication RootCA2" +# Serial: 0 +# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 +# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 +# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2011" +# Serial: 0 +# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9 +# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d +# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71 +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix +RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p +YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw +NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK +EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl +cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz +dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ +fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns +bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD +75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP +FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV +HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp +5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu +b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA +A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p +6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 +dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys +Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI +l7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- + +# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Label: "Actalis Authentication Root CA" +# Serial: 6271844772424770508 +# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 +# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac +# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +# Issuer: O=Trustis Limited OU=Trustis FPS Root CA +# Subject: O=Trustis Limited OU=Trustis FPS Root CA +# Label: "Trustis FPS Root CA" +# Serial: 36053640375399034304724988975563710553 +# MD5 Fingerprint: 30:c9:e7:1e:6b:e6:14:eb:65:b2:16:69:20:31:67:4d +# SHA1 Fingerprint: 3b:c0:38:0b:33:c3:f6:a6:0c:86:15:22:93:d9:df:f5:4b:81:c0:04 +# SHA256 Fingerprint: c1:b4:82:99:ab:a5:20:8f:e9:63:0a:ce:55:ca:68:a0:3e:da:5a:51:9c:88:02:a0:d3:a6:73:be:8f:8e:55:7d +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL +ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx +MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc +MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ +AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH +iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj +vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA +0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB +OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ +BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E +FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 +GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW +zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 +1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE +f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F +jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN +ZetX2fNXlrtIzYE= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 2 Root CA" +# Serial: 2 +# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 +# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 +# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 3 Root CA" +# Serial: 2 +# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec +# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 +# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 3" +# Serial: 1 +# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef +# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 +# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- + +# Issuer: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus +# Subject: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus +# Label: "EE Certification Centre Root CA" +# Serial: 112324828676200291871926431888494945866 +# MD5 Fingerprint: 43:5e:88:d4:7d:1a:4a:7e:fd:84:2e:52:eb:01:d4:6f +# SHA1 Fingerprint: c9:a8:b9:e7:55:80:5e:58:e3:53:77:a7:25:eb:af:c3:7b:27:cc:d7 +# SHA256 Fingerprint: 3e:84:ba:43:42:90:85:16:e7:75:73:c0:99:2f:09:79:ca:08:4e:46:85:68:1f:f1:95:cc:ba:8a:22:9b:8a:76 +-----BEGIN CERTIFICATE----- +MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1 +MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 +czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG +CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy +MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl +ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS +b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy +euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO +bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw +WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d +MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE +1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/ +zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB +BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF +BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV +v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG +E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u +uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW +iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v +GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 2009" +# Serial: 623603 +# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f +# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0 +# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1 +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 EV 2009" +# Serial: 623604 +# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6 +# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83 +# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81 +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +# Issuer: CN=CA Disig Root R2 O=Disig a.s. +# Subject: CN=CA Disig Root R2 O=Disig a.s. +# Label: "CA Disig Root R2" +# Serial: 10572350602393338211 +# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03 +# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71 +# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03 +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Label: "ACCVRAIZ1" +# Serial: 6828503384748696800 +# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02 +# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17 +# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13 +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Label: "TWCA Global Root CA" +# Serial: 3262 +# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96 +# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65 +# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- + +# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Label: "TeliaSonera Root CA v1" +# Serial: 199041966741090107964904287217786801558 +# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c +# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37 +# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89 +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +# Issuer: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi +# Subject: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi +# Label: "E-Tugra Certification Authority" +# Serial: 7667447206703254355 +# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49 +# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39 +# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC +aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV +BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 +Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz +MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ +BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp +em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY +B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH +D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF +Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo +q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D +k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH +fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut +dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM +ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 +zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX +U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 +Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 +XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF +Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR +HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY +GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c +77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 ++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK +vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 +FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl +yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P +AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD +y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d +NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 2" +# Serial: 1 +# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a +# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9 +# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52 +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot 2011 O=Atos +# Subject: CN=Atos TrustedRoot 2011 O=Atos +# Label: "Atos TrustedRoot 2011" +# Serial: 6643877497813316402 +# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56 +# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21 +# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 1 G3" +# Serial: 687049649626669250736271037606554624078720034195 +# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab +# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67 +# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2 G3" +# Serial: 390156079458959257446133169266079962026824725800 +# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06 +# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36 +# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3 G3" +# Serial: 268090761170461462463995952157327242137089239581 +# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7 +# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d +# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G2" +# Serial: 15385348160840213938643033620894905419 +# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d +# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f +# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85 +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G3" +# Serial: 15459312981008553731928384953135426796 +# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb +# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89 +# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2 +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G2" +# Serial: 4293743540046975378534879503202253541 +# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44 +# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4 +# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G3" +# Serial: 7089244469030293291760083333884364146 +# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca +# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e +# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0 +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Trusted Root G4" +# Serial: 7451500558977370777930084869016614236 +# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49 +# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4 +# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88 +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- + +# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Label: "COMODO RSA Certification Authority" +# Serial: 101909084537582093308941363524873193117 +# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18 +# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4 +# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34 +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Label: "USERTrust RSA Certification Authority" +# Serial: 2645093764781058787591871645665788717 +# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 +# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e +# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Label: "USERTrust ECC Certification Authority" +# Serial: 123013823720199481456569720443997572134 +# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1 +# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0 +# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Label: "GlobalSign ECC Root CA - R4" +# Serial: 14367148294922964480859022125800977897474 +# MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e +# SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb +# SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ +FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F +uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX +kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs +ewv4n4Q= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Label: "GlobalSign ECC Root CA - R5" +# Serial: 32785792099990507226680698011560947931244 +# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08 +# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa +# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24 +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Label: "Staat der Nederlanden Root CA - G3" +# Serial: 10003001 +# MD5 Fingerprint: 0b:46:67:07:db:10:2f:19:8c:35:50:60:d1:0b:f4:37 +# SHA1 Fingerprint: d8:eb:6b:41:51:92:59:e0:f3:e7:85:00:c0:3d:b6:88:97:c9:ee:fc +# SHA256 Fingerprint: 3c:4f:b0:b9:5a:b8:b3:00:32:f4:32:b8:6f:53:5f:e1:72:c1:85:d0:fd:39:86:58:37:cf:36:18:7f:a6:f4:28 +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX +DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP +cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW +IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX +xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy +KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR +9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az +5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 +6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 +Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP +bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt +BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt +XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd +INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp +LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 +Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp +gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh +/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw +0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A +fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq +4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR +1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ +QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM +94B7IWcnMFk= +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Label: "Staat der Nederlanden EV Root CA" +# Serial: 10000013 +# MD5 Fingerprint: fc:06:af:7b:e8:1a:f1:9a:b4:e8:d2:70:1f:c0:f5:ba +# SHA1 Fingerprint: 76:e2:7e:c1:4f:db:82:c1:c0:a6:75:b5:05:be:3d:29:b4:ed:db:bb +# SHA256 Fingerprint: 4d:24:91:41:4c:fe:95:67:46:ec:4c:ef:a6:cf:6f:72:e2:8a:13:29:43:2f:9d:8a:90:7a:c4:cb:5d:ad:c1:5a +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y +MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg +TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS +M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC +UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d +Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p +rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l +pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb +j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC +KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS +/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X +cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH +1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP +px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 +MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u +2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS +v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC +wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy +CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e +vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 +Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa +Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL +eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 +FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc +7uzXLg== +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Label: "IdenTrust Commercial Root CA 1" +# Serial: 13298821034946342390520003877796839426 +# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 +# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 +# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Label: "IdenTrust Public Sector Root CA 1" +# Serial: 13298821034946342390521976156843933698 +# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba +# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd +# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G2" +# Serial: 1246989352 +# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2 +# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4 +# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39 +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - EC1" +# Serial: 51543124481930649114116133369 +# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc +# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47 +# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5 +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority +# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority +# Label: "CFCA EV ROOT" +# Serial: 407555286 +# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 +# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 +# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +# Issuer: CN=T\xdcRKTRUST Elektronik Sertifika Hizmet Sa\u011flay\u0131c\u0131s\u0131 H5 O=T\xdcRKTRUST Bilgi \u0130leti\u015fim ve Bili\u015fim G\xfcvenli\u011fi Hizmetleri A.\u015e. +# Subject: CN=T\xdcRKTRUST Elektronik Sertifika Hizmet Sa\u011flay\u0131c\u0131s\u0131 H5 O=T\xdcRKTRUST Bilgi \u0130leti\u015fim ve Bili\u015fim G\xfcvenli\u011fi Hizmetleri A.\u015e. +# Label: "T\xdcRKTRUST Elektronik Sertifika Hizmet Sa\u011flay\u0131c\u0131s\u0131 H5" +# Serial: 156233699172481 +# MD5 Fingerprint: da:70:8e:f0:22:df:93:26:f6:5f:9f:d3:15:06:52:4e +# SHA1 Fingerprint: c4:18:f6:4d:46:d1:df:00:3d:27:30:13:72:43:a9:12:11:c6:75:fb +# SHA256 Fingerprint: 49:35:1b:90:34:44:c1:85:cc:dc:5c:69:3d:24:d8:55:5c:b2:08:d6:a8:14:13:07:69:9f:4a:f0:63:19:9d:78 +-----BEGIN CERTIFICATE----- +MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UE +BhMCVFIxDzANBgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxn +aSDEsGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkg +QS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1QgRWxla3Ryb25payBTZXJ0aWZpa2Eg +SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAwODA3MDFaFw0yMzA0 +MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYD +VQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8 +dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApCUZ4WWe60ghUEoI5RHwWrom +/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537jVJp45wnEFPzpALFp/kR +Gml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1mep5Fimh3 +4khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z +5UNP9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0 +hO8EuPbJbKoCPrZV4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QID +AQABo0IwQDAdBgNVHQ4EFgQUVpkHHtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJ5FdnsX +SDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPoBP5yCccLqh0l +VX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq +URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nf +peYVhDfwwvJllpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CF +Yv4HAqGEVka+lgqaE9chTLd8B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW ++qtB4Uu2NQvAmxU= +-----END CERTIFICATE----- + +# Issuer: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903 +# Subject: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903 +# Label: "Certinomis - Root CA" +# Serial: 1 +# MD5 Fingerprint: 14:0a:fd:8d:a8:28:b5:38:69:db:56:7e:61:22:03:3f +# SHA1 Fingerprint: 9d:70:bb:01:a5:a4:a0:18:11:2e:f7:1c:01:b9:32:c5:34:e7:88:a8 +# SHA256 Fingerprint: 2a:99:f5:bc:11:74:b7:3c:bb:1d:62:08:84:e0:1c:34:e5:1c:cb:39:78:da:12:5f:0e:33:26:88:83:bf:41:58 +-----BEGIN CERTIFICATE----- +MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET +MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb +BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz +MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx +FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g +Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2 +fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl +LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV +WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF +TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb +5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc +CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri +wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ +wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG +m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4 +F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng +WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0 +2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF +AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/ +0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw +F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS +g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj +qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN +h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/ +ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V +btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj +Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ +8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW +gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GB CA" +# Serial: 157768595616588414422159278966750757568 +# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d +# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed +# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Label: "SZAFIR ROOT CA2" +# Serial: 357043034767186914217277344587386743377558296292 +# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 +# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de +# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA 2" +# Serial: 44979900017204383099463764357512596969 +# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 +# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 +# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce +# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 +# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef +# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 +# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +# Issuer: CN=Certplus Root CA G1 O=Certplus +# Subject: CN=Certplus Root CA G1 O=Certplus +# Label: "Certplus Root CA G1" +# Serial: 1491911565779898356709731176965615564637713 +# MD5 Fingerprint: 7f:09:9c:f7:d9:b9:5c:69:69:56:d5:37:3e:14:0d:42 +# SHA1 Fingerprint: 22:fd:d0:b7:fd:a2:4e:0d:ac:49:2c:a0:ac:a6:7b:6a:1f:e3:f7:66 +# SHA256 Fingerprint: 15:2a:40:2b:fc:df:2c:d5:48:05:4d:22:75:b3:9c:7f:ca:3e:c0:97:80:78:b0:f0:ea:76:e5:61:a6:c7:43:3e +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUA +MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy +dHBsdXMgUm9vdCBDQSBHMTAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBa +MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy +dHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +ANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHNr49a +iZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt +6kuJPKNxQv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP +0FG7Yn2ksYyy/yARujVjBYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f +6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTvLRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDE +EW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2z4QTd28n6v+WZxcIbekN +1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc4nBvCGrc +h2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCT +mehd4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV +4EJQeIQEQWGw9CEjjy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPO +WftwenMGE9nTdDckQQoRb5fc5+R+ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1Ud +DwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSowcCbkahDFXxd +Bie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHYlwuBsTANBgkq +hkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh +66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7 +/SMNkPX0XtPGYX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BS +S7CTKtQ+FjPlnsZlFT5kOwQ/2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j +2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F6ALEUz65noe8zDUa3qHpimOHZR4R +Kttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilXCNQ314cnrUlZp5Gr +RHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWetUNy +6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEV +V/xuZDDCVRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5 +g4VCXA9DO2pJNdWY9BW/+mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl +++O/QmueD6i9a5jc2NvLi6Td11n0bt3+qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo= +-----END CERTIFICATE----- + +# Issuer: CN=Certplus Root CA G2 O=Certplus +# Subject: CN=Certplus Root CA G2 O=Certplus +# Label: "Certplus Root CA G2" +# Serial: 1492087096131536844209563509228951875861589 +# MD5 Fingerprint: a7:ee:c4:78:2d:1b:ee:2d:b9:29:ce:d6:a7:96:32:31 +# SHA1 Fingerprint: 4f:65:8e:1f:e9:06:d8:28:02:e9:54:47:41:c9:54:25:5d:69:cc:1a +# SHA256 Fingerprint: 6c:c0:50:41:e6:44:5e:74:69:6c:4c:fb:c9:f8:0f:54:3b:7e:ab:bb:44:b4:ce:6f:78:7c:6a:99:71:c4:2f:17 +-----BEGIN CERTIFICATE----- +MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4x +CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs +dXMgUm9vdCBDQSBHMjAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4x +CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs +dXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABM0PW1aC3/BFGtat +93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uNAm8x +Ik0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0P +AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwj +FNiPwyCrKGBZMB8GA1UdIwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqG +SM49BAMDA2gAMGUCMHD+sAvZ94OX7PNVHdTcswYO/jOYnYs5kGuUIe22113WTNch +p+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjlvPl5adytRSv3tjFzzAal +U5ORGpOucGpnutee5WEaXw== +-----END CERTIFICATE----- + +# Issuer: CN=OpenTrust Root CA G1 O=OpenTrust +# Subject: CN=OpenTrust Root CA G1 O=OpenTrust +# Label: "OpenTrust Root CA G1" +# Serial: 1492036577811947013770400127034825178844775 +# MD5 Fingerprint: 76:00:cc:81:29:cd:55:5e:88:6a:7a:2e:f7:4d:39:da +# SHA1 Fingerprint: 79:91:e8:34:f7:e2:ee:dd:08:95:01:52:e9:55:2d:14:e9:58:d5:7e +# SHA256 Fingerprint: 56:c7:71:28:d9:8c:18:d9:1b:4c:fd:ff:bc:25:ee:91:03:d4:75:8e:a2:ab:ad:82:6a:90:f3:45:7d:46:0e:b4 +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUA +MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w +ZW5UcnVzdCBSb290IENBIEcxMB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAw +MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU +T3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7faYp6b +wiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX +/uMftk87ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR0 +77F9jAHiOH3BX2pfJLKOYheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGP +uY4zbGneWK2gDqdkVBFpRGZPTBKnjix9xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLx +p2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO9z0M+Yo0FMT7MzUj8czx +Kselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq3ywgsNw2 +TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+W +G+Oin6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPw +vFEVVJSmdz7QdFG9URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYY +EQRVzXR7z2FwefR7LFxckvzluFqrTJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUl0YhVyE1 +2jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/PxN3DlCPaTKbYw +DQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E +PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kf +gLMtMrpkZ2CvuVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbS +FXJfLkur1J1juONI5f6ELlgKn0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0 +V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLhX4SPgPL0DTatdrOjteFkdjpY3H1P +XlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80nR14SohWZ25g/4/I +i+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcmGS3t +TAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L91 +09S5zvE/bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/Ky +Pu1svf0OnWZzsD2097+o4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJ +AwSQiumPv+i2tCqjI40cHLI5kqiPAlxAOXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj +1oxx +-----END CERTIFICATE----- + +# Issuer: CN=OpenTrust Root CA G2 O=OpenTrust +# Subject: CN=OpenTrust Root CA G2 O=OpenTrust +# Label: "OpenTrust Root CA G2" +# Serial: 1492012448042702096986875987676935573415441 +# MD5 Fingerprint: 57:24:b6:59:24:6b:ae:c8:fe:1c:0c:20:f2:c0:4e:eb +# SHA1 Fingerprint: 79:5f:88:60:c5:ab:7c:3d:92:e6:cb:f4:8d:e1:45:cd:11:ef:60:0b +# SHA256 Fingerprint: 27:99:58:29:fe:6a:75:15:c1:bf:e8:48:f9:c4:76:1d:b1:6c:22:59:29:25:7b:f4:0d:08:94:f2:9e:a8:ba:f2 +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUA +MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w +ZW5UcnVzdCBSb290IENBIEcyMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAw +MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU +T3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+Ntmh +/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78e +CbY2albz4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/6 +1UWY0jUJ9gNDlP7ZvyCVeYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fE +FY8ElggGQgT4hNYdvJGmQr5J1WqIP7wtUdGejeBSzFfdNTVY27SPJIjki9/ca1TS +gSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz3GIZ38i1MH/1PCZ1Eb3X +G7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj3CzMpSZy +YhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaH +vGOz9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4 +t/bQWVyJ98LVtZR00dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/ +gh7PU3+06yzbXfZqfUAkBXKJOAGTy3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUajn6QiL3 +5okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59M4PLuG53hq8w +DQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz +Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0 +nXGEL8pZ0keImUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qT +RmTFAHneIWv2V6CG1wZy7HBGS4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpT +wm+bREx50B1ws9efAvSyB7DH5fitIw6mVskpEndI2S9G/Tvw/HRwkqWOOAgfZDC2 +t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ6e18CL13zSdkzJTa +TkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97krgCf2 +o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU +3jg9CcCoSmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eA +iN1nE28daCSLT7d0geX0YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14f +WKGVyasvc0rQLW6aWQ9VGHgtPFGml4vmu7JwqkwR3v98KzfUetF3NI/n+UL3PIEM +S1IK +-----END CERTIFICATE----- + +# Issuer: CN=OpenTrust Root CA G3 O=OpenTrust +# Subject: CN=OpenTrust Root CA G3 O=OpenTrust +# Label: "OpenTrust Root CA G3" +# Serial: 1492104908271485653071219941864171170455615 +# MD5 Fingerprint: 21:37:b4:17:16:92:7b:67:46:70:a9:96:d7:a8:13:24 +# SHA1 Fingerprint: 6e:26:64:f3:56:bf:34:55:bf:d1:93:3f:7c:01:de:d8:13:da:8a:a6 +# SHA256 Fingerprint: b7:c3:62:31:70:6e:81:07:8c:36:7c:b8:96:19:8f:1e:32:08:dd:92:69:49:dd:8f:57:09:a4:10:f7:5b:62:92 +-----BEGIN CERTIFICATE----- +MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAx +CzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5U +cnVzdCBSb290IENBIEczMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFow +QDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwUT3Bl +blRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARK7liuTcpm +3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5Bta1d +oYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4G +A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5 +DMlv4VBN0BBY3JWIbTAfBgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAK +BggqhkjOPQQDAwNpADBmAjEAj6jcnboMBBf6Fek9LykBl7+BFjNAk2z8+e2AcG+q +j9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta3U1fJAuwACEl74+nBCZx +4nxp5V2a+EEfOzmTk51V6s2N8fvB +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X1 O=Internet Security Research Group +# Subject: CN=ISRG Root X1 O=Internet Security Research Group +# Label: "ISRG Root X1" +# Serial: 172886928669790476064670243504169061120 +# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e +# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8 +# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6 +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Label: "AC RAIZ FNMT-RCM" +# Serial: 485876308206448804701554682760554759 +# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d +# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 +# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 1 O=Amazon +# Subject: CN=Amazon Root CA 1 O=Amazon +# Label: "Amazon Root CA 1" +# Serial: 143266978916655856878034712317230054538369994 +# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 +# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 +# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 2 O=Amazon +# Subject: CN=Amazon Root CA 2 O=Amazon +# Label: "Amazon Root CA 2" +# Serial: 143266982885963551818349160658925006970653239 +# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 +# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a +# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 3 O=Amazon +# Subject: CN=Amazon Root CA 3 O=Amazon +# Label: "Amazon Root CA 3" +# Serial: 143266986699090766294700635381230934788665930 +# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 +# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e +# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 4 O=Amazon +# Subject: CN=Amazon Root CA 4 O=Amazon +# Label: "Amazon Root CA 4" +# Serial: 143266989758080763974105200630763877849284878 +# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd +# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be +# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +# Issuer: CN=LuxTrust Global Root 2 O=LuxTrust S.A. +# Subject: CN=LuxTrust Global Root 2 O=LuxTrust S.A. +# Label: "LuxTrust Global Root 2" +# Serial: 59914338225734147123941058376788110305822489521 +# MD5 Fingerprint: b2:e1:09:00:61:af:f7:f1:91:6f:c4:ad:8d:5e:3b:7c +# SHA1 Fingerprint: 1e:0e:56:19:0a:d1:8b:25:98:b2:04:44:ff:66:8a:04:17:99:5f:3f +# SHA256 Fingerprint: 54:45:5f:71:29:c2:0b:14:47:c4:18:f9:97:16:8f:24:c5:8f:c5:02:3b:f5:da:5b:e2:eb:6e:1d:d8:90:2e:d5 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" +# Serial: 1 +# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49 +# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca +# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16 +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- + +# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Label: "GDCA TrustAUTH R5 ROOT" +# Serial: 9009899650740120186 +# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4 +# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4 +# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93 +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor RootCert CA-1" +# Serial: 15752444095811006489 +# MD5 Fingerprint: 6e:85:f1:dc:1a:00:d3:22:d5:b2:b2:ac:6b:37:05:45 +# SHA1 Fingerprint: ff:bd:cd:e7:82:c8:43:5e:3c:6f:26:86:5c:ca:a8:3a:45:5b:c3:0a +# SHA256 Fingerprint: d4:0e:9c:86:cd:8f:e4:68:c1:77:69:59:f4:9e:a7:74:fa:54:86:84:b6:c4:06:f3:90:92:61:f4:dc:e2:57:5c +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y +IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB +pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h +IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG +A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU +cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid +RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V +seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme +9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV +EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW +hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ +DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD +ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I +/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf +ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ +yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts +L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN +zl/HHk484IkzlQsPpTLWPFp5LBk= +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor RootCert CA-2" +# Serial: 2711694510199101698 +# MD5 Fingerprint: a2:e1:f8:18:0b:ba:45:d5:c7:41:2a:bb:37:52:45:64 +# SHA1 Fingerprint: b8:be:6d:cb:56:f1:55:b9:63:d4:12:ca:4e:06:34:c7:94:b2:1c:c0 +# SHA256 Fingerprint: 07:53:e9:40:37:8c:1b:d5:e3:83:6e:39:5d:ae:a5:cb:83:9e:50:46:f1:bd:0e:ae:19:51:cf:10:fe:c7:c9:65 +-----BEGIN CERTIFICATE----- +MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig +Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk +MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg +Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD +VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy +dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ +QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq +1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp +2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK +DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape +az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF +3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 +oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM +g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 +mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh +8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd +BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U +nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw +DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX +dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ +MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL +/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX +CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa +ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW +2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 +N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 +Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB +As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp +5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu +1uwJ +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor ECA-1" +# Serial: 9548242946988625984 +# MD5 Fingerprint: 27:92:23:1d:0a:f5:40:7c:e9:e6:6b:9d:d8:f5:e7:6c +# SHA1 Fingerprint: 58:d1:df:95:95:67:6b:63:c0:f0:5b:1c:17:4d:8b:84:0b:c8:78:bd +# SHA256 Fingerprint: 5a:88:5d:b1:9c:01:d9:12:c5:75:93:88:93:8c:af:bb:df:03:1a:b2:d4:8e:91:ee:15:58:9b:42:97:1d:03:9c +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y +IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig +RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb +3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA +BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 +3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou +owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ +wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF +ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf +BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv +civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 +AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F +hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 +soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI +WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi +tJ/X5g== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Label: "SSL.com Root Certification Authority RSA" +# Serial: 8875640296558310041 +# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29 +# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb +# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69 +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com Root Certification Authority ECC" +# Serial: 8495723813297216424 +# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e +# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a +# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority RSA R2" +# Serial: 6248227494352943350 +# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95 +# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a +# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority ECC" +# Serial: 3182246526754555285 +# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90 +# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d +# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8 +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/core.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/core.py new file mode 100644 index 0000000..eab9d1d --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/core.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +certifi.py +~~~~~~~~~~ + +This module returns the installation location of cacert.pem. +""" +import os +import warnings + + +class DeprecatedBundleWarning(DeprecationWarning): + """ + The weak security bundle is being deprecated. Please bother your service + provider to get them to stop using cross-signed roots. + """ + + +def where(): + f = os.path.dirname(__file__) + + return os.path.join(f, 'cacert.pem') + + +def old_where(): + warnings.warn( + "The weak security bundle has been removed. certifi.old_where() is now an alias " + "of certifi.where(). Please update your code to use certifi.where() instead. " + "certifi.old_where() will be removed in 2018.", + DeprecatedBundleWarning + ) + return where() + +if __name__ == '__main__': + print(where()) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__init__.py new file mode 100644 index 0000000..0f9f820 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__init__.py @@ -0,0 +1,39 @@ +######################## BEGIN LICENSE BLOCK ######################## +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +from .compat import PY2, PY3 +from .universaldetector import UniversalDetector +from .version import __version__, VERSION + + +def detect(byte_str): + """ + Detect the encoding of the given byte string. + + :param byte_str: The byte sequence to examine. + :type byte_str: ``bytes`` or ``bytearray`` + """ + if not isinstance(byte_str, bytearray): + if not isinstance(byte_str, bytes): + raise TypeError('Expected object of type bytes or bytearray, got: ' + '{0}'.format(type(byte_str))) + else: + byte_str = bytearray(byte_str) + detector = UniversalDetector() + detector.feed(byte_str) + return detector.close() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/big5freq.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/big5freq.py new file mode 100644 index 0000000..38f3251 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/big5freq.py @@ -0,0 +1,386 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Big5 frequency table +# by Taiwan's Mandarin Promotion Council +# <http://www.edu.tw:81/mandr/> +# +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Ideal Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +BIG5_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +#Char to FreqOrder table +BIG5_TABLE_SIZE = 5376 + +BIG5_CHAR_TO_FREQ_ORDER = ( + 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, # 16 +3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, # 32 +1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, # 48 + 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, # 64 +3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, # 80 +4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, # 96 +5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, # 112 + 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, # 128 + 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, # 144 + 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, # 160 +2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, # 176 +1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, # 192 +3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, # 208 + 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, # 224 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, # 240 +3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, # 256 +2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, # 272 + 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, # 288 +3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, # 304 +1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, # 320 +5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, # 336 + 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, # 352 +5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, # 368 +1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, # 384 + 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, # 400 + 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, # 416 +3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, # 432 +3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, # 448 + 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, # 464 +2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, # 480 +2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, # 496 + 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, # 512 + 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, # 528 +3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, # 544 +1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, # 560 +1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, # 576 +1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, # 592 +2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, # 608 + 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, # 624 +4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, # 640 +1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, # 656 +5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, # 672 +2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, # 688 + 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, # 704 + 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, # 720 + 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, # 736 + 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, # 752 +5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, # 768 + 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, # 784 +1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, # 800 + 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, # 816 + 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, # 832 +5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, # 848 +1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, # 864 + 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, # 880 +3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, # 896 +4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, # 912 +3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, # 928 + 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, # 944 + 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, # 960 +1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, # 976 +4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, # 992 +3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, # 1008 +3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, # 1024 +2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, # 1040 +5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, # 1056 +3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, # 1072 +5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, # 1088 +1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, # 1104 +2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, # 1120 +1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, # 1136 + 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, # 1152 +1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, # 1168 +4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, # 1184 +3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, # 1200 + 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, # 1216 + 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, # 1232 + 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, # 1248 +2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, # 1264 +5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, # 1280 +1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, # 1296 +2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, # 1312 +1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, # 1328 +1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, # 1344 +5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, # 1360 +5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, # 1376 +5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, # 1392 +3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, # 1408 +4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, # 1424 +4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, # 1440 +2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, # 1456 +5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, # 1472 +3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, # 1488 + 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, # 1504 +5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, # 1520 +5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, # 1536 +1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, # 1552 +2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, # 1568 +3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, # 1584 +4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, # 1600 +5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, # 1616 +3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, # 1632 +4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, # 1648 +1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, # 1664 +1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, # 1680 +4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, # 1696 +1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, # 1712 + 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, # 1728 +1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, # 1744 +1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, # 1760 +3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, # 1776 + 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, # 1792 +5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, # 1808 +2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, # 1824 +1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, # 1840 +1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, # 1856 +5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, # 1872 + 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, # 1888 +4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, # 1904 + 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, # 1920 +2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, # 1936 + 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, # 1952 +1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, # 1968 +1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, # 1984 + 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, # 2000 +4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, # 2016 +4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, # 2032 +1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, # 2048 +3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, # 2064 +5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, # 2080 +5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, # 2096 +1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, # 2112 +2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, # 2128 +1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, # 2144 +3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, # 2160 +2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, # 2176 +3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, # 2192 +2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, # 2208 +4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, # 2224 +4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, # 2240 +3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, # 2256 + 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, # 2272 +3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, # 2288 + 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, # 2304 +3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, # 2320 +4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, # 2336 +3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, # 2352 +1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, # 2368 +5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, # 2384 + 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, # 2400 +5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, # 2416 +1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, # 2432 + 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, # 2448 +4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, # 2464 +4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, # 2480 + 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, # 2496 +2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, # 2512 +2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, # 2528 +3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, # 2544 +1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, # 2560 +4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, # 2576 +2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, # 2592 +1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, # 2608 +1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, # 2624 +2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, # 2640 +3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, # 2656 +1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, # 2672 +5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, # 2688 +1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, # 2704 +4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, # 2720 +1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, # 2736 + 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, # 2752 +1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, # 2768 +4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, # 2784 +4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, # 2800 +2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, # 2816 +1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, # 2832 +4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, # 2848 + 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, # 2864 +5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, # 2880 +2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, # 2896 +3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, # 2912 +4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, # 2928 + 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, # 2944 +5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, # 2960 +5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, # 2976 +1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, # 2992 +4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, # 3008 +4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, # 3024 +2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, # 3040 +3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, # 3056 +3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, # 3072 +2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, # 3088 +1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, # 3104 +4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, # 3120 +3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, # 3136 +3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, # 3152 +2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, # 3168 +4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, # 3184 +5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, # 3200 +3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, # 3216 +2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, # 3232 +3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, # 3248 +1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, # 3264 +2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, # 3280 +3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, # 3296 +4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, # 3312 +2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, # 3328 +2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, # 3344 +5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, # 3360 +1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, # 3376 +2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, # 3392 +1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, # 3408 +3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, # 3424 +4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, # 3440 +2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, # 3456 +3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, # 3472 +3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, # 3488 +2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, # 3504 +4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, # 3520 +2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, # 3536 +3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, # 3552 +4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, # 3568 +5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, # 3584 +3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, # 3600 + 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, # 3616 +1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, # 3632 +4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, # 3648 +1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, # 3664 +4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, # 3680 +5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, # 3696 + 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, # 3712 +5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, # 3728 +5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, # 3744 +2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, # 3760 +3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, # 3776 +2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, # 3792 +2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, # 3808 + 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, # 3824 +1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, # 3840 +4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, # 3856 +3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, # 3872 +3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, # 3888 + 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, # 3904 +2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, # 3920 + 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, # 3936 +2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, # 3952 +4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, # 3968 +1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, # 3984 +4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, # 4000 +1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, # 4016 +3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, # 4032 + 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, # 4048 +3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, # 4064 +5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, # 4080 +5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, # 4096 +3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, # 4112 +3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, # 4128 +1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, # 4144 +2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, # 4160 +5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, # 4176 +1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, # 4192 +1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, # 4208 +3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, # 4224 + 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, # 4240 +1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, # 4256 +4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, # 4272 +5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, # 4288 +2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, # 4304 +3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, # 4320 + 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, # 4336 +1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, # 4352 +2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, # 4368 +2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, # 4384 +5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, # 4400 +5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, # 4416 +5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, # 4432 +2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, # 4448 +2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, # 4464 +1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, # 4480 +4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, # 4496 +3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, # 4512 +3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, # 4528 +4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, # 4544 +4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, # 4560 +2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, # 4576 +2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, # 4592 +5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, # 4608 +4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, # 4624 +5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, # 4640 +4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, # 4656 + 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, # 4672 + 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, # 4688 +1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, # 4704 +3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, # 4720 +4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, # 4736 +1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, # 4752 +5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, # 4768 +2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, # 4784 +2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, # 4800 +3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, # 4816 +5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, # 4832 +1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, # 4848 +3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, # 4864 +5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, # 4880 +1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, # 4896 +5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, # 4912 +2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, # 4928 +3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, # 4944 +2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, # 4960 +3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, # 4976 +3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, # 4992 +3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, # 5008 +4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, # 5024 + 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, # 5040 +2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, # 5056 +4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, # 5072 +3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, # 5088 +5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, # 5104 +1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, # 5120 +5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, # 5136 + 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, # 5152 +1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, # 5168 + 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, # 5184 +4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, # 5200 +1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, # 5216 +4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, # 5232 +1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, # 5248 + 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, # 5264 +3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, # 5280 +4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, # 5296 +5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, # 5312 + 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, # 5328 +3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, # 5344 + 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, # 5360 +2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, # 5376 +) + diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/big5prober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/big5prober.py new file mode 100644 index 0000000..98f9970 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/big5prober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import Big5DistributionAnalysis +from .mbcssm import BIG5_SM_MODEL + + +class Big5Prober(MultiByteCharSetProber): + def __init__(self): + super(Big5Prober, self).__init__() + self.coding_sm = CodingStateMachine(BIG5_SM_MODEL) + self.distribution_analyzer = Big5DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "Big5" + + @property + def language(self): + return "Chinese" diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/chardistribution.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/chardistribution.py new file mode 100644 index 0000000..c0395f4 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/chardistribution.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .euctwfreq import (EUCTW_CHAR_TO_FREQ_ORDER, EUCTW_TABLE_SIZE, + EUCTW_TYPICAL_DISTRIBUTION_RATIO) +from .euckrfreq import (EUCKR_CHAR_TO_FREQ_ORDER, EUCKR_TABLE_SIZE, + EUCKR_TYPICAL_DISTRIBUTION_RATIO) +from .gb2312freq import (GB2312_CHAR_TO_FREQ_ORDER, GB2312_TABLE_SIZE, + GB2312_TYPICAL_DISTRIBUTION_RATIO) +from .big5freq import (BIG5_CHAR_TO_FREQ_ORDER, BIG5_TABLE_SIZE, + BIG5_TYPICAL_DISTRIBUTION_RATIO) +from .jisfreq import (JIS_CHAR_TO_FREQ_ORDER, JIS_TABLE_SIZE, + JIS_TYPICAL_DISTRIBUTION_RATIO) + + +class CharDistributionAnalysis(object): + ENOUGH_DATA_THRESHOLD = 1024 + SURE_YES = 0.99 + SURE_NO = 0.01 + MINIMUM_DATA_THRESHOLD = 3 + + def __init__(self): + # Mapping table to get frequency order from char order (get from + # GetOrder()) + self._char_to_freq_order = None + self._table_size = None # Size of above table + # This is a constant value which varies from language to language, + # used in calculating confidence. See + # http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html + # for further detail. + self.typical_distribution_ratio = None + self._done = None + self._total_chars = None + self._freq_chars = None + self.reset() + + def reset(self): + """reset analyser, clear any state""" + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + self._total_chars = 0 # Total characters encountered + # The number of characters whose frequency order is less than 512 + self._freq_chars = 0 + + def feed(self, char, char_len): + """feed a character with known length""" + if char_len == 2: + # we only care about 2-bytes character in our distribution analysis + order = self.get_order(char) + else: + order = -1 + if order >= 0: + self._total_chars += 1 + # order is valid + if order < self._table_size: + if 512 > self._char_to_freq_order[order]: + self._freq_chars += 1 + + def get_confidence(self): + """return confidence based on existing data""" + # if we didn't receive any character in our consideration range, + # return negative answer + if self._total_chars <= 0 or self._freq_chars <= self.MINIMUM_DATA_THRESHOLD: + return self.SURE_NO + + if self._total_chars != self._freq_chars: + r = (self._freq_chars / ((self._total_chars - self._freq_chars) + * self.typical_distribution_ratio)) + if r < self.SURE_YES: + return r + + # normalize confidence (we don't want to be 100% sure) + return self.SURE_YES + + def got_enough_data(self): + # It is not necessary to receive all data to draw conclusion. + # For charset detection, certain amount of data is enough + return self._total_chars > self.ENOUGH_DATA_THRESHOLD + + def get_order(self, byte_str): + # We do not handle characters based on the original encoding string, + # but convert this encoding string to a number, here called order. + # This allows multiple encodings of a language to share one frequency + # table. + return -1 + + +class EUCTWDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCTWDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCTW_CHAR_TO_FREQ_ORDER + self._table_size = EUCTW_TABLE_SIZE + self.typical_distribution_ratio = EUCTW_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-TW encoding, we are interested + # first byte range: 0xc4 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xC4: + return 94 * (first_char - 0xC4) + byte_str[1] - 0xA1 + else: + return -1 + + +class EUCKRDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCKRDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCKR_CHAR_TO_FREQ_ORDER + self._table_size = EUCKR_TABLE_SIZE + self.typical_distribution_ratio = EUCKR_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-KR encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xB0: + return 94 * (first_char - 0xB0) + byte_str[1] - 0xA1 + else: + return -1 + + +class GB2312DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(GB2312DistributionAnalysis, self).__init__() + self._char_to_freq_order = GB2312_CHAR_TO_FREQ_ORDER + self._table_size = GB2312_TABLE_SIZE + self.typical_distribution_ratio = GB2312_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for GB2312 encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0xB0) and (second_char >= 0xA1): + return 94 * (first_char - 0xB0) + second_char - 0xA1 + else: + return -1 + + +class Big5DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(Big5DistributionAnalysis, self).__init__() + self._char_to_freq_order = BIG5_CHAR_TO_FREQ_ORDER + self._table_size = BIG5_TABLE_SIZE + self.typical_distribution_ratio = BIG5_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for big5 encoding, we are interested + # first byte range: 0xa4 -- 0xfe + # second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if first_char >= 0xA4: + if second_char >= 0xA1: + return 157 * (first_char - 0xA4) + second_char - 0xA1 + 63 + else: + return 157 * (first_char - 0xA4) + second_char - 0x40 + else: + return -1 + + +class SJISDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(SJISDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for sjis encoding, we are interested + # first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe + # second byte range: 0x40 -- 0x7e, 0x81 -- oxfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0x81) and (first_char <= 0x9F): + order = 188 * (first_char - 0x81) + elif (first_char >= 0xE0) and (first_char <= 0xEF): + order = 188 * (first_char - 0xE0 + 31) + else: + return -1 + order = order + second_char - 0x40 + if second_char > 0x7F: + order = -1 + return order + + +class EUCJPDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCJPDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-JP encoding, we are interested + # first byte range: 0xa0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + char = byte_str[0] + if char >= 0xA0: + return 94 * (char - 0xA1) + byte_str[1] - 0xa1 + else: + return -1 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/charsetgroupprober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/charsetgroupprober.py new file mode 100644 index 0000000..8b3738e --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/charsetgroupprober.py @@ -0,0 +1,106 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState +from .charsetprober import CharSetProber + + +class CharSetGroupProber(CharSetProber): + def __init__(self, lang_filter=None): + super(CharSetGroupProber, self).__init__(lang_filter=lang_filter) + self._active_num = 0 + self.probers = [] + self._best_guess_prober = None + + def reset(self): + super(CharSetGroupProber, self).reset() + self._active_num = 0 + for prober in self.probers: + if prober: + prober.reset() + prober.active = True + self._active_num += 1 + self._best_guess_prober = None + + @property + def charset_name(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.charset_name + + @property + def language(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.language + + def feed(self, byte_str): + for prober in self.probers: + if not prober: + continue + if not prober.active: + continue + state = prober.feed(byte_str) + if not state: + continue + if state == ProbingState.FOUND_IT: + self._best_guess_prober = prober + return self.state + elif state == ProbingState.NOT_ME: + prober.active = False + self._active_num -= 1 + if self._active_num <= 0: + self._state = ProbingState.NOT_ME + return self.state + return self.state + + def get_confidence(self): + state = self.state + if state == ProbingState.FOUND_IT: + return 0.99 + elif state == ProbingState.NOT_ME: + return 0.01 + best_conf = 0.0 + self._best_guess_prober = None + for prober in self.probers: + if not prober: + continue + if not prober.active: + self.logger.debug('%s not active', prober.charset_name) + continue + conf = prober.get_confidence() + self.logger.debug('%s %s confidence = %s', prober.charset_name, prober.language, conf) + if best_conf < conf: + best_conf = conf + self._best_guess_prober = prober + if not self._best_guess_prober: + return 0.0 + return best_conf diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/charsetprober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/charsetprober.py new file mode 100644 index 0000000..eac4e59 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/charsetprober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging +import re + +from .enums import ProbingState + + +class CharSetProber(object): + + SHORTCUT_THRESHOLD = 0.95 + + def __init__(self, lang_filter=None): + self._state = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + + def reset(self): + self._state = ProbingState.DETECTING + + @property + def charset_name(self): + return None + + def feed(self, buf): + pass + + @property + def state(self): + return self._state + + def get_confidence(self): + return 0.0 + + @staticmethod + def filter_high_byte_only(buf): + buf = re.sub(b'([\x00-\x7F])+', b' ', buf) + return buf + + @staticmethod + def filter_international_words(buf): + """ + We define three types of bytes: + alphabet: english alphabets [a-zA-Z] + international: international characters [\x80-\xFF] + marker: everything else [^a-zA-Z\x80-\xFF] + + The input buffer can be thought to contain a series of words delimited + by markers. This function works to filter all words that contain at + least one international character. All contiguous sequences of markers + are replaced by a single space ascii character. + + This filter applies to all scripts which do not use English characters. + """ + filtered = bytearray() + + # This regex expression filters out only words that have at-least one + # international character. The word may include one marker character at + # the end. + words = re.findall(b'[a-zA-Z]*[\x80-\xFF]+[a-zA-Z]*[^a-zA-Z\x80-\xFF]?', + buf) + + for word in words: + filtered.extend(word[:-1]) + + # If the last character in the word is a marker, replace it with a + # space as markers shouldn't affect our analysis (they are used + # similarly across all languages and may thus have similar + # frequencies). + last_char = word[-1:] + if not last_char.isalpha() and last_char < b'\x80': + last_char = b' ' + filtered.extend(last_char) + + return filtered + + @staticmethod + def filter_with_english_letters(buf): + """ + Returns a copy of ``buf`` that retains only the sequences of English + alphabet and high byte characters that are not between <> characters. + Also retains English alphabet and high byte characters immediately + before occurrences of >. + + This filter can be applied to all scripts which contain both English + characters and extended ASCII characters, but is currently only used by + ``Latin1Prober``. + """ + filtered = bytearray() + in_tag = False + prev = 0 + + for curr in range(len(buf)): + # Slice here to get bytes instead of an int with Python 3 + buf_char = buf[curr:curr + 1] + # Check if we're coming out of or entering an HTML tag + if buf_char == b'>': + in_tag = False + elif buf_char == b'<': + in_tag = True + + # If current character is not extended-ASCII and not alphabetic... + if buf_char < b'\x80' and not buf_char.isalpha(): + # ...and we're not in a tag + if curr > prev and not in_tag: + # Keep everything after last non-extended-ASCII, + # non-alphabetic character + filtered.extend(buf[prev:curr]) + # Output a space to delimit stretch we kept + filtered.extend(b' ') + prev = curr + 1 + + # If we're not in a tag... + if not in_tag: + # Keep everything after last non-extended-ASCII, non-alphabetic + # character + filtered.extend(buf[prev:]) + + return filtered diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cli/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cli/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cli/__init__.py @@ -0,0 +1 @@ + diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cli/chardetect.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cli/chardetect.py new file mode 100644 index 0000000..c61136b --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cli/chardetect.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +""" +Script which takes one or more file paths and reports on their detected +encodings + +Example:: + + % chardetect somefile someotherfile + somefile: windows-1252 with confidence 0.5 + someotherfile: ascii with confidence 1.0 + +If no paths are provided, it takes its input from stdin. + +""" + +from __future__ import absolute_import, print_function, unicode_literals + +import argparse +import sys + +from pip._vendor.chardet import __version__ +from pip._vendor.chardet.compat import PY2 +from pip._vendor.chardet.universaldetector import UniversalDetector + + +def description_of(lines, name='stdin'): + """ + Return a string describing the probable encoding of a file or + list of strings. + + :param lines: The lines to get the encoding of. + :type lines: Iterable of bytes + :param name: Name of file or collection of lines + :type name: str + """ + u = UniversalDetector() + for line in lines: + line = bytearray(line) + u.feed(line) + # shortcut out of the loop to save reading further - particularly useful if we read a BOM. + if u.done: + break + u.close() + result = u.result + if PY2: + name = name.decode(sys.getfilesystemencoding(), 'ignore') + if result['encoding']: + return '{0}: {1} with confidence {2}'.format(name, result['encoding'], + result['confidence']) + else: + return '{0}: no result'.format(name) + + +def main(argv=None): + """ + Handles command line arguments and gets things started. + + :param argv: List of arguments, as if specified on the command-line. + If None, ``sys.argv[1:]`` is used instead. + :type argv: list of str + """ + # Get command line arguments + parser = argparse.ArgumentParser( + description="Takes one or more file paths and reports their detected \ + encodings") + parser.add_argument('input', + help='File whose encoding we would like to determine. \ + (default: stdin)', + type=argparse.FileType('rb'), nargs='*', + default=[sys.stdin if PY2 else sys.stdin.buffer]) + parser.add_argument('--version', action='version', + version='%(prog)s {0}'.format(__version__)) + args = parser.parse_args(argv) + + for f in args.input: + if f.isatty(): + print("You are running chardetect interactively. Press " + + "CTRL-D twice at the start of a blank line to signal the " + + "end of your input. If you want help, run chardetect " + + "--help\n", file=sys.stderr) + print(description_of(f, f.name)) + + +if __name__ == '__main__': + main() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/codingstatemachine.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/codingstatemachine.py new file mode 100644 index 0000000..68fba44 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/codingstatemachine.py @@ -0,0 +1,88 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging + +from .enums import MachineState + + +class CodingStateMachine(object): + """ + A state machine to verify a byte sequence for a particular encoding. For + each byte the detector receives, it will feed that byte to every active + state machine available, one byte at a time. The state machine changes its + state based on its previous state and the byte it receives. There are 3 + states in a state machine that are of interest to an auto-detector: + + START state: This is the state to start with, or a legal byte sequence + (i.e. a valid code point) for character has been identified. + + ME state: This indicates that the state machine identified a byte sequence + that is specific to the charset it is designed for and that + there is no other possible encoding which can contain this byte + sequence. This will to lead to an immediate positive answer for + the detector. + + ERROR state: This indicates the state machine identified an illegal byte + sequence for that encoding. This will lead to an immediate + negative answer for this encoding. Detector will exclude this + encoding from consideration from here on. + """ + def __init__(self, sm): + self._model = sm + self._curr_byte_pos = 0 + self._curr_char_len = 0 + self._curr_state = None + self.logger = logging.getLogger(__name__) + self.reset() + + def reset(self): + self._curr_state = MachineState.START + + def next_state(self, c): + # for each byte we get its class + # if it is first byte, we also get byte length + byte_class = self._model['class_table'][c] + if self._curr_state == MachineState.START: + self._curr_byte_pos = 0 + self._curr_char_len = self._model['char_len_table'][byte_class] + # from byte's class and state_table, we get its next state + curr_state = (self._curr_state * self._model['class_factor'] + + byte_class) + self._curr_state = self._model['state_table'][curr_state] + self._curr_byte_pos += 1 + return self._curr_state + + def get_current_charlen(self): + return self._curr_char_len + + def get_coding_state_machine(self): + return self._model['name'] + + @property + def language(self): + return self._model['language'] diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/compat.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/compat.py new file mode 100644 index 0000000..ddd7468 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/compat.py @@ -0,0 +1,34 @@ +######################## BEGIN LICENSE BLOCK ######################## +# Contributor(s): +# Dan Blanchard +# Ian Cordasco +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import sys + + +if sys.version_info < (3, 0): + PY2 = True + PY3 = False + base_str = (str, unicode) + text_type = unicode +else: + PY2 = False + PY3 = True + base_str = (bytes, str) + text_type = str diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cp949prober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cp949prober.py new file mode 100644 index 0000000..efd793a --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cp949prober.py @@ -0,0 +1,49 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .chardistribution import EUCKRDistributionAnalysis +from .codingstatemachine import CodingStateMachine +from .mbcharsetprober import MultiByteCharSetProber +from .mbcssm import CP949_SM_MODEL + + +class CP949Prober(MultiByteCharSetProber): + def __init__(self): + super(CP949Prober, self).__init__() + self.coding_sm = CodingStateMachine(CP949_SM_MODEL) + # NOTE: CP949 is a superset of EUC-KR, so the distribution should be + # not different. + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "CP949" + + @property + def language(self): + return "Korean" diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/enums.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/enums.py new file mode 100644 index 0000000..0451207 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/enums.py @@ -0,0 +1,76 @@ +""" +All of the Enums that are used throughout the chardet package. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + + +class InputState(object): + """ + This enum represents the different states a universal detector can be in. + """ + PURE_ASCII = 0 + ESC_ASCII = 1 + HIGH_BYTE = 2 + + +class LanguageFilter(object): + """ + This enum represents the different language filters we can apply to a + ``UniversalDetector``. + """ + CHINESE_SIMPLIFIED = 0x01 + CHINESE_TRADITIONAL = 0x02 + JAPANESE = 0x04 + KOREAN = 0x08 + NON_CJK = 0x10 + ALL = 0x1F + CHINESE = CHINESE_SIMPLIFIED | CHINESE_TRADITIONAL + CJK = CHINESE | JAPANESE | KOREAN + + +class ProbingState(object): + """ + This enum represents the different states a prober can be in. + """ + DETECTING = 0 + FOUND_IT = 1 + NOT_ME = 2 + + +class MachineState(object): + """ + This enum represents the different states a state machine can be in. + """ + START = 0 + ERROR = 1 + ITS_ME = 2 + + +class SequenceLikelihood(object): + """ + This enum represents the likelihood of a character following the previous one. + """ + NEGATIVE = 0 + UNLIKELY = 1 + LIKELY = 2 + POSITIVE = 3 + + @classmethod + def get_num_categories(cls): + """:returns: The number of likelihood categories in the enum.""" + return 4 + + +class CharacterCategory(object): + """ + This enum represents the different categories language models for + ``SingleByteCharsetProber`` put characters into. + + Anything less than CONTROL is considered a letter. + """ + UNDEFINED = 255 + LINE_BREAK = 254 + SYMBOL = 253 + DIGIT = 252 + CONTROL = 251 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/escprober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/escprober.py new file mode 100644 index 0000000..c70493f --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/escprober.py @@ -0,0 +1,101 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .codingstatemachine import CodingStateMachine +from .enums import LanguageFilter, ProbingState, MachineState +from .escsm import (HZ_SM_MODEL, ISO2022CN_SM_MODEL, ISO2022JP_SM_MODEL, + ISO2022KR_SM_MODEL) + + +class EscCharSetProber(CharSetProber): + """ + This CharSetProber uses a "code scheme" approach for detecting encodings, + whereby easily recognizable escape or shift sequences are relied on to + identify these encodings. + """ + + def __init__(self, lang_filter=None): + super(EscCharSetProber, self).__init__(lang_filter=lang_filter) + self.coding_sm = [] + if self.lang_filter & LanguageFilter.CHINESE_SIMPLIFIED: + self.coding_sm.append(CodingStateMachine(HZ_SM_MODEL)) + self.coding_sm.append(CodingStateMachine(ISO2022CN_SM_MODEL)) + if self.lang_filter & LanguageFilter.JAPANESE: + self.coding_sm.append(CodingStateMachine(ISO2022JP_SM_MODEL)) + if self.lang_filter & LanguageFilter.KOREAN: + self.coding_sm.append(CodingStateMachine(ISO2022KR_SM_MODEL)) + self.active_sm_count = None + self._detected_charset = None + self._detected_language = None + self._state = None + self.reset() + + def reset(self): + super(EscCharSetProber, self).reset() + for coding_sm in self.coding_sm: + if not coding_sm: + continue + coding_sm.active = True + coding_sm.reset() + self.active_sm_count = len(self.coding_sm) + self._detected_charset = None + self._detected_language = None + + @property + def charset_name(self): + return self._detected_charset + + @property + def language(self): + return self._detected_language + + def get_confidence(self): + if self._detected_charset: + return 0.99 + else: + return 0.00 + + def feed(self, byte_str): + for c in byte_str: + for coding_sm in self.coding_sm: + if not coding_sm or not coding_sm.active: + continue + coding_state = coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + coding_sm.active = False + self.active_sm_count -= 1 + if self.active_sm_count <= 0: + self._state = ProbingState.NOT_ME + return self.state + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + self._detected_charset = coding_sm.get_coding_state_machine() + self._detected_language = coding_sm.language + return self.state + + return self.state diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/escsm.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/escsm.py new file mode 100644 index 0000000..0069523 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/escsm.py @@ -0,0 +1,246 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +HZ_CLS = ( +1,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,0,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,4,0,5,2,0, # 78 - 7f +1,1,1,1,1,1,1,1, # 80 - 87 +1,1,1,1,1,1,1,1, # 88 - 8f +1,1,1,1,1,1,1,1, # 90 - 97 +1,1,1,1,1,1,1,1, # 98 - 9f +1,1,1,1,1,1,1,1, # a0 - a7 +1,1,1,1,1,1,1,1, # a8 - af +1,1,1,1,1,1,1,1, # b0 - b7 +1,1,1,1,1,1,1,1, # b8 - bf +1,1,1,1,1,1,1,1, # c0 - c7 +1,1,1,1,1,1,1,1, # c8 - cf +1,1,1,1,1,1,1,1, # d0 - d7 +1,1,1,1,1,1,1,1, # d8 - df +1,1,1,1,1,1,1,1, # e0 - e7 +1,1,1,1,1,1,1,1, # e8 - ef +1,1,1,1,1,1,1,1, # f0 - f7 +1,1,1,1,1,1,1,1, # f8 - ff +) + +HZ_ST = ( +MachineState.START,MachineState.ERROR, 3,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START, 4,MachineState.ERROR,# 10-17 + 5,MachineState.ERROR, 6,MachineState.ERROR, 5, 5, 4,MachineState.ERROR,# 18-1f + 4,MachineState.ERROR, 4, 4, 4,MachineState.ERROR, 4,MachineState.ERROR,# 20-27 + 4,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 28-2f +) + +HZ_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +HZ_SM_MODEL = {'class_table': HZ_CLS, + 'class_factor': 6, + 'state_table': HZ_ST, + 'char_len_table': HZ_CHAR_LEN_TABLE, + 'name': "HZ-GB-2312", + 'language': 'Chinese'} + +ISO2022CN_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,3,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,4,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022CN_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 20-27 + 5, 6,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,# 38-3f +) + +ISO2022CN_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022CN_SM_MODEL = {'class_table': ISO2022CN_CLS, + 'class_factor': 9, + 'state_table': ISO2022CN_ST, + 'char_len_table': ISO2022CN_CHAR_LEN_TABLE, + 'name': "ISO-2022-CN", + 'language': 'Chinese'} + +ISO2022JP_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,2,2, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,7,0,0,0, # 20 - 27 +3,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +6,0,4,0,8,0,0,0, # 40 - 47 +0,9,5,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022JP_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 20-27 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 6,MachineState.ITS_ME,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 38-3f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.START,# 40-47 +) + +ISO2022JP_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022JP_SM_MODEL = {'class_table': ISO2022JP_CLS, + 'class_factor': 10, + 'state_table': ISO2022JP_ST, + 'char_len_table': ISO2022JP_CHAR_LEN_TABLE, + 'name': "ISO-2022-JP", + 'language': 'Japanese'} + +ISO2022KR_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,3,0,0,0, # 20 - 27 +0,4,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,5,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022KR_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 10-17 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 20-27 +) + +ISO2022KR_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +ISO2022KR_SM_MODEL = {'class_table': ISO2022KR_CLS, + 'class_factor': 6, + 'state_table': ISO2022KR_ST, + 'char_len_table': ISO2022KR_CHAR_LEN_TABLE, + 'name': "ISO-2022-KR", + 'language': 'Korean'} + + diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/eucjpprober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/eucjpprober.py new file mode 100644 index 0000000..20ce8f7 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/eucjpprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState, MachineState +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCJPDistributionAnalysis +from .jpcntx import EUCJPContextAnalysis +from .mbcssm import EUCJP_SM_MODEL + + +class EUCJPProber(MultiByteCharSetProber): + def __init__(self): + super(EUCJPProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCJP_SM_MODEL) + self.distribution_analyzer = EUCJPDistributionAnalysis() + self.context_analyzer = EUCJPContextAnalysis() + self.reset() + + def reset(self): + super(EUCJPProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return "EUC-JP" + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + # PY3K: byte_str is a byte array, so byte_str[i] is an int, not a byte + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char, char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euckrfreq.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euckrfreq.py new file mode 100644 index 0000000..b68078c --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euckrfreq.py @@ -0,0 +1,195 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology + +# 128 --> 0.79 +# 256 --> 0.92 +# 512 --> 0.986 +# 1024 --> 0.99944 +# 2048 --> 0.99999 +# +# Idea Distribution Ratio = 0.98653 / (1-0.98653) = 73.24 +# Random Distribution Ration = 512 / (2350-512) = 0.279. +# +# Typical Distribution Ratio + +EUCKR_TYPICAL_DISTRIBUTION_RATIO = 6.0 + +EUCKR_TABLE_SIZE = 2352 + +# Char to FreqOrder table , +EUCKR_CHAR_TO_FREQ_ORDER = ( + 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87, +1397,1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398, +1399,1729,1730,1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734, + 945,1400,1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739, + 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622, + 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750, +1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856, + 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205, + 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779, +1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19, +1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567, +1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797, +1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802, +1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899, + 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818, +1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409, +1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697, +1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770, +1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723, + 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416, +1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300, + 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083, + 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857, +1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871, + 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420, +1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885, + 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889, + 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893, +1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317, +1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841, +1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910, +1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610, + 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375, +1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939, + 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870, + 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934, +1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888, +1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950, +1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065, +1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002, +1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965, +1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467, + 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285, + 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7, + 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979, +1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985, + 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994, +1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250, + 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824, + 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003, +2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745, + 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61, + 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023, +2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032, +2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912, +2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224, + 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012, + 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050, +2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681, + 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414, +1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068, +2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075, +1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850, +2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606, +2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449, +1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452, + 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112, +2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121, +2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130, + 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274, + 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139, +2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721, +1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298, +2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463, +2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747, +2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285, +2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187, +2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10, +2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350, +1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201, +2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972, +2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219, +2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233, +2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242, +2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247, +1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178, +1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255, +2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259, +1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262, +2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702, +1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273, + 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541, +2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117, + 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187, +2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800, + 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312, +2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229, +2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315, + 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484, +2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170, +1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335, + 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601, +1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395, +2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354, +1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476, +2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035, + 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498, +2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310, +1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389, +2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504, +1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505, +2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145, +1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624, + 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700, +2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221, +2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377, + 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448, + 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485, +1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705, +1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465, + 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471, +2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997, +2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486, + 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494, + 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771, + 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323, +2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491, + 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510, + 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519, +2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532, +2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199, + 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544, +2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247, +1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441, + 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562, +2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362, +2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583, +2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465, + 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431, + 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151, + 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596, +2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406, +2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611, +2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619, +1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628, +2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042, + 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, # 512, 256 +) + diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euckrprober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euckrprober.py new file mode 100644 index 0000000..345a060 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euckrprober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCKRDistributionAnalysis +from .mbcssm import EUCKR_SM_MODEL + + +class EUCKRProber(MultiByteCharSetProber): + def __init__(self): + super(EUCKRProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCKR_SM_MODEL) + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-KR" + + @property + def language(self): + return "Korean" diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euctwfreq.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euctwfreq.py new file mode 100644 index 0000000..ed7a995 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euctwfreq.py @@ -0,0 +1,387 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# EUCTW frequency table +# Converted from big5 work +# by Taiwan's Mandarin Promotion Council +# <http:#www.edu.tw:81/mandr/> + +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +EUCTW_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +# Char to FreqOrder table , +EUCTW_TABLE_SIZE = 5376 + +EUCTW_CHAR_TO_FREQ_ORDER = ( + 1,1800,1506, 255,1431, 198, 9, 82, 6,7310, 177, 202,3615,1256,2808, 110, # 2742 +3735, 33,3241, 261, 76, 44,2113, 16,2931,2184,1176, 659,3868, 26,3404,2643, # 2758 +1198,3869,3313,4060, 410,2211, 302, 590, 361,1963, 8, 204, 58,4296,7311,1931, # 2774 + 63,7312,7313, 317,1614, 75, 222, 159,4061,2412,1480,7314,3500,3068, 224,2809, # 2790 +3616, 3, 10,3870,1471, 29,2774,1135,2852,1939, 873, 130,3242,1123, 312,7315, # 2806 +4297,2051, 507, 252, 682,7316, 142,1914, 124, 206,2932, 34,3501,3173, 64, 604, # 2822 +7317,2494,1976,1977, 155,1990, 645, 641,1606,7318,3405, 337, 72, 406,7319, 80, # 2838 + 630, 238,3174,1509, 263, 939,1092,2644, 756,1440,1094,3406, 449, 69,2969, 591, # 2854 + 179,2095, 471, 115,2034,1843, 60, 50,2970, 134, 806,1868, 734,2035,3407, 180, # 2870 + 995,1607, 156, 537,2893, 688,7320, 319,1305, 779,2144, 514,2374, 298,4298, 359, # 2886 +2495, 90,2707,1338, 663, 11, 906,1099,2545, 20,2436, 182, 532,1716,7321, 732, # 2902 +1376,4062,1311,1420,3175, 25,2312,1056, 113, 399, 382,1949, 242,3408,2467, 529, # 2918 +3243, 475,1447,3617,7322, 117, 21, 656, 810,1297,2295,2329,3502,7323, 126,4063, # 2934 + 706, 456, 150, 613,4299, 71,1118,2036,4064, 145,3069, 85, 835, 486,2114,1246, # 2950 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,7324,2127,2354, 347,3736, 221, # 2966 +3503,3110,7325,1955,1153,4065, 83, 296,1199,3070, 192, 624, 93,7326, 822,1897, # 2982 +2810,3111, 795,2064, 991,1554,1542,1592, 27, 43,2853, 859, 139,1456, 860,4300, # 2998 + 437, 712,3871, 164,2392,3112, 695, 211,3017,2096, 195,3872,1608,3504,3505,3618, # 3014 +3873, 234, 811,2971,2097,3874,2229,1441,3506,1615,2375, 668,2076,1638, 305, 228, # 3030 +1664,4301, 467, 415,7327, 262,2098,1593, 239, 108, 300, 200,1033, 512,1247,2077, # 3046 +7328,7329,2173,3176,3619,2673, 593, 845,1062,3244, 88,1723,2037,3875,1950, 212, # 3062 + 266, 152, 149, 468,1898,4066,4302, 77, 187,7330,3018, 37, 5,2972,7331,3876, # 3078 +7332,7333, 39,2517,4303,2894,3177,2078, 55, 148, 74,4304, 545, 483,1474,1029, # 3094 +1665, 217,1869,1531,3113,1104,2645,4067, 24, 172,3507, 900,3877,3508,3509,4305, # 3110 + 32,1408,2811,1312, 329, 487,2355,2247,2708, 784,2674, 4,3019,3314,1427,1788, # 3126 + 188, 109, 499,7334,3620,1717,1789, 888,1217,3020,4306,7335,3510,7336,3315,1520, # 3142 +3621,3878, 196,1034, 775,7337,7338, 929,1815, 249, 439, 38,7339,1063,7340, 794, # 3158 +3879,1435,2296, 46, 178,3245,2065,7341,2376,7342, 214,1709,4307, 804, 35, 707, # 3174 + 324,3622,1601,2546, 140, 459,4068,7343,7344,1365, 839, 272, 978,2257,2572,3409, # 3190 +2128,1363,3623,1423, 697, 100,3071, 48, 70,1231, 495,3114,2193,7345,1294,7346, # 3206 +2079, 462, 586,1042,3246, 853, 256, 988, 185,2377,3410,1698, 434,1084,7347,3411, # 3222 + 314,2615,2775,4308,2330,2331, 569,2280, 637,1816,2518, 757,1162,1878,1616,3412, # 3238 + 287,1577,2115, 768,4309,1671,2854,3511,2519,1321,3737, 909,2413,7348,4069, 933, # 3254 +3738,7349,2052,2356,1222,4310, 765,2414,1322, 786,4311,7350,1919,1462,1677,2895, # 3270 +1699,7351,4312,1424,2437,3115,3624,2590,3316,1774,1940,3413,3880,4070, 309,1369, # 3286 +1130,2812, 364,2230,1653,1299,3881,3512,3882,3883,2646, 525,1085,3021, 902,2000, # 3302 +1475, 964,4313, 421,1844,1415,1057,2281, 940,1364,3116, 376,4314,4315,1381, 7, # 3318 +2520, 983,2378, 336,1710,2675,1845, 321,3414, 559,1131,3022,2742,1808,1132,1313, # 3334 + 265,1481,1857,7352, 352,1203,2813,3247, 167,1089, 420,2814, 776, 792,1724,3513, # 3350 +4071,2438,3248,7353,4072,7354, 446, 229, 333,2743, 901,3739,1200,1557,4316,2647, # 3366 +1920, 395,2744,2676,3740,4073,1835, 125, 916,3178,2616,4317,7355,7356,3741,7357, # 3382 +7358,7359,4318,3117,3625,1133,2547,1757,3415,1510,2313,1409,3514,7360,2145, 438, # 3398 +2591,2896,2379,3317,1068, 958,3023, 461, 311,2855,2677,4074,1915,3179,4075,1978, # 3414 + 383, 750,2745,2617,4076, 274, 539, 385,1278,1442,7361,1154,1964, 384, 561, 210, # 3430 + 98,1295,2548,3515,7362,1711,2415,1482,3416,3884,2897,1257, 129,7363,3742, 642, # 3446 + 523,2776,2777,2648,7364, 141,2231,1333, 68, 176, 441, 876, 907,4077, 603,2592, # 3462 + 710, 171,3417, 404, 549, 18,3118,2393,1410,3626,1666,7365,3516,4319,2898,4320, # 3478 +7366,2973, 368,7367, 146, 366, 99, 871,3627,1543, 748, 807,1586,1185, 22,2258, # 3494 + 379,3743,3180,7368,3181, 505,1941,2618,1991,1382,2314,7369, 380,2357, 218, 702, # 3510 +1817,1248,3418,3024,3517,3318,3249,7370,2974,3628, 930,3250,3744,7371, 59,7372, # 3526 + 585, 601,4078, 497,3419,1112,1314,4321,1801,7373,1223,1472,2174,7374, 749,1836, # 3542 + 690,1899,3745,1772,3885,1476, 429,1043,1790,2232,2116, 917,4079, 447,1086,1629, # 3558 +7375, 556,7376,7377,2020,1654, 844,1090, 105, 550, 966,1758,2815,1008,1782, 686, # 3574 +1095,7378,2282, 793,1602,7379,3518,2593,4322,4080,2933,2297,4323,3746, 980,2496, # 3590 + 544, 353, 527,4324, 908,2678,2899,7380, 381,2619,1942,1348,7381,1341,1252, 560, # 3606 +3072,7382,3420,2856,7383,2053, 973, 886,2080, 143,4325,7384,7385, 157,3886, 496, # 3622 +4081, 57, 840, 540,2038,4326,4327,3421,2117,1445, 970,2259,1748,1965,2081,4082, # 3638 +3119,1234,1775,3251,2816,3629, 773,1206,2129,1066,2039,1326,3887,1738,1725,4083, # 3654 + 279,3120, 51,1544,2594, 423,1578,2130,2066, 173,4328,1879,7386,7387,1583, 264, # 3670 + 610,3630,4329,2439, 280, 154,7388,7389,7390,1739, 338,1282,3073, 693,2857,1411, # 3686 +1074,3747,2440,7391,4330,7392,7393,1240, 952,2394,7394,2900,1538,2679, 685,1483, # 3702 +4084,2468,1436, 953,4085,2054,4331, 671,2395, 79,4086,2441,3252, 608, 567,2680, # 3718 +3422,4087,4088,1691, 393,1261,1791,2396,7395,4332,7396,7397,7398,7399,1383,1672, # 3734 +3748,3182,1464, 522,1119, 661,1150, 216, 675,4333,3888,1432,3519, 609,4334,2681, # 3750 +2397,7400,7401,7402,4089,3025, 0,7403,2469, 315, 231,2442, 301,3319,4335,2380, # 3766 +7404, 233,4090,3631,1818,4336,4337,7405, 96,1776,1315,2082,7406, 257,7407,1809, # 3782 +3632,2709,1139,1819,4091,2021,1124,2163,2778,1777,2649,7408,3074, 363,1655,3183, # 3798 +7409,2975,7410,7411,7412,3889,1567,3890, 718, 103,3184, 849,1443, 341,3320,2934, # 3814 +1484,7413,1712, 127, 67, 339,4092,2398, 679,1412, 821,7414,7415, 834, 738, 351, # 3830 +2976,2146, 846, 235,1497,1880, 418,1992,3749,2710, 186,1100,2147,2746,3520,1545, # 3846 +1355,2935,2858,1377, 583,3891,4093,2573,2977,7416,1298,3633,1078,2549,3634,2358, # 3862 + 78,3750,3751, 267,1289,2099,2001,1594,4094, 348, 369,1274,2194,2175,1837,4338, # 3878 +1820,2817,3635,2747,2283,2002,4339,2936,2748, 144,3321, 882,4340,3892,2749,3423, # 3894 +4341,2901,7417,4095,1726, 320,7418,3893,3026, 788,2978,7419,2818,1773,1327,2859, # 3910 +3894,2819,7420,1306,4342,2003,1700,3752,3521,2359,2650, 787,2022, 506, 824,3636, # 3926 + 534, 323,4343,1044,3322,2023,1900, 946,3424,7421,1778,1500,1678,7422,1881,4344, # 3942 + 165, 243,4345,3637,2521, 123, 683,4096, 764,4346, 36,3895,1792, 589,2902, 816, # 3958 + 626,1667,3027,2233,1639,1555,1622,3753,3896,7423,3897,2860,1370,1228,1932, 891, # 3974 +2083,2903, 304,4097,7424, 292,2979,2711,3522, 691,2100,4098,1115,4347, 118, 662, # 3990 +7425, 611,1156, 854,2381,1316,2861, 2, 386, 515,2904,7426,7427,3253, 868,2234, # 4006 +1486, 855,2651, 785,2212,3028,7428,1040,3185,3523,7429,3121, 448,7430,1525,7431, # 4022 +2164,4348,7432,3754,7433,4099,2820,3524,3122, 503, 818,3898,3123,1568, 814, 676, # 4038 +1444, 306,1749,7434,3755,1416,1030, 197,1428, 805,2821,1501,4349,7435,7436,7437, # 4054 +1993,7438,4350,7439,7440,2195, 13,2779,3638,2980,3124,1229,1916,7441,3756,2131, # 4070 +7442,4100,4351,2399,3525,7443,2213,1511,1727,1120,7444,7445, 646,3757,2443, 307, # 4086 +7446,7447,1595,3186,7448,7449,7450,3639,1113,1356,3899,1465,2522,2523,7451, 519, # 4102 +7452, 128,2132, 92,2284,1979,7453,3900,1512, 342,3125,2196,7454,2780,2214,1980, # 4118 +3323,7455, 290,1656,1317, 789, 827,2360,7456,3758,4352, 562, 581,3901,7457, 401, # 4134 +4353,2248, 94,4354,1399,2781,7458,1463,2024,4355,3187,1943,7459, 828,1105,4101, # 4150 +1262,1394,7460,4102, 605,4356,7461,1783,2862,7462,2822, 819,2101, 578,2197,2937, # 4166 +7463,1502, 436,3254,4103,3255,2823,3902,2905,3425,3426,7464,2712,2315,7465,7466, # 4182 +2332,2067, 23,4357, 193, 826,3759,2102, 699,1630,4104,3075, 390,1793,1064,3526, # 4198 +7467,1579,3076,3077,1400,7468,4105,1838,1640,2863,7469,4358,4359, 137,4106, 598, # 4214 +3078,1966, 780, 104, 974,2938,7470, 278, 899, 253, 402, 572, 504, 493,1339,7471, # 4230 +3903,1275,4360,2574,2550,7472,3640,3029,3079,2249, 565,1334,2713, 863, 41,7473, # 4246 +7474,4361,7475,1657,2333, 19, 463,2750,4107, 606,7476,2981,3256,1087,2084,1323, # 4262 +2652,2982,7477,1631,1623,1750,4108,2682,7478,2864, 791,2714,2653,2334, 232,2416, # 4278 +7479,2983,1498,7480,2654,2620, 755,1366,3641,3257,3126,2025,1609, 119,1917,3427, # 4294 + 862,1026,4109,7481,3904,3760,4362,3905,4363,2260,1951,2470,7482,1125, 817,4110, # 4310 +4111,3906,1513,1766,2040,1487,4112,3030,3258,2824,3761,3127,7483,7484,1507,7485, # 4326 +2683, 733, 40,1632,1106,2865, 345,4113, 841,2524, 230,4364,2984,1846,3259,3428, # 4342 +7486,1263, 986,3429,7487, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562,3907, # 4358 +3908,2939, 967,2751,2655,1349, 592,2133,1692,3324,2985,1994,4114,1679,3909,1901, # 4374 +2185,7488, 739,3642,2715,1296,1290,7489,4115,2198,2199,1921,1563,2595,2551,1870, # 4390 +2752,2986,7490, 435,7491, 343,1108, 596, 17,1751,4365,2235,3430,3643,7492,4366, # 4406 + 294,3527,2940,1693, 477, 979, 281,2041,3528, 643,2042,3644,2621,2782,2261,1031, # 4422 +2335,2134,2298,3529,4367, 367,1249,2552,7493,3530,7494,4368,1283,3325,2004, 240, # 4438 +1762,3326,4369,4370, 836,1069,3128, 474,7495,2148,2525, 268,3531,7496,3188,1521, # 4454 +1284,7497,1658,1546,4116,7498,3532,3533,7499,4117,3327,2684,1685,4118, 961,1673, # 4470 +2622, 190,2005,2200,3762,4371,4372,7500, 570,2497,3645,1490,7501,4373,2623,3260, # 4486 +1956,4374, 584,1514, 396,1045,1944,7502,4375,1967,2444,7503,7504,4376,3910, 619, # 4502 +7505,3129,3261, 215,2006,2783,2553,3189,4377,3190,4378, 763,4119,3763,4379,7506, # 4518 +7507,1957,1767,2941,3328,3646,1174, 452,1477,4380,3329,3130,7508,2825,1253,2382, # 4534 +2186,1091,2285,4120, 492,7509, 638,1169,1824,2135,1752,3911, 648, 926,1021,1324, # 4550 +4381, 520,4382, 997, 847,1007, 892,4383,3764,2262,1871,3647,7510,2400,1784,4384, # 4566 +1952,2942,3080,3191,1728,4121,2043,3648,4385,2007,1701,3131,1551, 30,2263,4122, # 4582 +7511,2026,4386,3534,7512, 501,7513,4123, 594,3431,2165,1821,3535,3432,3536,3192, # 4598 + 829,2826,4124,7514,1680,3132,1225,4125,7515,3262,4387,4126,3133,2336,7516,4388, # 4614 +4127,7517,3912,3913,7518,1847,2383,2596,3330,7519,4389, 374,3914, 652,4128,4129, # 4630 + 375,1140, 798,7520,7521,7522,2361,4390,2264, 546,1659, 138,3031,2445,4391,7523, # 4646 +2250, 612,1848, 910, 796,3765,1740,1371, 825,3766,3767,7524,2906,2554,7525, 692, # 4662 + 444,3032,2624, 801,4392,4130,7526,1491, 244,1053,3033,4131,4132, 340,7527,3915, # 4678 +1041,2987, 293,1168, 87,1357,7528,1539, 959,7529,2236, 721, 694,4133,3768, 219, # 4694 +1478, 644,1417,3331,2656,1413,1401,1335,1389,3916,7530,7531,2988,2362,3134,1825, # 4710 + 730,1515, 184,2827, 66,4393,7532,1660,2943, 246,3332, 378,1457, 226,3433, 975, # 4726 +3917,2944,1264,3537, 674, 696,7533, 163,7534,1141,2417,2166, 713,3538,3333,4394, # 4742 +3918,7535,7536,1186, 15,7537,1079,1070,7538,1522,3193,3539, 276,1050,2716, 758, # 4758 +1126, 653,2945,3263,7539,2337, 889,3540,3919,3081,2989, 903,1250,4395,3920,3434, # 4774 +3541,1342,1681,1718, 766,3264, 286, 89,2946,3649,7540,1713,7541,2597,3334,2990, # 4790 +7542,2947,2215,3194,2866,7543,4396,2498,2526, 181, 387,1075,3921, 731,2187,3335, # 4806 +7544,3265, 310, 313,3435,2299, 770,4134, 54,3034, 189,4397,3082,3769,3922,7545, # 4822 +1230,1617,1849, 355,3542,4135,4398,3336, 111,4136,3650,1350,3135,3436,3035,4137, # 4838 +2149,3266,3543,7546,2784,3923,3924,2991, 722,2008,7547,1071, 247,1207,2338,2471, # 4854 +1378,4399,2009, 864,1437,1214,4400, 373,3770,1142,2216, 667,4401, 442,2753,2555, # 4870 +3771,3925,1968,4138,3267,1839, 837, 170,1107, 934,1336,1882,7548,7549,2118,4139, # 4886 +2828, 743,1569,7550,4402,4140, 582,2384,1418,3437,7551,1802,7552, 357,1395,1729, # 4902 +3651,3268,2418,1564,2237,7553,3083,3772,1633,4403,1114,2085,4141,1532,7554, 482, # 4918 +2446,4404,7555,7556,1492, 833,1466,7557,2717,3544,1641,2829,7558,1526,1272,3652, # 4934 +4142,1686,1794, 416,2556,1902,1953,1803,7559,3773,2785,3774,1159,2316,7560,2867, # 4950 +4405,1610,1584,3036,2419,2754, 443,3269,1163,3136,7561,7562,3926,7563,4143,2499, # 4966 +3037,4406,3927,3137,2103,1647,3545,2010,1872,4144,7564,4145, 431,3438,7565, 250, # 4982 + 97, 81,4146,7566,1648,1850,1558, 160, 848,7567, 866, 740,1694,7568,2201,2830, # 4998 +3195,4147,4407,3653,1687, 950,2472, 426, 469,3196,3654,3655,3928,7569,7570,1188, # 5014 + 424,1995, 861,3546,4148,3775,2202,2685, 168,1235,3547,4149,7571,2086,1674,4408, # 5030 +3337,3270, 220,2557,1009,7572,3776, 670,2992, 332,1208, 717,7573,7574,3548,2447, # 5046 +3929,3338,7575, 513,7576,1209,2868,3339,3138,4409,1080,7577,7578,7579,7580,2527, # 5062 +3656,3549, 815,1587,3930,3931,7581,3550,3439,3777,1254,4410,1328,3038,1390,3932, # 5078 +1741,3933,3778,3934,7582, 236,3779,2448,3271,7583,7584,3657,3780,1273,3781,4411, # 5094 +7585, 308,7586,4412, 245,4413,1851,2473,1307,2575, 430, 715,2136,2449,7587, 270, # 5110 + 199,2869,3935,7588,3551,2718,1753, 761,1754, 725,1661,1840,4414,3440,3658,7589, # 5126 +7590, 587, 14,3272, 227,2598, 326, 480,2265, 943,2755,3552, 291, 650,1883,7591, # 5142 +1702,1226, 102,1547, 62,3441, 904,4415,3442,1164,4150,7592,7593,1224,1548,2756, # 5158 + 391, 498,1493,7594,1386,1419,7595,2055,1177,4416, 813, 880,1081,2363, 566,1145, # 5174 +4417,2286,1001,1035,2558,2599,2238, 394,1286,7596,7597,2068,7598, 86,1494,1730, # 5190 +3936, 491,1588, 745, 897,2948, 843,3340,3937,2757,2870,3273,1768, 998,2217,2069, # 5206 + 397,1826,1195,1969,3659,2993,3341, 284,7599,3782,2500,2137,2119,1903,7600,3938, # 5222 +2150,3939,4151,1036,3443,1904, 114,2559,4152, 209,1527,7601,7602,2949,2831,2625, # 5238 +2385,2719,3139, 812,2560,7603,3274,7604,1559, 737,1884,3660,1210, 885, 28,2686, # 5254 +3553,3783,7605,4153,1004,1779,4418,7606, 346,1981,2218,2687,4419,3784,1742, 797, # 5270 +1642,3940,1933,1072,1384,2151, 896,3941,3275,3661,3197,2871,3554,7607,2561,1958, # 5286 +4420,2450,1785,7608,7609,7610,3942,4154,1005,1308,3662,4155,2720,4421,4422,1528, # 5302 +2600, 161,1178,4156,1982, 987,4423,1101,4157, 631,3943,1157,3198,2420,1343,1241, # 5318 +1016,2239,2562, 372, 877,2339,2501,1160, 555,1934, 911,3944,7611, 466,1170, 169, # 5334 +1051,2907,2688,3663,2474,2994,1182,2011,2563,1251,2626,7612, 992,2340,3444,1540, # 5350 +2721,1201,2070,2401,1996,2475,7613,4424, 528,1922,2188,1503,1873,1570,2364,3342, # 5366 +3276,7614, 557,1073,7615,1827,3445,2087,2266,3140,3039,3084, 767,3085,2786,4425, # 5382 +1006,4158,4426,2341,1267,2176,3664,3199, 778,3945,3200,2722,1597,2657,7616,4427, # 5398 +7617,3446,7618,7619,7620,3277,2689,1433,3278, 131, 95,1504,3946, 723,4159,3141, # 5414 +1841,3555,2758,2189,3947,2027,2104,3665,7621,2995,3948,1218,7622,3343,3201,3949, # 5430 +4160,2576, 248,1634,3785, 912,7623,2832,3666,3040,3786, 654, 53,7624,2996,7625, # 5446 +1688,4428, 777,3447,1032,3950,1425,7626, 191, 820,2120,2833, 971,4429, 931,3202, # 5462 + 135, 664, 783,3787,1997, 772,2908,1935,3951,3788,4430,2909,3203, 282,2723, 640, # 5478 +1372,3448,1127, 922, 325,3344,7627,7628, 711,2044,7629,7630,3952,2219,2787,1936, # 5494 +3953,3345,2220,2251,3789,2300,7631,4431,3790,1258,3279,3954,3204,2138,2950,3955, # 5510 +3956,7632,2221, 258,3205,4432, 101,1227,7633,3280,1755,7634,1391,3281,7635,2910, # 5526 +2056, 893,7636,7637,7638,1402,4161,2342,7639,7640,3206,3556,7641,7642, 878,1325, # 5542 +1780,2788,4433, 259,1385,2577, 744,1183,2267,4434,7643,3957,2502,7644, 684,1024, # 5558 +4162,7645, 472,3557,3449,1165,3282,3958,3959, 322,2152, 881, 455,1695,1152,1340, # 5574 + 660, 554,2153,4435,1058,4436,4163, 830,1065,3346,3960,4437,1923,7646,1703,1918, # 5590 +7647, 932,2268, 122,7648,4438, 947, 677,7649,3791,2627, 297,1905,1924,2269,4439, # 5606 +2317,3283,7650,7651,4164,7652,4165, 84,4166, 112, 989,7653, 547,1059,3961, 701, # 5622 +3558,1019,7654,4167,7655,3450, 942, 639, 457,2301,2451, 993,2951, 407, 851, 494, # 5638 +4440,3347, 927,7656,1237,7657,2421,3348, 573,4168, 680, 921,2911,1279,1874, 285, # 5654 + 790,1448,1983, 719,2167,7658,7659,4441,3962,3963,1649,7660,1541, 563,7661,1077, # 5670 +7662,3349,3041,3451, 511,2997,3964,3965,3667,3966,1268,2564,3350,3207,4442,4443, # 5686 +7663, 535,1048,1276,1189,2912,2028,3142,1438,1373,2834,2952,1134,2012,7664,4169, # 5702 +1238,2578,3086,1259,7665, 700,7666,2953,3143,3668,4170,7667,4171,1146,1875,1906, # 5718 +4444,2601,3967, 781,2422, 132,1589, 203, 147, 273,2789,2402, 898,1786,2154,3968, # 5734 +3969,7668,3792,2790,7669,7670,4445,4446,7671,3208,7672,1635,3793, 965,7673,1804, # 5750 +2690,1516,3559,1121,1082,1329,3284,3970,1449,3794, 65,1128,2835,2913,2759,1590, # 5766 +3795,7674,7675, 12,2658, 45, 976,2579,3144,4447, 517,2528,1013,1037,3209,7676, # 5782 +3796,2836,7677,3797,7678,3452,7679,2602, 614,1998,2318,3798,3087,2724,2628,7680, # 5798 +2580,4172, 599,1269,7681,1810,3669,7682,2691,3088, 759,1060, 489,1805,3351,3285, # 5814 +1358,7683,7684,2386,1387,1215,2629,2252, 490,7685,7686,4173,1759,2387,2343,7687, # 5830 +4448,3799,1907,3971,2630,1806,3210,4449,3453,3286,2760,2344, 874,7688,7689,3454, # 5846 +3670,1858, 91,2914,3671,3042,3800,4450,7690,3145,3972,2659,7691,3455,1202,1403, # 5862 +3801,2954,2529,1517,2503,4451,3456,2504,7692,4452,7693,2692,1885,1495,1731,3973, # 5878 +2365,4453,7694,2029,7695,7696,3974,2693,1216, 237,2581,4174,2319,3975,3802,4454, # 5894 +4455,2694,3560,3457, 445,4456,7697,7698,7699,7700,2761, 61,3976,3672,1822,3977, # 5910 +7701, 687,2045, 935, 925, 405,2660, 703,1096,1859,2725,4457,3978,1876,1367,2695, # 5926 +3352, 918,2105,1781,2476, 334,3287,1611,1093,4458, 564,3146,3458,3673,3353, 945, # 5942 +2631,2057,4459,7702,1925, 872,4175,7703,3459,2696,3089, 349,4176,3674,3979,4460, # 5958 +3803,4177,3675,2155,3980,4461,4462,4178,4463,2403,2046, 782,3981, 400, 251,4179, # 5974 +1624,7704,7705, 277,3676, 299,1265, 476,1191,3804,2121,4180,4181,1109, 205,7706, # 5990 +2582,1000,2156,3561,1860,7707,7708,7709,4464,7710,4465,2565, 107,2477,2157,3982, # 6006 +3460,3147,7711,1533, 541,1301, 158, 753,4182,2872,3562,7712,1696, 370,1088,4183, # 6022 +4466,3563, 579, 327, 440, 162,2240, 269,1937,1374,3461, 968,3043, 56,1396,3090, # 6038 +2106,3288,3354,7713,1926,2158,4467,2998,7714,3564,7715,7716,3677,4468,2478,7717, # 6054 +2791,7718,1650,4469,7719,2603,7720,7721,3983,2661,3355,1149,3356,3984,3805,3985, # 6070 +7722,1076, 49,7723, 951,3211,3289,3290, 450,2837, 920,7724,1811,2792,2366,4184, # 6086 +1908,1138,2367,3806,3462,7725,3212,4470,1909,1147,1518,2423,4471,3807,7726,4472, # 6102 +2388,2604, 260,1795,3213,7727,7728,3808,3291, 708,7729,3565,1704,7730,3566,1351, # 6118 +1618,3357,2999,1886, 944,4185,3358,4186,3044,3359,4187,7731,3678, 422, 413,1714, # 6134 +3292, 500,2058,2345,4188,2479,7732,1344,1910, 954,7733,1668,7734,7735,3986,2404, # 6150 +4189,3567,3809,4190,7736,2302,1318,2505,3091, 133,3092,2873,4473, 629, 31,2838, # 6166 +2697,3810,4474, 850, 949,4475,3987,2955,1732,2088,4191,1496,1852,7737,3988, 620, # 6182 +3214, 981,1242,3679,3360,1619,3680,1643,3293,2139,2452,1970,1719,3463,2168,7738, # 6198 +3215,7739,7740,3361,1828,7741,1277,4476,1565,2047,7742,1636,3568,3093,7743, 869, # 6214 +2839, 655,3811,3812,3094,3989,3000,3813,1310,3569,4477,7744,7745,7746,1733, 558, # 6230 +4478,3681, 335,1549,3045,1756,4192,3682,1945,3464,1829,1291,1192, 470,2726,2107, # 6246 +2793, 913,1054,3990,7747,1027,7748,3046,3991,4479, 982,2662,3362,3148,3465,3216, # 6262 +3217,1946,2794,7749, 571,4480,7750,1830,7751,3570,2583,1523,2424,7752,2089, 984, # 6278 +4481,3683,1959,7753,3684, 852, 923,2795,3466,3685, 969,1519, 999,2048,2320,1705, # 6294 +7754,3095, 615,1662, 151, 597,3992,2405,2321,1049, 275,4482,3686,4193, 568,3687, # 6310 +3571,2480,4194,3688,7755,2425,2270, 409,3218,7756,1566,2874,3467,1002, 769,2840, # 6326 + 194,2090,3149,3689,2222,3294,4195, 628,1505,7757,7758,1763,2177,3001,3993, 521, # 6342 +1161,2584,1787,2203,2406,4483,3994,1625,4196,4197, 412, 42,3096, 464,7759,2632, # 6358 +4484,3363,1760,1571,2875,3468,2530,1219,2204,3814,2633,2140,2368,4485,4486,3295, # 6374 +1651,3364,3572,7760,7761,3573,2481,3469,7762,3690,7763,7764,2271,2091, 460,7765, # 6390 +4487,7766,3002, 962, 588,3574, 289,3219,2634,1116, 52,7767,3047,1796,7768,7769, # 6406 +7770,1467,7771,1598,1143,3691,4198,1984,1734,1067,4488,1280,3365, 465,4489,1572, # 6422 + 510,7772,1927,2241,1812,1644,3575,7773,4490,3692,7774,7775,2663,1573,1534,7776, # 6438 +7777,4199, 536,1807,1761,3470,3815,3150,2635,7778,7779,7780,4491,3471,2915,1911, # 6454 +2796,7781,3296,1122, 377,3220,7782, 360,7783,7784,4200,1529, 551,7785,2059,3693, # 6470 +1769,2426,7786,2916,4201,3297,3097,2322,2108,2030,4492,1404, 136,1468,1479, 672, # 6486 +1171,3221,2303, 271,3151,7787,2762,7788,2049, 678,2727, 865,1947,4493,7789,2013, # 6502 +3995,2956,7790,2728,2223,1397,3048,3694,4494,4495,1735,2917,3366,3576,7791,3816, # 6518 + 509,2841,2453,2876,3817,7792,7793,3152,3153,4496,4202,2531,4497,2304,1166,1010, # 6534 + 552, 681,1887,7794,7795,2957,2958,3996,1287,1596,1861,3154, 358, 453, 736, 175, # 6550 + 478,1117, 905,1167,1097,7796,1853,1530,7797,1706,7798,2178,3472,2287,3695,3473, # 6566 +3577,4203,2092,4204,7799,3367,1193,2482,4205,1458,2190,2205,1862,1888,1421,3298, # 6582 +2918,3049,2179,3474, 595,2122,7800,3997,7801,7802,4206,1707,2636, 223,3696,1359, # 6598 + 751,3098, 183,3475,7803,2797,3003, 419,2369, 633, 704,3818,2389, 241,7804,7805, # 6614 +7806, 838,3004,3697,2272,2763,2454,3819,1938,2050,3998,1309,3099,2242,1181,7807, # 6630 +1136,2206,3820,2370,1446,4207,2305,4498,7808,7809,4208,1055,2605, 484,3698,7810, # 6646 +3999, 625,4209,2273,3368,1499,4210,4000,7811,4001,4211,3222,2274,2275,3476,7812, # 6662 +7813,2764, 808,2606,3699,3369,4002,4212,3100,2532, 526,3370,3821,4213, 955,7814, # 6678 +1620,4214,2637,2427,7815,1429,3700,1669,1831, 994, 928,7816,3578,1260,7817,7818, # 6694 +7819,1948,2288, 741,2919,1626,4215,2729,2455, 867,1184, 362,3371,1392,7820,7821, # 6710 +4003,4216,1770,1736,3223,2920,4499,4500,1928,2698,1459,1158,7822,3050,3372,2877, # 6726 +1292,1929,2506,2842,3701,1985,1187,2071,2014,2607,4217,7823,2566,2507,2169,3702, # 6742 +2483,3299,7824,3703,4501,7825,7826, 666,1003,3005,1022,3579,4218,7827,4502,1813, # 6758 +2253, 574,3822,1603, 295,1535, 705,3823,4219, 283, 858, 417,7828,7829,3224,4503, # 6774 +4504,3051,1220,1889,1046,2276,2456,4004,1393,1599, 689,2567, 388,4220,7830,2484, # 6790 + 802,7831,2798,3824,2060,1405,2254,7832,4505,3825,2109,1052,1345,3225,1585,7833, # 6806 + 809,7834,7835,7836, 575,2730,3477, 956,1552,1469,1144,2323,7837,2324,1560,2457, # 6822 +3580,3226,4005, 616,2207,3155,2180,2289,7838,1832,7839,3478,4506,7840,1319,3704, # 6838 +3705,1211,3581,1023,3227,1293,2799,7841,7842,7843,3826, 607,2306,3827, 762,2878, # 6854 +1439,4221,1360,7844,1485,3052,7845,4507,1038,4222,1450,2061,2638,4223,1379,4508, # 6870 +2585,7846,7847,4224,1352,1414,2325,2921,1172,7848,7849,3828,3829,7850,1797,1451, # 6886 +7851,7852,7853,7854,2922,4006,4007,2485,2346, 411,4008,4009,3582,3300,3101,4509, # 6902 +1561,2664,1452,4010,1375,7855,7856, 47,2959, 316,7857,1406,1591,2923,3156,7858, # 6918 +1025,2141,3102,3157, 354,2731, 884,2224,4225,2407, 508,3706, 726,3583, 996,2428, # 6934 +3584, 729,7859, 392,2191,1453,4011,4510,3707,7860,7861,2458,3585,2608,1675,2800, # 6950 + 919,2347,2960,2348,1270,4511,4012, 73,7862,7863, 647,7864,3228,2843,2255,1550, # 6966 +1346,3006,7865,1332, 883,3479,7866,7867,7868,7869,3301,2765,7870,1212, 831,1347, # 6982 +4226,4512,2326,3830,1863,3053, 720,3831,4513,4514,3832,7871,4227,7872,7873,4515, # 6998 +7874,7875,1798,4516,3708,2609,4517,3586,1645,2371,7876,7877,2924, 669,2208,2665, # 7014 +2429,7878,2879,7879,7880,1028,3229,7881,4228,2408,7882,2256,1353,7883,7884,4518, # 7030 +3158, 518,7885,4013,7886,4229,1960,7887,2142,4230,7888,7889,3007,2349,2350,3833, # 7046 + 516,1833,1454,4014,2699,4231,4519,2225,2610,1971,1129,3587,7890,2766,7891,2961, # 7062 +1422, 577,1470,3008,1524,3373,7892,7893, 432,4232,3054,3480,7894,2586,1455,2508, # 7078 +2226,1972,1175,7895,1020,2732,4015,3481,4520,7896,2733,7897,1743,1361,3055,3482, # 7094 +2639,4016,4233,4521,2290, 895, 924,4234,2170, 331,2243,3056, 166,1627,3057,1098, # 7110 +7898,1232,2880,2227,3374,4522, 657, 403,1196,2372, 542,3709,3375,1600,4235,3483, # 7126 +7899,4523,2767,3230, 576, 530,1362,7900,4524,2533,2666,3710,4017,7901, 842,3834, # 7142 +7902,2801,2031,1014,4018, 213,2700,3376, 665, 621,4236,7903,3711,2925,2430,7904, # 7158 +2431,3302,3588,3377,7905,4237,2534,4238,4525,3589,1682,4239,3484,1380,7906, 724, # 7174 +2277, 600,1670,7907,1337,1233,4526,3103,2244,7908,1621,4527,7909, 651,4240,7910, # 7190 +1612,4241,2611,7911,2844,7912,2734,2307,3058,7913, 716,2459,3059, 174,1255,2701, # 7206 +4019,3590, 548,1320,1398, 728,4020,1574,7914,1890,1197,3060,4021,7915,3061,3062, # 7222 +3712,3591,3713, 747,7916, 635,4242,4528,7917,7918,7919,4243,7920,7921,4529,7922, # 7238 +3378,4530,2432, 451,7923,3714,2535,2072,4244,2735,4245,4022,7924,1764,4531,7925, # 7254 +4246, 350,7926,2278,2390,2486,7927,4247,4023,2245,1434,4024, 488,4532, 458,4248, # 7270 +4025,3715, 771,1330,2391,3835,2568,3159,2159,2409,1553,2667,3160,4249,7928,2487, # 7286 +2881,2612,1720,2702,4250,3379,4533,7929,2536,4251,7930,3231,4252,2768,7931,2015, # 7302 +2736,7932,1155,1017,3716,3836,7933,3303,2308, 201,1864,4253,1430,7934,4026,7935, # 7318 +7936,7937,7938,7939,4254,1604,7940, 414,1865, 371,2587,4534,4535,3485,2016,3104, # 7334 +4536,1708, 960,4255, 887, 389,2171,1536,1663,1721,7941,2228,4027,2351,2926,1580, # 7350 +7942,7943,7944,1744,7945,2537,4537,4538,7946,4539,7947,2073,7948,7949,3592,3380, # 7366 +2882,4256,7950,4257,2640,3381,2802, 673,2703,2460, 709,3486,4028,3593,4258,7951, # 7382 +1148, 502, 634,7952,7953,1204,4540,3594,1575,4541,2613,3717,7954,3718,3105, 948, # 7398 +3232, 121,1745,3837,1110,7955,4259,3063,2509,3009,4029,3719,1151,1771,3838,1488, # 7414 +4030,1986,7956,2433,3487,7957,7958,2093,7959,4260,3839,1213,1407,2803, 531,2737, # 7430 +2538,3233,1011,1537,7960,2769,4261,3106,1061,7961,3720,3721,1866,2883,7962,2017, # 7446 + 120,4262,4263,2062,3595,3234,2309,3840,2668,3382,1954,4542,7963,7964,3488,1047, # 7462 +2704,1266,7965,1368,4543,2845, 649,3383,3841,2539,2738,1102,2846,2669,7966,7967, # 7478 +1999,7968,1111,3596,2962,7969,2488,3842,3597,2804,1854,3384,3722,7970,7971,3385, # 7494 +2410,2884,3304,3235,3598,7972,2569,7973,3599,2805,4031,1460, 856,7974,3600,7975, # 7510 +2885,2963,7976,2886,3843,7977,4264, 632,2510, 875,3844,1697,3845,2291,7978,7979, # 7526 +4544,3010,1239, 580,4545,4265,7980, 914, 936,2074,1190,4032,1039,2123,7981,7982, # 7542 +7983,3386,1473,7984,1354,4266,3846,7985,2172,3064,4033, 915,3305,4267,4268,3306, # 7558 +1605,1834,7986,2739, 398,3601,4269,3847,4034, 328,1912,2847,4035,3848,1331,4270, # 7574 +3011, 937,4271,7987,3602,4036,4037,3387,2160,4546,3388, 524, 742, 538,3065,1012, # 7590 +7988,7989,3849,2461,7990, 658,1103, 225,3850,7991,7992,4547,7993,4548,7994,3236, # 7606 +1243,7995,4038, 963,2246,4549,7996,2705,3603,3161,7997,7998,2588,2327,7999,4550, # 7622 +8000,8001,8002,3489,3307, 957,3389,2540,2032,1930,2927,2462, 870,2018,3604,1746, # 7638 +2770,2771,2434,2463,8003,3851,8004,3723,3107,3724,3490,3390,3725,8005,1179,3066, # 7654 +8006,3162,2373,4272,3726,2541,3163,3108,2740,4039,8007,3391,1556,2542,2292, 977, # 7670 +2887,2033,4040,1205,3392,8008,1765,3393,3164,2124,1271,1689, 714,4551,3491,8009, # 7686 +2328,3852, 533,4273,3605,2181, 617,8010,2464,3308,3492,2310,8011,8012,3165,8013, # 7702 +8014,3853,1987, 618, 427,2641,3493,3394,8015,8016,1244,1690,8017,2806,4274,4552, # 7718 +8018,3494,8019,8020,2279,1576, 473,3606,4275,3395, 972,8021,3607,8022,3067,8023, # 7734 +8024,4553,4554,8025,3727,4041,4042,8026, 153,4555, 356,8027,1891,2888,4276,2143, # 7750 + 408, 803,2352,8028,3854,8029,4277,1646,2570,2511,4556,4557,3855,8030,3856,4278, # 7766 +8031,2411,3396, 752,8032,8033,1961,2964,8034, 746,3012,2465,8035,4279,3728, 698, # 7782 +4558,1892,4280,3608,2543,4559,3609,3857,8036,3166,3397,8037,1823,1302,4043,2706, # 7798 +3858,1973,4281,8038,4282,3167, 823,1303,1288,1236,2848,3495,4044,3398, 774,3859, # 7814 +8039,1581,4560,1304,2849,3860,4561,8040,2435,2161,1083,3237,4283,4045,4284, 344, # 7830 +1173, 288,2311, 454,1683,8041,8042,1461,4562,4046,2589,8043,8044,4563, 985, 894, # 7846 +8045,3399,3168,8046,1913,2928,3729,1988,8047,2110,1974,8048,4047,8049,2571,1194, # 7862 + 425,8050,4564,3169,1245,3730,4285,8051,8052,2850,8053, 636,4565,1855,3861, 760, # 7878 +1799,8054,4286,2209,1508,4566,4048,1893,1684,2293,8055,8056,8057,4287,4288,2210, # 7894 + 479,8058,8059, 832,8060,4049,2489,8061,2965,2490,3731, 990,3109, 627,1814,2642, # 7910 +4289,1582,4290,2125,2111,3496,4567,8062, 799,4291,3170,8063,4568,2112,1737,3013, # 7926 +1018, 543, 754,4292,3309,1676,4569,4570,4050,8064,1489,8065,3497,8066,2614,2889, # 7942 +4051,8067,8068,2966,8069,8070,8071,8072,3171,4571,4572,2182,1722,8073,3238,3239, # 7958 +1842,3610,1715, 481, 365,1975,1856,8074,8075,1962,2491,4573,8076,2126,3611,3240, # 7974 + 433,1894,2063,2075,8077, 602,2741,8078,8079,8080,8081,8082,3014,1628,3400,8083, # 7990 +3172,4574,4052,2890,4575,2512,8084,2544,2772,8085,8086,8087,3310,4576,2891,8088, # 8006 +4577,8089,2851,4578,4579,1221,2967,4053,2513,8090,8091,8092,1867,1989,8093,8094, # 8022 +8095,1895,8096,8097,4580,1896,4054, 318,8098,2094,4055,4293,8099,8100, 485,8101, # 8038 + 938,3862, 553,2670, 116,8102,3863,3612,8103,3498,2671,2773,3401,3311,2807,8104, # 8054 +3613,2929,4056,1747,2930,2968,8105,8106, 207,8107,8108,2672,4581,2514,8109,3015, # 8070 + 890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, # 8086 +2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, # 8102 +) + diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euctwprober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euctwprober.py new file mode 100644 index 0000000..35669cc --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euctwprober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCTWDistributionAnalysis +from .mbcssm import EUCTW_SM_MODEL + +class EUCTWProber(MultiByteCharSetProber): + def __init__(self): + super(EUCTWProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCTW_SM_MODEL) + self.distribution_analyzer = EUCTWDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-TW" + + @property + def language(self): + return "Taiwan" diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/gb2312freq.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/gb2312freq.py new file mode 100644 index 0000000..697837b --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/gb2312freq.py @@ -0,0 +1,283 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# GB2312 most frequently used character table +# +# Char to FreqOrder table , from hz6763 + +# 512 --> 0.79 -- 0.79 +# 1024 --> 0.92 -- 0.13 +# 2048 --> 0.98 -- 0.06 +# 6768 --> 1.00 -- 0.02 +# +# Ideal Distribution Ratio = 0.79135/(1-0.79135) = 3.79 +# Random Distribution Ration = 512 / (3755 - 512) = 0.157 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR + +GB2312_TYPICAL_DISTRIBUTION_RATIO = 0.9 + +GB2312_TABLE_SIZE = 3760 + +GB2312_CHAR_TO_FREQ_ORDER = ( +1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205, +2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842, +2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409, + 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670, +1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820, +1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585, + 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566, +1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575, +2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853, +3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061, + 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155, +1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406, + 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816, +2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606, + 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023, +2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414, +1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513, +3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052, + 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570, +1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575, + 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250, +2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506, +1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26, +3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835, +1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686, +2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054, +1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894, + 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105, +3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403, +3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694, + 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873, +3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940, + 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121, +1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648, +3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992, +2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233, +1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157, + 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807, +1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094, +4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258, + 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478, +3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152, +3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909, + 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272, +1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221, +2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252, +1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301, +1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254, + 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070, +3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461, +3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360, +4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124, + 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535, +3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243, +1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713, +1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071, +4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442, + 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946, + 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257, +3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180, +1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427, + 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781, +1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724, +2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937, + 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943, + 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789, + 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552, +3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246, +4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451, +3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310, + 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860, +2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297, +2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780, +2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745, + 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936, +2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032, + 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657, + 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414, + 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976, +3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436, +2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254, +2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536, +1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238, + 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059, +2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741, + 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447, + 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601, +1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269, +1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894, + 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173, + 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994, +1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956, +2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437, +3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154, +2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240, +2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143, +2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634, +3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472, +1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541, +1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143, +2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312, +1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414, +3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754, +1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424, +1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302, +3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739, + 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004, +2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484, +1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739, +4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535, +1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641, +1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307, +3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573, +1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533, + 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965, + 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99, +1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280, + 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505, +1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012, +1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039, + 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982, +3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530, +4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392, +3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656, +2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220, +2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766, +1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535, +3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728, +2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338, +1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627, +1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885, + 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411, +2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671, +2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162, +3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774, +4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524, +3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346, + 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040, +3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188, +2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280, +1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131, + 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947, + 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970, +3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814, +4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557, +2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997, +1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972, +1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369, + 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376, +1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480, +3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610, + 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128, + 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769, +1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207, + 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392, +1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623, + 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782, +2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650, + 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478, +2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773, +2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007, +1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323, +1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598, +2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961, + 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302, +1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409, +1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683, +2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191, +2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616, +3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302, +1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774, +4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147, + 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731, + 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464, +3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377, +1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315, + 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557, +3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903, +1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060, +4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261, +1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092, +2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810, +1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708, + 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658, +1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871, +3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503, + 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229, +2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112, + 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504, +1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389, +1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27, +1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542, +3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861, +2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845, +3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700, +3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469, +3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582, + 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999, +2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274, + 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020, +2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601, + 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628, +1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31, + 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668, + 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778, +1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169, +3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667, +3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881, +1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276, +1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320, +3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751, +2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432, +2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772, +1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843, +3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116, + 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904, +4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652, +1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664, +2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770, +3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283, +3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626, +1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713, + 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333, + 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062, +2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555, + 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014, +1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510, + 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015, +1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459, +1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390, +1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238, +1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232, +1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624, + 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189, + 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, #last 512 +) + diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/gb2312prober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/gb2312prober.py new file mode 100644 index 0000000..8446d2d --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/gb2312prober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import GB2312DistributionAnalysis +from .mbcssm import GB2312_SM_MODEL + +class GB2312Prober(MultiByteCharSetProber): + def __init__(self): + super(GB2312Prober, self).__init__() + self.coding_sm = CodingStateMachine(GB2312_SM_MODEL) + self.distribution_analyzer = GB2312DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "GB2312" + + @property + def language(self): + return "Chinese" diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/hebrewprober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/hebrewprober.py new file mode 100644 index 0000000..b0e1bf4 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/hebrewprober.py @@ -0,0 +1,292 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Shy Shalom +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +# This prober doesn't actually recognize a language or a charset. +# It is a helper prober for the use of the Hebrew model probers + +### General ideas of the Hebrew charset recognition ### +# +# Four main charsets exist in Hebrew: +# "ISO-8859-8" - Visual Hebrew +# "windows-1255" - Logical Hebrew +# "ISO-8859-8-I" - Logical Hebrew +# "x-mac-hebrew" - ?? Logical Hebrew ?? +# +# Both "ISO" charsets use a completely identical set of code points, whereas +# "windows-1255" and "x-mac-hebrew" are two different proper supersets of +# these code points. windows-1255 defines additional characters in the range +# 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific +# diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6. +# x-mac-hebrew defines similar additional code points but with a different +# mapping. +# +# As far as an average Hebrew text with no diacritics is concerned, all four +# charsets are identical with respect to code points. Meaning that for the +# main Hebrew alphabet, all four map the same values to all 27 Hebrew letters +# (including final letters). +# +# The dominant difference between these charsets is their directionality. +# "Visual" directionality means that the text is ordered as if the renderer is +# not aware of a BIDI rendering algorithm. The renderer sees the text and +# draws it from left to right. The text itself when ordered naturally is read +# backwards. A buffer of Visual Hebrew generally looks like so: +# "[last word of first line spelled backwards] [whole line ordered backwards +# and spelled backwards] [first word of first line spelled backwards] +# [end of line] [last word of second line] ... etc' " +# adding punctuation marks, numbers and English text to visual text is +# naturally also "visual" and from left to right. +# +# "Logical" directionality means the text is ordered "naturally" according to +# the order it is read. It is the responsibility of the renderer to display +# the text from right to left. A BIDI algorithm is used to place general +# punctuation marks, numbers and English text in the text. +# +# Texts in x-mac-hebrew are almost impossible to find on the Internet. From +# what little evidence I could find, it seems that its general directionality +# is Logical. +# +# To sum up all of the above, the Hebrew probing mechanism knows about two +# charsets: +# Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are +# backwards while line order is natural. For charset recognition purposes +# the line order is unimportant (In fact, for this implementation, even +# word order is unimportant). +# Logical Hebrew - "windows-1255" - normal, naturally ordered text. +# +# "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be +# specifically identified. +# "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew +# that contain special punctuation marks or diacritics is displayed with +# some unconverted characters showing as question marks. This problem might +# be corrected using another model prober for x-mac-hebrew. Due to the fact +# that x-mac-hebrew texts are so rare, writing another model prober isn't +# worth the effort and performance hit. +# +#### The Prober #### +# +# The prober is divided between two SBCharSetProbers and a HebrewProber, +# all of which are managed, created, fed data, inquired and deleted by the +# SBCSGroupProber. The two SBCharSetProbers identify that the text is in +# fact some kind of Hebrew, Logical or Visual. The final decision about which +# one is it is made by the HebrewProber by combining final-letter scores +# with the scores of the two SBCharSetProbers to produce a final answer. +# +# The SBCSGroupProber is responsible for stripping the original text of HTML +# tags, English characters, numbers, low-ASCII punctuation characters, spaces +# and new lines. It reduces any sequence of such characters to a single space. +# The buffer fed to each prober in the SBCS group prober is pure text in +# high-ASCII. +# The two SBCharSetProbers (model probers) share the same language model: +# Win1255Model. +# The first SBCharSetProber uses the model normally as any other +# SBCharSetProber does, to recognize windows-1255, upon which this model was +# built. The second SBCharSetProber is told to make the pair-of-letter +# lookup in the language model backwards. This in practice exactly simulates +# a visual Hebrew model using the windows-1255 logical Hebrew model. +# +# The HebrewProber is not using any language model. All it does is look for +# final-letter evidence suggesting the text is either logical Hebrew or visual +# Hebrew. Disjointed from the model probers, the results of the HebrewProber +# alone are meaningless. HebrewProber always returns 0.00 as confidence +# since it never identifies a charset by itself. Instead, the pointer to the +# HebrewProber is passed to the model probers as a helper "Name Prober". +# When the Group prober receives a positive identification from any prober, +# it asks for the name of the charset identified. If the prober queried is a +# Hebrew model prober, the model prober forwards the call to the +# HebrewProber to make the final decision. In the HebrewProber, the +# decision is made according to the final-letters scores maintained and Both +# model probers scores. The answer is returned in the form of the name of the +# charset identified, either "windows-1255" or "ISO-8859-8". + +class HebrewProber(CharSetProber): + # windows-1255 / ISO-8859-8 code points of interest + FINAL_KAF = 0xea + NORMAL_KAF = 0xeb + FINAL_MEM = 0xed + NORMAL_MEM = 0xee + FINAL_NUN = 0xef + NORMAL_NUN = 0xf0 + FINAL_PE = 0xf3 + NORMAL_PE = 0xf4 + FINAL_TSADI = 0xf5 + NORMAL_TSADI = 0xf6 + + # Minimum Visual vs Logical final letter score difference. + # If the difference is below this, don't rely solely on the final letter score + # distance. + MIN_FINAL_CHAR_DISTANCE = 5 + + # Minimum Visual vs Logical model score difference. + # If the difference is below this, don't rely at all on the model score + # distance. + MIN_MODEL_DISTANCE = 0.01 + + VISUAL_HEBREW_NAME = "ISO-8859-8" + LOGICAL_HEBREW_NAME = "windows-1255" + + def __init__(self): + super(HebrewProber, self).__init__() + self._final_char_logical_score = None + self._final_char_visual_score = None + self._prev = None + self._before_prev = None + self._logical_prober = None + self._visual_prober = None + self.reset() + + def reset(self): + self._final_char_logical_score = 0 + self._final_char_visual_score = 0 + # The two last characters seen in the previous buffer, + # mPrev and mBeforePrev are initialized to space in order to simulate + # a word delimiter at the beginning of the data + self._prev = ' ' + self._before_prev = ' ' + # These probers are owned by the group prober. + + def set_model_probers(self, logicalProber, visualProber): + self._logical_prober = logicalProber + self._visual_prober = visualProber + + def is_final(self, c): + return c in [self.FINAL_KAF, self.FINAL_MEM, self.FINAL_NUN, + self.FINAL_PE, self.FINAL_TSADI] + + def is_non_final(self, c): + # The normal Tsadi is not a good Non-Final letter due to words like + # 'lechotet' (to chat) containing an apostrophe after the tsadi. This + # apostrophe is converted to a space in FilterWithoutEnglishLetters + # causing the Non-Final tsadi to appear at an end of a word even + # though this is not the case in the original text. + # The letters Pe and Kaf rarely display a related behavior of not being + # a good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak' + # for example legally end with a Non-Final Pe or Kaf. However, the + # benefit of these letters as Non-Final letters outweighs the damage + # since these words are quite rare. + return c in [self.NORMAL_KAF, self.NORMAL_MEM, + self.NORMAL_NUN, self.NORMAL_PE] + + def feed(self, byte_str): + # Final letter analysis for logical-visual decision. + # Look for evidence that the received buffer is either logical Hebrew + # or visual Hebrew. + # The following cases are checked: + # 1) A word longer than 1 letter, ending with a final letter. This is + # an indication that the text is laid out "naturally" since the + # final letter really appears at the end. +1 for logical score. + # 2) A word longer than 1 letter, ending with a Non-Final letter. In + # normal Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi, + # should not end with the Non-Final form of that letter. Exceptions + # to this rule are mentioned above in isNonFinal(). This is an + # indication that the text is laid out backwards. +1 for visual + # score + # 3) A word longer than 1 letter, starting with a final letter. Final + # letters should not appear at the beginning of a word. This is an + # indication that the text is laid out backwards. +1 for visual + # score. + # + # The visual score and logical score are accumulated throughout the + # text and are finally checked against each other in GetCharSetName(). + # No checking for final letters in the middle of words is done since + # that case is not an indication for either Logical or Visual text. + # + # We automatically filter out all 7-bit characters (replace them with + # spaces) so the word boundary detection works properly. [MAP] + + if self.state == ProbingState.NOT_ME: + # Both model probers say it's not them. No reason to continue. + return ProbingState.NOT_ME + + byte_str = self.filter_high_byte_only(byte_str) + + for cur in byte_str: + if cur == ' ': + # We stand on a space - a word just ended + if self._before_prev != ' ': + # next-to-last char was not a space so self._prev is not a + # 1 letter word + if self.is_final(self._prev): + # case (1) [-2:not space][-1:final letter][cur:space] + self._final_char_logical_score += 1 + elif self.is_non_final(self._prev): + # case (2) [-2:not space][-1:Non-Final letter][ + # cur:space] + self._final_char_visual_score += 1 + else: + # Not standing on a space + if ((self._before_prev == ' ') and + (self.is_final(self._prev)) and (cur != ' ')): + # case (3) [-2:space][-1:final letter][cur:not space] + self._final_char_visual_score += 1 + self._before_prev = self._prev + self._prev = cur + + # Forever detecting, till the end or until both model probers return + # ProbingState.NOT_ME (handled above) + return ProbingState.DETECTING + + @property + def charset_name(self): + # Make the decision: is it Logical or Visual? + # If the final letter score distance is dominant enough, rely on it. + finalsub = self._final_char_logical_score - self._final_char_visual_score + if finalsub >= self.MIN_FINAL_CHAR_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if finalsub <= -self.MIN_FINAL_CHAR_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # It's not dominant enough, try to rely on the model scores instead. + modelsub = (self._logical_prober.get_confidence() + - self._visual_prober.get_confidence()) + if modelsub > self.MIN_MODEL_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if modelsub < -self.MIN_MODEL_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # Still no good, back to final letter distance, maybe it'll save the + # day. + if finalsub < 0.0: + return self.VISUAL_HEBREW_NAME + + # (finalsub > 0 - Logical) or (don't know what to do) default to + # Logical. + return self.LOGICAL_HEBREW_NAME + + @property + def language(self): + return 'Hebrew' + + @property + def state(self): + # Remain active as long as any of the model probers are active. + if (self._logical_prober.state == ProbingState.NOT_ME) and \ + (self._visual_prober.state == ProbingState.NOT_ME): + return ProbingState.NOT_ME + return ProbingState.DETECTING diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/jisfreq.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/jisfreq.py new file mode 100644 index 0000000..83fc082 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/jisfreq.py @@ -0,0 +1,325 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology +# +# Japanese frequency table, applied to both S-JIS and EUC-JP +# They are sorted in order. + +# 128 --> 0.77094 +# 256 --> 0.85710 +# 512 --> 0.92635 +# 1024 --> 0.97130 +# 2048 --> 0.99431 +# +# Ideal Distribution Ratio = 0.92635 / (1-0.92635) = 12.58 +# Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191 +# +# Typical Distribution Ratio, 25% of IDR + +JIS_TYPICAL_DISTRIBUTION_RATIO = 3.0 + +# Char to FreqOrder table , +JIS_TABLE_SIZE = 4368 + +JIS_CHAR_TO_FREQ_ORDER = ( + 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, # 16 +3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, # 32 +1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, # 48 +2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, # 64 +2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, # 80 +5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, # 96 +1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, # 112 +5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, # 128 +5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, # 144 +5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, # 160 +5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, # 176 +5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, # 192 +5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, # 208 +1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, # 224 +1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, # 240 +1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, # 256 +2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, # 272 +3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, # 288 +3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, # 304 + 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, # 320 + 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, # 336 +1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, # 352 + 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, # 368 +5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, # 384 + 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, # 400 + 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, # 416 + 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, # 432 + 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, # 448 + 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, # 464 +5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, # 480 +5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, # 496 +5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, # 512 +4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, # 528 +5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, # 544 +5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, # 560 +5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, # 576 +5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, # 592 +5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, # 608 +5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, # 624 +5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, # 640 +5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, # 656 +5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, # 672 +3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, # 688 +5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, # 704 +5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, # 720 +5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, # 736 +5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, # 752 +5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, # 768 +5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, # 784 +5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, # 800 +5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, # 816 +5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, # 832 +5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, # 848 +5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, # 864 +5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, # 880 +5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, # 896 +5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, # 912 +5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, # 928 +5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, # 944 +5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, # 960 +5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, # 976 +5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, # 992 +5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, # 1008 +5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, # 1024 +5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, # 1040 +5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, # 1056 +5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, # 1072 +5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, # 1088 +5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, # 1104 +5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, # 1120 +5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, # 1136 +5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, # 1152 +5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, # 1168 +5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, # 1184 +5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, # 1200 +5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, # 1216 +5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, # 1232 +5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, # 1248 +5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, # 1264 +5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, # 1280 +5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, # 1296 +6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, # 1312 +6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, # 1328 +6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, # 1344 +6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, # 1360 +6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, # 1376 +6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, # 1392 +6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, # 1408 +6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, # 1424 +4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, # 1440 + 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, # 1456 + 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, # 1472 +1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, # 1488 +1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, # 1504 + 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, # 1520 +3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, # 1536 +3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, # 1552 + 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, # 1568 +3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, # 1584 +3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, # 1600 + 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, # 1616 +2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, # 1632 + 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, # 1648 +3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, # 1664 +1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, # 1680 + 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, # 1696 +1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, # 1712 + 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, # 1728 +2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, # 1744 +2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, # 1760 +2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, # 1776 +2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, # 1792 +1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, # 1808 +1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, # 1824 +1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, # 1840 +1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, # 1856 +2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, # 1872 +1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, # 1888 +2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, # 1904 +1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, # 1920 +1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, # 1936 +1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, # 1952 +1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, # 1968 +1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, # 1984 +1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, # 2000 + 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, # 2016 + 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, # 2032 +1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, # 2048 +2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, # 2064 +2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, # 2080 +2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, # 2096 +3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, # 2112 +3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, # 2128 + 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, # 2144 +3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, # 2160 +1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, # 2176 + 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, # 2192 +2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, # 2208 +1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, # 2224 + 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, # 2240 +3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, # 2256 +4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, # 2272 +2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, # 2288 +1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, # 2304 +2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, # 2320 +1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, # 2336 + 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, # 2352 + 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, # 2368 +1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, # 2384 +2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, # 2400 +2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, # 2416 +2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, # 2432 +3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, # 2448 +1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, # 2464 +2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, # 2480 + 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, # 2496 + 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, # 2512 + 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, # 2528 +1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, # 2544 +2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, # 2560 + 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, # 2576 +1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, # 2592 +1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, # 2608 + 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, # 2624 +1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, # 2640 +1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, # 2656 +1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, # 2672 + 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, # 2688 +2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, # 2704 + 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, # 2720 +2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, # 2736 +3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, # 2752 +2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, # 2768 +1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, # 2784 +6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, # 2800 +1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, # 2816 +2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, # 2832 +1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, # 2848 + 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, # 2864 + 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, # 2880 +3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, # 2896 +3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, # 2912 +1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, # 2928 +1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, # 2944 +1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, # 2960 +1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, # 2976 + 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, # 2992 + 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, # 3008 +2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, # 3024 + 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, # 3040 +3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, # 3056 +2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, # 3072 + 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, # 3088 +1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, # 3104 +2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, # 3120 + 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, # 3136 +1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, # 3152 + 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, # 3168 +4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, # 3184 +2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, # 3200 +1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, # 3216 + 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, # 3232 +1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, # 3248 +2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, # 3264 + 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, # 3280 +6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, # 3296 +1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, # 3312 +1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, # 3328 +2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, # 3344 +3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, # 3360 + 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, # 3376 +3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, # 3392 +1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, # 3408 + 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, # 3424 +1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, # 3440 + 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, # 3456 +3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, # 3472 + 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, # 3488 +2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, # 3504 + 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, # 3520 +4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, # 3536 +2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, # 3552 +1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, # 3568 +1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, # 3584 +1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, # 3600 + 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, # 3616 +1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, # 3632 +3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, # 3648 +1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, # 3664 +3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, # 3680 + 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, # 3696 + 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, # 3712 + 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, # 3728 +2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, # 3744 +1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, # 3760 + 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, # 3776 +1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, # 3792 + 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, # 3808 +1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, # 3824 + 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, # 3840 + 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, # 3856 + 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, # 3872 +1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, # 3888 +1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, # 3904 +2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, # 3920 +4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, # 3936 + 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, # 3952 +1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, # 3968 + 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, # 3984 +1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, # 4000 +3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, # 4016 +1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, # 4032 +2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, # 4048 +2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, # 4064 +1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, # 4080 +1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, # 4096 +2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, # 4112 + 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, # 4128 +2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, # 4144 +1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, # 4160 +1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, # 4176 +1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, # 4192 +1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, # 4208 +3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, # 4224 +2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, # 4240 +2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, # 4256 + 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, # 4272 +3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, # 4288 +3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, # 4304 +1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, # 4320 +2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, # 4336 +1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, # 4352 +2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, # 4368 #last 512 +) + + diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/jpcntx.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/jpcntx.py new file mode 100644 index 0000000..20044e4 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/jpcntx.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +# This is hiragana 2-char sequence table, the number in each cell represents its frequency category +jp2CharContext = ( +(0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1), +(2,4,0,4,0,3,0,4,0,3,4,4,4,2,4,3,3,4,3,2,3,3,4,2,3,3,3,2,4,1,4,3,3,1,5,4,3,4,3,4,3,5,3,0,3,5,4,2,0,3,1,0,3,3,0,3,3,0,1,1,0,4,3,0,3,3,0,4,0,2,0,3,5,5,5,5,4,0,4,1,0,3,4), +(0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2), +(0,4,0,5,0,5,0,4,0,4,5,4,4,3,5,3,5,1,5,3,4,3,4,4,3,4,3,3,4,3,5,4,4,3,5,5,3,5,5,5,3,5,5,3,4,5,5,3,1,3,2,0,3,4,0,4,2,0,4,2,1,5,3,2,3,5,0,4,0,2,0,5,4,4,5,4,5,0,4,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,4,0,3,0,3,0,4,5,4,3,3,3,3,4,3,5,4,4,3,5,4,4,3,4,3,4,4,4,4,5,3,4,4,3,4,5,5,4,5,5,1,4,5,4,3,0,3,3,1,3,3,0,4,4,0,3,3,1,5,3,3,3,5,0,4,0,3,0,4,4,3,4,3,3,0,4,1,1,3,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,4,0,3,0,3,0,4,0,3,4,4,3,2,2,1,2,1,3,1,3,3,3,3,3,4,3,1,3,3,5,3,3,0,4,3,0,5,4,3,3,5,4,4,3,4,4,5,0,1,2,0,1,2,0,2,2,0,1,0,0,5,2,2,1,4,0,3,0,1,0,4,4,3,5,4,3,0,2,1,0,4,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,5,0,4,0,2,1,4,4,2,4,1,4,2,4,2,4,3,3,3,4,3,3,3,3,1,4,2,3,3,3,1,4,4,1,1,1,4,3,3,2,0,2,4,3,2,0,3,3,0,3,1,1,0,0,0,3,3,0,4,2,2,3,4,0,4,0,3,0,4,4,5,3,4,4,0,3,0,0,1,4), +(1,4,0,4,0,4,0,4,0,3,5,4,4,3,4,3,5,4,3,3,4,3,5,4,4,4,4,3,4,2,4,3,3,1,5,4,3,2,4,5,4,5,5,4,4,5,4,4,0,3,2,2,3,3,0,4,3,1,3,2,1,4,3,3,4,5,0,3,0,2,0,4,5,5,4,5,4,0,4,0,0,5,4), +(0,5,0,5,0,4,0,3,0,4,4,3,4,3,3,3,4,0,4,4,4,3,4,3,4,3,3,1,4,2,4,3,4,0,5,4,1,4,5,4,4,5,3,2,4,3,4,3,2,4,1,3,3,3,2,3,2,0,4,3,3,4,3,3,3,4,0,4,0,3,0,4,5,4,4,4,3,0,4,1,0,1,3), +(0,3,1,4,0,3,0,2,0,3,4,4,3,1,4,2,3,3,4,3,4,3,4,3,4,4,3,2,3,1,5,4,4,1,4,4,3,5,4,4,3,5,5,4,3,4,4,3,1,2,3,1,2,2,0,3,2,0,3,1,0,5,3,3,3,4,3,3,3,3,4,4,4,4,5,4,2,0,3,3,2,4,3), +(0,2,0,3,0,1,0,1,0,0,3,2,0,0,2,0,1,0,2,1,3,3,3,1,2,3,1,0,1,0,4,2,1,1,3,3,0,4,3,3,1,4,3,3,0,3,3,2,0,0,0,0,1,0,0,2,0,0,0,0,0,4,1,0,2,3,2,2,2,1,3,3,3,4,4,3,2,0,3,1,0,3,3), +(0,4,0,4,0,3,0,3,0,4,4,4,3,3,3,3,3,3,4,3,4,2,4,3,4,3,3,2,4,3,4,5,4,1,4,5,3,5,4,5,3,5,4,0,3,5,5,3,1,3,3,2,2,3,0,3,4,1,3,3,2,4,3,3,3,4,0,4,0,3,0,4,5,4,4,5,3,0,4,1,0,3,4), +(0,2,0,3,0,3,0,0,0,2,2,2,1,0,1,0,0,0,3,0,3,0,3,0,1,3,1,0,3,1,3,3,3,1,3,3,3,0,1,3,1,3,4,0,0,3,1,1,0,3,2,0,0,0,0,1,3,0,1,0,0,3,3,2,0,3,0,0,0,0,0,3,4,3,4,3,3,0,3,0,0,2,3), +(2,3,0,3,0,2,0,1,0,3,3,4,3,1,3,1,1,1,3,1,4,3,4,3,3,3,0,0,3,1,5,4,3,1,4,3,2,5,5,4,4,4,4,3,3,4,4,4,0,2,1,1,3,2,0,1,2,0,0,1,0,4,1,3,3,3,0,3,0,1,0,4,4,4,5,5,3,0,2,0,0,4,4), +(0,2,0,1,0,3,1,3,0,2,3,3,3,0,3,1,0,0,3,0,3,2,3,1,3,2,1,1,0,0,4,2,1,0,2,3,1,4,3,2,0,4,4,3,1,3,1,3,0,1,0,0,1,0,0,0,1,0,0,0,0,4,1,1,1,2,0,3,0,0,0,3,4,2,4,3,2,0,1,0,0,3,3), +(0,1,0,4,0,5,0,4,0,2,4,4,2,3,3,2,3,3,5,3,3,3,4,3,4,2,3,0,4,3,3,3,4,1,4,3,2,1,5,5,3,4,5,1,3,5,4,2,0,3,3,0,1,3,0,4,2,0,1,3,1,4,3,3,3,3,0,3,0,1,0,3,4,4,4,5,5,0,3,0,1,4,5), +(0,2,0,3,0,3,0,0,0,2,3,1,3,0,4,0,1,1,3,0,3,4,3,2,3,1,0,3,3,2,3,1,3,0,2,3,0,2,1,4,1,2,2,0,0,3,3,0,0,2,0,0,0,1,0,0,0,0,2,2,0,3,2,1,3,3,0,2,0,2,0,0,3,3,1,2,4,0,3,0,2,2,3), +(2,4,0,5,0,4,0,4,0,2,4,4,4,3,4,3,3,3,1,2,4,3,4,3,4,4,5,0,3,3,3,3,2,0,4,3,1,4,3,4,1,4,4,3,3,4,4,3,1,2,3,0,4,2,0,4,1,0,3,3,0,4,3,3,3,4,0,4,0,2,0,3,5,3,4,5,2,0,3,0,0,4,5), +(0,3,0,4,0,1,0,1,0,1,3,2,2,1,3,0,3,0,2,0,2,0,3,0,2,0,0,0,1,0,1,1,0,0,3,1,0,0,0,4,0,3,1,0,2,1,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,2,2,3,1,0,3,0,0,0,1,4,4,4,3,0,0,4,0,0,1,4), +(1,4,1,5,0,3,0,3,0,4,5,4,4,3,5,3,3,4,4,3,4,1,3,3,3,3,2,1,4,1,5,4,3,1,4,4,3,5,4,4,3,5,4,3,3,4,4,4,0,3,3,1,2,3,0,3,1,0,3,3,0,5,4,4,4,4,4,4,3,3,5,4,4,3,3,5,4,0,3,2,0,4,4), +(0,2,0,3,0,1,0,0,0,1,3,3,3,2,4,1,3,0,3,1,3,0,2,2,1,1,0,0,2,0,4,3,1,0,4,3,0,4,4,4,1,4,3,1,1,3,3,1,0,2,0,0,1,3,0,0,0,0,2,0,0,4,3,2,4,3,5,4,3,3,3,4,3,3,4,3,3,0,2,1,0,3,3), +(0,2,0,4,0,3,0,2,0,2,5,5,3,4,4,4,4,1,4,3,3,0,4,3,4,3,1,3,3,2,4,3,0,3,4,3,0,3,4,4,2,4,4,0,4,5,3,3,2,2,1,1,1,2,0,1,5,0,3,3,2,4,3,3,3,4,0,3,0,2,0,4,4,3,5,5,0,0,3,0,2,3,3), +(0,3,0,4,0,3,0,1,0,3,4,3,3,1,3,3,3,0,3,1,3,0,4,3,3,1,1,0,3,0,3,3,0,0,4,4,0,1,5,4,3,3,5,0,3,3,4,3,0,2,0,1,1,1,0,1,3,0,1,2,1,3,3,2,3,3,0,3,0,1,0,1,3,3,4,4,1,0,1,2,2,1,3), +(0,1,0,4,0,4,0,3,0,1,3,3,3,2,3,1,1,0,3,0,3,3,4,3,2,4,2,0,1,0,4,3,2,0,4,3,0,5,3,3,2,4,4,4,3,3,3,4,0,1,3,0,0,1,0,0,1,0,0,0,0,4,2,3,3,3,0,3,0,0,0,4,4,4,5,3,2,0,3,3,0,3,5), +(0,2,0,3,0,0,0,3,0,1,3,0,2,0,0,0,1,0,3,1,1,3,3,0,0,3,0,0,3,0,2,3,1,0,3,1,0,3,3,2,0,4,2,2,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,1,2,0,1,0,1,0,0,0,1,3,1,2,0,0,0,1,0,0,1,4), +(0,3,0,3,0,5,0,1,0,2,4,3,1,3,3,2,1,1,5,2,1,0,5,1,2,0,0,0,3,3,2,2,3,2,4,3,0,0,3,3,1,3,3,0,2,5,3,4,0,3,3,0,1,2,0,2,2,0,3,2,0,2,2,3,3,3,0,2,0,1,0,3,4,4,2,5,4,0,3,0,0,3,5), +(0,3,0,3,0,3,0,1,0,3,3,3,3,0,3,0,2,0,2,1,1,0,2,0,1,0,0,0,2,1,0,0,1,0,3,2,0,0,3,3,1,2,3,1,0,3,3,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,3,1,2,3,0,3,0,1,0,3,2,1,0,4,3,0,1,1,0,3,3), +(0,4,0,5,0,3,0,3,0,4,5,5,4,3,5,3,4,3,5,3,3,2,5,3,4,4,4,3,4,3,4,5,5,3,4,4,3,4,4,5,4,4,4,3,4,5,5,4,2,3,4,2,3,4,0,3,3,1,4,3,2,4,3,3,5,5,0,3,0,3,0,5,5,5,5,4,4,0,4,0,1,4,4), +(0,4,0,4,0,3,0,3,0,3,5,4,4,2,3,2,5,1,3,2,5,1,4,2,3,2,3,3,4,3,3,3,3,2,5,4,1,3,3,5,3,4,4,0,4,4,3,1,1,3,1,0,2,3,0,2,3,0,3,0,0,4,3,1,3,4,0,3,0,2,0,4,4,4,3,4,5,0,4,0,0,3,4), +(0,3,0,3,0,3,1,2,0,3,4,4,3,3,3,0,2,2,4,3,3,1,3,3,3,1,1,0,3,1,4,3,2,3,4,4,2,4,4,4,3,4,4,3,2,4,4,3,1,3,3,1,3,3,0,4,1,0,2,2,1,4,3,2,3,3,5,4,3,3,5,4,4,3,3,0,4,0,3,2,2,4,4), +(0,2,0,1,0,0,0,0,0,1,2,1,3,0,0,0,0,0,2,0,1,2,1,0,0,1,0,0,0,0,3,0,0,1,0,1,1,3,1,0,0,0,1,1,0,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,2,2,0,3,4,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1), +(0,1,0,0,0,1,0,0,0,0,4,0,4,1,4,0,3,0,4,0,3,0,4,0,3,0,3,0,4,1,5,1,4,0,0,3,0,5,0,5,2,0,1,0,0,0,2,1,4,0,1,3,0,0,3,0,0,3,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0), +(1,4,0,5,0,3,0,2,0,3,5,4,4,3,4,3,5,3,4,3,3,0,4,3,3,3,3,3,3,2,4,4,3,1,3,4,4,5,4,4,3,4,4,1,3,5,4,3,3,3,1,2,2,3,3,1,3,1,3,3,3,5,3,3,4,5,0,3,0,3,0,3,4,3,4,4,3,0,3,0,2,4,3), +(0,1,0,4,0,0,0,0,0,1,4,0,4,1,4,2,4,0,3,0,1,0,1,0,0,0,0,0,2,0,3,1,1,1,0,3,0,0,0,1,2,1,0,0,1,1,1,1,0,1,0,0,0,1,0,0,3,0,0,0,0,3,2,0,2,2,0,1,0,0,0,2,3,2,3,3,0,0,0,0,2,1,0), +(0,5,1,5,0,3,0,3,0,5,4,4,5,1,5,3,3,0,4,3,4,3,5,3,4,3,3,2,4,3,4,3,3,0,3,3,1,4,4,3,4,4,4,3,4,5,5,3,2,3,1,1,3,3,1,3,1,1,3,3,2,4,5,3,3,5,0,4,0,3,0,4,4,3,5,3,3,0,3,4,0,4,3), +(0,5,0,5,0,3,0,2,0,4,4,3,5,2,4,3,3,3,4,4,4,3,5,3,5,3,3,1,4,0,4,3,3,0,3,3,0,4,4,4,4,5,4,3,3,5,5,3,2,3,1,2,3,2,0,1,0,0,3,2,2,4,4,3,1,5,0,4,0,3,0,4,3,1,3,2,1,0,3,3,0,3,3), +(0,4,0,5,0,5,0,4,0,4,5,5,5,3,4,3,3,2,5,4,4,3,5,3,5,3,4,0,4,3,4,4,3,2,4,4,3,4,5,4,4,5,5,0,3,5,5,4,1,3,3,2,3,3,1,3,1,0,4,3,1,4,4,3,4,5,0,4,0,2,0,4,3,4,4,3,3,0,4,0,0,5,5), +(0,4,0,4,0,5,0,1,1,3,3,4,4,3,4,1,3,0,5,1,3,0,3,1,3,1,1,0,3,0,3,3,4,0,4,3,0,4,4,4,3,4,4,0,3,5,4,1,0,3,0,0,2,3,0,3,1,0,3,1,0,3,2,1,3,5,0,3,0,1,0,3,2,3,3,4,4,0,2,2,0,4,4), +(2,4,0,5,0,4,0,3,0,4,5,5,4,3,5,3,5,3,5,3,5,2,5,3,4,3,3,4,3,4,5,3,2,1,5,4,3,2,3,4,5,3,4,1,2,5,4,3,0,3,3,0,3,2,0,2,3,0,4,1,0,3,4,3,3,5,0,3,0,1,0,4,5,5,5,4,3,0,4,2,0,3,5), +(0,5,0,4,0,4,0,2,0,5,4,3,4,3,4,3,3,3,4,3,4,2,5,3,5,3,4,1,4,3,4,4,4,0,3,5,0,4,4,4,4,5,3,1,3,4,5,3,3,3,3,3,3,3,0,2,2,0,3,3,2,4,3,3,3,5,3,4,1,3,3,5,3,2,0,0,0,0,4,3,1,3,3), +(0,1,0,3,0,3,0,1,0,1,3,3,3,2,3,3,3,0,3,0,0,0,3,1,3,0,0,0,2,2,2,3,0,0,3,2,0,1,2,4,1,3,3,0,0,3,3,3,0,1,0,0,2,1,0,0,3,0,3,1,0,3,0,0,1,3,0,2,0,1,0,3,3,1,3,3,0,0,1,1,0,3,3), +(0,2,0,3,0,2,1,4,0,2,2,3,1,1,3,1,1,0,2,0,3,1,2,3,1,3,0,0,1,0,4,3,2,3,3,3,1,4,2,3,3,3,3,1,0,3,1,4,0,1,1,0,1,2,0,1,1,0,1,1,0,3,1,3,2,2,0,1,0,0,0,2,3,3,3,1,0,0,0,0,0,2,3), +(0,5,0,4,0,5,0,2,0,4,5,5,3,3,4,3,3,1,5,4,4,2,4,4,4,3,4,2,4,3,5,5,4,3,3,4,3,3,5,5,4,5,5,1,3,4,5,3,1,4,3,1,3,3,0,3,3,1,4,3,1,4,5,3,3,5,0,4,0,3,0,5,3,3,1,4,3,0,4,0,1,5,3), +(0,5,0,5,0,4,0,2,0,4,4,3,4,3,3,3,3,3,5,4,4,4,4,4,4,5,3,3,5,2,4,4,4,3,4,4,3,3,4,4,5,5,3,3,4,3,4,3,3,4,3,3,3,3,1,2,2,1,4,3,3,5,4,4,3,4,0,4,0,3,0,4,4,4,4,4,1,0,4,2,0,2,4), +(0,4,0,4,0,3,0,1,0,3,5,2,3,0,3,0,2,1,4,2,3,3,4,1,4,3,3,2,4,1,3,3,3,0,3,3,0,0,3,3,3,5,3,3,3,3,3,2,0,2,0,0,2,0,0,2,0,0,1,0,0,3,1,2,2,3,0,3,0,2,0,4,4,3,3,4,1,0,3,0,0,2,4), +(0,0,0,4,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,1,0,2,0,1,0,0,0,0,0,3,1,3,0,3,2,0,0,0,1,0,3,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,2,0,0,0,0,0,0,2), +(0,2,1,3,0,2,0,2,0,3,3,3,3,1,3,1,3,3,3,3,3,3,4,2,2,1,2,1,4,0,4,3,1,3,3,3,2,4,3,5,4,3,3,3,3,3,3,3,0,1,3,0,2,0,0,1,0,0,1,0,0,4,2,0,2,3,0,3,3,0,3,3,4,2,3,1,4,0,1,2,0,2,3), +(0,3,0,3,0,1,0,3,0,2,3,3,3,0,3,1,2,0,3,3,2,3,3,2,3,2,3,1,3,0,4,3,2,0,3,3,1,4,3,3,2,3,4,3,1,3,3,1,1,0,1,1,0,1,0,1,0,1,0,0,0,4,1,1,0,3,0,3,1,0,2,3,3,3,3,3,1,0,0,2,0,3,3), +(0,0,0,0,0,0,0,0,0,0,3,0,2,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,0,3,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,2,0,2,3,0,0,0,0,0,0,0,0,3), +(0,2,0,3,1,3,0,3,0,2,3,3,3,1,3,1,3,1,3,1,3,3,3,1,3,0,2,3,1,1,4,3,3,2,3,3,1,2,2,4,1,3,3,0,1,4,2,3,0,1,3,0,3,0,0,1,3,0,2,0,0,3,3,2,1,3,0,3,0,2,0,3,4,4,4,3,1,0,3,0,0,3,3), +(0,2,0,1,0,2,0,0,0,1,3,2,2,1,3,0,1,1,3,0,3,2,3,1,2,0,2,0,1,1,3,3,3,0,3,3,1,1,2,3,2,3,3,1,2,3,2,0,0,1,0,0,0,0,0,0,3,0,1,0,0,2,1,2,1,3,0,3,0,0,0,3,4,4,4,3,2,0,2,0,0,2,4), +(0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,3,1,0,0,0,0,0,0,0,3), +(0,3,0,3,0,2,0,3,0,3,3,3,2,3,2,2,2,0,3,1,3,3,3,2,3,3,0,0,3,0,3,2,2,0,2,3,1,4,3,4,3,3,2,3,1,5,4,4,0,3,1,2,1,3,0,3,1,1,2,0,2,3,1,3,1,3,0,3,0,1,0,3,3,4,4,2,1,0,2,1,0,2,4), +(0,1,0,3,0,1,0,2,0,1,4,2,5,1,4,0,2,0,2,1,3,1,4,0,2,1,0,0,2,1,4,1,1,0,3,3,0,5,1,3,2,3,3,1,0,3,2,3,0,1,0,0,0,0,0,0,1,0,0,0,0,4,0,1,0,3,0,2,0,1,0,3,3,3,4,3,3,0,0,0,0,2,3), +(0,0,0,1,0,0,0,0,0,0,2,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,3), +(0,1,0,3,0,4,0,3,0,2,4,3,1,0,3,2,2,1,3,1,2,2,3,1,1,1,2,1,3,0,1,2,0,1,3,2,1,3,0,5,5,1,0,0,1,3,2,1,0,3,0,0,1,0,0,0,0,0,3,4,0,1,1,1,3,2,0,2,0,1,0,2,3,3,1,2,3,0,1,0,1,0,4), +(0,0,0,1,0,3,0,3,0,2,2,1,0,0,4,0,3,0,3,1,3,0,3,0,3,0,1,0,3,0,3,1,3,0,3,3,0,0,1,2,1,1,1,0,1,2,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,2,2,1,2,0,0,2,0,0,0,0,2,3,3,3,3,0,0,0,0,1,4), +(0,0,0,3,0,3,0,0,0,0,3,1,1,0,3,0,1,0,2,0,1,0,0,0,0,0,0,0,1,0,3,0,2,0,2,3,0,0,2,2,3,1,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,2,3), +(2,4,0,5,0,5,0,4,0,3,4,3,3,3,4,3,3,3,4,3,4,4,5,4,5,5,5,2,3,0,5,5,4,1,5,4,3,1,5,4,3,4,4,3,3,4,3,3,0,3,2,0,2,3,0,3,0,0,3,3,0,5,3,2,3,3,0,3,0,3,0,3,4,5,4,5,3,0,4,3,0,3,4), +(0,3,0,3,0,3,0,3,0,3,3,4,3,2,3,2,3,0,4,3,3,3,3,3,3,3,3,0,3,2,4,3,3,1,3,4,3,4,4,4,3,4,4,3,2,4,4,1,0,2,0,0,1,1,0,2,0,0,3,1,0,5,3,2,1,3,0,3,0,1,2,4,3,2,4,3,3,0,3,2,0,4,4), +(0,3,0,3,0,1,0,0,0,1,4,3,3,2,3,1,3,1,4,2,3,2,4,2,3,4,3,0,2,2,3,3,3,0,3,3,3,0,3,4,1,3,3,0,3,4,3,3,0,1,1,0,1,0,0,0,4,0,3,0,0,3,1,2,1,3,0,4,0,1,0,4,3,3,4,3,3,0,2,0,0,3,3), +(0,3,0,4,0,1,0,3,0,3,4,3,3,0,3,3,3,1,3,1,3,3,4,3,3,3,0,0,3,1,5,3,3,1,3,3,2,5,4,3,3,4,5,3,2,5,3,4,0,1,0,0,0,0,0,2,0,0,1,1,0,4,2,2,1,3,0,3,0,2,0,4,4,3,5,3,2,0,1,1,0,3,4), +(0,5,0,4,0,5,0,2,0,4,4,3,3,2,3,3,3,1,4,3,4,1,5,3,4,3,4,0,4,2,4,3,4,1,5,4,0,4,4,4,4,5,4,1,3,5,4,2,1,4,1,1,3,2,0,3,1,0,3,2,1,4,3,3,3,4,0,4,0,3,0,4,4,4,3,3,3,0,4,2,0,3,4), +(1,4,0,4,0,3,0,1,0,3,3,3,1,1,3,3,2,2,3,3,1,0,3,2,2,1,2,0,3,1,2,1,2,0,3,2,0,2,2,3,3,4,3,0,3,3,1,2,0,1,1,3,1,2,0,0,3,0,1,1,0,3,2,2,3,3,0,3,0,0,0,2,3,3,4,3,3,0,1,0,0,1,4), +(0,4,0,4,0,4,0,0,0,3,4,4,3,1,4,2,3,2,3,3,3,1,4,3,4,0,3,0,4,2,3,3,2,2,5,4,2,1,3,4,3,4,3,1,3,3,4,2,0,2,1,0,3,3,0,0,2,0,3,1,0,4,4,3,4,3,0,4,0,1,0,2,4,4,4,4,4,0,3,2,0,3,3), +(0,0,0,1,0,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,3,2,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2), +(0,2,0,3,0,4,0,4,0,1,3,3,3,0,4,0,2,1,2,1,1,1,2,0,3,1,1,0,1,0,3,1,0,0,3,3,2,0,1,1,0,0,0,0,0,1,0,2,0,2,2,0,3,1,0,0,1,0,1,1,0,1,2,0,3,0,0,0,0,1,0,0,3,3,4,3,1,0,1,0,3,0,2), +(0,0,0,3,0,5,0,0,0,0,1,0,2,0,3,1,0,1,3,0,0,0,2,0,0,0,1,0,0,0,1,1,0,0,4,0,0,0,2,3,0,1,4,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,3,0,0,0,0,0,3), +(0,2,0,5,0,5,0,1,0,2,4,3,3,2,5,1,3,2,3,3,3,0,4,1,2,0,3,0,4,0,2,2,1,1,5,3,0,0,1,4,2,3,2,0,3,3,3,2,0,2,4,1,1,2,0,1,1,0,3,1,0,1,3,1,2,3,0,2,0,0,0,1,3,5,4,4,4,0,3,0,0,1,3), +(0,4,0,5,0,4,0,4,0,4,5,4,3,3,4,3,3,3,4,3,4,4,5,3,4,5,4,2,4,2,3,4,3,1,4,4,1,3,5,4,4,5,5,4,4,5,5,5,2,3,3,1,4,3,1,3,3,0,3,3,1,4,3,4,4,4,0,3,0,4,0,3,3,4,4,5,0,0,4,3,0,4,5), +(0,4,0,4,0,3,0,3,0,3,4,4,4,3,3,2,4,3,4,3,4,3,5,3,4,3,2,1,4,2,4,4,3,1,3,4,2,4,5,5,3,4,5,4,1,5,4,3,0,3,2,2,3,2,1,3,1,0,3,3,3,5,3,3,3,5,4,4,2,3,3,4,3,3,3,2,1,0,3,2,1,4,3), +(0,4,0,5,0,4,0,3,0,3,5,5,3,2,4,3,4,0,5,4,4,1,4,4,4,3,3,3,4,3,5,5,2,3,3,4,1,2,5,5,3,5,5,2,3,5,5,4,0,3,2,0,3,3,1,1,5,1,4,1,0,4,3,2,3,5,0,4,0,3,0,5,4,3,4,3,0,0,4,1,0,4,4), +(1,3,0,4,0,2,0,2,0,2,5,5,3,3,3,3,3,0,4,2,3,4,4,4,3,4,0,0,3,4,5,4,3,3,3,3,2,5,5,4,5,5,5,4,3,5,5,5,1,3,1,0,1,0,0,3,2,0,4,2,0,5,2,3,2,4,1,3,0,3,0,4,5,4,5,4,3,0,4,2,0,5,4), +(0,3,0,4,0,5,0,3,0,3,4,4,3,2,3,2,3,3,3,3,3,2,4,3,3,2,2,0,3,3,3,3,3,1,3,3,3,0,4,4,3,4,4,1,1,4,4,2,0,3,1,0,1,1,0,4,1,0,2,3,1,3,3,1,3,4,0,3,0,1,0,3,1,3,0,0,1,0,2,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,3,0,2,0,3,0,1,5,4,3,3,3,1,4,2,1,2,3,4,4,2,4,4,5,0,3,1,4,3,4,0,4,3,3,3,2,3,2,5,3,4,3,2,2,3,0,0,3,0,2,1,0,1,2,0,0,0,0,2,1,1,3,1,0,2,0,4,0,3,4,4,4,5,2,0,2,0,0,1,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,0,0,0,4,2,1,1,0,1,0,3,2,0,0,3,1,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,2,0,0,0,1,4,0,4,2,1,0,0,0,0,0,1), +(0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,3,1,0,0,0,2,0,2,1,0,0,1,2,1,0,1,1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,3,1,0,0,0,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,2), +(0,4,0,4,0,4,0,3,0,4,4,3,4,2,4,3,2,0,4,4,4,3,5,3,5,3,3,2,4,2,4,3,4,3,1,4,0,2,3,4,4,4,3,3,3,4,4,4,3,4,1,3,4,3,2,1,2,1,3,3,3,4,4,3,3,5,0,4,0,3,0,4,3,3,3,2,1,0,3,0,0,3,3), +(0,4,0,3,0,3,0,3,0,3,5,5,3,3,3,3,4,3,4,3,3,3,4,4,4,3,3,3,3,4,3,5,3,3,1,3,2,4,5,5,5,5,4,3,4,5,5,3,2,2,3,3,3,3,2,3,3,1,2,3,2,4,3,3,3,4,0,4,0,2,0,4,3,2,2,1,2,0,3,0,0,4,1), +) + +class JapaneseContextAnalysis(object): + NUM_OF_CATEGORY = 6 + DONT_KNOW = -1 + ENOUGH_REL_THRESHOLD = 100 + MAX_REL_THRESHOLD = 1000 + MINIMUM_DATA_THRESHOLD = 4 + + def __init__(self): + self._total_rel = None + self._rel_sample = None + self._need_to_skip_char_num = None + self._last_char_order = None + self._done = None + self.reset() + + def reset(self): + self._total_rel = 0 # total sequence received + # category counters, each integer counts sequence in its category + self._rel_sample = [0] * self.NUM_OF_CATEGORY + # if last byte in current buffer is not the last byte of a character, + # we need to know how many bytes to skip in next buffer + self._need_to_skip_char_num = 0 + self._last_char_order = -1 # The order of previous char + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + + def feed(self, byte_str, num_bytes): + if self._done: + return + + # The buffer we got is byte oriented, and a character may span in more than one + # buffers. In case the last one or two byte in last buffer is not + # complete, we record how many byte needed to complete that character + # and skip these bytes here. We can choose to record those bytes as + # well and analyse the character once it is complete, but since a + # character will not make much difference, by simply skipping + # this character will simply our logic and improve performance. + i = self._need_to_skip_char_num + while i < num_bytes: + order, char_len = self.get_order(byte_str[i:i + 2]) + i += char_len + if i > num_bytes: + self._need_to_skip_char_num = i - num_bytes + self._last_char_order = -1 + else: + if (order != -1) and (self._last_char_order != -1): + self._total_rel += 1 + if self._total_rel > self.MAX_REL_THRESHOLD: + self._done = True + break + self._rel_sample[jp2CharContext[self._last_char_order][order]] += 1 + self._last_char_order = order + + def got_enough_data(self): + return self._total_rel > self.ENOUGH_REL_THRESHOLD + + def get_confidence(self): + # This is just one way to calculate confidence. It works well for me. + if self._total_rel > self.MINIMUM_DATA_THRESHOLD: + return (self._total_rel - self._rel_sample[0]) / self._total_rel + else: + return self.DONT_KNOW + + def get_order(self, byte_str): + return -1, 1 + +class SJISContextAnalysis(JapaneseContextAnalysis): + def __init__(self): + super(SJISContextAnalysis, self).__init__() + self._charset_name = "SHIFT_JIS" + + @property + def charset_name(self): + return self._charset_name + + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (0x81 <= first_char <= 0x9F) or (0xE0 <= first_char <= 0xFC): + char_len = 2 + if (first_char == 0x87) or (0xFA <= first_char <= 0xFC): + self._charset_name = "CP932" + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 202) and (0x9F <= second_char <= 0xF1): + return second_char - 0x9F, char_len + + return -1, char_len + +class EUCJPContextAnalysis(JapaneseContextAnalysis): + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (first_char == 0x8E) or (0xA1 <= first_char <= 0xFE): + char_len = 2 + elif first_char == 0x8F: + char_len = 3 + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 0xA4) and (0xA1 <= second_char <= 0xF3): + return second_char - 0xA1, char_len + + return -1, char_len + + diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langbulgarianmodel.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langbulgarianmodel.py new file mode 100644 index 0000000..2aa4fb2 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langbulgarianmodel.py @@ -0,0 +1,228 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +# this table is modified base on win1251BulgarianCharToOrderMap, so +# only number <64 is sure valid + +Latin5_BulgarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, # 40 +110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, # 50 +253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, # 60 +116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, # 70 +194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209, # 80 +210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225, # 90 + 81,226,227,228,229,230,105,231,232,233,234,235,236, 45,237,238, # a0 + 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, # b0 + 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,239, 67,240, 60, 56, # c0 + 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, # d0 + 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,241, 42, 16, # e0 + 62,242,243,244, 58,245, 98,246,247,248,249,250,251, 91,252,253, # f0 +) + +win1251BulgarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, # 40 +110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, # 50 +253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, # 60 +116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, # 70 +206,207,208,209,210,211,212,213,120,214,215,216,217,218,219,220, # 80 +221, 78, 64, 83,121, 98,117,105,222,223,224,225,226,227,228,229, # 90 + 88,230,231,232,233,122, 89,106,234,235,236,237,238, 45,239,240, # a0 + 73, 80,118,114,241,242,243,244,245, 62, 58,246,247,248,249,250, # b0 + 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, # c0 + 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,251, 67,252, 60, 56, # d0 + 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, # e0 + 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,253, 42, 16, # f0 +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 96.9392% +# first 1024 sequences:3.0618% +# rest sequences: 0.2992% +# negative sequences: 0.0020% +BulgarianLangModel = ( +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,2,2,1,2,2, +3,1,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,0,1, +0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,3,3,0,3,1,0, +0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,1,3,3,3,3,2,2,2,1,1,2,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,2,3,2,2,3,3,1,1,2,3,3,2,3,3,3,3,2,1,2,0,2,0,3,0,0, +0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,1,3,3,3,3,3,2,3,2,3,3,3,3,3,2,3,3,1,3,0,3,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,1,3,3,2,3,3,3,1,3,3,2,3,2,2,2,0,0,2,0,2,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,3,3,1,2,2,3,2,1,1,2,0,2,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,2,3,3,1,2,3,2,2,2,3,3,3,3,3,2,2,3,1,2,0,2,1,2,0,0, +0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,1,3,3,3,3,3,2,3,3,3,2,3,3,2,3,2,2,2,3,1,2,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,1,1,1,2,2,1,3,1,3,2,2,3,0,0,1,0,1,0,1,0,0, +0,0,0,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,2,2,3,2,2,3,1,2,1,1,1,2,3,1,3,1,2,2,0,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,1,3,2,2,3,3,1,2,3,1,1,3,3,3,3,1,2,2,1,1,1,0,2,0,2,0,1, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,2,2,3,3,3,2,2,1,1,2,0,2,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,0,1,2,1,3,3,2,3,3,3,3,3,2,3,2,1,0,3,1,2,1,2,1,2,3,2,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,1,2,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,1,3,3,2,3,3,2,2,2,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,0,3,3,3,3,3,2,1,1,2,1,3,3,0,3,1,1,1,1,3,2,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,1,1,3,1,3,3,2,3,2,2,2,3,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,3,2,2,3,2,1,1,1,1,1,3,1,3,1,1,0,0,0,1,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,2,0,3,2,0,3,0,2,0,0,2,1,3,1,0,0,1,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,2,1,1,1,1,2,1,1,2,1,1,1,2,2,1,2,1,1,1,0,1,1,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,2,1,3,1,1,2,1,3,2,1,1,0,1,2,3,2,1,1,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,2,2,1,0,1,0,0,1,0,0,0,2,1,0,3,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,2,3,2,3,3,1,3,2,1,1,1,2,1,1,2,1,3,0,1,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,2,2,3,3,2,3,2,2,2,3,1,2,2,1,1,2,1,1,2,2,0,1,1,0,1,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,3,1,0,2,2,1,3,2,1,0,0,2,0,2,0,1,0,0,0,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,1,2,0,2,3,1,2,3,2,0,1,3,1,2,1,1,1,0,0,1,0,0,2,2,2,3, +2,2,2,2,1,2,1,1,2,2,1,1,2,0,1,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,1, +3,3,3,3,3,2,1,2,2,1,2,0,2,0,1,0,1,2,1,2,1,1,0,0,0,1,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,2,3,3,1,1,3,1,0,3,2,1,0,0,0,1,2,0,2,0,1,0,0,0,1,0,1,2,1,2,2, +1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,0,1,2,1,1,1,0,0,0,0,0,1,1,0,0, +3,1,0,1,0,2,3,2,2,2,3,2,2,2,2,2,1,0,2,1,2,1,1,1,0,1,2,1,2,2,2,1, +1,1,2,2,2,2,1,2,1,1,0,1,2,1,2,2,2,1,1,1,0,1,1,1,1,2,0,1,0,0,0,0, +2,3,2,3,3,0,0,2,1,0,2,1,0,0,0,0,2,3,0,2,0,0,0,0,0,1,0,0,2,0,1,2, +2,1,2,1,2,2,1,1,1,2,1,1,1,0,1,2,2,1,1,1,1,1,0,1,1,1,0,0,1,2,0,0, +3,3,2,2,3,0,2,3,1,1,2,0,0,0,1,0,0,2,0,2,0,0,0,1,0,1,0,1,2,0,2,2, +1,1,1,1,2,1,0,1,2,2,2,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,0,0, +2,3,2,3,3,0,0,3,0,1,1,0,1,0,0,0,2,2,1,2,0,0,0,0,0,0,0,0,2,0,1,2, +2,2,1,1,1,1,1,2,2,2,1,0,2,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0, +3,3,3,3,2,2,2,2,2,0,2,1,1,1,1,2,1,2,1,1,0,2,0,1,0,1,0,0,2,0,1,2, +1,1,1,1,1,1,1,2,2,1,1,0,2,0,1,0,2,0,0,1,1,1,0,0,2,0,0,0,1,1,0,0, +2,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0,0,0,0,1,2,0,1,2, +2,2,2,1,1,2,1,1,2,2,2,1,2,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,0,0, +2,3,3,3,3,0,2,2,0,2,1,0,0,0,1,1,1,2,0,2,0,0,0,3,0,0,0,0,2,0,2,2, +1,1,1,2,1,2,1,1,2,2,2,1,2,0,1,1,1,0,1,1,1,1,0,2,1,0,0,0,1,1,0,0, +2,3,3,3,3,0,2,1,0,0,2,0,0,0,0,0,1,2,0,2,0,0,0,0,0,0,0,0,2,0,1,2, +1,1,1,2,1,1,1,1,2,2,2,0,1,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,0,1,0,0, +3,3,2,2,3,0,1,0,1,0,0,0,0,0,0,0,1,1,0,3,0,0,0,0,0,0,0,0,1,0,2,2, +1,1,1,1,1,2,1,1,2,2,1,2,2,1,0,1,1,1,1,1,0,1,0,0,1,0,0,0,1,1,0,0, +3,1,0,1,0,2,2,2,2,3,2,1,1,1,2,3,0,0,1,0,2,1,1,0,1,1,1,1,2,1,1,1, +1,2,2,1,2,1,2,2,1,1,0,1,2,1,2,2,1,1,1,0,0,1,1,1,2,1,0,1,0,0,0,0, +2,1,0,1,0,3,1,2,2,2,2,1,2,2,1,1,1,0,2,1,2,2,1,1,2,1,1,0,2,1,1,1, +1,2,2,2,2,2,2,2,1,2,0,1,1,0,2,1,1,1,1,1,0,0,1,1,1,1,0,1,0,0,0,0, +2,1,1,1,1,2,2,2,2,1,2,2,2,1,2,2,1,1,2,1,2,3,2,2,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,3,2,0,1,2,0,1,2,1,1,0,1,0,1,2,1,2,0,0,0,1,1,0,0,0,1,0,0,2, +1,1,0,0,1,1,0,1,1,1,1,0,2,0,1,1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0, +2,0,0,0,0,1,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,1,1,1, +1,2,2,2,2,1,1,2,1,2,1,1,1,0,2,1,2,1,1,1,0,2,1,1,1,1,0,1,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, +1,1,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,3,2,0,0,0,0,1,0,0,0,0,0,0,1,1,0,2,0,0,0,0,0,0,0,0,1,0,1,2, +1,1,1,1,1,1,0,0,2,2,2,2,2,0,1,1,0,1,1,1,1,1,0,0,1,0,0,0,1,1,0,1, +2,3,1,2,1,0,1,1,0,2,2,2,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,1,2, +1,1,1,1,2,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0, +2,2,2,2,2,0,0,2,0,0,2,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,0,2,2, +1,1,1,1,1,0,0,1,2,1,1,0,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,2,0,1,1,0,0,0,1,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,1,1, +0,0,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,3,2,0,0,1,0,0,1,0,0,0,0,0,0,1,0,2,0,0,0,1,0,0,0,0,0,0,0,2, +1,1,0,0,1,0,0,0,1,1,0,0,1,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,1,2,2,2,1,2,1,2,2,1,1,2,1,1,1,0,1,1,1,1,2,0,1,0,1,1,1,1,0,1,1, +1,1,2,1,1,1,1,1,1,0,0,1,2,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0, +1,0,0,1,3,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,1,0,0,1,0,2,0,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0,0,2,0,0,1, +0,2,0,1,0,0,1,1,2,0,1,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,1,1,0,2,1,0,1,1,1,0,0,1,0,2,0,1,0,0,0,0,0,0,0,0,0,1, +0,1,0,0,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,2,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, +0,1,0,1,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,0,1,2,1,1,1,1,1,1,2,2,1,0,0,1,0,1,0,0,0,0,1,1,1,1,0,0,0, +1,1,2,1,1,1,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,1,2,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +0,1,1,0,1,1,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, +1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,2,0,0,2,0,1,0,0,1,0,0,1, +1,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, +1,1,1,1,1,1,1,2,0,0,0,0,0,0,2,1,0,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +) + +Latin5BulgarianModel = { + 'char_to_order_map': Latin5_BulgarianCharToOrderMap, + 'precedence_matrix': BulgarianLangModel, + 'typical_positive_ratio': 0.969392, + 'keep_english_letter': False, + 'charset_name': "ISO-8859-5", + 'language': 'Bulgairan', +} + +Win1251BulgarianModel = { + 'char_to_order_map': win1251BulgarianCharToOrderMap, + 'precedence_matrix': BulgarianLangModel, + 'typical_positive_ratio': 0.969392, + 'keep_english_letter': False, + 'charset_name': "windows-1251", + 'language': 'Bulgarian', +} diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langcyrillicmodel.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langcyrillicmodel.py new file mode 100644 index 0000000..e5f9a1f --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langcyrillicmodel.py @@ -0,0 +1,333 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# KOI8-R language model +# Character Mapping Table: +KOI8R_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, # 80 +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, # 90 +223,224,225, 68,226,227,228,229,230,231,232,233,234,235,236,237, # a0 +238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253, # b0 + 27, 3, 21, 28, 13, 2, 39, 19, 26, 4, 23, 11, 8, 12, 5, 1, # c0 + 15, 16, 9, 7, 6, 14, 24, 10, 17, 18, 20, 25, 30, 29, 22, 54, # d0 + 59, 37, 44, 58, 41, 48, 53, 46, 55, 42, 60, 36, 49, 38, 31, 34, # e0 + 35, 43, 45, 32, 40, 52, 56, 33, 61, 62, 51, 57, 47, 63, 50, 70, # f0 +) + +win1251_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, +239,240,241,242,243,244,245,246, 68,247,248,249,250,251,252,253, + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +) + +latin5_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, +) + +macCyrillic_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, +239,240,241,242,243,244,245,246,247,248,249,250,251,252, 68, 16, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27,255, +) + +IBM855_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194, 68,195,196,197,198,199,200,201,202,203,204,205, +206,207,208,209,210,211,212,213,214,215,216,217, 27, 59, 54, 70, + 3, 37, 21, 44, 28, 58, 13, 41, 2, 48, 39, 53, 19, 46,218,219, +220,221,222,223,224, 26, 55, 4, 42,225,226,227,228, 23, 60,229, +230,231,232,233,234,235, 11, 36,236,237,238,239,240,241,242,243, + 8, 49, 12, 38, 5, 31, 1, 34, 15,244,245,246,247, 35, 16,248, + 43, 9, 45, 7, 32, 6, 40, 14, 52, 24, 56, 10, 33, 17, 61,249, +250, 18, 62, 20, 51, 25, 57, 30, 47, 29, 63, 22, 50,251,252,255, +) + +IBM866_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 97.6601% +# first 1024 sequences: 2.3389% +# rest sequences: 0.1237% +# negative sequences: 0.0009% +RussianLangModel = ( +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,3,3,3,3,1,3,3,3,2,3,2,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,2,2,2,2,2,0,0,2, +3,3,3,2,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,2,3,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,2,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,2,3,3,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, +0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, +0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,2,2,2,3,1,3,3,1,3,3,3,3,2,2,3,0,2,2,2,3,3,2,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,3,3,2,2,3,2,3,3,3,2,1,2,2,0,1,2,2,2,2,2,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,0,2,2,3,3,2,1,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,1,2,3,2,2,3,2,3,3,3,3,2,2,3,0,3,2,2,3,1,1,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,3,3,3,3,2,2,2,0,3,3,3,2,2,2,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,2,3,2,2,0,1,3,2,1,2,2,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,2,1,1,3,0,1,1,1,1,2,1,1,0,2,2,2,1,2,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,2,2,2,2,1,3,2,3,2,3,2,1,2,2,0,1,1,2,1,2,1,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,3,3,3,2,2,2,2,0,2,2,2,2,3,1,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,2,3,2,2,3,3,3,3,3,3,3,3,3,1,3,2,0,0,3,3,3,3,2,3,3,3,3,2,3,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,3,2,2,3,3,0,2,1,0,3,2,3,2,3,0,0,1,2,0,0,1,0,1,2,1,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,3,0,2,3,3,3,3,2,3,3,3,3,1,2,2,0,0,2,3,2,2,2,3,2,3,2,2,3,0,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,0,2,3,2,3,0,1,2,3,3,2,0,2,3,0,0,2,3,2,2,0,1,3,1,3,2,2,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,3,0,2,3,3,3,3,3,3,3,3,2,1,3,2,0,0,2,2,3,3,3,2,3,3,0,2,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,2,2,2,3,3,0,0,1,1,1,1,1,2,0,0,1,1,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,0,3,2,3,3,2,3,2,0,2,1,0,1,1,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,2,2,2,2,3,1,3,2,3,1,1,2,1,0,2,2,2,2,1,3,1,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +2,2,3,3,3,3,3,1,2,2,1,3,1,0,3,0,0,3,0,0,0,1,1,0,1,2,1,0,0,0,0,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,2,1,1,3,3,3,2,2,1,2,2,3,1,1,2,0,0,2,2,1,3,0,0,2,1,1,2,1,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,3,3,3,1,2,2,2,1,2,1,3,3,1,1,2,1,2,1,2,2,0,2,0,0,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,3,2,1,3,2,2,3,2,0,3,2,0,3,0,1,0,1,1,0,0,1,1,1,1,0,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,3,3,3,2,2,2,3,3,1,2,1,2,1,0,1,0,1,1,0,1,0,0,2,1,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,1,1,2,1,2,3,3,2,2,1,2,2,3,0,2,1,0,0,2,2,3,2,1,2,2,2,2,2,3,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,1,1,0,1,1,2,2,1,1,3,0,0,1,3,1,1,1,0,0,0,1,0,1,1,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,3,3,3,2,0,0,0,2,1,0,1,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,0,2,3,2,2,2,1,2,2,2,1,2,1,0,0,1,1,1,0,2,0,1,1,1,0,0,1,1, +1,0,0,0,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,0,0,0,0,1,0,0,0,0,3,0,1,2,1,0,0,0,0,0,0,0,1,1,0,0,1,1, +1,0,1,0,1,2,0,0,1,1,2,1,0,1,1,1,1,0,1,1,1,1,0,1,0,0,1,0,0,1,1,0, +2,2,3,2,2,2,3,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,0,1,1,1,0,2,1, +1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0, +3,3,3,2,2,2,2,3,2,2,1,1,2,2,2,2,1,1,3,1,2,1,2,0,0,1,1,0,1,0,2,1, +1,1,1,1,1,2,1,0,1,1,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,1,0, +2,0,0,1,0,3,2,2,2,2,1,2,1,2,1,2,0,0,0,2,1,2,2,1,1,2,2,0,1,1,0,2, +1,1,1,1,1,0,1,1,1,2,1,1,1,2,1,0,1,2,1,1,1,1,0,1,1,1,0,0,1,0,0,1, +1,3,2,2,2,1,1,1,2,3,0,0,0,0,2,0,2,2,1,0,0,0,0,0,0,1,0,0,0,0,1,1, +1,0,1,1,0,1,0,1,1,0,1,1,0,2,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, +2,3,2,3,2,1,2,2,2,2,1,0,0,0,2,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,1, +1,1,2,1,0,2,0,0,1,0,1,0,0,1,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,0, +3,0,0,1,0,2,2,2,3,2,2,2,2,2,2,2,0,0,0,2,1,2,1,1,1,2,2,0,0,0,1,2, +1,1,1,1,1,0,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1, +2,3,2,3,3,2,0,1,1,1,0,0,1,0,2,0,1,1,3,1,0,0,0,0,0,0,0,1,0,0,2,1, +1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,0,0,1,1,0,1,0,0,0,0,0,0,1,0, +2,3,3,3,3,1,2,2,2,2,0,1,1,0,2,1,1,1,2,1,0,1,1,0,0,1,0,1,0,0,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,2,0,0,1,1,2,2,1,0,0,2,0,1,1,3,0,0,1,0,0,0,0,0,1,0,1,2,1, +1,1,2,0,1,1,1,0,1,0,1,1,0,1,0,1,1,1,1,0,1,0,0,0,0,0,0,1,0,1,1,0, +1,3,2,3,2,1,0,0,2,2,2,0,1,0,2,0,1,1,1,0,1,0,0,0,3,0,1,1,0,0,2,1, +1,1,1,0,1,1,0,0,0,0,1,1,0,1,0,0,2,1,1,0,1,0,0,0,1,0,1,0,0,1,1,0, +3,1,2,1,1,2,2,2,2,2,2,1,2,2,1,1,0,0,0,2,2,2,0,0,0,1,2,1,0,1,0,1, +2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,1,1,1,0,1,0,1,1,0,1,1,1,0,0,1, +3,0,0,0,0,2,0,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,0,1,0,1,1,0,0,1,0,1, +1,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1, +1,3,3,2,2,0,0,0,2,2,0,0,0,1,2,0,1,1,2,0,0,0,0,0,0,0,0,1,0,0,2,1, +0,1,1,0,0,1,1,0,0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +2,3,2,3,2,0,0,0,0,1,1,0,0,0,2,0,2,0,2,0,0,0,0,0,1,0,0,1,0,0,1,1, +1,1,2,0,1,2,1,0,1,1,2,1,1,1,1,1,2,1,1,0,1,0,0,1,1,1,1,1,0,1,1,0, +1,3,2,2,2,1,0,0,2,2,1,0,1,2,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,1, +0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,0,2,3,1,2,2,2,2,2,2,1,1,0,0,0,1,0,1,0,2,1,1,1,0,0,0,0,1, +1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +2,0,2,0,0,1,0,3,2,1,2,1,2,2,0,1,0,0,0,2,1,0,0,2,1,1,1,1,0,2,0,2, +2,1,1,1,1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,0,0,0,1,1,1,1,0,1,0,0,1, +1,2,2,2,2,1,0,0,1,0,0,0,0,0,2,0,1,1,1,1,0,0,0,0,1,0,1,2,0,0,2,0, +1,0,1,1,1,2,1,0,1,0,1,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0, +2,1,2,2,2,0,3,0,1,1,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0, +1,2,2,3,2,2,0,0,1,1,2,0,1,2,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1, +0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, +2,2,1,1,2,1,2,2,2,2,2,1,2,2,0,1,0,0,0,1,2,2,2,1,2,1,1,1,1,1,2,1, +1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,0,1, +1,2,2,2,2,0,1,0,2,2,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0, +0,0,1,0,0,1,0,0,0,0,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,0,2,2,2,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1, +0,1,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,0,0,1,0,0,1,1,2,0,0,0,0,1,0,1,0,0,1,0,0,2,0,0,0,1, +0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,1,1,2,0,2,1,1,1,1,0,2,2,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1, +0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,0,2,1,2,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0, +0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +1,0,0,0,0,2,0,1,2,1,0,1,1,1,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1, +0,0,0,0,0,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1, +2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,1,0,1,0,1,0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,0,1,1,0,1,0,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0, +0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, +) + +Koi8rModel = { + 'char_to_order_map': KOI8R_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "KOI8-R", + 'language': 'Russian', +} + +Win1251CyrillicModel = { + 'char_to_order_map': win1251_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "windows-1251", + 'language': 'Russian', +} + +Latin5CyrillicModel = { + 'char_to_order_map': latin5_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "ISO-8859-5", + 'language': 'Russian', +} + +MacCyrillicModel = { + 'char_to_order_map': macCyrillic_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "MacCyrillic", + 'language': 'Russian', +} + +Ibm866Model = { + 'char_to_order_map': IBM866_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "IBM866", + 'language': 'Russian', +} + +Ibm855Model = { + 'char_to_order_map': IBM855_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "IBM855", + 'language': 'Russian', +} diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langgreekmodel.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langgreekmodel.py new file mode 100644 index 0000000..5332221 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langgreekmodel.py @@ -0,0 +1,225 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +Latin7_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, # 40 + 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, # 50 +253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, # 60 + 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, # 70 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 80 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 90 +253,233, 90,253,253,253,253,253,253,253,253,253,253, 74,253,253, # a0 +253,253,253,253,247,248, 61, 36, 46, 71, 73,253, 54,253,108,123, # b0 +110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, # c0 + 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, # d0 +124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, # e0 + 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, # f0 +) + +win1253_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, # 40 + 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, # 50 +253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, # 60 + 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, # 70 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 80 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 90 +253,233, 61,253,253,253,253,253,253,253,253,253,253, 74,253,253, # a0 +253,253,253,253,247,253,253, 36, 46, 71, 73,253, 54,253,108,123, # b0 +110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, # c0 + 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, # d0 +124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, # e0 + 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, # f0 +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 98.2851% +# first 1024 sequences:1.7001% +# rest sequences: 0.0359% +# negative sequences: 0.0148% +GreekLangModel = ( +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,2,2,3,3,3,3,3,3,3,3,1,3,3,3,0,2,2,3,3,0,3,0,3,2,0,3,3,3,0, +3,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,0,3,3,0,3,2,3,3,0,3,2,3,3,3,0,0,3,0,3,0,3,3,2,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,2,3,2,2,3,3,3,3,3,3,3,3,0,3,3,3,3,0,2,3,3,0,3,3,3,3,2,3,3,3,0, +2,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,2,1,3,3,3,3,2,3,3,2,3,3,2,0, +0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,2,3,3,0, +2,0,1,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,3,0,0,0,0,3,3,0,3,1,3,3,3,0,3,3,0,3,3,3,3,0,0,0,0, +2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,0,3,0,3,3,3,3,3,0,3,2,2,2,3,0,2,3,3,3,3,3,2,3,3,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,3,2,2,2,3,3,3,3,0,3,1,3,3,3,3,2,3,3,3,3,3,3,3,2,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,3,0,0,0,3,3,2,3,3,3,3,3,0,0,3,2,3,0,2,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,3,0,0,3,3,0,2,3,0,3,0,3,3,3,0,0,3,0,3,0,2,2,3,3,0,0, +0,0,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,3,2,3,3,3,3,0,3,3,3,3,3,0,3,3,2,3,2,3,3,2,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,2,3,2,3,3,3,3,3,3,0,2,3,2,3,2,2,2,3,2,3,3,2,3,0,2,2,2,3,0, +2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,0,3,3,3,2,3,3,0,0,3,0,3,0,0,0,3,2,0,3,0,3,0,0,2,0,2,0, +0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,0,0,0,3,3,0,3,3,3,0,0,1,2,3,0, +3,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,0,3,2,2,3,3,0,3,3,3,3,3,2,1,3,0,3,2,3,3,2,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,3,0,2,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,3,0,3,2,3,0,0,3,3,3,0, +3,0,0,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,2,0,3,2,3,0,0,3,2,3,0, +2,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,1,2,2,3,3,3,3,3,3,0,2,3,0,3,0,0,0,3,3,0,3,0,2,0,0,2,3,1,0, +2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,3,0,3,0,3,3,2,3,0,3,3,3,3,3,3,0,3,3,3,0,2,3,0,0,3,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,0,0,3,0,0,0,3,3,0,3,0,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,0,3,3,3,3,3,3,0,0,3,0,2,0,0,0,3,3,0,3,0,3,0,0,2,0,2,0, +0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,3,0,3,0,2,0,3,2,0,3,2,3,2,3,0,0,3,2,3,2,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,2,3,3,3,3,3,0,0,0,3,0,2,1,0,0,3,2,2,2,0,3,0,0,2,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,2,0,3,0,3,0,3,3,0,2,1,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,3,0,3,3,3,3,3,3,0,2,3,0,3,0,0,0,2,1,0,2,2,3,0,0,2,2,2,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,2,3,3,3,2,3,0,0,1,3,0,2,0,0,0,0,3,0,1,0,2,0,0,1,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,1,0,3,0,0,0,3,2,0,3,2,3,3,3,0,0,3,0,3,2,2,2,1,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,0,0,3,0,0,0,0,2,0,2,3,3,2,2,2,2,3,0,2,0,2,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,2,0,0,0,0,0,0,2,3,0,2,0,2,3,2,0,0,3,0,3,0,3,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,3,2,3,3,2,2,3,0,2,0,3,0,0,0,2,0,0,0,0,1,2,0,2,0,2,0, +0,2,0,2,0,2,2,0,0,1,0,2,2,2,0,2,2,2,0,2,2,2,0,0,2,0,0,1,0,0,0,0, +0,2,0,3,3,2,0,0,0,0,0,0,1,3,0,2,0,2,2,2,0,0,2,0,3,0,0,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,2,3,2,0,2,2,0,2,0,2,2,0,2,0,2,2,2,0,0,0,0,0,0,2,3,0,0,0,2, +0,1,2,0,0,0,0,2,2,0,0,0,2,1,0,2,2,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0, +0,0,2,1,0,2,3,2,2,3,2,3,2,0,0,3,3,3,0,0,3,2,0,0,0,1,1,0,2,0,2,2, +0,2,0,2,0,2,2,0,0,2,0,2,2,2,0,2,2,2,2,0,0,2,0,0,0,2,0,1,0,0,0,0, +0,3,0,3,3,2,2,0,3,0,0,0,2,2,0,2,2,2,1,2,0,0,1,2,2,0,0,3,0,0,0,2, +0,1,2,0,0,0,1,2,0,0,0,0,0,0,0,2,2,0,1,0,0,2,0,0,0,2,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,2,2,0,0,0,2,0,2,3,3,0,2,0,0,0,0,0,0,2,2,2,0,2,2,0,2,0,2, +0,2,2,0,0,2,2,2,2,1,0,0,2,2,0,2,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0, +0,2,0,3,2,3,0,0,0,3,0,0,2,2,0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,0,2, +0,0,2,2,0,0,2,2,2,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,3,2,0,2,2,2,2,2,0,0,0,2,0,0,0,0,2,0,1,0,0,2,0,1,0,0,0, +0,2,2,2,0,2,2,0,1,2,0,2,2,2,0,2,2,2,2,1,2,2,0,0,2,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,2,0,2,0,2,2,0,0,0,0,1,2,1,0,0,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,3,2,3,0,0,2,0,0,0,2,2,0,2,0,0,0,1,0,0,2,0,2,0,2,2,0,0,0,0, +0,0,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0, +0,2,2,3,2,2,0,0,0,0,0,0,1,3,0,2,0,2,2,0,0,0,1,0,2,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,0,2,0,3,2,0,2,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,2,0,0,0,0,1,1,0,0,2,1,2,0,2,2,0,1,0,0,1,0,0,0,2,0,0,0,0,0,0, +0,3,0,2,2,2,0,0,2,0,0,0,2,0,0,0,2,3,0,2,0,0,0,0,0,0,2,2,0,0,0,2, +0,1,2,0,0,0,1,2,2,1,0,0,0,2,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,1,2,0,2,2,0,2,0,0,2,0,0,0,0,1,2,1,0,2,1,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,0,3,1,2,2,0,2,0,0,0,0,2,0,0,0,2,0,0,3,0,0,0,0,2,2,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,1,0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,2, +0,2,2,0,0,2,2,2,2,2,0,1,2,0,0,0,2,2,0,1,0,2,0,0,2,2,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,2, +0,1,2,0,0,0,0,2,2,1,0,1,0,1,0,2,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,2,0,0,2,2,0,0,0,0,1,0,0,0,0,0,0,2, +0,2,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0, +0,2,2,2,2,0,0,0,3,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,1, +0,0,2,0,0,0,0,1,2,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,2,2,2,0,0,0,2,0,0,0,0,0,0,0,0,2, +0,0,1,0,0,0,0,2,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,3,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,2, +0,0,2,0,0,0,0,2,2,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,0,2,2,1,0,0,0,0,0,0,2,0,0,2,0,2,2,2,0,0,0,0,0,0,2,0,0,0,0,2, +0,0,2,0,0,2,0,2,2,0,0,0,0,2,0,2,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0, +0,0,3,0,0,0,2,2,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0, +0,2,2,2,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1, +0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,2,0,0,0,2,0,0,0,0,0,1,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,2,0,0,0, +0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,2,0,2,0,0,0, +0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +) + +Latin7GreekModel = { + 'char_to_order_map': Latin7_char_to_order_map, + 'precedence_matrix': GreekLangModel, + 'typical_positive_ratio': 0.982851, + 'keep_english_letter': False, + 'charset_name': "ISO-8859-7", + 'language': 'Greek', +} + +Win1253GreekModel = { + 'char_to_order_map': win1253_char_to_order_map, + 'precedence_matrix': GreekLangModel, + 'typical_positive_ratio': 0.982851, + 'keep_english_letter': False, + 'charset_name': "windows-1253", + 'language': 'Greek', +} diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langhebrewmodel.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langhebrewmodel.py new file mode 100644 index 0000000..58f4c87 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langhebrewmodel.py @@ -0,0 +1,200 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Simon Montagu +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Shoshannah Forbes - original C code (?) +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Windows-1255 language model +# Character Mapping Table: +WIN1255_CHAR_TO_ORDER_MAP = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 69, 91, 79, 80, 92, 89, 97, 90, 68,111,112, 82, 73, 95, 85, # 40 + 78,121, 86, 71, 67,102,107, 84,114,103,115,253,253,253,253,253, # 50 +253, 50, 74, 60, 61, 42, 76, 70, 64, 53,105, 93, 56, 65, 54, 49, # 60 + 66,110, 51, 43, 44, 63, 81, 77, 98, 75,108,253,253,253,253,253, # 70 +124,202,203,204,205, 40, 58,206,207,208,209,210,211,212,213,214, +215, 83, 52, 47, 46, 72, 32, 94,216,113,217,109,218,219,220,221, + 34,116,222,118,100,223,224,117,119,104,125,225,226, 87, 99,227, +106,122,123,228, 55,229,230,101,231,232,120,233, 48, 39, 57,234, + 30, 59, 41, 88, 33, 37, 36, 31, 29, 35,235, 62, 28,236,126,237, +238, 38, 45,239,240,241,242,243,127,244,245,246,247,248,249,250, + 9, 8, 20, 16, 3, 2, 24, 14, 22, 1, 25, 15, 4, 11, 6, 23, + 12, 19, 13, 26, 18, 27, 21, 17, 7, 10, 5,251,252,128, 96,253, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 98.4004% +# first 1024 sequences: 1.5981% +# rest sequences: 0.087% +# negative sequences: 0.0015% +HEBREW_LANG_MODEL = ( +0,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,2,1,2,0,1,0,0, +3,0,3,1,0,0,1,3,2,0,1,1,2,0,2,2,2,1,1,1,1,2,1,1,1,2,0,0,2,2,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2, +1,2,1,2,1,2,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2, +1,2,1,3,1,1,0,0,2,0,0,0,1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,1,2,2,1,3, +1,2,1,1,2,2,0,0,2,2,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,3,2, +1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,2,2,3,2,2,2,1,2,2,2,2, +1,2,1,1,2,2,0,1,2,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,0,2,2,2,2,2, +0,2,0,2,2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,0,2,2,2, +0,2,1,2,2,2,0,0,2,1,0,0,0,0,1,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1,2,3,2,2,2, +1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,2,0,2, +0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,2,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,2,2,3,2,1,2,1,1,1, +0,1,1,1,1,1,3,0,1,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0,0,0, +0,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,2,1,2,3,3,2,3,3,3,3,2,3,2,1,2,0,2,1,2, +0,2,0,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,1,2,2,3,3,2,3,2,3,2,2,3,1,2,2,0,2,2,2, +0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,2,3,3,3,3,1,3,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,2,3,2,2,2,1,2,2,0,2,2,2,2, +0,2,0,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,1,3,2,3,3,2,3,3,2,2,1,2,2,2,2,2,2, +0,2,1,2,1,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,2,3,3,2,3,3,3,3,2,3,2,3,3,3,3,3,2,2,2,2,2,2,2,1, +0,2,0,1,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,1,2,3,3,3,3,3,3,3,2,3,2,3,2,1,2,3,0,2,1,2,2, +0,2,1,1,2,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,2,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,3,2,1,3,1,2,2,2,1,2,3,3,1,2,1,2,2,2,2, +0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,0,2,3,3,3,1,3,3,3,1,2,2,2,2,1,1,2,2,2,2,2,2, +0,2,0,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,2,2,3,3,3,2,1,2,3,2,3,2,2,2,2,1,2,1,1,1,2,2, +0,2,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,0,0,0,0,0, +1,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,3,2,3,1,2,2,2,2,3,2,3,1,1,2,2,1,2,2,1,1,0,2,2,2,2, +0,1,0,1,2,2,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,0,0,1,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,0,1,0,1,1,0,1,1,0,0,0,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +3,2,2,1,2,2,2,2,2,2,2,1,2,2,1,2,2,1,1,1,1,1,1,1,1,2,1,1,0,3,3,3, +0,3,0,2,2,2,2,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,1,1,2,0,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0, +0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,0,2,1,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,3,1,1,2,2,2,2,2,1,2,2,2,1,1,2,2,2,2,2,2,2,1,2,2,1,0,1,1,1,1,0, +0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,1,1,1,1,2,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, +0,0,2,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,0,0, +2,1,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,2,1,2,1,1,1,1,0,0,0,0, +0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,1,2,1,1,2,1,1,1,2,1,2,1,2,0,1,0,1, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,1,2,2,2,1,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,2,1,2,1,1,0,1,0,1, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,1,1,1,1,1,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,1,1,1,0,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0, +0,1,1,1,2,1,2,2,2,0,2,0,2,0,1,1,2,1,1,1,1,2,1,0,1,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,1,0,0,0,0,0,1,0,1,2,2,0,1,0,0,1,1,2,2,1,2,0,2,0,0,0,1,2,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,2,1,2,0,2,0,0,1,1,1,1,1,1,0,1,0,0,0,1,0,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,1,2,2,0,0,1,0,0,0,1,0,0,1, +1,1,2,1,0,1,1,1,0,1,0,1,1,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,2,1, +0,2,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,0,0,1,0,1,1,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,1,0,0,0,1,1,0,1, +2,0,1,0,1,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,0,1,1,2,1,1,2,0,1,0,0,0,1,1,0,1, +1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,0,0,2,1,1,2,0,2,0,0,0,1,1,0,1, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,2,2,1,2,1,1,0,1,0,0,0,1,1,0,1, +2,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,1,0,1, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,2,1,1,1,0,2,1,1,0,0,0,2,1,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,0,2,1,1,0,1,0,0,0,1,1,0,1, +2,2,1,1,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,0,1,2,1,0,2,0,0,0,1,1,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0, +0,1,0,0,2,0,2,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,1,0,1,0,0,1,0,0,0,1,0,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,1,0,1,1,0,0,1,0,0,2,1,1,1,1,1,0,1,0,0,0,0,1,0,1, +0,1,1,1,2,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,1,1,1,0,1,0,0,0,1,1,0,0, +) + +Win1255HebrewModel = { + 'char_to_order_map': WIN1255_CHAR_TO_ORDER_MAP, + 'precedence_matrix': HEBREW_LANG_MODEL, + 'typical_positive_ratio': 0.984004, + 'keep_english_letter': False, + 'charset_name': "windows-1255", + 'language': 'Hebrew', +} diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langhungarianmodel.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langhungarianmodel.py new file mode 100644 index 0000000..bb7c095 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langhungarianmodel.py @@ -0,0 +1,225 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +Latin2_HungarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, + 46, 71, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, +253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, + 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, +159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174, +175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190, +191,192,193,194,195,196,197, 75,198,199,200,201,202,203,204,205, + 79,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, +221, 51, 81,222, 78,223,224,225,226, 44,227,228,229, 61,230,231, +232,233,234, 58,235, 66, 59,236,237,238, 60, 69, 63,239,240,241, + 82, 14, 74,242, 70, 80,243, 72,244, 15, 83, 77, 84, 30, 76, 85, +245,246,247, 25, 73, 42, 24,248,249,250, 31, 56, 29,251,252,253, +) + +win1250HungarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, + 46, 72, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, +253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, + 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, +161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176, +177,178,179,180, 78,181, 69,182,183,184,185,186,187,188,189,190, +191,192,193,194,195,196,197, 76,198,199,200,201,202,203,204,205, + 81,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, +221, 51, 83,222, 80,223,224,225,226, 44,227,228,229, 61,230,231, +232,233,234, 58,235, 66, 59,236,237,238, 60, 70, 63,239,240,241, + 84, 14, 75,242, 71, 82,243, 73,244, 15, 85, 79, 86, 30, 77, 87, +245,246,247, 25, 74, 42, 24,248,249,250, 31, 56, 29,251,252,253, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 94.7368% +# first 1024 sequences:5.2623% +# rest sequences: 0.8894% +# negative sequences: 0.0009% +HungarianLangModel = ( +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,2,3,3,1,1,2,2,2,2,2,1,2, +3,2,2,3,3,3,3,3,2,3,3,3,3,3,3,1,2,3,3,3,3,2,3,3,1,1,3,3,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0, +3,2,1,3,3,3,3,3,2,3,3,3,3,3,1,1,2,3,3,3,3,3,3,3,1,1,3,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,1,1,2,3,3,3,1,3,3,3,3,3,1,3,3,2,2,0,3,2,3, +0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,3,3,2,3,3,2,2,3,2,3,2,0,3,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,3,3,2,3,3,3,1,2,3,2,2,3,1,2,3,3,2,2,0,3,3,3, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,2,3,3,3,3,2,3,3,3,3,0,2,3,2, +0,0,0,1,1,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,1,1,1,3,3,2,1,3,2,2,3,2,1,3,2,2,1,0,3,3,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,2,2,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,3,2,2,3,1,1,3,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,1,3,3,3,3,3,2,2,1,3,3,3,0,1,1,2, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,2,0,3,2,3, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,1,3,2,2,2,3,1,1,3,3,1,1,0,3,3,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,2,3,3,3,3,3,1,2,3,2,2,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,1,3,3,2,2,1,3,3,3,1,1,3,1,2,3,2,3,2,2,2,1,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,2,2,3,2,1,0,3,2,0,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,1,0,3,3,3,3,0,2,3,0,0,2,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,2,2,2,2,3,3,0,1,2,3,2,3,2,2,3,2,1,2,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,3,3,3,3,3,1,2,3,3,3,2,1,2,3,3,2,2,2,3,2,3,3,1,3,3,1,1,0,2,3,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,1,2,2,2,2,3,3,3,1,1,1,3,3,1,1,3,1,1,3,2,1,2,3,1,1,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,1,2,1,1,3,3,1,1,1,1,3,3,1,1,2,2,1,2,1,1,2,2,1,1,0,2,2,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,1,1,2,1,1,3,3,1,0,1,1,3,3,2,0,1,1,2,3,1,0,2,2,1,0,0,1,3,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,2,1,3,3,3,3,3,1,2,3,2,3,3,2,1,1,3,2,3,2,1,2,2,0,1,2,1,0,0,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,2,2,2,2,3,1,2,2,1,1,3,3,0,3,2,1,2,3,2,1,3,3,1,1,0,2,1,3, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,2,3,3,3,2,1,1,3,3,1,1,1,2,2,3,2,3,2,2,2,1,0,2,2,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +1,0,0,3,3,3,3,3,0,0,3,3,2,3,0,0,0,2,3,3,1,0,1,2,0,0,1,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,2,3,3,3,3,3,1,2,3,3,2,2,1,1,0,3,3,2,2,1,2,2,1,0,2,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,2,1,3,1,2,3,3,2,2,1,1,2,2,1,1,1,1,3,2,1,1,1,1,2,1,0,1,2,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +2,3,3,1,1,1,1,1,3,3,3,0,1,1,3,3,1,1,1,1,1,2,2,0,3,1,1,2,0,2,1,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,1,0,1,2,1,2,2,0,1,2,3,1,2,0,0,0,2,1,1,1,1,1,2,0,0,1,1,0,0,0,0, +1,2,1,2,2,2,1,2,1,2,0,2,0,2,2,1,1,2,1,1,2,1,1,1,0,1,0,0,0,1,1,0, +1,1,1,2,3,2,3,3,0,1,2,2,3,1,0,1,0,2,1,2,2,0,1,1,0,0,1,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,3,3,2,2,1,0,0,3,2,3,2,0,0,0,1,1,3,0,0,1,1,0,0,2,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,2,2,3,3,1,0,1,3,2,3,1,1,1,0,1,1,1,1,1,3,1,0,0,2,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,1,2,2,2,1,0,1,2,3,3,2,0,0,0,2,1,1,1,2,1,1,1,0,1,1,1,0,0,0, +1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,2,1,1,1,1,1,1,0,1,1,1,0,0,1,1, +3,2,2,1,0,0,1,1,2,2,0,3,0,1,2,1,1,0,0,1,1,1,0,1,1,1,1,0,2,1,1,1, +2,2,1,1,1,2,1,2,1,1,1,1,1,1,1,2,1,1,1,2,3,1,1,1,1,1,1,1,1,1,0,1, +2,3,3,0,1,0,0,0,3,3,1,0,0,1,2,2,1,0,0,0,0,2,0,0,1,1,1,0,2,1,1,1, +2,1,1,1,1,1,1,2,1,1,0,1,1,0,1,1,1,0,1,2,1,1,0,1,1,1,1,1,1,1,0,1, +2,3,3,0,1,0,0,0,2,2,0,0,0,0,1,2,2,0,0,0,0,1,0,0,1,1,0,0,2,0,1,0, +2,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, +3,2,2,0,1,0,1,0,2,3,2,0,0,1,2,2,1,0,0,1,1,1,0,0,2,1,0,1,2,2,1,1, +2,1,1,1,1,1,1,2,1,1,1,1,1,1,0,2,1,0,1,1,0,1,1,1,0,1,1,2,1,1,0,1, +2,2,2,0,0,1,0,0,2,2,1,1,0,0,2,1,1,0,0,0,1,2,0,0,2,1,0,0,2,1,1,1, +2,1,1,1,1,2,1,2,1,1,1,2,2,1,1,2,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1, +1,2,3,0,0,0,1,0,3,2,1,0,0,1,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,2,1, +1,1,0,0,0,1,0,1,1,1,1,1,2,0,0,1,0,0,0,2,0,0,1,1,1,1,1,1,1,1,0,1, +3,0,0,2,1,2,2,1,0,0,2,1,2,2,0,0,0,2,1,1,1,0,1,1,0,0,1,1,2,0,0,0, +1,2,1,2,2,1,1,2,1,2,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,0,0,1, +1,3,2,0,0,0,1,0,2,2,2,0,0,0,2,2,1,0,0,0,0,3,1,1,1,1,0,0,2,1,1,1, +2,1,0,1,1,1,0,1,1,1,1,1,1,1,0,2,1,0,0,1,0,1,1,0,1,1,1,1,1,1,0,1, +2,3,2,0,0,0,1,0,2,2,0,0,0,0,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,1,0, +2,1,1,1,1,2,1,2,1,2,0,1,1,1,0,2,1,1,1,2,1,1,1,1,0,1,1,1,1,1,0,1, +3,1,1,2,2,2,3,2,1,1,2,2,1,1,0,1,0,2,2,1,1,1,1,1,0,0,1,1,0,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,0,0,0,0,0,2,2,0,0,0,0,2,2,1,0,0,0,1,1,0,0,1,2,0,0,2,1,1,1, +2,2,1,1,1,2,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,1,1,0,1,2,1,1,1,0,1, +1,0,0,1,2,3,2,1,0,0,2,0,1,1,0,0,0,1,1,1,1,0,1,1,0,0,1,0,0,0,0,0, +1,2,1,2,1,2,1,1,1,2,0,2,1,1,1,0,1,2,0,0,1,1,1,0,0,0,0,0,0,0,0,0, +2,3,2,0,0,0,0,0,1,1,2,1,0,0,1,1,1,0,0,0,0,2,0,0,1,1,0,0,2,1,1,1, +2,1,1,1,1,1,1,2,1,0,1,1,1,1,0,2,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1, +1,2,2,0,1,1,1,0,2,2,2,0,0,0,3,2,1,0,0,0,1,1,0,0,1,1,0,1,1,1,0,0, +1,1,0,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,0,0,1,1,1,0,1,0,1, +2,1,0,2,1,1,2,2,1,1,2,1,1,1,0,0,0,1,1,0,1,1,1,1,0,0,1,1,1,0,0,0, +1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,1,0, +1,2,3,0,0,0,1,0,2,2,0,0,0,0,2,2,0,0,0,0,0,1,0,0,1,0,0,0,2,0,1,0, +2,1,1,1,1,1,0,2,0,0,0,1,2,1,1,1,1,0,1,2,0,1,0,1,0,1,1,1,0,1,0,1, +2,2,2,0,0,0,1,0,2,1,2,0,0,0,1,1,2,0,0,0,0,1,0,0,1,1,0,0,2,1,0,1, +2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, +1,2,2,0,0,0,1,0,2,2,2,0,0,0,1,1,0,0,0,0,0,1,1,0,2,0,0,1,1,1,0,1, +1,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,0,0,1, +1,0,0,1,0,1,2,1,0,0,1,1,1,2,0,0,0,1,1,0,1,0,1,1,0,0,1,0,0,0,0,0, +0,2,1,2,1,1,1,1,1,2,0,2,0,1,1,0,1,2,1,0,1,1,1,0,0,0,0,0,0,1,0,0, +2,1,1,0,1,2,0,0,1,1,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,2,1,0,1, +2,2,1,1,1,1,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,0,1,0,1,1,1,1,1,0,1, +1,2,2,0,0,0,0,0,1,1,0,0,0,0,2,1,0,0,0,0,0,2,0,0,2,2,0,0,2,0,0,1, +2,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1, +1,1,2,0,0,3,1,0,2,1,1,1,0,0,1,1,1,0,0,0,1,1,0,0,0,1,0,0,1,0,1,0, +1,2,1,0,1,1,1,2,1,1,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,1,0,0,0,1,0,0, +2,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,2,0,0,0, +2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,1,0,1, +2,1,1,1,2,1,1,1,0,1,1,2,1,0,0,0,0,1,1,1,1,0,1,0,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,0,1,1,1,1,1,0,0,1,1,2,1,0,0,0,1,1,0,0,0,1,1,0,0,1,0,1,0,0,0, +1,2,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0, +2,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,1,1,1,2,0,0,1,0,0,1,0,1,0,0,0, +0,1,1,1,1,1,1,1,1,2,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,1,0,0,2,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0, +0,1,1,1,1,1,1,0,1,1,0,1,0,1,1,0,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +0,1,1,1,1,1,0,0,1,1,0,1,0,1,0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +0,0,0,1,0,0,0,0,0,0,1,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,1,1,0,1,0,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +2,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,0,1,0,1,1,1,0,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,1,1,1,1,1,0,1,1,0,1,0,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +) + +Latin2HungarianModel = { + 'char_to_order_map': Latin2_HungarianCharToOrderMap, + 'precedence_matrix': HungarianLangModel, + 'typical_positive_ratio': 0.947368, + 'keep_english_letter': True, + 'charset_name': "ISO-8859-2", + 'language': 'Hungarian', +} + +Win1250HungarianModel = { + 'char_to_order_map': win1250HungarianCharToOrderMap, + 'precedence_matrix': HungarianLangModel, + 'typical_positive_ratio': 0.947368, + 'keep_english_letter': True, + 'charset_name': "windows-1250", + 'language': 'Hungarian', +} diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langthaimodel.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langthaimodel.py new file mode 100644 index 0000000..15f94c2 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langthaimodel.py @@ -0,0 +1,199 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# The following result for thai was collected from a limited sample (1M). + +# Character Mapping Table: +TIS620CharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,182,106,107,100,183,184,185,101, 94,186,187,108,109,110,111, # 40 +188,189,190, 89, 95,112,113,191,192,193,194,253,253,253,253,253, # 50 +253, 64, 72, 73,114, 74,115,116,102, 81,201,117, 90,103, 78, 82, # 60 + 96,202, 91, 79, 84,104,105, 97, 98, 92,203,253,253,253,253,253, # 70 +209,210,211,212,213, 88,214,215,216,217,218,219,220,118,221,222, +223,224, 99, 85, 83,225,226,227,228,229,230,231,232,233,234,235, +236, 5, 30,237, 24,238, 75, 8, 26, 52, 34, 51,119, 47, 58, 57, + 49, 53, 55, 43, 20, 19, 44, 14, 48, 3, 17, 25, 39, 62, 31, 54, + 45, 9, 16, 2, 61, 15,239, 12, 42, 46, 18, 21, 76, 4, 66, 63, + 22, 10, 1, 36, 23, 13, 40, 27, 32, 35, 86,240,241,242,243,244, + 11, 28, 41, 29, 33,245, 50, 37, 6, 7, 67, 77, 38, 93,246,247, + 68, 56, 59, 65, 69, 60, 70, 80, 71, 87,248,249,250,251,252,253, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 92.6386% +# first 1024 sequences:7.3177% +# rest sequences: 1.0230% +# negative sequences: 0.0436% +ThaiLangModel = ( +0,1,3,3,3,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,0,0,3,3,3,0,3,3,3,3, +0,3,3,0,0,0,1,3,0,3,3,2,3,3,0,1,2,3,3,3,3,0,2,0,2,0,0,3,2,1,2,2, +3,0,3,3,2,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,0,3,2,3,0,2,2,2,3, +0,2,3,0,0,0,0,1,0,1,2,3,1,1,3,2,2,0,1,1,0,0,1,0,0,0,0,0,0,0,1,1, +3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,2,3,2,3,3,2,2,2, +3,1,2,3,0,3,3,2,2,1,2,3,3,1,2,0,1,3,0,1,0,0,1,0,0,0,0,0,0,0,1,1, +3,3,2,2,3,3,3,3,1,2,3,3,3,3,3,2,2,2,2,3,3,2,2,3,3,2,2,3,2,3,2,2, +3,3,1,2,3,1,2,2,3,3,1,0,2,1,0,0,3,1,2,1,0,0,1,0,0,0,0,0,0,1,0,1, +3,3,3,3,3,3,2,2,3,3,3,3,2,3,2,2,3,3,2,2,3,2,2,2,2,1,1,3,1,2,1,1, +3,2,1,0,2,1,0,1,0,1,1,0,1,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,3,2,3,2,3,3,2,2,3,2,3,3,2,3,1,1,2,3,2,2,2,3,2,2,2,2,2,1,2,1, +2,2,1,1,3,3,2,1,0,1,2,2,0,1,3,0,0,0,1,1,0,0,0,0,0,2,3,0,0,2,1,1, +3,3,2,3,3,2,0,0,3,3,0,3,3,0,2,2,3,1,2,2,1,1,1,0,2,2,2,0,2,2,1,1, +0,2,1,0,2,0,0,2,0,1,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,2,3,3,2,0,0,3,3,0,2,3,0,2,1,2,2,2,2,1,2,0,0,2,2,2,0,2,2,1,1, +0,2,1,0,2,0,0,2,0,1,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,2,3,2,3,2,0,2,2,1,3,2,1,3,2,1,2,3,2,2,3,0,2,3,2,2,1,2,2,2,2, +1,2,2,0,0,0,0,2,0,1,2,0,1,1,1,0,1,0,3,1,1,0,0,0,0,0,0,0,0,0,1,0, +3,3,2,3,3,2,3,2,2,2,3,2,2,3,2,2,1,2,3,2,2,3,1,3,2,2,2,3,2,2,2,3, +3,2,1,3,0,1,1,1,0,2,1,1,1,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,2,0,0, +1,0,0,3,0,3,3,3,3,3,0,0,3,0,2,2,3,3,3,3,3,0,0,0,1,1,3,0,0,0,0,2, +0,0,1,0,0,0,0,0,0,0,2,3,0,0,0,3,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +2,0,3,3,3,3,0,0,2,3,0,0,3,0,3,3,2,3,3,3,3,3,0,0,3,3,3,0,0,0,3,3, +0,0,3,0,0,0,0,2,0,0,2,1,1,3,0,0,1,0,0,2,3,0,1,0,0,0,0,0,0,0,1,0, +3,3,3,3,2,3,3,3,3,3,3,3,1,2,1,3,3,2,2,1,2,2,2,3,1,1,2,0,2,1,2,1, +2,2,1,0,0,0,1,1,0,1,0,1,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0, +3,0,2,1,2,3,3,3,0,2,0,2,2,0,2,1,3,2,2,1,2,1,0,0,2,2,1,0,2,1,2,2, +0,1,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,3,3,1,1,3,0,2,3,1,1,3,2,1,1,2,0,2,2,3,2,1,1,1,1,1,2, +3,0,0,1,3,1,2,1,2,0,3,0,0,0,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, +3,3,1,1,3,2,3,3,3,1,3,2,1,3,2,1,3,2,2,2,2,1,3,3,1,2,1,3,1,2,3,0, +2,1,1,3,2,2,2,1,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, +3,3,2,3,2,3,3,2,3,2,3,2,3,3,2,1,0,3,2,2,2,1,2,2,2,1,2,2,1,2,1,1, +2,2,2,3,0,1,3,1,1,1,1,0,1,1,0,2,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,3,2,2,1,1,3,2,3,2,3,2,0,3,2,2,1,2,0,2,2,2,1,2,2,2,2,1, +3,2,1,2,2,1,0,2,0,1,0,0,1,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,2,3,1,2,3,3,2,2,3,0,1,1,2,0,3,3,2,2,3,0,1,1,3,0,0,0,0, +3,1,0,3,3,0,2,0,2,1,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,3,2,3,3,0,1,3,1,1,2,1,2,1,1,3,1,1,0,2,3,1,1,1,1,1,1,1,1, +3,1,1,2,2,2,2,1,1,1,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,2,2,1,1,2,1,3,3,2,3,2,2,3,2,2,3,1,2,2,1,2,0,3,2,1,2,2,2,2,2,1, +3,2,1,2,2,2,1,1,1,1,0,0,1,1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,1,3,3,0,2,1,0,3,2,0,0,3,1,0,1,1,0,1,0,0,0,0,0,1, +1,0,0,1,0,3,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,2,2,2,3,0,0,1,3,0,3,2,0,3,2,2,3,3,3,3,3,1,0,2,2,2,0,2,2,1,2, +0,2,3,0,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,0,2,3,1,3,3,2,3,3,0,3,3,0,3,2,2,3,2,3,3,3,0,0,2,2,3,0,1,1,1,3, +0,0,3,0,0,0,2,2,0,1,3,0,1,2,2,2,3,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1, +3,2,3,3,2,0,3,3,2,2,3,1,3,2,1,3,2,0,1,2,2,0,2,3,2,1,0,3,0,0,0,0, +3,0,0,2,3,1,3,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,3,2,2,2,1,2,0,1,3,1,1,3,1,3,0,0,2,1,1,1,1,2,1,1,1,0,2,1,0,1, +1,2,0,0,0,3,1,1,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,3,1,0,0,0,1,0, +3,3,3,3,2,2,2,2,2,1,3,1,1,1,2,0,1,1,2,1,2,1,3,2,0,0,3,1,1,1,1,1, +3,1,0,2,3,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,2,3,0,3,3,0,2,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,3,1,3,0,0,1,2,0,0,2,0,3,3,2,3,3,3,2,3,0,0,2,2,2,0,0,0,2,2, +0,0,1,0,0,0,0,3,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +0,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,1,2,3,1,3,3,0,0,1,0,3,0,0,0,0,0, +0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,1,2,3,1,2,3,1,0,3,0,2,2,1,0,2,1,1,2,0,1,0,0,1,1,1,1,0,1,0,0, +1,0,0,0,0,1,1,0,3,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,0,1,1,1,3,1,2,2,2,2,2,2,1,1,1,1,0,3,1,0,1,3,1,1,1,1, +1,1,0,2,0,1,3,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1, +3,0,2,2,1,3,3,2,3,3,0,1,1,0,2,2,1,2,1,3,3,1,0,0,3,2,0,0,0,0,2,1, +0,1,0,0,0,0,1,2,0,1,1,3,1,1,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,3,0,0,1,0,0,0,3,0,0,3,0,3,1,0,1,1,1,3,2,0,0,0,3,0,0,0,0,2,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,1,3,2,1,3,3,1,2,2,0,1,2,1,0,1,2,0,0,0,0,0,3,0,0,0,3,0,0,0,0, +3,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,2,0,3,3,3,2,2,0,1,1,0,1,3,0,0,0,2,2,0,0,0,0,3,1,0,1,0,0,0, +0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,2,3,1,2,0,0,2,1,0,3,1,0,1,2,0,1,1,1,1,3,0,0,3,1,1,0,2,2,1,1, +0,2,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,3,1,2,0,0,2,2,0,1,2,0,1,0,1,3,1,2,1,0,0,0,2,0,3,0,0,0,1,0, +0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,1,2,2,0,0,0,2,0,2,1,0,1,1,0,1,1,1,2,1,0,0,1,1,1,0,2,1,1,1, +0,1,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1, +0,0,0,2,0,1,3,1,1,1,1,0,0,0,0,3,2,0,1,0,0,0,1,2,0,0,0,1,0,0,0,0, +0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,2,3,2,2,0,0,0,1,0,0,0,0,2,3,2,1,2,2,3,0,0,0,2,3,1,0,0,0,1,1, +0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0, +3,3,2,2,0,1,0,0,0,0,2,0,2,0,1,0,0,0,1,1,0,0,0,2,1,0,1,0,1,1,0,0, +0,1,0,2,0,0,1,0,3,0,1,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,1,0,0,1,0,0,0,0,0,1,1,2,0,0,0,0,1,0,0,1,3,1,0,0,0,0,1,1,0,0, +0,1,0,0,0,0,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0, +3,3,1,1,1,1,2,3,0,0,2,1,1,1,1,1,0,2,1,1,0,0,0,2,1,0,1,2,1,1,0,1, +2,1,0,3,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,3,1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1, +0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,0,0,0,0,1,2,1,0,1,1,0,2,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,2,0,0,0,1,3,0,1,0,0,0,2,0,0,0,0,0,0,0,1,2,0,0,0,0,0, +3,3,0,0,1,1,2,0,0,1,2,1,0,1,1,1,0,1,1,0,0,2,1,1,0,1,0,0,1,1,1,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,1,0,0,0,0,1,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,0,0,1,1,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,0,1,2,0,1,2,0,0,1,1,0,2,0,1,0,0,1,0,0,0,0,1,0,0,0,2,0,0,0,0, +1,0,0,1,0,1,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,0,0,0,0,0,0,0,1,1,0,1,1,0,2,1,3,0,0,0,0,1,1,0,0,0,0,0,0,0,3, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,1,0,0,2,0,0,2,0,0,1,1,2,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0, +1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,3,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0, +1,0,0,0,0,0,0,0,0,1,0,0,0,0,2,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,1,0,0,2,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +) + +TIS620ThaiModel = { + 'char_to_order_map': TIS620CharToOrderMap, + 'precedence_matrix': ThaiLangModel, + 'typical_positive_ratio': 0.926386, + 'keep_english_letter': False, + 'charset_name': "TIS-620", + 'language': 'Thai', +} diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langturkishmodel.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langturkishmodel.py new file mode 100644 index 0000000..a427a45 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langturkishmodel.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Özgür Baskın - Turkish Language Model +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +Latin5_TurkishCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255, 23, 37, 47, 39, 29, 52, 36, 45, 53, 60, 16, 49, 20, 46, 42, + 48, 69, 44, 35, 31, 51, 38, 62, 65, 43, 56,255,255,255,255,255, +255, 1, 21, 28, 12, 2, 18, 27, 25, 3, 24, 10, 5, 13, 4, 15, + 26, 64, 7, 8, 9, 14, 32, 57, 58, 11, 22,255,255,255,255,255, +180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165, +164,163,162,161,160,159,101,158,157,156,155,154,153,152,151,106, +150,149,148,147,146,145,144,100,143,142,141,140,139,138,137,136, + 94, 80, 93,135,105,134,133, 63,132,131,130,129,128,127,126,125, +124,104, 73, 99, 79, 85,123, 54,122, 98, 92,121,120, 91,103,119, + 68,118,117, 97,116,115, 50, 90,114,113,112,111, 55, 41, 40, 86, + 89, 70, 59, 78, 71, 82, 88, 33, 77, 66, 84, 83,110, 75, 61, 96, + 30, 67,109, 74, 87,102, 34, 95, 81,108, 76, 72, 17, 6, 19,107, +) + +TurkishLangModel = ( +3,2,3,3,3,1,3,3,3,3,3,3,3,3,2,1,1,3,3,1,3,3,0,3,3,3,3,3,0,3,1,3, +3,2,1,0,0,1,1,0,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,2,2,0,0,1,0,0,1, +3,2,2,3,3,0,3,3,3,3,3,3,3,2,3,1,0,3,3,1,3,3,0,3,3,3,3,3,0,3,0,3, +3,1,1,0,1,0,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,2,2,0,0,0,1,0,1, +3,3,2,3,3,0,3,3,3,3,3,3,3,2,3,1,1,3,3,0,3,3,1,2,3,3,3,3,0,3,0,3, +3,1,1,0,0,0,1,0,0,0,0,1,1,0,1,2,1,0,0,0,1,0,0,0,0,2,0,0,0,0,0,1, +3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,1,3,3,2,0,3,2,1,2,2,1,3,3,0,0,0,2, +2,2,0,1,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,1,0,0,1, +3,3,3,2,3,3,1,2,3,3,3,3,3,3,3,1,3,2,1,0,3,2,0,1,2,3,3,2,1,0,0,2, +2,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0, +1,0,1,3,3,1,3,3,3,3,3,3,3,1,2,0,0,2,3,0,2,3,0,0,2,2,2,3,0,3,0,1, +2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,0,3,2,0,2,3,2,3,3,1,0,0,2, +3,2,0,0,1,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,0,2,0,0,1, +3,3,3,2,3,3,2,3,3,3,3,2,3,3,3,0,3,3,0,0,2,1,0,0,2,3,2,2,0,0,0,2, +2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,1,0,2,0,0,1, +3,3,3,2,3,3,3,3,3,3,3,2,3,3,3,0,3,2,0,1,3,2,1,1,3,2,3,2,1,0,0,2, +2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, +3,3,3,2,3,3,3,3,3,3,3,2,3,3,3,0,3,2,2,0,2,3,0,0,2,2,2,2,0,0,0,2, +3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,1,0,0,0, +3,3,3,3,3,3,3,2,2,2,2,3,2,3,3,0,3,3,1,1,2,2,0,0,2,2,3,2,0,0,1,3, +0,3,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1, +3,3,3,2,3,3,3,2,1,2,2,3,2,3,3,0,3,2,0,0,1,1,0,1,1,2,1,2,0,0,0,1, +0,3,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0, +3,3,3,2,3,3,2,3,2,2,2,3,3,3,3,1,3,1,1,0,3,2,1,1,3,3,2,3,1,0,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,0,1, +3,2,2,3,3,0,3,3,3,3,3,3,3,2,2,1,0,3,3,1,3,3,0,1,3,3,2,3,0,3,0,3, +2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +2,2,2,3,3,0,3,3,3,3,3,3,3,3,3,0,0,3,2,0,3,3,0,3,2,3,3,3,0,3,1,3, +2,0,0,0,0,0,0,0,0,0,0,1,0,1,2,0,1,0,0,0,0,0,0,0,2,2,0,0,1,0,0,1, +3,3,3,1,2,3,3,1,0,0,1,0,0,3,3,2,3,0,0,2,0,0,2,0,2,0,0,0,2,0,2,0, +0,3,1,0,1,0,0,0,2,2,1,0,1,1,2,1,2,2,2,0,2,1,1,0,0,0,2,0,0,0,0,0, +1,2,1,3,3,0,3,3,3,3,3,2,3,0,0,0,0,2,3,0,2,3,1,0,2,3,1,3,0,3,0,2, +3,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,1,3,3,2,2,3,2,2,0,1,2,3,0,1,2,1,0,1,0,0,0,1,0,2,2,0,0,0,1, +1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0, +3,3,3,1,3,3,1,1,3,3,1,1,3,3,1,0,2,1,2,0,2,1,0,0,1,1,2,1,0,0,0,2, +2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,1,0,2,1,3,0,0,2,0,0,3,3,0,3,0,0,1,0,1,2,0,0,1,1,2,2,0,1,0, +0,1,2,1,1,0,1,0,1,1,1,1,1,0,1,1,1,2,2,1,2,0,1,0,0,0,0,0,0,1,0,0, +3,3,3,2,3,2,3,3,0,2,2,2,3,3,3,0,3,0,0,0,2,2,0,1,2,1,1,1,0,0,0,1, +0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +3,3,3,3,3,3,2,1,2,2,3,3,3,3,2,0,2,0,0,0,2,2,0,0,2,1,3,3,0,0,1,1, +1,1,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0, +1,1,2,3,3,0,3,3,3,3,3,3,2,2,0,2,0,2,3,2,3,2,2,2,2,2,2,2,1,3,2,3, +2,0,2,1,2,2,2,2,1,1,2,2,1,2,2,1,2,0,0,2,1,1,0,2,1,0,0,1,0,0,0,1, +2,3,3,1,1,1,0,1,1,1,2,3,2,1,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0, +0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,2,3,2,2,1,3,3,3,0,2,1,2,0,2,1,0,0,1,1,1,1,1,0,0,1, +2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,2,0,1,0,0,0, +3,3,3,2,3,3,3,3,3,2,3,1,2,3,3,1,2,0,0,0,0,0,0,0,3,2,1,1,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +3,3,3,2,2,3,3,2,1,1,1,1,1,3,3,0,3,1,0,0,1,1,0,0,3,1,2,1,0,0,0,0, +0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, +3,3,3,2,2,3,2,2,2,3,2,1,1,3,3,0,3,0,0,0,0,1,0,0,3,1,1,2,0,0,0,1, +1,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,1,3,3,0,3,3,3,3,3,2,2,2,1,2,0,2,1,2,2,1,1,0,1,2,2,2,2,2,2,2, +0,0,2,1,2,1,2,1,0,1,1,3,1,2,1,1,2,0,0,2,0,1,0,1,0,1,0,0,0,1,0,1, +3,3,3,1,3,3,3,0,1,1,0,2,2,3,1,0,3,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,2,2,1,0,0,1,0,0,3,3,1,3,0,0,1,1,0,2,0,3,0,0,0,2,0,1,1, +0,1,2,0,1,2,2,0,2,2,2,2,1,0,2,1,1,0,2,0,2,1,2,0,0,0,0,0,0,0,0,0, +3,3,3,1,3,2,3,2,0,2,2,2,1,3,2,0,2,1,2,0,1,2,0,0,1,0,2,2,0,0,0,2, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0, +3,3,3,0,3,3,1,1,2,3,1,0,3,2,3,0,3,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0, +1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,3,3,0,3,3,2,3,3,2,2,0,0,0,0,1,2,0,1,3,0,0,0,3,1,1,0,3,0,2, +2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,1,2,2,1,0,3,1,1,1,1,3,3,2,3,0,0,1,0,1,2,0,2,2,0,2,2,0,2,1, +0,2,2,1,1,1,1,0,2,1,1,0,1,1,1,1,2,1,2,1,2,0,1,0,1,0,0,0,0,0,0,0, +3,3,3,0,1,1,3,0,0,1,1,0,0,2,2,0,3,0,0,1,1,0,1,0,0,0,0,0,2,0,0,0, +0,3,1,0,1,0,1,0,2,0,0,1,0,1,0,1,1,1,2,1,1,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,0,2,0,2,0,1,1,1,0,0,3,3,0,2,0,0,1,0,0,2,1,1,0,1,0,1,0,1,0, +0,2,0,1,2,0,2,0,2,1,1,0,1,0,2,1,1,0,2,1,1,0,1,0,0,0,1,1,0,0,0,0, +3,2,3,0,1,0,0,0,0,0,0,0,0,1,2,0,1,0,0,1,0,0,1,0,0,0,0,0,2,0,0,0, +0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,2,1,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,0,0,2,3,0,0,1,0,1,0,2,3,2,3,0,0,1,3,0,2,1,0,0,0,0,2,0,1,0, +0,2,1,0,0,1,1,0,2,1,0,0,1,0,0,1,1,0,1,1,2,0,1,0,0,0,0,1,0,0,0,0, +3,2,2,0,0,1,1,0,0,0,0,0,0,3,1,1,1,0,0,0,0,0,1,0,0,0,0,0,2,0,1,0, +0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,3,3,0,2,3,2,2,1,2,2,1,1,2,0,1,3,2,2,2,0,0,2,2,0,0,0,1,2,1, +3,0,2,1,1,0,1,1,1,0,1,2,2,2,1,1,2,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0, +0,1,1,2,3,0,3,3,3,2,2,2,2,1,0,1,0,1,0,1,2,2,0,0,2,2,1,3,1,1,2,1, +0,0,1,1,2,0,1,1,0,0,1,2,0,2,1,1,2,0,0,1,0,0,0,1,0,1,0,1,0,0,0,0, +3,3,2,0,0,3,1,0,0,0,0,0,0,3,2,1,2,0,0,1,0,0,2,0,0,0,0,0,2,0,1,0, +0,2,1,1,0,0,1,0,1,2,0,0,1,1,0,0,2,1,1,1,1,0,2,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,1,0,0,0,0,1,0,0,3,3,2,2,0,0,1,0,0,2,0,1,0,0,0,2,0,1,0, +0,0,1,1,0,0,2,0,2,1,0,0,1,1,2,1,2,0,2,1,2,1,1,1,0,0,1,1,0,0,0,0, +3,3,2,0,0,2,2,0,0,0,1,1,0,2,2,1,3,1,0,1,0,1,2,0,0,0,0,0,1,0,1,0, +0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,0,0,0,1,0,0,1,0,0,2,3,1,2,0,0,1,0,0,2,0,0,0,1,0,2,0,2,0, +0,1,1,2,2,1,2,0,2,1,1,0,0,1,1,0,1,1,1,1,2,1,1,0,0,0,0,0,0,0,0,0, +3,3,3,0,2,1,2,1,0,0,1,1,0,3,3,1,2,0,0,1,0,0,2,0,2,0,1,1,2,0,0,0, +0,0,1,1,1,1,2,0,1,1,0,1,1,1,1,0,0,0,1,1,1,0,1,0,0,0,1,0,0,0,0,0, +3,3,3,0,2,2,3,2,0,0,1,0,0,2,3,1,0,0,0,0,0,0,2,0,2,0,0,0,2,0,0,0, +0,1,1,0,0,0,1,0,0,1,0,1,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,0,0,0,0,0,0,0,1,0,0,2,2,2,2,0,0,1,0,0,2,0,0,0,0,0,2,0,1,0, +0,0,2,1,1,0,1,0,2,1,1,0,0,1,1,2,1,0,2,0,2,0,1,0,0,0,2,0,0,0,0,0, +0,0,0,2,2,0,2,1,1,1,1,2,2,0,0,1,0,1,0,0,1,3,0,0,0,0,1,0,0,2,1,0, +0,0,1,0,1,0,0,0,0,0,2,1,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +2,0,0,2,3,0,2,3,1,2,2,0,2,0,0,2,0,2,1,1,1,2,1,0,0,1,2,1,1,2,1,0, +1,0,2,0,1,0,1,1,0,0,2,2,1,2,1,1,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,0,2,1,2,0,0,0,1,0,0,3,2,0,1,0,0,1,0,0,2,0,0,0,1,2,1,0,1,0, +0,0,0,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,2,2,0,2,2,1,1,0,1,1,1,1,1,0,0,1,2,1,1,1,0,1,0,0,0,1,1,1,1, +0,0,2,1,0,1,1,1,0,1,1,2,1,2,1,1,2,0,1,1,2,1,0,2,0,0,0,0,0,0,0,0, +3,2,2,0,0,2,0,0,0,0,0,0,0,2,2,0,2,0,0,1,0,0,2,0,0,0,0,0,2,0,0,0, +0,2,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,3,2,0,2,2,0,1,1,0,1,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0, +2,0,1,0,1,0,1,1,0,0,1,2,0,1,0,1,1,0,0,1,0,1,0,2,0,0,0,0,0,0,0,0, +2,2,2,0,1,1,0,0,0,1,0,0,0,1,2,0,1,0,0,1,0,0,1,0,0,0,0,1,2,0,1,0, +0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,1,0,1,1,1,0,0,0,0,1,2,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +1,1,2,0,1,0,0,0,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,1, +0,0,1,2,2,0,2,1,2,1,1,2,2,0,0,0,0,1,0,0,1,1,0,0,2,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +2,2,2,0,0,0,1,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,0,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +) + +Latin5TurkishModel = { + 'char_to_order_map': Latin5_TurkishCharToOrderMap, + 'precedence_matrix': TurkishLangModel, + 'typical_positive_ratio': 0.970290, + 'keep_english_letter': True, + 'charset_name': "ISO-8859-9", + 'language': 'Turkish', +} diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/latin1prober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/latin1prober.py new file mode 100644 index 0000000..7d1e8c2 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/latin1prober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +FREQ_CAT_NUM = 4 + +UDF = 0 # undefined +OTH = 1 # other +ASC = 2 # ascii capital letter +ASS = 3 # ascii small letter +ACV = 4 # accent capital vowel +ACO = 5 # accent capital other +ASV = 6 # accent small vowel +ASO = 7 # accent small other +CLASS_NUM = 8 # total classes + +Latin1_CharToClass = ( + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 00 - 07 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 08 - 0F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 10 - 17 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 18 - 1F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 20 - 27 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 28 - 2F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 30 - 37 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 38 - 3F + OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 40 - 47 + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 48 - 4F + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 50 - 57 + ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, # 58 - 5F + OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 60 - 67 + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 68 - 6F + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 70 - 77 + ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, # 78 - 7F + OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, # 80 - 87 + OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, # 88 - 8F + UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 90 - 97 + OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, # 98 - 9F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A0 - A7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A8 - AF + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B0 - B7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B8 - BF + ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, # C0 - C7 + ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, # C8 - CF + ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, # D0 - D7 + ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, # D8 - DF + ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, # E0 - E7 + ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, # E8 - EF + ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, # F0 - F7 + ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, # F8 - FF +) + +# 0 : illegal +# 1 : very unlikely +# 2 : normal +# 3 : very likely +Latin1ClassModel = ( +# UDF OTH ASC ASS ACV ACO ASV ASO + 0, 0, 0, 0, 0, 0, 0, 0, # UDF + 0, 3, 3, 3, 3, 3, 3, 3, # OTH + 0, 3, 3, 3, 3, 3, 3, 3, # ASC + 0, 3, 3, 3, 1, 1, 3, 3, # ASS + 0, 3, 3, 3, 1, 2, 1, 2, # ACV + 0, 3, 3, 3, 3, 3, 3, 3, # ACO + 0, 3, 1, 3, 1, 1, 1, 3, # ASV + 0, 3, 1, 3, 1, 1, 3, 3, # ASO +) + + +class Latin1Prober(CharSetProber): + def __init__(self): + super(Latin1Prober, self).__init__() + self._last_char_class = None + self._freq_counter = None + self.reset() + + def reset(self): + self._last_char_class = OTH + self._freq_counter = [0] * FREQ_CAT_NUM + CharSetProber.reset(self) + + @property + def charset_name(self): + return "ISO-8859-1" + + @property + def language(self): + return "" + + def feed(self, byte_str): + byte_str = self.filter_with_english_letters(byte_str) + for c in byte_str: + char_class = Latin1_CharToClass[c] + freq = Latin1ClassModel[(self._last_char_class * CLASS_NUM) + + char_class] + if freq == 0: + self._state = ProbingState.NOT_ME + break + self._freq_counter[freq] += 1 + self._last_char_class = char_class + + return self.state + + def get_confidence(self): + if self.state == ProbingState.NOT_ME: + return 0.01 + + total = sum(self._freq_counter) + if total < 0.01: + confidence = 0.0 + else: + confidence = ((self._freq_counter[3] - self._freq_counter[1] * 20.0) + / total) + if confidence < 0.0: + confidence = 0.0 + # lower the confidence of latin1 so that other more accurate + # detector can take priority. + confidence = confidence * 0.73 + return confidence diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcharsetprober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcharsetprober.py new file mode 100644 index 0000000..6256ecf --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcharsetprober.py @@ -0,0 +1,91 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState + + +class MultiByteCharSetProber(CharSetProber): + """ + MultiByteCharSetProber + """ + + def __init__(self, lang_filter=None): + super(MultiByteCharSetProber, self).__init__(lang_filter=lang_filter) + self.distribution_analyzer = None + self.coding_sm = None + self._last_char = [0, 0] + + def reset(self): + super(MultiByteCharSetProber, self).reset() + if self.coding_sm: + self.coding_sm.reset() + if self.distribution_analyzer: + self.distribution_analyzer.reset() + self._last_char = [0, 0] + + @property + def charset_name(self): + raise NotImplementedError + + @property + def language(self): + raise NotImplementedError + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.distribution_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + return self.distribution_analyzer.get_confidence() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcsgroupprober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcsgroupprober.py new file mode 100644 index 0000000..530abe7 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcsgroupprober.py @@ -0,0 +1,54 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .utf8prober import UTF8Prober +from .sjisprober import SJISProber +from .eucjpprober import EUCJPProber +from .gb2312prober import GB2312Prober +from .euckrprober import EUCKRProber +from .cp949prober import CP949Prober +from .big5prober import Big5Prober +from .euctwprober import EUCTWProber + + +class MBCSGroupProber(CharSetGroupProber): + def __init__(self, lang_filter=None): + super(MBCSGroupProber, self).__init__(lang_filter=lang_filter) + self.probers = [ + UTF8Prober(), + SJISProber(), + EUCJPProber(), + GB2312Prober(), + EUCKRProber(), + CP949Prober(), + Big5Prober(), + EUCTWProber() + ] + self.reset() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcssm.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcssm.py new file mode 100644 index 0000000..8360d0f --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcssm.py @@ -0,0 +1,572 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +# BIG5 + +BIG5_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 4,4,4,4,4,4,4,4, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 4,3,3,3,3,3,3,3, # a0 - a7 + 3,3,3,3,3,3,3,3, # a8 - af + 3,3,3,3,3,3,3,3, # b0 - b7 + 3,3,3,3,3,3,3,3, # b8 - bf + 3,3,3,3,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +BIG5_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,#08-0f + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START#10-17 +) + +BIG5_CHAR_LEN_TABLE = (0, 1, 1, 2, 0) + +BIG5_SM_MODEL = {'class_table': BIG5_CLS, + 'class_factor': 5, + 'state_table': BIG5_ST, + 'char_len_table': BIG5_CHAR_LEN_TABLE, + 'name': 'Big5'} + +# CP949 + +CP949_CLS = ( + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0, # 00 - 0f + 1,1,1,1,1,1,1,1, 1,1,1,0,1,1,1,1, # 10 - 1f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 20 - 2f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 30 - 3f + 1,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4, # 40 - 4f + 4,4,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 50 - 5f + 1,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5, # 60 - 6f + 5,5,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 70 - 7f + 0,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 80 - 8f + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 90 - 9f + 6,7,7,7,7,7,7,7, 7,7,7,7,7,8,8,8, # a0 - af + 7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7, # b0 - bf + 7,7,7,7,7,7,9,2, 2,3,2,2,2,2,2,2, # c0 - cf + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # d0 - df + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # e0 - ef + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,0, # f0 - ff +) + +CP949_ST = ( +#cls= 0 1 2 3 4 5 6 7 8 9 # previous state = + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START, 4, 5,MachineState.ERROR, 6, # MachineState.START + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, # MachineState.ERROR + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME, # MachineState.ITS_ME + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 3 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 4 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 5 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 6 +) + +CP949_CHAR_LEN_TABLE = (0, 1, 2, 0, 1, 1, 2, 2, 0, 2) + +CP949_SM_MODEL = {'class_table': CP949_CLS, + 'class_factor': 10, + 'state_table': CP949_ST, + 'char_len_table': CP949_CHAR_LEN_TABLE, + 'name': 'CP949'} + +# EUC-JP + +EUCJP_CLS = ( + 4,4,4,4,4,4,4,4, # 00 - 07 + 4,4,4,4,4,4,5,5, # 08 - 0f + 4,4,4,4,4,4,4,4, # 10 - 17 + 4,4,4,5,4,4,4,4, # 18 - 1f + 4,4,4,4,4,4,4,4, # 20 - 27 + 4,4,4,4,4,4,4,4, # 28 - 2f + 4,4,4,4,4,4,4,4, # 30 - 37 + 4,4,4,4,4,4,4,4, # 38 - 3f + 4,4,4,4,4,4,4,4, # 40 - 47 + 4,4,4,4,4,4,4,4, # 48 - 4f + 4,4,4,4,4,4,4,4, # 50 - 57 + 4,4,4,4,4,4,4,4, # 58 - 5f + 4,4,4,4,4,4,4,4, # 60 - 67 + 4,4,4,4,4,4,4,4, # 68 - 6f + 4,4,4,4,4,4,4,4, # 70 - 77 + 4,4,4,4,4,4,4,4, # 78 - 7f + 5,5,5,5,5,5,5,5, # 80 - 87 + 5,5,5,5,5,5,1,3, # 88 - 8f + 5,5,5,5,5,5,5,5, # 90 - 97 + 5,5,5,5,5,5,5,5, # 98 - 9f + 5,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,0,5 # f8 - ff +) + +EUCJP_ST = ( + 3, 4, 3, 5,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 3,MachineState.ERROR,#18-1f + 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START#20-27 +) + +EUCJP_CHAR_LEN_TABLE = (2, 2, 2, 3, 1, 0) + +EUCJP_SM_MODEL = {'class_table': EUCJP_CLS, + 'class_factor': 6, + 'state_table': EUCJP_ST, + 'char_len_table': EUCJP_CHAR_LEN_TABLE, + 'name': 'EUC-JP'} + +# EUC-KR + +EUCKR_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,3,3,3, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,3,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 2,2,2,2,2,2,2,2, # e0 - e7 + 2,2,2,2,2,2,2,2, # e8 - ef + 2,2,2,2,2,2,2,2, # f0 - f7 + 2,2,2,2,2,2,2,0 # f8 - ff +) + +EUCKR_ST = ( + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #08-0f +) + +EUCKR_CHAR_LEN_TABLE = (0, 1, 2, 0) + +EUCKR_SM_MODEL = {'class_table': EUCKR_CLS, + 'class_factor': 4, + 'state_table': EUCKR_ST, + 'char_len_table': EUCKR_CHAR_LEN_TABLE, + 'name': 'EUC-KR'} + +# EUC-TW + +EUCTW_CLS = ( + 2,2,2,2,2,2,2,2, # 00 - 07 + 2,2,2,2,2,2,0,0, # 08 - 0f + 2,2,2,2,2,2,2,2, # 10 - 17 + 2,2,2,0,2,2,2,2, # 18 - 1f + 2,2,2,2,2,2,2,2, # 20 - 27 + 2,2,2,2,2,2,2,2, # 28 - 2f + 2,2,2,2,2,2,2,2, # 30 - 37 + 2,2,2,2,2,2,2,2, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,2, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,6,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,3,4,4,4,4,4,4, # a0 - a7 + 5,5,1,1,1,1,1,1, # a8 - af + 1,1,1,1,1,1,1,1, # b0 - b7 + 1,1,1,1,1,1,1,1, # b8 - bf + 1,1,3,1,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +EUCTW_ST = ( + MachineState.ERROR,MachineState.ERROR,MachineState.START, 3, 3, 3, 4,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.ERROR,#10-17 + MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,#20-27 + MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +EUCTW_CHAR_LEN_TABLE = (0, 0, 1, 2, 2, 2, 3) + +EUCTW_SM_MODEL = {'class_table': EUCTW_CLS, + 'class_factor': 7, + 'state_table': EUCTW_ST, + 'char_len_table': EUCTW_CHAR_LEN_TABLE, + 'name': 'x-euc-tw'} + +# GB2312 + +GB2312_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 3,3,3,3,3,3,3,3, # 30 - 37 + 3,3,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,4, # 78 - 7f + 5,6,6,6,6,6,6,6, # 80 - 87 + 6,6,6,6,6,6,6,6, # 88 - 8f + 6,6,6,6,6,6,6,6, # 90 - 97 + 6,6,6,6,6,6,6,6, # 98 - 9f + 6,6,6,6,6,6,6,6, # a0 - a7 + 6,6,6,6,6,6,6,6, # a8 - af + 6,6,6,6,6,6,6,6, # b0 - b7 + 6,6,6,6,6,6,6,6, # b8 - bf + 6,6,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 6,6,6,6,6,6,6,6, # e0 - e7 + 6,6,6,6,6,6,6,6, # e8 - ef + 6,6,6,6,6,6,6,6, # f0 - f7 + 6,6,6,6,6,6,6,0 # f8 - ff +) + +GB2312_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, 3,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,#10-17 + 4,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#20-27 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +# To be accurate, the length of class 6 can be either 2 or 4. +# But it is not necessary to discriminate between the two since +# it is used for frequency analysis only, and we are validating +# each code range there as well. So it is safe to set it to be +# 2 here. +GB2312_CHAR_LEN_TABLE = (0, 1, 1, 1, 1, 1, 2) + +GB2312_SM_MODEL = {'class_table': GB2312_CLS, + 'class_factor': 7, + 'state_table': GB2312_ST, + 'char_len_table': GB2312_CHAR_LEN_TABLE, + 'name': 'GB2312'} + +# Shift_JIS + +SJIS_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 3,3,3,3,3,2,2,3, # 80 - 87 + 3,3,3,3,3,3,3,3, # 88 - 8f + 3,3,3,3,3,3,3,3, # 90 - 97 + 3,3,3,3,3,3,3,3, # 98 - 9f + #0xa0 is illegal in sjis encoding, but some pages does + #contain such byte. We need to be more error forgiven. + 2,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,4,4,4, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,0,0,0) # f8 - ff + + +SJIS_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START #10-17 +) + +SJIS_CHAR_LEN_TABLE = (0, 1, 1, 2, 0, 0) + +SJIS_SM_MODEL = {'class_table': SJIS_CLS, + 'class_factor': 6, + 'state_table': SJIS_ST, + 'char_len_table': SJIS_CHAR_LEN_TABLE, + 'name': 'Shift_JIS'} + +# UCS2-BE + +UCS2BE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2BE_ST = ( + 5, 7, 7,MachineState.ERROR, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,#10-17 + 6, 6, 6, 6, 6,MachineState.ITS_ME, 6, 6,#18-1f + 6, 6, 6, 6, 5, 7, 7,MachineState.ERROR,#20-27 + 5, 8, 6, 6,MachineState.ERROR, 6, 6, 6,#28-2f + 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2BE_CHAR_LEN_TABLE = (2, 2, 2, 0, 2, 2) + +UCS2BE_SM_MODEL = {'class_table': UCS2BE_CLS, + 'class_factor': 6, + 'state_table': UCS2BE_ST, + 'char_len_table': UCS2BE_CHAR_LEN_TABLE, + 'name': 'UTF-16BE'} + +# UCS2-LE + +UCS2LE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2LE_ST = ( + 6, 6, 7, 6, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 5, 5, 5,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#10-17 + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR, 6, 6,#18-1f + 7, 6, 8, 8, 5, 5, 5,MachineState.ERROR,#20-27 + 5, 5, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5,#28-2f + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2LE_CHAR_LEN_TABLE = (2, 2, 2, 2, 2, 2) + +UCS2LE_SM_MODEL = {'class_table': UCS2LE_CLS, + 'class_factor': 6, + 'state_table': UCS2LE_ST, + 'char_len_table': UCS2LE_CHAR_LEN_TABLE, + 'name': 'UTF-16LE'} + +# UTF-8 + +UTF8_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as a legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 2,2,2,2,3,3,3,3, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 5,5,5,5,5,5,5,5, # a0 - a7 + 5,5,5,5,5,5,5,5, # a8 - af + 5,5,5,5,5,5,5,5, # b0 - b7 + 5,5,5,5,5,5,5,5, # b8 - bf + 0,0,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 7,8,8,8,8,8,8,8, # e0 - e7 + 8,8,8,8,8,9,8,8, # e8 - ef + 10,11,11,11,11,11,11,11, # f0 - f7 + 12,13,13,13,14,15,0,0 # f8 - ff +) + +UTF8_ST = ( + MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12, 10,#00-07 + 9, 11, 8, 7, 6, 5, 4, 3,#08-0f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#20-27 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#28-2f + MachineState.ERROR,MachineState.ERROR, 5, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#30-37 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#38-3f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#40-47 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#48-4f + MachineState.ERROR,MachineState.ERROR, 7, 7, 7, 7,MachineState.ERROR,MachineState.ERROR,#50-57 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#58-5f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 7, 7,MachineState.ERROR,MachineState.ERROR,#60-67 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#68-6f + MachineState.ERROR,MachineState.ERROR, 9, 9, 9, 9,MachineState.ERROR,MachineState.ERROR,#70-77 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#78-7f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 9,MachineState.ERROR,MachineState.ERROR,#80-87 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#88-8f + MachineState.ERROR,MachineState.ERROR, 12, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,#90-97 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#98-9f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12,MachineState.ERROR,MachineState.ERROR,#a0-a7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#a8-af + MachineState.ERROR,MachineState.ERROR, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b0-b7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b8-bf + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,#c0-c7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR #c8-cf +) + +UTF8_CHAR_LEN_TABLE = (0, 1, 0, 0, 0, 0, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6) + +UTF8_SM_MODEL = {'class_table': UTF8_CLS, + 'class_factor': 16, + 'state_table': UTF8_ST, + 'char_len_table': UTF8_CHAR_LEN_TABLE, + 'name': 'UTF-8'} diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sbcharsetprober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sbcharsetprober.py new file mode 100644 index 0000000..0adb51d --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sbcharsetprober.py @@ -0,0 +1,132 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import CharacterCategory, ProbingState, SequenceLikelihood + + +class SingleByteCharSetProber(CharSetProber): + SAMPLE_SIZE = 64 + SB_ENOUGH_REL_THRESHOLD = 1024 # 0.25 * SAMPLE_SIZE^2 + POSITIVE_SHORTCUT_THRESHOLD = 0.95 + NEGATIVE_SHORTCUT_THRESHOLD = 0.05 + + def __init__(self, model, reversed=False, name_prober=None): + super(SingleByteCharSetProber, self).__init__() + self._model = model + # TRUE if we need to reverse every pair in the model lookup + self._reversed = reversed + # Optional auxiliary prober for name decision + self._name_prober = name_prober + self._last_order = None + self._seq_counters = None + self._total_seqs = None + self._total_char = None + self._freq_char = None + self.reset() + + def reset(self): + super(SingleByteCharSetProber, self).reset() + # char order of last character + self._last_order = 255 + self._seq_counters = [0] * SequenceLikelihood.get_num_categories() + self._total_seqs = 0 + self._total_char = 0 + # characters that fall in our sampling range + self._freq_char = 0 + + @property + def charset_name(self): + if self._name_prober: + return self._name_prober.charset_name + else: + return self._model['charset_name'] + + @property + def language(self): + if self._name_prober: + return self._name_prober.language + else: + return self._model.get('language') + + def feed(self, byte_str): + if not self._model['keep_english_letter']: + byte_str = self.filter_international_words(byte_str) + if not byte_str: + return self.state + char_to_order_map = self._model['char_to_order_map'] + for i, c in enumerate(byte_str): + # XXX: Order is in range 1-64, so one would think we want 0-63 here, + # but that leads to 27 more test failures than before. + order = char_to_order_map[c] + # XXX: This was SYMBOL_CAT_ORDER before, with a value of 250, but + # CharacterCategory.SYMBOL is actually 253, so we use CONTROL + # to make it closer to the original intent. The only difference + # is whether or not we count digits and control characters for + # _total_char purposes. + if order < CharacterCategory.CONTROL: + self._total_char += 1 + if order < self.SAMPLE_SIZE: + self._freq_char += 1 + if self._last_order < self.SAMPLE_SIZE: + self._total_seqs += 1 + if not self._reversed: + i = (self._last_order * self.SAMPLE_SIZE) + order + model = self._model['precedence_matrix'][i] + else: # reverse the order of the letters in the lookup + i = (order * self.SAMPLE_SIZE) + self._last_order + model = self._model['precedence_matrix'][i] + self._seq_counters[model] += 1 + self._last_order = order + + charset_name = self._model['charset_name'] + if self.state == ProbingState.DETECTING: + if self._total_seqs > self.SB_ENOUGH_REL_THRESHOLD: + confidence = self.get_confidence() + if confidence > self.POSITIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, we have a winner', + charset_name, confidence) + self._state = ProbingState.FOUND_IT + elif confidence < self.NEGATIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, below negative ' + 'shortcut threshhold %s', charset_name, + confidence, + self.NEGATIVE_SHORTCUT_THRESHOLD) + self._state = ProbingState.NOT_ME + + return self.state + + def get_confidence(self): + r = 0.01 + if self._total_seqs > 0: + r = ((1.0 * self._seq_counters[SequenceLikelihood.POSITIVE]) / + self._total_seqs / self._model['typical_positive_ratio']) + r = r * self._freq_char / self._total_char + if r >= 1.0: + r = 0.99 + return r diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sbcsgroupprober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sbcsgroupprober.py new file mode 100644 index 0000000..98e95dc --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sbcsgroupprober.py @@ -0,0 +1,73 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .sbcharsetprober import SingleByteCharSetProber +from .langcyrillicmodel import (Win1251CyrillicModel, Koi8rModel, + Latin5CyrillicModel, MacCyrillicModel, + Ibm866Model, Ibm855Model) +from .langgreekmodel import Latin7GreekModel, Win1253GreekModel +from .langbulgarianmodel import Latin5BulgarianModel, Win1251BulgarianModel +# from .langhungarianmodel import Latin2HungarianModel, Win1250HungarianModel +from .langthaimodel import TIS620ThaiModel +from .langhebrewmodel import Win1255HebrewModel +from .hebrewprober import HebrewProber +from .langturkishmodel import Latin5TurkishModel + + +class SBCSGroupProber(CharSetGroupProber): + def __init__(self): + super(SBCSGroupProber, self).__init__() + self.probers = [ + SingleByteCharSetProber(Win1251CyrillicModel), + SingleByteCharSetProber(Koi8rModel), + SingleByteCharSetProber(Latin5CyrillicModel), + SingleByteCharSetProber(MacCyrillicModel), + SingleByteCharSetProber(Ibm866Model), + SingleByteCharSetProber(Ibm855Model), + SingleByteCharSetProber(Latin7GreekModel), + SingleByteCharSetProber(Win1253GreekModel), + SingleByteCharSetProber(Latin5BulgarianModel), + SingleByteCharSetProber(Win1251BulgarianModel), + # TODO: Restore Hungarian encodings (iso-8859-2 and windows-1250) + # after we retrain model. + # SingleByteCharSetProber(Latin2HungarianModel), + # SingleByteCharSetProber(Win1250HungarianModel), + SingleByteCharSetProber(TIS620ThaiModel), + SingleByteCharSetProber(Latin5TurkishModel), + ] + hebrew_prober = HebrewProber() + logical_hebrew_prober = SingleByteCharSetProber(Win1255HebrewModel, + False, hebrew_prober) + visual_hebrew_prober = SingleByteCharSetProber(Win1255HebrewModel, True, + hebrew_prober) + hebrew_prober.set_model_probers(logical_hebrew_prober, visual_hebrew_prober) + self.probers.extend([hebrew_prober, logical_hebrew_prober, + visual_hebrew_prober]) + + self.reset() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sjisprober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sjisprober.py new file mode 100644 index 0000000..9e29623 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sjisprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import SJISDistributionAnalysis +from .jpcntx import SJISContextAnalysis +from .mbcssm import SJIS_SM_MODEL +from .enums import ProbingState, MachineState + + +class SJISProber(MultiByteCharSetProber): + def __init__(self): + super(SJISProber, self).__init__() + self.coding_sm = CodingStateMachine(SJIS_SM_MODEL) + self.distribution_analyzer = SJISDistributionAnalysis() + self.context_analyzer = SJISContextAnalysis() + self.reset() + + def reset(self): + super(SJISProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return self.context_analyzer.charset_name + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char[2 - char_len:], + char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i + 1 - char_len:i + 3 + - char_len], char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/universaldetector.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/universaldetector.py new file mode 100644 index 0000000..7b4e92d --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/universaldetector.py @@ -0,0 +1,286 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### +""" +Module containing the UniversalDetector detector class, which is the primary +class a user of ``chardet`` should use. + +:author: Mark Pilgrim (initial port to Python) +:author: Shy Shalom (original C code) +:author: Dan Blanchard (major refactoring for 3.0) +:author: Ian Cordasco +""" + + +import codecs +import logging +import re + +from .charsetgroupprober import CharSetGroupProber +from .enums import InputState, LanguageFilter, ProbingState +from .escprober import EscCharSetProber +from .latin1prober import Latin1Prober +from .mbcsgroupprober import MBCSGroupProber +from .sbcsgroupprober import SBCSGroupProber + + +class UniversalDetector(object): + """ + The ``UniversalDetector`` class underlies the ``chardet.detect`` function + and coordinates all of the different charset probers. + + To get a ``dict`` containing an encoding and its confidence, you can simply + run: + + .. code:: + + u = UniversalDetector() + u.feed(some_bytes) + u.close() + detected = u.result + + """ + + MINIMUM_THRESHOLD = 0.20 + HIGH_BYTE_DETECTOR = re.compile(b'[\x80-\xFF]') + ESC_DETECTOR = re.compile(b'(\033|~{)') + WIN_BYTE_DETECTOR = re.compile(b'[\x80-\x9F]') + ISO_WIN_MAP = {'iso-8859-1': 'Windows-1252', + 'iso-8859-2': 'Windows-1250', + 'iso-8859-5': 'Windows-1251', + 'iso-8859-6': 'Windows-1256', + 'iso-8859-7': 'Windows-1253', + 'iso-8859-8': 'Windows-1255', + 'iso-8859-9': 'Windows-1254', + 'iso-8859-13': 'Windows-1257'} + + def __init__(self, lang_filter=LanguageFilter.ALL): + self._esc_charset_prober = None + self._charset_probers = [] + self.result = None + self.done = None + self._got_data = None + self._input_state = None + self._last_char = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + self._has_win_bytes = None + self.reset() + + def reset(self): + """ + Reset the UniversalDetector and all of its probers back to their + initial states. This is called by ``__init__``, so you only need to + call this directly in between analyses of different documents. + """ + self.result = {'encoding': None, 'confidence': 0.0, 'language': None} + self.done = False + self._got_data = False + self._has_win_bytes = False + self._input_state = InputState.PURE_ASCII + self._last_char = b'' + if self._esc_charset_prober: + self._esc_charset_prober.reset() + for prober in self._charset_probers: + prober.reset() + + def feed(self, byte_str): + """ + Takes a chunk of a document and feeds it through all of the relevant + charset probers. + + After calling ``feed``, you can check the value of the ``done`` + attribute to see if you need to continue feeding the + ``UniversalDetector`` more data, or if it has made a prediction + (in the ``result`` attribute). + + .. note:: + You should always call ``close`` when you're done feeding in your + document if ``done`` is not already ``True``. + """ + if self.done: + return + + if not len(byte_str): + return + + if not isinstance(byte_str, bytearray): + byte_str = bytearray(byte_str) + + # First check for known BOMs, since these are guaranteed to be correct + if not self._got_data: + # If the data starts with BOM, we know it is UTF + if byte_str.startswith(codecs.BOM_UTF8): + # EF BB BF UTF-8 with BOM + self.result = {'encoding': "UTF-8-SIG", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_UTF32_LE, + codecs.BOM_UTF32_BE)): + # FF FE 00 00 UTF-32, little-endian BOM + # 00 00 FE FF UTF-32, big-endian BOM + self.result = {'encoding': "UTF-32", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\xFE\xFF\x00\x00'): + # FE FF 00 00 UCS-4, unusual octet order BOM (3412) + self.result = {'encoding': "X-ISO-10646-UCS-4-3412", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\x00\x00\xFF\xFE'): + # 00 00 FF FE UCS-4, unusual octet order BOM (2143) + self.result = {'encoding': "X-ISO-10646-UCS-4-2143", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_LE, codecs.BOM_BE)): + # FF FE UTF-16, little endian BOM + # FE FF UTF-16, big endian BOM + self.result = {'encoding': "UTF-16", + 'confidence': 1.0, + 'language': ''} + + self._got_data = True + if self.result['encoding'] is not None: + self.done = True + return + + # If none of those matched and we've only see ASCII so far, check + # for high bytes and escape sequences + if self._input_state == InputState.PURE_ASCII: + if self.HIGH_BYTE_DETECTOR.search(byte_str): + self._input_state = InputState.HIGH_BYTE + elif self._input_state == InputState.PURE_ASCII and \ + self.ESC_DETECTOR.search(self._last_char + byte_str): + self._input_state = InputState.ESC_ASCII + + self._last_char = byte_str[-1:] + + # If we've seen escape sequences, use the EscCharSetProber, which + # uses a simple state machine to check for known escape sequences in + # HZ and ISO-2022 encodings, since those are the only encodings that + # use such sequences. + if self._input_state == InputState.ESC_ASCII: + if not self._esc_charset_prober: + self._esc_charset_prober = EscCharSetProber(self.lang_filter) + if self._esc_charset_prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': + self._esc_charset_prober.charset_name, + 'confidence': + self._esc_charset_prober.get_confidence(), + 'language': + self._esc_charset_prober.language} + self.done = True + # If we've seen high bytes (i.e., those with values greater than 127), + # we need to do more complicated checks using all our multi-byte and + # single-byte probers that are left. The single-byte probers + # use character bigram distributions to determine the encoding, whereas + # the multi-byte probers use a combination of character unigram and + # bigram distributions. + elif self._input_state == InputState.HIGH_BYTE: + if not self._charset_probers: + self._charset_probers = [MBCSGroupProber(self.lang_filter)] + # If we're checking non-CJK encodings, use single-byte prober + if self.lang_filter & LanguageFilter.NON_CJK: + self._charset_probers.append(SBCSGroupProber()) + self._charset_probers.append(Latin1Prober()) + for prober in self._charset_probers: + if prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': prober.charset_name, + 'confidence': prober.get_confidence(), + 'language': prober.language} + self.done = True + break + if self.WIN_BYTE_DETECTOR.search(byte_str): + self._has_win_bytes = True + + def close(self): + """ + Stop analyzing the current document and come up with a final + prediction. + + :returns: The ``result`` attribute, a ``dict`` with the keys + `encoding`, `confidence`, and `language`. + """ + # Don't bother with checks if we're already done + if self.done: + return self.result + self.done = True + + if not self._got_data: + self.logger.debug('no data received!') + + # Default to ASCII if it is all we've seen so far + elif self._input_state == InputState.PURE_ASCII: + self.result = {'encoding': 'ascii', + 'confidence': 1.0, + 'language': ''} + + # If we have seen non-ASCII, return the best that met MINIMUM_THRESHOLD + elif self._input_state == InputState.HIGH_BYTE: + prober_confidence = None + max_prober_confidence = 0.0 + max_prober = None + for prober in self._charset_probers: + if not prober: + continue + prober_confidence = prober.get_confidence() + if prober_confidence > max_prober_confidence: + max_prober_confidence = prober_confidence + max_prober = prober + if max_prober and (max_prober_confidence > self.MINIMUM_THRESHOLD): + charset_name = max_prober.charset_name + lower_charset_name = max_prober.charset_name.lower() + confidence = max_prober.get_confidence() + # Use Windows encoding name instead of ISO-8859 if we saw any + # extra Windows-specific bytes + if lower_charset_name.startswith('iso-8859'): + if self._has_win_bytes: + charset_name = self.ISO_WIN_MAP.get(lower_charset_name, + charset_name) + self.result = {'encoding': charset_name, + 'confidence': confidence, + 'language': max_prober.language} + + # Log all prober confidences if none met MINIMUM_THRESHOLD + if self.logger.getEffectiveLevel() == logging.DEBUG: + if self.result['encoding'] is None: + self.logger.debug('no probers hit minimum threshold') + for group_prober in self._charset_probers: + if not group_prober: + continue + if isinstance(group_prober, CharSetGroupProber): + for prober in group_prober.probers: + self.logger.debug('%s %s confidence = %s', + prober.charset_name, + prober.language, + prober.get_confidence()) + else: + self.logger.debug('%s %s confidence = %s', + prober.charset_name, + prober.language, + prober.get_confidence()) + return self.result diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/utf8prober.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/utf8prober.py new file mode 100644 index 0000000..6c3196c --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/utf8prober.py @@ -0,0 +1,82 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState +from .codingstatemachine import CodingStateMachine +from .mbcssm import UTF8_SM_MODEL + + + +class UTF8Prober(CharSetProber): + ONE_CHAR_PROB = 0.5 + + def __init__(self): + super(UTF8Prober, self).__init__() + self.coding_sm = CodingStateMachine(UTF8_SM_MODEL) + self._num_mb_chars = None + self.reset() + + def reset(self): + super(UTF8Prober, self).reset() + self.coding_sm.reset() + self._num_mb_chars = 0 + + @property + def charset_name(self): + return "utf-8" + + @property + def language(self): + return "" + + def feed(self, byte_str): + for c in byte_str: + coding_state = self.coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + if self.coding_sm.get_current_charlen() >= 2: + self._num_mb_chars += 1 + + if self.state == ProbingState.DETECTING: + if self.get_confidence() > self.SHORTCUT_THRESHOLD: + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + unlike = 0.99 + if self._num_mb_chars < 6: + unlike *= self.ONE_CHAR_PROB ** self._num_mb_chars + return 1.0 - unlike + else: + return unlike diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/version.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/version.py new file mode 100644 index 0000000..bb2a34a --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/version.py @@ -0,0 +1,9 @@ +""" +This module exists only to simplify retrieving the version number of chardet +from within setup.py and from chardet subpackages. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + +__version__ = "3.0.4" +VERSION = __version__.split('.') diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__init__.py new file mode 100644 index 0000000..f4d9ce2 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__init__.py @@ -0,0 +1,7 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from .initialise import init, deinit, reinit, colorama_text +from .ansi import Fore, Back, Style, Cursor +from .ansitowin32 import AnsiToWin32 + +__version__ = '0.3.9' + diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/ansi.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/ansi.py new file mode 100644 index 0000000..7877658 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/ansi.py @@ -0,0 +1,102 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +''' +This module generates ANSI character codes to printing colors to terminals. +See: http://en.wikipedia.org/wiki/ANSI_escape_code +''' + +CSI = '\033[' +OSC = '\033]' +BEL = '\007' + + +def code_to_chars(code): + return CSI + str(code) + 'm' + +def set_title(title): + return OSC + '2;' + title + BEL + +def clear_screen(mode=2): + return CSI + str(mode) + 'J' + +def clear_line(mode=2): + return CSI + str(mode) + 'K' + + +class AnsiCodes(object): + def __init__(self): + # the subclasses declare class attributes which are numbers. + # Upon instantiation we define instance attributes, which are the same + # as the class attributes but wrapped with the ANSI escape sequence + for name in dir(self): + if not name.startswith('_'): + value = getattr(self, name) + setattr(self, name, code_to_chars(value)) + + +class AnsiCursor(object): + def UP(self, n=1): + return CSI + str(n) + 'A' + def DOWN(self, n=1): + return CSI + str(n) + 'B' + def FORWARD(self, n=1): + return CSI + str(n) + 'C' + def BACK(self, n=1): + return CSI + str(n) + 'D' + def POS(self, x=1, y=1): + return CSI + str(y) + ';' + str(x) + 'H' + + +class AnsiFore(AnsiCodes): + BLACK = 30 + RED = 31 + GREEN = 32 + YELLOW = 33 + BLUE = 34 + MAGENTA = 35 + CYAN = 36 + WHITE = 37 + RESET = 39 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 90 + LIGHTRED_EX = 91 + LIGHTGREEN_EX = 92 + LIGHTYELLOW_EX = 93 + LIGHTBLUE_EX = 94 + LIGHTMAGENTA_EX = 95 + LIGHTCYAN_EX = 96 + LIGHTWHITE_EX = 97 + + +class AnsiBack(AnsiCodes): + BLACK = 40 + RED = 41 + GREEN = 42 + YELLOW = 43 + BLUE = 44 + MAGENTA = 45 + CYAN = 46 + WHITE = 47 + RESET = 49 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 100 + LIGHTRED_EX = 101 + LIGHTGREEN_EX = 102 + LIGHTYELLOW_EX = 103 + LIGHTBLUE_EX = 104 + LIGHTMAGENTA_EX = 105 + LIGHTCYAN_EX = 106 + LIGHTWHITE_EX = 107 + + +class AnsiStyle(AnsiCodes): + BRIGHT = 1 + DIM = 2 + NORMAL = 22 + RESET_ALL = 0 + +Fore = AnsiFore() +Back = AnsiBack() +Style = AnsiStyle() +Cursor = AnsiCursor() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/ansitowin32.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/ansitowin32.py new file mode 100644 index 0000000..1d6e605 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/ansitowin32.py @@ -0,0 +1,236 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import re +import sys +import os + +from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style +from .winterm import WinTerm, WinColor, WinStyle +from .win32 import windll, winapi_test + + +winterm = None +if windll is not None: + winterm = WinTerm() + + +def is_stream_closed(stream): + return not hasattr(stream, 'closed') or stream.closed + + +def is_a_tty(stream): + return hasattr(stream, 'isatty') and stream.isatty() + + +class StreamWrapper(object): + ''' + Wraps a stream (such as stdout), acting as a transparent proxy for all + attribute access apart from method 'write()', which is delegated to our + Converter instance. + ''' + def __init__(self, wrapped, converter): + # double-underscore everything to prevent clashes with names of + # attributes on the wrapped stream object. + self.__wrapped = wrapped + self.__convertor = converter + + def __getattr__(self, name): + return getattr(self.__wrapped, name) + + def write(self, text): + self.__convertor.write(text) + + +class AnsiToWin32(object): + ''' + Implements a 'write()' method which, on Windows, will strip ANSI character + sequences from the text, and if outputting to a tty, will convert them into + win32 function calls. + ''' + ANSI_CSI_RE = re.compile('\001?\033\\[((?:\\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer + ANSI_OSC_RE = re.compile('\001?\033\\]((?:.|;)*?)(\x07)\002?') # Operating System Command + + def __init__(self, wrapped, convert=None, strip=None, autoreset=False): + # The wrapped stream (normally sys.stdout or sys.stderr) + self.wrapped = wrapped + + # should we reset colors to defaults after every .write() + self.autoreset = autoreset + + # create the proxy wrapping our output stream + self.stream = StreamWrapper(wrapped, self) + + on_windows = os.name == 'nt' + # We test if the WinAPI works, because even if we are on Windows + # we may be using a terminal that doesn't support the WinAPI + # (e.g. Cygwin Terminal). In this case it's up to the terminal + # to support the ANSI codes. + conversion_supported = on_windows and winapi_test() + + # should we strip ANSI sequences from our output? + if strip is None: + strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped)) + self.strip = strip + + # should we should convert ANSI sequences into win32 calls? + if convert is None: + convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped) + self.convert = convert + + # dict of ansi codes to win32 functions and parameters + self.win32_calls = self.get_win32_calls() + + # are we wrapping stderr? + self.on_stderr = self.wrapped is sys.stderr + + def should_wrap(self): + ''' + True if this class is actually needed. If false, then the output + stream will not be affected, nor will win32 calls be issued, so + wrapping stdout is not actually required. This will generally be + False on non-Windows platforms, unless optional functionality like + autoreset has been requested using kwargs to init() + ''' + return self.convert or self.strip or self.autoreset + + def get_win32_calls(self): + if self.convert and winterm: + return { + AnsiStyle.RESET_ALL: (winterm.reset_all, ), + AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), + AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), + AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), + AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), + AnsiFore.RED: (winterm.fore, WinColor.RED), + AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), + AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), + AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), + AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), + AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), + AnsiFore.WHITE: (winterm.fore, WinColor.GREY), + AnsiFore.RESET: (winterm.fore, ), + AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), + AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), + AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), + AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), + AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), + AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), + AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), + AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), + AnsiBack.BLACK: (winterm.back, WinColor.BLACK), + AnsiBack.RED: (winterm.back, WinColor.RED), + AnsiBack.GREEN: (winterm.back, WinColor.GREEN), + AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), + AnsiBack.BLUE: (winterm.back, WinColor.BLUE), + AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), + AnsiBack.CYAN: (winterm.back, WinColor.CYAN), + AnsiBack.WHITE: (winterm.back, WinColor.GREY), + AnsiBack.RESET: (winterm.back, ), + AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), + AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), + AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), + AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), + AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), + AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), + AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), + AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), + } + return dict() + + def write(self, text): + if self.strip or self.convert: + self.write_and_convert(text) + else: + self.wrapped.write(text) + self.wrapped.flush() + if self.autoreset: + self.reset_all() + + + def reset_all(self): + if self.convert: + self.call_win32('m', (0,)) + elif not self.strip and not is_stream_closed(self.wrapped): + self.wrapped.write(Style.RESET_ALL) + + + def write_and_convert(self, text): + ''' + Write the given text to our wrapped stream, stripping any ANSI + sequences from the text, and optionally converting them into win32 + calls. + ''' + cursor = 0 + text = self.convert_osc(text) + for match in self.ANSI_CSI_RE.finditer(text): + start, end = match.span() + self.write_plain_text(text, cursor, start) + self.convert_ansi(*match.groups()) + cursor = end + self.write_plain_text(text, cursor, len(text)) + + + def write_plain_text(self, text, start, end): + if start < end: + self.wrapped.write(text[start:end]) + self.wrapped.flush() + + + def convert_ansi(self, paramstring, command): + if self.convert: + params = self.extract_params(command, paramstring) + self.call_win32(command, params) + + + def extract_params(self, command, paramstring): + if command in 'Hf': + params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) + while len(params) < 2: + # defaults: + params = params + (1,) + else: + params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) + if len(params) == 0: + # defaults: + if command in 'JKm': + params = (0,) + elif command in 'ABCD': + params = (1,) + + return params + + + def call_win32(self, command, params): + if command == 'm': + for param in params: + if param in self.win32_calls: + func_args = self.win32_calls[param] + func = func_args[0] + args = func_args[1:] + kwargs = dict(on_stderr=self.on_stderr) + func(*args, **kwargs) + elif command in 'J': + winterm.erase_screen(params[0], on_stderr=self.on_stderr) + elif command in 'K': + winterm.erase_line(params[0], on_stderr=self.on_stderr) + elif command in 'Hf': # cursor position - absolute + winterm.set_cursor_position(params, on_stderr=self.on_stderr) + elif command in 'ABCD': # cursor position - relative + n = params[0] + # A - up, B - down, C - forward, D - back + x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] + winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) + + + def convert_osc(self, text): + for match in self.ANSI_OSC_RE.finditer(text): + start, end = match.span() + text = text[:start] + text[end:] + paramstring, command = match.groups() + if command in '\x07': # \x07 = BEL + params = paramstring.split(";") + # 0 - change title and icon (we will only change title) + # 1 - change icon (we don't support this) + # 2 - change title + if params[0] in '02': + winterm.set_title(params[1]) + return text diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/initialise.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/initialise.py new file mode 100644 index 0000000..834962a --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/initialise.py @@ -0,0 +1,82 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import atexit +import contextlib +import sys + +from .ansitowin32 import AnsiToWin32 + + +orig_stdout = None +orig_stderr = None + +wrapped_stdout = None +wrapped_stderr = None + +atexit_done = False + + +def reset_all(): + if AnsiToWin32 is not None: # Issue #74: objects might become None at exit + AnsiToWin32(orig_stdout).reset_all() + + +def init(autoreset=False, convert=None, strip=None, wrap=True): + + if not wrap and any([autoreset, convert, strip]): + raise ValueError('wrap=False conflicts with any other arg=True') + + global wrapped_stdout, wrapped_stderr + global orig_stdout, orig_stderr + + orig_stdout = sys.stdout + orig_stderr = sys.stderr + + if sys.stdout is None: + wrapped_stdout = None + else: + sys.stdout = wrapped_stdout = \ + wrap_stream(orig_stdout, convert, strip, autoreset, wrap) + if sys.stderr is None: + wrapped_stderr = None + else: + sys.stderr = wrapped_stderr = \ + wrap_stream(orig_stderr, convert, strip, autoreset, wrap) + + global atexit_done + if not atexit_done: + atexit.register(reset_all) + atexit_done = True + + +def deinit(): + if orig_stdout is not None: + sys.stdout = orig_stdout + if orig_stderr is not None: + sys.stderr = orig_stderr + + +@contextlib.contextmanager +def colorama_text(*args, **kwargs): + init(*args, **kwargs) + try: + yield + finally: + deinit() + + +def reinit(): + if wrapped_stdout is not None: + sys.stdout = wrapped_stdout + if wrapped_stderr is not None: + sys.stderr = wrapped_stderr + + +def wrap_stream(stream, convert, strip, autoreset, wrap): + if wrap: + wrapper = AnsiToWin32(stream, + convert=convert, strip=strip, autoreset=autoreset) + if wrapper.should_wrap(): + stream = wrapper.stream + return stream + + diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/win32.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/win32.py new file mode 100644 index 0000000..8262e35 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/win32.py @@ -0,0 +1,156 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. + +# from winbase.h +STDOUT = -11 +STDERR = -12 + +try: + import ctypes + from ctypes import LibraryLoader + windll = LibraryLoader(ctypes.WinDLL) + from ctypes import wintypes +except (AttributeError, ImportError): + windll = None + SetConsoleTextAttribute = lambda *_: None + winapi_test = lambda *_: None +else: + from ctypes import byref, Structure, c_char, POINTER + + COORD = wintypes._COORD + + class CONSOLE_SCREEN_BUFFER_INFO(Structure): + """struct in wincon.h.""" + _fields_ = [ + ("dwSize", COORD), + ("dwCursorPosition", COORD), + ("wAttributes", wintypes.WORD), + ("srWindow", wintypes.SMALL_RECT), + ("dwMaximumWindowSize", COORD), + ] + def __str__(self): + return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( + self.dwSize.Y, self.dwSize.X + , self.dwCursorPosition.Y, self.dwCursorPosition.X + , self.wAttributes + , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right + , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X + ) + + _GetStdHandle = windll.kernel32.GetStdHandle + _GetStdHandle.argtypes = [ + wintypes.DWORD, + ] + _GetStdHandle.restype = wintypes.HANDLE + + _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo + _GetConsoleScreenBufferInfo.argtypes = [ + wintypes.HANDLE, + POINTER(CONSOLE_SCREEN_BUFFER_INFO), + ] + _GetConsoleScreenBufferInfo.restype = wintypes.BOOL + + _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute + _SetConsoleTextAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + ] + _SetConsoleTextAttribute.restype = wintypes.BOOL + + _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition + _SetConsoleCursorPosition.argtypes = [ + wintypes.HANDLE, + COORD, + ] + _SetConsoleCursorPosition.restype = wintypes.BOOL + + _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA + _FillConsoleOutputCharacterA.argtypes = [ + wintypes.HANDLE, + c_char, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputCharacterA.restype = wintypes.BOOL + + _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute + _FillConsoleOutputAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputAttribute.restype = wintypes.BOOL + + _SetConsoleTitleW = windll.kernel32.SetConsoleTitleW + _SetConsoleTitleW.argtypes = [ + wintypes.LPCWSTR + ] + _SetConsoleTitleW.restype = wintypes.BOOL + + handles = { + STDOUT: _GetStdHandle(STDOUT), + STDERR: _GetStdHandle(STDERR), + } + + def _winapi_test(handle): + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return bool(success) + + def winapi_test(): + return any(_winapi_test(h) for h in handles.values()) + + def GetConsoleScreenBufferInfo(stream_id=STDOUT): + handle = handles[stream_id] + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return csbi + + def SetConsoleTextAttribute(stream_id, attrs): + handle = handles[stream_id] + return _SetConsoleTextAttribute(handle, attrs) + + def SetConsoleCursorPosition(stream_id, position, adjust=True): + position = COORD(*position) + # If the position is out of range, do nothing. + if position.Y <= 0 or position.X <= 0: + return + # Adjust for Windows' SetConsoleCursorPosition: + # 1. being 0-based, while ANSI is 1-based. + # 2. expecting (x,y), while ANSI uses (y,x). + adjusted_position = COORD(position.Y - 1, position.X - 1) + if adjust: + # Adjust for viewport's scroll position + sr = GetConsoleScreenBufferInfo(STDOUT).srWindow + adjusted_position.Y += sr.Top + adjusted_position.X += sr.Left + # Resume normal processing + handle = handles[stream_id] + return _SetConsoleCursorPosition(handle, adjusted_position) + + def FillConsoleOutputCharacter(stream_id, char, length, start): + handle = handles[stream_id] + char = c_char(char.encode()) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + success = _FillConsoleOutputCharacterA( + handle, char, length, start, byref(num_written)) + return num_written.value + + def FillConsoleOutputAttribute(stream_id, attr, length, start): + ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' + handle = handles[stream_id] + attribute = wintypes.WORD(attr) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + return _FillConsoleOutputAttribute( + handle, attribute, length, start, byref(num_written)) + + def SetConsoleTitle(title): + return _SetConsoleTitleW(title) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/winterm.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/winterm.py new file mode 100644 index 0000000..60309d3 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/winterm.py @@ -0,0 +1,162 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from . import win32 + + +# from wincon.h +class WinColor(object): + BLACK = 0 + BLUE = 1 + GREEN = 2 + CYAN = 3 + RED = 4 + MAGENTA = 5 + YELLOW = 6 + GREY = 7 + +# from wincon.h +class WinStyle(object): + NORMAL = 0x00 # dim text, dim background + BRIGHT = 0x08 # bright text, dim background + BRIGHT_BACKGROUND = 0x80 # dim text, bright background + +class WinTerm(object): + + def __init__(self): + self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes + self.set_attrs(self._default) + self._default_fore = self._fore + self._default_back = self._back + self._default_style = self._style + # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style. + # So that LIGHT_EX colors and BRIGHT style do not clobber each other, + # we track them separately, since LIGHT_EX is overwritten by Fore/Back + # and BRIGHT is overwritten by Style codes. + self._light = 0 + + def get_attrs(self): + return self._fore + self._back * 16 + (self._style | self._light) + + def set_attrs(self, value): + self._fore = value & 7 + self._back = (value >> 4) & 7 + self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) + + def reset_all(self, on_stderr=None): + self.set_attrs(self._default) + self.set_console(attrs=self._default) + + def fore(self, fore=None, light=False, on_stderr=False): + if fore is None: + fore = self._default_fore + self._fore = fore + # Emulate LIGHT_EX with BRIGHT Style + if light: + self._light |= WinStyle.BRIGHT + else: + self._light &= ~WinStyle.BRIGHT + self.set_console(on_stderr=on_stderr) + + def back(self, back=None, light=False, on_stderr=False): + if back is None: + back = self._default_back + self._back = back + # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style + if light: + self._light |= WinStyle.BRIGHT_BACKGROUND + else: + self._light &= ~WinStyle.BRIGHT_BACKGROUND + self.set_console(on_stderr=on_stderr) + + def style(self, style=None, on_stderr=False): + if style is None: + style = self._default_style + self._style = style + self.set_console(on_stderr=on_stderr) + + def set_console(self, attrs=None, on_stderr=False): + if attrs is None: + attrs = self.get_attrs() + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleTextAttribute(handle, attrs) + + def get_position(self, handle): + position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition + # Because Windows coordinates are 0-based, + # and win32.SetConsoleCursorPosition expects 1-based. + position.X += 1 + position.Y += 1 + return position + + def set_cursor_position(self, position=None, on_stderr=False): + if position is None: + # I'm not currently tracking the position, so there is no default. + # position = self.get_position() + return + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleCursorPosition(handle, position) + + def cursor_adjust(self, x, y, on_stderr=False): + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + position = self.get_position(handle) + adjusted_position = (position.Y + y, position.X + x) + win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) + + def erase_screen(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the screen. + # 1 should clear from the cursor to the beginning of the screen. + # 2 should clear the entire screen, and move cursor to (1,1) + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + # get the number of character cells in the current buffer + cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y + # get number of character cells before current cursor position + cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = cells_in_screen - cells_before_cursor + if mode == 1: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_before_cursor + elif mode == 2: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_in_screen + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + if mode == 2: + # put the cursor where needed + win32.SetConsoleCursorPosition(handle, (1, 1)) + + def erase_line(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the line. + # 1 should clear from the cursor to the beginning of the line. + # 2 should clear the entire line. + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X + if mode == 1: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwCursorPosition.X + elif mode == 2: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwSize.X + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + + def set_title(self, title): + win32.SetConsoleTitle(title) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__init__.py new file mode 100644 index 0000000..d4aab45 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import logging + +__version__ = '0.2.7' + +class DistlibException(Exception): + pass + +try: + from logging import NullHandler +except ImportError: # pragma: no cover + class NullHandler(logging.Handler): + def handle(self, record): pass + def emit(self, record): pass + def createLock(self): self.lock = None + +logger = logging.getLogger(__name__) +logger.addHandler(NullHandler()) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/__init__.py new file mode 100644 index 0000000..f7dbf4c --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/__init__.py @@ -0,0 +1,6 @@ +"""Modules copied from Python 3 standard libraries, for internal use only. + +Individual classes and functions are found in d2._backport.misc. Intended +usage is to always import things missing from 3.1 from that module: the +built-in/stdlib objects will be used if found. +""" diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/misc.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/misc.py new file mode 100644 index 0000000..cfb318d --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/misc.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Backports for individual classes and functions.""" + +import os +import sys + +__all__ = ['cache_from_source', 'callable', 'fsencode'] + + +try: + from imp import cache_from_source +except ImportError: + def cache_from_source(py_file, debug=__debug__): + ext = debug and 'c' or 'o' + return py_file + ext + + +try: + callable = callable +except NameError: + from collections import Callable + + def callable(obj): + return isinstance(obj, Callable) + + +try: + fsencode = os.fsencode +except AttributeError: + def fsencode(filename): + if isinstance(filename, bytes): + return filename + elif isinstance(filename, str): + return filename.encode(sys.getfilesystemencoding()) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/shutil.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/shutil.py new file mode 100644 index 0000000..159e49e --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/shutil.py @@ -0,0 +1,761 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Utility functions for copying and archiving files and directory trees. + +XXX The functions here don't copy the resource fork or other metadata on Mac. + +""" + +import os +import sys +import stat +from os.path import abspath +import fnmatch +import collections +import errno +from . import tarfile + +try: + import bz2 + _BZ2_SUPPORTED = True +except ImportError: + _BZ2_SUPPORTED = False + +try: + from pwd import getpwnam +except ImportError: + getpwnam = None + +try: + from grp import getgrnam +except ImportError: + getgrnam = None + +__all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", + "copytree", "move", "rmtree", "Error", "SpecialFileError", + "ExecError", "make_archive", "get_archive_formats", + "register_archive_format", "unregister_archive_format", + "get_unpack_formats", "register_unpack_format", + "unregister_unpack_format", "unpack_archive", "ignore_patterns"] + +class Error(EnvironmentError): + pass + +class SpecialFileError(EnvironmentError): + """Raised when trying to do a kind of operation (e.g. copying) which is + not supported on a special file (e.g. a named pipe)""" + +class ExecError(EnvironmentError): + """Raised when a command could not be executed""" + +class ReadError(EnvironmentError): + """Raised when an archive cannot be read""" + +class RegistryError(Exception): + """Raised when a registry operation with the archiving + and unpacking registries fails""" + + +try: + WindowsError +except NameError: + WindowsError = None + +def copyfileobj(fsrc, fdst, length=16*1024): + """copy data from file-like object fsrc to file-like object fdst""" + while 1: + buf = fsrc.read(length) + if not buf: + break + fdst.write(buf) + +def _samefile(src, dst): + # Macintosh, Unix. + if hasattr(os.path, 'samefile'): + try: + return os.path.samefile(src, dst) + except OSError: + return False + + # All other platforms: check for same pathname. + return (os.path.normcase(os.path.abspath(src)) == + os.path.normcase(os.path.abspath(dst))) + +def copyfile(src, dst): + """Copy data from src to dst""" + if _samefile(src, dst): + raise Error("`%s` and `%s` are the same file" % (src, dst)) + + for fn in [src, dst]: + try: + st = os.stat(fn) + except OSError: + # File most likely does not exist + pass + else: + # XXX What about other special files? (sockets, devices...) + if stat.S_ISFIFO(st.st_mode): + raise SpecialFileError("`%s` is a named pipe" % fn) + + with open(src, 'rb') as fsrc: + with open(dst, 'wb') as fdst: + copyfileobj(fsrc, fdst) + +def copymode(src, dst): + """Copy mode bits from src to dst""" + if hasattr(os, 'chmod'): + st = os.stat(src) + mode = stat.S_IMODE(st.st_mode) + os.chmod(dst, mode) + +def copystat(src, dst): + """Copy all stat info (mode bits, atime, mtime, flags) from src to dst""" + st = os.stat(src) + mode = stat.S_IMODE(st.st_mode) + if hasattr(os, 'utime'): + os.utime(dst, (st.st_atime, st.st_mtime)) + if hasattr(os, 'chmod'): + os.chmod(dst, mode) + if hasattr(os, 'chflags') and hasattr(st, 'st_flags'): + try: + os.chflags(dst, st.st_flags) + except OSError as why: + if (not hasattr(errno, 'EOPNOTSUPP') or + why.errno != errno.EOPNOTSUPP): + raise + +def copy(src, dst): + """Copy data and mode bits ("cp src dst"). + + The destination may be a directory. + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst) + copymode(src, dst) + +def copy2(src, dst): + """Copy data and all stat info ("cp -p src dst"). + + The destination may be a directory. + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst) + copystat(src, dst) + +def ignore_patterns(*patterns): + """Function that can be used as copytree() ignore parameter. + + Patterns is a sequence of glob-style patterns + that are used to exclude files""" + def _ignore_patterns(path, names): + ignored_names = [] + for pattern in patterns: + ignored_names.extend(fnmatch.filter(names, pattern)) + return set(ignored_names) + return _ignore_patterns + +def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, + ignore_dangling_symlinks=False): + """Recursively copy a directory tree. + + The destination directory must not already exist. + If exception(s) occur, an Error is raised with a list of reasons. + + If the optional symlinks flag is true, symbolic links in the + source tree result in symbolic links in the destination tree; if + it is false, the contents of the files pointed to by symbolic + links are copied. If the file pointed by the symlink doesn't + exist, an exception will be added in the list of errors raised in + an Error exception at the end of the copy process. + + You can set the optional ignore_dangling_symlinks flag to true if you + want to silence this exception. Notice that this has no effect on + platforms that don't support os.symlink. + + The optional ignore argument is a callable. If given, it + is called with the `src` parameter, which is the directory + being visited by copytree(), and `names` which is the list of + `src` contents, as returned by os.listdir(): + + callable(src, names) -> ignored_names + + Since copytree() is called recursively, the callable will be + called once for each directory that is copied. It returns a + list of names relative to the `src` directory that should + not be copied. + + The optional copy_function argument is a callable that will be used + to copy each file. It will be called with the source path and the + destination path as arguments. By default, copy2() is used, but any + function that supports the same signature (like copy()) can be used. + + """ + names = os.listdir(src) + if ignore is not None: + ignored_names = ignore(src, names) + else: + ignored_names = set() + + os.makedirs(dst) + errors = [] + for name in names: + if name in ignored_names: + continue + srcname = os.path.join(src, name) + dstname = os.path.join(dst, name) + try: + if os.path.islink(srcname): + linkto = os.readlink(srcname) + if symlinks: + os.symlink(linkto, dstname) + else: + # ignore dangling symlink if the flag is on + if not os.path.exists(linkto) and ignore_dangling_symlinks: + continue + # otherwise let the copy occurs. copy2 will raise an error + copy_function(srcname, dstname) + elif os.path.isdir(srcname): + copytree(srcname, dstname, symlinks, ignore, copy_function) + else: + # Will raise a SpecialFileError for unsupported file types + copy_function(srcname, dstname) + # catch the Error from the recursive copytree so that we can + # continue with other files + except Error as err: + errors.extend(err.args[0]) + except EnvironmentError as why: + errors.append((srcname, dstname, str(why))) + try: + copystat(src, dst) + except OSError as why: + if WindowsError is not None and isinstance(why, WindowsError): + # Copying file access times may fail on Windows + pass + else: + errors.extend((src, dst, str(why))) + if errors: + raise Error(errors) + +def rmtree(path, ignore_errors=False, onerror=None): + """Recursively delete a directory tree. + + If ignore_errors is set, errors are ignored; otherwise, if onerror + is set, it is called to handle the error with arguments (func, + path, exc_info) where func is os.listdir, os.remove, or os.rmdir; + path is the argument to that function that caused it to fail; and + exc_info is a tuple returned by sys.exc_info(). If ignore_errors + is false and onerror is None, an exception is raised. + + """ + if ignore_errors: + def onerror(*args): + pass + elif onerror is None: + def onerror(*args): + raise + try: + if os.path.islink(path): + # symlinks to directories are forbidden, see bug #1669 + raise OSError("Cannot call rmtree on a symbolic link") + except OSError: + onerror(os.path.islink, path, sys.exc_info()) + # can't continue even if onerror hook returns + return + names = [] + try: + names = os.listdir(path) + except os.error: + onerror(os.listdir, path, sys.exc_info()) + for name in names: + fullname = os.path.join(path, name) + try: + mode = os.lstat(fullname).st_mode + except os.error: + mode = 0 + if stat.S_ISDIR(mode): + rmtree(fullname, ignore_errors, onerror) + else: + try: + os.remove(fullname) + except os.error: + onerror(os.remove, fullname, sys.exc_info()) + try: + os.rmdir(path) + except os.error: + onerror(os.rmdir, path, sys.exc_info()) + + +def _basename(path): + # A basename() variant which first strips the trailing slash, if present. + # Thus we always get the last component of the path, even for directories. + return os.path.basename(path.rstrip(os.path.sep)) + +def move(src, dst): + """Recursively move a file or directory to another location. This is + similar to the Unix "mv" command. + + If the destination is a directory or a symlink to a directory, the source + is moved inside the directory. The destination path must not already + exist. + + If the destination already exists but is not a directory, it may be + overwritten depending on os.rename() semantics. + + If the destination is on our current filesystem, then rename() is used. + Otherwise, src is copied to the destination and then removed. + A lot more could be done here... A look at a mv.c shows a lot of + the issues this implementation glosses over. + + """ + real_dst = dst + if os.path.isdir(dst): + if _samefile(src, dst): + # We might be on a case insensitive filesystem, + # perform the rename anyway. + os.rename(src, dst) + return + + real_dst = os.path.join(dst, _basename(src)) + if os.path.exists(real_dst): + raise Error("Destination path '%s' already exists" % real_dst) + try: + os.rename(src, real_dst) + except OSError: + if os.path.isdir(src): + if _destinsrc(src, dst): + raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst)) + copytree(src, real_dst, symlinks=True) + rmtree(src) + else: + copy2(src, real_dst) + os.unlink(src) + +def _destinsrc(src, dst): + src = abspath(src) + dst = abspath(dst) + if not src.endswith(os.path.sep): + src += os.path.sep + if not dst.endswith(os.path.sep): + dst += os.path.sep + return dst.startswith(src) + +def _get_gid(name): + """Returns a gid, given a group name.""" + if getgrnam is None or name is None: + return None + try: + result = getgrnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _get_uid(name): + """Returns an uid, given a user name.""" + if getpwnam is None or name is None: + return None + try: + result = getpwnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, + owner=None, group=None, logger=None): + """Create a (possibly compressed) tar file from all the files under + 'base_dir'. + + 'compress' must be "gzip" (the default), "bzip2", or None. + + 'owner' and 'group' can be used to define an owner and a group for the + archive that is being built. If not provided, the current owner and group + will be used. + + The output tar file will be named 'base_name' + ".tar", possibly plus + the appropriate compression extension (".gz", or ".bz2"). + + Returns the output filename. + """ + tar_compression = {'gzip': 'gz', None: ''} + compress_ext = {'gzip': '.gz'} + + if _BZ2_SUPPORTED: + tar_compression['bzip2'] = 'bz2' + compress_ext['bzip2'] = '.bz2' + + # flags for compression program, each element of list will be an argument + if compress is not None and compress not in compress_ext: + raise ValueError("bad value for 'compress', or compression format not " + "supported : {0}".format(compress)) + + archive_name = base_name + '.tar' + compress_ext.get(compress, '') + archive_dir = os.path.dirname(archive_name) + + if not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + # creating the tarball + if logger is not None: + logger.info('Creating tar archive') + + uid = _get_uid(owner) + gid = _get_gid(group) + + def _set_uid_gid(tarinfo): + if gid is not None: + tarinfo.gid = gid + tarinfo.gname = group + if uid is not None: + tarinfo.uid = uid + tarinfo.uname = owner + return tarinfo + + if not dry_run: + tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress]) + try: + tar.add(base_dir, filter=_set_uid_gid) + finally: + tar.close() + + return archive_name + +def _call_external_zip(base_dir, zip_filename, verbose=False, dry_run=False): + # XXX see if we want to keep an external call here + if verbose: + zipoptions = "-r" + else: + zipoptions = "-rq" + from distutils.errors import DistutilsExecError + from distutils.spawn import spawn + try: + spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run) + except DistutilsExecError: + # XXX really should distinguish between "couldn't find + # external 'zip' command" and "zip failed". + raise ExecError("unable to create zip file '%s': " + "could neither import the 'zipfile' module nor " + "find a standalone zip utility") % zip_filename + +def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): + """Create a zip file from all the files under 'base_dir'. + + The output zip file will be named 'base_name' + ".zip". Uses either the + "zipfile" Python module (if available) or the InfoZIP "zip" utility + (if installed and found on the default search path). If neither tool is + available, raises ExecError. Returns the name of the output zip + file. + """ + zip_filename = base_name + ".zip" + archive_dir = os.path.dirname(base_name) + + if not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + # If zipfile module is not available, try spawning an external 'zip' + # command. + try: + import zipfile + except ImportError: + zipfile = None + + if zipfile is None: + _call_external_zip(base_dir, zip_filename, verbose, dry_run) + else: + if logger is not None: + logger.info("creating '%s' and adding '%s' to it", + zip_filename, base_dir) + + if not dry_run: + zip = zipfile.ZipFile(zip_filename, "w", + compression=zipfile.ZIP_DEFLATED) + + for dirpath, dirnames, filenames in os.walk(base_dir): + for name in filenames: + path = os.path.normpath(os.path.join(dirpath, name)) + if os.path.isfile(path): + zip.write(path, path) + if logger is not None: + logger.info("adding '%s'", path) + zip.close() + + return zip_filename + +_ARCHIVE_FORMATS = { + 'gztar': (_make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), + 'bztar': (_make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), + 'tar': (_make_tarball, [('compress', None)], "uncompressed tar file"), + 'zip': (_make_zipfile, [], "ZIP file"), + } + +if _BZ2_SUPPORTED: + _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], + "bzip2'ed tar-file") + +def get_archive_formats(): + """Returns a list of supported formats for archiving and unarchiving. + + Each element of the returned sequence is a tuple (name, description) + """ + formats = [(name, registry[2]) for name, registry in + _ARCHIVE_FORMATS.items()] + formats.sort() + return formats + +def register_archive_format(name, function, extra_args=None, description=''): + """Registers an archive format. + + name is the name of the format. function is the callable that will be + used to create archives. If provided, extra_args is a sequence of + (name, value) tuples that will be passed as arguments to the callable. + description can be provided to describe the format, and will be returned + by the get_archive_formats() function. + """ + if extra_args is None: + extra_args = [] + if not isinstance(function, collections.Callable): + raise TypeError('The %s object is not callable' % function) + if not isinstance(extra_args, (tuple, list)): + raise TypeError('extra_args needs to be a sequence') + for element in extra_args: + if not isinstance(element, (tuple, list)) or len(element) !=2: + raise TypeError('extra_args elements are : (arg_name, value)') + + _ARCHIVE_FORMATS[name] = (function, extra_args, description) + +def unregister_archive_format(name): + del _ARCHIVE_FORMATS[name] + +def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, + dry_run=0, owner=None, group=None, logger=None): + """Create an archive file (eg. zip or tar). + + 'base_name' is the name of the file to create, minus any format-specific + extension; 'format' is the archive format: one of "zip", "tar", "bztar" + or "gztar". + + 'root_dir' is a directory that will be the root directory of the + archive; ie. we typically chdir into 'root_dir' before creating the + archive. 'base_dir' is the directory where we start archiving from; + ie. 'base_dir' will be the common prefix of all files and + directories in the archive. 'root_dir' and 'base_dir' both default + to the current directory. Returns the name of the archive file. + + 'owner' and 'group' are used when creating a tar archive. By default, + uses the current owner and group. + """ + save_cwd = os.getcwd() + if root_dir is not None: + if logger is not None: + logger.debug("changing into '%s'", root_dir) + base_name = os.path.abspath(base_name) + if not dry_run: + os.chdir(root_dir) + + if base_dir is None: + base_dir = os.curdir + + kwargs = {'dry_run': dry_run, 'logger': logger} + + try: + format_info = _ARCHIVE_FORMATS[format] + except KeyError: + raise ValueError("unknown archive format '%s'" % format) + + func = format_info[0] + for arg, val in format_info[1]: + kwargs[arg] = val + + if format != 'zip': + kwargs['owner'] = owner + kwargs['group'] = group + + try: + filename = func(base_name, base_dir, **kwargs) + finally: + if root_dir is not None: + if logger is not None: + logger.debug("changing back to '%s'", save_cwd) + os.chdir(save_cwd) + + return filename + + +def get_unpack_formats(): + """Returns a list of supported formats for unpacking. + + Each element of the returned sequence is a tuple + (name, extensions, description) + """ + formats = [(name, info[0], info[3]) for name, info in + _UNPACK_FORMATS.items()] + formats.sort() + return formats + +def _check_unpack_options(extensions, function, extra_args): + """Checks what gets registered as an unpacker.""" + # first make sure no other unpacker is registered for this extension + existing_extensions = {} + for name, info in _UNPACK_FORMATS.items(): + for ext in info[0]: + existing_extensions[ext] = name + + for extension in extensions: + if extension in existing_extensions: + msg = '%s is already registered for "%s"' + raise RegistryError(msg % (extension, + existing_extensions[extension])) + + if not isinstance(function, collections.Callable): + raise TypeError('The registered function must be a callable') + + +def register_unpack_format(name, extensions, function, extra_args=None, + description=''): + """Registers an unpack format. + + `name` is the name of the format. `extensions` is a list of extensions + corresponding to the format. + + `function` is the callable that will be + used to unpack archives. The callable will receive archives to unpack. + If it's unable to handle an archive, it needs to raise a ReadError + exception. + + If provided, `extra_args` is a sequence of + (name, value) tuples that will be passed as arguments to the callable. + description can be provided to describe the format, and will be returned + by the get_unpack_formats() function. + """ + if extra_args is None: + extra_args = [] + _check_unpack_options(extensions, function, extra_args) + _UNPACK_FORMATS[name] = extensions, function, extra_args, description + +def unregister_unpack_format(name): + """Removes the pack format from the registry.""" + del _UNPACK_FORMATS[name] + +def _ensure_directory(path): + """Ensure that the parent directory of `path` exists""" + dirname = os.path.dirname(path) + if not os.path.isdir(dirname): + os.makedirs(dirname) + +def _unpack_zipfile(filename, extract_dir): + """Unpack zip `filename` to `extract_dir` + """ + try: + import zipfile + except ImportError: + raise ReadError('zlib not supported, cannot unpack this archive.') + + if not zipfile.is_zipfile(filename): + raise ReadError("%s is not a zip file" % filename) + + zip = zipfile.ZipFile(filename) + try: + for info in zip.infolist(): + name = info.filename + + # don't extract absolute paths or ones with .. in them + if name.startswith('/') or '..' in name: + continue + + target = os.path.join(extract_dir, *name.split('/')) + if not target: + continue + + _ensure_directory(target) + if not name.endswith('/'): + # file + data = zip.read(info.filename) + f = open(target, 'wb') + try: + f.write(data) + finally: + f.close() + del data + finally: + zip.close() + +def _unpack_tarfile(filename, extract_dir): + """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` + """ + try: + tarobj = tarfile.open(filename) + except tarfile.TarError: + raise ReadError( + "%s is not a compressed or uncompressed tar file" % filename) + try: + tarobj.extractall(extract_dir) + finally: + tarobj.close() + +_UNPACK_FORMATS = { + 'gztar': (['.tar.gz', '.tgz'], _unpack_tarfile, [], "gzip'ed tar-file"), + 'tar': (['.tar'], _unpack_tarfile, [], "uncompressed tar file"), + 'zip': (['.zip'], _unpack_zipfile, [], "ZIP file") + } + +if _BZ2_SUPPORTED: + _UNPACK_FORMATS['bztar'] = (['.bz2'], _unpack_tarfile, [], + "bzip2'ed tar-file") + +def _find_unpack_format(filename): + for name, info in _UNPACK_FORMATS.items(): + for extension in info[0]: + if filename.endswith(extension): + return name + return None + +def unpack_archive(filename, extract_dir=None, format=None): + """Unpack an archive. + + `filename` is the name of the archive. + + `extract_dir` is the name of the target directory, where the archive + is unpacked. If not provided, the current working directory is used. + + `format` is the archive format: one of "zip", "tar", or "gztar". Or any + other registered format. If not provided, unpack_archive will use the + filename extension and see if an unpacker was registered for that + extension. + + In case none is found, a ValueError is raised. + """ + if extract_dir is None: + extract_dir = os.getcwd() + + if format is not None: + try: + format_info = _UNPACK_FORMATS[format] + except KeyError: + raise ValueError("Unknown unpack format '{0}'".format(format)) + + func = format_info[1] + func(filename, extract_dir, **dict(format_info[2])) + else: + # we need to look at the registered unpackers supported extensions + format = _find_unpack_format(filename) + if format is None: + raise ReadError("Unknown archive format '{0}'".format(filename)) + + func = _UNPACK_FORMATS[format][1] + kwargs = dict(_UNPACK_FORMATS[format][2]) + func(filename, extract_dir, **kwargs) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.cfg b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.cfg new file mode 100644 index 0000000..1746bd0 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.cfg @@ -0,0 +1,84 @@ +[posix_prefix] +# Configuration directories. Some of these come straight out of the +# configure script. They are for implementing the other variables, not to +# be used directly in [resource_locations]. +confdir = /etc +datadir = /usr/share +libdir = /usr/lib +statedir = /var +# User resource directory +local = ~/.local/{distribution.name} + +stdlib = {base}/lib/python{py_version_short} +platstdlib = {platbase}/lib/python{py_version_short} +purelib = {base}/lib/python{py_version_short}/site-packages +platlib = {platbase}/lib/python{py_version_short}/site-packages +include = {base}/include/python{py_version_short}{abiflags} +platinclude = {platbase}/include/python{py_version_short}{abiflags} +data = {base} + +[posix_home] +stdlib = {base}/lib/python +platstdlib = {base}/lib/python +purelib = {base}/lib/python +platlib = {base}/lib/python +include = {base}/include/python +platinclude = {base}/include/python +scripts = {base}/bin +data = {base} + +[nt] +stdlib = {base}/Lib +platstdlib = {base}/Lib +purelib = {base}/Lib/site-packages +platlib = {base}/Lib/site-packages +include = {base}/Include +platinclude = {base}/Include +scripts = {base}/Scripts +data = {base} + +[os2] +stdlib = {base}/Lib +platstdlib = {base}/Lib +purelib = {base}/Lib/site-packages +platlib = {base}/Lib/site-packages +include = {base}/Include +platinclude = {base}/Include +scripts = {base}/Scripts +data = {base} + +[os2_home] +stdlib = {userbase}/lib/python{py_version_short} +platstdlib = {userbase}/lib/python{py_version_short} +purelib = {userbase}/lib/python{py_version_short}/site-packages +platlib = {userbase}/lib/python{py_version_short}/site-packages +include = {userbase}/include/python{py_version_short} +scripts = {userbase}/bin +data = {userbase} + +[nt_user] +stdlib = {userbase}/Python{py_version_nodot} +platstdlib = {userbase}/Python{py_version_nodot} +purelib = {userbase}/Python{py_version_nodot}/site-packages +platlib = {userbase}/Python{py_version_nodot}/site-packages +include = {userbase}/Python{py_version_nodot}/Include +scripts = {userbase}/Scripts +data = {userbase} + +[posix_user] +stdlib = {userbase}/lib/python{py_version_short} +platstdlib = {userbase}/lib/python{py_version_short} +purelib = {userbase}/lib/python{py_version_short}/site-packages +platlib = {userbase}/lib/python{py_version_short}/site-packages +include = {userbase}/include/python{py_version_short} +scripts = {userbase}/bin +data = {userbase} + +[osx_framework_user] +stdlib = {userbase}/lib/python +platstdlib = {userbase}/lib/python +purelib = {userbase}/lib/python/site-packages +platlib = {userbase}/lib/python/site-packages +include = {userbase}/include +scripts = {userbase}/bin +data = {userbase} diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py new file mode 100644 index 0000000..1df3aba --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py @@ -0,0 +1,788 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Access to Python's configuration information.""" + +import codecs +import os +import re +import sys +from os.path import pardir, realpath +try: + import configparser +except ImportError: + import ConfigParser as configparser + + +__all__ = [ + 'get_config_h_filename', + 'get_config_var', + 'get_config_vars', + 'get_makefile_filename', + 'get_path', + 'get_path_names', + 'get_paths', + 'get_platform', + 'get_python_version', + 'get_scheme_names', + 'parse_config_h', +] + + +def _safe_realpath(path): + try: + return realpath(path) + except OSError: + return path + + +if sys.executable: + _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) +else: + # sys.executable can be empty if argv[0] has been changed and Python is + # unable to retrieve the real program name + _PROJECT_BASE = _safe_realpath(os.getcwd()) + +if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir)) +# PC/VS7.1 +if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) +# PC/AMD64 +if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) + + +def is_python_build(): + for fn in ("Setup.dist", "Setup.local"): + if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): + return True + return False + +_PYTHON_BUILD = is_python_build() + +_cfg_read = False + +def _ensure_cfg_read(): + global _cfg_read + if not _cfg_read: + from ..resources import finder + backport_package = __name__.rsplit('.', 1)[0] + _finder = finder(backport_package) + _cfgfile = _finder.find('sysconfig.cfg') + assert _cfgfile, 'sysconfig.cfg exists' + with _cfgfile.as_stream() as s: + _SCHEMES.readfp(s) + if _PYTHON_BUILD: + for scheme in ('posix_prefix', 'posix_home'): + _SCHEMES.set(scheme, 'include', '{srcdir}/Include') + _SCHEMES.set(scheme, 'platinclude', '{projectbase}/.') + + _cfg_read = True + + +_SCHEMES = configparser.RawConfigParser() +_VAR_REPL = re.compile(r'\{([^{]*?)\}') + +def _expand_globals(config): + _ensure_cfg_read() + if config.has_section('globals'): + globals = config.items('globals') + else: + globals = tuple() + + sections = config.sections() + for section in sections: + if section == 'globals': + continue + for option, value in globals: + if config.has_option(section, option): + continue + config.set(section, option, value) + config.remove_section('globals') + + # now expanding local variables defined in the cfg file + # + for section in config.sections(): + variables = dict(config.items(section)) + + def _replacer(matchobj): + name = matchobj.group(1) + if name in variables: + return variables[name] + return matchobj.group(0) + + for option, value in config.items(section): + config.set(section, option, _VAR_REPL.sub(_replacer, value)) + +#_expand_globals(_SCHEMES) + + # FIXME don't rely on sys.version here, its format is an implementation detail + # of CPython, use sys.version_info or sys.hexversion +_PY_VERSION = sys.version.split()[0] +_PY_VERSION_SHORT = sys.version[:3] +_PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2] +_PREFIX = os.path.normpath(sys.prefix) +_EXEC_PREFIX = os.path.normpath(sys.exec_prefix) +_CONFIG_VARS = None +_USER_BASE = None + + +def _subst_vars(path, local_vars): + """In the string `path`, replace tokens like {some.thing} with the + corresponding value from the map `local_vars`. + + If there is no corresponding value, leave the token unchanged. + """ + def _replacer(matchobj): + name = matchobj.group(1) + if name in local_vars: + return local_vars[name] + elif name in os.environ: + return os.environ[name] + return matchobj.group(0) + return _VAR_REPL.sub(_replacer, path) + + +def _extend_dict(target_dict, other_dict): + target_keys = target_dict.keys() + for key, value in other_dict.items(): + if key in target_keys: + continue + target_dict[key] = value + + +def _expand_vars(scheme, vars): + res = {} + if vars is None: + vars = {} + _extend_dict(vars, get_config_vars()) + + for key, value in _SCHEMES.items(scheme): + if os.name in ('posix', 'nt'): + value = os.path.expanduser(value) + res[key] = os.path.normpath(_subst_vars(value, vars)) + return res + + +def format_value(value, vars): + def _replacer(matchobj): + name = matchobj.group(1) + if name in vars: + return vars[name] + return matchobj.group(0) + return _VAR_REPL.sub(_replacer, value) + + +def _get_default_scheme(): + if os.name == 'posix': + # the default scheme for posix is posix_prefix + return 'posix_prefix' + return os.name + + +def _getuserbase(): + env_base = os.environ.get("PYTHONUSERBASE", None) + + def joinuser(*args): + return os.path.expanduser(os.path.join(*args)) + + # what about 'os2emx', 'riscos' ? + if os.name == "nt": + base = os.environ.get("APPDATA") or "~" + if env_base: + return env_base + else: + return joinuser(base, "Python") + + if sys.platform == "darwin": + framework = get_config_var("PYTHONFRAMEWORK") + if framework: + if env_base: + return env_base + else: + return joinuser("~", "Library", framework, "%d.%d" % + sys.version_info[:2]) + + if env_base: + return env_base + else: + return joinuser("~", ".local") + + +def _parse_makefile(filename, vars=None): + """Parse a Makefile-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + # Regexes needed for parsing Makefile (and similar syntaxes, + # like old-style Setup files). + _variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") + _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") + _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") + + if vars is None: + vars = {} + done = {} + notdone = {} + + with codecs.open(filename, encoding='utf-8', errors="surrogateescape") as f: + lines = f.readlines() + + for line in lines: + if line.startswith('#') or line.strip() == '': + continue + m = _variable_rx.match(line) + if m: + n, v = m.group(1, 2) + v = v.strip() + # `$$' is a literal `$' in make + tmpv = v.replace('$$', '') + + if "$" in tmpv: + notdone[n] = v + else: + try: + v = int(v) + except ValueError: + # insert literal `$' + done[n] = v.replace('$$', '$') + else: + done[n] = v + + # do variable interpolation here + variables = list(notdone.keys()) + + # Variables with a 'PY_' prefix in the makefile. These need to + # be made available without that prefix through sysconfig. + # Special care is needed to ensure that variable expansion works, even + # if the expansion uses the name without a prefix. + renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') + + while len(variables) > 0: + for name in tuple(variables): + value = notdone[name] + m = _findvar1_rx.search(value) or _findvar2_rx.search(value) + if m is not None: + n = m.group(1) + found = True + if n in done: + item = str(done[n]) + elif n in notdone: + # get it on a subsequent round + found = False + elif n in os.environ: + # do it like make: fall back to environment + item = os.environ[n] + + elif n in renamed_variables: + if (name.startswith('PY_') and + name[3:] in renamed_variables): + item = "" + + elif 'PY_' + n in notdone: + found = False + + else: + item = str(done['PY_' + n]) + + else: + done[n] = item = "" + + if found: + after = value[m.end():] + value = value[:m.start()] + item + after + if "$" in after: + notdone[name] = value + else: + try: + value = int(value) + except ValueError: + done[name] = value.strip() + else: + done[name] = value + variables.remove(name) + + if (name.startswith('PY_') and + name[3:] in renamed_variables): + + name = name[3:] + if name not in done: + done[name] = value + + else: + # bogus variable reference (e.g. "prefix=$/opt/python"); + # just drop it since we can't deal + done[name] = value + variables.remove(name) + + # strip spurious spaces + for k, v in done.items(): + if isinstance(v, str): + done[k] = v.strip() + + # save the results in the global dictionary + vars.update(done) + return vars + + +def get_makefile_filename(): + """Return the path of the Makefile.""" + if _PYTHON_BUILD: + return os.path.join(_PROJECT_BASE, "Makefile") + if hasattr(sys, 'abiflags'): + config_dir_name = 'config-%s%s' % (_PY_VERSION_SHORT, sys.abiflags) + else: + config_dir_name = 'config' + return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') + + +def _init_posix(vars): + """Initialize the module as appropriate for POSIX systems.""" + # load the installed Makefile: + makefile = get_makefile_filename() + try: + _parse_makefile(makefile, vars) + except IOError as e: + msg = "invalid Python installation: unable to open %s" % makefile + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + # load the installed pyconfig.h: + config_h = get_config_h_filename() + try: + with open(config_h) as f: + parse_config_h(f, vars) + except IOError as e: + msg = "invalid Python installation: unable to open %s" % config_h + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + # On AIX, there are wrong paths to the linker scripts in the Makefile + # -- these paths are relative to the Python source, but when installed + # the scripts are in another directory. + if _PYTHON_BUILD: + vars['LDSHARED'] = vars['BLDSHARED'] + + +def _init_non_posix(vars): + """Initialize the module as appropriate for NT""" + # set basic install directories + vars['LIBDEST'] = get_path('stdlib') + vars['BINLIBDEST'] = get_path('platstdlib') + vars['INCLUDEPY'] = get_path('include') + vars['SO'] = '.pyd' + vars['EXE'] = '.exe' + vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT + vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) + +# +# public APIs +# + + +def parse_config_h(fp, vars=None): + """Parse a config.h-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + if vars is None: + vars = {} + define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") + undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") + + while True: + line = fp.readline() + if not line: + break + m = define_rx.match(line) + if m: + n, v = m.group(1, 2) + try: + v = int(v) + except ValueError: + pass + vars[n] = v + else: + m = undef_rx.match(line) + if m: + vars[m.group(1)] = 0 + return vars + + +def get_config_h_filename(): + """Return the path of pyconfig.h.""" + if _PYTHON_BUILD: + if os.name == "nt": + inc_dir = os.path.join(_PROJECT_BASE, "PC") + else: + inc_dir = _PROJECT_BASE + else: + inc_dir = get_path('platinclude') + return os.path.join(inc_dir, 'pyconfig.h') + + +def get_scheme_names(): + """Return a tuple containing the schemes names.""" + return tuple(sorted(_SCHEMES.sections())) + + +def get_path_names(): + """Return a tuple containing the paths names.""" + # xxx see if we want a static list + return _SCHEMES.options('posix_prefix') + + +def get_paths(scheme=_get_default_scheme(), vars=None, expand=True): + """Return a mapping containing an install scheme. + + ``scheme`` is the install scheme name. If not provided, it will + return the default scheme for the current platform. + """ + _ensure_cfg_read() + if expand: + return _expand_vars(scheme, vars) + else: + return dict(_SCHEMES.items(scheme)) + + +def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True): + """Return a path corresponding to the scheme. + + ``scheme`` is the install scheme name. + """ + return get_paths(scheme, vars, expand)[name] + + +def get_config_vars(*args): + """With no arguments, return a dictionary of all configuration + variables relevant for the current platform. + + On Unix, this means every variable defined in Python's installed Makefile; + On Windows and Mac OS it's a much smaller set. + + With arguments, return a list of values that result from looking up + each argument in the configuration variable dictionary. + """ + global _CONFIG_VARS + if _CONFIG_VARS is None: + _CONFIG_VARS = {} + # Normalized versions of prefix and exec_prefix are handy to have; + # in fact, these are the standard versions used most places in the + # distutils2 module. + _CONFIG_VARS['prefix'] = _PREFIX + _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX + _CONFIG_VARS['py_version'] = _PY_VERSION + _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT + _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2] + _CONFIG_VARS['base'] = _PREFIX + _CONFIG_VARS['platbase'] = _EXEC_PREFIX + _CONFIG_VARS['projectbase'] = _PROJECT_BASE + try: + _CONFIG_VARS['abiflags'] = sys.abiflags + except AttributeError: + # sys.abiflags may not be defined on all platforms. + _CONFIG_VARS['abiflags'] = '' + + if os.name in ('nt', 'os2'): + _init_non_posix(_CONFIG_VARS) + if os.name == 'posix': + _init_posix(_CONFIG_VARS) + # Setting 'userbase' is done below the call to the + # init function to enable using 'get_config_var' in + # the init-function. + if sys.version >= '2.6': + _CONFIG_VARS['userbase'] = _getuserbase() + + if 'srcdir' not in _CONFIG_VARS: + _CONFIG_VARS['srcdir'] = _PROJECT_BASE + else: + _CONFIG_VARS['srcdir'] = _safe_realpath(_CONFIG_VARS['srcdir']) + + # Convert srcdir into an absolute path if it appears necessary. + # Normally it is relative to the build directory. However, during + # testing, for example, we might be running a non-installed python + # from a different directory. + if _PYTHON_BUILD and os.name == "posix": + base = _PROJECT_BASE + try: + cwd = os.getcwd() + except OSError: + cwd = None + if (not os.path.isabs(_CONFIG_VARS['srcdir']) and + base != cwd): + # srcdir is relative and we are not in the same directory + # as the executable. Assume executable is in the build + # directory and make srcdir absolute. + srcdir = os.path.join(base, _CONFIG_VARS['srcdir']) + _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir) + + if sys.platform == 'darwin': + kernel_version = os.uname()[2] # Kernel version (8.4.3) + major_version = int(kernel_version.split('.')[0]) + + if major_version < 8: + # On Mac OS X before 10.4, check if -arch and -isysroot + # are in CFLAGS or LDFLAGS and remove them if they are. + # This is needed when building extensions on a 10.3 system + # using a universal build of python. + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + flags = _CONFIG_VARS[key] + flags = re.sub(r'-arch\s+\w+\s', ' ', flags) + flags = re.sub('-isysroot [^ \t]*', ' ', flags) + _CONFIG_VARS[key] = flags + else: + # Allow the user to override the architecture flags using + # an environment variable. + # NOTE: This name was introduced by Apple in OSX 10.5 and + # is used by several scripting languages distributed with + # that OS release. + if 'ARCHFLAGS' in os.environ: + arch = os.environ['ARCHFLAGS'] + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _CONFIG_VARS[key] + flags = re.sub(r'-arch\s+\w+\s', ' ', flags) + flags = flags + ' ' + arch + _CONFIG_VARS[key] = flags + + # If we're on OSX 10.5 or later and the user tries to + # compiles an extension using an SDK that is not present + # on the current machine it is better to not use an SDK + # than to fail. + # + # The major usecase for this is users using a Python.org + # binary installer on OSX 10.6: that installer uses + # the 10.4u SDK, but that SDK is not installed by default + # when you install Xcode. + # + CFLAGS = _CONFIG_VARS.get('CFLAGS', '') + m = re.search(r'-isysroot\s+(\S+)', CFLAGS) + if m is not None: + sdk = m.group(1) + if not os.path.exists(sdk): + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _CONFIG_VARS[key] + flags = re.sub(r'-isysroot\s+\S+(\s|$)', ' ', flags) + _CONFIG_VARS[key] = flags + + if args: + vals = [] + for name in args: + vals.append(_CONFIG_VARS.get(name)) + return vals + else: + return _CONFIG_VARS + + +def get_config_var(name): + """Return the value of a single variable using the dictionary returned by + 'get_config_vars()'. + + Equivalent to get_config_vars().get(name) + """ + return get_config_vars().get(name) + + +def get_platform(): + """Return a string that identifies the current platform. + + This is used mainly to distinguish platform-specific build directories and + platform-specific built distributions. Typically includes the OS name + and version and the architecture (as supplied by 'os.uname()'), + although the exact information included depends on the OS; eg. for IRIX + the architecture isn't particularly important (IRIX only runs on SGI + hardware), but for Linux the kernel version isn't particularly + important. + + Examples of returned values: + linux-i586 + linux-alpha (?) + solaris-2.6-sun4u + irix-5.3 + irix64-6.2 + + Windows will return one of: + win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) + win-ia64 (64bit Windows on Itanium) + win32 (all others - specifically, sys.platform is returned) + + For other non-POSIX platforms, currently just returns 'sys.platform'. + """ + if os.name == 'nt': + # sniff sys.version for architecture. + prefix = " bit (" + i = sys.version.find(prefix) + if i == -1: + return sys.platform + j = sys.version.find(")", i) + look = sys.version[i+len(prefix):j].lower() + if look == 'amd64': + return 'win-amd64' + if look == 'itanium': + return 'win-ia64' + return sys.platform + + if os.name != "posix" or not hasattr(os, 'uname'): + # XXX what about the architecture? NT is Intel or Alpha, + # Mac OS is M68k or PPC, etc. + return sys.platform + + # Try to distinguish various flavours of Unix + osname, host, release, version, machine = os.uname() + + # Convert the OS name to lowercase, remove '/' characters + # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") + osname = osname.lower().replace('/', '') + machine = machine.replace(' ', '_') + machine = machine.replace('/', '-') + + if osname[:5] == "linux": + # At least on Linux/Intel, 'machine' is the processor -- + # i386, etc. + # XXX what about Alpha, SPARC, etc? + return "%s-%s" % (osname, machine) + elif osname[:5] == "sunos": + if release[0] >= "5": # SunOS 5 == Solaris 2 + osname = "solaris" + release = "%d.%s" % (int(release[0]) - 3, release[2:]) + # fall through to standard osname-release-machine representation + elif osname[:4] == "irix": # could be "irix64"! + return "%s-%s" % (osname, release) + elif osname[:3] == "aix": + return "%s-%s.%s" % (osname, version, release) + elif osname[:6] == "cygwin": + osname = "cygwin" + rel_re = re.compile(r'[\d.]+') + m = rel_re.match(release) + if m: + release = m.group() + elif osname[:6] == "darwin": + # + # For our purposes, we'll assume that the system version from + # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set + # to. This makes the compatibility story a bit more sane because the + # machine is going to compile and link as if it were + # MACOSX_DEPLOYMENT_TARGET. + cfgvars = get_config_vars() + macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') + + if True: + # Always calculate the release of the running machine, + # needed to determine if we can build fat binaries or not. + + macrelease = macver + # Get the system version. Reading this plist is a documented + # way to get the system version (see the documentation for + # the Gestalt Manager) + try: + f = open('/System/Library/CoreServices/SystemVersion.plist') + except IOError: + # We're on a plain darwin box, fall back to the default + # behaviour. + pass + else: + try: + m = re.search(r'<key>ProductUserVisibleVersion</key>\s*' + r'<string>(.*?)</string>', f.read()) + finally: + f.close() + if m is not None: + macrelease = '.'.join(m.group(1).split('.')[:2]) + # else: fall back to the default behaviour + + if not macver: + macver = macrelease + + if macver: + release = macver + osname = "macosx" + + if ((macrelease + '.') >= '10.4.' and + '-arch' in get_config_vars().get('CFLAGS', '').strip()): + # The universal build will build fat binaries, but not on + # systems before 10.4 + # + # Try to detect 4-way universal builds, those have machine-type + # 'universal' instead of 'fat'. + + machine = 'fat' + cflags = get_config_vars().get('CFLAGS') + + archs = re.findall(r'-arch\s+(\S+)', cflags) + archs = tuple(sorted(set(archs))) + + if len(archs) == 1: + machine = archs[0] + elif archs == ('i386', 'ppc'): + machine = 'fat' + elif archs == ('i386', 'x86_64'): + machine = 'intel' + elif archs == ('i386', 'ppc', 'x86_64'): + machine = 'fat3' + elif archs == ('ppc64', 'x86_64'): + machine = 'fat64' + elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'): + machine = 'universal' + else: + raise ValueError( + "Don't know machine value for archs=%r" % (archs,)) + + elif machine == 'i386': + # On OSX the machine type returned by uname is always the + # 32-bit variant, even if the executable architecture is + # the 64-bit variant + if sys.maxsize >= 2**32: + machine = 'x86_64' + + elif machine in ('PowerPC', 'Power_Macintosh'): + # Pick a sane name for the PPC architecture. + # See 'i386' case + if sys.maxsize >= 2**32: + machine = 'ppc64' + else: + machine = 'ppc' + + return "%s-%s-%s" % (osname, release, machine) + + +def get_python_version(): + return _PY_VERSION_SHORT + + +def _print_dict(title, data): + for index, (key, value) in enumerate(sorted(data.items())): + if index == 0: + print('%s: ' % (title)) + print('\t%s = "%s"' % (key, value)) + + +def _main(): + """Display all information sysconfig detains.""" + print('Platform: "%s"' % get_platform()) + print('Python version: "%s"' % get_python_version()) + print('Current installation scheme: "%s"' % _get_default_scheme()) + print() + _print_dict('Paths', get_paths()) + print() + _print_dict('Variables', get_config_vars()) + + +if __name__ == '__main__': + _main() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/tarfile.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/tarfile.py new file mode 100644 index 0000000..d66d856 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/tarfile.py @@ -0,0 +1,2607 @@ +#------------------------------------------------------------------- +# tarfile.py +#------------------------------------------------------------------- +# Copyright (C) 2002 Lars Gustaebel <lars@gustaebel.de> +# All rights reserved. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +from __future__ import print_function + +"""Read from and write to tar format archives. +""" + +__version__ = "$Revision$" + +version = "0.9.0" +__author__ = "Lars Gust\u00e4bel (lars@gustaebel.de)" +__date__ = "$Date: 2011-02-25 17:42:01 +0200 (Fri, 25 Feb 2011) $" +__cvsid__ = "$Id: tarfile.py 88586 2011-02-25 15:42:01Z marc-andre.lemburg $" +__credits__ = "Gustavo Niemeyer, Niels Gust\u00e4bel, Richard Townsend." + +#--------- +# Imports +#--------- +import sys +import os +import stat +import errno +import time +import struct +import copy +import re + +try: + import grp, pwd +except ImportError: + grp = pwd = None + +# os.symlink on Windows prior to 6.0 raises NotImplementedError +symlink_exception = (AttributeError, NotImplementedError) +try: + # WindowsError (1314) will be raised if the caller does not hold the + # SeCreateSymbolicLinkPrivilege privilege + symlink_exception += (WindowsError,) +except NameError: + pass + +# from tarfile import * +__all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"] + +if sys.version_info[0] < 3: + import __builtin__ as builtins +else: + import builtins + +_open = builtins.open # Since 'open' is TarFile.open + +#--------------------------------------------------------- +# tar constants +#--------------------------------------------------------- +NUL = b"\0" # the null character +BLOCKSIZE = 512 # length of processing blocks +RECORDSIZE = BLOCKSIZE * 20 # length of records +GNU_MAGIC = b"ustar \0" # magic gnu tar string +POSIX_MAGIC = b"ustar\x0000" # magic posix tar string + +LENGTH_NAME = 100 # maximum length of a filename +LENGTH_LINK = 100 # maximum length of a linkname +LENGTH_PREFIX = 155 # maximum length of the prefix field + +REGTYPE = b"0" # regular file +AREGTYPE = b"\0" # regular file +LNKTYPE = b"1" # link (inside tarfile) +SYMTYPE = b"2" # symbolic link +CHRTYPE = b"3" # character special device +BLKTYPE = b"4" # block special device +DIRTYPE = b"5" # directory +FIFOTYPE = b"6" # fifo special device +CONTTYPE = b"7" # contiguous file + +GNUTYPE_LONGNAME = b"L" # GNU tar longname +GNUTYPE_LONGLINK = b"K" # GNU tar longlink +GNUTYPE_SPARSE = b"S" # GNU tar sparse file + +XHDTYPE = b"x" # POSIX.1-2001 extended header +XGLTYPE = b"g" # POSIX.1-2001 global header +SOLARIS_XHDTYPE = b"X" # Solaris extended header + +USTAR_FORMAT = 0 # POSIX.1-1988 (ustar) format +GNU_FORMAT = 1 # GNU tar format +PAX_FORMAT = 2 # POSIX.1-2001 (pax) format +DEFAULT_FORMAT = GNU_FORMAT + +#--------------------------------------------------------- +# tarfile constants +#--------------------------------------------------------- +# File types that tarfile supports: +SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE, + SYMTYPE, DIRTYPE, FIFOTYPE, + CONTTYPE, CHRTYPE, BLKTYPE, + GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, + GNUTYPE_SPARSE) + +# File types that will be treated as a regular file. +REGULAR_TYPES = (REGTYPE, AREGTYPE, + CONTTYPE, GNUTYPE_SPARSE) + +# File types that are part of the GNU tar format. +GNU_TYPES = (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, + GNUTYPE_SPARSE) + +# Fields from a pax header that override a TarInfo attribute. +PAX_FIELDS = ("path", "linkpath", "size", "mtime", + "uid", "gid", "uname", "gname") + +# Fields from a pax header that are affected by hdrcharset. +PAX_NAME_FIELDS = set(("path", "linkpath", "uname", "gname")) + +# Fields in a pax header that are numbers, all other fields +# are treated as strings. +PAX_NUMBER_FIELDS = { + "atime": float, + "ctime": float, + "mtime": float, + "uid": int, + "gid": int, + "size": int +} + +#--------------------------------------------------------- +# Bits used in the mode field, values in octal. +#--------------------------------------------------------- +S_IFLNK = 0o120000 # symbolic link +S_IFREG = 0o100000 # regular file +S_IFBLK = 0o060000 # block device +S_IFDIR = 0o040000 # directory +S_IFCHR = 0o020000 # character device +S_IFIFO = 0o010000 # fifo + +TSUID = 0o4000 # set UID on execution +TSGID = 0o2000 # set GID on execution +TSVTX = 0o1000 # reserved + +TUREAD = 0o400 # read by owner +TUWRITE = 0o200 # write by owner +TUEXEC = 0o100 # execute/search by owner +TGREAD = 0o040 # read by group +TGWRITE = 0o020 # write by group +TGEXEC = 0o010 # execute/search by group +TOREAD = 0o004 # read by other +TOWRITE = 0o002 # write by other +TOEXEC = 0o001 # execute/search by other + +#--------------------------------------------------------- +# initialization +#--------------------------------------------------------- +if os.name in ("nt", "ce"): + ENCODING = "utf-8" +else: + ENCODING = sys.getfilesystemencoding() + +#--------------------------------------------------------- +# Some useful functions +#--------------------------------------------------------- + +def stn(s, length, encoding, errors): + """Convert a string to a null-terminated bytes object. + """ + s = s.encode(encoding, errors) + return s[:length] + (length - len(s)) * NUL + +def nts(s, encoding, errors): + """Convert a null-terminated bytes object to a string. + """ + p = s.find(b"\0") + if p != -1: + s = s[:p] + return s.decode(encoding, errors) + +def nti(s): + """Convert a number field to a python number. + """ + # There are two possible encodings for a number field, see + # itn() below. + if s[0] != chr(0o200): + try: + n = int(nts(s, "ascii", "strict") or "0", 8) + except ValueError: + raise InvalidHeaderError("invalid header") + else: + n = 0 + for i in range(len(s) - 1): + n <<= 8 + n += ord(s[i + 1]) + return n + +def itn(n, digits=8, format=DEFAULT_FORMAT): + """Convert a python number to a number field. + """ + # POSIX 1003.1-1988 requires numbers to be encoded as a string of + # octal digits followed by a null-byte, this allows values up to + # (8**(digits-1))-1. GNU tar allows storing numbers greater than + # that if necessary. A leading 0o200 byte indicates this particular + # encoding, the following digits-1 bytes are a big-endian + # representation. This allows values up to (256**(digits-1))-1. + if 0 <= n < 8 ** (digits - 1): + s = ("%0*o" % (digits - 1, n)).encode("ascii") + NUL + else: + if format != GNU_FORMAT or n >= 256 ** (digits - 1): + raise ValueError("overflow in number field") + + if n < 0: + # XXX We mimic GNU tar's behaviour with negative numbers, + # this could raise OverflowError. + n = struct.unpack("L", struct.pack("l", n))[0] + + s = bytearray() + for i in range(digits - 1): + s.insert(0, n & 0o377) + n >>= 8 + s.insert(0, 0o200) + return s + +def calc_chksums(buf): + """Calculate the checksum for a member's header by summing up all + characters except for the chksum field which is treated as if + it was filled with spaces. According to the GNU tar sources, + some tars (Sun and NeXT) calculate chksum with signed char, + which will be different if there are chars in the buffer with + the high bit set. So we calculate two checksums, unsigned and + signed. + """ + unsigned_chksum = 256 + sum(struct.unpack("148B", buf[:148]) + struct.unpack("356B", buf[156:512])) + signed_chksum = 256 + sum(struct.unpack("148b", buf[:148]) + struct.unpack("356b", buf[156:512])) + return unsigned_chksum, signed_chksum + +def copyfileobj(src, dst, length=None): + """Copy length bytes from fileobj src to fileobj dst. + If length is None, copy the entire content. + """ + if length == 0: + return + if length is None: + while True: + buf = src.read(16*1024) + if not buf: + break + dst.write(buf) + return + + BUFSIZE = 16 * 1024 + blocks, remainder = divmod(length, BUFSIZE) + for b in range(blocks): + buf = src.read(BUFSIZE) + if len(buf) < BUFSIZE: + raise IOError("end of file reached") + dst.write(buf) + + if remainder != 0: + buf = src.read(remainder) + if len(buf) < remainder: + raise IOError("end of file reached") + dst.write(buf) + return + +filemode_table = ( + ((S_IFLNK, "l"), + (S_IFREG, "-"), + (S_IFBLK, "b"), + (S_IFDIR, "d"), + (S_IFCHR, "c"), + (S_IFIFO, "p")), + + ((TUREAD, "r"),), + ((TUWRITE, "w"),), + ((TUEXEC|TSUID, "s"), + (TSUID, "S"), + (TUEXEC, "x")), + + ((TGREAD, "r"),), + ((TGWRITE, "w"),), + ((TGEXEC|TSGID, "s"), + (TSGID, "S"), + (TGEXEC, "x")), + + ((TOREAD, "r"),), + ((TOWRITE, "w"),), + ((TOEXEC|TSVTX, "t"), + (TSVTX, "T"), + (TOEXEC, "x")) +) + +def filemode(mode): + """Convert a file's mode to a string of the form + -rwxrwxrwx. + Used by TarFile.list() + """ + perm = [] + for table in filemode_table: + for bit, char in table: + if mode & bit == bit: + perm.append(char) + break + else: + perm.append("-") + return "".join(perm) + +class TarError(Exception): + """Base exception.""" + pass +class ExtractError(TarError): + """General exception for extract errors.""" + pass +class ReadError(TarError): + """Exception for unreadable tar archives.""" + pass +class CompressionError(TarError): + """Exception for unavailable compression methods.""" + pass +class StreamError(TarError): + """Exception for unsupported operations on stream-like TarFiles.""" + pass +class HeaderError(TarError): + """Base exception for header errors.""" + pass +class EmptyHeaderError(HeaderError): + """Exception for empty headers.""" + pass +class TruncatedHeaderError(HeaderError): + """Exception for truncated headers.""" + pass +class EOFHeaderError(HeaderError): + """Exception for end of file headers.""" + pass +class InvalidHeaderError(HeaderError): + """Exception for invalid headers.""" + pass +class SubsequentHeaderError(HeaderError): + """Exception for missing and invalid extended headers.""" + pass + +#--------------------------- +# internal stream interface +#--------------------------- +class _LowLevelFile(object): + """Low-level file object. Supports reading and writing. + It is used instead of a regular file object for streaming + access. + """ + + def __init__(self, name, mode): + mode = { + "r": os.O_RDONLY, + "w": os.O_WRONLY | os.O_CREAT | os.O_TRUNC, + }[mode] + if hasattr(os, "O_BINARY"): + mode |= os.O_BINARY + self.fd = os.open(name, mode, 0o666) + + def close(self): + os.close(self.fd) + + def read(self, size): + return os.read(self.fd, size) + + def write(self, s): + os.write(self.fd, s) + +class _Stream(object): + """Class that serves as an adapter between TarFile and + a stream-like object. The stream-like object only + needs to have a read() or write() method and is accessed + blockwise. Use of gzip or bzip2 compression is possible. + A stream-like object could be for example: sys.stdin, + sys.stdout, a socket, a tape device etc. + + _Stream is intended to be used only internally. + """ + + def __init__(self, name, mode, comptype, fileobj, bufsize): + """Construct a _Stream object. + """ + self._extfileobj = True + if fileobj is None: + fileobj = _LowLevelFile(name, mode) + self._extfileobj = False + + if comptype == '*': + # Enable transparent compression detection for the + # stream interface + fileobj = _StreamProxy(fileobj) + comptype = fileobj.getcomptype() + + self.name = name or "" + self.mode = mode + self.comptype = comptype + self.fileobj = fileobj + self.bufsize = bufsize + self.buf = b"" + self.pos = 0 + self.closed = False + + try: + if comptype == "gz": + try: + import zlib + except ImportError: + raise CompressionError("zlib module is not available") + self.zlib = zlib + self.crc = zlib.crc32(b"") + if mode == "r": + self._init_read_gz() + else: + self._init_write_gz() + + if comptype == "bz2": + try: + import bz2 + except ImportError: + raise CompressionError("bz2 module is not available") + if mode == "r": + self.dbuf = b"" + self.cmp = bz2.BZ2Decompressor() + else: + self.cmp = bz2.BZ2Compressor() + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise + + def __del__(self): + if hasattr(self, "closed") and not self.closed: + self.close() + + def _init_write_gz(self): + """Initialize for writing with gzip compression. + """ + self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED, + -self.zlib.MAX_WBITS, + self.zlib.DEF_MEM_LEVEL, + 0) + timestamp = struct.pack("<L", int(time.time())) + self.__write(b"\037\213\010\010" + timestamp + b"\002\377") + if self.name.endswith(".gz"): + self.name = self.name[:-3] + # RFC1952 says we must use ISO-8859-1 for the FNAME field. + self.__write(self.name.encode("iso-8859-1", "replace") + NUL) + + def write(self, s): + """Write string s to the stream. + """ + if self.comptype == "gz": + self.crc = self.zlib.crc32(s, self.crc) + self.pos += len(s) + if self.comptype != "tar": + s = self.cmp.compress(s) + self.__write(s) + + def __write(self, s): + """Write string s to the stream if a whole new block + is ready to be written. + """ + self.buf += s + while len(self.buf) > self.bufsize: + self.fileobj.write(self.buf[:self.bufsize]) + self.buf = self.buf[self.bufsize:] + + def close(self): + """Close the _Stream object. No operation should be + done on it afterwards. + """ + if self.closed: + return + + if self.mode == "w" and self.comptype != "tar": + self.buf += self.cmp.flush() + + if self.mode == "w" and self.buf: + self.fileobj.write(self.buf) + self.buf = b"" + if self.comptype == "gz": + # The native zlib crc is an unsigned 32-bit integer, but + # the Python wrapper implicitly casts that to a signed C + # long. So, on a 32-bit box self.crc may "look negative", + # while the same crc on a 64-bit box may "look positive". + # To avoid irksome warnings from the `struct` module, force + # it to look positive on all boxes. + self.fileobj.write(struct.pack("<L", self.crc & 0xffffffff)) + self.fileobj.write(struct.pack("<L", self.pos & 0xffffFFFF)) + + if not self._extfileobj: + self.fileobj.close() + + self.closed = True + + def _init_read_gz(self): + """Initialize for reading a gzip compressed fileobj. + """ + self.cmp = self.zlib.decompressobj(-self.zlib.MAX_WBITS) + self.dbuf = b"" + + # taken from gzip.GzipFile with some alterations + if self.__read(2) != b"\037\213": + raise ReadError("not a gzip file") + if self.__read(1) != b"\010": + raise CompressionError("unsupported compression method") + + flag = ord(self.__read(1)) + self.__read(6) + + if flag & 4: + xlen = ord(self.__read(1)) + 256 * ord(self.__read(1)) + self.read(xlen) + if flag & 8: + while True: + s = self.__read(1) + if not s or s == NUL: + break + if flag & 16: + while True: + s = self.__read(1) + if not s or s == NUL: + break + if flag & 2: + self.__read(2) + + def tell(self): + """Return the stream's file pointer position. + """ + return self.pos + + def seek(self, pos=0): + """Set the stream's file pointer to pos. Negative seeking + is forbidden. + """ + if pos - self.pos >= 0: + blocks, remainder = divmod(pos - self.pos, self.bufsize) + for i in range(blocks): + self.read(self.bufsize) + self.read(remainder) + else: + raise StreamError("seeking backwards is not allowed") + return self.pos + + def read(self, size=None): + """Return the next size number of bytes from the stream. + If size is not defined, return all bytes of the stream + up to EOF. + """ + if size is None: + t = [] + while True: + buf = self._read(self.bufsize) + if not buf: + break + t.append(buf) + buf = "".join(t) + else: + buf = self._read(size) + self.pos += len(buf) + return buf + + def _read(self, size): + """Return size bytes from the stream. + """ + if self.comptype == "tar": + return self.__read(size) + + c = len(self.dbuf) + while c < size: + buf = self.__read(self.bufsize) + if not buf: + break + try: + buf = self.cmp.decompress(buf) + except IOError: + raise ReadError("invalid compressed data") + self.dbuf += buf + c += len(buf) + buf = self.dbuf[:size] + self.dbuf = self.dbuf[size:] + return buf + + def __read(self, size): + """Return size bytes from stream. If internal buffer is empty, + read another block from the stream. + """ + c = len(self.buf) + while c < size: + buf = self.fileobj.read(self.bufsize) + if not buf: + break + self.buf += buf + c += len(buf) + buf = self.buf[:size] + self.buf = self.buf[size:] + return buf +# class _Stream + +class _StreamProxy(object): + """Small proxy class that enables transparent compression + detection for the Stream interface (mode 'r|*'). + """ + + def __init__(self, fileobj): + self.fileobj = fileobj + self.buf = self.fileobj.read(BLOCKSIZE) + + def read(self, size): + self.read = self.fileobj.read + return self.buf + + def getcomptype(self): + if self.buf.startswith(b"\037\213\010"): + return "gz" + if self.buf.startswith(b"BZh91"): + return "bz2" + return "tar" + + def close(self): + self.fileobj.close() +# class StreamProxy + +class _BZ2Proxy(object): + """Small proxy class that enables external file object + support for "r:bz2" and "w:bz2" modes. This is actually + a workaround for a limitation in bz2 module's BZ2File + class which (unlike gzip.GzipFile) has no support for + a file object argument. + """ + + blocksize = 16 * 1024 + + def __init__(self, fileobj, mode): + self.fileobj = fileobj + self.mode = mode + self.name = getattr(self.fileobj, "name", None) + self.init() + + def init(self): + import bz2 + self.pos = 0 + if self.mode == "r": + self.bz2obj = bz2.BZ2Decompressor() + self.fileobj.seek(0) + self.buf = b"" + else: + self.bz2obj = bz2.BZ2Compressor() + + def read(self, size): + x = len(self.buf) + while x < size: + raw = self.fileobj.read(self.blocksize) + if not raw: + break + data = self.bz2obj.decompress(raw) + self.buf += data + x += len(data) + + buf = self.buf[:size] + self.buf = self.buf[size:] + self.pos += len(buf) + return buf + + def seek(self, pos): + if pos < self.pos: + self.init() + self.read(pos - self.pos) + + def tell(self): + return self.pos + + def write(self, data): + self.pos += len(data) + raw = self.bz2obj.compress(data) + self.fileobj.write(raw) + + def close(self): + if self.mode == "w": + raw = self.bz2obj.flush() + self.fileobj.write(raw) +# class _BZ2Proxy + +#------------------------ +# Extraction file object +#------------------------ +class _FileInFile(object): + """A thin wrapper around an existing file object that + provides a part of its data as an individual file + object. + """ + + def __init__(self, fileobj, offset, size, blockinfo=None): + self.fileobj = fileobj + self.offset = offset + self.size = size + self.position = 0 + + if blockinfo is None: + blockinfo = [(0, size)] + + # Construct a map with data and zero blocks. + self.map_index = 0 + self.map = [] + lastpos = 0 + realpos = self.offset + for offset, size in blockinfo: + if offset > lastpos: + self.map.append((False, lastpos, offset, None)) + self.map.append((True, offset, offset + size, realpos)) + realpos += size + lastpos = offset + size + if lastpos < self.size: + self.map.append((False, lastpos, self.size, None)) + + def seekable(self): + if not hasattr(self.fileobj, "seekable"): + # XXX gzip.GzipFile and bz2.BZ2File + return True + return self.fileobj.seekable() + + def tell(self): + """Return the current file position. + """ + return self.position + + def seek(self, position): + """Seek to a position in the file. + """ + self.position = position + + def read(self, size=None): + """Read data from the file. + """ + if size is None: + size = self.size - self.position + else: + size = min(size, self.size - self.position) + + buf = b"" + while size > 0: + while True: + data, start, stop, offset = self.map[self.map_index] + if start <= self.position < stop: + break + else: + self.map_index += 1 + if self.map_index == len(self.map): + self.map_index = 0 + length = min(size, stop - self.position) + if data: + self.fileobj.seek(offset + (self.position - start)) + buf += self.fileobj.read(length) + else: + buf += NUL * length + size -= length + self.position += length + return buf +#class _FileInFile + + +class ExFileObject(object): + """File-like object for reading an archive member. + Is returned by TarFile.extractfile(). + """ + blocksize = 1024 + + def __init__(self, tarfile, tarinfo): + self.fileobj = _FileInFile(tarfile.fileobj, + tarinfo.offset_data, + tarinfo.size, + tarinfo.sparse) + self.name = tarinfo.name + self.mode = "r" + self.closed = False + self.size = tarinfo.size + + self.position = 0 + self.buffer = b"" + + def readable(self): + return True + + def writable(self): + return False + + def seekable(self): + return self.fileobj.seekable() + + def read(self, size=None): + """Read at most size bytes from the file. If size is not + present or None, read all data until EOF is reached. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + buf = b"" + if self.buffer: + if size is None: + buf = self.buffer + self.buffer = b"" + else: + buf = self.buffer[:size] + self.buffer = self.buffer[size:] + + if size is None: + buf += self.fileobj.read() + else: + buf += self.fileobj.read(size - len(buf)) + + self.position += len(buf) + return buf + + # XXX TextIOWrapper uses the read1() method. + read1 = read + + def readline(self, size=-1): + """Read one entire line from the file. If size is present + and non-negative, return a string with at most that + size, which may be an incomplete line. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + pos = self.buffer.find(b"\n") + 1 + if pos == 0: + # no newline found. + while True: + buf = self.fileobj.read(self.blocksize) + self.buffer += buf + if not buf or b"\n" in buf: + pos = self.buffer.find(b"\n") + 1 + if pos == 0: + # no newline found. + pos = len(self.buffer) + break + + if size != -1: + pos = min(size, pos) + + buf = self.buffer[:pos] + self.buffer = self.buffer[pos:] + self.position += len(buf) + return buf + + def readlines(self): + """Return a list with all remaining lines. + """ + result = [] + while True: + line = self.readline() + if not line: break + result.append(line) + return result + + def tell(self): + """Return the current file position. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + return self.position + + def seek(self, pos, whence=os.SEEK_SET): + """Seek to a position in the file. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + if whence == os.SEEK_SET: + self.position = min(max(pos, 0), self.size) + elif whence == os.SEEK_CUR: + if pos < 0: + self.position = max(self.position + pos, 0) + else: + self.position = min(self.position + pos, self.size) + elif whence == os.SEEK_END: + self.position = max(min(self.size + pos, self.size), 0) + else: + raise ValueError("Invalid argument") + + self.buffer = b"" + self.fileobj.seek(self.position) + + def close(self): + """Close the file object. + """ + self.closed = True + + def __iter__(self): + """Get an iterator over the file's lines. + """ + while True: + line = self.readline() + if not line: + break + yield line +#class ExFileObject + +#------------------ +# Exported Classes +#------------------ +class TarInfo(object): + """Informational class which holds the details about an + archive member given by a tar header block. + TarInfo objects are returned by TarFile.getmember(), + TarFile.getmembers() and TarFile.gettarinfo() and are + usually created internally. + """ + + __slots__ = ("name", "mode", "uid", "gid", "size", "mtime", + "chksum", "type", "linkname", "uname", "gname", + "devmajor", "devminor", + "offset", "offset_data", "pax_headers", "sparse", + "tarfile", "_sparse_structs", "_link_target") + + def __init__(self, name=""): + """Construct a TarInfo object. name is the optional name + of the member. + """ + self.name = name # member name + self.mode = 0o644 # file permissions + self.uid = 0 # user id + self.gid = 0 # group id + self.size = 0 # file size + self.mtime = 0 # modification time + self.chksum = 0 # header checksum + self.type = REGTYPE # member type + self.linkname = "" # link name + self.uname = "" # user name + self.gname = "" # group name + self.devmajor = 0 # device major number + self.devminor = 0 # device minor number + + self.offset = 0 # the tar header starts here + self.offset_data = 0 # the file's data starts here + + self.sparse = None # sparse member information + self.pax_headers = {} # pax header information + + # In pax headers the "name" and "linkname" field are called + # "path" and "linkpath". + def _getpath(self): + return self.name + def _setpath(self, name): + self.name = name + path = property(_getpath, _setpath) + + def _getlinkpath(self): + return self.linkname + def _setlinkpath(self, linkname): + self.linkname = linkname + linkpath = property(_getlinkpath, _setlinkpath) + + def __repr__(self): + return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self)) + + def get_info(self): + """Return the TarInfo's attributes as a dictionary. + """ + info = { + "name": self.name, + "mode": self.mode & 0o7777, + "uid": self.uid, + "gid": self.gid, + "size": self.size, + "mtime": self.mtime, + "chksum": self.chksum, + "type": self.type, + "linkname": self.linkname, + "uname": self.uname, + "gname": self.gname, + "devmajor": self.devmajor, + "devminor": self.devminor + } + + if info["type"] == DIRTYPE and not info["name"].endswith("/"): + info["name"] += "/" + + return info + + def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="surrogateescape"): + """Return a tar header as a string of 512 byte blocks. + """ + info = self.get_info() + + if format == USTAR_FORMAT: + return self.create_ustar_header(info, encoding, errors) + elif format == GNU_FORMAT: + return self.create_gnu_header(info, encoding, errors) + elif format == PAX_FORMAT: + return self.create_pax_header(info, encoding) + else: + raise ValueError("invalid format") + + def create_ustar_header(self, info, encoding, errors): + """Return the object as a ustar header block. + """ + info["magic"] = POSIX_MAGIC + + if len(info["linkname"]) > LENGTH_LINK: + raise ValueError("linkname is too long") + + if len(info["name"]) > LENGTH_NAME: + info["prefix"], info["name"] = self._posix_split_name(info["name"]) + + return self._create_header(info, USTAR_FORMAT, encoding, errors) + + def create_gnu_header(self, info, encoding, errors): + """Return the object as a GNU header block sequence. + """ + info["magic"] = GNU_MAGIC + + buf = b"" + if len(info["linkname"]) > LENGTH_LINK: + buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK, encoding, errors) + + if len(info["name"]) > LENGTH_NAME: + buf += self._create_gnu_long_header(info["name"], GNUTYPE_LONGNAME, encoding, errors) + + return buf + self._create_header(info, GNU_FORMAT, encoding, errors) + + def create_pax_header(self, info, encoding): + """Return the object as a ustar header block. If it cannot be + represented this way, prepend a pax extended header sequence + with supplement information. + """ + info["magic"] = POSIX_MAGIC + pax_headers = self.pax_headers.copy() + + # Test string fields for values that exceed the field length or cannot + # be represented in ASCII encoding. + for name, hname, length in ( + ("name", "path", LENGTH_NAME), ("linkname", "linkpath", LENGTH_LINK), + ("uname", "uname", 32), ("gname", "gname", 32)): + + if hname in pax_headers: + # The pax header has priority. + continue + + # Try to encode the string as ASCII. + try: + info[name].encode("ascii", "strict") + except UnicodeEncodeError: + pax_headers[hname] = info[name] + continue + + if len(info[name]) > length: + pax_headers[hname] = info[name] + + # Test number fields for values that exceed the field limit or values + # that like to be stored as float. + for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)): + if name in pax_headers: + # The pax header has priority. Avoid overflow. + info[name] = 0 + continue + + val = info[name] + if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float): + pax_headers[name] = str(val) + info[name] = 0 + + # Create a pax extended header if necessary. + if pax_headers: + buf = self._create_pax_generic_header(pax_headers, XHDTYPE, encoding) + else: + buf = b"" + + return buf + self._create_header(info, USTAR_FORMAT, "ascii", "replace") + + @classmethod + def create_pax_global_header(cls, pax_headers): + """Return the object as a pax global header block sequence. + """ + return cls._create_pax_generic_header(pax_headers, XGLTYPE, "utf8") + + def _posix_split_name(self, name): + """Split a name longer than 100 chars into a prefix + and a name part. + """ + prefix = name[:LENGTH_PREFIX + 1] + while prefix and prefix[-1] != "/": + prefix = prefix[:-1] + + name = name[len(prefix):] + prefix = prefix[:-1] + + if not prefix or len(name) > LENGTH_NAME: + raise ValueError("name is too long") + return prefix, name + + @staticmethod + def _create_header(info, format, encoding, errors): + """Return a header block. info is a dictionary with file + information, format must be one of the *_FORMAT constants. + """ + parts = [ + stn(info.get("name", ""), 100, encoding, errors), + itn(info.get("mode", 0) & 0o7777, 8, format), + itn(info.get("uid", 0), 8, format), + itn(info.get("gid", 0), 8, format), + itn(info.get("size", 0), 12, format), + itn(info.get("mtime", 0), 12, format), + b" ", # checksum field + info.get("type", REGTYPE), + stn(info.get("linkname", ""), 100, encoding, errors), + info.get("magic", POSIX_MAGIC), + stn(info.get("uname", ""), 32, encoding, errors), + stn(info.get("gname", ""), 32, encoding, errors), + itn(info.get("devmajor", 0), 8, format), + itn(info.get("devminor", 0), 8, format), + stn(info.get("prefix", ""), 155, encoding, errors) + ] + + buf = struct.pack("%ds" % BLOCKSIZE, b"".join(parts)) + chksum = calc_chksums(buf[-BLOCKSIZE:])[0] + buf = buf[:-364] + ("%06o\0" % chksum).encode("ascii") + buf[-357:] + return buf + + @staticmethod + def _create_payload(payload): + """Return the string payload filled with zero bytes + up to the next 512 byte border. + """ + blocks, remainder = divmod(len(payload), BLOCKSIZE) + if remainder > 0: + payload += (BLOCKSIZE - remainder) * NUL + return payload + + @classmethod + def _create_gnu_long_header(cls, name, type, encoding, errors): + """Return a GNUTYPE_LONGNAME or GNUTYPE_LONGLINK sequence + for name. + """ + name = name.encode(encoding, errors) + NUL + + info = {} + info["name"] = "././@LongLink" + info["type"] = type + info["size"] = len(name) + info["magic"] = GNU_MAGIC + + # create extended header + name blocks. + return cls._create_header(info, USTAR_FORMAT, encoding, errors) + \ + cls._create_payload(name) + + @classmethod + def _create_pax_generic_header(cls, pax_headers, type, encoding): + """Return a POSIX.1-2008 extended or global header sequence + that contains a list of keyword, value pairs. The values + must be strings. + """ + # Check if one of the fields contains surrogate characters and thereby + # forces hdrcharset=BINARY, see _proc_pax() for more information. + binary = False + for keyword, value in pax_headers.items(): + try: + value.encode("utf8", "strict") + except UnicodeEncodeError: + binary = True + break + + records = b"" + if binary: + # Put the hdrcharset field at the beginning of the header. + records += b"21 hdrcharset=BINARY\n" + + for keyword, value in pax_headers.items(): + keyword = keyword.encode("utf8") + if binary: + # Try to restore the original byte representation of `value'. + # Needless to say, that the encoding must match the string. + value = value.encode(encoding, "surrogateescape") + else: + value = value.encode("utf8") + + l = len(keyword) + len(value) + 3 # ' ' + '=' + '\n' + n = p = 0 + while True: + n = l + len(str(p)) + if n == p: + break + p = n + records += bytes(str(p), "ascii") + b" " + keyword + b"=" + value + b"\n" + + # We use a hardcoded "././@PaxHeader" name like star does + # instead of the one that POSIX recommends. + info = {} + info["name"] = "././@PaxHeader" + info["type"] = type + info["size"] = len(records) + info["magic"] = POSIX_MAGIC + + # Create pax header + record blocks. + return cls._create_header(info, USTAR_FORMAT, "ascii", "replace") + \ + cls._create_payload(records) + + @classmethod + def frombuf(cls, buf, encoding, errors): + """Construct a TarInfo object from a 512 byte bytes object. + """ + if len(buf) == 0: + raise EmptyHeaderError("empty header") + if len(buf) != BLOCKSIZE: + raise TruncatedHeaderError("truncated header") + if buf.count(NUL) == BLOCKSIZE: + raise EOFHeaderError("end of file header") + + chksum = nti(buf[148:156]) + if chksum not in calc_chksums(buf): + raise InvalidHeaderError("bad checksum") + + obj = cls() + obj.name = nts(buf[0:100], encoding, errors) + obj.mode = nti(buf[100:108]) + obj.uid = nti(buf[108:116]) + obj.gid = nti(buf[116:124]) + obj.size = nti(buf[124:136]) + obj.mtime = nti(buf[136:148]) + obj.chksum = chksum + obj.type = buf[156:157] + obj.linkname = nts(buf[157:257], encoding, errors) + obj.uname = nts(buf[265:297], encoding, errors) + obj.gname = nts(buf[297:329], encoding, errors) + obj.devmajor = nti(buf[329:337]) + obj.devminor = nti(buf[337:345]) + prefix = nts(buf[345:500], encoding, errors) + + # Old V7 tar format represents a directory as a regular + # file with a trailing slash. + if obj.type == AREGTYPE and obj.name.endswith("/"): + obj.type = DIRTYPE + + # The old GNU sparse format occupies some of the unused + # space in the buffer for up to 4 sparse structures. + # Save the them for later processing in _proc_sparse(). + if obj.type == GNUTYPE_SPARSE: + pos = 386 + structs = [] + for i in range(4): + try: + offset = nti(buf[pos:pos + 12]) + numbytes = nti(buf[pos + 12:pos + 24]) + except ValueError: + break + structs.append((offset, numbytes)) + pos += 24 + isextended = bool(buf[482]) + origsize = nti(buf[483:495]) + obj._sparse_structs = (structs, isextended, origsize) + + # Remove redundant slashes from directories. + if obj.isdir(): + obj.name = obj.name.rstrip("/") + + # Reconstruct a ustar longname. + if prefix and obj.type not in GNU_TYPES: + obj.name = prefix + "/" + obj.name + return obj + + @classmethod + def fromtarfile(cls, tarfile): + """Return the next TarInfo object from TarFile object + tarfile. + """ + buf = tarfile.fileobj.read(BLOCKSIZE) + obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors) + obj.offset = tarfile.fileobj.tell() - BLOCKSIZE + return obj._proc_member(tarfile) + + #-------------------------------------------------------------------------- + # The following are methods that are called depending on the type of a + # member. The entry point is _proc_member() which can be overridden in a + # subclass to add custom _proc_*() methods. A _proc_*() method MUST + # implement the following + # operations: + # 1. Set self.offset_data to the position where the data blocks begin, + # if there is data that follows. + # 2. Set tarfile.offset to the position where the next member's header will + # begin. + # 3. Return self or another valid TarInfo object. + def _proc_member(self, tarfile): + """Choose the right processing method depending on + the type and call it. + """ + if self.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK): + return self._proc_gnulong(tarfile) + elif self.type == GNUTYPE_SPARSE: + return self._proc_sparse(tarfile) + elif self.type in (XHDTYPE, XGLTYPE, SOLARIS_XHDTYPE): + return self._proc_pax(tarfile) + else: + return self._proc_builtin(tarfile) + + def _proc_builtin(self, tarfile): + """Process a builtin type or an unknown type which + will be treated as a regular file. + """ + self.offset_data = tarfile.fileobj.tell() + offset = self.offset_data + if self.isreg() or self.type not in SUPPORTED_TYPES: + # Skip the following data blocks. + offset += self._block(self.size) + tarfile.offset = offset + + # Patch the TarInfo object with saved global + # header information. + self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors) + + return self + + def _proc_gnulong(self, tarfile): + """Process the blocks that hold a GNU longname + or longlink member. + """ + buf = tarfile.fileobj.read(self._block(self.size)) + + # Fetch the next header and process it. + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") + + # Patch the TarInfo object from the next header with + # the longname information. + next.offset = self.offset + if self.type == GNUTYPE_LONGNAME: + next.name = nts(buf, tarfile.encoding, tarfile.errors) + elif self.type == GNUTYPE_LONGLINK: + next.linkname = nts(buf, tarfile.encoding, tarfile.errors) + + return next + + def _proc_sparse(self, tarfile): + """Process a GNU sparse header plus extra headers. + """ + # We already collected some sparse structures in frombuf(). + structs, isextended, origsize = self._sparse_structs + del self._sparse_structs + + # Collect sparse structures from extended header blocks. + while isextended: + buf = tarfile.fileobj.read(BLOCKSIZE) + pos = 0 + for i in range(21): + try: + offset = nti(buf[pos:pos + 12]) + numbytes = nti(buf[pos + 12:pos + 24]) + except ValueError: + break + if offset and numbytes: + structs.append((offset, numbytes)) + pos += 24 + isextended = bool(buf[504]) + self.sparse = structs + + self.offset_data = tarfile.fileobj.tell() + tarfile.offset = self.offset_data + self._block(self.size) + self.size = origsize + return self + + def _proc_pax(self, tarfile): + """Process an extended or global header as described in + POSIX.1-2008. + """ + # Read the header information. + buf = tarfile.fileobj.read(self._block(self.size)) + + # A pax header stores supplemental information for either + # the following file (extended) or all following files + # (global). + if self.type == XGLTYPE: + pax_headers = tarfile.pax_headers + else: + pax_headers = tarfile.pax_headers.copy() + + # Check if the pax header contains a hdrcharset field. This tells us + # the encoding of the path, linkpath, uname and gname fields. Normally, + # these fields are UTF-8 encoded but since POSIX.1-2008 tar + # implementations are allowed to store them as raw binary strings if + # the translation to UTF-8 fails. + match = re.search(br"\d+ hdrcharset=([^\n]+)\n", buf) + if match is not None: + pax_headers["hdrcharset"] = match.group(1).decode("utf8") + + # For the time being, we don't care about anything other than "BINARY". + # The only other value that is currently allowed by the standard is + # "ISO-IR 10646 2000 UTF-8" in other words UTF-8. + hdrcharset = pax_headers.get("hdrcharset") + if hdrcharset == "BINARY": + encoding = tarfile.encoding + else: + encoding = "utf8" + + # Parse pax header information. A record looks like that: + # "%d %s=%s\n" % (length, keyword, value). length is the size + # of the complete record including the length field itself and + # the newline. keyword and value are both UTF-8 encoded strings. + regex = re.compile(br"(\d+) ([^=]+)=") + pos = 0 + while True: + match = regex.match(buf, pos) + if not match: + break + + length, keyword = match.groups() + length = int(length) + value = buf[match.end(2) + 1:match.start(1) + length - 1] + + # Normally, we could just use "utf8" as the encoding and "strict" + # as the error handler, but we better not take the risk. For + # example, GNU tar <= 1.23 is known to store filenames it cannot + # translate to UTF-8 as raw strings (unfortunately without a + # hdrcharset=BINARY header). + # We first try the strict standard encoding, and if that fails we + # fall back on the user's encoding and error handler. + keyword = self._decode_pax_field(keyword, "utf8", "utf8", + tarfile.errors) + if keyword in PAX_NAME_FIELDS: + value = self._decode_pax_field(value, encoding, tarfile.encoding, + tarfile.errors) + else: + value = self._decode_pax_field(value, "utf8", "utf8", + tarfile.errors) + + pax_headers[keyword] = value + pos += length + + # Fetch the next header. + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") + + # Process GNU sparse information. + if "GNU.sparse.map" in pax_headers: + # GNU extended sparse format version 0.1. + self._proc_gnusparse_01(next, pax_headers) + + elif "GNU.sparse.size" in pax_headers: + # GNU extended sparse format version 0.0. + self._proc_gnusparse_00(next, pax_headers, buf) + + elif pax_headers.get("GNU.sparse.major") == "1" and pax_headers.get("GNU.sparse.minor") == "0": + # GNU extended sparse format version 1.0. + self._proc_gnusparse_10(next, pax_headers, tarfile) + + if self.type in (XHDTYPE, SOLARIS_XHDTYPE): + # Patch the TarInfo object with the extended header info. + next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors) + next.offset = self.offset + + if "size" in pax_headers: + # If the extended header replaces the size field, + # we need to recalculate the offset where the next + # header starts. + offset = next.offset_data + if next.isreg() or next.type not in SUPPORTED_TYPES: + offset += next._block(next.size) + tarfile.offset = offset + + return next + + def _proc_gnusparse_00(self, next, pax_headers, buf): + """Process a GNU tar extended sparse header, version 0.0. + """ + offsets = [] + for match in re.finditer(br"\d+ GNU.sparse.offset=(\d+)\n", buf): + offsets.append(int(match.group(1))) + numbytes = [] + for match in re.finditer(br"\d+ GNU.sparse.numbytes=(\d+)\n", buf): + numbytes.append(int(match.group(1))) + next.sparse = list(zip(offsets, numbytes)) + + def _proc_gnusparse_01(self, next, pax_headers): + """Process a GNU tar extended sparse header, version 0.1. + """ + sparse = [int(x) for x in pax_headers["GNU.sparse.map"].split(",")] + next.sparse = list(zip(sparse[::2], sparse[1::2])) + + def _proc_gnusparse_10(self, next, pax_headers, tarfile): + """Process a GNU tar extended sparse header, version 1.0. + """ + fields = None + sparse = [] + buf = tarfile.fileobj.read(BLOCKSIZE) + fields, buf = buf.split(b"\n", 1) + fields = int(fields) + while len(sparse) < fields * 2: + if b"\n" not in buf: + buf += tarfile.fileobj.read(BLOCKSIZE) + number, buf = buf.split(b"\n", 1) + sparse.append(int(number)) + next.offset_data = tarfile.fileobj.tell() + next.sparse = list(zip(sparse[::2], sparse[1::2])) + + def _apply_pax_info(self, pax_headers, encoding, errors): + """Replace fields with supplemental information from a previous + pax extended or global header. + """ + for keyword, value in pax_headers.items(): + if keyword == "GNU.sparse.name": + setattr(self, "path", value) + elif keyword == "GNU.sparse.size": + setattr(self, "size", int(value)) + elif keyword == "GNU.sparse.realsize": + setattr(self, "size", int(value)) + elif keyword in PAX_FIELDS: + if keyword in PAX_NUMBER_FIELDS: + try: + value = PAX_NUMBER_FIELDS[keyword](value) + except ValueError: + value = 0 + if keyword == "path": + value = value.rstrip("/") + setattr(self, keyword, value) + + self.pax_headers = pax_headers.copy() + + def _decode_pax_field(self, value, encoding, fallback_encoding, fallback_errors): + """Decode a single field from a pax record. + """ + try: + return value.decode(encoding, "strict") + except UnicodeDecodeError: + return value.decode(fallback_encoding, fallback_errors) + + def _block(self, count): + """Round up a byte count by BLOCKSIZE and return it, + e.g. _block(834) => 1024. + """ + blocks, remainder = divmod(count, BLOCKSIZE) + if remainder: + blocks += 1 + return blocks * BLOCKSIZE + + def isreg(self): + return self.type in REGULAR_TYPES + def isfile(self): + return self.isreg() + def isdir(self): + return self.type == DIRTYPE + def issym(self): + return self.type == SYMTYPE + def islnk(self): + return self.type == LNKTYPE + def ischr(self): + return self.type == CHRTYPE + def isblk(self): + return self.type == BLKTYPE + def isfifo(self): + return self.type == FIFOTYPE + def issparse(self): + return self.sparse is not None + def isdev(self): + return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE) +# class TarInfo + +class TarFile(object): + """The TarFile Class provides an interface to tar archives. + """ + + debug = 0 # May be set from 0 (no msgs) to 3 (all msgs) + + dereference = False # If true, add content of linked file to the + # tar file, else the link. + + ignore_zeros = False # If true, skips empty or invalid blocks and + # continues processing. + + errorlevel = 1 # If 0, fatal errors only appear in debug + # messages (if debug >= 0). If > 0, errors + # are passed to the caller as exceptions. + + format = DEFAULT_FORMAT # The format to use when creating an archive. + + encoding = ENCODING # Encoding for 8-bit character strings. + + errors = None # Error handler for unicode conversion. + + tarinfo = TarInfo # The default TarInfo class to use. + + fileobject = ExFileObject # The default ExFileObject class to use. + + def __init__(self, name=None, mode="r", fileobj=None, format=None, + tarinfo=None, dereference=None, ignore_zeros=None, encoding=None, + errors="surrogateescape", pax_headers=None, debug=None, errorlevel=None): + """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to + read from an existing archive, 'a' to append data to an existing + file or 'w' to create a new file overwriting an existing one. `mode' + defaults to 'r'. + If `fileobj' is given, it is used for reading or writing data. If it + can be determined, `mode' is overridden by `fileobj's mode. + `fileobj' is not closed, when TarFile is closed. + """ + if len(mode) > 1 or mode not in "raw": + raise ValueError("mode must be 'r', 'a' or 'w'") + self.mode = mode + self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode] + + if not fileobj: + if self.mode == "a" and not os.path.exists(name): + # Create nonexistent files in append mode. + self.mode = "w" + self._mode = "wb" + fileobj = bltn_open(name, self._mode) + self._extfileobj = False + else: + if name is None and hasattr(fileobj, "name"): + name = fileobj.name + if hasattr(fileobj, "mode"): + self._mode = fileobj.mode + self._extfileobj = True + self.name = os.path.abspath(name) if name else None + self.fileobj = fileobj + + # Init attributes. + if format is not None: + self.format = format + if tarinfo is not None: + self.tarinfo = tarinfo + if dereference is not None: + self.dereference = dereference + if ignore_zeros is not None: + self.ignore_zeros = ignore_zeros + if encoding is not None: + self.encoding = encoding + self.errors = errors + + if pax_headers is not None and self.format == PAX_FORMAT: + self.pax_headers = pax_headers + else: + self.pax_headers = {} + + if debug is not None: + self.debug = debug + if errorlevel is not None: + self.errorlevel = errorlevel + + # Init datastructures. + self.closed = False + self.members = [] # list of members as TarInfo objects + self._loaded = False # flag if all members have been read + self.offset = self.fileobj.tell() + # current position in the archive file + self.inodes = {} # dictionary caching the inodes of + # archive members already added + + try: + if self.mode == "r": + self.firstmember = None + self.firstmember = self.next() + + if self.mode == "a": + # Move to the end of the archive, + # before the first empty block. + while True: + self.fileobj.seek(self.offset) + try: + tarinfo = self.tarinfo.fromtarfile(self) + self.members.append(tarinfo) + except EOFHeaderError: + self.fileobj.seek(self.offset) + break + except HeaderError as e: + raise ReadError(str(e)) + + if self.mode in "aw": + self._loaded = True + + if self.pax_headers: + buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) + self.fileobj.write(buf) + self.offset += len(buf) + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise + + #-------------------------------------------------------------------------- + # Below are the classmethods which act as alternate constructors to the + # TarFile class. The open() method is the only one that is needed for + # public use; it is the "super"-constructor and is able to select an + # adequate "sub"-constructor for a particular compression using the mapping + # from OPEN_METH. + # + # This concept allows one to subclass TarFile without losing the comfort of + # the super-constructor. A sub-constructor is registered and made available + # by adding it to the mapping in OPEN_METH. + + @classmethod + def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): + """Open a tar archive for reading, writing or appending. Return + an appropriate TarFile class. + + mode: + 'r' or 'r:*' open for reading with transparent compression + 'r:' open for reading exclusively uncompressed + 'r:gz' open for reading with gzip compression + 'r:bz2' open for reading with bzip2 compression + 'a' or 'a:' open for appending, creating the file if necessary + 'w' or 'w:' open for writing without compression + 'w:gz' open for writing with gzip compression + 'w:bz2' open for writing with bzip2 compression + + 'r|*' open a stream of tar blocks with transparent compression + 'r|' open an uncompressed stream of tar blocks for reading + 'r|gz' open a gzip compressed stream of tar blocks + 'r|bz2' open a bzip2 compressed stream of tar blocks + 'w|' open an uncompressed stream for writing + 'w|gz' open a gzip compressed stream for writing + 'w|bz2' open a bzip2 compressed stream for writing + """ + + if not name and not fileobj: + raise ValueError("nothing to open") + + if mode in ("r", "r:*"): + # Find out which *open() is appropriate for opening the file. + for comptype in cls.OPEN_METH: + func = getattr(cls, cls.OPEN_METH[comptype]) + if fileobj is not None: + saved_pos = fileobj.tell() + try: + return func(name, "r", fileobj, **kwargs) + except (ReadError, CompressionError) as e: + if fileobj is not None: + fileobj.seek(saved_pos) + continue + raise ReadError("file could not be opened successfully") + + elif ":" in mode: + filemode, comptype = mode.split(":", 1) + filemode = filemode or "r" + comptype = comptype or "tar" + + # Select the *open() function according to + # given compression. + if comptype in cls.OPEN_METH: + func = getattr(cls, cls.OPEN_METH[comptype]) + else: + raise CompressionError("unknown compression type %r" % comptype) + return func(name, filemode, fileobj, **kwargs) + + elif "|" in mode: + filemode, comptype = mode.split("|", 1) + filemode = filemode or "r" + comptype = comptype or "tar" + + if filemode not in "rw": + raise ValueError("mode must be 'r' or 'w'") + + stream = _Stream(name, filemode, comptype, fileobj, bufsize) + try: + t = cls(name, filemode, stream, **kwargs) + except: + stream.close() + raise + t._extfileobj = False + return t + + elif mode in "aw": + return cls.taropen(name, mode, fileobj, **kwargs) + + raise ValueError("undiscernible mode") + + @classmethod + def taropen(cls, name, mode="r", fileobj=None, **kwargs): + """Open uncompressed tar archive name for reading or writing. + """ + if len(mode) > 1 or mode not in "raw": + raise ValueError("mode must be 'r', 'a' or 'w'") + return cls(name, mode, fileobj, **kwargs) + + @classmethod + def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): + """Open gzip compressed tar archive name for reading or writing. + Appending is not allowed. + """ + if len(mode) > 1 or mode not in "rw": + raise ValueError("mode must be 'r' or 'w'") + + try: + import gzip + gzip.GzipFile + except (ImportError, AttributeError): + raise CompressionError("gzip module is not available") + + extfileobj = fileobj is not None + try: + fileobj = gzip.GzipFile(name, mode + "b", compresslevel, fileobj) + t = cls.taropen(name, mode, fileobj, **kwargs) + except IOError: + if not extfileobj and fileobj is not None: + fileobj.close() + if fileobj is None: + raise + raise ReadError("not a gzip file") + except: + if not extfileobj and fileobj is not None: + fileobj.close() + raise + t._extfileobj = extfileobj + return t + + @classmethod + def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): + """Open bzip2 compressed tar archive name for reading or writing. + Appending is not allowed. + """ + if len(mode) > 1 or mode not in "rw": + raise ValueError("mode must be 'r' or 'w'.") + + try: + import bz2 + except ImportError: + raise CompressionError("bz2 module is not available") + + if fileobj is not None: + fileobj = _BZ2Proxy(fileobj, mode) + else: + fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel) + + try: + t = cls.taropen(name, mode, fileobj, **kwargs) + except (IOError, EOFError): + fileobj.close() + raise ReadError("not a bzip2 file") + t._extfileobj = False + return t + + # All *open() methods are registered here. + OPEN_METH = { + "tar": "taropen", # uncompressed tar + "gz": "gzopen", # gzip compressed tar + "bz2": "bz2open" # bzip2 compressed tar + } + + #-------------------------------------------------------------------------- + # The public methods which TarFile provides: + + def close(self): + """Close the TarFile. In write-mode, two finishing zero blocks are + appended to the archive. + """ + if self.closed: + return + + if self.mode in "aw": + self.fileobj.write(NUL * (BLOCKSIZE * 2)) + self.offset += (BLOCKSIZE * 2) + # fill up the end with zero-blocks + # (like option -b20 for tar does) + blocks, remainder = divmod(self.offset, RECORDSIZE) + if remainder > 0: + self.fileobj.write(NUL * (RECORDSIZE - remainder)) + + if not self._extfileobj: + self.fileobj.close() + self.closed = True + + def getmember(self, name): + """Return a TarInfo object for member `name'. If `name' can not be + found in the archive, KeyError is raised. If a member occurs more + than once in the archive, its last occurrence is assumed to be the + most up-to-date version. + """ + tarinfo = self._getmember(name) + if tarinfo is None: + raise KeyError("filename %r not found" % name) + return tarinfo + + def getmembers(self): + """Return the members of the archive as a list of TarInfo objects. The + list has the same order as the members in the archive. + """ + self._check() + if not self._loaded: # if we want to obtain a list of + self._load() # all members, we first have to + # scan the whole archive. + return self.members + + def getnames(self): + """Return the members of the archive as a list of their names. It has + the same order as the list returned by getmembers(). + """ + return [tarinfo.name for tarinfo in self.getmembers()] + + def gettarinfo(self, name=None, arcname=None, fileobj=None): + """Create a TarInfo object for either the file `name' or the file + object `fileobj' (using os.fstat on its file descriptor). You can + modify some of the TarInfo's attributes before you add it using + addfile(). If given, `arcname' specifies an alternative name for the + file in the archive. + """ + self._check("aw") + + # When fileobj is given, replace name by + # fileobj's real name. + if fileobj is not None: + name = fileobj.name + + # Building the name of the member in the archive. + # Backward slashes are converted to forward slashes, + # Absolute paths are turned to relative paths. + if arcname is None: + arcname = name + drv, arcname = os.path.splitdrive(arcname) + arcname = arcname.replace(os.sep, "/") + arcname = arcname.lstrip("/") + + # Now, fill the TarInfo object with + # information specific for the file. + tarinfo = self.tarinfo() + tarinfo.tarfile = self + + # Use os.stat or os.lstat, depending on platform + # and if symlinks shall be resolved. + if fileobj is None: + if hasattr(os, "lstat") and not self.dereference: + statres = os.lstat(name) + else: + statres = os.stat(name) + else: + statres = os.fstat(fileobj.fileno()) + linkname = "" + + stmd = statres.st_mode + if stat.S_ISREG(stmd): + inode = (statres.st_ino, statres.st_dev) + if not self.dereference and statres.st_nlink > 1 and \ + inode in self.inodes and arcname != self.inodes[inode]: + # Is it a hardlink to an already + # archived file? + type = LNKTYPE + linkname = self.inodes[inode] + else: + # The inode is added only if its valid. + # For win32 it is always 0. + type = REGTYPE + if inode[0]: + self.inodes[inode] = arcname + elif stat.S_ISDIR(stmd): + type = DIRTYPE + elif stat.S_ISFIFO(stmd): + type = FIFOTYPE + elif stat.S_ISLNK(stmd): + type = SYMTYPE + linkname = os.readlink(name) + elif stat.S_ISCHR(stmd): + type = CHRTYPE + elif stat.S_ISBLK(stmd): + type = BLKTYPE + else: + return None + + # Fill the TarInfo object with all + # information we can get. + tarinfo.name = arcname + tarinfo.mode = stmd + tarinfo.uid = statres.st_uid + tarinfo.gid = statres.st_gid + if type == REGTYPE: + tarinfo.size = statres.st_size + else: + tarinfo.size = 0 + tarinfo.mtime = statres.st_mtime + tarinfo.type = type + tarinfo.linkname = linkname + if pwd: + try: + tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0] + except KeyError: + pass + if grp: + try: + tarinfo.gname = grp.getgrgid(tarinfo.gid)[0] + except KeyError: + pass + + if type in (CHRTYPE, BLKTYPE): + if hasattr(os, "major") and hasattr(os, "minor"): + tarinfo.devmajor = os.major(statres.st_rdev) + tarinfo.devminor = os.minor(statres.st_rdev) + return tarinfo + + def list(self, verbose=True): + """Print a table of contents to sys.stdout. If `verbose' is False, only + the names of the members are printed. If it is True, an `ls -l'-like + output is produced. + """ + self._check() + + for tarinfo in self: + if verbose: + print(filemode(tarinfo.mode), end=' ') + print("%s/%s" % (tarinfo.uname or tarinfo.uid, + tarinfo.gname or tarinfo.gid), end=' ') + if tarinfo.ischr() or tarinfo.isblk(): + print("%10s" % ("%d,%d" \ + % (tarinfo.devmajor, tarinfo.devminor)), end=' ') + else: + print("%10d" % tarinfo.size, end=' ') + print("%d-%02d-%02d %02d:%02d:%02d" \ + % time.localtime(tarinfo.mtime)[:6], end=' ') + + print(tarinfo.name + ("/" if tarinfo.isdir() else ""), end=' ') + + if verbose: + if tarinfo.issym(): + print("->", tarinfo.linkname, end=' ') + if tarinfo.islnk(): + print("link to", tarinfo.linkname, end=' ') + print() + + def add(self, name, arcname=None, recursive=True, exclude=None, filter=None): + """Add the file `name' to the archive. `name' may be any type of file + (directory, fifo, symbolic link, etc.). If given, `arcname' + specifies an alternative name for the file in the archive. + Directories are added recursively by default. This can be avoided by + setting `recursive' to False. `exclude' is a function that should + return True for each filename to be excluded. `filter' is a function + that expects a TarInfo object argument and returns the changed + TarInfo object, if it returns None the TarInfo object will be + excluded from the archive. + """ + self._check("aw") + + if arcname is None: + arcname = name + + # Exclude pathnames. + if exclude is not None: + import warnings + warnings.warn("use the filter argument instead", + DeprecationWarning, 2) + if exclude(name): + self._dbg(2, "tarfile: Excluded %r" % name) + return + + # Skip if somebody tries to archive the archive... + if self.name is not None and os.path.abspath(name) == self.name: + self._dbg(2, "tarfile: Skipped %r" % name) + return + + self._dbg(1, name) + + # Create a TarInfo object from the file. + tarinfo = self.gettarinfo(name, arcname) + + if tarinfo is None: + self._dbg(1, "tarfile: Unsupported type %r" % name) + return + + # Change or exclude the TarInfo object. + if filter is not None: + tarinfo = filter(tarinfo) + if tarinfo is None: + self._dbg(2, "tarfile: Excluded %r" % name) + return + + # Append the tar header and data to the archive. + if tarinfo.isreg(): + f = bltn_open(name, "rb") + self.addfile(tarinfo, f) + f.close() + + elif tarinfo.isdir(): + self.addfile(tarinfo) + if recursive: + for f in os.listdir(name): + self.add(os.path.join(name, f), os.path.join(arcname, f), + recursive, exclude, filter=filter) + + else: + self.addfile(tarinfo) + + def addfile(self, tarinfo, fileobj=None): + """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is + given, tarinfo.size bytes are read from it and added to the archive. + You can create TarInfo objects using gettarinfo(). + On Windows platforms, `fileobj' should always be opened with mode + 'rb' to avoid irritation about the file size. + """ + self._check("aw") + + tarinfo = copy.copy(tarinfo) + + buf = tarinfo.tobuf(self.format, self.encoding, self.errors) + self.fileobj.write(buf) + self.offset += len(buf) + + # If there's data to follow, append it. + if fileobj is not None: + copyfileobj(fileobj, self.fileobj, tarinfo.size) + blocks, remainder = divmod(tarinfo.size, BLOCKSIZE) + if remainder > 0: + self.fileobj.write(NUL * (BLOCKSIZE - remainder)) + blocks += 1 + self.offset += blocks * BLOCKSIZE + + self.members.append(tarinfo) + + def extractall(self, path=".", members=None): + """Extract all members from the archive to the current working + directory and set owner, modification time and permissions on + directories afterwards. `path' specifies a different directory + to extract to. `members' is optional and must be a subset of the + list returned by getmembers(). + """ + directories = [] + + if members is None: + members = self + + for tarinfo in members: + if tarinfo.isdir(): + # Extract directories with a safe mode. + directories.append(tarinfo) + tarinfo = copy.copy(tarinfo) + tarinfo.mode = 0o700 + # Do not set_attrs directories, as we will do that further down + self.extract(tarinfo, path, set_attrs=not tarinfo.isdir()) + + # Reverse sort directories. + directories.sort(key=lambda a: a.name) + directories.reverse() + + # Set correct owner, mtime and filemode on directories. + for tarinfo in directories: + dirpath = os.path.join(path, tarinfo.name) + try: + self.chown(tarinfo, dirpath) + self.utime(tarinfo, dirpath) + self.chmod(tarinfo, dirpath) + except ExtractError as e: + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + def extract(self, member, path="", set_attrs=True): + """Extract a member from the archive to the current working directory, + using its full name. Its file information is extracted as accurately + as possible. `member' may be a filename or a TarInfo object. You can + specify a different directory using `path'. File attributes (owner, + mtime, mode) are set unless `set_attrs' is False. + """ + self._check("r") + + if isinstance(member, str): + tarinfo = self.getmember(member) + else: + tarinfo = member + + # Prepare the link target for makelink(). + if tarinfo.islnk(): + tarinfo._link_target = os.path.join(path, tarinfo.linkname) + + try: + self._extract_member(tarinfo, os.path.join(path, tarinfo.name), + set_attrs=set_attrs) + except EnvironmentError as e: + if self.errorlevel > 0: + raise + else: + if e.filename is None: + self._dbg(1, "tarfile: %s" % e.strerror) + else: + self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename)) + except ExtractError as e: + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + def extractfile(self, member): + """Extract a member from the archive as a file object. `member' may be + a filename or a TarInfo object. If `member' is a regular file, a + file-like object is returned. If `member' is a link, a file-like + object is constructed from the link's target. If `member' is none of + the above, None is returned. + The file-like object is read-only and provides the following + methods: read(), readline(), readlines(), seek() and tell() + """ + self._check("r") + + if isinstance(member, str): + tarinfo = self.getmember(member) + else: + tarinfo = member + + if tarinfo.isreg(): + return self.fileobject(self, tarinfo) + + elif tarinfo.type not in SUPPORTED_TYPES: + # If a member's type is unknown, it is treated as a + # regular file. + return self.fileobject(self, tarinfo) + + elif tarinfo.islnk() or tarinfo.issym(): + if isinstance(self.fileobj, _Stream): + # A small but ugly workaround for the case that someone tries + # to extract a (sym)link as a file-object from a non-seekable + # stream of tar blocks. + raise StreamError("cannot extract (sym)link as file object") + else: + # A (sym)link's file object is its target's file object. + return self.extractfile(self._find_link_target(tarinfo)) + else: + # If there's no data associated with the member (directory, chrdev, + # blkdev, etc.), return None instead of a file object. + return None + + def _extract_member(self, tarinfo, targetpath, set_attrs=True): + """Extract the TarInfo object tarinfo to a physical + file called targetpath. + """ + # Fetch the TarInfo object for the given name + # and build the destination pathname, replacing + # forward slashes to platform specific separators. + targetpath = targetpath.rstrip("/") + targetpath = targetpath.replace("/", os.sep) + + # Create all upper directories. + upperdirs = os.path.dirname(targetpath) + if upperdirs and not os.path.exists(upperdirs): + # Create directories that are not part of the archive with + # default permissions. + os.makedirs(upperdirs) + + if tarinfo.islnk() or tarinfo.issym(): + self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname)) + else: + self._dbg(1, tarinfo.name) + + if tarinfo.isreg(): + self.makefile(tarinfo, targetpath) + elif tarinfo.isdir(): + self.makedir(tarinfo, targetpath) + elif tarinfo.isfifo(): + self.makefifo(tarinfo, targetpath) + elif tarinfo.ischr() or tarinfo.isblk(): + self.makedev(tarinfo, targetpath) + elif tarinfo.islnk() or tarinfo.issym(): + self.makelink(tarinfo, targetpath) + elif tarinfo.type not in SUPPORTED_TYPES: + self.makeunknown(tarinfo, targetpath) + else: + self.makefile(tarinfo, targetpath) + + if set_attrs: + self.chown(tarinfo, targetpath) + if not tarinfo.issym(): + self.chmod(tarinfo, targetpath) + self.utime(tarinfo, targetpath) + + #-------------------------------------------------------------------------- + # Below are the different file methods. They are called via + # _extract_member() when extract() is called. They can be replaced in a + # subclass to implement other functionality. + + def makedir(self, tarinfo, targetpath): + """Make a directory called targetpath. + """ + try: + # Use a safe mode for the directory, the real mode is set + # later in _extract_member(). + os.mkdir(targetpath, 0o700) + except EnvironmentError as e: + if e.errno != errno.EEXIST: + raise + + def makefile(self, tarinfo, targetpath): + """Make a file called targetpath. + """ + source = self.fileobj + source.seek(tarinfo.offset_data) + target = bltn_open(targetpath, "wb") + if tarinfo.sparse is not None: + for offset, size in tarinfo.sparse: + target.seek(offset) + copyfileobj(source, target, size) + else: + copyfileobj(source, target, tarinfo.size) + target.seek(tarinfo.size) + target.truncate() + target.close() + + def makeunknown(self, tarinfo, targetpath): + """Make a file from a TarInfo object with an unknown type + at targetpath. + """ + self.makefile(tarinfo, targetpath) + self._dbg(1, "tarfile: Unknown file type %r, " \ + "extracted as regular file." % tarinfo.type) + + def makefifo(self, tarinfo, targetpath): + """Make a fifo called targetpath. + """ + if hasattr(os, "mkfifo"): + os.mkfifo(targetpath) + else: + raise ExtractError("fifo not supported by system") + + def makedev(self, tarinfo, targetpath): + """Make a character or block device called targetpath. + """ + if not hasattr(os, "mknod") or not hasattr(os, "makedev"): + raise ExtractError("special devices not supported by system") + + mode = tarinfo.mode + if tarinfo.isblk(): + mode |= stat.S_IFBLK + else: + mode |= stat.S_IFCHR + + os.mknod(targetpath, mode, + os.makedev(tarinfo.devmajor, tarinfo.devminor)) + + def makelink(self, tarinfo, targetpath): + """Make a (symbolic) link called targetpath. If it cannot be created + (platform limitation), we try to make a copy of the referenced file + instead of a link. + """ + try: + # For systems that support symbolic and hard links. + if tarinfo.issym(): + os.symlink(tarinfo.linkname, targetpath) + else: + # See extract(). + if os.path.exists(tarinfo._link_target): + os.link(tarinfo._link_target, targetpath) + else: + self._extract_member(self._find_link_target(tarinfo), + targetpath) + except symlink_exception: + if tarinfo.issym(): + linkpath = os.path.join(os.path.dirname(tarinfo.name), + tarinfo.linkname) + else: + linkpath = tarinfo.linkname + else: + try: + self._extract_member(self._find_link_target(tarinfo), + targetpath) + except KeyError: + raise ExtractError("unable to resolve link inside archive") + + def chown(self, tarinfo, targetpath): + """Set owner of targetpath according to tarinfo. + """ + if pwd and hasattr(os, "geteuid") and os.geteuid() == 0: + # We have to be root to do so. + try: + g = grp.getgrnam(tarinfo.gname)[2] + except KeyError: + g = tarinfo.gid + try: + u = pwd.getpwnam(tarinfo.uname)[2] + except KeyError: + u = tarinfo.uid + try: + if tarinfo.issym() and hasattr(os, "lchown"): + os.lchown(targetpath, u, g) + else: + if sys.platform != "os2emx": + os.chown(targetpath, u, g) + except EnvironmentError as e: + raise ExtractError("could not change owner") + + def chmod(self, tarinfo, targetpath): + """Set file permissions of targetpath according to tarinfo. + """ + if hasattr(os, 'chmod'): + try: + os.chmod(targetpath, tarinfo.mode) + except EnvironmentError as e: + raise ExtractError("could not change mode") + + def utime(self, tarinfo, targetpath): + """Set modification time of targetpath according to tarinfo. + """ + if not hasattr(os, 'utime'): + return + try: + os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime)) + except EnvironmentError as e: + raise ExtractError("could not change modification time") + + #-------------------------------------------------------------------------- + def next(self): + """Return the next member of the archive as a TarInfo object, when + TarFile is opened for reading. Return None if there is no more + available. + """ + self._check("ra") + if self.firstmember is not None: + m = self.firstmember + self.firstmember = None + return m + + # Read the next block. + self.fileobj.seek(self.offset) + tarinfo = None + while True: + try: + tarinfo = self.tarinfo.fromtarfile(self) + except EOFHeaderError as e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + except InvalidHeaderError as e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + elif self.offset == 0: + raise ReadError(str(e)) + except EmptyHeaderError: + if self.offset == 0: + raise ReadError("empty file") + except TruncatedHeaderError as e: + if self.offset == 0: + raise ReadError(str(e)) + except SubsequentHeaderError as e: + raise ReadError(str(e)) + break + + if tarinfo is not None: + self.members.append(tarinfo) + else: + self._loaded = True + + return tarinfo + + #-------------------------------------------------------------------------- + # Little helper methods: + + def _getmember(self, name, tarinfo=None, normalize=False): + """Find an archive member by name from bottom to top. + If tarinfo is given, it is used as the starting point. + """ + # Ensure that all members have been loaded. + members = self.getmembers() + + # Limit the member search list up to tarinfo. + if tarinfo is not None: + members = members[:members.index(tarinfo)] + + if normalize: + name = os.path.normpath(name) + + for member in reversed(members): + if normalize: + member_name = os.path.normpath(member.name) + else: + member_name = member.name + + if name == member_name: + return member + + def _load(self): + """Read through the entire archive file and look for readable + members. + """ + while True: + tarinfo = self.next() + if tarinfo is None: + break + self._loaded = True + + def _check(self, mode=None): + """Check if TarFile is still open, and if the operation's mode + corresponds to TarFile's mode. + """ + if self.closed: + raise IOError("%s is closed" % self.__class__.__name__) + if mode is not None and self.mode not in mode: + raise IOError("bad operation for mode %r" % self.mode) + + def _find_link_target(self, tarinfo): + """Find the target member of a symlink or hardlink member in the + archive. + """ + if tarinfo.issym(): + # Always search the entire archive. + linkname = os.path.dirname(tarinfo.name) + "/" + tarinfo.linkname + limit = None + else: + # Search the archive before the link, because a hard link is + # just a reference to an already archived file. + linkname = tarinfo.linkname + limit = tarinfo + + member = self._getmember(linkname, tarinfo=limit, normalize=True) + if member is None: + raise KeyError("linkname %r not found" % linkname) + return member + + def __iter__(self): + """Provide an iterator object. + """ + if self._loaded: + return iter(self.members) + else: + return TarIter(self) + + def _dbg(self, level, msg): + """Write debugging output to sys.stderr. + """ + if level <= self.debug: + print(msg, file=sys.stderr) + + def __enter__(self): + self._check() + return self + + def __exit__(self, type, value, traceback): + if type is None: + self.close() + else: + # An exception occurred. We must not call close() because + # it would try to write end-of-archive blocks and padding. + if not self._extfileobj: + self.fileobj.close() + self.closed = True +# class TarFile + +class TarIter(object): + """Iterator Class. + + for tarinfo in TarFile(...): + suite... + """ + + def __init__(self, tarfile): + """Construct a TarIter object. + """ + self.tarfile = tarfile + self.index = 0 + def __iter__(self): + """Return iterator object. + """ + return self + + def __next__(self): + """Return the next item using TarFile's next() method. + When all members have been read, set TarFile as _loaded. + """ + # Fix for SF #1100429: Under rare circumstances it can + # happen that getmembers() is called during iteration, + # which will cause TarIter to stop prematurely. + if not self.tarfile._loaded: + tarinfo = self.tarfile.next() + if not tarinfo: + self.tarfile._loaded = True + raise StopIteration + else: + try: + tarinfo = self.tarfile.members[self.index] + except IndexError: + raise StopIteration + self.index += 1 + return tarinfo + + next = __next__ # for Python 2.x + +#-------------------- +# exported functions +#-------------------- +def is_tarfile(name): + """Return True if name points to a tar archive that we + are able to handle, else return False. + """ + try: + t = open(name) + t.close() + return True + except TarError: + return False + +bltn_open = open +open = TarFile.open diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/compat.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/compat.py new file mode 100644 index 0000000..ff328c8 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/compat.py @@ -0,0 +1,1120 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import absolute_import + +import os +import re +import sys + +try: + import ssl +except ImportError: # pragma: no cover + ssl = None + +if sys.version_info[0] < 3: # pragma: no cover + from StringIO import StringIO + string_types = basestring, + text_type = unicode + from types import FileType as file_type + import __builtin__ as builtins + import ConfigParser as configparser + from ._backport import shutil + from urlparse import urlparse, urlunparse, urljoin, urlsplit, urlunsplit + from urllib import (urlretrieve, quote as _quote, unquote, url2pathname, + pathname2url, ContentTooShortError, splittype) + + def quote(s): + if isinstance(s, unicode): + s = s.encode('utf-8') + return _quote(s) + + import urllib2 + from urllib2 import (Request, urlopen, URLError, HTTPError, + HTTPBasicAuthHandler, HTTPPasswordMgr, + HTTPHandler, HTTPRedirectHandler, + build_opener) + if ssl: + from urllib2 import HTTPSHandler + import httplib + import xmlrpclib + import Queue as queue + from HTMLParser import HTMLParser + import htmlentitydefs + raw_input = raw_input + from itertools import ifilter as filter + from itertools import ifilterfalse as filterfalse + + _userprog = None + def splituser(host): + """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.""" + global _userprog + if _userprog is None: + import re + _userprog = re.compile('^(.*)@(.*)$') + + match = _userprog.match(host) + if match: return match.group(1, 2) + return None, host + +else: # pragma: no cover + from io import StringIO + string_types = str, + text_type = str + from io import TextIOWrapper as file_type + import builtins + import configparser + import shutil + from urllib.parse import (urlparse, urlunparse, urljoin, splituser, quote, + unquote, urlsplit, urlunsplit, splittype) + from urllib.request import (urlopen, urlretrieve, Request, url2pathname, + pathname2url, + HTTPBasicAuthHandler, HTTPPasswordMgr, + HTTPHandler, HTTPRedirectHandler, + build_opener) + if ssl: + from urllib.request import HTTPSHandler + from urllib.error import HTTPError, URLError, ContentTooShortError + import http.client as httplib + import urllib.request as urllib2 + import xmlrpc.client as xmlrpclib + import queue + from html.parser import HTMLParser + import html.entities as htmlentitydefs + raw_input = input + from itertools import filterfalse + filter = filter + +try: + from ssl import match_hostname, CertificateError +except ImportError: # pragma: no cover + class CertificateError(ValueError): + pass + + + def _dnsname_match(dn, hostname, max_wildcards=1): + """Matching according to RFC 6125, section 6.4.3 + + http://tools.ietf.org/html/rfc6125#section-6.4.3 + """ + pats = [] + if not dn: + return False + + parts = dn.split('.') + leftmost, remainder = parts[0], parts[1:] + + wildcards = leftmost.count('*') + if wildcards > max_wildcards: + # Issue #17980: avoid denials of service by refusing more + # than one wildcard per fragment. A survey of established + # policy among SSL implementations showed it to be a + # reasonable choice. + raise CertificateError( + "too many wildcards in certificate DNS name: " + repr(dn)) + + # speed up common case w/o wildcards + if not wildcards: + return dn.lower() == hostname.lower() + + # RFC 6125, section 6.4.3, subitem 1. + # The client SHOULD NOT attempt to match a presented identifier in which + # the wildcard character comprises a label other than the left-most label. + if leftmost == '*': + # When '*' is a fragment by itself, it matches a non-empty dotless + # fragment. + pats.append('[^.]+') + elif leftmost.startswith('xn--') or hostname.startswith('xn--'): + # RFC 6125, section 6.4.3, subitem 3. + # The client SHOULD NOT attempt to match a presented identifier + # where the wildcard character is embedded within an A-label or + # U-label of an internationalized domain name. + pats.append(re.escape(leftmost)) + else: + # Otherwise, '*' matches any dotless string, e.g. www* + pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) + + # add the remaining fragments, ignore any wildcards + for frag in remainder: + pats.append(re.escape(frag)) + + pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) + return pat.match(hostname) + + + def match_hostname(cert, hostname): + """Verify that *cert* (in decoded format as returned by + SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 + rules are followed, but IP addresses are not accepted for *hostname*. + + CertificateError is raised on failure. On success, the function + returns nothing. + """ + if not cert: + raise ValueError("empty or no certificate, match_hostname needs a " + "SSL socket or SSL context with either " + "CERT_OPTIONAL or CERT_REQUIRED") + dnsnames = [] + san = cert.get('subjectAltName', ()) + for key, value in san: + if key == 'DNS': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if not dnsnames: + # The subject is only checked when there is no dNSName entry + # in subjectAltName + for sub in cert.get('subject', ()): + for key, value in sub: + # XXX according to RFC 2818, the most specific Common Name + # must be used. + if key == 'commonName': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if len(dnsnames) > 1: + raise CertificateError("hostname %r " + "doesn't match either of %s" + % (hostname, ', '.join(map(repr, dnsnames)))) + elif len(dnsnames) == 1: + raise CertificateError("hostname %r " + "doesn't match %r" + % (hostname, dnsnames[0])) + else: + raise CertificateError("no appropriate commonName or " + "subjectAltName fields were found") + + +try: + from types import SimpleNamespace as Container +except ImportError: # pragma: no cover + class Container(object): + """ + A generic container for when multiple values need to be returned + """ + def __init__(self, **kwargs): + self.__dict__.update(kwargs) + + +try: + from shutil import which +except ImportError: # pragma: no cover + # Implementation from Python 3.3 + def which(cmd, mode=os.F_OK | os.X_OK, path=None): + """Given a command, mode, and a PATH string, return the path which + conforms to the given mode on the PATH, or None if there is no such + file. + + `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result + of os.environ.get("PATH"), or can be overridden with a custom search + path. + + """ + # Check that a given file can be accessed with the correct mode. + # Additionally check that `file` is not a directory, as on Windows + # directories pass the os.access check. + def _access_check(fn, mode): + return (os.path.exists(fn) and os.access(fn, mode) + and not os.path.isdir(fn)) + + # If we're given a path with a directory part, look it up directly rather + # than referring to PATH directories. This includes checking relative to the + # current directory, e.g. ./script + if os.path.dirname(cmd): + if _access_check(cmd, mode): + return cmd + return None + + if path is None: + path = os.environ.get("PATH", os.defpath) + if not path: + return None + path = path.split(os.pathsep) + + if sys.platform == "win32": + # The current directory takes precedence on Windows. + if not os.curdir in path: + path.insert(0, os.curdir) + + # PATHEXT is necessary to check on Windows. + pathext = os.environ.get("PATHEXT", "").split(os.pathsep) + # See if the given file matches any of the expected path extensions. + # This will allow us to short circuit when given "python.exe". + # If it does match, only test that one, otherwise we have to try + # others. + if any(cmd.lower().endswith(ext.lower()) for ext in pathext): + files = [cmd] + else: + files = [cmd + ext for ext in pathext] + else: + # On other platforms you don't have things like PATHEXT to tell you + # what file suffixes are executable, so just pass on cmd as-is. + files = [cmd] + + seen = set() + for dir in path: + normdir = os.path.normcase(dir) + if not normdir in seen: + seen.add(normdir) + for thefile in files: + name = os.path.join(dir, thefile) + if _access_check(name, mode): + return name + return None + + +# ZipFile is a context manager in 2.7, but not in 2.6 + +from zipfile import ZipFile as BaseZipFile + +if hasattr(BaseZipFile, '__enter__'): # pragma: no cover + ZipFile = BaseZipFile +else: # pragma: no cover + from zipfile import ZipExtFile as BaseZipExtFile + + class ZipExtFile(BaseZipExtFile): + def __init__(self, base): + self.__dict__.update(base.__dict__) + + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.close() + # return None, so if an exception occurred, it will propagate + + class ZipFile(BaseZipFile): + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.close() + # return None, so if an exception occurred, it will propagate + + def open(self, *args, **kwargs): + base = BaseZipFile.open(self, *args, **kwargs) + return ZipExtFile(base) + +try: + from platform import python_implementation +except ImportError: # pragma: no cover + def python_implementation(): + """Return a string identifying the Python implementation.""" + if 'PyPy' in sys.version: + return 'PyPy' + if os.name == 'java': + return 'Jython' + if sys.version.startswith('IronPython'): + return 'IronPython' + return 'CPython' + +try: + import sysconfig +except ImportError: # pragma: no cover + from ._backport import sysconfig + +try: + callable = callable +except NameError: # pragma: no cover + from collections import Callable + + def callable(obj): + return isinstance(obj, Callable) + + +try: + fsencode = os.fsencode + fsdecode = os.fsdecode +except AttributeError: # pragma: no cover + # Issue #99: on some systems (e.g. containerised), + # sys.getfilesystemencoding() returns None, and we need a real value, + # so fall back to utf-8. From the CPython 2.7 docs relating to Unix and + # sys.getfilesystemencoding(): the return value is "the user’s preference + # according to the result of nl_langinfo(CODESET), or None if the + # nl_langinfo(CODESET) failed." + _fsencoding = sys.getfilesystemencoding() or 'utf-8' + if _fsencoding == 'mbcs': + _fserrors = 'strict' + else: + _fserrors = 'surrogateescape' + + def fsencode(filename): + if isinstance(filename, bytes): + return filename + elif isinstance(filename, text_type): + return filename.encode(_fsencoding, _fserrors) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) + + def fsdecode(filename): + if isinstance(filename, text_type): + return filename + elif isinstance(filename, bytes): + return filename.decode(_fsencoding, _fserrors) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) + +try: + from tokenize import detect_encoding +except ImportError: # pragma: no cover + from codecs import BOM_UTF8, lookup + import re + + cookie_re = re.compile(r"coding[:=]\s*([-\w.]+)") + + def _get_normal_name(orig_enc): + """Imitates get_normal_name in tokenizer.c.""" + # Only care about the first 12 characters. + enc = orig_enc[:12].lower().replace("_", "-") + if enc == "utf-8" or enc.startswith("utf-8-"): + return "utf-8" + if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \ + enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")): + return "iso-8859-1" + return orig_enc + + def detect_encoding(readline): + """ + The detect_encoding() function is used to detect the encoding that should + be used to decode a Python source file. It requires one argument, readline, + in the same way as the tokenize() generator. + + It will call readline a maximum of twice, and return the encoding used + (as a string) and a list of any lines (left as bytes) it has read in. + + It detects the encoding from the presence of a utf-8 bom or an encoding + cookie as specified in pep-0263. If both a bom and a cookie are present, + but disagree, a SyntaxError will be raised. If the encoding cookie is an + invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found, + 'utf-8-sig' is returned. + + If no encoding is specified, then the default of 'utf-8' will be returned. + """ + try: + filename = readline.__self__.name + except AttributeError: + filename = None + bom_found = False + encoding = None + default = 'utf-8' + def read_or_stop(): + try: + return readline() + except StopIteration: + return b'' + + def find_cookie(line): + try: + # Decode as UTF-8. Either the line is an encoding declaration, + # in which case it should be pure ASCII, or it must be UTF-8 + # per default encoding. + line_string = line.decode('utf-8') + except UnicodeDecodeError: + msg = "invalid or missing encoding declaration" + if filename is not None: + msg = '{} for {!r}'.format(msg, filename) + raise SyntaxError(msg) + + matches = cookie_re.findall(line_string) + if not matches: + return None + encoding = _get_normal_name(matches[0]) + try: + codec = lookup(encoding) + except LookupError: + # This behaviour mimics the Python interpreter + if filename is None: + msg = "unknown encoding: " + encoding + else: + msg = "unknown encoding for {!r}: {}".format(filename, + encoding) + raise SyntaxError(msg) + + if bom_found: + if codec.name != 'utf-8': + # This behaviour mimics the Python interpreter + if filename is None: + msg = 'encoding problem: utf-8' + else: + msg = 'encoding problem for {!r}: utf-8'.format(filename) + raise SyntaxError(msg) + encoding += '-sig' + return encoding + + first = read_or_stop() + if first.startswith(BOM_UTF8): + bom_found = True + first = first[3:] + default = 'utf-8-sig' + if not first: + return default, [] + + encoding = find_cookie(first) + if encoding: + return encoding, [first] + + second = read_or_stop() + if not second: + return default, [first] + + encoding = find_cookie(second) + if encoding: + return encoding, [first, second] + + return default, [first, second] + +# For converting & <-> & etc. +try: + from html import escape +except ImportError: + from cgi import escape +if sys.version_info[:2] < (3, 4): + unescape = HTMLParser().unescape +else: + from html import unescape + +try: + from collections import ChainMap +except ImportError: # pragma: no cover + from collections import MutableMapping + + try: + from reprlib import recursive_repr as _recursive_repr + except ImportError: + def _recursive_repr(fillvalue='...'): + ''' + Decorator to make a repr function return fillvalue for a recursive + call + ''' + + def decorating_function(user_function): + repr_running = set() + + def wrapper(self): + key = id(self), get_ident() + if key in repr_running: + return fillvalue + repr_running.add(key) + try: + result = user_function(self) + finally: + repr_running.discard(key) + return result + + # Can't use functools.wraps() here because of bootstrap issues + wrapper.__module__ = getattr(user_function, '__module__') + wrapper.__doc__ = getattr(user_function, '__doc__') + wrapper.__name__ = getattr(user_function, '__name__') + wrapper.__annotations__ = getattr(user_function, '__annotations__', {}) + return wrapper + + return decorating_function + + class ChainMap(MutableMapping): + ''' A ChainMap groups multiple dicts (or other mappings) together + to create a single, updateable view. + + The underlying mappings are stored in a list. That list is public and can + accessed or updated using the *maps* attribute. There is no other state. + + Lookups search the underlying mappings successively until a key is found. + In contrast, writes, updates, and deletions only operate on the first + mapping. + + ''' + + def __init__(self, *maps): + '''Initialize a ChainMap by setting *maps* to the given mappings. + If no mappings are provided, a single empty dictionary is used. + + ''' + self.maps = list(maps) or [{}] # always at least one map + + def __missing__(self, key): + raise KeyError(key) + + def __getitem__(self, key): + for mapping in self.maps: + try: + return mapping[key] # can't use 'key in mapping' with defaultdict + except KeyError: + pass + return self.__missing__(key) # support subclasses that define __missing__ + + def get(self, key, default=None): + return self[key] if key in self else default + + def __len__(self): + return len(set().union(*self.maps)) # reuses stored hash values if possible + + def __iter__(self): + return iter(set().union(*self.maps)) + + def __contains__(self, key): + return any(key in m for m in self.maps) + + def __bool__(self): + return any(self.maps) + + @_recursive_repr() + def __repr__(self): + return '{0.__class__.__name__}({1})'.format( + self, ', '.join(map(repr, self.maps))) + + @classmethod + def fromkeys(cls, iterable, *args): + 'Create a ChainMap with a single dict created from the iterable.' + return cls(dict.fromkeys(iterable, *args)) + + def copy(self): + 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]' + return self.__class__(self.maps[0].copy(), *self.maps[1:]) + + __copy__ = copy + + def new_child(self): # like Django's Context.push() + 'New ChainMap with a new dict followed by all previous maps.' + return self.__class__({}, *self.maps) + + @property + def parents(self): # like Django's Context.pop() + 'New ChainMap from maps[1:].' + return self.__class__(*self.maps[1:]) + + def __setitem__(self, key, value): + self.maps[0][key] = value + + def __delitem__(self, key): + try: + del self.maps[0][key] + except KeyError: + raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + + def popitem(self): + 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.' + try: + return self.maps[0].popitem() + except KeyError: + raise KeyError('No keys found in the first mapping.') + + def pop(self, key, *args): + 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].' + try: + return self.maps[0].pop(key, *args) + except KeyError: + raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + + def clear(self): + 'Clear maps[0], leaving maps[1:] intact.' + self.maps[0].clear() + +try: + from importlib.util import cache_from_source # Python >= 3.4 +except ImportError: # pragma: no cover + try: + from imp import cache_from_source + except ImportError: # pragma: no cover + def cache_from_source(path, debug_override=None): + assert path.endswith('.py') + if debug_override is None: + debug_override = __debug__ + if debug_override: + suffix = 'c' + else: + suffix = 'o' + return path + suffix + +try: + from collections import OrderedDict +except ImportError: # pragma: no cover +## {{{ http://code.activestate.com/recipes/576693/ (r9) +# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. +# Passes Python2.7's test suite and incorporates all the latest updates. + try: + from thread import get_ident as _get_ident + except ImportError: + from dummy_thread import get_ident as _get_ident + + try: + from _abcoll import KeysView, ValuesView, ItemsView + except ImportError: + pass + + + class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as for regular dictionaries. + + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link which goes at the end of the linked + # list, and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which is + # then removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, key = self.__map.pop(key) + link_prev[1] = link_next + link_next[0] = link_prev + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + root = self.__root + curr = root[1] + while curr is not root: + yield curr[2] + curr = curr[1] + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + root = self.__root + curr = root[0] + while curr is not root: + yield curr[2] + curr = curr[0] + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + try: + for node in self.__map.itervalues(): + del node[:] + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + except AttributeError: + pass + dict.clear(self) + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + root = self.__root + if last: + link = root[0] + link_prev = link[0] + link_prev[1] = root + root[0] = link_prev + else: + link = root[1] + link_next = link[1] + root[1] = link_next + link_next[0] = root + key = link[2] + del self.__map[key] + value = dict.pop(self, key) + return key, value + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) items in od' + for k in self: + yield (k, self[k]) + + def update(*args, **kwds): + '''od.update(E, **F) -> None. Update od from dict/iterable E and F. + + If E is a dict instance, does: for k in E: od[k] = E[k] + If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] + Or if E is an iterable of items, does: for k, v in E: od[k] = v + In either case, this is followed by: for k, v in F.items(): od[k] = v + + ''' + if len(args) > 2: + raise TypeError('update() takes at most 2 positional ' + 'arguments (%d given)' % (len(args),)) + elif not args: + raise TypeError('update() takes at least 1 argument (0 given)') + self = args[0] + # Make progressively weaker assumptions about "other" + other = () + if len(args) == 2: + other = args[1] + if isinstance(other, dict): + for key in other: + self[key] = other[key] + elif hasattr(other, 'keys'): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def __repr__(self, _repr_running=None): + 'od.__repr__() <==> repr(od)' + if not _repr_running: _repr_running = {} + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other + + # -- the following methods are only used in Python 2.7 -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) + +try: + from logging.config import BaseConfigurator, valid_ident +except ImportError: # pragma: no cover + IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I) + + + def valid_ident(s): + m = IDENTIFIER.match(s) + if not m: + raise ValueError('Not a valid Python identifier: %r' % s) + return True + + + # The ConvertingXXX classes are wrappers around standard Python containers, + # and they serve to convert any suitable values in the container. The + # conversion converts base dicts, lists and tuples to their wrapped + # equivalents, whereas strings which match a conversion format are converted + # appropriately. + # + # Each wrapper should have a configurator attribute holding the actual + # configurator to use for conversion. + + class ConvertingDict(dict): + """A converting dictionary wrapper.""" + + def __getitem__(self, key): + value = dict.__getitem__(self, key) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def get(self, key, default=None): + value = dict.get(self, key, default) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def pop(self, key, default=None): + value = dict.pop(self, key, default) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + class ConvertingList(list): + """A converting list wrapper.""" + def __getitem__(self, key): + value = list.__getitem__(self, key) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def pop(self, idx=-1): + value = list.pop(self, idx) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + return result + + class ConvertingTuple(tuple): + """A converting tuple wrapper.""" + def __getitem__(self, key): + value = tuple.__getitem__(self, key) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + class BaseConfigurator(object): + """ + The configurator base class which defines some useful defaults. + """ + + CONVERT_PATTERN = re.compile(r'^(?P<prefix>[a-z]+)://(?P<suffix>.*)$') + + WORD_PATTERN = re.compile(r'^\s*(\w+)\s*') + DOT_PATTERN = re.compile(r'^\.\s*(\w+)\s*') + INDEX_PATTERN = re.compile(r'^\[\s*(\w+)\s*\]\s*') + DIGIT_PATTERN = re.compile(r'^\d+$') + + value_converters = { + 'ext' : 'ext_convert', + 'cfg' : 'cfg_convert', + } + + # We might want to use a different one, e.g. importlib + importer = staticmethod(__import__) + + def __init__(self, config): + self.config = ConvertingDict(config) + self.config.configurator = self + + def resolve(self, s): + """ + Resolve strings to objects using standard import and attribute + syntax. + """ + name = s.split('.') + used = name.pop(0) + try: + found = self.importer(used) + for frag in name: + used += '.' + frag + try: + found = getattr(found, frag) + except AttributeError: + self.importer(used) + found = getattr(found, frag) + return found + except ImportError: + e, tb = sys.exc_info()[1:] + v = ValueError('Cannot resolve %r: %s' % (s, e)) + v.__cause__, v.__traceback__ = e, tb + raise v + + def ext_convert(self, value): + """Default converter for the ext:// protocol.""" + return self.resolve(value) + + def cfg_convert(self, value): + """Default converter for the cfg:// protocol.""" + rest = value + m = self.WORD_PATTERN.match(rest) + if m is None: + raise ValueError("Unable to convert %r" % value) + else: + rest = rest[m.end():] + d = self.config[m.groups()[0]] + #print d, rest + while rest: + m = self.DOT_PATTERN.match(rest) + if m: + d = d[m.groups()[0]] + else: + m = self.INDEX_PATTERN.match(rest) + if m: + idx = m.groups()[0] + if not self.DIGIT_PATTERN.match(idx): + d = d[idx] + else: + try: + n = int(idx) # try as number first (most likely) + d = d[n] + except TypeError: + d = d[idx] + if m: + rest = rest[m.end():] + else: + raise ValueError('Unable to convert ' + '%r at %r' % (value, rest)) + #rest should be empty + return d + + def convert(self, value): + """ + Convert values to an appropriate type. dicts, lists and tuples are + replaced by their converting alternatives. Strings are checked to + see if they have a conversion format and are converted if they do. + """ + if not isinstance(value, ConvertingDict) and isinstance(value, dict): + value = ConvertingDict(value) + value.configurator = self + elif not isinstance(value, ConvertingList) and isinstance(value, list): + value = ConvertingList(value) + value.configurator = self + elif not isinstance(value, ConvertingTuple) and\ + isinstance(value, tuple): + value = ConvertingTuple(value) + value.configurator = self + elif isinstance(value, string_types): + m = self.CONVERT_PATTERN.match(value) + if m: + d = m.groupdict() + prefix = d['prefix'] + converter = self.value_converters.get(prefix, None) + if converter: + suffix = d['suffix'] + converter = getattr(self, converter) + value = converter(suffix) + return value + + def configure_custom(self, config): + """Configure an object with a user-supplied factory.""" + c = config.pop('()') + if not callable(c): + c = self.resolve(c) + props = config.pop('.', None) + # Check for valid identifiers + kwargs = dict([(k, config[k]) for k in config if valid_ident(k)]) + result = c(**kwargs) + if props: + for name, value in props.items(): + setattr(result, name, value) + return result + + def as_tuple(self, value): + """Utility function which converts lists to tuples.""" + if isinstance(value, list): + value = tuple(value) + return value diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/database.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/database.py new file mode 100644 index 0000000..a19905e --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/database.py @@ -0,0 +1,1336 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""PEP 376 implementation.""" + +from __future__ import unicode_literals + +import base64 +import codecs +import contextlib +import hashlib +import logging +import os +import posixpath +import sys +import zipimport + +from . import DistlibException, resources +from .compat import StringIO +from .version import get_scheme, UnsupportedVersionError +from .metadata import Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME +from .util import (parse_requirement, cached_property, parse_name_and_version, + read_exports, write_exports, CSVReader, CSVWriter) + + +__all__ = ['Distribution', 'BaseInstalledDistribution', + 'InstalledDistribution', 'EggInfoDistribution', + 'DistributionPath'] + + +logger = logging.getLogger(__name__) + +EXPORTS_FILENAME = 'pydist-exports.json' +COMMANDS_FILENAME = 'pydist-commands.json' + +DIST_FILES = ('INSTALLER', METADATA_FILENAME, 'RECORD', 'REQUESTED', + 'RESOURCES', EXPORTS_FILENAME, 'SHARED') + +DISTINFO_EXT = '.dist-info' + + +class _Cache(object): + """ + A simple cache mapping names and .dist-info paths to distributions + """ + def __init__(self): + """ + Initialise an instance. There is normally one for each DistributionPath. + """ + self.name = {} + self.path = {} + self.generated = False + + def clear(self): + """ + Clear the cache, setting it to its initial state. + """ + self.name.clear() + self.path.clear() + self.generated = False + + def add(self, dist): + """ + Add a distribution to the cache. + :param dist: The distribution to add. + """ + if dist.path not in self.path: + self.path[dist.path] = dist + self.name.setdefault(dist.key, []).append(dist) + + +class DistributionPath(object): + """ + Represents a set of distributions installed on a path (typically sys.path). + """ + def __init__(self, path=None, include_egg=False): + """ + Create an instance from a path, optionally including legacy (distutils/ + setuptools/distribute) distributions. + :param path: The path to use, as a list of directories. If not specified, + sys.path is used. + :param include_egg: If True, this instance will look for and return legacy + distributions as well as those based on PEP 376. + """ + if path is None: + path = sys.path + self.path = path + self._include_dist = True + self._include_egg = include_egg + + self._cache = _Cache() + self._cache_egg = _Cache() + self._cache_enabled = True + self._scheme = get_scheme('default') + + def _get_cache_enabled(self): + return self._cache_enabled + + def _set_cache_enabled(self, value): + self._cache_enabled = value + + cache_enabled = property(_get_cache_enabled, _set_cache_enabled) + + def clear_cache(self): + """ + Clears the internal cache. + """ + self._cache.clear() + self._cache_egg.clear() + + + def _yield_distributions(self): + """ + Yield .dist-info and/or .egg(-info) distributions. + """ + # We need to check if we've seen some resources already, because on + # some Linux systems (e.g. some Debian/Ubuntu variants) there are + # symlinks which alias other files in the environment. + seen = set() + for path in self.path: + finder = resources.finder_for_path(path) + if finder is None: + continue + r = finder.find('') + if not r or not r.is_container: + continue + rset = sorted(r.resources) + for entry in rset: + r = finder.find(entry) + if not r or r.path in seen: + continue + if self._include_dist and entry.endswith(DISTINFO_EXT): + possible_filenames = [METADATA_FILENAME, WHEEL_METADATA_FILENAME] + for metadata_filename in possible_filenames: + metadata_path = posixpath.join(entry, metadata_filename) + pydist = finder.find(metadata_path) + if pydist: + break + else: + continue + + with contextlib.closing(pydist.as_stream()) as stream: + metadata = Metadata(fileobj=stream, scheme='legacy') + logger.debug('Found %s', r.path) + seen.add(r.path) + yield new_dist_class(r.path, metadata=metadata, + env=self) + elif self._include_egg and entry.endswith(('.egg-info', + '.egg')): + logger.debug('Found %s', r.path) + seen.add(r.path) + yield old_dist_class(r.path, self) + + def _generate_cache(self): + """ + Scan the path for distributions and populate the cache with + those that are found. + """ + gen_dist = not self._cache.generated + gen_egg = self._include_egg and not self._cache_egg.generated + if gen_dist or gen_egg: + for dist in self._yield_distributions(): + if isinstance(dist, InstalledDistribution): + self._cache.add(dist) + else: + self._cache_egg.add(dist) + + if gen_dist: + self._cache.generated = True + if gen_egg: + self._cache_egg.generated = True + + @classmethod + def distinfo_dirname(cls, name, version): + """ + The *name* and *version* parameters are converted into their + filename-escaped form, i.e. any ``'-'`` characters are replaced + with ``'_'`` other than the one in ``'dist-info'`` and the one + separating the name from the version number. + + :parameter name: is converted to a standard distribution name by replacing + any runs of non- alphanumeric characters with a single + ``'-'``. + :type name: string + :parameter version: is converted to a standard version string. Spaces + become dots, and all other non-alphanumeric characters + (except dots) become dashes, with runs of multiple + dashes condensed to a single dash. + :type version: string + :returns: directory name + :rtype: string""" + name = name.replace('-', '_') + return '-'.join([name, version]) + DISTINFO_EXT + + def get_distributions(self): + """ + Provides an iterator that looks for distributions and returns + :class:`InstalledDistribution` or + :class:`EggInfoDistribution` instances for each one of them. + + :rtype: iterator of :class:`InstalledDistribution` and + :class:`EggInfoDistribution` instances + """ + if not self._cache_enabled: + for dist in self._yield_distributions(): + yield dist + else: + self._generate_cache() + + for dist in self._cache.path.values(): + yield dist + + if self._include_egg: + for dist in self._cache_egg.path.values(): + yield dist + + def get_distribution(self, name): + """ + Looks for a named distribution on the path. + + This function only returns the first result found, as no more than one + value is expected. If nothing is found, ``None`` is returned. + + :rtype: :class:`InstalledDistribution`, :class:`EggInfoDistribution` + or ``None`` + """ + result = None + name = name.lower() + if not self._cache_enabled: + for dist in self._yield_distributions(): + if dist.key == name: + result = dist + break + else: + self._generate_cache() + + if name in self._cache.name: + result = self._cache.name[name][0] + elif self._include_egg and name in self._cache_egg.name: + result = self._cache_egg.name[name][0] + return result + + def provides_distribution(self, name, version=None): + """ + Iterates over all distributions to find which distributions provide *name*. + If a *version* is provided, it will be used to filter the results. + + This function only returns the first result found, since no more than + one values are expected. If the directory is not found, returns ``None``. + + :parameter version: a version specifier that indicates the version + required, conforming to the format in ``PEP-345`` + + :type name: string + :type version: string + """ + matcher = None + if version is not None: + try: + matcher = self._scheme.matcher('%s (%s)' % (name, version)) + except ValueError: + raise DistlibException('invalid name or version: %r, %r' % + (name, version)) + + for dist in self.get_distributions(): + # We hit a problem on Travis where enum34 was installed and doesn't + # have a provides attribute ... + if not hasattr(dist, 'provides'): + logger.debug('No "provides": %s', dist) + else: + provided = dist.provides + + for p in provided: + p_name, p_ver = parse_name_and_version(p) + if matcher is None: + if p_name == name: + yield dist + break + else: + if p_name == name and matcher.match(p_ver): + yield dist + break + + def get_file_path(self, name, relative_path): + """ + Return the path to a resource file. + """ + dist = self.get_distribution(name) + if dist is None: + raise LookupError('no distribution named %r found' % name) + return dist.get_resource_path(relative_path) + + def get_exported_entries(self, category, name=None): + """ + Return all of the exported entries in a particular category. + + :param category: The category to search for entries. + :param name: If specified, only entries with that name are returned. + """ + for dist in self.get_distributions(): + r = dist.exports + if category in r: + d = r[category] + if name is not None: + if name in d: + yield d[name] + else: + for v in d.values(): + yield v + + +class Distribution(object): + """ + A base class for distributions, whether installed or from indexes. + Either way, it must have some metadata, so that's all that's needed + for construction. + """ + + build_time_dependency = False + """ + Set to True if it's known to be only a build-time dependency (i.e. + not needed after installation). + """ + + requested = False + """A boolean that indicates whether the ``REQUESTED`` metadata file is + present (in other words, whether the package was installed by user + request or it was installed as a dependency).""" + + def __init__(self, metadata): + """ + Initialise an instance. + :param metadata: The instance of :class:`Metadata` describing this + distribution. + """ + self.metadata = metadata + self.name = metadata.name + self.key = self.name.lower() # for case-insensitive comparisons + self.version = metadata.version + self.locator = None + self.digest = None + self.extras = None # additional features requested + self.context = None # environment marker overrides + self.download_urls = set() + self.digests = {} + + @property + def source_url(self): + """ + The source archive download URL for this distribution. + """ + return self.metadata.source_url + + download_url = source_url # Backward compatibility + + @property + def name_and_version(self): + """ + A utility property which displays the name and version in parentheses. + """ + return '%s (%s)' % (self.name, self.version) + + @property + def provides(self): + """ + A set of distribution names and versions provided by this distribution. + :return: A set of "name (version)" strings. + """ + plist = self.metadata.provides + s = '%s (%s)' % (self.name, self.version) + if s not in plist: + plist.append(s) + return plist + + def _get_requirements(self, req_attr): + md = self.metadata + logger.debug('Getting requirements from metadata %r', md.todict()) + reqts = getattr(md, req_attr) + return set(md.get_requirements(reqts, extras=self.extras, + env=self.context)) + + @property + def run_requires(self): + return self._get_requirements('run_requires') + + @property + def meta_requires(self): + return self._get_requirements('meta_requires') + + @property + def build_requires(self): + return self._get_requirements('build_requires') + + @property + def test_requires(self): + return self._get_requirements('test_requires') + + @property + def dev_requires(self): + return self._get_requirements('dev_requires') + + def matches_requirement(self, req): + """ + Say if this instance matches (fulfills) a requirement. + :param req: The requirement to match. + :rtype req: str + :return: True if it matches, else False. + """ + # Requirement may contain extras - parse to lose those + # from what's passed to the matcher + r = parse_requirement(req) + scheme = get_scheme(self.metadata.scheme) + try: + matcher = scheme.matcher(r.requirement) + except UnsupportedVersionError: + # XXX compat-mode if cannot read the version + logger.warning('could not read version %r - using name only', + req) + name = req.split()[0] + matcher = scheme.matcher(name) + + name = matcher.key # case-insensitive + + result = False + for p in self.provides: + p_name, p_ver = parse_name_and_version(p) + if p_name != name: + continue + try: + result = matcher.match(p_ver) + break + except UnsupportedVersionError: + pass + return result + + def __repr__(self): + """ + Return a textual representation of this instance, + """ + if self.source_url: + suffix = ' [%s]' % self.source_url + else: + suffix = '' + return '<Distribution %s (%s)%s>' % (self.name, self.version, suffix) + + def __eq__(self, other): + """ + See if this distribution is the same as another. + :param other: The distribution to compare with. To be equal to one + another. distributions must have the same type, name, + version and source_url. + :return: True if it is the same, else False. + """ + if type(other) is not type(self): + result = False + else: + result = (self.name == other.name and + self.version == other.version and + self.source_url == other.source_url) + return result + + def __hash__(self): + """ + Compute hash in a way which matches the equality test. + """ + return hash(self.name) + hash(self.version) + hash(self.source_url) + + +class BaseInstalledDistribution(Distribution): + """ + This is the base class for installed distributions (whether PEP 376 or + legacy). + """ + + hasher = None + + def __init__(self, metadata, path, env=None): + """ + Initialise an instance. + :param metadata: An instance of :class:`Metadata` which describes the + distribution. This will normally have been initialised + from a metadata file in the ``path``. + :param path: The path of the ``.dist-info`` or ``.egg-info`` + directory for the distribution. + :param env: This is normally the :class:`DistributionPath` + instance where this distribution was found. + """ + super(BaseInstalledDistribution, self).__init__(metadata) + self.path = path + self.dist_path = env + + def get_hash(self, data, hasher=None): + """ + Get the hash of some data, using a particular hash algorithm, if + specified. + + :param data: The data to be hashed. + :type data: bytes + :param hasher: The name of a hash implementation, supported by hashlib, + or ``None``. Examples of valid values are ``'sha1'``, + ``'sha224'``, ``'sha384'``, '``sha256'``, ``'md5'`` and + ``'sha512'``. If no hasher is specified, the ``hasher`` + attribute of the :class:`InstalledDistribution` instance + is used. If the hasher is determined to be ``None``, MD5 + is used as the hashing algorithm. + :returns: The hash of the data. If a hasher was explicitly specified, + the returned hash will be prefixed with the specified hasher + followed by '='. + :rtype: str + """ + if hasher is None: + hasher = self.hasher + if hasher is None: + hasher = hashlib.md5 + prefix = '' + else: + hasher = getattr(hashlib, hasher) + prefix = '%s=' % self.hasher + digest = hasher(data).digest() + digest = base64.urlsafe_b64encode(digest).rstrip(b'=').decode('ascii') + return '%s%s' % (prefix, digest) + + +class InstalledDistribution(BaseInstalledDistribution): + """ + Created with the *path* of the ``.dist-info`` directory provided to the + constructor. It reads the metadata contained in ``pydist.json`` when it is + instantiated., or uses a passed in Metadata instance (useful for when + dry-run mode is being used). + """ + + hasher = 'sha256' + + def __init__(self, path, metadata=None, env=None): + self.modules = [] + self.finder = finder = resources.finder_for_path(path) + if finder is None: + raise ValueError('finder unavailable for %s' % path) + if env and env._cache_enabled and path in env._cache.path: + metadata = env._cache.path[path].metadata + elif metadata is None: + r = finder.find(METADATA_FILENAME) + # Temporary - for Wheel 0.23 support + if r is None: + r = finder.find(WHEEL_METADATA_FILENAME) + # Temporary - for legacy support + if r is None: + r = finder.find('METADATA') + if r is None: + raise ValueError('no %s found in %s' % (METADATA_FILENAME, + path)) + with contextlib.closing(r.as_stream()) as stream: + metadata = Metadata(fileobj=stream, scheme='legacy') + + super(InstalledDistribution, self).__init__(metadata, path, env) + + if env and env._cache_enabled: + env._cache.add(self) + + r = finder.find('REQUESTED') + self.requested = r is not None + p = os.path.join(path, 'top_level.txt') + if os.path.exists(p): + with open(p, 'rb') as f: + data = f.read() + self.modules = data.splitlines() + + def __repr__(self): + return '<InstalledDistribution %r %s at %r>' % ( + self.name, self.version, self.path) + + def __str__(self): + return "%s %s" % (self.name, self.version) + + def _get_records(self): + """ + Get the list of installed files for the distribution + :return: A list of tuples of path, hash and size. Note that hash and + size might be ``None`` for some entries. The path is exactly + as stored in the file (which is as in PEP 376). + """ + results = [] + r = self.get_distinfo_resource('RECORD') + with contextlib.closing(r.as_stream()) as stream: + with CSVReader(stream=stream) as record_reader: + # Base location is parent dir of .dist-info dir + #base_location = os.path.dirname(self.path) + #base_location = os.path.abspath(base_location) + for row in record_reader: + missing = [None for i in range(len(row), 3)] + path, checksum, size = row + missing + #if not os.path.isabs(path): + # path = path.replace('/', os.sep) + # path = os.path.join(base_location, path) + results.append((path, checksum, size)) + return results + + @cached_property + def exports(self): + """ + Return the information exported by this distribution. + :return: A dictionary of exports, mapping an export category to a dict + of :class:`ExportEntry` instances describing the individual + export entries, and keyed by name. + """ + result = {} + r = self.get_distinfo_resource(EXPORTS_FILENAME) + if r: + result = self.read_exports() + return result + + def read_exports(self): + """ + Read exports data from a file in .ini format. + + :return: A dictionary of exports, mapping an export category to a list + of :class:`ExportEntry` instances describing the individual + export entries. + """ + result = {} + r = self.get_distinfo_resource(EXPORTS_FILENAME) + if r: + with contextlib.closing(r.as_stream()) as stream: + result = read_exports(stream) + return result + + def write_exports(self, exports): + """ + Write a dictionary of exports to a file in .ini format. + :param exports: A dictionary of exports, mapping an export category to + a list of :class:`ExportEntry` instances describing the + individual export entries. + """ + rf = self.get_distinfo_file(EXPORTS_FILENAME) + with open(rf, 'w') as f: + write_exports(exports, f) + + def get_resource_path(self, relative_path): + """ + NOTE: This API may change in the future. + + Return the absolute path to a resource file with the given relative + path. + + :param relative_path: The path, relative to .dist-info, of the resource + of interest. + :return: The absolute path where the resource is to be found. + """ + r = self.get_distinfo_resource('RESOURCES') + with contextlib.closing(r.as_stream()) as stream: + with CSVReader(stream=stream) as resources_reader: + for relative, destination in resources_reader: + if relative == relative_path: + return destination + raise KeyError('no resource file with relative path %r ' + 'is installed' % relative_path) + + def list_installed_files(self): + """ + Iterates over the ``RECORD`` entries and returns a tuple + ``(path, hash, size)`` for each line. + + :returns: iterator of (path, hash, size) + """ + for result in self._get_records(): + yield result + + def write_installed_files(self, paths, prefix, dry_run=False): + """ + Writes the ``RECORD`` file, using the ``paths`` iterable passed in. Any + existing ``RECORD`` file is silently overwritten. + + prefix is used to determine when to write absolute paths. + """ + prefix = os.path.join(prefix, '') + base = os.path.dirname(self.path) + base_under_prefix = base.startswith(prefix) + base = os.path.join(base, '') + record_path = self.get_distinfo_file('RECORD') + logger.info('creating %s', record_path) + if dry_run: + return None + with CSVWriter(record_path) as writer: + for path in paths: + if os.path.isdir(path) or path.endswith(('.pyc', '.pyo')): + # do not put size and hash, as in PEP-376 + hash_value = size = '' + else: + size = '%d' % os.path.getsize(path) + with open(path, 'rb') as fp: + hash_value = self.get_hash(fp.read()) + if path.startswith(base) or (base_under_prefix and + path.startswith(prefix)): + path = os.path.relpath(path, base) + writer.writerow((path, hash_value, size)) + + # add the RECORD file itself + if record_path.startswith(base): + record_path = os.path.relpath(record_path, base) + writer.writerow((record_path, '', '')) + return record_path + + def check_installed_files(self): + """ + Checks that the hashes and sizes of the files in ``RECORD`` are + matched by the files themselves. Returns a (possibly empty) list of + mismatches. Each entry in the mismatch list will be a tuple consisting + of the path, 'exists', 'size' or 'hash' according to what didn't match + (existence is checked first, then size, then hash), the expected + value and the actual value. + """ + mismatches = [] + base = os.path.dirname(self.path) + record_path = self.get_distinfo_file('RECORD') + for path, hash_value, size in self.list_installed_files(): + if not os.path.isabs(path): + path = os.path.join(base, path) + if path == record_path: + continue + if not os.path.exists(path): + mismatches.append((path, 'exists', True, False)) + elif os.path.isfile(path): + actual_size = str(os.path.getsize(path)) + if size and actual_size != size: + mismatches.append((path, 'size', size, actual_size)) + elif hash_value: + if '=' in hash_value: + hasher = hash_value.split('=', 1)[0] + else: + hasher = None + + with open(path, 'rb') as f: + actual_hash = self.get_hash(f.read(), hasher) + if actual_hash != hash_value: + mismatches.append((path, 'hash', hash_value, actual_hash)) + return mismatches + + @cached_property + def shared_locations(self): + """ + A dictionary of shared locations whose keys are in the set 'prefix', + 'purelib', 'platlib', 'scripts', 'headers', 'data' and 'namespace'. + The corresponding value is the absolute path of that category for + this distribution, and takes into account any paths selected by the + user at installation time (e.g. via command-line arguments). In the + case of the 'namespace' key, this would be a list of absolute paths + for the roots of namespace packages in this distribution. + + The first time this property is accessed, the relevant information is + read from the SHARED file in the .dist-info directory. + """ + result = {} + shared_path = os.path.join(self.path, 'SHARED') + if os.path.isfile(shared_path): + with codecs.open(shared_path, 'r', encoding='utf-8') as f: + lines = f.read().splitlines() + for line in lines: + key, value = line.split('=', 1) + if key == 'namespace': + result.setdefault(key, []).append(value) + else: + result[key] = value + return result + + def write_shared_locations(self, paths, dry_run=False): + """ + Write shared location information to the SHARED file in .dist-info. + :param paths: A dictionary as described in the documentation for + :meth:`shared_locations`. + :param dry_run: If True, the action is logged but no file is actually + written. + :return: The path of the file written to. + """ + shared_path = os.path.join(self.path, 'SHARED') + logger.info('creating %s', shared_path) + if dry_run: + return None + lines = [] + for key in ('prefix', 'lib', 'headers', 'scripts', 'data'): + path = paths[key] + if os.path.isdir(paths[key]): + lines.append('%s=%s' % (key, path)) + for ns in paths.get('namespace', ()): + lines.append('namespace=%s' % ns) + + with codecs.open(shared_path, 'w', encoding='utf-8') as f: + f.write('\n'.join(lines)) + return shared_path + + def get_distinfo_resource(self, path): + if path not in DIST_FILES: + raise DistlibException('invalid path for a dist-info file: ' + '%r at %r' % (path, self.path)) + finder = resources.finder_for_path(self.path) + if finder is None: + raise DistlibException('Unable to get a finder for %s' % self.path) + return finder.find(path) + + def get_distinfo_file(self, path): + """ + Returns a path located under the ``.dist-info`` directory. Returns a + string representing the path. + + :parameter path: a ``'/'``-separated path relative to the + ``.dist-info`` directory or an absolute path; + If *path* is an absolute path and doesn't start + with the ``.dist-info`` directory path, + a :class:`DistlibException` is raised + :type path: str + :rtype: str + """ + # Check if it is an absolute path # XXX use relpath, add tests + if path.find(os.sep) >= 0: + # it's an absolute path? + distinfo_dirname, path = path.split(os.sep)[-2:] + if distinfo_dirname != self.path.split(os.sep)[-1]: + raise DistlibException( + 'dist-info file %r does not belong to the %r %s ' + 'distribution' % (path, self.name, self.version)) + + # The file must be relative + if path not in DIST_FILES: + raise DistlibException('invalid path for a dist-info file: ' + '%r at %r' % (path, self.path)) + + return os.path.join(self.path, path) + + def list_distinfo_files(self): + """ + Iterates over the ``RECORD`` entries and returns paths for each line if + the path is pointing to a file located in the ``.dist-info`` directory + or one of its subdirectories. + + :returns: iterator of paths + """ + base = os.path.dirname(self.path) + for path, checksum, size in self._get_records(): + # XXX add separator or use real relpath algo + if not os.path.isabs(path): + path = os.path.join(base, path) + if path.startswith(self.path): + yield path + + def __eq__(self, other): + return (isinstance(other, InstalledDistribution) and + self.path == other.path) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + __hash__ = object.__hash__ + + +class EggInfoDistribution(BaseInstalledDistribution): + """Created with the *path* of the ``.egg-info`` directory or file provided + to the constructor. It reads the metadata contained in the file itself, or + if the given path happens to be a directory, the metadata is read from the + file ``PKG-INFO`` under that directory.""" + + requested = True # as we have no way of knowing, assume it was + shared_locations = {} + + def __init__(self, path, env=None): + def set_name_and_version(s, n, v): + s.name = n + s.key = n.lower() # for case-insensitive comparisons + s.version = v + + self.path = path + self.dist_path = env + if env and env._cache_enabled and path in env._cache_egg.path: + metadata = env._cache_egg.path[path].metadata + set_name_and_version(self, metadata.name, metadata.version) + else: + metadata = self._get_metadata(path) + + # Need to be set before caching + set_name_and_version(self, metadata.name, metadata.version) + + if env and env._cache_enabled: + env._cache_egg.add(self) + super(EggInfoDistribution, self).__init__(metadata, path, env) + + def _get_metadata(self, path): + requires = None + + def parse_requires_data(data): + """Create a list of dependencies from a requires.txt file. + + *data*: the contents of a setuptools-produced requires.txt file. + """ + reqs = [] + lines = data.splitlines() + for line in lines: + line = line.strip() + if line.startswith('['): + logger.warning('Unexpected line: quitting requirement scan: %r', + line) + break + r = parse_requirement(line) + if not r: + logger.warning('Not recognised as a requirement: %r', line) + continue + if r.extras: + logger.warning('extra requirements in requires.txt are ' + 'not supported') + if not r.constraints: + reqs.append(r.name) + else: + cons = ', '.join('%s%s' % c for c in r.constraints) + reqs.append('%s (%s)' % (r.name, cons)) + return reqs + + def parse_requires_path(req_path): + """Create a list of dependencies from a requires.txt file. + + *req_path*: the path to a setuptools-produced requires.txt file. + """ + + reqs = [] + try: + with codecs.open(req_path, 'r', 'utf-8') as fp: + reqs = parse_requires_data(fp.read()) + except IOError: + pass + return reqs + + tl_path = tl_data = None + if path.endswith('.egg'): + if os.path.isdir(path): + p = os.path.join(path, 'EGG-INFO') + meta_path = os.path.join(p, 'PKG-INFO') + metadata = Metadata(path=meta_path, scheme='legacy') + req_path = os.path.join(p, 'requires.txt') + tl_path = os.path.join(p, 'top_level.txt') + requires = parse_requires_path(req_path) + else: + # FIXME handle the case where zipfile is not available + zipf = zipimport.zipimporter(path) + fileobj = StringIO( + zipf.get_data('EGG-INFO/PKG-INFO').decode('utf8')) + metadata = Metadata(fileobj=fileobj, scheme='legacy') + try: + data = zipf.get_data('EGG-INFO/requires.txt') + tl_data = zipf.get_data('EGG-INFO/top_level.txt').decode('utf-8') + requires = parse_requires_data(data.decode('utf-8')) + except IOError: + requires = None + elif path.endswith('.egg-info'): + if os.path.isdir(path): + req_path = os.path.join(path, 'requires.txt') + requires = parse_requires_path(req_path) + path = os.path.join(path, 'PKG-INFO') + tl_path = os.path.join(path, 'top_level.txt') + metadata = Metadata(path=path, scheme='legacy') + else: + raise DistlibException('path must end with .egg-info or .egg, ' + 'got %r' % path) + + if requires: + metadata.add_requirements(requires) + # look for top-level modules in top_level.txt, if present + if tl_data is None: + if tl_path is not None and os.path.exists(tl_path): + with open(tl_path, 'rb') as f: + tl_data = f.read().decode('utf-8') + if not tl_data: + tl_data = [] + else: + tl_data = tl_data.splitlines() + self.modules = tl_data + return metadata + + def __repr__(self): + return '<EggInfoDistribution %r %s at %r>' % ( + self.name, self.version, self.path) + + def __str__(self): + return "%s %s" % (self.name, self.version) + + def check_installed_files(self): + """ + Checks that the hashes and sizes of the files in ``RECORD`` are + matched by the files themselves. Returns a (possibly empty) list of + mismatches. Each entry in the mismatch list will be a tuple consisting + of the path, 'exists', 'size' or 'hash' according to what didn't match + (existence is checked first, then size, then hash), the expected + value and the actual value. + """ + mismatches = [] + record_path = os.path.join(self.path, 'installed-files.txt') + if os.path.exists(record_path): + for path, _, _ in self.list_installed_files(): + if path == record_path: + continue + if not os.path.exists(path): + mismatches.append((path, 'exists', True, False)) + return mismatches + + def list_installed_files(self): + """ + Iterates over the ``installed-files.txt`` entries and returns a tuple + ``(path, hash, size)`` for each line. + + :returns: a list of (path, hash, size) + """ + + def _md5(path): + f = open(path, 'rb') + try: + content = f.read() + finally: + f.close() + return hashlib.md5(content).hexdigest() + + def _size(path): + return os.stat(path).st_size + + record_path = os.path.join(self.path, 'installed-files.txt') + result = [] + if os.path.exists(record_path): + with codecs.open(record_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + p = os.path.normpath(os.path.join(self.path, line)) + # "./" is present as a marker between installed files + # and installation metadata files + if not os.path.exists(p): + logger.warning('Non-existent file: %s', p) + if p.endswith(('.pyc', '.pyo')): + continue + #otherwise fall through and fail + if not os.path.isdir(p): + result.append((p, _md5(p), _size(p))) + result.append((record_path, None, None)) + return result + + def list_distinfo_files(self, absolute=False): + """ + Iterates over the ``installed-files.txt`` entries and returns paths for + each line if the path is pointing to a file located in the + ``.egg-info`` directory or one of its subdirectories. + + :parameter absolute: If *absolute* is ``True``, each returned path is + transformed into a local absolute path. Otherwise the + raw value from ``installed-files.txt`` is returned. + :type absolute: boolean + :returns: iterator of paths + """ + record_path = os.path.join(self.path, 'installed-files.txt') + if os.path.exists(record_path): + skip = True + with codecs.open(record_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + if line == './': + skip = False + continue + if not skip: + p = os.path.normpath(os.path.join(self.path, line)) + if p.startswith(self.path): + if absolute: + yield p + else: + yield line + + def __eq__(self, other): + return (isinstance(other, EggInfoDistribution) and + self.path == other.path) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + __hash__ = object.__hash__ + +new_dist_class = InstalledDistribution +old_dist_class = EggInfoDistribution + + +class DependencyGraph(object): + """ + Represents a dependency graph between distributions. + + The dependency relationships are stored in an ``adjacency_list`` that maps + distributions to a list of ``(other, label)`` tuples where ``other`` + is a distribution and the edge is labeled with ``label`` (i.e. the version + specifier, if such was provided). Also, for more efficient traversal, for + every distribution ``x``, a list of predecessors is kept in + ``reverse_list[x]``. An edge from distribution ``a`` to + distribution ``b`` means that ``a`` depends on ``b``. If any missing + dependencies are found, they are stored in ``missing``, which is a + dictionary that maps distributions to a list of requirements that were not + provided by any other distributions. + """ + + def __init__(self): + self.adjacency_list = {} + self.reverse_list = {} + self.missing = {} + + def add_distribution(self, distribution): + """Add the *distribution* to the graph. + + :type distribution: :class:`distutils2.database.InstalledDistribution` + or :class:`distutils2.database.EggInfoDistribution` + """ + self.adjacency_list[distribution] = [] + self.reverse_list[distribution] = [] + #self.missing[distribution] = [] + + def add_edge(self, x, y, label=None): + """Add an edge from distribution *x* to distribution *y* with the given + *label*. + + :type x: :class:`distutils2.database.InstalledDistribution` or + :class:`distutils2.database.EggInfoDistribution` + :type y: :class:`distutils2.database.InstalledDistribution` or + :class:`distutils2.database.EggInfoDistribution` + :type label: ``str`` or ``None`` + """ + self.adjacency_list[x].append((y, label)) + # multiple edges are allowed, so be careful + if x not in self.reverse_list[y]: + self.reverse_list[y].append(x) + + def add_missing(self, distribution, requirement): + """ + Add a missing *requirement* for the given *distribution*. + + :type distribution: :class:`distutils2.database.InstalledDistribution` + or :class:`distutils2.database.EggInfoDistribution` + :type requirement: ``str`` + """ + logger.debug('%s missing %r', distribution, requirement) + self.missing.setdefault(distribution, []).append(requirement) + + def _repr_dist(self, dist): + return '%s %s' % (dist.name, dist.version) + + def repr_node(self, dist, level=1): + """Prints only a subgraph""" + output = [self._repr_dist(dist)] + for other, label in self.adjacency_list[dist]: + dist = self._repr_dist(other) + if label is not None: + dist = '%s [%s]' % (dist, label) + output.append(' ' * level + str(dist)) + suboutput = self.repr_node(other, level + 1) + subs = suboutput.split('\n') + output.extend(subs[1:]) + return '\n'.join(output) + + def to_dot(self, f, skip_disconnected=True): + """Writes a DOT output for the graph to the provided file *f*. + + If *skip_disconnected* is set to ``True``, then all distributions + that are not dependent on any other distribution are skipped. + + :type f: has to support ``file``-like operations + :type skip_disconnected: ``bool`` + """ + disconnected = [] + + f.write("digraph dependencies {\n") + for dist, adjs in self.adjacency_list.items(): + if len(adjs) == 0 and not skip_disconnected: + disconnected.append(dist) + for other, label in adjs: + if not label is None: + f.write('"%s" -> "%s" [label="%s"]\n' % + (dist.name, other.name, label)) + else: + f.write('"%s" -> "%s"\n' % (dist.name, other.name)) + if not skip_disconnected and len(disconnected) > 0: + f.write('subgraph disconnected {\n') + f.write('label = "Disconnected"\n') + f.write('bgcolor = red\n') + + for dist in disconnected: + f.write('"%s"' % dist.name) + f.write('\n') + f.write('}\n') + f.write('}\n') + + def topological_sort(self): + """ + Perform a topological sort of the graph. + :return: A tuple, the first element of which is a topologically sorted + list of distributions, and the second element of which is a + list of distributions that cannot be sorted because they have + circular dependencies and so form a cycle. + """ + result = [] + # Make a shallow copy of the adjacency list + alist = {} + for k, v in self.adjacency_list.items(): + alist[k] = v[:] + while True: + # See what we can remove in this run + to_remove = [] + for k, v in list(alist.items())[:]: + if not v: + to_remove.append(k) + del alist[k] + if not to_remove: + # What's left in alist (if anything) is a cycle. + break + # Remove from the adjacency list of others + for k, v in alist.items(): + alist[k] = [(d, r) for d, r in v if d not in to_remove] + logger.debug('Moving to result: %s', + ['%s (%s)' % (d.name, d.version) for d in to_remove]) + result.extend(to_remove) + return result, list(alist.keys()) + + def __repr__(self): + """Representation of the graph""" + output = [] + for dist, adjs in self.adjacency_list.items(): + output.append(self.repr_node(dist)) + return '\n'.join(output) + + +def make_graph(dists, scheme='default'): + """Makes a dependency graph from the given distributions. + + :parameter dists: a list of distributions + :type dists: list of :class:`distutils2.database.InstalledDistribution` and + :class:`distutils2.database.EggInfoDistribution` instances + :rtype: a :class:`DependencyGraph` instance + """ + scheme = get_scheme(scheme) + graph = DependencyGraph() + provided = {} # maps names to lists of (version, dist) tuples + + # first, build the graph and find out what's provided + for dist in dists: + graph.add_distribution(dist) + + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Add to provided: %s, %s, %s', name, version, dist) + provided.setdefault(name, []).append((version, dist)) + + # now make the edges + for dist in dists: + requires = (dist.run_requires | dist.meta_requires | + dist.build_requires | dist.dev_requires) + for req in requires: + try: + matcher = scheme.matcher(req) + except UnsupportedVersionError: + # XXX compat-mode if cannot read the version + logger.warning('could not read version %r - using name only', + req) + name = req.split()[0] + matcher = scheme.matcher(name) + + name = matcher.key # case-insensitive + + matched = False + if name in provided: + for version, provider in provided[name]: + try: + match = matcher.match(version) + except UnsupportedVersionError: + match = False + + if match: + graph.add_edge(dist, provider, req) + matched = True + break + if not matched: + graph.add_missing(dist, req) + return graph + + +def get_dependent_dists(dists, dist): + """Recursively generate a list of distributions from *dists* that are + dependent on *dist*. + + :param dists: a list of distributions + :param dist: a distribution, member of *dists* for which we are interested + """ + if dist not in dists: + raise DistlibException('given distribution %r is not a member ' + 'of the list' % dist.name) + graph = make_graph(dists) + + dep = [dist] # dependent distributions + todo = graph.reverse_list[dist] # list of nodes we should inspect + + while todo: + d = todo.pop() + dep.append(d) + for succ in graph.reverse_list[d]: + if succ not in dep: + todo.append(succ) + + dep.pop(0) # remove dist from dep, was there to prevent infinite loops + return dep + + +def get_required_dists(dists, dist): + """Recursively generate a list of distributions from *dists* that are + required by *dist*. + + :param dists: a list of distributions + :param dist: a distribution, member of *dists* for which we are interested + """ + if dist not in dists: + raise DistlibException('given distribution %r is not a member ' + 'of the list' % dist.name) + graph = make_graph(dists) + + req = [] # required distributions + todo = graph.adjacency_list[dist] # list of nodes we should inspect + + while todo: + d = todo.pop()[0] + req.append(d) + for pred in graph.adjacency_list[d]: + if pred not in req: + todo.append(pred) + + return req + + +def make_dist(name, version, **kwargs): + """ + A convenience method for making a dist given just a name and version. + """ + summary = kwargs.pop('summary', 'Placeholder for summary') + md = Metadata(**kwargs) + md.name = name + md.version = version + md.summary = summary or 'Placeholder for summary' + return Distribution(md) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/index.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/index.py new file mode 100644 index 0000000..2406be2 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/index.py @@ -0,0 +1,516 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import hashlib +import logging +import os +import shutil +import subprocess +import tempfile +try: + from threading import Thread +except ImportError: + from dummy_threading import Thread + +from . import DistlibException +from .compat import (HTTPBasicAuthHandler, Request, HTTPPasswordMgr, + urlparse, build_opener, string_types) +from .util import cached_property, zip_dir, ServerProxy + +logger = logging.getLogger(__name__) + +DEFAULT_INDEX = 'https://pypi.python.org/pypi' +DEFAULT_REALM = 'pypi' + +class PackageIndex(object): + """ + This class represents a package index compatible with PyPI, the Python + Package Index. + """ + + boundary = b'----------ThIs_Is_tHe_distlib_index_bouNdaRY_$' + + def __init__(self, url=None): + """ + Initialise an instance. + + :param url: The URL of the index. If not specified, the URL for PyPI is + used. + """ + self.url = url or DEFAULT_INDEX + self.read_configuration() + scheme, netloc, path, params, query, frag = urlparse(self.url) + if params or query or frag or scheme not in ('http', 'https'): + raise DistlibException('invalid repository: %s' % self.url) + self.password_handler = None + self.ssl_verifier = None + self.gpg = None + self.gpg_home = None + with open(os.devnull, 'w') as sink: + # Use gpg by default rather than gpg2, as gpg2 insists on + # prompting for passwords + for s in ('gpg', 'gpg2'): + try: + rc = subprocess.check_call([s, '--version'], stdout=sink, + stderr=sink) + if rc == 0: + self.gpg = s + break + except OSError: + pass + + def _get_pypirc_command(self): + """ + Get the distutils command for interacting with PyPI configurations. + :return: the command. + """ + from distutils.core import Distribution + from distutils.config import PyPIRCCommand + d = Distribution() + return PyPIRCCommand(d) + + def read_configuration(self): + """ + Read the PyPI access configuration as supported by distutils, getting + PyPI to do the actual work. This populates ``username``, ``password``, + ``realm`` and ``url`` attributes from the configuration. + """ + # get distutils to do the work + c = self._get_pypirc_command() + c.repository = self.url + cfg = c._read_pypirc() + self.username = cfg.get('username') + self.password = cfg.get('password') + self.realm = cfg.get('realm', 'pypi') + self.url = cfg.get('repository', self.url) + + def save_configuration(self): + """ + Save the PyPI access configuration. You must have set ``username`` and + ``password`` attributes before calling this method. + + Again, distutils is used to do the actual work. + """ + self.check_credentials() + # get distutils to do the work + c = self._get_pypirc_command() + c._store_pypirc(self.username, self.password) + + def check_credentials(self): + """ + Check that ``username`` and ``password`` have been set, and raise an + exception if not. + """ + if self.username is None or self.password is None: + raise DistlibException('username and password must be set') + pm = HTTPPasswordMgr() + _, netloc, _, _, _, _ = urlparse(self.url) + pm.add_password(self.realm, netloc, self.username, self.password) + self.password_handler = HTTPBasicAuthHandler(pm) + + def register(self, metadata): + """ + Register a distribution on PyPI, using the provided metadata. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the distribution to be + registered. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + metadata.validate() + d = metadata.todict() + d[':action'] = 'verify' + request = self.encode_request(d.items(), []) + response = self.send_request(request) + d[':action'] = 'submit' + request = self.encode_request(d.items(), []) + return self.send_request(request) + + def _reader(self, name, stream, outbuf): + """ + Thread runner for reading lines of from a subprocess into a buffer. + + :param name: The logical name of the stream (used for logging only). + :param stream: The stream to read from. This will typically a pipe + connected to the output stream of a subprocess. + :param outbuf: The list to append the read lines to. + """ + while True: + s = stream.readline() + if not s: + break + s = s.decode('utf-8').rstrip() + outbuf.append(s) + logger.debug('%s: %s' % (name, s)) + stream.close() + + def get_sign_command(self, filename, signer, sign_password, + keystore=None): + """ + Return a suitable command for signing a file. + + :param filename: The pathname to the file to be signed. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: The signing command as a list suitable to be + passed to :class:`subprocess.Popen`. + """ + cmd = [self.gpg, '--status-fd', '2', '--no-tty'] + if keystore is None: + keystore = self.gpg_home + if keystore: + cmd.extend(['--homedir', keystore]) + if sign_password is not None: + cmd.extend(['--batch', '--passphrase-fd', '0']) + td = tempfile.mkdtemp() + sf = os.path.join(td, os.path.basename(filename) + '.asc') + cmd.extend(['--detach-sign', '--armor', '--local-user', + signer, '--output', sf, filename]) + logger.debug('invoking: %s', ' '.join(cmd)) + return cmd, sf + + def run_command(self, cmd, input_data=None): + """ + Run a command in a child process , passing it any input data specified. + + :param cmd: The command to run. + :param input_data: If specified, this must be a byte string containing + data to be sent to the child process. + :return: A tuple consisting of the subprocess' exit code, a list of + lines read from the subprocess' ``stdout``, and a list of + lines read from the subprocess' ``stderr``. + """ + kwargs = { + 'stdout': subprocess.PIPE, + 'stderr': subprocess.PIPE, + } + if input_data is not None: + kwargs['stdin'] = subprocess.PIPE + stdout = [] + stderr = [] + p = subprocess.Popen(cmd, **kwargs) + # We don't use communicate() here because we may need to + # get clever with interacting with the command + t1 = Thread(target=self._reader, args=('stdout', p.stdout, stdout)) + t1.start() + t2 = Thread(target=self._reader, args=('stderr', p.stderr, stderr)) + t2.start() + if input_data is not None: + p.stdin.write(input_data) + p.stdin.close() + + p.wait() + t1.join() + t2.join() + return p.returncode, stdout, stderr + + def sign_file(self, filename, signer, sign_password, keystore=None): + """ + Sign a file. + + :param filename: The pathname to the file to be signed. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param keystore: The path to a directory which contains the keys + used in signing. If not specified, the instance's + ``gpg_home`` attribute is used instead. + :return: The absolute pathname of the file where the signature is + stored. + """ + cmd, sig_file = self.get_sign_command(filename, signer, sign_password, + keystore) + rc, stdout, stderr = self.run_command(cmd, + sign_password.encode('utf-8')) + if rc != 0: + raise DistlibException('sign command failed with error ' + 'code %s' % rc) + return sig_file + + def upload_file(self, metadata, filename, signer=None, sign_password=None, + filetype='sdist', pyversion='source', keystore=None): + """ + Upload a release file to the index. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the file to be uploaded. + :param filename: The pathname of the file to be uploaded. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param filetype: The type of the file being uploaded. This is the + distutils command which produced that file, e.g. + ``sdist`` or ``bdist_wheel``. + :param pyversion: The version of Python which the release relates + to. For code compatible with any Python, this would + be ``source``, otherwise it would be e.g. ``3.2``. + :param keystore: The path to a directory which contains the keys + used in signing. If not specified, the instance's + ``gpg_home`` attribute is used instead. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + if not os.path.exists(filename): + raise DistlibException('not found: %s' % filename) + metadata.validate() + d = metadata.todict() + sig_file = None + if signer: + if not self.gpg: + logger.warning('no signing program available - not signed') + else: + sig_file = self.sign_file(filename, signer, sign_password, + keystore) + with open(filename, 'rb') as f: + file_data = f.read() + md5_digest = hashlib.md5(file_data).hexdigest() + sha256_digest = hashlib.sha256(file_data).hexdigest() + d.update({ + ':action': 'file_upload', + 'protocol_version': '1', + 'filetype': filetype, + 'pyversion': pyversion, + 'md5_digest': md5_digest, + 'sha256_digest': sha256_digest, + }) + files = [('content', os.path.basename(filename), file_data)] + if sig_file: + with open(sig_file, 'rb') as f: + sig_data = f.read() + files.append(('gpg_signature', os.path.basename(sig_file), + sig_data)) + shutil.rmtree(os.path.dirname(sig_file)) + request = self.encode_request(d.items(), files) + return self.send_request(request) + + def upload_documentation(self, metadata, doc_dir): + """ + Upload documentation to the index. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the documentation to be + uploaded. + :param doc_dir: The pathname of the directory which contains the + documentation. This should be the directory that + contains the ``index.html`` for the documentation. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + if not os.path.isdir(doc_dir): + raise DistlibException('not a directory: %r' % doc_dir) + fn = os.path.join(doc_dir, 'index.html') + if not os.path.exists(fn): + raise DistlibException('not found: %r' % fn) + metadata.validate() + name, version = metadata.name, metadata.version + zip_data = zip_dir(doc_dir).getvalue() + fields = [(':action', 'doc_upload'), + ('name', name), ('version', version)] + files = [('content', name, zip_data)] + request = self.encode_request(fields, files) + return self.send_request(request) + + def get_verify_command(self, signature_filename, data_filename, + keystore=None): + """ + Return a suitable command for verifying a file. + + :param signature_filename: The pathname to the file containing the + signature. + :param data_filename: The pathname to the file containing the + signed data. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: The verifying command as a list suitable to be + passed to :class:`subprocess.Popen`. + """ + cmd = [self.gpg, '--status-fd', '2', '--no-tty'] + if keystore is None: + keystore = self.gpg_home + if keystore: + cmd.extend(['--homedir', keystore]) + cmd.extend(['--verify', signature_filename, data_filename]) + logger.debug('invoking: %s', ' '.join(cmd)) + return cmd + + def verify_signature(self, signature_filename, data_filename, + keystore=None): + """ + Verify a signature for a file. + + :param signature_filename: The pathname to the file containing the + signature. + :param data_filename: The pathname to the file containing the + signed data. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: True if the signature was verified, else False. + """ + if not self.gpg: + raise DistlibException('verification unavailable because gpg ' + 'unavailable') + cmd = self.get_verify_command(signature_filename, data_filename, + keystore) + rc, stdout, stderr = self.run_command(cmd) + if rc not in (0, 1): + raise DistlibException('verify command failed with error ' + 'code %s' % rc) + return rc == 0 + + def download_file(self, url, destfile, digest=None, reporthook=None): + """ + This is a convenience method for downloading a file from an URL. + Normally, this will be a file from the index, though currently + no check is made for this (i.e. a file can be downloaded from + anywhere). + + The method is just like the :func:`urlretrieve` function in the + standard library, except that it allows digest computation to be + done during download and checking that the downloaded data + matched any expected value. + + :param url: The URL of the file to be downloaded (assumed to be + available via an HTTP GET request). + :param destfile: The pathname where the downloaded file is to be + saved. + :param digest: If specified, this must be a (hasher, value) + tuple, where hasher is the algorithm used (e.g. + ``'md5'``) and ``value`` is the expected value. + :param reporthook: The same as for :func:`urlretrieve` in the + standard library. + """ + if digest is None: + digester = None + logger.debug('No digest specified') + else: + if isinstance(digest, (list, tuple)): + hasher, digest = digest + else: + hasher = 'md5' + digester = getattr(hashlib, hasher)() + logger.debug('Digest specified: %s' % digest) + # The following code is equivalent to urlretrieve. + # We need to do it this way so that we can compute the + # digest of the file as we go. + with open(destfile, 'wb') as dfp: + # addinfourl is not a context manager on 2.x + # so we have to use try/finally + sfp = self.send_request(Request(url)) + try: + headers = sfp.info() + blocksize = 8192 + size = -1 + read = 0 + blocknum = 0 + if "content-length" in headers: + size = int(headers["Content-Length"]) + if reporthook: + reporthook(blocknum, blocksize, size) + while True: + block = sfp.read(blocksize) + if not block: + break + read += len(block) + dfp.write(block) + if digester: + digester.update(block) + blocknum += 1 + if reporthook: + reporthook(blocknum, blocksize, size) + finally: + sfp.close() + + # check that we got the whole file, if we can + if size >= 0 and read < size: + raise DistlibException( + 'retrieval incomplete: got only %d out of %d bytes' + % (read, size)) + # if we have a digest, it must match. + if digester: + actual = digester.hexdigest() + if digest != actual: + raise DistlibException('%s digest mismatch for %s: expected ' + '%s, got %s' % (hasher, destfile, + digest, actual)) + logger.debug('Digest verified: %s', digest) + + def send_request(self, req): + """ + Send a standard library :class:`Request` to PyPI and return its + response. + + :param req: The request to send. + :return: The HTTP response from PyPI (a standard library HTTPResponse). + """ + handlers = [] + if self.password_handler: + handlers.append(self.password_handler) + if self.ssl_verifier: + handlers.append(self.ssl_verifier) + opener = build_opener(*handlers) + return opener.open(req) + + def encode_request(self, fields, files): + """ + Encode fields and files for posting to an HTTP server. + + :param fields: The fields to send as a list of (fieldname, value) + tuples. + :param files: The files to send as a list of (fieldname, filename, + file_bytes) tuple. + """ + # Adapted from packaging, which in turn was adapted from + # http://code.activestate.com/recipes/146306 + + parts = [] + boundary = self.boundary + for k, values in fields: + if not isinstance(values, (list, tuple)): + values = [values] + + for v in values: + parts.extend(( + b'--' + boundary, + ('Content-Disposition: form-data; name="%s"' % + k).encode('utf-8'), + b'', + v.encode('utf-8'))) + for key, filename, value in files: + parts.extend(( + b'--' + boundary, + ('Content-Disposition: form-data; name="%s"; filename="%s"' % + (key, filename)).encode('utf-8'), + b'', + value)) + + parts.extend((b'--' + boundary + b'--', b'')) + + body = b'\r\n'.join(parts) + ct = b'multipart/form-data; boundary=' + boundary + headers = { + 'Content-type': ct, + 'Content-length': str(len(body)) + } + return Request(self.url, body, headers) + + def search(self, terms, operator=None): + if isinstance(terms, string_types): + terms = {'name': terms} + rpc_proxy = ServerProxy(self.url, timeout=3.0) + try: + return rpc_proxy.search(terms, operator or 'and') + finally: + rpc_proxy('close')() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/locators.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/locators.py new file mode 100644 index 0000000..11d2636 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/locators.py @@ -0,0 +1,1292 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2015 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# + +import gzip +from io import BytesIO +import json +import logging +import os +import posixpath +import re +try: + import threading +except ImportError: # pragma: no cover + import dummy_threading as threading +import zlib + +from . import DistlibException +from .compat import (urljoin, urlparse, urlunparse, url2pathname, pathname2url, + queue, quote, unescape, string_types, build_opener, + HTTPRedirectHandler as BaseRedirectHandler, text_type, + Request, HTTPError, URLError) +from .database import Distribution, DistributionPath, make_dist +from .metadata import Metadata, MetadataInvalidError +from .util import (cached_property, parse_credentials, ensure_slash, + split_filename, get_project_data, parse_requirement, + parse_name_and_version, ServerProxy, normalize_name) +from .version import get_scheme, UnsupportedVersionError +from .wheel import Wheel, is_compatible + +logger = logging.getLogger(__name__) + +HASHER_HASH = re.compile(r'^(\w+)=([a-f0-9]+)') +CHARSET = re.compile(r';\s*charset\s*=\s*(.*)\s*$', re.I) +HTML_CONTENT_TYPE = re.compile('text/html|application/x(ht)?ml') +DEFAULT_INDEX = 'https://pypi.python.org/pypi' + +def get_all_distribution_names(url=None): + """ + Return all distribution names known by an index. + :param url: The URL of the index. + :return: A list of all known distribution names. + """ + if url is None: + url = DEFAULT_INDEX + client = ServerProxy(url, timeout=3.0) + try: + return client.list_packages() + finally: + client('close')() + +class RedirectHandler(BaseRedirectHandler): + """ + A class to work around a bug in some Python 3.2.x releases. + """ + # There's a bug in the base version for some 3.2.x + # (e.g. 3.2.2 on Ubuntu Oneiric). If a Location header + # returns e.g. /abc, it bails because it says the scheme '' + # is bogus, when actually it should use the request's + # URL for the scheme. See Python issue #13696. + def http_error_302(self, req, fp, code, msg, headers): + # Some servers (incorrectly) return multiple Location headers + # (so probably same goes for URI). Use first header. + newurl = None + for key in ('location', 'uri'): + if key in headers: + newurl = headers[key] + break + if newurl is None: # pragma: no cover + return + urlparts = urlparse(newurl) + if urlparts.scheme == '': + newurl = urljoin(req.get_full_url(), newurl) + if hasattr(headers, 'replace_header'): + headers.replace_header(key, newurl) + else: + headers[key] = newurl + return BaseRedirectHandler.http_error_302(self, req, fp, code, msg, + headers) + + http_error_301 = http_error_303 = http_error_307 = http_error_302 + +class Locator(object): + """ + A base class for locators - things that locate distributions. + """ + source_extensions = ('.tar.gz', '.tar.bz2', '.tar', '.zip', '.tgz', '.tbz') + binary_extensions = ('.egg', '.exe', '.whl') + excluded_extensions = ('.pdf',) + + # A list of tags indicating which wheels you want to match. The default + # value of None matches against the tags compatible with the running + # Python. If you want to match other values, set wheel_tags on a locator + # instance to a list of tuples (pyver, abi, arch) which you want to match. + wheel_tags = None + + downloadable_extensions = source_extensions + ('.whl',) + + def __init__(self, scheme='default'): + """ + Initialise an instance. + :param scheme: Because locators look for most recent versions, they + need to know the version scheme to use. This specifies + the current PEP-recommended scheme - use ``'legacy'`` + if you need to support existing distributions on PyPI. + """ + self._cache = {} + self.scheme = scheme + # Because of bugs in some of the handlers on some of the platforms, + # we use our own opener rather than just using urlopen. + self.opener = build_opener(RedirectHandler()) + # If get_project() is called from locate(), the matcher instance + # is set from the requirement passed to locate(). See issue #18 for + # why this can be useful to know. + self.matcher = None + self.errors = queue.Queue() + + def get_errors(self): + """ + Return any errors which have occurred. + """ + result = [] + while not self.errors.empty(): # pragma: no cover + try: + e = self.errors.get(False) + result.append(e) + except self.errors.Empty: + continue + self.errors.task_done() + return result + + def clear_errors(self): + """ + Clear any errors which may have been logged. + """ + # Just get the errors and throw them away + self.get_errors() + + def clear_cache(self): + self._cache.clear() + + def _get_scheme(self): + return self._scheme + + def _set_scheme(self, value): + self._scheme = value + + scheme = property(_get_scheme, _set_scheme) + + def _get_project(self, name): + """ + For a given project, get a dictionary mapping available versions to Distribution + instances. + + This should be implemented in subclasses. + + If called from a locate() request, self.matcher will be set to a + matcher for the requirement to satisfy, otherwise it will be None. + """ + raise NotImplementedError('Please implement in the subclass') + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Please implement in the subclass') + + def get_project(self, name): + """ + For a given project, get a dictionary mapping available versions to Distribution + instances. + + This calls _get_project to do all the work, and just implements a caching layer on top. + """ + if self._cache is None: # pragma: no cover + result = self._get_project(name) + elif name in self._cache: + result = self._cache[name] + else: + self.clear_errors() + result = self._get_project(name) + self._cache[name] = result + return result + + def score_url(self, url): + """ + Give an url a score which can be used to choose preferred URLs + for a given project release. + """ + t = urlparse(url) + basename = posixpath.basename(t.path) + compatible = True + is_wheel = basename.endswith('.whl') + is_downloadable = basename.endswith(self.downloadable_extensions) + if is_wheel: + compatible = is_compatible(Wheel(basename), self.wheel_tags) + return (t.scheme == 'https', 'pypi.python.org' in t.netloc, + is_downloadable, is_wheel, compatible, basename) + + def prefer_url(self, url1, url2): + """ + Choose one of two URLs where both are candidates for distribution + archives for the same version of a distribution (for example, + .tar.gz vs. zip). + + The current implementation favours https:// URLs over http://, archives + from PyPI over those from other locations, wheel compatibility (if a + wheel) and then the archive name. + """ + result = url2 + if url1: + s1 = self.score_url(url1) + s2 = self.score_url(url2) + if s1 > s2: + result = url1 + if result != url2: + logger.debug('Not replacing %r with %r', url1, url2) + else: + logger.debug('Replacing %r with %r', url1, url2) + return result + + def split_filename(self, filename, project_name): + """ + Attempt to split a filename in project name, version and Python version. + """ + return split_filename(filename, project_name) + + def convert_url_to_download_info(self, url, project_name): + """ + See if a URL is a candidate for a download URL for a project (the URL + has typically been scraped from an HTML page). + + If it is, a dictionary is returned with keys "name", "version", + "filename" and "url"; otherwise, None is returned. + """ + def same_project(name1, name2): + return normalize_name(name1) == normalize_name(name2) + + result = None + scheme, netloc, path, params, query, frag = urlparse(url) + if frag.lower().startswith('egg='): # pragma: no cover + logger.debug('%s: version hint in fragment: %r', + project_name, frag) + m = HASHER_HASH.match(frag) + if m: + algo, digest = m.groups() + else: + algo, digest = None, None + origpath = path + if path and path[-1] == '/': # pragma: no cover + path = path[:-1] + if path.endswith('.whl'): + try: + wheel = Wheel(path) + if is_compatible(wheel, self.wheel_tags): + if project_name is None: + include = True + else: + include = same_project(wheel.name, project_name) + if include: + result = { + 'name': wheel.name, + 'version': wheel.version, + 'filename': wheel.filename, + 'url': urlunparse((scheme, netloc, origpath, + params, query, '')), + 'python-version': ', '.join( + ['.'.join(list(v[2:])) for v in wheel.pyver]), + } + except Exception as e: # pragma: no cover + logger.warning('invalid path for wheel: %s', path) + elif not path.endswith(self.downloadable_extensions): # pragma: no cover + logger.debug('Not downloadable: %s', path) + else: # downloadable extension + path = filename = posixpath.basename(path) + for ext in self.downloadable_extensions: + if path.endswith(ext): + path = path[:-len(ext)] + t = self.split_filename(path, project_name) + if not t: # pragma: no cover + logger.debug('No match for project/version: %s', path) + else: + name, version, pyver = t + if not project_name or same_project(project_name, name): + result = { + 'name': name, + 'version': version, + 'filename': filename, + 'url': urlunparse((scheme, netloc, origpath, + params, query, '')), + #'packagetype': 'sdist', + } + if pyver: # pragma: no cover + result['python-version'] = pyver + break + if result and algo: + result['%s_digest' % algo] = digest + return result + + def _get_digest(self, info): + """ + Get a digest from a dictionary by looking at keys of the form + 'algo_digest'. + + Returns a 2-tuple (algo, digest) if found, else None. Currently + looks only for SHA256, then MD5. + """ + result = None + for algo in ('sha256', 'md5'): + key = '%s_digest' % algo + if key in info: + result = (algo, info[key]) + break + return result + + def _update_version_data(self, result, info): + """ + Update a result dictionary (the final result from _get_project) with a + dictionary for a specific version, which typically holds information + gleaned from a filename or URL for an archive for the distribution. + """ + name = info.pop('name') + version = info.pop('version') + if version in result: + dist = result[version] + md = dist.metadata + else: + dist = make_dist(name, version, scheme=self.scheme) + md = dist.metadata + dist.digest = digest = self._get_digest(info) + url = info['url'] + result['digests'][url] = digest + if md.source_url != info['url']: + md.source_url = self.prefer_url(md.source_url, url) + result['urls'].setdefault(version, set()).add(url) + dist.locator = self + result[version] = dist + + def locate(self, requirement, prereleases=False): + """ + Find the most recent distribution which matches the given + requirement. + + :param requirement: A requirement of the form 'foo (1.0)' or perhaps + 'foo (>= 1.0, < 2.0, != 1.3)' + :param prereleases: If ``True``, allow pre-release versions + to be located. Otherwise, pre-release versions + are not returned. + :return: A :class:`Distribution` instance, or ``None`` if no such + distribution could be located. + """ + result = None + r = parse_requirement(requirement) + if r is None: # pragma: no cover + raise DistlibException('Not a valid requirement: %r' % requirement) + scheme = get_scheme(self.scheme) + self.matcher = matcher = scheme.matcher(r.requirement) + logger.debug('matcher: %s (%s)', matcher, type(matcher).__name__) + versions = self.get_project(r.name) + if len(versions) > 2: # urls and digests keys are present + # sometimes, versions are invalid + slist = [] + vcls = matcher.version_class + for k in versions: + if k in ('urls', 'digests'): + continue + try: + if not matcher.match(k): + logger.debug('%s did not match %r', matcher, k) + else: + if prereleases or not vcls(k).is_prerelease: + slist.append(k) + else: + logger.debug('skipping pre-release ' + 'version %s of %s', k, matcher.name) + except Exception: # pragma: no cover + logger.warning('error matching %s with %r', matcher, k) + pass # slist.append(k) + if len(slist) > 1: + slist = sorted(slist, key=scheme.key) + if slist: + logger.debug('sorted list: %s', slist) + version = slist[-1] + result = versions[version] + if result: + if r.extras: + result.extras = r.extras + result.download_urls = versions.get('urls', {}).get(version, set()) + d = {} + sd = versions.get('digests', {}) + for url in result.download_urls: + if url in sd: # pragma: no cover + d[url] = sd[url] + result.digests = d + self.matcher = None + return result + + +class PyPIRPCLocator(Locator): + """ + This locator uses XML-RPC to locate distributions. It therefore + cannot be used with simple mirrors (that only mirror file content). + """ + def __init__(self, url, **kwargs): + """ + Initialise an instance. + + :param url: The URL to use for XML-RPC. + :param kwargs: Passed to the superclass constructor. + """ + super(PyPIRPCLocator, self).__init__(**kwargs) + self.base_url = url + self.client = ServerProxy(url, timeout=3.0) + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + return set(self.client.list_packages()) + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + versions = self.client.package_releases(name, True) + for v in versions: + urls = self.client.release_urls(name, v) + data = self.client.release_data(name, v) + metadata = Metadata(scheme=self.scheme) + metadata.name = data['name'] + metadata.version = data['version'] + metadata.license = data.get('license') + metadata.keywords = data.get('keywords', []) + metadata.summary = data.get('summary') + dist = Distribution(metadata) + if urls: + info = urls[0] + metadata.source_url = info['url'] + dist.digest = self._get_digest(info) + dist.locator = self + result[v] = dist + for info in urls: + url = info['url'] + digest = self._get_digest(info) + result['urls'].setdefault(v, set()).add(url) + result['digests'][url] = digest + return result + +class PyPIJSONLocator(Locator): + """ + This locator uses PyPI's JSON interface. It's very limited in functionality + and probably not worth using. + """ + def __init__(self, url, **kwargs): + super(PyPIJSONLocator, self).__init__(**kwargs) + self.base_url = ensure_slash(url) + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Not available from this locator') + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + url = urljoin(self.base_url, '%s/json' % quote(name)) + try: + resp = self.opener.open(url) + data = resp.read().decode() # for now + d = json.loads(data) + md = Metadata(scheme=self.scheme) + data = d['info'] + md.name = data['name'] + md.version = data['version'] + md.license = data.get('license') + md.keywords = data.get('keywords', []) + md.summary = data.get('summary') + dist = Distribution(md) + dist.locator = self + urls = d['urls'] + result[md.version] = dist + for info in d['urls']: + url = info['url'] + dist.download_urls.add(url) + dist.digests[url] = self._get_digest(info) + result['urls'].setdefault(md.version, set()).add(url) + result['digests'][url] = self._get_digest(info) + # Now get other releases + for version, infos in d['releases'].items(): + if version == md.version: + continue # already done + omd = Metadata(scheme=self.scheme) + omd.name = md.name + omd.version = version + odist = Distribution(omd) + odist.locator = self + result[version] = odist + for info in infos: + url = info['url'] + odist.download_urls.add(url) + odist.digests[url] = self._get_digest(info) + result['urls'].setdefault(version, set()).add(url) + result['digests'][url] = self._get_digest(info) +# for info in urls: +# md.source_url = info['url'] +# dist.digest = self._get_digest(info) +# dist.locator = self +# for info in urls: +# url = info['url'] +# result['urls'].setdefault(md.version, set()).add(url) +# result['digests'][url] = self._get_digest(info) + except Exception as e: + self.errors.put(text_type(e)) + logger.exception('JSON fetch failed: %s', e) + return result + + +class Page(object): + """ + This class represents a scraped HTML page. + """ + # The following slightly hairy-looking regex just looks for the contents of + # an anchor link, which has an attribute "href" either immediately preceded + # or immediately followed by a "rel" attribute. The attribute values can be + # declared with double quotes, single quotes or no quotes - which leads to + # the length of the expression. + _href = re.compile(""" +(rel\\s*=\\s*(?:"(?P<rel1>[^"]*)"|'(?P<rel2>[^']*)'|(?P<rel3>[^>\\s\n]*))\\s+)? +href\\s*=\\s*(?:"(?P<url1>[^"]*)"|'(?P<url2>[^']*)'|(?P<url3>[^>\\s\n]*)) +(\\s+rel\\s*=\\s*(?:"(?P<rel4>[^"]*)"|'(?P<rel5>[^']*)'|(?P<rel6>[^>\\s\n]*)))? +""", re.I | re.S | re.X) + _base = re.compile(r"""<base\s+href\s*=\s*['"]?([^'">]+)""", re.I | re.S) + + def __init__(self, data, url): + """ + Initialise an instance with the Unicode page contents and the URL they + came from. + """ + self.data = data + self.base_url = self.url = url + m = self._base.search(self.data) + if m: + self.base_url = m.group(1) + + _clean_re = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) + + @cached_property + def links(self): + """ + Return the URLs of all the links on a page together with information + about their "rel" attribute, for determining which ones to treat as + downloads and which ones to queue for further scraping. + """ + def clean(url): + "Tidy up an URL." + scheme, netloc, path, params, query, frag = urlparse(url) + return urlunparse((scheme, netloc, quote(path), + params, query, frag)) + + result = set() + for match in self._href.finditer(self.data): + d = match.groupdict('') + rel = (d['rel1'] or d['rel2'] or d['rel3'] or + d['rel4'] or d['rel5'] or d['rel6']) + url = d['url1'] or d['url2'] or d['url3'] + url = urljoin(self.base_url, url) + url = unescape(url) + url = self._clean_re.sub(lambda m: '%%%2x' % ord(m.group(0)), url) + result.add((url, rel)) + # We sort the result, hoping to bring the most recent versions + # to the front + result = sorted(result, key=lambda t: t[0], reverse=True) + return result + + +class SimpleScrapingLocator(Locator): + """ + A locator which scrapes HTML pages to locate downloads for a distribution. + This runs multiple threads to do the I/O; performance is at least as good + as pip's PackageFinder, which works in an analogous fashion. + """ + + # These are used to deal with various Content-Encoding schemes. + decoders = { + 'deflate': zlib.decompress, + 'gzip': lambda b: gzip.GzipFile(fileobj=BytesIO(d)).read(), + 'none': lambda b: b, + } + + def __init__(self, url, timeout=None, num_workers=10, **kwargs): + """ + Initialise an instance. + :param url: The root URL to use for scraping. + :param timeout: The timeout, in seconds, to be applied to requests. + This defaults to ``None`` (no timeout specified). + :param num_workers: The number of worker threads you want to do I/O, + This defaults to 10. + :param kwargs: Passed to the superclass. + """ + super(SimpleScrapingLocator, self).__init__(**kwargs) + self.base_url = ensure_slash(url) + self.timeout = timeout + self._page_cache = {} + self._seen = set() + self._to_fetch = queue.Queue() + self._bad_hosts = set() + self.skip_externals = False + self.num_workers = num_workers + self._lock = threading.RLock() + # See issue #45: we need to be resilient when the locator is used + # in a thread, e.g. with concurrent.futures. We can't use self._lock + # as it is for coordinating our internal threads - the ones created + # in _prepare_threads. + self._gplock = threading.RLock() + + def _prepare_threads(self): + """ + Threads are created only when get_project is called, and terminate + before it returns. They are there primarily to parallelise I/O (i.e. + fetching web pages). + """ + self._threads = [] + for i in range(self.num_workers): + t = threading.Thread(target=self._fetch) + t.setDaemon(True) + t.start() + self._threads.append(t) + + def _wait_threads(self): + """ + Tell all the threads to terminate (by sending a sentinel value) and + wait for them to do so. + """ + # Note that you need two loops, since you can't say which + # thread will get each sentinel + for t in self._threads: + self._to_fetch.put(None) # sentinel + for t in self._threads: + t.join() + self._threads = [] + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + with self._gplock: + self.result = result + self.project_name = name + url = urljoin(self.base_url, '%s/' % quote(name)) + self._seen.clear() + self._page_cache.clear() + self._prepare_threads() + try: + logger.debug('Queueing %s', url) + self._to_fetch.put(url) + self._to_fetch.join() + finally: + self._wait_threads() + del self.result + return result + + platform_dependent = re.compile(r'\b(linux-(i\d86|x86_64|arm\w+)|' + r'win(32|-amd64)|macosx-?\d+)\b', re.I) + + def _is_platform_dependent(self, url): + """ + Does an URL refer to a platform-specific download? + """ + return self.platform_dependent.search(url) + + def _process_download(self, url): + """ + See if an URL is a suitable download for a project. + + If it is, register information in the result dictionary (for + _get_project) about the specific version it's for. + + Note that the return value isn't actually used other than as a boolean + value. + """ + if self._is_platform_dependent(url): + info = None + else: + info = self.convert_url_to_download_info(url, self.project_name) + logger.debug('process_download: %s -> %s', url, info) + if info: + with self._lock: # needed because self.result is shared + self._update_version_data(self.result, info) + return info + + def _should_queue(self, link, referrer, rel): + """ + Determine whether a link URL from a referring page and with a + particular "rel" attribute should be queued for scraping. + """ + scheme, netloc, path, _, _, _ = urlparse(link) + if path.endswith(self.source_extensions + self.binary_extensions + + self.excluded_extensions): + result = False + elif self.skip_externals and not link.startswith(self.base_url): + result = False + elif not referrer.startswith(self.base_url): + result = False + elif rel not in ('homepage', 'download'): + result = False + elif scheme not in ('http', 'https', 'ftp'): + result = False + elif self._is_platform_dependent(link): + result = False + else: + host = netloc.split(':', 1)[0] + if host.lower() == 'localhost': + result = False + else: + result = True + logger.debug('should_queue: %s (%s) from %s -> %s', link, rel, + referrer, result) + return result + + def _fetch(self): + """ + Get a URL to fetch from the work queue, get the HTML page, examine its + links for download candidates and candidates for further scraping. + + This is a handy method to run in a thread. + """ + while True: + url = self._to_fetch.get() + try: + if url: + page = self.get_page(url) + if page is None: # e.g. after an error + continue + for link, rel in page.links: + if link not in self._seen: + try: + self._seen.add(link) + if (not self._process_download(link) and + self._should_queue(link, url, rel)): + logger.debug('Queueing %s from %s', link, url) + self._to_fetch.put(link) + except MetadataInvalidError: # e.g. invalid versions + pass + except Exception as e: # pragma: no cover + self.errors.put(text_type(e)) + finally: + # always do this, to avoid hangs :-) + self._to_fetch.task_done() + if not url: + #logger.debug('Sentinel seen, quitting.') + break + + def get_page(self, url): + """ + Get the HTML for an URL, possibly from an in-memory cache. + + XXX TODO Note: this cache is never actually cleared. It's assumed that + the data won't get stale over the lifetime of a locator instance (not + necessarily true for the default_locator). + """ + # http://peak.telecommunity.com/DevCenter/EasyInstall#package-index-api + scheme, netloc, path, _, _, _ = urlparse(url) + if scheme == 'file' and os.path.isdir(url2pathname(path)): + url = urljoin(ensure_slash(url), 'index.html') + + if url in self._page_cache: + result = self._page_cache[url] + logger.debug('Returning %s from cache: %s', url, result) + else: + host = netloc.split(':', 1)[0] + result = None + if host in self._bad_hosts: + logger.debug('Skipping %s due to bad host %s', url, host) + else: + req = Request(url, headers={'Accept-encoding': 'identity'}) + try: + logger.debug('Fetching %s', url) + resp = self.opener.open(req, timeout=self.timeout) + logger.debug('Fetched %s', url) + headers = resp.info() + content_type = headers.get('Content-Type', '') + if HTML_CONTENT_TYPE.match(content_type): + final_url = resp.geturl() + data = resp.read() + encoding = headers.get('Content-Encoding') + if encoding: + decoder = self.decoders[encoding] # fail if not found + data = decoder(data) + encoding = 'utf-8' + m = CHARSET.search(content_type) + if m: + encoding = m.group(1) + try: + data = data.decode(encoding) + except UnicodeError: # pragma: no cover + data = data.decode('latin-1') # fallback + result = Page(data, final_url) + self._page_cache[final_url] = result + except HTTPError as e: + if e.code != 404: + logger.exception('Fetch failed: %s: %s', url, e) + except URLError as e: # pragma: no cover + logger.exception('Fetch failed: %s: %s', url, e) + with self._lock: + self._bad_hosts.add(host) + except Exception as e: # pragma: no cover + logger.exception('Fetch failed: %s: %s', url, e) + finally: + self._page_cache[url] = result # even if None (failure) + return result + + _distname_re = re.compile('<a href=[^>]*>([^<]+)<') + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + page = self.get_page(self.base_url) + if not page: + raise DistlibException('Unable to get %s' % self.base_url) + for match in self._distname_re.finditer(page.data): + result.add(match.group(1)) + return result + +class DirectoryLocator(Locator): + """ + This class locates distributions in a directory tree. + """ + + def __init__(self, path, **kwargs): + """ + Initialise an instance. + :param path: The root of the directory tree to search. + :param kwargs: Passed to the superclass constructor, + except for: + * recursive - if True (the default), subdirectories are + recursed into. If False, only the top-level directory + is searched, + """ + self.recursive = kwargs.pop('recursive', True) + super(DirectoryLocator, self).__init__(**kwargs) + path = os.path.abspath(path) + if not os.path.isdir(path): # pragma: no cover + raise DistlibException('Not a directory: %r' % path) + self.base_dir = path + + def should_include(self, filename, parent): + """ + Should a filename be considered as a candidate for a distribution + archive? As well as the filename, the directory which contains it + is provided, though not used by the current implementation. + """ + return filename.endswith(self.downloadable_extensions) + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + for root, dirs, files in os.walk(self.base_dir): + for fn in files: + if self.should_include(fn, root): + fn = os.path.join(root, fn) + url = urlunparse(('file', '', + pathname2url(os.path.abspath(fn)), + '', '', '')) + info = self.convert_url_to_download_info(url, name) + if info: + self._update_version_data(result, info) + if not self.recursive: + break + return result + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + for root, dirs, files in os.walk(self.base_dir): + for fn in files: + if self.should_include(fn, root): + fn = os.path.join(root, fn) + url = urlunparse(('file', '', + pathname2url(os.path.abspath(fn)), + '', '', '')) + info = self.convert_url_to_download_info(url, None) + if info: + result.add(info['name']) + if not self.recursive: + break + return result + +class JSONLocator(Locator): + """ + This locator uses special extended metadata (not available on PyPI) and is + the basis of performant dependency resolution in distlib. Other locators + require archive downloads before dependencies can be determined! As you + might imagine, that can be slow. + """ + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Not available from this locator') + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + data = get_project_data(name) + if data: + for info in data.get('files', []): + if info['ptype'] != 'sdist' or info['pyversion'] != 'source': + continue + # We don't store summary in project metadata as it makes + # the data bigger for no benefit during dependency + # resolution + dist = make_dist(data['name'], info['version'], + summary=data.get('summary', + 'Placeholder for summary'), + scheme=self.scheme) + md = dist.metadata + md.source_url = info['url'] + # TODO SHA256 digest + if 'digest' in info and info['digest']: + dist.digest = ('md5', info['digest']) + md.dependencies = info.get('requirements', {}) + dist.exports = info.get('exports', {}) + result[dist.version] = dist + result['urls'].setdefault(dist.version, set()).add(info['url']) + return result + +class DistPathLocator(Locator): + """ + This locator finds installed distributions in a path. It can be useful for + adding to an :class:`AggregatingLocator`. + """ + def __init__(self, distpath, **kwargs): + """ + Initialise an instance. + + :param distpath: A :class:`DistributionPath` instance to search. + """ + super(DistPathLocator, self).__init__(**kwargs) + assert isinstance(distpath, DistributionPath) + self.distpath = distpath + + def _get_project(self, name): + dist = self.distpath.get_distribution(name) + if dist is None: + result = {'urls': {}, 'digests': {}} + else: + result = { + dist.version: dist, + 'urls': {dist.version: set([dist.source_url])}, + 'digests': {dist.version: set([None])} + } + return result + + +class AggregatingLocator(Locator): + """ + This class allows you to chain and/or merge a list of locators. + """ + def __init__(self, *locators, **kwargs): + """ + Initialise an instance. + + :param locators: The list of locators to search. + :param kwargs: Passed to the superclass constructor, + except for: + * merge - if False (the default), the first successful + search from any of the locators is returned. If True, + the results from all locators are merged (this can be + slow). + """ + self.merge = kwargs.pop('merge', False) + self.locators = locators + super(AggregatingLocator, self).__init__(**kwargs) + + def clear_cache(self): + super(AggregatingLocator, self).clear_cache() + for locator in self.locators: + locator.clear_cache() + + def _set_scheme(self, value): + self._scheme = value + for locator in self.locators: + locator.scheme = value + + scheme = property(Locator.scheme.fget, _set_scheme) + + def _get_project(self, name): + result = {} + for locator in self.locators: + d = locator.get_project(name) + if d: + if self.merge: + files = result.get('urls', {}) + digests = result.get('digests', {}) + # next line could overwrite result['urls'], result['digests'] + result.update(d) + df = result.get('urls') + if files and df: + for k, v in files.items(): + if k in df: + df[k] |= v + else: + df[k] = v + dd = result.get('digests') + if digests and dd: + dd.update(digests) + else: + # See issue #18. If any dists are found and we're looking + # for specific constraints, we only return something if + # a match is found. For example, if a DirectoryLocator + # returns just foo (1.0) while we're looking for + # foo (>= 2.0), we'll pretend there was nothing there so + # that subsequent locators can be queried. Otherwise we + # would just return foo (1.0) which would then lead to a + # failure to find foo (>= 2.0), because other locators + # weren't searched. Note that this only matters when + # merge=False. + if self.matcher is None: + found = True + else: + found = False + for k in d: + if self.matcher.match(k): + found = True + break + if found: + result = d + break + return result + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + for locator in self.locators: + try: + result |= locator.get_distribution_names() + except NotImplementedError: + pass + return result + + +# We use a legacy scheme simply because most of the dists on PyPI use legacy +# versions which don't conform to PEP 426 / PEP 440. +default_locator = AggregatingLocator( + JSONLocator(), + SimpleScrapingLocator('https://pypi.python.org/simple/', + timeout=3.0), + scheme='legacy') + +locate = default_locator.locate + +NAME_VERSION_RE = re.compile(r'(?P<name>[\w-]+)\s*' + r'\(\s*(==\s*)?(?P<ver>[^)]+)\)$') + +class DependencyFinder(object): + """ + Locate dependencies for distributions. + """ + + def __init__(self, locator=None): + """ + Initialise an instance, using the specified locator + to locate distributions. + """ + self.locator = locator or default_locator + self.scheme = get_scheme(self.locator.scheme) + + def add_distribution(self, dist): + """ + Add a distribution to the finder. This will update internal information + about who provides what. + :param dist: The distribution to add. + """ + logger.debug('adding distribution %s', dist) + name = dist.key + self.dists_by_name[name] = dist + self.dists[(name, dist.version)] = dist + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Add to provided: %s, %s, %s', name, version, dist) + self.provided.setdefault(name, set()).add((version, dist)) + + def remove_distribution(self, dist): + """ + Remove a distribution from the finder. This will update internal + information about who provides what. + :param dist: The distribution to remove. + """ + logger.debug('removing distribution %s', dist) + name = dist.key + del self.dists_by_name[name] + del self.dists[(name, dist.version)] + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Remove from provided: %s, %s, %s', name, version, dist) + s = self.provided[name] + s.remove((version, dist)) + if not s: + del self.provided[name] + + def get_matcher(self, reqt): + """ + Get a version matcher for a requirement. + :param reqt: The requirement + :type reqt: str + :return: A version matcher (an instance of + :class:`distlib.version.Matcher`). + """ + try: + matcher = self.scheme.matcher(reqt) + except UnsupportedVersionError: # pragma: no cover + # XXX compat-mode if cannot read the version + name = reqt.split()[0] + matcher = self.scheme.matcher(name) + return matcher + + def find_providers(self, reqt): + """ + Find the distributions which can fulfill a requirement. + + :param reqt: The requirement. + :type reqt: str + :return: A set of distribution which can fulfill the requirement. + """ + matcher = self.get_matcher(reqt) + name = matcher.key # case-insensitive + result = set() + provided = self.provided + if name in provided: + for version, provider in provided[name]: + try: + match = matcher.match(version) + except UnsupportedVersionError: + match = False + + if match: + result.add(provider) + break + return result + + def try_to_replace(self, provider, other, problems): + """ + Attempt to replace one provider with another. This is typically used + when resolving dependencies from multiple sources, e.g. A requires + (B >= 1.0) while C requires (B >= 1.1). + + For successful replacement, ``provider`` must meet all the requirements + which ``other`` fulfills. + + :param provider: The provider we are trying to replace with. + :param other: The provider we're trying to replace. + :param problems: If False is returned, this will contain what + problems prevented replacement. This is currently + a tuple of the literal string 'cantreplace', + ``provider``, ``other`` and the set of requirements + that ``provider`` couldn't fulfill. + :return: True if we can replace ``other`` with ``provider``, else + False. + """ + rlist = self.reqts[other] + unmatched = set() + for s in rlist: + matcher = self.get_matcher(s) + if not matcher.match(provider.version): + unmatched.add(s) + if unmatched: + # can't replace other with provider + problems.add(('cantreplace', provider, other, + frozenset(unmatched))) + result = False + else: + # can replace other with provider + self.remove_distribution(other) + del self.reqts[other] + for s in rlist: + self.reqts.setdefault(provider, set()).add(s) + self.add_distribution(provider) + result = True + return result + + def find(self, requirement, meta_extras=None, prereleases=False): + """ + Find a distribution and all distributions it depends on. + + :param requirement: The requirement specifying the distribution to + find, or a Distribution instance. + :param meta_extras: A list of meta extras such as :test:, :build: and + so on. + :param prereleases: If ``True``, allow pre-release versions to be + returned - otherwise, don't return prereleases + unless they're all that's available. + + Return a set of :class:`Distribution` instances and a set of + problems. + + The distributions returned should be such that they have the + :attr:`required` attribute set to ``True`` if they were + from the ``requirement`` passed to ``find()``, and they have the + :attr:`build_time_dependency` attribute set to ``True`` unless they + are post-installation dependencies of the ``requirement``. + + The problems should be a tuple consisting of the string + ``'unsatisfied'`` and the requirement which couldn't be satisfied + by any distribution known to the locator. + """ + + self.provided = {} + self.dists = {} + self.dists_by_name = {} + self.reqts = {} + + meta_extras = set(meta_extras or []) + if ':*:' in meta_extras: + meta_extras.remove(':*:') + # :meta: and :run: are implicitly included + meta_extras |= set([':test:', ':build:', ':dev:']) + + if isinstance(requirement, Distribution): + dist = odist = requirement + logger.debug('passed %s as requirement', odist) + else: + dist = odist = self.locator.locate(requirement, + prereleases=prereleases) + if dist is None: + raise DistlibException('Unable to locate %r' % requirement) + logger.debug('located %s', odist) + dist.requested = True + problems = set() + todo = set([dist]) + install_dists = set([odist]) + while todo: + dist = todo.pop() + name = dist.key # case-insensitive + if name not in self.dists_by_name: + self.add_distribution(dist) + else: + #import pdb; pdb.set_trace() + other = self.dists_by_name[name] + if other != dist: + self.try_to_replace(dist, other, problems) + + ireqts = dist.run_requires | dist.meta_requires + sreqts = dist.build_requires + ereqts = set() + if meta_extras and dist in install_dists: + for key in ('test', 'build', 'dev'): + e = ':%s:' % key + if e in meta_extras: + ereqts |= getattr(dist, '%s_requires' % key) + all_reqts = ireqts | sreqts | ereqts + for r in all_reqts: + providers = self.find_providers(r) + if not providers: + logger.debug('No providers found for %r', r) + provider = self.locator.locate(r, prereleases=prereleases) + # If no provider is found and we didn't consider + # prereleases, consider them now. + if provider is None and not prereleases: + provider = self.locator.locate(r, prereleases=True) + if provider is None: + logger.debug('Cannot satisfy %r', r) + problems.add(('unsatisfied', r)) + else: + n, v = provider.key, provider.version + if (n, v) not in self.dists: + todo.add(provider) + providers.add(provider) + if r in ireqts and dist in install_dists: + install_dists.add(provider) + logger.debug('Adding %s to install_dists', + provider.name_and_version) + for p in providers: + name = p.key + if name not in self.dists_by_name: + self.reqts.setdefault(p, set()).add(r) + else: + other = self.dists_by_name[name] + if other != p: + # see if other can be replaced by p + self.try_to_replace(p, other, problems) + + dists = set(self.dists.values()) + for dist in dists: + dist.build_time_dependency = dist not in install_dists + if dist.build_time_dependency: + logger.debug('%s is a build-time dependency only.', + dist.name_and_version) + logger.debug('find done for %s', odist) + return dists, problems diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/manifest.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/manifest.py new file mode 100644 index 0000000..ca0fe44 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/manifest.py @@ -0,0 +1,393 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2013 Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Class representing the list of files in a distribution. + +Equivalent to distutils.filelist, but fixes some problems. +""" +import fnmatch +import logging +import os +import re +import sys + +from . import DistlibException +from .compat import fsdecode +from .util import convert_path + + +__all__ = ['Manifest'] + +logger = logging.getLogger(__name__) + +# a \ followed by some spaces + EOL +_COLLAPSE_PATTERN = re.compile('\\\\w*\n', re.M) +_COMMENTED_LINE = re.compile('#.*?(?=\n)|\n(?=$)', re.M | re.S) + +# +# Due to the different results returned by fnmatch.translate, we need +# to do slightly different processing for Python 2.7 and 3.2 ... this needed +# to be brought in for Python 3.6 onwards. +# +_PYTHON_VERSION = sys.version_info[:2] + +class Manifest(object): + """A list of files built by on exploring the filesystem and filtered by + applying various patterns to what we find there. + """ + + def __init__(self, base=None): + """ + Initialise an instance. + + :param base: The base directory to explore under. + """ + self.base = os.path.abspath(os.path.normpath(base or os.getcwd())) + self.prefix = self.base + os.sep + self.allfiles = None + self.files = set() + + # + # Public API + # + + def findall(self): + """Find all files under the base and set ``allfiles`` to the absolute + pathnames of files found. + """ + from stat import S_ISREG, S_ISDIR, S_ISLNK + + self.allfiles = allfiles = [] + root = self.base + stack = [root] + pop = stack.pop + push = stack.append + + while stack: + root = pop() + names = os.listdir(root) + + for name in names: + fullname = os.path.join(root, name) + + # Avoid excess stat calls -- just one will do, thank you! + stat = os.stat(fullname) + mode = stat.st_mode + if S_ISREG(mode): + allfiles.append(fsdecode(fullname)) + elif S_ISDIR(mode) and not S_ISLNK(mode): + push(fullname) + + def add(self, item): + """ + Add a file to the manifest. + + :param item: The pathname to add. This can be relative to the base. + """ + if not item.startswith(self.prefix): + item = os.path.join(self.base, item) + self.files.add(os.path.normpath(item)) + + def add_many(self, items): + """ + Add a list of files to the manifest. + + :param items: The pathnames to add. These can be relative to the base. + """ + for item in items: + self.add(item) + + def sorted(self, wantdirs=False): + """ + Return sorted files in directory order + """ + + def add_dir(dirs, d): + dirs.add(d) + logger.debug('add_dir added %s', d) + if d != self.base: + parent, _ = os.path.split(d) + assert parent not in ('', '/') + add_dir(dirs, parent) + + result = set(self.files) # make a copy! + if wantdirs: + dirs = set() + for f in result: + add_dir(dirs, os.path.dirname(f)) + result |= dirs + return [os.path.join(*path_tuple) for path_tuple in + sorted(os.path.split(path) for path in result)] + + def clear(self): + """Clear all collected files.""" + self.files = set() + self.allfiles = [] + + def process_directive(self, directive): + """ + Process a directive which either adds some files from ``allfiles`` to + ``files``, or removes some files from ``files``. + + :param directive: The directive to process. This should be in a format + compatible with distutils ``MANIFEST.in`` files: + + http://docs.python.org/distutils/sourcedist.html#commands + """ + # Parse the line: split it up, make sure the right number of words + # is there, and return the relevant words. 'action' is always + # defined: it's the first word of the line. Which of the other + # three are defined depends on the action; it'll be either + # patterns, (dir and patterns), or (dirpattern). + action, patterns, thedir, dirpattern = self._parse_directive(directive) + + # OK, now we know that the action is valid and we have the + # right number of words on the line for that action -- so we + # can proceed with minimal error-checking. + if action == 'include': + for pattern in patterns: + if not self._include_pattern(pattern, anchor=True): + logger.warning('no files found matching %r', pattern) + + elif action == 'exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, anchor=True) + #if not found: + # logger.warning('no previously-included files ' + # 'found matching %r', pattern) + + elif action == 'global-include': + for pattern in patterns: + if not self._include_pattern(pattern, anchor=False): + logger.warning('no files found matching %r ' + 'anywhere in distribution', pattern) + + elif action == 'global-exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, anchor=False) + #if not found: + # logger.warning('no previously-included files ' + # 'matching %r found anywhere in ' + # 'distribution', pattern) + + elif action == 'recursive-include': + for pattern in patterns: + if not self._include_pattern(pattern, prefix=thedir): + logger.warning('no files found matching %r ' + 'under directory %r', pattern, thedir) + + elif action == 'recursive-exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, prefix=thedir) + #if not found: + # logger.warning('no previously-included files ' + # 'matching %r found under directory %r', + # pattern, thedir) + + elif action == 'graft': + if not self._include_pattern(None, prefix=dirpattern): + logger.warning('no directories found matching %r', + dirpattern) + + elif action == 'prune': + if not self._exclude_pattern(None, prefix=dirpattern): + logger.warning('no previously-included directories found ' + 'matching %r', dirpattern) + else: # pragma: no cover + # This should never happen, as it should be caught in + # _parse_template_line + raise DistlibException( + 'invalid action %r' % action) + + # + # Private API + # + + def _parse_directive(self, directive): + """ + Validate a directive. + :param directive: The directive to validate. + :return: A tuple of action, patterns, thedir, dir_patterns + """ + words = directive.split() + if len(words) == 1 and words[0] not in ('include', 'exclude', + 'global-include', + 'global-exclude', + 'recursive-include', + 'recursive-exclude', + 'graft', 'prune'): + # no action given, let's use the default 'include' + words.insert(0, 'include') + + action = words[0] + patterns = thedir = dir_pattern = None + + if action in ('include', 'exclude', + 'global-include', 'global-exclude'): + if len(words) < 2: + raise DistlibException( + '%r expects <pattern1> <pattern2> ...' % action) + + patterns = [convert_path(word) for word in words[1:]] + + elif action in ('recursive-include', 'recursive-exclude'): + if len(words) < 3: + raise DistlibException( + '%r expects <dir> <pattern1> <pattern2> ...' % action) + + thedir = convert_path(words[1]) + patterns = [convert_path(word) for word in words[2:]] + + elif action in ('graft', 'prune'): + if len(words) != 2: + raise DistlibException( + '%r expects a single <dir_pattern>' % action) + + dir_pattern = convert_path(words[1]) + + else: + raise DistlibException('unknown action %r' % action) + + return action, patterns, thedir, dir_pattern + + def _include_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Select strings (presumably filenames) from 'self.files' that + match 'pattern', a Unix-style wildcard (glob) pattern. + + Patterns are not quite the same as implemented by the 'fnmatch' + module: '*' and '?' match non-special characters, where "special" + is platform-dependent: slash on Unix; colon, slash, and backslash on + DOS/Windows; and colon on Mac OS. + + If 'anchor' is true (the default), then the pattern match is more + stringent: "*.py" will match "foo.py" but not "foo/bar.py". If + 'anchor' is false, both of these will match. + + If 'prefix' is supplied, then only filenames starting with 'prefix' + (itself a pattern) and ending with 'pattern', with anything in between + them, will match. 'anchor' is ignored in this case. + + If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and + 'pattern' is assumed to be either a string containing a regex or a + regex object -- no translation is done, the regex is just compiled + and used as-is. + + Selected strings will be added to self.files. + + Return True if files are found. + """ + # XXX docstring lying about what the special chars are? + found = False + pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) + + # delayed loading of allfiles list + if self.allfiles is None: + self.findall() + + for name in self.allfiles: + if pattern_re.search(name): + self.files.add(name) + found = True + return found + + def _exclude_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Remove strings (presumably filenames) from 'files' that match + 'pattern'. + + Other parameters are the same as for 'include_pattern()', above. + The list 'self.files' is modified in place. Return True if files are + found. + + This API is public to allow e.g. exclusion of SCM subdirs, e.g. when + packaging source distributions + """ + found = False + pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) + for f in list(self.files): + if pattern_re.search(f): + self.files.remove(f) + found = True + return found + + def _translate_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Translate a shell-like wildcard pattern to a compiled regular + expression. + + Return the compiled regex. If 'is_regex' true, + then 'pattern' is directly compiled to a regex (if it's a string) + or just returned as-is (assumes it's a regex object). + """ + if is_regex: + if isinstance(pattern, str): + return re.compile(pattern) + else: + return pattern + + if _PYTHON_VERSION > (3, 2): + # ditch start and end characters + start, _, end = self._glob_to_re('_').partition('_') + + if pattern: + pattern_re = self._glob_to_re(pattern) + if _PYTHON_VERSION > (3, 2): + assert pattern_re.startswith(start) and pattern_re.endswith(end) + else: + pattern_re = '' + + base = re.escape(os.path.join(self.base, '')) + if prefix is not None: + # ditch end of pattern character + if _PYTHON_VERSION <= (3, 2): + empty_pattern = self._glob_to_re('') + prefix_re = self._glob_to_re(prefix)[:-len(empty_pattern)] + else: + prefix_re = self._glob_to_re(prefix) + assert prefix_re.startswith(start) and prefix_re.endswith(end) + prefix_re = prefix_re[len(start): len(prefix_re) - len(end)] + sep = os.sep + if os.sep == '\\': + sep = r'\\' + if _PYTHON_VERSION <= (3, 2): + pattern_re = '^' + base + sep.join((prefix_re, + '.*' + pattern_re)) + else: + pattern_re = pattern_re[len(start): len(pattern_re) - len(end)] + pattern_re = r'%s%s%s%s.*%s%s' % (start, base, prefix_re, sep, + pattern_re, end) + else: # no prefix -- respect anchor flag + if anchor: + if _PYTHON_VERSION <= (3, 2): + pattern_re = '^' + base + pattern_re + else: + pattern_re = r'%s%s%s' % (start, base, pattern_re[len(start):]) + + return re.compile(pattern_re) + + def _glob_to_re(self, pattern): + """Translate a shell-like glob pattern to a regular expression. + + Return a string containing the regex. Differs from + 'fnmatch.translate()' in that '*' does not match "special characters" + (which are platform-specific). + """ + pattern_re = fnmatch.translate(pattern) + + # '?' and '*' in the glob pattern become '.' and '.*' in the RE, which + # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, + # and by extension they shouldn't match such "special characters" under + # any OS. So change all non-escaped dots in the RE to match any + # character except the special characters (currently: just os.sep). + sep = os.sep + if os.sep == '\\': + # we're using a regex to manipulate a regex, so we need + # to escape the backslash twice + sep = r'\\\\' + escaped = r'\1[^%s]' % sep + pattern_re = re.sub(r'((?<!\\)(\\\\)*)\.', escaped, pattern_re) + return pattern_re diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/markers.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/markers.py new file mode 100644 index 0000000..ee1f3e2 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/markers.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Parser for the environment markers micro-language defined in PEP 508. +""" + +# Note: In PEP 345, the micro-language was Python compatible, so the ast +# module could be used to parse it. However, PEP 508 introduced operators such +# as ~= and === which aren't in Python, necessitating a different approach. + +import os +import sys +import platform +import re + +from .compat import python_implementation, urlparse, string_types +from .util import in_venv, parse_marker + +__all__ = ['interpret'] + +def _is_literal(o): + if not isinstance(o, string_types) or not o: + return False + return o[0] in '\'"' + +class Evaluator(object): + """ + This class is used to evaluate marker expessions. + """ + + operations = { + '==': lambda x, y: x == y, + '===': lambda x, y: x == y, + '~=': lambda x, y: x == y or x > y, + '!=': lambda x, y: x != y, + '<': lambda x, y: x < y, + '<=': lambda x, y: x == y or x < y, + '>': lambda x, y: x > y, + '>=': lambda x, y: x == y or x > y, + 'and': lambda x, y: x and y, + 'or': lambda x, y: x or y, + 'in': lambda x, y: x in y, + 'not in': lambda x, y: x not in y, + } + + def evaluate(self, expr, context): + """ + Evaluate a marker expression returned by the :func:`parse_requirement` + function in the specified context. + """ + if isinstance(expr, string_types): + if expr[0] in '\'"': + result = expr[1:-1] + else: + if expr not in context: + raise SyntaxError('unknown variable: %s' % expr) + result = context[expr] + else: + assert isinstance(expr, dict) + op = expr['op'] + if op not in self.operations: + raise NotImplementedError('op not implemented: %s' % op) + elhs = expr['lhs'] + erhs = expr['rhs'] + if _is_literal(expr['lhs']) and _is_literal(expr['rhs']): + raise SyntaxError('invalid comparison: %s %s %s' % (elhs, op, erhs)) + + lhs = self.evaluate(elhs, context) + rhs = self.evaluate(erhs, context) + result = self.operations[op](lhs, rhs) + return result + +def default_context(): + def format_full_version(info): + version = '%s.%s.%s' % (info.major, info.minor, info.micro) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + if hasattr(sys, 'implementation'): + implementation_version = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + implementation_version = '0' + implementation_name = '' + + result = { + 'implementation_name': implementation_name, + 'implementation_version': implementation_version, + 'os_name': os.name, + 'platform_machine': platform.machine(), + 'platform_python_implementation': platform.python_implementation(), + 'platform_release': platform.release(), + 'platform_system': platform.system(), + 'platform_version': platform.version(), + 'platform_in_venv': str(in_venv()), + 'python_full_version': platform.python_version(), + 'python_version': platform.python_version()[:3], + 'sys_platform': sys.platform, + } + return result + +DEFAULT_CONTEXT = default_context() +del default_context + +evaluator = Evaluator() + +def interpret(marker, execution_context=None): + """ + Interpret a marker and return a result depending on environment. + + :param marker: The marker to interpret. + :type marker: str + :param execution_context: The context used for name lookup. + :type execution_context: mapping + """ + try: + expr, rest = parse_marker(marker) + except Exception as e: + raise SyntaxError('Unable to interpret marker syntax: %s: %s' % (marker, e)) + if rest and rest[0] != '#': + raise SyntaxError('unexpected trailing data in marker: %s: %s' % (marker, rest)) + context = dict(DEFAULT_CONTEXT) + if execution_context: + context.update(execution_context) + return evaluator.evaluate(expr, context) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/metadata.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/metadata.py new file mode 100644 index 0000000..6d6470f --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/metadata.py @@ -0,0 +1,1091 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Implementation of the Metadata for Python packages PEPs. + +Supports all metadata formats (1.0, 1.1, 1.2, and 2.0 experimental). +""" +from __future__ import unicode_literals + +import codecs +from email import message_from_file +import json +import logging +import re + + +from . import DistlibException, __version__ +from .compat import StringIO, string_types, text_type +from .markers import interpret +from .util import extract_by_key, get_extras +from .version import get_scheme, PEP440_VERSION_RE + +logger = logging.getLogger(__name__) + + +class MetadataMissingError(DistlibException): + """A required metadata is missing""" + + +class MetadataConflictError(DistlibException): + """Attempt to read or write metadata fields that are conflictual.""" + + +class MetadataUnrecognizedVersionError(DistlibException): + """Unknown metadata version number.""" + + +class MetadataInvalidError(DistlibException): + """A metadata value is invalid""" + +# public API of this module +__all__ = ['Metadata', 'PKG_INFO_ENCODING', 'PKG_INFO_PREFERRED_VERSION'] + +# Encoding used for the PKG-INFO files +PKG_INFO_ENCODING = 'utf-8' + +# preferred version. Hopefully will be changed +# to 1.2 once PEP 345 is supported everywhere +PKG_INFO_PREFERRED_VERSION = '1.1' + +_LINE_PREFIX_1_2 = re.compile('\n \\|') +_LINE_PREFIX_PRE_1_2 = re.compile('\n ') +_241_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'License') + +_314_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'License', 'Classifier', 'Download-URL', 'Obsoletes', + 'Provides', 'Requires') + +_314_MARKERS = ('Obsoletes', 'Provides', 'Requires', 'Classifier', + 'Download-URL') + +_345_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'Maintainer', 'Maintainer-email', 'License', + 'Classifier', 'Download-URL', 'Obsoletes-Dist', + 'Project-URL', 'Provides-Dist', 'Requires-Dist', + 'Requires-Python', 'Requires-External') + +_345_MARKERS = ('Provides-Dist', 'Requires-Dist', 'Requires-Python', + 'Obsoletes-Dist', 'Requires-External', 'Maintainer', + 'Maintainer-email', 'Project-URL') + +_426_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'Maintainer', 'Maintainer-email', 'License', + 'Classifier', 'Download-URL', 'Obsoletes-Dist', + 'Project-URL', 'Provides-Dist', 'Requires-Dist', + 'Requires-Python', 'Requires-External', 'Private-Version', + 'Obsoleted-By', 'Setup-Requires-Dist', 'Extension', + 'Provides-Extra') + +_426_MARKERS = ('Private-Version', 'Provides-Extra', 'Obsoleted-By', + 'Setup-Requires-Dist', 'Extension') + +_566_FIELDS = _426_FIELDS + ('Description-Content-Type',) + +_566_MARKERS = ('Description-Content-Type',) + +_ALL_FIELDS = set() +_ALL_FIELDS.update(_241_FIELDS) +_ALL_FIELDS.update(_314_FIELDS) +_ALL_FIELDS.update(_345_FIELDS) +_ALL_FIELDS.update(_426_FIELDS) +_ALL_FIELDS.update(_566_FIELDS) + +EXTRA_RE = re.compile(r'''extra\s*==\s*("([^"]+)"|'([^']+)')''') + + +def _version2fieldlist(version): + if version == '1.0': + return _241_FIELDS + elif version == '1.1': + return _314_FIELDS + elif version == '1.2': + return _345_FIELDS + elif version in ('1.3', '2.1'): + return _345_FIELDS + _566_FIELDS + elif version == '2.0': + return _426_FIELDS + raise MetadataUnrecognizedVersionError(version) + + +def _best_version(fields): + """Detect the best version depending on the fields used.""" + def _has_marker(keys, markers): + for marker in markers: + if marker in keys: + return True + return False + + keys = [] + for key, value in fields.items(): + if value in ([], 'UNKNOWN', None): + continue + keys.append(key) + + possible_versions = ['1.0', '1.1', '1.2', '1.3', '2.0', '2.1'] + + # first let's try to see if a field is not part of one of the version + for key in keys: + if key not in _241_FIELDS and '1.0' in possible_versions: + possible_versions.remove('1.0') + logger.debug('Removed 1.0 due to %s', key) + if key not in _314_FIELDS and '1.1' in possible_versions: + possible_versions.remove('1.1') + logger.debug('Removed 1.1 due to %s', key) + if key not in _345_FIELDS and '1.2' in possible_versions: + possible_versions.remove('1.2') + logger.debug('Removed 1.2 due to %s', key) + if key not in _566_FIELDS and '1.3' in possible_versions: + possible_versions.remove('1.3') + logger.debug('Removed 1.3 due to %s', key) + if key not in _566_FIELDS and '2.1' in possible_versions: + if key != 'Description': # In 2.1, description allowed after headers + possible_versions.remove('2.1') + logger.debug('Removed 2.1 due to %s', key) + if key not in _426_FIELDS and '2.0' in possible_versions: + possible_versions.remove('2.0') + logger.debug('Removed 2.0 due to %s', key) + + # possible_version contains qualified versions + if len(possible_versions) == 1: + return possible_versions[0] # found ! + elif len(possible_versions) == 0: + logger.debug('Out of options - unknown metadata set: %s', fields) + raise MetadataConflictError('Unknown metadata set') + + # let's see if one unique marker is found + is_1_1 = '1.1' in possible_versions and _has_marker(keys, _314_MARKERS) + is_1_2 = '1.2' in possible_versions and _has_marker(keys, _345_MARKERS) + is_2_1 = '2.1' in possible_versions and _has_marker(keys, _566_MARKERS) + is_2_0 = '2.0' in possible_versions and _has_marker(keys, _426_MARKERS) + if int(is_1_1) + int(is_1_2) + int(is_2_1) + int(is_2_0) > 1: + raise MetadataConflictError('You used incompatible 1.1/1.2/2.0/2.1 fields') + + # we have the choice, 1.0, or 1.2, or 2.0 + # - 1.0 has a broken Summary field but works with all tools + # - 1.1 is to avoid + # - 1.2 fixes Summary but has little adoption + # - 2.0 adds more features and is very new + if not is_1_1 and not is_1_2 and not is_2_1 and not is_2_0: + # we couldn't find any specific marker + if PKG_INFO_PREFERRED_VERSION in possible_versions: + return PKG_INFO_PREFERRED_VERSION + if is_1_1: + return '1.1' + if is_1_2: + return '1.2' + if is_2_1: + return '2.1' + + return '2.0' + +_ATTR2FIELD = { + 'metadata_version': 'Metadata-Version', + 'name': 'Name', + 'version': 'Version', + 'platform': 'Platform', + 'supported_platform': 'Supported-Platform', + 'summary': 'Summary', + 'description': 'Description', + 'keywords': 'Keywords', + 'home_page': 'Home-page', + 'author': 'Author', + 'author_email': 'Author-email', + 'maintainer': 'Maintainer', + 'maintainer_email': 'Maintainer-email', + 'license': 'License', + 'classifier': 'Classifier', + 'download_url': 'Download-URL', + 'obsoletes_dist': 'Obsoletes-Dist', + 'provides_dist': 'Provides-Dist', + 'requires_dist': 'Requires-Dist', + 'setup_requires_dist': 'Setup-Requires-Dist', + 'requires_python': 'Requires-Python', + 'requires_external': 'Requires-External', + 'requires': 'Requires', + 'provides': 'Provides', + 'obsoletes': 'Obsoletes', + 'project_url': 'Project-URL', + 'private_version': 'Private-Version', + 'obsoleted_by': 'Obsoleted-By', + 'extension': 'Extension', + 'provides_extra': 'Provides-Extra', +} + +_PREDICATE_FIELDS = ('Requires-Dist', 'Obsoletes-Dist', 'Provides-Dist') +_VERSIONS_FIELDS = ('Requires-Python',) +_VERSION_FIELDS = ('Version',) +_LISTFIELDS = ('Platform', 'Classifier', 'Obsoletes', + 'Requires', 'Provides', 'Obsoletes-Dist', + 'Provides-Dist', 'Requires-Dist', 'Requires-External', + 'Project-URL', 'Supported-Platform', 'Setup-Requires-Dist', + 'Provides-Extra', 'Extension') +_LISTTUPLEFIELDS = ('Project-URL',) + +_ELEMENTSFIELD = ('Keywords',) + +_UNICODEFIELDS = ('Author', 'Maintainer', 'Summary', 'Description') + +_MISSING = object() + +_FILESAFE = re.compile('[^A-Za-z0-9.]+') + + +def _get_name_and_version(name, version, for_filename=False): + """Return the distribution name with version. + + If for_filename is true, return a filename-escaped form.""" + if for_filename: + # For both name and version any runs of non-alphanumeric or '.' + # characters are replaced with a single '-'. Additionally any + # spaces in the version string become '.' + name = _FILESAFE.sub('-', name) + version = _FILESAFE.sub('-', version.replace(' ', '.')) + return '%s-%s' % (name, version) + + +class LegacyMetadata(object): + """The legacy metadata of a release. + + Supports versions 1.0, 1.1 and 1.2 (auto-detected). You can + instantiate the class with one of these arguments (or none): + - *path*, the path to a metadata file + - *fileobj* give a file-like object with metadata as content + - *mapping* is a dict-like object + - *scheme* is a version scheme name + """ + # TODO document the mapping API and UNKNOWN default key + + def __init__(self, path=None, fileobj=None, mapping=None, + scheme='default'): + if [path, fileobj, mapping].count(None) < 2: + raise TypeError('path, fileobj and mapping are exclusive') + self._fields = {} + self.requires_files = [] + self._dependencies = None + self.scheme = scheme + if path is not None: + self.read(path) + elif fileobj is not None: + self.read_file(fileobj) + elif mapping is not None: + self.update(mapping) + self.set_metadata_version() + + def set_metadata_version(self): + self._fields['Metadata-Version'] = _best_version(self._fields) + + def _write_field(self, fileobj, name, value): + fileobj.write('%s: %s\n' % (name, value)) + + def __getitem__(self, name): + return self.get(name) + + def __setitem__(self, name, value): + return self.set(name, value) + + def __delitem__(self, name): + field_name = self._convert_name(name) + try: + del self._fields[field_name] + except KeyError: + raise KeyError(name) + + def __contains__(self, name): + return (name in self._fields or + self._convert_name(name) in self._fields) + + def _convert_name(self, name): + if name in _ALL_FIELDS: + return name + name = name.replace('-', '_').lower() + return _ATTR2FIELD.get(name, name) + + def _default_value(self, name): + if name in _LISTFIELDS or name in _ELEMENTSFIELD: + return [] + return 'UNKNOWN' + + def _remove_line_prefix(self, value): + if self.metadata_version in ('1.0', '1.1'): + return _LINE_PREFIX_PRE_1_2.sub('\n', value) + else: + return _LINE_PREFIX_1_2.sub('\n', value) + + def __getattr__(self, name): + if name in _ATTR2FIELD: + return self[name] + raise AttributeError(name) + + # + # Public API + # + +# dependencies = property(_get_dependencies, _set_dependencies) + + def get_fullname(self, filesafe=False): + """Return the distribution name with version. + + If filesafe is true, return a filename-escaped form.""" + return _get_name_and_version(self['Name'], self['Version'], filesafe) + + def is_field(self, name): + """return True if name is a valid metadata key""" + name = self._convert_name(name) + return name in _ALL_FIELDS + + def is_multi_field(self, name): + name = self._convert_name(name) + return name in _LISTFIELDS + + def read(self, filepath): + """Read the metadata values from a file path.""" + fp = codecs.open(filepath, 'r', encoding='utf-8') + try: + self.read_file(fp) + finally: + fp.close() + + def read_file(self, fileob): + """Read the metadata values from a file object.""" + msg = message_from_file(fileob) + self._fields['Metadata-Version'] = msg['metadata-version'] + + # When reading, get all the fields we can + for field in _ALL_FIELDS: + if field not in msg: + continue + if field in _LISTFIELDS: + # we can have multiple lines + values = msg.get_all(field) + if field in _LISTTUPLEFIELDS and values is not None: + values = [tuple(value.split(',')) for value in values] + self.set(field, values) + else: + # single line + value = msg[field] + if value is not None and value != 'UNKNOWN': + self.set(field, value) + logger.debug('Attempting to set metadata for %s', self) + self.set_metadata_version() + + def write(self, filepath, skip_unknown=False): + """Write the metadata fields to filepath.""" + fp = codecs.open(filepath, 'w', encoding='utf-8') + try: + self.write_file(fp, skip_unknown) + finally: + fp.close() + + def write_file(self, fileobject, skip_unknown=False): + """Write the PKG-INFO format data to a file object.""" + self.set_metadata_version() + + for field in _version2fieldlist(self['Metadata-Version']): + values = self.get(field) + if skip_unknown and values in ('UNKNOWN', [], ['UNKNOWN']): + continue + if field in _ELEMENTSFIELD: + self._write_field(fileobject, field, ','.join(values)) + continue + if field not in _LISTFIELDS: + if field == 'Description': + if self.metadata_version in ('1.0', '1.1'): + values = values.replace('\n', '\n ') + else: + values = values.replace('\n', '\n |') + values = [values] + + if field in _LISTTUPLEFIELDS: + values = [','.join(value) for value in values] + + for value in values: + self._write_field(fileobject, field, value) + + def update(self, other=None, **kwargs): + """Set metadata values from the given iterable `other` and kwargs. + + Behavior is like `dict.update`: If `other` has a ``keys`` method, + they are looped over and ``self[key]`` is assigned ``other[key]``. + Else, ``other`` is an iterable of ``(key, value)`` iterables. + + Keys that don't match a metadata field or that have an empty value are + dropped. + """ + def _set(key, value): + if key in _ATTR2FIELD and value: + self.set(self._convert_name(key), value) + + if not other: + # other is None or empty container + pass + elif hasattr(other, 'keys'): + for k in other.keys(): + _set(k, other[k]) + else: + for k, v in other: + _set(k, v) + + if kwargs: + for k, v in kwargs.items(): + _set(k, v) + + def set(self, name, value): + """Control then set a metadata field.""" + name = self._convert_name(name) + + if ((name in _ELEMENTSFIELD or name == 'Platform') and + not isinstance(value, (list, tuple))): + if isinstance(value, string_types): + value = [v.strip() for v in value.split(',')] + else: + value = [] + elif (name in _LISTFIELDS and + not isinstance(value, (list, tuple))): + if isinstance(value, string_types): + value = [value] + else: + value = [] + + if logger.isEnabledFor(logging.WARNING): + project_name = self['Name'] + + scheme = get_scheme(self.scheme) + if name in _PREDICATE_FIELDS and value is not None: + for v in value: + # check that the values are valid + if not scheme.is_valid_matcher(v.split(';')[0]): + logger.warning( + "'%s': '%s' is not valid (field '%s')", + project_name, v, name) + # FIXME this rejects UNKNOWN, is that right? + elif name in _VERSIONS_FIELDS and value is not None: + if not scheme.is_valid_constraint_list(value): + logger.warning("'%s': '%s' is not a valid version (field '%s')", + project_name, value, name) + elif name in _VERSION_FIELDS and value is not None: + if not scheme.is_valid_version(value): + logger.warning("'%s': '%s' is not a valid version (field '%s')", + project_name, value, name) + + if name in _UNICODEFIELDS: + if name == 'Description': + value = self._remove_line_prefix(value) + + self._fields[name] = value + + def get(self, name, default=_MISSING): + """Get a metadata field.""" + name = self._convert_name(name) + if name not in self._fields: + if default is _MISSING: + default = self._default_value(name) + return default + if name in _UNICODEFIELDS: + value = self._fields[name] + return value + elif name in _LISTFIELDS: + value = self._fields[name] + if value is None: + return [] + res = [] + for val in value: + if name not in _LISTTUPLEFIELDS: + res.append(val) + else: + # That's for Project-URL + res.append((val[0], val[1])) + return res + + elif name in _ELEMENTSFIELD: + value = self._fields[name] + if isinstance(value, string_types): + return value.split(',') + return self._fields[name] + + def check(self, strict=False): + """Check if the metadata is compliant. If strict is True then raise if + no Name or Version are provided""" + self.set_metadata_version() + + # XXX should check the versions (if the file was loaded) + missing, warnings = [], [] + + for attr in ('Name', 'Version'): # required by PEP 345 + if attr not in self: + missing.append(attr) + + if strict and missing != []: + msg = 'missing required metadata: %s' % ', '.join(missing) + raise MetadataMissingError(msg) + + for attr in ('Home-page', 'Author'): + if attr not in self: + missing.append(attr) + + # checking metadata 1.2 (XXX needs to check 1.1, 1.0) + if self['Metadata-Version'] != '1.2': + return missing, warnings + + scheme = get_scheme(self.scheme) + + def are_valid_constraints(value): + for v in value: + if not scheme.is_valid_matcher(v.split(';')[0]): + return False + return True + + for fields, controller in ((_PREDICATE_FIELDS, are_valid_constraints), + (_VERSIONS_FIELDS, + scheme.is_valid_constraint_list), + (_VERSION_FIELDS, + scheme.is_valid_version)): + for field in fields: + value = self.get(field, None) + if value is not None and not controller(value): + warnings.append("Wrong value for '%s': %s" % (field, value)) + + return missing, warnings + + def todict(self, skip_missing=False): + """Return fields as a dict. + + Field names will be converted to use the underscore-lowercase style + instead of hyphen-mixed case (i.e. home_page instead of Home-page). + """ + self.set_metadata_version() + + mapping_1_0 = ( + ('metadata_version', 'Metadata-Version'), + ('name', 'Name'), + ('version', 'Version'), + ('summary', 'Summary'), + ('home_page', 'Home-page'), + ('author', 'Author'), + ('author_email', 'Author-email'), + ('license', 'License'), + ('description', 'Description'), + ('keywords', 'Keywords'), + ('platform', 'Platform'), + ('classifiers', 'Classifier'), + ('download_url', 'Download-URL'), + ) + + data = {} + for key, field_name in mapping_1_0: + if not skip_missing or field_name in self._fields: + data[key] = self[field_name] + + if self['Metadata-Version'] == '1.2': + mapping_1_2 = ( + ('requires_dist', 'Requires-Dist'), + ('requires_python', 'Requires-Python'), + ('requires_external', 'Requires-External'), + ('provides_dist', 'Provides-Dist'), + ('obsoletes_dist', 'Obsoletes-Dist'), + ('project_url', 'Project-URL'), + ('maintainer', 'Maintainer'), + ('maintainer_email', 'Maintainer-email'), + ) + for key, field_name in mapping_1_2: + if not skip_missing or field_name in self._fields: + if key != 'project_url': + data[key] = self[field_name] + else: + data[key] = [','.join(u) for u in self[field_name]] + + elif self['Metadata-Version'] == '1.1': + mapping_1_1 = ( + ('provides', 'Provides'), + ('requires', 'Requires'), + ('obsoletes', 'Obsoletes'), + ) + for key, field_name in mapping_1_1: + if not skip_missing or field_name in self._fields: + data[key] = self[field_name] + + return data + + def add_requirements(self, requirements): + if self['Metadata-Version'] == '1.1': + # we can't have 1.1 metadata *and* Setuptools requires + for field in ('Obsoletes', 'Requires', 'Provides'): + if field in self: + del self[field] + self['Requires-Dist'] += requirements + + # Mapping API + # TODO could add iter* variants + + def keys(self): + return list(_version2fieldlist(self['Metadata-Version'])) + + def __iter__(self): + for key in self.keys(): + yield key + + def values(self): + return [self[key] for key in self.keys()] + + def items(self): + return [(key, self[key]) for key in self.keys()] + + def __repr__(self): + return '<%s %s %s>' % (self.__class__.__name__, self.name, + self.version) + + +METADATA_FILENAME = 'pydist.json' +WHEEL_METADATA_FILENAME = 'metadata.json' + + +class Metadata(object): + """ + The metadata of a release. This implementation uses 2.0 (JSON) + metadata where possible. If not possible, it wraps a LegacyMetadata + instance which handles the key-value metadata format. + """ + + METADATA_VERSION_MATCHER = re.compile(r'^\d+(\.\d+)*$') + + NAME_MATCHER = re.compile('^[0-9A-Z]([0-9A-Z_.-]*[0-9A-Z])?$', re.I) + + VERSION_MATCHER = PEP440_VERSION_RE + + SUMMARY_MATCHER = re.compile('.{1,2047}') + + METADATA_VERSION = '2.0' + + GENERATOR = 'distlib (%s)' % __version__ + + MANDATORY_KEYS = { + 'name': (), + 'version': (), + 'summary': ('legacy',), + } + + INDEX_KEYS = ('name version license summary description author ' + 'author_email keywords platform home_page classifiers ' + 'download_url') + + DEPENDENCY_KEYS = ('extras run_requires test_requires build_requires ' + 'dev_requires provides meta_requires obsoleted_by ' + 'supports_environments') + + SYNTAX_VALIDATORS = { + 'metadata_version': (METADATA_VERSION_MATCHER, ()), + 'name': (NAME_MATCHER, ('legacy',)), + 'version': (VERSION_MATCHER, ('legacy',)), + 'summary': (SUMMARY_MATCHER, ('legacy',)), + } + + __slots__ = ('_legacy', '_data', 'scheme') + + def __init__(self, path=None, fileobj=None, mapping=None, + scheme='default'): + if [path, fileobj, mapping].count(None) < 2: + raise TypeError('path, fileobj and mapping are exclusive') + self._legacy = None + self._data = None + self.scheme = scheme + #import pdb; pdb.set_trace() + if mapping is not None: + try: + self._validate_mapping(mapping, scheme) + self._data = mapping + except MetadataUnrecognizedVersionError: + self._legacy = LegacyMetadata(mapping=mapping, scheme=scheme) + self.validate() + else: + data = None + if path: + with open(path, 'rb') as f: + data = f.read() + elif fileobj: + data = fileobj.read() + if data is None: + # Initialised with no args - to be added + self._data = { + 'metadata_version': self.METADATA_VERSION, + 'generator': self.GENERATOR, + } + else: + if not isinstance(data, text_type): + data = data.decode('utf-8') + try: + self._data = json.loads(data) + self._validate_mapping(self._data, scheme) + except ValueError: + # Note: MetadataUnrecognizedVersionError does not + # inherit from ValueError (it's a DistlibException, + # which should not inherit from ValueError). + # The ValueError comes from the json.load - if that + # succeeds and we get a validation error, we want + # that to propagate + self._legacy = LegacyMetadata(fileobj=StringIO(data), + scheme=scheme) + self.validate() + + common_keys = set(('name', 'version', 'license', 'keywords', 'summary')) + + none_list = (None, list) + none_dict = (None, dict) + + mapped_keys = { + 'run_requires': ('Requires-Dist', list), + 'build_requires': ('Setup-Requires-Dist', list), + 'dev_requires': none_list, + 'test_requires': none_list, + 'meta_requires': none_list, + 'extras': ('Provides-Extra', list), + 'modules': none_list, + 'namespaces': none_list, + 'exports': none_dict, + 'commands': none_dict, + 'classifiers': ('Classifier', list), + 'source_url': ('Download-URL', None), + 'metadata_version': ('Metadata-Version', None), + } + + del none_list, none_dict + + def __getattribute__(self, key): + common = object.__getattribute__(self, 'common_keys') + mapped = object.__getattribute__(self, 'mapped_keys') + if key in mapped: + lk, maker = mapped[key] + if self._legacy: + if lk is None: + result = None if maker is None else maker() + else: + result = self._legacy.get(lk) + else: + value = None if maker is None else maker() + if key not in ('commands', 'exports', 'modules', 'namespaces', + 'classifiers'): + result = self._data.get(key, value) + else: + # special cases for PEP 459 + sentinel = object() + result = sentinel + d = self._data.get('extensions') + if d: + if key == 'commands': + result = d.get('python.commands', value) + elif key == 'classifiers': + d = d.get('python.details') + if d: + result = d.get(key, value) + else: + d = d.get('python.exports') + if not d: + d = self._data.get('python.exports') + if d: + result = d.get(key, value) + if result is sentinel: + result = value + elif key not in common: + result = object.__getattribute__(self, key) + elif self._legacy: + result = self._legacy.get(key) + else: + result = self._data.get(key) + return result + + def _validate_value(self, key, value, scheme=None): + if key in self.SYNTAX_VALIDATORS: + pattern, exclusions = self.SYNTAX_VALIDATORS[key] + if (scheme or self.scheme) not in exclusions: + m = pattern.match(value) + if not m: + raise MetadataInvalidError("'%s' is an invalid value for " + "the '%s' property" % (value, + key)) + + def __setattr__(self, key, value): + self._validate_value(key, value) + common = object.__getattribute__(self, 'common_keys') + mapped = object.__getattribute__(self, 'mapped_keys') + if key in mapped: + lk, _ = mapped[key] + if self._legacy: + if lk is None: + raise NotImplementedError + self._legacy[lk] = value + elif key not in ('commands', 'exports', 'modules', 'namespaces', + 'classifiers'): + self._data[key] = value + else: + # special cases for PEP 459 + d = self._data.setdefault('extensions', {}) + if key == 'commands': + d['python.commands'] = value + elif key == 'classifiers': + d = d.setdefault('python.details', {}) + d[key] = value + else: + d = d.setdefault('python.exports', {}) + d[key] = value + elif key not in common: + object.__setattr__(self, key, value) + else: + if key == 'keywords': + if isinstance(value, string_types): + value = value.strip() + if value: + value = value.split() + else: + value = [] + if self._legacy: + self._legacy[key] = value + else: + self._data[key] = value + + @property + def name_and_version(self): + return _get_name_and_version(self.name, self.version, True) + + @property + def provides(self): + if self._legacy: + result = self._legacy['Provides-Dist'] + else: + result = self._data.setdefault('provides', []) + s = '%s (%s)' % (self.name, self.version) + if s not in result: + result.append(s) + return result + + @provides.setter + def provides(self, value): + if self._legacy: + self._legacy['Provides-Dist'] = value + else: + self._data['provides'] = value + + def get_requirements(self, reqts, extras=None, env=None): + """ + Base method to get dependencies, given a set of extras + to satisfy and an optional environment context. + :param reqts: A list of sometimes-wanted dependencies, + perhaps dependent on extras and environment. + :param extras: A list of optional components being requested. + :param env: An optional environment for marker evaluation. + """ + if self._legacy: + result = reqts + else: + result = [] + extras = get_extras(extras or [], self.extras) + for d in reqts: + if 'extra' not in d and 'environment' not in d: + # unconditional + include = True + else: + if 'extra' not in d: + # Not extra-dependent - only environment-dependent + include = True + else: + include = d.get('extra') in extras + if include: + # Not excluded because of extras, check environment + marker = d.get('environment') + if marker: + include = interpret(marker, env) + if include: + result.extend(d['requires']) + for key in ('build', 'dev', 'test'): + e = ':%s:' % key + if e in extras: + extras.remove(e) + # A recursive call, but it should terminate since 'test' + # has been removed from the extras + reqts = self._data.get('%s_requires' % key, []) + result.extend(self.get_requirements(reqts, extras=extras, + env=env)) + return result + + @property + def dictionary(self): + if self._legacy: + return self._from_legacy() + return self._data + + @property + def dependencies(self): + if self._legacy: + raise NotImplementedError + else: + return extract_by_key(self._data, self.DEPENDENCY_KEYS) + + @dependencies.setter + def dependencies(self, value): + if self._legacy: + raise NotImplementedError + else: + self._data.update(value) + + def _validate_mapping(self, mapping, scheme): + if mapping.get('metadata_version') != self.METADATA_VERSION: + raise MetadataUnrecognizedVersionError() + missing = [] + for key, exclusions in self.MANDATORY_KEYS.items(): + if key not in mapping: + if scheme not in exclusions: + missing.append(key) + if missing: + msg = 'Missing metadata items: %s' % ', '.join(missing) + raise MetadataMissingError(msg) + for k, v in mapping.items(): + self._validate_value(k, v, scheme) + + def validate(self): + if self._legacy: + missing, warnings = self._legacy.check(True) + if missing or warnings: + logger.warning('Metadata: missing: %s, warnings: %s', + missing, warnings) + else: + self._validate_mapping(self._data, self.scheme) + + def todict(self): + if self._legacy: + return self._legacy.todict(True) + else: + result = extract_by_key(self._data, self.INDEX_KEYS) + return result + + def _from_legacy(self): + assert self._legacy and not self._data + result = { + 'metadata_version': self.METADATA_VERSION, + 'generator': self.GENERATOR, + } + lmd = self._legacy.todict(True) # skip missing ones + for k in ('name', 'version', 'license', 'summary', 'description', + 'classifier'): + if k in lmd: + if k == 'classifier': + nk = 'classifiers' + else: + nk = k + result[nk] = lmd[k] + kw = lmd.get('Keywords', []) + if kw == ['']: + kw = [] + result['keywords'] = kw + keys = (('requires_dist', 'run_requires'), + ('setup_requires_dist', 'build_requires')) + for ok, nk in keys: + if ok in lmd and lmd[ok]: + result[nk] = [{'requires': lmd[ok]}] + result['provides'] = self.provides + author = {} + maintainer = {} + return result + + LEGACY_MAPPING = { + 'name': 'Name', + 'version': 'Version', + 'license': 'License', + 'summary': 'Summary', + 'description': 'Description', + 'classifiers': 'Classifier', + } + + def _to_legacy(self): + def process_entries(entries): + reqts = set() + for e in entries: + extra = e.get('extra') + env = e.get('environment') + rlist = e['requires'] + for r in rlist: + if not env and not extra: + reqts.add(r) + else: + marker = '' + if extra: + marker = 'extra == "%s"' % extra + if env: + if marker: + marker = '(%s) and %s' % (env, marker) + else: + marker = env + reqts.add(';'.join((r, marker))) + return reqts + + assert self._data and not self._legacy + result = LegacyMetadata() + nmd = self._data + for nk, ok in self.LEGACY_MAPPING.items(): + if nk in nmd: + result[ok] = nmd[nk] + r1 = process_entries(self.run_requires + self.meta_requires) + r2 = process_entries(self.build_requires + self.dev_requires) + if self.extras: + result['Provides-Extra'] = sorted(self.extras) + result['Requires-Dist'] = sorted(r1) + result['Setup-Requires-Dist'] = sorted(r2) + # TODO: other fields such as contacts + return result + + def write(self, path=None, fileobj=None, legacy=False, skip_unknown=True): + if [path, fileobj].count(None) != 1: + raise ValueError('Exactly one of path and fileobj is needed') + self.validate() + if legacy: + if self._legacy: + legacy_md = self._legacy + else: + legacy_md = self._to_legacy() + if path: + legacy_md.write(path, skip_unknown=skip_unknown) + else: + legacy_md.write_file(fileobj, skip_unknown=skip_unknown) + else: + if self._legacy: + d = self._from_legacy() + else: + d = self._data + if fileobj: + json.dump(d, fileobj, ensure_ascii=True, indent=2, + sort_keys=True) + else: + with codecs.open(path, 'w', 'utf-8') as f: + json.dump(d, f, ensure_ascii=True, indent=2, + sort_keys=True) + + def add_requirements(self, requirements): + if self._legacy: + self._legacy.add_requirements(requirements) + else: + run_requires = self._data.setdefault('run_requires', []) + always = None + for entry in run_requires: + if 'environment' not in entry and 'extra' not in entry: + always = entry + break + if always is None: + always = { 'requires': requirements } + run_requires.insert(0, always) + else: + rset = set(always['requires']) | set(requirements) + always['requires'] = sorted(rset) + + def __repr__(self): + name = self.name or '(no name)' + version = self.version or 'no version' + return '<%s %s %s (%s)>' % (self.__class__.__name__, + self.metadata_version, name, version) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/resources.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/resources.py new file mode 100644 index 0000000..1884016 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/resources.py @@ -0,0 +1,355 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import unicode_literals + +import bisect +import io +import logging +import os +import pkgutil +import shutil +import sys +import types +import zipimport + +from . import DistlibException +from .util import cached_property, get_cache_base, path_to_cache_dir, Cache + +logger = logging.getLogger(__name__) + + +cache = None # created when needed + + +class ResourceCache(Cache): + def __init__(self, base=None): + if base is None: + # Use native string to avoid issues on 2.x: see Python #20140. + base = os.path.join(get_cache_base(), str('resource-cache')) + super(ResourceCache, self).__init__(base) + + def is_stale(self, resource, path): + """ + Is the cache stale for the given resource? + + :param resource: The :class:`Resource` being cached. + :param path: The path of the resource in the cache. + :return: True if the cache is stale. + """ + # Cache invalidation is a hard problem :-) + return True + + def get(self, resource): + """ + Get a resource into the cache, + + :param resource: A :class:`Resource` instance. + :return: The pathname of the resource in the cache. + """ + prefix, path = resource.finder.get_cache_info(resource) + if prefix is None: + result = path + else: + result = os.path.join(self.base, self.prefix_to_dir(prefix), path) + dirname = os.path.dirname(result) + if not os.path.isdir(dirname): + os.makedirs(dirname) + if not os.path.exists(result): + stale = True + else: + stale = self.is_stale(resource, path) + if stale: + # write the bytes of the resource to the cache location + with open(result, 'wb') as f: + f.write(resource.bytes) + return result + + +class ResourceBase(object): + def __init__(self, finder, name): + self.finder = finder + self.name = name + + +class Resource(ResourceBase): + """ + A class representing an in-package resource, such as a data file. This is + not normally instantiated by user code, but rather by a + :class:`ResourceFinder` which manages the resource. + """ + is_container = False # Backwards compatibility + + def as_stream(self): + """ + Get the resource as a stream. + + This is not a property to make it obvious that it returns a new stream + each time. + """ + return self.finder.get_stream(self) + + @cached_property + def file_path(self): + global cache + if cache is None: + cache = ResourceCache() + return cache.get(self) + + @cached_property + def bytes(self): + return self.finder.get_bytes(self) + + @cached_property + def size(self): + return self.finder.get_size(self) + + +class ResourceContainer(ResourceBase): + is_container = True # Backwards compatibility + + @cached_property + def resources(self): + return self.finder.get_resources(self) + + +class ResourceFinder(object): + """ + Resource finder for file system resources. + """ + + if sys.platform.startswith('java'): + skipped_extensions = ('.pyc', '.pyo', '.class') + else: + skipped_extensions = ('.pyc', '.pyo') + + def __init__(self, module): + self.module = module + self.loader = getattr(module, '__loader__', None) + self.base = os.path.dirname(getattr(module, '__file__', '')) + + def _adjust_path(self, path): + return os.path.realpath(path) + + def _make_path(self, resource_name): + # Issue #50: need to preserve type of path on Python 2.x + # like os.path._get_sep + if isinstance(resource_name, bytes): # should only happen on 2.x + sep = b'/' + else: + sep = '/' + parts = resource_name.split(sep) + parts.insert(0, self.base) + result = os.path.join(*parts) + return self._adjust_path(result) + + def _find(self, path): + return os.path.exists(path) + + def get_cache_info(self, resource): + return None, resource.path + + def find(self, resource_name): + path = self._make_path(resource_name) + if not self._find(path): + result = None + else: + if self._is_directory(path): + result = ResourceContainer(self, resource_name) + else: + result = Resource(self, resource_name) + result.path = path + return result + + def get_stream(self, resource): + return open(resource.path, 'rb') + + def get_bytes(self, resource): + with open(resource.path, 'rb') as f: + return f.read() + + def get_size(self, resource): + return os.path.getsize(resource.path) + + def get_resources(self, resource): + def allowed(f): + return (f != '__pycache__' and not + f.endswith(self.skipped_extensions)) + return set([f for f in os.listdir(resource.path) if allowed(f)]) + + def is_container(self, resource): + return self._is_directory(resource.path) + + _is_directory = staticmethod(os.path.isdir) + + def iterator(self, resource_name): + resource = self.find(resource_name) + if resource is not None: + todo = [resource] + while todo: + resource = todo.pop(0) + yield resource + if resource.is_container: + rname = resource.name + for name in resource.resources: + if not rname: + new_name = name + else: + new_name = '/'.join([rname, name]) + child = self.find(new_name) + if child.is_container: + todo.append(child) + else: + yield child + + +class ZipResourceFinder(ResourceFinder): + """ + Resource finder for resources in .zip files. + """ + def __init__(self, module): + super(ZipResourceFinder, self).__init__(module) + archive = self.loader.archive + self.prefix_len = 1 + len(archive) + # PyPy doesn't have a _files attr on zipimporter, and you can't set one + if hasattr(self.loader, '_files'): + self._files = self.loader._files + else: + self._files = zipimport._zip_directory_cache[archive] + self.index = sorted(self._files) + + def _adjust_path(self, path): + return path + + def _find(self, path): + path = path[self.prefix_len:] + if path in self._files: + result = True + else: + if path and path[-1] != os.sep: + path = path + os.sep + i = bisect.bisect(self.index, path) + try: + result = self.index[i].startswith(path) + except IndexError: + result = False + if not result: + logger.debug('_find failed: %r %r', path, self.loader.prefix) + else: + logger.debug('_find worked: %r %r', path, self.loader.prefix) + return result + + def get_cache_info(self, resource): + prefix = self.loader.archive + path = resource.path[1 + len(prefix):] + return prefix, path + + def get_bytes(self, resource): + return self.loader.get_data(resource.path) + + def get_stream(self, resource): + return io.BytesIO(self.get_bytes(resource)) + + def get_size(self, resource): + path = resource.path[self.prefix_len:] + return self._files[path][3] + + def get_resources(self, resource): + path = resource.path[self.prefix_len:] + if path and path[-1] != os.sep: + path += os.sep + plen = len(path) + result = set() + i = bisect.bisect(self.index, path) + while i < len(self.index): + if not self.index[i].startswith(path): + break + s = self.index[i][plen:] + result.add(s.split(os.sep, 1)[0]) # only immediate children + i += 1 + return result + + def _is_directory(self, path): + path = path[self.prefix_len:] + if path and path[-1] != os.sep: + path += os.sep + i = bisect.bisect(self.index, path) + try: + result = self.index[i].startswith(path) + except IndexError: + result = False + return result + +_finder_registry = { + type(None): ResourceFinder, + zipimport.zipimporter: ZipResourceFinder +} + +try: + # In Python 3.6, _frozen_importlib -> _frozen_importlib_external + try: + import _frozen_importlib_external as _fi + except ImportError: + import _frozen_importlib as _fi + _finder_registry[_fi.SourceFileLoader] = ResourceFinder + _finder_registry[_fi.FileFinder] = ResourceFinder + del _fi +except (ImportError, AttributeError): + pass + + +def register_finder(loader, finder_maker): + _finder_registry[type(loader)] = finder_maker + +_finder_cache = {} + + +def finder(package): + """ + Return a resource finder for a package. + :param package: The name of the package. + :return: A :class:`ResourceFinder` instance for the package. + """ + if package in _finder_cache: + result = _finder_cache[package] + else: + if package not in sys.modules: + __import__(package) + module = sys.modules[package] + path = getattr(module, '__path__', None) + if path is None: + raise DistlibException('You cannot get a finder for a module, ' + 'only for a package') + loader = getattr(module, '__loader__', None) + finder_maker = _finder_registry.get(type(loader)) + if finder_maker is None: + raise DistlibException('Unable to locate finder for %r' % package) + result = finder_maker(module) + _finder_cache[package] = result + return result + + +_dummy_module = types.ModuleType(str('__dummy__')) + + +def finder_for_path(path): + """ + Return a resource finder for a path, which should represent a container. + + :param path: The path. + :return: A :class:`ResourceFinder` instance for the path. + """ + result = None + # calls any path hooks, gets importer into cache + pkgutil.get_importer(path) + loader = sys.path_importer_cache.get(path) + finder = _finder_registry.get(type(loader)) + if finder: + module = _dummy_module + module.__file__ = os.path.join(path, '') + module.__loader__ = loader + result = finder(module) + return result diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/scripts.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/scripts.py new file mode 100644 index 0000000..0b7c3d0 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/scripts.py @@ -0,0 +1,415 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2015 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from io import BytesIO +import logging +import os +import re +import struct +import sys + +from .compat import sysconfig, detect_encoding, ZipFile +from .resources import finder +from .util import (FileOperator, get_export_entry, convert_path, + get_executable, in_venv) + +logger = logging.getLogger(__name__) + +_DEFAULT_MANIFEST = ''' +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity version="1.0.0.0" + processorArchitecture="X86" + name="%s" + type="win32"/> + + <!-- Identify the application security requirements. --> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"/> + </requestedPrivileges> + </security> + </trustInfo> +</assembly>'''.strip() + +# check if Python is called on the first line with this expression +FIRST_LINE_RE = re.compile(b'^#!.*pythonw?[0-9.]*([ \t].*)?$') +SCRIPT_TEMPLATE = r'''# -*- coding: utf-8 -*- +if __name__ == '__main__': + import sys, re + + def _resolve(module, func): + __import__(module) + mod = sys.modules[module] + parts = func.split('.') + result = getattr(mod, parts.pop(0)) + for p in parts: + result = getattr(result, p) + return result + + try: + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + + func = _resolve('%(module)s', '%(func)s') + rc = func() # None interpreted as 0 + except Exception as e: # only supporting Python >= 2.6 + sys.stderr.write('%%s\n' %% e) + rc = 1 + sys.exit(rc) +''' + + +def _enquote_executable(executable): + if ' ' in executable: + # make sure we quote only the executable in case of env + # for example /usr/bin/env "/dir with spaces/bin/jython" + # instead of "/usr/bin/env /dir with spaces/bin/jython" + # otherwise whole + if executable.startswith('/usr/bin/env '): + env, _executable = executable.split(' ', 1) + if ' ' in _executable and not _executable.startswith('"'): + executable = '%s "%s"' % (env, _executable) + else: + if not executable.startswith('"'): + executable = '"%s"' % executable + return executable + + +class ScriptMaker(object): + """ + A class to copy or create scripts from source scripts or callable + specifications. + """ + script_template = SCRIPT_TEMPLATE + + executable = None # for shebangs + + def __init__(self, source_dir, target_dir, add_launchers=True, + dry_run=False, fileop=None): + self.source_dir = source_dir + self.target_dir = target_dir + self.add_launchers = add_launchers + self.force = False + self.clobber = False + # It only makes sense to set mode bits on POSIX. + self.set_mode = (os.name == 'posix') or (os.name == 'java' and + os._name == 'posix') + self.variants = set(('', 'X.Y')) + self._fileop = fileop or FileOperator(dry_run) + + self._is_nt = os.name == 'nt' or ( + os.name == 'java' and os._name == 'nt') + + def _get_alternate_executable(self, executable, options): + if options.get('gui', False) and self._is_nt: # pragma: no cover + dn, fn = os.path.split(executable) + fn = fn.replace('python', 'pythonw') + executable = os.path.join(dn, fn) + return executable + + if sys.platform.startswith('java'): # pragma: no cover + def _is_shell(self, executable): + """ + Determine if the specified executable is a script + (contains a #! line) + """ + try: + with open(executable) as fp: + return fp.read(2) == '#!' + except (OSError, IOError): + logger.warning('Failed to open %s', executable) + return False + + def _fix_jython_executable(self, executable): + if self._is_shell(executable): + # Workaround for Jython is not needed on Linux systems. + import java + + if java.lang.System.getProperty('os.name') == 'Linux': + return executable + elif executable.lower().endswith('jython.exe'): + # Use wrapper exe for Jython on Windows + return executable + return '/usr/bin/env %s' % executable + + def _build_shebang(self, executable, post_interp): + """ + Build a shebang line. In the simple case (on Windows, or a shebang line + which is not too long or contains spaces) use a simple formulation for + the shebang. Otherwise, use /bin/sh as the executable, with a contrived + shebang which allows the script to run either under Python or sh, using + suitable quoting. Thanks to Harald Nordgren for his input. + + See also: http://www.in-ulm.de/~mascheck/various/shebang/#length + https://hg.mozilla.org/mozilla-central/file/tip/mach + """ + if os.name != 'posix': + simple_shebang = True + else: + # Add 3 for '#!' prefix and newline suffix. + shebang_length = len(executable) + len(post_interp) + 3 + if sys.platform == 'darwin': + max_shebang_length = 512 + else: + max_shebang_length = 127 + simple_shebang = ((b' ' not in executable) and + (shebang_length <= max_shebang_length)) + + if simple_shebang: + result = b'#!' + executable + post_interp + b'\n' + else: + result = b'#!/bin/sh\n' + result += b"'''exec' " + executable + post_interp + b' "$0" "$@"\n' + result += b"' '''" + return result + + def _get_shebang(self, encoding, post_interp=b'', options=None): + enquote = True + if self.executable: + executable = self.executable + enquote = False # assume this will be taken care of + elif not sysconfig.is_python_build(): + executable = get_executable() + elif in_venv(): # pragma: no cover + executable = os.path.join(sysconfig.get_path('scripts'), + 'python%s' % sysconfig.get_config_var('EXE')) + else: # pragma: no cover + executable = os.path.join( + sysconfig.get_config_var('BINDIR'), + 'python%s%s' % (sysconfig.get_config_var('VERSION'), + sysconfig.get_config_var('EXE'))) + if options: + executable = self._get_alternate_executable(executable, options) + + if sys.platform.startswith('java'): # pragma: no cover + executable = self._fix_jython_executable(executable) + # Normalise case for Windows + executable = os.path.normcase(executable) + # If the user didn't specify an executable, it may be necessary to + # cater for executable paths with spaces (not uncommon on Windows) + if enquote: + executable = _enquote_executable(executable) + # Issue #51: don't use fsencode, since we later try to + # check that the shebang is decodable using utf-8. + executable = executable.encode('utf-8') + # in case of IronPython, play safe and enable frames support + if (sys.platform == 'cli' and '-X:Frames' not in post_interp + and '-X:FullFrames' not in post_interp): # pragma: no cover + post_interp += b' -X:Frames' + shebang = self._build_shebang(executable, post_interp) + # Python parser starts to read a script using UTF-8 until + # it gets a #coding:xxx cookie. The shebang has to be the + # first line of a file, the #coding:xxx cookie cannot be + # written before. So the shebang has to be decodable from + # UTF-8. + try: + shebang.decode('utf-8') + except UnicodeDecodeError: # pragma: no cover + raise ValueError( + 'The shebang (%r) is not decodable from utf-8' % shebang) + # If the script is encoded to a custom encoding (use a + # #coding:xxx cookie), the shebang has to be decodable from + # the script encoding too. + if encoding != 'utf-8': + try: + shebang.decode(encoding) + except UnicodeDecodeError: # pragma: no cover + raise ValueError( + 'The shebang (%r) is not decodable ' + 'from the script encoding (%r)' % (shebang, encoding)) + return shebang + + def _get_script_text(self, entry): + return self.script_template % dict(module=entry.prefix, + func=entry.suffix) + + manifest = _DEFAULT_MANIFEST + + def get_manifest(self, exename): + base = os.path.basename(exename) + return self.manifest % base + + def _write_script(self, names, shebang, script_bytes, filenames, ext): + use_launcher = self.add_launchers and self._is_nt + linesep = os.linesep.encode('utf-8') + if not use_launcher: + script_bytes = shebang + linesep + script_bytes + else: # pragma: no cover + if ext == 'py': + launcher = self._get_launcher('t') + else: + launcher = self._get_launcher('w') + stream = BytesIO() + with ZipFile(stream, 'w') as zf: + zf.writestr('__main__.py', script_bytes) + zip_data = stream.getvalue() + script_bytes = launcher + shebang + linesep + zip_data + for name in names: + outname = os.path.join(self.target_dir, name) + if use_launcher: # pragma: no cover + n, e = os.path.splitext(outname) + if e.startswith('.py'): + outname = n + outname = '%s.exe' % outname + try: + self._fileop.write_binary_file(outname, script_bytes) + except Exception: + # Failed writing an executable - it might be in use. + logger.warning('Failed to write executable - trying to ' + 'use .deleteme logic') + dfname = '%s.deleteme' % outname + if os.path.exists(dfname): + os.remove(dfname) # Not allowed to fail here + os.rename(outname, dfname) # nor here + self._fileop.write_binary_file(outname, script_bytes) + logger.debug('Able to replace executable using ' + '.deleteme logic') + try: + os.remove(dfname) + except Exception: + pass # still in use - ignore error + else: + if self._is_nt and not outname.endswith('.' + ext): # pragma: no cover + outname = '%s.%s' % (outname, ext) + if os.path.exists(outname) and not self.clobber: + logger.warning('Skipping existing file %s', outname) + continue + self._fileop.write_binary_file(outname, script_bytes) + if self.set_mode: + self._fileop.set_executable_mode([outname]) + filenames.append(outname) + + def _make_script(self, entry, filenames, options=None): + post_interp = b'' + if options: + args = options.get('interpreter_args', []) + if args: + args = ' %s' % ' '.join(args) + post_interp = args.encode('utf-8') + shebang = self._get_shebang('utf-8', post_interp, options=options) + script = self._get_script_text(entry).encode('utf-8') + name = entry.name + scriptnames = set() + if '' in self.variants: + scriptnames.add(name) + if 'X' in self.variants: + scriptnames.add('%s%s' % (name, sys.version[0])) + if 'X.Y' in self.variants: + scriptnames.add('%s-%s' % (name, sys.version[:3])) + if options and options.get('gui', False): + ext = 'pyw' + else: + ext = 'py' + self._write_script(scriptnames, shebang, script, filenames, ext) + + def _copy_script(self, script, filenames): + adjust = False + script = os.path.join(self.source_dir, convert_path(script)) + outname = os.path.join(self.target_dir, os.path.basename(script)) + if not self.force and not self._fileop.newer(script, outname): + logger.debug('not copying %s (up-to-date)', script) + return + + # Always open the file, but ignore failures in dry-run mode -- + # that way, we'll get accurate feedback if we can read the + # script. + try: + f = open(script, 'rb') + except IOError: # pragma: no cover + if not self.dry_run: + raise + f = None + else: + first_line = f.readline() + if not first_line: # pragma: no cover + logger.warning('%s: %s is an empty file (skipping)', + self.get_command_name(), script) + return + + match = FIRST_LINE_RE.match(first_line.replace(b'\r\n', b'\n')) + if match: + adjust = True + post_interp = match.group(1) or b'' + + if not adjust: + if f: + f.close() + self._fileop.copy_file(script, outname) + if self.set_mode: + self._fileop.set_executable_mode([outname]) + filenames.append(outname) + else: + logger.info('copying and adjusting %s -> %s', script, + self.target_dir) + if not self._fileop.dry_run: + encoding, lines = detect_encoding(f.readline) + f.seek(0) + shebang = self._get_shebang(encoding, post_interp) + if b'pythonw' in first_line: # pragma: no cover + ext = 'pyw' + else: + ext = 'py' + n = os.path.basename(outname) + self._write_script([n], shebang, f.read(), filenames, ext) + if f: + f.close() + + @property + def dry_run(self): + return self._fileop.dry_run + + @dry_run.setter + def dry_run(self, value): + self._fileop.dry_run = value + + if os.name == 'nt' or (os.name == 'java' and os._name == 'nt'): # pragma: no cover + # Executable launcher support. + # Launchers are from https://bitbucket.org/vinay.sajip/simple_launcher/ + + def _get_launcher(self, kind): + if struct.calcsize('P') == 8: # 64-bit + bits = '64' + else: + bits = '32' + name = '%s%s.exe' % (kind, bits) + # Issue 31: don't hardcode an absolute package name, but + # determine it relative to the current package + distlib_package = __name__.rsplit('.', 1)[0] + result = finder(distlib_package).find(name).bytes + return result + + # Public API follows + + def make(self, specification, options=None): + """ + Make a script. + + :param specification: The specification, which is either a valid export + entry specification (to make a script from a + callable) or a filename (to make a script by + copying from a source location). + :param options: A dictionary of options controlling script generation. + :return: A list of all absolute pathnames written to. + """ + filenames = [] + entry = get_export_entry(specification) + if entry is None: + self._copy_script(specification, filenames) + else: + self._make_script(entry, filenames, options=options) + return filenames + + def make_multiple(self, specifications, options=None): + """ + Take a list of specifications and make scripts from them, + :param specifications: A list of specifications. + :return: A list of all absolute pathnames written to, + """ + filenames = [] + for specification in specifications: + filenames.extend(self.make(specification, options)) + return filenames diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/t32.exe b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/t32.exe new file mode 100755 index 0000000000000000000000000000000000000000..a09d926872d84ae22a617dfe9ebb560d420b37de GIT binary patch literal 92672 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 literal 0 HcmV?d00001 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/t64.exe b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/t64.exe new file mode 100755 index 0000000000000000000000000000000000000000..9da9b40de922fb203df6b9a1d0ad4139af536850 GIT binary patch literal 102400 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�vlnW`{LoXpTySn$@;x8yoz96jn?+Kk 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�?dYNUd4WaURX_A__M4W}D0!0n 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 literal 0 HcmV?d00001 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/util.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/util.py new file mode 100644 index 0000000..0b14a93 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/util.py @@ -0,0 +1,1755 @@ +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import codecs +from collections import deque +import contextlib +import csv +from glob import iglob as std_iglob +import io +import json +import logging +import os +import py_compile +import re +import socket +try: + import ssl +except ImportError: # pragma: no cover + ssl = None +import subprocess +import sys +import tarfile +import tempfile +import textwrap + +try: + import threading +except ImportError: # pragma: no cover + import dummy_threading as threading +import time + +from . import DistlibException +from .compat import (string_types, text_type, shutil, raw_input, StringIO, + cache_from_source, urlopen, urljoin, httplib, xmlrpclib, + splittype, HTTPHandler, BaseConfigurator, valid_ident, + Container, configparser, URLError, ZipFile, fsdecode, + unquote, urlparse) + +logger = logging.getLogger(__name__) + +# +# Requirement parsing code as per PEP 508 +# + +IDENTIFIER = re.compile(r'^([\w\.-]+)\s*') +VERSION_IDENTIFIER = re.compile(r'^([\w\.*+-]+)\s*') +COMPARE_OP = re.compile(r'^(<=?|>=?|={2,3}|[~!]=)\s*') +MARKER_OP = re.compile(r'^((<=?)|(>=?)|={2,3}|[~!]=|in|not\s+in)\s*') +OR = re.compile(r'^or\b\s*') +AND = re.compile(r'^and\b\s*') +NON_SPACE = re.compile(r'(\S+)\s*') +STRING_CHUNK = re.compile(r'([\s\w\.{}()*+#:;,/?!~`@$%^&=|<>\[\]-]+)') + + +def parse_marker(marker_string): + """ + Parse a marker string and return a dictionary containing a marker expression. + + The dictionary will contain keys "op", "lhs" and "rhs" for non-terminals in + the expression grammar, or strings. A string contained in quotes is to be + interpreted as a literal string, and a string not contained in quotes is a + variable (such as os_name). + """ + def marker_var(remaining): + # either identifier, or literal string + m = IDENTIFIER.match(remaining) + if m: + result = m.groups()[0] + remaining = remaining[m.end():] + elif not remaining: + raise SyntaxError('unexpected end of input') + else: + q = remaining[0] + if q not in '\'"': + raise SyntaxError('invalid expression: %s' % remaining) + oq = '\'"'.replace(q, '') + remaining = remaining[1:] + parts = [q] + while remaining: + # either a string chunk, or oq, or q to terminate + if remaining[0] == q: + break + elif remaining[0] == oq: + parts.append(oq) + remaining = remaining[1:] + else: + m = STRING_CHUNK.match(remaining) + if not m: + raise SyntaxError('error in string literal: %s' % remaining) + parts.append(m.groups()[0]) + remaining = remaining[m.end():] + else: + s = ''.join(parts) + raise SyntaxError('unterminated string: %s' % s) + parts.append(q) + result = ''.join(parts) + remaining = remaining[1:].lstrip() # skip past closing quote + return result, remaining + + def marker_expr(remaining): + if remaining and remaining[0] == '(': + result, remaining = marker(remaining[1:].lstrip()) + if remaining[0] != ')': + raise SyntaxError('unterminated parenthesis: %s' % remaining) + remaining = remaining[1:].lstrip() + else: + lhs, remaining = marker_var(remaining) + while remaining: + m = MARKER_OP.match(remaining) + if not m: + break + op = m.groups()[0] + remaining = remaining[m.end():] + rhs, remaining = marker_var(remaining) + lhs = {'op': op, 'lhs': lhs, 'rhs': rhs} + result = lhs + return result, remaining + + def marker_and(remaining): + lhs, remaining = marker_expr(remaining) + while remaining: + m = AND.match(remaining) + if not m: + break + remaining = remaining[m.end():] + rhs, remaining = marker_expr(remaining) + lhs = {'op': 'and', 'lhs': lhs, 'rhs': rhs} + return lhs, remaining + + def marker(remaining): + lhs, remaining = marker_and(remaining) + while remaining: + m = OR.match(remaining) + if not m: + break + remaining = remaining[m.end():] + rhs, remaining = marker_and(remaining) + lhs = {'op': 'or', 'lhs': lhs, 'rhs': rhs} + return lhs, remaining + + return marker(marker_string) + + +def parse_requirement(req): + """ + Parse a requirement passed in as a string. Return a Container + whose attributes contain the various parts of the requirement. + """ + remaining = req.strip() + if not remaining or remaining.startswith('#'): + return None + m = IDENTIFIER.match(remaining) + if not m: + raise SyntaxError('name expected: %s' % remaining) + distname = m.groups()[0] + remaining = remaining[m.end():] + extras = mark_expr = versions = uri = None + if remaining and remaining[0] == '[': + i = remaining.find(']', 1) + if i < 0: + raise SyntaxError('unterminated extra: %s' % remaining) + s = remaining[1:i] + remaining = remaining[i + 1:].lstrip() + extras = [] + while s: + m = IDENTIFIER.match(s) + if not m: + raise SyntaxError('malformed extra: %s' % s) + extras.append(m.groups()[0]) + s = s[m.end():] + if not s: + break + if s[0] != ',': + raise SyntaxError('comma expected in extras: %s' % s) + s = s[1:].lstrip() + if not extras: + extras = None + if remaining: + if remaining[0] == '@': + # it's a URI + remaining = remaining[1:].lstrip() + m = NON_SPACE.match(remaining) + if not m: + raise SyntaxError('invalid URI: %s' % remaining) + uri = m.groups()[0] + t = urlparse(uri) + # there are issues with Python and URL parsing, so this test + # is a bit crude. See bpo-20271, bpo-23505. Python doesn't + # always parse invalid URLs correctly - it should raise + # exceptions for malformed URLs + if not (t.scheme and t.netloc): + raise SyntaxError('Invalid URL: %s' % uri) + remaining = remaining[m.end():].lstrip() + else: + + def get_versions(ver_remaining): + """ + Return a list of operator, version tuples if any are + specified, else None. + """ + m = COMPARE_OP.match(ver_remaining) + versions = None + if m: + versions = [] + while True: + op = m.groups()[0] + ver_remaining = ver_remaining[m.end():] + m = VERSION_IDENTIFIER.match(ver_remaining) + if not m: + raise SyntaxError('invalid version: %s' % ver_remaining) + v = m.groups()[0] + versions.append((op, v)) + ver_remaining = ver_remaining[m.end():] + if not ver_remaining or ver_remaining[0] != ',': + break + ver_remaining = ver_remaining[1:].lstrip() + m = COMPARE_OP.match(ver_remaining) + if not m: + raise SyntaxError('invalid constraint: %s' % ver_remaining) + if not versions: + versions = None + return versions, ver_remaining + + if remaining[0] != '(': + versions, remaining = get_versions(remaining) + else: + i = remaining.find(')', 1) + if i < 0: + raise SyntaxError('unterminated parenthesis: %s' % remaining) + s = remaining[1:i] + remaining = remaining[i + 1:].lstrip() + # As a special diversion from PEP 508, allow a version number + # a.b.c in parentheses as a synonym for ~= a.b.c (because this + # is allowed in earlier PEPs) + if COMPARE_OP.match(s): + versions, _ = get_versions(s) + else: + m = VERSION_IDENTIFIER.match(s) + if not m: + raise SyntaxError('invalid constraint: %s' % s) + v = m.groups()[0] + s = s[m.end():].lstrip() + if s: + raise SyntaxError('invalid constraint: %s' % s) + versions = [('~=', v)] + + if remaining: + if remaining[0] != ';': + raise SyntaxError('invalid requirement: %s' % remaining) + remaining = remaining[1:].lstrip() + + mark_expr, remaining = parse_marker(remaining) + + if remaining and remaining[0] != '#': + raise SyntaxError('unexpected trailing data: %s' % remaining) + + if not versions: + rs = distname + else: + rs = '%s %s' % (distname, ', '.join(['%s %s' % con for con in versions])) + return Container(name=distname, extras=extras, constraints=versions, + marker=mark_expr, url=uri, requirement=rs) + + +def get_resources_dests(resources_root, rules): + """Find destinations for resources files""" + + def get_rel_path(root, path): + # normalizes and returns a lstripped-/-separated path + root = root.replace(os.path.sep, '/') + path = path.replace(os.path.sep, '/') + assert path.startswith(root) + return path[len(root):].lstrip('/') + + destinations = {} + for base, suffix, dest in rules: + prefix = os.path.join(resources_root, base) + for abs_base in iglob(prefix): + abs_glob = os.path.join(abs_base, suffix) + for abs_path in iglob(abs_glob): + resource_file = get_rel_path(resources_root, abs_path) + if dest is None: # remove the entry if it was here + destinations.pop(resource_file, None) + else: + rel_path = get_rel_path(abs_base, abs_path) + rel_dest = dest.replace(os.path.sep, '/').rstrip('/') + destinations[resource_file] = rel_dest + '/' + rel_path + return destinations + + +def in_venv(): + if hasattr(sys, 'real_prefix'): + # virtualenv venvs + result = True + else: + # PEP 405 venvs + result = sys.prefix != getattr(sys, 'base_prefix', sys.prefix) + return result + + +def get_executable(): +# The __PYVENV_LAUNCHER__ dance is apparently no longer needed, as +# changes to the stub launcher mean that sys.executable always points +# to the stub on OS X +# if sys.platform == 'darwin' and ('__PYVENV_LAUNCHER__' +# in os.environ): +# result = os.environ['__PYVENV_LAUNCHER__'] +# else: +# result = sys.executable +# return result + result = os.path.normcase(sys.executable) + if not isinstance(result, text_type): + result = fsdecode(result) + return result + + +def proceed(prompt, allowed_chars, error_prompt=None, default=None): + p = prompt + while True: + s = raw_input(p) + p = prompt + if not s and default: + s = default + if s: + c = s[0].lower() + if c in allowed_chars: + break + if error_prompt: + p = '%c: %s\n%s' % (c, error_prompt, prompt) + return c + + +def extract_by_key(d, keys): + if isinstance(keys, string_types): + keys = keys.split() + result = {} + for key in keys: + if key in d: + result[key] = d[key] + return result + +def read_exports(stream): + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getreader('utf-8')(stream) + # Try to load as JSON, falling back on legacy format + data = stream.read() + stream = StringIO(data) + try: + jdata = json.load(stream) + result = jdata['extensions']['python.exports']['exports'] + for group, entries in result.items(): + for k, v in entries.items(): + s = '%s = %s' % (k, v) + entry = get_export_entry(s) + assert entry is not None + entries[k] = entry + return result + except Exception: + stream.seek(0, 0) + + def read_stream(cp, stream): + if hasattr(cp, 'read_file'): + cp.read_file(stream) + else: + cp.readfp(stream) + + cp = configparser.ConfigParser() + try: + read_stream(cp, stream) + except configparser.MissingSectionHeaderError: + stream.close() + data = textwrap.dedent(data) + stream = StringIO(data) + read_stream(cp, stream) + + result = {} + for key in cp.sections(): + result[key] = entries = {} + for name, value in cp.items(key): + s = '%s = %s' % (name, value) + entry = get_export_entry(s) + assert entry is not None + #entry.dist = self + entries[name] = entry + return result + + +def write_exports(exports, stream): + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getwriter('utf-8')(stream) + cp = configparser.ConfigParser() + for k, v in exports.items(): + # TODO check k, v for valid values + cp.add_section(k) + for entry in v.values(): + if entry.suffix is None: + s = entry.prefix + else: + s = '%s:%s' % (entry.prefix, entry.suffix) + if entry.flags: + s = '%s [%s]' % (s, ', '.join(entry.flags)) + cp.set(k, entry.name, s) + cp.write(stream) + + +@contextlib.contextmanager +def tempdir(): + td = tempfile.mkdtemp() + try: + yield td + finally: + shutil.rmtree(td) + +@contextlib.contextmanager +def chdir(d): + cwd = os.getcwd() + try: + os.chdir(d) + yield + finally: + os.chdir(cwd) + + +@contextlib.contextmanager +def socket_timeout(seconds=15): + cto = socket.getdefaulttimeout() + try: + socket.setdefaulttimeout(seconds) + yield + finally: + socket.setdefaulttimeout(cto) + + +class cached_property(object): + def __init__(self, func): + self.func = func + #for attr in ('__name__', '__module__', '__doc__'): + # setattr(self, attr, getattr(func, attr, None)) + + def __get__(self, obj, cls=None): + if obj is None: + return self + value = self.func(obj) + object.__setattr__(obj, self.func.__name__, value) + #obj.__dict__[self.func.__name__] = value = self.func(obj) + return value + +def convert_path(pathname): + """Return 'pathname' as a name that will work on the native filesystem. + + The path is split on '/' and put back together again using the current + directory separator. Needed because filenames in the setup script are + always supplied in Unix style, and have to be converted to the local + convention before we can actually use them in the filesystem. Raises + ValueError on non-Unix-ish systems if 'pathname' either starts or + ends with a slash. + """ + if os.sep == '/': + return pathname + if not pathname: + return pathname + if pathname[0] == '/': + raise ValueError("path '%s' cannot be absolute" % pathname) + if pathname[-1] == '/': + raise ValueError("path '%s' cannot end with '/'" % pathname) + + paths = pathname.split('/') + while os.curdir in paths: + paths.remove(os.curdir) + if not paths: + return os.curdir + return os.path.join(*paths) + + +class FileOperator(object): + def __init__(self, dry_run=False): + self.dry_run = dry_run + self.ensured = set() + self._init_record() + + def _init_record(self): + self.record = False + self.files_written = set() + self.dirs_created = set() + + def record_as_written(self, path): + if self.record: + self.files_written.add(path) + + def newer(self, source, target): + """Tell if the target is newer than the source. + + Returns true if 'source' exists and is more recently modified than + 'target', or if 'source' exists and 'target' doesn't. + + Returns false if both exist and 'target' is the same age or younger + than 'source'. Raise PackagingFileError if 'source' does not exist. + + Note that this test is not very accurate: files created in the same + second will have the same "age". + """ + if not os.path.exists(source): + raise DistlibException("file '%r' does not exist" % + os.path.abspath(source)) + if not os.path.exists(target): + return True + + return os.stat(source).st_mtime > os.stat(target).st_mtime + + def copy_file(self, infile, outfile, check=True): + """Copy a file respecting dry-run and force flags. + """ + self.ensure_dir(os.path.dirname(outfile)) + logger.info('Copying %s to %s', infile, outfile) + if not self.dry_run: + msg = None + if check: + if os.path.islink(outfile): + msg = '%s is a symlink' % outfile + elif os.path.exists(outfile) and not os.path.isfile(outfile): + msg = '%s is a non-regular file' % outfile + if msg: + raise ValueError(msg + ' which would be overwritten') + shutil.copyfile(infile, outfile) + self.record_as_written(outfile) + + def copy_stream(self, instream, outfile, encoding=None): + assert not os.path.isdir(outfile) + self.ensure_dir(os.path.dirname(outfile)) + logger.info('Copying stream %s to %s', instream, outfile) + if not self.dry_run: + if encoding is None: + outstream = open(outfile, 'wb') + else: + outstream = codecs.open(outfile, 'w', encoding=encoding) + try: + shutil.copyfileobj(instream, outstream) + finally: + outstream.close() + self.record_as_written(outfile) + + def write_binary_file(self, path, data): + self.ensure_dir(os.path.dirname(path)) + if not self.dry_run: + with open(path, 'wb') as f: + f.write(data) + self.record_as_written(path) + + def write_text_file(self, path, data, encoding): + self.ensure_dir(os.path.dirname(path)) + if not self.dry_run: + with open(path, 'wb') as f: + f.write(data.encode(encoding)) + self.record_as_written(path) + + def set_mode(self, bits, mask, files): + if os.name == 'posix' or (os.name == 'java' and os._name == 'posix'): + # Set the executable bits (owner, group, and world) on + # all the files specified. + for f in files: + if self.dry_run: + logger.info("changing mode of %s", f) + else: + mode = (os.stat(f).st_mode | bits) & mask + logger.info("changing mode of %s to %o", f, mode) + os.chmod(f, mode) + + set_executable_mode = lambda s, f: s.set_mode(0o555, 0o7777, f) + + def ensure_dir(self, path): + path = os.path.abspath(path) + if path not in self.ensured and not os.path.exists(path): + self.ensured.add(path) + d, f = os.path.split(path) + self.ensure_dir(d) + logger.info('Creating %s' % path) + if not self.dry_run: + os.mkdir(path) + if self.record: + self.dirs_created.add(path) + + def byte_compile(self, path, optimize=False, force=False, prefix=None): + dpath = cache_from_source(path, not optimize) + logger.info('Byte-compiling %s to %s', path, dpath) + if not self.dry_run: + if force or self.newer(path, dpath): + if not prefix: + diagpath = None + else: + assert path.startswith(prefix) + diagpath = path[len(prefix):] + py_compile.compile(path, dpath, diagpath, True) # raise error + self.record_as_written(dpath) + return dpath + + def ensure_removed(self, path): + if os.path.exists(path): + if os.path.isdir(path) and not os.path.islink(path): + logger.debug('Removing directory tree at %s', path) + if not self.dry_run: + shutil.rmtree(path) + if self.record: + if path in self.dirs_created: + self.dirs_created.remove(path) + else: + if os.path.islink(path): + s = 'link' + else: + s = 'file' + logger.debug('Removing %s %s', s, path) + if not self.dry_run: + os.remove(path) + if self.record: + if path in self.files_written: + self.files_written.remove(path) + + def is_writable(self, path): + result = False + while not result: + if os.path.exists(path): + result = os.access(path, os.W_OK) + break + parent = os.path.dirname(path) + if parent == path: + break + path = parent + return result + + def commit(self): + """ + Commit recorded changes, turn off recording, return + changes. + """ + assert self.record + result = self.files_written, self.dirs_created + self._init_record() + return result + + def rollback(self): + if not self.dry_run: + for f in list(self.files_written): + if os.path.exists(f): + os.remove(f) + # dirs should all be empty now, except perhaps for + # __pycache__ subdirs + # reverse so that subdirs appear before their parents + dirs = sorted(self.dirs_created, reverse=True) + for d in dirs: + flist = os.listdir(d) + if flist: + assert flist == ['__pycache__'] + sd = os.path.join(d, flist[0]) + os.rmdir(sd) + os.rmdir(d) # should fail if non-empty + self._init_record() + +def resolve(module_name, dotted_path): + if module_name in sys.modules: + mod = sys.modules[module_name] + else: + mod = __import__(module_name) + if dotted_path is None: + result = mod + else: + parts = dotted_path.split('.') + result = getattr(mod, parts.pop(0)) + for p in parts: + result = getattr(result, p) + return result + + +class ExportEntry(object): + def __init__(self, name, prefix, suffix, flags): + self.name = name + self.prefix = prefix + self.suffix = suffix + self.flags = flags + + @cached_property + def value(self): + return resolve(self.prefix, self.suffix) + + def __repr__(self): # pragma: no cover + return '<ExportEntry %s = %s:%s %s>' % (self.name, self.prefix, + self.suffix, self.flags) + + def __eq__(self, other): + if not isinstance(other, ExportEntry): + result = False + else: + result = (self.name == other.name and + self.prefix == other.prefix and + self.suffix == other.suffix and + self.flags == other.flags) + return result + + __hash__ = object.__hash__ + + +ENTRY_RE = re.compile(r'''(?P<name>(\w|[-.+])+) + \s*=\s*(?P<callable>(\w+)([:\.]\w+)*) + \s*(\[\s*(?P<flags>\w+(=\w+)?(,\s*\w+(=\w+)?)*)\s*\])? + ''', re.VERBOSE) + +def get_export_entry(specification): + m = ENTRY_RE.search(specification) + if not m: + result = None + if '[' in specification or ']' in specification: + raise DistlibException("Invalid specification " + "'%s'" % specification) + else: + d = m.groupdict() + name = d['name'] + path = d['callable'] + colons = path.count(':') + if colons == 0: + prefix, suffix = path, None + else: + if colons != 1: + raise DistlibException("Invalid specification " + "'%s'" % specification) + prefix, suffix = path.split(':') + flags = d['flags'] + if flags is None: + if '[' in specification or ']' in specification: + raise DistlibException("Invalid specification " + "'%s'" % specification) + flags = [] + else: + flags = [f.strip() for f in flags.split(',')] + result = ExportEntry(name, prefix, suffix, flags) + return result + + +def get_cache_base(suffix=None): + """ + Return the default base location for distlib caches. If the directory does + not exist, it is created. Use the suffix provided for the base directory, + and default to '.distlib' if it isn't provided. + + On Windows, if LOCALAPPDATA is defined in the environment, then it is + assumed to be a directory, and will be the parent directory of the result. + On POSIX, and on Windows if LOCALAPPDATA is not defined, the user's home + directory - using os.expanduser('~') - will be the parent directory of + the result. + + The result is just the directory '.distlib' in the parent directory as + determined above, or with the name specified with ``suffix``. + """ + if suffix is None: + suffix = '.distlib' + if os.name == 'nt' and 'LOCALAPPDATA' in os.environ: + result = os.path.expandvars('$localappdata') + else: + # Assume posix, or old Windows + result = os.path.expanduser('~') + # we use 'isdir' instead of 'exists', because we want to + # fail if there's a file with that name + if os.path.isdir(result): + usable = os.access(result, os.W_OK) + if not usable: + logger.warning('Directory exists but is not writable: %s', result) + else: + try: + os.makedirs(result) + usable = True + except OSError: + logger.warning('Unable to create %s', result, exc_info=True) + usable = False + if not usable: + result = tempfile.mkdtemp() + logger.warning('Default location unusable, using %s', result) + return os.path.join(result, suffix) + + +def path_to_cache_dir(path): + """ + Convert an absolute path to a directory name for use in a cache. + + The algorithm used is: + + #. On Windows, any ``':'`` in the drive is replaced with ``'---'``. + #. Any occurrence of ``os.sep`` is replaced with ``'--'``. + #. ``'.cache'`` is appended. + """ + d, p = os.path.splitdrive(os.path.abspath(path)) + if d: + d = d.replace(':', '---') + p = p.replace(os.sep, '--') + return d + p + '.cache' + + +def ensure_slash(s): + if not s.endswith('/'): + return s + '/' + return s + + +def parse_credentials(netloc): + username = password = None + if '@' in netloc: + prefix, netloc = netloc.split('@', 1) + if ':' not in prefix: + username = prefix + else: + username, password = prefix.split(':', 1) + return username, password, netloc + + +def get_process_umask(): + result = os.umask(0o22) + os.umask(result) + return result + +def is_string_sequence(seq): + result = True + i = None + for i, s in enumerate(seq): + if not isinstance(s, string_types): + result = False + break + assert i is not None + return result + +PROJECT_NAME_AND_VERSION = re.compile('([a-z0-9_]+([.-][a-z_][a-z0-9_]*)*)-' + '([a-z0-9_.+-]+)', re.I) +PYTHON_VERSION = re.compile(r'-py(\d\.?\d?)') + + +def split_filename(filename, project_name=None): + """ + Extract name, version, python version from a filename (no extension) + + Return name, version, pyver or None + """ + result = None + pyver = None + filename = unquote(filename).replace(' ', '-') + m = PYTHON_VERSION.search(filename) + if m: + pyver = m.group(1) + filename = filename[:m.start()] + if project_name and len(filename) > len(project_name) + 1: + m = re.match(re.escape(project_name) + r'\b', filename) + if m: + n = m.end() + result = filename[:n], filename[n + 1:], pyver + if result is None: + m = PROJECT_NAME_AND_VERSION.match(filename) + if m: + result = m.group(1), m.group(3), pyver + return result + +# Allow spaces in name because of legacy dists like "Twisted Core" +NAME_VERSION_RE = re.compile(r'(?P<name>[\w .-]+)\s*' + r'\(\s*(?P<ver>[^\s)]+)\)$') + +def parse_name_and_version(p): + """ + A utility method used to get name and version from a string. + + From e.g. a Provides-Dist value. + + :param p: A value in a form 'foo (1.0)' + :return: The name and version as a tuple. + """ + m = NAME_VERSION_RE.match(p) + if not m: + raise DistlibException('Ill-formed name/version string: \'%s\'' % p) + d = m.groupdict() + return d['name'].strip().lower(), d['ver'] + +def get_extras(requested, available): + result = set() + requested = set(requested or []) + available = set(available or []) + if '*' in requested: + requested.remove('*') + result |= available + for r in requested: + if r == '-': + result.add(r) + elif r.startswith('-'): + unwanted = r[1:] + if unwanted not in available: + logger.warning('undeclared extra: %s' % unwanted) + if unwanted in result: + result.remove(unwanted) + else: + if r not in available: + logger.warning('undeclared extra: %s' % r) + result.add(r) + return result +# +# Extended metadata functionality +# + +def _get_external_data(url): + result = {} + try: + # urlopen might fail if it runs into redirections, + # because of Python issue #13696. Fixed in locators + # using a custom redirect handler. + resp = urlopen(url) + headers = resp.info() + ct = headers.get('Content-Type') + if not ct.startswith('application/json'): + logger.debug('Unexpected response for JSON request: %s', ct) + else: + reader = codecs.getreader('utf-8')(resp) + #data = reader.read().decode('utf-8') + #result = json.loads(data) + result = json.load(reader) + except Exception as e: + logger.exception('Failed to get external data for %s: %s', url, e) + return result + +_external_data_base_url = 'https://www.red-dove.com/pypi/projects/' + +def get_project_data(name): + url = '%s/%s/project.json' % (name[0].upper(), name) + url = urljoin(_external_data_base_url, url) + result = _get_external_data(url) + return result + +def get_package_data(name, version): + url = '%s/%s/package-%s.json' % (name[0].upper(), name, version) + url = urljoin(_external_data_base_url, url) + return _get_external_data(url) + + +class Cache(object): + """ + A class implementing a cache for resources that need to live in the file system + e.g. shared libraries. This class was moved from resources to here because it + could be used by other modules, e.g. the wheel module. + """ + + def __init__(self, base): + """ + Initialise an instance. + + :param base: The base directory where the cache should be located. + """ + # we use 'isdir' instead of 'exists', because we want to + # fail if there's a file with that name + if not os.path.isdir(base): # pragma: no cover + os.makedirs(base) + if (os.stat(base).st_mode & 0o77) != 0: + logger.warning('Directory \'%s\' is not private', base) + self.base = os.path.abspath(os.path.normpath(base)) + + def prefix_to_dir(self, prefix): + """ + Converts a resource prefix to a directory name in the cache. + """ + return path_to_cache_dir(prefix) + + def clear(self): + """ + Clear the cache. + """ + not_removed = [] + for fn in os.listdir(self.base): + fn = os.path.join(self.base, fn) + try: + if os.path.islink(fn) or os.path.isfile(fn): + os.remove(fn) + elif os.path.isdir(fn): + shutil.rmtree(fn) + except Exception: + not_removed.append(fn) + return not_removed + + +class EventMixin(object): + """ + A very simple publish/subscribe system. + """ + def __init__(self): + self._subscribers = {} + + def add(self, event, subscriber, append=True): + """ + Add a subscriber for an event. + + :param event: The name of an event. + :param subscriber: The subscriber to be added (and called when the + event is published). + :param append: Whether to append or prepend the subscriber to an + existing subscriber list for the event. + """ + subs = self._subscribers + if event not in subs: + subs[event] = deque([subscriber]) + else: + sq = subs[event] + if append: + sq.append(subscriber) + else: + sq.appendleft(subscriber) + + def remove(self, event, subscriber): + """ + Remove a subscriber for an event. + + :param event: The name of an event. + :param subscriber: The subscriber to be removed. + """ + subs = self._subscribers + if event not in subs: + raise ValueError('No subscribers: %r' % event) + subs[event].remove(subscriber) + + def get_subscribers(self, event): + """ + Return an iterator for the subscribers for an event. + :param event: The event to return subscribers for. + """ + return iter(self._subscribers.get(event, ())) + + def publish(self, event, *args, **kwargs): + """ + Publish a event and return a list of values returned by its + subscribers. + + :param event: The event to publish. + :param args: The positional arguments to pass to the event's + subscribers. + :param kwargs: The keyword arguments to pass to the event's + subscribers. + """ + result = [] + for subscriber in self.get_subscribers(event): + try: + value = subscriber(event, *args, **kwargs) + except Exception: + logger.exception('Exception during event publication') + value = None + result.append(value) + logger.debug('publish %s: args = %s, kwargs = %s, result = %s', + event, args, kwargs, result) + return result + +# +# Simple sequencing +# +class Sequencer(object): + def __init__(self): + self._preds = {} + self._succs = {} + self._nodes = set() # nodes with no preds/succs + + def add_node(self, node): + self._nodes.add(node) + + def remove_node(self, node, edges=False): + if node in self._nodes: + self._nodes.remove(node) + if edges: + for p in set(self._preds.get(node, ())): + self.remove(p, node) + for s in set(self._succs.get(node, ())): + self.remove(node, s) + # Remove empties + for k, v in list(self._preds.items()): + if not v: + del self._preds[k] + for k, v in list(self._succs.items()): + if not v: + del self._succs[k] + + def add(self, pred, succ): + assert pred != succ + self._preds.setdefault(succ, set()).add(pred) + self._succs.setdefault(pred, set()).add(succ) + + def remove(self, pred, succ): + assert pred != succ + try: + preds = self._preds[succ] + succs = self._succs[pred] + except KeyError: # pragma: no cover + raise ValueError('%r not a successor of anything' % succ) + try: + preds.remove(pred) + succs.remove(succ) + except KeyError: # pragma: no cover + raise ValueError('%r not a successor of %r' % (succ, pred)) + + def is_step(self, step): + return (step in self._preds or step in self._succs or + step in self._nodes) + + def get_steps(self, final): + if not self.is_step(final): + raise ValueError('Unknown: %r' % final) + result = [] + todo = [] + seen = set() + todo.append(final) + while todo: + step = todo.pop(0) + if step in seen: + # if a step was already seen, + # move it to the end (so it will appear earlier + # when reversed on return) ... but not for the + # final step, as that would be confusing for + # users + if step != final: + result.remove(step) + result.append(step) + else: + seen.add(step) + result.append(step) + preds = self._preds.get(step, ()) + todo.extend(preds) + return reversed(result) + + @property + def strong_connections(self): + #http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm + index_counter = [0] + stack = [] + lowlinks = {} + index = {} + result = [] + + graph = self._succs + + def strongconnect(node): + # set the depth index for this node to the smallest unused index + index[node] = index_counter[0] + lowlinks[node] = index_counter[0] + index_counter[0] += 1 + stack.append(node) + + # Consider successors + try: + successors = graph[node] + except Exception: + successors = [] + for successor in successors: + if successor not in lowlinks: + # Successor has not yet been visited + strongconnect(successor) + lowlinks[node] = min(lowlinks[node],lowlinks[successor]) + elif successor in stack: + # the successor is in the stack and hence in the current + # strongly connected component (SCC) + lowlinks[node] = min(lowlinks[node],index[successor]) + + # If `node` is a root node, pop the stack and generate an SCC + if lowlinks[node] == index[node]: + connected_component = [] + + while True: + successor = stack.pop() + connected_component.append(successor) + if successor == node: break + component = tuple(connected_component) + # storing the result + result.append(component) + + for node in graph: + if node not in lowlinks: + strongconnect(node) + + return result + + @property + def dot(self): + result = ['digraph G {'] + for succ in self._preds: + preds = self._preds[succ] + for pred in preds: + result.append(' %s -> %s;' % (pred, succ)) + for node in self._nodes: + result.append(' %s;' % node) + result.append('}') + return '\n'.join(result) + +# +# Unarchiving functionality for zip, tar, tgz, tbz, whl +# + +ARCHIVE_EXTENSIONS = ('.tar.gz', '.tar.bz2', '.tar', '.zip', + '.tgz', '.tbz', '.whl') + +def unarchive(archive_filename, dest_dir, format=None, check=True): + + def check_path(path): + if not isinstance(path, text_type): + path = path.decode('utf-8') + p = os.path.abspath(os.path.join(dest_dir, path)) + if not p.startswith(dest_dir) or p[plen] != os.sep: + raise ValueError('path outside destination: %r' % p) + + dest_dir = os.path.abspath(dest_dir) + plen = len(dest_dir) + archive = None + if format is None: + if archive_filename.endswith(('.zip', '.whl')): + format = 'zip' + elif archive_filename.endswith(('.tar.gz', '.tgz')): + format = 'tgz' + mode = 'r:gz' + elif archive_filename.endswith(('.tar.bz2', '.tbz')): + format = 'tbz' + mode = 'r:bz2' + elif archive_filename.endswith('.tar'): + format = 'tar' + mode = 'r' + else: # pragma: no cover + raise ValueError('Unknown format for %r' % archive_filename) + try: + if format == 'zip': + archive = ZipFile(archive_filename, 'r') + if check: + names = archive.namelist() + for name in names: + check_path(name) + else: + archive = tarfile.open(archive_filename, mode) + if check: + names = archive.getnames() + for name in names: + check_path(name) + if format != 'zip' and sys.version_info[0] < 3: + # See Python issue 17153. If the dest path contains Unicode, + # tarfile extraction fails on Python 2.x if a member path name + # contains non-ASCII characters - it leads to an implicit + # bytes -> unicode conversion using ASCII to decode. + for tarinfo in archive.getmembers(): + if not isinstance(tarinfo.name, text_type): + tarinfo.name = tarinfo.name.decode('utf-8') + archive.extractall(dest_dir) + + finally: + if archive: + archive.close() + + +def zip_dir(directory): + """zip a directory tree into a BytesIO object""" + result = io.BytesIO() + dlen = len(directory) + with ZipFile(result, "w") as zf: + for root, dirs, files in os.walk(directory): + for name in files: + full = os.path.join(root, name) + rel = root[dlen:] + dest = os.path.join(rel, name) + zf.write(full, dest) + return result + +# +# Simple progress bar +# + +UNITS = ('', 'K', 'M', 'G','T','P') + + +class Progress(object): + unknown = 'UNKNOWN' + + def __init__(self, minval=0, maxval=100): + assert maxval is None or maxval >= minval + self.min = self.cur = minval + self.max = maxval + self.started = None + self.elapsed = 0 + self.done = False + + def update(self, curval): + assert self.min <= curval + assert self.max is None or curval <= self.max + self.cur = curval + now = time.time() + if self.started is None: + self.started = now + else: + self.elapsed = now - self.started + + def increment(self, incr): + assert incr >= 0 + self.update(self.cur + incr) + + def start(self): + self.update(self.min) + return self + + def stop(self): + if self.max is not None: + self.update(self.max) + self.done = True + + @property + def maximum(self): + return self.unknown if self.max is None else self.max + + @property + def percentage(self): + if self.done: + result = '100 %' + elif self.max is None: + result = ' ?? %' + else: + v = 100.0 * (self.cur - self.min) / (self.max - self.min) + result = '%3d %%' % v + return result + + def format_duration(self, duration): + if (duration <= 0) and self.max is None or self.cur == self.min: + result = '??:??:??' + #elif duration < 1: + # result = '--:--:--' + else: + result = time.strftime('%H:%M:%S', time.gmtime(duration)) + return result + + @property + def ETA(self): + if self.done: + prefix = 'Done' + t = self.elapsed + #import pdb; pdb.set_trace() + else: + prefix = 'ETA ' + if self.max is None: + t = -1 + elif self.elapsed == 0 or (self.cur == self.min): + t = 0 + else: + #import pdb; pdb.set_trace() + t = float(self.max - self.min) + t /= self.cur - self.min + t = (t - 1) * self.elapsed + return '%s: %s' % (prefix, self.format_duration(t)) + + @property + def speed(self): + if self.elapsed == 0: + result = 0.0 + else: + result = (self.cur - self.min) / self.elapsed + for unit in UNITS: + if result < 1000: + break + result /= 1000.0 + return '%d %sB/s' % (result, unit) + +# +# Glob functionality +# + +RICH_GLOB = re.compile(r'\{([^}]*)\}') +_CHECK_RECURSIVE_GLOB = re.compile(r'[^/\\,{]\*\*|\*\*[^/\\,}]') +_CHECK_MISMATCH_SET = re.compile(r'^[^{]*\}|\{[^}]*$') + + +def iglob(path_glob): + """Extended globbing function that supports ** and {opt1,opt2,opt3}.""" + if _CHECK_RECURSIVE_GLOB.search(path_glob): + msg = """invalid glob %r: recursive glob "**" must be used alone""" + raise ValueError(msg % path_glob) + if _CHECK_MISMATCH_SET.search(path_glob): + msg = """invalid glob %r: mismatching set marker '{' or '}'""" + raise ValueError(msg % path_glob) + return _iglob(path_glob) + + +def _iglob(path_glob): + rich_path_glob = RICH_GLOB.split(path_glob, 1) + if len(rich_path_glob) > 1: + assert len(rich_path_glob) == 3, rich_path_glob + prefix, set, suffix = rich_path_glob + for item in set.split(','): + for path in _iglob(''.join((prefix, item, suffix))): + yield path + else: + if '**' not in path_glob: + for item in std_iglob(path_glob): + yield item + else: + prefix, radical = path_glob.split('**', 1) + if prefix == '': + prefix = '.' + if radical == '': + radical = '*' + else: + # we support both + radical = radical.lstrip('/') + radical = radical.lstrip('\\') + for path, dir, files in os.walk(prefix): + path = os.path.normpath(path) + for fn in _iglob(os.path.join(path, radical)): + yield fn + +if ssl: + from .compat import (HTTPSHandler as BaseHTTPSHandler, match_hostname, + CertificateError) + + +# +# HTTPSConnection which verifies certificates/matches domains +# + + class HTTPSConnection(httplib.HTTPSConnection): + ca_certs = None # set this to the path to the certs file (.pem) + check_domain = True # only used if ca_certs is not None + + # noinspection PyPropertyAccess + def connect(self): + sock = socket.create_connection((self.host, self.port), self.timeout) + if getattr(self, '_tunnel_host', False): + self.sock = sock + self._tunnel() + + if not hasattr(ssl, 'SSLContext'): + # For 2.x + if self.ca_certs: + cert_reqs = ssl.CERT_REQUIRED + else: + cert_reqs = ssl.CERT_NONE + self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, + cert_reqs=cert_reqs, + ssl_version=ssl.PROTOCOL_SSLv23, + ca_certs=self.ca_certs) + else: # pragma: no cover + context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + context.options |= ssl.OP_NO_SSLv2 + if self.cert_file: + context.load_cert_chain(self.cert_file, self.key_file) + kwargs = {} + if self.ca_certs: + context.verify_mode = ssl.CERT_REQUIRED + context.load_verify_locations(cafile=self.ca_certs) + if getattr(ssl, 'HAS_SNI', False): + kwargs['server_hostname'] = self.host + self.sock = context.wrap_socket(sock, **kwargs) + if self.ca_certs and self.check_domain: + try: + match_hostname(self.sock.getpeercert(), self.host) + logger.debug('Host verified: %s', self.host) + except CertificateError: # pragma: no cover + self.sock.shutdown(socket.SHUT_RDWR) + self.sock.close() + raise + + class HTTPSHandler(BaseHTTPSHandler): + def __init__(self, ca_certs, check_domain=True): + BaseHTTPSHandler.__init__(self) + self.ca_certs = ca_certs + self.check_domain = check_domain + + def _conn_maker(self, *args, **kwargs): + """ + This is called to create a connection instance. Normally you'd + pass a connection class to do_open, but it doesn't actually check for + a class, and just expects a callable. As long as we behave just as a + constructor would have, we should be OK. If it ever changes so that + we *must* pass a class, we'll create an UnsafeHTTPSConnection class + which just sets check_domain to False in the class definition, and + choose which one to pass to do_open. + """ + result = HTTPSConnection(*args, **kwargs) + if self.ca_certs: + result.ca_certs = self.ca_certs + result.check_domain = self.check_domain + return result + + def https_open(self, req): + try: + return self.do_open(self._conn_maker, req) + except URLError as e: + if 'certificate verify failed' in str(e.reason): + raise CertificateError('Unable to verify server certificate ' + 'for %s' % req.host) + else: + raise + + # + # To prevent against mixing HTTP traffic with HTTPS (examples: A Man-In-The- + # Middle proxy using HTTP listens on port 443, or an index mistakenly serves + # HTML containing a http://xyz link when it should be https://xyz), + # you can use the following handler class, which does not allow HTTP traffic. + # + # It works by inheriting from HTTPHandler - so build_opener won't add a + # handler for HTTP itself. + # + class HTTPSOnlyHandler(HTTPSHandler, HTTPHandler): + def http_open(self, req): + raise URLError('Unexpected HTTP request on what should be a secure ' + 'connection: %s' % req) + +# +# XML-RPC with timeouts +# + +_ver_info = sys.version_info[:2] + +if _ver_info == (2, 6): + class HTTP(httplib.HTTP): + def __init__(self, host='', port=None, **kwargs): + if port == 0: # 0 means use port 0, not the default port + port = None + self._setup(self._connection_class(host, port, **kwargs)) + + + if ssl: + class HTTPS(httplib.HTTPS): + def __init__(self, host='', port=None, **kwargs): + if port == 0: # 0 means use port 0, not the default port + port = None + self._setup(self._connection_class(host, port, **kwargs)) + + +class Transport(xmlrpclib.Transport): + def __init__(self, timeout, use_datetime=0): + self.timeout = timeout + xmlrpclib.Transport.__init__(self, use_datetime) + + def make_connection(self, host): + h, eh, x509 = self.get_host_info(host) + if _ver_info == (2, 6): + result = HTTP(h, timeout=self.timeout) + else: + if not self._connection or host != self._connection[0]: + self._extra_headers = eh + self._connection = host, httplib.HTTPConnection(h) + result = self._connection[1] + return result + +if ssl: + class SafeTransport(xmlrpclib.SafeTransport): + def __init__(self, timeout, use_datetime=0): + self.timeout = timeout + xmlrpclib.SafeTransport.__init__(self, use_datetime) + + def make_connection(self, host): + h, eh, kwargs = self.get_host_info(host) + if not kwargs: + kwargs = {} + kwargs['timeout'] = self.timeout + if _ver_info == (2, 6): + result = HTTPS(host, None, **kwargs) + else: + if not self._connection or host != self._connection[0]: + self._extra_headers = eh + self._connection = host, httplib.HTTPSConnection(h, None, + **kwargs) + result = self._connection[1] + return result + + +class ServerProxy(xmlrpclib.ServerProxy): + def __init__(self, uri, **kwargs): + self.timeout = timeout = kwargs.pop('timeout', None) + # The above classes only come into play if a timeout + # is specified + if timeout is not None: + scheme, _ = splittype(uri) + use_datetime = kwargs.get('use_datetime', 0) + if scheme == 'https': + tcls = SafeTransport + else: + tcls = Transport + kwargs['transport'] = t = tcls(timeout, use_datetime=use_datetime) + self.transport = t + xmlrpclib.ServerProxy.__init__(self, uri, **kwargs) + +# +# CSV functionality. This is provided because on 2.x, the csv module can't +# handle Unicode. However, we need to deal with Unicode in e.g. RECORD files. +# + +def _csv_open(fn, mode, **kwargs): + if sys.version_info[0] < 3: + mode += 'b' + else: + kwargs['newline'] = '' + # Python 3 determines encoding from locale. Force 'utf-8' + # file encoding to match other forced utf-8 encoding + kwargs['encoding'] = 'utf-8' + return open(fn, mode, **kwargs) + + +class CSVBase(object): + defaults = { + 'delimiter': str(','), # The strs are used because we need native + 'quotechar': str('"'), # str in the csv API (2.x won't take + 'lineterminator': str('\n') # Unicode) + } + + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.stream.close() + + +class CSVReader(CSVBase): + def __init__(self, **kwargs): + if 'stream' in kwargs: + stream = kwargs['stream'] + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getreader('utf-8')(stream) + self.stream = stream + else: + self.stream = _csv_open(kwargs['path'], 'r') + self.reader = csv.reader(self.stream, **self.defaults) + + def __iter__(self): + return self + + def next(self): + result = next(self.reader) + if sys.version_info[0] < 3: + for i, item in enumerate(result): + if not isinstance(item, text_type): + result[i] = item.decode('utf-8') + return result + + __next__ = next + +class CSVWriter(CSVBase): + def __init__(self, fn, **kwargs): + self.stream = _csv_open(fn, 'w') + self.writer = csv.writer(self.stream, **self.defaults) + + def writerow(self, row): + if sys.version_info[0] < 3: + r = [] + for item in row: + if isinstance(item, text_type): + item = item.encode('utf-8') + r.append(item) + row = r + self.writer.writerow(row) + +# +# Configurator functionality +# + +class Configurator(BaseConfigurator): + + value_converters = dict(BaseConfigurator.value_converters) + value_converters['inc'] = 'inc_convert' + + def __init__(self, config, base=None): + super(Configurator, self).__init__(config) + self.base = base or os.getcwd() + + def configure_custom(self, config): + def convert(o): + if isinstance(o, (list, tuple)): + result = type(o)([convert(i) for i in o]) + elif isinstance(o, dict): + if '()' in o: + result = self.configure_custom(o) + else: + result = {} + for k in o: + result[k] = convert(o[k]) + else: + result = self.convert(o) + return result + + c = config.pop('()') + if not callable(c): + c = self.resolve(c) + props = config.pop('.', None) + # Check for valid identifiers + args = config.pop('[]', ()) + if args: + args = tuple([convert(o) for o in args]) + items = [(k, convert(config[k])) for k in config if valid_ident(k)] + kwargs = dict(items) + result = c(*args, **kwargs) + if props: + for n, v in props.items(): + setattr(result, n, convert(v)) + return result + + def __getitem__(self, key): + result = self.config[key] + if isinstance(result, dict) and '()' in result: + self.config[key] = result = self.configure_custom(result) + return result + + def inc_convert(self, value): + """Default converter for the inc:// protocol.""" + if not os.path.isabs(value): + value = os.path.join(self.base, value) + with codecs.open(value, 'r', encoding='utf-8') as f: + result = json.load(f) + return result + + +class SubprocessMixin(object): + """ + Mixin for running subprocesses and capturing their output + """ + def __init__(self, verbose=False, progress=None): + self.verbose = verbose + self.progress = progress + + def reader(self, stream, context): + """ + Read lines from a subprocess' output stream and either pass to a progress + callable (if specified) or write progress information to sys.stderr. + """ + progress = self.progress + verbose = self.verbose + while True: + s = stream.readline() + if not s: + break + if progress is not None: + progress(s, context) + else: + if not verbose: + sys.stderr.write('.') + else: + sys.stderr.write(s.decode('utf-8')) + sys.stderr.flush() + stream.close() + + def run_command(self, cmd, **kwargs): + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, **kwargs) + t1 = threading.Thread(target=self.reader, args=(p.stdout, 'stdout')) + t1.start() + t2 = threading.Thread(target=self.reader, args=(p.stderr, 'stderr')) + t2.start() + p.wait() + t1.join() + t2.join() + if self.progress is not None: + self.progress('done.', 'main') + elif self.verbose: + sys.stderr.write('done.\n') + return p + + +def normalize_name(name): + """Normalize a python package name a la PEP 503""" + # https://www.python.org/dev/peps/pep-0503/#normalized-names + return re.sub('[-_.]+', '-', name).lower() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/version.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/version.py new file mode 100644 index 0000000..3eebe18 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/version.py @@ -0,0 +1,736 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Implementation of a flexible versioning scheme providing support for PEP-440, +setuptools-compatible and semantic versioning. +""" + +import logging +import re + +from .compat import string_types +from .util import parse_requirement + +__all__ = ['NormalizedVersion', 'NormalizedMatcher', + 'LegacyVersion', 'LegacyMatcher', + 'SemanticVersion', 'SemanticMatcher', + 'UnsupportedVersionError', 'get_scheme'] + +logger = logging.getLogger(__name__) + + +class UnsupportedVersionError(ValueError): + """This is an unsupported version.""" + pass + + +class Version(object): + def __init__(self, s): + self._string = s = s.strip() + self._parts = parts = self.parse(s) + assert isinstance(parts, tuple) + assert len(parts) > 0 + + def parse(self, s): + raise NotImplementedError('please implement in a subclass') + + def _check_compatible(self, other): + if type(self) != type(other): + raise TypeError('cannot compare %r and %r' % (self, other)) + + def __eq__(self, other): + self._check_compatible(other) + return self._parts == other._parts + + def __ne__(self, other): + return not self.__eq__(other) + + def __lt__(self, other): + self._check_compatible(other) + return self._parts < other._parts + + def __gt__(self, other): + return not (self.__lt__(other) or self.__eq__(other)) + + def __le__(self, other): + return self.__lt__(other) or self.__eq__(other) + + def __ge__(self, other): + return self.__gt__(other) or self.__eq__(other) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + def __hash__(self): + return hash(self._parts) + + def __repr__(self): + return "%s('%s')" % (self.__class__.__name__, self._string) + + def __str__(self): + return self._string + + @property + def is_prerelease(self): + raise NotImplementedError('Please implement in subclasses.') + + +class Matcher(object): + version_class = None + + # value is either a callable or the name of a method + _operators = { + '<': lambda v, c, p: v < c, + '>': lambda v, c, p: v > c, + '<=': lambda v, c, p: v == c or v < c, + '>=': lambda v, c, p: v == c or v > c, + '==': lambda v, c, p: v == c, + '===': lambda v, c, p: v == c, + # by default, compatible => >=. + '~=': lambda v, c, p: v == c or v > c, + '!=': lambda v, c, p: v != c, + } + + # this is a method only to support alternative implementations + # via overriding + def parse_requirement(self, s): + return parse_requirement(s) + + def __init__(self, s): + if self.version_class is None: + raise ValueError('Please specify a version class') + self._string = s = s.strip() + r = self.parse_requirement(s) + if not r: + raise ValueError('Not valid: %r' % s) + self.name = r.name + self.key = self.name.lower() # for case-insensitive comparisons + clist = [] + if r.constraints: + # import pdb; pdb.set_trace() + for op, s in r.constraints: + if s.endswith('.*'): + if op not in ('==', '!='): + raise ValueError('\'.*\' not allowed for ' + '%r constraints' % op) + # Could be a partial version (e.g. for '2.*') which + # won't parse as a version, so keep it as a string + vn, prefix = s[:-2], True + # Just to check that vn is a valid version + self.version_class(vn) + else: + # Should parse as a version, so we can create an + # instance for the comparison + vn, prefix = self.version_class(s), False + clist.append((op, vn, prefix)) + self._parts = tuple(clist) + + def match(self, version): + """ + Check if the provided version matches the constraints. + + :param version: The version to match against this instance. + :type version: String or :class:`Version` instance. + """ + if isinstance(version, string_types): + version = self.version_class(version) + for operator, constraint, prefix in self._parts: + f = self._operators.get(operator) + if isinstance(f, string_types): + f = getattr(self, f) + if not f: + msg = ('%r not implemented ' + 'for %s' % (operator, self.__class__.__name__)) + raise NotImplementedError(msg) + if not f(version, constraint, prefix): + return False + return True + + @property + def exact_version(self): + result = None + if len(self._parts) == 1 and self._parts[0][0] in ('==', '==='): + result = self._parts[0][1] + return result + + def _check_compatible(self, other): + if type(self) != type(other) or self.name != other.name: + raise TypeError('cannot compare %s and %s' % (self, other)) + + def __eq__(self, other): + self._check_compatible(other) + return self.key == other.key and self._parts == other._parts + + def __ne__(self, other): + return not self.__eq__(other) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + def __hash__(self): + return hash(self.key) + hash(self._parts) + + def __repr__(self): + return "%s(%r)" % (self.__class__.__name__, self._string) + + def __str__(self): + return self._string + + +PEP440_VERSION_RE = re.compile(r'^v?(\d+!)?(\d+(\.\d+)*)((a|b|c|rc)(\d+))?' + r'(\.(post)(\d+))?(\.(dev)(\d+))?' + r'(\+([a-zA-Z\d]+(\.[a-zA-Z\d]+)?))?$') + + +def _pep_440_key(s): + s = s.strip() + m = PEP440_VERSION_RE.match(s) + if not m: + raise UnsupportedVersionError('Not a valid version: %s' % s) + groups = m.groups() + nums = tuple(int(v) for v in groups[1].split('.')) + while len(nums) > 1 and nums[-1] == 0: + nums = nums[:-1] + + if not groups[0]: + epoch = 0 + else: + epoch = int(groups[0]) + pre = groups[4:6] + post = groups[7:9] + dev = groups[10:12] + local = groups[13] + if pre == (None, None): + pre = () + else: + pre = pre[0], int(pre[1]) + if post == (None, None): + post = () + else: + post = post[0], int(post[1]) + if dev == (None, None): + dev = () + else: + dev = dev[0], int(dev[1]) + if local is None: + local = () + else: + parts = [] + for part in local.split('.'): + # to ensure that numeric compares as > lexicographic, avoid + # comparing them directly, but encode a tuple which ensures + # correct sorting + if part.isdigit(): + part = (1, int(part)) + else: + part = (0, part) + parts.append(part) + local = tuple(parts) + if not pre: + # either before pre-release, or final release and after + if not post and dev: + # before pre-release + pre = ('a', -1) # to sort before a0 + else: + pre = ('z',) # to sort after all pre-releases + # now look at the state of post and dev. + if not post: + post = ('_',) # sort before 'a' + if not dev: + dev = ('final',) + + #print('%s -> %s' % (s, m.groups())) + return epoch, nums, pre, post, dev, local + + +_normalized_key = _pep_440_key + + +class NormalizedVersion(Version): + """A rational version. + + Good: + 1.2 # equivalent to "1.2.0" + 1.2.0 + 1.2a1 + 1.2.3a2 + 1.2.3b1 + 1.2.3c1 + 1.2.3.4 + TODO: fill this out + + Bad: + 1 # minimum two numbers + 1.2a # release level must have a release serial + 1.2.3b + """ + def parse(self, s): + result = _normalized_key(s) + # _normalized_key loses trailing zeroes in the release + # clause, since that's needed to ensure that X.Y == X.Y.0 == X.Y.0.0 + # However, PEP 440 prefix matching needs it: for example, + # (~= 1.4.5.0) matches differently to (~= 1.4.5.0.0). + m = PEP440_VERSION_RE.match(s) # must succeed + groups = m.groups() + self._release_clause = tuple(int(v) for v in groups[1].split('.')) + return result + + PREREL_TAGS = set(['a', 'b', 'c', 'rc', 'dev']) + + @property + def is_prerelease(self): + return any(t[0] in self.PREREL_TAGS for t in self._parts if t) + + +def _match_prefix(x, y): + x = str(x) + y = str(y) + if x == y: + return True + if not x.startswith(y): + return False + n = len(y) + return x[n] == '.' + + +class NormalizedMatcher(Matcher): + version_class = NormalizedVersion + + # value is either a callable or the name of a method + _operators = { + '~=': '_match_compatible', + '<': '_match_lt', + '>': '_match_gt', + '<=': '_match_le', + '>=': '_match_ge', + '==': '_match_eq', + '===': '_match_arbitrary', + '!=': '_match_ne', + } + + def _adjust_local(self, version, constraint, prefix): + if prefix: + strip_local = '+' not in constraint and version._parts[-1] + else: + # both constraint and version are + # NormalizedVersion instances. + # If constraint does not have a local component, + # ensure the version doesn't, either. + strip_local = not constraint._parts[-1] and version._parts[-1] + if strip_local: + s = version._string.split('+', 1)[0] + version = self.version_class(s) + return version, constraint + + def _match_lt(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version >= constraint: + return False + release_clause = constraint._release_clause + pfx = '.'.join([str(i) for i in release_clause]) + return not _match_prefix(version, pfx) + + def _match_gt(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version <= constraint: + return False + release_clause = constraint._release_clause + pfx = '.'.join([str(i) for i in release_clause]) + return not _match_prefix(version, pfx) + + def _match_le(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + return version <= constraint + + def _match_ge(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + return version >= constraint + + def _match_eq(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if not prefix: + result = (version == constraint) + else: + result = _match_prefix(version, constraint) + return result + + def _match_arbitrary(self, version, constraint, prefix): + return str(version) == str(constraint) + + def _match_ne(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if not prefix: + result = (version != constraint) + else: + result = not _match_prefix(version, constraint) + return result + + def _match_compatible(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version == constraint: + return True + if version < constraint: + return False +# if not prefix: +# return True + release_clause = constraint._release_clause + if len(release_clause) > 1: + release_clause = release_clause[:-1] + pfx = '.'.join([str(i) for i in release_clause]) + return _match_prefix(version, pfx) + +_REPLACEMENTS = ( + (re.compile('[.+-]$'), ''), # remove trailing puncts + (re.compile(r'^[.](\d)'), r'0.\1'), # .N -> 0.N at start + (re.compile('^[.-]'), ''), # remove leading puncts + (re.compile(r'^\((.*)\)$'), r'\1'), # remove parentheses + (re.compile(r'^v(ersion)?\s*(\d+)'), r'\2'), # remove leading v(ersion) + (re.compile(r'^r(ev)?\s*(\d+)'), r'\2'), # remove leading v(ersion) + (re.compile('[.]{2,}'), '.'), # multiple runs of '.' + (re.compile(r'\b(alfa|apha)\b'), 'alpha'), # misspelt alpha + (re.compile(r'\b(pre-alpha|prealpha)\b'), + 'pre.alpha'), # standardise + (re.compile(r'\(beta\)$'), 'beta'), # remove parentheses +) + +_SUFFIX_REPLACEMENTS = ( + (re.compile('^[:~._+-]+'), ''), # remove leading puncts + (re.compile('[,*")([\\]]'), ''), # remove unwanted chars + (re.compile('[~:+_ -]'), '.'), # replace illegal chars + (re.compile('[.]{2,}'), '.'), # multiple runs of '.' + (re.compile(r'\.$'), ''), # trailing '.' +) + +_NUMERIC_PREFIX = re.compile(r'(\d+(\.\d+)*)') + + +def _suggest_semantic_version(s): + """ + Try to suggest a semantic form for a version for which + _suggest_normalized_version couldn't come up with anything. + """ + result = s.strip().lower() + for pat, repl in _REPLACEMENTS: + result = pat.sub(repl, result) + if not result: + result = '0.0.0' + + # Now look for numeric prefix, and separate it out from + # the rest. + #import pdb; pdb.set_trace() + m = _NUMERIC_PREFIX.match(result) + if not m: + prefix = '0.0.0' + suffix = result + else: + prefix = m.groups()[0].split('.') + prefix = [int(i) for i in prefix] + while len(prefix) < 3: + prefix.append(0) + if len(prefix) == 3: + suffix = result[m.end():] + else: + suffix = '.'.join([str(i) for i in prefix[3:]]) + result[m.end():] + prefix = prefix[:3] + prefix = '.'.join([str(i) for i in prefix]) + suffix = suffix.strip() + if suffix: + #import pdb; pdb.set_trace() + # massage the suffix. + for pat, repl in _SUFFIX_REPLACEMENTS: + suffix = pat.sub(repl, suffix) + + if not suffix: + result = prefix + else: + sep = '-' if 'dev' in suffix else '+' + result = prefix + sep + suffix + if not is_semver(result): + result = None + return result + + +def _suggest_normalized_version(s): + """Suggest a normalized version close to the given version string. + + If you have a version string that isn't rational (i.e. NormalizedVersion + doesn't like it) then you might be able to get an equivalent (or close) + rational version from this function. + + This does a number of simple normalizations to the given string, based + on observation of versions currently in use on PyPI. Given a dump of + those version during PyCon 2009, 4287 of them: + - 2312 (53.93%) match NormalizedVersion without change + with the automatic suggestion + - 3474 (81.04%) match when using this suggestion method + + @param s {str} An irrational version string. + @returns A rational version string, or None, if couldn't determine one. + """ + try: + _normalized_key(s) + return s # already rational + except UnsupportedVersionError: + pass + + rs = s.lower() + + # part of this could use maketrans + for orig, repl in (('-alpha', 'a'), ('-beta', 'b'), ('alpha', 'a'), + ('beta', 'b'), ('rc', 'c'), ('-final', ''), + ('-pre', 'c'), + ('-release', ''), ('.release', ''), ('-stable', ''), + ('+', '.'), ('_', '.'), (' ', ''), ('.final', ''), + ('final', '')): + rs = rs.replace(orig, repl) + + # if something ends with dev or pre, we add a 0 + rs = re.sub(r"pre$", r"pre0", rs) + rs = re.sub(r"dev$", r"dev0", rs) + + # if we have something like "b-2" or "a.2" at the end of the + # version, that is probably beta, alpha, etc + # let's remove the dash or dot + rs = re.sub(r"([abc]|rc)[\-\.](\d+)$", r"\1\2", rs) + + # 1.0-dev-r371 -> 1.0.dev371 + # 0.1-dev-r79 -> 0.1.dev79 + rs = re.sub(r"[\-\.](dev)[\-\.]?r?(\d+)$", r".\1\2", rs) + + # Clean: 2.0.a.3, 2.0.b1, 0.9.0~c1 + rs = re.sub(r"[.~]?([abc])\.?", r"\1", rs) + + # Clean: v0.3, v1.0 + if rs.startswith('v'): + rs = rs[1:] + + # Clean leading '0's on numbers. + #TODO: unintended side-effect on, e.g., "2003.05.09" + # PyPI stats: 77 (~2%) better + rs = re.sub(r"\b0+(\d+)(?!\d)", r"\1", rs) + + # Clean a/b/c with no version. E.g. "1.0a" -> "1.0a0". Setuptools infers + # zero. + # PyPI stats: 245 (7.56%) better + rs = re.sub(r"(\d+[abc])$", r"\g<1>0", rs) + + # the 'dev-rNNN' tag is a dev tag + rs = re.sub(r"\.?(dev-r|dev\.r)\.?(\d+)$", r".dev\2", rs) + + # clean the - when used as a pre delimiter + rs = re.sub(r"-(a|b|c)(\d+)$", r"\1\2", rs) + + # a terminal "dev" or "devel" can be changed into ".dev0" + rs = re.sub(r"[\.\-](dev|devel)$", r".dev0", rs) + + # a terminal "dev" can be changed into ".dev0" + rs = re.sub(r"(?![\.\-])dev$", r".dev0", rs) + + # a terminal "final" or "stable" can be removed + rs = re.sub(r"(final|stable)$", "", rs) + + # The 'r' and the '-' tags are post release tags + # 0.4a1.r10 -> 0.4a1.post10 + # 0.9.33-17222 -> 0.9.33.post17222 + # 0.9.33-r17222 -> 0.9.33.post17222 + rs = re.sub(r"\.?(r|-|-r)\.?(\d+)$", r".post\2", rs) + + # Clean 'r' instead of 'dev' usage: + # 0.9.33+r17222 -> 0.9.33.dev17222 + # 1.0dev123 -> 1.0.dev123 + # 1.0.git123 -> 1.0.dev123 + # 1.0.bzr123 -> 1.0.dev123 + # 0.1a0dev.123 -> 0.1a0.dev123 + # PyPI stats: ~150 (~4%) better + rs = re.sub(r"\.?(dev|git|bzr)\.?(\d+)$", r".dev\2", rs) + + # Clean '.pre' (normalized from '-pre' above) instead of 'c' usage: + # 0.2.pre1 -> 0.2c1 + # 0.2-c1 -> 0.2c1 + # 1.0preview123 -> 1.0c123 + # PyPI stats: ~21 (0.62%) better + rs = re.sub(r"\.?(pre|preview|-c)(\d+)$", r"c\g<2>", rs) + + # Tcl/Tk uses "px" for their post release markers + rs = re.sub(r"p(\d+)$", r".post\1", rs) + + try: + _normalized_key(rs) + except UnsupportedVersionError: + rs = None + return rs + +# +# Legacy version processing (distribute-compatible) +# + +_VERSION_PART = re.compile(r'([a-z]+|\d+|[\.-])', re.I) +_VERSION_REPLACE = { + 'pre': 'c', + 'preview': 'c', + '-': 'final-', + 'rc': 'c', + 'dev': '@', + '': None, + '.': None, +} + + +def _legacy_key(s): + def get_parts(s): + result = [] + for p in _VERSION_PART.split(s.lower()): + p = _VERSION_REPLACE.get(p, p) + if p: + if '0' <= p[:1] <= '9': + p = p.zfill(8) + else: + p = '*' + p + result.append(p) + result.append('*final') + return result + + result = [] + for p in get_parts(s): + if p.startswith('*'): + if p < '*final': + while result and result[-1] == '*final-': + result.pop() + while result and result[-1] == '00000000': + result.pop() + result.append(p) + return tuple(result) + + +class LegacyVersion(Version): + def parse(self, s): + return _legacy_key(s) + + @property + def is_prerelease(self): + result = False + for x in self._parts: + if (isinstance(x, string_types) and x.startswith('*') and + x < '*final'): + result = True + break + return result + + +class LegacyMatcher(Matcher): + version_class = LegacyVersion + + _operators = dict(Matcher._operators) + _operators['~='] = '_match_compatible' + + numeric_re = re.compile(r'^(\d+(\.\d+)*)') + + def _match_compatible(self, version, constraint, prefix): + if version < constraint: + return False + m = self.numeric_re.match(str(constraint)) + if not m: + logger.warning('Cannot compute compatible match for version %s ' + ' and constraint %s', version, constraint) + return True + s = m.groups()[0] + if '.' in s: + s = s.rsplit('.', 1)[0] + return _match_prefix(version, s) + +# +# Semantic versioning +# + +_SEMVER_RE = re.compile(r'^(\d+)\.(\d+)\.(\d+)' + r'(-[a-z0-9]+(\.[a-z0-9-]+)*)?' + r'(\+[a-z0-9]+(\.[a-z0-9-]+)*)?$', re.I) + + +def is_semver(s): + return _SEMVER_RE.match(s) + + +def _semantic_key(s): + def make_tuple(s, absent): + if s is None: + result = (absent,) + else: + parts = s[1:].split('.') + # We can't compare ints and strings on Python 3, so fudge it + # by zero-filling numeric values so simulate a numeric comparison + result = tuple([p.zfill(8) if p.isdigit() else p for p in parts]) + return result + + m = is_semver(s) + if not m: + raise UnsupportedVersionError(s) + groups = m.groups() + major, minor, patch = [int(i) for i in groups[:3]] + # choose the '|' and '*' so that versions sort correctly + pre, build = make_tuple(groups[3], '|'), make_tuple(groups[5], '*') + return (major, minor, patch), pre, build + + +class SemanticVersion(Version): + def parse(self, s): + return _semantic_key(s) + + @property + def is_prerelease(self): + return self._parts[1][0] != '|' + + +class SemanticMatcher(Matcher): + version_class = SemanticVersion + + +class VersionScheme(object): + def __init__(self, key, matcher, suggester=None): + self.key = key + self.matcher = matcher + self.suggester = suggester + + def is_valid_version(self, s): + try: + self.matcher.version_class(s) + result = True + except UnsupportedVersionError: + result = False + return result + + def is_valid_matcher(self, s): + try: + self.matcher(s) + result = True + except UnsupportedVersionError: + result = False + return result + + def is_valid_constraint_list(self, s): + """ + Used for processing some metadata fields + """ + return self.is_valid_matcher('dummy_name (%s)' % s) + + def suggest(self, s): + if self.suggester is None: + result = None + else: + result = self.suggester(s) + return result + +_SCHEMES = { + 'normalized': VersionScheme(_normalized_key, NormalizedMatcher, + _suggest_normalized_version), + 'legacy': VersionScheme(_legacy_key, LegacyMatcher, lambda self, s: s), + 'semantic': VersionScheme(_semantic_key, SemanticMatcher, + _suggest_semantic_version), +} + +_SCHEMES['default'] = _SCHEMES['normalized'] + + +def get_scheme(name): + if name not in _SCHEMES: + raise ValueError('unknown scheme name: %r' % name) + return _SCHEMES[name] diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/w32.exe b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/w32.exe new file mode 100755 index 0000000000000000000000000000000000000000..732215a9d34ccb7b417d637a7646d9b843ecafa8 GIT binary patch literal 89088 zcmeFae|S?>wm*FGqitH!CO`{C3REl(SahnPNDYM`O{q#T7)Xdvz$<hz5gjb&0FD$| zPs=nt#$jgk-tk`NUb*PJIy$3wMg@OiORy=5PEkZ0P^;6cyPm2=Y8#~Xyq~pC(iU~@ z_dd`2ywCg3TS)e=wSTX@_S$Q$y;FJf9>F9Cf*Bu86NCeB>CeT#|L3nblC!40kR?2m z{>H@z3`^g*ct!B1Tk<#8{Ol(+x7?n8>n(TO@iQ_1pEl;#NO$D_^p5<p8@>6r|7^p? zD>5@P3KB)%InlPUc<U{5lb_$uJ2!U@!dIxT&CTYnHuoCtzCL#`-1%8w%`JjkymkHD zpYr&>Cg9H}+(GW%^wV2|ROUbGfyXTfOART)i?<!WISJD#7!6|#8G`TvV*Xu^z32+K zc6>T0?9%;4K}Zn{6fx`yPa}*$9C+R!7zI~72c&$InY+UdMGBkF3c`HyxD3K09`bzW z?_q;rO&5ec#{?noJ4vI19bbHBt~vx^h2FH$V8i|^#EsiUg#JboP3@w-(&Uf&%NK<8 zSJZ5{MZ852W)~s>WeT(LIf&1wKNqULLI)GN_(-E-D)X~ZK=1;t<%*guHMhdg`-(mb zHzDv1KBN9zR9?--O+N$ReOXAr81V9z!X5SJ5`=3<1^<8V|AP@&sr2}Qvp;hQT24iW zOHg|EiZd1ojV;oo#(r^ba2`^8T22{~_UQ@YMZp7O1R*2@?SerFE~TuJB_wDaYC0h8 zfONF1t%{=H`W`bdYp+>YBsg9Ty9ec3iy+O3xa}TIvPK#Q&udyx1MvwG0(#iaGC|N| zJ#3?<Y4YLRkU`54s9BYRjyISA>){9$tW;Y34lPnX=&>D4X~|k7c$TwEfOzs@Yh#Nz z`FV;`(w!E`sKg@`2E}bDY>ku^4XS@tV(WO*<eu67;0Clk;vRHp!Qf<+5w0B!*Y>g? zYH=KK#%%Yu1~&m>IlB^#2^syGG|2AB1(}4aOcaC%!)}%`I7AIC2(Ro3yW`GSttng^ z_xb=ECor!L{-PNO>_ulJ3%fm=O0X!s%)$GZ?~I94l-^KEAX0n$?4wGpr7&i4#~)OB zQD%2NrWUKtZuYT1Vnu}AeF`cSgx>Rkk@}Lg{WltgT76VeA2aic`cTnpXrt2WXmJkM z9%u<Rp-*9{$HQ)>Xm?McyDyZ28Ux7mpxy?mnmvzMMr-85vkRrJLaDRx>|I7je+cM+ zj{RJ(3Vrgke;W@#D!y%U%fQLtlPKTAzWtVuOQdXpwsy6eRjt^cZ%0D4bF7$F;f!th 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ð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 literal 0 HcmV?d00001 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/w64.exe b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/w64.exe new file mode 100755 index 0000000000000000000000000000000000000000..c41bd0a011fd760ce20ba795d9e535e0d2c39876 GIT binary patch literal 99328 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 B=L-M; literal 0 HcmV?d00001 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/wheel.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/wheel.py new file mode 100644 index 0000000..7737223 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/wheel.py @@ -0,0 +1,984 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import unicode_literals + +import base64 +import codecs +import datetime +import distutils.util +from email import message_from_file +import hashlib +import imp +import json +import logging +import os +import posixpath +import re +import shutil +import sys +import tempfile +import zipfile + +from . import __version__, DistlibException +from .compat import sysconfig, ZipFile, fsdecode, text_type, filter +from .database import InstalledDistribution +from .metadata import Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME +from .util import (FileOperator, convert_path, CSVReader, CSVWriter, Cache, + cached_property, get_cache_base, read_exports, tempdir) +from .version import NormalizedVersion, UnsupportedVersionError + +logger = logging.getLogger(__name__) + +cache = None # created when needed + +if hasattr(sys, 'pypy_version_info'): # pragma: no cover + IMP_PREFIX = 'pp' +elif sys.platform.startswith('java'): # pragma: no cover + IMP_PREFIX = 'jy' +elif sys.platform == 'cli': # pragma: no cover + IMP_PREFIX = 'ip' +else: + IMP_PREFIX = 'cp' + +VER_SUFFIX = sysconfig.get_config_var('py_version_nodot') +if not VER_SUFFIX: # pragma: no cover + VER_SUFFIX = '%s%s' % sys.version_info[:2] +PYVER = 'py' + VER_SUFFIX +IMPVER = IMP_PREFIX + VER_SUFFIX + +ARCH = distutils.util.get_platform().replace('-', '_').replace('.', '_') + +ABI = sysconfig.get_config_var('SOABI') +if ABI and ABI.startswith('cpython-'): + ABI = ABI.replace('cpython-', 'cp') +else: + def _derive_abi(): + parts = ['cp', VER_SUFFIX] + if sysconfig.get_config_var('Py_DEBUG'): + parts.append('d') + if sysconfig.get_config_var('WITH_PYMALLOC'): + parts.append('m') + if sysconfig.get_config_var('Py_UNICODE_SIZE') == 4: + parts.append('u') + return ''.join(parts) + ABI = _derive_abi() + del _derive_abi + +FILENAME_RE = re.compile(r''' +(?P<nm>[^-]+) +-(?P<vn>\d+[^-]*) +(-(?P<bn>\d+[^-]*))? +-(?P<py>\w+\d+(\.\w+\d+)*) +-(?P<bi>\w+) +-(?P<ar>\w+(\.\w+)*) +\.whl$ +''', re.IGNORECASE | re.VERBOSE) + +NAME_VERSION_RE = re.compile(r''' +(?P<nm>[^-]+) +-(?P<vn>\d+[^-]*) +(-(?P<bn>\d+[^-]*))?$ +''', re.IGNORECASE | re.VERBOSE) + +SHEBANG_RE = re.compile(br'\s*#![^\r\n]*') +SHEBANG_DETAIL_RE = re.compile(br'^(\s*#!("[^"]+"|\S+))\s+(.*)$') +SHEBANG_PYTHON = b'#!python' +SHEBANG_PYTHONW = b'#!pythonw' + +if os.sep == '/': + to_posix = lambda o: o +else: + to_posix = lambda o: o.replace(os.sep, '/') + + +class Mounter(object): + def __init__(self): + self.impure_wheels = {} + self.libs = {} + + def add(self, pathname, extensions): + self.impure_wheels[pathname] = extensions + self.libs.update(extensions) + + def remove(self, pathname): + extensions = self.impure_wheels.pop(pathname) + for k, v in extensions: + if k in self.libs: + del self.libs[k] + + def find_module(self, fullname, path=None): + if fullname in self.libs: + result = self + else: + result = None + return result + + def load_module(self, fullname): + if fullname in sys.modules: + result = sys.modules[fullname] + else: + if fullname not in self.libs: + raise ImportError('unable to find extension for %s' % fullname) + result = imp.load_dynamic(fullname, self.libs[fullname]) + result.__loader__ = self + parts = fullname.rsplit('.', 1) + if len(parts) > 1: + result.__package__ = parts[0] + return result + +_hook = Mounter() + + +class Wheel(object): + """ + Class to build and install from Wheel files (PEP 427). + """ + + wheel_version = (1, 1) + hash_kind = 'sha256' + + def __init__(self, filename=None, sign=False, verify=False): + """ + Initialise an instance using a (valid) filename. + """ + self.sign = sign + self.should_verify = verify + self.buildver = '' + self.pyver = [PYVER] + self.abi = ['none'] + self.arch = ['any'] + self.dirname = os.getcwd() + if filename is None: + self.name = 'dummy' + self.version = '0.1' + self._filename = self.filename + else: + m = NAME_VERSION_RE.match(filename) + if m: + info = m.groupdict('') + self.name = info['nm'] + # Reinstate the local version separator + self.version = info['vn'].replace('_', '-') + self.buildver = info['bn'] + self._filename = self.filename + else: + dirname, filename = os.path.split(filename) + m = FILENAME_RE.match(filename) + if not m: + raise DistlibException('Invalid name or ' + 'filename: %r' % filename) + if dirname: + self.dirname = os.path.abspath(dirname) + self._filename = filename + info = m.groupdict('') + self.name = info['nm'] + self.version = info['vn'] + self.buildver = info['bn'] + self.pyver = info['py'].split('.') + self.abi = info['bi'].split('.') + self.arch = info['ar'].split('.') + + @property + def filename(self): + """ + Build and return a filename from the various components. + """ + if self.buildver: + buildver = '-' + self.buildver + else: + buildver = '' + pyver = '.'.join(self.pyver) + abi = '.'.join(self.abi) + arch = '.'.join(self.arch) + # replace - with _ as a local version separator + version = self.version.replace('-', '_') + return '%s-%s%s-%s-%s-%s.whl' % (self.name, version, buildver, + pyver, abi, arch) + + @property + def exists(self): + path = os.path.join(self.dirname, self.filename) + return os.path.isfile(path) + + @property + def tags(self): + for pyver in self.pyver: + for abi in self.abi: + for arch in self.arch: + yield pyver, abi, arch + + @cached_property + def metadata(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + wrapper = codecs.getreader('utf-8') + with ZipFile(pathname, 'r') as zf: + wheel_metadata = self.get_wheel_metadata(zf) + wv = wheel_metadata['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + if file_version < (1, 1): + fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME, 'METADATA'] + else: + fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME] + result = None + for fn in fns: + try: + metadata_filename = posixpath.join(info_dir, fn) + with zf.open(metadata_filename) as bf: + wf = wrapper(bf) + result = Metadata(fileobj=wf) + if result: + break + except KeyError: + pass + if not result: + raise ValueError('Invalid wheel, because metadata is ' + 'missing: looked in %s' % ', '.join(fns)) + return result + + def get_wheel_metadata(self, zf): + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + metadata_filename = posixpath.join(info_dir, 'WHEEL') + with zf.open(metadata_filename) as bf: + wf = codecs.getreader('utf-8')(bf) + message = message_from_file(wf) + return dict(message) + + @cached_property + def info(self): + pathname = os.path.join(self.dirname, self.filename) + with ZipFile(pathname, 'r') as zf: + result = self.get_wheel_metadata(zf) + return result + + def process_shebang(self, data): + m = SHEBANG_RE.match(data) + if m: + end = m.end() + shebang, data_after_shebang = data[:end], data[end:] + # Preserve any arguments after the interpreter + if b'pythonw' in shebang.lower(): + shebang_python = SHEBANG_PYTHONW + else: + shebang_python = SHEBANG_PYTHON + m = SHEBANG_DETAIL_RE.match(shebang) + if m: + args = b' ' + m.groups()[-1] + else: + args = b'' + shebang = shebang_python + args + data = shebang + data_after_shebang + else: + cr = data.find(b'\r') + lf = data.find(b'\n') + if cr < 0 or cr > lf: + term = b'\n' + else: + if data[cr:cr + 2] == b'\r\n': + term = b'\r\n' + else: + term = b'\r' + data = SHEBANG_PYTHON + term + data + return data + + def get_hash(self, data, hash_kind=None): + if hash_kind is None: + hash_kind = self.hash_kind + try: + hasher = getattr(hashlib, hash_kind) + except AttributeError: + raise DistlibException('Unsupported hash algorithm: %r' % hash_kind) + result = hasher(data).digest() + result = base64.urlsafe_b64encode(result).rstrip(b'=').decode('ascii') + return hash_kind, result + + def write_record(self, records, record_path, base): + records = list(records) # make a copy for sorting + p = to_posix(os.path.relpath(record_path, base)) + records.append((p, '', '')) + records.sort() + with CSVWriter(record_path) as writer: + for row in records: + writer.writerow(row) + + def write_records(self, info, libdir, archive_paths): + records = [] + distinfo, info_dir = info + hasher = getattr(hashlib, self.hash_kind) + for ap, p in archive_paths: + with open(p, 'rb') as f: + data = f.read() + digest = '%s=%s' % self.get_hash(data) + size = os.path.getsize(p) + records.append((ap, digest, size)) + + p = os.path.join(distinfo, 'RECORD') + self.write_record(records, p, libdir) + ap = to_posix(os.path.join(info_dir, 'RECORD')) + archive_paths.append((ap, p)) + + def build_zip(self, pathname, archive_paths): + with ZipFile(pathname, 'w', zipfile.ZIP_DEFLATED) as zf: + for ap, p in archive_paths: + logger.debug('Wrote %s to %s in wheel', p, ap) + zf.write(p, ap) + + def build(self, paths, tags=None, wheel_version=None): + """ + Build a wheel from files in specified paths, and use any specified tags + when determining the name of the wheel. + """ + if tags is None: + tags = {} + + libkey = list(filter(lambda o: o in paths, ('purelib', 'platlib')))[0] + if libkey == 'platlib': + is_pure = 'false' + default_pyver = [IMPVER] + default_abi = [ABI] + default_arch = [ARCH] + else: + is_pure = 'true' + default_pyver = [PYVER] + default_abi = ['none'] + default_arch = ['any'] + + self.pyver = tags.get('pyver', default_pyver) + self.abi = tags.get('abi', default_abi) + self.arch = tags.get('arch', default_arch) + + libdir = paths[libkey] + + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + archive_paths = [] + + # First, stuff which is not in site-packages + for key in ('data', 'headers', 'scripts'): + if key not in paths: + continue + path = paths[key] + if os.path.isdir(path): + for root, dirs, files in os.walk(path): + for fn in files: + p = fsdecode(os.path.join(root, fn)) + rp = os.path.relpath(p, path) + ap = to_posix(os.path.join(data_dir, key, rp)) + archive_paths.append((ap, p)) + if key == 'scripts' and not p.endswith('.exe'): + with open(p, 'rb') as f: + data = f.read() + data = self.process_shebang(data) + with open(p, 'wb') as f: + f.write(data) + + # Now, stuff which is in site-packages, other than the + # distinfo stuff. + path = libdir + distinfo = None + for root, dirs, files in os.walk(path): + if root == path: + # At the top level only, save distinfo for later + # and skip it for now + for i, dn in enumerate(dirs): + dn = fsdecode(dn) + if dn.endswith('.dist-info'): + distinfo = os.path.join(root, dn) + del dirs[i] + break + assert distinfo, '.dist-info directory expected, not found' + + for fn in files: + # comment out next suite to leave .pyc files in + if fsdecode(fn).endswith(('.pyc', '.pyo')): + continue + p = os.path.join(root, fn) + rp = to_posix(os.path.relpath(p, path)) + archive_paths.append((rp, p)) + + # Now distinfo. Assumed to be flat, i.e. os.listdir is enough. + files = os.listdir(distinfo) + for fn in files: + if fn not in ('RECORD', 'INSTALLER', 'SHARED', 'WHEEL'): + p = fsdecode(os.path.join(distinfo, fn)) + ap = to_posix(os.path.join(info_dir, fn)) + archive_paths.append((ap, p)) + + wheel_metadata = [ + 'Wheel-Version: %d.%d' % (wheel_version or self.wheel_version), + 'Generator: distlib %s' % __version__, + 'Root-Is-Purelib: %s' % is_pure, + ] + for pyver, abi, arch in self.tags: + wheel_metadata.append('Tag: %s-%s-%s' % (pyver, abi, arch)) + p = os.path.join(distinfo, 'WHEEL') + with open(p, 'w') as f: + f.write('\n'.join(wheel_metadata)) + ap = to_posix(os.path.join(info_dir, 'WHEEL')) + archive_paths.append((ap, p)) + + # Now, at last, RECORD. + # Paths in here are archive paths - nothing else makes sense. + self.write_records((distinfo, info_dir), libdir, archive_paths) + # Now, ready to build the zip file + pathname = os.path.join(self.dirname, self.filename) + self.build_zip(pathname, archive_paths) + return pathname + + def install(self, paths, maker, **kwargs): + """ + Install a wheel to the specified paths. If kwarg ``warner`` is + specified, it should be a callable, which will be called with two + tuples indicating the wheel version of this software and the wheel + version in the file, if there is a discrepancy in the versions. + This can be used to issue any warnings to raise any exceptions. + If kwarg ``lib_only`` is True, only the purelib/platlib files are + installed, and the headers, scripts, data and dist-info metadata are + not written. + + The return value is a :class:`InstalledDistribution` instance unless + ``options.lib_only`` is True, in which case the return value is ``None``. + """ + + dry_run = maker.dry_run + warner = kwargs.get('warner') + lib_only = kwargs.get('lib_only', False) + + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + metadata_name = posixpath.join(info_dir, METADATA_FILENAME) + wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') + record_name = posixpath.join(info_dir, 'RECORD') + + wrapper = codecs.getreader('utf-8') + + with ZipFile(pathname, 'r') as zf: + with zf.open(wheel_metadata_name) as bwf: + wf = wrapper(bwf) + message = message_from_file(wf) + wv = message['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + if (file_version != self.wheel_version) and warner: + warner(self.wheel_version, file_version) + + if message['Root-Is-Purelib'] == 'true': + libdir = paths['purelib'] + else: + libdir = paths['platlib'] + + records = {} + with zf.open(record_name) as bf: + with CSVReader(stream=bf) as reader: + for row in reader: + p = row[0] + records[p] = row + + data_pfx = posixpath.join(data_dir, '') + info_pfx = posixpath.join(info_dir, '') + script_pfx = posixpath.join(data_dir, 'scripts', '') + + # make a new instance rather than a copy of maker's, + # as we mutate it + fileop = FileOperator(dry_run=dry_run) + fileop.record = True # so we can rollback if needed + + bc = not sys.dont_write_bytecode # Double negatives. Lovely! + + outfiles = [] # for RECORD writing + + # for script copying/shebang processing + workdir = tempfile.mkdtemp() + # set target dir later + # we default add_launchers to False, as the + # Python Launcher should be used instead + maker.source_dir = workdir + maker.target_dir = None + try: + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + # The signature file won't be in RECORD, + # and we don't currently don't do anything with it + if u_arcname.endswith('/RECORD.jws'): + continue + row = records[u_arcname] + if row[2] and str(zinfo.file_size) != row[2]: + raise DistlibException('size mismatch for ' + '%s' % u_arcname) + if row[1]: + kind, value = row[1].split('=', 1) + with zf.open(arcname) as bf: + data = bf.read() + _, digest = self.get_hash(data, kind) + if digest != value: + raise DistlibException('digest mismatch for ' + '%s' % arcname) + + if lib_only and u_arcname.startswith((info_pfx, data_pfx)): + logger.debug('lib_only: skipping %s', u_arcname) + continue + is_script = (u_arcname.startswith(script_pfx) + and not u_arcname.endswith('.exe')) + + if u_arcname.startswith(data_pfx): + _, where, rp = u_arcname.split('/', 2) + outfile = os.path.join(paths[where], convert_path(rp)) + else: + # meant for site-packages. + if u_arcname in (wheel_metadata_name, record_name): + continue + outfile = os.path.join(libdir, convert_path(u_arcname)) + if not is_script: + with zf.open(arcname) as bf: + fileop.copy_stream(bf, outfile) + outfiles.append(outfile) + # Double check the digest of the written file + if not dry_run and row[1]: + with open(outfile, 'rb') as bf: + data = bf.read() + _, newdigest = self.get_hash(data, kind) + if newdigest != digest: + raise DistlibException('digest mismatch ' + 'on write for ' + '%s' % outfile) + if bc and outfile.endswith('.py'): + try: + pyc = fileop.byte_compile(outfile) + outfiles.append(pyc) + except Exception: + # Don't give up if byte-compilation fails, + # but log it and perhaps warn the user + logger.warning('Byte-compilation failed', + exc_info=True) + else: + fn = os.path.basename(convert_path(arcname)) + workname = os.path.join(workdir, fn) + with zf.open(arcname) as bf: + fileop.copy_stream(bf, workname) + + dn, fn = os.path.split(outfile) + maker.target_dir = dn + filenames = maker.make(fn) + fileop.set_executable_mode(filenames) + outfiles.extend(filenames) + + if lib_only: + logger.debug('lib_only: returning None') + dist = None + else: + # Generate scripts + + # Try to get pydist.json so we can see if there are + # any commands to generate. If this fails (e.g. because + # of a legacy wheel), log a warning but don't give up. + commands = None + file_version = self.info['Wheel-Version'] + if file_version == '1.0': + # Use legacy info + ep = posixpath.join(info_dir, 'entry_points.txt') + try: + with zf.open(ep) as bwf: + epdata = read_exports(bwf) + commands = {} + for key in ('console', 'gui'): + k = '%s_scripts' % key + if k in epdata: + commands['wrap_%s' % key] = d = {} + for v in epdata[k].values(): + s = '%s:%s' % (v.prefix, v.suffix) + if v.flags: + s += ' %s' % v.flags + d[v.name] = s + except Exception: + logger.warning('Unable to read legacy script ' + 'metadata, so cannot generate ' + 'scripts') + else: + try: + with zf.open(metadata_name) as bwf: + wf = wrapper(bwf) + commands = json.load(wf).get('extensions') + if commands: + commands = commands.get('python.commands') + except Exception: + logger.warning('Unable to read JSON metadata, so ' + 'cannot generate scripts') + if commands: + console_scripts = commands.get('wrap_console', {}) + gui_scripts = commands.get('wrap_gui', {}) + if console_scripts or gui_scripts: + script_dir = paths.get('scripts', '') + if not os.path.isdir(script_dir): + raise ValueError('Valid script path not ' + 'specified') + maker.target_dir = script_dir + for k, v in console_scripts.items(): + script = '%s = %s' % (k, v) + filenames = maker.make(script) + fileop.set_executable_mode(filenames) + + if gui_scripts: + options = {'gui': True } + for k, v in gui_scripts.items(): + script = '%s = %s' % (k, v) + filenames = maker.make(script, options) + fileop.set_executable_mode(filenames) + + p = os.path.join(libdir, info_dir) + dist = InstalledDistribution(p) + + # Write SHARED + paths = dict(paths) # don't change passed in dict + del paths['purelib'] + del paths['platlib'] + paths['lib'] = libdir + p = dist.write_shared_locations(paths, dry_run) + if p: + outfiles.append(p) + + # Write RECORD + dist.write_installed_files(outfiles, paths['prefix'], + dry_run) + return dist + except Exception: # pragma: no cover + logger.exception('installation failed.') + fileop.rollback() + raise + finally: + shutil.rmtree(workdir) + + def _get_dylib_cache(self): + global cache + if cache is None: + # Use native string to avoid issues on 2.x: see Python #20140. + base = os.path.join(get_cache_base(), str('dylib-cache'), + sys.version[:3]) + cache = Cache(base) + return cache + + def _get_extensions(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + arcname = posixpath.join(info_dir, 'EXTENSIONS') + wrapper = codecs.getreader('utf-8') + result = [] + with ZipFile(pathname, 'r') as zf: + try: + with zf.open(arcname) as bf: + wf = wrapper(bf) + extensions = json.load(wf) + cache = self._get_dylib_cache() + prefix = cache.prefix_to_dir(pathname) + cache_base = os.path.join(cache.base, prefix) + if not os.path.isdir(cache_base): + os.makedirs(cache_base) + for name, relpath in extensions.items(): + dest = os.path.join(cache_base, convert_path(relpath)) + if not os.path.exists(dest): + extract = True + else: + file_time = os.stat(dest).st_mtime + file_time = datetime.datetime.fromtimestamp(file_time) + info = zf.getinfo(relpath) + wheel_time = datetime.datetime(*info.date_time) + extract = wheel_time > file_time + if extract: + zf.extract(relpath, cache_base) + result.append((name, dest)) + except KeyError: + pass + return result + + def is_compatible(self): + """ + Determine if a wheel is compatible with the running system. + """ + return is_compatible(self) + + def is_mountable(self): + """ + Determine if a wheel is asserted as mountable by its metadata. + """ + return True # for now - metadata details TBD + + def mount(self, append=False): + pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) + if not self.is_compatible(): + msg = 'Wheel %s not compatible with this Python.' % pathname + raise DistlibException(msg) + if not self.is_mountable(): + msg = 'Wheel %s is marked as not mountable.' % pathname + raise DistlibException(msg) + if pathname in sys.path: + logger.debug('%s already in path', pathname) + else: + if append: + sys.path.append(pathname) + else: + sys.path.insert(0, pathname) + extensions = self._get_extensions() + if extensions: + if _hook not in sys.meta_path: + sys.meta_path.append(_hook) + _hook.add(pathname, extensions) + + def unmount(self): + pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) + if pathname not in sys.path: + logger.debug('%s not in path', pathname) + else: + sys.path.remove(pathname) + if pathname in _hook.impure_wheels: + _hook.remove(pathname) + if not _hook.impure_wheels: + if _hook in sys.meta_path: + sys.meta_path.remove(_hook) + + def verify(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + metadata_name = posixpath.join(info_dir, METADATA_FILENAME) + wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') + record_name = posixpath.join(info_dir, 'RECORD') + + wrapper = codecs.getreader('utf-8') + + with ZipFile(pathname, 'r') as zf: + with zf.open(wheel_metadata_name) as bwf: + wf = wrapper(bwf) + message = message_from_file(wf) + wv = message['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + # TODO version verification + + records = {} + with zf.open(record_name) as bf: + with CSVReader(stream=bf) as reader: + for row in reader: + p = row[0] + records[p] = row + + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + if '..' in u_arcname: + raise DistlibException('invalid entry in ' + 'wheel: %r' % u_arcname) + + # The signature file won't be in RECORD, + # and we don't currently don't do anything with it + if u_arcname.endswith('/RECORD.jws'): + continue + row = records[u_arcname] + if row[2] and str(zinfo.file_size) != row[2]: + raise DistlibException('size mismatch for ' + '%s' % u_arcname) + if row[1]: + kind, value = row[1].split('=', 1) + with zf.open(arcname) as bf: + data = bf.read() + _, digest = self.get_hash(data, kind) + if digest != value: + raise DistlibException('digest mismatch for ' + '%s' % arcname) + + def update(self, modifier, dest_dir=None, **kwargs): + """ + Update the contents of a wheel in a generic way. The modifier should + be a callable which expects a dictionary argument: its keys are + archive-entry paths, and its values are absolute filesystem paths + where the contents the corresponding archive entries can be found. The + modifier is free to change the contents of the files pointed to, add + new entries and remove entries, before returning. This method will + extract the entire contents of the wheel to a temporary location, call + the modifier, and then use the passed (and possibly updated) + dictionary to write a new wheel. If ``dest_dir`` is specified, the new + wheel is written there -- otherwise, the original wheel is overwritten. + + The modifier should return True if it updated the wheel, else False. + This method returns the same value the modifier returns. + """ + + def get_version(path_map, info_dir): + version = path = None + key = '%s/%s' % (info_dir, METADATA_FILENAME) + if key not in path_map: + key = '%s/PKG-INFO' % info_dir + if key in path_map: + path = path_map[key] + version = Metadata(path=path).version + return version, path + + def update_version(version, path): + updated = None + try: + v = NormalizedVersion(version) + i = version.find('-') + if i < 0: + updated = '%s+1' % version + else: + parts = [int(s) for s in version[i + 1:].split('.')] + parts[-1] += 1 + updated = '%s+%s' % (version[:i], + '.'.join(str(i) for i in parts)) + except UnsupportedVersionError: + logger.debug('Cannot update non-compliant (PEP-440) ' + 'version %r', version) + if updated: + md = Metadata(path=path) + md.version = updated + legacy = not path.endswith(METADATA_FILENAME) + md.write(path=path, legacy=legacy) + logger.debug('Version updated from %r to %r', version, + updated) + + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + record_name = posixpath.join(info_dir, 'RECORD') + with tempdir() as workdir: + with ZipFile(pathname, 'r') as zf: + path_map = {} + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + if u_arcname == record_name: + continue + if '..' in u_arcname: + raise DistlibException('invalid entry in ' + 'wheel: %r' % u_arcname) + zf.extract(zinfo, workdir) + path = os.path.join(workdir, convert_path(u_arcname)) + path_map[u_arcname] = path + + # Remember the version. + original_version, _ = get_version(path_map, info_dir) + # Files extracted. Call the modifier. + modified = modifier(path_map, **kwargs) + if modified: + # Something changed - need to build a new wheel. + current_version, path = get_version(path_map, info_dir) + if current_version and (current_version == original_version): + # Add or update local version to signify changes. + update_version(current_version, path) + # Decide where the new wheel goes. + if dest_dir is None: + fd, newpath = tempfile.mkstemp(suffix='.whl', + prefix='wheel-update-', + dir=workdir) + os.close(fd) + else: + if not os.path.isdir(dest_dir): + raise DistlibException('Not a directory: %r' % dest_dir) + newpath = os.path.join(dest_dir, self.filename) + archive_paths = list(path_map.items()) + distinfo = os.path.join(workdir, info_dir) + info = distinfo, info_dir + self.write_records(info, workdir, archive_paths) + self.build_zip(newpath, archive_paths) + if dest_dir is None: + shutil.copyfile(newpath, pathname) + return modified + +def compatible_tags(): + """ + Return (pyver, abi, arch) tuples compatible with this Python. + """ + versions = [VER_SUFFIX] + major = VER_SUFFIX[0] + for minor in range(sys.version_info[1] - 1, - 1, -1): + versions.append(''.join([major, str(minor)])) + + abis = [] + for suffix, _, _ in imp.get_suffixes(): + if suffix.startswith('.abi'): + abis.append(suffix.split('.', 2)[1]) + abis.sort() + if ABI != 'none': + abis.insert(0, ABI) + abis.append('none') + result = [] + + arches = [ARCH] + if sys.platform == 'darwin': + m = re.match(r'(\w+)_(\d+)_(\d+)_(\w+)$', ARCH) + if m: + name, major, minor, arch = m.groups() + minor = int(minor) + matches = [arch] + if arch in ('i386', 'ppc'): + matches.append('fat') + if arch in ('i386', 'ppc', 'x86_64'): + matches.append('fat3') + if arch in ('ppc64', 'x86_64'): + matches.append('fat64') + if arch in ('i386', 'x86_64'): + matches.append('intel') + if arch in ('i386', 'x86_64', 'intel', 'ppc', 'ppc64'): + matches.append('universal') + while minor >= 0: + for match in matches: + s = '%s_%s_%s_%s' % (name, major, minor, match) + if s != ARCH: # already there + arches.append(s) + minor -= 1 + + # Most specific - our Python version, ABI and arch + for abi in abis: + for arch in arches: + result.append((''.join((IMP_PREFIX, versions[0])), abi, arch)) + + # where no ABI / arch dependency, but IMP_PREFIX dependency + for i, version in enumerate(versions): + result.append((''.join((IMP_PREFIX, version)), 'none', 'any')) + if i == 0: + result.append((''.join((IMP_PREFIX, version[0])), 'none', 'any')) + + # no IMP_PREFIX, ABI or arch dependency + for i, version in enumerate(versions): + result.append((''.join(('py', version)), 'none', 'any')) + if i == 0: + result.append((''.join(('py', version[0])), 'none', 'any')) + return set(result) + + +COMPATIBLE_TAGS = compatible_tags() + +del compatible_tags + + +def is_compatible(wheel, tags=None): + if not isinstance(wheel, Wheel): + wheel = Wheel(wheel) # assume it's a filename + result = False + if tags is None: + tags = COMPATIBLE_TAGS + for ver, abi, arch in tags: + if ver in wheel.pyver and abi in wheel.abi and arch in wheel.arch: + result = True + break + return result diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distro.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distro.py new file mode 100644 index 0000000..39bfce7 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distro.py @@ -0,0 +1,1104 @@ +# Copyright 2015,2016 Nir Cohen +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +The ``distro`` package (``distro`` stands for Linux Distribution) provides +information about the Linux distribution it runs on, such as a reliable +machine-readable distro ID, or version information. + +It is a renewed alternative implementation for Python's original +:py:func:`platform.linux_distribution` function, but it provides much more +functionality. An alternative implementation became necessary because Python +3.5 deprecated this function, and Python 3.7 is expected to remove it +altogether. Its predecessor function :py:func:`platform.dist` was already +deprecated since Python 2.6 and is also expected to be removed in Python 3.7. +Still, there are many cases in which access to Linux distribution information +is needed. See `Python issue 1322 <https://bugs.python.org/issue1322>`_ for +more information. +""" + +import os +import re +import sys +import json +import shlex +import logging +import argparse +import subprocess + + +_UNIXCONFDIR = os.environ.get('UNIXCONFDIR', '/etc') +_OS_RELEASE_BASENAME = 'os-release' + +#: Translation table for normalizing the "ID" attribute defined in os-release +#: files, for use by the :func:`distro.id` method. +#: +#: * Key: Value as defined in the os-release file, translated to lower case, +#: with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_OS_ID = {} + +#: Translation table for normalizing the "Distributor ID" attribute returned by +#: the lsb_release command, for use by the :func:`distro.id` method. +#: +#: * Key: Value as returned by the lsb_release command, translated to lower +#: case, with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_LSB_ID = { + 'enterpriseenterprise': 'oracle', # Oracle Enterprise Linux + 'redhatenterpriseworkstation': 'rhel', # RHEL 6, 7 Workstation + 'redhatenterpriseserver': 'rhel', # RHEL 6, 7 Server +} + +#: Translation table for normalizing the distro ID derived from the file name +#: of distro release files, for use by the :func:`distro.id` method. +#: +#: * Key: Value as derived from the file name of a distro release file, +#: translated to lower case, with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_DISTRO_ID = { + 'redhat': 'rhel', # RHEL 6.x, 7.x +} + +# Pattern for content of distro release file (reversed) +_DISTRO_RELEASE_CONTENT_REVERSED_PATTERN = re.compile( + r'(?:[^)]*\)(.*)\()? *(?:STL )?([\d.+\-a-z]*\d) *(?:esaeler *)?(.+)') + +# Pattern for base file name of distro release file +_DISTRO_RELEASE_BASENAME_PATTERN = re.compile( + r'(\w+)[-_](release|version)$') + +# Base file names to be ignored when searching for distro release file +_DISTRO_RELEASE_IGNORE_BASENAMES = ( + 'debian_version', + 'lsb-release', + 'oem-release', + _OS_RELEASE_BASENAME, + 'system-release' +) + + +def linux_distribution(full_distribution_name=True): + """ + Return information about the current Linux distribution as a tuple + ``(id_name, version, codename)`` with items as follows: + + * ``id_name``: If *full_distribution_name* is false, the result of + :func:`distro.id`. Otherwise, the result of :func:`distro.name`. + + * ``version``: The result of :func:`distro.version`. + + * ``codename``: The result of :func:`distro.codename`. + + The interface of this function is compatible with the original + :py:func:`platform.linux_distribution` function, supporting a subset of + its parameters. + + The data it returns may not exactly be the same, because it uses more data + sources than the original function, and that may lead to different data if + the Linux distribution is not consistent across multiple data sources it + provides (there are indeed such distributions ...). + + Another reason for differences is the fact that the :func:`distro.id` + method normalizes the distro ID string to a reliable machine-readable value + for a number of popular Linux distributions. + """ + return _distro.linux_distribution(full_distribution_name) + + +def id(): + """ + Return the distro ID of the current Linux distribution, as a + machine-readable string. + + For a number of Linux distributions, the returned distro ID value is + *reliable*, in the sense that it is documented and that it does not change + across releases of the distribution. + + This package maintains the following reliable distro ID values: + + ============== ========================================= + Distro ID Distribution + ============== ========================================= + "ubuntu" Ubuntu + "debian" Debian + "rhel" RedHat Enterprise Linux + "centos" CentOS + "fedora" Fedora + "sles" SUSE Linux Enterprise Server + "opensuse" openSUSE + "amazon" Amazon Linux + "arch" Arch Linux + "cloudlinux" CloudLinux OS + "exherbo" Exherbo Linux + "gentoo" GenToo Linux + "ibm_powerkvm" IBM PowerKVM + "kvmibm" KVM for IBM z Systems + "linuxmint" Linux Mint + "mageia" Mageia + "mandriva" Mandriva Linux + "parallels" Parallels + "pidora" Pidora + "raspbian" Raspbian + "oracle" Oracle Linux (and Oracle Enterprise Linux) + "scientific" Scientific Linux + "slackware" Slackware + "xenserver" XenServer + ============== ========================================= + + If you have a need to get distros for reliable IDs added into this set, + or if you find that the :func:`distro.id` function returns a different + distro ID for one of the listed distros, please create an issue in the + `distro issue tracker`_. + + **Lookup hierarchy and transformations:** + + First, the ID is obtained from the following sources, in the specified + order. The first available and non-empty value is used: + + * the value of the "ID" attribute of the os-release file, + + * the value of the "Distributor ID" attribute returned by the lsb_release + command, + + * the first part of the file name of the distro release file, + + The so determined ID value then passes the following transformations, + before it is returned by this method: + + * it is translated to lower case, + + * blanks (which should not be there anyway) are translated to underscores, + + * a normalization of the ID is performed, based upon + `normalization tables`_. The purpose of this normalization is to ensure + that the ID is as reliable as possible, even across incompatible changes + in the Linux distributions. A common reason for an incompatible change is + the addition of an os-release file, or the addition of the lsb_release + command, with ID values that differ from what was previously determined + from the distro release file name. + """ + return _distro.id() + + +def name(pretty=False): + """ + Return the name of the current Linux distribution, as a human-readable + string. + + If *pretty* is false, the name is returned without version or codename. + (e.g. "CentOS Linux") + + If *pretty* is true, the version and codename are appended. + (e.g. "CentOS Linux 7.1.1503 (Core)") + + **Lookup hierarchy:** + + The name is obtained from the following sources, in the specified order. + The first available and non-empty value is used: + + * If *pretty* is false: + + - the value of the "NAME" attribute of the os-release file, + + - the value of the "Distributor ID" attribute returned by the lsb_release + command, + + - the value of the "<name>" field of the distro release file. + + * If *pretty* is true: + + - the value of the "PRETTY_NAME" attribute of the os-release file, + + - the value of the "Description" attribute returned by the lsb_release + command, + + - the value of the "<name>" field of the distro release file, appended + with the value of the pretty version ("<version_id>" and "<codename>" + fields) of the distro release file, if available. + """ + return _distro.name(pretty) + + +def version(pretty=False, best=False): + """ + Return the version of the current Linux distribution, as a human-readable + string. + + If *pretty* is false, the version is returned without codename (e.g. + "7.0"). + + If *pretty* is true, the codename in parenthesis is appended, if the + codename is non-empty (e.g. "7.0 (Maipo)"). + + Some distributions provide version numbers with different precisions in + the different sources of distribution information. Examining the different + sources in a fixed priority order does not always yield the most precise + version (e.g. for Debian 8.2, or CentOS 7.1). + + The *best* parameter can be used to control the approach for the returned + version: + + If *best* is false, the first non-empty version number in priority order of + the examined sources is returned. + + If *best* is true, the most precise version number out of all examined + sources is returned. + + **Lookup hierarchy:** + + In all cases, the version number is obtained from the following sources. + If *best* is false, this order represents the priority order: + + * the value of the "VERSION_ID" attribute of the os-release file, + * the value of the "Release" attribute returned by the lsb_release + command, + * the version number parsed from the "<version_id>" field of the first line + of the distro release file, + * the version number parsed from the "PRETTY_NAME" attribute of the + os-release file, if it follows the format of the distro release files. + * the version number parsed from the "Description" attribute returned by + the lsb_release command, if it follows the format of the distro release + files. + """ + return _distro.version(pretty, best) + + +def version_parts(best=False): + """ + Return the version of the current Linux distribution as a tuple + ``(major, minor, build_number)`` with items as follows: + + * ``major``: The result of :func:`distro.major_version`. + + * ``minor``: The result of :func:`distro.minor_version`. + + * ``build_number``: The result of :func:`distro.build_number`. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.version_parts(best) + + +def major_version(best=False): + """ + Return the major version of the current Linux distribution, as a string, + if provided. + Otherwise, the empty string is returned. The major version is the first + part of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.major_version(best) + + +def minor_version(best=False): + """ + Return the minor version of the current Linux distribution, as a string, + if provided. + Otherwise, the empty string is returned. The minor version is the second + part of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.minor_version(best) + + +def build_number(best=False): + """ + Return the build number of the current Linux distribution, as a string, + if provided. + Otherwise, the empty string is returned. The build number is the third part + of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.build_number(best) + + +def like(): + """ + Return a space-separated list of distro IDs of distributions that are + closely related to the current Linux distribution in regards to packaging + and programming interfaces, for example distributions the current + distribution is a derivative from. + + **Lookup hierarchy:** + + This information item is only provided by the os-release file. + For details, see the description of the "ID_LIKE" attribute in the + `os-release man page + <http://www.freedesktop.org/software/systemd/man/os-release.html>`_. + """ + return _distro.like() + + +def codename(): + """ + Return the codename for the release of the current Linux distribution, + as a string. + + If the distribution does not have a codename, an empty string is returned. + + Note that the returned codename is not always really a codename. For + example, openSUSE returns "x86_64". This function does not handle such + cases in any special way and just returns the string it finds, if any. + + **Lookup hierarchy:** + + * the codename within the "VERSION" attribute of the os-release file, if + provided, + + * the value of the "Codename" attribute returned by the lsb_release + command, + + * the value of the "<codename>" field of the distro release file. + """ + return _distro.codename() + + +def info(pretty=False, best=False): + """ + Return certain machine-readable information items about the current Linux + distribution in a dictionary, as shown in the following example: + + .. sourcecode:: python + + { + 'id': 'rhel', + 'version': '7.0', + 'version_parts': { + 'major': '7', + 'minor': '0', + 'build_number': '' + }, + 'like': 'fedora', + 'codename': 'Maipo' + } + + The dictionary structure and keys are always the same, regardless of which + information items are available in the underlying data sources. The values + for the various keys are as follows: + + * ``id``: The result of :func:`distro.id`. + + * ``version``: The result of :func:`distro.version`. + + * ``version_parts -> major``: The result of :func:`distro.major_version`. + + * ``version_parts -> minor``: The result of :func:`distro.minor_version`. + + * ``version_parts -> build_number``: The result of + :func:`distro.build_number`. + + * ``like``: The result of :func:`distro.like`. + + * ``codename``: The result of :func:`distro.codename`. + + For a description of the *pretty* and *best* parameters, see the + :func:`distro.version` method. + """ + return _distro.info(pretty, best) + + +def os_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the os-release file data source of the current Linux distribution. + + See `os-release file`_ for details about these information items. + """ + return _distro.os_release_info() + + +def lsb_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the lsb_release command data source of the current Linux distribution. + + See `lsb_release command output`_ for details about these information + items. + """ + return _distro.lsb_release_info() + + +def distro_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the distro release file data source of the current Linux distribution. + + See `distro release file`_ for details about these information items. + """ + return _distro.distro_release_info() + + +def os_release_attr(attribute): + """ + Return a single named information item from the os-release file data source + of the current Linux distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `os-release file`_ for details about these information items. + """ + return _distro.os_release_attr(attribute) + + +def lsb_release_attr(attribute): + """ + Return a single named information item from the lsb_release command output + data source of the current Linux distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `lsb_release command output`_ for details about these information + items. + """ + return _distro.lsb_release_attr(attribute) + + +def distro_release_attr(attribute): + """ + Return a single named information item from the distro release file + data source of the current Linux distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `distro release file`_ for details about these information items. + """ + return _distro.distro_release_attr(attribute) + + +class cached_property(object): + """A version of @property which caches the value. On access, it calls the + underlying function and sets the value in `__dict__` so future accesses + will not re-call the property. + """ + def __init__(self, f): + self._fname = f.__name__ + self._f = f + + def __get__(self, obj, owner): + assert obj is not None, 'call {} on an instance'.format(self._fname) + ret = obj.__dict__[self._fname] = self._f(obj) + return ret + + +class LinuxDistribution(object): + """ + Provides information about a Linux distribution. + + This package creates a private module-global instance of this class with + default initialization arguments, that is used by the + `consolidated accessor functions`_ and `single source accessor functions`_. + By using default initialization arguments, that module-global instance + returns data about the current Linux distribution (i.e. the distro this + package runs on). + + Normally, it is not necessary to create additional instances of this class. + However, in situations where control is needed over the exact data sources + that are used, instances of this class can be created with a specific + distro release file, or a specific os-release file, or without invoking the + lsb_release command. + """ + + def __init__(self, + include_lsb=True, + os_release_file='', + distro_release_file=''): + """ + The initialization method of this class gathers information from the + available data sources, and stores that in private instance attributes. + Subsequent access to the information items uses these private instance + attributes, so that the data sources are read only once. + + Parameters: + + * ``include_lsb`` (bool): Controls whether the + `lsb_release command output`_ is included as a data source. + + If the lsb_release command is not available in the program execution + path, the data source for the lsb_release command will be empty. + + * ``os_release_file`` (string): The path name of the + `os-release file`_ that is to be used as a data source. + + An empty string (the default) will cause the default path name to + be used (see `os-release file`_ for details). + + If the specified or defaulted os-release file does not exist, the + data source for the os-release file will be empty. + + * ``distro_release_file`` (string): The path name of the + `distro release file`_ that is to be used as a data source. + + An empty string (the default) will cause a default search algorithm + to be used (see `distro release file`_ for details). + + If the specified distro release file does not exist, or if no default + distro release file can be found, the data source for the distro + release file will be empty. + + Public instance attributes: + + * ``os_release_file`` (string): The path name of the + `os-release file`_ that is actually used as a data source. The + empty string if no distro release file is used as a data source. + + * ``distro_release_file`` (string): The path name of the + `distro release file`_ that is actually used as a data source. The + empty string if no distro release file is used as a data source. + + * ``include_lsb`` (bool): The result of the ``include_lsb`` parameter. + This controls whether the lsb information will be loaded. + + Raises: + + * :py:exc:`IOError`: Some I/O issue with an os-release file or distro + release file. + + * :py:exc:`subprocess.CalledProcessError`: The lsb_release command had + some issue (other than not being available in the program execution + path). + + * :py:exc:`UnicodeError`: A data source has unexpected characters or + uses an unexpected encoding. + """ + self.os_release_file = os_release_file or \ + os.path.join(_UNIXCONFDIR, _OS_RELEASE_BASENAME) + self.distro_release_file = distro_release_file or '' # updated later + self.include_lsb = include_lsb + + def __repr__(self): + """Return repr of all info + """ + return \ + "LinuxDistribution(" \ + "os_release_file={self.os_release_file!r}, " \ + "distro_release_file={self.distro_release_file!r}, " \ + "include_lsb={self.include_lsb!r}, " \ + "_os_release_info={self._os_release_info!r}, " \ + "_lsb_release_info={self._lsb_release_info!r}, " \ + "_distro_release_info={self._distro_release_info!r})".format( + self=self) + + def linux_distribution(self, full_distribution_name=True): + """ + Return information about the Linux distribution that is compatible + with Python's :func:`platform.linux_distribution`, supporting a subset + of its parameters. + + For details, see :func:`distro.linux_distribution`. + """ + return ( + self.name() if full_distribution_name else self.id(), + self.version(), + self.codename() + ) + + def id(self): + """Return the distro ID of the Linux distribution, as a string. + + For details, see :func:`distro.id`. + """ + def normalize(distro_id, table): + distro_id = distro_id.lower().replace(' ', '_') + return table.get(distro_id, distro_id) + + distro_id = self.os_release_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_OS_ID) + + distro_id = self.lsb_release_attr('distributor_id') + if distro_id: + return normalize(distro_id, NORMALIZED_LSB_ID) + + distro_id = self.distro_release_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_DISTRO_ID) + + return '' + + def name(self, pretty=False): + """ + Return the name of the Linux distribution, as a string. + + For details, see :func:`distro.name`. + """ + name = self.os_release_attr('name') \ + or self.lsb_release_attr('distributor_id') \ + or self.distro_release_attr('name') + if pretty: + name = self.os_release_attr('pretty_name') \ + or self.lsb_release_attr('description') + if not name: + name = self.distro_release_attr('name') + version = self.version(pretty=True) + if version: + name = name + ' ' + version + return name or '' + + def version(self, pretty=False, best=False): + """ + Return the version of the Linux distribution, as a string. + + For details, see :func:`distro.version`. + """ + versions = [ + self.os_release_attr('version_id'), + self.lsb_release_attr('release'), + self.distro_release_attr('version_id'), + self._parse_distro_release_content( + self.os_release_attr('pretty_name')).get('version_id', ''), + self._parse_distro_release_content( + self.lsb_release_attr('description')).get('version_id', '') + ] + version = '' + if best: + # This algorithm uses the last version in priority order that has + # the best precision. If the versions are not in conflict, that + # does not matter; otherwise, using the last one instead of the + # first one might be considered a surprise. + for v in versions: + if v.count(".") > version.count(".") or version == '': + version = v + else: + for v in versions: + if v != '': + version = v + break + if pretty and version and self.codename(): + version = u'{0} ({1})'.format(version, self.codename()) + return version + + def version_parts(self, best=False): + """ + Return the version of the Linux distribution, as a tuple of version + numbers. + + For details, see :func:`distro.version_parts`. + """ + version_str = self.version(best=best) + if version_str: + version_regex = re.compile(r'(\d+)\.?(\d+)?\.?(\d+)?') + matches = version_regex.match(version_str) + if matches: + major, minor, build_number = matches.groups() + return major, minor or '', build_number or '' + return '', '', '' + + def major_version(self, best=False): + """ + Return the major version number of the current distribution. + + For details, see :func:`distro.major_version`. + """ + return self.version_parts(best)[0] + + def minor_version(self, best=False): + """ + Return the minor version number of the Linux distribution. + + For details, see :func:`distro.minor_version`. + """ + return self.version_parts(best)[1] + + def build_number(self, best=False): + """ + Return the build number of the Linux distribution. + + For details, see :func:`distro.build_number`. + """ + return self.version_parts(best)[2] + + def like(self): + """ + Return the IDs of distributions that are like the Linux distribution. + + For details, see :func:`distro.like`. + """ + return self.os_release_attr('id_like') or '' + + def codename(self): + """ + Return the codename of the Linux distribution. + + For details, see :func:`distro.codename`. + """ + return self.os_release_attr('codename') \ + or self.lsb_release_attr('codename') \ + or self.distro_release_attr('codename') \ + or '' + + def info(self, pretty=False, best=False): + """ + Return certain machine-readable information about the Linux + distribution. + + For details, see :func:`distro.info`. + """ + return dict( + id=self.id(), + version=self.version(pretty, best), + version_parts=dict( + major=self.major_version(best), + minor=self.minor_version(best), + build_number=self.build_number(best) + ), + like=self.like(), + codename=self.codename(), + ) + + def os_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the os-release file data source of the Linux distribution. + + For details, see :func:`distro.os_release_info`. + """ + return self._os_release_info + + def lsb_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the lsb_release command data source of the Linux + distribution. + + For details, see :func:`distro.lsb_release_info`. + """ + return self._lsb_release_info + + def distro_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the distro release file data source of the Linux + distribution. + + For details, see :func:`distro.distro_release_info`. + """ + return self._distro_release_info + + def os_release_attr(self, attribute): + """ + Return a single named information item from the os-release file data + source of the Linux distribution. + + For details, see :func:`distro.os_release_attr`. + """ + return self._os_release_info.get(attribute, '') + + def lsb_release_attr(self, attribute): + """ + Return a single named information item from the lsb_release command + output data source of the Linux distribution. + + For details, see :func:`distro.lsb_release_attr`. + """ + return self._lsb_release_info.get(attribute, '') + + def distro_release_attr(self, attribute): + """ + Return a single named information item from the distro release file + data source of the Linux distribution. + + For details, see :func:`distro.distro_release_attr`. + """ + return self._distro_release_info.get(attribute, '') + + @cached_property + def _os_release_info(self): + """ + Get the information items from the specified os-release file. + + Returns: + A dictionary containing all information items. + """ + if os.path.isfile(self.os_release_file): + with open(self.os_release_file) as release_file: + return self._parse_os_release_content(release_file) + return {} + + @staticmethod + def _parse_os_release_content(lines): + """ + Parse the lines of an os-release file. + + Parameters: + + * lines: Iterable through the lines in the os-release file. + Each line must be a unicode string or a UTF-8 encoded byte + string. + + Returns: + A dictionary containing all information items. + """ + props = {} + lexer = shlex.shlex(lines, posix=True) + lexer.whitespace_split = True + + # The shlex module defines its `wordchars` variable using literals, + # making it dependent on the encoding of the Python source file. + # In Python 2.6 and 2.7, the shlex source file is encoded in + # 'iso-8859-1', and the `wordchars` variable is defined as a byte + # string. This causes a UnicodeDecodeError to be raised when the + # parsed content is a unicode object. The following fix resolves that + # (... but it should be fixed in shlex...): + if sys.version_info[0] == 2 and isinstance(lexer.wordchars, bytes): + lexer.wordchars = lexer.wordchars.decode('iso-8859-1') + + tokens = list(lexer) + for token in tokens: + # At this point, all shell-like parsing has been done (i.e. + # comments processed, quotes and backslash escape sequences + # processed, multi-line values assembled, trailing newlines + # stripped, etc.), so the tokens are now either: + # * variable assignments: var=value + # * commands or their arguments (not allowed in os-release) + if '=' in token: + k, v = token.split('=', 1) + if isinstance(v, bytes): + v = v.decode('utf-8') + props[k.lower()] = v + if k == 'VERSION': + # this handles cases in which the codename is in + # the `(CODENAME)` (rhel, centos, fedora) format + # or in the `, CODENAME` format (Ubuntu). + codename = re.search(r'(\(\D+\))|,(\s+)?\D+', v) + if codename: + codename = codename.group() + codename = codename.strip('()') + codename = codename.strip(',') + codename = codename.strip() + # codename appears within paranthese. + props['codename'] = codename + else: + props['codename'] = '' + else: + # Ignore any tokens that are not variable assignments + pass + return props + + @cached_property + def _lsb_release_info(self): + """ + Get the information items from the lsb_release command output. + + Returns: + A dictionary containing all information items. + """ + if not self.include_lsb: + return {} + with open(os.devnull, 'w') as devnull: + try: + cmd = ('lsb_release', '-a') + stdout = subprocess.check_output(cmd, stderr=devnull) + except OSError: # Command not found + return {} + content = stdout.decode(sys.getfilesystemencoding()).splitlines() + return self._parse_lsb_release_content(content) + + @staticmethod + def _parse_lsb_release_content(lines): + """ + Parse the output of the lsb_release command. + + Parameters: + + * lines: Iterable through the lines of the lsb_release output. + Each line must be a unicode string or a UTF-8 encoded byte + string. + + Returns: + A dictionary containing all information items. + """ + props = {} + for line in lines: + kv = line.strip('\n').split(':', 1) + if len(kv) != 2: + # Ignore lines without colon. + continue + k, v = kv + props.update({k.replace(' ', '_').lower(): v.strip()}) + return props + + @cached_property + def _distro_release_info(self): + """ + Get the information items from the specified distro release file. + + Returns: + A dictionary containing all information items. + """ + if self.distro_release_file: + # If it was specified, we use it and parse what we can, even if + # its file name or content does not match the expected pattern. + distro_info = self._parse_distro_release_file( + self.distro_release_file) + basename = os.path.basename(self.distro_release_file) + # The file name pattern for user-specified distro release files + # is somewhat more tolerant (compared to when searching for the + # file), because we want to use what was specified as best as + # possible. + match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) + if match: + distro_info['id'] = match.group(1) + return distro_info + else: + try: + basenames = os.listdir(_UNIXCONFDIR) + # We sort for repeatability in cases where there are multiple + # distro specific files; e.g. CentOS, Oracle, Enterprise all + # containing `redhat-release` on top of their own. + basenames.sort() + except OSError: + # This may occur when /etc is not readable but we can't be + # sure about the *-release files. Check common entries of + # /etc for information. If they turn out to not be there the + # error is handled in `_parse_distro_release_file()`. + basenames = ['SuSE-release', + 'arch-release', + 'base-release', + 'centos-release', + 'fedora-release', + 'gentoo-release', + 'mageia-release', + 'mandrake-release', + 'mandriva-release', + 'mandrivalinux-release', + 'manjaro-release', + 'oracle-release', + 'redhat-release', + 'sl-release', + 'slackware-version'] + for basename in basenames: + if basename in _DISTRO_RELEASE_IGNORE_BASENAMES: + continue + match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) + if match: + filepath = os.path.join(_UNIXCONFDIR, basename) + distro_info = self._parse_distro_release_file(filepath) + if 'name' in distro_info: + # The name is always present if the pattern matches + self.distro_release_file = filepath + distro_info['id'] = match.group(1) + return distro_info + return {} + + def _parse_distro_release_file(self, filepath): + """ + Parse a distro release file. + + Parameters: + + * filepath: Path name of the distro release file. + + Returns: + A dictionary containing all information items. + """ + try: + with open(filepath) as fp: + # Only parse the first line. For instance, on SLES there + # are multiple lines. We don't want them... + return self._parse_distro_release_content(fp.readline()) + except (OSError, IOError): + # Ignore not being able to read a specific, seemingly version + # related file. + # See https://github.com/nir0s/distro/issues/162 + return {} + + @staticmethod + def _parse_distro_release_content(line): + """ + Parse a line from a distro release file. + + Parameters: + * line: Line from the distro release file. Must be a unicode string + or a UTF-8 encoded byte string. + + Returns: + A dictionary containing all information items. + """ + if isinstance(line, bytes): + line = line.decode('utf-8') + matches = _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN.match( + line.strip()[::-1]) + distro_info = {} + if matches: + # regexp ensures non-None + distro_info['name'] = matches.group(3)[::-1] + if matches.group(2): + distro_info['version_id'] = matches.group(2)[::-1] + if matches.group(1): + distro_info['codename'] = matches.group(1)[::-1] + elif line: + distro_info['name'] = line.strip() + return distro_info + + +_distro = LinuxDistribution() + + +def main(): + logger = logging.getLogger(__name__) + logger.setLevel(logging.DEBUG) + logger.addHandler(logging.StreamHandler(sys.stdout)) + + parser = argparse.ArgumentParser(description="Linux distro info tool") + parser.add_argument( + '--json', + '-j', + help="Output in machine readable format", + action="store_true") + args = parser.parse_args() + + if args.json: + logger.info(json.dumps(info(), indent=4, sort_keys=True)) + else: + logger.info('Name: %s', name(pretty=True)) + distribution_version = version(pretty=True) + logger.info('Version: %s', distribution_version) + distribution_codename = codename() + logger.info('Codename: %s', distribution_codename) + + +if __name__ == '__main__': + main() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__init__.py new file mode 100644 index 0000000..0491234 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__init__.py @@ -0,0 +1,35 @@ +""" +HTML parsing library based on the `WHATWG HTML specification +<https://whatwg.org/html>`_. The parser is designed to be compatible with +existing HTML found in the wild and implements well-defined error recovery that +is largely compatible with modern desktop web browsers. + +Example usage:: + + from pip._vendor import html5lib + with open("my_document.html", "rb") as f: + tree = html5lib.parse(f) + +For convenience, this module re-exports the following names: + +* :func:`~.html5parser.parse` +* :func:`~.html5parser.parseFragment` +* :class:`~.html5parser.HTMLParser` +* :func:`~.treebuilders.getTreeBuilder` +* :func:`~.treewalkers.getTreeWalker` +* :func:`~.serializer.serialize` +""" + +from __future__ import absolute_import, division, unicode_literals + +from .html5parser import HTMLParser, parse, parseFragment +from .treebuilders import getTreeBuilder +from .treewalkers import getTreeWalker +from .serializer import serialize + +__all__ = ["HTMLParser", "parse", "parseFragment", "getTreeBuilder", + "getTreeWalker", "serialize"] + +# this has to be at the top level, see how setup.py parses this +#: Distribution version number. +__version__ = "1.0.1" diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_ihatexml.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_ihatexml.py new file mode 100644 index 0000000..4c77717 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_ihatexml.py @@ -0,0 +1,288 @@ +from __future__ import absolute_import, division, unicode_literals + +import re +import warnings + +from .constants import DataLossWarning + +baseChar = """ +[#x0041-#x005A] | [#x0061-#x007A] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | +[#x00F8-#x00FF] | [#x0100-#x0131] | [#x0134-#x013E] | [#x0141-#x0148] | +[#x014A-#x017E] | [#x0180-#x01C3] | [#x01CD-#x01F0] | [#x01F4-#x01F5] | +[#x01FA-#x0217] | [#x0250-#x02A8] | [#x02BB-#x02C1] | #x0386 | +[#x0388-#x038A] | #x038C | [#x038E-#x03A1] | [#x03A3-#x03CE] | +[#x03D0-#x03D6] | #x03DA | #x03DC | #x03DE | #x03E0 | [#x03E2-#x03F3] | +[#x0401-#x040C] | [#x040E-#x044F] | [#x0451-#x045C] | [#x045E-#x0481] | +[#x0490-#x04C4] | [#x04C7-#x04C8] | [#x04CB-#x04CC] | [#x04D0-#x04EB] | +[#x04EE-#x04F5] | [#x04F8-#x04F9] | [#x0531-#x0556] | #x0559 | +[#x0561-#x0586] | [#x05D0-#x05EA] | [#x05F0-#x05F2] | [#x0621-#x063A] | +[#x0641-#x064A] | [#x0671-#x06B7] | [#x06BA-#x06BE] | [#x06C0-#x06CE] | +[#x06D0-#x06D3] | #x06D5 | [#x06E5-#x06E6] | [#x0905-#x0939] | #x093D | +[#x0958-#x0961] | [#x0985-#x098C] | [#x098F-#x0990] | [#x0993-#x09A8] | +[#x09AA-#x09B0] | #x09B2 | [#x09B6-#x09B9] | [#x09DC-#x09DD] | +[#x09DF-#x09E1] | [#x09F0-#x09F1] | [#x0A05-#x0A0A] | [#x0A0F-#x0A10] | +[#x0A13-#x0A28] | [#x0A2A-#x0A30] | [#x0A32-#x0A33] | [#x0A35-#x0A36] | +[#x0A38-#x0A39] | [#x0A59-#x0A5C] | #x0A5E | [#x0A72-#x0A74] | +[#x0A85-#x0A8B] | #x0A8D | [#x0A8F-#x0A91] | [#x0A93-#x0AA8] | +[#x0AAA-#x0AB0] | [#x0AB2-#x0AB3] | [#x0AB5-#x0AB9] | #x0ABD | #x0AE0 | +[#x0B05-#x0B0C] | [#x0B0F-#x0B10] | [#x0B13-#x0B28] | [#x0B2A-#x0B30] | +[#x0B32-#x0B33] | [#x0B36-#x0B39] | #x0B3D | [#x0B5C-#x0B5D] | +[#x0B5F-#x0B61] | [#x0B85-#x0B8A] | [#x0B8E-#x0B90] | [#x0B92-#x0B95] | +[#x0B99-#x0B9A] | #x0B9C | [#x0B9E-#x0B9F] | [#x0BA3-#x0BA4] | +[#x0BA8-#x0BAA] | [#x0BAE-#x0BB5] | [#x0BB7-#x0BB9] | [#x0C05-#x0C0C] | +[#x0C0E-#x0C10] | [#x0C12-#x0C28] | [#x0C2A-#x0C33] | [#x0C35-#x0C39] | +[#x0C60-#x0C61] | [#x0C85-#x0C8C] | [#x0C8E-#x0C90] | [#x0C92-#x0CA8] | +[#x0CAA-#x0CB3] | [#x0CB5-#x0CB9] | #x0CDE | [#x0CE0-#x0CE1] | +[#x0D05-#x0D0C] | [#x0D0E-#x0D10] | [#x0D12-#x0D28] | [#x0D2A-#x0D39] | +[#x0D60-#x0D61] | [#x0E01-#x0E2E] | #x0E30 | [#x0E32-#x0E33] | +[#x0E40-#x0E45] | [#x0E81-#x0E82] | #x0E84 | [#x0E87-#x0E88] | #x0E8A | +#x0E8D | [#x0E94-#x0E97] | [#x0E99-#x0E9F] | [#x0EA1-#x0EA3] | #x0EA5 | +#x0EA7 | [#x0EAA-#x0EAB] | [#x0EAD-#x0EAE] | #x0EB0 | [#x0EB2-#x0EB3] | +#x0EBD | [#x0EC0-#x0EC4] | [#x0F40-#x0F47] | [#x0F49-#x0F69] | +[#x10A0-#x10C5] | [#x10D0-#x10F6] | #x1100 | [#x1102-#x1103] | +[#x1105-#x1107] | #x1109 | [#x110B-#x110C] | [#x110E-#x1112] | #x113C | +#x113E | #x1140 | #x114C | #x114E | #x1150 | [#x1154-#x1155] | #x1159 | +[#x115F-#x1161] | #x1163 | #x1165 | #x1167 | #x1169 | [#x116D-#x116E] | +[#x1172-#x1173] | #x1175 | #x119E | #x11A8 | #x11AB | [#x11AE-#x11AF] | +[#x11B7-#x11B8] | #x11BA | [#x11BC-#x11C2] | #x11EB | #x11F0 | #x11F9 | +[#x1E00-#x1E9B] | [#x1EA0-#x1EF9] | [#x1F00-#x1F15] | [#x1F18-#x1F1D] | +[#x1F20-#x1F45] | [#x1F48-#x1F4D] | [#x1F50-#x1F57] | #x1F59 | #x1F5B | +#x1F5D | [#x1F5F-#x1F7D] | [#x1F80-#x1FB4] | [#x1FB6-#x1FBC] | #x1FBE | +[#x1FC2-#x1FC4] | [#x1FC6-#x1FCC] | [#x1FD0-#x1FD3] | [#x1FD6-#x1FDB] | +[#x1FE0-#x1FEC] | [#x1FF2-#x1FF4] | [#x1FF6-#x1FFC] | #x2126 | +[#x212A-#x212B] | #x212E | [#x2180-#x2182] | [#x3041-#x3094] | +[#x30A1-#x30FA] | [#x3105-#x312C] | [#xAC00-#xD7A3]""" + +ideographic = """[#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]""" + +combiningCharacter = """ +[#x0300-#x0345] | [#x0360-#x0361] | [#x0483-#x0486] | [#x0591-#x05A1] | +[#x05A3-#x05B9] | [#x05BB-#x05BD] | #x05BF | [#x05C1-#x05C2] | #x05C4 | +[#x064B-#x0652] | #x0670 | [#x06D6-#x06DC] | [#x06DD-#x06DF] | +[#x06E0-#x06E4] | [#x06E7-#x06E8] | [#x06EA-#x06ED] | [#x0901-#x0903] | +#x093C | [#x093E-#x094C] | #x094D | [#x0951-#x0954] | [#x0962-#x0963] | +[#x0981-#x0983] | #x09BC | #x09BE | #x09BF | [#x09C0-#x09C4] | +[#x09C7-#x09C8] | [#x09CB-#x09CD] | #x09D7 | [#x09E2-#x09E3] | #x0A02 | +#x0A3C | #x0A3E | #x0A3F | [#x0A40-#x0A42] | [#x0A47-#x0A48] | +[#x0A4B-#x0A4D] | [#x0A70-#x0A71] | [#x0A81-#x0A83] | #x0ABC | +[#x0ABE-#x0AC5] | [#x0AC7-#x0AC9] | [#x0ACB-#x0ACD] | [#x0B01-#x0B03] | +#x0B3C | [#x0B3E-#x0B43] | [#x0B47-#x0B48] | [#x0B4B-#x0B4D] | +[#x0B56-#x0B57] | [#x0B82-#x0B83] | [#x0BBE-#x0BC2] | [#x0BC6-#x0BC8] | +[#x0BCA-#x0BCD] | #x0BD7 | [#x0C01-#x0C03] | [#x0C3E-#x0C44] | +[#x0C46-#x0C48] | [#x0C4A-#x0C4D] | [#x0C55-#x0C56] | [#x0C82-#x0C83] | +[#x0CBE-#x0CC4] | [#x0CC6-#x0CC8] | [#x0CCA-#x0CCD] | [#x0CD5-#x0CD6] | +[#x0D02-#x0D03] | [#x0D3E-#x0D43] | [#x0D46-#x0D48] | [#x0D4A-#x0D4D] | +#x0D57 | #x0E31 | [#x0E34-#x0E3A] | [#x0E47-#x0E4E] | #x0EB1 | +[#x0EB4-#x0EB9] | [#x0EBB-#x0EBC] | [#x0EC8-#x0ECD] | [#x0F18-#x0F19] | +#x0F35 | #x0F37 | #x0F39 | #x0F3E | #x0F3F | [#x0F71-#x0F84] | +[#x0F86-#x0F8B] | [#x0F90-#x0F95] | #x0F97 | [#x0F99-#x0FAD] | +[#x0FB1-#x0FB7] | #x0FB9 | [#x20D0-#x20DC] | #x20E1 | [#x302A-#x302F] | +#x3099 | #x309A""" + +digit = """ +[#x0030-#x0039] | [#x0660-#x0669] | [#x06F0-#x06F9] | [#x0966-#x096F] | +[#x09E6-#x09EF] | [#x0A66-#x0A6F] | [#x0AE6-#x0AEF] | [#x0B66-#x0B6F] | +[#x0BE7-#x0BEF] | [#x0C66-#x0C6F] | [#x0CE6-#x0CEF] | [#x0D66-#x0D6F] | +[#x0E50-#x0E59] | [#x0ED0-#x0ED9] | [#x0F20-#x0F29]""" + +extender = """ +#x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 | #x0E46 | #x0EC6 | #x3005 | +#[#x3031-#x3035] | [#x309D-#x309E] | [#x30FC-#x30FE]""" + +letter = " | ".join([baseChar, ideographic]) + +# Without the +name = " | ".join([letter, digit, ".", "-", "_", combiningCharacter, + extender]) +nameFirst = " | ".join([letter, "_"]) + +reChar = re.compile(r"#x([\d|A-F]{4,4})") +reCharRange = re.compile(r"\[#x([\d|A-F]{4,4})-#x([\d|A-F]{4,4})\]") + + +def charStringToList(chars): + charRanges = [item.strip() for item in chars.split(" | ")] + rv = [] + for item in charRanges: + foundMatch = False + for regexp in (reChar, reCharRange): + match = regexp.match(item) + if match is not None: + rv.append([hexToInt(item) for item in match.groups()]) + if len(rv[-1]) == 1: + rv[-1] = rv[-1] * 2 + foundMatch = True + break + if not foundMatch: + assert len(item) == 1 + + rv.append([ord(item)] * 2) + rv = normaliseCharList(rv) + return rv + + +def normaliseCharList(charList): + charList = sorted(charList) + for item in charList: + assert item[1] >= item[0] + rv = [] + i = 0 + while i < len(charList): + j = 1 + rv.append(charList[i]) + while i + j < len(charList) and charList[i + j][0] <= rv[-1][1] + 1: + rv[-1][1] = charList[i + j][1] + j += 1 + i += j + return rv + +# We don't really support characters above the BMP :( +max_unicode = int("FFFF", 16) + + +def missingRanges(charList): + rv = [] + if charList[0] != 0: + rv.append([0, charList[0][0] - 1]) + for i, item in enumerate(charList[:-1]): + rv.append([item[1] + 1, charList[i + 1][0] - 1]) + if charList[-1][1] != max_unicode: + rv.append([charList[-1][1] + 1, max_unicode]) + return rv + + +def listToRegexpStr(charList): + rv = [] + for item in charList: + if item[0] == item[1]: + rv.append(escapeRegexp(chr(item[0]))) + else: + rv.append(escapeRegexp(chr(item[0])) + "-" + + escapeRegexp(chr(item[1]))) + return "[%s]" % "".join(rv) + + +def hexToInt(hex_str): + return int(hex_str, 16) + + +def escapeRegexp(string): + specialCharacters = (".", "^", "$", "*", "+", "?", "{", "}", + "[", "]", "|", "(", ")", "-") + for char in specialCharacters: + string = string.replace(char, "\\" + char) + + return string + +# output from the above +nonXmlNameBMPRegexp = re.compile('[\x00-,/:-@\\[-\\^`\\{-\xb6\xb8-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u02cf\u02d2-\u02ff\u0346-\u035f\u0362-\u0385\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482\u0487-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u0590\u05a2\u05ba\u05be\u05c0\u05c3\u05c5-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u063f\u0653-\u065f\u066a-\u066f\u06b8-\u06b9\u06bf\u06cf\u06d4\u06e9\u06ee-\u06ef\u06fa-\u0900\u0904\u093a-\u093b\u094e-\u0950\u0955-\u0957\u0964-\u0965\u0970-\u0980\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09bb\u09bd\u09c5-\u09c6\u09c9-\u09ca\u09ce-\u09d6\u09d8-\u09db\u09de\u09e4-\u09e5\u09f2-\u0a01\u0a03-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a3b\u0a3d\u0a43-\u0a46\u0a49-\u0a4a\u0a4e-\u0a58\u0a5d\u0a5f-\u0a65\u0a75-\u0a80\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abb\u0ac6\u0aca\u0ace-\u0adf\u0ae1-\u0ae5\u0af0-\u0b00\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3b\u0b44-\u0b46\u0b49-\u0b4a\u0b4e-\u0b55\u0b58-\u0b5b\u0b5e\u0b62-\u0b65\u0b70-\u0b81\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0bbd\u0bc3-\u0bc5\u0bc9\u0bce-\u0bd6\u0bd8-\u0be6\u0bf0-\u0c00\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c3d\u0c45\u0c49\u0c4e-\u0c54\u0c57-\u0c5f\u0c62-\u0c65\u0c70-\u0c81\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cbd\u0cc5\u0cc9\u0cce-\u0cd4\u0cd7-\u0cdd\u0cdf\u0ce2-\u0ce5\u0cf0-\u0d01\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d3d\u0d44-\u0d45\u0d49\u0d4e-\u0d56\u0d58-\u0d5f\u0d62-\u0d65\u0d70-\u0e00\u0e2f\u0e3b-\u0e3f\u0e4f\u0e5a-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eba\u0ebe-\u0ebf\u0ec5\u0ec7\u0ece-\u0ecf\u0eda-\u0f17\u0f1a-\u0f1f\u0f2a-\u0f34\u0f36\u0f38\u0f3a-\u0f3d\u0f48\u0f6a-\u0f70\u0f85\u0f8c-\u0f8f\u0f96\u0f98\u0fae-\u0fb0\u0fb8\u0fba-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u20cf\u20dd-\u20e0\u20e2-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3004\u3006\u3008-\u3020\u3030\u3036-\u3040\u3095-\u3098\u309b-\u309c\u309f-\u30a0\u30fb\u30ff-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa + +nonXmlNameFirstBMPRegexp = re.compile('[\x00-@\\[-\\^`\\{-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u0385\u0387\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u0640\u064b-\u0670\u06b8-\u06b9\u06bf\u06cf\u06d4\u06d6-\u06e4\u06e7-\u0904\u093a-\u093c\u093e-\u0957\u0962-\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09db\u09de\u09e2-\u09ef\u09f2-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a58\u0a5d\u0a5f-\u0a71\u0a75-\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abc\u0abe-\u0adf\u0ae1-\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3c\u0b3e-\u0b5b\u0b5e\u0b62-\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c5f\u0c62-\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cdd\u0cdf\u0ce2-\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d5f\u0d62-\u0e00\u0e2f\u0e31\u0e34-\u0e3f\u0e46-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eb1\u0eb4-\u0ebc\u0ebe-\u0ebf\u0ec5-\u0f3f\u0f48\u0f6a-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3006\u3008-\u3020\u302a-\u3040\u3095-\u30a0\u30fb-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa + +# Simpler things +nonPubidCharRegexp = re.compile("[^\x20\x0D\x0Aa-zA-Z0-9\\-'()+,./:=?;!*#@$_%]") + + +class InfosetFilter(object): + replacementRegexp = re.compile(r"U[\dA-F]{5,5}") + + def __init__(self, + dropXmlnsLocalName=False, + dropXmlnsAttrNs=False, + preventDoubleDashComments=False, + preventDashAtCommentEnd=False, + replaceFormFeedCharacters=True, + preventSingleQuotePubid=False): + + self.dropXmlnsLocalName = dropXmlnsLocalName + self.dropXmlnsAttrNs = dropXmlnsAttrNs + + self.preventDoubleDashComments = preventDoubleDashComments + self.preventDashAtCommentEnd = preventDashAtCommentEnd + + self.replaceFormFeedCharacters = replaceFormFeedCharacters + + self.preventSingleQuotePubid = preventSingleQuotePubid + + self.replaceCache = {} + + def coerceAttribute(self, name, namespace=None): + if self.dropXmlnsLocalName and name.startswith("xmlns:"): + warnings.warn("Attributes cannot begin with xmlns", DataLossWarning) + return None + elif (self.dropXmlnsAttrNs and + namespace == "http://www.w3.org/2000/xmlns/"): + warnings.warn("Attributes cannot be in the xml namespace", DataLossWarning) + return None + else: + return self.toXmlName(name) + + def coerceElement(self, name): + return self.toXmlName(name) + + def coerceComment(self, data): + if self.preventDoubleDashComments: + while "--" in data: + warnings.warn("Comments cannot contain adjacent dashes", DataLossWarning) + data = data.replace("--", "- -") + if data.endswith("-"): + warnings.warn("Comments cannot end in a dash", DataLossWarning) + data += " " + return data + + def coerceCharacters(self, data): + if self.replaceFormFeedCharacters: + for _ in range(data.count("\x0C")): + warnings.warn("Text cannot contain U+000C", DataLossWarning) + data = data.replace("\x0C", " ") + # Other non-xml characters + return data + + def coercePubid(self, data): + dataOutput = data + for char in nonPubidCharRegexp.findall(data): + warnings.warn("Coercing non-XML pubid", DataLossWarning) + replacement = self.getReplacementCharacter(char) + dataOutput = dataOutput.replace(char, replacement) + if self.preventSingleQuotePubid and dataOutput.find("'") >= 0: + warnings.warn("Pubid cannot contain single quote", DataLossWarning) + dataOutput = dataOutput.replace("'", self.getReplacementCharacter("'")) + return dataOutput + + def toXmlName(self, name): + nameFirst = name[0] + nameRest = name[1:] + m = nonXmlNameFirstBMPRegexp.match(nameFirst) + if m: + warnings.warn("Coercing non-XML name", DataLossWarning) + nameFirstOutput = self.getReplacementCharacter(nameFirst) + else: + nameFirstOutput = nameFirst + + nameRestOutput = nameRest + replaceChars = set(nonXmlNameBMPRegexp.findall(nameRest)) + for char in replaceChars: + warnings.warn("Coercing non-XML name", DataLossWarning) + replacement = self.getReplacementCharacter(char) + nameRestOutput = nameRestOutput.replace(char, replacement) + return nameFirstOutput + nameRestOutput + + def getReplacementCharacter(self, char): + if char in self.replaceCache: + replacement = self.replaceCache[char] + else: + replacement = self.escapeChar(char) + return replacement + + def fromXmlName(self, name): + for item in set(self.replacementRegexp.findall(name)): + name = name.replace(item, self.unescapeChar(item)) + return name + + def escapeChar(self, char): + replacement = "U%05X" % ord(char) + self.replaceCache[char] = replacement + return replacement + + def unescapeChar(self, charcode): + return chr(int(charcode[1:], 16)) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_inputstream.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_inputstream.py new file mode 100644 index 0000000..a65e55f --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_inputstream.py @@ -0,0 +1,923 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import text_type, binary_type +from pip._vendor.six.moves import http_client, urllib + +import codecs +import re + +from pip._vendor import webencodings + +from .constants import EOF, spaceCharacters, asciiLetters, asciiUppercase +from .constants import _ReparseException +from . import _utils + +from io import StringIO + +try: + from io import BytesIO +except ImportError: + BytesIO = StringIO + +# Non-unicode versions of constants for use in the pre-parser +spaceCharactersBytes = frozenset([item.encode("ascii") for item in spaceCharacters]) +asciiLettersBytes = frozenset([item.encode("ascii") for item in asciiLetters]) +asciiUppercaseBytes = frozenset([item.encode("ascii") for item in asciiUppercase]) +spacesAngleBrackets = spaceCharactersBytes | frozenset([b">", b"<"]) + + +invalid_unicode_no_surrogate = "[\u0001-\u0008\u000B\u000E-\u001F\u007F-\u009F\uFDD0-\uFDEF\uFFFE\uFFFF\U0001FFFE\U0001FFFF\U0002FFFE\U0002FFFF\U0003FFFE\U0003FFFF\U0004FFFE\U0004FFFF\U0005FFFE\U0005FFFF\U0006FFFE\U0006FFFF\U0007FFFE\U0007FFFF\U0008FFFE\U0008FFFF\U0009FFFE\U0009FFFF\U000AFFFE\U000AFFFF\U000BFFFE\U000BFFFF\U000CFFFE\U000CFFFF\U000DFFFE\U000DFFFF\U000EFFFE\U000EFFFF\U000FFFFE\U000FFFFF\U0010FFFE\U0010FFFF]" # noqa + +if _utils.supports_lone_surrogates: + # Use one extra step of indirection and create surrogates with + # eval. Not using this indirection would introduce an illegal + # unicode literal on platforms not supporting such lone + # surrogates. + assert invalid_unicode_no_surrogate[-1] == "]" and invalid_unicode_no_surrogate.count("]") == 1 + invalid_unicode_re = re.compile(invalid_unicode_no_surrogate[:-1] + + eval('"\\uD800-\\uDFFF"') + # pylint:disable=eval-used + "]") +else: + invalid_unicode_re = re.compile(invalid_unicode_no_surrogate) + +non_bmp_invalid_codepoints = set([0x1FFFE, 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, + 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, 0x5FFFF, + 0x6FFFE, 0x6FFFF, 0x7FFFE, 0x7FFFF, 0x8FFFE, + 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE, 0xAFFFF, + 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, + 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, + 0x10FFFE, 0x10FFFF]) + +ascii_punctuation_re = re.compile("[\u0009-\u000D\u0020-\u002F\u003A-\u0040\u005C\u005B-\u0060\u007B-\u007E]") + +# Cache for charsUntil() +charsUntilRegEx = {} + + +class BufferedStream(object): + """Buffering for streams that do not have buffering of their own + + The buffer is implemented as a list of chunks on the assumption that + joining many strings will be slow since it is O(n**2) + """ + + def __init__(self, stream): + self.stream = stream + self.buffer = [] + self.position = [-1, 0] # chunk number, offset + + def tell(self): + pos = 0 + for chunk in self.buffer[:self.position[0]]: + pos += len(chunk) + pos += self.position[1] + return pos + + def seek(self, pos): + assert pos <= self._bufferedBytes() + offset = pos + i = 0 + while len(self.buffer[i]) < offset: + offset -= len(self.buffer[i]) + i += 1 + self.position = [i, offset] + + def read(self, bytes): + if not self.buffer: + return self._readStream(bytes) + elif (self.position[0] == len(self.buffer) and + self.position[1] == len(self.buffer[-1])): + return self._readStream(bytes) + else: + return self._readFromBuffer(bytes) + + def _bufferedBytes(self): + return sum([len(item) for item in self.buffer]) + + def _readStream(self, bytes): + data = self.stream.read(bytes) + self.buffer.append(data) + self.position[0] += 1 + self.position[1] = len(data) + return data + + def _readFromBuffer(self, bytes): + remainingBytes = bytes + rv = [] + bufferIndex = self.position[0] + bufferOffset = self.position[1] + while bufferIndex < len(self.buffer) and remainingBytes != 0: + assert remainingBytes > 0 + bufferedData = self.buffer[bufferIndex] + + if remainingBytes <= len(bufferedData) - bufferOffset: + bytesToRead = remainingBytes + self.position = [bufferIndex, bufferOffset + bytesToRead] + else: + bytesToRead = len(bufferedData) - bufferOffset + self.position = [bufferIndex, len(bufferedData)] + bufferIndex += 1 + rv.append(bufferedData[bufferOffset:bufferOffset + bytesToRead]) + remainingBytes -= bytesToRead + + bufferOffset = 0 + + if remainingBytes: + rv.append(self._readStream(remainingBytes)) + + return b"".join(rv) + + +def HTMLInputStream(source, **kwargs): + # Work around Python bug #20007: read(0) closes the connection. + # http://bugs.python.org/issue20007 + if (isinstance(source, http_client.HTTPResponse) or + # Also check for addinfourl wrapping HTTPResponse + (isinstance(source, urllib.response.addbase) and + isinstance(source.fp, http_client.HTTPResponse))): + isUnicode = False + elif hasattr(source, "read"): + isUnicode = isinstance(source.read(0), text_type) + else: + isUnicode = isinstance(source, text_type) + + if isUnicode: + encodings = [x for x in kwargs if x.endswith("_encoding")] + if encodings: + raise TypeError("Cannot set an encoding with a unicode input, set %r" % encodings) + + return HTMLUnicodeInputStream(source, **kwargs) + else: + return HTMLBinaryInputStream(source, **kwargs) + + +class HTMLUnicodeInputStream(object): + """Provides a unicode stream of characters to the HTMLTokenizer. + + This class takes care of character encoding and removing or replacing + incorrect byte-sequences and also provides column and line tracking. + + """ + + _defaultChunkSize = 10240 + + def __init__(self, source): + """Initialises the HTMLInputStream. + + HTMLInputStream(source, [encoding]) -> Normalized stream from source + for use by html5lib. + + source can be either a file-object, local filename or a string. + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + """ + + if not _utils.supports_lone_surrogates: + # Such platforms will have already checked for such + # surrogate errors, so no need to do this checking. + self.reportCharacterErrors = None + elif len("\U0010FFFF") == 1: + self.reportCharacterErrors = self.characterErrorsUCS4 + else: + self.reportCharacterErrors = self.characterErrorsUCS2 + + # List of where new lines occur + self.newLines = [0] + + self.charEncoding = (lookupEncoding("utf-8"), "certain") + self.dataStream = self.openStream(source) + + self.reset() + + def reset(self): + self.chunk = "" + self.chunkSize = 0 + self.chunkOffset = 0 + self.errors = [] + + # number of (complete) lines in previous chunks + self.prevNumLines = 0 + # number of columns in the last line of the previous chunk + self.prevNumCols = 0 + + # Deal with CR LF and surrogates split over chunk boundaries + self._bufferedCharacter = None + + def openStream(self, source): + """Produces a file object from source. + + source can be either a file object, local filename or a string. + + """ + # Already a file object + if hasattr(source, 'read'): + stream = source + else: + stream = StringIO(source) + + return stream + + def _position(self, offset): + chunk = self.chunk + nLines = chunk.count('\n', 0, offset) + positionLine = self.prevNumLines + nLines + lastLinePos = chunk.rfind('\n', 0, offset) + if lastLinePos == -1: + positionColumn = self.prevNumCols + offset + else: + positionColumn = offset - (lastLinePos + 1) + return (positionLine, positionColumn) + + def position(self): + """Returns (line, col) of the current position in the stream.""" + line, col = self._position(self.chunkOffset) + return (line + 1, col) + + def char(self): + """ Read one character from the stream or queue if available. Return + EOF when EOF is reached. + """ + # Read a new chunk from the input stream if necessary + if self.chunkOffset >= self.chunkSize: + if not self.readChunk(): + return EOF + + chunkOffset = self.chunkOffset + char = self.chunk[chunkOffset] + self.chunkOffset = chunkOffset + 1 + + return char + + def readChunk(self, chunkSize=None): + if chunkSize is None: + chunkSize = self._defaultChunkSize + + self.prevNumLines, self.prevNumCols = self._position(self.chunkSize) + + self.chunk = "" + self.chunkSize = 0 + self.chunkOffset = 0 + + data = self.dataStream.read(chunkSize) + + # Deal with CR LF and surrogates broken across chunks + if self._bufferedCharacter: + data = self._bufferedCharacter + data + self._bufferedCharacter = None + elif not data: + # We have no more data, bye-bye stream + return False + + if len(data) > 1: + lastv = ord(data[-1]) + if lastv == 0x0D or 0xD800 <= lastv <= 0xDBFF: + self._bufferedCharacter = data[-1] + data = data[:-1] + + if self.reportCharacterErrors: + self.reportCharacterErrors(data) + + # Replace invalid characters + data = data.replace("\r\n", "\n") + data = data.replace("\r", "\n") + + self.chunk = data + self.chunkSize = len(data) + + return True + + def characterErrorsUCS4(self, data): + for _ in range(len(invalid_unicode_re.findall(data))): + self.errors.append("invalid-codepoint") + + def characterErrorsUCS2(self, data): + # Someone picked the wrong compile option + # You lose + skip = False + for match in invalid_unicode_re.finditer(data): + if skip: + continue + codepoint = ord(match.group()) + pos = match.start() + # Pretty sure there should be endianness issues here + if _utils.isSurrogatePair(data[pos:pos + 2]): + # We have a surrogate pair! + char_val = _utils.surrogatePairToCodepoint(data[pos:pos + 2]) + if char_val in non_bmp_invalid_codepoints: + self.errors.append("invalid-codepoint") + skip = True + elif (codepoint >= 0xD800 and codepoint <= 0xDFFF and + pos == len(data) - 1): + self.errors.append("invalid-codepoint") + else: + skip = False + self.errors.append("invalid-codepoint") + + def charsUntil(self, characters, opposite=False): + """ Returns a string of characters from the stream up to but not + including any character in 'characters' or EOF. 'characters' must be + a container that supports the 'in' method and iteration over its + characters. + """ + + # Use a cache of regexps to find the required characters + try: + chars = charsUntilRegEx[(characters, opposite)] + except KeyError: + if __debug__: + for c in characters: + assert(ord(c) < 128) + regex = "".join(["\\x%02x" % ord(c) for c in characters]) + if not opposite: + regex = "^%s" % regex + chars = charsUntilRegEx[(characters, opposite)] = re.compile("[%s]+" % regex) + + rv = [] + + while True: + # Find the longest matching prefix + m = chars.match(self.chunk, self.chunkOffset) + if m is None: + # If nothing matched, and it wasn't because we ran out of chunk, + # then stop + if self.chunkOffset != self.chunkSize: + break + else: + end = m.end() + # If not the whole chunk matched, return everything + # up to the part that didn't match + if end != self.chunkSize: + rv.append(self.chunk[self.chunkOffset:end]) + self.chunkOffset = end + break + # If the whole remainder of the chunk matched, + # use it all and read the next chunk + rv.append(self.chunk[self.chunkOffset:]) + if not self.readChunk(): + # Reached EOF + break + + r = "".join(rv) + return r + + def unget(self, char): + # Only one character is allowed to be ungotten at once - it must + # be consumed again before any further call to unget + if char is not None: + if self.chunkOffset == 0: + # unget is called quite rarely, so it's a good idea to do + # more work here if it saves a bit of work in the frequently + # called char and charsUntil. + # So, just prepend the ungotten character onto the current + # chunk: + self.chunk = char + self.chunk + self.chunkSize += 1 + else: + self.chunkOffset -= 1 + assert self.chunk[self.chunkOffset] == char + + +class HTMLBinaryInputStream(HTMLUnicodeInputStream): + """Provides a unicode stream of characters to the HTMLTokenizer. + + This class takes care of character encoding and removing or replacing + incorrect byte-sequences and also provides column and line tracking. + + """ + + def __init__(self, source, override_encoding=None, transport_encoding=None, + same_origin_parent_encoding=None, likely_encoding=None, + default_encoding="windows-1252", useChardet=True): + """Initialises the HTMLInputStream. + + HTMLInputStream(source, [encoding]) -> Normalized stream from source + for use by html5lib. + + source can be either a file-object, local filename or a string. + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + """ + # Raw Stream - for unicode objects this will encode to utf-8 and set + # self.charEncoding as appropriate + self.rawStream = self.openStream(source) + + HTMLUnicodeInputStream.__init__(self, self.rawStream) + + # Encoding Information + # Number of bytes to use when looking for a meta element with + # encoding information + self.numBytesMeta = 1024 + # Number of bytes to use when using detecting encoding using chardet + self.numBytesChardet = 100 + # Things from args + self.override_encoding = override_encoding + self.transport_encoding = transport_encoding + self.same_origin_parent_encoding = same_origin_parent_encoding + self.likely_encoding = likely_encoding + self.default_encoding = default_encoding + + # Determine encoding + self.charEncoding = self.determineEncoding(useChardet) + assert self.charEncoding[0] is not None + + # Call superclass + self.reset() + + def reset(self): + self.dataStream = self.charEncoding[0].codec_info.streamreader(self.rawStream, 'replace') + HTMLUnicodeInputStream.reset(self) + + def openStream(self, source): + """Produces a file object from source. + + source can be either a file object, local filename or a string. + + """ + # Already a file object + if hasattr(source, 'read'): + stream = source + else: + stream = BytesIO(source) + + try: + stream.seek(stream.tell()) + except: # pylint:disable=bare-except + stream = BufferedStream(stream) + + return stream + + def determineEncoding(self, chardet=True): + # BOMs take precedence over everything + # This will also read past the BOM if present + charEncoding = self.detectBOM(), "certain" + if charEncoding[0] is not None: + return charEncoding + + # If we've been overriden, we've been overriden + charEncoding = lookupEncoding(self.override_encoding), "certain" + if charEncoding[0] is not None: + return charEncoding + + # Now check the transport layer + charEncoding = lookupEncoding(self.transport_encoding), "certain" + if charEncoding[0] is not None: + return charEncoding + + # Look for meta elements with encoding information + charEncoding = self.detectEncodingMeta(), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Parent document encoding + charEncoding = lookupEncoding(self.same_origin_parent_encoding), "tentative" + if charEncoding[0] is not None and not charEncoding[0].name.startswith("utf-16"): + return charEncoding + + # "likely" encoding + charEncoding = lookupEncoding(self.likely_encoding), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Guess with chardet, if available + if chardet: + try: + from pip._vendor.chardet.universaldetector import UniversalDetector + except ImportError: + pass + else: + buffers = [] + detector = UniversalDetector() + while not detector.done: + buffer = self.rawStream.read(self.numBytesChardet) + assert isinstance(buffer, bytes) + if not buffer: + break + buffers.append(buffer) + detector.feed(buffer) + detector.close() + encoding = lookupEncoding(detector.result['encoding']) + self.rawStream.seek(0) + if encoding is not None: + return encoding, "tentative" + + # Try the default encoding + charEncoding = lookupEncoding(self.default_encoding), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Fallback to html5lib's default if even that hasn't worked + return lookupEncoding("windows-1252"), "tentative" + + def changeEncoding(self, newEncoding): + assert self.charEncoding[1] != "certain" + newEncoding = lookupEncoding(newEncoding) + if newEncoding is None: + return + if newEncoding.name in ("utf-16be", "utf-16le"): + newEncoding = lookupEncoding("utf-8") + assert newEncoding is not None + elif newEncoding == self.charEncoding[0]: + self.charEncoding = (self.charEncoding[0], "certain") + else: + self.rawStream.seek(0) + self.charEncoding = (newEncoding, "certain") + self.reset() + raise _ReparseException("Encoding changed from %s to %s" % (self.charEncoding[0], newEncoding)) + + def detectBOM(self): + """Attempts to detect at BOM at the start of the stream. If + an encoding can be determined from the BOM return the name of the + encoding otherwise return None""" + bomDict = { + codecs.BOM_UTF8: 'utf-8', + codecs.BOM_UTF16_LE: 'utf-16le', codecs.BOM_UTF16_BE: 'utf-16be', + codecs.BOM_UTF32_LE: 'utf-32le', codecs.BOM_UTF32_BE: 'utf-32be' + } + + # Go to beginning of file and read in 4 bytes + string = self.rawStream.read(4) + assert isinstance(string, bytes) + + # Try detecting the BOM using bytes from the string + encoding = bomDict.get(string[:3]) # UTF-8 + seek = 3 + if not encoding: + # Need to detect UTF-32 before UTF-16 + encoding = bomDict.get(string) # UTF-32 + seek = 4 + if not encoding: + encoding = bomDict.get(string[:2]) # UTF-16 + seek = 2 + + # Set the read position past the BOM if one was found, otherwise + # set it to the start of the stream + if encoding: + self.rawStream.seek(seek) + return lookupEncoding(encoding) + else: + self.rawStream.seek(0) + return None + + def detectEncodingMeta(self): + """Report the encoding declared by the meta element + """ + buffer = self.rawStream.read(self.numBytesMeta) + assert isinstance(buffer, bytes) + parser = EncodingParser(buffer) + self.rawStream.seek(0) + encoding = parser.getEncoding() + + if encoding is not None and encoding.name in ("utf-16be", "utf-16le"): + encoding = lookupEncoding("utf-8") + + return encoding + + +class EncodingBytes(bytes): + """String-like object with an associated position and various extra methods + If the position is ever greater than the string length then an exception is + raised""" + def __new__(self, value): + assert isinstance(value, bytes) + return bytes.__new__(self, value.lower()) + + def __init__(self, value): + # pylint:disable=unused-argument + self._position = -1 + + def __iter__(self): + return self + + def __next__(self): + p = self._position = self._position + 1 + if p >= len(self): + raise StopIteration + elif p < 0: + raise TypeError + return self[p:p + 1] + + def next(self): + # Py2 compat + return self.__next__() + + def previous(self): + p = self._position + if p >= len(self): + raise StopIteration + elif p < 0: + raise TypeError + self._position = p = p - 1 + return self[p:p + 1] + + def setPosition(self, position): + if self._position >= len(self): + raise StopIteration + self._position = position + + def getPosition(self): + if self._position >= len(self): + raise StopIteration + if self._position >= 0: + return self._position + else: + return None + + position = property(getPosition, setPosition) + + def getCurrentByte(self): + return self[self.position:self.position + 1] + + currentByte = property(getCurrentByte) + + def skip(self, chars=spaceCharactersBytes): + """Skip past a list of characters""" + p = self.position # use property for the error-checking + while p < len(self): + c = self[p:p + 1] + if c not in chars: + self._position = p + return c + p += 1 + self._position = p + return None + + def skipUntil(self, chars): + p = self.position + while p < len(self): + c = self[p:p + 1] + if c in chars: + self._position = p + return c + p += 1 + self._position = p + return None + + def matchBytes(self, bytes): + """Look for a sequence of bytes at the start of a string. If the bytes + are found return True and advance the position to the byte after the + match. Otherwise return False and leave the position alone""" + p = self.position + data = self[p:p + len(bytes)] + rv = data.startswith(bytes) + if rv: + self.position += len(bytes) + return rv + + def jumpTo(self, bytes): + """Look for the next sequence of bytes matching a given sequence. If + a match is found advance the position to the last byte of the match""" + newPosition = self[self.position:].find(bytes) + if newPosition > -1: + # XXX: This is ugly, but I can't see a nicer way to fix this. + if self._position == -1: + self._position = 0 + self._position += (newPosition + len(bytes) - 1) + return True + else: + raise StopIteration + + +class EncodingParser(object): + """Mini parser for detecting character encoding from meta elements""" + + def __init__(self, data): + """string - the data to work on for encoding detection""" + self.data = EncodingBytes(data) + self.encoding = None + + def getEncoding(self): + methodDispatch = ( + (b"<!--", self.handleComment), + (b"<meta", self.handleMeta), + (b"</", self.handlePossibleEndTag), + (b"<!", self.handleOther), + (b"<?", self.handleOther), + (b"<", self.handlePossibleStartTag)) + for _ in self.data: + keepParsing = True + for key, method in methodDispatch: + if self.data.matchBytes(key): + try: + keepParsing = method() + break + except StopIteration: + keepParsing = False + break + if not keepParsing: + break + + return self.encoding + + def handleComment(self): + """Skip over comments""" + return self.data.jumpTo(b"-->") + + def handleMeta(self): + if self.data.currentByte not in spaceCharactersBytes: + # if we have <meta not followed by a space so just keep going + return True + # We have a valid meta element we want to search for attributes + hasPragma = False + pendingEncoding = None + while True: + # Try to find the next attribute after the current position + attr = self.getAttribute() + if attr is None: + return True + else: + if attr[0] == b"http-equiv": + hasPragma = attr[1] == b"content-type" + if hasPragma and pendingEncoding is not None: + self.encoding = pendingEncoding + return False + elif attr[0] == b"charset": + tentativeEncoding = attr[1] + codec = lookupEncoding(tentativeEncoding) + if codec is not None: + self.encoding = codec + return False + elif attr[0] == b"content": + contentParser = ContentAttrParser(EncodingBytes(attr[1])) + tentativeEncoding = contentParser.parse() + if tentativeEncoding is not None: + codec = lookupEncoding(tentativeEncoding) + if codec is not None: + if hasPragma: + self.encoding = codec + return False + else: + pendingEncoding = codec + + def handlePossibleStartTag(self): + return self.handlePossibleTag(False) + + def handlePossibleEndTag(self): + next(self.data) + return self.handlePossibleTag(True) + + def handlePossibleTag(self, endTag): + data = self.data + if data.currentByte not in asciiLettersBytes: + # If the next byte is not an ascii letter either ignore this + # fragment (possible start tag case) or treat it according to + # handleOther + if endTag: + data.previous() + self.handleOther() + return True + + c = data.skipUntil(spacesAngleBrackets) + if c == b"<": + # return to the first step in the overall "two step" algorithm + # reprocessing the < byte + data.previous() + else: + # Read all attributes + attr = self.getAttribute() + while attr is not None: + attr = self.getAttribute() + return True + + def handleOther(self): + return self.data.jumpTo(b">") + + def getAttribute(self): + """Return a name,value pair for the next attribute in the stream, + if one is found, or None""" + data = self.data + # Step 1 (skip chars) + c = data.skip(spaceCharactersBytes | frozenset([b"/"])) + assert c is None or len(c) == 1 + # Step 2 + if c in (b">", None): + return None + # Step 3 + attrName = [] + attrValue = [] + # Step 4 attribute name + while True: + if c == b"=" and attrName: + break + elif c in spaceCharactersBytes: + # Step 6! + c = data.skip() + break + elif c in (b"/", b">"): + return b"".join(attrName), b"" + elif c in asciiUppercaseBytes: + attrName.append(c.lower()) + elif c is None: + return None + else: + attrName.append(c) + # Step 5 + c = next(data) + # Step 7 + if c != b"=": + data.previous() + return b"".join(attrName), b"" + # Step 8 + next(data) + # Step 9 + c = data.skip() + # Step 10 + if c in (b"'", b'"'): + # 10.1 + quoteChar = c + while True: + # 10.2 + c = next(data) + # 10.3 + if c == quoteChar: + next(data) + return b"".join(attrName), b"".join(attrValue) + # 10.4 + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + # 10.5 + else: + attrValue.append(c) + elif c == b">": + return b"".join(attrName), b"" + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + elif c is None: + return None + else: + attrValue.append(c) + # Step 11 + while True: + c = next(data) + if c in spacesAngleBrackets: + return b"".join(attrName), b"".join(attrValue) + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + elif c is None: + return None + else: + attrValue.append(c) + + +class ContentAttrParser(object): + def __init__(self, data): + assert isinstance(data, bytes) + self.data = data + + def parse(self): + try: + # Check if the attr name is charset + # otherwise return + self.data.jumpTo(b"charset") + self.data.position += 1 + self.data.skip() + if not self.data.currentByte == b"=": + # If there is no = sign keep looking for attrs + return None + self.data.position += 1 + self.data.skip() + # Look for an encoding between matching quote marks + if self.data.currentByte in (b'"', b"'"): + quoteMark = self.data.currentByte + self.data.position += 1 + oldPosition = self.data.position + if self.data.jumpTo(quoteMark): + return self.data[oldPosition:self.data.position] + else: + return None + else: + # Unquoted value + oldPosition = self.data.position + try: + self.data.skipUntil(spaceCharactersBytes) + return self.data[oldPosition:self.data.position] + except StopIteration: + # Return the whole remaining value + return self.data[oldPosition:] + except StopIteration: + return None + + +def lookupEncoding(encoding): + """Return the python codec name corresponding to an encoding or None if the + string doesn't correspond to a valid encoding.""" + if isinstance(encoding, binary_type): + try: + encoding = encoding.decode("ascii") + except UnicodeDecodeError: + return None + + if encoding is not None: + try: + return webencodings.lookup(encoding) + except AttributeError: + return None + else: + return None diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_tokenizer.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_tokenizer.py new file mode 100644 index 0000000..178f6e7 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_tokenizer.py @@ -0,0 +1,1721 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import unichr as chr + +from collections import deque + +from .constants import spaceCharacters +from .constants import entities +from .constants import asciiLetters, asciiUpper2Lower +from .constants import digits, hexDigits, EOF +from .constants import tokenTypes, tagTokenTypes +from .constants import replacementCharacters + +from ._inputstream import HTMLInputStream + +from ._trie import Trie + +entitiesTrie = Trie(entities) + + +class HTMLTokenizer(object): + """ This class takes care of tokenizing HTML. + + * self.currentToken + Holds the token that is currently being processed. + + * self.state + Holds a reference to the method to be invoked... XXX + + * self.stream + Points to HTMLInputStream object. + """ + + def __init__(self, stream, parser=None, **kwargs): + + self.stream = HTMLInputStream(stream, **kwargs) + self.parser = parser + + # Setup the initial tokenizer state + self.escapeFlag = False + self.lastFourChars = [] + self.state = self.dataState + self.escape = False + + # The current token being created + self.currentToken = None + super(HTMLTokenizer, self).__init__() + + def __iter__(self): + """ This is where the magic happens. + + We do our usually processing through the states and when we have a token + to return we yield the token which pauses processing until the next token + is requested. + """ + self.tokenQueue = deque([]) + # Start processing. When EOF is reached self.state will return False + # instead of True and the loop will terminate. + while self.state(): + while self.stream.errors: + yield {"type": tokenTypes["ParseError"], "data": self.stream.errors.pop(0)} + while self.tokenQueue: + yield self.tokenQueue.popleft() + + def consumeNumberEntity(self, isHex): + """This function returns either U+FFFD or the character based on the + decimal or hexadecimal representation. It also discards ";" if present. + If not present self.tokenQueue.append({"type": tokenTypes["ParseError"]}) is invoked. + """ + + allowed = digits + radix = 10 + if isHex: + allowed = hexDigits + radix = 16 + + charStack = [] + + # Consume all the characters that are in range while making sure we + # don't hit an EOF. + c = self.stream.char() + while c in allowed and c is not EOF: + charStack.append(c) + c = self.stream.char() + + # Convert the set of characters consumed to an int. + charAsInt = int("".join(charStack), radix) + + # Certain characters get replaced with others + if charAsInt in replacementCharacters: + char = replacementCharacters[charAsInt] + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + elif ((0xD800 <= charAsInt <= 0xDFFF) or + (charAsInt > 0x10FFFF)): + char = "\uFFFD" + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + else: + # Should speed up this check somehow (e.g. move the set to a constant) + if ((0x0001 <= charAsInt <= 0x0008) or + (0x000E <= charAsInt <= 0x001F) or + (0x007F <= charAsInt <= 0x009F) or + (0xFDD0 <= charAsInt <= 0xFDEF) or + charAsInt in frozenset([0x000B, 0xFFFE, 0xFFFF, 0x1FFFE, + 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, + 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, + 0x5FFFF, 0x6FFFE, 0x6FFFF, 0x7FFFE, + 0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, + 0x9FFFF, 0xAFFFE, 0xAFFFF, 0xBFFFE, + 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, + 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, + 0xFFFFF, 0x10FFFE, 0x10FFFF])): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + try: + # Try/except needed as UCS-2 Python builds' unichar only works + # within the BMP. + char = chr(charAsInt) + except ValueError: + v = charAsInt - 0x10000 + char = chr(0xD800 | (v >> 10)) + chr(0xDC00 | (v & 0x3FF)) + + # Discard the ; if present. Otherwise, put it back on the queue and + # invoke parseError on parser. + if c != ";": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "numeric-entity-without-semicolon"}) + self.stream.unget(c) + + return char + + def consumeEntity(self, allowedChar=None, fromAttribute=False): + # Initialise to the default output for when no entity is matched + output = "&" + + charStack = [self.stream.char()] + if (charStack[0] in spaceCharacters or charStack[0] in (EOF, "<", "&") or + (allowedChar is not None and allowedChar == charStack[0])): + self.stream.unget(charStack[0]) + + elif charStack[0] == "#": + # Read the next character to see if it's hex or decimal + hex = False + charStack.append(self.stream.char()) + if charStack[-1] in ("x", "X"): + hex = True + charStack.append(self.stream.char()) + + # charStack[-1] should be the first digit + if (hex and charStack[-1] in hexDigits) \ + or (not hex and charStack[-1] in digits): + # At least one digit found, so consume the whole number + self.stream.unget(charStack[-1]) + output = self.consumeNumberEntity(hex) + else: + # No digits found + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "expected-numeric-entity"}) + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + + else: + # At this point in the process might have named entity. Entities + # are stored in the global variable "entities". + # + # Consume characters and compare to these to a substring of the + # entity names in the list until the substring no longer matches. + while (charStack[-1] is not EOF): + if not entitiesTrie.has_keys_with_prefix("".join(charStack)): + break + charStack.append(self.stream.char()) + + # At this point we have a string that starts with some characters + # that may match an entity + # Try to find the longest entity the string will match to take care + # of ¬i for instance. + try: + entityName = entitiesTrie.longest_prefix("".join(charStack[:-1])) + entityLength = len(entityName) + except KeyError: + entityName = None + + if entityName is not None: + if entityName[-1] != ";": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "named-entity-without-semicolon"}) + if (entityName[-1] != ";" and fromAttribute and + (charStack[entityLength] in asciiLetters or + charStack[entityLength] in digits or + charStack[entityLength] == "=")): + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + else: + output = entities[entityName] + self.stream.unget(charStack.pop()) + output += "".join(charStack[entityLength:]) + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-named-entity"}) + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + + if fromAttribute: + self.currentToken["data"][-1][1] += output + else: + if output in spaceCharacters: + tokenType = "SpaceCharacters" + else: + tokenType = "Characters" + self.tokenQueue.append({"type": tokenTypes[tokenType], "data": output}) + + def processEntityInAttribute(self, allowedChar): + """This method replaces the need for "entityInAttributeValueState". + """ + self.consumeEntity(allowedChar=allowedChar, fromAttribute=True) + + def emitCurrentToken(self): + """This method is a generic handler for emitting the tags. It also sets + the state to "data" because that's what's needed after a token has been + emitted. + """ + token = self.currentToken + # Add token to the queue to be yielded + if (token["type"] in tagTokenTypes): + token["name"] = token["name"].translate(asciiUpper2Lower) + if token["type"] == tokenTypes["EndTag"]: + if token["data"]: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "attributes-in-end-tag"}) + if token["selfClosing"]: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "self-closing-flag-on-end-tag"}) + self.tokenQueue.append(token) + self.state = self.dataState + + # Below are the various tokenizer states worked out. + def dataState(self): + data = self.stream.char() + if data == "&": + self.state = self.entityDataState + elif data == "<": + self.state = self.tagOpenState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\u0000"}) + elif data is EOF: + # Tokenization ends. + return False + elif data in spaceCharacters: + # Directly after emitting a token you switch back to the "data + # state". At that point spaceCharacters are important so they are + # emitted separately. + self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": + data + self.stream.charsUntil(spaceCharacters, True)}) + # No need to update lastFourChars here, since the first space will + # have already been appended to lastFourChars and will have broken + # any <!-- or --> sequences + else: + chars = self.stream.charsUntil(("&", "<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def entityDataState(self): + self.consumeEntity() + self.state = self.dataState + return True + + def rcdataState(self): + data = self.stream.char() + if data == "&": + self.state = self.characterReferenceInRcdata + elif data == "<": + self.state = self.rcdataLessThanSignState + elif data == EOF: + # Tokenization ends. + return False + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data in spaceCharacters: + # Directly after emitting a token you switch back to the "data + # state". At that point spaceCharacters are important so they are + # emitted separately. + self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": + data + self.stream.charsUntil(spaceCharacters, True)}) + # No need to update lastFourChars here, since the first space will + # have already been appended to lastFourChars and will have broken + # any <!-- or --> sequences + else: + chars = self.stream.charsUntil(("&", "<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def characterReferenceInRcdata(self): + self.consumeEntity() + self.state = self.rcdataState + return True + + def rawtextState(self): + data = self.stream.char() + if data == "<": + self.state = self.rawtextLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + # Tokenization ends. + return False + else: + chars = self.stream.charsUntil(("<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def scriptDataState(self): + data = self.stream.char() + if data == "<": + self.state = self.scriptDataLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + # Tokenization ends. + return False + else: + chars = self.stream.charsUntil(("<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def plaintextState(self): + data = self.stream.char() + if data == EOF: + # Tokenization ends. + return False + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + self.stream.charsUntil("\u0000")}) + return True + + def tagOpenState(self): + data = self.stream.char() + if data == "!": + self.state = self.markupDeclarationOpenState + elif data == "/": + self.state = self.closeTagOpenState + elif data in asciiLetters: + self.currentToken = {"type": tokenTypes["StartTag"], + "name": data, "data": [], + "selfClosing": False, + "selfClosingAcknowledged": False} + self.state = self.tagNameState + elif data == ">": + # XXX In theory it could be something besides a tag name. But + # do we really care? + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name-but-got-right-bracket"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<>"}) + self.state = self.dataState + elif data == "?": + # XXX In theory it could be something besides a tag name. But + # do we really care? + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name-but-got-question-mark"}) + self.stream.unget(data) + self.state = self.bogusCommentState + else: + # XXX + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.dataState + return True + + def closeTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.currentToken = {"type": tokenTypes["EndTag"], "name": data, + "data": [], "selfClosing": False} + self.state = self.tagNameState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-right-bracket"}) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-eof"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.state = self.dataState + else: + # XXX data can be _'_... + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-char", + "datavars": {"data": data}}) + self.stream.unget(data) + self.state = self.bogusCommentState + return True + + def tagNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == ">": + self.emitCurrentToken() + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-tag-name"}) + self.state = self.dataState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] += "\uFFFD" + else: + self.currentToken["name"] += data + # (Don't use charsUntil here, because tag names are + # very short and it's faster to not do anything fancy) + return True + + def rcdataLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.rcdataEndTagOpenState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rcdataEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.rcdataEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rcdataEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rawtextLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.rawtextEndTagOpenState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.rawtextState + return True + + def rawtextEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.rawtextEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.rawtextState + return True + + def rawtextEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.rawtextState + return True + + def scriptDataLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.scriptDataEndTagOpenState + elif data == "!": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<!"}) + self.state = self.scriptDataEscapeStartState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.scriptDataEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEscapeStartState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapeStartDashState + else: + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEscapeStartDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapedDashDashState + else: + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEscapedState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapedDashState + elif data == "<": + self.state = self.scriptDataEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + self.state = self.dataState + else: + chars = self.stream.charsUntil(("<", "-", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def scriptDataEscapedDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapedDashDashState + elif data == "<": + self.state = self.scriptDataEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataEscapedState + elif data == EOF: + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedDashDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + elif data == "<": + self.state = self.scriptDataEscapedLessThanSignState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) + self.state = self.scriptDataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataEscapedState + elif data == EOF: + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.scriptDataEscapedEndTagOpenState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<" + data}) + self.temporaryBuffer = data + self.state = self.scriptDataDoubleEscapeStartState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer = data + self.state = self.scriptDataEscapedEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataDoubleEscapeStartState(self): + data = self.stream.char() + if data in (spaceCharacters | frozenset(("/", ">"))): + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + if self.temporaryBuffer.lower() == "script": + self.state = self.scriptDataDoubleEscapedState + else: + self.state = self.scriptDataEscapedState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.temporaryBuffer += data + else: + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataDoubleEscapedState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataDoubleEscapedDashState + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + return True + + def scriptDataDoubleEscapedDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataDoubleEscapedDashDashState + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataDoubleEscapedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapedDashDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) + self.state = self.scriptDataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataDoubleEscapedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapedLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "/"}) + self.temporaryBuffer = "" + self.state = self.scriptDataDoubleEscapeEndState + else: + self.stream.unget(data) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapeEndState(self): + data = self.stream.char() + if data in (spaceCharacters | frozenset(("/", ">"))): + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + if self.temporaryBuffer.lower() == "script": + self.state = self.scriptDataEscapedState + else: + self.state = self.scriptDataDoubleEscapedState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.temporaryBuffer += data + else: + self.stream.unget(data) + self.state = self.scriptDataDoubleEscapedState + return True + + def beforeAttributeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data in asciiLetters: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == ">": + self.emitCurrentToken() + elif data == "/": + self.state = self.selfClosingStartTagState + elif data in ("'", '"', "=", "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "invalid-character-in-attribute-name"}) + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"].append(["\uFFFD", ""]) + self.state = self.attributeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-name-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + return True + + def attributeNameState(self): + data = self.stream.char() + leavingThisState = True + emitToken = False + if data == "=": + self.state = self.beforeAttributeValueState + elif data in asciiLetters: + self.currentToken["data"][-1][0] += data +\ + self.stream.charsUntil(asciiLetters, True) + leavingThisState = False + elif data == ">": + # XXX If we emit here the attributes are converted to a dict + # without being checked and when the code below runs we error + # because data is a dict not a list + emitToken = True + elif data in spaceCharacters: + self.state = self.afterAttributeNameState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][0] += "\uFFFD" + leavingThisState = False + elif data in ("'", '"', "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "invalid-character-in-attribute-name"}) + self.currentToken["data"][-1][0] += data + leavingThisState = False + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "eof-in-attribute-name"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][0] += data + leavingThisState = False + + if leavingThisState: + # Attributes are not dropped at this stage. That happens when the + # start tag token is emitted so values can still be safely appended + # to attributes, but we do want to report the parse error in time. + self.currentToken["data"][-1][0] = ( + self.currentToken["data"][-1][0].translate(asciiUpper2Lower)) + for name, _ in self.currentToken["data"][:-1]: + if self.currentToken["data"][-1][0] == name: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "duplicate-attribute"}) + break + # XXX Fix for above XXX + if emitToken: + self.emitCurrentToken() + return True + + def afterAttributeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data == "=": + self.state = self.beforeAttributeValueState + elif data == ">": + self.emitCurrentToken() + elif data in asciiLetters: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"].append(["\uFFFD", ""]) + self.state = self.attributeNameState + elif data in ("'", '"', "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "invalid-character-after-attribute-name"}) + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-end-of-tag-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + return True + + def beforeAttributeValueState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data == "\"": + self.state = self.attributeValueDoubleQuotedState + elif data == "&": + self.state = self.attributeValueUnQuotedState + self.stream.unget(data) + elif data == "'": + self.state = self.attributeValueSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-value-but-got-right-bracket"}) + self.emitCurrentToken() + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + self.state = self.attributeValueUnQuotedState + elif data in ("=", "<", "`"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "equals-in-unquoted-attribute-value"}) + self.currentToken["data"][-1][1] += data + self.state = self.attributeValueUnQuotedState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-value-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data + self.state = self.attributeValueUnQuotedState + return True + + def attributeValueDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterAttributeValueState + elif data == "&": + self.processEntityInAttribute('"') + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-double-quote"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data +\ + self.stream.charsUntil(("\"", "&", "\u0000")) + return True + + def attributeValueSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterAttributeValueState + elif data == "&": + self.processEntityInAttribute("'") + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-single-quote"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data +\ + self.stream.charsUntil(("'", "&", "\u0000")) + return True + + def attributeValueUnQuotedState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == "&": + self.processEntityInAttribute(">") + elif data == ">": + self.emitCurrentToken() + elif data in ('"', "'", "=", "<", "`"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-in-unquoted-attribute-value"}) + self.currentToken["data"][-1][1] += data + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-no-quotes"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data + self.stream.charsUntil( + frozenset(("&", ">", '"', "'", "=", "<", "`", "\u0000")) | spaceCharacters) + return True + + def afterAttributeValueState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == ">": + self.emitCurrentToken() + elif data == "/": + self.state = self.selfClosingStartTagState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-EOF-after-attribute-value"}) + self.stream.unget(data) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-after-attribute-value"}) + self.stream.unget(data) + self.state = self.beforeAttributeNameState + return True + + def selfClosingStartTagState(self): + data = self.stream.char() + if data == ">": + self.currentToken["selfClosing"] = True + self.emitCurrentToken() + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "unexpected-EOF-after-solidus-in-tag"}) + self.stream.unget(data) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-after-solidus-in-tag"}) + self.stream.unget(data) + self.state = self.beforeAttributeNameState + return True + + def bogusCommentState(self): + # Make a new comment token and give it as value all the characters + # until the first > or EOF (charsUntil checks for EOF automatically) + # and emit it. + data = self.stream.charsUntil(">") + data = data.replace("\u0000", "\uFFFD") + self.tokenQueue.append( + {"type": tokenTypes["Comment"], "data": data}) + + # Eat the character directly after the bogus comment which is either a + # ">" or an EOF. + self.stream.char() + self.state = self.dataState + return True + + def markupDeclarationOpenState(self): + charStack = [self.stream.char()] + if charStack[-1] == "-": + charStack.append(self.stream.char()) + if charStack[-1] == "-": + self.currentToken = {"type": tokenTypes["Comment"], "data": ""} + self.state = self.commentStartState + return True + elif charStack[-1] in ('d', 'D'): + matched = True + for expected in (('o', 'O'), ('c', 'C'), ('t', 'T'), + ('y', 'Y'), ('p', 'P'), ('e', 'E')): + charStack.append(self.stream.char()) + if charStack[-1] not in expected: + matched = False + break + if matched: + self.currentToken = {"type": tokenTypes["Doctype"], + "name": "", + "publicId": None, "systemId": None, + "correct": True} + self.state = self.doctypeState + return True + elif (charStack[-1] == "[" and + self.parser is not None and + self.parser.tree.openElements and + self.parser.tree.openElements[-1].namespace != self.parser.tree.defaultNamespace): + matched = True + for expected in ["C", "D", "A", "T", "A", "["]: + charStack.append(self.stream.char()) + if charStack[-1] != expected: + matched = False + break + if matched: + self.state = self.cdataSectionState + return True + + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-dashes-or-doctype"}) + + while charStack: + self.stream.unget(charStack.pop()) + self.state = self.bogusCommentState + return True + + def commentStartState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentStartDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "incorrect-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += data + self.state = self.commentState + return True + + def commentStartDashState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "-\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "incorrect-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "-" + data + self.state = self.commentState + return True + + def commentState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += data + \ + self.stream.charsUntil(("-", "\u0000")) + return True + + def commentEndDashState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "-\uFFFD" + self.state = self.commentState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-end-dash"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "-" + data + self.state = self.commentState + return True + + def commentEndState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "--\uFFFD" + self.state = self.commentState + elif data == "!": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-bang-after-double-dash-in-comment"}) + self.state = self.commentEndBangState + elif data == "-": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-dash-after-double-dash-in-comment"}) + self.currentToken["data"] += data + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-double-dash"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + # XXX + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-comment"}) + self.currentToken["data"] += "--" + data + self.state = self.commentState + return True + + def commentEndBangState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "-": + self.currentToken["data"] += "--!" + self.state = self.commentEndDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "--!\uFFFD" + self.state = self.commentState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-end-bang-state"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "--!" + data + self.state = self.commentState + return True + + def doctypeState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-eof"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "need-space-after-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypeNameState + return True + + def beforeDoctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-right-bracket"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] = "\uFFFD" + self.state = self.doctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-eof"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["name"] = data + self.state = self.doctypeNameState + return True + + def doctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.state = self.afterDoctypeNameState + elif data == ">": + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] += "\uFFFD" + self.state = self.doctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype-name"}) + self.currentToken["correct"] = False + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["name"] += data + return True + + def afterDoctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.currentToken["correct"] = False + self.stream.unget(data) + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + if data in ("p", "P"): + matched = True + for expected in (("u", "U"), ("b", "B"), ("l", "L"), + ("i", "I"), ("c", "C")): + data = self.stream.char() + if data not in expected: + matched = False + break + if matched: + self.state = self.afterDoctypePublicKeywordState + return True + elif data in ("s", "S"): + matched = True + for expected in (("y", "Y"), ("s", "S"), ("t", "T"), + ("e", "E"), ("m", "M")): + data = self.stream.char() + if data not in expected: + matched = False + break + if matched: + self.state = self.afterDoctypeSystemKeywordState + return True + + # All the characters read before the current 'data' will be + # [a-zA-Z], so they're garbage in the bogus doctype and can be + # discarded; only the latest character might be '>' or EOF + # and needs to be ungetted + self.stream.unget(data) + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-space-or-right-bracket-in-doctype", "datavars": + {"data": data}}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + + return True + + def afterDoctypePublicKeywordState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypePublicIdentifierState + elif data in ("'", '"'): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypePublicIdentifierState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.stream.unget(data) + self.state = self.beforeDoctypePublicIdentifierState + return True + + def beforeDoctypePublicIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == "\"": + self.currentToken["publicId"] = "" + self.state = self.doctypePublicIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["publicId"] = "" + self.state = self.doctypePublicIdentifierSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def doctypePublicIdentifierDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterDoctypePublicIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["publicId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["publicId"] += data + return True + + def doctypePublicIdentifierSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterDoctypePublicIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["publicId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["publicId"] += data + return True + + def afterDoctypePublicIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.betweenDoctypePublicAndSystemIdentifiersState + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == '"': + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def betweenDoctypePublicAndSystemIdentifiersState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == '"': + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def afterDoctypeSystemKeywordState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypeSystemIdentifierState + elif data in ("'", '"'): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypeSystemIdentifierState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.stream.unget(data) + self.state = self.beforeDoctypeSystemIdentifierState + return True + + def beforeDoctypeSystemIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == "\"": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def doctypeSystemIdentifierDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterDoctypeSystemIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["systemId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["systemId"] += data + return True + + def doctypeSystemIdentifierSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterDoctypeSystemIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["systemId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["systemId"] += data + return True + + def afterDoctypeSystemIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.state = self.bogusDoctypeState + return True + + def bogusDoctypeState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + # XXX EMIT + self.stream.unget(data) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + pass + return True + + def cdataSectionState(self): + data = [] + while True: + data.append(self.stream.charsUntil("]")) + data.append(self.stream.charsUntil(">")) + char = self.stream.char() + if char == EOF: + break + else: + assert char == ">" + if data[-1][-2:] == "]]": + data[-1] = data[-1][:-2] + break + else: + data.append(char) + + data = "".join(data) # pylint:disable=redefined-variable-type + # Deal with null here rather than in the parser + nullCount = data.count("\u0000") + if nullCount > 0: + for _ in range(nullCount): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + data = data.replace("\u0000", "\uFFFD") + if data: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": data}) + self.state = self.dataState + return True diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__init__.py new file mode 100644 index 0000000..a5ba4bf --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__init__.py @@ -0,0 +1,14 @@ +from __future__ import absolute_import, division, unicode_literals + +from .py import Trie as PyTrie + +Trie = PyTrie + +# pylint:disable=wrong-import-position +try: + from .datrie import Trie as DATrie +except ImportError: + pass +else: + Trie = DATrie +# pylint:enable=wrong-import-position diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/_base.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/_base.py new file mode 100644 index 0000000..a1158bb --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/_base.py @@ -0,0 +1,37 @@ +from __future__ import absolute_import, division, unicode_literals + +from collections import Mapping + + +class Trie(Mapping): + """Abstract base class for tries""" + + def keys(self, prefix=None): + # pylint:disable=arguments-differ + keys = super(Trie, self).keys() + + if prefix is None: + return set(keys) + + return {x for x in keys if x.startswith(prefix)} + + def has_keys_with_prefix(self, prefix): + for key in self.keys(): + if key.startswith(prefix): + return True + + return False + + def longest_prefix(self, prefix): + if prefix in self: + return prefix + + for i in range(1, len(prefix) + 1): + if prefix[:-i] in self: + return prefix[:-i] + + raise KeyError(prefix) + + def longest_prefix_item(self, prefix): + lprefix = self.longest_prefix(prefix) + return (lprefix, self[lprefix]) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/datrie.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/datrie.py new file mode 100644 index 0000000..e2e5f86 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/datrie.py @@ -0,0 +1,44 @@ +from __future__ import absolute_import, division, unicode_literals + +from datrie import Trie as DATrie +from pip._vendor.six import text_type + +from ._base import Trie as ABCTrie + + +class Trie(ABCTrie): + def __init__(self, data): + chars = set() + for key in data.keys(): + if not isinstance(key, text_type): + raise TypeError("All keys must be strings") + for char in key: + chars.add(char) + + self._data = DATrie("".join(chars)) + for key, value in data.items(): + self._data[key] = value + + def __contains__(self, key): + return key in self._data + + def __len__(self): + return len(self._data) + + def __iter__(self): + raise NotImplementedError() + + def __getitem__(self, key): + return self._data[key] + + def keys(self, prefix=None): + return self._data.keys(prefix) + + def has_keys_with_prefix(self, prefix): + return self._data.has_keys_with_prefix(prefix) + + def longest_prefix(self, prefix): + return self._data.longest_prefix(prefix) + + def longest_prefix_item(self, prefix): + return self._data.longest_prefix_item(prefix) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/py.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/py.py new file mode 100644 index 0000000..c178b21 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/py.py @@ -0,0 +1,67 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from bisect import bisect_left + +from ._base import Trie as ABCTrie + + +class Trie(ABCTrie): + def __init__(self, data): + if not all(isinstance(x, text_type) for x in data.keys()): + raise TypeError("All keys must be strings") + + self._data = data + self._keys = sorted(data.keys()) + self._cachestr = "" + self._cachepoints = (0, len(data)) + + def __contains__(self, key): + return key in self._data + + def __len__(self): + return len(self._data) + + def __iter__(self): + return iter(self._data) + + def __getitem__(self, key): + return self._data[key] + + def keys(self, prefix=None): + if prefix is None or prefix == "" or not self._keys: + return set(self._keys) + + if prefix.startswith(self._cachestr): + lo, hi = self._cachepoints + start = i = bisect_left(self._keys, prefix, lo, hi) + else: + start = i = bisect_left(self._keys, prefix) + + keys = set() + if start == len(self._keys): + return keys + + while self._keys[i].startswith(prefix): + keys.add(self._keys[i]) + i += 1 + + self._cachestr = prefix + self._cachepoints = (start, i) + + return keys + + def has_keys_with_prefix(self, prefix): + if prefix in self._data: + return True + + if prefix.startswith(self._cachestr): + lo, hi = self._cachepoints + i = bisect_left(self._keys, prefix, lo, hi) + else: + i = bisect_left(self._keys, prefix) + + if i == len(self._keys): + return False + + return self._keys[i].startswith(prefix) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_utils.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_utils.py new file mode 100644 index 0000000..0703afb --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_utils.py @@ -0,0 +1,124 @@ +from __future__ import absolute_import, division, unicode_literals + +from types import ModuleType + +from pip._vendor.six import text_type + +try: + import xml.etree.cElementTree as default_etree +except ImportError: + import xml.etree.ElementTree as default_etree + + +__all__ = ["default_etree", "MethodDispatcher", "isSurrogatePair", + "surrogatePairToCodepoint", "moduleFactoryFactory", + "supports_lone_surrogates"] + + +# Platforms not supporting lone surrogates (\uD800-\uDFFF) should be +# caught by the below test. In general this would be any platform +# using UTF-16 as its encoding of unicode strings, such as +# Jython. This is because UTF-16 itself is based on the use of such +# surrogates, and there is no mechanism to further escape such +# escapes. +try: + _x = eval('"\\uD800"') # pylint:disable=eval-used + if not isinstance(_x, text_type): + # We need this with u"" because of http://bugs.jython.org/issue2039 + _x = eval('u"\\uD800"') # pylint:disable=eval-used + assert isinstance(_x, text_type) +except: # pylint:disable=bare-except + supports_lone_surrogates = False +else: + supports_lone_surrogates = True + + +class MethodDispatcher(dict): + """Dict with 2 special properties: + + On initiation, keys that are lists, sets or tuples are converted to + multiple keys so accessing any one of the items in the original + list-like object returns the matching value + + md = MethodDispatcher({("foo", "bar"):"baz"}) + md["foo"] == "baz" + + A default value which can be set through the default attribute. + """ + + def __init__(self, items=()): + # Using _dictEntries instead of directly assigning to self is about + # twice as fast. Please do careful performance testing before changing + # anything here. + _dictEntries = [] + for name, value in items: + if isinstance(name, (list, tuple, frozenset, set)): + for item in name: + _dictEntries.append((item, value)) + else: + _dictEntries.append((name, value)) + dict.__init__(self, _dictEntries) + assert len(self) == len(_dictEntries) + self.default = None + + def __getitem__(self, key): + return dict.get(self, key, self.default) + + +# Some utility functions to deal with weirdness around UCS2 vs UCS4 +# python builds + +def isSurrogatePair(data): + return (len(data) == 2 and + ord(data[0]) >= 0xD800 and ord(data[0]) <= 0xDBFF and + ord(data[1]) >= 0xDC00 and ord(data[1]) <= 0xDFFF) + + +def surrogatePairToCodepoint(data): + char_val = (0x10000 + (ord(data[0]) - 0xD800) * 0x400 + + (ord(data[1]) - 0xDC00)) + return char_val + +# Module Factory Factory (no, this isn't Java, I know) +# Here to stop this being duplicated all over the place. + + +def moduleFactoryFactory(factory): + moduleCache = {} + + def moduleFactory(baseModule, *args, **kwargs): + if isinstance(ModuleType.__name__, type("")): + name = "_%s_factory" % baseModule.__name__ + else: + name = b"_%s_factory" % baseModule.__name__ + + kwargs_tuple = tuple(kwargs.items()) + + try: + return moduleCache[name][args][kwargs_tuple] + except KeyError: + mod = ModuleType(name) + objs = factory(baseModule, *args, **kwargs) + mod.__dict__.update(objs) + if "name" not in moduleCache: + moduleCache[name] = {} + if "args" not in moduleCache[name]: + moduleCache[name][args] = {} + if "kwargs" not in moduleCache[name][args]: + moduleCache[name][args][kwargs_tuple] = {} + moduleCache[name][args][kwargs_tuple] = mod + return mod + + return moduleFactory + + +def memoize(func): + cache = {} + + def wrapped(*args, **kwargs): + key = (tuple(args), tuple(kwargs.items())) + if key not in cache: + cache[key] = func(*args, **kwargs) + return cache[key] + + return wrapped diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/constants.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/constants.py new file mode 100644 index 0000000..1ff8041 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/constants.py @@ -0,0 +1,2947 @@ +from __future__ import absolute_import, division, unicode_literals + +import string + +EOF = None + +E = { + "null-character": + "Null character in input stream, replaced with U+FFFD.", + "invalid-codepoint": + "Invalid codepoint in stream.", + "incorrectly-placed-solidus": + "Solidus (/) incorrectly placed in tag.", + "incorrect-cr-newline-entity": + "Incorrect CR newline entity, replaced with LF.", + "illegal-windows-1252-entity": + "Entity used with illegal number (windows-1252 reference).", + "cant-convert-numeric-entity": + "Numeric entity couldn't be converted to character " + "(codepoint U+%(charAsInt)08x).", + "illegal-codepoint-for-numeric-entity": + "Numeric entity represents an illegal codepoint: " + "U+%(charAsInt)08x.", + "numeric-entity-without-semicolon": + "Numeric entity didn't end with ';'.", + "expected-numeric-entity-but-got-eof": + "Numeric entity expected. Got end of file instead.", + "expected-numeric-entity": + "Numeric entity expected but none found.", + "named-entity-without-semicolon": + "Named entity didn't end with ';'.", + "expected-named-entity": + "Named entity expected. Got none.", + "attributes-in-end-tag": + "End tag contains unexpected attributes.", + 'self-closing-flag-on-end-tag': + "End tag contains unexpected self-closing flag.", + "expected-tag-name-but-got-right-bracket": + "Expected tag name. Got '>' instead.", + "expected-tag-name-but-got-question-mark": + "Expected tag name. Got '?' instead. (HTML doesn't " + "support processing instructions.)", + "expected-tag-name": + "Expected tag name. Got something else instead", + "expected-closing-tag-but-got-right-bracket": + "Expected closing tag. Got '>' instead. Ignoring '</>'.", + "expected-closing-tag-but-got-eof": + "Expected closing tag. Unexpected end of file.", + "expected-closing-tag-but-got-char": + "Expected closing tag. Unexpected character '%(data)s' found.", + "eof-in-tag-name": + "Unexpected end of file in the tag name.", + "expected-attribute-name-but-got-eof": + "Unexpected end of file. Expected attribute name instead.", + "eof-in-attribute-name": + "Unexpected end of file in attribute name.", + "invalid-character-in-attribute-name": + "Invalid character in attribute name", + "duplicate-attribute": + "Dropped duplicate attribute on tag.", + "expected-end-of-tag-name-but-got-eof": + "Unexpected end of file. Expected = or end of tag.", + "expected-attribute-value-but-got-eof": + "Unexpected end of file. Expected attribute value.", + "expected-attribute-value-but-got-right-bracket": + "Expected attribute value. Got '>' instead.", + 'equals-in-unquoted-attribute-value': + "Unexpected = in unquoted attribute", + 'unexpected-character-in-unquoted-attribute-value': + "Unexpected character in unquoted attribute", + "invalid-character-after-attribute-name": + "Unexpected character after attribute name.", + "unexpected-character-after-attribute-value": + "Unexpected character after attribute value.", + "eof-in-attribute-value-double-quote": + "Unexpected end of file in attribute value (\").", + "eof-in-attribute-value-single-quote": + "Unexpected end of file in attribute value (').", + "eof-in-attribute-value-no-quotes": + "Unexpected end of file in attribute value.", + "unexpected-EOF-after-solidus-in-tag": + "Unexpected end of file in tag. Expected >", + "unexpected-character-after-solidus-in-tag": + "Unexpected character after / in tag. Expected >", + "expected-dashes-or-doctype": + "Expected '--' or 'DOCTYPE'. Not found.", + "unexpected-bang-after-double-dash-in-comment": + "Unexpected ! after -- in comment", + "unexpected-space-after-double-dash-in-comment": + "Unexpected space after -- in comment", + "incorrect-comment": + "Incorrect comment.", + "eof-in-comment": + "Unexpected end of file in comment.", + "eof-in-comment-end-dash": + "Unexpected end of file in comment (-)", + "unexpected-dash-after-double-dash-in-comment": + "Unexpected '-' after '--' found in comment.", + "eof-in-comment-double-dash": + "Unexpected end of file in comment (--).", + "eof-in-comment-end-space-state": + "Unexpected end of file in comment.", + "eof-in-comment-end-bang-state": + "Unexpected end of file in comment.", + "unexpected-char-in-comment": + "Unexpected character in comment found.", + "need-space-after-doctype": + "No space after literal string 'DOCTYPE'.", + "expected-doctype-name-but-got-right-bracket": + "Unexpected > character. Expected DOCTYPE name.", + "expected-doctype-name-but-got-eof": + "Unexpected end of file. Expected DOCTYPE name.", + "eof-in-doctype-name": + "Unexpected end of file in DOCTYPE name.", + "eof-in-doctype": + "Unexpected end of file in DOCTYPE.", + "expected-space-or-right-bracket-in-doctype": + "Expected space or '>'. Got '%(data)s'", + "unexpected-end-of-doctype": + "Unexpected end of DOCTYPE.", + "unexpected-char-in-doctype": + "Unexpected character in DOCTYPE.", + "eof-in-innerhtml": + "XXX innerHTML EOF", + "unexpected-doctype": + "Unexpected DOCTYPE. Ignored.", + "non-html-root": + "html needs to be the first start tag.", + "expected-doctype-but-got-eof": + "Unexpected End of file. Expected DOCTYPE.", + "unknown-doctype": + "Erroneous DOCTYPE.", + "expected-doctype-but-got-chars": + "Unexpected non-space characters. Expected DOCTYPE.", + "expected-doctype-but-got-start-tag": + "Unexpected start tag (%(name)s). Expected DOCTYPE.", + "expected-doctype-but-got-end-tag": + "Unexpected end tag (%(name)s). Expected DOCTYPE.", + "end-tag-after-implied-root": + "Unexpected end tag (%(name)s) after the (implied) root element.", + "expected-named-closing-tag-but-got-eof": + "Unexpected end of file. Expected end tag (%(name)s).", + "two-heads-are-not-better-than-one": + "Unexpected start tag head in existing head. Ignored.", + "unexpected-end-tag": + "Unexpected end tag (%(name)s). Ignored.", + "unexpected-start-tag-out-of-my-head": + "Unexpected start tag (%(name)s) that can be in head. Moved.", + "unexpected-start-tag": + "Unexpected start tag (%(name)s).", + "missing-end-tag": + "Missing end tag (%(name)s).", + "missing-end-tags": + "Missing end tags (%(name)s).", + "unexpected-start-tag-implies-end-tag": + "Unexpected start tag (%(startName)s) " + "implies end tag (%(endName)s).", + "unexpected-start-tag-treated-as": + "Unexpected start tag (%(originalName)s). Treated as %(newName)s.", + "deprecated-tag": + "Unexpected start tag %(name)s. Don't use it!", + "unexpected-start-tag-ignored": + "Unexpected start tag %(name)s. Ignored.", + "expected-one-end-tag-but-got-another": + "Unexpected end tag (%(gotName)s). " + "Missing end tag (%(expectedName)s).", + "end-tag-too-early": + "End tag (%(name)s) seen too early. Expected other end tag.", + "end-tag-too-early-named": + "Unexpected end tag (%(gotName)s). Expected end tag (%(expectedName)s).", + "end-tag-too-early-ignored": + "End tag (%(name)s) seen too early. Ignored.", + "adoption-agency-1.1": + "End tag (%(name)s) violates step 1, " + "paragraph 1 of the adoption agency algorithm.", + "adoption-agency-1.2": + "End tag (%(name)s) violates step 1, " + "paragraph 2 of the adoption agency algorithm.", + "adoption-agency-1.3": + "End tag (%(name)s) violates step 1, " + "paragraph 3 of the adoption agency algorithm.", + "adoption-agency-4.4": + "End tag (%(name)s) violates step 4, " + "paragraph 4 of the adoption agency algorithm.", + "unexpected-end-tag-treated-as": + "Unexpected end tag (%(originalName)s). Treated as %(newName)s.", + "no-end-tag": + "This element (%(name)s) has no end tag.", + "unexpected-implied-end-tag-in-table": + "Unexpected implied end tag (%(name)s) in the table phase.", + "unexpected-implied-end-tag-in-table-body": + "Unexpected implied end tag (%(name)s) in the table body phase.", + "unexpected-char-implies-table-voodoo": + "Unexpected non-space characters in " + "table context caused voodoo mode.", + "unexpected-hidden-input-in-table": + "Unexpected input with type hidden in table context.", + "unexpected-form-in-table": + "Unexpected form in table context.", + "unexpected-start-tag-implies-table-voodoo": + "Unexpected start tag (%(name)s) in " + "table context caused voodoo mode.", + "unexpected-end-tag-implies-table-voodoo": + "Unexpected end tag (%(name)s) in " + "table context caused voodoo mode.", + "unexpected-cell-in-table-body": + "Unexpected table cell start tag (%(name)s) " + "in the table body phase.", + "unexpected-cell-end-tag": + "Got table cell end tag (%(name)s) " + "while required end tags are missing.", + "unexpected-end-tag-in-table-body": + "Unexpected end tag (%(name)s) in the table body phase. Ignored.", + "unexpected-implied-end-tag-in-table-row": + "Unexpected implied end tag (%(name)s) in the table row phase.", + "unexpected-end-tag-in-table-row": + "Unexpected end tag (%(name)s) in the table row phase. Ignored.", + "unexpected-select-in-select": + "Unexpected select start tag in the select phase " + "treated as select end tag.", + "unexpected-input-in-select": + "Unexpected input start tag in the select phase.", + "unexpected-start-tag-in-select": + "Unexpected start tag token (%(name)s in the select phase. " + "Ignored.", + "unexpected-end-tag-in-select": + "Unexpected end tag (%(name)s) in the select phase. Ignored.", + "unexpected-table-element-start-tag-in-select-in-table": + "Unexpected table element start tag (%(name)s) in the select in table phase.", + "unexpected-table-element-end-tag-in-select-in-table": + "Unexpected table element end tag (%(name)s) in the select in table phase.", + "unexpected-char-after-body": + "Unexpected non-space characters in the after body phase.", + "unexpected-start-tag-after-body": + "Unexpected start tag token (%(name)s)" + " in the after body phase.", + "unexpected-end-tag-after-body": + "Unexpected end tag token (%(name)s)" + " in the after body phase.", + "unexpected-char-in-frameset": + "Unexpected characters in the frameset phase. Characters ignored.", + "unexpected-start-tag-in-frameset": + "Unexpected start tag token (%(name)s)" + " in the frameset phase. Ignored.", + "unexpected-frameset-in-frameset-innerhtml": + "Unexpected end tag token (frameset) " + "in the frameset phase (innerHTML).", + "unexpected-end-tag-in-frameset": + "Unexpected end tag token (%(name)s)" + " in the frameset phase. Ignored.", + "unexpected-char-after-frameset": + "Unexpected non-space characters in the " + "after frameset phase. Ignored.", + "unexpected-start-tag-after-frameset": + "Unexpected start tag (%(name)s)" + " in the after frameset phase. Ignored.", + "unexpected-end-tag-after-frameset": + "Unexpected end tag (%(name)s)" + " in the after frameset phase. Ignored.", + "unexpected-end-tag-after-body-innerhtml": + "Unexpected end tag after body(innerHtml)", + "expected-eof-but-got-char": + "Unexpected non-space characters. Expected end of file.", + "expected-eof-but-got-start-tag": + "Unexpected start tag (%(name)s)" + ". Expected end of file.", + "expected-eof-but-got-end-tag": + "Unexpected end tag (%(name)s)" + ". Expected end of file.", + "eof-in-table": + "Unexpected end of file. Expected table content.", + "eof-in-select": + "Unexpected end of file. Expected select content.", + "eof-in-frameset": + "Unexpected end of file. Expected frameset content.", + "eof-in-script-in-script": + "Unexpected end of file. Expected script content.", + "eof-in-foreign-lands": + "Unexpected end of file. Expected foreign content", + "non-void-element-with-trailing-solidus": + "Trailing solidus not allowed on element %(name)s", + "unexpected-html-element-in-foreign-content": + "Element %(name)s not allowed in a non-html context", + "unexpected-end-tag-before-html": + "Unexpected end tag (%(name)s) before html.", + "unexpected-inhead-noscript-tag": + "Element %(name)s not allowed in a inhead-noscript context", + "eof-in-head-noscript": + "Unexpected end of file. Expected inhead-noscript content", + "char-in-head-noscript": + "Unexpected non-space character. Expected inhead-noscript content", + "XXX-undefined-error": + "Undefined error (this sucks and should be fixed)", +} + +namespaces = { + "html": "http://www.w3.org/1999/xhtml", + "mathml": "http://www.w3.org/1998/Math/MathML", + "svg": "http://www.w3.org/2000/svg", + "xlink": "http://www.w3.org/1999/xlink", + "xml": "http://www.w3.org/XML/1998/namespace", + "xmlns": "http://www.w3.org/2000/xmlns/" +} + +scopingElements = frozenset([ + (namespaces["html"], "applet"), + (namespaces["html"], "caption"), + (namespaces["html"], "html"), + (namespaces["html"], "marquee"), + (namespaces["html"], "object"), + (namespaces["html"], "table"), + (namespaces["html"], "td"), + (namespaces["html"], "th"), + (namespaces["mathml"], "mi"), + (namespaces["mathml"], "mo"), + (namespaces["mathml"], "mn"), + (namespaces["mathml"], "ms"), + (namespaces["mathml"], "mtext"), + (namespaces["mathml"], "annotation-xml"), + (namespaces["svg"], "foreignObject"), + (namespaces["svg"], "desc"), + (namespaces["svg"], "title"), +]) + +formattingElements = frozenset([ + (namespaces["html"], "a"), + (namespaces["html"], "b"), + (namespaces["html"], "big"), + (namespaces["html"], "code"), + (namespaces["html"], "em"), + (namespaces["html"], "font"), + (namespaces["html"], "i"), + (namespaces["html"], "nobr"), + (namespaces["html"], "s"), + (namespaces["html"], "small"), + (namespaces["html"], "strike"), + (namespaces["html"], "strong"), + (namespaces["html"], "tt"), + (namespaces["html"], "u") +]) + +specialElements = frozenset([ + (namespaces["html"], "address"), + (namespaces["html"], "applet"), + (namespaces["html"], "area"), + (namespaces["html"], "article"), + (namespaces["html"], "aside"), + (namespaces["html"], "base"), + (namespaces["html"], "basefont"), + (namespaces["html"], "bgsound"), + (namespaces["html"], "blockquote"), + (namespaces["html"], "body"), + (namespaces["html"], "br"), + (namespaces["html"], "button"), + (namespaces["html"], "caption"), + (namespaces["html"], "center"), + (namespaces["html"], "col"), + (namespaces["html"], "colgroup"), + (namespaces["html"], "command"), + (namespaces["html"], "dd"), + (namespaces["html"], "details"), + (namespaces["html"], "dir"), + (namespaces["html"], "div"), + (namespaces["html"], "dl"), + (namespaces["html"], "dt"), + (namespaces["html"], "embed"), + (namespaces["html"], "fieldset"), + (namespaces["html"], "figure"), + (namespaces["html"], "footer"), + (namespaces["html"], "form"), + (namespaces["html"], "frame"), + (namespaces["html"], "frameset"), + (namespaces["html"], "h1"), + (namespaces["html"], "h2"), + (namespaces["html"], "h3"), + (namespaces["html"], "h4"), + (namespaces["html"], "h5"), + (namespaces["html"], "h6"), + (namespaces["html"], "head"), + (namespaces["html"], "header"), + (namespaces["html"], "hr"), + (namespaces["html"], "html"), + (namespaces["html"], "iframe"), + # Note that image is commented out in the spec as "this isn't an + # element that can end up on the stack, so it doesn't matter," + (namespaces["html"], "image"), + (namespaces["html"], "img"), + (namespaces["html"], "input"), + (namespaces["html"], "isindex"), + (namespaces["html"], "li"), + (namespaces["html"], "link"), + (namespaces["html"], "listing"), + (namespaces["html"], "marquee"), + (namespaces["html"], "menu"), + (namespaces["html"], "meta"), + (namespaces["html"], "nav"), + (namespaces["html"], "noembed"), + (namespaces["html"], "noframes"), + (namespaces["html"], "noscript"), + (namespaces["html"], "object"), + (namespaces["html"], "ol"), + (namespaces["html"], "p"), + (namespaces["html"], "param"), + (namespaces["html"], "plaintext"), + (namespaces["html"], "pre"), + (namespaces["html"], "script"), + (namespaces["html"], "section"), + (namespaces["html"], "select"), + (namespaces["html"], "style"), + (namespaces["html"], "table"), + (namespaces["html"], "tbody"), + (namespaces["html"], "td"), + (namespaces["html"], "textarea"), + (namespaces["html"], "tfoot"), + (namespaces["html"], "th"), + (namespaces["html"], "thead"), + (namespaces["html"], "title"), + (namespaces["html"], "tr"), + (namespaces["html"], "ul"), + (namespaces["html"], "wbr"), + (namespaces["html"], "xmp"), + (namespaces["svg"], "foreignObject") +]) + +htmlIntegrationPointElements = frozenset([ + (namespaces["mathml"], "annotation-xml"), + (namespaces["svg"], "foreignObject"), + (namespaces["svg"], "desc"), + (namespaces["svg"], "title") +]) + +mathmlTextIntegrationPointElements = frozenset([ + (namespaces["mathml"], "mi"), + (namespaces["mathml"], "mo"), + (namespaces["mathml"], "mn"), + (namespaces["mathml"], "ms"), + (namespaces["mathml"], "mtext") +]) + +adjustSVGAttributes = { + "attributename": "attributeName", + "attributetype": "attributeType", + "basefrequency": "baseFrequency", + "baseprofile": "baseProfile", + "calcmode": "calcMode", + "clippathunits": "clipPathUnits", + "contentscripttype": "contentScriptType", + "contentstyletype": "contentStyleType", + "diffuseconstant": "diffuseConstant", + "edgemode": "edgeMode", + "externalresourcesrequired": "externalResourcesRequired", + "filterres": "filterRes", + "filterunits": "filterUnits", + "glyphref": "glyphRef", + "gradienttransform": "gradientTransform", + "gradientunits": "gradientUnits", + "kernelmatrix": "kernelMatrix", + "kernelunitlength": "kernelUnitLength", + "keypoints": "keyPoints", + "keysplines": "keySplines", + "keytimes": "keyTimes", + "lengthadjust": "lengthAdjust", + "limitingconeangle": "limitingConeAngle", + "markerheight": "markerHeight", + "markerunits": "markerUnits", + "markerwidth": "markerWidth", + "maskcontentunits": "maskContentUnits", + "maskunits": "maskUnits", + "numoctaves": "numOctaves", + "pathlength": "pathLength", + "patterncontentunits": "patternContentUnits", + "patterntransform": "patternTransform", + "patternunits": "patternUnits", + "pointsatx": "pointsAtX", + "pointsaty": "pointsAtY", + "pointsatz": "pointsAtZ", + "preservealpha": "preserveAlpha", + "preserveaspectratio": "preserveAspectRatio", + "primitiveunits": "primitiveUnits", + "refx": "refX", + "refy": "refY", + "repeatcount": "repeatCount", + "repeatdur": "repeatDur", + "requiredextensions": "requiredExtensions", + "requiredfeatures": "requiredFeatures", + "specularconstant": "specularConstant", + "specularexponent": "specularExponent", + "spreadmethod": "spreadMethod", + "startoffset": "startOffset", + "stddeviation": "stdDeviation", + "stitchtiles": "stitchTiles", + "surfacescale": "surfaceScale", + "systemlanguage": "systemLanguage", + "tablevalues": "tableValues", + "targetx": "targetX", + "targety": "targetY", + "textlength": "textLength", + "viewbox": "viewBox", + "viewtarget": "viewTarget", + "xchannelselector": "xChannelSelector", + "ychannelselector": "yChannelSelector", + "zoomandpan": "zoomAndPan" +} + +adjustMathMLAttributes = {"definitionurl": "definitionURL"} + +adjustForeignAttributes = { + "xlink:actuate": ("xlink", "actuate", namespaces["xlink"]), + "xlink:arcrole": ("xlink", "arcrole", namespaces["xlink"]), + "xlink:href": ("xlink", "href", namespaces["xlink"]), + "xlink:role": ("xlink", "role", namespaces["xlink"]), + "xlink:show": ("xlink", "show", namespaces["xlink"]), + "xlink:title": ("xlink", "title", namespaces["xlink"]), + "xlink:type": ("xlink", "type", namespaces["xlink"]), + "xml:base": ("xml", "base", namespaces["xml"]), + "xml:lang": ("xml", "lang", namespaces["xml"]), + "xml:space": ("xml", "space", namespaces["xml"]), + "xmlns": (None, "xmlns", namespaces["xmlns"]), + "xmlns:xlink": ("xmlns", "xlink", namespaces["xmlns"]) +} + +unadjustForeignAttributes = dict([((ns, local), qname) for qname, (prefix, local, ns) in + adjustForeignAttributes.items()]) + +spaceCharacters = frozenset([ + "\t", + "\n", + "\u000C", + " ", + "\r" +]) + +tableInsertModeElements = frozenset([ + "table", + "tbody", + "tfoot", + "thead", + "tr" +]) + +asciiLowercase = frozenset(string.ascii_lowercase) +asciiUppercase = frozenset(string.ascii_uppercase) +asciiLetters = frozenset(string.ascii_letters) +digits = frozenset(string.digits) +hexDigits = frozenset(string.hexdigits) + +asciiUpper2Lower = dict([(ord(c), ord(c.lower())) + for c in string.ascii_uppercase]) + +# Heading elements need to be ordered +headingElements = ( + "h1", + "h2", + "h3", + "h4", + "h5", + "h6" +) + +voidElements = frozenset([ + "base", + "command", + "event-source", + "link", + "meta", + "hr", + "br", + "img", + "embed", + "param", + "area", + "col", + "input", + "source", + "track" +]) + +cdataElements = frozenset(['title', 'textarea']) + +rcdataElements = frozenset([ + 'style', + 'script', + 'xmp', + 'iframe', + 'noembed', + 'noframes', + 'noscript' +]) + +booleanAttributes = { + "": frozenset(["irrelevant", "itemscope"]), + "style": frozenset(["scoped"]), + "img": frozenset(["ismap"]), + "audio": frozenset(["autoplay", "controls"]), + "video": frozenset(["autoplay", "controls"]), + "script": frozenset(["defer", "async"]), + "details": frozenset(["open"]), + "datagrid": frozenset(["multiple", "disabled"]), + "command": frozenset(["hidden", "disabled", "checked", "default"]), + "hr": frozenset(["noshade"]), + "menu": frozenset(["autosubmit"]), + "fieldset": frozenset(["disabled", "readonly"]), + "option": frozenset(["disabled", "readonly", "selected"]), + "optgroup": frozenset(["disabled", "readonly"]), + "button": frozenset(["disabled", "autofocus"]), + "input": frozenset(["disabled", "readonly", "required", "autofocus", "checked", "ismap"]), + "select": frozenset(["disabled", "readonly", "autofocus", "multiple"]), + "output": frozenset(["disabled", "readonly"]), + "iframe": frozenset(["seamless"]), +} + +# entitiesWindows1252 has to be _ordered_ and needs to have an index. It +# therefore can't be a frozenset. +entitiesWindows1252 = ( + 8364, # 0x80 0x20AC EURO SIGN + 65533, # 0x81 UNDEFINED + 8218, # 0x82 0x201A SINGLE LOW-9 QUOTATION MARK + 402, # 0x83 0x0192 LATIN SMALL LETTER F WITH HOOK + 8222, # 0x84 0x201E DOUBLE LOW-9 QUOTATION MARK + 8230, # 0x85 0x2026 HORIZONTAL ELLIPSIS + 8224, # 0x86 0x2020 DAGGER + 8225, # 0x87 0x2021 DOUBLE DAGGER + 710, # 0x88 0x02C6 MODIFIER LETTER CIRCUMFLEX ACCENT + 8240, # 0x89 0x2030 PER MILLE SIGN + 352, # 0x8A 0x0160 LATIN CAPITAL LETTER S WITH CARON + 8249, # 0x8B 0x2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 338, # 0x8C 0x0152 LATIN CAPITAL LIGATURE OE + 65533, # 0x8D UNDEFINED + 381, # 0x8E 0x017D LATIN CAPITAL LETTER Z WITH CARON + 65533, # 0x8F UNDEFINED + 65533, # 0x90 UNDEFINED + 8216, # 0x91 0x2018 LEFT SINGLE QUOTATION MARK + 8217, # 0x92 0x2019 RIGHT SINGLE QUOTATION MARK + 8220, # 0x93 0x201C LEFT DOUBLE QUOTATION MARK + 8221, # 0x94 0x201D RIGHT DOUBLE QUOTATION MARK + 8226, # 0x95 0x2022 BULLET + 8211, # 0x96 0x2013 EN DASH + 8212, # 0x97 0x2014 EM DASH + 732, # 0x98 0x02DC SMALL TILDE + 8482, # 0x99 0x2122 TRADE MARK SIGN + 353, # 0x9A 0x0161 LATIN SMALL LETTER S WITH CARON + 8250, # 0x9B 0x203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + 339, # 0x9C 0x0153 LATIN SMALL LIGATURE OE + 65533, # 0x9D UNDEFINED + 382, # 0x9E 0x017E LATIN SMALL LETTER Z WITH CARON + 376 # 0x9F 0x0178 LATIN CAPITAL LETTER Y WITH DIAERESIS +) + +xmlEntities = frozenset(['lt;', 'gt;', 'amp;', 'apos;', 'quot;']) + +entities = { + "AElig": "\xc6", + "AElig;": "\xc6", + "AMP": "&", + "AMP;": "&", + "Aacute": "\xc1", + "Aacute;": "\xc1", + "Abreve;": "\u0102", + "Acirc": "\xc2", + "Acirc;": "\xc2", + "Acy;": "\u0410", + "Afr;": "\U0001d504", + "Agrave": "\xc0", + "Agrave;": "\xc0", + "Alpha;": "\u0391", + "Amacr;": "\u0100", + "And;": "\u2a53", + "Aogon;": "\u0104", + "Aopf;": "\U0001d538", + "ApplyFunction;": "\u2061", + "Aring": "\xc5", + "Aring;": "\xc5", + "Ascr;": "\U0001d49c", + "Assign;": "\u2254", + "Atilde": "\xc3", + "Atilde;": "\xc3", + "Auml": "\xc4", + "Auml;": "\xc4", + "Backslash;": "\u2216", + "Barv;": "\u2ae7", + "Barwed;": "\u2306", + "Bcy;": "\u0411", + "Because;": "\u2235", + "Bernoullis;": "\u212c", + "Beta;": "\u0392", + "Bfr;": "\U0001d505", + "Bopf;": "\U0001d539", + "Breve;": "\u02d8", + "Bscr;": "\u212c", + "Bumpeq;": "\u224e", + "CHcy;": "\u0427", + "COPY": "\xa9", + "COPY;": "\xa9", + "Cacute;": "\u0106", + "Cap;": "\u22d2", + "CapitalDifferentialD;": "\u2145", + "Cayleys;": "\u212d", + "Ccaron;": "\u010c", + "Ccedil": "\xc7", + "Ccedil;": "\xc7", + "Ccirc;": "\u0108", + "Cconint;": "\u2230", + "Cdot;": "\u010a", + "Cedilla;": "\xb8", + "CenterDot;": "\xb7", + "Cfr;": "\u212d", + "Chi;": "\u03a7", + "CircleDot;": "\u2299", + "CircleMinus;": "\u2296", + "CirclePlus;": "\u2295", + "CircleTimes;": "\u2297", + "ClockwiseContourIntegral;": "\u2232", + "CloseCurlyDoubleQuote;": "\u201d", + "CloseCurlyQuote;": "\u2019", + "Colon;": "\u2237", + "Colone;": "\u2a74", + "Congruent;": "\u2261", + "Conint;": "\u222f", + "ContourIntegral;": "\u222e", + "Copf;": "\u2102", + "Coproduct;": "\u2210", + "CounterClockwiseContourIntegral;": "\u2233", + "Cross;": "\u2a2f", + "Cscr;": "\U0001d49e", + "Cup;": "\u22d3", + "CupCap;": "\u224d", + "DD;": "\u2145", + "DDotrahd;": "\u2911", + "DJcy;": "\u0402", + "DScy;": "\u0405", + "DZcy;": "\u040f", + "Dagger;": "\u2021", + "Darr;": "\u21a1", + "Dashv;": "\u2ae4", + "Dcaron;": "\u010e", + "Dcy;": "\u0414", + "Del;": "\u2207", + "Delta;": "\u0394", + "Dfr;": "\U0001d507", + "DiacriticalAcute;": "\xb4", + "DiacriticalDot;": "\u02d9", + "DiacriticalDoubleAcute;": "\u02dd", + "DiacriticalGrave;": "`", + "DiacriticalTilde;": "\u02dc", + "Diamond;": "\u22c4", + "DifferentialD;": "\u2146", + "Dopf;": "\U0001d53b", + "Dot;": "\xa8", + "DotDot;": "\u20dc", + "DotEqual;": "\u2250", + "DoubleContourIntegral;": "\u222f", + "DoubleDot;": "\xa8", + "DoubleDownArrow;": "\u21d3", + "DoubleLeftArrow;": "\u21d0", + "DoubleLeftRightArrow;": "\u21d4", + "DoubleLeftTee;": "\u2ae4", + "DoubleLongLeftArrow;": "\u27f8", + "DoubleLongLeftRightArrow;": "\u27fa", + "DoubleLongRightArrow;": "\u27f9", + "DoubleRightArrow;": "\u21d2", + "DoubleRightTee;": "\u22a8", + "DoubleUpArrow;": "\u21d1", + "DoubleUpDownArrow;": "\u21d5", + "DoubleVerticalBar;": "\u2225", + "DownArrow;": "\u2193", + "DownArrowBar;": "\u2913", + "DownArrowUpArrow;": "\u21f5", + "DownBreve;": "\u0311", + "DownLeftRightVector;": "\u2950", + "DownLeftTeeVector;": "\u295e", + "DownLeftVector;": "\u21bd", + "DownLeftVectorBar;": "\u2956", + "DownRightTeeVector;": "\u295f", + "DownRightVector;": "\u21c1", + "DownRightVectorBar;": "\u2957", + "DownTee;": "\u22a4", + "DownTeeArrow;": "\u21a7", + "Downarrow;": "\u21d3", + "Dscr;": "\U0001d49f", + "Dstrok;": "\u0110", + "ENG;": "\u014a", + "ETH": "\xd0", + "ETH;": "\xd0", + "Eacute": "\xc9", + "Eacute;": "\xc9", + "Ecaron;": "\u011a", + "Ecirc": "\xca", + "Ecirc;": "\xca", + "Ecy;": "\u042d", + "Edot;": "\u0116", + "Efr;": "\U0001d508", + "Egrave": "\xc8", + "Egrave;": "\xc8", + "Element;": "\u2208", + "Emacr;": "\u0112", + "EmptySmallSquare;": "\u25fb", + "EmptyVerySmallSquare;": "\u25ab", + "Eogon;": "\u0118", + "Eopf;": "\U0001d53c", + "Epsilon;": "\u0395", + "Equal;": "\u2a75", + "EqualTilde;": "\u2242", + "Equilibrium;": "\u21cc", + "Escr;": "\u2130", + "Esim;": "\u2a73", + "Eta;": "\u0397", + "Euml": "\xcb", + "Euml;": "\xcb", + "Exists;": "\u2203", + "ExponentialE;": "\u2147", + "Fcy;": "\u0424", + "Ffr;": "\U0001d509", + "FilledSmallSquare;": "\u25fc", + "FilledVerySmallSquare;": "\u25aa", + "Fopf;": "\U0001d53d", + "ForAll;": "\u2200", + "Fouriertrf;": "\u2131", + "Fscr;": "\u2131", + "GJcy;": "\u0403", + "GT": ">", + "GT;": ">", + "Gamma;": "\u0393", + "Gammad;": "\u03dc", + "Gbreve;": "\u011e", + "Gcedil;": "\u0122", + "Gcirc;": "\u011c", + "Gcy;": "\u0413", + "Gdot;": "\u0120", + "Gfr;": "\U0001d50a", + "Gg;": "\u22d9", + "Gopf;": "\U0001d53e", + "GreaterEqual;": "\u2265", + "GreaterEqualLess;": "\u22db", + "GreaterFullEqual;": "\u2267", + "GreaterGreater;": "\u2aa2", + "GreaterLess;": "\u2277", + "GreaterSlantEqual;": "\u2a7e", + "GreaterTilde;": "\u2273", + "Gscr;": "\U0001d4a2", + "Gt;": "\u226b", + "HARDcy;": "\u042a", + "Hacek;": "\u02c7", + "Hat;": "^", + "Hcirc;": "\u0124", + "Hfr;": "\u210c", + "HilbertSpace;": "\u210b", + "Hopf;": "\u210d", + "HorizontalLine;": "\u2500", + "Hscr;": "\u210b", + "Hstrok;": "\u0126", + "HumpDownHump;": "\u224e", + "HumpEqual;": "\u224f", + "IEcy;": "\u0415", + "IJlig;": "\u0132", + "IOcy;": "\u0401", + "Iacute": "\xcd", + "Iacute;": "\xcd", + "Icirc": "\xce", + "Icirc;": "\xce", + "Icy;": "\u0418", + "Idot;": "\u0130", + "Ifr;": "\u2111", + "Igrave": "\xcc", + "Igrave;": "\xcc", + "Im;": "\u2111", + "Imacr;": "\u012a", + "ImaginaryI;": "\u2148", + "Implies;": "\u21d2", + "Int;": "\u222c", + "Integral;": "\u222b", + "Intersection;": "\u22c2", + "InvisibleComma;": "\u2063", + "InvisibleTimes;": "\u2062", + "Iogon;": "\u012e", + "Iopf;": "\U0001d540", + "Iota;": "\u0399", + "Iscr;": "\u2110", + "Itilde;": "\u0128", + "Iukcy;": "\u0406", + "Iuml": "\xcf", + "Iuml;": "\xcf", + "Jcirc;": "\u0134", + "Jcy;": "\u0419", + "Jfr;": "\U0001d50d", + "Jopf;": "\U0001d541", + "Jscr;": "\U0001d4a5", + "Jsercy;": "\u0408", + "Jukcy;": "\u0404", + "KHcy;": "\u0425", + "KJcy;": "\u040c", + "Kappa;": "\u039a", + "Kcedil;": "\u0136", + "Kcy;": "\u041a", + "Kfr;": "\U0001d50e", + "Kopf;": "\U0001d542", + "Kscr;": "\U0001d4a6", + "LJcy;": "\u0409", + "LT": "<", + "LT;": "<", + "Lacute;": "\u0139", + "Lambda;": "\u039b", + "Lang;": "\u27ea", + "Laplacetrf;": "\u2112", + "Larr;": "\u219e", + "Lcaron;": "\u013d", + "Lcedil;": "\u013b", + "Lcy;": "\u041b", + "LeftAngleBracket;": "\u27e8", + "LeftArrow;": "\u2190", + "LeftArrowBar;": "\u21e4", + "LeftArrowRightArrow;": "\u21c6", + "LeftCeiling;": "\u2308", + "LeftDoubleBracket;": "\u27e6", + "LeftDownTeeVector;": "\u2961", + "LeftDownVector;": "\u21c3", + "LeftDownVectorBar;": "\u2959", + "LeftFloor;": "\u230a", + "LeftRightArrow;": "\u2194", + "LeftRightVector;": "\u294e", + "LeftTee;": "\u22a3", + "LeftTeeArrow;": "\u21a4", + "LeftTeeVector;": "\u295a", + "LeftTriangle;": "\u22b2", + "LeftTriangleBar;": "\u29cf", + "LeftTriangleEqual;": "\u22b4", + "LeftUpDownVector;": "\u2951", + "LeftUpTeeVector;": "\u2960", + "LeftUpVector;": "\u21bf", + "LeftUpVectorBar;": "\u2958", + "LeftVector;": "\u21bc", + "LeftVectorBar;": "\u2952", + "Leftarrow;": "\u21d0", + "Leftrightarrow;": "\u21d4", + "LessEqualGreater;": "\u22da", + "LessFullEqual;": "\u2266", + "LessGreater;": "\u2276", + "LessLess;": "\u2aa1", + "LessSlantEqual;": "\u2a7d", + "LessTilde;": "\u2272", + "Lfr;": "\U0001d50f", + "Ll;": "\u22d8", + "Lleftarrow;": "\u21da", + "Lmidot;": "\u013f", + "LongLeftArrow;": "\u27f5", + "LongLeftRightArrow;": "\u27f7", + "LongRightArrow;": "\u27f6", + "Longleftarrow;": "\u27f8", + "Longleftrightarrow;": "\u27fa", + "Longrightarrow;": "\u27f9", + "Lopf;": "\U0001d543", + "LowerLeftArrow;": "\u2199", + "LowerRightArrow;": "\u2198", + "Lscr;": "\u2112", + "Lsh;": "\u21b0", + "Lstrok;": "\u0141", + "Lt;": "\u226a", + "Map;": "\u2905", + "Mcy;": "\u041c", + "MediumSpace;": "\u205f", + "Mellintrf;": "\u2133", + "Mfr;": "\U0001d510", + "MinusPlus;": "\u2213", + "Mopf;": "\U0001d544", + "Mscr;": "\u2133", + "Mu;": "\u039c", + "NJcy;": "\u040a", + "Nacute;": "\u0143", + "Ncaron;": "\u0147", + "Ncedil;": "\u0145", + "Ncy;": "\u041d", + "NegativeMediumSpace;": "\u200b", + "NegativeThickSpace;": "\u200b", + "NegativeThinSpace;": "\u200b", + "NegativeVeryThinSpace;": "\u200b", + "NestedGreaterGreater;": "\u226b", + "NestedLessLess;": "\u226a", + "NewLine;": "\n", + "Nfr;": "\U0001d511", + "NoBreak;": "\u2060", + "NonBreakingSpace;": "\xa0", + "Nopf;": "\u2115", + "Not;": "\u2aec", + "NotCongruent;": "\u2262", + "NotCupCap;": "\u226d", + "NotDoubleVerticalBar;": "\u2226", + "NotElement;": "\u2209", + "NotEqual;": "\u2260", + "NotEqualTilde;": "\u2242\u0338", + "NotExists;": "\u2204", + "NotGreater;": "\u226f", + "NotGreaterEqual;": "\u2271", + "NotGreaterFullEqual;": "\u2267\u0338", + "NotGreaterGreater;": "\u226b\u0338", + "NotGreaterLess;": "\u2279", + "NotGreaterSlantEqual;": "\u2a7e\u0338", + "NotGreaterTilde;": "\u2275", + "NotHumpDownHump;": "\u224e\u0338", + "NotHumpEqual;": "\u224f\u0338", + "NotLeftTriangle;": "\u22ea", + "NotLeftTriangleBar;": "\u29cf\u0338", + "NotLeftTriangleEqual;": "\u22ec", + "NotLess;": "\u226e", + "NotLessEqual;": "\u2270", + "NotLessGreater;": "\u2278", + "NotLessLess;": "\u226a\u0338", + "NotLessSlantEqual;": "\u2a7d\u0338", + "NotLessTilde;": "\u2274", + "NotNestedGreaterGreater;": "\u2aa2\u0338", + "NotNestedLessLess;": "\u2aa1\u0338", + "NotPrecedes;": "\u2280", + "NotPrecedesEqual;": "\u2aaf\u0338", + "NotPrecedesSlantEqual;": "\u22e0", + "NotReverseElement;": "\u220c", + "NotRightTriangle;": "\u22eb", + "NotRightTriangleBar;": "\u29d0\u0338", + "NotRightTriangleEqual;": "\u22ed", + "NotSquareSubset;": "\u228f\u0338", + "NotSquareSubsetEqual;": "\u22e2", + "NotSquareSuperset;": "\u2290\u0338", + "NotSquareSupersetEqual;": "\u22e3", + "NotSubset;": "\u2282\u20d2", + "NotSubsetEqual;": "\u2288", + "NotSucceeds;": "\u2281", + "NotSucceedsEqual;": "\u2ab0\u0338", + "NotSucceedsSlantEqual;": "\u22e1", + "NotSucceedsTilde;": "\u227f\u0338", + "NotSuperset;": "\u2283\u20d2", + "NotSupersetEqual;": "\u2289", + "NotTilde;": "\u2241", + "NotTildeEqual;": "\u2244", + "NotTildeFullEqual;": "\u2247", + "NotTildeTilde;": "\u2249", + "NotVerticalBar;": "\u2224", + "Nscr;": "\U0001d4a9", + "Ntilde": "\xd1", + "Ntilde;": "\xd1", + "Nu;": "\u039d", + "OElig;": "\u0152", + "Oacute": "\xd3", + "Oacute;": "\xd3", + "Ocirc": "\xd4", + "Ocirc;": "\xd4", + "Ocy;": "\u041e", + "Odblac;": "\u0150", + "Ofr;": "\U0001d512", + "Ograve": "\xd2", + "Ograve;": "\xd2", + "Omacr;": "\u014c", + "Omega;": "\u03a9", + "Omicron;": "\u039f", + "Oopf;": "\U0001d546", + "OpenCurlyDoubleQuote;": "\u201c", + "OpenCurlyQuote;": "\u2018", + "Or;": "\u2a54", + "Oscr;": "\U0001d4aa", + "Oslash": "\xd8", + "Oslash;": "\xd8", + "Otilde": "\xd5", + "Otilde;": "\xd5", + "Otimes;": "\u2a37", + "Ouml": "\xd6", + "Ouml;": "\xd6", + "OverBar;": "\u203e", + "OverBrace;": "\u23de", + "OverBracket;": "\u23b4", + "OverParenthesis;": "\u23dc", + "PartialD;": "\u2202", + "Pcy;": "\u041f", + "Pfr;": "\U0001d513", + "Phi;": "\u03a6", + "Pi;": "\u03a0", + "PlusMinus;": "\xb1", + "Poincareplane;": "\u210c", + "Popf;": "\u2119", + "Pr;": "\u2abb", + "Precedes;": "\u227a", + "PrecedesEqual;": "\u2aaf", + "PrecedesSlantEqual;": "\u227c", + "PrecedesTilde;": "\u227e", + "Prime;": "\u2033", + "Product;": "\u220f", + "Proportion;": "\u2237", + "Proportional;": "\u221d", + "Pscr;": "\U0001d4ab", + "Psi;": "\u03a8", + "QUOT": "\"", + "QUOT;": "\"", + "Qfr;": "\U0001d514", + "Qopf;": "\u211a", + "Qscr;": "\U0001d4ac", + "RBarr;": "\u2910", + "REG": "\xae", + "REG;": "\xae", + "Racute;": "\u0154", + "Rang;": "\u27eb", + "Rarr;": "\u21a0", + "Rarrtl;": "\u2916", + "Rcaron;": "\u0158", + "Rcedil;": "\u0156", + "Rcy;": "\u0420", + "Re;": "\u211c", + "ReverseElement;": "\u220b", + "ReverseEquilibrium;": "\u21cb", + "ReverseUpEquilibrium;": "\u296f", + "Rfr;": "\u211c", + "Rho;": "\u03a1", + "RightAngleBracket;": "\u27e9", + "RightArrow;": "\u2192", + "RightArrowBar;": "\u21e5", + "RightArrowLeftArrow;": "\u21c4", + "RightCeiling;": "\u2309", + "RightDoubleBracket;": "\u27e7", + "RightDownTeeVector;": "\u295d", + "RightDownVector;": "\u21c2", + "RightDownVectorBar;": "\u2955", + "RightFloor;": "\u230b", + "RightTee;": "\u22a2", + "RightTeeArrow;": "\u21a6", + "RightTeeVector;": "\u295b", + "RightTriangle;": "\u22b3", + "RightTriangleBar;": "\u29d0", + "RightTriangleEqual;": "\u22b5", + "RightUpDownVector;": "\u294f", + "RightUpTeeVector;": "\u295c", + "RightUpVector;": "\u21be", + "RightUpVectorBar;": "\u2954", + "RightVector;": "\u21c0", + "RightVectorBar;": "\u2953", + "Rightarrow;": "\u21d2", + "Ropf;": "\u211d", + "RoundImplies;": "\u2970", + "Rrightarrow;": "\u21db", + "Rscr;": "\u211b", + "Rsh;": "\u21b1", + "RuleDelayed;": "\u29f4", + "SHCHcy;": "\u0429", + "SHcy;": "\u0428", + "SOFTcy;": "\u042c", + "Sacute;": "\u015a", + "Sc;": "\u2abc", + "Scaron;": "\u0160", + "Scedil;": "\u015e", + "Scirc;": "\u015c", + "Scy;": "\u0421", + "Sfr;": "\U0001d516", + "ShortDownArrow;": "\u2193", + "ShortLeftArrow;": "\u2190", + "ShortRightArrow;": "\u2192", + "ShortUpArrow;": "\u2191", + "Sigma;": "\u03a3", + "SmallCircle;": "\u2218", + "Sopf;": "\U0001d54a", + "Sqrt;": "\u221a", + "Square;": "\u25a1", + "SquareIntersection;": "\u2293", + "SquareSubset;": "\u228f", + "SquareSubsetEqual;": "\u2291", + "SquareSuperset;": "\u2290", + "SquareSupersetEqual;": "\u2292", + "SquareUnion;": "\u2294", + "Sscr;": "\U0001d4ae", + "Star;": "\u22c6", + "Sub;": "\u22d0", + "Subset;": "\u22d0", + "SubsetEqual;": "\u2286", + "Succeeds;": "\u227b", + "SucceedsEqual;": "\u2ab0", + "SucceedsSlantEqual;": "\u227d", + "SucceedsTilde;": "\u227f", + "SuchThat;": "\u220b", + "Sum;": "\u2211", + "Sup;": "\u22d1", + "Superset;": "\u2283", + "SupersetEqual;": "\u2287", + "Supset;": "\u22d1", + "THORN": "\xde", + "THORN;": "\xde", + "TRADE;": "\u2122", + "TSHcy;": "\u040b", + "TScy;": "\u0426", + "Tab;": "\t", + "Tau;": "\u03a4", + "Tcaron;": "\u0164", + "Tcedil;": "\u0162", + "Tcy;": "\u0422", + "Tfr;": "\U0001d517", + "Therefore;": "\u2234", + "Theta;": "\u0398", + "ThickSpace;": "\u205f\u200a", + "ThinSpace;": "\u2009", + "Tilde;": "\u223c", + "TildeEqual;": "\u2243", + "TildeFullEqual;": "\u2245", + "TildeTilde;": "\u2248", + "Topf;": "\U0001d54b", + "TripleDot;": "\u20db", + "Tscr;": "\U0001d4af", + "Tstrok;": "\u0166", + "Uacute": "\xda", + "Uacute;": "\xda", + "Uarr;": "\u219f", + "Uarrocir;": "\u2949", + "Ubrcy;": "\u040e", + "Ubreve;": "\u016c", + "Ucirc": "\xdb", + "Ucirc;": "\xdb", + "Ucy;": "\u0423", + "Udblac;": "\u0170", + "Ufr;": "\U0001d518", + "Ugrave": "\xd9", + "Ugrave;": "\xd9", + "Umacr;": "\u016a", + "UnderBar;": "_", + "UnderBrace;": "\u23df", + "UnderBracket;": "\u23b5", + "UnderParenthesis;": "\u23dd", + "Union;": "\u22c3", + "UnionPlus;": "\u228e", + "Uogon;": "\u0172", + "Uopf;": "\U0001d54c", + "UpArrow;": "\u2191", + "UpArrowBar;": "\u2912", + "UpArrowDownArrow;": "\u21c5", + "UpDownArrow;": "\u2195", + "UpEquilibrium;": "\u296e", + "UpTee;": "\u22a5", + "UpTeeArrow;": "\u21a5", + "Uparrow;": "\u21d1", + "Updownarrow;": "\u21d5", + "UpperLeftArrow;": "\u2196", + "UpperRightArrow;": "\u2197", + "Upsi;": "\u03d2", + "Upsilon;": "\u03a5", + "Uring;": "\u016e", + "Uscr;": "\U0001d4b0", + "Utilde;": "\u0168", + "Uuml": "\xdc", + "Uuml;": "\xdc", + "VDash;": "\u22ab", + "Vbar;": "\u2aeb", + "Vcy;": "\u0412", + "Vdash;": "\u22a9", + "Vdashl;": "\u2ae6", + "Vee;": "\u22c1", + "Verbar;": "\u2016", + "Vert;": "\u2016", + "VerticalBar;": "\u2223", + "VerticalLine;": "|", + "VerticalSeparator;": "\u2758", + "VerticalTilde;": "\u2240", + "VeryThinSpace;": "\u200a", + "Vfr;": "\U0001d519", + "Vopf;": "\U0001d54d", + "Vscr;": "\U0001d4b1", + "Vvdash;": "\u22aa", + "Wcirc;": "\u0174", + "Wedge;": "\u22c0", + "Wfr;": "\U0001d51a", + "Wopf;": "\U0001d54e", + "Wscr;": "\U0001d4b2", + "Xfr;": "\U0001d51b", + "Xi;": "\u039e", + "Xopf;": "\U0001d54f", + "Xscr;": "\U0001d4b3", + "YAcy;": "\u042f", + "YIcy;": "\u0407", + "YUcy;": "\u042e", + "Yacute": "\xdd", + "Yacute;": "\xdd", + "Ycirc;": "\u0176", + "Ycy;": "\u042b", + "Yfr;": "\U0001d51c", + "Yopf;": "\U0001d550", + "Yscr;": "\U0001d4b4", + "Yuml;": "\u0178", + "ZHcy;": "\u0416", + "Zacute;": "\u0179", + "Zcaron;": "\u017d", + "Zcy;": "\u0417", + "Zdot;": "\u017b", + "ZeroWidthSpace;": "\u200b", + "Zeta;": "\u0396", + "Zfr;": "\u2128", + "Zopf;": "\u2124", + "Zscr;": "\U0001d4b5", + "aacute": "\xe1", + "aacute;": "\xe1", + "abreve;": "\u0103", + "ac;": "\u223e", + "acE;": "\u223e\u0333", + "acd;": "\u223f", + "acirc": "\xe2", + "acirc;": "\xe2", + "acute": "\xb4", + "acute;": "\xb4", + "acy;": "\u0430", + "aelig": "\xe6", + "aelig;": "\xe6", + "af;": "\u2061", + "afr;": "\U0001d51e", + "agrave": "\xe0", + "agrave;": "\xe0", + "alefsym;": "\u2135", + "aleph;": "\u2135", + "alpha;": "\u03b1", + "amacr;": "\u0101", + "amalg;": "\u2a3f", + "amp": "&", + "amp;": "&", + "and;": "\u2227", + "andand;": "\u2a55", + "andd;": "\u2a5c", + "andslope;": "\u2a58", + "andv;": "\u2a5a", + "ang;": "\u2220", + "ange;": "\u29a4", + "angle;": "\u2220", + "angmsd;": "\u2221", + "angmsdaa;": "\u29a8", + "angmsdab;": "\u29a9", + "angmsdac;": "\u29aa", + "angmsdad;": "\u29ab", + "angmsdae;": "\u29ac", + "angmsdaf;": "\u29ad", + "angmsdag;": "\u29ae", + "angmsdah;": "\u29af", + "angrt;": "\u221f", + "angrtvb;": "\u22be", + "angrtvbd;": "\u299d", + "angsph;": "\u2222", + "angst;": "\xc5", + "angzarr;": "\u237c", + "aogon;": "\u0105", + "aopf;": "\U0001d552", + "ap;": "\u2248", + "apE;": "\u2a70", + "apacir;": "\u2a6f", + "ape;": "\u224a", + "apid;": "\u224b", + "apos;": "'", + "approx;": "\u2248", + "approxeq;": "\u224a", + "aring": "\xe5", + "aring;": "\xe5", + "ascr;": "\U0001d4b6", + "ast;": "*", + "asymp;": "\u2248", + "asympeq;": "\u224d", + "atilde": "\xe3", + "atilde;": "\xe3", + "auml": "\xe4", + "auml;": "\xe4", + "awconint;": "\u2233", + "awint;": "\u2a11", + "bNot;": "\u2aed", + "backcong;": "\u224c", + "backepsilon;": "\u03f6", + "backprime;": "\u2035", + "backsim;": "\u223d", + "backsimeq;": "\u22cd", + "barvee;": "\u22bd", + "barwed;": "\u2305", + "barwedge;": "\u2305", + "bbrk;": "\u23b5", + "bbrktbrk;": "\u23b6", + "bcong;": "\u224c", + "bcy;": "\u0431", + "bdquo;": "\u201e", + "becaus;": "\u2235", + "because;": "\u2235", + "bemptyv;": "\u29b0", + "bepsi;": "\u03f6", + "bernou;": "\u212c", + "beta;": "\u03b2", + "beth;": "\u2136", + "between;": "\u226c", + "bfr;": "\U0001d51f", + "bigcap;": "\u22c2", + "bigcirc;": "\u25ef", + "bigcup;": "\u22c3", + "bigodot;": "\u2a00", + "bigoplus;": "\u2a01", + "bigotimes;": "\u2a02", + "bigsqcup;": "\u2a06", + "bigstar;": "\u2605", + "bigtriangledown;": "\u25bd", + "bigtriangleup;": "\u25b3", + "biguplus;": "\u2a04", + "bigvee;": "\u22c1", + "bigwedge;": "\u22c0", + "bkarow;": "\u290d", + "blacklozenge;": "\u29eb", + "blacksquare;": "\u25aa", + "blacktriangle;": "\u25b4", + "blacktriangledown;": "\u25be", + "blacktriangleleft;": "\u25c2", + "blacktriangleright;": "\u25b8", + "blank;": "\u2423", + "blk12;": "\u2592", + "blk14;": "\u2591", + "blk34;": "\u2593", + "block;": "\u2588", + "bne;": "=\u20e5", + "bnequiv;": "\u2261\u20e5", + "bnot;": "\u2310", + "bopf;": "\U0001d553", + "bot;": "\u22a5", + "bottom;": "\u22a5", + "bowtie;": "\u22c8", + "boxDL;": "\u2557", + "boxDR;": "\u2554", + "boxDl;": "\u2556", + "boxDr;": "\u2553", + "boxH;": "\u2550", + "boxHD;": "\u2566", + "boxHU;": "\u2569", + "boxHd;": "\u2564", + "boxHu;": "\u2567", + "boxUL;": "\u255d", + "boxUR;": "\u255a", + "boxUl;": "\u255c", + "boxUr;": "\u2559", + "boxV;": "\u2551", + "boxVH;": "\u256c", + "boxVL;": "\u2563", + "boxVR;": "\u2560", + "boxVh;": "\u256b", + "boxVl;": "\u2562", + "boxVr;": "\u255f", + "boxbox;": "\u29c9", + "boxdL;": "\u2555", + "boxdR;": "\u2552", + "boxdl;": "\u2510", + "boxdr;": "\u250c", + "boxh;": "\u2500", + "boxhD;": "\u2565", + "boxhU;": "\u2568", + "boxhd;": "\u252c", + "boxhu;": "\u2534", + "boxminus;": "\u229f", + "boxplus;": "\u229e", + "boxtimes;": "\u22a0", + "boxuL;": "\u255b", + "boxuR;": "\u2558", + "boxul;": "\u2518", + "boxur;": "\u2514", + "boxv;": "\u2502", + "boxvH;": "\u256a", + "boxvL;": "\u2561", + "boxvR;": "\u255e", + "boxvh;": "\u253c", + "boxvl;": "\u2524", + "boxvr;": "\u251c", + "bprime;": "\u2035", + "breve;": "\u02d8", + "brvbar": "\xa6", + "brvbar;": "\xa6", + "bscr;": "\U0001d4b7", + "bsemi;": "\u204f", + "bsim;": "\u223d", + "bsime;": "\u22cd", + "bsol;": "\\", + "bsolb;": "\u29c5", + "bsolhsub;": "\u27c8", + "bull;": "\u2022", + "bullet;": "\u2022", + "bump;": "\u224e", + "bumpE;": "\u2aae", + "bumpe;": "\u224f", + "bumpeq;": "\u224f", + "cacute;": "\u0107", + "cap;": "\u2229", + "capand;": "\u2a44", + "capbrcup;": "\u2a49", + "capcap;": "\u2a4b", + "capcup;": "\u2a47", + "capdot;": "\u2a40", + "caps;": "\u2229\ufe00", + "caret;": "\u2041", + "caron;": "\u02c7", + "ccaps;": "\u2a4d", + "ccaron;": "\u010d", + "ccedil": "\xe7", + "ccedil;": "\xe7", + "ccirc;": "\u0109", + "ccups;": "\u2a4c", + "ccupssm;": "\u2a50", + "cdot;": "\u010b", + "cedil": "\xb8", + "cedil;": "\xb8", + "cemptyv;": "\u29b2", + "cent": "\xa2", + "cent;": "\xa2", + "centerdot;": "\xb7", + "cfr;": "\U0001d520", + "chcy;": "\u0447", + "check;": "\u2713", + "checkmark;": "\u2713", + "chi;": "\u03c7", + "cir;": "\u25cb", + "cirE;": "\u29c3", + "circ;": "\u02c6", + "circeq;": "\u2257", + "circlearrowleft;": "\u21ba", + "circlearrowright;": "\u21bb", + "circledR;": "\xae", + "circledS;": "\u24c8", + "circledast;": "\u229b", + "circledcirc;": "\u229a", + "circleddash;": "\u229d", + "cire;": "\u2257", + "cirfnint;": "\u2a10", + "cirmid;": "\u2aef", + "cirscir;": "\u29c2", + "clubs;": "\u2663", + "clubsuit;": "\u2663", + "colon;": ":", + "colone;": "\u2254", + "coloneq;": "\u2254", + "comma;": ",", + "commat;": "@", + "comp;": "\u2201", + "compfn;": "\u2218", + "complement;": "\u2201", + "complexes;": "\u2102", + "cong;": "\u2245", + "congdot;": "\u2a6d", + "conint;": "\u222e", + "copf;": "\U0001d554", + "coprod;": "\u2210", + "copy": "\xa9", + "copy;": "\xa9", + "copysr;": "\u2117", + "crarr;": "\u21b5", + "cross;": "\u2717", + "cscr;": "\U0001d4b8", + "csub;": "\u2acf", + "csube;": "\u2ad1", + "csup;": "\u2ad0", + "csupe;": "\u2ad2", + "ctdot;": "\u22ef", + "cudarrl;": "\u2938", + "cudarrr;": "\u2935", + "cuepr;": "\u22de", + "cuesc;": "\u22df", + "cularr;": "\u21b6", + "cularrp;": "\u293d", + "cup;": "\u222a", + "cupbrcap;": "\u2a48", + "cupcap;": "\u2a46", + "cupcup;": "\u2a4a", + "cupdot;": "\u228d", + "cupor;": "\u2a45", + "cups;": "\u222a\ufe00", + "curarr;": "\u21b7", + "curarrm;": "\u293c", + "curlyeqprec;": "\u22de", + "curlyeqsucc;": "\u22df", + "curlyvee;": "\u22ce", + "curlywedge;": "\u22cf", + "curren": "\xa4", + "curren;": "\xa4", + "curvearrowleft;": "\u21b6", + "curvearrowright;": "\u21b7", + "cuvee;": "\u22ce", + "cuwed;": "\u22cf", + "cwconint;": "\u2232", + "cwint;": "\u2231", + "cylcty;": "\u232d", + "dArr;": "\u21d3", + "dHar;": "\u2965", + "dagger;": "\u2020", + "daleth;": "\u2138", + "darr;": "\u2193", + "dash;": "\u2010", + "dashv;": "\u22a3", + "dbkarow;": "\u290f", + "dblac;": "\u02dd", + "dcaron;": "\u010f", + "dcy;": "\u0434", + "dd;": "\u2146", + "ddagger;": "\u2021", + "ddarr;": "\u21ca", + "ddotseq;": "\u2a77", + "deg": "\xb0", + "deg;": "\xb0", + "delta;": "\u03b4", + "demptyv;": "\u29b1", + "dfisht;": "\u297f", + "dfr;": "\U0001d521", + "dharl;": "\u21c3", + "dharr;": "\u21c2", + "diam;": "\u22c4", + "diamond;": "\u22c4", + "diamondsuit;": "\u2666", + "diams;": "\u2666", + "die;": "\xa8", + "digamma;": "\u03dd", + "disin;": "\u22f2", + "div;": "\xf7", + "divide": "\xf7", + "divide;": "\xf7", + "divideontimes;": "\u22c7", + "divonx;": "\u22c7", + "djcy;": "\u0452", + "dlcorn;": "\u231e", + "dlcrop;": "\u230d", + "dollar;": "$", + "dopf;": "\U0001d555", + "dot;": "\u02d9", + "doteq;": "\u2250", + "doteqdot;": "\u2251", + "dotminus;": "\u2238", + "dotplus;": "\u2214", + "dotsquare;": "\u22a1", + "doublebarwedge;": "\u2306", + "downarrow;": "\u2193", + "downdownarrows;": "\u21ca", + "downharpoonleft;": "\u21c3", + "downharpoonright;": "\u21c2", + "drbkarow;": "\u2910", + "drcorn;": "\u231f", + "drcrop;": "\u230c", + "dscr;": "\U0001d4b9", + "dscy;": "\u0455", + "dsol;": "\u29f6", + "dstrok;": "\u0111", + "dtdot;": "\u22f1", + "dtri;": "\u25bf", + "dtrif;": "\u25be", + "duarr;": "\u21f5", + "duhar;": "\u296f", + "dwangle;": "\u29a6", + "dzcy;": "\u045f", + "dzigrarr;": "\u27ff", + "eDDot;": "\u2a77", + "eDot;": "\u2251", + "eacute": "\xe9", + "eacute;": "\xe9", + "easter;": "\u2a6e", + "ecaron;": "\u011b", + "ecir;": "\u2256", + "ecirc": "\xea", + "ecirc;": "\xea", + "ecolon;": "\u2255", + "ecy;": "\u044d", + "edot;": "\u0117", + "ee;": "\u2147", + "efDot;": "\u2252", + "efr;": "\U0001d522", + "eg;": "\u2a9a", + "egrave": "\xe8", + "egrave;": "\xe8", + "egs;": "\u2a96", + "egsdot;": "\u2a98", + "el;": "\u2a99", + "elinters;": "\u23e7", + "ell;": "\u2113", + "els;": "\u2a95", + "elsdot;": "\u2a97", + "emacr;": "\u0113", + "empty;": "\u2205", + "emptyset;": "\u2205", + "emptyv;": "\u2205", + "emsp13;": "\u2004", + "emsp14;": "\u2005", + "emsp;": "\u2003", + "eng;": "\u014b", + "ensp;": "\u2002", + "eogon;": "\u0119", + "eopf;": "\U0001d556", + "epar;": "\u22d5", + "eparsl;": "\u29e3", + "eplus;": "\u2a71", + "epsi;": "\u03b5", + "epsilon;": "\u03b5", + "epsiv;": "\u03f5", + "eqcirc;": "\u2256", + "eqcolon;": "\u2255", + "eqsim;": "\u2242", + "eqslantgtr;": "\u2a96", + "eqslantless;": "\u2a95", + "equals;": "=", + "equest;": "\u225f", + "equiv;": "\u2261", + "equivDD;": "\u2a78", + "eqvparsl;": "\u29e5", + "erDot;": "\u2253", + "erarr;": "\u2971", + "escr;": "\u212f", + "esdot;": "\u2250", + "esim;": "\u2242", + "eta;": "\u03b7", + "eth": "\xf0", + "eth;": "\xf0", + "euml": "\xeb", + "euml;": "\xeb", + "euro;": "\u20ac", + "excl;": "!", + "exist;": "\u2203", + "expectation;": "\u2130", + "exponentiale;": "\u2147", + "fallingdotseq;": "\u2252", + "fcy;": "\u0444", + "female;": "\u2640", + "ffilig;": "\ufb03", + "fflig;": "\ufb00", + "ffllig;": "\ufb04", + "ffr;": "\U0001d523", + "filig;": "\ufb01", + "fjlig;": "fj", + "flat;": "\u266d", + "fllig;": "\ufb02", + "fltns;": "\u25b1", + "fnof;": "\u0192", + "fopf;": "\U0001d557", + "forall;": "\u2200", + "fork;": "\u22d4", + "forkv;": "\u2ad9", + "fpartint;": "\u2a0d", + "frac12": "\xbd", + "frac12;": "\xbd", + "frac13;": "\u2153", + "frac14": "\xbc", + "frac14;": "\xbc", + "frac15;": "\u2155", + "frac16;": "\u2159", + "frac18;": "\u215b", + "frac23;": "\u2154", + "frac25;": "\u2156", + "frac34": "\xbe", + "frac34;": "\xbe", + "frac35;": "\u2157", + "frac38;": "\u215c", + "frac45;": "\u2158", + "frac56;": "\u215a", + "frac58;": "\u215d", + "frac78;": "\u215e", + "frasl;": "\u2044", + "frown;": "\u2322", + "fscr;": "\U0001d4bb", + "gE;": "\u2267", + "gEl;": "\u2a8c", + "gacute;": "\u01f5", + "gamma;": "\u03b3", + "gammad;": "\u03dd", + "gap;": "\u2a86", + "gbreve;": "\u011f", + "gcirc;": "\u011d", + "gcy;": "\u0433", + "gdot;": "\u0121", + "ge;": "\u2265", + "gel;": "\u22db", + "geq;": "\u2265", + "geqq;": "\u2267", + "geqslant;": "\u2a7e", + "ges;": "\u2a7e", + "gescc;": "\u2aa9", + "gesdot;": "\u2a80", + "gesdoto;": "\u2a82", + "gesdotol;": "\u2a84", + "gesl;": "\u22db\ufe00", + "gesles;": "\u2a94", + "gfr;": "\U0001d524", + "gg;": "\u226b", + "ggg;": "\u22d9", + "gimel;": "\u2137", + "gjcy;": "\u0453", + "gl;": "\u2277", + "glE;": "\u2a92", + "gla;": "\u2aa5", + "glj;": "\u2aa4", + "gnE;": "\u2269", + "gnap;": "\u2a8a", + "gnapprox;": "\u2a8a", + "gne;": "\u2a88", + "gneq;": "\u2a88", + "gneqq;": "\u2269", + "gnsim;": "\u22e7", + "gopf;": "\U0001d558", + "grave;": "`", + "gscr;": "\u210a", + "gsim;": "\u2273", + "gsime;": "\u2a8e", + "gsiml;": "\u2a90", + "gt": ">", + "gt;": ">", + "gtcc;": "\u2aa7", + "gtcir;": "\u2a7a", + "gtdot;": "\u22d7", + "gtlPar;": "\u2995", + "gtquest;": "\u2a7c", + "gtrapprox;": "\u2a86", + "gtrarr;": "\u2978", + "gtrdot;": "\u22d7", + "gtreqless;": "\u22db", + "gtreqqless;": "\u2a8c", + "gtrless;": "\u2277", + "gtrsim;": "\u2273", + "gvertneqq;": "\u2269\ufe00", + "gvnE;": "\u2269\ufe00", + "hArr;": "\u21d4", + "hairsp;": "\u200a", + "half;": "\xbd", + "hamilt;": "\u210b", + "hardcy;": "\u044a", + "harr;": "\u2194", + "harrcir;": "\u2948", + "harrw;": "\u21ad", + "hbar;": "\u210f", + "hcirc;": "\u0125", + "hearts;": "\u2665", + "heartsuit;": "\u2665", + "hellip;": "\u2026", + "hercon;": "\u22b9", + "hfr;": "\U0001d525", + "hksearow;": "\u2925", + "hkswarow;": "\u2926", + "hoarr;": "\u21ff", + "homtht;": "\u223b", + "hookleftarrow;": "\u21a9", + "hookrightarrow;": "\u21aa", + "hopf;": "\U0001d559", + "horbar;": "\u2015", + "hscr;": "\U0001d4bd", + "hslash;": "\u210f", + "hstrok;": "\u0127", + "hybull;": "\u2043", + "hyphen;": "\u2010", + "iacute": "\xed", + "iacute;": "\xed", + "ic;": "\u2063", + "icirc": "\xee", + "icirc;": "\xee", + "icy;": "\u0438", + "iecy;": "\u0435", + "iexcl": "\xa1", + "iexcl;": "\xa1", + "iff;": "\u21d4", + "ifr;": "\U0001d526", + "igrave": "\xec", + "igrave;": "\xec", + "ii;": "\u2148", + "iiiint;": "\u2a0c", + "iiint;": "\u222d", + "iinfin;": "\u29dc", + "iiota;": "\u2129", + "ijlig;": "\u0133", + "imacr;": "\u012b", + "image;": "\u2111", + "imagline;": "\u2110", + "imagpart;": "\u2111", + "imath;": "\u0131", + "imof;": "\u22b7", + "imped;": "\u01b5", + "in;": "\u2208", + "incare;": "\u2105", + "infin;": "\u221e", + "infintie;": "\u29dd", + "inodot;": "\u0131", + "int;": "\u222b", + "intcal;": "\u22ba", + "integers;": "\u2124", + "intercal;": "\u22ba", + "intlarhk;": "\u2a17", + "intprod;": "\u2a3c", + "iocy;": "\u0451", + "iogon;": "\u012f", + "iopf;": "\U0001d55a", + "iota;": "\u03b9", + "iprod;": "\u2a3c", + "iquest": "\xbf", + "iquest;": "\xbf", + "iscr;": "\U0001d4be", + "isin;": "\u2208", + "isinE;": "\u22f9", + "isindot;": "\u22f5", + "isins;": "\u22f4", + "isinsv;": "\u22f3", + "isinv;": "\u2208", + "it;": "\u2062", + "itilde;": "\u0129", + "iukcy;": "\u0456", + "iuml": "\xef", + "iuml;": "\xef", + "jcirc;": "\u0135", + "jcy;": "\u0439", + "jfr;": "\U0001d527", + "jmath;": "\u0237", + "jopf;": "\U0001d55b", + "jscr;": "\U0001d4bf", + "jsercy;": "\u0458", + "jukcy;": "\u0454", + "kappa;": "\u03ba", + "kappav;": "\u03f0", + "kcedil;": "\u0137", + "kcy;": "\u043a", + "kfr;": "\U0001d528", + "kgreen;": "\u0138", + "khcy;": "\u0445", + "kjcy;": "\u045c", + "kopf;": "\U0001d55c", + "kscr;": "\U0001d4c0", + "lAarr;": "\u21da", + "lArr;": "\u21d0", + "lAtail;": "\u291b", + "lBarr;": "\u290e", + "lE;": "\u2266", + "lEg;": "\u2a8b", + "lHar;": "\u2962", + "lacute;": "\u013a", + "laemptyv;": "\u29b4", + "lagran;": "\u2112", + "lambda;": "\u03bb", + "lang;": "\u27e8", + "langd;": "\u2991", + "langle;": "\u27e8", + "lap;": "\u2a85", + "laquo": "\xab", + "laquo;": "\xab", + "larr;": "\u2190", + "larrb;": "\u21e4", + "larrbfs;": "\u291f", + "larrfs;": "\u291d", + "larrhk;": "\u21a9", + "larrlp;": "\u21ab", + "larrpl;": "\u2939", + "larrsim;": "\u2973", + "larrtl;": "\u21a2", + "lat;": "\u2aab", + "latail;": "\u2919", + "late;": "\u2aad", + "lates;": "\u2aad\ufe00", + "lbarr;": "\u290c", + "lbbrk;": "\u2772", + "lbrace;": "{", + "lbrack;": "[", + "lbrke;": "\u298b", + "lbrksld;": "\u298f", + "lbrkslu;": "\u298d", + "lcaron;": "\u013e", + "lcedil;": "\u013c", + "lceil;": "\u2308", + "lcub;": "{", + "lcy;": "\u043b", + "ldca;": "\u2936", + "ldquo;": "\u201c", + "ldquor;": "\u201e", + "ldrdhar;": "\u2967", + "ldrushar;": "\u294b", + "ldsh;": "\u21b2", + "le;": "\u2264", + "leftarrow;": "\u2190", + "leftarrowtail;": "\u21a2", + "leftharpoondown;": "\u21bd", + "leftharpoonup;": "\u21bc", + "leftleftarrows;": "\u21c7", + "leftrightarrow;": "\u2194", + "leftrightarrows;": "\u21c6", + "leftrightharpoons;": "\u21cb", + "leftrightsquigarrow;": "\u21ad", + "leftthreetimes;": "\u22cb", + "leg;": "\u22da", + "leq;": "\u2264", + "leqq;": "\u2266", + "leqslant;": "\u2a7d", + "les;": "\u2a7d", + "lescc;": "\u2aa8", + "lesdot;": "\u2a7f", + "lesdoto;": "\u2a81", + "lesdotor;": "\u2a83", + "lesg;": "\u22da\ufe00", + "lesges;": "\u2a93", + "lessapprox;": "\u2a85", + "lessdot;": "\u22d6", + "lesseqgtr;": "\u22da", + "lesseqqgtr;": "\u2a8b", + "lessgtr;": "\u2276", + "lesssim;": "\u2272", + "lfisht;": "\u297c", + "lfloor;": "\u230a", + "lfr;": "\U0001d529", + "lg;": "\u2276", + "lgE;": "\u2a91", + "lhard;": "\u21bd", + "lharu;": "\u21bc", + "lharul;": "\u296a", + "lhblk;": "\u2584", + "ljcy;": "\u0459", + "ll;": "\u226a", + "llarr;": "\u21c7", + "llcorner;": "\u231e", + "llhard;": "\u296b", + "lltri;": "\u25fa", + "lmidot;": "\u0140", + "lmoust;": "\u23b0", + "lmoustache;": "\u23b0", + "lnE;": "\u2268", + "lnap;": "\u2a89", + "lnapprox;": "\u2a89", + "lne;": "\u2a87", + "lneq;": "\u2a87", + "lneqq;": "\u2268", + "lnsim;": "\u22e6", + "loang;": "\u27ec", + "loarr;": "\u21fd", + "lobrk;": "\u27e6", + "longleftarrow;": "\u27f5", + "longleftrightarrow;": "\u27f7", + "longmapsto;": "\u27fc", + "longrightarrow;": "\u27f6", + "looparrowleft;": "\u21ab", + "looparrowright;": "\u21ac", + "lopar;": "\u2985", + "lopf;": "\U0001d55d", + "loplus;": "\u2a2d", + "lotimes;": "\u2a34", + "lowast;": "\u2217", + "lowbar;": "_", + "loz;": "\u25ca", + "lozenge;": "\u25ca", + "lozf;": "\u29eb", + "lpar;": "(", + "lparlt;": "\u2993", + "lrarr;": "\u21c6", + "lrcorner;": "\u231f", + "lrhar;": "\u21cb", + "lrhard;": "\u296d", + "lrm;": "\u200e", + "lrtri;": "\u22bf", + "lsaquo;": "\u2039", + "lscr;": "\U0001d4c1", + "lsh;": "\u21b0", + "lsim;": "\u2272", + "lsime;": "\u2a8d", + "lsimg;": "\u2a8f", + "lsqb;": "[", + "lsquo;": "\u2018", + "lsquor;": "\u201a", + "lstrok;": "\u0142", + "lt": "<", + "lt;": "<", + "ltcc;": "\u2aa6", + "ltcir;": "\u2a79", + "ltdot;": "\u22d6", + "lthree;": "\u22cb", + "ltimes;": "\u22c9", + "ltlarr;": "\u2976", + "ltquest;": "\u2a7b", + "ltrPar;": "\u2996", + "ltri;": "\u25c3", + "ltrie;": "\u22b4", + "ltrif;": "\u25c2", + "lurdshar;": "\u294a", + "luruhar;": "\u2966", + "lvertneqq;": "\u2268\ufe00", + "lvnE;": "\u2268\ufe00", + "mDDot;": "\u223a", + "macr": "\xaf", + "macr;": "\xaf", + "male;": "\u2642", + "malt;": "\u2720", + "maltese;": "\u2720", + "map;": "\u21a6", + "mapsto;": "\u21a6", + "mapstodown;": "\u21a7", + "mapstoleft;": "\u21a4", + "mapstoup;": "\u21a5", + "marker;": "\u25ae", + "mcomma;": "\u2a29", + "mcy;": "\u043c", + "mdash;": "\u2014", + "measuredangle;": "\u2221", + "mfr;": "\U0001d52a", + "mho;": "\u2127", + "micro": "\xb5", + "micro;": "\xb5", + "mid;": "\u2223", + "midast;": "*", + "midcir;": "\u2af0", + "middot": "\xb7", + "middot;": "\xb7", + "minus;": "\u2212", + "minusb;": "\u229f", + "minusd;": "\u2238", + "minusdu;": "\u2a2a", + "mlcp;": "\u2adb", + "mldr;": "\u2026", + "mnplus;": "\u2213", + "models;": "\u22a7", + "mopf;": "\U0001d55e", + "mp;": "\u2213", + "mscr;": "\U0001d4c2", + "mstpos;": "\u223e", + "mu;": "\u03bc", + "multimap;": "\u22b8", + "mumap;": "\u22b8", + "nGg;": "\u22d9\u0338", + "nGt;": "\u226b\u20d2", + "nGtv;": "\u226b\u0338", + "nLeftarrow;": "\u21cd", + "nLeftrightarrow;": "\u21ce", + "nLl;": "\u22d8\u0338", + "nLt;": "\u226a\u20d2", + "nLtv;": "\u226a\u0338", + "nRightarrow;": "\u21cf", + "nVDash;": "\u22af", + "nVdash;": "\u22ae", + "nabla;": "\u2207", + "nacute;": "\u0144", + "nang;": "\u2220\u20d2", + "nap;": "\u2249", + "napE;": "\u2a70\u0338", + "napid;": "\u224b\u0338", + "napos;": "\u0149", + "napprox;": "\u2249", + "natur;": "\u266e", + "natural;": "\u266e", + "naturals;": "\u2115", + "nbsp": "\xa0", + "nbsp;": "\xa0", + "nbump;": "\u224e\u0338", + "nbumpe;": "\u224f\u0338", + "ncap;": "\u2a43", + "ncaron;": "\u0148", + "ncedil;": "\u0146", + "ncong;": "\u2247", + "ncongdot;": "\u2a6d\u0338", + "ncup;": "\u2a42", + "ncy;": "\u043d", + "ndash;": "\u2013", + "ne;": "\u2260", + "neArr;": "\u21d7", + "nearhk;": "\u2924", + "nearr;": "\u2197", + "nearrow;": "\u2197", + "nedot;": "\u2250\u0338", + "nequiv;": "\u2262", + "nesear;": "\u2928", + "nesim;": "\u2242\u0338", + "nexist;": "\u2204", + "nexists;": "\u2204", + "nfr;": "\U0001d52b", + "ngE;": "\u2267\u0338", + "nge;": "\u2271", + "ngeq;": "\u2271", + "ngeqq;": "\u2267\u0338", + "ngeqslant;": "\u2a7e\u0338", + "nges;": "\u2a7e\u0338", + "ngsim;": "\u2275", + "ngt;": "\u226f", + "ngtr;": "\u226f", + "nhArr;": "\u21ce", + "nharr;": "\u21ae", + "nhpar;": "\u2af2", + "ni;": "\u220b", + "nis;": "\u22fc", + "nisd;": "\u22fa", + "niv;": "\u220b", + "njcy;": "\u045a", + "nlArr;": "\u21cd", + "nlE;": "\u2266\u0338", + "nlarr;": "\u219a", + "nldr;": "\u2025", + "nle;": "\u2270", + "nleftarrow;": "\u219a", + "nleftrightarrow;": "\u21ae", + "nleq;": "\u2270", + "nleqq;": "\u2266\u0338", + "nleqslant;": "\u2a7d\u0338", + "nles;": "\u2a7d\u0338", + "nless;": "\u226e", + "nlsim;": "\u2274", + "nlt;": "\u226e", + "nltri;": "\u22ea", + "nltrie;": "\u22ec", + "nmid;": "\u2224", + "nopf;": "\U0001d55f", + "not": "\xac", + "not;": "\xac", + "notin;": "\u2209", + "notinE;": "\u22f9\u0338", + "notindot;": "\u22f5\u0338", + "notinva;": "\u2209", + "notinvb;": "\u22f7", + "notinvc;": "\u22f6", + "notni;": "\u220c", + "notniva;": "\u220c", + "notnivb;": "\u22fe", + "notnivc;": "\u22fd", + "npar;": "\u2226", + "nparallel;": "\u2226", + "nparsl;": "\u2afd\u20e5", + "npart;": "\u2202\u0338", + "npolint;": "\u2a14", + "npr;": "\u2280", + "nprcue;": "\u22e0", + "npre;": "\u2aaf\u0338", + "nprec;": "\u2280", + "npreceq;": "\u2aaf\u0338", + "nrArr;": "\u21cf", + "nrarr;": "\u219b", + "nrarrc;": "\u2933\u0338", + "nrarrw;": "\u219d\u0338", + "nrightarrow;": "\u219b", + "nrtri;": "\u22eb", + "nrtrie;": "\u22ed", + "nsc;": "\u2281", + "nsccue;": "\u22e1", + "nsce;": "\u2ab0\u0338", + "nscr;": "\U0001d4c3", + "nshortmid;": "\u2224", + "nshortparallel;": "\u2226", + "nsim;": "\u2241", + "nsime;": "\u2244", + "nsimeq;": "\u2244", + "nsmid;": "\u2224", + "nspar;": "\u2226", + "nsqsube;": "\u22e2", + "nsqsupe;": "\u22e3", + "nsub;": "\u2284", + "nsubE;": "\u2ac5\u0338", + "nsube;": "\u2288", + "nsubset;": "\u2282\u20d2", + "nsubseteq;": "\u2288", + "nsubseteqq;": "\u2ac5\u0338", + "nsucc;": "\u2281", + "nsucceq;": "\u2ab0\u0338", + "nsup;": "\u2285", + "nsupE;": "\u2ac6\u0338", + "nsupe;": "\u2289", + "nsupset;": "\u2283\u20d2", + "nsupseteq;": "\u2289", + "nsupseteqq;": "\u2ac6\u0338", + "ntgl;": "\u2279", + "ntilde": "\xf1", + "ntilde;": "\xf1", + "ntlg;": "\u2278", + "ntriangleleft;": "\u22ea", + "ntrianglelefteq;": "\u22ec", + "ntriangleright;": "\u22eb", + "ntrianglerighteq;": "\u22ed", + "nu;": "\u03bd", + "num;": "#", + "numero;": "\u2116", + "numsp;": "\u2007", + "nvDash;": "\u22ad", + "nvHarr;": "\u2904", + "nvap;": "\u224d\u20d2", + "nvdash;": "\u22ac", + "nvge;": "\u2265\u20d2", + "nvgt;": ">\u20d2", + "nvinfin;": "\u29de", + "nvlArr;": "\u2902", + "nvle;": "\u2264\u20d2", + "nvlt;": "<\u20d2", + "nvltrie;": "\u22b4\u20d2", + "nvrArr;": "\u2903", + "nvrtrie;": "\u22b5\u20d2", + "nvsim;": "\u223c\u20d2", + "nwArr;": "\u21d6", + "nwarhk;": "\u2923", + "nwarr;": "\u2196", + "nwarrow;": "\u2196", + "nwnear;": "\u2927", + "oS;": "\u24c8", + "oacute": "\xf3", + "oacute;": "\xf3", + "oast;": "\u229b", + "ocir;": "\u229a", + "ocirc": "\xf4", + "ocirc;": "\xf4", + "ocy;": "\u043e", + "odash;": "\u229d", + "odblac;": "\u0151", + "odiv;": "\u2a38", + "odot;": "\u2299", + "odsold;": "\u29bc", + "oelig;": "\u0153", + "ofcir;": "\u29bf", + "ofr;": "\U0001d52c", + "ogon;": "\u02db", + "ograve": "\xf2", + "ograve;": "\xf2", + "ogt;": "\u29c1", + "ohbar;": "\u29b5", + "ohm;": "\u03a9", + "oint;": "\u222e", + "olarr;": "\u21ba", + "olcir;": "\u29be", + "olcross;": "\u29bb", + "oline;": "\u203e", + "olt;": "\u29c0", + "omacr;": "\u014d", + "omega;": "\u03c9", + "omicron;": "\u03bf", + "omid;": "\u29b6", + "ominus;": "\u2296", + "oopf;": "\U0001d560", + "opar;": "\u29b7", + "operp;": "\u29b9", + "oplus;": "\u2295", + "or;": "\u2228", + "orarr;": "\u21bb", + "ord;": "\u2a5d", + "order;": "\u2134", + "orderof;": "\u2134", + "ordf": "\xaa", + "ordf;": "\xaa", + "ordm": "\xba", + "ordm;": "\xba", + "origof;": "\u22b6", + "oror;": "\u2a56", + "orslope;": "\u2a57", + "orv;": "\u2a5b", + "oscr;": "\u2134", + "oslash": "\xf8", + "oslash;": "\xf8", + "osol;": "\u2298", + "otilde": "\xf5", + "otilde;": "\xf5", + "otimes;": "\u2297", + "otimesas;": "\u2a36", + "ouml": "\xf6", + "ouml;": "\xf6", + "ovbar;": "\u233d", + "par;": "\u2225", + "para": "\xb6", + "para;": "\xb6", + "parallel;": "\u2225", + "parsim;": "\u2af3", + "parsl;": "\u2afd", + "part;": "\u2202", + "pcy;": "\u043f", + "percnt;": "%", + "period;": ".", + "permil;": "\u2030", + "perp;": "\u22a5", + "pertenk;": "\u2031", + "pfr;": "\U0001d52d", + "phi;": "\u03c6", + "phiv;": "\u03d5", + "phmmat;": "\u2133", + "phone;": "\u260e", + "pi;": "\u03c0", + "pitchfork;": "\u22d4", + "piv;": "\u03d6", + "planck;": "\u210f", + "planckh;": "\u210e", + "plankv;": "\u210f", + "plus;": "+", + "plusacir;": "\u2a23", + "plusb;": "\u229e", + "pluscir;": "\u2a22", + "plusdo;": "\u2214", + "plusdu;": "\u2a25", + "pluse;": "\u2a72", + "plusmn": "\xb1", + "plusmn;": "\xb1", + "plussim;": "\u2a26", + "plustwo;": "\u2a27", + "pm;": "\xb1", + "pointint;": "\u2a15", + "popf;": "\U0001d561", + "pound": "\xa3", + "pound;": "\xa3", + "pr;": "\u227a", + "prE;": "\u2ab3", + "prap;": "\u2ab7", + "prcue;": "\u227c", + "pre;": "\u2aaf", + "prec;": "\u227a", + "precapprox;": "\u2ab7", + "preccurlyeq;": "\u227c", + "preceq;": "\u2aaf", + "precnapprox;": "\u2ab9", + "precneqq;": "\u2ab5", + "precnsim;": "\u22e8", + "precsim;": "\u227e", + "prime;": "\u2032", + "primes;": "\u2119", + "prnE;": "\u2ab5", + "prnap;": "\u2ab9", + "prnsim;": "\u22e8", + "prod;": "\u220f", + "profalar;": "\u232e", + "profline;": "\u2312", + "profsurf;": "\u2313", + "prop;": "\u221d", + "propto;": "\u221d", + "prsim;": "\u227e", + "prurel;": "\u22b0", + "pscr;": "\U0001d4c5", + "psi;": "\u03c8", + "puncsp;": "\u2008", + "qfr;": "\U0001d52e", + "qint;": "\u2a0c", + "qopf;": "\U0001d562", + "qprime;": "\u2057", + "qscr;": "\U0001d4c6", + "quaternions;": "\u210d", + "quatint;": "\u2a16", + "quest;": "?", + "questeq;": "\u225f", + "quot": "\"", + "quot;": "\"", + "rAarr;": "\u21db", + "rArr;": "\u21d2", + "rAtail;": "\u291c", + "rBarr;": "\u290f", + "rHar;": "\u2964", + "race;": "\u223d\u0331", + "racute;": "\u0155", + "radic;": "\u221a", + "raemptyv;": "\u29b3", + "rang;": "\u27e9", + "rangd;": "\u2992", + "range;": "\u29a5", + "rangle;": "\u27e9", + "raquo": "\xbb", + "raquo;": "\xbb", + "rarr;": "\u2192", + "rarrap;": "\u2975", + "rarrb;": "\u21e5", + "rarrbfs;": "\u2920", + "rarrc;": "\u2933", + "rarrfs;": "\u291e", + "rarrhk;": "\u21aa", + "rarrlp;": "\u21ac", + "rarrpl;": "\u2945", + "rarrsim;": "\u2974", + "rarrtl;": "\u21a3", + "rarrw;": "\u219d", + "ratail;": "\u291a", + "ratio;": "\u2236", + "rationals;": "\u211a", + "rbarr;": "\u290d", + "rbbrk;": "\u2773", + "rbrace;": "}", + "rbrack;": "]", + "rbrke;": "\u298c", + "rbrksld;": "\u298e", + "rbrkslu;": "\u2990", + "rcaron;": "\u0159", + "rcedil;": "\u0157", + "rceil;": "\u2309", + "rcub;": "}", + "rcy;": "\u0440", + "rdca;": "\u2937", + "rdldhar;": "\u2969", + "rdquo;": "\u201d", + "rdquor;": "\u201d", + "rdsh;": "\u21b3", + "real;": "\u211c", + "realine;": "\u211b", + "realpart;": "\u211c", + "reals;": "\u211d", + "rect;": "\u25ad", + "reg": "\xae", + "reg;": "\xae", + "rfisht;": "\u297d", + "rfloor;": "\u230b", + "rfr;": "\U0001d52f", + "rhard;": "\u21c1", + "rharu;": "\u21c0", + "rharul;": "\u296c", + "rho;": "\u03c1", + "rhov;": "\u03f1", + "rightarrow;": "\u2192", + "rightarrowtail;": "\u21a3", + "rightharpoondown;": "\u21c1", + "rightharpoonup;": "\u21c0", + "rightleftarrows;": "\u21c4", + "rightleftharpoons;": "\u21cc", + "rightrightarrows;": "\u21c9", + "rightsquigarrow;": "\u219d", + "rightthreetimes;": "\u22cc", + "ring;": "\u02da", + "risingdotseq;": "\u2253", + "rlarr;": "\u21c4", + "rlhar;": "\u21cc", + "rlm;": "\u200f", + "rmoust;": "\u23b1", + "rmoustache;": "\u23b1", + "rnmid;": "\u2aee", + "roang;": "\u27ed", + "roarr;": "\u21fe", + "robrk;": "\u27e7", + "ropar;": "\u2986", + "ropf;": "\U0001d563", + "roplus;": "\u2a2e", + "rotimes;": "\u2a35", + "rpar;": ")", + "rpargt;": "\u2994", + "rppolint;": "\u2a12", + "rrarr;": "\u21c9", + "rsaquo;": "\u203a", + "rscr;": "\U0001d4c7", + "rsh;": "\u21b1", + "rsqb;": "]", + "rsquo;": "\u2019", + "rsquor;": "\u2019", + "rthree;": "\u22cc", + "rtimes;": "\u22ca", + "rtri;": "\u25b9", + "rtrie;": "\u22b5", + "rtrif;": "\u25b8", + "rtriltri;": "\u29ce", + "ruluhar;": "\u2968", + "rx;": "\u211e", + "sacute;": "\u015b", + "sbquo;": "\u201a", + "sc;": "\u227b", + "scE;": "\u2ab4", + "scap;": "\u2ab8", + "scaron;": "\u0161", + "sccue;": "\u227d", + "sce;": "\u2ab0", + "scedil;": "\u015f", + "scirc;": "\u015d", + "scnE;": "\u2ab6", + "scnap;": "\u2aba", + "scnsim;": "\u22e9", + "scpolint;": "\u2a13", + "scsim;": "\u227f", + "scy;": "\u0441", + "sdot;": "\u22c5", + "sdotb;": "\u22a1", + "sdote;": "\u2a66", + "seArr;": "\u21d8", + "searhk;": "\u2925", + "searr;": "\u2198", + "searrow;": "\u2198", + "sect": "\xa7", + "sect;": "\xa7", + "semi;": ";", + "seswar;": "\u2929", + "setminus;": "\u2216", + "setmn;": "\u2216", + "sext;": "\u2736", + "sfr;": "\U0001d530", + "sfrown;": "\u2322", + "sharp;": "\u266f", + "shchcy;": "\u0449", + "shcy;": "\u0448", + "shortmid;": "\u2223", + "shortparallel;": "\u2225", + "shy": "\xad", + "shy;": "\xad", + "sigma;": "\u03c3", + "sigmaf;": "\u03c2", + "sigmav;": "\u03c2", + "sim;": "\u223c", + "simdot;": "\u2a6a", + "sime;": "\u2243", + "simeq;": "\u2243", + "simg;": "\u2a9e", + "simgE;": "\u2aa0", + "siml;": "\u2a9d", + "simlE;": "\u2a9f", + "simne;": "\u2246", + "simplus;": "\u2a24", + "simrarr;": "\u2972", + "slarr;": "\u2190", + "smallsetminus;": "\u2216", + "smashp;": "\u2a33", + "smeparsl;": "\u29e4", + "smid;": "\u2223", + "smile;": "\u2323", + "smt;": "\u2aaa", + "smte;": "\u2aac", + "smtes;": "\u2aac\ufe00", + "softcy;": "\u044c", + "sol;": "/", + "solb;": "\u29c4", + "solbar;": "\u233f", + "sopf;": "\U0001d564", + "spades;": "\u2660", + "spadesuit;": "\u2660", + "spar;": "\u2225", + "sqcap;": "\u2293", + "sqcaps;": "\u2293\ufe00", + "sqcup;": "\u2294", + "sqcups;": "\u2294\ufe00", + "sqsub;": "\u228f", + "sqsube;": "\u2291", + "sqsubset;": "\u228f", + "sqsubseteq;": "\u2291", + "sqsup;": "\u2290", + "sqsupe;": "\u2292", + "sqsupset;": "\u2290", + "sqsupseteq;": "\u2292", + "squ;": "\u25a1", + "square;": "\u25a1", + "squarf;": "\u25aa", + "squf;": "\u25aa", + "srarr;": "\u2192", + "sscr;": "\U0001d4c8", + "ssetmn;": "\u2216", + "ssmile;": "\u2323", + "sstarf;": "\u22c6", + "star;": "\u2606", + "starf;": "\u2605", + "straightepsilon;": "\u03f5", + "straightphi;": "\u03d5", + "strns;": "\xaf", + "sub;": "\u2282", + "subE;": "\u2ac5", + "subdot;": "\u2abd", + "sube;": "\u2286", + "subedot;": "\u2ac3", + "submult;": "\u2ac1", + "subnE;": "\u2acb", + "subne;": "\u228a", + "subplus;": "\u2abf", + "subrarr;": "\u2979", + "subset;": "\u2282", + "subseteq;": "\u2286", + "subseteqq;": "\u2ac5", + "subsetneq;": "\u228a", + "subsetneqq;": "\u2acb", + "subsim;": "\u2ac7", + "subsub;": "\u2ad5", + "subsup;": "\u2ad3", + "succ;": "\u227b", + "succapprox;": "\u2ab8", + "succcurlyeq;": "\u227d", + "succeq;": "\u2ab0", + "succnapprox;": "\u2aba", + "succneqq;": "\u2ab6", + "succnsim;": "\u22e9", + "succsim;": "\u227f", + "sum;": "\u2211", + "sung;": "\u266a", + "sup1": "\xb9", + "sup1;": "\xb9", + "sup2": "\xb2", + "sup2;": "\xb2", + "sup3": "\xb3", + "sup3;": "\xb3", + "sup;": "\u2283", + "supE;": "\u2ac6", + "supdot;": "\u2abe", + "supdsub;": "\u2ad8", + "supe;": "\u2287", + "supedot;": "\u2ac4", + "suphsol;": "\u27c9", + "suphsub;": "\u2ad7", + "suplarr;": "\u297b", + "supmult;": "\u2ac2", + "supnE;": "\u2acc", + "supne;": "\u228b", + "supplus;": "\u2ac0", + "supset;": "\u2283", + "supseteq;": "\u2287", + "supseteqq;": "\u2ac6", + "supsetneq;": "\u228b", + "supsetneqq;": "\u2acc", + "supsim;": "\u2ac8", + "supsub;": "\u2ad4", + "supsup;": "\u2ad6", + "swArr;": "\u21d9", + "swarhk;": "\u2926", + "swarr;": "\u2199", + "swarrow;": "\u2199", + "swnwar;": "\u292a", + "szlig": "\xdf", + "szlig;": "\xdf", + "target;": "\u2316", + "tau;": "\u03c4", + "tbrk;": "\u23b4", + "tcaron;": "\u0165", + "tcedil;": "\u0163", + "tcy;": "\u0442", + "tdot;": "\u20db", + "telrec;": "\u2315", + "tfr;": "\U0001d531", + "there4;": "\u2234", + "therefore;": "\u2234", + "theta;": "\u03b8", + "thetasym;": "\u03d1", + "thetav;": "\u03d1", + "thickapprox;": "\u2248", + "thicksim;": "\u223c", + "thinsp;": "\u2009", + "thkap;": "\u2248", + "thksim;": "\u223c", + "thorn": "\xfe", + "thorn;": "\xfe", + "tilde;": "\u02dc", + "times": "\xd7", + "times;": "\xd7", + "timesb;": "\u22a0", + "timesbar;": "\u2a31", + "timesd;": "\u2a30", + "tint;": "\u222d", + "toea;": "\u2928", + "top;": "\u22a4", + "topbot;": "\u2336", + "topcir;": "\u2af1", + "topf;": "\U0001d565", + "topfork;": "\u2ada", + "tosa;": "\u2929", + "tprime;": "\u2034", + "trade;": "\u2122", + "triangle;": "\u25b5", + "triangledown;": "\u25bf", + "triangleleft;": "\u25c3", + "trianglelefteq;": "\u22b4", + "triangleq;": "\u225c", + "triangleright;": "\u25b9", + "trianglerighteq;": "\u22b5", + "tridot;": "\u25ec", + "trie;": "\u225c", + "triminus;": "\u2a3a", + "triplus;": "\u2a39", + "trisb;": "\u29cd", + "tritime;": "\u2a3b", + "trpezium;": "\u23e2", + "tscr;": "\U0001d4c9", + "tscy;": "\u0446", + "tshcy;": "\u045b", + "tstrok;": "\u0167", + "twixt;": "\u226c", + "twoheadleftarrow;": "\u219e", + "twoheadrightarrow;": "\u21a0", + "uArr;": "\u21d1", + "uHar;": "\u2963", + "uacute": "\xfa", + "uacute;": "\xfa", + "uarr;": "\u2191", + "ubrcy;": "\u045e", + "ubreve;": "\u016d", + "ucirc": "\xfb", + "ucirc;": "\xfb", + "ucy;": "\u0443", + "udarr;": "\u21c5", + "udblac;": "\u0171", + "udhar;": "\u296e", + "ufisht;": "\u297e", + "ufr;": "\U0001d532", + "ugrave": "\xf9", + "ugrave;": "\xf9", + "uharl;": "\u21bf", + "uharr;": "\u21be", + "uhblk;": "\u2580", + "ulcorn;": "\u231c", + "ulcorner;": "\u231c", + "ulcrop;": "\u230f", + "ultri;": "\u25f8", + "umacr;": "\u016b", + "uml": "\xa8", + "uml;": "\xa8", + "uogon;": "\u0173", + "uopf;": "\U0001d566", + "uparrow;": "\u2191", + "updownarrow;": "\u2195", + "upharpoonleft;": "\u21bf", + "upharpoonright;": "\u21be", + "uplus;": "\u228e", + "upsi;": "\u03c5", + "upsih;": "\u03d2", + "upsilon;": "\u03c5", + "upuparrows;": "\u21c8", + "urcorn;": "\u231d", + "urcorner;": "\u231d", + "urcrop;": "\u230e", + "uring;": "\u016f", + "urtri;": "\u25f9", + "uscr;": "\U0001d4ca", + "utdot;": "\u22f0", + "utilde;": "\u0169", + "utri;": "\u25b5", + "utrif;": "\u25b4", + "uuarr;": "\u21c8", + "uuml": "\xfc", + "uuml;": "\xfc", + "uwangle;": "\u29a7", + "vArr;": "\u21d5", + "vBar;": "\u2ae8", + "vBarv;": "\u2ae9", + "vDash;": "\u22a8", + "vangrt;": "\u299c", + "varepsilon;": "\u03f5", + "varkappa;": "\u03f0", + "varnothing;": "\u2205", + "varphi;": "\u03d5", + "varpi;": "\u03d6", + "varpropto;": "\u221d", + "varr;": "\u2195", + "varrho;": "\u03f1", + "varsigma;": "\u03c2", + "varsubsetneq;": "\u228a\ufe00", + "varsubsetneqq;": "\u2acb\ufe00", + "varsupsetneq;": "\u228b\ufe00", + "varsupsetneqq;": "\u2acc\ufe00", + "vartheta;": "\u03d1", + "vartriangleleft;": "\u22b2", + "vartriangleright;": "\u22b3", + "vcy;": "\u0432", + "vdash;": "\u22a2", + "vee;": "\u2228", + "veebar;": "\u22bb", + "veeeq;": "\u225a", + "vellip;": "\u22ee", + "verbar;": "|", + "vert;": "|", + "vfr;": "\U0001d533", + "vltri;": "\u22b2", + "vnsub;": "\u2282\u20d2", + "vnsup;": "\u2283\u20d2", + "vopf;": "\U0001d567", + "vprop;": "\u221d", + "vrtri;": "\u22b3", + "vscr;": "\U0001d4cb", + "vsubnE;": "\u2acb\ufe00", + "vsubne;": "\u228a\ufe00", + "vsupnE;": "\u2acc\ufe00", + "vsupne;": "\u228b\ufe00", + "vzigzag;": "\u299a", + "wcirc;": "\u0175", + "wedbar;": "\u2a5f", + "wedge;": "\u2227", + "wedgeq;": "\u2259", + "weierp;": "\u2118", + "wfr;": "\U0001d534", + "wopf;": "\U0001d568", + "wp;": "\u2118", + "wr;": "\u2240", + "wreath;": "\u2240", + "wscr;": "\U0001d4cc", + "xcap;": "\u22c2", + "xcirc;": "\u25ef", + "xcup;": "\u22c3", + "xdtri;": "\u25bd", + "xfr;": "\U0001d535", + "xhArr;": "\u27fa", + "xharr;": "\u27f7", + "xi;": "\u03be", + "xlArr;": "\u27f8", + "xlarr;": "\u27f5", + "xmap;": "\u27fc", + "xnis;": "\u22fb", + "xodot;": "\u2a00", + "xopf;": "\U0001d569", + "xoplus;": "\u2a01", + "xotime;": "\u2a02", + "xrArr;": "\u27f9", + "xrarr;": "\u27f6", + "xscr;": "\U0001d4cd", + "xsqcup;": "\u2a06", + "xuplus;": "\u2a04", + "xutri;": "\u25b3", + "xvee;": "\u22c1", + "xwedge;": "\u22c0", + "yacute": "\xfd", + "yacute;": "\xfd", + "yacy;": "\u044f", + "ycirc;": "\u0177", + "ycy;": "\u044b", + "yen": "\xa5", + "yen;": "\xa5", + "yfr;": "\U0001d536", + "yicy;": "\u0457", + "yopf;": "\U0001d56a", + "yscr;": "\U0001d4ce", + "yucy;": "\u044e", + "yuml": "\xff", + "yuml;": "\xff", + "zacute;": "\u017a", + "zcaron;": "\u017e", + "zcy;": "\u0437", + "zdot;": "\u017c", + "zeetrf;": "\u2128", + "zeta;": "\u03b6", + "zfr;": "\U0001d537", + "zhcy;": "\u0436", + "zigrarr;": "\u21dd", + "zopf;": "\U0001d56b", + "zscr;": "\U0001d4cf", + "zwj;": "\u200d", + "zwnj;": "\u200c", +} + +replacementCharacters = { + 0x0: "\uFFFD", + 0x0d: "\u000D", + 0x80: "\u20AC", + 0x81: "\u0081", + 0x82: "\u201A", + 0x83: "\u0192", + 0x84: "\u201E", + 0x85: "\u2026", + 0x86: "\u2020", + 0x87: "\u2021", + 0x88: "\u02C6", + 0x89: "\u2030", + 0x8A: "\u0160", + 0x8B: "\u2039", + 0x8C: "\u0152", + 0x8D: "\u008D", + 0x8E: "\u017D", + 0x8F: "\u008F", + 0x90: "\u0090", + 0x91: "\u2018", + 0x92: "\u2019", + 0x93: "\u201C", + 0x94: "\u201D", + 0x95: "\u2022", + 0x96: "\u2013", + 0x97: "\u2014", + 0x98: "\u02DC", + 0x99: "\u2122", + 0x9A: "\u0161", + 0x9B: "\u203A", + 0x9C: "\u0153", + 0x9D: "\u009D", + 0x9E: "\u017E", + 0x9F: "\u0178", +} + +tokenTypes = { + "Doctype": 0, + "Characters": 1, + "SpaceCharacters": 2, + "StartTag": 3, + "EndTag": 4, + "EmptyTag": 5, + "Comment": 6, + "ParseError": 7 +} + +tagTokenTypes = frozenset([tokenTypes["StartTag"], tokenTypes["EndTag"], + tokenTypes["EmptyTag"]]) + + +prefixes = dict([(v, k) for k, v in namespaces.items()]) +prefixes["http://www.w3.org/1998/Math/MathML"] = "math" + + +class DataLossWarning(UserWarning): + """Raised when the current tree is unable to represent the input data""" + pass + + +class _ReparseException(Exception): + pass diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/alphabeticalattributes.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/alphabeticalattributes.py new file mode 100644 index 0000000..5ba926e --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/alphabeticalattributes.py @@ -0,0 +1,29 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + +from collections import OrderedDict + + +def _attr_key(attr): + """Return an appropriate key for an attribute for sorting + + Attributes have a namespace that can be either ``None`` or a string. We + can't compare the two because they're different types, so we convert + ``None`` to an empty string first. + + """ + return (attr[0][0] or ''), attr[0][1] + + +class Filter(base.Filter): + """Alphabetizes attributes for elements""" + def __iter__(self): + for token in base.Filter.__iter__(self): + if token["type"] in ("StartTag", "EmptyTag"): + attrs = OrderedDict() + for name, value in sorted(token["data"].items(), + key=_attr_key): + attrs[name] = value + token["data"] = attrs + yield token diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/base.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/base.py new file mode 100644 index 0000000..c7dbaed --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/base.py @@ -0,0 +1,12 @@ +from __future__ import absolute_import, division, unicode_literals + + +class Filter(object): + def __init__(self, source): + self.source = source + + def __iter__(self): + return iter(self.source) + + def __getattr__(self, name): + return getattr(self.source, name) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/inject_meta_charset.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/inject_meta_charset.py new file mode 100644 index 0000000..aefb5c8 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/inject_meta_charset.py @@ -0,0 +1,73 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + + +class Filter(base.Filter): + """Injects ``<meta charset=ENCODING>`` tag into head of document""" + def __init__(self, source, encoding): + """Creates a Filter + + :arg source: the source token stream + + :arg encoding: the encoding to set + + """ + base.Filter.__init__(self, source) + self.encoding = encoding + + def __iter__(self): + state = "pre_head" + meta_found = (self.encoding is None) + pending = [] + + for token in base.Filter.__iter__(self): + type = token["type"] + if type == "StartTag": + if token["name"].lower() == "head": + state = "in_head" + + elif type == "EmptyTag": + if token["name"].lower() == "meta": + # replace charset with actual encoding + has_http_equiv_content_type = False + for (namespace, name), value in token["data"].items(): + if namespace is not None: + continue + elif name.lower() == 'charset': + token["data"][(namespace, name)] = self.encoding + meta_found = True + break + elif name == 'http-equiv' and value.lower() == 'content-type': + has_http_equiv_content_type = True + else: + if has_http_equiv_content_type and (None, "content") in token["data"]: + token["data"][(None, "content")] = 'text/html; charset=%s' % self.encoding + meta_found = True + + elif token["name"].lower() == "head" and not meta_found: + # insert meta into empty head + yield {"type": "StartTag", "name": "head", + "data": token["data"]} + yield {"type": "EmptyTag", "name": "meta", + "data": {(None, "charset"): self.encoding}} + yield {"type": "EndTag", "name": "head"} + meta_found = True + continue + + elif type == "EndTag": + if token["name"].lower() == "head" and pending: + # insert meta into head (if necessary) and flush pending queue + yield pending.pop(0) + if not meta_found: + yield {"type": "EmptyTag", "name": "meta", + "data": {(None, "charset"): self.encoding}} + while pending: + yield pending.pop(0) + meta_found = True + state = "post_head" + + if state == "in_head": + pending.append(token) + else: + yield token diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/lint.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/lint.py new file mode 100644 index 0000000..fcc07ee --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/lint.py @@ -0,0 +1,93 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import text_type + +from . import base +from ..constants import namespaces, voidElements + +from ..constants import spaceCharacters +spaceCharacters = "".join(spaceCharacters) + + +class Filter(base.Filter): + """Lints the token stream for errors + + If it finds any errors, it'll raise an ``AssertionError``. + + """ + def __init__(self, source, require_matching_tags=True): + """Creates a Filter + + :arg source: the source token stream + + :arg require_matching_tags: whether or not to require matching tags + + """ + super(Filter, self).__init__(source) + self.require_matching_tags = require_matching_tags + + def __iter__(self): + open_elements = [] + for token in base.Filter.__iter__(self): + type = token["type"] + if type in ("StartTag", "EmptyTag"): + namespace = token["namespace"] + name = token["name"] + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + assert isinstance(token["data"], dict) + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + assert type == "EmptyTag" + else: + assert type == "StartTag" + if type == "StartTag" and self.require_matching_tags: + open_elements.append((namespace, name)) + for (namespace, name), value in token["data"].items(): + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + assert isinstance(value, text_type) + + elif type == "EndTag": + namespace = token["namespace"] + name = token["name"] + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + assert False, "Void element reported as EndTag token: %(tag)s" % {"tag": name} + elif self.require_matching_tags: + start = open_elements.pop() + assert start == (namespace, name) + + elif type == "Comment": + data = token["data"] + assert isinstance(data, text_type) + + elif type in ("Characters", "SpaceCharacters"): + data = token["data"] + assert isinstance(data, text_type) + assert data != "" + if type == "SpaceCharacters": + assert data.strip(spaceCharacters) == "" + + elif type == "Doctype": + name = token["name"] + assert name is None or isinstance(name, text_type) + assert token["publicId"] is None or isinstance(name, text_type) + assert token["systemId"] is None or isinstance(name, text_type) + + elif type == "Entity": + assert isinstance(token["name"], text_type) + + elif type == "SerializerError": + assert isinstance(token["data"], text_type) + + else: + assert False, "Unknown token type: %(type)s" % {"type": type} + + yield token diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/optionaltags.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/optionaltags.py new file mode 100644 index 0000000..4a86501 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/optionaltags.py @@ -0,0 +1,207 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + + +class Filter(base.Filter): + """Removes optional tags from the token stream""" + def slider(self): + previous1 = previous2 = None + for token in self.source: + if previous1 is not None: + yield previous2, previous1, token + previous2 = previous1 + previous1 = token + if previous1 is not None: + yield previous2, previous1, None + + def __iter__(self): + for previous, token, next in self.slider(): + type = token["type"] + if type == "StartTag": + if (token["data"] or + not self.is_optional_start(token["name"], previous, next)): + yield token + elif type == "EndTag": + if not self.is_optional_end(token["name"], next): + yield token + else: + yield token + + def is_optional_start(self, tagname, previous, next): + type = next and next["type"] or None + if tagname in 'html': + # An html element's start tag may be omitted if the first thing + # inside the html element is not a space character or a comment. + return type not in ("Comment", "SpaceCharacters") + elif tagname == 'head': + # A head element's start tag may be omitted if the first thing + # inside the head element is an element. + # XXX: we also omit the start tag if the head element is empty + if type in ("StartTag", "EmptyTag"): + return True + elif type == "EndTag": + return next["name"] == "head" + elif tagname == 'body': + # A body element's start tag may be omitted if the first thing + # inside the body element is not a space character or a comment, + # except if the first thing inside the body element is a script + # or style element and the node immediately preceding the body + # element is a head element whose end tag has been omitted. + if type in ("Comment", "SpaceCharacters"): + return False + elif type == "StartTag": + # XXX: we do not look at the preceding event, so we never omit + # the body element's start tag if it's followed by a script or + # a style element. + return next["name"] not in ('script', 'style') + else: + return True + elif tagname == 'colgroup': + # A colgroup element's start tag may be omitted if the first thing + # inside the colgroup element is a col element, and if the element + # is not immediately preceded by another colgroup element whose + # end tag has been omitted. + if type in ("StartTag", "EmptyTag"): + # XXX: we do not look at the preceding event, so instead we never + # omit the colgroup element's end tag when it is immediately + # followed by another colgroup element. See is_optional_end. + return next["name"] == "col" + else: + return False + elif tagname == 'tbody': + # A tbody element's start tag may be omitted if the first thing + # inside the tbody element is a tr element, and if the element is + # not immediately preceded by a tbody, thead, or tfoot element + # whose end tag has been omitted. + if type == "StartTag": + # omit the thead and tfoot elements' end tag when they are + # immediately followed by a tbody element. See is_optional_end. + if previous and previous['type'] == 'EndTag' and \ + previous['name'] in ('tbody', 'thead', 'tfoot'): + return False + return next["name"] == 'tr' + else: + return False + return False + + def is_optional_end(self, tagname, next): + type = next and next["type"] or None + if tagname in ('html', 'head', 'body'): + # An html element's end tag may be omitted if the html element + # is not immediately followed by a space character or a comment. + return type not in ("Comment", "SpaceCharacters") + elif tagname in ('li', 'optgroup', 'tr'): + # A li element's end tag may be omitted if the li element is + # immediately followed by another li element or if there is + # no more content in the parent element. + # An optgroup element's end tag may be omitted if the optgroup + # element is immediately followed by another optgroup element, + # or if there is no more content in the parent element. + # A tr element's end tag may be omitted if the tr element is + # immediately followed by another tr element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] == tagname + else: + return type == "EndTag" or type is None + elif tagname in ('dt', 'dd'): + # A dt element's end tag may be omitted if the dt element is + # immediately followed by another dt element or a dd element. + # A dd element's end tag may be omitted if the dd element is + # immediately followed by another dd element or a dt element, + # or if there is no more content in the parent element. + if type == "StartTag": + return next["name"] in ('dt', 'dd') + elif tagname == 'dd': + return type == "EndTag" or type is None + else: + return False + elif tagname == 'p': + # A p element's end tag may be omitted if the p element is + # immediately followed by an address, article, aside, + # blockquote, datagrid, dialog, dir, div, dl, fieldset, + # footer, form, h1, h2, h3, h4, h5, h6, header, hr, menu, + # nav, ol, p, pre, section, table, or ul, element, or if + # there is no more content in the parent element. + if type in ("StartTag", "EmptyTag"): + return next["name"] in ('address', 'article', 'aside', + 'blockquote', 'datagrid', 'dialog', + 'dir', 'div', 'dl', 'fieldset', 'footer', + 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', + 'header', 'hr', 'menu', 'nav', 'ol', + 'p', 'pre', 'section', 'table', 'ul') + else: + return type == "EndTag" or type is None + elif tagname == 'option': + # An option element's end tag may be omitted if the option + # element is immediately followed by another option element, + # or if it is immediately followed by an <code>optgroup</code> + # element, or if there is no more content in the parent + # element. + if type == "StartTag": + return next["name"] in ('option', 'optgroup') + else: + return type == "EndTag" or type is None + elif tagname in ('rt', 'rp'): + # An rt element's end tag may be omitted if the rt element is + # immediately followed by an rt or rp element, or if there is + # no more content in the parent element. + # An rp element's end tag may be omitted if the rp element is + # immediately followed by an rt or rp element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] in ('rt', 'rp') + else: + return type == "EndTag" or type is None + elif tagname == 'colgroup': + # A colgroup element's end tag may be omitted if the colgroup + # element is not immediately followed by a space character or + # a comment. + if type in ("Comment", "SpaceCharacters"): + return False + elif type == "StartTag": + # XXX: we also look for an immediately following colgroup + # element. See is_optional_start. + return next["name"] != 'colgroup' + else: + return True + elif tagname in ('thead', 'tbody'): + # A thead element's end tag may be omitted if the thead element + # is immediately followed by a tbody or tfoot element. + # A tbody element's end tag may be omitted if the tbody element + # is immediately followed by a tbody or tfoot element, or if + # there is no more content in the parent element. + # A tfoot element's end tag may be omitted if the tfoot element + # is immediately followed by a tbody element, or if there is no + # more content in the parent element. + # XXX: we never omit the end tag when the following element is + # a tbody. See is_optional_start. + if type == "StartTag": + return next["name"] in ['tbody', 'tfoot'] + elif tagname == 'tbody': + return type == "EndTag" or type is None + else: + return False + elif tagname == 'tfoot': + # A tfoot element's end tag may be omitted if the tfoot element + # is immediately followed by a tbody element, or if there is no + # more content in the parent element. + # XXX: we never omit the end tag when the following element is + # a tbody. See is_optional_start. + if type == "StartTag": + return next["name"] == 'tbody' + else: + return type == "EndTag" or type is None + elif tagname in ('td', 'th'): + # A td element's end tag may be omitted if the td element is + # immediately followed by a td or th element, or if there is + # no more content in the parent element. + # A th element's end tag may be omitted if the th element is + # immediately followed by a td or th element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] in ('td', 'th') + else: + return type == "EndTag" or type is None + return False diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/sanitizer.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/sanitizer.py new file mode 100644 index 0000000..af8e77b --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/sanitizer.py @@ -0,0 +1,896 @@ +from __future__ import absolute_import, division, unicode_literals + +import re +from xml.sax.saxutils import escape, unescape + +from pip._vendor.six.moves import urllib_parse as urlparse + +from . import base +from ..constants import namespaces, prefixes + +__all__ = ["Filter"] + + +allowed_elements = frozenset(( + (namespaces['html'], 'a'), + (namespaces['html'], 'abbr'), + (namespaces['html'], 'acronym'), + (namespaces['html'], 'address'), + (namespaces['html'], 'area'), + (namespaces['html'], 'article'), + (namespaces['html'], 'aside'), + (namespaces['html'], 'audio'), + (namespaces['html'], 'b'), + (namespaces['html'], 'big'), + (namespaces['html'], 'blockquote'), + (namespaces['html'], 'br'), + (namespaces['html'], 'button'), + (namespaces['html'], 'canvas'), + (namespaces['html'], 'caption'), + (namespaces['html'], 'center'), + (namespaces['html'], 'cite'), + (namespaces['html'], 'code'), + (namespaces['html'], 'col'), + (namespaces['html'], 'colgroup'), + (namespaces['html'], 'command'), + (namespaces['html'], 'datagrid'), + (namespaces['html'], 'datalist'), + (namespaces['html'], 'dd'), + (namespaces['html'], 'del'), + (namespaces['html'], 'details'), + (namespaces['html'], 'dfn'), + (namespaces['html'], 'dialog'), + (namespaces['html'], 'dir'), + (namespaces['html'], 'div'), + (namespaces['html'], 'dl'), + (namespaces['html'], 'dt'), + (namespaces['html'], 'em'), + (namespaces['html'], 'event-source'), + (namespaces['html'], 'fieldset'), + (namespaces['html'], 'figcaption'), + (namespaces['html'], 'figure'), + (namespaces['html'], 'footer'), + (namespaces['html'], 'font'), + (namespaces['html'], 'form'), + (namespaces['html'], 'header'), + (namespaces['html'], 'h1'), + (namespaces['html'], 'h2'), + (namespaces['html'], 'h3'), + (namespaces['html'], 'h4'), + (namespaces['html'], 'h5'), + (namespaces['html'], 'h6'), + (namespaces['html'], 'hr'), + (namespaces['html'], 'i'), + (namespaces['html'], 'img'), + (namespaces['html'], 'input'), + (namespaces['html'], 'ins'), + (namespaces['html'], 'keygen'), + (namespaces['html'], 'kbd'), + (namespaces['html'], 'label'), + (namespaces['html'], 'legend'), + (namespaces['html'], 'li'), + (namespaces['html'], 'm'), + (namespaces['html'], 'map'), + (namespaces['html'], 'menu'), + (namespaces['html'], 'meter'), + (namespaces['html'], 'multicol'), + (namespaces['html'], 'nav'), + (namespaces['html'], 'nextid'), + (namespaces['html'], 'ol'), + (namespaces['html'], 'output'), + (namespaces['html'], 'optgroup'), + (namespaces['html'], 'option'), + (namespaces['html'], 'p'), + (namespaces['html'], 'pre'), + (namespaces['html'], 'progress'), + (namespaces['html'], 'q'), + (namespaces['html'], 's'), + (namespaces['html'], 'samp'), + (namespaces['html'], 'section'), + (namespaces['html'], 'select'), + (namespaces['html'], 'small'), + (namespaces['html'], 'sound'), + (namespaces['html'], 'source'), + (namespaces['html'], 'spacer'), + (namespaces['html'], 'span'), + (namespaces['html'], 'strike'), + (namespaces['html'], 'strong'), + (namespaces['html'], 'sub'), + (namespaces['html'], 'sup'), + (namespaces['html'], 'table'), + (namespaces['html'], 'tbody'), + (namespaces['html'], 'td'), + (namespaces['html'], 'textarea'), + (namespaces['html'], 'time'), + (namespaces['html'], 'tfoot'), + (namespaces['html'], 'th'), + (namespaces['html'], 'thead'), + (namespaces['html'], 'tr'), + (namespaces['html'], 'tt'), + (namespaces['html'], 'u'), + (namespaces['html'], 'ul'), + (namespaces['html'], 'var'), + (namespaces['html'], 'video'), + (namespaces['mathml'], 'maction'), + (namespaces['mathml'], 'math'), + (namespaces['mathml'], 'merror'), + (namespaces['mathml'], 'mfrac'), + (namespaces['mathml'], 'mi'), + (namespaces['mathml'], 'mmultiscripts'), + (namespaces['mathml'], 'mn'), + (namespaces['mathml'], 'mo'), + (namespaces['mathml'], 'mover'), + (namespaces['mathml'], 'mpadded'), + (namespaces['mathml'], 'mphantom'), + (namespaces['mathml'], 'mprescripts'), + (namespaces['mathml'], 'mroot'), + (namespaces['mathml'], 'mrow'), + (namespaces['mathml'], 'mspace'), + (namespaces['mathml'], 'msqrt'), + (namespaces['mathml'], 'mstyle'), + (namespaces['mathml'], 'msub'), + (namespaces['mathml'], 'msubsup'), + (namespaces['mathml'], 'msup'), + (namespaces['mathml'], 'mtable'), + (namespaces['mathml'], 'mtd'), + (namespaces['mathml'], 'mtext'), + (namespaces['mathml'], 'mtr'), + (namespaces['mathml'], 'munder'), + (namespaces['mathml'], 'munderover'), + (namespaces['mathml'], 'none'), + (namespaces['svg'], 'a'), + (namespaces['svg'], 'animate'), + (namespaces['svg'], 'animateColor'), + (namespaces['svg'], 'animateMotion'), + (namespaces['svg'], 'animateTransform'), + (namespaces['svg'], 'clipPath'), + (namespaces['svg'], 'circle'), + (namespaces['svg'], 'defs'), + (namespaces['svg'], 'desc'), + (namespaces['svg'], 'ellipse'), + (namespaces['svg'], 'font-face'), + (namespaces['svg'], 'font-face-name'), + (namespaces['svg'], 'font-face-src'), + (namespaces['svg'], 'g'), + (namespaces['svg'], 'glyph'), + (namespaces['svg'], 'hkern'), + (namespaces['svg'], 'linearGradient'), + (namespaces['svg'], 'line'), + (namespaces['svg'], 'marker'), + (namespaces['svg'], 'metadata'), + (namespaces['svg'], 'missing-glyph'), + (namespaces['svg'], 'mpath'), + (namespaces['svg'], 'path'), + (namespaces['svg'], 'polygon'), + (namespaces['svg'], 'polyline'), + (namespaces['svg'], 'radialGradient'), + (namespaces['svg'], 'rect'), + (namespaces['svg'], 'set'), + (namespaces['svg'], 'stop'), + (namespaces['svg'], 'svg'), + (namespaces['svg'], 'switch'), + (namespaces['svg'], 'text'), + (namespaces['svg'], 'title'), + (namespaces['svg'], 'tspan'), + (namespaces['svg'], 'use'), +)) + +allowed_attributes = frozenset(( + # HTML attributes + (None, 'abbr'), + (None, 'accept'), + (None, 'accept-charset'), + (None, 'accesskey'), + (None, 'action'), + (None, 'align'), + (None, 'alt'), + (None, 'autocomplete'), + (None, 'autofocus'), + (None, 'axis'), + (None, 'background'), + (None, 'balance'), + (None, 'bgcolor'), + (None, 'bgproperties'), + (None, 'border'), + (None, 'bordercolor'), + (None, 'bordercolordark'), + (None, 'bordercolorlight'), + (None, 'bottompadding'), + (None, 'cellpadding'), + (None, 'cellspacing'), + (None, 'ch'), + (None, 'challenge'), + (None, 'char'), + (None, 'charoff'), + (None, 'choff'), + (None, 'charset'), + (None, 'checked'), + (None, 'cite'), + (None, 'class'), + (None, 'clear'), + (None, 'color'), + (None, 'cols'), + (None, 'colspan'), + (None, 'compact'), + (None, 'contenteditable'), + (None, 'controls'), + (None, 'coords'), + (None, 'data'), + (None, 'datafld'), + (None, 'datapagesize'), + (None, 'datasrc'), + (None, 'datetime'), + (None, 'default'), + (None, 'delay'), + (None, 'dir'), + (None, 'disabled'), + (None, 'draggable'), + (None, 'dynsrc'), + (None, 'enctype'), + (None, 'end'), + (None, 'face'), + (None, 'for'), + (None, 'form'), + (None, 'frame'), + (None, 'galleryimg'), + (None, 'gutter'), + (None, 'headers'), + (None, 'height'), + (None, 'hidefocus'), + (None, 'hidden'), + (None, 'high'), + (None, 'href'), + (None, 'hreflang'), + (None, 'hspace'), + (None, 'icon'), + (None, 'id'), + (None, 'inputmode'), + (None, 'ismap'), + (None, 'keytype'), + (None, 'label'), + (None, 'leftspacing'), + (None, 'lang'), + (None, 'list'), + (None, 'longdesc'), + (None, 'loop'), + (None, 'loopcount'), + (None, 'loopend'), + (None, 'loopstart'), + (None, 'low'), + (None, 'lowsrc'), + (None, 'max'), + (None, 'maxlength'), + (None, 'media'), + (None, 'method'), + (None, 'min'), + (None, 'multiple'), + (None, 'name'), + (None, 'nohref'), + (None, 'noshade'), + (None, 'nowrap'), + (None, 'open'), + (None, 'optimum'), + (None, 'pattern'), + (None, 'ping'), + (None, 'point-size'), + (None, 'poster'), + (None, 'pqg'), + (None, 'preload'), + (None, 'prompt'), + (None, 'radiogroup'), + (None, 'readonly'), + (None, 'rel'), + (None, 'repeat-max'), + (None, 'repeat-min'), + (None, 'replace'), + (None, 'required'), + (None, 'rev'), + (None, 'rightspacing'), + (None, 'rows'), + (None, 'rowspan'), + (None, 'rules'), + (None, 'scope'), + (None, 'selected'), + (None, 'shape'), + (None, 'size'), + (None, 'span'), + (None, 'src'), + (None, 'start'), + (None, 'step'), + (None, 'style'), + (None, 'summary'), + (None, 'suppress'), + (None, 'tabindex'), + (None, 'target'), + (None, 'template'), + (None, 'title'), + (None, 'toppadding'), + (None, 'type'), + (None, 'unselectable'), + (None, 'usemap'), + (None, 'urn'), + (None, 'valign'), + (None, 'value'), + (None, 'variable'), + (None, 'volume'), + (None, 'vspace'), + (None, 'vrml'), + (None, 'width'), + (None, 'wrap'), + (namespaces['xml'], 'lang'), + # MathML attributes + (None, 'actiontype'), + (None, 'align'), + (None, 'columnalign'), + (None, 'columnalign'), + (None, 'columnalign'), + (None, 'columnlines'), + (None, 'columnspacing'), + (None, 'columnspan'), + (None, 'depth'), + (None, 'display'), + (None, 'displaystyle'), + (None, 'equalcolumns'), + (None, 'equalrows'), + (None, 'fence'), + (None, 'fontstyle'), + (None, 'fontweight'), + (None, 'frame'), + (None, 'height'), + (None, 'linethickness'), + (None, 'lspace'), + (None, 'mathbackground'), + (None, 'mathcolor'), + (None, 'mathvariant'), + (None, 'mathvariant'), + (None, 'maxsize'), + (None, 'minsize'), + (None, 'other'), + (None, 'rowalign'), + (None, 'rowalign'), + (None, 'rowalign'), + (None, 'rowlines'), + (None, 'rowspacing'), + (None, 'rowspan'), + (None, 'rspace'), + (None, 'scriptlevel'), + (None, 'selection'), + (None, 'separator'), + (None, 'stretchy'), + (None, 'width'), + (None, 'width'), + (namespaces['xlink'], 'href'), + (namespaces['xlink'], 'show'), + (namespaces['xlink'], 'type'), + # SVG attributes + (None, 'accent-height'), + (None, 'accumulate'), + (None, 'additive'), + (None, 'alphabetic'), + (None, 'arabic-form'), + (None, 'ascent'), + (None, 'attributeName'), + (None, 'attributeType'), + (None, 'baseProfile'), + (None, 'bbox'), + (None, 'begin'), + (None, 'by'), + (None, 'calcMode'), + (None, 'cap-height'), + (None, 'class'), + (None, 'clip-path'), + (None, 'color'), + (None, 'color-rendering'), + (None, 'content'), + (None, 'cx'), + (None, 'cy'), + (None, 'd'), + (None, 'dx'), + (None, 'dy'), + (None, 'descent'), + (None, 'display'), + (None, 'dur'), + (None, 'end'), + (None, 'fill'), + (None, 'fill-opacity'), + (None, 'fill-rule'), + (None, 'font-family'), + (None, 'font-size'), + (None, 'font-stretch'), + (None, 'font-style'), + (None, 'font-variant'), + (None, 'font-weight'), + (None, 'from'), + (None, 'fx'), + (None, 'fy'), + (None, 'g1'), + (None, 'g2'), + (None, 'glyph-name'), + (None, 'gradientUnits'), + (None, 'hanging'), + (None, 'height'), + (None, 'horiz-adv-x'), + (None, 'horiz-origin-x'), + (None, 'id'), + (None, 'ideographic'), + (None, 'k'), + (None, 'keyPoints'), + (None, 'keySplines'), + (None, 'keyTimes'), + (None, 'lang'), + (None, 'marker-end'), + (None, 'marker-mid'), + (None, 'marker-start'), + (None, 'markerHeight'), + (None, 'markerUnits'), + (None, 'markerWidth'), + (None, 'mathematical'), + (None, 'max'), + (None, 'min'), + (None, 'name'), + (None, 'offset'), + (None, 'opacity'), + (None, 'orient'), + (None, 'origin'), + (None, 'overline-position'), + (None, 'overline-thickness'), + (None, 'panose-1'), + (None, 'path'), + (None, 'pathLength'), + (None, 'points'), + (None, 'preserveAspectRatio'), + (None, 'r'), + (None, 'refX'), + (None, 'refY'), + (None, 'repeatCount'), + (None, 'repeatDur'), + (None, 'requiredExtensions'), + (None, 'requiredFeatures'), + (None, 'restart'), + (None, 'rotate'), + (None, 'rx'), + (None, 'ry'), + (None, 'slope'), + (None, 'stemh'), + (None, 'stemv'), + (None, 'stop-color'), + (None, 'stop-opacity'), + (None, 'strikethrough-position'), + (None, 'strikethrough-thickness'), + (None, 'stroke'), + (None, 'stroke-dasharray'), + (None, 'stroke-dashoffset'), + (None, 'stroke-linecap'), + (None, 'stroke-linejoin'), + (None, 'stroke-miterlimit'), + (None, 'stroke-opacity'), + (None, 'stroke-width'), + (None, 'systemLanguage'), + (None, 'target'), + (None, 'text-anchor'), + (None, 'to'), + (None, 'transform'), + (None, 'type'), + (None, 'u1'), + (None, 'u2'), + (None, 'underline-position'), + (None, 'underline-thickness'), + (None, 'unicode'), + (None, 'unicode-range'), + (None, 'units-per-em'), + (None, 'values'), + (None, 'version'), + (None, 'viewBox'), + (None, 'visibility'), + (None, 'width'), + (None, 'widths'), + (None, 'x'), + (None, 'x-height'), + (None, 'x1'), + (None, 'x2'), + (namespaces['xlink'], 'actuate'), + (namespaces['xlink'], 'arcrole'), + (namespaces['xlink'], 'href'), + (namespaces['xlink'], 'role'), + (namespaces['xlink'], 'show'), + (namespaces['xlink'], 'title'), + (namespaces['xlink'], 'type'), + (namespaces['xml'], 'base'), + (namespaces['xml'], 'lang'), + (namespaces['xml'], 'space'), + (None, 'y'), + (None, 'y1'), + (None, 'y2'), + (None, 'zoomAndPan'), +)) + +attr_val_is_uri = frozenset(( + (None, 'href'), + (None, 'src'), + (None, 'cite'), + (None, 'action'), + (None, 'longdesc'), + (None, 'poster'), + (None, 'background'), + (None, 'datasrc'), + (None, 'dynsrc'), + (None, 'lowsrc'), + (None, 'ping'), + (namespaces['xlink'], 'href'), + (namespaces['xml'], 'base'), +)) + +svg_attr_val_allows_ref = frozenset(( + (None, 'clip-path'), + (None, 'color-profile'), + (None, 'cursor'), + (None, 'fill'), + (None, 'filter'), + (None, 'marker'), + (None, 'marker-start'), + (None, 'marker-mid'), + (None, 'marker-end'), + (None, 'mask'), + (None, 'stroke'), +)) + +svg_allow_local_href = frozenset(( + (None, 'altGlyph'), + (None, 'animate'), + (None, 'animateColor'), + (None, 'animateMotion'), + (None, 'animateTransform'), + (None, 'cursor'), + (None, 'feImage'), + (None, 'filter'), + (None, 'linearGradient'), + (None, 'pattern'), + (None, 'radialGradient'), + (None, 'textpath'), + (None, 'tref'), + (None, 'set'), + (None, 'use') +)) + +allowed_css_properties = frozenset(( + 'azimuth', + 'background-color', + 'border-bottom-color', + 'border-collapse', + 'border-color', + 'border-left-color', + 'border-right-color', + 'border-top-color', + 'clear', + 'color', + 'cursor', + 'direction', + 'display', + 'elevation', + 'float', + 'font', + 'font-family', + 'font-size', + 'font-style', + 'font-variant', + 'font-weight', + 'height', + 'letter-spacing', + 'line-height', + 'overflow', + 'pause', + 'pause-after', + 'pause-before', + 'pitch', + 'pitch-range', + 'richness', + 'speak', + 'speak-header', + 'speak-numeral', + 'speak-punctuation', + 'speech-rate', + 'stress', + 'text-align', + 'text-decoration', + 'text-indent', + 'unicode-bidi', + 'vertical-align', + 'voice-family', + 'volume', + 'white-space', + 'width', +)) + +allowed_css_keywords = frozenset(( + 'auto', + 'aqua', + 'black', + 'block', + 'blue', + 'bold', + 'both', + 'bottom', + 'brown', + 'center', + 'collapse', + 'dashed', + 'dotted', + 'fuchsia', + 'gray', + 'green', + '!important', + 'italic', + 'left', + 'lime', + 'maroon', + 'medium', + 'none', + 'navy', + 'normal', + 'nowrap', + 'olive', + 'pointer', + 'purple', + 'red', + 'right', + 'solid', + 'silver', + 'teal', + 'top', + 'transparent', + 'underline', + 'white', + 'yellow', +)) + +allowed_svg_properties = frozenset(( + 'fill', + 'fill-opacity', + 'fill-rule', + 'stroke', + 'stroke-width', + 'stroke-linecap', + 'stroke-linejoin', + 'stroke-opacity', +)) + +allowed_protocols = frozenset(( + 'ed2k', + 'ftp', + 'http', + 'https', + 'irc', + 'mailto', + 'news', + 'gopher', + 'nntp', + 'telnet', + 'webcal', + 'xmpp', + 'callto', + 'feed', + 'urn', + 'aim', + 'rsync', + 'tag', + 'ssh', + 'sftp', + 'rtsp', + 'afs', + 'data', +)) + +allowed_content_types = frozenset(( + 'image/png', + 'image/jpeg', + 'image/gif', + 'image/webp', + 'image/bmp', + 'text/plain', +)) + + +data_content_type = re.compile(r''' + ^ + # Match a content type <application>/<type> + (?P<content_type>[-a-zA-Z0-9.]+/[-a-zA-Z0-9.]+) + # Match any character set and encoding + (?:(?:;charset=(?:[-a-zA-Z0-9]+)(?:;(?:base64))?) + |(?:;(?:base64))?(?:;charset=(?:[-a-zA-Z0-9]+))?) + # Assume the rest is data + ,.* + $ + ''', + re.VERBOSE) + + +class Filter(base.Filter): + """Sanitizes token stream of XHTML+MathML+SVG and of inline style attributes""" + def __init__(self, + source, + allowed_elements=allowed_elements, + allowed_attributes=allowed_attributes, + allowed_css_properties=allowed_css_properties, + allowed_css_keywords=allowed_css_keywords, + allowed_svg_properties=allowed_svg_properties, + allowed_protocols=allowed_protocols, + allowed_content_types=allowed_content_types, + attr_val_is_uri=attr_val_is_uri, + svg_attr_val_allows_ref=svg_attr_val_allows_ref, + svg_allow_local_href=svg_allow_local_href): + """Creates a Filter + + :arg allowed_elements: set of elements to allow--everything else will + be escaped + + :arg allowed_attributes: set of attributes to allow in + elements--everything else will be stripped + + :arg allowed_css_properties: set of CSS properties to allow--everything + else will be stripped + + :arg allowed_css_keywords: set of CSS keywords to allow--everything + else will be stripped + + :arg allowed_svg_properties: set of SVG properties to allow--everything + else will be removed + + :arg allowed_protocols: set of allowed protocols for URIs + + :arg allowed_content_types: set of allowed content types for ``data`` URIs. + + :arg attr_val_is_uri: set of attributes that have URI values--values + that have a scheme not listed in ``allowed_protocols`` are removed + + :arg svg_attr_val_allows_ref: set of SVG attributes that can have + references + + :arg svg_allow_local_href: set of SVG elements that can have local + hrefs--these are removed + + """ + super(Filter, self).__init__(source) + self.allowed_elements = allowed_elements + self.allowed_attributes = allowed_attributes + self.allowed_css_properties = allowed_css_properties + self.allowed_css_keywords = allowed_css_keywords + self.allowed_svg_properties = allowed_svg_properties + self.allowed_protocols = allowed_protocols + self.allowed_content_types = allowed_content_types + self.attr_val_is_uri = attr_val_is_uri + self.svg_attr_val_allows_ref = svg_attr_val_allows_ref + self.svg_allow_local_href = svg_allow_local_href + + def __iter__(self): + for token in base.Filter.__iter__(self): + token = self.sanitize_token(token) + if token: + yield token + + # Sanitize the +html+, escaping all elements not in ALLOWED_ELEMENTS, and + # stripping out all attributes not in ALLOWED_ATTRIBUTES. Style attributes + # are parsed, and a restricted set, specified by ALLOWED_CSS_PROPERTIES and + # ALLOWED_CSS_KEYWORDS, are allowed through. attributes in ATTR_VAL_IS_URI + # are scanned, and only URI schemes specified in ALLOWED_PROTOCOLS are + # allowed. + # + # sanitize_html('<script> do_nasty_stuff() </script>') + # => <script> do_nasty_stuff() </script> + # sanitize_html('<a href="javascript: sucker();">Click here for $100</a>') + # => <a>Click here for $100</a> + def sanitize_token(self, token): + + # accommodate filters which use token_type differently + token_type = token["type"] + if token_type in ("StartTag", "EndTag", "EmptyTag"): + name = token["name"] + namespace = token["namespace"] + if ((namespace, name) in self.allowed_elements or + (namespace is None and + (namespaces["html"], name) in self.allowed_elements)): + return self.allowed_token(token) + else: + return self.disallowed_token(token) + elif token_type == "Comment": + pass + else: + return token + + def allowed_token(self, token): + if "data" in token: + attrs = token["data"] + attr_names = set(attrs.keys()) + + # Remove forbidden attributes + for to_remove in (attr_names - self.allowed_attributes): + del token["data"][to_remove] + attr_names.remove(to_remove) + + # Remove attributes with disallowed URL values + for attr in (attr_names & self.attr_val_is_uri): + assert attr in attrs + # I don't have a clue where this regexp comes from or why it matches those + # characters, nor why we call unescape. I just know it's always been here. + # Should you be worried by this comment in a sanitizer? Yes. On the other hand, all + # this will do is remove *more* than it otherwise would. + val_unescaped = re.sub("[`\x00-\x20\x7f-\xa0\\s]+", '', + unescape(attrs[attr])).lower() + # remove replacement characters from unescaped characters + val_unescaped = val_unescaped.replace("\ufffd", "") + try: + uri = urlparse.urlparse(val_unescaped) + except ValueError: + uri = None + del attrs[attr] + if uri and uri.scheme: + if uri.scheme not in self.allowed_protocols: + del attrs[attr] + if uri.scheme == 'data': + m = data_content_type.match(uri.path) + if not m: + del attrs[attr] + elif m.group('content_type') not in self.allowed_content_types: + del attrs[attr] + + for attr in self.svg_attr_val_allows_ref: + if attr in attrs: + attrs[attr] = re.sub(r'url\s*\(\s*[^#\s][^)]+?\)', + ' ', + unescape(attrs[attr])) + if (token["name"] in self.svg_allow_local_href and + (namespaces['xlink'], 'href') in attrs and re.search(r'^\s*[^#\s].*', + attrs[(namespaces['xlink'], 'href')])): + del attrs[(namespaces['xlink'], 'href')] + if (None, 'style') in attrs: + attrs[(None, 'style')] = self.sanitize_css(attrs[(None, 'style')]) + token["data"] = attrs + return token + + def disallowed_token(self, token): + token_type = token["type"] + if token_type == "EndTag": + token["data"] = "</%s>" % token["name"] + elif token["data"]: + assert token_type in ("StartTag", "EmptyTag") + attrs = [] + for (ns, name), v in token["data"].items(): + attrs.append(' %s="%s"' % (name if ns is None else "%s:%s" % (prefixes[ns], name), escape(v))) + token["data"] = "<%s%s>" % (token["name"], ''.join(attrs)) + else: + token["data"] = "<%s>" % token["name"] + if token.get("selfClosing"): + token["data"] = token["data"][:-1] + "/>" + + token["type"] = "Characters" + + del token["name"] + return token + + def sanitize_css(self, style): + # disallow urls + style = re.compile(r'url\s*\(\s*[^\s)]+?\s*\)\s*').sub(' ', style) + + # gauntlet + if not re.match(r"""^([:,;#%.\sa-zA-Z0-9!]|\w-\w|'[\s\w]+'|"[\s\w]+"|\([\d,\s]+\))*$""", style): + return '' + if not re.match(r"^\s*([-\w]+\s*:[^:;]*(;\s*|$))*$", style): + return '' + + clean = [] + for prop, value in re.findall(r"([-\w]+)\s*:\s*([^:;]*)", style): + if not value: + continue + if prop.lower() in self.allowed_css_properties: + clean.append(prop + ': ' + value + ';') + elif prop.split('-')[0].lower() in ['background', 'border', 'margin', + 'padding']: + for keyword in value.split(): + if keyword not in self.allowed_css_keywords and \ + not re.match(r"^(#[0-9a-fA-F]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$", keyword): # noqa + break + else: + clean.append(prop + ': ' + value + ';') + elif prop.lower() in self.allowed_svg_properties: + clean.append(prop + ': ' + value + ';') + + return ' '.join(clean) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/whitespace.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/whitespace.py new file mode 100644 index 0000000..0d12584 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/whitespace.py @@ -0,0 +1,38 @@ +from __future__ import absolute_import, division, unicode_literals + +import re + +from . import base +from ..constants import rcdataElements, spaceCharacters +spaceCharacters = "".join(spaceCharacters) + +SPACES_REGEX = re.compile("[%s]+" % spaceCharacters) + + +class Filter(base.Filter): + """Collapses whitespace except in pre, textarea, and script elements""" + spacePreserveElements = frozenset(["pre", "textarea"] + list(rcdataElements)) + + def __iter__(self): + preserve = 0 + for token in base.Filter.__iter__(self): + type = token["type"] + if type == "StartTag" \ + and (preserve or token["name"] in self.spacePreserveElements): + preserve += 1 + + elif type == "EndTag" and preserve: + preserve -= 1 + + elif not preserve and type == "SpaceCharacters" and token["data"]: + # Test on token["data"] above to not introduce spaces where there were not + token["data"] = " " + + elif not preserve and type == "Characters": + token["data"] = collapse_spaces(token["data"]) + + yield token + + +def collapse_spaces(text): + return SPACES_REGEX.sub(' ', text) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/html5parser.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/html5parser.py new file mode 100644 index 0000000..ae41a13 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/html5parser.py @@ -0,0 +1,2791 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import with_metaclass, viewkeys + +import types +from collections import OrderedDict + +from . import _inputstream +from . import _tokenizer + +from . import treebuilders +from .treebuilders.base import Marker + +from . import _utils +from .constants import ( + spaceCharacters, asciiUpper2Lower, + specialElements, headingElements, cdataElements, rcdataElements, + tokenTypes, tagTokenTypes, + namespaces, + htmlIntegrationPointElements, mathmlTextIntegrationPointElements, + adjustForeignAttributes as adjustForeignAttributesMap, + adjustMathMLAttributes, adjustSVGAttributes, + E, + _ReparseException +) + + +def parse(doc, treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML document as a string or file-like object into a tree + + :arg doc: the document to parse as a string or file-like object + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import parse + >>> parse('<html><body><p>This is a doc</p></body></html>') + <Element u'{http://www.w3.org/1999/xhtml}html' at 0x7feac4909db0> + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parse(doc, **kwargs) + + +def parseFragment(doc, container="div", treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML fragment as a string or file-like object into a tree + + :arg doc: the fragment to parse as a string or file-like object + + :arg container: the container context to parse the fragment in + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import parseFragment + >>> parseFragment('<b>this is a fragment</b>') + <Element u'DOCUMENT_FRAGMENT' at 0x7feac484b090> + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parseFragment(doc, container=container, **kwargs) + + +def method_decorator_metaclass(function): + class Decorated(type): + def __new__(meta, classname, bases, classDict): + for attributeName, attribute in classDict.items(): + if isinstance(attribute, types.FunctionType): + attribute = function(attribute) + + classDict[attributeName] = attribute + return type.__new__(meta, classname, bases, classDict) + return Decorated + + +class HTMLParser(object): + """HTML parser + + Generates a tree structure from a stream of (possibly malformed) HTML. + + """ + + def __init__(self, tree=None, strict=False, namespaceHTMLElements=True, debug=False): + """ + :arg tree: a treebuilder class controlling the type of tree that will be + returned. Built in treebuilders can be accessed through + html5lib.treebuilders.getTreeBuilder(treeType) + + :arg strict: raise an exception when a parse error is encountered + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :arg debug: whether or not to enable debug mode which logs things + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() # generates parser with etree builder + >>> parser = HTMLParser('lxml', strict=True) # generates parser with lxml builder which is strict + + """ + + # Raise an exception on the first error encountered + self.strict = strict + + if tree is None: + tree = treebuilders.getTreeBuilder("etree") + self.tree = tree(namespaceHTMLElements) + self.errors = [] + + self.phases = dict([(name, cls(self, self.tree)) for name, cls in + getPhases(debug).items()]) + + def _parse(self, stream, innerHTML=False, container="div", scripting=False, **kwargs): + + self.innerHTMLMode = innerHTML + self.container = container + self.scripting = scripting + self.tokenizer = _tokenizer.HTMLTokenizer(stream, parser=self, **kwargs) + self.reset() + + try: + self.mainLoop() + except _ReparseException: + self.reset() + self.mainLoop() + + def reset(self): + self.tree.reset() + self.firstStartTag = False + self.errors = [] + self.log = [] # only used with debug mode + # "quirks" / "limited quirks" / "no quirks" + self.compatMode = "no quirks" + + if self.innerHTMLMode: + self.innerHTML = self.container.lower() + + if self.innerHTML in cdataElements: + self.tokenizer.state = self.tokenizer.rcdataState + elif self.innerHTML in rcdataElements: + self.tokenizer.state = self.tokenizer.rawtextState + elif self.innerHTML == 'plaintext': + self.tokenizer.state = self.tokenizer.plaintextState + else: + # state already is data state + # self.tokenizer.state = self.tokenizer.dataState + pass + self.phase = self.phases["beforeHtml"] + self.phase.insertHtmlElement() + self.resetInsertionMode() + else: + self.innerHTML = False # pylint:disable=redefined-variable-type + self.phase = self.phases["initial"] + + self.lastPhase = None + + self.beforeRCDataPhase = None + + self.framesetOK = True + + @property + def documentEncoding(self): + """Name of the character encoding that was used to decode the input stream, or + :obj:`None` if that is not determined yet + + """ + if not hasattr(self, 'tokenizer'): + return None + return self.tokenizer.stream.charEncoding[0].name + + def isHTMLIntegrationPoint(self, element): + if (element.name == "annotation-xml" and + element.namespace == namespaces["mathml"]): + return ("encoding" in element.attributes and + element.attributes["encoding"].translate( + asciiUpper2Lower) in + ("text/html", "application/xhtml+xml")) + else: + return (element.namespace, element.name) in htmlIntegrationPointElements + + def isMathMLTextIntegrationPoint(self, element): + return (element.namespace, element.name) in mathmlTextIntegrationPointElements + + def mainLoop(self): + CharactersToken = tokenTypes["Characters"] + SpaceCharactersToken = tokenTypes["SpaceCharacters"] + StartTagToken = tokenTypes["StartTag"] + EndTagToken = tokenTypes["EndTag"] + CommentToken = tokenTypes["Comment"] + DoctypeToken = tokenTypes["Doctype"] + ParseErrorToken = tokenTypes["ParseError"] + + for token in self.normalizedTokens(): + prev_token = None + new_token = token + while new_token is not None: + prev_token = new_token + currentNode = self.tree.openElements[-1] if self.tree.openElements else None + currentNodeNamespace = currentNode.namespace if currentNode else None + currentNodeName = currentNode.name if currentNode else None + + type = new_token["type"] + + if type == ParseErrorToken: + self.parseError(new_token["data"], new_token.get("datavars", {})) + new_token = None + else: + if (len(self.tree.openElements) == 0 or + currentNodeNamespace == self.tree.defaultNamespace or + (self.isMathMLTextIntegrationPoint(currentNode) and + ((type == StartTagToken and + token["name"] not in frozenset(["mglyph", "malignmark"])) or + type in (CharactersToken, SpaceCharactersToken))) or + (currentNodeNamespace == namespaces["mathml"] and + currentNodeName == "annotation-xml" and + type == StartTagToken and + token["name"] == "svg") or + (self.isHTMLIntegrationPoint(currentNode) and + type in (StartTagToken, CharactersToken, SpaceCharactersToken))): + phase = self.phase + else: + phase = self.phases["inForeignContent"] + + if type == CharactersToken: + new_token = phase.processCharacters(new_token) + elif type == SpaceCharactersToken: + new_token = phase.processSpaceCharacters(new_token) + elif type == StartTagToken: + new_token = phase.processStartTag(new_token) + elif type == EndTagToken: + new_token = phase.processEndTag(new_token) + elif type == CommentToken: + new_token = phase.processComment(new_token) + elif type == DoctypeToken: + new_token = phase.processDoctype(new_token) + + if (type == StartTagToken and prev_token["selfClosing"] and + not prev_token["selfClosingAcknowledged"]): + self.parseError("non-void-element-with-trailing-solidus", + {"name": prev_token["name"]}) + + # When the loop finishes it's EOF + reprocess = True + phases = [] + while reprocess: + phases.append(self.phase) + reprocess = self.phase.processEOF() + if reprocess: + assert self.phase not in phases + + def normalizedTokens(self): + for token in self.tokenizer: + yield self.normalizeToken(token) + + def parse(self, stream, *args, **kwargs): + """Parse a HTML document into a well-formed tree + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element). + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parse('<html><body><p>This is a doc</p></body></html>') + <Element u'{http://www.w3.org/1999/xhtml}html' at 0x7feac4909db0> + + """ + self._parse(stream, False, None, *args, **kwargs) + return self.tree.getDocument() + + def parseFragment(self, stream, *args, **kwargs): + """Parse a HTML fragment into a well-formed tree fragment + + :arg container: name of the element we're setting the innerHTML + property if set to None, default to 'div' + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parseFragment('<b>this is a fragment</b>') + <Element u'DOCUMENT_FRAGMENT' at 0x7feac484b090> + + """ + self._parse(stream, True, *args, **kwargs) + return self.tree.getFragment() + + def parseError(self, errorcode="XXX-undefined-error", datavars=None): + # XXX The idea is to make errorcode mandatory. + if datavars is None: + datavars = {} + self.errors.append((self.tokenizer.stream.position(), errorcode, datavars)) + if self.strict: + raise ParseError(E[errorcode] % datavars) + + def normalizeToken(self, token): + # HTML5 specific normalizations to the token stream + if token["type"] == tokenTypes["StartTag"]: + raw = token["data"] + token["data"] = OrderedDict(raw) + if len(raw) > len(token["data"]): + # we had some duplicated attribute, fix so first wins + token["data"].update(raw[::-1]) + + return token + + def adjustMathMLAttributes(self, token): + adjust_attributes(token, adjustMathMLAttributes) + + def adjustSVGAttributes(self, token): + adjust_attributes(token, adjustSVGAttributes) + + def adjustForeignAttributes(self, token): + adjust_attributes(token, adjustForeignAttributesMap) + + def reparseTokenNormal(self, token): + # pylint:disable=unused-argument + self.parser.phase() + + def resetInsertionMode(self): + # The name of this method is mostly historical. (It's also used in the + # specification.) + last = False + newModes = { + "select": "inSelect", + "td": "inCell", + "th": "inCell", + "tr": "inRow", + "tbody": "inTableBody", + "thead": "inTableBody", + "tfoot": "inTableBody", + "caption": "inCaption", + "colgroup": "inColumnGroup", + "table": "inTable", + "head": "inBody", + "body": "inBody", + "frameset": "inFrameset", + "html": "beforeHead" + } + for node in self.tree.openElements[::-1]: + nodeName = node.name + new_phase = None + if node == self.tree.openElements[0]: + assert self.innerHTML + last = True + nodeName = self.innerHTML + # Check for conditions that should only happen in the innerHTML + # case + if nodeName in ("select", "colgroup", "head", "html"): + assert self.innerHTML + + if not last and node.namespace != self.tree.defaultNamespace: + continue + + if nodeName in newModes: + new_phase = self.phases[newModes[nodeName]] + break + elif last: + new_phase = self.phases["inBody"] + break + + self.phase = new_phase + + def parseRCDataRawtext(self, token, contentType): + # Generic RCDATA/RAWTEXT Parsing algorithm + assert contentType in ("RAWTEXT", "RCDATA") + + self.tree.insertElement(token) + + if contentType == "RAWTEXT": + self.tokenizer.state = self.tokenizer.rawtextState + else: + self.tokenizer.state = self.tokenizer.rcdataState + + self.originalPhase = self.phase + + self.phase = self.phases["text"] + + +@_utils.memoize +def getPhases(debug): + def log(function): + """Logger that records which phase processes each token""" + type_names = dict((value, key) for key, value in + tokenTypes.items()) + + def wrapped(self, *args, **kwargs): + if function.__name__.startswith("process") and len(args) > 0: + token = args[0] + try: + info = {"type": type_names[token['type']]} + except: + raise + if token['type'] in tagTokenTypes: + info["name"] = token['name'] + + self.parser.log.append((self.parser.tokenizer.state.__name__, + self.parser.phase.__class__.__name__, + self.__class__.__name__, + function.__name__, + info)) + return function(self, *args, **kwargs) + else: + return function(self, *args, **kwargs) + return wrapped + + def getMetaclass(use_metaclass, metaclass_func): + if use_metaclass: + return method_decorator_metaclass(metaclass_func) + else: + return type + + # pylint:disable=unused-argument + class Phase(with_metaclass(getMetaclass(debug, log))): + """Base class for helper object that implements each phase of processing + """ + + def __init__(self, parser, tree): + self.parser = parser + self.tree = tree + + def processEOF(self): + raise NotImplementedError + + def processComment(self, token): + # For most phases the following is correct. Where it's not it will be + # overridden. + self.tree.insertComment(token, self.tree.openElements[-1]) + + def processDoctype(self, token): + self.parser.parseError("unexpected-doctype") + + def processCharacters(self, token): + self.tree.insertText(token["data"]) + + def processSpaceCharacters(self, token): + self.tree.insertText(token["data"]) + + def processStartTag(self, token): + return self.startTagHandler[token["name"]](token) + + def startTagHtml(self, token): + if not self.parser.firstStartTag and token["name"] == "html": + self.parser.parseError("non-html-root") + # XXX Need a check here to see if the first start tag token emitted is + # this token... If it's not, invoke self.parser.parseError(). + for attr, value in token["data"].items(): + if attr not in self.tree.openElements[0].attributes: + self.tree.openElements[0].attributes[attr] = value + self.parser.firstStartTag = False + + def processEndTag(self, token): + return self.endTagHandler[token["name"]](token) + + class InitialPhase(Phase): + def processSpaceCharacters(self, token): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + correct = token["correct"] + + if (name != "html" or publicId is not None or + systemId is not None and systemId != "about:legacy-compat"): + self.parser.parseError("unknown-doctype") + + if publicId is None: + publicId = "" + + self.tree.insertDoctype(token) + + if publicId != "": + publicId = publicId.translate(asciiUpper2Lower) + + if (not correct or token["name"] != "html" or + publicId.startswith( + ("+//silmaril//dtd html pro v0r11 19970101//", + "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", + "-//as//dtd html 3.0 aswedit + extensions//", + "-//ietf//dtd html 2.0 level 1//", + "-//ietf//dtd html 2.0 level 2//", + "-//ietf//dtd html 2.0 strict level 1//", + "-//ietf//dtd html 2.0 strict level 2//", + "-//ietf//dtd html 2.0 strict//", + "-//ietf//dtd html 2.0//", + "-//ietf//dtd html 2.1e//", + "-//ietf//dtd html 3.0//", + "-//ietf//dtd html 3.2 final//", + "-//ietf//dtd html 3.2//", + "-//ietf//dtd html 3//", + "-//ietf//dtd html level 0//", + "-//ietf//dtd html level 1//", + "-//ietf//dtd html level 2//", + "-//ietf//dtd html level 3//", + "-//ietf//dtd html strict level 0//", + "-//ietf//dtd html strict level 1//", + "-//ietf//dtd html strict level 2//", + "-//ietf//dtd html strict level 3//", + "-//ietf//dtd html strict//", + "-//ietf//dtd html//", + "-//metrius//dtd metrius presentational//", + "-//microsoft//dtd internet explorer 2.0 html strict//", + "-//microsoft//dtd internet explorer 2.0 html//", + "-//microsoft//dtd internet explorer 2.0 tables//", + "-//microsoft//dtd internet explorer 3.0 html strict//", + "-//microsoft//dtd internet explorer 3.0 html//", + "-//microsoft//dtd internet explorer 3.0 tables//", + "-//netscape comm. corp.//dtd html//", + "-//netscape comm. corp.//dtd strict html//", + "-//o'reilly and associates//dtd html 2.0//", + "-//o'reilly and associates//dtd html extended 1.0//", + "-//o'reilly and associates//dtd html extended relaxed 1.0//", + "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", + "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", + "-//spyglass//dtd html 2.0 extended//", + "-//sq//dtd html 2.0 hotmetal + extensions//", + "-//sun microsystems corp.//dtd hotjava html//", + "-//sun microsystems corp.//dtd hotjava strict html//", + "-//w3c//dtd html 3 1995-03-24//", + "-//w3c//dtd html 3.2 draft//", + "-//w3c//dtd html 3.2 final//", + "-//w3c//dtd html 3.2//", + "-//w3c//dtd html 3.2s draft//", + "-//w3c//dtd html 4.0 frameset//", + "-//w3c//dtd html 4.0 transitional//", + "-//w3c//dtd html experimental 19960712//", + "-//w3c//dtd html experimental 970421//", + "-//w3c//dtd w3 html//", + "-//w3o//dtd w3 html 3.0//", + "-//webtechs//dtd mozilla html 2.0//", + "-//webtechs//dtd mozilla html//")) or + publicId in ("-//w3o//dtd w3 html strict 3.0//en//", + "-/w3c/dtd html 4.0 transitional/en", + "html") or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is None or + systemId and systemId.lower() == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"): + self.parser.compatMode = "quirks" + elif (publicId.startswith( + ("-//w3c//dtd xhtml 1.0 frameset//", + "-//w3c//dtd xhtml 1.0 transitional//")) or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is not None): + self.parser.compatMode = "limited quirks" + + self.parser.phase = self.parser.phases["beforeHtml"] + + def anythingElse(self): + self.parser.compatMode = "quirks" + self.parser.phase = self.parser.phases["beforeHtml"] + + def processCharacters(self, token): + self.parser.parseError("expected-doctype-but-got-chars") + self.anythingElse() + return token + + def processStartTag(self, token): + self.parser.parseError("expected-doctype-but-got-start-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEndTag(self, token): + self.parser.parseError("expected-doctype-but-got-end-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEOF(self): + self.parser.parseError("expected-doctype-but-got-eof") + self.anythingElse() + return True + + class BeforeHtmlPhase(Phase): + # helper methods + def insertHtmlElement(self): + self.tree.insertRoot(impliedTagToken("html", "StartTag")) + self.parser.phase = self.parser.phases["beforeHead"] + + # other + def processEOF(self): + self.insertHtmlElement() + return True + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.insertHtmlElement() + return token + + def processStartTag(self, token): + if token["name"] == "html": + self.parser.firstStartTag = True + self.insertHtmlElement() + return token + + def processEndTag(self, token): + if token["name"] not in ("head", "body", "html", "br"): + self.parser.parseError("unexpected-end-tag-before-html", + {"name": token["name"]}) + else: + self.insertHtmlElement() + return token + + class BeforeHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("head", self.startTagHead) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("head", "body", "html", "br"), self.endTagImplyHead) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.startTagHead(impliedTagToken("head", "StartTag")) + return True + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.tree.insertElement(token) + self.tree.headPointer = self.tree.openElements[-1] + self.parser.phase = self.parser.phases["inHead"] + + def startTagOther(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagImplyHead(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagOther(self, token): + self.parser.parseError("end-tag-after-implied-root", + {"name": token["name"]}) + + class InHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("title", self.startTagTitle), + (("noframes", "style"), self.startTagNoFramesStyle), + ("noscript", self.startTagNoscript), + ("script", self.startTagScript), + (("base", "basefont", "bgsound", "command", "link"), + self.startTagBaseLinkCommand), + ("meta", self.startTagMeta), + ("head", self.startTagHead) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("head", self.endTagHead), + (("br", "html", "body"), self.endTagHtmlBodyBr) + ]) + self.endTagHandler.default = self.endTagOther + + # the real thing + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.parser.parseError("two-heads-are-not-better-than-one") + + def startTagBaseLinkCommand(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagMeta(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + attributes = token["data"] + if self.parser.tokenizer.stream.charEncoding[1] == "tentative": + if "charset" in attributes: + self.parser.tokenizer.stream.changeEncoding(attributes["charset"]) + elif ("content" in attributes and + "http-equiv" in attributes and + attributes["http-equiv"].lower() == "content-type"): + # Encoding it as UTF-8 here is a hack, as really we should pass + # the abstract Unicode string, and just use the + # ContentAttrParser on that, but using UTF-8 allows all chars + # to be encoded and as a ASCII-superset works. + data = _inputstream.EncodingBytes(attributes["content"].encode("utf-8")) + parser = _inputstream.ContentAttrParser(data) + codec = parser.parse() + self.parser.tokenizer.stream.changeEncoding(codec) + + def startTagTitle(self, token): + self.parser.parseRCDataRawtext(token, "RCDATA") + + def startTagNoFramesStyle(self, token): + # Need to decide whether to implement the scripting-disabled case + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagNoscript(self, token): + if self.parser.scripting: + self.parser.parseRCDataRawtext(token, "RAWTEXT") + else: + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inHeadNoscript"] + + def startTagScript(self, token): + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.scriptDataState + self.parser.originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["text"] + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHead(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "head", "Expected head got %s" % node.name + self.parser.phase = self.parser.phases["afterHead"] + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.endTagHead(impliedTagToken("head")) + + class InHeadNoscriptPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("basefont", "bgsound", "link", "meta", "noframes", "style"), self.startTagBaseLinkCommand), + (("head", "noscript"), self.startTagHeadNoscript), + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("noscript", self.endTagNoscript), + ("br", self.endTagBr), + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.parser.parseError("eof-in-head-noscript") + self.anythingElse() + return True + + def processComment(self, token): + return self.parser.phases["inHead"].processComment(token) + + def processCharacters(self, token): + self.parser.parseError("char-in-head-noscript") + self.anythingElse() + return token + + def processSpaceCharacters(self, token): + return self.parser.phases["inHead"].processSpaceCharacters(token) + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBaseLinkCommand(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagHeadNoscript(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagNoscript(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "noscript", "Expected noscript got %s" % node.name + self.parser.phase = self.parser.phases["inHead"] + + def endTagBr(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + # Caller must raise parse error first! + self.endTagNoscript(impliedTagToken("noscript")) + + class AfterHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("body", self.startTagBody), + ("frameset", self.startTagFrameset), + (("base", "basefont", "bgsound", "link", "meta", "noframes", "script", + "style", "title"), + self.startTagFromHead), + ("head", self.startTagHead) + ]) + self.startTagHandler.default = self.startTagOther + self.endTagHandler = _utils.MethodDispatcher([(("body", "html", "br"), + self.endTagHtmlBodyBr)]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBody(self, token): + self.parser.framesetOK = False + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inBody"] + + def startTagFrameset(self, token): + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inFrameset"] + + def startTagFromHead(self, token): + self.parser.parseError("unexpected-start-tag-out-of-my-head", + {"name": token["name"]}) + self.tree.openElements.append(self.tree.headPointer) + self.parser.phases["inHead"].processStartTag(token) + for node in self.tree.openElements[::-1]: + if node.name == "head": + self.tree.openElements.remove(node) + break + + def startTagHead(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.tree.insertElement(impliedTagToken("body", "StartTag")) + self.parser.phase = self.parser.phases["inBody"] + self.parser.framesetOK = True + + class InBodyPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#parsing-main-inbody + # the really-really-really-very crazy mode + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + # Set this to the default handler + self.processSpaceCharacters = self.processSpaceCharactersNonPre + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("base", "basefont", "bgsound", "command", "link", "meta", + "script", "style", "title"), + self.startTagProcessInHead), + ("body", self.startTagBody), + ("frameset", self.startTagFrameset), + (("address", "article", "aside", "blockquote", "center", "details", + "dir", "div", "dl", "fieldset", "figcaption", "figure", + "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", + "section", "summary", "ul"), + self.startTagCloseP), + (headingElements, self.startTagHeading), + (("pre", "listing"), self.startTagPreListing), + ("form", self.startTagForm), + (("li", "dd", "dt"), self.startTagListItem), + ("plaintext", self.startTagPlaintext), + ("a", self.startTagA), + (("b", "big", "code", "em", "font", "i", "s", "small", "strike", + "strong", "tt", "u"), self.startTagFormatting), + ("nobr", self.startTagNobr), + ("button", self.startTagButton), + (("applet", "marquee", "object"), self.startTagAppletMarqueeObject), + ("xmp", self.startTagXmp), + ("table", self.startTagTable), + (("area", "br", "embed", "img", "keygen", "wbr"), + self.startTagVoidFormatting), + (("param", "source", "track"), self.startTagParamSource), + ("input", self.startTagInput), + ("hr", self.startTagHr), + ("image", self.startTagImage), + ("isindex", self.startTagIsIndex), + ("textarea", self.startTagTextarea), + ("iframe", self.startTagIFrame), + ("noscript", self.startTagNoscript), + (("noembed", "noframes"), self.startTagRawtext), + ("select", self.startTagSelect), + (("rp", "rt"), self.startTagRpRt), + (("option", "optgroup"), self.startTagOpt), + (("math"), self.startTagMath), + (("svg"), self.startTagSvg), + (("caption", "col", "colgroup", "frame", "head", + "tbody", "td", "tfoot", "th", "thead", + "tr"), self.startTagMisplaced) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("body", self.endTagBody), + ("html", self.endTagHtml), + (("address", "article", "aside", "blockquote", "button", "center", + "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", + "footer", "header", "hgroup", "listing", "main", "menu", "nav", "ol", "pre", + "section", "summary", "ul"), self.endTagBlock), + ("form", self.endTagForm), + ("p", self.endTagP), + (("dd", "dt", "li"), self.endTagListItem), + (headingElements, self.endTagHeading), + (("a", "b", "big", "code", "em", "font", "i", "nobr", "s", "small", + "strike", "strong", "tt", "u"), self.endTagFormatting), + (("applet", "marquee", "object"), self.endTagAppletMarqueeObject), + ("br", self.endTagBr), + ]) + self.endTagHandler.default = self.endTagOther + + def isMatchingFormattingElement(self, node1, node2): + return (node1.name == node2.name and + node1.namespace == node2.namespace and + node1.attributes == node2.attributes) + + # helper + def addFormattingElement(self, token): + self.tree.insertElement(token) + element = self.tree.openElements[-1] + + matchingElements = [] + for node in self.tree.activeFormattingElements[::-1]: + if node is Marker: + break + elif self.isMatchingFormattingElement(node, element): + matchingElements.append(node) + + assert len(matchingElements) <= 3 + if len(matchingElements) == 3: + self.tree.activeFormattingElements.remove(matchingElements[-1]) + self.tree.activeFormattingElements.append(element) + + # the real deal + def processEOF(self): + allowed_elements = frozenset(("dd", "dt", "li", "p", "tbody", "td", + "tfoot", "th", "thead", "tr", "body", + "html")) + for node in self.tree.openElements[::-1]: + if node.name not in allowed_elements: + self.parser.parseError("expected-closing-tag-but-got-eof") + break + # Stop parsing + + def processSpaceCharactersDropNewline(self, token): + # Sometimes (start of <pre>, <listing>, and <textarea> blocks) we + # want to drop leading newlines + data = token["data"] + self.processSpaceCharacters = self.processSpaceCharactersNonPre + if (data.startswith("\n") and + self.tree.openElements[-1].name in ("pre", "listing", "textarea") and + not self.tree.openElements[-1].hasContent()): + data = data[1:] + if data: + self.tree.reconstructActiveFormattingElements() + self.tree.insertText(data) + + def processCharacters(self, token): + if token["data"] == "\u0000": + # The tokenizer should always emit null on its own + return + self.tree.reconstructActiveFormattingElements() + self.tree.insertText(token["data"]) + # This must be bad for performance + if (self.parser.framesetOK and + any([char not in spaceCharacters + for char in token["data"]])): + self.parser.framesetOK = False + + def processSpaceCharactersNonPre(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertText(token["data"]) + + def startTagProcessInHead(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagBody(self, token): + self.parser.parseError("unexpected-start-tag", {"name": "body"}) + if (len(self.tree.openElements) == 1 or + self.tree.openElements[1].name != "body"): + assert self.parser.innerHTML + else: + self.parser.framesetOK = False + for attr, value in token["data"].items(): + if attr not in self.tree.openElements[1].attributes: + self.tree.openElements[1].attributes[attr] = value + + def startTagFrameset(self, token): + self.parser.parseError("unexpected-start-tag", {"name": "frameset"}) + if (len(self.tree.openElements) == 1 or self.tree.openElements[1].name != "body"): + assert self.parser.innerHTML + elif not self.parser.framesetOK: + pass + else: + if self.tree.openElements[1].parent: + self.tree.openElements[1].parent.removeChild(self.tree.openElements[1]) + while self.tree.openElements[-1].name != "html": + self.tree.openElements.pop() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inFrameset"] + + def startTagCloseP(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + + def startTagPreListing(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.parser.framesetOK = False + self.processSpaceCharacters = self.processSpaceCharactersDropNewline + + def startTagForm(self, token): + if self.tree.formPointer: + self.parser.parseError("unexpected-start-tag", {"name": "form"}) + else: + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.tree.formPointer = self.tree.openElements[-1] + + def startTagListItem(self, token): + self.parser.framesetOK = False + + stopNamesMap = {"li": ["li"], + "dt": ["dt", "dd"], + "dd": ["dt", "dd"]} + stopNames = stopNamesMap[token["name"]] + for node in reversed(self.tree.openElements): + if node.name in stopNames: + self.parser.phase.processEndTag( + impliedTagToken(node.name, "EndTag")) + break + if (node.nameTuple in specialElements and + node.name not in ("address", "div", "p")): + break + + if self.tree.elementInScope("p", variant="button"): + self.parser.phase.processEndTag( + impliedTagToken("p", "EndTag")) + + self.tree.insertElement(token) + + def startTagPlaintext(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.plaintextState + + def startTagHeading(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + if self.tree.openElements[-1].name in headingElements: + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + self.tree.openElements.pop() + self.tree.insertElement(token) + + def startTagA(self, token): + afeAElement = self.tree.elementInActiveFormattingElements("a") + if afeAElement: + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "a", "endName": "a"}) + self.endTagFormatting(impliedTagToken("a")) + if afeAElement in self.tree.openElements: + self.tree.openElements.remove(afeAElement) + if afeAElement in self.tree.activeFormattingElements: + self.tree.activeFormattingElements.remove(afeAElement) + self.tree.reconstructActiveFormattingElements() + self.addFormattingElement(token) + + def startTagFormatting(self, token): + self.tree.reconstructActiveFormattingElements() + self.addFormattingElement(token) + + def startTagNobr(self, token): + self.tree.reconstructActiveFormattingElements() + if self.tree.elementInScope("nobr"): + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "nobr", "endName": "nobr"}) + self.processEndTag(impliedTagToken("nobr")) + # XXX Need tests that trigger the following + self.tree.reconstructActiveFormattingElements() + self.addFormattingElement(token) + + def startTagButton(self, token): + if self.tree.elementInScope("button"): + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "button", "endName": "button"}) + self.processEndTag(impliedTagToken("button")) + return token + else: + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.parser.framesetOK = False + + def startTagAppletMarqueeObject(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.tree.activeFormattingElements.append(Marker) + self.parser.framesetOK = False + + def startTagXmp(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.reconstructActiveFormattingElements() + self.parser.framesetOK = False + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagTable(self, token): + if self.parser.compatMode != "quirks": + if self.tree.elementInScope("p", variant="button"): + self.processEndTag(impliedTagToken("p")) + self.tree.insertElement(token) + self.parser.framesetOK = False + self.parser.phase = self.parser.phases["inTable"] + + def startTagVoidFormatting(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + self.parser.framesetOK = False + + def startTagInput(self, token): + framesetOK = self.parser.framesetOK + self.startTagVoidFormatting(token) + if ("type" in token["data"] and + token["data"]["type"].translate(asciiUpper2Lower) == "hidden"): + # input type=hidden doesn't change framesetOK + self.parser.framesetOK = framesetOK + + def startTagParamSource(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagHr(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + self.parser.framesetOK = False + + def startTagImage(self, token): + # No really... + self.parser.parseError("unexpected-start-tag-treated-as", + {"originalName": "image", "newName": "img"}) + self.processStartTag(impliedTagToken("img", "StartTag", + attributes=token["data"], + selfClosing=token["selfClosing"])) + + def startTagIsIndex(self, token): + self.parser.parseError("deprecated-tag", {"name": "isindex"}) + if self.tree.formPointer: + return + form_attrs = {} + if "action" in token["data"]: + form_attrs["action"] = token["data"]["action"] + self.processStartTag(impliedTagToken("form", "StartTag", + attributes=form_attrs)) + self.processStartTag(impliedTagToken("hr", "StartTag")) + self.processStartTag(impliedTagToken("label", "StartTag")) + # XXX Localization ... + if "prompt" in token["data"]: + prompt = token["data"]["prompt"] + else: + prompt = "This is a searchable index. Enter search keywords: " + self.processCharacters( + {"type": tokenTypes["Characters"], "data": prompt}) + attributes = token["data"].copy() + if "action" in attributes: + del attributes["action"] + if "prompt" in attributes: + del attributes["prompt"] + attributes["name"] = "isindex" + self.processStartTag(impliedTagToken("input", "StartTag", + attributes=attributes, + selfClosing=token["selfClosing"])) + self.processEndTag(impliedTagToken("label")) + self.processStartTag(impliedTagToken("hr", "StartTag")) + self.processEndTag(impliedTagToken("form")) + + def startTagTextarea(self, token): + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.rcdataState + self.processSpaceCharacters = self.processSpaceCharactersDropNewline + self.parser.framesetOK = False + + def startTagIFrame(self, token): + self.parser.framesetOK = False + self.startTagRawtext(token) + + def startTagNoscript(self, token): + if self.parser.scripting: + self.startTagRawtext(token) + else: + self.startTagOther(token) + + def startTagRawtext(self, token): + """iframe, noembed noframes, noscript(if scripting enabled)""" + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagOpt(self, token): + if self.tree.openElements[-1].name == "option": + self.parser.phase.processEndTag(impliedTagToken("option")) + self.tree.reconstructActiveFormattingElements() + self.parser.tree.insertElement(token) + + def startTagSelect(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.parser.framesetOK = False + if self.parser.phase in (self.parser.phases["inTable"], + self.parser.phases["inCaption"], + self.parser.phases["inColumnGroup"], + self.parser.phases["inTableBody"], + self.parser.phases["inRow"], + self.parser.phases["inCell"]): + self.parser.phase = self.parser.phases["inSelectInTable"] + else: + self.parser.phase = self.parser.phases["inSelect"] + + def startTagRpRt(self, token): + if self.tree.elementInScope("ruby"): + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != "ruby": + self.parser.parseError() + self.tree.insertElement(token) + + def startTagMath(self, token): + self.tree.reconstructActiveFormattingElements() + self.parser.adjustMathMLAttributes(token) + self.parser.adjustForeignAttributes(token) + token["namespace"] = namespaces["mathml"] + self.tree.insertElement(token) + # Need to get the parse error right for the case where the token + # has a namespace not equal to the xmlns attribute + if token["selfClosing"]: + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagSvg(self, token): + self.tree.reconstructActiveFormattingElements() + self.parser.adjustSVGAttributes(token) + self.parser.adjustForeignAttributes(token) + token["namespace"] = namespaces["svg"] + self.tree.insertElement(token) + # Need to get the parse error right for the case where the token + # has a namespace not equal to the xmlns attribute + if token["selfClosing"]: + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagMisplaced(self, token): + """ Elements that should be children of other elements that have a + different insertion mode; here they are ignored + "caption", "col", "colgroup", "frame", "frameset", "head", + "option", "optgroup", "tbody", "td", "tfoot", "th", "thead", + "tr", "noscript" + """ + self.parser.parseError("unexpected-start-tag-ignored", {"name": token["name"]}) + + def startTagOther(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + + def endTagP(self, token): + if not self.tree.elementInScope("p", variant="button"): + self.startTagCloseP(impliedTagToken("p", "StartTag")) + self.parser.parseError("unexpected-end-tag", {"name": "p"}) + self.endTagP(impliedTagToken("p", "EndTag")) + else: + self.tree.generateImpliedEndTags("p") + if self.tree.openElements[-1].name != "p": + self.parser.parseError("unexpected-end-tag", {"name": "p"}) + node = self.tree.openElements.pop() + while node.name != "p": + node = self.tree.openElements.pop() + + def endTagBody(self, token): + if not self.tree.elementInScope("body"): + self.parser.parseError() + return + elif self.tree.openElements[-1].name != "body": + for node in self.tree.openElements[2:]: + if node.name not in frozenset(("dd", "dt", "li", "optgroup", + "option", "p", "rp", "rt", + "tbody", "td", "tfoot", + "th", "thead", "tr", "body", + "html")): + # Not sure this is the correct name for the parse error + self.parser.parseError( + "expected-one-end-tag-but-got-another", + {"gotName": "body", "expectedName": node.name}) + break + self.parser.phase = self.parser.phases["afterBody"] + + def endTagHtml(self, token): + # We repeat the test for the body end tag token being ignored here + if self.tree.elementInScope("body"): + self.endTagBody(impliedTagToken("body")) + return token + + def endTagBlock(self, token): + # Put us back in the right whitespace handling mode + if token["name"] == "pre": + self.processSpaceCharacters = self.processSpaceCharactersNonPre + inScope = self.tree.elementInScope(token["name"]) + if inScope: + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("end-tag-too-early", {"name": token["name"]}) + if inScope: + node = self.tree.openElements.pop() + while node.name != token["name"]: + node = self.tree.openElements.pop() + + def endTagForm(self, token): + node = self.tree.formPointer + self.tree.formPointer = None + if node is None or not self.tree.elementInScope(node): + self.parser.parseError("unexpected-end-tag", + {"name": "form"}) + else: + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1] != node: + self.parser.parseError("end-tag-too-early-ignored", + {"name": "form"}) + self.tree.openElements.remove(node) + + def endTagListItem(self, token): + if token["name"] == "li": + variant = "list" + else: + variant = None + if not self.tree.elementInScope(token["name"], variant=variant): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + else: + self.tree.generateImpliedEndTags(exclude=token["name"]) + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError( + "end-tag-too-early", + {"name": token["name"]}) + node = self.tree.openElements.pop() + while node.name != token["name"]: + node = self.tree.openElements.pop() + + def endTagHeading(self, token): + for item in headingElements: + if self.tree.elementInScope(item): + self.tree.generateImpliedEndTags() + break + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("end-tag-too-early", {"name": token["name"]}) + + for item in headingElements: + if self.tree.elementInScope(item): + item = self.tree.openElements.pop() + while item.name not in headingElements: + item = self.tree.openElements.pop() + break + + def endTagFormatting(self, token): + """The much-feared adoption agency algorithm""" + # http://svn.whatwg.org/webapps/complete.html#adoptionAgency revision 7867 + # XXX Better parseError messages appreciated. + + # Step 1 + outerLoopCounter = 0 + + # Step 2 + while outerLoopCounter < 8: + + # Step 3 + outerLoopCounter += 1 + + # Step 4: + + # Let the formatting element be the last element in + # the list of active formatting elements that: + # - is between the end of the list and the last scope + # marker in the list, if any, or the start of the list + # otherwise, and + # - has the same tag name as the token. + formattingElement = self.tree.elementInActiveFormattingElements( + token["name"]) + if (not formattingElement or + (formattingElement in self.tree.openElements and + not self.tree.elementInScope(formattingElement.name))): + # If there is no such node, then abort these steps + # and instead act as described in the "any other + # end tag" entry below. + self.endTagOther(token) + return + + # Otherwise, if there is such a node, but that node is + # not in the stack of open elements, then this is a + # parse error; remove the element from the list, and + # abort these steps. + elif formattingElement not in self.tree.openElements: + self.parser.parseError("adoption-agency-1.2", {"name": token["name"]}) + self.tree.activeFormattingElements.remove(formattingElement) + return + + # Otherwise, if there is such a node, and that node is + # also in the stack of open elements, but the element + # is not in scope, then this is a parse error; ignore + # the token, and abort these steps. + elif not self.tree.elementInScope(formattingElement.name): + self.parser.parseError("adoption-agency-4.4", {"name": token["name"]}) + return + + # Otherwise, there is a formatting element and that + # element is in the stack and is in scope. If the + # element is not the current node, this is a parse + # error. In any case, proceed with the algorithm as + # written in the following steps. + else: + if formattingElement != self.tree.openElements[-1]: + self.parser.parseError("adoption-agency-1.3", {"name": token["name"]}) + + # Step 5: + + # Let the furthest block be the topmost node in the + # stack of open elements that is lower in the stack + # than the formatting element, and is an element in + # the special category. There might not be one. + afeIndex = self.tree.openElements.index(formattingElement) + furthestBlock = None + for element in self.tree.openElements[afeIndex:]: + if element.nameTuple in specialElements: + furthestBlock = element + break + + # Step 6: + + # If there is no furthest block, then the UA must + # first pop all the nodes from the bottom of the stack + # of open elements, from the current node up to and + # including the formatting element, then remove the + # formatting element from the list of active + # formatting elements, and finally abort these steps. + if furthestBlock is None: + element = self.tree.openElements.pop() + while element != formattingElement: + element = self.tree.openElements.pop() + self.tree.activeFormattingElements.remove(element) + return + + # Step 7 + commonAncestor = self.tree.openElements[afeIndex - 1] + + # Step 8: + # The bookmark is supposed to help us identify where to reinsert + # nodes in step 15. We have to ensure that we reinsert nodes after + # the node before the active formatting element. Note the bookmark + # can move in step 9.7 + bookmark = self.tree.activeFormattingElements.index(formattingElement) + + # Step 9 + lastNode = node = furthestBlock + innerLoopCounter = 0 + + index = self.tree.openElements.index(node) + while innerLoopCounter < 3: + innerLoopCounter += 1 + # Node is element before node in open elements + index -= 1 + node = self.tree.openElements[index] + if node not in self.tree.activeFormattingElements: + self.tree.openElements.remove(node) + continue + # Step 9.6 + if node == formattingElement: + break + # Step 9.7 + if lastNode == furthestBlock: + bookmark = self.tree.activeFormattingElements.index(node) + 1 + # Step 9.8 + clone = node.cloneNode() + # Replace node with clone + self.tree.activeFormattingElements[ + self.tree.activeFormattingElements.index(node)] = clone + self.tree.openElements[ + self.tree.openElements.index(node)] = clone + node = clone + # Step 9.9 + # Remove lastNode from its parents, if any + if lastNode.parent: + lastNode.parent.removeChild(lastNode) + node.appendChild(lastNode) + # Step 9.10 + lastNode = node + + # Step 10 + # Foster parent lastNode if commonAncestor is a + # table, tbody, tfoot, thead, or tr we need to foster + # parent the lastNode + if lastNode.parent: + lastNode.parent.removeChild(lastNode) + + if commonAncestor.name in frozenset(("table", "tbody", "tfoot", "thead", "tr")): + parent, insertBefore = self.tree.getTableMisnestedNodePosition() + parent.insertBefore(lastNode, insertBefore) + else: + commonAncestor.appendChild(lastNode) + + # Step 11 + clone = formattingElement.cloneNode() + + # Step 12 + furthestBlock.reparentChildren(clone) + + # Step 13 + furthestBlock.appendChild(clone) + + # Step 14 + self.tree.activeFormattingElements.remove(formattingElement) + self.tree.activeFormattingElements.insert(bookmark, clone) + + # Step 15 + self.tree.openElements.remove(formattingElement) + self.tree.openElements.insert( + self.tree.openElements.index(furthestBlock) + 1, clone) + + def endTagAppletMarqueeObject(self, token): + if self.tree.elementInScope(token["name"]): + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("end-tag-too-early", {"name": token["name"]}) + + if self.tree.elementInScope(token["name"]): + element = self.tree.openElements.pop() + while element.name != token["name"]: + element = self.tree.openElements.pop() + self.tree.clearActiveFormattingElements() + + def endTagBr(self, token): + self.parser.parseError("unexpected-end-tag-treated-as", + {"originalName": "br", "newName": "br element"}) + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(impliedTagToken("br", "StartTag")) + self.tree.openElements.pop() + + def endTagOther(self, token): + for node in self.tree.openElements[::-1]: + if node.name == token["name"]: + self.tree.generateImpliedEndTags(exclude=token["name"]) + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + while self.tree.openElements.pop() != node: + pass + break + else: + if node.nameTuple in specialElements: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + break + + class TextPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([]) + self.startTagHandler.default = self.startTagOther + self.endTagHandler = _utils.MethodDispatcher([ + ("script", self.endTagScript)]) + self.endTagHandler.default = self.endTagOther + + def processCharacters(self, token): + self.tree.insertText(token["data"]) + + def processEOF(self): + self.parser.parseError("expected-named-closing-tag-but-got-eof", + {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + self.parser.phase = self.parser.originalPhase + return True + + def startTagOther(self, token): + assert False, "Tried to process start tag %s in RCDATA/RAWTEXT mode" % token['name'] + + def endTagScript(self, token): + node = self.tree.openElements.pop() + assert node.name == "script" + self.parser.phase = self.parser.originalPhase + # The rest of this method is all stuff that only happens if + # document.write works + + def endTagOther(self, token): + self.tree.openElements.pop() + self.parser.phase = self.parser.originalPhase + + class InTablePhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-table + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("caption", self.startTagCaption), + ("colgroup", self.startTagColgroup), + ("col", self.startTagCol), + (("tbody", "tfoot", "thead"), self.startTagRowGroup), + (("td", "th", "tr"), self.startTagImplyTbody), + ("table", self.startTagTable), + (("style", "script"), self.startTagStyleScript), + ("input", self.startTagInput), + ("form", self.startTagForm) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("table", self.endTagTable), + (("body", "caption", "col", "colgroup", "html", "tbody", "td", + "tfoot", "th", "thead", "tr"), self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + # helper methods + def clearStackToTableContext(self): + # "clear the stack back to a table context" + while self.tree.openElements[-1].name not in ("table", "html"): + # self.parser.parseError("unexpected-implied-end-tag-in-table", + # {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + # When the current node is <html> it's an innerHTML case + + # processing methods + def processEOF(self): + if self.tree.openElements[-1].name != "html": + self.parser.parseError("eof-in-table") + else: + assert self.parser.innerHTML + # Stop parsing + + def processSpaceCharacters(self, token): + originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["inTableText"] + self.parser.phase.originalPhase = originalPhase + self.parser.phase.processSpaceCharacters(token) + + def processCharacters(self, token): + originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["inTableText"] + self.parser.phase.originalPhase = originalPhase + self.parser.phase.processCharacters(token) + + def insertText(self, token): + # If we get here there must be at least one non-whitespace character + # Do the table magic! + self.tree.insertFromTable = True + self.parser.phases["inBody"].processCharacters(token) + self.tree.insertFromTable = False + + def startTagCaption(self, token): + self.clearStackToTableContext() + self.tree.activeFormattingElements.append(Marker) + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inCaption"] + + def startTagColgroup(self, token): + self.clearStackToTableContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inColumnGroup"] + + def startTagCol(self, token): + self.startTagColgroup(impliedTagToken("colgroup", "StartTag")) + return token + + def startTagRowGroup(self, token): + self.clearStackToTableContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inTableBody"] + + def startTagImplyTbody(self, token): + self.startTagRowGroup(impliedTagToken("tbody", "StartTag")) + return token + + def startTagTable(self, token): + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "table", "endName": "table"}) + self.parser.phase.processEndTag(impliedTagToken("table")) + if not self.parser.innerHTML: + return token + + def startTagStyleScript(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagInput(self, token): + if ("type" in token["data"] and + token["data"]["type"].translate(asciiUpper2Lower) == "hidden"): + self.parser.parseError("unexpected-hidden-input-in-table") + self.tree.insertElement(token) + # XXX associate with form + self.tree.openElements.pop() + else: + self.startTagOther(token) + + def startTagForm(self, token): + self.parser.parseError("unexpected-form-in-table") + if self.tree.formPointer is None: + self.tree.insertElement(token) + self.tree.formPointer = self.tree.openElements[-1] + self.tree.openElements.pop() + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-implies-table-voodoo", {"name": token["name"]}) + # Do the table magic! + self.tree.insertFromTable = True + self.parser.phases["inBody"].processStartTag(token) + self.tree.insertFromTable = False + + def endTagTable(self, token): + if self.tree.elementInScope("table", variant="table"): + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != "table": + self.parser.parseError("end-tag-too-early-named", + {"gotName": "table", + "expectedName": self.tree.openElements[-1].name}) + while self.tree.openElements[-1].name != "table": + self.tree.openElements.pop() + self.tree.openElements.pop() + self.parser.resetInsertionMode() + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-implies-table-voodoo", {"name": token["name"]}) + # Do the table magic! + self.tree.insertFromTable = True + self.parser.phases["inBody"].processEndTag(token) + self.tree.insertFromTable = False + + class InTableTextPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.originalPhase = None + self.characterTokens = [] + + def flushCharacters(self): + data = "".join([item["data"] for item in self.characterTokens]) + if any([item not in spaceCharacters for item in data]): + token = {"type": tokenTypes["Characters"], "data": data} + self.parser.phases["inTable"].insertText(token) + elif data: + self.tree.insertText(data) + self.characterTokens = [] + + def processComment(self, token): + self.flushCharacters() + self.parser.phase = self.originalPhase + return token + + def processEOF(self): + self.flushCharacters() + self.parser.phase = self.originalPhase + return True + + def processCharacters(self, token): + if token["data"] == "\u0000": + return + self.characterTokens.append(token) + + def processSpaceCharacters(self, token): + # pretty sure we should never reach here + self.characterTokens.append(token) + # assert False + + def processStartTag(self, token): + self.flushCharacters() + self.parser.phase = self.originalPhase + return token + + def processEndTag(self, token): + self.flushCharacters() + self.parser.phase = self.originalPhase + return token + + class InCaptionPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-caption + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("caption", "col", "colgroup", "tbody", "td", "tfoot", "th", + "thead", "tr"), self.startTagTableElement) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("caption", self.endTagCaption), + ("table", self.endTagTable), + (("body", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", + "thead", "tr"), self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + def ignoreEndTagCaption(self): + return not self.tree.elementInScope("caption", variant="table") + + def processEOF(self): + self.parser.phases["inBody"].processEOF() + + def processCharacters(self, token): + return self.parser.phases["inBody"].processCharacters(token) + + def startTagTableElement(self, token): + self.parser.parseError() + # XXX Have to duplicate logic here to find out if the tag is ignored + ignoreEndTag = self.ignoreEndTagCaption() + self.parser.phase.processEndTag(impliedTagToken("caption")) + if not ignoreEndTag: + return token + + def startTagOther(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def endTagCaption(self, token): + if not self.ignoreEndTagCaption(): + # AT this code is quite similar to endTagTable in "InTable" + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != "caption": + self.parser.parseError("expected-one-end-tag-but-got-another", + {"gotName": "caption", + "expectedName": self.tree.openElements[-1].name}) + while self.tree.openElements[-1].name != "caption": + self.tree.openElements.pop() + self.tree.openElements.pop() + self.tree.clearActiveFormattingElements() + self.parser.phase = self.parser.phases["inTable"] + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagTable(self, token): + self.parser.parseError() + ignoreEndTag = self.ignoreEndTagCaption() + self.parser.phase.processEndTag(impliedTagToken("caption")) + if not ignoreEndTag: + return token + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagOther(self, token): + return self.parser.phases["inBody"].processEndTag(token) + + class InColumnGroupPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-column + + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("col", self.startTagCol) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("colgroup", self.endTagColgroup), + ("col", self.endTagCol) + ]) + self.endTagHandler.default = self.endTagOther + + def ignoreEndTagColgroup(self): + return self.tree.openElements[-1].name == "html" + + def processEOF(self): + if self.tree.openElements[-1].name == "html": + assert self.parser.innerHTML + return + else: + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return True + + def processCharacters(self, token): + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return token + + def startTagCol(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagOther(self, token): + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return token + + def endTagColgroup(self, token): + if self.ignoreEndTagColgroup(): + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + else: + self.tree.openElements.pop() + self.parser.phase = self.parser.phases["inTable"] + + def endTagCol(self, token): + self.parser.parseError("no-end-tag", {"name": "col"}) + + def endTagOther(self, token): + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return token + + class InTableBodyPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-table0 + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("tr", self.startTagTr), + (("td", "th"), self.startTagTableCell), + (("caption", "col", "colgroup", "tbody", "tfoot", "thead"), + self.startTagTableOther) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("tbody", "tfoot", "thead"), self.endTagTableRowGroup), + ("table", self.endTagTable), + (("body", "caption", "col", "colgroup", "html", "td", "th", + "tr"), self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + # helper methods + def clearStackToTableBodyContext(self): + while self.tree.openElements[-1].name not in ("tbody", "tfoot", + "thead", "html"): + # self.parser.parseError("unexpected-implied-end-tag-in-table", + # {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + if self.tree.openElements[-1].name == "html": + assert self.parser.innerHTML + + # the rest + def processEOF(self): + self.parser.phases["inTable"].processEOF() + + def processSpaceCharacters(self, token): + return self.parser.phases["inTable"].processSpaceCharacters(token) + + def processCharacters(self, token): + return self.parser.phases["inTable"].processCharacters(token) + + def startTagTr(self, token): + self.clearStackToTableBodyContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inRow"] + + def startTagTableCell(self, token): + self.parser.parseError("unexpected-cell-in-table-body", + {"name": token["name"]}) + self.startTagTr(impliedTagToken("tr", "StartTag")) + return token + + def startTagTableOther(self, token): + # XXX AT Any ideas on how to share this with endTagTable? + if (self.tree.elementInScope("tbody", variant="table") or + self.tree.elementInScope("thead", variant="table") or + self.tree.elementInScope("tfoot", variant="table")): + self.clearStackToTableBodyContext() + self.endTagTableRowGroup( + impliedTagToken(self.tree.openElements[-1].name)) + return token + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def startTagOther(self, token): + return self.parser.phases["inTable"].processStartTag(token) + + def endTagTableRowGroup(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.clearStackToTableBodyContext() + self.tree.openElements.pop() + self.parser.phase = self.parser.phases["inTable"] + else: + self.parser.parseError("unexpected-end-tag-in-table-body", + {"name": token["name"]}) + + def endTagTable(self, token): + if (self.tree.elementInScope("tbody", variant="table") or + self.tree.elementInScope("thead", variant="table") or + self.tree.elementInScope("tfoot", variant="table")): + self.clearStackToTableBodyContext() + self.endTagTableRowGroup( + impliedTagToken(self.tree.openElements[-1].name)) + return token + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag-in-table-body", + {"name": token["name"]}) + + def endTagOther(self, token): + return self.parser.phases["inTable"].processEndTag(token) + + class InRowPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-row + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("td", "th"), self.startTagTableCell), + (("caption", "col", "colgroup", "tbody", "tfoot", "thead", + "tr"), self.startTagTableOther) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("tr", self.endTagTr), + ("table", self.endTagTable), + (("tbody", "tfoot", "thead"), self.endTagTableRowGroup), + (("body", "caption", "col", "colgroup", "html", "td", "th"), + self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + # helper methods (XXX unify this with other table helper methods) + def clearStackToTableRowContext(self): + while self.tree.openElements[-1].name not in ("tr", "html"): + self.parser.parseError("unexpected-implied-end-tag-in-table-row", + {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + + def ignoreEndTagTr(self): + return not self.tree.elementInScope("tr", variant="table") + + # the rest + def processEOF(self): + self.parser.phases["inTable"].processEOF() + + def processSpaceCharacters(self, token): + return self.parser.phases["inTable"].processSpaceCharacters(token) + + def processCharacters(self, token): + return self.parser.phases["inTable"].processCharacters(token) + + def startTagTableCell(self, token): + self.clearStackToTableRowContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inCell"] + self.tree.activeFormattingElements.append(Marker) + + def startTagTableOther(self, token): + ignoreEndTag = self.ignoreEndTagTr() + self.endTagTr(impliedTagToken("tr")) + # XXX how are we sure it's always ignored in the innerHTML case? + if not ignoreEndTag: + return token + + def startTagOther(self, token): + return self.parser.phases["inTable"].processStartTag(token) + + def endTagTr(self, token): + if not self.ignoreEndTagTr(): + self.clearStackToTableRowContext() + self.tree.openElements.pop() + self.parser.phase = self.parser.phases["inTableBody"] + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagTable(self, token): + ignoreEndTag = self.ignoreEndTagTr() + self.endTagTr(impliedTagToken("tr")) + # Reprocess the current tag if the tr end tag was not ignored + # XXX how are we sure it's always ignored in the innerHTML case? + if not ignoreEndTag: + return token + + def endTagTableRowGroup(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.endTagTr(impliedTagToken("tr")) + return token + else: + self.parser.parseError() + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag-in-table-row", + {"name": token["name"]}) + + def endTagOther(self, token): + return self.parser.phases["inTable"].processEndTag(token) + + class InCellPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-cell + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("caption", "col", "colgroup", "tbody", "td", "tfoot", "th", + "thead", "tr"), self.startTagTableOther) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("td", "th"), self.endTagTableCell), + (("body", "caption", "col", "colgroup", "html"), self.endTagIgnore), + (("table", "tbody", "tfoot", "thead", "tr"), self.endTagImply) + ]) + self.endTagHandler.default = self.endTagOther + + # helper + def closeCell(self): + if self.tree.elementInScope("td", variant="table"): + self.endTagTableCell(impliedTagToken("td")) + elif self.tree.elementInScope("th", variant="table"): + self.endTagTableCell(impliedTagToken("th")) + + # the rest + def processEOF(self): + self.parser.phases["inBody"].processEOF() + + def processCharacters(self, token): + return self.parser.phases["inBody"].processCharacters(token) + + def startTagTableOther(self, token): + if (self.tree.elementInScope("td", variant="table") or + self.tree.elementInScope("th", variant="table")): + self.closeCell() + return token + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def startTagOther(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def endTagTableCell(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.tree.generateImpliedEndTags(token["name"]) + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("unexpected-cell-end-tag", + {"name": token["name"]}) + while True: + node = self.tree.openElements.pop() + if node.name == token["name"]: + break + else: + self.tree.openElements.pop() + self.tree.clearActiveFormattingElements() + self.parser.phase = self.parser.phases["inRow"] + else: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagImply(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.closeCell() + return token + else: + # sometimes innerHTML case + self.parser.parseError() + + def endTagOther(self, token): + return self.parser.phases["inBody"].processEndTag(token) + + class InSelectPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("option", self.startTagOption), + ("optgroup", self.startTagOptgroup), + ("select", self.startTagSelect), + (("input", "keygen", "textarea"), self.startTagInput), + ("script", self.startTagScript) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("option", self.endTagOption), + ("optgroup", self.endTagOptgroup), + ("select", self.endTagSelect) + ]) + self.endTagHandler.default = self.endTagOther + + # http://www.whatwg.org/specs/web-apps/current-work/#in-select + def processEOF(self): + if self.tree.openElements[-1].name != "html": + self.parser.parseError("eof-in-select") + else: + assert self.parser.innerHTML + + def processCharacters(self, token): + if token["data"] == "\u0000": + return + self.tree.insertText(token["data"]) + + def startTagOption(self, token): + # We need to imply </option> if <option> is the current node. + if self.tree.openElements[-1].name == "option": + self.tree.openElements.pop() + self.tree.insertElement(token) + + def startTagOptgroup(self, token): + if self.tree.openElements[-1].name == "option": + self.tree.openElements.pop() + if self.tree.openElements[-1].name == "optgroup": + self.tree.openElements.pop() + self.tree.insertElement(token) + + def startTagSelect(self, token): + self.parser.parseError("unexpected-select-in-select") + self.endTagSelect(impliedTagToken("select")) + + def startTagInput(self, token): + self.parser.parseError("unexpected-input-in-select") + if self.tree.elementInScope("select", variant="select"): + self.endTagSelect(impliedTagToken("select")) + return token + else: + assert self.parser.innerHTML + + def startTagScript(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-in-select", + {"name": token["name"]}) + + def endTagOption(self, token): + if self.tree.openElements[-1].name == "option": + self.tree.openElements.pop() + else: + self.parser.parseError("unexpected-end-tag-in-select", + {"name": "option"}) + + def endTagOptgroup(self, token): + # </optgroup> implicitly closes <option> + if (self.tree.openElements[-1].name == "option" and + self.tree.openElements[-2].name == "optgroup"): + self.tree.openElements.pop() + # It also closes </optgroup> + if self.tree.openElements[-1].name == "optgroup": + self.tree.openElements.pop() + # But nothing else + else: + self.parser.parseError("unexpected-end-tag-in-select", + {"name": "optgroup"}) + + def endTagSelect(self, token): + if self.tree.elementInScope("select", variant="select"): + node = self.tree.openElements.pop() + while node.name != "select": + node = self.tree.openElements.pop() + self.parser.resetInsertionMode() + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-in-select", + {"name": token["name"]}) + + class InSelectInTablePhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + (("caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th"), + self.startTagTable) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th"), + self.endTagTable) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.parser.phases["inSelect"].processEOF() + + def processCharacters(self, token): + return self.parser.phases["inSelect"].processCharacters(token) + + def startTagTable(self, token): + self.parser.parseError("unexpected-table-element-start-tag-in-select-in-table", {"name": token["name"]}) + self.endTagOther(impliedTagToken("select")) + return token + + def startTagOther(self, token): + return self.parser.phases["inSelect"].processStartTag(token) + + def endTagTable(self, token): + self.parser.parseError("unexpected-table-element-end-tag-in-select-in-table", {"name": token["name"]}) + if self.tree.elementInScope(token["name"], variant="table"): + self.endTagOther(impliedTagToken("select")) + return token + + def endTagOther(self, token): + return self.parser.phases["inSelect"].processEndTag(token) + + class InForeignContentPhase(Phase): + breakoutElements = frozenset(["b", "big", "blockquote", "body", "br", + "center", "code", "dd", "div", "dl", "dt", + "em", "embed", "h1", "h2", "h3", + "h4", "h5", "h6", "head", "hr", "i", "img", + "li", "listing", "menu", "meta", "nobr", + "ol", "p", "pre", "ruby", "s", "small", + "span", "strong", "strike", "sub", "sup", + "table", "tt", "u", "ul", "var"]) + + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + def adjustSVGTagNames(self, token): + replacements = {"altglyph": "altGlyph", + "altglyphdef": "altGlyphDef", + "altglyphitem": "altGlyphItem", + "animatecolor": "animateColor", + "animatemotion": "animateMotion", + "animatetransform": "animateTransform", + "clippath": "clipPath", + "feblend": "feBlend", + "fecolormatrix": "feColorMatrix", + "fecomponenttransfer": "feComponentTransfer", + "fecomposite": "feComposite", + "feconvolvematrix": "feConvolveMatrix", + "fediffuselighting": "feDiffuseLighting", + "fedisplacementmap": "feDisplacementMap", + "fedistantlight": "feDistantLight", + "feflood": "feFlood", + "fefunca": "feFuncA", + "fefuncb": "feFuncB", + "fefuncg": "feFuncG", + "fefuncr": "feFuncR", + "fegaussianblur": "feGaussianBlur", + "feimage": "feImage", + "femerge": "feMerge", + "femergenode": "feMergeNode", + "femorphology": "feMorphology", + "feoffset": "feOffset", + "fepointlight": "fePointLight", + "fespecularlighting": "feSpecularLighting", + "fespotlight": "feSpotLight", + "fetile": "feTile", + "feturbulence": "feTurbulence", + "foreignobject": "foreignObject", + "glyphref": "glyphRef", + "lineargradient": "linearGradient", + "radialgradient": "radialGradient", + "textpath": "textPath"} + + if token["name"] in replacements: + token["name"] = replacements[token["name"]] + + def processCharacters(self, token): + if token["data"] == "\u0000": + token["data"] = "\uFFFD" + elif (self.parser.framesetOK and + any(char not in spaceCharacters for char in token["data"])): + self.parser.framesetOK = False + Phase.processCharacters(self, token) + + def processStartTag(self, token): + currentNode = self.tree.openElements[-1] + if (token["name"] in self.breakoutElements or + (token["name"] == "font" and + set(token["data"].keys()) & set(["color", "face", "size"]))): + self.parser.parseError("unexpected-html-element-in-foreign-content", + {"name": token["name"]}) + while (self.tree.openElements[-1].namespace != + self.tree.defaultNamespace and + not self.parser.isHTMLIntegrationPoint(self.tree.openElements[-1]) and + not self.parser.isMathMLTextIntegrationPoint(self.tree.openElements[-1])): + self.tree.openElements.pop() + return token + + else: + if currentNode.namespace == namespaces["mathml"]: + self.parser.adjustMathMLAttributes(token) + elif currentNode.namespace == namespaces["svg"]: + self.adjustSVGTagNames(token) + self.parser.adjustSVGAttributes(token) + self.parser.adjustForeignAttributes(token) + token["namespace"] = currentNode.namespace + self.tree.insertElement(token) + if token["selfClosing"]: + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def processEndTag(self, token): + nodeIndex = len(self.tree.openElements) - 1 + node = self.tree.openElements[-1] + if node.name.translate(asciiUpper2Lower) != token["name"]: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + while True: + if node.name.translate(asciiUpper2Lower) == token["name"]: + # XXX this isn't in the spec but it seems necessary + if self.parser.phase == self.parser.phases["inTableText"]: + self.parser.phase.flushCharacters() + self.parser.phase = self.parser.phase.originalPhase + while self.tree.openElements.pop() != node: + assert self.tree.openElements + new_token = None + break + nodeIndex -= 1 + + node = self.tree.openElements[nodeIndex] + if node.namespace != self.tree.defaultNamespace: + continue + else: + new_token = self.parser.phase.processEndTag(token) + break + return new_token + + class AfterBodyPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([("html", self.endTagHtml)]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + # Stop parsing + pass + + def processComment(self, token): + # This is needed because data is to be appended to the <html> element + # here and not to whatever is currently open. + self.tree.insertComment(token, self.tree.openElements[0]) + + def processCharacters(self, token): + self.parser.parseError("unexpected-char-after-body") + self.parser.phase = self.parser.phases["inBody"] + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-after-body", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + def endTagHtml(self, name): + if self.parser.innerHTML: + self.parser.parseError("unexpected-end-tag-after-body-innerhtml") + else: + self.parser.phase = self.parser.phases["afterAfterBody"] + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-after-body", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + class InFramesetPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-frameset + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("frameset", self.startTagFrameset), + ("frame", self.startTagFrame), + ("noframes", self.startTagNoframes) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("frameset", self.endTagFrameset) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + if self.tree.openElements[-1].name != "html": + self.parser.parseError("eof-in-frameset") + else: + assert self.parser.innerHTML + + def processCharacters(self, token): + self.parser.parseError("unexpected-char-in-frameset") + + def startTagFrameset(self, token): + self.tree.insertElement(token) + + def startTagFrame(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + + def startTagNoframes(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-in-frameset", + {"name": token["name"]}) + + def endTagFrameset(self, token): + if self.tree.openElements[-1].name == "html": + # innerHTML case + self.parser.parseError("unexpected-frameset-in-frameset-innerhtml") + else: + self.tree.openElements.pop() + if (not self.parser.innerHTML and + self.tree.openElements[-1].name != "frameset"): + # If we're not in innerHTML mode and the current node is not a + # "frameset" element (anymore) then switch. + self.parser.phase = self.parser.phases["afterFrameset"] + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-in-frameset", + {"name": token["name"]}) + + class AfterFramesetPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#after3 + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("noframes", self.startTagNoframes) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("html", self.endTagHtml) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + # Stop parsing + pass + + def processCharacters(self, token): + self.parser.parseError("unexpected-char-after-frameset") + + def startTagNoframes(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-after-frameset", + {"name": token["name"]}) + + def endTagHtml(self, token): + self.parser.phase = self.parser.phases["afterAfterFrameset"] + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-after-frameset", + {"name": token["name"]}) + + class AfterAfterBodyPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml) + ]) + self.startTagHandler.default = self.startTagOther + + def processEOF(self): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + return self.parser.phases["inBody"].processSpaceCharacters(token) + + def processCharacters(self, token): + self.parser.parseError("expected-eof-but-got-char") + self.parser.phase = self.parser.phases["inBody"] + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("expected-eof-but-got-start-tag", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + def processEndTag(self, token): + self.parser.parseError("expected-eof-but-got-end-tag", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + class AfterAfterFramesetPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("noframes", self.startTagNoFrames) + ]) + self.startTagHandler.default = self.startTagOther + + def processEOF(self): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + return self.parser.phases["inBody"].processSpaceCharacters(token) + + def processCharacters(self, token): + self.parser.parseError("expected-eof-but-got-char") + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagNoFrames(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("expected-eof-but-got-start-tag", + {"name": token["name"]}) + + def processEndTag(self, token): + self.parser.parseError("expected-eof-but-got-end-tag", + {"name": token["name"]}) + # pylint:enable=unused-argument + + return { + "initial": InitialPhase, + "beforeHtml": BeforeHtmlPhase, + "beforeHead": BeforeHeadPhase, + "inHead": InHeadPhase, + "inHeadNoscript": InHeadNoscriptPhase, + "afterHead": AfterHeadPhase, + "inBody": InBodyPhase, + "text": TextPhase, + "inTable": InTablePhase, + "inTableText": InTableTextPhase, + "inCaption": InCaptionPhase, + "inColumnGroup": InColumnGroupPhase, + "inTableBody": InTableBodyPhase, + "inRow": InRowPhase, + "inCell": InCellPhase, + "inSelect": InSelectPhase, + "inSelectInTable": InSelectInTablePhase, + "inForeignContent": InForeignContentPhase, + "afterBody": AfterBodyPhase, + "inFrameset": InFramesetPhase, + "afterFrameset": AfterFramesetPhase, + "afterAfterBody": AfterAfterBodyPhase, + "afterAfterFrameset": AfterAfterFramesetPhase, + # XXX after after frameset + } + + +def adjust_attributes(token, replacements): + needs_adjustment = viewkeys(token['data']) & viewkeys(replacements) + if needs_adjustment: + token['data'] = OrderedDict((replacements.get(k, k), v) + for k, v in token['data'].items()) + + +def impliedTagToken(name, type="EndTag", attributes=None, + selfClosing=False): + if attributes is None: + attributes = {} + return {"type": tokenTypes[type], "name": name, "data": attributes, + "selfClosing": selfClosing} + + +class ParseError(Exception): + """Error in parsed document""" + pass diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/serializer.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/serializer.py new file mode 100644 index 0000000..53f4d44 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/serializer.py @@ -0,0 +1,409 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +import re + +from codecs import register_error, xmlcharrefreplace_errors + +from .constants import voidElements, booleanAttributes, spaceCharacters +from .constants import rcdataElements, entities, xmlEntities +from . import treewalkers, _utils +from xml.sax.saxutils import escape + +_quoteAttributeSpecChars = "".join(spaceCharacters) + "\"'=<>`" +_quoteAttributeSpec = re.compile("[" + _quoteAttributeSpecChars + "]") +_quoteAttributeLegacy = re.compile("[" + _quoteAttributeSpecChars + + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n" + "\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15" + "\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + "\x20\x2f\x60\xa0\u1680\u180e\u180f\u2000" + "\u2001\u2002\u2003\u2004\u2005\u2006\u2007" + "\u2008\u2009\u200a\u2028\u2029\u202f\u205f" + "\u3000]") + + +_encode_entity_map = {} +_is_ucs4 = len("\U0010FFFF") == 1 +for k, v in list(entities.items()): + # skip multi-character entities + if ((_is_ucs4 and len(v) > 1) or + (not _is_ucs4 and len(v) > 2)): + continue + if v != "&": + if len(v) == 2: + v = _utils.surrogatePairToCodepoint(v) + else: + v = ord(v) + if v not in _encode_entity_map or k.islower(): + # prefer < over < and similarly for &, >, etc. + _encode_entity_map[v] = k + + +def htmlentityreplace_errors(exc): + if isinstance(exc, (UnicodeEncodeError, UnicodeTranslateError)): + res = [] + codepoints = [] + skip = False + for i, c in enumerate(exc.object[exc.start:exc.end]): + if skip: + skip = False + continue + index = i + exc.start + if _utils.isSurrogatePair(exc.object[index:min([exc.end, index + 2])]): + codepoint = _utils.surrogatePairToCodepoint(exc.object[index:index + 2]) + skip = True + else: + codepoint = ord(c) + codepoints.append(codepoint) + for cp in codepoints: + e = _encode_entity_map.get(cp) + if e: + res.append("&") + res.append(e) + if not e.endswith(";"): + res.append(";") + else: + res.append("&#x%s;" % (hex(cp)[2:])) + return ("".join(res), exc.end) + else: + return xmlcharrefreplace_errors(exc) + + +register_error("htmlentityreplace", htmlentityreplace_errors) + + +def serialize(input, tree="etree", encoding=None, **serializer_opts): + """Serializes the input token stream using the specified treewalker + + :arg input: the token stream to serialize + + :arg tree: the treewalker to use + + :arg encoding: the encoding to use + + :arg serializer_opts: any options to pass to the + :py:class:`html5lib.serializer.HTMLSerializer` that gets created + + :returns: the tree serialized as a string + + Example: + + >>> from html5lib.html5parser import parse + >>> from html5lib.serializer import serialize + >>> token_stream = parse('<html><body><p>Hi!</p></body></html>') + >>> serialize(token_stream, omit_optional_tags=False) + '<html><head></head><body><p>Hi!</p></body></html>' + + """ + # XXX: Should we cache this? + walker = treewalkers.getTreeWalker(tree) + s = HTMLSerializer(**serializer_opts) + return s.render(walker(input), encoding) + + +class HTMLSerializer(object): + + # attribute quoting options + quote_attr_values = "legacy" # be secure by default + quote_char = '"' + use_best_quote_char = True + + # tag syntax options + omit_optional_tags = True + minimize_boolean_attributes = True + use_trailing_solidus = False + space_before_trailing_solidus = True + + # escaping options + escape_lt_in_attrs = False + escape_rcdata = False + resolve_entities = True + + # miscellaneous options + alphabetical_attributes = False + inject_meta_charset = True + strip_whitespace = False + sanitize = False + + options = ("quote_attr_values", "quote_char", "use_best_quote_char", + "omit_optional_tags", "minimize_boolean_attributes", + "use_trailing_solidus", "space_before_trailing_solidus", + "escape_lt_in_attrs", "escape_rcdata", "resolve_entities", + "alphabetical_attributes", "inject_meta_charset", + "strip_whitespace", "sanitize") + + def __init__(self, **kwargs): + """Initialize HTMLSerializer + + :arg inject_meta_charset: Whether or not to inject the meta charset. + + Defaults to ``True``. + + :arg quote_attr_values: Whether to quote attribute values that don't + require quoting per legacy browser behavior (``"legacy"``), when + required by the standard (``"spec"``), or always (``"always"``). + + Defaults to ``"legacy"``. + + :arg quote_char: Use given quote character for attribute quoting. + + Defaults to ``"`` which will use double quotes unless attribute + value contains a double quote, in which case single quotes are + used. + + :arg escape_lt_in_attrs: Whether or not to escape ``<`` in attribute + values. + + Defaults to ``False``. + + :arg escape_rcdata: Whether to escape characters that need to be + escaped within normal elements within rcdata elements such as + style. + + Defaults to ``False``. + + :arg resolve_entities: Whether to resolve named character entities that + appear in the source tree. The XML predefined entities < > + & " ' are unaffected by this setting. + + Defaults to ``True``. + + :arg strip_whitespace: Whether to remove semantically meaningless + whitespace. (This compresses all whitespace to a single space + except within ``pre``.) + + Defaults to ``False``. + + :arg minimize_boolean_attributes: Shortens boolean attributes to give + just the attribute value, for example:: + + <input disabled="disabled"> + + becomes:: + + <input disabled> + + Defaults to ``True``. + + :arg use_trailing_solidus: Includes a close-tag slash at the end of the + start tag of void elements (empty elements whose end tag is + forbidden). E.g. ``<hr/>``. + + Defaults to ``False``. + + :arg space_before_trailing_solidus: Places a space immediately before + the closing slash in a tag using a trailing solidus. E.g. + ``<hr />``. Requires ``use_trailing_solidus=True``. + + Defaults to ``True``. + + :arg sanitize: Strip all unsafe or unknown constructs from output. + See :py:class:`html5lib.filters.sanitizer.Filter`. + + Defaults to ``False``. + + :arg omit_optional_tags: Omit start/end tags that are optional. + + Defaults to ``True``. + + :arg alphabetical_attributes: Reorder attributes to be in alphabetical order. + + Defaults to ``False``. + + """ + unexpected_args = frozenset(kwargs) - frozenset(self.options) + if len(unexpected_args) > 0: + raise TypeError("__init__() got an unexpected keyword argument '%s'" % next(iter(unexpected_args))) + if 'quote_char' in kwargs: + self.use_best_quote_char = False + for attr in self.options: + setattr(self, attr, kwargs.get(attr, getattr(self, attr))) + self.errors = [] + self.strict = False + + def encode(self, string): + assert(isinstance(string, text_type)) + if self.encoding: + return string.encode(self.encoding, "htmlentityreplace") + else: + return string + + def encodeStrict(self, string): + assert(isinstance(string, text_type)) + if self.encoding: + return string.encode(self.encoding, "strict") + else: + return string + + def serialize(self, treewalker, encoding=None): + # pylint:disable=too-many-nested-blocks + self.encoding = encoding + in_cdata = False + self.errors = [] + + if encoding and self.inject_meta_charset: + from .filters.inject_meta_charset import Filter + treewalker = Filter(treewalker, encoding) + # Alphabetical attributes is here under the assumption that none of + # the later filters add or change order of attributes; it needs to be + # before the sanitizer so escaped elements come out correctly + if self.alphabetical_attributes: + from .filters.alphabeticalattributes import Filter + treewalker = Filter(treewalker) + # WhitespaceFilter should be used before OptionalTagFilter + # for maximum efficiently of this latter filter + if self.strip_whitespace: + from .filters.whitespace import Filter + treewalker = Filter(treewalker) + if self.sanitize: + from .filters.sanitizer import Filter + treewalker = Filter(treewalker) + if self.omit_optional_tags: + from .filters.optionaltags import Filter + treewalker = Filter(treewalker) + + for token in treewalker: + type = token["type"] + if type == "Doctype": + doctype = "<!DOCTYPE %s" % token["name"] + + if token["publicId"]: + doctype += ' PUBLIC "%s"' % token["publicId"] + elif token["systemId"]: + doctype += " SYSTEM" + if token["systemId"]: + if token["systemId"].find('"') >= 0: + if token["systemId"].find("'") >= 0: + self.serializeError("System identifer contains both single and double quote characters") + quote_char = "'" + else: + quote_char = '"' + doctype += " %s%s%s" % (quote_char, token["systemId"], quote_char) + + doctype += ">" + yield self.encodeStrict(doctype) + + elif type in ("Characters", "SpaceCharacters"): + if type == "SpaceCharacters" or in_cdata: + if in_cdata and token["data"].find("</") >= 0: + self.serializeError("Unexpected </ in CDATA") + yield self.encode(token["data"]) + else: + yield self.encode(escape(token["data"])) + + elif type in ("StartTag", "EmptyTag"): + name = token["name"] + yield self.encodeStrict("<%s" % name) + if name in rcdataElements and not self.escape_rcdata: + in_cdata = True + elif in_cdata: + self.serializeError("Unexpected child element of a CDATA element") + for (_, attr_name), attr_value in token["data"].items(): + # TODO: Add namespace support here + k = attr_name + v = attr_value + yield self.encodeStrict(' ') + + yield self.encodeStrict(k) + if not self.minimize_boolean_attributes or \ + (k not in booleanAttributes.get(name, tuple()) and + k not in booleanAttributes.get("", tuple())): + yield self.encodeStrict("=") + if self.quote_attr_values == "always" or len(v) == 0: + quote_attr = True + elif self.quote_attr_values == "spec": + quote_attr = _quoteAttributeSpec.search(v) is not None + elif self.quote_attr_values == "legacy": + quote_attr = _quoteAttributeLegacy.search(v) is not None + else: + raise ValueError("quote_attr_values must be one of: " + "'always', 'spec', or 'legacy'") + v = v.replace("&", "&") + if self.escape_lt_in_attrs: + v = v.replace("<", "<") + if quote_attr: + quote_char = self.quote_char + if self.use_best_quote_char: + if "'" in v and '"' not in v: + quote_char = '"' + elif '"' in v and "'" not in v: + quote_char = "'" + if quote_char == "'": + v = v.replace("'", "'") + else: + v = v.replace('"', """) + yield self.encodeStrict(quote_char) + yield self.encode(v) + yield self.encodeStrict(quote_char) + else: + yield self.encode(v) + if name in voidElements and self.use_trailing_solidus: + if self.space_before_trailing_solidus: + yield self.encodeStrict(" /") + else: + yield self.encodeStrict("/") + yield self.encode(">") + + elif type == "EndTag": + name = token["name"] + if name in rcdataElements: + in_cdata = False + elif in_cdata: + self.serializeError("Unexpected child element of a CDATA element") + yield self.encodeStrict("</%s>" % name) + + elif type == "Comment": + data = token["data"] + if data.find("--") >= 0: + self.serializeError("Comment contains --") + yield self.encodeStrict("<!--%s-->" % token["data"]) + + elif type == "Entity": + name = token["name"] + key = name + ";" + if key not in entities: + self.serializeError("Entity %s not recognized" % name) + if self.resolve_entities and key not in xmlEntities: + data = entities[key] + else: + data = "&%s;" % name + yield self.encodeStrict(data) + + else: + self.serializeError(token["data"]) + + def render(self, treewalker, encoding=None): + """Serializes the stream from the treewalker into a string + + :arg treewalker: the treewalker to serialize + + :arg encoding: the string encoding to use + + :returns: the serialized tree + + Example: + + >>> from html5lib import parse, getTreeWalker + >>> from html5lib.serializer import HTMLSerializer + >>> token_stream = parse('<html><body>Hi!</body></html>') + >>> walker = getTreeWalker('etree') + >>> serializer = HTMLSerializer(omit_optional_tags=False) + >>> serializer.render(walker(token_stream)) + '<html><head></head><body>Hi!</body></html>' + + """ + if encoding: + return b"".join(list(self.serialize(treewalker, encoding))) + else: + return "".join(list(self.serialize(treewalker))) + + def serializeError(self, data="XXX ERROR MESSAGE NEEDED"): + # XXX The idea is to make data mandatory. + self.errors.append(data) + if self.strict: + raise SerializeError + + +class SerializeError(Exception): + """Error in serialized tree""" + pass diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/__init__.py new file mode 100644 index 0000000..7ef5959 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/__init__.py @@ -0,0 +1,30 @@ +"""Tree adapters let you convert from one tree structure to another + +Example: + +.. code-block:: python + + from pip._vendor import html5lib + from pip._vendor.html5lib.treeadapters import genshi + + doc = '<html><body>Hi!</body></html>' + treebuilder = html5lib.getTreeBuilder('etree') + parser = html5lib.HTMLParser(tree=treebuilder) + tree = parser.parse(doc) + TreeWalker = html5lib.getTreeWalker('etree') + + genshi_tree = genshi.to_genshi(TreeWalker(tree)) + +""" +from __future__ import absolute_import, division, unicode_literals + +from . import sax + +__all__ = ["sax"] + +try: + from . import genshi # noqa +except ImportError: + pass +else: + __all__.append("genshi") diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/genshi.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/genshi.py new file mode 100644 index 0000000..61d5fb6 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/genshi.py @@ -0,0 +1,54 @@ +from __future__ import absolute_import, division, unicode_literals + +from genshi.core import QName, Attrs +from genshi.core import START, END, TEXT, COMMENT, DOCTYPE + + +def to_genshi(walker): + """Convert a tree to a genshi tree + + :arg walker: the treewalker to use to walk the tree to convert it + + :returns: generator of genshi nodes + + """ + text = [] + for token in walker: + type = token["type"] + if type in ("Characters", "SpaceCharacters"): + text.append(token["data"]) + elif text: + yield TEXT, "".join(text), (None, -1, -1) + text = [] + + if type in ("StartTag", "EmptyTag"): + if token["namespace"]: + name = "{%s}%s" % (token["namespace"], token["name"]) + else: + name = token["name"] + attrs = Attrs([(QName("{%s}%s" % attr if attr[0] is not None else attr[1]), value) + for attr, value in token["data"].items()]) + yield (START, (QName(name), attrs), (None, -1, -1)) + if type == "EmptyTag": + type = "EndTag" + + if type == "EndTag": + if token["namespace"]: + name = "{%s}%s" % (token["namespace"], token["name"]) + else: + name = token["name"] + + yield END, QName(name), (None, -1, -1) + + elif type == "Comment": + yield COMMENT, token["data"], (None, -1, -1) + + elif type == "Doctype": + yield DOCTYPE, (token["name"], token["publicId"], + token["systemId"]), (None, -1, -1) + + else: + pass # FIXME: What to do? + + if text: + yield TEXT, "".join(text), (None, -1, -1) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/sax.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/sax.py new file mode 100644 index 0000000..f4ccea5 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/sax.py @@ -0,0 +1,50 @@ +from __future__ import absolute_import, division, unicode_literals + +from xml.sax.xmlreader import AttributesNSImpl + +from ..constants import adjustForeignAttributes, unadjustForeignAttributes + +prefix_mapping = {} +for prefix, localName, namespace in adjustForeignAttributes.values(): + if prefix is not None: + prefix_mapping[prefix] = namespace + + +def to_sax(walker, handler): + """Call SAX-like content handler based on treewalker walker + + :arg walker: the treewalker to use to walk the tree to convert it + + :arg handler: SAX handler to use + + """ + handler.startDocument() + for prefix, namespace in prefix_mapping.items(): + handler.startPrefixMapping(prefix, namespace) + + for token in walker: + type = token["type"] + if type == "Doctype": + continue + elif type in ("StartTag", "EmptyTag"): + attrs = AttributesNSImpl(token["data"], + unadjustForeignAttributes) + handler.startElementNS((token["namespace"], token["name"]), + token["name"], + attrs) + if type == "EmptyTag": + handler.endElementNS((token["namespace"], token["name"]), + token["name"]) + elif type == "EndTag": + handler.endElementNS((token["namespace"], token["name"]), + token["name"]) + elif type in ("Characters", "SpaceCharacters"): + handler.characters(token["data"]) + elif type == "Comment": + pass + else: + assert False, "Unknown token type" + + for prefix, namespace in prefix_mapping.items(): + handler.endPrefixMapping(prefix) + handler.endDocument() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__init__.py new file mode 100644 index 0000000..d44447e --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__init__.py @@ -0,0 +1,88 @@ +"""A collection of modules for building different kinds of trees from HTML +documents. + +To create a treebuilder for a new type of tree, you need to do +implement several things: + +1. A set of classes for various types of elements: Document, Doctype, Comment, + Element. These must implement the interface of ``base.treebuilders.Node`` + (although comment nodes have a different signature for their constructor, + see ``treebuilders.etree.Comment``) Textual content may also be implemented + as another node type, or not, as your tree implementation requires. + +2. A treebuilder object (called ``TreeBuilder`` by convention) that inherits + from ``treebuilders.base.TreeBuilder``. This has 4 required attributes: + + * ``documentClass`` - the class to use for the bottommost node of a document + * ``elementClass`` - the class to use for HTML Elements + * ``commentClass`` - the class to use for comments + * ``doctypeClass`` - the class to use for doctypes + + It also has one required method: + + * ``getDocument`` - Returns the root node of the complete document tree + +3. If you wish to run the unit tests, you must also create a ``testSerializer`` + method on your treebuilder which accepts a node and returns a string + containing Node and its children serialized according to the format used in + the unittests + +""" + +from __future__ import absolute_import, division, unicode_literals + +from .._utils import default_etree + +treeBuilderCache = {} + + +def getTreeBuilder(treeType, implementation=None, **kwargs): + """Get a TreeBuilder class for various types of trees with built-in support + + :arg treeType: the name of the tree type required (case-insensitive). Supported + values are: + + * "dom" - A generic builder for DOM implementations, defaulting to a + xml.dom.minidom based implementation. + * "etree" - A generic builder for tree implementations exposing an + ElementTree-like interface, defaulting to xml.etree.cElementTree if + available and xml.etree.ElementTree if not. + * "lxml" - A etree-based builder for lxml.etree, handling limitations + of lxml's implementation. + + :arg implementation: (Currently applies to the "etree" and "dom" tree + types). A module implementing the tree type e.g. xml.etree.ElementTree + or xml.etree.cElementTree. + + :arg kwargs: Any additional options to pass to the TreeBuilder when + creating it. + + Example: + + >>> from html5lib.treebuilders import getTreeBuilder + >>> builder = getTreeBuilder('etree') + + """ + + treeType = treeType.lower() + if treeType not in treeBuilderCache: + if treeType == "dom": + from . import dom + # Come up with a sane default (pref. from the stdlib) + if implementation is None: + from xml.dom import minidom + implementation = minidom + # NEVER cache here, caching is done in the dom submodule + return dom.getDomModule(implementation, **kwargs).TreeBuilder + elif treeType == "lxml": + from . import etree_lxml + treeBuilderCache[treeType] = etree_lxml.TreeBuilder + elif treeType == "etree": + from . import etree + if implementation is None: + implementation = default_etree + # NEVER cache here, caching is done in the etree submodule + return etree.getETreeModule(implementation, **kwargs).TreeBuilder + else: + raise ValueError("""Unrecognised treebuilder "%s" """ % treeType) + return treeBuilderCache.get(treeType) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/base.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/base.py new file mode 100644 index 0000000..73973db --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/base.py @@ -0,0 +1,417 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from ..constants import scopingElements, tableInsertModeElements, namespaces + +# The scope markers are inserted when entering object elements, +# marquees, table cells, and table captions, and are used to prevent formatting +# from "leaking" into tables, object elements, and marquees. +Marker = None + +listElementsMap = { + None: (frozenset(scopingElements), False), + "button": (frozenset(scopingElements | set([(namespaces["html"], "button")])), False), + "list": (frozenset(scopingElements | set([(namespaces["html"], "ol"), + (namespaces["html"], "ul")])), False), + "table": (frozenset([(namespaces["html"], "html"), + (namespaces["html"], "table")]), False), + "select": (frozenset([(namespaces["html"], "optgroup"), + (namespaces["html"], "option")]), True) +} + + +class Node(object): + """Represents an item in the tree""" + def __init__(self, name): + """Creates a Node + + :arg name: The tag name associated with the node + + """ + # The tag name assocaited with the node + self.name = name + # The parent of the current node (or None for the document node) + self.parent = None + # The value of the current node (applies to text nodes and comments) + self.value = None + # A dict holding name -> value pairs for attributes of the node + self.attributes = {} + # A list of child nodes of the current node. This must include all + # elements but not necessarily other node types. + self.childNodes = [] + # A list of miscellaneous flags that can be set on the node. + self._flags = [] + + def __str__(self): + attributesStr = " ".join(["%s=\"%s\"" % (name, value) + for name, value in + self.attributes.items()]) + if attributesStr: + return "<%s %s>" % (self.name, attributesStr) + else: + return "<%s>" % (self.name) + + def __repr__(self): + return "<%s>" % (self.name) + + def appendChild(self, node): + """Insert node as a child of the current node + + :arg node: the node to insert + + """ + raise NotImplementedError + + def insertText(self, data, insertBefore=None): + """Insert data as text in the current node, positioned before the + start of node insertBefore or to the end of the node's text. + + :arg data: the data to insert + + :arg insertBefore: True if you want to insert the text before the node + and False if you want to insert it after the node + + """ + raise NotImplementedError + + def insertBefore(self, node, refNode): + """Insert node as a child of the current node, before refNode in the + list of child nodes. Raises ValueError if refNode is not a child of + the current node + + :arg node: the node to insert + + :arg refNode: the child node to insert the node before + + """ + raise NotImplementedError + + def removeChild(self, node): + """Remove node from the children of the current node + + :arg node: the child node to remove + + """ + raise NotImplementedError + + def reparentChildren(self, newParent): + """Move all the children of the current node to newParent. + This is needed so that trees that don't store text as nodes move the + text in the correct way + + :arg newParent: the node to move all this node's children to + + """ + # XXX - should this method be made more general? + for child in self.childNodes: + newParent.appendChild(child) + self.childNodes = [] + + def cloneNode(self): + """Return a shallow copy of the current node i.e. a node with the same + name and attributes but with no parent or child nodes + """ + raise NotImplementedError + + def hasContent(self): + """Return true if the node has children or text, false otherwise + """ + raise NotImplementedError + + +class ActiveFormattingElements(list): + def append(self, node): + equalCount = 0 + if node != Marker: + for element in self[::-1]: + if element == Marker: + break + if self.nodesEqual(element, node): + equalCount += 1 + if equalCount == 3: + self.remove(element) + break + list.append(self, node) + + def nodesEqual(self, node1, node2): + if not node1.nameTuple == node2.nameTuple: + return False + + if not node1.attributes == node2.attributes: + return False + + return True + + +class TreeBuilder(object): + """Base treebuilder implementation + + * documentClass - the class to use for the bottommost node of a document + * elementClass - the class to use for HTML Elements + * commentClass - the class to use for comments + * doctypeClass - the class to use for doctypes + + """ + # pylint:disable=not-callable + + # Document class + documentClass = None + + # The class to use for creating a node + elementClass = None + + # The class to use for creating comments + commentClass = None + + # The class to use for creating doctypes + doctypeClass = None + + # Fragment class + fragmentClass = None + + def __init__(self, namespaceHTMLElements): + """Create a TreeBuilder + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + """ + if namespaceHTMLElements: + self.defaultNamespace = "http://www.w3.org/1999/xhtml" + else: + self.defaultNamespace = None + self.reset() + + def reset(self): + self.openElements = [] + self.activeFormattingElements = ActiveFormattingElements() + + # XXX - rename these to headElement, formElement + self.headPointer = None + self.formPointer = None + + self.insertFromTable = False + + self.document = self.documentClass() + + def elementInScope(self, target, variant=None): + + # If we pass a node in we match that. if we pass a string + # match any node with that name + exactNode = hasattr(target, "nameTuple") + if not exactNode: + if isinstance(target, text_type): + target = (namespaces["html"], target) + assert isinstance(target, tuple) + + listElements, invert = listElementsMap[variant] + + for node in reversed(self.openElements): + if exactNode and node == target: + return True + elif not exactNode and node.nameTuple == target: + return True + elif (invert ^ (node.nameTuple in listElements)): + return False + + assert False # We should never reach this point + + def reconstructActiveFormattingElements(self): + # Within this algorithm the order of steps described in the + # specification is not quite the same as the order of steps in the + # code. It should still do the same though. + + # Step 1: stop the algorithm when there's nothing to do. + if not self.activeFormattingElements: + return + + # Step 2 and step 3: we start with the last element. So i is -1. + i = len(self.activeFormattingElements) - 1 + entry = self.activeFormattingElements[i] + if entry == Marker or entry in self.openElements: + return + + # Step 6 + while entry != Marker and entry not in self.openElements: + if i == 0: + # This will be reset to 0 below + i = -1 + break + i -= 1 + # Step 5: let entry be one earlier in the list. + entry = self.activeFormattingElements[i] + + while True: + # Step 7 + i += 1 + + # Step 8 + entry = self.activeFormattingElements[i] + clone = entry.cloneNode() # Mainly to get a new copy of the attributes + + # Step 9 + element = self.insertElement({"type": "StartTag", + "name": clone.name, + "namespace": clone.namespace, + "data": clone.attributes}) + + # Step 10 + self.activeFormattingElements[i] = element + + # Step 11 + if element == self.activeFormattingElements[-1]: + break + + def clearActiveFormattingElements(self): + entry = self.activeFormattingElements.pop() + while self.activeFormattingElements and entry != Marker: + entry = self.activeFormattingElements.pop() + + def elementInActiveFormattingElements(self, name): + """Check if an element exists between the end of the active + formatting elements and the last marker. If it does, return it, else + return false""" + + for item in self.activeFormattingElements[::-1]: + # Check for Marker first because if it's a Marker it doesn't have a + # name attribute. + if item == Marker: + break + elif item.name == name: + return item + return False + + def insertRoot(self, token): + element = self.createElement(token) + self.openElements.append(element) + self.document.appendChild(element) + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + doctype = self.doctypeClass(name, publicId, systemId) + self.document.appendChild(doctype) + + def insertComment(self, token, parent=None): + if parent is None: + parent = self.openElements[-1] + parent.appendChild(self.commentClass(token["data"])) + + def createElement(self, token): + """Create an element but don't insert it anywhere""" + name = token["name"] + namespace = token.get("namespace", self.defaultNamespace) + element = self.elementClass(name, namespace) + element.attributes = token["data"] + return element + + def _getInsertFromTable(self): + return self._insertFromTable + + def _setInsertFromTable(self, value): + """Switch the function used to insert an element from the + normal one to the misnested table one and back again""" + self._insertFromTable = value + if value: + self.insertElement = self.insertElementTable + else: + self.insertElement = self.insertElementNormal + + insertFromTable = property(_getInsertFromTable, _setInsertFromTable) + + def insertElementNormal(self, token): + name = token["name"] + assert isinstance(name, text_type), "Element %s not unicode" % name + namespace = token.get("namespace", self.defaultNamespace) + element = self.elementClass(name, namespace) + element.attributes = token["data"] + self.openElements[-1].appendChild(element) + self.openElements.append(element) + return element + + def insertElementTable(self, token): + """Create an element and insert it into the tree""" + element = self.createElement(token) + if self.openElements[-1].name not in tableInsertModeElements: + return self.insertElementNormal(token) + else: + # We should be in the InTable mode. This means we want to do + # special magic element rearranging + parent, insertBefore = self.getTableMisnestedNodePosition() + if insertBefore is None: + parent.appendChild(element) + else: + parent.insertBefore(element, insertBefore) + self.openElements.append(element) + return element + + def insertText(self, data, parent=None): + """Insert text data.""" + if parent is None: + parent = self.openElements[-1] + + if (not self.insertFromTable or (self.insertFromTable and + self.openElements[-1].name + not in tableInsertModeElements)): + parent.insertText(data) + else: + # We should be in the InTable mode. This means we want to do + # special magic element rearranging + parent, insertBefore = self.getTableMisnestedNodePosition() + parent.insertText(data, insertBefore) + + def getTableMisnestedNodePosition(self): + """Get the foster parent element, and sibling to insert before + (or None) when inserting a misnested table node""" + # The foster parent element is the one which comes before the most + # recently opened table element + # XXX - this is really inelegant + lastTable = None + fosterParent = None + insertBefore = None + for elm in self.openElements[::-1]: + if elm.name == "table": + lastTable = elm + break + if lastTable: + # XXX - we should really check that this parent is actually a + # node here + if lastTable.parent: + fosterParent = lastTable.parent + insertBefore = lastTable + else: + fosterParent = self.openElements[ + self.openElements.index(lastTable) - 1] + else: + fosterParent = self.openElements[0] + return fosterParent, insertBefore + + def generateImpliedEndTags(self, exclude=None): + name = self.openElements[-1].name + # XXX td, th and tr are not actually needed + if (name in frozenset(("dd", "dt", "li", "option", "optgroup", "p", "rp", "rt")) and + name != exclude): + self.openElements.pop() + # XXX This is not entirely what the specification says. We should + # investigate it more closely. + self.generateImpliedEndTags(exclude) + + def getDocument(self): + """Return the final tree""" + return self.document + + def getFragment(self): + """Return the final fragment""" + # assert self.innerHTML + fragment = self.fragmentClass() + self.openElements[0].reparentChildren(fragment) + return fragment + + def testSerializer(self, node): + """Serialize the subtree of node in the format required by unit tests + + :arg node: the node from which to start serializing + + """ + raise NotImplementedError diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/dom.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/dom.py new file mode 100644 index 0000000..dcfac22 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/dom.py @@ -0,0 +1,236 @@ +from __future__ import absolute_import, division, unicode_literals + + +from collections import MutableMapping +from xml.dom import minidom, Node +import weakref + +from . import base +from .. import constants +from ..constants import namespaces +from .._utils import moduleFactoryFactory + + +def getDomBuilder(DomImplementation): + Dom = DomImplementation + + class AttrList(MutableMapping): + def __init__(self, element): + self.element = element + + def __iter__(self): + return iter(self.element.attributes.keys()) + + def __setitem__(self, name, value): + if isinstance(name, tuple): + raise NotImplementedError + else: + attr = self.element.ownerDocument.createAttribute(name) + attr.value = value + self.element.attributes[name] = attr + + def __len__(self): + return len(self.element.attributes) + + def items(self): + return list(self.element.attributes.items()) + + def values(self): + return list(self.element.attributes.values()) + + def __getitem__(self, name): + if isinstance(name, tuple): + raise NotImplementedError + else: + return self.element.attributes[name].value + + def __delitem__(self, name): + if isinstance(name, tuple): + raise NotImplementedError + else: + del self.element.attributes[name] + + class NodeBuilder(base.Node): + def __init__(self, element): + base.Node.__init__(self, element.nodeName) + self.element = element + + namespace = property(lambda self: hasattr(self.element, "namespaceURI") and + self.element.namespaceURI or None) + + def appendChild(self, node): + node.parent = self + self.element.appendChild(node.element) + + def insertText(self, data, insertBefore=None): + text = self.element.ownerDocument.createTextNode(data) + if insertBefore: + self.element.insertBefore(text, insertBefore.element) + else: + self.element.appendChild(text) + + def insertBefore(self, node, refNode): + self.element.insertBefore(node.element, refNode.element) + node.parent = self + + def removeChild(self, node): + if node.element.parentNode == self.element: + self.element.removeChild(node.element) + node.parent = None + + def reparentChildren(self, newParent): + while self.element.hasChildNodes(): + child = self.element.firstChild + self.element.removeChild(child) + newParent.element.appendChild(child) + self.childNodes = [] + + def getAttributes(self): + return AttrList(self.element) + + def setAttributes(self, attributes): + if attributes: + for name, value in list(attributes.items()): + if isinstance(name, tuple): + if name[0] is not None: + qualifiedName = (name[0] + ":" + name[1]) + else: + qualifiedName = name[1] + self.element.setAttributeNS(name[2], qualifiedName, + value) + else: + self.element.setAttribute( + name, value) + attributes = property(getAttributes, setAttributes) + + def cloneNode(self): + return NodeBuilder(self.element.cloneNode(False)) + + def hasContent(self): + return self.element.hasChildNodes() + + def getNameTuple(self): + if self.namespace is None: + return namespaces["html"], self.name + else: + return self.namespace, self.name + + nameTuple = property(getNameTuple) + + class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable + def documentClass(self): + self.dom = Dom.getDOMImplementation().createDocument(None, None, None) + return weakref.proxy(self) + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + domimpl = Dom.getDOMImplementation() + doctype = domimpl.createDocumentType(name, publicId, systemId) + self.document.appendChild(NodeBuilder(doctype)) + if Dom == minidom: + doctype.ownerDocument = self.dom + + def elementClass(self, name, namespace=None): + if namespace is None and self.defaultNamespace is None: + node = self.dom.createElement(name) + else: + node = self.dom.createElementNS(namespace, name) + + return NodeBuilder(node) + + def commentClass(self, data): + return NodeBuilder(self.dom.createComment(data)) + + def fragmentClass(self): + return NodeBuilder(self.dom.createDocumentFragment()) + + def appendChild(self, node): + self.dom.appendChild(node.element) + + def testSerializer(self, element): + return testSerializer(element) + + def getDocument(self): + return self.dom + + def getFragment(self): + return base.TreeBuilder.getFragment(self).element + + def insertText(self, data, parent=None): + data = data + if parent != self: + base.TreeBuilder.insertText(self, data, parent) + else: + # HACK: allow text nodes as children of the document node + if hasattr(self.dom, '_child_node_types'): + # pylint:disable=protected-access + if Node.TEXT_NODE not in self.dom._child_node_types: + self.dom._child_node_types = list(self.dom._child_node_types) + self.dom._child_node_types.append(Node.TEXT_NODE) + self.dom.appendChild(self.dom.createTextNode(data)) + + implementation = DomImplementation + name = None + + def testSerializer(element): + element.normalize() + rv = [] + + def serializeElement(element, indent=0): + if element.nodeType == Node.DOCUMENT_TYPE_NODE: + if element.name: + if element.publicId or element.systemId: + publicId = element.publicId or "" + systemId = element.systemId or "" + rv.append("""|%s<!DOCTYPE %s "%s" "%s">""" % + (' ' * indent, element.name, publicId, systemId)) + else: + rv.append("|%s<!DOCTYPE %s>" % (' ' * indent, element.name)) + else: + rv.append("|%s<!DOCTYPE >" % (' ' * indent,)) + elif element.nodeType == Node.DOCUMENT_NODE: + rv.append("#document") + elif element.nodeType == Node.DOCUMENT_FRAGMENT_NODE: + rv.append("#document-fragment") + elif element.nodeType == Node.COMMENT_NODE: + rv.append("|%s<!-- %s -->" % (' ' * indent, element.nodeValue)) + elif element.nodeType == Node.TEXT_NODE: + rv.append("|%s\"%s\"" % (' ' * indent, element.nodeValue)) + else: + if (hasattr(element, "namespaceURI") and + element.namespaceURI is not None): + name = "%s %s" % (constants.prefixes[element.namespaceURI], + element.nodeName) + else: + name = element.nodeName + rv.append("|%s<%s>" % (' ' * indent, name)) + if element.hasAttributes(): + attributes = [] + for i in range(len(element.attributes)): + attr = element.attributes.item(i) + name = attr.nodeName + value = attr.value + ns = attr.namespaceURI + if ns: + name = "%s %s" % (constants.prefixes[ns], attr.localName) + else: + name = attr.nodeName + attributes.append((name, value)) + + for name, value in sorted(attributes): + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) + indent += 2 + for child in element.childNodes: + serializeElement(child, indent) + serializeElement(element, 0) + + return "\n".join(rv) + + return locals() + + +# The actual means to get a module! +getDomModule = moduleFactoryFactory(getDomBuilder) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree.py new file mode 100644 index 0000000..0dedf44 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree.py @@ -0,0 +1,340 @@ +from __future__ import absolute_import, division, unicode_literals +# pylint:disable=protected-access + +from pip._vendor.six import text_type + +import re + +from . import base +from .. import _ihatexml +from .. import constants +from ..constants import namespaces +from .._utils import moduleFactoryFactory + +tag_regexp = re.compile("{([^}]*)}(.*)") + + +def getETreeBuilder(ElementTreeImplementation, fullTree=False): + ElementTree = ElementTreeImplementation + ElementTreeCommentType = ElementTree.Comment("asd").tag + + class Element(base.Node): + def __init__(self, name, namespace=None): + self._name = name + self._namespace = namespace + self._element = ElementTree.Element(self._getETreeTag(name, + namespace)) + if namespace is None: + self.nameTuple = namespaces["html"], self._name + else: + self.nameTuple = self._namespace, self._name + self.parent = None + self._childNodes = [] + self._flags = [] + + def _getETreeTag(self, name, namespace): + if namespace is None: + etree_tag = name + else: + etree_tag = "{%s}%s" % (namespace, name) + return etree_tag + + def _setName(self, name): + self._name = name + self._element.tag = self._getETreeTag(self._name, self._namespace) + + def _getName(self): + return self._name + + name = property(_getName, _setName) + + def _setNamespace(self, namespace): + self._namespace = namespace + self._element.tag = self._getETreeTag(self._name, self._namespace) + + def _getNamespace(self): + return self._namespace + + namespace = property(_getNamespace, _setNamespace) + + def _getAttributes(self): + return self._element.attrib + + def _setAttributes(self, attributes): + # Delete existing attributes first + # XXX - there may be a better way to do this... + for key in list(self._element.attrib.keys()): + del self._element.attrib[key] + for key, value in attributes.items(): + if isinstance(key, tuple): + name = "{%s}%s" % (key[2], key[1]) + else: + name = key + self._element.set(name, value) + + attributes = property(_getAttributes, _setAttributes) + + def _getChildNodes(self): + return self._childNodes + + def _setChildNodes(self, value): + del self._element[:] + self._childNodes = [] + for element in value: + self.insertChild(element) + + childNodes = property(_getChildNodes, _setChildNodes) + + def hasContent(self): + """Return true if the node has children or text""" + return bool(self._element.text or len(self._element)) + + def appendChild(self, node): + self._childNodes.append(node) + self._element.append(node._element) + node.parent = self + + def insertBefore(self, node, refNode): + index = list(self._element).index(refNode._element) + self._element.insert(index, node._element) + node.parent = self + + def removeChild(self, node): + self._childNodes.remove(node) + self._element.remove(node._element) + node.parent = None + + def insertText(self, data, insertBefore=None): + if not(len(self._element)): + if not self._element.text: + self._element.text = "" + self._element.text += data + elif insertBefore is None: + # Insert the text as the tail of the last child element + if not self._element[-1].tail: + self._element[-1].tail = "" + self._element[-1].tail += data + else: + # Insert the text before the specified node + children = list(self._element) + index = children.index(insertBefore._element) + if index > 0: + if not self._element[index - 1].tail: + self._element[index - 1].tail = "" + self._element[index - 1].tail += data + else: + if not self._element.text: + self._element.text = "" + self._element.text += data + + def cloneNode(self): + element = type(self)(self.name, self.namespace) + for name, value in self.attributes.items(): + element.attributes[name] = value + return element + + def reparentChildren(self, newParent): + if newParent.childNodes: + newParent.childNodes[-1]._element.tail += self._element.text + else: + if not newParent._element.text: + newParent._element.text = "" + if self._element.text is not None: + newParent._element.text += self._element.text + self._element.text = "" + base.Node.reparentChildren(self, newParent) + + class Comment(Element): + def __init__(self, data): + # Use the superclass constructor to set all properties on the + # wrapper element + self._element = ElementTree.Comment(data) + self.parent = None + self._childNodes = [] + self._flags = [] + + def _getData(self): + return self._element.text + + def _setData(self, value): + self._element.text = value + + data = property(_getData, _setData) + + class DocumentType(Element): + def __init__(self, name, publicId, systemId): + Element.__init__(self, "<!DOCTYPE>") + self._element.text = name + self.publicId = publicId + self.systemId = systemId + + def _getPublicId(self): + return self._element.get("publicId", "") + + def _setPublicId(self, value): + if value is not None: + self._element.set("publicId", value) + + publicId = property(_getPublicId, _setPublicId) + + def _getSystemId(self): + return self._element.get("systemId", "") + + def _setSystemId(self, value): + if value is not None: + self._element.set("systemId", value) + + systemId = property(_getSystemId, _setSystemId) + + class Document(Element): + def __init__(self): + Element.__init__(self, "DOCUMENT_ROOT") + + class DocumentFragment(Element): + def __init__(self): + Element.__init__(self, "DOCUMENT_FRAGMENT") + + def testSerializer(element): + rv = [] + + def serializeElement(element, indent=0): + if not(hasattr(element, "tag")): + element = element.getroot() + if element.tag == "<!DOCTYPE>": + if element.get("publicId") or element.get("systemId"): + publicId = element.get("publicId") or "" + systemId = element.get("systemId") or "" + rv.append("""<!DOCTYPE %s "%s" "%s">""" % + (element.text, publicId, systemId)) + else: + rv.append("<!DOCTYPE %s>" % (element.text,)) + elif element.tag == "DOCUMENT_ROOT": + rv.append("#document") + if element.text is not None: + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) + if element.tail is not None: + raise TypeError("Document node cannot have tail") + if hasattr(element, "attrib") and len(element.attrib): + raise TypeError("Document node cannot have attributes") + elif element.tag == ElementTreeCommentType: + rv.append("|%s<!-- %s -->" % (' ' * indent, element.text)) + else: + assert isinstance(element.tag, text_type), \ + "Expected unicode, got %s, %s" % (type(element.tag), element.tag) + nsmatch = tag_regexp.match(element.tag) + + if nsmatch is None: + name = element.tag + else: + ns, name = nsmatch.groups() + prefix = constants.prefixes[ns] + name = "%s %s" % (prefix, name) + rv.append("|%s<%s>" % (' ' * indent, name)) + + if hasattr(element, "attrib"): + attributes = [] + for name, value in element.attrib.items(): + nsmatch = tag_regexp.match(name) + if nsmatch is not None: + ns, name = nsmatch.groups() + prefix = constants.prefixes[ns] + attr_string = "%s %s" % (prefix, name) + else: + attr_string = name + attributes.append((attr_string, value)) + + for name, value in sorted(attributes): + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) + if element.text: + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) + indent += 2 + for child in element: + serializeElement(child, indent) + if element.tail: + rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail)) + serializeElement(element, 0) + + return "\n".join(rv) + + def tostring(element): # pylint:disable=unused-variable + """Serialize an element and its child nodes to a string""" + rv = [] + filter = _ihatexml.InfosetFilter() + + def serializeElement(element): + if isinstance(element, ElementTree.ElementTree): + element = element.getroot() + + if element.tag == "<!DOCTYPE>": + if element.get("publicId") or element.get("systemId"): + publicId = element.get("publicId") or "" + systemId = element.get("systemId") or "" + rv.append("""<!DOCTYPE %s PUBLIC "%s" "%s">""" % + (element.text, publicId, systemId)) + else: + rv.append("<!DOCTYPE %s>" % (element.text,)) + elif element.tag == "DOCUMENT_ROOT": + if element.text is not None: + rv.append(element.text) + if element.tail is not None: + raise TypeError("Document node cannot have tail") + if hasattr(element, "attrib") and len(element.attrib): + raise TypeError("Document node cannot have attributes") + + for child in element: + serializeElement(child) + + elif element.tag == ElementTreeCommentType: + rv.append("<!--%s-->" % (element.text,)) + else: + # This is assumed to be an ordinary element + if not element.attrib: + rv.append("<%s>" % (filter.fromXmlName(element.tag),)) + else: + attr = " ".join(["%s=\"%s\"" % ( + filter.fromXmlName(name), value) + for name, value in element.attrib.items()]) + rv.append("<%s %s>" % (element.tag, attr)) + if element.text: + rv.append(element.text) + + for child in element: + serializeElement(child) + + rv.append("</%s>" % (element.tag,)) + + if element.tail: + rv.append(element.tail) + + serializeElement(element) + + return "".join(rv) + + class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable + documentClass = Document + doctypeClass = DocumentType + elementClass = Element + commentClass = Comment + fragmentClass = DocumentFragment + implementation = ElementTreeImplementation + + def testSerializer(self, element): + return testSerializer(element) + + def getDocument(self): + if fullTree: + return self.document._element + else: + if self.defaultNamespace is not None: + return self.document._element.find( + "{%s}html" % self.defaultNamespace) + else: + return self.document._element.find("html") + + def getFragment(self): + return base.TreeBuilder.getFragment(self)._element + + return locals() + + +getETreeModule = moduleFactoryFactory(getETreeBuilder) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py new file mode 100644 index 0000000..ca12a99 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py @@ -0,0 +1,366 @@ +"""Module for supporting the lxml.etree library. The idea here is to use as much +of the native library as possible, without using fragile hacks like custom element +names that break between releases. The downside of this is that we cannot represent +all possible trees; specifically the following are known to cause problems: + +Text or comments as siblings of the root element +Docypes with no name + +When any of these things occur, we emit a DataLossWarning +""" + +from __future__ import absolute_import, division, unicode_literals +# pylint:disable=protected-access + +import warnings +import re +import sys + +from . import base +from ..constants import DataLossWarning +from .. import constants +from . import etree as etree_builders +from .. import _ihatexml + +import lxml.etree as etree + + +fullTree = True +tag_regexp = re.compile("{([^}]*)}(.*)") + +comment_type = etree.Comment("asd").tag + + +class DocumentType(object): + def __init__(self, name, publicId, systemId): + self.name = name + self.publicId = publicId + self.systemId = systemId + + +class Document(object): + def __init__(self): + self._elementTree = None + self._childNodes = [] + + def appendChild(self, element): + self._elementTree.getroot().addnext(element._element) + + def _getChildNodes(self): + return self._childNodes + + childNodes = property(_getChildNodes) + + +def testSerializer(element): + rv = [] + infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True) + + def serializeElement(element, indent=0): + if not hasattr(element, "tag"): + if hasattr(element, "getroot"): + # Full tree case + rv.append("#document") + if element.docinfo.internalDTD: + if not (element.docinfo.public_id or + element.docinfo.system_url): + dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name + else: + dtd_str = """<!DOCTYPE %s "%s" "%s">""" % ( + element.docinfo.root_name, + element.docinfo.public_id, + element.docinfo.system_url) + rv.append("|%s%s" % (' ' * (indent + 2), dtd_str)) + next_element = element.getroot() + while next_element.getprevious() is not None: + next_element = next_element.getprevious() + while next_element is not None: + serializeElement(next_element, indent + 2) + next_element = next_element.getnext() + elif isinstance(element, str) or isinstance(element, bytes): + # Text in a fragment + assert isinstance(element, str) or sys.version_info[0] == 2 + rv.append("|%s\"%s\"" % (' ' * indent, element)) + else: + # Fragment case + rv.append("#document-fragment") + for next_element in element: + serializeElement(next_element, indent + 2) + elif element.tag == comment_type: + rv.append("|%s<!-- %s -->" % (' ' * indent, element.text)) + if hasattr(element, "tail") and element.tail: + rv.append("|%s\"%s\"" % (' ' * indent, element.tail)) + else: + assert isinstance(element, etree._Element) + nsmatch = etree_builders.tag_regexp.match(element.tag) + if nsmatch is not None: + ns = nsmatch.group(1) + tag = nsmatch.group(2) + prefix = constants.prefixes[ns] + rv.append("|%s<%s %s>" % (' ' * indent, prefix, + infosetFilter.fromXmlName(tag))) + else: + rv.append("|%s<%s>" % (' ' * indent, + infosetFilter.fromXmlName(element.tag))) + + if hasattr(element, "attrib"): + attributes = [] + for name, value in element.attrib.items(): + nsmatch = tag_regexp.match(name) + if nsmatch is not None: + ns, name = nsmatch.groups() + name = infosetFilter.fromXmlName(name) + prefix = constants.prefixes[ns] + attr_string = "%s %s" % (prefix, name) + else: + attr_string = infosetFilter.fromXmlName(name) + attributes.append((attr_string, value)) + + for name, value in sorted(attributes): + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) + + if element.text: + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) + indent += 2 + for child in element: + serializeElement(child, indent) + if hasattr(element, "tail") and element.tail: + rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail)) + serializeElement(element, 0) + + return "\n".join(rv) + + +def tostring(element): + """Serialize an element and its child nodes to a string""" + rv = [] + + def serializeElement(element): + if not hasattr(element, "tag"): + if element.docinfo.internalDTD: + if element.docinfo.doctype: + dtd_str = element.docinfo.doctype + else: + dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name + rv.append(dtd_str) + serializeElement(element.getroot()) + + elif element.tag == comment_type: + rv.append("<!--%s-->" % (element.text,)) + + else: + # This is assumed to be an ordinary element + if not element.attrib: + rv.append("<%s>" % (element.tag,)) + else: + attr = " ".join(["%s=\"%s\"" % (name, value) + for name, value in element.attrib.items()]) + rv.append("<%s %s>" % (element.tag, attr)) + if element.text: + rv.append(element.text) + + for child in element: + serializeElement(child) + + rv.append("</%s>" % (element.tag,)) + + if hasattr(element, "tail") and element.tail: + rv.append(element.tail) + + serializeElement(element) + + return "".join(rv) + + +class TreeBuilder(base.TreeBuilder): + documentClass = Document + doctypeClass = DocumentType + elementClass = None + commentClass = None + fragmentClass = Document + implementation = etree + + def __init__(self, namespaceHTMLElements, fullTree=False): + builder = etree_builders.getETreeModule(etree, fullTree=fullTree) + infosetFilter = self.infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True) + self.namespaceHTMLElements = namespaceHTMLElements + + class Attributes(dict): + def __init__(self, element, value=None): + if value is None: + value = {} + self._element = element + dict.__init__(self, value) # pylint:disable=non-parent-init-called + for key, value in self.items(): + if isinstance(key, tuple): + name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1])) + else: + name = infosetFilter.coerceAttribute(key) + self._element._element.attrib[name] = value + + def __setitem__(self, key, value): + dict.__setitem__(self, key, value) + if isinstance(key, tuple): + name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1])) + else: + name = infosetFilter.coerceAttribute(key) + self._element._element.attrib[name] = value + + class Element(builder.Element): + def __init__(self, name, namespace): + name = infosetFilter.coerceElement(name) + builder.Element.__init__(self, name, namespace=namespace) + self._attributes = Attributes(self) + + def _setName(self, name): + self._name = infosetFilter.coerceElement(name) + self._element.tag = self._getETreeTag( + self._name, self._namespace) + + def _getName(self): + return infosetFilter.fromXmlName(self._name) + + name = property(_getName, _setName) + + def _getAttributes(self): + return self._attributes + + def _setAttributes(self, attributes): + self._attributes = Attributes(self, attributes) + + attributes = property(_getAttributes, _setAttributes) + + def insertText(self, data, insertBefore=None): + data = infosetFilter.coerceCharacters(data) + builder.Element.insertText(self, data, insertBefore) + + def appendChild(self, child): + builder.Element.appendChild(self, child) + + class Comment(builder.Comment): + def __init__(self, data): + data = infosetFilter.coerceComment(data) + builder.Comment.__init__(self, data) + + def _setData(self, data): + data = infosetFilter.coerceComment(data) + self._element.text = data + + def _getData(self): + return self._element.text + + data = property(_getData, _setData) + + self.elementClass = Element + self.commentClass = Comment + # self.fragmentClass = builder.DocumentFragment + base.TreeBuilder.__init__(self, namespaceHTMLElements) + + def reset(self): + base.TreeBuilder.reset(self) + self.insertComment = self.insertCommentInitial + self.initial_comments = [] + self.doctype = None + + def testSerializer(self, element): + return testSerializer(element) + + def getDocument(self): + if fullTree: + return self.document._elementTree + else: + return self.document._elementTree.getroot() + + def getFragment(self): + fragment = [] + element = self.openElements[0]._element + if element.text: + fragment.append(element.text) + fragment.extend(list(element)) + if element.tail: + fragment.append(element.tail) + return fragment + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + if not name: + warnings.warn("lxml cannot represent empty doctype", DataLossWarning) + self.doctype = None + else: + coercedName = self.infosetFilter.coerceElement(name) + if coercedName != name: + warnings.warn("lxml cannot represent non-xml doctype", DataLossWarning) + + doctype = self.doctypeClass(coercedName, publicId, systemId) + self.doctype = doctype + + def insertCommentInitial(self, data, parent=None): + assert parent is None or parent is self.document + assert self.document._elementTree is None + self.initial_comments.append(data) + + def insertCommentMain(self, data, parent=None): + if (parent == self.document and + self.document._elementTree.getroot()[-1].tag == comment_type): + warnings.warn("lxml cannot represent adjacent comments beyond the root elements", DataLossWarning) + super(TreeBuilder, self).insertComment(data, parent) + + def insertRoot(self, token): + # Because of the way libxml2 works, it doesn't seem to be possible to + # alter information like the doctype after the tree has been parsed. + # Therefore we need to use the built-in parser to create our initial + # tree, after which we can add elements like normal + docStr = "" + if self.doctype: + assert self.doctype.name + docStr += "<!DOCTYPE %s" % self.doctype.name + if (self.doctype.publicId is not None or + self.doctype.systemId is not None): + docStr += (' PUBLIC "%s" ' % + (self.infosetFilter.coercePubid(self.doctype.publicId or ""))) + if self.doctype.systemId: + sysid = self.doctype.systemId + if sysid.find("'") >= 0 and sysid.find('"') >= 0: + warnings.warn("DOCTYPE system cannot contain single and double quotes", DataLossWarning) + sysid = sysid.replace("'", 'U00027') + if sysid.find("'") >= 0: + docStr += '"%s"' % sysid + else: + docStr += "'%s'" % sysid + else: + docStr += "''" + docStr += ">" + if self.doctype.name != token["name"]: + warnings.warn("lxml cannot represent doctype with a different name to the root element", DataLossWarning) + docStr += "<THIS_SHOULD_NEVER_APPEAR_PUBLICLY/>" + root = etree.fromstring(docStr) + + # Append the initial comments: + for comment_token in self.initial_comments: + comment = self.commentClass(comment_token["data"]) + root.addprevious(comment._element) + + # Create the root document and add the ElementTree to it + self.document = self.documentClass() + self.document._elementTree = root.getroottree() + + # Give the root element the right name + name = token["name"] + namespace = token.get("namespace", self.defaultNamespace) + if namespace is None: + etree_tag = name + else: + etree_tag = "{%s}%s" % (namespace, name) + root.tag = etree_tag + + # Add the root element to the internal child/open data structures + root_element = self.elementClass(name, namespace) + root_element._element = root + self.document._childNodes.append(root_element) + self.openElements.append(root_element) + + # Reset to the default insert comment function + self.insertComment = self.insertCommentMain diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/__init__.py new file mode 100644 index 0000000..9bec207 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/__init__.py @@ -0,0 +1,154 @@ +"""A collection of modules for iterating through different kinds of +tree, generating tokens identical to those produced by the tokenizer +module. + +To create a tree walker for a new type of tree, you need to do +implement a tree walker object (called TreeWalker by convention) that +implements a 'serialize' method taking a tree as sole argument and +returning an iterator generating tokens. +""" + +from __future__ import absolute_import, division, unicode_literals + +from .. import constants +from .._utils import default_etree + +__all__ = ["getTreeWalker", "pprint"] + +treeWalkerCache = {} + + +def getTreeWalker(treeType, implementation=None, **kwargs): + """Get a TreeWalker class for various types of tree with built-in support + + :arg str treeType: the name of the tree type required (case-insensitive). + Supported values are: + + * "dom": The xml.dom.minidom DOM implementation + * "etree": A generic walker for tree implementations exposing an + elementtree-like interface (known to work with ElementTree, + cElementTree and lxml.etree). + * "lxml": Optimized walker for lxml.etree + * "genshi": a Genshi stream + + :arg implementation: A module implementing the tree type e.g. + xml.etree.ElementTree or cElementTree (Currently applies to the "etree" + tree type only). + + :arg kwargs: keyword arguments passed to the etree walker--for other + walkers, this has no effect + + :returns: a TreeWalker class + + """ + + treeType = treeType.lower() + if treeType not in treeWalkerCache: + if treeType == "dom": + from . import dom + treeWalkerCache[treeType] = dom.TreeWalker + elif treeType == "genshi": + from . import genshi + treeWalkerCache[treeType] = genshi.TreeWalker + elif treeType == "lxml": + from . import etree_lxml + treeWalkerCache[treeType] = etree_lxml.TreeWalker + elif treeType == "etree": + from . import etree + if implementation is None: + implementation = default_etree + # XXX: NEVER cache here, caching is done in the etree submodule + return etree.getETreeModule(implementation, **kwargs).TreeWalker + return treeWalkerCache.get(treeType) + + +def concatenateCharacterTokens(tokens): + pendingCharacters = [] + for token in tokens: + type = token["type"] + if type in ("Characters", "SpaceCharacters"): + pendingCharacters.append(token["data"]) + else: + if pendingCharacters: + yield {"type": "Characters", "data": "".join(pendingCharacters)} + pendingCharacters = [] + yield token + if pendingCharacters: + yield {"type": "Characters", "data": "".join(pendingCharacters)} + + +def pprint(walker): + """Pretty printer for tree walkers + + Takes a TreeWalker instance and pretty prints the output of walking the tree. + + :arg walker: a TreeWalker instance + + """ + output = [] + indent = 0 + for token in concatenateCharacterTokens(walker): + type = token["type"] + if type in ("StartTag", "EmptyTag"): + # tag name + if token["namespace"] and token["namespace"] != constants.namespaces["html"]: + if token["namespace"] in constants.prefixes: + ns = constants.prefixes[token["namespace"]] + else: + ns = token["namespace"] + name = "%s %s" % (ns, token["name"]) + else: + name = token["name"] + output.append("%s<%s>" % (" " * indent, name)) + indent += 2 + # attributes (sorted for consistent ordering) + attrs = token["data"] + for (namespace, localname), value in sorted(attrs.items()): + if namespace: + if namespace in constants.prefixes: + ns = constants.prefixes[namespace] + else: + ns = namespace + name = "%s %s" % (ns, localname) + else: + name = localname + output.append("%s%s=\"%s\"" % (" " * indent, name, value)) + # self-closing + if type == "EmptyTag": + indent -= 2 + + elif type == "EndTag": + indent -= 2 + + elif type == "Comment": + output.append("%s<!-- %s -->" % (" " * indent, token["data"])) + + elif type == "Doctype": + if token["name"]: + if token["publicId"]: + output.append("""%s<!DOCTYPE %s "%s" "%s">""" % + (" " * indent, + token["name"], + token["publicId"], + token["systemId"] if token["systemId"] else "")) + elif token["systemId"]: + output.append("""%s<!DOCTYPE %s "" "%s">""" % + (" " * indent, + token["name"], + token["systemId"])) + else: + output.append("%s<!DOCTYPE %s>" % (" " * indent, + token["name"])) + else: + output.append("%s<!DOCTYPE >" % (" " * indent,)) + + elif type == "Characters": + output.append("%s\"%s\"" % (" " * indent, token["data"])) + + elif type == "SpaceCharacters": + assert False, "concatenateCharacterTokens should have got rid of all Space tokens" + + else: + raise ValueError("Unknown token type, %s" % type) + + return "\n".join(output) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/base.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/base.py new file mode 100644 index 0000000..80c474c --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/base.py @@ -0,0 +1,252 @@ +from __future__ import absolute_import, division, unicode_literals + +from xml.dom import Node +from ..constants import namespaces, voidElements, spaceCharacters + +__all__ = ["DOCUMENT", "DOCTYPE", "TEXT", "ELEMENT", "COMMENT", "ENTITY", "UNKNOWN", + "TreeWalker", "NonRecursiveTreeWalker"] + +DOCUMENT = Node.DOCUMENT_NODE +DOCTYPE = Node.DOCUMENT_TYPE_NODE +TEXT = Node.TEXT_NODE +ELEMENT = Node.ELEMENT_NODE +COMMENT = Node.COMMENT_NODE +ENTITY = Node.ENTITY_NODE +UNKNOWN = "<#UNKNOWN#>" + +spaceCharacters = "".join(spaceCharacters) + + +class TreeWalker(object): + """Walks a tree yielding tokens + + Tokens are dicts that all have a ``type`` field specifying the type of the + token. + + """ + def __init__(self, tree): + """Creates a TreeWalker + + :arg tree: the tree to walk + + """ + self.tree = tree + + def __iter__(self): + raise NotImplementedError + + def error(self, msg): + """Generates an error token with the given message + + :arg msg: the error message + + :returns: SerializeError token + + """ + return {"type": "SerializeError", "data": msg} + + def emptyTag(self, namespace, name, attrs, hasChildren=False): + """Generates an EmptyTag token + + :arg namespace: the namespace of the token--can be ``None`` + + :arg name: the name of the element + + :arg attrs: the attributes of the element as a dict + + :arg hasChildren: whether or not to yield a SerializationError because + this tag shouldn't have children + + :returns: EmptyTag token + + """ + yield {"type": "EmptyTag", "name": name, + "namespace": namespace, + "data": attrs} + if hasChildren: + yield self.error("Void element has children") + + def startTag(self, namespace, name, attrs): + """Generates a StartTag token + + :arg namespace: the namespace of the token--can be ``None`` + + :arg name: the name of the element + + :arg attrs: the attributes of the element as a dict + + :returns: StartTag token + + """ + return {"type": "StartTag", + "name": name, + "namespace": namespace, + "data": attrs} + + def endTag(self, namespace, name): + """Generates an EndTag token + + :arg namespace: the namespace of the token--can be ``None`` + + :arg name: the name of the element + + :returns: EndTag token + + """ + return {"type": "EndTag", + "name": name, + "namespace": namespace} + + def text(self, data): + """Generates SpaceCharacters and Characters tokens + + Depending on what's in the data, this generates one or more + ``SpaceCharacters`` and ``Characters`` tokens. + + For example: + + >>> from html5lib.treewalkers.base import TreeWalker + >>> # Give it an empty tree just so it instantiates + >>> walker = TreeWalker([]) + >>> list(walker.text('')) + [] + >>> list(walker.text(' ')) + [{u'data': ' ', u'type': u'SpaceCharacters'}] + >>> list(walker.text(' abc ')) # doctest: +NORMALIZE_WHITESPACE + [{u'data': ' ', u'type': u'SpaceCharacters'}, + {u'data': u'abc', u'type': u'Characters'}, + {u'data': u' ', u'type': u'SpaceCharacters'}] + + :arg data: the text data + + :returns: one or more ``SpaceCharacters`` and ``Characters`` tokens + + """ + data = data + middle = data.lstrip(spaceCharacters) + left = data[:len(data) - len(middle)] + if left: + yield {"type": "SpaceCharacters", "data": left} + data = middle + middle = data.rstrip(spaceCharacters) + right = data[len(middle):] + if middle: + yield {"type": "Characters", "data": middle} + if right: + yield {"type": "SpaceCharacters", "data": right} + + def comment(self, data): + """Generates a Comment token + + :arg data: the comment + + :returns: Comment token + + """ + return {"type": "Comment", "data": data} + + def doctype(self, name, publicId=None, systemId=None): + """Generates a Doctype token + + :arg name: + + :arg publicId: + + :arg systemId: + + :returns: the Doctype token + + """ + return {"type": "Doctype", + "name": name, + "publicId": publicId, + "systemId": systemId} + + def entity(self, name): + """Generates an Entity token + + :arg name: the entity name + + :returns: an Entity token + + """ + return {"type": "Entity", "name": name} + + def unknown(self, nodeType): + """Handles unknown node types""" + return self.error("Unknown node type: " + nodeType) + + +class NonRecursiveTreeWalker(TreeWalker): + def getNodeDetails(self, node): + raise NotImplementedError + + def getFirstChild(self, node): + raise NotImplementedError + + def getNextSibling(self, node): + raise NotImplementedError + + def getParentNode(self, node): + raise NotImplementedError + + def __iter__(self): + currentNode = self.tree + while currentNode is not None: + details = self.getNodeDetails(currentNode) + type, details = details[0], details[1:] + hasChildren = False + + if type == DOCTYPE: + yield self.doctype(*details) + + elif type == TEXT: + for token in self.text(*details): + yield token + + elif type == ELEMENT: + namespace, name, attributes, hasChildren = details + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + for token in self.emptyTag(namespace, name, attributes, + hasChildren): + yield token + hasChildren = False + else: + yield self.startTag(namespace, name, attributes) + + elif type == COMMENT: + yield self.comment(details[0]) + + elif type == ENTITY: + yield self.entity(details[0]) + + elif type == DOCUMENT: + hasChildren = True + + else: + yield self.unknown(details[0]) + + if hasChildren: + firstChild = self.getFirstChild(currentNode) + else: + firstChild = None + + if firstChild is not None: + currentNode = firstChild + else: + while currentNode is not None: + details = self.getNodeDetails(currentNode) + type, details = details[0], details[1:] + if type == ELEMENT: + namespace, name, attributes, hasChildren = details + if (namespace and namespace != namespaces["html"]) or name not in voidElements: + yield self.endTag(namespace, name) + if self.tree is currentNode: + currentNode = None + break + nextSibling = self.getNextSibling(currentNode) + if nextSibling is not None: + currentNode = nextSibling + break + else: + currentNode = self.getParentNode(currentNode) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/dom.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/dom.py new file mode 100644 index 0000000..b0c89b0 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/dom.py @@ -0,0 +1,43 @@ +from __future__ import absolute_import, division, unicode_literals + +from xml.dom import Node + +from . import base + + +class TreeWalker(base.NonRecursiveTreeWalker): + def getNodeDetails(self, node): + if node.nodeType == Node.DOCUMENT_TYPE_NODE: + return base.DOCTYPE, node.name, node.publicId, node.systemId + + elif node.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE): + return base.TEXT, node.nodeValue + + elif node.nodeType == Node.ELEMENT_NODE: + attrs = {} + for attr in list(node.attributes.keys()): + attr = node.getAttributeNode(attr) + if attr.namespaceURI: + attrs[(attr.namespaceURI, attr.localName)] = attr.value + else: + attrs[(None, attr.name)] = attr.value + return (base.ELEMENT, node.namespaceURI, node.nodeName, + attrs, node.hasChildNodes()) + + elif node.nodeType == Node.COMMENT_NODE: + return base.COMMENT, node.nodeValue + + elif node.nodeType in (Node.DOCUMENT_NODE, Node.DOCUMENT_FRAGMENT_NODE): + return (base.DOCUMENT,) + + else: + return base.UNKNOWN, node.nodeType + + def getFirstChild(self, node): + return node.firstChild + + def getNextSibling(self, node): + return node.nextSibling + + def getParentNode(self, node): + return node.parentNode diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree.py new file mode 100644 index 0000000..95fc0c1 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree.py @@ -0,0 +1,130 @@ +from __future__ import absolute_import, division, unicode_literals + +from collections import OrderedDict +import re + +from pip._vendor.six import string_types + +from . import base +from .._utils import moduleFactoryFactory + +tag_regexp = re.compile("{([^}]*)}(.*)") + + +def getETreeBuilder(ElementTreeImplementation): + ElementTree = ElementTreeImplementation + ElementTreeCommentType = ElementTree.Comment("asd").tag + + class TreeWalker(base.NonRecursiveTreeWalker): # pylint:disable=unused-variable + """Given the particular ElementTree representation, this implementation, + to avoid using recursion, returns "nodes" as tuples with the following + content: + + 1. The current element + + 2. The index of the element relative to its parent + + 3. A stack of ancestor elements + + 4. A flag "text", "tail" or None to indicate if the current node is a + text node; either the text or tail of the current element (1) + """ + def getNodeDetails(self, node): + if isinstance(node, tuple): # It might be the root Element + elt, _, _, flag = node + if flag in ("text", "tail"): + return base.TEXT, getattr(elt, flag) + else: + node = elt + + if not(hasattr(node, "tag")): + node = node.getroot() + + if node.tag in ("DOCUMENT_ROOT", "DOCUMENT_FRAGMENT"): + return (base.DOCUMENT,) + + elif node.tag == "<!DOCTYPE>": + return (base.DOCTYPE, node.text, + node.get("publicId"), node.get("systemId")) + + elif node.tag == ElementTreeCommentType: + return base.COMMENT, node.text + + else: + assert isinstance(node.tag, string_types), type(node.tag) + # This is assumed to be an ordinary element + match = tag_regexp.match(node.tag) + if match: + namespace, tag = match.groups() + else: + namespace = None + tag = node.tag + attrs = OrderedDict() + for name, value in list(node.attrib.items()): + match = tag_regexp.match(name) + if match: + attrs[(match.group(1), match.group(2))] = value + else: + attrs[(None, name)] = value + return (base.ELEMENT, namespace, tag, + attrs, len(node) or node.text) + + def getFirstChild(self, node): + if isinstance(node, tuple): + element, key, parents, flag = node + else: + element, key, parents, flag = node, None, [], None + + if flag in ("text", "tail"): + return None + else: + if element.text: + return element, key, parents, "text" + elif len(element): + parents.append(element) + return element[0], 0, parents, None + else: + return None + + def getNextSibling(self, node): + if isinstance(node, tuple): + element, key, parents, flag = node + else: + return None + + if flag == "text": + if len(element): + parents.append(element) + return element[0], 0, parents, None + else: + return None + else: + if element.tail and flag != "tail": + return element, key, parents, "tail" + elif key < len(parents[-1]) - 1: + return parents[-1][key + 1], key + 1, parents, None + else: + return None + + def getParentNode(self, node): + if isinstance(node, tuple): + element, key, parents, flag = node + else: + return None + + if flag == "text": + if not parents: + return element + else: + return element, key, parents, None + else: + parent = parents.pop() + if not parents: + return parent + else: + assert list(parents[-1]).count(parent) == 1 + return parent, list(parents[-1]).index(parent), parents, None + + return locals() + +getETreeModule = moduleFactoryFactory(getETreeBuilder) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree_lxml.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree_lxml.py new file mode 100644 index 0000000..e81ddf3 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree_lxml.py @@ -0,0 +1,213 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from lxml import etree +from ..treebuilders.etree import tag_regexp + +from . import base + +from .. import _ihatexml + + +def ensure_str(s): + if s is None: + return None + elif isinstance(s, text_type): + return s + else: + return s.decode("ascii", "strict") + + +class Root(object): + def __init__(self, et): + self.elementtree = et + self.children = [] + + try: + if et.docinfo.internalDTD: + self.children.append(Doctype(self, + ensure_str(et.docinfo.root_name), + ensure_str(et.docinfo.public_id), + ensure_str(et.docinfo.system_url))) + except AttributeError: + pass + + try: + node = et.getroot() + except AttributeError: + node = et + + while node.getprevious() is not None: + node = node.getprevious() + while node is not None: + self.children.append(node) + node = node.getnext() + + self.text = None + self.tail = None + + def __getitem__(self, key): + return self.children[key] + + def getnext(self): + return None + + def __len__(self): + return 1 + + +class Doctype(object): + def __init__(self, root_node, name, public_id, system_id): + self.root_node = root_node + self.name = name + self.public_id = public_id + self.system_id = system_id + + self.text = None + self.tail = None + + def getnext(self): + return self.root_node.children[1] + + +class FragmentRoot(Root): + def __init__(self, children): + self.children = [FragmentWrapper(self, child) for child in children] + self.text = self.tail = None + + def getnext(self): + return None + + +class FragmentWrapper(object): + def __init__(self, fragment_root, obj): + self.root_node = fragment_root + self.obj = obj + if hasattr(self.obj, 'text'): + self.text = ensure_str(self.obj.text) + else: + self.text = None + if hasattr(self.obj, 'tail'): + self.tail = ensure_str(self.obj.tail) + else: + self.tail = None + + def __getattr__(self, name): + return getattr(self.obj, name) + + def getnext(self): + siblings = self.root_node.children + idx = siblings.index(self) + if idx < len(siblings) - 1: + return siblings[idx + 1] + else: + return None + + def __getitem__(self, key): + return self.obj[key] + + def __bool__(self): + return bool(self.obj) + + def getparent(self): + return None + + def __str__(self): + return str(self.obj) + + def __unicode__(self): + return str(self.obj) + + def __len__(self): + return len(self.obj) + + +class TreeWalker(base.NonRecursiveTreeWalker): + def __init__(self, tree): + # pylint:disable=redefined-variable-type + if isinstance(tree, list): + self.fragmentChildren = set(tree) + tree = FragmentRoot(tree) + else: + self.fragmentChildren = set() + tree = Root(tree) + base.NonRecursiveTreeWalker.__init__(self, tree) + self.filter = _ihatexml.InfosetFilter() + + def getNodeDetails(self, node): + if isinstance(node, tuple): # Text node + node, key = node + assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key + return base.TEXT, ensure_str(getattr(node, key)) + + elif isinstance(node, Root): + return (base.DOCUMENT,) + + elif isinstance(node, Doctype): + return base.DOCTYPE, node.name, node.public_id, node.system_id + + elif isinstance(node, FragmentWrapper) and not hasattr(node, "tag"): + return base.TEXT, ensure_str(node.obj) + + elif node.tag == etree.Comment: + return base.COMMENT, ensure_str(node.text) + + elif node.tag == etree.Entity: + return base.ENTITY, ensure_str(node.text)[1:-1] # strip &; + + else: + # This is assumed to be an ordinary element + match = tag_regexp.match(ensure_str(node.tag)) + if match: + namespace, tag = match.groups() + else: + namespace = None + tag = ensure_str(node.tag) + attrs = {} + for name, value in list(node.attrib.items()): + name = ensure_str(name) + value = ensure_str(value) + match = tag_regexp.match(name) + if match: + attrs[(match.group(1), match.group(2))] = value + else: + attrs[(None, name)] = value + return (base.ELEMENT, namespace, self.filter.fromXmlName(tag), + attrs, len(node) > 0 or node.text) + + def getFirstChild(self, node): + assert not isinstance(node, tuple), "Text nodes have no children" + + assert len(node) or node.text, "Node has no children" + if node.text: + return (node, "text") + else: + return node[0] + + def getNextSibling(self, node): + if isinstance(node, tuple): # Text node + node, key = node + assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key + if key == "text": + # XXX: we cannot use a "bool(node) and node[0] or None" construct here + # because node[0] might evaluate to False if it has no child element + if len(node): + return node[0] + else: + return None + else: # tail + return node.getnext() + + return (node, "tail") if node.tail else node.getnext() + + def getParentNode(self, node): + if isinstance(node, tuple): # Text node + node, key = node + assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key + if key == "text": + return node + # else: fallback to "normal" processing + elif node in self.fragmentChildren: + return None + + return node.getparent() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/genshi.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/genshi.py new file mode 100644 index 0000000..7483be2 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/genshi.py @@ -0,0 +1,69 @@ +from __future__ import absolute_import, division, unicode_literals + +from genshi.core import QName +from genshi.core import START, END, XML_NAMESPACE, DOCTYPE, TEXT +from genshi.core import START_NS, END_NS, START_CDATA, END_CDATA, PI, COMMENT + +from . import base + +from ..constants import voidElements, namespaces + + +class TreeWalker(base.TreeWalker): + def __iter__(self): + # Buffer the events so we can pass in the following one + previous = None + for event in self.tree: + if previous is not None: + for token in self.tokens(previous, event): + yield token + previous = event + + # Don't forget the final event! + if previous is not None: + for token in self.tokens(previous, None): + yield token + + def tokens(self, event, next): + kind, data, _ = event + if kind == START: + tag, attribs = data + name = tag.localname + namespace = tag.namespace + converted_attribs = {} + for k, v in attribs: + if isinstance(k, QName): + converted_attribs[(k.namespace, k.localname)] = v + else: + converted_attribs[(None, k)] = v + + if namespace == namespaces["html"] and name in voidElements: + for token in self.emptyTag(namespace, name, converted_attribs, + not next or next[0] != END or + next[1] != tag): + yield token + else: + yield self.startTag(namespace, name, converted_attribs) + + elif kind == END: + name = data.localname + namespace = data.namespace + if namespace != namespaces["html"] or name not in voidElements: + yield self.endTag(namespace, name) + + elif kind == COMMENT: + yield self.comment(data) + + elif kind == TEXT: + for token in self.text(data): + yield token + + elif kind == DOCTYPE: + yield self.doctype(*data) + + elif kind in (XML_NAMESPACE, DOCTYPE, START_NS, END_NS, + START_CDATA, END_CDATA, PI): + pass + + else: + yield self.unknown(kind) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__init__.py new file mode 100644 index 0000000..847bf93 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__init__.py @@ -0,0 +1,2 @@ +from .package_data import __version__ +from .core import * diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/codec.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/codec.py new file mode 100644 index 0000000..98c65ea --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/codec.py @@ -0,0 +1,118 @@ +from .core import encode, decode, alabel, ulabel, IDNAError +import codecs +import re + +_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') + +class Codec(codecs.Codec): + + def encode(self, data, errors='strict'): + + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return "", 0 + + return encode(data), len(data) + + def decode(self, data, errors='strict'): + + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return u"", 0 + + return decode(data), len(data) + +class IncrementalEncoder(codecs.BufferedIncrementalEncoder): + def _buffer_encode(self, data, errors, final): + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return ("", 0) + + labels = _unicode_dots_re.split(data) + trailing_dot = u'' + if labels: + if not labels[-1]: + trailing_dot = '.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = '.' + + result = [] + size = 0 + for label in labels: + result.append(alabel(label)) + if size: + size += 1 + size += len(label) + + # Join with U+002E + result = ".".join(result) + trailing_dot + size += len(trailing_dot) + return (result, size) + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def _buffer_decode(self, data, errors, final): + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return (u"", 0) + + # IDNA allows decoding to operate on Unicode strings, too. + if isinstance(data, unicode): + labels = _unicode_dots_re.split(data) + else: + # Must be ASCII string + data = str(data) + unicode(data, "ascii") + labels = data.split(".") + + trailing_dot = u'' + if labels: + if not labels[-1]: + trailing_dot = u'.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = u'.' + + result = [] + size = 0 + for label in labels: + result.append(ulabel(label)) + if size: + size += 1 + size += len(label) + + result = u".".join(result) + trailing_dot + size += len(trailing_dot) + return (result, size) + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + +class StreamReader(Codec, codecs.StreamReader): + pass + +def getregentry(): + return codecs.CodecInfo( + name='idna', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/compat.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/compat.py new file mode 100644 index 0000000..4d47f33 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/compat.py @@ -0,0 +1,12 @@ +from .core import * +from .codec import * + +def ToASCII(label): + return encode(label) + +def ToUnicode(label): + return decode(label) + +def nameprep(s): + raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol") + diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/core.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/core.py new file mode 100644 index 0000000..b55b664 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/core.py @@ -0,0 +1,387 @@ +from . import idnadata +import bisect +import unicodedata +import re +import sys +from .intranges import intranges_contain + +_virama_combining_class = 9 +_alabel_prefix = b'xn--' +_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') + +if sys.version_info[0] == 3: + unicode = str + unichr = chr + +class IDNAError(UnicodeError): + """ Base exception for all IDNA-encoding related problems """ + pass + + +class IDNABidiError(IDNAError): + """ Exception when bidirectional requirements are not satisfied """ + pass + + +class InvalidCodepoint(IDNAError): + """ Exception when a disallowed or unallocated codepoint is used """ + pass + + +class InvalidCodepointContext(IDNAError): + """ Exception when the codepoint is not valid in the context it is used """ + pass + + +def _combining_class(cp): + return unicodedata.combining(unichr(cp)) + +def _is_script(cp, script): + return intranges_contain(ord(cp), idnadata.scripts[script]) + +def _punycode(s): + return s.encode('punycode') + +def _unot(s): + return 'U+{0:04X}'.format(s) + + +def valid_label_length(label): + + if len(label) > 63: + return False + return True + + +def valid_string_length(label, trailing_dot): + + if len(label) > (254 if trailing_dot else 253): + return False + return True + + +def check_bidi(label, check_ltr=False): + + # Bidi rules should only be applied if string contains RTL characters + bidi_label = False + for (idx, cp) in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + if direction == '': + # String likely comes from a newer version of Unicode + raise IDNABidiError('Unknown directionality in label {0} at position {1}'.format(repr(label), idx)) + if direction in ['R', 'AL', 'AN']: + bidi_label = True + break + if not bidi_label and not check_ltr: + return True + + # Bidi rule 1 + direction = unicodedata.bidirectional(label[0]) + if direction in ['R', 'AL']: + rtl = True + elif direction == 'L': + rtl = False + else: + raise IDNABidiError('First codepoint in label {0} must be directionality L, R or AL'.format(repr(label))) + + valid_ending = False + number_type = False + for (idx, cp) in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + + if rtl: + # Bidi rule 2 + if not direction in ['R', 'AL', 'AN', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: + raise IDNABidiError('Invalid direction for codepoint at position {0} in a right-to-left label'.format(idx)) + # Bidi rule 3 + if direction in ['R', 'AL', 'EN', 'AN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + # Bidi rule 4 + if direction in ['AN', 'EN']: + if not number_type: + number_type = direction + else: + if number_type != direction: + raise IDNABidiError('Can not mix numeral types in a right-to-left label') + else: + # Bidi rule 5 + if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: + raise IDNABidiError('Invalid direction for codepoint at position {0} in a left-to-right label'.format(idx)) + # Bidi rule 6 + if direction in ['L', 'EN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + + if not valid_ending: + raise IDNABidiError('Label ends with illegal codepoint directionality') + + return True + + +def check_initial_combiner(label): + + if unicodedata.category(label[0])[0] == 'M': + raise IDNAError('Label begins with an illegal combining character') + return True + + +def check_hyphen_ok(label): + + if label[2:4] == '--': + raise IDNAError('Label has disallowed hyphens in 3rd and 4th position') + if label[0] == '-' or label[-1] == '-': + raise IDNAError('Label must not start or end with a hyphen') + return True + + +def check_nfc(label): + + if unicodedata.normalize('NFC', label) != label: + raise IDNAError('Label must be in Normalization Form C') + + +def valid_contextj(label, pos): + + cp_value = ord(label[pos]) + + if cp_value == 0x200c: + + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + + ok = False + for i in range(pos-1, -1, -1): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('L'), ord('D')]: + ok = True + break + + if not ok: + return False + + ok = False + for i in range(pos+1, len(label)): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('R'), ord('D')]: + ok = True + break + return ok + + if cp_value == 0x200d: + + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + return False + + else: + + return False + + +def valid_contexto(label, pos, exception=False): + + cp_value = ord(label[pos]) + + if cp_value == 0x00b7: + if 0 < pos < len(label)-1: + if ord(label[pos - 1]) == 0x006c and ord(label[pos + 1]) == 0x006c: + return True + return False + + elif cp_value == 0x0375: + if pos < len(label)-1 and len(label) > 1: + return _is_script(label[pos + 1], 'Greek') + return False + + elif cp_value == 0x05f3 or cp_value == 0x05f4: + if pos > 0: + return _is_script(label[pos - 1], 'Hebrew') + return False + + elif cp_value == 0x30fb: + for cp in label: + if cp == u'\u30fb': + continue + if _is_script(cp, 'Hiragana') or _is_script(cp, 'Katakana') or _is_script(cp, 'Han'): + return True + return False + + elif 0x660 <= cp_value <= 0x669: + for cp in label: + if 0x6f0 <= ord(cp) <= 0x06f9: + return False + return True + + elif 0x6f0 <= cp_value <= 0x6f9: + for cp in label: + if 0x660 <= ord(cp) <= 0x0669: + return False + return True + + +def check_label(label): + + if isinstance(label, (bytes, bytearray)): + label = label.decode('utf-8') + if len(label) == 0: + raise IDNAError('Empty Label') + + check_nfc(label) + check_hyphen_ok(label) + check_initial_combiner(label) + + for (pos, cp) in enumerate(label): + cp_value = ord(cp) + if intranges_contain(cp_value, idnadata.codepoint_classes['PVALID']): + continue + elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']): + if not valid_contextj(label, pos): + raise InvalidCodepointContext('Joiner {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label))) + elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']): + if not valid_contexto(label, pos): + raise InvalidCodepointContext('Codepoint {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label))) + else: + raise InvalidCodepoint('Codepoint {0} at position {1} of {2} not allowed'.format(_unot(cp_value), pos+1, repr(label))) + + check_bidi(label) + + +def alabel(label): + + try: + label = label.encode('ascii') + try: + ulabel(label) + except IDNAError: + raise IDNAError('The label {0} is not a valid A-label'.format(label)) + if not valid_label_length(label): + raise IDNAError('Label too long') + return label + except UnicodeEncodeError: + pass + + if not label: + raise IDNAError('No Input') + + label = unicode(label) + check_label(label) + label = _punycode(label) + label = _alabel_prefix + label + + if not valid_label_length(label): + raise IDNAError('Label too long') + + return label + + +def ulabel(label): + + if not isinstance(label, (bytes, bytearray)): + try: + label = label.encode('ascii') + except UnicodeEncodeError: + check_label(label) + return label + + label = label.lower() + if label.startswith(_alabel_prefix): + label = label[len(_alabel_prefix):] + else: + check_label(label) + return label.decode('ascii') + + label = label.decode('punycode') + check_label(label) + return label + + +def uts46_remap(domain, std3_rules=True, transitional=False): + """Re-map the characters in the string according to UTS46 processing.""" + from .uts46data import uts46data + output = u"" + try: + for pos, char in enumerate(domain): + code_point = ord(char) + uts46row = uts46data[code_point if code_point < 256 else + bisect.bisect_left(uts46data, (code_point, "Z")) - 1] + status = uts46row[1] + replacement = uts46row[2] if len(uts46row) == 3 else None + if (status == "V" or + (status == "D" and not transitional) or + (status == "3" and std3_rules and replacement is None)): + output += char + elif replacement is not None and (status == "M" or + (status == "3" and std3_rules) or + (status == "D" and transitional)): + output += replacement + elif status != "I": + raise IndexError() + return unicodedata.normalize("NFC", output) + except IndexError: + raise InvalidCodepoint( + "Codepoint {0} not allowed at position {1} in {2}".format( + _unot(code_point), pos + 1, repr(domain))) + + +def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False): + + if isinstance(s, (bytes, bytearray)): + s = s.decode("ascii") + if uts46: + s = uts46_remap(s, std3_rules, transitional) + trailing_dot = False + result = [] + if strict: + labels = s.split('.') + else: + labels = _unicode_dots_re.split(s) + while labels and not labels[0]: + del labels[0] + if not labels: + raise IDNAError('Empty domain') + if labels[-1] == '': + del labels[-1] + trailing_dot = True + for label in labels: + result.append(alabel(label)) + if trailing_dot: + result.append(b'') + s = b'.'.join(result) + if not valid_string_length(s, trailing_dot): + raise IDNAError('Domain too long') + return s + + +def decode(s, strict=False, uts46=False, std3_rules=False): + + if isinstance(s, (bytes, bytearray)): + s = s.decode("ascii") + if uts46: + s = uts46_remap(s, std3_rules, False) + trailing_dot = False + result = [] + if not strict: + labels = _unicode_dots_re.split(s) + else: + labels = s.split(u'.') + while labels and not labels[0]: + del labels[0] + if not labels: + raise IDNAError('Empty domain') + if not labels[-1]: + del labels[-1] + trailing_dot = True + for label in labels: + result.append(ulabel(label)) + if trailing_dot: + result.append(u'') + return u'.'.join(result) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/idnadata.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/idnadata.py new file mode 100644 index 0000000..c48f1b5 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/idnadata.py @@ -0,0 +1,1585 @@ +# This file is automatically generated by tools/idna-data + +__version__ = "6.3.0" +scripts = { + 'Greek': ( + 0x37000000374, + 0x37500000378, + 0x37a0000037e, + 0x38400000385, + 0x38600000387, + 0x3880000038b, + 0x38c0000038d, + 0x38e000003a2, + 0x3a3000003e2, + 0x3f000000400, + 0x1d2600001d2b, + 0x1d5d00001d62, + 0x1d6600001d6b, + 0x1dbf00001dc0, + 0x1f0000001f16, + 0x1f1800001f1e, + 0x1f2000001f46, + 0x1f4800001f4e, + 0x1f5000001f58, + 0x1f5900001f5a, + 0x1f5b00001f5c, + 0x1f5d00001f5e, + 0x1f5f00001f7e, + 0x1f8000001fb5, + 0x1fb600001fc5, + 0x1fc600001fd4, + 0x1fd600001fdc, + 0x1fdd00001ff0, + 0x1ff200001ff5, + 0x1ff600001fff, + 0x212600002127, + 0x101400001018b, + 0x1d2000001d246, + ), + 'Han': ( + 0x2e8000002e9a, + 0x2e9b00002ef4, + 0x2f0000002fd6, + 0x300500003006, + 0x300700003008, + 0x30210000302a, + 0x30380000303c, + 0x340000004db6, + 0x4e0000009fcd, + 0xf9000000fa6e, + 0xfa700000fada, + 0x200000002a6d7, + 0x2a7000002b735, + 0x2b7400002b81e, + 0x2f8000002fa1e, + ), + 'Hebrew': ( + 0x591000005c8, + 0x5d0000005eb, + 0x5f0000005f5, + 0xfb1d0000fb37, + 0xfb380000fb3d, + 0xfb3e0000fb3f, + 0xfb400000fb42, + 0xfb430000fb45, + 0xfb460000fb50, + ), + 'Hiragana': ( + 0x304100003097, + 0x309d000030a0, + 0x1b0010001b002, + 0x1f2000001f201, + ), + 'Katakana': ( + 0x30a1000030fb, + 0x30fd00003100, + 0x31f000003200, + 0x32d0000032ff, + 0x330000003358, + 0xff660000ff70, + 0xff710000ff9e, + 0x1b0000001b001, + ), +} +joining_types = { + 0x600: 85, + 0x601: 85, + 0x602: 85, + 0x603: 85, + 0x604: 85, + 0x608: 85, + 0x60b: 85, + 0x620: 68, + 0x621: 85, + 0x622: 82, + 0x623: 82, + 0x624: 82, + 0x625: 82, + 0x626: 68, + 0x627: 82, + 0x628: 68, + 0x629: 82, + 0x62a: 68, + 0x62b: 68, + 0x62c: 68, + 0x62d: 68, + 0x62e: 68, + 0x62f: 82, + 0x630: 82, + 0x631: 82, + 0x632: 82, + 0x633: 68, + 0x634: 68, + 0x635: 68, + 0x636: 68, + 0x637: 68, + 0x638: 68, + 0x639: 68, + 0x63a: 68, + 0x63b: 68, + 0x63c: 68, + 0x63d: 68, + 0x63e: 68, + 0x63f: 68, + 0x640: 67, + 0x641: 68, + 0x642: 68, + 0x643: 68, + 0x644: 68, + 0x645: 68, + 0x646: 68, + 0x647: 68, + 0x648: 82, + 0x649: 68, + 0x64a: 68, + 0x66e: 68, + 0x66f: 68, + 0x671: 82, + 0x672: 82, + 0x673: 82, + 0x674: 85, + 0x675: 82, + 0x676: 82, + 0x677: 82, + 0x678: 68, + 0x679: 68, + 0x67a: 68, + 0x67b: 68, + 0x67c: 68, + 0x67d: 68, + 0x67e: 68, + 0x67f: 68, + 0x680: 68, + 0x681: 68, + 0x682: 68, + 0x683: 68, + 0x684: 68, + 0x685: 68, + 0x686: 68, + 0x687: 68, + 0x688: 82, + 0x689: 82, + 0x68a: 82, + 0x68b: 82, + 0x68c: 82, + 0x68d: 82, + 0x68e: 82, + 0x68f: 82, + 0x690: 82, + 0x691: 82, + 0x692: 82, + 0x693: 82, + 0x694: 82, + 0x695: 82, + 0x696: 82, + 0x697: 82, + 0x698: 82, + 0x699: 82, + 0x69a: 68, + 0x69b: 68, + 0x69c: 68, + 0x69d: 68, + 0x69e: 68, + 0x69f: 68, + 0x6a0: 68, + 0x6a1: 68, + 0x6a2: 68, + 0x6a3: 68, + 0x6a4: 68, + 0x6a5: 68, + 0x6a6: 68, + 0x6a7: 68, + 0x6a8: 68, + 0x6a9: 68, + 0x6aa: 68, + 0x6ab: 68, + 0x6ac: 68, + 0x6ad: 68, + 0x6ae: 68, + 0x6af: 68, + 0x6b0: 68, + 0x6b1: 68, + 0x6b2: 68, + 0x6b3: 68, + 0x6b4: 68, + 0x6b5: 68, + 0x6b6: 68, + 0x6b7: 68, + 0x6b8: 68, + 0x6b9: 68, + 0x6ba: 68, + 0x6bb: 68, + 0x6bc: 68, + 0x6bd: 68, + 0x6be: 68, + 0x6bf: 68, + 0x6c0: 82, + 0x6c1: 68, + 0x6c2: 68, + 0x6c3: 82, + 0x6c4: 82, + 0x6c5: 82, + 0x6c6: 82, + 0x6c7: 82, + 0x6c8: 82, + 0x6c9: 82, + 0x6ca: 82, + 0x6cb: 82, + 0x6cc: 68, + 0x6cd: 82, + 0x6ce: 68, + 0x6cf: 82, + 0x6d0: 68, + 0x6d1: 68, + 0x6d2: 82, + 0x6d3: 82, + 0x6d5: 82, + 0x6dd: 85, + 0x6ee: 82, + 0x6ef: 82, + 0x6fa: 68, + 0x6fb: 68, + 0x6fc: 68, + 0x6ff: 68, + 0x710: 82, + 0x712: 68, + 0x713: 68, + 0x714: 68, + 0x715: 82, + 0x716: 82, + 0x717: 82, + 0x718: 82, + 0x719: 82, + 0x71a: 68, + 0x71b: 68, + 0x71c: 68, + 0x71d: 68, + 0x71e: 82, + 0x71f: 68, + 0x720: 68, + 0x721: 68, + 0x722: 68, + 0x723: 68, + 0x724: 68, + 0x725: 68, + 0x726: 68, + 0x727: 68, + 0x728: 82, + 0x729: 68, + 0x72a: 82, + 0x72b: 68, + 0x72c: 82, + 0x72d: 68, + 0x72e: 68, + 0x72f: 82, + 0x74d: 82, + 0x74e: 68, + 0x74f: 68, + 0x750: 68, + 0x751: 68, + 0x752: 68, + 0x753: 68, + 0x754: 68, + 0x755: 68, + 0x756: 68, + 0x757: 68, + 0x758: 68, + 0x759: 82, + 0x75a: 82, + 0x75b: 82, + 0x75c: 68, + 0x75d: 68, + 0x75e: 68, + 0x75f: 68, + 0x760: 68, + 0x761: 68, + 0x762: 68, + 0x763: 68, + 0x764: 68, + 0x765: 68, + 0x766: 68, + 0x767: 68, + 0x768: 68, + 0x769: 68, + 0x76a: 68, + 0x76b: 82, + 0x76c: 82, + 0x76d: 68, + 0x76e: 68, + 0x76f: 68, + 0x770: 68, + 0x771: 82, + 0x772: 68, + 0x773: 82, + 0x774: 82, + 0x775: 68, + 0x776: 68, + 0x777: 68, + 0x778: 82, + 0x779: 82, + 0x77a: 68, + 0x77b: 68, + 0x77c: 68, + 0x77d: 68, + 0x77e: 68, + 0x77f: 68, + 0x7ca: 68, + 0x7cb: 68, + 0x7cc: 68, + 0x7cd: 68, + 0x7ce: 68, + 0x7cf: 68, + 0x7d0: 68, + 0x7d1: 68, + 0x7d2: 68, + 0x7d3: 68, + 0x7d4: 68, + 0x7d5: 68, + 0x7d6: 68, + 0x7d7: 68, + 0x7d8: 68, + 0x7d9: 68, + 0x7da: 68, + 0x7db: 68, + 0x7dc: 68, + 0x7dd: 68, + 0x7de: 68, + 0x7df: 68, + 0x7e0: 68, + 0x7e1: 68, + 0x7e2: 68, + 0x7e3: 68, + 0x7e4: 68, + 0x7e5: 68, + 0x7e6: 68, + 0x7e7: 68, + 0x7e8: 68, + 0x7e9: 68, + 0x7ea: 68, + 0x7fa: 67, + 0x840: 82, + 0x841: 68, + 0x842: 68, + 0x843: 68, + 0x844: 68, + 0x845: 68, + 0x846: 82, + 0x847: 68, + 0x848: 68, + 0x849: 82, + 0x84a: 68, + 0x84b: 68, + 0x84c: 68, + 0x84d: 68, + 0x84e: 68, + 0x84f: 82, + 0x850: 68, + 0x851: 68, + 0x852: 68, + 0x853: 68, + 0x854: 82, + 0x855: 68, + 0x856: 85, + 0x857: 85, + 0x858: 85, + 0x8a0: 68, + 0x8a2: 68, + 0x8a3: 68, + 0x8a4: 68, + 0x8a5: 68, + 0x8a6: 68, + 0x8a7: 68, + 0x8a8: 68, + 0x8a9: 68, + 0x8aa: 82, + 0x8ab: 82, + 0x8ac: 82, + 0x1806: 85, + 0x1807: 68, + 0x180a: 67, + 0x180e: 85, + 0x1820: 68, + 0x1821: 68, + 0x1822: 68, + 0x1823: 68, + 0x1824: 68, + 0x1825: 68, + 0x1826: 68, + 0x1827: 68, + 0x1828: 68, + 0x1829: 68, + 0x182a: 68, + 0x182b: 68, + 0x182c: 68, + 0x182d: 68, + 0x182e: 68, + 0x182f: 68, + 0x1830: 68, + 0x1831: 68, + 0x1832: 68, + 0x1833: 68, + 0x1834: 68, + 0x1835: 68, + 0x1836: 68, + 0x1837: 68, + 0x1838: 68, + 0x1839: 68, + 0x183a: 68, + 0x183b: 68, + 0x183c: 68, + 0x183d: 68, + 0x183e: 68, + 0x183f: 68, + 0x1840: 68, + 0x1841: 68, + 0x1842: 68, + 0x1843: 68, + 0x1844: 68, + 0x1845: 68, + 0x1846: 68, + 0x1847: 68, + 0x1848: 68, + 0x1849: 68, + 0x184a: 68, + 0x184b: 68, + 0x184c: 68, + 0x184d: 68, + 0x184e: 68, + 0x184f: 68, + 0x1850: 68, + 0x1851: 68, + 0x1852: 68, + 0x1853: 68, + 0x1854: 68, + 0x1855: 68, + 0x1856: 68, + 0x1857: 68, + 0x1858: 68, + 0x1859: 68, + 0x185a: 68, + 0x185b: 68, + 0x185c: 68, + 0x185d: 68, + 0x185e: 68, + 0x185f: 68, + 0x1860: 68, + 0x1861: 68, + 0x1862: 68, + 0x1863: 68, + 0x1864: 68, + 0x1865: 68, + 0x1866: 68, + 0x1867: 68, + 0x1868: 68, + 0x1869: 68, + 0x186a: 68, + 0x186b: 68, + 0x186c: 68, + 0x186d: 68, + 0x186e: 68, + 0x186f: 68, + 0x1870: 68, + 0x1871: 68, + 0x1872: 68, + 0x1873: 68, + 0x1874: 68, + 0x1875: 68, + 0x1876: 68, + 0x1877: 68, + 0x1880: 85, + 0x1881: 85, + 0x1882: 85, + 0x1883: 85, + 0x1884: 85, + 0x1885: 85, + 0x1886: 85, + 0x1887: 68, + 0x1888: 68, + 0x1889: 68, + 0x188a: 68, + 0x188b: 68, + 0x188c: 68, + 0x188d: 68, + 0x188e: 68, + 0x188f: 68, + 0x1890: 68, + 0x1891: 68, + 0x1892: 68, + 0x1893: 68, + 0x1894: 68, + 0x1895: 68, + 0x1896: 68, + 0x1897: 68, + 0x1898: 68, + 0x1899: 68, + 0x189a: 68, + 0x189b: 68, + 0x189c: 68, + 0x189d: 68, + 0x189e: 68, + 0x189f: 68, + 0x18a0: 68, + 0x18a1: 68, + 0x18a2: 68, + 0x18a3: 68, + 0x18a4: 68, + 0x18a5: 68, + 0x18a6: 68, + 0x18a7: 68, + 0x18a8: 68, + 0x18aa: 68, + 0x200c: 85, + 0x200d: 67, + 0x2066: 85, + 0x2067: 85, + 0x2068: 85, + 0x2069: 85, + 0xa840: 68, + 0xa841: 68, + 0xa842: 68, + 0xa843: 68, + 0xa844: 68, + 0xa845: 68, + 0xa846: 68, + 0xa847: 68, + 0xa848: 68, + 0xa849: 68, + 0xa84a: 68, + 0xa84b: 68, + 0xa84c: 68, + 0xa84d: 68, + 0xa84e: 68, + 0xa84f: 68, + 0xa850: 68, + 0xa851: 68, + 0xa852: 68, + 0xa853: 68, + 0xa854: 68, + 0xa855: 68, + 0xa856: 68, + 0xa857: 68, + 0xa858: 68, + 0xa859: 68, + 0xa85a: 68, + 0xa85b: 68, + 0xa85c: 68, + 0xa85d: 68, + 0xa85e: 68, + 0xa85f: 68, + 0xa860: 68, + 0xa861: 68, + 0xa862: 68, + 0xa863: 68, + 0xa864: 68, + 0xa865: 68, + 0xa866: 68, + 0xa867: 68, + 0xa868: 68, + 0xa869: 68, + 0xa86a: 68, + 0xa86b: 68, + 0xa86c: 68, + 0xa86d: 68, + 0xa86e: 68, + 0xa86f: 68, + 0xa870: 68, + 0xa871: 68, + 0xa872: 76, + 0xa873: 85, +} +codepoint_classes = { + 'PVALID': ( + 0x2d0000002e, + 0x300000003a, + 0x610000007b, + 0xdf000000f7, + 0xf800000100, + 0x10100000102, + 0x10300000104, + 0x10500000106, + 0x10700000108, + 0x1090000010a, + 0x10b0000010c, + 0x10d0000010e, + 0x10f00000110, + 0x11100000112, + 0x11300000114, + 0x11500000116, + 0x11700000118, + 0x1190000011a, + 0x11b0000011c, + 0x11d0000011e, + 0x11f00000120, + 0x12100000122, + 0x12300000124, + 0x12500000126, + 0x12700000128, + 0x1290000012a, + 0x12b0000012c, + 0x12d0000012e, + 0x12f00000130, + 0x13100000132, + 0x13500000136, + 0x13700000139, + 0x13a0000013b, + 0x13c0000013d, + 0x13e0000013f, + 0x14200000143, + 0x14400000145, + 0x14600000147, + 0x14800000149, + 0x14b0000014c, + 0x14d0000014e, + 0x14f00000150, + 0x15100000152, + 0x15300000154, + 0x15500000156, + 0x15700000158, + 0x1590000015a, + 0x15b0000015c, + 0x15d0000015e, + 0x15f00000160, + 0x16100000162, + 0x16300000164, + 0x16500000166, + 0x16700000168, + 0x1690000016a, + 0x16b0000016c, + 0x16d0000016e, + 0x16f00000170, + 0x17100000172, + 0x17300000174, + 0x17500000176, + 0x17700000178, + 0x17a0000017b, + 0x17c0000017d, + 0x17e0000017f, + 0x18000000181, + 0x18300000184, + 0x18500000186, + 0x18800000189, + 0x18c0000018e, + 0x19200000193, + 0x19500000196, + 0x1990000019c, + 0x19e0000019f, + 0x1a1000001a2, + 0x1a3000001a4, + 0x1a5000001a6, + 0x1a8000001a9, + 0x1aa000001ac, + 0x1ad000001ae, + 0x1b0000001b1, + 0x1b4000001b5, + 0x1b6000001b7, + 0x1b9000001bc, + 0x1bd000001c4, + 0x1ce000001cf, + 0x1d0000001d1, + 0x1d2000001d3, + 0x1d4000001d5, + 0x1d6000001d7, + 0x1d8000001d9, + 0x1da000001db, + 0x1dc000001de, + 0x1df000001e0, + 0x1e1000001e2, + 0x1e3000001e4, + 0x1e5000001e6, + 0x1e7000001e8, + 0x1e9000001ea, + 0x1eb000001ec, + 0x1ed000001ee, + 0x1ef000001f1, + 0x1f5000001f6, + 0x1f9000001fa, + 0x1fb000001fc, + 0x1fd000001fe, + 0x1ff00000200, + 0x20100000202, + 0x20300000204, + 0x20500000206, + 0x20700000208, + 0x2090000020a, + 0x20b0000020c, + 0x20d0000020e, + 0x20f00000210, + 0x21100000212, + 0x21300000214, + 0x21500000216, + 0x21700000218, + 0x2190000021a, + 0x21b0000021c, + 0x21d0000021e, + 0x21f00000220, + 0x22100000222, + 0x22300000224, + 0x22500000226, + 0x22700000228, + 0x2290000022a, + 0x22b0000022c, + 0x22d0000022e, + 0x22f00000230, + 0x23100000232, + 0x2330000023a, + 0x23c0000023d, + 0x23f00000241, + 0x24200000243, + 0x24700000248, + 0x2490000024a, + 0x24b0000024c, + 0x24d0000024e, + 0x24f000002b0, + 0x2b9000002c2, + 0x2c6000002d2, + 0x2ec000002ed, + 0x2ee000002ef, + 0x30000000340, + 0x34200000343, + 0x3460000034f, + 0x35000000370, + 0x37100000372, + 0x37300000374, + 0x37700000378, + 0x37b0000037e, + 0x39000000391, + 0x3ac000003cf, + 0x3d7000003d8, + 0x3d9000003da, + 0x3db000003dc, + 0x3dd000003de, + 0x3df000003e0, + 0x3e1000003e2, + 0x3e3000003e4, + 0x3e5000003e6, + 0x3e7000003e8, + 0x3e9000003ea, + 0x3eb000003ec, + 0x3ed000003ee, + 0x3ef000003f0, + 0x3f3000003f4, + 0x3f8000003f9, + 0x3fb000003fd, + 0x43000000460, + 0x46100000462, + 0x46300000464, + 0x46500000466, + 0x46700000468, + 0x4690000046a, + 0x46b0000046c, + 0x46d0000046e, + 0x46f00000470, + 0x47100000472, + 0x47300000474, + 0x47500000476, + 0x47700000478, + 0x4790000047a, + 0x47b0000047c, + 0x47d0000047e, + 0x47f00000480, + 0x48100000482, + 0x48300000488, + 0x48b0000048c, + 0x48d0000048e, + 0x48f00000490, + 0x49100000492, + 0x49300000494, + 0x49500000496, + 0x49700000498, + 0x4990000049a, + 0x49b0000049c, + 0x49d0000049e, + 0x49f000004a0, + 0x4a1000004a2, + 0x4a3000004a4, + 0x4a5000004a6, + 0x4a7000004a8, + 0x4a9000004aa, + 0x4ab000004ac, + 0x4ad000004ae, + 0x4af000004b0, + 0x4b1000004b2, + 0x4b3000004b4, + 0x4b5000004b6, + 0x4b7000004b8, + 0x4b9000004ba, + 0x4bb000004bc, + 0x4bd000004be, + 0x4bf000004c0, + 0x4c2000004c3, + 0x4c4000004c5, + 0x4c6000004c7, + 0x4c8000004c9, + 0x4ca000004cb, + 0x4cc000004cd, + 0x4ce000004d0, + 0x4d1000004d2, + 0x4d3000004d4, + 0x4d5000004d6, + 0x4d7000004d8, + 0x4d9000004da, + 0x4db000004dc, + 0x4dd000004de, + 0x4df000004e0, + 0x4e1000004e2, + 0x4e3000004e4, + 0x4e5000004e6, + 0x4e7000004e8, + 0x4e9000004ea, + 0x4eb000004ec, + 0x4ed000004ee, + 0x4ef000004f0, + 0x4f1000004f2, + 0x4f3000004f4, + 0x4f5000004f6, + 0x4f7000004f8, + 0x4f9000004fa, + 0x4fb000004fc, + 0x4fd000004fe, + 0x4ff00000500, + 0x50100000502, + 0x50300000504, + 0x50500000506, + 0x50700000508, + 0x5090000050a, + 0x50b0000050c, + 0x50d0000050e, + 0x50f00000510, + 0x51100000512, + 0x51300000514, + 0x51500000516, + 0x51700000518, + 0x5190000051a, + 0x51b0000051c, + 0x51d0000051e, + 0x51f00000520, + 0x52100000522, + 0x52300000524, + 0x52500000526, + 0x52700000528, + 0x5590000055a, + 0x56100000587, + 0x591000005be, + 0x5bf000005c0, + 0x5c1000005c3, + 0x5c4000005c6, + 0x5c7000005c8, + 0x5d0000005eb, + 0x5f0000005f3, + 0x6100000061b, + 0x62000000640, + 0x64100000660, + 0x66e00000675, + 0x679000006d4, + 0x6d5000006dd, + 0x6df000006e9, + 0x6ea000006f0, + 0x6fa00000700, + 0x7100000074b, + 0x74d000007b2, + 0x7c0000007f6, + 0x8000000082e, + 0x8400000085c, + 0x8a0000008a1, + 0x8a2000008ad, + 0x8e4000008ff, + 0x90000000958, + 0x96000000964, + 0x96600000970, + 0x97100000978, + 0x97900000980, + 0x98100000984, + 0x9850000098d, + 0x98f00000991, + 0x993000009a9, + 0x9aa000009b1, + 0x9b2000009b3, + 0x9b6000009ba, + 0x9bc000009c5, + 0x9c7000009c9, + 0x9cb000009cf, + 0x9d7000009d8, + 0x9e0000009e4, + 0x9e6000009f2, + 0xa0100000a04, + 0xa0500000a0b, + 0xa0f00000a11, + 0xa1300000a29, + 0xa2a00000a31, + 0xa3200000a33, + 0xa3500000a36, + 0xa3800000a3a, + 0xa3c00000a3d, + 0xa3e00000a43, + 0xa4700000a49, + 0xa4b00000a4e, + 0xa5100000a52, + 0xa5c00000a5d, + 0xa6600000a76, + 0xa8100000a84, + 0xa8500000a8e, + 0xa8f00000a92, + 0xa9300000aa9, + 0xaaa00000ab1, + 0xab200000ab4, + 0xab500000aba, + 0xabc00000ac6, + 0xac700000aca, + 0xacb00000ace, + 0xad000000ad1, + 0xae000000ae4, + 0xae600000af0, + 0xb0100000b04, + 0xb0500000b0d, + 0xb0f00000b11, + 0xb1300000b29, + 0xb2a00000b31, + 0xb3200000b34, + 0xb3500000b3a, + 0xb3c00000b45, + 0xb4700000b49, + 0xb4b00000b4e, + 0xb5600000b58, + 0xb5f00000b64, + 0xb6600000b70, + 0xb7100000b72, + 0xb8200000b84, + 0xb8500000b8b, + 0xb8e00000b91, + 0xb9200000b96, + 0xb9900000b9b, + 0xb9c00000b9d, + 0xb9e00000ba0, + 0xba300000ba5, + 0xba800000bab, + 0xbae00000bba, + 0xbbe00000bc3, + 0xbc600000bc9, + 0xbca00000bce, + 0xbd000000bd1, + 0xbd700000bd8, + 0xbe600000bf0, + 0xc0100000c04, + 0xc0500000c0d, + 0xc0e00000c11, + 0xc1200000c29, + 0xc2a00000c34, + 0xc3500000c3a, + 0xc3d00000c45, + 0xc4600000c49, + 0xc4a00000c4e, + 0xc5500000c57, + 0xc5800000c5a, + 0xc6000000c64, + 0xc6600000c70, + 0xc8200000c84, + 0xc8500000c8d, + 0xc8e00000c91, + 0xc9200000ca9, + 0xcaa00000cb4, + 0xcb500000cba, + 0xcbc00000cc5, + 0xcc600000cc9, + 0xcca00000cce, + 0xcd500000cd7, + 0xcde00000cdf, + 0xce000000ce4, + 0xce600000cf0, + 0xcf100000cf3, + 0xd0200000d04, + 0xd0500000d0d, + 0xd0e00000d11, + 0xd1200000d3b, + 0xd3d00000d45, + 0xd4600000d49, + 0xd4a00000d4f, + 0xd5700000d58, + 0xd6000000d64, + 0xd6600000d70, + 0xd7a00000d80, + 0xd8200000d84, + 0xd8500000d97, + 0xd9a00000db2, + 0xdb300000dbc, + 0xdbd00000dbe, + 0xdc000000dc7, + 0xdca00000dcb, + 0xdcf00000dd5, + 0xdd600000dd7, + 0xdd800000de0, + 0xdf200000df4, + 0xe0100000e33, + 0xe3400000e3b, + 0xe4000000e4f, + 0xe5000000e5a, + 0xe8100000e83, + 0xe8400000e85, + 0xe8700000e89, + 0xe8a00000e8b, + 0xe8d00000e8e, + 0xe9400000e98, + 0xe9900000ea0, + 0xea100000ea4, + 0xea500000ea6, + 0xea700000ea8, + 0xeaa00000eac, + 0xead00000eb3, + 0xeb400000eba, + 0xebb00000ebe, + 0xec000000ec5, + 0xec600000ec7, + 0xec800000ece, + 0xed000000eda, + 0xede00000ee0, + 0xf0000000f01, + 0xf0b00000f0c, + 0xf1800000f1a, + 0xf2000000f2a, + 0xf3500000f36, + 0xf3700000f38, + 0xf3900000f3a, + 0xf3e00000f43, + 0xf4400000f48, + 0xf4900000f4d, + 0xf4e00000f52, + 0xf5300000f57, + 0xf5800000f5c, + 0xf5d00000f69, + 0xf6a00000f6d, + 0xf7100000f73, + 0xf7400000f75, + 0xf7a00000f81, + 0xf8200000f85, + 0xf8600000f93, + 0xf9400000f98, + 0xf9900000f9d, + 0xf9e00000fa2, + 0xfa300000fa7, + 0xfa800000fac, + 0xfad00000fb9, + 0xfba00000fbd, + 0xfc600000fc7, + 0x10000000104a, + 0x10500000109e, + 0x10d0000010fb, + 0x10fd00001100, + 0x120000001249, + 0x124a0000124e, + 0x125000001257, + 0x125800001259, + 0x125a0000125e, + 0x126000001289, + 0x128a0000128e, + 0x1290000012b1, + 0x12b2000012b6, + 0x12b8000012bf, + 0x12c0000012c1, + 0x12c2000012c6, + 0x12c8000012d7, + 0x12d800001311, + 0x131200001316, + 0x13180000135b, + 0x135d00001360, + 0x138000001390, + 0x13a0000013f5, + 0x14010000166d, + 0x166f00001680, + 0x16810000169b, + 0x16a0000016eb, + 0x17000000170d, + 0x170e00001715, + 0x172000001735, + 0x174000001754, + 0x17600000176d, + 0x176e00001771, + 0x177200001774, + 0x1780000017b4, + 0x17b6000017d4, + 0x17d7000017d8, + 0x17dc000017de, + 0x17e0000017ea, + 0x18100000181a, + 0x182000001878, + 0x1880000018ab, + 0x18b0000018f6, + 0x19000000191d, + 0x19200000192c, + 0x19300000193c, + 0x19460000196e, + 0x197000001975, + 0x1980000019ac, + 0x19b0000019ca, + 0x19d0000019da, + 0x1a0000001a1c, + 0x1a2000001a5f, + 0x1a6000001a7d, + 0x1a7f00001a8a, + 0x1a9000001a9a, + 0x1aa700001aa8, + 0x1b0000001b4c, + 0x1b5000001b5a, + 0x1b6b00001b74, + 0x1b8000001bf4, + 0x1c0000001c38, + 0x1c4000001c4a, + 0x1c4d00001c7e, + 0x1cd000001cd3, + 0x1cd400001cf7, + 0x1d0000001d2c, + 0x1d2f00001d30, + 0x1d3b00001d3c, + 0x1d4e00001d4f, + 0x1d6b00001d78, + 0x1d7900001d9b, + 0x1dc000001de7, + 0x1dfc00001e00, + 0x1e0100001e02, + 0x1e0300001e04, + 0x1e0500001e06, + 0x1e0700001e08, + 0x1e0900001e0a, + 0x1e0b00001e0c, + 0x1e0d00001e0e, + 0x1e0f00001e10, + 0x1e1100001e12, + 0x1e1300001e14, + 0x1e1500001e16, + 0x1e1700001e18, + 0x1e1900001e1a, + 0x1e1b00001e1c, + 0x1e1d00001e1e, + 0x1e1f00001e20, + 0x1e2100001e22, + 0x1e2300001e24, + 0x1e2500001e26, + 0x1e2700001e28, + 0x1e2900001e2a, + 0x1e2b00001e2c, + 0x1e2d00001e2e, + 0x1e2f00001e30, + 0x1e3100001e32, + 0x1e3300001e34, + 0x1e3500001e36, + 0x1e3700001e38, + 0x1e3900001e3a, + 0x1e3b00001e3c, + 0x1e3d00001e3e, + 0x1e3f00001e40, + 0x1e4100001e42, + 0x1e4300001e44, + 0x1e4500001e46, + 0x1e4700001e48, + 0x1e4900001e4a, + 0x1e4b00001e4c, + 0x1e4d00001e4e, + 0x1e4f00001e50, + 0x1e5100001e52, + 0x1e5300001e54, + 0x1e5500001e56, + 0x1e5700001e58, + 0x1e5900001e5a, + 0x1e5b00001e5c, + 0x1e5d00001e5e, + 0x1e5f00001e60, + 0x1e6100001e62, + 0x1e6300001e64, + 0x1e6500001e66, + 0x1e6700001e68, + 0x1e6900001e6a, + 0x1e6b00001e6c, + 0x1e6d00001e6e, + 0x1e6f00001e70, + 0x1e7100001e72, + 0x1e7300001e74, + 0x1e7500001e76, + 0x1e7700001e78, + 0x1e7900001e7a, + 0x1e7b00001e7c, + 0x1e7d00001e7e, + 0x1e7f00001e80, + 0x1e8100001e82, + 0x1e8300001e84, + 0x1e8500001e86, + 0x1e8700001e88, + 0x1e8900001e8a, + 0x1e8b00001e8c, + 0x1e8d00001e8e, + 0x1e8f00001e90, + 0x1e9100001e92, + 0x1e9300001e94, + 0x1e9500001e9a, + 0x1e9c00001e9e, + 0x1e9f00001ea0, + 0x1ea100001ea2, + 0x1ea300001ea4, + 0x1ea500001ea6, + 0x1ea700001ea8, + 0x1ea900001eaa, + 0x1eab00001eac, + 0x1ead00001eae, + 0x1eaf00001eb0, + 0x1eb100001eb2, + 0x1eb300001eb4, + 0x1eb500001eb6, + 0x1eb700001eb8, + 0x1eb900001eba, + 0x1ebb00001ebc, + 0x1ebd00001ebe, + 0x1ebf00001ec0, + 0x1ec100001ec2, + 0x1ec300001ec4, + 0x1ec500001ec6, + 0x1ec700001ec8, + 0x1ec900001eca, + 0x1ecb00001ecc, + 0x1ecd00001ece, + 0x1ecf00001ed0, + 0x1ed100001ed2, + 0x1ed300001ed4, + 0x1ed500001ed6, + 0x1ed700001ed8, + 0x1ed900001eda, + 0x1edb00001edc, + 0x1edd00001ede, + 0x1edf00001ee0, + 0x1ee100001ee2, + 0x1ee300001ee4, + 0x1ee500001ee6, + 0x1ee700001ee8, + 0x1ee900001eea, + 0x1eeb00001eec, + 0x1eed00001eee, + 0x1eef00001ef0, + 0x1ef100001ef2, + 0x1ef300001ef4, + 0x1ef500001ef6, + 0x1ef700001ef8, + 0x1ef900001efa, + 0x1efb00001efc, + 0x1efd00001efe, + 0x1eff00001f08, + 0x1f1000001f16, + 0x1f2000001f28, + 0x1f3000001f38, + 0x1f4000001f46, + 0x1f5000001f58, + 0x1f6000001f68, + 0x1f7000001f71, + 0x1f7200001f73, + 0x1f7400001f75, + 0x1f7600001f77, + 0x1f7800001f79, + 0x1f7a00001f7b, + 0x1f7c00001f7d, + 0x1fb000001fb2, + 0x1fb600001fb7, + 0x1fc600001fc7, + 0x1fd000001fd3, + 0x1fd600001fd8, + 0x1fe000001fe3, + 0x1fe400001fe8, + 0x1ff600001ff7, + 0x214e0000214f, + 0x218400002185, + 0x2c3000002c5f, + 0x2c6100002c62, + 0x2c6500002c67, + 0x2c6800002c69, + 0x2c6a00002c6b, + 0x2c6c00002c6d, + 0x2c7100002c72, + 0x2c7300002c75, + 0x2c7600002c7c, + 0x2c8100002c82, + 0x2c8300002c84, + 0x2c8500002c86, + 0x2c8700002c88, + 0x2c8900002c8a, + 0x2c8b00002c8c, + 0x2c8d00002c8e, + 0x2c8f00002c90, + 0x2c9100002c92, + 0x2c9300002c94, + 0x2c9500002c96, + 0x2c9700002c98, + 0x2c9900002c9a, + 0x2c9b00002c9c, + 0x2c9d00002c9e, + 0x2c9f00002ca0, + 0x2ca100002ca2, + 0x2ca300002ca4, + 0x2ca500002ca6, + 0x2ca700002ca8, + 0x2ca900002caa, + 0x2cab00002cac, + 0x2cad00002cae, + 0x2caf00002cb0, + 0x2cb100002cb2, + 0x2cb300002cb4, + 0x2cb500002cb6, + 0x2cb700002cb8, + 0x2cb900002cba, + 0x2cbb00002cbc, + 0x2cbd00002cbe, + 0x2cbf00002cc0, + 0x2cc100002cc2, + 0x2cc300002cc4, + 0x2cc500002cc6, + 0x2cc700002cc8, + 0x2cc900002cca, + 0x2ccb00002ccc, + 0x2ccd00002cce, + 0x2ccf00002cd0, + 0x2cd100002cd2, + 0x2cd300002cd4, + 0x2cd500002cd6, + 0x2cd700002cd8, + 0x2cd900002cda, + 0x2cdb00002cdc, + 0x2cdd00002cde, + 0x2cdf00002ce0, + 0x2ce100002ce2, + 0x2ce300002ce5, + 0x2cec00002ced, + 0x2cee00002cf2, + 0x2cf300002cf4, + 0x2d0000002d26, + 0x2d2700002d28, + 0x2d2d00002d2e, + 0x2d3000002d68, + 0x2d7f00002d97, + 0x2da000002da7, + 0x2da800002daf, + 0x2db000002db7, + 0x2db800002dbf, + 0x2dc000002dc7, + 0x2dc800002dcf, + 0x2dd000002dd7, + 0x2dd800002ddf, + 0x2de000002e00, + 0x2e2f00002e30, + 0x300500003008, + 0x302a0000302e, + 0x303c0000303d, + 0x304100003097, + 0x30990000309b, + 0x309d0000309f, + 0x30a1000030fb, + 0x30fc000030ff, + 0x31050000312e, + 0x31a0000031bb, + 0x31f000003200, + 0x340000004db6, + 0x4e0000009fcd, + 0xa0000000a48d, + 0xa4d00000a4fe, + 0xa5000000a60d, + 0xa6100000a62c, + 0xa6410000a642, + 0xa6430000a644, + 0xa6450000a646, + 0xa6470000a648, + 0xa6490000a64a, + 0xa64b0000a64c, + 0xa64d0000a64e, + 0xa64f0000a650, + 0xa6510000a652, + 0xa6530000a654, + 0xa6550000a656, + 0xa6570000a658, + 0xa6590000a65a, + 0xa65b0000a65c, + 0xa65d0000a65e, + 0xa65f0000a660, + 0xa6610000a662, + 0xa6630000a664, + 0xa6650000a666, + 0xa6670000a668, + 0xa6690000a66a, + 0xa66b0000a66c, + 0xa66d0000a670, + 0xa6740000a67e, + 0xa67f0000a680, + 0xa6810000a682, + 0xa6830000a684, + 0xa6850000a686, + 0xa6870000a688, + 0xa6890000a68a, + 0xa68b0000a68c, + 0xa68d0000a68e, + 0xa68f0000a690, + 0xa6910000a692, + 0xa6930000a694, + 0xa6950000a696, + 0xa6970000a698, + 0xa69f0000a6e6, + 0xa6f00000a6f2, + 0xa7170000a720, + 0xa7230000a724, + 0xa7250000a726, + 0xa7270000a728, + 0xa7290000a72a, + 0xa72b0000a72c, + 0xa72d0000a72e, + 0xa72f0000a732, + 0xa7330000a734, + 0xa7350000a736, + 0xa7370000a738, + 0xa7390000a73a, + 0xa73b0000a73c, + 0xa73d0000a73e, + 0xa73f0000a740, + 0xa7410000a742, + 0xa7430000a744, + 0xa7450000a746, + 0xa7470000a748, + 0xa7490000a74a, + 0xa74b0000a74c, + 0xa74d0000a74e, + 0xa74f0000a750, + 0xa7510000a752, + 0xa7530000a754, + 0xa7550000a756, + 0xa7570000a758, + 0xa7590000a75a, + 0xa75b0000a75c, + 0xa75d0000a75e, + 0xa75f0000a760, + 0xa7610000a762, + 0xa7630000a764, + 0xa7650000a766, + 0xa7670000a768, + 0xa7690000a76a, + 0xa76b0000a76c, + 0xa76d0000a76e, + 0xa76f0000a770, + 0xa7710000a779, + 0xa77a0000a77b, + 0xa77c0000a77d, + 0xa77f0000a780, + 0xa7810000a782, + 0xa7830000a784, + 0xa7850000a786, + 0xa7870000a789, + 0xa78c0000a78d, + 0xa78e0000a78f, + 0xa7910000a792, + 0xa7930000a794, + 0xa7a10000a7a2, + 0xa7a30000a7a4, + 0xa7a50000a7a6, + 0xa7a70000a7a8, + 0xa7a90000a7aa, + 0xa7fa0000a828, + 0xa8400000a874, + 0xa8800000a8c5, + 0xa8d00000a8da, + 0xa8e00000a8f8, + 0xa8fb0000a8fc, + 0xa9000000a92e, + 0xa9300000a954, + 0xa9800000a9c1, + 0xa9cf0000a9da, + 0xaa000000aa37, + 0xaa400000aa4e, + 0xaa500000aa5a, + 0xaa600000aa77, + 0xaa7a0000aa7c, + 0xaa800000aac3, + 0xaadb0000aade, + 0xaae00000aaf0, + 0xaaf20000aaf7, + 0xab010000ab07, + 0xab090000ab0f, + 0xab110000ab17, + 0xab200000ab27, + 0xab280000ab2f, + 0xabc00000abeb, + 0xabec0000abee, + 0xabf00000abfa, + 0xac000000d7a4, + 0xfa0e0000fa10, + 0xfa110000fa12, + 0xfa130000fa15, + 0xfa1f0000fa20, + 0xfa210000fa22, + 0xfa230000fa25, + 0xfa270000fa2a, + 0xfb1e0000fb1f, + 0xfe200000fe27, + 0xfe730000fe74, + 0x100000001000c, + 0x1000d00010027, + 0x100280001003b, + 0x1003c0001003e, + 0x1003f0001004e, + 0x100500001005e, + 0x10080000100fb, + 0x101fd000101fe, + 0x102800001029d, + 0x102a0000102d1, + 0x103000001031f, + 0x1033000010341, + 0x103420001034a, + 0x103800001039e, + 0x103a0000103c4, + 0x103c8000103d0, + 0x104280001049e, + 0x104a0000104aa, + 0x1080000010806, + 0x1080800010809, + 0x1080a00010836, + 0x1083700010839, + 0x1083c0001083d, + 0x1083f00010856, + 0x1090000010916, + 0x109200001093a, + 0x10980000109b8, + 0x109be000109c0, + 0x10a0000010a04, + 0x10a0500010a07, + 0x10a0c00010a14, + 0x10a1500010a18, + 0x10a1900010a34, + 0x10a3800010a3b, + 0x10a3f00010a40, + 0x10a6000010a7d, + 0x10b0000010b36, + 0x10b4000010b56, + 0x10b6000010b73, + 0x10c0000010c49, + 0x1100000011047, + 0x1106600011070, + 0x11080000110bb, + 0x110d0000110e9, + 0x110f0000110fa, + 0x1110000011135, + 0x1113600011140, + 0x11180000111c5, + 0x111d0000111da, + 0x11680000116b8, + 0x116c0000116ca, + 0x120000001236f, + 0x130000001342f, + 0x1680000016a39, + 0x16f0000016f45, + 0x16f5000016f7f, + 0x16f8f00016fa0, + 0x1b0000001b002, + 0x200000002a6d7, + 0x2a7000002b735, + 0x2b7400002b81e, + ), + 'CONTEXTJ': ( + 0x200c0000200e, + ), + 'CONTEXTO': ( + 0xb7000000b8, + 0x37500000376, + 0x5f3000005f5, + 0x6600000066a, + 0x6f0000006fa, + 0x30fb000030fc, + ), +} diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/intranges.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/intranges.py new file mode 100644 index 0000000..fa8a735 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/intranges.py @@ -0,0 +1,53 @@ +""" +Given a list of integers, made up of (hopefully) a small number of long runs +of consecutive integers, compute a representation of the form +((start1, end1), (start2, end2) ...). Then answer the question "was x present +in the original list?" in time O(log(# runs)). +""" + +import bisect + +def intranges_from_list(list_): + """Represent a list of integers as a sequence of ranges: + ((start_0, end_0), (start_1, end_1), ...), such that the original + integers are exactly those x such that start_i <= x < end_i for some i. + + Ranges are encoded as single integers (start << 32 | end), not as tuples. + """ + + sorted_list = sorted(list_) + ranges = [] + last_write = -1 + for i in range(len(sorted_list)): + if i+1 < len(sorted_list): + if sorted_list[i] == sorted_list[i+1]-1: + continue + current_range = sorted_list[last_write+1:i+1] + ranges.append(_encode_range(current_range[0], current_range[-1] + 1)) + last_write = i + + return tuple(ranges) + +def _encode_range(start, end): + return (start << 32) | end + +def _decode_range(r): + return (r >> 32), (r & ((1 << 32) - 1)) + + +def intranges_contain(int_, ranges): + """Determine if `int_` falls into one of the ranges in `ranges`.""" + tuple_ = _encode_range(int_, 0) + pos = bisect.bisect_left(ranges, tuple_) + # we could be immediately ahead of a tuple (start, end) + # with start < int_ <= end + if pos > 0: + left, right = _decode_range(ranges[pos-1]) + if left <= int_ < right: + return True + # or we could be immediately behind a tuple (int_, end) + if pos < len(ranges): + left, _ = _decode_range(ranges[pos]) + if left == int_: + return True + return False diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/package_data.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/package_data.py new file mode 100644 index 0000000..fc33139 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/package_data.py @@ -0,0 +1,2 @@ +__version__ = '2.6' + diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/uts46data.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/uts46data.py new file mode 100644 index 0000000..f9b3236 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/uts46data.py @@ -0,0 +1,7634 @@ +# This file is automatically generated by tools/idna-data +# vim: set fileencoding=utf-8 : + +"""IDNA Mapping Table from UTS46.""" + + +__version__ = "6.3.0" +def _seg_0(): + return [ + (0x0, '3'), + (0x1, '3'), + (0x2, '3'), + (0x3, '3'), + (0x4, '3'), + (0x5, '3'), + (0x6, '3'), + (0x7, '3'), + (0x8, '3'), + (0x9, '3'), + (0xA, '3'), + (0xB, '3'), + (0xC, '3'), + (0xD, '3'), + (0xE, '3'), + (0xF, '3'), + (0x10, '3'), + (0x11, '3'), + (0x12, '3'), + (0x13, '3'), + (0x14, '3'), + (0x15, '3'), + (0x16, '3'), + (0x17, '3'), + (0x18, '3'), + (0x19, '3'), + (0x1A, '3'), + (0x1B, '3'), + (0x1C, '3'), + (0x1D, '3'), + (0x1E, '3'), + (0x1F, '3'), + (0x20, '3'), + (0x21, '3'), + (0x22, '3'), + (0x23, '3'), + (0x24, '3'), + (0x25, '3'), + (0x26, '3'), + (0x27, '3'), + (0x28, '3'), + (0x29, '3'), + (0x2A, '3'), + (0x2B, '3'), + (0x2C, '3'), + (0x2D, 'V'), + (0x2E, 'V'), + (0x2F, '3'), + (0x30, 'V'), + (0x31, 'V'), + (0x32, 'V'), + (0x33, 'V'), + (0x34, 'V'), + (0x35, 'V'), + (0x36, 'V'), + (0x37, 'V'), + (0x38, 'V'), + (0x39, 'V'), + (0x3A, '3'), + (0x3B, '3'), + (0x3C, '3'), + (0x3D, '3'), + (0x3E, '3'), + (0x3F, '3'), + (0x40, '3'), + (0x41, 'M', u'a'), + (0x42, 'M', u'b'), + (0x43, 'M', u'c'), + (0x44, 'M', u'd'), + (0x45, 'M', u'e'), + (0x46, 'M', u'f'), + (0x47, 'M', u'g'), + (0x48, 'M', u'h'), + (0x49, 'M', u'i'), + (0x4A, 'M', u'j'), + (0x4B, 'M', u'k'), + (0x4C, 'M', u'l'), + (0x4D, 'M', u'm'), + (0x4E, 'M', u'n'), + (0x4F, 'M', u'o'), + (0x50, 'M', u'p'), + (0x51, 'M', u'q'), + (0x52, 'M', u'r'), + (0x53, 'M', u's'), + (0x54, 'M', u't'), + (0x55, 'M', u'u'), + (0x56, 'M', u'v'), + (0x57, 'M', u'w'), + (0x58, 'M', u'x'), + (0x59, 'M', u'y'), + (0x5A, 'M', u'z'), + (0x5B, '3'), + (0x5C, '3'), + (0x5D, '3'), + (0x5E, '3'), + (0x5F, '3'), + (0x60, '3'), + (0x61, 'V'), + (0x62, 'V'), + (0x63, 'V'), + ] + +def _seg_1(): + return [ + (0x64, 'V'), + (0x65, 'V'), + (0x66, 'V'), + (0x67, 'V'), + (0x68, 'V'), + (0x69, 'V'), + (0x6A, 'V'), + (0x6B, 'V'), + (0x6C, 'V'), + (0x6D, 'V'), + (0x6E, 'V'), + (0x6F, 'V'), + (0x70, 'V'), + (0x71, 'V'), + (0x72, 'V'), + (0x73, 'V'), + (0x74, 'V'), + (0x75, 'V'), + (0x76, 'V'), + (0x77, 'V'), + (0x78, 'V'), + (0x79, 'V'), + (0x7A, 'V'), + (0x7B, '3'), + (0x7C, '3'), + (0x7D, '3'), + (0x7E, '3'), + (0x7F, '3'), + (0x80, 'X'), + (0x81, 'X'), + (0x82, 'X'), + (0x83, 'X'), + (0x84, 'X'), + (0x85, 'X'), + (0x86, 'X'), + (0x87, 'X'), + (0x88, 'X'), + (0x89, 'X'), + (0x8A, 'X'), + (0x8B, 'X'), + (0x8C, 'X'), + (0x8D, 'X'), + (0x8E, 'X'), + (0x8F, 'X'), + (0x90, 'X'), + (0x91, 'X'), + (0x92, 'X'), + (0x93, 'X'), + (0x94, 'X'), + (0x95, 'X'), + (0x96, 'X'), + (0x97, 'X'), + (0x98, 'X'), + (0x99, 'X'), + (0x9A, 'X'), + (0x9B, 'X'), + (0x9C, 'X'), + (0x9D, 'X'), + (0x9E, 'X'), + (0x9F, 'X'), + (0xA0, '3', u' '), + (0xA1, 'V'), + (0xA2, 'V'), + (0xA3, 'V'), + (0xA4, 'V'), + (0xA5, 'V'), + (0xA6, 'V'), + (0xA7, 'V'), + (0xA8, '3', u' ̈'), + (0xA9, 'V'), + (0xAA, 'M', u'a'), + (0xAB, 'V'), + (0xAC, 'V'), + (0xAD, 'I'), + (0xAE, 'V'), + (0xAF, '3', u' ̄'), + (0xB0, 'V'), + (0xB1, 'V'), + (0xB2, 'M', u'2'), + (0xB3, 'M', u'3'), + (0xB4, '3', u' ́'), + (0xB5, 'M', u'μ'), + (0xB6, 'V'), + (0xB7, 'V'), + (0xB8, '3', u' ̧'), + (0xB9, 'M', u'1'), + (0xBA, 'M', u'o'), + (0xBB, 'V'), + (0xBC, 'M', u'1⁄4'), + (0xBD, 'M', u'1⁄2'), + (0xBE, 'M', u'3⁄4'), + (0xBF, 'V'), + (0xC0, 'M', u'à'), + (0xC1, 'M', u'á'), + (0xC2, 'M', u'â'), + (0xC3, 'M', u'ã'), + (0xC4, 'M', u'ä'), + (0xC5, 'M', u'å'), + (0xC6, 'M', u'æ'), + (0xC7, 'M', u'ç'), + ] + +def _seg_2(): + return [ + (0xC8, 'M', u'è'), + (0xC9, 'M', u'é'), + (0xCA, 'M', u'ê'), + (0xCB, 'M', u'ë'), + (0xCC, 'M', u'ì'), + (0xCD, 'M', u'í'), + (0xCE, 'M', u'î'), + (0xCF, 'M', u'ï'), + (0xD0, 'M', u'ð'), + (0xD1, 'M', u'ñ'), + (0xD2, 'M', u'ò'), + (0xD3, 'M', u'ó'), + (0xD4, 'M', u'ô'), + (0xD5, 'M', u'õ'), + (0xD6, 'M', u'ö'), + (0xD7, 'V'), + (0xD8, 'M', u'ø'), + (0xD9, 'M', u'ù'), + (0xDA, 'M', u'ú'), + (0xDB, 'M', u'û'), + (0xDC, 'M', u'ü'), + (0xDD, 'M', u'ý'), + (0xDE, 'M', u'þ'), + (0xDF, 'D', u'ss'), + (0xE0, 'V'), + (0xE1, 'V'), + (0xE2, 'V'), + (0xE3, 'V'), + (0xE4, 'V'), + (0xE5, 'V'), + (0xE6, 'V'), + (0xE7, 'V'), + (0xE8, 'V'), + (0xE9, 'V'), + (0xEA, 'V'), + (0xEB, 'V'), + (0xEC, 'V'), + (0xED, 'V'), + (0xEE, 'V'), + (0xEF, 'V'), + (0xF0, 'V'), + (0xF1, 'V'), + (0xF2, 'V'), + (0xF3, 'V'), + (0xF4, 'V'), + (0xF5, 'V'), + (0xF6, 'V'), + (0xF7, 'V'), + (0xF8, 'V'), + (0xF9, 'V'), + (0xFA, 'V'), + (0xFB, 'V'), + (0xFC, 'V'), + (0xFD, 'V'), + (0xFE, 'V'), + (0xFF, 'V'), + (0x100, 'M', u'ā'), + (0x101, 'V'), + (0x102, 'M', u'ă'), + (0x103, 'V'), + (0x104, 'M', u'ą'), + (0x105, 'V'), + (0x106, 'M', u'ć'), + (0x107, 'V'), + (0x108, 'M', u'ĉ'), + (0x109, 'V'), + (0x10A, 'M', u'ċ'), + (0x10B, 'V'), + (0x10C, 'M', u'č'), + (0x10D, 'V'), + (0x10E, 'M', u'ď'), + (0x10F, 'V'), + (0x110, 'M', u'đ'), + (0x111, 'V'), + (0x112, 'M', u'ē'), + (0x113, 'V'), + (0x114, 'M', u'ĕ'), + (0x115, 'V'), + (0x116, 'M', u'ė'), + (0x117, 'V'), + (0x118, 'M', u'ę'), + (0x119, 'V'), + (0x11A, 'M', u'ě'), + (0x11B, 'V'), + (0x11C, 'M', u'ĝ'), + (0x11D, 'V'), + (0x11E, 'M', u'ğ'), + (0x11F, 'V'), + (0x120, 'M', u'ġ'), + (0x121, 'V'), + (0x122, 'M', u'ģ'), + (0x123, 'V'), + (0x124, 'M', u'ĥ'), + (0x125, 'V'), + (0x126, 'M', u'ħ'), + (0x127, 'V'), + (0x128, 'M', u'ĩ'), + (0x129, 'V'), + (0x12A, 'M', u'ī'), + (0x12B, 'V'), + ] + +def _seg_3(): + return [ + (0x12C, 'M', u'ĭ'), + (0x12D, 'V'), + (0x12E, 'M', u'į'), + (0x12F, 'V'), + (0x130, 'M', u'i̇'), + (0x131, 'V'), + (0x132, 'M', u'ij'), + (0x134, 'M', u'ĵ'), + (0x135, 'V'), + (0x136, 'M', u'ķ'), + (0x137, 'V'), + (0x139, 'M', u'ĺ'), + (0x13A, 'V'), + (0x13B, 'M', u'ļ'), + (0x13C, 'V'), + (0x13D, 'M', u'ľ'), + (0x13E, 'V'), + (0x13F, 'M', u'l·'), + (0x141, 'M', u'ł'), + (0x142, 'V'), + (0x143, 'M', u'ń'), + (0x144, 'V'), + (0x145, 'M', u'ņ'), + (0x146, 'V'), + (0x147, 'M', u'ň'), + (0x148, 'V'), + (0x149, 'M', u'ʼn'), + (0x14A, 'M', u'ŋ'), + (0x14B, 'V'), + (0x14C, 'M', u'ō'), + (0x14D, 'V'), + (0x14E, 'M', u'ŏ'), + (0x14F, 'V'), + (0x150, 'M', u'ő'), + (0x151, 'V'), + (0x152, 'M', u'œ'), + (0x153, 'V'), + (0x154, 'M', u'ŕ'), + (0x155, 'V'), + (0x156, 'M', u'ŗ'), + (0x157, 'V'), + (0x158, 'M', u'ř'), + (0x159, 'V'), + (0x15A, 'M', u'ś'), + (0x15B, 'V'), + (0x15C, 'M', u'ŝ'), + (0x15D, 'V'), + (0x15E, 'M', u'ş'), + (0x15F, 'V'), + (0x160, 'M', u'š'), + (0x161, 'V'), + (0x162, 'M', u'ţ'), + (0x163, 'V'), + (0x164, 'M', u'ť'), + (0x165, 'V'), + (0x166, 'M', u'ŧ'), + (0x167, 'V'), + (0x168, 'M', u'ũ'), + (0x169, 'V'), + (0x16A, 'M', u'ū'), + (0x16B, 'V'), + (0x16C, 'M', u'ŭ'), + (0x16D, 'V'), + (0x16E, 'M', u'ů'), + (0x16F, 'V'), + (0x170, 'M', u'ű'), + (0x171, 'V'), + (0x172, 'M', u'ų'), + (0x173, 'V'), + (0x174, 'M', u'ŵ'), + (0x175, 'V'), + (0x176, 'M', u'ŷ'), + (0x177, 'V'), + (0x178, 'M', u'ÿ'), + (0x179, 'M', u'ź'), + (0x17A, 'V'), + (0x17B, 'M', u'ż'), + (0x17C, 'V'), + (0x17D, 'M', u'ž'), + (0x17E, 'V'), + (0x17F, 'M', u's'), + (0x180, 'V'), + (0x181, 'M', u'ɓ'), + (0x182, 'M', u'ƃ'), + (0x183, 'V'), + (0x184, 'M', u'ƅ'), + (0x185, 'V'), + (0x186, 'M', u'ɔ'), + (0x187, 'M', u'ƈ'), + (0x188, 'V'), + (0x189, 'M', u'ɖ'), + (0x18A, 'M', u'ɗ'), + (0x18B, 'M', u'ƌ'), + (0x18C, 'V'), + (0x18E, 'M', u'ǝ'), + (0x18F, 'M', u'ə'), + (0x190, 'M', u'ɛ'), + (0x191, 'M', u'ƒ'), + (0x192, 'V'), + (0x193, 'M', u'ɠ'), + ] + +def _seg_4(): + return [ + (0x194, 'M', u'ɣ'), + (0x195, 'V'), + (0x196, 'M', u'ɩ'), + (0x197, 'M', u'ɨ'), + (0x198, 'M', u'ƙ'), + (0x199, 'V'), + (0x19C, 'M', u'ɯ'), + (0x19D, 'M', u'ɲ'), + (0x19E, 'V'), + (0x19F, 'M', u'ɵ'), + (0x1A0, 'M', u'ơ'), + (0x1A1, 'V'), + (0x1A2, 'M', u'ƣ'), + (0x1A3, 'V'), + (0x1A4, 'M', u'ƥ'), + (0x1A5, 'V'), + (0x1A6, 'M', u'ʀ'), + (0x1A7, 'M', u'ƨ'), + (0x1A8, 'V'), + (0x1A9, 'M', u'ʃ'), + (0x1AA, 'V'), + (0x1AC, 'M', u'ƭ'), + (0x1AD, 'V'), + (0x1AE, 'M', u'ʈ'), + (0x1AF, 'M', u'ư'), + (0x1B0, 'V'), + (0x1B1, 'M', u'ʊ'), + (0x1B2, 'M', u'ʋ'), + (0x1B3, 'M', u'ƴ'), + (0x1B4, 'V'), + (0x1B5, 'M', u'ƶ'), + (0x1B6, 'V'), + (0x1B7, 'M', u'ʒ'), + (0x1B8, 'M', u'ƹ'), + (0x1B9, 'V'), + (0x1BC, 'M', u'ƽ'), + (0x1BD, 'V'), + (0x1C4, 'M', u'dž'), + (0x1C7, 'M', u'lj'), + (0x1CA, 'M', u'nj'), + (0x1CD, 'M', u'ǎ'), + (0x1CE, 'V'), + (0x1CF, 'M', u'ǐ'), + (0x1D0, 'V'), + (0x1D1, 'M', u'ǒ'), + (0x1D2, 'V'), + (0x1D3, 'M', u'ǔ'), + (0x1D4, 'V'), + (0x1D5, 'M', u'ǖ'), + (0x1D6, 'V'), + (0x1D7, 'M', u'ǘ'), + (0x1D8, 'V'), + (0x1D9, 'M', u'ǚ'), + (0x1DA, 'V'), + (0x1DB, 'M', u'ǜ'), + (0x1DC, 'V'), + (0x1DE, 'M', u'ǟ'), + (0x1DF, 'V'), + (0x1E0, 'M', u'ǡ'), + (0x1E1, 'V'), + (0x1E2, 'M', u'ǣ'), + (0x1E3, 'V'), + (0x1E4, 'M', u'ǥ'), + (0x1E5, 'V'), + (0x1E6, 'M', u'ǧ'), + (0x1E7, 'V'), + (0x1E8, 'M', u'ǩ'), + (0x1E9, 'V'), + (0x1EA, 'M', u'ǫ'), + (0x1EB, 'V'), + (0x1EC, 'M', u'ǭ'), + (0x1ED, 'V'), + (0x1EE, 'M', u'ǯ'), + (0x1EF, 'V'), + (0x1F1, 'M', u'dz'), + (0x1F4, 'M', u'ǵ'), + (0x1F5, 'V'), + (0x1F6, 'M', u'ƕ'), + (0x1F7, 'M', u'ƿ'), + (0x1F8, 'M', u'ǹ'), + (0x1F9, 'V'), + (0x1FA, 'M', u'ǻ'), + (0x1FB, 'V'), + (0x1FC, 'M', u'ǽ'), + (0x1FD, 'V'), + (0x1FE, 'M', u'ǿ'), + (0x1FF, 'V'), + (0x200, 'M', u'ȁ'), + (0x201, 'V'), + (0x202, 'M', u'ȃ'), + (0x203, 'V'), + (0x204, 'M', u'ȅ'), + (0x205, 'V'), + (0x206, 'M', u'ȇ'), + (0x207, 'V'), + (0x208, 'M', u'ȉ'), + (0x209, 'V'), + (0x20A, 'M', u'ȋ'), + (0x20B, 'V'), + (0x20C, 'M', u'ȍ'), + ] + +def _seg_5(): + return [ + (0x20D, 'V'), + (0x20E, 'M', u'ȏ'), + (0x20F, 'V'), + (0x210, 'M', u'ȑ'), + (0x211, 'V'), + (0x212, 'M', u'ȓ'), + (0x213, 'V'), + (0x214, 'M', u'ȕ'), + (0x215, 'V'), + (0x216, 'M', u'ȗ'), + (0x217, 'V'), + (0x218, 'M', u'ș'), + (0x219, 'V'), + (0x21A, 'M', u'ț'), + (0x21B, 'V'), + (0x21C, 'M', u'ȝ'), + (0x21D, 'V'), + (0x21E, 'M', u'ȟ'), + (0x21F, 'V'), + (0x220, 'M', u'ƞ'), + (0x221, 'V'), + (0x222, 'M', u'ȣ'), + (0x223, 'V'), + (0x224, 'M', u'ȥ'), + (0x225, 'V'), + (0x226, 'M', u'ȧ'), + (0x227, 'V'), + (0x228, 'M', u'ȩ'), + (0x229, 'V'), + (0x22A, 'M', u'ȫ'), + (0x22B, 'V'), + (0x22C, 'M', u'ȭ'), + (0x22D, 'V'), + (0x22E, 'M', u'ȯ'), + (0x22F, 'V'), + (0x230, 'M', u'ȱ'), + (0x231, 'V'), + (0x232, 'M', u'ȳ'), + (0x233, 'V'), + (0x23A, 'M', u'ⱥ'), + (0x23B, 'M', u'ȼ'), + (0x23C, 'V'), + (0x23D, 'M', u'ƚ'), + (0x23E, 'M', u'ⱦ'), + (0x23F, 'V'), + (0x241, 'M', u'ɂ'), + (0x242, 'V'), + (0x243, 'M', u'ƀ'), + (0x244, 'M', u'ʉ'), + (0x245, 'M', u'ʌ'), + (0x246, 'M', u'ɇ'), + (0x247, 'V'), + (0x248, 'M', u'ɉ'), + (0x249, 'V'), + (0x24A, 'M', u'ɋ'), + (0x24B, 'V'), + (0x24C, 'M', u'ɍ'), + (0x24D, 'V'), + (0x24E, 'M', u'ɏ'), + (0x24F, 'V'), + (0x2B0, 'M', u'h'), + (0x2B1, 'M', u'ɦ'), + (0x2B2, 'M', u'j'), + (0x2B3, 'M', u'r'), + (0x2B4, 'M', u'ɹ'), + (0x2B5, 'M', u'ɻ'), + (0x2B6, 'M', u'ʁ'), + (0x2B7, 'M', u'w'), + (0x2B8, 'M', u'y'), + (0x2B9, 'V'), + (0x2D8, '3', u' ̆'), + (0x2D9, '3', u' ̇'), + (0x2DA, '3', u' ̊'), + (0x2DB, '3', u' ̨'), + (0x2DC, '3', u' ̃'), + (0x2DD, '3', u' ̋'), + (0x2DE, 'V'), + (0x2E0, 'M', u'ɣ'), + (0x2E1, 'M', u'l'), + (0x2E2, 'M', u's'), + (0x2E3, 'M', u'x'), + (0x2E4, 'M', u'ʕ'), + (0x2E5, 'V'), + (0x340, 'M', u'̀'), + (0x341, 'M', u'́'), + (0x342, 'V'), + (0x343, 'M', u'̓'), + (0x344, 'M', u'̈́'), + (0x345, 'M', u'ι'), + (0x346, 'V'), + (0x34F, 'I'), + (0x350, 'V'), + (0x370, 'M', u'ͱ'), + (0x371, 'V'), + (0x372, 'M', u'ͳ'), + (0x373, 'V'), + (0x374, 'M', u'ʹ'), + (0x375, 'V'), + (0x376, 'M', u'ͷ'), + (0x377, 'V'), + ] + +def _seg_6(): + return [ + (0x378, 'X'), + (0x37A, '3', u' ι'), + (0x37B, 'V'), + (0x37E, '3', u';'), + (0x37F, 'X'), + (0x384, '3', u' ́'), + (0x385, '3', u' ̈́'), + (0x386, 'M', u'ά'), + (0x387, 'M', u'·'), + (0x388, 'M', u'έ'), + (0x389, 'M', u'ή'), + (0x38A, 'M', u'ί'), + (0x38B, 'X'), + (0x38C, 'M', u'ό'), + (0x38D, 'X'), + (0x38E, 'M', u'ύ'), + (0x38F, 'M', u'ώ'), + (0x390, 'V'), + (0x391, 'M', u'α'), + (0x392, 'M', u'β'), + (0x393, 'M', u'γ'), + (0x394, 'M', u'δ'), + (0x395, 'M', u'ε'), + (0x396, 'M', u'ζ'), + (0x397, 'M', u'η'), + (0x398, 'M', u'θ'), + (0x399, 'M', u'ι'), + (0x39A, 'M', u'κ'), + (0x39B, 'M', u'λ'), + (0x39C, 'M', u'μ'), + (0x39D, 'M', u'ν'), + (0x39E, 'M', u'ξ'), + (0x39F, 'M', u'ο'), + (0x3A0, 'M', u'π'), + (0x3A1, 'M', u'ρ'), + (0x3A2, 'X'), + (0x3A3, 'M', u'σ'), + (0x3A4, 'M', u'τ'), + (0x3A5, 'M', u'υ'), + (0x3A6, 'M', u'φ'), + (0x3A7, 'M', u'χ'), + (0x3A8, 'M', u'ψ'), + (0x3A9, 'M', u'ω'), + (0x3AA, 'M', u'ϊ'), + (0x3AB, 'M', u'ϋ'), + (0x3AC, 'V'), + (0x3C2, 'D', u'σ'), + (0x3C3, 'V'), + (0x3CF, 'M', u'ϗ'), + (0x3D0, 'M', u'β'), + (0x3D1, 'M', u'θ'), + (0x3D2, 'M', u'υ'), + (0x3D3, 'M', u'ύ'), + (0x3D4, 'M', u'ϋ'), + (0x3D5, 'M', u'φ'), + (0x3D6, 'M', u'π'), + (0x3D7, 'V'), + (0x3D8, 'M', u'ϙ'), + (0x3D9, 'V'), + (0x3DA, 'M', u'ϛ'), + (0x3DB, 'V'), + (0x3DC, 'M', u'ϝ'), + (0x3DD, 'V'), + (0x3DE, 'M', u'ϟ'), + (0x3DF, 'V'), + (0x3E0, 'M', u'ϡ'), + (0x3E1, 'V'), + (0x3E2, 'M', u'ϣ'), + (0x3E3, 'V'), + (0x3E4, 'M', u'ϥ'), + (0x3E5, 'V'), + (0x3E6, 'M', u'ϧ'), + (0x3E7, 'V'), + (0x3E8, 'M', u'ϩ'), + (0x3E9, 'V'), + (0x3EA, 'M', u'ϫ'), + (0x3EB, 'V'), + (0x3EC, 'M', u'ϭ'), + (0x3ED, 'V'), + (0x3EE, 'M', u'ϯ'), + (0x3EF, 'V'), + (0x3F0, 'M', u'κ'), + (0x3F1, 'M', u'ρ'), + (0x3F2, 'M', u'σ'), + (0x3F3, 'V'), + (0x3F4, 'M', u'θ'), + (0x3F5, 'M', u'ε'), + (0x3F6, 'V'), + (0x3F7, 'M', u'ϸ'), + (0x3F8, 'V'), + (0x3F9, 'M', u'σ'), + (0x3FA, 'M', u'ϻ'), + (0x3FB, 'V'), + (0x3FD, 'M', u'ͻ'), + (0x3FE, 'M', u'ͼ'), + (0x3FF, 'M', u'ͽ'), + (0x400, 'M', u'ѐ'), + (0x401, 'M', u'ё'), + (0x402, 'M', u'ђ'), + (0x403, 'M', u'ѓ'), + ] + +def _seg_7(): + return [ + (0x404, 'M', u'є'), + (0x405, 'M', u'ѕ'), + (0x406, 'M', u'і'), + (0x407, 'M', u'ї'), + (0x408, 'M', u'ј'), + (0x409, 'M', u'љ'), + (0x40A, 'M', u'њ'), + (0x40B, 'M', u'ћ'), + (0x40C, 'M', u'ќ'), + (0x40D, 'M', u'ѝ'), + (0x40E, 'M', u'ў'), + (0x40F, 'M', u'џ'), + (0x410, 'M', u'а'), + (0x411, 'M', u'б'), + (0x412, 'M', u'в'), + (0x413, 'M', u'г'), + (0x414, 'M', u'д'), + (0x415, 'M', u'е'), + (0x416, 'M', u'ж'), + (0x417, 'M', u'з'), + (0x418, 'M', u'и'), + (0x419, 'M', u'й'), + (0x41A, 'M', u'к'), + (0x41B, 'M', u'л'), + (0x41C, 'M', u'м'), + (0x41D, 'M', u'н'), + (0x41E, 'M', u'о'), + (0x41F, 'M', u'п'), + (0x420, 'M', u'р'), + (0x421, 'M', u'с'), + (0x422, 'M', u'т'), + (0x423, 'M', u'у'), + (0x424, 'M', u'ф'), + (0x425, 'M', u'х'), + (0x426, 'M', u'ц'), + (0x427, 'M', u'ч'), + (0x428, 'M', u'ш'), + (0x429, 'M', u'щ'), + (0x42A, 'M', u'ъ'), + (0x42B, 'M', u'ы'), + (0x42C, 'M', u'ь'), + (0x42D, 'M', u'э'), + (0x42E, 'M', u'ю'), + (0x42F, 'M', u'я'), + (0x430, 'V'), + (0x460, 'M', u'ѡ'), + (0x461, 'V'), + (0x462, 'M', u'ѣ'), + (0x463, 'V'), + (0x464, 'M', u'ѥ'), + (0x465, 'V'), + (0x466, 'M', u'ѧ'), + (0x467, 'V'), + (0x468, 'M', u'ѩ'), + (0x469, 'V'), + (0x46A, 'M', u'ѫ'), + (0x46B, 'V'), + (0x46C, 'M', u'ѭ'), + (0x46D, 'V'), + (0x46E, 'M', u'ѯ'), + (0x46F, 'V'), + (0x470, 'M', u'ѱ'), + (0x471, 'V'), + (0x472, 'M', u'ѳ'), + (0x473, 'V'), + (0x474, 'M', u'ѵ'), + (0x475, 'V'), + (0x476, 'M', u'ѷ'), + (0x477, 'V'), + (0x478, 'M', u'ѹ'), + (0x479, 'V'), + (0x47A, 'M', u'ѻ'), + (0x47B, 'V'), + (0x47C, 'M', u'ѽ'), + (0x47D, 'V'), + (0x47E, 'M', u'ѿ'), + (0x47F, 'V'), + (0x480, 'M', u'ҁ'), + (0x481, 'V'), + (0x48A, 'M', u'ҋ'), + (0x48B, 'V'), + (0x48C, 'M', u'ҍ'), + (0x48D, 'V'), + (0x48E, 'M', u'ҏ'), + (0x48F, 'V'), + (0x490, 'M', u'ґ'), + (0x491, 'V'), + (0x492, 'M', u'ғ'), + (0x493, 'V'), + (0x494, 'M', u'ҕ'), + (0x495, 'V'), + (0x496, 'M', u'җ'), + (0x497, 'V'), + (0x498, 'M', u'ҙ'), + (0x499, 'V'), + (0x49A, 'M', u'қ'), + (0x49B, 'V'), + (0x49C, 'M', u'ҝ'), + (0x49D, 'V'), + (0x49E, 'M', u'ҟ'), + ] + +def _seg_8(): + return [ + (0x49F, 'V'), + (0x4A0, 'M', u'ҡ'), + (0x4A1, 'V'), + (0x4A2, 'M', u'ң'), + (0x4A3, 'V'), + (0x4A4, 'M', u'ҥ'), + (0x4A5, 'V'), + (0x4A6, 'M', u'ҧ'), + (0x4A7, 'V'), + (0x4A8, 'M', u'ҩ'), + (0x4A9, 'V'), + (0x4AA, 'M', u'ҫ'), + (0x4AB, 'V'), + (0x4AC, 'M', u'ҭ'), + (0x4AD, 'V'), + (0x4AE, 'M', u'ү'), + (0x4AF, 'V'), + (0x4B0, 'M', u'ұ'), + (0x4B1, 'V'), + (0x4B2, 'M', u'ҳ'), + (0x4B3, 'V'), + (0x4B4, 'M', u'ҵ'), + (0x4B5, 'V'), + (0x4B6, 'M', u'ҷ'), + (0x4B7, 'V'), + (0x4B8, 'M', u'ҹ'), + (0x4B9, 'V'), + (0x4BA, 'M', u'һ'), + (0x4BB, 'V'), + (0x4BC, 'M', u'ҽ'), + (0x4BD, 'V'), + (0x4BE, 'M', u'ҿ'), + (0x4BF, 'V'), + (0x4C0, 'X'), + (0x4C1, 'M', u'ӂ'), + (0x4C2, 'V'), + (0x4C3, 'M', u'ӄ'), + (0x4C4, 'V'), + (0x4C5, 'M', u'ӆ'), + (0x4C6, 'V'), + (0x4C7, 'M', u'ӈ'), + (0x4C8, 'V'), + (0x4C9, 'M', u'ӊ'), + (0x4CA, 'V'), + (0x4CB, 'M', u'ӌ'), + (0x4CC, 'V'), + (0x4CD, 'M', u'ӎ'), + (0x4CE, 'V'), + (0x4D0, 'M', u'ӑ'), + (0x4D1, 'V'), + (0x4D2, 'M', u'ӓ'), + (0x4D3, 'V'), + (0x4D4, 'M', u'ӕ'), + (0x4D5, 'V'), + (0x4D6, 'M', u'ӗ'), + (0x4D7, 'V'), + (0x4D8, 'M', u'ә'), + (0x4D9, 'V'), + (0x4DA, 'M', u'ӛ'), + (0x4DB, 'V'), + (0x4DC, 'M', u'ӝ'), + (0x4DD, 'V'), + (0x4DE, 'M', u'ӟ'), + (0x4DF, 'V'), + (0x4E0, 'M', u'ӡ'), + (0x4E1, 'V'), + (0x4E2, 'M', u'ӣ'), + (0x4E3, 'V'), + (0x4E4, 'M', u'ӥ'), + (0x4E5, 'V'), + (0x4E6, 'M', u'ӧ'), + (0x4E7, 'V'), + (0x4E8, 'M', u'ө'), + (0x4E9, 'V'), + (0x4EA, 'M', u'ӫ'), + (0x4EB, 'V'), + (0x4EC, 'M', u'ӭ'), + (0x4ED, 'V'), + (0x4EE, 'M', u'ӯ'), + (0x4EF, 'V'), + (0x4F0, 'M', u'ӱ'), + (0x4F1, 'V'), + (0x4F2, 'M', u'ӳ'), + (0x4F3, 'V'), + (0x4F4, 'M', u'ӵ'), + (0x4F5, 'V'), + (0x4F6, 'M', u'ӷ'), + (0x4F7, 'V'), + (0x4F8, 'M', u'ӹ'), + (0x4F9, 'V'), + (0x4FA, 'M', u'ӻ'), + (0x4FB, 'V'), + (0x4FC, 'M', u'ӽ'), + (0x4FD, 'V'), + (0x4FE, 'M', u'ӿ'), + (0x4FF, 'V'), + (0x500, 'M', u'ԁ'), + (0x501, 'V'), + (0x502, 'M', u'ԃ'), + (0x503, 'V'), + ] + +def _seg_9(): + return [ + (0x504, 'M', u'ԅ'), + (0x505, 'V'), + (0x506, 'M', u'ԇ'), + (0x507, 'V'), + (0x508, 'M', u'ԉ'), + (0x509, 'V'), + (0x50A, 'M', u'ԋ'), + (0x50B, 'V'), + (0x50C, 'M', u'ԍ'), + (0x50D, 'V'), + (0x50E, 'M', u'ԏ'), + (0x50F, 'V'), + (0x510, 'M', u'ԑ'), + (0x511, 'V'), + (0x512, 'M', u'ԓ'), + (0x513, 'V'), + (0x514, 'M', u'ԕ'), + (0x515, 'V'), + (0x516, 'M', u'ԗ'), + (0x517, 'V'), + (0x518, 'M', u'ԙ'), + (0x519, 'V'), + (0x51A, 'M', u'ԛ'), + (0x51B, 'V'), + (0x51C, 'M', u'ԝ'), + (0x51D, 'V'), + (0x51E, 'M', u'ԟ'), + (0x51F, 'V'), + (0x520, 'M', u'ԡ'), + (0x521, 'V'), + (0x522, 'M', u'ԣ'), + (0x523, 'V'), + (0x524, 'M', u'ԥ'), + (0x525, 'V'), + (0x526, 'M', u'ԧ'), + (0x527, 'V'), + (0x528, 'X'), + (0x531, 'M', u'ա'), + (0x532, 'M', u'բ'), + (0x533, 'M', u'գ'), + (0x534, 'M', u'դ'), + (0x535, 'M', u'ե'), + (0x536, 'M', u'զ'), + (0x537, 'M', u'է'), + (0x538, 'M', u'ը'), + (0x539, 'M', u'թ'), + (0x53A, 'M', u'ժ'), + (0x53B, 'M', u'ի'), + (0x53C, 'M', u'լ'), + (0x53D, 'M', u'խ'), + (0x53E, 'M', u'ծ'), + (0x53F, 'M', u'կ'), + (0x540, 'M', u'հ'), + (0x541, 'M', u'ձ'), + (0x542, 'M', u'ղ'), + (0x543, 'M', u'ճ'), + (0x544, 'M', u'մ'), + (0x545, 'M', u'յ'), + (0x546, 'M', u'ն'), + (0x547, 'M', u'շ'), + (0x548, 'M', u'ո'), + (0x549, 'M', u'չ'), + (0x54A, 'M', u'պ'), + (0x54B, 'M', u'ջ'), + (0x54C, 'M', u'ռ'), + (0x54D, 'M', u'ս'), + (0x54E, 'M', u'վ'), + (0x54F, 'M', u'տ'), + (0x550, 'M', u'ր'), + (0x551, 'M', u'ց'), + (0x552, 'M', u'ւ'), + (0x553, 'M', u'փ'), + (0x554, 'M', u'ք'), + (0x555, 'M', u'օ'), + (0x556, 'M', u'ֆ'), + (0x557, 'X'), + (0x559, 'V'), + (0x560, 'X'), + (0x561, 'V'), + (0x587, 'M', u'եւ'), + (0x588, 'X'), + (0x589, 'V'), + (0x58B, 'X'), + (0x58F, 'V'), + (0x590, 'X'), + (0x591, 'V'), + (0x5C8, 'X'), + (0x5D0, 'V'), + (0x5EB, 'X'), + (0x5F0, 'V'), + (0x5F5, 'X'), + (0x606, 'V'), + (0x61C, 'X'), + (0x61E, 'V'), + (0x675, 'M', u'اٴ'), + (0x676, 'M', u'وٴ'), + (0x677, 'M', u'ۇٴ'), + (0x678, 'M', u'يٴ'), + (0x679, 'V'), + (0x6DD, 'X'), + ] + +def _seg_10(): + return [ + (0x6DE, 'V'), + (0x70E, 'X'), + (0x710, 'V'), + (0x74B, 'X'), + (0x74D, 'V'), + (0x7B2, 'X'), + (0x7C0, 'V'), + (0x7FB, 'X'), + (0x800, 'V'), + (0x82E, 'X'), + (0x830, 'V'), + (0x83F, 'X'), + (0x840, 'V'), + (0x85C, 'X'), + (0x85E, 'V'), + (0x85F, 'X'), + (0x8A0, 'V'), + (0x8A1, 'X'), + (0x8A2, 'V'), + (0x8AD, 'X'), + (0x8E4, 'V'), + (0x8FF, 'X'), + (0x900, 'V'), + (0x958, 'M', u'क़'), + (0x959, 'M', u'ख़'), + (0x95A, 'M', u'ग़'), + (0x95B, 'M', u'ज़'), + (0x95C, 'M', u'ड़'), + (0x95D, 'M', u'ढ़'), + (0x95E, 'M', u'फ़'), + (0x95F, 'M', u'य़'), + (0x960, 'V'), + (0x978, 'X'), + (0x979, 'V'), + (0x980, 'X'), + (0x981, 'V'), + (0x984, 'X'), + (0x985, 'V'), + (0x98D, 'X'), + (0x98F, 'V'), + (0x991, 'X'), + (0x993, 'V'), + (0x9A9, 'X'), + (0x9AA, 'V'), + (0x9B1, 'X'), + (0x9B2, 'V'), + (0x9B3, 'X'), + (0x9B6, 'V'), + (0x9BA, 'X'), + (0x9BC, 'V'), + (0x9C5, 'X'), + (0x9C7, 'V'), + (0x9C9, 'X'), + (0x9CB, 'V'), + (0x9CF, 'X'), + (0x9D7, 'V'), + (0x9D8, 'X'), + (0x9DC, 'M', u'ড়'), + (0x9DD, 'M', u'ঢ়'), + (0x9DE, 'X'), + (0x9DF, 'M', u'য়'), + (0x9E0, 'V'), + (0x9E4, 'X'), + (0x9E6, 'V'), + (0x9FC, 'X'), + (0xA01, 'V'), + (0xA04, 'X'), + (0xA05, 'V'), + (0xA0B, 'X'), + (0xA0F, 'V'), + (0xA11, 'X'), + (0xA13, 'V'), + (0xA29, 'X'), + (0xA2A, 'V'), + (0xA31, 'X'), + (0xA32, 'V'), + (0xA33, 'M', u'ਲ਼'), + (0xA34, 'X'), + (0xA35, 'V'), + (0xA36, 'M', u'ਸ਼'), + (0xA37, 'X'), + (0xA38, 'V'), + (0xA3A, 'X'), + (0xA3C, 'V'), + (0xA3D, 'X'), + (0xA3E, 'V'), + (0xA43, 'X'), + (0xA47, 'V'), + (0xA49, 'X'), + (0xA4B, 'V'), + (0xA4E, 'X'), + (0xA51, 'V'), + (0xA52, 'X'), + (0xA59, 'M', u'ਖ਼'), + (0xA5A, 'M', u'ਗ਼'), + (0xA5B, 'M', u'ਜ਼'), + (0xA5C, 'V'), + (0xA5D, 'X'), + (0xA5E, 'M', u'ਫ਼'), + (0xA5F, 'X'), + ] + +def _seg_11(): + return [ + (0xA66, 'V'), + (0xA76, 'X'), + (0xA81, 'V'), + (0xA84, 'X'), + (0xA85, 'V'), + (0xA8E, 'X'), + (0xA8F, 'V'), + (0xA92, 'X'), + (0xA93, 'V'), + (0xAA9, 'X'), + (0xAAA, 'V'), + (0xAB1, 'X'), + (0xAB2, 'V'), + (0xAB4, 'X'), + (0xAB5, 'V'), + (0xABA, 'X'), + (0xABC, 'V'), + (0xAC6, 'X'), + (0xAC7, 'V'), + (0xACA, 'X'), + (0xACB, 'V'), + (0xACE, 'X'), + (0xAD0, 'V'), + (0xAD1, 'X'), + (0xAE0, 'V'), + (0xAE4, 'X'), + (0xAE6, 'V'), + (0xAF2, 'X'), + (0xB01, 'V'), + (0xB04, 'X'), + (0xB05, 'V'), + (0xB0D, 'X'), + (0xB0F, 'V'), + (0xB11, 'X'), + (0xB13, 'V'), + (0xB29, 'X'), + (0xB2A, 'V'), + (0xB31, 'X'), + (0xB32, 'V'), + (0xB34, 'X'), + (0xB35, 'V'), + (0xB3A, 'X'), + (0xB3C, 'V'), + (0xB45, 'X'), + (0xB47, 'V'), + (0xB49, 'X'), + (0xB4B, 'V'), + (0xB4E, 'X'), + (0xB56, 'V'), + (0xB58, 'X'), + (0xB5C, 'M', u'ଡ଼'), + (0xB5D, 'M', u'ଢ଼'), + (0xB5E, 'X'), + (0xB5F, 'V'), + (0xB64, 'X'), + (0xB66, 'V'), + (0xB78, 'X'), + (0xB82, 'V'), + (0xB84, 'X'), + (0xB85, 'V'), + (0xB8B, 'X'), + (0xB8E, 'V'), + (0xB91, 'X'), + (0xB92, 'V'), + (0xB96, 'X'), + (0xB99, 'V'), + (0xB9B, 'X'), + (0xB9C, 'V'), + (0xB9D, 'X'), + (0xB9E, 'V'), + (0xBA0, 'X'), + (0xBA3, 'V'), + (0xBA5, 'X'), + (0xBA8, 'V'), + (0xBAB, 'X'), + (0xBAE, 'V'), + (0xBBA, 'X'), + (0xBBE, 'V'), + (0xBC3, 'X'), + (0xBC6, 'V'), + (0xBC9, 'X'), + (0xBCA, 'V'), + (0xBCE, 'X'), + (0xBD0, 'V'), + (0xBD1, 'X'), + (0xBD7, 'V'), + (0xBD8, 'X'), + (0xBE6, 'V'), + (0xBFB, 'X'), + (0xC01, 'V'), + (0xC04, 'X'), + (0xC05, 'V'), + (0xC0D, 'X'), + (0xC0E, 'V'), + (0xC11, 'X'), + (0xC12, 'V'), + (0xC29, 'X'), + (0xC2A, 'V'), + (0xC34, 'X'), + (0xC35, 'V'), + ] + +def _seg_12(): + return [ + (0xC3A, 'X'), + (0xC3D, 'V'), + (0xC45, 'X'), + (0xC46, 'V'), + (0xC49, 'X'), + (0xC4A, 'V'), + (0xC4E, 'X'), + (0xC55, 'V'), + (0xC57, 'X'), + (0xC58, 'V'), + (0xC5A, 'X'), + (0xC60, 'V'), + (0xC64, 'X'), + (0xC66, 'V'), + (0xC70, 'X'), + (0xC78, 'V'), + (0xC80, 'X'), + (0xC82, 'V'), + (0xC84, 'X'), + (0xC85, 'V'), + (0xC8D, 'X'), + (0xC8E, 'V'), + (0xC91, 'X'), + (0xC92, 'V'), + (0xCA9, 'X'), + (0xCAA, 'V'), + (0xCB4, 'X'), + (0xCB5, 'V'), + (0xCBA, 'X'), + (0xCBC, 'V'), + (0xCC5, 'X'), + (0xCC6, 'V'), + (0xCC9, 'X'), + (0xCCA, 'V'), + (0xCCE, 'X'), + (0xCD5, 'V'), + (0xCD7, 'X'), + (0xCDE, 'V'), + (0xCDF, 'X'), + (0xCE0, 'V'), + (0xCE4, 'X'), + (0xCE6, 'V'), + (0xCF0, 'X'), + (0xCF1, 'V'), + (0xCF3, 'X'), + (0xD02, 'V'), + (0xD04, 'X'), + (0xD05, 'V'), + (0xD0D, 'X'), + (0xD0E, 'V'), + (0xD11, 'X'), + (0xD12, 'V'), + (0xD3B, 'X'), + (0xD3D, 'V'), + (0xD45, 'X'), + (0xD46, 'V'), + (0xD49, 'X'), + (0xD4A, 'V'), + (0xD4F, 'X'), + (0xD57, 'V'), + (0xD58, 'X'), + (0xD60, 'V'), + (0xD64, 'X'), + (0xD66, 'V'), + (0xD76, 'X'), + (0xD79, 'V'), + (0xD80, 'X'), + (0xD82, 'V'), + (0xD84, 'X'), + (0xD85, 'V'), + (0xD97, 'X'), + (0xD9A, 'V'), + (0xDB2, 'X'), + (0xDB3, 'V'), + (0xDBC, 'X'), + (0xDBD, 'V'), + (0xDBE, 'X'), + (0xDC0, 'V'), + (0xDC7, 'X'), + (0xDCA, 'V'), + (0xDCB, 'X'), + (0xDCF, 'V'), + (0xDD5, 'X'), + (0xDD6, 'V'), + (0xDD7, 'X'), + (0xDD8, 'V'), + (0xDE0, 'X'), + (0xDF2, 'V'), + (0xDF5, 'X'), + (0xE01, 'V'), + (0xE33, 'M', u'ํา'), + (0xE34, 'V'), + (0xE3B, 'X'), + (0xE3F, 'V'), + (0xE5C, 'X'), + (0xE81, 'V'), + (0xE83, 'X'), + (0xE84, 'V'), + (0xE85, 'X'), + (0xE87, 'V'), + ] + +def _seg_13(): + return [ + (0xE89, 'X'), + (0xE8A, 'V'), + (0xE8B, 'X'), + (0xE8D, 'V'), + (0xE8E, 'X'), + (0xE94, 'V'), + (0xE98, 'X'), + (0xE99, 'V'), + (0xEA0, 'X'), + (0xEA1, 'V'), + (0xEA4, 'X'), + (0xEA5, 'V'), + (0xEA6, 'X'), + (0xEA7, 'V'), + (0xEA8, 'X'), + (0xEAA, 'V'), + (0xEAC, 'X'), + (0xEAD, 'V'), + (0xEB3, 'M', u'ໍາ'), + (0xEB4, 'V'), + (0xEBA, 'X'), + (0xEBB, 'V'), + (0xEBE, 'X'), + (0xEC0, 'V'), + (0xEC5, 'X'), + (0xEC6, 'V'), + (0xEC7, 'X'), + (0xEC8, 'V'), + (0xECE, 'X'), + (0xED0, 'V'), + (0xEDA, 'X'), + (0xEDC, 'M', u'ຫນ'), + (0xEDD, 'M', u'ຫມ'), + (0xEDE, 'V'), + (0xEE0, 'X'), + (0xF00, 'V'), + (0xF0C, 'M', u'་'), + (0xF0D, 'V'), + (0xF43, 'M', u'གྷ'), + (0xF44, 'V'), + (0xF48, 'X'), + (0xF49, 'V'), + (0xF4D, 'M', u'ཌྷ'), + (0xF4E, 'V'), + (0xF52, 'M', u'དྷ'), + (0xF53, 'V'), + (0xF57, 'M', u'བྷ'), + (0xF58, 'V'), + (0xF5C, 'M', u'ཛྷ'), + (0xF5D, 'V'), + (0xF69, 'M', u'ཀྵ'), + (0xF6A, 'V'), + (0xF6D, 'X'), + (0xF71, 'V'), + (0xF73, 'M', u'ཱི'), + (0xF74, 'V'), + (0xF75, 'M', u'ཱུ'), + (0xF76, 'M', u'ྲྀ'), + (0xF77, 'M', u'ྲཱྀ'), + (0xF78, 'M', u'ླྀ'), + (0xF79, 'M', u'ླཱྀ'), + (0xF7A, 'V'), + (0xF81, 'M', u'ཱྀ'), + (0xF82, 'V'), + (0xF93, 'M', u'ྒྷ'), + (0xF94, 'V'), + (0xF98, 'X'), + (0xF99, 'V'), + (0xF9D, 'M', u'ྜྷ'), + (0xF9E, 'V'), + (0xFA2, 'M', u'ྡྷ'), + (0xFA3, 'V'), + (0xFA7, 'M', u'ྦྷ'), + (0xFA8, 'V'), + (0xFAC, 'M', u'ྫྷ'), + (0xFAD, 'V'), + (0xFB9, 'M', u'ྐྵ'), + (0xFBA, 'V'), + (0xFBD, 'X'), + (0xFBE, 'V'), + (0xFCD, 'X'), + (0xFCE, 'V'), + (0xFDB, 'X'), + (0x1000, 'V'), + (0x10A0, 'X'), + (0x10C7, 'M', u'ⴧ'), + (0x10C8, 'X'), + (0x10CD, 'M', u'ⴭ'), + (0x10CE, 'X'), + (0x10D0, 'V'), + (0x10FC, 'M', u'ნ'), + (0x10FD, 'V'), + (0x115F, 'X'), + (0x1161, 'V'), + (0x1249, 'X'), + (0x124A, 'V'), + (0x124E, 'X'), + (0x1250, 'V'), + (0x1257, 'X'), + (0x1258, 'V'), + ] + +def _seg_14(): + return [ + (0x1259, 'X'), + (0x125A, 'V'), + (0x125E, 'X'), + (0x1260, 'V'), + (0x1289, 'X'), + (0x128A, 'V'), + (0x128E, 'X'), + (0x1290, 'V'), + (0x12B1, 'X'), + (0x12B2, 'V'), + (0x12B6, 'X'), + (0x12B8, 'V'), + (0x12BF, 'X'), + (0x12C0, 'V'), + (0x12C1, 'X'), + (0x12C2, 'V'), + (0x12C6, 'X'), + (0x12C8, 'V'), + (0x12D7, 'X'), + (0x12D8, 'V'), + (0x1311, 'X'), + (0x1312, 'V'), + (0x1316, 'X'), + (0x1318, 'V'), + (0x135B, 'X'), + (0x135D, 'V'), + (0x137D, 'X'), + (0x1380, 'V'), + (0x139A, 'X'), + (0x13A0, 'V'), + (0x13F5, 'X'), + (0x1400, 'V'), + (0x1680, 'X'), + (0x1681, 'V'), + (0x169D, 'X'), + (0x16A0, 'V'), + (0x16F1, 'X'), + (0x1700, 'V'), + (0x170D, 'X'), + (0x170E, 'V'), + (0x1715, 'X'), + (0x1720, 'V'), + (0x1737, 'X'), + (0x1740, 'V'), + (0x1754, 'X'), + (0x1760, 'V'), + (0x176D, 'X'), + (0x176E, 'V'), + (0x1771, 'X'), + (0x1772, 'V'), + (0x1774, 'X'), + (0x1780, 'V'), + (0x17B4, 'X'), + (0x17B6, 'V'), + (0x17DE, 'X'), + (0x17E0, 'V'), + (0x17EA, 'X'), + (0x17F0, 'V'), + (0x17FA, 'X'), + (0x1800, 'V'), + (0x1806, 'X'), + (0x1807, 'V'), + (0x180B, 'I'), + (0x180E, 'X'), + (0x1810, 'V'), + (0x181A, 'X'), + (0x1820, 'V'), + (0x1878, 'X'), + (0x1880, 'V'), + (0x18AB, 'X'), + (0x18B0, 'V'), + (0x18F6, 'X'), + (0x1900, 'V'), + (0x191D, 'X'), + (0x1920, 'V'), + (0x192C, 'X'), + (0x1930, 'V'), + (0x193C, 'X'), + (0x1940, 'V'), + (0x1941, 'X'), + (0x1944, 'V'), + (0x196E, 'X'), + (0x1970, 'V'), + (0x1975, 'X'), + (0x1980, 'V'), + (0x19AC, 'X'), + (0x19B0, 'V'), + (0x19CA, 'X'), + (0x19D0, 'V'), + (0x19DB, 'X'), + (0x19DE, 'V'), + (0x1A1C, 'X'), + (0x1A1E, 'V'), + (0x1A5F, 'X'), + (0x1A60, 'V'), + (0x1A7D, 'X'), + (0x1A7F, 'V'), + (0x1A8A, 'X'), + (0x1A90, 'V'), + (0x1A9A, 'X'), + ] + +def _seg_15(): + return [ + (0x1AA0, 'V'), + (0x1AAE, 'X'), + (0x1B00, 'V'), + (0x1B4C, 'X'), + (0x1B50, 'V'), + (0x1B7D, 'X'), + (0x1B80, 'V'), + (0x1BF4, 'X'), + (0x1BFC, 'V'), + (0x1C38, 'X'), + (0x1C3B, 'V'), + (0x1C4A, 'X'), + (0x1C4D, 'V'), + (0x1C80, 'X'), + (0x1CC0, 'V'), + (0x1CC8, 'X'), + (0x1CD0, 'V'), + (0x1CF7, 'X'), + (0x1D00, 'V'), + (0x1D2C, 'M', u'a'), + (0x1D2D, 'M', u'æ'), + (0x1D2E, 'M', u'b'), + (0x1D2F, 'V'), + (0x1D30, 'M', u'd'), + (0x1D31, 'M', u'e'), + (0x1D32, 'M', u'ǝ'), + (0x1D33, 'M', u'g'), + (0x1D34, 'M', u'h'), + (0x1D35, 'M', u'i'), + (0x1D36, 'M', u'j'), + (0x1D37, 'M', u'k'), + (0x1D38, 'M', u'l'), + (0x1D39, 'M', u'm'), + (0x1D3A, 'M', u'n'), + (0x1D3B, 'V'), + (0x1D3C, 'M', u'o'), + (0x1D3D, 'M', u'ȣ'), + (0x1D3E, 'M', u'p'), + (0x1D3F, 'M', u'r'), + (0x1D40, 'M', u't'), + (0x1D41, 'M', u'u'), + (0x1D42, 'M', u'w'), + (0x1D43, 'M', u'a'), + (0x1D44, 'M', u'ɐ'), + (0x1D45, 'M', u'ɑ'), + (0x1D46, 'M', u'ᴂ'), + (0x1D47, 'M', u'b'), + (0x1D48, 'M', u'd'), + (0x1D49, 'M', u'e'), + (0x1D4A, 'M', u'ə'), + (0x1D4B, 'M', u'ɛ'), + (0x1D4C, 'M', u'ɜ'), + (0x1D4D, 'M', u'g'), + (0x1D4E, 'V'), + (0x1D4F, 'M', u'k'), + (0x1D50, 'M', u'm'), + (0x1D51, 'M', u'ŋ'), + (0x1D52, 'M', u'o'), + (0x1D53, 'M', u'ɔ'), + (0x1D54, 'M', u'ᴖ'), + (0x1D55, 'M', u'ᴗ'), + (0x1D56, 'M', u'p'), + (0x1D57, 'M', u't'), + (0x1D58, 'M', u'u'), + (0x1D59, 'M', u'ᴝ'), + (0x1D5A, 'M', u'ɯ'), + (0x1D5B, 'M', u'v'), + (0x1D5C, 'M', u'ᴥ'), + (0x1D5D, 'M', u'β'), + (0x1D5E, 'M', u'γ'), + (0x1D5F, 'M', u'δ'), + (0x1D60, 'M', u'φ'), + (0x1D61, 'M', u'χ'), + (0x1D62, 'M', u'i'), + (0x1D63, 'M', u'r'), + (0x1D64, 'M', u'u'), + (0x1D65, 'M', u'v'), + (0x1D66, 'M', u'β'), + (0x1D67, 'M', u'γ'), + (0x1D68, 'M', u'ρ'), + (0x1D69, 'M', u'φ'), + (0x1D6A, 'M', u'χ'), + (0x1D6B, 'V'), + (0x1D78, 'M', u'н'), + (0x1D79, 'V'), + (0x1D9B, 'M', u'ɒ'), + (0x1D9C, 'M', u'c'), + (0x1D9D, 'M', u'ɕ'), + (0x1D9E, 'M', u'ð'), + (0x1D9F, 'M', u'ɜ'), + (0x1DA0, 'M', u'f'), + (0x1DA1, 'M', u'ɟ'), + (0x1DA2, 'M', u'ɡ'), + (0x1DA3, 'M', u'ɥ'), + (0x1DA4, 'M', u'ɨ'), + (0x1DA5, 'M', u'ɩ'), + (0x1DA6, 'M', u'ɪ'), + (0x1DA7, 'M', u'ᵻ'), + (0x1DA8, 'M', u'ʝ'), + (0x1DA9, 'M', u'ɭ'), + ] + +def _seg_16(): + return [ + (0x1DAA, 'M', u'ᶅ'), + (0x1DAB, 'M', u'ʟ'), + (0x1DAC, 'M', u'ɱ'), + (0x1DAD, 'M', u'ɰ'), + (0x1DAE, 'M', u'ɲ'), + (0x1DAF, 'M', u'ɳ'), + (0x1DB0, 'M', u'ɴ'), + (0x1DB1, 'M', u'ɵ'), + (0x1DB2, 'M', u'ɸ'), + (0x1DB3, 'M', u'ʂ'), + (0x1DB4, 'M', u'ʃ'), + (0x1DB5, 'M', u'ƫ'), + (0x1DB6, 'M', u'ʉ'), + (0x1DB7, 'M', u'ʊ'), + (0x1DB8, 'M', u'ᴜ'), + (0x1DB9, 'M', u'ʋ'), + (0x1DBA, 'M', u'ʌ'), + (0x1DBB, 'M', u'z'), + (0x1DBC, 'M', u'ʐ'), + (0x1DBD, 'M', u'ʑ'), + (0x1DBE, 'M', u'ʒ'), + (0x1DBF, 'M', u'θ'), + (0x1DC0, 'V'), + (0x1DE7, 'X'), + (0x1DFC, 'V'), + (0x1E00, 'M', u'ḁ'), + (0x1E01, 'V'), + (0x1E02, 'M', u'ḃ'), + (0x1E03, 'V'), + (0x1E04, 'M', u'ḅ'), + (0x1E05, 'V'), + (0x1E06, 'M', u'ḇ'), + (0x1E07, 'V'), + (0x1E08, 'M', u'ḉ'), + (0x1E09, 'V'), + (0x1E0A, 'M', u'ḋ'), + (0x1E0B, 'V'), + (0x1E0C, 'M', u'ḍ'), + (0x1E0D, 'V'), + (0x1E0E, 'M', u'ḏ'), + (0x1E0F, 'V'), + (0x1E10, 'M', u'ḑ'), + (0x1E11, 'V'), + (0x1E12, 'M', u'ḓ'), + (0x1E13, 'V'), + (0x1E14, 'M', u'ḕ'), + (0x1E15, 'V'), + (0x1E16, 'M', u'ḗ'), + (0x1E17, 'V'), + (0x1E18, 'M', u'ḙ'), + (0x1E19, 'V'), + (0x1E1A, 'M', u'ḛ'), + (0x1E1B, 'V'), + (0x1E1C, 'M', u'ḝ'), + (0x1E1D, 'V'), + (0x1E1E, 'M', u'ḟ'), + (0x1E1F, 'V'), + (0x1E20, 'M', u'ḡ'), + (0x1E21, 'V'), + (0x1E22, 'M', u'ḣ'), + (0x1E23, 'V'), + (0x1E24, 'M', u'ḥ'), + (0x1E25, 'V'), + (0x1E26, 'M', u'ḧ'), + (0x1E27, 'V'), + (0x1E28, 'M', u'ḩ'), + (0x1E29, 'V'), + (0x1E2A, 'M', u'ḫ'), + (0x1E2B, 'V'), + (0x1E2C, 'M', u'ḭ'), + (0x1E2D, 'V'), + (0x1E2E, 'M', u'ḯ'), + (0x1E2F, 'V'), + (0x1E30, 'M', u'ḱ'), + (0x1E31, 'V'), + (0x1E32, 'M', u'ḳ'), + (0x1E33, 'V'), + (0x1E34, 'M', u'ḵ'), + (0x1E35, 'V'), + (0x1E36, 'M', u'ḷ'), + (0x1E37, 'V'), + (0x1E38, 'M', u'ḹ'), + (0x1E39, 'V'), + (0x1E3A, 'M', u'ḻ'), + (0x1E3B, 'V'), + (0x1E3C, 'M', u'ḽ'), + (0x1E3D, 'V'), + (0x1E3E, 'M', u'ḿ'), + (0x1E3F, 'V'), + (0x1E40, 'M', u'ṁ'), + (0x1E41, 'V'), + (0x1E42, 'M', u'ṃ'), + (0x1E43, 'V'), + (0x1E44, 'M', u'ṅ'), + (0x1E45, 'V'), + (0x1E46, 'M', u'ṇ'), + (0x1E47, 'V'), + (0x1E48, 'M', u'ṉ'), + (0x1E49, 'V'), + (0x1E4A, 'M', u'ṋ'), + ] + +def _seg_17(): + return [ + (0x1E4B, 'V'), + (0x1E4C, 'M', u'ṍ'), + (0x1E4D, 'V'), + (0x1E4E, 'M', u'ṏ'), + (0x1E4F, 'V'), + (0x1E50, 'M', u'ṑ'), + (0x1E51, 'V'), + (0x1E52, 'M', u'ṓ'), + (0x1E53, 'V'), + (0x1E54, 'M', u'ṕ'), + (0x1E55, 'V'), + (0x1E56, 'M', u'ṗ'), + (0x1E57, 'V'), + (0x1E58, 'M', u'ṙ'), + (0x1E59, 'V'), + (0x1E5A, 'M', u'ṛ'), + (0x1E5B, 'V'), + (0x1E5C, 'M', u'ṝ'), + (0x1E5D, 'V'), + (0x1E5E, 'M', u'ṟ'), + (0x1E5F, 'V'), + (0x1E60, 'M', u'ṡ'), + (0x1E61, 'V'), + (0x1E62, 'M', u'ṣ'), + (0x1E63, 'V'), + (0x1E64, 'M', u'ṥ'), + (0x1E65, 'V'), + (0x1E66, 'M', u'ṧ'), + (0x1E67, 'V'), + (0x1E68, 'M', u'ṩ'), + (0x1E69, 'V'), + (0x1E6A, 'M', u'ṫ'), + (0x1E6B, 'V'), + (0x1E6C, 'M', u'ṭ'), + (0x1E6D, 'V'), + (0x1E6E, 'M', u'ṯ'), + (0x1E6F, 'V'), + (0x1E70, 'M', u'ṱ'), + (0x1E71, 'V'), + (0x1E72, 'M', u'ṳ'), + (0x1E73, 'V'), + (0x1E74, 'M', u'ṵ'), + (0x1E75, 'V'), + (0x1E76, 'M', u'ṷ'), + (0x1E77, 'V'), + (0x1E78, 'M', u'ṹ'), + (0x1E79, 'V'), + (0x1E7A, 'M', u'ṻ'), + (0x1E7B, 'V'), + (0x1E7C, 'M', u'ṽ'), + (0x1E7D, 'V'), + (0x1E7E, 'M', u'ṿ'), + (0x1E7F, 'V'), + (0x1E80, 'M', u'ẁ'), + (0x1E81, 'V'), + (0x1E82, 'M', u'ẃ'), + (0x1E83, 'V'), + (0x1E84, 'M', u'ẅ'), + (0x1E85, 'V'), + (0x1E86, 'M', u'ẇ'), + (0x1E87, 'V'), + (0x1E88, 'M', u'ẉ'), + (0x1E89, 'V'), + (0x1E8A, 'M', u'ẋ'), + (0x1E8B, 'V'), + (0x1E8C, 'M', u'ẍ'), + (0x1E8D, 'V'), + (0x1E8E, 'M', u'ẏ'), + (0x1E8F, 'V'), + (0x1E90, 'M', u'ẑ'), + (0x1E91, 'V'), + (0x1E92, 'M', u'ẓ'), + (0x1E93, 'V'), + (0x1E94, 'M', u'ẕ'), + (0x1E95, 'V'), + (0x1E9A, 'M', u'aʾ'), + (0x1E9B, 'M', u'ṡ'), + (0x1E9C, 'V'), + (0x1E9E, 'M', u'ss'), + (0x1E9F, 'V'), + (0x1EA0, 'M', u'ạ'), + (0x1EA1, 'V'), + (0x1EA2, 'M', u'ả'), + (0x1EA3, 'V'), + (0x1EA4, 'M', u'ấ'), + (0x1EA5, 'V'), + (0x1EA6, 'M', u'ầ'), + (0x1EA7, 'V'), + (0x1EA8, 'M', u'ẩ'), + (0x1EA9, 'V'), + (0x1EAA, 'M', u'ẫ'), + (0x1EAB, 'V'), + (0x1EAC, 'M', u'ậ'), + (0x1EAD, 'V'), + (0x1EAE, 'M', u'ắ'), + (0x1EAF, 'V'), + (0x1EB0, 'M', u'ằ'), + (0x1EB1, 'V'), + (0x1EB2, 'M', u'ẳ'), + (0x1EB3, 'V'), + ] + +def _seg_18(): + return [ + (0x1EB4, 'M', u'ẵ'), + (0x1EB5, 'V'), + (0x1EB6, 'M', u'ặ'), + (0x1EB7, 'V'), + (0x1EB8, 'M', u'ẹ'), + (0x1EB9, 'V'), + (0x1EBA, 'M', u'ẻ'), + (0x1EBB, 'V'), + (0x1EBC, 'M', u'ẽ'), + (0x1EBD, 'V'), + (0x1EBE, 'M', u'ế'), + (0x1EBF, 'V'), + (0x1EC0, 'M', u'ề'), + (0x1EC1, 'V'), + (0x1EC2, 'M', u'ể'), + (0x1EC3, 'V'), + (0x1EC4, 'M', u'ễ'), + (0x1EC5, 'V'), + (0x1EC6, 'M', u'ệ'), + (0x1EC7, 'V'), + (0x1EC8, 'M', u'ỉ'), + (0x1EC9, 'V'), + (0x1ECA, 'M', u'ị'), + (0x1ECB, 'V'), + (0x1ECC, 'M', u'ọ'), + (0x1ECD, 'V'), + (0x1ECE, 'M', u'ỏ'), + (0x1ECF, 'V'), + (0x1ED0, 'M', u'ố'), + (0x1ED1, 'V'), + (0x1ED2, 'M', u'ồ'), + (0x1ED3, 'V'), + (0x1ED4, 'M', u'ổ'), + (0x1ED5, 'V'), + (0x1ED6, 'M', u'ỗ'), + (0x1ED7, 'V'), + (0x1ED8, 'M', u'ộ'), + (0x1ED9, 'V'), + (0x1EDA, 'M', u'ớ'), + (0x1EDB, 'V'), + (0x1EDC, 'M', u'ờ'), + (0x1EDD, 'V'), + (0x1EDE, 'M', u'ở'), + (0x1EDF, 'V'), + (0x1EE0, 'M', u'ỡ'), + (0x1EE1, 'V'), + (0x1EE2, 'M', u'ợ'), + (0x1EE3, 'V'), + (0x1EE4, 'M', u'ụ'), + (0x1EE5, 'V'), + (0x1EE6, 'M', u'ủ'), + (0x1EE7, 'V'), + (0x1EE8, 'M', u'ứ'), + (0x1EE9, 'V'), + (0x1EEA, 'M', u'ừ'), + (0x1EEB, 'V'), + (0x1EEC, 'M', u'ử'), + (0x1EED, 'V'), + (0x1EEE, 'M', u'ữ'), + (0x1EEF, 'V'), + (0x1EF0, 'M', u'ự'), + (0x1EF1, 'V'), + (0x1EF2, 'M', u'ỳ'), + (0x1EF3, 'V'), + (0x1EF4, 'M', u'ỵ'), + (0x1EF5, 'V'), + (0x1EF6, 'M', u'ỷ'), + (0x1EF7, 'V'), + (0x1EF8, 'M', u'ỹ'), + (0x1EF9, 'V'), + (0x1EFA, 'M', u'ỻ'), + (0x1EFB, 'V'), + (0x1EFC, 'M', u'ỽ'), + (0x1EFD, 'V'), + (0x1EFE, 'M', u'ỿ'), + (0x1EFF, 'V'), + (0x1F08, 'M', u'ἀ'), + (0x1F09, 'M', u'ἁ'), + (0x1F0A, 'M', u'ἂ'), + (0x1F0B, 'M', u'ἃ'), + (0x1F0C, 'M', u'ἄ'), + (0x1F0D, 'M', u'ἅ'), + (0x1F0E, 'M', u'ἆ'), + (0x1F0F, 'M', u'ἇ'), + (0x1F10, 'V'), + (0x1F16, 'X'), + (0x1F18, 'M', u'ἐ'), + (0x1F19, 'M', u'ἑ'), + (0x1F1A, 'M', u'ἒ'), + (0x1F1B, 'M', u'ἓ'), + (0x1F1C, 'M', u'ἔ'), + (0x1F1D, 'M', u'ἕ'), + (0x1F1E, 'X'), + (0x1F20, 'V'), + (0x1F28, 'M', u'ἠ'), + (0x1F29, 'M', u'ἡ'), + (0x1F2A, 'M', u'ἢ'), + (0x1F2B, 'M', u'ἣ'), + (0x1F2C, 'M', u'ἤ'), + (0x1F2D, 'M', u'ἥ'), + ] + +def _seg_19(): + return [ + (0x1F2E, 'M', u'ἦ'), + (0x1F2F, 'M', u'ἧ'), + (0x1F30, 'V'), + (0x1F38, 'M', u'ἰ'), + (0x1F39, 'M', u'ἱ'), + (0x1F3A, 'M', u'ἲ'), + (0x1F3B, 'M', u'ἳ'), + (0x1F3C, 'M', u'ἴ'), + (0x1F3D, 'M', u'ἵ'), + (0x1F3E, 'M', u'ἶ'), + (0x1F3F, 'M', u'ἷ'), + (0x1F40, 'V'), + (0x1F46, 'X'), + (0x1F48, 'M', u'ὀ'), + (0x1F49, 'M', u'ὁ'), + (0x1F4A, 'M', u'ὂ'), + (0x1F4B, 'M', u'ὃ'), + (0x1F4C, 'M', u'ὄ'), + (0x1F4D, 'M', u'ὅ'), + (0x1F4E, 'X'), + (0x1F50, 'V'), + (0x1F58, 'X'), + (0x1F59, 'M', u'ὑ'), + (0x1F5A, 'X'), + (0x1F5B, 'M', u'ὓ'), + (0x1F5C, 'X'), + (0x1F5D, 'M', u'ὕ'), + (0x1F5E, 'X'), + (0x1F5F, 'M', u'ὗ'), + (0x1F60, 'V'), + (0x1F68, 'M', u'ὠ'), + (0x1F69, 'M', u'ὡ'), + (0x1F6A, 'M', u'ὢ'), + (0x1F6B, 'M', u'ὣ'), + (0x1F6C, 'M', u'ὤ'), + (0x1F6D, 'M', u'ὥ'), + (0x1F6E, 'M', u'ὦ'), + (0x1F6F, 'M', u'ὧ'), + (0x1F70, 'V'), + (0x1F71, 'M', u'ά'), + (0x1F72, 'V'), + (0x1F73, 'M', u'έ'), + (0x1F74, 'V'), + (0x1F75, 'M', u'ή'), + (0x1F76, 'V'), + (0x1F77, 'M', u'ί'), + (0x1F78, 'V'), + (0x1F79, 'M', u'ό'), + (0x1F7A, 'V'), + (0x1F7B, 'M', u'ύ'), + (0x1F7C, 'V'), + (0x1F7D, 'M', u'ώ'), + (0x1F7E, 'X'), + (0x1F80, 'M', u'ἀι'), + (0x1F81, 'M', u'ἁι'), + (0x1F82, 'M', u'ἂι'), + (0x1F83, 'M', u'ἃι'), + (0x1F84, 'M', u'ἄι'), + (0x1F85, 'M', u'ἅι'), + (0x1F86, 'M', u'ἆι'), + (0x1F87, 'M', u'ἇι'), + (0x1F88, 'M', u'ἀι'), + (0x1F89, 'M', u'ἁι'), + (0x1F8A, 'M', u'ἂι'), + (0x1F8B, 'M', u'ἃι'), + (0x1F8C, 'M', u'ἄι'), + (0x1F8D, 'M', u'ἅι'), + (0x1F8E, 'M', u'ἆι'), + (0x1F8F, 'M', u'ἇι'), + (0x1F90, 'M', u'ἠι'), + (0x1F91, 'M', u'ἡι'), + (0x1F92, 'M', u'ἢι'), + (0x1F93, 'M', u'ἣι'), + (0x1F94, 'M', u'ἤι'), + (0x1F95, 'M', u'ἥι'), + (0x1F96, 'M', u'ἦι'), + (0x1F97, 'M', u'ἧι'), + (0x1F98, 'M', u'ἠι'), + (0x1F99, 'M', u'ἡι'), + (0x1F9A, 'M', u'ἢι'), + (0x1F9B, 'M', u'ἣι'), + (0x1F9C, 'M', u'ἤι'), + (0x1F9D, 'M', u'ἥι'), + (0x1F9E, 'M', u'ἦι'), + (0x1F9F, 'M', u'ἧι'), + (0x1FA0, 'M', u'ὠι'), + (0x1FA1, 'M', u'ὡι'), + (0x1FA2, 'M', u'ὢι'), + (0x1FA3, 'M', u'ὣι'), + (0x1FA4, 'M', u'ὤι'), + (0x1FA5, 'M', u'ὥι'), + (0x1FA6, 'M', u'ὦι'), + (0x1FA7, 'M', u'ὧι'), + (0x1FA8, 'M', u'ὠι'), + (0x1FA9, 'M', u'ὡι'), + (0x1FAA, 'M', u'ὢι'), + (0x1FAB, 'M', u'ὣι'), + (0x1FAC, 'M', u'ὤι'), + (0x1FAD, 'M', u'ὥι'), + (0x1FAE, 'M', u'ὦι'), + ] + +def _seg_20(): + return [ + (0x1FAF, 'M', u'ὧι'), + (0x1FB0, 'V'), + (0x1FB2, 'M', u'ὰι'), + (0x1FB3, 'M', u'αι'), + (0x1FB4, 'M', u'άι'), + (0x1FB5, 'X'), + (0x1FB6, 'V'), + (0x1FB7, 'M', u'ᾶι'), + (0x1FB8, 'M', u'ᾰ'), + (0x1FB9, 'M', u'ᾱ'), + (0x1FBA, 'M', u'ὰ'), + (0x1FBB, 'M', u'ά'), + (0x1FBC, 'M', u'αι'), + (0x1FBD, '3', u' ̓'), + (0x1FBE, 'M', u'ι'), + (0x1FBF, '3', u' ̓'), + (0x1FC0, '3', u' ͂'), + (0x1FC1, '3', u' ̈͂'), + (0x1FC2, 'M', u'ὴι'), + (0x1FC3, 'M', u'ηι'), + (0x1FC4, 'M', u'ήι'), + (0x1FC5, 'X'), + (0x1FC6, 'V'), + (0x1FC7, 'M', u'ῆι'), + (0x1FC8, 'M', u'ὲ'), + (0x1FC9, 'M', u'έ'), + (0x1FCA, 'M', u'ὴ'), + (0x1FCB, 'M', u'ή'), + (0x1FCC, 'M', u'ηι'), + (0x1FCD, '3', u' ̓̀'), + (0x1FCE, '3', u' ̓́'), + (0x1FCF, '3', u' ̓͂'), + (0x1FD0, 'V'), + (0x1FD3, 'M', u'ΐ'), + (0x1FD4, 'X'), + (0x1FD6, 'V'), + (0x1FD8, 'M', u'ῐ'), + (0x1FD9, 'M', u'ῑ'), + (0x1FDA, 'M', u'ὶ'), + (0x1FDB, 'M', u'ί'), + (0x1FDC, 'X'), + (0x1FDD, '3', u' ̔̀'), + (0x1FDE, '3', u' ̔́'), + (0x1FDF, '3', u' ̔͂'), + (0x1FE0, 'V'), + (0x1FE3, 'M', u'ΰ'), + (0x1FE4, 'V'), + (0x1FE8, 'M', u'ῠ'), + (0x1FE9, 'M', u'ῡ'), + (0x1FEA, 'M', u'ὺ'), + (0x1FEB, 'M', u'ύ'), + (0x1FEC, 'M', u'ῥ'), + (0x1FED, '3', u' ̈̀'), + (0x1FEE, '3', u' ̈́'), + (0x1FEF, '3', u'`'), + (0x1FF0, 'X'), + (0x1FF2, 'M', u'ὼι'), + (0x1FF3, 'M', u'ωι'), + (0x1FF4, 'M', u'ώι'), + (0x1FF5, 'X'), + (0x1FF6, 'V'), + (0x1FF7, 'M', u'ῶι'), + (0x1FF8, 'M', u'ὸ'), + (0x1FF9, 'M', u'ό'), + (0x1FFA, 'M', u'ὼ'), + (0x1FFB, 'M', u'ώ'), + (0x1FFC, 'M', u'ωι'), + (0x1FFD, '3', u' ́'), + (0x1FFE, '3', u' ̔'), + (0x1FFF, 'X'), + (0x2000, '3', u' '), + (0x200B, 'I'), + (0x200C, 'D', u''), + (0x200E, 'X'), + (0x2010, 'V'), + (0x2011, 'M', u'‐'), + (0x2012, 'V'), + (0x2017, '3', u' ̳'), + (0x2018, 'V'), + (0x2024, 'X'), + (0x2027, 'V'), + (0x2028, 'X'), + (0x202F, '3', u' '), + (0x2030, 'V'), + (0x2033, 'M', u'′′'), + (0x2034, 'M', u'′′′'), + (0x2035, 'V'), + (0x2036, 'M', u'‵‵'), + (0x2037, 'M', u'‵‵‵'), + (0x2038, 'V'), + (0x203C, '3', u'!!'), + (0x203D, 'V'), + (0x203E, '3', u' ̅'), + (0x203F, 'V'), + (0x2047, '3', u'??'), + (0x2048, '3', u'?!'), + (0x2049, '3', u'!?'), + (0x204A, 'V'), + (0x2057, 'M', u'′′′′'), + (0x2058, 'V'), + ] + +def _seg_21(): + return [ + (0x205F, '3', u' '), + (0x2060, 'I'), + (0x2061, 'X'), + (0x2064, 'I'), + (0x2065, 'X'), + (0x2070, 'M', u'0'), + (0x2071, 'M', u'i'), + (0x2072, 'X'), + (0x2074, 'M', u'4'), + (0x2075, 'M', u'5'), + (0x2076, 'M', u'6'), + (0x2077, 'M', u'7'), + (0x2078, 'M', u'8'), + (0x2079, 'M', u'9'), + (0x207A, '3', u'+'), + (0x207B, 'M', u'−'), + (0x207C, '3', u'='), + (0x207D, '3', u'('), + (0x207E, '3', u')'), + (0x207F, 'M', u'n'), + (0x2080, 'M', u'0'), + (0x2081, 'M', u'1'), + (0x2082, 'M', u'2'), + (0x2083, 'M', u'3'), + (0x2084, 'M', u'4'), + (0x2085, 'M', u'5'), + (0x2086, 'M', u'6'), + (0x2087, 'M', u'7'), + (0x2088, 'M', u'8'), + (0x2089, 'M', u'9'), + (0x208A, '3', u'+'), + (0x208B, 'M', u'−'), + (0x208C, '3', u'='), + (0x208D, '3', u'('), + (0x208E, '3', u')'), + (0x208F, 'X'), + (0x2090, 'M', u'a'), + (0x2091, 'M', u'e'), + (0x2092, 'M', u'o'), + (0x2093, 'M', u'x'), + (0x2094, 'M', u'ə'), + (0x2095, 'M', u'h'), + (0x2096, 'M', u'k'), + (0x2097, 'M', u'l'), + (0x2098, 'M', u'm'), + (0x2099, 'M', u'n'), + (0x209A, 'M', u'p'), + (0x209B, 'M', u's'), + (0x209C, 'M', u't'), + (0x209D, 'X'), + (0x20A0, 'V'), + (0x20A8, 'M', u'rs'), + (0x20A9, 'V'), + (0x20BB, 'X'), + (0x20D0, 'V'), + (0x20F1, 'X'), + (0x2100, '3', u'a/c'), + (0x2101, '3', u'a/s'), + (0x2102, 'M', u'c'), + (0x2103, 'M', u'°c'), + (0x2104, 'V'), + (0x2105, '3', u'c/o'), + (0x2106, '3', u'c/u'), + (0x2107, 'M', u'ɛ'), + (0x2108, 'V'), + (0x2109, 'M', u'°f'), + (0x210A, 'M', u'g'), + (0x210B, 'M', u'h'), + (0x210F, 'M', u'ħ'), + (0x2110, 'M', u'i'), + (0x2112, 'M', u'l'), + (0x2114, 'V'), + (0x2115, 'M', u'n'), + (0x2116, 'M', u'no'), + (0x2117, 'V'), + (0x2119, 'M', u'p'), + (0x211A, 'M', u'q'), + (0x211B, 'M', u'r'), + (0x211E, 'V'), + (0x2120, 'M', u'sm'), + (0x2121, 'M', u'tel'), + (0x2122, 'M', u'tm'), + (0x2123, 'V'), + (0x2124, 'M', u'z'), + (0x2125, 'V'), + (0x2126, 'M', u'ω'), + (0x2127, 'V'), + (0x2128, 'M', u'z'), + (0x2129, 'V'), + (0x212A, 'M', u'k'), + (0x212B, 'M', u'å'), + (0x212C, 'M', u'b'), + (0x212D, 'M', u'c'), + (0x212E, 'V'), + (0x212F, 'M', u'e'), + (0x2131, 'M', u'f'), + (0x2132, 'X'), + (0x2133, 'M', u'm'), + (0x2134, 'M', u'o'), + (0x2135, 'M', u'א'), + ] + +def _seg_22(): + return [ + (0x2136, 'M', u'ב'), + (0x2137, 'M', u'ג'), + (0x2138, 'M', u'ד'), + (0x2139, 'M', u'i'), + (0x213A, 'V'), + (0x213B, 'M', u'fax'), + (0x213C, 'M', u'π'), + (0x213D, 'M', u'γ'), + (0x213F, 'M', u'π'), + (0x2140, 'M', u'∑'), + (0x2141, 'V'), + (0x2145, 'M', u'd'), + (0x2147, 'M', u'e'), + (0x2148, 'M', u'i'), + (0x2149, 'M', u'j'), + (0x214A, 'V'), + (0x2150, 'M', u'1⁄7'), + (0x2151, 'M', u'1⁄9'), + (0x2152, 'M', u'1⁄10'), + (0x2153, 'M', u'1⁄3'), + (0x2154, 'M', u'2⁄3'), + (0x2155, 'M', u'1⁄5'), + (0x2156, 'M', u'2⁄5'), + (0x2157, 'M', u'3⁄5'), + (0x2158, 'M', u'4⁄5'), + (0x2159, 'M', u'1⁄6'), + (0x215A, 'M', u'5⁄6'), + (0x215B, 'M', u'1⁄8'), + (0x215C, 'M', u'3⁄8'), + (0x215D, 'M', u'5⁄8'), + (0x215E, 'M', u'7⁄8'), + (0x215F, 'M', u'1⁄'), + (0x2160, 'M', u'i'), + (0x2161, 'M', u'ii'), + (0x2162, 'M', u'iii'), + (0x2163, 'M', u'iv'), + (0x2164, 'M', u'v'), + (0x2165, 'M', u'vi'), + (0x2166, 'M', u'vii'), + (0x2167, 'M', u'viii'), + (0x2168, 'M', u'ix'), + (0x2169, 'M', u'x'), + (0x216A, 'M', u'xi'), + (0x216B, 'M', u'xii'), + (0x216C, 'M', u'l'), + (0x216D, 'M', u'c'), + (0x216E, 'M', u'd'), + (0x216F, 'M', u'm'), + (0x2170, 'M', u'i'), + (0x2171, 'M', u'ii'), + (0x2172, 'M', u'iii'), + (0x2173, 'M', u'iv'), + (0x2174, 'M', u'v'), + (0x2175, 'M', u'vi'), + (0x2176, 'M', u'vii'), + (0x2177, 'M', u'viii'), + (0x2178, 'M', u'ix'), + (0x2179, 'M', u'x'), + (0x217A, 'M', u'xi'), + (0x217B, 'M', u'xii'), + (0x217C, 'M', u'l'), + (0x217D, 'M', u'c'), + (0x217E, 'M', u'd'), + (0x217F, 'M', u'm'), + (0x2180, 'V'), + (0x2183, 'X'), + (0x2184, 'V'), + (0x2189, 'M', u'0⁄3'), + (0x218A, 'X'), + (0x2190, 'V'), + (0x222C, 'M', u'∫∫'), + (0x222D, 'M', u'∫∫∫'), + (0x222E, 'V'), + (0x222F, 'M', u'∮∮'), + (0x2230, 'M', u'∮∮∮'), + (0x2231, 'V'), + (0x2260, '3'), + (0x2261, 'V'), + (0x226E, '3'), + (0x2270, 'V'), + (0x2329, 'M', u'〈'), + (0x232A, 'M', u'〉'), + (0x232B, 'V'), + (0x23F4, 'X'), + (0x2400, 'V'), + (0x2427, 'X'), + (0x2440, 'V'), + (0x244B, 'X'), + (0x2460, 'M', u'1'), + (0x2461, 'M', u'2'), + (0x2462, 'M', u'3'), + (0x2463, 'M', u'4'), + (0x2464, 'M', u'5'), + (0x2465, 'M', u'6'), + (0x2466, 'M', u'7'), + (0x2467, 'M', u'8'), + (0x2468, 'M', u'9'), + (0x2469, 'M', u'10'), + (0x246A, 'M', u'11'), + (0x246B, 'M', u'12'), + ] + +def _seg_23(): + return [ + (0x246C, 'M', u'13'), + (0x246D, 'M', u'14'), + (0x246E, 'M', u'15'), + (0x246F, 'M', u'16'), + (0x2470, 'M', u'17'), + (0x2471, 'M', u'18'), + (0x2472, 'M', u'19'), + (0x2473, 'M', u'20'), + (0x2474, '3', u'(1)'), + (0x2475, '3', u'(2)'), + (0x2476, '3', u'(3)'), + (0x2477, '3', u'(4)'), + (0x2478, '3', u'(5)'), + (0x2479, '3', u'(6)'), + (0x247A, '3', u'(7)'), + (0x247B, '3', u'(8)'), + (0x247C, '3', u'(9)'), + (0x247D, '3', u'(10)'), + (0x247E, '3', u'(11)'), + (0x247F, '3', u'(12)'), + (0x2480, '3', u'(13)'), + (0x2481, '3', u'(14)'), + (0x2482, '3', u'(15)'), + (0x2483, '3', u'(16)'), + (0x2484, '3', u'(17)'), + (0x2485, '3', u'(18)'), + (0x2486, '3', u'(19)'), + (0x2487, '3', u'(20)'), + (0x2488, 'X'), + (0x249C, '3', u'(a)'), + (0x249D, '3', u'(b)'), + (0x249E, '3', u'(c)'), + (0x249F, '3', u'(d)'), + (0x24A0, '3', u'(e)'), + (0x24A1, '3', u'(f)'), + (0x24A2, '3', u'(g)'), + (0x24A3, '3', u'(h)'), + (0x24A4, '3', u'(i)'), + (0x24A5, '3', u'(j)'), + (0x24A6, '3', u'(k)'), + (0x24A7, '3', u'(l)'), + (0x24A8, '3', u'(m)'), + (0x24A9, '3', u'(n)'), + (0x24AA, '3', u'(o)'), + (0x24AB, '3', u'(p)'), + (0x24AC, '3', u'(q)'), + (0x24AD, '3', u'(r)'), + (0x24AE, '3', u'(s)'), + (0x24AF, '3', u'(t)'), + (0x24B0, '3', u'(u)'), + (0x24B1, '3', u'(v)'), + (0x24B2, '3', u'(w)'), + (0x24B3, '3', u'(x)'), + (0x24B4, '3', u'(y)'), + (0x24B5, '3', u'(z)'), + (0x24B6, 'M', u'a'), + (0x24B7, 'M', u'b'), + (0x24B8, 'M', u'c'), + (0x24B9, 'M', u'd'), + (0x24BA, 'M', u'e'), + (0x24BB, 'M', u'f'), + (0x24BC, 'M', u'g'), + (0x24BD, 'M', u'h'), + (0x24BE, 'M', u'i'), + (0x24BF, 'M', u'j'), + (0x24C0, 'M', u'k'), + (0x24C1, 'M', u'l'), + (0x24C2, 'M', u'm'), + (0x24C3, 'M', u'n'), + (0x24C4, 'M', u'o'), + (0x24C5, 'M', u'p'), + (0x24C6, 'M', u'q'), + (0x24C7, 'M', u'r'), + (0x24C8, 'M', u's'), + (0x24C9, 'M', u't'), + (0x24CA, 'M', u'u'), + (0x24CB, 'M', u'v'), + (0x24CC, 'M', u'w'), + (0x24CD, 'M', u'x'), + (0x24CE, 'M', u'y'), + (0x24CF, 'M', u'z'), + (0x24D0, 'M', u'a'), + (0x24D1, 'M', u'b'), + (0x24D2, 'M', u'c'), + (0x24D3, 'M', u'd'), + (0x24D4, 'M', u'e'), + (0x24D5, 'M', u'f'), + (0x24D6, 'M', u'g'), + (0x24D7, 'M', u'h'), + (0x24D8, 'M', u'i'), + (0x24D9, 'M', u'j'), + (0x24DA, 'M', u'k'), + (0x24DB, 'M', u'l'), + (0x24DC, 'M', u'm'), + (0x24DD, 'M', u'n'), + (0x24DE, 'M', u'o'), + (0x24DF, 'M', u'p'), + (0x24E0, 'M', u'q'), + (0x24E1, 'M', u'r'), + (0x24E2, 'M', u's'), + ] + +def _seg_24(): + return [ + (0x24E3, 'M', u't'), + (0x24E4, 'M', u'u'), + (0x24E5, 'M', u'v'), + (0x24E6, 'M', u'w'), + (0x24E7, 'M', u'x'), + (0x24E8, 'M', u'y'), + (0x24E9, 'M', u'z'), + (0x24EA, 'M', u'0'), + (0x24EB, 'V'), + (0x2700, 'X'), + (0x2701, 'V'), + (0x2A0C, 'M', u'∫∫∫∫'), + (0x2A0D, 'V'), + (0x2A74, '3', u'::='), + (0x2A75, '3', u'=='), + (0x2A76, '3', u'==='), + (0x2A77, 'V'), + (0x2ADC, 'M', u'⫝̸'), + (0x2ADD, 'V'), + (0x2B4D, 'X'), + (0x2B50, 'V'), + (0x2B5A, 'X'), + (0x2C00, 'M', u'ⰰ'), + (0x2C01, 'M', u'ⰱ'), + (0x2C02, 'M', u'ⰲ'), + (0x2C03, 'M', u'ⰳ'), + (0x2C04, 'M', u'ⰴ'), + (0x2C05, 'M', u'ⰵ'), + (0x2C06, 'M', u'ⰶ'), + (0x2C07, 'M', u'ⰷ'), + (0x2C08, 'M', u'ⰸ'), + (0x2C09, 'M', u'ⰹ'), + (0x2C0A, 'M', u'ⰺ'), + (0x2C0B, 'M', u'ⰻ'), + (0x2C0C, 'M', u'ⰼ'), + (0x2C0D, 'M', u'ⰽ'), + (0x2C0E, 'M', u'ⰾ'), + (0x2C0F, 'M', u'ⰿ'), + (0x2C10, 'M', u'ⱀ'), + (0x2C11, 'M', u'ⱁ'), + (0x2C12, 'M', u'ⱂ'), + (0x2C13, 'M', u'ⱃ'), + (0x2C14, 'M', u'ⱄ'), + (0x2C15, 'M', u'ⱅ'), + (0x2C16, 'M', u'ⱆ'), + (0x2C17, 'M', u'ⱇ'), + (0x2C18, 'M', u'ⱈ'), + (0x2C19, 'M', u'ⱉ'), + (0x2C1A, 'M', u'ⱊ'), + (0x2C1B, 'M', u'ⱋ'), + (0x2C1C, 'M', u'ⱌ'), + (0x2C1D, 'M', u'ⱍ'), + (0x2C1E, 'M', u'ⱎ'), + (0x2C1F, 'M', u'ⱏ'), + (0x2C20, 'M', u'ⱐ'), + (0x2C21, 'M', u'ⱑ'), + (0x2C22, 'M', u'ⱒ'), + (0x2C23, 'M', u'ⱓ'), + (0x2C24, 'M', u'ⱔ'), + (0x2C25, 'M', u'ⱕ'), + (0x2C26, 'M', u'ⱖ'), + (0x2C27, 'M', u'ⱗ'), + (0x2C28, 'M', u'ⱘ'), + (0x2C29, 'M', u'ⱙ'), + (0x2C2A, 'M', u'ⱚ'), + (0x2C2B, 'M', u'ⱛ'), + (0x2C2C, 'M', u'ⱜ'), + (0x2C2D, 'M', u'ⱝ'), + (0x2C2E, 'M', u'ⱞ'), + (0x2C2F, 'X'), + (0x2C30, 'V'), + (0x2C5F, 'X'), + (0x2C60, 'M', u'ⱡ'), + (0x2C61, 'V'), + (0x2C62, 'M', u'ɫ'), + (0x2C63, 'M', u'ᵽ'), + (0x2C64, 'M', u'ɽ'), + (0x2C65, 'V'), + (0x2C67, 'M', u'ⱨ'), + (0x2C68, 'V'), + (0x2C69, 'M', u'ⱪ'), + (0x2C6A, 'V'), + (0x2C6B, 'M', u'ⱬ'), + (0x2C6C, 'V'), + (0x2C6D, 'M', u'ɑ'), + (0x2C6E, 'M', u'ɱ'), + (0x2C6F, 'M', u'ɐ'), + (0x2C70, 'M', u'ɒ'), + (0x2C71, 'V'), + (0x2C72, 'M', u'ⱳ'), + (0x2C73, 'V'), + (0x2C75, 'M', u'ⱶ'), + (0x2C76, 'V'), + (0x2C7C, 'M', u'j'), + (0x2C7D, 'M', u'v'), + (0x2C7E, 'M', u'ȿ'), + (0x2C7F, 'M', u'ɀ'), + (0x2C80, 'M', u'ⲁ'), + (0x2C81, 'V'), + (0x2C82, 'M', u'ⲃ'), + ] + +def _seg_25(): + return [ + (0x2C83, 'V'), + (0x2C84, 'M', u'ⲅ'), + (0x2C85, 'V'), + (0x2C86, 'M', u'ⲇ'), + (0x2C87, 'V'), + (0x2C88, 'M', u'ⲉ'), + (0x2C89, 'V'), + (0x2C8A, 'M', u'ⲋ'), + (0x2C8B, 'V'), + (0x2C8C, 'M', u'ⲍ'), + (0x2C8D, 'V'), + (0x2C8E, 'M', u'ⲏ'), + (0x2C8F, 'V'), + (0x2C90, 'M', u'ⲑ'), + (0x2C91, 'V'), + (0x2C92, 'M', u'ⲓ'), + (0x2C93, 'V'), + (0x2C94, 'M', u'ⲕ'), + (0x2C95, 'V'), + (0x2C96, 'M', u'ⲗ'), + (0x2C97, 'V'), + (0x2C98, 'M', u'ⲙ'), + (0x2C99, 'V'), + (0x2C9A, 'M', u'ⲛ'), + (0x2C9B, 'V'), + (0x2C9C, 'M', u'ⲝ'), + (0x2C9D, 'V'), + (0x2C9E, 'M', u'ⲟ'), + (0x2C9F, 'V'), + (0x2CA0, 'M', u'ⲡ'), + (0x2CA1, 'V'), + (0x2CA2, 'M', u'ⲣ'), + (0x2CA3, 'V'), + (0x2CA4, 'M', u'ⲥ'), + (0x2CA5, 'V'), + (0x2CA6, 'M', u'ⲧ'), + (0x2CA7, 'V'), + (0x2CA8, 'M', u'ⲩ'), + (0x2CA9, 'V'), + (0x2CAA, 'M', u'ⲫ'), + (0x2CAB, 'V'), + (0x2CAC, 'M', u'ⲭ'), + (0x2CAD, 'V'), + (0x2CAE, 'M', u'ⲯ'), + (0x2CAF, 'V'), + (0x2CB0, 'M', u'ⲱ'), + (0x2CB1, 'V'), + (0x2CB2, 'M', u'ⲳ'), + (0x2CB3, 'V'), + (0x2CB4, 'M', u'ⲵ'), + (0x2CB5, 'V'), + (0x2CB6, 'M', u'ⲷ'), + (0x2CB7, 'V'), + (0x2CB8, 'M', u'ⲹ'), + (0x2CB9, 'V'), + (0x2CBA, 'M', u'ⲻ'), + (0x2CBB, 'V'), + (0x2CBC, 'M', u'ⲽ'), + (0x2CBD, 'V'), + (0x2CBE, 'M', u'ⲿ'), + (0x2CBF, 'V'), + (0x2CC0, 'M', u'ⳁ'), + (0x2CC1, 'V'), + (0x2CC2, 'M', u'ⳃ'), + (0x2CC3, 'V'), + (0x2CC4, 'M', u'ⳅ'), + (0x2CC5, 'V'), + (0x2CC6, 'M', u'ⳇ'), + (0x2CC7, 'V'), + (0x2CC8, 'M', u'ⳉ'), + (0x2CC9, 'V'), + (0x2CCA, 'M', u'ⳋ'), + (0x2CCB, 'V'), + (0x2CCC, 'M', u'ⳍ'), + (0x2CCD, 'V'), + (0x2CCE, 'M', u'ⳏ'), + (0x2CCF, 'V'), + (0x2CD0, 'M', u'ⳑ'), + (0x2CD1, 'V'), + (0x2CD2, 'M', u'ⳓ'), + (0x2CD3, 'V'), + (0x2CD4, 'M', u'ⳕ'), + (0x2CD5, 'V'), + (0x2CD6, 'M', u'ⳗ'), + (0x2CD7, 'V'), + (0x2CD8, 'M', u'ⳙ'), + (0x2CD9, 'V'), + (0x2CDA, 'M', u'ⳛ'), + (0x2CDB, 'V'), + (0x2CDC, 'M', u'ⳝ'), + (0x2CDD, 'V'), + (0x2CDE, 'M', u'ⳟ'), + (0x2CDF, 'V'), + (0x2CE0, 'M', u'ⳡ'), + (0x2CE1, 'V'), + (0x2CE2, 'M', u'ⳣ'), + (0x2CE3, 'V'), + (0x2CEB, 'M', u'ⳬ'), + (0x2CEC, 'V'), + (0x2CED, 'M', u'ⳮ'), + ] + +def _seg_26(): + return [ + (0x2CEE, 'V'), + (0x2CF2, 'M', u'ⳳ'), + (0x2CF3, 'V'), + (0x2CF4, 'X'), + (0x2CF9, 'V'), + (0x2D26, 'X'), + (0x2D27, 'V'), + (0x2D28, 'X'), + (0x2D2D, 'V'), + (0x2D2E, 'X'), + (0x2D30, 'V'), + (0x2D68, 'X'), + (0x2D6F, 'M', u'ⵡ'), + (0x2D70, 'V'), + (0x2D71, 'X'), + (0x2D7F, 'V'), + (0x2D97, 'X'), + (0x2DA0, 'V'), + (0x2DA7, 'X'), + (0x2DA8, 'V'), + (0x2DAF, 'X'), + (0x2DB0, 'V'), + (0x2DB7, 'X'), + (0x2DB8, 'V'), + (0x2DBF, 'X'), + (0x2DC0, 'V'), + (0x2DC7, 'X'), + (0x2DC8, 'V'), + (0x2DCF, 'X'), + (0x2DD0, 'V'), + (0x2DD7, 'X'), + (0x2DD8, 'V'), + (0x2DDF, 'X'), + (0x2DE0, 'V'), + (0x2E3C, 'X'), + (0x2E80, 'V'), + (0x2E9A, 'X'), + (0x2E9B, 'V'), + (0x2E9F, 'M', u'母'), + (0x2EA0, 'V'), + (0x2EF3, 'M', u'龟'), + (0x2EF4, 'X'), + (0x2F00, 'M', u'一'), + (0x2F01, 'M', u'丨'), + (0x2F02, 'M', u'丶'), + (0x2F03, 'M', u'丿'), + (0x2F04, 'M', u'乙'), + (0x2F05, 'M', u'亅'), + (0x2F06, 'M', u'二'), + (0x2F07, 'M', u'亠'), + (0x2F08, 'M', u'人'), + (0x2F09, 'M', u'儿'), + (0x2F0A, 'M', u'入'), + (0x2F0B, 'M', u'八'), + (0x2F0C, 'M', u'冂'), + (0x2F0D, 'M', u'冖'), + (0x2F0E, 'M', u'冫'), + (0x2F0F, 'M', u'几'), + (0x2F10, 'M', u'凵'), + (0x2F11, 'M', u'刀'), + (0x2F12, 'M', u'力'), + (0x2F13, 'M', u'勹'), + (0x2F14, 'M', u'匕'), + (0x2F15, 'M', u'匚'), + (0x2F16, 'M', u'匸'), + (0x2F17, 'M', u'十'), + (0x2F18, 'M', u'卜'), + (0x2F19, 'M', u'卩'), + (0x2F1A, 'M', u'厂'), + (0x2F1B, 'M', u'厶'), + (0x2F1C, 'M', u'又'), + (0x2F1D, 'M', u'口'), + (0x2F1E, 'M', u'囗'), + (0x2F1F, 'M', u'土'), + (0x2F20, 'M', u'士'), + (0x2F21, 'M', u'夂'), + (0x2F22, 'M', u'夊'), + (0x2F23, 'M', u'夕'), + (0x2F24, 'M', u'大'), + (0x2F25, 'M', u'女'), + (0x2F26, 'M', u'子'), + (0x2F27, 'M', u'宀'), + (0x2F28, 'M', u'寸'), + (0x2F29, 'M', u'小'), + (0x2F2A, 'M', u'尢'), + (0x2F2B, 'M', u'尸'), + (0x2F2C, 'M', u'屮'), + (0x2F2D, 'M', u'山'), + (0x2F2E, 'M', u'巛'), + (0x2F2F, 'M', u'工'), + (0x2F30, 'M', u'己'), + (0x2F31, 'M', u'巾'), + (0x2F32, 'M', u'干'), + (0x2F33, 'M', u'幺'), + (0x2F34, 'M', u'广'), + (0x2F35, 'M', u'廴'), + (0x2F36, 'M', u'廾'), + (0x2F37, 'M', u'弋'), + (0x2F38, 'M', u'弓'), + (0x2F39, 'M', u'彐'), + ] + +def _seg_27(): + return [ + (0x2F3A, 'M', u'彡'), + (0x2F3B, 'M', u'彳'), + (0x2F3C, 'M', u'心'), + (0x2F3D, 'M', u'戈'), + (0x2F3E, 'M', u'戶'), + (0x2F3F, 'M', u'手'), + (0x2F40, 'M', u'支'), + (0x2F41, 'M', u'攴'), + (0x2F42, 'M', u'文'), + (0x2F43, 'M', u'斗'), + (0x2F44, 'M', u'斤'), + (0x2F45, 'M', u'方'), + (0x2F46, 'M', u'无'), + (0x2F47, 'M', u'日'), + (0x2F48, 'M', u'曰'), + (0x2F49, 'M', u'月'), + (0x2F4A, 'M', u'木'), + (0x2F4B, 'M', u'欠'), + (0x2F4C, 'M', u'止'), + (0x2F4D, 'M', u'歹'), + (0x2F4E, 'M', u'殳'), + (0x2F4F, 'M', u'毋'), + (0x2F50, 'M', u'比'), + (0x2F51, 'M', u'毛'), + (0x2F52, 'M', u'氏'), + (0x2F53, 'M', u'气'), + (0x2F54, 'M', u'水'), + (0x2F55, 'M', u'火'), + (0x2F56, 'M', u'爪'), + (0x2F57, 'M', u'父'), + (0x2F58, 'M', u'爻'), + (0x2F59, 'M', u'爿'), + (0x2F5A, 'M', u'片'), + (0x2F5B, 'M', u'牙'), + (0x2F5C, 'M', u'牛'), + (0x2F5D, 'M', u'犬'), + (0x2F5E, 'M', u'玄'), + (0x2F5F, 'M', u'玉'), + (0x2F60, 'M', u'瓜'), + (0x2F61, 'M', u'瓦'), + (0x2F62, 'M', u'甘'), + (0x2F63, 'M', u'生'), + (0x2F64, 'M', u'用'), + (0x2F65, 'M', u'田'), + (0x2F66, 'M', u'疋'), + (0x2F67, 'M', u'疒'), + (0x2F68, 'M', u'癶'), + (0x2F69, 'M', u'白'), + (0x2F6A, 'M', u'皮'), + (0x2F6B, 'M', u'皿'), + (0x2F6C, 'M', u'目'), + (0x2F6D, 'M', u'矛'), + (0x2F6E, 'M', u'矢'), + (0x2F6F, 'M', u'石'), + (0x2F70, 'M', u'示'), + (0x2F71, 'M', u'禸'), + (0x2F72, 'M', u'禾'), + (0x2F73, 'M', u'穴'), + (0x2F74, 'M', u'立'), + (0x2F75, 'M', u'竹'), + (0x2F76, 'M', u'米'), + (0x2F77, 'M', u'糸'), + (0x2F78, 'M', u'缶'), + (0x2F79, 'M', u'网'), + (0x2F7A, 'M', u'羊'), + (0x2F7B, 'M', u'羽'), + (0x2F7C, 'M', u'老'), + (0x2F7D, 'M', u'而'), + (0x2F7E, 'M', u'耒'), + (0x2F7F, 'M', u'耳'), + (0x2F80, 'M', u'聿'), + (0x2F81, 'M', u'肉'), + (0x2F82, 'M', u'臣'), + (0x2F83, 'M', u'自'), + (0x2F84, 'M', u'至'), + (0x2F85, 'M', u'臼'), + (0x2F86, 'M', u'舌'), + (0x2F87, 'M', u'舛'), + (0x2F88, 'M', u'舟'), + (0x2F89, 'M', u'艮'), + (0x2F8A, 'M', u'色'), + (0x2F8B, 'M', u'艸'), + (0x2F8C, 'M', u'虍'), + (0x2F8D, 'M', u'虫'), + (0x2F8E, 'M', u'血'), + (0x2F8F, 'M', u'行'), + (0x2F90, 'M', u'衣'), + (0x2F91, 'M', u'襾'), + (0x2F92, 'M', u'見'), + (0x2F93, 'M', u'角'), + (0x2F94, 'M', u'言'), + (0x2F95, 'M', u'谷'), + (0x2F96, 'M', u'豆'), + (0x2F97, 'M', u'豕'), + (0x2F98, 'M', u'豸'), + (0x2F99, 'M', u'貝'), + (0x2F9A, 'M', u'赤'), + (0x2F9B, 'M', u'走'), + (0x2F9C, 'M', u'足'), + (0x2F9D, 'M', u'身'), + ] + +def _seg_28(): + return [ + (0x2F9E, 'M', u'車'), + (0x2F9F, 'M', u'辛'), + (0x2FA0, 'M', u'辰'), + (0x2FA1, 'M', u'辵'), + (0x2FA2, 'M', u'邑'), + (0x2FA3, 'M', u'酉'), + (0x2FA4, 'M', u'釆'), + (0x2FA5, 'M', u'里'), + (0x2FA6, 'M', u'金'), + (0x2FA7, 'M', u'長'), + (0x2FA8, 'M', u'門'), + (0x2FA9, 'M', u'阜'), + (0x2FAA, 'M', u'隶'), + (0x2FAB, 'M', u'隹'), + (0x2FAC, 'M', u'雨'), + (0x2FAD, 'M', u'靑'), + (0x2FAE, 'M', u'非'), + (0x2FAF, 'M', u'面'), + (0x2FB0, 'M', u'革'), + (0x2FB1, 'M', u'韋'), + (0x2FB2, 'M', u'韭'), + (0x2FB3, 'M', u'音'), + (0x2FB4, 'M', u'頁'), + (0x2FB5, 'M', u'風'), + (0x2FB6, 'M', u'飛'), + (0x2FB7, 'M', u'食'), + (0x2FB8, 'M', u'首'), + (0x2FB9, 'M', u'香'), + (0x2FBA, 'M', u'馬'), + (0x2FBB, 'M', u'骨'), + (0x2FBC, 'M', u'高'), + (0x2FBD, 'M', u'髟'), + (0x2FBE, 'M', u'鬥'), + (0x2FBF, 'M', u'鬯'), + (0x2FC0, 'M', u'鬲'), + (0x2FC1, 'M', u'鬼'), + (0x2FC2, 'M', u'魚'), + (0x2FC3, 'M', u'鳥'), + (0x2FC4, 'M', u'鹵'), + (0x2FC5, 'M', u'鹿'), + (0x2FC6, 'M', u'麥'), + (0x2FC7, 'M', u'麻'), + (0x2FC8, 'M', u'黃'), + (0x2FC9, 'M', u'黍'), + (0x2FCA, 'M', u'黑'), + (0x2FCB, 'M', u'黹'), + (0x2FCC, 'M', u'黽'), + (0x2FCD, 'M', u'鼎'), + (0x2FCE, 'M', u'鼓'), + (0x2FCF, 'M', u'鼠'), + (0x2FD0, 'M', u'鼻'), + (0x2FD1, 'M', u'齊'), + (0x2FD2, 'M', u'齒'), + (0x2FD3, 'M', u'龍'), + (0x2FD4, 'M', u'龜'), + (0x2FD5, 'M', u'龠'), + (0x2FD6, 'X'), + (0x3000, '3', u' '), + (0x3001, 'V'), + (0x3002, 'M', u'.'), + (0x3003, 'V'), + (0x3036, 'M', u'〒'), + (0x3037, 'V'), + (0x3038, 'M', u'十'), + (0x3039, 'M', u'卄'), + (0x303A, 'M', u'卅'), + (0x303B, 'V'), + (0x3040, 'X'), + (0x3041, 'V'), + (0x3097, 'X'), + (0x3099, 'V'), + (0x309B, '3', u' ゙'), + (0x309C, '3', u' ゚'), + (0x309D, 'V'), + (0x309F, 'M', u'より'), + (0x30A0, 'V'), + (0x30FF, 'M', u'コト'), + (0x3100, 'X'), + (0x3105, 'V'), + (0x312E, 'X'), + (0x3131, 'M', u'ᄀ'), + (0x3132, 'M', u'ᄁ'), + (0x3133, 'M', u'ᆪ'), + (0x3134, 'M', u'ᄂ'), + (0x3135, 'M', u'ᆬ'), + (0x3136, 'M', u'ᆭ'), + (0x3137, 'M', u'ᄃ'), + (0x3138, 'M', u'ᄄ'), + (0x3139, 'M', u'ᄅ'), + (0x313A, 'M', u'ᆰ'), + (0x313B, 'M', u'ᆱ'), + (0x313C, 'M', u'ᆲ'), + (0x313D, 'M', u'ᆳ'), + (0x313E, 'M', u'ᆴ'), + (0x313F, 'M', u'ᆵ'), + (0x3140, 'M', u'ᄚ'), + (0x3141, 'M', u'ᄆ'), + (0x3142, 'M', u'ᄇ'), + (0x3143, 'M', u'ᄈ'), + (0x3144, 'M', u'ᄡ'), + ] + +def _seg_29(): + return [ + (0x3145, 'M', u'ᄉ'), + (0x3146, 'M', u'ᄊ'), + (0x3147, 'M', u'ᄋ'), + (0x3148, 'M', u'ᄌ'), + (0x3149, 'M', u'ᄍ'), + (0x314A, 'M', u'ᄎ'), + (0x314B, 'M', u'ᄏ'), + (0x314C, 'M', u'ᄐ'), + (0x314D, 'M', u'ᄑ'), + (0x314E, 'M', u'ᄒ'), + (0x314F, 'M', u'ᅡ'), + (0x3150, 'M', u'ᅢ'), + (0x3151, 'M', u'ᅣ'), + (0x3152, 'M', u'ᅤ'), + (0x3153, 'M', u'ᅥ'), + (0x3154, 'M', u'ᅦ'), + (0x3155, 'M', u'ᅧ'), + (0x3156, 'M', u'ᅨ'), + (0x3157, 'M', u'ᅩ'), + (0x3158, 'M', u'ᅪ'), + (0x3159, 'M', u'ᅫ'), + (0x315A, 'M', u'ᅬ'), + (0x315B, 'M', u'ᅭ'), + (0x315C, 'M', u'ᅮ'), + (0x315D, 'M', u'ᅯ'), + (0x315E, 'M', u'ᅰ'), + (0x315F, 'M', u'ᅱ'), + (0x3160, 'M', u'ᅲ'), + (0x3161, 'M', u'ᅳ'), + (0x3162, 'M', u'ᅴ'), + (0x3163, 'M', u'ᅵ'), + (0x3164, 'X'), + (0x3165, 'M', u'ᄔ'), + (0x3166, 'M', u'ᄕ'), + (0x3167, 'M', u'ᇇ'), + (0x3168, 'M', u'ᇈ'), + (0x3169, 'M', u'ᇌ'), + (0x316A, 'M', u'ᇎ'), + (0x316B, 'M', u'ᇓ'), + (0x316C, 'M', u'ᇗ'), + (0x316D, 'M', u'ᇙ'), + (0x316E, 'M', u'ᄜ'), + (0x316F, 'M', u'ᇝ'), + (0x3170, 'M', u'ᇟ'), + (0x3171, 'M', u'ᄝ'), + (0x3172, 'M', u'ᄞ'), + (0x3173, 'M', u'ᄠ'), + (0x3174, 'M', u'ᄢ'), + (0x3175, 'M', u'ᄣ'), + (0x3176, 'M', u'ᄧ'), + (0x3177, 'M', u'ᄩ'), + (0x3178, 'M', u'ᄫ'), + (0x3179, 'M', u'ᄬ'), + (0x317A, 'M', u'ᄭ'), + (0x317B, 'M', u'ᄮ'), + (0x317C, 'M', u'ᄯ'), + (0x317D, 'M', u'ᄲ'), + (0x317E, 'M', u'ᄶ'), + (0x317F, 'M', u'ᅀ'), + (0x3180, 'M', u'ᅇ'), + (0x3181, 'M', u'ᅌ'), + (0x3182, 'M', u'ᇱ'), + (0x3183, 'M', u'ᇲ'), + (0x3184, 'M', u'ᅗ'), + (0x3185, 'M', u'ᅘ'), + (0x3186, 'M', u'ᅙ'), + (0x3187, 'M', u'ᆄ'), + (0x3188, 'M', u'ᆅ'), + (0x3189, 'M', u'ᆈ'), + (0x318A, 'M', u'ᆑ'), + (0x318B, 'M', u'ᆒ'), + (0x318C, 'M', u'ᆔ'), + (0x318D, 'M', u'ᆞ'), + (0x318E, 'M', u'ᆡ'), + (0x318F, 'X'), + (0x3190, 'V'), + (0x3192, 'M', u'一'), + (0x3193, 'M', u'二'), + (0x3194, 'M', u'三'), + (0x3195, 'M', u'四'), + (0x3196, 'M', u'上'), + (0x3197, 'M', u'中'), + (0x3198, 'M', u'下'), + (0x3199, 'M', u'甲'), + (0x319A, 'M', u'乙'), + (0x319B, 'M', u'丙'), + (0x319C, 'M', u'丁'), + (0x319D, 'M', u'天'), + (0x319E, 'M', u'地'), + (0x319F, 'M', u'人'), + (0x31A0, 'V'), + (0x31BB, 'X'), + (0x31C0, 'V'), + (0x31E4, 'X'), + (0x31F0, 'V'), + (0x3200, '3', u'(ᄀ)'), + (0x3201, '3', u'(ᄂ)'), + (0x3202, '3', u'(ᄃ)'), + (0x3203, '3', u'(ᄅ)'), + (0x3204, '3', u'(ᄆ)'), + ] + +def _seg_30(): + return [ + (0x3205, '3', u'(ᄇ)'), + (0x3206, '3', u'(ᄉ)'), + (0x3207, '3', u'(ᄋ)'), + (0x3208, '3', u'(ᄌ)'), + (0x3209, '3', u'(ᄎ)'), + (0x320A, '3', u'(ᄏ)'), + (0x320B, '3', u'(ᄐ)'), + (0x320C, '3', u'(ᄑ)'), + (0x320D, '3', u'(ᄒ)'), + (0x320E, '3', u'(가)'), + (0x320F, '3', u'(나)'), + (0x3210, '3', u'(다)'), + (0x3211, '3', u'(라)'), + (0x3212, '3', u'(마)'), + (0x3213, '3', u'(바)'), + (0x3214, '3', u'(사)'), + (0x3215, '3', u'(아)'), + (0x3216, '3', u'(자)'), + (0x3217, '3', u'(차)'), + (0x3218, '3', u'(카)'), + (0x3219, '3', u'(타)'), + (0x321A, '3', u'(파)'), + (0x321B, '3', u'(하)'), + (0x321C, '3', u'(주)'), + (0x321D, '3', u'(오전)'), + (0x321E, '3', u'(오후)'), + (0x321F, 'X'), + (0x3220, '3', u'(一)'), + (0x3221, '3', u'(二)'), + (0x3222, '3', u'(三)'), + (0x3223, '3', u'(四)'), + (0x3224, '3', u'(五)'), + (0x3225, '3', u'(六)'), + (0x3226, '3', u'(七)'), + (0x3227, '3', u'(八)'), + (0x3228, '3', u'(九)'), + (0x3229, '3', u'(十)'), + (0x322A, '3', u'(月)'), + (0x322B, '3', u'(火)'), + (0x322C, '3', u'(水)'), + (0x322D, '3', u'(木)'), + (0x322E, '3', u'(金)'), + (0x322F, '3', u'(土)'), + (0x3230, '3', u'(日)'), + (0x3231, '3', u'(株)'), + (0x3232, '3', u'(有)'), + (0x3233, '3', u'(社)'), + (0x3234, '3', u'(名)'), + (0x3235, '3', u'(特)'), + (0x3236, '3', u'(財)'), + (0x3237, '3', u'(祝)'), + (0x3238, '3', u'(労)'), + (0x3239, '3', u'(代)'), + (0x323A, '3', u'(呼)'), + (0x323B, '3', u'(学)'), + (0x323C, '3', u'(監)'), + (0x323D, '3', u'(企)'), + (0x323E, '3', u'(資)'), + (0x323F, '3', u'(協)'), + (0x3240, '3', u'(祭)'), + (0x3241, '3', u'(休)'), + (0x3242, '3', u'(自)'), + (0x3243, '3', u'(至)'), + (0x3244, 'M', u'問'), + (0x3245, 'M', u'幼'), + (0x3246, 'M', u'文'), + (0x3247, 'M', u'箏'), + (0x3248, 'V'), + (0x3250, 'M', u'pte'), + (0x3251, 'M', u'21'), + (0x3252, 'M', u'22'), + (0x3253, 'M', u'23'), + (0x3254, 'M', u'24'), + (0x3255, 'M', u'25'), + (0x3256, 'M', u'26'), + (0x3257, 'M', u'27'), + (0x3258, 'M', u'28'), + (0x3259, 'M', u'29'), + (0x325A, 'M', u'30'), + (0x325B, 'M', u'31'), + (0x325C, 'M', u'32'), + (0x325D, 'M', u'33'), + (0x325E, 'M', u'34'), + (0x325F, 'M', u'35'), + (0x3260, 'M', u'ᄀ'), + (0x3261, 'M', u'ᄂ'), + (0x3262, 'M', u'ᄃ'), + (0x3263, 'M', u'ᄅ'), + (0x3264, 'M', u'ᄆ'), + (0x3265, 'M', u'ᄇ'), + (0x3266, 'M', u'ᄉ'), + (0x3267, 'M', u'ᄋ'), + (0x3268, 'M', u'ᄌ'), + (0x3269, 'M', u'ᄎ'), + (0x326A, 'M', u'ᄏ'), + (0x326B, 'M', u'ᄐ'), + (0x326C, 'M', u'ᄑ'), + (0x326D, 'M', u'ᄒ'), + (0x326E, 'M', u'가'), + (0x326F, 'M', u'나'), + ] + +def _seg_31(): + return [ + (0x3270, 'M', u'다'), + (0x3271, 'M', u'라'), + (0x3272, 'M', u'마'), + (0x3273, 'M', u'바'), + (0x3274, 'M', u'사'), + (0x3275, 'M', u'아'), + (0x3276, 'M', u'자'), + (0x3277, 'M', u'차'), + (0x3278, 'M', u'카'), + (0x3279, 'M', u'타'), + (0x327A, 'M', u'파'), + (0x327B, 'M', u'하'), + (0x327C, 'M', u'참고'), + (0x327D, 'M', u'주의'), + (0x327E, 'M', u'우'), + (0x327F, 'V'), + (0x3280, 'M', u'一'), + (0x3281, 'M', u'二'), + (0x3282, 'M', u'三'), + (0x3283, 'M', u'四'), + (0x3284, 'M', u'五'), + (0x3285, 'M', u'六'), + (0x3286, 'M', u'七'), + (0x3287, 'M', u'八'), + (0x3288, 'M', u'九'), + (0x3289, 'M', u'十'), + (0x328A, 'M', u'月'), + (0x328B, 'M', u'火'), + (0x328C, 'M', u'水'), + (0x328D, 'M', u'木'), + (0x328E, 'M', u'金'), + (0x328F, 'M', u'土'), + (0x3290, 'M', u'日'), + (0x3291, 'M', u'株'), + (0x3292, 'M', u'有'), + (0x3293, 'M', u'社'), + (0x3294, 'M', u'名'), + (0x3295, 'M', u'特'), + (0x3296, 'M', u'財'), + (0x3297, 'M', u'祝'), + (0x3298, 'M', u'労'), + (0x3299, 'M', u'秘'), + (0x329A, 'M', u'男'), + (0x329B, 'M', u'女'), + (0x329C, 'M', u'適'), + (0x329D, 'M', u'優'), + (0x329E, 'M', u'印'), + (0x329F, 'M', u'注'), + (0x32A0, 'M', u'項'), + (0x32A1, 'M', u'休'), + (0x32A2, 'M', u'写'), + (0x32A3, 'M', u'正'), + (0x32A4, 'M', u'上'), + (0x32A5, 'M', u'中'), + (0x32A6, 'M', u'下'), + (0x32A7, 'M', u'左'), + (0x32A8, 'M', u'右'), + (0x32A9, 'M', u'医'), + (0x32AA, 'M', u'宗'), + (0x32AB, 'M', u'学'), + (0x32AC, 'M', u'監'), + (0x32AD, 'M', u'企'), + (0x32AE, 'M', u'資'), + (0x32AF, 'M', u'協'), + (0x32B0, 'M', u'夜'), + (0x32B1, 'M', u'36'), + (0x32B2, 'M', u'37'), + (0x32B3, 'M', u'38'), + (0x32B4, 'M', u'39'), + (0x32B5, 'M', u'40'), + (0x32B6, 'M', u'41'), + (0x32B7, 'M', u'42'), + (0x32B8, 'M', u'43'), + (0x32B9, 'M', u'44'), + (0x32BA, 'M', u'45'), + (0x32BB, 'M', u'46'), + (0x32BC, 'M', u'47'), + (0x32BD, 'M', u'48'), + (0x32BE, 'M', u'49'), + (0x32BF, 'M', u'50'), + (0x32C0, 'M', u'1月'), + (0x32C1, 'M', u'2月'), + (0x32C2, 'M', u'3月'), + (0x32C3, 'M', u'4月'), + (0x32C4, 'M', u'5月'), + (0x32C5, 'M', u'6月'), + (0x32C6, 'M', u'7月'), + (0x32C7, 'M', u'8月'), + (0x32C8, 'M', u'9月'), + (0x32C9, 'M', u'10月'), + (0x32CA, 'M', u'11月'), + (0x32CB, 'M', u'12月'), + (0x32CC, 'M', u'hg'), + (0x32CD, 'M', u'erg'), + (0x32CE, 'M', u'ev'), + (0x32CF, 'M', u'ltd'), + (0x32D0, 'M', u'ア'), + (0x32D1, 'M', u'イ'), + (0x32D2, 'M', u'ウ'), + (0x32D3, 'M', u'エ'), + ] + +def _seg_32(): + return [ + (0x32D4, 'M', u'オ'), + (0x32D5, 'M', u'カ'), + (0x32D6, 'M', u'キ'), + (0x32D7, 'M', u'ク'), + (0x32D8, 'M', u'ケ'), + (0x32D9, 'M', u'コ'), + (0x32DA, 'M', u'サ'), + (0x32DB, 'M', u'シ'), + (0x32DC, 'M', u'ス'), + (0x32DD, 'M', u'セ'), + (0x32DE, 'M', u'ソ'), + (0x32DF, 'M', u'タ'), + (0x32E0, 'M', u'チ'), + (0x32E1, 'M', u'ツ'), + (0x32E2, 'M', u'テ'), + (0x32E3, 'M', u'ト'), + (0x32E4, 'M', u'ナ'), + (0x32E5, 'M', u'ニ'), + (0x32E6, 'M', u'ヌ'), + (0x32E7, 'M', u'ネ'), + (0x32E8, 'M', u'ノ'), + (0x32E9, 'M', u'ハ'), + (0x32EA, 'M', u'ヒ'), + (0x32EB, 'M', u'フ'), + (0x32EC, 'M', u'ヘ'), + (0x32ED, 'M', u'ホ'), + (0x32EE, 'M', u'マ'), + (0x32EF, 'M', u'ミ'), + (0x32F0, 'M', u'ム'), + (0x32F1, 'M', u'メ'), + (0x32F2, 'M', u'モ'), + (0x32F3, 'M', u'ヤ'), + (0x32F4, 'M', u'ユ'), + (0x32F5, 'M', u'ヨ'), + (0x32F6, 'M', u'ラ'), + (0x32F7, 'M', u'リ'), + (0x32F8, 'M', u'ル'), + (0x32F9, 'M', u'レ'), + (0x32FA, 'M', u'ロ'), + (0x32FB, 'M', u'ワ'), + (0x32FC, 'M', u'ヰ'), + (0x32FD, 'M', u'ヱ'), + (0x32FE, 'M', u'ヲ'), + (0x32FF, 'X'), + (0x3300, 'M', u'アパート'), + (0x3301, 'M', u'アルファ'), + (0x3302, 'M', u'アンペア'), + (0x3303, 'M', u'アール'), + (0x3304, 'M', u'イニング'), + (0x3305, 'M', u'インチ'), + (0x3306, 'M', u'ウォン'), + (0x3307, 'M', u'エスクード'), + (0x3308, 'M', u'エーカー'), + (0x3309, 'M', u'オンス'), + (0x330A, 'M', u'オーム'), + (0x330B, 'M', u'カイリ'), + (0x330C, 'M', u'カラット'), + (0x330D, 'M', u'カロリー'), + (0x330E, 'M', u'ガロン'), + (0x330F, 'M', u'ガンマ'), + (0x3310, 'M', u'ギガ'), + (0x3311, 'M', u'ギニー'), + (0x3312, 'M', u'キュリー'), + (0x3313, 'M', u'ギルダー'), + (0x3314, 'M', u'キロ'), + (0x3315, 'M', u'キログラム'), + (0x3316, 'M', u'キロメートル'), + (0x3317, 'M', u'キロワット'), + (0x3318, 'M', u'グラム'), + (0x3319, 'M', u'グラムトン'), + (0x331A, 'M', u'クルゼイロ'), + (0x331B, 'M', u'クローネ'), + (0x331C, 'M', u'ケース'), + (0x331D, 'M', u'コルナ'), + (0x331E, 'M', u'コーポ'), + (0x331F, 'M', u'サイクル'), + (0x3320, 'M', u'サンチーム'), + (0x3321, 'M', u'シリング'), + (0x3322, 'M', u'センチ'), + (0x3323, 'M', u'セント'), + (0x3324, 'M', u'ダース'), + (0x3325, 'M', u'デシ'), + (0x3326, 'M', u'ドル'), + (0x3327, 'M', u'トン'), + (0x3328, 'M', u'ナノ'), + (0x3329, 'M', u'ノット'), + (0x332A, 'M', u'ハイツ'), + (0x332B, 'M', u'パーセント'), + (0x332C, 'M', u'パーツ'), + (0x332D, 'M', u'バーレル'), + (0x332E, 'M', u'ピアストル'), + (0x332F, 'M', u'ピクル'), + (0x3330, 'M', u'ピコ'), + (0x3331, 'M', u'ビル'), + (0x3332, 'M', u'ファラッド'), + (0x3333, 'M', u'フィート'), + (0x3334, 'M', u'ブッシェル'), + (0x3335, 'M', u'フラン'), + (0x3336, 'M', u'ヘクタール'), + (0x3337, 'M', u'ペソ'), + ] + +def _seg_33(): + return [ + (0x3338, 'M', u'ペニヒ'), + (0x3339, 'M', u'ヘルツ'), + (0x333A, 'M', u'ペンス'), + (0x333B, 'M', u'ページ'), + (0x333C, 'M', u'ベータ'), + (0x333D, 'M', u'ポイント'), + (0x333E, 'M', u'ボルト'), + (0x333F, 'M', u'ホン'), + (0x3340, 'M', u'ポンド'), + (0x3341, 'M', u'ホール'), + (0x3342, 'M', u'ホーン'), + (0x3343, 'M', u'マイクロ'), + (0x3344, 'M', u'マイル'), + (0x3345, 'M', u'マッハ'), + (0x3346, 'M', u'マルク'), + (0x3347, 'M', u'マンション'), + (0x3348, 'M', u'ミクロン'), + (0x3349, 'M', u'ミリ'), + (0x334A, 'M', u'ミリバール'), + (0x334B, 'M', u'メガ'), + (0x334C, 'M', u'メガトン'), + (0x334D, 'M', u'メートル'), + (0x334E, 'M', u'ヤード'), + (0x334F, 'M', u'ヤール'), + (0x3350, 'M', u'ユアン'), + (0x3351, 'M', u'リットル'), + (0x3352, 'M', u'リラ'), + (0x3353, 'M', u'ルピー'), + (0x3354, 'M', u'ルーブル'), + (0x3355, 'M', u'レム'), + (0x3356, 'M', u'レントゲン'), + (0x3357, 'M', u'ワット'), + (0x3358, 'M', u'0点'), + (0x3359, 'M', u'1点'), + (0x335A, 'M', u'2点'), + (0x335B, 'M', u'3点'), + (0x335C, 'M', u'4点'), + (0x335D, 'M', u'5点'), + (0x335E, 'M', u'6点'), + (0x335F, 'M', u'7点'), + (0x3360, 'M', u'8点'), + (0x3361, 'M', u'9点'), + (0x3362, 'M', u'10点'), + (0x3363, 'M', u'11点'), + (0x3364, 'M', u'12点'), + (0x3365, 'M', u'13点'), + (0x3366, 'M', u'14点'), + (0x3367, 'M', u'15点'), + (0x3368, 'M', u'16点'), + (0x3369, 'M', u'17点'), + (0x336A, 'M', u'18点'), + (0x336B, 'M', u'19点'), + (0x336C, 'M', u'20点'), + (0x336D, 'M', u'21点'), + (0x336E, 'M', u'22点'), + (0x336F, 'M', u'23点'), + (0x3370, 'M', u'24点'), + (0x3371, 'M', u'hpa'), + (0x3372, 'M', u'da'), + (0x3373, 'M', u'au'), + (0x3374, 'M', u'bar'), + (0x3375, 'M', u'ov'), + (0x3376, 'M', u'pc'), + (0x3377, 'M', u'dm'), + (0x3378, 'M', u'dm2'), + (0x3379, 'M', u'dm3'), + (0x337A, 'M', u'iu'), + (0x337B, 'M', u'平成'), + (0x337C, 'M', u'昭和'), + (0x337D, 'M', u'大正'), + (0x337E, 'M', u'明治'), + (0x337F, 'M', u'株式会社'), + (0x3380, 'M', u'pa'), + (0x3381, 'M', u'na'), + (0x3382, 'M', u'μa'), + (0x3383, 'M', u'ma'), + (0x3384, 'M', u'ka'), + (0x3385, 'M', u'kb'), + (0x3386, 'M', u'mb'), + (0x3387, 'M', u'gb'), + (0x3388, 'M', u'cal'), + (0x3389, 'M', u'kcal'), + (0x338A, 'M', u'pf'), + (0x338B, 'M', u'nf'), + (0x338C, 'M', u'μf'), + (0x338D, 'M', u'μg'), + (0x338E, 'M', u'mg'), + (0x338F, 'M', u'kg'), + (0x3390, 'M', u'hz'), + (0x3391, 'M', u'khz'), + (0x3392, 'M', u'mhz'), + (0x3393, 'M', u'ghz'), + (0x3394, 'M', u'thz'), + (0x3395, 'M', u'μl'), + (0x3396, 'M', u'ml'), + (0x3397, 'M', u'dl'), + (0x3398, 'M', u'kl'), + (0x3399, 'M', u'fm'), + (0x339A, 'M', u'nm'), + (0x339B, 'M', u'μm'), + ] + +def _seg_34(): + return [ + (0x339C, 'M', u'mm'), + (0x339D, 'M', u'cm'), + (0x339E, 'M', u'km'), + (0x339F, 'M', u'mm2'), + (0x33A0, 'M', u'cm2'), + (0x33A1, 'M', u'm2'), + (0x33A2, 'M', u'km2'), + (0x33A3, 'M', u'mm3'), + (0x33A4, 'M', u'cm3'), + (0x33A5, 'M', u'm3'), + (0x33A6, 'M', u'km3'), + (0x33A7, 'M', u'm∕s'), + (0x33A8, 'M', u'm∕s2'), + (0x33A9, 'M', u'pa'), + (0x33AA, 'M', u'kpa'), + (0x33AB, 'M', u'mpa'), + (0x33AC, 'M', u'gpa'), + (0x33AD, 'M', u'rad'), + (0x33AE, 'M', u'rad∕s'), + (0x33AF, 'M', u'rad∕s2'), + (0x33B0, 'M', u'ps'), + (0x33B1, 'M', u'ns'), + (0x33B2, 'M', u'μs'), + (0x33B3, 'M', u'ms'), + (0x33B4, 'M', u'pv'), + (0x33B5, 'M', u'nv'), + (0x33B6, 'M', u'μv'), + (0x33B7, 'M', u'mv'), + (0x33B8, 'M', u'kv'), + (0x33B9, 'M', u'mv'), + (0x33BA, 'M', u'pw'), + (0x33BB, 'M', u'nw'), + (0x33BC, 'M', u'μw'), + (0x33BD, 'M', u'mw'), + (0x33BE, 'M', u'kw'), + (0x33BF, 'M', u'mw'), + (0x33C0, 'M', u'kω'), + (0x33C1, 'M', u'mω'), + (0x33C2, 'X'), + (0x33C3, 'M', u'bq'), + (0x33C4, 'M', u'cc'), + (0x33C5, 'M', u'cd'), + (0x33C6, 'M', u'c∕kg'), + (0x33C7, 'X'), + (0x33C8, 'M', u'db'), + (0x33C9, 'M', u'gy'), + (0x33CA, 'M', u'ha'), + (0x33CB, 'M', u'hp'), + (0x33CC, 'M', u'in'), + (0x33CD, 'M', u'kk'), + (0x33CE, 'M', u'km'), + (0x33CF, 'M', u'kt'), + (0x33D0, 'M', u'lm'), + (0x33D1, 'M', u'ln'), + (0x33D2, 'M', u'log'), + (0x33D3, 'M', u'lx'), + (0x33D4, 'M', u'mb'), + (0x33D5, 'M', u'mil'), + (0x33D6, 'M', u'mol'), + (0x33D7, 'M', u'ph'), + (0x33D8, 'X'), + (0x33D9, 'M', u'ppm'), + (0x33DA, 'M', u'pr'), + (0x33DB, 'M', u'sr'), + (0x33DC, 'M', u'sv'), + (0x33DD, 'M', u'wb'), + (0x33DE, 'M', u'v∕m'), + (0x33DF, 'M', u'a∕m'), + (0x33E0, 'M', u'1日'), + (0x33E1, 'M', u'2日'), + (0x33E2, 'M', u'3日'), + (0x33E3, 'M', u'4日'), + (0x33E4, 'M', u'5日'), + (0x33E5, 'M', u'6日'), + (0x33E6, 'M', u'7日'), + (0x33E7, 'M', u'8日'), + (0x33E8, 'M', u'9日'), + (0x33E9, 'M', u'10日'), + (0x33EA, 'M', u'11日'), + (0x33EB, 'M', u'12日'), + (0x33EC, 'M', u'13日'), + (0x33ED, 'M', u'14日'), + (0x33EE, 'M', u'15日'), + (0x33EF, 'M', u'16日'), + (0x33F0, 'M', u'17日'), + (0x33F1, 'M', u'18日'), + (0x33F2, 'M', u'19日'), + (0x33F3, 'M', u'20日'), + (0x33F4, 'M', u'21日'), + (0x33F5, 'M', u'22日'), + (0x33F6, 'M', u'23日'), + (0x33F7, 'M', u'24日'), + (0x33F8, 'M', u'25日'), + (0x33F9, 'M', u'26日'), + (0x33FA, 'M', u'27日'), + (0x33FB, 'M', u'28日'), + (0x33FC, 'M', u'29日'), + (0x33FD, 'M', u'30日'), + (0x33FE, 'M', u'31日'), + (0x33FF, 'M', u'gal'), + ] + +def _seg_35(): + return [ + (0x3400, 'V'), + (0x4DB6, 'X'), + (0x4DC0, 'V'), + (0x9FCD, 'X'), + (0xA000, 'V'), + (0xA48D, 'X'), + (0xA490, 'V'), + (0xA4C7, 'X'), + (0xA4D0, 'V'), + (0xA62C, 'X'), + (0xA640, 'M', u'ꙁ'), + (0xA641, 'V'), + (0xA642, 'M', u'ꙃ'), + (0xA643, 'V'), + (0xA644, 'M', u'ꙅ'), + (0xA645, 'V'), + (0xA646, 'M', u'ꙇ'), + (0xA647, 'V'), + (0xA648, 'M', u'ꙉ'), + (0xA649, 'V'), + (0xA64A, 'M', u'ꙋ'), + (0xA64B, 'V'), + (0xA64C, 'M', u'ꙍ'), + (0xA64D, 'V'), + (0xA64E, 'M', u'ꙏ'), + (0xA64F, 'V'), + (0xA650, 'M', u'ꙑ'), + (0xA651, 'V'), + (0xA652, 'M', u'ꙓ'), + (0xA653, 'V'), + (0xA654, 'M', u'ꙕ'), + (0xA655, 'V'), + (0xA656, 'M', u'ꙗ'), + (0xA657, 'V'), + (0xA658, 'M', u'ꙙ'), + (0xA659, 'V'), + (0xA65A, 'M', u'ꙛ'), + (0xA65B, 'V'), + (0xA65C, 'M', u'ꙝ'), + (0xA65D, 'V'), + (0xA65E, 'M', u'ꙟ'), + (0xA65F, 'V'), + (0xA660, 'M', u'ꙡ'), + (0xA661, 'V'), + (0xA662, 'M', u'ꙣ'), + (0xA663, 'V'), + (0xA664, 'M', u'ꙥ'), + (0xA665, 'V'), + (0xA666, 'M', u'ꙧ'), + (0xA667, 'V'), + (0xA668, 'M', u'ꙩ'), + (0xA669, 'V'), + (0xA66A, 'M', u'ꙫ'), + (0xA66B, 'V'), + (0xA66C, 'M', u'ꙭ'), + (0xA66D, 'V'), + (0xA680, 'M', u'ꚁ'), + (0xA681, 'V'), + (0xA682, 'M', u'ꚃ'), + (0xA683, 'V'), + (0xA684, 'M', u'ꚅ'), + (0xA685, 'V'), + (0xA686, 'M', u'ꚇ'), + (0xA687, 'V'), + (0xA688, 'M', u'ꚉ'), + (0xA689, 'V'), + (0xA68A, 'M', u'ꚋ'), + (0xA68B, 'V'), + (0xA68C, 'M', u'ꚍ'), + (0xA68D, 'V'), + (0xA68E, 'M', u'ꚏ'), + (0xA68F, 'V'), + (0xA690, 'M', u'ꚑ'), + (0xA691, 'V'), + (0xA692, 'M', u'ꚓ'), + (0xA693, 'V'), + (0xA694, 'M', u'ꚕ'), + (0xA695, 'V'), + (0xA696, 'M', u'ꚗ'), + (0xA697, 'V'), + (0xA698, 'X'), + (0xA69F, 'V'), + (0xA6F8, 'X'), + (0xA700, 'V'), + (0xA722, 'M', u'ꜣ'), + (0xA723, 'V'), + (0xA724, 'M', u'ꜥ'), + (0xA725, 'V'), + (0xA726, 'M', u'ꜧ'), + (0xA727, 'V'), + (0xA728, 'M', u'ꜩ'), + (0xA729, 'V'), + (0xA72A, 'M', u'ꜫ'), + (0xA72B, 'V'), + (0xA72C, 'M', u'ꜭ'), + (0xA72D, 'V'), + (0xA72E, 'M', u'ꜯ'), + (0xA72F, 'V'), + (0xA732, 'M', u'ꜳ'), + (0xA733, 'V'), + ] + +def _seg_36(): + return [ + (0xA734, 'M', u'ꜵ'), + (0xA735, 'V'), + (0xA736, 'M', u'ꜷ'), + (0xA737, 'V'), + (0xA738, 'M', u'ꜹ'), + (0xA739, 'V'), + (0xA73A, 'M', u'ꜻ'), + (0xA73B, 'V'), + (0xA73C, 'M', u'ꜽ'), + (0xA73D, 'V'), + (0xA73E, 'M', u'ꜿ'), + (0xA73F, 'V'), + (0xA740, 'M', u'ꝁ'), + (0xA741, 'V'), + (0xA742, 'M', u'ꝃ'), + (0xA743, 'V'), + (0xA744, 'M', u'ꝅ'), + (0xA745, 'V'), + (0xA746, 'M', u'ꝇ'), + (0xA747, 'V'), + (0xA748, 'M', u'ꝉ'), + (0xA749, 'V'), + (0xA74A, 'M', u'ꝋ'), + (0xA74B, 'V'), + (0xA74C, 'M', u'ꝍ'), + (0xA74D, 'V'), + (0xA74E, 'M', u'ꝏ'), + (0xA74F, 'V'), + (0xA750, 'M', u'ꝑ'), + (0xA751, 'V'), + (0xA752, 'M', u'ꝓ'), + (0xA753, 'V'), + (0xA754, 'M', u'ꝕ'), + (0xA755, 'V'), + (0xA756, 'M', u'ꝗ'), + (0xA757, 'V'), + (0xA758, 'M', u'ꝙ'), + (0xA759, 'V'), + (0xA75A, 'M', u'ꝛ'), + (0xA75B, 'V'), + (0xA75C, 'M', u'ꝝ'), + (0xA75D, 'V'), + (0xA75E, 'M', u'ꝟ'), + (0xA75F, 'V'), + (0xA760, 'M', u'ꝡ'), + (0xA761, 'V'), + (0xA762, 'M', u'ꝣ'), + (0xA763, 'V'), + (0xA764, 'M', u'ꝥ'), + (0xA765, 'V'), + (0xA766, 'M', u'ꝧ'), + (0xA767, 'V'), + (0xA768, 'M', u'ꝩ'), + (0xA769, 'V'), + (0xA76A, 'M', u'ꝫ'), + (0xA76B, 'V'), + (0xA76C, 'M', u'ꝭ'), + (0xA76D, 'V'), + (0xA76E, 'M', u'ꝯ'), + (0xA76F, 'V'), + (0xA770, 'M', u'ꝯ'), + (0xA771, 'V'), + (0xA779, 'M', u'ꝺ'), + (0xA77A, 'V'), + (0xA77B, 'M', u'ꝼ'), + (0xA77C, 'V'), + (0xA77D, 'M', u'ᵹ'), + (0xA77E, 'M', u'ꝿ'), + (0xA77F, 'V'), + (0xA780, 'M', u'ꞁ'), + (0xA781, 'V'), + (0xA782, 'M', u'ꞃ'), + (0xA783, 'V'), + (0xA784, 'M', u'ꞅ'), + (0xA785, 'V'), + (0xA786, 'M', u'ꞇ'), + (0xA787, 'V'), + (0xA78B, 'M', u'ꞌ'), + (0xA78C, 'V'), + (0xA78D, 'M', u'ɥ'), + (0xA78E, 'V'), + (0xA78F, 'X'), + (0xA790, 'M', u'ꞑ'), + (0xA791, 'V'), + (0xA792, 'M', u'ꞓ'), + (0xA793, 'V'), + (0xA794, 'X'), + (0xA7A0, 'M', u'ꞡ'), + (0xA7A1, 'V'), + (0xA7A2, 'M', u'ꞣ'), + (0xA7A3, 'V'), + (0xA7A4, 'M', u'ꞥ'), + (0xA7A5, 'V'), + (0xA7A6, 'M', u'ꞧ'), + (0xA7A7, 'V'), + (0xA7A8, 'M', u'ꞩ'), + (0xA7A9, 'V'), + (0xA7AA, 'M', u'ɦ'), + (0xA7AB, 'X'), + (0xA7F8, 'M', u'ħ'), + ] + +def _seg_37(): + return [ + (0xA7F9, 'M', u'œ'), + (0xA7FA, 'V'), + (0xA82C, 'X'), + (0xA830, 'V'), + (0xA83A, 'X'), + (0xA840, 'V'), + (0xA878, 'X'), + (0xA880, 'V'), + (0xA8C5, 'X'), + (0xA8CE, 'V'), + (0xA8DA, 'X'), + (0xA8E0, 'V'), + (0xA8FC, 'X'), + (0xA900, 'V'), + (0xA954, 'X'), + (0xA95F, 'V'), + (0xA97D, 'X'), + (0xA980, 'V'), + (0xA9CE, 'X'), + (0xA9CF, 'V'), + (0xA9DA, 'X'), + (0xA9DE, 'V'), + (0xA9E0, 'X'), + (0xAA00, 'V'), + (0xAA37, 'X'), + (0xAA40, 'V'), + (0xAA4E, 'X'), + (0xAA50, 'V'), + (0xAA5A, 'X'), + (0xAA5C, 'V'), + (0xAA7C, 'X'), + (0xAA80, 'V'), + (0xAAC3, 'X'), + (0xAADB, 'V'), + (0xAAF7, 'X'), + (0xAB01, 'V'), + (0xAB07, 'X'), + (0xAB09, 'V'), + (0xAB0F, 'X'), + (0xAB11, 'V'), + (0xAB17, 'X'), + (0xAB20, 'V'), + (0xAB27, 'X'), + (0xAB28, 'V'), + (0xAB2F, 'X'), + (0xABC0, 'V'), + (0xABEE, 'X'), + (0xABF0, 'V'), + (0xABFA, 'X'), + (0xAC00, 'V'), + (0xD7A4, 'X'), + (0xD7B0, 'V'), + (0xD7C7, 'X'), + (0xD7CB, 'V'), + (0xD7FC, 'X'), + (0xF900, 'M', u'豈'), + (0xF901, 'M', u'更'), + (0xF902, 'M', u'車'), + (0xF903, 'M', u'賈'), + (0xF904, 'M', u'滑'), + (0xF905, 'M', u'串'), + (0xF906, 'M', u'句'), + (0xF907, 'M', u'龜'), + (0xF909, 'M', u'契'), + (0xF90A, 'M', u'金'), + (0xF90B, 'M', u'喇'), + (0xF90C, 'M', u'奈'), + (0xF90D, 'M', u'懶'), + (0xF90E, 'M', u'癩'), + (0xF90F, 'M', u'羅'), + (0xF910, 'M', u'蘿'), + (0xF911, 'M', u'螺'), + (0xF912, 'M', u'裸'), + (0xF913, 'M', u'邏'), + (0xF914, 'M', u'樂'), + (0xF915, 'M', u'洛'), + (0xF916, 'M', u'烙'), + (0xF917, 'M', u'珞'), + (0xF918, 'M', u'落'), + (0xF919, 'M', u'酪'), + (0xF91A, 'M', u'駱'), + (0xF91B, 'M', u'亂'), + (0xF91C, 'M', u'卵'), + (0xF91D, 'M', u'欄'), + (0xF91E, 'M', u'爛'), + (0xF91F, 'M', u'蘭'), + (0xF920, 'M', u'鸞'), + (0xF921, 'M', u'嵐'), + (0xF922, 'M', u'濫'), + (0xF923, 'M', u'藍'), + (0xF924, 'M', u'襤'), + (0xF925, 'M', u'拉'), + (0xF926, 'M', u'臘'), + (0xF927, 'M', u'蠟'), + (0xF928, 'M', u'廊'), + (0xF929, 'M', u'朗'), + (0xF92A, 'M', u'浪'), + (0xF92B, 'M', u'狼'), + (0xF92C, 'M', u'郎'), + (0xF92D, 'M', u'來'), + ] + +def _seg_38(): + return [ + (0xF92E, 'M', u'冷'), + (0xF92F, 'M', u'勞'), + (0xF930, 'M', u'擄'), + (0xF931, 'M', u'櫓'), + (0xF932, 'M', u'爐'), + (0xF933, 'M', u'盧'), + (0xF934, 'M', u'老'), + (0xF935, 'M', u'蘆'), + (0xF936, 'M', u'虜'), + (0xF937, 'M', u'路'), + (0xF938, 'M', u'露'), + (0xF939, 'M', u'魯'), + (0xF93A, 'M', u'鷺'), + (0xF93B, 'M', u'碌'), + (0xF93C, 'M', u'祿'), + (0xF93D, 'M', u'綠'), + (0xF93E, 'M', u'菉'), + (0xF93F, 'M', u'錄'), + (0xF940, 'M', u'鹿'), + (0xF941, 'M', u'論'), + (0xF942, 'M', u'壟'), + (0xF943, 'M', u'弄'), + (0xF944, 'M', u'籠'), + (0xF945, 'M', u'聾'), + (0xF946, 'M', u'牢'), + (0xF947, 'M', u'磊'), + (0xF948, 'M', u'賂'), + (0xF949, 'M', u'雷'), + (0xF94A, 'M', u'壘'), + (0xF94B, 'M', u'屢'), + (0xF94C, 'M', u'樓'), + (0xF94D, 'M', u'淚'), + (0xF94E, 'M', u'漏'), + (0xF94F, 'M', u'累'), + (0xF950, 'M', u'縷'), + (0xF951, 'M', u'陋'), + (0xF952, 'M', u'勒'), + (0xF953, 'M', u'肋'), + (0xF954, 'M', u'凜'), + (0xF955, 'M', u'凌'), + (0xF956, 'M', u'稜'), + (0xF957, 'M', u'綾'), + (0xF958, 'M', u'菱'), + (0xF959, 'M', u'陵'), + (0xF95A, 'M', u'讀'), + (0xF95B, 'M', u'拏'), + (0xF95C, 'M', u'樂'), + (0xF95D, 'M', u'諾'), + (0xF95E, 'M', u'丹'), + (0xF95F, 'M', u'寧'), + (0xF960, 'M', u'怒'), + (0xF961, 'M', u'率'), + (0xF962, 'M', u'異'), + (0xF963, 'M', u'北'), + (0xF964, 'M', u'磻'), + (0xF965, 'M', u'便'), + (0xF966, 'M', u'復'), + (0xF967, 'M', u'不'), + (0xF968, 'M', u'泌'), + (0xF969, 'M', u'數'), + (0xF96A, 'M', u'索'), + (0xF96B, 'M', u'參'), + (0xF96C, 'M', u'塞'), + (0xF96D, 'M', u'省'), + (0xF96E, 'M', u'葉'), + (0xF96F, 'M', u'說'), + (0xF970, 'M', u'殺'), + (0xF971, 'M', u'辰'), + (0xF972, 'M', u'沈'), + (0xF973, 'M', u'拾'), + (0xF974, 'M', u'若'), + (0xF975, 'M', u'掠'), + (0xF976, 'M', u'略'), + (0xF977, 'M', u'亮'), + (0xF978, 'M', u'兩'), + (0xF979, 'M', u'凉'), + (0xF97A, 'M', u'梁'), + (0xF97B, 'M', u'糧'), + (0xF97C, 'M', u'良'), + (0xF97D, 'M', u'諒'), + (0xF97E, 'M', u'量'), + (0xF97F, 'M', u'勵'), + (0xF980, 'M', u'呂'), + (0xF981, 'M', u'女'), + (0xF982, 'M', u'廬'), + (0xF983, 'M', u'旅'), + (0xF984, 'M', u'濾'), + (0xF985, 'M', u'礪'), + (0xF986, 'M', u'閭'), + (0xF987, 'M', u'驪'), + (0xF988, 'M', u'麗'), + (0xF989, 'M', u'黎'), + (0xF98A, 'M', u'力'), + (0xF98B, 'M', u'曆'), + (0xF98C, 'M', u'歷'), + (0xF98D, 'M', u'轢'), + (0xF98E, 'M', u'年'), + (0xF98F, 'M', u'憐'), + (0xF990, 'M', u'戀'), + (0xF991, 'M', u'撚'), + ] + +def _seg_39(): + return [ + (0xF992, 'M', u'漣'), + (0xF993, 'M', u'煉'), + (0xF994, 'M', u'璉'), + (0xF995, 'M', u'秊'), + (0xF996, 'M', u'練'), + (0xF997, 'M', u'聯'), + (0xF998, 'M', u'輦'), + (0xF999, 'M', u'蓮'), + (0xF99A, 'M', u'連'), + (0xF99B, 'M', u'鍊'), + (0xF99C, 'M', u'列'), + (0xF99D, 'M', u'劣'), + (0xF99E, 'M', u'咽'), + (0xF99F, 'M', u'烈'), + (0xF9A0, 'M', u'裂'), + (0xF9A1, 'M', u'說'), + (0xF9A2, 'M', u'廉'), + (0xF9A3, 'M', u'念'), + (0xF9A4, 'M', u'捻'), + (0xF9A5, 'M', u'殮'), + (0xF9A6, 'M', u'簾'), + (0xF9A7, 'M', u'獵'), + (0xF9A8, 'M', u'令'), + (0xF9A9, 'M', u'囹'), + (0xF9AA, 'M', u'寧'), + (0xF9AB, 'M', u'嶺'), + (0xF9AC, 'M', u'怜'), + (0xF9AD, 'M', u'玲'), + (0xF9AE, 'M', u'瑩'), + (0xF9AF, 'M', u'羚'), + (0xF9B0, 'M', u'聆'), + (0xF9B1, 'M', u'鈴'), + (0xF9B2, 'M', u'零'), + (0xF9B3, 'M', u'靈'), + (0xF9B4, 'M', u'領'), + (0xF9B5, 'M', u'例'), + (0xF9B6, 'M', u'禮'), + (0xF9B7, 'M', u'醴'), + (0xF9B8, 'M', u'隸'), + (0xF9B9, 'M', u'惡'), + (0xF9BA, 'M', u'了'), + (0xF9BB, 'M', u'僚'), + (0xF9BC, 'M', u'寮'), + (0xF9BD, 'M', u'尿'), + (0xF9BE, 'M', u'料'), + (0xF9BF, 'M', u'樂'), + (0xF9C0, 'M', u'燎'), + (0xF9C1, 'M', u'療'), + (0xF9C2, 'M', u'蓼'), + (0xF9C3, 'M', u'遼'), + (0xF9C4, 'M', u'龍'), + (0xF9C5, 'M', u'暈'), + (0xF9C6, 'M', u'阮'), + (0xF9C7, 'M', u'劉'), + (0xF9C8, 'M', u'杻'), + (0xF9C9, 'M', u'柳'), + (0xF9CA, 'M', u'流'), + (0xF9CB, 'M', u'溜'), + (0xF9CC, 'M', u'琉'), + (0xF9CD, 'M', u'留'), + (0xF9CE, 'M', u'硫'), + (0xF9CF, 'M', u'紐'), + (0xF9D0, 'M', u'類'), + (0xF9D1, 'M', u'六'), + (0xF9D2, 'M', u'戮'), + (0xF9D3, 'M', u'陸'), + (0xF9D4, 'M', u'倫'), + (0xF9D5, 'M', u'崙'), + (0xF9D6, 'M', u'淪'), + (0xF9D7, 'M', u'輪'), + (0xF9D8, 'M', u'律'), + (0xF9D9, 'M', u'慄'), + (0xF9DA, 'M', u'栗'), + (0xF9DB, 'M', u'率'), + (0xF9DC, 'M', u'隆'), + (0xF9DD, 'M', u'利'), + (0xF9DE, 'M', u'吏'), + (0xF9DF, 'M', u'履'), + (0xF9E0, 'M', u'易'), + (0xF9E1, 'M', u'李'), + (0xF9E2, 'M', u'梨'), + (0xF9E3, 'M', u'泥'), + (0xF9E4, 'M', u'理'), + (0xF9E5, 'M', u'痢'), + (0xF9E6, 'M', u'罹'), + (0xF9E7, 'M', u'裏'), + (0xF9E8, 'M', u'裡'), + (0xF9E9, 'M', u'里'), + (0xF9EA, 'M', u'離'), + (0xF9EB, 'M', u'匿'), + (0xF9EC, 'M', u'溺'), + (0xF9ED, 'M', u'吝'), + (0xF9EE, 'M', u'燐'), + (0xF9EF, 'M', u'璘'), + (0xF9F0, 'M', u'藺'), + (0xF9F1, 'M', u'隣'), + (0xF9F2, 'M', u'鱗'), + (0xF9F3, 'M', u'麟'), + (0xF9F4, 'M', u'林'), + (0xF9F5, 'M', u'淋'), + ] + +def _seg_40(): + return [ + (0xF9F6, 'M', u'臨'), + (0xF9F7, 'M', u'立'), + (0xF9F8, 'M', u'笠'), + (0xF9F9, 'M', u'粒'), + (0xF9FA, 'M', u'狀'), + (0xF9FB, 'M', u'炙'), + (0xF9FC, 'M', u'識'), + (0xF9FD, 'M', u'什'), + (0xF9FE, 'M', u'茶'), + (0xF9FF, 'M', u'刺'), + (0xFA00, 'M', u'切'), + (0xFA01, 'M', u'度'), + (0xFA02, 'M', u'拓'), + (0xFA03, 'M', u'糖'), + (0xFA04, 'M', u'宅'), + (0xFA05, 'M', u'洞'), + (0xFA06, 'M', u'暴'), + (0xFA07, 'M', u'輻'), + (0xFA08, 'M', u'行'), + (0xFA09, 'M', u'降'), + (0xFA0A, 'M', u'見'), + (0xFA0B, 'M', u'廓'), + (0xFA0C, 'M', u'兀'), + (0xFA0D, 'M', u'嗀'), + (0xFA0E, 'V'), + (0xFA10, 'M', u'塚'), + (0xFA11, 'V'), + (0xFA12, 'M', u'晴'), + (0xFA13, 'V'), + (0xFA15, 'M', u'凞'), + (0xFA16, 'M', u'猪'), + (0xFA17, 'M', u'益'), + (0xFA18, 'M', u'礼'), + (0xFA19, 'M', u'神'), + (0xFA1A, 'M', u'祥'), + (0xFA1B, 'M', u'福'), + (0xFA1C, 'M', u'靖'), + (0xFA1D, 'M', u'精'), + (0xFA1E, 'M', u'羽'), + (0xFA1F, 'V'), + (0xFA20, 'M', u'蘒'), + (0xFA21, 'V'), + (0xFA22, 'M', u'諸'), + (0xFA23, 'V'), + (0xFA25, 'M', u'逸'), + (0xFA26, 'M', u'都'), + (0xFA27, 'V'), + (0xFA2A, 'M', u'飯'), + (0xFA2B, 'M', u'飼'), + (0xFA2C, 'M', u'館'), + (0xFA2D, 'M', u'鶴'), + (0xFA2E, 'M', u'郞'), + (0xFA2F, 'M', u'隷'), + (0xFA30, 'M', u'侮'), + (0xFA31, 'M', u'僧'), + (0xFA32, 'M', u'免'), + (0xFA33, 'M', u'勉'), + (0xFA34, 'M', u'勤'), + (0xFA35, 'M', u'卑'), + (0xFA36, 'M', u'喝'), + (0xFA37, 'M', u'嘆'), + (0xFA38, 'M', u'器'), + (0xFA39, 'M', u'塀'), + (0xFA3A, 'M', u'墨'), + (0xFA3B, 'M', u'層'), + (0xFA3C, 'M', u'屮'), + (0xFA3D, 'M', u'悔'), + (0xFA3E, 'M', u'慨'), + (0xFA3F, 'M', u'憎'), + (0xFA40, 'M', u'懲'), + (0xFA41, 'M', u'敏'), + (0xFA42, 'M', u'既'), + (0xFA43, 'M', u'暑'), + (0xFA44, 'M', u'梅'), + (0xFA45, 'M', u'海'), + (0xFA46, 'M', u'渚'), + (0xFA47, 'M', u'漢'), + (0xFA48, 'M', u'煮'), + (0xFA49, 'M', u'爫'), + (0xFA4A, 'M', u'琢'), + (0xFA4B, 'M', u'碑'), + (0xFA4C, 'M', u'社'), + (0xFA4D, 'M', u'祉'), + (0xFA4E, 'M', u'祈'), + (0xFA4F, 'M', u'祐'), + (0xFA50, 'M', u'祖'), + (0xFA51, 'M', u'祝'), + (0xFA52, 'M', u'禍'), + (0xFA53, 'M', u'禎'), + (0xFA54, 'M', u'穀'), + (0xFA55, 'M', u'突'), + (0xFA56, 'M', u'節'), + (0xFA57, 'M', u'練'), + (0xFA58, 'M', u'縉'), + (0xFA59, 'M', u'繁'), + (0xFA5A, 'M', u'署'), + (0xFA5B, 'M', u'者'), + (0xFA5C, 'M', u'臭'), + (0xFA5D, 'M', u'艹'), + (0xFA5F, 'M', u'著'), + ] + +def _seg_41(): + return [ + (0xFA60, 'M', u'褐'), + (0xFA61, 'M', u'視'), + (0xFA62, 'M', u'謁'), + (0xFA63, 'M', u'謹'), + (0xFA64, 'M', u'賓'), + (0xFA65, 'M', u'贈'), + (0xFA66, 'M', u'辶'), + (0xFA67, 'M', u'逸'), + (0xFA68, 'M', u'難'), + (0xFA69, 'M', u'響'), + (0xFA6A, 'M', u'頻'), + (0xFA6B, 'M', u'恵'), + (0xFA6C, 'M', u'𤋮'), + (0xFA6D, 'M', u'舘'), + (0xFA6E, 'X'), + (0xFA70, 'M', u'並'), + (0xFA71, 'M', u'况'), + (0xFA72, 'M', u'全'), + (0xFA73, 'M', u'侀'), + (0xFA74, 'M', u'充'), + (0xFA75, 'M', u'冀'), + (0xFA76, 'M', u'勇'), + (0xFA77, 'M', u'勺'), + (0xFA78, 'M', u'喝'), + (0xFA79, 'M', u'啕'), + (0xFA7A, 'M', u'喙'), + (0xFA7B, 'M', u'嗢'), + (0xFA7C, 'M', u'塚'), + (0xFA7D, 'M', u'墳'), + (0xFA7E, 'M', u'奄'), + (0xFA7F, 'M', u'奔'), + (0xFA80, 'M', u'婢'), + (0xFA81, 'M', u'嬨'), + (0xFA82, 'M', u'廒'), + (0xFA83, 'M', u'廙'), + (0xFA84, 'M', u'彩'), + (0xFA85, 'M', u'徭'), + (0xFA86, 'M', u'惘'), + (0xFA87, 'M', u'慎'), + (0xFA88, 'M', u'愈'), + (0xFA89, 'M', u'憎'), + (0xFA8A, 'M', u'慠'), + (0xFA8B, 'M', u'懲'), + (0xFA8C, 'M', u'戴'), + (0xFA8D, 'M', u'揄'), + (0xFA8E, 'M', u'搜'), + (0xFA8F, 'M', u'摒'), + (0xFA90, 'M', u'敖'), + (0xFA91, 'M', u'晴'), + (0xFA92, 'M', u'朗'), + (0xFA93, 'M', u'望'), + (0xFA94, 'M', u'杖'), + (0xFA95, 'M', u'歹'), + (0xFA96, 'M', u'殺'), + (0xFA97, 'M', u'流'), + (0xFA98, 'M', u'滛'), + (0xFA99, 'M', u'滋'), + (0xFA9A, 'M', u'漢'), + (0xFA9B, 'M', u'瀞'), + (0xFA9C, 'M', u'煮'), + (0xFA9D, 'M', u'瞧'), + (0xFA9E, 'M', u'爵'), + (0xFA9F, 'M', u'犯'), + (0xFAA0, 'M', u'猪'), + (0xFAA1, 'M', u'瑱'), + (0xFAA2, 'M', u'甆'), + (0xFAA3, 'M', u'画'), + (0xFAA4, 'M', u'瘝'), + (0xFAA5, 'M', u'瘟'), + (0xFAA6, 'M', u'益'), + (0xFAA7, 'M', u'盛'), + (0xFAA8, 'M', u'直'), + (0xFAA9, 'M', u'睊'), + (0xFAAA, 'M', u'着'), + (0xFAAB, 'M', u'磌'), + (0xFAAC, 'M', u'窱'), + (0xFAAD, 'M', u'節'), + (0xFAAE, 'M', u'类'), + (0xFAAF, 'M', u'絛'), + (0xFAB0, 'M', u'練'), + (0xFAB1, 'M', u'缾'), + (0xFAB2, 'M', u'者'), + (0xFAB3, 'M', u'荒'), + (0xFAB4, 'M', u'華'), + (0xFAB5, 'M', u'蝹'), + (0xFAB6, 'M', u'襁'), + (0xFAB7, 'M', u'覆'), + (0xFAB8, 'M', u'視'), + (0xFAB9, 'M', u'調'), + (0xFABA, 'M', u'諸'), + (0xFABB, 'M', u'請'), + (0xFABC, 'M', u'謁'), + (0xFABD, 'M', u'諾'), + (0xFABE, 'M', u'諭'), + (0xFABF, 'M', u'謹'), + (0xFAC0, 'M', u'變'), + (0xFAC1, 'M', u'贈'), + (0xFAC2, 'M', u'輸'), + (0xFAC3, 'M', u'遲'), + (0xFAC4, 'M', u'醙'), + ] + +def _seg_42(): + return [ + (0xFAC5, 'M', u'鉶'), + (0xFAC6, 'M', u'陼'), + (0xFAC7, 'M', u'難'), + (0xFAC8, 'M', u'靖'), + (0xFAC9, 'M', u'韛'), + (0xFACA, 'M', u'響'), + (0xFACB, 'M', u'頋'), + (0xFACC, 'M', u'頻'), + (0xFACD, 'M', u'鬒'), + (0xFACE, 'M', u'龜'), + (0xFACF, 'M', u'𢡊'), + (0xFAD0, 'M', u'𢡄'), + (0xFAD1, 'M', u'𣏕'), + (0xFAD2, 'M', u'㮝'), + (0xFAD3, 'M', u'䀘'), + (0xFAD4, 'M', u'䀹'), + (0xFAD5, 'M', u'𥉉'), + (0xFAD6, 'M', u'𥳐'), + (0xFAD7, 'M', u'𧻓'), + (0xFAD8, 'M', u'齃'), + (0xFAD9, 'M', u'龎'), + (0xFADA, 'X'), + (0xFB00, 'M', u'ff'), + (0xFB01, 'M', u'fi'), + (0xFB02, 'M', u'fl'), + (0xFB03, 'M', u'ffi'), + (0xFB04, 'M', u'ffl'), + (0xFB05, 'M', u'st'), + (0xFB07, 'X'), + (0xFB13, 'M', u'մն'), + (0xFB14, 'M', u'մե'), + (0xFB15, 'M', u'մի'), + (0xFB16, 'M', u'վն'), + (0xFB17, 'M', u'մխ'), + (0xFB18, 'X'), + (0xFB1D, 'M', u'יִ'), + (0xFB1E, 'V'), + (0xFB1F, 'M', u'ײַ'), + (0xFB20, 'M', u'ע'), + (0xFB21, 'M', u'א'), + (0xFB22, 'M', u'ד'), + (0xFB23, 'M', u'ה'), + (0xFB24, 'M', u'כ'), + (0xFB25, 'M', u'ל'), + (0xFB26, 'M', u'ם'), + (0xFB27, 'M', u'ר'), + (0xFB28, 'M', u'ת'), + (0xFB29, '3', u'+'), + (0xFB2A, 'M', u'שׁ'), + (0xFB2B, 'M', u'שׂ'), + (0xFB2C, 'M', u'שּׁ'), + (0xFB2D, 'M', u'שּׂ'), + (0xFB2E, 'M', u'אַ'), + (0xFB2F, 'M', u'אָ'), + (0xFB30, 'M', u'אּ'), + (0xFB31, 'M', u'בּ'), + (0xFB32, 'M', u'גּ'), + (0xFB33, 'M', u'דּ'), + (0xFB34, 'M', u'הּ'), + (0xFB35, 'M', u'וּ'), + (0xFB36, 'M', u'זּ'), + (0xFB37, 'X'), + (0xFB38, 'M', u'טּ'), + (0xFB39, 'M', u'יּ'), + (0xFB3A, 'M', u'ךּ'), + (0xFB3B, 'M', u'כּ'), + (0xFB3C, 'M', u'לּ'), + (0xFB3D, 'X'), + (0xFB3E, 'M', u'מּ'), + (0xFB3F, 'X'), + (0xFB40, 'M', u'נּ'), + (0xFB41, 'M', u'סּ'), + (0xFB42, 'X'), + (0xFB43, 'M', u'ףּ'), + (0xFB44, 'M', u'פּ'), + (0xFB45, 'X'), + (0xFB46, 'M', u'צּ'), + (0xFB47, 'M', u'קּ'), + (0xFB48, 'M', u'רּ'), + (0xFB49, 'M', u'שּ'), + (0xFB4A, 'M', u'תּ'), + (0xFB4B, 'M', u'וֹ'), + (0xFB4C, 'M', u'בֿ'), + (0xFB4D, 'M', u'כֿ'), + (0xFB4E, 'M', u'פֿ'), + (0xFB4F, 'M', u'אל'), + (0xFB50, 'M', u'ٱ'), + (0xFB52, 'M', u'ٻ'), + (0xFB56, 'M', u'پ'), + (0xFB5A, 'M', u'ڀ'), + (0xFB5E, 'M', u'ٺ'), + (0xFB62, 'M', u'ٿ'), + (0xFB66, 'M', u'ٹ'), + (0xFB6A, 'M', u'ڤ'), + (0xFB6E, 'M', u'ڦ'), + (0xFB72, 'M', u'ڄ'), + (0xFB76, 'M', u'ڃ'), + (0xFB7A, 'M', u'چ'), + (0xFB7E, 'M', u'ڇ'), + (0xFB82, 'M', u'ڍ'), + ] + +def _seg_43(): + return [ + (0xFB84, 'M', u'ڌ'), + (0xFB86, 'M', u'ڎ'), + (0xFB88, 'M', u'ڈ'), + (0xFB8A, 'M', u'ژ'), + (0xFB8C, 'M', u'ڑ'), + (0xFB8E, 'M', u'ک'), + (0xFB92, 'M', u'گ'), + (0xFB96, 'M', u'ڳ'), + (0xFB9A, 'M', u'ڱ'), + (0xFB9E, 'M', u'ں'), + (0xFBA0, 'M', u'ڻ'), + (0xFBA4, 'M', u'ۀ'), + (0xFBA6, 'M', u'ہ'), + (0xFBAA, 'M', u'ھ'), + (0xFBAE, 'M', u'ے'), + (0xFBB0, 'M', u'ۓ'), + (0xFBB2, 'V'), + (0xFBC2, 'X'), + (0xFBD3, 'M', u'ڭ'), + (0xFBD7, 'M', u'ۇ'), + (0xFBD9, 'M', u'ۆ'), + (0xFBDB, 'M', u'ۈ'), + (0xFBDD, 'M', u'ۇٴ'), + (0xFBDE, 'M', u'ۋ'), + (0xFBE0, 'M', u'ۅ'), + (0xFBE2, 'M', u'ۉ'), + (0xFBE4, 'M', u'ې'), + (0xFBE8, 'M', u'ى'), + (0xFBEA, 'M', u'ئا'), + (0xFBEC, 'M', u'ئە'), + (0xFBEE, 'M', u'ئو'), + (0xFBF0, 'M', u'ئۇ'), + (0xFBF2, 'M', u'ئۆ'), + (0xFBF4, 'M', u'ئۈ'), + (0xFBF6, 'M', u'ئې'), + (0xFBF9, 'M', u'ئى'), + (0xFBFC, 'M', u'ی'), + (0xFC00, 'M', u'ئج'), + (0xFC01, 'M', u'ئح'), + (0xFC02, 'M', u'ئم'), + (0xFC03, 'M', u'ئى'), + (0xFC04, 'M', u'ئي'), + (0xFC05, 'M', u'بج'), + (0xFC06, 'M', u'بح'), + (0xFC07, 'M', u'بخ'), + (0xFC08, 'M', u'بم'), + (0xFC09, 'M', u'بى'), + (0xFC0A, 'M', u'بي'), + (0xFC0B, 'M', u'تج'), + (0xFC0C, 'M', u'تح'), + (0xFC0D, 'M', u'تخ'), + (0xFC0E, 'M', u'تم'), + (0xFC0F, 'M', u'تى'), + (0xFC10, 'M', u'تي'), + (0xFC11, 'M', u'ثج'), + (0xFC12, 'M', u'ثم'), + (0xFC13, 'M', u'ثى'), + (0xFC14, 'M', u'ثي'), + (0xFC15, 'M', u'جح'), + (0xFC16, 'M', u'جم'), + (0xFC17, 'M', u'حج'), + (0xFC18, 'M', u'حم'), + (0xFC19, 'M', u'خج'), + (0xFC1A, 'M', u'خح'), + (0xFC1B, 'M', u'خم'), + (0xFC1C, 'M', u'سج'), + (0xFC1D, 'M', u'سح'), + (0xFC1E, 'M', u'سخ'), + (0xFC1F, 'M', u'سم'), + (0xFC20, 'M', u'صح'), + (0xFC21, 'M', u'صم'), + (0xFC22, 'M', u'ضج'), + (0xFC23, 'M', u'ضح'), + (0xFC24, 'M', u'ضخ'), + (0xFC25, 'M', u'ضم'), + (0xFC26, 'M', u'طح'), + (0xFC27, 'M', u'طم'), + (0xFC28, 'M', u'ظم'), + (0xFC29, 'M', u'عج'), + (0xFC2A, 'M', u'عم'), + (0xFC2B, 'M', u'غج'), + (0xFC2C, 'M', u'غم'), + (0xFC2D, 'M', u'فج'), + (0xFC2E, 'M', u'فح'), + (0xFC2F, 'M', u'فخ'), + (0xFC30, 'M', u'فم'), + (0xFC31, 'M', u'فى'), + (0xFC32, 'M', u'في'), + (0xFC33, 'M', u'قح'), + (0xFC34, 'M', u'قم'), + (0xFC35, 'M', u'قى'), + (0xFC36, 'M', u'قي'), + (0xFC37, 'M', u'كا'), + (0xFC38, 'M', u'كج'), + (0xFC39, 'M', u'كح'), + (0xFC3A, 'M', u'كخ'), + (0xFC3B, 'M', u'كل'), + (0xFC3C, 'M', u'كم'), + (0xFC3D, 'M', u'كى'), + (0xFC3E, 'M', u'كي'), + ] + +def _seg_44(): + return [ + (0xFC3F, 'M', u'لج'), + (0xFC40, 'M', u'لح'), + (0xFC41, 'M', u'لخ'), + (0xFC42, 'M', u'لم'), + (0xFC43, 'M', u'لى'), + (0xFC44, 'M', u'لي'), + (0xFC45, 'M', u'مج'), + (0xFC46, 'M', u'مح'), + (0xFC47, 'M', u'مخ'), + (0xFC48, 'M', u'مم'), + (0xFC49, 'M', u'مى'), + (0xFC4A, 'M', u'مي'), + (0xFC4B, 'M', u'نج'), + (0xFC4C, 'M', u'نح'), + (0xFC4D, 'M', u'نخ'), + (0xFC4E, 'M', u'نم'), + (0xFC4F, 'M', u'نى'), + (0xFC50, 'M', u'ني'), + (0xFC51, 'M', u'هج'), + (0xFC52, 'M', u'هم'), + (0xFC53, 'M', u'هى'), + (0xFC54, 'M', u'هي'), + (0xFC55, 'M', u'يج'), + (0xFC56, 'M', u'يح'), + (0xFC57, 'M', u'يخ'), + (0xFC58, 'M', u'يم'), + (0xFC59, 'M', u'يى'), + (0xFC5A, 'M', u'يي'), + (0xFC5B, 'M', u'ذٰ'), + (0xFC5C, 'M', u'رٰ'), + (0xFC5D, 'M', u'ىٰ'), + (0xFC5E, '3', u' ٌّ'), + (0xFC5F, '3', u' ٍّ'), + (0xFC60, '3', u' َّ'), + (0xFC61, '3', u' ُّ'), + (0xFC62, '3', u' ِّ'), + (0xFC63, '3', u' ّٰ'), + (0xFC64, 'M', u'ئر'), + (0xFC65, 'M', u'ئز'), + (0xFC66, 'M', u'ئم'), + (0xFC67, 'M', u'ئن'), + (0xFC68, 'M', u'ئى'), + (0xFC69, 'M', u'ئي'), + (0xFC6A, 'M', u'بر'), + (0xFC6B, 'M', u'بز'), + (0xFC6C, 'M', u'بم'), + (0xFC6D, 'M', u'بن'), + (0xFC6E, 'M', u'بى'), + (0xFC6F, 'M', u'بي'), + (0xFC70, 'M', u'تر'), + (0xFC71, 'M', u'تز'), + (0xFC72, 'M', u'تم'), + (0xFC73, 'M', u'تن'), + (0xFC74, 'M', u'تى'), + (0xFC75, 'M', u'تي'), + (0xFC76, 'M', u'ثر'), + (0xFC77, 'M', u'ثز'), + (0xFC78, 'M', u'ثم'), + (0xFC79, 'M', u'ثن'), + (0xFC7A, 'M', u'ثى'), + (0xFC7B, 'M', u'ثي'), + (0xFC7C, 'M', u'فى'), + (0xFC7D, 'M', u'في'), + (0xFC7E, 'M', u'قى'), + (0xFC7F, 'M', u'قي'), + (0xFC80, 'M', u'كا'), + (0xFC81, 'M', u'كل'), + (0xFC82, 'M', u'كم'), + (0xFC83, 'M', u'كى'), + (0xFC84, 'M', u'كي'), + (0xFC85, 'M', u'لم'), + (0xFC86, 'M', u'لى'), + (0xFC87, 'M', u'لي'), + (0xFC88, 'M', u'ما'), + (0xFC89, 'M', u'مم'), + (0xFC8A, 'M', u'نر'), + (0xFC8B, 'M', u'نز'), + (0xFC8C, 'M', u'نم'), + (0xFC8D, 'M', u'نن'), + (0xFC8E, 'M', u'نى'), + (0xFC8F, 'M', u'ني'), + (0xFC90, 'M', u'ىٰ'), + (0xFC91, 'M', u'ير'), + (0xFC92, 'M', u'يز'), + (0xFC93, 'M', u'يم'), + (0xFC94, 'M', u'ين'), + (0xFC95, 'M', u'يى'), + (0xFC96, 'M', u'يي'), + (0xFC97, 'M', u'ئج'), + (0xFC98, 'M', u'ئح'), + (0xFC99, 'M', u'ئخ'), + (0xFC9A, 'M', u'ئم'), + (0xFC9B, 'M', u'ئه'), + (0xFC9C, 'M', u'بج'), + (0xFC9D, 'M', u'بح'), + (0xFC9E, 'M', u'بخ'), + (0xFC9F, 'M', u'بم'), + (0xFCA0, 'M', u'به'), + (0xFCA1, 'M', u'تج'), + (0xFCA2, 'M', u'تح'), + ] + +def _seg_45(): + return [ + (0xFCA3, 'M', u'تخ'), + (0xFCA4, 'M', u'تم'), + (0xFCA5, 'M', u'ته'), + (0xFCA6, 'M', u'ثم'), + (0xFCA7, 'M', u'جح'), + (0xFCA8, 'M', u'جم'), + (0xFCA9, 'M', u'حج'), + (0xFCAA, 'M', u'حم'), + (0xFCAB, 'M', u'خج'), + (0xFCAC, 'M', u'خم'), + (0xFCAD, 'M', u'سج'), + (0xFCAE, 'M', u'سح'), + (0xFCAF, 'M', u'سخ'), + (0xFCB0, 'M', u'سم'), + (0xFCB1, 'M', u'صح'), + (0xFCB2, 'M', u'صخ'), + (0xFCB3, 'M', u'صم'), + (0xFCB4, 'M', u'ضج'), + (0xFCB5, 'M', u'ضح'), + (0xFCB6, 'M', u'ضخ'), + (0xFCB7, 'M', u'ضم'), + (0xFCB8, 'M', u'طح'), + (0xFCB9, 'M', u'ظم'), + (0xFCBA, 'M', u'عج'), + (0xFCBB, 'M', u'عم'), + (0xFCBC, 'M', u'غج'), + (0xFCBD, 'M', u'غم'), + (0xFCBE, 'M', u'فج'), + (0xFCBF, 'M', u'فح'), + (0xFCC0, 'M', u'فخ'), + (0xFCC1, 'M', u'فم'), + (0xFCC2, 'M', u'قح'), + (0xFCC3, 'M', u'قم'), + (0xFCC4, 'M', u'كج'), + (0xFCC5, 'M', u'كح'), + (0xFCC6, 'M', u'كخ'), + (0xFCC7, 'M', u'كل'), + (0xFCC8, 'M', u'كم'), + (0xFCC9, 'M', u'لج'), + (0xFCCA, 'M', u'لح'), + (0xFCCB, 'M', u'لخ'), + (0xFCCC, 'M', u'لم'), + (0xFCCD, 'M', u'له'), + (0xFCCE, 'M', u'مج'), + (0xFCCF, 'M', u'مح'), + (0xFCD0, 'M', u'مخ'), + (0xFCD1, 'M', u'مم'), + (0xFCD2, 'M', u'نج'), + (0xFCD3, 'M', u'نح'), + (0xFCD4, 'M', u'نخ'), + (0xFCD5, 'M', u'نم'), + (0xFCD6, 'M', u'نه'), + (0xFCD7, 'M', u'هج'), + (0xFCD8, 'M', u'هم'), + (0xFCD9, 'M', u'هٰ'), + (0xFCDA, 'M', u'يج'), + (0xFCDB, 'M', u'يح'), + (0xFCDC, 'M', u'يخ'), + (0xFCDD, 'M', u'يم'), + (0xFCDE, 'M', u'يه'), + (0xFCDF, 'M', u'ئم'), + (0xFCE0, 'M', u'ئه'), + (0xFCE1, 'M', u'بم'), + (0xFCE2, 'M', u'به'), + (0xFCE3, 'M', u'تم'), + (0xFCE4, 'M', u'ته'), + (0xFCE5, 'M', u'ثم'), + (0xFCE6, 'M', u'ثه'), + (0xFCE7, 'M', u'سم'), + (0xFCE8, 'M', u'سه'), + (0xFCE9, 'M', u'شم'), + (0xFCEA, 'M', u'شه'), + (0xFCEB, 'M', u'كل'), + (0xFCEC, 'M', u'كم'), + (0xFCED, 'M', u'لم'), + (0xFCEE, 'M', u'نم'), + (0xFCEF, 'M', u'نه'), + (0xFCF0, 'M', u'يم'), + (0xFCF1, 'M', u'يه'), + (0xFCF2, 'M', u'ـَّ'), + (0xFCF3, 'M', u'ـُّ'), + (0xFCF4, 'M', u'ـِّ'), + (0xFCF5, 'M', u'طى'), + (0xFCF6, 'M', u'طي'), + (0xFCF7, 'M', u'عى'), + (0xFCF8, 'M', u'عي'), + (0xFCF9, 'M', u'غى'), + (0xFCFA, 'M', u'غي'), + (0xFCFB, 'M', u'سى'), + (0xFCFC, 'M', u'سي'), + (0xFCFD, 'M', u'شى'), + (0xFCFE, 'M', u'شي'), + (0xFCFF, 'M', u'حى'), + (0xFD00, 'M', u'حي'), + (0xFD01, 'M', u'جى'), + (0xFD02, 'M', u'جي'), + (0xFD03, 'M', u'خى'), + (0xFD04, 'M', u'خي'), + (0xFD05, 'M', u'صى'), + (0xFD06, 'M', u'صي'), + ] + +def _seg_46(): + return [ + (0xFD07, 'M', u'ضى'), + (0xFD08, 'M', u'ضي'), + (0xFD09, 'M', u'شج'), + (0xFD0A, 'M', u'شح'), + (0xFD0B, 'M', u'شخ'), + (0xFD0C, 'M', u'شم'), + (0xFD0D, 'M', u'شر'), + (0xFD0E, 'M', u'سر'), + (0xFD0F, 'M', u'صر'), + (0xFD10, 'M', u'ضر'), + (0xFD11, 'M', u'طى'), + (0xFD12, 'M', u'طي'), + (0xFD13, 'M', u'عى'), + (0xFD14, 'M', u'عي'), + (0xFD15, 'M', u'غى'), + (0xFD16, 'M', u'غي'), + (0xFD17, 'M', u'سى'), + (0xFD18, 'M', u'سي'), + (0xFD19, 'M', u'شى'), + (0xFD1A, 'M', u'شي'), + (0xFD1B, 'M', u'حى'), + (0xFD1C, 'M', u'حي'), + (0xFD1D, 'M', u'جى'), + (0xFD1E, 'M', u'جي'), + (0xFD1F, 'M', u'خى'), + (0xFD20, 'M', u'خي'), + (0xFD21, 'M', u'صى'), + (0xFD22, 'M', u'صي'), + (0xFD23, 'M', u'ضى'), + (0xFD24, 'M', u'ضي'), + (0xFD25, 'M', u'شج'), + (0xFD26, 'M', u'شح'), + (0xFD27, 'M', u'شخ'), + (0xFD28, 'M', u'شم'), + (0xFD29, 'M', u'شر'), + (0xFD2A, 'M', u'سر'), + (0xFD2B, 'M', u'صر'), + (0xFD2C, 'M', u'ضر'), + (0xFD2D, 'M', u'شج'), + (0xFD2E, 'M', u'شح'), + (0xFD2F, 'M', u'شخ'), + (0xFD30, 'M', u'شم'), + (0xFD31, 'M', u'سه'), + (0xFD32, 'M', u'شه'), + (0xFD33, 'M', u'طم'), + (0xFD34, 'M', u'سج'), + (0xFD35, 'M', u'سح'), + (0xFD36, 'M', u'سخ'), + (0xFD37, 'M', u'شج'), + (0xFD38, 'M', u'شح'), + (0xFD39, 'M', u'شخ'), + (0xFD3A, 'M', u'طم'), + (0xFD3B, 'M', u'ظم'), + (0xFD3C, 'M', u'اً'), + (0xFD3E, 'V'), + (0xFD40, 'X'), + (0xFD50, 'M', u'تجم'), + (0xFD51, 'M', u'تحج'), + (0xFD53, 'M', u'تحم'), + (0xFD54, 'M', u'تخم'), + (0xFD55, 'M', u'تمج'), + (0xFD56, 'M', u'تمح'), + (0xFD57, 'M', u'تمخ'), + (0xFD58, 'M', u'جمح'), + (0xFD5A, 'M', u'حمي'), + (0xFD5B, 'M', u'حمى'), + (0xFD5C, 'M', u'سحج'), + (0xFD5D, 'M', u'سجح'), + (0xFD5E, 'M', u'سجى'), + (0xFD5F, 'M', u'سمح'), + (0xFD61, 'M', u'سمج'), + (0xFD62, 'M', u'سمم'), + (0xFD64, 'M', u'صحح'), + (0xFD66, 'M', u'صمم'), + (0xFD67, 'M', u'شحم'), + (0xFD69, 'M', u'شجي'), + (0xFD6A, 'M', u'شمخ'), + (0xFD6C, 'M', u'شمم'), + (0xFD6E, 'M', u'ضحى'), + (0xFD6F, 'M', u'ضخم'), + (0xFD71, 'M', u'طمح'), + (0xFD73, 'M', u'طمم'), + (0xFD74, 'M', u'طمي'), + (0xFD75, 'M', u'عجم'), + (0xFD76, 'M', u'عمم'), + (0xFD78, 'M', u'عمى'), + (0xFD79, 'M', u'غمم'), + (0xFD7A, 'M', u'غمي'), + (0xFD7B, 'M', u'غمى'), + (0xFD7C, 'M', u'فخم'), + (0xFD7E, 'M', u'قمح'), + (0xFD7F, 'M', u'قمم'), + (0xFD80, 'M', u'لحم'), + (0xFD81, 'M', u'لحي'), + (0xFD82, 'M', u'لحى'), + (0xFD83, 'M', u'لجج'), + (0xFD85, 'M', u'لخم'), + (0xFD87, 'M', u'لمح'), + (0xFD89, 'M', u'محج'), + (0xFD8A, 'M', u'محم'), + ] + +def _seg_47(): + return [ + (0xFD8B, 'M', u'محي'), + (0xFD8C, 'M', u'مجح'), + (0xFD8D, 'M', u'مجم'), + (0xFD8E, 'M', u'مخج'), + (0xFD8F, 'M', u'مخم'), + (0xFD90, 'X'), + (0xFD92, 'M', u'مجخ'), + (0xFD93, 'M', u'همج'), + (0xFD94, 'M', u'همم'), + (0xFD95, 'M', u'نحم'), + (0xFD96, 'M', u'نحى'), + (0xFD97, 'M', u'نجم'), + (0xFD99, 'M', u'نجى'), + (0xFD9A, 'M', u'نمي'), + (0xFD9B, 'M', u'نمى'), + (0xFD9C, 'M', u'يمم'), + (0xFD9E, 'M', u'بخي'), + (0xFD9F, 'M', u'تجي'), + (0xFDA0, 'M', u'تجى'), + (0xFDA1, 'M', u'تخي'), + (0xFDA2, 'M', u'تخى'), + (0xFDA3, 'M', u'تمي'), + (0xFDA4, 'M', u'تمى'), + (0xFDA5, 'M', u'جمي'), + (0xFDA6, 'M', u'جحى'), + (0xFDA7, 'M', u'جمى'), + (0xFDA8, 'M', u'سخى'), + (0xFDA9, 'M', u'صحي'), + (0xFDAA, 'M', u'شحي'), + (0xFDAB, 'M', u'ضحي'), + (0xFDAC, 'M', u'لجي'), + (0xFDAD, 'M', u'لمي'), + (0xFDAE, 'M', u'يحي'), + (0xFDAF, 'M', u'يجي'), + (0xFDB0, 'M', u'يمي'), + (0xFDB1, 'M', u'ممي'), + (0xFDB2, 'M', u'قمي'), + (0xFDB3, 'M', u'نحي'), + (0xFDB4, 'M', u'قمح'), + (0xFDB5, 'M', u'لحم'), + (0xFDB6, 'M', u'عمي'), + (0xFDB7, 'M', u'كمي'), + (0xFDB8, 'M', u'نجح'), + (0xFDB9, 'M', u'مخي'), + (0xFDBA, 'M', u'لجم'), + (0xFDBB, 'M', u'كمم'), + (0xFDBC, 'M', u'لجم'), + (0xFDBD, 'M', u'نجح'), + (0xFDBE, 'M', u'جحي'), + (0xFDBF, 'M', u'حجي'), + (0xFDC0, 'M', u'مجي'), + (0xFDC1, 'M', u'فمي'), + (0xFDC2, 'M', u'بحي'), + (0xFDC3, 'M', u'كمم'), + (0xFDC4, 'M', u'عجم'), + (0xFDC5, 'M', u'صمم'), + (0xFDC6, 'M', u'سخي'), + (0xFDC7, 'M', u'نجي'), + (0xFDC8, 'X'), + (0xFDF0, 'M', u'صلے'), + (0xFDF1, 'M', u'قلے'), + (0xFDF2, 'M', u'الله'), + (0xFDF3, 'M', u'اكبر'), + (0xFDF4, 'M', u'محمد'), + (0xFDF5, 'M', u'صلعم'), + (0xFDF6, 'M', u'رسول'), + (0xFDF7, 'M', u'عليه'), + (0xFDF8, 'M', u'وسلم'), + (0xFDF9, 'M', u'صلى'), + (0xFDFA, '3', u'صلى الله عليه وسلم'), + (0xFDFB, '3', u'جل جلاله'), + (0xFDFC, 'M', u'ریال'), + (0xFDFD, 'V'), + (0xFDFE, 'X'), + (0xFE00, 'I'), + (0xFE10, '3', u','), + (0xFE11, 'M', u'、'), + (0xFE12, 'X'), + (0xFE13, '3', u':'), + (0xFE14, '3', u';'), + (0xFE15, '3', u'!'), + (0xFE16, '3', u'?'), + (0xFE17, 'M', u'〖'), + (0xFE18, 'M', u'〗'), + (0xFE19, 'X'), + (0xFE20, 'V'), + (0xFE27, 'X'), + (0xFE31, 'M', u'—'), + (0xFE32, 'M', u'–'), + (0xFE33, '3', u'_'), + (0xFE35, '3', u'('), + (0xFE36, '3', u')'), + (0xFE37, '3', u'{'), + (0xFE38, '3', u'}'), + (0xFE39, 'M', u'〔'), + (0xFE3A, 'M', u'〕'), + (0xFE3B, 'M', u'【'), + (0xFE3C, 'M', u'】'), + (0xFE3D, 'M', u'《'), + (0xFE3E, 'M', u'》'), + ] + +def _seg_48(): + return [ + (0xFE3F, 'M', u'〈'), + (0xFE40, 'M', u'〉'), + (0xFE41, 'M', u'「'), + (0xFE42, 'M', u'」'), + (0xFE43, 'M', u'『'), + (0xFE44, 'M', u'』'), + (0xFE45, 'V'), + (0xFE47, '3', u'['), + (0xFE48, '3', u']'), + (0xFE49, '3', u' ̅'), + (0xFE4D, '3', u'_'), + (0xFE50, '3', u','), + (0xFE51, 'M', u'、'), + (0xFE52, 'X'), + (0xFE54, '3', u';'), + (0xFE55, '3', u':'), + (0xFE56, '3', u'?'), + (0xFE57, '3', u'!'), + (0xFE58, 'M', u'—'), + (0xFE59, '3', u'('), + (0xFE5A, '3', u')'), + (0xFE5B, '3', u'{'), + (0xFE5C, '3', u'}'), + (0xFE5D, 'M', u'〔'), + (0xFE5E, 'M', u'〕'), + (0xFE5F, '3', u'#'), + (0xFE60, '3', u'&'), + (0xFE61, '3', u'*'), + (0xFE62, '3', u'+'), + (0xFE63, 'M', u'-'), + (0xFE64, '3', u'<'), + (0xFE65, '3', u'>'), + (0xFE66, '3', u'='), + (0xFE67, 'X'), + (0xFE68, '3', u'\\'), + (0xFE69, '3', u'$'), + (0xFE6A, '3', u'%'), + (0xFE6B, '3', u'@'), + (0xFE6C, 'X'), + (0xFE70, '3', u' ً'), + (0xFE71, 'M', u'ـً'), + (0xFE72, '3', u' ٌ'), + (0xFE73, 'V'), + (0xFE74, '3', u' ٍ'), + (0xFE75, 'X'), + (0xFE76, '3', u' َ'), + (0xFE77, 'M', u'ـَ'), + (0xFE78, '3', u' ُ'), + (0xFE79, 'M', u'ـُ'), + (0xFE7A, '3', u' ِ'), + (0xFE7B, 'M', u'ـِ'), + (0xFE7C, '3', u' ّ'), + (0xFE7D, 'M', u'ـّ'), + (0xFE7E, '3', u' ْ'), + (0xFE7F, 'M', u'ـْ'), + (0xFE80, 'M', u'ء'), + (0xFE81, 'M', u'آ'), + (0xFE83, 'M', u'أ'), + (0xFE85, 'M', u'ؤ'), + (0xFE87, 'M', u'إ'), + (0xFE89, 'M', u'ئ'), + (0xFE8D, 'M', u'ا'), + (0xFE8F, 'M', u'ب'), + (0xFE93, 'M', u'ة'), + (0xFE95, 'M', u'ت'), + (0xFE99, 'M', u'ث'), + (0xFE9D, 'M', u'ج'), + (0xFEA1, 'M', u'ح'), + (0xFEA5, 'M', u'خ'), + (0xFEA9, 'M', u'د'), + (0xFEAB, 'M', u'ذ'), + (0xFEAD, 'M', u'ر'), + (0xFEAF, 'M', u'ز'), + (0xFEB1, 'M', u'س'), + (0xFEB5, 'M', u'ش'), + (0xFEB9, 'M', u'ص'), + (0xFEBD, 'M', u'ض'), + (0xFEC1, 'M', u'ط'), + (0xFEC5, 'M', u'ظ'), + (0xFEC9, 'M', u'ع'), + (0xFECD, 'M', u'غ'), + (0xFED1, 'M', u'ف'), + (0xFED5, 'M', u'ق'), + (0xFED9, 'M', u'ك'), + (0xFEDD, 'M', u'ل'), + (0xFEE1, 'M', u'م'), + (0xFEE5, 'M', u'ن'), + (0xFEE9, 'M', u'ه'), + (0xFEED, 'M', u'و'), + (0xFEEF, 'M', u'ى'), + (0xFEF1, 'M', u'ي'), + (0xFEF5, 'M', u'لآ'), + (0xFEF7, 'M', u'لأ'), + (0xFEF9, 'M', u'لإ'), + (0xFEFB, 'M', u'لا'), + (0xFEFD, 'X'), + (0xFEFF, 'I'), + (0xFF00, 'X'), + (0xFF01, '3', u'!'), + (0xFF02, '3', u'"'), + ] + +def _seg_49(): + return [ + (0xFF03, '3', u'#'), + (0xFF04, '3', u'$'), + (0xFF05, '3', u'%'), + (0xFF06, '3', u'&'), + (0xFF07, '3', u'\''), + (0xFF08, '3', u'('), + (0xFF09, '3', u')'), + (0xFF0A, '3', u'*'), + (0xFF0B, '3', u'+'), + (0xFF0C, '3', u','), + (0xFF0D, 'M', u'-'), + (0xFF0E, 'M', u'.'), + (0xFF0F, '3', u'/'), + (0xFF10, 'M', u'0'), + (0xFF11, 'M', u'1'), + (0xFF12, 'M', u'2'), + (0xFF13, 'M', u'3'), + (0xFF14, 'M', u'4'), + (0xFF15, 'M', u'5'), + (0xFF16, 'M', u'6'), + (0xFF17, 'M', u'7'), + (0xFF18, 'M', u'8'), + (0xFF19, 'M', u'9'), + (0xFF1A, '3', u':'), + (0xFF1B, '3', u';'), + (0xFF1C, '3', u'<'), + (0xFF1D, '3', u'='), + (0xFF1E, '3', u'>'), + (0xFF1F, '3', u'?'), + (0xFF20, '3', u'@'), + (0xFF21, 'M', u'a'), + (0xFF22, 'M', u'b'), + (0xFF23, 'M', u'c'), + (0xFF24, 'M', u'd'), + (0xFF25, 'M', u'e'), + (0xFF26, 'M', u'f'), + (0xFF27, 'M', u'g'), + (0xFF28, 'M', u'h'), + (0xFF29, 'M', u'i'), + (0xFF2A, 'M', u'j'), + (0xFF2B, 'M', u'k'), + (0xFF2C, 'M', u'l'), + (0xFF2D, 'M', u'm'), + (0xFF2E, 'M', u'n'), + (0xFF2F, 'M', u'o'), + (0xFF30, 'M', u'p'), + (0xFF31, 'M', u'q'), + (0xFF32, 'M', u'r'), + (0xFF33, 'M', u's'), + (0xFF34, 'M', u't'), + (0xFF35, 'M', u'u'), + (0xFF36, 'M', u'v'), + (0xFF37, 'M', u'w'), + (0xFF38, 'M', u'x'), + (0xFF39, 'M', u'y'), + (0xFF3A, 'M', u'z'), + (0xFF3B, '3', u'['), + (0xFF3C, '3', u'\\'), + (0xFF3D, '3', u']'), + (0xFF3E, '3', u'^'), + (0xFF3F, '3', u'_'), + (0xFF40, '3', u'`'), + (0xFF41, 'M', u'a'), + (0xFF42, 'M', u'b'), + (0xFF43, 'M', u'c'), + (0xFF44, 'M', u'd'), + (0xFF45, 'M', u'e'), + (0xFF46, 'M', u'f'), + (0xFF47, 'M', u'g'), + (0xFF48, 'M', u'h'), + (0xFF49, 'M', u'i'), + (0xFF4A, 'M', u'j'), + (0xFF4B, 'M', u'k'), + (0xFF4C, 'M', u'l'), + (0xFF4D, 'M', u'm'), + (0xFF4E, 'M', u'n'), + (0xFF4F, 'M', u'o'), + (0xFF50, 'M', u'p'), + (0xFF51, 'M', u'q'), + (0xFF52, 'M', u'r'), + (0xFF53, 'M', u's'), + (0xFF54, 'M', u't'), + (0xFF55, 'M', u'u'), + (0xFF56, 'M', u'v'), + (0xFF57, 'M', u'w'), + (0xFF58, 'M', u'x'), + (0xFF59, 'M', u'y'), + (0xFF5A, 'M', u'z'), + (0xFF5B, '3', u'{'), + (0xFF5C, '3', u'|'), + (0xFF5D, '3', u'}'), + (0xFF5E, '3', u'~'), + (0xFF5F, 'M', u'⦅'), + (0xFF60, 'M', u'⦆'), + (0xFF61, 'M', u'.'), + (0xFF62, 'M', u'「'), + (0xFF63, 'M', u'」'), + (0xFF64, 'M', u'、'), + (0xFF65, 'M', u'・'), + (0xFF66, 'M', u'ヲ'), + ] + +def _seg_50(): + return [ + (0xFF67, 'M', u'ァ'), + (0xFF68, 'M', u'ィ'), + (0xFF69, 'M', u'ゥ'), + (0xFF6A, 'M', u'ェ'), + (0xFF6B, 'M', u'ォ'), + (0xFF6C, 'M', u'ャ'), + (0xFF6D, 'M', u'ュ'), + (0xFF6E, 'M', u'ョ'), + (0xFF6F, 'M', u'ッ'), + (0xFF70, 'M', u'ー'), + (0xFF71, 'M', u'ア'), + (0xFF72, 'M', u'イ'), + (0xFF73, 'M', u'ウ'), + (0xFF74, 'M', u'エ'), + (0xFF75, 'M', u'オ'), + (0xFF76, 'M', u'カ'), + (0xFF77, 'M', u'キ'), + (0xFF78, 'M', u'ク'), + (0xFF79, 'M', u'ケ'), + (0xFF7A, 'M', u'コ'), + (0xFF7B, 'M', u'サ'), + (0xFF7C, 'M', u'シ'), + (0xFF7D, 'M', u'ス'), + (0xFF7E, 'M', u'セ'), + (0xFF7F, 'M', u'ソ'), + (0xFF80, 'M', u'タ'), + (0xFF81, 'M', u'チ'), + (0xFF82, 'M', u'ツ'), + (0xFF83, 'M', u'テ'), + (0xFF84, 'M', u'ト'), + (0xFF85, 'M', u'ナ'), + (0xFF86, 'M', u'ニ'), + (0xFF87, 'M', u'ヌ'), + (0xFF88, 'M', u'ネ'), + (0xFF89, 'M', u'ノ'), + (0xFF8A, 'M', u'ハ'), + (0xFF8B, 'M', u'ヒ'), + (0xFF8C, 'M', u'フ'), + (0xFF8D, 'M', u'ヘ'), + (0xFF8E, 'M', u'ホ'), + (0xFF8F, 'M', u'マ'), + (0xFF90, 'M', u'ミ'), + (0xFF91, 'M', u'ム'), + (0xFF92, 'M', u'メ'), + (0xFF93, 'M', u'モ'), + (0xFF94, 'M', u'ヤ'), + (0xFF95, 'M', u'ユ'), + (0xFF96, 'M', u'ヨ'), + (0xFF97, 'M', u'ラ'), + (0xFF98, 'M', u'リ'), + (0xFF99, 'M', u'ル'), + (0xFF9A, 'M', u'レ'), + (0xFF9B, 'M', u'ロ'), + (0xFF9C, 'M', u'ワ'), + (0xFF9D, 'M', u'ン'), + (0xFF9E, 'M', u'゙'), + (0xFF9F, 'M', u'゚'), + (0xFFA0, 'X'), + (0xFFA1, 'M', u'ᄀ'), + (0xFFA2, 'M', u'ᄁ'), + (0xFFA3, 'M', u'ᆪ'), + (0xFFA4, 'M', u'ᄂ'), + (0xFFA5, 'M', u'ᆬ'), + (0xFFA6, 'M', u'ᆭ'), + (0xFFA7, 'M', u'ᄃ'), + (0xFFA8, 'M', u'ᄄ'), + (0xFFA9, 'M', u'ᄅ'), + (0xFFAA, 'M', u'ᆰ'), + (0xFFAB, 'M', u'ᆱ'), + (0xFFAC, 'M', u'ᆲ'), + (0xFFAD, 'M', u'ᆳ'), + (0xFFAE, 'M', u'ᆴ'), + (0xFFAF, 'M', u'ᆵ'), + (0xFFB0, 'M', u'ᄚ'), + (0xFFB1, 'M', u'ᄆ'), + (0xFFB2, 'M', u'ᄇ'), + (0xFFB3, 'M', u'ᄈ'), + (0xFFB4, 'M', u'ᄡ'), + (0xFFB5, 'M', u'ᄉ'), + (0xFFB6, 'M', u'ᄊ'), + (0xFFB7, 'M', u'ᄋ'), + (0xFFB8, 'M', u'ᄌ'), + (0xFFB9, 'M', u'ᄍ'), + (0xFFBA, 'M', u'ᄎ'), + (0xFFBB, 'M', u'ᄏ'), + (0xFFBC, 'M', u'ᄐ'), + (0xFFBD, 'M', u'ᄑ'), + (0xFFBE, 'M', u'ᄒ'), + (0xFFBF, 'X'), + (0xFFC2, 'M', u'ᅡ'), + (0xFFC3, 'M', u'ᅢ'), + (0xFFC4, 'M', u'ᅣ'), + (0xFFC5, 'M', u'ᅤ'), + (0xFFC6, 'M', u'ᅥ'), + (0xFFC7, 'M', u'ᅦ'), + (0xFFC8, 'X'), + (0xFFCA, 'M', u'ᅧ'), + (0xFFCB, 'M', u'ᅨ'), + (0xFFCC, 'M', u'ᅩ'), + (0xFFCD, 'M', u'ᅪ'), + ] + +def _seg_51(): + return [ + (0xFFCE, 'M', u'ᅫ'), + (0xFFCF, 'M', u'ᅬ'), + (0xFFD0, 'X'), + (0xFFD2, 'M', u'ᅭ'), + (0xFFD3, 'M', u'ᅮ'), + (0xFFD4, 'M', u'ᅯ'), + (0xFFD5, 'M', u'ᅰ'), + (0xFFD6, 'M', u'ᅱ'), + (0xFFD7, 'M', u'ᅲ'), + (0xFFD8, 'X'), + (0xFFDA, 'M', u'ᅳ'), + (0xFFDB, 'M', u'ᅴ'), + (0xFFDC, 'M', u'ᅵ'), + (0xFFDD, 'X'), + (0xFFE0, 'M', u'¢'), + (0xFFE1, 'M', u'£'), + (0xFFE2, 'M', u'¬'), + (0xFFE3, '3', u' ̄'), + (0xFFE4, 'M', u'¦'), + (0xFFE5, 'M', u'¥'), + (0xFFE6, 'M', u'₩'), + (0xFFE7, 'X'), + (0xFFE8, 'M', u'│'), + (0xFFE9, 'M', u'←'), + (0xFFEA, 'M', u'↑'), + (0xFFEB, 'M', u'→'), + (0xFFEC, 'M', u'↓'), + (0xFFED, 'M', u'■'), + (0xFFEE, 'M', u'○'), + (0xFFEF, 'X'), + (0x10000, 'V'), + (0x1000C, 'X'), + (0x1000D, 'V'), + (0x10027, 'X'), + (0x10028, 'V'), + (0x1003B, 'X'), + (0x1003C, 'V'), + (0x1003E, 'X'), + (0x1003F, 'V'), + (0x1004E, 'X'), + (0x10050, 'V'), + (0x1005E, 'X'), + (0x10080, 'V'), + (0x100FB, 'X'), + (0x10100, 'V'), + (0x10103, 'X'), + (0x10107, 'V'), + (0x10134, 'X'), + (0x10137, 'V'), + (0x1018B, 'X'), + (0x10190, 'V'), + (0x1019C, 'X'), + (0x101D0, 'V'), + (0x101FE, 'X'), + (0x10280, 'V'), + (0x1029D, 'X'), + (0x102A0, 'V'), + (0x102D1, 'X'), + (0x10300, 'V'), + (0x1031F, 'X'), + (0x10320, 'V'), + (0x10324, 'X'), + (0x10330, 'V'), + (0x1034B, 'X'), + (0x10380, 'V'), + (0x1039E, 'X'), + (0x1039F, 'V'), + (0x103C4, 'X'), + (0x103C8, 'V'), + (0x103D6, 'X'), + (0x10400, 'M', u'𐐨'), + (0x10401, 'M', u'𐐩'), + (0x10402, 'M', u'𐐪'), + (0x10403, 'M', u'𐐫'), + (0x10404, 'M', u'𐐬'), + (0x10405, 'M', u'𐐭'), + (0x10406, 'M', u'𐐮'), + (0x10407, 'M', u'𐐯'), + (0x10408, 'M', u'𐐰'), + (0x10409, 'M', u'𐐱'), + (0x1040A, 'M', u'𐐲'), + (0x1040B, 'M', u'𐐳'), + (0x1040C, 'M', u'𐐴'), + (0x1040D, 'M', u'𐐵'), + (0x1040E, 'M', u'𐐶'), + (0x1040F, 'M', u'𐐷'), + (0x10410, 'M', u'𐐸'), + (0x10411, 'M', u'𐐹'), + (0x10412, 'M', u'𐐺'), + (0x10413, 'M', u'𐐻'), + (0x10414, 'M', u'𐐼'), + (0x10415, 'M', u'𐐽'), + (0x10416, 'M', u'𐐾'), + (0x10417, 'M', u'𐐿'), + (0x10418, 'M', u'𐑀'), + (0x10419, 'M', u'𐑁'), + (0x1041A, 'M', u'𐑂'), + (0x1041B, 'M', u'𐑃'), + (0x1041C, 'M', u'𐑄'), + (0x1041D, 'M', u'𐑅'), + ] + +def _seg_52(): + return [ + (0x1041E, 'M', u'𐑆'), + (0x1041F, 'M', u'𐑇'), + (0x10420, 'M', u'𐑈'), + (0x10421, 'M', u'𐑉'), + (0x10422, 'M', u'𐑊'), + (0x10423, 'M', u'𐑋'), + (0x10424, 'M', u'𐑌'), + (0x10425, 'M', u'𐑍'), + (0x10426, 'M', u'𐑎'), + (0x10427, 'M', u'𐑏'), + (0x10428, 'V'), + (0x1049E, 'X'), + (0x104A0, 'V'), + (0x104AA, 'X'), + (0x10800, 'V'), + (0x10806, 'X'), + (0x10808, 'V'), + (0x10809, 'X'), + (0x1080A, 'V'), + (0x10836, 'X'), + (0x10837, 'V'), + (0x10839, 'X'), + (0x1083C, 'V'), + (0x1083D, 'X'), + (0x1083F, 'V'), + (0x10856, 'X'), + (0x10857, 'V'), + (0x10860, 'X'), + (0x10900, 'V'), + (0x1091C, 'X'), + (0x1091F, 'V'), + (0x1093A, 'X'), + (0x1093F, 'V'), + (0x10940, 'X'), + (0x10980, 'V'), + (0x109B8, 'X'), + (0x109BE, 'V'), + (0x109C0, 'X'), + (0x10A00, 'V'), + (0x10A04, 'X'), + (0x10A05, 'V'), + (0x10A07, 'X'), + (0x10A0C, 'V'), + (0x10A14, 'X'), + (0x10A15, 'V'), + (0x10A18, 'X'), + (0x10A19, 'V'), + (0x10A34, 'X'), + (0x10A38, 'V'), + (0x10A3B, 'X'), + (0x10A3F, 'V'), + (0x10A48, 'X'), + (0x10A50, 'V'), + (0x10A59, 'X'), + (0x10A60, 'V'), + (0x10A80, 'X'), + (0x10B00, 'V'), + (0x10B36, 'X'), + (0x10B39, 'V'), + (0x10B56, 'X'), + (0x10B58, 'V'), + (0x10B73, 'X'), + (0x10B78, 'V'), + (0x10B80, 'X'), + (0x10C00, 'V'), + (0x10C49, 'X'), + (0x10E60, 'V'), + (0x10E7F, 'X'), + (0x11000, 'V'), + (0x1104E, 'X'), + (0x11052, 'V'), + (0x11070, 'X'), + (0x11080, 'V'), + (0x110BD, 'X'), + (0x110BE, 'V'), + (0x110C2, 'X'), + (0x110D0, 'V'), + (0x110E9, 'X'), + (0x110F0, 'V'), + (0x110FA, 'X'), + (0x11100, 'V'), + (0x11135, 'X'), + (0x11136, 'V'), + (0x11144, 'X'), + (0x11180, 'V'), + (0x111C9, 'X'), + (0x111D0, 'V'), + (0x111DA, 'X'), + (0x11680, 'V'), + (0x116B8, 'X'), + (0x116C0, 'V'), + (0x116CA, 'X'), + (0x12000, 'V'), + (0x1236F, 'X'), + (0x12400, 'V'), + (0x12463, 'X'), + (0x12470, 'V'), + (0x12474, 'X'), + (0x13000, 'V'), + (0x1342F, 'X'), + ] + +def _seg_53(): + return [ + (0x16800, 'V'), + (0x16A39, 'X'), + (0x16F00, 'V'), + (0x16F45, 'X'), + (0x16F50, 'V'), + (0x16F7F, 'X'), + (0x16F8F, 'V'), + (0x16FA0, 'X'), + (0x1B000, 'V'), + (0x1B002, 'X'), + (0x1D000, 'V'), + (0x1D0F6, 'X'), + (0x1D100, 'V'), + (0x1D127, 'X'), + (0x1D129, 'V'), + (0x1D15E, 'M', u'𝅗𝅥'), + (0x1D15F, 'M', u'𝅘𝅥'), + (0x1D160, 'M', u'𝅘𝅥𝅮'), + (0x1D161, 'M', u'𝅘𝅥𝅯'), + (0x1D162, 'M', u'𝅘𝅥𝅰'), + (0x1D163, 'M', u'𝅘𝅥𝅱'), + (0x1D164, 'M', u'𝅘𝅥𝅲'), + (0x1D165, 'V'), + (0x1D173, 'X'), + (0x1D17B, 'V'), + (0x1D1BB, 'M', u'𝆹𝅥'), + (0x1D1BC, 'M', u'𝆺𝅥'), + (0x1D1BD, 'M', u'𝆹𝅥𝅮'), + (0x1D1BE, 'M', u'𝆺𝅥𝅮'), + (0x1D1BF, 'M', u'𝆹𝅥𝅯'), + (0x1D1C0, 'M', u'𝆺𝅥𝅯'), + (0x1D1C1, 'V'), + (0x1D1DE, 'X'), + (0x1D200, 'V'), + (0x1D246, 'X'), + (0x1D300, 'V'), + (0x1D357, 'X'), + (0x1D360, 'V'), + (0x1D372, 'X'), + (0x1D400, 'M', u'a'), + (0x1D401, 'M', u'b'), + (0x1D402, 'M', u'c'), + (0x1D403, 'M', u'd'), + (0x1D404, 'M', u'e'), + (0x1D405, 'M', u'f'), + (0x1D406, 'M', u'g'), + (0x1D407, 'M', u'h'), + (0x1D408, 'M', u'i'), + (0x1D409, 'M', u'j'), + (0x1D40A, 'M', u'k'), + (0x1D40B, 'M', u'l'), + (0x1D40C, 'M', u'm'), + (0x1D40D, 'M', u'n'), + (0x1D40E, 'M', u'o'), + (0x1D40F, 'M', u'p'), + (0x1D410, 'M', u'q'), + (0x1D411, 'M', u'r'), + (0x1D412, 'M', u's'), + (0x1D413, 'M', u't'), + (0x1D414, 'M', u'u'), + (0x1D415, 'M', u'v'), + (0x1D416, 'M', u'w'), + (0x1D417, 'M', u'x'), + (0x1D418, 'M', u'y'), + (0x1D419, 'M', u'z'), + (0x1D41A, 'M', u'a'), + (0x1D41B, 'M', u'b'), + (0x1D41C, 'M', u'c'), + (0x1D41D, 'M', u'd'), + (0x1D41E, 'M', u'e'), + (0x1D41F, 'M', u'f'), + (0x1D420, 'M', u'g'), + (0x1D421, 'M', u'h'), + (0x1D422, 'M', u'i'), + (0x1D423, 'M', u'j'), + (0x1D424, 'M', u'k'), + (0x1D425, 'M', u'l'), + (0x1D426, 'M', u'm'), + (0x1D427, 'M', u'n'), + (0x1D428, 'M', u'o'), + (0x1D429, 'M', u'p'), + (0x1D42A, 'M', u'q'), + (0x1D42B, 'M', u'r'), + (0x1D42C, 'M', u's'), + (0x1D42D, 'M', u't'), + (0x1D42E, 'M', u'u'), + (0x1D42F, 'M', u'v'), + (0x1D430, 'M', u'w'), + (0x1D431, 'M', u'x'), + (0x1D432, 'M', u'y'), + (0x1D433, 'M', u'z'), + (0x1D434, 'M', u'a'), + (0x1D435, 'M', u'b'), + (0x1D436, 'M', u'c'), + (0x1D437, 'M', u'd'), + (0x1D438, 'M', u'e'), + (0x1D439, 'M', u'f'), + (0x1D43A, 'M', u'g'), + (0x1D43B, 'M', u'h'), + (0x1D43C, 'M', u'i'), + ] + +def _seg_54(): + return [ + (0x1D43D, 'M', u'j'), + (0x1D43E, 'M', u'k'), + (0x1D43F, 'M', u'l'), + (0x1D440, 'M', u'm'), + (0x1D441, 'M', u'n'), + (0x1D442, 'M', u'o'), + (0x1D443, 'M', u'p'), + (0x1D444, 'M', u'q'), + (0x1D445, 'M', u'r'), + (0x1D446, 'M', u's'), + (0x1D447, 'M', u't'), + (0x1D448, 'M', u'u'), + (0x1D449, 'M', u'v'), + (0x1D44A, 'M', u'w'), + (0x1D44B, 'M', u'x'), + (0x1D44C, 'M', u'y'), + (0x1D44D, 'M', u'z'), + (0x1D44E, 'M', u'a'), + (0x1D44F, 'M', u'b'), + (0x1D450, 'M', u'c'), + (0x1D451, 'M', u'd'), + (0x1D452, 'M', u'e'), + (0x1D453, 'M', u'f'), + (0x1D454, 'M', u'g'), + (0x1D455, 'X'), + (0x1D456, 'M', u'i'), + (0x1D457, 'M', u'j'), + (0x1D458, 'M', u'k'), + (0x1D459, 'M', u'l'), + (0x1D45A, 'M', u'm'), + (0x1D45B, 'M', u'n'), + (0x1D45C, 'M', u'o'), + (0x1D45D, 'M', u'p'), + (0x1D45E, 'M', u'q'), + (0x1D45F, 'M', u'r'), + (0x1D460, 'M', u's'), + (0x1D461, 'M', u't'), + (0x1D462, 'M', u'u'), + (0x1D463, 'M', u'v'), + (0x1D464, 'M', u'w'), + (0x1D465, 'M', u'x'), + (0x1D466, 'M', u'y'), + (0x1D467, 'M', u'z'), + (0x1D468, 'M', u'a'), + (0x1D469, 'M', u'b'), + (0x1D46A, 'M', u'c'), + (0x1D46B, 'M', u'd'), + (0x1D46C, 'M', u'e'), + (0x1D46D, 'M', u'f'), + (0x1D46E, 'M', u'g'), + (0x1D46F, 'M', u'h'), + (0x1D470, 'M', u'i'), + (0x1D471, 'M', u'j'), + (0x1D472, 'M', u'k'), + (0x1D473, 'M', u'l'), + (0x1D474, 'M', u'm'), + (0x1D475, 'M', u'n'), + (0x1D476, 'M', u'o'), + (0x1D477, 'M', u'p'), + (0x1D478, 'M', u'q'), + (0x1D479, 'M', u'r'), + (0x1D47A, 'M', u's'), + (0x1D47B, 'M', u't'), + (0x1D47C, 'M', u'u'), + (0x1D47D, 'M', u'v'), + (0x1D47E, 'M', u'w'), + (0x1D47F, 'M', u'x'), + (0x1D480, 'M', u'y'), + (0x1D481, 'M', u'z'), + (0x1D482, 'M', u'a'), + (0x1D483, 'M', u'b'), + (0x1D484, 'M', u'c'), + (0x1D485, 'M', u'd'), + (0x1D486, 'M', u'e'), + (0x1D487, 'M', u'f'), + (0x1D488, 'M', u'g'), + (0x1D489, 'M', u'h'), + (0x1D48A, 'M', u'i'), + (0x1D48B, 'M', u'j'), + (0x1D48C, 'M', u'k'), + (0x1D48D, 'M', u'l'), + (0x1D48E, 'M', u'm'), + (0x1D48F, 'M', u'n'), + (0x1D490, 'M', u'o'), + (0x1D491, 'M', u'p'), + (0x1D492, 'M', u'q'), + (0x1D493, 'M', u'r'), + (0x1D494, 'M', u's'), + (0x1D495, 'M', u't'), + (0x1D496, 'M', u'u'), + (0x1D497, 'M', u'v'), + (0x1D498, 'M', u'w'), + (0x1D499, 'M', u'x'), + (0x1D49A, 'M', u'y'), + (0x1D49B, 'M', u'z'), + (0x1D49C, 'M', u'a'), + (0x1D49D, 'X'), + (0x1D49E, 'M', u'c'), + (0x1D49F, 'M', u'd'), + (0x1D4A0, 'X'), + ] + +def _seg_55(): + return [ + (0x1D4A2, 'M', u'g'), + (0x1D4A3, 'X'), + (0x1D4A5, 'M', u'j'), + (0x1D4A6, 'M', u'k'), + (0x1D4A7, 'X'), + (0x1D4A9, 'M', u'n'), + (0x1D4AA, 'M', u'o'), + (0x1D4AB, 'M', u'p'), + (0x1D4AC, 'M', u'q'), + (0x1D4AD, 'X'), + (0x1D4AE, 'M', u's'), + (0x1D4AF, 'M', u't'), + (0x1D4B0, 'M', u'u'), + (0x1D4B1, 'M', u'v'), + (0x1D4B2, 'M', u'w'), + (0x1D4B3, 'M', u'x'), + (0x1D4B4, 'M', u'y'), + (0x1D4B5, 'M', u'z'), + (0x1D4B6, 'M', u'a'), + (0x1D4B7, 'M', u'b'), + (0x1D4B8, 'M', u'c'), + (0x1D4B9, 'M', u'd'), + (0x1D4BA, 'X'), + (0x1D4BB, 'M', u'f'), + (0x1D4BC, 'X'), + (0x1D4BD, 'M', u'h'), + (0x1D4BE, 'M', u'i'), + (0x1D4BF, 'M', u'j'), + (0x1D4C0, 'M', u'k'), + (0x1D4C1, 'M', u'l'), + (0x1D4C2, 'M', u'm'), + (0x1D4C3, 'M', u'n'), + (0x1D4C4, 'X'), + (0x1D4C5, 'M', u'p'), + (0x1D4C6, 'M', u'q'), + (0x1D4C7, 'M', u'r'), + (0x1D4C8, 'M', u's'), + (0x1D4C9, 'M', u't'), + (0x1D4CA, 'M', u'u'), + (0x1D4CB, 'M', u'v'), + (0x1D4CC, 'M', u'w'), + (0x1D4CD, 'M', u'x'), + (0x1D4CE, 'M', u'y'), + (0x1D4CF, 'M', u'z'), + (0x1D4D0, 'M', u'a'), + (0x1D4D1, 'M', u'b'), + (0x1D4D2, 'M', u'c'), + (0x1D4D3, 'M', u'd'), + (0x1D4D4, 'M', u'e'), + (0x1D4D5, 'M', u'f'), + (0x1D4D6, 'M', u'g'), + (0x1D4D7, 'M', u'h'), + (0x1D4D8, 'M', u'i'), + (0x1D4D9, 'M', u'j'), + (0x1D4DA, 'M', u'k'), + (0x1D4DB, 'M', u'l'), + (0x1D4DC, 'M', u'm'), + (0x1D4DD, 'M', u'n'), + (0x1D4DE, 'M', u'o'), + (0x1D4DF, 'M', u'p'), + (0x1D4E0, 'M', u'q'), + (0x1D4E1, 'M', u'r'), + (0x1D4E2, 'M', u's'), + (0x1D4E3, 'M', u't'), + (0x1D4E4, 'M', u'u'), + (0x1D4E5, 'M', u'v'), + (0x1D4E6, 'M', u'w'), + (0x1D4E7, 'M', u'x'), + (0x1D4E8, 'M', u'y'), + (0x1D4E9, 'M', u'z'), + (0x1D4EA, 'M', u'a'), + (0x1D4EB, 'M', u'b'), + (0x1D4EC, 'M', u'c'), + (0x1D4ED, 'M', u'd'), + (0x1D4EE, 'M', u'e'), + (0x1D4EF, 'M', u'f'), + (0x1D4F0, 'M', u'g'), + (0x1D4F1, 'M', u'h'), + (0x1D4F2, 'M', u'i'), + (0x1D4F3, 'M', u'j'), + (0x1D4F4, 'M', u'k'), + (0x1D4F5, 'M', u'l'), + (0x1D4F6, 'M', u'm'), + (0x1D4F7, 'M', u'n'), + (0x1D4F8, 'M', u'o'), + (0x1D4F9, 'M', u'p'), + (0x1D4FA, 'M', u'q'), + (0x1D4FB, 'M', u'r'), + (0x1D4FC, 'M', u's'), + (0x1D4FD, 'M', u't'), + (0x1D4FE, 'M', u'u'), + (0x1D4FF, 'M', u'v'), + (0x1D500, 'M', u'w'), + (0x1D501, 'M', u'x'), + (0x1D502, 'M', u'y'), + (0x1D503, 'M', u'z'), + (0x1D504, 'M', u'a'), + (0x1D505, 'M', u'b'), + (0x1D506, 'X'), + (0x1D507, 'M', u'd'), + ] + +def _seg_56(): + return [ + (0x1D508, 'M', u'e'), + (0x1D509, 'M', u'f'), + (0x1D50A, 'M', u'g'), + (0x1D50B, 'X'), + (0x1D50D, 'M', u'j'), + (0x1D50E, 'M', u'k'), + (0x1D50F, 'M', u'l'), + (0x1D510, 'M', u'm'), + (0x1D511, 'M', u'n'), + (0x1D512, 'M', u'o'), + (0x1D513, 'M', u'p'), + (0x1D514, 'M', u'q'), + (0x1D515, 'X'), + (0x1D516, 'M', u's'), + (0x1D517, 'M', u't'), + (0x1D518, 'M', u'u'), + (0x1D519, 'M', u'v'), + (0x1D51A, 'M', u'w'), + (0x1D51B, 'M', u'x'), + (0x1D51C, 'M', u'y'), + (0x1D51D, 'X'), + (0x1D51E, 'M', u'a'), + (0x1D51F, 'M', u'b'), + (0x1D520, 'M', u'c'), + (0x1D521, 'M', u'd'), + (0x1D522, 'M', u'e'), + (0x1D523, 'M', u'f'), + (0x1D524, 'M', u'g'), + (0x1D525, 'M', u'h'), + (0x1D526, 'M', u'i'), + (0x1D527, 'M', u'j'), + (0x1D528, 'M', u'k'), + (0x1D529, 'M', u'l'), + (0x1D52A, 'M', u'm'), + (0x1D52B, 'M', u'n'), + (0x1D52C, 'M', u'o'), + (0x1D52D, 'M', u'p'), + (0x1D52E, 'M', u'q'), + (0x1D52F, 'M', u'r'), + (0x1D530, 'M', u's'), + (0x1D531, 'M', u't'), + (0x1D532, 'M', u'u'), + (0x1D533, 'M', u'v'), + (0x1D534, 'M', u'w'), + (0x1D535, 'M', u'x'), + (0x1D536, 'M', u'y'), + (0x1D537, 'M', u'z'), + (0x1D538, 'M', u'a'), + (0x1D539, 'M', u'b'), + (0x1D53A, 'X'), + (0x1D53B, 'M', u'd'), + (0x1D53C, 'M', u'e'), + (0x1D53D, 'M', u'f'), + (0x1D53E, 'M', u'g'), + (0x1D53F, 'X'), + (0x1D540, 'M', u'i'), + (0x1D541, 'M', u'j'), + (0x1D542, 'M', u'k'), + (0x1D543, 'M', u'l'), + (0x1D544, 'M', u'm'), + (0x1D545, 'X'), + (0x1D546, 'M', u'o'), + (0x1D547, 'X'), + (0x1D54A, 'M', u's'), + (0x1D54B, 'M', u't'), + (0x1D54C, 'M', u'u'), + (0x1D54D, 'M', u'v'), + (0x1D54E, 'M', u'w'), + (0x1D54F, 'M', u'x'), + (0x1D550, 'M', u'y'), + (0x1D551, 'X'), + (0x1D552, 'M', u'a'), + (0x1D553, 'M', u'b'), + (0x1D554, 'M', u'c'), + (0x1D555, 'M', u'd'), + (0x1D556, 'M', u'e'), + (0x1D557, 'M', u'f'), + (0x1D558, 'M', u'g'), + (0x1D559, 'M', u'h'), + (0x1D55A, 'M', u'i'), + (0x1D55B, 'M', u'j'), + (0x1D55C, 'M', u'k'), + (0x1D55D, 'M', u'l'), + (0x1D55E, 'M', u'm'), + (0x1D55F, 'M', u'n'), + (0x1D560, 'M', u'o'), + (0x1D561, 'M', u'p'), + (0x1D562, 'M', u'q'), + (0x1D563, 'M', u'r'), + (0x1D564, 'M', u's'), + (0x1D565, 'M', u't'), + (0x1D566, 'M', u'u'), + (0x1D567, 'M', u'v'), + (0x1D568, 'M', u'w'), + (0x1D569, 'M', u'x'), + (0x1D56A, 'M', u'y'), + (0x1D56B, 'M', u'z'), + (0x1D56C, 'M', u'a'), + (0x1D56D, 'M', u'b'), + (0x1D56E, 'M', u'c'), + ] + +def _seg_57(): + return [ + (0x1D56F, 'M', u'd'), + (0x1D570, 'M', u'e'), + (0x1D571, 'M', u'f'), + (0x1D572, 'M', u'g'), + (0x1D573, 'M', u'h'), + (0x1D574, 'M', u'i'), + (0x1D575, 'M', u'j'), + (0x1D576, 'M', u'k'), + (0x1D577, 'M', u'l'), + (0x1D578, 'M', u'm'), + (0x1D579, 'M', u'n'), + (0x1D57A, 'M', u'o'), + (0x1D57B, 'M', u'p'), + (0x1D57C, 'M', u'q'), + (0x1D57D, 'M', u'r'), + (0x1D57E, 'M', u's'), + (0x1D57F, 'M', u't'), + (0x1D580, 'M', u'u'), + (0x1D581, 'M', u'v'), + (0x1D582, 'M', u'w'), + (0x1D583, 'M', u'x'), + (0x1D584, 'M', u'y'), + (0x1D585, 'M', u'z'), + (0x1D586, 'M', u'a'), + (0x1D587, 'M', u'b'), + (0x1D588, 'M', u'c'), + (0x1D589, 'M', u'd'), + (0x1D58A, 'M', u'e'), + (0x1D58B, 'M', u'f'), + (0x1D58C, 'M', u'g'), + (0x1D58D, 'M', u'h'), + (0x1D58E, 'M', u'i'), + (0x1D58F, 'M', u'j'), + (0x1D590, 'M', u'k'), + (0x1D591, 'M', u'l'), + (0x1D592, 'M', u'm'), + (0x1D593, 'M', u'n'), + (0x1D594, 'M', u'o'), + (0x1D595, 'M', u'p'), + (0x1D596, 'M', u'q'), + (0x1D597, 'M', u'r'), + (0x1D598, 'M', u's'), + (0x1D599, 'M', u't'), + (0x1D59A, 'M', u'u'), + (0x1D59B, 'M', u'v'), + (0x1D59C, 'M', u'w'), + (0x1D59D, 'M', u'x'), + (0x1D59E, 'M', u'y'), + (0x1D59F, 'M', u'z'), + (0x1D5A0, 'M', u'a'), + (0x1D5A1, 'M', u'b'), + (0x1D5A2, 'M', u'c'), + (0x1D5A3, 'M', u'd'), + (0x1D5A4, 'M', u'e'), + (0x1D5A5, 'M', u'f'), + (0x1D5A6, 'M', u'g'), + (0x1D5A7, 'M', u'h'), + (0x1D5A8, 'M', u'i'), + (0x1D5A9, 'M', u'j'), + (0x1D5AA, 'M', u'k'), + (0x1D5AB, 'M', u'l'), + (0x1D5AC, 'M', u'm'), + (0x1D5AD, 'M', u'n'), + (0x1D5AE, 'M', u'o'), + (0x1D5AF, 'M', u'p'), + (0x1D5B0, 'M', u'q'), + (0x1D5B1, 'M', u'r'), + (0x1D5B2, 'M', u's'), + (0x1D5B3, 'M', u't'), + (0x1D5B4, 'M', u'u'), + (0x1D5B5, 'M', u'v'), + (0x1D5B6, 'M', u'w'), + (0x1D5B7, 'M', u'x'), + (0x1D5B8, 'M', u'y'), + (0x1D5B9, 'M', u'z'), + (0x1D5BA, 'M', u'a'), + (0x1D5BB, 'M', u'b'), + (0x1D5BC, 'M', u'c'), + (0x1D5BD, 'M', u'd'), + (0x1D5BE, 'M', u'e'), + (0x1D5BF, 'M', u'f'), + (0x1D5C0, 'M', u'g'), + (0x1D5C1, 'M', u'h'), + (0x1D5C2, 'M', u'i'), + (0x1D5C3, 'M', u'j'), + (0x1D5C4, 'M', u'k'), + (0x1D5C5, 'M', u'l'), + (0x1D5C6, 'M', u'm'), + (0x1D5C7, 'M', u'n'), + (0x1D5C8, 'M', u'o'), + (0x1D5C9, 'M', u'p'), + (0x1D5CA, 'M', u'q'), + (0x1D5CB, 'M', u'r'), + (0x1D5CC, 'M', u's'), + (0x1D5CD, 'M', u't'), + (0x1D5CE, 'M', u'u'), + (0x1D5CF, 'M', u'v'), + (0x1D5D0, 'M', u'w'), + (0x1D5D1, 'M', u'x'), + (0x1D5D2, 'M', u'y'), + ] + +def _seg_58(): + return [ + (0x1D5D3, 'M', u'z'), + (0x1D5D4, 'M', u'a'), + (0x1D5D5, 'M', u'b'), + (0x1D5D6, 'M', u'c'), + (0x1D5D7, 'M', u'd'), + (0x1D5D8, 'M', u'e'), + (0x1D5D9, 'M', u'f'), + (0x1D5DA, 'M', u'g'), + (0x1D5DB, 'M', u'h'), + (0x1D5DC, 'M', u'i'), + (0x1D5DD, 'M', u'j'), + (0x1D5DE, 'M', u'k'), + (0x1D5DF, 'M', u'l'), + (0x1D5E0, 'M', u'm'), + (0x1D5E1, 'M', u'n'), + (0x1D5E2, 'M', u'o'), + (0x1D5E3, 'M', u'p'), + (0x1D5E4, 'M', u'q'), + (0x1D5E5, 'M', u'r'), + (0x1D5E6, 'M', u's'), + (0x1D5E7, 'M', u't'), + (0x1D5E8, 'M', u'u'), + (0x1D5E9, 'M', u'v'), + (0x1D5EA, 'M', u'w'), + (0x1D5EB, 'M', u'x'), + (0x1D5EC, 'M', u'y'), + (0x1D5ED, 'M', u'z'), + (0x1D5EE, 'M', u'a'), + (0x1D5EF, 'M', u'b'), + (0x1D5F0, 'M', u'c'), + (0x1D5F1, 'M', u'd'), + (0x1D5F2, 'M', u'e'), + (0x1D5F3, 'M', u'f'), + (0x1D5F4, 'M', u'g'), + (0x1D5F5, 'M', u'h'), + (0x1D5F6, 'M', u'i'), + (0x1D5F7, 'M', u'j'), + (0x1D5F8, 'M', u'k'), + (0x1D5F9, 'M', u'l'), + (0x1D5FA, 'M', u'm'), + (0x1D5FB, 'M', u'n'), + (0x1D5FC, 'M', u'o'), + (0x1D5FD, 'M', u'p'), + (0x1D5FE, 'M', u'q'), + (0x1D5FF, 'M', u'r'), + (0x1D600, 'M', u's'), + (0x1D601, 'M', u't'), + (0x1D602, 'M', u'u'), + (0x1D603, 'M', u'v'), + (0x1D604, 'M', u'w'), + (0x1D605, 'M', u'x'), + (0x1D606, 'M', u'y'), + (0x1D607, 'M', u'z'), + (0x1D608, 'M', u'a'), + (0x1D609, 'M', u'b'), + (0x1D60A, 'M', u'c'), + (0x1D60B, 'M', u'd'), + (0x1D60C, 'M', u'e'), + (0x1D60D, 'M', u'f'), + (0x1D60E, 'M', u'g'), + (0x1D60F, 'M', u'h'), + (0x1D610, 'M', u'i'), + (0x1D611, 'M', u'j'), + (0x1D612, 'M', u'k'), + (0x1D613, 'M', u'l'), + (0x1D614, 'M', u'm'), + (0x1D615, 'M', u'n'), + (0x1D616, 'M', u'o'), + (0x1D617, 'M', u'p'), + (0x1D618, 'M', u'q'), + (0x1D619, 'M', u'r'), + (0x1D61A, 'M', u's'), + (0x1D61B, 'M', u't'), + (0x1D61C, 'M', u'u'), + (0x1D61D, 'M', u'v'), + (0x1D61E, 'M', u'w'), + (0x1D61F, 'M', u'x'), + (0x1D620, 'M', u'y'), + (0x1D621, 'M', u'z'), + (0x1D622, 'M', u'a'), + (0x1D623, 'M', u'b'), + (0x1D624, 'M', u'c'), + (0x1D625, 'M', u'd'), + (0x1D626, 'M', u'e'), + (0x1D627, 'M', u'f'), + (0x1D628, 'M', u'g'), + (0x1D629, 'M', u'h'), + (0x1D62A, 'M', u'i'), + (0x1D62B, 'M', u'j'), + (0x1D62C, 'M', u'k'), + (0x1D62D, 'M', u'l'), + (0x1D62E, 'M', u'm'), + (0x1D62F, 'M', u'n'), + (0x1D630, 'M', u'o'), + (0x1D631, 'M', u'p'), + (0x1D632, 'M', u'q'), + (0x1D633, 'M', u'r'), + (0x1D634, 'M', u's'), + (0x1D635, 'M', u't'), + (0x1D636, 'M', u'u'), + ] + +def _seg_59(): + return [ + (0x1D637, 'M', u'v'), + (0x1D638, 'M', u'w'), + (0x1D639, 'M', u'x'), + (0x1D63A, 'M', u'y'), + (0x1D63B, 'M', u'z'), + (0x1D63C, 'M', u'a'), + (0x1D63D, 'M', u'b'), + (0x1D63E, 'M', u'c'), + (0x1D63F, 'M', u'd'), + (0x1D640, 'M', u'e'), + (0x1D641, 'M', u'f'), + (0x1D642, 'M', u'g'), + (0x1D643, 'M', u'h'), + (0x1D644, 'M', u'i'), + (0x1D645, 'M', u'j'), + (0x1D646, 'M', u'k'), + (0x1D647, 'M', u'l'), + (0x1D648, 'M', u'm'), + (0x1D649, 'M', u'n'), + (0x1D64A, 'M', u'o'), + (0x1D64B, 'M', u'p'), + (0x1D64C, 'M', u'q'), + (0x1D64D, 'M', u'r'), + (0x1D64E, 'M', u's'), + (0x1D64F, 'M', u't'), + (0x1D650, 'M', u'u'), + (0x1D651, 'M', u'v'), + (0x1D652, 'M', u'w'), + (0x1D653, 'M', u'x'), + (0x1D654, 'M', u'y'), + (0x1D655, 'M', u'z'), + (0x1D656, 'M', u'a'), + (0x1D657, 'M', u'b'), + (0x1D658, 'M', u'c'), + (0x1D659, 'M', u'd'), + (0x1D65A, 'M', u'e'), + (0x1D65B, 'M', u'f'), + (0x1D65C, 'M', u'g'), + (0x1D65D, 'M', u'h'), + (0x1D65E, 'M', u'i'), + (0x1D65F, 'M', u'j'), + (0x1D660, 'M', u'k'), + (0x1D661, 'M', u'l'), + (0x1D662, 'M', u'm'), + (0x1D663, 'M', u'n'), + (0x1D664, 'M', u'o'), + (0x1D665, 'M', u'p'), + (0x1D666, 'M', u'q'), + (0x1D667, 'M', u'r'), + (0x1D668, 'M', u's'), + (0x1D669, 'M', u't'), + (0x1D66A, 'M', u'u'), + (0x1D66B, 'M', u'v'), + (0x1D66C, 'M', u'w'), + (0x1D66D, 'M', u'x'), + (0x1D66E, 'M', u'y'), + (0x1D66F, 'M', u'z'), + (0x1D670, 'M', u'a'), + (0x1D671, 'M', u'b'), + (0x1D672, 'M', u'c'), + (0x1D673, 'M', u'd'), + (0x1D674, 'M', u'e'), + (0x1D675, 'M', u'f'), + (0x1D676, 'M', u'g'), + (0x1D677, 'M', u'h'), + (0x1D678, 'M', u'i'), + (0x1D679, 'M', u'j'), + (0x1D67A, 'M', u'k'), + (0x1D67B, 'M', u'l'), + (0x1D67C, 'M', u'm'), + (0x1D67D, 'M', u'n'), + (0x1D67E, 'M', u'o'), + (0x1D67F, 'M', u'p'), + (0x1D680, 'M', u'q'), + (0x1D681, 'M', u'r'), + (0x1D682, 'M', u's'), + (0x1D683, 'M', u't'), + (0x1D684, 'M', u'u'), + (0x1D685, 'M', u'v'), + (0x1D686, 'M', u'w'), + (0x1D687, 'M', u'x'), + (0x1D688, 'M', u'y'), + (0x1D689, 'M', u'z'), + (0x1D68A, 'M', u'a'), + (0x1D68B, 'M', u'b'), + (0x1D68C, 'M', u'c'), + (0x1D68D, 'M', u'd'), + (0x1D68E, 'M', u'e'), + (0x1D68F, 'M', u'f'), + (0x1D690, 'M', u'g'), + (0x1D691, 'M', u'h'), + (0x1D692, 'M', u'i'), + (0x1D693, 'M', u'j'), + (0x1D694, 'M', u'k'), + (0x1D695, 'M', u'l'), + (0x1D696, 'M', u'm'), + (0x1D697, 'M', u'n'), + (0x1D698, 'M', u'o'), + (0x1D699, 'M', u'p'), + (0x1D69A, 'M', u'q'), + ] + +def _seg_60(): + return [ + (0x1D69B, 'M', u'r'), + (0x1D69C, 'M', u's'), + (0x1D69D, 'M', u't'), + (0x1D69E, 'M', u'u'), + (0x1D69F, 'M', u'v'), + (0x1D6A0, 'M', u'w'), + (0x1D6A1, 'M', u'x'), + (0x1D6A2, 'M', u'y'), + (0x1D6A3, 'M', u'z'), + (0x1D6A4, 'M', u'ı'), + (0x1D6A5, 'M', u'ȷ'), + (0x1D6A6, 'X'), + (0x1D6A8, 'M', u'α'), + (0x1D6A9, 'M', u'β'), + (0x1D6AA, 'M', u'γ'), + (0x1D6AB, 'M', u'δ'), + (0x1D6AC, 'M', u'ε'), + (0x1D6AD, 'M', u'ζ'), + (0x1D6AE, 'M', u'η'), + (0x1D6AF, 'M', u'θ'), + (0x1D6B0, 'M', u'ι'), + (0x1D6B1, 'M', u'κ'), + (0x1D6B2, 'M', u'λ'), + (0x1D6B3, 'M', u'μ'), + (0x1D6B4, 'M', u'ν'), + (0x1D6B5, 'M', u'ξ'), + (0x1D6B6, 'M', u'ο'), + (0x1D6B7, 'M', u'π'), + (0x1D6B8, 'M', u'ρ'), + (0x1D6B9, 'M', u'θ'), + (0x1D6BA, 'M', u'σ'), + (0x1D6BB, 'M', u'τ'), + (0x1D6BC, 'M', u'υ'), + (0x1D6BD, 'M', u'φ'), + (0x1D6BE, 'M', u'χ'), + (0x1D6BF, 'M', u'ψ'), + (0x1D6C0, 'M', u'ω'), + (0x1D6C1, 'M', u'∇'), + (0x1D6C2, 'M', u'α'), + (0x1D6C3, 'M', u'β'), + (0x1D6C4, 'M', u'γ'), + (0x1D6C5, 'M', u'δ'), + (0x1D6C6, 'M', u'ε'), + (0x1D6C7, 'M', u'ζ'), + (0x1D6C8, 'M', u'η'), + (0x1D6C9, 'M', u'θ'), + (0x1D6CA, 'M', u'ι'), + (0x1D6CB, 'M', u'κ'), + (0x1D6CC, 'M', u'λ'), + (0x1D6CD, 'M', u'μ'), + (0x1D6CE, 'M', u'ν'), + (0x1D6CF, 'M', u'ξ'), + (0x1D6D0, 'M', u'ο'), + (0x1D6D1, 'M', u'π'), + (0x1D6D2, 'M', u'ρ'), + (0x1D6D3, 'M', u'σ'), + (0x1D6D5, 'M', u'τ'), + (0x1D6D6, 'M', u'υ'), + (0x1D6D7, 'M', u'φ'), + (0x1D6D8, 'M', u'χ'), + (0x1D6D9, 'M', u'ψ'), + (0x1D6DA, 'M', u'ω'), + (0x1D6DB, 'M', u'∂'), + (0x1D6DC, 'M', u'ε'), + (0x1D6DD, 'M', u'θ'), + (0x1D6DE, 'M', u'κ'), + (0x1D6DF, 'M', u'φ'), + (0x1D6E0, 'M', u'ρ'), + (0x1D6E1, 'M', u'π'), + (0x1D6E2, 'M', u'α'), + (0x1D6E3, 'M', u'β'), + (0x1D6E4, 'M', u'γ'), + (0x1D6E5, 'M', u'δ'), + (0x1D6E6, 'M', u'ε'), + (0x1D6E7, 'M', u'ζ'), + (0x1D6E8, 'M', u'η'), + (0x1D6E9, 'M', u'θ'), + (0x1D6EA, 'M', u'ι'), + (0x1D6EB, 'M', u'κ'), + (0x1D6EC, 'M', u'λ'), + (0x1D6ED, 'M', u'μ'), + (0x1D6EE, 'M', u'ν'), + (0x1D6EF, 'M', u'ξ'), + (0x1D6F0, 'M', u'ο'), + (0x1D6F1, 'M', u'π'), + (0x1D6F2, 'M', u'ρ'), + (0x1D6F3, 'M', u'θ'), + (0x1D6F4, 'M', u'σ'), + (0x1D6F5, 'M', u'τ'), + (0x1D6F6, 'M', u'υ'), + (0x1D6F7, 'M', u'φ'), + (0x1D6F8, 'M', u'χ'), + (0x1D6F9, 'M', u'ψ'), + (0x1D6FA, 'M', u'ω'), + (0x1D6FB, 'M', u'∇'), + (0x1D6FC, 'M', u'α'), + (0x1D6FD, 'M', u'β'), + (0x1D6FE, 'M', u'γ'), + (0x1D6FF, 'M', u'δ'), + (0x1D700, 'M', u'ε'), + ] + +def _seg_61(): + return [ + (0x1D701, 'M', u'ζ'), + (0x1D702, 'M', u'η'), + (0x1D703, 'M', u'θ'), + (0x1D704, 'M', u'ι'), + (0x1D705, 'M', u'κ'), + (0x1D706, 'M', u'λ'), + (0x1D707, 'M', u'μ'), + (0x1D708, 'M', u'ν'), + (0x1D709, 'M', u'ξ'), + (0x1D70A, 'M', u'ο'), + (0x1D70B, 'M', u'π'), + (0x1D70C, 'M', u'ρ'), + (0x1D70D, 'M', u'σ'), + (0x1D70F, 'M', u'τ'), + (0x1D710, 'M', u'υ'), + (0x1D711, 'M', u'φ'), + (0x1D712, 'M', u'χ'), + (0x1D713, 'M', u'ψ'), + (0x1D714, 'M', u'ω'), + (0x1D715, 'M', u'∂'), + (0x1D716, 'M', u'ε'), + (0x1D717, 'M', u'θ'), + (0x1D718, 'M', u'κ'), + (0x1D719, 'M', u'φ'), + (0x1D71A, 'M', u'ρ'), + (0x1D71B, 'M', u'π'), + (0x1D71C, 'M', u'α'), + (0x1D71D, 'M', u'β'), + (0x1D71E, 'M', u'γ'), + (0x1D71F, 'M', u'δ'), + (0x1D720, 'M', u'ε'), + (0x1D721, 'M', u'ζ'), + (0x1D722, 'M', u'η'), + (0x1D723, 'M', u'θ'), + (0x1D724, 'M', u'ι'), + (0x1D725, 'M', u'κ'), + (0x1D726, 'M', u'λ'), + (0x1D727, 'M', u'μ'), + (0x1D728, 'M', u'ν'), + (0x1D729, 'M', u'ξ'), + (0x1D72A, 'M', u'ο'), + (0x1D72B, 'M', u'π'), + (0x1D72C, 'M', u'ρ'), + (0x1D72D, 'M', u'θ'), + (0x1D72E, 'M', u'σ'), + (0x1D72F, 'M', u'τ'), + (0x1D730, 'M', u'υ'), + (0x1D731, 'M', u'φ'), + (0x1D732, 'M', u'χ'), + (0x1D733, 'M', u'ψ'), + (0x1D734, 'M', u'ω'), + (0x1D735, 'M', u'∇'), + (0x1D736, 'M', u'α'), + (0x1D737, 'M', u'β'), + (0x1D738, 'M', u'γ'), + (0x1D739, 'M', u'δ'), + (0x1D73A, 'M', u'ε'), + (0x1D73B, 'M', u'ζ'), + (0x1D73C, 'M', u'η'), + (0x1D73D, 'M', u'θ'), + (0x1D73E, 'M', u'ι'), + (0x1D73F, 'M', u'κ'), + (0x1D740, 'M', u'λ'), + (0x1D741, 'M', u'μ'), + (0x1D742, 'M', u'ν'), + (0x1D743, 'M', u'ξ'), + (0x1D744, 'M', u'ο'), + (0x1D745, 'M', u'π'), + (0x1D746, 'M', u'ρ'), + (0x1D747, 'M', u'σ'), + (0x1D749, 'M', u'τ'), + (0x1D74A, 'M', u'υ'), + (0x1D74B, 'M', u'φ'), + (0x1D74C, 'M', u'χ'), + (0x1D74D, 'M', u'ψ'), + (0x1D74E, 'M', u'ω'), + (0x1D74F, 'M', u'∂'), + (0x1D750, 'M', u'ε'), + (0x1D751, 'M', u'θ'), + (0x1D752, 'M', u'κ'), + (0x1D753, 'M', u'φ'), + (0x1D754, 'M', u'ρ'), + (0x1D755, 'M', u'π'), + (0x1D756, 'M', u'α'), + (0x1D757, 'M', u'β'), + (0x1D758, 'M', u'γ'), + (0x1D759, 'M', u'δ'), + (0x1D75A, 'M', u'ε'), + (0x1D75B, 'M', u'ζ'), + (0x1D75C, 'M', u'η'), + (0x1D75D, 'M', u'θ'), + (0x1D75E, 'M', u'ι'), + (0x1D75F, 'M', u'κ'), + (0x1D760, 'M', u'λ'), + (0x1D761, 'M', u'μ'), + (0x1D762, 'M', u'ν'), + (0x1D763, 'M', u'ξ'), + (0x1D764, 'M', u'ο'), + (0x1D765, 'M', u'π'), + (0x1D766, 'M', u'ρ'), + ] + +def _seg_62(): + return [ + (0x1D767, 'M', u'θ'), + (0x1D768, 'M', u'σ'), + (0x1D769, 'M', u'τ'), + (0x1D76A, 'M', u'υ'), + (0x1D76B, 'M', u'φ'), + (0x1D76C, 'M', u'χ'), + (0x1D76D, 'M', u'ψ'), + (0x1D76E, 'M', u'ω'), + (0x1D76F, 'M', u'∇'), + (0x1D770, 'M', u'α'), + (0x1D771, 'M', u'β'), + (0x1D772, 'M', u'γ'), + (0x1D773, 'M', u'δ'), + (0x1D774, 'M', u'ε'), + (0x1D775, 'M', u'ζ'), + (0x1D776, 'M', u'η'), + (0x1D777, 'M', u'θ'), + (0x1D778, 'M', u'ι'), + (0x1D779, 'M', u'κ'), + (0x1D77A, 'M', u'λ'), + (0x1D77B, 'M', u'μ'), + (0x1D77C, 'M', u'ν'), + (0x1D77D, 'M', u'ξ'), + (0x1D77E, 'M', u'ο'), + (0x1D77F, 'M', u'π'), + (0x1D780, 'M', u'ρ'), + (0x1D781, 'M', u'σ'), + (0x1D783, 'M', u'τ'), + (0x1D784, 'M', u'υ'), + (0x1D785, 'M', u'φ'), + (0x1D786, 'M', u'χ'), + (0x1D787, 'M', u'ψ'), + (0x1D788, 'M', u'ω'), + (0x1D789, 'M', u'∂'), + (0x1D78A, 'M', u'ε'), + (0x1D78B, 'M', u'θ'), + (0x1D78C, 'M', u'κ'), + (0x1D78D, 'M', u'φ'), + (0x1D78E, 'M', u'ρ'), + (0x1D78F, 'M', u'π'), + (0x1D790, 'M', u'α'), + (0x1D791, 'M', u'β'), + (0x1D792, 'M', u'γ'), + (0x1D793, 'M', u'δ'), + (0x1D794, 'M', u'ε'), + (0x1D795, 'M', u'ζ'), + (0x1D796, 'M', u'η'), + (0x1D797, 'M', u'θ'), + (0x1D798, 'M', u'ι'), + (0x1D799, 'M', u'κ'), + (0x1D79A, 'M', u'λ'), + (0x1D79B, 'M', u'μ'), + (0x1D79C, 'M', u'ν'), + (0x1D79D, 'M', u'ξ'), + (0x1D79E, 'M', u'ο'), + (0x1D79F, 'M', u'π'), + (0x1D7A0, 'M', u'ρ'), + (0x1D7A1, 'M', u'θ'), + (0x1D7A2, 'M', u'σ'), + (0x1D7A3, 'M', u'τ'), + (0x1D7A4, 'M', u'υ'), + (0x1D7A5, 'M', u'φ'), + (0x1D7A6, 'M', u'χ'), + (0x1D7A7, 'M', u'ψ'), + (0x1D7A8, 'M', u'ω'), + (0x1D7A9, 'M', u'∇'), + (0x1D7AA, 'M', u'α'), + (0x1D7AB, 'M', u'β'), + (0x1D7AC, 'M', u'γ'), + (0x1D7AD, 'M', u'δ'), + (0x1D7AE, 'M', u'ε'), + (0x1D7AF, 'M', u'ζ'), + (0x1D7B0, 'M', u'η'), + (0x1D7B1, 'M', u'θ'), + (0x1D7B2, 'M', u'ι'), + (0x1D7B3, 'M', u'κ'), + (0x1D7B4, 'M', u'λ'), + (0x1D7B5, 'M', u'μ'), + (0x1D7B6, 'M', u'ν'), + (0x1D7B7, 'M', u'ξ'), + (0x1D7B8, 'M', u'ο'), + (0x1D7B9, 'M', u'π'), + (0x1D7BA, 'M', u'ρ'), + (0x1D7BB, 'M', u'σ'), + (0x1D7BD, 'M', u'τ'), + (0x1D7BE, 'M', u'υ'), + (0x1D7BF, 'M', u'φ'), + (0x1D7C0, 'M', u'χ'), + (0x1D7C1, 'M', u'ψ'), + (0x1D7C2, 'M', u'ω'), + (0x1D7C3, 'M', u'∂'), + (0x1D7C4, 'M', u'ε'), + (0x1D7C5, 'M', u'θ'), + (0x1D7C6, 'M', u'κ'), + (0x1D7C7, 'M', u'φ'), + (0x1D7C8, 'M', u'ρ'), + (0x1D7C9, 'M', u'π'), + (0x1D7CA, 'M', u'ϝ'), + (0x1D7CC, 'X'), + (0x1D7CE, 'M', u'0'), + ] + +def _seg_63(): + return [ + (0x1D7CF, 'M', u'1'), + (0x1D7D0, 'M', u'2'), + (0x1D7D1, 'M', u'3'), + (0x1D7D2, 'M', u'4'), + (0x1D7D3, 'M', u'5'), + (0x1D7D4, 'M', u'6'), + (0x1D7D5, 'M', u'7'), + (0x1D7D6, 'M', u'8'), + (0x1D7D7, 'M', u'9'), + (0x1D7D8, 'M', u'0'), + (0x1D7D9, 'M', u'1'), + (0x1D7DA, 'M', u'2'), + (0x1D7DB, 'M', u'3'), + (0x1D7DC, 'M', u'4'), + (0x1D7DD, 'M', u'5'), + (0x1D7DE, 'M', u'6'), + (0x1D7DF, 'M', u'7'), + (0x1D7E0, 'M', u'8'), + (0x1D7E1, 'M', u'9'), + (0x1D7E2, 'M', u'0'), + (0x1D7E3, 'M', u'1'), + (0x1D7E4, 'M', u'2'), + (0x1D7E5, 'M', u'3'), + (0x1D7E6, 'M', u'4'), + (0x1D7E7, 'M', u'5'), + (0x1D7E8, 'M', u'6'), + (0x1D7E9, 'M', u'7'), + (0x1D7EA, 'M', u'8'), + (0x1D7EB, 'M', u'9'), + (0x1D7EC, 'M', u'0'), + (0x1D7ED, 'M', u'1'), + (0x1D7EE, 'M', u'2'), + (0x1D7EF, 'M', u'3'), + (0x1D7F0, 'M', u'4'), + (0x1D7F1, 'M', u'5'), + (0x1D7F2, 'M', u'6'), + (0x1D7F3, 'M', u'7'), + (0x1D7F4, 'M', u'8'), + (0x1D7F5, 'M', u'9'), + (0x1D7F6, 'M', u'0'), + (0x1D7F7, 'M', u'1'), + (0x1D7F8, 'M', u'2'), + (0x1D7F9, 'M', u'3'), + (0x1D7FA, 'M', u'4'), + (0x1D7FB, 'M', u'5'), + (0x1D7FC, 'M', u'6'), + (0x1D7FD, 'M', u'7'), + (0x1D7FE, 'M', u'8'), + (0x1D7FF, 'M', u'9'), + (0x1D800, 'X'), + (0x1EE00, 'M', u'ا'), + (0x1EE01, 'M', u'ب'), + (0x1EE02, 'M', u'ج'), + (0x1EE03, 'M', u'د'), + (0x1EE04, 'X'), + (0x1EE05, 'M', u'و'), + (0x1EE06, 'M', u'ز'), + (0x1EE07, 'M', u'ح'), + (0x1EE08, 'M', u'ط'), + (0x1EE09, 'M', u'ي'), + (0x1EE0A, 'M', u'ك'), + (0x1EE0B, 'M', u'ل'), + (0x1EE0C, 'M', u'م'), + (0x1EE0D, 'M', u'ن'), + (0x1EE0E, 'M', u'س'), + (0x1EE0F, 'M', u'ع'), + (0x1EE10, 'M', u'ف'), + (0x1EE11, 'M', u'ص'), + (0x1EE12, 'M', u'ق'), + (0x1EE13, 'M', u'ر'), + (0x1EE14, 'M', u'ش'), + (0x1EE15, 'M', u'ت'), + (0x1EE16, 'M', u'ث'), + (0x1EE17, 'M', u'خ'), + (0x1EE18, 'M', u'ذ'), + (0x1EE19, 'M', u'ض'), + (0x1EE1A, 'M', u'ظ'), + (0x1EE1B, 'M', u'غ'), + (0x1EE1C, 'M', u'ٮ'), + (0x1EE1D, 'M', u'ں'), + (0x1EE1E, 'M', u'ڡ'), + (0x1EE1F, 'M', u'ٯ'), + (0x1EE20, 'X'), + (0x1EE21, 'M', u'ب'), + (0x1EE22, 'M', u'ج'), + (0x1EE23, 'X'), + (0x1EE24, 'M', u'ه'), + (0x1EE25, 'X'), + (0x1EE27, 'M', u'ح'), + (0x1EE28, 'X'), + (0x1EE29, 'M', u'ي'), + (0x1EE2A, 'M', u'ك'), + (0x1EE2B, 'M', u'ل'), + (0x1EE2C, 'M', u'م'), + (0x1EE2D, 'M', u'ن'), + (0x1EE2E, 'M', u'س'), + (0x1EE2F, 'M', u'ع'), + (0x1EE30, 'M', u'ف'), + (0x1EE31, 'M', u'ص'), + (0x1EE32, 'M', u'ق'), + ] + +def _seg_64(): + return [ + (0x1EE33, 'X'), + (0x1EE34, 'M', u'ش'), + (0x1EE35, 'M', u'ت'), + (0x1EE36, 'M', u'ث'), + (0x1EE37, 'M', u'خ'), + (0x1EE38, 'X'), + (0x1EE39, 'M', u'ض'), + (0x1EE3A, 'X'), + (0x1EE3B, 'M', u'غ'), + (0x1EE3C, 'X'), + (0x1EE42, 'M', u'ج'), + (0x1EE43, 'X'), + (0x1EE47, 'M', u'ح'), + (0x1EE48, 'X'), + (0x1EE49, 'M', u'ي'), + (0x1EE4A, 'X'), + (0x1EE4B, 'M', u'ل'), + (0x1EE4C, 'X'), + (0x1EE4D, 'M', u'ن'), + (0x1EE4E, 'M', u'س'), + (0x1EE4F, 'M', u'ع'), + (0x1EE50, 'X'), + (0x1EE51, 'M', u'ص'), + (0x1EE52, 'M', u'ق'), + (0x1EE53, 'X'), + (0x1EE54, 'M', u'ش'), + (0x1EE55, 'X'), + (0x1EE57, 'M', u'خ'), + (0x1EE58, 'X'), + (0x1EE59, 'M', u'ض'), + (0x1EE5A, 'X'), + (0x1EE5B, 'M', u'غ'), + (0x1EE5C, 'X'), + (0x1EE5D, 'M', u'ں'), + (0x1EE5E, 'X'), + (0x1EE5F, 'M', u'ٯ'), + (0x1EE60, 'X'), + (0x1EE61, 'M', u'ب'), + (0x1EE62, 'M', u'ج'), + (0x1EE63, 'X'), + (0x1EE64, 'M', u'ه'), + (0x1EE65, 'X'), + (0x1EE67, 'M', u'ح'), + (0x1EE68, 'M', u'ط'), + (0x1EE69, 'M', u'ي'), + (0x1EE6A, 'M', u'ك'), + (0x1EE6B, 'X'), + (0x1EE6C, 'M', u'م'), + (0x1EE6D, 'M', u'ن'), + (0x1EE6E, 'M', u'س'), + (0x1EE6F, 'M', u'ع'), + (0x1EE70, 'M', u'ف'), + (0x1EE71, 'M', u'ص'), + (0x1EE72, 'M', u'ق'), + (0x1EE73, 'X'), + (0x1EE74, 'M', u'ش'), + (0x1EE75, 'M', u'ت'), + (0x1EE76, 'M', u'ث'), + (0x1EE77, 'M', u'خ'), + (0x1EE78, 'X'), + (0x1EE79, 'M', u'ض'), + (0x1EE7A, 'M', u'ظ'), + (0x1EE7B, 'M', u'غ'), + (0x1EE7C, 'M', u'ٮ'), + (0x1EE7D, 'X'), + (0x1EE7E, 'M', u'ڡ'), + (0x1EE7F, 'X'), + (0x1EE80, 'M', u'ا'), + (0x1EE81, 'M', u'ب'), + (0x1EE82, 'M', u'ج'), + (0x1EE83, 'M', u'د'), + (0x1EE84, 'M', u'ه'), + (0x1EE85, 'M', u'و'), + (0x1EE86, 'M', u'ز'), + (0x1EE87, 'M', u'ح'), + (0x1EE88, 'M', u'ط'), + (0x1EE89, 'M', u'ي'), + (0x1EE8A, 'X'), + (0x1EE8B, 'M', u'ل'), + (0x1EE8C, 'M', u'م'), + (0x1EE8D, 'M', u'ن'), + (0x1EE8E, 'M', u'س'), + (0x1EE8F, 'M', u'ع'), + (0x1EE90, 'M', u'ف'), + (0x1EE91, 'M', u'ص'), + (0x1EE92, 'M', u'ق'), + (0x1EE93, 'M', u'ر'), + (0x1EE94, 'M', u'ش'), + (0x1EE95, 'M', u'ت'), + (0x1EE96, 'M', u'ث'), + (0x1EE97, 'M', u'خ'), + (0x1EE98, 'M', u'ذ'), + (0x1EE99, 'M', u'ض'), + (0x1EE9A, 'M', u'ظ'), + (0x1EE9B, 'M', u'غ'), + (0x1EE9C, 'X'), + (0x1EEA1, 'M', u'ب'), + (0x1EEA2, 'M', u'ج'), + (0x1EEA3, 'M', u'د'), + (0x1EEA4, 'X'), + ] + +def _seg_65(): + return [ + (0x1EEA5, 'M', u'و'), + (0x1EEA6, 'M', u'ز'), + (0x1EEA7, 'M', u'ح'), + (0x1EEA8, 'M', u'ط'), + (0x1EEA9, 'M', u'ي'), + (0x1EEAA, 'X'), + (0x1EEAB, 'M', u'ل'), + (0x1EEAC, 'M', u'م'), + (0x1EEAD, 'M', u'ن'), + (0x1EEAE, 'M', u'س'), + (0x1EEAF, 'M', u'ع'), + (0x1EEB0, 'M', u'ف'), + (0x1EEB1, 'M', u'ص'), + (0x1EEB2, 'M', u'ق'), + (0x1EEB3, 'M', u'ر'), + (0x1EEB4, 'M', u'ش'), + (0x1EEB5, 'M', u'ت'), + (0x1EEB6, 'M', u'ث'), + (0x1EEB7, 'M', u'خ'), + (0x1EEB8, 'M', u'ذ'), + (0x1EEB9, 'M', u'ض'), + (0x1EEBA, 'M', u'ظ'), + (0x1EEBB, 'M', u'غ'), + (0x1EEBC, 'X'), + (0x1EEF0, 'V'), + (0x1EEF2, 'X'), + (0x1F000, 'V'), + (0x1F02C, 'X'), + (0x1F030, 'V'), + (0x1F094, 'X'), + (0x1F0A0, 'V'), + (0x1F0AF, 'X'), + (0x1F0B1, 'V'), + (0x1F0BF, 'X'), + (0x1F0C1, 'V'), + (0x1F0D0, 'X'), + (0x1F0D1, 'V'), + (0x1F0E0, 'X'), + (0x1F101, '3', u'0,'), + (0x1F102, '3', u'1,'), + (0x1F103, '3', u'2,'), + (0x1F104, '3', u'3,'), + (0x1F105, '3', u'4,'), + (0x1F106, '3', u'5,'), + (0x1F107, '3', u'6,'), + (0x1F108, '3', u'7,'), + (0x1F109, '3', u'8,'), + (0x1F10A, '3', u'9,'), + (0x1F10B, 'X'), + (0x1F110, '3', u'(a)'), + (0x1F111, '3', u'(b)'), + (0x1F112, '3', u'(c)'), + (0x1F113, '3', u'(d)'), + (0x1F114, '3', u'(e)'), + (0x1F115, '3', u'(f)'), + (0x1F116, '3', u'(g)'), + (0x1F117, '3', u'(h)'), + (0x1F118, '3', u'(i)'), + (0x1F119, '3', u'(j)'), + (0x1F11A, '3', u'(k)'), + (0x1F11B, '3', u'(l)'), + (0x1F11C, '3', u'(m)'), + (0x1F11D, '3', u'(n)'), + (0x1F11E, '3', u'(o)'), + (0x1F11F, '3', u'(p)'), + (0x1F120, '3', u'(q)'), + (0x1F121, '3', u'(r)'), + (0x1F122, '3', u'(s)'), + (0x1F123, '3', u'(t)'), + (0x1F124, '3', u'(u)'), + (0x1F125, '3', u'(v)'), + (0x1F126, '3', u'(w)'), + (0x1F127, '3', u'(x)'), + (0x1F128, '3', u'(y)'), + (0x1F129, '3', u'(z)'), + (0x1F12A, 'M', u'〔s〕'), + (0x1F12B, 'M', u'c'), + (0x1F12C, 'M', u'r'), + (0x1F12D, 'M', u'cd'), + (0x1F12E, 'M', u'wz'), + (0x1F12F, 'X'), + (0x1F130, 'M', u'a'), + (0x1F131, 'M', u'b'), + (0x1F132, 'M', u'c'), + (0x1F133, 'M', u'd'), + (0x1F134, 'M', u'e'), + (0x1F135, 'M', u'f'), + (0x1F136, 'M', u'g'), + (0x1F137, 'M', u'h'), + (0x1F138, 'M', u'i'), + (0x1F139, 'M', u'j'), + (0x1F13A, 'M', u'k'), + (0x1F13B, 'M', u'l'), + (0x1F13C, 'M', u'm'), + (0x1F13D, 'M', u'n'), + (0x1F13E, 'M', u'o'), + (0x1F13F, 'M', u'p'), + (0x1F140, 'M', u'q'), + (0x1F141, 'M', u'r'), + (0x1F142, 'M', u's'), + ] + +def _seg_66(): + return [ + (0x1F143, 'M', u't'), + (0x1F144, 'M', u'u'), + (0x1F145, 'M', u'v'), + (0x1F146, 'M', u'w'), + (0x1F147, 'M', u'x'), + (0x1F148, 'M', u'y'), + (0x1F149, 'M', u'z'), + (0x1F14A, 'M', u'hv'), + (0x1F14B, 'M', u'mv'), + (0x1F14C, 'M', u'sd'), + (0x1F14D, 'M', u'ss'), + (0x1F14E, 'M', u'ppv'), + (0x1F14F, 'M', u'wc'), + (0x1F150, 'V'), + (0x1F16A, 'M', u'mc'), + (0x1F16B, 'M', u'md'), + (0x1F16C, 'X'), + (0x1F170, 'V'), + (0x1F190, 'M', u'dj'), + (0x1F191, 'V'), + (0x1F19B, 'X'), + (0x1F1E6, 'V'), + (0x1F200, 'M', u'ほか'), + (0x1F201, 'M', u'ココ'), + (0x1F202, 'M', u'サ'), + (0x1F203, 'X'), + (0x1F210, 'M', u'手'), + (0x1F211, 'M', u'字'), + (0x1F212, 'M', u'双'), + (0x1F213, 'M', u'デ'), + (0x1F214, 'M', u'二'), + (0x1F215, 'M', u'多'), + (0x1F216, 'M', u'解'), + (0x1F217, 'M', u'天'), + (0x1F218, 'M', u'交'), + (0x1F219, 'M', u'映'), + (0x1F21A, 'M', u'無'), + (0x1F21B, 'M', u'料'), + (0x1F21C, 'M', u'前'), + (0x1F21D, 'M', u'後'), + (0x1F21E, 'M', u'再'), + (0x1F21F, 'M', u'新'), + (0x1F220, 'M', u'初'), + (0x1F221, 'M', u'終'), + (0x1F222, 'M', u'生'), + (0x1F223, 'M', u'販'), + (0x1F224, 'M', u'声'), + (0x1F225, 'M', u'吹'), + (0x1F226, 'M', u'演'), + (0x1F227, 'M', u'投'), + (0x1F228, 'M', u'捕'), + (0x1F229, 'M', u'一'), + (0x1F22A, 'M', u'三'), + (0x1F22B, 'M', u'遊'), + (0x1F22C, 'M', u'左'), + (0x1F22D, 'M', u'中'), + (0x1F22E, 'M', u'右'), + (0x1F22F, 'M', u'指'), + (0x1F230, 'M', u'走'), + (0x1F231, 'M', u'打'), + (0x1F232, 'M', u'禁'), + (0x1F233, 'M', u'空'), + (0x1F234, 'M', u'合'), + (0x1F235, 'M', u'満'), + (0x1F236, 'M', u'有'), + (0x1F237, 'M', u'月'), + (0x1F238, 'M', u'申'), + (0x1F239, 'M', u'割'), + (0x1F23A, 'M', u'営'), + (0x1F23B, 'X'), + (0x1F240, 'M', u'〔本〕'), + (0x1F241, 'M', u'〔三〕'), + (0x1F242, 'M', u'〔二〕'), + (0x1F243, 'M', u'〔安〕'), + (0x1F244, 'M', u'〔点〕'), + (0x1F245, 'M', u'〔打〕'), + (0x1F246, 'M', u'〔盗〕'), + (0x1F247, 'M', u'〔勝〕'), + (0x1F248, 'M', u'〔敗〕'), + (0x1F249, 'X'), + (0x1F250, 'M', u'得'), + (0x1F251, 'M', u'可'), + (0x1F252, 'X'), + (0x1F300, 'V'), + (0x1F321, 'X'), + (0x1F330, 'V'), + (0x1F336, 'X'), + (0x1F337, 'V'), + (0x1F37D, 'X'), + (0x1F380, 'V'), + (0x1F394, 'X'), + (0x1F3A0, 'V'), + (0x1F3C5, 'X'), + (0x1F3C6, 'V'), + (0x1F3CB, 'X'), + (0x1F3E0, 'V'), + (0x1F3F1, 'X'), + (0x1F400, 'V'), + (0x1F43F, 'X'), + (0x1F440, 'V'), + ] + +def _seg_67(): + return [ + (0x1F441, 'X'), + (0x1F442, 'V'), + (0x1F4F8, 'X'), + (0x1F4F9, 'V'), + (0x1F4FD, 'X'), + (0x1F500, 'V'), + (0x1F53E, 'X'), + (0x1F540, 'V'), + (0x1F544, 'X'), + (0x1F550, 'V'), + (0x1F568, 'X'), + (0x1F5FB, 'V'), + (0x1F641, 'X'), + (0x1F645, 'V'), + (0x1F650, 'X'), + (0x1F680, 'V'), + (0x1F6C6, 'X'), + (0x1F700, 'V'), + (0x1F774, 'X'), + (0x20000, 'V'), + (0x2A6D7, 'X'), + (0x2A700, 'V'), + (0x2B735, 'X'), + (0x2B740, 'V'), + (0x2B81E, 'X'), + (0x2F800, 'M', u'丽'), + (0x2F801, 'M', u'丸'), + (0x2F802, 'M', u'乁'), + (0x2F803, 'M', u'𠄢'), + (0x2F804, 'M', u'你'), + (0x2F805, 'M', u'侮'), + (0x2F806, 'M', u'侻'), + (0x2F807, 'M', u'倂'), + (0x2F808, 'M', u'偺'), + (0x2F809, 'M', u'備'), + (0x2F80A, 'M', u'僧'), + (0x2F80B, 'M', u'像'), + (0x2F80C, 'M', u'㒞'), + (0x2F80D, 'M', u'𠘺'), + (0x2F80E, 'M', u'免'), + (0x2F80F, 'M', u'兔'), + (0x2F810, 'M', u'兤'), + (0x2F811, 'M', u'具'), + (0x2F812, 'M', u'𠔜'), + (0x2F813, 'M', u'㒹'), + (0x2F814, 'M', u'內'), + (0x2F815, 'M', u'再'), + (0x2F816, 'M', u'𠕋'), + (0x2F817, 'M', u'冗'), + (0x2F818, 'M', u'冤'), + (0x2F819, 'M', u'仌'), + (0x2F81A, 'M', u'冬'), + (0x2F81B, 'M', u'况'), + (0x2F81C, 'M', u'𩇟'), + (0x2F81D, 'M', u'凵'), + (0x2F81E, 'M', u'刃'), + (0x2F81F, 'M', u'㓟'), + (0x2F820, 'M', u'刻'), + (0x2F821, 'M', u'剆'), + (0x2F822, 'M', u'割'), + (0x2F823, 'M', u'剷'), + (0x2F824, 'M', u'㔕'), + (0x2F825, 'M', u'勇'), + (0x2F826, 'M', u'勉'), + (0x2F827, 'M', u'勤'), + (0x2F828, 'M', u'勺'), + (0x2F829, 'M', u'包'), + (0x2F82A, 'M', u'匆'), + (0x2F82B, 'M', u'北'), + (0x2F82C, 'M', u'卉'), + (0x2F82D, 'M', u'卑'), + (0x2F82E, 'M', u'博'), + (0x2F82F, 'M', u'即'), + (0x2F830, 'M', u'卽'), + (0x2F831, 'M', u'卿'), + (0x2F834, 'M', u'𠨬'), + (0x2F835, 'M', u'灰'), + (0x2F836, 'M', u'及'), + (0x2F837, 'M', u'叟'), + (0x2F838, 'M', u'𠭣'), + (0x2F839, 'M', u'叫'), + (0x2F83A, 'M', u'叱'), + (0x2F83B, 'M', u'吆'), + (0x2F83C, 'M', u'咞'), + (0x2F83D, 'M', u'吸'), + (0x2F83E, 'M', u'呈'), + (0x2F83F, 'M', u'周'), + (0x2F840, 'M', u'咢'), + (0x2F841, 'M', u'哶'), + (0x2F842, 'M', u'唐'), + (0x2F843, 'M', u'啓'), + (0x2F844, 'M', u'啣'), + (0x2F845, 'M', u'善'), + (0x2F847, 'M', u'喙'), + (0x2F848, 'M', u'喫'), + (0x2F849, 'M', u'喳'), + (0x2F84A, 'M', u'嗂'), + (0x2F84B, 'M', u'圖'), + (0x2F84C, 'M', u'嘆'), + (0x2F84D, 'M', u'圗'), + ] + +def _seg_68(): + return [ + (0x2F84E, 'M', u'噑'), + (0x2F84F, 'M', u'噴'), + (0x2F850, 'M', u'切'), + (0x2F851, 'M', u'壮'), + (0x2F852, 'M', u'城'), + (0x2F853, 'M', u'埴'), + (0x2F854, 'M', u'堍'), + (0x2F855, 'M', u'型'), + (0x2F856, 'M', u'堲'), + (0x2F857, 'M', u'報'), + (0x2F858, 'M', u'墬'), + (0x2F859, 'M', u'𡓤'), + (0x2F85A, 'M', u'売'), + (0x2F85B, 'M', u'壷'), + (0x2F85C, 'M', u'夆'), + (0x2F85D, 'M', u'多'), + (0x2F85E, 'M', u'夢'), + (0x2F85F, 'M', u'奢'), + (0x2F860, 'M', u'𡚨'), + (0x2F861, 'M', u'𡛪'), + (0x2F862, 'M', u'姬'), + (0x2F863, 'M', u'娛'), + (0x2F864, 'M', u'娧'), + (0x2F865, 'M', u'姘'), + (0x2F866, 'M', u'婦'), + (0x2F867, 'M', u'㛮'), + (0x2F868, 'X'), + (0x2F869, 'M', u'嬈'), + (0x2F86A, 'M', u'嬾'), + (0x2F86C, 'M', u'𡧈'), + (0x2F86D, 'M', u'寃'), + (0x2F86E, 'M', u'寘'), + (0x2F86F, 'M', u'寧'), + (0x2F870, 'M', u'寳'), + (0x2F871, 'M', u'𡬘'), + (0x2F872, 'M', u'寿'), + (0x2F873, 'M', u'将'), + (0x2F874, 'X'), + (0x2F875, 'M', u'尢'), + (0x2F876, 'M', u'㞁'), + (0x2F877, 'M', u'屠'), + (0x2F878, 'M', u'屮'), + (0x2F879, 'M', u'峀'), + (0x2F87A, 'M', u'岍'), + (0x2F87B, 'M', u'𡷤'), + (0x2F87C, 'M', u'嵃'), + (0x2F87D, 'M', u'𡷦'), + (0x2F87E, 'M', u'嵮'), + (0x2F87F, 'M', u'嵫'), + (0x2F880, 'M', u'嵼'), + (0x2F881, 'M', u'巡'), + (0x2F882, 'M', u'巢'), + (0x2F883, 'M', u'㠯'), + (0x2F884, 'M', u'巽'), + (0x2F885, 'M', u'帨'), + (0x2F886, 'M', u'帽'), + (0x2F887, 'M', u'幩'), + (0x2F888, 'M', u'㡢'), + (0x2F889, 'M', u'𢆃'), + (0x2F88A, 'M', u'㡼'), + (0x2F88B, 'M', u'庰'), + (0x2F88C, 'M', u'庳'), + (0x2F88D, 'M', u'庶'), + (0x2F88E, 'M', u'廊'), + (0x2F88F, 'M', u'𪎒'), + (0x2F890, 'M', u'廾'), + (0x2F891, 'M', u'𢌱'), + (0x2F893, 'M', u'舁'), + (0x2F894, 'M', u'弢'), + (0x2F896, 'M', u'㣇'), + (0x2F897, 'M', u'𣊸'), + (0x2F898, 'M', u'𦇚'), + (0x2F899, 'M', u'形'), + (0x2F89A, 'M', u'彫'), + (0x2F89B, 'M', u'㣣'), + (0x2F89C, 'M', u'徚'), + (0x2F89D, 'M', u'忍'), + (0x2F89E, 'M', u'志'), + (0x2F89F, 'M', u'忹'), + (0x2F8A0, 'M', u'悁'), + (0x2F8A1, 'M', u'㤺'), + (0x2F8A2, 'M', u'㤜'), + (0x2F8A3, 'M', u'悔'), + (0x2F8A4, 'M', u'𢛔'), + (0x2F8A5, 'M', u'惇'), + (0x2F8A6, 'M', u'慈'), + (0x2F8A7, 'M', u'慌'), + (0x2F8A8, 'M', u'慎'), + (0x2F8A9, 'M', u'慌'), + (0x2F8AA, 'M', u'慺'), + (0x2F8AB, 'M', u'憎'), + (0x2F8AC, 'M', u'憲'), + (0x2F8AD, 'M', u'憤'), + (0x2F8AE, 'M', u'憯'), + (0x2F8AF, 'M', u'懞'), + (0x2F8B0, 'M', u'懲'), + (0x2F8B1, 'M', u'懶'), + (0x2F8B2, 'M', u'成'), + (0x2F8B3, 'M', u'戛'), + (0x2F8B4, 'M', u'扝'), + ] + +def _seg_69(): + return [ + (0x2F8B5, 'M', u'抱'), + (0x2F8B6, 'M', u'拔'), + (0x2F8B7, 'M', u'捐'), + (0x2F8B8, 'M', u'𢬌'), + (0x2F8B9, 'M', u'挽'), + (0x2F8BA, 'M', u'拼'), + (0x2F8BB, 'M', u'捨'), + (0x2F8BC, 'M', u'掃'), + (0x2F8BD, 'M', u'揤'), + (0x2F8BE, 'M', u'𢯱'), + (0x2F8BF, 'M', u'搢'), + (0x2F8C0, 'M', u'揅'), + (0x2F8C1, 'M', u'掩'), + (0x2F8C2, 'M', u'㨮'), + (0x2F8C3, 'M', u'摩'), + (0x2F8C4, 'M', u'摾'), + (0x2F8C5, 'M', u'撝'), + (0x2F8C6, 'M', u'摷'), + (0x2F8C7, 'M', u'㩬'), + (0x2F8C8, 'M', u'敏'), + (0x2F8C9, 'M', u'敬'), + (0x2F8CA, 'M', u'𣀊'), + (0x2F8CB, 'M', u'旣'), + (0x2F8CC, 'M', u'書'), + (0x2F8CD, 'M', u'晉'), + (0x2F8CE, 'M', u'㬙'), + (0x2F8CF, 'M', u'暑'), + (0x2F8D0, 'M', u'㬈'), + (0x2F8D1, 'M', u'㫤'), + (0x2F8D2, 'M', u'冒'), + (0x2F8D3, 'M', u'冕'), + (0x2F8D4, 'M', u'最'), + (0x2F8D5, 'M', u'暜'), + (0x2F8D6, 'M', u'肭'), + (0x2F8D7, 'M', u'䏙'), + (0x2F8D8, 'M', u'朗'), + (0x2F8D9, 'M', u'望'), + (0x2F8DA, 'M', u'朡'), + (0x2F8DB, 'M', u'杞'), + (0x2F8DC, 'M', u'杓'), + (0x2F8DD, 'M', u'𣏃'), + (0x2F8DE, 'M', u'㭉'), + (0x2F8DF, 'M', u'柺'), + (0x2F8E0, 'M', u'枅'), + (0x2F8E1, 'M', u'桒'), + (0x2F8E2, 'M', u'梅'), + (0x2F8E3, 'M', u'𣑭'), + (0x2F8E4, 'M', u'梎'), + (0x2F8E5, 'M', u'栟'), + (0x2F8E6, 'M', u'椔'), + (0x2F8E7, 'M', u'㮝'), + (0x2F8E8, 'M', u'楂'), + (0x2F8E9, 'M', u'榣'), + (0x2F8EA, 'M', u'槪'), + (0x2F8EB, 'M', u'檨'), + (0x2F8EC, 'M', u'𣚣'), + (0x2F8ED, 'M', u'櫛'), + (0x2F8EE, 'M', u'㰘'), + (0x2F8EF, 'M', u'次'), + (0x2F8F0, 'M', u'𣢧'), + (0x2F8F1, 'M', u'歔'), + (0x2F8F2, 'M', u'㱎'), + (0x2F8F3, 'M', u'歲'), + (0x2F8F4, 'M', u'殟'), + (0x2F8F5, 'M', u'殺'), + (0x2F8F6, 'M', u'殻'), + (0x2F8F7, 'M', u'𣪍'), + (0x2F8F8, 'M', u'𡴋'), + (0x2F8F9, 'M', u'𣫺'), + (0x2F8FA, 'M', u'汎'), + (0x2F8FB, 'M', u'𣲼'), + (0x2F8FC, 'M', u'沿'), + (0x2F8FD, 'M', u'泍'), + (0x2F8FE, 'M', u'汧'), + (0x2F8FF, 'M', u'洖'), + (0x2F900, 'M', u'派'), + (0x2F901, 'M', u'海'), + (0x2F902, 'M', u'流'), + (0x2F903, 'M', u'浩'), + (0x2F904, 'M', u'浸'), + (0x2F905, 'M', u'涅'), + (0x2F906, 'M', u'𣴞'), + (0x2F907, 'M', u'洴'), + (0x2F908, 'M', u'港'), + (0x2F909, 'M', u'湮'), + (0x2F90A, 'M', u'㴳'), + (0x2F90B, 'M', u'滋'), + (0x2F90C, 'M', u'滇'), + (0x2F90D, 'M', u'𣻑'), + (0x2F90E, 'M', u'淹'), + (0x2F90F, 'M', u'潮'), + (0x2F910, 'M', u'𣽞'), + (0x2F911, 'M', u'𣾎'), + (0x2F912, 'M', u'濆'), + (0x2F913, 'M', u'瀹'), + (0x2F914, 'M', u'瀞'), + (0x2F915, 'M', u'瀛'), + (0x2F916, 'M', u'㶖'), + (0x2F917, 'M', u'灊'), + (0x2F918, 'M', u'災'), + ] + +def _seg_70(): + return [ + (0x2F919, 'M', u'灷'), + (0x2F91A, 'M', u'炭'), + (0x2F91B, 'M', u'𠔥'), + (0x2F91C, 'M', u'煅'), + (0x2F91D, 'M', u'𤉣'), + (0x2F91E, 'M', u'熜'), + (0x2F91F, 'X'), + (0x2F920, 'M', u'爨'), + (0x2F921, 'M', u'爵'), + (0x2F922, 'M', u'牐'), + (0x2F923, 'M', u'𤘈'), + (0x2F924, 'M', u'犀'), + (0x2F925, 'M', u'犕'), + (0x2F926, 'M', u'𤜵'), + (0x2F927, 'M', u'𤠔'), + (0x2F928, 'M', u'獺'), + (0x2F929, 'M', u'王'), + (0x2F92A, 'M', u'㺬'), + (0x2F92B, 'M', u'玥'), + (0x2F92C, 'M', u'㺸'), + (0x2F92E, 'M', u'瑇'), + (0x2F92F, 'M', u'瑜'), + (0x2F930, 'M', u'瑱'), + (0x2F931, 'M', u'璅'), + (0x2F932, 'M', u'瓊'), + (0x2F933, 'M', u'㼛'), + (0x2F934, 'M', u'甤'), + (0x2F935, 'M', u'𤰶'), + (0x2F936, 'M', u'甾'), + (0x2F937, 'M', u'𤲒'), + (0x2F938, 'M', u'異'), + (0x2F939, 'M', u'𢆟'), + (0x2F93A, 'M', u'瘐'), + (0x2F93B, 'M', u'𤾡'), + (0x2F93C, 'M', u'𤾸'), + (0x2F93D, 'M', u'𥁄'), + (0x2F93E, 'M', u'㿼'), + (0x2F93F, 'M', u'䀈'), + (0x2F940, 'M', u'直'), + (0x2F941, 'M', u'𥃳'), + (0x2F942, 'M', u'𥃲'), + (0x2F943, 'M', u'𥄙'), + (0x2F944, 'M', u'𥄳'), + (0x2F945, 'M', u'眞'), + (0x2F946, 'M', u'真'), + (0x2F948, 'M', u'睊'), + (0x2F949, 'M', u'䀹'), + (0x2F94A, 'M', u'瞋'), + (0x2F94B, 'M', u'䁆'), + (0x2F94C, 'M', u'䂖'), + (0x2F94D, 'M', u'𥐝'), + (0x2F94E, 'M', u'硎'), + (0x2F94F, 'M', u'碌'), + (0x2F950, 'M', u'磌'), + (0x2F951, 'M', u'䃣'), + (0x2F952, 'M', u'𥘦'), + (0x2F953, 'M', u'祖'), + (0x2F954, 'M', u'𥚚'), + (0x2F955, 'M', u'𥛅'), + (0x2F956, 'M', u'福'), + (0x2F957, 'M', u'秫'), + (0x2F958, 'M', u'䄯'), + (0x2F959, 'M', u'穀'), + (0x2F95A, 'M', u'穊'), + (0x2F95B, 'M', u'穏'), + (0x2F95C, 'M', u'𥥼'), + (0x2F95D, 'M', u'𥪧'), + (0x2F95F, 'X'), + (0x2F960, 'M', u'䈂'), + (0x2F961, 'M', u'𥮫'), + (0x2F962, 'M', u'篆'), + (0x2F963, 'M', u'築'), + (0x2F964, 'M', u'䈧'), + (0x2F965, 'M', u'𥲀'), + (0x2F966, 'M', u'糒'), + (0x2F967, 'M', u'䊠'), + (0x2F968, 'M', u'糨'), + (0x2F969, 'M', u'糣'), + (0x2F96A, 'M', u'紀'), + (0x2F96B, 'M', u'𥾆'), + (0x2F96C, 'M', u'絣'), + (0x2F96D, 'M', u'䌁'), + (0x2F96E, 'M', u'緇'), + (0x2F96F, 'M', u'縂'), + (0x2F970, 'M', u'繅'), + (0x2F971, 'M', u'䌴'), + (0x2F972, 'M', u'𦈨'), + (0x2F973, 'M', u'𦉇'), + (0x2F974, 'M', u'䍙'), + (0x2F975, 'M', u'𦋙'), + (0x2F976, 'M', u'罺'), + (0x2F977, 'M', u'𦌾'), + (0x2F978, 'M', u'羕'), + (0x2F979, 'M', u'翺'), + (0x2F97A, 'M', u'者'), + (0x2F97B, 'M', u'𦓚'), + (0x2F97C, 'M', u'𦔣'), + (0x2F97D, 'M', u'聠'), + (0x2F97E, 'M', u'𦖨'), + (0x2F97F, 'M', u'聰'), + ] + +def _seg_71(): + return [ + (0x2F980, 'M', u'𣍟'), + (0x2F981, 'M', u'䏕'), + (0x2F982, 'M', u'育'), + (0x2F983, 'M', u'脃'), + (0x2F984, 'M', u'䐋'), + (0x2F985, 'M', u'脾'), + (0x2F986, 'M', u'媵'), + (0x2F987, 'M', u'𦞧'), + (0x2F988, 'M', u'𦞵'), + (0x2F989, 'M', u'𣎓'), + (0x2F98A, 'M', u'𣎜'), + (0x2F98B, 'M', u'舁'), + (0x2F98C, 'M', u'舄'), + (0x2F98D, 'M', u'辞'), + (0x2F98E, 'M', u'䑫'), + (0x2F98F, 'M', u'芑'), + (0x2F990, 'M', u'芋'), + (0x2F991, 'M', u'芝'), + (0x2F992, 'M', u'劳'), + (0x2F993, 'M', u'花'), + (0x2F994, 'M', u'芳'), + (0x2F995, 'M', u'芽'), + (0x2F996, 'M', u'苦'), + (0x2F997, 'M', u'𦬼'), + (0x2F998, 'M', u'若'), + (0x2F999, 'M', u'茝'), + (0x2F99A, 'M', u'荣'), + (0x2F99B, 'M', u'莭'), + (0x2F99C, 'M', u'茣'), + (0x2F99D, 'M', u'莽'), + (0x2F99E, 'M', u'菧'), + (0x2F99F, 'M', u'著'), + (0x2F9A0, 'M', u'荓'), + (0x2F9A1, 'M', u'菊'), + (0x2F9A2, 'M', u'菌'), + (0x2F9A3, 'M', u'菜'), + (0x2F9A4, 'M', u'𦰶'), + (0x2F9A5, 'M', u'𦵫'), + (0x2F9A6, 'M', u'𦳕'), + (0x2F9A7, 'M', u'䔫'), + (0x2F9A8, 'M', u'蓱'), + (0x2F9A9, 'M', u'蓳'), + (0x2F9AA, 'M', u'蔖'), + (0x2F9AB, 'M', u'𧏊'), + (0x2F9AC, 'M', u'蕤'), + (0x2F9AD, 'M', u'𦼬'), + (0x2F9AE, 'M', u'䕝'), + (0x2F9AF, 'M', u'䕡'), + (0x2F9B0, 'M', u'𦾱'), + (0x2F9B1, 'M', u'𧃒'), + (0x2F9B2, 'M', u'䕫'), + (0x2F9B3, 'M', u'虐'), + (0x2F9B4, 'M', u'虜'), + (0x2F9B5, 'M', u'虧'), + (0x2F9B6, 'M', u'虩'), + (0x2F9B7, 'M', u'蚩'), + (0x2F9B8, 'M', u'蚈'), + (0x2F9B9, 'M', u'蜎'), + (0x2F9BA, 'M', u'蛢'), + (0x2F9BB, 'M', u'蝹'), + (0x2F9BC, 'M', u'蜨'), + (0x2F9BD, 'M', u'蝫'), + (0x2F9BE, 'M', u'螆'), + (0x2F9BF, 'X'), + (0x2F9C0, 'M', u'蟡'), + (0x2F9C1, 'M', u'蠁'), + (0x2F9C2, 'M', u'䗹'), + (0x2F9C3, 'M', u'衠'), + (0x2F9C4, 'M', u'衣'), + (0x2F9C5, 'M', u'𧙧'), + (0x2F9C6, 'M', u'裗'), + (0x2F9C7, 'M', u'裞'), + (0x2F9C8, 'M', u'䘵'), + (0x2F9C9, 'M', u'裺'), + (0x2F9CA, 'M', u'㒻'), + (0x2F9CB, 'M', u'𧢮'), + (0x2F9CC, 'M', u'𧥦'), + (0x2F9CD, 'M', u'䚾'), + (0x2F9CE, 'M', u'䛇'), + (0x2F9CF, 'M', u'誠'), + (0x2F9D0, 'M', u'諭'), + (0x2F9D1, 'M', u'變'), + (0x2F9D2, 'M', u'豕'), + (0x2F9D3, 'M', u'𧲨'), + (0x2F9D4, 'M', u'貫'), + (0x2F9D5, 'M', u'賁'), + (0x2F9D6, 'M', u'贛'), + (0x2F9D7, 'M', u'起'), + (0x2F9D8, 'M', u'𧼯'), + (0x2F9D9, 'M', u'𠠄'), + (0x2F9DA, 'M', u'跋'), + (0x2F9DB, 'M', u'趼'), + (0x2F9DC, 'M', u'跰'), + (0x2F9DD, 'M', u'𠣞'), + (0x2F9DE, 'M', u'軔'), + (0x2F9DF, 'M', u'輸'), + (0x2F9E0, 'M', u'𨗒'), + (0x2F9E1, 'M', u'𨗭'), + (0x2F9E2, 'M', u'邔'), + (0x2F9E3, 'M', u'郱'), + ] + +def _seg_72(): + return [ + (0x2F9E4, 'M', u'鄑'), + (0x2F9E5, 'M', u'𨜮'), + (0x2F9E6, 'M', u'鄛'), + (0x2F9E7, 'M', u'鈸'), + (0x2F9E8, 'M', u'鋗'), + (0x2F9E9, 'M', u'鋘'), + (0x2F9EA, 'M', u'鉼'), + (0x2F9EB, 'M', u'鏹'), + (0x2F9EC, 'M', u'鐕'), + (0x2F9ED, 'M', u'𨯺'), + (0x2F9EE, 'M', u'開'), + (0x2F9EF, 'M', u'䦕'), + (0x2F9F0, 'M', u'閷'), + (0x2F9F1, 'M', u'𨵷'), + (0x2F9F2, 'M', u'䧦'), + (0x2F9F3, 'M', u'雃'), + (0x2F9F4, 'M', u'嶲'), + (0x2F9F5, 'M', u'霣'), + (0x2F9F6, 'M', u'𩅅'), + (0x2F9F7, 'M', u'𩈚'), + (0x2F9F8, 'M', u'䩮'), + (0x2F9F9, 'M', u'䩶'), + (0x2F9FA, 'M', u'韠'), + (0x2F9FB, 'M', u'𩐊'), + (0x2F9FC, 'M', u'䪲'), + (0x2F9FD, 'M', u'𩒖'), + (0x2F9FE, 'M', u'頋'), + (0x2FA00, 'M', u'頩'), + (0x2FA01, 'M', u'𩖶'), + (0x2FA02, 'M', u'飢'), + (0x2FA03, 'M', u'䬳'), + (0x2FA04, 'M', u'餩'), + (0x2FA05, 'M', u'馧'), + (0x2FA06, 'M', u'駂'), + (0x2FA07, 'M', u'駾'), + (0x2FA08, 'M', u'䯎'), + (0x2FA09, 'M', u'𩬰'), + (0x2FA0A, 'M', u'鬒'), + (0x2FA0B, 'M', u'鱀'), + (0x2FA0C, 'M', u'鳽'), + (0x2FA0D, 'M', u'䳎'), + (0x2FA0E, 'M', u'䳭'), + (0x2FA0F, 'M', u'鵧'), + (0x2FA10, 'M', u'𪃎'), + (0x2FA11, 'M', u'䳸'), + (0x2FA12, 'M', u'𪄅'), + (0x2FA13, 'M', u'𪈎'), + (0x2FA14, 'M', u'𪊑'), + (0x2FA15, 'M', u'麻'), + (0x2FA16, 'M', u'䵖'), + (0x2FA17, 'M', u'黹'), + (0x2FA18, 'M', u'黾'), + (0x2FA19, 'M', u'鼅'), + (0x2FA1A, 'M', u'鼏'), + (0x2FA1B, 'M', u'鼖'), + (0x2FA1C, 'M', u'鼻'), + (0x2FA1D, 'M', u'𪘀'), + (0x2FA1E, 'X'), + (0xE0100, 'I'), + (0xE01F0, 'X'), + ] + +uts46data = tuple( + _seg_0() + + _seg_1() + + _seg_2() + + _seg_3() + + _seg_4() + + _seg_5() + + _seg_6() + + _seg_7() + + _seg_8() + + _seg_9() + + _seg_10() + + _seg_11() + + _seg_12() + + _seg_13() + + _seg_14() + + _seg_15() + + _seg_16() + + _seg_17() + + _seg_18() + + _seg_19() + + _seg_20() + + _seg_21() + + _seg_22() + + _seg_23() + + _seg_24() + + _seg_25() + + _seg_26() + + _seg_27() + + _seg_28() + + _seg_29() + + _seg_30() + + _seg_31() + + _seg_32() + + _seg_33() + + _seg_34() + + _seg_35() + + _seg_36() + + _seg_37() + + _seg_38() + + _seg_39() + + _seg_40() + + _seg_41() + + _seg_42() + + _seg_43() + + _seg_44() + + _seg_45() + + _seg_46() + + _seg_47() + + _seg_48() + + _seg_49() + + _seg_50() + + _seg_51() + + _seg_52() + + _seg_53() + + _seg_54() + + _seg_55() + + _seg_56() + + _seg_57() + + _seg_58() + + _seg_59() + + _seg_60() + + _seg_61() + + _seg_62() + + _seg_63() + + _seg_64() + + _seg_65() + + _seg_66() + + _seg_67() + + _seg_68() + + _seg_69() + + _seg_70() + + _seg_71() + + _seg_72() +) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/ipaddress.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/ipaddress.py new file mode 100644 index 0000000..8cfdd58 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/ipaddress.py @@ -0,0 +1,2419 @@ +# Copyright 2007 Google Inc. +# Licensed to PSF under a Contributor Agreement. + +"""A fast, lightweight IPv4/IPv6 manipulation library in Python. + +This library is used to create/poke/manipulate IPv4 and IPv6 addresses +and networks. + +""" + +from __future__ import unicode_literals + + +import itertools +import struct + +__version__ = '1.0.19' + +# Compatibility functions +_compat_int_types = (int,) +try: + _compat_int_types = (int, long) +except NameError: + pass +try: + _compat_str = unicode +except NameError: + _compat_str = str + assert bytes != str +if b'\0'[0] == 0: # Python 3 semantics + def _compat_bytes_to_byte_vals(byt): + return byt +else: + def _compat_bytes_to_byte_vals(byt): + return [struct.unpack(b'!B', b)[0] for b in byt] +try: + _compat_int_from_byte_vals = int.from_bytes +except AttributeError: + def _compat_int_from_byte_vals(bytvals, endianess): + assert endianess == 'big' + res = 0 + for bv in bytvals: + assert isinstance(bv, _compat_int_types) + res = (res << 8) + bv + return res + + +def _compat_to_bytes(intval, length, endianess): + assert isinstance(intval, _compat_int_types) + assert endianess == 'big' + if length == 4: + if intval < 0 or intval >= 2 ** 32: + raise struct.error("integer out of range for 'I' format code") + return struct.pack(b'!I', intval) + elif length == 16: + if intval < 0 or intval >= 2 ** 128: + raise struct.error("integer out of range for 'QQ' format code") + return struct.pack(b'!QQ', intval >> 64, intval & 0xffffffffffffffff) + else: + raise NotImplementedError() + + +if hasattr(int, 'bit_length'): + # Not int.bit_length , since that won't work in 2.7 where long exists + def _compat_bit_length(i): + return i.bit_length() +else: + def _compat_bit_length(i): + for res in itertools.count(): + if i >> res == 0: + return res + + +def _compat_range(start, end, step=1): + assert step > 0 + i = start + while i < end: + yield i + i += step + + +class _TotalOrderingMixin(object): + __slots__ = () + + # Helper that derives the other comparison operations from + # __lt__ and __eq__ + # We avoid functools.total_ordering because it doesn't handle + # NotImplemented correctly yet (http://bugs.python.org/issue10042) + def __eq__(self, other): + raise NotImplementedError + + def __ne__(self, other): + equal = self.__eq__(other) + if equal is NotImplemented: + return NotImplemented + return not equal + + def __lt__(self, other): + raise NotImplementedError + + def __le__(self, other): + less = self.__lt__(other) + if less is NotImplemented or not less: + return self.__eq__(other) + return less + + def __gt__(self, other): + less = self.__lt__(other) + if less is NotImplemented: + return NotImplemented + equal = self.__eq__(other) + if equal is NotImplemented: + return NotImplemented + return not (less or equal) + + def __ge__(self, other): + less = self.__lt__(other) + if less is NotImplemented: + return NotImplemented + return not less + + +IPV4LENGTH = 32 +IPV6LENGTH = 128 + + +class AddressValueError(ValueError): + """A Value Error related to the address.""" + + +class NetmaskValueError(ValueError): + """A Value Error related to the netmask.""" + + +def ip_address(address): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Address or IPv6Address object. + + Raises: + ValueError: if the *address* passed isn't either a v4 or a v6 + address + + """ + try: + return IPv4Address(address) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Address(address) + except (AddressValueError, NetmaskValueError): + pass + + if isinstance(address, bytes): + raise AddressValueError( + '%r does not appear to be an IPv4 or IPv6 address. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?' % address) + + raise ValueError('%r does not appear to be an IPv4 or IPv6 address' % + address) + + +def ip_network(address, strict=True): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP network. Either IPv4 or + IPv6 networks may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Network or IPv6Network object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. Or if the network has host bits set. + + """ + try: + return IPv4Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + if isinstance(address, bytes): + raise AddressValueError( + '%r does not appear to be an IPv4 or IPv6 network. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?' % address) + + raise ValueError('%r does not appear to be an IPv4 or IPv6 network' % + address) + + +def ip_interface(address): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Interface or IPv6Interface object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. + + Notes: + The IPv?Interface classes describe an Address on a particular + Network, so they're basically a combination of both the Address + and Network classes. + + """ + try: + return IPv4Interface(address) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Interface(address) + except (AddressValueError, NetmaskValueError): + pass + + raise ValueError('%r does not appear to be an IPv4 or IPv6 interface' % + address) + + +def v4_int_to_packed(address): + """Represent an address as 4 packed bytes in network (big-endian) order. + + Args: + address: An integer representation of an IPv4 IP address. + + Returns: + The integer address packed as 4 bytes in network (big-endian) order. + + Raises: + ValueError: If the integer is negative or too large to be an + IPv4 IP address. + + """ + try: + return _compat_to_bytes(address, 4, 'big') + except (struct.error, OverflowError): + raise ValueError("Address negative or too large for IPv4") + + +def v6_int_to_packed(address): + """Represent an address as 16 packed bytes in network (big-endian) order. + + Args: + address: An integer representation of an IPv6 IP address. + + Returns: + The integer address packed as 16 bytes in network (big-endian) order. + + """ + try: + return _compat_to_bytes(address, 16, 'big') + except (struct.error, OverflowError): + raise ValueError("Address negative or too large for IPv6") + + +def _split_optional_netmask(address): + """Helper to split the netmask and raise AddressValueError if needed""" + addr = _compat_str(address).split('/') + if len(addr) > 2: + raise AddressValueError("Only one '/' permitted in %r" % address) + return addr + + +def _find_address_range(addresses): + """Find a sequence of sorted deduplicated IPv#Address. + + Args: + addresses: a list of IPv#Address objects. + + Yields: + A tuple containing the first and last IP addresses in the sequence. + + """ + it = iter(addresses) + first = last = next(it) + for ip in it: + if ip._ip != last._ip + 1: + yield first, last + first = ip + last = ip + yield first, last + + +def _count_righthand_zero_bits(number, bits): + """Count the number of zero bits on the right hand side. + + Args: + number: an integer. + bits: maximum number of bits to count. + + Returns: + The number of zero bits on the right hand side of the number. + + """ + if number == 0: + return bits + return min(bits, _compat_bit_length(~number & (number - 1))) + + +def summarize_address_range(first, last): + """Summarize a network range given the first and last IP addresses. + + Example: + >>> list(summarize_address_range(IPv4Address('192.0.2.0'), + ... IPv4Address('192.0.2.130'))) + ... #doctest: +NORMALIZE_WHITESPACE + [IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/31'), + IPv4Network('192.0.2.130/32')] + + Args: + first: the first IPv4Address or IPv6Address in the range. + last: the last IPv4Address or IPv6Address in the range. + + Returns: + An iterator of the summarized IPv(4|6) network objects. + + Raise: + TypeError: + If the first and last objects are not IP addresses. + If the first and last objects are not the same version. + ValueError: + If the last object is not greater than the first. + If the version of the first address is not 4 or 6. + + """ + if (not (isinstance(first, _BaseAddress) and + isinstance(last, _BaseAddress))): + raise TypeError('first and last must be IP addresses, not networks') + if first.version != last.version: + raise TypeError("%s and %s are not of the same version" % ( + first, last)) + if first > last: + raise ValueError('last IP address must be greater than first') + + if first.version == 4: + ip = IPv4Network + elif first.version == 6: + ip = IPv6Network + else: + raise ValueError('unknown IP version') + + ip_bits = first._max_prefixlen + first_int = first._ip + last_int = last._ip + while first_int <= last_int: + nbits = min(_count_righthand_zero_bits(first_int, ip_bits), + _compat_bit_length(last_int - first_int + 1) - 1) + net = ip((first_int, ip_bits - nbits)) + yield net + first_int += 1 << nbits + if first_int - 1 == ip._ALL_ONES: + break + + +def _collapse_addresses_internal(addresses): + """Loops through the addresses, collapsing concurrent netblocks. + + Example: + + ip1 = IPv4Network('192.0.2.0/26') + ip2 = IPv4Network('192.0.2.64/26') + ip3 = IPv4Network('192.0.2.128/26') + ip4 = IPv4Network('192.0.2.192/26') + + _collapse_addresses_internal([ip1, ip2, ip3, ip4]) -> + [IPv4Network('192.0.2.0/24')] + + This shouldn't be called directly; it is called via + collapse_addresses([]). + + Args: + addresses: A list of IPv4Network's or IPv6Network's + + Returns: + A list of IPv4Network's or IPv6Network's depending on what we were + passed. + + """ + # First merge + to_merge = list(addresses) + subnets = {} + while to_merge: + net = to_merge.pop() + supernet = net.supernet() + existing = subnets.get(supernet) + if existing is None: + subnets[supernet] = net + elif existing != net: + # Merge consecutive subnets + del subnets[supernet] + to_merge.append(supernet) + # Then iterate over resulting networks, skipping subsumed subnets + last = None + for net in sorted(subnets.values()): + if last is not None: + # Since they are sorted, + # last.network_address <= net.network_address is a given. + if last.broadcast_address >= net.broadcast_address: + continue + yield net + last = net + + +def collapse_addresses(addresses): + """Collapse a list of IP objects. + + Example: + collapse_addresses([IPv4Network('192.0.2.0/25'), + IPv4Network('192.0.2.128/25')]) -> + [IPv4Network('192.0.2.0/24')] + + Args: + addresses: An iterator of IPv4Network or IPv6Network objects. + + Returns: + An iterator of the collapsed IPv(4|6)Network objects. + + Raises: + TypeError: If passed a list of mixed version objects. + + """ + addrs = [] + ips = [] + nets = [] + + # split IP addresses and networks + for ip in addresses: + if isinstance(ip, _BaseAddress): + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, ips[-1])) + ips.append(ip) + elif ip._prefixlen == ip._max_prefixlen: + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, ips[-1])) + try: + ips.append(ip.ip) + except AttributeError: + ips.append(ip.network_address) + else: + if nets and nets[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, nets[-1])) + nets.append(ip) + + # sort and dedup + ips = sorted(set(ips)) + + # find consecutive address ranges in the sorted sequence and summarize them + if ips: + for first, last in _find_address_range(ips): + addrs.extend(summarize_address_range(first, last)) + + return _collapse_addresses_internal(addrs + nets) + + +def get_mixed_type_key(obj): + """Return a key suitable for sorting between networks and addresses. + + Address and Network objects are not sortable by default; they're + fundamentally different so the expression + + IPv4Address('192.0.2.0') <= IPv4Network('192.0.2.0/24') + + doesn't make any sense. There are some times however, where you may wish + to have ipaddress sort these for you anyway. If you need to do this, you + can use this function as the key= argument to sorted(). + + Args: + obj: either a Network or Address object. + Returns: + appropriate key. + + """ + if isinstance(obj, _BaseNetwork): + return obj._get_networks_key() + elif isinstance(obj, _BaseAddress): + return obj._get_address_key() + return NotImplemented + + +class _IPAddressBase(_TotalOrderingMixin): + + """The mother class.""" + + __slots__ = () + + @property + def exploded(self): + """Return the longhand version of the IP address as a string.""" + return self._explode_shorthand_ip_string() + + @property + def compressed(self): + """Return the shorthand version of the IP address as a string.""" + return _compat_str(self) + + @property + def reverse_pointer(self): + """The name of the reverse DNS pointer for the IP address, e.g.: + >>> ipaddress.ip_address("127.0.0.1").reverse_pointer + '1.0.0.127.in-addr.arpa' + >>> ipaddress.ip_address("2001:db8::1").reverse_pointer + '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa' + + """ + return self._reverse_pointer() + + @property + def version(self): + msg = '%200s has no version specified' % (type(self),) + raise NotImplementedError(msg) + + def _check_int_address(self, address): + if address < 0: + msg = "%d (< 0) is not permitted as an IPv%d address" + raise AddressValueError(msg % (address, self._version)) + if address > self._ALL_ONES: + msg = "%d (>= 2**%d) is not permitted as an IPv%d address" + raise AddressValueError(msg % (address, self._max_prefixlen, + self._version)) + + def _check_packed_address(self, address, expected_len): + address_len = len(address) + if address_len != expected_len: + msg = ( + '%r (len %d != %d) is not permitted as an IPv%d address. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?') + raise AddressValueError(msg % (address, address_len, + expected_len, self._version)) + + @classmethod + def _ip_int_from_prefix(cls, prefixlen): + """Turn the prefix length into a bitwise netmask + + Args: + prefixlen: An integer, the prefix length. + + Returns: + An integer. + + """ + return cls._ALL_ONES ^ (cls._ALL_ONES >> prefixlen) + + @classmethod + def _prefix_from_ip_int(cls, ip_int): + """Return prefix length from the bitwise netmask. + + Args: + ip_int: An integer, the netmask in expanded bitwise format + + Returns: + An integer, the prefix length. + + Raises: + ValueError: If the input intermingles zeroes & ones + """ + trailing_zeroes = _count_righthand_zero_bits(ip_int, + cls._max_prefixlen) + prefixlen = cls._max_prefixlen - trailing_zeroes + leading_ones = ip_int >> trailing_zeroes + all_ones = (1 << prefixlen) - 1 + if leading_ones != all_ones: + byteslen = cls._max_prefixlen // 8 + details = _compat_to_bytes(ip_int, byteslen, 'big') + msg = 'Netmask pattern %r mixes zeroes & ones' + raise ValueError(msg % details) + return prefixlen + + @classmethod + def _report_invalid_netmask(cls, netmask_str): + msg = '%r is not a valid netmask' % netmask_str + raise NetmaskValueError(msg) + + @classmethod + def _prefix_from_prefix_string(cls, prefixlen_str): + """Return prefix length from a numeric string + + Args: + prefixlen_str: The string to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask + """ + # int allows a leading +/- as well as surrounding whitespace, + # so we ensure that isn't the case + if not _BaseV4._DECIMAL_DIGITS.issuperset(prefixlen_str): + cls._report_invalid_netmask(prefixlen_str) + try: + prefixlen = int(prefixlen_str) + except ValueError: + cls._report_invalid_netmask(prefixlen_str) + if not (0 <= prefixlen <= cls._max_prefixlen): + cls._report_invalid_netmask(prefixlen_str) + return prefixlen + + @classmethod + def _prefix_from_ip_string(cls, ip_str): + """Turn a netmask/hostmask string into a prefix length + + Args: + ip_str: The netmask/hostmask to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask/hostmask + """ + # Parse the netmask/hostmask like an IP address. + try: + ip_int = cls._ip_int_from_string(ip_str) + except AddressValueError: + cls._report_invalid_netmask(ip_str) + + # Try matching a netmask (this would be /1*0*/ as a bitwise regexp). + # Note that the two ambiguous cases (all-ones and all-zeroes) are + # treated as netmasks. + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + pass + + # Invert the bits, and try matching a /0+1+/ hostmask instead. + ip_int ^= cls._ALL_ONES + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + cls._report_invalid_netmask(ip_str) + + def __reduce__(self): + return self.__class__, (_compat_str(self),) + + +class _BaseAddress(_IPAddressBase): + + """A generic IP object. + + This IP class contains the version independent methods which are + used by single IP addresses. + """ + + __slots__ = () + + def __int__(self): + return self._ip + + def __eq__(self, other): + try: + return (self._ip == other._ip and + self._version == other._version) + except AttributeError: + return NotImplemented + + def __lt__(self, other): + if not isinstance(other, _IPAddressBase): + return NotImplemented + if not isinstance(other, _BaseAddress): + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + self, other)) + if self._ip != other._ip: + return self._ip < other._ip + return False + + # Shorthand for Integer addition and subtraction. This is not + # meant to ever support addition/subtraction of addresses. + def __add__(self, other): + if not isinstance(other, _compat_int_types): + return NotImplemented + return self.__class__(int(self) + other) + + def __sub__(self, other): + if not isinstance(other, _compat_int_types): + return NotImplemented + return self.__class__(int(self) - other) + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) + + def __str__(self): + return _compat_str(self._string_from_ip_int(self._ip)) + + def __hash__(self): + return hash(hex(int(self._ip))) + + def _get_address_key(self): + return (self._version, self) + + def __reduce__(self): + return self.__class__, (self._ip,) + + +class _BaseNetwork(_IPAddressBase): + + """A generic IP network object. + + This IP class contains the version independent methods which are + used by networks. + + """ + def __init__(self, address): + self._cache = {} + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) + + def __str__(self): + return '%s/%d' % (self.network_address, self.prefixlen) + + def hosts(self): + """Generate Iterator over usable hosts in a network. + + This is like __iter__ except it doesn't return the network + or broadcast addresses. + + """ + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network + 1, broadcast): + yield self._address_class(x) + + def __iter__(self): + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network, broadcast + 1): + yield self._address_class(x) + + def __getitem__(self, n): + network = int(self.network_address) + broadcast = int(self.broadcast_address) + if n >= 0: + if network + n > broadcast: + raise IndexError('address out of range') + return self._address_class(network + n) + else: + n += 1 + if broadcast + n < network: + raise IndexError('address out of range') + return self._address_class(broadcast + n) + + def __lt__(self, other): + if not isinstance(other, _IPAddressBase): + return NotImplemented + if not isinstance(other, _BaseNetwork): + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + self, other)) + if self.network_address != other.network_address: + return self.network_address < other.network_address + if self.netmask != other.netmask: + return self.netmask < other.netmask + return False + + def __eq__(self, other): + try: + return (self._version == other._version and + self.network_address == other.network_address and + int(self.netmask) == int(other.netmask)) + except AttributeError: + return NotImplemented + + def __hash__(self): + return hash(int(self.network_address) ^ int(self.netmask)) + + def __contains__(self, other): + # always false if one is v4 and the other is v6. + if self._version != other._version: + return False + # dealing with another network. + if isinstance(other, _BaseNetwork): + return False + # dealing with another address + else: + # address + return (int(self.network_address) <= int(other._ip) <= + int(self.broadcast_address)) + + def overlaps(self, other): + """Tell if self is partly contained in other.""" + return self.network_address in other or ( + self.broadcast_address in other or ( + other.network_address in self or ( + other.broadcast_address in self))) + + @property + def broadcast_address(self): + x = self._cache.get('broadcast_address') + if x is None: + x = self._address_class(int(self.network_address) | + int(self.hostmask)) + self._cache['broadcast_address'] = x + return x + + @property + def hostmask(self): + x = self._cache.get('hostmask') + if x is None: + x = self._address_class(int(self.netmask) ^ self._ALL_ONES) + self._cache['hostmask'] = x + return x + + @property + def with_prefixlen(self): + return '%s/%d' % (self.network_address, self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self.network_address, self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self.network_address, self.hostmask) + + @property + def num_addresses(self): + """Number of hosts in the current subnet.""" + return int(self.broadcast_address) - int(self.network_address) + 1 + + @property + def _address_class(self): + # Returning bare address objects (rather than interfaces) allows for + # more consistent behaviour across the network address, broadcast + # address and individual host addresses. + msg = '%200s has no associated address class' % (type(self),) + raise NotImplementedError(msg) + + @property + def prefixlen(self): + return self._prefixlen + + def address_exclude(self, other): + """Remove an address from a larger block. + + For example: + + addr1 = ip_network('192.0.2.0/28') + addr2 = ip_network('192.0.2.1/32') + list(addr1.address_exclude(addr2)) = + [IPv4Network('192.0.2.0/32'), IPv4Network('192.0.2.2/31'), + IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')] + + or IPv6: + + addr1 = ip_network('2001:db8::1/32') + addr2 = ip_network('2001:db8::1/128') + list(addr1.address_exclude(addr2)) = + [ip_network('2001:db8::1/128'), + ip_network('2001:db8::2/127'), + ip_network('2001:db8::4/126'), + ip_network('2001:db8::8/125'), + ... + ip_network('2001:db8:8000::/33')] + + Args: + other: An IPv4Network or IPv6Network object of the same type. + + Returns: + An iterator of the IPv(4|6)Network objects which is self + minus other. + + Raises: + TypeError: If self and other are of differing address + versions, or if other is not a network object. + ValueError: If other is not completely contained by self. + + """ + if not self._version == other._version: + raise TypeError("%s and %s are not of the same version" % ( + self, other)) + + if not isinstance(other, _BaseNetwork): + raise TypeError("%s is not a network object" % other) + + if not other.subnet_of(self): + raise ValueError('%s not contained in %s' % (other, self)) + if other == self: + return + + # Make sure we're comparing the network of other. + other = other.__class__('%s/%s' % (other.network_address, + other.prefixlen)) + + s1, s2 = self.subnets() + while s1 != other and s2 != other: + if other.subnet_of(s1): + yield s2 + s1, s2 = s1.subnets() + elif other.subnet_of(s2): + yield s1 + s1, s2 = s2.subnets() + else: + # If we got here, there's a bug somewhere. + raise AssertionError('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (s1, s2, other)) + if s1 == other: + yield s2 + elif s2 == other: + yield s1 + else: + # If we got here, there's a bug somewhere. + raise AssertionError('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (s1, s2, other)) + + def compare_networks(self, other): + """Compare two IP objects. + + This is only concerned about the comparison of the integer + representation of the network addresses. This means that the + host bits aren't considered at all in this method. If you want + to compare host bits, you can easily enough do a + 'HostA._ip < HostB._ip' + + Args: + other: An IP object. + + Returns: + If the IP versions of self and other are the same, returns: + + -1 if self < other: + eg: IPv4Network('192.0.2.0/25') < IPv4Network('192.0.2.128/25') + IPv6Network('2001:db8::1000/124') < + IPv6Network('2001:db8::2000/124') + 0 if self == other + eg: IPv4Network('192.0.2.0/24') == IPv4Network('192.0.2.0/24') + IPv6Network('2001:db8::1000/124') == + IPv6Network('2001:db8::1000/124') + 1 if self > other + eg: IPv4Network('192.0.2.128/25') > IPv4Network('192.0.2.0/25') + IPv6Network('2001:db8::2000/124') > + IPv6Network('2001:db8::1000/124') + + Raises: + TypeError if the IP versions are different. + + """ + # does this need to raise a ValueError? + if self._version != other._version: + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + # self._version == other._version below here: + if self.network_address < other.network_address: + return -1 + if self.network_address > other.network_address: + return 1 + # self.network_address == other.network_address below here: + if self.netmask < other.netmask: + return -1 + if self.netmask > other.netmask: + return 1 + return 0 + + def _get_networks_key(self): + """Network-only key function. + + Returns an object that identifies this address' network and + netmask. This function is a suitable "key" argument for sorted() + and list.sort(). + + """ + return (self._version, self.network_address, self.netmask) + + def subnets(self, prefixlen_diff=1, new_prefix=None): + """The subnets which join to make the current subnet. + + In the case that self contains only one IP + (self._prefixlen == 32 for IPv4 or self._prefixlen == 128 + for IPv6), yield an iterator with just ourself. + + Args: + prefixlen_diff: An integer, the amount the prefix length + should be increased by. This should not be set if + new_prefix is also set. + new_prefix: The desired new prefix length. This must be a + larger number (smaller prefix) than the existing prefix. + This should not be set if prefixlen_diff is also set. + + Returns: + An iterator of IPv(4|6) objects. + + Raises: + ValueError: The prefixlen_diff is too small or too large. + OR + prefixlen_diff and new_prefix are both set or new_prefix + is a smaller number than the current prefix (smaller + number means a larger network) + + """ + if self._prefixlen == self._max_prefixlen: + yield self + return + + if new_prefix is not None: + if new_prefix < self._prefixlen: + raise ValueError('new prefix must be longer') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = new_prefix - self._prefixlen + + if prefixlen_diff < 0: + raise ValueError('prefix length diff must be > 0') + new_prefixlen = self._prefixlen + prefixlen_diff + + if new_prefixlen > self._max_prefixlen: + raise ValueError( + 'prefix length diff %d is invalid for netblock %s' % ( + new_prefixlen, self)) + + start = int(self.network_address) + end = int(self.broadcast_address) + 1 + step = (int(self.hostmask) + 1) >> prefixlen_diff + for new_addr in _compat_range(start, end, step): + current = self.__class__((new_addr, new_prefixlen)) + yield current + + def supernet(self, prefixlen_diff=1, new_prefix=None): + """The supernet containing the current network. + + Args: + prefixlen_diff: An integer, the amount the prefix length of + the network should be decreased by. For example, given a + /24 network and a prefixlen_diff of 3, a supernet with a + /21 netmask is returned. + + Returns: + An IPv4 network object. + + Raises: + ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have + a negative prefix length. + OR + If prefixlen_diff and new_prefix are both set or new_prefix is a + larger number than the current prefix (larger number means a + smaller network) + + """ + if self._prefixlen == 0: + return self + + if new_prefix is not None: + if new_prefix > self._prefixlen: + raise ValueError('new prefix must be shorter') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = self._prefixlen - new_prefix + + new_prefixlen = self.prefixlen - prefixlen_diff + if new_prefixlen < 0: + raise ValueError( + 'current prefixlen is %d, cannot have a prefixlen_diff of %d' % + (self.prefixlen, prefixlen_diff)) + return self.__class__(( + int(self.network_address) & (int(self.netmask) << prefixlen_diff), + new_prefixlen)) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is a multicast address. + See RFC 2373 2.7 for details. + + """ + return (self.network_address.is_multicast and + self.broadcast_address.is_multicast) + + @staticmethod + def _is_subnet_of(a, b): + try: + # Always false if one is v4 and the other is v6. + if a._version != b._version: + raise TypeError("%s and %s are not of the same version" (a, b)) + return (b.network_address <= a.network_address and + b.broadcast_address >= a.broadcast_address) + except AttributeError: + raise TypeError("Unable to test subnet containment " + "between %s and %s" % (a, b)) + + def subnet_of(self, other): + """Return True if this network is a subnet of other.""" + return self._is_subnet_of(self, other) + + def supernet_of(self, other): + """Return True if this network is a supernet of other.""" + return self._is_subnet_of(other, self) + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within one of the + reserved IPv6 Network ranges. + + """ + return (self.network_address.is_reserved and + self.broadcast_address.is_reserved) + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is reserved per RFC 4291. + + """ + return (self.network_address.is_link_local and + self.broadcast_address.is_link_local) + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv4-special-registry or iana-ipv6-special-registry. + + """ + return (self.network_address.is_private and + self.broadcast_address.is_private) + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, True if the address is not reserved per + iana-ipv4-special-registry or iana-ipv6-special-registry. + + """ + return not self.is_private + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 2373 2.5.2. + + """ + return (self.network_address.is_unspecified and + self.broadcast_address.is_unspecified) + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback address as defined in + RFC 2373 2.5.3. + + """ + return (self.network_address.is_loopback and + self.broadcast_address.is_loopback) + + +class _BaseV4(object): + + """Base IPv4 object. + + The following methods are used by IPv4 objects in both single IP + addresses and networks. + + """ + + __slots__ = () + _version = 4 + # Equivalent to 255.255.255.255 or 32 bits of 1's. + _ALL_ONES = (2 ** IPV4LENGTH) - 1 + _DECIMAL_DIGITS = frozenset('0123456789') + + # the valid octets for host and netmasks. only useful for IPv4. + _valid_mask_octets = frozenset([255, 254, 252, 248, 240, 224, 192, 128, 0]) + + _max_prefixlen = IPV4LENGTH + # There are only a handful of valid v4 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} + + def _explode_shorthand_ip_string(self): + return _compat_str(self) + + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, _compat_int_types): + prefixlen = arg + else: + try: + # Check for a netmask in prefix length form + prefixlen = cls._prefix_from_prefix_string(arg) + except NetmaskValueError: + # Check for a netmask or hostmask in dotted-quad form. + # This may raise NetmaskValueError. + prefixlen = cls._prefix_from_ip_string(arg) + netmask = IPv4Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): + """Turn the given IP string into an integer for comparison. + + Args: + ip_str: A string, the IP ip_str. + + Returns: + The IP ip_str as an integer. + + Raises: + AddressValueError: if ip_str isn't a valid IPv4 Address. + + """ + if not ip_str: + raise AddressValueError('Address cannot be empty') + + octets = ip_str.split('.') + if len(octets) != 4: + raise AddressValueError("Expected 4 octets in %r" % ip_str) + + try: + return _compat_int_from_byte_vals( + map(cls._parse_octet, octets), 'big') + except ValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + + @classmethod + def _parse_octet(cls, octet_str): + """Convert a decimal octet into an integer. + + Args: + octet_str: A string, the number to parse. + + Returns: + The octet as an integer. + + Raises: + ValueError: if the octet isn't strictly a decimal from [0..255]. + + """ + if not octet_str: + raise ValueError("Empty octet not permitted") + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not cls._DECIMAL_DIGITS.issuperset(octet_str): + msg = "Only decimal digits permitted in %r" + raise ValueError(msg % octet_str) + # We do the length check second, since the invalid character error + # is likely to be more informative for the user + if len(octet_str) > 3: + msg = "At most 3 characters permitted in %r" + raise ValueError(msg % octet_str) + # Convert to integer (we know digits are legal) + octet_int = int(octet_str, 10) + # Any octets that look like they *might* be written in octal, + # and which don't look exactly the same in both octal and + # decimal are rejected as ambiguous + if octet_int > 7 and octet_str[0] == '0': + msg = "Ambiguous (octal/decimal) value in %r not permitted" + raise ValueError(msg % octet_str) + if octet_int > 255: + raise ValueError("Octet %d (> 255) not permitted" % octet_int) + return octet_int + + @classmethod + def _string_from_ip_int(cls, ip_int): + """Turns a 32-bit integer into dotted decimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + The IP address as a string in dotted decimal notation. + + """ + return '.'.join(_compat_str(struct.unpack(b'!B', b)[0] + if isinstance(b, bytes) + else b) + for b in _compat_to_bytes(ip_int, 4, 'big')) + + def _is_hostmask(self, ip_str): + """Test if the IP string is a hostmask (rather than a netmask). + + Args: + ip_str: A string, the potential hostmask. + + Returns: + A boolean, True if the IP string is a hostmask. + + """ + bits = ip_str.split('.') + try: + parts = [x for x in map(int, bits) if x in self._valid_mask_octets] + except ValueError: + return False + if len(parts) != len(bits): + return False + if parts[0] < parts[-1]: + return True + return False + + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv4 address. + + This implements the method described in RFC1035 3.5. + + """ + reverse_octets = _compat_str(self).split('.')[::-1] + return '.'.join(reverse_octets) + '.in-addr.arpa' + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def version(self): + return self._version + + +class IPv4Address(_BaseV4, _BaseAddress): + + """Represent and manipulate single IPv4 Addresses.""" + + __slots__ = ('_ip', '__weakref__') + + def __init__(self, address): + + """ + Args: + address: A string or integer representing the IP + + Additionally, an integer can be passed, so + IPv4Address('192.0.2.1') == IPv4Address(3221225985). + or, more generally + IPv4Address(int(IPv4Address('192.0.2.1'))) == + IPv4Address('192.0.2.1') + + Raises: + AddressValueError: If ipaddress isn't a valid IPv4 address. + + """ + # Efficient constructor from integer. + if isinstance(address, _compat_int_types): + self._check_int_address(address) + self._ip = address + return + + # Constructing from a packed address + if isinstance(address, bytes): + self._check_packed_address(address, 4) + bvs = _compat_bytes_to_byte_vals(address) + self._ip = _compat_int_from_byte_vals(bvs, 'big') + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = _compat_str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) + self._ip = self._ip_int_from_string(addr_str) + + @property + def packed(self): + """The binary representation of this address.""" + return v4_int_to_packed(self._ip) + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within the + reserved IPv4 Network range. + + """ + return self in self._constants._reserved_network + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv4-special-registry. + + """ + return any(self in net for net in self._constants._private_networks) + + @property + def is_global(self): + return ( + self not in self._constants._public_network and + not self.is_private) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is multicast. + See RFC 3171 for details. + + """ + return self in self._constants._multicast_network + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 5735 3. + + """ + return self == self._constants._unspecified_address + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback per RFC 3330. + + """ + return self in self._constants._loopback_network + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is link-local per RFC 3927. + + """ + return self in self._constants._linklocal_network + + +class IPv4Interface(IPv4Address): + + def __init__(self, address): + if isinstance(address, (bytes, _compat_int_types)): + IPv4Address.__init__(self, address) + self.network = IPv4Network(self._ip) + self._prefixlen = self._max_prefixlen + return + + if isinstance(address, tuple): + IPv4Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + + self.network = IPv4Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + + addr = _split_optional_netmask(address) + IPv4Address.__init__(self, addr[0]) + + self.network = IPv4Network(address, strict=False) + self._prefixlen = self.network._prefixlen + + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + + def __str__(self): + return '%s/%d' % (self._string_from_ip_int(self._ip), + self.network.prefixlen) + + def __eq__(self, other): + address_equal = IPv4Address.__eq__(self, other) + if not address_equal or address_equal is NotImplemented: + return address_equal + try: + return self.network == other.network + except AttributeError: + # An interface with an associated network is NOT the + # same as an unassociated address. That's why the hash + # takes the extra info into account. + return False + + def __lt__(self, other): + address_less = IPv4Address.__lt__(self, other) + if address_less is NotImplemented: + return NotImplemented + try: + return (self.network < other.network or + self.network == other.network and address_less) + except AttributeError: + # We *do* allow addresses and interfaces to be sorted. The + # unassociated address is considered less than all interfaces. + return False + + def __hash__(self): + return self._ip ^ self._prefixlen ^ int(self.network.network_address) + + __reduce__ = _IPAddressBase.__reduce__ + + @property + def ip(self): + return IPv4Address(self._ip) + + @property + def with_prefixlen(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.hostmask) + + +class IPv4Network(_BaseV4, _BaseNetwork): + + """This class represents and manipulates 32-bit IPv4 network + addresses.. + + Attributes: [examples for IPv4Network('192.0.2.0/27')] + .network_address: IPv4Address('192.0.2.0') + .hostmask: IPv4Address('0.0.0.31') + .broadcast_address: IPv4Address('192.0.2.32') + .netmask: IPv4Address('255.255.255.224') + .prefixlen: 27 + + """ + # Class to use when creating address objects + _address_class = IPv4Address + + def __init__(self, address, strict=True): + + """Instantiate a new IPv4 network object. + + Args: + address: A string or integer representing the IP [& network]. + '192.0.2.0/24' + '192.0.2.0/255.255.255.0' + '192.0.0.2/0.0.0.255' + are all functionally the same in IPv4. Similarly, + '192.0.2.1' + '192.0.2.1/255.255.255.255' + '192.0.2.1/32' + are also functionally equivalent. That is to say, failing to + provide a subnetmask will create an object with a mask of /32. + + If the mask (portion after the / in the argument) is given in + dotted quad form, it is treated as a netmask if it starts with a + non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it + starts with a zero field (e.g. 0.255.255.255 == /8), with the + single exception of an all-zero mask which is treated as a + netmask == /0. If no mask is given, a default of /32 is used. + + Additionally, an integer can be passed, so + IPv4Network('192.0.2.1') == IPv4Network(3221225985) + or, more generally + IPv4Interface(int(IPv4Interface('192.0.2.1'))) == + IPv4Interface('192.0.2.1') + + Raises: + AddressValueError: If ipaddress isn't a valid IPv4 address. + NetmaskValueError: If the netmask isn't valid for + an IPv4 address. + ValueError: If strict is True and a network address is not + supplied. + + """ + _BaseNetwork.__init__(self, address) + + # Constructing from a packed address or integer + if isinstance(address, (_compat_int_types, bytes)): + self.network_address = IPv4Address(address) + self.netmask, self._prefixlen = self._make_netmask( + self._max_prefixlen) + # fixme: address/network test here. + return + + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + # We weren't given an address[1] + arg = self._max_prefixlen + self.network_address = IPv4Address(address[0]) + self.netmask, self._prefixlen = self._make_netmask(arg) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv4Address(packed & + int(self.netmask)) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = _split_optional_netmask(address) + self.network_address = IPv4Address(self._ip_int_from_string(addr[0])) + + if len(addr) == 2: + arg = addr[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + + if strict: + if (IPv4Address(int(self.network_address) & int(self.netmask)) != + self.network_address): + raise ValueError('%s has host bits set' % self) + self.network_address = IPv4Address(int(self.network_address) & + int(self.netmask)) + + if self._prefixlen == (self._max_prefixlen - 1): + self.hosts = self.__iter__ + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, True if the address is not reserved per + iana-ipv4-special-registry. + + """ + return (not (self.network_address in IPv4Network('100.64.0.0/10') and + self.broadcast_address in IPv4Network('100.64.0.0/10')) and + not self.is_private) + + +class _IPv4Constants(object): + + _linklocal_network = IPv4Network('169.254.0.0/16') + + _loopback_network = IPv4Network('127.0.0.0/8') + + _multicast_network = IPv4Network('224.0.0.0/4') + + _public_network = IPv4Network('100.64.0.0/10') + + _private_networks = [ + IPv4Network('0.0.0.0/8'), + IPv4Network('10.0.0.0/8'), + IPv4Network('127.0.0.0/8'), + IPv4Network('169.254.0.0/16'), + IPv4Network('172.16.0.0/12'), + IPv4Network('192.0.0.0/29'), + IPv4Network('192.0.0.170/31'), + IPv4Network('192.0.2.0/24'), + IPv4Network('192.168.0.0/16'), + IPv4Network('198.18.0.0/15'), + IPv4Network('198.51.100.0/24'), + IPv4Network('203.0.113.0/24'), + IPv4Network('240.0.0.0/4'), + IPv4Network('255.255.255.255/32'), + ] + + _reserved_network = IPv4Network('240.0.0.0/4') + + _unspecified_address = IPv4Address('0.0.0.0') + + +IPv4Address._constants = _IPv4Constants + + +class _BaseV6(object): + + """Base IPv6 object. + + The following methods are used by IPv6 objects in both single IP + addresses and networks. + + """ + + __slots__ = () + _version = 6 + _ALL_ONES = (2 ** IPV6LENGTH) - 1 + _HEXTET_COUNT = 8 + _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef') + _max_prefixlen = IPV6LENGTH + + # There are only a bunch of valid v6 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} + + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, _compat_int_types): + prefixlen = arg + else: + prefixlen = cls._prefix_from_prefix_string(arg) + netmask = IPv6Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): + """Turn an IPv6 ip_str into an integer. + + Args: + ip_str: A string, the IPv6 ip_str. + + Returns: + An int, the IPv6 address + + Raises: + AddressValueError: if ip_str isn't a valid IPv6 Address. + + """ + if not ip_str: + raise AddressValueError('Address cannot be empty') + + parts = ip_str.split(':') + + # An IPv6 address needs at least 2 colons (3 parts). + _min_parts = 3 + if len(parts) < _min_parts: + msg = "At least %d parts expected in %r" % (_min_parts, ip_str) + raise AddressValueError(msg) + + # If the address has an IPv4-style suffix, convert it to hexadecimal. + if '.' in parts[-1]: + try: + ipv4_int = IPv4Address(parts.pop())._ip + except AddressValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF)) + parts.append('%x' % (ipv4_int & 0xFFFF)) + + # An IPv6 address can't have more than 8 colons (9 parts). + # The extra colon comes from using the "::" notation for a single + # leading or trailing zero part. + _max_parts = cls._HEXTET_COUNT + 1 + if len(parts) > _max_parts: + msg = "At most %d colons permitted in %r" % ( + _max_parts - 1, ip_str) + raise AddressValueError(msg) + + # Disregarding the endpoints, find '::' with nothing in between. + # This indicates that a run of zeroes has been skipped. + skip_index = None + for i in _compat_range(1, len(parts) - 1): + if not parts[i]: + if skip_index is not None: + # Can't have more than one '::' + msg = "At most one '::' permitted in %r" % ip_str + raise AddressValueError(msg) + skip_index = i + + # parts_hi is the number of parts to copy from above/before the '::' + # parts_lo is the number of parts to copy from below/after the '::' + if skip_index is not None: + # If we found a '::', then check if it also covers the endpoints. + parts_hi = skip_index + parts_lo = len(parts) - skip_index - 1 + if not parts[0]: + parts_hi -= 1 + if parts_hi: + msg = "Leading ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # ^: requires ^:: + if not parts[-1]: + parts_lo -= 1 + if parts_lo: + msg = "Trailing ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # :$ requires ::$ + parts_skipped = cls._HEXTET_COUNT - (parts_hi + parts_lo) + if parts_skipped < 1: + msg = "Expected at most %d other parts with '::' in %r" + raise AddressValueError(msg % (cls._HEXTET_COUNT - 1, ip_str)) + else: + # Otherwise, allocate the entire address to parts_hi. The + # endpoints could still be empty, but _parse_hextet() will check + # for that. + if len(parts) != cls._HEXTET_COUNT: + msg = "Exactly %d parts expected without '::' in %r" + raise AddressValueError(msg % (cls._HEXTET_COUNT, ip_str)) + if not parts[0]: + msg = "Leading ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # ^: requires ^:: + if not parts[-1]: + msg = "Trailing ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # :$ requires ::$ + parts_hi = len(parts) + parts_lo = 0 + parts_skipped = 0 + + try: + # Now, parse the hextets into a 128-bit integer. + ip_int = 0 + for i in range(parts_hi): + ip_int <<= 16 + ip_int |= cls._parse_hextet(parts[i]) + ip_int <<= 16 * parts_skipped + for i in range(-parts_lo, 0): + ip_int <<= 16 + ip_int |= cls._parse_hextet(parts[i]) + return ip_int + except ValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + + @classmethod + def _parse_hextet(cls, hextet_str): + """Convert an IPv6 hextet string into an integer. + + Args: + hextet_str: A string, the number to parse. + + Returns: + The hextet as an integer. + + Raises: + ValueError: if the input isn't strictly a hex number from + [0..FFFF]. + + """ + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not cls._HEX_DIGITS.issuperset(hextet_str): + raise ValueError("Only hex digits permitted in %r" % hextet_str) + # We do the length check second, since the invalid character error + # is likely to be more informative for the user + if len(hextet_str) > 4: + msg = "At most 4 characters permitted in %r" + raise ValueError(msg % hextet_str) + # Length check means we can skip checking the integer value + return int(hextet_str, 16) + + @classmethod + def _compress_hextets(cls, hextets): + """Compresses a list of hextets. + + Compresses a list of strings, replacing the longest continuous + sequence of "0" in the list with "" and adding empty strings at + the beginning or at the end of the string such that subsequently + calling ":".join(hextets) will produce the compressed version of + the IPv6 address. + + Args: + hextets: A list of strings, the hextets to compress. + + Returns: + A list of strings. + + """ + best_doublecolon_start = -1 + best_doublecolon_len = 0 + doublecolon_start = -1 + doublecolon_len = 0 + for index, hextet in enumerate(hextets): + if hextet == '0': + doublecolon_len += 1 + if doublecolon_start == -1: + # Start of a sequence of zeros. + doublecolon_start = index + if doublecolon_len > best_doublecolon_len: + # This is the longest sequence of zeros so far. + best_doublecolon_len = doublecolon_len + best_doublecolon_start = doublecolon_start + else: + doublecolon_len = 0 + doublecolon_start = -1 + + if best_doublecolon_len > 1: + best_doublecolon_end = (best_doublecolon_start + + best_doublecolon_len) + # For zeros at the end of the address. + if best_doublecolon_end == len(hextets): + hextets += [''] + hextets[best_doublecolon_start:best_doublecolon_end] = [''] + # For zeros at the beginning of the address. + if best_doublecolon_start == 0: + hextets = [''] + hextets + + return hextets + + @classmethod + def _string_from_ip_int(cls, ip_int=None): + """Turns a 128-bit integer into hexadecimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + A string, the hexadecimal representation of the address. + + Raises: + ValueError: The address is bigger than 128 bits of all ones. + + """ + if ip_int is None: + ip_int = int(cls._ip) + + if ip_int > cls._ALL_ONES: + raise ValueError('IPv6 address is too large') + + hex_str = '%032x' % ip_int + hextets = ['%x' % int(hex_str[x:x + 4], 16) for x in range(0, 32, 4)] + + hextets = cls._compress_hextets(hextets) + return ':'.join(hextets) + + def _explode_shorthand_ip_string(self): + """Expand a shortened IPv6 address. + + Args: + ip_str: A string, the IPv6 address. + + Returns: + A string, the expanded IPv6 address. + + """ + if isinstance(self, IPv6Network): + ip_str = _compat_str(self.network_address) + elif isinstance(self, IPv6Interface): + ip_str = _compat_str(self.ip) + else: + ip_str = _compat_str(self) + + ip_int = self._ip_int_from_string(ip_str) + hex_str = '%032x' % ip_int + parts = [hex_str[x:x + 4] for x in range(0, 32, 4)] + if isinstance(self, (_BaseNetwork, IPv6Interface)): + return '%s/%d' % (':'.join(parts), self._prefixlen) + return ':'.join(parts) + + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv6 address. + + This implements the method described in RFC3596 2.5. + + """ + reverse_chars = self.exploded[::-1].replace(':', '') + return '.'.join(reverse_chars) + '.ip6.arpa' + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def version(self): + return self._version + + +class IPv6Address(_BaseV6, _BaseAddress): + + """Represent and manipulate single IPv6 Addresses.""" + + __slots__ = ('_ip', '__weakref__') + + def __init__(self, address): + """Instantiate a new IPv6 address object. + + Args: + address: A string or integer representing the IP + + Additionally, an integer can be passed, so + IPv6Address('2001:db8::') == + IPv6Address(42540766411282592856903984951653826560) + or, more generally + IPv6Address(int(IPv6Address('2001:db8::'))) == + IPv6Address('2001:db8::') + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + + """ + # Efficient constructor from integer. + if isinstance(address, _compat_int_types): + self._check_int_address(address) + self._ip = address + return + + # Constructing from a packed address + if isinstance(address, bytes): + self._check_packed_address(address, 16) + bvs = _compat_bytes_to_byte_vals(address) + self._ip = _compat_int_from_byte_vals(bvs, 'big') + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = _compat_str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) + self._ip = self._ip_int_from_string(addr_str) + + @property + def packed(self): + """The binary representation of this address.""" + return v6_int_to_packed(self._ip) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is a multicast address. + See RFC 2373 2.7 for details. + + """ + return self in self._constants._multicast_network + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within one of the + reserved IPv6 Network ranges. + + """ + return any(self in x for x in self._constants._reserved_networks) + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is reserved per RFC 4291. + + """ + return self in self._constants._linklocal_network + + @property + def is_site_local(self): + """Test if the address is reserved for site-local. + + Note that the site-local address space has been deprecated by RFC 3879. + Use is_private to test if this address is in the space of unique local + addresses as defined by RFC 4193. + + Returns: + A boolean, True if the address is reserved per RFC 3513 2.5.6. + + """ + return self in self._constants._sitelocal_network + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv6-special-registry. + + """ + return any(self in net for net in self._constants._private_networks) + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, true if the address is not reserved per + iana-ipv6-special-registry. + + """ + return not self.is_private + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 2373 2.5.2. + + """ + return self._ip == 0 + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback address as defined in + RFC 2373 2.5.3. + + """ + return self._ip == 1 + + @property + def ipv4_mapped(self): + """Return the IPv4 mapped address. + + Returns: + If the IPv6 address is a v4 mapped address, return the + IPv4 mapped address. Return None otherwise. + + """ + if (self._ip >> 32) != 0xFFFF: + return None + return IPv4Address(self._ip & 0xFFFFFFFF) + + @property + def teredo(self): + """Tuple of embedded teredo IPs. + + Returns: + Tuple of the (server, client) IPs or None if the address + doesn't appear to be a teredo address (doesn't start with + 2001::/32) + + """ + if (self._ip >> 96) != 0x20010000: + return None + return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF), + IPv4Address(~self._ip & 0xFFFFFFFF)) + + @property + def sixtofour(self): + """Return the IPv4 6to4 embedded address. + + Returns: + The IPv4 6to4-embedded address if present or None if the + address doesn't appear to contain a 6to4 embedded address. + + """ + if (self._ip >> 112) != 0x2002: + return None + return IPv4Address((self._ip >> 80) & 0xFFFFFFFF) + + +class IPv6Interface(IPv6Address): + + def __init__(self, address): + if isinstance(address, (bytes, _compat_int_types)): + IPv6Address.__init__(self, address) + self.network = IPv6Network(self._ip) + self._prefixlen = self._max_prefixlen + return + if isinstance(address, tuple): + IPv6Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + + addr = _split_optional_netmask(address) + IPv6Address.__init__(self, addr[0]) + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self._prefixlen = self.network._prefixlen + self.hostmask = self.network.hostmask + + def __str__(self): + return '%s/%d' % (self._string_from_ip_int(self._ip), + self.network.prefixlen) + + def __eq__(self, other): + address_equal = IPv6Address.__eq__(self, other) + if not address_equal or address_equal is NotImplemented: + return address_equal + try: + return self.network == other.network + except AttributeError: + # An interface with an associated network is NOT the + # same as an unassociated address. That's why the hash + # takes the extra info into account. + return False + + def __lt__(self, other): + address_less = IPv6Address.__lt__(self, other) + if address_less is NotImplemented: + return NotImplemented + try: + return (self.network < other.network or + self.network == other.network and address_less) + except AttributeError: + # We *do* allow addresses and interfaces to be sorted. The + # unassociated address is considered less than all interfaces. + return False + + def __hash__(self): + return self._ip ^ self._prefixlen ^ int(self.network.network_address) + + __reduce__ = _IPAddressBase.__reduce__ + + @property + def ip(self): + return IPv6Address(self._ip) + + @property + def with_prefixlen(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.hostmask) + + @property + def is_unspecified(self): + return self._ip == 0 and self.network.is_unspecified + + @property + def is_loopback(self): + return self._ip == 1 and self.network.is_loopback + + +class IPv6Network(_BaseV6, _BaseNetwork): + + """This class represents and manipulates 128-bit IPv6 networks. + + Attributes: [examples for IPv6('2001:db8::1000/124')] + .network_address: IPv6Address('2001:db8::1000') + .hostmask: IPv6Address('::f') + .broadcast_address: IPv6Address('2001:db8::100f') + .netmask: IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0') + .prefixlen: 124 + + """ + + # Class to use when creating address objects + _address_class = IPv6Address + + def __init__(self, address, strict=True): + """Instantiate a new IPv6 Network object. + + Args: + address: A string or integer representing the IPv6 network or the + IP and prefix/netmask. + '2001:db8::/128' + '2001:db8:0000:0000:0000:0000:0000:0000/128' + '2001:db8::' + are all functionally the same in IPv6. That is to say, + failing to provide a subnetmask will create an object with + a mask of /128. + + Additionally, an integer can be passed, so + IPv6Network('2001:db8::') == + IPv6Network(42540766411282592856903984951653826560) + or, more generally + IPv6Network(int(IPv6Network('2001:db8::'))) == + IPv6Network('2001:db8::') + + strict: A boolean. If true, ensure that we have been passed + A true network address, eg, 2001:db8::1000/124 and not an + IP address on a network, eg, 2001:db8::1/124. + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + NetmaskValueError: If the netmask isn't valid for + an IPv6 address. + ValueError: If strict was True and a network address was not + supplied. + + """ + _BaseNetwork.__init__(self, address) + + # Efficient constructor from integer or packed address + if isinstance(address, (bytes, _compat_int_types)): + self.network_address = IPv6Address(address) + self.netmask, self._prefixlen = self._make_netmask( + self._max_prefixlen) + return + + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + self.network_address = IPv6Address(address[0]) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv6Address(packed & + int(self.netmask)) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = _split_optional_netmask(address) + + self.network_address = IPv6Address(self._ip_int_from_string(addr[0])) + + if len(addr) == 2: + arg = addr[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + + if strict: + if (IPv6Address(int(self.network_address) & int(self.netmask)) != + self.network_address): + raise ValueError('%s has host bits set' % self) + self.network_address = IPv6Address(int(self.network_address) & + int(self.netmask)) + + if self._prefixlen == (self._max_prefixlen - 1): + self.hosts = self.__iter__ + + def hosts(self): + """Generate Iterator over usable hosts in a network. + + This is like __iter__ except it doesn't return the + Subnet-Router anycast address. + + """ + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network + 1, broadcast + 1): + yield self._address_class(x) + + @property + def is_site_local(self): + """Test if the address is reserved for site-local. + + Note that the site-local address space has been deprecated by RFC 3879. + Use is_private to test if this address is in the space of unique local + addresses as defined by RFC 4193. + + Returns: + A boolean, True if the address is reserved per RFC 3513 2.5.6. + + """ + return (self.network_address.is_site_local and + self.broadcast_address.is_site_local) + + +class _IPv6Constants(object): + + _linklocal_network = IPv6Network('fe80::/10') + + _multicast_network = IPv6Network('ff00::/8') + + _private_networks = [ + IPv6Network('::1/128'), + IPv6Network('::/128'), + IPv6Network('::ffff:0:0/96'), + IPv6Network('100::/64'), + IPv6Network('2001::/23'), + IPv6Network('2001:2::/48'), + IPv6Network('2001:db8::/32'), + IPv6Network('2001:10::/28'), + IPv6Network('fc00::/7'), + IPv6Network('fe80::/10'), + ] + + _reserved_networks = [ + IPv6Network('::/8'), IPv6Network('100::/8'), + IPv6Network('200::/7'), IPv6Network('400::/6'), + IPv6Network('800::/5'), IPv6Network('1000::/4'), + IPv6Network('4000::/3'), IPv6Network('6000::/3'), + IPv6Network('8000::/3'), IPv6Network('A000::/3'), + IPv6Network('C000::/3'), IPv6Network('E000::/4'), + IPv6Network('F000::/5'), IPv6Network('F800::/6'), + IPv6Network('FE00::/9'), + ] + + _sitelocal_network = IPv6Network('fec0::/10') + + +IPv6Address._constants = _IPv6Constants diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__init__.py new file mode 100644 index 0000000..a6f44a5 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__init__.py @@ -0,0 +1,347 @@ +# -*- coding: utf-8 -*- + +""" +lockfile.py - Platform-independent advisory file locks. + +Requires Python 2.5 unless you apply 2.4.diff +Locking is done on a per-thread basis instead of a per-process basis. + +Usage: + +>>> lock = LockFile('somefile') +>>> try: +... lock.acquire() +... except AlreadyLocked: +... print 'somefile', 'is locked already.' +... except LockFailed: +... print 'somefile', 'can\\'t be locked.' +... else: +... print 'got lock' +got lock +>>> print lock.is_locked() +True +>>> lock.release() + +>>> lock = LockFile('somefile') +>>> print lock.is_locked() +False +>>> with lock: +... print lock.is_locked() +True +>>> print lock.is_locked() +False + +>>> lock = LockFile('somefile') +>>> # It is okay to lock twice from the same thread... +>>> with lock: +... lock.acquire() +... +>>> # Though no counter is kept, so you can't unlock multiple times... +>>> print lock.is_locked() +False + +Exceptions: + + Error - base class for other exceptions + LockError - base class for all locking exceptions + AlreadyLocked - Another thread or process already holds the lock + LockFailed - Lock failed for some other reason + UnlockError - base class for all unlocking exceptions + AlreadyUnlocked - File was not locked. + NotMyLock - File was locked but not by the current thread/process +""" + +from __future__ import absolute_import + +import functools +import os +import socket +import threading +import warnings + +# Work with PEP8 and non-PEP8 versions of threading module. +if not hasattr(threading, "current_thread"): + threading.current_thread = threading.currentThread +if not hasattr(threading.Thread, "get_name"): + threading.Thread.get_name = threading.Thread.getName + +__all__ = ['Error', 'LockError', 'LockTimeout', 'AlreadyLocked', + 'LockFailed', 'UnlockError', 'NotLocked', 'NotMyLock', + 'LinkFileLock', 'MkdirFileLock', 'SQLiteFileLock', + 'LockBase', 'locked'] + + +class Error(Exception): + """ + Base class for other exceptions. + + >>> try: + ... raise Error + ... except Exception: + ... pass + """ + pass + + +class LockError(Error): + """ + Base class for error arising from attempts to acquire the lock. + + >>> try: + ... raise LockError + ... except Error: + ... pass + """ + pass + + +class LockTimeout(LockError): + """Raised when lock creation fails within a user-defined period of time. + + >>> try: + ... raise LockTimeout + ... except LockError: + ... pass + """ + pass + + +class AlreadyLocked(LockError): + """Some other thread/process is locking the file. + + >>> try: + ... raise AlreadyLocked + ... except LockError: + ... pass + """ + pass + + +class LockFailed(LockError): + """Lock file creation failed for some other reason. + + >>> try: + ... raise LockFailed + ... except LockError: + ... pass + """ + pass + + +class UnlockError(Error): + """ + Base class for errors arising from attempts to release the lock. + + >>> try: + ... raise UnlockError + ... except Error: + ... pass + """ + pass + + +class NotLocked(UnlockError): + """Raised when an attempt is made to unlock an unlocked file. + + >>> try: + ... raise NotLocked + ... except UnlockError: + ... pass + """ + pass + + +class NotMyLock(UnlockError): + """Raised when an attempt is made to unlock a file someone else locked. + + >>> try: + ... raise NotMyLock + ... except UnlockError: + ... pass + """ + pass + + +class _SharedBase(object): + def __init__(self, path): + self.path = path + + def acquire(self, timeout=None): + """ + Acquire the lock. + + * If timeout is omitted (or None), wait forever trying to lock the + file. + + * If timeout > 0, try to acquire the lock for that many seconds. If + the lock period expires and the file is still locked, raise + LockTimeout. + + * If timeout <= 0, raise AlreadyLocked immediately if the file is + already locked. + """ + raise NotImplemented("implement in subclass") + + def release(self): + """ + Release the lock. + + If the file is not locked, raise NotLocked. + """ + raise NotImplemented("implement in subclass") + + def __enter__(self): + """ + Context manager support. + """ + self.acquire() + return self + + def __exit__(self, *_exc): + """ + Context manager support. + """ + self.release() + + def __repr__(self): + return "<%s: %r>" % (self.__class__.__name__, self.path) + + +class LockBase(_SharedBase): + """Base class for platform-specific lock classes.""" + def __init__(self, path, threaded=True, timeout=None): + """ + >>> lock = LockBase('somefile') + >>> lock = LockBase('somefile', threaded=False) + """ + super(LockBase, self).__init__(path) + self.lock_file = os.path.abspath(path) + ".lock" + self.hostname = socket.gethostname() + self.pid = os.getpid() + if threaded: + t = threading.current_thread() + # Thread objects in Python 2.4 and earlier do not have ident + # attrs. Worm around that. + ident = getattr(t, "ident", hash(t)) + self.tname = "-%x" % (ident & 0xffffffff) + else: + self.tname = "" + dirname = os.path.dirname(self.lock_file) + + # unique name is mostly about the current process, but must + # also contain the path -- otherwise, two adjacent locked + # files conflict (one file gets locked, creating lock-file and + # unique file, the other one gets locked, creating lock-file + # and overwriting the already existing lock-file, then one + # gets unlocked, deleting both lock-file and unique file, + # finally the last lock errors out upon releasing. + self.unique_name = os.path.join(dirname, + "%s%s.%s%s" % (self.hostname, + self.tname, + self.pid, + hash(self.path))) + self.timeout = timeout + + def is_locked(self): + """ + Tell whether or not the file is locked. + """ + raise NotImplemented("implement in subclass") + + def i_am_locking(self): + """ + Return True if this object is locking the file. + """ + raise NotImplemented("implement in subclass") + + def break_lock(self): + """ + Remove a lock. Useful if a locking thread failed to unlock. + """ + raise NotImplemented("implement in subclass") + + def __repr__(self): + return "<%s: %r -- %r>" % (self.__class__.__name__, self.unique_name, + self.path) + + +def _fl_helper(cls, mod, *args, **kwds): + warnings.warn("Import from %s module instead of lockfile package" % mod, + DeprecationWarning, stacklevel=2) + # This is a bit funky, but it's only for awhile. The way the unit tests + # are constructed this function winds up as an unbound method, so it + # actually takes three args, not two. We want to toss out self. + if not isinstance(args[0], str): + # We are testing, avoid the first arg + args = args[1:] + if len(args) == 1 and not kwds: + kwds["threaded"] = True + return cls(*args, **kwds) + + +def LinkFileLock(*args, **kwds): + """Factory function provided for backwards compatibility. + + Do not use in new code. Instead, import LinkLockFile from the + lockfile.linklockfile module. + """ + from . import linklockfile + return _fl_helper(linklockfile.LinkLockFile, "lockfile.linklockfile", + *args, **kwds) + + +def MkdirFileLock(*args, **kwds): + """Factory function provided for backwards compatibility. + + Do not use in new code. Instead, import MkdirLockFile from the + lockfile.mkdirlockfile module. + """ + from . import mkdirlockfile + return _fl_helper(mkdirlockfile.MkdirLockFile, "lockfile.mkdirlockfile", + *args, **kwds) + + +def SQLiteFileLock(*args, **kwds): + """Factory function provided for backwards compatibility. + + Do not use in new code. Instead, import SQLiteLockFile from the + lockfile.mkdirlockfile module. + """ + from . import sqlitelockfile + return _fl_helper(sqlitelockfile.SQLiteLockFile, "lockfile.sqlitelockfile", + *args, **kwds) + + +def locked(path, timeout=None): + """Decorator which enables locks for decorated function. + + Arguments: + - path: path for lockfile. + - timeout (optional): Timeout for acquiring lock. + + Usage: + @locked('/var/run/myname', timeout=0) + def myname(...): + ... + """ + def decor(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + lock = FileLock(path, timeout=timeout) + lock.acquire() + try: + return func(*args, **kwargs) + finally: + lock.release() + return wrapper + return decor + + +if hasattr(os, "link"): + from . import linklockfile as _llf + LockFile = _llf.LinkLockFile +else: + from . import mkdirlockfile as _mlf + LockFile = _mlf.MkdirLockFile + +FileLock = LockFile diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/linklockfile.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/linklockfile.py new file mode 100644 index 0000000..2ca9be0 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/linklockfile.py @@ -0,0 +1,73 @@ +from __future__ import absolute_import + +import time +import os + +from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, + AlreadyLocked) + + +class LinkLockFile(LockBase): + """Lock access to a file using atomic property of link(2). + + >>> lock = LinkLockFile('somefile') + >>> lock = LinkLockFile('somefile', threaded=False) + """ + + def acquire(self, timeout=None): + try: + open(self.unique_name, "wb").close() + except IOError: + raise LockFailed("failed to create %s" % self.unique_name) + + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + while True: + # Try and create a hard link to it. + try: + os.link(self.unique_name, self.lock_file) + except OSError: + # Link creation failed. Maybe we've double-locked? + nlinks = os.stat(self.unique_name).st_nlink + if nlinks == 2: + # The original link plus the one I created == 2. We're + # good to go. + return + else: + # Otherwise the lock creation failed. + if timeout is not None and time.time() > end_time: + os.unlink(self.unique_name) + if timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(timeout is not None and timeout / 10 or 0.1) + else: + # Link creation succeeded. We're good to go. + return + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + elif not os.path.exists(self.unique_name): + raise NotMyLock("%s is locked, but not by me" % self.path) + os.unlink(self.unique_name) + os.unlink(self.lock_file) + + def is_locked(self): + return os.path.exists(self.lock_file) + + def i_am_locking(self): + return (self.is_locked() and + os.path.exists(self.unique_name) and + os.stat(self.unique_name).st_nlink == 2) + + def break_lock(self): + if os.path.exists(self.lock_file): + os.unlink(self.lock_file) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/mkdirlockfile.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/mkdirlockfile.py new file mode 100644 index 0000000..05a8c96 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/mkdirlockfile.py @@ -0,0 +1,84 @@ +from __future__ import absolute_import, division + +import time +import os +import sys +import errno + +from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, + AlreadyLocked) + + +class MkdirLockFile(LockBase): + """Lock file by creating a directory.""" + def __init__(self, path, threaded=True, timeout=None): + """ + >>> lock = MkdirLockFile('somefile') + >>> lock = MkdirLockFile('somefile', threaded=False) + """ + LockBase.__init__(self, path, threaded, timeout) + # Lock file itself is a directory. Place the unique file name into + # it. + self.unique_name = os.path.join(self.lock_file, + "%s.%s%s" % (self.hostname, + self.tname, + self.pid)) + + def acquire(self, timeout=None): + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + if timeout is None: + wait = 0.1 + else: + wait = max(0, timeout / 10) + + while True: + try: + os.mkdir(self.lock_file) + except OSError: + err = sys.exc_info()[1] + if err.errno == errno.EEXIST: + # Already locked. + if os.path.exists(self.unique_name): + # Already locked by me. + return + if timeout is not None and time.time() > end_time: + if timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + # Someone else has the lock. + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(wait) + else: + # Couldn't create the lock for some other reason + raise LockFailed("failed to create %s" % self.lock_file) + else: + open(self.unique_name, "wb").close() + return + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + elif not os.path.exists(self.unique_name): + raise NotMyLock("%s is locked, but not by me" % self.path) + os.unlink(self.unique_name) + os.rmdir(self.lock_file) + + def is_locked(self): + return os.path.exists(self.lock_file) + + def i_am_locking(self): + return (self.is_locked() and + os.path.exists(self.unique_name)) + + def break_lock(self): + if os.path.exists(self.lock_file): + for name in os.listdir(self.lock_file): + os.unlink(os.path.join(self.lock_file, name)) + os.rmdir(self.lock_file) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py new file mode 100644 index 0000000..069e85b --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- + +# pidlockfile.py +# +# Copyright © 2008–2009 Ben Finney <ben+python@benfinney.id.au> +# +# This is free software: you may copy, modify, and/or distribute this work +# under the terms of the Python Software Foundation License, version 2 or +# later as published by the Python Software Foundation. +# No warranty expressed or implied. See the file LICENSE.PSF-2 for details. + +""" Lockfile behaviour implemented via Unix PID files. + """ + +from __future__ import absolute_import + +import errno +import os +import time + +from . import (LockBase, AlreadyLocked, LockFailed, NotLocked, NotMyLock, + LockTimeout) + + +class PIDLockFile(LockBase): + """ Lockfile implemented as a Unix PID file. + + The lock file is a normal file named by the attribute `path`. + A lock's PID file contains a single line of text, containing + the process ID (PID) of the process that acquired the lock. + + >>> lock = PIDLockFile('somefile') + >>> lock = PIDLockFile('somefile') + """ + + def __init__(self, path, threaded=False, timeout=None): + # pid lockfiles don't support threaded operation, so always force + # False as the threaded arg. + LockBase.__init__(self, path, False, timeout) + self.unique_name = self.path + + def read_pid(self): + """ Get the PID from the lock file. + """ + return read_pid_from_pidfile(self.path) + + def is_locked(self): + """ Test if the lock is currently held. + + The lock is held if the PID file for this lock exists. + + """ + return os.path.exists(self.path) + + def i_am_locking(self): + """ Test if the lock is held by the current process. + + Returns ``True`` if the current process ID matches the + number stored in the PID file. + """ + return self.is_locked() and os.getpid() == self.read_pid() + + def acquire(self, timeout=None): + """ Acquire the lock. + + Creates the PID file for this lock, or raises an error if + the lock could not be acquired. + """ + + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + while True: + try: + write_pid_to_pidfile(self.path) + except OSError as exc: + if exc.errno == errno.EEXIST: + # The lock creation failed. Maybe sleep a bit. + if time.time() > end_time: + if timeout is not None and timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(timeout is not None and timeout / 10 or 0.1) + else: + raise LockFailed("failed to create %s" % self.path) + else: + return + + def release(self): + """ Release the lock. + + Removes the PID file to release the lock, or raises an + error if the current process does not hold the lock. + + """ + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + if not self.i_am_locking(): + raise NotMyLock("%s is locked, but not by me" % self.path) + remove_existing_pidfile(self.path) + + def break_lock(self): + """ Break an existing lock. + + Removes the PID file if it already exists, otherwise does + nothing. + + """ + remove_existing_pidfile(self.path) + + +def read_pid_from_pidfile(pidfile_path): + """ Read the PID recorded in the named PID file. + + Read and return the numeric PID recorded as text in the named + PID file. If the PID file cannot be read, or if the content is + not a valid PID, return ``None``. + + """ + pid = None + try: + pidfile = open(pidfile_path, 'r') + except IOError: + pass + else: + # According to the FHS 2.3 section on PID files in /var/run: + # + # The file must consist of the process identifier in + # ASCII-encoded decimal, followed by a newline character. + # + # Programs that read PID files should be somewhat flexible + # in what they accept; i.e., they should ignore extra + # whitespace, leading zeroes, absence of the trailing + # newline, or additional lines in the PID file. + + line = pidfile.readline().strip() + try: + pid = int(line) + except ValueError: + pass + pidfile.close() + + return pid + + +def write_pid_to_pidfile(pidfile_path): + """ Write the PID in the named PID file. + + Get the numeric process ID (“PID”) of the current process + and write it to the named file as a line of text. + + """ + open_flags = (os.O_CREAT | os.O_EXCL | os.O_WRONLY) + open_mode = 0o644 + pidfile_fd = os.open(pidfile_path, open_flags, open_mode) + pidfile = os.fdopen(pidfile_fd, 'w') + + # According to the FHS 2.3 section on PID files in /var/run: + # + # The file must consist of the process identifier in + # ASCII-encoded decimal, followed by a newline character. For + # example, if crond was process number 25, /var/run/crond.pid + # would contain three characters: two, five, and newline. + + pid = os.getpid() + pidfile.write("%s\n" % pid) + pidfile.close() + + +def remove_existing_pidfile(pidfile_path): + """ Remove the named PID file if it exists. + + Removing a PID file that doesn't already exist puts us in the + desired state, so we ignore the condition if the file does not + exist. + + """ + try: + os.remove(pidfile_path) + except OSError as exc: + if exc.errno == errno.ENOENT: + pass + else: + raise diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/sqlitelockfile.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/sqlitelockfile.py new file mode 100644 index 0000000..f997e24 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/sqlitelockfile.py @@ -0,0 +1,156 @@ +from __future__ import absolute_import, division + +import time +import os + +try: + unicode +except NameError: + unicode = str + +from . import LockBase, NotLocked, NotMyLock, LockTimeout, AlreadyLocked + + +class SQLiteLockFile(LockBase): + "Demonstrate SQL-based locking." + + testdb = None + + def __init__(self, path, threaded=True, timeout=None): + """ + >>> lock = SQLiteLockFile('somefile') + >>> lock = SQLiteLockFile('somefile', threaded=False) + """ + LockBase.__init__(self, path, threaded, timeout) + self.lock_file = unicode(self.lock_file) + self.unique_name = unicode(self.unique_name) + + if SQLiteLockFile.testdb is None: + import tempfile + _fd, testdb = tempfile.mkstemp() + os.close(_fd) + os.unlink(testdb) + del _fd, tempfile + SQLiteLockFile.testdb = testdb + + import sqlite3 + self.connection = sqlite3.connect(SQLiteLockFile.testdb) + + c = self.connection.cursor() + try: + c.execute("create table locks" + "(" + " lock_file varchar(32)," + " unique_name varchar(32)" + ")") + except sqlite3.OperationalError: + pass + else: + self.connection.commit() + import atexit + atexit.register(os.unlink, SQLiteLockFile.testdb) + + def acquire(self, timeout=None): + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + if timeout is None: + wait = 0.1 + elif timeout <= 0: + wait = 0 + else: + wait = timeout / 10 + + cursor = self.connection.cursor() + + while True: + if not self.is_locked(): + # Not locked. Try to lock it. + cursor.execute("insert into locks" + " (lock_file, unique_name)" + " values" + " (?, ?)", + (self.lock_file, self.unique_name)) + self.connection.commit() + + # Check to see if we are the only lock holder. + cursor.execute("select * from locks" + " where unique_name = ?", + (self.unique_name,)) + rows = cursor.fetchall() + if len(rows) > 1: + # Nope. Someone else got there. Remove our lock. + cursor.execute("delete from locks" + " where unique_name = ?", + (self.unique_name,)) + self.connection.commit() + else: + # Yup. We're done, so go home. + return + else: + # Check to see if we are the only lock holder. + cursor.execute("select * from locks" + " where unique_name = ?", + (self.unique_name,)) + rows = cursor.fetchall() + if len(rows) == 1: + # We're the locker, so go home. + return + + # Maybe we should wait a bit longer. + if timeout is not None and time.time() > end_time: + if timeout > 0: + # No more waiting. + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + # Someone else has the lock and we are impatient.. + raise AlreadyLocked("%s is already locked" % self.path) + + # Well, okay. We'll give it a bit longer. + time.sleep(wait) + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + if not self.i_am_locking(): + raise NotMyLock("%s is locked, but not by me (by %s)" % + (self.unique_name, self._who_is_locking())) + cursor = self.connection.cursor() + cursor.execute("delete from locks" + " where unique_name = ?", + (self.unique_name,)) + self.connection.commit() + + def _who_is_locking(self): + cursor = self.connection.cursor() + cursor.execute("select unique_name from locks" + " where lock_file = ?", + (self.lock_file,)) + return cursor.fetchone()[0] + + def is_locked(self): + cursor = self.connection.cursor() + cursor.execute("select * from locks" + " where lock_file = ?", + (self.lock_file,)) + rows = cursor.fetchall() + return not not rows + + def i_am_locking(self): + cursor = self.connection.cursor() + cursor.execute("select * from locks" + " where lock_file = ?" + " and unique_name = ?", + (self.lock_file, self.unique_name)) + return not not cursor.fetchall() + + def break_lock(self): + cursor = self.connection.cursor() + cursor.execute("delete from locks" + " where lock_file = ?", + (self.lock_file,)) + self.connection.commit() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/symlinklockfile.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/symlinklockfile.py new file mode 100644 index 0000000..23b41f5 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/symlinklockfile.py @@ -0,0 +1,70 @@ +from __future__ import absolute_import + +import os +import time + +from . import (LockBase, NotLocked, NotMyLock, LockTimeout, + AlreadyLocked) + + +class SymlinkLockFile(LockBase): + """Lock access to a file using symlink(2).""" + + def __init__(self, path, threaded=True, timeout=None): + # super(SymlinkLockFile).__init(...) + LockBase.__init__(self, path, threaded, timeout) + # split it back! + self.unique_name = os.path.split(self.unique_name)[1] + + def acquire(self, timeout=None): + # Hopefully unnecessary for symlink. + # try: + # open(self.unique_name, "wb").close() + # except IOError: + # raise LockFailed("failed to create %s" % self.unique_name) + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + while True: + # Try and create a symbolic link to it. + try: + os.symlink(self.unique_name, self.lock_file) + except OSError: + # Link creation failed. Maybe we've double-locked? + if self.i_am_locking(): + # Linked to out unique name. Proceed. + return + else: + # Otherwise the lock creation failed. + if timeout is not None and time.time() > end_time: + if timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(timeout / 10 if timeout is not None else 0.1) + else: + # Link creation succeeded. We're good to go. + return + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + elif not self.i_am_locking(): + raise NotMyLock("%s is locked, but not by me" % self.path) + os.unlink(self.lock_file) + + def is_locked(self): + return os.path.islink(self.lock_file) + + def i_am_locking(self): + return (os.path.islink(self.lock_file) + and os.readlink(self.lock_file) == self.unique_name) + + def break_lock(self): + if os.path.islink(self.lock_file): # exists && link + os.unlink(self.lock_file) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__init__.py new file mode 100644 index 0000000..2afca5a --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__init__.py @@ -0,0 +1,66 @@ +# coding: utf-8 +from pip._vendor.msgpack._version import version +from pip._vendor.msgpack.exceptions import * + +from collections import namedtuple + + +class ExtType(namedtuple('ExtType', 'code data')): + """ExtType represents ext type in msgpack.""" + def __new__(cls, code, data): + if not isinstance(code, int): + raise TypeError("code must be int") + if not isinstance(data, bytes): + raise TypeError("data must be bytes") + if not 0 <= code <= 127: + raise ValueError("code must be 0~127") + return super(ExtType, cls).__new__(cls, code, data) + + +import os +if os.environ.get('MSGPACK_PUREPYTHON'): + from pip._vendor.msgpack.fallback import Packer, unpackb, Unpacker +else: + try: + from pip._vendor.msgpack._packer import Packer + from pip._vendor.msgpack._unpacker import unpackb, Unpacker + except ImportError: + from pip._vendor.msgpack.fallback import Packer, unpackb, Unpacker + + +def pack(o, stream, **kwargs): + """ + Pack object `o` and write it to `stream` + + See :class:`Packer` for options. + """ + packer = Packer(**kwargs) + stream.write(packer.pack(o)) + + +def packb(o, **kwargs): + """ + Pack object `o` and return packed bytes + + See :class:`Packer` for options. + """ + return Packer(**kwargs).pack(o) + + +def unpack(stream, **kwargs): + """ + Unpack an object from `stream`. + + Raises `ExtraData` when `stream` contains extra bytes. + See :class:`Unpacker` for options. + """ + data = stream.read() + return unpackb(data, **kwargs) + + +# alias for compatibility to simplejson/marshal/pickle. +load = unpack +loads = unpackb + +dump = pack +dumps = packb diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/_version.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/_version.py new file mode 100644 index 0000000..d28f0de --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/_version.py @@ -0,0 +1 @@ +version = (0, 5, 6) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/exceptions.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/exceptions.py new file mode 100644 index 0000000..9766881 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/exceptions.py @@ -0,0 +1,41 @@ +class UnpackException(Exception): + """Deprecated. Use Exception instead to catch all exception during unpacking.""" + + +class BufferFull(UnpackException): + pass + + +class OutOfData(UnpackException): + pass + + +class UnpackValueError(UnpackException, ValueError): + """Deprecated. Use ValueError instead.""" + + +class ExtraData(UnpackValueError): + def __init__(self, unpacked, extra): + self.unpacked = unpacked + self.extra = extra + + def __str__(self): + return "unpack(b) received extra data." + + +class PackException(Exception): + """Deprecated. Use Exception instead to catch all exception during packing.""" + + +class PackValueError(PackException, ValueError): + """PackValueError is raised when type of input data is supported but it's value is unsupported. + + Deprecated. Use ValueError instead. + """ + + +class PackOverflowError(PackValueError, OverflowError): + """PackOverflowError is raised when integer value is out of range of msgpack support [-2**31, 2**32). + + Deprecated. Use ValueError instead. + """ diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/fallback.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/fallback.py new file mode 100644 index 0000000..9418421 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/fallback.py @@ -0,0 +1,977 @@ +"""Fallback pure Python implementation of msgpack""" + +import sys +import struct +import warnings + +if sys.version_info[0] == 3: + PY3 = True + int_types = int + Unicode = str + xrange = range + def dict_iteritems(d): + return d.items() +else: + PY3 = False + int_types = (int, long) + Unicode = unicode + def dict_iteritems(d): + return d.iteritems() + + +if hasattr(sys, 'pypy_version_info'): + # cStringIO is slow on PyPy, StringIO is faster. However: PyPy's own + # StringBuilder is fastest. + from __pypy__ import newlist_hint + try: + from __pypy__.builders import BytesBuilder as StringBuilder + except ImportError: + from __pypy__.builders import StringBuilder + USING_STRINGBUILDER = True + class StringIO(object): + def __init__(self, s=b''): + if s: + self.builder = StringBuilder(len(s)) + self.builder.append(s) + else: + self.builder = StringBuilder() + def write(self, s): + if isinstance(s, memoryview): + s = s.tobytes() + elif isinstance(s, bytearray): + s = bytes(s) + self.builder.append(s) + def getvalue(self): + return self.builder.build() +else: + USING_STRINGBUILDER = False + from io import BytesIO as StringIO + newlist_hint = lambda size: [] + + +from pip._vendor.msgpack.exceptions import ( + BufferFull, + OutOfData, + UnpackValueError, + PackValueError, + PackOverflowError, + ExtraData) + +from pip._vendor.msgpack import ExtType + + +EX_SKIP = 0 +EX_CONSTRUCT = 1 +EX_READ_ARRAY_HEADER = 2 +EX_READ_MAP_HEADER = 3 + +TYPE_IMMEDIATE = 0 +TYPE_ARRAY = 1 +TYPE_MAP = 2 +TYPE_RAW = 3 +TYPE_BIN = 4 +TYPE_EXT = 5 + +DEFAULT_RECURSE_LIMIT = 511 + + +def _check_type_strict(obj, t, type=type, tuple=tuple): + if type(t) is tuple: + return type(obj) in t + else: + return type(obj) is t + + +def _get_data_from_buffer(obj): + try: + view = memoryview(obj) + except TypeError: + # try to use legacy buffer protocol if 2.7, otherwise re-raise + if not PY3: + view = memoryview(buffer(obj)) + warnings.warn("using old buffer interface to unpack %s; " + "this leads to unpacking errors if slicing is used and " + "will be removed in a future version" % type(obj), + RuntimeWarning) + else: + raise + if view.itemsize != 1: + raise ValueError("cannot unpack from multi-byte object") + return view + + +def unpack(stream, **kwargs): + warnings.warn( + "Direct calling implementation's unpack() is deprecated, Use msgpack.unpack() or unpackb() instead.", + PendingDeprecationWarning) + data = stream.read() + return unpackb(data, **kwargs) + + +def unpackb(packed, **kwargs): + """ + Unpack an object from `packed`. + + Raises `ExtraData` when `packed` contains extra bytes. + See :class:`Unpacker` for options. + """ + unpacker = Unpacker(None, **kwargs) + unpacker.feed(packed) + try: + ret = unpacker._unpack() + except OutOfData: + raise UnpackValueError("Data is not enough.") + if unpacker._got_extradata(): + raise ExtraData(ret, unpacker._get_extradata()) + return ret + + +class Unpacker(object): + """Streaming unpacker. + + arguments: + + :param file_like: + File-like object having `.read(n)` method. + If specified, unpacker reads serialized data from it and :meth:`feed()` is not usable. + + :param int read_size: + Used as `file_like.read(read_size)`. (default: `min(16*1024, max_buffer_size)`) + + :param bool use_list: + If true, unpack msgpack array to Python list. + Otherwise, unpack to Python tuple. (default: True) + + :param bool raw: + If true, unpack msgpack raw to Python bytes (default). + Otherwise, unpack to Python str (or unicode on Python 2) by decoding + with UTF-8 encoding (recommended). + Currently, the default is true, but it will be changed to false in + near future. So you must specify it explicitly for keeping backward + compatibility. + + *encoding* option which is deprecated overrides this option. + + :param callable object_hook: + When specified, it should be callable. + Unpacker calls it with a dict argument after unpacking msgpack map. + (See also simplejson) + + :param callable object_pairs_hook: + When specified, it should be callable. + Unpacker calls it with a list of key-value pairs after unpacking msgpack map. + (See also simplejson) + + :param str encoding: + Encoding used for decoding msgpack raw. + If it is None (default), msgpack raw is deserialized to Python bytes. + + :param str unicode_errors: + (deprecated) Used for decoding msgpack raw with *encoding*. + (default: `'strict'`) + + :param int max_buffer_size: + Limits size of data waiting unpacked. 0 means system's INT_MAX (default). + Raises `BufferFull` exception when it is insufficient. + You should set this parameter when unpacking data from untrusted source. + + :param int max_str_len: + Limits max length of str. (default: 2**31-1) + + :param int max_bin_len: + Limits max length of bin. (default: 2**31-1) + + :param int max_array_len: + Limits max length of array. (default: 2**31-1) + + :param int max_map_len: + Limits max length of map. (default: 2**31-1) + + + example of streaming deserialize from file-like object:: + + unpacker = Unpacker(file_like, raw=False) + for o in unpacker: + process(o) + + example of streaming deserialize from socket:: + + unpacker = Unpacker(raw=False) + while True: + buf = sock.recv(1024**2) + if not buf: + break + unpacker.feed(buf) + for o in unpacker: + process(o) + """ + + def __init__(self, file_like=None, read_size=0, use_list=True, raw=True, + object_hook=None, object_pairs_hook=None, list_hook=None, + encoding=None, unicode_errors=None, max_buffer_size=0, + ext_hook=ExtType, + max_str_len=2147483647, # 2**32-1 + max_bin_len=2147483647, + max_array_len=2147483647, + max_map_len=2147483647, + max_ext_len=2147483647): + + if encoding is not None: + warnings.warn( + "encoding is deprecated, Use raw=False instead.", + PendingDeprecationWarning) + + if unicode_errors is None: + unicode_errors = 'strict' + + if file_like is None: + self._feeding = True + else: + if not callable(file_like.read): + raise TypeError("`file_like.read` must be callable") + self.file_like = file_like + self._feeding = False + + #: array of bytes fed. + self._buffer = bytearray() + # Some very old pythons don't support `struct.unpack_from()` with a + # `bytearray`. So we wrap it in a `buffer()` there. + if sys.version_info < (2, 7, 6): + self._buffer_view = buffer(self._buffer) + else: + self._buffer_view = self._buffer + #: Which position we currently reads + self._buff_i = 0 + + # When Unpacker is used as an iterable, between the calls to next(), + # the buffer is not "consumed" completely, for efficiency sake. + # Instead, it is done sloppily. To make sure we raise BufferFull at + # the correct moments, we have to keep track of how sloppy we were. + # Furthermore, when the buffer is incomplete (that is: in the case + # we raise an OutOfData) we need to rollback the buffer to the correct + # state, which _buf_checkpoint records. + self._buf_checkpoint = 0 + + self._max_buffer_size = max_buffer_size or 2**31-1 + if read_size > self._max_buffer_size: + raise ValueError("read_size must be smaller than max_buffer_size") + self._read_size = read_size or min(self._max_buffer_size, 16*1024) + self._raw = bool(raw) + self._encoding = encoding + self._unicode_errors = unicode_errors + self._use_list = use_list + self._list_hook = list_hook + self._object_hook = object_hook + self._object_pairs_hook = object_pairs_hook + self._ext_hook = ext_hook + self._max_str_len = max_str_len + self._max_bin_len = max_bin_len + self._max_array_len = max_array_len + self._max_map_len = max_map_len + self._max_ext_len = max_ext_len + self._stream_offset = 0 + + if list_hook is not None and not callable(list_hook): + raise TypeError('`list_hook` is not callable') + if object_hook is not None and not callable(object_hook): + raise TypeError('`object_hook` is not callable') + if object_pairs_hook is not None and not callable(object_pairs_hook): + raise TypeError('`object_pairs_hook` is not callable') + if object_hook is not None and object_pairs_hook is not None: + raise TypeError("object_pairs_hook and object_hook are mutually " + "exclusive") + if not callable(ext_hook): + raise TypeError("`ext_hook` is not callable") + + def feed(self, next_bytes): + assert self._feeding + view = _get_data_from_buffer(next_bytes) + if (len(self._buffer) - self._buff_i + len(view) > self._max_buffer_size): + raise BufferFull + + # Strip buffer before checkpoint before reading file. + if self._buf_checkpoint > 0: + del self._buffer[:self._buf_checkpoint] + self._buff_i -= self._buf_checkpoint + self._buf_checkpoint = 0 + + self._buffer += view + + def _consume(self): + """ Gets rid of the used parts of the buffer. """ + self._stream_offset += self._buff_i - self._buf_checkpoint + self._buf_checkpoint = self._buff_i + + def _got_extradata(self): + return self._buff_i < len(self._buffer) + + def _get_extradata(self): + return self._buffer[self._buff_i:] + + def read_bytes(self, n): + return self._read(n) + + def _read(self, n): + # (int) -> bytearray + self._reserve(n) + i = self._buff_i + self._buff_i = i+n + return self._buffer[i:i+n] + + def _reserve(self, n): + remain_bytes = len(self._buffer) - self._buff_i - n + + # Fast path: buffer has n bytes already + if remain_bytes >= 0: + return + + if self._feeding: + self._buff_i = self._buf_checkpoint + raise OutOfData + + # Strip buffer before checkpoint before reading file. + if self._buf_checkpoint > 0: + del self._buffer[:self._buf_checkpoint] + self._buff_i -= self._buf_checkpoint + self._buf_checkpoint = 0 + + # Read from file + remain_bytes = -remain_bytes + while remain_bytes > 0: + to_read_bytes = max(self._read_size, remain_bytes) + read_data = self.file_like.read(to_read_bytes) + if not read_data: + break + assert isinstance(read_data, bytes) + self._buffer += read_data + remain_bytes -= len(read_data) + + if len(self._buffer) < n + self._buff_i: + self._buff_i = 0 # rollback + raise OutOfData + + def _read_header(self, execute=EX_CONSTRUCT): + typ = TYPE_IMMEDIATE + n = 0 + obj = None + self._reserve(1) + b = self._buffer[self._buff_i] + self._buff_i += 1 + if b & 0b10000000 == 0: + obj = b + elif b & 0b11100000 == 0b11100000: + obj = -1 - (b ^ 0xff) + elif b & 0b11100000 == 0b10100000: + n = b & 0b00011111 + typ = TYPE_RAW + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b & 0b11110000 == 0b10010000: + n = b & 0b00001111 + typ = TYPE_ARRAY + if n > self._max_array_len: + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + elif b & 0b11110000 == 0b10000000: + n = b & 0b00001111 + typ = TYPE_MAP + if n > self._max_map_len: + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + elif b == 0xc0: + obj = None + elif b == 0xc2: + obj = False + elif b == 0xc3: + obj = True + elif b == 0xc4: + typ = TYPE_BIN + self._reserve(1) + n = self._buffer[self._buff_i] + self._buff_i += 1 + if n > self._max_bin_len: + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + obj = self._read(n) + elif b == 0xc5: + typ = TYPE_BIN + self._reserve(2) + n = struct.unpack_from(">H", self._buffer_view, self._buff_i)[0] + self._buff_i += 2 + if n > self._max_bin_len: + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + obj = self._read(n) + elif b == 0xc6: + typ = TYPE_BIN + self._reserve(4) + n = struct.unpack_from(">I", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + if n > self._max_bin_len: + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + obj = self._read(n) + elif b == 0xc7: # ext 8 + typ = TYPE_EXT + self._reserve(2) + L, n = struct.unpack_from('Bb', self._buffer_view, self._buff_i) + self._buff_i += 2 + if L > self._max_ext_len: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + obj = self._read(L) + elif b == 0xc8: # ext 16 + typ = TYPE_EXT + self._reserve(3) + L, n = struct.unpack_from('>Hb', self._buffer_view, self._buff_i) + self._buff_i += 3 + if L > self._max_ext_len: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + obj = self._read(L) + elif b == 0xc9: # ext 32 + typ = TYPE_EXT + self._reserve(5) + L, n = struct.unpack_from('>Ib', self._buffer_view, self._buff_i) + self._buff_i += 5 + if L > self._max_ext_len: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + obj = self._read(L) + elif b == 0xca: + self._reserve(4) + obj = struct.unpack_from(">f", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + elif b == 0xcb: + self._reserve(8) + obj = struct.unpack_from(">d", self._buffer_view, self._buff_i)[0] + self._buff_i += 8 + elif b == 0xcc: + self._reserve(1) + obj = self._buffer[self._buff_i] + self._buff_i += 1 + elif b == 0xcd: + self._reserve(2) + obj = struct.unpack_from(">H", self._buffer_view, self._buff_i)[0] + self._buff_i += 2 + elif b == 0xce: + self._reserve(4) + obj = struct.unpack_from(">I", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + elif b == 0xcf: + self._reserve(8) + obj = struct.unpack_from(">Q", self._buffer_view, self._buff_i)[0] + self._buff_i += 8 + elif b == 0xd0: + self._reserve(1) + obj = struct.unpack_from("b", self._buffer_view, self._buff_i)[0] + self._buff_i += 1 + elif b == 0xd1: + self._reserve(2) + obj = struct.unpack_from(">h", self._buffer_view, self._buff_i)[0] + self._buff_i += 2 + elif b == 0xd2: + self._reserve(4) + obj = struct.unpack_from(">i", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + elif b == 0xd3: + self._reserve(8) + obj = struct.unpack_from(">q", self._buffer_view, self._buff_i)[0] + self._buff_i += 8 + elif b == 0xd4: # fixext 1 + typ = TYPE_EXT + if self._max_ext_len < 1: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (1, self._max_ext_len)) + self._reserve(2) + n, obj = struct.unpack_from("b1s", self._buffer_view, self._buff_i) + self._buff_i += 2 + elif b == 0xd5: # fixext 2 + typ = TYPE_EXT + if self._max_ext_len < 2: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (2, self._max_ext_len)) + self._reserve(3) + n, obj = struct.unpack_from("b2s", self._buffer_view, self._buff_i) + self._buff_i += 3 + elif b == 0xd6: # fixext 4 + typ = TYPE_EXT + if self._max_ext_len < 4: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (4, self._max_ext_len)) + self._reserve(5) + n, obj = struct.unpack_from("b4s", self._buffer_view, self._buff_i) + self._buff_i += 5 + elif b == 0xd7: # fixext 8 + typ = TYPE_EXT + if self._max_ext_len < 8: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (8, self._max_ext_len)) + self._reserve(9) + n, obj = struct.unpack_from("b8s", self._buffer_view, self._buff_i) + self._buff_i += 9 + elif b == 0xd8: # fixext 16 + typ = TYPE_EXT + if self._max_ext_len < 16: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (16, self._max_ext_len)) + self._reserve(17) + n, obj = struct.unpack_from("b16s", self._buffer_view, self._buff_i) + self._buff_i += 17 + elif b == 0xd9: + typ = TYPE_RAW + self._reserve(1) + n = self._buffer[self._buff_i] + self._buff_i += 1 + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b == 0xda: + typ = TYPE_RAW + self._reserve(2) + n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) + self._buff_i += 2 + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b == 0xdb: + typ = TYPE_RAW + self._reserve(4) + n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) + self._buff_i += 4 + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b == 0xdc: + typ = TYPE_ARRAY + self._reserve(2) + n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) + self._buff_i += 2 + if n > self._max_array_len: + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + elif b == 0xdd: + typ = TYPE_ARRAY + self._reserve(4) + n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) + self._buff_i += 4 + if n > self._max_array_len: + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + elif b == 0xde: + self._reserve(2) + n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) + self._buff_i += 2 + if n > self._max_map_len: + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + typ = TYPE_MAP + elif b == 0xdf: + self._reserve(4) + n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) + self._buff_i += 4 + if n > self._max_map_len: + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + typ = TYPE_MAP + else: + raise UnpackValueError("Unknown header: 0x%x" % b) + return typ, n, obj + + def _unpack(self, execute=EX_CONSTRUCT): + typ, n, obj = self._read_header(execute) + + if execute == EX_READ_ARRAY_HEADER: + if typ != TYPE_ARRAY: + raise UnpackValueError("Expected array") + return n + if execute == EX_READ_MAP_HEADER: + if typ != TYPE_MAP: + raise UnpackValueError("Expected map") + return n + # TODO should we eliminate the recursion? + if typ == TYPE_ARRAY: + if execute == EX_SKIP: + for i in xrange(n): + # TODO check whether we need to call `list_hook` + self._unpack(EX_SKIP) + return + ret = newlist_hint(n) + for i in xrange(n): + ret.append(self._unpack(EX_CONSTRUCT)) + if self._list_hook is not None: + ret = self._list_hook(ret) + # TODO is the interaction between `list_hook` and `use_list` ok? + return ret if self._use_list else tuple(ret) + if typ == TYPE_MAP: + if execute == EX_SKIP: + for i in xrange(n): + # TODO check whether we need to call hooks + self._unpack(EX_SKIP) + self._unpack(EX_SKIP) + return + if self._object_pairs_hook is not None: + ret = self._object_pairs_hook( + (self._unpack(EX_CONSTRUCT), + self._unpack(EX_CONSTRUCT)) + for _ in xrange(n)) + else: + ret = {} + for _ in xrange(n): + key = self._unpack(EX_CONSTRUCT) + ret[key] = self._unpack(EX_CONSTRUCT) + if self._object_hook is not None: + ret = self._object_hook(ret) + return ret + if execute == EX_SKIP: + return + if typ == TYPE_RAW: + if self._encoding is not None: + obj = obj.decode(self._encoding, self._unicode_errors) + elif self._raw: + obj = bytes(obj) + else: + obj = obj.decode('utf_8') + return obj + if typ == TYPE_EXT: + return self._ext_hook(n, bytes(obj)) + if typ == TYPE_BIN: + return bytes(obj) + assert typ == TYPE_IMMEDIATE + return obj + + def __iter__(self): + return self + + def __next__(self): + try: + ret = self._unpack(EX_CONSTRUCT) + self._consume() + return ret + except OutOfData: + self._consume() + raise StopIteration + + next = __next__ + + def skip(self, write_bytes=None): + self._unpack(EX_SKIP) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + + def unpack(self, write_bytes=None): + ret = self._unpack(EX_CONSTRUCT) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + return ret + + def read_array_header(self, write_bytes=None): + ret = self._unpack(EX_READ_ARRAY_HEADER) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + return ret + + def read_map_header(self, write_bytes=None): + ret = self._unpack(EX_READ_MAP_HEADER) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + return ret + + def tell(self): + return self._stream_offset + + +class Packer(object): + """ + MessagePack Packer + + usage: + + packer = Packer() + astream.write(packer.pack(a)) + astream.write(packer.pack(b)) + + Packer's constructor has some keyword arguments: + + :param callable default: + Convert user type to builtin type that Packer supports. + See also simplejson's document. + + :param bool use_single_float: + Use single precision float type for float. (default: False) + + :param bool autoreset: + Reset buffer after each pack and return its content as `bytes`. (default: True). + If set this to false, use `bytes()` to get content and `.reset()` to clear buffer. + + :param bool use_bin_type: + Use bin type introduced in msgpack spec 2.0 for bytes. + It also enables str8 type for unicode. + + :param bool strict_types: + If set to true, types will be checked to be exact. Derived classes + from serializeable types will not be serialized and will be + treated as unsupported type and forwarded to default. + Additionally tuples will not be serialized as lists. + This is useful when trying to implement accurate serialization + for python types. + + :param str encoding: + (deprecated) Convert unicode to bytes with this encoding. (default: 'utf-8') + + :param str unicode_errors: + Error handler for encoding unicode. (default: 'strict') + """ + def __init__(self, default=None, encoding=None, unicode_errors=None, + use_single_float=False, autoreset=True, use_bin_type=False, + strict_types=False): + if encoding is None: + encoding = 'utf_8' + else: + warnings.warn( + "encoding is deprecated, Use raw=False instead.", + PendingDeprecationWarning) + + if unicode_errors is None: + unicode_errors = 'strict' + + self._strict_types = strict_types + self._use_float = use_single_float + self._autoreset = autoreset + self._use_bin_type = use_bin_type + self._encoding = encoding + self._unicode_errors = unicode_errors + self._buffer = StringIO() + if default is not None: + if not callable(default): + raise TypeError("default must be callable") + self._default = default + + def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT, + check=isinstance, check_type_strict=_check_type_strict): + default_used = False + if self._strict_types: + check = check_type_strict + list_types = list + else: + list_types = (list, tuple) + while True: + if nest_limit < 0: + raise PackValueError("recursion limit exceeded") + if obj is None: + return self._buffer.write(b"\xc0") + if check(obj, bool): + if obj: + return self._buffer.write(b"\xc3") + return self._buffer.write(b"\xc2") + if check(obj, int_types): + if 0 <= obj < 0x80: + return self._buffer.write(struct.pack("B", obj)) + if -0x20 <= obj < 0: + return self._buffer.write(struct.pack("b", obj)) + if 0x80 <= obj <= 0xff: + return self._buffer.write(struct.pack("BB", 0xcc, obj)) + if -0x80 <= obj < 0: + return self._buffer.write(struct.pack(">Bb", 0xd0, obj)) + if 0xff < obj <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xcd, obj)) + if -0x8000 <= obj < -0x80: + return self._buffer.write(struct.pack(">Bh", 0xd1, obj)) + if 0xffff < obj <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xce, obj)) + if -0x80000000 <= obj < -0x8000: + return self._buffer.write(struct.pack(">Bi", 0xd2, obj)) + if 0xffffffff < obj <= 0xffffffffffffffff: + return self._buffer.write(struct.pack(">BQ", 0xcf, obj)) + if -0x8000000000000000 <= obj < -0x80000000: + return self._buffer.write(struct.pack(">Bq", 0xd3, obj)) + if not default_used and self._default is not None: + obj = self._default(obj) + default_used = True + continue + raise PackOverflowError("Integer value out of range") + if check(obj, (bytes, bytearray)): + n = len(obj) + if n >= 2**32: + raise PackValueError("%s is too large" % type(obj).__name__) + self._pack_bin_header(n) + return self._buffer.write(obj) + if check(obj, Unicode): + if self._encoding is None: + raise TypeError( + "Can't encode unicode string: " + "no encoding is specified") + obj = obj.encode(self._encoding, self._unicode_errors) + n = len(obj) + if n >= 2**32: + raise PackValueError("String is too large") + self._pack_raw_header(n) + return self._buffer.write(obj) + if check(obj, memoryview): + n = len(obj) * obj.itemsize + if n >= 2**32: + raise PackValueError("Memoryview is too large") + self._pack_bin_header(n) + return self._buffer.write(obj) + if check(obj, float): + if self._use_float: + return self._buffer.write(struct.pack(">Bf", 0xca, obj)) + return self._buffer.write(struct.pack(">Bd", 0xcb, obj)) + if check(obj, ExtType): + code = obj.code + data = obj.data + assert isinstance(code, int) + assert isinstance(data, bytes) + L = len(data) + if L == 1: + self._buffer.write(b'\xd4') + elif L == 2: + self._buffer.write(b'\xd5') + elif L == 4: + self._buffer.write(b'\xd6') + elif L == 8: + self._buffer.write(b'\xd7') + elif L == 16: + self._buffer.write(b'\xd8') + elif L <= 0xff: + self._buffer.write(struct.pack(">BB", 0xc7, L)) + elif L <= 0xffff: + self._buffer.write(struct.pack(">BH", 0xc8, L)) + else: + self._buffer.write(struct.pack(">BI", 0xc9, L)) + self._buffer.write(struct.pack("b", code)) + self._buffer.write(data) + return + if check(obj, list_types): + n = len(obj) + self._pack_array_header(n) + for i in xrange(n): + self._pack(obj[i], nest_limit - 1) + return + if check(obj, dict): + return self._pack_map_pairs(len(obj), dict_iteritems(obj), + nest_limit - 1) + if not default_used and self._default is not None: + obj = self._default(obj) + default_used = 1 + continue + raise TypeError("Cannot serialize %r" % (obj, )) + + def pack(self, obj): + try: + self._pack(obj) + except: + self._buffer = StringIO() # force reset + raise + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_map_pairs(self, pairs): + self._pack_map_pairs(len(pairs), pairs) + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_array_header(self, n): + if n >= 2**32: + raise PackValueError + self._pack_array_header(n) + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_map_header(self, n): + if n >= 2**32: + raise PackValueError + self._pack_map_header(n) + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_ext_type(self, typecode, data): + if not isinstance(typecode, int): + raise TypeError("typecode must have int type.") + if not 0 <= typecode <= 127: + raise ValueError("typecode should be 0-127") + if not isinstance(data, bytes): + raise TypeError("data must have bytes type") + L = len(data) + if L > 0xffffffff: + raise PackValueError("Too large data") + if L == 1: + self._buffer.write(b'\xd4') + elif L == 2: + self._buffer.write(b'\xd5') + elif L == 4: + self._buffer.write(b'\xd6') + elif L == 8: + self._buffer.write(b'\xd7') + elif L == 16: + self._buffer.write(b'\xd8') + elif L <= 0xff: + self._buffer.write(b'\xc7' + struct.pack('B', L)) + elif L <= 0xffff: + self._buffer.write(b'\xc8' + struct.pack('>H', L)) + else: + self._buffer.write(b'\xc9' + struct.pack('>I', L)) + self._buffer.write(struct.pack('B', typecode)) + self._buffer.write(data) + + def _pack_array_header(self, n): + if n <= 0x0f: + return self._buffer.write(struct.pack('B', 0x90 + n)) + if n <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xdc, n)) + if n <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xdd, n)) + raise PackValueError("Array is too large") + + def _pack_map_header(self, n): + if n <= 0x0f: + return self._buffer.write(struct.pack('B', 0x80 + n)) + if n <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xde, n)) + if n <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xdf, n)) + raise PackValueError("Dict is too large") + + def _pack_map_pairs(self, n, pairs, nest_limit=DEFAULT_RECURSE_LIMIT): + self._pack_map_header(n) + for (k, v) in pairs: + self._pack(k, nest_limit - 1) + self._pack(v, nest_limit - 1) + + def _pack_raw_header(self, n): + if n <= 0x1f: + self._buffer.write(struct.pack('B', 0xa0 + n)) + elif self._use_bin_type and n <= 0xff: + self._buffer.write(struct.pack('>BB', 0xd9, n)) + elif n <= 0xffff: + self._buffer.write(struct.pack(">BH", 0xda, n)) + elif n <= 0xffffffff: + self._buffer.write(struct.pack(">BI", 0xdb, n)) + else: + raise PackValueError('Raw is too large') + + def _pack_bin_header(self, n): + if not self._use_bin_type: + return self._pack_raw_header(n) + elif n <= 0xff: + return self._buffer.write(struct.pack('>BB', 0xc4, n)) + elif n <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xc5, n)) + elif n <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xc6, n)) + else: + raise PackValueError('Bin is too large') + + def bytes(self): + return self._buffer.getvalue() + + def reset(self): + self._buffer = StringIO() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__about__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__about__.py new file mode 100644 index 0000000..4255c5b --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__about__.py @@ -0,0 +1,21 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] + +__title__ = "packaging" +__summary__ = "Core utilities for Python packages" +__uri__ = "https://github.com/pypa/packaging" + +__version__ = "17.1" + +__author__ = "Donald Stufft and individual contributors" +__email__ = "donald@stufft.io" + +__license__ = "BSD or Apache License, Version 2.0" +__copyright__ = "Copyright 2014-2016 %s" % __author__ diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__init__.py new file mode 100644 index 0000000..5ee6220 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__init__.py @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +from .__about__ import ( + __author__, __copyright__, __email__, __license__, __summary__, __title__, + __uri__, __version__ +) + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_compat.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_compat.py new file mode 100644 index 0000000..210bb80 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_compat.py @@ -0,0 +1,30 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import sys + + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +# flake8: noqa + +if PY3: + string_types = str, +else: + string_types = basestring, + + +def with_metaclass(meta, *bases): + """ + Create a base class with a metaclass. + """ + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(meta): + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_structures.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_structures.py new file mode 100644 index 0000000..e9fc4a0 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_structures.py @@ -0,0 +1,70 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + + +class Infinity(object): + + def __repr__(self): + return "Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return False + + def __le__(self, other): + return False + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return True + + def __ge__(self, other): + return True + + def __neg__(self): + return NegativeInfinity + + +Infinity = Infinity() + + +class NegativeInfinity(object): + + def __repr__(self): + return "-Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return True + + def __le__(self, other): + return True + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return False + + def __ge__(self, other): + return False + + def __neg__(self): + return Infinity + + +NegativeInfinity = NegativeInfinity() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/markers.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/markers.py new file mode 100644 index 0000000..e5834ce --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/markers.py @@ -0,0 +1,301 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import operator +import os +import platform +import sys + +from pip._vendor.pyparsing import ParseException, ParseResults, stringStart, stringEnd +from pip._vendor.pyparsing import ZeroOrMore, Group, Forward, QuotedString +from pip._vendor.pyparsing import Literal as L # noqa + +from ._compat import string_types +from .specifiers import Specifier, InvalidSpecifier + + +__all__ = [ + "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName", + "Marker", "default_environment", +] + + +class InvalidMarker(ValueError): + """ + An invalid marker was found, users should refer to PEP 508. + """ + + +class UndefinedComparison(ValueError): + """ + An invalid operation was attempted on a value that doesn't support it. + """ + + +class UndefinedEnvironmentName(ValueError): + """ + A name was attempted to be used that does not exist inside of the + environment. + """ + + +class Node(object): + + def __init__(self, value): + self.value = value + + def __str__(self): + return str(self.value) + + def __repr__(self): + return "<{0}({1!r})>".format(self.__class__.__name__, str(self)) + + def serialize(self): + raise NotImplementedError + + +class Variable(Node): + + def serialize(self): + return str(self) + + +class Value(Node): + + def serialize(self): + return '"{0}"'.format(self) + + +class Op(Node): + + def serialize(self): + return str(self) + + +VARIABLE = ( + L("implementation_version") | + L("platform_python_implementation") | + L("implementation_name") | + L("python_full_version") | + L("platform_release") | + L("platform_version") | + L("platform_machine") | + L("platform_system") | + L("python_version") | + L("sys_platform") | + L("os_name") | + L("os.name") | # PEP-345 + L("sys.platform") | # PEP-345 + L("platform.version") | # PEP-345 + L("platform.machine") | # PEP-345 + L("platform.python_implementation") | # PEP-345 + L("python_implementation") | # undocumented setuptools legacy + L("extra") +) +ALIASES = { + 'os.name': 'os_name', + 'sys.platform': 'sys_platform', + 'platform.version': 'platform_version', + 'platform.machine': 'platform_machine', + 'platform.python_implementation': 'platform_python_implementation', + 'python_implementation': 'platform_python_implementation' +} +VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0]))) + +VERSION_CMP = ( + L("===") | + L("==") | + L(">=") | + L("<=") | + L("!=") | + L("~=") | + L(">") | + L("<") +) + +MARKER_OP = VERSION_CMP | L("not in") | L("in") +MARKER_OP.setParseAction(lambda s, l, t: Op(t[0])) + +MARKER_VALUE = QuotedString("'") | QuotedString('"') +MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0])) + +BOOLOP = L("and") | L("or") + +MARKER_VAR = VARIABLE | MARKER_VALUE + +MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR) +MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0])) + +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() + +MARKER_EXPR = Forward() +MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN) +MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR) + +MARKER = stringStart + MARKER_EXPR + stringEnd + + +def _coerce_parse_result(results): + if isinstance(results, ParseResults): + return [_coerce_parse_result(i) for i in results] + else: + return results + + +def _format_marker(marker, first=True): + assert isinstance(marker, (list, tuple, string_types)) + + # Sometimes we have a structure like [[...]] which is a single item list + # where the single item is itself it's own list. In that case we want skip + # the rest of this function so that we don't get extraneous () on the + # outside. + if (isinstance(marker, list) and len(marker) == 1 and + isinstance(marker[0], (list, tuple))): + return _format_marker(marker[0]) + + if isinstance(marker, list): + inner = (_format_marker(m, first=False) for m in marker) + if first: + return " ".join(inner) + else: + return "(" + " ".join(inner) + ")" + elif isinstance(marker, tuple): + return " ".join([m.serialize() for m in marker]) + else: + return marker + + +_operators = { + "in": lambda lhs, rhs: lhs in rhs, + "not in": lambda lhs, rhs: lhs not in rhs, + "<": operator.lt, + "<=": operator.le, + "==": operator.eq, + "!=": operator.ne, + ">=": operator.ge, + ">": operator.gt, +} + + +def _eval_op(lhs, op, rhs): + try: + spec = Specifier("".join([op.serialize(), rhs])) + except InvalidSpecifier: + pass + else: + return spec.contains(lhs) + + oper = _operators.get(op.serialize()) + if oper is None: + raise UndefinedComparison( + "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs) + ) + + return oper(lhs, rhs) + + +_undefined = object() + + +def _get_env(environment, name): + value = environment.get(name, _undefined) + + if value is _undefined: + raise UndefinedEnvironmentName( + "{0!r} does not exist in evaluation environment.".format(name) + ) + + return value + + +def _evaluate_markers(markers, environment): + groups = [[]] + + for marker in markers: + assert isinstance(marker, (list, tuple, string_types)) + + if isinstance(marker, list): + groups[-1].append(_evaluate_markers(marker, environment)) + elif isinstance(marker, tuple): + lhs, op, rhs = marker + + if isinstance(lhs, Variable): + lhs_value = _get_env(environment, lhs.value) + rhs_value = rhs.value + else: + lhs_value = lhs.value + rhs_value = _get_env(environment, rhs.value) + + groups[-1].append(_eval_op(lhs_value, op, rhs_value)) + else: + assert marker in ["and", "or"] + if marker == "or": + groups.append([]) + + return any(all(item) for item in groups) + + +def format_full_version(info): + version = '{0.major}.{0.minor}.{0.micro}'.format(info) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + +def default_environment(): + if hasattr(sys, 'implementation'): + iver = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + iver = '0' + implementation_name = '' + + return { + "implementation_name": implementation_name, + "implementation_version": iver, + "os_name": os.name, + "platform_machine": platform.machine(), + "platform_release": platform.release(), + "platform_system": platform.system(), + "platform_version": platform.version(), + "python_full_version": platform.python_version(), + "platform_python_implementation": platform.python_implementation(), + "python_version": platform.python_version()[:3], + "sys_platform": sys.platform, + } + + +class Marker(object): + + def __init__(self, marker): + try: + self._markers = _coerce_parse_result(MARKER.parseString(marker)) + except ParseException as e: + err_str = "Invalid marker: {0!r}, parse error at {1!r}".format( + marker, marker[e.loc:e.loc + 8]) + raise InvalidMarker(err_str) + + def __str__(self): + return _format_marker(self._markers) + + def __repr__(self): + return "<Marker({0!r})>".format(str(self)) + + def evaluate(self, environment=None): + """Evaluate a marker. + + Return the boolean from evaluating the given marker against the + environment. environment is an optional argument to override all or + part of the determined environment. + + The environment is determined from the current Python process. + """ + current_environment = default_environment() + if environment is not None: + current_environment.update(environment) + + return _evaluate_markers(self._markers, current_environment) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/requirements.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/requirements.py new file mode 100644 index 0000000..2760483 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/requirements.py @@ -0,0 +1,130 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import string +import re + +from pip._vendor.pyparsing import stringStart, stringEnd, originalTextFor, ParseException +from pip._vendor.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine +from pip._vendor.pyparsing import Literal as L # noqa +from pip._vendor.six.moves.urllib import parse as urlparse + +from .markers import MARKER_EXPR, Marker +from .specifiers import LegacySpecifier, Specifier, SpecifierSet + + +class InvalidRequirement(ValueError): + """ + An invalid requirement was found, users should refer to PEP 508. + """ + + +ALPHANUM = Word(string.ascii_letters + string.digits) + +LBRACKET = L("[").suppress() +RBRACKET = L("]").suppress() +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() +COMMA = L(",").suppress() +SEMICOLON = L(";").suppress() +AT = L("@").suppress() + +PUNCTUATION = Word("-_.") +IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) +IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) + +NAME = IDENTIFIER("name") +EXTRA = IDENTIFIER + +URI = Regex(r'[^ ]+')("url") +URL = (AT + URI) + +EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) +EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") + +VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE) +VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE) + +VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY +VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), + joinString=",", adjacent=False)("_raw_spec") +_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) +_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '') + +VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier") +VERSION_SPEC.setParseAction(lambda s, l, t: t[1]) + +MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") +MARKER_EXPR.setParseAction( + lambda s, l, t: Marker(s[t._original_start:t._original_end]) +) +MARKER_SEPARATOR = SEMICOLON +MARKER = MARKER_SEPARATOR + MARKER_EXPR + +VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) +URL_AND_MARKER = URL + Optional(MARKER) + +NAMED_REQUIREMENT = \ + NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) + +REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd +# pyparsing isn't thread safe during initialization, so we do it eagerly, see +# issue #104 +REQUIREMENT.parseString("x[]") + + +class Requirement(object): + """Parse a requirement. + + Parse a given requirement string into its parts, such as name, specifier, + URL, and extras. Raises InvalidRequirement on a badly-formed requirement + string. + """ + + # TODO: Can we test whether something is contained within a requirement? + # If so how do we do that? Do we need to test against the _name_ of + # the thing as well as the version? What about the markers? + # TODO: Can we normalize the name and extra name? + + def __init__(self, requirement_string): + try: + req = REQUIREMENT.parseString(requirement_string) + except ParseException as e: + raise InvalidRequirement( + "Invalid requirement, parse error at \"{0!r}\"".format( + requirement_string[e.loc:e.loc + 8])) + + self.name = req.name + if req.url: + parsed_url = urlparse.urlparse(req.url) + if not (parsed_url.scheme and parsed_url.netloc) or ( + not parsed_url.scheme and not parsed_url.netloc): + raise InvalidRequirement("Invalid URL given") + self.url = req.url + else: + self.url = None + self.extras = set(req.extras.asList() if req.extras else []) + self.specifier = SpecifierSet(req.specifier) + self.marker = req.marker if req.marker else None + + def __str__(self): + parts = [self.name] + + if self.extras: + parts.append("[{0}]".format(",".join(sorted(self.extras)))) + + if self.specifier: + parts.append(str(self.specifier)) + + if self.url: + parts.append("@ {0}".format(self.url)) + + if self.marker: + parts.append("; {0}".format(self.marker)) + + return "".join(parts) + + def __repr__(self): + return "<Requirement({0!r})>".format(str(self)) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/specifiers.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/specifiers.py new file mode 100644 index 0000000..9b6353f --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/specifiers.py @@ -0,0 +1,774 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import abc +import functools +import itertools +import re + +from ._compat import string_types, with_metaclass +from .version import Version, LegacyVersion, parse + + +class InvalidSpecifier(ValueError): + """ + An invalid specifier was found, users should refer to PEP 440. + """ + + +class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): + + @abc.abstractmethod + def __str__(self): + """ + Returns the str representation of this Specifier like object. This + should be representative of the Specifier itself. + """ + + @abc.abstractmethod + def __hash__(self): + """ + Returns a hash value for this Specifier like object. + """ + + @abc.abstractmethod + def __eq__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are equal. + """ + + @abc.abstractmethod + def __ne__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are not equal. + """ + + @abc.abstractproperty + def prereleases(self): + """ + Returns whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @prereleases.setter + def prereleases(self, value): + """ + Sets whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @abc.abstractmethod + def contains(self, item, prereleases=None): + """ + Determines if the given item is contained within this specifier. + """ + + @abc.abstractmethod + def filter(self, iterable, prereleases=None): + """ + Takes an iterable of items and filters them so that only items which + are contained within this specifier are allowed in it. + """ + + +class _IndividualSpecifier(BaseSpecifier): + + _operators = {} + + def __init__(self, spec="", prereleases=None): + match = self._regex.search(spec) + if not match: + raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec)) + + self._spec = ( + match.group("operator").strip(), + match.group("version").strip(), + ) + + # Store whether or not this Specifier should accept prereleases + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<{0}({1!r}{2})>".format( + self.__class__.__name__, + str(self), + pre, + ) + + def __str__(self): + return "{0}{1}".format(*self._spec) + + def __hash__(self): + return hash(self._spec) + + def __eq__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec == other._spec + + def __ne__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec != other._spec + + def _get_operator(self, op): + return getattr(self, "_compare_{0}".format(self._operators[op])) + + def _coerce_version(self, version): + if not isinstance(version, (LegacyVersion, Version)): + version = parse(version) + return version + + @property + def operator(self): + return self._spec[0] + + @property + def version(self): + return self._spec[1] + + @property + def prereleases(self): + return self._prereleases + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # Determine if prereleases are to be allowed or not. + if prereleases is None: + prereleases = self.prereleases + + # Normalize item to a Version or LegacyVersion, this allows us to have + # a shortcut for ``"2.0" in Specifier(">=2") + item = self._coerce_version(item) + + # Determine if we should be supporting prereleases in this specifier + # or not, if we do not support prereleases than we can short circuit + # logic if this version is a prereleases. + if item.is_prerelease and not prereleases: + return False + + # Actually do the comparison to determine if this item is contained + # within this Specifier or not. + return self._get_operator(self.operator)(item, self.version) + + def filter(self, iterable, prereleases=None): + yielded = False + found_prereleases = [] + + kw = {"prereleases": prereleases if prereleases is not None else True} + + # Attempt to iterate over all the values in the iterable and if any of + # them match, yield them. + for version in iterable: + parsed_version = self._coerce_version(version) + + if self.contains(parsed_version, **kw): + # If our version is a prerelease, and we were not set to allow + # prereleases, then we'll store it for later incase nothing + # else matches this specifier. + if (parsed_version.is_prerelease and not + (prereleases or self.prereleases)): + found_prereleases.append(version) + # Either this is not a prerelease, or we should have been + # accepting prereleases from the beginning. + else: + yielded = True + yield version + + # Now that we've iterated over everything, determine if we've yielded + # any values, and if we have not and we have any prereleases stored up + # then we will go ahead and yield the prereleases. + if not yielded and found_prereleases: + for version in found_prereleases: + yield version + + +class LegacySpecifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(==|!=|<=|>=|<|>)) + \s* + (?P<version> + [^,;\s)]* # Since this is a "legacy" specifier, and the version + # string can be just about anything, we match everything + # except for whitespace, a semi-colon for marker support, + # a closing paren since versions can be enclosed in + # them, and a comma since it's a version separator. + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + } + + def _coerce_version(self, version): + if not isinstance(version, LegacyVersion): + version = LegacyVersion(str(version)) + return version + + def _compare_equal(self, prospective, spec): + return prospective == self._coerce_version(spec) + + def _compare_not_equal(self, prospective, spec): + return prospective != self._coerce_version(spec) + + def _compare_less_than_equal(self, prospective, spec): + return prospective <= self._coerce_version(spec) + + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= self._coerce_version(spec) + + def _compare_less_than(self, prospective, spec): + return prospective < self._coerce_version(spec) + + def _compare_greater_than(self, prospective, spec): + return prospective > self._coerce_version(spec) + + +def _require_version_compare(fn): + @functools.wraps(fn) + def wrapped(self, prospective, spec): + if not isinstance(prospective, Version): + return False + return fn(self, prospective, spec) + return wrapped + + +class Specifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(~=|==|!=|<=|>=|<|>|===)) + (?P<version> + (?: + # The identity operators allow for an escape hatch that will + # do an exact string match of the version you wish to install. + # This will not be parsed by PEP 440 and we cannot determine + # any semantic meaning from it. This operator is discouraged + # but included entirely as an escape hatch. + (?<====) # Only match for the identity operator + \s* + [^\s]* # We just match everything, except for whitespace + # since we are only testing for strict identity. + ) + | + (?: + # The (non)equality operators allow for wild card and local + # versions to be specified so we have to define these two + # operators separately to enable that. + (?<===|!=) # Only match for equals and not equals + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + + # You cannot use a wild card and a dev or local version + # together so group them with a | and make them optional. + (?: + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local + | + \.\* # Wild card syntax of .* + )? + ) + | + (?: + # The compatible operator requires at least two digits in the + # release segment. + (?<=~=) # Only match for the compatible operator + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + | + (?: + # All other operators only allow a sub set of what the + # (non)equality operators do. Specifically they do not allow + # local versions to be specified nor do they allow the prefix + # matching wild cards. + (?<!==|!=|~=) # We have special cases for these + # operators so we want to make sure they + # don't match here. + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "~=": "compatible", + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + "===": "arbitrary", + } + + @_require_version_compare + def _compare_compatible(self, prospective, spec): + # Compatible releases have an equivalent combination of >= and ==. That + # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to + # implement this in terms of the other specifiers instead of + # implementing it ourselves. The only thing we need to do is construct + # the other specifiers. + + # We want everything but the last item in the version, but we want to + # ignore post and dev releases and we want to treat the pre-release as + # it's own separate segment. + prefix = ".".join( + list( + itertools.takewhile( + lambda x: (not x.startswith("post") and not + x.startswith("dev")), + _version_split(spec), + ) + )[:-1] + ) + + # Add the prefix notation to the end of our string + prefix += ".*" + + return (self._get_operator(">=")(prospective, spec) and + self._get_operator("==")(prospective, prefix)) + + @_require_version_compare + def _compare_equal(self, prospective, spec): + # We need special logic to handle prefix matching + if spec.endswith(".*"): + # In the case of prefix matching we want to ignore local segment. + prospective = Version(prospective.public) + # Split the spec out by dots, and pretend that there is an implicit + # dot in between a release segment and a pre-release segment. + spec = _version_split(spec[:-2]) # Remove the trailing .* + + # Split the prospective version out by dots, and pretend that there + # is an implicit dot in between a release segment and a pre-release + # segment. + prospective = _version_split(str(prospective)) + + # Shorten the prospective version to be the same length as the spec + # so that we can determine if the specifier is a prefix of the + # prospective version or not. + prospective = prospective[:len(spec)] + + # Pad out our two sides with zeros so that they both equal the same + # length. + spec, prospective = _pad_version(spec, prospective) + else: + # Convert our spec string into a Version + spec = Version(spec) + + # If the specifier does not have a local segment, then we want to + # act as if the prospective version also does not have a local + # segment. + if not spec.local: + prospective = Version(prospective.public) + + return prospective == spec + + @_require_version_compare + def _compare_not_equal(self, prospective, spec): + return not self._compare_equal(prospective, spec) + + @_require_version_compare + def _compare_less_than_equal(self, prospective, spec): + return prospective <= Version(spec) + + @_require_version_compare + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= Version(spec) + + @_require_version_compare + def _compare_less_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # Check to see if the prospective version is less than the spec + # version. If it's not we can short circuit and just return False now + # instead of doing extra unneeded work. + if not prospective < spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a pre-release version, that we do not accept pre-release + # versions for the version mentioned in the specifier (e.g. <3.1 should + # not match 3.1.dev0, but should match 3.0.dev0). + if not spec.is_prerelease and prospective.is_prerelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # less than the spec version *and* it's not a pre-release of the same + # version in the spec. + return True + + @_require_version_compare + def _compare_greater_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # Check to see if the prospective version is greater than the spec + # version. If it's not we can short circuit and just return False now + # instead of doing extra unneeded work. + if not prospective > spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a post-release version, that we do not accept + # post-release versions for the version mentioned in the specifier + # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0). + if not spec.is_postrelease and prospective.is_postrelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # Ensure that we do not allow a local version of the version mentioned + # in the specifier, which is techincally greater than, to match. + if prospective.local is not None: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # greater than the spec version *and* it's not a pre-release of the + # same version in the spec. + return True + + def _compare_arbitrary(self, prospective, spec): + return str(prospective).lower() == str(spec).lower() + + @property + def prereleases(self): + # If there is an explicit prereleases set for this, then we'll just + # blindly use that. + if self._prereleases is not None: + return self._prereleases + + # Look at all of our specifiers and determine if they are inclusive + # operators, and if they are if they are including an explicit + # prerelease. + operator, version = self._spec + if operator in ["==", ">=", "<=", "~=", "==="]: + # The == specifier can include a trailing .*, if it does we + # want to remove before parsing. + if operator == "==" and version.endswith(".*"): + version = version[:-2] + + # Parse the version, and if it is a pre-release than this + # specifier allows pre-releases. + if parse(version).is_prerelease: + return True + + return False + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + +_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$") + + +def _version_split(version): + result = [] + for item in version.split("."): + match = _prefix_regex.search(item) + if match: + result.extend(match.groups()) + else: + result.append(item) + return result + + +def _pad_version(left, right): + left_split, right_split = [], [] + + # Get the release segment of our versions + left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left))) + right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right))) + + # Get the rest of our versions + left_split.append(left[len(left_split[0]):]) + right_split.append(right[len(right_split[0]):]) + + # Insert our padding + left_split.insert( + 1, + ["0"] * max(0, len(right_split[0]) - len(left_split[0])), + ) + right_split.insert( + 1, + ["0"] * max(0, len(left_split[0]) - len(right_split[0])), + ) + + return ( + list(itertools.chain(*left_split)), + list(itertools.chain(*right_split)), + ) + + +class SpecifierSet(BaseSpecifier): + + def __init__(self, specifiers="", prereleases=None): + # Split on , to break each indidivual specifier into it's own item, and + # strip each item to remove leading/trailing whitespace. + specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] + + # Parsed each individual specifier, attempting first to make it a + # Specifier and falling back to a LegacySpecifier. + parsed = set() + for specifier in specifiers: + try: + parsed.add(Specifier(specifier)) + except InvalidSpecifier: + parsed.add(LegacySpecifier(specifier)) + + # Turn our parsed specifiers into a frozen set and save them for later. + self._specs = frozenset(parsed) + + # Store our prereleases value so we can use it later to determine if + # we accept prereleases or not. + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<SpecifierSet({0!r}{1})>".format(str(self), pre) + + def __str__(self): + return ",".join(sorted(str(s) for s in self._specs)) + + def __hash__(self): + return hash(self._specs) + + def __and__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + specifier = SpecifierSet() + specifier._specs = frozenset(self._specs | other._specs) + + if self._prereleases is None and other._prereleases is not None: + specifier._prereleases = other._prereleases + elif self._prereleases is not None and other._prereleases is None: + specifier._prereleases = self._prereleases + elif self._prereleases == other._prereleases: + specifier._prereleases = self._prereleases + else: + raise ValueError( + "Cannot combine SpecifierSets with True and False prerelease " + "overrides." + ) + + return specifier + + def __eq__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs == other._specs + + def __ne__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs != other._specs + + def __len__(self): + return len(self._specs) + + def __iter__(self): + return iter(self._specs) + + @property + def prereleases(self): + # If we have been given an explicit prerelease modifier, then we'll + # pass that through here. + if self._prereleases is not None: + return self._prereleases + + # If we don't have any specifiers, and we don't have a forced value, + # then we'll just return None since we don't know if this should have + # pre-releases or not. + if not self._specs: + return None + + # Otherwise we'll see if any of the given specifiers accept + # prereleases, if any of them do we'll return True, otherwise False. + return any(s.prereleases for s in self._specs) + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # Ensure that our item is a Version or LegacyVersion instance. + if not isinstance(item, (LegacyVersion, Version)): + item = parse(item) + + # Determine if we're forcing a prerelease or not, if we're not forcing + # one for this particular filter call, then we'll use whatever the + # SpecifierSet thinks for whether or not we should support prereleases. + if prereleases is None: + prereleases = self.prereleases + + # We can determine if we're going to allow pre-releases by looking to + # see if any of the underlying items supports them. If none of them do + # and this item is a pre-release then we do not allow it and we can + # short circuit that here. + # Note: This means that 1.0.dev1 would not be contained in something + # like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0 + if not prereleases and item.is_prerelease: + return False + + # We simply dispatch to the underlying specs here to make sure that the + # given version is contained within all of them. + # Note: This use of all() here means that an empty set of specifiers + # will always return True, this is an explicit design decision. + return all( + s.contains(item, prereleases=prereleases) + for s in self._specs + ) + + def filter(self, iterable, prereleases=None): + # Determine if we're forcing a prerelease or not, if we're not forcing + # one for this particular filter call, then we'll use whatever the + # SpecifierSet thinks for whether or not we should support prereleases. + if prereleases is None: + prereleases = self.prereleases + + # If we have any specifiers, then we want to wrap our iterable in the + # filter method for each one, this will act as a logical AND amongst + # each specifier. + if self._specs: + for spec in self._specs: + iterable = spec.filter(iterable, prereleases=bool(prereleases)) + return iterable + # If we do not have any specifiers, then we need to have a rough filter + # which will filter out any pre-releases, unless there are no final + # releases, and which will filter out LegacyVersion in general. + else: + filtered = [] + found_prereleases = [] + + for item in iterable: + # Ensure that we some kind of Version class for this item. + if not isinstance(item, (LegacyVersion, Version)): + parsed_version = parse(item) + else: + parsed_version = item + + # Filter out any item which is parsed as a LegacyVersion + if isinstance(parsed_version, LegacyVersion): + continue + + # Store any item which is a pre-release for later unless we've + # already found a final version or we are accepting prereleases + if parsed_version.is_prerelease and not prereleases: + if not filtered: + found_prereleases.append(item) + else: + filtered.append(item) + + # If we've found no items except for pre-releases, then we'll go + # ahead and use the pre-releases + if not filtered and found_prereleases and prereleases is None: + return found_prereleases + + return filtered diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/utils.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/utils.py new file mode 100644 index 0000000..4b94a82 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/utils.py @@ -0,0 +1,63 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import re + +from .version import InvalidVersion, Version + + +_canonicalize_regex = re.compile(r"[-_.]+") + + +def canonicalize_name(name): + # This is taken from PEP 503. + return _canonicalize_regex.sub("-", name).lower() + + +def canonicalize_version(version): + """ + This is very similar to Version.__str__, but has one subtle differences + with the way it handles the release segment. + """ + + try: + version = Version(version) + except InvalidVersion: + # Legacy versions cannot be normalized + return version + + parts = [] + + # Epoch + if version.epoch != 0: + parts.append("{0}!".format(version.epoch)) + + # Release segment + # NB: This strips trailing '.0's to normalize + parts.append( + re.sub( + r'(\.0)+$', + '', + ".".join(str(x) for x in version.release) + ) + ) + + # Pre-release + if version.pre is not None: + parts.append("".join(str(x) for x in version.pre)) + + # Post-release + if version.post is not None: + parts.append(".post{0}".format(version.post)) + + # Development release + if version.dev is not None: + parts.append(".dev{0}".format(version.dev)) + + # Local version segment + if version.local is not None: + parts.append("+{0}".format(version.local)) + + return "".join(parts) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/version.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/version.py new file mode 100644 index 0000000..6ed5cbb --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/version.py @@ -0,0 +1,441 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import collections +import itertools +import re + +from ._structures import Infinity + + +__all__ = [ + "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN" +] + + +_Version = collections.namedtuple( + "_Version", + ["epoch", "release", "dev", "pre", "post", "local"], +) + + +def parse(version): + """ + Parse the given version string and return either a :class:`Version` object + or a :class:`LegacyVersion` object depending on if the given version is + a valid PEP 440 version or a legacy version. + """ + try: + return Version(version) + except InvalidVersion: + return LegacyVersion(version) + + +class InvalidVersion(ValueError): + """ + An invalid version was found, users should refer to PEP 440. + """ + + +class _BaseVersion(object): + + def __hash__(self): + return hash(self._key) + + def __lt__(self, other): + return self._compare(other, lambda s, o: s < o) + + def __le__(self, other): + return self._compare(other, lambda s, o: s <= o) + + def __eq__(self, other): + return self._compare(other, lambda s, o: s == o) + + def __ge__(self, other): + return self._compare(other, lambda s, o: s >= o) + + def __gt__(self, other): + return self._compare(other, lambda s, o: s > o) + + def __ne__(self, other): + return self._compare(other, lambda s, o: s != o) + + def _compare(self, other, method): + if not isinstance(other, _BaseVersion): + return NotImplemented + + return method(self._key, other._key) + + +class LegacyVersion(_BaseVersion): + + def __init__(self, version): + self._version = str(version) + self._key = _legacy_cmpkey(self._version) + + def __str__(self): + return self._version + + def __repr__(self): + return "<LegacyVersion({0})>".format(repr(str(self))) + + @property + def public(self): + return self._version + + @property + def base_version(self): + return self._version + + @property + def epoch(self): + return -1 + + @property + def release(self): + return None + + @property + def pre(self): + return None + + @property + def post(self): + return None + + @property + def dev(self): + return None + + @property + def local(self): + return None + + @property + def is_prerelease(self): + return False + + @property + def is_postrelease(self): + return False + + @property + def is_devrelease(self): + return False + + +_legacy_version_component_re = re.compile( + r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE, +) + +_legacy_version_replacement_map = { + "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@", +} + + +def _parse_version_parts(s): + for part in _legacy_version_component_re.split(s): + part = _legacy_version_replacement_map.get(part, part) + + if not part or part == ".": + continue + + if part[:1] in "0123456789": + # pad for numeric comparison + yield part.zfill(8) + else: + yield "*" + part + + # ensure that alpha/beta/candidate are before final + yield "*final" + + +def _legacy_cmpkey(version): + # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch + # greater than or equal to 0. This will effectively put the LegacyVersion, + # which uses the defacto standard originally implemented by setuptools, + # as before all PEP 440 versions. + epoch = -1 + + # This scheme is taken from pkg_resources.parse_version setuptools prior to + # it's adoption of the packaging library. + parts = [] + for part in _parse_version_parts(version.lower()): + if part.startswith("*"): + # remove "-" before a prerelease tag + if part < "*final": + while parts and parts[-1] == "*final-": + parts.pop() + + # remove trailing zeros from each series of numeric parts + while parts and parts[-1] == "00000000": + parts.pop() + + parts.append(part) + parts = tuple(parts) + + return epoch, parts + + +# Deliberately not anchored to the start and end of the string, to make it +# easier for 3rd party code to reuse +VERSION_PATTERN = r""" + v? + (?: + (?:(?P<epoch>[0-9]+)!)? # epoch + (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment + (?P<pre> # pre-release + [-_\.]? + (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview)) + [-_\.]? + (?P<pre_n>[0-9]+)? + )? + (?P<post> # post release + (?:-(?P<post_n1>[0-9]+)) + | + (?: + [-_\.]? + (?P<post_l>post|rev|r) + [-_\.]? + (?P<post_n2>[0-9]+)? + ) + )? + (?P<dev> # dev release + [-_\.]? + (?P<dev_l>dev) + [-_\.]? + (?P<dev_n>[0-9]+)? + )? + ) + (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version +""" + + +class Version(_BaseVersion): + + _regex = re.compile( + r"^\s*" + VERSION_PATTERN + r"\s*$", + re.VERBOSE | re.IGNORECASE, + ) + + def __init__(self, version): + # Validate the version and parse it into pieces + match = self._regex.search(version) + if not match: + raise InvalidVersion("Invalid version: '{0}'".format(version)) + + # Store the parsed out pieces of the version + self._version = _Version( + epoch=int(match.group("epoch")) if match.group("epoch") else 0, + release=tuple(int(i) for i in match.group("release").split(".")), + pre=_parse_letter_version( + match.group("pre_l"), + match.group("pre_n"), + ), + post=_parse_letter_version( + match.group("post_l"), + match.group("post_n1") or match.group("post_n2"), + ), + dev=_parse_letter_version( + match.group("dev_l"), + match.group("dev_n"), + ), + local=_parse_local_version(match.group("local")), + ) + + # Generate a key which will be used for sorting + self._key = _cmpkey( + self._version.epoch, + self._version.release, + self._version.pre, + self._version.post, + self._version.dev, + self._version.local, + ) + + def __repr__(self): + return "<Version({0})>".format(repr(str(self))) + + def __str__(self): + parts = [] + + # Epoch + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self.release)) + + # Pre-release + if self.pre is not None: + parts.append("".join(str(x) for x in self.pre)) + + # Post-release + if self.post is not None: + parts.append(".post{0}".format(self.post)) + + # Development release + if self.dev is not None: + parts.append(".dev{0}".format(self.dev)) + + # Local version segment + if self.local is not None: + parts.append("+{0}".format(self.local)) + + return "".join(parts) + + @property + def epoch(self): + return self._version.epoch + + @property + def release(self): + return self._version.release + + @property + def pre(self): + return self._version.pre + + @property + def post(self): + return self._version.post[1] if self._version.post else None + + @property + def dev(self): + return self._version.dev[1] if self._version.dev else None + + @property + def local(self): + if self._version.local: + return ".".join(str(x) for x in self._version.local) + else: + return None + + @property + def public(self): + return str(self).split("+", 1)[0] + + @property + def base_version(self): + parts = [] + + # Epoch + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self.release)) + + return "".join(parts) + + @property + def is_prerelease(self): + return self.dev is not None or self.pre is not None + + @property + def is_postrelease(self): + return self.post is not None + + @property + def is_devrelease(self): + return self.dev is not None + + +def _parse_letter_version(letter, number): + if letter: + # We consider there to be an implicit 0 in a pre-release if there is + # not a numeral associated with it. + if number is None: + number = 0 + + # We normalize any letters to their lower case form + letter = letter.lower() + + # We consider some words to be alternate spellings of other words and + # in those cases we want to normalize the spellings to our preferred + # spelling. + if letter == "alpha": + letter = "a" + elif letter == "beta": + letter = "b" + elif letter in ["c", "pre", "preview"]: + letter = "rc" + elif letter in ["rev", "r"]: + letter = "post" + + return letter, int(number) + if not letter and number: + # We assume if we are given a number, but we are not given a letter + # then this is using the implicit post release syntax (e.g. 1.0-1) + letter = "post" + + return letter, int(number) + + +_local_version_separators = re.compile(r"[\._-]") + + +def _parse_local_version(local): + """ + Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve"). + """ + if local is not None: + return tuple( + part.lower() if not part.isdigit() else int(part) + for part in _local_version_separators.split(local) + ) + + +def _cmpkey(epoch, release, pre, post, dev, local): + # When we compare a release version, we want to compare it with all of the + # trailing zeros removed. So we'll use a reverse the list, drop all the now + # leading zeros until we come to something non zero, then take the rest + # re-reverse it back into the correct order and make it a tuple and use + # that for our sorting key. + release = tuple( + reversed(list( + itertools.dropwhile( + lambda x: x == 0, + reversed(release), + ) + )) + ) + + # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0. + # We'll do this by abusing the pre segment, but we _only_ want to do this + # if there is not a pre or a post segment. If we have one of those then + # the normal sorting rules will handle this case correctly. + if pre is None and post is None and dev is not None: + pre = -Infinity + # Versions without a pre-release (except as noted above) should sort after + # those with one. + elif pre is None: + pre = Infinity + + # Versions without a post segment should sort before those with one. + if post is None: + post = -Infinity + + # Versions without a development segment should sort after those with one. + if dev is None: + dev = Infinity + + if local is None: + # Versions without a local segment should sort before those with one. + local = -Infinity + else: + # Versions with a local segment need that segment parsed to implement + # the sorting rules in PEP440. + # - Alpha numeric segments sort before numeric segments + # - Alpha numeric segments sort lexicographically + # - Numeric segments sort numerically + # - Shorter versions sort before longer versions when the prefixes + # match exactly + local = tuple( + (i, "") if isinstance(i, int) else (-Infinity, i) + for i in local + ) + + return epoch, release, pre, post, dev, local diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/__init__.py new file mode 100644 index 0000000..19d3d05 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/__init__.py @@ -0,0 +1,3125 @@ +# coding: utf-8 +""" +Package resource API +-------------------- + +A resource is a logical file contained within a package, or a logical +subdirectory thereof. The package resource API expects resource names +to have their path parts separated with ``/``, *not* whatever the local +path separator is. Do not use os.path operations to manipulate resource +names being passed into the API. + +The package resource API is designed to work with normal filesystem packages, +.egg files, and unpacked .egg files. It can also work in a limited way with +.zip files and with custom PEP 302 loaders that support the ``get_data()`` +method. +""" + +from __future__ import absolute_import + +import sys +import os +import io +import time +import re +import types +import zipfile +import zipimport +import warnings +import stat +import functools +import pkgutil +import operator +import platform +import collections +import plistlib +import email.parser +import errno +import tempfile +import textwrap +import itertools +import inspect +from pkgutil import get_importer + +try: + import _imp +except ImportError: + # Python 3.2 compatibility + import imp as _imp + +from pip._vendor import six +from pip._vendor.six.moves import urllib, map, filter + +# capture these to bypass sandboxing +from os import utime +try: + from os import mkdir, rename, unlink + WRITE_SUPPORT = True +except ImportError: + # no write support, probably under GAE + WRITE_SUPPORT = False + +from os import open as os_open +from os.path import isdir, split + +try: + import importlib.machinery as importlib_machinery + # access attribute to force import under delayed import mechanisms. + importlib_machinery.__name__ +except ImportError: + importlib_machinery = None + +from . import py31compat +from pip._vendor import appdirs +from pip._vendor import packaging +__import__('pip._vendor.packaging.version') +__import__('pip._vendor.packaging.specifiers') +__import__('pip._vendor.packaging.requirements') +__import__('pip._vendor.packaging.markers') + + +if (3, 0) < sys.version_info < (3, 3): + raise RuntimeError("Python 3.3 or later is required") + +if six.PY2: + # Those builtin exceptions are only defined in Python 3 + PermissionError = None + NotADirectoryError = None + +# declare some globals that will be defined later to +# satisfy the linters. +require = None +working_set = None +add_activation_listener = None +resources_stream = None +cleanup_resources = None +resource_dir = None +resource_stream = None +set_extraction_path = None +resource_isdir = None +resource_string = None +iter_entry_points = None +resource_listdir = None +resource_filename = None +resource_exists = None +_distribution_finders = None +_namespace_handlers = None +_namespace_packages = None + + +class PEP440Warning(RuntimeWarning): + """ + Used when there is an issue with a version or specifier not complying with + PEP 440. + """ + + +def parse_version(v): + try: + return packaging.version.Version(v) + except packaging.version.InvalidVersion: + return packaging.version.LegacyVersion(v) + + +_state_vars = {} + + +def _declare_state(vartype, **kw): + globals().update(kw) + _state_vars.update(dict.fromkeys(kw, vartype)) + + +def __getstate__(): + state = {} + g = globals() + for k, v in _state_vars.items(): + state[k] = g['_sget_' + v](g[k]) + return state + + +def __setstate__(state): + g = globals() + for k, v in state.items(): + g['_sset_' + _state_vars[k]](k, g[k], v) + return state + + +def _sget_dict(val): + return val.copy() + + +def _sset_dict(key, ob, state): + ob.clear() + ob.update(state) + + +def _sget_object(val): + return val.__getstate__() + + +def _sset_object(key, ob, state): + ob.__setstate__(state) + + +_sget_none = _sset_none = lambda *args: None + + +def get_supported_platform(): + """Return this platform's maximum compatible version. + + distutils.util.get_platform() normally reports the minimum version + of Mac OS X that would be required to *use* extensions produced by + distutils. But what we want when checking compatibility is to know the + version of Mac OS X that we are *running*. To allow usage of packages that + explicitly require a newer version of Mac OS X, we must also know the + current version of the OS. + + If this condition occurs for any other platform with a version in its + platform strings, this function should be extended accordingly. + """ + plat = get_build_platform() + m = macosVersionString.match(plat) + if m is not None and sys.platform == "darwin": + try: + plat = 'macosx-%s-%s' % ('.'.join(_macosx_vers()[:2]), m.group(3)) + except ValueError: + # not Mac OS X + pass + return plat + + +__all__ = [ + # Basic resource access and distribution/entry point discovery + 'require', 'run_script', 'get_provider', 'get_distribution', + 'load_entry_point', 'get_entry_map', 'get_entry_info', + 'iter_entry_points', + 'resource_string', 'resource_stream', 'resource_filename', + 'resource_listdir', 'resource_exists', 'resource_isdir', + + # Environmental control + 'declare_namespace', 'working_set', 'add_activation_listener', + 'find_distributions', 'set_extraction_path', 'cleanup_resources', + 'get_default_cache', + + # Primary implementation classes + 'Environment', 'WorkingSet', 'ResourceManager', + 'Distribution', 'Requirement', 'EntryPoint', + + # Exceptions + 'ResolutionError', 'VersionConflict', 'DistributionNotFound', + 'UnknownExtra', 'ExtractionError', + + # Warnings + 'PEP440Warning', + + # Parsing functions and string utilities + 'parse_requirements', 'parse_version', 'safe_name', 'safe_version', + 'get_platform', 'compatible_platforms', 'yield_lines', 'split_sections', + 'safe_extra', 'to_filename', 'invalid_marker', 'evaluate_marker', + + # filesystem utilities + 'ensure_directory', 'normalize_path', + + # Distribution "precedence" constants + 'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'DEVELOP_DIST', + + # "Provider" interfaces, implementations, and registration/lookup APIs + 'IMetadataProvider', 'IResourceProvider', 'FileMetadata', + 'PathMetadata', 'EggMetadata', 'EmptyProvider', 'empty_provider', + 'NullProvider', 'EggProvider', 'DefaultProvider', 'ZipProvider', + 'register_finder', 'register_namespace_handler', 'register_loader_type', + 'fixup_namespace_packages', 'get_importer', + + # Deprecated/backward compatibility only + 'run_main', 'AvailableDistributions', +] + + +class ResolutionError(Exception): + """Abstract base for dependency resolution errors""" + + def __repr__(self): + return self.__class__.__name__ + repr(self.args) + + +class VersionConflict(ResolutionError): + """ + An already-installed version conflicts with the requested version. + + Should be initialized with the installed Distribution and the requested + Requirement. + """ + + _template = "{self.dist} is installed but {self.req} is required" + + @property + def dist(self): + return self.args[0] + + @property + def req(self): + return self.args[1] + + def report(self): + return self._template.format(**locals()) + + def with_context(self, required_by): + """ + If required_by is non-empty, return a version of self that is a + ContextualVersionConflict. + """ + if not required_by: + return self + args = self.args + (required_by,) + return ContextualVersionConflict(*args) + + +class ContextualVersionConflict(VersionConflict): + """ + A VersionConflict that accepts a third parameter, the set of the + requirements that required the installed Distribution. + """ + + _template = VersionConflict._template + ' by {self.required_by}' + + @property + def required_by(self): + return self.args[2] + + +class DistributionNotFound(ResolutionError): + """A requested distribution was not found""" + + _template = ("The '{self.req}' distribution was not found " + "and is required by {self.requirers_str}") + + @property + def req(self): + return self.args[0] + + @property + def requirers(self): + return self.args[1] + + @property + def requirers_str(self): + if not self.requirers: + return 'the application' + return ', '.join(self.requirers) + + def report(self): + return self._template.format(**locals()) + + def __str__(self): + return self.report() + + +class UnknownExtra(ResolutionError): + """Distribution doesn't have an "extra feature" of the given name""" + + +_provider_factories = {} + +PY_MAJOR = sys.version[:3] +EGG_DIST = 3 +BINARY_DIST = 2 +SOURCE_DIST = 1 +CHECKOUT_DIST = 0 +DEVELOP_DIST = -1 + + +def register_loader_type(loader_type, provider_factory): + """Register `provider_factory` to make providers for `loader_type` + + `loader_type` is the type or class of a PEP 302 ``module.__loader__``, + and `provider_factory` is a function that, passed a *module* object, + returns an ``IResourceProvider`` for that module. + """ + _provider_factories[loader_type] = provider_factory + + +def get_provider(moduleOrReq): + """Return an IResourceProvider for the named module or requirement""" + if isinstance(moduleOrReq, Requirement): + return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0] + try: + module = sys.modules[moduleOrReq] + except KeyError: + __import__(moduleOrReq) + module = sys.modules[moduleOrReq] + loader = getattr(module, '__loader__', None) + return _find_adapter(_provider_factories, loader)(module) + + +def _macosx_vers(_cache=[]): + if not _cache: + version = platform.mac_ver()[0] + # fallback for MacPorts + if version == '': + plist = '/System/Library/CoreServices/SystemVersion.plist' + if os.path.exists(plist): + if hasattr(plistlib, 'readPlist'): + plist_content = plistlib.readPlist(plist) + if 'ProductVersion' in plist_content: + version = plist_content['ProductVersion'] + + _cache.append(version.split('.')) + return _cache[0] + + +def _macosx_arch(machine): + return {'PowerPC': 'ppc', 'Power_Macintosh': 'ppc'}.get(machine, machine) + + +def get_build_platform(): + """Return this platform's string for platform-specific distributions + + XXX Currently this is the same as ``distutils.util.get_platform()``, but it + needs some hacks for Linux and Mac OS X. + """ + try: + # Python 2.7 or >=3.2 + from sysconfig import get_platform + except ImportError: + from distutils.util import get_platform + + plat = get_platform() + if sys.platform == "darwin" and not plat.startswith('macosx-'): + try: + version = _macosx_vers() + machine = os.uname()[4].replace(" ", "_") + return "macosx-%d.%d-%s" % ( + int(version[0]), int(version[1]), + _macosx_arch(machine), + ) + except ValueError: + # if someone is running a non-Mac darwin system, this will fall + # through to the default implementation + pass + return plat + + +macosVersionString = re.compile(r"macosx-(\d+)\.(\d+)-(.*)") +darwinVersionString = re.compile(r"darwin-(\d+)\.(\d+)\.(\d+)-(.*)") +# XXX backward compat +get_platform = get_build_platform + + +def compatible_platforms(provided, required): + """Can code for the `provided` platform run on the `required` platform? + + Returns true if either platform is ``None``, or the platforms are equal. + + XXX Needs compatibility checks for Linux and other unixy OSes. + """ + if provided is None or required is None or provided == required: + # easy case + return True + + # Mac OS X special cases + reqMac = macosVersionString.match(required) + if reqMac: + provMac = macosVersionString.match(provided) + + # is this a Mac package? + if not provMac: + # this is backwards compatibility for packages built before + # setuptools 0.6. All packages built after this point will + # use the new macosx designation. + provDarwin = darwinVersionString.match(provided) + if provDarwin: + dversion = int(provDarwin.group(1)) + macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2)) + if dversion == 7 and macosversion >= "10.3" or \ + dversion == 8 and macosversion >= "10.4": + return True + # egg isn't macosx or legacy darwin + return False + + # are they the same major version and machine type? + if provMac.group(1) != reqMac.group(1) or \ + provMac.group(3) != reqMac.group(3): + return False + + # is the required OS major update >= the provided one? + if int(provMac.group(2)) > int(reqMac.group(2)): + return False + + return True + + # XXX Linux and other platforms' special cases should go here + return False + + +def run_script(dist_spec, script_name): + """Locate distribution `dist_spec` and run its `script_name` script""" + ns = sys._getframe(1).f_globals + name = ns['__name__'] + ns.clear() + ns['__name__'] = name + require(dist_spec)[0].run_script(script_name, ns) + + +# backward compatibility +run_main = run_script + + +def get_distribution(dist): + """Return a current distribution object for a Requirement or string""" + if isinstance(dist, six.string_types): + dist = Requirement.parse(dist) + if isinstance(dist, Requirement): + dist = get_provider(dist) + if not isinstance(dist, Distribution): + raise TypeError("Expected string, Requirement, or Distribution", dist) + return dist + + +def load_entry_point(dist, group, name): + """Return `name` entry point of `group` for `dist` or raise ImportError""" + return get_distribution(dist).load_entry_point(group, name) + + +def get_entry_map(dist, group=None): + """Return the entry point map for `group`, or the full entry map""" + return get_distribution(dist).get_entry_map(group) + + +def get_entry_info(dist, group, name): + """Return the EntryPoint object for `group`+`name`, or ``None``""" + return get_distribution(dist).get_entry_info(group, name) + + +class IMetadataProvider: + def has_metadata(name): + """Does the package's distribution contain the named metadata?""" + + def get_metadata(name): + """The named metadata resource as a string""" + + def get_metadata_lines(name): + """Yield named metadata resource as list of non-blank non-comment lines + + Leading and trailing whitespace is stripped from each line, and lines + with ``#`` as the first non-blank character are omitted.""" + + def metadata_isdir(name): + """Is the named metadata a directory? (like ``os.path.isdir()``)""" + + def metadata_listdir(name): + """List of metadata names in the directory (like ``os.listdir()``)""" + + def run_script(script_name, namespace): + """Execute the named script in the supplied namespace dictionary""" + + +class IResourceProvider(IMetadataProvider): + """An object that provides access to package resources""" + + def get_resource_filename(manager, resource_name): + """Return a true filesystem path for `resource_name` + + `manager` must be an ``IResourceManager``""" + + def get_resource_stream(manager, resource_name): + """Return a readable file-like object for `resource_name` + + `manager` must be an ``IResourceManager``""" + + def get_resource_string(manager, resource_name): + """Return a string containing the contents of `resource_name` + + `manager` must be an ``IResourceManager``""" + + def has_resource(resource_name): + """Does the package contain the named resource?""" + + def resource_isdir(resource_name): + """Is the named resource a directory? (like ``os.path.isdir()``)""" + + def resource_listdir(resource_name): + """List of resource names in the directory (like ``os.listdir()``)""" + + +class WorkingSet(object): + """A collection of active distributions on sys.path (or a similar list)""" + + def __init__(self, entries=None): + """Create working set from list of path entries (default=sys.path)""" + self.entries = [] + self.entry_keys = {} + self.by_key = {} + self.callbacks = [] + + if entries is None: + entries = sys.path + + for entry in entries: + self.add_entry(entry) + + @classmethod + def _build_master(cls): + """ + Prepare the master working set. + """ + ws = cls() + try: + from __main__ import __requires__ + except ImportError: + # The main program does not list any requirements + return ws + + # ensure the requirements are met + try: + ws.require(__requires__) + except VersionConflict: + return cls._build_from_requirements(__requires__) + + return ws + + @classmethod + def _build_from_requirements(cls, req_spec): + """ + Build a working set from a requirement spec. Rewrites sys.path. + """ + # try it without defaults already on sys.path + # by starting with an empty path + ws = cls([]) + reqs = parse_requirements(req_spec) + dists = ws.resolve(reqs, Environment()) + for dist in dists: + ws.add(dist) + + # add any missing entries from sys.path + for entry in sys.path: + if entry not in ws.entries: + ws.add_entry(entry) + + # then copy back to sys.path + sys.path[:] = ws.entries + return ws + + def add_entry(self, entry): + """Add a path item to ``.entries``, finding any distributions on it + + ``find_distributions(entry, True)`` is used to find distributions + corresponding to the path entry, and they are added. `entry` is + always appended to ``.entries``, even if it is already present. + (This is because ``sys.path`` can contain the same value more than + once, and the ``.entries`` of the ``sys.path`` WorkingSet should always + equal ``sys.path``.) + """ + self.entry_keys.setdefault(entry, []) + self.entries.append(entry) + for dist in find_distributions(entry, True): + self.add(dist, entry, False) + + def __contains__(self, dist): + """True if `dist` is the active distribution for its project""" + return self.by_key.get(dist.key) == dist + + def find(self, req): + """Find a distribution matching requirement `req` + + If there is an active distribution for the requested project, this + returns it as long as it meets the version requirement specified by + `req`. But, if there is an active distribution for the project and it + does *not* meet the `req` requirement, ``VersionConflict`` is raised. + If there is no active distribution for the requested project, ``None`` + is returned. + """ + dist = self.by_key.get(req.key) + if dist is not None and dist not in req: + # XXX add more info + raise VersionConflict(dist, req) + return dist + + def iter_entry_points(self, group, name=None): + """Yield entry point objects from `group` matching `name` + + If `name` is None, yields all entry points in `group` from all + distributions in the working set, otherwise only ones matching + both `group` and `name` are yielded (in distribution order). + """ + for dist in self: + entries = dist.get_entry_map(group) + if name is None: + for ep in entries.values(): + yield ep + elif name in entries: + yield entries[name] + + def run_script(self, requires, script_name): + """Locate distribution for `requires` and run `script_name` script""" + ns = sys._getframe(1).f_globals + name = ns['__name__'] + ns.clear() + ns['__name__'] = name + self.require(requires)[0].run_script(script_name, ns) + + def __iter__(self): + """Yield distributions for non-duplicate projects in the working set + + The yield order is the order in which the items' path entries were + added to the working set. + """ + seen = {} + for item in self.entries: + if item not in self.entry_keys: + # workaround a cache issue + continue + + for key in self.entry_keys[item]: + if key not in seen: + seen[key] = 1 + yield self.by_key[key] + + def add(self, dist, entry=None, insert=True, replace=False): + """Add `dist` to working set, associated with `entry` + + If `entry` is unspecified, it defaults to the ``.location`` of `dist`. + On exit from this routine, `entry` is added to the end of the working + set's ``.entries`` (if it wasn't already present). + + `dist` is only added to the working set if it's for a project that + doesn't already have a distribution in the set, unless `replace=True`. + If it's added, any callbacks registered with the ``subscribe()`` method + will be called. + """ + if insert: + dist.insert_on(self.entries, entry, replace=replace) + + if entry is None: + entry = dist.location + keys = self.entry_keys.setdefault(entry, []) + keys2 = self.entry_keys.setdefault(dist.location, []) + if not replace and dist.key in self.by_key: + # ignore hidden distros + return + + self.by_key[dist.key] = dist + if dist.key not in keys: + keys.append(dist.key) + if dist.key not in keys2: + keys2.append(dist.key) + self._added_new(dist) + + def resolve(self, requirements, env=None, installer=None, + replace_conflicting=False, extras=None): + """List all distributions needed to (recursively) meet `requirements` + + `requirements` must be a sequence of ``Requirement`` objects. `env`, + if supplied, should be an ``Environment`` instance. If + not supplied, it defaults to all distributions available within any + entry or distribution in the working set. `installer`, if supplied, + will be invoked with each requirement that cannot be met by an + already-installed distribution; it should return a ``Distribution`` or + ``None``. + + Unless `replace_conflicting=True`, raises a VersionConflict exception + if + any requirements are found on the path that have the correct name but + the wrong version. Otherwise, if an `installer` is supplied it will be + invoked to obtain the correct version of the requirement and activate + it. + + `extras` is a list of the extras to be used with these requirements. + This is important because extra requirements may look like `my_req; + extra = "my_extra"`, which would otherwise be interpreted as a purely + optional requirement. Instead, we want to be able to assert that these + requirements are truly required. + """ + + # set up the stack + requirements = list(requirements)[::-1] + # set of processed requirements + processed = {} + # key -> dist + best = {} + to_activate = [] + + req_extras = _ReqExtras() + + # Mapping of requirement to set of distributions that required it; + # useful for reporting info about conflicts. + required_by = collections.defaultdict(set) + + while requirements: + # process dependencies breadth-first + req = requirements.pop(0) + if req in processed: + # Ignore cyclic or redundant dependencies + continue + + if not req_extras.markers_pass(req, extras): + continue + + dist = best.get(req.key) + if dist is None: + # Find the best distribution and add it to the map + dist = self.by_key.get(req.key) + if dist is None or (dist not in req and replace_conflicting): + ws = self + if env is None: + if dist is None: + env = Environment(self.entries) + else: + # Use an empty environment and workingset to avoid + # any further conflicts with the conflicting + # distribution + env = Environment([]) + ws = WorkingSet([]) + dist = best[req.key] = env.best_match( + req, ws, installer, + replace_conflicting=replace_conflicting + ) + if dist is None: + requirers = required_by.get(req, None) + raise DistributionNotFound(req, requirers) + to_activate.append(dist) + if dist not in req: + # Oops, the "best" so far conflicts with a dependency + dependent_req = required_by[req] + raise VersionConflict(dist, req).with_context(dependent_req) + + # push the new requirements onto the stack + new_requirements = dist.requires(req.extras)[::-1] + requirements.extend(new_requirements) + + # Register the new requirements needed by req + for new_requirement in new_requirements: + required_by[new_requirement].add(req.project_name) + req_extras[new_requirement] = req.extras + + processed[req] = True + + # return list of distros to activate + return to_activate + + def find_plugins( + self, plugin_env, full_env=None, installer=None, fallback=True): + """Find all activatable distributions in `plugin_env` + + Example usage:: + + distributions, errors = working_set.find_plugins( + Environment(plugin_dirlist) + ) + # add plugins+libs to sys.path + map(working_set.add, distributions) + # display errors + print('Could not load', errors) + + The `plugin_env` should be an ``Environment`` instance that contains + only distributions that are in the project's "plugin directory" or + directories. The `full_env`, if supplied, should be an ``Environment`` + contains all currently-available distributions. If `full_env` is not + supplied, one is created automatically from the ``WorkingSet`` this + method is called on, which will typically mean that every directory on + ``sys.path`` will be scanned for distributions. + + `installer` is a standard installer callback as used by the + ``resolve()`` method. The `fallback` flag indicates whether we should + attempt to resolve older versions of a plugin if the newest version + cannot be resolved. + + This method returns a 2-tuple: (`distributions`, `error_info`), where + `distributions` is a list of the distributions found in `plugin_env` + that were loadable, along with any other distributions that are needed + to resolve their dependencies. `error_info` is a dictionary mapping + unloadable plugin distributions to an exception instance describing the + error that occurred. Usually this will be a ``DistributionNotFound`` or + ``VersionConflict`` instance. + """ + + plugin_projects = list(plugin_env) + # scan project names in alphabetic order + plugin_projects.sort() + + error_info = {} + distributions = {} + + if full_env is None: + env = Environment(self.entries) + env += plugin_env + else: + env = full_env + plugin_env + + shadow_set = self.__class__([]) + # put all our entries in shadow_set + list(map(shadow_set.add, self)) + + for project_name in plugin_projects: + + for dist in plugin_env[project_name]: + + req = [dist.as_requirement()] + + try: + resolvees = shadow_set.resolve(req, env, installer) + + except ResolutionError as v: + # save error info + error_info[dist] = v + if fallback: + # try the next older version of project + continue + else: + # give up on this project, keep going + break + + else: + list(map(shadow_set.add, resolvees)) + distributions.update(dict.fromkeys(resolvees)) + + # success, no need to try any more versions of this project + break + + distributions = list(distributions) + distributions.sort() + + return distributions, error_info + + def require(self, *requirements): + """Ensure that distributions matching `requirements` are activated + + `requirements` must be a string or a (possibly-nested) sequence + thereof, specifying the distributions and versions required. The + return value is a sequence of the distributions that needed to be + activated to fulfill the requirements; all relevant distributions are + included, even if they were already activated in this working set. + """ + needed = self.resolve(parse_requirements(requirements)) + + for dist in needed: + self.add(dist) + + return needed + + def subscribe(self, callback, existing=True): + """Invoke `callback` for all distributions + + If `existing=True` (default), + call on all existing ones, as well. + """ + if callback in self.callbacks: + return + self.callbacks.append(callback) + if not existing: + return + for dist in self: + callback(dist) + + def _added_new(self, dist): + for callback in self.callbacks: + callback(dist) + + def __getstate__(self): + return ( + self.entries[:], self.entry_keys.copy(), self.by_key.copy(), + self.callbacks[:] + ) + + def __setstate__(self, e_k_b_c): + entries, keys, by_key, callbacks = e_k_b_c + self.entries = entries[:] + self.entry_keys = keys.copy() + self.by_key = by_key.copy() + self.callbacks = callbacks[:] + + +class _ReqExtras(dict): + """ + Map each requirement to the extras that demanded it. + """ + + def markers_pass(self, req, extras=None): + """ + Evaluate markers for req against each extra that + demanded it. + + Return False if the req has a marker and fails + evaluation. Otherwise, return True. + """ + extra_evals = ( + req.marker.evaluate({'extra': extra}) + for extra in self.get(req, ()) + (extras or (None,)) + ) + return not req.marker or any(extra_evals) + + +class Environment(object): + """Searchable snapshot of distributions on a search path""" + + def __init__( + self, search_path=None, platform=get_supported_platform(), + python=PY_MAJOR): + """Snapshot distributions available on a search path + + Any distributions found on `search_path` are added to the environment. + `search_path` should be a sequence of ``sys.path`` items. If not + supplied, ``sys.path`` is used. + + `platform` is an optional string specifying the name of the platform + that platform-specific distributions must be compatible with. If + unspecified, it defaults to the current platform. `python` is an + optional string naming the desired version of Python (e.g. ``'3.3'``); + it defaults to the current version. + + You may explicitly set `platform` (and/or `python`) to ``None`` if you + wish to map *all* distributions, not just those compatible with the + running platform or Python version. + """ + self._distmap = {} + self.platform = platform + self.python = python + self.scan(search_path) + + def can_add(self, dist): + """Is distribution `dist` acceptable for this environment? + + The distribution must match the platform and python version + requirements specified when this environment was created, or False + is returned. + """ + py_compat = ( + self.python is None + or dist.py_version is None + or dist.py_version == self.python + ) + return py_compat and compatible_platforms(dist.platform, self.platform) + + def remove(self, dist): + """Remove `dist` from the environment""" + self._distmap[dist.key].remove(dist) + + def scan(self, search_path=None): + """Scan `search_path` for distributions usable in this environment + + Any distributions found are added to the environment. + `search_path` should be a sequence of ``sys.path`` items. If not + supplied, ``sys.path`` is used. Only distributions conforming to + the platform/python version defined at initialization are added. + """ + if search_path is None: + search_path = sys.path + + for item in search_path: + for dist in find_distributions(item): + self.add(dist) + + def __getitem__(self, project_name): + """Return a newest-to-oldest list of distributions for `project_name` + + Uses case-insensitive `project_name` comparison, assuming all the + project's distributions use their project's name converted to all + lowercase as their key. + + """ + distribution_key = project_name.lower() + return self._distmap.get(distribution_key, []) + + def add(self, dist): + """Add `dist` if we ``can_add()`` it and it has not already been added + """ + if self.can_add(dist) and dist.has_version(): + dists = self._distmap.setdefault(dist.key, []) + if dist not in dists: + dists.append(dist) + dists.sort(key=operator.attrgetter('hashcmp'), reverse=True) + + def best_match( + self, req, working_set, installer=None, replace_conflicting=False): + """Find distribution best matching `req` and usable on `working_set` + + This calls the ``find(req)`` method of the `working_set` to see if a + suitable distribution is already active. (This may raise + ``VersionConflict`` if an unsuitable version of the project is already + active in the specified `working_set`.) If a suitable distribution + isn't active, this method returns the newest distribution in the + environment that meets the ``Requirement`` in `req`. If no suitable + distribution is found, and `installer` is supplied, then the result of + calling the environment's ``obtain(req, installer)`` method will be + returned. + """ + try: + dist = working_set.find(req) + except VersionConflict: + if not replace_conflicting: + raise + dist = None + if dist is not None: + return dist + for dist in self[req.key]: + if dist in req: + return dist + # try to download/install + return self.obtain(req, installer) + + def obtain(self, requirement, installer=None): + """Obtain a distribution matching `requirement` (e.g. via download) + + Obtain a distro that matches requirement (e.g. via download). In the + base ``Environment`` class, this routine just returns + ``installer(requirement)``, unless `installer` is None, in which case + None is returned instead. This method is a hook that allows subclasses + to attempt other ways of obtaining a distribution before falling back + to the `installer` argument.""" + if installer is not None: + return installer(requirement) + + def __iter__(self): + """Yield the unique project names of the available distributions""" + for key in self._distmap.keys(): + if self[key]: + yield key + + def __iadd__(self, other): + """In-place addition of a distribution or environment""" + if isinstance(other, Distribution): + self.add(other) + elif isinstance(other, Environment): + for project in other: + for dist in other[project]: + self.add(dist) + else: + raise TypeError("Can't add %r to environment" % (other,)) + return self + + def __add__(self, other): + """Add an environment or distribution to an environment""" + new = self.__class__([], platform=None, python=None) + for env in self, other: + new += env + return new + + +# XXX backward compatibility +AvailableDistributions = Environment + + +class ExtractionError(RuntimeError): + """An error occurred extracting a resource + + The following attributes are available from instances of this exception: + + manager + The resource manager that raised this exception + + cache_path + The base directory for resource extraction + + original_error + The exception instance that caused extraction to fail + """ + + +class ResourceManager: + """Manage resource extraction and packages""" + extraction_path = None + + def __init__(self): + self.cached_files = {} + + def resource_exists(self, package_or_requirement, resource_name): + """Does the named resource exist?""" + return get_provider(package_or_requirement).has_resource(resource_name) + + def resource_isdir(self, package_or_requirement, resource_name): + """Is the named resource an existing directory?""" + return get_provider(package_or_requirement).resource_isdir( + resource_name + ) + + def resource_filename(self, package_or_requirement, resource_name): + """Return a true filesystem path for specified resource""" + return get_provider(package_or_requirement).get_resource_filename( + self, resource_name + ) + + def resource_stream(self, package_or_requirement, resource_name): + """Return a readable file-like object for specified resource""" + return get_provider(package_or_requirement).get_resource_stream( + self, resource_name + ) + + def resource_string(self, package_or_requirement, resource_name): + """Return specified resource as a string""" + return get_provider(package_or_requirement).get_resource_string( + self, resource_name + ) + + def resource_listdir(self, package_or_requirement, resource_name): + """List the contents of the named resource directory""" + return get_provider(package_or_requirement).resource_listdir( + resource_name + ) + + def extraction_error(self): + """Give an error message for problems extracting file(s)""" + + old_exc = sys.exc_info()[1] + cache_path = self.extraction_path or get_default_cache() + + tmpl = textwrap.dedent(""" + Can't extract file(s) to egg cache + + The following error occurred while trying to extract file(s) + to the Python egg cache: + + {old_exc} + + The Python egg cache directory is currently set to: + + {cache_path} + + Perhaps your account does not have write access to this directory? + You can change the cache directory by setting the PYTHON_EGG_CACHE + environment variable to point to an accessible directory. + """).lstrip() + err = ExtractionError(tmpl.format(**locals())) + err.manager = self + err.cache_path = cache_path + err.original_error = old_exc + raise err + + def get_cache_path(self, archive_name, names=()): + """Return absolute location in cache for `archive_name` and `names` + + The parent directory of the resulting path will be created if it does + not already exist. `archive_name` should be the base filename of the + enclosing egg (which may not be the name of the enclosing zipfile!), + including its ".egg" extension. `names`, if provided, should be a + sequence of path name parts "under" the egg's extraction location. + + This method should only be called by resource providers that need to + obtain an extraction location, and only for names they intend to + extract, as it tracks the generated names for possible cleanup later. + """ + extract_path = self.extraction_path or get_default_cache() + target_path = os.path.join(extract_path, archive_name + '-tmp', *names) + try: + _bypass_ensure_directory(target_path) + except Exception: + self.extraction_error() + + self._warn_unsafe_extraction_path(extract_path) + + self.cached_files[target_path] = 1 + return target_path + + @staticmethod + def _warn_unsafe_extraction_path(path): + """ + If the default extraction path is overridden and set to an insecure + location, such as /tmp, it opens up an opportunity for an attacker to + replace an extracted file with an unauthorized payload. Warn the user + if a known insecure location is used. + + See Distribute #375 for more details. + """ + if os.name == 'nt' and not path.startswith(os.environ['windir']): + # On Windows, permissions are generally restrictive by default + # and temp directories are not writable by other users, so + # bypass the warning. + return + mode = os.stat(path).st_mode + if mode & stat.S_IWOTH or mode & stat.S_IWGRP: + msg = ( + "%s is writable by group/others and vulnerable to attack " + "when " + "used with get_resource_filename. Consider a more secure " + "location (set with .set_extraction_path or the " + "PYTHON_EGG_CACHE environment variable)." % path + ) + warnings.warn(msg, UserWarning) + + def postprocess(self, tempname, filename): + """Perform any platform-specific postprocessing of `tempname` + + This is where Mac header rewrites should be done; other platforms don't + have anything special they should do. + + Resource providers should call this method ONLY after successfully + extracting a compressed resource. They must NOT call it on resources + that are already in the filesystem. + + `tempname` is the current (temporary) name of the file, and `filename` + is the name it will be renamed to by the caller after this routine + returns. + """ + + if os.name == 'posix': + # Make the resource executable + mode = ((os.stat(tempname).st_mode) | 0o555) & 0o7777 + os.chmod(tempname, mode) + + def set_extraction_path(self, path): + """Set the base path where resources will be extracted to, if needed. + + If you do not call this routine before any extractions take place, the + path defaults to the return value of ``get_default_cache()``. (Which + is based on the ``PYTHON_EGG_CACHE`` environment variable, with various + platform-specific fallbacks. See that routine's documentation for more + details.) + + Resources are extracted to subdirectories of this path based upon + information given by the ``IResourceProvider``. You may set this to a + temporary directory, but then you must call ``cleanup_resources()`` to + delete the extracted files when done. There is no guarantee that + ``cleanup_resources()`` will be able to remove all extracted files. + + (Note: you may not change the extraction path for a given resource + manager once resources have been extracted, unless you first call + ``cleanup_resources()``.) + """ + if self.cached_files: + raise ValueError( + "Can't change extraction path, files already extracted" + ) + + self.extraction_path = path + + def cleanup_resources(self, force=False): + """ + Delete all extracted resource files and directories, returning a list + of the file and directory names that could not be successfully removed. + This function does not have any concurrency protection, so it should + generally only be called when the extraction path is a temporary + directory exclusive to a single process. This method is not + automatically called; you must call it explicitly or register it as an + ``atexit`` function if you wish to ensure cleanup of a temporary + directory used for extractions. + """ + # XXX + + +def get_default_cache(): + """ + Return the ``PYTHON_EGG_CACHE`` environment variable + or a platform-relevant user cache dir for an app + named "Python-Eggs". + """ + return ( + os.environ.get('PYTHON_EGG_CACHE') + or appdirs.user_cache_dir(appname='Python-Eggs') + ) + + +def safe_name(name): + """Convert an arbitrary string to a standard distribution name + + Any runs of non-alphanumeric/. characters are replaced with a single '-'. + """ + return re.sub('[^A-Za-z0-9.]+', '-', name) + + +def safe_version(version): + """ + Convert an arbitrary string to a standard version string + """ + try: + # normalize the version + return str(packaging.version.Version(version)) + except packaging.version.InvalidVersion: + version = version.replace(' ', '.') + return re.sub('[^A-Za-z0-9.]+', '-', version) + + +def safe_extra(extra): + """Convert an arbitrary string to a standard 'extra' name + + Any runs of non-alphanumeric characters are replaced with a single '_', + and the result is always lowercased. + """ + return re.sub('[^A-Za-z0-9.-]+', '_', extra).lower() + + +def to_filename(name): + """Convert a project or version name to its filename-escaped form + + Any '-' characters are currently replaced with '_'. + """ + return name.replace('-', '_') + + +def invalid_marker(text): + """ + Validate text as a PEP 508 environment marker; return an exception + if invalid or False otherwise. + """ + try: + evaluate_marker(text) + except SyntaxError as e: + e.filename = None + e.lineno = None + return e + return False + + +def evaluate_marker(text, extra=None): + """ + Evaluate a PEP 508 environment marker. + Return a boolean indicating the marker result in this environment. + Raise SyntaxError if marker is invalid. + + This implementation uses the 'pyparsing' module. + """ + try: + marker = packaging.markers.Marker(text) + return marker.evaluate() + except packaging.markers.InvalidMarker as e: + raise SyntaxError(e) + + +class NullProvider: + """Try to implement resources and metadata for arbitrary PEP 302 loaders""" + + egg_name = None + egg_info = None + loader = None + + def __init__(self, module): + self.loader = getattr(module, '__loader__', None) + self.module_path = os.path.dirname(getattr(module, '__file__', '')) + + def get_resource_filename(self, manager, resource_name): + return self._fn(self.module_path, resource_name) + + def get_resource_stream(self, manager, resource_name): + return io.BytesIO(self.get_resource_string(manager, resource_name)) + + def get_resource_string(self, manager, resource_name): + return self._get(self._fn(self.module_path, resource_name)) + + def has_resource(self, resource_name): + return self._has(self._fn(self.module_path, resource_name)) + + def has_metadata(self, name): + return self.egg_info and self._has(self._fn(self.egg_info, name)) + + def get_metadata(self, name): + if not self.egg_info: + return "" + value = self._get(self._fn(self.egg_info, name)) + return value.decode('utf-8') if six.PY3 else value + + def get_metadata_lines(self, name): + return yield_lines(self.get_metadata(name)) + + def resource_isdir(self, resource_name): + return self._isdir(self._fn(self.module_path, resource_name)) + + def metadata_isdir(self, name): + return self.egg_info and self._isdir(self._fn(self.egg_info, name)) + + def resource_listdir(self, resource_name): + return self._listdir(self._fn(self.module_path, resource_name)) + + def metadata_listdir(self, name): + if self.egg_info: + return self._listdir(self._fn(self.egg_info, name)) + return [] + + def run_script(self, script_name, namespace): + script = 'scripts/' + script_name + if not self.has_metadata(script): + raise ResolutionError( + "Script {script!r} not found in metadata at {self.egg_info!r}" + .format(**locals()), + ) + script_text = self.get_metadata(script).replace('\r\n', '\n') + script_text = script_text.replace('\r', '\n') + script_filename = self._fn(self.egg_info, script) + namespace['__file__'] = script_filename + if os.path.exists(script_filename): + source = open(script_filename).read() + code = compile(source, script_filename, 'exec') + exec(code, namespace, namespace) + else: + from linecache import cache + cache[script_filename] = ( + len(script_text), 0, script_text.split('\n'), script_filename + ) + script_code = compile(script_text, script_filename, 'exec') + exec(script_code, namespace, namespace) + + def _has(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _isdir(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _listdir(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _fn(self, base, resource_name): + if resource_name: + return os.path.join(base, *resource_name.split('/')) + return base + + def _get(self, path): + if hasattr(self.loader, 'get_data'): + return self.loader.get_data(path) + raise NotImplementedError( + "Can't perform this operation for loaders without 'get_data()'" + ) + + +register_loader_type(object, NullProvider) + + +class EggProvider(NullProvider): + """Provider based on a virtual filesystem""" + + def __init__(self, module): + NullProvider.__init__(self, module) + self._setup_prefix() + + def _setup_prefix(self): + # we assume here that our metadata may be nested inside a "basket" + # of multiple eggs; that's why we use module_path instead of .archive + path = self.module_path + old = None + while path != old: + if _is_egg_path(path): + self.egg_name = os.path.basename(path) + self.egg_info = os.path.join(path, 'EGG-INFO') + self.egg_root = path + break + old = path + path, base = os.path.split(path) + + +class DefaultProvider(EggProvider): + """Provides access to package resources in the filesystem""" + + def _has(self, path): + return os.path.exists(path) + + def _isdir(self, path): + return os.path.isdir(path) + + def _listdir(self, path): + return os.listdir(path) + + def get_resource_stream(self, manager, resource_name): + return open(self._fn(self.module_path, resource_name), 'rb') + + def _get(self, path): + with open(path, 'rb') as stream: + return stream.read() + + @classmethod + def _register(cls): + loader_cls = getattr( + importlib_machinery, + 'SourceFileLoader', + type(None), + ) + register_loader_type(loader_cls, cls) + + +DefaultProvider._register() + + +class EmptyProvider(NullProvider): + """Provider that returns nothing for all requests""" + + module_path = None + + _isdir = _has = lambda self, path: False + + def _get(self, path): + return '' + + def _listdir(self, path): + return [] + + def __init__(self): + pass + + +empty_provider = EmptyProvider() + + +class ZipManifests(dict): + """ + zip manifest builder + """ + + @classmethod + def build(cls, path): + """ + Build a dictionary similar to the zipimport directory + caches, except instead of tuples, store ZipInfo objects. + + Use a platform-specific path separator (os.sep) for the path keys + for compatibility with pypy on Windows. + """ + with zipfile.ZipFile(path) as zfile: + items = ( + ( + name.replace('/', os.sep), + zfile.getinfo(name), + ) + for name in zfile.namelist() + ) + return dict(items) + + load = build + + +class MemoizedZipManifests(ZipManifests): + """ + Memoized zipfile manifests. + """ + manifest_mod = collections.namedtuple('manifest_mod', 'manifest mtime') + + def load(self, path): + """ + Load a manifest at path or return a suitable manifest already loaded. + """ + path = os.path.normpath(path) + mtime = os.stat(path).st_mtime + + if path not in self or self[path].mtime != mtime: + manifest = self.build(path) + self[path] = self.manifest_mod(manifest, mtime) + + return self[path].manifest + + +class ZipProvider(EggProvider): + """Resource support for zips and eggs""" + + eagers = None + _zip_manifests = MemoizedZipManifests() + + def __init__(self, module): + EggProvider.__init__(self, module) + self.zip_pre = self.loader.archive + os.sep + + def _zipinfo_name(self, fspath): + # Convert a virtual filename (full path to file) into a zipfile subpath + # usable with the zipimport directory cache for our target archive + fspath = fspath.rstrip(os.sep) + if fspath == self.loader.archive: + return '' + if fspath.startswith(self.zip_pre): + return fspath[len(self.zip_pre):] + raise AssertionError( + "%s is not a subpath of %s" % (fspath, self.zip_pre) + ) + + def _parts(self, zip_path): + # Convert a zipfile subpath into an egg-relative path part list. + # pseudo-fs path + fspath = self.zip_pre + zip_path + if fspath.startswith(self.egg_root + os.sep): + return fspath[len(self.egg_root) + 1:].split(os.sep) + raise AssertionError( + "%s is not a subpath of %s" % (fspath, self.egg_root) + ) + + @property + def zipinfo(self): + return self._zip_manifests.load(self.loader.archive) + + def get_resource_filename(self, manager, resource_name): + if not self.egg_name: + raise NotImplementedError( + "resource_filename() only supported for .egg, not .zip" + ) + # no need to lock for extraction, since we use temp names + zip_path = self._resource_to_zip(resource_name) + eagers = self._get_eager_resources() + if '/'.join(self._parts(zip_path)) in eagers: + for name in eagers: + self._extract_resource(manager, self._eager_to_zip(name)) + return self._extract_resource(manager, zip_path) + + @staticmethod + def _get_date_and_size(zip_stat): + size = zip_stat.file_size + # ymdhms+wday, yday, dst + date_time = zip_stat.date_time + (0, 0, -1) + # 1980 offset already done + timestamp = time.mktime(date_time) + return timestamp, size + + def _extract_resource(self, manager, zip_path): + + if zip_path in self._index(): + for name in self._index()[zip_path]: + last = self._extract_resource( + manager, os.path.join(zip_path, name) + ) + # return the extracted directory name + return os.path.dirname(last) + + timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) + + if not WRITE_SUPPORT: + raise IOError('"os.rename" and "os.unlink" are not supported ' + 'on this platform') + try: + + real_path = manager.get_cache_path( + self.egg_name, self._parts(zip_path) + ) + + if self._is_current(real_path, zip_path): + return real_path + + outf, tmpnam = _mkstemp( + ".$extract", + dir=os.path.dirname(real_path), + ) + os.write(outf, self.loader.get_data(zip_path)) + os.close(outf) + utime(tmpnam, (timestamp, timestamp)) + manager.postprocess(tmpnam, real_path) + + try: + rename(tmpnam, real_path) + + except os.error: + if os.path.isfile(real_path): + if self._is_current(real_path, zip_path): + # the file became current since it was checked above, + # so proceed. + return real_path + # Windows, del old file and retry + elif os.name == 'nt': + unlink(real_path) + rename(tmpnam, real_path) + return real_path + raise + + except os.error: + # report a user-friendly error + manager.extraction_error() + + return real_path + + def _is_current(self, file_path, zip_path): + """ + Return True if the file_path is current for this zip_path + """ + timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) + if not os.path.isfile(file_path): + return False + stat = os.stat(file_path) + if stat.st_size != size or stat.st_mtime != timestamp: + return False + # check that the contents match + zip_contents = self.loader.get_data(zip_path) + with open(file_path, 'rb') as f: + file_contents = f.read() + return zip_contents == file_contents + + def _get_eager_resources(self): + if self.eagers is None: + eagers = [] + for name in ('native_libs.txt', 'eager_resources.txt'): + if self.has_metadata(name): + eagers.extend(self.get_metadata_lines(name)) + self.eagers = eagers + return self.eagers + + def _index(self): + try: + return self._dirindex + except AttributeError: + ind = {} + for path in self.zipinfo: + parts = path.split(os.sep) + while parts: + parent = os.sep.join(parts[:-1]) + if parent in ind: + ind[parent].append(parts[-1]) + break + else: + ind[parent] = [parts.pop()] + self._dirindex = ind + return ind + + def _has(self, fspath): + zip_path = self._zipinfo_name(fspath) + return zip_path in self.zipinfo or zip_path in self._index() + + def _isdir(self, fspath): + return self._zipinfo_name(fspath) in self._index() + + def _listdir(self, fspath): + return list(self._index().get(self._zipinfo_name(fspath), ())) + + def _eager_to_zip(self, resource_name): + return self._zipinfo_name(self._fn(self.egg_root, resource_name)) + + def _resource_to_zip(self, resource_name): + return self._zipinfo_name(self._fn(self.module_path, resource_name)) + + +register_loader_type(zipimport.zipimporter, ZipProvider) + + +class FileMetadata(EmptyProvider): + """Metadata handler for standalone PKG-INFO files + + Usage:: + + metadata = FileMetadata("/path/to/PKG-INFO") + + This provider rejects all data and metadata requests except for PKG-INFO, + which is treated as existing, and will be the contents of the file at + the provided location. + """ + + def __init__(self, path): + self.path = path + + def has_metadata(self, name): + return name == 'PKG-INFO' and os.path.isfile(self.path) + + def get_metadata(self, name): + if name != 'PKG-INFO': + raise KeyError("No metadata except PKG-INFO is available") + + with io.open(self.path, encoding='utf-8', errors="replace") as f: + metadata = f.read() + self._warn_on_replacement(metadata) + return metadata + + def _warn_on_replacement(self, metadata): + # Python 2.7 compat for: replacement_char = '�' + replacement_char = b'\xef\xbf\xbd'.decode('utf-8') + if replacement_char in metadata: + tmpl = "{self.path} could not be properly decoded in UTF-8" + msg = tmpl.format(**locals()) + warnings.warn(msg) + + def get_metadata_lines(self, name): + return yield_lines(self.get_metadata(name)) + + +class PathMetadata(DefaultProvider): + """Metadata provider for egg directories + + Usage:: + + # Development eggs: + + egg_info = "/path/to/PackageName.egg-info" + base_dir = os.path.dirname(egg_info) + metadata = PathMetadata(base_dir, egg_info) + dist_name = os.path.splitext(os.path.basename(egg_info))[0] + dist = Distribution(basedir, project_name=dist_name, metadata=metadata) + + # Unpacked egg directories: + + egg_path = "/path/to/PackageName-ver-pyver-etc.egg" + metadata = PathMetadata(egg_path, os.path.join(egg_path,'EGG-INFO')) + dist = Distribution.from_filename(egg_path, metadata=metadata) + """ + + def __init__(self, path, egg_info): + self.module_path = path + self.egg_info = egg_info + + +class EggMetadata(ZipProvider): + """Metadata provider for .egg files""" + + def __init__(self, importer): + """Create a metadata provider from a zipimporter""" + + self.zip_pre = importer.archive + os.sep + self.loader = importer + if importer.prefix: + self.module_path = os.path.join(importer.archive, importer.prefix) + else: + self.module_path = importer.archive + self._setup_prefix() + + +_declare_state('dict', _distribution_finders={}) + + +def register_finder(importer_type, distribution_finder): + """Register `distribution_finder` to find distributions in sys.path items + + `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item + handler), and `distribution_finder` is a callable that, passed a path + item and the importer instance, yields ``Distribution`` instances found on + that path item. See ``pkg_resources.find_on_path`` for an example.""" + _distribution_finders[importer_type] = distribution_finder + + +def find_distributions(path_item, only=False): + """Yield distributions accessible via `path_item`""" + importer = get_importer(path_item) + finder = _find_adapter(_distribution_finders, importer) + return finder(importer, path_item, only) + + +def find_eggs_in_zip(importer, path_item, only=False): + """ + Find eggs in zip files; possibly multiple nested eggs. + """ + if importer.archive.endswith('.whl'): + # wheels are not supported with this finder + # they don't have PKG-INFO metadata, and won't ever contain eggs + return + metadata = EggMetadata(importer) + if metadata.has_metadata('PKG-INFO'): + yield Distribution.from_filename(path_item, metadata=metadata) + if only: + # don't yield nested distros + return + for subitem in metadata.resource_listdir('/'): + if _is_egg_path(subitem): + subpath = os.path.join(path_item, subitem) + dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath) + for dist in dists: + yield dist + elif subitem.lower().endswith('.dist-info'): + subpath = os.path.join(path_item, subitem) + submeta = EggMetadata(zipimport.zipimporter(subpath)) + submeta.egg_info = subpath + yield Distribution.from_location(path_item, subitem, submeta) + + +register_finder(zipimport.zipimporter, find_eggs_in_zip) + + +def find_nothing(importer, path_item, only=False): + return () + + +register_finder(object, find_nothing) + + +def _by_version_descending(names): + """ + Given a list of filenames, return them in descending order + by version number. + + >>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg' + >>> _by_version_descending(names) + ['Python-2.7.10.egg', 'Python-2.7.2.egg', 'foo', 'bar'] + >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg' + >>> _by_version_descending(names) + ['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg'] + >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.post1.egg' + >>> _by_version_descending(names) + ['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg'] + """ + def _by_version(name): + """ + Parse each component of the filename + """ + name, ext = os.path.splitext(name) + parts = itertools.chain(name.split('-'), [ext]) + return [packaging.version.parse(part) for part in parts] + + return sorted(names, key=_by_version, reverse=True) + + +def find_on_path(importer, path_item, only=False): + """Yield distributions accessible on a sys.path directory""" + path_item = _normalize_cached(path_item) + + if _is_unpacked_egg(path_item): + yield Distribution.from_filename( + path_item, metadata=PathMetadata( + path_item, os.path.join(path_item, 'EGG-INFO') + ) + ) + return + + entries = safe_listdir(path_item) + + # for performance, before sorting by version, + # screen entries for only those that will yield + # distributions + filtered = ( + entry + for entry in entries + if dist_factory(path_item, entry, only) + ) + + # scan for .egg and .egg-info in directory + path_item_entries = _by_version_descending(filtered) + for entry in path_item_entries: + fullpath = os.path.join(path_item, entry) + factory = dist_factory(path_item, entry, only) + for dist in factory(fullpath): + yield dist + + +def dist_factory(path_item, entry, only): + """ + Return a dist_factory for a path_item and entry + """ + lower = entry.lower() + is_meta = any(map(lower.endswith, ('.egg-info', '.dist-info'))) + return ( + distributions_from_metadata + if is_meta else + find_distributions + if not only and _is_egg_path(entry) else + resolve_egg_link + if not only and lower.endswith('.egg-link') else + NoDists() + ) + + +class NoDists: + """ + >>> bool(NoDists()) + False + + >>> list(NoDists()('anything')) + [] + """ + def __bool__(self): + return False + if six.PY2: + __nonzero__ = __bool__ + + def __call__(self, fullpath): + return iter(()) + + +def safe_listdir(path): + """ + Attempt to list contents of path, but suppress some exceptions. + """ + try: + return os.listdir(path) + except (PermissionError, NotADirectoryError): + pass + except OSError as e: + # Ignore the directory if does not exist, not a directory or + # permission denied + ignorable = ( + e.errno in (errno.ENOTDIR, errno.EACCES, errno.ENOENT) + # Python 2 on Windows needs to be handled this way :( + or getattr(e, "winerror", None) == 267 + ) + if not ignorable: + raise + return () + + +def distributions_from_metadata(path): + root = os.path.dirname(path) + if os.path.isdir(path): + if len(os.listdir(path)) == 0: + # empty metadata dir; skip + return + metadata = PathMetadata(root, path) + else: + metadata = FileMetadata(path) + entry = os.path.basename(path) + yield Distribution.from_location( + root, entry, metadata, precedence=DEVELOP_DIST, + ) + + +def non_empty_lines(path): + """ + Yield non-empty lines from file at path + """ + with open(path) as f: + for line in f: + line = line.strip() + if line: + yield line + + +def resolve_egg_link(path): + """ + Given a path to an .egg-link, resolve distributions + present in the referenced path. + """ + referenced_paths = non_empty_lines(path) + resolved_paths = ( + os.path.join(os.path.dirname(path), ref) + for ref in referenced_paths + ) + dist_groups = map(find_distributions, resolved_paths) + return next(dist_groups, ()) + + +register_finder(pkgutil.ImpImporter, find_on_path) + +if hasattr(importlib_machinery, 'FileFinder'): + register_finder(importlib_machinery.FileFinder, find_on_path) + +_declare_state('dict', _namespace_handlers={}) +_declare_state('dict', _namespace_packages={}) + + +def register_namespace_handler(importer_type, namespace_handler): + """Register `namespace_handler` to declare namespace packages + + `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item + handler), and `namespace_handler` is a callable like this:: + + def namespace_handler(importer, path_entry, moduleName, module): + # return a path_entry to use for child packages + + Namespace handlers are only called if the importer object has already + agreed that it can handle the relevant path item, and they should only + return a subpath if the module __path__ does not already contain an + equivalent subpath. For an example namespace handler, see + ``pkg_resources.file_ns_handler``. + """ + _namespace_handlers[importer_type] = namespace_handler + + +def _handle_ns(packageName, path_item): + """Ensure that named package includes a subpath of path_item (if needed)""" + + importer = get_importer(path_item) + if importer is None: + return None + loader = importer.find_module(packageName) + if loader is None: + return None + module = sys.modules.get(packageName) + if module is None: + module = sys.modules[packageName] = types.ModuleType(packageName) + module.__path__ = [] + _set_parent_ns(packageName) + elif not hasattr(module, '__path__'): + raise TypeError("Not a package:", packageName) + handler = _find_adapter(_namespace_handlers, importer) + subpath = handler(importer, path_item, packageName, module) + if subpath is not None: + path = module.__path__ + path.append(subpath) + loader.load_module(packageName) + _rebuild_mod_path(path, packageName, module) + return subpath + + +def _rebuild_mod_path(orig_path, package_name, module): + """ + Rebuild module.__path__ ensuring that all entries are ordered + corresponding to their sys.path order + """ + sys_path = [_normalize_cached(p) for p in sys.path] + + def safe_sys_path_index(entry): + """ + Workaround for #520 and #513. + """ + try: + return sys_path.index(entry) + except ValueError: + return float('inf') + + def position_in_sys_path(path): + """ + Return the ordinal of the path based on its position in sys.path + """ + path_parts = path.split(os.sep) + module_parts = package_name.count('.') + 1 + parts = path_parts[:-module_parts] + return safe_sys_path_index(_normalize_cached(os.sep.join(parts))) + + if not isinstance(orig_path, list): + # Is this behavior useful when module.__path__ is not a list? + return + + orig_path.sort(key=position_in_sys_path) + module.__path__[:] = [_normalize_cached(p) for p in orig_path] + + +def declare_namespace(packageName): + """Declare that package 'packageName' is a namespace package""" + + _imp.acquire_lock() + try: + if packageName in _namespace_packages: + return + + path, parent = sys.path, None + if '.' in packageName: + parent = '.'.join(packageName.split('.')[:-1]) + declare_namespace(parent) + if parent not in _namespace_packages: + __import__(parent) + try: + path = sys.modules[parent].__path__ + except AttributeError: + raise TypeError("Not a package:", parent) + + # Track what packages are namespaces, so when new path items are added, + # they can be updated + _namespace_packages.setdefault(parent, []).append(packageName) + _namespace_packages.setdefault(packageName, []) + + for path_item in path: + # Ensure all the parent's path items are reflected in the child, + # if they apply + _handle_ns(packageName, path_item) + + finally: + _imp.release_lock() + + +def fixup_namespace_packages(path_item, parent=None): + """Ensure that previously-declared namespace packages include path_item""" + _imp.acquire_lock() + try: + for package in _namespace_packages.get(parent, ()): + subpath = _handle_ns(package, path_item) + if subpath: + fixup_namespace_packages(subpath, package) + finally: + _imp.release_lock() + + +def file_ns_handler(importer, path_item, packageName, module): + """Compute an ns-package subpath for a filesystem or zipfile importer""" + + subpath = os.path.join(path_item, packageName.split('.')[-1]) + normalized = _normalize_cached(subpath) + for item in module.__path__: + if _normalize_cached(item) == normalized: + break + else: + # Only return the path if it's not already there + return subpath + + +register_namespace_handler(pkgutil.ImpImporter, file_ns_handler) +register_namespace_handler(zipimport.zipimporter, file_ns_handler) + +if hasattr(importlib_machinery, 'FileFinder'): + register_namespace_handler(importlib_machinery.FileFinder, file_ns_handler) + + +def null_ns_handler(importer, path_item, packageName, module): + return None + + +register_namespace_handler(object, null_ns_handler) + + +def normalize_path(filename): + """Normalize a file/dir name for comparison purposes""" + return os.path.normcase(os.path.realpath(filename)) + + +def _normalize_cached(filename, _cache={}): + try: + return _cache[filename] + except KeyError: + _cache[filename] = result = normalize_path(filename) + return result + + +def _is_egg_path(path): + """ + Determine if given path appears to be an egg. + """ + return path.lower().endswith('.egg') + + +def _is_unpacked_egg(path): + """ + Determine if given path appears to be an unpacked egg. + """ + return ( + _is_egg_path(path) and + os.path.isfile(os.path.join(path, 'EGG-INFO', 'PKG-INFO')) + ) + + +def _set_parent_ns(packageName): + parts = packageName.split('.') + name = parts.pop() + if parts: + parent = '.'.join(parts) + setattr(sys.modules[parent], name, sys.modules[packageName]) + + +def yield_lines(strs): + """Yield non-empty/non-comment lines of a string or sequence""" + if isinstance(strs, six.string_types): + for s in strs.splitlines(): + s = s.strip() + # skip blank lines/comments + if s and not s.startswith('#'): + yield s + else: + for ss in strs: + for s in yield_lines(ss): + yield s + + +MODULE = re.compile(r"\w+(\.\w+)*$").match +EGG_NAME = re.compile( + r""" + (?P<name>[^-]+) ( + -(?P<ver>[^-]+) ( + -py(?P<pyver>[^-]+) ( + -(?P<plat>.+) + )? + )? + )? + """, + re.VERBOSE | re.IGNORECASE, +).match + + +class EntryPoint(object): + """Object representing an advertised importable object""" + + def __init__(self, name, module_name, attrs=(), extras=(), dist=None): + if not MODULE(module_name): + raise ValueError("Invalid module name", module_name) + self.name = name + self.module_name = module_name + self.attrs = tuple(attrs) + self.extras = tuple(extras) + self.dist = dist + + def __str__(self): + s = "%s = %s" % (self.name, self.module_name) + if self.attrs: + s += ':' + '.'.join(self.attrs) + if self.extras: + s += ' [%s]' % ','.join(self.extras) + return s + + def __repr__(self): + return "EntryPoint.parse(%r)" % str(self) + + def load(self, require=True, *args, **kwargs): + """ + Require packages for this EntryPoint, then resolve it. + """ + if not require or args or kwargs: + warnings.warn( + "Parameters to load are deprecated. Call .resolve and " + ".require separately.", + DeprecationWarning, + stacklevel=2, + ) + if require: + self.require(*args, **kwargs) + return self.resolve() + + def resolve(self): + """ + Resolve the entry point from its module and attrs. + """ + module = __import__(self.module_name, fromlist=['__name__'], level=0) + try: + return functools.reduce(getattr, self.attrs, module) + except AttributeError as exc: + raise ImportError(str(exc)) + + def require(self, env=None, installer=None): + if self.extras and not self.dist: + raise UnknownExtra("Can't require() without a distribution", self) + + # Get the requirements for this entry point with all its extras and + # then resolve them. We have to pass `extras` along when resolving so + # that the working set knows what extras we want. Otherwise, for + # dist-info distributions, the working set will assume that the + # requirements for that extra are purely optional and skip over them. + reqs = self.dist.requires(self.extras) + items = working_set.resolve(reqs, env, installer, extras=self.extras) + list(map(working_set.add, items)) + + pattern = re.compile( + r'\s*' + r'(?P<name>.+?)\s*' + r'=\s*' + r'(?P<module>[\w.]+)\s*' + r'(:\s*(?P<attr>[\w.]+))?\s*' + r'(?P<extras>\[.*\])?\s*$' + ) + + @classmethod + def parse(cls, src, dist=None): + """Parse a single entry point from string `src` + + Entry point syntax follows the form:: + + name = some.module:some.attr [extra1, extra2] + + The entry name and module name are required, but the ``:attrs`` and + ``[extras]`` parts are optional + """ + m = cls.pattern.match(src) + if not m: + msg = "EntryPoint must be in 'name=module:attrs [extras]' format" + raise ValueError(msg, src) + res = m.groupdict() + extras = cls._parse_extras(res['extras']) + attrs = res['attr'].split('.') if res['attr'] else () + return cls(res['name'], res['module'], attrs, extras, dist) + + @classmethod + def _parse_extras(cls, extras_spec): + if not extras_spec: + return () + req = Requirement.parse('x' + extras_spec) + if req.specs: + raise ValueError() + return req.extras + + @classmethod + def parse_group(cls, group, lines, dist=None): + """Parse an entry point group""" + if not MODULE(group): + raise ValueError("Invalid group name", group) + this = {} + for line in yield_lines(lines): + ep = cls.parse(line, dist) + if ep.name in this: + raise ValueError("Duplicate entry point", group, ep.name) + this[ep.name] = ep + return this + + @classmethod + def parse_map(cls, data, dist=None): + """Parse a map of entry point groups""" + if isinstance(data, dict): + data = data.items() + else: + data = split_sections(data) + maps = {} + for group, lines in data: + if group is None: + if not lines: + continue + raise ValueError("Entry points must be listed in groups") + group = group.strip() + if group in maps: + raise ValueError("Duplicate group name", group) + maps[group] = cls.parse_group(group, lines, dist) + return maps + + +def _remove_md5_fragment(location): + if not location: + return '' + parsed = urllib.parse.urlparse(location) + if parsed[-1].startswith('md5='): + return urllib.parse.urlunparse(parsed[:-1] + ('',)) + return location + + +def _version_from_file(lines): + """ + Given an iterable of lines from a Metadata file, return + the value of the Version field, if present, or None otherwise. + """ + def is_version_line(line): + return line.lower().startswith('version:') + version_lines = filter(is_version_line, lines) + line = next(iter(version_lines), '') + _, _, value = line.partition(':') + return safe_version(value.strip()) or None + + +class Distribution(object): + """Wrap an actual or potential sys.path entry w/metadata""" + PKG_INFO = 'PKG-INFO' + + def __init__( + self, location=None, metadata=None, project_name=None, + version=None, py_version=PY_MAJOR, platform=None, + precedence=EGG_DIST): + self.project_name = safe_name(project_name or 'Unknown') + if version is not None: + self._version = safe_version(version) + self.py_version = py_version + self.platform = platform + self.location = location + self.precedence = precedence + self._provider = metadata or empty_provider + + @classmethod + def from_location(cls, location, basename, metadata=None, **kw): + project_name, version, py_version, platform = [None] * 4 + basename, ext = os.path.splitext(basename) + if ext.lower() in _distributionImpl: + cls = _distributionImpl[ext.lower()] + + match = EGG_NAME(basename) + if match: + project_name, version, py_version, platform = match.group( + 'name', 'ver', 'pyver', 'plat' + ) + return cls( + location, metadata, project_name=project_name, version=version, + py_version=py_version, platform=platform, **kw + )._reload_version() + + def _reload_version(self): + return self + + @property + def hashcmp(self): + return ( + self.parsed_version, + self.precedence, + self.key, + _remove_md5_fragment(self.location), + self.py_version or '', + self.platform or '', + ) + + def __hash__(self): + return hash(self.hashcmp) + + def __lt__(self, other): + return self.hashcmp < other.hashcmp + + def __le__(self, other): + return self.hashcmp <= other.hashcmp + + def __gt__(self, other): + return self.hashcmp > other.hashcmp + + def __ge__(self, other): + return self.hashcmp >= other.hashcmp + + def __eq__(self, other): + if not isinstance(other, self.__class__): + # It's not a Distribution, so they are not equal + return False + return self.hashcmp == other.hashcmp + + def __ne__(self, other): + return not self == other + + # These properties have to be lazy so that we don't have to load any + # metadata until/unless it's actually needed. (i.e., some distributions + # may not know their name or version without loading PKG-INFO) + + @property + def key(self): + try: + return self._key + except AttributeError: + self._key = key = self.project_name.lower() + return key + + @property + def parsed_version(self): + if not hasattr(self, "_parsed_version"): + self._parsed_version = parse_version(self.version) + + return self._parsed_version + + def _warn_legacy_version(self): + LV = packaging.version.LegacyVersion + is_legacy = isinstance(self._parsed_version, LV) + if not is_legacy: + return + + # While an empty version is technically a legacy version and + # is not a valid PEP 440 version, it's also unlikely to + # actually come from someone and instead it is more likely that + # it comes from setuptools attempting to parse a filename and + # including it in the list. So for that we'll gate this warning + # on if the version is anything at all or not. + if not self.version: + return + + tmpl = textwrap.dedent(""" + '{project_name} ({version})' is being parsed as a legacy, + non PEP 440, + version. You may find odd behavior and sort order. + In particular it will be sorted as less than 0.0. It + is recommended to migrate to PEP 440 compatible + versions. + """).strip().replace('\n', ' ') + + warnings.warn(tmpl.format(**vars(self)), PEP440Warning) + + @property + def version(self): + try: + return self._version + except AttributeError: + version = _version_from_file(self._get_metadata(self.PKG_INFO)) + if version is None: + tmpl = "Missing 'Version:' header and/or %s file" + raise ValueError(tmpl % self.PKG_INFO, self) + return version + + @property + def _dep_map(self): + """ + A map of extra to its list of (direct) requirements + for this distribution, including the null extra. + """ + try: + return self.__dep_map + except AttributeError: + self.__dep_map = self._filter_extras(self._build_dep_map()) + return self.__dep_map + + @staticmethod + def _filter_extras(dm): + """ + Given a mapping of extras to dependencies, strip off + environment markers and filter out any dependencies + not matching the markers. + """ + for extra in list(filter(None, dm)): + new_extra = extra + reqs = dm.pop(extra) + new_extra, _, marker = extra.partition(':') + fails_marker = marker and ( + invalid_marker(marker) + or not evaluate_marker(marker) + ) + if fails_marker: + reqs = [] + new_extra = safe_extra(new_extra) or None + + dm.setdefault(new_extra, []).extend(reqs) + return dm + + def _build_dep_map(self): + dm = {} + for name in 'requires.txt', 'depends.txt': + for extra, reqs in split_sections(self._get_metadata(name)): + dm.setdefault(extra, []).extend(parse_requirements(reqs)) + return dm + + def requires(self, extras=()): + """List of Requirements needed for this distro if `extras` are used""" + dm = self._dep_map + deps = [] + deps.extend(dm.get(None, ())) + for ext in extras: + try: + deps.extend(dm[safe_extra(ext)]) + except KeyError: + raise UnknownExtra( + "%s has no such extra feature %r" % (self, ext) + ) + return deps + + def _get_metadata(self, name): + if self.has_metadata(name): + for line in self.get_metadata_lines(name): + yield line + + def activate(self, path=None, replace=False): + """Ensure distribution is importable on `path` (default=sys.path)""" + if path is None: + path = sys.path + self.insert_on(path, replace=replace) + if path is sys.path: + fixup_namespace_packages(self.location) + for pkg in self._get_metadata('namespace_packages.txt'): + if pkg in sys.modules: + declare_namespace(pkg) + + def egg_name(self): + """Return what this distribution's standard .egg filename should be""" + filename = "%s-%s-py%s" % ( + to_filename(self.project_name), to_filename(self.version), + self.py_version or PY_MAJOR + ) + + if self.platform: + filename += '-' + self.platform + return filename + + def __repr__(self): + if self.location: + return "%s (%s)" % (self, self.location) + else: + return str(self) + + def __str__(self): + try: + version = getattr(self, 'version', None) + except ValueError: + version = None + version = version or "[unknown version]" + return "%s %s" % (self.project_name, version) + + def __getattr__(self, attr): + """Delegate all unrecognized public attributes to .metadata provider""" + if attr.startswith('_'): + raise AttributeError(attr) + return getattr(self._provider, attr) + + @classmethod + def from_filename(cls, filename, metadata=None, **kw): + return cls.from_location( + _normalize_cached(filename), os.path.basename(filename), metadata, + **kw + ) + + def as_requirement(self): + """Return a ``Requirement`` that matches this distribution exactly""" + if isinstance(self.parsed_version, packaging.version.Version): + spec = "%s==%s" % (self.project_name, self.parsed_version) + else: + spec = "%s===%s" % (self.project_name, self.parsed_version) + + return Requirement.parse(spec) + + def load_entry_point(self, group, name): + """Return the `name` entry point of `group` or raise ImportError""" + ep = self.get_entry_info(group, name) + if ep is None: + raise ImportError("Entry point %r not found" % ((group, name),)) + return ep.load() + + def get_entry_map(self, group=None): + """Return the entry point map for `group`, or the full entry map""" + try: + ep_map = self._ep_map + except AttributeError: + ep_map = self._ep_map = EntryPoint.parse_map( + self._get_metadata('entry_points.txt'), self + ) + if group is not None: + return ep_map.get(group, {}) + return ep_map + + def get_entry_info(self, group, name): + """Return the EntryPoint object for `group`+`name`, or ``None``""" + return self.get_entry_map(group).get(name) + + def insert_on(self, path, loc=None, replace=False): + """Ensure self.location is on path + + If replace=False (default): + - If location is already in path anywhere, do nothing. + - Else: + - If it's an egg and its parent directory is on path, + insert just ahead of the parent. + - Else: add to the end of path. + If replace=True: + - If location is already on path anywhere (not eggs) + or higher priority than its parent (eggs) + do nothing. + - Else: + - If it's an egg and its parent directory is on path, + insert just ahead of the parent, + removing any lower-priority entries. + - Else: add it to the front of path. + """ + + loc = loc or self.location + if not loc: + return + + nloc = _normalize_cached(loc) + bdir = os.path.dirname(nloc) + npath = [(p and _normalize_cached(p) or p) for p in path] + + for p, item in enumerate(npath): + if item == nloc: + if replace: + break + else: + # don't modify path (even removing duplicates) if + # found and not replace + return + elif item == bdir and self.precedence == EGG_DIST: + # if it's an .egg, give it precedence over its directory + # UNLESS it's already been added to sys.path and replace=False + if (not replace) and nloc in npath[p:]: + return + if path is sys.path: + self.check_version_conflict() + path.insert(p, loc) + npath.insert(p, nloc) + break + else: + if path is sys.path: + self.check_version_conflict() + if replace: + path.insert(0, loc) + else: + path.append(loc) + return + + # p is the spot where we found or inserted loc; now remove duplicates + while True: + try: + np = npath.index(nloc, p + 1) + except ValueError: + break + else: + del npath[np], path[np] + # ha! + p = np + + return + + def check_version_conflict(self): + if self.key == 'setuptools': + # ignore the inevitable setuptools self-conflicts :( + return + + nsp = dict.fromkeys(self._get_metadata('namespace_packages.txt')) + loc = normalize_path(self.location) + for modname in self._get_metadata('top_level.txt'): + if (modname not in sys.modules or modname in nsp + or modname in _namespace_packages): + continue + if modname in ('pkg_resources', 'setuptools', 'site'): + continue + fn = getattr(sys.modules[modname], '__file__', None) + if fn and (normalize_path(fn).startswith(loc) or + fn.startswith(self.location)): + continue + issue_warning( + "Module %s was already imported from %s, but %s is being added" + " to sys.path" % (modname, fn, self.location), + ) + + def has_version(self): + try: + self.version + except ValueError: + issue_warning("Unbuilt egg for " + repr(self)) + return False + return True + + def clone(self, **kw): + """Copy this distribution, substituting in any changed keyword args""" + names = 'project_name version py_version platform location precedence' + for attr in names.split(): + kw.setdefault(attr, getattr(self, attr, None)) + kw.setdefault('metadata', self._provider) + return self.__class__(**kw) + + @property + def extras(self): + return [dep for dep in self._dep_map if dep] + + +class EggInfoDistribution(Distribution): + def _reload_version(self): + """ + Packages installed by distutils (e.g. numpy or scipy), + which uses an old safe_version, and so + their version numbers can get mangled when + converted to filenames (e.g., 1.11.0.dev0+2329eae to + 1.11.0.dev0_2329eae). These distributions will not be + parsed properly + downstream by Distribution and safe_version, so + take an extra step and try to get the version number from + the metadata file itself instead of the filename. + """ + md_version = _version_from_file(self._get_metadata(self.PKG_INFO)) + if md_version: + self._version = md_version + return self + + +class DistInfoDistribution(Distribution): + """ + Wrap an actual or potential sys.path entry + w/metadata, .dist-info style. + """ + PKG_INFO = 'METADATA' + EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])") + + @property + def _parsed_pkg_info(self): + """Parse and cache metadata""" + try: + return self._pkg_info + except AttributeError: + metadata = self.get_metadata(self.PKG_INFO) + self._pkg_info = email.parser.Parser().parsestr(metadata) + return self._pkg_info + + @property + def _dep_map(self): + try: + return self.__dep_map + except AttributeError: + self.__dep_map = self._compute_dependencies() + return self.__dep_map + + def _compute_dependencies(self): + """Recompute this distribution's dependencies.""" + dm = self.__dep_map = {None: []} + + reqs = [] + # Including any condition expressions + for req in self._parsed_pkg_info.get_all('Requires-Dist') or []: + reqs.extend(parse_requirements(req)) + + def reqs_for_extra(extra): + for req in reqs: + if not req.marker or req.marker.evaluate({'extra': extra}): + yield req + + common = frozenset(reqs_for_extra(None)) + dm[None].extend(common) + + for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []: + s_extra = safe_extra(extra.strip()) + dm[s_extra] = list(frozenset(reqs_for_extra(extra)) - common) + + return dm + + +_distributionImpl = { + '.egg': Distribution, + '.egg-info': EggInfoDistribution, + '.dist-info': DistInfoDistribution, +} + + +def issue_warning(*args, **kw): + level = 1 + g = globals() + try: + # find the first stack frame that is *not* code in + # the pkg_resources module, to use for the warning + while sys._getframe(level).f_globals is g: + level += 1 + except ValueError: + pass + warnings.warn(stacklevel=level + 1, *args, **kw) + + +class RequirementParseError(ValueError): + def __str__(self): + return ' '.join(self.args) + + +def parse_requirements(strs): + """Yield ``Requirement`` objects for each specification in `strs` + + `strs` must be a string, or a (possibly-nested) iterable thereof. + """ + # create a steppable iterator, so we can handle \-continuations + lines = iter(yield_lines(strs)) + + for line in lines: + # Drop comments -- a hash without a space may be in a URL. + if ' #' in line: + line = line[:line.find(' #')] + # If there is a line continuation, drop it, and append the next line. + if line.endswith('\\'): + line = line[:-2].strip() + try: + line += next(lines) + except StopIteration: + return + yield Requirement(line) + + +class Requirement(packaging.requirements.Requirement): + def __init__(self, requirement_string): + """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!""" + try: + super(Requirement, self).__init__(requirement_string) + except packaging.requirements.InvalidRequirement as e: + raise RequirementParseError(str(e)) + self.unsafe_name = self.name + project_name = safe_name(self.name) + self.project_name, self.key = project_name, project_name.lower() + self.specs = [ + (spec.operator, spec.version) for spec in self.specifier] + self.extras = tuple(map(safe_extra, self.extras)) + self.hashCmp = ( + self.key, + self.specifier, + frozenset(self.extras), + str(self.marker) if self.marker else None, + ) + self.__hash = hash(self.hashCmp) + + def __eq__(self, other): + return ( + isinstance(other, Requirement) and + self.hashCmp == other.hashCmp + ) + + def __ne__(self, other): + return not self == other + + def __contains__(self, item): + if isinstance(item, Distribution): + if item.key != self.key: + return False + + item = item.version + + # Allow prereleases always in order to match the previous behavior of + # this method. In the future this should be smarter and follow PEP 440 + # more accurately. + return self.specifier.contains(item, prereleases=True) + + def __hash__(self): + return self.__hash + + def __repr__(self): + return "Requirement.parse(%r)" % str(self) + + @staticmethod + def parse(s): + req, = parse_requirements(s) + return req + + +def _always_object(classes): + """ + Ensure object appears in the mro even + for old-style classes. + """ + if object not in classes: + return classes + (object,) + return classes + + +def _find_adapter(registry, ob): + """Return an adapter factory for `ob` from `registry`""" + types = _always_object(inspect.getmro(getattr(ob, '__class__', type(ob)))) + for t in types: + if t in registry: + return registry[t] + + +def ensure_directory(path): + """Ensure that the parent directory of `path` exists""" + dirname = os.path.dirname(path) + py31compat.makedirs(dirname, exist_ok=True) + + +def _bypass_ensure_directory(path): + """Sandbox-bypassing version of ensure_directory()""" + if not WRITE_SUPPORT: + raise IOError('"os.mkdir" not supported on this platform.') + dirname, filename = split(path) + if dirname and filename and not isdir(dirname): + _bypass_ensure_directory(dirname) + mkdir(dirname, 0o755) + + +def split_sections(s): + """Split a string or iterable thereof into (section, content) pairs + + Each ``section`` is a stripped version of the section header ("[section]") + and each ``content`` is a list of stripped lines excluding blank lines and + comment-only lines. If there are any such lines before the first section + header, they're returned in a first ``section`` of ``None``. + """ + section = None + content = [] + for line in yield_lines(s): + if line.startswith("["): + if line.endswith("]"): + if section or content: + yield section, content + section = line[1:-1].strip() + content = [] + else: + raise ValueError("Invalid section heading", line) + else: + content.append(line) + + # wrap up last segment + yield section, content + + +def _mkstemp(*args, **kw): + old_open = os.open + try: + # temporarily bypass sandboxing + os.open = os_open + return tempfile.mkstemp(*args, **kw) + finally: + # and then put it back + os.open = old_open + + +# Silence the PEP440Warning by default, so that end users don't get hit by it +# randomly just because they use pkg_resources. We want to append the rule +# because we want earlier uses of filterwarnings to take precedence over this +# one. +warnings.filterwarnings("ignore", category=PEP440Warning, append=True) + + +# from jaraco.functools 1.3 +def _call_aside(f, *args, **kwargs): + f(*args, **kwargs) + return f + + +@_call_aside +def _initialize(g=globals()): + "Set up global resource manager (deliberately not state-saved)" + manager = ResourceManager() + g['_manager'] = manager + g.update( + (name, getattr(manager, name)) + for name in dir(manager) + if not name.startswith('_') + ) + + +@_call_aside +def _initialize_master_working_set(): + """ + Prepare the master working set and make the ``require()`` + API available. + + This function has explicit effects on the global state + of pkg_resources. It is intended to be invoked once at + the initialization of this module. + + Invocation by other packages is unsupported and done + at their own risk. + """ + working_set = WorkingSet._build_master() + _declare_state('object', working_set=working_set) + + require = working_set.require + iter_entry_points = working_set.iter_entry_points + add_activation_listener = working_set.subscribe + run_script = working_set.run_script + # backward compatibility + run_main = run_script + # Activate all distributions already on sys.path with replace=False and + # ensure that all distributions added to the working set in the future + # (e.g. by calling ``require()``) will get activated as well, + # with higher priority (replace=True). + tuple( + dist.activate(replace=False) + for dist in working_set + ) + add_activation_listener( + lambda dist: dist.activate(replace=True), + existing=False, + ) + working_set.entries = [] + # match order + list(map(working_set.add_entry, sys.path)) + globals().update(locals()) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/py31compat.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/py31compat.py new file mode 100644 index 0000000..331a51b --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/py31compat.py @@ -0,0 +1,22 @@ +import os +import errno +import sys + + +def _makedirs_31(path, exist_ok=False): + try: + os.makedirs(path) + except OSError as exc: + if not exist_ok or exc.errno != errno.EEXIST: + raise + + +# rely on compatibility behavior until mode considerations +# and exists_ok considerations are disentangled. +# See https://github.com/pypa/setuptools/pull/1083#issuecomment-315168663 +needs_makedirs = ( + sys.version_info < (3, 2, 5) or + (3, 3) <= sys.version_info < (3, 3, 6) or + (3, 4) <= sys.version_info < (3, 4, 1) +) +makedirs = _makedirs_31 if needs_makedirs else os.makedirs diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__init__.py new file mode 100644 index 0000000..09dfc1e --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__init__.py @@ -0,0 +1,127 @@ +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import division + +from collections import deque +from datetime import timedelta +from math import ceil +from sys import stderr +from time import time + + +__version__ = '1.3' + + +class Infinite(object): + file = stderr + sma_window = 10 # Simple Moving Average window + + def __init__(self, *args, **kwargs): + self.index = 0 + self.start_ts = time() + self.avg = 0 + self._ts = self.start_ts + self._xput = deque(maxlen=self.sma_window) + for key, val in kwargs.items(): + setattr(self, key, val) + + def __getitem__(self, key): + if key.startswith('_'): + return None + return getattr(self, key, None) + + @property + def elapsed(self): + return int(time() - self.start_ts) + + @property + def elapsed_td(self): + return timedelta(seconds=self.elapsed) + + def update_avg(self, n, dt): + if n > 0: + self._xput.append(dt / n) + self.avg = sum(self._xput) / len(self._xput) + + def update(self): + pass + + def start(self): + pass + + def finish(self): + pass + + def next(self, n=1): + now = time() + dt = now - self._ts + self.update_avg(n, dt) + self._ts = now + self.index = self.index + n + self.update() + + def iter(self, it): + try: + for x in it: + yield x + self.next() + finally: + self.finish() + + +class Progress(Infinite): + def __init__(self, *args, **kwargs): + super(Progress, self).__init__(*args, **kwargs) + self.max = kwargs.get('max', 100) + + @property + def eta(self): + return int(ceil(self.avg * self.remaining)) + + @property + def eta_td(self): + return timedelta(seconds=self.eta) + + @property + def percent(self): + return self.progress * 100 + + @property + def progress(self): + return min(1, self.index / self.max) + + @property + def remaining(self): + return max(self.max - self.index, 0) + + def start(self): + self.update() + + def goto(self, index): + incr = index - self.index + self.next(incr) + + def iter(self, it): + try: + self.max = len(it) + except TypeError: + pass + + try: + for x in it: + yield x + self.next() + finally: + self.finish() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/bar.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/bar.py new file mode 100644 index 0000000..5ee968f --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/bar.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import unicode_literals +from . import Progress +from .helpers import WritelnMixin + + +class Bar(WritelnMixin, Progress): + width = 32 + message = '' + suffix = '%(index)d/%(max)d' + bar_prefix = ' |' + bar_suffix = '| ' + empty_fill = ' ' + fill = '#' + hide_cursor = True + + def update(self): + filled_length = int(self.width * self.progress) + empty_length = self.width - filled_length + + message = self.message % self + bar = self.fill * filled_length + empty = self.empty_fill * empty_length + suffix = self.suffix % self + line = ''.join([message, self.bar_prefix, bar, empty, self.bar_suffix, + suffix]) + self.writeln(line) + + +class ChargingBar(Bar): + suffix = '%(percent)d%%' + bar_prefix = ' ' + bar_suffix = ' ' + empty_fill = '∙' + fill = '█' + + +class FillingSquaresBar(ChargingBar): + empty_fill = '▢' + fill = '▣' + + +class FillingCirclesBar(ChargingBar): + empty_fill = '◯' + fill = '◉' + + +class IncrementalBar(Bar): + phases = (' ', '▏', '▎', '▍', '▌', '▋', '▊', '▉', '█') + + def update(self): + nphases = len(self.phases) + filled_len = self.width * self.progress + nfull = int(filled_len) # Number of full chars + phase = int((filled_len - nfull) * nphases) # Phase of last char + nempty = self.width - nfull # Number of empty chars + + message = self.message % self + bar = self.phases[-1] * nfull + current = self.phases[phase] if phase > 0 else '' + empty = self.empty_fill * max(0, nempty - len(current)) + suffix = self.suffix % self + line = ''.join([message, self.bar_prefix, bar, current, empty, + self.bar_suffix, suffix]) + self.writeln(line) + + +class PixelBar(IncrementalBar): + phases = ('⡀', '⡄', '⡆', '⡇', '⣇', '⣧', '⣷', '⣿') + + +class ShadyBar(IncrementalBar): + phases = (' ', '░', '▒', '▓', '█') diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/counter.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/counter.py new file mode 100644 index 0000000..6b45a1e --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/counter.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import unicode_literals +from . import Infinite, Progress +from .helpers import WriteMixin + + +class Counter(WriteMixin, Infinite): + message = '' + hide_cursor = True + + def update(self): + self.write(str(self.index)) + + +class Countdown(WriteMixin, Progress): + hide_cursor = True + + def update(self): + self.write(str(self.remaining)) + + +class Stack(WriteMixin, Progress): + phases = (' ', '▁', '▂', '▃', '▄', '▅', '▆', '▇', '█') + hide_cursor = True + + def update(self): + nphases = len(self.phases) + i = min(nphases - 1, int(self.progress * nphases)) + self.write(self.phases[i]) + + +class Pie(Stack): + phases = ('○', '◔', '◑', '◕', '●') diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/helpers.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/helpers.py new file mode 100644 index 0000000..9ed90b2 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/helpers.py @@ -0,0 +1,91 @@ +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import print_function + + +HIDE_CURSOR = '\x1b[?25l' +SHOW_CURSOR = '\x1b[?25h' + + +class WriteMixin(object): + hide_cursor = False + + def __init__(self, message=None, **kwargs): + super(WriteMixin, self).__init__(**kwargs) + self._width = 0 + if message: + self.message = message + + if self.file.isatty(): + if self.hide_cursor: + print(HIDE_CURSOR, end='', file=self.file) + print(self.message, end='', file=self.file) + self.file.flush() + + def write(self, s): + if self.file.isatty(): + b = '\b' * self._width + c = s.ljust(self._width) + print(b + c, end='', file=self.file) + self._width = max(self._width, len(s)) + self.file.flush() + + def finish(self): + if self.file.isatty() and self.hide_cursor: + print(SHOW_CURSOR, end='', file=self.file) + + +class WritelnMixin(object): + hide_cursor = False + + def __init__(self, message=None, **kwargs): + super(WritelnMixin, self).__init__(**kwargs) + if message: + self.message = message + + if self.file.isatty() and self.hide_cursor: + print(HIDE_CURSOR, end='', file=self.file) + + def clearln(self): + if self.file.isatty(): + print('\r\x1b[K', end='', file=self.file) + + def writeln(self, line): + if self.file.isatty(): + self.clearln() + print(line, end='', file=self.file) + self.file.flush() + + def finish(self): + if self.file.isatty(): + print(file=self.file) + if self.hide_cursor: + print(SHOW_CURSOR, end='', file=self.file) + + +from signal import signal, SIGINT +from sys import exit + + +class SigIntMixin(object): + """Registers a signal handler that calls finish on SIGINT""" + + def __init__(self, *args, **kwargs): + super(SigIntMixin, self).__init__(*args, **kwargs) + signal(SIGINT, self._sigint_handler) + + def _sigint_handler(self, signum, frame): + self.finish() + exit(0) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/spinner.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/spinner.py new file mode 100644 index 0000000..464c7b2 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/spinner.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import unicode_literals +from . import Infinite +from .helpers import WriteMixin + + +class Spinner(WriteMixin, Infinite): + message = '' + phases = ('-', '\\', '|', '/') + hide_cursor = True + + def update(self): + i = self.index % len(self.phases) + self.write(self.phases[i]) + + +class PieSpinner(Spinner): + phases = ['◷', '◶', '◵', '◴'] + + +class MoonSpinner(Spinner): + phases = ['◑', '◒', '◐', '◓'] + + +class LineSpinner(Spinner): + phases = ['⎺', '⎻', '⎼', '⎽', '⎼', '⎻'] + +class PixelSpinner(Spinner): + phases = ['⣾','⣷', '⣯', '⣟', '⡿', '⢿', '⣻', '⣽'] diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pyparsing.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pyparsing.py new file mode 100644 index 0000000..ba2619c --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pyparsing.py @@ -0,0 +1,5720 @@ +# module pyparsing.py +# +# Copyright (c) 2003-2016 Paul T. McGuire +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__doc__ = \ +""" +pyparsing module - Classes and methods to define and execute parsing grammars + +The pyparsing module is an alternative approach to creating and executing simple grammars, +vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you +don't need to learn a new syntax for defining grammars or matching expressions - the parsing module +provides a library of classes that you use to construct the grammar directly in Python. + +Here is a program to parse "Hello, World!" (or any greeting of the form +C{"<salutation>, <addressee>!"}), built up using L{Word}, L{Literal}, and L{And} elements +(L{'+'<ParserElement.__add__>} operator gives L{And} expressions, strings are auto-converted to +L{Literal} expressions):: + + from pip._vendor.pyparsing import Word, alphas + + # define grammar of a greeting + greet = Word(alphas) + "," + Word(alphas) + "!" + + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + +The program outputs the following:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + +The Python representation of the grammar is quite readable, owing to the self-explanatory +class names, and the use of '+', '|' and '^' operators. + +The L{ParseResults} object returned from L{ParserElement.parseString<ParserElement.parseString>} can be accessed as a nested list, a dictionary, or an +object with named attributes. + +The pyparsing module handles some of the problems that are typically vexing when writing text parsers: + - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) + - quoted strings + - embedded comments +""" + +__version__ = "2.2.0" +__versionTime__ = "06 Mar 2017 02:06 UTC" +__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>" + +import string +from weakref import ref as wkref +import copy +import sys +import warnings +import re +import sre_constants +import collections +import pprint +import traceback +import types +from datetime import datetime + +try: + from _thread import RLock +except ImportError: + from threading import RLock + +try: + from collections import OrderedDict as _OrderedDict +except ImportError: + try: + from ordereddict import OrderedDict as _OrderedDict + except ImportError: + _OrderedDict = None + +#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) + +__all__ = [ +'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', +'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', +'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', +'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException', +'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException', +'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', +'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore', +'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col', +'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString', +'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums', +'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno', +'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral', +'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables', +'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', +'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd', +'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute', +'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass', +'CloseMatch', 'tokenMap', 'pyparsing_common', +] + +system_version = tuple(sys.version_info)[:3] +PY_3 = system_version[0] == 3 +if PY_3: + _MAX_INT = sys.maxsize + basestring = str + unichr = chr + _ustr = str + + # build list of single arg builtins, that can be used as parse actions + singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max] + +else: + _MAX_INT = sys.maxint + range = xrange + + def _ustr(obj): + """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries + str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It + then < returns the unicode object | encodes it with the default encoding | ... >. + """ + if isinstance(obj,unicode): + return obj + + try: + # If this works, then _ustr(obj) has the same behaviour as str(obj), so + # it won't break any existing code. + return str(obj) + + except UnicodeEncodeError: + # Else encode it + ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace') + xmlcharref = Regex(r'&#\d+;') + xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:]) + return xmlcharref.transformString(ret) + + # build list of single arg builtins, tolerant of Python version, that can be used as parse actions + singleArgBuiltins = [] + import __builtin__ + for fname in "sum len sorted reversed list tuple set any all min max".split(): + try: + singleArgBuiltins.append(getattr(__builtin__,fname)) + except AttributeError: + continue + +_generatorType = type((y for y in range(1))) + +def _xml_escape(data): + """Escape &, <, >, ", ', etc. in a string of data.""" + + # ampersand must be replaced first + from_symbols = '&><"\'' + to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split()) + for from_,to_ in zip(from_symbols, to_symbols): + data = data.replace(from_, to_) + return data + +class _Constants(object): + pass + +alphas = string.ascii_uppercase + string.ascii_lowercase +nums = "0123456789" +hexnums = nums + "ABCDEFabcdef" +alphanums = alphas + nums +_bslash = chr(92) +printables = "".join(c for c in string.printable if c not in string.whitespace) + +class ParseBaseException(Exception): + """base exception class for all parsing runtime exceptions""" + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, pstr, loc=0, msg=None, elem=None ): + self.loc = loc + if msg is None: + self.msg = pstr + self.pstr = "" + else: + self.msg = msg + self.pstr = pstr + self.parserElement = elem + self.args = (pstr, loc, msg) + + @classmethod + def _from_exception(cls, pe): + """ + internal factory method to simplify creating one type of ParseException + from another - avoids having __init__ signature conflicts among subclasses + """ + return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement) + + def __getattr__( self, aname ): + """supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + """ + if( aname == "lineno" ): + return lineno( self.loc, self.pstr ) + elif( aname in ("col", "column") ): + return col( self.loc, self.pstr ) + elif( aname == "line" ): + return line( self.loc, self.pstr ) + else: + raise AttributeError(aname) + + def __str__( self ): + return "%s (at char %d), (line:%d, col:%d)" % \ + ( self.msg, self.loc, self.lineno, self.column ) + def __repr__( self ): + return _ustr(self) + def markInputline( self, markerString = ">!<" ): + """Extracts the exception line from the input string, and marks + the location of the exception with a special symbol. + """ + line_str = self.line + line_column = self.column - 1 + if markerString: + line_str = "".join((line_str[:line_column], + markerString, line_str[line_column:])) + return line_str.strip() + def __dir__(self): + return "lineno col line".split() + dir(type(self)) + +class ParseException(ParseBaseException): + """ + Exception thrown when parse expressions don't match class; + supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + + Example:: + try: + Word(nums).setName("integer").parseString("ABC") + except ParseException as pe: + print(pe) + print("column: {}".format(pe.col)) + + prints:: + Expected integer (at char 0), (line:1, col:1) + column: 1 + """ + pass + +class ParseFatalException(ParseBaseException): + """user-throwable exception thrown when inconsistent parse content + is found; stops all parsing immediately""" + pass + +class ParseSyntaxException(ParseFatalException): + """just like L{ParseFatalException}, but thrown internally when an + L{ErrorStop<And._ErrorStop>} ('-' operator) indicates that parsing is to stop + immediately because an unbacktrackable syntax error has been found""" + pass + +#~ class ReparseException(ParseBaseException): + #~ """Experimental class - parse actions can raise this exception to cause + #~ pyparsing to reparse the input string: + #~ - with a modified input string, and/or + #~ - with a modified start location + #~ Set the values of the ReparseException in the constructor, and raise the + #~ exception in a parse action to cause pyparsing to use the new string/location. + #~ Setting the values as None causes no change to be made. + #~ """ + #~ def __init_( self, newstring, restartLoc ): + #~ self.newParseText = newstring + #~ self.reparseLoc = restartLoc + +class RecursiveGrammarException(Exception): + """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive""" + def __init__( self, parseElementList ): + self.parseElementTrace = parseElementList + + def __str__( self ): + return "RecursiveGrammarException: %s" % self.parseElementTrace + +class _ParseResultsWithOffset(object): + def __init__(self,p1,p2): + self.tup = (p1,p2) + def __getitem__(self,i): + return self.tup[i] + def __repr__(self): + return repr(self.tup[0]) + def setOffset(self,i): + self.tup = (self.tup[0],i) + +class ParseResults(object): + """ + Structured parse results, to provide multiple means of access to the parsed data: + - as a list (C{len(results)}) + - by list index (C{results[0], results[1]}, etc.) + - by attribute (C{results.<resultsName>} - see L{ParserElement.setResultsName}) + + Example:: + integer = Word(nums) + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + # equivalent form: + # date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + # parseString returns a ParseResults object + result = date_str.parseString("1999/12/31") + + def test(s, fn=repr): + print("%s -> %s" % (s, fn(eval(s)))) + test("list(result)") + test("result[0]") + test("result['month']") + test("result.day") + test("'month' in result") + test("'minutes' in result") + test("result.dump()", str) + prints:: + list(result) -> ['1999', '/', '12', '/', '31'] + result[0] -> '1999' + result['month'] -> '12' + result.day -> '31' + 'month' in result -> True + 'minutes' in result -> False + result.dump() -> ['1999', '/', '12', '/', '31'] + - day: 31 + - month: 12 + - year: 1999 + """ + def __new__(cls, toklist=None, name=None, asList=True, modal=True ): + if isinstance(toklist, cls): + return toklist + retobj = object.__new__(cls) + retobj.__doinit = True + return retobj + + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ): + if self.__doinit: + self.__doinit = False + self.__name = None + self.__parent = None + self.__accumNames = {} + self.__asList = asList + self.__modal = modal + if toklist is None: + toklist = [] + if isinstance(toklist, list): + self.__toklist = toklist[:] + elif isinstance(toklist, _generatorType): + self.__toklist = list(toklist) + else: + self.__toklist = [toklist] + self.__tokdict = dict() + + if name is not None and name: + if not modal: + self.__accumNames[name] = 0 + if isinstance(name,int): + name = _ustr(name) # will always return a str, but use _ustr for consistency + self.__name = name + if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])): + if isinstance(toklist,basestring): + toklist = [ toklist ] + if asList: + if isinstance(toklist,ParseResults): + self[name] = _ParseResultsWithOffset(toklist.copy(),0) + else: + self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) + self[name].__name = name + else: + try: + self[name] = toklist[0] + except (KeyError,TypeError,IndexError): + self[name] = toklist + + def __getitem__( self, i ): + if isinstance( i, (int,slice) ): + return self.__toklist[i] + else: + if i not in self.__accumNames: + return self.__tokdict[i][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[i] ]) + + def __setitem__( self, k, v, isinstance=isinstance ): + if isinstance(v,_ParseResultsWithOffset): + self.__tokdict[k] = self.__tokdict.get(k,list()) + [v] + sub = v[0] + elif isinstance(k,(int,slice)): + self.__toklist[k] = v + sub = v + else: + self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] + sub = v + if isinstance(sub,ParseResults): + sub.__parent = wkref(self) + + def __delitem__( self, i ): + if isinstance(i,(int,slice)): + mylen = len( self.__toklist ) + del self.__toklist[i] + + # convert int to slice + if isinstance(i, int): + if i < 0: + i += mylen + i = slice(i, i+1) + # get removed indices + removed = list(range(*i.indices(mylen))) + removed.reverse() + # fixup indices in token dictionary + for name,occurrences in self.__tokdict.items(): + for j in removed: + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position - (position > j)) + else: + del self.__tokdict[i] + + def __contains__( self, k ): + return k in self.__tokdict + + def __len__( self ): return len( self.__toklist ) + def __bool__(self): return ( not not self.__toklist ) + __nonzero__ = __bool__ + def __iter__( self ): return iter( self.__toklist ) + def __reversed__( self ): return iter( self.__toklist[::-1] ) + def _iterkeys( self ): + if hasattr(self.__tokdict, "iterkeys"): + return self.__tokdict.iterkeys() + else: + return iter(self.__tokdict) + + def _itervalues( self ): + return (self[k] for k in self._iterkeys()) + + def _iteritems( self ): + return ((k, self[k]) for k in self._iterkeys()) + + if PY_3: + keys = _iterkeys + """Returns an iterator of all named result keys (Python 3.x only).""" + + values = _itervalues + """Returns an iterator of all named result values (Python 3.x only).""" + + items = _iteritems + """Returns an iterator of all named result key-value tuples (Python 3.x only).""" + + else: + iterkeys = _iterkeys + """Returns an iterator of all named result keys (Python 2.x only).""" + + itervalues = _itervalues + """Returns an iterator of all named result values (Python 2.x only).""" + + iteritems = _iteritems + """Returns an iterator of all named result key-value tuples (Python 2.x only).""" + + def keys( self ): + """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x).""" + return list(self.iterkeys()) + + def values( self ): + """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x).""" + return list(self.itervalues()) + + def items( self ): + """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x).""" + return list(self.iteritems()) + + def haskeys( self ): + """Since keys() returns an iterator, this method is helpful in bypassing + code that looks for the existence of any defined results names.""" + return bool(self.__tokdict) + + def pop( self, *args, **kwargs): + """ + Removes and returns item at specified index (default=C{last}). + Supports both C{list} and C{dict} semantics for C{pop()}. If passed no + argument or an integer argument, it will use C{list} semantics + and pop tokens from the list of parsed tokens. If passed a + non-integer argument (most likely a string), it will use C{dict} + semantics and pop the corresponding value from any defined + results names. A second default return value argument is + supported, just as in C{dict.pop()}. + + Example:: + def remove_first(tokens): + tokens.pop(0) + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321'] + + label = Word(alphas) + patt = label("LABEL") + OneOrMore(Word(nums)) + print(patt.parseString("AAB 123 321").dump()) + + # Use pop() in a parse action to remove named result (note that corresponding value is not + # removed from list form of results) + def remove_LABEL(tokens): + tokens.pop("LABEL") + return tokens + patt.addParseAction(remove_LABEL) + print(patt.parseString("AAB 123 321").dump()) + prints:: + ['AAB', '123', '321'] + - LABEL: AAB + + ['AAB', '123', '321'] + """ + if not args: + args = [-1] + for k,v in kwargs.items(): + if k == 'default': + args = (args[0], v) + else: + raise TypeError("pop() got an unexpected keyword argument '%s'" % k) + if (isinstance(args[0], int) or + len(args) == 1 or + args[0] in self): + index = args[0] + ret = self[index] + del self[index] + return ret + else: + defaultvalue = args[1] + return defaultvalue + + def get(self, key, defaultValue=None): + """ + Returns named result matching the given key, or if there is no + such name, then returns the given C{defaultValue} or C{None} if no + C{defaultValue} is specified. + + Similar to C{dict.get()}. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString("1999/12/31") + print(result.get("year")) # -> '1999' + print(result.get("hour", "not specified")) # -> 'not specified' + print(result.get("hour")) # -> None + """ + if key in self: + return self[key] + else: + return defaultValue + + def insert( self, index, insStr ): + """ + Inserts new element at location index in the list of parsed tokens. + + Similar to C{list.insert()}. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to insert the parse location in the front of the parsed results + def insert_locn(locn, tokens): + tokens.insert(0, locn) + print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321'] + """ + self.__toklist.insert(index, insStr) + # fixup indices in token dictionary + for name,occurrences in self.__tokdict.items(): + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position + (position > index)) + + def append( self, item ): + """ + Add single element to end of ParseResults list of elements. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to compute the sum of the parsed integers, and add it to the end + def append_sum(tokens): + tokens.append(sum(map(int, tokens))) + print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444] + """ + self.__toklist.append(item) + + def extend( self, itemseq ): + """ + Add sequence of elements to end of ParseResults list of elements. + + Example:: + patt = OneOrMore(Word(alphas)) + + # use a parse action to append the reverse of the matched strings, to make a palindrome + def make_palindrome(tokens): + tokens.extend(reversed([t[::-1] for t in tokens])) + return ''.join(tokens) + print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' + """ + if isinstance(itemseq, ParseResults): + self += itemseq + else: + self.__toklist.extend(itemseq) + + def clear( self ): + """ + Clear all elements and results names. + """ + del self.__toklist[:] + self.__tokdict.clear() + + def __getattr__( self, name ): + try: + return self[name] + except KeyError: + return "" + + if name in self.__tokdict: + if name not in self.__accumNames: + return self.__tokdict[name][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[name] ]) + else: + return "" + + def __add__( self, other ): + ret = self.copy() + ret += other + return ret + + def __iadd__( self, other ): + if other.__tokdict: + offset = len(self.__toklist) + addoffset = lambda a: offset if a<0 else a+offset + otheritems = other.__tokdict.items() + otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) ) + for (k,vlist) in otheritems for v in vlist] + for k,v in otherdictitems: + self[k] = v + if isinstance(v[0],ParseResults): + v[0].__parent = wkref(self) + + self.__toklist += other.__toklist + self.__accumNames.update( other.__accumNames ) + return self + + def __radd__(self, other): + if isinstance(other,int) and other == 0: + # useful for merging many ParseResults using sum() builtin + return self.copy() + else: + # this may raise a TypeError - so be it + return other + self + + def __repr__( self ): + return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) ) + + def __str__( self ): + return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']' + + def _asStringList( self, sep='' ): + out = [] + for item in self.__toklist: + if out and sep: + out.append(sep) + if isinstance( item, ParseResults ): + out += item._asStringList() + else: + out.append( _ustr(item) ) + return out + + def asList( self ): + """ + Returns the parse results as a nested list of matching tokens, all converted to strings. + + Example:: + patt = OneOrMore(Word(alphas)) + result = patt.parseString("sldkj lsdkj sldkj") + # even though the result prints in string-like form, it is actually a pyparsing ParseResults + print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj'] + + # Use asList() to create an actual list + result_list = result.asList() + print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj'] + """ + return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist] + + def asDict( self ): + """ + Returns the named parse results as a nested dictionary. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]}) + + result_dict = result.asDict() + print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'} + + # even though a ParseResults supports dict-like access, sometime you just need to have a dict + import json + print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable + print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"} + """ + if PY_3: + item_fn = self.items + else: + item_fn = self.iteritems + + def toItem(obj): + if isinstance(obj, ParseResults): + if obj.haskeys(): + return obj.asDict() + else: + return [toItem(v) for v in obj] + else: + return obj + + return dict((k,toItem(v)) for k,v in item_fn()) + + def copy( self ): + """ + Returns a new copy of a C{ParseResults} object. + """ + ret = ParseResults( self.__toklist ) + ret.__tokdict = self.__tokdict.copy() + ret.__parent = self.__parent + ret.__accumNames.update( self.__accumNames ) + ret.__name = self.__name + return ret + + def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ): + """ + (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names. + """ + nl = "\n" + out = [] + namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items() + for v in vlist) + nextLevelIndent = indent + " " + + # collapse out indents if formatting is not desired + if not formatted: + indent = "" + nextLevelIndent = "" + nl = "" + + selfTag = None + if doctag is not None: + selfTag = doctag + else: + if self.__name: + selfTag = self.__name + + if not selfTag: + if namedItemsOnly: + return "" + else: + selfTag = "ITEM" + + out += [ nl, indent, "<", selfTag, ">" ] + + for i,res in enumerate(self.__toklist): + if isinstance(res,ParseResults): + if i in namedItems: + out += [ res.asXML(namedItems[i], + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + out += [ res.asXML(None, + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + # individual token, see if there is a name for it + resTag = None + if i in namedItems: + resTag = namedItems[i] + if not resTag: + if namedItemsOnly: + continue + else: + resTag = "ITEM" + xmlBodyText = _xml_escape(_ustr(res)) + out += [ nl, nextLevelIndent, "<", resTag, ">", + xmlBodyText, + "</", resTag, ">" ] + + out += [ nl, indent, "</", selfTag, ">" ] + return "".join(out) + + def __lookup(self,sub): + for k,vlist in self.__tokdict.items(): + for v,loc in vlist: + if sub is v: + return k + return None + + def getName(self): + r""" + Returns the results name for this token expression. Useful when several + different expressions might match at a particular location. + + Example:: + integer = Word(nums) + ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d") + house_number_expr = Suppress('#') + Word(nums, alphanums) + user_data = (Group(house_number_expr)("house_number") + | Group(ssn_expr)("ssn") + | Group(integer)("age")) + user_info = OneOrMore(user_data) + + result = user_info.parseString("22 111-22-3333 #221B") + for item in result: + print(item.getName(), ':', item[0]) + prints:: + age : 22 + ssn : 111-22-3333 + house_number : 221B + """ + if self.__name: + return self.__name + elif self.__parent: + par = self.__parent() + if par: + return par.__lookup(self) + else: + return None + elif (len(self) == 1 and + len(self.__tokdict) == 1 and + next(iter(self.__tokdict.values()))[0][1] in (0,-1)): + return next(iter(self.__tokdict.keys())) + else: + return None + + def dump(self, indent='', depth=0, full=True): + """ + Diagnostic method for listing out the contents of a C{ParseResults}. + Accepts an optional C{indent} argument so that this string can be embedded + in a nested display of other data. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(result.dump()) + prints:: + ['12', '/', '31', '/', '1999'] + - day: 1999 + - month: 31 + - year: 12 + """ + out = [] + NL = '\n' + out.append( indent+_ustr(self.asList()) ) + if full: + if self.haskeys(): + items = sorted((str(k), v) for k,v in self.items()) + for k,v in items: + if out: + out.append(NL) + out.append( "%s%s- %s: " % (indent,(' '*depth), k) ) + if isinstance(v,ParseResults): + if v: + out.append( v.dump(indent,depth+1) ) + else: + out.append(_ustr(v)) + else: + out.append(repr(v)) + elif any(isinstance(vv,ParseResults) for vv in self): + v = self + for i,vv in enumerate(v): + if isinstance(vv,ParseResults): + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),vv.dump(indent,depth+1) )) + else: + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),_ustr(vv))) + + return "".join(out) + + def pprint(self, *args, **kwargs): + """ + Pretty-printer for parsed results as a list, using the C{pprint} module. + Accepts additional positional or keyword args as defined for the + C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint}) + + Example:: + ident = Word(alphas, alphanums) + num = Word(nums) + func = Forward() + term = ident | num | Group('(' + func + ')') + func <<= ident + Group(Optional(delimitedList(term))) + result = func.parseString("fna a,b,(fnb c,d,200),100") + result.pprint(width=40) + prints:: + ['fna', + ['a', + 'b', + ['(', 'fnb', ['c', 'd', '200'], ')'], + '100']] + """ + pprint.pprint(self.asList(), *args, **kwargs) + + # add support for pickle protocol + def __getstate__(self): + return ( self.__toklist, + ( self.__tokdict.copy(), + self.__parent is not None and self.__parent() or None, + self.__accumNames, + self.__name ) ) + + def __setstate__(self,state): + self.__toklist = state[0] + (self.__tokdict, + par, + inAccumNames, + self.__name) = state[1] + self.__accumNames = {} + self.__accumNames.update(inAccumNames) + if par is not None: + self.__parent = wkref(par) + else: + self.__parent = None + + def __getnewargs__(self): + return self.__toklist, self.__name, self.__asList, self.__modal + + def __dir__(self): + return (dir(type(self)) + list(self.keys())) + +collections.MutableMapping.register(ParseResults) + +def col (loc,strg): + """Returns current column within a string, counting newlines as line separators. + The first column is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + s = strg + return 1 if 0<loc<len(s) and s[loc-1] == '\n' else loc - s.rfind("\n", 0, loc) + +def lineno(loc,strg): + """Returns current line number within a string, counting newlines as line separators. + The first line is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + return strg.count("\n",0,loc) + 1 + +def line( loc, strg ): + """Returns the line of text containing loc within a string, counting newlines as line separators. + """ + lastCR = strg.rfind("\n", 0, loc) + nextCR = strg.find("\n", loc) + if nextCR >= 0: + return strg[lastCR+1:nextCR] + else: + return strg[lastCR+1:] + +def _defaultStartDebugAction( instring, loc, expr ): + print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))) + +def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ): + print ("Matched " + _ustr(expr) + " -> " + str(toks.asList())) + +def _defaultExceptionDebugAction( instring, loc, expr, exc ): + print ("Exception raised:" + _ustr(exc)) + +def nullDebugAction(*args): + """'Do-nothing' debug action, to suppress debugging output during parsing.""" + pass + +# Only works on Python 3.x - nonlocal is toxic to Python 2 installs +#~ 'decorator to trim function calls to match the arity of the target' +#~ def _trim_arity(func, maxargs=3): + #~ if func in singleArgBuiltins: + #~ return lambda s,l,t: func(t) + #~ limit = 0 + #~ foundArity = False + #~ def wrapper(*args): + #~ nonlocal limit,foundArity + #~ while 1: + #~ try: + #~ ret = func(*args[limit:]) + #~ foundArity = True + #~ return ret + #~ except TypeError: + #~ if limit == maxargs or foundArity: + #~ raise + #~ limit += 1 + #~ continue + #~ return wrapper + +# this version is Python 2.x-3.x cross-compatible +'decorator to trim function calls to match the arity of the target' +def _trim_arity(func, maxargs=2): + if func in singleArgBuiltins: + return lambda s,l,t: func(t) + limit = [0] + foundArity = [False] + + # traceback return data structure changed in Py3.5 - normalize back to plain tuples + if system_version[:2] >= (3,5): + def extract_stack(limit=0): + # special handling for Python 3.5.0 - extra deep call stack by 1 + offset = -3 if system_version == (3,5,0) else -2 + frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset] + return [(frame_summary.filename, frame_summary.lineno)] + def extract_tb(tb, limit=0): + frames = traceback.extract_tb(tb, limit=limit) + frame_summary = frames[-1] + return [(frame_summary.filename, frame_summary.lineno)] + else: + extract_stack = traceback.extract_stack + extract_tb = traceback.extract_tb + + # synthesize what would be returned by traceback.extract_stack at the call to + # user's parse action 'func', so that we don't incur call penalty at parse time + + LINE_DIFF = 6 + # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND + # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!! + this_line = extract_stack(limit=2)[-1] + pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF) + + def wrapper(*args): + while 1: + try: + ret = func(*args[limit[0]:]) + foundArity[0] = True + return ret + except TypeError: + # re-raise TypeErrors if they did not come from our arity testing + if foundArity[0]: + raise + else: + try: + tb = sys.exc_info()[-1] + if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth: + raise + finally: + del tb + + if limit[0] <= maxargs: + limit[0] += 1 + continue + raise + + # copy func name to wrapper for sensible debug output + func_name = "<parse action>" + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + wrapper.__name__ = func_name + + return wrapper + +class ParserElement(object): + """Abstract base level parser element class.""" + DEFAULT_WHITE_CHARS = " \n\t\r" + verbose_stacktrace = False + + @staticmethod + def setDefaultWhitespaceChars( chars ): + r""" + Overrides the default whitespace chars + + Example:: + # default whitespace chars are space, <TAB> and newline + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl'] + + # change to just treat newline as significant + ParserElement.setDefaultWhitespaceChars(" \t") + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def'] + """ + ParserElement.DEFAULT_WHITE_CHARS = chars + + @staticmethod + def inlineLiteralsUsing(cls): + """ + Set class to be used for inclusion of string literals into a parser. + + Example:: + # default literal class used is Literal + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + + # change to Suppress + ParserElement.inlineLiteralsUsing(Suppress) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '12', '31'] + """ + ParserElement._literalStringClass = cls + + def __init__( self, savelist=False ): + self.parseAction = list() + self.failAction = None + #~ self.name = "<unknown>" # don't define self.name, let subclasses try/except upcall + self.strRepr = None + self.resultsName = None + self.saveAsList = savelist + self.skipWhitespace = True + self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + self.copyDefaultWhiteChars = True + self.mayReturnEmpty = False # used when checking for left-recursion + self.keepTabs = False + self.ignoreExprs = list() + self.debug = False + self.streamlined = False + self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index + self.errmsg = "" + self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all) + self.debugActions = ( None, None, None ) #custom debug actions + self.re = None + self.callPreparse = True # used to avoid redundant calls to preParse + self.callDuringTry = False + + def copy( self ): + """ + Make a copy of this C{ParserElement}. Useful for defining different parse actions + for the same parsing pattern, using copies of the original parse element. + + Example:: + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K") + integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + + print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M")) + prints:: + [5120, 100, 655360, 268435456] + Equivalent form of C{expr.copy()} is just C{expr()}:: + integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + """ + cpy = copy.copy( self ) + cpy.parseAction = self.parseAction[:] + cpy.ignoreExprs = self.ignoreExprs[:] + if self.copyDefaultWhiteChars: + cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + return cpy + + def setName( self, name ): + """ + Define name for this expression, makes debugging and exception messages clearer. + + Example:: + Word(nums).parseString("ABC") # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1) + Word(nums).setName("integer").parseString("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1) + """ + self.name = name + self.errmsg = "Expected " + self.name + if hasattr(self,"exception"): + self.exception.msg = self.errmsg + return self + + def setResultsName( self, name, listAllMatches=False ): + """ + Define name for referencing matching tokens as a nested attribute + of the returned parse results. + NOTE: this returns a *copy* of the original C{ParserElement} object; + this is so that the client can define a basic element, such as an + integer, and reference it in multiple places with different names. + + You can also set results names using the abbreviated syntax, + C{expr("name")} in place of C{expr.setResultsName("name")} - + see L{I{__call__}<__call__>}. + + Example:: + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + + # equivalent form: + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + """ + newself = self.copy() + if name.endswith("*"): + name = name[:-1] + listAllMatches=True + newself.resultsName = name + newself.modalResults = not listAllMatches + return newself + + def setBreak(self,breakFlag = True): + """Method to invoke the Python pdb debugger when this element is + about to be parsed. Set C{breakFlag} to True to enable, False to + disable. + """ + if breakFlag: + _parseMethod = self._parse + def breaker(instring, loc, doActions=True, callPreParse=True): + import pdb + pdb.set_trace() + return _parseMethod( instring, loc, doActions, callPreParse ) + breaker._originalParseMethod = _parseMethod + self._parse = breaker + else: + if hasattr(self._parse,"_originalParseMethod"): + self._parse = self._parse._originalParseMethod + return self + + def setParseAction( self, *fns, **kwargs ): + """ + Define one or more actions to perform when successfully matching parse element definition. + Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)}, + C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where: + - s = the original string being parsed (see note below) + - loc = the location of the matching substring + - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object + If the functions in fns modify the tokens, they can return them as the return + value from fn, and the modified list of tokens will replace the original. + Otherwise, fn does not need to return any value. + + Optional keyword arguments: + - callDuringTry = (default=C{False}) indicate if parse action should be run during lookaheads and alternate testing + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{parseString}<parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + + Example:: + integer = Word(nums) + date_str = integer + '/' + integer + '/' + integer + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + # use parse action to convert to ints at parse time + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + date_str = integer + '/' + integer + '/' + integer + + # note that integer fields are now ints, not strings + date_str.parseString("1999/12/31") # -> [1999, '/', 12, '/', 31] + """ + self.parseAction = list(map(_trim_arity, list(fns))) + self.callDuringTry = kwargs.get("callDuringTry", False) + return self + + def addParseAction( self, *fns, **kwargs ): + """ + Add one or more parse actions to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}. + + See examples in L{I{copy}<copy>}. + """ + self.parseAction += list(map(_trim_arity, list(fns))) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def addCondition(self, *fns, **kwargs): + """Add a boolean predicate function to expression's list of parse actions. See + L{I{setParseAction}<setParseAction>} for function call signatures. Unlike C{setParseAction}, + functions passed to C{addCondition} need to return boolean success/fail of the condition. + + Optional keyword arguments: + - message = define a custom message to be used in the raised exception + - fatal = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException + + Example:: + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + year_int = integer.copy() + year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later") + date_str = year_int + '/' + integer + '/' + integer + + result = date_str.parseString("1999/12/31") # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1) + """ + msg = kwargs.get("message", "failed user-defined condition") + exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException + for fn in fns: + def pa(s,l,t): + if not bool(_trim_arity(fn)(s,l,t)): + raise exc_type(s,l,msg) + self.parseAction.append(pa) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def setFailAction( self, fn ): + """Define action to perform if parsing fails at this expression. + Fail acton fn is a callable function that takes the arguments + C{fn(s,loc,expr,err)} where: + - s = string being parsed + - loc = location where expression match was attempted and failed + - expr = the parse expression that failed + - err = the exception thrown + The function returns no value. It may throw C{L{ParseFatalException}} + if it is desired to stop parsing immediately.""" + self.failAction = fn + return self + + def _skipIgnorables( self, instring, loc ): + exprsFound = True + while exprsFound: + exprsFound = False + for e in self.ignoreExprs: + try: + while 1: + loc,dummy = e._parse( instring, loc ) + exprsFound = True + except ParseException: + pass + return loc + + def preParse( self, instring, loc ): + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + + if self.skipWhitespace: + wt = self.whiteChars + instrlen = len(instring) + while loc < instrlen and instring[loc] in wt: + loc += 1 + + return loc + + def parseImpl( self, instring, loc, doActions=True ): + return loc, [] + + def postParse( self, instring, loc, tokenlist ): + return tokenlist + + #~ @profile + def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): + debugging = ( self.debug ) #and doActions ) + + if debugging or self.failAction: + #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) + if (self.debugActions[0] ): + self.debugActions[0]( instring, loc, self ) + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + try: + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + except ParseBaseException as err: + #~ print ("Exception raised:", err) + if self.debugActions[2]: + self.debugActions[2]( instring, tokensStart, self, err ) + if self.failAction: + self.failAction( instring, tokensStart, self, err ) + raise + else: + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + if self.mayIndexError or loc >= len(instring): + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + else: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + + tokens = self.postParse( instring, loc, tokens ) + + retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults ) + if self.parseAction and (doActions or self.callDuringTry): + if debugging: + try: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + except ParseBaseException as err: + #~ print "Exception raised in user parse action:", err + if (self.debugActions[2] ): + self.debugActions[2]( instring, tokensStart, self, err ) + raise + else: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + + if debugging: + #~ print ("Matched",self,"->",retTokens.asList()) + if (self.debugActions[1] ): + self.debugActions[1]( instring, tokensStart, loc, self, retTokens ) + + return loc, retTokens + + def tryParse( self, instring, loc ): + try: + return self._parse( instring, loc, doActions=False )[0] + except ParseFatalException: + raise ParseException( instring, loc, self.errmsg, self) + + def canParseNext(self, instring, loc): + try: + self.tryParse(instring, loc) + except (ParseException, IndexError): + return False + else: + return True + + class _UnboundedCache(object): + def __init__(self): + cache = {} + self.not_in_cache = not_in_cache = object() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + if _OrderedDict is not None: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = _OrderedDict() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(cache) > size: + try: + cache.popitem(False) + except KeyError: + pass + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + else: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = {} + key_fifo = collections.deque([], size) + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(key_fifo) > size: + cache.pop(key_fifo.popleft(), None) + key_fifo.append(key) + + def clear(self): + cache.clear() + key_fifo.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + # argument cache for optimizing repeated calls when backtracking through recursive expressions + packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail + packrat_cache_lock = RLock() + packrat_cache_stats = [0, 0] + + # this method gets repeatedly called during backtracking with the same arguments - + # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression + def _parseCache( self, instring, loc, doActions=True, callPreParse=True ): + HIT, MISS = 0, 1 + lookup = (self, instring, loc, callPreParse, doActions) + with ParserElement.packrat_cache_lock: + cache = ParserElement.packrat_cache + value = cache.get(lookup) + if value is cache.not_in_cache: + ParserElement.packrat_cache_stats[MISS] += 1 + try: + value = self._parseNoCache(instring, loc, doActions, callPreParse) + except ParseBaseException as pe: + # cache a copy of the exception, without the traceback + cache.set(lookup, pe.__class__(*pe.args)) + raise + else: + cache.set(lookup, (value[0], value[1].copy())) + return value + else: + ParserElement.packrat_cache_stats[HIT] += 1 + if isinstance(value, Exception): + raise value + return (value[0], value[1].copy()) + + _parse = _parseNoCache + + @staticmethod + def resetCache(): + ParserElement.packrat_cache.clear() + ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats) + + _packratEnabled = False + @staticmethod + def enablePackrat(cache_size_limit=128): + """Enables "packrat" parsing, which adds memoizing to the parsing logic. + Repeated parse attempts at the same string location (which happens + often in many complex grammars) can immediately return a cached value, + instead of re-executing parsing/validating code. Memoizing is done of + both valid results and parsing exceptions. + + Parameters: + - cache_size_limit - (default=C{128}) - if an integer value is provided + will limit the size of the packrat cache; if None is passed, then + the cache size will be unbounded; if 0 is passed, the cache will + be effectively disabled. + + This speedup may break existing programs that use parse actions that + have side-effects. For this reason, packrat parsing is disabled when + you first import pyparsing. To activate the packrat feature, your + program must call the class method C{ParserElement.enablePackrat()}. If + your program uses C{psyco} to "compile as you go", you must call + C{enablePackrat} before calling C{psyco.full()}. If you do not do this, + Python will crash. For best results, call C{enablePackrat()} immediately + after importing pyparsing. + + Example:: + from pip._vendor import pyparsing + pyparsing.ParserElement.enablePackrat() + """ + if not ParserElement._packratEnabled: + ParserElement._packratEnabled = True + if cache_size_limit is None: + ParserElement.packrat_cache = ParserElement._UnboundedCache() + else: + ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit) + ParserElement._parse = ParserElement._parseCache + + def parseString( self, instring, parseAll=False ): + """ + Execute the parse expression with the given string. + This is the main interface to the client code, once the complete + expression has been built. + + If you want the grammar to require that the entire input string be + successfully parsed, then set C{parseAll} to True (equivalent to ending + the grammar with C{L{StringEnd()}}). + + Note: C{parseString} implicitly calls C{expandtabs()} on the input string, + in order to report proper column numbers in parse actions. + If the input string contains tabs and + the grammar uses parse actions that use the C{loc} argument to index into the + string being parsed, you can ensure you have a consistent view of the input + string by: + - calling C{parseWithTabs} on your grammar before calling C{parseString} + (see L{I{parseWithTabs}<parseWithTabs>}) + - define your parse action using the full C{(s,loc,toks)} signature, and + reference the input string using the parse action's C{s} argument + - explictly expand the tabs in your input string before calling + C{parseString} + + Example:: + Word('a').parseString('aaaaabaaa') # -> ['aaaaa'] + Word('a').parseString('aaaaabaaa', parseAll=True) # -> Exception: Expected end of text + """ + ParserElement.resetCache() + if not self.streamlined: + self.streamline() + #~ self.saveAsList = True + for e in self.ignoreExprs: + e.streamline() + if not self.keepTabs: + instring = instring.expandtabs() + try: + loc, tokens = self._parse( instring, 0 ) + if parseAll: + loc = self.preParse( instring, loc ) + se = Empty() + StringEnd() + se._parse( instring, loc ) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + else: + return tokens + + def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ): + """ + Scan the input string for expression matches. Each match will return the + matching tokens, start location, and end location. May be called with optional + C{maxMatches} argument, to clip scanning after 'n' matches are found. If + C{overlap} is specified, then overlapping matches will be reported. + + Note that the start and end locations are reported relative to the string + being parsed. See L{I{parseString}<parseString>} for more information on parsing + strings with embedded tabs. + + Example:: + source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" + print(source) + for tokens,start,end in Word(alphas).scanString(source): + print(' '*start + '^'*(end-start)) + print(' '*start + tokens[0]) + + prints:: + + sldjf123lsdjjkf345sldkjf879lkjsfd987 + ^^^^^ + sldjf + ^^^^^^^ + lsdjjkf + ^^^^^^ + sldkjf + ^^^^^^ + lkjsfd + """ + if not self.streamlined: + self.streamline() + for e in self.ignoreExprs: + e.streamline() + + if not self.keepTabs: + instring = _ustr(instring).expandtabs() + instrlen = len(instring) + loc = 0 + preparseFn = self.preParse + parseFn = self._parse + ParserElement.resetCache() + matches = 0 + try: + while loc <= instrlen and matches < maxMatches: + try: + preloc = preparseFn( instring, loc ) + nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) + except ParseException: + loc = preloc+1 + else: + if nextLoc > loc: + matches += 1 + yield tokens, preloc, nextLoc + if overlap: + nextloc = preparseFn( instring, loc ) + if nextloc > loc: + loc = nextLoc + else: + loc += 1 + else: + loc = nextLoc + else: + loc = preloc+1 + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def transformString( self, instring ): + """ + Extension to C{L{scanString}}, to modify matching text with modified tokens that may + be returned from a parse action. To use C{transformString}, define a grammar and + attach a parse action to it that modifies the returned token list. + Invoking C{transformString()} on a target string will then scan for matches, + and replace the matched text patterns according to the logic in the parse + action. C{transformString()} returns the resulting transformed string. + + Example:: + wd = Word(alphas) + wd.setParseAction(lambda toks: toks[0].title()) + + print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york.")) + Prints:: + Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York. + """ + out = [] + lastE = 0 + # force preservation of <TAB>s, to minimize unwanted transformation of string, and to + # keep string locs straight between transformString and scanString + self.keepTabs = True + try: + for t,s,e in self.scanString( instring ): + out.append( instring[lastE:s] ) + if t: + if isinstance(t,ParseResults): + out += t.asList() + elif isinstance(t,list): + out += t + else: + out.append(t) + lastE = e + out.append(instring[lastE:]) + out = [o for o in out if o] + return "".join(map(_ustr,_flatten(out))) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def searchString( self, instring, maxMatches=_MAX_INT ): + """ + Another extension to C{L{scanString}}, simplifying the access to the tokens found + to match the given parse expression. May be called with optional + C{maxMatches} argument, to clip searching after 'n' matches are found. + + Example:: + # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters + cap_word = Word(alphas.upper(), alphas.lower()) + + print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")) + + # the sum() builtin can be used to merge results into a single ParseResults object + print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))) + prints:: + [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] + ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] + """ + try: + return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ]) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False): + """ + Generator method to split a string using the given expression as a separator. + May be called with optional C{maxsplit} argument, to limit the number of splits; + and the optional C{includeSeparators} argument (default=C{False}), if the separating + matching text should be included in the split results. + + Example:: + punc = oneOf(list(".,;:/-!?")) + print(list(punc.split("This, this?, this sentence, is badly punctuated!"))) + prints:: + ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] + """ + splits = 0 + last = 0 + for t,s,e in self.scanString(instring, maxMatches=maxsplit): + yield instring[last:s] + if includeSeparators: + yield t[0] + last = e + yield instring[last:] + + def __add__(self, other ): + """ + Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement + converts them to L{Literal}s by default. + + Example:: + greet = Word(alphas) + "," + Word(alphas) + "!" + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + Prints:: + Hello, World! -> ['Hello', ',', 'World', '!'] + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return And( [ self, other ] ) + + def __radd__(self, other ): + """ + Implementation of + operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other + self + + def __sub__(self, other): + """ + Implementation of - operator, returns C{L{And}} with error stop + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return self + And._ErrorStop() + other + + def __rsub__(self, other ): + """ + Implementation of - operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other - self + + def __mul__(self,other): + """ + Implementation of * operator, allows use of C{expr * 3} in place of + C{expr + expr + expr}. Expressions may also me multiplied by a 2-integer + tuple, similar to C{{min,max}} multipliers in regular expressions. Tuples + may also include C{None} as in: + - C{expr*(n,None)} or C{expr*(n,)} is equivalent + to C{expr*n + L{ZeroOrMore}(expr)} + (read as "at least n instances of C{expr}") + - C{expr*(None,n)} is equivalent to C{expr*(0,n)} + (read as "0 to n instances of C{expr}") + - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)} + - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)} + + Note that C{expr*(None,n)} does not raise an exception if + more than n exprs exist in the input stream; that is, + C{expr*(None,n)} does not enforce a maximum number of expr + occurrences. If this behavior is desired, then write + C{expr*(None,n) + ~expr} + """ + if isinstance(other,int): + minElements, optElements = other,0 + elif isinstance(other,tuple): + other = (other + (None, None))[:2] + if other[0] is None: + other = (0, other[1]) + if isinstance(other[0],int) and other[1] is None: + if other[0] == 0: + return ZeroOrMore(self) + if other[0] == 1: + return OneOrMore(self) + else: + return self*other[0] + ZeroOrMore(self) + elif isinstance(other[0],int) and isinstance(other[1],int): + minElements, optElements = other + optElements -= minElements + else: + raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1])) + else: + raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other)) + + if minElements < 0: + raise ValueError("cannot multiply ParserElement by negative value") + if optElements < 0: + raise ValueError("second tuple value must be greater or equal to first tuple value") + if minElements == optElements == 0: + raise ValueError("cannot multiply ParserElement by 0 or (0,0)") + + if (optElements): + def makeOptionalList(n): + if n>1: + return Optional(self + makeOptionalList(n-1)) + else: + return Optional(self) + if minElements: + if minElements == 1: + ret = self + makeOptionalList(optElements) + else: + ret = And([self]*minElements) + makeOptionalList(optElements) + else: + ret = makeOptionalList(optElements) + else: + if minElements == 1: + ret = self + else: + ret = And([self]*minElements) + return ret + + def __rmul__(self, other): + return self.__mul__(other) + + def __or__(self, other ): + """ + Implementation of | operator - returns C{L{MatchFirst}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return MatchFirst( [ self, other ] ) + + def __ror__(self, other ): + """ + Implementation of | operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other | self + + def __xor__(self, other ): + """ + Implementation of ^ operator - returns C{L{Or}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Or( [ self, other ] ) + + def __rxor__(self, other ): + """ + Implementation of ^ operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other ^ self + + def __and__(self, other ): + """ + Implementation of & operator - returns C{L{Each}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Each( [ self, other ] ) + + def __rand__(self, other ): + """ + Implementation of & operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other & self + + def __invert__( self ): + """ + Implementation of ~ operator - returns C{L{NotAny}} + """ + return NotAny( self ) + + def __call__(self, name=None): + """ + Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}. + + If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be + passed as C{True}. + + If C{name} is omitted, same as calling C{L{copy}}. + + Example:: + # these are equivalent + userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno") + userdata = Word(alphas)("name") + Word(nums+"-")("socsecno") + """ + if name is not None: + return self.setResultsName(name) + else: + return self.copy() + + def suppress( self ): + """ + Suppresses the output of this C{ParserElement}; useful to keep punctuation from + cluttering up returned output. + """ + return Suppress( self ) + + def leaveWhitespace( self ): + """ + Disables the skipping of whitespace before matching the characters in the + C{ParserElement}'s defined pattern. This is normally only used internally by + the pyparsing module, but may be needed in some whitespace-sensitive grammars. + """ + self.skipWhitespace = False + return self + + def setWhitespaceChars( self, chars ): + """ + Overrides the default whitespace chars + """ + self.skipWhitespace = True + self.whiteChars = chars + self.copyDefaultWhiteChars = False + return self + + def parseWithTabs( self ): + """ + Overrides default behavior to expand C{<TAB>}s to spaces before parsing the input string. + Must be called before C{parseString} when the input grammar contains elements that + match C{<TAB>} characters. + """ + self.keepTabs = True + return self + + def ignore( self, other ): + """ + Define expression to be ignored (e.g., comments) while doing pattern + matching; may be called repeatedly, to define multiple comment or other + ignorable patterns. + + Example:: + patt = OneOrMore(Word(alphas)) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj'] + + patt.ignore(cStyleComment) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd'] + """ + if isinstance(other, basestring): + other = Suppress(other) + + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + self.ignoreExprs.append(other) + else: + self.ignoreExprs.append( Suppress( other.copy() ) ) + return self + + def setDebugActions( self, startAction, successAction, exceptionAction ): + """ + Enable display of debugging messages while doing pattern matching. + """ + self.debugActions = (startAction or _defaultStartDebugAction, + successAction or _defaultSuccessDebugAction, + exceptionAction or _defaultExceptionDebugAction) + self.debug = True + return self + + def setDebug( self, flag=True ): + """ + Enable display of debugging messages while doing pattern matching. + Set C{flag} to True to enable, False to disable. + + Example:: + wd = Word(alphas).setName("alphaword") + integer = Word(nums).setName("numword") + term = wd | integer + + # turn on debugging for wd + wd.setDebug() + + OneOrMore(term).parseString("abc 123 xyz 890") + + prints:: + Match alphaword at loc 0(1,1) + Matched alphaword -> ['abc'] + Match alphaword at loc 3(1,4) + Exception raised:Expected alphaword (at char 4), (line:1, col:5) + Match alphaword at loc 7(1,8) + Matched alphaword -> ['xyz'] + Match alphaword at loc 11(1,12) + Exception raised:Expected alphaword (at char 12), (line:1, col:13) + Match alphaword at loc 15(1,16) + Exception raised:Expected alphaword (at char 15), (line:1, col:16) + + The output shown is that produced by the default debug actions - custom debug actions can be + specified using L{setDebugActions}. Prior to attempting + to match the C{wd} expression, the debugging message C{"Match <exprname> at loc <n>(<line>,<col>)"} + is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"} + message is shown. Also note the use of L{setName} to assign a human-readable name to the expression, + which makes debugging and exception messages easier to understand - for instance, the default + name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}. + """ + if flag: + self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) + else: + self.debug = False + return self + + def __str__( self ): + return self.name + + def __repr__( self ): + return _ustr(self) + + def streamline( self ): + self.streamlined = True + self.strRepr = None + return self + + def checkRecursion( self, parseElementList ): + pass + + def validate( self, validateTrace=[] ): + """ + Check defined expressions for valid structure, check for infinite recursive definitions. + """ + self.checkRecursion( [] ) + + def parseFile( self, file_or_filename, parseAll=False ): + """ + Execute the parse expression on the given file or filename. + If a filename is specified (instead of a file object), + the entire file is opened, read, and closed before parsing. + """ + try: + file_contents = file_or_filename.read() + except AttributeError: + with open(file_or_filename, "r") as f: + file_contents = f.read() + try: + return self.parseString(file_contents, parseAll) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def __eq__(self,other): + if isinstance(other, ParserElement): + return self is other or vars(self) == vars(other) + elif isinstance(other, basestring): + return self.matches(other) + else: + return super(ParserElement,self)==other + + def __ne__(self,other): + return not (self == other) + + def __hash__(self): + return hash(id(self)) + + def __req__(self,other): + return self == other + + def __rne__(self,other): + return not (self == other) + + def matches(self, testString, parseAll=True): + """ + Method for quick testing of a parser against a test string. Good for simple + inline microtests of sub expressions while building up larger parser. + + Parameters: + - testString - to test against this expression for a match + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + + Example:: + expr = Word(nums) + assert expr.matches("100") + """ + try: + self.parseString(_ustr(testString), parseAll=parseAll) + return True + except ParseBaseException: + return False + + def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False): + """ + Execute the parse expression on a series of test strings, showing each + test, the parsed results or where the parse failed. Quick and easy way to + run a parse expression against a list of sample strings. + + Parameters: + - tests - a list of separate test strings, or a multiline string of test strings + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + - comment - (default=C{'#'}) - expression for indicating embedded comments in the test + string; pass None to disable comment filtering + - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline; + if False, only dump nested list + - printResults - (default=C{True}) prints test output to stdout + - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing + + Returns: a (success, results) tuple, where success indicates that all tests succeeded + (or failed if C{failureTests} is True), and the results contain a list of lines of each + test's output + + Example:: + number_expr = pyparsing_common.number.copy() + + result = number_expr.runTests(''' + # unsigned integer + 100 + # negative integer + -100 + # float with scientific notation + 6.02e23 + # integer with scientific notation + 1e-12 + ''') + print("Success" if result[0] else "Failed!") + + result = number_expr.runTests(''' + # stray character + 100Z + # missing leading digit before '.' + -.100 + # too many '.' + 3.14.159 + ''', failureTests=True) + print("Success" if result[0] else "Failed!") + prints:: + # unsigned integer + 100 + [100] + + # negative integer + -100 + [-100] + + # float with scientific notation + 6.02e23 + [6.02e+23] + + # integer with scientific notation + 1e-12 + [1e-12] + + Success + + # stray character + 100Z + ^ + FAIL: Expected end of text (at char 3), (line:1, col:4) + + # missing leading digit before '.' + -.100 + ^ + FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1) + + # too many '.' + 3.14.159 + ^ + FAIL: Expected end of text (at char 4), (line:1, col:5) + + Success + + Each test string must be on a single line. If you want to test a string that spans multiple + lines, create a test like this:: + + expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines") + + (Note that this is a raw string literal, you must include the leading 'r'.) + """ + if isinstance(tests, basestring): + tests = list(map(str.strip, tests.rstrip().splitlines())) + if isinstance(comment, basestring): + comment = Literal(comment) + allResults = [] + comments = [] + success = True + for t in tests: + if comment is not None and comment.matches(t, False) or comments and not t: + comments.append(t) + continue + if not t: + continue + out = ['\n'.join(comments), t] + comments = [] + try: + t = t.replace(r'\n','\n') + result = self.parseString(t, parseAll=parseAll) + out.append(result.dump(full=fullDump)) + success = success and not failureTests + except ParseBaseException as pe: + fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else "" + if '\n' in t: + out.append(line(pe.loc, t)) + out.append(' '*(col(pe.loc,t)-1) + '^' + fatal) + else: + out.append(' '*pe.loc + '^' + fatal) + out.append("FAIL: " + str(pe)) + success = success and failureTests + result = pe + except Exception as exc: + out.append("FAIL-EXCEPTION: " + str(exc)) + success = success and failureTests + result = exc + + if printResults: + if fullDump: + out.append('') + print('\n'.join(out)) + + allResults.append((t, result)) + + return success, allResults + + +class Token(ParserElement): + """ + Abstract C{ParserElement} subclass, for defining atomic matching patterns. + """ + def __init__( self ): + super(Token,self).__init__( savelist=False ) + + +class Empty(Token): + """ + An empty token, will always match. + """ + def __init__( self ): + super(Empty,self).__init__() + self.name = "Empty" + self.mayReturnEmpty = True + self.mayIndexError = False + + +class NoMatch(Token): + """ + A token that will never match. + """ + def __init__( self ): + super(NoMatch,self).__init__() + self.name = "NoMatch" + self.mayReturnEmpty = True + self.mayIndexError = False + self.errmsg = "Unmatchable token" + + def parseImpl( self, instring, loc, doActions=True ): + raise ParseException(instring, loc, self.errmsg, self) + + +class Literal(Token): + """ + Token to exactly match a specified string. + + Example:: + Literal('blah').parseString('blah') # -> ['blah'] + Literal('blah').parseString('blahfooblah') # -> ['blah'] + Literal('blah').parseString('bla') # -> Exception: Expected "blah" + + For case-insensitive matching, use L{CaselessLiteral}. + + For keyword matching (force word break before and after the matched string), + use L{Keyword} or L{CaselessKeyword}. + """ + def __init__( self, matchString ): + super(Literal,self).__init__() + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Literal; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.__class__ = Empty + self.name = '"%s"' % _ustr(self.match) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + + # Performance tuning: this routine gets called a *lot* + # if this is a single character match string and the first character matches, + # short-circuit as quickly as possible, and avoid calling startswith + #~ @profile + def parseImpl( self, instring, loc, doActions=True ): + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) +_L = Literal +ParserElement._literalStringClass = Literal + +class Keyword(Token): + """ + Token to exactly match a specified string as a keyword, that is, it must be + immediately followed by a non-keyword character. Compare with C{L{Literal}}: + - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}. + - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'} + Accepts two optional constructor arguments in addition to the keyword string: + - C{identChars} is a string of characters that would be valid identifier characters, + defaulting to all alphanumerics + "_" and "$" + - C{caseless} allows case-insensitive matching, default is C{False}. + + Example:: + Keyword("start").parseString("start") # -> ['start'] + Keyword("start").parseString("starting") # -> Exception + + For case-insensitive matching, use L{CaselessKeyword}. + """ + DEFAULT_KEYWORD_CHARS = alphanums+"_$" + + def __init__( self, matchString, identChars=None, caseless=False ): + super(Keyword,self).__init__() + if identChars is None: + identChars = Keyword.DEFAULT_KEYWORD_CHARS + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Keyword; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.name = '"%s"' % self.match + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + self.caseless = caseless + if caseless: + self.caselessmatch = matchString.upper() + identChars = identChars.upper() + self.identChars = set(identChars) + + def parseImpl( self, instring, loc, doActions=True ): + if self.caseless: + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and + (loc == 0 or instring[loc-1].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + else: + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and + (loc == 0 or instring[loc-1] not in self.identChars) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + + def copy(self): + c = super(Keyword,self).copy() + c.identChars = Keyword.DEFAULT_KEYWORD_CHARS + return c + + @staticmethod + def setDefaultKeywordChars( chars ): + """Overrides the default Keyword chars + """ + Keyword.DEFAULT_KEYWORD_CHARS = chars + +class CaselessLiteral(Literal): + """ + Token to match a specified string, ignoring case of letters. + Note: the matched results will always be in the case of the given + match string, NOT the case of the input text. + + Example:: + OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD'] + + (Contrast with example for L{CaselessKeyword}.) + """ + def __init__( self, matchString ): + super(CaselessLiteral,self).__init__( matchString.upper() ) + # Preserve the defining literal. + self.returnString = matchString + self.name = "'%s'" % self.returnString + self.errmsg = "Expected " + self.name + + def parseImpl( self, instring, loc, doActions=True ): + if instring[ loc:loc+self.matchLen ].upper() == self.match: + return loc+self.matchLen, self.returnString + raise ParseException(instring, loc, self.errmsg, self) + +class CaselessKeyword(Keyword): + """ + Caseless version of L{Keyword}. + + Example:: + OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD'] + + (Contrast with example for L{CaselessLiteral}.) + """ + def __init__( self, matchString, identChars=None ): + super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) + + def parseImpl( self, instring, loc, doActions=True ): + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + +class CloseMatch(Token): + """ + A variation on L{Literal} which matches "close" matches, that is, + strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters: + - C{match_string} - string to be matched + - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match + + The results from a successful parse will contain the matched text from the input string and the following named results: + - C{mismatches} - a list of the positions within the match_string where mismatches were found + - C{original} - the original match_string used to compare against the input string + + If C{mismatches} is an empty list, then the match was an exact match. + + Example:: + patt = CloseMatch("ATCATCGAATGGA") + patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']}) + patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1) + + # exact match + patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']}) + + # close match allowing up to 2 mismatches + patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2) + patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) + """ + def __init__(self, match_string, maxMismatches=1): + super(CloseMatch,self).__init__() + self.name = match_string + self.match_string = match_string + self.maxMismatches = maxMismatches + self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches) + self.mayIndexError = False + self.mayReturnEmpty = False + + def parseImpl( self, instring, loc, doActions=True ): + start = loc + instrlen = len(instring) + maxloc = start + len(self.match_string) + + if maxloc <= instrlen: + match_string = self.match_string + match_stringloc = 0 + mismatches = [] + maxMismatches = self.maxMismatches + + for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)): + src,mat = s_m + if src != mat: + mismatches.append(match_stringloc) + if len(mismatches) > maxMismatches: + break + else: + loc = match_stringloc + 1 + results = ParseResults([instring[start:loc]]) + results['original'] = self.match_string + results['mismatches'] = mismatches + return loc, results + + raise ParseException(instring, loc, self.errmsg, self) + + +class Word(Token): + """ + Token for matching words composed of allowed character sets. + Defined with string containing all allowed initial characters, + an optional string containing allowed body characters (if omitted, + defaults to the initial character set), and an optional minimum, + maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. An optional + C{excludeChars} parameter can list characters that might be found in + the input C{bodyChars} string; useful to define a word of all printables + except for one or two characters, for instance. + + L{srange} is useful for defining custom character set strings for defining + C{Word} expressions, using range notation from regular expression character sets. + + A common mistake is to use C{Word} to match a specific literal string, as in + C{Word("Address")}. Remember that C{Word} uses the string argument to define + I{sets} of matchable characters. This expression would match "Add", "AAA", + "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'. + To match an exact literal string, use L{Literal} or L{Keyword}. + + pyparsing includes helper strings for building Words: + - L{alphas} + - L{nums} + - L{alphanums} + - L{hexnums} + - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.) + - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.) + - L{printables} (any non-whitespace character) + + Example:: + # a word composed of digits + integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9")) + + # a word with a leading capital, and zero or more lowercase + capital_word = Word(alphas.upper(), alphas.lower()) + + # hostnames are alphanumeric, with leading alpha, and '-' + hostname = Word(alphas, alphanums+'-') + + # roman numeral (not a strict parser, accepts invalid mix of characters) + roman = Word("IVXLCDM") + + # any string of non-whitespace characters, except for ',' + csv_value = Word(printables, excludeChars=",") + """ + def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ): + super(Word,self).__init__() + if excludeChars: + initChars = ''.join(c for c in initChars if c not in excludeChars) + if bodyChars: + bodyChars = ''.join(c for c in bodyChars if c not in excludeChars) + self.initCharsOrig = initChars + self.initChars = set(initChars) + if bodyChars : + self.bodyCharsOrig = bodyChars + self.bodyChars = set(bodyChars) + else: + self.bodyCharsOrig = initChars + self.bodyChars = set(initChars) + + self.maxSpecified = max > 0 + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.asKeyword = asKeyword + + if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0): + if self.bodyCharsOrig == self.initCharsOrig: + self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig) + elif len(self.initCharsOrig) == 1: + self.reString = "%s[%s]*" % \ + (re.escape(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + else: + self.reString = "[%s][%s]*" % \ + (_escapeRegexRangeChars(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + if self.asKeyword: + self.reString = r"\b"+self.reString+r"\b" + try: + self.re = re.compile( self.reString ) + except Exception: + self.re = None + + def parseImpl( self, instring, loc, doActions=True ): + if self.re: + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + return loc, result.group() + + if not(instring[ loc ] in self.initChars): + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + instrlen = len(instring) + bodychars = self.bodyChars + maxloc = start + self.maxLen + maxloc = min( maxloc, instrlen ) + while loc < maxloc and instring[loc] in bodychars: + loc += 1 + + throwException = False + if loc - start < self.minLen: + throwException = True + if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: + throwException = True + if self.asKeyword: + if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars): + throwException = True + + if throwException: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(Word,self).__str__() + except Exception: + pass + + + if self.strRepr is None: + + def charsAsStr(s): + if len(s)>4: + return s[:4]+"..." + else: + return s + + if ( self.initCharsOrig != self.bodyCharsOrig ): + self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) ) + else: + self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) + + return self.strRepr + + +class Regex(Token): + r""" + Token for matching strings that match a given regular expression. + Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module. + If the given regex contains named groups (defined using C{(?P<name>...)}), these will be preserved as + named parse results. + + Example:: + realnum = Regex(r"[+-]?\d+\.\d*") + date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)') + # ref: http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression + roman = Regex(r"M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") + """ + compiledREtype = type(re.compile("[A-Z]")) + def __init__( self, pattern, flags=0): + """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags.""" + super(Regex,self).__init__() + + if isinstance(pattern, basestring): + if not pattern: + warnings.warn("null string passed to Regex; use Empty() instead", + SyntaxWarning, stacklevel=2) + + self.pattern = pattern + self.flags = flags + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % pattern, + SyntaxWarning, stacklevel=2) + raise + + elif isinstance(pattern, Regex.compiledREtype): + self.re = pattern + self.pattern = \ + self.reString = str(pattern) + self.flags = flags + + else: + raise ValueError("Regex may only be constructed with a string or a compiled RE object") + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + d = result.groupdict() + ret = ParseResults(result.group()) + if d: + for k in d: + ret[k] = d[k] + return loc,ret + + def __str__( self ): + try: + return super(Regex,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "Re:(%s)" % repr(self.pattern) + + return self.strRepr + + +class QuotedString(Token): + r""" + Token for matching strings that are delimited by quoting characters. + + Defined with the following parameters: + - quoteChar - string of one or more characters defining the quote delimiting string + - escChar - character to escape quotes, typically backslash (default=C{None}) + - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None}) + - multiline - boolean indicating whether quotes can span multiple lines (default=C{False}) + - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True}) + - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar) + - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True}) + + Example:: + qs = QuotedString('"') + print(qs.searchString('lsjdf "This is the quote" sldjf')) + complex_qs = QuotedString('{{', endQuoteChar='}}') + print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf')) + sql_qs = QuotedString('"', escQuote='""') + print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf')) + prints:: + [['This is the quote']] + [['This is the "quote"']] + [['This is the quote with "embedded" quotes']] + """ + def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True): + super(QuotedString,self).__init__() + + # remove white space from quote chars - wont work anyway + quoteChar = quoteChar.strip() + if not quoteChar: + warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + if endQuoteChar is None: + endQuoteChar = quoteChar + else: + endQuoteChar = endQuoteChar.strip() + if not endQuoteChar: + warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + self.quoteChar = quoteChar + self.quoteCharLen = len(quoteChar) + self.firstQuoteChar = quoteChar[0] + self.endQuoteChar = endQuoteChar + self.endQuoteCharLen = len(endQuoteChar) + self.escChar = escChar + self.escQuote = escQuote + self.unquoteResults = unquoteResults + self.convertWhitespaceEscapes = convertWhitespaceEscapes + + if multiline: + self.flags = re.MULTILINE | re.DOTALL + self.pattern = r'%s(?:[^%s%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + else: + self.flags = 0 + self.pattern = r'%s(?:[^%s\n\r%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + if len(self.endQuoteChar) > 1: + self.pattern += ( + '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]), + _escapeRegexRangeChars(self.endQuoteChar[i])) + for i in range(len(self.endQuoteChar)-1,0,-1)) + ')' + ) + if escQuote: + self.pattern += (r'|(?:%s)' % re.escape(escQuote)) + if escChar: + self.pattern += (r'|(?:%s.)' % re.escape(escChar)) + self.escCharReplacePattern = re.escape(self.escChar)+"(.)" + self.pattern += (r')*%s' % re.escape(self.endQuoteChar)) + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, + SyntaxWarning, stacklevel=2) + raise + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + ret = result.group() + + if self.unquoteResults: + + # strip off quotes + ret = ret[self.quoteCharLen:-self.endQuoteCharLen] + + if isinstance(ret,basestring): + # replace escaped whitespace + if '\\' in ret and self.convertWhitespaceEscapes: + ws_map = { + r'\t' : '\t', + r'\n' : '\n', + r'\f' : '\f', + r'\r' : '\r', + } + for wslit,wschar in ws_map.items(): + ret = ret.replace(wslit, wschar) + + # replace escaped characters + if self.escChar: + ret = re.sub(self.escCharReplacePattern, r"\g<1>", ret) + + # replace escaped quotes + if self.escQuote: + ret = ret.replace(self.escQuote, self.endQuoteChar) + + return loc, ret + + def __str__( self ): + try: + return super(QuotedString,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) + + return self.strRepr + + +class CharsNotIn(Token): + """ + Token for matching words composed of characters I{not} in a given set (will + include whitespace in matched characters if not listed in the provided exclusion set - see example). + Defined with string containing all disallowed characters, and an optional + minimum, maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. + + Example:: + # define a comma-separated-value as anything that is not a ',' + csv_value = CharsNotIn(',') + print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213")) + prints:: + ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] + """ + def __init__( self, notChars, min=1, max=0, exact=0 ): + super(CharsNotIn,self).__init__() + self.skipWhitespace = False + self.notChars = notChars + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = ( self.minLen == 0 ) + self.mayIndexError = False + + def parseImpl( self, instring, loc, doActions=True ): + if instring[loc] in self.notChars: + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + notchars = self.notChars + maxlen = min( start+self.maxLen, len(instring) ) + while loc < maxlen and \ + (instring[loc] not in notchars): + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(CharsNotIn, self).__str__() + except Exception: + pass + + if self.strRepr is None: + if len(self.notChars) > 4: + self.strRepr = "!W:(%s...)" % self.notChars[:4] + else: + self.strRepr = "!W:(%s)" % self.notChars + + return self.strRepr + +class White(Token): + """ + Special matching class for matching whitespace. Normally, whitespace is ignored + by pyparsing grammars. This class is included when some whitespace structures + are significant. Define with a string containing the whitespace characters to be + matched; default is C{" \\t\\r\\n"}. Also takes optional C{min}, C{max}, and C{exact} arguments, + as defined for the C{L{Word}} class. + """ + whiteStrs = { + " " : "<SPC>", + "\t": "<TAB>", + "\n": "<LF>", + "\r": "<CR>", + "\f": "<FF>", + } + def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): + super(White,self).__init__() + self.matchWhite = ws + self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) ) + #~ self.leaveWhitespace() + self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite)) + self.mayReturnEmpty = True + self.errmsg = "Expected " + self.name + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + def parseImpl( self, instring, loc, doActions=True ): + if not(instring[ loc ] in self.matchWhite): + raise ParseException(instring, loc, self.errmsg, self) + start = loc + loc += 1 + maxloc = start + self.maxLen + maxloc = min( maxloc, len(instring) ) + while loc < maxloc and instring[loc] in self.matchWhite: + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + +class _PositionToken(Token): + def __init__( self ): + super(_PositionToken,self).__init__() + self.name=self.__class__.__name__ + self.mayReturnEmpty = True + self.mayIndexError = False + +class GoToColumn(_PositionToken): + """ + Token to advance to a specific column of input text; useful for tabular report scraping. + """ + def __init__( self, colno ): + super(GoToColumn,self).__init__() + self.col = colno + + def preParse( self, instring, loc ): + if col(loc,instring) != self.col: + instrlen = len(instring) + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col : + loc += 1 + return loc + + def parseImpl( self, instring, loc, doActions=True ): + thiscol = col( loc, instring ) + if thiscol > self.col: + raise ParseException( instring, loc, "Text not in expected column", self ) + newloc = loc + self.col - thiscol + ret = instring[ loc: newloc ] + return newloc, ret + + +class LineStart(_PositionToken): + """ + Matches if current position is at the beginning of a line within the parse string + + Example:: + + test = '''\ + AAA this line + AAA and this line + AAA but not this one + B AAA and definitely not this one + ''' + + for t in (LineStart() + 'AAA' + restOfLine).searchString(test): + print(t) + + Prints:: + ['AAA', ' this line'] + ['AAA', ' and this line'] + + """ + def __init__( self ): + super(LineStart,self).__init__() + self.errmsg = "Expected start of line" + + def parseImpl( self, instring, loc, doActions=True ): + if col(loc, instring) == 1: + return loc, [] + raise ParseException(instring, loc, self.errmsg, self) + +class LineEnd(_PositionToken): + """ + Matches if current position is at the end of a line within the parse string + """ + def __init__( self ): + super(LineEnd,self).__init__() + self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) + self.errmsg = "Expected end of line" + + def parseImpl( self, instring, loc, doActions=True ): + if loc<len(instring): + if instring[loc] == "\n": + return loc+1, "\n" + else: + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc+1, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class StringStart(_PositionToken): + """ + Matches if current position is at the beginning of the parse string + """ + def __init__( self ): + super(StringStart,self).__init__() + self.errmsg = "Expected start of text" + + def parseImpl( self, instring, loc, doActions=True ): + if loc != 0: + # see if entire string up to here is just whitespace and ignoreables + if loc != self.preParse( instring, 0 ): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class StringEnd(_PositionToken): + """ + Matches if current position is at the end of the parse string + """ + def __init__( self ): + super(StringEnd,self).__init__() + self.errmsg = "Expected end of text" + + def parseImpl( self, instring, loc, doActions=True ): + if loc < len(instring): + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc+1, [] + elif loc > len(instring): + return loc, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class WordStart(_PositionToken): + """ + Matches if the current position is at the beginning of a Word, and + is not preceded by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of + the string being parsed, or at the beginning of a line. + """ + def __init__(self, wordChars = printables): + super(WordStart,self).__init__() + self.wordChars = set(wordChars) + self.errmsg = "Not at the start of a word" + + def parseImpl(self, instring, loc, doActions=True ): + if loc != 0: + if (instring[loc-1] in self.wordChars or + instring[loc] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class WordEnd(_PositionToken): + """ + Matches if the current position is at the end of a Word, and + is not followed by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of + the string being parsed, or at the end of a line. + """ + def __init__(self, wordChars = printables): + super(WordEnd,self).__init__() + self.wordChars = set(wordChars) + self.skipWhitespace = False + self.errmsg = "Not at the end of a word" + + def parseImpl(self, instring, loc, doActions=True ): + instrlen = len(instring) + if instrlen>0 and loc<instrlen: + if (instring[loc] in self.wordChars or + instring[loc-1] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + +class ParseExpression(ParserElement): + """ + Abstract subclass of ParserElement, for combining and post-processing parsed tokens. + """ + def __init__( self, exprs, savelist = False ): + super(ParseExpression,self).__init__(savelist) + if isinstance( exprs, _generatorType ): + exprs = list(exprs) + + if isinstance( exprs, basestring ): + self.exprs = [ ParserElement._literalStringClass( exprs ) ] + elif isinstance( exprs, collections.Iterable ): + exprs = list(exprs) + # if sequence of strings provided, wrap with Literal + if all(isinstance(expr, basestring) for expr in exprs): + exprs = map(ParserElement._literalStringClass, exprs) + self.exprs = list(exprs) + else: + try: + self.exprs = list( exprs ) + except TypeError: + self.exprs = [ exprs ] + self.callPreparse = False + + def __getitem__( self, i ): + return self.exprs[i] + + def append( self, other ): + self.exprs.append( other ) + self.strRepr = None + return self + + def leaveWhitespace( self ): + """Extends C{leaveWhitespace} defined in base class, and also invokes C{leaveWhitespace} on + all contained expressions.""" + self.skipWhitespace = False + self.exprs = [ e.copy() for e in self.exprs ] + for e in self.exprs: + e.leaveWhitespace() + return self + + def ignore( self, other ): + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + else: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + return self + + def __str__( self ): + try: + return super(ParseExpression,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) ) + return self.strRepr + + def streamline( self ): + super(ParseExpression,self).streamline() + + for e in self.exprs: + e.streamline() + + # collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d ) + # but only if there are no parse actions or resultsNames on the nested And's + # (likewise for Or's and MatchFirst's) + if ( len(self.exprs) == 2 ): + other = self.exprs[0] + if ( isinstance( other, self.__class__ ) and + not(other.parseAction) and + other.resultsName is None and + not other.debug ): + self.exprs = other.exprs[:] + [ self.exprs[1] ] + self.strRepr = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + other = self.exprs[-1] + if ( isinstance( other, self.__class__ ) and + not(other.parseAction) and + other.resultsName is None and + not other.debug ): + self.exprs = self.exprs[:-1] + other.exprs[:] + self.strRepr = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + self.errmsg = "Expected " + _ustr(self) + + return self + + def setResultsName( self, name, listAllMatches=False ): + ret = super(ParseExpression,self).setResultsName(name,listAllMatches) + return ret + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + for e in self.exprs: + e.validate(tmp) + self.checkRecursion( [] ) + + def copy(self): + ret = super(ParseExpression,self).copy() + ret.exprs = [e.copy() for e in self.exprs] + return ret + +class And(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found in the given order. + Expressions may be separated by whitespace. + May be constructed using the C{'+'} operator. + May also be constructed using the C{'-'} operator, which will suppress backtracking. + + Example:: + integer = Word(nums) + name_expr = OneOrMore(Word(alphas)) + + expr = And([integer("id"),name_expr("name"),integer("age")]) + # more easily written as: + expr = integer("id") + name_expr("name") + integer("age") + """ + + class _ErrorStop(Empty): + def __init__(self, *args, **kwargs): + super(And._ErrorStop,self).__init__(*args, **kwargs) + self.name = '-' + self.leaveWhitespace() + + def __init__( self, exprs, savelist = True ): + super(And,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.setWhitespaceChars( self.exprs[0].whiteChars ) + self.skipWhitespace = self.exprs[0].skipWhitespace + self.callPreparse = True + + def parseImpl( self, instring, loc, doActions=True ): + # pass False as last arg to _parse for first element, since we already + # pre-parsed the string as part of our And pre-parsing + loc, resultlist = self.exprs[0]._parse( instring, loc, doActions, callPreParse=False ) + errorStop = False + for e in self.exprs[1:]: + if isinstance(e, And._ErrorStop): + errorStop = True + continue + if errorStop: + try: + loc, exprtokens = e._parse( instring, loc, doActions ) + except ParseSyntaxException: + raise + except ParseBaseException as pe: + pe.__traceback__ = None + raise ParseSyntaxException._from_exception(pe) + except IndexError: + raise ParseSyntaxException(instring, len(instring), self.errmsg, self) + else: + loc, exprtokens = e._parse( instring, loc, doActions ) + if exprtokens or exprtokens.haskeys(): + resultlist += exprtokens + return loc, resultlist + + def __iadd__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #And( [ self, other ] ) + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + if not e.mayReturnEmpty: + break + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + +class Or(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the expression that matches the longest string will be used. + May be constructed using the C{'^'} operator. + + Example:: + # construct Or using '^' operator + + number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) + prints:: + [['123'], ['3.1416'], ['789']] + """ + def __init__( self, exprs, savelist = False ): + super(Or,self).__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + matches = [] + for e in self.exprs: + try: + loc2 = e.tryParse( instring, loc ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + else: + # save match among all matches, to retry longest to shortest + matches.append((loc2, e)) + + if matches: + matches.sort(key=lambda x: -x[0]) + for _,e in matches: + try: + return e._parse( instring, loc, doActions ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + + def __ixor__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #Or( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class MatchFirst(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the first one listed is the one that will match. + May be constructed using the C{'|'} operator. + + Example:: + # construct MatchFirst using '|' operator + + # watch the order of expressions to match + number = Word(nums) | Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']] + + # put more selective expression first + number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums) + print(number.searchString("123 3.1416 789")) # Better -> [['123'], ['3.1416'], ['789']] + """ + def __init__( self, exprs, savelist = False ): + super(MatchFirst,self).__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + for e in self.exprs: + try: + ret = e._parse( instring, loc, doActions ) + return ret + except ParseException as err: + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + + # only got here if no expression matched, raise exception for match that made it the furthest + else: + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + def __ior__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #MatchFirst( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class Each(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found, but in any order. + Expressions may be separated by whitespace. + May be constructed using the C{'&'} operator. + + Example:: + color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN") + shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON") + integer = Word(nums) + shape_attr = "shape:" + shape_type("shape") + posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn") + color_attr = "color:" + color("color") + size_attr = "size:" + integer("size") + + # use Each (using operator '&') to accept attributes in any order + # (shape and posn are required, color and size are optional) + shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr) + + shape_spec.runTests(''' + shape: SQUARE color: BLACK posn: 100, 120 + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + color:GREEN size:20 shape:TRIANGLE posn:20,40 + ''' + ) + prints:: + shape: SQUARE color: BLACK posn: 100, 120 + ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']] + - color: BLACK + - posn: ['100', ',', '120'] + - x: 100 + - y: 120 + - shape: SQUARE + + + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']] + - color: BLUE + - posn: ['50', ',', '80'] + - x: 50 + - y: 80 + - shape: CIRCLE + - size: 50 + + + color: GREEN size: 20 shape: TRIANGLE posn: 20,40 + ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']] + - color: GREEN + - posn: ['20', ',', '40'] + - x: 20 + - y: 40 + - shape: TRIANGLE + - size: 20 + """ + def __init__( self, exprs, savelist = True ): + super(Each,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.skipWhitespace = True + self.initExprGroups = True + + def parseImpl( self, instring, loc, doActions=True ): + if self.initExprGroups: + self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional)) + opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ] + opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)] + self.optionals = opt1 + opt2 + self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ] + self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ] + self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ] + self.required += self.multirequired + self.initExprGroups = False + tmpLoc = loc + tmpReqd = self.required[:] + tmpOpt = self.optionals[:] + matchOrder = [] + + keepMatching = True + while keepMatching: + tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired + failed = [] + for e in tmpExprs: + try: + tmpLoc = e.tryParse( instring, tmpLoc ) + except ParseException: + failed.append(e) + else: + matchOrder.append(self.opt1map.get(id(e),e)) + if e in tmpReqd: + tmpReqd.remove(e) + elif e in tmpOpt: + tmpOpt.remove(e) + if len(failed) == len(tmpExprs): + keepMatching = False + + if tmpReqd: + missing = ", ".join(_ustr(e) for e in tmpReqd) + raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing ) + + # add any unmatched Optionals, in case they have default values defined + matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt] + + resultlist = [] + for e in matchOrder: + loc,results = e._parse(instring,loc,doActions) + resultlist.append(results) + + finalResults = sum(resultlist, ParseResults([])) + return loc, finalResults + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class ParseElementEnhance(ParserElement): + """ + Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens. + """ + def __init__( self, expr, savelist=False ): + super(ParseElementEnhance,self).__init__(savelist) + if isinstance( expr, basestring ): + if issubclass(ParserElement._literalStringClass, Token): + expr = ParserElement._literalStringClass(expr) + else: + expr = ParserElement._literalStringClass(Literal(expr)) + self.expr = expr + self.strRepr = None + if expr is not None: + self.mayIndexError = expr.mayIndexError + self.mayReturnEmpty = expr.mayReturnEmpty + self.setWhitespaceChars( expr.whiteChars ) + self.skipWhitespace = expr.skipWhitespace + self.saveAsList = expr.saveAsList + self.callPreparse = expr.callPreparse + self.ignoreExprs.extend(expr.ignoreExprs) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr is not None: + return self.expr._parse( instring, loc, doActions, callPreParse=False ) + else: + raise ParseException("",loc,self.errmsg,self) + + def leaveWhitespace( self ): + self.skipWhitespace = False + self.expr = self.expr.copy() + if self.expr is not None: + self.expr.leaveWhitespace() + return self + + def ignore( self, other ): + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + else: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + return self + + def streamline( self ): + super(ParseElementEnhance,self).streamline() + if self.expr is not None: + self.expr.streamline() + return self + + def checkRecursion( self, parseElementList ): + if self in parseElementList: + raise RecursiveGrammarException( parseElementList+[self] ) + subRecCheckList = parseElementList[:] + [ self ] + if self.expr is not None: + self.expr.checkRecursion( subRecCheckList ) + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion( [] ) + + def __str__( self ): + try: + return super(ParseElementEnhance,self).__str__() + except Exception: + pass + + if self.strRepr is None and self.expr is not None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) ) + return self.strRepr + + +class FollowedBy(ParseElementEnhance): + """ + Lookahead matching of the given parse expression. C{FollowedBy} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression matches at the current + position. C{FollowedBy} always returns a null token list. + + Example:: + # use FollowedBy to match a label only if it is followed by a ':' + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint() + prints:: + [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] + """ + def __init__( self, expr ): + super(FollowedBy,self).__init__(expr) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + self.expr.tryParse( instring, loc ) + return loc, [] + + +class NotAny(ParseElementEnhance): + """ + Lookahead to disallow matching with the given parse expression. C{NotAny} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression does I{not} match at the current + position. Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny} + always returns a null token list. May be constructed using the '~' operator. + + Example:: + + """ + def __init__( self, expr ): + super(NotAny,self).__init__(expr) + #~ self.leaveWhitespace() + self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs + self.mayReturnEmpty = True + self.errmsg = "Found unwanted token, "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr.canParseNext(instring, loc): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "~{" + _ustr(self.expr) + "}" + + return self.strRepr + +class _MultipleMatch(ParseElementEnhance): + def __init__( self, expr, stopOn=None): + super(_MultipleMatch, self).__init__(expr) + self.saveAsList = True + ender = stopOn + if isinstance(ender, basestring): + ender = ParserElement._literalStringClass(ender) + self.not_ender = ~ender if ender is not None else None + + def parseImpl( self, instring, loc, doActions=True ): + self_expr_parse = self.expr._parse + self_skip_ignorables = self._skipIgnorables + check_ender = self.not_ender is not None + if check_ender: + try_not_ender = self.not_ender.tryParse + + # must be at least one (but first see if we are the stopOn sentinel; + # if so, fail) + if check_ender: + try_not_ender(instring, loc) + loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False ) + try: + hasIgnoreExprs = (not not self.ignoreExprs) + while 1: + if check_ender: + try_not_ender(instring, loc) + if hasIgnoreExprs: + preloc = self_skip_ignorables( instring, loc ) + else: + preloc = loc + loc, tmptokens = self_expr_parse( instring, preloc, doActions ) + if tmptokens or tmptokens.haskeys(): + tokens += tmptokens + except (ParseException,IndexError): + pass + + return loc, tokens + +class OneOrMore(_MultipleMatch): + """ + Repetition of one or more of the given expression. + + Parameters: + - expr - expression that must match one or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: BLACK" + OneOrMore(attr_expr).parseString(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']] + + # use stopOn attribute for OneOrMore to avoid reading label string as part of the data + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']] + + # could also be written as + (attr_expr * (1,)).parseString(text).pprint() + """ + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + _ustr(self.expr) + "}..." + + return self.strRepr + +class ZeroOrMore(_MultipleMatch): + """ + Optional repetition of zero or more of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example: similar to L{OneOrMore} + """ + def __init__( self, expr, stopOn=None): + super(ZeroOrMore,self).__init__(expr, stopOn=stopOn) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + return super(ZeroOrMore, self).parseImpl(instring, loc, doActions) + except (ParseException,IndexError): + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]..." + + return self.strRepr + +class _NullToken(object): + def __bool__(self): + return False + __nonzero__ = __bool__ + def __str__(self): + return "" + +_optionalNotMatched = _NullToken() +class Optional(ParseElementEnhance): + """ + Optional matching of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - default (optional) - value to be returned if the optional expression is not found. + + Example:: + # US postal code can be a 5-digit zip, plus optional 4-digit qualifier + zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4))) + zip.runTests(''' + # traditional ZIP code + 12345 + + # ZIP+4 form + 12101-0001 + + # invalid ZIP + 98765- + ''') + prints:: + # traditional ZIP code + 12345 + ['12345'] + + # ZIP+4 form + 12101-0001 + ['12101-0001'] + + # invalid ZIP + 98765- + ^ + FAIL: Expected end of text (at char 5), (line:1, col:6) + """ + def __init__( self, expr, default=_optionalNotMatched ): + super(Optional,self).__init__( expr, savelist=False ) + self.saveAsList = self.expr.saveAsList + self.defaultValue = default + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) + except (ParseException,IndexError): + if self.defaultValue is not _optionalNotMatched: + if self.expr.resultsName: + tokens = ParseResults([ self.defaultValue ]) + tokens[self.expr.resultsName] = self.defaultValue + else: + tokens = [ self.defaultValue ] + else: + tokens = [] + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]" + + return self.strRepr + +class SkipTo(ParseElementEnhance): + """ + Token for skipping over all undefined text until the matched expression is found. + + Parameters: + - expr - target expression marking the end of the data to be skipped + - include - (default=C{False}) if True, the target expression is also parsed + (the skipped text and target expression are returned as a 2-element list). + - ignore - (default=C{None}) used to define grammars (typically quoted strings and + comments) that might contain false matches to the target expression + - failOn - (default=C{None}) define expressions that are not allowed to be + included in the skipped test; if found before the target expression is found, + the SkipTo is not a match + + Example:: + report = ''' + Outstanding Issues Report - 1 Jan 2000 + + # | Severity | Description | Days Open + -----+----------+-------------------------------------------+----------- + 101 | Critical | Intermittent system crash | 6 + 94 | Cosmetic | Spelling error on Login ('log|n') | 14 + 79 | Minor | System slow when running too many reports | 47 + ''' + integer = Word(nums) + SEP = Suppress('|') + # use SkipTo to simply match everything up until the next SEP + # - ignore quoted strings, so that a '|' character inside a quoted string does not match + # - parse action will call token.strip() for each matched token, i.e., the description body + string_data = SkipTo(SEP, ignore=quotedString) + string_data.setParseAction(tokenMap(str.strip)) + ticket_expr = (integer("issue_num") + SEP + + string_data("sev") + SEP + + string_data("desc") + SEP + + integer("days_open")) + + for tkt in ticket_expr.searchString(report): + print tkt.dump() + prints:: + ['101', 'Critical', 'Intermittent system crash', '6'] + - days_open: 6 + - desc: Intermittent system crash + - issue_num: 101 + - sev: Critical + ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14'] + - days_open: 14 + - desc: Spelling error on Login ('log|n') + - issue_num: 94 + - sev: Cosmetic + ['79', 'Minor', 'System slow when running too many reports', '47'] + - days_open: 47 + - desc: System slow when running too many reports + - issue_num: 79 + - sev: Minor + """ + def __init__( self, other, include=False, ignore=None, failOn=None ): + super( SkipTo, self ).__init__( other ) + self.ignoreExpr = ignore + self.mayReturnEmpty = True + self.mayIndexError = False + self.includeMatch = include + self.asList = False + if isinstance(failOn, basestring): + self.failOn = ParserElement._literalStringClass(failOn) + else: + self.failOn = failOn + self.errmsg = "No match found for "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + startloc = loc + instrlen = len(instring) + expr = self.expr + expr_parse = self.expr._parse + self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None + self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None + + tmploc = loc + while tmploc <= instrlen: + if self_failOn_canParseNext is not None: + # break if failOn expression matches + if self_failOn_canParseNext(instring, tmploc): + break + + if self_ignoreExpr_tryParse is not None: + # advance past ignore expressions + while 1: + try: + tmploc = self_ignoreExpr_tryParse(instring, tmploc) + except ParseBaseException: + break + + try: + expr_parse(instring, tmploc, doActions=False, callPreParse=False) + except (ParseException, IndexError): + # no match, advance loc in string + tmploc += 1 + else: + # matched skipto expr, done + break + + else: + # ran off the end of the input string without matching skipto expr, fail + raise ParseException(instring, loc, self.errmsg, self) + + # build up return values + loc = tmploc + skiptext = instring[startloc:loc] + skipresult = ParseResults(skiptext) + + if self.includeMatch: + loc, mat = expr_parse(instring,loc,doActions,callPreParse=False) + skipresult += mat + + return loc, skipresult + +class Forward(ParseElementEnhance): + """ + Forward declaration of an expression to be defined later - + used for recursive grammars, such as algebraic infix notation. + When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator. + + Note: take care when assigning to C{Forward} not to overlook precedence of operators. + Specifically, '|' has a lower precedence than '<<', so that:: + fwdExpr << a | b | c + will actually be evaluated as:: + (fwdExpr << a) | b | c + thereby leaving b and c out as parseable alternatives. It is recommended that you + explicitly group the values inserted into the C{Forward}:: + fwdExpr << (a | b | c) + Converting to use the '<<=' operator instead will avoid this problem. + + See L{ParseResults.pprint} for an example of a recursive parser created using + C{Forward}. + """ + def __init__( self, other=None ): + super(Forward,self).__init__( other, savelist=False ) + + def __lshift__( self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass(other) + self.expr = other + self.strRepr = None + self.mayIndexError = self.expr.mayIndexError + self.mayReturnEmpty = self.expr.mayReturnEmpty + self.setWhitespaceChars( self.expr.whiteChars ) + self.skipWhitespace = self.expr.skipWhitespace + self.saveAsList = self.expr.saveAsList + self.ignoreExprs.extend(self.expr.ignoreExprs) + return self + + def __ilshift__(self, other): + return self << other + + def leaveWhitespace( self ): + self.skipWhitespace = False + return self + + def streamline( self ): + if not self.streamlined: + self.streamlined = True + if self.expr is not None: + self.expr.streamline() + return self + + def validate( self, validateTrace=[] ): + if self not in validateTrace: + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion([]) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + return self.__class__.__name__ + ": ..." + + # stubbed out for now - creates awful memory and perf issues + self._revertClass = self.__class__ + self.__class__ = _ForwardNoRecurse + try: + if self.expr is not None: + retString = _ustr(self.expr) + else: + retString = "None" + finally: + self.__class__ = self._revertClass + return self.__class__.__name__ + ": " + retString + + def copy(self): + if self.expr is not None: + return super(Forward,self).copy() + else: + ret = Forward() + ret <<= self + return ret + +class _ForwardNoRecurse(Forward): + def __str__( self ): + return "..." + +class TokenConverter(ParseElementEnhance): + """ + Abstract subclass of C{ParseExpression}, for converting parsed results. + """ + def __init__( self, expr, savelist=False ): + super(TokenConverter,self).__init__( expr )#, savelist ) + self.saveAsList = False + +class Combine(TokenConverter): + """ + Converter to concatenate all matching tokens to a single string. + By default, the matching patterns must also be contiguous in the input string; + this can be disabled by specifying C{'adjacent=False'} in the constructor. + + Example:: + real = Word(nums) + '.' + Word(nums) + print(real.parseString('3.1416')) # -> ['3', '.', '1416'] + # will also erroneously match the following + print(real.parseString('3. 1416')) # -> ['3', '.', '1416'] + + real = Combine(Word(nums) + '.' + Word(nums)) + print(real.parseString('3.1416')) # -> ['3.1416'] + # no match when there are internal spaces + print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...) + """ + def __init__( self, expr, joinString="", adjacent=True ): + super(Combine,self).__init__( expr ) + # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself + if adjacent: + self.leaveWhitespace() + self.adjacent = adjacent + self.skipWhitespace = True + self.joinString = joinString + self.callPreparse = True + + def ignore( self, other ): + if self.adjacent: + ParserElement.ignore(self, other) + else: + super( Combine, self).ignore( other ) + return self + + def postParse( self, instring, loc, tokenlist ): + retToks = tokenlist.copy() + del retToks[:] + retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) + + if self.resultsName and retToks.haskeys(): + return [ retToks ] + else: + return retToks + +class Group(TokenConverter): + """ + Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions. + + Example:: + ident = Word(alphas) + num = Word(nums) + term = ident | num + func = ident + Optional(delimitedList(term)) + print(func.parseString("fn a,b,100")) # -> ['fn', 'a', 'b', '100'] + + func = ident + Group(Optional(delimitedList(term))) + print(func.parseString("fn a,b,100")) # -> ['fn', ['a', 'b', '100']] + """ + def __init__( self, expr ): + super(Group,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + return [ tokenlist ] + +class Dict(TokenConverter): + """ + Converter to return a repetitive expression as a list, but also as a dictionary. + Each element can also be referenced using the first token in the expression as its key. + Useful for tabular report scraping when the first column can be used as a item key. + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + # print attributes as plain groups + print(OneOrMore(attr_expr).parseString(text).dump()) + + # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names + result = Dict(OneOrMore(Group(attr_expr))).parseString(text) + print(result.dump()) + + # access named fields as dict entries, or output as dict + print(result['shape']) + print(result.asDict()) + prints:: + ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap'] + + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'} + See more examples at L{ParseResults} of accessing fields by results name. + """ + def __init__( self, expr ): + super(Dict,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + for i,tok in enumerate(tokenlist): + if len(tok) == 0: + continue + ikey = tok[0] + if isinstance(ikey,int): + ikey = _ustr(tok[0]).strip() + if len(tok)==1: + tokenlist[ikey] = _ParseResultsWithOffset("",i) + elif len(tok)==2 and not isinstance(tok[1],ParseResults): + tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i) + else: + dictvalue = tok.copy() #ParseResults(i) + del dictvalue[0] + if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()): + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) + else: + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) + + if self.resultsName: + return [ tokenlist ] + else: + return tokenlist + + +class Suppress(TokenConverter): + """ + Converter for ignoring the results of a parsed expression. + + Example:: + source = "a, b, c,d" + wd = Word(alphas) + wd_list1 = wd + ZeroOrMore(',' + wd) + print(wd_list1.parseString(source)) + + # often, delimiters that are useful during parsing are just in the + # way afterward - use Suppress to keep them out of the parsed output + wd_list2 = wd + ZeroOrMore(Suppress(',') + wd) + print(wd_list2.parseString(source)) + prints:: + ['a', ',', 'b', ',', 'c', ',', 'd'] + ['a', 'b', 'c', 'd'] + (See also L{delimitedList}.) + """ + def postParse( self, instring, loc, tokenlist ): + return [] + + def suppress( self ): + return self + + +class OnlyOnce(object): + """ + Wrapper for parse actions, to ensure they are only called once. + """ + def __init__(self, methodCall): + self.callable = _trim_arity(methodCall) + self.called = False + def __call__(self,s,l,t): + if not self.called: + results = self.callable(s,l,t) + self.called = True + return results + raise ParseException(s,l,"") + def reset(self): + self.called = False + +def traceParseAction(f): + """ + Decorator for debugging parse actions. + + When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".} + When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised. + + Example:: + wd = Word(alphas) + + @traceParseAction + def remove_duplicate_chars(tokens): + return ''.join(sorted(set(''.join(tokens))) + + wds = OneOrMore(wd).setParseAction(remove_duplicate_chars) + print(wds.parseString("slkdjs sld sldd sdlf sdljf")) + prints:: + >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {})) + <<leaving remove_duplicate_chars (ret: 'dfjkls') + ['dfjkls'] + """ + f = _trim_arity(f) + def z(*paArgs): + thisFunc = f.__name__ + s,l,t = paArgs[-3:] + if len(paArgs)>3: + thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc + sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) ) + try: + ret = f(*paArgs) + except Exception as exc: + sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) ) + raise + sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) ) + return ret + try: + z.__name__ = f.__name__ + except AttributeError: + pass + return z + +# +# global helpers +# +def delimitedList( expr, delim=",", combine=False ): + """ + Helper to define a delimited list of expressions - the delimiter defaults to ','. + By default, the list elements and delimiters can have intervening whitespace, and + comments, but this can be overridden by passing C{combine=True} in the constructor. + If C{combine} is set to C{True}, the matching tokens are returned as a single token + string, with the delimiters included; otherwise, the matching tokens are returned + as a list of tokens, with the delimiters suppressed. + + Example:: + delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc'] + delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE'] + """ + dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..." + if combine: + return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName) + else: + return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName) + +def countedArray( expr, intExpr=None ): + """ + Helper to define a counted list of expressions. + This helper defines a pattern of the form:: + integer expr expr expr... + where the leading integer tells how many expr expressions follow. + The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed. + + If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value. + + Example:: + countedArray(Word(alphas)).parseString('2 ab cd ef') # -> ['ab', 'cd'] + + # in this parser, the leading integer value is given in binary, + # '10' indicating that 2 values are in the array + binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2)) + countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef') # -> ['ab', 'cd'] + """ + arrayExpr = Forward() + def countFieldParseAction(s,l,t): + n = t[0] + arrayExpr << (n and Group(And([expr]*n)) or Group(empty)) + return [] + if intExpr is None: + intExpr = Word(nums).setParseAction(lambda t:int(t[0])) + else: + intExpr = intExpr.copy() + intExpr.setName("arrayLen") + intExpr.addParseAction(countFieldParseAction, callDuringTry=True) + return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...') + +def _flatten(L): + ret = [] + for i in L: + if isinstance(i,list): + ret.extend(_flatten(i)) + else: + ret.append(i) + return ret + +def matchPreviousLiteral(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousLiteral(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches a + previous literal, will also match the leading C{"1:1"} in C{"1:10"}. + If this is not desired, use C{matchPreviousExpr}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + def copyTokenToRepeater(s,l,t): + if t: + if len(t) == 1: + rep << t[0] + else: + # flatten t tokens + tflat = _flatten(t.asList()) + rep << And(Literal(tt) for tt in tflat) + else: + rep << Empty() + expr.addParseAction(copyTokenToRepeater, callDuringTry=True) + rep.setName('(prev) ' + _ustr(expr)) + return rep + +def matchPreviousExpr(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousExpr(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches by + expressions, will I{not} match the leading C{"1:1"} in C{"1:10"}; + the expressions are evaluated first, and then compared, so + C{"1"} is compared with C{"10"}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + e2 = expr.copy() + rep <<= e2 + def copyTokenToRepeater(s,l,t): + matchTokens = _flatten(t.asList()) + def mustMatchTheseTokens(s,l,t): + theseTokens = _flatten(t.asList()) + if theseTokens != matchTokens: + raise ParseException("",0,"") + rep.setParseAction( mustMatchTheseTokens, callDuringTry=True ) + expr.addParseAction(copyTokenToRepeater, callDuringTry=True) + rep.setName('(prev) ' + _ustr(expr)) + return rep + +def _escapeRegexRangeChars(s): + #~ escape these chars: ^-] + for c in r"\^-]": + s = s.replace(c,_bslash+c) + s = s.replace("\n",r"\n") + s = s.replace("\t",r"\t") + return _ustr(s) + +def oneOf( strs, caseless=False, useRegex=True ): + """ + Helper to quickly define a set of alternative Literals, and makes sure to do + longest-first testing when there is a conflict, regardless of the input order, + but returns a C{L{MatchFirst}} for best performance. + + Parameters: + - strs - a string of space-delimited literals, or a collection of string literals + - caseless - (default=C{False}) - treat all literals as caseless + - useRegex - (default=C{True}) - as an optimization, will generate a Regex + object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or + if creating a C{Regex} raises an exception) + + Example:: + comp_oper = oneOf("< = > <= >= !=") + var = Word(alphas) + number = Word(nums) + term = var | number + comparison_expr = term + comp_oper + term + print(comparison_expr.searchString("B = 12 AA=23 B<=AA AA>12")) + prints:: + [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] + """ + if caseless: + isequal = ( lambda a,b: a.upper() == b.upper() ) + masks = ( lambda a,b: b.upper().startswith(a.upper()) ) + parseElementClass = CaselessLiteral + else: + isequal = ( lambda a,b: a == b ) + masks = ( lambda a,b: b.startswith(a) ) + parseElementClass = Literal + + symbols = [] + if isinstance(strs,basestring): + symbols = strs.split() + elif isinstance(strs, collections.Iterable): + symbols = list(strs) + else: + warnings.warn("Invalid argument to oneOf, expected string or iterable", + SyntaxWarning, stacklevel=2) + if not symbols: + return NoMatch() + + i = 0 + while i < len(symbols)-1: + cur = symbols[i] + for j,other in enumerate(symbols[i+1:]): + if ( isequal(other, cur) ): + del symbols[i+j+1] + break + elif ( masks(cur, other) ): + del symbols[i+j+1] + symbols.insert(i,other) + cur = other + break + else: + i += 1 + + if not caseless and useRegex: + #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )) + try: + if len(symbols)==len("".join(symbols)): + return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols)) + else: + return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols)) + except Exception: + warnings.warn("Exception creating Regex for oneOf, building MatchFirst", + SyntaxWarning, stacklevel=2) + + + # last resort, just use MatchFirst + return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols)) + +def dictOf( key, value ): + """ + Helper to easily and clearly define a dictionary by specifying the respective patterns + for the key and value. Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens + in the proper order. The key pattern can include delimiting markers or punctuation, + as long as they are suppressed, thereby leaving the significant key text. The value + pattern can include named results, so that the C{Dict} results can include named token + fields. + + Example:: + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + print(OneOrMore(attr_expr).parseString(text).dump()) + + attr_label = label + attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join) + + # similar to Dict, but simpler call format + result = dictOf(attr_label, attr_value).parseString(text) + print(result.dump()) + print(result['shape']) + print(result.shape) # object attribute access works too + print(result.asDict()) + prints:: + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + SQUARE + {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'} + """ + return Dict( ZeroOrMore( Group ( key + value ) ) ) + +def originalTextFor(expr, asString=True): + """ + Helper to return the original, untokenized text for a given expression. Useful to + restore the parsed fields of an HTML start tag into the raw tag text itself, or to + revert separate tokens with intervening whitespace back to the original matching + input text. By default, returns astring containing the original parsed text. + + If the optional C{asString} argument is passed as C{False}, then the return value is a + C{L{ParseResults}} containing any results names that were originally matched, and a + single token containing the original matched text from the input string. So if + the expression passed to C{L{originalTextFor}} contains expressions with defined + results names, you must set C{asString} to C{False} if you want to preserve those + results name values. + + Example:: + src = "this is test <b> bold <i>text</i> </b> normal text " + for tag in ("b","i"): + opener,closer = makeHTMLTags(tag) + patt = originalTextFor(opener + SkipTo(closer) + closer) + print(patt.searchString(src)[0]) + prints:: + ['<b> bold <i>text</i> </b>'] + ['<i>text</i>'] + """ + locMarker = Empty().setParseAction(lambda s,loc,t: loc) + endlocMarker = locMarker.copy() + endlocMarker.callPreparse = False + matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end") + if asString: + extractText = lambda s,l,t: s[t._original_start:t._original_end] + else: + def extractText(s,l,t): + t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]] + matchExpr.setParseAction(extractText) + matchExpr.ignoreExprs = expr.ignoreExprs + return matchExpr + +def ungroup(expr): + """ + Helper to undo pyparsing's default grouping of And expressions, even + if all but one are non-empty. + """ + return TokenConverter(expr).setParseAction(lambda t:t[0]) + +def locatedExpr(expr): + """ + Helper to decorate a returned token with its starting and ending locations in the input string. + This helper adds the following results names: + - locn_start = location where matched expression begins + - locn_end = location where matched expression ends + - value = the actual parsed results + + Be careful if the input text contains C{<TAB>} characters, you may want to call + C{L{ParserElement.parseWithTabs}} + + Example:: + wd = Word(alphas) + for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"): + print(match) + prints:: + [[0, 'ljsdf', 5]] + [[8, 'lksdjjf', 15]] + [[18, 'lkkjj', 23]] + """ + locator = Empty().setParseAction(lambda s,l,t: l) + return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end")) + + +# convenience constants for positional expressions +empty = Empty().setName("empty") +lineStart = LineStart().setName("lineStart") +lineEnd = LineEnd().setName("lineEnd") +stringStart = StringStart().setName("stringStart") +stringEnd = StringEnd().setName("stringEnd") + +_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1]) +_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16))) +_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8))) +_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(printables, excludeChars=r'\]', exact=1) | Regex(r"\w", re.UNICODE) +_charRange = Group(_singleChar + Suppress("-") + _singleChar) +_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]" + +def srange(s): + r""" + Helper to easily define string ranges for use in Word construction. Borrows + syntax from regexp '[]' string range definitions:: + srange("[0-9]") -> "0123456789" + srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" + srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" + The input string must be enclosed in []'s, and the returned string is the expanded + character set joined into a single string. + The values enclosed in the []'s may be: + - a single character + - an escaped character with a leading backslash (such as C{\-} or C{\]}) + - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) + (C{\0x##} is also supported for backwards compatibility) + - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character) + - a range of any of the above, separated by a dash (C{'a-z'}, etc.) + - any combination of the above (C{'aeiouy'}, C{'a-zA-Z0-9_$'}, etc.) + """ + _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1)) + try: + return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body) + except Exception: + return "" + +def matchOnlyAtCol(n): + """ + Helper method for defining parse actions that require matching at a specific + column in the input text. + """ + def verifyCol(strg,locn,toks): + if col(locn,strg) != n: + raise ParseException(strg,locn,"matched token not at column %d" % n) + return verifyCol + +def replaceWith(replStr): + """ + Helper method for common parse actions that simply return a literal value. Especially + useful when used with C{L{transformString<ParserElement.transformString>}()}. + + Example:: + num = Word(nums).setParseAction(lambda toks: int(toks[0])) + na = oneOf("N/A NA").setParseAction(replaceWith(math.nan)) + term = na | num + + OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234] + """ + return lambda s,l,t: [replStr] + +def removeQuotes(s,l,t): + """ + Helper parse action for removing quotation marks from parsed quoted strings. + + Example:: + # by default, quotation marks are included in parsed results + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"] + + # use removeQuotes to strip quotation marks from parsed results + quotedString.setParseAction(removeQuotes) + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"] + """ + return t[0][1:-1] + +def tokenMap(func, *args): + """ + Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional + args are passed, they are forwarded to the given function as additional arguments after + the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the + parsed data to an integer using base 16. + + Example (compare the last to example in L{ParserElement.transformString}:: + hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16)) + hex_ints.runTests(''' + 00 11 22 aa FF 0a 0d 1a + ''') + + upperword = Word(alphas).setParseAction(tokenMap(str.upper)) + OneOrMore(upperword).runTests(''' + my kingdom for a horse + ''') + + wd = Word(alphas).setParseAction(tokenMap(str.title)) + OneOrMore(wd).setParseAction(' '.join).runTests(''' + now is the winter of our discontent made glorious summer by this sun of york + ''') + prints:: + 00 11 22 aa FF 0a 0d 1a + [0, 17, 34, 170, 255, 10, 13, 26] + + my kingdom for a horse + ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE'] + + now is the winter of our discontent made glorious summer by this sun of york + ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York'] + """ + def pa(s,l,t): + return [func(tokn, *args) for tokn in t] + + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + pa.__name__ = func_name + + return pa + +upcaseTokens = tokenMap(lambda t: _ustr(t).upper()) +"""(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}""" + +downcaseTokens = tokenMap(lambda t: _ustr(t).lower()) +"""(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}""" + +def _makeTags(tagStr, xml): + """Internal helper to construct opening and closing tag expressions, given a tag name""" + if isinstance(tagStr,basestring): + resname = tagStr + tagStr = Keyword(tagStr, caseless=not xml) + else: + resname = tagStr.name + + tagAttrName = Word(alphas,alphanums+"_-:") + if (xml): + tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes ) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + else: + printablesLessRAbrack = "".join(c for c in printables if c not in ">") + tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ + Optional( Suppress("=") + tagAttrValue ) ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + closeTag = Combine(_L("</") + tagStr + ">") + + openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname) + closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname) + openTag.tag = resname + closeTag.tag = resname + return openTag, closeTag + +def makeHTMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches + tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values. + + Example:: + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>' + # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple + a,a_end = makeHTMLTags("A") + link_expr = a + SkipTo(a_end)("link_text") + a_end + + for link in link_expr.searchString(text): + # attributes in the <A> tag (like "href" shown here) are also accessible as named results + print(link.link_text, '->', link.href) + prints:: + pyparsing -> http://pyparsing.wikispaces.com + """ + return _makeTags( tagStr, False ) + +def makeXMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for XML, given a tag name. Matches + tags only in the given upper/lower case. + + Example: similar to L{makeHTMLTags} + """ + return _makeTags( tagStr, True ) + +def withAttribute(*args,**attrDict): + """ + Helper to create a validating parse action to be used with start tags created + with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag + with a required attribute value, to avoid false matches on common tags such as + C{<TD>} or C{<DIV>}. + + Call C{withAttribute} with a series of attribute names and values. Specify the list + of filter attributes names and values as: + - keyword arguments, as in C{(align="right")}, or + - as an explicit dict with C{**} operator, when an attribute name is also a Python + reserved word, as in C{**{"class":"Customer", "align":"right"}} + - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") ) + For attribute names with a namespace prefix, you must use the second form. Attribute + names are matched insensitive to upper/lower case. + + If just testing for C{class} (with or without a namespace), use C{L{withClass}}. + + To verify that the attribute exists, but without specifying a value, pass + C{withAttribute.ANY_VALUE} as the value. + + Example:: + html = ''' + <div> + Some text + <div type="grid">1 4 0 1 0</div> + <div type="graph">1,3 2,3 1,1</div> + <div>this has no type</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + + # only match div tag having a type attribute with value "grid" + div_grid = div().setParseAction(withAttribute(type="grid")) + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + # construct a match with any div tag having a type attribute, regardless of the value + div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + if args: + attrs = args[:] + else: + attrs = attrDict.items() + attrs = [(k,v) for k,v in attrs] + def pa(s,l,tokens): + for attrName,attrValue in attrs: + if attrName not in tokens: + raise ParseException(s,l,"no matching attribute " + attrName) + if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: + raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % + (attrName, tokens[attrName], attrValue)) + return pa +withAttribute.ANY_VALUE = object() + +def withClass(classname, namespace=''): + """ + Simplified version of C{L{withAttribute}} when matching on a div class - made + difficult because C{class} is a reserved word in Python. + + Example:: + html = ''' + <div> + Some text + <div class="grid">1 4 0 1 0</div> + <div class="graph">1,3 2,3 1,1</div> + <div>this <div> has no class</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + div_grid = div().setParseAction(withClass("grid")) + + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + classattr = "%s:class" % namespace if namespace else "class" + return withAttribute(**{classattr : classname}) + +opAssoc = _Constants() +opAssoc.LEFT = object() +opAssoc.RIGHT = object() + +def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): + """ + Helper method for constructing grammars of expressions made up of + operators working in a precedence hierarchy. Operators may be unary or + binary, left- or right-associative. Parse actions can also be attached + to operator expressions. The generated parser will also recognize the use + of parentheses to override operator precedences (see example below). + + Note: if you define a deep operator list, you may see performance issues + when using infixNotation. See L{ParserElement.enablePackrat} for a + mechanism to potentially improve your parser performance. + + Parameters: + - baseExpr - expression representing the most basic element for the nested + - opList - list of tuples, one for each operator precedence level in the + expression grammar; each tuple is of the form + (opExpr, numTerms, rightLeftAssoc, parseAction), where: + - opExpr is the pyparsing expression for the operator; + may also be a string, which will be converted to a Literal; + if numTerms is 3, opExpr is a tuple of two expressions, for the + two operators separating the 3 terms + - numTerms is the number of terms for this operator (must + be 1, 2, or 3) + - rightLeftAssoc is the indicator whether the operator is + right or left associative, using the pyparsing-defined + constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}. + - parseAction is the parse action to be associated with + expressions matching this operator expression (the + parse action tuple member may be omitted); if the parse action + is passed a tuple or list of functions, this is equivalent to + calling C{setParseAction(*fn)} (L{ParserElement.setParseAction}) + - lpar - expression for matching left-parentheses (default=C{Suppress('(')}) + - rpar - expression for matching right-parentheses (default=C{Suppress(')')}) + + Example:: + # simple example of four-function arithmetic with ints and variable names + integer = pyparsing_common.signed_integer + varname = pyparsing_common.identifier + + arith_expr = infixNotation(integer | varname, + [ + ('-', 1, opAssoc.RIGHT), + (oneOf('* /'), 2, opAssoc.LEFT), + (oneOf('+ -'), 2, opAssoc.LEFT), + ]) + + arith_expr.runTests(''' + 5+3*6 + (5+3)*6 + -2--11 + ''', fullDump=False) + prints:: + 5+3*6 + [[5, '+', [3, '*', 6]]] + + (5+3)*6 + [[[5, '+', 3], '*', 6]] + + -2--11 + [[['-', 2], '-', ['-', 11]]] + """ + ret = Forward() + lastExpr = baseExpr | ( lpar + ret + rpar ) + for i,operDef in enumerate(opList): + opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] + termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr + if arity == 3: + if opExpr is None or len(opExpr) != 2: + raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") + opExpr1, opExpr2 = opExpr + thisExpr = Forward().setName(termName) + if rightLeftAssoc == opAssoc.LEFT: + if arity == 1: + matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) + else: + matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ + Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + elif rightLeftAssoc == opAssoc.RIGHT: + if arity == 1: + # try to avoid LR with this extra test + if not isinstance(opExpr, Optional): + opExpr = Optional(opExpr) + matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) + else: + matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ + Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + else: + raise ValueError("operator must indicate right or left associativity") + if pa: + if isinstance(pa, (tuple, list)): + matchExpr.setParseAction(*pa) + else: + matchExpr.setParseAction(pa) + thisExpr <<= ( matchExpr.setName(termName) | lastExpr ) + lastExpr = thisExpr + ret <<= lastExpr + return ret + +operatorPrecedence = infixNotation +"""(Deprecated) Former name of C{L{infixNotation}}, will be dropped in a future release.""" + +dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes") +sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes") +quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'| + Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes") +unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal") + +def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): + """ + Helper method for defining nested lists enclosed in opening and closing + delimiters ("(" and ")" are the default). + + Parameters: + - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression + - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression + - content - expression for items within the nested lists (default=C{None}) + - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString}) + + If an expression is not provided for the content argument, the nested + expression will capture all whitespace-delimited content between delimiters + as a list of separate values. + + Use the C{ignoreExpr} argument to define expressions that may contain + opening or closing characters that should not be treated as opening + or closing characters for nesting, such as quotedString or a comment + expression. Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}. + The default is L{quotedString}, but if no expressions are to be ignored, + then pass C{None} for this argument. + + Example:: + data_type = oneOf("void int short long char float double") + decl_data_type = Combine(data_type + Optional(Word('*'))) + ident = Word(alphas+'_', alphanums+'_') + number = pyparsing_common.number + arg = Group(decl_data_type + ident) + LPAR,RPAR = map(Suppress, "()") + + code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) + + c_function = (decl_data_type("type") + + ident("name") + + LPAR + Optional(delimitedList(arg), [])("args") + RPAR + + code_body("body")) + c_function.ignore(cStyleComment) + + source_code = ''' + int is_odd(int x) { + return (x%2); + } + + int dec_to_hex(char hchar) { + if (hchar >= '0' && hchar <= '9') { + return (ord(hchar)-ord('0')); + } else { + return (10+ord(hchar)-ord('A')); + } + } + ''' + for func in c_function.searchString(source_code): + print("%(name)s (%(type)s) args: %(args)s" % func) + + prints:: + is_odd (int) args: [['int', 'x']] + dec_to_hex (int) args: [['char', 'hchar']] + """ + if opener == closer: + raise ValueError("opening and closing strings cannot be the same") + if content is None: + if isinstance(opener,basestring) and isinstance(closer,basestring): + if len(opener) == 1 and len(closer)==1: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS + ).setParseAction(lambda t:t[0].strip())) + else: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + ~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + raise ValueError("opening and closing arguments must be strings if no content expression is given") + ret = Forward() + if ignoreExpr is not None: + ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) + else: + ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) + ret.setName('nested %s%s expression' % (opener,closer)) + return ret + +def indentedBlock(blockStatementExpr, indentStack, indent=True): + """ + Helper method for defining space-delimited indentation blocks, such as + those used to define block statements in Python source code. + + Parameters: + - blockStatementExpr - expression defining syntax of statement that + is repeated within the indented block + - indentStack - list created by caller to manage indentation stack + (multiple statementWithIndentedBlock expressions within a single grammar + should share a common indentStack) + - indent - boolean indicating whether block must be indented beyond the + the current level; set to False for block of left-most statements + (default=C{True}) + + A valid block must contain at least one C{blockStatement}. + + Example:: + data = ''' + def A(z): + A1 + B = 100 + G = A2 + A2 + A3 + B + def BB(a,b,c): + BB1 + def BBA(): + bba1 + bba2 + bba3 + C + D + def spam(x,y): + def eggs(z): + pass + ''' + + + indentStack = [1] + stmt = Forward() + + identifier = Word(alphas, alphanums) + funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") + func_body = indentedBlock(stmt, indentStack) + funcDef = Group( funcDecl + func_body ) + + rvalue = Forward() + funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")") + rvalue << (funcCall | identifier | Word(nums)) + assignment = Group(identifier + "=" + rvalue) + stmt << ( funcDef | assignment | identifier ) + + module_body = OneOrMore(stmt) + + parseTree = module_body.parseString(data) + parseTree.pprint() + prints:: + [['def', + 'A', + ['(', 'z', ')'], + ':', + [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], + 'B', + ['def', + 'BB', + ['(', 'a', 'b', 'c', ')'], + ':', + [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], + 'C', + 'D', + ['def', + 'spam', + ['(', 'x', 'y', ')'], + ':', + [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] + """ + def checkPeerIndent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if curCol != indentStack[-1]: + if curCol > indentStack[-1]: + raise ParseFatalException(s,l,"illegal nesting") + raise ParseException(s,l,"not a peer entry") + + def checkSubIndent(s,l,t): + curCol = col(l,s) + if curCol > indentStack[-1]: + indentStack.append( curCol ) + else: + raise ParseException(s,l,"not a subentry") + + def checkUnindent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): + raise ParseException(s,l,"not an unindent") + indentStack.pop() + + NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) + INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT') + PEER = Empty().setParseAction(checkPeerIndent).setName('') + UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT') + if indent: + smExpr = Group( Optional(NL) + + #~ FollowedBy(blockStatementExpr) + + INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) + else: + smExpr = Group( Optional(NL) + + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) + blockStatementExpr.ignore(_bslash + LineEnd()) + return smExpr.setName('indented block') + +alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") +punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") + +anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag')) +_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\'')) +commonHTMLEntity = Regex('&(?P<entity>' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity") +def replaceHTMLEntity(t): + """Helper parser action to replace common HTML entities with their special characters""" + return _htmlEntityMap.get(t.entity) + +# it's easy to get these comment structures wrong - they're very common, so may as well make them available +cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment") +"Comment of the form C{/* ... */}" + +htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment") +"Comment of the form C{<!-- ... -->}" + +restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line") +dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment") +"Comment of the form C{// ... (to end of line)}" + +cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment") +"Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}" + +javaStyleComment = cppStyleComment +"Same as C{L{cppStyleComment}}" + +pythonStyleComment = Regex(r"#.*").setName("Python style comment") +"Comment of the form C{# ... (to end of line)}" + +_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') + + Optional( Word(" \t") + + ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem") +commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList") +"""(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas. + This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}.""" + +# some other useful expressions - using lower-case class name since we are really using this as a namespace +class pyparsing_common: + """ + Here are some common low-level expressions that may be useful in jump-starting parser development: + - numeric forms (L{integers<integer>}, L{reals<real>}, L{scientific notation<sci_real>}) + - common L{programming identifiers<identifier>} + - network addresses (L{MAC<mac_address>}, L{IPv4<ipv4_address>}, L{IPv6<ipv6_address>}) + - ISO8601 L{dates<iso8601_date>} and L{datetime<iso8601_datetime>} + - L{UUID<uuid>} + - L{comma-separated list<comma_separated_list>} + Parse actions: + - C{L{convertToInteger}} + - C{L{convertToFloat}} + - C{L{convertToDate}} + - C{L{convertToDatetime}} + - C{L{stripHTMLTags}} + - C{L{upcaseTokens}} + - C{L{downcaseTokens}} + + Example:: + pyparsing_common.number.runTests(''' + # any int or real number, returned as the appropriate type + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.fnumber.runTests(''' + # any int or real number, returned as float + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.hex_integer.runTests(''' + # hex numbers + 100 + FF + ''') + + pyparsing_common.fraction.runTests(''' + # fractions + 1/2 + -3/4 + ''') + + pyparsing_common.mixed_integer.runTests(''' + # mixed fractions + 1 + 1/2 + -3/4 + 1-3/4 + ''') + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(''' + # uuid + 12345678-1234-5678-1234-567812345678 + ''') + prints:: + # any int or real number, returned as the appropriate type + 100 + [100] + + -100 + [-100] + + +100 + [100] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # any int or real number, returned as float + 100 + [100.0] + + -100 + [-100.0] + + +100 + [100.0] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # hex numbers + 100 + [256] + + FF + [255] + + # fractions + 1/2 + [0.5] + + -3/4 + [-0.75] + + # mixed fractions + 1 + [1] + + 1/2 + [0.5] + + -3/4 + [-0.75] + + 1-3/4 + [1.75] + + # uuid + 12345678-1234-5678-1234-567812345678 + [UUID('12345678-1234-5678-1234-567812345678')] + """ + + convertToInteger = tokenMap(int) + """ + Parse action for converting parsed integers to Python int + """ + + convertToFloat = tokenMap(float) + """ + Parse action for converting parsed numbers to Python float + """ + + integer = Word(nums).setName("integer").setParseAction(convertToInteger) + """expression that parses an unsigned integer, returns an int""" + + hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16)) + """expression that parses a hexadecimal integer, returns an int""" + + signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger) + """expression that parses an integer with optional leading sign, returns an int""" + + fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction") + """fractional expression of an integer divided by an integer, returns a float""" + fraction.addParseAction(lambda t: t[0]/t[-1]) + + mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction") + """mixed integer of the form 'integer - fraction', with optional leading integer, returns float""" + mixed_integer.addParseAction(sum) + + real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat) + """expression that parses a floating point number and returns a float""" + + sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat) + """expression that parses a floating point number with optional scientific notation and returns a float""" + + # streamlining this expression makes the docs nicer-looking + number = (sci_real | real | signed_integer).streamline() + """any numeric expression, returns the corresponding Python type""" + + fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat) + """any int or real number, returned as float""" + + identifier = Word(alphas+'_', alphanums+'_').setName("identifier") + """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')""" + + ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address") + "IPv4 address (C{0.0.0.0 - 255.255.255.255})" + + _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer") + _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address") + _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address") + _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8) + _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address") + ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address") + "IPv6 address (long, short, or mixed form)" + + mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address") + "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)" + + @staticmethod + def convertToDate(fmt="%Y-%m-%d"): + """ + Helper to create a parse action for converting parsed date string to Python datetime.date + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"}) + + Example:: + date_expr = pyparsing_common.iso8601_date.copy() + date_expr.setParseAction(pyparsing_common.convertToDate()) + print(date_expr.parseString("1999-12-31")) + prints:: + [datetime.date(1999, 12, 31)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt).date() + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + @staticmethod + def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"): + """ + Helper to create a parse action for converting parsed datetime string to Python datetime.datetime + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"}) + + Example:: + dt_expr = pyparsing_common.iso8601_datetime.copy() + dt_expr.setParseAction(pyparsing_common.convertToDatetime()) + print(dt_expr.parseString("1999-12-31T23:59:59.999")) + prints:: + [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt) + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date") + "ISO8601 date (C{yyyy-mm-dd})" + + iso8601_datetime = Regex(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime") + "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}" + + uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID") + "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})" + + _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress() + @staticmethod + def stripHTMLTags(s, l, tokens): + """ + Parse action to remove HTML tags from web page HTML source + + Example:: + # strip HTML links from normal text + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>' + td,td_end = makeHTMLTags("TD") + table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end + + print(table_text.parseString(text).body) # -> 'More info at the pyparsing wiki page' + """ + return pyparsing_common._html_stripper.transformString(tokens[0]) + + _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') + + Optional( White(" \t") ) ) ).streamline().setName("commaItem") + comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list") + """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" + + upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper())) + """Parse action to convert tokens to upper case.""" + + downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower())) + """Parse action to convert tokens to lower case.""" + + +if __name__ == "__main__": + + selectToken = CaselessLiteral("select") + fromToken = CaselessLiteral("from") + + ident = Word(alphas, alphanums + "_$") + + columnName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + columnNameList = Group(delimitedList(columnName)).setName("columns") + columnSpec = ('*' | columnNameList) + + tableName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + tableNameList = Group(delimitedList(tableName)).setName("tables") + + simpleSQL = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables") + + # demo runTests method, including embedded comments in test string + simpleSQL.runTests(""" + # '*' as column list and dotted table name + select * from SYS.XYZZY + + # caseless match on "SELECT", and casts back to "select" + SELECT * from XYZZY, ABC + + # list of column names, and mixed case SELECT keyword + Select AA,BB,CC from Sys.dual + + # multiple tables + Select A, B, C from Sys.dual, Table2 + + # invalid SELECT keyword - should fail + Xelect A, B, C from Sys.dual + + # incomplete command - should fail + Select + + # invalid column name - should fail + Select ^^^ frox Sys.dual + + """) + + pyparsing_common.number.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + # any int or real number, returned as float + pyparsing_common.fnumber.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + pyparsing_common.hex_integer.runTests(""" + 100 + FF + """) + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(""" + 12345678-1234-5678-1234-567812345678 + """) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__init__.py new file mode 100644 index 0000000..8dc7315 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__init__.py @@ -0,0 +1,3 @@ +from .core import TomlError +from .parser import load, loads +from .writer import dump, dumps diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/core.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/core.py new file mode 100644 index 0000000..c182734 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/core.py @@ -0,0 +1,13 @@ +class TomlError(RuntimeError): + def __init__(self, message, line, col, filename): + RuntimeError.__init__(self, message, line, col, filename) + self.message = message + self.line = line + self.col = col + self.filename = filename + + def __str__(self): + return '{}({}, {}): {}'.format(self.filename, self.line, self.col, self.message) + + def __repr__(self): + return 'TomlError({!r}, {!r}, {!r}, {!r})'.format(self.message, self.line, self.col, self.filename) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/parser.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/parser.py new file mode 100644 index 0000000..7fc3d34 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/parser.py @@ -0,0 +1,374 @@ +import string, re, sys, datetime +from .core import TomlError + +if sys.version_info[0] == 2: + _chr = unichr +else: + _chr = chr + +def load(fin, translate=lambda t, x, v: v): + return loads(fin.read(), translate=translate, filename=getattr(fin, 'name', repr(fin))) + +def loads(s, filename='<string>', translate=lambda t, x, v: v): + if isinstance(s, bytes): + s = s.decode('utf-8') + + s = s.replace('\r\n', '\n') + + root = {} + tables = {} + scope = root + + src = _Source(s, filename=filename) + ast = _p_toml(src) + + def error(msg): + raise TomlError(msg, pos[0], pos[1], filename) + + def process_value(v): + kind, text, value, pos = v + if kind == 'str' and value.startswith('\n'): + value = value[1:] + if kind == 'array': + if value and any(k != value[0][0] for k, t, v, p in value[1:]): + error('array-type-mismatch') + value = [process_value(item) for item in value] + elif kind == 'table': + value = dict([(k, process_value(value[k])) for k in value]) + return translate(kind, text, value) + + for kind, value, pos in ast: + if kind == 'kv': + k, v = value + if k in scope: + error('duplicate_keys. Key "{0}" was used more than once.'.format(k)) + scope[k] = process_value(v) + else: + is_table_array = (kind == 'table_array') + cur = tables + for name in value[:-1]: + if isinstance(cur.get(name), list): + d, cur = cur[name][-1] + else: + d, cur = cur.setdefault(name, (None, {})) + + scope = {} + name = value[-1] + if name not in cur: + if is_table_array: + cur[name] = [(scope, {})] + else: + cur[name] = (scope, {}) + elif isinstance(cur[name], list): + if not is_table_array: + error('table_type_mismatch') + cur[name].append((scope, {})) + else: + if is_table_array: + error('table_type_mismatch') + old_scope, next_table = cur[name] + if old_scope is not None: + error('duplicate_tables') + cur[name] = (scope, next_table) + + def merge_tables(scope, tables): + if scope is None: + scope = {} + for k in tables: + if k in scope: + error('key_table_conflict') + v = tables[k] + if isinstance(v, list): + scope[k] = [merge_tables(sc, tbl) for sc, tbl in v] + else: + scope[k] = merge_tables(v[0], v[1]) + return scope + + return merge_tables(root, tables) + +class _Source: + def __init__(self, s, filename=None): + self.s = s + self._pos = (1, 1) + self._last = None + self._filename = filename + self.backtrack_stack = [] + + def last(self): + return self._last + + def pos(self): + return self._pos + + def fail(self): + return self._expect(None) + + def consume_dot(self): + if self.s: + self._last = self.s[0] + self.s = self[1:] + self._advance(self._last) + return self._last + return None + + def expect_dot(self): + return self._expect(self.consume_dot()) + + def consume_eof(self): + if not self.s: + self._last = '' + return True + return False + + def expect_eof(self): + return self._expect(self.consume_eof()) + + def consume(self, s): + if self.s.startswith(s): + self.s = self.s[len(s):] + self._last = s + self._advance(s) + return True + return False + + def expect(self, s): + return self._expect(self.consume(s)) + + def consume_re(self, re): + m = re.match(self.s) + if m: + self.s = self.s[len(m.group(0)):] + self._last = m + self._advance(m.group(0)) + return m + return None + + def expect_re(self, re): + return self._expect(self.consume_re(re)) + + def __enter__(self): + self.backtrack_stack.append((self.s, self._pos)) + + def __exit__(self, type, value, traceback): + if type is None: + self.backtrack_stack.pop() + else: + self.s, self._pos = self.backtrack_stack.pop() + return type == TomlError + + def commit(self): + self.backtrack_stack[-1] = (self.s, self._pos) + + def _expect(self, r): + if not r: + raise TomlError('msg', self._pos[0], self._pos[1], self._filename) + return r + + def _advance(self, s): + suffix_pos = s.rfind('\n') + if suffix_pos == -1: + self._pos = (self._pos[0], self._pos[1] + len(s)) + else: + self._pos = (self._pos[0] + s.count('\n'), len(s) - suffix_pos) + +_ews_re = re.compile(r'(?:[ \t]|#[^\n]*\n|#[^\n]*\Z|\n)*') +def _p_ews(s): + s.expect_re(_ews_re) + +_ws_re = re.compile(r'[ \t]*') +def _p_ws(s): + s.expect_re(_ws_re) + +_escapes = { 'b': '\b', 'n': '\n', 'r': '\r', 't': '\t', '"': '"', '\'': '\'', + '\\': '\\', '/': '/', 'f': '\f' } + +_basicstr_re = re.compile(r'[^"\\\000-\037]*') +_short_uni_re = re.compile(r'u([0-9a-fA-F]{4})') +_long_uni_re = re.compile(r'U([0-9a-fA-F]{8})') +_escapes_re = re.compile('[bnrt"\'\\\\/f]') +_newline_esc_re = re.compile('\n[ \t\n]*') +def _p_basicstr_content(s, content=_basicstr_re): + res = [] + while True: + res.append(s.expect_re(content).group(0)) + if not s.consume('\\'): + break + if s.consume_re(_newline_esc_re): + pass + elif s.consume_re(_short_uni_re) or s.consume_re(_long_uni_re): + res.append(_chr(int(s.last().group(1), 16))) + else: + s.expect_re(_escapes_re) + res.append(_escapes[s.last().group(0)]) + return ''.join(res) + +_key_re = re.compile(r'[0-9a-zA-Z-_]+') +def _p_key(s): + with s: + s.expect('"') + r = _p_basicstr_content(s, _basicstr_re) + s.expect('"') + return r + if s.consume('\''): + if s.consume('\'\''): + r = s.expect_re(_litstr_ml_re).group(0) + s.expect('\'\'\'') + else: + r = s.expect_re(_litstr_re).group(0) + s.expect('\'') + return r + return s.expect_re(_key_re).group(0) + +_float_re = re.compile(r'[+-]?(?:0|[1-9](?:_?\d)*)(?:\.\d(?:_?\d)*)?(?:[eE][+-]?(?:\d(?:_?\d)*))?') +_datetime_re = re.compile(r'(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d+)?(?:Z|([+-]\d{2}):(\d{2}))') + +_basicstr_ml_re = re.compile(r'(?:(?:|"|"")[^"\\\000-\011\013-\037])*') +_litstr_re = re.compile(r"[^'\000-\037]*") +_litstr_ml_re = re.compile(r"(?:(?:|'|'')(?:[^'\000-\011\013-\037]))*") +def _p_value(s): + pos = s.pos() + + if s.consume('true'): + return 'bool', s.last(), True, pos + if s.consume('false'): + return 'bool', s.last(), False, pos + + if s.consume('"'): + if s.consume('""'): + r = _p_basicstr_content(s, _basicstr_ml_re) + s.expect('"""') + else: + r = _p_basicstr_content(s, _basicstr_re) + s.expect('"') + return 'str', r, r, pos + + if s.consume('\''): + if s.consume('\'\''): + r = s.expect_re(_litstr_ml_re).group(0) + s.expect('\'\'\'') + else: + r = s.expect_re(_litstr_re).group(0) + s.expect('\'') + return 'str', r, r, pos + + if s.consume_re(_datetime_re): + m = s.last() + s0 = m.group(0) + r = map(int, m.groups()[:6]) + if m.group(7): + micro = float(m.group(7)) + else: + micro = 0 + + if m.group(8): + g = int(m.group(8), 10) * 60 + int(m.group(9), 10) + tz = _TimeZone(datetime.timedelta(0, g * 60)) + else: + tz = _TimeZone(datetime.timedelta(0, 0)) + + y, m, d, H, M, S = r + dt = datetime.datetime(y, m, d, H, M, S, int(micro * 1000000), tz) + return 'datetime', s0, dt, pos + + if s.consume_re(_float_re): + m = s.last().group(0) + r = m.replace('_','') + if '.' in m or 'e' in m or 'E' in m: + return 'float', m, float(r), pos + else: + return 'int', m, int(r, 10), pos + + if s.consume('['): + items = [] + with s: + while True: + _p_ews(s) + items.append(_p_value(s)) + s.commit() + _p_ews(s) + s.expect(',') + s.commit() + _p_ews(s) + s.expect(']') + return 'array', None, items, pos + + if s.consume('{'): + _p_ws(s) + items = {} + if not s.consume('}'): + k = _p_key(s) + _p_ws(s) + s.expect('=') + _p_ws(s) + items[k] = _p_value(s) + _p_ws(s) + while s.consume(','): + _p_ws(s) + k = _p_key(s) + _p_ws(s) + s.expect('=') + _p_ws(s) + items[k] = _p_value(s) + _p_ws(s) + s.expect('}') + return 'table', None, items, pos + + s.fail() + +def _p_stmt(s): + pos = s.pos() + if s.consume( '['): + is_array = s.consume('[') + _p_ws(s) + keys = [_p_key(s)] + _p_ws(s) + while s.consume('.'): + _p_ws(s) + keys.append(_p_key(s)) + _p_ws(s) + s.expect(']') + if is_array: + s.expect(']') + return 'table_array' if is_array else 'table', keys, pos + + key = _p_key(s) + _p_ws(s) + s.expect('=') + _p_ws(s) + value = _p_value(s) + return 'kv', (key, value), pos + +_stmtsep_re = re.compile(r'(?:[ \t]*(?:#[^\n]*)?\n)+[ \t]*') +def _p_toml(s): + stmts = [] + _p_ews(s) + with s: + stmts.append(_p_stmt(s)) + while True: + s.commit() + s.expect_re(_stmtsep_re) + stmts.append(_p_stmt(s)) + _p_ews(s) + s.expect_eof() + return stmts + +class _TimeZone(datetime.tzinfo): + def __init__(self, offset): + self._offset = offset + + def utcoffset(self, dt): + return self._offset + + def dst(self, dt): + return None + + def tzname(self, dt): + m = self._offset.total_seconds() // 60 + if m < 0: + res = '-' + m = -m + else: + res = '+' + h = m // 60 + m = m - h * 60 + return '{}{:.02}{:.02}'.format(res, h, m) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/writer.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/writer.py new file mode 100644 index 0000000..6eaf5d7 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/writer.py @@ -0,0 +1,127 @@ +from __future__ import unicode_literals +import io, datetime, math, sys + +if sys.version_info[0] == 3: + long = int + unicode = str + + +def dumps(obj, sort_keys=False): + fout = io.StringIO() + dump(obj, fout, sort_keys=sort_keys) + return fout.getvalue() + + +_escapes = {'\n': 'n', '\r': 'r', '\\': '\\', '\t': 't', '\b': 'b', '\f': 'f', '"': '"'} + + +def _escape_string(s): + res = [] + start = 0 + + def flush(): + if start != i: + res.append(s[start:i]) + return i + 1 + + i = 0 + while i < len(s): + c = s[i] + if c in '"\\\n\r\t\b\f': + start = flush() + res.append('\\' + _escapes[c]) + elif ord(c) < 0x20: + start = flush() + res.append('\\u%04x' % ord(c)) + i += 1 + + flush() + return '"' + ''.join(res) + '"' + + +def _escape_id(s): + if any(not c.isalnum() and c not in '-_' for c in s): + return _escape_string(s) + return s + + +def _format_list(v): + return '[{0}]'.format(', '.join(_format_value(obj) for obj in v)) + +# Formula from: +# https://docs.python.org/2/library/datetime.html#datetime.timedelta.total_seconds +# Once support for py26 is dropped, this can be replaced by td.total_seconds() +def _total_seconds(td): + return ((td.microseconds + + (td.seconds + td.days * 24 * 3600) * 10**6) / 10.0**6) + +def _format_value(v): + if isinstance(v, bool): + return 'true' if v else 'false' + if isinstance(v, int) or isinstance(v, long): + return unicode(v) + if isinstance(v, float): + if math.isnan(v) or math.isinf(v): + raise ValueError("{0} is not a valid TOML value".format(v)) + else: + return repr(v) + elif isinstance(v, unicode) or isinstance(v, bytes): + return _escape_string(v) + elif isinstance(v, datetime.datetime): + offs = v.utcoffset() + offs = _total_seconds(offs) // 60 if offs is not None else 0 + + if offs == 0: + suffix = 'Z' + else: + if offs > 0: + suffix = '+' + else: + suffix = '-' + offs = -offs + suffix = '{0}{1:.02}{2:.02}'.format(suffix, offs // 60, offs % 60) + + if v.microsecond: + return v.strftime('%Y-%m-%dT%H:%M:%S.%f') + suffix + else: + return v.strftime('%Y-%m-%dT%H:%M:%S') + suffix + elif isinstance(v, list): + return _format_list(v) + else: + raise RuntimeError(v) + + +def dump(obj, fout, sort_keys=False): + tables = [((), obj, False)] + + while tables: + name, table, is_array = tables.pop() + if name: + section_name = '.'.join(_escape_id(c) for c in name) + if is_array: + fout.write('[[{0}]]\n'.format(section_name)) + else: + fout.write('[{0}]\n'.format(section_name)) + + table_keys = sorted(table.keys()) if sort_keys else table.keys() + new_tables = [] + has_kv = False + for k in table_keys: + v = table[k] + if isinstance(v, dict): + new_tables.append((name + (k,), v, False)) + elif isinstance(v, list) and v and all(isinstance(o, dict) for o in v): + new_tables.extend((name + (k,), d, True) for d in v) + elif v is None: + # based on mojombo's comment: https://github.com/toml-lang/toml/issues/146#issuecomment-25019344 + fout.write( + '#{} = null # To use: uncomment and replace null with value\n'.format(_escape_id(k))) + has_kv = True + else: + fout.write('{0} = {1}\n'.format(_escape_id(k), _format_value(v))) + has_kv = True + + tables.extend(reversed(new_tables)) + + if (name or has_kv) and tables: + fout.write('\n') diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__init__.py new file mode 100644 index 0000000..ccd361a --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__init__.py @@ -0,0 +1,123 @@ +# -*- coding: utf-8 -*- + +# __ +# /__) _ _ _ _ _/ _ +# / ( (- (/ (/ (- _) / _) +# / + +""" +Requests HTTP Library +~~~~~~~~~~~~~~~~~~~~~ + +Requests is an HTTP library, written in Python, for human beings. Basic GET +usage: + + >>> import requests + >>> r = requests.get('https://www.python.org') + >>> r.status_code + 200 + >>> 'Python is a programming language' in r.content + True + +... or POST: + + >>> payload = dict(key1='value1', key2='value2') + >>> r = requests.post('http://httpbin.org/post', data=payload) + >>> print(r.text) + { + ... + "form": { + "key2": "value2", + "key1": "value1" + }, + ... + } + +The other HTTP methods are supported - see `requests.api`. Full documentation +is at <http://python-requests.org>. + +:copyright: (c) 2017 by Kenneth Reitz. +:license: Apache 2.0, see LICENSE for more details. +""" + +from pip._vendor import urllib3 +from pip._vendor import chardet +import warnings +from .exceptions import RequestsDependencyWarning + + +def check_compatibility(urllib3_version, chardet_version): + urllib3_version = urllib3_version.split('.') + assert urllib3_version != ['dev'] # Verify urllib3 isn't installed from git. + + # Sometimes, urllib3 only reports its version as 16.1. + if len(urllib3_version) == 2: + urllib3_version.append('0') + + # Check urllib3 for compatibility. + major, minor, patch = urllib3_version # noqa: F811 + major, minor, patch = int(major), int(minor), int(patch) + # urllib3 >= 1.21.1, <= 1.22 + assert major == 1 + assert minor >= 21 + assert minor <= 22 + + # Check chardet for compatibility. + major, minor, patch = chardet_version.split('.')[:3] + major, minor, patch = int(major), int(minor), int(patch) + # chardet >= 3.0.2, < 3.1.0 + assert major == 3 + assert minor < 1 + assert patch >= 2 + + +# Check imported dependencies for compatibility. +try: + check_compatibility(urllib3.__version__, chardet.__version__) +except (AssertionError, ValueError): + warnings.warn("urllib3 ({0}) or chardet ({1}) doesn't match a supported " + "version!".format(urllib3.__version__, chardet.__version__), + RequestsDependencyWarning) + +# Attempt to enable urllib3's SNI support, if possible +from pip._internal.compat import WINDOWS +if not WINDOWS: + try: + from pip._vendor.urllib3.contrib import pyopenssl + pyopenssl.inject_into_urllib3() + except ImportError: + pass + +# urllib3's DependencyWarnings should be silenced. +from pip._vendor.urllib3.exceptions import DependencyWarning +warnings.simplefilter('ignore', DependencyWarning) + +from .__version__ import __title__, __description__, __url__, __version__ +from .__version__ import __build__, __author__, __author_email__, __license__ +from .__version__ import __copyright__, __cake__ + +from . import utils +from . import packages +from .models import Request, Response, PreparedRequest +from .api import request, get, head, post, patch, put, delete, options +from .sessions import session, Session +from .status_codes import codes +from .exceptions import ( + RequestException, Timeout, URLRequired, + TooManyRedirects, HTTPError, ConnectionError, + FileModeWarning, ConnectTimeout, ReadTimeout +) + +# Set default logging handler to avoid "No handler found" warnings. +import logging +try: # Python 2.7+ + from logging import NullHandler +except ImportError: + class NullHandler(logging.Handler): + def emit(self, record): + pass + +logging.getLogger(__name__).addHandler(NullHandler()) + +# FileModeWarnings go off per the default. +warnings.simplefilter('default', FileModeWarning, append=True) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__version__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__version__.py new file mode 100644 index 0000000..dc33eef --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__version__.py @@ -0,0 +1,14 @@ +# .-. .-. .-. . . .-. .-. .-. .-. +# |( |- |.| | | |- `-. | `-. +# ' ' `-' `-`.`-' `-' `-' ' `-' + +__title__ = 'requests' +__description__ = 'Python HTTP for Humans.' +__url__ = 'http://python-requests.org' +__version__ = '2.18.4' +__build__ = 0x021804 +__author__ = 'Kenneth Reitz' +__author_email__ = 'me@kennethreitz.org' +__license__ = 'Apache 2.0' +__copyright__ = 'Copyright 2017 Kenneth Reitz' +__cake__ = u'\u2728 \U0001f370 \u2728' diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/_internal_utils.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/_internal_utils.py new file mode 100644 index 0000000..759d9a5 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/_internal_utils.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +""" +requests._internal_utils +~~~~~~~~~~~~~~ + +Provides utility functions that are consumed internally by Requests +which depend on extremely few external helpers (such as compat) +""" + +from .compat import is_py2, builtin_str, str + + +def to_native_string(string, encoding='ascii'): + """Given a string object, regardless of type, returns a representation of + that string in the native string type, encoding and decoding where + necessary. This assumes ASCII unless told otherwise. + """ + if isinstance(string, builtin_str): + out = string + else: + if is_py2: + out = string.encode(encoding) + else: + out = string.decode(encoding) + + return out + + +def unicode_is_ascii(u_string): + """Determine if unicode string only contains ASCII characters. + + :param str u_string: unicode string to check. Must be unicode + and not Python 2 `str`. + :rtype: bool + """ + assert isinstance(u_string, str) + try: + u_string.encode('ascii') + return True + except UnicodeEncodeError: + return False diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/adapters.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/adapters.py new file mode 100644 index 0000000..5787638 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/adapters.py @@ -0,0 +1,525 @@ +# -*- coding: utf-8 -*- + +""" +requests.adapters +~~~~~~~~~~~~~~~~~ + +This module contains the transport adapters that Requests uses to define +and maintain connections. +""" + +import os.path +import socket + +from pip._vendor.urllib3.poolmanager import PoolManager, proxy_from_url +from pip._vendor.urllib3.response import HTTPResponse +from pip._vendor.urllib3.util import Timeout as TimeoutSauce +from pip._vendor.urllib3.util.retry import Retry +from pip._vendor.urllib3.exceptions import ClosedPoolError +from pip._vendor.urllib3.exceptions import ConnectTimeoutError +from pip._vendor.urllib3.exceptions import HTTPError as _HTTPError +from pip._vendor.urllib3.exceptions import MaxRetryError +from pip._vendor.urllib3.exceptions import NewConnectionError +from pip._vendor.urllib3.exceptions import ProxyError as _ProxyError +from pip._vendor.urllib3.exceptions import ProtocolError +from pip._vendor.urllib3.exceptions import ReadTimeoutError +from pip._vendor.urllib3.exceptions import SSLError as _SSLError +from pip._vendor.urllib3.exceptions import ResponseError + +from .models import Response +from .compat import urlparse, basestring +from .utils import (DEFAULT_CA_BUNDLE_PATH, get_encoding_from_headers, + prepend_scheme_if_needed, get_auth_from_url, urldefragauth, + select_proxy) +from .structures import CaseInsensitiveDict +from .cookies import extract_cookies_to_jar +from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError, + ProxyError, RetryError, InvalidSchema) +from .auth import _basic_auth_str + +try: + from pip._vendor.urllib3.contrib.socks import SOCKSProxyManager +except ImportError: + def SOCKSProxyManager(*args, **kwargs): + raise InvalidSchema("Missing dependencies for SOCKS support.") + +DEFAULT_POOLBLOCK = False +DEFAULT_POOLSIZE = 10 +DEFAULT_RETRIES = 0 +DEFAULT_POOL_TIMEOUT = None + + +class BaseAdapter(object): + """The Base Transport Adapter""" + + def __init__(self): + super(BaseAdapter, self).__init__() + + def send(self, request, stream=False, timeout=None, verify=True, + cert=None, proxies=None): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) <timeouts>` tuple. + :type timeout: float or tuple + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + """ + raise NotImplementedError + + def close(self): + """Cleans up adapter specific items.""" + raise NotImplementedError + + +class HTTPAdapter(BaseAdapter): + """The built-in HTTP Adapter for urllib3. + + Provides a general-case interface for Requests sessions to contact HTTP and + HTTPS urls by implementing the Transport Adapter interface. This class will + usually be created by the :class:`Session <Session>` class under the + covers. + + :param pool_connections: The number of urllib3 connection pools to cache. + :param pool_maxsize: The maximum number of connections to save in the pool. + :param max_retries: The maximum number of retries each connection + should attempt. Note, this applies only to failed DNS lookups, socket + connections and connection timeouts, never to requests where data has + made it to the server. By default, Requests does not retry failed + connections. If you need granular control over the conditions under + which we retry a request, import urllib3's ``Retry`` class and pass + that instead. + :param pool_block: Whether the connection pool should block for connections. + + Usage:: + + >>> import requests + >>> s = requests.Session() + >>> a = requests.adapters.HTTPAdapter(max_retries=3) + >>> s.mount('http://', a) + """ + __attrs__ = ['max_retries', 'config', '_pool_connections', '_pool_maxsize', + '_pool_block'] + + def __init__(self, pool_connections=DEFAULT_POOLSIZE, + pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES, + pool_block=DEFAULT_POOLBLOCK): + if max_retries == DEFAULT_RETRIES: + self.max_retries = Retry(0, read=False) + else: + self.max_retries = Retry.from_int(max_retries) + self.config = {} + self.proxy_manager = {} + + super(HTTPAdapter, self).__init__() + + self._pool_connections = pool_connections + self._pool_maxsize = pool_maxsize + self._pool_block = pool_block + + self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block) + + def __getstate__(self): + return dict((attr, getattr(self, attr, None)) for attr in + self.__attrs__) + + def __setstate__(self, state): + # Can't handle by adding 'proxy_manager' to self.__attrs__ because + # self.poolmanager uses a lambda function, which isn't pickleable. + self.proxy_manager = {} + self.config = {} + + for attr, value in state.items(): + setattr(self, attr, value) + + self.init_poolmanager(self._pool_connections, self._pool_maxsize, + block=self._pool_block) + + def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs): + """Initializes a urllib3 PoolManager. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param connections: The number of urllib3 connection pools to cache. + :param maxsize: The maximum number of connections to save in the pool. + :param block: Block when no free connections are available. + :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager. + """ + # save these values for pickling + self._pool_connections = connections + self._pool_maxsize = maxsize + self._pool_block = block + + self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize, + block=block, strict=True, **pool_kwargs) + + def proxy_manager_for(self, proxy, **proxy_kwargs): + """Return urllib3 ProxyManager for the given proxy. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param proxy: The proxy to return a urllib3 ProxyManager for. + :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager. + :returns: ProxyManager + :rtype: urllib3.ProxyManager + """ + if proxy in self.proxy_manager: + manager = self.proxy_manager[proxy] + elif proxy.lower().startswith('socks'): + username, password = get_auth_from_url(proxy) + manager = self.proxy_manager[proxy] = SOCKSProxyManager( + proxy, + username=username, + password=password, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs + ) + else: + proxy_headers = self.proxy_headers(proxy) + manager = self.proxy_manager[proxy] = proxy_from_url( + proxy, + proxy_headers=proxy_headers, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs) + + return manager + + def cert_verify(self, conn, url, verify, cert): + """Verify a SSL certificate. This method should not be called from user + code, and is only exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param conn: The urllib3 connection object associated with the cert. + :param url: The requested URL. + :param verify: Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: The SSL certificate to verify. + """ + if url.lower().startswith('https') and verify: + + cert_loc = None + + # Allow self-specified cert location. + if verify is not True: + cert_loc = verify + + if not cert_loc: + cert_loc = DEFAULT_CA_BUNDLE_PATH + + if not cert_loc or not os.path.exists(cert_loc): + raise IOError("Could not find a suitable TLS CA certificate bundle, " + "invalid path: {0}".format(cert_loc)) + + conn.cert_reqs = 'CERT_REQUIRED' + + if not os.path.isdir(cert_loc): + conn.ca_certs = cert_loc + else: + conn.ca_cert_dir = cert_loc + else: + conn.cert_reqs = 'CERT_NONE' + conn.ca_certs = None + conn.ca_cert_dir = None + + if cert: + if not isinstance(cert, basestring): + conn.cert_file = cert[0] + conn.key_file = cert[1] + else: + conn.cert_file = cert + conn.key_file = None + if conn.cert_file and not os.path.exists(conn.cert_file): + raise IOError("Could not find the TLS certificate file, " + "invalid path: {0}".format(conn.cert_file)) + if conn.key_file and not os.path.exists(conn.key_file): + raise IOError("Could not find the TLS key file, " + "invalid path: {0}".format(conn.key_file)) + + def build_response(self, req, resp): + """Builds a :class:`Response <requests.Response>` object from a urllib3 + response. This should not be called from user code, and is only exposed + for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>` + + :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response. + :param resp: The urllib3 response object. + :rtype: requests.Response + """ + response = Response() + + # Fallback to None if there's no status_code, for whatever reason. + response.status_code = getattr(resp, 'status', None) + + # Make headers case-insensitive. + response.headers = CaseInsensitiveDict(getattr(resp, 'headers', {})) + + # Set encoding. + response.encoding = get_encoding_from_headers(response.headers) + response.raw = resp + response.reason = response.raw.reason + + if isinstance(req.url, bytes): + response.url = req.url.decode('utf-8') + else: + response.url = req.url + + # Add new cookies from the server. + extract_cookies_to_jar(response.cookies, req, resp) + + # Give the Response some context. + response.request = req + response.connection = self + + return response + + def get_connection(self, url, proxies=None): + """Returns a urllib3 connection for the given URL. This should not be + called from user code, and is only exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param url: The URL to connect to. + :param proxies: (optional) A Requests-style dictionary of proxies used on this request. + :rtype: urllib3.ConnectionPool + """ + proxy = select_proxy(url, proxies) + + if proxy: + proxy = prepend_scheme_if_needed(proxy, 'http') + proxy_manager = self.proxy_manager_for(proxy) + conn = proxy_manager.connection_from_url(url) + else: + # Only scheme should be lower case + parsed = urlparse(url) + url = parsed.geturl() + conn = self.poolmanager.connection_from_url(url) + + return conn + + def close(self): + """Disposes of any internal state. + + Currently, this closes the PoolManager and any active ProxyManager, + which closes any pooled connections. + """ + self.poolmanager.clear() + for proxy in self.proxy_manager.values(): + proxy.clear() + + def request_url(self, request, proxies): + """Obtain the url to use when making the final request. + + If the message is being sent through a HTTP proxy, the full URL has to + be used. Otherwise, we should only use the path portion of the URL. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs. + :rtype: str + """ + proxy = select_proxy(request.url, proxies) + scheme = urlparse(request.url).scheme + + is_proxied_http_request = (proxy and scheme != 'https') + using_socks_proxy = False + if proxy: + proxy_scheme = urlparse(proxy).scheme.lower() + using_socks_proxy = proxy_scheme.startswith('socks') + + url = request.path_url + if is_proxied_http_request and not using_socks_proxy: + url = urldefragauth(request.url) + + return url + + def add_headers(self, request, **kwargs): + """Add any headers needed by the connection. As of v2.0 this does + nothing by default, but is left for overriding by users that subclass + the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to. + :param kwargs: The keyword arguments from the call to send(). + """ + pass + + def proxy_headers(self, proxy): + """Returns a dictionary of the headers to add to any request sent + through a proxy. This works with urllib3 magic to ensure that they are + correctly sent to the proxy, rather than in a tunnelled request if + CONNECT is being used. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param proxies: The url of the proxy being used for this request. + :rtype: dict + """ + headers = {} + username, password = get_auth_from_url(proxy) + + if username: + headers['Proxy-Authorization'] = _basic_auth_str(username, + password) + + return headers + + def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) <timeouts>` tuple. + :type timeout: float or tuple or urllib3 Timeout object + :param verify: (optional) Either a boolean, in which case it controls whether + we verify the server's TLS certificate, or a string, in which case it + must be a path to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + :rtype: requests.Response + """ + + conn = self.get_connection(request.url, proxies) + + self.cert_verify(conn, request.url, verify, cert) + url = self.request_url(request, proxies) + self.add_headers(request) + + chunked = not (request.body is None or 'Content-Length' in request.headers) + + if isinstance(timeout, tuple): + try: + connect, read = timeout + timeout = TimeoutSauce(connect=connect, read=read) + except ValueError as e: + # this may raise a string formatting error. + err = ("Invalid timeout {0}. Pass a (connect, read) " + "timeout tuple, or a single float to set " + "both timeouts to the same value".format(timeout)) + raise ValueError(err) + elif isinstance(timeout, TimeoutSauce): + pass + else: + timeout = TimeoutSauce(connect=timeout, read=timeout) + + try: + if not chunked: + resp = conn.urlopen( + method=request.method, + url=url, + body=request.body, + headers=request.headers, + redirect=False, + assert_same_host=False, + preload_content=False, + decode_content=False, + retries=self.max_retries, + timeout=timeout + ) + + # Send the request. + else: + if hasattr(conn, 'proxy_pool'): + conn = conn.proxy_pool + + low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT) + + try: + low_conn.putrequest(request.method, + url, + skip_accept_encoding=True) + + for header, value in request.headers.items(): + low_conn.putheader(header, value) + + low_conn.endheaders() + + for i in request.body: + low_conn.send(hex(len(i))[2:].encode('utf-8')) + low_conn.send(b'\r\n') + low_conn.send(i) + low_conn.send(b'\r\n') + low_conn.send(b'0\r\n\r\n') + + # Receive the response from the server + try: + # For Python 2.7+ versions, use buffering of HTTP + # responses + r = low_conn.getresponse(buffering=True) + except TypeError: + # For compatibility with Python 2.6 versions and back + r = low_conn.getresponse() + + resp = HTTPResponse.from_httplib( + r, + pool=conn, + connection=low_conn, + preload_content=False, + decode_content=False + ) + except: + # If we hit any problems here, clean up the connection. + # Then, reraise so that we can handle the actual exception. + low_conn.close() + raise + + except (ProtocolError, socket.error) as err: + raise ConnectionError(err, request=request) + + except MaxRetryError as e: + if isinstance(e.reason, ConnectTimeoutError): + # TODO: Remove this in 3.0.0: see #2811 + if not isinstance(e.reason, NewConnectionError): + raise ConnectTimeout(e, request=request) + + if isinstance(e.reason, ResponseError): + raise RetryError(e, request=request) + + if isinstance(e.reason, _ProxyError): + raise ProxyError(e, request=request) + + if isinstance(e.reason, _SSLError): + # This branch is for urllib3 v1.22 and later. + raise SSLError(e, request=request) + + raise ConnectionError(e, request=request) + + except ClosedPoolError as e: + raise ConnectionError(e, request=request) + + except _ProxyError as e: + raise ProxyError(e) + + except (_SSLError, _HTTPError) as e: + if isinstance(e, _SSLError): + # This branch is for urllib3 versions earlier than v1.22 + raise SSLError(e, request=request) + elif isinstance(e, ReadTimeoutError): + raise ReadTimeout(e, request=request) + else: + raise + + return self.build_response(request, resp) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/api.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/api.py new file mode 100644 index 0000000..bc2115c --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/api.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- + +""" +requests.api +~~~~~~~~~~~~ + +This module implements the Requests API. + +:copyright: (c) 2012 by Kenneth Reitz. +:license: Apache2, see LICENSE for more details. +""" + +from . import sessions + + +def request(method, url, **kwargs): + """Constructs and sends a :class:`Request <Request>`. + + :param method: method for the new :class:`Request` object. + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. + :param data: (optional) Dictionary or list of tuples ``[(key, value)]`` (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. + :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload. + ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')`` + or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string + defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers + to add for the file. + :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How many seconds to wait for the server to send data + before giving up, as a float, or a :ref:`(connect timeout, read + timeout) <timeouts>` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. + :param stream: (optional) if ``False``, the response content will be immediately downloaded. + :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair. + :return: :class:`Response <Response>` object + :rtype: requests.Response + + Usage:: + + >>> import requests + >>> req = requests.request('GET', 'http://httpbin.org/get') + <Response [200]> + """ + + # By using the 'with' statement we are sure the session is closed, thus we + # avoid leaving sockets open which can trigger a ResourceWarning in some + # cases, and look like a memory leak in others. + with sessions.Session() as session: + return session.request(method=method, url=url, **kwargs) + + +def get(url, params=None, **kwargs): + r"""Sends a GET request. + + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return request('get', url, params=params, **kwargs) + + +def options(url, **kwargs): + r"""Sends an OPTIONS request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return request('options', url, **kwargs) + + +def head(url, **kwargs): + r"""Sends a HEAD request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', False) + return request('head', url, **kwargs) + + +def post(url, data=None, json=None, **kwargs): + r"""Sends a POST request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('post', url, data=data, json=json, **kwargs) + + +def put(url, data=None, **kwargs): + r"""Sends a PUT request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('put', url, data=data, **kwargs) + + +def patch(url, data=None, **kwargs): + r"""Sends a PATCH request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('patch', url, data=data, **kwargs) + + +def delete(url, **kwargs): + r"""Sends a DELETE request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('delete', url, **kwargs) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/auth.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/auth.py new file mode 100644 index 0000000..1a182df --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/auth.py @@ -0,0 +1,293 @@ +# -*- coding: utf-8 -*- + +""" +requests.auth +~~~~~~~~~~~~~ + +This module contains the authentication handlers for Requests. +""" + +import os +import re +import time +import hashlib +import threading +import warnings + +from base64 import b64encode + +from .compat import urlparse, str, basestring +from .cookies import extract_cookies_to_jar +from ._internal_utils import to_native_string +from .utils import parse_dict_header + +CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded' +CONTENT_TYPE_MULTI_PART = 'multipart/form-data' + + +def _basic_auth_str(username, password): + """Returns a Basic Auth string.""" + + # "I want us to put a big-ol' comment on top of it that + # says that this behaviour is dumb but we need to preserve + # it because people are relying on it." + # - Lukasa + # + # These are here solely to maintain backwards compatibility + # for things like ints. This will be removed in 3.0.0. + if not isinstance(username, basestring): + warnings.warn( + "Non-string usernames will no longer be supported in Requests " + "3.0.0. Please convert the object you've passed in ({0!r}) to " + "a string or bytes object in the near future to avoid " + "problems.".format(username), + category=DeprecationWarning, + ) + username = str(username) + + if not isinstance(password, basestring): + warnings.warn( + "Non-string passwords will no longer be supported in Requests " + "3.0.0. Please convert the object you've passed in ({0!r}) to " + "a string or bytes object in the near future to avoid " + "problems.".format(password), + category=DeprecationWarning, + ) + password = str(password) + # -- End Removal -- + + if isinstance(username, str): + username = username.encode('latin1') + + if isinstance(password, str): + password = password.encode('latin1') + + authstr = 'Basic ' + to_native_string( + b64encode(b':'.join((username, password))).strip() + ) + + return authstr + + +class AuthBase(object): + """Base class that all auth implementations derive from""" + + def __call__(self, r): + raise NotImplementedError('Auth hooks must be callable.') + + +class HTTPBasicAuth(AuthBase): + """Attaches HTTP Basic Authentication to the given Request object.""" + + def __init__(self, username, password): + self.username = username + self.password = password + + def __eq__(self, other): + return all([ + self.username == getattr(other, 'username', None), + self.password == getattr(other, 'password', None) + ]) + + def __ne__(self, other): + return not self == other + + def __call__(self, r): + r.headers['Authorization'] = _basic_auth_str(self.username, self.password) + return r + + +class HTTPProxyAuth(HTTPBasicAuth): + """Attaches HTTP Proxy Authentication to a given Request object.""" + + def __call__(self, r): + r.headers['Proxy-Authorization'] = _basic_auth_str(self.username, self.password) + return r + + +class HTTPDigestAuth(AuthBase): + """Attaches HTTP Digest Authentication to the given Request object.""" + + def __init__(self, username, password): + self.username = username + self.password = password + # Keep state in per-thread local storage + self._thread_local = threading.local() + + def init_per_thread_state(self): + # Ensure state is initialized just once per-thread + if not hasattr(self._thread_local, 'init'): + self._thread_local.init = True + self._thread_local.last_nonce = '' + self._thread_local.nonce_count = 0 + self._thread_local.chal = {} + self._thread_local.pos = None + self._thread_local.num_401_calls = None + + def build_digest_header(self, method, url): + """ + :rtype: str + """ + + realm = self._thread_local.chal['realm'] + nonce = self._thread_local.chal['nonce'] + qop = self._thread_local.chal.get('qop') + algorithm = self._thread_local.chal.get('algorithm') + opaque = self._thread_local.chal.get('opaque') + hash_utf8 = None + + if algorithm is None: + _algorithm = 'MD5' + else: + _algorithm = algorithm.upper() + # lambdas assume digest modules are imported at the top level + if _algorithm == 'MD5' or _algorithm == 'MD5-SESS': + def md5_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.md5(x).hexdigest() + hash_utf8 = md5_utf8 + elif _algorithm == 'SHA': + def sha_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.sha1(x).hexdigest() + hash_utf8 = sha_utf8 + + KD = lambda s, d: hash_utf8("%s:%s" % (s, d)) + + if hash_utf8 is None: + return None + + # XXX not implemented yet + entdig = None + p_parsed = urlparse(url) + #: path is request-uri defined in RFC 2616 which should not be empty + path = p_parsed.path or "/" + if p_parsed.query: + path += '?' + p_parsed.query + + A1 = '%s:%s:%s' % (self.username, realm, self.password) + A2 = '%s:%s' % (method, path) + + HA1 = hash_utf8(A1) + HA2 = hash_utf8(A2) + + if nonce == self._thread_local.last_nonce: + self._thread_local.nonce_count += 1 + else: + self._thread_local.nonce_count = 1 + ncvalue = '%08x' % self._thread_local.nonce_count + s = str(self._thread_local.nonce_count).encode('utf-8') + s += nonce.encode('utf-8') + s += time.ctime().encode('utf-8') + s += os.urandom(8) + + cnonce = (hashlib.sha1(s).hexdigest()[:16]) + if _algorithm == 'MD5-SESS': + HA1 = hash_utf8('%s:%s:%s' % (HA1, nonce, cnonce)) + + if not qop: + respdig = KD(HA1, "%s:%s" % (nonce, HA2)) + elif qop == 'auth' or 'auth' in qop.split(','): + noncebit = "%s:%s:%s:%s:%s" % ( + nonce, ncvalue, cnonce, 'auth', HA2 + ) + respdig = KD(HA1, noncebit) + else: + # XXX handle auth-int. + return None + + self._thread_local.last_nonce = nonce + + # XXX should the partial digests be encoded too? + base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \ + 'response="%s"' % (self.username, realm, nonce, path, respdig) + if opaque: + base += ', opaque="%s"' % opaque + if algorithm: + base += ', algorithm="%s"' % algorithm + if entdig: + base += ', digest="%s"' % entdig + if qop: + base += ', qop="auth", nc=%s, cnonce="%s"' % (ncvalue, cnonce) + + return 'Digest %s' % (base) + + def handle_redirect(self, r, **kwargs): + """Reset num_401_calls counter on redirects.""" + if r.is_redirect: + self._thread_local.num_401_calls = 1 + + def handle_401(self, r, **kwargs): + """ + Takes the given response and tries digest-auth, if needed. + + :rtype: requests.Response + """ + + # If response is not 4xx, do not auth + # See https://github.com/requests/requests/issues/3772 + if not 400 <= r.status_code < 500: + self._thread_local.num_401_calls = 1 + return r + + if self._thread_local.pos is not None: + # Rewind the file position indicator of the body to where + # it was to resend the request. + r.request.body.seek(self._thread_local.pos) + s_auth = r.headers.get('www-authenticate', '') + + if 'digest' in s_auth.lower() and self._thread_local.num_401_calls < 2: + + self._thread_local.num_401_calls += 1 + pat = re.compile(r'digest ', flags=re.IGNORECASE) + self._thread_local.chal = parse_dict_header(pat.sub('', s_auth, count=1)) + + # Consume content and release the original connection + # to allow our new request to reuse the same one. + r.content + r.close() + prep = r.request.copy() + extract_cookies_to_jar(prep._cookies, r.request, r.raw) + prep.prepare_cookies(prep._cookies) + + prep.headers['Authorization'] = self.build_digest_header( + prep.method, prep.url) + _r = r.connection.send(prep, **kwargs) + _r.history.append(r) + _r.request = prep + + return _r + + self._thread_local.num_401_calls = 1 + return r + + def __call__(self, r): + # Initialize per-thread state, if needed + self.init_per_thread_state() + # If we have a saved nonce, skip the 401 + if self._thread_local.last_nonce: + r.headers['Authorization'] = self.build_digest_header(r.method, r.url) + try: + self._thread_local.pos = r.body.tell() + except AttributeError: + # In the case of HTTPDigestAuth being reused and the body of + # the previous request was a file-like object, pos has the + # file position of the previous body. Ensure it's set to + # None. + self._thread_local.pos = None + r.register_hook('response', self.handle_401) + r.register_hook('response', self.handle_redirect) + self._thread_local.num_401_calls = 1 + + return r + + def __eq__(self, other): + return all([ + self.username == getattr(other, 'username', None), + self.password == getattr(other, 'password', None) + ]) + + def __ne__(self, other): + return not self == other diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/certs.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/certs.py new file mode 100644 index 0000000..06a594e --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/certs.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +requests.certs +~~~~~~~~~~~~~~ + +This module returns the preferred default CA certificate bundle. There is +only one — the one from the certifi package. + +If you are packaging Requests, e.g., for a Linux distribution or a managed +environment, you can change the definition of where() to return a separately +packaged CA bundle. +""" +from pip._vendor.certifi import where + +if __name__ == '__main__': + print(where()) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/compat.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/compat.py new file mode 100644 index 0000000..20da3e0 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/compat.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- + +""" +requests.compat +~~~~~~~~~~~~~~~ + +This module handles import compatibility issues between Python 2 and +Python 3. +""" + +from pip._vendor import chardet + +import sys + +# ------- +# Pythons +# ------- + +# Syntax sugar. +_ver = sys.version_info + +#: Python 2.x? +is_py2 = (_ver[0] == 2) + +#: Python 3.x? +is_py3 = (_ver[0] == 3) + +# Note: We've patched out simplejson support in pip because it prevents +# upgrading simplejson on Windows. +# try: +# import simplejson as json +# except (ImportError, SyntaxError): +# # simplejson does not support Python 3.2, it throws a SyntaxError +# # because of u'...' Unicode literals. +import json + +# --------- +# Specifics +# --------- + +if is_py2: + from urllib import ( + quote, unquote, quote_plus, unquote_plus, urlencode, getproxies, + proxy_bypass, proxy_bypass_environment, getproxies_environment) + from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag + from urllib2 import parse_http_list + import cookielib + from Cookie import Morsel + from StringIO import StringIO + + from pip._vendor.urllib3.packages.ordered_dict import OrderedDict + + builtin_str = str + bytes = str + str = unicode + basestring = basestring + numeric_types = (int, long, float) + integer_types = (int, long) + +elif is_py3: + from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag + from urllib.request import parse_http_list, getproxies, proxy_bypass, proxy_bypass_environment, getproxies_environment + from http import cookiejar as cookielib + from http.cookies import Morsel + from io import StringIO + from collections import OrderedDict + + builtin_str = str + str = str + bytes = bytes + basestring = (str, bytes) + numeric_types = (int, float) + integer_types = (int,) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/cookies.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/cookies.py new file mode 100644 index 0000000..ab3c88b --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/cookies.py @@ -0,0 +1,542 @@ +# -*- coding: utf-8 -*- + +""" +requests.cookies +~~~~~~~~~~~~~~~~ + +Compatibility code to be able to use `cookielib.CookieJar` with requests. + +requests.utils imports from here, so be careful with imports. +""" + +import copy +import time +import calendar +import collections + +from ._internal_utils import to_native_string +from .compat import cookielib, urlparse, urlunparse, Morsel + +try: + import threading +except ImportError: + import dummy_threading as threading + + +class MockRequest(object): + """Wraps a `requests.Request` to mimic a `urllib2.Request`. + + The code in `cookielib.CookieJar` expects this interface in order to correctly + manage cookie policies, i.e., determine whether a cookie can be set, given the + domains of the request and the cookie. + + The original request object is read-only. The client is responsible for collecting + the new headers via `get_new_headers()` and interpreting them appropriately. You + probably want `get_cookie_header`, defined below. + """ + + def __init__(self, request): + self._r = request + self._new_headers = {} + self.type = urlparse(self._r.url).scheme + + def get_type(self): + return self.type + + def get_host(self): + return urlparse(self._r.url).netloc + + def get_origin_req_host(self): + return self.get_host() + + def get_full_url(self): + # Only return the response's URL if the user hadn't set the Host + # header + if not self._r.headers.get('Host'): + return self._r.url + # If they did set it, retrieve it and reconstruct the expected domain + host = to_native_string(self._r.headers['Host'], encoding='utf-8') + parsed = urlparse(self._r.url) + # Reconstruct the URL as we expect it + return urlunparse([ + parsed.scheme, host, parsed.path, parsed.params, parsed.query, + parsed.fragment + ]) + + def is_unverifiable(self): + return True + + def has_header(self, name): + return name in self._r.headers or name in self._new_headers + + def get_header(self, name, default=None): + return self._r.headers.get(name, self._new_headers.get(name, default)) + + def add_header(self, key, val): + """cookielib has no legitimate use for this method; add it back if you find one.""" + raise NotImplementedError("Cookie headers should be added with add_unredirected_header()") + + def add_unredirected_header(self, name, value): + self._new_headers[name] = value + + def get_new_headers(self): + return self._new_headers + + @property + def unverifiable(self): + return self.is_unverifiable() + + @property + def origin_req_host(self): + return self.get_origin_req_host() + + @property + def host(self): + return self.get_host() + + +class MockResponse(object): + """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`. + + ...what? Basically, expose the parsed HTTP headers from the server response + the way `cookielib` expects to see them. + """ + + def __init__(self, headers): + """Make a MockResponse for `cookielib` to read. + + :param headers: a httplib.HTTPMessage or analogous carrying the headers + """ + self._headers = headers + + def info(self): + return self._headers + + def getheaders(self, name): + self._headers.getheaders(name) + + +def extract_cookies_to_jar(jar, request, response): + """Extract the cookies from the response into a CookieJar. + + :param jar: cookielib.CookieJar (not necessarily a RequestsCookieJar) + :param request: our own requests.Request object + :param response: urllib3.HTTPResponse object + """ + if not (hasattr(response, '_original_response') and + response._original_response): + return + # the _original_response field is the wrapped httplib.HTTPResponse object, + req = MockRequest(request) + # pull out the HTTPMessage with the headers and put it in the mock: + res = MockResponse(response._original_response.msg) + jar.extract_cookies(res, req) + + +def get_cookie_header(jar, request): + """ + Produce an appropriate Cookie header string to be sent with `request`, or None. + + :rtype: str + """ + r = MockRequest(request) + jar.add_cookie_header(r) + return r.get_new_headers().get('Cookie') + + +def remove_cookie_by_name(cookiejar, name, domain=None, path=None): + """Unsets a cookie by name, by default over all domains and paths. + + Wraps CookieJar.clear(), is O(n). + """ + clearables = [] + for cookie in cookiejar: + if cookie.name != name: + continue + if domain is not None and domain != cookie.domain: + continue + if path is not None and path != cookie.path: + continue + clearables.append((cookie.domain, cookie.path, cookie.name)) + + for domain, path, name in clearables: + cookiejar.clear(domain, path, name) + + +class CookieConflictError(RuntimeError): + """There are two cookies that meet the criteria specified in the cookie jar. + Use .get and .set and include domain and path args in order to be more specific. + """ + + +class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping): + """Compatibility class; is a cookielib.CookieJar, but exposes a dict + interface. + + This is the CookieJar we create by default for requests and sessions that + don't specify one, since some clients may expect response.cookies and + session.cookies to support dict operations. + + Requests does not use the dict interface internally; it's just for + compatibility with external client code. All requests code should work + out of the box with externally provided instances of ``CookieJar``, e.g. + ``LWPCookieJar`` and ``FileCookieJar``. + + Unlike a regular CookieJar, this class is pickleable. + + .. warning:: dictionary operations that are normally O(1) may be O(n). + """ + + def get(self, name, default=None, domain=None, path=None): + """Dict-like get() that also supports optional domain and path args in + order to resolve naming collisions from using one cookie jar over + multiple domains. + + .. warning:: operation is O(n), not O(1). + """ + try: + return self._find_no_duplicates(name, domain, path) + except KeyError: + return default + + def set(self, name, value, **kwargs): + """Dict-like set() that also supports optional domain and path args in + order to resolve naming collisions from using one cookie jar over + multiple domains. + """ + # support client code that unsets cookies by assignment of a None value: + if value is None: + remove_cookie_by_name(self, name, domain=kwargs.get('domain'), path=kwargs.get('path')) + return + + if isinstance(value, Morsel): + c = morsel_to_cookie(value) + else: + c = create_cookie(name, value, **kwargs) + self.set_cookie(c) + return c + + def iterkeys(self): + """Dict-like iterkeys() that returns an iterator of names of cookies + from the jar. + + .. seealso:: itervalues() and iteritems(). + """ + for cookie in iter(self): + yield cookie.name + + def keys(self): + """Dict-like keys() that returns a list of names of cookies from the + jar. + + .. seealso:: values() and items(). + """ + return list(self.iterkeys()) + + def itervalues(self): + """Dict-like itervalues() that returns an iterator of values of cookies + from the jar. + + .. seealso:: iterkeys() and iteritems(). + """ + for cookie in iter(self): + yield cookie.value + + def values(self): + """Dict-like values() that returns a list of values of cookies from the + jar. + + .. seealso:: keys() and items(). + """ + return list(self.itervalues()) + + def iteritems(self): + """Dict-like iteritems() that returns an iterator of name-value tuples + from the jar. + + .. seealso:: iterkeys() and itervalues(). + """ + for cookie in iter(self): + yield cookie.name, cookie.value + + def items(self): + """Dict-like items() that returns a list of name-value tuples from the + jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a + vanilla python dict of key value pairs. + + .. seealso:: keys() and values(). + """ + return list(self.iteritems()) + + def list_domains(self): + """Utility method to list all the domains in the jar.""" + domains = [] + for cookie in iter(self): + if cookie.domain not in domains: + domains.append(cookie.domain) + return domains + + def list_paths(self): + """Utility method to list all the paths in the jar.""" + paths = [] + for cookie in iter(self): + if cookie.path not in paths: + paths.append(cookie.path) + return paths + + def multiple_domains(self): + """Returns True if there are multiple domains in the jar. + Returns False otherwise. + + :rtype: bool + """ + domains = [] + for cookie in iter(self): + if cookie.domain is not None and cookie.domain in domains: + return True + domains.append(cookie.domain) + return False # there is only one domain in jar + + def get_dict(self, domain=None, path=None): + """Takes as an argument an optional domain and path and returns a plain + old Python dict of name-value pairs of cookies that meet the + requirements. + + :rtype: dict + """ + dictionary = {} + for cookie in iter(self): + if ( + (domain is None or cookie.domain == domain) and + (path is None or cookie.path == path) + ): + dictionary[cookie.name] = cookie.value + return dictionary + + def __contains__(self, name): + try: + return super(RequestsCookieJar, self).__contains__(name) + except CookieConflictError: + return True + + def __getitem__(self, name): + """Dict-like __getitem__() for compatibility with client code. Throws + exception if there are more than one cookie with name. In that case, + use the more explicit get() method instead. + + .. warning:: operation is O(n), not O(1). + """ + return self._find_no_duplicates(name) + + def __setitem__(self, name, value): + """Dict-like __setitem__ for compatibility with client code. Throws + exception if there is already a cookie of that name in the jar. In that + case, use the more explicit set() method instead. + """ + self.set(name, value) + + def __delitem__(self, name): + """Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s + ``remove_cookie_by_name()``. + """ + remove_cookie_by_name(self, name) + + def set_cookie(self, cookie, *args, **kwargs): + if hasattr(cookie.value, 'startswith') and cookie.value.startswith('"') and cookie.value.endswith('"'): + cookie.value = cookie.value.replace('\\"', '') + return super(RequestsCookieJar, self).set_cookie(cookie, *args, **kwargs) + + def update(self, other): + """Updates this jar with cookies from another CookieJar or dict-like""" + if isinstance(other, cookielib.CookieJar): + for cookie in other: + self.set_cookie(copy.copy(cookie)) + else: + super(RequestsCookieJar, self).update(other) + + def _find(self, name, domain=None, path=None): + """Requests uses this method internally to get cookie values. + + If there are conflicting cookies, _find arbitrarily chooses one. + See _find_no_duplicates if you want an exception thrown if there are + conflicting cookies. + + :param name: a string containing name of cookie + :param domain: (optional) string containing domain of cookie + :param path: (optional) string containing path of cookie + :return: cookie.value + """ + for cookie in iter(self): + if cookie.name == name: + if domain is None or cookie.domain == domain: + if path is None or cookie.path == path: + return cookie.value + + raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) + + def _find_no_duplicates(self, name, domain=None, path=None): + """Both ``__get_item__`` and ``get`` call this function: it's never + used elsewhere in Requests. + + :param name: a string containing name of cookie + :param domain: (optional) string containing domain of cookie + :param path: (optional) string containing path of cookie + :raises KeyError: if cookie is not found + :raises CookieConflictError: if there are multiple cookies + that match name and optionally domain and path + :return: cookie.value + """ + toReturn = None + for cookie in iter(self): + if cookie.name == name: + if domain is None or cookie.domain == domain: + if path is None or cookie.path == path: + if toReturn is not None: # if there are multiple cookies that meet passed in criteria + raise CookieConflictError('There are multiple cookies with name, %r' % (name)) + toReturn = cookie.value # we will eventually return this as long as no cookie conflict + + if toReturn: + return toReturn + raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) + + def __getstate__(self): + """Unlike a normal CookieJar, this class is pickleable.""" + state = self.__dict__.copy() + # remove the unpickleable RLock object + state.pop('_cookies_lock') + return state + + def __setstate__(self, state): + """Unlike a normal CookieJar, this class is pickleable.""" + self.__dict__.update(state) + if '_cookies_lock' not in self.__dict__: + self._cookies_lock = threading.RLock() + + def copy(self): + """Return a copy of this RequestsCookieJar.""" + new_cj = RequestsCookieJar() + new_cj.update(self) + return new_cj + + +def _copy_cookie_jar(jar): + if jar is None: + return None + + if hasattr(jar, 'copy'): + # We're dealing with an instance of RequestsCookieJar + return jar.copy() + # We're dealing with a generic CookieJar instance + new_jar = copy.copy(jar) + new_jar.clear() + for cookie in jar: + new_jar.set_cookie(copy.copy(cookie)) + return new_jar + + +def create_cookie(name, value, **kwargs): + """Make a cookie from underspecified parameters. + + By default, the pair of `name` and `value` will be set for the domain '' + and sent on every request (this is sometimes called a "supercookie"). + """ + result = dict( + version=0, + name=name, + value=value, + port=None, + domain='', + path='/', + secure=False, + expires=None, + discard=True, + comment=None, + comment_url=None, + rest={'HttpOnly': None}, + rfc2109=False,) + + badargs = set(kwargs) - set(result) + if badargs: + err = 'create_cookie() got unexpected keyword arguments: %s' + raise TypeError(err % list(badargs)) + + result.update(kwargs) + result['port_specified'] = bool(result['port']) + result['domain_specified'] = bool(result['domain']) + result['domain_initial_dot'] = result['domain'].startswith('.') + result['path_specified'] = bool(result['path']) + + return cookielib.Cookie(**result) + + +def morsel_to_cookie(morsel): + """Convert a Morsel object into a Cookie containing the one k/v pair.""" + + expires = None + if morsel['max-age']: + try: + expires = int(time.time() + int(morsel['max-age'])) + except ValueError: + raise TypeError('max-age: %s must be integer' % morsel['max-age']) + elif morsel['expires']: + time_template = '%a, %d-%b-%Y %H:%M:%S GMT' + expires = calendar.timegm( + time.strptime(morsel['expires'], time_template) + ) + return create_cookie( + comment=morsel['comment'], + comment_url=bool(morsel['comment']), + discard=False, + domain=morsel['domain'], + expires=expires, + name=morsel.key, + path=morsel['path'], + port=None, + rest={'HttpOnly': morsel['httponly']}, + rfc2109=False, + secure=bool(morsel['secure']), + value=morsel.value, + version=morsel['version'] or 0, + ) + + +def cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True): + """Returns a CookieJar from a key/value dictionary. + + :param cookie_dict: Dict of key/values to insert into CookieJar. + :param cookiejar: (optional) A cookiejar to add the cookies to. + :param overwrite: (optional) If False, will not replace cookies + already in the jar with new ones. + """ + if cookiejar is None: + cookiejar = RequestsCookieJar() + + if cookie_dict is not None: + names_from_jar = [cookie.name for cookie in cookiejar] + for name in cookie_dict: + if overwrite or (name not in names_from_jar): + cookiejar.set_cookie(create_cookie(name, cookie_dict[name])) + + return cookiejar + + +def merge_cookies(cookiejar, cookies): + """Add cookies to cookiejar and returns a merged CookieJar. + + :param cookiejar: CookieJar object to add the cookies to. + :param cookies: Dictionary or CookieJar object to be added. + """ + if not isinstance(cookiejar, cookielib.CookieJar): + raise ValueError('You can only merge into CookieJar') + + if isinstance(cookies, dict): + cookiejar = cookiejar_from_dict( + cookies, cookiejar=cookiejar, overwrite=False) + elif isinstance(cookies, cookielib.CookieJar): + try: + cookiejar.update(cookies) + except AttributeError: + for cookie_in_jar in cookies: + cookiejar.set_cookie(cookie_in_jar) + + return cookiejar diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/exceptions.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/exceptions.py new file mode 100644 index 0000000..3e5d0b2 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/exceptions.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- + +""" +requests.exceptions +~~~~~~~~~~~~~~~~~~~ + +This module contains the set of Requests' exceptions. +""" +from pip._vendor.urllib3.exceptions import HTTPError as BaseHTTPError + + +class RequestException(IOError): + """There was an ambiguous exception that occurred while handling your + request. + """ + + def __init__(self, *args, **kwargs): + """Initialize RequestException with `request` and `response` objects.""" + response = kwargs.pop('response', None) + self.response = response + self.request = kwargs.pop('request', None) + if (response is not None and not self.request and + hasattr(response, 'request')): + self.request = self.response.request + super(RequestException, self).__init__(*args, **kwargs) + + +class HTTPError(RequestException): + """An HTTP error occurred.""" + + +class ConnectionError(RequestException): + """A Connection error occurred.""" + + +class ProxyError(ConnectionError): + """A proxy error occurred.""" + + +class SSLError(ConnectionError): + """An SSL error occurred.""" + + +class Timeout(RequestException): + """The request timed out. + + Catching this error will catch both + :exc:`~requests.exceptions.ConnectTimeout` and + :exc:`~requests.exceptions.ReadTimeout` errors. + """ + + +class ConnectTimeout(ConnectionError, Timeout): + """The request timed out while trying to connect to the remote server. + + Requests that produced this error are safe to retry. + """ + + +class ReadTimeout(Timeout): + """The server did not send any data in the allotted amount of time.""" + + +class URLRequired(RequestException): + """A valid URL is required to make a request.""" + + +class TooManyRedirects(RequestException): + """Too many redirects.""" + + +class MissingSchema(RequestException, ValueError): + """The URL schema (e.g. http or https) is missing.""" + + +class InvalidSchema(RequestException, ValueError): + """See defaults.py for valid schemas.""" + + +class InvalidURL(RequestException, ValueError): + """The URL provided was somehow invalid.""" + + +class InvalidHeader(RequestException, ValueError): + """The header value provided was somehow invalid.""" + + +class ChunkedEncodingError(RequestException): + """The server declared chunked encoding but sent an invalid chunk.""" + + +class ContentDecodingError(RequestException, BaseHTTPError): + """Failed to decode response content""" + + +class StreamConsumedError(RequestException, TypeError): + """The content for this response was already consumed""" + + +class RetryError(RequestException): + """Custom retries logic failed""" + + +class UnrewindableBodyError(RequestException): + """Requests encountered an error when trying to rewind a body""" + +# Warnings + + +class RequestsWarning(Warning): + """Base warning for Requests.""" + pass + + +class FileModeWarning(RequestsWarning, DeprecationWarning): + """A file was opened in text mode, but Requests determined its binary length.""" + pass + + +class RequestsDependencyWarning(RequestsWarning): + """An imported dependency doesn't match the expected version range.""" + pass diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/help.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/help.py new file mode 100644 index 0000000..7c4b193 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/help.py @@ -0,0 +1,120 @@ +"""Module containing bug report helper(s).""" +from __future__ import print_function + +import json +import platform +import sys +import ssl + +from pip._vendor import idna +from pip._vendor import urllib3 +from pip._vendor import chardet + +from . import __version__ as requests_version + +try: + from .packages.urllib3.contrib import pyopenssl +except ImportError: + pyopenssl = None + OpenSSL = None + cryptography = None +else: + import OpenSSL + import cryptography + + +def _implementation(): + """Return a dict with the Python implementation and version. + + Provide both the name and the version of the Python implementation + currently running. For example, on CPython 2.7.5 it will return + {'name': 'CPython', 'version': '2.7.5'}. + + This function works best on CPython and PyPy: in particular, it probably + doesn't work for Jython or IronPython. Future investigation should be done + to work out the correct shape of the code for those platforms. + """ + implementation = platform.python_implementation() + + if implementation == 'CPython': + implementation_version = platform.python_version() + elif implementation == 'PyPy': + implementation_version = '%s.%s.%s' % (sys.pypy_version_info.major, + sys.pypy_version_info.minor, + sys.pypy_version_info.micro) + if sys.pypy_version_info.releaselevel != 'final': + implementation_version = ''.join([ + implementation_version, sys.pypy_version_info.releaselevel + ]) + elif implementation == 'Jython': + implementation_version = platform.python_version() # Complete Guess + elif implementation == 'IronPython': + implementation_version = platform.python_version() # Complete Guess + else: + implementation_version = 'Unknown' + + return {'name': implementation, 'version': implementation_version} + + +def info(): + """Generate information for a bug report.""" + try: + platform_info = { + 'system': platform.system(), + 'release': platform.release(), + } + except IOError: + platform_info = { + 'system': 'Unknown', + 'release': 'Unknown', + } + + implementation_info = _implementation() + urllib3_info = {'version': urllib3.__version__} + chardet_info = {'version': chardet.__version__} + + pyopenssl_info = { + 'version': None, + 'openssl_version': '', + } + if OpenSSL: + pyopenssl_info = { + 'version': OpenSSL.__version__, + 'openssl_version': '%x' % OpenSSL.SSL.OPENSSL_VERSION_NUMBER, + } + cryptography_info = { + 'version': getattr(cryptography, '__version__', ''), + } + idna_info = { + 'version': getattr(idna, '__version__', ''), + } + + # OPENSSL_VERSION_NUMBER doesn't exist in the Python 2.6 ssl module. + system_ssl = getattr(ssl, 'OPENSSL_VERSION_NUMBER', None) + system_ssl_info = { + 'version': '%x' % system_ssl if system_ssl is not None else '' + } + + return { + 'platform': platform_info, + 'implementation': implementation_info, + 'system_ssl': system_ssl_info, + 'using_pyopenssl': pyopenssl is not None, + 'pyOpenSSL': pyopenssl_info, + 'urllib3': urllib3_info, + 'chardet': chardet_info, + 'cryptography': cryptography_info, + 'idna': idna_info, + 'requests': { + 'version': requests_version, + }, + } + + +def main(): + """Pretty-print the bug information as JSON.""" + print(json.dumps(info(), sort_keys=True, indent=2)) + + +if __name__ == '__main__': + main() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/hooks.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/hooks.py new file mode 100644 index 0000000..32b32de --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/hooks.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +""" +requests.hooks +~~~~~~~~~~~~~~ + +This module provides the capabilities for the Requests hooks system. + +Available hooks: + +``response``: + The response generated from a Request. +""" +HOOKS = ['response'] + + +def default_hooks(): + return dict((event, []) for event in HOOKS) + +# TODO: response is the only one + + +def dispatch_hook(key, hooks, hook_data, **kwargs): + """Dispatches a hook dictionary on a given piece of data.""" + hooks = hooks or dict() + hooks = hooks.get(key) + if hooks: + if hasattr(hooks, '__call__'): + hooks = [hooks] + for hook in hooks: + _hook_data = hook(hook_data, **kwargs) + if _hook_data is not None: + hook_data = _hook_data + return hook_data diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/models.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/models.py new file mode 100644 index 0000000..4ab4fec --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/models.py @@ -0,0 +1,948 @@ +# -*- coding: utf-8 -*- + +""" +requests.models +~~~~~~~~~~~~~~~ + +This module contains the primary objects that power Requests. +""" + +import collections +import datetime +import sys + +# Import encoding now, to avoid implicit import later. +# Implicit import within threads may cause LookupError when standard library is in a ZIP, +# such as in Embedded Python. See https://github.com/requests/requests/issues/3578. +import encodings.idna + +from pip._vendor.urllib3.fields import RequestField +from pip._vendor.urllib3.filepost import encode_multipart_formdata +from pip._vendor.urllib3.util import parse_url +from pip._vendor.urllib3.exceptions import ( + DecodeError, ReadTimeoutError, ProtocolError, LocationParseError) + +from io import UnsupportedOperation +from .hooks import default_hooks +from .structures import CaseInsensitiveDict + +from .auth import HTTPBasicAuth +from .cookies import cookiejar_from_dict, get_cookie_header, _copy_cookie_jar +from .exceptions import ( + HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError, + ContentDecodingError, ConnectionError, StreamConsumedError) +from ._internal_utils import to_native_string, unicode_is_ascii +from .utils import ( + guess_filename, get_auth_from_url, requote_uri, + stream_decode_response_unicode, to_key_val_list, parse_header_links, + iter_slices, guess_json_utf, super_len, check_header_validity) +from .compat import ( + cookielib, urlunparse, urlsplit, urlencode, str, bytes, + is_py2, chardet, builtin_str, basestring) +from .compat import json as complexjson +from .status_codes import codes + +#: The set of HTTP status codes that indicate an automatically +#: processable redirect. +REDIRECT_STATI = ( + codes.moved, # 301 + codes.found, # 302 + codes.other, # 303 + codes.temporary_redirect, # 307 + codes.permanent_redirect, # 308 +) + +DEFAULT_REDIRECT_LIMIT = 30 +CONTENT_CHUNK_SIZE = 10 * 1024 +ITER_CHUNK_SIZE = 512 + + +class RequestEncodingMixin(object): + @property + def path_url(self): + """Build the path URL to use.""" + + url = [] + + p = urlsplit(self.url) + + path = p.path + if not path: + path = '/' + + url.append(path) + + query = p.query + if query: + url.append('?') + url.append(query) + + return ''.join(url) + + @staticmethod + def _encode_params(data): + """Encode parameters in a piece of data. + + Will successfully encode parameters when passed as a dict or a list of + 2-tuples. Order is retained if data is a list of 2-tuples but arbitrary + if parameters are supplied as a dict. + """ + + if isinstance(data, (str, bytes)): + return data + elif hasattr(data, 'read'): + return data + elif hasattr(data, '__iter__'): + result = [] + for k, vs in to_key_val_list(data): + if isinstance(vs, basestring) or not hasattr(vs, '__iter__'): + vs = [vs] + for v in vs: + if v is not None: + result.append( + (k.encode('utf-8') if isinstance(k, str) else k, + v.encode('utf-8') if isinstance(v, str) else v)) + return urlencode(result, doseq=True) + else: + return data + + @staticmethod + def _encode_files(files, data): + """Build the body for a multipart/form-data request. + + Will successfully encode files when passed as a dict or a list of + tuples. Order is retained if data is a list of tuples but arbitrary + if parameters are supplied as a dict. + The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype) + or 4-tuples (filename, fileobj, contentype, custom_headers). + """ + if (not files): + raise ValueError("Files must be provided.") + elif isinstance(data, basestring): + raise ValueError("Data must not be a string.") + + new_fields = [] + fields = to_key_val_list(data or {}) + files = to_key_val_list(files or {}) + + for field, val in fields: + if isinstance(val, basestring) or not hasattr(val, '__iter__'): + val = [val] + for v in val: + if v is not None: + # Don't call str() on bytestrings: in Py3 it all goes wrong. + if not isinstance(v, bytes): + v = str(v) + + new_fields.append( + (field.decode('utf-8') if isinstance(field, bytes) else field, + v.encode('utf-8') if isinstance(v, str) else v)) + + for (k, v) in files: + # support for explicit filename + ft = None + fh = None + if isinstance(v, (tuple, list)): + if len(v) == 2: + fn, fp = v + elif len(v) == 3: + fn, fp, ft = v + else: + fn, fp, ft, fh = v + else: + fn = guess_filename(v) or k + fp = v + + if isinstance(fp, (str, bytes, bytearray)): + fdata = fp + else: + fdata = fp.read() + + rf = RequestField(name=k, data=fdata, filename=fn, headers=fh) + rf.make_multipart(content_type=ft) + new_fields.append(rf) + + body, content_type = encode_multipart_formdata(new_fields) + + return body, content_type + + +class RequestHooksMixin(object): + def register_hook(self, event, hook): + """Properly register a hook.""" + + if event not in self.hooks: + raise ValueError('Unsupported event specified, with event name "%s"' % (event)) + + if isinstance(hook, collections.Callable): + self.hooks[event].append(hook) + elif hasattr(hook, '__iter__'): + self.hooks[event].extend(h for h in hook if isinstance(h, collections.Callable)) + + def deregister_hook(self, event, hook): + """Deregister a previously registered hook. + Returns True if the hook existed, False if not. + """ + + try: + self.hooks[event].remove(hook) + return True + except ValueError: + return False + + +class Request(RequestHooksMixin): + """A user-created :class:`Request <Request>` object. + + Used to prepare a :class:`PreparedRequest <PreparedRequest>`, which is sent to the server. + + :param method: HTTP method to use. + :param url: URL to send. + :param headers: dictionary of headers to send. + :param files: dictionary of {filename: fileobject} files to multipart upload. + :param data: the body to attach to the request. If a dictionary is provided, form-encoding will take place. + :param json: json for the body to attach to the request (if files or data is not specified). + :param params: dictionary of URL parameters to append to the URL. + :param auth: Auth handler or (user, pass) tuple. + :param cookies: dictionary or CookieJar of cookies to attach to this request. + :param hooks: dictionary of callback hooks, for internal usage. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'http://httpbin.org/get') + >>> req.prepare() + <PreparedRequest [GET]> + """ + + def __init__(self, + method=None, url=None, headers=None, files=None, data=None, + params=None, auth=None, cookies=None, hooks=None, json=None): + + # Default empty dicts for dict params. + data = [] if data is None else data + files = [] if files is None else files + headers = {} if headers is None else headers + params = {} if params is None else params + hooks = {} if hooks is None else hooks + + self.hooks = default_hooks() + for (k, v) in list(hooks.items()): + self.register_hook(event=k, hook=v) + + self.method = method + self.url = url + self.headers = headers + self.files = files + self.data = data + self.json = json + self.params = params + self.auth = auth + self.cookies = cookies + + def __repr__(self): + return '<Request [%s]>' % (self.method) + + def prepare(self): + """Constructs a :class:`PreparedRequest <PreparedRequest>` for transmission and returns it.""" + p = PreparedRequest() + p.prepare( + method=self.method, + url=self.url, + headers=self.headers, + files=self.files, + data=self.data, + json=self.json, + params=self.params, + auth=self.auth, + cookies=self.cookies, + hooks=self.hooks, + ) + return p + + +class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): + """The fully mutable :class:`PreparedRequest <PreparedRequest>` object, + containing the exact bytes that will be sent to the server. + + Generated from either a :class:`Request <Request>` object or manually. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'http://httpbin.org/get') + >>> r = req.prepare() + <PreparedRequest [GET]> + + >>> s = requests.Session() + >>> s.send(r) + <Response [200]> + """ + + def __init__(self): + #: HTTP verb to send to the server. + self.method = None + #: HTTP URL to send the request to. + self.url = None + #: dictionary of HTTP headers. + self.headers = None + # The `CookieJar` used to create the Cookie header will be stored here + # after prepare_cookies is called + self._cookies = None + #: request body to send to the server. + self.body = None + #: dictionary of callback hooks, for internal usage. + self.hooks = default_hooks() + #: integer denoting starting position of a readable file-like body. + self._body_position = None + + def prepare(self, + method=None, url=None, headers=None, files=None, data=None, + params=None, auth=None, cookies=None, hooks=None, json=None): + """Prepares the entire request with the given parameters.""" + + self.prepare_method(method) + self.prepare_url(url, params) + self.prepare_headers(headers) + self.prepare_cookies(cookies) + self.prepare_body(data, files, json) + self.prepare_auth(auth, url) + + # Note that prepare_auth must be last to enable authentication schemes + # such as OAuth to work on a fully prepared request. + + # This MUST go after prepare_auth. Authenticators could add a hook + self.prepare_hooks(hooks) + + def __repr__(self): + return '<PreparedRequest [%s]>' % (self.method) + + def copy(self): + p = PreparedRequest() + p.method = self.method + p.url = self.url + p.headers = self.headers.copy() if self.headers is not None else None + p._cookies = _copy_cookie_jar(self._cookies) + p.body = self.body + p.hooks = self.hooks + p._body_position = self._body_position + return p + + def prepare_method(self, method): + """Prepares the given HTTP method.""" + self.method = method + if self.method is not None: + self.method = to_native_string(self.method.upper()) + + @staticmethod + def _get_idna_encoded_host(host): + from pip._vendor import idna + + try: + host = idna.encode(host, uts46=True).decode('utf-8') + except idna.IDNAError: + raise UnicodeError + return host + + def prepare_url(self, url, params): + """Prepares the given HTTP URL.""" + #: Accept objects that have string representations. + #: We're unable to blindly call unicode/str functions + #: as this will include the bytestring indicator (b'') + #: on python 3.x. + #: https://github.com/requests/requests/pull/2238 + if isinstance(url, bytes): + url = url.decode('utf8') + else: + url = unicode(url) if is_py2 else str(url) + + # Remove leading whitespaces from url + url = url.lstrip() + + # Don't do any URL preparation for non-HTTP schemes like `mailto`, + # `data` etc to work around exceptions from `url_parse`, which + # handles RFC 3986 only. + if ':' in url and not url.lower().startswith('http'): + self.url = url + return + + # Support for unicode domain names and paths. + try: + scheme, auth, host, port, path, query, fragment = parse_url(url) + except LocationParseError as e: + raise InvalidURL(*e.args) + + if not scheme: + error = ("Invalid URL {0!r}: No schema supplied. Perhaps you meant http://{0}?") + error = error.format(to_native_string(url, 'utf8')) + + raise MissingSchema(error) + + if not host: + raise InvalidURL("Invalid URL %r: No host supplied" % url) + + # In general, we want to try IDNA encoding the hostname if the string contains + # non-ASCII characters. This allows users to automatically get the correct IDNA + # behaviour. For strings containing only ASCII characters, we need to also verify + # it doesn't start with a wildcard (*), before allowing the unencoded hostname. + if not unicode_is_ascii(host): + try: + host = self._get_idna_encoded_host(host) + except UnicodeError: + raise InvalidURL('URL has an invalid label.') + elif host.startswith(u'*'): + raise InvalidURL('URL has an invalid label.') + + # Carefully reconstruct the network location + netloc = auth or '' + if netloc: + netloc += '@' + netloc += host + if port: + netloc += ':' + str(port) + + # Bare domains aren't valid URLs. + if not path: + path = '/' + + if is_py2: + if isinstance(scheme, str): + scheme = scheme.encode('utf-8') + if isinstance(netloc, str): + netloc = netloc.encode('utf-8') + if isinstance(path, str): + path = path.encode('utf-8') + if isinstance(query, str): + query = query.encode('utf-8') + if isinstance(fragment, str): + fragment = fragment.encode('utf-8') + + if isinstance(params, (str, bytes)): + params = to_native_string(params) + + enc_params = self._encode_params(params) + if enc_params: + if query: + query = '%s&%s' % (query, enc_params) + else: + query = enc_params + + url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment])) + self.url = url + + def prepare_headers(self, headers): + """Prepares the given HTTP headers.""" + + self.headers = CaseInsensitiveDict() + if headers: + for header in headers.items(): + # Raise exception on invalid header value. + check_header_validity(header) + name, value = header + self.headers[to_native_string(name)] = value + + def prepare_body(self, data, files, json=None): + """Prepares the given HTTP body data.""" + + # Check if file, fo, generator, iterator. + # If not, run through normal process. + + # Nottin' on you. + body = None + content_type = None + + if not data and json is not None: + # urllib3 requires a bytes-like body. Python 2's json.dumps + # provides this natively, but Python 3 gives a Unicode string. + content_type = 'application/json' + body = complexjson.dumps(json) + if not isinstance(body, bytes): + body = body.encode('utf-8') + + is_stream = all([ + hasattr(data, '__iter__'), + not isinstance(data, (basestring, list, tuple, collections.Mapping)) + ]) + + try: + length = super_len(data) + except (TypeError, AttributeError, UnsupportedOperation): + length = None + + if is_stream: + body = data + + if getattr(body, 'tell', None) is not None: + # Record the current file position before reading. + # This will allow us to rewind a file in the event + # of a redirect. + try: + self._body_position = body.tell() + except (IOError, OSError): + # This differentiates from None, allowing us to catch + # a failed `tell()` later when trying to rewind the body + self._body_position = object() + + if files: + raise NotImplementedError('Streamed bodies and files are mutually exclusive.') + + if length: + self.headers['Content-Length'] = builtin_str(length) + else: + self.headers['Transfer-Encoding'] = 'chunked' + else: + # Multi-part file uploads. + if files: + (body, content_type) = self._encode_files(files, data) + else: + if data: + body = self._encode_params(data) + if isinstance(data, basestring) or hasattr(data, 'read'): + content_type = None + else: + content_type = 'application/x-www-form-urlencoded' + + self.prepare_content_length(body) + + # Add content-type if it wasn't explicitly provided. + if content_type and ('content-type' not in self.headers): + self.headers['Content-Type'] = content_type + + self.body = body + + def prepare_content_length(self, body): + """Prepare Content-Length header based on request method and body""" + if body is not None: + length = super_len(body) + if length: + # If length exists, set it. Otherwise, we fallback + # to Transfer-Encoding: chunked. + self.headers['Content-Length'] = builtin_str(length) + elif self.method not in ('GET', 'HEAD') and self.headers.get('Content-Length') is None: + # Set Content-Length to 0 for methods that can have a body + # but don't provide one. (i.e. not GET or HEAD) + self.headers['Content-Length'] = '0' + + def prepare_auth(self, auth, url=''): + """Prepares the given HTTP auth data.""" + + # If no Auth is explicitly provided, extract it from the URL first. + if auth is None: + url_auth = get_auth_from_url(self.url) + auth = url_auth if any(url_auth) else None + + if auth: + if isinstance(auth, tuple) and len(auth) == 2: + # special-case basic HTTP auth + auth = HTTPBasicAuth(*auth) + + # Allow auth to make its changes. + r = auth(self) + + # Update self to reflect the auth changes. + self.__dict__.update(r.__dict__) + + # Recompute Content-Length + self.prepare_content_length(self.body) + + def prepare_cookies(self, cookies): + """Prepares the given HTTP cookie data. + + This function eventually generates a ``Cookie`` header from the + given cookies using cookielib. Due to cookielib's design, the header + will not be regenerated if it already exists, meaning this function + can only be called once for the life of the + :class:`PreparedRequest <PreparedRequest>` object. Any subsequent calls + to ``prepare_cookies`` will have no actual effect, unless the "Cookie" + header is removed beforehand. + """ + if isinstance(cookies, cookielib.CookieJar): + self._cookies = cookies + else: + self._cookies = cookiejar_from_dict(cookies) + + cookie_header = get_cookie_header(self._cookies, self) + if cookie_header is not None: + self.headers['Cookie'] = cookie_header + + def prepare_hooks(self, hooks): + """Prepares the given hooks.""" + # hooks can be passed as None to the prepare method and to this + # method. To prevent iterating over None, simply use an empty list + # if hooks is False-y + hooks = hooks or [] + for event in hooks: + self.register_hook(event, hooks[event]) + + +class Response(object): + """The :class:`Response <Response>` object, which contains a + server's response to an HTTP request. + """ + + __attrs__ = [ + '_content', 'status_code', 'headers', 'url', 'history', + 'encoding', 'reason', 'cookies', 'elapsed', 'request' + ] + + def __init__(self): + self._content = False + self._content_consumed = False + self._next = None + + #: Integer Code of responded HTTP Status, e.g. 404 or 200. + self.status_code = None + + #: Case-insensitive Dictionary of Response Headers. + #: For example, ``headers['content-encoding']`` will return the + #: value of a ``'Content-Encoding'`` response header. + self.headers = CaseInsensitiveDict() + + #: File-like object representation of response (for advanced usage). + #: Use of ``raw`` requires that ``stream=True`` be set on the request. + # This requirement does not apply for use internally to Requests. + self.raw = None + + #: Final URL location of Response. + self.url = None + + #: Encoding to decode with when accessing r.text. + self.encoding = None + + #: A list of :class:`Response <Response>` objects from + #: the history of the Request. Any redirect responses will end + #: up here. The list is sorted from the oldest to the most recent request. + self.history = [] + + #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK". + self.reason = None + + #: A CookieJar of Cookies the server sent back. + self.cookies = cookiejar_from_dict({}) + + #: The amount of time elapsed between sending the request + #: and the arrival of the response (as a timedelta). + #: This property specifically measures the time taken between sending + #: the first byte of the request and finishing parsing the headers. It + #: is therefore unaffected by consuming the response content or the + #: value of the ``stream`` keyword argument. + self.elapsed = datetime.timedelta(0) + + #: The :class:`PreparedRequest <PreparedRequest>` object to which this + #: is a response. + self.request = None + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def __getstate__(self): + # Consume everything; accessing the content attribute makes + # sure the content has been fully read. + if not self._content_consumed: + self.content + + return dict( + (attr, getattr(self, attr, None)) + for attr in self.__attrs__ + ) + + def __setstate__(self, state): + for name, value in state.items(): + setattr(self, name, value) + + # pickled objects do not have .raw + setattr(self, '_content_consumed', True) + setattr(self, 'raw', None) + + def __repr__(self): + return '<Response [%s]>' % (self.status_code) + + def __bool__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __nonzero__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __iter__(self): + """Allows you to use a response as an iterator.""" + return self.iter_content(128) + + @property + def ok(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + try: + self.raise_for_status() + except HTTPError: + return False + return True + + @property + def is_redirect(self): + """True if this Response is a well-formed HTTP redirect that could have + been processed automatically (by :meth:`Session.resolve_redirects`). + """ + return ('location' in self.headers and self.status_code in REDIRECT_STATI) + + @property + def is_permanent_redirect(self): + """True if this Response one of the permanent versions of redirect.""" + return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect)) + + @property + def next(self): + """Returns a PreparedRequest for the next request in a redirect chain, if there is one.""" + return self._next + + @property + def apparent_encoding(self): + """The apparent encoding, provided by the chardet library.""" + return chardet.detect(self.content)['encoding'] + + def iter_content(self, chunk_size=1, decode_unicode=False): + """Iterates over the response data. When stream=True is set on the + request, this avoids reading the content at once into memory for + large responses. The chunk size is the number of bytes it should + read into memory. This is not necessarily the length of each item + returned as decoding can take place. + + chunk_size must be of type int or None. A value of None will + function differently depending on the value of `stream`. + stream=True will read data as it arrives in whatever size the + chunks are received. If stream=False, data is returned as + a single chunk. + + If decode_unicode is True, content will be decoded using the best + available encoding based on the response. + """ + + def generate(): + # Special case for urllib3. + if hasattr(self.raw, 'stream'): + try: + for chunk in self.raw.stream(chunk_size, decode_content=True): + yield chunk + except ProtocolError as e: + raise ChunkedEncodingError(e) + except DecodeError as e: + raise ContentDecodingError(e) + except ReadTimeoutError as e: + raise ConnectionError(e) + else: + # Standard file-like object. + while True: + chunk = self.raw.read(chunk_size) + if not chunk: + break + yield chunk + + self._content_consumed = True + + if self._content_consumed and isinstance(self._content, bool): + raise StreamConsumedError() + elif chunk_size is not None and not isinstance(chunk_size, int): + raise TypeError("chunk_size must be an int, it is instead a %s." % type(chunk_size)) + # simulate reading small chunks of the content + reused_chunks = iter_slices(self._content, chunk_size) + + stream_chunks = generate() + + chunks = reused_chunks if self._content_consumed else stream_chunks + + if decode_unicode: + chunks = stream_decode_response_unicode(chunks, self) + + return chunks + + def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=None, delimiter=None): + """Iterates over the response data, one line at a time. When + stream=True is set on the request, this avoids reading the + content at once into memory for large responses. + + .. note:: This method is not reentrant safe. + """ + + pending = None + + for chunk in self.iter_content(chunk_size=chunk_size, decode_unicode=decode_unicode): + + if pending is not None: + chunk = pending + chunk + + if delimiter: + lines = chunk.split(delimiter) + else: + lines = chunk.splitlines() + + if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]: + pending = lines.pop() + else: + pending = None + + for line in lines: + yield line + + if pending is not None: + yield pending + + @property + def content(self): + """Content of the response, in bytes.""" + + if self._content is False: + # Read the contents. + if self._content_consumed: + raise RuntimeError( + 'The content for this response was already consumed') + + if self.status_code == 0 or self.raw is None: + self._content = None + else: + self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes() + + self._content_consumed = True + # don't need to release the connection; that's been handled by urllib3 + # since we exhausted the data. + return self._content + + @property + def text(self): + """Content of the response, in unicode. + + If Response.encoding is None, encoding will be guessed using + ``chardet``. + + The encoding of the response content is determined based solely on HTTP + headers, following RFC 2616 to the letter. If you can take advantage of + non-HTTP knowledge to make a better guess at the encoding, you should + set ``r.encoding`` appropriately before accessing this property. + """ + + # Try charset from content-type + content = None + encoding = self.encoding + + if not self.content: + return str('') + + # Fallback to auto-detected encoding. + if self.encoding is None: + encoding = self.apparent_encoding + + # Decode unicode from given encoding. + try: + content = str(self.content, encoding, errors='replace') + except (LookupError, TypeError): + # A LookupError is raised if the encoding was not found which could + # indicate a misspelling or similar mistake. + # + # A TypeError can be raised if encoding is None + # + # So we try blindly encoding. + content = str(self.content, errors='replace') + + return content + + def json(self, **kwargs): + r"""Returns the json-encoded content of a response, if any. + + :param \*\*kwargs: Optional arguments that ``json.loads`` takes. + :raises ValueError: If the response body does not contain valid json. + """ + + if not self.encoding and self.content and len(self.content) > 3: + # No encoding set. JSON RFC 4627 section 3 states we should expect + # UTF-8, -16 or -32. Detect which one to use; If the detection or + # decoding fails, fall back to `self.text` (using chardet to make + # a best guess). + encoding = guess_json_utf(self.content) + if encoding is not None: + try: + return complexjson.loads( + self.content.decode(encoding), **kwargs + ) + except UnicodeDecodeError: + # Wrong UTF codec detected; usually because it's not UTF-8 + # but some other 8-bit codec. This is an RFC violation, + # and the server didn't bother to tell us what codec *was* + # used. + pass + return complexjson.loads(self.text, **kwargs) + + @property + def links(self): + """Returns the parsed header links of the response, if any.""" + + header = self.headers.get('link') + + # l = MultiDict() + l = {} + + if header: + links = parse_header_links(header) + + for link in links: + key = link.get('rel') or link.get('url') + l[key] = link + + return l + + def raise_for_status(self): + """Raises stored :class:`HTTPError`, if one occurred.""" + + http_error_msg = '' + if isinstance(self.reason, bytes): + # We attempt to decode utf-8 first because some servers + # choose to localize their reason strings. If the string + # isn't utf-8, we fall back to iso-8859-1 for all other + # encodings. (See PR #3538) + try: + reason = self.reason.decode('utf-8') + except UnicodeDecodeError: + reason = self.reason.decode('iso-8859-1') + else: + reason = self.reason + + if 400 <= self.status_code < 500: + http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url) + + elif 500 <= self.status_code < 600: + http_error_msg = u'%s Server Error: %s for url: %s' % (self.status_code, reason, self.url) + + if http_error_msg: + raise HTTPError(http_error_msg, response=self) + + def close(self): + """Releases the connection back to the pool. Once this method has been + called the underlying ``raw`` object must not be accessed again. + + *Note: Should not normally need to be called explicitly.* + """ + if not self._content_consumed: + self.raw.close() + + release_conn = getattr(self.raw, 'release_conn', None) + if release_conn is not None: + release_conn() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/packages.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/packages.py new file mode 100644 index 0000000..9582fa7 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/packages.py @@ -0,0 +1,16 @@ +import sys + +# This code exists for backwards compatibility reasons. +# I don't like it either. Just look the other way. :) + +for package in ('urllib3', 'idna', 'chardet'): + vendored_package = "pip._vendor." + package + locals()[package] = __import__(vendored_package) + # This traversal is apparently necessary such that the identities are + # preserved (requests.packages.urllib3.* is urllib3.*) + for mod in list(sys.modules): + if mod == vendored_package or mod.startswith(vendored_package + '.'): + unprefixed_mod = mod[len("pip._vendor."):] + sys.modules['pip._vendor.requests.packages.' + unprefixed_mod] = sys.modules[mod] + +# Kinda cool, though, right? diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/sessions.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/sessions.py new file mode 100644 index 0000000..6570e73 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/sessions.py @@ -0,0 +1,737 @@ +# -*- coding: utf-8 -*- + +""" +requests.session +~~~~~~~~~~~~~~~~ + +This module provides a Session object to manage and persist settings across +requests (cookies, auth, proxies). +""" +import os +import platform +import time +from collections import Mapping +from datetime import timedelta + +from .auth import _basic_auth_str +from .compat import cookielib, is_py3, OrderedDict, urljoin, urlparse +from .cookies import ( + cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies) +from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT +from .hooks import default_hooks, dispatch_hook +from ._internal_utils import to_native_string +from .utils import to_key_val_list, default_headers +from .exceptions import ( + TooManyRedirects, InvalidSchema, ChunkedEncodingError, ContentDecodingError) + +from .structures import CaseInsensitiveDict +from .adapters import HTTPAdapter + +from .utils import ( + requote_uri, get_environ_proxies, get_netrc_auth, should_bypass_proxies, + get_auth_from_url, rewind_body +) + +from .status_codes import codes + +# formerly defined here, reexposed here for backward compatibility +from .models import REDIRECT_STATI + +# Preferred clock, based on which one is more accurate on a given system. +if platform.system() == 'Windows': + try: # Python 3.3+ + preferred_clock = time.perf_counter + except AttributeError: # Earlier than Python 3. + preferred_clock = time.clock +else: + preferred_clock = time.time + + +def merge_setting(request_setting, session_setting, dict_class=OrderedDict): + """Determines appropriate setting for a given request, taking into account + the explicit setting on that request, and the setting in the session. If a + setting is a dictionary, they will be merged together using `dict_class` + """ + + if session_setting is None: + return request_setting + + if request_setting is None: + return session_setting + + # Bypass if not a dictionary (e.g. verify) + if not ( + isinstance(session_setting, Mapping) and + isinstance(request_setting, Mapping) + ): + return request_setting + + merged_setting = dict_class(to_key_val_list(session_setting)) + merged_setting.update(to_key_val_list(request_setting)) + + # Remove keys that are set to None. Extract keys first to avoid altering + # the dictionary during iteration. + none_keys = [k for (k, v) in merged_setting.items() if v is None] + for key in none_keys: + del merged_setting[key] + + return merged_setting + + +def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict): + """Properly merges both requests and session hooks. + + This is necessary because when request_hooks == {'response': []}, the + merge breaks Session hooks entirely. + """ + if session_hooks is None or session_hooks.get('response') == []: + return request_hooks + + if request_hooks is None or request_hooks.get('response') == []: + return session_hooks + + return merge_setting(request_hooks, session_hooks, dict_class) + + +class SessionRedirectMixin(object): + + def get_redirect_target(self, resp): + """Receives a Response. Returns a redirect URI or ``None``""" + # Due to the nature of how requests processes redirects this method will + # be called at least once upon the original response and at least twice + # on each subsequent redirect response (if any). + # If a custom mixin is used to handle this logic, it may be advantageous + # to cache the redirect location onto the response object as a private + # attribute. + if resp.is_redirect: + location = resp.headers['location'] + # Currently the underlying http module on py3 decode headers + # in latin1, but empirical evidence suggests that latin1 is very + # rarely used with non-ASCII characters in HTTP headers. + # It is more likely to get UTF8 header rather than latin1. + # This causes incorrect handling of UTF8 encoded location headers. + # To solve this, we re-encode the location in latin1. + if is_py3: + location = location.encode('latin1') + return to_native_string(location, 'utf8') + return None + + def resolve_redirects(self, resp, req, stream=False, timeout=None, + verify=True, cert=None, proxies=None, yield_requests=False, **adapter_kwargs): + """Receives a Response. Returns a generator of Responses or Requests.""" + + hist = [] # keep track of history + + url = self.get_redirect_target(resp) + while url: + prepared_request = req.copy() + + # Update history and keep track of redirects. + # resp.history must ignore the original request in this loop + hist.append(resp) + resp.history = hist[1:] + + try: + resp.content # Consume socket so it can be released + except (ChunkedEncodingError, ContentDecodingError, RuntimeError): + resp.raw.read(decode_content=False) + + if len(resp.history) >= self.max_redirects: + raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects, response=resp) + + # Release the connection back into the pool. + resp.close() + + # Handle redirection without scheme (see: RFC 1808 Section 4) + if url.startswith('//'): + parsed_rurl = urlparse(resp.url) + url = '%s:%s' % (to_native_string(parsed_rurl.scheme), url) + + # The scheme should be lower case... + parsed = urlparse(url) + url = parsed.geturl() + + # Facilitate relative 'location' headers, as allowed by RFC 7231. + # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource') + # Compliant with RFC3986, we percent encode the url. + if not parsed.netloc: + url = urljoin(resp.url, requote_uri(url)) + else: + url = requote_uri(url) + + prepared_request.url = to_native_string(url) + + self.rebuild_method(prepared_request, resp) + + # https://github.com/requests/requests/issues/1084 + if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect): + # https://github.com/requests/requests/issues/3490 + purged_headers = ('Content-Length', 'Content-Type', 'Transfer-Encoding') + for header in purged_headers: + prepared_request.headers.pop(header, None) + prepared_request.body = None + + headers = prepared_request.headers + try: + del headers['Cookie'] + except KeyError: + pass + + # Extract any cookies sent on the response to the cookiejar + # in the new request. Because we've mutated our copied prepared + # request, use the old one that we haven't yet touched. + extract_cookies_to_jar(prepared_request._cookies, req, resp.raw) + merge_cookies(prepared_request._cookies, self.cookies) + prepared_request.prepare_cookies(prepared_request._cookies) + + # Rebuild auth and proxy information. + proxies = self.rebuild_proxies(prepared_request, proxies) + self.rebuild_auth(prepared_request, resp) + + # A failed tell() sets `_body_position` to `object()`. This non-None + # value ensures `rewindable` will be True, allowing us to raise an + # UnrewindableBodyError, instead of hanging the connection. + rewindable = ( + prepared_request._body_position is not None and + ('Content-Length' in headers or 'Transfer-Encoding' in headers) + ) + + # Attempt to rewind consumed file-like object. + if rewindable: + rewind_body(prepared_request) + + # Override the original request. + req = prepared_request + + if yield_requests: + yield req + else: + + resp = self.send( + req, + stream=stream, + timeout=timeout, + verify=verify, + cert=cert, + proxies=proxies, + allow_redirects=False, + **adapter_kwargs + ) + + extract_cookies_to_jar(self.cookies, prepared_request, resp.raw) + + # extract redirect url, if any, for the next loop + url = self.get_redirect_target(resp) + yield resp + + def rebuild_auth(self, prepared_request, response): + """When being redirected we may want to strip authentication from the + request to avoid leaking credentials. This method intelligently removes + and reapplies authentication where possible to avoid credential loss. + """ + headers = prepared_request.headers + url = prepared_request.url + + if 'Authorization' in headers: + # If we get redirected to a new host, we should strip out any + # authentication headers. + original_parsed = urlparse(response.request.url) + redirect_parsed = urlparse(url) + + if (original_parsed.hostname != redirect_parsed.hostname): + del headers['Authorization'] + + # .netrc might have more auth for us on our new host. + new_auth = get_netrc_auth(url) if self.trust_env else None + if new_auth is not None: + prepared_request.prepare_auth(new_auth) + + return + + def rebuild_proxies(self, prepared_request, proxies): + """This method re-evaluates the proxy configuration by considering the + environment variables. If we are redirected to a URL covered by + NO_PROXY, we strip the proxy configuration. Otherwise, we set missing + proxy keys for this URL (in case they were stripped by a previous + redirect). + + This method also replaces the Proxy-Authorization header where + necessary. + + :rtype: dict + """ + proxies = proxies if proxies is not None else {} + headers = prepared_request.headers + url = prepared_request.url + scheme = urlparse(url).scheme + new_proxies = proxies.copy() + no_proxy = proxies.get('no_proxy') + + bypass_proxy = should_bypass_proxies(url, no_proxy=no_proxy) + if self.trust_env and not bypass_proxy: + environ_proxies = get_environ_proxies(url, no_proxy=no_proxy) + + proxy = environ_proxies.get(scheme, environ_proxies.get('all')) + + if proxy: + new_proxies.setdefault(scheme, proxy) + + if 'Proxy-Authorization' in headers: + del headers['Proxy-Authorization'] + + try: + username, password = get_auth_from_url(new_proxies[scheme]) + except KeyError: + username, password = None, None + + if username and password: + headers['Proxy-Authorization'] = _basic_auth_str(username, password) + + return new_proxies + + def rebuild_method(self, prepared_request, response): + """When being redirected we may want to change the method of the request + based on certain specs or browser behavior. + """ + method = prepared_request.method + + # http://tools.ietf.org/html/rfc7231#section-6.4.4 + if response.status_code == codes.see_other and method != 'HEAD': + method = 'GET' + + # Do what the browsers do, despite standards... + # First, turn 302s into GETs. + if response.status_code == codes.found and method != 'HEAD': + method = 'GET' + + # Second, if a POST is responded to with a 301, turn it into a GET. + # This bizarre behaviour is explained in Issue 1704. + if response.status_code == codes.moved and method == 'POST': + method = 'GET' + + prepared_request.method = method + + +class Session(SessionRedirectMixin): + """A Requests session. + + Provides cookie persistence, connection-pooling, and configuration. + + Basic Usage:: + + >>> import requests + >>> s = requests.Session() + >>> s.get('http://httpbin.org/get') + <Response [200]> + + Or as a context manager:: + + >>> with requests.Session() as s: + >>> s.get('http://httpbin.org/get') + <Response [200]> + """ + + __attrs__ = [ + 'headers', 'cookies', 'auth', 'proxies', 'hooks', 'params', 'verify', + 'cert', 'prefetch', 'adapters', 'stream', 'trust_env', + 'max_redirects', + ] + + def __init__(self): + + #: A case-insensitive dictionary of headers to be sent on each + #: :class:`Request <Request>` sent from this + #: :class:`Session <Session>`. + self.headers = default_headers() + + #: Default Authentication tuple or object to attach to + #: :class:`Request <Request>`. + self.auth = None + + #: Dictionary mapping protocol or protocol and host to the URL of the proxy + #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to + #: be used on each :class:`Request <Request>`. + self.proxies = {} + + #: Event-handling hooks. + self.hooks = default_hooks() + + #: Dictionary of querystring data to attach to each + #: :class:`Request <Request>`. The dictionary values may be lists for + #: representing multivalued query parameters. + self.params = {} + + #: Stream response content default. + self.stream = False + + #: SSL Verification default. + self.verify = True + + #: SSL client certificate default, if String, path to ssl client + #: cert file (.pem). If Tuple, ('cert', 'key') pair. + self.cert = None + + #: Maximum number of redirects allowed. If the request exceeds this + #: limit, a :class:`TooManyRedirects` exception is raised. + #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is + #: 30. + self.max_redirects = DEFAULT_REDIRECT_LIMIT + + #: Trust environment settings for proxy configuration, default + #: authentication and similar. + self.trust_env = True + + #: A CookieJar containing all currently outstanding cookies set on this + #: session. By default it is a + #: :class:`RequestsCookieJar <requests.cookies.RequestsCookieJar>`, but + #: may be any other ``cookielib.CookieJar`` compatible object. + self.cookies = cookiejar_from_dict({}) + + # Default connection adapters. + self.adapters = OrderedDict() + self.mount('https://', HTTPAdapter()) + self.mount('http://', HTTPAdapter()) + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def prepare_request(self, request): + """Constructs a :class:`PreparedRequest <PreparedRequest>` for + transmission and returns it. The :class:`PreparedRequest` has settings + merged from the :class:`Request <Request>` instance and those of the + :class:`Session`. + + :param request: :class:`Request` instance to prepare with this + session's settings. + :rtype: requests.PreparedRequest + """ + cookies = request.cookies or {} + + # Bootstrap CookieJar. + if not isinstance(cookies, cookielib.CookieJar): + cookies = cookiejar_from_dict(cookies) + + # Merge with session cookies + merged_cookies = merge_cookies( + merge_cookies(RequestsCookieJar(), self.cookies), cookies) + + # Set environment's basic authentication if not explicitly set. + auth = request.auth + if self.trust_env and not auth and not self.auth: + auth = get_netrc_auth(request.url) + + p = PreparedRequest() + p.prepare( + method=request.method.upper(), + url=request.url, + files=request.files, + data=request.data, + json=request.json, + headers=merge_setting(request.headers, self.headers, dict_class=CaseInsensitiveDict), + params=merge_setting(request.params, self.params), + auth=merge_setting(auth, self.auth), + cookies=merged_cookies, + hooks=merge_hooks(request.hooks, self.hooks), + ) + return p + + def request(self, method, url, + params=None, data=None, headers=None, cookies=None, files=None, + auth=None, timeout=None, allow_redirects=True, proxies=None, + hooks=None, stream=None, verify=None, cert=None, json=None): + """Constructs a :class:`Request <Request>`, prepares it and sends it. + Returns :class:`Response <Response>` object. + + :param method: method for the new :class:`Request` object. + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query + string for the :class:`Request`. + :param data: (optional) Dictionary, bytes, or file-like object to send + in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the + :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the + :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the + :class:`Request`. + :param files: (optional) Dictionary of ``'filename': file-like-objects`` + for multipart encoding upload. + :param auth: (optional) Auth tuple or callable to enable + Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) <timeouts>` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Set to True by default. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol or protocol and + hostname to the URL of the proxy. + :param stream: (optional) whether to immediately download the response + content. Defaults to ``False``. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. + :param cert: (optional) if String, path to ssl client cert file (.pem). + If Tuple, ('cert', 'key') pair. + :rtype: requests.Response + """ + # Create the Request. + req = Request( + method=method.upper(), + url=url, + headers=headers, + files=files, + data=data or {}, + json=json, + params=params or {}, + auth=auth, + cookies=cookies, + hooks=hooks, + ) + prep = self.prepare_request(req) + + proxies = proxies or {} + + settings = self.merge_environment_settings( + prep.url, proxies, stream, verify, cert + ) + + # Send the request. + send_kwargs = { + 'timeout': timeout, + 'allow_redirects': allow_redirects, + } + send_kwargs.update(settings) + resp = self.send(prep, **send_kwargs) + + return resp + + def get(self, url, **kwargs): + r"""Sends a GET request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return self.request('GET', url, **kwargs) + + def options(self, url, **kwargs): + r"""Sends a OPTIONS request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return self.request('OPTIONS', url, **kwargs) + + def head(self, url, **kwargs): + r"""Sends a HEAD request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', False) + return self.request('HEAD', url, **kwargs) + + def post(self, url, data=None, json=None, **kwargs): + r"""Sends a POST request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('POST', url, data=data, json=json, **kwargs) + + def put(self, url, data=None, **kwargs): + r"""Sends a PUT request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('PUT', url, data=data, **kwargs) + + def patch(self, url, data=None, **kwargs): + r"""Sends a PATCH request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('PATCH', url, data=data, **kwargs) + + def delete(self, url, **kwargs): + r"""Sends a DELETE request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('DELETE', url, **kwargs) + + def send(self, request, **kwargs): + """Send a given PreparedRequest. + + :rtype: requests.Response + """ + # Set defaults that the hooks can utilize to ensure they always have + # the correct parameters to reproduce the previous request. + kwargs.setdefault('stream', self.stream) + kwargs.setdefault('verify', self.verify) + kwargs.setdefault('cert', self.cert) + kwargs.setdefault('proxies', self.proxies) + + # It's possible that users might accidentally send a Request object. + # Guard against that specific failure case. + if isinstance(request, Request): + raise ValueError('You can only send PreparedRequests.') + + # Set up variables needed for resolve_redirects and dispatching of hooks + allow_redirects = kwargs.pop('allow_redirects', True) + stream = kwargs.get('stream') + hooks = request.hooks + + # Get the appropriate adapter to use + adapter = self.get_adapter(url=request.url) + + # Start time (approximately) of the request + start = preferred_clock() + + # Send the request + r = adapter.send(request, **kwargs) + + # Total elapsed time of the request (approximately) + elapsed = preferred_clock() - start + r.elapsed = timedelta(seconds=elapsed) + + # Response manipulation hooks + r = dispatch_hook('response', hooks, r, **kwargs) + + # Persist cookies + if r.history: + + # If the hooks create history then we want those cookies too + for resp in r.history: + extract_cookies_to_jar(self.cookies, resp.request, resp.raw) + + extract_cookies_to_jar(self.cookies, request, r.raw) + + # Redirect resolving generator. + gen = self.resolve_redirects(r, request, **kwargs) + + # Resolve redirects if allowed. + history = [resp for resp in gen] if allow_redirects else [] + + # Shuffle things around if there's history. + if history: + # Insert the first (original) request at the start + history.insert(0, r) + # Get the last request made + r = history.pop() + r.history = history + + # If redirects aren't being followed, store the response on the Request for Response.next(). + if not allow_redirects: + try: + r._next = next(self.resolve_redirects(r, request, yield_requests=True, **kwargs)) + except StopIteration: + pass + + if not stream: + r.content + + return r + + def merge_environment_settings(self, url, proxies, stream, verify, cert): + """ + Check the environment and merge it with some settings. + + :rtype: dict + """ + # Gather clues from the surrounding environment. + if self.trust_env: + # Set environment's proxies. + no_proxy = proxies.get('no_proxy') if proxies is not None else None + env_proxies = get_environ_proxies(url, no_proxy=no_proxy) + for (k, v) in env_proxies.items(): + proxies.setdefault(k, v) + + # Look for requests environment configuration and be compatible + # with cURL. + if verify is True or verify is None: + verify = (os.environ.get('REQUESTS_CA_BUNDLE') or + os.environ.get('CURL_CA_BUNDLE')) + + # Merge all the kwargs. + proxies = merge_setting(proxies, self.proxies) + stream = merge_setting(stream, self.stream) + verify = merge_setting(verify, self.verify) + cert = merge_setting(cert, self.cert) + + return {'verify': verify, 'proxies': proxies, 'stream': stream, + 'cert': cert} + + def get_adapter(self, url): + """ + Returns the appropriate connection adapter for the given URL. + + :rtype: requests.adapters.BaseAdapter + """ + for (prefix, adapter) in self.adapters.items(): + + if url.lower().startswith(prefix): + return adapter + + # Nothing matches :-/ + raise InvalidSchema("No connection adapters were found for '%s'" % url) + + def close(self): + """Closes all adapters and as such the session""" + for v in self.adapters.values(): + v.close() + + def mount(self, prefix, adapter): + """Registers a connection adapter to a prefix. + + Adapters are sorted in descending order by prefix length. + """ + self.adapters[prefix] = adapter + keys_to_move = [k for k in self.adapters if len(k) < len(prefix)] + + for key in keys_to_move: + self.adapters[key] = self.adapters.pop(key) + + def __getstate__(self): + state = dict((attr, getattr(self, attr, None)) for attr in self.__attrs__) + return state + + def __setstate__(self, state): + for attr, value in state.items(): + setattr(self, attr, value) + + +def session(): + """ + Returns a :class:`Session` for context-management. + + :rtype: Session + """ + + return Session() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/status_codes.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/status_codes.py new file mode 100644 index 0000000..dee8919 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/status_codes.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- + +from .structures import LookupDict + +_codes = { + + # Informational. + 100: ('continue',), + 101: ('switching_protocols',), + 102: ('processing',), + 103: ('checkpoint',), + 122: ('uri_too_long', 'request_uri_too_long'), + 200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'), + 201: ('created',), + 202: ('accepted',), + 203: ('non_authoritative_info', 'non_authoritative_information'), + 204: ('no_content',), + 205: ('reset_content', 'reset'), + 206: ('partial_content', 'partial'), + 207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'), + 208: ('already_reported',), + 226: ('im_used',), + + # Redirection. + 300: ('multiple_choices',), + 301: ('moved_permanently', 'moved', '\\o-'), + 302: ('found',), + 303: ('see_other', 'other'), + 304: ('not_modified',), + 305: ('use_proxy',), + 306: ('switch_proxy',), + 307: ('temporary_redirect', 'temporary_moved', 'temporary'), + 308: ('permanent_redirect', + 'resume_incomplete', 'resume',), # These 2 to be removed in 3.0 + + # Client Error. + 400: ('bad_request', 'bad'), + 401: ('unauthorized',), + 402: ('payment_required', 'payment'), + 403: ('forbidden',), + 404: ('not_found', '-o-'), + 405: ('method_not_allowed', 'not_allowed'), + 406: ('not_acceptable',), + 407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'), + 408: ('request_timeout', 'timeout'), + 409: ('conflict',), + 410: ('gone',), + 411: ('length_required',), + 412: ('precondition_failed', 'precondition'), + 413: ('request_entity_too_large',), + 414: ('request_uri_too_large',), + 415: ('unsupported_media_type', 'unsupported_media', 'media_type'), + 416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'), + 417: ('expectation_failed',), + 418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'), + 421: ('misdirected_request',), + 422: ('unprocessable_entity', 'unprocessable'), + 423: ('locked',), + 424: ('failed_dependency', 'dependency'), + 425: ('unordered_collection', 'unordered'), + 426: ('upgrade_required', 'upgrade'), + 428: ('precondition_required', 'precondition'), + 429: ('too_many_requests', 'too_many'), + 431: ('header_fields_too_large', 'fields_too_large'), + 444: ('no_response', 'none'), + 449: ('retry_with', 'retry'), + 450: ('blocked_by_windows_parental_controls', 'parental_controls'), + 451: ('unavailable_for_legal_reasons', 'legal_reasons'), + 499: ('client_closed_request',), + + # Server Error. + 500: ('internal_server_error', 'server_error', '/o\\', '✗'), + 501: ('not_implemented',), + 502: ('bad_gateway',), + 503: ('service_unavailable', 'unavailable'), + 504: ('gateway_timeout',), + 505: ('http_version_not_supported', 'http_version'), + 506: ('variant_also_negotiates',), + 507: ('insufficient_storage',), + 509: ('bandwidth_limit_exceeded', 'bandwidth'), + 510: ('not_extended',), + 511: ('network_authentication_required', 'network_auth', 'network_authentication'), +} + +codes = LookupDict(name='status_codes') + +for code, titles in _codes.items(): + for title in titles: + setattr(codes, title, code) + if not title.startswith(('\\', '/')): + setattr(codes, title.upper(), code) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/structures.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/structures.py new file mode 100644 index 0000000..05d2b3f --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/structures.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- + +""" +requests.structures +~~~~~~~~~~~~~~~~~~~ + +Data structures that power Requests. +""" + +import collections + +from .compat import OrderedDict + + +class CaseInsensitiveDict(collections.MutableMapping): + """A case-insensitive ``dict``-like object. + + Implements all methods and operations of + ``collections.MutableMapping`` as well as dict's ``copy``. Also + provides ``lower_items``. + + All keys are expected to be strings. The structure remembers the + case of the last key to be set, and ``iter(instance)``, + ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()`` + will contain case-sensitive keys. However, querying and contains + testing is case insensitive:: + + cid = CaseInsensitiveDict() + cid['Accept'] = 'application/json' + cid['aCCEPT'] == 'application/json' # True + list(cid) == ['Accept'] # True + + For example, ``headers['content-encoding']`` will return the + value of a ``'Content-Encoding'`` response header, regardless + of how the header name was originally stored. + + If the constructor, ``.update``, or equality comparison + operations are given keys that have equal ``.lower()``s, the + behavior is undefined. + """ + + def __init__(self, data=None, **kwargs): + self._store = OrderedDict() + if data is None: + data = {} + self.update(data, **kwargs) + + def __setitem__(self, key, value): + # Use the lowercased key for lookups, but store the actual + # key alongside the value. + self._store[key.lower()] = (key, value) + + def __getitem__(self, key): + return self._store[key.lower()][1] + + def __delitem__(self, key): + del self._store[key.lower()] + + def __iter__(self): + return (casedkey for casedkey, mappedvalue in self._store.values()) + + def __len__(self): + return len(self._store) + + def lower_items(self): + """Like iteritems(), but with all lowercase keys.""" + return ( + (lowerkey, keyval[1]) + for (lowerkey, keyval) + in self._store.items() + ) + + def __eq__(self, other): + if isinstance(other, collections.Mapping): + other = CaseInsensitiveDict(other) + else: + return NotImplemented + # Compare insensitively + return dict(self.lower_items()) == dict(other.lower_items()) + + # Copy is required + def copy(self): + return CaseInsensitiveDict(self._store.values()) + + def __repr__(self): + return str(dict(self.items())) + + +class LookupDict(dict): + """Dictionary lookup object.""" + + def __init__(self, name=None): + self.name = name + super(LookupDict, self).__init__() + + def __repr__(self): + return '<lookup \'%s\'>' % (self.name) + + def __getitem__(self, key): + # We allow fall-through here, so values default to None + + return self.__dict__.get(key, None) + + def get(self, key, default=None): + return self.__dict__.get(key, default) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/utils.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/utils.py new file mode 100644 index 0000000..5c47de9 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/utils.py @@ -0,0 +1,904 @@ +# -*- coding: utf-8 -*- + +""" +requests.utils +~~~~~~~~~~~~~~ + +This module provides utility functions that are used within Requests +that are also useful for external consumption. +""" + +import cgi +import codecs +import collections +import contextlib +import io +import os +import platform +import re +import socket +import struct +import warnings + +from .__version__ import __version__ +from . import certs +# to_native_string is unused here, but imported here for backwards compatibility +from ._internal_utils import to_native_string +from .compat import parse_http_list as _parse_list_header +from .compat import ( + quote, urlparse, bytes, str, OrderedDict, unquote, getproxies, + proxy_bypass, urlunparse, basestring, integer_types, is_py3, + proxy_bypass_environment, getproxies_environment) +from .cookies import cookiejar_from_dict +from .structures import CaseInsensitiveDict +from .exceptions import ( + InvalidURL, InvalidHeader, FileModeWarning, UnrewindableBodyError) + +NETRC_FILES = ('.netrc', '_netrc') + +DEFAULT_CA_BUNDLE_PATH = certs.where() + + +if platform.system() == 'Windows': + # provide a proxy_bypass version on Windows without DNS lookups + + def proxy_bypass_registry(host): + if is_py3: + import winreg + else: + import _winreg as winreg + try: + internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER, + r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') + proxyEnable = winreg.QueryValueEx(internetSettings, + 'ProxyEnable')[0] + proxyOverride = winreg.QueryValueEx(internetSettings, + 'ProxyOverride')[0] + except OSError: + return False + if not proxyEnable or not proxyOverride: + return False + + # make a check value list from the registry entry: replace the + # '<local>' string by the localhost entry and the corresponding + # canonical entry. + proxyOverride = proxyOverride.split(';') + # now check if we match one of the registry values. + for test in proxyOverride: + if test == '<local>': + if '.' not in host: + return True + test = test.replace(".", r"\.") # mask dots + test = test.replace("*", r".*") # change glob sequence + test = test.replace("?", r".") # change glob char + if re.match(test, host, re.I): + return True + return False + + def proxy_bypass(host): # noqa + """Return True, if the host should be bypassed. + + Checks proxy settings gathered from the environment, if specified, + or the registry. + """ + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return proxy_bypass_registry(host) + + +def dict_to_sequence(d): + """Returns an internal sequence dictionary update.""" + + if hasattr(d, 'items'): + d = d.items() + + return d + + +def super_len(o): + total_length = None + current_position = 0 + + if hasattr(o, '__len__'): + total_length = len(o) + + elif hasattr(o, 'len'): + total_length = o.len + + elif hasattr(o, 'fileno'): + try: + fileno = o.fileno() + except io.UnsupportedOperation: + pass + else: + total_length = os.fstat(fileno).st_size + + # Having used fstat to determine the file length, we need to + # confirm that this file was opened up in binary mode. + if 'b' not in o.mode: + warnings.warn(( + "Requests has determined the content-length for this " + "request using the binary size of the file: however, the " + "file has been opened in text mode (i.e. without the 'b' " + "flag in the mode). This may lead to an incorrect " + "content-length. In Requests 3.0, support will be removed " + "for files in text mode."), + FileModeWarning + ) + + if hasattr(o, 'tell'): + try: + current_position = o.tell() + except (OSError, IOError): + # This can happen in some weird situations, such as when the file + # is actually a special file descriptor like stdin. In this + # instance, we don't know what the length is, so set it to zero and + # let requests chunk it instead. + if total_length is not None: + current_position = total_length + else: + if hasattr(o, 'seek') and total_length is None: + # StringIO and BytesIO have seek but no useable fileno + try: + # seek to end of file + o.seek(0, 2) + total_length = o.tell() + + # seek back to current position to support + # partially read file-like objects + o.seek(current_position or 0) + except (OSError, IOError): + total_length = 0 + + if total_length is None: + total_length = 0 + + return max(0, total_length - current_position) + + +def get_netrc_auth(url, raise_errors=False): + """Returns the Requests tuple auth for a given url from netrc.""" + + try: + from netrc import netrc, NetrcParseError + + netrc_path = None + + for f in NETRC_FILES: + try: + loc = os.path.expanduser('~/{0}'.format(f)) + except KeyError: + # os.path.expanduser can fail when $HOME is undefined and + # getpwuid fails. See http://bugs.python.org/issue20164 & + # https://github.com/requests/requests/issues/1846 + return + + if os.path.exists(loc): + netrc_path = loc + break + + # Abort early if there isn't one. + if netrc_path is None: + return + + ri = urlparse(url) + + # Strip port numbers from netloc. This weird `if...encode`` dance is + # used for Python 3.2, which doesn't support unicode literals. + splitstr = b':' + if isinstance(url, str): + splitstr = splitstr.decode('ascii') + host = ri.netloc.split(splitstr)[0] + + try: + _netrc = netrc(netrc_path).authenticators(host) + if _netrc: + # Return with login / password + login_i = (0 if _netrc[0] else 1) + return (_netrc[login_i], _netrc[2]) + except (NetrcParseError, IOError): + # If there was a parsing error or a permissions issue reading the file, + # we'll just skip netrc auth unless explicitly asked to raise errors. + if raise_errors: + raise + + # AppEngine hackiness. + except (ImportError, AttributeError): + pass + + +def guess_filename(obj): + """Tries to guess the filename of the given object.""" + name = getattr(obj, 'name', None) + if (name and isinstance(name, basestring) and name[0] != '<' and + name[-1] != '>'): + return os.path.basename(name) + + +def from_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. Unless it can not be represented as such, return an + OrderedDict, e.g., + + :: + + >>> from_key_val_list([('key', 'val')]) + OrderedDict([('key', 'val')]) + >>> from_key_val_list('string') + ValueError: need more than 1 value to unpack + >>> from_key_val_list({'key': 'val'}) + OrderedDict([('key', 'val')]) + + :rtype: OrderedDict + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError('cannot encode objects that are not 2-tuples') + + return OrderedDict(value) + + +def to_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. If it can be, return a list of tuples, e.g., + + :: + + >>> to_key_val_list([('key', 'val')]) + [('key', 'val')] + >>> to_key_val_list({'key': 'val'}) + [('key', 'val')] + >>> to_key_val_list('string') + ValueError: cannot encode objects that are not 2-tuples. + + :rtype: list + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError('cannot encode objects that are not 2-tuples') + + if isinstance(value, collections.Mapping): + value = value.items() + + return list(value) + + +# From mitsuhiko/werkzeug (used with permission). +def parse_list_header(value): + """Parse lists as described by RFC 2068 Section 2. + + In particular, parse comma-separated lists where the elements of + the list may include quoted-strings. A quoted-string could + contain a comma. A non-quoted string could have quotes in the + middle. Quotes are removed automatically after parsing. + + It basically works like :func:`parse_set_header` just that items + may appear multiple times and case sensitivity is preserved. + + The return value is a standard :class:`list`: + + >>> parse_list_header('token, "quoted value"') + ['token', 'quoted value'] + + To create a header from the :class:`list` again, use the + :func:`dump_header` function. + + :param value: a string with a list header. + :return: :class:`list` + :rtype: list + """ + result = [] + for item in _parse_list_header(value): + if item[:1] == item[-1:] == '"': + item = unquote_header_value(item[1:-1]) + result.append(item) + return result + + +# From mitsuhiko/werkzeug (used with permission). +def parse_dict_header(value): + """Parse lists of key, value pairs as described by RFC 2068 Section 2 and + convert them into a python dict: + + >>> d = parse_dict_header('foo="is a fish", bar="as well"') + >>> type(d) is dict + True + >>> sorted(d.items()) + [('bar', 'as well'), ('foo', 'is a fish')] + + If there is no value for a key it will be `None`: + + >>> parse_dict_header('key_without_value') + {'key_without_value': None} + + To create a header from the :class:`dict` again, use the + :func:`dump_header` function. + + :param value: a string with a dict header. + :return: :class:`dict` + :rtype: dict + """ + result = {} + for item in _parse_list_header(value): + if '=' not in item: + result[item] = None + continue + name, value = item.split('=', 1) + if value[:1] == value[-1:] == '"': + value = unquote_header_value(value[1:-1]) + result[name] = value + return result + + +# From mitsuhiko/werkzeug (used with permission). +def unquote_header_value(value, is_filename=False): + r"""Unquotes a header value. (Reversal of :func:`quote_header_value`). + This does not use the real unquoting but what browsers are actually + using for quoting. + + :param value: the header value to unquote. + :rtype: str + """ + if value and value[0] == value[-1] == '"': + # this is not the real unquoting, but fixing this so that the + # RFC is met will result in bugs with internet explorer and + # probably some other browsers as well. IE for example is + # uploading files with "C:\foo\bar.txt" as filename + value = value[1:-1] + + # if this is a filename and the starting characters look like + # a UNC path, then just return the value without quotes. Using the + # replace sequence below on a UNC path has the effect of turning + # the leading double slash into a single slash and then + # _fix_ie_filename() doesn't work correctly. See #458. + if not is_filename or value[:2] != '\\\\': + return value.replace('\\\\', '\\').replace('\\"', '"') + return value + + +def dict_from_cookiejar(cj): + """Returns a key/value dictionary from a CookieJar. + + :param cj: CookieJar object to extract cookies from. + :rtype: dict + """ + + cookie_dict = {} + + for cookie in cj: + cookie_dict[cookie.name] = cookie.value + + return cookie_dict + + +def add_dict_to_cookiejar(cj, cookie_dict): + """Returns a CookieJar from a key/value dictionary. + + :param cj: CookieJar to insert cookies into. + :param cookie_dict: Dict of key/values to insert into CookieJar. + :rtype: CookieJar + """ + + return cookiejar_from_dict(cookie_dict, cj) + + +def get_encodings_from_content(content): + """Returns encodings from given content string. + + :param content: bytestring to extract encodings from. + """ + warnings.warn(( + 'In requests 3.0, get_encodings_from_content will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) + + charset_re = re.compile(r'<meta.*?charset=["\']*(.+?)["\'>]', flags=re.I) + pragma_re = re.compile(r'<meta.*?content=["\']*;?charset=(.+?)["\'>]', flags=re.I) + xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]') + + return (charset_re.findall(content) + + pragma_re.findall(content) + + xml_re.findall(content)) + + +def get_encoding_from_headers(headers): + """Returns encodings from given HTTP Header Dict. + + :param headers: dictionary to extract encoding from. + :rtype: str + """ + + content_type = headers.get('content-type') + + if not content_type: + return None + + content_type, params = cgi.parse_header(content_type) + + if 'charset' in params: + return params['charset'].strip("'\"") + + if 'text' in content_type: + return 'ISO-8859-1' + + +def stream_decode_response_unicode(iterator, r): + """Stream decodes a iterator.""" + + if r.encoding is None: + for item in iterator: + yield item + return + + decoder = codecs.getincrementaldecoder(r.encoding)(errors='replace') + for chunk in iterator: + rv = decoder.decode(chunk) + if rv: + yield rv + rv = decoder.decode(b'', final=True) + if rv: + yield rv + + +def iter_slices(string, slice_length): + """Iterate over slices of a string.""" + pos = 0 + if slice_length is None or slice_length <= 0: + slice_length = len(string) + while pos < len(string): + yield string[pos:pos + slice_length] + pos += slice_length + + +def get_unicode_from_response(r): + """Returns the requested content back in unicode. + + :param r: Response object to get unicode content from. + + Tried: + + 1. charset from content-type + 2. fall back and replace all unicode characters + + :rtype: str + """ + warnings.warn(( + 'In requests 3.0, get_unicode_from_response will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) + + tried_encodings = [] + + # Try charset from content-type + encoding = get_encoding_from_headers(r.headers) + + if encoding: + try: + return str(r.content, encoding) + except UnicodeError: + tried_encodings.append(encoding) + + # Fall back: + try: + return str(r.content, encoding, errors='replace') + except TypeError: + return r.content + + +# The unreserved URI characters (RFC 3986) +UNRESERVED_SET = frozenset( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~") + + +def unquote_unreserved(uri): + """Un-escape any percent-escape sequences in a URI that are unreserved + characters. This leaves all reserved, illegal and non-ASCII bytes encoded. + + :rtype: str + """ + parts = uri.split('%') + for i in range(1, len(parts)): + h = parts[i][0:2] + if len(h) == 2 and h.isalnum(): + try: + c = chr(int(h, 16)) + except ValueError: + raise InvalidURL("Invalid percent-escape sequence: '%s'" % h) + + if c in UNRESERVED_SET: + parts[i] = c + parts[i][2:] + else: + parts[i] = '%' + parts[i] + else: + parts[i] = '%' + parts[i] + return ''.join(parts) + + +def requote_uri(uri): + """Re-quote the given URI. + + This function passes the given URI through an unquote/quote cycle to + ensure that it is fully and consistently quoted. + + :rtype: str + """ + safe_with_percent = "!#$%&'()*+,/:;=?@[]~" + safe_without_percent = "!#$&'()*+,/:;=?@[]~" + try: + # Unquote only the unreserved characters + # Then quote only illegal characters (do not quote reserved, + # unreserved, or '%') + return quote(unquote_unreserved(uri), safe=safe_with_percent) + except InvalidURL: + # We couldn't unquote the given URI, so let's try quoting it, but + # there may be unquoted '%'s in the URI. We need to make sure they're + # properly quoted so they do not cause issues elsewhere. + return quote(uri, safe=safe_without_percent) + + +def address_in_network(ip, net): + """This function allows you to check if an IP belongs to a network subnet + + Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24 + returns False if ip = 192.168.1.1 and net = 192.168.100.0/24 + + :rtype: bool + """ + ipaddr = struct.unpack('=L', socket.inet_aton(ip))[0] + netaddr, bits = net.split('/') + netmask = struct.unpack('=L', socket.inet_aton(dotted_netmask(int(bits))))[0] + network = struct.unpack('=L', socket.inet_aton(netaddr))[0] & netmask + return (ipaddr & netmask) == (network & netmask) + + +def dotted_netmask(mask): + """Converts mask from /xx format to xxx.xxx.xxx.xxx + + Example: if mask is 24 function returns 255.255.255.0 + + :rtype: str + """ + bits = 0xffffffff ^ (1 << 32 - mask) - 1 + return socket.inet_ntoa(struct.pack('>I', bits)) + + +def is_ipv4_address(string_ip): + """ + :rtype: bool + """ + try: + socket.inet_aton(string_ip) + except socket.error: + return False + return True + + +def is_valid_cidr(string_network): + """ + Very simple check of the cidr format in no_proxy variable. + + :rtype: bool + """ + if string_network.count('/') == 1: + try: + mask = int(string_network.split('/')[1]) + except ValueError: + return False + + if mask < 1 or mask > 32: + return False + + try: + socket.inet_aton(string_network.split('/')[0]) + except socket.error: + return False + else: + return False + return True + + +@contextlib.contextmanager +def set_environ(env_name, value): + """Set the environment variable 'env_name' to 'value' + + Save previous value, yield, and then restore the previous value stored in + the environment variable 'env_name'. + + If 'value' is None, do nothing""" + value_changed = value is not None + if value_changed: + old_value = os.environ.get(env_name) + os.environ[env_name] = value + try: + yield + finally: + if value_changed: + if old_value is None: + del os.environ[env_name] + else: + os.environ[env_name] = old_value + + +def should_bypass_proxies(url, no_proxy): + """ + Returns whether we should bypass proxies or not. + + :rtype: bool + """ + get_proxy = lambda k: os.environ.get(k) or os.environ.get(k.upper()) + + # First check whether no_proxy is defined. If it is, check that the URL + # we're getting isn't in the no_proxy list. + no_proxy_arg = no_proxy + if no_proxy is None: + no_proxy = get_proxy('no_proxy') + netloc = urlparse(url).netloc + + if no_proxy: + # We need to check whether we match here. We need to see if we match + # the end of the netloc, both with and without the port. + no_proxy = ( + host for host in no_proxy.replace(' ', '').split(',') if host + ) + + ip = netloc.split(':')[0] + if is_ipv4_address(ip): + for proxy_ip in no_proxy: + if is_valid_cidr(proxy_ip): + if address_in_network(ip, proxy_ip): + return True + elif ip == proxy_ip: + # If no_proxy ip was defined in plain IP notation instead of cidr notation & + # matches the IP of the index + return True + else: + for host in no_proxy: + if netloc.endswith(host) or netloc.split(':')[0].endswith(host): + # The URL does match something in no_proxy, so we don't want + # to apply the proxies on this URL. + return True + + # If the system proxy settings indicate that this URL should be bypassed, + # don't proxy. + # The proxy_bypass function is incredibly buggy on OS X in early versions + # of Python 2.6, so allow this call to fail. Only catch the specific + # exceptions we've seen, though: this call failing in other ways can reveal + # legitimate problems. + with set_environ('no_proxy', no_proxy_arg): + try: + bypass = proxy_bypass(netloc) + except (TypeError, socket.gaierror): + bypass = False + + if bypass: + return True + + return False + + +def get_environ_proxies(url, no_proxy=None): + """ + Return a dict of environment proxies. + + :rtype: dict + """ + if should_bypass_proxies(url, no_proxy=no_proxy): + return {} + else: + return getproxies() + + +def select_proxy(url, proxies): + """Select a proxy for the url, if applicable. + + :param url: The url being for the request + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs + """ + proxies = proxies or {} + urlparts = urlparse(url) + if urlparts.hostname is None: + return proxies.get(urlparts.scheme, proxies.get('all')) + + proxy_keys = [ + urlparts.scheme + '://' + urlparts.hostname, + urlparts.scheme, + 'all://' + urlparts.hostname, + 'all', + ] + proxy = None + for proxy_key in proxy_keys: + if proxy_key in proxies: + proxy = proxies[proxy_key] + break + + return proxy + + +def default_user_agent(name="python-requests"): + """ + Return a string representing the default user agent. + + :rtype: str + """ + return '%s/%s' % (name, __version__) + + +def default_headers(): + """ + :rtype: requests.structures.CaseInsensitiveDict + """ + return CaseInsensitiveDict({ + 'User-Agent': default_user_agent(), + 'Accept-Encoding': ', '.join(('gzip', 'deflate')), + 'Accept': '*/*', + 'Connection': 'keep-alive', + }) + + +def parse_header_links(value): + """Return a dict of parsed link headers proxies. + + i.e. Link: <http:/.../front.jpeg>; rel=front; type="image/jpeg",<http://.../back.jpeg>; rel=back;type="image/jpeg" + + :rtype: list + """ + + links = [] + + replace_chars = ' \'"' + + for val in re.split(', *<', value): + try: + url, params = val.split(';', 1) + except ValueError: + url, params = val, '' + + link = {'url': url.strip('<> \'"')} + + for param in params.split(';'): + try: + key, value = param.split('=') + except ValueError: + break + + link[key.strip(replace_chars)] = value.strip(replace_chars) + + links.append(link) + + return links + + +# Null bytes; no need to recreate these on each call to guess_json_utf +_null = '\x00'.encode('ascii') # encoding to ASCII for Python 3 +_null2 = _null * 2 +_null3 = _null * 3 + + +def guess_json_utf(data): + """ + :rtype: str + """ + # JSON always starts with two ASCII characters, so detection is as + # easy as counting the nulls and from their location and count + # determine the encoding. Also detect a BOM, if present. + sample = data[:4] + if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE): + return 'utf-32' # BOM included + if sample[:3] == codecs.BOM_UTF8: + return 'utf-8-sig' # BOM included, MS style (discouraged) + if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE): + return 'utf-16' # BOM included + nullcount = sample.count(_null) + if nullcount == 0: + return 'utf-8' + if nullcount == 2: + if sample[::2] == _null2: # 1st and 3rd are null + return 'utf-16-be' + if sample[1::2] == _null2: # 2nd and 4th are null + return 'utf-16-le' + # Did not detect 2 valid UTF-16 ascii-range characters + if nullcount == 3: + if sample[:3] == _null3: + return 'utf-32-be' + if sample[1:] == _null3: + return 'utf-32-le' + # Did not detect a valid UTF-32 ascii-range character + return None + + +def prepend_scheme_if_needed(url, new_scheme): + """Given a URL that may or may not have a scheme, prepend the given scheme. + Does not replace a present scheme with the one provided as an argument. + + :rtype: str + """ + scheme, netloc, path, params, query, fragment = urlparse(url, new_scheme) + + # urlparse is a finicky beast, and sometimes decides that there isn't a + # netloc present. Assume that it's being over-cautious, and switch netloc + # and path if urlparse decided there was no netloc. + if not netloc: + netloc, path = path, netloc + + return urlunparse((scheme, netloc, path, params, query, fragment)) + + +def get_auth_from_url(url): + """Given a url with authentication components, extract them into a tuple of + username,password. + + :rtype: (str,str) + """ + parsed = urlparse(url) + + try: + auth = (unquote(parsed.username), unquote(parsed.password)) + except (AttributeError, TypeError): + auth = ('', '') + + return auth + + +# Moved outside of function to avoid recompile every call +_CLEAN_HEADER_REGEX_BYTE = re.compile(b'^\\S[^\\r\\n]*$|^$') +_CLEAN_HEADER_REGEX_STR = re.compile(r'^\S[^\r\n]*$|^$') + + +def check_header_validity(header): + """Verifies that header value is a string which doesn't contain + leading whitespace or return characters. This prevents unintended + header injection. + + :param header: tuple, in the format (name, value). + """ + name, value = header + + if isinstance(value, bytes): + pat = _CLEAN_HEADER_REGEX_BYTE + else: + pat = _CLEAN_HEADER_REGEX_STR + try: + if not pat.match(value): + raise InvalidHeader("Invalid return character or leading space in header: %s" % name) + except TypeError: + raise InvalidHeader("Value for header {%s: %s} must be of type str or " + "bytes, not %s" % (name, value, type(value))) + + +def urldefragauth(url): + """ + Given a url remove the fragment and the authentication part. + + :rtype: str + """ + scheme, netloc, path, params, query, fragment = urlparse(url) + + # see func:`prepend_scheme_if_needed` + if not netloc: + netloc, path = path, netloc + + netloc = netloc.rsplit('@', 1)[-1] + + return urlunparse((scheme, netloc, path, params, query, '')) + + +def rewind_body(prepared_request): + """Move file pointer back to its recorded starting position + so it can be read again on redirect. + """ + body_seek = getattr(prepared_request.body, 'seek', None) + if body_seek is not None and isinstance(prepared_request._body_position, integer_types): + try: + body_seek(prepared_request._body_position) + except (IOError, OSError): + raise UnrewindableBodyError("An error occurred when rewinding request " + "body for redirect.") + else: + raise UnrewindableBodyError("Unable to rewind request body for redirect.") diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/retrying.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/retrying.py new file mode 100644 index 0000000..6d1e627 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/retrying.py @@ -0,0 +1,267 @@ +## Copyright 2013-2014 Ray Holder +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. + +import random +from pip._vendor import six +import sys +import time +import traceback + + +# sys.maxint / 2, since Python 3.2 doesn't have a sys.maxint... +MAX_WAIT = 1073741823 + + +def retry(*dargs, **dkw): + """ + Decorator function that instantiates the Retrying object + @param *dargs: positional arguments passed to Retrying object + @param **dkw: keyword arguments passed to the Retrying object + """ + # support both @retry and @retry() as valid syntax + if len(dargs) == 1 and callable(dargs[0]): + def wrap_simple(f): + + @six.wraps(f) + def wrapped_f(*args, **kw): + return Retrying().call(f, *args, **kw) + + return wrapped_f + + return wrap_simple(dargs[0]) + + else: + def wrap(f): + + @six.wraps(f) + def wrapped_f(*args, **kw): + return Retrying(*dargs, **dkw).call(f, *args, **kw) + + return wrapped_f + + return wrap + + +class Retrying(object): + + def __init__(self, + stop=None, wait=None, + stop_max_attempt_number=None, + stop_max_delay=None, + wait_fixed=None, + wait_random_min=None, wait_random_max=None, + wait_incrementing_start=None, wait_incrementing_increment=None, + wait_exponential_multiplier=None, wait_exponential_max=None, + retry_on_exception=None, + retry_on_result=None, + wrap_exception=False, + stop_func=None, + wait_func=None, + wait_jitter_max=None): + + self._stop_max_attempt_number = 5 if stop_max_attempt_number is None else stop_max_attempt_number + self._stop_max_delay = 100 if stop_max_delay is None else stop_max_delay + self._wait_fixed = 1000 if wait_fixed is None else wait_fixed + self._wait_random_min = 0 if wait_random_min is None else wait_random_min + self._wait_random_max = 1000 if wait_random_max is None else wait_random_max + self._wait_incrementing_start = 0 if wait_incrementing_start is None else wait_incrementing_start + self._wait_incrementing_increment = 100 if wait_incrementing_increment is None else wait_incrementing_increment + self._wait_exponential_multiplier = 1 if wait_exponential_multiplier is None else wait_exponential_multiplier + self._wait_exponential_max = MAX_WAIT if wait_exponential_max is None else wait_exponential_max + self._wait_jitter_max = 0 if wait_jitter_max is None else wait_jitter_max + + # TODO add chaining of stop behaviors + # stop behavior + stop_funcs = [] + if stop_max_attempt_number is not None: + stop_funcs.append(self.stop_after_attempt) + + if stop_max_delay is not None: + stop_funcs.append(self.stop_after_delay) + + if stop_func is not None: + self.stop = stop_func + + elif stop is None: + self.stop = lambda attempts, delay: any(f(attempts, delay) for f in stop_funcs) + + else: + self.stop = getattr(self, stop) + + # TODO add chaining of wait behaviors + # wait behavior + wait_funcs = [lambda *args, **kwargs: 0] + if wait_fixed is not None: + wait_funcs.append(self.fixed_sleep) + + if wait_random_min is not None or wait_random_max is not None: + wait_funcs.append(self.random_sleep) + + if wait_incrementing_start is not None or wait_incrementing_increment is not None: + wait_funcs.append(self.incrementing_sleep) + + if wait_exponential_multiplier is not None or wait_exponential_max is not None: + wait_funcs.append(self.exponential_sleep) + + if wait_func is not None: + self.wait = wait_func + + elif wait is None: + self.wait = lambda attempts, delay: max(f(attempts, delay) for f in wait_funcs) + + else: + self.wait = getattr(self, wait) + + # retry on exception filter + if retry_on_exception is None: + self._retry_on_exception = self.always_reject + else: + self._retry_on_exception = retry_on_exception + + # TODO simplify retrying by Exception types + # retry on result filter + if retry_on_result is None: + self._retry_on_result = self.never_reject + else: + self._retry_on_result = retry_on_result + + self._wrap_exception = wrap_exception + + def stop_after_attempt(self, previous_attempt_number, delay_since_first_attempt_ms): + """Stop after the previous attempt >= stop_max_attempt_number.""" + return previous_attempt_number >= self._stop_max_attempt_number + + def stop_after_delay(self, previous_attempt_number, delay_since_first_attempt_ms): + """Stop after the time from the first attempt >= stop_max_delay.""" + return delay_since_first_attempt_ms >= self._stop_max_delay + + def no_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """Don't sleep at all before retrying.""" + return 0 + + def fixed_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """Sleep a fixed amount of time between each retry.""" + return self._wait_fixed + + def random_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """Sleep a random amount of time between wait_random_min and wait_random_max""" + return random.randint(self._wait_random_min, self._wait_random_max) + + def incrementing_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """ + Sleep an incremental amount of time after each attempt, starting at + wait_incrementing_start and incrementing by wait_incrementing_increment + """ + result = self._wait_incrementing_start + (self._wait_incrementing_increment * (previous_attempt_number - 1)) + if result < 0: + result = 0 + return result + + def exponential_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + exp = 2 ** previous_attempt_number + result = self._wait_exponential_multiplier * exp + if result > self._wait_exponential_max: + result = self._wait_exponential_max + if result < 0: + result = 0 + return result + + def never_reject(self, result): + return False + + def always_reject(self, result): + return True + + def should_reject(self, attempt): + reject = False + if attempt.has_exception: + reject |= self._retry_on_exception(attempt.value[1]) + else: + reject |= self._retry_on_result(attempt.value) + + return reject + + def call(self, fn, *args, **kwargs): + start_time = int(round(time.time() * 1000)) + attempt_number = 1 + while True: + try: + attempt = Attempt(fn(*args, **kwargs), attempt_number, False) + except: + tb = sys.exc_info() + attempt = Attempt(tb, attempt_number, True) + + if not self.should_reject(attempt): + return attempt.get(self._wrap_exception) + + delay_since_first_attempt_ms = int(round(time.time() * 1000)) - start_time + if self.stop(attempt_number, delay_since_first_attempt_ms): + if not self._wrap_exception and attempt.has_exception: + # get() on an attempt with an exception should cause it to be raised, but raise just in case + raise attempt.get() + else: + raise RetryError(attempt) + else: + sleep = self.wait(attempt_number, delay_since_first_attempt_ms) + if self._wait_jitter_max: + jitter = random.random() * self._wait_jitter_max + sleep = sleep + max(0, jitter) + time.sleep(sleep / 1000.0) + + attempt_number += 1 + + +class Attempt(object): + """ + An Attempt encapsulates a call to a target function that may end as a + normal return value from the function or an Exception depending on what + occurred during the execution. + """ + + def __init__(self, value, attempt_number, has_exception): + self.value = value + self.attempt_number = attempt_number + self.has_exception = has_exception + + def get(self, wrap_exception=False): + """ + Return the return value of this Attempt instance or raise an Exception. + If wrap_exception is true, this Attempt is wrapped inside of a + RetryError before being raised. + """ + if self.has_exception: + if wrap_exception: + raise RetryError(self) + else: + six.reraise(self.value[0], self.value[1], self.value[2]) + else: + return self.value + + def __repr__(self): + if self.has_exception: + return "Attempts: {0}, Error:\n{1}".format(self.attempt_number, "".join(traceback.format_tb(self.value[2]))) + else: + return "Attempts: {0}, Value: {1}".format(self.attempt_number, self.value) + + +class RetryError(Exception): + """ + A RetryError encapsulates the last Attempt instance right before giving up. + """ + + def __init__(self, last_attempt): + self.last_attempt = last_attempt + + def __str__(self): + return "RetryError[{0}]".format(self.last_attempt) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/six.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/six.py new file mode 100644 index 0000000..6bf4fd3 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/six.py @@ -0,0 +1,891 @@ +# Copyright (c) 2010-2017 Benjamin Peterson +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +"""Utilities for writing code that runs on Python 2 and 3""" + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.11.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY34 = sys.version_info[0:2] >= (3, 4) + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + Required, if is_package is implemented""" + self.__get_module(fullname) # eventually raises ImportError + return None + get_source = get_code # same as get_code + +_importer = _SixMetaPathImporter(__name__) + + +class _MovedItems(_LazyModule): + + """Lazy loading of moved objects""" + __path__ = [] # mark as package + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("intern", "__builtin__", "sys"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), + MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), + MovedAttribute("getoutput", "commands", "subprocess"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + MovedAttribute("UserString", "UserString", "collections"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("splitvalue", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes + +_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", "moves.urllib.parse") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes + +_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", "moves.urllib.error") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), + MovedAttribute("parse_http_list", "urllib2", "urllib.request"), + MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes + +_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", "moves.urllib.request") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes + +_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", "moves.urllib.response") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes + +_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), + "moves.urllib_robotparser", "moves.urllib.robotparser") + + +class Module_six_moves_urllib(types.ModuleType): + + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + __path__ = [] # mark as package + parse = _importer._get_module("moves.urllib_parse") + error = _importer._get_module("moves.urllib_error") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +try: + callable = callable +except NameError: + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + def get_unbound_function(unbound): + return unbound + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + return types.MethodType(func, None, cls) + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") +_add_doc(itervalues, "Return an iterator over the values of a dictionary.") +_add_doc(iteritems, + "Return an iterator over the (key, value) pairs of a dictionary.") +_add_doc(iterlists, + "Return an iterator over the (key, [values]) pairs of a dictionary.") + + +if PY3: + def b(s): + return s.encode("latin-1") + + def u(s): + return s + unichr = chr + import struct + int2byte = struct.Struct(">B").pack + del struct + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter + import io + StringIO = io.StringIO + BytesIO = io.BytesIO + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" +else: + def b(s): + return s + # Workaround for standalone backslash + + def u(s): + return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + def reraise(tp, value, tb=None): + try: + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + finally: + value = None + tb = None + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + try: + raise tp, value, tb + finally: + tb = None +""") + + +if sys.version_info[:2] == (3, 2): + exec_("""def raise_from(value, from_value): + try: + if from_value is None: + raise value + raise value from from_value + finally: + value = None +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + try: + raise value from from_value + finally: + value = None +""") +else: + def raise_from(value, from_value): + raise value + + +print_ = getattr(moves.builtins, "print", None) +if print_ is None: + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + if (isinstance(fp, file) and + isinstance(data, unicode) and + fp.encoding is not None): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(fp.encoding, errors) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + if flush and fp is not None: + fp.flush() + +_add_doc(reraise, """Reraise an exception.""") + +if sys.version_info[0:2] < (3, 4): + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + def wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(type): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + + @classmethod + def __prepare__(cls, name, this_bases): + return meta.__prepare__(name, bases) + return type.__new__(metaclass, 'temporary_class', (), {}) + + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + slots = orig_vars.get('__slots__') + if slots is not None: + if isinstance(slots, str): + slots = [slots] + for slots_var in slots: + orig_vars.pop(slots_var) + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def python_2_unicode_compatible(klass): + """ + A decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if PY2: + if '__str__' not in klass.__dict__: + raise ValueError("@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % + klass.__name__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # be floating around. Therefore, we can't use isinstance() to check for + # the six meta path importer, since the other six instance will have + # inserted an importer with different class. + if (type(importer).__name__ == "_SixMetaPathImporter" and + importer.name == __name__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__init__.py new file mode 100644 index 0000000..aaa6b1c --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__init__.py @@ -0,0 +1,97 @@ +""" +urllib3 - Thread-safe connection pooling and re-using. +""" + +from __future__ import absolute_import +import warnings + +from .connectionpool import ( + HTTPConnectionPool, + HTTPSConnectionPool, + connection_from_url +) + +from . import exceptions +from .filepost import encode_multipart_formdata +from .poolmanager import PoolManager, ProxyManager, proxy_from_url +from .response import HTTPResponse +from .util.request import make_headers +from .util.url import get_host +from .util.timeout import Timeout +from .util.retry import Retry + + +# Set default logging handler to avoid "No handler found" warnings. +import logging +try: # Python 2.7+ + from logging import NullHandler +except ImportError: + class NullHandler(logging.Handler): + def emit(self, record): + pass + +__author__ = 'Andrey Petrov (andrey.petrov@shazow.net)' +__license__ = 'MIT' +__version__ = '1.22' + +__all__ = ( + 'HTTPConnectionPool', + 'HTTPSConnectionPool', + 'PoolManager', + 'ProxyManager', + 'HTTPResponse', + 'Retry', + 'Timeout', + 'add_stderr_logger', + 'connection_from_url', + 'disable_warnings', + 'encode_multipart_formdata', + 'get_host', + 'make_headers', + 'proxy_from_url', +) + +logging.getLogger(__name__).addHandler(NullHandler()) + + +def add_stderr_logger(level=logging.DEBUG): + """ + Helper for quickly adding a StreamHandler to the logger. Useful for + debugging. + + Returns the handler after adding it. + """ + # This method needs to be in this __init__.py to get the __name__ correct + # even if urllib3 is vendored within another package. + logger = logging.getLogger(__name__) + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s')) + logger.addHandler(handler) + logger.setLevel(level) + logger.debug('Added a stderr logging handler to logger: %s', __name__) + return handler + + +# ... Clean up. +del NullHandler + + +# All warning filters *must* be appended unless you're really certain that they +# shouldn't be: otherwise, it's very hard for users to use most Python +# mechanisms to silence them. +# SecurityWarning's always go off by default. +warnings.simplefilter('always', exceptions.SecurityWarning, append=True) +# SubjectAltNameWarning's should go off once per host +warnings.simplefilter('default', exceptions.SubjectAltNameWarning, append=True) +# InsecurePlatformWarning's don't vary between requests, so we keep it default. +warnings.simplefilter('default', exceptions.InsecurePlatformWarning, + append=True) +# SNIMissingWarnings should go off only once. +warnings.simplefilter('default', exceptions.SNIMissingWarning, append=True) + + +def disable_warnings(category=exceptions.HTTPWarning): + """ + Helper for quickly disabling all urllib3 warnings. + """ + warnings.simplefilter('ignore', category) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/_collections.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/_collections.py new file mode 100644 index 0000000..5df2372 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/_collections.py @@ -0,0 +1,319 @@ +from __future__ import absolute_import +from collections import Mapping, MutableMapping +try: + from threading import RLock +except ImportError: # Platform-specific: No threads available + class RLock: + def __enter__(self): + pass + + def __exit__(self, exc_type, exc_value, traceback): + pass + + +try: # Python 2.7+ + from collections import OrderedDict +except ImportError: + from .packages.ordered_dict import OrderedDict +from .packages.six import iterkeys, itervalues, PY3 + + +__all__ = ['RecentlyUsedContainer', 'HTTPHeaderDict'] + + +_Null = object() + + +class RecentlyUsedContainer(MutableMapping): + """ + Provides a thread-safe dict-like container which maintains up to + ``maxsize`` keys while throwing away the least-recently-used keys beyond + ``maxsize``. + + :param maxsize: + Maximum number of recent elements to retain. + + :param dispose_func: + Every time an item is evicted from the container, + ``dispose_func(value)`` is called. Callback which will get called + """ + + ContainerCls = OrderedDict + + def __init__(self, maxsize=10, dispose_func=None): + self._maxsize = maxsize + self.dispose_func = dispose_func + + self._container = self.ContainerCls() + self.lock = RLock() + + def __getitem__(self, key): + # Re-insert the item, moving it to the end of the eviction line. + with self.lock: + item = self._container.pop(key) + self._container[key] = item + return item + + def __setitem__(self, key, value): + evicted_value = _Null + with self.lock: + # Possibly evict the existing value of 'key' + evicted_value = self._container.get(key, _Null) + self._container[key] = value + + # If we didn't evict an existing value, we might have to evict the + # least recently used item from the beginning of the container. + if len(self._container) > self._maxsize: + _key, evicted_value = self._container.popitem(last=False) + + if self.dispose_func and evicted_value is not _Null: + self.dispose_func(evicted_value) + + def __delitem__(self, key): + with self.lock: + value = self._container.pop(key) + + if self.dispose_func: + self.dispose_func(value) + + def __len__(self): + with self.lock: + return len(self._container) + + def __iter__(self): + raise NotImplementedError('Iteration over this class is unlikely to be threadsafe.') + + def clear(self): + with self.lock: + # Copy pointers to all values, then wipe the mapping + values = list(itervalues(self._container)) + self._container.clear() + + if self.dispose_func: + for value in values: + self.dispose_func(value) + + def keys(self): + with self.lock: + return list(iterkeys(self._container)) + + +class HTTPHeaderDict(MutableMapping): + """ + :param headers: + An iterable of field-value pairs. Must not contain multiple field names + when compared case-insensitively. + + :param kwargs: + Additional field-value pairs to pass in to ``dict.update``. + + A ``dict`` like container for storing HTTP Headers. + + Field names are stored and compared case-insensitively in compliance with + RFC 7230. Iteration provides the first case-sensitive key seen for each + case-insensitive pair. + + Using ``__setitem__`` syntax overwrites fields that compare equal + case-insensitively in order to maintain ``dict``'s api. For fields that + compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add`` + in a loop. + + If multiple fields that are equal case-insensitively are passed to the + constructor or ``.update``, the behavior is undefined and some will be + lost. + + >>> headers = HTTPHeaderDict() + >>> headers.add('Set-Cookie', 'foo=bar') + >>> headers.add('set-cookie', 'baz=quxx') + >>> headers['content-length'] = '7' + >>> headers['SET-cookie'] + 'foo=bar, baz=quxx' + >>> headers['Content-Length'] + '7' + """ + + def __init__(self, headers=None, **kwargs): + super(HTTPHeaderDict, self).__init__() + self._container = OrderedDict() + if headers is not None: + if isinstance(headers, HTTPHeaderDict): + self._copy_from(headers) + else: + self.extend(headers) + if kwargs: + self.extend(kwargs) + + def __setitem__(self, key, val): + self._container[key.lower()] = [key, val] + return self._container[key.lower()] + + def __getitem__(self, key): + val = self._container[key.lower()] + return ', '.join(val[1:]) + + def __delitem__(self, key): + del self._container[key.lower()] + + def __contains__(self, key): + return key.lower() in self._container + + def __eq__(self, other): + if not isinstance(other, Mapping) and not hasattr(other, 'keys'): + return False + if not isinstance(other, type(self)): + other = type(self)(other) + return (dict((k.lower(), v) for k, v in self.itermerged()) == + dict((k.lower(), v) for k, v in other.itermerged())) + + def __ne__(self, other): + return not self.__eq__(other) + + if not PY3: # Python 2 + iterkeys = MutableMapping.iterkeys + itervalues = MutableMapping.itervalues + + __marker = object() + + def __len__(self): + return len(self._container) + + def __iter__(self): + # Only provide the originally cased names + for vals in self._container.values(): + yield vals[0] + + def pop(self, key, default=__marker): + '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + ''' + # Using the MutableMapping function directly fails due to the private marker. + # Using ordinary dict.pop would expose the internal structures. + # So let's reinvent the wheel. + try: + value = self[key] + except KeyError: + if default is self.__marker: + raise + return default + else: + del self[key] + return value + + def discard(self, key): + try: + del self[key] + except KeyError: + pass + + def add(self, key, val): + """Adds a (name, value) pair, doesn't overwrite the value if it already + exists. + + >>> headers = HTTPHeaderDict(foo='bar') + >>> headers.add('Foo', 'baz') + >>> headers['foo'] + 'bar, baz' + """ + key_lower = key.lower() + new_vals = [key, val] + # Keep the common case aka no item present as fast as possible + vals = self._container.setdefault(key_lower, new_vals) + if new_vals is not vals: + vals.append(val) + + def extend(self, *args, **kwargs): + """Generic import function for any type of header-like object. + Adapted version of MutableMapping.update in order to insert items + with self.add instead of self.__setitem__ + """ + if len(args) > 1: + raise TypeError("extend() takes at most 1 positional " + "arguments ({0} given)".format(len(args))) + other = args[0] if len(args) >= 1 else () + + if isinstance(other, HTTPHeaderDict): + for key, val in other.iteritems(): + self.add(key, val) + elif isinstance(other, Mapping): + for key in other: + self.add(key, other[key]) + elif hasattr(other, "keys"): + for key in other.keys(): + self.add(key, other[key]) + else: + for key, value in other: + self.add(key, value) + + for key, value in kwargs.items(): + self.add(key, value) + + def getlist(self, key, default=__marker): + """Returns a list of all the values for the named field. Returns an + empty list if the key doesn't exist.""" + try: + vals = self._container[key.lower()] + except KeyError: + if default is self.__marker: + return [] + return default + else: + return vals[1:] + + # Backwards compatibility for httplib + getheaders = getlist + getallmatchingheaders = getlist + iget = getlist + + # Backwards compatibility for http.cookiejar + get_all = getlist + + def __repr__(self): + return "%s(%s)" % (type(self).__name__, dict(self.itermerged())) + + def _copy_from(self, other): + for key in other: + val = other.getlist(key) + if isinstance(val, list): + # Don't need to convert tuples + val = list(val) + self._container[key.lower()] = [key] + val + + def copy(self): + clone = type(self)() + clone._copy_from(self) + return clone + + def iteritems(self): + """Iterate over all header lines, including duplicate ones.""" + for key in self: + vals = self._container[key.lower()] + for val in vals[1:]: + yield vals[0], val + + def itermerged(self): + """Iterate over all headers, merging duplicate ones together.""" + for key in self: + val = self._container[key.lower()] + yield val[0], ', '.join(val[1:]) + + def items(self): + return list(self.iteritems()) + + @classmethod + def from_httplib(cls, message): # Python 2 + """Read headers from a Python 2 httplib message object.""" + # python2.7 does not expose a proper API for exporting multiheaders + # efficiently. This function re-reads raw lines from the message + # object and extracts the multiheaders properly. + headers = [] + + for line in message.headers: + if line.startswith((' ', '\t')): + key, value = headers[-1] + headers[-1] = (key, value + '\r\n' + line.rstrip()) + continue + + key, value = line.split(':', 1) + headers.append((key, value.strip())) + + return cls(headers) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/connection.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/connection.py new file mode 100644 index 0000000..c0d8329 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/connection.py @@ -0,0 +1,373 @@ +from __future__ import absolute_import +import datetime +import logging +import os +import sys +import socket +from socket import error as SocketError, timeout as SocketTimeout +import warnings +from .packages import six +from .packages.six.moves.http_client import HTTPConnection as _HTTPConnection +from .packages.six.moves.http_client import HTTPException # noqa: F401 + +try: # Compiled with SSL? + import ssl + BaseSSLError = ssl.SSLError +except (ImportError, AttributeError): # Platform-specific: No SSL. + ssl = None + + class BaseSSLError(BaseException): + pass + + +try: # Python 3: + # Not a no-op, we're adding this to the namespace so it can be imported. + ConnectionError = ConnectionError +except NameError: # Python 2: + class ConnectionError(Exception): + pass + + +from .exceptions import ( + NewConnectionError, + ConnectTimeoutError, + SubjectAltNameWarning, + SystemTimeWarning, +) +from .packages.ssl_match_hostname import match_hostname, CertificateError + +from .util.ssl_ import ( + resolve_cert_reqs, + resolve_ssl_version, + assert_fingerprint, + create_urllib3_context, + ssl_wrap_socket +) + + +from .util import connection + +from ._collections import HTTPHeaderDict + +log = logging.getLogger(__name__) + +port_by_scheme = { + 'http': 80, + 'https': 443, +} + +# When updating RECENT_DATE, move it to +# within two years of the current date, and no +# earlier than 6 months ago. +RECENT_DATE = datetime.date(2016, 1, 1) + + +class DummyConnection(object): + """Used to detect a failed ConnectionCls import.""" + pass + + +class HTTPConnection(_HTTPConnection, object): + """ + Based on httplib.HTTPConnection but provides an extra constructor + backwards-compatibility layer between older and newer Pythons. + + Additional keyword parameters are used to configure attributes of the connection. + Accepted parameters include: + + - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool` + - ``source_address``: Set the source address for the current connection. + + .. note:: This is ignored for Python 2.6. It is only applied for 2.7 and 3.x + + - ``socket_options``: Set specific options on the underlying socket. If not specified, then + defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling + Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy. + + For example, if you wish to enable TCP Keep Alive in addition to the defaults, + you might pass:: + + HTTPConnection.default_socket_options + [ + (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), + ] + + Or you may want to disable the defaults by passing an empty list (e.g., ``[]``). + """ + + default_port = port_by_scheme['http'] + + #: Disable Nagle's algorithm by default. + #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]`` + default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)] + + #: Whether this connection verifies the host's certificate. + is_verified = False + + def __init__(self, *args, **kw): + if six.PY3: # Python 3 + kw.pop('strict', None) + + # Pre-set source_address in case we have an older Python like 2.6. + self.source_address = kw.get('source_address') + + if sys.version_info < (2, 7): # Python 2.6 + # _HTTPConnection on Python 2.6 will balk at this keyword arg, but + # not newer versions. We can still use it when creating a + # connection though, so we pop it *after* we have saved it as + # self.source_address. + kw.pop('source_address', None) + + #: The socket options provided by the user. If no options are + #: provided, we use the default options. + self.socket_options = kw.pop('socket_options', self.default_socket_options) + + # Superclass also sets self.source_address in Python 2.7+. + _HTTPConnection.__init__(self, *args, **kw) + + def _new_conn(self): + """ Establish a socket connection and set nodelay settings on it. + + :return: New socket connection. + """ + extra_kw = {} + if self.source_address: + extra_kw['source_address'] = self.source_address + + if self.socket_options: + extra_kw['socket_options'] = self.socket_options + + try: + conn = connection.create_connection( + (self.host, self.port), self.timeout, **extra_kw) + + except SocketTimeout as e: + raise ConnectTimeoutError( + self, "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout)) + + except SocketError as e: + raise NewConnectionError( + self, "Failed to establish a new connection: %s" % e) + + return conn + + def _prepare_conn(self, conn): + self.sock = conn + # the _tunnel_host attribute was added in python 2.6.3 (via + # http://hg.python.org/cpython/rev/0f57b30a152f) so pythons 2.6(0-2) do + # not have them. + if getattr(self, '_tunnel_host', None): + # TODO: Fix tunnel so it doesn't depend on self.sock state. + self._tunnel() + # Mark this connection as not reusable + self.auto_open = 0 + + def connect(self): + conn = self._new_conn() + self._prepare_conn(conn) + + def request_chunked(self, method, url, body=None, headers=None): + """ + Alternative to the common request method, which sends the + body with chunked encoding and not as one block + """ + headers = HTTPHeaderDict(headers if headers is not None else {}) + skip_accept_encoding = 'accept-encoding' in headers + skip_host = 'host' in headers + self.putrequest( + method, + url, + skip_accept_encoding=skip_accept_encoding, + skip_host=skip_host + ) + for header, value in headers.items(): + self.putheader(header, value) + if 'transfer-encoding' not in headers: + self.putheader('Transfer-Encoding', 'chunked') + self.endheaders() + + if body is not None: + stringish_types = six.string_types + (six.binary_type,) + if isinstance(body, stringish_types): + body = (body,) + for chunk in body: + if not chunk: + continue + if not isinstance(chunk, six.binary_type): + chunk = chunk.encode('utf8') + len_str = hex(len(chunk))[2:] + self.send(len_str.encode('utf-8')) + self.send(b'\r\n') + self.send(chunk) + self.send(b'\r\n') + + # After the if clause, to always have a closed body + self.send(b'0\r\n\r\n') + + +class HTTPSConnection(HTTPConnection): + default_port = port_by_scheme['https'] + + ssl_version = None + + def __init__(self, host, port=None, key_file=None, cert_file=None, + strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + ssl_context=None, **kw): + + HTTPConnection.__init__(self, host, port, strict=strict, + timeout=timeout, **kw) + + self.key_file = key_file + self.cert_file = cert_file + self.ssl_context = ssl_context + + # Required property for Google AppEngine 1.9.0 which otherwise causes + # HTTPS requests to go out as HTTP. (See Issue #356) + self._protocol = 'https' + + def connect(self): + conn = self._new_conn() + self._prepare_conn(conn) + + if self.ssl_context is None: + self.ssl_context = create_urllib3_context( + ssl_version=resolve_ssl_version(None), + cert_reqs=resolve_cert_reqs(None), + ) + + self.sock = ssl_wrap_socket( + sock=conn, + keyfile=self.key_file, + certfile=self.cert_file, + ssl_context=self.ssl_context, + ) + + +class VerifiedHTTPSConnection(HTTPSConnection): + """ + Based on httplib.HTTPSConnection but wraps the socket with + SSL certification. + """ + cert_reqs = None + ca_certs = None + ca_cert_dir = None + ssl_version = None + assert_fingerprint = None + + def set_cert(self, key_file=None, cert_file=None, + cert_reqs=None, ca_certs=None, + assert_hostname=None, assert_fingerprint=None, + ca_cert_dir=None): + """ + This method should only be called once, before the connection is used. + """ + # If cert_reqs is not provided, we can try to guess. If the user gave + # us a cert database, we assume they want to use it: otherwise, if + # they gave us an SSL Context object we should use whatever is set for + # it. + if cert_reqs is None: + if ca_certs or ca_cert_dir: + cert_reqs = 'CERT_REQUIRED' + elif self.ssl_context is not None: + cert_reqs = self.ssl_context.verify_mode + + self.key_file = key_file + self.cert_file = cert_file + self.cert_reqs = cert_reqs + self.assert_hostname = assert_hostname + self.assert_fingerprint = assert_fingerprint + self.ca_certs = ca_certs and os.path.expanduser(ca_certs) + self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir) + + def connect(self): + # Add certificate verification + conn = self._new_conn() + + hostname = self.host + if getattr(self, '_tunnel_host', None): + # _tunnel_host was added in Python 2.6.3 + # (See: http://hg.python.org/cpython/rev/0f57b30a152f) + + self.sock = conn + # Calls self._set_hostport(), so self.host is + # self._tunnel_host below. + self._tunnel() + # Mark this connection as not reusable + self.auto_open = 0 + + # Override the host with the one we're requesting data from. + hostname = self._tunnel_host + + is_time_off = datetime.date.today() < RECENT_DATE + if is_time_off: + warnings.warn(( + 'System time is way off (before {0}). This will probably ' + 'lead to SSL verification errors').format(RECENT_DATE), + SystemTimeWarning + ) + + # Wrap socket using verification with the root certs in + # trusted_root_certs + if self.ssl_context is None: + self.ssl_context = create_urllib3_context( + ssl_version=resolve_ssl_version(self.ssl_version), + cert_reqs=resolve_cert_reqs(self.cert_reqs), + ) + + context = self.ssl_context + context.verify_mode = resolve_cert_reqs(self.cert_reqs) + self.sock = ssl_wrap_socket( + sock=conn, + keyfile=self.key_file, + certfile=self.cert_file, + ca_certs=self.ca_certs, + ca_cert_dir=self.ca_cert_dir, + server_hostname=hostname, + ssl_context=context) + + if self.assert_fingerprint: + assert_fingerprint(self.sock.getpeercert(binary_form=True), + self.assert_fingerprint) + elif context.verify_mode != ssl.CERT_NONE \ + and not getattr(context, 'check_hostname', False) \ + and self.assert_hostname is not False: + # While urllib3 attempts to always turn off hostname matching from + # the TLS library, this cannot always be done. So we check whether + # the TLS Library still thinks it's matching hostnames. + cert = self.sock.getpeercert() + if not cert.get('subjectAltName', ()): + warnings.warn(( + 'Certificate for {0} has no `subjectAltName`, falling back to check for a ' + '`commonName` for now. This feature is being removed by major browsers and ' + 'deprecated by RFC 2818. (See https://github.com/shazow/urllib3/issues/497 ' + 'for details.)'.format(hostname)), + SubjectAltNameWarning + ) + _match_hostname(cert, self.assert_hostname or hostname) + + self.is_verified = ( + context.verify_mode == ssl.CERT_REQUIRED or + self.assert_fingerprint is not None + ) + + +def _match_hostname(cert, asserted_hostname): + try: + match_hostname(cert, asserted_hostname) + except CertificateError as e: + log.error( + 'Certificate did not match expected hostname: %s. ' + 'Certificate: %s', asserted_hostname, cert + ) + # Add cert to exception and reraise so client code can inspect + # the cert when catching the exception, if they want to + e._peer_cert = cert + raise + + +if ssl: + # Make a copy for testing. + UnverifiedHTTPSConnection = HTTPSConnection + HTTPSConnection = VerifiedHTTPSConnection +else: + HTTPSConnection = DummyConnection diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/connectionpool.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/connectionpool.py new file mode 100644 index 0000000..ec9600f --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/connectionpool.py @@ -0,0 +1,905 @@ +from __future__ import absolute_import +import errno +import logging +import sys +import warnings + +from socket import error as SocketError, timeout as SocketTimeout +import socket + + +from .exceptions import ( + ClosedPoolError, + ProtocolError, + EmptyPoolError, + HeaderParsingError, + HostChangedError, + LocationValueError, + MaxRetryError, + ProxyError, + ReadTimeoutError, + SSLError, + TimeoutError, + InsecureRequestWarning, + NewConnectionError, +) +from .packages.ssl_match_hostname import CertificateError +from .packages import six +from .packages.six.moves import queue +from .connection import ( + port_by_scheme, + DummyConnection, + HTTPConnection, HTTPSConnection, VerifiedHTTPSConnection, + HTTPException, BaseSSLError, +) +from .request import RequestMethods +from .response import HTTPResponse + +from .util.connection import is_connection_dropped +from .util.request import set_file_position +from .util.response import assert_header_parsing +from .util.retry import Retry +from .util.timeout import Timeout +from .util.url import get_host, Url + + +if six.PY2: + # Queue is imported for side effects on MS Windows + import Queue as _unused_module_Queue # noqa: F401 + +xrange = six.moves.xrange + +log = logging.getLogger(__name__) + +_Default = object() + + +# Pool objects +class ConnectionPool(object): + """ + Base class for all connection pools, such as + :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`. + """ + + scheme = None + QueueCls = queue.LifoQueue + + def __init__(self, host, port=None): + if not host: + raise LocationValueError("No host specified.") + + self.host = _ipv6_host(host).lower() + self._proxy_host = host.lower() + self.port = port + + def __str__(self): + return '%s(host=%r, port=%r)' % (type(self).__name__, + self.host, self.port) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + # Return False to re-raise any potential exceptions + return False + + def close(self): + """ + Close all pooled connections and disable the pool. + """ + pass + + +# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252 +_blocking_errnos = set([errno.EAGAIN, errno.EWOULDBLOCK]) + + +class HTTPConnectionPool(ConnectionPool, RequestMethods): + """ + Thread-safe connection pool for one host. + + :param host: + Host used for this HTTP Connection (e.g. "localhost"), passed into + :class:`httplib.HTTPConnection`. + + :param port: + Port used for this HTTP Connection (None is equivalent to 80), passed + into :class:`httplib.HTTPConnection`. + + :param strict: + Causes BadStatusLine to be raised if the status line can't be parsed + as a valid HTTP/1.0 or 1.1 status line, passed into + :class:`httplib.HTTPConnection`. + + .. note:: + Only works in Python 2. This parameter is ignored in Python 3. + + :param timeout: + Socket timeout in seconds for each individual connection. This can + be a float or integer, which sets the timeout for the HTTP request, + or an instance of :class:`urllib3.util.Timeout` which gives you more + fine-grained control over request timeouts. After the constructor has + been parsed, this is always a `urllib3.util.Timeout` object. + + :param maxsize: + Number of connections to save that can be reused. More than 1 is useful + in multithreaded situations. If ``block`` is set to False, more + connections will be created but they will not be saved once they've + been used. + + :param block: + If set to True, no more than ``maxsize`` connections will be used at + a time. When no free connections are available, the call will block + until a connection has been released. This is a useful side effect for + particular multithreaded situations where one does not want to use more + than maxsize connections per host to prevent flooding. + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + + :param retries: + Retry configuration to use by default with requests in this pool. + + :param _proxy: + Parsed proxy URL, should not be used directly, instead, see + :class:`urllib3.connectionpool.ProxyManager`" + + :param _proxy_headers: + A dictionary with proxy headers, should not be used directly, + instead, see :class:`urllib3.connectionpool.ProxyManager`" + + :param \\**conn_kw: + Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`, + :class:`urllib3.connection.HTTPSConnection` instances. + """ + + scheme = 'http' + ConnectionCls = HTTPConnection + ResponseCls = HTTPResponse + + def __init__(self, host, port=None, strict=False, + timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, block=False, + headers=None, retries=None, + _proxy=None, _proxy_headers=None, + **conn_kw): + ConnectionPool.__init__(self, host, port) + RequestMethods.__init__(self, headers) + + self.strict = strict + + if not isinstance(timeout, Timeout): + timeout = Timeout.from_float(timeout) + + if retries is None: + retries = Retry.DEFAULT + + self.timeout = timeout + self.retries = retries + + self.pool = self.QueueCls(maxsize) + self.block = block + + self.proxy = _proxy + self.proxy_headers = _proxy_headers or {} + + # Fill the queue up so that doing get() on it will block properly + for _ in xrange(maxsize): + self.pool.put(None) + + # These are mostly for testing and debugging purposes. + self.num_connections = 0 + self.num_requests = 0 + self.conn_kw = conn_kw + + if self.proxy: + # Enable Nagle's algorithm for proxies, to avoid packet fragmentation. + # We cannot know if the user has added default socket options, so we cannot replace the + # list. + self.conn_kw.setdefault('socket_options', []) + + def _new_conn(self): + """ + Return a fresh :class:`HTTPConnection`. + """ + self.num_connections += 1 + log.debug("Starting new HTTP connection (%d): %s", + self.num_connections, self.host) + + conn = self.ConnectionCls(host=self.host, port=self.port, + timeout=self.timeout.connect_timeout, + strict=self.strict, **self.conn_kw) + return conn + + def _get_conn(self, timeout=None): + """ + Get a connection. Will return a pooled connection if one is available. + + If no connections are available and :prop:`.block` is ``False``, then a + fresh connection is returned. + + :param timeout: + Seconds to wait before giving up and raising + :class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and + :prop:`.block` is ``True``. + """ + conn = None + try: + conn = self.pool.get(block=self.block, timeout=timeout) + + except AttributeError: # self.pool is None + raise ClosedPoolError(self, "Pool is closed.") + + except queue.Empty: + if self.block: + raise EmptyPoolError(self, + "Pool reached maximum size and no more " + "connections are allowed.") + pass # Oh well, we'll create a new connection then + + # If this is a persistent connection, check if it got disconnected + if conn and is_connection_dropped(conn): + log.debug("Resetting dropped connection: %s", self.host) + conn.close() + if getattr(conn, 'auto_open', 1) == 0: + # This is a proxied connection that has been mutated by + # httplib._tunnel() and cannot be reused (since it would + # attempt to bypass the proxy) + conn = None + + return conn or self._new_conn() + + def _put_conn(self, conn): + """ + Put a connection back into the pool. + + :param conn: + Connection object for the current host and port as returned by + :meth:`._new_conn` or :meth:`._get_conn`. + + If the pool is already full, the connection is closed and discarded + because we exceeded maxsize. If connections are discarded frequently, + then maxsize should be increased. + + If the pool is closed, then the connection will be closed and discarded. + """ + try: + self.pool.put(conn, block=False) + return # Everything is dandy, done. + except AttributeError: + # self.pool is None. + pass + except queue.Full: + # This should never happen if self.block == True + log.warning( + "Connection pool is full, discarding connection: %s", + self.host) + + # Connection never got put back into the pool, close it. + if conn: + conn.close() + + def _validate_conn(self, conn): + """ + Called right before a request is made, after the socket is created. + """ + pass + + def _prepare_proxy(self, conn): + # Nothing to do for HTTP connections. + pass + + def _get_timeout(self, timeout): + """ Helper that always returns a :class:`urllib3.util.Timeout` """ + if timeout is _Default: + return self.timeout.clone() + + if isinstance(timeout, Timeout): + return timeout.clone() + else: + # User passed us an int/float. This is for backwards compatibility, + # can be removed later + return Timeout.from_float(timeout) + + def _raise_timeout(self, err, url, timeout_value): + """Is the error actually a timeout? Will raise a ReadTimeout or pass""" + + if isinstance(err, SocketTimeout): + raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + + # See the above comment about EAGAIN in Python 3. In Python 2 we have + # to specifically catch it and throw the timeout error + if hasattr(err, 'errno') and err.errno in _blocking_errnos: + raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + + # Catch possible read timeouts thrown as SSL errors. If not the + # case, rethrow the original. We need to do this because of: + # http://bugs.python.org/issue10272 + if 'timed out' in str(err) or 'did not complete (read)' in str(err): # Python 2.6 + raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + + def _make_request(self, conn, method, url, timeout=_Default, chunked=False, + **httplib_request_kw): + """ + Perform a request on a given urllib connection object taken from our + pool. + + :param conn: + a connection from one of our connection pools + + :param timeout: + Socket timeout in seconds for the request. This can be a + float or integer, which will set the same timeout value for + the socket connect and the socket read, or an instance of + :class:`urllib3.util.Timeout`, which gives you more fine-grained + control over your timeouts. + """ + self.num_requests += 1 + + timeout_obj = self._get_timeout(timeout) + timeout_obj.start_connect() + conn.timeout = timeout_obj.connect_timeout + + # Trigger any extra validation we need to do. + try: + self._validate_conn(conn) + except (SocketTimeout, BaseSSLError) as e: + # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout. + self._raise_timeout(err=e, url=url, timeout_value=conn.timeout) + raise + + # conn.request() calls httplib.*.request, not the method in + # urllib3.request. It also calls makefile (recv) on the socket. + if chunked: + conn.request_chunked(method, url, **httplib_request_kw) + else: + conn.request(method, url, **httplib_request_kw) + + # Reset the timeout for the recv() on the socket + read_timeout = timeout_obj.read_timeout + + # App Engine doesn't have a sock attr + if getattr(conn, 'sock', None): + # In Python 3 socket.py will catch EAGAIN and return None when you + # try and read into the file pointer created by http.client, which + # instead raises a BadStatusLine exception. Instead of catching + # the exception and assuming all BadStatusLine exceptions are read + # timeouts, check for a zero timeout before making the request. + if read_timeout == 0: + raise ReadTimeoutError( + self, url, "Read timed out. (read timeout=%s)" % read_timeout) + if read_timeout is Timeout.DEFAULT_TIMEOUT: + conn.sock.settimeout(socket.getdefaulttimeout()) + else: # None or a value + conn.sock.settimeout(read_timeout) + + # Receive the response from the server + try: + try: # Python 2.7, use buffering of HTTP responses + httplib_response = conn.getresponse(buffering=True) + except TypeError: # Python 2.6 and older, Python 3 + try: + httplib_response = conn.getresponse() + except Exception as e: + # Remove the TypeError from the exception chain in Python 3; + # otherwise it looks like a programming error was the cause. + six.raise_from(e, None) + except (SocketTimeout, BaseSSLError, SocketError) as e: + self._raise_timeout(err=e, url=url, timeout_value=read_timeout) + raise + + # AppEngine doesn't have a version attr. + http_version = getattr(conn, '_http_vsn_str', 'HTTP/?') + log.debug("%s://%s:%s \"%s %s %s\" %s %s", self.scheme, self.host, self.port, + method, url, http_version, httplib_response.status, + httplib_response.length) + + try: + assert_header_parsing(httplib_response.msg) + except (HeaderParsingError, TypeError) as hpe: # Platform-specific: Python 3 + log.warning( + 'Failed to parse headers (url=%s): %s', + self._absolute_url(url), hpe, exc_info=True) + + return httplib_response + + def _absolute_url(self, path): + return Url(scheme=self.scheme, host=self.host, port=self.port, path=path).url + + def close(self): + """ + Close all pooled connections and disable the pool. + """ + # Disable access to the pool + old_pool, self.pool = self.pool, None + + try: + while True: + conn = old_pool.get(block=False) + if conn: + conn.close() + + except queue.Empty: + pass # Done. + + def is_same_host(self, url): + """ + Check if the given ``url`` is a member of the same host as this + connection pool. + """ + if url.startswith('/'): + return True + + # TODO: Add optional support for socket.gethostbyname checking. + scheme, host, port = get_host(url) + + host = _ipv6_host(host).lower() + + # Use explicit default port for comparison when none is given + if self.port and not port: + port = port_by_scheme.get(scheme) + elif not self.port and port == port_by_scheme.get(scheme): + port = None + + return (scheme, host, port) == (self.scheme, self.host, self.port) + + def urlopen(self, method, url, body=None, headers=None, retries=None, + redirect=True, assert_same_host=True, timeout=_Default, + pool_timeout=None, release_conn=None, chunked=False, + body_pos=None, **response_kw): + """ + Get a connection from the pool and perform an HTTP request. This is the + lowest level call for making a request, so you'll need to specify all + the raw details. + + .. note:: + + More commonly, it's appropriate to use a convenience method provided + by :class:`.RequestMethods`, such as :meth:`request`. + + .. note:: + + `release_conn` will only behave as expected if + `preload_content=False` because we want to make + `preload_content=False` the default behaviour someday soon without + breaking backwards compatibility. + + :param method: + HTTP request method (such as GET, POST, PUT, etc.) + + :param body: + Data to send in the request body (useful for creating + POST requests, see HTTPConnectionPool.post_url for + more convenience). + + :param headers: + Dictionary of custom headers to send, such as User-Agent, + If-None-Match, etc. If None, pool headers are used. If provided, + these headers completely replace any pool-specific headers. + + :param retries: + Configure the number of retries to allow before raising a + :class:`~urllib3.exceptions.MaxRetryError` exception. + + Pass ``None`` to retry until you receive a response. Pass a + :class:`~urllib3.util.retry.Retry` object for fine-grained control + over different types of retries. + Pass an integer number to retry connection errors that many times, + but no other types of errors. Pass zero to never retry. + + If ``False``, then retries are disabled and any exception is raised + immediately. Also, instead of raising a MaxRetryError on redirects, + the redirect response will be returned. + + :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. + + :param redirect: + If True, automatically handle redirects (status codes 301, 302, + 303, 307, 308). Each redirect counts as a retry. Disabling retries + will disable redirect, too. + + :param assert_same_host: + If ``True``, will make sure that the host of the pool requests is + consistent else will raise HostChangedError. When False, you can + use the pool on an HTTP proxy and request foreign hosts. + + :param timeout: + If specified, overrides the default timeout for this one + request. It may be a float (in seconds) or an instance of + :class:`urllib3.util.Timeout`. + + :param pool_timeout: + If set and the pool is set to block=True, then this method will + block for ``pool_timeout`` seconds and raise EmptyPoolError if no + connection is available within the time period. + + :param release_conn: + If False, then the urlopen call will not release the connection + back into the pool once a response is received (but will release if + you read the entire contents of the response such as when + `preload_content=True`). This is useful if you're not preloading + the response's content immediately. You will need to call + ``r.release_conn()`` on the response ``r`` to return the connection + back into the pool. If None, it takes the value of + ``response_kw.get('preload_content', True)``. + + :param chunked: + If True, urllib3 will send the body using chunked transfer + encoding. Otherwise, urllib3 will send the body using the standard + content-length form. Defaults to False. + + :param int body_pos: + Position to seek to in file-like body in the event of a retry or + redirect. Typically this won't need to be set because urllib3 will + auto-populate the value when needed. + + :param \\**response_kw: + Additional parameters are passed to + :meth:`urllib3.response.HTTPResponse.from_httplib` + """ + if headers is None: + headers = self.headers + + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect, default=self.retries) + + if release_conn is None: + release_conn = response_kw.get('preload_content', True) + + # Check host + if assert_same_host and not self.is_same_host(url): + raise HostChangedError(self, url, retries) + + conn = None + + # Track whether `conn` needs to be released before + # returning/raising/recursing. Update this variable if necessary, and + # leave `release_conn` constant throughout the function. That way, if + # the function recurses, the original value of `release_conn` will be + # passed down into the recursive call, and its value will be respected. + # + # See issue #651 [1] for details. + # + # [1] <https://github.com/shazow/urllib3/issues/651> + release_this_conn = release_conn + + # Merge the proxy headers. Only do this in HTTP. We have to copy the + # headers dict so we can safely change it without those changes being + # reflected in anyone else's copy. + if self.scheme == 'http': + headers = headers.copy() + headers.update(self.proxy_headers) + + # Must keep the exception bound to a separate variable or else Python 3 + # complains about UnboundLocalError. + err = None + + # Keep track of whether we cleanly exited the except block. This + # ensures we do proper cleanup in finally. + clean_exit = False + + # Rewind body position, if needed. Record current position + # for future rewinds in the event of a redirect/retry. + body_pos = set_file_position(body, body_pos) + + try: + # Request a connection from the queue. + timeout_obj = self._get_timeout(timeout) + conn = self._get_conn(timeout=pool_timeout) + + conn.timeout = timeout_obj.connect_timeout + + is_new_proxy_conn = self.proxy is not None and not getattr(conn, 'sock', None) + if is_new_proxy_conn: + self._prepare_proxy(conn) + + # Make the request on the httplib connection object. + httplib_response = self._make_request(conn, method, url, + timeout=timeout_obj, + body=body, headers=headers, + chunked=chunked) + + # If we're going to release the connection in ``finally:``, then + # the response doesn't need to know about the connection. Otherwise + # it will also try to release it and we'll have a double-release + # mess. + response_conn = conn if not release_conn else None + + # Pass method to Response for length checking + response_kw['request_method'] = method + + # Import httplib's response into our own wrapper object + response = self.ResponseCls.from_httplib(httplib_response, + pool=self, + connection=response_conn, + retries=retries, + **response_kw) + + # Everything went great! + clean_exit = True + + except queue.Empty: + # Timed out by queue. + raise EmptyPoolError(self, "No pool connections are available.") + + except (TimeoutError, HTTPException, SocketError, ProtocolError, + BaseSSLError, SSLError, CertificateError) as e: + # Discard the connection for these exceptions. It will be + # replaced during the next _get_conn() call. + clean_exit = False + if isinstance(e, (BaseSSLError, CertificateError)): + e = SSLError(e) + elif isinstance(e, (SocketError, NewConnectionError)) and self.proxy: + e = ProxyError('Cannot connect to proxy.', e) + elif isinstance(e, (SocketError, HTTPException)): + e = ProtocolError('Connection aborted.', e) + + retries = retries.increment(method, url, error=e, _pool=self, + _stacktrace=sys.exc_info()[2]) + retries.sleep() + + # Keep track of the error for the retry warning. + err = e + + finally: + if not clean_exit: + # We hit some kind of exception, handled or otherwise. We need + # to throw the connection away unless explicitly told not to. + # Close the connection, set the variable to None, and make sure + # we put the None back in the pool to avoid leaking it. + conn = conn and conn.close() + release_this_conn = True + + if release_this_conn: + # Put the connection back to be reused. If the connection is + # expired then it will be None, which will get replaced with a + # fresh connection during _get_conn. + self._put_conn(conn) + + if not conn: + # Try again + log.warning("Retrying (%r) after connection " + "broken by '%r': %s", retries, err, url) + return self.urlopen(method, url, body, headers, retries, + redirect, assert_same_host, + timeout=timeout, pool_timeout=pool_timeout, + release_conn=release_conn, body_pos=body_pos, + **response_kw) + + def drain_and_release_conn(response): + try: + # discard any remaining response body, the connection will be + # released back to the pool once the entire response is read + response.read() + except (TimeoutError, HTTPException, SocketError, ProtocolError, + BaseSSLError, SSLError) as e: + pass + + # Handle redirect? + redirect_location = redirect and response.get_redirect_location() + if redirect_location: + if response.status == 303: + method = 'GET' + + try: + retries = retries.increment(method, url, response=response, _pool=self) + except MaxRetryError: + if retries.raise_on_redirect: + # Drain and release the connection for this response, since + # we're not returning it to be released manually. + drain_and_release_conn(response) + raise + return response + + # drain and return the connection to the pool before recursing + drain_and_release_conn(response) + + retries.sleep_for_retry(response) + log.debug("Redirecting %s -> %s", url, redirect_location) + return self.urlopen( + method, redirect_location, body, headers, + retries=retries, redirect=redirect, + assert_same_host=assert_same_host, + timeout=timeout, pool_timeout=pool_timeout, + release_conn=release_conn, body_pos=body_pos, + **response_kw) + + # Check if we should retry the HTTP response. + has_retry_after = bool(response.getheader('Retry-After')) + if retries.is_retry(method, response.status, has_retry_after): + try: + retries = retries.increment(method, url, response=response, _pool=self) + except MaxRetryError: + if retries.raise_on_status: + # Drain and release the connection for this response, since + # we're not returning it to be released manually. + drain_and_release_conn(response) + raise + return response + + # drain and return the connection to the pool before recursing + drain_and_release_conn(response) + + retries.sleep(response) + log.debug("Retry: %s", url) + return self.urlopen( + method, url, body, headers, + retries=retries, redirect=redirect, + assert_same_host=assert_same_host, + timeout=timeout, pool_timeout=pool_timeout, + release_conn=release_conn, + body_pos=body_pos, **response_kw) + + return response + + +class HTTPSConnectionPool(HTTPConnectionPool): + """ + Same as :class:`.HTTPConnectionPool`, but HTTPS. + + When Python is compiled with the :mod:`ssl` module, then + :class:`.VerifiedHTTPSConnection` is used, which *can* verify certificates, + instead of :class:`.HTTPSConnection`. + + :class:`.VerifiedHTTPSConnection` uses one of ``assert_fingerprint``, + ``assert_hostname`` and ``host`` in this order to verify connections. + If ``assert_hostname`` is False, no verification is done. + + The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs``, + ``ca_cert_dir``, and ``ssl_version`` are only used if :mod:`ssl` is + available and are fed into :meth:`urllib3.util.ssl_wrap_socket` to upgrade + the connection socket into an SSL socket. + """ + + scheme = 'https' + ConnectionCls = HTTPSConnection + + def __init__(self, host, port=None, + strict=False, timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, + block=False, headers=None, retries=None, + _proxy=None, _proxy_headers=None, + key_file=None, cert_file=None, cert_reqs=None, + ca_certs=None, ssl_version=None, + assert_hostname=None, assert_fingerprint=None, + ca_cert_dir=None, **conn_kw): + + HTTPConnectionPool.__init__(self, host, port, strict, timeout, maxsize, + block, headers, retries, _proxy, _proxy_headers, + **conn_kw) + + if ca_certs and cert_reqs is None: + cert_reqs = 'CERT_REQUIRED' + + self.key_file = key_file + self.cert_file = cert_file + self.cert_reqs = cert_reqs + self.ca_certs = ca_certs + self.ca_cert_dir = ca_cert_dir + self.ssl_version = ssl_version + self.assert_hostname = assert_hostname + self.assert_fingerprint = assert_fingerprint + + def _prepare_conn(self, conn): + """ + Prepare the ``connection`` for :meth:`urllib3.util.ssl_wrap_socket` + and establish the tunnel if proxy is used. + """ + + if isinstance(conn, VerifiedHTTPSConnection): + conn.set_cert(key_file=self.key_file, + cert_file=self.cert_file, + cert_reqs=self.cert_reqs, + ca_certs=self.ca_certs, + ca_cert_dir=self.ca_cert_dir, + assert_hostname=self.assert_hostname, + assert_fingerprint=self.assert_fingerprint) + conn.ssl_version = self.ssl_version + return conn + + def _prepare_proxy(self, conn): + """ + Establish tunnel connection early, because otherwise httplib + would improperly set Host: header to proxy's IP:port. + """ + # Python 2.7+ + try: + set_tunnel = conn.set_tunnel + except AttributeError: # Platform-specific: Python 2.6 + set_tunnel = conn._set_tunnel + + if sys.version_info <= (2, 6, 4) and not self.proxy_headers: # Python 2.6.4 and older + set_tunnel(self._proxy_host, self.port) + else: + set_tunnel(self._proxy_host, self.port, self.proxy_headers) + + conn.connect() + + def _new_conn(self): + """ + Return a fresh :class:`httplib.HTTPSConnection`. + """ + self.num_connections += 1 + log.debug("Starting new HTTPS connection (%d): %s", + self.num_connections, self.host) + + if not self.ConnectionCls or self.ConnectionCls is DummyConnection: + raise SSLError("Can't connect to HTTPS URL because the SSL " + "module is not available.") + + actual_host = self.host + actual_port = self.port + if self.proxy is not None: + actual_host = self.proxy.host + actual_port = self.proxy.port + + conn = self.ConnectionCls(host=actual_host, port=actual_port, + timeout=self.timeout.connect_timeout, + strict=self.strict, **self.conn_kw) + + return self._prepare_conn(conn) + + def _validate_conn(self, conn): + """ + Called right before a request is made, after the socket is created. + """ + super(HTTPSConnectionPool, self)._validate_conn(conn) + + # Force connect early to allow us to validate the connection. + if not getattr(conn, 'sock', None): # AppEngine might not have `.sock` + conn.connect() + + if not conn.is_verified: + warnings.warn(( + 'Unverified HTTPS request is being made. ' + 'Adding certificate verification is strongly advised. See: ' + 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' + '#ssl-warnings'), + InsecureRequestWarning) + + +def connection_from_url(url, **kw): + """ + Given a url, return an :class:`.ConnectionPool` instance of its host. + + This is a shortcut for not having to parse out the scheme, host, and port + of the url before creating an :class:`.ConnectionPool` instance. + + :param url: + Absolute URL string that must include the scheme. Port is optional. + + :param \\**kw: + Passes additional parameters to the constructor of the appropriate + :class:`.ConnectionPool`. Useful for specifying things like + timeout, maxsize, headers, etc. + + Example:: + + >>> conn = connection_from_url('http://google.com/') + >>> r = conn.request('GET', '/') + """ + scheme, host, port = get_host(url) + port = port or port_by_scheme.get(scheme, 80) + if scheme == 'https': + return HTTPSConnectionPool(host, port=port, **kw) + else: + return HTTPConnectionPool(host, port=port, **kw) + + +def _ipv6_host(host): + """ + Process IPv6 address literals + """ + + # httplib doesn't like it when we include brackets in IPv6 addresses + # Specifically, if we include brackets but also pass the port then + # httplib crazily doubles up the square brackets on the Host header. + # Instead, we need to make sure we never pass ``None`` as the port. + # However, for backward compatibility reasons we can't actually + # *assert* that. See http://bugs.python.org/issue28539 + # + # Also if an IPv6 address literal has a zone identifier, the + # percent sign might be URIencoded, convert it back into ASCII + if host.startswith('[') and host.endswith(']'): + host = host.replace('%25', '%').strip('[]') + return host diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/bindings.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/bindings.py new file mode 100644 index 0000000..bcf41c0 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/bindings.py @@ -0,0 +1,593 @@ +""" +This module uses ctypes to bind a whole bunch of functions and constants from +SecureTransport. The goal here is to provide the low-level API to +SecureTransport. These are essentially the C-level functions and constants, and +they're pretty gross to work with. + +This code is a bastardised version of the code found in Will Bond's oscrypto +library. An enormous debt is owed to him for blazing this trail for us. For +that reason, this code should be considered to be covered both by urllib3's +license and by oscrypto's: + + Copyright (c) 2015-2016 Will Bond <will@wbond.net> + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +""" +from __future__ import absolute_import + +import platform +from ctypes.util import find_library +from ctypes import ( + c_void_p, c_int32, c_char_p, c_size_t, c_byte, c_uint32, c_ulong, c_long, + c_bool +) +from ctypes import CDLL, POINTER, CFUNCTYPE + + +security_path = find_library('Security') +if not security_path: + raise ImportError('The library Security could not be found') + + +core_foundation_path = find_library('CoreFoundation') +if not core_foundation_path: + raise ImportError('The library CoreFoundation could not be found') + + +version = platform.mac_ver()[0] +version_info = tuple(map(int, version.split('.'))) +if version_info < (10, 8): + raise OSError( + 'Only OS X 10.8 and newer are supported, not %s.%s' % ( + version_info[0], version_info[1] + ) + ) + +Security = CDLL(security_path, use_errno=True) +CoreFoundation = CDLL(core_foundation_path, use_errno=True) + +Boolean = c_bool +CFIndex = c_long +CFStringEncoding = c_uint32 +CFData = c_void_p +CFString = c_void_p +CFArray = c_void_p +CFMutableArray = c_void_p +CFDictionary = c_void_p +CFError = c_void_p +CFType = c_void_p +CFTypeID = c_ulong + +CFTypeRef = POINTER(CFType) +CFAllocatorRef = c_void_p + +OSStatus = c_int32 + +CFDataRef = POINTER(CFData) +CFStringRef = POINTER(CFString) +CFArrayRef = POINTER(CFArray) +CFMutableArrayRef = POINTER(CFMutableArray) +CFDictionaryRef = POINTER(CFDictionary) +CFArrayCallBacks = c_void_p +CFDictionaryKeyCallBacks = c_void_p +CFDictionaryValueCallBacks = c_void_p + +SecCertificateRef = POINTER(c_void_p) +SecExternalFormat = c_uint32 +SecExternalItemType = c_uint32 +SecIdentityRef = POINTER(c_void_p) +SecItemImportExportFlags = c_uint32 +SecItemImportExportKeyParameters = c_void_p +SecKeychainRef = POINTER(c_void_p) +SSLProtocol = c_uint32 +SSLCipherSuite = c_uint32 +SSLContextRef = POINTER(c_void_p) +SecTrustRef = POINTER(c_void_p) +SSLConnectionRef = c_uint32 +SecTrustResultType = c_uint32 +SecTrustOptionFlags = c_uint32 +SSLProtocolSide = c_uint32 +SSLConnectionType = c_uint32 +SSLSessionOption = c_uint32 + + +try: + Security.SecItemImport.argtypes = [ + CFDataRef, + CFStringRef, + POINTER(SecExternalFormat), + POINTER(SecExternalItemType), + SecItemImportExportFlags, + POINTER(SecItemImportExportKeyParameters), + SecKeychainRef, + POINTER(CFArrayRef), + ] + Security.SecItemImport.restype = OSStatus + + Security.SecCertificateGetTypeID.argtypes = [] + Security.SecCertificateGetTypeID.restype = CFTypeID + + Security.SecIdentityGetTypeID.argtypes = [] + Security.SecIdentityGetTypeID.restype = CFTypeID + + Security.SecKeyGetTypeID.argtypes = [] + Security.SecKeyGetTypeID.restype = CFTypeID + + Security.SecCertificateCreateWithData.argtypes = [ + CFAllocatorRef, + CFDataRef + ] + Security.SecCertificateCreateWithData.restype = SecCertificateRef + + Security.SecCertificateCopyData.argtypes = [ + SecCertificateRef + ] + Security.SecCertificateCopyData.restype = CFDataRef + + Security.SecCopyErrorMessageString.argtypes = [ + OSStatus, + c_void_p + ] + Security.SecCopyErrorMessageString.restype = CFStringRef + + Security.SecIdentityCreateWithCertificate.argtypes = [ + CFTypeRef, + SecCertificateRef, + POINTER(SecIdentityRef) + ] + Security.SecIdentityCreateWithCertificate.restype = OSStatus + + Security.SecKeychainCreate.argtypes = [ + c_char_p, + c_uint32, + c_void_p, + Boolean, + c_void_p, + POINTER(SecKeychainRef) + ] + Security.SecKeychainCreate.restype = OSStatus + + Security.SecKeychainDelete.argtypes = [ + SecKeychainRef + ] + Security.SecKeychainDelete.restype = OSStatus + + Security.SecPKCS12Import.argtypes = [ + CFDataRef, + CFDictionaryRef, + POINTER(CFArrayRef) + ] + Security.SecPKCS12Import.restype = OSStatus + + SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t)) + SSLWriteFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t)) + + Security.SSLSetIOFuncs.argtypes = [ + SSLContextRef, + SSLReadFunc, + SSLWriteFunc + ] + Security.SSLSetIOFuncs.restype = OSStatus + + Security.SSLSetPeerID.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t + ] + Security.SSLSetPeerID.restype = OSStatus + + Security.SSLSetCertificate.argtypes = [ + SSLContextRef, + CFArrayRef + ] + Security.SSLSetCertificate.restype = OSStatus + + Security.SSLSetCertificateAuthorities.argtypes = [ + SSLContextRef, + CFTypeRef, + Boolean + ] + Security.SSLSetCertificateAuthorities.restype = OSStatus + + Security.SSLSetConnection.argtypes = [ + SSLContextRef, + SSLConnectionRef + ] + Security.SSLSetConnection.restype = OSStatus + + Security.SSLSetPeerDomainName.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t + ] + Security.SSLSetPeerDomainName.restype = OSStatus + + Security.SSLHandshake.argtypes = [ + SSLContextRef + ] + Security.SSLHandshake.restype = OSStatus + + Security.SSLRead.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t, + POINTER(c_size_t) + ] + Security.SSLRead.restype = OSStatus + + Security.SSLWrite.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t, + POINTER(c_size_t) + ] + Security.SSLWrite.restype = OSStatus + + Security.SSLClose.argtypes = [ + SSLContextRef + ] + Security.SSLClose.restype = OSStatus + + Security.SSLGetNumberSupportedCiphers.argtypes = [ + SSLContextRef, + POINTER(c_size_t) + ] + Security.SSLGetNumberSupportedCiphers.restype = OSStatus + + Security.SSLGetSupportedCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + POINTER(c_size_t) + ] + Security.SSLGetSupportedCiphers.restype = OSStatus + + Security.SSLSetEnabledCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + c_size_t + ] + Security.SSLSetEnabledCiphers.restype = OSStatus + + Security.SSLGetNumberEnabledCiphers.argtype = [ + SSLContextRef, + POINTER(c_size_t) + ] + Security.SSLGetNumberEnabledCiphers.restype = OSStatus + + Security.SSLGetEnabledCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + POINTER(c_size_t) + ] + Security.SSLGetEnabledCiphers.restype = OSStatus + + Security.SSLGetNegotiatedCipher.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite) + ] + Security.SSLGetNegotiatedCipher.restype = OSStatus + + Security.SSLGetNegotiatedProtocolVersion.argtypes = [ + SSLContextRef, + POINTER(SSLProtocol) + ] + Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus + + Security.SSLCopyPeerTrust.argtypes = [ + SSLContextRef, + POINTER(SecTrustRef) + ] + Security.SSLCopyPeerTrust.restype = OSStatus + + Security.SecTrustSetAnchorCertificates.argtypes = [ + SecTrustRef, + CFArrayRef + ] + Security.SecTrustSetAnchorCertificates.restype = OSStatus + + Security.SecTrustSetAnchorCertificatesOnly.argstypes = [ + SecTrustRef, + Boolean + ] + Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus + + Security.SecTrustEvaluate.argtypes = [ + SecTrustRef, + POINTER(SecTrustResultType) + ] + Security.SecTrustEvaluate.restype = OSStatus + + Security.SecTrustGetCertificateCount.argtypes = [ + SecTrustRef + ] + Security.SecTrustGetCertificateCount.restype = CFIndex + + Security.SecTrustGetCertificateAtIndex.argtypes = [ + SecTrustRef, + CFIndex + ] + Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef + + Security.SSLCreateContext.argtypes = [ + CFAllocatorRef, + SSLProtocolSide, + SSLConnectionType + ] + Security.SSLCreateContext.restype = SSLContextRef + + Security.SSLSetSessionOption.argtypes = [ + SSLContextRef, + SSLSessionOption, + Boolean + ] + Security.SSLSetSessionOption.restype = OSStatus + + Security.SSLSetProtocolVersionMin.argtypes = [ + SSLContextRef, + SSLProtocol + ] + Security.SSLSetProtocolVersionMin.restype = OSStatus + + Security.SSLSetProtocolVersionMax.argtypes = [ + SSLContextRef, + SSLProtocol + ] + Security.SSLSetProtocolVersionMax.restype = OSStatus + + Security.SecCopyErrorMessageString.argtypes = [ + OSStatus, + c_void_p + ] + Security.SecCopyErrorMessageString.restype = CFStringRef + + Security.SSLReadFunc = SSLReadFunc + Security.SSLWriteFunc = SSLWriteFunc + Security.SSLContextRef = SSLContextRef + Security.SSLProtocol = SSLProtocol + Security.SSLCipherSuite = SSLCipherSuite + Security.SecIdentityRef = SecIdentityRef + Security.SecKeychainRef = SecKeychainRef + Security.SecTrustRef = SecTrustRef + Security.SecTrustResultType = SecTrustResultType + Security.SecExternalFormat = SecExternalFormat + Security.OSStatus = OSStatus + + Security.kSecImportExportPassphrase = CFStringRef.in_dll( + Security, 'kSecImportExportPassphrase' + ) + Security.kSecImportItemIdentity = CFStringRef.in_dll( + Security, 'kSecImportItemIdentity' + ) + + # CoreFoundation time! + CoreFoundation.CFRetain.argtypes = [ + CFTypeRef + ] + CoreFoundation.CFRetain.restype = CFTypeRef + + CoreFoundation.CFRelease.argtypes = [ + CFTypeRef + ] + CoreFoundation.CFRelease.restype = None + + CoreFoundation.CFGetTypeID.argtypes = [ + CFTypeRef + ] + CoreFoundation.CFGetTypeID.restype = CFTypeID + + CoreFoundation.CFStringCreateWithCString.argtypes = [ + CFAllocatorRef, + c_char_p, + CFStringEncoding + ] + CoreFoundation.CFStringCreateWithCString.restype = CFStringRef + + CoreFoundation.CFStringGetCStringPtr.argtypes = [ + CFStringRef, + CFStringEncoding + ] + CoreFoundation.CFStringGetCStringPtr.restype = c_char_p + + CoreFoundation.CFStringGetCString.argtypes = [ + CFStringRef, + c_char_p, + CFIndex, + CFStringEncoding + ] + CoreFoundation.CFStringGetCString.restype = c_bool + + CoreFoundation.CFDataCreate.argtypes = [ + CFAllocatorRef, + c_char_p, + CFIndex + ] + CoreFoundation.CFDataCreate.restype = CFDataRef + + CoreFoundation.CFDataGetLength.argtypes = [ + CFDataRef + ] + CoreFoundation.CFDataGetLength.restype = CFIndex + + CoreFoundation.CFDataGetBytePtr.argtypes = [ + CFDataRef + ] + CoreFoundation.CFDataGetBytePtr.restype = c_void_p + + CoreFoundation.CFDictionaryCreate.argtypes = [ + CFAllocatorRef, + POINTER(CFTypeRef), + POINTER(CFTypeRef), + CFIndex, + CFDictionaryKeyCallBacks, + CFDictionaryValueCallBacks + ] + CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef + + CoreFoundation.CFDictionaryGetValue.argtypes = [ + CFDictionaryRef, + CFTypeRef + ] + CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef + + CoreFoundation.CFArrayCreate.argtypes = [ + CFAllocatorRef, + POINTER(CFTypeRef), + CFIndex, + CFArrayCallBacks, + ] + CoreFoundation.CFArrayCreate.restype = CFArrayRef + + CoreFoundation.CFArrayCreateMutable.argtypes = [ + CFAllocatorRef, + CFIndex, + CFArrayCallBacks + ] + CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef + + CoreFoundation.CFArrayAppendValue.argtypes = [ + CFMutableArrayRef, + c_void_p + ] + CoreFoundation.CFArrayAppendValue.restype = None + + CoreFoundation.CFArrayGetCount.argtypes = [ + CFArrayRef + ] + CoreFoundation.CFArrayGetCount.restype = CFIndex + + CoreFoundation.CFArrayGetValueAtIndex.argtypes = [ + CFArrayRef, + CFIndex + ] + CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p + + CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll( + CoreFoundation, 'kCFAllocatorDefault' + ) + CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll(CoreFoundation, 'kCFTypeArrayCallBacks') + CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll( + CoreFoundation, 'kCFTypeDictionaryKeyCallBacks' + ) + CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll( + CoreFoundation, 'kCFTypeDictionaryValueCallBacks' + ) + + CoreFoundation.CFTypeRef = CFTypeRef + CoreFoundation.CFArrayRef = CFArrayRef + CoreFoundation.CFStringRef = CFStringRef + CoreFoundation.CFDictionaryRef = CFDictionaryRef + +except (AttributeError): + raise ImportError('Error initializing ctypes') + + +class CFConst(object): + """ + A class object that acts as essentially a namespace for CoreFoundation + constants. + """ + kCFStringEncodingUTF8 = CFStringEncoding(0x08000100) + + +class SecurityConst(object): + """ + A class object that acts as essentially a namespace for Security constants. + """ + kSSLSessionOptionBreakOnServerAuth = 0 + + kSSLProtocol2 = 1 + kSSLProtocol3 = 2 + kTLSProtocol1 = 4 + kTLSProtocol11 = 7 + kTLSProtocol12 = 8 + + kSSLClientSide = 1 + kSSLStreamType = 0 + + kSecFormatPEMSequence = 10 + + kSecTrustResultInvalid = 0 + kSecTrustResultProceed = 1 + # This gap is present on purpose: this was kSecTrustResultConfirm, which + # is deprecated. + kSecTrustResultDeny = 3 + kSecTrustResultUnspecified = 4 + kSecTrustResultRecoverableTrustFailure = 5 + kSecTrustResultFatalTrustFailure = 6 + kSecTrustResultOtherError = 7 + + errSSLProtocol = -9800 + errSSLWouldBlock = -9803 + errSSLClosedGraceful = -9805 + errSSLClosedNoNotify = -9816 + errSSLClosedAbort = -9806 + + errSSLXCertChainInvalid = -9807 + errSSLCrypto = -9809 + errSSLInternal = -9810 + errSSLCertExpired = -9814 + errSSLCertNotYetValid = -9815 + errSSLUnknownRootCert = -9812 + errSSLNoRootCert = -9813 + errSSLHostNameMismatch = -9843 + errSSLPeerHandshakeFail = -9824 + errSSLPeerUserCancelled = -9839 + errSSLWeakPeerEphemeralDHKey = -9850 + errSSLServerAuthCompleted = -9841 + errSSLRecordOverflow = -9847 + + errSecVerifyFailed = -67808 + errSecNoTrustSettings = -25263 + errSecItemNotFound = -25300 + errSecInvalidTrustSettings = -25262 + + # Cipher suites. We only pick the ones our default cipher string allows. + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F + TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F + TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024 + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028 + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014 + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B + TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A + TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039 + TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013 + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067 + TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040 + TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033 + TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032 + TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D + TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C + TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D + TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C + TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035 + TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F + TLS_AES_128_GCM_SHA256 = 0x1301 + TLS_AES_256_GCM_SHA384 = 0x1302 + TLS_CHACHA20_POLY1305_SHA256 = 0x1303 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/low_level.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/low_level.py new file mode 100644 index 0000000..5e3494b --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/low_level.py @@ -0,0 +1,343 @@ +""" +Low-level helpers for the SecureTransport bindings. + +These are Python functions that are not directly related to the high-level APIs +but are necessary to get them to work. They include a whole bunch of low-level +CoreFoundation messing about and memory management. The concerns in this module +are almost entirely about trying to avoid memory leaks and providing +appropriate and useful assistance to the higher-level code. +""" +import base64 +import ctypes +import itertools +import re +import os +import ssl +import tempfile + +from .bindings import Security, CoreFoundation, CFConst + + +# This regular expression is used to grab PEM data out of a PEM bundle. +_PEM_CERTS_RE = re.compile( + b"-----BEGIN CERTIFICATE-----\n(.*?)\n-----END CERTIFICATE-----", re.DOTALL +) + + +def _cf_data_from_bytes(bytestring): + """ + Given a bytestring, create a CFData object from it. This CFData object must + be CFReleased by the caller. + """ + return CoreFoundation.CFDataCreate( + CoreFoundation.kCFAllocatorDefault, bytestring, len(bytestring) + ) + + +def _cf_dictionary_from_tuples(tuples): + """ + Given a list of Python tuples, create an associated CFDictionary. + """ + dictionary_size = len(tuples) + + # We need to get the dictionary keys and values out in the same order. + keys = (t[0] for t in tuples) + values = (t[1] for t in tuples) + cf_keys = (CoreFoundation.CFTypeRef * dictionary_size)(*keys) + cf_values = (CoreFoundation.CFTypeRef * dictionary_size)(*values) + + return CoreFoundation.CFDictionaryCreate( + CoreFoundation.kCFAllocatorDefault, + cf_keys, + cf_values, + dictionary_size, + CoreFoundation.kCFTypeDictionaryKeyCallBacks, + CoreFoundation.kCFTypeDictionaryValueCallBacks, + ) + + +def _cf_string_to_unicode(value): + """ + Creates a Unicode string from a CFString object. Used entirely for error + reporting. + + Yes, it annoys me quite a lot that this function is this complex. + """ + value_as_void_p = ctypes.cast(value, ctypes.POINTER(ctypes.c_void_p)) + + string = CoreFoundation.CFStringGetCStringPtr( + value_as_void_p, + CFConst.kCFStringEncodingUTF8 + ) + if string is None: + buffer = ctypes.create_string_buffer(1024) + result = CoreFoundation.CFStringGetCString( + value_as_void_p, + buffer, + 1024, + CFConst.kCFStringEncodingUTF8 + ) + if not result: + raise OSError('Error copying C string from CFStringRef') + string = buffer.value + if string is not None: + string = string.decode('utf-8') + return string + + +def _assert_no_error(error, exception_class=None): + """ + Checks the return code and throws an exception if there is an error to + report + """ + if error == 0: + return + + cf_error_string = Security.SecCopyErrorMessageString(error, None) + output = _cf_string_to_unicode(cf_error_string) + CoreFoundation.CFRelease(cf_error_string) + + if output is None or output == u'': + output = u'OSStatus %s' % error + + if exception_class is None: + exception_class = ssl.SSLError + + raise exception_class(output) + + +def _cert_array_from_pem(pem_bundle): + """ + Given a bundle of certs in PEM format, turns them into a CFArray of certs + that can be used to validate a cert chain. + """ + der_certs = [ + base64.b64decode(match.group(1)) + for match in _PEM_CERTS_RE.finditer(pem_bundle) + ] + if not der_certs: + raise ssl.SSLError("No root certificates specified") + + cert_array = CoreFoundation.CFArrayCreateMutable( + CoreFoundation.kCFAllocatorDefault, + 0, + ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks) + ) + if not cert_array: + raise ssl.SSLError("Unable to allocate memory!") + + try: + for der_bytes in der_certs: + certdata = _cf_data_from_bytes(der_bytes) + if not certdata: + raise ssl.SSLError("Unable to allocate memory!") + cert = Security.SecCertificateCreateWithData( + CoreFoundation.kCFAllocatorDefault, certdata + ) + CoreFoundation.CFRelease(certdata) + if not cert: + raise ssl.SSLError("Unable to build cert object!") + + CoreFoundation.CFArrayAppendValue(cert_array, cert) + CoreFoundation.CFRelease(cert) + except Exception: + # We need to free the array before the exception bubbles further. + # We only want to do that if an error occurs: otherwise, the caller + # should free. + CoreFoundation.CFRelease(cert_array) + + return cert_array + + +def _is_cert(item): + """ + Returns True if a given CFTypeRef is a certificate. + """ + expected = Security.SecCertificateGetTypeID() + return CoreFoundation.CFGetTypeID(item) == expected + + +def _is_identity(item): + """ + Returns True if a given CFTypeRef is an identity. + """ + expected = Security.SecIdentityGetTypeID() + return CoreFoundation.CFGetTypeID(item) == expected + + +def _temporary_keychain(): + """ + This function creates a temporary Mac keychain that we can use to work with + credentials. This keychain uses a one-time password and a temporary file to + store the data. We expect to have one keychain per socket. The returned + SecKeychainRef must be freed by the caller, including calling + SecKeychainDelete. + + Returns a tuple of the SecKeychainRef and the path to the temporary + directory that contains it. + """ + # Unfortunately, SecKeychainCreate requires a path to a keychain. This + # means we cannot use mkstemp to use a generic temporary file. Instead, + # we're going to create a temporary directory and a filename to use there. + # This filename will be 8 random bytes expanded into base64. We also need + # some random bytes to password-protect the keychain we're creating, so we + # ask for 40 random bytes. + random_bytes = os.urandom(40) + filename = base64.b64encode(random_bytes[:8]).decode('utf-8') + password = base64.b64encode(random_bytes[8:]) # Must be valid UTF-8 + tempdirectory = tempfile.mkdtemp() + + keychain_path = os.path.join(tempdirectory, filename).encode('utf-8') + + # We now want to create the keychain itself. + keychain = Security.SecKeychainRef() + status = Security.SecKeychainCreate( + keychain_path, + len(password), + password, + False, + None, + ctypes.byref(keychain) + ) + _assert_no_error(status) + + # Having created the keychain, we want to pass it off to the caller. + return keychain, tempdirectory + + +def _load_items_from_file(keychain, path): + """ + Given a single file, loads all the trust objects from it into arrays and + the keychain. + Returns a tuple of lists: the first list is a list of identities, the + second a list of certs. + """ + certificates = [] + identities = [] + result_array = None + + with open(path, 'rb') as f: + raw_filedata = f.read() + + try: + filedata = CoreFoundation.CFDataCreate( + CoreFoundation.kCFAllocatorDefault, + raw_filedata, + len(raw_filedata) + ) + result_array = CoreFoundation.CFArrayRef() + result = Security.SecItemImport( + filedata, # cert data + None, # Filename, leaving it out for now + None, # What the type of the file is, we don't care + None, # what's in the file, we don't care + 0, # import flags + None, # key params, can include passphrase in the future + keychain, # The keychain to insert into + ctypes.byref(result_array) # Results + ) + _assert_no_error(result) + + # A CFArray is not very useful to us as an intermediary + # representation, so we are going to extract the objects we want + # and then free the array. We don't need to keep hold of keys: the + # keychain already has them! + result_count = CoreFoundation.CFArrayGetCount(result_array) + for index in range(result_count): + item = CoreFoundation.CFArrayGetValueAtIndex( + result_array, index + ) + item = ctypes.cast(item, CoreFoundation.CFTypeRef) + + if _is_cert(item): + CoreFoundation.CFRetain(item) + certificates.append(item) + elif _is_identity(item): + CoreFoundation.CFRetain(item) + identities.append(item) + finally: + if result_array: + CoreFoundation.CFRelease(result_array) + + CoreFoundation.CFRelease(filedata) + + return (identities, certificates) + + +def _load_client_cert_chain(keychain, *paths): + """ + Load certificates and maybe keys from a number of files. Has the end goal + of returning a CFArray containing one SecIdentityRef, and then zero or more + SecCertificateRef objects, suitable for use as a client certificate trust + chain. + """ + # Ok, the strategy. + # + # This relies on knowing that macOS will not give you a SecIdentityRef + # unless you have imported a key into a keychain. This is a somewhat + # artificial limitation of macOS (for example, it doesn't necessarily + # affect iOS), but there is nothing inside Security.framework that lets you + # get a SecIdentityRef without having a key in a keychain. + # + # So the policy here is we take all the files and iterate them in order. + # Each one will use SecItemImport to have one or more objects loaded from + # it. We will also point at a keychain that macOS can use to work with the + # private key. + # + # Once we have all the objects, we'll check what we actually have. If we + # already have a SecIdentityRef in hand, fab: we'll use that. Otherwise, + # we'll take the first certificate (which we assume to be our leaf) and + # ask the keychain to give us a SecIdentityRef with that cert's associated + # key. + # + # We'll then return a CFArray containing the trust chain: one + # SecIdentityRef and then zero-or-more SecCertificateRef objects. The + # responsibility for freeing this CFArray will be with the caller. This + # CFArray must remain alive for the entire connection, so in practice it + # will be stored with a single SSLSocket, along with the reference to the + # keychain. + certificates = [] + identities = [] + + # Filter out bad paths. + paths = (path for path in paths if path) + + try: + for file_path in paths: + new_identities, new_certs = _load_items_from_file( + keychain, file_path + ) + identities.extend(new_identities) + certificates.extend(new_certs) + + # Ok, we have everything. The question is: do we have an identity? If + # not, we want to grab one from the first cert we have. + if not identities: + new_identity = Security.SecIdentityRef() + status = Security.SecIdentityCreateWithCertificate( + keychain, + certificates[0], + ctypes.byref(new_identity) + ) + _assert_no_error(status) + identities.append(new_identity) + + # We now want to release the original certificate, as we no longer + # need it. + CoreFoundation.CFRelease(certificates.pop(0)) + + # We now need to build a new CFArray that holds the trust chain. + trust_chain = CoreFoundation.CFArrayCreateMutable( + CoreFoundation.kCFAllocatorDefault, + 0, + ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), + ) + for item in itertools.chain(identities, certificates): + # ArrayAppendValue does a CFRetain on the item. That's fine, + # because the finally block will release our other refs to them. + CoreFoundation.CFArrayAppendValue(trust_chain, item) + + return trust_chain + finally: + for obj in itertools.chain(identities, certificates): + CoreFoundation.CFRelease(obj) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/appengine.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/appengine.py new file mode 100644 index 0000000..ce17e83 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/appengine.py @@ -0,0 +1,296 @@ +""" +This module provides a pool manager that uses Google App Engine's +`URLFetch Service <https://cloud.google.com/appengine/docs/python/urlfetch>`_. + +Example usage:: + + from pip._vendor.urllib3 import PoolManager + from pip._vendor.urllib3.contrib.appengine import AppEngineManager, is_appengine_sandbox + + if is_appengine_sandbox(): + # AppEngineManager uses AppEngine's URLFetch API behind the scenes + http = AppEngineManager() + else: + # PoolManager uses a socket-level API behind the scenes + http = PoolManager() + + r = http.request('GET', 'https://google.com/') + +There are `limitations <https://cloud.google.com/appengine/docs/python/\ +urlfetch/#Python_Quotas_and_limits>`_ to the URLFetch service and it may not be +the best choice for your application. There are three options for using +urllib3 on Google App Engine: + +1. You can use :class:`AppEngineManager` with URLFetch. URLFetch is + cost-effective in many circumstances as long as your usage is within the + limitations. +2. You can use a normal :class:`~urllib3.PoolManager` by enabling sockets. + Sockets also have `limitations and restrictions + <https://cloud.google.com/appengine/docs/python/sockets/\ + #limitations-and-restrictions>`_ and have a lower free quota than URLFetch. + To use sockets, be sure to specify the following in your ``app.yaml``:: + + env_variables: + GAE_USE_SOCKETS_HTTPLIB : 'true' + +3. If you are using `App Engine Flexible +<https://cloud.google.com/appengine/docs/flexible/>`_, you can use the standard +:class:`PoolManager` without any configuration or special environment variables. +""" + +from __future__ import absolute_import +import logging +import os +import warnings +from ..packages.six.moves.urllib.parse import urljoin + +from ..exceptions import ( + HTTPError, + HTTPWarning, + MaxRetryError, + ProtocolError, + TimeoutError, + SSLError +) + +from ..packages.six import BytesIO +from ..request import RequestMethods +from ..response import HTTPResponse +from ..util.timeout import Timeout +from ..util.retry import Retry + +try: + from google.appengine.api import urlfetch +except ImportError: + urlfetch = None + + +log = logging.getLogger(__name__) + + +class AppEnginePlatformWarning(HTTPWarning): + pass + + +class AppEnginePlatformError(HTTPError): + pass + + +class AppEngineManager(RequestMethods): + """ + Connection manager for Google App Engine sandbox applications. + + This manager uses the URLFetch service directly instead of using the + emulated httplib, and is subject to URLFetch limitations as described in + the App Engine documentation `here + <https://cloud.google.com/appengine/docs/python/urlfetch>`_. + + Notably it will raise an :class:`AppEnginePlatformError` if: + * URLFetch is not available. + * If you attempt to use this on App Engine Flexible, as full socket + support is available. + * If a request size is more than 10 megabytes. + * If a response size is more than 32 megabtyes. + * If you use an unsupported request method such as OPTIONS. + + Beyond those cases, it will raise normal urllib3 errors. + """ + + def __init__(self, headers=None, retries=None, validate_certificate=True, + urlfetch_retries=True): + if not urlfetch: + raise AppEnginePlatformError( + "URLFetch is not available in this environment.") + + if is_prod_appengine_mvms(): + raise AppEnginePlatformError( + "Use normal urllib3.PoolManager instead of AppEngineManager" + "on Managed VMs, as using URLFetch is not necessary in " + "this environment.") + + warnings.warn( + "urllib3 is using URLFetch on Google App Engine sandbox instead " + "of sockets. To use sockets directly instead of URLFetch see " + "https://urllib3.readthedocs.io/en/latest/reference/urllib3.contrib.html.", + AppEnginePlatformWarning) + + RequestMethods.__init__(self, headers) + self.validate_certificate = validate_certificate + self.urlfetch_retries = urlfetch_retries + + self.retries = retries or Retry.DEFAULT + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + # Return False to re-raise any potential exceptions + return False + + def urlopen(self, method, url, body=None, headers=None, + retries=None, redirect=True, timeout=Timeout.DEFAULT_TIMEOUT, + **response_kw): + + retries = self._get_retries(retries, redirect) + + try: + follow_redirects = ( + redirect and + retries.redirect != 0 and + retries.total) + response = urlfetch.fetch( + url, + payload=body, + method=method, + headers=headers or {}, + allow_truncated=False, + follow_redirects=self.urlfetch_retries and follow_redirects, + deadline=self._get_absolute_timeout(timeout), + validate_certificate=self.validate_certificate, + ) + except urlfetch.DeadlineExceededError as e: + raise TimeoutError(self, e) + + except urlfetch.InvalidURLError as e: + if 'too large' in str(e): + raise AppEnginePlatformError( + "URLFetch request too large, URLFetch only " + "supports requests up to 10mb in size.", e) + raise ProtocolError(e) + + except urlfetch.DownloadError as e: + if 'Too many redirects' in str(e): + raise MaxRetryError(self, url, reason=e) + raise ProtocolError(e) + + except urlfetch.ResponseTooLargeError as e: + raise AppEnginePlatformError( + "URLFetch response too large, URLFetch only supports" + "responses up to 32mb in size.", e) + + except urlfetch.SSLCertificateError as e: + raise SSLError(e) + + except urlfetch.InvalidMethodError as e: + raise AppEnginePlatformError( + "URLFetch does not support method: %s" % method, e) + + http_response = self._urlfetch_response_to_http_response( + response, retries=retries, **response_kw) + + # Handle redirect? + redirect_location = redirect and http_response.get_redirect_location() + if redirect_location: + # Check for redirect response + if (self.urlfetch_retries and retries.raise_on_redirect): + raise MaxRetryError(self, url, "too many redirects") + else: + if http_response.status == 303: + method = 'GET' + + try: + retries = retries.increment(method, url, response=http_response, _pool=self) + except MaxRetryError: + if retries.raise_on_redirect: + raise MaxRetryError(self, url, "too many redirects") + return http_response + + retries.sleep_for_retry(http_response) + log.debug("Redirecting %s -> %s", url, redirect_location) + redirect_url = urljoin(url, redirect_location) + return self.urlopen( + method, redirect_url, body, headers, + retries=retries, redirect=redirect, + timeout=timeout, **response_kw) + + # Check if we should retry the HTTP response. + has_retry_after = bool(http_response.getheader('Retry-After')) + if retries.is_retry(method, http_response.status, has_retry_after): + retries = retries.increment( + method, url, response=http_response, _pool=self) + log.debug("Retry: %s", url) + retries.sleep(http_response) + return self.urlopen( + method, url, + body=body, headers=headers, + retries=retries, redirect=redirect, + timeout=timeout, **response_kw) + + return http_response + + def _urlfetch_response_to_http_response(self, urlfetch_resp, **response_kw): + + if is_prod_appengine(): + # Production GAE handles deflate encoding automatically, but does + # not remove the encoding header. + content_encoding = urlfetch_resp.headers.get('content-encoding') + + if content_encoding == 'deflate': + del urlfetch_resp.headers['content-encoding'] + + transfer_encoding = urlfetch_resp.headers.get('transfer-encoding') + # We have a full response's content, + # so let's make sure we don't report ourselves as chunked data. + if transfer_encoding == 'chunked': + encodings = transfer_encoding.split(",") + encodings.remove('chunked') + urlfetch_resp.headers['transfer-encoding'] = ','.join(encodings) + + return HTTPResponse( + # In order for decoding to work, we must present the content as + # a file-like object. + body=BytesIO(urlfetch_resp.content), + headers=urlfetch_resp.headers, + status=urlfetch_resp.status_code, + **response_kw + ) + + def _get_absolute_timeout(self, timeout): + if timeout is Timeout.DEFAULT_TIMEOUT: + return None # Defer to URLFetch's default. + if isinstance(timeout, Timeout): + if timeout._read is not None or timeout._connect is not None: + warnings.warn( + "URLFetch does not support granular timeout settings, " + "reverting to total or default URLFetch timeout.", + AppEnginePlatformWarning) + return timeout.total + return timeout + + def _get_retries(self, retries, redirect): + if not isinstance(retries, Retry): + retries = Retry.from_int( + retries, redirect=redirect, default=self.retries) + + if retries.connect or retries.read or retries.redirect: + warnings.warn( + "URLFetch only supports total retries and does not " + "recognize connect, read, or redirect retry parameters.", + AppEnginePlatformWarning) + + return retries + + +def is_appengine(): + return (is_local_appengine() or + is_prod_appengine() or + is_prod_appengine_mvms()) + + +def is_appengine_sandbox(): + return is_appengine() and not is_prod_appengine_mvms() + + +def is_local_appengine(): + return ('APPENGINE_RUNTIME' in os.environ and + 'Development/' in os.environ['SERVER_SOFTWARE']) + + +def is_prod_appengine(): + return ('APPENGINE_RUNTIME' in os.environ and + 'Google App Engine/' in os.environ['SERVER_SOFTWARE'] and + not is_prod_appengine_mvms()) + + +def is_prod_appengine_mvms(): + return os.environ.get('GAE_VM', False) == 'true' diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/ntlmpool.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/ntlmpool.py new file mode 100644 index 0000000..642e99e --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/ntlmpool.py @@ -0,0 +1,112 @@ +""" +NTLM authenticating pool, contributed by erikcederstran + +Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10 +""" +from __future__ import absolute_import + +from logging import getLogger +from ntlm import ntlm + +from .. import HTTPSConnectionPool +from ..packages.six.moves.http_client import HTTPSConnection + + +log = getLogger(__name__) + + +class NTLMConnectionPool(HTTPSConnectionPool): + """ + Implements an NTLM authentication version of an urllib3 connection pool + """ + + scheme = 'https' + + def __init__(self, user, pw, authurl, *args, **kwargs): + """ + authurl is a random URL on the server that is protected by NTLM. + user is the Windows user, probably in the DOMAIN\\username format. + pw is the password for the user. + """ + super(NTLMConnectionPool, self).__init__(*args, **kwargs) + self.authurl = authurl + self.rawuser = user + user_parts = user.split('\\', 1) + self.domain = user_parts[0].upper() + self.user = user_parts[1] + self.pw = pw + + def _new_conn(self): + # Performs the NTLM handshake that secures the connection. The socket + # must be kept open while requests are performed. + self.num_connections += 1 + log.debug('Starting NTLM HTTPS connection no. %d: https://%s%s', + self.num_connections, self.host, self.authurl) + + headers = {} + headers['Connection'] = 'Keep-Alive' + req_header = 'Authorization' + resp_header = 'www-authenticate' + + conn = HTTPSConnection(host=self.host, port=self.port) + + # Send negotiation message + headers[req_header] = ( + 'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(self.rawuser)) + log.debug('Request headers: %s', headers) + conn.request('GET', self.authurl, None, headers) + res = conn.getresponse() + reshdr = dict(res.getheaders()) + log.debug('Response status: %s %s', res.status, res.reason) + log.debug('Response headers: %s', reshdr) + log.debug('Response data: %s [...]', res.read(100)) + + # Remove the reference to the socket, so that it can not be closed by + # the response object (we want to keep the socket open) + res.fp = None + + # Server should respond with a challenge message + auth_header_values = reshdr[resp_header].split(', ') + auth_header_value = None + for s in auth_header_values: + if s[:5] == 'NTLM ': + auth_header_value = s[5:] + if auth_header_value is None: + raise Exception('Unexpected %s response header: %s' % + (resp_header, reshdr[resp_header])) + + # Send authentication message + ServerChallenge, NegotiateFlags = \ + ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value) + auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge, + self.user, + self.domain, + self.pw, + NegotiateFlags) + headers[req_header] = 'NTLM %s' % auth_msg + log.debug('Request headers: %s', headers) + conn.request('GET', self.authurl, None, headers) + res = conn.getresponse() + log.debug('Response status: %s %s', res.status, res.reason) + log.debug('Response headers: %s', dict(res.getheaders())) + log.debug('Response data: %s [...]', res.read()[:100]) + if res.status != 200: + if res.status == 401: + raise Exception('Server rejected request: wrong ' + 'username or password') + raise Exception('Wrong server response: %s %s' % + (res.status, res.reason)) + + res.fp = None + log.debug('Connection established') + return conn + + def urlopen(self, method, url, body=None, headers=None, retries=3, + redirect=True, assert_same_host=True): + if headers is None: + headers = {} + headers['Connection'] = 'Keep-Alive' + return super(NTLMConnectionPool, self).urlopen(method, url, body, + headers, retries, + redirect, + assert_same_host) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/pyopenssl.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/pyopenssl.py new file mode 100644 index 0000000..1bb3787 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/pyopenssl.py @@ -0,0 +1,455 @@ +""" +SSL with SNI_-support for Python 2. Follow these instructions if you would +like to verify SSL certificates in Python 2. Note, the default libraries do +*not* do certificate checking; you need to do additional work to validate +certificates yourself. + +This needs the following packages installed: + +* pyOpenSSL (tested with 16.0.0) +* cryptography (minimum 1.3.4, from pyopenssl) +* idna (minimum 2.0, from cryptography) + +However, pyopenssl depends on cryptography, which depends on idna, so while we +use all three directly here we end up having relatively few packages required. + +You can install them with the following command: + + pip install pyopenssl cryptography idna + +To activate certificate checking, call +:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code +before you begin making HTTP requests. This can be done in a ``sitecustomize`` +module, or at any other time before your application begins using ``urllib3``, +like this:: + + try: + import urllib3.contrib.pyopenssl + urllib3.contrib.pyopenssl.inject_into_urllib3() + except ImportError: + pass + +Now you can use :mod:`urllib3` as you normally would, and it will support SNI +when the required modules are installed. + +Activating this module also has the positive side effect of disabling SSL/TLS +compression in Python 2 (see `CRIME attack`_). + +If you want to configure the default list of supported cipher suites, you can +set the ``urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST`` variable. + +.. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication +.. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit) +""" +from __future__ import absolute_import + +import OpenSSL.SSL +from cryptography import x509 +from cryptography.hazmat.backends.openssl import backend as openssl_backend +from cryptography.hazmat.backends.openssl.x509 import _Certificate + +from socket import timeout, error as SocketError +from io import BytesIO + +try: # Platform-specific: Python 2 + from socket import _fileobject +except ImportError: # Platform-specific: Python 3 + _fileobject = None + from ..packages.backports.makefile import backport_makefile + +import logging +import ssl +from ..packages import six +import sys + +from .. import util + +__all__ = ['inject_into_urllib3', 'extract_from_urllib3'] + +# SNI always works. +HAS_SNI = True + +# Map from urllib3 to PyOpenSSL compatible parameter-values. +_openssl_versions = { + ssl.PROTOCOL_SSLv23: OpenSSL.SSL.SSLv23_METHOD, + ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD, +} + +if hasattr(ssl, 'PROTOCOL_TLSv1_1') and hasattr(OpenSSL.SSL, 'TLSv1_1_METHOD'): + _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD + +if hasattr(ssl, 'PROTOCOL_TLSv1_2') and hasattr(OpenSSL.SSL, 'TLSv1_2_METHOD'): + _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD + +try: + _openssl_versions.update({ssl.PROTOCOL_SSLv3: OpenSSL.SSL.SSLv3_METHOD}) +except AttributeError: + pass + +_stdlib_to_openssl_verify = { + ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE, + ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER, + ssl.CERT_REQUIRED: + OpenSSL.SSL.VERIFY_PEER + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT, +} +_openssl_to_stdlib_verify = dict( + (v, k) for k, v in _stdlib_to_openssl_verify.items() +) + +# OpenSSL will only write 16K at a time +SSL_WRITE_BLOCKSIZE = 16384 + +orig_util_HAS_SNI = util.HAS_SNI +orig_util_SSLContext = util.ssl_.SSLContext + + +log = logging.getLogger(__name__) + + +def inject_into_urllib3(): + 'Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.' + + _validate_dependencies_met() + + util.ssl_.SSLContext = PyOpenSSLContext + util.HAS_SNI = HAS_SNI + util.ssl_.HAS_SNI = HAS_SNI + util.IS_PYOPENSSL = True + util.ssl_.IS_PYOPENSSL = True + + +def extract_from_urllib3(): + 'Undo monkey-patching by :func:`inject_into_urllib3`.' + + util.ssl_.SSLContext = orig_util_SSLContext + util.HAS_SNI = orig_util_HAS_SNI + util.ssl_.HAS_SNI = orig_util_HAS_SNI + util.IS_PYOPENSSL = False + util.ssl_.IS_PYOPENSSL = False + + +def _validate_dependencies_met(): + """ + Verifies that PyOpenSSL's package-level dependencies have been met. + Throws `ImportError` if they are not met. + """ + # Method added in `cryptography==1.1`; not available in older versions + from cryptography.x509.extensions import Extensions + if getattr(Extensions, "get_extension_for_class", None) is None: + raise ImportError("'cryptography' module missing required functionality. " + "Try upgrading to v1.3.4 or newer.") + + # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509 + # attribute is only present on those versions. + from OpenSSL.crypto import X509 + x509 = X509() + if getattr(x509, "_x509", None) is None: + raise ImportError("'pyOpenSSL' module missing required functionality. " + "Try upgrading to v0.14 or newer.") + + +def _dnsname_to_stdlib(name): + """ + Converts a dNSName SubjectAlternativeName field to the form used by the + standard library on the given Python version. + + Cryptography produces a dNSName as a unicode string that was idna-decoded + from ASCII bytes. We need to idna-encode that string to get it back, and + then on Python 3 we also need to convert to unicode via UTF-8 (the stdlib + uses PyUnicode_FromStringAndSize on it, which decodes via UTF-8). + """ + def idna_encode(name): + """ + Borrowed wholesale from the Python Cryptography Project. It turns out + that we can't just safely call `idna.encode`: it can explode for + wildcard names. This avoids that problem. + """ + from pip._vendor import idna + + for prefix in [u'*.', u'.']: + if name.startswith(prefix): + name = name[len(prefix):] + return prefix.encode('ascii') + idna.encode(name) + return idna.encode(name) + + name = idna_encode(name) + if sys.version_info >= (3, 0): + name = name.decode('utf-8') + return name + + +def get_subj_alt_name(peer_cert): + """ + Given an PyOpenSSL certificate, provides all the subject alternative names. + """ + # Pass the cert to cryptography, which has much better APIs for this. + if hasattr(peer_cert, "to_cryptography"): + cert = peer_cert.to_cryptography() + else: + # This is technically using private APIs, but should work across all + # relevant versions before PyOpenSSL got a proper API for this. + cert = _Certificate(openssl_backend, peer_cert._x509) + + # We want to find the SAN extension. Ask Cryptography to locate it (it's + # faster than looping in Python) + try: + ext = cert.extensions.get_extension_for_class( + x509.SubjectAlternativeName + ).value + except x509.ExtensionNotFound: + # No such extension, return the empty list. + return [] + except (x509.DuplicateExtension, x509.UnsupportedExtension, + x509.UnsupportedGeneralNameType, UnicodeError) as e: + # A problem has been found with the quality of the certificate. Assume + # no SAN field is present. + log.warning( + "A problem was encountered with the certificate that prevented " + "urllib3 from finding the SubjectAlternativeName field. This can " + "affect certificate validation. The error was %s", + e, + ) + return [] + + # We want to return dNSName and iPAddress fields. We need to cast the IPs + # back to strings because the match_hostname function wants them as + # strings. + # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8 + # decoded. This is pretty frustrating, but that's what the standard library + # does with certificates, and so we need to attempt to do the same. + names = [ + ('DNS', _dnsname_to_stdlib(name)) + for name in ext.get_values_for_type(x509.DNSName) + ] + names.extend( + ('IP Address', str(name)) + for name in ext.get_values_for_type(x509.IPAddress) + ) + + return names + + +class WrappedSocket(object): + '''API-compatibility wrapper for Python OpenSSL's Connection-class. + + Note: _makefile_refs, _drop() and _reuse() are needed for the garbage + collector of pypy. + ''' + + def __init__(self, connection, socket, suppress_ragged_eofs=True): + self.connection = connection + self.socket = socket + self.suppress_ragged_eofs = suppress_ragged_eofs + self._makefile_refs = 0 + self._closed = False + + def fileno(self): + return self.socket.fileno() + + # Copy-pasted from Python 3.5 source code + def _decref_socketios(self): + if self._makefile_refs > 0: + self._makefile_refs -= 1 + if self._closed: + self.close() + + def recv(self, *args, **kwargs): + try: + data = self.connection.recv(*args, **kwargs) + except OpenSSL.SSL.SysCallError as e: + if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'): + return b'' + else: + raise SocketError(str(e)) + except OpenSSL.SSL.ZeroReturnError as e: + if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: + return b'' + else: + raise + except OpenSSL.SSL.WantReadError: + rd = util.wait_for_read(self.socket, self.socket.gettimeout()) + if not rd: + raise timeout('The read operation timed out') + else: + return self.recv(*args, **kwargs) + else: + return data + + def recv_into(self, *args, **kwargs): + try: + return self.connection.recv_into(*args, **kwargs) + except OpenSSL.SSL.SysCallError as e: + if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'): + return 0 + else: + raise SocketError(str(e)) + except OpenSSL.SSL.ZeroReturnError as e: + if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: + return 0 + else: + raise + except OpenSSL.SSL.WantReadError: + rd = util.wait_for_read(self.socket, self.socket.gettimeout()) + if not rd: + raise timeout('The read operation timed out') + else: + return self.recv_into(*args, **kwargs) + + def settimeout(self, timeout): + return self.socket.settimeout(timeout) + + def _send_until_done(self, data): + while True: + try: + return self.connection.send(data) + except OpenSSL.SSL.WantWriteError: + wr = util.wait_for_write(self.socket, self.socket.gettimeout()) + if not wr: + raise timeout() + continue + except OpenSSL.SSL.SysCallError as e: + raise SocketError(str(e)) + + def sendall(self, data): + total_sent = 0 + while total_sent < len(data): + sent = self._send_until_done(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE]) + total_sent += sent + + def shutdown(self): + # FIXME rethrow compatible exceptions should we ever use this + self.connection.shutdown() + + def close(self): + if self._makefile_refs < 1: + try: + self._closed = True + return self.connection.close() + except OpenSSL.SSL.Error: + return + else: + self._makefile_refs -= 1 + + def getpeercert(self, binary_form=False): + x509 = self.connection.get_peer_certificate() + + if not x509: + return x509 + + if binary_form: + return OpenSSL.crypto.dump_certificate( + OpenSSL.crypto.FILETYPE_ASN1, + x509) + + return { + 'subject': ( + (('commonName', x509.get_subject().CN),), + ), + 'subjectAltName': get_subj_alt_name(x509) + } + + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + + +if _fileobject: # Platform-specific: Python 2 + def makefile(self, mode, bufsize=-1): + self._makefile_refs += 1 + return _fileobject(self, mode, bufsize, close=True) +else: # Platform-specific: Python 3 + makefile = backport_makefile + +WrappedSocket.makefile = makefile + + +class PyOpenSSLContext(object): + """ + I am a wrapper class for the PyOpenSSL ``Context`` object. I am responsible + for translating the interface of the standard library ``SSLContext`` object + to calls into PyOpenSSL. + """ + def __init__(self, protocol): + self.protocol = _openssl_versions[protocol] + self._ctx = OpenSSL.SSL.Context(self.protocol) + self._options = 0 + self.check_hostname = False + + @property + def options(self): + return self._options + + @options.setter + def options(self, value): + self._options = value + self._ctx.set_options(value) + + @property + def verify_mode(self): + return _openssl_to_stdlib_verify[self._ctx.get_verify_mode()] + + @verify_mode.setter + def verify_mode(self, value): + self._ctx.set_verify( + _stdlib_to_openssl_verify[value], + _verify_callback + ) + + def set_default_verify_paths(self): + self._ctx.set_default_verify_paths() + + def set_ciphers(self, ciphers): + if isinstance(ciphers, six.text_type): + ciphers = ciphers.encode('utf-8') + self._ctx.set_cipher_list(ciphers) + + def load_verify_locations(self, cafile=None, capath=None, cadata=None): + if cafile is not None: + cafile = cafile.encode('utf-8') + if capath is not None: + capath = capath.encode('utf-8') + self._ctx.load_verify_locations(cafile, capath) + if cadata is not None: + self._ctx.load_verify_locations(BytesIO(cadata)) + + def load_cert_chain(self, certfile, keyfile=None, password=None): + self._ctx.use_certificate_file(certfile) + if password is not None: + self._ctx.set_passwd_cb(lambda max_length, prompt_twice, userdata: password) + self._ctx.use_privatekey_file(keyfile or certfile) + + def wrap_socket(self, sock, server_side=False, + do_handshake_on_connect=True, suppress_ragged_eofs=True, + server_hostname=None): + cnx = OpenSSL.SSL.Connection(self._ctx, sock) + + if isinstance(server_hostname, six.text_type): # Platform-specific: Python 3 + server_hostname = server_hostname.encode('utf-8') + + if server_hostname is not None: + cnx.set_tlsext_host_name(server_hostname) + + cnx.set_connect_state() + + while True: + try: + cnx.do_handshake() + except OpenSSL.SSL.WantReadError: + rd = util.wait_for_read(sock, sock.gettimeout()) + if not rd: + raise timeout('select timed out') + continue + except OpenSSL.SSL.Error as e: + raise ssl.SSLError('bad handshake: %r' % e) + break + + return WrappedSocket(cnx, sock) + + +def _verify_callback(cnx, x509, err_no, err_depth, return_code): + return err_no == 0 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/securetransport.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/securetransport.py new file mode 100644 index 0000000..2cac70f --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/securetransport.py @@ -0,0 +1,810 @@ +""" +SecureTranport support for urllib3 via ctypes. + +This makes platform-native TLS available to urllib3 users on macOS without the +use of a compiler. This is an important feature because the Python Package +Index is moving to become a TLSv1.2-or-higher server, and the default OpenSSL +that ships with macOS is not capable of doing TLSv1.2. The only way to resolve +this is to give macOS users an alternative solution to the problem, and that +solution is to use SecureTransport. + +We use ctypes here because this solution must not require a compiler. That's +because pip is not allowed to require a compiler either. + +This is not intended to be a seriously long-term solution to this problem. +The hope is that PEP 543 will eventually solve this issue for us, at which +point we can retire this contrib module. But in the short term, we need to +solve the impending tire fire that is Python on Mac without this kind of +contrib module. So...here we are. + +To use this module, simply import and inject it:: + + import urllib3.contrib.securetransport + urllib3.contrib.securetransport.inject_into_urllib3() + +Happy TLSing! +""" +from __future__ import absolute_import + +import contextlib +import ctypes +import errno +import os.path +import shutil +import socket +import ssl +import threading +import weakref + +from .. import util +from ._securetransport.bindings import ( + Security, SecurityConst, CoreFoundation +) +from ._securetransport.low_level import ( + _assert_no_error, _cert_array_from_pem, _temporary_keychain, + _load_client_cert_chain +) + +try: # Platform-specific: Python 2 + from socket import _fileobject +except ImportError: # Platform-specific: Python 3 + _fileobject = None + from ..packages.backports.makefile import backport_makefile + +try: + memoryview(b'') +except NameError: + raise ImportError("SecureTransport only works on Pythons with memoryview") + +__all__ = ['inject_into_urllib3', 'extract_from_urllib3'] + +# SNI always works +HAS_SNI = True + +orig_util_HAS_SNI = util.HAS_SNI +orig_util_SSLContext = util.ssl_.SSLContext + +# This dictionary is used by the read callback to obtain a handle to the +# calling wrapped socket. This is a pretty silly approach, but for now it'll +# do. I feel like I should be able to smuggle a handle to the wrapped socket +# directly in the SSLConnectionRef, but for now this approach will work I +# guess. +# +# We need to lock around this structure for inserts, but we don't do it for +# reads/writes in the callbacks. The reasoning here goes as follows: +# +# 1. It is not possible to call into the callbacks before the dictionary is +# populated, so once in the callback the id must be in the dictionary. +# 2. The callbacks don't mutate the dictionary, they only read from it, and +# so cannot conflict with any of the insertions. +# +# This is good: if we had to lock in the callbacks we'd drastically slow down +# the performance of this code. +_connection_refs = weakref.WeakValueDictionary() +_connection_ref_lock = threading.Lock() + +# Limit writes to 16kB. This is OpenSSL's limit, but we'll cargo-cult it over +# for no better reason than we need *a* limit, and this one is right there. +SSL_WRITE_BLOCKSIZE = 16384 + +# This is our equivalent of util.ssl_.DEFAULT_CIPHERS, but expanded out to +# individual cipher suites. We need to do this becuase this is how +# SecureTransport wants them. +CIPHER_SUITES = [ + SecurityConst.TLS_AES_256_GCM_SHA384, + SecurityConst.TLS_CHACHA20_POLY1305_SHA256, + SecurityConst.TLS_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA, +] + +# Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of +# TLSv1 and a high of TLSv1.2. For everything else, we pin to that version. +_protocol_to_min_max = { + ssl.PROTOCOL_SSLv23: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12), +} + +if hasattr(ssl, "PROTOCOL_SSLv2"): + _protocol_to_min_max[ssl.PROTOCOL_SSLv2] = ( + SecurityConst.kSSLProtocol2, SecurityConst.kSSLProtocol2 + ) +if hasattr(ssl, "PROTOCOL_SSLv3"): + _protocol_to_min_max[ssl.PROTOCOL_SSLv3] = ( + SecurityConst.kSSLProtocol3, SecurityConst.kSSLProtocol3 + ) +if hasattr(ssl, "PROTOCOL_TLSv1"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1] = ( + SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol1 + ) +if hasattr(ssl, "PROTOCOL_TLSv1_1"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1_1] = ( + SecurityConst.kTLSProtocol11, SecurityConst.kTLSProtocol11 + ) +if hasattr(ssl, "PROTOCOL_TLSv1_2"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1_2] = ( + SecurityConst.kTLSProtocol12, SecurityConst.kTLSProtocol12 + ) +if hasattr(ssl, "PROTOCOL_TLS"): + _protocol_to_min_max[ssl.PROTOCOL_TLS] = _protocol_to_min_max[ssl.PROTOCOL_SSLv23] + + +def inject_into_urllib3(): + """ + Monkey-patch urllib3 with SecureTransport-backed SSL-support. + """ + util.ssl_.SSLContext = SecureTransportContext + util.HAS_SNI = HAS_SNI + util.ssl_.HAS_SNI = HAS_SNI + util.IS_SECURETRANSPORT = True + util.ssl_.IS_SECURETRANSPORT = True + + +def extract_from_urllib3(): + """ + Undo monkey-patching by :func:`inject_into_urllib3`. + """ + util.ssl_.SSLContext = orig_util_SSLContext + util.HAS_SNI = orig_util_HAS_SNI + util.ssl_.HAS_SNI = orig_util_HAS_SNI + util.IS_SECURETRANSPORT = False + util.ssl_.IS_SECURETRANSPORT = False + + +def _read_callback(connection_id, data_buffer, data_length_pointer): + """ + SecureTransport read callback. This is called by ST to request that data + be returned from the socket. + """ + wrapped_socket = None + try: + wrapped_socket = _connection_refs.get(connection_id) + if wrapped_socket is None: + return SecurityConst.errSSLInternal + base_socket = wrapped_socket.socket + + requested_length = data_length_pointer[0] + + timeout = wrapped_socket.gettimeout() + error = None + read_count = 0 + buffer = (ctypes.c_char * requested_length).from_address(data_buffer) + buffer_view = memoryview(buffer) + + try: + while read_count < requested_length: + if timeout is None or timeout >= 0: + readables = util.wait_for_read([base_socket], timeout) + if not readables: + raise socket.error(errno.EAGAIN, 'timed out') + + # We need to tell ctypes that we have a buffer that can be + # written to. Upsettingly, we do that like this: + chunk_size = base_socket.recv_into( + buffer_view[read_count:requested_length] + ) + read_count += chunk_size + if not chunk_size: + if not read_count: + return SecurityConst.errSSLClosedGraceful + break + except (socket.error) as e: + error = e.errno + + if error is not None and error != errno.EAGAIN: + if error == errno.ECONNRESET: + return SecurityConst.errSSLClosedAbort + raise + + data_length_pointer[0] = read_count + + if read_count != requested_length: + return SecurityConst.errSSLWouldBlock + + return 0 + except Exception as e: + if wrapped_socket is not None: + wrapped_socket._exception = e + return SecurityConst.errSSLInternal + + +def _write_callback(connection_id, data_buffer, data_length_pointer): + """ + SecureTransport write callback. This is called by ST to request that data + actually be sent on the network. + """ + wrapped_socket = None + try: + wrapped_socket = _connection_refs.get(connection_id) + if wrapped_socket is None: + return SecurityConst.errSSLInternal + base_socket = wrapped_socket.socket + + bytes_to_write = data_length_pointer[0] + data = ctypes.string_at(data_buffer, bytes_to_write) + + timeout = wrapped_socket.gettimeout() + error = None + sent = 0 + + try: + while sent < bytes_to_write: + if timeout is None or timeout >= 0: + writables = util.wait_for_write([base_socket], timeout) + if not writables: + raise socket.error(errno.EAGAIN, 'timed out') + chunk_sent = base_socket.send(data) + sent += chunk_sent + + # This has some needless copying here, but I'm not sure there's + # much value in optimising this data path. + data = data[chunk_sent:] + except (socket.error) as e: + error = e.errno + + if error is not None and error != errno.EAGAIN: + if error == errno.ECONNRESET: + return SecurityConst.errSSLClosedAbort + raise + + data_length_pointer[0] = sent + if sent != bytes_to_write: + return SecurityConst.errSSLWouldBlock + + return 0 + except Exception as e: + if wrapped_socket is not None: + wrapped_socket._exception = e + return SecurityConst.errSSLInternal + + +# We need to keep these two objects references alive: if they get GC'd while +# in use then SecureTransport could attempt to call a function that is in freed +# memory. That would be...uh...bad. Yeah, that's the word. Bad. +_read_callback_pointer = Security.SSLReadFunc(_read_callback) +_write_callback_pointer = Security.SSLWriteFunc(_write_callback) + + +class WrappedSocket(object): + """ + API-compatibility wrapper for Python's OpenSSL wrapped socket object. + + Note: _makefile_refs, _drop(), and _reuse() are needed for the garbage + collector of PyPy. + """ + def __init__(self, socket): + self.socket = socket + self.context = None + self._makefile_refs = 0 + self._closed = False + self._exception = None + self._keychain = None + self._keychain_dir = None + self._client_cert_chain = None + + # We save off the previously-configured timeout and then set it to + # zero. This is done because we use select and friends to handle the + # timeouts, but if we leave the timeout set on the lower socket then + # Python will "kindly" call select on that socket again for us. Avoid + # that by forcing the timeout to zero. + self._timeout = self.socket.gettimeout() + self.socket.settimeout(0) + + @contextlib.contextmanager + def _raise_on_error(self): + """ + A context manager that can be used to wrap calls that do I/O from + SecureTransport. If any of the I/O callbacks hit an exception, this + context manager will correctly propagate the exception after the fact. + This avoids silently swallowing those exceptions. + + It also correctly forces the socket closed. + """ + self._exception = None + + # We explicitly don't catch around this yield because in the unlikely + # event that an exception was hit in the block we don't want to swallow + # it. + yield + if self._exception is not None: + exception, self._exception = self._exception, None + self.close() + raise exception + + def _set_ciphers(self): + """ + Sets up the allowed ciphers. By default this matches the set in + util.ssl_.DEFAULT_CIPHERS, at least as supported by macOS. This is done + custom and doesn't allow changing at this time, mostly because parsing + OpenSSL cipher strings is going to be a freaking nightmare. + """ + ciphers = (Security.SSLCipherSuite * len(CIPHER_SUITES))(*CIPHER_SUITES) + result = Security.SSLSetEnabledCiphers( + self.context, ciphers, len(CIPHER_SUITES) + ) + _assert_no_error(result) + + def _custom_validate(self, verify, trust_bundle): + """ + Called when we have set custom validation. We do this in two cases: + first, when cert validation is entirely disabled; and second, when + using a custom trust DB. + """ + # If we disabled cert validation, just say: cool. + if not verify: + return + + # We want data in memory, so load it up. + if os.path.isfile(trust_bundle): + with open(trust_bundle, 'rb') as f: + trust_bundle = f.read() + + cert_array = None + trust = Security.SecTrustRef() + + try: + # Get a CFArray that contains the certs we want. + cert_array = _cert_array_from_pem(trust_bundle) + + # Ok, now the hard part. We want to get the SecTrustRef that ST has + # created for this connection, shove our CAs into it, tell ST to + # ignore everything else it knows, and then ask if it can build a + # chain. This is a buuuunch of code. + result = Security.SSLCopyPeerTrust( + self.context, ctypes.byref(trust) + ) + _assert_no_error(result) + if not trust: + raise ssl.SSLError("Failed to copy trust reference") + + result = Security.SecTrustSetAnchorCertificates(trust, cert_array) + _assert_no_error(result) + + result = Security.SecTrustSetAnchorCertificatesOnly(trust, True) + _assert_no_error(result) + + trust_result = Security.SecTrustResultType() + result = Security.SecTrustEvaluate( + trust, ctypes.byref(trust_result) + ) + _assert_no_error(result) + finally: + if trust: + CoreFoundation.CFRelease(trust) + + if cert_array is None: + CoreFoundation.CFRelease(cert_array) + + # Ok, now we can look at what the result was. + successes = ( + SecurityConst.kSecTrustResultUnspecified, + SecurityConst.kSecTrustResultProceed + ) + if trust_result.value not in successes: + raise ssl.SSLError( + "certificate verify failed, error code: %d" % + trust_result.value + ) + + def handshake(self, + server_hostname, + verify, + trust_bundle, + min_version, + max_version, + client_cert, + client_key, + client_key_passphrase): + """ + Actually performs the TLS handshake. This is run automatically by + wrapped socket, and shouldn't be needed in user code. + """ + # First, we do the initial bits of connection setup. We need to create + # a context, set its I/O funcs, and set the connection reference. + self.context = Security.SSLCreateContext( + None, SecurityConst.kSSLClientSide, SecurityConst.kSSLStreamType + ) + result = Security.SSLSetIOFuncs( + self.context, _read_callback_pointer, _write_callback_pointer + ) + _assert_no_error(result) + + # Here we need to compute the handle to use. We do this by taking the + # id of self modulo 2**31 - 1. If this is already in the dictionary, we + # just keep incrementing by one until we find a free space. + with _connection_ref_lock: + handle = id(self) % 2147483647 + while handle in _connection_refs: + handle = (handle + 1) % 2147483647 + _connection_refs[handle] = self + + result = Security.SSLSetConnection(self.context, handle) + _assert_no_error(result) + + # If we have a server hostname, we should set that too. + if server_hostname: + if not isinstance(server_hostname, bytes): + server_hostname = server_hostname.encode('utf-8') + + result = Security.SSLSetPeerDomainName( + self.context, server_hostname, len(server_hostname) + ) + _assert_no_error(result) + + # Setup the ciphers. + self._set_ciphers() + + # Set the minimum and maximum TLS versions. + result = Security.SSLSetProtocolVersionMin(self.context, min_version) + _assert_no_error(result) + result = Security.SSLSetProtocolVersionMax(self.context, max_version) + _assert_no_error(result) + + # If there's a trust DB, we need to use it. We do that by telling + # SecureTransport to break on server auth. We also do that if we don't + # want to validate the certs at all: we just won't actually do any + # authing in that case. + if not verify or trust_bundle is not None: + result = Security.SSLSetSessionOption( + self.context, + SecurityConst.kSSLSessionOptionBreakOnServerAuth, + True + ) + _assert_no_error(result) + + # If there's a client cert, we need to use it. + if client_cert: + self._keychain, self._keychain_dir = _temporary_keychain() + self._client_cert_chain = _load_client_cert_chain( + self._keychain, client_cert, client_key + ) + result = Security.SSLSetCertificate( + self.context, self._client_cert_chain + ) + _assert_no_error(result) + + while True: + with self._raise_on_error(): + result = Security.SSLHandshake(self.context) + + if result == SecurityConst.errSSLWouldBlock: + raise socket.timeout("handshake timed out") + elif result == SecurityConst.errSSLServerAuthCompleted: + self._custom_validate(verify, trust_bundle) + continue + else: + _assert_no_error(result) + break + + def fileno(self): + return self.socket.fileno() + + # Copy-pasted from Python 3.5 source code + def _decref_socketios(self): + if self._makefile_refs > 0: + self._makefile_refs -= 1 + if self._closed: + self.close() + + def recv(self, bufsiz): + buffer = ctypes.create_string_buffer(bufsiz) + bytes_read = self.recv_into(buffer, bufsiz) + data = buffer[:bytes_read] + return data + + def recv_into(self, buffer, nbytes=None): + # Read short on EOF. + if self._closed: + return 0 + + if nbytes is None: + nbytes = len(buffer) + + buffer = (ctypes.c_char * nbytes).from_buffer(buffer) + processed_bytes = ctypes.c_size_t(0) + + with self._raise_on_error(): + result = Security.SSLRead( + self.context, buffer, nbytes, ctypes.byref(processed_bytes) + ) + + # There are some result codes that we want to treat as "not always + # errors". Specifically, those are errSSLWouldBlock, + # errSSLClosedGraceful, and errSSLClosedNoNotify. + if (result == SecurityConst.errSSLWouldBlock): + # If we didn't process any bytes, then this was just a time out. + # However, we can get errSSLWouldBlock in situations when we *did* + # read some data, and in those cases we should just read "short" + # and return. + if processed_bytes.value == 0: + # Timed out, no data read. + raise socket.timeout("recv timed out") + elif result in (SecurityConst.errSSLClosedGraceful, SecurityConst.errSSLClosedNoNotify): + # The remote peer has closed this connection. We should do so as + # well. Note that we don't actually return here because in + # principle this could actually be fired along with return data. + # It's unlikely though. + self.close() + else: + _assert_no_error(result) + + # Ok, we read and probably succeeded. We should return whatever data + # was actually read. + return processed_bytes.value + + def settimeout(self, timeout): + self._timeout = timeout + + def gettimeout(self): + return self._timeout + + def send(self, data): + processed_bytes = ctypes.c_size_t(0) + + with self._raise_on_error(): + result = Security.SSLWrite( + self.context, data, len(data), ctypes.byref(processed_bytes) + ) + + if result == SecurityConst.errSSLWouldBlock and processed_bytes.value == 0: + # Timed out + raise socket.timeout("send timed out") + else: + _assert_no_error(result) + + # We sent, and probably succeeded. Tell them how much we sent. + return processed_bytes.value + + def sendall(self, data): + total_sent = 0 + while total_sent < len(data): + sent = self.send(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE]) + total_sent += sent + + def shutdown(self): + with self._raise_on_error(): + Security.SSLClose(self.context) + + def close(self): + # TODO: should I do clean shutdown here? Do I have to? + if self._makefile_refs < 1: + self._closed = True + if self.context: + CoreFoundation.CFRelease(self.context) + self.context = None + if self._client_cert_chain: + CoreFoundation.CFRelease(self._client_cert_chain) + self._client_cert_chain = None + if self._keychain: + Security.SecKeychainDelete(self._keychain) + CoreFoundation.CFRelease(self._keychain) + shutil.rmtree(self._keychain_dir) + self._keychain = self._keychain_dir = None + return self.socket.close() + else: + self._makefile_refs -= 1 + + def getpeercert(self, binary_form=False): + # Urgh, annoying. + # + # Here's how we do this: + # + # 1. Call SSLCopyPeerTrust to get hold of the trust object for this + # connection. + # 2. Call SecTrustGetCertificateAtIndex for index 0 to get the leaf. + # 3. To get the CN, call SecCertificateCopyCommonName and process that + # string so that it's of the appropriate type. + # 4. To get the SAN, we need to do something a bit more complex: + # a. Call SecCertificateCopyValues to get the data, requesting + # kSecOIDSubjectAltName. + # b. Mess about with this dictionary to try to get the SANs out. + # + # This is gross. Really gross. It's going to be a few hundred LoC extra + # just to repeat something that SecureTransport can *already do*. So my + # operating assumption at this time is that what we want to do is + # instead to just flag to urllib3 that it shouldn't do its own hostname + # validation when using SecureTransport. + if not binary_form: + raise ValueError( + "SecureTransport only supports dumping binary certs" + ) + trust = Security.SecTrustRef() + certdata = None + der_bytes = None + + try: + # Grab the trust store. + result = Security.SSLCopyPeerTrust( + self.context, ctypes.byref(trust) + ) + _assert_no_error(result) + if not trust: + # Probably we haven't done the handshake yet. No biggie. + return None + + cert_count = Security.SecTrustGetCertificateCount(trust) + if not cert_count: + # Also a case that might happen if we haven't handshaked. + # Handshook? Handshaken? + return None + + leaf = Security.SecTrustGetCertificateAtIndex(trust, 0) + assert leaf + + # Ok, now we want the DER bytes. + certdata = Security.SecCertificateCopyData(leaf) + assert certdata + + data_length = CoreFoundation.CFDataGetLength(certdata) + data_buffer = CoreFoundation.CFDataGetBytePtr(certdata) + der_bytes = ctypes.string_at(data_buffer, data_length) + finally: + if certdata: + CoreFoundation.CFRelease(certdata) + if trust: + CoreFoundation.CFRelease(trust) + + return der_bytes + + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + + +if _fileobject: # Platform-specific: Python 2 + def makefile(self, mode, bufsize=-1): + self._makefile_refs += 1 + return _fileobject(self, mode, bufsize, close=True) +else: # Platform-specific: Python 3 + def makefile(self, mode="r", buffering=None, *args, **kwargs): + # We disable buffering with SecureTransport because it conflicts with + # the buffering that ST does internally (see issue #1153 for more). + buffering = 0 + return backport_makefile(self, mode, buffering, *args, **kwargs) + +WrappedSocket.makefile = makefile + + +class SecureTransportContext(object): + """ + I am a wrapper class for the SecureTransport library, to translate the + interface of the standard library ``SSLContext`` object to calls into + SecureTransport. + """ + def __init__(self, protocol): + self._min_version, self._max_version = _protocol_to_min_max[protocol] + self._options = 0 + self._verify = False + self._trust_bundle = None + self._client_cert = None + self._client_key = None + self._client_key_passphrase = None + + @property + def check_hostname(self): + """ + SecureTransport cannot have its hostname checking disabled. For more, + see the comment on getpeercert() in this file. + """ + return True + + @check_hostname.setter + def check_hostname(self, value): + """ + SecureTransport cannot have its hostname checking disabled. For more, + see the comment on getpeercert() in this file. + """ + pass + + @property + def options(self): + # TODO: Well, crap. + # + # So this is the bit of the code that is the most likely to cause us + # trouble. Essentially we need to enumerate all of the SSL options that + # users might want to use and try to see if we can sensibly translate + # them, or whether we should just ignore them. + return self._options + + @options.setter + def options(self, value): + # TODO: Update in line with above. + self._options = value + + @property + def verify_mode(self): + return ssl.CERT_REQUIRED if self._verify else ssl.CERT_NONE + + @verify_mode.setter + def verify_mode(self, value): + self._verify = True if value == ssl.CERT_REQUIRED else False + + def set_default_verify_paths(self): + # So, this has to do something a bit weird. Specifically, what it does + # is nothing. + # + # This means that, if we had previously had load_verify_locations + # called, this does not undo that. We need to do that because it turns + # out that the rest of the urllib3 code will attempt to load the + # default verify paths if it hasn't been told about any paths, even if + # the context itself was sometime earlier. We resolve that by just + # ignoring it. + pass + + def load_default_certs(self): + return self.set_default_verify_paths() + + def set_ciphers(self, ciphers): + # For now, we just require the default cipher string. + if ciphers != util.ssl_.DEFAULT_CIPHERS: + raise ValueError( + "SecureTransport doesn't support custom cipher strings" + ) + + def load_verify_locations(self, cafile=None, capath=None, cadata=None): + # OK, we only really support cadata and cafile. + if capath is not None: + raise ValueError( + "SecureTransport does not support cert directories" + ) + + self._trust_bundle = cafile or cadata + + def load_cert_chain(self, certfile, keyfile=None, password=None): + self._client_cert = certfile + self._client_key = keyfile + self._client_cert_passphrase = password + + def wrap_socket(self, sock, server_side=False, + do_handshake_on_connect=True, suppress_ragged_eofs=True, + server_hostname=None): + # So, what do we do here? Firstly, we assert some properties. This is a + # stripped down shim, so there is some functionality we don't support. + # See PEP 543 for the real deal. + assert not server_side + assert do_handshake_on_connect + assert suppress_ragged_eofs + + # Ok, we're good to go. Now we want to create the wrapped socket object + # and store it in the appropriate place. + wrapped_socket = WrappedSocket(sock) + + # Now we can handshake + wrapped_socket.handshake( + server_hostname, self._verify, self._trust_bundle, + self._min_version, self._max_version, self._client_cert, + self._client_key, self._client_key_passphrase + ) + return wrapped_socket diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/socks.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/socks.py new file mode 100644 index 0000000..39e92fd --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/socks.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- +""" +This module contains provisional support for SOCKS proxies from within +urllib3. This module supports SOCKS4 (specifically the SOCKS4A variant) and +SOCKS5. To enable its functionality, either install PySocks or install this +module with the ``socks`` extra. + +The SOCKS implementation supports the full range of urllib3 features. It also +supports the following SOCKS features: + +- SOCKS4 +- SOCKS4a +- SOCKS5 +- Usernames and passwords for the SOCKS proxy + +Known Limitations: + +- Currently PySocks does not support contacting remote websites via literal + IPv6 addresses. Any such connection attempt will fail. You must use a domain + name. +- Currently PySocks does not support IPv6 connections to the SOCKS proxy. Any + such connection attempt will fail. +""" +from __future__ import absolute_import + +try: + import socks +except ImportError: + import warnings + from ..exceptions import DependencyWarning + + warnings.warn(( + 'SOCKS support in urllib3 requires the installation of optional ' + 'dependencies: specifically, PySocks. For more information, see ' + 'https://urllib3.readthedocs.io/en/latest/contrib.html#socks-proxies' + ), + DependencyWarning + ) + raise + +from socket import error as SocketError, timeout as SocketTimeout + +from ..connection import ( + HTTPConnection, HTTPSConnection +) +from ..connectionpool import ( + HTTPConnectionPool, HTTPSConnectionPool +) +from ..exceptions import ConnectTimeoutError, NewConnectionError +from ..poolmanager import PoolManager +from ..util.url import parse_url + +try: + import ssl +except ImportError: + ssl = None + + +class SOCKSConnection(HTTPConnection): + """ + A plain-text HTTP connection that connects via a SOCKS proxy. + """ + def __init__(self, *args, **kwargs): + self._socks_options = kwargs.pop('_socks_options') + super(SOCKSConnection, self).__init__(*args, **kwargs) + + def _new_conn(self): + """ + Establish a new connection via the SOCKS proxy. + """ + extra_kw = {} + if self.source_address: + extra_kw['source_address'] = self.source_address + + if self.socket_options: + extra_kw['socket_options'] = self.socket_options + + try: + conn = socks.create_connection( + (self.host, self.port), + proxy_type=self._socks_options['socks_version'], + proxy_addr=self._socks_options['proxy_host'], + proxy_port=self._socks_options['proxy_port'], + proxy_username=self._socks_options['username'], + proxy_password=self._socks_options['password'], + proxy_rdns=self._socks_options['rdns'], + timeout=self.timeout, + **extra_kw + ) + + except SocketTimeout as e: + raise ConnectTimeoutError( + self, "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout)) + + except socks.ProxyError as e: + # This is fragile as hell, but it seems to be the only way to raise + # useful errors here. + if e.socket_err: + error = e.socket_err + if isinstance(error, SocketTimeout): + raise ConnectTimeoutError( + self, + "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout) + ) + else: + raise NewConnectionError( + self, + "Failed to establish a new connection: %s" % error + ) + else: + raise NewConnectionError( + self, + "Failed to establish a new connection: %s" % e + ) + + except SocketError as e: # Defensive: PySocks should catch all these. + raise NewConnectionError( + self, "Failed to establish a new connection: %s" % e) + + return conn + + +# We don't need to duplicate the Verified/Unverified distinction from +# urllib3/connection.py here because the HTTPSConnection will already have been +# correctly set to either the Verified or Unverified form by that module. This +# means the SOCKSHTTPSConnection will automatically be the correct type. +class SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection): + pass + + +class SOCKSHTTPConnectionPool(HTTPConnectionPool): + ConnectionCls = SOCKSConnection + + +class SOCKSHTTPSConnectionPool(HTTPSConnectionPool): + ConnectionCls = SOCKSHTTPSConnection + + +class SOCKSProxyManager(PoolManager): + """ + A version of the urllib3 ProxyManager that routes connections via the + defined SOCKS proxy. + """ + pool_classes_by_scheme = { + 'http': SOCKSHTTPConnectionPool, + 'https': SOCKSHTTPSConnectionPool, + } + + def __init__(self, proxy_url, username=None, password=None, + num_pools=10, headers=None, **connection_pool_kw): + parsed = parse_url(proxy_url) + + if parsed.scheme == 'socks5': + socks_version = socks.PROXY_TYPE_SOCKS5 + rdns = False + elif parsed.scheme == 'socks5h': + socks_version = socks.PROXY_TYPE_SOCKS5 + rdns = True + elif parsed.scheme == 'socks4': + socks_version = socks.PROXY_TYPE_SOCKS4 + rdns = False + elif parsed.scheme == 'socks4a': + socks_version = socks.PROXY_TYPE_SOCKS4 + rdns = True + else: + raise ValueError( + "Unable to determine SOCKS version from %s" % proxy_url + ) + + self.proxy_url = proxy_url + + socks_options = { + 'socks_version': socks_version, + 'proxy_host': parsed.host, + 'proxy_port': parsed.port, + 'username': username, + 'password': password, + 'rdns': rdns + } + connection_pool_kw['_socks_options'] = socks_options + + super(SOCKSProxyManager, self).__init__( + num_pools, headers, **connection_pool_kw + ) + + self.pool_classes_by_scheme = SOCKSProxyManager.pool_classes_by_scheme diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/exceptions.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/exceptions.py new file mode 100644 index 0000000..6c4be58 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/exceptions.py @@ -0,0 +1,246 @@ +from __future__ import absolute_import +from .packages.six.moves.http_client import ( + IncompleteRead as httplib_IncompleteRead +) +# Base Exceptions + + +class HTTPError(Exception): + "Base exception used by this module." + pass + + +class HTTPWarning(Warning): + "Base warning used by this module." + pass + + +class PoolError(HTTPError): + "Base exception for errors caused within a pool." + def __init__(self, pool, message): + self.pool = pool + HTTPError.__init__(self, "%s: %s" % (pool, message)) + + def __reduce__(self): + # For pickling purposes. + return self.__class__, (None, None) + + +class RequestError(PoolError): + "Base exception for PoolErrors that have associated URLs." + def __init__(self, pool, url, message): + self.url = url + PoolError.__init__(self, pool, message) + + def __reduce__(self): + # For pickling purposes. + return self.__class__, (None, self.url, None) + + +class SSLError(HTTPError): + "Raised when SSL certificate fails in an HTTPS connection." + pass + + +class ProxyError(HTTPError): + "Raised when the connection to a proxy fails." + pass + + +class DecodeError(HTTPError): + "Raised when automatic decoding based on Content-Type fails." + pass + + +class ProtocolError(HTTPError): + "Raised when something unexpected happens mid-request/response." + pass + + +#: Renamed to ProtocolError but aliased for backwards compatibility. +ConnectionError = ProtocolError + + +# Leaf Exceptions + +class MaxRetryError(RequestError): + """Raised when the maximum number of retries is exceeded. + + :param pool: The connection pool + :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool` + :param string url: The requested Url + :param exceptions.Exception reason: The underlying error + + """ + + def __init__(self, pool, url, reason=None): + self.reason = reason + + message = "Max retries exceeded with url: %s (Caused by %r)" % ( + url, reason) + + RequestError.__init__(self, pool, url, message) + + +class HostChangedError(RequestError): + "Raised when an existing pool gets a request for a foreign host." + + def __init__(self, pool, url, retries=3): + message = "Tried to open a foreign host with url: %s" % url + RequestError.__init__(self, pool, url, message) + self.retries = retries + + +class TimeoutStateError(HTTPError): + """ Raised when passing an invalid state to a timeout """ + pass + + +class TimeoutError(HTTPError): + """ Raised when a socket timeout error occurs. + + Catching this error will catch both :exc:`ReadTimeoutErrors + <ReadTimeoutError>` and :exc:`ConnectTimeoutErrors <ConnectTimeoutError>`. + """ + pass + + +class ReadTimeoutError(TimeoutError, RequestError): + "Raised when a socket timeout occurs while receiving data from a server" + pass + + +# This timeout error does not have a URL attached and needs to inherit from the +# base HTTPError +class ConnectTimeoutError(TimeoutError): + "Raised when a socket timeout occurs while connecting to a server" + pass + + +class NewConnectionError(ConnectTimeoutError, PoolError): + "Raised when we fail to establish a new connection. Usually ECONNREFUSED." + pass + + +class EmptyPoolError(PoolError): + "Raised when a pool runs out of connections and no more are allowed." + pass + + +class ClosedPoolError(PoolError): + "Raised when a request enters a pool after the pool has been closed." + pass + + +class LocationValueError(ValueError, HTTPError): + "Raised when there is something wrong with a given URL input." + pass + + +class LocationParseError(LocationValueError): + "Raised when get_host or similar fails to parse the URL input." + + def __init__(self, location): + message = "Failed to parse: %s" % location + HTTPError.__init__(self, message) + + self.location = location + + +class ResponseError(HTTPError): + "Used as a container for an error reason supplied in a MaxRetryError." + GENERIC_ERROR = 'too many error responses' + SPECIFIC_ERROR = 'too many {status_code} error responses' + + +class SecurityWarning(HTTPWarning): + "Warned when perfoming security reducing actions" + pass + + +class SubjectAltNameWarning(SecurityWarning): + "Warned when connecting to a host with a certificate missing a SAN." + pass + + +class InsecureRequestWarning(SecurityWarning): + "Warned when making an unverified HTTPS request." + pass + + +class SystemTimeWarning(SecurityWarning): + "Warned when system time is suspected to be wrong" + pass + + +class InsecurePlatformWarning(SecurityWarning): + "Warned when certain SSL configuration is not available on a platform." + pass + + +class SNIMissingWarning(HTTPWarning): + "Warned when making a HTTPS request without SNI available." + pass + + +class DependencyWarning(HTTPWarning): + """ + Warned when an attempt is made to import a module with missing optional + dependencies. + """ + pass + + +class ResponseNotChunked(ProtocolError, ValueError): + "Response needs to be chunked in order to read it as chunks." + pass + + +class BodyNotHttplibCompatible(HTTPError): + """ + Body should be httplib.HTTPResponse like (have an fp attribute which + returns raw chunks) for read_chunked(). + """ + pass + + +class IncompleteRead(HTTPError, httplib_IncompleteRead): + """ + Response length doesn't match expected Content-Length + + Subclass of http_client.IncompleteRead to allow int value + for `partial` to avoid creating large objects on streamed + reads. + """ + def __init__(self, partial, expected): + super(IncompleteRead, self).__init__(partial, expected) + + def __repr__(self): + return ('IncompleteRead(%i bytes read, ' + '%i more expected)' % (self.partial, self.expected)) + + +class InvalidHeader(HTTPError): + "The header provided was somehow invalid." + pass + + +class ProxySchemeUnknown(AssertionError, ValueError): + "ProxyManager does not support the supplied scheme" + # TODO(t-8ch): Stop inheriting from AssertionError in v2.0. + + def __init__(self, scheme): + message = "Not supported proxy scheme %s" % scheme + super(ProxySchemeUnknown, self).__init__(message) + + +class HeaderParsingError(HTTPError): + "Raised by assert_header_parsing, but we convert it to a log.warning statement." + def __init__(self, defects, unparsed_data): + message = '%s, unparsed data: %r' % (defects or 'Unknown', unparsed_data) + super(HeaderParsingError, self).__init__(message) + + +class UnrewindableBodyError(HTTPError): + "urllib3 encountered an error when trying to rewind a body" + pass diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/fields.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/fields.py new file mode 100644 index 0000000..19b0ae0 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/fields.py @@ -0,0 +1,178 @@ +from __future__ import absolute_import +import email.utils +import mimetypes + +from .packages import six + + +def guess_content_type(filename, default='application/octet-stream'): + """ + Guess the "Content-Type" of a file. + + :param filename: + The filename to guess the "Content-Type" of using :mod:`mimetypes`. + :param default: + If no "Content-Type" can be guessed, default to `default`. + """ + if filename: + return mimetypes.guess_type(filename)[0] or default + return default + + +def format_header_param(name, value): + """ + Helper function to format and quote a single header parameter. + + Particularly useful for header parameters which might contain + non-ASCII values, like file names. This follows RFC 2231, as + suggested by RFC 2388 Section 4.4. + + :param name: + The name of the parameter, a string expected to be ASCII only. + :param value: + The value of the parameter, provided as a unicode string. + """ + if not any(ch in value for ch in '"\\\r\n'): + result = '%s="%s"' % (name, value) + try: + result.encode('ascii') + except (UnicodeEncodeError, UnicodeDecodeError): + pass + else: + return result + if not six.PY3 and isinstance(value, six.text_type): # Python 2: + value = value.encode('utf-8') + value = email.utils.encode_rfc2231(value, 'utf-8') + value = '%s*=%s' % (name, value) + return value + + +class RequestField(object): + """ + A data container for request body parameters. + + :param name: + The name of this request field. + :param data: + The data/value body. + :param filename: + An optional filename of the request field. + :param headers: + An optional dict-like object of headers to initially use for the field. + """ + def __init__(self, name, data, filename=None, headers=None): + self._name = name + self._filename = filename + self.data = data + self.headers = {} + if headers: + self.headers = dict(headers) + + @classmethod + def from_tuples(cls, fieldname, value): + """ + A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters. + + Supports constructing :class:`~urllib3.fields.RequestField` from + parameter of key/value strings AND key/filetuple. A filetuple is a + (filename, data, MIME type) tuple where the MIME type is optional. + For example:: + + 'foo': 'bar', + 'fakefile': ('foofile.txt', 'contents of foofile'), + 'realfile': ('barfile.txt', open('realfile').read()), + 'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'), + 'nonamefile': 'contents of nonamefile field', + + Field names and filenames must be unicode. + """ + if isinstance(value, tuple): + if len(value) == 3: + filename, data, content_type = value + else: + filename, data = value + content_type = guess_content_type(filename) + else: + filename = None + content_type = None + data = value + + request_param = cls(fieldname, data, filename=filename) + request_param.make_multipart(content_type=content_type) + + return request_param + + def _render_part(self, name, value): + """ + Overridable helper function to format a single header parameter. + + :param name: + The name of the parameter, a string expected to be ASCII only. + :param value: + The value of the parameter, provided as a unicode string. + """ + return format_header_param(name, value) + + def _render_parts(self, header_parts): + """ + Helper function to format and quote a single header. + + Useful for single headers that are composed of multiple items. E.g., + 'Content-Disposition' fields. + + :param header_parts: + A sequence of (k, v) typles or a :class:`dict` of (k, v) to format + as `k1="v1"; k2="v2"; ...`. + """ + parts = [] + iterable = header_parts + if isinstance(header_parts, dict): + iterable = header_parts.items() + + for name, value in iterable: + if value is not None: + parts.append(self._render_part(name, value)) + + return '; '.join(parts) + + def render_headers(self): + """ + Renders the headers for this request field. + """ + lines = [] + + sort_keys = ['Content-Disposition', 'Content-Type', 'Content-Location'] + for sort_key in sort_keys: + if self.headers.get(sort_key, False): + lines.append('%s: %s' % (sort_key, self.headers[sort_key])) + + for header_name, header_value in self.headers.items(): + if header_name not in sort_keys: + if header_value: + lines.append('%s: %s' % (header_name, header_value)) + + lines.append('\r\n') + return '\r\n'.join(lines) + + def make_multipart(self, content_disposition=None, content_type=None, + content_location=None): + """ + Makes this request field into a multipart request field. + + This method overrides "Content-Disposition", "Content-Type" and + "Content-Location" headers to the request parameter. + + :param content_type: + The 'Content-Type' of the request body. + :param content_location: + The 'Content-Location' of the request body. + + """ + self.headers['Content-Disposition'] = content_disposition or 'form-data' + self.headers['Content-Disposition'] += '; '.join([ + '', self._render_parts( + (('name', self._name), ('filename', self._filename)) + ) + ]) + self.headers['Content-Type'] = content_type + self.headers['Content-Location'] = content_location diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/filepost.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/filepost.py new file mode 100644 index 0000000..cd11cee --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/filepost.py @@ -0,0 +1,94 @@ +from __future__ import absolute_import +import codecs + +from uuid import uuid4 +from io import BytesIO + +from .packages import six +from .packages.six import b +from .fields import RequestField + +writer = codecs.lookup('utf-8')[3] + + +def choose_boundary(): + """ + Our embarrassingly-simple replacement for mimetools.choose_boundary. + """ + return uuid4().hex + + +def iter_field_objects(fields): + """ + Iterate over fields. + + Supports list of (k, v) tuples and dicts, and lists of + :class:`~urllib3.fields.RequestField`. + + """ + if isinstance(fields, dict): + i = six.iteritems(fields) + else: + i = iter(fields) + + for field in i: + if isinstance(field, RequestField): + yield field + else: + yield RequestField.from_tuples(*field) + + +def iter_fields(fields): + """ + .. deprecated:: 1.6 + + Iterate over fields. + + The addition of :class:`~urllib3.fields.RequestField` makes this function + obsolete. Instead, use :func:`iter_field_objects`, which returns + :class:`~urllib3.fields.RequestField` objects. + + Supports list of (k, v) tuples and dicts. + """ + if isinstance(fields, dict): + return ((k, v) for k, v in six.iteritems(fields)) + + return ((k, v) for k, v in fields) + + +def encode_multipart_formdata(fields, boundary=None): + """ + Encode a dictionary of ``fields`` using the multipart/form-data MIME format. + + :param fields: + Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`). + + :param boundary: + If not specified, then a random boundary will be generated using + :func:`mimetools.choose_boundary`. + """ + body = BytesIO() + if boundary is None: + boundary = choose_boundary() + + for field in iter_field_objects(fields): + body.write(b('--%s\r\n' % (boundary))) + + writer(body).write(field.render_headers()) + data = field.data + + if isinstance(data, int): + data = str(data) # Backwards compatibility + + if isinstance(data, six.text_type): + writer(body).write(data) + else: + body.write(data) + + body.write(b'\r\n') + + body.write(b('--%s--\r\n' % (boundary))) + + content_type = str('multipart/form-data; boundary=%s' % boundary) + + return body.getvalue(), content_type diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/__init__.py new file mode 100644 index 0000000..170e974 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/__init__.py @@ -0,0 +1,5 @@ +from __future__ import absolute_import + +from . import ssl_match_hostname + +__all__ = ('ssl_match_hostname', ) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/backports/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/backports/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/backports/makefile.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/backports/makefile.py new file mode 100644 index 0000000..75b80dc --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/backports/makefile.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +""" +backports.makefile +~~~~~~~~~~~~~~~~~~ + +Backports the Python 3 ``socket.makefile`` method for use with anything that +wants to create a "fake" socket object. +""" +import io + +from socket import SocketIO + + +def backport_makefile(self, mode="r", buffering=None, encoding=None, + errors=None, newline=None): + """ + Backport of ``socket.makefile`` from Python 3.5. + """ + if not set(mode) <= set(["r", "w", "b"]): + raise ValueError( + "invalid mode %r (only r, w, b allowed)" % (mode,) + ) + writing = "w" in mode + reading = "r" in mode or not writing + assert reading or writing + binary = "b" in mode + rawmode = "" + if reading: + rawmode += "r" + if writing: + rawmode += "w" + raw = SocketIO(self, rawmode) + self._makefile_refs += 1 + if buffering is None: + buffering = -1 + if buffering < 0: + buffering = io.DEFAULT_BUFFER_SIZE + if buffering == 0: + if not binary: + raise ValueError("unbuffered streams must be binary") + return raw + if reading and writing: + buffer = io.BufferedRWPair(raw, raw, buffering) + elif reading: + buffer = io.BufferedReader(raw, buffering) + else: + assert writing + buffer = io.BufferedWriter(raw, buffering) + if binary: + return buffer + text = io.TextIOWrapper(buffer, encoding, errors, newline) + text.mode = mode + return text diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ordered_dict.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ordered_dict.py new file mode 100644 index 0000000..4479363 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ordered_dict.py @@ -0,0 +1,259 @@ +# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. +# Passes Python2.7's test suite and incorporates all the latest updates. +# Copyright 2009 Raymond Hettinger, released under the MIT License. +# http://code.activestate.com/recipes/576693/ +try: + from thread import get_ident as _get_ident +except ImportError: + from dummy_thread import get_ident as _get_ident + +try: + from _abcoll import KeysView, ValuesView, ItemsView +except ImportError: + pass + + +class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as for regular dictionaries. + + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link which goes at the end of the linked + # list, and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which is + # then removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, key = self.__map.pop(key) + link_prev[1] = link_next + link_next[0] = link_prev + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + root = self.__root + curr = root[1] + while curr is not root: + yield curr[2] + curr = curr[1] + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + root = self.__root + curr = root[0] + while curr is not root: + yield curr[2] + curr = curr[0] + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + try: + for node in self.__map.itervalues(): + del node[:] + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + except AttributeError: + pass + dict.clear(self) + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + root = self.__root + if last: + link = root[0] + link_prev = link[0] + link_prev[1] = root + root[0] = link_prev + else: + link = root[1] + link_next = link[1] + root[1] = link_next + link_next[0] = root + key = link[2] + del self.__map[key] + value = dict.pop(self, key) + return key, value + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) items in od' + for k in self: + yield (k, self[k]) + + def update(*args, **kwds): + '''od.update(E, **F) -> None. Update od from dict/iterable E and F. + + If E is a dict instance, does: for k in E: od[k] = E[k] + If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] + Or if E is an iterable of items, does: for k, v in E: od[k] = v + In either case, this is followed by: for k, v in F.items(): od[k] = v + + ''' + if len(args) > 2: + raise TypeError('update() takes at most 2 positional ' + 'arguments (%d given)' % (len(args),)) + elif not args: + raise TypeError('update() takes at least 1 argument (0 given)') + self = args[0] + # Make progressively weaker assumptions about "other" + other = () + if len(args) == 2: + other = args[1] + if isinstance(other, dict): + for key in other: + self[key] = other[key] + elif hasattr(other, 'keys'): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def __repr__(self, _repr_running={}): + 'od.__repr__() <==> repr(od)' + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other + + # -- the following methods are only used in Python 2.7 -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/six.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/six.py new file mode 100644 index 0000000..190c023 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/six.py @@ -0,0 +1,868 @@ +"""Utilities for writing code that runs on Python 2 and 3""" + +# Copyright (c) 2010-2015 Benjamin Peterson +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.10.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY34 = sys.version_info[0:2] >= (3, 4) + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + Required, if is_package is implemented""" + self.__get_module(fullname) # eventually raises ImportError + return None + get_source = get_code # same as get_code + +_importer = _SixMetaPathImporter(__name__) + + +class _MovedItems(_LazyModule): + + """Lazy loading of moved objects""" + __path__ = [] # mark as package + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("intern", "__builtin__", "sys"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), + MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + MovedAttribute("UserString", "UserString", "collections"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes + +_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", "moves.urllib.parse") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes + +_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", "moves.urllib.error") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes + +_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", "moves.urllib.request") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes + +_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", "moves.urllib.response") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes + +_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), + "moves.urllib_robotparser", "moves.urllib.robotparser") + + +class Module_six_moves_urllib(types.ModuleType): + + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + __path__ = [] # mark as package + parse = _importer._get_module("moves.urllib_parse") + error = _importer._get_module("moves.urllib_error") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +try: + callable = callable +except NameError: + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + def get_unbound_function(unbound): + return unbound + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + return types.MethodType(func, None, cls) + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") +_add_doc(itervalues, "Return an iterator over the values of a dictionary.") +_add_doc(iteritems, + "Return an iterator over the (key, value) pairs of a dictionary.") +_add_doc(iterlists, + "Return an iterator over the (key, [values]) pairs of a dictionary.") + + +if PY3: + def b(s): + return s.encode("latin-1") + + def u(s): + return s + unichr = chr + import struct + int2byte = struct.Struct(">B").pack + del struct + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter + import io + StringIO = io.StringIO + BytesIO = io.BytesIO + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" +else: + def b(s): + return s + # Workaround for standalone backslash + + def u(s): + return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + def reraise(tp, value, tb=None): + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + raise tp, value, tb +""") + + +if sys.version_info[:2] == (3, 2): + exec_("""def raise_from(value, from_value): + if from_value is None: + raise value + raise value from from_value +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + raise value from from_value +""") +else: + def raise_from(value, from_value): + raise value + + +print_ = getattr(moves.builtins, "print", None) +if print_ is None: + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + if (isinstance(fp, file) and + isinstance(data, unicode) and + fp.encoding is not None): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(fp.encoding, errors) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + if flush and fp is not None: + fp.flush() + +_add_doc(reraise, """Reraise an exception.""") + +if sys.version_info[0:2] < (3, 4): + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + def wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(meta): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) + + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + slots = orig_vars.get('__slots__') + if slots is not None: + if isinstance(slots, str): + slots = [slots] + for slots_var in slots: + orig_vars.pop(slots_var) + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def python_2_unicode_compatible(klass): + """ + A decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if PY2: + if '__str__' not in klass.__dict__: + raise ValueError("@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % + klass.__name__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # be floating around. Therefore, we can't use isinstance() to check for + # the six meta path importer, since the other six instance will have + # inserted an importer with different class. + if (type(importer).__name__ == "_SixMetaPathImporter" and + importer.name == __name__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py new file mode 100644 index 0000000..d6594eb --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py @@ -0,0 +1,19 @@ +import sys + +try: + # Our match_hostname function is the same as 3.5's, so we only want to + # import the match_hostname function if it's at least that good. + if sys.version_info < (3, 5): + raise ImportError("Fallback to vendored code") + + from ssl import CertificateError, match_hostname +except ImportError: + try: + # Backport of the function from a pypi module + from backports.ssl_match_hostname import CertificateError, match_hostname + except ImportError: + # Our vendored copy + from ._implementation import CertificateError, match_hostname + +# Not needed, but documenting what we provide. +__all__ = ('CertificateError', 'match_hostname') diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py new file mode 100644 index 0000000..92c9bc7 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py @@ -0,0 +1,157 @@ +"""The match_hostname() function from Python 3.3.3, essential when using SSL.""" + +# Note: This file is under the PSF license as the code comes from the python +# stdlib. http://docs.python.org/3/license.html + +import re +import sys + +# ipaddress has been backported to 2.6+ in pypi. If it is installed on the +# system, use it to handle IPAddress ServerAltnames (this was added in +# python-3.5) otherwise only do DNS matching. This allows +# backports.ssl_match_hostname to continue to be used all the way back to +# python-2.4. +try: + from pip._vendor import ipaddress +except ImportError: + ipaddress = None + +__version__ = '3.5.0.1' + + +class CertificateError(ValueError): + pass + + +def _dnsname_match(dn, hostname, max_wildcards=1): + """Matching according to RFC 6125, section 6.4.3 + + http://tools.ietf.org/html/rfc6125#section-6.4.3 + """ + pats = [] + if not dn: + return False + + # Ported from python3-syntax: + # leftmost, *remainder = dn.split(r'.') + parts = dn.split(r'.') + leftmost = parts[0] + remainder = parts[1:] + + wildcards = leftmost.count('*') + if wildcards > max_wildcards: + # Issue #17980: avoid denials of service by refusing more + # than one wildcard per fragment. A survey of established + # policy among SSL implementations showed it to be a + # reasonable choice. + raise CertificateError( + "too many wildcards in certificate DNS name: " + repr(dn)) + + # speed up common case w/o wildcards + if not wildcards: + return dn.lower() == hostname.lower() + + # RFC 6125, section 6.4.3, subitem 1. + # The client SHOULD NOT attempt to match a presented identifier in which + # the wildcard character comprises a label other than the left-most label. + if leftmost == '*': + # When '*' is a fragment by itself, it matches a non-empty dotless + # fragment. + pats.append('[^.]+') + elif leftmost.startswith('xn--') or hostname.startswith('xn--'): + # RFC 6125, section 6.4.3, subitem 3. + # The client SHOULD NOT attempt to match a presented identifier + # where the wildcard character is embedded within an A-label or + # U-label of an internationalized domain name. + pats.append(re.escape(leftmost)) + else: + # Otherwise, '*' matches any dotless string, e.g. www* + pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) + + # add the remaining fragments, ignore any wildcards + for frag in remainder: + pats.append(re.escape(frag)) + + pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) + return pat.match(hostname) + + +def _to_unicode(obj): + if isinstance(obj, str) and sys.version_info < (3,): + obj = unicode(obj, encoding='ascii', errors='strict') + return obj + +def _ipaddress_match(ipname, host_ip): + """Exact matching of IP addresses. + + RFC 6125 explicitly doesn't define an algorithm for this + (section 1.7.2 - "Out of Scope"). + """ + # OpenSSL may add a trailing newline to a subjectAltName's IP address + # Divergence from upstream: ipaddress can't handle byte str + ip = ipaddress.ip_address(_to_unicode(ipname).rstrip()) + return ip == host_ip + + +def match_hostname(cert, hostname): + """Verify that *cert* (in decoded format as returned by + SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 + rules are followed, but IP addresses are not accepted for *hostname*. + + CertificateError is raised on failure. On success, the function + returns nothing. + """ + if not cert: + raise ValueError("empty or no certificate, match_hostname needs a " + "SSL socket or SSL context with either " + "CERT_OPTIONAL or CERT_REQUIRED") + try: + # Divergence from upstream: ipaddress can't handle byte str + host_ip = ipaddress.ip_address(_to_unicode(hostname)) + except ValueError: + # Not an IP address (common case) + host_ip = None + except UnicodeError: + # Divergence from upstream: Have to deal with ipaddress not taking + # byte strings. addresses should be all ascii, so we consider it not + # an ipaddress in this case + host_ip = None + except AttributeError: + # Divergence from upstream: Make ipaddress library optional + if ipaddress is None: + host_ip = None + else: + raise + dnsnames = [] + san = cert.get('subjectAltName', ()) + for key, value in san: + if key == 'DNS': + if host_ip is None and _dnsname_match(value, hostname): + return + dnsnames.append(value) + elif key == 'IP Address': + if host_ip is not None and _ipaddress_match(value, host_ip): + return + dnsnames.append(value) + if not dnsnames: + # The subject is only checked when there is no dNSName entry + # in subjectAltName + for sub in cert.get('subject', ()): + for key, value in sub: + # XXX according to RFC 2818, the most specific Common Name + # must be used. + if key == 'commonName': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if len(dnsnames) > 1: + raise CertificateError("hostname %r " + "doesn't match either of %s" + % (hostname, ', '.join(map(repr, dnsnames)))) + elif len(dnsnames) == 1: + raise CertificateError("hostname %r " + "doesn't match %r" + % (hostname, dnsnames[0])) + else: + raise CertificateError("no appropriate commonName or " + "subjectAltName fields were found") diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/poolmanager.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/poolmanager.py new file mode 100644 index 0000000..4ae9174 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/poolmanager.py @@ -0,0 +1,440 @@ +from __future__ import absolute_import +import collections +import functools +import logging + +from ._collections import RecentlyUsedContainer +from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool +from .connectionpool import port_by_scheme +from .exceptions import LocationValueError, MaxRetryError, ProxySchemeUnknown +from .packages.six.moves.urllib.parse import urljoin +from .request import RequestMethods +from .util.url import parse_url +from .util.retry import Retry + + +__all__ = ['PoolManager', 'ProxyManager', 'proxy_from_url'] + + +log = logging.getLogger(__name__) + +SSL_KEYWORDS = ('key_file', 'cert_file', 'cert_reqs', 'ca_certs', + 'ssl_version', 'ca_cert_dir', 'ssl_context') + +# All known keyword arguments that could be provided to the pool manager, its +# pools, or the underlying connections. This is used to construct a pool key. +_key_fields = ( + 'key_scheme', # str + 'key_host', # str + 'key_port', # int + 'key_timeout', # int or float or Timeout + 'key_retries', # int or Retry + 'key_strict', # bool + 'key_block', # bool + 'key_source_address', # str + 'key_key_file', # str + 'key_cert_file', # str + 'key_cert_reqs', # str + 'key_ca_certs', # str + 'key_ssl_version', # str + 'key_ca_cert_dir', # str + 'key_ssl_context', # instance of ssl.SSLContext or urllib3.util.ssl_.SSLContext + 'key_maxsize', # int + 'key_headers', # dict + 'key__proxy', # parsed proxy url + 'key__proxy_headers', # dict + 'key_socket_options', # list of (level (int), optname (int), value (int or str)) tuples + 'key__socks_options', # dict + 'key_assert_hostname', # bool or string + 'key_assert_fingerprint', # str +) + +#: The namedtuple class used to construct keys for the connection pool. +#: All custom key schemes should include the fields in this key at a minimum. +PoolKey = collections.namedtuple('PoolKey', _key_fields) + + +def _default_key_normalizer(key_class, request_context): + """ + Create a pool key out of a request context dictionary. + + According to RFC 3986, both the scheme and host are case-insensitive. + Therefore, this function normalizes both before constructing the pool + key for an HTTPS request. If you wish to change this behaviour, provide + alternate callables to ``key_fn_by_scheme``. + + :param key_class: + The class to use when constructing the key. This should be a namedtuple + with the ``scheme`` and ``host`` keys at a minimum. + :type key_class: namedtuple + :param request_context: + A dictionary-like object that contain the context for a request. + :type request_context: dict + + :return: A namedtuple that can be used as a connection pool key. + :rtype: PoolKey + """ + # Since we mutate the dictionary, make a copy first + context = request_context.copy() + context['scheme'] = context['scheme'].lower() + context['host'] = context['host'].lower() + + # These are both dictionaries and need to be transformed into frozensets + for key in ('headers', '_proxy_headers', '_socks_options'): + if key in context and context[key] is not None: + context[key] = frozenset(context[key].items()) + + # The socket_options key may be a list and needs to be transformed into a + # tuple. + socket_opts = context.get('socket_options') + if socket_opts is not None: + context['socket_options'] = tuple(socket_opts) + + # Map the kwargs to the names in the namedtuple - this is necessary since + # namedtuples can't have fields starting with '_'. + for key in list(context.keys()): + context['key_' + key] = context.pop(key) + + # Default to ``None`` for keys missing from the context + for field in key_class._fields: + if field not in context: + context[field] = None + + return key_class(**context) + + +#: A dictionary that maps a scheme to a callable that creates a pool key. +#: This can be used to alter the way pool keys are constructed, if desired. +#: Each PoolManager makes a copy of this dictionary so they can be configured +#: globally here, or individually on the instance. +key_fn_by_scheme = { + 'http': functools.partial(_default_key_normalizer, PoolKey), + 'https': functools.partial(_default_key_normalizer, PoolKey), +} + +pool_classes_by_scheme = { + 'http': HTTPConnectionPool, + 'https': HTTPSConnectionPool, +} + + +class PoolManager(RequestMethods): + """ + Allows for arbitrary requests while transparently keeping track of + necessary connection pools for you. + + :param num_pools: + Number of connection pools to cache before discarding the least + recently used pool. + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + + :param \\**connection_pool_kw: + Additional parameters are used to create fresh + :class:`urllib3.connectionpool.ConnectionPool` instances. + + Example:: + + >>> manager = PoolManager(num_pools=2) + >>> r = manager.request('GET', 'http://google.com/') + >>> r = manager.request('GET', 'http://google.com/mail') + >>> r = manager.request('GET', 'http://yahoo.com/') + >>> len(manager.pools) + 2 + + """ + + proxy = None + + def __init__(self, num_pools=10, headers=None, **connection_pool_kw): + RequestMethods.__init__(self, headers) + self.connection_pool_kw = connection_pool_kw + self.pools = RecentlyUsedContainer(num_pools, + dispose_func=lambda p: p.close()) + + # Locally set the pool classes and keys so other PoolManagers can + # override them. + self.pool_classes_by_scheme = pool_classes_by_scheme + self.key_fn_by_scheme = key_fn_by_scheme.copy() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.clear() + # Return False to re-raise any potential exceptions + return False + + def _new_pool(self, scheme, host, port, request_context=None): + """ + Create a new :class:`ConnectionPool` based on host, port, scheme, and + any additional pool keyword arguments. + + If ``request_context`` is provided, it is provided as keyword arguments + to the pool class used. This method is used to actually create the + connection pools handed out by :meth:`connection_from_url` and + companion methods. It is intended to be overridden for customization. + """ + pool_cls = self.pool_classes_by_scheme[scheme] + if request_context is None: + request_context = self.connection_pool_kw.copy() + + # Although the context has everything necessary to create the pool, + # this function has historically only used the scheme, host, and port + # in the positional args. When an API change is acceptable these can + # be removed. + for key in ('scheme', 'host', 'port'): + request_context.pop(key, None) + + if scheme == 'http': + for kw in SSL_KEYWORDS: + request_context.pop(kw, None) + + return pool_cls(host, port, **request_context) + + def clear(self): + """ + Empty our store of pools and direct them all to close. + + This will not affect in-flight connections, but they will not be + re-used after completion. + """ + self.pools.clear() + + def connection_from_host(self, host, port=None, scheme='http', pool_kwargs=None): + """ + Get a :class:`ConnectionPool` based on the host, port, and scheme. + + If ``port`` isn't given, it will be derived from the ``scheme`` using + ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is + provided, it is merged with the instance's ``connection_pool_kw`` + variable and used to create the new connection pool, if one is + needed. + """ + + if not host: + raise LocationValueError("No host specified.") + + request_context = self._merge_pool_kwargs(pool_kwargs) + request_context['scheme'] = scheme or 'http' + if not port: + port = port_by_scheme.get(request_context['scheme'].lower(), 80) + request_context['port'] = port + request_context['host'] = host + + return self.connection_from_context(request_context) + + def connection_from_context(self, request_context): + """ + Get a :class:`ConnectionPool` based on the request context. + + ``request_context`` must at least contain the ``scheme`` key and its + value must be a key in ``key_fn_by_scheme`` instance variable. + """ + scheme = request_context['scheme'].lower() + pool_key_constructor = self.key_fn_by_scheme[scheme] + pool_key = pool_key_constructor(request_context) + + return self.connection_from_pool_key(pool_key, request_context=request_context) + + def connection_from_pool_key(self, pool_key, request_context=None): + """ + Get a :class:`ConnectionPool` based on the provided pool key. + + ``pool_key`` should be a namedtuple that only contains immutable + objects. At a minimum it must have the ``scheme``, ``host``, and + ``port`` fields. + """ + with self.pools.lock: + # If the scheme, host, or port doesn't match existing open + # connections, open a new ConnectionPool. + pool = self.pools.get(pool_key) + if pool: + return pool + + # Make a fresh ConnectionPool of the desired type + scheme = request_context['scheme'] + host = request_context['host'] + port = request_context['port'] + pool = self._new_pool(scheme, host, port, request_context=request_context) + self.pools[pool_key] = pool + + return pool + + def connection_from_url(self, url, pool_kwargs=None): + """ + Similar to :func:`urllib3.connectionpool.connection_from_url`. + + If ``pool_kwargs`` is not provided and a new pool needs to be + constructed, ``self.connection_pool_kw`` is used to initialize + the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs`` + is provided, it is used instead. Note that if a new pool does not + need to be created for the request, the provided ``pool_kwargs`` are + not used. + """ + u = parse_url(url) + return self.connection_from_host(u.host, port=u.port, scheme=u.scheme, + pool_kwargs=pool_kwargs) + + def _merge_pool_kwargs(self, override): + """ + Merge a dictionary of override values for self.connection_pool_kw. + + This does not modify self.connection_pool_kw and returns a new dict. + Any keys in the override dictionary with a value of ``None`` are + removed from the merged dictionary. + """ + base_pool_kwargs = self.connection_pool_kw.copy() + if override: + for key, value in override.items(): + if value is None: + try: + del base_pool_kwargs[key] + except KeyError: + pass + else: + base_pool_kwargs[key] = value + return base_pool_kwargs + + def urlopen(self, method, url, redirect=True, **kw): + """ + Same as :meth:`urllib3.connectionpool.HTTPConnectionPool.urlopen` + with custom cross-host redirect logic and only sends the request-uri + portion of the ``url``. + + The given ``url`` parameter must be absolute, such that an appropriate + :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it. + """ + u = parse_url(url) + conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme) + + kw['assert_same_host'] = False + kw['redirect'] = False + if 'headers' not in kw: + kw['headers'] = self.headers + + if self.proxy is not None and u.scheme == "http": + response = conn.urlopen(method, url, **kw) + else: + response = conn.urlopen(method, u.request_uri, **kw) + + redirect_location = redirect and response.get_redirect_location() + if not redirect_location: + return response + + # Support relative URLs for redirecting. + redirect_location = urljoin(url, redirect_location) + + # RFC 7231, Section 6.4.4 + if response.status == 303: + method = 'GET' + + retries = kw.get('retries') + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect) + + try: + retries = retries.increment(method, url, response=response, _pool=conn) + except MaxRetryError: + if retries.raise_on_redirect: + raise + return response + + kw['retries'] = retries + kw['redirect'] = redirect + + log.info("Redirecting %s -> %s", url, redirect_location) + return self.urlopen(method, redirect_location, **kw) + + +class ProxyManager(PoolManager): + """ + Behaves just like :class:`PoolManager`, but sends all requests through + the defined proxy, using the CONNECT method for HTTPS URLs. + + :param proxy_url: + The URL of the proxy to be used. + + :param proxy_headers: + A dictionary contaning headers that will be sent to the proxy. In case + of HTTP they are being sent with each request, while in the + HTTPS/CONNECT case they are sent only once. Could be used for proxy + authentication. + + Example: + >>> proxy = urllib3.ProxyManager('http://localhost:3128/') + >>> r1 = proxy.request('GET', 'http://google.com/') + >>> r2 = proxy.request('GET', 'http://httpbin.org/') + >>> len(proxy.pools) + 1 + >>> r3 = proxy.request('GET', 'https://httpbin.org/') + >>> r4 = proxy.request('GET', 'https://twitter.com/') + >>> len(proxy.pools) + 3 + + """ + + def __init__(self, proxy_url, num_pools=10, headers=None, + proxy_headers=None, **connection_pool_kw): + + if isinstance(proxy_url, HTTPConnectionPool): + proxy_url = '%s://%s:%i' % (proxy_url.scheme, proxy_url.host, + proxy_url.port) + proxy = parse_url(proxy_url) + if not proxy.port: + port = port_by_scheme.get(proxy.scheme, 80) + proxy = proxy._replace(port=port) + + if proxy.scheme not in ("http", "https"): + raise ProxySchemeUnknown(proxy.scheme) + + self.proxy = proxy + self.proxy_headers = proxy_headers or {} + + connection_pool_kw['_proxy'] = self.proxy + connection_pool_kw['_proxy_headers'] = self.proxy_headers + + super(ProxyManager, self).__init__( + num_pools, headers, **connection_pool_kw) + + def connection_from_host(self, host, port=None, scheme='http', pool_kwargs=None): + if scheme == "https": + return super(ProxyManager, self).connection_from_host( + host, port, scheme, pool_kwargs=pool_kwargs) + + return super(ProxyManager, self).connection_from_host( + self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs) + + def _set_proxy_headers(self, url, headers=None): + """ + Sets headers needed by proxies: specifically, the Accept and Host + headers. Only sets headers not provided by the user. + """ + headers_ = {'Accept': '*/*'} + + netloc = parse_url(url).netloc + if netloc: + headers_['Host'] = netloc + + if headers: + headers_.update(headers) + return headers_ + + def urlopen(self, method, url, redirect=True, **kw): + "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute." + u = parse_url(url) + + if u.scheme == "http": + # For proxied HTTPS requests, httplib sets the necessary headers + # on the CONNECT to the proxy. For HTTP, we'll definitely + # need to set 'Host' at the very least. + headers = kw.get('headers', self.headers) + kw['headers'] = self._set_proxy_headers(url, headers) + + return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw) + + +def proxy_from_url(url, **kw): + return ProxyManager(proxy_url=url, **kw) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/request.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/request.py new file mode 100644 index 0000000..c0fddff --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/request.py @@ -0,0 +1,148 @@ +from __future__ import absolute_import + +from .filepost import encode_multipart_formdata +from .packages.six.moves.urllib.parse import urlencode + + +__all__ = ['RequestMethods'] + + +class RequestMethods(object): + """ + Convenience mixin for classes who implement a :meth:`urlopen` method, such + as :class:`~urllib3.connectionpool.HTTPConnectionPool` and + :class:`~urllib3.poolmanager.PoolManager`. + + Provides behavior for making common types of HTTP request methods and + decides which type of request field encoding to use. + + Specifically, + + :meth:`.request_encode_url` is for sending requests whose fields are + encoded in the URL (such as GET, HEAD, DELETE). + + :meth:`.request_encode_body` is for sending requests whose fields are + encoded in the *body* of the request using multipart or www-form-urlencoded + (such as for POST, PUT, PATCH). + + :meth:`.request` is for making any kind of request, it will look up the + appropriate encoding format and use one of the above two methods to make + the request. + + Initializer parameters: + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + """ + + _encode_url_methods = set(['DELETE', 'GET', 'HEAD', 'OPTIONS']) + + def __init__(self, headers=None): + self.headers = headers or {} + + def urlopen(self, method, url, body=None, headers=None, + encode_multipart=True, multipart_boundary=None, + **kw): # Abstract + raise NotImplemented("Classes extending RequestMethods must implement " + "their own ``urlopen`` method.") + + def request(self, method, url, fields=None, headers=None, **urlopen_kw): + """ + Make a request using :meth:`urlopen` with the appropriate encoding of + ``fields`` based on the ``method`` used. + + This is a convenience method that requires the least amount of manual + effort. It can be used in most situations, while still having the + option to drop down to more specific methods when necessary, such as + :meth:`request_encode_url`, :meth:`request_encode_body`, + or even the lowest level :meth:`urlopen`. + """ + method = method.upper() + + if method in self._encode_url_methods: + return self.request_encode_url(method, url, fields=fields, + headers=headers, + **urlopen_kw) + else: + return self.request_encode_body(method, url, fields=fields, + headers=headers, + **urlopen_kw) + + def request_encode_url(self, method, url, fields=None, headers=None, + **urlopen_kw): + """ + Make a request using :meth:`urlopen` with the ``fields`` encoded in + the url. This is useful for request methods like GET, HEAD, DELETE, etc. + """ + if headers is None: + headers = self.headers + + extra_kw = {'headers': headers} + extra_kw.update(urlopen_kw) + + if fields: + url += '?' + urlencode(fields) + + return self.urlopen(method, url, **extra_kw) + + def request_encode_body(self, method, url, fields=None, headers=None, + encode_multipart=True, multipart_boundary=None, + **urlopen_kw): + """ + Make a request using :meth:`urlopen` with the ``fields`` encoded in + the body. This is useful for request methods like POST, PUT, PATCH, etc. + + When ``encode_multipart=True`` (default), then + :meth:`urllib3.filepost.encode_multipart_formdata` is used to encode + the payload with the appropriate content type. Otherwise + :meth:`urllib.urlencode` is used with the + 'application/x-www-form-urlencoded' content type. + + Multipart encoding must be used when posting files, and it's reasonably + safe to use it in other times too. However, it may break request + signing, such as with OAuth. + + Supports an optional ``fields`` parameter of key/value strings AND + key/filetuple. A filetuple is a (filename, data, MIME type) tuple where + the MIME type is optional. For example:: + + fields = { + 'foo': 'bar', + 'fakefile': ('foofile.txt', 'contents of foofile'), + 'realfile': ('barfile.txt', open('realfile').read()), + 'typedfile': ('bazfile.bin', open('bazfile').read(), + 'image/jpeg'), + 'nonamefile': 'contents of nonamefile field', + } + + When uploading a file, providing a filename (the first parameter of the + tuple) is optional but recommended to best mimick behavior of browsers. + + Note that if ``headers`` are supplied, the 'Content-Type' header will + be overwritten because it depends on the dynamic random boundary string + which is used to compose the body of the request. The random boundary + string can be explicitly set with the ``multipart_boundary`` parameter. + """ + if headers is None: + headers = self.headers + + extra_kw = {'headers': {}} + + if fields: + if 'body' in urlopen_kw: + raise TypeError( + "request got values for both 'fields' and 'body', can only specify one.") + + if encode_multipart: + body, content_type = encode_multipart_formdata(fields, boundary=multipart_boundary) + else: + body, content_type = urlencode(fields), 'application/x-www-form-urlencoded' + + extra_kw['body'] = body + extra_kw['headers'] = {'Content-Type': content_type} + + extra_kw['headers'].update(headers) + extra_kw.update(urlopen_kw) + + return self.urlopen(method, url, **extra_kw) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/response.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/response.py new file mode 100644 index 0000000..d3e5a1e --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/response.py @@ -0,0 +1,626 @@ +from __future__ import absolute_import +from contextlib import contextmanager +import zlib +import io +import logging +from socket import timeout as SocketTimeout +from socket import error as SocketError + +from ._collections import HTTPHeaderDict +from .exceptions import ( + BodyNotHttplibCompatible, ProtocolError, DecodeError, ReadTimeoutError, + ResponseNotChunked, IncompleteRead, InvalidHeader +) +from .packages.six import string_types as basestring, binary_type, PY3 +from .packages.six.moves import http_client as httplib +from .connection import HTTPException, BaseSSLError +from .util.response import is_fp_closed, is_response_to_head + +log = logging.getLogger(__name__) + + +class DeflateDecoder(object): + + def __init__(self): + self._first_try = True + self._data = binary_type() + self._obj = zlib.decompressobj() + + def __getattr__(self, name): + return getattr(self._obj, name) + + def decompress(self, data): + if not data: + return data + + if not self._first_try: + return self._obj.decompress(data) + + self._data += data + try: + decompressed = self._obj.decompress(data) + if decompressed: + self._first_try = False + self._data = None + return decompressed + except zlib.error: + self._first_try = False + self._obj = zlib.decompressobj(-zlib.MAX_WBITS) + try: + return self.decompress(self._data) + finally: + self._data = None + + +class GzipDecoder(object): + + def __init__(self): + self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) + + def __getattr__(self, name): + return getattr(self._obj, name) + + def decompress(self, data): + if not data: + return data + return self._obj.decompress(data) + + +def _get_decoder(mode): + if mode == 'gzip': + return GzipDecoder() + + return DeflateDecoder() + + +class HTTPResponse(io.IOBase): + """ + HTTP Response container. + + Backwards-compatible to httplib's HTTPResponse but the response ``body`` is + loaded and decoded on-demand when the ``data`` property is accessed. This + class is also compatible with the Python standard library's :mod:`io` + module, and can hence be treated as a readable object in the context of that + framework. + + Extra parameters for behaviour not present in httplib.HTTPResponse: + + :param preload_content: + If True, the response's body will be preloaded during construction. + + :param decode_content: + If True, attempts to decode specific content-encoding's based on headers + (like 'gzip' and 'deflate') will be skipped and raw data will be used + instead. + + :param original_response: + When this HTTPResponse wrapper is generated from an httplib.HTTPResponse + object, it's convenient to include the original for debug purposes. It's + otherwise unused. + + :param retries: + The retries contains the last :class:`~urllib3.util.retry.Retry` that + was used during the request. + + :param enforce_content_length: + Enforce content length checking. Body returned by server must match + value of Content-Length header, if present. Otherwise, raise error. + """ + + CONTENT_DECODERS = ['gzip', 'deflate'] + REDIRECT_STATUSES = [301, 302, 303, 307, 308] + + def __init__(self, body='', headers=None, status=0, version=0, reason=None, + strict=0, preload_content=True, decode_content=True, + original_response=None, pool=None, connection=None, + retries=None, enforce_content_length=False, request_method=None): + + if isinstance(headers, HTTPHeaderDict): + self.headers = headers + else: + self.headers = HTTPHeaderDict(headers) + self.status = status + self.version = version + self.reason = reason + self.strict = strict + self.decode_content = decode_content + self.retries = retries + self.enforce_content_length = enforce_content_length + + self._decoder = None + self._body = None + self._fp = None + self._original_response = original_response + self._fp_bytes_read = 0 + + if body and isinstance(body, (basestring, binary_type)): + self._body = body + + self._pool = pool + self._connection = connection + + if hasattr(body, 'read'): + self._fp = body + + # Are we using the chunked-style of transfer encoding? + self.chunked = False + self.chunk_left = None + tr_enc = self.headers.get('transfer-encoding', '').lower() + # Don't incur the penalty of creating a list and then discarding it + encodings = (enc.strip() for enc in tr_enc.split(",")) + if "chunked" in encodings: + self.chunked = True + + # Determine length of response + self.length_remaining = self._init_length(request_method) + + # If requested, preload the body. + if preload_content and not self._body: + self._body = self.read(decode_content=decode_content) + + def get_redirect_location(self): + """ + Should we redirect and where to? + + :returns: Truthy redirect location string if we got a redirect status + code and valid location. ``None`` if redirect status and no + location. ``False`` if not a redirect status code. + """ + if self.status in self.REDIRECT_STATUSES: + return self.headers.get('location') + + return False + + def release_conn(self): + if not self._pool or not self._connection: + return + + self._pool._put_conn(self._connection) + self._connection = None + + @property + def data(self): + # For backwords-compat with earlier urllib3 0.4 and earlier. + if self._body: + return self._body + + if self._fp: + return self.read(cache_content=True) + + @property + def connection(self): + return self._connection + + def tell(self): + """ + Obtain the number of bytes pulled over the wire so far. May differ from + the amount of content returned by :meth:``HTTPResponse.read`` if bytes + are encoded on the wire (e.g, compressed). + """ + return self._fp_bytes_read + + def _init_length(self, request_method): + """ + Set initial length value for Response content if available. + """ + length = self.headers.get('content-length') + + if length is not None and self.chunked: + # This Response will fail with an IncompleteRead if it can't be + # received as chunked. This method falls back to attempt reading + # the response before raising an exception. + log.warning("Received response with both Content-Length and " + "Transfer-Encoding set. This is expressly forbidden " + "by RFC 7230 sec 3.3.2. Ignoring Content-Length and " + "attempting to process response as Transfer-Encoding: " + "chunked.") + return None + + elif length is not None: + try: + # RFC 7230 section 3.3.2 specifies multiple content lengths can + # be sent in a single Content-Length header + # (e.g. Content-Length: 42, 42). This line ensures the values + # are all valid ints and that as long as the `set` length is 1, + # all values are the same. Otherwise, the header is invalid. + lengths = set([int(val) for val in length.split(',')]) + if len(lengths) > 1: + raise InvalidHeader("Content-Length contained multiple " + "unmatching values (%s)" % length) + length = lengths.pop() + except ValueError: + length = None + else: + if length < 0: + length = None + + # Convert status to int for comparison + # In some cases, httplib returns a status of "_UNKNOWN" + try: + status = int(self.status) + except ValueError: + status = 0 + + # Check for responses that shouldn't include a body + if status in (204, 304) or 100 <= status < 200 or request_method == 'HEAD': + length = 0 + + return length + + def _init_decoder(self): + """ + Set-up the _decoder attribute if necessary. + """ + # Note: content-encoding value should be case-insensitive, per RFC 7230 + # Section 3.2 + content_encoding = self.headers.get('content-encoding', '').lower() + if self._decoder is None and content_encoding in self.CONTENT_DECODERS: + self._decoder = _get_decoder(content_encoding) + + def _decode(self, data, decode_content, flush_decoder): + """ + Decode the data passed in and potentially flush the decoder. + """ + try: + if decode_content and self._decoder: + data = self._decoder.decompress(data) + except (IOError, zlib.error) as e: + content_encoding = self.headers.get('content-encoding', '').lower() + raise DecodeError( + "Received response with content-encoding: %s, but " + "failed to decode it." % content_encoding, e) + + if flush_decoder and decode_content: + data += self._flush_decoder() + + return data + + def _flush_decoder(self): + """ + Flushes the decoder. Should only be called if the decoder is actually + being used. + """ + if self._decoder: + buf = self._decoder.decompress(b'') + return buf + self._decoder.flush() + + return b'' + + @contextmanager + def _error_catcher(self): + """ + Catch low-level python exceptions, instead re-raising urllib3 + variants, so that low-level exceptions are not leaked in the + high-level api. + + On exit, release the connection back to the pool. + """ + clean_exit = False + + try: + try: + yield + + except SocketTimeout: + # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but + # there is yet no clean way to get at it from this context. + raise ReadTimeoutError(self._pool, None, 'Read timed out.') + + except BaseSSLError as e: + # FIXME: Is there a better way to differentiate between SSLErrors? + if 'read operation timed out' not in str(e): # Defensive: + # This shouldn't happen but just in case we're missing an edge + # case, let's avoid swallowing SSL errors. + raise + + raise ReadTimeoutError(self._pool, None, 'Read timed out.') + + except (HTTPException, SocketError) as e: + # This includes IncompleteRead. + raise ProtocolError('Connection broken: %r' % e, e) + + # If no exception is thrown, we should avoid cleaning up + # unnecessarily. + clean_exit = True + finally: + # If we didn't terminate cleanly, we need to throw away our + # connection. + if not clean_exit: + # The response may not be closed but we're not going to use it + # anymore so close it now to ensure that the connection is + # released back to the pool. + if self._original_response: + self._original_response.close() + + # Closing the response may not actually be sufficient to close + # everything, so if we have a hold of the connection close that + # too. + if self._connection: + self._connection.close() + + # If we hold the original response but it's closed now, we should + # return the connection back to the pool. + if self._original_response and self._original_response.isclosed(): + self.release_conn() + + def read(self, amt=None, decode_content=None, cache_content=False): + """ + Similar to :meth:`httplib.HTTPResponse.read`, but with two additional + parameters: ``decode_content`` and ``cache_content``. + + :param amt: + How much of the content to read. If specified, caching is skipped + because it doesn't make sense to cache partial content as the full + response. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + + :param cache_content: + If True, will save the returned data such that the same result is + returned despite of the state of the underlying file object. This + is useful if you want the ``.data`` property to continue working + after having ``.read()`` the file object. (Overridden if ``amt`` is + set.) + """ + self._init_decoder() + if decode_content is None: + decode_content = self.decode_content + + if self._fp is None: + return + + flush_decoder = False + data = None + + with self._error_catcher(): + if amt is None: + # cStringIO doesn't like amt=None + data = self._fp.read() + flush_decoder = True + else: + cache_content = False + data = self._fp.read(amt) + if amt != 0 and not data: # Platform-specific: Buggy versions of Python. + # Close the connection when no data is returned + # + # This is redundant to what httplib/http.client _should_ + # already do. However, versions of python released before + # December 15, 2012 (http://bugs.python.org/issue16298) do + # not properly close the connection in all cases. There is + # no harm in redundantly calling close. + self._fp.close() + flush_decoder = True + if self.enforce_content_length and self.length_remaining not in (0, None): + # This is an edge case that httplib failed to cover due + # to concerns of backward compatibility. We're + # addressing it here to make sure IncompleteRead is + # raised during streaming, so all calls with incorrect + # Content-Length are caught. + raise IncompleteRead(self._fp_bytes_read, self.length_remaining) + + if data: + self._fp_bytes_read += len(data) + if self.length_remaining is not None: + self.length_remaining -= len(data) + + data = self._decode(data, decode_content, flush_decoder) + + if cache_content: + self._body = data + + return data + + def stream(self, amt=2**16, decode_content=None): + """ + A generator wrapper for the read() method. A call will block until + ``amt`` bytes have been read from the connection or until the + connection is closed. + + :param amt: + How much of the content to read. The generator will return up to + much data per iteration, but may return less. This is particularly + likely when using compressed data. However, the empty string will + never be returned. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + """ + if self.chunked and self.supports_chunked_reads(): + for line in self.read_chunked(amt, decode_content=decode_content): + yield line + else: + while not is_fp_closed(self._fp): + data = self.read(amt=amt, decode_content=decode_content) + + if data: + yield data + + @classmethod + def from_httplib(ResponseCls, r, **response_kw): + """ + Given an :class:`httplib.HTTPResponse` instance ``r``, return a + corresponding :class:`urllib3.response.HTTPResponse` object. + + Remaining parameters are passed to the HTTPResponse constructor, along + with ``original_response=r``. + """ + headers = r.msg + + if not isinstance(headers, HTTPHeaderDict): + if PY3: # Python 3 + headers = HTTPHeaderDict(headers.items()) + else: # Python 2 + headers = HTTPHeaderDict.from_httplib(headers) + + # HTTPResponse objects in Python 3 don't have a .strict attribute + strict = getattr(r, 'strict', 0) + resp = ResponseCls(body=r, + headers=headers, + status=r.status, + version=r.version, + reason=r.reason, + strict=strict, + original_response=r, + **response_kw) + return resp + + # Backwards-compatibility methods for httplib.HTTPResponse + def getheaders(self): + return self.headers + + def getheader(self, name, default=None): + return self.headers.get(name, default) + + # Backwards compatibility for http.cookiejar + def info(self): + return self.headers + + # Overrides from io.IOBase + def close(self): + if not self.closed: + self._fp.close() + + if self._connection: + self._connection.close() + + @property + def closed(self): + if self._fp is None: + return True + elif hasattr(self._fp, 'isclosed'): + return self._fp.isclosed() + elif hasattr(self._fp, 'closed'): + return self._fp.closed + else: + return True + + def fileno(self): + if self._fp is None: + raise IOError("HTTPResponse has no file to get a fileno from") + elif hasattr(self._fp, "fileno"): + return self._fp.fileno() + else: + raise IOError("The file-like object this HTTPResponse is wrapped " + "around has no file descriptor") + + def flush(self): + if self._fp is not None and hasattr(self._fp, 'flush'): + return self._fp.flush() + + def readable(self): + # This method is required for `io` module compatibility. + return True + + def readinto(self, b): + # This method is required for `io` module compatibility. + temp = self.read(len(b)) + if len(temp) == 0: + return 0 + else: + b[:len(temp)] = temp + return len(temp) + + def supports_chunked_reads(self): + """ + Checks if the underlying file-like object looks like a + httplib.HTTPResponse object. We do this by testing for the fp + attribute. If it is present we assume it returns raw chunks as + processed by read_chunked(). + """ + return hasattr(self._fp, 'fp') + + def _update_chunk_length(self): + # First, we'll figure out length of a chunk and then + # we'll try to read it from socket. + if self.chunk_left is not None: + return + line = self._fp.fp.readline() + line = line.split(b';', 1)[0] + try: + self.chunk_left = int(line, 16) + except ValueError: + # Invalid chunked protocol response, abort. + self.close() + raise httplib.IncompleteRead(line) + + def _handle_chunk(self, amt): + returned_chunk = None + if amt is None: + chunk = self._fp._safe_read(self.chunk_left) + returned_chunk = chunk + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + elif amt < self.chunk_left: + value = self._fp._safe_read(amt) + self.chunk_left = self.chunk_left - amt + returned_chunk = value + elif amt == self.chunk_left: + value = self._fp._safe_read(amt) + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + returned_chunk = value + else: # amt > self.chunk_left + returned_chunk = self._fp._safe_read(self.chunk_left) + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + return returned_chunk + + def read_chunked(self, amt=None, decode_content=None): + """ + Similar to :meth:`HTTPResponse.read`, but with an additional + parameter: ``decode_content``. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + """ + self._init_decoder() + # FIXME: Rewrite this method and make it a class with a better structured logic. + if not self.chunked: + raise ResponseNotChunked( + "Response is not chunked. " + "Header 'transfer-encoding: chunked' is missing.") + if not self.supports_chunked_reads(): + raise BodyNotHttplibCompatible( + "Body should be httplib.HTTPResponse like. " + "It should have have an fp attribute which returns raw chunks.") + + # Don't bother reading the body of a HEAD request. + if self._original_response and is_response_to_head(self._original_response): + self._original_response.close() + return + + with self._error_catcher(): + while True: + self._update_chunk_length() + if self.chunk_left == 0: + break + chunk = self._handle_chunk(amt) + decoded = self._decode(chunk, decode_content=decode_content, + flush_decoder=False) + if decoded: + yield decoded + + if decode_content: + # On CPython and PyPy, we should never need to flush the + # decoder. However, on Jython we *might* need to, so + # lets defensively do it anyway. + decoded = self._flush_decoder() + if decoded: # Platform-specific: Jython. + yield decoded + + # Chunk content ends with \r\n: discard it. + while True: + line = self._fp.fp.readline() + if not line: + # Some sites may not end with '\r\n'. + break + if line == b'\r\n': + break + + # We read everything; close the "file". + if self._original_response: + self._original_response.close() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__init__.py new file mode 100644 index 0000000..2f2770b --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__init__.py @@ -0,0 +1,54 @@ +from __future__ import absolute_import +# For backwards compatibility, provide imports that used to be here. +from .connection import is_connection_dropped +from .request import make_headers +from .response import is_fp_closed +from .ssl_ import ( + SSLContext, + HAS_SNI, + IS_PYOPENSSL, + IS_SECURETRANSPORT, + assert_fingerprint, + resolve_cert_reqs, + resolve_ssl_version, + ssl_wrap_socket, +) +from .timeout import ( + current_time, + Timeout, +) + +from .retry import Retry +from .url import ( + get_host, + parse_url, + split_first, + Url, +) +from .wait import ( + wait_for_read, + wait_for_write +) + +__all__ = ( + 'HAS_SNI', + 'IS_PYOPENSSL', + 'IS_SECURETRANSPORT', + 'SSLContext', + 'Retry', + 'Timeout', + 'Url', + 'assert_fingerprint', + 'current_time', + 'is_connection_dropped', + 'is_fp_closed', + 'get_host', + 'parse_url', + 'make_headers', + 'resolve_cert_reqs', + 'resolve_ssl_version', + 'split_first', + 'ssl_wrap_socket', + 'wait_for_read', + 'wait_for_write' +) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/connection.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/connection.py new file mode 100644 index 0000000..bf699cf --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/connection.py @@ -0,0 +1,130 @@ +from __future__ import absolute_import +import socket +from .wait import wait_for_read +from .selectors import HAS_SELECT, SelectorError + + +def is_connection_dropped(conn): # Platform-specific + """ + Returns True if the connection is dropped and should be closed. + + :param conn: + :class:`httplib.HTTPConnection` object. + + Note: For platforms like AppEngine, this will always return ``False`` to + let the platform handle connection recycling transparently for us. + """ + sock = getattr(conn, 'sock', False) + if sock is False: # Platform-specific: AppEngine + return False + if sock is None: # Connection already closed (such as by httplib). + return True + + if not HAS_SELECT: + return False + + try: + return bool(wait_for_read(sock, timeout=0.0)) + except SelectorError: + return True + + +# This function is copied from socket.py in the Python 2.7 standard +# library test suite. Added to its signature is only `socket_options`. +# One additional modification is that we avoid binding to IPv6 servers +# discovered in DNS if the system doesn't have IPv6 functionality. +def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + source_address=None, socket_options=None): + """Connect to *address* and return the socket object. + + Convenience function. Connect to *address* (a 2-tuple ``(host, + port)``) and return the socket object. Passing the optional + *timeout* parameter will set the timeout on the socket instance + before attempting to connect. If no *timeout* is supplied, the + global default timeout setting returned by :func:`getdefaulttimeout` + is used. If *source_address* is set it must be a tuple of (host, port) + for the socket to bind as a source address before making the connection. + An host of '' or port 0 tells the OS to use the default. + """ + + host, port = address + if host.startswith('['): + host = host.strip('[]') + err = None + + # Using the value from allowed_gai_family() in the context of getaddrinfo lets + # us select whether to work with IPv4 DNS records, IPv6 records, or both. + # The original create_connection function always returns all records. + family = allowed_gai_family() + + for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): + af, socktype, proto, canonname, sa = res + sock = None + try: + sock = socket.socket(af, socktype, proto) + + # If provided, set socket level options before connecting. + _set_socket_options(sock, socket_options) + + if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: + sock.settimeout(timeout) + if source_address: + sock.bind(source_address) + sock.connect(sa) + return sock + + except socket.error as e: + err = e + if sock is not None: + sock.close() + sock = None + + if err is not None: + raise err + + raise socket.error("getaddrinfo returns an empty list") + + +def _set_socket_options(sock, options): + if options is None: + return + + for opt in options: + sock.setsockopt(*opt) + + +def allowed_gai_family(): + """This function is designed to work in the context of + getaddrinfo, where family=socket.AF_UNSPEC is the default and + will perform a DNS search for both IPv6 and IPv4 records.""" + + family = socket.AF_INET + if HAS_IPV6: + family = socket.AF_UNSPEC + return family + + +def _has_ipv6(host): + """ Returns True if the system can bind an IPv6 address. """ + sock = None + has_ipv6 = False + + if socket.has_ipv6: + # has_ipv6 returns true if cPython was compiled with IPv6 support. + # It does not tell us if the system has IPv6 support enabled. To + # determine that we must bind to an IPv6 address. + # https://github.com/shazow/urllib3/pull/611 + # https://bugs.python.org/issue658327 + try: + sock = socket.socket(socket.AF_INET6) + sock.bind((host, 0)) + has_ipv6 = True + except Exception: + pass + + if sock: + sock.close() + return has_ipv6 + + +HAS_IPV6 = _has_ipv6('::1') diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/request.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/request.py new file mode 100644 index 0000000..3ddfcd5 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/request.py @@ -0,0 +1,118 @@ +from __future__ import absolute_import +from base64 import b64encode + +from ..packages.six import b, integer_types +from ..exceptions import UnrewindableBodyError + +ACCEPT_ENCODING = 'gzip,deflate' +_FAILEDTELL = object() + + +def make_headers(keep_alive=None, accept_encoding=None, user_agent=None, + basic_auth=None, proxy_basic_auth=None, disable_cache=None): + """ + Shortcuts for generating request headers. + + :param keep_alive: + If ``True``, adds 'connection: keep-alive' header. + + :param accept_encoding: + Can be a boolean, list, or string. + ``True`` translates to 'gzip,deflate'. + List will get joined by comma. + String will be used as provided. + + :param user_agent: + String representing the user-agent you want, such as + "python-urllib3/0.6" + + :param basic_auth: + Colon-separated username:password string for 'authorization: basic ...' + auth header. + + :param proxy_basic_auth: + Colon-separated username:password string for 'proxy-authorization: basic ...' + auth header. + + :param disable_cache: + If ``True``, adds 'cache-control: no-cache' header. + + Example:: + + >>> make_headers(keep_alive=True, user_agent="Batman/1.0") + {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'} + >>> make_headers(accept_encoding=True) + {'accept-encoding': 'gzip,deflate'} + """ + headers = {} + if accept_encoding: + if isinstance(accept_encoding, str): + pass + elif isinstance(accept_encoding, list): + accept_encoding = ','.join(accept_encoding) + else: + accept_encoding = ACCEPT_ENCODING + headers['accept-encoding'] = accept_encoding + + if user_agent: + headers['user-agent'] = user_agent + + if keep_alive: + headers['connection'] = 'keep-alive' + + if basic_auth: + headers['authorization'] = 'Basic ' + \ + b64encode(b(basic_auth)).decode('utf-8') + + if proxy_basic_auth: + headers['proxy-authorization'] = 'Basic ' + \ + b64encode(b(proxy_basic_auth)).decode('utf-8') + + if disable_cache: + headers['cache-control'] = 'no-cache' + + return headers + + +def set_file_position(body, pos): + """ + If a position is provided, move file to that point. + Otherwise, we'll attempt to record a position for future use. + """ + if pos is not None: + rewind_body(body, pos) + elif getattr(body, 'tell', None) is not None: + try: + pos = body.tell() + except (IOError, OSError): + # This differentiates from None, allowing us to catch + # a failed `tell()` later when trying to rewind the body. + pos = _FAILEDTELL + + return pos + + +def rewind_body(body, body_pos): + """ + Attempt to rewind body to a certain position. + Primarily used for request redirects and retries. + + :param body: + File-like object that supports seek. + + :param int pos: + Position to seek to in file. + """ + body_seek = getattr(body, 'seek', None) + if body_seek is not None and isinstance(body_pos, integer_types): + try: + body_seek(body_pos) + except (IOError, OSError): + raise UnrewindableBodyError("An error occurred when rewinding request " + "body for redirect/retry.") + elif body_pos is _FAILEDTELL: + raise UnrewindableBodyError("Unable to record file position for rewinding " + "request body during a redirect/retry.") + else: + raise ValueError("body_pos must be of type integer, " + "instead it was %s." % type(body_pos)) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/response.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/response.py new file mode 100644 index 0000000..67cf730 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/response.py @@ -0,0 +1,81 @@ +from __future__ import absolute_import +from ..packages.six.moves import http_client as httplib + +from ..exceptions import HeaderParsingError + + +def is_fp_closed(obj): + """ + Checks whether a given file-like object is closed. + + :param obj: + The file-like object to check. + """ + + try: + # Check `isclosed()` first, in case Python3 doesn't set `closed`. + # GH Issue #928 + return obj.isclosed() + except AttributeError: + pass + + try: + # Check via the official file-like-object way. + return obj.closed + except AttributeError: + pass + + try: + # Check if the object is a container for another file-like object that + # gets released on exhaustion (e.g. HTTPResponse). + return obj.fp is None + except AttributeError: + pass + + raise ValueError("Unable to determine whether fp is closed.") + + +def assert_header_parsing(headers): + """ + Asserts whether all headers have been successfully parsed. + Extracts encountered errors from the result of parsing headers. + + Only works on Python 3. + + :param headers: Headers to verify. + :type headers: `httplib.HTTPMessage`. + + :raises urllib3.exceptions.HeaderParsingError: + If parsing errors are found. + """ + + # This will fail silently if we pass in the wrong kind of parameter. + # To make debugging easier add an explicit check. + if not isinstance(headers, httplib.HTTPMessage): + raise TypeError('expected httplib.Message, got {0}.'.format( + type(headers))) + + defects = getattr(headers, 'defects', None) + get_payload = getattr(headers, 'get_payload', None) + + unparsed_data = None + if get_payload: # Platform-specific: Python 3. + unparsed_data = get_payload() + + if defects or unparsed_data: + raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data) + + +def is_response_to_head(response): + """ + Checks whether the request of a response has been a HEAD-request. + Handles the quirks of AppEngine. + + :param conn: + :type conn: :class:`httplib.HTTPResponse` + """ + # FIXME: Can we do this somehow without accessing private httplib _method? + method = response._method + if isinstance(method, int): # Platform-specific: Appengine + return method == 3 + return method.upper() == 'HEAD' diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/retry.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/retry.py new file mode 100644 index 0000000..c603cb4 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/retry.py @@ -0,0 +1,401 @@ +from __future__ import absolute_import +import time +import logging +from collections import namedtuple +from itertools import takewhile +import email +import re + +from ..exceptions import ( + ConnectTimeoutError, + MaxRetryError, + ProtocolError, + ReadTimeoutError, + ResponseError, + InvalidHeader, +) +from ..packages import six + + +log = logging.getLogger(__name__) + +# Data structure for representing the metadata of requests that result in a retry. +RequestHistory = namedtuple('RequestHistory', ["method", "url", "error", + "status", "redirect_location"]) + + +class Retry(object): + """ Retry configuration. + + Each retry attempt will create a new Retry object with updated values, so + they can be safely reused. + + Retries can be defined as a default for a pool:: + + retries = Retry(connect=5, read=2, redirect=5) + http = PoolManager(retries=retries) + response = http.request('GET', 'http://example.com/') + + Or per-request (which overrides the default for the pool):: + + response = http.request('GET', 'http://example.com/', retries=Retry(10)) + + Retries can be disabled by passing ``False``:: + + response = http.request('GET', 'http://example.com/', retries=False) + + Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless + retries are disabled, in which case the causing exception will be raised. + + :param int total: + Total number of retries to allow. Takes precedence over other counts. + + Set to ``None`` to remove this constraint and fall back on other + counts. It's a good idea to set this to some sensibly-high value to + account for unexpected edge cases and avoid infinite retry loops. + + Set to ``0`` to fail on the first retry. + + Set to ``False`` to disable and imply ``raise_on_redirect=False``. + + :param int connect: + How many connection-related errors to retry on. + + These are errors raised before the request is sent to the remote server, + which we assume has not triggered the server to process the request. + + Set to ``0`` to fail on the first retry of this type. + + :param int read: + How many times to retry on read errors. + + These errors are raised after the request was sent to the server, so the + request may have side-effects. + + Set to ``0`` to fail on the first retry of this type. + + :param int redirect: + How many redirects to perform. Limit this to avoid infinite redirect + loops. + + A redirect is a HTTP response with a status code 301, 302, 303, 307 or + 308. + + Set to ``0`` to fail on the first retry of this type. + + Set to ``False`` to disable and imply ``raise_on_redirect=False``. + + :param int status: + How many times to retry on bad status codes. + + These are retries made on responses, where status code matches + ``status_forcelist``. + + Set to ``0`` to fail on the first retry of this type. + + :param iterable method_whitelist: + Set of uppercased HTTP method verbs that we should retry on. + + By default, we only retry on methods which are considered to be + idempotent (multiple requests with the same parameters end with the + same state). See :attr:`Retry.DEFAULT_METHOD_WHITELIST`. + + Set to a ``False`` value to retry on any verb. + + :param iterable status_forcelist: + A set of integer HTTP status codes that we should force a retry on. + A retry is initiated if the request method is in ``method_whitelist`` + and the response status code is in ``status_forcelist``. + + By default, this is disabled with ``None``. + + :param float backoff_factor: + A backoff factor to apply between attempts after the second try + (most errors are resolved immediately by a second try without a + delay). urllib3 will sleep for:: + + {backoff factor} * (2 ^ ({number of total retries} - 1)) + + seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep + for [0.0s, 0.2s, 0.4s, ...] between retries. It will never be longer + than :attr:`Retry.BACKOFF_MAX`. + + By default, backoff is disabled (set to 0). + + :param bool raise_on_redirect: Whether, if the number of redirects is + exhausted, to raise a MaxRetryError, or to return a response with a + response code in the 3xx range. + + :param bool raise_on_status: Similar meaning to ``raise_on_redirect``: + whether we should raise an exception, or return a response, + if status falls in ``status_forcelist`` range and retries have + been exhausted. + + :param tuple history: The history of the request encountered during + each call to :meth:`~Retry.increment`. The list is in the order + the requests occurred. Each list item is of class :class:`RequestHistory`. + + :param bool respect_retry_after_header: + Whether to respect Retry-After header on status codes defined as + :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not. + + """ + + DEFAULT_METHOD_WHITELIST = frozenset([ + 'HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS', 'TRACE']) + + RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) + + #: Maximum backoff time. + BACKOFF_MAX = 120 + + def __init__(self, total=10, connect=None, read=None, redirect=None, status=None, + method_whitelist=DEFAULT_METHOD_WHITELIST, status_forcelist=None, + backoff_factor=0, raise_on_redirect=True, raise_on_status=True, + history=None, respect_retry_after_header=True): + + self.total = total + self.connect = connect + self.read = read + self.status = status + + if redirect is False or total is False: + redirect = 0 + raise_on_redirect = False + + self.redirect = redirect + self.status_forcelist = status_forcelist or set() + self.method_whitelist = method_whitelist + self.backoff_factor = backoff_factor + self.raise_on_redirect = raise_on_redirect + self.raise_on_status = raise_on_status + self.history = history or tuple() + self.respect_retry_after_header = respect_retry_after_header + + def new(self, **kw): + params = dict( + total=self.total, + connect=self.connect, read=self.read, redirect=self.redirect, status=self.status, + method_whitelist=self.method_whitelist, + status_forcelist=self.status_forcelist, + backoff_factor=self.backoff_factor, + raise_on_redirect=self.raise_on_redirect, + raise_on_status=self.raise_on_status, + history=self.history, + ) + params.update(kw) + return type(self)(**params) + + @classmethod + def from_int(cls, retries, redirect=True, default=None): + """ Backwards-compatibility for the old retries format.""" + if retries is None: + retries = default if default is not None else cls.DEFAULT + + if isinstance(retries, Retry): + return retries + + redirect = bool(redirect) and None + new_retries = cls(retries, redirect=redirect) + log.debug("Converted retries value: %r -> %r", retries, new_retries) + return new_retries + + def get_backoff_time(self): + """ Formula for computing the current backoff + + :rtype: float + """ + # We want to consider only the last consecutive errors sequence (Ignore redirects). + consecutive_errors_len = len(list(takewhile(lambda x: x.redirect_location is None, + reversed(self.history)))) + if consecutive_errors_len <= 1: + return 0 + + backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1)) + return min(self.BACKOFF_MAX, backoff_value) + + def parse_retry_after(self, retry_after): + # Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4 + if re.match(r"^\s*[0-9]+\s*$", retry_after): + seconds = int(retry_after) + else: + retry_date_tuple = email.utils.parsedate(retry_after) + if retry_date_tuple is None: + raise InvalidHeader("Invalid Retry-After header: %s" % retry_after) + retry_date = time.mktime(retry_date_tuple) + seconds = retry_date - time.time() + + if seconds < 0: + seconds = 0 + + return seconds + + def get_retry_after(self, response): + """ Get the value of Retry-After in seconds. """ + + retry_after = response.getheader("Retry-After") + + if retry_after is None: + return None + + return self.parse_retry_after(retry_after) + + def sleep_for_retry(self, response=None): + retry_after = self.get_retry_after(response) + if retry_after: + time.sleep(retry_after) + return True + + return False + + def _sleep_backoff(self): + backoff = self.get_backoff_time() + if backoff <= 0: + return + time.sleep(backoff) + + def sleep(self, response=None): + """ Sleep between retry attempts. + + This method will respect a server's ``Retry-After`` response header + and sleep the duration of the time requested. If that is not present, it + will use an exponential backoff. By default, the backoff factor is 0 and + this method will return immediately. + """ + + if response: + slept = self.sleep_for_retry(response) + if slept: + return + + self._sleep_backoff() + + def _is_connection_error(self, err): + """ Errors when we're fairly sure that the server did not receive the + request, so it should be safe to retry. + """ + return isinstance(err, ConnectTimeoutError) + + def _is_read_error(self, err): + """ Errors that occur after the request has been started, so we should + assume that the server began processing it. + """ + return isinstance(err, (ReadTimeoutError, ProtocolError)) + + def _is_method_retryable(self, method): + """ Checks if a given HTTP method should be retried upon, depending if + it is included on the method whitelist. + """ + if self.method_whitelist and method.upper() not in self.method_whitelist: + return False + + return True + + def is_retry(self, method, status_code, has_retry_after=False): + """ Is this method/status code retryable? (Based on whitelists and control + variables such as the number of total retries to allow, whether to + respect the Retry-After header, whether this header is present, and + whether the returned status code is on the list of status codes to + be retried upon on the presence of the aforementioned header) + """ + if not self._is_method_retryable(method): + return False + + if self.status_forcelist and status_code in self.status_forcelist: + return True + + return (self.total and self.respect_retry_after_header and + has_retry_after and (status_code in self.RETRY_AFTER_STATUS_CODES)) + + def is_exhausted(self): + """ Are we out of retries? """ + retry_counts = (self.total, self.connect, self.read, self.redirect, self.status) + retry_counts = list(filter(None, retry_counts)) + if not retry_counts: + return False + + return min(retry_counts) < 0 + + def increment(self, method=None, url=None, response=None, error=None, + _pool=None, _stacktrace=None): + """ Return a new Retry object with incremented retry counters. + + :param response: A response object, or None, if the server did not + return a response. + :type response: :class:`~urllib3.response.HTTPResponse` + :param Exception error: An error encountered during the request, or + None if the response was received successfully. + + :return: A new ``Retry`` object. + """ + if self.total is False and error: + # Disabled, indicate to re-raise the error. + raise six.reraise(type(error), error, _stacktrace) + + total = self.total + if total is not None: + total -= 1 + + connect = self.connect + read = self.read + redirect = self.redirect + status_count = self.status + cause = 'unknown' + status = None + redirect_location = None + + if error and self._is_connection_error(error): + # Connect retry? + if connect is False: + raise six.reraise(type(error), error, _stacktrace) + elif connect is not None: + connect -= 1 + + elif error and self._is_read_error(error): + # Read retry? + if read is False or not self._is_method_retryable(method): + raise six.reraise(type(error), error, _stacktrace) + elif read is not None: + read -= 1 + + elif response and response.get_redirect_location(): + # Redirect retry? + if redirect is not None: + redirect -= 1 + cause = 'too many redirects' + redirect_location = response.get_redirect_location() + status = response.status + + else: + # Incrementing because of a server error like a 500 in + # status_forcelist and a the given method is in the whitelist + cause = ResponseError.GENERIC_ERROR + if response and response.status: + if status_count is not None: + status_count -= 1 + cause = ResponseError.SPECIFIC_ERROR.format( + status_code=response.status) + status = response.status + + history = self.history + (RequestHistory(method, url, error, status, redirect_location),) + + new_retry = self.new( + total=total, + connect=connect, read=read, redirect=redirect, status=status_count, + history=history) + + if new_retry.is_exhausted(): + raise MaxRetryError(_pool, url, error or ResponseError(cause)) + + log.debug("Incremented Retry for (url='%s'): %r", url, new_retry) + + return new_retry + + def __repr__(self): + return ('{cls.__name__}(total={self.total}, connect={self.connect}, ' + 'read={self.read}, redirect={self.redirect}, status={self.status})').format( + cls=type(self), self=self) + + +# For backwards compatibility (equivalent to pre-v1.9): +Retry.DEFAULT = Retry(3) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/selectors.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/selectors.py new file mode 100644 index 0000000..d75cb26 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/selectors.py @@ -0,0 +1,581 @@ +# Backport of selectors.py from Python 3.5+ to support Python < 3.4 +# Also has the behavior specified in PEP 475 which is to retry syscalls +# in the case of an EINTR error. This module is required because selectors34 +# does not follow this behavior and instead returns that no dile descriptor +# events have occurred rather than retry the syscall. The decision to drop +# support for select.devpoll is made to maintain 100% test coverage. + +import errno +import math +import select +import socket +import sys +import time +from collections import namedtuple, Mapping + +try: + monotonic = time.monotonic +except (AttributeError, ImportError): # Python 3.3< + monotonic = time.time + +EVENT_READ = (1 << 0) +EVENT_WRITE = (1 << 1) + +HAS_SELECT = True # Variable that shows whether the platform has a selector. +_SYSCALL_SENTINEL = object() # Sentinel in case a system call returns None. +_DEFAULT_SELECTOR = None + + +class SelectorError(Exception): + def __init__(self, errcode): + super(SelectorError, self).__init__() + self.errno = errcode + + def __repr__(self): + return "<SelectorError errno={0}>".format(self.errno) + + def __str__(self): + return self.__repr__() + + +def _fileobj_to_fd(fileobj): + """ Return a file descriptor from a file object. If + given an integer will simply return that integer back. """ + if isinstance(fileobj, int): + fd = fileobj + else: + try: + fd = int(fileobj.fileno()) + except (AttributeError, TypeError, ValueError): + raise ValueError("Invalid file object: {0!r}".format(fileobj)) + if fd < 0: + raise ValueError("Invalid file descriptor: {0}".format(fd)) + return fd + + +# Determine which function to use to wrap system calls because Python 3.5+ +# already handles the case when system calls are interrupted. +if sys.version_info >= (3, 5): + def _syscall_wrapper(func, _, *args, **kwargs): + """ This is the short-circuit version of the below logic + because in Python 3.5+ all system calls automatically restart + and recalculate their timeouts. """ + try: + return func(*args, **kwargs) + except (OSError, IOError, select.error) as e: + errcode = None + if hasattr(e, "errno"): + errcode = e.errno + raise SelectorError(errcode) +else: + def _syscall_wrapper(func, recalc_timeout, *args, **kwargs): + """ Wrapper function for syscalls that could fail due to EINTR. + All functions should be retried if there is time left in the timeout + in accordance with PEP 475. """ + timeout = kwargs.get("timeout", None) + if timeout is None: + expires = None + recalc_timeout = False + else: + timeout = float(timeout) + if timeout < 0.0: # Timeout less than 0 treated as no timeout. + expires = None + else: + expires = monotonic() + timeout + + args = list(args) + if recalc_timeout and "timeout" not in kwargs: + raise ValueError( + "Timeout must be in args or kwargs to be recalculated") + + result = _SYSCALL_SENTINEL + while result is _SYSCALL_SENTINEL: + try: + result = func(*args, **kwargs) + # OSError is thrown by select.select + # IOError is thrown by select.epoll.poll + # select.error is thrown by select.poll.poll + # Aren't we thankful for Python 3.x rework for exceptions? + except (OSError, IOError, select.error) as e: + # select.error wasn't a subclass of OSError in the past. + errcode = None + if hasattr(e, "errno"): + errcode = e.errno + elif hasattr(e, "args"): + errcode = e.args[0] + + # Also test for the Windows equivalent of EINTR. + is_interrupt = (errcode == errno.EINTR or (hasattr(errno, "WSAEINTR") and + errcode == errno.WSAEINTR)) + + if is_interrupt: + if expires is not None: + current_time = monotonic() + if current_time > expires: + raise OSError(errno=errno.ETIMEDOUT) + if recalc_timeout: + if "timeout" in kwargs: + kwargs["timeout"] = expires - current_time + continue + if errcode: + raise SelectorError(errcode) + else: + raise + return result + + +SelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data']) + + +class _SelectorMapping(Mapping): + """ Mapping of file objects to selector keys """ + + def __init__(self, selector): + self._selector = selector + + def __len__(self): + return len(self._selector._fd_to_key) + + def __getitem__(self, fileobj): + try: + fd = self._selector._fileobj_lookup(fileobj) + return self._selector._fd_to_key[fd] + except KeyError: + raise KeyError("{0!r} is not registered.".format(fileobj)) + + def __iter__(self): + return iter(self._selector._fd_to_key) + + +class BaseSelector(object): + """ Abstract Selector class + + A selector supports registering file objects to be monitored + for specific I/O events. + + A file object is a file descriptor or any object with a + `fileno()` method. An arbitrary object can be attached to the + file object which can be used for example to store context info, + a callback, etc. + + A selector can use various implementations (select(), poll(), epoll(), + and kqueue()) depending on the platform. The 'DefaultSelector' class uses + the most efficient implementation for the current platform. + """ + def __init__(self): + # Maps file descriptors to keys. + self._fd_to_key = {} + + # Read-only mapping returned by get_map() + self._map = _SelectorMapping(self) + + def _fileobj_lookup(self, fileobj): + """ Return a file descriptor from a file object. + This wraps _fileobj_to_fd() to do an exhaustive + search in case the object is invalid but we still + have it in our map. Used by unregister() so we can + unregister an object that was previously registered + even if it is closed. It is also used by _SelectorMapping + """ + try: + return _fileobj_to_fd(fileobj) + except ValueError: + + # Search through all our mapped keys. + for key in self._fd_to_key.values(): + if key.fileobj is fileobj: + return key.fd + + # Raise ValueError after all. + raise + + def register(self, fileobj, events, data=None): + """ Register a file object for a set of events to monitor. """ + if (not events) or (events & ~(EVENT_READ | EVENT_WRITE)): + raise ValueError("Invalid events: {0!r}".format(events)) + + key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data) + + if key.fd in self._fd_to_key: + raise KeyError("{0!r} (FD {1}) is already registered" + .format(fileobj, key.fd)) + + self._fd_to_key[key.fd] = key + return key + + def unregister(self, fileobj): + """ Unregister a file object from being monitored. """ + try: + key = self._fd_to_key.pop(self._fileobj_lookup(fileobj)) + except KeyError: + raise KeyError("{0!r} is not registered".format(fileobj)) + + # Getting the fileno of a closed socket on Windows errors with EBADF. + except socket.error as e: # Platform-specific: Windows. + if e.errno != errno.EBADF: + raise + else: + for key in self._fd_to_key.values(): + if key.fileobj is fileobj: + self._fd_to_key.pop(key.fd) + break + else: + raise KeyError("{0!r} is not registered".format(fileobj)) + return key + + def modify(self, fileobj, events, data=None): + """ Change a registered file object monitored events and data. """ + # NOTE: Some subclasses optimize this operation even further. + try: + key = self._fd_to_key[self._fileobj_lookup(fileobj)] + except KeyError: + raise KeyError("{0!r} is not registered".format(fileobj)) + + if events != key.events: + self.unregister(fileobj) + key = self.register(fileobj, events, data) + + elif data != key.data: + # Use a shortcut to update the data. + key = key._replace(data=data) + self._fd_to_key[key.fd] = key + + return key + + def select(self, timeout=None): + """ Perform the actual selection until some monitored file objects + are ready or the timeout expires. """ + raise NotImplementedError() + + def close(self): + """ Close the selector. This must be called to ensure that all + underlying resources are freed. """ + self._fd_to_key.clear() + self._map = None + + def get_key(self, fileobj): + """ Return the key associated with a registered file object. """ + mapping = self.get_map() + if mapping is None: + raise RuntimeError("Selector is closed") + try: + return mapping[fileobj] + except KeyError: + raise KeyError("{0!r} is not registered".format(fileobj)) + + def get_map(self): + """ Return a mapping of file objects to selector keys """ + return self._map + + def _key_from_fd(self, fd): + """ Return the key associated to a given file descriptor + Return None if it is not found. """ + try: + return self._fd_to_key[fd] + except KeyError: + return None + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + +# Almost all platforms have select.select() +if hasattr(select, "select"): + class SelectSelector(BaseSelector): + """ Select-based selector. """ + def __init__(self): + super(SelectSelector, self).__init__() + self._readers = set() + self._writers = set() + + def register(self, fileobj, events, data=None): + key = super(SelectSelector, self).register(fileobj, events, data) + if events & EVENT_READ: + self._readers.add(key.fd) + if events & EVENT_WRITE: + self._writers.add(key.fd) + return key + + def unregister(self, fileobj): + key = super(SelectSelector, self).unregister(fileobj) + self._readers.discard(key.fd) + self._writers.discard(key.fd) + return key + + def _select(self, r, w, timeout=None): + """ Wrapper for select.select because timeout is a positional arg """ + return select.select(r, w, [], timeout) + + def select(self, timeout=None): + # Selecting on empty lists on Windows errors out. + if not len(self._readers) and not len(self._writers): + return [] + + timeout = None if timeout is None else max(timeout, 0.0) + ready = [] + r, w, _ = _syscall_wrapper(self._select, True, self._readers, + self._writers, timeout) + r = set(r) + w = set(w) + for fd in r | w: + events = 0 + if fd in r: + events |= EVENT_READ + if fd in w: + events |= EVENT_WRITE + + key = self._key_from_fd(fd) + if key: + ready.append((key, events & key.events)) + return ready + + +if hasattr(select, "poll"): + class PollSelector(BaseSelector): + """ Poll-based selector """ + def __init__(self): + super(PollSelector, self).__init__() + self._poll = select.poll() + + def register(self, fileobj, events, data=None): + key = super(PollSelector, self).register(fileobj, events, data) + event_mask = 0 + if events & EVENT_READ: + event_mask |= select.POLLIN + if events & EVENT_WRITE: + event_mask |= select.POLLOUT + self._poll.register(key.fd, event_mask) + return key + + def unregister(self, fileobj): + key = super(PollSelector, self).unregister(fileobj) + self._poll.unregister(key.fd) + return key + + def _wrap_poll(self, timeout=None): + """ Wrapper function for select.poll.poll() so that + _syscall_wrapper can work with only seconds. """ + if timeout is not None: + if timeout <= 0: + timeout = 0 + else: + # select.poll.poll() has a resolution of 1 millisecond, + # round away from zero to wait *at least* timeout seconds. + timeout = math.ceil(timeout * 1e3) + + result = self._poll.poll(timeout) + return result + + def select(self, timeout=None): + ready = [] + fd_events = _syscall_wrapper(self._wrap_poll, True, timeout=timeout) + for fd, event_mask in fd_events: + events = 0 + if event_mask & ~select.POLLIN: + events |= EVENT_WRITE + if event_mask & ~select.POLLOUT: + events |= EVENT_READ + + key = self._key_from_fd(fd) + if key: + ready.append((key, events & key.events)) + + return ready + + +if hasattr(select, "epoll"): + class EpollSelector(BaseSelector): + """ Epoll-based selector """ + def __init__(self): + super(EpollSelector, self).__init__() + self._epoll = select.epoll() + + def fileno(self): + return self._epoll.fileno() + + def register(self, fileobj, events, data=None): + key = super(EpollSelector, self).register(fileobj, events, data) + events_mask = 0 + if events & EVENT_READ: + events_mask |= select.EPOLLIN + if events & EVENT_WRITE: + events_mask |= select.EPOLLOUT + _syscall_wrapper(self._epoll.register, False, key.fd, events_mask) + return key + + def unregister(self, fileobj): + key = super(EpollSelector, self).unregister(fileobj) + try: + _syscall_wrapper(self._epoll.unregister, False, key.fd) + except SelectorError: + # This can occur when the fd was closed since registry. + pass + return key + + def select(self, timeout=None): + if timeout is not None: + if timeout <= 0: + timeout = 0.0 + else: + # select.epoll.poll() has a resolution of 1 millisecond + # but luckily takes seconds so we don't need a wrapper + # like PollSelector. Just for better rounding. + timeout = math.ceil(timeout * 1e3) * 1e-3 + timeout = float(timeout) + else: + timeout = -1.0 # epoll.poll() must have a float. + + # We always want at least 1 to ensure that select can be called + # with no file descriptors registered. Otherwise will fail. + max_events = max(len(self._fd_to_key), 1) + + ready = [] + fd_events = _syscall_wrapper(self._epoll.poll, True, + timeout=timeout, + maxevents=max_events) + for fd, event_mask in fd_events: + events = 0 + if event_mask & ~select.EPOLLIN: + events |= EVENT_WRITE + if event_mask & ~select.EPOLLOUT: + events |= EVENT_READ + + key = self._key_from_fd(fd) + if key: + ready.append((key, events & key.events)) + return ready + + def close(self): + self._epoll.close() + super(EpollSelector, self).close() + + +if hasattr(select, "kqueue"): + class KqueueSelector(BaseSelector): + """ Kqueue / Kevent-based selector """ + def __init__(self): + super(KqueueSelector, self).__init__() + self._kqueue = select.kqueue() + + def fileno(self): + return self._kqueue.fileno() + + def register(self, fileobj, events, data=None): + key = super(KqueueSelector, self).register(fileobj, events, data) + if events & EVENT_READ: + kevent = select.kevent(key.fd, + select.KQ_FILTER_READ, + select.KQ_EV_ADD) + + _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0) + + if events & EVENT_WRITE: + kevent = select.kevent(key.fd, + select.KQ_FILTER_WRITE, + select.KQ_EV_ADD) + + _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0) + + return key + + def unregister(self, fileobj): + key = super(KqueueSelector, self).unregister(fileobj) + if key.events & EVENT_READ: + kevent = select.kevent(key.fd, + select.KQ_FILTER_READ, + select.KQ_EV_DELETE) + try: + _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0) + except SelectorError: + pass + if key.events & EVENT_WRITE: + kevent = select.kevent(key.fd, + select.KQ_FILTER_WRITE, + select.KQ_EV_DELETE) + try: + _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0) + except SelectorError: + pass + + return key + + def select(self, timeout=None): + if timeout is not None: + timeout = max(timeout, 0) + + max_events = len(self._fd_to_key) * 2 + ready_fds = {} + + kevent_list = _syscall_wrapper(self._kqueue.control, True, + None, max_events, timeout) + + for kevent in kevent_list: + fd = kevent.ident + event_mask = kevent.filter + events = 0 + if event_mask == select.KQ_FILTER_READ: + events |= EVENT_READ + if event_mask == select.KQ_FILTER_WRITE: + events |= EVENT_WRITE + + key = self._key_from_fd(fd) + if key: + if key.fd not in ready_fds: + ready_fds[key.fd] = (key, events & key.events) + else: + old_events = ready_fds[key.fd][1] + ready_fds[key.fd] = (key, (events | old_events) & key.events) + + return list(ready_fds.values()) + + def close(self): + self._kqueue.close() + super(KqueueSelector, self).close() + + +if not hasattr(select, 'select'): # Platform-specific: AppEngine + HAS_SELECT = False + + +def _can_allocate(struct): + """ Checks that select structs can be allocated by the underlying + operating system, not just advertised by the select module. We don't + check select() because we'll be hopeful that most platforms that + don't have it available will not advertise it. (ie: GAE) """ + try: + # select.poll() objects won't fail until used. + if struct == 'poll': + p = select.poll() + p.poll(0) + + # All others will fail on allocation. + else: + getattr(select, struct)().close() + return True + except (OSError, AttributeError) as e: + return False + + +# Choose the best implementation, roughly: +# kqueue == epoll > poll > select. Devpoll not supported. (See above) +# select() also can't accept a FD > FD_SETSIZE (usually around 1024) +def DefaultSelector(): + """ This function serves as a first call for DefaultSelector to + detect if the select module is being monkey-patched incorrectly + by eventlet, greenlet, and preserve proper behavior. """ + global _DEFAULT_SELECTOR + if _DEFAULT_SELECTOR is None: + if _can_allocate('kqueue'): + _DEFAULT_SELECTOR = KqueueSelector + elif _can_allocate('epoll'): + _DEFAULT_SELECTOR = EpollSelector + elif _can_allocate('poll'): + _DEFAULT_SELECTOR = PollSelector + elif hasattr(select, 'select'): + _DEFAULT_SELECTOR = SelectSelector + else: # Platform-specific: AppEngine + raise ValueError('Platform does not have a selector') + return _DEFAULT_SELECTOR() diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/ssl_.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/ssl_.py new file mode 100644 index 0000000..dafc75b --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/ssl_.py @@ -0,0 +1,341 @@ +from __future__ import absolute_import +import errno +import warnings +import hmac + +from binascii import hexlify, unhexlify +from hashlib import md5, sha1, sha256 + +from ..exceptions import SSLError, InsecurePlatformWarning, SNIMissingWarning + + +SSLContext = None +HAS_SNI = False +IS_PYOPENSSL = False +IS_SECURETRANSPORT = False + +# Maps the length of a digest to a possible hash function producing this digest +HASHFUNC_MAP = { + 32: md5, + 40: sha1, + 64: sha256, +} + + +def _const_compare_digest_backport(a, b): + """ + Compare two digests of equal length in constant time. + + The digests must be of type str/bytes. + Returns True if the digests match, and False otherwise. + """ + result = abs(len(a) - len(b)) + for l, r in zip(bytearray(a), bytearray(b)): + result |= l ^ r + return result == 0 + + +_const_compare_digest = getattr(hmac, 'compare_digest', + _const_compare_digest_backport) + + +try: # Test for SSL features + import ssl + from ssl import wrap_socket, CERT_NONE, PROTOCOL_SSLv23 + from ssl import HAS_SNI # Has SNI? +except ImportError: + pass + + +try: + from ssl import OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION +except ImportError: + OP_NO_SSLv2, OP_NO_SSLv3 = 0x1000000, 0x2000000 + OP_NO_COMPRESSION = 0x20000 + +# A secure default. +# Sources for more information on TLS ciphers: +# +# - https://wiki.mozilla.org/Security/Server_Side_TLS +# - https://www.ssllabs.com/projects/best-practices/index.html +# - https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ +# +# The general intent is: +# - Prefer TLS 1.3 cipher suites +# - prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE), +# - prefer ECDHE over DHE for better performance, +# - prefer any AES-GCM and ChaCha20 over any AES-CBC for better performance and +# security, +# - prefer AES-GCM over ChaCha20 because hardware-accelerated AES is common, +# - disable NULL authentication, MD5 MACs and DSS for security reasons. +DEFAULT_CIPHERS = ':'.join([ + 'TLS13-AES-256-GCM-SHA384', + 'TLS13-CHACHA20-POLY1305-SHA256', + 'TLS13-AES-128-GCM-SHA256', + 'ECDH+AESGCM', + 'ECDH+CHACHA20', + 'DH+AESGCM', + 'DH+CHACHA20', + 'ECDH+AES256', + 'DH+AES256', + 'ECDH+AES128', + 'DH+AES', + 'RSA+AESGCM', + 'RSA+AES', + '!aNULL', + '!eNULL', + '!MD5', +]) + +try: + from ssl import SSLContext # Modern SSL? +except ImportError: + import sys + + class SSLContext(object): # Platform-specific: Python 2 & 3.1 + supports_set_ciphers = ((2, 7) <= sys.version_info < (3,) or + (3, 2) <= sys.version_info) + + def __init__(self, protocol_version): + self.protocol = protocol_version + # Use default values from a real SSLContext + self.check_hostname = False + self.verify_mode = ssl.CERT_NONE + self.ca_certs = None + self.options = 0 + self.certfile = None + self.keyfile = None + self.ciphers = None + + def load_cert_chain(self, certfile, keyfile): + self.certfile = certfile + self.keyfile = keyfile + + def load_verify_locations(self, cafile=None, capath=None): + self.ca_certs = cafile + + if capath is not None: + raise SSLError("CA directories not supported in older Pythons") + + def set_ciphers(self, cipher_suite): + if not self.supports_set_ciphers: + raise TypeError( + 'Your version of Python does not support setting ' + 'a custom cipher suite. Please upgrade to Python ' + '2.7, 3.2, or later if you need this functionality.' + ) + self.ciphers = cipher_suite + + def wrap_socket(self, socket, server_hostname=None, server_side=False): + warnings.warn( + 'A true SSLContext object is not available. This prevents ' + 'urllib3 from configuring SSL appropriately and may cause ' + 'certain SSL connections to fail. You can upgrade to a newer ' + 'version of Python to solve this. For more information, see ' + 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' + '#ssl-warnings', + InsecurePlatformWarning + ) + kwargs = { + 'keyfile': self.keyfile, + 'certfile': self.certfile, + 'ca_certs': self.ca_certs, + 'cert_reqs': self.verify_mode, + 'ssl_version': self.protocol, + 'server_side': server_side, + } + if self.supports_set_ciphers: # Platform-specific: Python 2.7+ + return wrap_socket(socket, ciphers=self.ciphers, **kwargs) + else: # Platform-specific: Python 2.6 + return wrap_socket(socket, **kwargs) + + +def assert_fingerprint(cert, fingerprint): + """ + Checks if given fingerprint matches the supplied certificate. + + :param cert: + Certificate as bytes object. + :param fingerprint: + Fingerprint as string of hexdigits, can be interspersed by colons. + """ + + fingerprint = fingerprint.replace(':', '').lower() + digest_length = len(fingerprint) + hashfunc = HASHFUNC_MAP.get(digest_length) + if not hashfunc: + raise SSLError( + 'Fingerprint of invalid length: {0}'.format(fingerprint)) + + # We need encode() here for py32; works on py2 and p33. + fingerprint_bytes = unhexlify(fingerprint.encode()) + + cert_digest = hashfunc(cert).digest() + + if not _const_compare_digest(cert_digest, fingerprint_bytes): + raise SSLError('Fingerprints did not match. Expected "{0}", got "{1}".' + .format(fingerprint, hexlify(cert_digest))) + + +def resolve_cert_reqs(candidate): + """ + Resolves the argument to a numeric constant, which can be passed to + the wrap_socket function/method from the ssl module. + Defaults to :data:`ssl.CERT_NONE`. + If given a string it is assumed to be the name of the constant in the + :mod:`ssl` module or its abbrevation. + (So you can specify `REQUIRED` instead of `CERT_REQUIRED`. + If it's neither `None` nor a string we assume it is already the numeric + constant which can directly be passed to wrap_socket. + """ + if candidate is None: + return CERT_NONE + + if isinstance(candidate, str): + res = getattr(ssl, candidate, None) + if res is None: + res = getattr(ssl, 'CERT_' + candidate) + return res + + return candidate + + +def resolve_ssl_version(candidate): + """ + like resolve_cert_reqs + """ + if candidate is None: + return PROTOCOL_SSLv23 + + if isinstance(candidate, str): + res = getattr(ssl, candidate, None) + if res is None: + res = getattr(ssl, 'PROTOCOL_' + candidate) + return res + + return candidate + + +def create_urllib3_context(ssl_version=None, cert_reqs=None, + options=None, ciphers=None): + """All arguments have the same meaning as ``ssl_wrap_socket``. + + By default, this function does a lot of the same work that + ``ssl.create_default_context`` does on Python 3.4+. It: + + - Disables SSLv2, SSLv3, and compression + - Sets a restricted set of server ciphers + + If you wish to enable SSLv3, you can do:: + + from pip._vendor.urllib3.util import ssl_ + context = ssl_.create_urllib3_context() + context.options &= ~ssl_.OP_NO_SSLv3 + + You can do the same to enable compression (substituting ``COMPRESSION`` + for ``SSLv3`` in the last line above). + + :param ssl_version: + The desired protocol version to use. This will default to + PROTOCOL_SSLv23 which will negotiate the highest protocol that both + the server and your installation of OpenSSL support. + :param cert_reqs: + Whether to require the certificate verification. This defaults to + ``ssl.CERT_REQUIRED``. + :param options: + Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``, + ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``. + :param ciphers: + Which cipher suites to allow the server to select. + :returns: + Constructed SSLContext object with specified options + :rtype: SSLContext + """ + context = SSLContext(ssl_version or ssl.PROTOCOL_SSLv23) + + # Setting the default here, as we may have no ssl module on import + cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs + + if options is None: + options = 0 + # SSLv2 is easily broken and is considered harmful and dangerous + options |= OP_NO_SSLv2 + # SSLv3 has several problems and is now dangerous + options |= OP_NO_SSLv3 + # Disable compression to prevent CRIME attacks for OpenSSL 1.0+ + # (issue #309) + options |= OP_NO_COMPRESSION + + context.options |= options + + if getattr(context, 'supports_set_ciphers', True): # Platform-specific: Python 2.6 + context.set_ciphers(ciphers or DEFAULT_CIPHERS) + + context.verify_mode = cert_reqs + if getattr(context, 'check_hostname', None) is not None: # Platform-specific: Python 3.2 + # We do our own verification, including fingerprints and alternative + # hostnames. So disable it here + context.check_hostname = False + return context + + +def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, + ca_certs=None, server_hostname=None, + ssl_version=None, ciphers=None, ssl_context=None, + ca_cert_dir=None): + """ + All arguments except for server_hostname, ssl_context, and ca_cert_dir have + the same meaning as they do when using :func:`ssl.wrap_socket`. + + :param server_hostname: + When SNI is supported, the expected hostname of the certificate + :param ssl_context: + A pre-made :class:`SSLContext` object. If none is provided, one will + be created using :func:`create_urllib3_context`. + :param ciphers: + A string of ciphers we wish the client to support. This is not + supported on Python 2.6 as the ssl module does not support it. + :param ca_cert_dir: + A directory containing CA certificates in multiple separate files, as + supported by OpenSSL's -CApath flag or the capath argument to + SSLContext.load_verify_locations(). + """ + context = ssl_context + if context is None: + # Note: This branch of code and all the variables in it are no longer + # used by urllib3 itself. We should consider deprecating and removing + # this code. + context = create_urllib3_context(ssl_version, cert_reqs, + ciphers=ciphers) + + if ca_certs or ca_cert_dir: + try: + context.load_verify_locations(ca_certs, ca_cert_dir) + except IOError as e: # Platform-specific: Python 2.6, 2.7, 3.2 + raise SSLError(e) + # Py33 raises FileNotFoundError which subclasses OSError + # These are not equivalent unless we check the errno attribute + except OSError as e: # Platform-specific: Python 3.3 and beyond + if e.errno == errno.ENOENT: + raise SSLError(e) + raise + elif getattr(context, 'load_default_certs', None) is not None: + # try to load OS default certs; works well on Windows (require Python3.4+) + context.load_default_certs() + + if certfile: + context.load_cert_chain(certfile, keyfile) + if HAS_SNI: # Platform-specific: OpenSSL with enabled SNI + return context.wrap_socket(sock, server_hostname=server_hostname) + + warnings.warn( + 'An HTTPS request has been made, but the SNI (Subject Name ' + 'Indication) extension to TLS is not available on this platform. ' + 'This may cause the server to present an incorrect TLS ' + 'certificate, which can cause validation failures. You can upgrade to ' + 'a newer version of Python to solve this. For more information, see ' + 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' + '#ssl-warnings', + SNIMissingWarning + ) + return context.wrap_socket(sock) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/timeout.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/timeout.py new file mode 100644 index 0000000..cec817e --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/timeout.py @@ -0,0 +1,242 @@ +from __future__ import absolute_import +# The default socket timeout, used by httplib to indicate that no timeout was +# specified by the user +from socket import _GLOBAL_DEFAULT_TIMEOUT +import time + +from ..exceptions import TimeoutStateError + +# A sentinel value to indicate that no timeout was specified by the user in +# urllib3 +_Default = object() + + +# Use time.monotonic if available. +current_time = getattr(time, "monotonic", time.time) + + +class Timeout(object): + """ Timeout configuration. + + Timeouts can be defined as a default for a pool:: + + timeout = Timeout(connect=2.0, read=7.0) + http = PoolManager(timeout=timeout) + response = http.request('GET', 'http://example.com/') + + Or per-request (which overrides the default for the pool):: + + response = http.request('GET', 'http://example.com/', timeout=Timeout(10)) + + Timeouts can be disabled by setting all the parameters to ``None``:: + + no_timeout = Timeout(connect=None, read=None) + response = http.request('GET', 'http://example.com/, timeout=no_timeout) + + + :param total: + This combines the connect and read timeouts into one; the read timeout + will be set to the time leftover from the connect attempt. In the + event that both a connect timeout and a total are specified, or a read + timeout and a total are specified, the shorter timeout will be applied. + + Defaults to None. + + :type total: integer, float, or None + + :param connect: + The maximum amount of time to wait for a connection attempt to a server + to succeed. Omitting the parameter will default the connect timeout to + the system default, probably `the global default timeout in socket.py + <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. + None will set an infinite timeout for connection attempts. + + :type connect: integer, float, or None + + :param read: + The maximum amount of time to wait between consecutive + read operations for a response from the server. Omitting + the parameter will default the read timeout to the system + default, probably `the global default timeout in socket.py + <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. + None will set an infinite timeout. + + :type read: integer, float, or None + + .. note:: + + Many factors can affect the total amount of time for urllib3 to return + an HTTP response. + + For example, Python's DNS resolver does not obey the timeout specified + on the socket. Other factors that can affect total request time include + high CPU load, high swap, the program running at a low priority level, + or other behaviors. + + In addition, the read and total timeouts only measure the time between + read operations on the socket connecting the client and the server, + not the total amount of time for the request to return a complete + response. For most requests, the timeout is raised because the server + has not sent the first byte in the specified time. This is not always + the case; if a server streams one byte every fifteen seconds, a timeout + of 20 seconds will not trigger, even though the request will take + several minutes to complete. + + If your goal is to cut off any request after a set amount of wall clock + time, consider having a second "watcher" thread to cut off a slow + request. + """ + + #: A sentinel object representing the default timeout value + DEFAULT_TIMEOUT = _GLOBAL_DEFAULT_TIMEOUT + + def __init__(self, total=None, connect=_Default, read=_Default): + self._connect = self._validate_timeout(connect, 'connect') + self._read = self._validate_timeout(read, 'read') + self.total = self._validate_timeout(total, 'total') + self._start_connect = None + + def __str__(self): + return '%s(connect=%r, read=%r, total=%r)' % ( + type(self).__name__, self._connect, self._read, self.total) + + @classmethod + def _validate_timeout(cls, value, name): + """ Check that a timeout attribute is valid. + + :param value: The timeout value to validate + :param name: The name of the timeout attribute to validate. This is + used to specify in error messages. + :return: The validated and casted version of the given value. + :raises ValueError: If it is a numeric value less than or equal to + zero, or the type is not an integer, float, or None. + """ + if value is _Default: + return cls.DEFAULT_TIMEOUT + + if value is None or value is cls.DEFAULT_TIMEOUT: + return value + + if isinstance(value, bool): + raise ValueError("Timeout cannot be a boolean value. It must " + "be an int, float or None.") + try: + float(value) + except (TypeError, ValueError): + raise ValueError("Timeout value %s was %s, but it must be an " + "int, float or None." % (name, value)) + + try: + if value <= 0: + raise ValueError("Attempted to set %s timeout to %s, but the " + "timeout cannot be set to a value less " + "than or equal to 0." % (name, value)) + except TypeError: # Python 3 + raise ValueError("Timeout value %s was %s, but it must be an " + "int, float or None." % (name, value)) + + return value + + @classmethod + def from_float(cls, timeout): + """ Create a new Timeout from a legacy timeout value. + + The timeout value used by httplib.py sets the same timeout on the + connect(), and recv() socket requests. This creates a :class:`Timeout` + object that sets the individual timeouts to the ``timeout`` value + passed to this function. + + :param timeout: The legacy timeout value. + :type timeout: integer, float, sentinel default object, or None + :return: Timeout object + :rtype: :class:`Timeout` + """ + return Timeout(read=timeout, connect=timeout) + + def clone(self): + """ Create a copy of the timeout object + + Timeout properties are stored per-pool but each request needs a fresh + Timeout object to ensure each one has its own start/stop configured. + + :return: a copy of the timeout object + :rtype: :class:`Timeout` + """ + # We can't use copy.deepcopy because that will also create a new object + # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to + # detect the user default. + return Timeout(connect=self._connect, read=self._read, + total=self.total) + + def start_connect(self): + """ Start the timeout clock, used during a connect() attempt + + :raises urllib3.exceptions.TimeoutStateError: if you attempt + to start a timer that has been started already. + """ + if self._start_connect is not None: + raise TimeoutStateError("Timeout timer has already been started.") + self._start_connect = current_time() + return self._start_connect + + def get_connect_duration(self): + """ Gets the time elapsed since the call to :meth:`start_connect`. + + :return: Elapsed time. + :rtype: float + :raises urllib3.exceptions.TimeoutStateError: if you attempt + to get duration for a timer that hasn't been started. + """ + if self._start_connect is None: + raise TimeoutStateError("Can't get connect duration for timer " + "that has not started.") + return current_time() - self._start_connect + + @property + def connect_timeout(self): + """ Get the value to use when setting a connection timeout. + + This will be a positive float or integer, the value None + (never timeout), or the default system timeout. + + :return: Connect timeout. + :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None + """ + if self.total is None: + return self._connect + + if self._connect is None or self._connect is self.DEFAULT_TIMEOUT: + return self.total + + return min(self._connect, self.total) + + @property + def read_timeout(self): + """ Get the value for the read timeout. + + This assumes some time has elapsed in the connection timeout and + computes the read timeout appropriately. + + If self.total is set, the read timeout is dependent on the amount of + time taken by the connect timeout. If the connection time has not been + established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be + raised. + + :return: Value to use for the read timeout. + :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None + :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect` + has not yet been called on this object. + """ + if (self.total is not None and + self.total is not self.DEFAULT_TIMEOUT and + self._read is not None and + self._read is not self.DEFAULT_TIMEOUT): + # In case the connect timeout has not yet been established. + if self._start_connect is None: + return self._read + return max(0, min(self.total - self.get_connect_duration(), + self._read)) + elif self.total is not None and self.total is not self.DEFAULT_TIMEOUT: + return max(0, self.total - self.get_connect_duration()) + else: + return self._read diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/url.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/url.py new file mode 100644 index 0000000..6b6f996 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/url.py @@ -0,0 +1,230 @@ +from __future__ import absolute_import +from collections import namedtuple + +from ..exceptions import LocationParseError + + +url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment'] + +# We only want to normalize urls with an HTTP(S) scheme. +# urllib3 infers URLs without a scheme (None) to be http. +NORMALIZABLE_SCHEMES = ('http', 'https', None) + + +class Url(namedtuple('Url', url_attrs)): + """ + Datastructure for representing an HTTP URL. Used as a return value for + :func:`parse_url`. Both the scheme and host are normalized as they are + both case-insensitive according to RFC 3986. + """ + __slots__ = () + + def __new__(cls, scheme=None, auth=None, host=None, port=None, path=None, + query=None, fragment=None): + if path and not path.startswith('/'): + path = '/' + path + if scheme: + scheme = scheme.lower() + if host and scheme in NORMALIZABLE_SCHEMES: + host = host.lower() + return super(Url, cls).__new__(cls, scheme, auth, host, port, path, + query, fragment) + + @property + def hostname(self): + """For backwards-compatibility with urlparse. We're nice like that.""" + return self.host + + @property + def request_uri(self): + """Absolute path including the query string.""" + uri = self.path or '/' + + if self.query is not None: + uri += '?' + self.query + + return uri + + @property + def netloc(self): + """Network location including host and port""" + if self.port: + return '%s:%d' % (self.host, self.port) + return self.host + + @property + def url(self): + """ + Convert self into a url + + This function should more or less round-trip with :func:`.parse_url`. The + returned url may not be exactly the same as the url inputted to + :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls + with a blank port will have : removed). + + Example: :: + + >>> U = parse_url('http://google.com/mail/') + >>> U.url + 'http://google.com/mail/' + >>> Url('http', 'username:password', 'host.com', 80, + ... '/path', 'query', 'fragment').url + 'http://username:password@host.com:80/path?query#fragment' + """ + scheme, auth, host, port, path, query, fragment = self + url = '' + + # We use "is not None" we want things to happen with empty strings (or 0 port) + if scheme is not None: + url += scheme + '://' + if auth is not None: + url += auth + '@' + if host is not None: + url += host + if port is not None: + url += ':' + str(port) + if path is not None: + url += path + if query is not None: + url += '?' + query + if fragment is not None: + url += '#' + fragment + + return url + + def __str__(self): + return self.url + + +def split_first(s, delims): + """ + Given a string and an iterable of delimiters, split on the first found + delimiter. Return two split parts and the matched delimiter. + + If not found, then the first part is the full input string. + + Example:: + + >>> split_first('foo/bar?baz', '?/=') + ('foo', 'bar?baz', '/') + >>> split_first('foo/bar?baz', '123') + ('foo/bar?baz', '', None) + + Scales linearly with number of delims. Not ideal for large number of delims. + """ + min_idx = None + min_delim = None + for d in delims: + idx = s.find(d) + if idx < 0: + continue + + if min_idx is None or idx < min_idx: + min_idx = idx + min_delim = d + + if min_idx is None or min_idx < 0: + return s, '', None + + return s[:min_idx], s[min_idx + 1:], min_delim + + +def parse_url(url): + """ + Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is + performed to parse incomplete urls. Fields not provided will be None. + + Partly backwards-compatible with :mod:`urlparse`. + + Example:: + + >>> parse_url('http://google.com/mail/') + Url(scheme='http', host='google.com', port=None, path='/mail/', ...) + >>> parse_url('google.com:80') + Url(scheme=None, host='google.com', port=80, path=None, ...) + >>> parse_url('/foo?bar') + Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...) + """ + + # While this code has overlap with stdlib's urlparse, it is much + # simplified for our needs and less annoying. + # Additionally, this implementations does silly things to be optimal + # on CPython. + + if not url: + # Empty + return Url() + + scheme = None + auth = None + host = None + port = None + path = None + fragment = None + query = None + + # Scheme + if '://' in url: + scheme, url = url.split('://', 1) + + # Find the earliest Authority Terminator + # (http://tools.ietf.org/html/rfc3986#section-3.2) + url, path_, delim = split_first(url, ['/', '?', '#']) + + if delim: + # Reassemble the path + path = delim + path_ + + # Auth + if '@' in url: + # Last '@' denotes end of auth part + auth, url = url.rsplit('@', 1) + + # IPv6 + if url and url[0] == '[': + host, url = url.split(']', 1) + host += ']' + + # Port + if ':' in url: + _host, port = url.split(':', 1) + + if not host: + host = _host + + if port: + # If given, ports must be integers. No whitespace, no plus or + # minus prefixes, no non-integer digits such as ^2 (superscript). + if not port.isdigit(): + raise LocationParseError(url) + try: + port = int(port) + except ValueError: + raise LocationParseError(url) + else: + # Blank ports are cool, too. (rfc3986#section-3.2.3) + port = None + + elif not host and url: + host = url + + if not path: + return Url(scheme, auth, host, port, path, query, fragment) + + # Fragment + if '#' in path: + path, fragment = path.split('#', 1) + + # Query + if '?' in path: + path, query = path.split('?', 1) + + return Url(scheme, auth, host, port, path, query, fragment) + + +def get_host(url): + """ + Deprecated. Use :func:`parse_url` instead. + """ + p = parse_url(url) + return p.scheme or 'http', p.hostname, p.port diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/wait.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/wait.py new file mode 100644 index 0000000..cb396e5 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/wait.py @@ -0,0 +1,40 @@ +from .selectors import ( + HAS_SELECT, + DefaultSelector, + EVENT_READ, + EVENT_WRITE +) + + +def _wait_for_io_events(socks, events, timeout=None): + """ Waits for IO events to be available from a list of sockets + or optionally a single socket if passed in. Returns a list of + sockets that can be interacted with immediately. """ + if not HAS_SELECT: + raise ValueError('Platform does not have a selector') + if not isinstance(socks, list): + # Probably just a single socket. + if hasattr(socks, "fileno"): + socks = [socks] + # Otherwise it might be a non-list iterable. + else: + socks = list(socks) + with DefaultSelector() as selector: + for sock in socks: + selector.register(sock, events) + return [key[0].fileobj for key in + selector.select(timeout) if key[1] & events] + + +def wait_for_read(socks, timeout=None): + """ Waits for reading to be available from a list of sockets + or optionally a single socket if passed in. Returns a list of + sockets that can be read from immediately. """ + return _wait_for_io_events(socks, EVENT_READ, timeout) + + +def wait_for_write(socks, timeout=None): + """ Waits for writing to be available from a list of sockets + or optionally a single socket if passed in. Returns a list of + sockets that can be written to immediately. """ + return _wait_for_io_events(socks, EVENT_WRITE, timeout) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/__init__.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/__init__.py new file mode 100644 index 0000000..d21d697 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/__init__.py @@ -0,0 +1,342 @@ +# coding: utf-8 +""" + + webencodings + ~~~~~~~~~~~~ + + This is a Python implementation of the `WHATWG Encoding standard + <http://encoding.spec.whatwg.org/>`. See README for details. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +from __future__ import unicode_literals + +import codecs + +from .labels import LABELS + + +VERSION = '0.5.1' + + +# Some names in Encoding are not valid Python aliases. Remap these. +PYTHON_NAMES = { + 'iso-8859-8-i': 'iso-8859-8', + 'x-mac-cyrillic': 'mac-cyrillic', + 'macintosh': 'mac-roman', + 'windows-874': 'cp874'} + +CACHE = {} + + +def ascii_lower(string): + r"""Transform (only) ASCII letters to lower case: A-Z is mapped to a-z. + + :param string: An Unicode string. + :returns: A new Unicode string. + + This is used for `ASCII case-insensitive + <http://encoding.spec.whatwg.org/#ascii-case-insensitive>`_ + matching of encoding labels. + The same matching is also used, among other things, + for `CSS keywords <http://dev.w3.org/csswg/css-values/#keywords>`_. + + This is different from the :meth:`~py:str.lower` method of Unicode strings + which also affect non-ASCII characters, + sometimes mapping them into the ASCII range: + + >>> keyword = u'Bac\N{KELVIN SIGN}ground' + >>> assert keyword.lower() == u'background' + >>> assert ascii_lower(keyword) != keyword.lower() + >>> assert ascii_lower(keyword) == u'bac\N{KELVIN SIGN}ground' + + """ + # This turns out to be faster than unicode.translate() + return string.encode('utf8').lower().decode('utf8') + + +def lookup(label): + """ + Look for an encoding by its label. + This is the spec’s `get an encoding + <http://encoding.spec.whatwg.org/#concept-encoding-get>`_ algorithm. + Supported labels are listed there. + + :param label: A string. + :returns: + An :class:`Encoding` object, or :obj:`None` for an unknown label. + + """ + # Only strip ASCII whitespace: U+0009, U+000A, U+000C, U+000D, and U+0020. + label = ascii_lower(label.strip('\t\n\f\r ')) + name = LABELS.get(label) + if name is None: + return None + encoding = CACHE.get(name) + if encoding is None: + if name == 'x-user-defined': + from .x_user_defined import codec_info + else: + python_name = PYTHON_NAMES.get(name, name) + # Any python_name value that gets to here should be valid. + codec_info = codecs.lookup(python_name) + encoding = Encoding(name, codec_info) + CACHE[name] = encoding + return encoding + + +def _get_encoding(encoding_or_label): + """ + Accept either an encoding object or label. + + :param encoding: An :class:`Encoding` object or a label string. + :returns: An :class:`Encoding` object. + :raises: :exc:`~exceptions.LookupError` for an unknown label. + + """ + if hasattr(encoding_or_label, 'codec_info'): + return encoding_or_label + + encoding = lookup(encoding_or_label) + if encoding is None: + raise LookupError('Unknown encoding label: %r' % encoding_or_label) + return encoding + + +class Encoding(object): + """Reresents a character encoding such as UTF-8, + that can be used for decoding or encoding. + + .. attribute:: name + + Canonical name of the encoding + + .. attribute:: codec_info + + The actual implementation of the encoding, + a stdlib :class:`~codecs.CodecInfo` object. + See :func:`codecs.register`. + + """ + def __init__(self, name, codec_info): + self.name = name + self.codec_info = codec_info + + def __repr__(self): + return '<Encoding %s>' % self.name + + +#: The UTF-8 encoding. Should be used for new content and formats. +UTF8 = lookup('utf-8') + +_UTF16LE = lookup('utf-16le') +_UTF16BE = lookup('utf-16be') + + +def decode(input, fallback_encoding, errors='replace'): + """ + Decode a single string. + + :param input: A byte string + :param fallback_encoding: + An :class:`Encoding` object or a label string. + The encoding to use if :obj:`input` does note have a BOM. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :return: + A ``(output, encoding)`` tuple of an Unicode string + and an :obj:`Encoding`. + + """ + # Fail early if `encoding` is an invalid label. + fallback_encoding = _get_encoding(fallback_encoding) + bom_encoding, input = _detect_bom(input) + encoding = bom_encoding or fallback_encoding + return encoding.codec_info.decode(input, errors)[0], encoding + + +def _detect_bom(input): + """Return (bom_encoding, input), with any BOM removed from the input.""" + if input.startswith(b'\xFF\xFE'): + return _UTF16LE, input[2:] + if input.startswith(b'\xFE\xFF'): + return _UTF16BE, input[2:] + if input.startswith(b'\xEF\xBB\xBF'): + return UTF8, input[3:] + return None, input + + +def encode(input, encoding=UTF8, errors='strict'): + """ + Encode a single string. + + :param input: An Unicode string. + :param encoding: An :class:`Encoding` object or a label string. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :return: A byte string. + + """ + return _get_encoding(encoding).codec_info.encode(input, errors)[0] + + +def iter_decode(input, fallback_encoding, errors='replace'): + """ + "Pull"-based decoder. + + :param input: + An iterable of byte strings. + + The input is first consumed just enough to determine the encoding + based on the precense of a BOM, + then consumed on demand when the return value is. + :param fallback_encoding: + An :class:`Encoding` object or a label string. + The encoding to use if :obj:`input` does note have a BOM. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :returns: + An ``(output, encoding)`` tuple. + :obj:`output` is an iterable of Unicode strings, + :obj:`encoding` is the :obj:`Encoding` that is being used. + + """ + + decoder = IncrementalDecoder(fallback_encoding, errors) + generator = _iter_decode_generator(input, decoder) + encoding = next(generator) + return generator, encoding + + +def _iter_decode_generator(input, decoder): + """Return a generator that first yields the :obj:`Encoding`, + then yields output chukns as Unicode strings. + + """ + decode = decoder.decode + input = iter(input) + for chunck in input: + output = decode(chunck) + if output: + assert decoder.encoding is not None + yield decoder.encoding + yield output + break + else: + # Input exhausted without determining the encoding + output = decode(b'', final=True) + assert decoder.encoding is not None + yield decoder.encoding + if output: + yield output + return + + for chunck in input: + output = decode(chunck) + if output: + yield output + output = decode(b'', final=True) + if output: + yield output + + +def iter_encode(input, encoding=UTF8, errors='strict'): + """ + “Pull”-based encoder. + + :param input: An iterable of Unicode strings. + :param encoding: An :class:`Encoding` object or a label string. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :returns: An iterable of byte strings. + + """ + # Fail early if `encoding` is an invalid label. + encode = IncrementalEncoder(encoding, errors).encode + return _iter_encode_generator(input, encode) + + +def _iter_encode_generator(input, encode): + for chunck in input: + output = encode(chunck) + if output: + yield output + output = encode('', final=True) + if output: + yield output + + +class IncrementalDecoder(object): + """ + “Push”-based decoder. + + :param fallback_encoding: + An :class:`Encoding` object or a label string. + The encoding to use if :obj:`input` does note have a BOM. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + + """ + def __init__(self, fallback_encoding, errors='replace'): + # Fail early if `encoding` is an invalid label. + self._fallback_encoding = _get_encoding(fallback_encoding) + self._errors = errors + self._buffer = b'' + self._decoder = None + #: The actual :class:`Encoding` that is being used, + #: or :obj:`None` if that is not determined yet. + #: (Ie. if there is not enough input yet to determine + #: if there is a BOM.) + self.encoding = None # Not known yet. + + def decode(self, input, final=False): + """Decode one chunk of the input. + + :param input: A byte string. + :param final: + Indicate that no more input is available. + Must be :obj:`True` if this is the last call. + :returns: An Unicode string. + + """ + decoder = self._decoder + if decoder is not None: + return decoder(input, final) + + input = self._buffer + input + encoding, input = _detect_bom(input) + if encoding is None: + if len(input) < 3 and not final: # Not enough data yet. + self._buffer = input + return '' + else: # No BOM + encoding = self._fallback_encoding + decoder = encoding.codec_info.incrementaldecoder(self._errors).decode + self._decoder = decoder + self.encoding = encoding + return decoder(input, final) + + +class IncrementalEncoder(object): + """ + “Push”-based encoder. + + :param encoding: An :class:`Encoding` object or a label string. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + + .. method:: encode(input, final=False) + + :param input: An Unicode string. + :param final: + Indicate that no more input is available. + Must be :obj:`True` if this is the last call. + :returns: A byte string. + + """ + def __init__(self, encoding=UTF8, errors='strict'): + encoding = _get_encoding(encoding) + self.encode = encoding.codec_info.incrementalencoder(errors).encode diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/labels.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/labels.py new file mode 100644 index 0000000..29cbf91 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/labels.py @@ -0,0 +1,231 @@ +""" + + webencodings.labels + ~~~~~~~~~~~~~~~~~~~ + + Map encoding labels to their name. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +# XXX Do not edit! +# This file is automatically generated by mklabels.py + +LABELS = { + 'unicode-1-1-utf-8': 'utf-8', + 'utf-8': 'utf-8', + 'utf8': 'utf-8', + '866': 'ibm866', + 'cp866': 'ibm866', + 'csibm866': 'ibm866', + 'ibm866': 'ibm866', + 'csisolatin2': 'iso-8859-2', + 'iso-8859-2': 'iso-8859-2', + 'iso-ir-101': 'iso-8859-2', + 'iso8859-2': 'iso-8859-2', + 'iso88592': 'iso-8859-2', + 'iso_8859-2': 'iso-8859-2', + 'iso_8859-2:1987': 'iso-8859-2', + 'l2': 'iso-8859-2', + 'latin2': 'iso-8859-2', + 'csisolatin3': 'iso-8859-3', + 'iso-8859-3': 'iso-8859-3', + 'iso-ir-109': 'iso-8859-3', + 'iso8859-3': 'iso-8859-3', + 'iso88593': 'iso-8859-3', + 'iso_8859-3': 'iso-8859-3', + 'iso_8859-3:1988': 'iso-8859-3', + 'l3': 'iso-8859-3', + 'latin3': 'iso-8859-3', + 'csisolatin4': 'iso-8859-4', + 'iso-8859-4': 'iso-8859-4', + 'iso-ir-110': 'iso-8859-4', + 'iso8859-4': 'iso-8859-4', + 'iso88594': 'iso-8859-4', + 'iso_8859-4': 'iso-8859-4', + 'iso_8859-4:1988': 'iso-8859-4', + 'l4': 'iso-8859-4', + 'latin4': 'iso-8859-4', + 'csisolatincyrillic': 'iso-8859-5', + 'cyrillic': 'iso-8859-5', + 'iso-8859-5': 'iso-8859-5', + 'iso-ir-144': 'iso-8859-5', + 'iso8859-5': 'iso-8859-5', + 'iso88595': 'iso-8859-5', + 'iso_8859-5': 'iso-8859-5', + 'iso_8859-5:1988': 'iso-8859-5', + 'arabic': 'iso-8859-6', + 'asmo-708': 'iso-8859-6', + 'csiso88596e': 'iso-8859-6', + 'csiso88596i': 'iso-8859-6', + 'csisolatinarabic': 'iso-8859-6', + 'ecma-114': 'iso-8859-6', + 'iso-8859-6': 'iso-8859-6', + 'iso-8859-6-e': 'iso-8859-6', + 'iso-8859-6-i': 'iso-8859-6', + 'iso-ir-127': 'iso-8859-6', + 'iso8859-6': 'iso-8859-6', + 'iso88596': 'iso-8859-6', + 'iso_8859-6': 'iso-8859-6', + 'iso_8859-6:1987': 'iso-8859-6', + 'csisolatingreek': 'iso-8859-7', + 'ecma-118': 'iso-8859-7', + 'elot_928': 'iso-8859-7', + 'greek': 'iso-8859-7', + 'greek8': 'iso-8859-7', + 'iso-8859-7': 'iso-8859-7', + 'iso-ir-126': 'iso-8859-7', + 'iso8859-7': 'iso-8859-7', + 'iso88597': 'iso-8859-7', + 'iso_8859-7': 'iso-8859-7', + 'iso_8859-7:1987': 'iso-8859-7', + 'sun_eu_greek': 'iso-8859-7', + 'csiso88598e': 'iso-8859-8', + 'csisolatinhebrew': 'iso-8859-8', + 'hebrew': 'iso-8859-8', + 'iso-8859-8': 'iso-8859-8', + 'iso-8859-8-e': 'iso-8859-8', + 'iso-ir-138': 'iso-8859-8', + 'iso8859-8': 'iso-8859-8', + 'iso88598': 'iso-8859-8', + 'iso_8859-8': 'iso-8859-8', + 'iso_8859-8:1988': 'iso-8859-8', + 'visual': 'iso-8859-8', + 'csiso88598i': 'iso-8859-8-i', + 'iso-8859-8-i': 'iso-8859-8-i', + 'logical': 'iso-8859-8-i', + 'csisolatin6': 'iso-8859-10', + 'iso-8859-10': 'iso-8859-10', + 'iso-ir-157': 'iso-8859-10', + 'iso8859-10': 'iso-8859-10', + 'iso885910': 'iso-8859-10', + 'l6': 'iso-8859-10', + 'latin6': 'iso-8859-10', + 'iso-8859-13': 'iso-8859-13', + 'iso8859-13': 'iso-8859-13', + 'iso885913': 'iso-8859-13', + 'iso-8859-14': 'iso-8859-14', + 'iso8859-14': 'iso-8859-14', + 'iso885914': 'iso-8859-14', + 'csisolatin9': 'iso-8859-15', + 'iso-8859-15': 'iso-8859-15', + 'iso8859-15': 'iso-8859-15', + 'iso885915': 'iso-8859-15', + 'iso_8859-15': 'iso-8859-15', + 'l9': 'iso-8859-15', + 'iso-8859-16': 'iso-8859-16', + 'cskoi8r': 'koi8-r', + 'koi': 'koi8-r', + 'koi8': 'koi8-r', + 'koi8-r': 'koi8-r', + 'koi8_r': 'koi8-r', + 'koi8-u': 'koi8-u', + 'csmacintosh': 'macintosh', + 'mac': 'macintosh', + 'macintosh': 'macintosh', + 'x-mac-roman': 'macintosh', + 'dos-874': 'windows-874', + 'iso-8859-11': 'windows-874', + 'iso8859-11': 'windows-874', + 'iso885911': 'windows-874', + 'tis-620': 'windows-874', + 'windows-874': 'windows-874', + 'cp1250': 'windows-1250', + 'windows-1250': 'windows-1250', + 'x-cp1250': 'windows-1250', + 'cp1251': 'windows-1251', + 'windows-1251': 'windows-1251', + 'x-cp1251': 'windows-1251', + 'ansi_x3.4-1968': 'windows-1252', + 'ascii': 'windows-1252', + 'cp1252': 'windows-1252', + 'cp819': 'windows-1252', + 'csisolatin1': 'windows-1252', + 'ibm819': 'windows-1252', + 'iso-8859-1': 'windows-1252', + 'iso-ir-100': 'windows-1252', + 'iso8859-1': 'windows-1252', + 'iso88591': 'windows-1252', + 'iso_8859-1': 'windows-1252', + 'iso_8859-1:1987': 'windows-1252', + 'l1': 'windows-1252', + 'latin1': 'windows-1252', + 'us-ascii': 'windows-1252', + 'windows-1252': 'windows-1252', + 'x-cp1252': 'windows-1252', + 'cp1253': 'windows-1253', + 'windows-1253': 'windows-1253', + 'x-cp1253': 'windows-1253', + 'cp1254': 'windows-1254', + 'csisolatin5': 'windows-1254', + 'iso-8859-9': 'windows-1254', + 'iso-ir-148': 'windows-1254', + 'iso8859-9': 'windows-1254', + 'iso88599': 'windows-1254', + 'iso_8859-9': 'windows-1254', + 'iso_8859-9:1989': 'windows-1254', + 'l5': 'windows-1254', + 'latin5': 'windows-1254', + 'windows-1254': 'windows-1254', + 'x-cp1254': 'windows-1254', + 'cp1255': 'windows-1255', + 'windows-1255': 'windows-1255', + 'x-cp1255': 'windows-1255', + 'cp1256': 'windows-1256', + 'windows-1256': 'windows-1256', + 'x-cp1256': 'windows-1256', + 'cp1257': 'windows-1257', + 'windows-1257': 'windows-1257', + 'x-cp1257': 'windows-1257', + 'cp1258': 'windows-1258', + 'windows-1258': 'windows-1258', + 'x-cp1258': 'windows-1258', + 'x-mac-cyrillic': 'x-mac-cyrillic', + 'x-mac-ukrainian': 'x-mac-cyrillic', + 'chinese': 'gbk', + 'csgb2312': 'gbk', + 'csiso58gb231280': 'gbk', + 'gb2312': 'gbk', + 'gb_2312': 'gbk', + 'gb_2312-80': 'gbk', + 'gbk': 'gbk', + 'iso-ir-58': 'gbk', + 'x-gbk': 'gbk', + 'gb18030': 'gb18030', + 'hz-gb-2312': 'hz-gb-2312', + 'big5': 'big5', + 'big5-hkscs': 'big5', + 'cn-big5': 'big5', + 'csbig5': 'big5', + 'x-x-big5': 'big5', + 'cseucpkdfmtjapanese': 'euc-jp', + 'euc-jp': 'euc-jp', + 'x-euc-jp': 'euc-jp', + 'csiso2022jp': 'iso-2022-jp', + 'iso-2022-jp': 'iso-2022-jp', + 'csshiftjis': 'shift_jis', + 'ms_kanji': 'shift_jis', + 'shift-jis': 'shift_jis', + 'shift_jis': 'shift_jis', + 'sjis': 'shift_jis', + 'windows-31j': 'shift_jis', + 'x-sjis': 'shift_jis', + 'cseuckr': 'euc-kr', + 'csksc56011987': 'euc-kr', + 'euc-kr': 'euc-kr', + 'iso-ir-149': 'euc-kr', + 'korean': 'euc-kr', + 'ks_c_5601-1987': 'euc-kr', + 'ks_c_5601-1989': 'euc-kr', + 'ksc5601': 'euc-kr', + 'ksc_5601': 'euc-kr', + 'windows-949': 'euc-kr', + 'csiso2022kr': 'iso-2022-kr', + 'iso-2022-kr': 'iso-2022-kr', + 'utf-16be': 'utf-16be', + 'utf-16': 'utf-16le', + 'utf-16le': 'utf-16le', + 'x-user-defined': 'x-user-defined', +} diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/mklabels.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/mklabels.py new file mode 100644 index 0000000..295dc92 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/mklabels.py @@ -0,0 +1,59 @@ +""" + + webencodings.mklabels + ~~~~~~~~~~~~~~~~~~~~~ + + Regenarate the webencodings.labels module. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +import json +try: + from urllib import urlopen +except ImportError: + from urllib.request import urlopen + + +def assert_lower(string): + assert string == string.lower() + return string + + +def generate(url): + parts = ['''\ +""" + + webencodings.labels + ~~~~~~~~~~~~~~~~~~~ + + Map encoding labels to their name. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +# XXX Do not edit! +# This file is automatically generated by mklabels.py + +LABELS = { +'''] + labels = [ + (repr(assert_lower(label)).lstrip('u'), + repr(encoding['name']).lstrip('u')) + for category in json.loads(urlopen(url).read().decode('ascii')) + for encoding in category['encodings'] + for label in encoding['labels']] + max_len = max(len(label) for label, name in labels) + parts.extend( + ' %s:%s %s,\n' % (label, ' ' * (max_len - len(label)), name) + for label, name in labels) + parts.append('}') + return ''.join(parts) + + +if __name__ == '__main__': + print(generate('http://encoding.spec.whatwg.org/encodings.json')) diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/tests.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/tests.py new file mode 100644 index 0000000..e12c10d --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/tests.py @@ -0,0 +1,153 @@ +# coding: utf-8 +""" + + webencodings.tests + ~~~~~~~~~~~~~~~~~~ + + A basic test suite for Encoding. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +from __future__ import unicode_literals + +from . import (lookup, LABELS, decode, encode, iter_decode, iter_encode, + IncrementalDecoder, IncrementalEncoder, UTF8) + + +def assert_raises(exception, function, *args, **kwargs): + try: + function(*args, **kwargs) + except exception: + return + else: # pragma: no cover + raise AssertionError('Did not raise %s.' % exception) + + +def test_labels(): + assert lookup('utf-8').name == 'utf-8' + assert lookup('Utf-8').name == 'utf-8' + assert lookup('UTF-8').name == 'utf-8' + assert lookup('utf8').name == 'utf-8' + assert lookup('utf8').name == 'utf-8' + assert lookup('utf8 ').name == 'utf-8' + assert lookup(' \r\nutf8\t').name == 'utf-8' + assert lookup('u8') is None # Python label. + assert lookup('utf-8 ') is None # Non-ASCII white space. + + assert lookup('US-ASCII').name == 'windows-1252' + assert lookup('iso-8859-1').name == 'windows-1252' + assert lookup('latin1').name == 'windows-1252' + assert lookup('LATIN1').name == 'windows-1252' + assert lookup('latin-1') is None + assert lookup('LATİN1') is None # ASCII-only case insensitivity. + + +def test_all_labels(): + for label in LABELS: + assert decode(b'', label) == ('', lookup(label)) + assert encode('', label) == b'' + for repeat in [0, 1, 12]: + output, _ = iter_decode([b''] * repeat, label) + assert list(output) == [] + assert list(iter_encode([''] * repeat, label)) == [] + decoder = IncrementalDecoder(label) + assert decoder.decode(b'') == '' + assert decoder.decode(b'', final=True) == '' + encoder = IncrementalEncoder(label) + assert encoder.encode('') == b'' + assert encoder.encode('', final=True) == b'' + # All encoding names are valid labels too: + for name in set(LABELS.values()): + assert lookup(name).name == name + + +def test_invalid_label(): + assert_raises(LookupError, decode, b'\xEF\xBB\xBF\xc3\xa9', 'invalid') + assert_raises(LookupError, encode, 'é', 'invalid') + assert_raises(LookupError, iter_decode, [], 'invalid') + assert_raises(LookupError, iter_encode, [], 'invalid') + assert_raises(LookupError, IncrementalDecoder, 'invalid') + assert_raises(LookupError, IncrementalEncoder, 'invalid') + + +def test_decode(): + assert decode(b'\x80', 'latin1') == ('€', lookup('latin1')) + assert decode(b'\x80', lookup('latin1')) == ('€', lookup('latin1')) + assert decode(b'\xc3\xa9', 'utf8') == ('é', lookup('utf8')) + assert decode(b'\xc3\xa9', UTF8) == ('é', lookup('utf8')) + assert decode(b'\xc3\xa9', 'ascii') == ('é', lookup('ascii')) + assert decode(b'\xEF\xBB\xBF\xc3\xa9', 'ascii') == ('é', lookup('utf8')) # UTF-8 with BOM + + assert decode(b'\xFE\xFF\x00\xe9', 'ascii') == ('é', lookup('utf-16be')) # UTF-16-BE with BOM + assert decode(b'\xFF\xFE\xe9\x00', 'ascii') == ('é', lookup('utf-16le')) # UTF-16-LE with BOM + assert decode(b'\xFE\xFF\xe9\x00', 'ascii') == ('\ue900', lookup('utf-16be')) + assert decode(b'\xFF\xFE\x00\xe9', 'ascii') == ('\ue900', lookup('utf-16le')) + + assert decode(b'\x00\xe9', 'UTF-16BE') == ('é', lookup('utf-16be')) + assert decode(b'\xe9\x00', 'UTF-16LE') == ('é', lookup('utf-16le')) + assert decode(b'\xe9\x00', 'UTF-16') == ('é', lookup('utf-16le')) + + assert decode(b'\xe9\x00', 'UTF-16BE') == ('\ue900', lookup('utf-16be')) + assert decode(b'\x00\xe9', 'UTF-16LE') == ('\ue900', lookup('utf-16le')) + assert decode(b'\x00\xe9', 'UTF-16') == ('\ue900', lookup('utf-16le')) + + +def test_encode(): + assert encode('é', 'latin1') == b'\xe9' + assert encode('é', 'utf8') == b'\xc3\xa9' + assert encode('é', 'utf8') == b'\xc3\xa9' + assert encode('é', 'utf-16') == b'\xe9\x00' + assert encode('é', 'utf-16le') == b'\xe9\x00' + assert encode('é', 'utf-16be') == b'\x00\xe9' + + +def test_iter_decode(): + def iter_decode_to_string(input, fallback_encoding): + output, _encoding = iter_decode(input, fallback_encoding) + return ''.join(output) + assert iter_decode_to_string([], 'latin1') == '' + assert iter_decode_to_string([b''], 'latin1') == '' + assert iter_decode_to_string([b'\xe9'], 'latin1') == 'é' + assert iter_decode_to_string([b'hello'], 'latin1') == 'hello' + assert iter_decode_to_string([b'he', b'llo'], 'latin1') == 'hello' + assert iter_decode_to_string([b'hell', b'o'], 'latin1') == 'hello' + assert iter_decode_to_string([b'\xc3\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([b'\xEF\xBB\xBF\xc3\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'\xEF\xBB\xBF', b'\xc3', b'\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'\xEF\xBB\xBF', b'a', b'\xc3'], 'latin1') == 'a\uFFFD' + assert iter_decode_to_string([ + b'', b'\xEF', b'', b'', b'\xBB\xBF\xc3', b'\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([b'\xEF\xBB\xBF'], 'latin1') == '' + assert iter_decode_to_string([b'\xEF\xBB'], 'latin1') == 'ï»' + assert iter_decode_to_string([b'\xFE\xFF\x00\xe9'], 'latin1') == 'é' + assert iter_decode_to_string([b'\xFF\xFE\xe9\x00'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'', b'\xFF', b'', b'', b'\xFE\xe9', b'\x00'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'', b'h\xe9', b'llo'], 'x-user-defined') == 'h\uF7E9llo' + + +def test_iter_encode(): + assert b''.join(iter_encode([], 'latin1')) == b'' + assert b''.join(iter_encode([''], 'latin1')) == b'' + assert b''.join(iter_encode(['é'], 'latin1')) == b'\xe9' + assert b''.join(iter_encode(['', 'é', '', ''], 'latin1')) == b'\xe9' + assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16')) == b'\xe9\x00' + assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16le')) == b'\xe9\x00' + assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16be')) == b'\x00\xe9' + assert b''.join(iter_encode([ + '', 'h\uF7E9', '', 'llo'], 'x-user-defined')) == b'h\xe9llo' + + +def test_x_user_defined(): + encoded = b'2,\x0c\x0b\x1aO\xd9#\xcb\x0f\xc9\xbbt\xcf\xa8\xca' + decoded = '2,\x0c\x0b\x1aO\uf7d9#\uf7cb\x0f\uf7c9\uf7bbt\uf7cf\uf7a8\uf7ca' + encoded = b'aa' + decoded = 'aa' + assert decode(encoded, 'x-user-defined') == (decoded, lookup('x-user-defined')) + assert encode(decoded, 'x-user-defined') == encoded diff --git a/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/x_user_defined.py b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/x_user_defined.py new file mode 100644 index 0000000..d16e326 --- /dev/null +++ b/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/x_user_defined.py @@ -0,0 +1,325 @@ +# coding: utf-8 +""" + + webencodings.x_user_defined + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + An implementation of the x-user-defined encoding. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +from __future__ import unicode_literals + +import codecs + + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self, input, errors='strict'): + return codecs.charmap_encode(input, errors, encoding_table) + + def decode(self, input, errors='strict'): + return codecs.charmap_decode(input, errors, decoding_table) + + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input, self.errors, encoding_table)[0] + + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input, self.errors, decoding_table)[0] + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + + +class StreamReader(Codec, codecs.StreamReader): + pass + + +### encodings module API + +codec_info = codecs.CodecInfo( + name='x-user-defined', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, +) + + +### Decoding Table + +# Python 3: +# for c in range(256): print(' %r' % chr(c if c < 128 else c + 0xF700)) +decoding_table = ( + '\x00' + '\x01' + '\x02' + '\x03' + '\x04' + '\x05' + '\x06' + '\x07' + '\x08' + '\t' + '\n' + '\x0b' + '\x0c' + '\r' + '\x0e' + '\x0f' + '\x10' + '\x11' + '\x12' + '\x13' + '\x14' + '\x15' + '\x16' + '\x17' + '\x18' + '\x19' + '\x1a' + '\x1b' + '\x1c' + '\x1d' + '\x1e' + '\x1f' + ' ' + '!' + '"' + '#' + '$' + '%' + '&' + "'" + '(' + ')' + '*' + '+' + ',' + '-' + '.' + '/' + '0' + '1' + '2' + '3' + '4' + '5' + '6' + '7' + '8' + '9' + ':' + ';' + '<' + '=' + '>' + '?' + '@' + 'A' + 'B' + 'C' + 'D' + 'E' + 'F' + 'G' + 'H' + 'I' + 'J' + 'K' + 'L' + 'M' + 'N' + 'O' + 'P' + 'Q' + 'R' + 'S' + 'T' + 'U' + 'V' + 'W' + 'X' + 'Y' + 'Z' + '[' + '\\' + ']' + '^' + '_' + '`' + 'a' + 'b' + 'c' + 'd' + 'e' + 'f' + 'g' + 'h' + 'i' + 'j' + 'k' + 'l' + 'm' + 'n' + 'o' + 'p' + 'q' + 'r' + 's' + 't' + 'u' + 'v' + 'w' + 'x' + 'y' + 'z' + '{' + '|' + '}' + '~' + '\x7f' + '\uf780' + '\uf781' + '\uf782' + '\uf783' + '\uf784' + '\uf785' + '\uf786' + '\uf787' + '\uf788' + '\uf789' + '\uf78a' + '\uf78b' + '\uf78c' + '\uf78d' + '\uf78e' + '\uf78f' + '\uf790' + '\uf791' + '\uf792' + '\uf793' + '\uf794' + '\uf795' + '\uf796' + '\uf797' + '\uf798' + '\uf799' + '\uf79a' + '\uf79b' + '\uf79c' + '\uf79d' + '\uf79e' + '\uf79f' + '\uf7a0' + '\uf7a1' + '\uf7a2' + '\uf7a3' + '\uf7a4' + '\uf7a5' + '\uf7a6' + '\uf7a7' + '\uf7a8' + '\uf7a9' + '\uf7aa' + '\uf7ab' + '\uf7ac' + '\uf7ad' + '\uf7ae' + '\uf7af' + '\uf7b0' + '\uf7b1' + '\uf7b2' + '\uf7b3' + '\uf7b4' + '\uf7b5' + '\uf7b6' + '\uf7b7' + '\uf7b8' + '\uf7b9' + '\uf7ba' + '\uf7bb' + '\uf7bc' + '\uf7bd' + '\uf7be' + '\uf7bf' + '\uf7c0' + '\uf7c1' + '\uf7c2' + '\uf7c3' + '\uf7c4' + '\uf7c5' + '\uf7c6' + '\uf7c7' + '\uf7c8' + '\uf7c9' + '\uf7ca' + '\uf7cb' + '\uf7cc' + '\uf7cd' + '\uf7ce' + '\uf7cf' + '\uf7d0' + '\uf7d1' + '\uf7d2' + '\uf7d3' + '\uf7d4' + '\uf7d5' + '\uf7d6' + '\uf7d7' + '\uf7d8' + '\uf7d9' + '\uf7da' + '\uf7db' + '\uf7dc' + '\uf7dd' + '\uf7de' + '\uf7df' + '\uf7e0' + '\uf7e1' + '\uf7e2' + '\uf7e3' + '\uf7e4' + '\uf7e5' + '\uf7e6' + '\uf7e7' + '\uf7e8' + '\uf7e9' + '\uf7ea' + '\uf7eb' + '\uf7ec' + '\uf7ed' + '\uf7ee' + '\uf7ef' + '\uf7f0' + '\uf7f1' + '\uf7f2' + '\uf7f3' + '\uf7f4' + '\uf7f5' + '\uf7f6' + '\uf7f7' + '\uf7f8' + '\uf7f9' + '\uf7fa' + '\uf7fb' + '\uf7fc' + '\uf7fd' + '\uf7fe' + '\uf7ff' +) + +### Encoding table +encoding_table = codecs.charmap_build(decoding_table) diff --git a/lib/python3.7/site-packages/setuptools-39.1.0-py3.7.egg b/lib/python3.7/site-packages/setuptools-39.1.0-py3.7.egg new file mode 100644 index 0000000000000000000000000000000000000000..fbda8e8dc93117a8c520f295bda57885c6b06a5a GIT binary patch literal 563197 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'^EHd3i=D)v<pVlm2I?m)E9 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%0DvrH`b*o~p0=JY@)*QQle@4-K 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�^jtA9dZi8ZXrbWH&`Z-cUbZbMQa_Snit8b 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 N1EI){8xWI#{tp(+fGGd~ literal 0 HcmV?d00001 diff --git a/lib/python3.7/site-packages/setuptools.pth b/lib/python3.7/site-packages/setuptools.pth new file mode 100644 index 0000000..e8c36d4 --- /dev/null +++ b/lib/python3.7/site-packages/setuptools.pth @@ -0,0 +1 @@ +./setuptools-39.1.0-py3.7.egg diff --git a/pyvenv.cfg b/pyvenv.cfg new file mode 100644 index 0000000..15d85f6 --- /dev/null +++ b/pyvenv.cfg @@ -0,0 +1,3 @@ +home = /usr/local/bin +include-system-site-packages = false +version = 3.7.0 diff --git a/web2py/CHANGELOG b/web2py/CHANGELOG new file mode 100644 index 0000000..4869fb1 --- /dev/null +++ b/web2py/CHANGELOG @@ -0,0 +1,1726 @@ +## 2.17.1 +- pydal 18.08 +- many small bug fixes + +## 2.16.1 +- pydal 17.11 +- bootstrap 4 +- better welcome examples +- many bug fixes + +## 2.15.1-4 +- pydal 17.08 +- dropped support for python 2.6 +- dropped web shell +- experimental python 3 support +- experimental authapi for service login +- allow ajax file uploads +- more tests +- more pep8 compliance +- d3.js model visulization +- improved scheduler +- is_email support for internationalized Domain Names +- improved used of cookies with CookieJar +- SQLFORM.grid(showblobs=True) +- import JS events (added w2p.componentBegin event) +- added support for CASv3 +- allow first_name and last_name placeholders in verify_email message +- added three-quote support in markmin +- updated pg8000 driver (but we still recommend psycopg2) +- compiled views use . separator not _ separator (must recompile code) +- better serbian, french, and catalan translations +- speed improvements (refactor of compileapp and pyc caching) +- removed web shell (never worked as intended) +- allow Expose(..., follow_symlink_out=False). +- Updated fpdf to latest version +- JWT support +- import fabfile for remote deployment +- scheduler new feature: you can now specify intervals with cron +- gluon/* removed from sys.path. Applications relying on statements like e.g. + "from storage import Storage" + will need to be rewritten with + "from gluon.storage import Storage" +- tests can only be run with the usual web2py.py --run_system_tests OR with + python -m unittest -v gluon.tests on the root dir +- jQuery 3.2.1 +- PyDAL 17.07 including: + allow jsonb support for postgres + correctly configure adapters that need connection for configuration + better caching + updated IMAP adapter methods to new API + experimental suport for joinable subselects + improved Teradata support + improved mongodb support + overall refactoring + experimental support for Google Cloud SQL v2 + new pymysql driver + +## 2.14.6 + +- Increased test coverage (thanks Richard) +- Fixed some newly discovered security issues in admin: + CSRF vulnerability in admin that allows disabling apps + Brute force password attack vulnerability in admin + (thanks Narendra and Leonel) + +## 2.14.1-5 + +- fixed two major security issues that caused the examples app to leak information +- new Auth(…,host_names=[…]) to prevent host header injection +- improved scheduler +- pep8 enhancements +- many bug fixes +- restored GAE support that was broken in 2.13.* +- improved fabfile for deployment +- refactored examples with stupid.css +- new JWT implementation (experimental) +- new gluon.contrib.redis_scheduler +- myconf.get +- LDAP groups (experimental) +- .flash -> .w2p_flash +- Updated feedparser.py 5.2.1 +- Updated jQuery 1.12.2 +- welcome app now checks for version number +- Redis improvements. New syntax: + + BEFORE: + from gluon.contrib.redis_cache import RedisCache + cache.redis = RedisCache('localhost:6379',db=None, debug=True) + + NOW: + from gluon.contrib.redis_utils import RConn + from gluon.contrib.redis_cache import RedisCache + rconn = RConn() + # or RConn(host='localhost', port=6379, + # db=0, password=None, socket_timeout=None, + # socket_connect_timeout=None, .....) + # exactly as a redis.StrictRedis instance + cache.redis = RedisCache(redis_conn=rconn, debug=True) + + BEFORE: + from gluon.contrib.redis_session import RedisSession + sessiondb = RedisSession('localhost:6379',db=0, session_expiry=False) + session.connect(request, response, db = sessiondb) + + NOW: + from gluon.contrib.redis_utils import RConn + from gluon.contrib.redis_session import RedisSession + rconn = RConn() + sessiondb = RedisSession(redis_conn=rconn, session_expiry=False) + session.connect(request, response, db = sessiondb) + +Many thanks to Richard and Simone for their work and dedication. + +## 2.13.* + +- fixed a security issue in request_reset_password +- added fabfile.py +- fixed oauth2 renew token, thanks dokime7 +- fixed add_membership, del_membership, add_membership IntegrityError (when auth.enable_record_versioning) +- allow passing unicode to template render +- allow IS_NOT_IN_DB to work with custom primarykey, thanks timmyborg +- allow HttpOnly cookies +- french pluralizaiton rules, thanks Mathieu Clabaut +- fixed bug in redirect to cas service, thanks Fernando González +- allow deploying to pythonanywhere from the web2py admin that you're running locally, thanks Leonel +- better tests +- many more bug fixes + +## 2.12.1-3 + +- security fix: Validate for open redirect everywhere, not just in login() +- allow to pack invidual apps and selected files as packed exe files +- allow bulk user registration with default bulk_register_enabled=False +- allow unsorted multiword query in grid search +- better MongoDB support with newer pyDAL +- enable <app>/appadmin/manage/auth by default for user admin +- allow mail.settings.server='logging:filename' to log emails to a file +- better caching logic +- fixed order of confirm-password field +- TLS support in ldap +- prettydate can do UTC +- jquery 1.11.3 +- bootstrap 3.3.5 +- moved to codecov and enabled appveyor +- many bug fixes + +## 2.11.1 + +- Many small but significative improvements and bug fixes + +## 2.10.1-2.10.2 + +- welcome app defaults to Bootstrap 3 +- DAL -> pyDAL (thanks Giovanni, Niphlod, Paolo) + - new modular dal + - fixed problems with GAE support + - moved to full NDB support + - improved connection pooling logic +- optional cache.ram.max_ram_utilization = 90 (experimental) +- improved cache.disk logic (thanks Niphlod and Leonel) +- lots of pep8 improvements, thanks Richard +- added support for email attchments when auth.settings.server='gae' +- fixed app.yaml.example for GAE +- fixed many small issues +- many many more tests (thanks Giovanni, Niphlod, Paolo) +- upgrading static libraries (bootstrap, codemirror, jquery, etc) + +## 2.9.12 + +- Tornado HTTPS support, thanks Diego +- Modular DAL, thanks Giovanni +- Added coverage support, thanks Niphlod +- More tests, thanks Niphlod and Paolo Valleri +- Added support for show_if in readonly sqlform, thanks Paolo +- Improved scheduler, thanks Niphlod +- Email timeout support +- Made web2py's custom_import work with circular imports, thanks Jack Kuan +- Added Portuguese, Catalan, and Burmese translations +- Allow map_hyphen to work for application names, thanks Tim Nyborg +- New module appconfig.py, thanks Niphlod +- Added geospatial support to Teradata adaptor, thanks Andrew Willimott +- Many bug fixes + + + +## 2.9.6 - 2.9.10 + +- fixed support of GAE + SQL +- fixed a typo in the license of some login_methods code. It is now LGPL consistently with the rest of the web2py code. This change applied to all previous web2py versions. +- support for SAML2 (with pysaml2) +- Sphinx documentation (thanks Niphlod) +- improved scheduler (thanks Niphlod) +- increased security +- better cache.disk (thanks Leonel) +- sessions are stored in subfolders for speed +- postgres support for "INSERT ... RETURING ..." +- ldap support for Certificate Authority (thanks Maggs and Shane) +- improved support for S/Mime X.509 (thanks Gyuris) +- better welcome app +- support for Collection+JSON Hypermedia API (RESTful self documenting API) +- jQuery 1.11 +- codemirror 4.0.3 +- markdown2 2.2.3 +- memcache 1.53 +- support for the new janrain API +- new "web2py.py -G config" to make GAE configuration easier +- many small bug fixes + +## 2.9.1 - 2.9.5 + +- many small but important bug fixes +- jquery 1.11 +- codemirror 3.21, thanks Paolo Valleri +- fixed security issue with sessions in database, thanks Nathan Humphreys +- fixed security issue with persistant data in session, thanks Kiran +- fixed security issue with redirect after expired login, thanks André Kablu +- cleaner DAL and rname integration, thanks niphlod and Michele +- added mongodb and imap tests for dal, thanks Alan +- NoSQL dal tests, thanks Alan +- better docstrings, thanks Niphlod +- allow URL(...,language=...) with parametric router, thanks Jonathan +- allow non-expiration of gae-memcache, thanks crimsoncantab +- MARKMIN(...,_class='...'), thanks Luca +- better transliteration in building slugs +- autolink emails +- new Janrain API, thanks PeterQ2 +- enable admin app for GAE (experimental), thanks Alan +- many bug fixes +- invalidate function in web2py.js, thanks Paolo +- DAL(...,adapter_args=dict(engine='MyISAM')) +- todolist panel in admin editor, thanks Paolo Valleri + +## 2.8.1 + +- no more winservice (use nssm instead) +- better imap support in DAL +- db().select().as_tree() +- bootstrap 2.3.2 +- codemirror 3.19 +- improved mongoDB support, thanks Alan +- support for wiki custom render function +- Wiki(...groups=['x','y']) allows bypassing default permissions +- fixed websocket_messaging.py to support newer Tornado +- NDB support for GAE, thanks Quint +- fixed major concurrecy issue with MEMDB +- blocked generic.jsonp for security reasons +- many bug fixes, thanks Niphlod, Michele, Anthony, Tim, and many others. + +## 2.7.1 - 2.7.4 + +- jQuery 1.10.2 +- codemirror 3.18, thanks Paolo +- namespaces in T("Welcome", ns="namespace"), thanks jamarcer (experimental) +- more Auth options, thanks Charles +- more admin configuration, thanks Roberto +- new gluon.contrib.strip.StripeForm for PCI compliant payments +- webclient can hendle lists, thanks Yair +- allows SQLFORM.grid(...,ignore_common_filters=True) +- more translations, thanks Vladyslav +- better session2trash.py, works with scheduler, thanks niphlod +- fixed problem with ENABLED/DISABLED +- many bug fixes, thanks niphlod, michele, anthony, roberto, tim, and others + +## 2.6.1 - 2.6.4 + +Attention all users: For pre 2.6 applications to work with web2py >=2.6, you must copy static/js/web2py.js, controllers/appadmin.py, and views/appadmin.html from the welcome app to your own apps (all of them). + +Attention production users: The updated handlers and examples are in handlers/ and examples/. The updated ones will not override the existing ones. To use the new ones it is not sufficient to upgrade web2py, you also need to copy the desired handler/example in the root web2py/ folder. + +Attention MySQL users: The length of string fields changed from 255 to 512 bytes. If you have migrations enabled this will trigger a large migration. To prevent it, first set migrate_enabled=False, upgrade, check everything is ok, then add length=255 to your string Fields, then re-enable migrations with migrate_enabled=True if needed. + +- better directory structure: handlers/ extras/ examples/ +- better MongoDb support, thanks Alan +- better Admin editor interface, thanks Paolo, Roberto (codemirror 3), and Lightdot +- better layout.html and web2py_bootstrap.css, thanks Paolo +- refactored web2py.js makes code more readable, thanks Niphlod +- compute fields can depend on other compute(d) fields +- more functions in appadmin (/manage/auth), thanks Anthony +- support for CAST in SQL generation +- new API jQuery('#component').reload() +- new API rows.render() +- new API table.field.referent, table._references +- new API db(...).validate_and_update(...) +- new API Wiki(..., force_render=True) renders the page source again instead of using cached +- Wiki now automatically parses named component arguments @{f:a=1,b='twp',c=variable} +- auth.get_or_create_user(login=False) +- auth = Auth(crsf_protection = False) prevents creating sessions in login/register forms. +- enable multiple renderers in wiki, thanks Alan +- log messages from Auth are no longer translated (for speed and readability) +- update jQuery mobile to 1.3.1 +- reduced memory footprint by conditionally loading Tk +- faster pbkdf2 uses OpenSSL, thanks Michele +- many speed improvements, thanks Michele +- better session logic, prevents false positive when detecting session changes. +- scripts/import_static.py converts a static site to a web2py app (experimental) +- support for new http error code 451 +- profiler saves dump in dir, thanks Niphlod +- upgraded pyfpdf, thanks Mariano +- gluon/contrib/pdfinvoice.py for generating PDF invoices (assumes reportlab) +- no more double submission of forms (even without crsf protection), thanks Niphlod +- speedup for define_table, thanks Michele +- settings.cfg to admin, thanks Paolo +- many bugs fixed, thanks Niphlod, Michele, Roberto, Jonathan, and many others +- 2.6,3 specifically fixed a possible DoS vulnerability +- 2.6.4 specifically fixes major problem introduced in 2.6.1 with session logic + +## 2.5.2 + +- Web editor with tabs, thanks ilvalle + +## 2.5.1 + +- New style virtual fields in grid +- Conditional fields (experimental) ``db.table.field.show_if = db.table.otherfield==True`` or ``db.table.field.show_if = db.table.otherfiel.contains(values)`` +- auth.settings.manager_group_role="manager" enables http://.../app/appadmin/auth_manage and http://.../app/appadmin/manage for members of the "manager" group. (also experimental) +- support for POST variables in DELETE +- Fixed memory leak when using the TAG helper + + +## 2.4.7 + +- pypy support, thanks Niphlod +- more bug fixes +- ... + +## 2.4.6 + +- better tests +- new ANY_OF and IS_IPV6 validators +- new custom save option +- many small bug fixes + +## 2.4.5 + +- travis.ci integration (thanks Marc Abramowitz and Niphlod). Passes all tests (thanks Niplod). +- IS_DATE and IS_DATETIME can specify timezone + +## 2.4.1- 2.4.3 + +- 2D GEO API: geoPoint, getLine, geoPolygon +- support for 'json' field type in DAL +- schema export with db.as_json/as_xml, thanks Alan +- graph representation of models +- support for semantic versioning +- new bootstrap based admin, thanks Paolo +- improved scheduler (and change in scheduler field names), thanks Niphlod +- graphviz support added to adm, thanks Jose +- on_failure in grid +- db.table.field.abs() +- better wiki +- geoPoint, getLine, geoPolygon +- better reporting of 500 ajax errors +- better grid +- improved/fixed mongodb support +- improved parse_as_rest(patterns=...), thanks Denes +- improved IMAP DAL support, thanks Alan +- improved security when cookies in sessions +- Row.as_xml, as_json, as_dict, as_yaml thanks Alan +- smarter custom_import +- setup-ubuntu-12-04-redmine-unicorn-web2py-uwsgi-nginx.sh +- added support for motor and pulsar servers, thanks Niphlod +- added json-rpc2 support +- added pypyodbc.py driver +- allow auth.settings.ondelete='CASCADE' +- new syntax IS_EXPR(lambda value: ... +- using google for QR codes (although Graph API will be deprecated in 2015) +- upgraded fpdf to 1.7.1 +- bug fixes (including issues with calendar.js and archive tables) + +## 2.3.1 - 2.3.2 + +- new virtual fields syntax: + ``db.define_table('person',Field('name'),Field.Virtual('namey',lambda row: row.person.name+'y'))`` +- db.thing(name='Cohen',_orderby=db.thing.name), thanks Yair +- made many modules Python 3.3 friendly (compile but not tested) +- better welcome css, thanks Paolo +- jQuery 1.8.3 +- Bootstrap 2.2.2 +- Modernizr 2.6.2 (custom full options) +- integration with analyitics.js (0.2.0) +- better scheduler, thanks Niphlod +- page and media preview in wiki, thanks Niphlod +- create new auth.wiki page from slug model, thanks Nico +- conditional menus with auth.wiki(menugroups=['wiki_editor']) +- better security in grid/smartgrid +- allow LOADing multiple grids, thanks Niphlod +- auth.settings.login_onfail, thanks Yair +- better handling of session files for speed +- added heroku support (experimental) +- added rocket support for IPV6, thanks Chirs Winebrinner +- more customizable menus with MENU(li_first, li_last..) +- added support for paymentech (gluon/contrib/paymentech.py) +- fixed broken cron +- fixed possible xss with share.js +- many bug fixes. Closed more than 50 tickets since 2.2.1 + +## 2.2.1 + +- session.connect(cookie_key='secret', compression_level=9) stores sessions in cookies +- T.is_writable = False prevents T from dynamically updating langauge files +- all code is more PEP8 compliant +- better custom_importer behaviour (now works per app, is smalled and faster) +- fixed some bugs +- upgraded feedparser.py and rss2.py +- codemirror has autoresize + +## 2.1.0 + +- overall faster web2py +- when apps are deleted, a w2p copy is left in deposit folder +- change in cron (it is now disabled by default). removed -N option and introduced -Y. +- faster web2py_uuid() and request initialization logic, thanks Michele +- static asset management, thanks Niphlod +- improved mobile admin +- request.requires_https and Auth(secure=True), thanks Yarin and Niphlod +- better custom_import (works per app and is faster), thanks Michele +- redis_sesssion.py, thanks Niphlod +- allow entropy computation in IS_STRONG and web2py.js, thanks Jonathan and Niphlod +- fixed many aith.wiki problems +- support for auth.wiki(render='html') +- better welcome layout, thanks Paolo +- db.define_table(...,redefine=True) +- DAL, Row, and Rows object can now be pickled/unpickled, thanks to zombie DAL. +- admin uses codemirror +- allow syntax auth = Auth(db).define_tables() +- better auth.wiki with preview, thanks Alan +- better auth.impersonate, thanks Alan +- upgraded jQuery 1.8 +- upgraded Bootstrap 2.1 +- fixed problem with dropbox_account.py +- many fixes to cache.ram, cache.disk, memcache and gae_memcache +- cache.with_prefix(cache.ram,'prefix') +- db.table.field.epoch() counts seconds from epoch +- DAL support for SQL CASE, example: db().select(...query.case('true','false)) +- DAL(...,do_connect=False) allows faking connections +- DAL(...,auto_import=True) now retieves some fiel attributes +- mail can specify a sender: mail.send(...,sender='Mr X <%(sender)s>') +- renamed gluon/contrib/comet_messaging.py -> gluon/contrib/websocket_messaging.py + +## 2.0.1-11 + +### DAL Improvements + +- Support for DAL(lazy_tables=True) and db.define_table(on_define=lambda table:), thanks Jonathan +- db(...).select(cacheable=True) make select 30% faster +- db(...).select(cache=(cache.ram,3600)) now caches parsed data 100x faster +- db(...).count(cache=(cache.ram,3600)) now supported +- MongoDB support in DAL (experimental), thanks Mark Breedveld +- geodal and spatialite, thanks Denes and Fran (experimental) +- db.mytable._before_insert, _after_insert, _before_update, _after_update, _before_delete. _after_delete (list of callbacks) +- db(...).update_naive(...) same as update but ignores table._before_update and table._after_update +- DAL BIGINT support and DAL(...,bigint_id=True) +- IS_IN_DB(..., distinct=True) +- new syntax: db.mytable.insert(myuploadfield=open(....)), thank you Iceberg +- db(...).select(db.mytable.myfield.count(distinct=True)) +- db(db.a)._update(name=db(db.b.a==db.a.id).nested_select(db.b.id)) +- db.mytable.myfield.filter_in, filter_out +- db.mytable._enable_record_versioning(db) adds versioning to this table +- teradata adapter, thanks Andrew Willimott +- experimental Sybase Adapter +- added db.table.field.avg() +- Support for Google App Engine projections, thanks Christian +- Field(... 'upload', default=path) now accepts a path to a local file as default value, if user does not upload a file. Relative path looks inside current application folder, thanks Marin +- executesql(...,fields=,columns=) allows parsing of results in Rows, thanks Anthony +- Rows.find(lambda row: bool(), limitby=(0,1)) + +### Auth improvements + +- auth.enable_record_versioning(db) adds full versioning to all tables +- @auth.requires_login(otherwise=URL(...)) +- auth supports salt and compatible with third party data, thanks Dave Stoll +- CRYPT now defaults to pbkdf2(1000,20,sha1) +- Built-in wiki with menu, tags, search, media, permissions. def index: return auth.wiki() +- auth.settings.everybody_group_id +- allow storage of uploads on any PyFileSystem (including amazon) + +### Form improvements + +- FORM.confirm('Are you sure?',{'Back':URL(...)}) +- SQLFORM.smartdictform(dict) +- form.add_button(value,link) +- SQLFORM.grid(groupby='...') +- fixed security issue with SQLFORM.grid and SQLFORM.smartgrid +- more export options in SQLFORM.grid and SQLFORM.smartgrid (html, xml, csv, ...) + +### Admin improvements + +- new admin pages: manage_students, bulk_regsiter, and progress reports +- increased security in admin against CSRF +- experimental Git integration +- experimental OpenShift deployment +- multi-language pluralization engine +- ace text web editor in admin +- Ukrainian translations, thanks Vladyslav Kozlovskyy +- Romanian translation for welcome, thanks ionel +- support for mercurial 2.6, thanks Vlad + +### Scheduler Improvements (thanks to niphlod, ykessler, dhx, toomim) + +- web2py.py -K myapp -X starts the myapp scheduler alongside the webserver +- tasks are marked EXPIRED (if stop_time passed) +- functions with no result don't end up in scheduler_run +- more options: web2py.py -E -b -L +- scheduler can now handle 10k tasks with 20 concurrent workers and with no issues +- new params: + tasks can be found in the environment (no need to define the tasks parameter) + max_empty_runs kills the workers automatically if no new tasks are found in queue (nice for "spikes" of processing power) + discard_results to completely discard the results (if you don't need the output of the task) + utc_time enables datetime calculations with UTC time +- scheduler_task changes: + task_name is no longer required (filled automatically with function_name if found empty) + uuid makes easy to coordinate scheduler_task maintenance (filled automatically if not provided) + stop_time has no default (previously was today+1) + retry_failed to requeue automatically failed tasks + sync_output refreshes automatically the output (nice to report percentages) +- workers can be: + DISABLED (put to sleep and do nothing if not sending the heartbeat every 30 seconds) + TERMINATE (complete the current task and then die) + KILL (kill ASAP) + +### Other Improvements + +- gluon/contrib/webclient.py makes it easy to create functional tests for app +- DIV(..).elements(...replace=...), thanks Anthony +- new layout based on Twitter Bootstrap +- New generic views: generic.ics (Mac Mail Calendar) and generic.map (Google Maps) +- request.args(0,default=0, cast=int, otherwise=URL(...)), thanks Anthony +- redirect(...,type='auto') will be handled properly in ajax responses +- routes in can redirect outside with routes_in=[('/path','303->http://..')] +- better memcache support +- improved spreadsheet, thanks Alan +- new internationalization engine, thanks Vladyslav +- pluralization engine, thanks Vladyslav +- new markmin with support for nested lists, <i>, <em>, autolinks, thanks Vladyslav +- new syntax: {{=BR()*5}} +- gluon.cache.lazy_cache decorator allows caching functions in modules +- .coffee and .less support in response.files, thanks Sam Sheftel +- ldap certificate support +- pg8000 postgresql driver support (experimental) +- @cache('%(name)s%(args)s%(vars)s',5) and cache.autokey +- added tox.ini, thanks Marc +- web2py.py --run_system_tests, thanks Marc Abramowitz +- html.py (and web2py helpers) can be used without web2py dependencies +- new fpdf, thanks Mariano + + +## 1.99.5-1.99.7 +- admin in Russian (Bulat), Japanese (Omi) and Slovenian (Robert Valentak) +- included web-based debugger (experimental, thanks Mariano) +- def index(): return dict(a=gluon.tools.Expose(folder)) +- db.table.field.like(...,case_sensitive=False) (thanks Floyd) +- db.table.field.regexp(...) for sqlite and postgres +- db(...,ignore_common_filters=True) +- db(db.dog_id.belongs(db.dogs.owner=='james')).select() +- db(...).select().group_by_value(db.table.field) (thanks Yair) +- db = DAL('imap://user:password@server:port') support (thanks Alan Etkin) +- db = DAL('teradata://DSN=dsn;UID=user;PWD=pass; DATABASE=database') (thanks Adrew Willmott) +- db = DAL('mongodb://127.0.0.1:5984/db') (experimental, thanks Mark Breedveld) +- db = DAL('cubrid') (experimental) +- db = DAL('postgres:pg8000:...') and DAL('postgres:psycopg2:...') +- pg8000 now ships with web2py (thanks Mariano) +- reponse.delimiters = ('\\[','\\]') (thanks Denes) +- auth.user_groups stores user groups +- auth.is_impersonating() +- populate can now deal with computed fields (thanks Tsvi Mostovicz) +- new rediscache (thanks niphold) +- sync languages capability (thanks Yair) +- improved markmin auto-links +- improved ldap support (thanks Omi) +- added TimeCollector (thanks Caleb) +- better cpdb.py (thanks pasxidis) +- conditional menu items (reponse.menu=[(title,bool,link,[],condition)] +- scripts/services/service.py (thanks Ross) +- gluon/contrib/login_methods/browserid_account.py (thanks Pai) +- gluon/contrib/htmlmin.py for html minimization (thanks kerncece) +- web2py_component has timeout parameter, thanks Alan +- 100's of small bug fixes and small improvements + +## 1.99.4 +Improved mobile admin, thanks Angelo +Improved examples page, thanks Anthony +fixed a SQLCustomField bug + +## 1.99.3 +This is a major revision in peparation for web2py 2.0 +- moved to GitHub and abandoned Lanchpad +- new web site layout, thanks Anthony +- new welcome app using skeleton, thanks Anthony +- jQuery 1.7.1 +- modernizr 2.0.6 (customized) +- ``define_table('thing', singluar='thing',plural='things')`` +- CAS 1.0 and 2.0 compliant, thanks Olivier +- fixed validate_and_insert and validate_and_update, thanks Anthony +- ``request.user_agent().is_mobile`` etc., thanks Ross and Angelo +- better router, thanks Jonathan +- app on/off buttons +- support for dropbox_login +- improved markmin recognizes qr code, supports auto audio/video/embed +- ``response.optimize_css = 'concat,minify,inline'``, thanks Ross +- ``response.optimize_js = 'concat,minify,inline'`` thanks Ross +- ``db.define_table(...,common_filter=query)``, thanks Yair +- ``db(...,ignore_common_filter=True)`` +- support for stripe payments +- support for DowCommerce payments, thanks Dave +- experimental PyPy support +- experimental mongodb support, thanks Mark +- tickets in db now accessible from admin, thanks Niphlod + + + + +## 1.99.1-1.99.2 +- gluon/contrib/simplejsonrpc.py +- gluon/contrib/redis_cache.py +- support for A(name,callback=url,target='id',delete='tr') +- support for A(name,component=url,target='id',delete='tr') +- new pip installer, thanks Chris Steel +- isapiwsgihandler.py +- dal expression.coalesce(*options) +- gluon/contrib/simplejsonrpc.py, thanks Mariano +- expire_sessions.py respects expiration time, thanks iceberg +- addressed this issue: http://fuelyourcoding.com/jquery-events-stop-misusing-return-false/ +- x509 support (thanks Michele) +- form.process() and for.validate() +- rocket upgrade (1.2.4) +- jQuery upgrade (1.6.3) +- new syntax rows[i]('tablename.fieldname') +- new query syntax field.contains(list,all=True or False) +- new SQLFORM.grid and SQLFORM.smartgrid (should replace crud.search and crud.select) +- support for natural language queries (english only) in SQLFORM.grid +- support for computed columns and additional links in SQLFORM.grid +- new style virtual fields (experimental): db.table.field=Field.Lazy(...) +- request.utcnow +- cleaner/simpler welcome/models/db.py and welcome layout.html +- response.include_meta() and response.include_files(), thanks Denes +- dal auto-reconnect on time-out connections +- COL and COLGROUP helpers +- addresed OWASP #10, thanks Anthony and Eric +- auth.settings.login_after_registration=True +- detection of mobile devices and @mobilize helper (view.mobile.html), thanks Angelo +- experimental gluon/scheduler.py +- scripts/make_min_web2py.py +- crud.search has more options, thanks Denes +- many bug fixes (thanks Jonathan, Michele, Fran and others) + +## 1.98.1-1.98.2 +- fixed some problems with LOAD(ajax=False), thanks Anthony +- jquery 1.6.2 +- gevent.pywsgi adds ssl support, thanks Vasile +- import/export of blobs are base64 encoded +- max number of login attemts in admin, thanks Ross +- fixed joins with alias tables +- new field.custom_delete attribute +- removed resctions on large 'text fields, thanks Martin +- field.represent = lambda value,record: .... (record is optional) +- FORM.validate() and FORM.process(), thanks Bruno +- faster visrtualfields, thanks Howsec +- mail has ssl support separate from tls, thanks Eric +- TAG objects are now pickable +- new CAT tag for no tags +- request.user_agent(), thanks Ross +- fixed fawps support +- SQLFORM(...,separator=': ') now customizable +- many small bug fixes + +## 1.97.1 +- validate_and_update, thanks Bruno +- fixed problem with new custom import, thanks Mart +- fixed pyamf 0.6, thanks Alexei and Nickd +- fixed "+ =" bug in wizard +- fixed problem with allowed_patterns +- fixed problems with LOAD and vars and ajax +- closed lots of google code tickets +- checkboxes should now work with list:string +- web2py works on Android, thanks Corne Dickens +- new cpdb.py, thanks Mart +- improved translation (frech in particuler), thanks Pierre +- improved cas_auth.py, thanks Sergio +- IS_DATE and IS_DATETIME validators now work with native types +- better description of --shell, thanks Anthony +- extra SQLTABLE columns, thanks Martin +- fixed toolbar conflics, thanks Simon +- GAE password shows with **** + +## 1.96.2-1.96.4 +- bug fixes + +## 1.96.1 + +- "from gluon import *" imports in every python module a web2py environment (A, DIV,..SQLFORM, DAL, Field,...) including current.request, current.response, current.session, current.T, current.cache, thanks Jonathan. +- conditional models in + models/<controller>/a.py and models/<controller>/<function>/a.py +- from mymodule import *, looks for mymodule in applications/thisapp/modules first and then in sys.path. No more need for local_import. Thanks Pierre. +- usage of generic.* views is - by default - restricted to localhost for security. This can be changed in a granular way with: response.generic_patterns=['*']. This is a slight change of behavior for new app but a major security fix. + +- all applications have cas 2.0 provider at http://.../user/cas/login +- all applications can delegate to login to external provider Auth(...,cas_provider='http://.../other_app/default/user/cas') +- A(...,callback=URL(...),larget='id') does Ajax +- URL(...,user_signature=True), LOAD(...,user_signature=True) can sign urls and @auth.requires_signature() will check the signature for any decorated action. + +- DAL(...,migrate_enabled=False) to disable all migrations +- DAL(...,fake_migrate_all=True) to rebuild all corrupted metadata +- new DAL metadata format (databases/*.table) +- DAL(...,adapter_arg={}) allows support for alternate drivers +- DAL now allows circular table defintions +- DAL(..,auto_import=True) automatically imports tables from metadata without need to db.define_table(...)s. +- new alterante syntax for inner joins: db(...).select(join=...) +- experimental cubrid database support +- DAL 'request_tenant' fields are special, the altomatically filer all records based on their default value. +- db._common_fields.append(Field('owner')) allows to add fields to ALL tables +- DAL ignores repeated fields with same names + +- web2py_ajax.html is more modular, thanks Anthony +- request.is_local +- request.is_http +- new sessions2trash.py thanks Jim Karsten +- corrupted cache files are automatically deleted +- new simpler API gluon.contrib.AuthorizeNet.procss(...) +- fixed recaptcha (as they released new API) +- messages in validators have default internationalization +- No more Auth(globals(),db), just Auth(db). Same for Crud and Service. +- scripts/access.wsgi allows apache+mod_wsgi to delegate authentication of any URL to any web2py app +- json now supports T(...) +- scripts/setup-web2py-nginx-uwsgi-ubuntu.sh +- web2py HTTP responses now set: "X-Powered-By: web2py", thanks Bruno +- mostly fixed generic.pdf. You can view any page in PDF if you have pdflatex installed or if your html follows the pyfpdf convention. +- auth.settings.extra_fields['auth_user'].append(Field('country')) allows to extend auth_* tables without need of definiting a custom auth_* table. Must be placed before auth.define_tables() +- {{=response.toolbar()}} to help you debug applications +- web based shell now supports object modifications (but no redefinitions of non-serializable types) +- jQuery 1.6.1 +- Lots of bug fixes + + +## 1.95.1 +- Google MySQL support (experimental) +- pip support, thanks lifeeth +- better setup_exe.py, thanks meredyk +- importved pyfpdf +- domain check in email_auth.py, thanks Gyuris +- added change_password_onvalidation and change_password_onaccept +- DAL(...,migrate_enabled=True) +- login_methods/loginza.py, thanks Vladimir +- bpython shell support, thanks Arun +- request.uuid and response.uuid (for a future toolbar) +- db._timings contains database query timing info +- efficient db(...).isempty() +- setup-web2py-nginx-uwsgi-ubuntu.sh +- Many bug fixes, thanks Jonathan + +## 1.94.6 +- fixed a number of minor bugs including adding some missing files +- better session handling on session._unlock(..), thanks Jonathan +- added experimental pip support, thanks Lifeeth +- added experimental SAP DB support + +## 1.94.5 +- fixed a major bug with session introdued in 1.94.1 + +## 1.94.4 +- removed debug print statement that caused problems on GAE and mod_wsgi + +## 1.94.3 +- fixed major bug in auth redirection + +## 1.94.2 +- reverted wrong behavior of auth.requires(condition) in 1.94.1 + +## 1.94.1 +- moderniz 1.17 +- web2py no longer saves session if no change, this makes it up up to 10x faster for simple actions +- experimental REST API +- better support for MSSQL NOT NULL +- small bug fixes + +## 1.93.1-2 +- support for multiple interfaces, thanks Jonathan +- jquery 1.5.1 +- simplejson 2.1.3 +- customizable simplejson +- leaner app.yaml +- css3 buttons in welcome +- android support (experimental) +- Field(':hidden'), Field('.readonly'), Field('name=value') +- combined expressions print db.data.body.len().sum() +- wizard can download plugins +- better json serilization (object.custom_json) +- better xml serialization (object.custom_xml) +- better formstyle support +- better comet_messaging.py (needs more testing) +- many bug fixes + +## 1.92.1 +- much improved routing (thanks Jonathan) +- Expression.__mod__ (thanks Denes) +- admin has MULTI_USER_MODE (admin/models/0.py) +- support for count(distinct=...) +- has_permissions(...,group_id) +- IS_MATCH(...,strict=True) +- URL(...,scheme=,host=,port=), thanks Jonathan +- admin in Afrikaans, thanks Caleb +- auth.signature (experimental) +- many other bug fixes + +## 1.91.6 +- web2py comet via gluon/contrib/comet_messaging.py (html5 websockets) experimental +- fixed problem with services (broken in 1.91.5), thanks Vollrath +- customizable uploadwidget, thanks Fran +- fixed problem with mail unicode support, thanks Richard +- fixed problem with linkto=None and references fields in SQLTABLE, thanks villas +- no more upgrade button on windows since does not work +- better remember-me login, thanks Martin Weissenboeck +- support for recatcha options +- support for GAE namespaces via DAL('gae://namespace') +- new rocket (1.2.2), thanks Tim +- many other bug fixes and improvements (thanks Jonathan) + +## 1.91.2-1.91.5 +- fixed a problem with deplyment on GAE +- other new dal bug fixes + +## 1.91.1 +- LICENSE CHANGE FROM GPLv2 to LGPLv3 +- URL(...,hash_vars=...) allows to specify which vars need to be signed +- fixed bug with aliasing in new DAL + +## 1.90.6 +- fix issue with pickling new dal Row and Rows. + +## 1.90.5 +- set poll = False in rocket because of poll python thread bug often unfixed, thanks Jonathan +- fixes issue with crud and reCaptcha + +## 1.90.2-4 +- pymysql no longer requires ssl (if not used) +- fixed bug with virtualfields +- fixed bug in truncate (new dal) +- fixed bug in select with alternate primary key (new dal) +- fixed bug with IS_IN_DB and self refences (also new dal) + +## 1.90.1 +- new DAL (complete rewrite of the web2py DAL is more modular) +- rewrite has fail safe reload, thanks Jonathan +- better CAS with v2 support, thanks Olivier ROCH VILATO +- better markmin2latex +- session.connect(separate=True) to handle many session files, thanks huaiyu wang +- changed bahvior of impersonate (more secure, can generate form or used as API) +- new rocket, thanks Tim +- new pyfpdf +- no more old style classes +- experimental couchdb support in new dal (only insert, select, update by id) +- mysql support out of the box via pymysql +- SQLITABLE(...,headers='labels') thanks Bruno +- optional: digitally signed URLs, thanks Brian Meredyk +- minor bug fixes + +## 1.89.1-.5 +- new admin layout (thanks Branko Vukelic) +- new admin search +- new admin language selector (thanks Yair) +- new Welcome app (thanks Martin Mulone) +- better wizard +- admin support for DEMO_MODE=True +- admin exposes GAE deployment button (always) +- MENU support None links (thanks Michael Wolfe) +- web2py.py -J for running cron (thanks Jonathan Lundell) +- fixed ~db.table.id on GAE (thanks MicLee) +- service.jsonrpc supports service.JsonRpcException (thanks Matt) +- bug fixes + +## 1.88.1-2 +- better list: string support, thanks Bob +- jquery 1.4.3 +- scripts/autoroutes.py +- new admin wizard +- added retrieve_username to navbar (if username) +- internal rewrite for arbitrary paths (abspath), thanks Jonathan +- populate support for list: and decimal, thanks Chirstian +- markmin2latex has extra attribute +- better mercual admin allows list of files, versions and retrieve +- new error report system, thanks Thadeus and Selecta +- SQLFORM.accepts(detect_record_change).record_changed +- fixed cron for bytecode compiled apps, thanks Álvaro J. Iradier Muro +- other bugs fixes and pep8 compliant fixes + +## 1.87.3 +- fixed a major bug introduced in 1.87.1 that prevents appadmin from working for new apps created with 1.87.1-2. +- upgraded to clockpick 1.28, thanks villas + +## 1.87.1-2 +- new layout for examples, thanks Bruno and Martin +- admin allow ``DEMO_MODE=True`` and ``FILTER_APPS=['welcome']`` +- fixed a possible problem with CRON and paths + + +## 1.86.3 +- Error reporting on save, thanks Mariano +recalled + +## 1.86.1-1.86.3 +- markmin2latex +- markmin2pdf +- fixed some bugs +- Storage getfirst, getlast, getall by Kevin and Nathan +- db(db.table), db(db.table.id) both suported and equivalent to db(db.table.id>0) +- postresql ssl support +- less un-necessary logging and warnings on GAE +- IS_DECIMAL_IN_RANGE and IS_FLOAT_IN_RANGE support dot="," (dot="." is default) +- on_failed_authorization can be a function, thanks Niphold +- gluon/contrib/login_methods/cas_auth.py for integration between CAS and Auth. + +## 1.85.1-3 +- fixed some bugs +- added pyfpdf, thank Mariano + +## 1.84.1-4 +- flash now stays put in the top right corner +- improved behavior for URL and T objects +- new app level logging with logging.conf (thanks Jonathan) +- improved OpenID (thanks Michele) +- web2py_ajax handles prepend, append, hide (thanks Juris) +- web2py_ajax also handels pre-validation of decimal fields +- ru-ru translation (thanks Michele) +- sk-sk translation (thanks Julius) +- migrations save .table only if changed and after each ALTER TABLE (no more mysql inconsistencies) +- fixed bugs in SQLCustomField, Field(default=...), IS_IMAGE, IS_DECIMAL_IN_RANGE and a few more. +- Better validators (IS_DECIMAL_IN_RANGE, IS_INT_IN_RANGE, etc) thanks Jonatham +- Polymmodel support on GAE +- Experimental ListWidget +- moved DAL and routes to thread.local (thanks Jonathan, again) +- scripts/extract_mysql_models.py, thanks Falko Krause and Ron McOuat +- scripts/dbsessions2trash.py, thanks Scott + +## 1.83.2 +- mostly cleanup + +## 1.83.1 +- New error reporting mechanism (thanks Mariano) +- New routing system with app level routing (thanks Jonathan) +- Integrated GAE appstat and GAE precompilation (thanks Scott) +- New Field types "list:string", "list:integer", "list:reference" +- request.cid, request.ajax, A(cid=request.cid), response.js + +## 1.82.1 +- request.ajax to detect if action is called via ajax, tahnks Jonathan and David Mako +- more captcha options, thanks Vidul +- openid and oauth2 thanks Michele and Keith +- better PluginManager and load components +- new template system, thanks Thadeus +- new db.table(id,[field=value]) and db.table(query) syntax +- URL('index') (no more r=request), thanks Thadeus +- mail.send(message='<html>...</html>', ....) +- DAL([....]) for load balancing +- @service.soap(...) with mysimplesoap, thanks Mariano +- hideerror + +## 1.81.5 +- Fixed a few bugs. The most important bugs we fixed are in memcache (thanks Scott) and in a process starvation issue with Rocket (thanks Mike Ellis and Tim). + +## 1.81.4 +- Fixed gluon.tools to work work with load and base.css to nowrap labels + +## 1.81.3 +- fixed bug in label names in formstyle +- fixed id names in admin test.html page + +## 1.81.2 +- fixed bug in Auth + +## 1.81.1 +- rpx (janrain) support out of the box, allows login with Facebook, MySpace, etc. Thanks Mr Freeze +- Increased security (escape single and double quotes, thanks Craig" +- Fixed a bug with db.table.field.uploadseparate=True and autodelete +- New welcome app with superfish and jQuery 1.4.2 +- Deleted openwysiwyg from admin +- In XML and xmlescape quote defaults to True. Both ' and " are escaped. Thanks Craig Younkins + +## 1.80.1 +- MARKMIN helper (no backward compatibility promise yet) +- self._last_reference, thanks Dave (no backward compatibility promise yet) +- IS_EQUAL_TO +- zh-tw and better internationalization page, thanks Daniel Lin and Iceberg +- better crud.search, thanks MrFreeze +- Rocket interfaces, thanks Nik Klever +- db.table.field.uploadseparate=True, thanks Gyuris +- SCOPE_IDENITY for MSSQL, thanks Jose +- fixed email attachment issue, thanks Bob_in_Comox +- fixed problem with groupby and IS_IN_DB +- other bug fixes +- new implementation for local_import +- ajax(..,...,null) +- fixed Chrome bug in calendar.js, thanks Iceberg +- experimental scrips/web2py-setup-fedora.sh +- generic.load, thanks Iceberg + +## 1.79.2 +- solved simplejson imcompatibility problem + +## 1.79.1 +- x509 emails, thanks Gyuris +- attachment and html in Mail on GAE, thanks PanosJee +- fixed docstring in SQLTABLE, thanks aabelyakov +- TAG(html) parese html into helpers (experimental, still some problems with unicode, , thanks RobertVa for unicode help) +- DIV.elements(find=re.compile(....)) +- DIV.flatten() +- DIV.elements('....') supports jQuery syntax in '....' +- better it-it.py and it.py, thanks Marcello Della Longa +- Many Bug fixes: +- improved support for DAL and joins in postgresql/oracle, thanks Nico de Groot +- bux fixex in html.py, thanks Ian +- fixed an issue with registration_key==None, thanks Jay Kelkar +- fixed bug in gql.py, thanks NoNoNo +- fixed problem with multiple and checkboxes, thanks MIchael Howden +- fixed bug in gae, thanks NoNoNo +- restored 2.4 compatibility, thanks Paolo Gasparello +- auth.update() when pictures in profile +- formstyle can be a function, thanks Howden +- escape in sanitizer, thanks Howes +- add missing settings, thanks Hamdy +- find and exclude return empty Rows instead of [], thanks iceberg +- simplejson 2.1.1 should fix compatibility problems +- added sms_utils and Authorize.net in contrib + +## 1.78.3 +- reverted temporarily to old template system because of backward compatibility issues + +## 1.78.1 +- new template system allows {{block name}}{{end}}, thanks Thadeus +- fixed mime headers in emails, included PGP in emails, thanks Gyuris +- automatic database retry connect when pooling and lost connections +- OPTGROUP helper, thanks Iceberg +- web2py_ajax_trap captures all form submissions, thank you Skiros +- multicolumn checkwidget and arbitrary chars in multiple is_in_set, thanks hy +- Québécois for welcome, thanks Chris +- crud.search(), thanks Mr Freeze +- DAL(...migrate,fake_migrate), thanks Thadeus + +## 1.77.3 +- some cleanup of code in compileapp + +## 1.77.2 +- fixed x-index in calendar +## 1.77.1 +- Replaced CherryPy with Rocket web server, thanks Tim +- CacheOnDisk allows to specify a folder +- IS_DATE/DATETIME can handle any year since 0 +- SQLTABLE(...,headers='fieldname:capitalize') +- Field().with_alias, thanks Nathan and Mengu +- has_membership(group=...,role=...), thank Jonathan +- db.define_table(username=True), thanks Jonathan +- gluon.tools.prettydate +- can specify hostname in routes_out (same syntax as routes in), thanks Martin +- db.table.bulk_insert([...records...]) now works on GAE, thanks Jon +- IS_EMAIL validates on 'localhost', thanks Jonathan +- welcome/views/layout.html uses ez.css, thanks Yarko +- mail attachments support utf8, thanks szimszon +- works with PyPy, thanks Joe +- better Firebird support, thanks Jose +- better Oracle support, thanks Gabriele +- cron supports days of week +- SQLFORM(...,formstyle="table3cols") or "table2cols" or "divs" or "ul" +- crud.settings.formstyle +- web2py.py -f folder allows to specify locations of applications, thanks Iceberg +- better/faster regex in template works in Jython +- fixed lots of small bugs + +## 1.76.5 +- Fixed a typo in auth that created some registration problems + +## 1.76.4 +- SQLTABLE(db(db.auth_user.id>0).select(),headers='fieldname:capitalize') +- Oracle limitby improved (thanks Sergey) +- fixed migrations in Firebird, thanks Jose Jachuf +- gluon/contrib/login_methods/linkedin_account.py (to be tested) + +## 1.76.2-1.76.3 +- major fix in cron (will I ever get this 100% right?) +- fix in delete for GAE +- auth.settings.login_captcha and auth.settings.register_captcha +- crud.settings.create_captcha and crud.settings.update_captcha +- automatic update button in admin + +## 1.76.1 +- editarea 0.8.2 + zencoding +- new (better) cron locking meachnism +- no storing session cookies on session.forget(), thank you Alvaro +- routes_apps_raw allows disabling of request.args validation, thanks Jonathan and Denes +- fixed problem with edit_languages ad multiple tabs, thanks Iceberg +- crud captcha, thanks you Nathan +- softcron disabled by default in wsgihandler and fcgihandler + +## 1.75.5 +- fixed behaviour with languages.py, thanks Iceberg +- added chinese (thanks Iceberg) and Hungarian (thanks Gyuris) +- fixed problem with GAE deleted by id (thanks what_ho) +- fixed bug in LOAD with custom views, thanks vhang +- improved IS_IN_SET takes iterator, dict, list and list of tuples, thanks Iceberg +- Auth(...,controller='default') +- Fixed major bug in parsing repeated request.vars, thanks Ben +- IS_DATE and IS_DATETIME can now handle any 0<year +- allow to disable editarea onload, thanks Alex + +## 1.75.4 +- customizable BEAUTIFY, thanks John + +## 1.75.3 +- added support for PAM authentican for apps and for admin +- INTRODUCED MAJOR BUG IN BEAUTIFY (upgrade to 1.75.4) IMMEDIATELY + +## 1.75.2 +- fetch supports cache +- curd.update(....,onaccept=crud.archive) magic +- new UUID mechnism fixes session conflicts with cloned machine in cloud +- allow to upload app and overwrite existing old ones, thanks Jonathan +- print gluon.tools.prettydate(request.now,T), thanks Richard + +## 1.75.1 +- better cron +- better fetch +- logging of email failures +- new web2py.fedora.sh +- new setup-web2py-ubuntu.sh +- experimental autocomplete +- menus work on IE6 + +## 1.74.9 +- IS_IN_SET(((0,'label0'),(1,'label1'))), thanks Falko Krause +- SQLFORM(...).accpets stores True or False in boolean types no None, thanks Frederik Wagner +- SQLFORM.factory(...,table_name='no_table'), thanks Thedeus +- jQuery 1.4.1 +- Fixed major problem with internationalization of multiple languages. +- Fixed a serius security issue with login +- Possibly fixed some issues with cron + +## 1.74.8 +- IS_SLUG, thanks Gustavo and Jonathan +- web2py.py -nogui, thanks Jeff Bauer +- solved a problem with jython, thanks Tim Farrel +- login has "remember be option", thanks Piotr Banasziewicz +- fixed problem with keepvalue in update forms, thanks Miguel Lopez + +## 1.74.7 +- request_password_reset and password reset verification +- python web2py.py -S app -M -R script.py -A arg1 arg2 arg3 +- T("%(a)s") % dict(a="hello") + +## 1.74.6 +- bug fixes +- IS_IN_DB(...,_and=IS_NOT_IN_DB) +- Smaller populate, thanks Piotr +- better slicing of fields, thanks Michael Fig +- Cache stats, thanks Thadeus +- Better gql.py +- IS_IN_DB and IS_IN_SET default to zero='', no longer zero=None + +## 1.74.5 +- bug fixes +- restored python 2.4 support,thanks ont.rif +- support for native types on Google App Engine +- cache.ram usage statictics, thanks Thadus +- no more auth manu in scaffolding +- no more spash screen with -Q +- fixed doctest in html.py, thanks Anand Vaidya +- export_to_csv_file has represent, thanks Thadeus + +## 1.74.2-4 +- Fix bugs including including unicode in emails and blobs on GAE + +## 1.74.1 +- Moved to mercurial +- Default validators use the new define_table(....,format='...') +- New get_vars and post_vars compatible in 2.5 and 2.6 (thanks Tim) +- Major rewrite of gql.py extends DAL syntax on GAE +- No more *.w2p, welcome.w2p is create automatically, base apps are always upgraded +- export_to_csv(delimiter = ',', quotechar = '"', quoting = csv.QUOTE_MINIMAL), thanks Thadeus + +## 1.73.1 +- Fixed problem with storage and comparison of Row objects +- Fixed problem with mail on GAE +- Fixed problem with T in IS_DATE(TIME) error_message and format +- Rows[i].delete_record() +- Even better support for legacy databases +- Experimantal support for non UTF8 encoding in DB +- Better IPV4 (thanks Thandeus) +- T.current_languages default to 'en' and new T.set_current_languages(...) (thanks Yarko) +- INPUT(...,hideerror=False) used to fix rare chechbox widget problem +- Admin allows change of admin password +- New gluon/contrib/populate.py +- Size of input/textarea set by CSS no more by jQuery (thanks Iceberg) +- Customizable CSV (thanks Thandeus) +- More bug fixed (thanks Thandeus) +- Better regex for template fixed Jython problem (thank Jonathan) + +## 1.72.1 - 1.72.3 +- Better support for legacy databases + +## 1.71.1 +- Complete rewrite of Rows +- renamed DALStorage->Rows, DALRef->Reference +- Experimental serializarion of Row and Rows (get serialized to dict and list of dict) +- DAL(...,folder) and template.render(content=, context=) make it more modular + +## 1.70.1 +- Fixed bug with Rows.as_list and DALRef +- Added Rows.as_dict (thanks Mr Freeze and Thedeus) +- Added request.wsgi (thanks hcvst) allows running wsgi apps under web2py and applying wegi middleware to regular web2py actions that return strings. +- Experimental distributed transactions between postgresql, mysql and firebird +- Finally local_import is here! + +## 1.69.1 +- Fixed a bug introduced in 1.68 about inserting unicode in DAL +- Fixed other small bugs +- Better support for legacy databases (thank Denes) +- response.meta replaces response.author, response.keywords, response.description +- response.files stets dependes in plugins +- better admin for packing/unpacking plugins +- reference fiels nor evaluate to DALRef with lazy evaluation (cool, thanks Mr Freeze) +- can insert a record in place of a reference +- record[e] instead of record._extra[e] (tentatively!) +- record.update_record() with no args +- rows.find() (thanks Mr Freeze) +- rows.exclude() +- rows.sort() +- rows[:] + +## 1.68.2 +- Fixing bug with admin and missing crontab +- Fixing bug with rewrite.load on GAE (thanks Willian Wang) + +## 1.68.1 +- New official markdown with security fix +- rows.first() +- rows.last() +- New cron +- New hindi and spanish translation +- cached uploads allow for progress bars (thanks AndCycle) +- ingres support (thanks Chris) +- legacy database support for db2, mssql with non-int primary keys (thanks Denes) +- default setting of content-type (this may cause strange behavior in old apps when downloading images) +- IS_UPPER and IS_LOWER works with unicode +- CLENUP not takes regex of allowed/now allowed chartares +- New rewrite.py allows dynamic routes +- Better error messages for IS_INT_* and IS_FLOAT_* + +## 1.67.2 +- Security fix in markdown + +## 1.67.1 +- Bux fixed + +## 1.67.0 +- Python 2.4 support (again) +- New layout for welcome +- changed defauld field sizes to 512 +- Field(uploadfolder="...") +- appadmin works on GAE (again, somehting got broken at some point) +- new wsgiserver 3.2.0 should fix recurrent broken download problems + +## 1.66 +- new doctypes +- form.vars.newfilename +- new HTML and XHTML helpers +- better IS_LENGTH + +## 1.65.13 +- request.url (thanks Jonathan) +- restored uploadfield_newfilename +- new examples layout nad logo (thanks Mateusz) + +## 1.65.12 +- lables in auth auto-translate (thanks Alvaro) +- better ldap_auth (thanks Fran) +- auth chacks locally for blocked accounts even for alternate login methods (thanks Fran) + +## 1.65.11 +- Fixed a sqlhtml bug with image upload + +## 1.65.3-10 +- Fixed some small bugs and typos in the docstrings +- Fixed AMF3 support + +## 1.65.2 +- Fixed some small auth bugs +- Field.store(...) + +## 1.65.1 +- spreadsheet +- shell history, thanks sherdim +- crontab editor, thanks Angelo +- gluon/contrib/login_methods/cas_auth.py (thanks Hans) +- DAL(...) instead of SQLDB(...) +- DAL('gae') instead of GQLDB() +- Field instead of SQLField +- (the old syntax still works) + +## 1.65 +- reST docstrings for Sphinx, thanks Hans +- gluon/conrtib/login_methods/gae_google_account.py for google CAS login on GAE, thanks Hans +- fixed problem with Auth and Firebird 'password' issue +- new auth.settings.create_user_groups +- tickets stored on datastore on GAE and also logged, thanks Hans +- imporved IS_LENGTH with max and min, thanks Mateusz +- improved IS_EMAIL with filters, thanks Mateusz +- new IS_IMAGE checks for format and size, thanks Mateusz +- new IS_IPV4, thanks Mateusz + +## 1.64.4 +- Som bug fixes +- Informix Support +- response.render(stream) +- SQLFORM.factory +- SQLFORM.widgets.radio and SQLFORM.widgets.checkboxes + +## 1.64.3 +- Some bug fixes + +## 1.64.2 +- New IS_COMPLEX validator, thank Mr. Freeze +- Experimental Informix support +- Autologin on registration + +## 1.64 +- Models 2-3 times faster (thanks Alexey) +- Better LDAP support +- Works with Jython (including sqlite and postgresql with zxJDBC): + +- download jython-2.5rc3.jar +- download qlite-jdbc-3.6.14.2.jar +- java -jar jython-xxx.jar +- export CLASSPATH=$CLASSPATH:/Users/mdipierro/jython2.5rc3/sqlite-jdbc-3.6.14.2.jar +- cd web2py +- ../jython2.5rc3/jython web2py.py + +## 1.63.5 +- You can do jQuery.noConflict() without breaking web2py_ajax +- Wigets can have attributes (thanks Hans) +- Lots of internal cleanup and better code reusage (thanks Hans) + +## 1.63-1.63.4 +- no more import gluon. +- support for generic.xxx +- simplejson can handle datetime date and time + +## 1.62 +- SQLFORMS and crud now show readble fields +- Better WingIDE support +- Languages are automatically translated +- T.force and lazyT works better, optional T.lazy=False +- gluon.storage.Messages are now translated without T +- if routes.py then request.env.web2py_original_uri +- db.table.field.isattachment = True +- internationalizaiton of admin by Yair +- admin.py by Alvaro +- new MENU helper +- new w2p file format +- new welcome app with auth, service and crud turned on + +## 1.61 +- fixed some typos +- auth.add_permissions(0,....) 0 indicates group of current user +- crud.update has deletable=True or False +- fixed issue with GAE detection -> gluon.settings.web2py_runtime -> request + +## 1.59-1.60 +- fixed lots of small bugs +- routes_in can filter by http_host + +## 1.58 +- Fixed some CRON bugs +- Fixed a bug with new ajax edit +- Experimental DB2 support in DAL +- Customizable font size in admin edit page +- New welcome/models/db.py shows how to memcache sessions on GAE with MEMDB +- More expressive titles in admin +- DB2 support. Thanks Denes! + +## 1.57 +- New ajax edit with keepalive (no longer logged out when editing code) +- Fixed conflict resolution page. +- Removed /user/bin/python from models/controllers + +## 1.56.1-1.56.4 +- fixing lots of small bugs with tool and languages +- jquery.1.3.2 + +## + +- One more feature in trunk.... + +- db.define_table('image',SQLField('file','upload')) + +- db.image.file.authorize=lambda row: True or False + +- then controller +- def download(): return response.download(request,db) +- id' is now a hidden field sqlform +- gql references converted to long +- admin login has autofocus +- new notation proposed by Robin, db.table[id] +- new UploadWidget shows images +- new generic.html shows request, response, session +- new LEGEND helper (thanks Marcus) +- fixed doctests in sql (thanks Robin) +- new notation for DB + +- record=db.table[id] +- db.table[id]=dict(...) +- del db.table[id] + +- request.env.web2py_version +- new class gluon.storage.Settings has lock_keys, lock_values +- jquery 1.3.1 +- PEP8 compliance +- new examples application +- runs on jython (no database drivers yet, thanks Phyo) +- fixed bugs in tests +- passes all unittest but test_rewite (not sure it should pass that one) + +- Lots of patches from Fran Boone (about tools) and Dougla Soares de Andarde (Python 2.6 compliance, user use of hashlib instead of md5, new markdown2.py) +- db.define_table('mytable',db.Field('somefield'),timestamp) +Example: +`` +timestamp=SQLTable(None,'timestamp', + SQLField('created_on','datetime', + writable=False, + default=request.now), + SQLField('modified_on','datetime', + writable=False, + default=request.now,update=request.now)) +`` +and use it in all your tables +- form=SQLFORM(db.circle,request.args[-1]) +- and you get a create form if the URL ends in /0, you get an update +- form if the URL ends in /[valid_record_id] +make a display form in two possible ways: +- form=SQLFORM(db.circle,record,readonly=True) +- form=SQLFORM(db.circle,record_id,readonly=True) +make an update form in two possible ways: +- form=SQLFORM(db.circle,record) +- form=SQLFORM(db.circle,record_id) +make a create form in two possible ways: +- form=SQLFORM(db.circle) +- form=SQLFORM(db.circle,0) +make a form that automatically computes area +- pi=3.1415 +- form=SQLFOM(db.circle) +- if form.accepts(request.vars, +- onvalidation=lambda form: form.vars.area=pi*form.vars.radius**2): ... +make the radius appear in bold in display and table +- db.circle.radius.represent=lambda value: B(value) +automatically timestamp when record is modified +- db.circle.modified_on.update=request.now +automatically timestamp when record cretaed +- db.circle.modified_on.default=request.now +do not show now in display forms +- db.circle.modified_on.readable=False +do not show area in create/edit forms +- db.circle.area.writable=False +add a comment in the forms +- db.circle.area.comment="(this is a comment)" + +## 1.56 +- Now you can do: +`` +db.define_table('cirlce', + db.Field('radius','double'), + db.Field('area','double'), + db.Field('modified_on','datetime')) +`` + +## 1.55 +- rowcount +- fixed bug when IS_IN_DB involved multiple fields on GAE +- T.set_current_languages +- better unittests +- response.custom_commit and response.custom_rollback +- you can next cache calls (like cache a controller that caches a select). Thanks Iceberg +- db(....id==None).select() no longer returns an error but an empty SQLRows on GAE +- db(...).delete(delete_uploads=True) and SQLFORM.accepts(....delete_uploads=True) will delete all referenced uploaded files +- DIV.element and DIV.update +- sqlrows.json() +- SQLFORM.widgets +- URL(r=request,args=0) +- IS_IN_DB(...,multiple=True) for Many2Many (sort of) +- In URL(...,f) f is url encoded +- In routes_in=[['a/b/c/','a/b/c/?var=value']] +- simplejson 2.0.7 + + +## 1.54 +- fixed minor bugs + +## 1.53 +- On GAE upload data goes automatically in datastore (blob created automatically) +- New appadmin runs on GAE (most of it, not all) +- Martin Hufsky patch allow slicing of fields in DAL expressions + +## 1.52 +- Fixed a minor bug with _extra[key] and key not str. +- check for upgrade via ajax + +## 1.51 +- Fixed more bugs introduced in 1.49 (sql _extra and html select) +- support for sqlite:memory: + +## 1.50 +- Fixed some bugs introduced in 1.49 + +## 1.49 +- fixed a bug with taskbar widget, thanks Mark +- fixed a bug with form.latest +- made many DIV methods private (_) + + +## 1.43-1.48 +- html.py rewrite (better support for custom forms) (Bill Ferrett) +- new stickers in examples (thanks Mateusz) +- on windows can run in taskbar (Mark Larsen) +- in admin|edit page link to edit|controller (Nathan Freeze) +- better error codes and routes_onerror (Timothy Farrell) +- DAL support for groupy and having +- DAL support for expressions instead of values +- DAL has experimental Informix support +- fixed bug with non-printable chars in DAL +- 'text' fields limited to 2**16 (to avoid mysql problems) +- widget has -quiet and -debug (Attila Csipa) +- web2py_session uses BLOB instead of TEXT +- improved IS_URL +- Runs with python 2.6 (Tim) +- On GAE uses GAE for static files (Robin) + + +## 1.42 +- fixed security issue by removing slash escape in mysql +- removed random everywhere +- use uuid for session and tickets +- use http_x_forward_for to figure out the client causing a ticket +- use longtext and longblob for mysql +- main now really catches all exceptions +- no more warnings on GAE + +## web2py 1.31-1.41 +- some bug fixes, mostly better appengine support +- mssql support +- firebird support +- widgets support +- connection pools + +## web2py 1.30 +- added flv to contenttype +- added support for appengine + +## web2py 1.29 +- Now selet mutliple works with get, so does is IS_LENGTH +- Added IS_LIST_OF +- fixed problem with admin from windows and localhost + +## web2py 1.28 +- fixed bug with belongs, faster sql.py +- included jquery.js +- minor aestetical fixes +- sortable.js is gone + +## web2py 1.27 +- IS_NULL_OR now works will all fields +- admin creates paths to static files +- wsgiserver options are passed to HttpServer +- faking limitby for oracle to make appadmin work +- all objects inherit from object +- fixed bug in app names with . +- fixed bug in created RestrictedError object on windows +- shell is now in gluon and accessible via web2py.py + +## web2py 1.26 +- added shell.py (thanks Limodou!) +- added memcache support + +## web2py 1.22-1.25 +- fixed minor bugs, added IS_NULL_OR + +## web2py 1.21 +- replaced paste.httpserver with cherrypy.wsgi server +- temporary sessions are no longer saved +- widget has [stop] button and graph +- logging is done by main by appfactory +- fixed a bug in sql belongs + +## web2py 1.20 +- new IFRAME, LABEL, FIELDSET validators +- P(..cr2br=True) option +- FORM and SQLFORM have hidden=dict(...) option for REST +- testing framework. +- improved examples pages + +## web2py 1.19 +- minor typos + +## web2py v1.18 +- removed vulnerability in accept_languages and session_id +- Minor bug fixes. Typos and cleanup cache. Textarea now clears. +- Support for PyAMF. +- T returns a class, not a string +- new template parser (faster?) +- got rid of sintaxhighlighter in favor of server side CODE +- fix problem with cacheondisk locking +- fix 'None' instead of NULL in IS_NOT_IN_DB (I think) +- gluon.contrib.markdown +- notnull and unique in SQLField now supported (tested on sqlite mysql and postgresql) +- Storage now has __getstate__ and __setstate__ needed for pickling. +- session files are now locked to make it work better with asynchronous requests +- cxoracle should work, apart for limitby +- .../examples is now mapped to .../examples/default/index etc. +- .../init is now mapped to .../welcome if init is not present + +## web2py v1.17 +- I posted v1.16 too soon. v1.17 was released after 1h to fix some bugs. + +## web2py v1.16 +- yes we changed the name! Turns out Gluon was trademarked by somebody else. +- Although we are not infringing the trademark since this is a non-commercial +- product we could have run into some issues. So we have been professional +- and changed the name to web2py. +- Now SQLFORMs and FORM can have a formname and multiple forms are allowed +- per page. +- A new examples/default/index page. +- web2py.py instead of runme.py +- mysql sets utf8 encoding. +- input integer field values are automatically converted int(). + +## Gluon v1.15 +- New try:... except. in gluon/main.py for when sessions cannot be saved +- Now validator/formatter method allows IS_DATE('%d/%m/%Y') + +## Gluon v1.14 +- Fixed a bug fix in URLs + +## Gluon v1.13 +- (this is one of the biggest revisions ever) +- Improved sql.py has support MySQL, cxOracle (experimental), extract, like and better testing +- SQLDB.tables and SQLTable.fields are now SQLCalableList objects +- Fixed bug with editing integer fields storing zero +- Admin interface now says "insert new [tablename]" and display insert, select or update properly in the title. +- Added a cache mechamism. Works for data, controllers, views and SQLRows. +- main.py now uses a request.folder absolute path when not os.name in ['nt','posix']. Seems to work on windowsce devices, except no file locking has consequences. +- Now you can put modules in applications/[anyapp]/modules and import them with +- import applications.[anyapp].modules.[module] as [module] +- Fixed problem with init +- New applications/examples/controller/global.py controller for docs. + +## Gluon v1.12 +- in sql.py +- handles NULL values properly +- unicode support (data always stored in utf-8) +- 'date' -> datetime.date ,'time' -> datetime.time, 'datetime' -> datetime.datetime, 'boolean' -> True/False +- most types have default validators +- SQLField(...,required=True) option. +- SQLRows has __str__ that serializes in CSV and xml() that serializes in HTML +- SQLTable has import_from_csv_file(...) +- gluon.simplejson for AJAX +- in validators.py +- IS_IN_DB(db,..) - db can be an SQLSet or an SQLDB +- better error messages +- in admin +- new import/export in csv, update and delete interface. +- in appadmin +- edit form allows to keep stored encrypted password +- in main.py +- http://host not defaults to http://host/init/default/index +- New third party modules +- gluon.simplejson(.dumps, .loads) +- gluon.pyrtf(.dumps) +- gluon.rss2(.dumps) + +## Gluon v1.11 +- appadmin allows to keep or delete uploaded files + +## Gluon v1.10 +- fixed concurrency problems with SQLDB._instances and SQLDB._folders, now use lock +- now, by default, edit SQLFORMs retain uploaded files + +## Gluon v1.9 +- allow "count(*)" in select +- db.execute() +- fixed problem with continue and return in template +- removed try: ... except in sql.py +- fixed '\t' + +## Gluon v1.8 +- no more chdir (thread unsafe) +- no more sys.stdout (thread unsafe) +- response.body is StringIO() +- admin/default/site informs about upgrade +- response.locker (optional) + +## Gluon v1.5 +- <form> -> <form method="post"> in errors.html +- replace('//','////') in sub in template.py + +## Gluon v1.4 +- fixed problem with IS_INT_IN_RANGE and IS_FLOAT_IN_RANGE. Now an error in a validator is reported as a ticket. Good validators should not raise Exceptions. +- IS_IN_DB displays "label (id)" +- it can upload files without extension +- migration is now optional (define_table has migrate=False option) + +## Gluon v1.3 +- added IS_IN_DB, IS_NOT_IN_DB and updated examples accordingly + +## Gluon v1.1 -> v1.2 +- fixed some typos in examples +- IS_IN_SET now supports labels +- cleanup in sql.py does not cleanup, just checks valid field and table names + +## Gluon v1.0 -> v1.1 +- bug in sqlhtml with JOINS queries + +## EWF v1.7 -> Gluon v1.0 +- Name change +- Improved layout.html + +## EWF v1.6 -> v1.7 +- in paths replace '\' with '/' to fix problem with windows paths +- using limitby in database administration +- replaced mime/miltupart with multipart/form-data to fix a windows problem + +## EWF v1.5 -> v1.6 (2007) +- load and save .py in ascii, avoids problem with LF+CR on windows +- added path.join in compileapp, fixed problem with Windows compileapp diff --git a/web2py/LICENSE b/web2py/LICENSE new file mode 100644 index 0000000..a1e8b7f --- /dev/null +++ b/web2py/LICENSE @@ -0,0 +1,118 @@ +## Web2py License + +Web2py is Licensed under the LGPL license version 3 +(http://www.gnu.org/licenses/lgpl.html) + +Copyrighted (c) by Massimo Di Pierro (2007-2013) + +### On Commercial Redistribution + +In accordance with LGPL you may: +- redistribute web2py with your apps (including official web2py binary versions) +- release your applications which use official web2py libraries under any license you wish +But you must: +- make clear in the documentation that your application uses web2py +- release any modification of the web2py libraries under the LGPLv3 license + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL +NECESSARY SERVICING, REPAIR OR CORRECTION. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT +HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, +BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL +DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER +PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +(Earlier versions of web2py, 1.0.*-1.90.*, were released under the GPL2 license plus a +commercial exception which, for practical purposes, was very similar to the current LPGLv3) + +### Licenses for third party contributed software + +web2py contains third party software under the gluon/contrib/ folder. +Each file/module in contrib is distributed with web2py under its original license. +Here we list some of them. + +#### gluon.contrib.rss2.py (originally PyRSS2Gen) LICENSE + +This is copyright (c) by Dalke Scientific Software, LLC and released under the +BSD license. See the file LICENSE in the distribution or +<http://www.opensource.org/licenses/bsd-license.php> for details. + +#### gluon.contrib.markdown (markdown2) LICENSE + +MIT License from from <http://code.google.com/p/python-markdown2/> + +#### gluon.contrib.feedparser LICENSE + +Copyright (c) 2002-2005, Mark Pilgrim + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +#### gluon.wsgiserver.py LICENSE (borrowed from cherrypy) + +Copyright (c) 2004, CherryPy Team (team@cherrypy.org) +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 CherryPy Team 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 OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#### gluon.contrib.pam LICENSE + +Copyright (C) 2007-2009 Chris AtLee <chris@atlee.ca> Licensed under the MIT license + +#### gluon.contrib.shell LICENSE + +Copyright (C) by Google inc. Apache 2.0 Lincense + +#### The javascript licenses are in the code itself + diff --git a/web2py/MANIFEST.in b/web2py/MANIFEST.in new file mode 100644 index 0000000..7cd53a8 --- /dev/null +++ b/web2py/MANIFEST.in @@ -0,0 +1 @@ +include VERSION LICENSE diff --git a/web2py/README.markdown b/web2py/README.markdown new file mode 100644 index 0000000..27fa236 --- /dev/null +++ b/web2py/README.markdown @@ -0,0 +1,100 @@ +## Readme + +web2py is a free open source full-stack framework for rapid development of fast, scalable, secure and portable database-driven web-based applications. + +It is written and programmable in Python. LGPLv3 License + +Learn more at http://web2py.com + +## Google App Engine deployment + + cp examples/app.yaml ./ + cp handlers/gaehandler.py ./ + +Then edit ./app.yaml and replace "yourappname" with yourappname. + +## Important reminder about this GIT repo + +An important part of web2py is the Database Abstraction Layer (DAL). In early 2015 this was decoupled into a separate code-base (PyDAL). In terms of git, it is a sub-module of the main repository. + +The use of a sub-module requires a one-time use of the --recursive flag for git clone if you are cloning web2py from scratch. + + git clone --recursive https://github.com/web2py/web2py.git + +If you have an existing repository, the commands below need to be executed at least once: + + git submodule update --init --recursive + +If you have a folder gluon/dal you must remove it: + + rm -r gluon/dal + +PyDAL uses a separate stable release cycle to the rest of web2py. PyDAL releases will use a date-naming scheme similar to Ubuntu. Issues related to PyDAL should be reported to its separate repository. + + +## Documentation (readthedocs.org) + +[![Docs Status](https://readthedocs.org/projects/web2py/badge/?version=latest&style=flat-square)](http://web2py.rtfd.org/) + +## Tests + +[![Build Status](https://img.shields.io/travis/web2py/web2py/master.svg?style=flat-square&label=Travis-CI)](https://travis-ci.org/web2py/web2py) +[![MS Build Status](https://img.shields.io/appveyor/ci/web2py/web2py/master.svg?style=flat-square&label=Appveyor-CI)](https://ci.appveyor.com/project/web2py/web2py) +[![Coverage Status](https://img.shields.io/codecov/c/github/web2py/web2py.svg?style=flat-square)](https://codecov.io/github/web2py/web2py) + + +## Installation Instructions + +To start web2py there is NO NEED to install it. Just unzip and do: + + python web2py.py + +That's it!!! + +## web2py directory structure + + project/ + README + LICENSE + VERSION > this web2py version + web2py.py > the startup script + anyserver.py > to run with third party servers + ... > other handlers and example files + gluon/ > the core libraries + packages/ > web2py submodules + dal/ + contrib/ > third party libraries + tests/ > unittests + applications/ > are the apps + admin/ > web based IDE + ... + examples/ > examples, docs, links + ... + welcome/ > the scaffolding app (they all copy it) + ABOUT + LICENSE + models/ + views/ + controllers/ + sessions/ + errors/ + cache/ + static/ + uploads/ + modules/ + cron/ + tests/ + ... > your own apps + examples/ > example config files, mv .. and customize + extras/ > other files which are required for building web2py + scripts/ > utility and installation scripts + handlers/ + wsgihandler.py > handler to connect to WSGI + ... > handlers for Fast-CGI, SCGI, Gevent, etc + site-packages/ > additional optional modules + logs/ > log files will go in there + deposit/ > a place where web2py stores apps temporarily + +## Issues? + +Report issues at https://github.com/web2py/web2py/issues diff --git a/web2py/VERSION b/web2py/VERSION new file mode 100644 index 0000000..f86eaec --- /dev/null +++ b/web2py/VERSION @@ -0,0 +1 @@ +Version 2.17.1-stable+timestamp.2018.08.06.01.02.56 diff --git a/web2py/anyserver.py b/web2py/anyserver.py new file mode 100644 index 0000000..b935a1e --- /dev/null +++ b/web2py/anyserver.py @@ -0,0 +1,365 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +This file is part of the web2py Web Framework +Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu> +License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +This file is based, although a rewrite, on MIT-licensed code from the Bottle web framework. +""" + +import os +import sys +import optparse +import urllib + +path = os.path.dirname(os.path.abspath(__file__)) +os.chdir(path) +sys.path = [path] + [p for p in sys.path if not p == path] + + +class Servers: + @staticmethod + def cgi(app, address=None, **options): + from wsgiref.handlers import CGIHandler + CGIHandler().run(app) # Just ignore host and port here + + @staticmethod + def flup(app, address, **options): + import flup.server.fcgi + flup.server.fcgi.WSGIServer(app, bindAddress=address).run() + + @staticmethod + def wsgiref(app, address, **options): # pragma: no cover + from wsgiref.simple_server import make_server, WSGIRequestHandler + options = {} + class QuietHandler(WSGIRequestHandler): + def log_request(*args, **kw): + pass + options['handler_class'] = QuietHandler + srv = make_server(address[0], address[1], app, **options) + srv.serve_forever() + + @staticmethod + def cherrypy(app, address, **options): + from cheroot.wsgi import Server as WSGIServer + server = WSGIServer(address, app) + server.start() + + @staticmethod + def rocket(app, address, **options): + from gluon.rocket import CherryPyWSGIServer + server = CherryPyWSGIServer(address, app) + server.start() + + @staticmethod + def rocket_with_repoze_profiler(app, address, **options): + from gluon.rocket import CherryPyWSGIServer + from repoze.profile.profiler import AccumulatingProfileMiddleware + from gluon.settings import global_settings + global_settings.web2py_crontype = 'none' + wrapped = AccumulatingProfileMiddleware( + app, + log_filename='wsgi.prof', + discard_first_request=True, + flush_at_shutdown=True, + path='/__profile__' + ) + server = CherryPyWSGIServer(address, wrapped) + server.start() + + @staticmethod + def paste(app, address, **options): + options = {} + from paste import httpserver + from paste.translogger import TransLogger + httpserver.serve(app, host=address[0], port=address[1], **options) + + @staticmethod + def fapws(app, address, **options): + import fapws._evwsgi as evwsgi + from fapws import base + evwsgi.start(address[0], str(address[1])) + evwsgi.set_base_module(base) + + def app(environ, start_response): + environ['wsgi.multiprocess'] = False + return app(environ, start_response) + evwsgi.wsgi_cb(('', app)) + evwsgi.run() + + @staticmethod + def gevent(app, address, **options): + options = options['options'] + workers = options.workers + from gevent import pywsgi + from gevent.pool import Pool + pywsgi.WSGIServer(address, app, spawn=workers and Pool( + int(options.workers)) or 'default', log=None).serve_forever() + + @staticmethod + def bjoern(app, address, **options): + import bjoern + bjoern.run(app, *address) + + @staticmethod + def tornado(app, address, **options): + import tornado.wsgi + import tornado.httpserver + import tornado.ioloop + container = tornado.wsgi.WSGIContainer(app) + server = tornado.httpserver.HTTPServer(container) + server.listen(address=address[0], port=address[1]) + tornado.ioloop.IOLoop.instance().start() + + @staticmethod + def twisted(app, address, **options): + from twisted.web import server, wsgi + from twisted.python.threadpool import ThreadPool + from twisted.internet import reactor + thread_pool = ThreadPool() + thread_pool.start() + reactor.addSystemEventTrigger('after', 'shutdown', thread_pool.stop) + factory = server.Site(wsgi.WSGIResource(reactor, thread_pool, app)) + reactor.listenTCP(address[1], factory, interface=address[0]) + reactor.run() + + @staticmethod + def diesel(app, address, **options): + from diesel.protocols.wsgi import WSGIApplication + app = WSGIApplication(app, port=address[1]) + app.run() + + @staticmethod + def gunicorn(app, address, **options): + options = {} + from gunicorn.app.base import Application + config = {'bind': "%s:%d" % address} + config.update(options) + sys.argv = ['anyserver.py'] + + class GunicornApplication(Application): + def init(self, parser, opts, args): + return config + + def load(self): + return app + g = GunicornApplication() + g.run() + + @staticmethod + def eventlet(app, address, **options): + from eventlet import wsgi, listen + wsgi.server(listen(address), app) + + @staticmethod + def mongrel2(app, address, **options): + import uuid + sys.path.append(os.path.abspath(os.path.dirname(__file__))) + from mongrel2 import handler + conn = handler.Connection(str(uuid.uuid4()), + "tcp://127.0.0.1:9997", + "tcp://127.0.0.1:9996") + mongrel2_handler(app, conn, debug=False) + + @staticmethod + def motor(app, address, **options): + #https://github.com/rpedroso/motor + import motor + app = motor.WSGIContainer(app) + http_server = motor.HTTPServer(app) + http_server.listen(address=address[0], port=address[1]) + #http_server.start(2) + motor.IOLoop.instance().start() + + @staticmethod + def pulsar(app, address, **options): + from pulsar.apps import wsgi + sys.argv = ['anyserver.py'] + s = wsgi.WSGIServer(callable=app, bind="%s:%d" % address) + s.start() + + @staticmethod + def waitress(app, address, **options): + from waitress import serve + serve(app, host=address[0], port=address[1], _quiet=True) + + +def mongrel2_handler(application, conn, debug=False): + """ + Based on : + https://github.com/berry/Mongrel2-WSGI-Handler/blob/master/wsgi-handler.py + + WSGI handler based on the Python wsgiref SimpleHandler. + A WSGI application should return a iterable op StringTypes. + Any encoding must be handled by the WSGI application itself. + """ + from wsgiref.handlers import SimpleHandler + try: + import cStringIO as StringIO + except: + import StringIO + + # TODO - this wsgi handler executes the application and renders a page + # in memory completely before returning it as a response to the client. + # Thus, it does not "stream" the result back to the client. It should be + # possible though. The SimpleHandler accepts file-like stream objects. So, + # it should be just a matter of connecting 0MQ requests/response streams to + # the SimpleHandler requests and response streams. However, the Python API + # for Mongrel2 doesn't seem to support file-like stream objects for requests + # and responses. Unless I have missed something. + + while True: + if debug: + print "WAITING FOR REQUEST" + + # receive a request + req = conn.recv() + if debug: + print "REQUEST BODY: %r\n" % req.body + + if req.is_disconnect(): + if debug: + print "DISCONNECT" + continue # effectively ignore the disconnect from the client + + # Set a couple of environment attributes a.k.a. header attributes + # that are a must according to PEP 333 + environ = req.headers + environ['SERVER_PROTOCOL'] = 'HTTP/1.1' # SimpleHandler expects a server_protocol, lets assume it is HTTP 1.1 + environ['REQUEST_METHOD'] = environ['METHOD'] + if ':' in environ['Host']: + environ['SERVER_NAME'] = environ['Host'].split(':')[0] + environ['SERVER_PORT'] = environ['Host'].split(':')[1] + else: + environ['SERVER_NAME'] = environ['Host'] + environ['SERVER_PORT'] = '' + environ['SCRIPT_NAME'] = '' # empty for now + environ['PATH_INFO'] = urllib.unquote(environ['PATH']) + if '?' in environ['URI']: + environ['QUERY_STRING'] = environ['URI'].split('?')[1] + else: + environ['QUERY_STRING'] = '' + if 'Content-Length' in environ: + environ['CONTENT_LENGTH'] = environ[ + 'Content-Length'] # necessary for POST to work with Django + environ['wsgi.input'] = req.body + + if debug: + print "ENVIRON: %r\n" % environ + + # SimpleHandler needs file-like stream objects for + # requests, errors and responses + reqIO = StringIO.StringIO(req.body) + errIO = StringIO.StringIO() + respIO = StringIO.StringIO() + + # execute the application + handler = SimpleHandler(reqIO, respIO, errIO, environ, + multithread=False, multiprocess=False) + handler.run(application) + + # Get the response and filter out the response (=data) itself, + # the response headers, + # the response status code and the response status description + response = respIO.getvalue() + response = response.split("\r\n") + data = response[-1] + headers = dict([r.split(": ") for r in response[1:-2]]) + code = response[0][9:12] + status = response[0][13:] + + # strip BOM's from response data + # Especially the WSGI handler from Django seems to generate them (2 actually, huh?) + # a BOM isn't really necessary and cause HTML parsing errors in Chrome and Safari + # See also: http://www.xs4all.nl/~mechiel/projects/bomstrip/ + # Although I still find this a ugly hack, it does work. + data = data.replace('\xef\xbb\xbf', '') + + # Get the generated errors + errors = errIO.getvalue() + + # return the response + if debug: + print "RESPONSE: %r\n" % response + if errors: + if debug: + print "ERRORS: %r" % errors + data = "%s\r\n\r\n%s" % (data, errors) + conn.reply_http( + req, data, code=code, status=status, headers=headers) + + +def run(servername, ip, port, softcron=True, logging=False, profiler=None, + options=None): + if servername == 'gevent': + from gevent import monkey + monkey.patch_all() + elif servername == 'eventlet': + import eventlet + eventlet.monkey_patch() + + import gluon.main + + if logging: + application = gluon.main.appfactory(wsgiapp=gluon.main.wsgibase, + logfilename='httpserver.log', + profiler_dir=profiler) + else: + application = gluon.main.wsgibase + if softcron: + from gluon.settings import global_settings + global_settings.web2py_crontype = 'soft' + getattr(Servers, servername)(application, (ip, int(port)), options=options) + + + +def main(): + usage = "python anyserver.py -s tornado -i 127.0.0.1 -p 8000 -l -P" + try: + version = open('VERSION','r') + except IOError: + version = '' + parser = optparse.OptionParser(usage, None, optparse.Option, version) + parser.add_option('-l', + '--logging', + action='store_true', + default=False, + dest='logging', + help='log into httpserver.log') + parser.add_option('-P', + '--profiler', + default=False, + dest='profiler_dir', + help='profiler dir') + servers = ', '.join(x for x in dir(Servers) if not x[0] == '_') + parser.add_option('-s', + '--server', + default='rocket', + dest='server', + help='server name (%s)' % servers) + parser.add_option('-i', + '--ip', + default='127.0.0.1', + dest='ip', + help='ip address') + parser.add_option('-p', + '--port', + default='8000', + dest='port', + help='port number') + parser.add_option('-w', + '--workers', + default=None, + dest='workers', + help='number of workers number') + (options, args) = parser.parse_args() + print 'starting %s on %s:%s...' % ( + options.server, options.ip, options.port) + run(options.server, options.ip, options.port, + logging=options.logging, profiler=options.profiler_dir, + options=options) + +if __name__ == '__main__': + main() diff --git a/web2py/applications/SP/ABOUT b/web2py/applications/SP/ABOUT new file mode 100644 index 0000000..184b19c --- /dev/null +++ b/web2py/applications/SP/ABOUT @@ -0,0 +1,2 @@ +Write something about this app. +Developed with web2py. diff --git a/web2py/applications/SP/LICENSE b/web2py/applications/SP/LICENSE new file mode 100644 index 0000000..217b7c4 --- /dev/null +++ b/web2py/applications/SP/LICENSE @@ -0,0 +1,4 @@ +The web2py welcome app is licensed under public domain +(except for the css and js files that it includes, which have their own third party licenses). + +You can modify this license when you add your own code. diff --git a/web2py/applications/SP/__init__.py b/web2py/applications/SP/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/web2py/applications/SP/__init__.py @@ -0,0 +1 @@ + diff --git a/web2py/applications/SP/controllers/appadmin.py b/web2py/applications/SP/controllers/appadmin.py new file mode 100644 index 0000000..9814687 --- /dev/null +++ b/web2py/applications/SP/controllers/appadmin.py @@ -0,0 +1,863 @@ +# -*- coding: utf-8 -*- + +# ########################################################## +# ## make sure administrator is on localhost +# ########################################################### + +import os +import socket +import datetime +import copy +import gluon.contenttype +import gluon.fileutils +from gluon._compat import iteritems + +is_gae = request.env.web2py_runtime_gae or False + +# ## critical --- make a copy of the environment + +global_env = copy.copy(globals()) +global_env['datetime'] = datetime + +http_host = request.env.http_host.split(':')[0] +remote_addr = request.env.remote_addr +try: + hosts = (http_host, socket.gethostname(), + socket.gethostbyname(http_host), + '::1', '127.0.0.1', '::ffff:127.0.0.1') +except: + hosts = (http_host, ) + +if request.is_https: + session.secure() +elif (remote_addr not in hosts) and (remote_addr != "127.0.0.1") and \ + (request.function != 'manage'): + raise HTTP(200, T('appadmin is disabled because insecure channel')) + +if request.function == 'manage': + if not 'auth' in globals() or not request.args: + redirect(URL(request.controller, 'index')) + manager_action = auth.settings.manager_actions.get(request.args(0), None) + if manager_action is None and request.args(0) == 'auth': + manager_action = dict(role=auth.settings.auth_manager_role, + heading=T('权限管理'), + tables=[auth.table_user(), + auth.table_group(), + auth.table_permission()]) + manager_role = manager_action.get('role', None) if manager_action else None + if not (gluon.fileutils.check_credentials(request) or auth.has_membership(manager_role)): + raise HTTP(403, "没有经过管理员认证") + menu = False +elif (request.application == 'admin' and not session.authorized) or \ + (request.application != 'admin' and not gluon.fileutils.check_credentials(request)): + redirect(URL('admin', 'default', 'index', + vars=dict(send=URL(args=request.args, vars=request.vars)))) +else: + response.subtitle = T('数据库管理 (appadmin)') + menu = True + +ignore_rw = True +response.view = 'appadmin/appadmin.html' +if menu: + response.menu = [[T('数据库'), False, + URL('index')]] + if auth.has_membership(group_id=2): + response.menu.append([T('design'), False, URL('admin', 'default', 'design', + args=[request.application])]) + response.menu.append([T('state'), False, + URL('state')]) + response.menu.append([T('cache'), False, + URL('ccache')]) + +# ########################################################## +# ## auxiliary functions +# ########################################################### + +if False and request.tickets_db: + from gluon.restricted import TicketStorage + ts = TicketStorage() + ts._get_table(request.tickets_db, ts.tablename, request.application) + +def get_databases(request): + dbs = {} + for (key, value) in global_env.items(): + try: + cond = isinstance(value, GQLDB) + except: + cond = isinstance(value, SQLDB) + if cond: + dbs[key] = value + return dbs + +databases = get_databases(None) + +def eval_in_global_env(text): + exec ('_ret=%s' % text, {}, global_env) + return global_env['_ret'] + + +def get_database(request): + if request.args and request.args[0] in databases: + return eval_in_global_env(request.args[0]) + else: + session.flash = T('invalid request') + redirect(URL('index')) + +def get_table(request): + db = get_database(request) + if len(request.args) > 1 and request.args[1] in db.tables: + return (db, request.args[1]) + else: + session.flash = T('invalid request') + redirect(URL('index')) + + +def get_query(request): + try: + return eval_in_global_env(request.vars.query) + except Exception: + return None + + +def query_by_table_type(tablename, db, request=request): + keyed = hasattr(db[tablename], '_primarykey') + if keyed: + firstkey = db[tablename][db[tablename]._primarykey[0]] + cond = '>0' + if firstkey.type in ['string', 'text']: + cond = '!=""' + qry = '%s.%s.%s%s' % ( + request.args[0], request.args[1], firstkey.name, cond) + else: + qry = '%s.%s.id>0' % tuple(request.args[:2]) + return qry + + +# ########################################################## +# ## list all databases and tables +# ########################################################### +def index(): + return dict(databases=databases) + + +# ########################################################## +# ## insert a new record +# ########################################################### + + +def insert(): + (db, table) = get_table(request) + form = SQLFORM(db[table], ignore_rw=ignore_rw) + if form.accepts(request.vars, session): + response.flash = T('new record inserted') + return dict(form=form, table=db[table]) + + +# ########################################################## +# ## list all records in table and insert new record +# ########################################################### + + +def download(): + import os + db = get_database(request) + return response.download(request, db) + + +def csv(): + import gluon.contenttype + response.headers['Content-Type'] = \ + gluon.contenttype.contenttype('.csv') + db = get_database(request) + query = get_query(request) + if not query: + return None + response.headers['Content-disposition'] = 'attachment; filename=%s_%s.csv'\ + % tuple(request.vars.query.split('.')[:2]) + return str(db(query, ignore_common_filters=True).select()) + + +def import_csv(table, file): + table.import_from_csv_file(file) + + +def select(): + import re + db = get_database(request) + dbname = request.args[0] + try: + is_imap = db._uri.startswith("imap://") + except (KeyError, AttributeError, TypeError): + is_imap = False + regex = re.compile('(?P<table>\w+)\.(?P<field>\w+)=(?P<value>\d+)') + if len(request.args) > 1 and hasattr(db[request.args[1]], '_primarykey'): + regex = re.compile('(?P<table>\w+)\.(?P<field>\w+)=(?P<value>.+)') + if request.vars.query: + match = regex.match(request.vars.query) + if match: + request.vars.query = '%s.%s.%s==%s' % (request.args[0], + match.group('table'), match.group('field'), + match.group('value')) + else: + request.vars.query = session.last_query + query = get_query(request) + if request.vars.start: + start = int(request.vars.start) + else: + start = 0 + nrows = 0 + + step = 100 + fields = [] + + if is_imap: + step = 3 + + stop = start + step + + table = None + rows = [] + orderby = request.vars.orderby + if orderby: + orderby = dbname + '.' + orderby + if orderby == session.last_orderby: + if orderby[0] == '~': + orderby = orderby[1:] + else: + orderby = '~' + orderby + session.last_orderby = orderby + session.last_query = request.vars.query + form = FORM(TABLE(TR(T('Query:'), '', INPUT(_style='width:400px', + _name='query', _value=request.vars.query or '', _class="form-control", + requires=IS_NOT_EMPTY( + error_message=T("Cannot be empty")))), TR(T('Update:'), + INPUT(_name='update_check', _type='checkbox', + value=False), INPUT(_style='width:400px', + _name='update_fields', _value=request.vars.update_fields + or '', _class="form-control")), TR(T('Delete:'), INPUT(_name='delete_check', + _class='delete', _type='checkbox', value=False), ''), + TR('', '', INPUT(_type='submit', _value=T('submit'), _class="btn btn-primary"))), + _action=URL(r=request, args=request.args)) + + tb = None + if form.accepts(request.vars, formname=None): + regex = re.compile(request.args[0] + '\.(?P<table>\w+)\..+') + match = regex.match(form.vars.query.strip()) + if match: + table = match.group('table') + try: + nrows = db(query, ignore_common_filters=True).count() + if form.vars.update_check and form.vars.update_fields: + db(query, ignore_common_filters=True).update( + **eval_in_global_env('dict(%s)' % form.vars.update_fields)) + response.flash = T('%s %%{row} updated', nrows) + elif form.vars.delete_check: + db(query, ignore_common_filters=True).delete() + response.flash = T('%s %%{row} deleted', nrows) + nrows = db(query, ignore_common_filters=True).count() + + if is_imap: + fields = [db[table][name] for name in + ("id", "uid", "created", "to", + "sender", "subject")] + if orderby: + rows = db(query, ignore_common_filters=True).select( + *fields, limitby=(start, stop), + orderby=eval_in_global_env(orderby)) + else: + rows = db(query, ignore_common_filters=True).select( + *fields, limitby=(start, stop)) + except Exception as e: + import traceback + tb = traceback.format_exc() + (rows, nrows) = ([], 0) + response.flash = DIV(T('Invalid Query'), PRE(str(e))) + # begin handle upload csv + csv_table = table or request.vars.table + if csv_table: + formcsv = FORM(str(T('or import from csv file')) + " ", + INPUT(_type='file', _name='csvfile'), + INPUT(_type='hidden', _value=csv_table, _name='table'), + INPUT(_type='submit', _value=T('import'), _class="btn btn-primary")) + else: + formcsv = None + if formcsv and formcsv.process().accepted: + try: + import_csv(db[request.vars.table], + request.vars.csvfile.file) + response.flash = T('data uploaded') + except Exception as e: + response.flash = DIV(T('unable to parse csv file'), PRE(str(e))) + # end handle upload csv + + return dict( + form=form, + table=table, + start=start, + stop=stop, + step=step, + nrows=nrows, + rows=rows, + query=request.vars.query, + formcsv=formcsv, + tb=tb + ) + + +# ########################################################## +# ## edit delete one record +# ########################################################### + + +def update(): + (db, table) = get_table(request) + keyed = hasattr(db[table], '_primarykey') + record = None + db[table]._common_filter = None + if keyed: + key = [f for f in request.vars if f in db[table]._primarykey] + if key: + record = db(db[table][key[0]] == request.vars[key[ + 0]]).select().first() + else: + record = db(db[table].id == request.args( + 2)).select().first() + + if not record: + qry = query_by_table_type(table, db) + session.flash = T('record does not exist') + redirect(URL('select', args=request.args[:1], + vars=dict(query=qry))) + + if keyed: + for k in db[table]._primarykey: + db[table][k].writable = False + + form = SQLFORM( + db[table], record, deletable=True, delete_label=T('Check to delete'), + ignore_rw=ignore_rw and not keyed, + linkto=URL('select', + args=request.args[:1]), upload=URL(r=request, + f='download', args=request.args[:1])) + + if form.accepts(request.vars, session): + session.flash = T('done!') + qry = query_by_table_type(table, db) + redirect(URL('select', args=request.args[:1], + vars=dict(query=qry))) + return dict(form=form, table=db[table]) + + +# ########################################################## +# ## get global variables +# ########################################################### + + +def state(): + return dict() + + +def ccache(): + if is_gae: + form = FORM( + P(TAG.BUTTON(T("Clear CACHE?"), _type="submit", _name="yes", _value="yes"))) + else: + cache.ram.initialize() + cache.disk.initialize() + + form = FORM( + P(TAG.BUTTON( + T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")), + P(TAG.BUTTON( + T("Clear RAM"), _type="submit", _name="ram", _value="ram")), + P(TAG.BUTTON( + T("Clear DISK"), _type="submit", _name="disk", _value="disk")), + ) + + if form.accepts(request.vars, session): + session.flash = "" + if is_gae: + if request.vars.yes: + cache.ram.clear() + session.flash += T("Cache Cleared") + else: + clear_ram = False + clear_disk = False + if request.vars.yes: + clear_ram = clear_disk = True + if request.vars.ram: + clear_ram = True + if request.vars.disk: + clear_disk = True + if clear_ram: + cache.ram.clear() + session.flash += T("Ram Cleared") + if clear_disk: + cache.disk.clear() + session.flash += T("Disk Cleared") + redirect(URL(r=request)) + + try: + from pympler.asizeof import asizeof + except ImportError: + asizeof = False + + import shelve + import os + import copy + import time + import math + from pydal.contrib import portalocker + + ram = { + 'entries': 0, + 'bytes': 0, + 'objects': 0, + 'hits': 0, + 'misses': 0, + 'ratio': 0, + 'oldest': time.time(), + 'keys': [] + } + + disk = copy.copy(ram) + total = copy.copy(ram) + disk['keys'] = [] + total['keys'] = [] + + def GetInHMS(seconds): + hours = math.floor(seconds / 3600) + seconds -= hours * 3600 + minutes = math.floor(seconds / 60) + seconds -= minutes * 60 + seconds = math.floor(seconds) + + return (hours, minutes, seconds) + + if is_gae: + gae_stats = cache.ram.client.get_stats() + try: + gae_stats['ratio'] = ((gae_stats['hits'] * 100) / + (gae_stats['hits'] + gae_stats['misses'])) + except ZeroDivisionError: + gae_stats['ratio'] = T("?") + gae_stats['oldest'] = GetInHMS(time.time() - gae_stats['oldest_item_age']) + total.update(gae_stats) + else: + # get ram stats directly from the cache object + ram_stats = cache.ram.stats[request.application] + ram['hits'] = ram_stats['hit_total'] - ram_stats['misses'] + ram['misses'] = ram_stats['misses'] + try: + ram['ratio'] = ram['hits'] * 100 / ram_stats['hit_total'] + except (KeyError, ZeroDivisionError): + ram['ratio'] = 0 + + for key, value in iteritems(cache.ram.storage): + if asizeof: + ram['bytes'] += asizeof(value[1]) + ram['objects'] += 1 + ram['entries'] += 1 + if value[0] < ram['oldest']: + ram['oldest'] = value[0] + ram['keys'].append((key, GetInHMS(time.time() - value[0]))) + + for key in cache.disk.storage: + value = cache.disk.storage[key] + if key == 'web2py_cache_statistics' and isinstance(value[1], dict): + disk['hits'] = value[1]['hit_total'] - value[1]['misses'] + disk['misses'] = value[1]['misses'] + try: + disk['ratio'] = disk['hits'] * 100 / value[1]['hit_total'] + except (KeyError, ZeroDivisionError): + disk['ratio'] = 0 + else: + if asizeof: + disk['bytes'] += asizeof(value[1]) + disk['objects'] += 1 + disk['entries'] += 1 + if value[0] < disk['oldest']: + disk['oldest'] = value[0] + disk['keys'].append((key, GetInHMS(time.time() - value[0]))) + + ram_keys = list(ram) # ['hits', 'objects', 'ratio', 'entries', 'keys', 'oldest', 'bytes', 'misses'] + ram_keys.remove('ratio') + ram_keys.remove('oldest') + for key in ram_keys: + total[key] = ram[key] + disk[key] + + try: + total['ratio'] = total['hits'] * 100 / (total['hits'] + + total['misses']) + except (KeyError, ZeroDivisionError): + total['ratio'] = 0 + + if disk['oldest'] < ram['oldest']: + total['oldest'] = disk['oldest'] + else: + total['oldest'] = ram['oldest'] + + ram['oldest'] = GetInHMS(time.time() - ram['oldest']) + disk['oldest'] = GetInHMS(time.time() - disk['oldest']) + total['oldest'] = GetInHMS(time.time() - total['oldest']) + + def key_table(keys): + return TABLE( + TR(TD(B(T('Key'))), TD(B(T('Time in Cache (h:m:s)')))), + *[TR(TD(k[0]), TD('%02d:%02d:%02d' % k[1])) for k in keys], + **dict(_class='cache-keys', + _style="border-collapse: separate; border-spacing: .5em;")) + + if not is_gae: + ram['keys'] = key_table(ram['keys']) + disk['keys'] = key_table(disk['keys']) + total['keys'] = key_table(total['keys']) + + return dict(form=form, total=total, + ram=ram, disk=disk, object_stats=asizeof != False) + + +def table_template(table): + from gluon.html import TR, TD, TABLE, TAG + + def FONT(*args, **kwargs): + return TAG.font(*args, **kwargs) + + def types(field): + f_type = field.type + if not isinstance(f_type,str): + return ' ' + elif f_type == 'string': + return field.length + elif f_type == 'id': + return B('pk') + elif f_type.startswith('reference') or \ + f_type.startswith('list:reference'): + return B('fk') + else: + return ' ' + + # This is horribe HTML but the only one graphiz understands + rows = [] + cellpadding = 4 + color = "#000000" + bgcolor = "#FFFFFF" + face = "Helvetica" + face_bold = "Helvetica Bold" + border = 0 + + rows.append(TR(TD(FONT(table, _face=face_bold, _color=bgcolor), + _colspan=3, _cellpadding=cellpadding, + _align="center", _bgcolor=color))) + for row in db[table]: + rows.append(TR(TD(FONT(row.name, _color=color, _face=face_bold), + _align="left", _cellpadding=cellpadding, + _border=border), + TD(FONT(row.type, _color=color, _face=face), + _align="left", _cellpadding=cellpadding, + _border=border), + TD(FONT(types(row), _color=color, _face=face), + _align="center", _cellpadding=cellpadding, + _border=border))) + return "< %s >" % TABLE(*rows, **dict(_bgcolor=bgcolor, _border=1, + _cellborder=0, _cellspacing=0) + ).xml() + +def manage(): + tables = manager_action['tables'] + if isinstance(tables[0], str): + db = manager_action.get('db', auth.db) + db = globals()[db] if isinstance(db, str) else db + tables = [db[table] for table in tables] + if request.args(0) == 'auth': + auth.table_user()._plural = T('Users') + auth.table_group()._plural = T('Roles') + auth.table_membership()._plural = T('Memberships') + auth.table_permission()._plural = T('Permissions') + if request.extension != 'load': + return dict(heading=manager_action.get('heading', + T('Manage %(action)s') % dict(action=request.args(0).replace('_', ' ').title())), + tablenames=[table._tablename for table in tables], + labels=[table._plural.title() for table in tables]) + + table = tables[request.args(1, cast=int)] + formname = '%s_grid' % table._tablename + linked_tables = orderby = None + if request.args(0) == 'auth': + auth.table_group()._id.readable = \ + auth.table_membership()._id.readable = \ + auth.table_permission()._id.readable = False + auth.table_membership().user_id.label = T('User') + auth.table_membership().group_id.label = T('Role') + auth.table_permission().group_id.label = T('Role') + auth.table_permission().name.label = T('Permission') + if table == auth.table_user(): + linked_tables = [auth.settings.table_membership_name] + elif table == auth.table_group(): + orderby = 'role' if not request.args(3) or '.group_id' not in request.args(3) else None + elif table == auth.table_permission(): + orderby = 'group_id' + kwargs = dict(user_signature=True, maxtextlength=1000, + orderby=orderby, linked_tables=linked_tables) + smartgrid_args = manager_action.get('smartgrid_args', {}) + kwargs.update(**smartgrid_args.get('DEFAULT', {})) + kwargs.update(**smartgrid_args.get(table._tablename, {})) + grid = SQLFORM.smartgrid(table, args=request.args[:2], formname=formname, **kwargs) + return grid + +def hooks(): + import functools + import inspect + list_op = ['_%s_%s' %(h,m) for h in ['before', 'after'] for m in ['insert','update','delete']] + tables = [] + with_build_it = False + for db_str in sorted(databases): + db = databases[db_str] + for t in db.tables: + method_hooks = [] + for op in list_op: + functions = [] + for f in getattr(db[t], op): + if hasattr(f, '__call__'): + try: + if isinstance(f, (functools.partial)): + f = f.func + filename = inspect.getsourcefile(f) + details = {'funcname':f.__name__, + 'filename':filename[len(request.folder):] if request.folder in filename else None, + 'lineno': inspect.getsourcelines(f)[1]} + if details['filename']: # Built in functions as delete_uploaded_files are not editable + details['url'] = URL(a='admin',c='default',f='edit', args=[request['application'], details['filename']],vars={'lineno':details['lineno']}) + if details['filename'] or with_build_it: + functions.append(details) + # compiled app and windows build don't support code inspection + except: + pass + if len(functions): + method_hooks.append({'name': op, 'functions':functions}) + if len(method_hooks): + tables.append({'name': "%s.%s" % (db_str, t), 'slug': IS_SLUG()("%s.%s" % (db_str,t))[0], 'method_hooks':method_hooks}) + # Render + ul_main = UL(_class='nav nav-list') + for t in tables: + ul_main.append(A(t['name'], _onclick="collapse('a_%s')" % t['slug'])) + ul_t = UL(_class='nav nav-list', _id="a_%s" % t['slug'], _style='display:none') + for op in t['method_hooks']: + ul_t.append(LI(op['name'])) + ul_t.append(UL([LI(A(f['funcname'], _class="editor_filelink", _href=f['url']if 'url' in f else None, **{'_data-lineno':f['lineno']-1})) for f in op['functions']])) + ul_main.append(ul_t) + return ul_main + + +# ########################################################## +# d3 based model visualizations +# ########################################################### + +def d3_graph_model(): + """ See https://www.facebook.com/web2py/posts/145613995589010 from Bruno Rocha + and also the app_admin bg_graph_model function + + Create a list of table dicts, called "nodes" + """ + + nodes = [] + links = [] + + for database in databases: + db = eval_in_global_env(database) + for tablename in db.tables: + fields = [] + for field in db[tablename]: + f_type = field.type + if not isinstance(f_type, str): + disp = ' ' + elif f_type == 'string': + disp = field.length + elif f_type == 'id': + disp = "PK" + elif f_type.startswith('reference') or \ + f_type.startswith('list:reference'): + disp = "FK" + else: + disp = ' ' + fields.append(dict(name=field.name, type=field.type, disp=disp)) + + if isinstance(f_type, str) and ( + f_type.startswith('reference') or + f_type.startswith('list:reference')): + referenced_table = f_type.split()[1].split('.')[0] + + links.append(dict(source=tablename, target = referenced_table)) + + nodes.append(dict(name=tablename, type="table", fields = fields)) + + # d3 v4 allows individual modules to be specified. The complete d3 library is included below. + response.files.append(URL('admin','static','js/d3.min.js')) + response.files.append(URL('admin','static','js/d3_graph.js')) + return dict(databases=databases, nodes=nodes, links=links) + + +def userinfo(): + return dict() + +def change_userinfo(): + record = m_db(m_db.user_info.username == request.args(0)).select().first() + form = SQLFORM(m_db['user_info'],record, + labels={"username":"认证名","score":"综合分数", + "bean":"欢乐豆","workrate":"签到率", + "room":"宿舍"}) + if form.process().accepts(request.vars,session): + response.flash("修改成功") + redirect(URL('appadmin',"#userinfo")) + elif form.errors: + response.flash("修改未能成功") + return dict(form=form) + +def add_userinfo(): + form=SQLFORM(m_db.user_info,labels={"username":"认证名","score":"综合分数", + "bean":"欢乐豆","workrate":"签到率", + "room":"宿舍"}) + if form.process().accepted: + response.flash("添加成功") + elif form.errors: + response.flash("添加未能成功") + return dict(form=form) + +def change_user(): + record = db(db.auth_user.username == request.args(0)).select().first() + form = SQLFORM(db['auth_user'], record, + labels={"username": "认证名", "email": "电子邮件地址", + "name": "真实姓名"}) + if form.process().accepts(request.vars, session): + response.flash("修改成功") + redirect(URL('appadmin',"#user")) + elif form.errors: + response.flash("修改未能成功") + return dict(form=form) + +def add_user(): + form=SQLFORM(db.auth_user, + labels={"username": "认证名", "email": "电子邮件地址", + "name": "真实姓名"}) + if form.process().accepted: + response.flash("添加成功") + elif form.errors: + response.flash("添加未能成功") + return dict(form=form) + +def change_userinfo(): + record = m_db(m_db.user_info.username == request.args(0)).select().first() + form = SQLFORM(m_db['user_info'],record, + labels={"username":"认证名","score":"综合分数", + "bean":"欢乐豆","workrate":"签到率", + "room":"宿舍"}) + if form.process().accepts(request.vars,session): + response.flash("修改成功") + redirect(URL('appadmin',"#userinfo")) + elif form.errors: + response.flash("修改未能成功") + return dict(form=form) + +def add_task(): + import types + + form = SQLFORM(m_db.task, + labels={"name":"任务名","create_date":"创建日期", + "end_date":"截止日期","info":"备注", + "people":"参与者","dopeople":"完成者","id":"任务编号", + "active":"任务是否有效","admindo":"是否需要班委确认"}) + if form.process().accepted: + o_pop = [] + group_tag = "" + if type(request.vars.people) is type(""): + if request.vars.people[0] == '#': + if request.vars.people == "#所有人": + for record in db(db.auth_user).select(): + o_pop.append(record.name) + else: + group_tag = request.vars.people[1:]; + for person in get_users_in_group(group_tag): + o_pop.append(person) + else: + for item in request.vars.people: + if item[0] == "#": + if item == "#所有人": + for record in db(db.auth_user).select(): + o_pop.append(record.name) + else: + group_tag = item[1:]; + for person in get_users_in_group(group_tag): + o_pop.append(person) + else: + o_pop.append(item) + + o_pop = list(set(o_pop)) + t_task = m_db(m_db.task.create_date == request.vars.create_date + and m_db.task.end_date == request.vars.end_date).select().first() + t_task.update_record(people=o_pop) + elif form.errors: + pass + return dict(form=form) + +def delete_task(): + record = m_db(m_db.task.id == request.args(0)) + record.delete() + redirect(URL("appadmin","#taskinfo")) + +def change_task(): + record = m_db(m_db.task.id == request.args(0)).select().first() + form = SQLFORM(m_db['task'],record, + labels={"name":"任务名","create_date":"创建日期", + "end_date":"截止日期","info":"备注", + "people":"参与者","dopeople":"完成者", + "active":"任务是否有效","admindo":"是否需要班委确认"}) + if form.process().accepts(request.vars,session): + + response.flash("修改成功") + redirect(URL('appadmin',"#userinfo")) + elif form.errors: + response.flash("修改未能成功") + return dict(form=form) + +def add_group(): + form = SQLFORM(db.auth_group, + labels={"role": "用户组身份", + "description": "用户组描述"}) + if form.process().accepted: + pass + elif form.errors: + pass + return dict(form=form) + +def change_group(): + record = db(db.auth_group.id == request.args(0)).select().first() + form = SQLFORM(db['auth_group'], record, + labels={"role": "用户组身份", + "description": "用户组描述"}) + if form.process().accepts(request.vars, session): + pass + redirect(URL('appadmin', "#groupinfo")) + elif form.errors: + pass + return dict(form=form) + +def add_relation(): + form = SQLFORM(db.auth_membership, + labels={"id": "关系编号", + "user_id": "用户ID","group_id": "用户组ID"}) + if form.process().accepted: + pass + elif form.errors: + pass + return dict(form=form) + +def change_relation(): + record = db(db.auth_membership.id == request.args(0)).select().first() + form = SQLFORM(db.auth_membership,record, + labels={"id": "关系编号", + "user_id": "用户ID", "group_id": "用户组ID"}) + if form.process().accepts(request.vars, session): + pass + elif form.errors: + pass + return dict(form=form) diff --git a/web2py/applications/SP/controllers/default.py b/web2py/applications/SP/controllers/default.py new file mode 100644 index 0000000..0c73412 --- /dev/null +++ b/web2py/applications/SP/controllers/default.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------- +# This is a sample controller +# this file is released under public domain and you can use without limitations +# ------------------------------------------------------------------------- + +# ---- example index page ---- +def index(): + response.flash = T("Hello World") + return dict(message=T('Welcome to web2py!')) + +# ---- API (example) ----- +@auth.requires_login() +def api_get_user_email(): + if not request.env.request_method == 'GET': raise HTTP(403) + return response.json({'status':'success', 'email':auth.user.email}) + +# ---- Smart Grid (example) ----- +@auth.requires_membership('admin') # can only be accessed by members of admin groupd +def grid(): + response.view = 'generic.html' # use a generic view + tablename = request.args(0) + if not tablename in db.tables: raise HTTP(403) + grid = SQLFORM.smartgrid(db[tablename], args=[tablename], deletable=False, editable=False) + return dict(grid=grid) + +# ---- Embedded wiki (example) ---- +def wiki(): + auth.wikimenu() # add the wiki to the menu + return auth.wiki() + +# ---- Action for login/register/etc (required for auth) ----- +def user(): + """ + exposes: + http://..../[app]/default/user/login + http://..../[app]/default/user/logout + http://..../[app]/default/user/register + http://..../[app]/default/user/profile + http://..../[app]/default/user/retrieve_password + http://..../[app]/default/user/change_password + http://..../[app]/default/user/bulk_register + use @auth.requires_login() + @auth.requires_membership('group name') + @auth.requires_permission('read','table name',record_id) + to decorate functions that need access control + also notice there is http://..../[app]/appadmin/manage/auth to allow administrator to manage users + """ + return dict(form=auth()) + +@auth.requires_login() +def myhome(): + user_info=get_user_info(auth) + info_menu = UL("认证名:"+auth.user.username, + "宿舍:"+user_info.room, + "综合评价分:"+str(user_info.score), + "签到率:"+str(user_info.workrate), + "欢乐豆:" + str(user_info.bean)) + return dict(info_menu=info_menu) +@auth.requires_login() +def change_settings(): + user_info = get_user_info(auth) + form = FORM(INPUT(_type='checkbox', _name="ifrank"), + " 加入班级排行榜", + DIV(INPUT(_class='btn btn-primary', _type='submit', _value="修改设置"),_class='container center'), + _method='POST') + if user_info.showrank == True: + form.vars.ifrank = 'on' + if form.accepts(request,session): + if form.vars.ifrank == 'on': + user_info.update_record(showrank = True); + else: + user_info.update_record(showrank = False); + response.flash = "设置已保存" + elif form.errors: + response.flash = "设置未保存" + return dict(form=form) + +@auth.requires_login() +def task(): + return dict(if_done = False) + +@auth.requires_login() +def finish_task(): + record = m_db(m_db.history.type == "task").select().find(lambda row:row.t_id == request.args(0) + and row.u_id == request.args(1)) + if len(record) == 0: + m_db.history.insert(type="task", t_id=request.args(0), + u_id = request.args(1), time=datetime.datetime.now()) + t_record = m_db(m_db.task.id == request.args(0)).select().first() + p_record = db(db.auth_user.id == request.args(1)).select().first() + peo_lst = t_record.dopeople + peo_lst.append(p_record.name) + t_record.update_record(dopeople=peo_lst) + if request.args(2) == "monitor": + redirect(URL("monitorctl", args=[request.args(0)])) + else: + redirect(URL("task")) + +def myclass(): + students = m_db(m_db.user_info) + class_info = UL("班级已注册人数:"+str(students.count())+"人") + rank_list = students.select(orderby=m_db.user_info.score) + return dict(info=class_info,rank_list=rank_list); + + +# ---- action to server uploaded static content (required) --- +@cache.action() +def download(): + """ + allows downloading of uploaded files + http://..../[app]/default/download/[filename] + """ + return response.download(request, db) + +@auth.requires(auth.has_membership(group_id=1)) +def monitorctl(): + t_record = m_db(m_db.task.id == request.args(0)).select().first() + peo_lst = t_record.people + dopeo_lst = t_record.dopeople + prcd_lst = [] + for person in peo_lst: + p_rcd = db(db.auth_user.name == person) + if p_rcd.isempty() is False: + prcd_lst.append(p_rcd.select().first()) + else: + p_rcd.append(None) + + return dict(t_record=t_record,peo_lst=peo_lst,prcd_lst=prcd_lst,dopeo_lst=dopeo_lst) + +def history_task(): + t_record = m_db(m_db.task.id == request.args(0)) \ No newline at end of file diff --git a/web2py/applications/SP/cron/crontab b/web2py/applications/SP/cron/crontab new file mode 100644 index 0000000..6ab4ea8 --- /dev/null +++ b/web2py/applications/SP/cron/crontab @@ -0,0 +1 @@ +#crontab \ No newline at end of file diff --git a/web2py/applications/SP/cron/crontab.example b/web2py/applications/SP/cron/crontab.example new file mode 100644 index 0000000..6ab4ea8 --- /dev/null +++ b/web2py/applications/SP/cron/crontab.example @@ -0,0 +1 @@ +#crontab \ No newline at end of file diff --git a/web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_cas.table b/web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_cas.table new file mode 100644 index 0000000000000000000000000000000000000000..2e3b45b88ccabf2fc43255af4224d63f189f4420 GIT binary patch literal 684 zcmZXSOK;Oa5P+R`8d4rDr94`?T{t)wq#|+X(Q=nI3U({UNZV87CQH}CtQlvQs0T~E z=3g`G1gOHzvorJUH#@#>l;F6$?l?|5gIWo7m$xy<gu2xd8i7-<Vxv+p0-8(S!K})) zGFb+#CGTQ5&kLR0WCGfw8gJr(zWXVlBWt{2vyefTALG|BjM+Jh$W=59yy%*Y*fsIK z#+Sp;k66IM7`Au|>k5_p5YVeoG@Vg+#JB8mvY4z=eOWV=h?$FGg5ujHJa(nEmCdDW zEoFODmmR)qyTmt92sITXF<MS+2RxBoe)>QtVxL*WLZ6KZ{aZzeYcC&=%aEM0FDz!n z_r|_=#t4C@vR66LwE=}^vM;v{?;&<th(wFoBv-Ig!tRDx1I6sC&9FwNIOub<vGc{l zfQ@4>xPm>T_wj`OBT;yP7woLY#u<L4Qvv%WyxgESk!}|_*F~ys;nkY$UwD!G>Ez=8 zUjH#)LnypK@V=?KbUOVmG#r$0xWR47j{G0?7GZW4x@x3wgscOz+M-Zm0i=ZE4OANy j?O$}0=b1<pP;|6$<#;lHcL=pH#kGkAh4;uL#(ek<OU0~& literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_event.table b/web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_event.table new file mode 100644 index 0000000000000000000000000000000000000000..9e8e7bd1ec03db5f92b071ec25dae3882130ec74 GIT binary patch literal 694 zcmZXS&2Q5%7{=4@u4`dz!1x&8c^t9}5=b04Mwx-CB%9J8d8a6}rnZ!(eG^;2A=0k> zuX&w~g38VB*U!)U*f*^T9G5p8$5C@=RM2#J7lTaX3oW4)IL$gXxdJ1gz2QBq<}00> zEQ8L5_c1J2g-*X^0=kn1Z(~CLS_|mO25;FaWYFiQcp8T>`@|x06^#Qgx+W8LO}wx1 z<v8>s7O*geJ>J2-B2SkB1~rPRIfZ?`XVdAA<hC@F4Z{bR(rPJ^Qm4x`j4HV2N-J2l zH?p&l-APmSYJKxm3)>0zWxpoH<A6<LFSvpOIp9MC(Z3`L59CmeOx-!ll*o0W)^J$C z(GI_bd}~&z3zaY6;T_%o>_zVTx9`s35z_Z9eT$*+7~zMew$YTLNYM7<3ZCqs+lW5G z$wGV=g~(@uq(;lcPQX*V=L6RM*cq{pEMlS0ri5<0C~>WI=j1XZ7wij*8S%ZT?_DrL z;2G+&j?y~?6rQ81V^eRlD%3*da8kjG9Z?<Glm9RI5@Gfi(Az-@uaI?O>c!`xoE2)V s)hY*4!D$V=**;Jgx2*q*_^E;7S~iFokKqiVBMbe9K;bo#i7{_}1MJhXX#fBK literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_group.table b/web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_group.table new file mode 100644 index 0000000000000000000000000000000000000000..cb6ec31f5ca9ab8410f8096bf6150ccbfd6c0028 GIT binary patch literal 361 zcmYk1OH0E*5XbXs)2EO6IM+SJi=f~K2xZX_8YM*7o}}8PyAU^>bQkpy=r!Nk$qM3a ze)AuGGjs48a3bb8jw3hVHsD39k5F>8)dKvb<5@OJg5eOfEW}h*TA8whUdslE`>NLK zw~|9Yby<K7{k`K53YYm^3MCBK6;?@B&<C2&pYvoH=c{>2SM&I#cuKNGPM0(*V90tn zSF800hmlngxgjuS!>+yleEp3k!ZkLnE8IG5;3yK^sUm1auND2&6QMnOuWPBca4ZJa zuy~B~=>GQZ8cxK>4v@}3;8aY+)UYvb+3@{)Eq7X03T6$QS@Yq~?4#Mf$iFn4qql>C UvH~tpIYl7<3<NIGJTvCz2k)m^0ssI2 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_membership.table b/web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_membership.table new file mode 100644 index 0000000000000000000000000000000000000000..27ad4149c16a6e530f6db4a86f4829360cea6cc3 GIT binary patch literal 492 zcmaLT%TK~E7y$4+fDHs6fSzkl^Wt4^%czDR!;G1f6PZ#e$=vwH8slM!*ZtSF^%0{9 zw|?(m`fgWXc+@fsW3vLY0?VT<8Kf**mmKV=Vd+?88xRZ{HFab)%gaopDKu;9%5aw# zW%8IZXiZGokcskb%fR6#wN({TaOt^xjl-DSk_g>L<EbAl(1a|I{}9i{VGxli31eu} zrtB-S<b^>;ufm%Zh6CDG>Ew0!S?Y3AXo%RcVkzOh3JyK4w7gOCX3bj@i#v3nrr0wp zSoXwFB1*ng6L7>`di4twksA_`Fd%b;f4VU8)bR^63(<(&k(i*sp9lVkAOy#}qfPir zfZ>F9c~9v7SQok2DptRO!5@|_S;PM<Jpx1Ny58r~ZF^y-64sF`@HYa(nUwW~xcmV9 CS%HZF literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_permission.table b/web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_permission.table new file mode 100644 index 0000000000000000000000000000000000000000..7f1e446c1e1a4f9e9cbda670778588305909fd89 GIT binary patch literal 601 zcmZXR$xg#C5J1y?p=@O-JI1GQK>~>jw<s8>N&^Z-a!*yDrj8WSP8thwh{Uyj&DelI z<>v9sym=mf6f&@Ep0_M396~OGyv@rPL?Rxg5(-@_Z(<dPpac|Wyn@+yoW?4OpfuxE z45#BH4W1$a<xY+l@gjYn2&l*$FX${pP~}H>YI{9)&3tn2x4VwtCmq%&&SUSc?YTbd zGOq_UUc$O04qgS+4T^?C3JbiZuY<S2SE?a%%1j<5V>KC|`C<l3w$!?^IFqHBEO+v< z!q;`1coB(+p9Kk2DhH+omSvS+{894R74w<rvIjzc%P6t+{9|(GkxO>VdW^WvgX>%} zLSRMKc^wh-M}oqtY{*4ryv-Au8LZ7&70^mAc$y|*Jc4!f&~I~Z9N#`aJv)XC#Oea7 z2^2OF*;Hnb+3~=DTN!N4fs3*t|I@aS*3h)yW(qsVY^krEisx}M)EnH*U~djtLRbCW fVVsJQNMIjjb^QI0aDeay4Nrb36b_NStJKLSqMDeV literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_user.table b/web2py/applications/SP/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_user.table new file mode 100644 index 0000000000000000000000000000000000000000..5bdd83e79096f7f8c647db6c17a393276e1ad6a6 GIT binary patch literal 1160 zcmZuxYg5`l6h+=>t!VAjK5*M=@L8x*`&6WvmZ4zFz)bwa#InQ96oWU(j^l^S__6%! z-rW=|Dc{(;_nve1+!L;2K1MVn8i_=#F3$KE)r=$^`rPh$fU$Zcs?Nf;P;iV7jTGJ5 z1J4%yJ|>1nnvU+k@yxS6$7F5Bh*QD4y5N`^p{9+PY{EWfj8*zoZM5_+dNcRES*@3w zr@5Mbnk%<kC)Gx!sn_*J3ulc4^*OeA&T&p5GONq*mXVQV^Rg3M%|lwKTh(~m#{~^y zwIhfRAu)txEea_m-t`>I?qL=(N^a$Axv7=*^0)|d>YmAYhD$JigLX%#Ug7e9YuU%U z5<Ls?-vN3IQXnB0NRxsrl=8WDqxz$*<2^#2r8*nUGrUje(yUPh9|Q~+rt4k~oGw1} z@ewhQ<KqX!=>c+P+_OS_(gVe}Unu7B@rY^E!|(~r!-`NA@^jPb<5M4>N$uBT;KX0; zW2{2)Adfl1lIvw^jNvLtmWv2bSODq%95@`G`}kraDKA4wS({ACdMGJcEqRlayxKx{ zAY_I%#%bA9<<BSW<8L}{{S%4pK&4W`a3_?CUDX-Ld==#5jGHzVd@O1pb;8;Z)`y_g zQjmuY*n}<E4uT*X8NP;HB~Fd)2_s7$IJ{?3j!e%Q*qvYe3io|1h1Qh}yQ((yhFo2e zu7)8P9+1IP!QTos;&7LHozZ3$?K>aehiFq%X+IF{azGmfVfc}VrKTwapM*;Egjo7( fIP~!-#G9VVTPEJc|DG#9-(w<`A4?dzBE-%g-tjVw literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/databases/fb87181b96a99be45f5a23f4277867ce_history.table b/web2py/applications/SP/databases/fb87181b96a99be45f5a23f4277867ce_history.table new file mode 100644 index 0000000000000000000000000000000000000000..d2b174d63adab953800dc5c88cc3bdaebb12bfaf GIT binary patch literal 545 zcmZ9JO-sW-5Qg*Fw6%WJk7~7Q%qd<31%E&&K|@I`F~as#B3-(Hm^x_|@euHuf9-5i zddO{O=6xULo&8e_kZhtzk`ymNE<mwK3yXxNtDJ%AOG;JqGzLyVD~W;Abe*R>NkA`2 z8_Uf)%cIYPLTe%u4IBCIHwA;qL={s=piS=Z<xNBP#SP3^;Q3B4Hz)4gbUwm2Z#oWK z-<^igAv)@^H2R{@tx#6Hv|x{PL_7Lf)T17gIWr2_x0%?GX(iK3)|x2HsJ7kYS)8um zfVC^*_|*yQ=f|geIAq;QV2KSaIAT3!@OtG1=I<A9+(4>`6p`aJrz@Jl2{J{!%>t)8 zA_6QpLt?)sazPvvaNZzl%wR}iJEss@aDmQ2?fj%s3c~^}8&19H6haHG&^g?ui1Bcv o0<Ig*7N!tCwTyC_3(d{;G@<9a@1f(*;C2@T=N6a<9dZ8f50!s|3;+NC literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/databases/fb87181b96a99be45f5a23f4277867ce_task.table b/web2py/applications/SP/databases/fb87181b96a99be45f5a23f4277867ce_task.table new file mode 100644 index 0000000000000000000000000000000000000000..9ef62017d3035afcb8eb259cb96f375943bc29f4 GIT binary patch literal 1167 zcmZ9L*>BT85XRHo2Z3_mkS<rkQAnX2<qXBNQIt>xBe_qNTW`9ST)SUl1AVa6*ZkMa zuI-Tc#q#XV{^px+cTRI5GEF0!$z*H`OChpNqey|n-9uj>*Uw~C9Jn?Dj{MXp(XQ+H zZs0g5OpP*y6L0LB`wmC3w`AmL!9O|XC?(Xgk&{VqP%&2MuRGASEp6D?8Fu@f;cla+ z?KV2U^dH^9=1}Wv107YPKzU==JmRP+BC{=qGe$)&n}7DAt-2@&YF8zm4RNk1q+*eu zio#SBds$IZ>L>o#b`P;EDvGeV-5EC5+iNYH7d4f@B!S_AsQ>3(42&9;I~a4*=X(}? za4E#)REZpwkRHf=-zL3R;v#ytul>|J{T*DTB6Uh(b0~&uR4dKD9w-)ft*G9O5I0lx z@}eZDgpkmxgeJ)hw}>dEBrCWbxnsK{4|hV`RjAXMI|Y)iZj1l*(ID9}&^1HHN@9yV z%D`e<6zE={96RRTG2Qt65Dy63Tb@yiM3sFx_Qc<ajekgjB~z+n(Mg6!M3ql1CN-np zEiaB+As(lCFH!FaO7)&3GdziVPgd|Wl4&0J_HT}7Ay!kcGU=3WdEfIKZn}6*2FO@F zj&=(#61@?Ep&jduk!z8;6Yh-gGQ_Kexmi!m&FjUvd6Sx(x4p=GH8<}TWNplb=lz1b z4|5~(F?z#N3d5(=kbG9xs$_l%6vDKQY}fM83Gp>$N`)LIBZO>T&Kiqz88)eVX-{(a mTc8r`k)V6_#wXB1d{5D;b2RxR*esi2i+HlaYzf;zu=)=uOf13x literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/databases/fb87181b96a99be45f5a23f4277867ce_user_info.table b/web2py/applications/SP/databases/fb87181b96a99be45f5a23f4277867ce_user_info.table new file mode 100644 index 0000000000000000000000000000000000000000..cad9e64844d4ad52e047c0bc9a2bd2b0e95a983f GIT binary patch literal 645 zcmZ9I%}?7v6vUl4i9>+W(o$MlO0rNXxgb#i=cd%6QJPR$L0V48X;y56@iMkoQ4f~5 z=D+6cx~{6+_I=E6-^`Pn!|C#><2dsfDmkiM-k>59@m(h2j-0Bkbv%a_s4cli(^zG( zjv~~Tyh&xMk}RA?0*zsX*Qk;Gc@*$ug}Y{o2u<Fh*I+#HFa4nXD;SLW!A*PU-?aPJ zldHk_BJfB4c!D)vr@bT&9|T$!#pW}Hb-rfW;o`O!ZODqYKkHN!oy{CCy3!qfm9?d; zFJ)s`m7cvk&60V1hb`H(ii;oppnHDW!%NxXEuylL!SG6M$W3ieNPnwDU^~ZaqEZO| zu<l>%Oljlz4Pi}Q-><H}{q(UzP!kZddWN?|+}75}RD>~hbG%yt)}$wiB8}9Lm|0|a zPs-iG<U%F)Ntg-j<@m6ouK%aDZpvkbk3`rj{!Wy7z<!QTE9wTRO)w^18_e0smmUtv zON@-6O`QGWl2oci62|xF<X|f-kAgAQr%FY}>LGDWZMi2s9F=*O5Qfi0?r44d4Exre A_y7O^ literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/databases/sql.log b/web2py/applications/SP/databases/sql.log new file mode 100644 index 0000000..19b0caf --- /dev/null +++ b/web2py/applications/SP/databases/sql.log @@ -0,0 +1,3696 @@ +timestamp: 2018-09-23T16:05:40.158876 +CREATE TABLE "auth_user"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "name" CHAR(64), + "username" CHAR(16) UNIQUE, + "password" CHAR(512), + "email" CHAR(128), + "score" DOUBLE, + "bean" DOUBLE, + "registration_key" CHAR(512), + "reset_password_key" CHAR(512), + "registration_id" CHAR(512) +); +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +timestamp: 2018-09-23T16:05:40.163956 +CREATE TABLE "auth_group"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "role" CHAR(512), + "description" TEXT +); +success! +timestamp: 2018-09-23T16:05:40.166728 +CREATE TABLE "auth_membership"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "user_id" INTEGER REFERENCES "auth_user" ("id") ON DELETE CASCADE , + "group_id" INTEGER REFERENCES "auth_group" ("id") ON DELETE CASCADE +); +success! +timestamp: 2018-09-23T16:05:40.169314 +CREATE TABLE "auth_permission"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "group_id" INTEGER REFERENCES "auth_group" ("id") ON DELETE CASCADE , + "name" CHAR(512), + "table_name" CHAR(512), + "record_id" INTEGER +); +success! +timestamp: 2018-09-23T16:05:40.171695 +CREATE TABLE "auth_event"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "time_stamp" TIMESTAMP, + "client_ip" CHAR(512), + "user_id" INTEGER REFERENCES "auth_user" ("id") ON DELETE CASCADE , + "origin" CHAR(512), + "description" TEXT +); +success! +timestamp: 2018-09-23T16:05:40.174358 +CREATE TABLE "auth_cas"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "user_id" INTEGER REFERENCES "auth_user" ("id") ON DELETE CASCADE , + "created_on" TIMESTAMP, + "service" CHAR(512), + "ticket" CHAR(512), + "renew" CHAR(1) +); +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +timestamp: 2018-09-23T16:48:17.192606 +CREATE TABLE "user_info"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "username" CHAR(64), + "score" DOUBLE, + "bean" DOUBLE +); +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +timestamp: 2018-09-23T20:23:38.851660 +ALTER TABLE "user_info" ADD "workrate" DOUBLE; +timestamp: 2018-09-23T20:23:38.857075 +ALTER TABLE "user_info" ADD "room" CHAR(512); +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +timestamp: 2018-09-23T20:28:47.060282 +ALTER TABLE "user_info" ADD "showrank" CHAR(1); +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +DELETE FROM "auth_user"; +DELETE FROM sqlite_sequence WHERE name='auth_user' +success! +success! +success! +success! +timestamp: 2018-09-23T21:25:25.867859 +CREATE TABLE "user_info"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "username" CHAR(64), + "score" DOUBLE, + "bean" DOUBLE, + "workrate" DOUBLE, + "room" CHAR(512), + "showrank" CHAR(1) +); +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +timestamp: 2018-09-23T22:23:53.430906 +CREATE TABLE "task"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "name" CHAR(512), + "create_date" TIMESTAMP, + "end_date" TIMESTAMP, + "info" CHAR(512), + "people" TEXT, + "dopeople" TEXT +); +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +timestamp: 2018-09-24T15:57:20.140617 +ALTER TABLE "task" ADD "active" CHAR(1); +success! +success! +success! +success! +success! +success! +success! +success! +success! +timestamp: 2018-09-24T15:59:58.137215 +ALTER TABLE "task" ADD "self" CHAR(1); +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +timestamp: 2018-09-24T16:14:24.370936 +ALTER TABLE "task" ADD "admindo" CHAR(1); +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +timestamp: 2018-09-24T22:02:29.127833 +CREATE TABLE "history"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "type" CHAR(512), + "t_id" INTEGER, + "u_id" INTEGER, + "bean" INTEGER, + "time" TIMESTAMP +); +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +timestamp: 2018-09-30T20:02:59.780509 +ALTER TABLE "task" ADD "ifhistory" CHAR(1); +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! +success! diff --git a/web2py/applications/SP/databases/storage.db b/web2py/applications/SP/databases/storage.db new file mode 100644 index 0000000000000000000000000000000000000000..c52f39888a38353bee202484cd34e79b0c73892d GIT binary patch literal 20480 zcmeI2U2NM_6vyqRBkAWQ+CtSuC|0&gjruWvByD3Mv@k+fv3}5|(ke76w{dCOChi=E zvMCR13#=7l0`W1V4Y5i{+Y77$9-y!X-gwxac|aOMG-;oac;ba)$Ik4usiwV^oup~( zbI<*sdw%!aNZ0n*Yv)p$%*-fiTGAMSdX}PT>NLYp6s5xF2z;!U8xCr%6ZocW$JGv1 zs{7=XrlvboZNnx-jyC_&u-W*qnlsvw01`j~NB{{S0VIF~kN^^J5?JYQxm$cb`kkmI zO)bcpl%3Z<wP!}-u|%9n#9lfVXM(yZ*j~@TE0{_KnSr51ygxq5jEoKp#zrTYSK|{* zY&<bMFa-Su<3owgl5a*z%R%PM+1O}%gyTb|by}4rO`c4`zaWzs7>ti4VuK@Qqnt@r zX-Q>fl)Yk$va-0K>%`AnQIm?@Sl`J6rD-komNgPC1eUD4Fk^}t=Tb7A$|Nm)!<3qt zO=UGjy;SxKE%(>DTl{`{1wa8Uv)%kU;$&uZegbUTrA2G7Hf-9Y4ZTS#w~uW~mNMlj zGX1oaJ`rWs^&!}9wHotIaNh0n9vZ26rlq5Uo-nXvFD}4tb}}np%*mN)x#HC2nDC0m zcD?pHp=W4$j&`>M0`%$$Lo=6^)k(dU%Lg?MonYDiBr8tuY+H3bVQbN4rxg`S;N{_Q zSkY!xlq$txT2j<`)mWGgv#KcRy=yN!t1PKfX1=^Y>O)QN^HM_|P~<Q2fPCNFzu(*W z3xsD#00|%gB!C2v01`j~NB{{S0VMEL6QEa*dOWnBB$RY=JTsqBmNKuvMT>N+VI7mS zoSLyWBrX^YFTA;sQ!?F}qAX;)V>xY>QKshPX^nxq(d^qCHzkC_QMT_zd)L;->)O{7 zW_f2<>fwHaq<*b3Nb2t6MVjKnl03uO2T5uBMtY-Kr1-w>r>eQ1+SmP<*F)`X@Y5a& zblg5tnuXKn`@cDM`OmX)o)Z#H<ZsGF?o;GG*(JX})fJ4%BLO6U1dsp{Kmter2_OL^ zfCP{L5;znDnrK&mE<cUnZE(5#wE0vE@zl6{wEkF-A5v+qD|_kp|7o&8kqr_ejm`HO zzqH<mB4r#T5<mh-00|%gB!C2v01`j~|0e=2i4%mjsJHO(8vGT%-6-B%FMRmH&h1T} z<@&nVXcr%5I8F=;A}{PQah%!XtE<KD?&J$U-`f6RJzxCdTH(fx{O;;T;oYzE`8+%V z{ckTs8TJ;|HVa#yLWlzb@uI*v0|`+vd{Ceh#q}$oxxKZO-?{ew_SPq*m{;}81aI;B zt=-%2RSzieBFk3<<irT;$jlbPOwvf}WCw)k_wH^kSJ&rzMK<Ep=Obby>d<$RJCTQs z@{m$q&q<F&Z|RZRya%E)WGf;GqR{7vWXr@5mP}zN>emB;V1Bhlpd#RS7)))?o7DjY zVpoSG!XgLH06eM_!^HBAfMzx5!7RDr+DFCD?*g?)eWCHUHi*^HK`27DfBFm@3fJ{N z%ST`to)!79$o5s31To^w(MhwSEE5TMaDtlC6N6wE{EbwrAoxmgcUFFc5_QT8eIj3~ z5033(IeicUOew41->;CiD&LF`k@Wq)r}-a>{6X%Ko8&T?Aid-{FyIRbAOR$R1dsp{ zKmter2_OL^fCP}hVJ8qEZpug3c?9EzxUrjttutIlf~~WD9jQ0ae1HQd@+{M&JJ6;= z&7KW;Bob)cBLUZ{O4kTr$1e0T4K|76l@dL0O(sxplQ>=x0~`dV&L+`XA;Ci;Y`|la LXmv_(Akq6DZ1ZSx literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/databases/storage.sqlite b/web2py/applications/SP/databases/storage.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..37840fb61a33d7f2fa4d031bf3d4f049d101a8cf GIT binary patch literal 40960 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 SiPV4ek9MW!Xe6TBX6Y{zZp4WI literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-22.18-19-16.eb57736d-d461-4d86-8577-c7454f82f56b b/web2py/applications/SP/errors/127.0.0.1.2018-09-22.18-19-16.eb57736d-d461-4d86-8577-c7454f82f56b new file mode 100644 index 0000000000000000000000000000000000000000..40807c379aee71e900165a3ba8b66efddbd02d6f GIT binary patch literal 60558 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.13-54-12.04660296-7ce3-4dc0-ba16-8b688a41df11 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.13-54-12.04660296-7ce3-4dc0-ba16-8b688a41df11 new file mode 100644 index 0000000000000000000000000000000000000000..4f1c47411ca49a7f48ab6a54d6711c3f3b2ecccd GIT binary patch literal 38394 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 A5&!@I literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.13-54-21.5c142673-7f02-4f59-becd-f8a8458197b8 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.13-54-21.5c142673-7f02-4f59-becd-f8a8458197b8 new file mode 100644 index 0000000000000000000000000000000000000000..02d1bf223896e38b7c1a499a84d1e7731e5742f1 GIT binary patch literal 38394 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.13-59-27.f2e76b1c-d22b-469f-a693-39b6af0b0fcc b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.13-59-27.f2e76b1c-d22b-469f-a693-39b6af0b0fcc new file mode 100644 index 0000000000000000000000000000000000000000..016f390789cecbf92f2bece1549682a65e55e63a GIT binary patch literal 40135 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.14-01-43.8f7a6d8f-112e-49d0-b426-5391c93f8986 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.14-01-43.8f7a6d8f-112e-49d0-b426-5391c93f8986 new file mode 100644 index 0000000000000000000000000000000000000000..1f451bcc6fd9c79b9a0eb7efd84fda9060127ed7 GIT binary patch literal 41287 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 J|8+W<{|Da8Eqed} literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.14-02-44.e5d30aa7-20da-4772-b99b-9c0f6fef9a98 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.14-02-44.e5d30aa7-20da-4772-b99b-9c0f6fef9a98 new file mode 100644 index 0000000000000000000000000000000000000000..0c57cb9ab7394eb202513e60ca12fae264f40400 GIT binary patch literal 38737 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 H1oHm_cTz)) literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.14-04-32.75533ba0-3cde-4ff1-8c00-9bbb2d28d8c8 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.14-04-32.75533ba0-3cde-4ff1-8c00-9bbb2d28d8c8 new file mode 100644 index 0000000000000000000000000000000000000000..0dd6538e21cd9058d611e2288340596f7ce4d205 GIT binary patch literal 38729 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 A(f|Me literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.14-36-18.ffba9911-051f-4f00-8da7-a20a9d5a754b b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.14-36-18.ffba9911-051f-4f00-8da7-a20a9d5a754b new file mode 100644 index 0000000000000000000000000000000000000000..b76b72bb4d4cea8ff34461ec82a529e7c299c12b GIT binary patch literal 1696 zcmchX&u-H|5XJ-jLz^3KFp7kdR92j(rB$LP5(j!hs8WmY&05=IXX$#^-d(pfQYGMy z#6xg~r$XvuFm_0r3fe;oT&(f#YWFwa%zPhKF7rmmTWd5Lf|aQAN8T%n-8Tlcai>Me z11=Nys0^n}r$<`7!_XSHkd|A4k$aB8AS+##WrByyawUy>eB`DoLSft}=w)U8*juG5 zLt4sLyiXJ!R57Tax(g2IY$0$0%tHTSdwX|(xW60p9f-L=X#Gu+mIH!Ig#Agr>a7!q zDr{ERe9e1XQwe4aw2w<^*~Lq(m2OYqkfVr3z~vbeJOaxCqLM7d5nO%ydiDL|k1wAc zC=7zGRv}gzT5%y|*{YA3eBIlm+pT6H1}r?ypLkD6?vwdHbW&w3Xbe$W2$>K-9JV`Z z0zJNr1c@k=bTt~Qd1x`B8q6~vY!4mEg<hL)(klRXfng`Cs^S33Gp?0PiKe?W!hQWP zXBqC*DD(Q)Agr*{UW74K$*-k09g?<Ic6_1>!ZSRP%oZBQhfEk;9&x6URZ5sef%-#g zJyPfvM9pT340Y!P5fTN8xO)fa0;2;dPc*Z{9kWyPfBkiPv*i5iWPHJmU0Ur~DwTFD z;|s~`4DQN>x-?~W+<tZ~Z`ZWD4;3?`_GSsv+%w^3W%Ui1!3Cn{e^9p;cQ#k!TG*ao z?@NEN0G)cfnlA^o;%Xud1zV@*Oef~wQ}6W$bx-`pbql>_^ux+TI#qu-Gqd=A)H6f9 z)y=y*HMs9{$*u3#yzP6;stwO>sBeTlsN6y(llkbrRuY>FJ~?{0O*ZolZ-ac&NS2wY Mvias^-Yj}Q0fl2rnE(I) literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.14-36-24.36e7b540-e50e-4572-a869-d16cab440b1d b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.14-36-24.36e7b540-e50e-4572-a869-d16cab440b1d new file mode 100644 index 0000000000000000000000000000000000000000..b76b72bb4d4cea8ff34461ec82a529e7c299c12b GIT binary patch literal 1696 zcmchX&u-H|5XJ-jLz^3KFp7kdR92j(rB$LP5(j!hs8WmY&05=IXX$#^-d(pfQYGMy z#6xg~r$XvuFm_0r3fe;oT&(f#YWFwa%zPhKF7rmmTWd5Lf|aQAN8T%n-8Tlcai>Me z11=Nys0^n}r$<`7!_XSHkd|A4k$aB8AS+##WrByyawUy>eB`DoLSft}=w)U8*juG5 zLt4sLyiXJ!R57Tax(g2IY$0$0%tHTSdwX|(xW60p9f-L=X#Gu+mIH!Ig#Agr>a7!q zDr{ERe9e1XQwe4aw2w<^*~Lq(m2OYqkfVr3z~vbeJOaxCqLM7d5nO%ydiDL|k1wAc zC=7zGRv}gzT5%y|*{YA3eBIlm+pT6H1}r?ypLkD6?vwdHbW&w3Xbe$W2$>K-9JV`Z z0zJNr1c@k=bTt~Qd1x`B8q6~vY!4mEg<hL)(klRXfng`Cs^S33Gp?0PiKe?W!hQWP zXBqC*DD(Q)Agr*{UW74K$*-k09g?<Ic6_1>!ZSRP%oZBQhfEk;9&x6URZ5sef%-#g zJyPfvM9pT340Y!P5fTN8xO)fa0;2;dPc*Z{9kWyPfBkiPv*i5iWPHJmU0Ur~DwTFD z;|s~`4DQN>x-?~W+<tZ~Z`ZWD4;3?`_GSsv+%w^3W%Ui1!3Cn{e^9p;cQ#k!TG*ao z?@NEN0G)cfnlA^o;%Xud1zV@*Oef~wQ}6W$bx-`pbql>_^ux+TI#qu-Gqd=A)H6f9 z)y=y*HMs9{$*u3#yzP6;stwO>sBeTlsN6y(llkbrRuY>FJ~?{0O*ZolZ-ac&NS2wY Mvias^-Yj}Q0fl2rnE(I) literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-04-11.b47795e9-b7d8-46a9-ae91-efc4733dca39 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-04-11.b47795e9-b7d8-46a9-ae91-efc4733dca39 new file mode 100644 index 0000000000000000000000000000000000000000..375e849864f07c78d362668714ee214162728f8b GIT binary patch literal 44055 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 B-dX?v literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-27-29.a5c546a7-8774-4128-a2ae-519ed5135e08 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-27-29.a5c546a7-8774-4128-a2ae-519ed5135e08 new file mode 100644 index 0000000000000000000000000000000000000000..039088dd8589810cdcd61400ed6485a80244f726 GIT binary patch literal 42290 zcmeG_2Vfh?aU$MTE^&R^u^pfJuLqzf4}~2f=};6U@j;M$lKMYMuRkB|7Qjgd9QF!} z6ef<7Pw%}rjuSh*_uhN&?j=s|agtAS>dfvPa3BCZxjen}e)3-gc)L40J3Bi&ZTH@E z*DgJlQl5G2*fC4nAr2i-mf(Blf=e7XQ}cJsve~F+R(JH8=G0dm`zp~rH{&-v)3b<? z*&^k9b0?!Uo0h3-o@qDS%=&7kZX3jMGe%i%?$Ctt3;?OaBYKzeX81ad-zB?@u%v0I z>sw@2(mW}<oy(1m5~5FKhop*W5os_^Oa_M}%WM#7VwOHbc@`jI`(D%c=rff^8CI6& zx>9m|r{QVa3yxzu$yv#4Y-*NiNS;=<NJh6Uzuu4<S{+a`Y#*KtN~SAm(%{_E(xBuJ zpxY)fr1b}vGRrIQTe?Pewrt0s&r+TXop_F>ld`5?qt8~}4rJK~|CUm9+w}l|P8y!1 zYnCMeI$pYPT$0WTQKD-3b|V8Ad5)=j#DJ*?36RfC4Z+9|-JlS9ktDKB^puX1GbEA5 zrs>#?I$)C)M&V{`5#o}|jxbz8K46$^IVL0c%vsHH0UL*C22Mcuw?QhJZ+SDxWIBCH z7(Gs*Cd`IbCBUtkm1*wa@3Q8S2)V|P9f4fXE3l8sFk@)4Z_<q9600Ix+VveZS|!Db zkynPKlNFO#h6`U#Ufa@~sw+;^{bD_y%`>dK@ajOF;i&4!`Y9a75a;wK4{I(4+z7cx zMmcw?s@X6-Rb}|<HKJcr!}X;Gt189Fsv@?xo}gm^UcFIaSSD{GE>5_isK9UGNV+9O zQaT}}IQ>yjkcJ`q%_ebD>2!OH)3|UO)!A?rE!z!pJR-RYu?eo@^f}6NKytYat?AZm zk3M&o9_Kqob7vEFjOQsH6tC`hHM=2=$P;q5AnjXf!|noWjx|j+9avx6`){14&u2S} zp?QS9KzSu#vF<mdb<&jbBT{axke?{zr=)x~H%VW}<bA~fMsexKU7;^Z?a~*gSaaNG z=u4D&XufZ>gKe*eh@~&(K>dbJU#1)fplu;bU(R<z5bpGD<sFG*$GEheIp~Hc%kn-q z-;h5hW;;as%#Gw+vLH>fbuT5^IOLjFx8%7b)J)DTUsPAlcGX~8q2}3+D+e`L<@NQ& zbIT8`WAzG*8?^vwE_lc)G@J8wqheM&YlKf(72m6Mb?4c(1wCOA);Zl(fnj`_7cR_Q z*jPM!u}___l)+g!)2|wquqtbP;H>fD3mY3N%YCZwGJpcJv<n&ss#P<|gR<7mw$9{` z<l-*<r0`9ezJjZVu=Tn0mAmv+sp318R|8|C%3xNangXgqD2WR6<BRWN3li(#Peh%7 z{qn{xeRc8O$~^&)Na5wAs^WrF)#MeZ$aT`!6yKxBz3ZZ!4C+G5_ELjq^tHwJGRcMg zd(KXQenRnmiWI<MNcGWo=<AB_S6&o$xUG|>C!OEeSS?Vg_yOew5eSZEx`e*I_`w!I z2(P}@(yW*wS)hZ(4=D?gmiI`8Ej4TpD5Ha5^(_!$Qpzq@d>8a+l9s$0sK}04H5-~G z?Ey#c@tGvC8h)ML3!_2>+wkj6dSaK}mr|Ywf0ljI@?g$jj5NvSVwyb~21TZ|O0jg7 za%s*KKblqyX#8XdBzltJ8JT=~zfv1GcI-$t^%BgdW0y^I$oF^YaH{r__-#J9_A<8i zLam-=YIiHJ;T=n*X|@JZB$q0dl{7rSg?JW~<5bciRTK0YW=5ih2Xf9LjjC6h8O!B| zXuhZ`<3S5-B}oS`6NczW(NON++o4N5wF$Z}nrJ<`94(T=bU9Y6D5<?&M#g9wdxkh( ztSS?tLrkBd6UCYW&5zN^qN$9*7u|O~yRK@mhjP0GgsM@#jDO28b`TI%SLQZ=52h>A zq_5Da;#K8BuhufkTiGGhH$m0{ENO9FU0&Hx7fP!e7gGd{W))N{7YwQy)=BV(E1RxL z>P>GaO$)_q%F2PDFD|QRPN$6WkkmCE8PR6?KRxBw?k!epAOfdTjQK+Lpfk+&_8Z(f zGw3WU4vk9shT5$1Y(OZmD(NTIW^rZA;mTNr=Lg-ppU6U^r(tzGpLf_YDCs<`kn<q^ zm>D)ReP(V+@*Q(#(505?kwPW|GwA?bW&U6gG>n#kIg?~FjI;ob3XIK})HE|^<<P`p z%PjD_K<kgS(sbLpp1HA`re{#jETl?{3FWmwY$h?_7pN@EURRl6%t+`K=-JW(31v1? z4XZ=d7Kzzr4SOeVyEJ#{qPj76dTC)Dc4@HYIBON?xl%EqJg^52!s=>wxdj?Eov5=Q z^c4i20(!o*l<3f=5FTp{4N>2si=|ScLoosG8)#t<l$I09`8~*l4H-gR&VeW%-A)Ty zEUhG3A`Q{#OCr_{5O%4wnrI1nY=J+lZ(c(NO&4t3cE4#_Dm|D`UKT;yA)fCv_>k#x zX)RHkgtZQX!^OVB)fWbhuEJ7AWe7W<4>ApNA1jHjDR&2ry4^T*T`5B0blC<0BGm~P ztA+%tv%98bSEPOPHcL0SFAzOiD7xqcrU^yXFnx&ItITOcA67mB2t3_ZGgTN3_#&Ve znf3sN!zC2Wmv5P9egs7Gi-Fo*3xi%clF#0uc8$IA`B9Y5YN~W0(bCIMHt2S}Za2UR zM29H|I4(Flp3*m#9!e;$f@#7A_yc07qeg*hrH2y=iB!RAEua=Cn%sHlrltF(%N2xR zx@N=mw1!Sn;0N8n<(ZaHl1dd>w?NLO(ozMaJ=AP;c6WuAOA1J((#1rFzQ}|U_pZW7 zI4i4F;-!+264<eMUsNw$N+@rL;LK`4%Si40cxkCox|~p6vlo!8YP#oxIXNS3I6k4I z^hiQ^U8EM0x^r7%9n(tbN<t|_D&8a2L9qm4SeCsdX=Qtp@X(59OEs-wK;#Bt!M<1_ z4p_M0IjEK%O(=sA7!0(m>Y#>s1Wfm^CRhkHl<t?9bT^~Y{VGUzv~45gpx4;u9(uAm z6`l>8!sINq+IvEM-+Mx1kC3*zgmg11r0LUBNIOv>?beud_E0*n!#u^NIENZ6L=*kM zvJ9gGbQ9$A+uC|Fn{%n94ofN17-9jtAt^K!hNRHs1E*+RGp#hpHKQDh&VBh~O{+eP zop1#;a*TE{eS8b${dTIP3@9TJIe>B*v}dVzSS1?aDbStL#R28yp2i3Oq&Ji8%zzC- zn=BGrpw~;62AI8x_4fWS2c8rOoTLUB93J95;WDis{Pp%0F$N(p)9xfqZ<H<%bO>3t zH{iB~2=J|@KtHMU$Uw`}8Ft?W1G1R?!7OXKTe>pPa&?B4pO`T8lS_{dC_{Vb0yHto z5=dkCkX5tVupPp;RaJ)oXMui7NgYr!ds<<y73Nk2tFs=W$LJ~}86XZt-&A_z0Mn8} z6!DXr9G_a!29)IfVbV9FtiLjVn*67wm>S-Dy!6wVE#9q$_pZKgUHmZ?q-jqG{S4+D zNb=}@l71%Yo1b;d^v%x(afY@>?@`dt0pT_U#RqT-;M~oG=%?xD;;Q?+R7pxGXCu>c z!3F<Kpjvf=R;8_)sn>W?18PY~NE^bBEbJq}{ti-9rk`JWeS+<WAqNZ&4$?0u4JJCc z5En!c!^9=gtGfdI!qPnnB^N;rK?3jMIKs$htM%G?@p1t1N`Zb+>E2GABE+V9S<^2r zok*}qWmqTrd8^~L^h-+jp?a8Xt9K~!nwsMhRdZS3B2es_n&*K>3sMD8a1KeEP-jS@ zK5<Oq&Y-nFM8C9@O7s+id`u9ifqV}Y$PEcLGpOpN3-rrM>4b7$gv^0ajiH5A#KU0- zq-BOwihen+%M(lo`wAW?Wv1#^cCL=EVve(5M(9_wNKq2xWs-gk^G9?<u<6$-CjfzV z93n8LS$G@y44l8Ady2lr_Xz_>yqzYYU&pvDBB<$GndU(tCJCzS*E2WAO``7yOV)WC z)BSiX2cntu8+Pe8rr0wTWGAcuRi$rdN+ol@ydx~aGzuvCCgtTg&LFxPK^k<?Z)O7l zFm}Tu+mPNszoiZ6TZ2N#o&q*-pzzz2Q3S;)HN54Zx5SYk*43(#M9M|_Xi@On*;GMI zNdEyy-%-27CJP@R<nLsnziTpr;(kECD}-U|0OPyaE|6RdlB8UgIwdFR_prH9RYIZC z_wtUqhk&JhvHw0MmmwNxJ9Q25|9&Oki+S2L`l0*-0WwvbwIA$<43_pq=7(4~P({-X z=fy1hV6v$6hnZ~dF*%*}`hxwD5HlR#kM_k3O8bKNv0##Gnp*=PKh7j+4~%$uUobyW z+w9kpC*kyM`IC$V0&U#&%Z%v(lb`B0T?}5kBF-AF@D|(tbU+jg0@I)AM-&z!?l<E< z8-hT({#;)WH>2y%2OuEdOQpZi4+NI>rOYn|OQk`!0LCvdw`q^%#)`YB@XG=FgJ;>- z5r<#tN6)ZEKVtkU6T}!CXOPG?0Q)r-9O{8gq*6b4zaDU$Lz*Z?exo1X@bbRY`OQGo zK@=(wb-&e5)U~Sg1@_x4oT9>(=Ya!<t<B%z&{{F?V6TbR={LgP4QTJ0*NI($G5%gZ z+J`mzLHhlG1z=+XFn^$Ad&_cG+;?z)7zm$m&D3oB8bJFaPWT=J3>G1;hp2U|uXi%n zI?w^OT?pd2k)7yWY{O+am-O8M+q5!Pq09FuFTnw{9<|o&d)XF-3JZOoQi3|En`u-B z+KZDzY5IP~a+nvwbdV3UH_Q*RWr|t74V!+b{rr!Wy8w&2Tcsan(U|zqp?|`<v?~>0 zHu|USF8@q<DRkL{v^<Zeuz=;IB4+f@+m-%;eZ`HR{$=~=UnwtyrduWkX~TqI`q#{p z*tJGGYxQHizwtR?Y{(>b>EG_szvDU_s^IkR_w57w2Zkdf`aiNc2<-~`5ysh};`dJx z#qXbeR)j%fP%Y`d=<V#X<4S2s^&3r7zh;r+^zqX+Bwl~`D*T!@%+1+p=GTJ{2mTqL z4emh3?_dQKrQt1NR%>3NY+J@DNILW&+1wh2#O!LL;MvVngR|OIZF@T78PS$KD;C09 zv#d|X?9&<6J!_s}y^CPb&VdiR2#2sAMAld1!2;HxNcWwz=d`hG$Uf@ADih3795mBS zLj+k=y1Vca;TqjCA;Db)g<KvIUE#l6Ja_<)JK#(wjtDM6-a<^6*w?_&6hWhtg+kun z-|_`-gbRk2Y8t9$)RF5BzLZ;2GCVRiKAA5Yqr+rMuMCgoM)Jd2j*#J;mK_}*86g^( zAcw&gLrsEw6U!tSHh8UtXcSBLWV?y!KO%D!OaC>`YuXKK=e8kG*S3ct6X&+|4?d#W zZR^}6y6@b+vBO@9k|LJj$GMe7B$(S2!LBX7vLlszR?p>zbK?`E!=oeP#_&{rY<zga z7}1SN9)#L>`AB>TD{4pL>qvZwEYMi?uBU+b+9DPxI6@M>EyKpLxeA$_oER>TPa4Cc z*-?GCJgQF)SEeSWvLM!UcyuJgj%1jqwSA<52`$j4j0}rYHG?BYLh}9)?kGGirq0dJ zFRX5ebd3(e44!Trikt(?Y~z#rxA#7+Tc_wuR-PI<nK{Y6O~x|Iks+uH%kwK|7MIV7 zjHP<rY(jb!so)W}*fCq0TRwMT?%aY1X4h-OdbfW|#E-;iHNUdFyfDA9xUwvQ%r!!q z=+WGakw)_?E5$`2(sWoeGwp4CKc>kkNc8CR=0pJO$2HRdAkao4AoitN#NnM}vwD7I zU1$lnXjYiaX0!3}{o2CWg|&q>5f($g37jM9#0;-%2^@$SOpt^dL-2$edLm<RiZc>k zSUtBkcV<CdTwY(8zp%ETt}Q%xVPSn^U1SjPI9xei>kDft$c|;92`<^!P0P|UV{%qX zl{6jVKDJvsB`rc;hb6%SX=Pnfq+C|bji}>kX%6B8<Y7`SnqFo+J0|Dk+?bRqp5G`f z;k`81h;$CFxUkdGL)^mw^8}FBwTkALtp>47%Ie(4d6<l|D<bso;+Ni00ud<+OtE%R zUEf#}+-YJV&e}q0Wn)2|J99>8jkOk6oXD)MtO>E`*i<e%784?D#j2%+jq@vKMEK_1 z0t_JriLySwwz#^XF3**OHnw<hSXg@qM29F2bxkir3?I^IA&MC%LZW;U+YSW+6$!Jt zwz9D@zp^C4Cn%XSARFVP%lgXMjfdyfgcxSchC6sXDJSRU@mO#IjUJNPECZyx2z_qc zch7cy;?zNpRz&OwH^V|~84hSjiUDAtq{Rsm)Dn)^Zd_Dv-B1T7{^3xPCqn%Ll06pG z^*RJa4;j{v)0{?p>?XVGPlSZ`S>CCKFliUA&0|;oWhb@q$`qL_NC9t~O+NF5fHhlt zYA44wZO02Mq67;$xvG)yF-w;YpoC|B!ZQAOlKt@SApqC4R2`E{DtM=13mC7|T@_M( zHZkW6Zmi&iA>Q3pb*&fR4lE%89ws_<LPPBx^mA|^%T3ehgbg~_6Ssm&ovq;Z7_Wx6 zAh=;qQA{8Tf3s3;`zECvPj+Y|1kFD?w!Thmf`lOz(uRDZVrE^~bS#`0&#V);voU<0 zYfZUZ^F71fYN&f^v|74MiuWz%@;HRcKM%Ond7}_hn5DAqwnh+KW60~k<r$<khK>@R zJjQO(XiZ5+1%s6Rszo-572-M)p#ia4kE0V=<`=AmEjj=;El4EjSz^|4eX0B=&z?0L zztxhL^WPx}TsYE#H+wo^<0wuni><3h2WlQ<kM(K_t}z{MrVNWZ+PHS5e<9%8w;>i> zwaYz$LZ&|4T^1JcPyRa`YSXcC%{rJ_AJ&VG*3;Z;Wvx}zfpWvH`exXuqXcDsSa6wt z;lJTn9skm>%UYw+rf^4dSiZ!mz;&Z7AW@Wn7^=Gic79z&LbvL4fMBzv!{J`McO*oG z)!4nS>Ya*ZcQeY6waeT^Lh2ACVW!gYAcAWP65gsJn;IiZENHN7$)}ixf?E@uEys(} zM2L4Mc)KG*P~pJ3Z3r?#{NC;;W|r2d`huB9@p-!$Mj#a%aJ)<~6(?qIcYqP5E{ZT< z#9!?;BcA4`mA9MGum+b<i%_toqQ~d$X87=HA%wDGvHg?m?Pe(Z&8njr1THV;nR0OO zhGoJFZEx|oK{#HZl&c^+#0=l3uD2U5p1aC!7#88{`1W-`qq&p618`^x<;})Q2-o%< zT}V>nVdhxWEarPvQQQfw%g)p#eq5qZ=(k#VIpjlS3x&yvk;3@o6e)~Xa(V%>())Q8 zL!cG-DYWEkpTYCWx$!AEKQ=1or{sx=o7U{G!*5!%f6sCHlrW<iBxc1HSs=GCB!%bh zcT_l^C#VkgA??8qM>wQzgMUdg455v%{|t%*=>lZXIUq7u@r9&9e-S^}DS}H}A*m1( zxUN$Kja$gRuI`vkkNM$5FpGtIBfdZp9QGrr4z`>EghV+wwqRL^hhuv-yjVtrII#xH z0({Vi2Cpa)+MZ(%mhl%YfICF&z{>%BxUukifHFAEM9-<@<=ljv8-|nYaDCnV=+cI- z^`?w(vXHaz|G1pZ$=SR-)=zgh*n-${tESAo<{R0Ugz}<qh!6F0MQrTv39DhGzn= zB~)-d2zWZ^HRR7EbSwwuTfw8y?-D$|uyJ;HGJp`5w~-B%y<i}?N=0<Q{B9SH9RdYI zRrWp8lFx!8IH19;z};-X8>>W-##uV;SMa7qV-4ayaFYz1rrdaJ?p#LTI=q|71gALo zo`tmQ_>7G<Iy_n>Lb=#%4u%Xm-fg%MQv{Qk>Eb(<iZK|mvmWSFh(}<e_&J2Q>}8AH z+!E_f$BfgK!D&{XKH`*LcJb5{r(km4`QlW)v&1P!=ME94>YXD_)jLR>s&}Y3jZ@5m zwn-YIDmI>^iDmQRnIj^b`2lT{u6L})gMRS7Hjx3~X@OXfs9KQ60IEpvJ{l2RI(2}9 znLkGfnfraMFE?n85;BhxGK0&HI75W#NJj~or$SO3C1f5YWV*GZgv_IaOniMg7n4T` znFrI$ShDj`LZ(QN_9*A2bulQ*yE)2v!8=lqa$cVB*kzDM)Aw@EI2{<bH&7VoNMMa& zG~hPJdH{>yMD4-v4vj6w14zKtm|n#fis#1{-~l{Z$7@6!D)C~1n(*z#;`V0=HS8@B z5*To_5K{o;@JkBQ0EVQgAt^sHB<0|UTYdum!QYel$&ty4cuvDO+LrL4)A(+LKr9aB z=fxvWvG^##xi2z%w=lQM_w-xCQpimaj+z>chodkoDndd`FX30n<E6*)l6HOP;q`Ni z!Mg{7GsL;kk#c#IWP9c@bZm9>Umv6YwnqP*U1txX8g3GH3H^`S<EPbEz-9E8;Mbuq zqc7WrP?B|+Nwd!KO&3@8j&YQb{N!ZMF^X6TI$T0=d++)_x+(YOZ#6i&==<oRZxNZ9 ziDl1w8r<~Vu{Cf?3*X5KZ)7v;@X}1NdtEvsnA{G%aih;X^5Wg@NL-xb!8A!BlP(-e ztjNHt^={vt_xKVz)zZoYqttMF489CgWL@@|&V%_y5gGPw91#q_0|Kwef*jpZ$bG`M z6UBlOoGOI(Q|g$f&0bz9f?3ElT$AA(ezFU@IC-kZQeY3o;v#C7GQ5iK(Iv+4X(26< z`;BfXW#H{5{$b`Y&RGJ>UAtp&fuwcIRXrQ?&JKfAl*u1`Wb6J%<mS%3T~pdoE4-xh zV71wmo_(9dIZsVEOBv*RiyoE>-z*h=#&BI=c(ngcdDBx1A7*>OyZ7qsC4BhqBX+Nk z2vf!8<k*AUAzqXbJ4)dF(uB{kh2vsC(B_Phu~17AnY7T>Z=J`0*9F>jejbCziw~P1 z7>wG@<R->5*{NLn;@{!@Tx`LSh|Sp$&H>U351ok6EIx{a0iJzPB36FE7x9XWeXKHO zlq-|t<74^B@ocWF8)ajRl(muZd?jBQEys$a*lYP(2aTV6s=}>#qD&PsCV+@pG(a@! z8WDQIVQk^3aBy`Euk?mYR}t2W>D81WF7U!*5iH`1NQH>FV8y|OC@Q`lR|F$2`s3J3 z;GM<3kR6hb>1z2+Q*2T~r4-dnxo1*+hl)x6^D+9-HTqxd4Y9#A(EqMIKL6H_zU9zf bcX+{sm}u>(taRf2KabJ>U8Dc!`||$-Em7OJ literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-28-35.6fcf7282-da2c-4ef5-a851-7a8615d2f238 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-28-35.6fcf7282-da2c-4ef5-a851-7a8615d2f238 new file mode 100644 index 0000000000000000000000000000000000000000..e3572a7e14b386cb20d6e7369cb03ebf455e0f8a GIT binary patch literal 49293 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 QS=x;;+KqAe+h`>JADR6G%m4rY literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-28-41.f7e5dabb-dc3e-4608-9610-42173d36f15d b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-28-41.f7e5dabb-dc3e-4608-9610-42173d36f15d new file mode 100644 index 0000000000000000000000000000000000000000..0b594a2948c91433ba64d3feab5278d07cb3923b GIT binary patch literal 49293 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 S+Knvj#yIW91pI9@<o^c@H3WYE literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-28-42.556f96b6-7809-4d22-826f-b68d99f4657b b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-28-42.556f96b6-7809-4d22-826f-b68d99f4657b new file mode 100644 index 0000000000000000000000000000000000000000..1fc743faa2b84800620f82105a30a2d5c20756d4 GIT binary patch literal 49293 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 R-N@2zjL~k4!{0_D`Ts+71RnqZ literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-43-49.91a5a50d-8533-4e3f-9930-9752252ca014 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-43-49.91a5a50d-8533-4e3f-9930-9752252ca014 new file mode 100644 index 0000000000000000000000000000000000000000..2016572301bc695a9019f66f0ffc7e1908bffcaa GIT binary patch literal 57383 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 Wl@;lb5w-s673*JbT7TVc=l(yN5+g1E literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-44-13.f096514b-1984-4004-a4c7-7357441b2e56 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-44-13.f096514b-1984-4004-a4c7-7357441b2e56 new file mode 100644 index 0000000000000000000000000000000000000000..ef9955aceebd2fa291edced566d7c9746b10ee68 GIT binary patch literal 55247 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 I^m>K=4+_>&e*gdg literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-44-24.8b339ad9-121a-463b-bb42-ab39db214d4b b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-44-24.8b339ad9-121a-463b-bb42-ab39db214d4b new file mode 100644 index 0000000000000000000000000000000000000000..2b35c4d94753513db4cc250c9b25778866783de8 GIT binary patch literal 55239 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 CKTpO0 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-44-34.64fe6b5c-294f-4773-9d30-846867a15716 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-44-34.64fe6b5c-294f-4773-9d30-846867a15716 new file mode 100644 index 0000000000000000000000000000000000000000..9f896b255b415df6c9b202facfbea5313b0b80f1 GIT binary patch literal 75882 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 Gh5ru;7)Ve6 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-45-14.00ff237f-e9cc-45de-841a-06797fb7be10 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-45-14.00ff237f-e9cc-45de-841a-06797fb7be10 new file mode 100644 index 0000000000000000000000000000000000000000..79cfb08afb6ad58b1d0192962b54bea3e24399a0 GIT binary patch literal 56669 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 Hy1D-kW!5kB literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-45-14.fd8a6a99-18e3-4527-aaca-41237dadadfc b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-45-14.fd8a6a99-18e3-4527-aaca-41237dadadfc new file mode 100644 index 0000000000000000000000000000000000000000..e5743d0681edf8790a38259c79679e5f74a91334 GIT binary patch literal 56669 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 G?*9WeL@+4; literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-46-48.4c0a2f29-52b9-4bc3-977e-1c0a9ee7fbef b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-46-48.4c0a2f29-52b9-4bc3-977e-1c0a9ee7fbef new file mode 100644 index 0000000000000000000000000000000000000000..a62603c5a60edd2d23e00ba8b72eb413181ef843 GIT binary patch literal 54897 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 K`8WN3;r|0x0o&gI literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-46-49.9783d6ab-e408-4aba-b29c-86a5d5ef3cc7 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-46-49.9783d6ab-e408-4aba-b29c-86a5d5ef3cc7 new file mode 100644 index 0000000000000000000000000000000000000000..63ff10efd0a01f0624df87f23ff3b01dab0709b9 GIT binary patch literal 54897 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 I<9UVu4<muwT>t<8 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-47-30.81ec9fb0-adcd-47f6-9fb5-4185913ed1bf b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-47-30.81ec9fb0-adcd-47f6-9fb5-4185913ed1bf new file mode 100644 index 0000000000000000000000000000000000000000..db63b53ef5ec2028c4825d0d22acdb30b00dc651 GIT binary patch literal 56669 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 DN(L_& literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-47-53.ec10d560-0784-42a2-a0fe-bdc477d9543b b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-47-53.ec10d560-0784-42a2-a0fe-bdc477d9543b new file mode 100644 index 0000000000000000000000000000000000000000..8a7e20a42cd9046c8c48c47bf0570944cfbd6233 GIT binary patch literal 56667 zcmeHw`+pqAaVHYz$viIcIZkrETt+KXyO6Liya<2*V~_+Xcu9f=Kyew8nVa3|-5p?d zXXk|lr0`CTBIjXUtaI!*@hg!}wtTtR{vmPVNS}-Ui+evl_c>9N{($@Ce!2Tr_ss0< z?(AYQ7@E|_fGA*hrn|bjy1Kf$s=E5c58N{+GUXqin3&L&17?{&QZD0j{)WvgJKt~* zw2IcM=dT}B8;aGuZW%kQ>ezX=<!Fx1)O?3krrQU3rQO!Gs^Vxy%g%3I&+lohW9L;? zQ(WE2Yb}-S=Ne8^H-EJJV*p<@RAzpltSwGVSj=vt63cZg&0(4J@)H*~E^Obrz9v!m zb9Y+HPh_*VwVITvJJR}^v^e?OPh{5DChwl37w4p9DkfER#kN;cEhD>QrzBlz)mKvK zDT&!trOj3@DZ0%jPxUpmol~k+)^?aGQw3M4Gs&=|G;5^?%BE9j3GFREahtVNt#%hp z-)Tu`ohd5+gwIXpC=$`hX3k2=b!yp#l>ZKOrB0`lYd6{&Q*%|LnXejvL=;o>EWS5c z%dxW+-Kg$nRio3=4Mnx{lGhNx6Npv4qa4^$&9JHr-E^4EiDCgMW?`Tt)~ahQMyPo| z8Men-l1Bd=OKCA@QhG|d(6EdqlP+0GGhB9)HH|$cIStL0K=A{^m0X*?GYO+d)Uxdm zLcG5X$7yGo>1ul`sdDzlYW9NBY=aRhI!j6DqJwU&q}JC~m|ACt4N1#zBn!aMt(<1d zpoOAKN=uc}Q&o=gN-@pHC~|~EuQ{Eht42lBne-g^ux(h5bV=I}5k=a`HQV_nFGH-# zi##Q%%ATfH&}PGMTYQYB3&jFwW-5`T4m(Oc3`k{rT9suxn(8!`q>XCTZ68QASJx%} zNHS`ie0J4h-Y__}RCO(kn1h~Z_`_#S7^c<&TYxFRyy(J;RLm7X6-Uupwxnv{6Pu<P z2Gn-IebmJBhS8+aH(ZAXu1&1mU|PN5NarMhqW3-A4#w8vjVKr_v~$30NzrwqV{@G8 zwd5EaI5AL{6Zycmz&k4`pL(IO<{e)N6J`q4LtR=yhk}X0<;c0i7$cavyg0Fd&n6+s zGdOFP^8&o+HRlZC*QGo}(_XGKlQXP(o&?BTzNuKdE_ecT&QaI6xQgy`sL3o94fXx- zehB6cff&R(pbgFVtu|A3`PkN^%Z5?c*_5OjtvhLlq(GfHG(-?MG+Qmnh76V5_EKn= zy$;uTUCz{y*-Zt!V+~AZF{YwumSAP~AXaLgWDoVT2Su$_)m@cIwsW8}yTKS(yvr=Q z*4o8r=_{%3`;^qMSZyUmxY-zus@mGIb5-4N)tatYjH9XSDEoO`tJwJ(#7I`@FdITE zKbt#~E99$o@8cZ!KZl2@yf1M_wR_kw-PpX6N!v6ttLdpUwN)_;$A$oH`wgWhBL?mv zH7*v}Y=FZo^>l0m8W3Go5)6>WKH-l>0Idmu0(wI{0!9wMA{&>S11z>FUOK;@<?RiQ z2C+WNI)+<qh$0>@91Ep(s~(Ax-@I5mb?M{Ep0ZW7w6-HDm^oP3Du&}2O{fa{qzllT z!rFnww52_7Nu7pPZD36$0cnTk)U(@HugpnIXMEAdf?8vW<5~=|)*<~U#Qu={)S7Ko z57$U~*>1<i3guyvoz5-fW;pNdM34Nr<-BMr+~rGR#6tKSM&<Ofhp-q+hwVH09S}`C zO>w155F($Kwi^uU!JcAioInz0E-4JER5{?Z6?`kxM3!j<z{1$7lEy>JN$6#6$CfgJ z*3dji@gW!tE74?5G<F!;t6N*^m#=+%D|4zd-4+dkQ)`;ll$%gmXgyq!wlnEfU`T3> zO@l=rIttcdNKh4n3DL<_AEQD_?r)?gr@GKo&89xe9nER<g1l*1B%gD+TyF&^XEL~{ z2|nXZpT3nn-OQd=2TD0u(j!Ysr=MLqeRb*d7FFRyWR_)E@?4=nAahsIpO(a*Nd`0z zi>Xr*CYORixqTZV7lf2f+jsBs!62m|Jt>`*h|3hKZm$GOD85Y5Fm@kdU6JX*<f#ZT z=Z`;Re2D3W4^a)8n4N>V!Yn6Km>S^n9juAg0hpj?3is41_SGVhOxjUPRjdJF*i&=5 zuO?<yP;pd?GlTU6$M)mtt$tt%N6CcN1phh5Cj7$N=-g=yr<hkn==?$*7i+971;m<? zLjA}S5xAxtAla2chqgllx||QTGRqZ1J@Cbds_pr^E1FtZp6v#-L=2_)oyE*(YM5fA z@Q<&@2{^Rficsa3^JvvafJFB-Wv`-G(#m*0-JUPElmL5tBpBjPR_DsG_l51ZvB}6b zA$0258kashuI*^G18mIr4klZLqRuQ|?ZMt^S@G7bJk%m@_sLtxR<O-dB{f^q*}l}t z&K0Dll~r8FNS%A|nQuLK^Nsu8`o`OT{}=DR_|pAPzy8ikFW>*vcOSg<=kI>|HT=8( z`=4FTD_+;Bm5PhysnyqlW7MGsS}AYA6=hP`zBmdNR(iLRsv5ekv~4J-;xT4C?Mj~% zUB0I5U9^lg?K4vl+nT~VY8g6hqIow4O9(14btP4!{j^t4S0JcYQro;)qOMlw8=4TQ z&<z^|j_!n~CP0v&NT}m^(W}st5GM*0fwSl%_L<&?PPSMmq$CYU4tApp3mCawqk$MU zl*eeHx^(E+V_*j66e$ieH0CC)ZNYX0`hiQkmD_ihPSJ)uco7HzdMbVfK+<FE<{;%V z9P;GyEWx5pGXH*i#)C=)M?qfJwGi>M9LvboycPxYVhDOv3ksI<y}>O#74?7Gu*&d$ z(}R8tdpHE|F{8Q@2@|xnJ5*cs;rD?Qcu(J*9MR^`en-M8jDXcMQ3-!+R>CYc$RmU{ z!_*PHK;QZrO^c<K-T+?2sHy&>?P(~Ac9LJzlL!ximc0VUZ_kqp4Fz_+w%cAwIhN}S zi+&L@xL$~^4-iI->`_JoGzkd|A32zCT5dn%Ma*U&4L+-Fx8hIi!Ffj|M~x!A?{ap4 z2LU{ENFrd%9x}JXTpm#l2FszG9#K318zyl?xpY6%Q<;$sjT8Z4b_bb4%Ra%SC*w>h zDj760YAhlV<u!-bTF$#<g{C&>X8;5QbQ+6$BTaI@t{WAsjhV^Aq<!!5<0~b!1T}T8 zD-2nRpz!u`@52!iPx@Mer%d>4d!)JDCE5_u(PNO0sFx#S<4~~}l*nO6XFD>Psf3Il zEluD3_UrF{=aU0NCeRs^XNU<y3K_3ERI+r1F3Fj!MM`Gxcv1aGgvKI7&-y^1;!2i2 ze&<^<&szh77Y#<fZ5gz6p*<P3L_dACM#-4IqS$)B{k^|@`^`5WeEya9zVfwEKnKY^ zgkppd%|3WsT6HGVJnk5ln&t`;CL`w>SVkS}&TaU5xN}POHu7qh*`j*Z&%1Hy905Cu z*8N=w(L4geD7r@!2kqba(%-!ExxW|F;r@3%_1<T{9v*>+IuBLOKUB8WjXJy_;qLXZ z;wb9%6$Rzqd-28lzxSpmNJ7KXS8{xMjh0wR@m(K!Q9K7iY4CI=G`ka|5V0f8Ym3!2 z@>0AXCv<>&h`v$N>}XmV&E)UD_|D(FHAw9!;75|A1RzkNqM-G&X5=bH6~)*&@NMqB zzojyKu6><Id^G>yAMStYtB;Rd9y+E0XY>h{K855^4gN4~n)qj=LLP2mIS+*yy1C#? z?%ll#zb4r+$1@dn4TS?8AM9sX>DzIe@Ech$%mtrd?sGLYC7hrusftqFty>5qP{~SV zSWD8AGcz-1$x?+c@O3!sEPAS{P)?R+3hn)~q`PE0@Gve_EVz8L^!=<*9>YzOK@yPw zaLxCcB$pdS-+TfUr;T8q>|E+x{;-Y(K7eijPsoPtS*gZ`Lde002;1Z_fcQ?LK@hM} z7x`Yy=K}xlVZHR&)MF9ohT|EMQL4)#yz+UhNiB>U{7If=I8-2HZwN+7u!YpbkZ}_$ zAG+?AU<|~^@DtD!2=j<#bfOqXhlM*^oc3EEXqyDL=Pet5H@n=Jj<z)P%^(l3P&fMC zL3;ueZyL9KHijb$o818{NksJ3$GZ6L*S~-Nl`q`?yRX0fy)WK>olNZS{`>E|{np>U z{k=cB{}11O@VW2a|JJK`_}-s=O*}`*2jBekA`J4Qt?|Bs)Yl>~Zu<xux<BbhOku(r zd-XB9lX~aNe<i#D?|k8#_rLtjx4-|=yWjtk=RJ7!6`=g!i@z%nfAGe4-udb$-+A$k z|NY|cq`dWM5ZRC!Wn3)ESFdD1*jsRt?r9VYqH;H)Yw7SQVpLW$zU*MFy&OWm8u0Pf zj47Fic0|6L#80FdyvNRSL<DbgA3c0w2uI`?`tk#4!k3JoL_Ei&C1*cvXgT&Ai%ho* zew}C1naQ-*h4ho;ccp<_&7_4}tvAl`bS50e1HWP*{p|edO!wQQoogSY;d%9lB7h1y zam`#&5xs(acXtQgW^5NU=5E@6&Y{*2l+tZ1J>^ro`|z1GwMhiWPvSI(<DX*9+K4Lg z0^B%d;k;K6p~iRGibXL1aDI0b8y%<kL~`njzyOLG>yE>i<fTgegbjt3#v$+s`tsJI zC_9zzhO>GEPL96bgsZ|^hS(1{AVEW-YIk+!PF_V-5L1GH3PdjOxUUvtDtDg~yN;Ot z%X!1MW`-AxK#Liw&y1_8Q2SxX#F0_z3NIHpd@4>$!vEQ}h2SCUV5DKZuXjTx5Fevq z!rNZ~2??MZILB&=R3lGl9dR!CF?>0FsBC9ad?pVQ!`&TJ@6N1iT=MB)Gtdp84M(R0 z+gF+h0fB%HNs~i}G2RlJ+GxQi#}FtbS{T;LBlpb<Q1k*9szx()uKW4;&?t0ocWgc4 zqEU4zsEhlshw;ymks61>eKs1Ut;rOHL$+9%L4VYTVKa8$R<Ey1Yhv_<!TLe;tZr#) zo{Y1+Z^JMdyH}S1?s4c=N88no-I<#Ja+J>a8z3&nLhiExhGRN6l|veXxyRS;2jEac zePWM9Jb*@P8A9d_fazL6`+#{nwSfu|?Vev-y|KN1=@#@O?+A$qSvwLU1b3*x!KbeO zm-bm>ZN~^|gx4ZKRP3vRua05ph)v2&lI<*bYB!9I?7iY)1Cg;(-mb|T`yu2GU`7O% z;Y@)zri0j51LoGyhSq!FMP>Nk{1x4^czD~O-eo`7feK3WY6N}z(5NEq1MWMM+Biv( z)maT*v;mgr>l9R{3x-#Z=3(FKwDi=I#regvgWk8kg1#=@GCH{frbJjWe0C6s({J8C z3OZ^V9ny2pW8wCw#(NOy2ppqB*9ADJ%~3t->JuCXKOoItPjT9)yN>4lMYUJL1ND&9 z;9z>bhu<zE4xbpr8}P%>58GU5ztD{$KFs<O;=p4?PY3bxxeDxXIy+MM^s!nNbPosY z_l25z^N{pR(a_O|Izaod+z`h%WCiES4sd|MmNn1W*~jSN0b2D7A2v4Ja5nA$5kK`c z%C(%}WCen812jXU6HyOdyFOAK5~%J^jxK!f43hRd%e>&fy^|JaYNUVwchXBQ;G9R5 zV!GGWr90^XT1Q|PbTWeWk;_pkea}bX-sD;Fv9Eur{^N_(?uezz3)+P#O`MzT$J_j| z@=xICrP#KcKVJS-d|Bo~N=mOf@N^*HlC4pIdHS4W{zUnw@tz35$dqmVWLf#Z#KgA$ zUCJ~K96huc8KEf<S;uKa+u?C9m&nMHI_e41y6zgSd>d`?vnHyd=i3MLTSViN2?Z44 zJCI^wkxrCJGAYOkP?u$I2aYosEgXi@YdQXof~;gYvr9wp(6L&a?;<4{7Dy=?!tqP& zfRi?}%MK<_`QMhLbT^<Sed^Rjm!IK8JcEjk;y9l;Jg8LYRHitfg2NLq3n2uwft5OV zB*Oo(@GPA=_0Y!%%noj;!mJh=lj))ulkQ92d$!N2nJOLk1vj_$G`LJ?cNKp?LY9z` z2aSDRIWxmYWf|5KS7+yb5R6bP7Q37fW>3xuy;JQ}-&gae%0Gp9XSWc#-7p;Ur|+4k z#Odtz0gmFCKT~$_`uc&>fbVIBPQoooW6w04<i?!hRWogzzti@|uRLk~EI+x8U~*>u zT=`dk#g^NWwpd%5o{@@kOS5N|=4K?Emt8P_o(q~99WJ)be{|RUh0Hzk7c;y%nF-Ag zmM@_C*l3HzG%o~1m%qS#=06rdajMAtQ27*qc3+#nBu<(`G?^bR|MibfOb9+)Stf3j zgjB(qZNV3G8mzEiEY8j>oKY)<DPbw*LJS9cy4JU`c&>P^huK$NNUx@sBwyC@e(=+! zxz#jErdO}sk~c05l-N^r4b(O)JLi?)g}sALRNOaOOaAF6UZCB+KqsH-y(Rpoya<IW z_9H|a4YWkBsLc6+0<^5;&Wo4c&TB{+|1F2Jaq-rWV)TX=*&I?}Q@p;hy}fa5ND=W4 zP%ujOusl!-gO&7AS!-OOf+f`^?pd)?V6-EpEdYL@BnPzMFT*g!kJ$`eu~U=gFN@3! zu)EpjuiP_#HB<Tz<&S{RNf&_57ZRxw%*5A>7F#m^N$EfG`AKEyCtPSndf}e=k<x!E zKj{Gpy}X^4WtyL|oW6_mWg;EKKP~;|axS_oMPYhnQL{Vq@XY+R(tqKCjM{gsgC+By zmHum4^5Af!hAa%`ub2K?`4{{K#hJ`!x3{k^nNsP$mwzq<!6I>LK2iD~0YSVYoSVV= z#FyM9GgbPZ<+V`FCvkw92MMwk(nHuT<x!9_My2NB#J$5NxvL0g^Wo}6`hh-h=94ZL zEPBgrnjb~4D4&JuHrwXud*)M_^3ULF#np5~9n#`wrukUl91k94p|k{(mfoH-g>dI9 zq&ZnuQTYcUpUkH@o}s}vpD8zfWMbk(R7J_@^NEWpbINt^nb}O^gAX^|O0MxCJ`eqM z&dfJHT*g{Bk(o3L4M>z?ru4C3zR|>_AKGP@)1}q&EtKR>@T*_q`TG~~K5QuPpM;#w z^k`s1GE+KV{@G9qyxG~(g>u1rII773Xmh2Dfym*I=1Xg3B$y$cphr}95kDjv$vjiK zRQ_c^Ak!%sto!Vy=0fRmIfYq6y&KU=&r!1<&RBnQvGi>D7rkKxIeBb0kNG#3O6%n* z?@a_DgOcIcfAehV<9vfk6}T<gTrQP@g(?C}+6$TN+f<t?r7MFxc&>D{{E~;#@NuP9 z`mJf6DbTb1`Nt;ssiSyj1I*tjT^mBUkCiscH-{6>Gw%?V;-~9o4Dh0T>M&=kxmvnj zo*NFo&tKJdX23jO`b7EZ;k6^8u+0ml&GO{%DlqW&ogpwUmbS{v!)uHcm2IxMjgOYr z8(6+CK_*`&nY;y<M^z%nFkqO^LL8HV5VBmD>yXIz@GL`ii<RX~qa(eL)>J6G)6m07 z$->9<yDz;4iN{Z7_>b1G3CA-^JOCzztB|A~g&@f=GEg0=AOevs?#_fEkUzc$eR+2! zY<ie9KTeB5DO1{^>|Yb+mC|nc*YJTj2kwEesfFVS0Fz7R)so&bdAO!`t<)?(<y94o zN5XNKWyahnwR*Kxq4NbM67zb==+PVrCfEI>-o3N=iBh|9rDSr6O@##BRrmy810v!A z<IR%Q)0&4Eh%QQ)TP3@3g&4vhhS)Cu5_;mPbA8R-5Q^Op3!3?y?J};sGs>i4-Yow- zAoYPL^NljYPS0iLt;Q8D(gLH7`J4C5+Zp~$ma7UTm@J!jxV}k>zIoSwMW@g4>bFKC zBzv64-F5p8D*W^Ehk=t%=}a#}C|+?S#!$G4&8(Eqpg3hYYZxL@wGA5-RR5p|a&y)C zM#bA`pEIj`aYkWSj?lKswGeDZSotRbm7c?lXV%Ko)JC8!i^jly{PhU%bsvmT1(*i! zS=X$|wf!1J<L1()#;GpL%tXl@(coaG=<TTf>~ebpc1%3Q2O#NOSVo}kml%P4(?bcz zm}Ijx3?+Iy3MGRpa)E5&23^2wa}gOaZl3kjD>n+V>ElO3XAQ*<Z%09~Jr=;x;0EA0 z<=JR{67NSray>|7(g&oyVUWc8QII-(ag}*`8af2ar!zqA4`W0QvRjbbXfeS9K0okC zMf+&;`C+8uyX+AR@q!P9y7${dp&UZ+dmfY);qotrL7}&!Nc1ngsnuc~fO)Z;iJqbS z^#D0O=}i;Zrrj!`@jJt&iC<y_RbJu-0J1f3U~C`oez&|3jZdi12#_y(oMf>!$)8UR z<0SEZ6q$a{6PQ?uJ%RcA!vtnfWE8wV;7hA4qcHi)h<1M{01isWZkZ8X{j@g}HauWP z4d7lGHWYq|5y1YH#}se{0MZ|oXQHPve?6*~pYddtKcgB5)&js+%f;wX?JY+L(()S2 zzJFc*5bA+wZW|VEEQ{UM?z4O~=BYr<KlT_Y@Nc2X&y_z&O$Ltwn4jlME`^Gkf8y_* zzrdGso(w9eVE!rJZVs#fy`@Ib^v_&AUwPI`+x+4^^Gm{LPP&Wv<#LVC`+=y3=2yzt z)lTf1U*$X)Rt(HPclpSBQ4;1~RJ-=<QwSNC-Bw$x?&|E6`P%u<-<g>BU$5d9#Ydc5 zb|^;>{#f{5^<(CFZodxCRk>6#boDIU9PnBr{Uz+*_12POv~dcCvR@&YqZ+OmS#ZfO zb&j{mhg;Yt#EU#{Jq`w4CxG9C--U4y*}9$#7U04-&HJ>^dt<<ZJdR0`s;0(4g>=_M zXi?QEdukjMiqmkM;lE-scpxB39D0g_ix+&A5GKa1#*W1xaVDn?K?}b$wwE%Ge~v?j zU`VnvbMp(+6?Hbt7OS=FY;k5fs}vc_7L~&6{LBnf*cs-ta~y0DU`#IPI7lWkNUA}H z!5&%jNWr6FWqf4qQ*@fq(hnXP0!?K<ix87X);^t-dSs2`U;)xZKC<SqQj(-dr2Qn9 zvXBI`+i|e#imzgI{!Bq#EM(6tROhm@wHcPJ%*|G^YNe)BW@?I3D9oRTuh?qXiTFAZ zUvVaAB1`xCKzwzW4h1Kcgzw6*>fHQdabdBREfkB3+1Z)uOm<;@5uX++bBnXZ+L_91 z<wS;^$gsG3=@S(!)&zau$gm_;GsGyxlK00jHc`Bpyn5ln+V$-?P4k@j6fHRwiYv_T z)01cR`=2)Tv*t=6w>b55{%QVcA(2rIbwOUcc46b<`nAh(`ci*hYvaBVhIHKyc$S;- zxEU_C@C##hW%b(S8>^Ss;$ZfCBU{BrA}Ne6Y+Spxc42#c<60bKb{T7vy>c%>8eQ1f zD6PjLO=vg6?J+Cem3<uJ%2}MC2n;%&J`n;jj&jfg!fuCZkF`BYY*e4!*orlU1A;9r z6bgmpxa`LD%bTkg*W~qUTWc3?Y_7?hYoEBWwza(#hv|~BUh?^PV{2_w#zedpi&|HW z=QZSC&(GnWs?1fTikrp^yKz=p$GKo#!UJhzODapnf?S-D=O?9An9|uzRw-#te!ei5 zE9Q!GQl><gs?Z6aT_#;-)m>v!dQO-N^2KRD-co8vR3B7GWKgcJZa<5`xU><6{<!BZ z5hTC?o44ex?ai1nIuRr`*RF1CugR+yFK))6MKEEKMCSU&W-NZ3pPrpbX3~1oQ@*;k z{p`lYIE1;phAt$qNNru%T))08Ut7HzYe`53hqcY;ASdGD&{V3FiX+GUn@J)RmroLt z?U0^CnCqJx+Zz`)uEgOJ62o~2!X)XkwQ*_t=IUlFhS|h5l(<x`n48YcCxR1nVZ=)5 zNCOqi_wd3~Pwr2jIeXNg%#a3-qsEkGD=z>|AsxW60eZ?&k|1$+szB^sQdAG_Wkq}_ z-8vbEJC8{AL{P6b;ZA&<+}*&(X!9iEaY*=-?woy&0zHw<i=Q<tEGYA}MYgacdAzN) z#mFyttQoASy&Ow7k@^Kmg87_WSD62pT<rd1KPcFLC;mRof5d0Mq;2bRm4Yw$eUAY! zQE0Fza&_%dSQ3Jb#Y-RW!J<_q3UCjW@Ez0HGm35Qg~qRlWEM=XxwfYE!bS?~!)u{X zZ!H|$a*(4Cx9j>Xg)xDM81+`!AMqBcnt&(2p1=n!{`M?=z1VnxG&1f$bD2z$SANww ze_-f>I2_yepBIB6w;QfQS2)RiC4!nZm*PWT3wi9r6@QO7)kP&AQ}n)K*g+3?^o{=x zR|K=54?S<dNi9calzJc-lAZ!8tGKw-YLDqYt}`JTFg<u29>|I~>g?C(0f_XtS}XF6 z)};9*)5VK=G%}VO)D#fJZ@-&%wSnkFWWe>ohjHSeU;`z3P@^lIqpIQ}#wt$F`>%TH z*hX#mOW-@SBE8r#Dv>}DIfqlk{wwiU{Pw%*-4J0>aJFAA+*?Pncahe}f7OF>%c#3r z<QtOt{)^k<gZO>dZ?}a@R$9n_?3d~R3|3-R4QVR^AYqh14B0+FR{5q(gbvE|fZ(H4 zMa~5aaRNP!+<U6-oK0kPQ!5DU<W`ng>JS1xGn2_6LURizUF&fcHBPof(BM&o?=uaB zmL^%;As>f$kAs~!)CC!*p$$q$9;YwK+lj-N>A2v<jTy6(oSm3s1gY4<<*+e>SQ54q zdl*sBUz|Y;nR$PB?Zljh4J0#)L%~2rPtH!v@p0RA3)hh1REh}L!ifidZ+xt^A{m>4 zz>AWRVj{-dMZSOS#F{Pd@WeTBm?XJH5@@s!rXK?w+Ofhn6D5RgxK=fm*xSZ^l!@pp z+>j}g?1(ildn0JXd4;8=VY5}dud#)~($d12nWg!KMYc3wD^`~f96iiL=L4<bXDJX? zLpm=CBS&U#dTus1y_h?5W@O2pP3_2%!&^==QXsg3AkG9y%9+EjGM6bqT0BK+2p#>S zCgYu!u~-v{IuVSoT5)JGe7NGo+k42+wmJ?n$vJa;ON%(`8wZ!9oH;%wNcR^9jih*0 zWFF<_syJvQ!m1&YSsWb3kwHhBJ03!D*)=hrl8=XFI0i0_ibI@4eM%laWNPZbj}Ql+ z#C=L4Ga#%6@lI46(bSm;zk4XdwiNdu#B{EBCRfbjOfXJUK0}sYd~CLJlzK5&z`yxi zp_nU7=jMiK1xK3@9lNgOgmE^`pp)N2){NXX44CU1H*voiWsM*^|B7eaLjl`?U(h1s zns`Q+pZM=P-Xq^U;Z?h_eJQ)(K}gCd$Ggf?;L$y7z%y=#MN$xf9RWqM&7A9KdhQZ@ z93BlG2JTu5SMtO~nnvloTdPq5^G&!%{9!82Cua5J1a7)WjtAQ@Oti7|=H#{!U37#~ zCl2Kj+f8s}$Ubef;_Yh^rVB3mlF3yO?=S(G3z89-Bz}$|E~9o?qxV>Yp+iaTQfQbx zUsoJ<d%uZOkx}&hDNbR2d;G<z{CJ5|fzD$hPUXi(oXU@pIF%n$ahjx<g|^9BaaC+O zs*%XzB?2ts$oV7gO?oe;L=agr=p%F>uB(gRIhP0)bsheG=pxKPPUYjJKZ#?%Itg5~ zj2*Z<?Y!G^GzYh==Dm#kJ;9YHfs1~wqLaWyKfR9F;`(7bCxMG+eNvnRE}jG~+KrRI z#go8AI|$T130ypyU7804p9C((QE5-YS%SopJf!9%oP~01o`ka;dOXn!k@5B0f$eRQ z7K}&hDNM2_m}BG)c*M>gVBwuSJ$f41#GE`p0?8Mhnj6cZpPYvWcm&5#;+UtB#e_8B zM~lUyj|swc({V^Z_c2loK+gY=p*Vmk3Ab@h<Lb*Ij)KjenUd!4dA6`HvzW}G5liXB zKbx7vad<-DSSDUN6f_{d<LFYb>&F?lq++;Sr}}U>2TT)UoY}c#7>B%{amYn(PmySx zlIP~GD9<0<+`7E(<!BFX@0?a=re_P0;R-zqn)$Vt&406LzRr{XLm>0}!OX8WUOO-S z`ozTl`3Qa;J7qcD?ijbL6pFFMV@TIG`um6*O4-~(WFO=3ZxtyS9&OI(lZ>nNhBG4f z{Yk>;lZ4T61W7VJz#oE)(LGCppmgl?b~rY!HF2$8yeubC!AdW@Fhoxgo6&oNi9(X> z4@E=9+PFn^1xinz?y}LU`5imI!_P|Ob^tyyL6YcSs7}?k^SBs<wN%B*;mf%7&{j}w z{MJxQY{8>2Oq9g9zb#fq_-C<gGNhY^rQ;%wND>~+qDmK)$+}Wu<ZMT>7`l8sj^IfQ z8QVF~V?~<7kb_H;5W_o*7%m+*F(-l&&OI{Rxk&NmnBc9%rp40(*d@tcb;CgJ3|YZl z)(4n*Hm>Q2GpLDem>N8^I051vjk(L&>qdt{o3rO*spUczJk*iGwIptwp@|Z;QP1A{ z#-F_R+II)KAa)Hx+Kw=Eb;YrFWlermh>s}kV=;`MhdmFY<iiL*d+?cWJ$Unt2cLiC zy{~+2WPe84sk$BVQW@nNJac-VB#nz>_^#T=7RR^Vy8nl-J>GPD=QFRq{pRbB7RS*% za5O;#Q=@YHS$?!O=@RXDYxyl4vzD&mw2nk3m;=N87~98bBc0`N%|K#C2$hMmh%wV@ zC=#p~x`Z1jCB&o+nQTX+7+>q-DnK_`Wx9PJ;g5950_|`q^KK$oA=esR@EmLLr15Ji z?S6C88Kt(c7;R2Ul<RpyE!i<BCj0p8FJ$*`-RV4YC)Yms=n&$1rTq2kXr=k;mLFOt zN#eATLclu^75CV<f3Khaw{H=PV;S_*!#pnc>;?F6izROMZ1O8U>E=0}8!ir4C8pK( zA$N>xiV{Z&o*^anA#cB590*xz6J#v1EyNi#{|r=cSW#)gMjAd-dfe!Fuh(|IFg=qm z)E1C|+`BO{J5B=ogpYRmV?gwxgR^mHmKa5jMu|lEh3*B9)A#BE!#!;3jJhyeoKvgn ze5ImP7N-{$Dl@ZlvsEP2Nsy`I?XDjoRgrl$E>ro82@na321IJ?vRHPC5j)tUX@Gv` znhMfI(sA%Ote4Og0X{C!aN}SxY8M=jC^k%k$O9(R<=b&E5~4qeY1c41&?*fbiALif zk|1ed*mh%S=F<sXF|wz{V-H_H<{ED<^6*=awrhUlW%G?q^PBu4aE~?3e+%dN|2qZe z`TxbQV>{1j!y0EedyPd$<87|9!8sA{e$tuwghsJ}oHmqHJ5KkJ7_7RWs?*s*WnRh7 zPP4^qrB<nA7tbu#iVL`xR4F8LzZ6^+j=ZPYTC8jneyq}{pd|`eLJ-qjVQyw2si-C7 zGH6zi!7!c*m7J(>kxVDf@E(V|D@=*C@5VjpiRecRfjhAxrI3#VIY~aY$1P5Ypb}3- zOGZtMt7^Ub(rbzI-C}i(JYyv0VtRs-$0Me+O9&AhEQU+Zw#l*<SMVl+id{A0CDux6 zj*?u8%b;uUj1EwtM{N)iFLq=FAt%=@!;Ke6ejM3}sekmCagOhx&=^LNVb9}O?r>XU zyq$7lwkNJ1U_RkKh**kDvWW0NlQ?6jR&u0?$~2ZaO_f$wq(es3{L7ckf46D=mFwpI EKfB^C>;M1& literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-48-08.f52ea77b-61b3-4c5f-afc8-f5c7d7fc7967 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-48-08.f52ea77b-61b3-4c5f-afc8-f5c7d7fc7967 new file mode 100644 index 0000000000000000000000000000000000000000..b9e064a5a7bcac14d96e9ed88e389ce075d79083 GIT binary patch literal 56667 zcmeHw`+pqAaVHb!$viIcIZkrETt+KXyO6Liya57?K@z0kB?%e;#brolZg!`4cYxWQ zofj66!aF&NoQHL>&avafuS7oC^5tUths22^eJ=hl?)~`O=R{HZ1MZjm<?dVEGqbb1 zvx~)GXi^^oqJZ6*?&|95>gwvM>gpFiaL+uIDgXGXQ>S$0fLZ2`l*{;>zhN`W&Ntix zt)jK+`RfPOhGI3ZTgDEnI(FV|Ihvz0HQ!;CsrEr$X}5K)syLd_vh!Ql^LrZW*m;%J z6jyihT1#d7xrWo!%^xlQ7{FHzm6;zXYm28&S<G&u63cZg&0(4J@)H*~E^Obrz9v!m zb9Y+HPh_*VwVITvJJR}^v^eqGPh{5DChnf27w4p9DkfER#kN;cEhD>QrzBlz)mKvK zNr~B2rOj3@DZ0%jPWLsnol~k+)^?aGQw3M4Gs&=|G;5^?%BE9j3GFREahtVNt#%hp z-)Tu`ohd5+gwIXpC=$`hX3k2=b!yp#l>ZKOrB0`lYd6{&Q*%|LnXejvL=;o>EWS5c z%dxW+-Kg$nRio3=4Mnx{lGhNx6Npv4qa4^$&9JHr-E^4EiDCgMW?`Tt)~ahQMyPo| z8Men-l1Bd=OKCA@LV8NN(6EdqlP+0GGhB9)HH|$cIStL0K=A{^m0X*?GYO+d)Uxdm zLcG5X$7yGo>1ul`sdDzlYW9NBY=aRhI!j6DqJwU&q}JC~m|ACt4N1#zBn!aMt(<1d zpoOAKN=uc}lU0uLN-@pHC~|~EuQ{Eht42lBne-g^ux(h5bV=I}5k=a`HQV_nFGH-# zi##Q%%ATfH&}PGMTYQYB3dI6vW-5`T4m(Oc3`k{rT9suxn(8!`q>XCTZ68QASJx%} zNHS`ie0J4h-Y__}RCO(kn1h~Z_`_#S7^c<&TYxFRyy(J;RLm7X6-Uupwxnv{6Pu<P z2Gn-IebmJBhS8+aH(ZAXu1&1mU|PN5NarMhqW3-A4#w8vjVKr_v~$30NzrwqV{@G8 zwd5EaI5AL{6Zycmz&k4`pL(IO<{e)N6J`?CLtR=yhk}X0<;c0i7$cavyg0Fd&n6+s zGdOFP^8&o+HRlZC*QGo}(_XGKoinU@o&?BjzNuKdE_ecT&QaI6xQgy`sL3o94fXx- zehB6cff&R(pbgFVtu|A3`PkN^%Z5?c*`%ZztvhLlq(GfHG(-?MG+Qmnh76V5_EKn= zy$;uTUCz{y*-Zt!V+~AZF{YwumSAP~AXaLgWDoVT2Su$_)m@cIwsW8}yTKS(yvr=Q z*4o8r=_{%3`;^qMSZyUmxY-zus@mGIb5-4N)tatYjH9XSDEoO`tJwJ(#7I`@FdITE zKa-o!74lWP_i+yVpTomc-j}$e+C6NTZfsu3q-~m+)%0YV+Nv0aV?%(p{f5#L5d-&- z8W)RfHo#$qdO9`&4T!EP2?j`GpYTT`fYyXS0lgs}0V9WBk&R2v0T$a7FP-1d^7aNt zgIJ$s9mB0QL=le{j)hXYRgXl;Z(gjOy7X~nPuZ$kTHBEn%p5Fi6~l3iCRBxe(gkQv zVeP<T+R~o4q)tPtHn66WfV4w%>e=n9S7s%qGrnkJL9H>xaV-W}>yUmFVt+_}YR$H) zhifFgY`0@$h4L`TPURMI)13EqqDTJRa$YnQ?(!uuVj+AEqjGxLLs*QZ!}gv04u~e6 zrnu522$9cA+YJWwU{A3$P9O<0mlOt7svL0I3ci(TBFnS_U}0=kN#mjAB=j=3V@nx9 zYiJ&%_z(<+m1rU-8aoW_)vc}d%hx`>l{wv+YKsQJsWr`N%1tOOv>vWV+nMw#FeJ6c zroo~Q9R=$!B&dqPgy`g|k5M5d_cziLlU-=4W>X*Kj^;FaLEbbhlFzwZuD1e|Ga1~} z1fTJy&)mwMX=cx;1Em}+>5(O+GtVxaxw>>_i>h!UGRrb7dA3j>kh!bqPfOy@Bm<g< z#ned&lS{#%+`bKw3qnd~?7MgQV31Ofo{-K+#AS+Aw^xEC6kjH37`u<KuE_LY;&g<V z^T!`DKE!mxho}Zk%+5hwVV09AOb&4Q4%S5L08G#`g?nlh`)ZL$Che%DD%OB7?5R1` zR}-@;s5q*{>A`w}WBc*+RzEO>qhvyBg8!Uj6Mo@sbndi<Q_L$Obbg_Zi#67k0%A={ zp?>6v2wYPRknGB!L))PNUCswvndOS19{6HJ)%N_|6-_NH&vpY^B8F1@&SGXXHB2#5 z_{Z1d1RUCKMX2)2d9>;yK%)DavR6?oX=S{hZqJunN`O5+5)APtt8?Yp`@;6y*kojz z5IXg2jZ2>$*LJkp0XAlQ2a~NrQD>H~_F!+dta$5I9%_-d`{XTTE7)eKlA5jQY+veR zXA4r($||m7q|QC~%(ouA`NsWkedF!F|BH8DeChtDUw`MNm+yb-yAR&_^LM}f8vfn? z{m(Av6|d{mO2x(U)aq-&G3w9*t(3RmiZUr|UmOJsE4^DuRSjKN+BTF^@fb6ncBM~> zE?-mjE?P#L_L(V&ZB5}FwG5p$(YzajB?Oh2x{|8Ve%h<2D-hHxscqgYQCF+;4NZtt z=!OjfM|Z+g6Cg-XB-HV|=vC-Rh!X{hz*+PW`%LdcCtEBOQj!KF2fNXQ1&rLT(Lf9v z%44)pT{?8^F)#yjiWCPK8grA@wqUyg{lKN&%I&*Lr)fhTya<E<JrzF#An7r7bC7Zw z4tZjEhG5YqnSZ}M?Lno2qaZKqT8Q{rj%8$PUW)>HF$6uT1qDm_-r$y=iuyloSY>#> z=|Mk+Jsg7fm{Hw{gbCW(9jdMR@cTdtyr=F?jA(OczawE4M!@QssDwW@D`6HJ<Pk!f zVd@B8pl^MRrp3}qZvZc1)Kq`c_B0elJIOEVNrZ<$%U*%wx97=)h61}@+ikC;9Lx2E zMZX9cTrWh|2M8lZ_9&wPnuG*~j~q-mEw`WXB4)FX2A|coTk$9M;Jl-fqehY5cR4%2 zg8&{nBoVM>51HFxE{`Y&gXK_8k0>614U;&cT)Lm>sm#cRMv8ziyMs)jWuM^ElX0dL zl?<90H5QSG@|weIE$3abLQ@;`GXMetI*rA>ktVrc*NqC+#>~WF(!O{3@s$!<f|@$l z6^1NDP<VT}_u&YMCw;BKQzm@2J<{Cn5^V_S=rPDg)XR~vai~}fO60JkvmKetR6@p& zmZtB1`}KFf^T~lB6X=Y|GsJ`;g^br7Dp|Thm*h;=A|<nTyr_O8LSqr4XMG@0aV1M1 zzw<4b=dFRkiv}a#whY?3(4LH1qMyE6qhw59QEa{6{@!1{{pOnwKL5&lU-{Z7po8Qd zLNUUKW*<B*tvZuw9(N2&O>+ealaX@`ETax~=Qeyj+&LwC8+o<MY*9Vy=iRt;j({CS z>;5i;XdVG!6x}0=gZA%y>2Kco+~14oaQ{1>dhfGe505}ZorfytA1d4GMjc*|aQFIH zaTN9Xih^?Qz4+q&-+R*&B%xvHD>**BMoX-u_^uDVD4qkMG<Z4_n%xOfh}e<lwZ-Zh zc`4qH6FR^>MBk`sb~G)GX7cx6eCKc88l-j<@FPi50uU%sQPBEXGjbK9iel^>_%`?6 z-%=Sq*S=09KAL~<5BI<H)yGFJ4;|BhGx`KepF(n|27j0~P5d)bArH5(oQJ{;-CS@c z_wHVWUz6;Z<CzM(hQfi45B4*x^zFD!_>C+W=7LW!_qm#y5>C*SR7I)o)-8k)sAQ!w ztR?Bm>FMdSWU0az_&OYR7Clu}C?`wPh4%hg(p|D0co>%|7F@nr`hHd@kKv}tAc;r- zxaNCJlFN;vZ$5#F(?&2)b~be`e^|!?A3!&NCuGC+tW;w|A>?30gl+N|Kzt|BAPCr~ zi+nHUbAkW&uwHs>>ahrP!|@EsDAi>VUim!Mq!z{v{v^*b94Zj9Hw2?3*g|Sz$he7> z4_$XlFb3jd_z7qVgn7g=I#G<H!@`{{PWi15v`vEB^OlXjn_X^9MOzyBW{?M1s2hFn zpgjSKH;vmq8^e)>&F%n}BqI9iV_kgr>)*fs$`|hc-Phm#-WTt`PA2wu|NVE~e(P`F z{@x$m|A%is_}q8zf9q8|eDBY`CZ40@gKvI%5eE6u)_7k*>T3}gw|#^S-JkR$rZ8cR zz51BlNxk#szY^YncfRn=`(OU%+uwib-S2<N^B%nV3Q&IV#orZ(KX~Ii?|k)>@4WcN z|9<gzQr`MBh-}D=GA<V7t5-50>@7G+_cV$HQMnt@wRHFtF)FJWUv{w8UJfB&4fuF# z#-z+cJ0jmr;3v`y-ec!EB7!%$j~>1-gd=hcefa@2;Y&tPBA#Q?lCz&Sv>bbmMW)*Y zzs@u1%tYGjLi$PayVAg|X41l~)*I(|CKC?hfnPC@es=y$ru%Ke&b1HH@Vt6N5kLi< zxMr@Xh+e_IySoE#GqwvFb2n{3=TK`1O6fM1p7g2RefUh8+9ZPGCvlp?@lUa4ZA6uL z0dAbKaNaA3P~$so#iAGhIKMlJjgC`%B02R%U;sspb;n^$@=~RK!iGXi;}CcReR*q9 zl$}g>!&yB7Cr4jz!d2ldL+l3}kf0$^wYxfVC$FL^h$%rp1tJ%C+*gY+mAlW0T}Mp+ z<-FlrGs6o;pv4T;XU0`ksQoZx;>aj<g_jE)J{6}W;s0#gLhz7vFw!vI*SjGTh>y`Q z;q9-0gaptHoMSabs*xwOjyRY67`~i7RJJoIK9h%u;qDHqcW2f$F8Oq@8R&-4hNDx0 z?JG@$fIvWpq{$(~7;lM9ZM5K%V+fQIEez}Bk^ANaD0+blRil|Y*Zq8aXcW4)JGLHi z(Wtr<)Wv<+!}#aONR30`J{yhF)?|vpAzQ4>pg-!vuo=5=tJl}1H8Fa_VErI^R<|@Y zPsUl^w_%u!-K)z0_c(N`qwQ+P?#xX9IZ9{z4G@=OA@|t;!!ezk${~%x+~aHa18}IJ zKCwq49zdhD3?cIdz;vykeZah(+CYVfcF(V^-q>EhbPM{CcZ5WQtQ`pvf;-gU;8WNC zOZ%*`wqpb}!fO#AD)!aESI01P#3p4X$aWSywHro9_FnO@fyh`XZ`b6F{Sa~oFe3uX zaHc>U(?RU30ds3;L+d^8qB8t%{)+BdJiKjC@3J54Km{dwHG;l<XjGB*0r#CrZJeaY z>Z}GY+5k)RbqcD}1;eXH^RVxAT6*fq;@sldLGN2%L0^|{8J*k#Qz9%GK064+={N5m z1s%1G4(Yk)v2c4-<2{IU1dh?6>jE6q=BOTZ^$CuHACTs+r#NlYT}Si&qS`CrfqF=4 za4<dJ!*7=nhffUR4ftW`hixvjU+6{=A7*_Cap19{r-OL;Tm^PGogFEB`dBRsx`zYy z`$A2<c}RMuXy|A}9iV+!ZiwR>vVwDE2ROiB%bMrx>|^xs0Im9k4;ve9I2(6>h@biz z<yuZ~vI4=l0h*!FiKqv!T_33q2~_tdM;E?#21$FKWnS>#-bsryHBvx;JL#ntaL%Jj zG2QFx(w+1Gts}4tIvGLx$mJ-NzUQNGZ{n=@*w?>Q|M5j?cf?ZV1?|F=CeBUv<8A&} z`6qDnQf%AJA20tZzASSgC8bv#csdYp$<`>qJbg|wf1>=;cu$02WXd*wvaEdI)TwR% zyOe1fIC^L?GD1@zvX0Y;w!`CIE|HNXb<`82b=@^u`8L|(XH8T^&$kcgw}{3k6ACE8 zcOb>WBAqCcWKxh7pf1ba4jgANS~v`)*K+(F1zE{*W|xNGp<}f;*F{P+ERa$(gyWak z0Vi!{mmN%;_P;Gj>25$v`t<3GE<eMGcm@?6#c@7ycu=X(sZ4P|1&1eK7D5PU11oj# zNQD1m;aNI;`k{{zm>t|wg;^~$CR0T*Cf%33_iUe4GgUh73vO=hX>gg)?kfI(ge)N= z4;uTtGC$2nWf|5KS7+yb5R6bP7Q37fW>3xuy;JRU-&gae%0Gp9XSWc#-7p;Ur|+4k z#p&$!0gmFCKT~$_`uc&>fbVIVPQoooW6w04<i?!hRWogzzti@|uRLM?EI+x8U~*>u zT=`dk#g^NWwpd%5nwE;QOEU{gg#`)cWf#n!=Ypn2hl_3VAKf*7A#>0C#SE`bW<v9W z<qN1jHriq_%?kn1<u5Rw`HuxqoGLOuR6Y%$-Ph(XiIe6KP3DKofBmDUP6<9-Stf3j zgjB(qZNV3G8mzEiEY3{LO|zN8q_7loA%=rJUF+LeJXbu|!|W?Bq*v2Rk}qp{Kltg= z+-e#n)2r8R$s3mjO6)1R25K9Yo%2fY!rnnAD()MtCI9pjFVJpZpp#Ga-V**(UWCFG z`w^mz23n$5ROb9Z0a{ja=fz8J=QX5^|CYnqxOi(wF?z#`Yz`@~DPG^$-rl%2q=<M2 zC>W)CSRN>a!Akn5tTnDs!IEkd_pDecFxrvQ7689ck^@@smtmOV$83hK*r^Hgmqlg< z*xhXNSMHg=nkoH<@<+huqzgdj3yD+-X5wo`i!GV|r1T&8{G>AU6E3tOy>QR`Na;V7 zpY(u)Ufxd2GR;p}PT$4(GLa7ApO*e}ITu})qA<O(sM(!)cxL`u>A!G6M(sP+!IJsU zO8>Pid2l#VLly?}*GvDc{0n}A;!NhV+uPTdOsVwW%Rd)_V39aApD6v0fFRxx&dp$b z;!Ez5nJWFy@>;0olQ=-lg9KR%=^<>F@+e3dqf&Em;@)8s+*O3L`Ed0j{Xic$^GTNr z7QN**&5xp2l+QwSn{D&VJ@ctd`DgI8;%Yjg4r%c-(|jy&jt7sjP+EdXOK;DaLb&r4 z(wr!(sQiPFPv+Ac&(PqT&y*WKa_ZEHsEU%)=MxuI=A`T1Gqah-2On;_m0aUPd>;Di zoSAQYxQw;%RA#~~G$2umnbOCC`9>3yerT6rPL)>6w@{Kl!LNRa=kH&{`>>(Fe-d&! z)1!e6$#m&_`Da5d@MdR97s>_i;ix7Dpv{&p1|o+;nk%i9kzj^&f*w)bMf{LxBy+xW zsr<`;K&DeNSohgY&4tqCatgDCdN-n#o}*?zoU#7qV(HoPFM7iYa`M=09`kQ5mDbCX z-kS(Q1|`F>|K{1!$N2`8DsWq}xm+p*3snS|v==hjx2ZN)N>>JX@LcI?`6Umf;p0lJ z^jp(BQ=n)2^N&sNQ%CX62AIE5x;BJxA1iH?Zw@D%XWk(!#ZTAG7~n<w)M3t6bG3B6 zJUbkIpTDZ_%z$~m^ojD*!)r%GVVf69o8^h&Rbb%lJ40YzENzvShu0V@D%)Ih8y_vL zH?VwPf=s?lGI<LykE%qDVZbn-g*YY!A!NBQ*CCPb;aP_47Awn}Mn`%ft*KCWr=W+E zl7)}ycVBu95|5wE@E@&V6OLz;cmPZaS0PC~3PF-#WS}}!K?EXO+?@$SAb)%h`tt5d z*z_=Aew-GAQl_*+*}qPiS4z9(U&9CD9JmL<rWTGT08A{IS4(=&<l&m$wNkVElvh<S z9tp=`mKk%S)aun%h0Yh4NX+XcqepWjm|XXhdiT!eCra(cm6FLNHWd<hSK$+Y4Ty*f zj5kYGPir1xAi5}FZk6oD6=Dd37-GBpOX!KG&h<5SLnwAbENJF)w#&Hk&M1?Hd9(cU zfYb+~%s0vmJ3W_~w;ETtNDGWQ=5O9JZ)f;3S*|LWV6tr9;rb>i`sQ8#6`elEtKS-p zknC|Dch~JZsPNCr9|lf7r8B(@p?JlS7(?MEHnUQmM{&w>)-Xh*Y8y5vsQy6_<mRgN zjf%I?K4(_>;*7$u9HDKMYa!T-u<}m=Dm{l8&#aZFsEt5d7L9@Z`0Eki>pmEx3NQ`c zv#wc_Yx^~d#?7TojZ<BgnTe7+qQSvV(c4k|+2!^I?3j3p4?xnnu#7<6FEIl9riT)a zG0A3Y7)tbZ6iNnH<O12k4Z48W<{~m;+&t^4S8fz!)5nj7&Kimz-j0G|dn|yX!41H1 z$}`dYB;JpL<a&_Eqz_1Y!yt+Gqabzo;wtm>G;|1-PiKJKAI69rWVax<(PDxJe171O ziuTdw^TSBRciAHt;sqZHb?>)_LOF!s_dF;q!sTBKgF<gdk?3D~Q>(=~0P|uw6Fo!u z>j83n(wio*O}kY><9CKl6Tid=s=UMv0Ay?6z}P<E{cd?78lO<15g=doILTsdl0Tms z#!2G+C^G$?Cor)Rdjj+KhY8G}$S8P!z?W88Mq%=o5$*m^034K#-7+J(`e|<{Y<R$o z8o<3WY$*H^BY^!Yk15~^0Hi-EPe)H>{(4j|KjX<Pe?~PBtObCtmW$D&+FOngq~$f3 zegC@rA=CrW+%_!SSQfjh-Dmk~%u|7yf9x?*;NL=%pDTZmnhYKVFh9?iTnZI6|HR)r ze}OOOJQ-9_!TeLc-5gi}dP|L<>7TiLzVfV>w)w?-=9h%goOBoS%jFuO_XAN6&99WP zt39=AewFiJSTQjF+~p(hMM;={QSI8ZPa|Ypc3W+&x~sF(=4<Caf9KSx|Me<<QGCR? zWruPE;g5y?RX=8)=l1LHT$M`|Ls!qj%>l19(qF><U2iQpMjNMKDEk$XIjZ5Bkp-9h zQs;P^e7J>eLcGZH*5hE%bprTJ_+1zWk*({=U;!?S)4Wgnyf+3s$m5t4scLE*R7iJC zgcenuvZuyDp*RJ{8U8CKg9iel#G$7+xOl-=31MRFYV24H5@&MS5VY`1V|yv{_~$re z2!<p(Jv+BBRZ(ZMY_VF)&J?GovPzM$Y*8u9%uP=-h0Qaco#SAO0Aq4N$3ZfYK~fDm z4ED&HM+zPdE8`<;pQ6)@mVWTa5NIm<S%jE8vi9ku)FW#g2MdrU@{u)<m69YyBJC%+ zl!YXi-HwA@S9}$#bMpmtv5=i#sLp0*YSS!RnVqR*)k;mNOxF~pP?$RrU$ND&6Y+H- zzT!;KM3(ONf%xh$9STk?3E!1r)!Dhl;=*DrTPPM6voq7x>FmPXB0eotW*29QwfV|S z<wS;^$gsG3=@S(!)&zau$gm_;GsGyxlK00jHc`Bpyn5ln+V$-?P4k@j6fHR!iYv_T z)01cR`=2)Tv*t=6w>bH9{%QVcA(2rIbwOUcc46b<`nAh(`ci*hYvaBVhIHKyc$S;- zxEU_C@C##hW%b(S8>^Ss;$ZfCBU{BrA}Ne6Y+Spxc42#c<60bKb{T7vy>c%>8eQ1f zD6PjLO=vg6?J+Cem3<uJ%2}MC2n;%&J`n;jj&jfg!fuCZkF`BYY*e4!*orlU1A;9r z6bgmpxa`LD%bTkg*W~qUTWc3?Y_7?hYoEBWwza(#hv|~BUh?^PV{2_w#zedpi&|HW z=QZSC&(GqXs?1fTikrp^yKz=p$GKo#!UJhzODapnf?S-I=O(08n9|uzRw-#tey%W^ zE9Q!`Ql><gs?Z6aT_#;-)m>vkdQO-N^2I4Y-co8vR3B7GWKgcJZa<5`xU><6{<!BZ z5hTC?o44ex?ai1nIuRr`*RF1CugR+yFK))6MKEEKMCSU&W-NZ3o0^$VW^#DbQ@*;k z{p`lYIE1;phAt$qNNru%T))08Ut7HzYe`53hqcY;ASdGD&{V3FiX+GUn@J)RmroLt z?U0^CnCqJx+Zz`)uEgOJ62o~2!X)XkwQ*_t=IUlFhS|h5l(<x`n48MYC4v)lVZ=)5 zNCOqi_wd3~Pwr36pFL_&W=I3aQDaK8l^1{}kq+S406pa>NszcZRUmdRDXItevLZf| zZk>$7okt{lBB)oJa3?-a?rz{?w0RQoI3#>Zcg{XXfu6|b#m^cR7L>W#B3oFJJl@vY zV&s=R)(qCvUXG=kNd1B&!F*1xE6jgPE_VO19~A7r6MvuPKjO1r(zbQEO2HTWzQ+KV zC^T3Uxw`f!ED6EJ;-!!GV9}})1-J)G_>Sr98O1jDLgQCNG7F~HTw7CnVIzh0;k8hx zw-yd=Iml6n+jaex!k9orjC!l=k9dnzO~8|1PvC<Ve|wg`UTnNT8X0$>xlE?WE5GWj zKQMGb9FFb#&x^s3+YQ&DE1cxM5<yLyOYxzvg*^7*ioZvk>Y|d5DSBTq?4Soc`o@2U zD}q_jhn_d!q?RKyN<9z^NlyWlRa{(Zwa0WH*Xa-qm>xV14`f9gb@prY07QCRtrhu3 zYtsCZ>EcB_8X3zCY6=MAx8F^>+CX$7GT{2)!#MF!uz?aisL_?qQB`pfV-=_8{Z~D8 zY@;^(CGZ_ukzVW=l}Mn7oWm(%|CRVFe*0bZZiuibINL85?yaNPyGU!~zv@A`Wz=0Q z@(sy+|HW<bLHxe!x7)%cD=lO|_Dl5u1}ibEhO`v{kT6OhhHM`ot9(-?LI-7fK=4tj zBIkmIIDwu<?mbm^&L*<DsTBlvaw|(LbqE2UnTcc&p}B>VuJt&J8Yf#KXz(b)_nC%5 zOOq__kdH&W$H7h<>Vk~Z&<3R=kJFdr?ZjcsbX@S_#*EoX&Q8oRf>dnba@d$bED76* zJ&Y*mFV3Ka%)CFmc4AJ$29g=Yp<tk*Cub+-__*!5g=<K0Dn$fr;lu;KH$K){k&I12 z;6=$uF%jeKBHzDuV$GI!c;cKmOp@Fp2{hUVQ;z`-?O5TPi4wv#T&o&O>}}&d%0zS) zZpf5LcEp;Oy%99xyu#Abu-Pi!*VsZ~X=!18dTDN9kuA;Diq$0qM-Ma6`9N#<Sqg;J zkj{(3$dQ?wnw`l_E#~IuN0#i_)Q&7UyyYY#1%fLG;!KdFoH_g|bD0vP#Z#n)(9u6? zGTvz!i#3s`6T$eZ6^9nXhbvCJy@w2KtK%S(oHNI_w1~65ad1h>nd4)EbboQsNQzfQ z=2330ii1WXtQs<z#lc}58FaL{;~^B6T@&*u`FL1{W8l)LIK)ZRr{v*7rlt=32yyU9 z+@~Zm1Hx($??lBBO`VDGyN5DtOK}fEOy!F6xndS)f^nMi8M6H1W3!#3)Qh<S{>|kI z#av-3H#<x#INF5h*mW%@jI(hDo%|lMX5_YEz+B(BiTlkcYXsT(S3Kh$3fK<(f)*Lq z#5215#DCxM9{J`8uiB06OW6evLQ+OK-c_CgkM3auo^d-Yl7a~A2q=<m=3Gb9bC=-b z@M!QbaMxP6k|!?GG)m{)T8$EzZ^Av|4^we2F{>vhaMML{JlKw5qK&0DC%290q9dF- zaVVGAZh|92_GzOPZ(oxzU2xHtOs<M}hY84Bkc_}2@pBAu8MVtAy~i4i_e*k@Lc{F& zy5g|g`%RpRjH2&PaSHR><1bF-$4i_FbRH9NDnCBrRDO)asr;CV(<H?#v`yBEt76kp zjYJkN5nvHV&L44a(t9x_g2<9VAE5(rU0wXnxkRw2>+ttO7hw)^DjzTXNgVstN#LSo z?7-z|=iQd0Ik;st?`7og39dW|T=a7lodhoW>2<^w*ALq{30yqulj0<B@g#83Zkz-z zo&+x1L7?_Y;NsEj(mW{mBycf~N_!H{5+s)7AvGuAER<vOB%I~Y<B48~jIZAgY;Tja zU_4q+VUj(;93ywYBX;%x3-9FV(bLE#=HvkqNWSRQ+*l6%<UBmUBRGZ<$2^rRCZq{J zS}Y!YOc1V{jza>vkC9>ka{h-5#Q{u8xQ%lPS6>!!6l?}x>B-#G)ckBRhej-=6aQ>x z635{Qfn%9?=}^#s_>QAX!LA=?+>(mna-HhK;hgy%##tyP!#L#qj6*JRdx}Kklsq?g zMS1?<=GNtPFGqWDqIPPwP*D~l!xefKH1lgOoBw9he4Qu%hd}1{gPC7%ymnst^;4(* z&qwg<*eT2DcE`9~rBIA59z(jm(c8!3%=E&1VJ5ndarn22lnjqHXY@(N)q2Ajk^BB6 zVf0DD=s1ET86V&eLB{Bwr9n_Sc6vJ;8`qk+Rxe(blc->&7hV{mr-;qyy}?8wN%n`L zA!BXaqPha5Cr@|TXx03Vo!{YSC2~6eADJLY^e<GWYTJ2S48mHfV&(8<+<Is$s5X9U zs3o@GQ5YslV%*;rD<k}~*ftr`O~cZ05l18mk7iM&i^^nOsW5W3BUubxJ|0K#B!-Ob z9O$tk&0)yFrAdh4ok0wjj+>YhK?&y`8SY%9cymnfR$|lQ=>hDLWUsnmAa{nW;4bR} z%sd;{bi^6d#5PO~9$K6L@s7sa<?MB%L!r&t^Rd)&AqyVrNa0!%H_p&RiQ1@V?|tJ> z-h1u416>fi1|e-n7`nRR*t@bOKPtpWl=iV0#?Ql^hf(rjgr7b5%(ouA`No6Kzw+K! zzBaNyqwG}O4tc4J@(rFjy-$+H#W8$W?PH7MTW{U}!`B{fI==InSKof~^+${2XdXD4 zAcCn;IsPm^TAOr<cD%Lx7LHj<*Kk@#A`{Gk;eL$m<Ft{^a=2z7($Ese2%$1@7BOa8 z4Ml<#Lzi#^rG%KYA(QQB6ys}sTm|SRt4y^IB>a&sS)d&*W!_B$E96?E3!Y;wo-}?< zrQL5%no}2N<_nP{nJCxugj%v=P)zpm*<Z-+-@4Oz=1#7C@X;Z}^-B5c)zM1x)h$1? zPLjlFBZYu>AS&*$asOUF|8L(S7H3lW>0ut1d-ei+xWy7Tdp7wMpLFva&kYxcs}j>{ z`;a@vHARV|1kaEX`;fQaFAjt(wFxp7*%smqntui=IIO6&U?UBmDLroVyw__xUznQC z7itU0K<?cbnH?vAeZogO{V^bV(ZSg`G)s&kN25fd{6hDF$LV`@f#DuDby{7RDbA`@ zb*@rTDvMJK3zg}a*_kR5>Lke2@pjjbkgCYM8kebj#sr9jMFS!=c3CVt#fTm3(KJB6 zb4>;5BI!7I9M((diU1!MXt;5(7_|$IM-&^TLF56G>GJJ37zxpz#I$P|9cYz?jzptz z5J`|UFl@WAH1ny1t{B<V;<1OXA9Ia27kT)tN82^O@v`~Gruj{N5xB>i=D&sW{QsSX z^Zftf*Rh@Fv|)`ioV~`PqwzM^+2EXrcR%U$TtcJRKu#M<svW2MNDNk8P}Qkyp)#jr zXQtR<wo<E9vWxSJwIbpMRHcy2{ZepQIP#umYq7FT__0c(f|d}xG=m_f*~0Af!eTPP zC&)y_niXU)jHf~+Cn{Vd(}^>@$Kmb@Q)2DAaZh?8`Vm9mPOL~N<Rd{&l8^0ii&G+~ z#8c6dQ4`~;TJOH}S|WY7SY0E}7>T)<o}lFMh$-z7LIekk;nK5hvaH1wyosP<SB-dy zwUU~nB$whc=o&nu161fy8-&D*9a%xh$#u(c;{}o*M|NWBA3bKA<2xuchLL30^Ej3} z+}0Rxr<|DWiR%ZLPq+^vmLiiZB0SI}&KRnd9BHC5jb%<#rIi)wkP$Wi@@4biZJK}O Hy1D-kd1o$W literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-48-13.4c033311-3c6a-4e28-b43b-3ab4b0113751 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-48-13.4c033311-3c6a-4e28-b43b-3ab4b0113751 new file mode 100644 index 0000000000000000000000000000000000000000..5c506255d01e7ecfa24ad86db85a083f1cbcdd75 GIT binary patch literal 56669 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%0Ay?6z}P<E{a$$?8lO<15g=djILTsdl0Tms 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 IyKe6P1Nuxa2mk;8 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-49-21.e9d59f2b-d9ff-456e-b69f-6285fd2b696d b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-49-21.e9d59f2b-d9ff-456e-b69f-6285fd2b696d new file mode 100644 index 0000000000000000000000000000000000000000..f0eba826ccc9755095c085a06658712c3dbe397f GIT binary patch literal 56669 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 J{@QUe{~yV#F7E&U literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-49-22.57c52698-0974-40c8-8da5-11c393e0cb95 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-49-22.57c52698-0974-40c8-8da5-11c393e0cb95 new file mode 100644 index 0000000000000000000000000000000000000000..02db342e19fb61b3f69e36ab8a85508363b3a02b GIT binary patch literal 56669 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 E2Uf=~DgXcg literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-49-28.b53d2050-8e27-4d65-bdb0-4a1b51017307 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-49-28.b53d2050-8e27-4d65-bdb0-4a1b51017307 new file mode 100644 index 0000000000000000000000000000000000000000..2cd19bcd087cf052c56817802dc459b0113740f2 GIT binary patch literal 56669 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 G?*9X;e=o`a literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-49-52.7dd8f18e-944d-4deb-959c-ba8634d43f2a b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-49-52.7dd8f18e-944d-4deb-959c-ba8634d43f2a new file mode 100644 index 0000000000000000000000000000000000000000..732e337807c28c6ecea9e030ee1318b308297c8f GIT binary patch literal 56666 zcmeHw`+pqQbsrPw$vm34j+4|)Gg_J2g@k?K4G>@qk{|^yNzec&E=w}g*_pe$1I+I1 zJQfQ`VJk<G^RODLjvXg{C30oUO=J6q#;qfL8vhr4KR*3b6s13)KlGP=`aSo~%+Bu4 zE*68KNPP^50(NKaJ@?#m&pr3tbIv{Y#Sh)HPG!nJdFs?DLpfl!^<(8SKId;Z%y#ni z_JLl}o3;G)1GTQ$jqA3#!&KMFx0|l+8cfS~SY@hpkXKqQLsu17H=9m=>w11qXB{W6 zv8vKG+`Qh@*nY0=HVo^>%Rd3|s;M#SLuGyO)G3=eEmUH;j;*^alU{z};>LyTTi4el zDu3=ybNPvE_O@P?GBsCPUy~Lme&>nI`r5?ZbM)ezv`ob$)leK~CDk;uJ5EY6lxA%u zm7bKCqbe=7a!D~9HgUSIsqLJis;uQQO{NNMrN$)FmeQ=59w?hmp(V7p{KRe6)b#3I zG<~Njp>?Kc{1ZMmn5#%cCx^K!skU3qE~NZ-s4I0kom{Kl(wUZ1%|>1|0f{K47+HL8 zu%_!|D~74=W;L_ZG)zTv@{-pOz!Qj7qoW)+Qq{CohHkpd;Y6{46tgi<5^L7<CL`3m zpA6e$O-ZMJuB|kgJ0U$KU8vh;gGrZcr4cT>$r|P!lia%QNTB$E*_PT4eP<FzkErE1 zA%u8;>#p0%GOMlct)$A?8>`t1W}^j0s2D6Ip^GlMwUSz2TVYy_9X2FQ)0J!hL$`9e zBZC%-At_BwN>8dB<&|QZk5S|ZiC%L$NmtE^ZZPRN@L|ieUFnj(A0mphlWVl{4PJ&= zl^1zR(v&@2tDw!g*>3VNnkp0voSCUamOAVzwJ;!!?ddAZc680HFG(A!+HM_4)wW?s z{E=i<Ir$vbX5KKkj-<A2jF^j_==j5DO&F%$1Y3Y9z`W?fid4)MKowWfn~tRE;1h?Y z83xpG!F|-k^QPIL(Kp*J4P1*@xz6-j-IdNs0!8n8xE+kG%^OiLSZL>fIg(-+X2;<; z(`(5!IdEd2E+_JVZ-RGLQa<%UW6e9h5+=+fs)xF?f(``}gUgX~hcQMlb$M}O0iR7m zl4o$%F6RY!(QD2b#IH+vh^D<<XF6xvwLA%s*?dE>ciZ3z&^bq4<Kim1&!Hx>R5aB0 z!}}qaI|O17>wq>i<F{H&+2vzfl`flR&0v#~W;XAnU6KMd=F$*B;LvQfB?mH8YPXg` z!|Zjq#_MvXhRkj#;2nElGK(=4MY9Aey9cpS^(1?!pFJq*P1R^?Omf@<gE@7^z~WtI zG4$pxM$1@9b>F9?y3ML9DZ<UcXsB9q$H}RN+19FtVl$4WvZL(h4ZY&zs}LhurNbNu zt^7=GK3B-APVeI!_&<k-sk|?7N40y{Fx}X^l1V!>Gu8BDn%b(Ert3g}w)}?D6A=UV zkQx_@Y&O7QhI%?S0(FQkl>`H%u}}D;5kPN1pn%>GkARWGugJzF_W+A+ikHssXL);r zqd~0CvaZ=y>!OIq3&%pK)vQIL<To$YPDA>nvZrjRw%&3j1v3W=Tg7x;vjJ6MpL7A5 zQ&>B&m^St2ZK+e&)jHNx5|B=4PCdJQ^~$Wo48|92ET~ncxNVz3*1Du0h1egGpIUQl z^>B@(m+f{OtWX{%*{R$@ZkqGnPV~s1Th5E7!d<>3Ml6KSVN^~pdkBlMblJX}-vQCY z(-c>_1R?TyX}iv#9_%T$&Iu%8=90poNtFXmTfw(7O=Ou?04$76l{6k&PC_qpJC2kQ zw1(zEiVwkHScxWbqOrr!UftSSzkKbJTba|Hsg`IEoLbfGhTMSCLhIp*w4F(>0z*=3 z92zY8&{41sLxO4;Oo&dd`j{0`a(^p5G1-Nt=??W#?&xm47vxRTCi$Gp<$5bXIg`On z4e%Ln`pm8DnMU@EHc-mNk{(%7I`iz(nX5}@wx|jxBC~DNmS+nE0-3vt{xl{2OfsQ) z*i4(0Fu4>A%I(__xgex;#<_c!4+bd(=?UqKL|mrWHD@JQLh)sihOzqy>xxVdCQe6) zIe+{i<3mh0e2A*h#GD+|6=u7c!sGy#?_f=|55NRHQ@E#Av9A`1WYUhBnqm(K!=9Q` zeKj$wf{LSBoF1$vIJO^8Z}kIHxJo9pCiu@eHsKfEM(0j*IK{joLgyFixL9KyDInIQ z6zWHwh`=@F0LiWlI<y@c(B*uvm07Ns+JP@dG=0zCUD4FS^6b>1C1NPW?<{6UL&p>& zg@1fKPQan<R)i|QoJXrZ0wlVxDSH*gmR835>GpiNsRY>LBf$`VvIbX<y)SIPg-u4b z0ijdNR=M=qX*;f7J;26{?_jbj6m@3%Y7h2S%Zj&d<)IdNyHDOiwt{VzCTZEK!S<z2 zcD5ij?5xsu&D6OEpZm^(H{ZDboo~JUw}1KWi!a^(?CbBm^z!}BeE-2)fAQ{jU&Fuq zfAIO`yyA78TB)?LJT?1TaLpR@Ks)6vxS~u7+ZR{C!b<N}QmSbfO3Q(ADjs9T)2{SM z(dBE(-bLGN(LOT;v8^k-qqb?#CYpC+u!Nuz(^gVd+E07+3<ZLECAH0)CF<%mzM%<` z3f*u(;OI_xY61iaiiA3z7rhES32~x85jcxJVxQ@K=wyq9LQ2ws<X|_tuz*p!YcvqU zhVmFKRF@7NdkoCLoFc_RhQ{2WwJq4LKtE{HZsqpfrPH(_4_*X9fS!t<0g&_<yE#a? z42L|iJVUT(lgz*0p7x+p!BLQx4LwBsEXOjkHLpbhy%>TX)q;Yhd~a||PeuKo7OXP7 z-}Im#!yXR7d(5crM8X7Z?he&fefWJK1>RG4Cq}e6wBM1i3L{|kOjN=jo0Tw&4e|(~ z%`kNYFVMHXM$=+xr8j^VF>0DWX?q%qqMhUy^(4YWpk=SX@!Rv{LS2Dfuhnj?q+Gl0 z3yXdcGPqudt`87KjO<ZH12hQ<3?Dg|aGLFY#*3KEJ{o*hJMD@;u?OcJl^ivS^uEj4 z0UiYK&>@L{Eqln^4s&@#IT$R5a(YDZ0Bo4V5#`eTOiyJ-HZ)QMgxMWr3N8Btm!6C> zrKn`k%&4)5M3mPYUTZnuCMz_xK|cc^AfVG&-0NwQ`!&O?U~SAy94761mmgm#p(Utc za9v@@QUry!mwO+Mka*J98a!pfXWJvq?Jm)Vkd7XMd_=t*85@U+#h^qEJ37ae$xJ0= z{Ag+V?ss2*_j{in7&3v*m^?#F7*fc1-Jz1DD|AWDWNlJ1d&i6FM<O&9A$rya0u@)X z^zl32l6l@57`$jO@-5q>tqbkRs3rR8t2Ii-^cBU{`|Th6)!T2r`QVGMy!W+li~>4H z?jaN-jA-`3<I=1#ndWiFw6!!>kT4lJ*T6FBVt4Mq*TbDtvbT}fy37{Uvwq%<OXmpK zQMB&wLWt%O5Ju5GqBv;(&R72CoiF^Ym=5>9_nG%T|IP3SMAUhxa{i&Rtzp*S1qpYr zj}=EzudgU5_uh*y-v9kKJwXy0mcEkX(`&TEN{a9L(2L?Z5K4!qGojg?Accq>X<pl` zrjwWAgE*lB+(Yz@nr27S(r70C@Wprj=B+_$M*%;QBqacW5)}olpEV;_F{&uW&V_Gt z?}IIs;dAZlMB=0QhktkfD_?(n<nqul4LGAuu=FV;hidSLY170%BNg&+3(I*Z%+SpR zXL9fERroc@jyayGuxltB==fki!%E*yy8*wE4Z~dU3Ff}GuBC(%bR|_$)ZLnmFanLN zRHnToJvlu+eU>a$_yS*t%g&;wng-=$X}ZwbKTEnxwgV62QpJYLH%s5o3gt1}G#Mlj z2>{o8uSs&bUi8f;P;pua=E=^c&gBp5Sl|Qb2JnPz*q)VYY$${rjEJyJ9s`K)BpL(( z8+DQI#e6RC{~p#$k4-%mfo?dSAsMB*EW#_F$C}i{xWS*~S%yOeLiUDWlmuHy4GbAK zvGSqoZVARfd<;JUO@T0v*k&h+aST|vv&AXD^?|lYaC_de@prS!^{Hq}L*ESY01I`a z?;W%!K=Gz=%V%Ravas15z>-8nUwy2L?|$=#_h0$a{eSn(w}0^E`>&IU{oQ~6y|>@` zw{QR8kMIB8cOQJ=`}e=|DjvS~=id;|QS!mJKf4Hn{Ag>uuORic2#i}k!lvO*`Vmu@ zu*P0}%<iP#`RZQ_Z@@cW`u6>=e*5hozVz-7zv6ihUVQ~9Klt+R3B(_~@x6Dx{^@sK zeB*z=_`4}@eHuhIWJVbmi}KYg84&gsoTPg?#e!(ujo7vg_!KcJs~KN*u;yM4AzyX) zc&p~5%tJdO-%a2r(hS~X=Q$#RH@S}<zA%I%atwX>0W{%DMo=Q2W73kdpEk4{dyYk> z+XcVQGwIAk+Ur94N%FhWz^!J|!mZXD=XfR)4&#AeF_3;v{!FI(ZNka54$|<vdPEUG z1)aENu4sr}!M?k@18*_53mS7bZ9wNxYY0l|HkO|Bsoj0}Oq$vxg5xJ~n#1u=v1Tnq zm3RSeoU(A<D~M3zJ8i|L7yvlGJBovjQ+y&h^+jL+MU8dGVNCK;rGCPOLQCTicm#cU zYf+S)On1XsJpw03UvI*x@RlL=0}e>gkf_>Sow<`&(G<j#AfN(~3q0<t$(Y97=ftif zrvGx@^sSlU1tZX6hUzopsw&ie7&38Wl)A#p1rDEz+m!Hswq+xD$UYcp81L)dkO{=c zXqfQ!S3p7n=myTQsv=d%6Iw%@OMVPrP9G}UnG~PN!^CiR2i3bX>l&AQIyek;LukX% zDZ%!Y20}m}phME+5MqqC#HKcy@X0X*N{JSR_43Gl^8ysTzy;N8q|S9eA0HZp?(L4P zM_e@3HU)KYANDZ*IWkh?P`J-VqqKCHqHxF-D>LYi#xQKg?%V41b!knE-Y{72N6%`u zuI0%%%lkGAld*es8Q>m=Zguos{n(wk2_Q%5jK2ZmaxCON8(=tQa8o&?F_?RN?S23b zHPk2eNW=qZw3Z=c-T;`c6|@hSw^JLa5Yg`WwbdKj>z8gpKk|-{h>*1-AwqD68XSD; z`hRJkHP&{FphkEt0z}2WI{50Erh(X`%mmraf~QX1?8x3L9ySmeE9LE)ys;lb?f_;) zU>VL7h+{g4eKlcj4Q*(>2VPW$|IJ^~J&T984eDL?gB_@#M6X8Bw-1df(mLS2GpU7> z6j_5+;YAx@iM~!jb-G}B^=KaUy-rI{Jz1PvJUi%p>nrH%(oM6IJ77wLCBtV2fjIr< z{iC3xmf0aa_dFJEk7~RJk&eJII&@utgW4R`qpm)|aqt7u{Ph&4jk@b--d|LEB|K0M zNevFB=X?0=GUD)wLA(J!4E?aph4u^GDB{DcFCh**R`hfbFQ2Qx4rj0<g-;)=WkL6F zz<yt-sW%Tv&lC+Eji>{(56ca4d_z`nuIvB@7#vymoSl7)9v+}ozwlvW!wqNS4iNEE zU!z>h2~JiZ7&kyOG&&LW;I-=`)ggiE{^aPw_s$^c&$G-6{@Xigai&HJ2yiF8^a9R# zs1(z^t}We3570USyP%U1w2xelQt5j>3il??ijRH$OZ6XLq;^LvRbJ38OljiWWIx{4 zPn3TOM=!;;-TKM$uj9)y7gADs)rF@60herz0?gCrB<rWjKa2N72u7xC>!-`ghfbZ^ z_P<M+hKZwxHX|c61tJ?bjp(>M?&T60SyD$mL0U7~W;5SHTl}nvrWpCw0sR)y_+&x> zMfeV+SXiVJWs*z^vI5j)+1r8R3`P@&p^R#dzoQ^4S<dXz5Il6O7U#N1iG~GIijHvn z5<B3e&Fr#+iPQeKB`MtvXi1+weX-5Ya3Y>TLq~C(PaGapDs(DS98kgG37CZt0$RsP z9Xt}@|5$jIPM?10V+3Xgx2Q0yg~nv6D8{7wlJ}nNGc}{qabIwAb5DoMgmzc)2P9+( z8F|py=au<sJ}S$wrnC)q?)_kdVzJoegfM$@PUxL#r~AHIKU4l0%sZ!v(CxbET0eWw zIxS9Tw+?U=&-%Hti`Ul=+&X+u({vJUNg8{m;UqWa6t9|T;ryMxKYry2>*x8&Z3L4u z>lezu1}wJPO=*j@q^W7CIJ-2nxHLN@;k@jE^^084ROxWBWBt9m)-Pr5S-+g&)yYg~ zeYku9)yGC#ET(xOAiDeo=Cl630E$yZ)<?>x0kr$t`W11~9HPnkX!+m#_^DHZ4_B6n z8zmuCaAsTZ1)T;f>=%nO^NaJ!Y++JZin$QO!Je-5Z7iNEp6g-ul^4>h=_SdRwY(qv zbZKrijgslrYq#W$O9LhL6hjBKP20(NC3s=)pc57Mjn<NX`iU24wJy-fr&@0b|0yp* z;fnnT(MAI;(JLx*exLv?E4lOHrML4MQpSJF;cQ&IHKZ85;YBuw6xbB6Z)|UGTpLnE zyaN=B(mgB>l)_*oeN@&OSEyh~b%=Xb>=YR7NNEdzUnt1|E%?hYOz~qjLs#t7g!QW; zGXv~yj`eHztY6QR{zLg=;B(Rip!0=9ssuCfHM7Z<tbb7Yk9>Yo8TttqT9ID3XML>n zpUO{qKteBXr)8Pur!1%M;(VD%2k{R}|GAutE=y6EURl)a&OAJ`exvkXxFDnUUHf3k z`bVYzT9!OG9H}7-gY}!G|5pAbzd>;(^V#j~>r0kY`tRjm2tlw(oLWzm{zpI%?+E8+ zus-o6cgaeX{%3hDRP#w3pyok>tcmmxPMh*5NEx$IZR5nf%O<$12xs%*>P7m2K5*8P zZ7x`hX1ig19KE7^7FxT}vd-MIp30Pe4qq#6-9XeKEq+#-j|I;0;87MzOE78a?Kw*b zcfLYe6J-sR-w*j@J<ah94ZihEx&C9PPMwIVC^>yTaZzPWw%hltY^MI<hnsFCSN{l~ zhyFTe<?A0UV=X+DnXn3VNR(ox^od};(Zr-5+GSW%rPcB+l;ltFt6$>z`xo&(Y$))b zgq+UwXkbG!T{>U>`A`eI*_qOXa>08zs>uOpv!#oH$l;LYN^4~#m?52@M^twaKO`E- znlD`{|0*Dm>68rCeRfl8p>(;N!mOd*jcBFksM(KZtiQEbdba$_-mrq4JT{xh{98+< z_41_mCW4Sb$#Cqyb++_LzCoo5+?H%DmrB7x6#*vgg-rHss;!mMl|ddnSGrn$$wO)Q zxKb<q)-=x)=-K}KV-x(;QM|JO)^C-r4I$hoN*m>y!wKh^cL+=I({(cjc+oy}n6uSd zEnP3q4u{|8uj)H9V4W|0s{Hiu+7VIM)`ik$d181K7<l{65Lg#WTjk~9HO7j{w$|G9 zkC)c#SiUboCSN9*yakv?RU*eQU|7#W9Fu|&vRqi}kjVG&EJJpSmE}#dBfXH;H7LAO z(8Ec|!pHQxFTDnd$4_SXkJhjW$1_Si049a2kfa`kAjvQ?P#vlu0+DU*&V(V5KfVWj zd3PmjdYG_2NsB=#Q`({IU#F}qrQPyx-~(|E+yh}#3&#@xCYG$LC8KBZa82)8sZoB) zt11|egyS&FjI~i}_G+s_=L<|E*7cIvqd5{xuKP*7duQuYrB?k)$>I{53JJVb_yk}B zBH{w$&63^Inui#OE=pKiC8vIc7{Vlm*e?GHdg7^bea+nviro+kn)RI1W?Xq^lu5(7 zS^h;p>H|^c8)b%_UYl9B>Q}f(3yeC}KfY((&hTfltSXpbvTWVq`X(v*)?NP<oj%8_ z-yV&S>~S7<*X_Hg@K4Gg1x`MtGrbI<c*T(zL*XVit5TjvamsR5H$|js3pOaI{y`Ds z=BoCMinq}|XQ_N~MqyZv(6+|45Nt+R`KJMup2Li1Rm)S<MxZT=#=w63^$74aAB?F2 zOr7_vYu4o2ewCteb7@QGRF`FDq2!KeaIjPKc2s|MxxE29CZ6I0kPI#?BT)BCjKIF( zp@d^hveg`h61^RTlF1dhK(=s$F5tDeh>RFF&wA>W8wJ_&@uQ)$hvJ8~qo6n*3*cyQ z9dO+8Of)}<_oE=SJxFBI2c*4Wki`2@kUD&Em3ev^It0t7GeGVSV?++JTaepmF~I{q zKk!IJ`)KR=VWi@_>=6v{f)9nd_d7$O976DW9+W2G@=u3Bp|_(*^v}Gh)npxjd9j>{ zo}v8p069MGO%vFr+bW^)yThi5Ut$DRUg8D-vNdpEY#;D`ue=bAPpHrckS}|jWV05@ zpU({AB=LR}nSS3Bm{^HDf%yl+1ZGfV6udv=ORFrSF!{@fc7G%Q4ob&vnGs$6tTz-6 zJYZ%O;9eOv6n=>j!2Y?%6mSIq(jS+nqo*=|J*t<V^JJDkqv{CO0>D?x#pqG(Ek_8_ z@*2#(e^LGj>VatO7A)LY7Q3t6=lN>PQ-NB4;xSU--$IjLD1Vrm3?2nAzsQ$d3Kg~f z)ZaUQi7)3o8B|cg`ZK=W99RK*OO2rEpSSsZ<ykKs>&y47uLz?#=`Pk+%T+?}eNhjs zua&W@J+*6no%3K=F|huk%}3sglCb_#?b@?XBV=4|H(R>8Yp~PSYv;ds=hUhH^(uZ* ze8jnBmvRK*kB$E|KW3ii_UrIml}i=V(9Xim0k1XEU&8)fYc9EF3#VWx`xTNoYT=rZ z1(*C%=XjfZxP@&(yvXy`<6zKr0{Bh%T^I+Et?S8P0WOTwyifbQHwHY&<CqjtbuA7m zq`M|U3)P_Psc}#!PQh`8|BA`rfq*D+=qU~^Uhq{yn3%gdI~Ie)nVb#;E&S5hUdlZF zISv_uA<0h9&Miz;w3#ehRIAyU;`CHjDKeHVDutQ3>1n30dFHco9BdI_OfKj+NG38! znn{Pj9$E89!J}hkd}QrYbeh>T4jvf-4P`%z5R*sNKAn_$WR2rs0n$W1vgWZ;lB7ta z{Un#NkOXsDaj@%(ucA6PU(gl{+4%)^Hak<DX4%T@OeL#Ts!C<LswjoR+==*#t%jY5 zuM_bVXM!fObbkQESBDu;aAHaLt_)LW=N5|#i`8tQSX|7`Osmt`g}Ft1TByt}&J?Tj zm6^(k3_Foware?EDp;%u`hk&QNvdXuQHmw+k6~=0cr$tR!iBZ#+i{xaIrAx6axxTG znBS)-&+PX<Z5U^*l|pWD^6C83{L?}rqa5mjymsxv#>Mq(m*e!M_PpN0eIpF%x?S)r zH{)?LTx{VN#_Y=KwaYhFFR#VH?D=|D#YQ42j4o_kyS8>=dwt_t9AtJGYmvQjFF_hz z*w`qo$0AK=H^c2QE8UfS9OKGaoS+B{I-Wie0x^zq&;!D0g=&wrJxXj;pWWDsHH8C$ zEiDuZh2*&G#`Vjas~6Yg^=n&e7jA5>$(w7Ry0Nyky%mS)lCfU$`FLY%ZBxcXycUaE zSIy^j<X_Lv;-0F^RYk>3W2RF-E3M;Pup!}rw6P_XrD8!YPRnx>(ke{p>?W&}bT>a& zn9UV)#aSs+qDxiigwHOME;Du4oRFRq=7M~23Xr#yDiYNP6%rYg>#N((VlXak#Gya# zxl05IaKPp*d24$!ri@MmiOsdE8{2F0>cxwjacB`tm?V+8zOfmLALpj#rxz1KgilZT z>e}|R8yDjc=JFc4kia6fbzyV;`nG&+^=hmoAsHOjHlKr>h>Jr*Q7IKij{7&0L?|ww zBqrM-J&7>aH#fF7E^J(h!zUz$^ALnd(q(Jo()P{O%~%YxiEAivsa!EPm77ZhC+Nb6 zl`@b9Dwglzg{Pj}pPD~=)S%3e29Be~lx8b008Jttz_9^(%2ARaad)af>|Rn-5AJ0} zd??*I8HYQMNcKcfR~v9AK2Gj#;A6IU67e`Be9CaoK1YF`$mYe*8Wt9mx#}WYSdu*6 z)>~ramps-C*3@2(rJG3of+WFwPOd4;e@rfR|FItw?7tI#pXNW}vtQD23|Xb%3x3~Y z08A7bEQ(xRdlZ(0U}N#p$9u4-szd?q!4ke>I(tU3&Arh06_Lz_={48VwO-grVSRWl z6zZ*ogIg|g6ykPWzojrH5D}x^D*GeeB2^Rc<ku7UpvB*wrLPwoFOWvY9cXPPQ{<Ij zb=Dskx*!h6_WkF@V91?%+oda<<h~L?O@~YIp|6EJ_Th@ZN1W=Sl8-5RUooAa2R!=5 ze}^lAS<r``H{hhED>F(x5DZCA0gYAKxYTNo89uJlAsR3vcpM(cia6@**XRL=^tgI6 z@{Qi0`6biEi$*jub~~skAc)_7HyyQ(=tN||^}&a6;-O#zC3;Y!E1jdN;vz;Br|11w zJ#`$jI{YQ@9a@oI?3k5EpopBqDPsSX_$z+<UG;8=uqim(FBk5ut2nzzYvjM`LAhzx z+Ir+0lKK9N+v0=xeb;ZdiAz?R$bjsZ>H!Q^Vs;g2D*_;4lt2vGIY3tVhD?MG%JhKX zqog9|f{i$Vo<{CHRddfKvbt#%1a@*OODuH=0iT(PWDudbg_EweIExx5TOw%iD8dhz zhC)k|EbfqxL%heqP8{ljjMLC2r6Z5im*nllVayC%@Y0SMvy+^im}3N~*u>?qF@snV zwiA08QP5wUK?|9Ae{}7{oQ8EIGm1mOKt)f^PR#LXw`w-7A;qZ_5wL|55B%QvSZhTx zHU)tfB_qW|jJJ#Y;M$3GN8aIybK)>ba*HI;XdO&F1~{~0g>NQG2*+&OYAmt0jr%AQ z(OI}5QzqFFYhLz7(1`O2OH0FMt9V~!3x%bnh56~FxrIfxG*>OEO9+l0W}@?fR`IhG z2&*BT7ln}{GdDFmlbc%1&Cic4*|Vt~S#o&GNk$3;R}jRRAW1oM_*LdIB}j{>NDZN* zf7E2W(=s+|AW<iR@ijXRErt(QoOpW=8QNCIK_)q8j&ErZXMN+~l9V&Y#{}vA;-HZf zuZqm0+*}n0jYL>AWHO6`!#FbNXmiIyC@#Au=2P<Vuua#*rBQK+lc-P0!-q^w9rzLA z;FGvdNn{3u)ga!9iX)mj6XACcW!RSD9)y_673XusEY1YuH03j7`NhXZD@Umpa|QgH z%N2^b!c=Z{m{xGK3DI$CdQKQ;;|x0aJ!IX?ZNq@MzHt-xn^D#Xvh%Na#yu2pT=)fT zGOmedboq(@zT-Xe%@ba=8{3z%3m$}|jB>oIJOv)z!v;L#c330@5!ew>B-_ljUERoC zf{(+a!Nb5^Z{kXxxJc6|oo`pGl)!uw?h${OigSrsJvo6JZ6wEo?HDH7SbB4E+lVeY z!l@I7a*6FGI5K3PHk<MGH3`!N7k$a(s)%=(fXoHS2uu<`#}JoMyR6ZBtigD{BzGw^ z%$~0+4!eEO#Hq+A`oR>ZFuy(i;#7XT#Hm2%F%hTo<0DSx$4H#YkEu9KQp`fzWX-rL zHXYSSWbqOK7IEbK5%(s&7gHjLEE)6>IuO^@#qXR;1dEyhe?N2)<|3!^@zS5fv0t48 zF52b}T%Jz8-E?&qx2)#9jQl;pl_!CVey*aEz(qg3j@aV*VLK;*i)VdOoCGeO1TH%D zlfcE3z(pqr)IJGZJepma2L+!5F2+%5Pr_M(#F9Lu<|Leja%`T2vmAOn(F>9B_1l5% zZITv@N9!p}vL~2h<PLbm&K_Xlojg5y8rj60JU{};7u{+*mP0=|4-fDNj-kXcPbG^9 zX~K^di$@<5gzKi`kbv%Eq!@sl{~<$h0Fx4K<DA0Pmqi=}o5AN<+$FMDoGMNyb7;g? zI`PkDCUG2|5IB~JmktFDi0?SM6zuwO#x1EBuC}W_9L|~VWt_!i7>B%{amYn(PmySx zlIP~GD9<0<+`7E(<!BFX@0^=f=d^{$aD|=)&HBd6*1z1eUgydGA&~j~VAeP5ubr2E z^VF&T^D+E7cFJ<P-7#)gDHLOi$B?dX^!0ICE6i(ZbRXmJuZolmk2YuYNygP$-5rtp z{v=`aNy6wjf+QIq;EzDY=$@rPP&#&cI~*I=8@N_4UY3)nV5Jvc7^0_$&FH<sL?KD` zhoT{4ZQP=|0;MNUciHG_e#go0@Us%R9e|HakR<vSs-rqi9v6eKrl#0Ad>OYM+6t<T z-x_L(EqD}$iIN!ix5df`|17pmrgYP^4P3+#Ny4L9ROzBJ*-$Esob5;!Lzj=o5j=?@ z<G2S#tVnYha&T!9Vt8i|!)4$m=0s4!xkrXO7b)Hx6TF$&w0L>|yCm7GW}3*IAuG7c z`T#S}!8ILm1~st_Q=NwvCqTTTF?Tt8-Rw|kbM|~JwOq)8hdNTYmZTkLXre@I)U)@# z^{4N>_Wgk_h+Tt_wj&H(U2*JPS(6_X;v-7?SPbLmVb8-T`7pxI9(?XQ58iy^!53e7 z?`z)}*`HB%s&0q8R7Uwa&z#;TN#o)ezN_}J#qq7T?*Gwik2f9P`P{2-zxn#3#c?zb z98D0x)TkVPmLIK6x<otPT7C=1tfgx>ts{{M=D=)!g6-q9k->7fW+2kg62}OkF>w|# zW?BtJf)&G%a08`;n6x32?PwI^Ykgb==q9U7wGJfwkuKSw9WG_wO$00CTB8e|V=bOE zehsD7XHJ@#nx86E3y~w4DA)6ZTC!_WO!o2FU&!v?zSDW;POf$E@gc<ZO8M*6(Mt2x zEkCqQlEi5tg@AV;D(<my|6V`;Z{H#oXHxp<VIG%z_5ysk#S%ArHux2vbn_g~4Ht*2 z64Pq?kUPdTMTw&X&yW)PkhkA24umYV2{IPh7UB$=e+DWztf(|$BMqM^J#O^8*J~$V zn3~QPstd?K?%f!f9VdZ(!bdy(F(7);!Pz)8ON=5%qeP<oLid8l>ASkXa1Wa{tu4$H zXEjxut5lTA;?%-IWqM|IMnyuM1erSC?)ni@6`5D#GL_Gm0Fkh0K%~Yli)E)6v4cID z2IzOLp&(r(9S4uYdI?<-;Nt=fHx3q~cERz8;=nYBJYX_iz8wc6A^MY;c6GA@t<p4* zXfzHY36che?RG59d@7+UM)vf0?BVOjT;t6}9)9c5cCBx{Y`w8*eVbnd?y;uzui!lY zf2ZL*|G)TkZ09*`SmO+5ud(Q8yv=nsI49!WPdYu9&?wfC(}t32$LT&2gQ*LeHkB<@ z=9KKr6kE(zs+CH1aelE{T)@4gN+Fs1rQot~<vrceV`ZE0W0l_Lpe3X-XjG8EFrEgL zoTO+Ymrk6~Jq~kMm=bH-jcd{qQI8nnc47reAsq=)l6+#18=MkBC7y<sjFuQz(|Y%% z*AnTw&1yP1#z@M=bOa@jM@(Ut5F$8N43D1UkYO#Z+)V@(M>XT+)k<oPl3a?*plfi9 z4p5;-YY-AIc3=e|C)aGV9WRdjII<H{|L7s(9N$5qF^nX`p2soV;j+ef8|B1IPh35~ we8P1QvGkZ^5#ezramG-q<VX>fX)JTPCatVUhm5H8S1()tdei#rc02d~0iL@qxBvhE literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-54-10.3fcf7b45-3ff9-4842-86ff-dad45dc4e871 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-54-10.3fcf7b45-3ff9-4842-86ff-dad45dc4e871 new file mode 100644 index 0000000000000000000000000000000000000000..e4c8817fbe82134593c127588573d5a7cab1d9c8 GIT binary patch literal 48778 zcmeG_2Xq_9l_KfHu~S{*Zf7kQ0y4P(SV6GF6h%oixFk(d_Byh%w*UsfiVG}ecOi<_ z=`NRCuGd^kFL$}iwOsGL<$5n^mvX+E>or$$CHMc#?sAtXB1bDqex?$Gz?46K{`~p# z=l?%5uj{)=4<*zW96EH!)VGLDd(=hvo;u|a+euZMTSmdCS5hlm#j0-CR&47mDY{Oo zS$7TBB&F0QDGW8XQhK9d8b#eTth$q0TS?Wd5;2`rsUSDDXs>!5fGk21?NeV5U#IZ9 zWEBvWGzDdwCYh0RS4yAHWJZR@hO>HlKq?z1kq*a+$>9OXH0neepP|>OF9bxarrT(` z^abi1!^+ehN9uQ|X}DxqUTzSZ^+-48ZQHW@XCzlIAWnMIt!ho6&|yh8ZK9X9By!$x zT!+3;y#XM(wq7I!y|_WIS099S*8Sg7qGma+WRoJPyHZg%O$pj`lerru>9|mLD`wNG zr)=W5wo!CR3Fz(jawsz~AQ^RN&Ci5ZB*2su6Ga?>0g2Sl8Malg0X9it6uOPQk4q*! z#&Gcmn_;qP8;qdS$92;IY><*jVE=cCl=Y_RPWSgGlas>eaSAnHH1rAqmekEuV+%hE zx<f+b8l3>119CyDz#|&NjG@T~eOhveS(Z)xnJq0`B*C)ldJQ^oq-+qg<iM9B8=Jaa zam0zbTdc>1Mi|yDcrnx)mbt~I;&kxs3ZMj|)^Jf=?4aoQM3&)Jgn@O#6t#)lwCkLp zHKPKv%(CThsl*Ya-W8=|&~9kLjCa77jl9=OA5VwSCaD*Rrq@dvOukA5D3E|OduxEp ziG8GWHk%1kx-D*uAy`jP0yJI1k-d^wYMN0uTulqjvaxZ7=%%eV7(yN^l=or8JF)3V zW|-mRk%gmmPVy#vv1vQNoj%QqR;>mj4y=hBdODLk6Xw!ROGoaKE60uWMe2)S>2T_L z!>L*>z2PFgk*~{*t#hz0zgTr4du7Y5T6Jky9+%TOY1eBbtl=Q^Sk*+s1_5_|_mz|M zC2ajJ!5pS9Rqp^S)|z!`jWnd8VJS138y(4I($Y{mlcg_Xt7_Q>Y3R_GpP{cvT%<Q8 zSan>@>CJ4R-8I^ta?xguqqlIN&3cjEs@@1VZLf0lm0aI|)s^0+zPI<#A->#A?^W%P zWqFq>j=#)}&qUVL=?nd{{W)o>$Q29L54q~rOnJ5+O7_n#J*6!lZz*w3Hw~b+WjnH0 zf)!p{TR5@w*cuiuL%&hil4iX`R-n<Cv+8A|5-s7UvLc|kv^3{hmI*Ck7M3~MQh;H6 zlxNP*o?2fx{#1uDelCNve5_M3%wa`VJHT1x*{9ammzO#e;duZBM(HBxb*Q{f_wSXp zy6G<c1CoPk(!TIblHSghaL_#*ddEe2XCnVW^=@En)Y*)3SXGk@M_RJ#BuDSce~3*; zEQ9|-`W(ow3m56#`46iPctAp#r~5SxC#0tJpMip0^S>wm5mjzq7S$WCEY#edYLG_n z&3}|hE^Obmw{rBp{2!~52ZtfmLE)sY%709Kh2P-$B5AnN$@TS>9F_7PS6>=}VCx1f zY4_(p5fFs%;;Vsb%QW;HJ)HlfIv=X}fK;-iy5$08iXd2<CI~SpVHL_v2X-qYDY;eH zh`{P?)OAzZ0ggV<WRk?JH*54k=oM~bO3hk>K6H^joKRm3KMPI6bYaY(kF=kS#S}{# z1WhuSrI<TIxin{*H%+P~sJtHni5_8ih6bNLqE>qj9XgOr?F94D*kuzPXf`j>!9?}u z_;=QF^;S0b{B0FYRc}*a!8?>l(sUK1NG6ddY7!D~A|A)xNuu8-71*ott*y2}wm{CA zq+W5W)1#T80Xmc~t7BdbtR+c%*ryH9;e17XWM_j8akU0)t~V{a)TYUieD!jg9L*bQ zVrP?~J{qMRT^!4wRmVlUn4F~J`3)7SAEMd3sgA;zV$*T0n#Sw`{&ulcIE}w$=sO6A ziX*cOW;W1Jo}Qr-`I>sFU2PfjWgB)F2FO|v(9*)1wzRyi%_}SGPbCOiBQ#L49N5uL zvqrohj%+v@sWsfKB+cdP>hhkTFDz-tjwVWl0jZ@wGFm$jt0bLlRv*ltt%3-gN-*a0 z*@I3q<43d3x5p(q!?OKdJ$-d`M!g;o^0xK#(drD&j9Hu+E0Dg|wfj<AWO@{4$4hvF z!H%BJ!3-&b_)FkcXnN|{?4s1Pjp@T&b<d?zFp@UVRptqYLBj}k_|yGtgpn4&QQmHU zIx)rU2{N~5IWn7Oo^=aqKfiL5+uNb(3m2307)qh}gtE}9-U~y)<OzI$Lc_MA8nat4 z0y{Z+TzRZloe34g;!rdg0JfCF%F635&c5a;ZGHCW;`|z{;b1=EjF+P)lzgxH*bX=d ztEJxQ05s}BVOx%G%JB?2^rW)b8_~589;*!%Q5&NRiqacVTfhPeI@)8(Qm=Y)2Qq#| zhER*`CX7d`O^N1}<=#NxAsQV?#F_!ZE-EX%!7_j~@E>cNmykgZCiT*GyGg1jkN2v# zhS2tQ>Z}4?QdWDbS&#(KITQuUT)E+yD=^VfRl)}7<4phD#XO^{>TO=7Rx2A_Q}d8H zRj@$3NHqdm*^&fvx3#2Xm8D&@Hbd9BsTK{6DA?#JrYD7FIDLZeW|>WoKB>M8rN;AX zHg}g^Nvbjm@hL)|VwwkRI$ncf{qz+R>raDNzX_P3W!lg)2eRG0f-BBW+5TFT?OH<F z=nb}UT(Wo@!Ov05UbP=a%1`zGo>*KyI=iSXF3;uXS7p7(^c+xGb*0uDD35+&{LAI` z4ht+3HVIl#>g_9GMOJ1&;>KPw?fo5~MaAk3HoI6b{I9HU5Y4X={xLvHN+T+I!}S6i zd&t^Oi30wwupGr2;9&sk6zrADioF{W*~BE^tpE~L6sO%HQ&rsP0*kG%&dXY<;QC9H zffBpHB=%V*{sNTg1{2wAAu}DAzcrk{Pr=~Drk3rrztXy=pM@>|)PgzuEHvxsXI!=N zt9nYAy!QAaxahWZEM|-aMQok<=K>{7N*G|NMd>~u`3mfS<Zncn>1cZ!g#M?U`xH!z zY$TF11Cd$KA7&4*RC%7Pevf+~W!-K<>-_<tAqj~Ls!;={4^1d{_EodWU46ld4qA*< zXqp>fJO@S7WrXmQP_R?Gq~;`Z)K>29Qzt`n%UhmLv#H|M^td1EB&9N_NcatXTnx$? z>L~YM+xPaV10E!7J3Jg-<2&6kIqE9+^{Khm_F411_m}eN(5CV#Y+mXMR1<7oE7?|q zyWg}TuzkJR2$KN%eonbR+P2dKS8W2AVwQWNz;FkuM-o`S6%?aMl5Q%8`<T9g69xbI zIux5PIeH#v%6)yP+iY<IHiD$js1HG(Jtd$!SJDei8H^BwelD|&dG!M_DV`6^XJ~p+ zy$hO&RQ3H%41fB0OrwmdLq3#9Nv00*Nz}2q8T$Eb@}ozCzD}(`)B7})=of?)h}ScQ zz92rQ=o?V;_(GIi>(GhVBv(K=2xfR=_0}rNs1G2OaD=8WHJaYso!%Ge6fAXI?u5mY z?^X{)(KHI8B>f_kLtmUwZt7uN$EO4T+%YM>M7g=A?W)N*)wC*!e%Am~gsayYIq4zi z={o+`Prp>TrAIvq1PjBCe1AwvpnnN#%fT1dD(PE^B-k`85MDLiO(X~CmnpaQs7JcN z0>I1-3xe94>|d_DvL|Aa#<rnvXc!JtC`Z3SxvfV%(FQu}p*P|E3D(xl8g&8FuT*aD z39Q!PE<<Px`VtN36#XjYjvi)53Kzid4@fHzFH%7xP=#1E&>JwmK+<g@>7^1WK@T<u z=vOOu_NYT`kbXeY%ix%2Ms7w5sj53tfsnc<<V*Bxl)HM=Oq;s6Tre`?deHzZ*s=gV zCvY4f5;^*{C?ap`K@s_;kcj-c-HEubXQr7jS?M?ILAZV+TQkDdyN(L|CRKw@Mg`{f zg3+~ZNQ8Em_%rm)%!k9sM&F_u&|?4G>iq2byu{2D;mD!H({&u-!$#?_w6L^3e`0=B zT3KCCX2G9Dwhl{kCudg^V317?cm;Q8BB2sb*OQa|^sTIIzC65*yBF54ygEeRjw1IR zS6*3sCn$^e06{(Nr0v|J?*hSm>$Y)kcgiChuIYUnsQq0Ij&Ri&O>yr=Iscx7V)h05 zkw-TTh-52T^*Ti2!Q7_btknA0EJWT!ZOpbz6C>F)2pedC+$njw82Al96Z;mW-lrZ8 zNe?z5x8cctbr5pzRV>u@8hz@lS0SWqwjEBdDK<WV0?a!EZGWo*(S*K(6wzgE`*9kq zQj&g~Vq>FDpZaL1Q84W~dfAIe3M-d<tKj<sxe|(Le5K6M_bF~)WbuJTq_s5qXK`u4 z<uymYU1|2I$3iqhT*DDiB||rX{4#j`btlmZ&g(kjk)+>&LYFeV^gBaB_q+BWI=_2c z@_N*w?^j<72u7vj4%X1X<-q)~@|0;o<f1bpV-U|CgyZ*wgyZ+_vvB-Alv3Z1QtAwJ zG&aT1Uk_5DNGJLOAgR#&iR7U_2omXi@Po%U1-=5mVy6x5zDc9VZWe^Z5229w;Y5B$ zy$`TPR>fJ0U1^EX%F!RmzdADeJ(Y?@My1bye&frP9R1P!qY(!HLWbgCdre^Rq%<RC za`eaYv%y{vOZfj7<4I5GW|J^SKdW;(b0$fDJbzT3@Gy;*Ud0&YnpeKRZb{qdNcuV5 zFmZA0Ptu>r&#Cu^AasmKqd%EHroP-O>6Kz*{8Rb)YBqly{yV{hL)ivZO~znI$*46f z+m*I8jRBAf+rQ{f!*tHip$hdg2^AKuLuLB2j85AjKHH`JAha3!bKCp1pI6@m)qK13 zwZm8R7s6Y+U#v2t@Go6?J>df|`>qFy_@eEXVFJD%DTK>|zgN2ynLK;azRkj@Q3<Bu zui!NN)r9iqp1^>L^Uz=2urFQ+;<mpH*2G^^-V)sjc;Sj*|6{8o#Qea1K!f!U7JU}T z$Y)X-X40=KZ|#YA#j6nKXhKk{Us=PzmXhWtYp_GmI6|N~zykjp%G;v5EZjnPrEwGC zSIp7hRNmgxV(0a;<pP0v#Dh!{9-c}1Tgp3nBF;fuC`Ob1w(`zhqWL?@yIQxJKALQ2 z)r#fsD(~)L-ibgM@mOd39Q{4zJw4oK_71jb`uzlRm_W`SgdJvoxQC_ukC@Mj4K0sT zr5{vp2WFq*&g)@$jzzBqcBK!gw?J;Fyf0GdhuH>lJ9f!)v3U%Kt9%ELA7Qi28zuVD zeO}jjOcpa-eM~iRn(yPBr5_KAxKE&nBTUC3?pA})PcpB_&Qm1xPgo@aL7q)QpJkh6 zzBli3tmIFbv7QILp_=|@7wMlTSem94buevf8vToH1O8w7Sr~T;S%1Y=X+I3rAIP1U z_0P~xF@6G=R^27%A#$7k^)}SM@iO6LkM6oQWd1E%dZ#$A4B}b{c324_1cM^|$T>S3 z3fS@QSbzu=hodV1?(eIwVa$XH2>u_`5#;3{p3dV*FS{$`fAj%aMF8|q+nxAlMtw~q z6w?2NH_(bd=5|N@Us=#GL{T!s6u|m7COg|8>zC+?@25SqDmaq=-U%(t?T*%eFrL%2 z3UP6ai~_{@1H}Jig0sy)May-E{a-$gI98wOh$G~7hx6awsDmx43XuMXg?_ccjpuiV z^}il0e$IgYUnf{RzdNkYGP&((@=mkBqP8L0^$_S~?WJQ&SsY`W`#y);Jy;h{nrRwF z+uFVOn{jn3)3I>eZd_vbg`feM?d!ThyVN+?FTmOuI<IN`2p&LuA*SIGHvbe{zkU67 zqi`%rvtQJuQ7q7v$o36b8}&0ytCLLtcOxcX^j@2(!%DQ!^u<_%;|=zRCLF=h?3Z8~ zhV-?8;uq>l+Ls~#j5!8i94I*tUoqx`xw$&S#d2LizZ_xU*$xEV0KsOz0#h)?vJKbs zBHf926V}J*V@(5(B^So_&6tQ=p*BE+Qr+R+f*>$rj==>pJ_-*T4Qd>4t0V@%Ua_tu zcqM}1L*^LI5UUJeZ^N_>L*^Ii3iNgaz*z~xSpni5n1JD!?I?gHy7&H0td8;M(0gz8 zS1oG;0N;f<Xe4jL1<|62a6|yyjaAY8k3bt>M1uu6SY7RVFc;6>GQY8XFaG3A7#tym z=I_Jgo3Z&IH4reb!aU9jn?&D$vprBj!bCJdpasgl-~WYbl6@F|p%W8)HOxHRS?%Z_ zNZJoz@s~kyW)2G4w;#lG^gp+dBwDcR2tEWrnoK-$lal=~BwV!n;d9%zWhbzyUAtZF zBosf(db!{FpnU`}MQP6?qU=ZDx2My13bH+bMfTM(U=L!GD1ZD7m@Q)p9`!iw`7W!( z1kKHn*^);bdEKZ%$nr_P0rYw8jGe-IIO9A>b{Z2fc3>}X><rXuGB_CGj7K<zAf>o{ zJnBYOS=5^KhEd!w$&L0f<Q}~N40q372Om=<<J`;?<6Zb;!+#~oakt>u@ZmD3t%IAy zs8rot!7@veaB$9rW9jA~*j6j`oNF~E56|dl_489Hw-m0~wqVXLHN)Cub95@jnrGEh ztaT9#wol9ZP552d4I*nR@n8YsK&1I7?Ky40_iNN!uu6HO6bH?UMo9!&lz=UGiEvHP zG~krH2nv}YIIIc(%fy2R@Hl!^h%JH(7?JQueN32G8wQDig?!%M-Sl-}2}L)wQPT7h zh$#^=1Vb`7JUW&gDwIYB$waX{2uFd32K5XfgBd+NGB!L+bTUq&48J#QQSJ-!O)P^{ zvTC{*jbdq@oNwR}7LhTErTwbwHmth2b=454>E{RGG|5$KzoEO;tJb&!_YBxqukWyy zqNIqW`*AL1AqnO*M6lZyUzy_Ac)B!^9vsgWM+ZmB!(^~9I#L)c70P;HxUB2x^w@#; z5?0g>#MgoN5}BZ}tX<Cm@wG`zP;i7K{I(1$j*d-avJ>UObS5(~I5J!u9?XtSz_)B+ zbYdh^9xsd(4rJJY3=`dLAE;nL6ZAPF!{SuU;F=5}d4Cz^D7^ASo1L4RUs)Gv8vV2> zyrE|xbeB!)Jf=KyerIaUoTSrfd1By5>InOmjb)TWUC`#2=9Z5wES(VPOXV4(F@OPQ zcuh;}m@UpOoj5gnVqOHZXR3q6R{NHS9f{FuZh2{Ger|nXc}WDB4MG}d(L5I;jpmk@ z^9w?x3GHT>J!X1)W#5f)WfCHj0)vjHPlQ11MmdOpa2lc7yV@SbVVz{7dUAP9XbJ}e z%VpE)bbNe&YURZ0?6G-mVQFoC?$qkMwmSd#srj|_H4&zZ$9l==bZTvWRfCDRBt$L6 zdd4tKJvAz)rG%mvjk;?&)k$dqLRL%(5~SrdNtH5bEi<f*C8b#~wv#7GA#b>;vGk~% zku#%GB7bsSS;XsLH;8nC6gRA-^aM8-q%uPQc}*|twh>f_Wl&aT*H6M=9A6fpKi;bA zS#MK#mNnJh<SrtTfGJj=($>~j1;utO#95tJme=RC*<;66MaUD(p*WFQSzZ-l(Xru? z;doY7Z^mlM{QAk|V<Ln(F%Mmc!DqELx4N*ht}V?fLaRhPILxm;0ir_`hnik2fJ0wq z&gM7~66KTF#61X9B+Sa{^7``J@}dZzpkz*gY>bmGYs<&ipPXG4VwhE{xItVgBM-@A zvET&iF+}T`C6MwW^ttfx1LudvC--`EB&3u(DW)H#IG_P327sQv6embnW;kLO<Dz<S zF+5xWXAAnm_DJ?vP%qZN!+4oK@;LXVh>z7^SL};0@WZA%$xhI~`C)d`embj<l_y9x zCwaVWH2BEpJk|`>)F{W|i59;gN-&?3D?0I$(d+If``2ywdHnAY_K$z}OF9l5OTdVY zGCm~`0ON&Pi#BZI97d?YQAD2U<K0@csJ8<g!4llbcq1yFvWr4P7b56eV2za<Mkxv# zbg)a;f<n<+aGj`I#cS~#zojrH;L`4vtDo<Z%kgB_3;Lk>-^kJz#m0-l(I671Ni>YS z^Q(^f1B2(N;Hd;ZJrfMMQ*F8>YqPHHC=t|jm=y1r&E>HVm;c@4ROgj^OktD?mJ{^A zyN-pIfm?=1(1%D4a8ljX*tLqmkVFcUNTFFV$vI;BxDJPCK+GUHJdg!`<F;QT0<d9% zSH5iyKQV?8xo~}4+Y)v&sLAvBr%wW>ScL#qh!62AhjC)Tc`YR(sJRf3)vhYonTqgM zgr60u0~a)O&IEirR>X|6R-r9W2$O`%to<zhmw)<QZP*shSsTv__~pXAb#-T>pa)qI zl<QWdY50{QIVkh}jMMxJ|AedF`Iov?(BWufd%(a-#4f`FAOVmtN<a+F*>d0>9t{Z{ zl!;*A9lZr+hR^{Y6;|Tn!xeWjmes9PfY@PXco9;EAn-Slj0X{%TM#`~5n0q2QDQ-Z zMIS!LG!$H#G`)y7XNwT;S}+}lx}d=w-BwAE5#l!;hcPqtdZj5C#uK0Em|?ViidkgH zV>TUo7-1Zs2sR<h@AKDm%xGAJ3wA^(7^vv+nT{Dg%?7;6QzGmNI*j3hlPfGzTWGC_ z$ELvX0u5J#i6|C{``k4h!?oUL+50UbOcLKB31~F7hOPk|8bT4Bu@b_uns!l0?BUgH zvFI$!kg1{U5So|Kpc)>?pUZWctvtU>vguqdJ3gEn%TAEoSUFS7LA-P)6P*vV4F7V0 zu<FoxUN|#0ArFm?$U_tI_;}ZnkxgyalAT+Q(?El<wjeRfmdFITg8m(L7m|jL0E#Ku z9Z0*kKzN(fEHKu<wRJ)V7dnrih{wxA1}#}4V-=r&$2Y$4)4(FQ#O2@dF@eVrM9{c` z?CTV5qv0~6mI!9CaBs-4CW6CmB-P%glZTKf2gl}l^6{`O*D6}32ytTdJbCz_K?+{r z6k48R_dM}u?7+4lb`)ce2GLmf-9s5HP@*R&hUCn+oEe1E;c(5?BWNFH*TTy9PN1BI z|BuP(jGP{lM?2{bdz%oOPQ{S930H&((L16Umb?yT&V}VCy{k;v-G8155DGXhcn@tf z!SOT+t+dnp`=*!V8!^1(Q|reEvmS)FOn0oS?D;nD$`#QL^LGh7{DFROdR%V0h6zvD zK*$WI!Ii+>sKcwvqDbQ?9c`A&1ny~A1t$vJIKzf1GZvd|lo7ZF=OhiVFoPjiNV|@2 zv$2g1cm0S^F19@fLk6wb7Ce3{f=SGDY1*cS4h^wW2xwG@M_{7(xeRgHZZFn-C)OG$ z80TIFhuQOpi45{{O`P)AFrS;^6t<k#zBtvcEpf`xxkkjPcI}8$?HUrN+BGUp;}o-? zZIZgEij8MHVp+U+7>0<P-{amS6$yufP_uZ@_g=#m=>UdO$AUz~grERWMZDKOMR1Ag z0DIg197H$T)>*hk-AUoK&u*7@+xdp(AiD7&y3xCqhckp9+j9`zIO&t(AiD7&y3v8F z;SQo35271=nQ#!@xHr9wMGhZCH;OoE4`N<|D=S&t%|Xly-rji-^K!{Ej9wf~$7?6! zG+<m^M`4^jfjNfWfUE550W7@Zse8YmHZ~s*AOV*)y5**jKR-SP58x4;RS_|$#ES`P z!dDlIs~;r<?~RI(Ab8T%|B}EkfB|V@KpGkzkTP&yY;*+v!lA0siOfiPG@hd+w!SHR zf-}DB6%dQdvh(8kp;&B`VB8lOy(<{o)pUzjhNZ@%9F<AO!%^rK6(J$|L;3yYcpb02 zs6Vsy<l2b^?`n1LKrS%;Sax_c+cu6Nveella3%U1?NRt#wa4I--R}-E8!o#AgZ4P2 zoMpGBSK&3NXN&N0*|(+_tdda7weJaDW8tR@%R9R~LWo{&-(`_aLlG``xVo28A6)6$ z{rdfb8>tU&q!tmO@%Rd#2Uk)@RtipO;mbqe5IQ^s0tcFfwnb5gCf}A`xX?kB;n^2k z9dmK^2csr0t1Gc01JCmbUCzE}RVt(eZ)$cR<=#w`_&}Woui+B(Uc(hFx@!p?(TEKh z_L_@`hycq7JVym_t0NE-Wg0PQ&2ZX~*hUfKw_zgGFN=M+O2b+GNDIN@WUeX;jg0}> zy)lzIxMFQ$Xzt)qA$5`4lddRb;609}2zU9?EY4Aa9ld_d;KHsP(Oe7T(Jlw6Fq6Ob z>CH!;mK$3SwhU>clz+3~-b%B35Ia_hbDSD*#?p%g7d=GhzlG%gjp0r{|NQ*5@-|U` z58H&{6VvR$JAAE&U7jPtRIwR9b|7~dPdmhp5?IA_;qz^NzZekQe8$LFs4j^Nn!o7} z&S}6)a#oF>)8OGYmm4_f_1a0LhlW$>au#lF^}=}ucXR1)%%@uXF+h6ZVH6RX#YU06 zQ6g4;!6$n~`d-Wuc)O-FT*{7QMoY!gSfQX7CWf-v!tluGND*!vh>@wq9+JC?RE4YQ zM48HGOaKwHXaFzO1`&FaFE%%o-?^F&_i5p2H4)Z}=`lqg7kIK*1dI4QRX!pP?Bd{} z6b)aa6~Ty${y3%`JR{r`+J_9qbQ$_NLu^odr4-dnxoxn0M8&kT%qTy>jPf}&%Hvb1 z-gwxPfldCi@DTE+KLa0^ZIjoVVke6Ios5Wqo#{<F-a;zERl{R3jcFB*)Z@*cB1pjP zCB<y1G&GnljOl|TLu6vGP%ab(C&nkrnJm1grl;e%y&LR1u6E9F457oWzOPjFzwDFK z6pm8X3UJMmm>LtGB;!Xj_8tatIow?!x)5K(`>wI*C<NStLOxnJ4h=`5A3aB8*mcE% zikO-dkE$lB?tJPE?}?@FHmMkBNJKFQ56y}QnfUP#ly)&80tcJG0_r%MmR%ARys@C- z6fLoPJ>r_9D3?STbRG=JEmVkT5uDeA9X5!ZR<W(7SRmWw$WEC0dl%LW-&Uc~i6ouU zMKl?BWlC(f8k_xx=?5^M;L>U#MJ8TE*fn7yV^}K4sEKMgma<Wjrl+M#jHo@uROM-= LD$l@Yvnl^SZr9_< literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-55-46.19a4455f-b08f-4716-88e3-98cf0d4856eb b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-55-46.19a4455f-b08f-4716-88e3-98cf0d4856eb new file mode 100644 index 0000000000000000000000000000000000000000..d20d7c4e87cf3eb89b02d010634f66c610e4dd61 GIT binary patch literal 48157 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 JFMN8Q`2YPYKym;8 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-55-58.09ce167e-6a0a-4e67-976d-f3dccbda7f15 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-55-58.09ce167e-6a0a-4e67-976d-f3dccbda7f15 new file mode 100644 index 0000000000000000000000000000000000000000..55deaedd83a19492ebba7cfa1e8f98916ef3938a GIT binary patch literal 47450 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-56-46.7d37504e-8bed-49bc-9490-f5fd8fb3b2d6 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-56-46.7d37504e-8bed-49bc-9490-f5fd8fb3b2d6 new file mode 100644 index 0000000000000000000000000000000000000000..1a9ba12a19b8decc93a1cbed14be82b8ff915555 GIT binary patch literal 49068 zcmeG_2Xq_Bbs}l|Y`I?X^*itB3IQFs09Zf}BI%<jNaBG@@<{4#&pLUtz%GCl7g)^h zLKIJ7;@EL|b((ugoH)(ty*H=#;ue=&s?)1eoZ|dHv%6RjMdWBj>E4ldB7rG?{`~p# z=g<FtW?nb6O%BE6=N~$B$W*s<n+(W{@Hu(L(QPMLZEhJwqh3j_Y?Z32U0boO^Loj3 zlFhnnxTdZpH}&FZV=JjP8m3WFUBjw7$+eYa&C+z!Noqy0u|)>u=K;tPB#|Nc_3&{T zKMPh7VF}YvwrT3Kg6ayXi|Ld;s;5h-R6-~lrY;<b5|bkd!8Gc+FgZ(}C%*s?v6^n9 z>5}Km^AsynbsS;XA*SK#W8!i{w`q@5GjH3LJv=M8Y7uc#n{HKU0)>tUs%h)0wk7Bn z4aarJ3*;98B-d6;dQmNHkQ?L&pq+L9yAZ2cjw{%DNw2#?Ni|IY+H~W&!-8;<tGgAm zY1Naq?zpy5a&-;p?e}stJ(UoQI<)3zLMsAbs+VFV9D#(O*Dn~hRj&ayac&g)jlGXc zI+dZg_=8O`*|ZHx(3z8}=>RrJNhGlUUDL~I({yKshvV^M+~_e1HDEN<iViHPn#sl% z{w}JH9wOJo6!0973t9ypQ7C2<O*ZH=f}@*d(Nv$_Qo==IG`p_WpaVzChHh#Od^ozX zsoE8XpQyXVIx{*>vF^Z&qTaB~Ejkrvf=^cgB^b4ai{fGjMJK1S6t@x#tQ)4Nt-DRT z&InpFDlp3|TMU<q9YyM0RXPUkh9=Bp4}9s!d%g7Wbac|x>m^-L>zV?SuTlXD#30Sy zN-#OGkCe`4(_u<?#f>rq?FmYNrmHh#uO^m?V$=;+Q9`pUGf5HMwABVh$YX`_K8$!T zHXTooQJg%oFtjcR-h?kTZ3np1r&-CW)nLSdHIYNlrgP`QT-s~t$X#~jI80tBzYvxV zr>-`fs^yXwZIi=nU2be$fOYxBvJ2TOTW-~=3uEG>n92#eUK?Qz2cbu+#u_#VxQn~5 z949ZK>$e7Tn7mZJ9k5ty)`c~_A&ia*>51G#CO4iDMpNl5c^O?*%Qi?uhrIk8c|~lS z+!&+PaWyA5(S>%`XnV><mo<*u%z!rQC31^=7;tK>a^#gv-+<MX+$z6!@X#T)+|BG& z?GQzAmnx3G%uUX=t*JAYhUbQJ!gPr#7PKE?)vcN0+%S|Jo?CiSSw7iO;(}@#KyAx* zM6U!bytcM*YU$B6EMA6wqpl^)d5N?@qcLyQ%SNTWgr7=_fa228oNHMow1in$=6FW| zit%xlnV&nezHsu%9%cMo3TOF5uVR=(i>&s5v&yp1tgkOG^(eyf01AxKHt2Pzyv_{o zm9_fmF2f1IK{aV#_$E$nV@f#a9uB#Eo7@pAd{Dj%7#npqqa0S%1j7-Qth$~fcNRWG zCnT1^pO8KW^6SzzxvTJD`F;;bDD&*FqTqy7l;LwwkZJyR7d|43-OHkS<CTS)t*HiS z<etJuspP`;U3)7>?k)VWEO>AzQauz-@~Xne<X89&UM%SiS2(@CzLFzC;p6g4LlA7$ zfF<p|!Y2ZP=&bl^pxROmJx7idJ}KuzHSZTROQ>5eP^JWewP}J76Jl1e+;m{KqQ?cd z3L6nvy^XqR3Om4&`<qmfnDu6jJOI7IZH(5eHOPb8<e`}SV)$BY8m0?l27M&MbS$Q6 z(g<jh!7RnxS;C|_)x1eu)}Zo!2qbcp;u#uz@~~VTICSVhHgyxs$0L_bB++bclaW~U zrs#LpV)Yg}_xx=YNmg%_VZl2Ti<49pq)0ke(B(KJ;6yx$yOY?ktyf^L%C@%3hQ0-I z&eZD_w>mSC9!-$ZLRrpuHL#W->|vjlAY+A!{P4~O9o<zLu({r}Y^_U^<Av&#G&xZ) z<k-$8Lwz)~9bL>6&dZa$U5p<ilZ6c#svjcRf+<hHhf>pVt(rpZ0{(VUE1t#gBJ>>u zM8y$l1~nTfC{NFksX|RY)2+6M`JxRw3<G2>2xwtpO<7uASMt)z`jasotq}^SSPtxH zXJ{kd7e_Q4MXxp7tvJaQ>hkiQpf4;bCyvLoVnXQXkBHU|#41jXHLDL4&R0PMPRA(o z`RqYvsPUs&XWL_q%+hRsS5IDDot19@guHD%d89gvGh+^C#tNkGb?v^~7MUD}+3^zA zV6dYn^DsloApT;w6`GkoF}El*ZDZyLQ{8jPB#fjDbQM{`5zsJ#9sbNP9bu#eaFn;( zpNUOVdxFU9S&m4jnP=UC+Rv@rcxyW}b7?zHPM{RZ$E1Zp`5qVwDo@}SC^U2{s!+QH zC9sntC#6RR<=Id%EDlA30ia7ctgNi=;@oSVRMzK?FXq=^4F~fPW4s(WB^3tcM|Z$M zSRM7w2B1+73fppgQ;uiIA*ZFq!8TnB;nCVq5w$V0AW4I5Y71CEK}UO3S{js3??A?{ zND=C=-GuSzv?-B-v^*FHJVc`>iD)xG*hOh&Fjxk#2L8~tSqTyJV7;!j+Km%QdTda> zC4{!OQ>PWklC(Nl&4MI=&Y>t+X37oAT!D#>suDIp9;5o_F6J3om2dSbbz0fTnp}X) z>7oVVMX2epmDL28yPYKkt1RrIwOO*xOtolmM8QVRP(3L$!^z`pH%o1L<O%s@C^ep2 zv$?<YiW8Yqh)oglB-K1%)A1S<>u0Z;Sbqw{`i;O09n*%KJCN<}Ra|j)%J$cyY*%8^ z#$d3GW0J+&2!4)a4$8wYQhuuc_tfI@@wr81ae2OwUlr97)pI~)Ri)Zspgj78@h_9x zJ1nqN*u+Rts&}u16=|7-z>K~6jQ2M|N|H4gY<96=_@}IH=!#z@{3Ss&snITa!}S6i zd&t^ObP4=lVL6I5z{3F6DcCEQC3`m{vUO7jZv~L3B01d_nX2TrFR<7O?YyXHMb}@V z43yXnDzVQ~@fV;>HmJy^3z_M_{H@{qeG&#QGPP`{{gu=`{VZ(xCl<`%XP{Y6KVzzu zU)58}#I?s3!9~~7v8XW?6tQ*cp9_>UA!dN37NvVa@D<pE;BQ2z>8Q00LjTjweF~<v zZ6xBeiMClV9A*!&RC%7PVUK$tW!-K<>%#$|Aqj~Ls!;={4~a>43{|tzokPKj4qA** zY?>QjJO@S7rG)U5P_R?Gdd-RFh%MbUBp(aSEpK@~OQ(ug)8l@u6Bo*$BH<_WaZxDe zh$G#NZQnB_Cp<{lc6d0v#&^17a>SMH9g=gM?bGI2?=R=mAx-I3*t{?ls3zFFqS;o1 zx!;r$uzkJR2$KN%enGmgy=|unuG$zd#T@fQf#D8Rk2tV?Cn!pjIN6kr3{iapCkp=f zIuxBRIdTza%DqFV+iWodHi9Hi%MU`IJtd$&SCUIq8Ehj6`CMul^Xdm=k~|-n&(LIB zz7v{htLpomDE{R0s7BeY4*5{pN>X)*O`@L7&63ZjlOH`A<aKfdn%<|WM7|)bK)jwZ z^d<f|Mc#m##}}gHT8B<VCb<I2K`_G`tG859MtuOOgd;R_xzY6I?##YOr(mgLawjaF ze7AZaie^v{#mN_;9QxvzbmIW!IyN2H?;VrkOQf3yx~`g(Q%$Q98+HvaMYw9MkrN(t zo~q-&Ve+NY%>(jrAXpf7+vf*`82Xp6witYHElu5u#lfawf$*xSZY-W4Unbo$ARp}q z3jk9$EC_0EvVXbs%7HeMG`0<WL&I>GLOJpk(yasXsV>lI54{QRPq40T)^-;#`AX@w zfxv1V?lOeNpfAyYPLZ#YZXcj_q;LWJe7~>)@gfy80#$UY26_X=7YM4Y3#z8+8uVZ@ zLB3kLV?ZA5g7p1@S_a2FHF8r@2vyY)in?C+guF(+M!IuAPIsw`%LOGPt``l!f-Vc- za{|W!B9S9siz4#Y0ThvM3W><C+ntE}dTN>pla+kK9)#;R(lsMoz3-@yZ;}=0WV^s@ zEf{_4hD2z8i9bu;Ono?%Y~(Gn0WA*Cujc30^8z(fgd>MyPt|dRj~Ln!VPR=Ke=5H! ztgJ3bbKuX?w~h$&r{`8<V33U`yn;J4kx+@J>hWX4<gK)AwmiIzxfj;2zB)wSjw1IR zS6^9tCn$?|13^9Qr0d)x?*hSmOUt;oJLQoM*UY{R)c!69N11Ajrnq;boPSSDGKYfw z$RnEuM6#8vdL1J1U~ZFdmTE(E79ww=HfCF<iIHpygbg%6?r5Ga27Uw3#J)wU56MSD z(t}RO7Ch0f4npp|l7-q{V@RI!Duk5HuEXgyMaL&lfLVv2?QfMJn$UNUBD%C~KTd;I zij!}XY;4pSk{<~*3Z`90Eqf73Vdau-6?}gnQ$jI~t&}<PKFJ+wTYO*<=`4-@SzKCh zdCie;mzqQJi4ctt*Kh=sW~e5RUj(ne>cl$1d0j_5;^aF}=n|@zerHJNe%BsE=XbXx zuSYHNe)+Y4V7qkO!5Rv<9H<{woHi|pTy$nd4C2{?aQvQ-aQxnV7LMPCQtJCrN}Yp_ zMy440>p?OU=|p}2Bo&%Jkv!xFK_a~mzOeYFz*pc`?6slYH)+(in*|~9LntJEI98aI z?**)pRdJSLS2`lJa^yz}uWp<Do=Qa{qf+NUzwzZtj{Iohkv0baLWbgCdyQf7xG*cE zbL7VgbHQE^OZY#O@r1`!v#C=@Kdo~%eJ)OZyl`Be@-S^Ly^1l)HLv_|-4a^p2<ipZ zFmZ7lj+37#%**$MAoPq#BR^R<A-~)!>6M~m{8NQ|HCs3d|4vciP_{u;6EPT4Flr6U zc7>LvkpQXC`bK^lrgLE)Rj8kd$*^!8DwCh3bZUk8v`YIyXtU(!TKl!1m)``{e7p4Z z!&l@N!dtsvtWu-!FI{~-;R7)HZUBn-qV1Pq0=^$9gv*1!SGydUJbTi<&BAu05=_Hi z!D;xbG3m_%fdLigp})FeU%U{+mcI?w#9x!%(!LY$!WF^(M^{IP`GNg_0_z_v`ZSP{ z&7>5}q+gfbI?(17uR@%o2|=xXWd#FUG{sL=V27YEgg|qE1^zdrx3%xGa0}s;#!ZA@ zF-Lw=diy|!o!842i#pWPJ;-{@!!u5POM1sZn{&|SiqRy$ExmJ>X#S4$uFkEdk0#w& zbz=Fu(z^$!cOno*EY{h+Kz>hp&j9n8y@PI=em_PXCXn+7VTait?qMnaBkHrFL(Ae+ z$p_`zfZ3;+^Lk92r_rl{UFk#e&5#=^?~4@jVY-2A#V&a+Hjm+OmG1%aBXqWTqeMQs z&+9si$)bj<kI5!Z^L?DN<l|ux_X!knI@NJ>cdMb3Pg1YQ&Qm1hPiQ3_f;^i#d4_J5 z+1|X*v64Tf#(Ea?hHCnsZIeHb(KJOVsbJbx6!I4>1O8w7Sr~T;S${=WX+I3rAIP1U z4bPHKQGNoLR^8PvLgY62>lW0%@iO6LkLtQMWd1E(dZ!t$jNn=bc31%-1cM^O$T>S3 z3fS@QXn+V5hodV1?(eIwq0EE{2>u`BapdJ7p3dV*FS{?~fAj%aB>?nKtxo(irM{x* z1k(S7HPDGa=JrSZUun=WL{U=16u|m7Dm%L%>zC+@@25SqDmaq=-U}_v?T^-fP@Yqi zitgeV8AXWm2Z;Yk1!tFmYA@Fx_J8>};#hsACytQYAI^V!qYk#HDnR-l8v4}*H<sTY z*8h62*f|68f4yL_{Qj^$OXaqw$ve#=joOB2*F&I}b(fAEWpRvg?)w~W4`5w9X{IO` zZEFwWcgoeBOh?0U`*Ddq6oLk1wx8Dz+U3T<em>U5(0N5+NALjR3os3ju=%IphV2_# zjl!`g#eQL*MzKI&BHJ&*+Nhr?N?qRsaECDgqxZT@9a^G;rZ2`C3~#VUG~o!2V!s5_ zFr=>w6u(ek(!LY{V9YT9V?gzb@DXD^sGF-dTrAfY^ve+jp6x);4G?VhD=-CPEW2<$ zE7G5cH)4H^K2{X)STbR3--L;{73u;sDAgbC%?JV`<|te+<D>Af(V)fvcS>Ra>=o-v zf>$C4He`<Rv~HCF?5&vAW61nMeSzMF02nJlI4eNB9TPAdvl|7lME~C3fz>e{9eVH0 z{;Fkd0N^_@2aV)ixS+i#BHShb?!v0*{zsq<FrvYN9IUSP-I$AKZ>itdz6ZZDCJc^{ zLi6`x@=e%$kQxY>S79Dwg-u=EfU`YNLBK>bL7)Z7zR&-LYLa~fzo8Qod^OZO+*|D! zPQ>l|vG~iNI5h_a?b{DvI{KeGNYY-g?+88!K$=uMGLw@15F~8d!|=Oh+p=TW)UMsG zb{vYIr@h>7eb7FNn4+|25mENT@ZHmCJO$ZKV3B=w4A>*sB+4Iu17?euf=4~hdcMo5 zZi43Kh;+%*9dX^LLCErHwgL2c?VO#&dN|`eNOlSnFm_-saO^bHYEn2D;*3W)Mj@rt zIv#acmKK#}y<wC#O#QGu2D!)MV4-~G0r)ko85d@!DeuA`8~$m6<8HyR;Ui^GTSqo^ zqf&KqMa$HV!NEBfj-{I;U|X%!bFS4mc4SsPuU?!^x>~qq*Md2})GTe2&e7>4ZJt(7 z($;w}Xq}e#oAA4^8${MtqQL^h0Z;Qj?UUXZL_v{~q4A)C@+}ftluQH8!1JJx9)+Wr z@LxI_Jb;7IXQJCYxPXZW56nk|iM3(qSHvJZlhc6(5}nM3rl=YSAs#XWLozZpk;#r0 zweb;ss#G3<gTA99YFgJv(rRivGd8BH`lRl&GY_^X)j9bll0nj}n#xC`NSfC#Ht>K7 z&lpA0e${mwR^8mXW(d^Oiz9GW<eIhLP~GY^Yutfb1ng_qcUUP=Qbf}ID3`L31alfZ z*tNu0x|EqrX;Z0@$!uw2WV}44j}#}yiz8aGtQN=0s+vk=4#XF?8g?MQ4#XGF1dU|v zdKQSUP2B_qhfBh@WLRk;GnLLxl}A$P^wh}sSZQn|o0)=7+2X|1c)C1U94{Woumc&! zyO%yt!MG;qvqpwRshYth7+muH3XDy7p@}j#Kc8P&=V=<fut~gsClR`-CV3H49=^CU zwPqe8GbwQ@aWr|9e#%BN%AqbO`K9^g6AMeHc=}R#+Gr#&oD45vi5#=VxusKQ=1%2# zFnhW>Qi6>{1eQHYtNG=nrTqN*!txRiG8?+yKzrqd2x&CGyj)n|B28#FL+vp$t(AQ@ z#+73bcN7?OJbfYrVmHb`8wjTns=cf2QDmcfdU=g&3I_zsWmBnCbX>NYKbc?6ukx@M z+D+i5i+0SCbbOPZ4KeA!8Nuj~J+pFZb?!u7Sy)=j&!1V%E35g(&g9qD*Lcv6#?(ru z>Y26tssd7DiEC&j>uJL@)#QYj5@M2CGU~47RF4S@5ItiGkRU9t39^t*Dd{mK6Bp*d z?yo<g7Yl})%%mp7w3wa{VujP|(jwkWyP*rG^wNeE7anJ}4HzMSyrz~_+XyN|GAJu^ z>!)EbPA>D%A20az*~Ea`Ucj3Yf#?K&Sbb7iTVLf|ULrwaH7_l%=asn=C%7h7Fr%VG zW@UMmi#s!8*@<YTiZ@vmDZhSt`2-KkoXSHNB4CoW`PGG$b!BNz;#$q3!6Co;I7kg% z9BOK*2w?>xb$LgL5HFuZwk&}xMZ&DCF0U`oFE8@&2@2&Th{Y)BvbKD3{fW6%E{0jP zN*lT>q{UG&6A4bB#zV}Yseyp!q0gm<?!P!Xd2Fu-SVEfz2d-?VW}PGhl@KBT2@67m z(3m2^0B%P`_27DXxQNc?^x5r^?2({es(~l;dh*l*K30QX^v}b<51H;UdX5K9F|+&r z$MmsLbt0P+Jl-}MY~*tuV+Lz#JBQ)98owY)FrSYrs_rLabbz1iU;5$avA;*@5Buzw zbR0MwfpH^ce9#~O#tL;7ZP>;IjFW={ku1~4yR&FX?FP6FOK^MRy{vfFuN@ky>~I?h zSdGPop|!(?gZG!O1%=vc!KJ2d6))#={FcI)fa|?qu6nUgF2j>va_EC*f7_P6c5J*z zAO+%qn!1AVe}2^oe_-%57d+VDr>BD<cdAWSvo`C>juJslhf49D*-Re$aM|BIPIXqv z#}r1XXgNU-yh~wN8My065BkuS1DsTM6?(a2FeGgSG`-lYnED0X^l=>v(LgtY<nTZi z*}dO>jW&P{6QT#Y=CE^X7#9qe*mW&oH-nlipZ)ep;FPKmMhkH)e&sMuG(@nYL>p=@ zgoSmh3ihxPyjbC9wbg-ZB6?>6zC9~q#(AsQ6(|I2!j;;77W>P7`(16=7S354Pc8W6 z!o77>XQQYFS#2oStxD7IE4AgI%=a_SvJdPxTsY4@)UBcl2Q0e-23FGTGCV^P012Z6 z#88|q2W|sWkkCPyHVnK2z`)E9;^3n~OKd+>agRl^x@kp-V5SBlE_DdPk7My@5W%?x zw?J2T7BxzgNYJ1$kk2v=1(zm8E#dv$JjA;mOx&R^C~#A_rExMs^d{~wW~N%NG&#eK zqBC(*j9O=@d4@b<6Ss#E#w+q*6S7c0cTL=shE=%chlhfJiXNSbo8kkf8FZU36c+36 zn~9qu+ibu?Mw(7<?Zd!0IP61%+qo9DXbd0>FHpx7kQ#j9&CgyFH{67No<4cQ!_m>L z=zvCJYxFw6p}`d<8z~_it7(_GWHjDp7m0#Jt*#0RI<9%y9;w96g_QMdDwoSnj^#4h zDLt1dr%O2qGVf(CWR=pHDRFdSTpXPeCntOKjFoKLH1{o;%a!3L7f9pF6z(NsJOq25 zYlt!;0|S^rVwNqQ337G(Q1s>~1)ogh+YI!ex_`iDcW0Dry=H+?2`>5LItX$(7T`h# zEp9x+6rCT+HxjY4(>%CD<%jYyfu|#Q(6~CB>y&Jx;ZnOB4^ojZZpik>gTrow-QJkj zLx`7oBXf@Vc-WR}l`NBoIFUNXJbch*22Yi8Ey|HQ$Jl#+VE*7c)v`yMZ6y5ep$tYc z-oq%PVtP_ckH9f{xR2~%G-1>Gb47emQB1-A88MX>Q={TUFO6bv6Jpb;7$UPW^DrSg za1_H5*TE9Iu>6E~=L@|g(X&!Q0mlUgr;S!ZmL{Mfd4_%7^pbo#i<f+6{p3j2gAkQ< zk#?27bLZVn!`or@fTM>$&<{4IV$(HDc<ToOdKe9^2JS{3o~PzT8b|4Pvy5A4Z58}H za5WDdrgSDU^DQNC4UU`|U<3zSGnY;s-4>&T4)ad&P%g5a21N!9?H0Te%!5h9bZOeA zf<70%1085eh(=(d__+dc*=+~be<#x!a~b6h28Y>m+VKqXvrU|`XG5Qz;uJQT*S|Pb zt}k)Q(78^;sdD{@Q{_4mr^<CIPNNjFpl#}PUKJaU%S5txu}BdfIlsrfNwO_s55nuB zLEn2eoTmfP1$tLZ2wVVN#CsQ&2bp#yU~l`Mg9uExY~D%Y?bvRw=j{(7Fhlo69YkRI zt^l^h_2Z8YA~28nq&SGcJcz(_;1a!q2+V^BOkXA(L}2bsFQd`T2N9S&*U%k=x&)Vd z(r}xDP#3)C^dQs)u6V^Wr@35z199(Yi6|`?*Va=QWlvy^p*!FjJ9_{N?+ESQukww| z$pc8h1(<HR$>q?G&cg$E1m|gZ3@XuLf|~HP#p2pW2*Jy&JR}Gnzx6-FFb*IgOeKWT zv4oI@Gi?)@gfNc(vXhy~@o0{}*y<+#Dbpwp_9FsUWaGu-O_3N$!LZLWa91a!tLc`m z4kJyr^HDY(4IiO5l!tog24(lZ<AuiJqWbjK6KkgyysPK^qr!S7TgqgzUBegJ7C3tx zu8e=9JpsR0?F{^;_uqr0hU<bM@M#iK&eL1v&%<k3&*<>$if@%KS{he?weJ94qXDN2 z%R9QP6-UR)lij<_vsEa;)f3nDTJM8Par-|{aB!#h!JXbbA~YHo;d9_p@3xhKQJVYu zRX83GPo=<7Yp%^uyBm{jRxe%Zp~bN5?am8PqU;X_OI}e|B1HzCFXX!3e$lE_bPe7d z?Lo@D87A=oKLuV3*3oATm&d5C#dRnnGGyp$H#{N&?wx|?x*%M2973T?BO-+vjuz^+ zQNplom<aVNVjrf`Fjha>L9i&9t4bqcBS3a<%p{MjSeqD;J93;$U1V0It4bMo(WJ@4 zUA{Dna+F{nuU<E}(92L1*TOKgD?uvE<ga~d^Wmq&#?}KJL)uo#zix4FrD@DgvS*zr z2dV)lD!mwR-g9&Qb5j1_2(AnCkM>_L&pQS9&|Mh5!A)NT#0QV)y*@l#6`A2<2Xa^N zI!5FufiX<wKG){=ivq#jXM~J}`V!Be`Mdt$d<HzVXVuvG3>IZ`r2&IpubpISbS#-F zXIr=Zj_l^%<cLqR_+x<d!b2!LG>eQPfxl;0l!%mH@J(Z$zL&B(JpZGOY1#4ggjUir z#iClA8qH>lW8)L!CAeQ8LZ;?>i|-mz6>iPrWh$RB0Yt>20i07CI@ha)k$I>5&ec@7 z>I+Y)@vvS*uTA>6z?;rISVZTb@)2=h8wb~-DEM424@OM%M=|Z-o#iIiMr1Ui`{XYe ze1qa^rBu%pyGGf!>6mtwn&qdcSw4qmd3;RP8xZ?gV3q$YJQe-v&%m!Mw#utbzN5tc zUWUiSP8BB=Z%E}~tFcT(gIa~N^mr>N4-#;hNhzyoqa&$eMjaU+)u%>^<zjJUYI3Ta z&cd5?YATwyMZm)2Di;iRY=8$%-$yF?ANI*v3TG&5MYvUoPmhUClr_PZ#Y49%;qIcY za`831ksFDUqJx8w%Rvk0py4d^BNucLwq22+!lx%iqpR`iJD+;Pdm`z(tyc^*C8C&v z$9lQAFbbWu4G&If7ZE|=Koi(N9cR<BHD19R2`Wy>;=9lzsyT{siI+k1U`p<wLYo%B zc#Yd-gUBfr+iLO!uw9AlgsH#xST%}or_ks{l3wXNnhd<u#kXCJ%m7671DH>6p*EKy q6D=b2YA~KL)QTc%q6&_sXlTOBjBuF|wWq17JVRCGS@_*-ivJIh2u7^{ literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-59-23.cbd147d7-275d-49c8-bb62-f5710fa6b182 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-59-23.cbd147d7-275d-49c8-bb62-f5710fa6b182 new file mode 100644 index 0000000000000000000000000000000000000000..9084f72846fb5a89797938a7fc651461028eecf4 GIT binary patch literal 56669 zcmeHw`+pqAaVHYz$viIcIZkrETt+KXyO6Liya<2*V~_+Xcu9f=Kyew8nVa3|-5p?d zXXk|lr0`CTBIjXU>~rim@hg!}wtTtR{vmPVNS}-Ui+evl_c>9N{($@Ce!2Tr_ss0< z?(AYQ7>d-#fGA*hrn|bjy1Kf$s=E5c58N{+GUXqin3&L&17?{&QZD0j{)WvgJKt~* zw2IcM=dT}B8;aGuZW%kQ>ezX=<!Fx1)O?3krrQU3rQO!Gs^Vxy%g%3I&+lohW9L;? zQ(WE2Yb}-S=Ne8^H-EJJV*p<@RAzpltSwGVSj=vt63cZg&0(4J@)H*~E^Obrz9v!m zb9Y+HPh_*VwVITvJJR}^v^e?OPh{5DChwl37w4p9DkfER#kN;cEhD>QrzBlz)mKvK zDT&!trOj3@DZ0%jPxUpmol~k+)^?aGQw3M4Gs&=|G;5^?%BE9j3GFREahtVNt#%hp z-)Tu`ohd5+gwIXpC=$`hX3k2=b!yp#l>ZKOrB0`lYd6{&Q*%|LnXejvL=;o>EWS5c z%dxW+-Kg$nRio3=4Mnx{lGhNx6Npv4qa4^$&9JHr-E^4EiDCgMW?`Tt)~ahQMyPo| z8Men-l1Bd=OKCA@QhG|d(6EdqlP+0GGhB9)HH|$cIStL0K=A{^m0X*?GYO+d)Uxdm zLcG5X$7yGo>1ul`sdDzlYW9NBY=aRhI!j6DqJwU&q}JC~m|ACt4N1#zBn!aMt(<1d zpoOAKN=uc}Q&o=gN-@pHC~|~EuQ{Eht42lBne-g^ux(h5bV=I}5k=a`HQV_nFGH-# zi##Q%%ATfH&}PGMTYQYB3&jFwW-5`T4m(Oc3`k{rT9suxn(8!`q>XCTZ68QASJx%} zNHS`ie0J4h-Y__}RCO(kn1h~Z_`_#S7^c<&TYxFRyy(J;RLm7X6-Uupwxnv{6Pu<P z2Gn-IebmJBhS8+aH(ZAXu1&1mU|PN5NarMhqW3-A4#w8vjVKr_v~$30NzrwqV{@G8 zwd5EaI5AL{6Zycmz&k4`pL(IO<{e)N6J`q4LtR=yhk}X0<;c0i7$cavyg0Fd&n6+s zGdOFP^8&o+HRlZC*QGo}(_XGKlQXP(o&?BTzNuKdE_ecT&QaI6xQgy`sL3o94fXx- zehB6cff&R(pbgFVtu|A3`PkN^%Z5?c*_5OjtvhLlq(GfHG(-?MG+Qmnh76V5_EKn= zy$;uTUCz{y*-Zt!V+~AZF{YwumSAP~AXaLgWDoVT2Su$_)m@cIwsW8}yTKS(yvr=Q z*4o8r=_{%3`;^qMSZyUmxY-zus@mGIb5-4N)tatYjH9XSDEoO`tJwJ(#7I`@FdITE zKbt#~E99$o@8cZ!KZl2@yf1M_wR_kw-PpX6N!v6ttLdpUwN)_;$A$oH`wgWhBL?mv zH7*v}Y=FZo^>l0m8W3Go5)6>WKH-l>0Idmu0(wI{0!9wMA{&>S11z>FUOK;@<?RiQ z2C+WNI)+<qh$0>@91Ep(s~(Ax-@I5mb?M{Ep0ZW7w6-HDm^oP3Du&}2O{fa{qzllT z!rFnww52_7Nu7pPZD36$0cnTk)U(@HugpnIXMEAdf?8vW<5~=|)*<~U#Qu={)S7Ko z57$U~*>1<i3guyvoz5-fW;pNdM34Nr<-BMr+~rGR#6tKSM&<Ofhp-q+hwVH09S}`C zO>w155F($Kwi^uU!JcAioInz0E-4JER5{?Z6?`kxM3!j<z{1$7lEy>JN$6#6$CfgJ z*3dji@gW!tE74?5G<F!;t6N*^m#=+%D|4zd-4+dkQ)`;ll$%gmXgyq!wlnEfU`T3> zO@l=rIttcdNKh4n3DL<_AEQD_?r)?gr@GKo&89xe9nER<g1l*1B%gD+TyF&^XEL~{ z2|nXZpT3nn-OQd=2TD0u(j!Ysr=MLqeRb*d7FFRyWR_)E@?4=nAahsIpO(a*Nd`0z zi>Xr*CYORixqTZV7lf2f+jsBs!62m|Jt>`*h|3hKZm$GOD85Y5Fm@kdU6JX*<f#ZT z=Z`;Re2D3W4^a)8n4N>V!Yn6Km>S^n9juAg0hpj?3is41_SGVhOxjUPRjdJF*i&=5 zuO?<yP;pd?GlTU6$M)mtt$tt%N6CcN1phh5Cj7$N=-g=yr<hkn==?$*7i+971;m<? zLjA}S5xAxtAla2chqgllx||QTGRqZ1J@Cbds_pr^E1FtZp6v#-L=2_)oyE*(YM5fA z@Q<&@2{^Rficsa3^JvvafJFB-Wv`-G(#m*0-JUPElmL5tBpBjPR_DsG_l51ZvB}6b zA$0258kashuI*^G18mIr4klZLqRuQ|?ZMt^S@G7bJk%m@_sLtxR<O-dB{f^q*}l}t z&K0Dll~r8FNS%A|nQuRM<MsRB{^nbM{}=DP_|pAPzxMV^FW>*v_a40Y=kI*yRs6gE z`=49RD_+;Bm5PhysnyqlW7MGsS}AYA6=hP`zBmdNR(iLRsv5ekv~4J-;xT4C?Mj~% zUB0I5U9^lg?K4vl+nT~VY8g6hqIow4O9(14btP4!{j^t4S0JcYQro;)qOMlw8=4TQ z&<z^|j_!n~CP0v&NT}m^(W}st5GM*0fwSl%_L<&?PPSMmq$CYU4tApp3mCawqk$MU zl*eeHx^(E+V_*j66e$ieH0CC)ZNYX0`hiQkmD_ihPSJ)uco7HzdMbVfK+<FE<{;%V z9P;GyEWx5pGXH*i#)C=)M?qfJwGi>M9LvboycPxYVhDOv3ksI<y}>O#74?7Gu*&d$ z(}R8tdpHE|F{8Q@2@|xnJ5*cs;rD?Qcu(J*9MR^`en-M8jDXcMQ3-!+R>CYc$RmU{ z!_*PHK;QZrO^c<K-T+?2sHy&>?P(~Ac9LJzlL!ximc0VUZ_kqp4Fz_+w%cAwIhN}S zi+&L@xL$~^4-iI->`_JoGzkd|A32zCT5dn%Ma*U&4L+-Fx8hIi!Ffj|M~x!A?{ap4 z2LU{ENFrd%9x}JXTpm#l2FszG9#K318zyl?xpY6%Q<;$sjT8Z4b_bb4%Ra%SC*w>h zDj760YAhlV<u!-bTF$#<g{C&>X8;5QbQ+6$BTaI@t{WAsjhV^Aq<!!5<0~b!1T}T8 zD-2nRpz!u`@52!iPx@Mer%d>4d!)JDCE5_u(PNO0sFx#S<4~~}l*nO6XFD>Psf3Il zEluC~&TH>{_mcxdCeRs^XNU<y3K_3ERI+r1F3Fj!MM`Gxcv1aGgvKI7&-y^1;!2i2 ze&<^<&szh77Y#<fZ5gz6p*<P3L_dACM#-4IqS$)B_5Htm>y0-aeBqUMzxwr2KnKY^ zgkppd%|3WsT6HGVJnk5ln&t`;CL`w>SVkS}&TaU5xN}POHu7qh*`j*Z&%1Hy905Cu z*8N=w(L4geD7r@!2kqbf^54Au`M(#_;r@3&_3r1s5gvhvIuBLOKUB8WjXJy_;qLXZ z;wb9%6$RzqeeuQnzxReGNJ7KXS8{xMjh0wR@m(K!Q9K7iY4CI=G`ka|5V0f8Ym3!2 z@>0AXCv<>&h`v$N>}XmV&Ey}v`1aqtIY{j&;75|A1RzkNqM-G&X5=bH6~)*&@NMqB zzojyKu6><Id^G>yAMStoYmbjy9y+E0XY>h{K855^4gN4~n)qj=LLP2mIS+*yy1C#? z?%ll#zb4r+$1@dn4TS?8AM9sX>DzIe@Ech$%mtrd?sGLYC7hrusftqFty>5qP{~SV zSWD8AGcz-1$x?+c@O3!sEPAS{P)?R+3hn)~q`PE0@Gve_EVz8L^!=<*9>YzOK@yPw zaLxCcB$pdS-+TfUr;T8q>|E+x{;-Y(K7eijPsoPtS*gZ`Lde002;1Z_fcQ?LK@hM} z7x`Yy=K}xlVZHR&)MF9ohT|EMQL4)#yz+UhNiB>U{7If=I8-2HZwN+7u!YpbkZ}_$ zAG+?AU<|~^@DtD!2=j<#bfOqXhlM*^oc3EEXqyDL=Pet5H@n=Jj<z)P%^(l3P&fMC zL3;ueZyL9KHijb$o818{NksJ3$GZ5=H-2#cl`r1^yKlVp{V&~rjZEzC{QK{|_2%Ec z_5DA({}11J@cHlE|Mq9`@ZCTAx_FL~55D#3MHu8qTjPBNsjo#~-1ZSRbbr#1n8JiL z_UdDHC-wGM{z`ZQ-u~jZ?tkT5Z~fq<cYg3?&wKFMSAg<^Fa54S{K4zrefw*leEY@M z|M!c(lk(Q5L1aT_lyR{rU%iq6VQ;}nx~EYrh|1lFuBF4Lh*4S1__Bkw_HqdMYQV=^ zGp1x7+7bC~5<ih<@E$wQ5fQw}ef02!Asmro=*thF312dT67d|9mYn^xq2<_fEHd3L z_;sF1XC~8L7t&9X-<1Y#HIo)@wca?#)0uD>5B!RO^t1D)Gu>~KcCLMphUe8IiU2C; z#5Hq8Mf3{x-Q68{o3UNcn7e5MI)_?AP)fJ4^psES?!#x&)Fu%eKZ(;Ej(>_ZYa^<} z3vlC<h4WrPgc{#zD;C87!1>)#Y;>IB6UnJB0s|;&tUC^4l9wv=6E+lD8i&9m=*wG+ zqU=<<8_wzxI63-y6Rrwx8Dc-+fCLSRs@>I@J9!mVK}-n(DiFEA<GxyqsoZ@|>^frl zFXs*4ni*a&0xf2!J~OVWLhXkk6Guj=E4*Cb@ToX03IAu?7J`SYgOP^uzTOR)Kzxjb z32%P|BqV@t;2f(dQjI*Jb;P;k$MEI!p|YJx@tHhK40m@>y*sn6amlBH%|JJVHXNN2 zY+q?21Ox&)Bux$>#&}C?YNG|897CX#Xkl0{kK8veK+y|as2a`Gx$fuVL!;2W-LdtE zi$>L@pf2vi9>zaMMrs@i_t|KawkA^)4%uR52K`YVhRxW0TfM$6t%=ba2J5}(S>4jq zJQ-(s--cl_cCRi2+~d%#j<%~EyE8Wd<S3o-H$YsDh1_QY499eCDu*-%bC0jx55S>@ z`otcIcmR#oGK9<<0MoUC_5t&DY6BG_+C9IvdSiS2(k<vm-VqWJvUVgy2<}jWgHK)m zFYU9&+Kv&_2(LwesMuErUme5H5u22mB->f=)NU9Z*?Yyq1|nmnyj_zw_Cv@Wz>Eki z!<hncOb4;A2F$IY4XyXUi^}l7`763-@$j}my~}>E0~M6$)d>3bp;1NJ2i$iiwQ-Un ztFs!sXag+K*D0t@7Ywf+&BMOeY3Zpai}Q<T2fc571$|w*Wpr`}Oo^~$`0OAMr{BDP z6m--!I;7{G$HMJVjrSnZ5jaMNt_yHbo1=Qv)h9R(en6VPp5nAocOA|9i)ycg2kIfI z!NK%=55HYT96m9KH{ge%AGW#BexVyhe3<nm#DT|(o(|&Wa~0U(batfh>0`Al=pGK( z?+Z2c<{{~sqM@S^b%6F^xgm~k$O_Jt9pC_iEo+{$vyaik1GMTFK5T5b;cVOiB7W*? zlxsP`$qEGH255#xC!!v_c73EeBv9R-99{U{86@p_mU+Q{dnYZ<)JOpV?xdGqz&Vd9 z#dNQ$OLx)(w2r_o=wt-#BbTF8`ks%%y~(rUV_*ML{l^!n-4RQb7qkmgnm9MvkGJ__ z<)6UOOR;S?f4uyw__EA}l$2g|;ORiXC0nBa^Yl5%{E6~U<2@0Akty5!$+Gf+iHU9h zyOe1fIC^L?GD1@zvX0Y;w!`CIE|HNXb<`82b=@^u`8L|(XH8T^&$kcgw}{3k6ACE8 zcOb>WBAqCcWKxh7pf1ba4jgANS~v`)*K+(F1zE{*W|xNGp<}f;-$hC^ERa$(gyWak z0Vi!{mmN%=^1m%f>25$v`qZh5E<eMGcm@?6#c@7ycu=X(sZ4P|1&1eK7D5PU11oj# zNQD1m;aNI$>Y<Mjm>t|wg;^~$CeuYRCf%33_iUe4GgUh73vO=hX>gg)?kfI(ge)N= z4;uTta%P5)$}+4euFlTA7mQFW7Q37fW>3xuy;JQ}-&gae%0Gp9XSWc#-7p;Ur|+4k z#Odtz0gmFCKT~$_`uc&>fbVIBPQoooW6w04<i?!hRWogzzti@|uRLk~EI+x8U~*>u zT=`dk#g^NWwpd%5o{@@kOLL1$_<-}W3+B&rK~tl{#kTp6?wY@lxo7@jhF2#uq4~k` z1ymm!ZLyf<g@EYt7nsld#{wu$6`3C@p90YCYx9@HNppxM^TXx8{?UmE!G|l$#Ep`W zDmb$(_<~M@750n8MU~Aj6bn<rQp|-I4)%1dZ)5RX@mvqHue^|6O)p8ltmXaSr%Q9I zX_QQ_Ub`i4TpB2`r|24}ZCG~BE5QqU2c4+6Z?u;D(@(rWyM2L9KGl0m_)mEe3Rmn$ zh&CE%iC$5e^8*EFS;?IjFTI`DkTU*T4rk-yts%we4KK1eq`;<lePerj<JyoS;vJx1 zl<r}9pcDox>7%mNxIzU>s!iOpVx_=nM@m}&{6a|%Xu)5GVTvEK8M<PpCe2?KnHgYr zv&~<*XZ~uY^dHI}0iTmD0G%%+QYDy)uNf`2Wd4)Vf8_I%%Fs`^(2DfJJ@X@_|5Sd` z0}^_9J1xsJKV><67w5}FI*5N-`p@NDbXkhR^va@Ucjn=l`D>;B!UY+%?^p**=07X_ z*Rtfn;YbZx7|dTU{kQTj_zj9Pna^%-Utcn%(tj`iTnK_i;?#Vi^gjZEct<!lgY}6o zxl3lM^gqjMp_)(P05uO1WG$qJuwBZdAZ3h7&Bcj(hfQ)<5zgkr)r<54ec;R|T`pMk zmfJKxie6DZ3)OA5&C~bHr!wWA!Pknb>4-X{#m`LhvA{VVJjz082_`MQJ!cBx&R0lt zvaF)=dm*39r#YUX!8e~NH-2Pd;zU$M$?5Zniz;)<b?=$kOyh$OH{D9E@gY7B{dLaF zH$Gg(S~!uJGz$$#lwzjzv0%Q@#H1hEWth{Y)$%Qr<WKOcU*h@u7x6x9DDa<zoX+%U zU_&xfI$!?TPz$`-+0un_!FxEW$pL6{rHg^c;gIG_Yh@&uA)TN{RCf_SBpS&)Q@T|C zWk4X)DH*K$?55^I>2f)RSwp=W(Mr!zvmee_e{-?)Z21?xVFfvPY&MViH<wE5<tgt? z1R;Zx;n;ukZ0X~CgGv>+E!kWym4byT0!-Qqne5wCn=7R&gFJYybhZ4FhtlwIrB?c_ zX`U(2v;FzUCitnNcxMC5-zZ%hLb#8WHp(}L6V5a55SHSn>t+n_qJ8QxXREndx?Y|e z4!_S|)pusVJYV`m`RU=cBcia)3#HBS<nSsm@b;Y{FfW$2%FDxRj1`q_uDOkmmew0s zzAr&0UnZHn1(-)wBF8Xbn9o8SlY$VkT$t;S$oKFpLw1Xm<xQg_y^z*aD7@3q!%4}) z$Micdy$XrPPiFX!*02f3GfF%FCWWhzq#lJJ$uKfd9jYJ#kuC1dgdvbWz6X7IcO`6k zm^435i$N(<+M(=U6XuoDZu!^nfj9^5fv~BC;|TzhOXk&*-ZOc)rgyE>EI;K{6^uv1 zahPSs+$gnrwN;_>1tt>nddcX~90?}Z{iNQ#v-ycqyK$vta*0ia1m0En1YiRq;sWE% zlGW3ihZu-1N|;+EyK#jW!XSp&F8>mG;;D0e&D{`+-4F|!`JC-CuDmnKq+#AH|2!b| zfhhBhGQ&>KW#+BM6)w^OqmKET_srWF{!Esu3MQB=n|HXrNs7LC*MCK)&++QFMk6G9 zoX6dD`wlAn^YVv*lTYbPFGDC^aU{l2xQWfIl+U0zWjSjYB2u*t8x&Okpa^nv)%r%o z+i0INt9)@rVOWmPw#u~-Y(`l5Cjph7!;ELv%G1<Fpe>8Wz<&Jo2=H|uj8O%c2Jczd ztjV?g8b#yg(x%3#F3ZeB$sN()V5jKqsQ&D7djob%JjDkf>0DSwpzfC#fqm0M3CEaZ zvo#DQdOHdwgDY}@Y~co7z-x0688L32_0%gj3bN_rM?+@~#Sd>sL9sm+z|r6a;5g;k zXnqp!M?rEuNMzCnq`hH~#QRZ@I(%`Jd3qW;1k0y0K<*D?L=LiBklSc6!2>=&@JL1b zX!H4Dq~g2m5e)Hy4~4q-+e4uoLhySYlosLgFNQ&(x1&h(FTJVNVjX~av7CvXq5Sm# zIX>x46WFHRDxvW^!={N}VgyxQ;syY+HE>{TAMk#+ybz5~sL%+IFMFJ1u{Oz{PYvTF z@qQGUe$Nw_ScyG>`TN5JW>91lyg%Set1P21`OAoQe<%PBO2=-Q5ncVXHxxEJU`7q# zUKutNeu)vl{*}iRa0LL;AC+gKr!s#%s+XVfWR^dp8VJ?`z|WS8(WBa1ju52fHJE+> zy8I#31JT?zEZkTYyQ|&j_-f2kftr8pF;d{)LX)2_e~_9C9tAMJz?WPK6*d3F-#dSi zFXucNR8YbEQ@-6CSOI!VjiBkDxqQCzte3X=rF-U=h0&aJ7xOFS8lm@|sE6iP%h=UU z?3!QWJQ!9C%s+Se$a_%|=3i91_Uuy#8JFEwTdVHs?3DTH`7hp?nD}3x!!L@DIJfLj zjv)N8@W1NE%=6rS9iFRlsbc8rS-3giwMP0&*uU$oCC6yv6bxm*LNZ4+Tr;xZl3(f^ zZ<7zVuuX^;dER;)47yGLzX`t!;~=tiJsB*(g>jnqX`lDTfCqUTlOk13je`p5u8Gj1 zs#EsVI4BgS;W)#8#boe6K$JN26bBbC_$nbxj9rZ#i$UT{P8)(2eraqkWgh<=hYZ1x zWM}5)7p5!fY?dunYuVZ2%yd>MGL|hWh1vO;8K$r^%xC8~*doA~T+nflOk|K$gARi| zvgVP3N5jha$l9mqG^3>-JTe5D%6=9hCXcLrIw|$Y8ppu`q=|fF&10n`Ns&nVNiJm} z31+wBVAmC2#p?W-g1T79o>{2QWoK(MEL)kItz^|oO{vV(6s1s@KM`NC)vy!sbt1mv zOwdG@?)QQC>M$J&PAm!Em0{Jn`NiVGVl7)hL{xTmraF^dm|w)Fh05IGY_WExGFv&3 zVJ9*y?q2#t1&cL7-#0QWN!1K7O0neqF^o+VZziu^xUhD8J5JL)XFf$sPKDwM^ZWGV znf?B!P5rF7Qphb%J)M7=e_BXnltW#R*REaIxVV1pa-6=@pV!*BZ-gOTw*#K#W;||& zi!J=Zm|a=DcKOEY<+V7NJ>SSyv5`m$qYE3?uB~0zUf;MD2bo>Q+GMZXOOQqvHa1G@ zu}Blz&2W3nN_S-+$GCD9Cny4gj;BwAK#Zdt^nkG2q1t0@j}jZzXE(NDP2qrGOACcU zAvrF)asBe<>cusA{o2;rg&Uh|^5)tnZmex>Z^dD{WUQBbKHk_`+mta8uf?L)RpWUL z`PcJvxTh*}RjJ~pF~e@0mDX`CSeNiX+SroHQn4TxXXN=wX%(h)c9T^~nv<U|%;k!? z;+&Kz(WNSM!e^IBmsxe!n3SFq=7M~28j!b?8WPn96%rYg>#N((VlXak#Gya#xl05I zaKPp*d24$!ri@MmiOsdE8{2F0>cxwjacB`tm?V+8zOfmLALnOhX6F+^gilZT>e}|R z8yDjc=JFc4kia6fbzyV;`nG&+^=hmoAsHOjHlKr>h>Js0sZuJA9QSV~iBMcVNldmw zdJ<u-Z*FXFT-dl0hfhch=OGA_q|4UErR|%mo3R*X6W37UQn_MoI+x5;f-a0$DIIB` zV)-6kc<Rah=`&}K8k8B*z;V==(ro1gpedvSI5t2}IZ6^F?oJhm-AjZM!u>~lDBU_4 zhdYl*_C!#xHsMZuoZQ{O$7u5;;&Dj$l<u5;jsiWA&5NHkEYubj3yXz?CCTG$tu01= z$z#o6P3`4ax{1^;ND|EF<hsKA$K+!7ANxVU{yXvaY5pTV`z38#m#Y+f!S8zvfQdqb zMUks(kHV4=Y%E^-cn=n>Dp7!Yu!QfJ&Yn?hb1yW0MI^Iedd;;pwHG#0SRY;sg?ek@ z;Fg0Ng}7bUZz+rkM8v4K%KnJANYw;9`Sk=oXz{ma>FdSD3#5^82b#-dioEix&iMmF z7sTP%zW<z#r;5*Z!*%EiC%LagP}Am8eCTT-kA1k}?-8fEsN^Gr-d7Ae=mC$u@!#Q! zU>5YD=M6Zi<;aXu4+KNfQ$S@E7nfS?G2O>?CPV|K2am%8SrJE_{Te+0kseoTMZVFR zG{0oJcu|i=#&Uz20)qJMchjym5S@q&xIXwWPCOKBphOR9bft4tRb0ea#p!wfRZkt; zs11J!e1}$~7du8J5-1|)aEjP}CH{)vepkI4A}k8d_REEP>nQdv(i-`%dQff|bytgg zLo(lgaa(*4zwi3(ws6Tx3mK68QaymdO3bPuZAAbij1q_;+Xu)h-;{~aL75&9e3Yul zxnLnqpr?_0Pt~2XiL7pF1%aL1$`VT*LcnKcG8sf@ZsDYBJ<g)W$(9HjJc{srrlHW% zB#S%b;}Gw0uoH*6AmcQ&LFvfj^d)&aaTqfl7reMJV|J3W6LX9p6<fF*Hf9h@!ggX0 zBMSP9GiV_*?+>q?nA5O<WJYl)7^vvU*@-zmZo6*b8d97}5dm8`@xbqmkF{1LV^a`# zQ8H3Y#CW^N_phB;v*jJ0I42I1B)3QcjrPIxV}L_DR`_P3gs=_Qs>Tv~+qjQ15uJq_ zGG&q-vF2rO1dTYa5D1hZ2#QimOEvr~jaRs5?>Q1I(qrbP=Vo)$i@7srMwYCxg~HO( z!kL++`GrNcG+!%Lmk^^p%u?uMJt&Eij1&m2Ac!+Tl5*zotITCekQPso8bWsesL6Pz zWh~Z2qD}<kt5zIZ9L86%kfCjL9AuJn=J=Ktan?5uE=f6ad`yt;FAf?>@v6u?%FR`A z&`5+;LngC0IE*9Qj>fJYLUGwOF`tr;hh;bhE{%#qoJ4&}9zJAh>cEc>2cN`!N+L5L ztOoH;R2<RNnFzmoD8sfC_aMY{u6QO_%;HQiPE$TZmS22qwsVwvF;~F9`COrxD@^C+ zhAqcOn-CqluH}SrHqM}v-$T}n+%^oD>l-(5zZqqXAUpqxXWT;p+ks!uBIBBPMwg%X z?>pWj-#p<}yRm&KyWl}c$|%RX%2VLcJ#4@;Zihuu5P=;5MY7GD>u7rJ5_}vU4IT#W zS_@b5#6_A$>AYL3Q3CT#xJUe9D$XZn_2dL@x=4-(+c8YEvGnHTwh>))gi|LD<r3RX zaAe3nZM5R;YZ9glF8Y$mRT1wn0htSu5tt-?jv+21cUeO)6Z@3Gc)uifDKyNUuPY9_ zz2C&C$SC^$6sIu1J^tcUe!Rq~K<6<Lr}E<?PUXi)oXU@>I89Q_Lfd4mxGFXs)flow z98Gr?0TyxO{1Nviy%$p=h%6cO5jqgp)y40eO9YF$4u3y%5#}JL^6}E2#K{+djlfCZ zB3zz!-fcOWgIiYfUPk_Ka3O3`CxMG1SJ6q}qMu$zY;patos+=Dvpy+K0vAsL7wyJL z;NnT(q8$Wkp9C%*O}FMj!6$)>aa7uqaF!skBoC=M31^`kn<wEck5xF!qxBRfX^X)e zBX__fcJ=@Z@8s#x)5s>~<N*>$zUb84SPuQ<JUqZ7IEE6(Je4daqzOM-EFOJK5U!h! zLjt;wkzxRH{)Y_30Zd7_jdL1TUlwr`Y|i_9W*WIvXOcNJVkw>YhclBn4^Idj%f?Hm zf)X)L!muA_;F1dBa-HhKVVyI*oHJ8QhI7dO8HZlv_!OzeDSdA4it_xy&8^GpUY2(M z{!XQ^Ft^ASA_EqBmNfJ0FPr~n(|nDm|A$ECH-wqrXuNt}`t^y4|ML<2I(E`>y5BKw zS1A}{i${^JZ}jzXv3iD0FGTk-&TgQJqzsQXYxGIZ)q2Ajk^TN8W%NnP=s1ET886@u zLC)x&r9n_Sc7i(`9M_t-STA0llc;c|7hV{msEBx_dxNP$lI#z~L&n;=MRkSTgmjyY zR?Y9&`5k^*BDVwZktvcy|3Y=Dww=e-AgrY-Rt{grt%tUPYU8(tT4EC(g<+y3#tm+< za>750jgukWG%OugaYT~vXf{>4s!Z0E3L|$r(#6pA<8cH}V#wIefgUT?9GRwYZ4#n* zXA#Av<1XezP{PSahFcdY;v5samDsd+dH}m5*{g0C$etl9xXt<iGtb6F9dQOVu^m%` z2Nx$myrVI9IeXpcP;hhhd@QwG$byGDQn;AJjWaY+qBiQ;yWjkicVGS9Ko`WWK}g#X zrmn6y_Aaf-j|%b;rF|@h@$<0fVU&Cr;b#v%^X&(3y#C+|ue|%!uaE4{C`(nhLtZkY ze1qps?~|l)aSY#9``F_6=9~Bb@YTngj&FbFvv0le+M~sBG!Gn25W(1}9DkM{txdW{ zJKkD;3kR*GYdEhXkqPF&a6iWOao$L0Ib1XlX=sUKgix6{jTkerh9bd=p-Z@fQbJVP zkjZv5it)8Rt^#zERi@hq68=b+EYJ?uGVdmW6|$|-70<C2Pa40b((W@SDTOn$HMI~q zl8JIXPpKt421R8bpZ$gG{;fNmXYS<M2Ok|mT(6YBULCD8U)}OU>m*5>Hj)T<N21~$ z9QSYb^Z)iOVsR#=pCIOOxoI!Jhg&Rhw`Y@I@=15k@$7JMxGFKNwhy^uTvU`eO7IOS zv5$HC{o+8#Qkx)Sk!>N)p!uhug5!!x3pUd5snX-d&wIVL^M&b|JW_Qc2f24=WOkes z_6Z;E^v8hcMMr1j&@3^E9E}o*@(bMz9;ffs1%{j0)ERYQwm7F&)%i+AsVu^YQkj{Z zo2??HPJ&DwZ+HC&sfygIahb|zOn^vOG$2-Em&LMEjM%{*O#}2h*Hn-&k`9E&VZDSd z3Gi`&h8qWqQM=%HM6qESL?$qquHTM>kr4e!OuL5BfmUhgNHrP<kpxKt!?qhsGoMcA zl94?v9((xuG1qu=k;mV9v|aO?FPpD#n&0AAfqSfJ{#!WD|KBM%&;Kue9ou<M8`e0( z*=sC18gFx*4bF*pH<ZrICp3x;WVNBR+Hty%oLtofRh`ZjD)UNqcA70_E44}`yLe`? zR$Rc%q==A6WVM6K!jbnhTZ@%%!jD#Zufvv*&7fI94#RjVRC1!iMLL~0!+RX=t}rFm zz8g2CC&DodfjhB6rI3*XSxG*&$1P5Ypb}3-OGZtMt7^UT(yNK|-C}i(JYyv0VtRs- z$0Me+O9&AhErv_aw#l*<SMVl+id{A0rPfMnj*?u8%b;uUj1EwtM{N)iFLq=FAt%=@ z!;Ke8ejM3}sekmSagOhx&=^LNVb9}O?r>jYyq$7lwkNJ1U_RkSh**kDvWW0NlQ?6j gR&u0?$~2ZaO_f$wq(es3{L7ckf46D=mFwpIKOW968vp<R literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-59-23.e413e2b4-dab0-46b3-b1bc-6ab7fd342cdc b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.15-59-23.e413e2b4-dab0-46b3-b1bc-6ab7fd342cdc new file mode 100644 index 0000000000000000000000000000000000000000..41f31e8d79a5b6c5de19351db4b1183649d4b156 GIT binary patch literal 56669 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 bvCL^zX=Oz^WJJxseA)bWo917+ZtnjB<EJm< literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-01-15.0cd2182e-7b39-417a-84a8-250066cf9933 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-01-15.0cd2182e-7b39-417a-84a8-250066cf9933 new file mode 100644 index 0000000000000000000000000000000000000000..a30d463426602f5d9b6fb63f2dec07a19c538df9 GIT binary patch literal 39573 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 XQ(9h@9?_!sZ{Nm$SHXWDhVuUdjNp{Y literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-01-55.64367cde-c27f-4b2a-bda0-a84ef1b4d4bd b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-01-55.64367cde-c27f-4b2a-bda0-a84ef1b4d4bd new file mode 100644 index 0000000000000000000000000000000000000000..6501da40650b60e2a1df779eeb24b763fab53958 GIT binary patch literal 45592 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 Vphfv7iRtmX#Ps;x`0R9|{{#EI|7`#O literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-02-09.5dce232c-a705-443a-b8b5-58d38143b62b b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-02-09.5dce232c-a705-443a-b8b5-58d38143b62b new file mode 100644 index 0000000000000000000000000000000000000000..f1f773aa37ec12b45029df719e01c13f1546596b GIT binary patch literal 46066 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 I>~!LP0S5G?1ONa4 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-02-36.a04ceeb1-5428-4d88-b3e6-0249fd5788c4 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-02-36.a04ceeb1-5428-4d88-b3e6-0249fd5788c4 new file mode 100644 index 0000000000000000000000000000000000000000..e44cb0fb665c6b046094fc7690a5f2590182bf8d GIT binary patch literal 39555 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 Vr6u73EsFo<4g9ye`0s*1{C@&Jk^}$% literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-04-41.7845f5bf-3033-4ccd-8e10-6b6ec04f9eff b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-04-41.7845f5bf-3033-4ccd-8e10-6b6ec04f9eff new file mode 100644 index 0000000000000000000000000000000000000000..14996b030df78eed355993e377f5dbb767fce5a3 GIT binary patch literal 54894 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-05-40.b7856e30-d3cd-43a1-bcf7-e6a4d3896509 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-05-40.b7856e30-d3cd-43a1-bcf7-e6a4d3896509 new file mode 100644 index 0000000000000000000000000000000000000000..9b4956ed2ccaa00ac70f95d02be764e1c33034e3 GIT binary patch literal 56501 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-05-40.e2f6d53f-6653-4115-810c-e3f4420d4879 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-05-40.e2f6d53f-6653-4115-810c-e3f4420d4879 new file mode 100644 index 0000000000000000000000000000000000000000..5766ec6f9dd9eaefb7faef4a066f321c231380be GIT binary patch literal 56504 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-05-57.6f691dd5-7b64-4b52-aec9-2e810baea65e b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-05-57.6f691dd5-7b64-4b52-aec9-2e810baea65e new file mode 100644 index 0000000000000000000000000000000000000000..228c4cca7a899b7494a409b5849b34a25d172972 GIT binary patch literal 56666 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-25-42.13ccbdf1-f384-4c6f-9aea-a4faf099756b b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-25-42.13ccbdf1-f384-4c6f-9aea-a4faf099756b new file mode 100644 index 0000000000000000000000000000000000000000..42e2bf9e893f0c80c5afe3238b24220d21818c3e GIT binary patch literal 61699 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-26-10.47595aed-16ca-4978-96c5-ae56ae864a4b b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-26-10.47595aed-16ca-4978-96c5-ae56ae864a4b new file mode 100644 index 0000000000000000000000000000000000000000..81b122a0c4c6f7ab7dca4fe6fdd8bc651c1fb086 GIT binary patch literal 61698 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-48-18.80a55e8c-2eb7-4457-85eb-3a997bc501fa b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-48-18.80a55e8c-2eb7-4457-85eb-3a997bc501fa new file mode 100644 index 0000000000000000000000000000000000000000..71d67e580db039e42973456af9fa1690d3fcfb16 GIT binary patch literal 42512 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 V2M6xHmZN|FH2sHl`j26#{y(t?T?_yK literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-59-05.36baa7de-e574-4590-bb7f-c26ebf50e515 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.16-59-05.36baa7de-e574-4590-bb7f-c26ebf50e515 new file mode 100644 index 0000000000000000000000000000000000000000..b06b09cf616c50e5f5b143ecd5d97ec306df9e5c GIT binary patch literal 60433 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.17-03-27.189a68a0-fc12-4f03-9cb7-e1029c150c54 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.17-03-27.189a68a0-fc12-4f03-9cb7-e1029c150c54 new file mode 100644 index 0000000000000000000000000000000000000000..66a7638c724bc9bd43bcb81164e4bd0cbfec523f GIT binary patch literal 56445 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 IXWOa&4<AH+S^xk5 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.17-05-50.b676e5f7-60ef-4992-b0b7-fb392b0fab28 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.17-05-50.b676e5f7-60ef-4992-b0b7-fb392b0fab28 new file mode 100644 index 0000000000000000000000000000000000000000..a8d081b2fd7d4fe12c61f26e578db8644c0f1778 GIT binary patch literal 46283 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 Q(f_@T{@()quJ5P*A65cFlK=n! literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.17-10-03.b76dcefe-bb84-428b-bd3b-928234f99a7e b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.17-10-03.b76dcefe-bb84-428b-bd3b-928234f99a7e new file mode 100644 index 0000000000000000000000000000000000000000..c50eb33dccc4ec6f920108b26812958caed4da6c GIT binary patch literal 42885 zcmeG_X?PpQbyV&shZ4te&Zb++F#wrZ93(*!JYtHXWCjAs@UYial<i`70Ia#dV)hV8 zsce%rPTkb0-6Lt6Hm&X0xtiEb+cb$C_rB8m`g$K<zfX>xU;WkpeQ)+4KmrUo99eQh z+9JT6w{PCOdGqGYn>TMh_|h%fmsDQf*Vkuho5Z2Vl)K=2X4NH*o2mPoX2opQGK-sf zU2__Xj(soDJvZYwJ=3#@ky$5|d}}kKwOW>`Yo2L0-OTc0Mz@=uV_Oy?F-TSOEl+N3 z(w8VN1LV4G5c*Q(0r)zB-zB?(Sfz=EZTJ?Mk~B}sZsc+W-54G=vIA1pw20JyZD{Hr zkSw!Fq|qt*GUXLOlI?pf-=i;ArWt*f=DJd1WwS+Q9mjSOQ<APVCA(>DO3+AXGHJp; z$@Ls5*|a^WziQc<*PoI+8z0hFD6a-Qo}=lcqUme&mCEQ#`}$U*zolfuc0I`<I%#@< z+Oj05(MuJNOVU}cX4fp=Ze|<;m7BUp4B&gz#(ZvUKr)+9TT}?OND|o~dQ!)p7?4Qw zlIhsZ22hjYCSiZl5K%P(Jq$!ez0X~1(D0gNS2W9QYxPh*7gS(rjf$a7u{OKJs>&+z zn>f-W@EnVzYEh~t`P&^(;MsOZ{ez>0JR_jWYIca{J55Q`aj+y$X#>)!Qx*O?560`^ z5k^U4vu-yCBgbr3Z56uP2QI9hPxe3m#ADAt`JrbY`q=+`<CFcjYra>Peb5E$S5s?{ zf&S;7{>HNp-T(ZPAHMqZSD(HABMc5fR754ay6phax4!u3)vrJF{FiqYSBTb39gl}o z@nECrIDM7!Di}^~Q){_(+oP}EqQ?X6)!MuS+Uqrn2gQq<Ufpg=gYt-+ElT^=8=&bj zt>D#U%OO>BWB)Iw=xdp7Ge8;8*C}rWDwh4Gv`ku3eo)Gd6m!{Pc1X%+bEEY2OwUvu z;HFDYT%>PEZqYX;+3Tq3=uOHDyuNR;LlxX*+|xG&Nd2ZxZ&r>2((RE?-yG;-7y<Ma z<%yT{^#v+m@}MeNmgRk_|7gIEPIc&+$t#KJL{Xa1169k~A=kZzB~K>+GBG`WkGgPn z7sMsaGJ)H+<H{if172R9J2(H{WdyH6yK#_7)8Rt~&}z-t&8k`JgovIp5D@xZ)diz^ z8jBF-^ezBK@#&y&c6xPX?(981V4_lnXW>jQFf3spOFi%`1;wi?D+}{IK!P&B0=={a zGaXLxlZk_h*8X%%VnBkyZ;%&6f>QJ?fzbkUw@cr;Mc<Yz{iE^@5OJK*%xe2YCYi1@ zZ#PMizP<EMY-l13{<O_@p#H9G(RY;oSveUZX)C;tP*oh7s+zdSW(%~G-dXw=MeYuZ ziZX<SH@62JJfq)J`d6mIuzt_kEYf$C{!NiWJdCIw(=q+t(!VQjh$`IBNz0S&Tv=Hx zQmOPG%In%NIGX7a`hBJUj2S`#@TGX-XU0sC_Lu%knQeRXq-59<nlS`So0jWaXxk+1 zO4WDK)B&re4(6I;*3716NjuQdlRncaR?~0LTcK5G>=}NeMc=(eZ%Zn#fj=w0X?f6R z&_<eIeKElvrNIJ-$19dj(Lk>=yM(3`173b1R1-bL=xpnJdb?6T*4KBWrMju;)55hB z9q|1vnoiblx|S;uxqdSng^|@sGxb{(m<0QhDVnW=KFK9Z;|l!UNAsnLdcHKNOu-)~ zr8NA6#v3#7i34_r<hQ`;H;4fyKP-ZDTpGZ_z>|^=p}y%5BZV*0!P1m+0?^!{YkHl? zp$(X#L#6ky=de_Q0l3~oWXV*K4wvpwUJ3B17W(`9X`wW&B*VX9;<ne_7#vn<l3m>< z1l5&GM@pxaT=+uW^IFAB24(^|a{*NP#Z0&|%S2UXF5p|Jye`tw(o9FyW2G}nD#R3; zu%Opku-+qb^ge4XsF(rCsHAAouisiaTZgef4jnpy9eM{KIOycF)2yeHQP+j`Je`8B zD+1<Zb+T>FN6R(jzAH~yHrV>^lxz^NPtj`FepH=G(f44N-;pdod`vkLHWGQxRtZ(G zOX{HY6A642{hXA*<~5|sCR2$aC#6d!S;tux7Ljzi{Kzq7awoP1@iaiT3?yhZl1v5o zwy_1)oT}ZcZ7?H<o-RMyg{aVCzi=_4hkb6NK|S4#sG0JoyAZ{M1*qyow~cKVQD@4J z9aG-6vu)}n&2a$@PPTNm{P;2D)?Faomt6F0`7_6qckhBmeyVM{I6{7|{Mlnl|1NOd zcRjnI>UN`HdJ*iM<<E5`B!ERP1uo1Z=(+OeyAV<%O#;hlwWWC;ahll33yD*Si}bx9 z<j_!*@={>Jqs-9rY}M~Kp$lNLGiX_X8KkdD=am9{@<}OOK*hL-;|Ns|-#CgEr}TaG zo9pv1a8Mn=Ds(cLVhhp9D_beLgri|OS$^Y*jt*=WH5e2%U;^kl!$cdKu9R;&p}Z52 zwL{@|u*J}zz!!>iwfv?N%DFC32&wyy14>hNiR%JNIU0Cu6vA4`g#qJ&($wLrYLKQ0 zjJ>OT^9g032f|QKp~$JW19q4Js#y1u^zQPTPcSB8wcUPLl`iqXRH?bL-Bha@XhuWD z^)Q$}mzk$4MV0a`CzRW|)ZTrOPwy$eWj8$dAymWGRTcOd%m~o~`u*j%o`@BGL?^-r z24?#U!4rC+{I(OZRoecB0nQ**mHig3P?OvBu*WI-{_@*TC^zqDN!W@iy@*nN%L$b7 z4<y;@H9$aB<&E&pwmb)pg(><2Ox`uBMRRI}J*ZHfJpfDFKw&1=c$TliRDnLdfGk?u zp5yB%;%2fm#0+N`rcwZdv+lj6;dmAR=`|`zqats6IPe>CTbhLa!dV6%uwVEzCF?eL zM?tYeakfa;N(E)CjjtW3Oqe|#FBxH+?1FBbTBQ-NKSq`L5KBzS<UuI|sYdZn$yL*F z;gdE>W6DN|_IfyiXtPv|RZJ*tD5%Mpn92BCirS@dV1zJZtcCW;7|Jv(HPA^LS4EwA znLP=diQpHbuJRUu=;EVTJ)fAO9$Pbn(AbI8XS3r(;LO<e9fYp#DSC<FkNcahD|N)b zWUotC5~cymd2m`LP@v#z;_5RGKl}JIu)t14qJmFnVMa;}fH{`{ON@9hIl1n-?HKAB z*~D^$cSy|yXD`!ND#M#dY)#P(<tC^uu0EDty2-{%fSO(oX0gb(N3SrQxs%A<BuNS8 z1q2$hGB|e===2NzfU19xO*yd;2M$BJrGQtw55VaUDX)ib+vWH&{o%OygT7DL%Aa`P zlcyhIB*y+k`Xh{f0?r|y&>vOOfa+lW`VTXN!Fn0zwfnZ{M*{Is!CeewsVe<3wz6eb z&ixD=iqLrlML({*395|bB&G{w<fBYR01}r58=#BnPi&)kAS^TpthhY~3O}ag5fPY+ zb=yd<J7BQGIs?23F-QXK{kVo$vVM}SYXFXEcKTr5V0Jt{K)eqzo@_6=g9@auxI4<9 ziZI|TMSog(7f_a%10QV5v0ILbJ_60D`M7ByVXw#u`ZKH_RFzP8<7b09cee#gdo<(Y z%wGv^7u#uQ$gNK(S!77;Er<z^AiC53b0Hx$?6{xrMF^JmAmkUA&qY;hV7Noqm=)hc zRG(Bvy7x~fTo0tb7*T~S`=y>#L1_;Jp9*`q4r>!Y@ykl4J2gRh4<x@5A~BmL((!OF zBtdx(B#$r?Kn3qVAaVUlG!h;S1bBCU?Eu7XL!pTU_|qY8(A`EK>%|-9jO*Uzk4Ffw zQJ?9Fpf__r8zN{T1)uAM084xD<n!TxX~OD7rC(qsTo=h@#k<=7tD)qBx$5gk!54c; zegx5-4PRoW4Z0s09<l+bo=^t6527}p?%19TWyK*aR3pFEOICvN9(?(7sODg{3f0`N z_fm5)NDoxMp}ZDaqN)IgJ{RQEZ}yV7ZJ6$D`%1`h*St*ZDq#ApUL21gy5sq3*zGXk z0+O#WJG_eqXT?35_4QEOL<6aA+iQU9DdxrLB0`;TNLI&KdYakvz$G7aH7=XBXP<Ad zS@bM;MF@Q+6qR_J8mjzlW+F_)kK*z9J8aqlh40eeWgJf?4m8Ck22%9**d)JhdUZ9f zfd0NR)J-@$p}KSa4}3Oc11}H#!!7zpJ4}~97Gb*liOV_|y-MKaqJOGy?^PXF%I8(T z*)sJtiyWulJe~YNU*CV9gkKYed1-3G(<%_z0NjLs=q22=$Yg&NOo8+|F>7_NSg|c* z99)UuJ=Cl;>}}PWMbB=H_fMfKXd>eo?QeDkEJjdMtWMUo6B$-Ldp*Ny=b>Obx+AJ0 zYQla9SzZ)F1xOrE^%3tgVIPR#h;AA@q@c+tgcrJHg0aOzLM{)R;_zQi3>|Tt4-YM& zgHjMB_L@l!B_KS5GxSx#(n{5ghS}s{L)<0l!QsMazG4ie$(UYE59J2)X)Q-cI;Ula z3WI}0BO@ddXC7+NG0G`7LORK?8yX*vgj7#9THpZWlMxYG19xCBa*RhvgfO6?ZKT18 zdfn;=_j&!gRqhgSFkip6!%T@@Z6VDUIhD0(Ft^1+U7PyKja2lZf|fQa`e1rU1NAiq zN-Ir9E5n1;Y+fU|u_N`xZH67GuOs!vGeCt*9WMg)wN5NBaJV%5whkM~4i04@JR_ac zL6Hq<WGp?FuNKldGFGV+^7=@=aAbmk6yh?HV<~y0!;W;=|7#s4(lmp>7cO2M!r6oY zrRwy|%<SR{Pt~}ymBC2pfwq|8%mzNWePid-hBZznv+~%$smv+%ZB)oi)z$=cc7A5z z%-sArp0?C3n=OcBBM^q-iSgRBQ+9rO{@m*Hxmg~{F4xmKEF=VY_83Jo3-j}{Gb?io z^E||?5z<0`<t2eUnps#V&2h1&V>L6mJ*^M!V`(xD@qR4wDE8*GBiM&)rUOA}jkKZI zmuVraSMOX{<{H8=&x)hjY*w6<EzO>tU7B6u5wS3GwUaVDW*9mUGbRMufsb6&fLL8T zw={ibR-Kz)o}F1;npKx(-?uuuyt2$gyckC-8>p+xvr8)IjCrn(E!&q(%hEE#a#l)~ zHQj7_wp$;U<{%!ylHh@~uq-K3F01AS)j~>|2CqN4n^a1smnme2<(!-wmXf7ASIXz{ z%;Xx8&JlghPDytKo{dZ{515y=s^*yS3qm?&aeC!W=!~-qJp6B$lOV=R2u&amOZTYD zD@&ZSix47~X3GmJv+DGjGhE{;9#A5QSzK7+63;?5KQ<(Y5H?!X^6bi;3uky_=G-ha zL4Y<{o>`h(Tv6wz%UqM07#e1m?gF*JOG87`E3gMGv#nK;1o6s=uvrO|DKchpX<=ny zX5l=KoS;_DfL;{Im*s`CD|b&XaS6<lt*;SJ%E@`TAcQ8c;voXdGC;%g@aM{HCpYpV z<C#?mA>_>_5ZY0h0M&pb03}!s0<p1uzYyV;D6YrZ6d<Y-gW`F(e?YbiAzg34M(B;S zQ4jRkEtZ#phlRIU-uPV@OX@~RDRP6A5p4{Pm4~uzwgOQqhJqQ-shtwmvK=o1L=6_n zaZMx9V+;<69!H_PQCaYLiv0xNBS_b^R2{=cs+fNxMiv0=28D3VOBgK$A;LjnME7n` zUF(LpgG$)-j!ukqVnd4^#ymKU<(6r5;<oJCcYX_iI^TjbrC!}3n&Cz@wNnB+?|YSM z8+()nbh0BA5$fQxW9sXqCJX^mArQzXDn^AxuMS5Y<CzTt$H1cJxwy;Sy6@qMIdum_ z{HDvac+cWMA4hnD&jSwi;H8LC=%tG7#w}oRLs1!=UL<iFI!Zv2nx0B9DN5WW9RLQY z_%(}MB34A}U>gsJ6+dq8$V!laA$p?&VatNxfvzQH1IL#N`D2LHofyZD-wZGWzoTZl za2ykJ&o~kKcA8iK+AfF=(maR<>-H+R!*oce5*2m4<J#5Ug+Oo57qQ@8yV4aY#P>mN zgQzI@41PyVg_vy|vku0CM{w<}^)z>_qQylWBscAvZ$>Y5l%UR!3N8d+g5MXTdYh1! zr3t6#BB+knL6nG7g&a9Cl6I1S8LGSKdZeKuqhpv36s(tY8-y7m96Bo5x~=Ao3z^-F z3dEZ-7ZH~^1aYXzlo&#AY{4P?8qcK0*d~Mw7XSDnvruqqQt=RBi_56G5j@;&O@PC( zkaL4m5X5`9+bOfOX3gh}HWKIIW)y)|Y{JPm&hQ(-9`2AL3|HhCy=^{fx7Frd{;u+H zGal9<a~cl^V-sDRhnvv@DWix(93GPJeaOwwNm;w+Qk;jIk?OZ<4&<wVLpwoK92^p1 zG3{K_ni%&-Ko_1h1f9XR;C=CWxJ_5Rmt`K~5gu{#IgruX%-;Ysw76nqg)+jmeMjfg z&?}A)?+I`pGoP!9YL07Mc7|F8heC?QUZXWA?^yHpXhZ;+D~!qc;UPIcCXbBl30W*w z;iniYw>^QYWHehWj*bi#3!`JCSg7XoB80&Aa%YCL^gPrcG8_Y=msyfSo&nOX%mr>k zf!205RZQo}w-)Hp7t!&a{hd&9NW%u7l4clOlizm|3@&2OA;8m5;<lk8A5m~nnTHlp z+fWfDzGL!`ag9XR)g80tF~1uRRYD}U&G*Mc!+x~o!K61Nh*x@rZH`5BIJRf&w#CC7 zp_^kNJ?JxAhYb-PdW3I|g;}w9549Z7XDdYBLz2Ns#(NeeFXu+&TpG??!-3Y@(S;3P z8!Z_#+saw^zaVFGayBmy_nNW~HXzpBnkfffW}Z&R4II_9<rVP6&Mn*>rqRH>DwCm? z5&&EeHaH#h5(dvCbR>u6>*1rw&k{afT{)W`4KaxFF0!VgZ&nS{eegCo$fO%khe%;z zD*K*k$!7t1$b)M^yV-=y>AXZ^FP-+QxP&&AV4nxFov?1o6@<BO8G{>;i{1n$IA#&! zp;g=>W1E~{cZ!D^VQURW3_98&sXdo^70egku~gi1;XBWP&IB<E6V=Zl)Md9d*xoC! z-65AE*D%=4;iesrxV_laX^^$~#i>qVsd?k8Q}xDDrvW)Ph&oko9CfPRK<ZSzLDi{9 zH4D}zY4V!bcv?ot<P}7U@aXviu1$7b03n9_@css#1_*Sq1!)~I(G<%D%R^146>zWx z&`}5`?A(5b8>fy!Fx&D)9fe><y8*!(Hwr*H3c(zYSaB4Bc@%=_){jCkk3ulrIOO~& z1oL2a84GVd3c=(_0&*1X5-0a$5jRKCE|}-^DB9(QigvlaTZJN>F)+q(Kj1p=_5c;( z8QO!V@)fqr14KXqOt0#5?dXf!;sHA112sGj6|t0{C47CUxc)IhO?#b(1$dhf1_8*? zmm~%P3`k=GaPRE^Tzm`v;M5m<9UIFH7jj~bzc|`D|0z=uk(o%qp?th}yh(_Y6de0J z{dSFFx_nQ+Hi885)GkLOV&n*SLwUG|+n_=2cg$xjpVuyL-o1QoE=-Xh9ThGRlGXCr zuHg$E^BeuM`{<u9(Z66<EP#Gyw<^-Vtbg<L3|zJHzf<t*&{^aww!sxs9qsrovk=p{ zg&l1i$qiS@@MzaI@+=K>$Te|&(|8{x!QJ~hf}<SXM>)KCbY@1#boX75#Jgi^2sq81 zZWYeMn{X8>XZn`TZOh=O#g!{P`Y|Zp+MNMKWP30=l4~6oHAN^fcrh@~Q0T$IgZUrv z+B4PCDg@%>2qcNYOO3B9G3-(s9tt486x`tip}9j4@?^n%xkC7}^U7Wx$|9)=ESW&U zPwk>kq)gRp8**l-T2r$&;VK{(Qc>~{E^K*GXOXyv8ge{lppss+*D(?}eVWT^4V+ik zw5RX}Zl12`CR5#>efu+?`1T`T+0}%0QQX5V6v%4(DsQh7!~t|fMK5{o^}L;=2uJ&~ z=N|mhb5DKtxsN~a?N2?rXM6VY>TEYCOktF%vs~{xj#={3c=c;vxcbyn!f1>VllBNh z;->QHr=R`kBf_Y>CY=1%gAZMO>apuf<KFx|*gOlaIqmS{{9twB#k_p8`8{xIS(?Y& zsd3@HY5RAO4LF`-5xADRA#9aykl^qhXF?4P?v1xC39i4CAiAxGN;nwD*lf>h0^Ln2 z`PQZcAJSO|cn6m#uL+?FvaI2S%v{qa_FqG5?ew<{R<)e551&#XvfK-YAeENt*%-up zc<~Rk_Xpm;e*637*5<7}m>WVx%JX2*fvU~)d`YBEXu*;E@CXs_x$EdM!sv6yJjP=* zMVVo4l*<8QdYDfSt{!c$J4iuks4OiUk5~yaY<CcMh<izdlLT8S8uzj2s9g*R`Z5Iy z7OuW|IxX@c$H)7$CU_Bp<9$Jl=3(Q_!&bYQ+$hOpNntyaPI^Cikpv%xjQRlig=ZLf zcqWb`Q8etnI3ZMC@bYn<wpa4i+^9aH7plWU`NG)nXrYid$Y8db8_o@C`tB2QhtZaN z3+y;&#S70>NV>`^RFPl;3c;!YLL1fym#borMeM;$z^HKz4KhXIL2n+>6LeQ`L<^X> zJXGwp5awfw3*JG<tEJ-Y;5-xss$axhQn%N^th6o2G0H=TK-R#u@jjPno)>g4$|aLe zJR$=*FnQ&!=fyhAUHVt|(Z61zf5WaX4`q}7E$lC^zZ&+J9r$(V{bgLT^7Ln?!{}hb z&5SmUH?8AfK~Oi=Aq@;B)aGeEDO7TB;d3>e*NsAYXbA32)kX?>I$Idcjtyra@f8s> z-N9akr(QB$lPf_(6y5W}hWYrA^@WG2hmt9X=-`T|S$Eb+^^U4jMNf+mGm6tP5mGm= zg>m(nho61?86hM%q-Nr_5RPxoZ4mKva1L`pguoe8$hPdd=v3m>I6_Flk;y9}vyQ3n zBBEou3dTIQ?+S@iYmV*nh5Q~ydq8TBgGcu=dUq!U>BW*>&v_O>aJM1f5>1%XgUw4I x&Tt0-*90n-5SC7nrw@&aj24iJeJR6@7myQb_q^TFbM)`-qkq3d|H1d={{z;$^#lL_ literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.17-11-50.c3b53257-9058-4328-9baa-b1492fe0229f b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.17-11-50.c3b53257-9058-4328-9baa-b1492fe0229f new file mode 100644 index 0000000000000000000000000000000000000000..23e519d2a3208f0026d2c0718e1bd12297b98eac GIT binary patch literal 46266 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.17-24-59.3ec330fb-a77c-491e-9a69-03899200aed8 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.17-24-59.3ec330fb-a77c-491e-9a69-03899200aed8 new file mode 100644 index 0000000000000000000000000000000000000000..beba3e7e3ee1b7a725a008b645d7fd1571dba767 GIT binary patch literal 46088 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 TyKCg=|K36WZ-IW>_f!85!EpDE literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.20-23-38.cb988dbf-e441-49c9-aa7d-ef4ea39edc8f b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.20-23-38.cb988dbf-e441-49c9-aa7d-ef4ea39edc8f new file mode 100644 index 0000000000000000000000000000000000000000..957c363951f480f98330aa56105a40153fd741d2 GIT binary patch literal 40867 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%0A}cWL zI=xr4bq!cSujgL*MtEx7v3<VK--GCnJdeU+czX}?7{ro6&v~3iaDyM;B(1O8qYD}R P+lT1iEz`gEefj?YHL@c` literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.20-28-47.eb0b29f6-b68c-43b8-94a3-5a91137462fc b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.20-28-47.eb0b29f6-b68c-43b8-94a3-5a91137462fc new file mode 100644 index 0000000000000000000000000000000000000000..0643b28fa4ee05da9425a6704c7a694b3264d6f7 GIT binary patch literal 45991 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 F{6F_`&&~h< literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-02-02.0b9ba78e-4c73-4ed1-b359-6c4a418425e7 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-02-02.0b9ba78e-4c73-4ed1-b359-6c4a418425e7 new file mode 100644 index 0000000000000000000000000000000000000000..2655ac8f72cda5d562c41a6a7fef5fd0c410ed27 GIT binary patch literal 5534 zcmeI0TW{Mo7>2#|u-5w%9}EPR1H-ZsJ3gQb8m#SA*JjHG=wg6CQ;e;JI+0WoUliy? zf9HP7K9aI6xX!Y+j(6jmfT0QU(aZ1fN*^D6$ZL-Oq*kkOGG`+H&VPqv_YcX0bZ5mp znncOeJ)hGV5%IZ5|6){0w@6f^I1AkyHaW`XF3B<;QKF(Wk?zI08>b=TxD0pcWb^!c z|1oY#aWa48f5PDlJ%)6mcY_zWy5Q^-h=T5|=M66V;b7Qp!)3%7G`7pqXakQD2Ht7@ z*nf&BX`!-0<xl*-pJ^^mq=e>g`T=A1T8LCMPvH%Tcp(_56lj_x2;BxHA{Ig)^g21N z|1Jn+6GE@RiBqXSFv=1IlyDBXr)rJs0B^qPfu_7j6F0-X$&^VqB;3vB`tO8DhVm{R zsn_qfAxa<!q9js5fCmCd#xFYo2}!1yfS;foIfsW=H$+TjYx`K`5z<|NR2lJF4WbsN zM8q&aFj-_wIA<307p6!XD3`5H5ZI;8p~h{)F2L7>Jw6$25Z3Ts{Q9;;ZX2mJuT}ql z<n14Cz}0bpL21L+d4Ov#x5g4sxo@w3WLTCbuYz*5Uf;gPD`!&i5O~X|jOQ}v6~vNo zdAK1IOcf%rSfPlnv5u7sFmnv7oej2;L%1_mlL=<EVcV29Bbzrr+v}?$mQyJEwj*vG z3;)-pPuKX0d?&-<9nn^<|K`j5ZyclUiQy<uUBy`-SY9xx0#c|M*5tBJ?Fh^Byq?u( zGlt>RWPvX5Of7N&sYzJQ?Fe-=^cJMcqYa)V>(CjaR{_&KaYsbQBU{NTCmSGS=m-)? z7MO$y*ezw54ot_kyO1dItrc!P>hzhbUh8!SMyrh!hSB^2MlEA192_QTThCk*-m06f zu8WFJecaiWC4I_!Y=p*25&l|>JqE|?_OQ1%&M0MQPePVx?{S$5&<+clGHbqU@)R58 z482DaoI;{&gABdQO)A1MynEkjwCed&|2aAywXiDr5B{egYqbZrE&{VpL{zb`qTrEd zo9gOEd$qTWI#k<3lq$K7M4H5yv|oRl|87ke-pNM(!igG^I0z@0jjzt$It_C<W7n10 z_#!j1hDTj*_;RVaD^(HBGm%aOi5Y7B&}PpY+~cIQg+lh-yQnqu)EjJYrH#8C^+8x# z>OYeM*?<FZh*B)h6nZ~3Y1OONe7tw&o8HFmd|_C6poK}T<YVuic-lMj&tH4*7kVuj z_Rf66YwR*AZ3|pA*}XIW>_dx<xOHz*dfvS={}Orj&V217-j|5CcjjAl=JouUkDniF RG9j6qr7C~^A+Hyme*n&RkOKe! literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-02-07.fd4ace61-2bd0-41c6-99ae-c2700d2b078a b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-02-07.fd4ace61-2bd0-41c6-99ae-c2700d2b078a new file mode 100644 index 0000000000000000000000000000000000000000..2655ac8f72cda5d562c41a6a7fef5fd0c410ed27 GIT binary patch literal 5534 zcmeI0TW{Mo7>2#|u-5w%9}EPR1H-ZsJ3gQb8m#SA*JjHG=wg6CQ;e;JI+0WoUliy? zf9HP7K9aI6xX!Y+j(6jmfT0QU(aZ1fN*^D6$ZL-Oq*kkOGG`+H&VPqv_YcX0bZ5mp znncOeJ)hGV5%IZ5|6){0w@6f^I1AkyHaW`XF3B<;QKF(Wk?zI08>b=TxD0pcWb^!c z|1oY#aWa48f5PDlJ%)6mcY_zWy5Q^-h=T5|=M66V;b7Qp!)3%7G`7pqXakQD2Ht7@ z*nf&BX`!-0<xl*-pJ^^mq=e>g`T=A1T8LCMPvH%Tcp(_56lj_x2;BxHA{Ig)^g21N z|1Jn+6GE@RiBqXSFv=1IlyDBXr)rJs0B^qPfu_7j6F0-X$&^VqB;3vB`tO8DhVm{R zsn_qfAxa<!q9js5fCmCd#xFYo2}!1yfS;foIfsW=H$+TjYx`K`5z<|NR2lJF4WbsN zM8q&aFj-_wIA<307p6!XD3`5H5ZI;8p~h{)F2L7>Jw6$25Z3Ts{Q9;;ZX2mJuT}ql z<n14Cz}0bpL21L+d4Ov#x5g4sxo@w3WLTCbuYz*5Uf;gPD`!&i5O~X|jOQ}v6~vNo zdAK1IOcf%rSfPlnv5u7sFmnv7oej2;L%1_mlL=<EVcV29Bbzrr+v}?$mQyJEwj*vG z3;)-pPuKX0d?&-<9nn^<|K`j5ZyclUiQy<uUBy`-SY9xx0#c|M*5tBJ?Fh^Byq?u( zGlt>RWPvX5Of7N&sYzJQ?Fe-=^cJMcqYa)V>(CjaR{_&KaYsbQBU{NTCmSGS=m-)? z7MO$y*ezw54ot_kyO1dItrc!P>hzhbUh8!SMyrh!hSB^2MlEA192_QTThCk*-m06f zu8WFJecaiWC4I_!Y=p*25&l|>JqE|?_OQ1%&M0MQPePVx?{S$5&<+clGHbqU@)R58 z482DaoI;{&gABdQO)A1MynEkjwCed&|2aAywXiDr5B{egYqbZrE&{VpL{zb`qTrEd zo9gOEd$qTWI#k<3lq$K7M4H5yv|oRl|87ke-pNM(!igG^I0z@0jjzt$It_C<W7n10 z_#!j1hDTj*_;RVaD^(HBGm%aOi5Y7B&}PpY+~cIQg+lh-yQnqu)EjJYrH#8C^+8x# z>OYeM*?<FZh*B)h6nZ~3Y1OONe7tw&o8HFmd|_C6poK}T<YVuic-lMj&tH4*7kVuj z_Rf66YwR*AZ3|pA*}XIW>_dx<xOHz*dfvS={}Orj&V217-j|5CcjjAl=JouUkDniF RG9j6qr7C~^A+Hyme*n&RkOKe! literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-03-36.59e9c8bd-1146-4be6-9401-294912f73db5 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-03-36.59e9c8bd-1146-4be6-9401-294912f73db5 new file mode 100644 index 0000000000000000000000000000000000000000..7a12e8b012c0cce65254f8fdf9b0e84d750f7ed7 GIT binary patch literal 5789 zcmeHL-*4MC5cbxzYmNO82LnOmK(Orma$<BrgS2^Rvt~^<7}yGdmS|fuO-dx?L=Oe_ z&_8@fN{Us_X}UDYFu*ScMN{N=-yQG1(_fE1CN-!3xK^t%l2Ms_*Z&#E-mi*E<&D!U z8bo~Lon^t8$my9Bf6_oJFXcMYjE3F?9c;y!N8*@80nw4*$~!;vrXr*am*Fn0I7`0o zui>TvP9~4~pK$oxj6n>{Ztxser;Hu~(a^r^bh^X6L3_LH!Z2bK8h4AO;R1^|h0bBJ z)_;OfM5^OdCy)Cdo*7(>C<PnujDb`7N=hL&4&j7EER__rfIx7Lpk2^1q9N>pS*LpS z_mTv3K!OQ4Q=v3S8c?nwAdCU-shhnzz{#x)8nIMx4-dv82VR^_GnFv&Y=9WXk>b*< z{R8AJ;w4Nx6TnfF4O?SG<$@i?Lh5EQF1GQF8AwHQjxtr!V*(BEjwxeA;>mi9K(<@m zR@*y~WJ)iDoG1(qGv6APGv03)J2nz<smCm4v%)+n5lpDA0PeQCIbcbNrvBV23w<ag zGO3J3BdSRl%7_nzliOm<Z~^T-e|!AeKY#!3)zN8{<_9uhXWtr7!M6zAFRZRC`OJhN znMN$bkji4}LM(+A82pTk6q-}MOCoBbu?N3nRB{3PAAsW};^+n(Nc60n*#~@o7KJo) z0cW|;FyZ2Y*Xu7+ByR*`!b7|PBM?K-V+v#-W)$dUKw}e3E)aZYOyztEL=dD>(y&** z|1gj73Xu_2UWkDgXXbZ66s<(e&hD-y-1j3MY2UYO+qm{gNMeo9e}ZD<Y;I02h(sdi zas4k-TYmeNz$%VVUJ0a%F~5brZ|;8q5wjfvQ)x`4bCd%;#h7*>V5-?FmpYpUt_u$V ze1X{Qy@MshTD<4KyeS~(X~W>n+5Zpm?rtxEYf>HN-aI)v_u%$<hN}3xv%6)nT%9}* z%K3WZeFLwU5%NCZT}7p>5*3IA!mGnALP>Qhc@7J6>kP|vu>fz51)I<McX5Ys=g%rw z8A271MfEz)-B*QJOksw)>xf%~h0jY0>)w8z=1b83aPT)f^XqUNY!~&iN)d^aP2qK$ ztc(i{(a38a1Xws)Z!zsyeMXp7H9c^)+HJf+jbp+$P^jel8Hsb6;dQt51XHQtu<^pm z08?}~z`0%dX*Qbm<VhbTR!x^mDfywl_G7Jf@5%`U1kw>`8df50tCJ_Y`JdLK^pXZn zVAQD#l+Pk5_!M>A?eoZ&m2oNCIyQThLf9gi`r!aG#>=BOPQ$vf=XomboyRdM)QfPd z-PwOJcZ{cW8fIAfM@EGq+21BMmz2AOV$tc|P~uE&L+}q@-WGuFbeG75#`TJRJuD>s zAADUkU>zKyHJ!#9i?SXx>($nvx9SX5ox%03&8joF%Le%7oV4l;zV2(y%`MGB4qbHy zm2X|wvNsow6`ir_48Hi`Feh_S`j#TQ!sDtlxarg1|F|=#Cr|rNu{BVf#A+;b^6X<$ HPg{QjZ)Def literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-07-02.01e76216-c3bb-4665-85e7-5e6e9f39340d b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-07-02.01e76216-c3bb-4665-85e7-5e6e9f39340d new file mode 100644 index 0000000000000000000000000000000000000000..aaae7b903e5ed847b25ef56c4bb5a858941d5498 GIT binary patch literal 5535 zcmeI0U2oeq6o%dPW3Bfm4vYns1H-Z$JBf`hXt1?cU7Ic&po;+lB{8-dT9imCi7yK5 zV*Q)_EjuJ-TX3CaZ5{8%HvvNv<fE78<CXq;_#v-3{^MG$#>k9{{DJ=l$L=4J3h7RY zSrR7c*gcy?6C$Q(g1@Jcl5UZzL@^q>*EH;9GnZr;OCq8Yo=W%p%$@R>GF*ncbh26g zo&N|ojc_u5=>Ltw=Xwl0)VslRTwO4F0z^Ug#`BIY4#R%0+lGsTQD|(IrO^hKq!hf9 z{E`0zQFx)ULgkPBPfs-$BT_>1H~oN9`ceoknkVpzB&-k=6o-hXDMGhFiG;>50KHC* z>c0yT(U3%!;7qwxAZSEW1rcEka8K15)d608)dP)L!BaQGy~&tLHzv%@X8LbPBt?1W zkJKLw+K{9W1WB5xAix6wBxM(!fW#zIRKQPAj-37d%WERWvbA}v@(Ah9L8^>+tp-sG zQzBv*AebyNDx6ab`YTnW4H1*AP7v6o&c4QN!#2QIggrPMt`XMop1*rtBDamyn%AoT zKk^O^*5K+mz@W6@>)gY&ms?{AsNA<V=oyy9$;+TzuGhD(@yZ!4?gMWTmD8EbSp~5q zTpVr)1yzMeEmka&E39MX0?Zr(YiEN^<Ph$R)g;8MHf-ziW@z)~XM25B#BvH{-*m*S zV&VU~^ywO3k?-*M_?BoZ*MIY6{x^<c_t0>Zr!M0x5Hv5SQ~@c}1Z#5Hr?!OUd0yY@ zvmV26YO+8Vc&g^PfYc-|=eC48Joe_Ki=z#mCF?{J8eIld_rxs`9Sm(HtDJ0rkf9?; zB57a}CZIPF&2(Tow%x@<k#DVVt5K)VT=rV8dt|g)OJNwzFJRO%rozEt%G-M8im+DQ zbah=+bn4^Iwk+vW-eMy(R*JBfTI>-xUbm0Ey>S{v6zxe&Q|&!2xB%_2peeKFizegP zC@1JWn&1=?T^nTRWv;o1NATuttI?|GPyA=-c+}jg<lp-rf2h^&-MR?OK9NL<#uWv7 zo^7hjAMMrN(8!6jJw&O}t3>d0ib?zRxB2hZbncyO<j<X`A(;koh}rnd>1(H9E@$Mr zG8>&|M%MVpUe`N*u@K#rs)%Qq;A26i6ve)8x91(*VWqT(Lip|5s1^6rKU!l;8@F5P zy}0z$f2Mn~0ej#OrRX$MX#P~#s#m@FXlKpWy^h`b#;`C!bC+64$o?Jiw6o@)zxUoP z^hz@9tofSv*hN&@9=PnXJ8S;gmlhjwtLCIMy*q3ECGza7`N~(kFA;BN%{OYz>-ke3 UzdzPwN-{a&Du4DNuNR$v0BUuR9smFU literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-15-12.b3c35513-a088-42d2-ba59-6e7b9c782316 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-15-12.b3c35513-a088-42d2-ba59-6e7b9c782316 new file mode 100644 index 0000000000000000000000000000000000000000..b18f0b79cff1a26b8535182739f2a4e60fa711f5 GIT binary patch literal 5534 zcmeI0U2oeq6o$R^W3Bfm4h#gA1H-ZsJBf`hXt1?cU7IZ%po;+lMKQJ->Wie3_@Y2B z`aAnuc1X&$;5zNvI^K<M0){5YM=#IEE4_d4u4p*^qei2_$&88O2mdvW-M=Lh(w&yG zIE>SYdp@I6B9e2Fy=7EMw@g*6IE&mH79Qj?m*hE*DN%8jO84U2O|pn_T!y>!@>%ht z{}4B&I9WXKKj8409zz!D-QXFnE;%~|qM(24dB>MWVR+o{!ez`Ev^LAq>H?2b2Ht7$ z(0`05S*h|;6_5OnPc#=NQbPMr{eTI3Aw(wHr|^=*yc7&n1~f}kgzkb8F^gabdYv3M z{}P0<kkBh|l1wTPjIvY#C7c89sXF5(z{_uXpb0Ot)Xi~kGGWq<2zT?D{u>g>P~Q0? z4Ti%m#3=+poW?2$@IU~`_+>935y=%3@C#HUXMg|dhKPymY#ysRLb`L1IwM}ILDa%j zh!_S4Cd-@&=gfls&J^ha<+9TY0=v}N*SKBS2Kb7whex9|!W!O-KVDVHT_d&Twd((m zyu-saxH=9nC~f#U_i*ji)>r~+_w5Z249nu=Wl%2H>)Y3O)l4St18)(P$xIf!hFB3U z4mX5?sZyjCD-!WF*0E{<W{!civ%w~E2zSP65@J>xwsm<kvU&5Xy}mkPHHEToI^tHb z@PA$Ubd9gccXV=cN3>Pzzxy)(8^@@BWH_o*mvI&dR+LPtfRt*AHM#0jTf*`@Z(#LV zk6}19S)dC%Q}bLvY7$j*TS6V3cyrRl(FV_w_2`t*tAOdAxFw>)k*#F4lMN6u^aP0| z3rxZU?3S`z2c~1&T|^Z5-U_!Gb^6R@ul4%JMys_HhSB^2MlEA192}-uSI=A%-f5by zu8WFJecaiWC4I^pY=p*25&lApJqE|?53skl&M0MQPa>9T?{S$4&<+dQGH*X`^9&p1 z6un0qoKm7|gB-ogO(vo-ynfSZb(+Ov|0y~iHMc6oPyUCW8;yInE&{Vp#8k1Urr?2R zo9gmMd$qTWI#k<3lq$WBMV2O*wBLT4pSPxS?_?u??nDhq5=0?p<8NoLoR+zqvFplw ze32Vjql3P8@_eDWD^(fIa*<60Nf>H<-)7I#2KjSNN?Ryo-@c1lF;9czHLkREx1-*R zDog!Ox+hz(2M$q+CAmWHr@~INZq3I#XTI)j?9La4g$J6O)LK3cz7S74Xa4DH@0W#M zNrs&>U-KHfh)UZ6mrZu(%s=_iVk2(Vn^c~6=ghxGo}Dva`H1&5;_aOIMxA-Hc;e&d S$A(NvE~l9)p1v!ZW$#}ss*o%I literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-20-13.c387dc8d-1ab5-4c8a-adf0-5c8d3995af73 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-20-13.c387dc8d-1ab5-4c8a-adf0-5c8d3995af73 new file mode 100644 index 0000000000000000000000000000000000000000..b18f0b79cff1a26b8535182739f2a4e60fa711f5 GIT binary patch literal 5534 zcmeI0U2oeq6o$R^W3Bfm4h#gA1H-ZsJBf`hXt1?cU7IZ%po;+lMKQJ->Wie3_@Y2B z`aAnuc1X&$;5zNvI^K<M0){5YM=#IEE4_d4u4p*^qei2_$&88O2mdvW-M=Lh(w&yG zIE>SYdp@I6B9e2Fy=7EMw@g*6IE&mH79Qj?m*hE*DN%8jO84U2O|pn_T!y>!@>%ht z{}4B&I9WXKKj8409zz!D-QXFnE;%~|qM(24dB>MWVR+o{!ez`Ev^LAq>H?2b2Ht7$ z(0`05S*h|;6_5OnPc#=NQbPMr{eTI3Aw(wHr|^=*yc7&n1~f}kgzkb8F^gabdYv3M z{}P0<kkBh|l1wTPjIvY#C7c89sXF5(z{_uXpb0Ot)Xi~kGGWq<2zT?D{u>g>P~Q0? z4Ti%m#3=+poW?2$@IU~`_+>935y=%3@C#HUXMg|dhKPymY#ysRLb`L1IwM}ILDa%j zh!_S4Cd-@&=gfls&J^ha<+9TY0=v}N*SKBS2Kb7whex9|!W!O-KVDVHT_d&Twd((m zyu-saxH=9nC~f#U_i*ji)>r~+_w5Z249nu=Wl%2H>)Y3O)l4St18)(P$xIf!hFB3U z4mX5?sZyjCD-!WF*0E{<W{!civ%w~E2zSP65@J>xwsm<kvU&5Xy}mkPHHEToI^tHb z@PA$Ubd9gccXV=cN3>Pzzxy)(8^@@BWH_o*mvI&dR+LPtfRt*AHM#0jTf*`@Z(#LV zk6}19S)dC%Q}bLvY7$j*TS6V3cyrRl(FV_w_2`t*tAOdAxFw>)k*#F4lMN6u^aP0| z3rxZU?3S`z2c~1&T|^Z5-U_!Gb^6R@ul4%JMys_HhSB^2MlEA192}-uSI=A%-f5by zu8WFJecaiWC4I^pY=p*25&lApJqE|?53skl&M0MQPa>9T?{S$4&<+dQGH*X`^9&p1 z6un0qoKm7|gB-ogO(vo-ynfSZb(+Ov|0y~iHMc6oPyUCW8;yInE&{Vp#8k1Urr?2R zo9gmMd$qTWI#k<3lq$WBMV2O*wBLT4pSPxS?_?u??nDhq5=0?p<8NoLoR+zqvFplw ze32Vjql3P8@_eDWD^(fIa*<60Nf>H<-)7I#2KjSNN?Ryo-@c1lF;9czHLkREx1-*R zDog!Ox+hz(2M$q+CAmWHr@~INZq3I#XTI)j?9La4g$J6O)LK3cz7S74Xa4DH@0W#M zNrs&>U-KHfh)UZ6mrZu(%s=_iVk2(Vn^c~6=ghxGo}Dva`H1&5;_aOIMxA-Hc;e&d S$A(NvE~l9)p1v!ZW$#}ss*o%I literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-21-18.2de1bbbf-d96a-4478-be19-d65c64d8d855 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-21-18.2de1bbbf-d96a-4478-be19-d65c64d8d855 new file mode 100644 index 0000000000000000000000000000000000000000..a81890dafa725482ba91d59d78d236bd0223106a GIT binary patch literal 5538 zcmeI0U2oeq6o$R^W3Bfm4h#gA1H-ZsJBf`hXt1_dU7IZ%po;+lMKQJ(N|Z<{i7yKD zV!(dp{>lz1*%n-9SzE`u@lC+c1o`OY`FN#|k3QrL$A8jjG&q?tnSbNI!?F9DVp6%& zVit#SI&sfubV_7$F2x^=YULKGjx}eId&9zmZ03?I<1r;V7O8SC&fP>rjN>xgrI*d} zZ~e!(DaFbBk^d(SUzjn7(Ch{;aCO1iDG&|)ThBYbJPP}V{VrU_oIz`|EUhl^IA!3S z=8yfSh$0G|6*_<7|NYExaiSEoe=!f3u-8%w**=9gB<6)=paoEorU=~yEn^nJ5X?F? zZvH9>Wg($g;3Pt6kc_fa10|dT?x{QDCcv97dY}m}MCxX^H<>WyMufZB%=`_BVkqzY zkp{zI7vdCxAWmZ)1b85TV*IifkcecON%#S(k+Z*lbwlJtbvBPx9iiMgNSzU{)gl^U zDntwe1XD%Eq;pn+{=_ut0_CdH3xaZ~vu|*_unq7PVGoZ+YlOAD7eBwPkh@lD!&|EV zKk^O_*Wj8sz@RL{*Li?zueQb#P`ht$cwku;Coh9?x!&Bq!K-G3d<eWnR3<Z(^BQ7B zxH#MrN~Q~$mROODud$9*3ovsmY&jcjB8PBitR^95wPjnEH={Cdek`xAj#y2h?3<3b zRV@79ls;4AYw{hPoZJy@)%vf#%>TwQ>K|E->eOYN1(M|jQ#v4po?=a|`qY-NJkJ}H z`mD#WoQ5ng1)k}7E+93Ds<|zpj!wKe>EdXMSCaMUl+mkznVz^MqQg;H$!aHCAY|xC z5-S$igbCO!Wtj;~r)+l-(d26@+-lUBGnc*A>mOUK)>2qT`wLjLtf_Etn2N5MxhA~R zv|Zg46_fh7b6J+mDetinS}R5PYa{j;9IrpX-rhQ+l%YL|SZch-rI2787PM6c?U!vX zuv1Rae6+zS6xue((9GNj8I9rH`%bIV%%A$t(emiISINKg|N6escyR9`G5usrHH&Hz z9(ZL}UH(|!?Jc7YHU1E_O0Q!n(gd^i%dhj_z3JRMm7zbkqLw5Hq7c*Z)!AF8Wp8Kf zx~TLRE;1`@bkO%sUM^I3l`f)LCdEXOgrV9G?f1Ond(4z^QAodiBemk62FGiRY3puN zy%$xk`uB8CwO|h%qBTo0jrLE6oo3ygk9X#L-3!^B?+gnYH20~sj2zq(Pdjt|>6`EU zLa!vl&YZ7#lU+n**#(z<c4y8%`PNcK+^RjPZ12vTe~vsmbH4H&?{mc4ne)w>^Jf0c U$4`(Am6A+Nh0dRU$eTs)AJL$YdH?_b literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-23-48.ba3ca114-2052-4345-8bb5-91f4d94b1752 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-23-48.ba3ca114-2052-4345-8bb5-91f4d94b1752 new file mode 100644 index 0000000000000000000000000000000000000000..fad00260ec6ac673e3c3fcf1b9bb0c6e4d9104bd GIT binary patch literal 5534 zcmeI0U2oeq6o$R^W3Bfm4h#gA1H-ZsJBf`hXt1_dU7IZ%;EMqQEuGj}C{ZG*B)%xn zi~i32mK{>EEx69IwvKn>n}DGS^3lul@k$>beaLFg=t-?s<7|d9`)>4(#_k^qrE;hF zEE-42#66z{QzqkcDgMGhD>qMcq&bG}4UP}enak3YM*-83NR)eV?#3cSPRnSQPCCoJ zA3df`1DebpjXu%vg&Bhwo890At<E`~0@KjF^}3e~(Zg;VE+dZ6*epw<4LnK^ywmLQ z=qaIyT&KCto{au}X1F+03Yx!}2aNHxltMO7;SGy;E)leVKqLu4w?WGYL+FE9r-t?4 zB@1xOf-7)hp)^PgFwqb&&VlyStzjMD%~w6pgy$l0Q`(zNP`M%FZaOo6$4nu~JAb5J zzu$%^0pE|3Nc%n=2%wN(c6=7HRHKBSpd2~-`&TziPE>32SmhDQor6>v=~^wK5vD|> zFd#6MrzoAX0`wQutPKHIt&Z;(OPzg#+lFm`uLyg1G*~07<-PdzZHe5rQXAev{r{1- zf4BzM!~q3m5x&j?Tzk1Sm4M29d;J5;vN(Ael*{$z_6=S+BjiKiEuu1>sf<?;OTxwB zmQbS3Wl~^;GP<TZRxY5-v9QIgzlj{8ovE6PDXT5py1W?_dGm8|eO1JAie%q(#I0h{ z|EBbr8efs`=;Y*%Xe-x$^JV@wjzRaxa+Ieo<II<s<*2mJay_M*T=uCgVR@d{EA&~9 zVL1(%Zwfr>c`gt&3(L7Jp$<;GIqBkPi&v0!f++@9KAN7mC8EPYQOPPNTOeZSNERvd zZNm6?8(?Yz(<$0r$Ta)b3bz_{=FDZU^}5GatF;uC(f$HfEo&+q8YZG`X091;)ooWd zMa85(?Oc>4bIN;agw{$i{@RE=1jp<4sJA!Hf&j^$gqRrbaVaDihXqZQHeWWmphh_* z@6iM&SLE6tB`<R$WH^L(?^}&lJ$pKOPL4;<txER8=+lq2+JjpcN!cf(Kx0@@@W3mY z>hj0pYHu-c0%H$Js^mJ7B8e$!zy3D=-I~t5QxW-dCu&JzKO9pwzB+sBH0<RJU00>U zi`2>*9(28vmkZ5ZrSou>N->cvM$-DB&7OCBkCQSMirBaBqE^gP?|6+XZQSjs_rlUr z|C#Km2JC^uw8l8q<o)!xRj*p};m(<_dmFp+g<;`=<|eh0kG*^1Y3Iy8f9<_r=#^yH zIrBBIv5TlITHvzD?wt8&A6kltTlFTT=iNE;FOg^G%vV0*eTjHGXTDKqUeBJ5=<{Pu QB`j4_p|j^7vU=Y62WS3}ga7~l literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-24-23.9f96565e-6e8c-47f5-ba6a-5778d179287c b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-24-23.9f96565e-6e8c-47f5-ba6a-5778d179287c new file mode 100644 index 0000000000000000000000000000000000000000..ae77d8aafbeb0ea5d009a81fc6a3285c249ea115 GIT binary patch literal 5536 zcmeI0U2oeq6o$R^W3Bfm4h#gA1H-Zs+lh@XXt1_dU7I!=po;+lEuGj}s4tRA;)?>k z81^&!TY5;zw%|I;+B)8iZvuuU$VV^F$18n&@FA;N?xR|*#@P%-_JjL|#`Yf)g|w&n zEF6dN#6Fw(QzoJ_k^F_el6D@eP;m_GYaAb>Gn=I;4}GS>B$oF1nH?noa#}{abkbS& zqx+CH^=UGD;Qmd+XL=0DSnmeUXm!r<1ek*Ejnlngh=W154HqFtXl$0H(FPvI2+m3N z(0xoONv_gdWslrXPc#>2QbO~+e!vJ{3XzEB3A|z<&jo@?z)#|spxdBChynCLual$t z?}GU_X8t8uQ6d!x^f6Z8GtPnbRIO1R;MF%h(1hnnY^St0o1nA<#_e>b|BjhNl6U?{ zy?(z9VGN!Z#-Z{&IuJl2zvy@@V5vd@zd$*%_V+KZnV87d=CR5nq&)|zGSamgL@i8- zNMS%=GEY%hrv>P5s8}0(E?XVXE0$XO8n+GG0ACUIa4=jWtl>R>_qs%G8>uyKq5l8K z+do``tK)!zvIt-69<IIIno2<BzMcMoVOgBK49ewteft`(oJque;4Pvun#qh;5KF?v z;f7G4%0*mY1tPqnI#w>A%rUUVthb3AqMfOlj47)P+q%3N7J2h)aeY<9a*AZ%bi}P< z(f_*i=^9^=Z*Y8kOSF~izxy)(8^^FaFdXHn%Q*7{W;sgbv0P25CYOC`OIVKM^a_2} zV;D|N=IH{DYMu*3&4O}nOQ^$RXHL2}+Tayr9e;}crH8sFZi(n{SX8pg$p(lRI)a4~ zJ(DmV-uRg6z_f~X7cj-Xx5BMPoj!BfYn|?q(P}M)VKl#hQOlSLi-vL1)-zX(x9X;= z>!PAlpLQ<Fl0M}vH9}*h7=Nk79)aa_d(_(-r@oJ5PXdg!_qa#|Xom$&nKqv{c|whH zO5URhRxZi4K}ufcIuXGL-n?x!TJ`L)`;;7ynp>6ZC-<M9Yqfi~E`qX8gucR{qTqp3 zG}Yyg#ns-RZ~59Dl2q|kD3Um$r2Y2W{C8_Q_fAFR&z-0tiM(J;+4$o0wbd|}GqP=& zj+*DG(KR^eI>*iD3)O9@@?e&VWFlCEr1pK=J?H2SFQrWs(Qn^Jt=OmD(HdXcxZP9l z1*NI}Gv1R8*aM3xg;A=={i$)QUNz^Voi|_iK6dLX!@>p4ZE7VWdw0as&YOSv;(NEy zE6K3)=4)PL7g1R>!DXA>dGjwmwG<Jz>P|}6yYuE>BhSv8uYAV)8u51Ce52mHo;`8t T17uCcES1wlWluk3^}O>L4%U#W literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-26-19.bbd61739-7ba5-4a26-904b-d4538eb0ab77 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-26-19.bbd61739-7ba5-4a26-904b-d4538eb0ab77 new file mode 100644 index 0000000000000000000000000000000000000000..ee358bf8d5468451cada1102d912d96a57d95d53 GIT binary patch literal 42132 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 S(SeNq{e$!$R_H$lf&Blu)b+~% literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-29-04.a76c77d4-350b-49ac-8234-514173e08b4d b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-29-04.a76c77d4-350b-49ac-8234-514173e08b4d new file mode 100644 index 0000000000000000000000000000000000000000..7e254044853205270c8ffba94dcbf390afb3a30e GIT binary patch literal 42130 zcmeHQ`F|uwb=PvU9E*)HXGkL(Yi3u|b4jDo>`JkASK5_lM-r0OZf99{db(?7+Ul8} z>SHCXqW}p8LpYoRl8}&KW6pqqBm}S>$bJ0*xzEqXi_K5@iQn^Hb@v>a!&0f1U4M}5 z)r`8TUVrP=t5>gHy{dZuOLyo<OnLdp$cUwF6NesA?uGBki!O28WX<0;%VwjRT-nxZ znp0nK><5YNxk<m_nVv<A<R&R+n%haO*|bbu^Gv(pCf8Pyy4~;`+p>^|K`NSWd2(}` zzC?K$5Z7&k(3dJ7gRiIXyJVM<s&uMu8@@$mCC!skTj^9q({oe#)VNeJEh3FxA55d; zl4UlCl%J(9Q(gg(Y~O489(}oTn&GoF*OkWRJkK%9zDMRA$9BeMrLiTuLDsjMWGq5o z(_E=x1NJbdH0IcLeT=?Bc{LF798D)>P2ZreRQ~5BBO~k4-%_k@yPo6_oisd2*DOnd zS9<ZnQAt|hs(01$?MBieE&$OzVgTc#N@mj2<C58cw?&EY7D*yoM33p%6yp+UTrnNH zQ3o_}ZU}o5hX@rmF@TDipZl#r#jBQG)-1Q9))Sd@@B&M#mkn)})!8LhMOKmD#F1uz z=a?i_3Q{G;U+(~cXWL!x&*pO(2B5;;>=4g)8j_}CZ;2h(#--!O%lz-$AFn4T8It;T z&8`y$XY|^WKY0F;kN@8@pBX*jL$6oOM#Yv<cE^u)i+y45Qh$`bN_iECz1z^5Zq4@S zt9R(pK+QC_uYj6)jp9M_%C=Xt8&X!Dl2Zj~&mA08QnDEojWr!oF}L<!I8I;7l#ro$ zguYIB3!qr@8`2tSN|~&bNf$EHh17(UNu~4j^-LjD9IZ}Vdh9ZNLu`lM5@W?tCDB`z zGf;fbutQzhr+?Bn21NaaPH$6=0?~F4rEdz9CP*s1U3n68N6=Mg_NzN(S>B_bZgtGr zE`2cb(AeBqK{}-eI+4{wu6cD!o*RRlV{=RQtIG>LIj(4y3EZ|FR}OQq%xi0l=a%kS z!|WBPH+BYTE_}!`G@EDaM#Zdl=ZK!NEWTIkd0o)^<}eBKobJiM5T6bb=jSf2FD~3a zAWxLa=q#Tdlnql@mem1tR)ge=>+8!)1F{5ZKm}T92ZkgZi)Y66D_VQg1!Loqi^~2d zB0+Kb=D@muLDr>j*`aTZ75_<jJBT=rJZ7bHz>!Q>!f~}g-&Xu*)-^E?{&b8=psXL- zp>Hq#i*iRuq$Batn5tseRMoM|Osk_w^N!-bDsun44d~ioUMSh_bnuM+O!42C4#W3* z&US&mv-t0d6w+a!1`M0@XN&)#ydiqwmQI?Ubbft(r9h?Pe=4u*px|hxOX$0b|J7m$ z39_%Y254q*6zFL2zm@rpl6Odk4d#XioY6tW`WC1&DQ1@|z6)j;iA!D$>?+5snhnj8 zc9ElZ_)Mo*4ZlwBgj%6hX883cefJK%E2g{#{w({Z<w2W49qAZri&N}T0!Hdqf5p^U z8t8RqKhU^hK;fT+YNE#(&W^^XCzRTek�!)lWsA7Oth}xbN@KM67n}^_()uwcA)P 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 Rg^d3F!}K3k=|B3u{QoV>_22*i literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-29-41.b0b49118-b1bd-4c60-99d7-6adcd31bab06 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-29-41.b0b49118-b1bd-4c60-99d7-6adcd31bab06 new file mode 100644 index 0000000000000000000000000000000000000000..5ed9fd38d343ca3a5e0c8c0430bd78e14c94b17f GIT binary patch literal 42157 zcmeHQX?!F{b=PvU91F&nGo+D?HM7?AT+&FIl@x1trCl*Ql904^JIlJ$(_J&u-k#~H zK339h6d=K1hymw-BqSu*m@{A?2?1;e$bEg!eg1x4Y(C`^-}7Gep&89#sZ`6Ze@OOf zMqO2}|MlwCt5>gHRlWbk+jJ<QymV-2$kMimLysu;!1wfdmpE>^?r)hDvsp{8Z0U8) zX{<Q*14Q@SwBPhhμ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 Y<eQ`Q^m=q4qksP({fAZhkG?PeKO1oV%>V!Z literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-30-06.52b5a733-2ee0-4f9e-8085-56c589e0e428 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-30-06.52b5a733-2ee0-4f9e-8085-56c589e0e428 new file mode 100644 index 0000000000000000000000000000000000000000..3b840a615eb862127a5d336430ad95e0e5cd49e0 GIT binary patch literal 42155 zcmeHQX?!F{b=PvU91F&nGo+D?HM6VfxpdA-inY7at~@)EkhFF?%evFkT{F{G&-7Fu zD`__hkYF&xfO9|+5)#{(GhiSI0c;1zeSOb;{(fF;KIIeN^Ir9#8O>p-RLib^NcL(* zT~)9D_3G8DSFc`Gec+|rbReO;d|+U}(zb|0k0|%R_w)sqIBvS;Z<%GYQB5yz={3!% zFFW=FMEBgZ-|$S&B1U?Hlyl9kwAO4|rmlIW-Eh;Z%W2(ic#dsZNW>r&&9^+cxkX>1 zybOrzwn6Aim51T$6n>ZNGE$YM>bBuqWJc0FDYKc)RP@oDMl!=v#k7btczrMp4ojBV zAkxGPeVOtKfMok#)A#7hl~W9#rMa#&H0ybeS@u0L=Qy@AG$Rcy+6}U{)g(g^`kLlS z4I8kBIi(@Tw(CRm70RoDkmqPRDQo&VeWmh0FBuqEi~g1pb=&nMhv=l?NxEiP61>t& z7LH2NJXgJ|mTx!G4sij9?hykRA5}7!og9|T2D~jwgttf%*(7>G$EFyTNaM2U*o``% zNpeHjn>a+MCbA4v)co9U4Jux>?6PLLEwvuWg)gwQdfCusSe;#BRb&<UO&n<&c#cU@ zr65%j{PhkHc(&d4{`|yPj@7Wj-s}+1cN&tWV{b_u*M_Cz$IJZh+#jz;#~70OR?V&x z250cvliz>-p^yLHGoKke;X|)i%|^wRQFe!qwu^mX?^1u1zDju&h`rm;nr_YZ=&QHs z(Ll{Kw=RR4d5z*h^758fvl~)g9+xu(Y0n)TR8qPb6iqZ8QZYC8UN}i#%ao9zd4#@B zc`Kk;^&8SEX-c`gl*<<KnL=hv%4M<>^z}?3R2;2NTzc#heM4fKzA?dyqe`N;D5s(L zo?(Z&vP=J@ZwiR|4V~Vq90j5~J(RvVP?{jA^fu*5&>cZno!+nRlx2C3dOGfyGi~}{ z`s&c^P(hl~1D(j~A=kXRCC?5)&Y{`G`_!fRjvSXY%LH!Qjw^>bSmxE$g|mxyuVVHJ z)Ehg4G#fr-8Jf-0cB5ie+jB%uSr*@`b-XU<eY2Q^c}{g?V2DoziF30T))waP>yal) zWptL#^vZ@QEXzs{Ix9i)g|)S%#U5FLG@t^lv<*WNj>XeM`xULd>4KqQ$wg)V6Oo`K zeM?|nz#!|=w{Fw7C5r!~yaPlWM;^1%I^amAE8)0Wpl>h!GwYg|2Y*^dB~aE^x9K~I z|DxO;5@|`iIHaoBHC1)!64UBv(!8_yuZr9~Zv(n^m={X!bUJuOf2R0vOo!q7J!h*x z-&Oo~MGEOKP(6lC`m@FVP~H%|a8oBuPdc}@wp^f6@jsQ<wNP+0(<SuX#s7*KLW1lo z@c_*XjshJl{<kvMQu21mu)*B$fHOL%Sl<G5CME20#dpCBBT31tfnDX8RkNX4(k^oJ zcAx1KtKrw_9Z)N@$_&5Wr0?0LcP5nAz@KH`v^;1ts3RR>Z860jrNDfM`zxl-&_J&< z`++7E0}B5nR1-bUaJDo)J)zW&3=AA<sctIzlyEIYhkbvWrV_PVuIH3NuHDLdVPqZB zbnP|;2El<ul4fe4PqK;PyaIm@&|L9sEmu6J%)lSFODXsXjV#HtC9rJ3?vVVZWorg8 zB-ex4iZ0<q1r6_nL#S^$#7JU6nlCOW$AHXTx~A8N9NKD0I#RrwJ%>3Bbij=U5=$ft zbhKDhUJ3b8EesA0(y`)sB@zA&1Gl~5#@S&yCE1l7AgHcfI$kU(*|0#(^O}Wp8b$&+ zeGydprF1xjN=L6uU&K<Vye`p+;$qvYCyPr;GNcrmnxNO3Ffk)?RG!rqRLrnsl#{gJ z*X}63w+4OxBsAz0Ht1bIV84UUZu6T?M@<*n-E;<;t^kx1mFbo-A4Y09<i0CUSvJ_@ z?u={@-FDDw*m+c$Nz$LgCci6Ddi02LCafg#oLTb~uuE#7^@oP=QS@`W1XisfmA9Bm z3^^%XHpvE#vM}4Dv!%z5DAT*C)rqG8u~mSeRY@Wl(A%LFSaYiOfVRnuAbP6wco$GG zk@A7e#Y+($_PIj_^>jB-r%Rvf0*VPs2e}<;9iYyXo;aesZFk+&%bMc?860fsT<P;i zlsh`Ibe|g0`O+7TDDUaWjr>$wba6!dZ0U<fl);Ydy6<{+UDfS+-Snco=SpAd3M9yj z?gX4bN4XbDU+w~=N*V;Fy=oKY;lycRB`*#gAG$>E1|f%vqLdc{6CP!To@cXjzX44E zgPlQ33XC8F6}qU5!6%=T(j`=k%h-=l74h|>Xc9@^Tf4Qk2ptF25zH2+6G=8<oW8o9 zq$}7PRuiQ+9&2mBR#AgaQ3WP|o-<6evFTdrmSf60fmmxU{0_Dl8WdQdKrfWubWAzh zB^Tz@ea8W%DZ9jVfutODJk|?guH-_8aY1S7@KrTP!vx0OQ@Zt-GTeh;sHafmRNDbN z%m7uadkK1P>CML&6Y;g(e%LEr;(@7Bb!EGuRy5FzhN^*90rTeyb4ewsQo8M!a%Y#f zcb|;Y`$})=%n$wo)v$F{1%3u2LiB+CeCe&nVuc^!#QcGQ*;*iYLNAuyb}Y6^TT2+= zv{6;rZ{iF!vGX4GI7#1Ediycu)?GCTYf+(>P|9yRhEjfig3Vq70#sGr2xWHUIdA~X z&|hHku2C%-Q_Ji@nd<BTSlR{(Gr7*Ad<BLIbiM_!Xmw|duc3&WiDF*44btzzc8y01 z)w0391w-J0;s~>=p%+U52^^Hyi=)cBLr%q>jp-`!)cCIi(o0gSI2QA?>6i^K5$8zK zdU0GC4auNyL=9E?h4YEQ=bwDy`LBQQ+9QGcgn`47GXBDb9;S`rL`O4+&E3cILha&Y z+mIAV2z(Ac_w+N@9(m~buYc&-r@wvep${|94fykRFv~E#b4YTSHj4!|;I@>Gz79V3 zweMYf=o`;{;v-$kZ`jT{48BN$7EdY@VeO-`;pgBFzxw#I-+koyZ!!qd39zYJL6nKs zNG7RMoQjoGD5ogmiI|ns@wX&((G;0L@%0jcW{x~kG?=om5$m$@dO#F65p!12jatd~ z37cyY4;-^}ljUl6VbLunW(0f^KA~5bp|p2b?o|dUn4+O7{l#s%9l%t<lL&ZJmHrZ& zOfi`6XW1bM{Uwm}fnXXHx=-4H4b9LGviS^TN0W3DbO8P39a_H<CK?20dY%J`A5zAF z2~%LE)NCWQ;eeqC_ASg}<1FBsu1M{#37yq5^g(7+LuRH{=!a_tGa~T;690&jL*ns_ zFL;X-CikKHP(%jxB>gDsv^(DOV1Th<xRr<K$5>OSDxr|`SA!RJ)&^7iRpepjE`wRW z?bJ17+Q(UE?E*c@(Fgq}LP%9?$xrrzgsJ@?J;EmcstTG0+ls9l0KH#Rrn)y+d%k{@ ze?7v775$B#_#m|(mER289#$-BK<87+NOxR8dOu2^4k?)p6A}GZFG@jrKT5yN#wQh= z&p^rb%Tb^ConC^tD<d{4_WD@BKNGSFeL?hhd$Edniuwq|??qIwdY|n{<pmi2`yrJE zV)=t!R4}z4iyjTTRs$?;l|IJIjV@x&k~`S(c-T$AwDNU?@wr~zB+Ai;D^IY&7X4+6 z7}*4RpJ$^)7d$PQ`jGrWC`k@!qW<|}FG&j0`?2Xup{4|*Fw~S^?xiW?EdA(xMR_fB z4^@TC=rcgx{b4|`Q#<bD=~LCOhE3s`SBPB!a$oD!6j6>o#GVX=0)}3o^mQfQy(_ci zezp8YsI#K3SF`PPAoxw@l<3l`?fDR3TkrcLW=;Xq{3a~W!05L#sQob;qUT|fPw1b7 zf)uZg!YjX}+=6w8AH_ZTPuXawIaQZ_o0(LJ!95S%gTqPs9cB+~m|jhdiPP^YllZpX zP1&BS5C5O?S>F!47WC<D`phn~<<EA;@b9^-vC!86z8Cs^eP;#bs8Tww`i-WkuUq6O z{lTdd_YVyG@15{#$}lg_OnF)v7RG@o@DF`gTNarftbn1A+8}1N<`v4eWt;>D7x=U^ zD+Mbq)keXyn<ocn&_OYk_Ken&T{9M<Tr=#Qtc9l1?Ded8n!TL|!A@{M^opnodjYb# zECvM#4$tc&-lxMh5Wx}MG<cw(RVjoQx@E%rod-fT2TQf^Useo`I81~GOXxNegv4Gq z$$<ofr*noL6x9Teg;6&fJZy-YBxO|e%w(oKma62+<EfFXmQPJgkdaiD<SLUR+9V;P zl}Ma<(4xDJQ*MMbl3~|1J{}2qJ=tu6TZ&IcL}(3M7qA=F7LSk!VL)BmOo40fhP@x0 zy0shja+iSH^TyR3MoRRx3aP%xp{zxNxlJB)JL+qsQqlB$mZUVJLQ*67vB{J+Ihjcj zlF=rNJjrFtqlfB?+YCEYUx(_8r-KR^I$i|oYlB!|;Baa99UWGw5TiVi8%>RkkLOY& z6PbzBB$>>mbZuNO=f`p+U)BzF*r5*Nol75@U|b#aMWe$+nr0A=!KLpH;B3M$M|Jk} z>AB@Ko>$|#R~qAUhg%|9)0_C@#OCg&b?YRZ&d8I)$J58zw+SJw+)@Q~Zt?WenT5r( zJawsFF`E!yMIboB1DO@zM{7lPes=Nfh1s)nJjkxpQaVf|L?Jr8w758TdTn88kq68= zAx-pGUKYrs(@RUm1uoXK%x0KBW_o92--~nQBm|<dkQj96xXqT*dzss`l@6_u77}|h zErhk|xusREE*vwgFp<e*#7Wu8-2B|i+zO9~h4GZ_$Z(fh=s--H5dH-|a#0=P!t&Xb z*)wzM!s6=O=?g1!>dM@EFU+m3t@3~u<7j27<HG9PiV8Yok*i@#_7&5zwDhQ)krE|M zhbS4_t(}w>AX>qa;DNNXDk)Mnqh|B!SW=n=uRpn$l#8a99?Oi%Svfl@C5q?PO6PIQ z-8zxZ5`EoHO7{ewjdV5#lvlNi=9qB-A&s&;yLJv5V}6N;|E+Qogcb?G1Ol;gpSrrX z!a2GK0kJYyT3VY^XV0AB>Q`}x5(#E`X@yHXNAtPds30J$x2mPNwR1~ncx2}698^Jo zHd#Hrvar0SF3y&?1~V}j=2q?jwZV&_uIXi1N|xCIsYpP)aw2S00%eMfSzcLMTROdT zo<~klE2lv(isZ}c()`-JvnyNzvtsM(#FMgeP977239NVs%(4v7@I3svdgtw%x$%?x z4WMqBJGihxoq2WA0jXh007<YM1X5#mW=L>b6xZX;_z(z>q1rs$-zVFJK-cTA5PCB$ z)B_&7$&NMPVd0&Yck&(#HFcvi4UFt$rJSEANTF<-%|Mh2p<u>iYP*CrZO4l;q6UlP zxT=xpF$M=jkDCy13NgG!loos*XFtLBD5vXMs*YhJ6+FHnCKhDs%nHHLmoWxvoooe( z5$?{cy4H<w8%mfYMf;fAsiDOlY}k^UW>|{|F~oeoa4E>tjtF)-dNqe=h8w-96$z}o z_e<3_`=kaqS)hMJI{0iG`r6TiAwVhw0{KM6Ft4cSXjDzltP|Lr6g|(zP43ow5BG7Y zyK=-OU8co*CI|XBq8ohfv#SS%BBbEjFWYWh0~R+FrNN#$64#+Eg@xIx1dr2*o1`s+ zLCSvBBA1C3Va>PjfLQV4)`lzx#{xtp+6Xo+2p;H~V%D*Lsc`%VvATnC{J3O5A^06t z(}hifcyx&qk#EJsV#zvkv_bPA9;{nYaEIw|7)O-UR>rj}y%Pa%&w`lnfL-oN6vFgi z$9<F(d<MUxsx}=P`>cb3;!(cV+IpJ1Ue@BIHpmUT>YGuawiML)QNqRGOYr+r^xg)X z>d}C`T~V&K;?RAG1B=HbCejKCn4!8`u1D%BGCI!FMuN4HZi6sGghSg)w(qQZCxwh| zMj4_=nSY4O9D?Z5L{bb8>|3yPrphy@F}4YT!QvlZWEKhzO)73}YjPP?H-m?}r3$cR z6HbEQ6a?`e?p9=$)~NcN(MIAt+zb(D#RhCg<P5(N?BNa(VYnhs?`?5V|MYse84qi4 z?iLRRV-sDRhnwMngN%qn93Dtm9!?BsN7m}O6zAb)Q2l1rfm0M<w@wfh2RlJnOgq=G zCdT~{;KJR4pfmU;yf0o4x9O@6u=B8Zgh$+X4ltTqxtjn(lPgA6C?j0kcXTcdz2^8( zPJsKE`CL_0b6owhJxnRs6jCVk>a9U~c5G74jgH9KOjaK6wH_a2t&oXKp)fI?FN{r0 zlEPRes~56_^m06g^j~26L6EC$=G}vpLC!*<0zZXVadu=D8IOVC%j|SLo*vSw%>}MQ zf!cPqRM;NIX#;jJjAvhgL+Um-l{CZP8vS~=-T}a%M}ViD#H~X`PNHB>G!GV0>rfFA z-!XY$Tqn_Wb;oRa%<;y9N{HmPIRAJs>_t&UTjln)+b;yfE4{*2$08h#?b*6*@i0f| z>R5;eon{-bBEo}5`07}ASQGEAmVG*Hg~)pd`2f+}IXOEnXH&418g{gvKp!@Itv6*n za8=I0|6?-P4w;-h+RGByUx(OmtEL>dnRyx=S8!C*me;@)yRdX`c*+JI?J^y@DItUF z!3w8?Zo=T1gr4LueItAnIa<QU7uM!e6Cnjr?nPErbk3^bX&}564o)Zu&>>NnnaaLr zTJk&)4|#Asu$v7yd7BqBw$dpdg5==9ffZQjfx}Q(GiAqw`EMD6>u{F230`nK+=>UQ zxLL*yoM3s12aT}F1_OhhcDunh?Gelu-?3C&bm803f!+i$3KP}O0n}x;Nm&0WSZB<o z$T<u)bGT~9BW^D?bs8Kd{NhxnFx9;I)v0=OsnY<?O`=ZKn@63hH<3D3Z&GzCQq6+3 zNgBNSy>YvYkijbm72(nI`<$C}+)E$^et4|_PXz?J*n$g5@cbxtNGT7Rb}L|i6QIKw z%oo0~=r9Je<-n-J7|dvqA(-Pv5lDwIm?tAv9L8WC#$dX&!x+rN7)&>gIX{fS+@D>> z;+qd+FnN|}55ryJ(>+<p&0)9;9&~yb?t)k6^q4u{fN+-^yH+UD8v~sT7X)tbau1*g zchT<uFkfNIJOBcY!1O9U*OI=tH6FkbZ>iz&sE9>^rtpnLapQx88ukVc3-Fd3i~^9O zFA0nU7?vi7;XYRQ2UqvvzAw18c5)<}%}$8f0OM#I{QFEr#AYIZ137tdgHsP(zdt(^ zJo`NDcAbK{d{4hVf|LbeY7wN|h!{b_^-v!6;X-I|{5u|LET7k|Y~8zhb|Jb<Jh}m0 z%jEK-6I}xs+6FlK=MU1qSfPK(Zc&J?`=ftV`@yOCcMS~ucou#g_#pYRZE%HEM{B;T zEXZ_WX?GprmUlhdy^cJS109Z=xUnaBAD)BT|3-qtW4sTK@#fK)X(8j?Pr*6fZ9_xA zY3>tOVN1LTcXV=|;L^Tu8B9X2UhUD2LGpIzAt)m2gYl7E6S=4=Lc!pTwLD#+2M70O z`Qe3Vs-=|)M9L93CkAiZy`f;(y*4}u;D{->oC$(+M<D3Qf{R>*@Mrg3vOLHlsR=BZ zK*EoApc5%mRojMRGgJ-kecyuHfLu6=k_Wi3`9+Pz;vT5W@tA>1YT4evSm4wtE~_>0 zUR~Fg!h1w{nx>mfb$j-sFMRq(kA1773az5p$1fDfYU?zw-zMT9cZ8ysJokFu3Mrz| z`s}$+e(kxZzWCgy9{$m1AMabAer}!43e~q*q<aTNUYO5*=PS=X_0)BMS!3tY@7fZ| zjq>TIuYK$>VJO2Rq0&Mz{_vBJJp0rWHx^@m{_bz61^1kG@UFhUcLrBr^St#w*t;w( z!X6h1=k8m!e;3(=JvtVV;ev#&&Ile2ZIECGALp?e8r*4aTM}G%DM5%^M<3=v#0Gp` zE9hQQ&Na6r_>kru;2qwfECdytwT5T8agCtZes!(6+vQ@6PgEwmyIh1yJv&fK^=yn} z<`KkhW5NCJ+c@z)xw&;m59S7H{{HA}=l$gl!ambI3yI`T6E^0D`-pfqUq@FGMxVPz z2%bI=oey)fToD-KVQxLRN3_l^6a}TBvcutc#7dZLy9?X_Zdeiy36@hd?!D1by%-U6 zX9^T7oPhH*TI5EK_xNcIa3ltM{DMHug9e?4wRY2)aygwP`JMB0QhPbRU+|8|s11-` zxRH^EXTmrVAF;3}P6(A3yoH>n?gXw~8qZ}$4TFq~Xl0|E(MHC`^5wjiAJMfuOo{~x zHQyZj267dSUgZ_4NHEzI7ecuR;SKAA%UjWB9=kuIIjUS;gYzPBw>OXI3A(X3!U85P z4~l+sVLqm~;2?z4wN$+7n+H*#`bBiRn!N#LrES4UqdY(avIee%_qj~-oS@rLE}MMf z5gEvV$t!o=G}dPB(!YL?{>=*gTXu<gD4X=}V2K$QoqxOvzYe^_j8j&g_H3Ug>`%Cv z(Wdbp?wB7F)QmMa3kHwX=BfT@K10SUmGM+AN3_()Xaz1E%#M-N=*Z;Qc)6^PjOFq| z6g4bYc<N=-HMve{h$4LYg!<$l&L=yLp+EVFTvkkoh7V`I@No4&LIqJBTwyg8I0W)8 zgE?A+v>2yhBIMn?2FA5#9)0#Z9~A<@AypF>hOm2cE`*53!P(0N0fBv}aO84uKLD@7 z5dsDKC9jCA!l>(X-eK1^UIl%gd*K`5sa41J`Qm;LqCG}<)D^?qc{E5bmh^hg<1>OQ Z4*BM2UA-P{$mricNdIAl{-f{9{|{iB{b>LI literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-34-58.2919a1e8-b4f0-4b65-8545-3348930435bd b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-34-58.2919a1e8-b4f0-4b65-8545-3348930435bd new file mode 100644 index 0000000000000000000000000000000000000000..c3de7f22845c9bfc7d64989aecdc9db2c38e733e GIT binary patch literal 44790 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-41-13.a240c4ba-af3f-496b-b49f-edc5be6ca5f6 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-41-13.a240c4ba-af3f-496b-b49f-edc5be6ca5f6 new file mode 100644 index 0000000000000000000000000000000000000000..f8c3c698208aeded53475a609d796e545a19435e GIT binary patch literal 42608 zcmeHQ`F|V7b*FMiIg~h#b2i<|jseKTNfHDhkr72vG6R8R0LorhQMQZS0kGy`7qf>* zN@bfKZkyCi(zHphq_uN6N1OCan>uOJ`}zagrcK*VJ|8=2KK-S?^!L6udk`Q1nj8)- z`4iF>2=2_j`Ocd+Z{EClGxPozZ_}}){L-<pF;m?l4m}}11mCk)UE;Xew!dXG46Bu0 z-O}2s(^+-wM~UXSS>N&u&m?+wgER`=t*qMZnuex&hHbgo`f66QEzhw{6N%`gsrsgu z>2A>%$u9xonynN1V)=3SdJex!b_1zO=Q_6Tn`BN>Jt?=D&ovtph5S@*TxuF7kxm~C zrqkn+X;?%m&C!?0F9S%n?{$5TzEmzUe5UHUQethZOBNl+b`o=vVL^H_C3)&PaV5)^ z*2&g}?dX!~wEPaSJeR&qekHu@IjTk)s<uvFE`ReyV`FR4-%_$;yPo6_4RTAGYMK%h z<E6?cCFv4ZU0bGaTUm#=o?~bp(Sg}f#R~bEalj0vMTt;~B#}*`B{gLKxJ0ZQhGScZ zJ;e=Se<Bc}Dorp@QIm6*8dSVx+6~oodulyd$Oi?OYNw&AbF9uTF`F3$`Ar;Y7I=<H zQnM^Ill=7#5O}uTSN=q)SYQB}tYn9HzGF$MhCL*CMje;VoN4fvc`#lVCm9mx!B&eX zF7Z6*(k{al$g&60J)6+lL|bpzn~7BFWGwIHeTe%>`U?3KAn&fFcHOq^(N}KMlYvg@ zZruQ#@+#Sb<kc;&ZClbrW;&BAOZ)E4pntO6;MHW;Ax&d*|1YQLtC_~pRgciu$ZrM| zb>EWeq$?FBq(Z(tnJ?$zOD<ocuVuZz>8Ksz(o@&z>yq2_^-1<R>K}TSya2E78+ND| zhjdK(hJdJVY4mRSBoN){n)Ho<h6E9%_sCxcr4jVe*@G&|OeV8Wr5yLjxjscOdn+-Y zC`;$GKmoFPWZGWG%*-bsXJUT&5oP7lK#m)#X#lrv$IXN}Smt_t>GJZs>zKU>^~PQx z&4&+JhHiJkwwgw(KS%VGW%0fCKyg90o5v)~b73F@Lwq4fT%5nUwsh%{5qY9iMrY;X zsBD<RveZV<sRhYb*Va~+M`Q`ofC{wIHjF<w@XjU<Dq8zf0*P_SMJ@llNKlHtDKI5q zM0M$#x9MAwm4BAs1|p6_j?wHLX(YpymTila>02xR!n!8r!JnSt2(<LAZThy#zsmQ9 zM0yghB@_j_rlKUSGj)#k%iAm8lrzKgTF|w_yzu5ur-Nto2P*%@bQqTJIa_7=j>^Bw zQb>n^8ZlndAFO;!eqB`HrbfD+^x)dsYMDxv|BzqPL%~rEm(U-o{AbJ%5@fH%BQrBG z%Jg*QzvRW9H}92n8w?E(IHQ4z^-WM`QqpcTeHUyl0;WhCj3~!w8J22FyU5XdeWp`P z%kR+ppjK#t>3*k6-?>fiPs*=?KO4Sb!k~aQ0Zp*BIL98P!ET8AE2hrTK(8~yfu>{~ zUVc7Q6FtLl_B1|yKyIHH8#~rg!&LMI;aZB0`~EgfC);-&<@_MizMJ*J$SkDU_B}ET zf@8@P&9y<F<dc;LW%zrH7Ai~aLgn4^9Q<*wl!l+sx{^Fwg2@Zm9g^QQZB-|_<a#hQ z(IlLepv9eZ2=xtz=qY@WPE;!LDIjxRQ^5wxghpD5PFAk4=P-eR4!B_<v1F=Drz%zX z<&YoM!s*keX|b{_C&RyC;I=p1I6D|xlHJ?^g6hhp)0GuDAHLA`yly$0g^?hWy#^}% zdN!OdWuqdq*YGV=Ue{@<vf5YlOyxatDx?(Jn4s6XFbgA@=zUgOP%-0@-bm51-@dO> zZ$sZd3k`Y>8}vL7IOyQB+wP{bQPYJ6H=To~D+A?ZbGB#9hmkrHa^KCIGi@-&-MNfT zG}}R|VdqhEE=AvkO@2OEed2_CF{~u=oSE@WuuIyY^%Dtv6#d*Q`7X3~V~eT8kdx94 zgKXd^3sXBfUw!g~JiD7(hj=Ows{;hJMPPEres-t@)|{d~s%|nPh+e3EY6vKpLHR)D z+Vu#}E;6X6hk;tCetHNfCM*Nw_5gLU`k52*TXxq?xuH5Pkio&0E>=H#LcVVx%kVi7 zy;Obbg#6Bd+{jO*M;AxLFIPWzLOwl^UGrVf?kJkw=@?#=_rdDthXM)mqVE7_&Qb2A z>KBFpX%UOSd{^nJo<|%DD|sz(CUKp<8-yGxic($)On8(TdWB8PeG8fZ20NWrWf(!m znshms>&GJ<+LQa0Qo4eQaTWU!sv^FA6wMy#d)jxmm!adJI)Z89Y%;}WinF)2Q?!P? zp`NV1{#0KB_KF&GiWV>d^qg*>jZN38cb$^o-qRvcZm`ABpuiW(^lJ4Dr{v2+a$#=G zcN|cf8JD;&kjz9KkM%;BE4k2NTu_=Cd{uN}8Nk?ws&}7~$43wh^%RPnVmn}m>7a@= zFG(M+zVQ@eVgz#cZ&qY9f6dsI(o{h+>WT{O1?JC9=6_02xq8nj`TilL51)n8N2+fc z%nyzNMYlCY0e%J}LiB+CaP`fnVuc@J#QcGQ+51B9gkGz@<y35y_P(Kmw?<Jieivt` z$(?f8;}m^w^{uDmyLZ(jtVNSvM=8JO6iWH~l5F-G5TJ_uR(NMe>+YKQ&(R-Yg0E6F z8eALfL4#`S0hru6N;Ns+;l2rD21@!ae6+PQ>bFtojb!C)Ec0RYk#kAIYT61a-P!nC ziauI7C*K29&!bqx-B>YgFpt5GSg*{oWKaUqu7YuJH!E}TTm!}uM?uQaq%Gnp@!v@# zouZw}yJ9(L+D-?uU0SJClc%5k;1kb2_Sx@#_)Fh?`g7m;&`1CK$;ZF*)F)1lQ>$`b zPV8z<6o(OR7;0DMSyN)3-g;wUv-pvs-O2^9gBIZ5MftTr8mraWVzYLv4#naAJc@{u zlwS?$p{dVGq%IpRhS>Tnd5(I$vjg-JQJ)nOc?IxMVvgSMeZuB_gyq>_YBqKu(M=|s z1Y83?p<8T#2r9g%5A`Oa5=@a$m4Q(HXp%isz=a1*p(u2lO=j4@_G3{J`YRym$K^Lb zZ6lyD7(n}eRw*EY*5D>|Kl&3pWPUPC)Co+oJO>hgN-iKFun^j|p5Ac4Mg!9lCXjKK z1e$np386Q8j{Y<=Wg#Ey%=EFg&P+FafOLOGP9xoTo)r`zg~`K7{%k}66%+kA`5izZ zu>@|nu48u{1E+<N6I#Ni$Ry|o81of{P<Z2mL79Vf!PF7e_<81{f|)jmn~L0eT+R&# z9_1L0{TD(Y;DS`>heiRx)Db{F%%<6j0zDC%#%TB+lKO}|J-mJT^Nk?-ixDcU*+)mB zg47WNekp9_HkhM8;+N&@a5O>s2qGT~i5QlFI6gj#NRU2)$gjw+hoTiwSU|+}8%zfP zwO<Vccu>%GWyEGfp@{|f*FxT)hlT$7DBdvt%kU=ujfenN>JuXgjArg9Ljo2e_{~uS zFm(h^ek<%S78tAweS&H0Azh9o57ht3Q1Zb-@ij#7sZo+2<rvO}Pct_VdYl*?vI(R< zBTo$PL_L{?Q~PWvD-P+R8hL7ztOV&J`0}|>&4Do$s=3dPQgd;Z5v0Drh7|?Z6>yr3 zeEQ-jiQCCDyl%f8a@;j;61xeMerFWNqa4HOd?{>pSn&cPUuLG)5Dm_fM^x)~Lv0gv zq_%CZ1Fhd<6Zat^)SnMw_4TFSXJ#C5$p>AHmh#T%^9O9`yaW?rLjN!nm3Zk8iu@z_ zE)<pcQQSYj!iFtS_%8ipW>zE<&poat##8i9*dV@Pcx@%7O1~;k4wK0KT*KM@r#|ba z!EByBy-mNy2IJUVqF)ajg*AIax|J|=aErt0TmsY4K!!gPbrl!Lz*(IDZ?%Jua_ADl zFZo<91B<{3$F@6|^{TaQfj5TbZQC#)TkG(c@o#&M{+Y|#9(@ep^PqpO?W|m!l&e=1 z-|8CLx=BvbZ(R6aWo+!*{{tWAbmPX{IZtiC>N7AJ{-Muk%Ota>n_wlRH;B<{d*z00 z>Sw{R1imEIOv6e?%PM<z_w4C8bPSx!dV24hLo=46Tyv~UhWcEV70+JJveJ1F?5w~? zMMPED50Lt*7!)9kJjF-6&xUOvf+L!t^FTpsQV1_J(|~z14}^RHmPp~hycisDECvsj z&|M`6iM?)+LkS2^=L|g;iUFPiy<=EBY>1mAtxu{mllke%^mKE&nVy`O)YIxT`zTBn z8#B|>jj4%9oO#fqn~YO#gfx<FcT_$e2`QdzcEKIQCnF-X2KwV|%iQ7-5+MxesGDhU zsol2n!I|2=ZH2o8+>N)d?l4lKk5fqXMGj>>8qDqTpxaSjjpFnq(VJ80=5(=<p3E0X zx-^~B)B4P0uF#kO)i#woR$ts^*s=OLR$n|FRLIcr0#IKY!~_F}OT+KzFpbPiXfuss zdTMeSbXZ9R6KqPINUJl=Mqz4NFE*!3$2#m-hw;v(k4-SH4*G)8VIoa42!r6#_lIyc zVR)f3zp${ly2ev9E_!7#E_S>pf;78{PafFZ{j_7ArL(!r%(&5kNeOQE=!Rd_uGJbp zlRd-IOG4Vdr((+D^1{l+rRB>!HEi89x)AL|AXLGF?F|h_IJztI%a^atUtZ)vce9;d zSRTLG4jD@<(HvY@S*a{>LF<`kFi*+s&X~I&x5rrs&0;|!=xPZ^`W_Pd8MgaKxZR$& z_cd`5;Q?S$_~1&Nt8>K+E0=P)oH)5#t*yw9C<`mg%Zm$ZODoGfg11gc7roXuK)Va@ zI5R%g7B4N<7Hd3k!pO&dj^XC9(B+uzY_*xGC<^P<)yuW{i;K$Aa(!{(YHd-eExzaK zVtuX7gI<hpmhtdveX*v1GFj%5xT<~AFikZ(mB~rTs;U{5XS?mQ(h@{Bm=ZjYR_c-r zt0+o-LMf)Cc~~eQ50gg4@Ul}A)0v5)1VOcH)hoCWZk<S%VHc2{k`~$yFh5%?fggHe zauS@;xuR58o2p}kuZa^PSpj{zwpd$M9$Ku`Ii-6t15kxvTAg2e5QOB?3Xfd$3h=J* zA|c>FVr!2m^|c!3*eC=<ZLzwtwy4ZsyvWt_<1Q}}%<4*wtN%<*P34M$fG~BUR2SDC zT)D_2JeL=t3Ifz!eWA9rx~448SGmjpF&GwW(3`n2bX2VYOYRxAs4Nl?ubc=Q&q3QG zV_-yITUl7S!Xqa*Y-IC-)(1m8^_5F&56{=Q1g2(d>%^1tnL<WPSAv-d1e}>V_~Uu_ zbL;+lHw)8e4;qZ!Gaqtcs>3{0*?`ozB!DE?HUg<J3q2&bEu@F^)*piEG3=X%`v+vZ z5a?P57I*KY-~+&8ciDLeJS@E5^v*tn@v?4o7=oS$=jKGIEQPXdbOTW;hk_Z8sr?ex zwH+_Yh#D-C<CaRI#~APsJ?=vAES_Z$r3Jswu%F<2l+$%hMZ-{-CZ78c6ALm8W`*d~ z8yFl0XC(xQ5$?gPnmUYdA4-^BMth?Aso|U=*!-308euIW#1H`f+;2gqenhZq(rY_J z)!nG1UL+7ruve<OxkqY%lWiJ^NC&_BhQ59@VOWy_!A(AF<%cl2=+&vHnx4@iu+b@c zo{yW{ZTlYX2~&3Eh~IRX79W`$=;MfP@cV#WJ$NZX3d<D@+l_0$Vxgim*q=w@I`pN0 zBw3z9@Gy?JN%}JAq~W(ra)X!=)`=b-5Ho(<+mMamh=J&hK7w5n0wRW{7#-|i3Y=R) z%;8`hKYlZy5PU|}bYa6Go_XR#<a;r((7S;geb79JaU1q3xcD?U(IZOgd&jk#qZ0w| z$QLo;QM)meD1<Y@?)@k!_#J#kRfQ0B?6VGrzeo9cYwM}*dP9wq`XF0&%QvEz`chEm zM+w)0FTv;as9Xz<2C-nDSd^>pbr2=uG~t+*m`E=qV20vuxgO~#$mlpv9|_h<nhnAX z4${6tw(oCwXN8PzdIQ31nP-j59D=ahWJ(MW>|3ypro}U;F}4YT!D2dJU=|7vO$u(4 z>v9=YcdpmIr(&=v6waF96py3v+V`R};Q$<;Gq&m|z4i>F2D4oQJhKN6BJOdzfB$;z z84ufVtQHRkW8+zz*Ph{lF>iAVL;Wq-;K~_TCfIAwaKSN3#38UOc5q?C_u;&Pevb7z zJq3F08CJjBa^MgL*wz#T2f{WQ7TV7>5{mKK2e@!^C@2%YIr0nJYtI<4senGkefP>C z;*P|5?G0CXlpPbsBh}(e6M)g(D%=4Wx?Ca5LK)%OzN2vsX={!T?+NgPGxxEA;{uny z=#L@`_Ux3)qqInno-fX13R9D?V3yB79NO?&1X-J;lq;7@(-Y-lX@-=G&Ae956Eez& z8q$A`-627)J}1JSAj;(?{FGyjK9E^txC};@vn};JJ*0P-If}J47+0Jv1&_((o8Sy^ zj%WXeLpnA%%2ZwF8lOiu;~~JHmxHIl#I3DGj;~<rIu906Yikh_-!XV#9JLI)nqzc5 z=2hf@Cq#sMJexci_M^I@y^Z_Zo*4q-6=Pvbe-RGH_H4~Id6*+~=`X~C9>EP*?%}~B zeCaPdYKwOp(g8ivLgYP!d<ZkRkjYPH@@d#W4_lBQKnFd1?Q}DEGHoUY{}(f0P2>uh zsZqAU!8*i-+cGkN51pscad}EH?93YYnU_``4$nlvz1*{*4;C`G9xUHF=mQO&N$4gI z(>KCLk-sQ>e0A+ox)f3n<vV3nMbEPmp54M*;ov0P038yANp!~d3^Q{Hh=)8l3hZo8 zKQCx(r3-!&r~7&hR<Ypd8rDqtqA=$)V{ivfcsIb^fv14+U==s-*ntzQz44$CHvM2= za2dh2_$ESv`QkgKf-6dVJ8*E?FGgXa`Z<KU95yZ6dr~$S87OjAgUuW+N%Dx>3r(E{ zr!K!R)hSFq;rfQdw9@mSPL(@Lod$635Ou2DIqFoogVgC^oUli!PDQF&ur`UsyFnlK zHwhWMf;bo+4RXM_$-o5;V&I4OFYr|0D4cG=-7WF8Bs{SC<@aDSq2ox?=f2SCIMTG| zsITKl(`fx6nCwPzR>zU1XCqb|N17f-n!4@dNYmp;Q#X#RKaMm#m|e!AxQ`=Ec@}Mt zBVpomSy?pBaU={LQF|N-gO?4Bm_i3JGtX-z%<Ww?6zP_MPKGN3w|U(MP=tGh4<6Ji zY`q6Sz~QA{)8|^-7q{30IO2^%JRTLXNYE6%y(n&f*bp39&cgz{7YM@vGSQbLh6IdD zaHn$tu29BXjwj(?9==cI@wRL+`+OXAgMT~i@QBBQnSTi2Q0`vb$2CIP9}Efj_<0)c zsN=kRPdgfsLQ(1ysiGK>!ZlJJM&jaVaE3pgOP#r*-rRb)et9XnG(Ng3ex^AylPe7k zYUms5=wCcW|FTB^iru0S-IYlHy8Vp{c$?1u)#2mNw*fS4oh$e{S_iJP2-KyO-F0kC z6v))@I`YgDf*nU(!}ei3?mgR;jt?{5`&x<Pv)GT%V&~DBSs^3e_rYQ8eM3XQY3^fl z;S2x+E;!{pvZi072J_Kdw??#Mki0#3>Wj$wV9ey91_z;F@VZ}~t}udw2eSe3W;@vJ z)*ui)N8n%_ysG%Nf?<~v@gRURwcwgA2-uy3KqwP#!4<-v-52rlARE>J&J3UvDN`-m zhI2v`)l$tZxYEgmQ%iY(3!7=QS$yuHx*U%gD5qEL4U7*?U*NJ@14q`8wiI6R%F{H% zWNO&6?>+VL?>+gIfhq*t43zC2E}|eq?}X2QE2iN-u%Y`GgWM5{QSv<Mc`u}hM(?xW z&e`vN?D6k?@>6>P*vrE+SfTJn*#U~YFrWGA7oU0h=_7zS^u$<hlwbSWvmbm?7|QSr ztgKLs-}&%Io_YE+w-@8y{5{xE3!Xal@Lm02Wd`?$^OX7s>~NNrVc&~{bN4OVKTkGc z-;PN#aLdI|X9SOi)=99dkMjfx6)uFgO$jbJl_1(}pbzsPVgo*}74$G^6uMgy{E{v? zz&ki_Ze0i}I9v`7uj3j)vHdz~x8LQGpN7jsrW?auE<&ZAogk)oHbyt|2;#7@;C=7i zc;LO6?$&)Hm>a11_eIBTA1wE-P|)niw?(q43;X!PO-8(1w4)0qqu)cv=!2<`$f0$o zT=*E{VJ8Z~@iQHE<t%6qg&m8>BVWRd++E-fabK2jNU+4Ba&MfD>cxnlUsIr9;Y^&T z(IS6xykkYRz@r#!01SdR4;zsl*4l;hfJip4P4Aowl-|#M4T85zMs0xn!d;F$JQK)~ z@DkU3aYCrP;9c`PbyxLbzBJQlPBbP<rQCD_ZeA{FO`=ZBl$!A0v`~<IlkNC;i|3!K zaOf<rP(^|XBm}Dl2zgj1TyBd!CbWFRUq^+LGI1+7kLU@ye>!3`*t$F@_L>y)F~tQ> zAsiB>;AQYUhyv9wVl08H(!sv8O*mtf2Z%t{cyQM{myKQ!bfeA<gHJpnOL>>=n;E*b ztk3SHfAbjq+Zz2lb~k+}r1bA$(fQl2fJNtT!N;K&opBP&)3E(Bhl5Euv))wRlMN?| zg4(kUC&u8(;yl%#(MuCraWa?A<=_U%$wo;{H>UMQTAwP;Oy%+gycSo;xCaXuo^r!* z4X(|{QTWeu#Q_z@rHNv(P%4QD+JM8TNT&e@9r77d;*^FDN7e8&@1dj{0#3MMf0}T- z=6Rj@fP{z+r>P{QY+jS+*{?tG%vV1k1cF0a2CiA5p5a`h5s!mY-3S5#Cwjy2*TG#4 zyqZr46zrG0B2ouCzyWX9F6*Xm;0*da_nJJyQ(BJg^F=2gMte;1s4Iqd@FbH_EE)Bj d$E6FGW%A7$hx%dqkkNm5jQ(Sd{*&)#{vUdHgqZ*U literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-41-51.0aca82ca-19f5-477e-bb53-231cd0676262 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-41-51.0aca82ca-19f5-477e-bb53-231cd0676262 new file mode 100644 index 0000000000000000000000000000000000000000..47673a14cc725b2580b9e762fba4e3bba5de173d GIT binary patch literal 42927 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 X4*O6)%m8NeA0DUwSf~Hw`|1A&E>G~^ literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-44-19.6909fe36-2c71-4e6b-801b-4b10c6639104 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-44-19.6909fe36-2c71-4e6b-801b-4b10c6639104 new file mode 100644 index 0000000000000000000000000000000000000000..4f80f5c87d2da2cfafd4814ee08543e75e8bcf94 GIT binary patch literal 42912 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 D)i@GU literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-58-28.cc9c6866-9411-43a0-bfd3-f5c184e91df2 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-58-28.cc9c6866-9411-43a0-bfd3-f5c184e91df2 new file mode 100644 index 0000000000000000000000000000000000000000..cc05020f4e6b09ed48369485a788783e90c1af44 GIT binary patch literal 41960 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 P@XJr&e=OlwJWu?8kp|mn literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-59-26.5cda7368-af7e-4821-9551-e4a63c66515c b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-59-26.5cda7368-af7e-4821-9551-e4a63c66515c new file mode 100644 index 0000000000000000000000000000000000000000..21ccea345a4c703f3bdeb331d45b5b77cee7d8be GIT binary patch literal 42247 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 DOH@7v literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-59-58.c999da0e-6456-442d-8965-cc2de92f0a24 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.21-59-58.c999da0e-6456-442d-8965-cc2de92f0a24 new file mode 100644 index 0000000000000000000000000000000000000000..0395b8710967681d733189dc1b57bc8232759a1f GIT binary patch literal 43499 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 U{+B+?@IO3=|FMey$@j(o2Y33~IRF3v literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-00-32.059eb584-594d-442d-aa10-39e01d88bd38 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-00-32.059eb584-594d-442d-aa10-39e01d88bd38 new file mode 100644 index 0000000000000000000000000000000000000000..7d90c2266b0d4c9fef74776b0d1f86d444fc1b5a GIT binary patch literal 55507 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�zh>;mAIDuw7#?XO1&(!v_dzJJO$;vkya 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-05-37.47604380-9ee5-49b0-9cf3-91702816db8b b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-05-37.47604380-9ee5-49b0-9cf3-91702816db8b new file mode 100644 index 0000000000000000000000000000000000000000..1a9fde1a3d607eadb57a72e05115297d9ddf9279 GIT binary patch literal 67083 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 Q%obW>wonDXo6W@k2Yt84tpET3 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-06-39.dacbe8e8-e39b-4bfa-9402-ad6667d992a9 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-06-39.dacbe8e8-e39b-4bfa-9402-ad6667d992a9 new file mode 100644 index 0000000000000000000000000000000000000000..289b83ae0a8727e490d3f561ac8eb7f7ca5f067c GIT binary patch literal 60710 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-06-54.01d228ed-55a4-482f-9d85-799e46d8f496 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-06-54.01d228ed-55a4-482f-9d85-799e46d8f496 new file mode 100644 index 0000000000000000000000000000000000000000..771b4b6ca708369a7d955c11474fd5e5a37de8e3 GIT binary patch literal 55382 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 U{nCS(`EOq|f3$7>xZTeDKjykA8~^|S literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-07-24.9e28c885-9705-42f7-a586-8e8bf33058fe b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-07-24.9e28c885-9705-42f7-a586-8e8bf33058fe new file mode 100644 index 0000000000000000000000000000000000000000..2716ad179974f994cdea6c77dfeff617c8ddd9e4 GIT binary patch literal 45865 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 IukR=SAK8eOxBvhE literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-07-40.0bf85b3c-af57-41b9-aec6-32821fa6b25d b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-07-40.0bf85b3c-af57-41b9-aec6-32821fa6b25d new file mode 100644 index 0000000000000000000000000000000000000000..1497105351be26d946722a4e4b9e443e87d85088 GIT binary patch literal 56404 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 SGxOg*ZT`Cr^WV4Ing0j7F>gcw literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-07-53.849ed3c0-87a0-417c-8c75-9df7f330e7b5 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-07-53.849ed3c0-87a0-417c-8c75-9df7f330e7b5 new file mode 100644 index 0000000000000000000000000000000000000000..e495597443bf61c5f861b106097e2a7ff452d09c GIT binary patch literal 60671 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-08-05.1b7ec789-952e-4ecf-bcc8-60b1631f8b81 b/web2py/applications/SP/errors/127.0.0.1.2018-09-23.22-08-05.1b7ec789-952e-4ecf-bcc8-60b1631f8b81 new file mode 100644 index 0000000000000000000000000000000000000000..58e77b68a433d87bbc2bf37f2e69ae2a438ad832 GIT binary patch literal 67129 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.07-30-57.f4714898-671c-4f2c-8b8e-7a6b8c5f06ae b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.07-30-57.f4714898-671c-4f2c-8b8e-7a6b8c5f06ae new file mode 100644 index 0000000000000000000000000000000000000000..f00ba2db39b44ec359c3932bb129df40b4bacc81 GIT binary patch literal 45128 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.07-38-42.099ed67b-9672-41ae-a0c5-0fe251bf11a9 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.07-38-42.099ed67b-9672-41ae-a0c5-0fe251bf11a9 new file mode 100644 index 0000000000000000000000000000000000000000..620c16ecbb7d66b8c76de95f46e4e0231eef9aea GIT binary patch literal 45044 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 M{)Za=$1qI)AF-RyJ^%m! literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.07-41-04.1f8690ed-aac3-4a21-b1fc-57791e303d19 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.07-41-04.1f8690ed-aac3-4a21-b1fc-57791e303d19 new file mode 100644 index 0000000000000000000000000000000000000000..650ff85de71c69a6e365b33dbb305e730e87b636 GIT binary patch literal 45044 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-15-41.ea6d2041-094b-49ef-bc93-33ecdcc3e79b b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-15-41.ea6d2041-094b-49ef-bc93-33ecdcc3e79b new file mode 100644 index 0000000000000000000000000000000000000000..1498082f560596e1dffb5638f2ca1255a711ceb6 GIT binary patch literal 42021 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 O+T-}^75t4bO#eTe4S{h0 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-19-32.6fbe9345-a360-411f-8c29-b534cd8690e0 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-19-32.6fbe9345-a360-411f-8c29-b534cd8690e0 new file mode 100644 index 0000000000000000000000000000000000000000..4bffc18c4fc31c5b6d7db6dd02888890a09ff130 GIT binary patch literal 78770 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-22-40.023ae398-07f4-4b3f-90a1-481b3c4b3c00 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-22-40.023ae398-07f4-4b3f-90a1-481b3c4b3c00 new file mode 100644 index 0000000000000000000000000000000000000000..bf557dbe2105be134f81ec1ad55b185efa8ea615 GIT binary patch literal 81567 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-24-42.f7b373a3-4254-4f43-895e-c6ec34004a4a b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-24-42.f7b373a3-4254-4f43-895e-c6ec34004a4a new file mode 100644 index 0000000000000000000000000000000000000000..ac7e5e2e8a3d4c8c93007933be64d9986a3a8381 GIT binary patch literal 44056 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 G$o~(-Kuh@m literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-29-03.1c9b8f34-d7c2-49a8-b5b5-0e2895e4db4e b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-29-03.1c9b8f34-d7c2-49a8-b5b5-0e2895e4db4e new file mode 100644 index 0000000000000000000000000000000000000000..5376376c082603c2397385b29b0e9c0e8f5898be GIT binary patch literal 82313 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 a3GU7s>o4T&Q`|oMG`A0*!tYKe^Zx-WSGZ{a literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-32-42.0762d17c-76e0-468d-83bb-acbedd3e0e39 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-32-42.0762d17c-76e0-468d-83bb-acbedd3e0e39 new file mode 100644 index 0000000000000000000000000000000000000000..dd9f905a3c594b5d34b9545a9befadf3130501cb GIT binary patch literal 82478 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 Q+wci)8-5JGyWQOX2lv(BzW@LL literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-38-19.d804f946-3776-428e-ab85-8abe4747f2bd b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-38-19.d804f946-3776-428e-ab85-8abe4747f2bd new file mode 100644 index 0000000000000000000000000000000000000000..067f824a2c7186f571f3849df3b7b9af71202555 GIT binary patch literal 82341 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-38-46.857a877d-3dee-4bcd-a2fa-d0d3eb6988e3 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.08-38-46.857a877d-3dee-4bcd-a2fa-d0d3eb6988e3 new file mode 100644 index 0000000000000000000000000000000000000000..536bf70dfe2eccd2d7646796af0ab4582c564d02 GIT binary patch literal 82349 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-10-54.00af0054-046e-4db4-90e7-bdec8baaea3c b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-10-54.00af0054-046e-4db4-90e7-bdec8baaea3c new file mode 100644 index 0000000000000000000000000000000000000000..b537c364a40a5764b3422cb536963f6529e7ed46 GIT binary patch literal 58035 zcmeHw31Az^btPr_ly7@{#CDP%$Qpn%#KoHs!I+XLjSPX5NoodKN$E6z2GCLijlOtD zmOak+wzJuFl3nk56WduQ*(5vTBpy5Cu`_m#z3(gcvDuw-?<;#{ulK9E8x5dA63x~~ zvmr-A0$tU=e*OCO>(@W39y)weA4!y6HZn4zO53ubA1bZlbNYfQ8)mv;Z!2Y`RZpMa zt~4a0dEU^j$`#8@+bv76RJoeol*{Ao?X=Wxt4c+(6s={Z*UqOm6nWE3*X5RMD3w&h zYO4B6N-qWAidL2N!=)$3Mn(+TY@@oI+B6hPPQ>T$KDBak{o?s0f$A?@Zq47FOkPrI zLZWU7XP1Pz(f8k-IJ-1@Wq}G7gn6naR8+|{^RbqeylTb-Rch7qvG|xEn-!@o=TA$j zDUTlMX=*(sRVs4ZlB*)UU`usb&<r6ix8i+u<1w^^_U7-tB)6(c?FyQ{+!D~bELGVj zd~V8?BoKv6*~-UktCpONxn+1)*xcMqwHs|kuBIwlGhNXDiD)IMNqle0Ez3-nRjqO@ zS=BaMswP#<wBR%Z@C0H}-ITUXp{5xX8QrvGlM%%LQlN3GF37FA(vk@^=O-a=$Spyk zf0iM&WNTEoM>yFqw5BYaHl(J%?yB6>He|tSD5e04Z)>(-oAg~4FnUBS)AS+4`rELq zc2d@DWg{OeB`+){PioCJSfH%RF#%n)(5-yz>{4E?*5%!Xq@`Jc0buA>N-;&yLQ(~( zRTbi66^3#?8)st_I6}PFj7~yPD=VrjJOB=CYlbD9R<?XZ5w511?R1mXAtq&2?h&fe zhEgq~&4y;T*cgpxvKhw4R3k|pwxqfrP*vVgDspmDsalPkuu`em?QNlEtE#{r30jSj z&#V}-GYpm~RBQtyW}znv{;>JthpDu{7GMf6FS?KyvZ)NHVo6HN6sijN#H0y^0W~df zA2o4Z)0#B;nr+d*wTYD*vQlqY!h*n2biVuB!PpwC5eb8ZcD7|xkW^LMG#SoRELa)? zP7KuHL^kj(@J>GFQqMQmtmAn<VaD*fuS<D!$eS2Uf-LOD7~a%n)rkdMHu1@v{#iSp z=HPj+8D|i`=F(}Pm)e|2X+}Lw0%R)Pl#FXOcmi}zQP-Hb3huM7$s|?v^?mn#aOU=b z=*QZl4bAwqwk%y^V_Or>Xj)yB$AqfZx*WGi3e;tbh6n<OW~(8XkfDOz&iRJf>2RIB z%a|I{x+#HojK0at$COu160GC~#7fPP>Arq;p{TSfs$G=@)7n;Lvmwi1@eZ@7O6wX% zOU=hR<uRdQ$hCZoa5FI)m1^s%nX0IoU9G8-Au}|ktI}3lRmx_%1~HP9Hf0k+D?OQ- zNoCR%v-@!h{GY<ZSlX4iJGHypFkM(Zmx!A*Gb{12IJH&QG|PklZMzM{M*{}#7B$Y7 z*QAHTB=vO92s9wNDkK;nja|YIM*yV>fdYC%JOV}vzXBT<tZgi|F;+Xhm1OPpj|Q>6 zoU}B%(%@AbUf35(?N&VyCAWFLcB;aAr44DVVkm7(kT7$wu$48-(wa~ewn!JCIfb<Y zi)l-_ZU~zVrP9EfN&?dK&8hp>i|3{US(VwMjRmzPOO|cOkhK<RMn3k3<fqn5qq4h3 z(#>{PO{`E3Cdu*CY-)n>-qqldUzktxru<z#%}30K&u&zX&pQb7v9#nZD}5D2<4<Eu z>EeV)r-k)~4E10`G89H20W+5rhN@8BX0+veE7C+3X$8Q-*s74mL(7S;Fm=@w5}el1 zJV@~&7&2C((G+iNH?$Ym*3O<;e(zf1$mV#PHwaFxDMnLlLTRD(FfXhp;)}qL)Ebip zi#}{hScf4&s~Aj(PNw>3Wm0dyCq6pXfmT&a>Z7=+SdDIw4{8R<=Ts`y{Q{IT5!}=S zpRuNoT}&QpCXZG7YFSv)18WM$?#~@7=8mn=D~yP;VQ7XpmB|puR1y7Y3GA7mLGv)= z>X?AZC1Fr5U4qC3A%$b+l`Cv8NGXVq3daQEGRdf$d2b2DmoXZ~&LgZVB0U&A5+LT> z@rR7}G2P%HszDPoQ&3lA!%Aev`ndcm)<k0)OwcujyWYz7yhS3Jw4+v4GWvvJ*PG)# zZ(>$?FYeUhME`r7V|(#*RzEO>B_(`og8Q6d<1cVFI+t66Ddtq+IzLy(`5J2q9<jy* zUq8}B1g0r_NOok<uI<o(&ZoVt%zRm^Zo6Wns%*HsE1FtZp3MfdL<}YWoy5#&DwtxV z@b6uZ<8WxZ6`;z`r_rj50EzBpX`?I|LVj;Qou1FPBoBLhBpCcpQf11q^F`ijW0R3= zLg>_!H70$o+NPz{wy`l|JD6kzin?sLY7h2S^OCb}rJ)u%yHD0avW#t3Rj4Lws=Os^ zCZ{q&(@09TrNtJW{lQ0`ed4E{e&i>g`uZ21d+6b(KlP<&9{$MFAN}gH-}wA<kA4yV zp8oh}=F^hXb!w$-V|i-zv|wp<=z&JeS#Wus7`88#goTyL^0A7hs#4p8a>^fL#?!9! zDDU#Jv~kMN+O*G%L2N4$>!_irw25Zj=&!-4Bv<pX8ttc@_f!djIv-nS%@TE$I@{3r zNQG{gAaHOe95n%g1XX+;PxD^+p7=PCqX?XNAF<DLK5QnlnM_PjfMkC+I<SC|-7y;Q zVMBe47G4*29eWH+-<%@FL4?NKq_xf4u0TJqX}5CeO6~}4$h`tj2+&jh(+83sV>bsW zmtc@b=O+mkZIapdOA`)Ms<;#6c~$WdKgqBRY|UwrL(lr42elw!Dc|Vd(o<FUrwywN z>o+~<#juM*P>vbZnMjzRt!o3dRTq8_NRIdTmC+sA9N6zbSeYGQbxl;lADb0Fi}mve zp)F(Ta9*HqJ&nfs(n=+O7cgp7chYt>6hu40t?EdGTR_Whf#bI4$c2UkyI$LF=VO*( zyTYPZg!Hc$yz700;UhcDXn-a@f#D(t6Hd$SWxRmd?4rSDwP}~#iQPZ%sOC<iNaY>Q z_V6HpyADYJY|%mHlAp^1>cL<+kkbRIdtm(}4yYIJWqPW!V?#TN06)8fOul8G;L?-5 zOew1AHM7%L1R~1b9Q@XN+9oSBwLw39ARwUQSlk<NlKXX4D`Ra;jP54wyO$qVDWN5( zsWM$*z)}Q-x0`!!jgUC%Y7LGu;j-;ebGt*d0i>hHARkdLMaIT~V$rL?EOT7C?<_~3 zd-O}sefdLugT)cqBexLy`BX9X?m(H+5w|2^k_M@l-6KWs2O_j55_GK$1S+gd>EU#? z8LP@Q$yP0xx|-V!*w|<vMs3hfPyL<bN>5d6x1W0aXP$cEiD!T0)6f6tkM9JupU?wn zMHtbHgO{aMmqnVpo0?ILGo=U<kZ}sEp%!-JCj2|h6(u^G_iBg1f_m1=uVE=10K13E z#O&$bF8F930AVM(2UG{`pZVNl&;0P$`9yg7%O8FIGe6-Ufq-{zscgSh49iHVYIS%% z{N3we#hs|vQx%kZ{-KAS{@4?a2=NU|PtCp4YiC&%72oxs7sPWQlmhQ&M6)|W3K2Wf zyf);zLY|2i<AnBb_t7_KnhmF!(M<l<L(e?+jecqe0Ut_|5&%ze3WC<lnt|&Vy~xMT zf<JTP#VwWLXYJ`k<fHkCC!hY@kKH+PdEl6OoY5m#dQ_2Jwf5aKXyTt8m2iIx^Jyr_ z(8oDvGLLQ%zD%-R?#(>dF%I^1Jh-2GtmdEs9b|7tO4RD0!d^ZB+1KK}d&lbNtKi$q zQXygi;JdG>wo(<E_`=M0>|sag+yml$RbsIi(e@&_NDu^}R+(Z2Hxz84+&Mz#?38f1 zbrudqlY4t4ge7nd5)Ly&IY<IU1yC`Ws@jHzs0uiAXfMs2)YJi(8ezeNPwjFGZT5!d zfW_t;<NZ6>-VqYwsjHgON^GSN=c8DXs$7>7qpYPZZinOUcGvHeG7+F;CE_C1K%c4J z4LwSu%>c7Jgd5r5yvDg_B%jX?+U50;l~~++ows&kY4O7P+0z$$z+P&><CcJR!00I$ z9lhd6q8>n?RbP9u8jSP8tw4G2Xzei5`?}EIOL{wCThLR{`)X;L3WGn`0krU*f~z-0 zr-<3&0v!;JbaCtv{M)V=`n@%s8Bs&v0ODvm@es}f$JFV5>z>n{N$lTn8ro*3019=N zOi<yzNM^_V6?&_*x7oH-Xd^r+sme8MP<QJTw2zaT^B(Dq9vxi|)jdbE({soBH?}<$ zT~}jE+e~fClF<*zFXZ`1v;L7KzpZV`@NJ&h_B<`D2Z4L+J#^?i2L~s0P>;G*9_#@- zktzsOp%6aD!&X5EUu=PY>D9V=JJbE$|7{+@EyN&>iD@_Vowb*(7x2Cd9oPJB%Z`r& z_Z5=h1)-$McB_iDfC6uN9H|a-AX=a&CShMKb5i@GVD{MT9*Npl%`Z22Oq3`gSaTau zL8hoU)`T8L_YcsbTY0y!VH(3;2Z$y|PosSvbq`J7=mflnZSjB+8W8>APL2+IC$Nv! z-5YM{<v0&i6FdT3j^}P5c&b8y5@)Nq%ke&12Vm!QGJy7c2kX_~3>S;vbWylDdYpgk z>0hijCYahCsC>>N?2CEA;T-3|$h~;$FD<<s@yxJ3v~5d&S?PX!nP;M1h_53WYKa0i z;tRr7Q^i6=esT)s%VGc#F$<X{v^9j;u^3>uVe2-<6Xk@sDXX=({_@hR0FLM;mq9!I z6{Vj>@btR-T}U)Fg#Q{c`KBotKt)8bX))XLX$pRg4I95*S8c78234^Ksvs^p)!qid z;E9uk@$4K$aT4b_h0H=IZ^@NJg~GW(*w%((Xf5gj4No`}e1VYzLdac=vJ+W`(LA(M zTa_0=H_3bLnC^XDo}8Fu4KU_ny`^DE5lcA1>Xs(9;OyRz6Bu6}Yn~u)J1Li83Ba)- zcJrZ<9iL*Tc+D_$uvfK>7NVEL@-`yDS<@-TX%RO+H=S{tXALK65~5GEQA8mzl8CI) zXuCW&HO|^3*sRfthUUs~N8`Wbks^VG7#Re_bxiU1z7o4K^t>k~^X7(Q%)oJRk%Sk< zw5S>4LII??^H3e0g*^F{3njje=&vlj67tJzAq=IVS^BGP>PL8vNqZY%#rmsD7K+br zTMY!bOi)yBPS~@=LOx2m&0kHl5lgIW?fvCZ{WUBL1yfblUt4-RuqXnBHMuQ}PYRj2 zTsD)NniLTGKdZlv$@dy1N|^fVujp?`+|=KgV6W3oSbtOLBwpV$+FXZ82MAjI%^WBq zB=x&WM*y@VYW279tQm-S{jH@(UNSPmWo~|+B(K2Z6_J0!1tCSYX121~$@1L9WEnG; z5ao*jf)w|dsN+f5g)YIKzY$-I=LC0&WBp)}@~Oo*YQ`6rFN!Ot`)X`pXAWv>hM96| zu*y!*CRKNL=z<%`$ttwlCn<`v-d)3e%Bqm-wHG1U-=QTcqB<w~DlqYSf)_gb@Bww) zQU+(`)WreSsDxEn9Z+GF7hhOkUs)bdg_i*eM(HM&T}s5t$A@LD-4{^kFedR$-iY-m zP`f5y0W)8!7HL?!t4Og?{cSw640?pAzx}5E9f`uPm);2uCs_$4+ow2?(P$aMJg2{- z@EdGqQXTs7SIP@FZtCwW{ATH>1H@N&DK3h{@S+&M0x8VX+1^$7tx_tuE~Pv;b@66r z&f%H<orT|KB8=L%jP0EMU4`E%2@V{F)ByEI|L(%?mfqkt$Ro?|Utd3;(}lwCm0s(E zU`UE7>vtD^-y?_<h`#D6T1<z`>9N8el$LyN9z_}mGqA}m7{5%LvcZIeR<7B|8?xk4 z7W9h@BN!EtMAZXMKWa0PqPFa&{%-V&vhu2Sv#lSyso#?*y&7N3wxYt1N-CZnXJdhA zL_A7jUG=6bl`iO9tTR1OA1zh!@(UrE^m`eezQNb;D>V*{j2sB5APIdUav`OU+4fC6 znP|M}R;7!k8h5c7=&o&gy7AT$*1wU&sGey+mShu!>!o|}pjVXf?O)%1ZM<-!^!UK) zcfJu{pD4V)6btM?UtcE+H%ptSdYg>;`c&Zq1BNEZxUWwaK3FOS^lV>7eto9!P$?b& z6<hisW4}II_)zH`s2^-VC!@bUSNML`FIoZm*{*LGa)pPPT_B)(C?|k^yzt>++Mh3c zge@*RI0f{4;iJQVTqu03gxu|sy?1GJRR5mB$A@X-J%vwri!WJd^u@v__saPv3ZE(^ z0tVeR5A}`F$-<|ZBHuHd-q#_V3HqtR50oYcHtrgK2gs)-yYcSA!wsy$ry*L;kZ64m zU=6DU@(o7ErlH>tK}zZU%$T8{g%tf9z9ndXoS$EVW=<(mH(1W2Z9+jE&tT&aC$}oR zbohQFUP?NK^CYD@LFHDZ>)Y!>{1glxWlA|(tilwGeXzme|AhoJQHdUn#usivt0luo ze%`lZaGBrPzo3efuD_0e;Zgm)B;E^&;v<Jjz;r}ESA6sko5{p<@HYzF=tn)^z`Nhi z>BZug50&1ESLp@%!IUP4ByT0BFBgCAkjId`hQJL5J`)eR<Ct{xmEzAI>eAg<SdV_b z_zQ<hGrndB6tg?{!0cct(%)D7%Av-&;$w$O-{nA|-tm-vHb7&-y|B03dvAF(r>_>j zdZ?7~wN^tWKjKbdxTB=mHZ)(*T~J^WL57ZDw?y*ABKuBXD}Jqy9OTxNMv)^vp3~RC zdFTqU-UYtFrB3J%aCPnlU=jU6X7BV!r<Y1^K}Y9BMN6&0=m^vCipwkd#nS6h=GEl} zIsH#DEx)6tA}6b%RXL|no_rvvOH5PebA^m)+@z;pF5N|~dz!9SvY=n_zu_68^zZF? z!z)?PMXq3D3h3WgdKbanVIt@fsa0i~`*~CiH}@S2qF%woCo{5#j9$g$PvZ&W>s@A~ zZo@g1=Mz$<30X@Nw!B$LoX%?G1g-5@u@i1606%m?uNSsUuRv>57mA49C|qxxgAyh< z&yK=8VZe-y{T17>08ejsp({{!CY*|xy~rt$EN4POI-x2O8Y$U|jNg=i=9xe-Q?5e$ zarcMR_zu=m{aWDzK<a~~Y^N<qii84dJ+i=C6%KezNKihkNY0TlxDR1-g{3#At57k> zh(xW>&rv~1$tkj4T5=uYQ*T12@K+#FNVZc~w&*RA`ZsCnX$i*I9d2aJ=<U**(Lfh7 zvVsL&?{Jo}J7<|}Nu~D5P^?>}X#!iuaTkaq;gjXm*$1eMrpr!Dx}e*{r5n+3=_a`J zFi;_+w!oh>aL(ei!$cX?w}~gOCyL)VTzV5;A?lOx1Q_-<2Iofcn}^vpk;>?YnDG6@ zUpib$Ixo;ec18_$&HUsG>OMuQu*^%(dYsa47N6{g^?~BI4nur@`>-dz31F~^T>oJ4 zm#Olv9PZ)=XJKN}4CjmF^oNSSdYB160_FZV3|!Il4;6n6P)J^X`!F%h_b1q%s3z$T zv$>AZghjL^SM?9G0=)8(#)lcBFq!_*-5KR$9a&5kc>UvSiR<SSD%_n_K0&PV$!J*R zQ(zUcRxq?aJp`}(0P)J7P87d#*fY%#X=^kU;aAXqu=v<vPb{$#O16V}h;pM<TPA-3 ziJzSQXNq4vTzapMeH=LV<%L8!j+E<s?3fv2$<_(aJ4290$A~o@PZ0w;CNSYTs{h&I z*N8KI@vvv8BA`dXnf#oB4o?yyi2j0?!SQ>T`e%xdA1*EX5Q@eFq5n|v>xWBk^TBm^ z(B*FZhl@`T)`O?tj|5G>KS!+lIAh&E&si57`dM%&namu~=g~?33xk){zsR`MBZU4r zKbQZd-MRcnJ6ePX#MFPRbT{z0)NSN8b(JltYwtUEdS$g3U$~-wp1Ar8(Qx$_!PR8+ z?|72*9|v!fl{Asc<k@3NK7(=%uH+W~g;D)46Hk9>Fi-!)o_YEwZvjvL)P8vSuiPS@ z{^{L#`e%0I>7Nba>A%|H=|?=CesmB|e|a!Z|6C7G|9t7Yi7%X>0=^pdF{Azq9qIm+ z#)pY9AB%=DzuLH~K^o&YaU$Qt?TpG8R|y@Z@oU7Ozc{SY_;`=f`1N6w#wYfnG=5_U zrSY5lQW}40H>L5(-IT^}c}nBAgO$c#9;h__N=Iq@)jhG-uXXE<f2{{HNkmc_7xcew z+cGmW$fPCfe}gfz=SkN8CUd9CZ0Xbg7BiFJwc$f!{x*ZlT_uQ~(f`g({qH8&Gf}Ka zND2}~{qM0(k~c~J`)&~()PSOY!13=7)Y1PT(-i@P&V7KcFY5oO1Lhw)g*YsR6af_e z6E-jC<Ui~)lbbjns*RNyjwG)N&a0~l9syj*t^ZR-P}D=94dDDUrl-NH_3Lc2M9&HQ zZ!jgbZ$Il42Sff%7lKv+gx_LXY5Xjl@Cd|i<D>_8iQGsdc78-EuKzY06;YIRyzx7{ z&HgS?>44t+E?c|ccw^_?0Lbq#8$|%(ZjE5vf8Rj_sePjU2ZIoy(gBG4bEZOwBD5wN zAq9s>5U4-o+G~HGy6X)9`Y&9pXr%t-K&((Y0KikuU}OK<0EnmA_B()Sc=-Sz&p1FR z;toKb9R!4z4*>F9>5Y)%B0G(Va=zIN0JP^hAA9~iXD`@Sk%o;Xw#Uc+%ApN8T=joF zh&Id}8$9Iy#sxr~`nLlC3?}Zsa{#mmgMU8=0F@4)$$xMrObd20QU8z3a2&w7thlfL z|H<Ke#PZn{!r(s-;(WJ8Fd6;}vn-MWn!%B`0P2sJ?IQpcU!`DZ|JC6YLvE88`EP@G zg_jSY%YS#I9nxtXY4<+{NjtB~08sz4^cu!?s7I&j5uN^c5XW`u1o!QKITSY$bE?$< z>3<KRxLYF_&i`?S9ab0s`M=z9*e@Yiad5Yc5%`)Nf#c4lhNfM^C?28`vL*$LUUyYO z&Of7!m(Z(ZdK581A+&LPS!Xpe4pS)^@|k(fcqx6Qcmh%M;zZH>%jhu~MCQGx?u<2F zPGz)#rZd2dSJ1aPd`rZ_EX1*~QR9^a;&lMQ&PMYZG+sr|$q~{=gYJrf!($x5+culp z>=anjcr_l}G+u+>+&WFVsPS5AV-NbV@j9wVbYu2P<Ms5Fh(Nn<;|=&`Gj?$D6pT0G zNu^_XI#Md06YW-8sa#X#BgUIhdg7JeH!|{vhw+Q@6c*;;1VIog=#BrY{3uKulmsmz zxycS<&6PE^dK__Yh#tq;t_X;#w{n)&J|0`3qup>)Y1RK`V8xtUYk{@NSb+PJctM)A z9tMNX!Od<HZWs1~$lCd6umD4bX}+8GoHlE89%HKyt+X>tEVE~yM5`#(FxZkp+J{#d zwyCIedT<yNvf~K0#DCdn@bJ?4!r<b12_r&9yQatyFp<msdz-)}WHfdm$O#dd$1@Ba zyfH~uC#AW`?960xrZ!VcA_~2llxEnk@yY4(+{{dQYNDIvhr<?@E{f3)gJdLwRMjYB z^|m#SGpLYx5spWq5F2#nvDQ+zZyN!c(pD1Q{@d0*PKR&Yw#H4F&Ply(&0{qsNfAl= zQLbe^31+s#VAl~}(-SijQf*vLX2vIHlan(uQ_1q|WEQ`&m1${ma=bDpABeBes@j40 zIuKuBCTJu}_lrP$ZOSSXoKO<JBg4w&$*D|bd@5PV&dwz#r(_u_*sPSCo6XcF=ceSc zoIOy%z=gEc46)rjkYNWh?Eh;S7Nu&2^p;Sx+J`}kQkBHTlP8zXuZL-xT^d2b5@Xoh zyBC6`x9G`zFfw*OZK}uhd?qzF#;*-Qf@ItIDB)6%v3t|^vhvwT)-PYj#HHnvE2qvb zp9#~$`gNs^pko=Q*jp3|Xhe?Pxy9u(7Z%Sfg~9H6BYARp?0Ul?tlWy4f+rVG-oGTC zTv=XUT{#y9LuU(`&qPPJlPfEQv!Tf4+xsx<O}?WC?8Ovw9Kqh6`NwSg-rmbjsOxP< zckzMPlOhs@Rf5fo`&ZUNO?Z!Bx!Fu6!ZAI+x>CAGe73xFa{cVeau`;-Cd+NIwr@Zs zWQKZXXb-KrFgjg0e`a;@)RK61d2Q+Bh1Df-b?JQ<me$tS!XOxp5tie%wzMijXe@^s z#iDjyK^S#<3fIjgic$sP%bM9ZE}TUqgeu^Hu(BqUgltC4PKeW^!XjPd^q^cWC{}uE zVkR{)EhGwbGZGyca!nS_$dzk2BZA*Gn4X@6!FghG5?1HTw6G@CaO;HgT66<b5+OI& zmsXd>2bNaXLUPO`u3CzQiO(;t-w!4^y%L5m=mJgGIPM-6OsCx{t(uk|;NA$MjDvGm zFN$mHt0C9INJejUskpMfBrcvhwHk(2o&bsxne!{Fq2|%#-1KZT>WU*)#NyKW{VS)! z5a!Ghx)6cbTRXXW_WZiIyjTpi#72X|(kf<kXdIeS1!tFCOEGtHln908lgQReNPQv< zR?GF3li?IHT0YX*h#Z0rK5Hwd*B@M54aG34xCIx1@7dINYC4j!f+R(Bno8M>Vdl|| zdya06&m12%70b8(VW(MfC}Tnd&>USc9U(}j{W<_|Mn!dZ|7YT`e!BEF4E2X3dnBk= znsDasGaw;KGXUYklk7q<@I9(^`~k{h!7Xw8c%V!*Gc_mABDI&ZkkaOVa}IZUYic)# zQC_KAktCSQ%ymh2A5(;b`<ODf>4pZkjQ_ot{qWCjP197x3Wdk8>t;P*yi$KvgtBf> zB-u52n-{ux_gAe*L4dokgy)_PjiDT!ZfNX=TG@c%JJnX4Ubq<JH2vM*LZxnuaN>%E zGevQ^x7(5*6XZ+pR4Q%lPzvP`cp`tbw-a4UUpF>Rz>|n`l5JU}h&dN4oH)ln(*2Y; z;Lv@Z^@iMR*cRO&C-&6v-ZYsMA6U%gu?v^~9dfGkmt0KI`?6+wJz()sZW+#7l)XN5 zm4K64mdLKr^oFFXLRBu?xKnRKR$W{td^C_%@3DU%%lvdQ_l+)qZ506!fh9a|Tcmqm z)nH_h((S&<|MK5%H_b`|5u`X;+pXlsiN)RZ)#yTvZj=vt6|wLY9Pa2Ab-iP1wZVnJ zci@Xua8)Y@0!08m4*qhB_+S3p?JDBgY0erHEAQ6x_tuikYd8SfE$TwKrPXaEu!Lm3 zTX2bg;J>f9?Y3~o6D8oewYmU<m1Lua6FWU1ev~L5-`vIp7fq1}?bYc5!A7Z~fteAd z(bdS!d+OHlNLIIMS#+#cp;i;b=q5&^L4@WOj;N}K(F+*aB0+<NdcMds6k3`@sY2IQ zhaujbYo+&fOvK@4S~Vnl+!`yrA3GJdP}w14scxl}p5a)Luoke;aa^_#hC`yY(sP`! z16N>)9X{CEXJr4AYo%v2Y~a-AFckC@`sl3m3?Hn+Tie8EE!>(OGPo^bD?P)@Zr2SQ zUxZvI9`uLY8g?5<s1+|7D?P^xdb$Xq5pFO1;<nN=0&Izpn^2Q*Hc|L+$mp!}iYZ=Y zCkcm{RMDv*K%>1qeh1*t4i%alDIrYFHY%Z(3Cib*L?dKoVv%HRD0$Hx;mUJTa=99Q za-JL>fG4lqwP)Y4W-d2KIB`fdc{Y>F&CX2Zrf28m+;lBl$z^4EkX@C(gj-!w<5QEV znW<EEe2_QHsX8#5Bue`iMU6w0*R(J*<c0F3VSO>SMWhUd)K~|M^KkhchTO!VUC2bK zA}nQiMQb<q4229?4Z|Q4oiEKbbny(&Ft|kJOLH-?4J8a3FBC8HyLy;4F$|iKu(Hph z83u>F$k5@~*+D2QJ4fd7bMY`VORI$2-9_s1bMPTc;3nKWVFoL5mmj}t0Y;s0=|)3Z zq9fsV2jzXJ#p9{$Oe&j1mOavu?<2!JJ~rDay38V#!N2KLCY#EPr=|w2|HDm)O|y=} z4(XPoP-+snrRY%3b=a5Bt~}_RpF$ptykmPs1=E7t)*#y_e<qN5+$rC59=UcR=kbO0 z)5%!}LR2<W)>U@3fOF1E7%ry{^J8Z?b_5jHm!xb<QB$X3&UR>UD{xm@xTGp9(lkmZ z>{^X(;#+0M0<*L6^4aOgjM9w2O<Y8;z@z{RdMJ*HZXeP?hx^>ZP%g6V2t$V42O3Tz z4TDL<bg>OpBu`SfOdB!-L?bXs{Om(q25r-J-c9xIg`(W$&@el$$S{NaViTwQrj{3{ zIK^i4&KIZRoh42=I(LXT74IBzD&9fjbU#MfTPaSX6tmDa<yP24e9B{rWbxwhFJa{T zkb4t~BlqI)$bJwF`iSfZ>+h*F;5n5=H=aEbeE7k^h-<KLYgH5{2@SUsI*2fZ`_D|< zElaUfxtivC*>2W5h%ogX`*jdu>N*biX4j3cI*2em?vmml!t@}*)NC9?m>xu!nqEZx zL4@gWdKrt}K8P?4lNx#u8RMPN%A#`)B4g;d+JnfLJ1a8g_BsutG|OO;k!RpG`+b0g zlOsHQ@JwX>9w323O0Ak5DsnqIXAki35{AN9s-ne&RN>o;#qAFtYH6EcNPy$gWeNvK zxgQb~5-=vrjS1tE><=aOP2uCj%;b1xJeu?#L)r|TMH}H67lg*XY`&Dl6^W4&hW;?4 z_d*4I*;eJ&@K<&W2gh{yE1QXizsO%2hMwdo<;VNeS=6a>xXSp!wKHd(OA_1^>8Z?& zJd@1?1~_!Bd&Zk_Bfv+DyYPF}cnf~B`#0R%qm8%X$yIh~z{_!0!5<yMuYF${K$i=L z?Rmg8xV|pWWoxs6T@JH_sIY{eP%C=3GikU@pD$bJ;5_4c!`k8YiG$<V4~}CGBS@lg zBK`?DkG*T9;FJ!1{2Y!2P?~fNXao|KXK&oNF+i{3#W(v8f{C&}6iyjgS4c^s>!p-R z`l^|}%91fsR{=io04&}=-#Zo4Oyg=ExmA^n6u#{BJ+$S$w)fWX7T>rBVHhciap&Rf zyKjN+`$M{4Sw^^^j1z$9`r0tkX24(!rxg$~rnRkx3ZTT{VYs{u5z3Q@{8Dkdb|fgV zi^r7;MX6IpWMp&U-ahQ2<f*!*;Xo8oYDwxgrkjbIZ^8^}WV@;c3rLQDc*F5iDS2Mo zq=4w;iBP&Y7XY_(q;S)Z9cE~{m2WO9gPuM2=#$Sq`o+F3@T~%WZ6_0uBZPTe2+mWM z5dEF5$|f#HgJkXlyE6|D#<E)O12rUu{=+zxR#nD@Z9S_>Slpid<ky~g=tF(r_JJR} zVzCckSp1&<+0Q=z(C451<_|sn$Y=Y2?gPsTJD;Kt;vh5!J?9t<H*aCYllDI;hHF!@ zaYb;brSBq=p@n6n#0X@y*w*a#$XiJ1QRNgax`=F}j!9QBly=yFK1sk%Ulnjks(?Va zzEKS`N^EHit1mn#m&e=N0{#f64bTo}&|QlJE1Wk+=h=l?YiRtMQoF~>G+8cZGv#2D zOQc-S4iytEjRK$d&;DH6e(&YY`!1*2+wUGgT&EUzg3I_JtM|l-rU$+rC863#`gbyr z!sc<i*G#&9d)A6D)4?@q-6_{TdiXF4AI^Vivb$>O9z=FlUKkFGOd;$+ZXXxUM2-^O zTN^s7+U*wuLYB=48H@JfVFt}jI`Xmur50?8JUfs_cJ4P^-RZTN&d$o|>{K=Fol%h7 z%N+|5=Tf?3K=h(a)i5-Rjv{Uh?VczRDZkKd^<ny6ld{v5$@0YP%xrm9l55$iNvSH0 zS7)Z>iHV7sTBJyZ+n5f=UlAj`Z{dK$Y$Fy8h=;f)huY#t77*dix~7EVGbv9z4C@7K zDfhD!L)#65#ZDXI;Wia6QA}9XaH5z<7s-dgh>QLx){=&{2@O+IaqwywL?R>&48e9N zEqy$qD{M@=%u->((BTx6gtBDH!eSLCLMvo<q@9_Na24rj+~*rgI1Y9#H7+*2_miXo zbL6^obmMKzW&U>NGXD;8nZIIWWW-@;;~k#IeB=l`=70RE2t4Mr0}nG6-Da=hCMZ)p z+0cb)d15*uR&3xT96BjI6cRODM_#K<CbPBiOmebZD<|hB#&H+s^we~%Ql6fhtwwW{ z2>cY5xS^Ozs52_uu%;I{z6l2)G|M>8F`OD0ow%b+$}pq5FXl$<OsHt4np~6LQ)Tw6 zNOY%=N?s&whur}@{mm~t_4p?uLBWvg-U<=Y6B9iiA*D@3h#(0VE;WAjL|DNW2`V%% z!?MVL0LZRol+XFl@dSjPST{5~T+sD?q{n0!amDcMKcHn0Nd`R+qx9ph&v5(Q$Sg=~ zfrRZDw_Jo;$)iPtg;#_b!)iH2su)ZDPvK4#oX?f%n`>PoXS|c?itl2&;&<Y=ZKwVp D3;3L6 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-11-20.4528f3cf-8a45-4a61-8537-1f8323b876c0 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-11-20.4528f3cf-8a45-4a61-8537-1f8323b876c0 new file mode 100644 index 0000000000000000000000000000000000000000..4b2334c801a11beee76575a4d86c1fafbc41fce6 GIT binary patch literal 54584 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-13-46.d8b4b653-2531-42c0-aea9-ae7d45b688b8 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-13-46.d8b4b653-2531-42c0-aea9-ae7d45b688b8 new file mode 100644 index 0000000000000000000000000000000000000000..e89f99d9c41b3ede61cf36a74a07023b9c56e75b GIT binary patch literal 54219 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-17-05.4d34eeca-bbf3-4340-aa15-b4fbc1f327f7 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-17-05.4d34eeca-bbf3-4340-aa15-b4fbc1f327f7 new file mode 100644 index 0000000000000000000000000000000000000000..4fa475dfee4fb6488d78e4ab2eb2e096e85db498 GIT binary patch literal 54630 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-18-26.80b9fe72-c085-4a2e-aad2-3d3782b91f71 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-18-26.80b9fe72-c085-4a2e-aad2-3d3782b91f71 new file mode 100644 index 0000000000000000000000000000000000000000..a5d77d93bbe73a7ff47aaa28abe3cb9eb1cc1132 GIT binary patch literal 83984 zcmeHw31Az^b*1Dh@#J<K-$xI|8h{!C;4O+G8B-)Aam33cG=qsGV;Vq%XbC{05AYb7 z$vBQDV<%1=ABhtu@e${a$GH<9iTA#<_vSt}yK{N(&2Bb(@4jEv)#z??17Nc?nu*EL zkU-V1U%!6+`t|GAuc}91e4w956<&Jc#EH7RuNeBt!Zm!(UNIHJ%+}ibYDsNwXE*lC zHQ8uv7}^b`Y?;}1(^9RvQpxTrrLoq2R&KTGYFV~at!ZYrHnKaavTIVRTxqCH=R>Au zHR}3{3NJwwWv!y<FE0G~V<%1+irGRzC9`X&mXb=&-o3QGn15&^ClUPowdU;I>GV~# zDy6n9X*nmI9eT&zspZ_z^?Ayemu3k}D%WMxoJ%yd^bIp1)#c{)Tp~FvDP~!2DRUR( zx~UA^<*O>6k;`SJWhs>+6==)biliA*QfVf;V3P^dg!*RhzN$1UYV|s*zSfjbyCPTE zCwy)wmMjskOvRc@w5@7-IwA5<R@&X&&9rJQRjFjkS|eN5fQh&!*VFjkP@0yRF4eX2 z&2&ZEZPqopVrC_~BA_P}3-w)j-;}DFQC84QOEDQ!3=pLl=qyQTZmUg&NV9)Z%8t^M zRQhKba#OK}q<f{snxQom>4G6Q+_0NUL)%d#tEQR~IKHp7rM5}m6$!mZ+%ioUL9D$s z%W9<+y{+!dB?{>)3+Y9z(Sk6P>PkXF6D>4rF0q`OQ!3j^zb<KNmSg}Knw3$_B6uO! zCAnFVlEY<2^4w^W^-*9C@m4cFNvm2(tt-+4kj0i}SkeV`&&3q!MyAoqHW&<vD+9S# zs>nNPrGz?bTD!^mXl!J3gb6f3q^ZG{yzNF*QFhd_lHOG-R&7RFFPGb`eW}{6*Cm!D zX;sEPvur4KH&~`rZX4(^3oTLchm9OJPPGZKfKWhq(S$i^G&2IOShCtQrHTqUF=?ow zLrn|PM^!wcX&7qTlGe7U<60!jHAUU7S<<}3NwmMa>p|ZdtP&ZWg?jcCQ<Cd-ZP#Qp zQ?_Jj3^@r<M-o}bHz7N73Bf&AU$chKxfwHz;;tsmp+U~TV7g?!pI|scmw}TA2r+SK zpYBmRo8{<vtC?hwyv}5^ATP5!p3#i$EGdx5Y(q9~wjmSXbB3D6)KzesT~($D)YbO> z?cl=gLeWjN!y6j$TP;Pt$@;b`UDUMgx-u+PwC1&>MOt86v8aonaA>p|k_jCuwOcc; zZnhh|&B`*NhTd+-kR79IF!Mg;plQOD-ho=F+S=XKP7jG{vs`ai6v?#q>xx-Z6o`07 zSn6u?CVHzrm+0gtq?(~r=MqGliQXtznm5c$xvsS<)w*mbj7<54yqB%3B{N%v8cEB$ ziV3BaoyeTYjAYBEH#r0O&mb|86&kl!z5TlB%H~QcY0}6nCx??%S4q<>6AH8?DoPFo zblh#KoKLiAhlUAi>A(ckpt{PW7@&;>;}6FGwE=|!enUM1M+UzFE0?T&OtuLIo!v{b z`nr3AL|;i;TDx51Ahs+ViKJF@JCGz%J)b-4(*5#|yj3>TmL<s;Ihfc=nq_GXm<oGj z3(%Ot+=0oosXk&zyEV03!<<SA(sYffOZnB6NlB?IY|_SrT2*ALZ79&S7THKH@rUN8 z+DxO|-y-pf-3=2nlub!`EHj-MXR>!Axaa3*v%D&IlP~ZdbJ5d}%gI@rVBVLOvS(#) zfN4B6!Hh1>h-_BM*A$osJF=lN21yvXWH3~u(mvxYm)jx@<RZ-gm>8R7vUq4Zab;$1 zm{N-K8kPqcK7>QTOf;0?mGvWgVQXvo;@bUNsk?T^TD(F?YE?BF#RiNPnh)osd@8vB z3dyW7sk7+Au8esY8nlAWgz99bk5(c>_nVVL!yRlD)uc8ScU7zAMfsp+kbcf>s6( z&Wezx2IP!Yed?j~sYd!#r3=c!lpY8vow_u0YIWw+78PMkR18BiijyNFgfg>=_B17y zCTXxd45czGVQ|Ull&e>va=}RHlzII+>kKjql0(udiKI+6w#_+b3dNUU>c&nI=9MBP z4BZu==0yKP$Ge0syo;)^#LNuL6~(YpBg0)%egku&u@52e3}H{HQC}%i$z&ZhE3(n0 z3_T^sd?hieoPxb-9Pcj2CDu=;J^Mi@EIH+x6GS?r#+_j=bgnhSIc9@!o1dHGe2z6G zhgrjts~uTl0<)AIB0D;$Z#~qZvsq^;Gh5Os`$COW)E%+9qM?Q9*{s1zL|5|PX^f19 ziXlb@|KN5U$3x4l08@T8i&_N%q`KGSosw)wbA$bKT0Yy99qRFsaPU9rIx~*#FUnpE zi;Q#wN@qJ=W!mRP+qBf`J{D$d1(PnrP*)6L_F!!_E8Fu{7G{yX`eZevOIT)Aq)NJ4 zSN5dc^yG-tFw%0{(h~E}eD9~9`P@%F_358@^0Oa*_R)7e^<AHO`d#mS>akyW=JOwW z_K8p6-&2o&U^Xk;O{ZE)ZA?#1Uk#SF4Li_C*b^>?NnrV6$(UFvZ!S^R>UFtg!Z_v0 z81b|!y@xk>P2O2Dv=*&16Hwc#%o=KFby`HTW^_YvE-96{M3vUlcDcF?MLn0uvucUE z>NZ=@xLAc|m|$>lBWyDPiUc68hG%)JTq!O|<RpS--bSo5?GL-@(UFmaq=LxqW^{0Y zqISn=z`G6b=q(hN`u06KrfW=*;ZTId+@QJ5S+2l7Xwz!t>h+nsXhH5|I7)z0`A-*0 zO2%pqS}w&f56w;xE?OkB?^nldtOVE#^K4ypF+a_y46Mzrkz*fqVGpW7##Fx3y`(2l z@za7=hP9g#{1kd51o;?Ioq>b_+PoQRtqS};l$`Fd>q9;23~hHHu8|(NJOh>J$701T zV%;)AWGfgtTo&k?uhJx+S}6zk0(z|?2Cb)}Al^v=)Yb^MftOx|BkHsDLQRHWuhnkN zB`l*Yl!ae~bk7&O>0ONBJ$snm08d;BLl6fSPP6S7ynxXx$Y7(|Y?s8q?jCmp*{c^R zza!ZW9fYuNmjvK0+QeLSOL+hs9G0Py9sus3b+b4CF6kF~g6UaNPZi)6cd*Gd?Gs)~ z8DvNiq*G0=z6d0gl?*R6n{AU9n(CmRE)-DENlfmwB<cO_x>my6m>TM*?Y+~FFiL0& zYSfvn5Hc0P;Pp!H?NJi<2&=(1CWP1?YHW9y7Q#A82K$J68FDs;sznEadFHrw@2y9l zed1Hke&(HBoy7?mP+Ca*T&5T+8>&+}>XtN2+931N+f!6Nkf4EB;F%c+RaBkglXSKi zt0+~uUAN%sYV6nGW21E#)j>Z#_+EO&2a4tPlfV8mPk!!m&wTj1zw{%Y?1i+O(ILDd zifF`Pm!-L_6lv`4YDOi=j3Nv`CMocST3C^r*xzBBQbl|5Ug-!}P|N)C8kNHVxP4qE zVbA)T;Np1zhF*LR00-}%{^&11{h`nDf$-F49{bV<e%##y0cCEhZogdu%UD_0wz2c! zZk|sRdvVVP3eJ7$(MO;9&d=E@#MLc6$iey5TUW&;cRuohWDbl{vAY@5=#G&?B#tz$ z4P{%UorxFXfOcqi@i%Cg9nLbNk^IF+pZ?{~cXK-k`Jpr^A#e<*AZ&io44l8HAn!X1 z`<Xj0Y^{uaR$n7x@6Gr8=2IX2(dUm|4((G%GJJ}~XNvT-+WT41BtJckaCZ%}Ss2N% z$GK#(9o<#zWs>i5F!x}`IoQ?k;C2oOW|IONWH2WspgN?m!sns;ntbox_By%%Tx(g% zL@WUI?yL2-T9F#~!rXT(v14=&K)Aix<J#4^@iy|srz%>xO?z8I83UZ%Pl=72)X*)? zc^fWak>59CVvCVJNEW${CCf+*Wf~ghW`vU%DQDX!H6(e9lWTh@BUdVm<Uvg(YA~Cb zXErf(PC5`c+E!l_28&z?#&XU>F*eSFNuJRvm1{{CHP@0nWzg~zXyZd*CjrC35PoH| z-YpXZH@W)N&~|y}xf9{pgkL&6I!0LmTLw_PVjD;F(cD~8ML5u2GHek#TN?{@4)_K@ zK9yM5kyUtj(X&f%E|;*g#CI9;lx8Mu-RLU^!w5AH*Skc}o-4?ONp5L|uw#|`@Sy%R z?92%`T41xi5LfVopuo`~^udRQ>8tJqcN*0rR*YQ5jeWF744i-!HMTv4xBngl$e<uK z-s}ECqI)BN`7b5zB2CN#Jxb8r?DA;zsi>xDHwURCF@K35eaK;Nce@YW?I6QhZC14b znt^?b5B=2BkN?_}U;M<=@BECXB1gBoWfrUu`zC^^Ajc)?1ORWpBKX5Pp~G00yJZ%j z5I);4%)hYTX#``aEyd>z36wYT;Z;f`J*1|TO3INa+f5TDGnCGM0`XE7;pS8Uy@U5^ zrF1>RlFg2A6L^qhQo8sFt%m?~V}CAr%FN)OTA3e7o=R0p!>pE$Jx_2)s>CYQ=REDW z%4)do_ydky12h(V!?I-=DO5I`EVc|pj2QbjmHnivL#Q75>DQVNCBqBz->4BaWn2|` zdqu$ZuZkdh_K`q^$OF?ti{?=ARbS;-N3MI>DGJ3{KbkB^$WSB)N&i(uG*OHw+&mQ4 zk@Riv2rB6BV3Z8V3qt6U-Bae>bBTmYdWRiKDg4YU%T!kU3`W#I-Q!)5iweZw!77T{ zde6wc18t{PI;Op7viRG->3#Vd&fEUT85w<RASfnKNsm^Fu?>VOkVpNR(3kcuti3SK zT83*bB%)@m8V|F?COid2n(8CU3<8ADOe&3YoynF!>E~WU*4x^--a5-i!9ps*CYc06 zg*r3LaFIo9^4J~3N|oU)W<f+W*A27Sp^93zQY@5b4!tvkA5ZuAs_9xqTD7jWipYB2 z82a6lzrGq4QqXrP_)pf9U1?J(lb?8K$lVYglGJGkpG~g=#x^)gR#U?NX?u!tTbo3U zufpyoc^iOeWN&}=Y>h`!desz)#la9>8YGc{<#67;)DE`UxW&wkQ>R!U3BFoa))$si zN!ae}SO`ia84`S;(6+fec8Nol6MX#!ay<KkK?Wr!&M|Er`lz!GX-ZN7Z*LJ2O0CV? z&YSnY5A5?xt$=yzi7!6;crSowKL3TM-v9Vhk3aVGhkw2Yo~M8AlTUv3{m=fwW4&NL z_`WB9<A=Kdkl<}WU^kHoYp~HlM+&4yu~JIWFSaFzu+6GAlrh<e7u%ZDL|^CnL_dsq zlwJv5dj=r2sbYk9O#^@JXsLIo5jOgXQk{Xr6dl!dTdOjmlw20iZLO=M$j#f_EJx!$ z`Nb!&_vF*I_J)@jokH#UdwDSRI}ob|8vrCH1E@*}Q>d~OnyG7mDfM6n4IfaU9vaj& zppT}ox?)dri6z@nf{<Sv2%#w&^VO+^l<*JHbd9x#cLF3okuz2MnM#VcuP?_cbyib> z2x{X4k9bVhc|$HMCAoaF*ESW18fVIVwq=OPtBd#4uk_<1$|{AA0^VSOGZbS_X$dSv zOHi6<d$TIAXh0L3aW<f3<Cg%wqz^Z9hNU7xK@mi1N0z!QIUh5Vvn3-t&wer9)eOlw z19PZ;Pi)e$Gt57EVw2m@>Z+0Y-l;LzBJ{37{1~`BF&lwCKCIw%>cx=(=%YUEDMZ1| z@-+lAw>?q$GWcvf+j9J7Snj7AZTP-I_8xuZX&B;YOoAEnu&LnlrK6nuw5n8BZz2x{ z0u!UrOjT9tmC?DmYsnqC-d3(96B%g>Q6%uy;z(i`v?xEu%a0{!oFWK?34ttay=_Ih ze|>okhbs7R^^wR0kN0HAvcOjYjk<z^5h)zh7`m7JX5PDnwWVR6_>NBE`X;PW1aW^W zPhx;;>v=jTQfjMp?73jx21^<^ZLud2n^c@|h?CSry9GBK;wFjtO-XC<gTgqb1np$f z0Z^N>HutY3o62s7{}174OIdD`pPeJ3z+vZ%i{kJaXGdkm=TO?SE!&Frj&z!#CW7^P z7vHg-v?nA8;IP!hMu!>Jt65;>y&9+tp+|8n&#>l4LN)0EE&0Ht9Tgi;G#65J?BELm z3tH~k&z^+&I@YfvJ4;$t;T-!7ud~vkHDv$wVejD`Jib}$wAL)+Q11pdF{EQ|+<mvb zanuu`&FU;6*vgI_7M)Ab24WQl!DbNI1xE%yXFWY~%I)k3loV326hn?7JBO3<jZ#IH zs>6~sEEzNG2vm{}3>4;m48H(K#;{bqK187nRTi}^CGJT$9u1$6cZd%qrro0RSaUoq z$3EY0+rYl6d)p_}uwe0_3?E%kqxpsNE4dW0ewg!Pm{T$ge~4m~_Swo?NHpIZ<+h60 zVzIxK7(5Q<iOpW2G6JgYutQkJ1Qg1eK4Ya@^9*2R_!xn`#N`GZ;?L&x=#QAeePFb8 z>9#I9$9w{b_myUSTQ+xsyS3X(MqBN|P3A+DbT$+HKBz&JE@ld}Q<8DrfVqR+fR0t= zuS&!W4bnuiIS3!76FRvS-1h<d)L{!D+Xct9f}b#MQVzUXEfzpweH$!*zDfsMFNHKb zRLY@5oJ}t>a6`AfeAGAtDX?#-IyV2abNkF3bMJCtvDa5$h2pK07*d~VijI#_*Nt-Y z2qcn83gyl)Uv>C^o!77pFMgE>+kRpKjIEgH4f6FA6imL~(j`~`1IExo%3)Wi!NNPJ zOR3m9#HY+tCfj2pmUF*0`{b}`n7BtP|9-Pgpo9#v!0Ms!Z!hmWGCS&VcnoOr@m&nh zX1j%1Q}OyzW^e{4Dg&w0dro_f-z9XN+Rem{J0MI2dZ)L*uJxhqwaDx$AExE~uD@e- zPyLS{AG43ueGjE^tnQ)7JIhj!jyhKNR)+bvkJY{BGCj{~rb}H1XrNfsy}hzN*78ip zA4$s#TZYDc1_5O_TY7BP`{LM+&3c59!3WO_{6Wq79uuw4D8b5xN6!eOGC*x453#g? zSv^OK6OU-qd3Y|{?gfu<(J>F5fM<Fhwl|*(MJf%D<Hd|U3u2cy#8BXo!_gNr5yS@3 z-7!gy=xZhc5CB(9S`SGXr&U^?b$;N~NOB(g8ZC!iH0J_P9{V7;;~RG_UnKK@2GZy& z(`))ZgjbHPK2&0eP9U!<-J66fZlx{4*`ujrd_zBMSJu~1U|zIuQMIL_2WlQGFbMz7 z=N7KymoGdd7WyIERLn8ScD|#K%P%~Rn_iCfHV}+6KeXQ%FTFO>P;vtgI|aHIaNZ90 z0hHx(EnH$lqiINtsAMA8m2Ep=+@XeboKNOwv9JZ|I@3bwX*!13xg{*rbAwuGG@yi9 z#vv-En|$)k2S1ZDJL-{rc2$Upp6*r_LBEICj$Ox|8r|F5qesOi>}+eW?FQUMm{@B! zO1Lo?Tgo7dHpFM7)2C0Fr%z+g*U~Jxeic`1vy3D(a!8}aZgb#Zg%{nA2=^O@Zw1@# zl(0qw*fDgeV&W1s^d?<m#u|_^=;M%i>eT7eQVK0f)l|zILc63>r*7dh|9-%%P|Bv; z@DvAtzKNuRp~SE=5wUP-i6Nh}TgAR4uMbO9gGi*$l*ZADRQ`<^*>7r_?d;$S<{oMi z-$IBvbt)TSGeTwpc-P-~h5qArYZhsOacu?n!q$V>fMTozsTY_*DSC;%*eM6YB$cVs zKJHEz+4RLuIe@UTo?+z$w>j0U8(2Y+&c1j%A%G@_F@2iS5pNqWgnM#qVr=?MXVaX} z(~n<WkaiG1fn!Hx(qCU;#xs)a%t%FAJ%9Q%#8eD4K}l8`9hsP(JTv8zH-XZJZqVjZ zamT#shby#A-kk_S6OkNWF<X!*f(F;$@<Xts0La=<0n6@G-PpHkh{U;ibz`4GfegG^ zz%R6J?YGoSi{-LA#_2mAQs6-BUNqdwio2~19DEyckEvb_2;~74@^I4E7NG}^qzOnf zvbmDo>d!8tXJZ5bMiduCg9_K?V-YqoR<U&>zS?OAEFX7tcXIIs5ou73%^{v^D&<Zt zzF>bUMQI0;R<C6Inv>Nf#vuUkWI*ydg||XcHoMZ{7DNbAxhtLR;5aI|AKOAZz*q46 zm3)4EjpC3v!!E;bgFAesqJ~>s)$+}`q&PlL$BB#N*1>^!esgC^eBg)Kr3Br&T2m_( z1vhmLo$DWT;WkR#W$B=^Q=1)Q)k7iqnq<#VL@M-MUyi{}>4c3rA)%rCbA;DdD+HG- zwnJDqn+vOAK>4x3oQvDA!3!F3m^EHBe>sdA)+Vn>!;*Xk4NE&VXGn+R$0xD@<_uH1 zhcaRqhr3J|mKwVO<HmX?%@+?Hw(;`iX1zT8@afY&`{m(>XK+jWm$?;#8RGe5!|>th zw_v=f!hZ3l-fruK7}eK;0ZGrH1>@9qXbXn1?ge1KEG=(cehv*7+>LoN4hzPIXAlzx z4zvg!iRaiu!yPodbzWnJr}?ZIo;bKULkH|SOo+k{_!7T7Jv0(`(QuA;nKwK+cKgPI z_D&i&UP8V+-7|kV4V<H^1X7VSjXa;M9DA7h%^Y8{uycILgBUtqwuQPHd<(3Ot7Zuk zVSj6f2#eX=0pYG~9ly(_Q{ka49?rzUOdjH1$7zFarOp|fP+s<M+jQ{x_pJ`IQReF` z?3=C1O?u3WS*1O!B>QyufLmvs2{^E+J}P?cvC|S>Oz484&R<tAm+?v$UK0{ofz>kZ z`s!v5u`XzA9Ei{e*CmjZ@!~cfEW~qVctx%rx|<)mH|nbz%)dzJ*z<Vx9=zup`CUX3 zYe48=S3f2ti97xR(GaR`>JD>Pq^~q{kOx-f-Cpn)BSLHkC3P;jSa(#j)31~dfjHDt zl)Ow=1KHU!`|2F;)0Cp0#XD#r2$Igzn4rk>R3H_=Yko^g6}QT=eT~XEj^elQW+Yt& z$QwvNfgGZYDxMR@;}>l_4oTNa%5_+zcwJOwC+?&hrq=A^F(xF4Sb}uGk&iPyp*8t> zfUdtF^eI-b*Jh}Fi>s)Jx+GFXtl)qZiJnQ(<*!sTDF+wpLtEKHu?Ch2R23we0Wm)T z%7TSZG?->RvYMa}2%P&5+uvsw!-ieP%4WF0214gbH?b*6C#)#Uk#35>I~xrJOERT% zSju!=AnB77HpDR!1JP5@_~1#hlHvjd`yN-EA_w<w61ztDkzjEKG5|qRY=Agd$1>{E zgA(AhHGH=v;O^GoaE$=+*t>1!)tfywbHuq&=g!(t(tF6OeM7AGs$;axdqZp>=D0fD zHSbczbn|RreF0qJQeeMycBtOxSCPfv<+fA}+5mRzT6HeTM|Xyfpra^@r^O4QI75P$ z*6CYn1pAXWu}kW|j4gmEd?-2QVkjv+rGguqfn@`=8Q%#M29x;PRo*v>8L8BSet=Fn zOVjFjClXhcGeyax>M~|c+b!BzossVp^1S9JXbUl5{Ds_)eBym~{uB>x9MKRr>AC>k zPOvYY5Z}C4!HZZhOfxQ-$I<^zhBwP|yEw6l|F}z+wbnj+%}8qDRr_>ZsUqa8A2(^| zTa=?6>#jE6d(Y_9*?@Z~eSktjo7!$>9~N^rCc$h$y4^mq#9G>}g3XTe`_55%)`GyN znFeUk21kdtje}Yw=69QcLg(9$ukY^eX6%PqacN98G0(pU1uKa6H^%$j{cRR+qLYAx zX#*c0?P0*48K9eeIxjl+d#%7Ff%e1D(O$B4-Y(CS+RX}{3_z5I|0P{}6p{JtGLq1v zN2-~#+WmOC@7dq5YWvBA&D1V1x8B&+G`z-IglSdZr(n;bYCl5Nqk|R%aKFA`4^0f( zK_p|oO8I536o^W%+~Z+nhfG)R1eC*TN+CTI@@Tji93A}h8aQ7jq;84aYsrg@Tav?o zYsr~g7Vd+i_qCTRGuM(`ybhqwX=DKJ1Fh0T@<5QlUTGklzV;y=PBF_eUbnwMPv3Gh zA=4BUwjWSNyouGI*8}}@>n|z1?8J!^c(e+OEd8a0EWXS#)h;F1VBY5Fo$us4-UWoI z%kN~t`+_E4JhNq5MSof0<tRn$Vb|s9Us2Fco;cxLpC_dnnrWfS>E&X2D!Ptaa7>FC z$QN)Kh?L0UIxNG?*4q1O2@FPf8jfijjSWMi=g-Y-yJ@LbU8!XG2+FecT^8&`3~w2C zi6OoXe8GB1k;X>P4wFgV$z<z2Wlt%m%4MwSz`y2>YG_UNs0cEnk>Gmy!OU)LWGRXn zVr$<i>wL%%+a21b&oJ6%;Rb2rs#`{xd#!ov)|`JCd2n#<E~g)6dUeBH`d1dd68&H{ z@z`=rv-FoA=y#<GFGW&oA92?DR~0OLwgUynGiNd*Gt$7EN55ow6rq&Dl~z@CZ}7rH z`d1fTf~x5nG5u=_uffMv#42tnEop2*8aX>NIz2NsC5?@YPU~OG#IcGkQpME2?z;Z< zsRR8RQmi;#9HYOYu!!OVlN~NF`Zsc<?PghjW#KL$?TC#2O)QT@Rex3C*Isnu1ecw; zS&|?-a##}GD9M&IvNt+fIy<5$6C=2*$q{PY@K&an?dHHTGCJ=O(79X5h2)GRMkIG^ zkW6J3l7LJutUXj*zt9DN>(^9pTf<3B8-f9EZ7pA1yMK$og?CO`uoD?TtF@>#tLnBF zLZmVfdSKK~5SgQ>iLwahd=~(t_&m?F&$WcWh+Kweed(bPFv?*dn;`(3Je!3-hJf%q zU_mb-7P~I*E5=;%u%dMsMF8cCdv+_zoRM(m27At*y?beWG5^p;4uQK&QImyq6%%-B z+me=ZL}SxbGA{GJziv+q>91zvpERSXzve)HZR+xG7hVrpr<n!FU8<0j`kK~MX7txx z{v9?(35I^$Ky%Wq1O4@vf46Xtjl`9CHCZf@=ogF0>+Gg8@Kb-o<=-o0f?;V&v0+iN zGy0IGzwz?#Gi65gTgLv3{-(=+P>^gqjHnQWuD|*69~Qn|RJd1GT9$MvpWm3#rOSU* z_!<`mLsm^izx(nZI}A}c_@*<ju*q*mPh9?!Le5q49;u?S2~cTbCdO5f&}&jkD^=T= znJs0AIW9F=_bQz>^P$u4X*1<ghtEiV3tGiAW4qDPPaWv@rV3w$is)uXyc<fBmY!sN zG0T$DnAn_wOS$tpSMY3R(}xNb6n-vrlzy7g>FRv_zCsO?{;|3W($(i<S6BLQyM3Ui zQ?*wVuA$Fwr_$0hwO6vSDCRpoTYFUjbK;5AkUmm_RvAsLzUpLQ3@J1+yEI$Rn;-PC z)mNW%)Qzt!+uzd1S6_3oaBm3q0E>2F^|dDpLx2xFq=z@jy6yndCs$v0vM?N41q|tc zOR)8+)z_aa+#OsBdsMDV;Pf-AZ#Y>v6%5*aVqKqJedEc(*<kR&u7%UjuD<DH;dC&H zkoBTIv-;+fg}2ycFg^6VC{91ODxEBh*w8^eFV-?$YmV8~yE{EfC7nwH=9rt(cXgaT zx0;Ap)BNf^Ckt<K(HMN0oc_(LZ;4pLTUSqYgn-(@T0nE#obVa3L*k>?^@Y`YBUW;L zHF>hI;%WvRNjd6;bNb?HDk42gt3xLX2^T%SfeY!++gH%(xpwU>kgFP|w+pGli%|$m z9{nO)Gr|F5uOTlnLxt^~>C3fC3=V4{{eC|E*(*|){fo@xyndNYpS16$uhcHJ+X_RY z(CS}bWmPzfCw+}AEfjV&vA)h`ed?yLRqX~V&TRr%@cP>h^vx7YD;CQ#-VP`h^(|IC znN50LWYPPP$huPaMl@9z?hX~8`2jX}0tp?P-LnAuU<XaX&cr@BJxqqohnQxarCY4E zN_rO?-z~UfVKF%%Njeni)L<`9=Jju3S{ra!BLmM>rn6zbT`PPAD5G>jf4z_<Ivx9h z*CW~4!I<AJFlc39C>CA^49r`=tfH!hZp9v~R>JyeKa<oSW{fWu6&=trudll~lpE5L z5?i0ay2O>AGPR}5^iBZL0wS31icJXKYcJ|b7$KA!LP(XFmc`<>0$&xJ54e?{P;D2^ z5D&ZC<b?}CS`$=J%hXV+kQ;*FhTYLn*EOKH$(=ae)bRWeBy}4J`NM#u5r%~4hahPd zzJZAr12WqsHf(`S<1*YWWIjOZHg;zw52BpcTQ+ZKRiW!)ykTpO;4U`=0&0{QiXfc1 zmW`lE6tu$-P;LlMcI?4|ThW1Gw~z`RZY;a2{d>0LWA~t4CJOe$Bws)Tv*8i8^r2N2 z!=vm0)vdyKFexseU~KQOWyMfhq(TnDWQFI4@a0==O=t441U%msrs*7z5LAyAzM6?0 z;Mjd3!1c~BiR-`wx9!_)j?;T)S{0by6~=J^5sc?M>~4pT5=h?77Qq1;f@Oy^>oHr~ zh=D|}Q~}p_7Dj{n%?n3ldB)P?g;#PewOj1we%A!_9yV<<kFx$=TT~o>E~@;l!Yims zC&`&(zMIWlWZ>xUW9#!&qQ{(?7#`BUr|`8vwX0gSqJvKV-oivsle|#De13nM4bZv< zZ=I=s-+}&tQ~?Xo6AStW3$G%i-KGOvXZnYj2n*+z{$V~_JBw?PF|U6=!**W(fiP@v zYv~_h*u<4B`VSV~7+kY}K#?C}oTHVY{?Wo~L%`X(QU75!bD!VTf28p05J0%Q^dDu6 z;9;ct$C!N+(0HB?@Q*X_#oSsxx2b<344mf!{FBTiTU^NNKNe<^ArpX~VhvkdU&`q} z9@a3*1?W$3oa-z4Pln=LCo}J-7=IVnS1xX@U)j)qI*h*p0!4m?;a*yPK>yh=+{gsr z&oS=iR`pMZaW}ULuqW6M$*rExE$N?O7Eb_kSvG)wp3!?@Ik&R3mCNhD5Js<nK#^Z$ zY`d_&xvKwC7~3cppufy0zBH=;N*KkLMgjJ#9BfSgwNS7zfc-iL8`nP@3N{X~&vCE` z{qvz<69D@H2b<J?BNS{BV86-1rt~j{f=vPJuP~-u$}KGEe>IFLlnc<m#xZW{e?1f< z4U)gXG3K$f_?w{^kqgkj#YX<J{<p(M{xX364jV<w7jQr=r~losQN;5B{`Z(vF0WqH z|9+TMA`^iBfQj4k+QyZ<{##+<#<BtY4;k>v!ui~a{*S_dSvG+GF{5}TcQLoNr2msJ zig`Z3|0(0^%Ci2?!uYyEeE8>#uPe)Im-T-U##hP(=x;NO81%mrhLMf=-(_G|R`lNs z1G_@K^!sd{U0v9`yt=%m|3Tpm!5Y#AK!HDGl&<F1uIPUhMk(b2^p9=O{DS@`;h=e% zPyQw2>iYTnbBlTXPs6y%^8x;^I1kqJf6c0(CnxnMIf{+^^7@+oR459T4-`)`@!Zg# z2@}r^06oj(ZDTX1e<@7fkO{zl!z$le++5zs>;E>aa-I+Hf5#Nu`bM5B<bNNg-~<GU z{0Ck`ZiP7XA46+k`2hb<j4@jq3v2p+4&y!L0`$)~=KSXR+C}}pgkom-0ROLSv~1-c zTFL2u9yVH7Hh}*d17<Im=zkFg%(4Oe-x;^_3m5hO!KrZhD~d&=7mJSN^go#d<d^jS z6(-(!QfvR4F*=_s<QFz`3;O>FW3+%kk^jpvU()|yDCSGadE*4EB;GjEpvFo1N(=db zX)VuntnnhJ2-z*hi+dH}K5yeCPLT`i>v`j)y^0V72z!}RWI4Z*Grpo%5rROGuOt|9 zN#{3>m(%AEJ1LJTz_`l+&KqCV3z&%cY62jq6+%>uuc0qwzIL`xkvwmFEv3^&d*KqM z4&&?SYX~bD1n_>nzzaW?@eTBaw#5T@&-`4*D+q$3EcP089{*u{BPEeV-yz1yoHt%c zx#Z_ja1~l*YQp#?N?=yJW8~Ud^Tw+vkHSFsX0h>V`hGW|_889ryUNCE2$bqsT*)o0 zUD+^RO9|u}3@vLzf(fr9SmN8_=0h8K<Ms4a>RFWFQ1A@|`E`I?-YPDvY+ORktGUhP zMdOW>L0<3B+I=N}>`hdLwhWQAw2;pgm)DA$3u_m1#+xbUzCPGIMSxDCLc|dpopCoM z^yG*QiNXnjrB1bz^2@6(dhVfIcZ3etFRp$GDh9M~p@Out=*l-vQ6lZD^x_q@j)(w~ zdkLPLnuH{`xV*Zs(qUDSGHIi?Co*3tAWcy@3R?lv-0H&eiZMhfw7uL569Yx@(*#UD zClp^<-pV5wf}`0o?xQT))9HoBTLuV+sg%vB-0DUi;T4-kniBhQN<afihTv@x$Q3p= zjVvYf69Ixm;Sqwhn{)v|)A<gQM=7gcle}esaEwaXEJmk6uE!~*AB!0%ich$UuN9Zh z8<PVSCr}ihB4E;7=phU&EQgFUltkN1y?Tbj0>Lyv+hcus&Bcwgl+kajyGsDs43)8a zW_ja*3F90k^y?XdMB!O);VENoz`|I{81n>6ZYtu##=_FlW^QZC_-0B?_G5(r2b#B1 z0h^sGxwVV=OU42v^<yW81%mSgP2o<R5o0V;8tqQ@>JWRV0L2o4+XA(+{$Os?$Wcl^ zfnuO2e!*3Ibs@ia$+$R3aR!Rwmk3yl(6?QI63VX|%aqu6gxb(RazDY_y@BU6p))Yl zjmwnUuQwcUpjq*ufzV=ntPYBXfdkDN6|nnc?aImu>6~>+>)Rq*LjlJI!P}C(wQ}X6 z@it26C)osv!kYwZOVt*$lZ`D(>L*nk76|gL+G)Blt_)JUJ+VAMuw<G*B(H4HIg#Rp zWe6;m)W(C9$9AZ~Op)$Fpoi8*LPW1@Y(PXGqLh9j%0N;4TL}1NHbpS}uG06r`wS46 zf+%{8K<$3Ge`|fsxK0WE`hg%(`0WHsVp%NOF+kW#G>Vk^Tlj_O8Uv0~?Chvz9+=yS z#PjD+bld{2e>EulunX9m!C=LHRu`-{gGJrRrjld9Qo!wst~>8ZXOQsAvY6?0Kic!Y z90qM@H<jjw+OorrJFPqK%VE&%YE?11@VZhN6kV_Splmb|SnMX%olJ0xHN2*ah~qNu znD*oB&SNFCW)tDbV8H@jq(m5USFvCKl%<G6<6-L7m!PvLKFyHnTaX{vYGnuj(orH1 z(!1E8!Ns3t%P3O{+h=x+dXYD8R4DVs0AE^IF%<gZUShQND{?(kLXTyT5A0QfAY=Rj zz2IPM(^t0}n-{QeH_0#{l%k+7RtoQXLiMSAtGPiC)Cd&dHQgMnraFPqz@mb1gc=P> zcry~bvzDpXS-7bU1{#~LD%n!q&?rUfRn%V68!dvQP9n8rP+U8+MLKIPN}o3j${=2E zJTzvQ_)>c>)2EhJY$5;{;nx;Hc$aHV=Dg9ST;dAS*iA9U4yAazR^-hayOc@#8W+z% zBjCXbW3L;2mOnN-KX2?)Ch0T2wP!p+-`NV)*^+e&5VjiUja#D3o*_5472_TBo$N5d zZk7!89#97UN5ucP(nqFb`O2h@l5O0QU}mt_(=-v%fYY<~-mdX&1WW=~rhCtgN9il0 ziI-)mnMKNTioBCxNCxcC8spn3p+ZD$0X5yna0^#^@6bT+By8n2AINPMx7IJ@AA}bL znaNFzK$W0)T@73!n^}<`*?(~B;<8;^C#-v7Wc2Lx{K35OE~<?WKz<s}_>O@3X$!J# z0{Peog29vgCU*LMD_Ka}XSdR*pQ^8;&b*Wqp<>cP1*eg48#}w-sVSwzfr6nV)&FkM zeEZIN<FSD1s|Y}$5N(P|LG?vES6nO7Bh9X~Dyko=DAPD?BPGYH)7A0uvC*_VeO69S zOpi~cOXHK{>4{RMa%N;|YHFf1oxG0fzmsaC*@<no75SNZ<8ex5D?dksNT@1BS9EA* zmhaEa;{$sD88Z1EDo4x|QNzZ2Ddp`*xxGQy#&>mUrp-#su-{E7<O1*qA{+0c92#j0 zA`0I49!m0#WG8dp_+H8-g+bx)#{218w=2jUFmHSx!BAu}0)h~G-{yU9e1MWkv~MLL z1x$R1T6{=8sMK+IkB$x}sdsTe2Z?xS-C$8b=v&B~VU-k_`aC(BM09(SpFv`1oWoBz z14aPJg9GD(RNISCTcu=th(5DXjF~}d8|qvFN)>8mCYv?+Fw5|S#Jurg0;cv7CC2yD zH#Up$fz@fKGlqYFKxlniZUb3^%O?w(Gd@CDY&5gzF^P#TBCQN5rB?7<JDNW%(Rcod zjy>(-Eoe5Ma<0*ZICxiE!7hJMWQ(+IXI!D(L-WQD3d%A1>&6cSQof2Thw_h#0!4I) z@x$U<a%&@L{0My`X{JLimWt~Dew0#JWB73&DJim&{FaJjwrv_&HZZb_O1&-{{Dckq zkB+~fWjC`A;9L|83^R-KI$7M(ZJ)uRZvq<*KS2q9Oi<G(q6a@t-`La`-h-7AdhZhi zNV11Wr6O^*s5TKp^+`%*)`BypJpl8@j}Zj5SEL)Cq7?6hCGzHtAE!)`5(>~VeuBOY zGIReV0n!vvq)E>BDf&wOud70FvPpuDda&39h&i3bLhrEaNwW4^9M_GXM#1(Cnk>p( zF3Cc;3$E2-yV=4u*mdPD<7be2e){1PC;oICzv$rc{45ho{4wx9o*TFJ>&jfBinzV> zuA*+&teFz-`#wjryNd9GG)~=YH)kxZg*V~p^!jYps<=xA0?r7ic~&QD2tQ!UGqSAq zC=|3>xZ;}~KN3}lCJaKz)<!&3AT}gQ^<Lg{-fUrFHJV*yW$kWa_W&G`X=Sw%g<6_y zyXcA{Hn^1?rzE40Fgk`4efV!Q9y%c8hE~T*0#RrYBQPdXw3~RtB?=v0ArjI**Z{U| zEX)-}rcI*M@AOH!G9jOx7(FwQK2tqYO;3zZRMPSp_G@fns&w|unbPF=QK*GIKnGf* z5E)A+RW!1p?^yN9UW=Z>xMTIx?Fw46zJJFEXvlkMEPw7;{Vmz5-LcB?o<`fab8W|L zN=8~N&5v^~b7?TM6@|Kv`kER)GcH%hl=R5h#B_S%%$dn_X?kK5zedYb^2Eeg`K)rR zz9O4y$Li}?eMK3du}s}B0QI%Y9Uf6w)X`z3(!}IQd2BLW9-Tg$o|se=m|)X#`t0;b zb>i%#Qc^~bO)#*SmYNZko5worScgR!pf4C57N=<j-*_Zm9l;?*n~24Q#l_r4K1$Ve zRFz#KHH^i*@GE8a$dPs*;tsv3jruu#ZX|PdSZ!cYLf1C6?2mG*xjlS3dz$4>$I|z% zh81&bI9js2b}>o|w;xekcyd$028snga|xag<^*I;yvS<NP2CEj3a=mlD++aw)Y6M< z!;jQ##wyLYIk>pKet9_(X|8n!^OVeW=G;Nt9_R2LB74`FTrFnHReF$Bho`h{C%8}y zH0j6I&zIJ>A`LEwVKdVsBO~$2-Nxp6;i2N<`q~<T?s2Rjis0Q;loolmcd)>YYdmb` zF61_In^DNI@3Hi9%;WV}aj5`Y?{U$3W#i)J!V*Q{ZsiuQZ03raxwl=(ZRNM3P#=$T zmg$r$*w!vWnXE;UxK-^D6<bc($;^n9T9wOc)6&e^IcXVp64WImNb6ft0Z;7~N5_j( zL(&42zVe__x~y8+$?-Fp@hK^FnWEk4-o2ZObWtha)P|(R8tz|LvQyJ=M2}BQz#Ba> zC2h%7*--6b@pVk02z`pfi)%&f?r%ku?uiUYjfJL-h5RK5$%XYOa^VqR-~BY%kZq4B zMmi*S^PwWb_9D)av2bcLx4Mondy0XL!YgO!$4Sh_`evkYG&yp1JRbS6)k<+Sm%p^W z6ooMtb7(>gYLB1tDpLGq6f)wWfyeAbrJ*60anJ8f+%k@R**FP`Dkrhc>vk{`X7>C# zjyp%`Aeuh1qcLq1`hu&X(6fmcQN@x*Gh>;lSo#Vp6x<bq2cC>bJ3_bay=QOi%(<gp zs>ZPlOEF-x?b>XND0zegM|cny*TuTfMDUFfaXa#mY>$QXas!*ZM+{Vm(>*}+Xf1Ye zY?J|YZ{0fgfLzCu3L=Pcq%tyjR+&Z&BJXjv#sALO(&@~pUI}X<u2}$*1{1=(Eh{3K zhZ*v3BH~Kq@xQ0p5C1F>m}b3Lrm&eRMW{H)I8Zle%TRX!Mv+`RQ_$TFT9$(ld#J=R zlkO>{ATlpDT3a9n3J&p1ORacu*R}2br2ynDg-bpW6^DmtOi`1Y62yA;%9Zze<Z?O@ zUF>g!XX^7(V@J*69wVi#6zTpNLDi(_7z$m(W#A%x)ai1w*0w6zZnNlva7vm?i-%@& zeJt?uzlR*^ypW(2y;Ranrv-KZ7>Ci@s^YZ4lLJX=T1AC!HFvti15i;)ZCsSUqtpeh z<1QW`Oiv`cJF>*D#uix~gsnOPBLZ`H04;wMEtnXi?Udvg_;0}i6S2{Blei(!yJ=#V z=X61MNW;kphfD6FaP^gOL%P7~DPwBY@J!GfT97hsXr(};Jn~g!@xT1HXll#QXv`XP zYn^~|lWfW6O+1z&vOFX=we7YVm_s^WWL)JR_-{Nv!#^}}iye-61S5thDMl67-aAO# zB!L-4bKgYZVv!i_z<6k5y;Rm9%y5(nQW(U+z1!BgSZ23Msc3uHBAG*orA-aRLkNv6 z+={#%Wm02IiG>Un0{Q~8P-to@%4NFGItufizutRS!*F5%x1&cCkK5zDcT*=0vqa(l z?eyL=8p~Mis_@VrKH%8peE;(G-ZLK7@JvY*4m!qjeBOIT59YkReY&O3K4ut&wwS&5 zj4nL?f#<9u1qM@joFegZ%;Wrw&wI~kZMX39Y(>Gb1|B4c8!*{ZbCG7kc)a(VE;?(0 zDL-1s?hD&{&ls>*gg%A&)GQt${wO~0y=oS3?Bgg^q$tk#OcRjN+8>KD&|{{d6)BWC zRw7IsXe&pW(&#$1SS&?;(2?eaNczGX5zEi8%*<5rGvjE$5IQ-qXD#0oa%Lt>IdM!? zWqM?0X8O$d%+&N*WoD{6TAmqIlrVoQFNBv7Gh>qznKP4_(Xp^y4jVM|^hun4F^V#0 zC)A>h5YIGo8~4~SzZm;PdYdfTLMNo34|jUSP#SoZ5hqtFk>=@s;u(n;@+L;<xcK(i zgaeG<jUI)Txc1ltB{*Fhg^cG)mic>^%*z;s%veO(<>`z<!yr2JaN=we6jhvK+X@tP z7@DQw{oE+biFGT`riVO)yV(ATLQm{lf&2kLID4WUPdcQBIu?1iNj`#EJeC<flNn9p zA__cGe;+yQ@v+g$&<l&15&WCVjErVR#xj#(^Z(%n#ICumX1Gs1N~hCyRZ-P4dH9`| z*B`WBIH8@5Iol@-0Mo*Du0cLgo+jZ`y~y9SlZ5}sE_Nk<Aw6wlh|8DCn#x|evtMF~ z+F*X26{n7nVo{xGTWTFQ>mbmI^Wb*St~T+|YgD4Cm(H^bmXyjScC~Ob1M8;Iso0#= zjKPgI-oJzUgDzu=LTh~MkPbO~FD?o-u`Nd!F|@6qHKQ$zV&+TRs26F6sS!!nlN%r& zg-Pn?2<kFunbvzX)x8#qbCpBgY;RFU5w{nbI^~aszA)7(7NgI9by|FWsZ&nQ^F*B% zpFirf_&idlM{&yDPIVfmnuWEgG@~Ber*luSOkO-LCW@Xv<l2O;MRMZv$bS$I`H1+S zIJGDZ@cH0kp@%;^h<FDJ4=BfR^U&c|LdTJ(xR%t+wwsn})s+gJ{2OcSdqwX!^3-)r z*m2~k*f`*eT@iP69C><9u;MuK^f>a=tQ|+59!H*<IF`=U<Z<Nb;p{RN)qNa!8s*67 zab%2hrz?xjIgX5>>urxCW1e4;F?V*;Fiy7&1{v)P+~Iv6P+^}PK72%VZ2LVR0+*Uv z)pn%4{rEO}K!<aXD2k&eUP{OmzOz)^`S78pwi|^7&Ykh%LyAHIhNZK^(%1z1L*K@x zhNa1~XQs!e<2m+Y$h(nG*T#7F1(9(ipD!Kmip5C@M}L&wd#-}M+E)4Y$k*tw<d(0A ziFo9T_DiGilQv2Re*Yyfz`--`89$2`1m11@9DZ*apT_SS^g7H9_O8HRyy?V=KmRlQ zI`X>$C9M)EG+XQnZ?U-4<#pdHH|5c>GVa9;Y-N;H13!-xX%hGDA02L;=Q_-EeC2WP z2P%$lY(KuSJ&M+hXW#J4;L3K-<iI%{`4-8FQdb-F*jo%5l^@u+bt}Y_;n@e>cf!Qk z9*Urhttn&|(W7f>IeWv*-eBi1GB<!e@GdOgK3AEtX=ZUtl+vuoMh0I7Er+_CVuRO) zQhco*L}9Efrgz|?4DgWlA8sP1cb;&<ucRPCP{CzD^zz>wC5AoT6omrZBWBTqe60xt zd)3vLmH;^UiI*G86qrtjAY&T~r@MMDPMPA5$Q9iW$VFjkYzry-ZN(@w9L35kIL|nq zk7SE;1#nw?3XcJ`kIojZE4{4ZY0p0Ko6kP+iLNH_r2+@(<@K?ZFb@U6mCG^$zOxm@ z#QSN`%w1@E%WycAl~Na~LsIB|PA>RpdQ{q;dGD`2{pdU6q>tvnZU;qF`o8qDANkUw zAA9BtAAIW5ABmGn{wQA;#xOF&(xWU&;kT2IJ}3@15%LE*qtxm==qb_KeP3(8RoTNS zp1P93V_&f?)G_GFhRW`mi$bI<VWnS}n#!((*tf1;jnYeOYK&?xJjephB>a&sh*vaY zp$b>e(OaXDCTi-xhTQVGTuNuoD%Gixz@Cg%>Tyu2ZWi%+G-92j^l^~>fBUuF`>x^X z(YJ&!m+R!WLngS6KP0#>G&CDpJWfWnaL(U8bQJaIws?tB{0&@z98Q4<m)7&;Wk`n} zcH<DPr)jjXNkwtgMRsjo6bXyXAoLM;gg0qoCkb0Fa^!>5qFoFLc{XDdELw|4=``U{ zb`Au}P52b~fj}OmbkqoSyVYiPbXv)dPF6bi2Bimi8Y1T7lcEoZUv%m*3eV!>hzOe< zh!e5OOD&>bVY*a0J2^2jGB#Nr!CR=)<%!XXQkj|@ov2QaO^%+8mB?t%_&V2KJojA1 zrL<9nN(d%<J|$KzA_U^566rzY*kT|=;~Fw<(xhY2QHEW>k}`^ADrkYV8-<Eq3*u-t zfeEh~E)gqQ`>jaoh^ziM=8~GW3ky@L;||t4%o;3$+mWpFv6x=oG210}`Xve<mS7~5 zWK)qAD!3e4CBGw`u98y1kd9}^d`FEY!Ga1p(8KKdOyD^<k5O(s!M4Re!?wkLo_53^ zbGF4#+=XrN|Ml`1w#8|g9fjfEwawv1A+s)7|3s;Id@3e+tKo(lx*0tZ5mh`(Uad}~ zN2_Ba>4{Rcls-E?hBq;%Ca0?9($v}MN<3GDU^Buh?x?03>Fx;;u9OiUg5#FPhoz~h zGb5vu@r)AOp`|oRxTi6itrwrVZ{ud2D7||m;l_LJk)o8UxE=JZ73QRh#TJQZ$;DE4 zREzAXFMRyTUw=<5BpAxJGY#N@yhvgY$7<0-M?`HC6GL#g7yD+WN&dK~iZ2#YXk11W zk&wVf&(z5~J95wfkyqR{w05*$>Z53ni70Z)=<U9EC5$Cu=}|0uy!jbzvphC85t|?( z(0J7%(o7yNAuNU>N*`8A88XF+)R!5&p@Mt2M!LqDr{|1cVD{lJGW+nC@Vnj4{C`0) B#T)<t literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-18-43.5d399fbd-6813-4f00-a84f-8b4848e0f3ac b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-18-43.5d399fbd-6813-4f00-a84f-8b4848e0f3ac new file mode 100644 index 0000000000000000000000000000000000000000..17ca6d2891b08d1777cdd2ed62cbc082ea56e7ce GIT binary patch literal 76657 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-19-03.79712761-a6ab-4d7f-93ef-8fd908e91c55 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-19-03.79712761-a6ab-4d7f-93ef-8fd908e91c55 new file mode 100644 index 0000000000000000000000000000000000000000..4479cc2475a2a5ac33dbf44e93d27b312ae6c734 GIT binary patch literal 44825 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 E0~-KjWdHyG literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-19-22.f20443f6-2c6a-44df-93b2-30984320c7d8 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-19-22.f20443f6-2c6a-44df-93b2-30984320c7d8 new file mode 100644 index 0000000000000000000000000000000000000000..e5046d968e1bb5a5a57fc7a6143d5dc0be421bd8 GIT binary patch literal 44783 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�$zZY<#aB{UQYYR&I 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 a`3VH4$_&l5zMjKhegc1`iofdn^8W*N7gl)y literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-19-30.e188909e-d416-4a0f-83f7-24b5b8b446f1 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-19-30.e188909e-d416-4a0f-83f7-24b5b8b446f1 new file mode 100644 index 0000000000000000000000000000000000000000..a6e4ff18222afedd008b8658d286c97366a9d860 GIT binary patch literal 44783 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 b!{sLsoGLRk*ZO)6fB6agl`8(K@5}!W%=lJD literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-19-55.f3486e48-a46b-4b1d-9766-322d984ab403 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-19-55.f3486e48-a46b-4b1d-9766-322d984ab403 new file mode 100644 index 0000000000000000000000000000000000000000..895a8a33944d80e6d4c8aa58d98dd89297905691 GIT binary patch literal 82689 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-20-59.a438a8ee-87fb-4c00-b300-5785e2b34fc5 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-20-59.a438a8ee-87fb-4c00-b300-5785e2b34fc5 new file mode 100644 index 0000000000000000000000000000000000000000..f24c0e5d3f4d84711a51364fcacf6df890719ebe GIT binary patch literal 42426 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 Jzv27o{{uDdaT5Rl literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-21-13.c8881e31-9041-40b3-9b56-75af994d315e b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-21-13.c8881e31-9041-40b3-9b56-75af994d315e new file mode 100644 index 0000000000000000000000000000000000000000..605b3ec7d469b1f9305d4bc81b40427f1956eac2 GIT binary patch literal 42426 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 Jzv27o{{w_)a9IEV literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-22-50.6ca44238-476a-4e60-a011-a3957354ae63 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-22-50.6ca44238-476a-4e60-a011-a3957354ae63 new file mode 100644 index 0000000000000000000000000000000000000000..d9a837994e781f0ba822951b8073e792f0c913fb GIT binary patch literal 42432 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 N(Z8(GZ}@)t{{XVeakT&d literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-25-18.a7715c2e-8aea-43ca-a2bb-1a1bc2abf4ec b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-25-18.a7715c2e-8aea-43ca-a2bb-1a1bc2abf4ec new file mode 100644 index 0000000000000000000000000000000000000000..5f2ac4c40ece61dd3a519d1f67af03d911a5d812 GIT binary patch literal 45476 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 VZ>{yr9R1tJ=-*Z7-}`>@{{h7oe{28% literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-25-33.c08338aa-9678-448b-a0c6-4a3857eb7a5e b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-25-33.c08338aa-9678-448b-a0c6-4a3857eb7a5e new file mode 100644 index 0000000000000000000000000000000000000000..8c5714fe8d57db21c796638ac28af2f5c96bcc19 GIT binary patch literal 45506 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 P-#kYDwnYEV_mlq*=BbRz literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-37-26.91dd915f-96bc-4e97-ac3f-631b5e47fc97 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-37-26.91dd915f-96bc-4e97-ac3f-631b5e47fc97 new file mode 100644 index 0000000000000000000000000000000000000000..2bc3ed1a5a0cfe4001dfa12a78af72abec44eb57 GIT binary patch literal 44551 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-39-46.60f70d02-7dd2-4150-9fb4-7bbf66d37dc4 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-39-46.60f70d02-7dd2-4150-9fb4-7bbf66d37dc4 new file mode 100644 index 0000000000000000000000000000000000000000..6caff8bb743890634dbd1fa26a150eb5fe41c8b2 GIT binary patch literal 48950 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-56-48.779ad15d-f9cb-4edb-9c0b-56a9a8f12acc b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-56-48.779ad15d-f9cb-4edb-9c0b-56a9a8f12acc new file mode 100644 index 0000000000000000000000000000000000000000..d9cd97c3e66f8cef3b5cd935ca3f6fdbb70247f3 GIT binary patch literal 84887 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 T_E~NpevaFRpU3Y`C-eUSH_z&} literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-57-42.e1353019-1e13-4c2f-90c4-19bbc31e04e4 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.09-57-42.e1353019-1e13-4c2f-90c4-19bbc31e04e4 new file mode 100644 index 0000000000000000000000000000000000000000..1d2e9a9825dc80412a18bf6acb7cdc0361a3128f GIT binary patch literal 84917 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 aOlz!Xta*BleU{sYpX2u7=kdGK$^3uNxc9gK literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-01-01.038b136a-cea0-412b-88c7-467ec747a1c2 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-01-01.038b136a-cea0-412b-88c7-467ec747a1c2 new file mode 100644 index 0000000000000000000000000000000000000000..9b3142e891f199a99c892bb32ad3a23a4907b733 GIT binary patch literal 77669 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-04-47.4e2bcd0c-1a67-4cf1-a142-cdef04d5394f b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-04-47.4e2bcd0c-1a67-4cf1-a142-cdef04d5394f new file mode 100644 index 0000000000000000000000000000000000000000..058499411edcdab371f41bd88f8d1e9fdeb4c130 GIT binary patch literal 43955 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 N5B_ll|HSje{{;uqatZ(d literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-04-52.8b0edbf8-188e-4ef2-8bee-e2997d063642 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-04-52.8b0edbf8-188e-4ef2-8bee-e2997d063642 new file mode 100644 index 0000000000000000000000000000000000000000..99bcc3999a14a67b64ca7501c820ebb7ec17e5f1 GIT binary patch literal 43955 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 P{>OXpk4yL`zAyhT9kg+* literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-28-30.3fa30d1c-a386-4198-84b5-8c1ea0872793 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-28-30.3fa30d1c-a386-4198-84b5-8c1ea0872793 new file mode 100644 index 0000000000000000000000000000000000000000..f87e5d132eec3d8607fe4460c83877c37ccaf267 GIT binary patch literal 87274 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-39-36.c4c9a367-eb3e-4ad6-a8e1-6174d152c58b b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-39-36.c4c9a367-eb3e-4ad6-a8e1-6174d152c58b new file mode 100644 index 0000000000000000000000000000000000000000..bdaf6ef97562b457ab76d0ec8f37cedb01e636d3 GIT binary patch literal 43905 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-44-24.ecb2667a-270f-492f-904c-5790ffeea5fd b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-44-24.ecb2667a-270f-492f-904c-5790ffeea5fd new file mode 100644 index 0000000000000000000000000000000000000000..eeb5f65128271a109aa93fba6e3cdc7b199ebfe8 GIT binary patch literal 80481 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 G$^CzQkk6a| literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-48-35.fde81767-cf3d-48f8-9b83-0fa821b65225 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-48-35.fde81767-cf3d-48f8-9b83-0fa821b65225 new file mode 100644 index 0000000000000000000000000000000000000000..bfc68c437e62b6ffd7ff141883f76b1727ac3dde GIT binary patch literal 80185 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-49-34.a9415e50-a09f-4afd-8480-a16f11b976d8 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-49-34.a9415e50-a09f-4afd-8480-a16f11b976d8 new file mode 100644 index 0000000000000000000000000000000000000000..9f43004cf1b3a24cab34a1c42ad71285023ff81d GIT binary patch literal 80481 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-51-52.823fdac2-9f46-4212-beda-f01da85617ee b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-51-52.823fdac2-9f46-4212-beda-f01da85617ee new file mode 100644 index 0000000000000000000000000000000000000000..1c7c739bc384c57eea57e6a06f07ed51cf55f19f GIT binary patch literal 44604 zcmeHQ>0=wmb*IEAiIw|ojwadC2SAy`MGzz*Q8h(TvO<AmK+0NGme-5j0kP&{7qf>* zN@eRbbz-}9>NZK6Hc4YA&Yd_;(&n;b=jeSOY3`$GEm`>k`k`%__Pv>190Wj%!<8jB zRAK<!IrcYi-n@D9=FOYid)H`BT;A2w(_^Zu#GyOn<M2Cq%q5PStoW-&$*>labE{fK zb*giYeH+m{H|blR;h98FE|XHGwwhFHHPg^k&#)~wIX{=wY|C?O)5J<3P1UQ0m8h-K zo$@oFcFooa?UnC=pZoB)WS6j7X<yaWeUt2$R8LB+q|;e7r=_&ifK)b2BK2J&P<;cE zX;?%W*-xJ#KNB$7zE|@-x=Vfy18AzQE5)YC>XhTyPHevv^MN>)S|u_1O!+Fv<2kBE zN~*R*pC#Ya+tafU{w>9;w(Cg_(TL?qnrfO7)aLc)cT3VCp*Ag=zHKEP;(Csuc|-@I zhWIn-u>r}j;B8?dyhW183en;kl6gQP)@j4Bttz1D7lv?=eI3FY8BH@-Vdo0Jmp6UU zv`eb#HnlsO30`2T)sn96XRUULSxzWOapFkhKy^%#%6X|Af9hJE%dwWj(6JVY;;HTu z!`A26cC|0xckaQ*F5G!f-<mieP7;@z6|ZVGktCfR;WSYc!!kTYVei#RS@lg1$N>y# zJNn78K};PP`P3FWr3SpOE)qAXt7fvcil2N)H}}&Rr-q^|5)dAw8lZAi!zEHUyy8n_ zwSRZ`SH5Yi?WWI`pACb}wbYthu|0a#8r{t$S8eq)NUrC|9wg7LdKKG}h7u!*R9?Dh zkpWT;fU~0UnnTLQ%EcG%r_W_#O;<fapC`WpP!s^dJgG^UtdvgWhtv7tjFd^GN9psK zgef~fbeF#16n$ZQjlL+(ildODFP0~v_(j7G#BT?wKwrWu^(~FQRNf7hHsk_*85hGa zI_S&gPwwpL;R0fOv(h+`NNiRb>~E1m<7Z<NvAncT<3g6TBf*$?A_h5Q6Ei22*+XqP zPOGK?)V3Wr5#(T*=jV?co_YN|W-mj#aW;}Bf`=?atu|>}Wn-~5NBERw@x4mh>pa^A zi8FyonCC!S28Q?mPn?=Kws7Roi7t7<R94UI!EV_wg=Hyrsi(-3k1Z_B&UDGb)1VgU zr8Su2aC#q)ZI-nzvVUU(l8bZ9Q^G?1^yj$70@JojU$I7C8K3@!{A%EFobZft^E@XR zt~6s?Bu`&8{Y^GDF%SN0nhZfCo?WA_p8l46bx=uD;>nnz;Mi1@*eN!Zpqlja)8Cd8 zo%5nV4e~<C#;Aj5^flApVL}Yw?>Vb^`r7I5%2H4d1Jz}=rmvg+p8Ue_g)17VdD4vw z3v+oYO@Cj0UQ-QBp3+~K{z07}gl8|-^#Z2I<Z0jZ59O(*l2=Q*Em^h)l+i%O`X<OT zDQ=g_z6+`y>6g3;sA`U}XjrN#t*ee+?K7cbT7H#Y1Fb?uPxq@edhHs$E-pU@{w(>1 z=|P`C8)=O7#Xk0E5VV&1fW_4PlnZvIw$OfAhr&;VY@&M@&Zf?%*UOb1Jw4lEs*{X9 z5V@G51HQjT2ji6&U(#hrqViHU3`3oiCMz$OVH)g-_tR7b1WGzy=<SsU;0X>&{0HN> z28$b#D8p1$iT6GJ*n{Wa{)O}J{^*4_ed+w2_ny1^y?y;OQ+P&ieb_m~^Bqf)bWqge zW!tHa<3~RoD(vc&q2?Z%Ej+VVehK^n%}i2tUBQKgVU_K8f1VB(p4D3y4XpV58;%~D zEf(TcMK2{VD=2qmyPxI?&+e697hnbHhnW*K$JU7J#`_bhhSGxQc{)<Ks#m@)$k?e- z=Rf!Gxx4SHH)pi4yH|c$ke`@g)dbf;Zk~=6p0hEHg6djnlrKEDSAJDcX+Wd(B--m& zt|>gPw*sPLAMnFC^1}^KWV4gk`XvM1A9j4OR-nHK9gkq*<?)8j(4?^M@258)LrlaA z_wA4m2C$KKY=yy?0Vai53?GI6u9l#8bg8t;Bxa~~pEk%c&cd*~qz4N3?~upW*H$H- z3YE=+VguTAyr0+CsEuoTih7&6!jvRBS$JOuP_Vr7p_-GYLOkrdQ4NamPM{7J-roTf zPJM1$b&cBEKur}M*df1iecP1Ns)N<wTucuYKCnZ+rY%e7<r+O)_}~ut+P2(CPo+sz zhn3%0_|OiyuPwXgyPjQDG`m_ga1F$O94UObBM_b!Ef~104|Bi1@R1Hc7KsI;R#R%K z=Yd^-(JHnlc8X3T7k^*}a`92F;v>({0<#(T7IXp3g*u&)VS?!?(^>iD@ZFgU=^V<% zH(YADScKt$6Lr%7pz{sUxPT+!SiJC`JLMNcE|gkLIZ<fcRQRu*Yz2cX$5)v^JQP@5 zYT+6<Vd&C0u0g2}8c9NR7TtKNzdr%Q0V5Cytg_*_@J){w{(EO#2BT1es+wisNoI&) zLNIn}fWK{k%7vfol#c*B#`UcqrdlGVJASq=wBW!h{KA6|T=?W0&)s`Z-#{OzunvJ| zPdxm{xqI(CcjueWzvH340eYhFKRa7ArPf;6UwtK_T2S=-$KUt(7w*0AsW(G)%eJ%R zfaZiXe&W${cRuvQTi*iJ{ZiqljdpdY3LmxE2<XYe|L&BtLAydxyk5$?@sO-I+y-2j z0bmgX9dmP`XJgSH%xB?DcB-(WR~~GlqC<28NbJRr6_3Vap-nF~(06q>Y4!E@(_0EV zH<~dN91%a=i6i1x;AeGfa=l^qprt^rhxQJt0oQ&V7q&R$#`p1sWmq6!qQLA3D<n@X znXq(Oz%P{Dd}fv6hCaalM3tT`a2)u;jvkQ0z8#RzngfXyd)ZN~rGBW6v*P%^qP;Ag zjTt&D(7+rMV<tl|X`H|7ZRhT}|NN)#KmYE#fbX98&_l3#ifIl3R#DK10Qq6f1{ryl z2i|i2Gatq*HDcFHOg$Mp_sD&ZfBr6fc>X<aJ@>A6!2pnAy4}ceY7KzsFr;|f4uQ=K zu!Es<$+O2%_Cd>PrmgD1AIuiyj-N!hP*pfU@HZP3_yb#x-`HZ75VRRz9u6&@30oNs zgn9{h$W30XEDkkjO00RTVM6`QkX9d?m=IE&6$*z_3|6+9Z4Ql}g&(e80@<#Ve9yD3 z@z^~36N)l25QRY;k4;txh;+{m9z#0zouQ8}I6hDXx<R)sb9Fo*8BQ2rFLi_DB|>U; z4gNd{jW!l7Xocb|hnacLD^M9HF-k4hTLtFge{*O^W{wpp=aQNVQo?qEJY)sz$*|%C z+Z=z(o;@(LI0lp@AiLK3sg81(#0y{CRmm0}-X%{ojZ+jJARWS1NUEi?HC-KQ{Rw+R z0y84p=V`g{$gY+JGFFBE(3o#nKB0?+FX0;>-Nj}qp2$Dh8_}kir<KBEyX5QFA;Mgt z%F)66NR7gmcgZhWR|rHkz`CvQm0fadT~cd(yd^>XbgA&wU2?8N0RU;ZhUI#yrIC1$ zeL$L=IC^yAz|pCN6LVAZAS%tm*E+wj^`$|1n5U{J)gIf0Qq79X&w@9HQ0&SKv-fef zpf&k+NW9!)fl{V`FruMIq7E|;HU=JbQQ7cNIL`xKF{OJ$lQ8uIMWe|WOizQzeh0iS z5ZRYqcrJ}MNYYQ2am=m6r%$%1mdFzL4`-Q^V7f*F5n(oLx;lMxefh>S@y}q%Q!hc! zOrMfp3+)aw1?HM5X0<^Rrs_&C4$e;B!q$pmHvHzcb3%W4TB&5GZ>=vq8)=~>onu;? zRv}-hu0|*dY!xXAfJQ@AjsFbxN)RB3V8*T2y8C0&wbIS>SEjYPMusoJObOLh*a9xl zu)Wn9$f=V@)ibN}#5>hbe|1`~WMPa<--<)z_PG24Xl-B%3h~i5GL<qk1c#4f`{}RA zu%p%kw54xa&!@lc`-B++3BHrw!PfL)QTk>!^a$9BL3F)kec3zNAmFqHBGbFp=-qMl zOo449n1mFC{suE*v4z5KhDm6shNOGC!F?-JprH;Bnjpy`>u)t`xi?6J2?<3yB>uLX zhSu$am0!iy2SJ0V)nLO4?1uF$G0861w?{&ih5im}D`W%X0#x%hX1xF#=G&S4!RJ`} zJ6LBmjBNZh(Ag}xW5vH4R$yyT!SAsNAyxobunjChFR;m^Y{T*;5u@*9BvuqcA@A?= zm$f$qQ#-ff4_L2&c@?Hf72EMHIf>+`TLtTY!yFwkzdL{dn`{bwPd6Bt+8M?lGRrEH zMfI5$YI-l5MLP5iY+yCz>s;r3Atr3r{arCZYUlFr3p%(0)+VUo{mk0j0Siy>T*m_y zty?j^E!er(2iQy;sM4UPu+163@Ig7#xpP=$jf~hwI3VlH`k{apXhWwT?nVn{Vei<# z9|_ANEkD||d{<h2EGTc``#;{TJf?Og$R~m^VS&Lxp%2RO&SYT8ZH@nAz~iuh@-+nT zP&XbAb9AJ^r<jo+#WbsitUyhl?$#kqnL1YXnSi;t%%^|UjZ1iXXQKRZAj@1n7y!;^ zyUDV8md-VOPJS*B6y_r0fo=wCAccOOSJf^D8hJW4><a<0UE>U~%TUo5yAeCg(XpC` zgAQl2BYlJ|ggcBqmfX2bUkXG@I4UZ(y##O`?b@zjnDKlFs$~Q{Ccl)E$gjcfG|WJa z>E+9824ssB`jvo5>JBOJ%CGX7s{W`xD!<0&B{aX#KVjwK4Si>zpZ=-*e0b%u;Z>A+ zS^8)4P$%AR&DD{lf9|tEXxd=pbLn5K(Z6gmiT%};p&0))v&1dYzge#={B2za`MdQ= zf6rwLTeQ)CXiWA0$m*)ne`-AXXZDEDuQwk3OXVJ>w1s*P^PNb9z7wDVg97vopK)Vg z*rDIl8oT7X<-$?Lw`zvAWRl(VTL*UC+SBu+9{AX&8>jd0V{3o-a^OE*;tSEfGH51) z%fwi$c=?iT>U+U?!UN|ma}ajb7p=T!*Y@`9M<esTq^CER?3ghh=GxER$ry28lD(c4 zPqMd*AZYlMg|7&ka4|sU=b}LY<3r^2t+eN~Nw*<N20au7y);7?0gCEv8!i!!(M$vE zBq9*f8F1Et|FzRc2uI!bPy|b8*^GuHAoUFr0sn-Ie{o|sF#CcTN@1RtB6O(t$)KK9 z$Fk{>?BGawq&%1%%Ibsa2>ZxnbEUD7k<#!`E4ObBZD3#%0U1dr>2_5$tjqR#vQh)X zx)_f{AvP+W2OHbw>SZH9Rb3f`?as^ge%QCGT(+0HMDv}?*LIjlaf2w5=0`b~HAyhH zCW5XZzH&n&Luxrg22+{r=wNnaWO%SNnoYw;TFa@~Y(^U++u}=DOWPJ-+u}=PfJQQP zKMlm!GBH8H5t8r?8CEJ~hf`W+cu-4^jtypq2>}&sR2>`}O_j4_!=yyg+bS4vA+9n7 zR+`%~Y+Hu?zm{Q9s%GGECq%0)*rL$UU747ioSIt@c{T3CCGm*H04(mqV~WWYd~*HD z`lnTMFC9-M#s-WkEK2ZvV=efp)~v;WJ;^;ReKeB!tEpki)Xe1U!6P$=MOwIc#;Bp2 z3%H|t=%M69j_&Bh%;94bho?l)ov92?&J3KX1cW74)D)bYot-`+1g&YE!7L@?jXC#X z%pQAT1Dtu-p{d2KHI=@YRYyzdKu>6@;-V(~C@cVs3vZmA7aCl3g5^h3sZ?})H&>jM zPbibKGc!|@3rA*WL>Lc!wa}=28q}`{4AP8F#i>J6#i^nQ9JI9LlgU<!;c4m6=9o0V zDHyEoQDHqcceprla7sBcGe0$XtT?3<r`~XEYJOo}1bsBdSw_QS^HW6ygvpE$#}(`| zhH0wF;Y3P`7gWu#Jln18m5zYJg(<-UX?9+c;oPN?9#V4s(gX;7a-5W=4KF!7G?Ey~ zN%83$7Yaww9de0Chru1t?w2Mj4(RF0+$b2Lhq76)MyGPpyjoTrBPbSK$H)rE(}k(x zjB?XdabA$Svk8D238uM;g&ToM4$X@2MGFHrxq~O8VHjZ8;t6Gbp(r>tMna(CRAF{u zN|`u#P-x)SM|_lE=4OjR!zVkI%Z^0^gh>;nFtu>w>_HLUIXneTh(OxSPZp2NEhsY+ z1tBdU8VplK7|g;Ls;X9k-J%5BAdeD|D4#?&orADP!oY;SFgrPWRD@4()<~u!+8+$? z%+DTLI6hGnVwj?>EfG&jCo+j#Bz*-M064*!I+)`{=yUeEt5-53dpGN;+q4{FQCoN| z15yOF1?p@v!YY}99#ps%71hJ#pbN*h9Kr4DO_Dtl=vo!_cDLx75T#WB@xZYN*h>;( z;Ok6p?@j2a>xQv^QhI85jEv@`fVYhrXQh0=o%K1jmBVVb<AoVff`!bysFLt8KZ(Kr zs)08zoGa18H2%GZ{o}vG3S8GzG<1|HW1ORUWjs@R)|z9SMpriQnB|Ef?)I#j+Nt6e zl(4$QW0>fz-&z|kDd4yg*ufJuBWOj4*t8d)ycA?=MFhw9y$T)*al<z?BY`kZ8>Ol% z8>DiaN_!((roL7*fzy)$M+JSNpwC{2YB+4BXH*FssSTf}>s{_vd{4KREoEJfdP$c_ z@vg~S9*6bv?@bPMUMNHgy;QQ@dJBT{MLZAn4N`AIOA2t3<thBkbqJ;<gHB5RqDf8@ zGfW<8q5(1MkDEKP#Dm?0C0Z)1ncxr6F~z9j_);KD7o5%Mn8WewC3!mk3`yW>74Tn$ zm`q{eW=zbBuq{UmG&liOr&4oKu<&UR*ea~GrHpHryC(wPt_3mSHoMfZQt-coI5J@p z|K^`zQ{iYPj#&qN?ZbS{knt#NNv$WfK(_2f-v|q}q@c_X6Hf9U{1Xn6@gEk%$Fkr= za+s^7IIt3N$`GxrUP&_~Aco?ux)_@Y30=?AQU&WJ%?4%$`)JEc)~;Lh_C_+h=_POm zW`;GP*#w+~<NeV9!LbGLP8LP9GDfyYU@(u*r<sO=Q<K7DPlyoj$~D?IH4MTJK+q#W z_P8`g`(|_|#GUg6U8^po(Vk({m~W&AYc$#1e|C-bjD{76E-6C6y7C;I(VpRfId5eZ z&n8$9DL~M#EMlWQ!vz8Th(lmkZ1eu?SpKOp+B2+vZP8J60%0w<Zy=obVSzG)X2NJ} zupAeLMF3$U=HmVIHrg`+tUv$(RG%zm3vNfz8SM>Mxs3&^6yfUVR1<(vTg_Yn7-~Wu z%#jkpwS7l}y~fQ;84NuUiKfWR#|q91Lh_>35tg4?$>+=PFJGTCy5QuQTh{U$=FI22 z2`64tnT)3L`O%S~d~S4%<a6b;mQNGX&E6WEu*r=jGQ-)#$Z#T^>9#o*WbJzBBucv& zI+wEuMIu~riMQ5ZT5(n}0)U_b+ogLqclyI2RU7PN5dBVQdVVsl6as@r4w3$fZfh;H zd-3z{B3Po@S__f*jv)f$60@+YIY!N6HboJ1k#KO6T~h?Z#YoJ}ad7}hl#3(V_zQ73 zwr4|(CK2L9y73p_L3`jbZ1#xYiG1TPh@L2V25FP_=t%fIfV>4IIFm?^B+`R$*dGE< zU61B@_*tzbFhY7F1^>?_Qt3o0lNjzc+iz|_EW3+Ff?Lo<IvqEs6vIv|fR*{k?C~H* z3+`i#bNeS|a6Q<(b<hIJpGjyW57L)|N1?SSczkT((BNoLLsXVi)>Ia)I*27B+F%}$ zouk7_VF{h^J;O{K0;6_7gG+(ku;A_uQP9{+2mCTF_Vps{VL>Pz)=lYLWTt6G;3{0B zU<9!jMX*M<>S(~>J8vRrB3pbgFt~|eLx43ABoWiacT5HMlf;hS;G#bofr;X03*xfV zqHN=}Q~Sy%$~6skbFd*P(#cOZams`LKRv}MEIqG$ajINd;*`U=Ld2<Z<%m<|3KFMV zF~MF+aT=wV1#Od9qNnrma8o3c7x#h@k@K5eo3z~_7Y+R29w3nhG&!?Jf`wmQhGEVi zoNg3Rg*LYe+V(MpP01&@x^Uaav?&DGwvTDJMZg!jp@-GBkLli!6x%+g+diglW!uMe z+s71dm*8S@+sAZsdKvTI-u5vS3EZ;n15=OJ%KUJ)ePA$j?Y0lhmE{9-c{dEBG|9jq z!(9O(*Q)6DHULF%O87E5ngIxiTI!X3p?&>GiBUf?Bx2-=7741tmlwt5_ZYJ5Wf2nK z#b@XWkO+Uo(H&qw8XJIH)CVA($AB~px2O$g2BgtkdNdc!0Ut+Q7CuMYZ4Yj9>K`K5 zlBpL@a7ALD1pB^7$6aC<FW=KH4MzbZH8Ip!CK`sq%~265;;twU?2pl?6L@>l@%h6? zg4-IxQ_)&xG?gW(j@}F{6CM5b9rQaz`dxO>M|gKJ{a)o;2VMhrP5s9!;A6{I1e9!D z$mcrT0G?-_r$=VjwJ}@LGP*X}v5g{&1b)y+XwGikD%#w*ZaSs39m06yyC$|Huy03T z7m=CCNT$7?fe`F1Qv;{8aIjoB`ftE3tAdegS|ut!iE;L9mwx2QYwf{aqHGU3OKxd$ zh!hN5FL?PbBfv}c_$|4xNgZ5DD>5#-bm!*g&-&H5A_yRq7ThHUp1N7^fPzbpqfwC8 z-}EkmtkVG4(?+l;d1}$NAv}npTB^AU_dK}}t5gJdWXp^SbIje+kP}e@<-s|786ATM z4+v?k+=_KcdkXHE_C>m;6Hj$|cHzNCFFbgETN5}nxv<^H9Kv%XxsOC}#c@(6E?gQ0 zYrwW@H|AkpStpcwsjaF_B7E|Ys-oDQxcjr`Z+~Ny_}GnyZ54{*`|-!#`QzK)`@|z} zJNJoqwpF?XDr%Yve$;I>c7xgNxyZN$gO<AWL9w~HNA=-4UZL}dC*TOMGy_LNBwXdL z+Wrk>1&+3uBmuWTM7E@bLB|fh35Hlu;YxSgl;FNn37o>(dR3&C*wl!Z*o$=4aZ<|E zRwek74mm(Oh{(1S2`Y%bhSA-G<{Iq3s#<F`PNd4}m<k7zJN9IxT+c#mDV~iEz#=s5 zBw25{dHMRA6SdWAx)7Jk<XeCzxQyRq_9lPHWY?lm5~&8q+=Ej%qDPp+`xnFS2!hdu zhMz0tKEyg67H|imvsBp?vLHJY7Bx<UyCPEt*MZx@O)QZ^f_(^8_+)X|E>;QJ{~}~8 zT(OFDT4;BzpO8~6u)OgTa@=)it1jC?tKDRJlqA!`dL!2T;Kf{s5b=4!un&-4cnna4 zX3<e3^d-G0N<_*pctyNO+soPE;Soagl$K7X$HvN|!}@SZ&*^%qtdksx<_eUslf)LK z_3#f*Jyjtlt0+@7+6<S5MB3Hh7qCQxmiLhz0u38iRUwcho|P71y$;Js5v?@D0-CM} zij5Y-n_EzXKwQv}A%>QMm%ED~;-Wu_xujw*gLY|~5Q0<$NQ9*ERL>XE&@&O;H{<#x z&+x?N)PtZTlvI~U6FS63HqhpXf$yYvs6<Dzt9;rJ<KPfQ{fe1H$Ae)lN;&=h9rOo9 z`a^c>e89N$Ut#BX$8Oj;{>fDl>>T6zT7>Ib7d4w3f=sn!og?z*p<G1FR)Kgg7!_Oy z1gt)@<#Ki~UCyKiv!!xraBL_8*Fffmb7ifR8ynT5377%95T0_{a1EhI450(hMxH$2 z&65QOj9hv+H#8j07=cJqq*{U?g<_gsbP~;nKr<rUyCv=huMr{doic>Ryg_H?sYo;t zK|L;#cZ=#{=N`H5@z38C2?U2M)+YhMjh5(f2#TACfWUcI2wlzZSrC<ckwC$5Das=A zprklph+C(6wM?9R%nNU<BRpl%v3)WB;;l%JtcbW`c-ws-yOE^Za}m8B?zt3O(ne+^ zVlyO|mf=bVp{YDtAS{xjNFVB@1nOc6_GJPt5P>jMsg0SO{^$<+Z$<j=zMuF%EK*k$ literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-56-00.fe65e955-02bd-4cdc-83c0-2738da8552bd b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.10-56-00.fe65e955-02bd-4cdc-83c0-2738da8552bd new file mode 100644 index 0000000000000000000000000000000000000000..967c88bfc9e688525c738d788fa38006f371152e GIT binary patch literal 44952 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 RXL9`IC-GOR_^ZAz|3C1vf}Q{X literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-12-54.90b0fa07-b98f-448d-a5b9-4f162df1c934 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-12-54.90b0fa07-b98f-448d-a5b9-4f162df1c934 new file mode 100644 index 0000000000000000000000000000000000000000..50c8b75c1749b505f9dbb746e60768ae5874f4ae GIT binary patch literal 45168 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-15-02.7fe4a98f-554e-40ec-95d8-0a89969062a6 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-15-02.7fe4a98f-554e-40ec-95d8-0a89969062a6 new file mode 100644 index 0000000000000000000000000000000000000000..e277829638e7c363c0b2b1e054f14b9a2499f4df GIT binary patch literal 47267 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 GE&BiUj)HXn literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-21-19.f45f242f-db32-41fd-a6d2-49fbbc3db4bb b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-21-19.f45f242f-db32-41fd-a6d2-49fbbc3db4bb new file mode 100644 index 0000000000000000000000000000000000000000..ac410860fee1fa1301b388fe8bc1645b1576dc0c GIT binary patch literal 45166 zcmeG_>3<u?b(ERJiE=y6eQhYm0BzzVNP>{anxaUFp+GVqWUZ<w+r{nxSZjgB>>-j; z*(yoh*lw;iX_MAYZ6|Tg#%Yr_b!_M8eSPnJ{QCP@it`8bL%*bbZ*~_1h{NJ=Xh{i` z7yx%>-@KW5^X6Ui=JMbs9f-;=9T*re)eU0P1M+G3ojBzX+euWt4Wne#D~Xj2t*Y9! z72CRxXs(m+>aO9ML{F@dQo6B`P#X=?&{Ws3>P}*HC81e$*S1U(fk2t6*Nl3+u|aQ< zUjooIODA+t{y6+Rg1;rJgkYs3HB0wQGA*gDlw41xGHSA{lH`a~HcTQ7?GaK#Ba&&< zi8L`yUn0K@aI!qN;kops@*+dfR2@f(%($*?lsuQr*|udzrlrV|RVT%b28o2|S5-%< zTY!8}Q;K*EU3H0K6V0;q2z{CS3V`U^szyqxcAnlUfBTk!fnxZ#6s=i~D?x2icO^|V zO$pj|hjRxdX`X8YDyC=E6E<-GBh4i`OhMS&bZT-$GV0J;SO~315?Lo&RKrObkx2c5 zVO#YYU^C2(!ZlJxh}J|l%g_o*fxBJ5>lM=~sixD??@T)7H(;u@lCDm(UOU7r#}yoL zVoOsn>R2R|b5c3_;`MyOM@-dq#Z{g246&M`m!kL)$47BPm!_s*%BTmk7Qdj{4m=u; z1NyLhqQmjBVLSNUMt9K$u^J|svXq9^7(Uoe$T<!=K1g3KzZ?kJsjCgAYPs|koAjX1 zLmC?wfQP(NcA<D>!>w9%X*50&Pv)d+UcA6>5)J>=Xu~FDWBuA+9;UBi3<g&neYN}+ zz#<PQtdfS5&Pb_LE}hDyCZ%*Tm8Gv?YrSl%HR90Mo};geZqnCB+3Uz|=xy>WynfAS z2aK@GilcAvfqHd~-Yy>mpj&H>zR_ohKzZ~{^0$B+_=|69r+hIUkMDG)O}DM^sY{WW zNKQJU`RtDMBVKiDW_%_BH6t@iXO!jnjv5zK(}2;ofD(fmtn%vW!ttf|tzz{u^c(jD zX(o8cDl{6iR=sRg+G~VQSryN%b~NW&7OdtOEW$cRJ1Q`YkNSmkGpC9R^JjY02}>EA z<zv07VF{~J=mDqT7oRE?mzR1}@yh@T%+e<8Hn`DFMRrPB*EqkC5y?UR{i2Z2FnzNx zJHQ6&(6?;Tw?-HLQGPqnIBq6Jxpfbb3`fE}Ge_UH_)lzYVjcX~ve5wdy|hW+zWC4b zp#Vrr;n|3y;M!D_$T`NQQDAw;;=jo8?se<1wu8Fx=GLl%XY`$m|H_ycw(r^-Ir^@} zf0LyE4nwNPPDtOq`0w)T!Uoqh(r~2{#o|hiN{jy?zq$p2tr`xY?^*oM=712tdZD@J zGGQV|hZg@!o@;sYkfd86O1LmG8t_=p1b!w(ty0-@K*%D)l3N9#$u=rRT{Wd`;OHTb zF%`4!)#x42D-^kOuhyXN-K2L$<yXR=CC@Njm^0`jjj*{m!XCvyB4{pHES;u4V`m}( z9hP-?`NiN(^e%>H%jDC$<?4ZffqgdBjYl69&Zg*y=WWthw0hf~Dg^QB?Q9u_@*Yi8 z-z38}I1nAC$tp0ER5X8ZP>#S8T$E+YuEEM*egDb%<wBlGMrR`^8b!{H_)_)=P3K=Z z$V7L1VcS1bEfLe1x-^8WVJJ8B+%wNydFb&gpZfUF$dG0e6xLC8fRZZ@JbdMur>}nY ziK~x1Iy6E@^RF6gTcX<l<DWyMu7|H*ec<a?zxjpm^&z8Pwh-u-K6>>#Uj=ZP{Hq7$ z6G5lCfMVc$xeZ_Y<cFVo>J!gjz8|pEt*ysTe(dT4pTftR!*neFnn5`eKm^8%BNcDh zmPQ;0Btlg~M&(3XWycW*%3x<6&e8GwYX{{!Tkrv9*#KRR#LFNLRHH-B{qV`FpZOj% zcjci+hlc4y{&j<LtgXIozy!F_Q-zb!NT~8fMurY~ph>ds4-eC9{`G_M8-v$~8KOy0 zrE+p~GJo5kJkkcWD;AG@{rQi4zllpO|AxUPhqa08*>y?MLEnku7);^EFg@&5@5tXi zSOpe%1n7DS>G~dMX{Vd;cC~^|hXfqx6Z98=fZq&|qvfeB*(Vh0r-$i1NYyjZ{9^~? zV=Y}}DhL~Fpzlbel_m~JFowER+F)#7CuP+$UFm{B)=-oHZIvF)KYl=-+77KoToo4! zNM~w=M2CHtThM%wRZ;I#*O{b8XY*g^f)wa~9)LM}t`#R~3k>c>-H<w#|6&)UaQ}8X zz->Y6Kx!`kr33O?xA#p!<p;o^Ktbp8PaKf%=%~_NpQFd~Up^qex1%<Wr_!?DguqYa zzj8nx>Zq=Hj%(Ev&8pQ5H>|sm|7ur6{JLlmLA^h${l5Iyx*$>^byzT((f~UGvFmKC zB6mg3(M2TTCk`M9pY-(<q#2rLMg^}9Qve&fPM2iZB?roMS$+e2cOgN#f}H*Rd(GJk z!NLehpRR6k_9Cu<Q_=iSZ;{{BGO|cuOiP6kI(v@ZoBzLCnk+3OK3L9ZApv^|S}#C5 z2HjW%eLz7zv!x2>=;{2xpgg<{db0)8mVjLYKSWS*+zy7RoIfzwlqFjmY=9jLG#F+s zY0<rXPMo7>^0y4O(O>v3>rB{`4`i7BVt#N?{@^ym#4GyrZ2l$vnC%DhFCCO$)q+L? z>|FF*{$+#m+k&S7Gu_ThKbXIDP=+c4R6&v)WL))^e8JK;xJcL?s><(%N=J^(oRmD< zm>P1ZX}BbpNWjWLjuh8RL({ax=(lO(pqf07Zxz)N*!*y7m!gI~BH;{;NG*FbYOnrw zi}swdH6r=bF#@u)|7&=f>a2%N;9xDGM1BXtZ*1tQ8TSp3PJG@VrXJYwrfFGz4O9ub z66~0?;>*4PH<d0$fLEZtxAkCku5j;ML0Mg%FP@$$%t2wK02-fxwS0ZLrh*ytq<V4V z^y=}2&}<kQJ4<8Zs+OJJoTgQVb?a754cSJlw;J=ih;1CY`rzfOk39I?(@%ry7YRF$ zCHS{ew$L`9$0pO+@mMA~F&fJfG8#*!%B50S*C!{-V^|M|5Z}4_?Z*L_FQ`NSm;2<` zLc^`N;2@r7N(E!SCX?U7l}BsUC1zOh@uPM46OGGkB~Xj4uCtLV&p!6tQx9UZS3m!W zD-S=6zYeiKAH2-I9$|&prE|35d4$0rE?8SBWs}ox#iBNAlYlkCBh-=8&?1L@)@7vV zD`_AXQDBo7qU@Oh#z9~(ibB`6dcGbOp~(b_Hhe`Yu%NVK7@4LQnMMPUz&1|SU3lTr z7OY<m3Uvayo@+zlraXZ&4x4z@(qn5jGAtYBQ)yNK!*f|`Z>CAYzrtn(DuWyZz<!m< z)Sy{kmTv{9_#E5#5F4p2)z5EC3X1!H|8NM#(g4gy7#H6%ku%k`Y{8xskI-LZQ==$^ zLe2aA20J^2rTzNz>&$Ql>OV+xD)#83@)!<JQ)_La9@glC{R06?6`arqd!dA-{ZM*{ zSpgKK0%BHZ@&|aoAs^{JZ|(K^LH<~XA9nQPJ@JFmeo#IUkN~(PssQJcY%A?TPkwnn zNS_KI8Fd3O`psUD{PKQ~eoKBmBR^Kt@k(s10LV}GBE)SKaZ-^BH0k^^!BC-5i2io3 zp<*VZJ_PYQAr$Q1XL~|<fdT(q0Huz&{BAEOSlVxhelJ*Bbr44t`mh}BPUft*V>liO zmWfStPeU|5-)otKHTsOo?=x!_8qOFnvJUVbm9yRPX{po)<YNIP*`$H|=kZ>Y<d^pw zrY{5x)A3gy0Q+JuhS{vr58jv9o~tNO*@5+pWA}s)u#?4X)#=mKF9%cM7#E3E25?{L zH5FlvKES>j5C!<^0Mggw(e5mU75D4q*8`pvF1@N{od<y5kW<}fwY?r9*tYuqK)xN` zgF*8e;HrU5aBFY-Cfl;-!TCn$lK~+$J)h9zx8&Qf$>yWxivB~kDXMnGp?}0CAUd@3 zt$b)?n0}iH3Tp=F2F+IJcjU=#J#DYmXCnUCV~gChK)H12pKQ|a1}-Dmm*}6$??T|d ztOwFAb4CQVs%HP5YLSP&$0H9t%`os47y67Zl@_cukVp+3B)BxlQcNMLky;7#ma5T! zr$<(aD@BKb0+0wJFki$4Ez@z<Km$_FlZ{Yhv`NJPN@Cu8g~5!VB={_A*Vkg`_gOC@ zD523Gc#JwjLHUQ;mh<SKoIj~}^@gFHH_1Wzqobdx3=I7DC*k9WZd{l?;-ZufUpD-w zOOCq%e#)UT2uQItVpOVbu4I||Vel!s5M5x#z}Zx(=Ul6CcxW2U7Dp1U-uh<Oin*}X zG;5QQ<dFnxp1q!6t@B{874#4`5q9BP5LsOjg9WS<p60``PXu!yVnj4U=RpPa2q9yk znFa(a@Su=NgO?iqmlA_VGyH`Im(Y4D2o>wRL3TwUJgYM>Ed%>dSnv<eI5g)Zrf1a2 zOll$%n<!6|W0}#69#bdSM>;cJnw*#@jg5x%%!4gj@i+-b$Rz0&S_XK=NJ#T!y#dC1 zJ{l3hHma@*&IWVix(z^0U5|l5>bkWLw%+P>Yuq84XJ5a*!&Zq-C?VY!xtFzYFsH$T z-4^>AADtLg%V`ozrZd@CW@2J2R?22l@R8ES)l4R>O_F`~#Vv>Jv#)*j#j`+#?436O z`&uI=2sm6Eev5~dN|~{wmL7{~sqADdGe!uAU|BUbnN5~6lVhYrQu`tpP$BA(9J=H_ z58LNqKhr!+q-X}7SFW+zg|%sRd8s(JR8&sREgdhO;Awp_Jt}0w2{9?2S()R(qXxl4 zMnkpT1bWJ15bmZPmP+WXQ|*nZ82md;N{fa&52Z(g$JRn|!Kf}(7nWDX+<PaF3F!z1 z%_=jqvvVs&o_?SYHGvk^5wMqphmR8L_~h>O?N4jwVLFwJPmUNh(DU%rQX}}OHtLm; zyApS?@~r5NDRWD+%f}X$j`Q@ea?xl&Gy{RCFc)GUO15z9PR=YHKQ(ili;gZ<W3x*m z7puX*lDg;-oSm6HF{dE87nV=*j9;MDPbI~TTe$eHKO11HCq(CGgBQ#$FE1`|(PE3P z&a917TXO5Qm<|t1EdZQG%iGtYxwpL?$l5I+u1RnfVMSvUabkIui<>qFESF6t1umH7 z!ou-|C7#ubMnQ-b+bhIY3d`~t<St8dv&DsFE)>rb(m<co1<<Vo_><TK7Ut&X3UdWv zBZjAOLx(~ljKvg(?x~gIg_&b>%EHp>-0Z2soKl#3|Eamv;wn!E#5iBrFrI>7JOy^P zC9c(ww=No{sV2taNhz9FHKXoYPW7;~0Fhg!1P`R;RY{goNhLL^j1NmQAb}8HY)Xuc zPQ*vYrRd^`V*Vr^Ej~}A<3u}e4NJ3C8}#tRcorN@qnQkNo08+ws#;cUBX~{R#K;P4 z?!~#nk^(V_tDFR$i36%aa9Wuuo&X}5U*@5Uy`y2E)xsHNwOHU3(S(dmVJ^R1oKt3w z9phT|O%5p%nU&=N*UA~ojAq9LA;K7mlAkM{SO$$_=bru*wigOu%&W77g_WYRG?V9& zPJ|3c5M0cQLrv965bG0Xfh!^r;w2PeVn#49u%8!~XZaKb+%Xa<LB9WOQQ$m;Td=hA z5U!Jor{iMQ5(oegIcw_RYU9D@(w&Fa(-VhxdRD4MFK0<Xd?+K50BC`joe&6;DGmX^ zO(83!wf_)kWphRt>~PqHpsv**ZsSG@ECPJ221_r)L%?^M?%{j!Y=9G{mPzW#u}PB6 zNdave4WE>90d+Pv)piPNShgEhL=F}bb44ZLV+>{rABWL(VVVDZ7yIY`4r@A&sc0DH zR>m|sO<;bd&Z-UDxPU>b5VhwQhIn^Y)zof)+pvTn9XytYM{L@mp$-Pes=&t;Zy0(z zY}2Z|@LN!+{Vh0??pEQTt?q;^wPFHUg8G%J>wQXnJeAH)v~7Lu*aRVq3Y_Wkh=Osr zAy#AI#JEO{z!A&vd8#?(PStaDYpt$qtI>SZVO+dtvCoe~xc>JJm%9H_h$+lc$#R-K zU~!IN8TAa(>_b}#P*UAh{1dn#GHn%fQt~P$xj@XYc(i2<h}nGHI*}zmgG=~E8^DGM zu})n}j2f;l1+qZFA?>a;Y_IvIU+#Z~-E_1n#HvFQpYY{YoLG!+M~ybrTu98&?Nu-} zYmf;kENXklvC6#*0pFf4V!?e@sVh*3qlV-tVUhpse}-L!qusb>Z9K^n)@$u8o}4SG z&7wAx>sG}x!k5}gkmrX5XZ;`k=ee-mIwVx8!wJ=}R@>`9O2jThdaEXoR+L~c6lcS6 zNln3lZq{i7!DdObfSAEh-`2?HofY@6nB5IeU;)(w%d7AOUWsz%uy}dE1f%MCHntna znWLBB<OItmz$IZqD0*~Q$lNk^1$j{_Jj2N-Q3x6=1pX!y`f#^b{6rBvgLmUP<XSog zC;TBf5+`}=jYF;#J5#M!JkChey>!Si95ofTS9Zh)G8ynth**c5kJAmq%G=Pn>G^rk z8$3I}Gt({pw4Yyx92>(br1az&!KMN#&LPL}@w0~UV1%#ljYEzh1_JH+26C4=q!Ho_ z2p8;-V|YOdN@5d;z1X<{y6cGToil@>>oqF2suRV4<V_gY52tro#u6^EOpHU$#|!jx z1$H*R<5@SiLyir=x&oU!X7o{Z5i%^!A!j(seJsl=4`GXwlL3v!M*0T8p}}?fNa#Q~ zmS<~R+ilVI;5`AJF6JImaL?l67wv~w{PVWCTp9l5n)_J~JpIaTwz|GGbGcs3$%j-X z*<>!4ofyrHXD3N+yqwZ<DMEVrQ~Z}w<CF39SSCI(7Eh&nIlhCcJr9hEjC93=VZh4E z7S9UVyPXDh6njI##Nm8;c8{42PfuUl0dSktEHHsXObgfM{6YlDg$&v+d8SI7+dMRB z`}uHqa1rJ<4^e^SUp#p19r-$%Z8TiwD&Rp(2=%tOD|m3Y7Dl-<3JwtBrC?$H{16Y@ zaxIO|&LGsEAK-&#{x$I7@=TU+e}0f8llR#04&6*b=siGr7qV|Uo|=fKVvwB&a)#WE zUN`tzYs4{|e>@5QACD(f@nkwa)@zgB*@9SeDn{IQjPXo5`kWQRiWk9ow6J_S$lr$U z$*I7x0u>w=Vlr%WZ1~S4^nC^8Yr&(?Vi`O>Rh*Ay0|=rVBCM+{vwDzcj<>^p?mHhl z1PaP?+;a^R5-dW1q(26GfxA(M8(Vmh##uV*l~K*t3*efDG<$5CQscrrPHcdEXN{kd znFm*K%ElHtzC)b{8(}&JLk4|=R-I4#5j-xQZ7S#{<~uQqy1p2OiR@<=?6R9K)?a1n zRCq+HGC0jaoB<EH-E8dCzo_EoWT&8U-uUcPxv|)(kIoIkPL&&nohmmFJKc@tbuZbe zNHz=7CaLo#)WO5ELN+fyxQ&O;?@%}CxOq?v`oW!5JRJ~v#>&q@j!8-3ww~SP`Qyn- zu^%@MzQ`B2?Q%bEyd^2;e%yHI7Vx#)Flur?Zv1dK6#H@G`*Gt=bw6%=KW^M<o|Cyr z;>P!boZC}y-;6=d`*APL4C*ZQW<Tx)lgaPLz1&!FFW1*wDAFDSiws=?T;WvW92<Z| zaPoiWQLMroJ%9vc8F$Mb*Wm%7gV8(&$YbFViwTOt*B6T$AXKPst?`Tj-qnkN0P*lg z6oUaqq{$H}of(l*Dfou}Qt<a^CYw%X#hfv-)iwUp@gl-B5rJJ9dhuAM5KAdo_jx96 z?_#?=SKAw68f~YgR7MOfp<9$^1koSr-?MWKmr8bxV`$su=%3wB|GYr|g5A#rT$)|} zO#ia_qoYG`r_uks6Fzo*V^7J_xq_@i*Y7HeH(gi`u2Kq9Ih4jylj?Z3Yae-x-Wue| zxxP21?B6%g|LUjx>r(cwOX1;}2_akF&%u2uZCiss(%hNtA(w{%SEO^Mp6cdyzjUd` zJo+ayHaoL7iR=%CNpfj(VONAA16L1o-5j*)X^^GEc~6g#+*zb7CK89!Z6yMMa|9Ay zsc^qH&-xUG47*5>2Ls5F2iJc>oN5MQpiD!MkPN3DiEU_*4#LF)fV-j|U!w6T{jQDy z6G>YY%YwW=idt9A4Y+>MfxFyzhE$lUQDvdI0tRnq#4X2GtThY`jveKaUVT&6p3W59 zUFY#kO~{d2X{y_^=b!w+^G`nB(S_F6`q@N$Vuj?xklrf+>FiawfdIZ8xXTmtzz(qe zY1jwW4NJY$0cwXBwx&up>N<h@MYo-)<i+jB4}JIQ<qvg$+Xa5?lHv}4y!id(8=w2h z<wt+~?5D4M^K%_QcY&qGa)xw3?1g5p=RO8ITeo1<Qg^>7cGf0dugkafoq@Bz(h?jF zkx<*+u)KT7Ivj2>NgS?j5~kY1qGLzjIMXYr66nUJ1Xqts5E<4nt30#Bwnkog;WR0w z8ygaQN%J<09b9C5UI<o@RuL~n=Gtp;{%UGtyOCm|40o6&yUwIgs%N?L6xYHK;N6qI z&uu^Wfwj9o5N~YU(PMCfT0j#%kKbYSFk&*%^F5Ix)PTe7kZS~`U*6Np;f=}R_qI)f zXB~tIb8eIyjGOo{V;H1msj&;*fpI|AJjeyfLt4Tl!EMOx;_fuzDB*QV+y{%pelZ|u z1QbYEsJ8M<T4;Q29*|S(V1Dxt$oVmjyN%cmdhH}qS&~SN>04KR#IEJ~6~V^|!#Tk5 z!c%}eV<v7y!f4WK8VRBFQsp!(ka1NTOT&$j<<$7t=;-8RR+|``g!CJuaPRHtL`Eo* zd>Uyp^TUfjs*q`!m#9L*1Q3E*14IU#CtSL{u+V_8b2Syx!{RYvo@LiXm)y-(3}P-1 z7X38gooN%{pg3SogUngnNn(B0FJdpLT5BL$S|%hGzRpAAs;<W+o~H%fZsm9-*Kqmv z)MFqdlvIaEGiVYq(BOy}@1$rbL5p!MUoiM6IK-lPZ&bYNxv(~&oc`7Q^sfu_Z{%AC z1_lDcrGE?V<Db3)+{gb5AG>xRqjJqdb?vsIoh?BoTC&OEX?b*95V2Ju-3#XW=R%^a zPG-vGOe|GSCu5mXxfGimO~b{_<74Axtu#KF)y3q?09S;oTreDiD-lB&!P6&{Ck3hX z)9Dc@GnP$`Pl#C~kVJ~qN|2h6Ptp^|>^;ac!!y0RqHYKs;nL*FkQ4JBo!O>@$a9=> zoRGG8<*_TzKK9&G4+=rSCY9zU!0BZXj|V5a5rhbwcm;Qv<DeOim-7ih1=l4niL8Q< zVuKZKo9NZHar$eX+q;hFDHYrD_#%vV!#zNi+j%fC!?!aHNv|R4^_)kphijDieC5K7 zL~Mryf`*G)xVCb!h_ED%Jabr6^imw}7m352K#+ne*`LDc-`!9DzCi!M^Wy&x1HusW literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-22-43.f236fc4a-5ffc-4951-8b09-fc87b13aa493 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-22-43.f236fc4a-5ffc-4951-8b09-fc87b13aa493 new file mode 100644 index 0000000000000000000000000000000000000000..d5db0bf3367c6b9fad92f8ec3205bb3aaebcdc5f GIT binary patch literal 45220 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 F|9|mrC=LJs literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-37-46.8ff165c3-169b-4fe0-8943-33268bac342e b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-37-46.8ff165c3-169b-4fe0-8943-33268bac342e new file mode 100644 index 0000000000000000000000000000000000000000..bed429ff49fc086b55a35419de65a4eb663f2ab1 GIT binary patch literal 44788 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 aMWS#c5G0_A52kSZ(+BX+iui9mFZ%xzS)&dB literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-38-27.9e9533f3-2040-4380-896a-f07d12be3ad1 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-38-27.9e9533f3-2040-4380-896a-f07d12be3ad1 new file mode 100644 index 0000000000000000000000000000000000000000..30fafa54995428f1c3503c73509406d52dbe6e89 GIT binary patch literal 44976 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-39-48.cb629b5b-b6e0-4981-865e-08e1ce2d7144 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-39-48.cb629b5b-b6e0-4981-865e-08e1ce2d7144 new file mode 100644 index 0000000000000000000000000000000000000000..16783335df1a69afec411721368b04ae2cd3b788 GIT binary patch literal 44824 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-57-02.84349f26-13d3-414a-abed-4f41b121c461 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-57-02.84349f26-13d3-414a-abed-4f41b121c461 new file mode 100644 index 0000000000000000000000000000000000000000..67e5c05699f864dd2216a7f377c87a159ca2981a GIT binary patch literal 3714 zcmc(i&2Hm16ouW+PiKNY1TmY)h9TLqGfsj@fTCzuMUi5Ds+~Yd*A5$+lt?Ox7X$PK z`mlY2UXqrgI1@~pLdnKqLPz}W;kk#@pU*y5gCKb^7z{YwfU3Spe#de2QG?RadA(s7 z6RYTKlb=(yK2!1!$c>I_VVL1iL|2f-<tCzK$yrVflR`)D&!Sukqa^3{Avi~iH4|aE zslH8~<I{6lK=my73y1IQn8?gNmb_cbqULZ)s3DW<>10V4M@2RnlO^Lo-t+|ZW=uE} zKo+Of^W-Hm$=Z~)sa_;MIzUdfCi|Z#ui+=9q}o3vOk7gV3j99<igL1)3jbz;A-Q7a zoMco3nNE(${;yKNe)TeWjZZR)=8)0+qWUiR`}@J*L-RWc)>0dyAO~ScPB|yIrWqdZ z5%TkcDqrzhib#Prisc3hl)kAlo*s>n6<2E}aTP+~8uB2wn=vLJE}4>IjWojtBm7H8 zG+2id+-AgTEb!oUed#MMGs<<R?s+`*3vjy53VQ0Q*1(rxY83}XPEd6_MV7~889Z9$ zi^I7CD}aN6)KGol*w7AA6-c#Ci!87op`8oSb|)veeN~M+7*e&;!DKiLu@r2fU>Gi$ z()ja#3Rt2~=?ZjIP#%>V`{|pst7#lB7LMI7zQs1R5`-4C#NKGIoX|+DHny387kZ3M zj_%BA1G)#;?fN>>m2J|F5f0;fkab;x3f}+r3x0o0EOD#qlaSjK>2NO&4tK$G$pu{l zYKc{%Q=H1F-;DGMXLYbcJ{moa>O1Uj7c<9xi_O`^@ipjhT~bjr%x)^hFgj^ReHvv4 zc|JSv$R5gj`w~fI8Mqd+7Qth#7?aURmiFYMJhkoE17yLd?QR|IK+fhqJD_rWZvVF; zHgJwLG@BAV-Rjs;v`^YJWrCSB?YQ{pty8rtD!9OK>`iKHYZzHMt-cpmJqg>!#E!7@ z`8~VuFcp+|eB$vKASjMBZvHmcQmb?in%)OG+s0Xo)D7V_(SGo0+@xCj<p4ANslaF6 z2`$SlaC<JdGkA=&<3}KF*Rq$_FIYG}@HdI}dpFtO+_3_awsW9Tyc{}LU~J&Q=M565 z%bs=b5PY$U>CE2)Q+NGI(>wAz#|5q;dqE2D##>{Cbc*P~=3l4wu5r+JkeLvu_YLh+ z0LDI%G5H#nJDAvX;nFMHsdr4a3ilXyo#pPFCGl2SR@?$MD&SJA{PqurdpGYv$N%v) YXs>#eyu$Y&EoiCFrKw(juJ-EiA1yN!ssI20 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-58-40.02fe98af-d9a8-45f8-8043-639a1cd6f2fa b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.11-58-40.02fe98af-d9a8-45f8-8043-639a1cd6f2fa new file mode 100644 index 0000000000000000000000000000000000000000..6d3987b00dcff4e39b69376ee59b58ce2c0933fa GIT binary patch literal 3714 zcmc(i%Wm5^6o%dFv_T(&=q9pZNVe?MNzeos3}#k?B1JEwoj^&)4jY=3NGgdJ1?C0j zVdo9zkh(;18nlx_$;M$qNBqvu|NNx>e)6>#c+s=LV8H1HRPiYK3&+7H4N3>6<%T6p ztb&tGdP>#$M9D9Z8Xc6vFvB4WE+7f>O+fRUvy>Vpg$_QP1gR88NzUy<aE@kcCj5L; zJdU2?(^Hv2@g({Ohi~ne$izODyj{zz<Zw)=A(PALG&xA;d-KVdEExy#x+kdDW5SsL zvN$fDM$eH+mL@Mv@htky0dlG}+5Jp;3BM~P)$TE2;+%4p;r|&>l#``Y_&4JX$ptf~ zB%vC}baF^`-$?<x#q;PTKFKJWLPFEC;+N>(SA)UF=6B+)r8Y!C3c`?-a!znfGd$cO z<c~X5zT%}6fdXw5OATZweN$yPJs2Y^uGUQADulo#q+V(_V@yDtGbP0uX@+-3_(4ZB zSo@Qy!)h#W=XI;nS6n8P>rUPCuwH=Eb&}CzSG5Md^kb_yC~}0V+bOa<Bunq!Dqrl+ zUF8{YFc2H6&m0@tL8=U?)^V12_QSVxKHBc+2)C~&aR+^>R@$2khd!2qE#wXTB~u!I z{-l68`joCf2N~r-zOkQGlXf)?!^Og}SBux!rc{E^jON%I4VDuciPgq7Gw@80vB}Y$ zNohd$09&uG16|lA?HFM{yaid8IVkVL`#<sfV`7P0RUd@hrbvf-vA4eso=Pt08c<8D z5}o2yj;qaxFK||STjZnB{iwdh{$??A?AO?wT^wJ74wpF<S;Oq6Vhp3BcGRa)wvgwu zy$ZR4s=R%Uq%!whi&=}{F_(?WXe4uc@=+e!cI*K%W7KxH4z?g?^C~-_aC~n6YY`hb z$LgC+j-GCH>?qnNZ5%VfOdNMyeDKDp+7%UCU^w<BHR>8hR!*z$*+oynwlT3K?0kO9 z?mJ8cIUb*QJbDO<BaNG1=UQx)?m^SrKxcKFwMg9%ZWHa-Dvg^|YrpJarau(;ta3uj zat+*`%k2yvBklMeh}*U7<@FmD4)>~?MEkv~Y;f*afr;BWP%&N(ohvXl@ZhTq;;HkV zb?*>-vx@1gx(CMY`V+@D<adtqTt)VR<l&9C#0=>a(SyyuPhGjjLEk`TLZIGPv=0Fo zR*8(s*Rb5c#HRC?m9m|B$D~%c$GGb(cjGJxYh_t>4cI7;OR=i9e>mK^dJj7MpRYkX X#f#_#z6WVRbA2jJ@$zf2Q~Lh__Kp-v literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-00-27.613a119a-0ba5-453a-9a33-57e1c58e2a45 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-00-27.613a119a-0ba5-453a-9a33-57e1c58e2a45 new file mode 100644 index 0000000000000000000000000000000000000000..6d3987b00dcff4e39b69376ee59b58ce2c0933fa GIT binary patch literal 3714 zcmc(i%Wm5^6o%dFv_T(&=q9pZNVe?MNzeos3}#k?B1JEwoj^&)4jY=3NGgdJ1?C0j zVdo9zkh(;18nlx_$;M$qNBqvu|NNx>e)6>#c+s=LV8H1HRPiYK3&+7H4N3>6<%T6p ztb&tGdP>#$M9D9Z8Xc6vFvB4WE+7f>O+fRUvy>Vpg$_QP1gR88NzUy<aE@kcCj5L; zJdU2?(^Hv2@g({Ohi~ne$izODyj{zz<Zw)=A(PALG&xA;d-KVdEExy#x+kdDW5SsL zvN$fDM$eH+mL@Mv@htky0dlG}+5Jp;3BM~P)$TE2;+%4p;r|&>l#``Y_&4JX$ptf~ zB%vC}baF^`-$?<x#q;PTKFKJWLPFEC;+N>(SA)UF=6B+)r8Y!C3c`?-a!znfGd$cO z<c~X5zT%}6fdXw5OATZweN$yPJs2Y^uGUQADulo#q+V(_V@yDtGbP0uX@+-3_(4ZB zSo@Qy!)h#W=XI;nS6n8P>rUPCuwH=Eb&}CzSG5Md^kb_yC~}0V+bOa<Bunq!Dqrl+ zUF8{YFc2H6&m0@tL8=U?)^V12_QSVxKHBc+2)C~&aR+^>R@$2khd!2qE#wXTB~u!I z{-l68`joCf2N~r-zOkQGlXf)?!^Og}SBux!rc{E^jON%I4VDuciPgq7Gw@80vB}Y$ zNohd$09&uG16|lA?HFM{yaid8IVkVL`#<sfV`7P0RUd@hrbvf-vA4eso=Pt08c<8D z5}o2yj;qaxFK||STjZnB{iwdh{$??A?AO?wT^wJ74wpF<S;Oq6Vhp3BcGRa)wvgwu zy$ZR4s=R%Uq%!whi&=}{F_(?WXe4uc@=+e!cI*K%W7KxH4z?g?^C~-_aC~n6YY`hb z$LgC+j-GCH>?qnNZ5%VfOdNMyeDKDp+7%UCU^w<BHR>8hR!*z$*+oynwlT3K?0kO9 z?mJ8cIUb*QJbDO<BaNG1=UQx)?m^SrKxcKFwMg9%ZWHa-Dvg^|YrpJarau(;ta3uj zat+*`%k2yvBklMeh}*U7<@FmD4)>~?MEkv~Y;f*afr;BWP%&N(ohvXl@ZhTq;;HkV zb?*>-vx@1gx(CMY`V+@D<adtqTt)VR<l&9C#0=>a(SyyuPhGjjLEk`TLZIGPv=0Fo zR*8(s*Rb5c#HRC?m9m|B$D~%c$GGb(cjGJxYh_t>4cI7;OR=i9e>mK^dJj7MpRYkX X#f#_#z6WVRbA2jJ@$zf2Q~Lh__Kp-v literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-01-44.9e59b647-658d-4421-ae22-a190c64bfe1b b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-01-44.9e59b647-658d-4421-ae22-a190c64bfe1b new file mode 100644 index 0000000000000000000000000000000000000000..c827915016a32982feddd8e8ae310dda6ffae2c6 GIT binary patch literal 43454 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 Uo4#w<@ZUa&|E`4p-t)x&1J-)gasU7T literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-02-37.c1142121-3382-4594-83bc-a3b9308934fc b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-02-37.c1142121-3382-4594-83bc-a3b9308934fc new file mode 100644 index 0000000000000000000000000000000000000000..2ca6bfb832468047c9796bb8909a13d58cfef358 GIT binary patch literal 42185 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-03-42.3c3cd596-1ccb-4f9c-8c32-cd19025ffd4f b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-03-42.3c3cd596-1ccb-4f9c-8c32-cd19025ffd4f new file mode 100644 index 0000000000000000000000000000000000000000..49075d02de9a4ff7bd29f0e257205a1d7d345dc6 GIT binary patch literal 46799 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-03-43.d0b4f48a-9dd9-44ba-a63c-64bb97ba554a b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-03-43.d0b4f48a-9dd9-44ba-a63c-64bb97ba554a new file mode 100644 index 0000000000000000000000000000000000000000..4ede5c3c712f3122661abb5a6209382262f58bf3 GIT binary patch literal 46458 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-03-45.33a89a0c-4c2a-48ec-b408-2510e4955953 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-03-45.33a89a0c-4c2a-48ec-b408-2510e4955953 new file mode 100644 index 0000000000000000000000000000000000000000..49eb11266480c8a572620e05c050184f3a6f8ab7 GIT binary patch literal 46799 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-03-50.6269acaa-fd38-4447-9e73-6069412873f0 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-03-50.6269acaa-fd38-4447-9e73-6069412873f0 new file mode 100644 index 0000000000000000000000000000000000000000..06ecc0afc532a7b0a452f6d0e1bee2eefe4afc0c GIT binary patch literal 46718 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-11-05.73b365fe-f13f-4c3f-b11d-e53a45441ddb b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-11-05.73b365fe-f13f-4c3f-b11d-e53a45441ddb new file mode 100644 index 0000000000000000000000000000000000000000..a7fb8fa4db43bfb40de13471052dcbb2500664ab GIT binary patch literal 63749 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 Bx9b1^ literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-11-48.01e44a61-c972-484b-b3aa-f74d6e69e3f4 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-11-48.01e44a61-c972-484b-b3aa-f74d6e69e3f4 new file mode 100644 index 0000000000000000000000000000000000000000..0b4b88ce1b67ad42f2192147e98742bccfce78af GIT binary patch literal 88804 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 KEdI9Jng0*U^5m)j literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-16-50.3e136a9b-0940-4a33-974f-2f92641aa949 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-16-50.3e136a9b-0940-4a33-974f-2f92641aa949 new file mode 100644 index 0000000000000000000000000000000000000000..7c0ba05f405b391c5e768e8b1dbd3725a85c770d GIT binary patch literal 42538 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 OpTd7t!awmm@&5qu?1Uo# literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-16-57.436c807c-5074-4991-9b08-f749854a201a b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.12-16-57.436c807c-5074-4991-9b08-f749854a201a new file mode 100644 index 0000000000000000000000000000000000000000..c425d951e11156197af98abb13e84090735630ff GIT binary patch literal 42242 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-23-55.ef12ccd5-6a87-4915-a2e6-6311dff79d62 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-23-55.ef12ccd5-6a87-4915-a2e6-6311dff79d62 new file mode 100644 index 0000000000000000000000000000000000000000..41cb3d9f505581b1ba884cd9c8572ad0ddff5c54 GIT binary patch literal 40159 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 ZV-4`8RLaL{a3Rau0O$GA?eo>Y~;$3DTE;jIk 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-24-12.f06cfd75-143b-4067-af17-9d7bd3f2ffff b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-24-12.f06cfd75-143b-4067-af17-9d7bd3f2ffff new file mode 100644 index 0000000000000000000000000000000000000000..41cb3d9f505581b1ba884cd9c8572ad0ddff5c54 GIT binary patch literal 40159 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 ZV-4`8RLaL{a3Rau0O$GA?eo>Y~;$3DTE;jIk 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-35-54.b4ea48c0-9572-44ab-a2bd-5835208e72d4 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-35-54.b4ea48c0-9572-44ab-a2bd-5835208e72d4 new file mode 100644 index 0000000000000000000000000000000000000000..98349db63206cc842383069f9c950173818ada49 GIT binary patch literal 86771 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 j(d%`8x! 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-44-42.762a4cbe-9fd4-429b-ad90-65afd6cfa2f7 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-44-42.762a4cbe-9fd4-429b-ad90-65afd6cfa2f7 new file mode 100644 index 0000000000000000000000000000000000000000..417e45b99448ee54556d99f4cf25c080b6375005 GIT binary patch literal 81320 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-44-51.5f6b97d4-f2db-44ff-b5a0-c0f44a7ae176 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-44-51.5f6b97d4-f2db-44ff-b5a0-c0f44a7ae176 new file mode 100644 index 0000000000000000000000000000000000000000..afac58d9546ad4474c706d22a7ea876fd2553ee6 GIT binary patch literal 81394 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%0DL zPb@@PFfe6{$o1K*)MTkXF4^OfSzt+=(tKi|G7q&0GJs@`OZB^BbU3Td@=i#pr&Ez8 zJI=FFY)i;=+LTeM$PX4e8A=`BM4;*Z`U$}bXCHbIn0yeUTT7R2E@z1J<D4Gj9FuWj z{-xj$!O{G92iH|Z6tMHF!pbAHm^iK?L`F!np0V_Vl|+uyfVt8ud4|w30))V6h#O5x zLz-Vcpnt>)9w<hKFTC1CH&Ib2@`2iHY^&B@_^|c{a?xQS5y=$*m3EIq1jD3;6}ng{ z&`(K5!c=Py0jpiDD%g}b^*BryN#`JVSWYPSRQTA3oV1DB2su$=Tq*<+<0|FQ$8E$0 zC~9oOXHB5d;r2@r9Vc>xQV~MLjmstlH!?CifQ>tmLZMP~Z2c#nNs*~z-au?@_6EwU zNVv5M0~!!b@!>J-dO=Pe14U9vA>0|{ZI=!>91s<g&66Rs2x-Q^h!&3Dp}<H%z-$fL zx`guvjbZ@UQpP1$q{6}ns7I(chZxRUXDt>6P9*1{m+YHMrg5Sk?feI=HlZ9c%myoB zDui@5VcPk4cG73?7*gfqfwsQ$AU0M_#cxX~Ad6630umMaE_<%sC32q{;2Apa=f>hj zi9rAI7CN*6u>CffJ@uocd@x3gW}g@(&%sMypk(xt5W!fGvBSX(;Xqf;lI3lBk!N1v zN3wXR6C+%ojmdBmq8B=MSq_3ekXr!w`i2Nzzk1{5*78OH87A8eIit7bs%jq=k(&<( zB3i1|5Kkt?xsp9SM!Bgq-7G$RVScV!xgc%c_|fGex3Kk$aR~L2<`I^qzRy_pv75%? z4F_IG&qDdad&u&nxWn6qk4O6O;5&g!NJKD~c(?>{1Pv>ZpaAi}8-hvL(b$9;gXsf~ zWrR?mkKd(BK2^vrVe>=QrZ(;+DX1;%`jA^z9N47@UcL(SMzsVSC-_MkO+R}Kq0x64 zdwc~Gp&lyS!q<^r&LRMT#nKTMp<t<aA5!(yiCRk?vqdy_59>OD!tf5?F^MIHY<)Q# zC`IbQ(>+t*9P8<x30e~z9BlVA?4Bt?vV=$sOu`LzN=InyA!X9xaw??cQU-gLBJKQq ztWD`sId6M+lfwSllg)k`8ymi_^g=n^DcU(A6}iy6&VfXCiZR#**&Pz%95L3ck6-}L znbba<GEH0H0Y;RbrHwe3K7E!$=nWzb&IlXeWw<Ea`=NN?n4nH@rRF-2>%9)eF;J)9 zHfIErC*6#r^x49Uuzug5wEDOKP1+=weY!ful(-QndD*#S%i)SXpoiZkURqwdy>;X2 zbHa)e;R9q=Up6pN9{RwzK!$eF<@ezwjW36K0th1|6ghK~#n%BEiEd~vtWbRu>DZ7i zwklT}(HtAeuQV=HGZpS9a3;9-sIi9hm2{wvv4AJ14L#3Nmb&hFyGUL}t27%>L#-mm z7L!c@hT&cw)`;Vt3O0y^p03^#hx<nGb+5x=N!Pmd8ByWkUT6>J%fVGOskIK}7oywh zfEGm?6r^+K&RXZr!J%&JwybUA=0)}*4T&7lY2nHb6?WM61OegtyJ$bVv)7601j+XR z+3C)m)OASc4Z7okbs%HX*D>qt*>mTl40@DlsJ1nReo1G~zJTxi_kE^?(rdabMR5zz zFY)O9SZdr|h*-J=i2*M<y<$JocgH1aK|G}I^o)ZQPx&t*<e;T(p&K3{h&$3EzKIkQ zG^lKb6$H<O(9ShPg^nFn!1(d2m&&xjc>L`Bp!GpEq#7GQ8U?0Micz8;&XfD&#Fd%K zA+FXGujz;L<UW{{jSQ<VsLiov!@w$v=j?}n5JGTr2{WK8UG{e1g1Kj>W~S!n_)eNY zi%)=WJxvT~ga8C8Gnx@+=O${>>ZNn%z@}oN2~6_R<iyPU?A&<|zYWGEk`qK#SG^Js z0;swDiiG61Y7>|!5CaGksOB&dg(u;5G@c`o1ORCpD$24ew{9KU4TL#uZ{IqkI4cuZ z+VcAj+lOs6*Jf|o6_oTF_w4dQ?Ai=m+J&nRO&l#B^UkS$9f+g>Rq|0X&=-e_$CCsk z8QEG%ad!N!QZ`2rH9|pWG^uc_DsB{;n5sFl5kH-0_t|?~;n;nP9|-q@Xl#w~w>WFx zeajEtXXx2|N!Mz*pyXt2iFt?uxKTEJmo`2Sl&zlUaIqo2tJ?FNxyM|QJcw+O0}!Zq z>Gsyv`Wgj!ae}SDZi7RZQd!3(Uut!?m=@VpDcfY3%sR-Y$}e`xh%Y?Xsg$Bixf*J% zrXU^R*u}vSEna2CTbJ@+x~;ip+F`rotWbn1<lR7uK{0ZgKxB*?ZyVW|%e(<Xf^kXh z!A@)VNWP7wRWYH0(4fvGt=Qm#<s{S^KbXHCN)79iU!`G>0tyX#cB;-0m*W#)*${Px z3Eh#D7)Ie96^1=cT!HaIeU$2p4-ZFqd8cVFAN=6Ca{>M3gC8v5647_K7K0VyanfP< z^bBe+{-;8J@jpFj?S%+6P=f(VZ=nX`wl=Z`!$|iw&|j|H*j#xF6&N_-cazXy0&s>= zVW8H<ut>bc78-7#;l1-KGyGXVo8b?KS7*qH&?Q0~dcc<W&a}`-+(g4E-lN{|$BFAV zKCq8c!SN&V&NR>b{Zw#{FA_*Z(lYWmX*td`4XQbT$3o8uJRU~T@slmm)DYNUbxk!_ zun-Q`b_lVA)g2)2@goIIHr)nC)_6D(hf{fodR?OpejU?n(}frGTaDr<3k(+gW~*{b z-ck5C_0f`?qxVC)&bkY5DBA?E=;vdnExcIJ1wq|^J)>OJ6d8Fr#jDU}nNcjzHZzFz zlnxIEtWB49Ou5}CH+3AVjr8V6`bGmygZS47oU}^d`p}*`@_UdZ(g4xnZU#zA5;y#X zf+0}7*o|_PP@pz5kcT$qcP|915h9L(k_MMdtb3}}9ank}hM+@@Kv*lLSTwuUP!xOM z-Oz!y*ugy~bv7<?fKRfDiyW$!l^5fj!;gOE;gm>w0E~FrAXlPDQa&$TQ4o8N8@_O? zzBY|K2kj2O!-;p0Iuc4DdQms^ChkV==q)5{HdR@JMrz`iJUh-P-Lv%80E;mJLBtZc z1BQGYn2KyEKo!a@Lf|v3Vn1i7bIF%zh=wFqL#*PE4T+J-(A{9vG6@F{=_7mD#~vP9 zCsb4rYlg)9ga`{3LeXTB_1I#9LLiV-A<Dnc?hT8&tBdhtXa^y4rCm5BDcGCB94QS4 zu3>H}*peyTlW5j}oMV`Yq2Os`LO3feBGsL1zHmez)Y~O;P4M&9;(%!gfV4Bax;Kk4 z?6bon;Py4z+Y)k*Q+T*W2zt2m4YF-}w~sSN9J+O{G>b&N55GD$MEP&RL*M*2M1?|5 zYS2CFE;URyPldJ@LM4(fY3G`%(MF$NMUecEJ6ttv2iUC(^<tXO?i`)(N7deR0+|W; zCwJi`4PM3&LKL=I3e~00s?e7!xUw1AjZkUkL|i!<ooKzMeqa_eRH+Mt3cB@dUDqnI ziJL5$pyW|?Ih;t_FFUWgGvBSWZ^9OlaT*i2MJO=AN)o#pl-+xXEH=(f?MUaMBW}`j zKdAG-$?73~aZkLsDOALQVVUvpJn|}ZU-)17E}tYa@sGE5Rc{}%%kHIiN7J&JQb)+y zAZn85Tht?!q^Hl%JUw~-Ldd-|fr297x25mr4xuskLK4Ils5|{5O{}f&D{yvPI&||C zupY3^cnLyPhv?8P4o<4znzCLz#QN?KP~0X-@gRkKet&;Ix35&D+J`x0<jJQN`41sr z1@ghp_<wtUE#x@|L`j1H9R+7TmCZ_&Ht8NhTDTrE=rUUm2Raojvsz3Iq8Gm>NNB0| ztb7IhjAI*eJ6GwnYPeArQ5v~>OkWM+O6s#mNy3O8t7T5=tc$?Ru+0wYqeIl5VqUqi zqw71GQif`!9a69-@&!hpib79mfR;qzL1V-2As%*sh{pny?inN(P0#3r)JsQ>5T!LJ zrs#ILe3!+#bFB*>hkR|mO~||;rp}%8HAby20q&#=FMwyNxbt)8My+rs-9zgT?A%U< z&^}ZvO{MP(6xb!c1T(;ah=)U_RT-VTDr=UL<27QLqRMnhGNvZtP3)$IFG0MGZzz4! znKNhfj*U&0@r|YH__4r5yOdtS&4?<p+9}JXshjCVDSc(>CXO3d?jc<wrRcyWNuui$ zSs^LSE{o`90Zkj<RQgtcBf7C9g~m6RzW<3cXWXQPQl_a}Hh7_mXk0{fY8rA6SvJ$0 zuObDDl*%IsnQ7%4okO(($|G(KCkxHyEmJ2HtbC_stG1@p@_cIL*~Tvqx&x;wGPoh| z4Fsbzozm3gg>ll=yD!;BP&rVlnQ9fAJrK6Fr<!_;T}F+U@lf#G7;NP?Z{;bx*~*K{ zrra+%8V?t@=~;%`0_-CloFQeHi36pvG2z6(f%aY4sjxYhwS4=K{?b**9?G1bn`W(- z%R36>q-~bV3<2Cv-!WU#CD~G|o3?HOO3p3AhP+%xSe%ALQLyZdJ?Uqc!l>Nxr134K zZvnelEx8RP$2Pw8zVT$H^o@AbK17_j@ogm=-<?3m>D*jyq96^;AYdQ#p2bLJkngOn z9t>Z3%=q@wH=t?CF=u>7>HG0@6|t6^N?V$mktU}LGc$$RNoi_ga^Cn(Hl6Bl@hX<_ z5AGV@mAP+xcZOA`tU|{3lrE$C&}c{Vweh_iXs1;*-c@=MK)al6{6qGRW|Z-LrLSVn zaTYHw5TlC;EVvC*SeiJPoUF)lWu`KLL|*RPL;Ale#hkZ>X64C6-#jY5kX}j`Bq33_ zVTM>gx0FW7^wQdM<@KvQC6Jp>1+{gYG<8a_!ke2nuC2XqlZuN(7}ApSkQHdRFYB$k zy5lb)p0Xmi(59z3Qm4@py`nOgdI~U%FY%YoxtxeH;w^)-e&xA{V)TX;*@!5x!C$lR z&4?oW9iU*85KE5p>xx-SkIGu3$SW)!xUH+E6wQ>owmBP)g{Q8pU*3A|)-nQ**+N4K z#5NR=%#JPHSSB1>kUF02$>6mqHD>%HHvdV0TgLa_H~w*E<zJP40K85sBY=A(HYMI% z(_2cx_$Mp>n$1xvLmzLUqV&Rj;|Es$P3dU|i09>Yx?CpKFPGDISsFah)A*+=|F)D1 zFH6=Rrz~oAXCIy!Ke+Pmm@uREZS$~T{Lsq3FG&s@hE&A5WBl;Se<*#IXz-w_v~B77 z*4C|pA+7w!(sy_un6hdq##1Z*$t8%wi*LBgA6vHzMr!3hmzF&>pO$JmvwkZrXcEXH z3b`g_^h&)0%>tL1FvF{k-HA%4<pSW0r#nozXs~%1??$hfWb8EC#@YMEGnvx2p&?59 zX=BXLM<dO~Vu3x%V*Pa|F1=kexPWI1urXGuq4HZHql|M5PtV{R?<qCD?#!7}aTO-3 zFC{LnjPXwAzLCu|zNd5tV}6oC%g8m}#pa?|?~Huo`$||7&t%4oi3X&~WM<{Rls<?D zG%@KD6mCK(=WoSde?}4URQwxuYlAVh@?T4-=!V4Y4agsFOs~9NT8S<iecdBRAhh|J zm7~(TqhX5X+2s+&?8<}05jel{u=Jk62zW1(Fy>a?C~ZgA=|_k_iWV_6JvJ6&e&x;5 zw|m;44V7_W<-e7-AQPxsFGqNJLa6HEnb$soO_;|5Cak{PCi~94WWp${{7q@qp*UIB z9p0lI8Wca7wkQ_AgE0I~!tOTHbJ>J(apk|iH4}MZ<!^_b$i<cak@!4XT=}1+w1-~< z>?tO)xQxPh@5=v59ETrS`QN3?U>w}bDU79+|8wFK`O?b&?VZS%SN>mV%fU22DOk?L zq@`&dJ(0zf?y;X-S@}Dr*oB@5FBa2I62*eC+-baf<!>6$lCCnPmN{gMYiz%WOv1Pv z&$w=3QM^Hm;w_*%>Y_Mkzi+$`3n8gz?k2umHde3}F5wy5$QKu2;E_6}itqqKgChY3 zW6Rn3^9LzxH?Y|+_SkyHjGMHSu4Yz$^NG?AJH&<yLGm=_F%}ezwbf5OQCf5g678YR zbIVecks)2y<mV5O&<vhe%27@^=kFNntDk<tr`-}P`T$LmCWBz!T>8=H$}H{kW_qk( z+*<w26QxTYv<MVylI67F8DuRGVV^u#*d~wxBv<x8$>C6Ch72Oc`&U2vMCn=pmSa_6 z)mVQ(B&f=~TV4M#j@7VCI%w+LIo{Zqv9bEOCrWc3fFqh{jLp^0KT$&cGsf2HZ#_|Z z#sS60$r9F|?l_Gj6au#tfG)RJzwkuqoTq6F7dp9Jn7k`Jg(!(Ke3KXthv?M1g7JaX z-+rR>L!LTBOSWy1HV<)d^MLJ7GRCu*8R!{JjZ&ucy{NFG=@o1}yrw7Pxzae^2ulL9 zWaS!))`o#F#|)OZRKQyyy=eSs=?788`>=<%jP24afweRouib}N0PxToVG481Trhgp zr8H+HVF0xjjXP}fL!CA5vK{3R^T+tH($}Lw5XvZ*z8l|qrjqf&PDf!PLLn=*A(y@r z#r)Paqr&8d!iLAFmhuE>MC)vgS!emC5hfl(xo^}n>{+>7m9cg}JnXO@(!Sbgh*z-D zT6m@Mja`JT*tqA28kQX5z($4LE-cM?iSR9Ma5S2XuNUYd484~141`;Rje(yE&g5P+ zT1>$&m+8DbTGE+%kDY$I^vxg)J%>@#FiKPS)!mBn#vq~CYZ~GR@TLHxR{_Q<eIHTV zEz7pjbsf&6T-vbNxRlF^fs!5GU~i}BZNL8PF@qk=5lA2|Q;+sJm%6)X7j;ph5B3KR zN;@>5hfyfe+kPlL&#V%`iDA4@S|FPCcG0mVdnb@fF*fhr!TWK6A9eJ8Bz}0?55J#q zSO9K`2H^a&(o8sB{Cz)2FFKIOGXzK<ih{)7_k;A4Y=W1|tfbYcu(<+|KNZD@fr2!s zEI&7wJd4IpJES5bmGR*yQZW-&ABOmdfI{8-nMf!D2>y}-1#4H?_}M5Z^tK;~e$JU% zxR3>4ex7NRAv2V{?jgr7IMW2a^-h)0_{FGcB1-h3$}chN8X58!Fy#R7UM|gtOAJq; zJ|I8paFVICN&fuvC{E(<`;qBmj=*%+Xycco1g2Z0AH0t<ExBAqVT#}++I@lp>=iNH zGJU%GE6z|@h_}@10Qaj=Lm^7^0rqPSQ^1V}NWWg14xh^Gb-!Nzh9k4Y)NAPaE&zVA zG#Ngs{&Iw%Z}$CW>0PJ?qIKHrUZHY#ZTl2kubE5M__V`FuHO?)ex~$2)TH~!6@H&( ziz4Zg#^)G&WKtup<Eim6<MT{K*jMdF*=@r3t<r_CZu(308HF!&*bLWn_>nB*x9=Oj z!~IxH-}&94^_|~y^__naq3`^DhmE%rVq^S4wd*E&5@B!UPOFVn6`Jy-@rReD<TGdf zI*UJKRasnMnmPV4@qb*lVjt2)Y<0vUW%m_zr(qW=NXT&!-a~{u$XXU|rJYv6*4wxd zhr-LS-$NeYZq3kw1yO2|waEsVZwL7cx+^#y2JJR-a4`RxXhL*h7(_O2C4&WcFHZA< z_D<g8L~yC9wK%Adews}Cnu<__I4Dd`!5@wPO(uf}I2cw~<nf7viwHJI2o-%78Pww7 zAvh$?>~ym7Axf#tjvB;i-yM@|ZAQK@GdVYtovY8)voq5(wX8hH{!GoBuUwd$tISRx z2U~>FQPfBrBoi5=n%<OE1o@0E%@S!Iw<l2|sz=s7#Ww0K?eLKy(3B6d2#<MW?YCvS z@yHrSHmi>L==zSOl9GZZ()}dYGLHna+HtV+h_CvjJUdaD%PO_{Y<6bmd^Iai%+6#h zlM|Ej^!%hUrzof5E4ChXD!xv|SDXo&$lCcf5MTR>1_dXUgzw6*N@ZqtqB=F3txnEg z$j;0v3RJLpIeTG#qCRtBR;ehHrz#k@Fy>zJREC|(u)o(bEJ@W2aeuLBbqs40#c-CF zE?-{0wH2pnc94Z4YsWqDy7>co@}7g>)24ROC{E-qjH^v-O6Y7v+xaTDTRY?D^5@w5 z`9#()Pshs3YnRur+*rF7r-wVwt8FB_R_YXuIxbaU`Ct}4wx^9P7QNWrTw1$!d+FM8 z9PFNNWG}CcKi_Z&tF)4);N_*u*O$we*Vnc-)^Ena(Ak0(Cz7Mv<@NQI8?ngc+50f- zO|h#73}cG9h^Pv7(*v1*9PPscVi;Az2f}K5YS)I@OeMy9*Vi{=O?a1Jh53nz1jqE& z#(L>F;<L5o%Ud_r*W$3+uA;Qbl)eX*FsV7Zv3zxTV|gPEI?l;fKgH<im9T^6;jzGR zv3#xaUVZ~nt&(GB)e!4J`SD;q$f>on)5{6c`Sz`A8%tM~%Qx0GmoMMmST1iYzyJ2~ z=GJDM9wuW{X0q`1=JG}vLU1h>SFY;MtC}X~XLA!$W))YZwrt&MT$Jc)9ZkXmX?;^F zAwhq6a=LteOj?46LwQ!Itf+Q=c6u&1eO}6}T;E!~Nr&=w73rE%-POmW%ME00QS#^K zVL+drnSm93;=Hse*JV?6swKy0CB$m2;l|gs@&}eTHe=3!nH*3}1gBd|Ti3xPSJ&h4 zg^$VAR!xCJD}f0KM%{R>yt%azb16>*iH+se^{wUd(v>T*gn}y#l0@d#`bMm2Gdnji zH<b_~Op26Om$$C3Ux~vr*Ot+R1ej#=^2Uu@TjjN-)mR!rGB_-6U=qj1p($5!7JnD1 zNZ=bz5}~+!lGsuYAy0(CV!yS1Ii5aAt3`e?A%CWW&*u8ot!I}uVlm8yUfoq}X)-sJ zJD<o{K|4Tv9kM{0u^d+~JoEIy)ZE2UgS0){H+H6$Lm8J6faWO5`2;~S<=p{zKPjq< zm<Oxemd%)6(-Fy@2<p`)e9@0numteY+w639oQ2>S&A#{nite_=0q}|1#OwuSz92cg zt+qKU6&&t#*Hk};wRO`L1xbPlX5Nt%@t6WM#A7;JwXd5s@s9s{j(zxdQPQ%sa+N}N z>J%m80^@~xi?&U5k3!iHTFqYyynBmQ<uJfLEV1*X!@v~v?}x@NR>HM)ikWMxPA>$; zn!Yo*77F<>!bw`YVIo_dC0g=gg7h@~-pU7k-XePj@GSRs!ngGKv2nt%5WTE)lrlx@ z39OK$f`7Hurh<$i;`yXI<W{3&*Yy2XIZ(o_X)!4t`I^gP0hj+f;#B9A1g7YHMYr4@ zu-Gl}4!371ZXbMaz)3B;tWeeycSw8%YD%SpY&v_2CUBkh&_L1L$KHXg@ca{^h7TZa zpI2L<Z+PZPo;fuf8MEWo<Pi8@(M=1NN>Wx4Q-Js4#DW2PO88L2?Q|}cyj77}r;2PT z0;;c$rPrfh0^i7r^x~dg2?dI1OQd!XulT?Gujp#q)M?I|6woiqc~PcQR>-I(UinaN z={p@Y^bN^;@nV~Q;eU~%j(=(4v`VYhrLYe$SV=MKNP*)5@uCD`l&wPxw*r=l&~6zY z2sTPp9n1`Su0VyAxc|(KeKC>MtyV!WFtdfkQil*EoEb|75t>^_J+KpJQDa0&1PvC0 z`Zm*0XlW|TRZ1EWhj@>#lfl!mGLly4l-D&*4^PI);KfdpTRWYYp<pNJWMDY5i&I(D zI)Y2%&@Wjh1IGzFa21B+(L)zKK7x0ylY!B&fi!AyDCjEm$vGJqK3Inj4vEiNFuTW$ z%}dzH!0<xeFXZ8bXK{39qxv`v?WdT}{`%HB8CZWhZKTz&DL7xoV=!@c30ga}h&Vk= z#>v3(!oH&nAs8<r`t9vxU<5e8QFT)LT4m^Laidd{b26w_`5w!C7l$vBQ>lPP`w({U z(Pv-6IJ9F$iYJPMg&T>hv6j6pvx9mGSn!$IyG(0GEP3G%IOb=g3WYj81y@Q&;K>X7 zY!H1*779_qi9@O@^Am-_{M>Zm{QL!_aK1iSEles(l%1GYLfYrt)a*=dZZ<bL73Iux zibfvpNir&lg7_iI>w26S;#-Q6a|JSgd709w##6W>hE*JM8}6i@sWg#-9Or;)v6k*Z z+!zZPGJ3`tr{r9L!cNDJ-p9cuDOaGt1c_tfpm9R1%TskT+h-iC65(8r{WT5_!$`={ zxYt1_F83zppcHtRx~(Jie;nc@>Y#M+A-g3K`@~w86L(PZ+`lkE#XH+IqTM_Zes@ql zhSEEgo1Du{W|5QtS)SfQZUlU7wsVwRIX8j-&gUj3a}!g!*{Ichv<b0q?Wj3!>5s#N z<U}j0dTtBW@EhyTI{Aah-%@le#VBCea59@@spZckx(3a8zwbN}RxRi8?X9cXc?UvL z7GBm>mf+S&uM@Y!Jmn9^j(}oYo$J`Dmb(h$yF-JMz@1$L78hw6rAwVU831Y<@U<b$ z6C0+<^NE?z8G)M}q`rj#1or+|YISnEj4nFdLl}p0iETC*GUV*gTk*C%3Dc!xYGv|! z#XHtSoBU)1CW)V8h|91|SpU6J?@lMlJq!)A<2a4OZf`en%JYT4J;f=unz-`gIHU9y zh|}`pB~CdykBK-fKR)8L{1}PT<Ct7eQk*6!W}$5=t+;k&Iy9EZ;>DwN;z*DY_a=0b z!;Kmwb3robBMv35cPcpx8&7pgiP&&s!tpXO#mTdC8U-7Ak(7_&PNQHwY12-lV1+Y) zZ*fHo*l85(ML~+wDA>~|Sllds8U=eA1?xurpGLusW|w9W=BH7xaa7vVXcsrfEsMB0 zjdr1Qzo*eIk5{zIqjeP~X^g=nBY(gn_Vxe^=N$9s;dP05d4L4+z}odrERTM2E*{|F z9%_nXpGp=JQiUHa7LPtgsHN}6Apu>vOhEuS@g+ln0OJzw@}8O*$KA{0(hUBcogA0u zCXo{Ld@^T{OnE>4QQstDGYNrX8F}f9St3?aSoY%#+zADBb?oZNa1u_adKqbUDj7y1 ze`p-?kt3Aff<TGAb2oAE*|VG1ZaCLQhy&X*%6Ubu&W8pt_*OXMiyt;#*)YDu?jsRb z;2D3^_`^$oi~G6$?hX7o_I(N!y%sC1TKIf7S&-?C^<W?C^Hb;N!uuF!cTi>Ljbbg< ze(%s|`#H~HrPFNC{V(P?O=f?Z%s!6HOvWqt4#;NjTN*f}V<*_e^?Yg*H-*MaqT`pS z{IJCfFGT1q{Pq3bJTyu6hvFj>SR6R6qy*9RT52_a&&uCphbeOR06z5ePEVbxW#y5X zN@>+(Glw6;)<auvwc%SsExsoY!!S`2;{wS?cUuKrn26JP6$SBs3K9^>xZgI8w22su z(X;|WhFw|}2Lt3T!{u!VIi5i%mxeoJ6F~{5HWgE?QrI~iU`%W-oa@0ZNuJu#b>w3y z%Pm<u#B{TeI5rMR6WcX4ScGu`#2byDO4(cbK1DcZFU8Wuxd1rPk-|Mmoj5}iwp4^Y zd*hYAdgGPP^>l%66}X7)XWemxFc0}aHfkB+-1(Yf;odk%^B%DMd6)wW!?ITC0W~6q z-u$-V(MWM|d-!vI`ryS6C5a!qVzLKdT>RergI{~|#m_wai(fwa;;;1pJq8u4EImdK z#3(eQp2yjg!agS-e^QJlD<}hUyru6soL!dIaK=TVz5Aiw`4Qy+XLK|rhigJYjS+EZ zf=O33RhHi_4rycwJAF;U#jz5Cxq3!54n}NgjH@p^t5l}ihZ6pgu9~17QsC_-f)&!; zQ98X?YYmNGQ*QfBE)(?&Q*)K+aFa`-T#sW=npL)Sie!#6#$l56$L{RE=T5GD`0fbe za+&;N;0Z3{M=Z`nZ9cM6lH_UQWWIBdDDLTN=fa94u@Z)?>SJ<Mri%}=>mlh(likgW ztTSbnpf3(zC8h=jkUPdDJ&B_Phl(8gaJ1+b148!9&<*Wq>ydy-JMcJzChW-WsT8>d zOCmqy$3r!b8+GnrXyqs8EBOhf(#-~x9p+MrgpWje=|v|Q<IpTQiin`tp(v3kzcgZ6 z6Xs=H`#N<VOI>BMdSSjkJvCdMQ)+Yd3svQOWdizGf=nH6JL+bxc<ZT(^tW-DN-!os zBrF;b;IOO2+Sn%+;UGHKl##QOj(f+Mb|D+dIQpo-1v+jVEc$JO<B4tywlt*uD%*$c zSmKC_{v@VdL*Iv9scXpg`iMyb^KU1XZa$UJwLey;Vykw%HT4RVgo<n_(ozj+s8zBy z(upZ4Bh=?)yySaoJPsCExHtXeLeIAO)L-MvA2$BwhVjRxZ$5M8j5C9bufP-jBVTvs z%wJ!`pJRK%Vc)jP*pealbSx`eV!9qfgn1p}OagIB(vGQj+PENzcJ>oJtD>K{fAV4D MPdALOb~?HL52F-74*&oF literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-47-26.cea36215-6c4f-4c24-b68a-9fa628c4095a b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-47-26.cea36215-6c4f-4c24-b68a-9fa628c4095a new file mode 100644 index 0000000000000000000000000000000000000000..1bd9f71cf140545254463d08cbb739cde1c258cb GIT binary patch literal 88904 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-47-53.8099e445-0191-4ba0-893c-0386f0015323 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-47-53.8099e445-0191-4ba0-893c-0386f0015323 new file mode 100644 index 0000000000000000000000000000000000000000..74c16bcea7ec7671994c527fbc1da4c8066c3323 GIT binary patch literal 88930 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-49-20.f6ac2903-4ac8-494a-a317-8d9a12efd0ca b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-49-20.f6ac2903-4ac8-494a-a317-8d9a12efd0ca new file mode 100644 index 0000000000000000000000000000000000000000..57b4c2445d11e8206005b0d6328c109da32a90a3 GIT binary patch literal 81569 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-58-55.3ec51b6c-4923-461a-a237-f93384d4a5dd b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.13-58-55.3ec51b6c-4923-461a-a237-f93384d4a5dd new file mode 100644 index 0000000000000000000000000000000000000000..8b084c7996980486040ab8173995c4344d99f24c GIT binary patch literal 42313 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-05-32.31f8dead-8462-4aa9-8261-8282ab1ab771 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-05-32.31f8dead-8462-4aa9-8261-8282ab1ab771 new file mode 100644 index 0000000000000000000000000000000000000000..1fad03c00ad7042e2787343d0e4a18346313f49a GIT binary patch literal 41986 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-27-09.2797c058-322a-4512-b0de-38cf90383715 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-27-09.2797c058-322a-4512-b0de-38cf90383715 new file mode 100644 index 0000000000000000000000000000000000000000..02ba58e7e7a7076cbba82fbad81b0c8a86ba248d GIT binary patch literal 85450 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-36-42.e8767d84-83ff-4302-ae92-1614609e7f6a b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-36-42.e8767d84-83ff-4302-ae92-1614609e7f6a new file mode 100644 index 0000000000000000000000000000000000000000..b50b722cc23e3988c5add2f0751848191a3d5416 GIT binary patch literal 85186 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 Wgjy5*W#0J8%f|gp<Ex!c?*9Xe`wqYW literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-42-19.091ca44b-ec9b-43b0-bc59-d7f510cb7196 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-42-19.091ca44b-ec9b-43b0-bc59-d7f510cb7196 new file mode 100644 index 0000000000000000000000000000000000000000..4a1eef36c804e18578baa15dd88fd8d3ec901b98 GIT binary patch literal 85486 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-43-25.aaba2dbc-357e-47ec-b9f2-3edea03a9b11 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-43-25.aaba2dbc-357e-47ec-b9f2-3edea03a9b11 new file mode 100644 index 0000000000000000000000000000000000000000..0876d959a34d827d1cf4ddccb7947103ebca5220 GIT binary patch literal 85782 zcmeHw`F|Y8btjcO%CSi{n@u*ywnnCAKw}PE1PEe~fFwx5AOIQwtx-T`+%waIX<%l0 z`WPHin3dy5Q5-u`>^PSbTXGaTm+0gZCypg2{$c-x{p@{w_Ok*>?eF{heqU8rPfs6n zG#a850iuAJ?y6U>-h1`x)vH&pp8w9f`k7SWyU(0CQ<o1FLw~Gr8=tecOvNy>wf3P} zQk&b^n}_9^Y&32f+Ky7T%xt@9sa9R7WcQWQc<V4Lw_0_zEL*D9G_xBwvwNztZ_-n_ z(ombuhfK|C)b;Nud>5K1YZXQR&cghkpE+YFW(yUS%)X&oN-8<`#Fe$no6p=_l&Jjt z?dIGQ>GYObl~UW5w6rK)82RNVQcH^?cjoEEyfjC}q;g$0&3vM%rFYDPRF|9E`9yM5 zQp~d4Qu0^jx~Ysj?rCZ>BbUoc%Tg*us?e6V6-hIsq|!|K$|e(N3GK~2v86OCYV{79 zzTK42x*}KDCwy)wmMjsiOvTD4+Ez6^lMwGvSK8m-&$MbSRjFjkS|eN50Ewt3*VFjk zP@0yRF4eX2Zn~oFH|v^QF|(505Wo|Nh5EjHXi8PhC@biurI?H;29Qz=FiTRJ+iFuG z)a;*>vZpj9mHt_V+*GU)=_%=Q&CnW(bk&d>?y~DjL)%j%tEQR~D1NB5rM5}m6$#uU zYMG`BA=clTWwp|Z-d6YWi9-6;Li)1SXh9fCbtNI8ix#?-Pb@9wmCCl#k0njbk_-St zw=$|(1TEycBsVKka<t4)&W|M-j{-Twd(G%1t!O2+u1Ft)EVeYmlCG);E}}>~nMNzy zU}Z>LS&^rtioB;*N@%mDwVRAb<GHaM6KE=trVd;3wi{4I*;C6(dS9(rwOMJcTyD1x zrE0rgm)Ijot1|MLWka#qV3|_6ZGdAIdZOYF8#!*6Y7=4sp@8tB3wdcQlLJ*OS#6q9 zMTMN0G}ORQ(}MI-6VGZIhT68IwJl;?i$uAmsM|G5nwL0=_IGzX;H|+Lk-;pqbEue- zT(4{UCc~LtOP0oflK^!jkukmr*~upa^<2DW9nZT7Gm7f2F6Gf7XJ9a0GT%=yoT1B# zlL!bgacLj_sGZAl@VwVdGDu!$vss{**`LU0#&(tz$W*o=8@p}D1n8Wht}%5L+-Fyl zX)5aKd;flL;dX)WW9`s}M*K!gk#`wytI{=1+pa64QblXtPFkb|wiSz51cgJR)sRf+ zP^sOTb+Os*@HVT<gc^FgAwzZy-(coE<wes3E4>G`Qnj_atDjvcs?Bn}T~Q>{I;<;Z zO;I4?9bu`f&0TP-o=<e%C#0I8RPzbK%>*~fmFA9_Dc7}jrCOH_g`p|$$OqZFS~9a$ zsFAe1ub5C;*~!dwCYLRn-H$Vn{|p``vO?qbYPTPoZmr))B~2Qc<>Y9R+A3+9WkP|r zL_^7u0LGnA<9wn`J2*^IPX|Vz2Gvz2#Q<$A2tOPF)CLp^=neG<7#aKuY+SMqG1(?q z>Fhz8wddysiN2Dyw0611i`cSoER<T!?Ld@7^L*~COCOQ<<c+eSwk%1;$ic)`(kx4B zz*IOOTY$zC<_=7zP4!tr+OMhQ8s=0|kfv))UEf@}F(oN=g-zO+P^*e;wG9Qj)*>6p zCH~O-)S79O`&%U4Vz*;rhO#k9k7s5w6HNAYf;m4wm*q{lyL^>%%!N-sDktY`ggGxQ z<-p4BfN1<_f*D<$5ZSD>SyNyh?8%182qa<TlEF}sN{5WLTyBdrkc%_}U}9{R$>O2u z#Pu?>V@fGbYgis+_z(;QGto$fH`WjBg^i7+YpWmGNIkwk-r@~HQmd-bC^lfU(0rJe zHdDz3U`S?-Nz9@T`!eQXXwV9n3DwC=AFV`&?$0MjMmx|ds!4q;?yFX<8|2fPLHaq9 z$#hqMaaM#hH6UlK>9fzI&o<I$E51?|ru4v)(%I{?XIEy=Zcr6QM8z;Pqd1kz5y;F6 z`qPxyGf9KxVJMYR34==pQ?|CCazRMxta;}SV+I)o$r0(SL{cUj+h*RGLh)sk*w}f5 zd8J4XMjj7PbAtcS@h+hYXHgZFn3;jOq8L^xH|mq}9n6WwA%vi72zS*Q^VA}hOx97e zA{#zs*j01fQxl`gso1N<34c8<v0gmw*$+Zt$tl;IAf7X9+%N2f&h2J6#q1*7=I7=( zpJPqQA=aqm>PMD{z$|44$&L={+YT{wF6%61=1N-SP^giLx+hjwG_){1n>AR8U?u;Z z#>i->7-D4b4{pbCIJDdfFy-g6XjLFUs(V%5E6IkGAMB^o^SP$%V2_Ukga1j_nQ?4? zQ4U&IWTYEVI@{?g(>^<G(^9L4SeUUDOu7t1T``2&gSFM1Y|mR+m__#LleLg8VVPBt zD(PxnIgs|#Q#q+&q~*4yCFUQz{KkVfzk2k>SKj{Ss}G<5<k4@we*cp%9KHB=58nFH z!+Wpc-_c8-oy*F0*Qu3K8`D$M(}JaK!wxhO_JqsJB(Qw3WK68|E}tlC^}5_LVVv^E z81b|!eUf*1Ro=T|Xf0Z2CZM)enRV3A>a>Vv-SC&-R8lJWM3vUlcD=d`MV(J<vSx|8 z>NZ=@xJZR=m>_U)Cu}nTiUdVm9nbP!xt_Qrk)sHlc^|RPv_I^p$8x!ZqykBQH#)F@ zQM=<b;A}&Aa0}I?zPtxxd}E3XhaxQI2F-2Gas~E5n^r4ZcV-`_1-bLWQ3CXo|M)=C zW31+&<x&jt$lN5sqD3<MzBOS(rGmX6&(&2I@zV^;z}D;*IrK3X^q>}GOyzt2B|Q}t zKP`A=Sik9k7sD<I!F!CT&OpKdZSICzs{+0UB*%OF&Pb0oL;D>FE7t>7*FYuwu~>17 zm|sQ+Z3RPz%L0A#G@9g7E4=}{0IpTUpzUfXh<1`FYHNfOpk=qh5$)M}p(ewx*J`)& z3Cm~;W#LsJ{`rD;-A5SC*<rW=nz$5(Kn^aPX4@-x0i#)<!A7;&E{TEdA9qx;7Z>S$ zN3tC}2w-291i&uZ$ZWZ#JfIvLmZ6d!P}~9QCUHQyq*v&vOwWdTssOjRgG{bzpWxDy zL538SbeieKi$FwK&G1@t**1BhsSWz^fq;TeVsft~N$+phwG!sW)JQ*V-#z^ZqlBiQ zMxEITAyW|y-frnV871+guo`S*LWu29W4lAN5Yo|OkdLUBA!lQ#T69V<&m7n8z4hqB zd#^wI+9!O>;)o0=EhK&}Q;gLO)hQiyOByC^ka^k7DXJfc&_E>Uni&XGRGs3Hbha3) zC{?*#x8Uk(9M<4tqjeayK|h}Iz4VHwD3;rA|HEIr{pOnwKL6=={`kwifcgm?LMy_E zMjUoon%hc|#_qmmRFcdn!T@BF0&l2=6}gH19kwY|v={G{j(`RA%qy=^DI5UXLuC^7 zthWm;ng>AWMfZT>p#A+XeEt6Ke3K7^qp!XA&S(GB&4GYAC#u^|N?;i&>)JMUKHS~& zh+;45d5VH^?>ztf(XYR0s}L7kJS7LGS8rVvm)v>K3z9hyO2zJGOrtwS3XwR{xHgn+ zm3AiHj|1Al-9_J^VK$s)MkD##&)@(0TYhQ>0Ut_}5&*|=3WDYp&A|DKDstXg*w5U1 ze`{szvwAuaJ2!vhpN_up#rKY04&|vM86L&rF-7`X?foohlAoSNxVwe9ER1B><6JV? zj_wNfGRb#2n0v6}9Q1WOxSs<Svr&N!GMJMRr8=mv%9o(~ntbox_By%>xYn}t60rc- zyRX*UYDH?`3v=JGhaIDH0L1Oh9@nnU&PT}?pQ>o(HtlVVWDHRDFeNr_QX|iC%G>1< z7WsWMCbk&qgJhBGSh9@7NT#7-ZbmqXk#e?uQX^7#b#iTwWaLWaGI>x_i5kpi=9x{5 zT$Jt#7;URB2!lng1Vg#lg)uhHgHfK<DwW$w7dE$({K=s8DbU6Pz<vY>cSrCmo9*5* zL2#3cuZFhIndg28&nEoR>9KKo6|iLh#VfXP1dsChq>6B$gJjqubgniY>>Th6fX!55 zVNX`!;RR=}z`0z)&Jy2c*raD>!q$zRdN7R80#V&3g7#cNE=+PuGk_hd+ye*guVQCT zl%oYU+Y508PY4Vg9YP;GV3@x0FSyfa9<gHNDsCL2Kb*i+AGWIB^@goa;qiZxj83&# z)jX?Y0CevKa2MwMgWvhH`!9Xt?Qg$!{}W%M*}2Q7F+f8@H1gmN-a7in&qr&@l1*%5 z4%nx+-+JrlQ?Es92rIXWid_f3Enzztf=PG(<yYQ*^Yv)WY#Um;HE@SGlODYFYtb5O zD2)=rX=-X~pnln{{o${n!J~it?9tzRF{D|DV%QL3D_uBQvF|9_PO&~0A<^Tu1Bzrh zXf)7s{?kVQ5e^2{&`|HsFNtpmB<3-gP{Swd12tIFwB11(OUz%Vk^zkb5{%mJY0ub3 z3MnnO`bFo(7GRHwm7qfrADboKma!uS&pBzR4j){;$T`Luv1!7;u-|D!Dyc2S<0=d# z3^}<gB~q_6k1LgwqjFthM1AZnN}=$nDz(8eL^BTjtxD-mhCMbrvj7#RpWdy7j0|3t z|JIGeeDbWB!9TS!pG%%iRZ63*wax-qls|T3R;ixv>em))>5k(_i>)O{8pgeBSw;$t zjwXvO10h$&;jVI+^e}ADHU}UkfkMk@G2?2`&$Ypuq>?>lMu4Kf2<0&?^e_(uwme8| z<?i^&EGqY7EH5`O9w320B|{-nG-|dGDoDZC@Sjq=RMN9=Dlid$2g7Ix+7Muute-WX z$R`pmX&-ekrua_3><h%`?_kIcOs;Ovm%AbHd9VhLLyfMH{|IS8J$B|G(S7&d{-hX) z?!9T=zY&JgKrK;8CU{AomJ|Kz-`v10h0?BH8w0fv2)!5NIm>X(#nj(9tHxuX5g|hn z%clCQGK=W_=_#dgv12|6(mZ9zdRx2LUk7@ySV$$<q?SM|UuQ-eEwYem9$bfD#xk~Z zSd<^lv7;=wucDT%6pOXXgKH!B@v+U*l+V>;)qH&x$6rLZ1{kWIRu)pwpD8#xSCxHf zT`ALs&d7+nLp*k{(;+^K-$5BWVx(j>CH$YZr$YC#P~hch)Zex4j^OA(H-Gy|kxznp zwb&C{7o>0~K#?qMha+x3ncs}<7?a$_cB+M<;%WKD+QOAo5{qwkt_!u23=lq0Y-)ZJ zVID4t@>F)n-Hl{u+YSjr;kY~}AVZqECsrWLWOf$mPDe=+hP0WfLbn)jal%ly7xqh6 zzy|NA;4RhWZ7=UDpXpKN=-#&<zSOJ0gSWnQ^vX*|FTHsG^MBm~&i%jo^4s5h<>BAF z*rQA!xjhtiM&tc&V3Gf-XC%T`R}_>*SaP57=K&4JkcU)w&`sVz3~BLTFug#ho}@;x zQcBS;7Bzs#@~SqHF`3R2kr%`OZ{yqz$oa<^)ZMgrGiOzT-D6b11JuR}>x+&q^%S8_ zcdM4;G(@!Tw&G5-IRgjF-ld+I(EBdq^hCQ=Qsm|dcgq<@Z-4t9_TfFl$lm;SMv^^M z3vm)$4w&Igj01{#KXlJ=0}*Smu|~q#SNT#QfQvNyP~W<Zp`mqhuvR9W+*{!?t^G$| zI=c78qpyDMC`2oB)&6%!Z@lu(uikrb?{Co0AoWf-)PnVdhZ~M0^i-%ZC{vp&UadBW zO6_<ql9f{OPR9eZ#lC0AwZ-)QqgJ$HWSsEm6$9~IRJ98B@#-hsEk_jlDJ5ZQ3pxn0 zpR7Xav2-|5mE`Pw9M4oFrRXtd*pP&t;2S2rRL;>$UpRW}&HKOi_wW4P*8^1!shj&R z{l)z^zTBe_wZ}En(aXR3_CNd<qVK}3Mp5$Kr|-Xnjh3Dz<5PA-?3k2Yr?W4;`pzG` z9!xf`g-MkLQHdQZlQ4Gl9u}vHQ98^s`;*>eaI~M!`ay*%F88Zv5^&Z(3}^fbk`(?f ziv1Z;PZ1i!8@uifJ01jYf5D7kt2bJk2z=%gKIsPOw2jbuEk(m|${vf_m^$fhv!X?B zbr@z2G!?M1>ak7LO01Ir$$TWdkJy;^*wy?PZ!rw-VOa_OdabDt<w4yz(K)KKpMBg( zDoFEiqn82|uq7Sh(&#Gl@Xfz``>lTr)VQ3Z!ao9d_g{Yb;kUzF7d^P|Q7MkZhT74L zMqbk;P+mQLLQhM<OZGrv2oVR5$6_G!nqlwEGeb-zL~tUbUsU-U{&sjhAIYh~n;d3D z3vG+jr%~4b(HpEFJrpHpKth5DcK7h@Is)9w`W{?{qk95u)Ps~8UIiLQRHcW0bNkjX zP9ix5I)N-F<{sd|Hb*b~?SsF4>%q5v_vqzs1ZuF3rVCMpM2$|N2mM?Mp5mbz)>p2t zmJJ!y9)0ErUa00ovIur+`+ciCJHiuPgN6z|t$vxC8EH2LQsq<uK4F9c3%|APs;+df z%dlN}B!(ca(~pN~z7+#66^bNN97AErYIxAJp&TF2_x*IlnI6Tj&lxq$6zB+;>wsgB zNI+YKEvl&aFinbC*I{_59LCsaM@BR6+HCJAzh1NMQ2OuvH}Q&1SD*4w>Ii5G2q5RX zX`vD15VZkg$O|hs?A`su6+4g{DT$D<jv^GWg>iNPt8F_c9?}pYl&gE+pW@h^NQEE` z**DhQDs_U?0s+(}g5CH50}wF^n}%FgN^%)KtZ>y0q$b!hZLVdA{dphl2|oRJkg`hQ za9Mb2R=^B}*uzi@G4Cj{kBqk7qzY}&(*<Y94H(ejl>mlHfR{n6+D4@!sgHcZ&V190 z6D1=%KS#e9?P`YP<melU?}>Fvi;2zWO(Ik8y*B`MS`4<PyF;`*)Uzl4xd{02VTHio zUKAnO?1LYPWltdr?v|$`SOnXf$DS9whjT3_bQw{T=|&r&$027UJ@siAB6VMa#WEp4 z8fQ`{)hy4ZE7jFqyhC&V6QeQMSxUV!me1c#?#cDGayyyGNE<lij<Y04nHpAF)F0>d z#}hP8aY&vCfh=u&^oI12wWU=gedEK`gJQBnVbC&g;CO1FQ@4<~ErmpKBTup4ENFUR z^~xxJ_{*J#YwHNQL6WIo;g49s)wNAZWLIjdb({&qUOGt9fcx@5A~LDSz!oQ}iFS(| z-kkVNNn@*MB<n?n7xaq~)Y_D_see1!RQ5ace+H@d%5sy=0dYW-*vQGjr#Q4mZd;kr zITZJ7%l3ycg1e|bSDOsh>pr?8oX(z*Ab_J%69=)(Fs^0+l`nP!c?vy>w4sJIp9|Hb z3l!-FBJHU-AV+f{HOCV3;ox)2J^R^{F!#TDbz~=^k2RQQzY+Mav?z40e^^}a;T<fo ztan;#j!~$02b&nuF?a66C*C>YL}<4<>oImrgC(=gC+L7<6^SZmu|tknPM!yPCU@2y z?-?j5q+%(@6^3jcnY<gNiY!$}C2LeNW?72HBp(>4%)>an0w5WqQuWRV1?5*+Rw*g* zWFpjvcN{dK$h2FOFEY>52H5$>ZFhjD>E8AUbu3tX=!IwSL5*%MT)MHCBGQj?dW>>R zM#WAW1r`d4=7%@Ats+jj*xyR5JQ9bB!>B@K1T^d7r7P!9C~5kP6~E>gz{>Ct0%skU z8kA%_yLdo<#0>5!Mn@~%vv(&AVIcCJ+Kjhlb1#^!{vcsG3M`_8J)n}#Nk?z!?Vw5* zGX?r7$w-H8?%_~H$Exx+C2|@J(nYd42p*;r$}Abo`+#$_VGAKU@|bG{FJj!J9QZJ; zSOA6bHh9!{8XauC6w+}bM<5lUM4U54WZ;ILD)M0C45UD))Et}tX?r@)%rW=jAuRU# z>Z?$=l@bH$QBBd|G3@*x$Buy_nWRwe4Dyyk2OM|{J2%9yI$)=Fm;mGCO7sqSI0Xf> z*>C9*EE~i{53q%lL#|MRg)_*fRO|zJXU(%FJEBA+=i&V9lS8Iaq8_dM`^`3i5;DjF zD`Y4HbT?+&b;;~lm&0Q~laC+b=sMeIVb)Z-eJQiZ5g3(#M1`Kyp5u23U8j0vhEDT4 z=R3kwVE6PE$XXBBUW-g${V*->4acR?C%EKFtI!qv9zG?62o`kgU@!wD(9yHxd7GH$ zdDZx#alWVHc$`8SA8bJQp>wBcKj?j>1%R)wi^EY@mu_q>uFoQWbgL$(w3b{}t;0Mr z@8WP?Q#EViNp6%I*%Kpl^F&=U@=sovnJ$+uNE=JPxR~c2HXn}zs28`4usdja@Un;B zG=x39Wy6LS(6d0faHoMdDd}*x(Iq227RMh1DIpcXqK|?#h^=T?i5L}#3*G=i!jgBy zEEvolustJ$0{wJv0n+9abeHh?Atz%Cw~o!KO|1HmIbNg`p~Dh<7Vz(NVJFHR<ASeb z(e(1i5E?zFvG=ZGBGdzwTd=P1OBMm}OqRB~2n0*TdyvXkCu}aI5y1BO!nCA~DK8V_ zAaDZ=?>oJrDb&gM67xWCgFaP^_I)o%NkwAe?6QW~SGHt0#bOi=56pq(gXidB0YfJ! zC=XoCoC-}xXlxf~xEu_+4UNUe2i*H2%vIVq$RLpll9ZqNUp#qRPW>-ffnl?hd140j zzl2yR0U8#AaGjmv7OVe&GRa_@C!pj)3jU8gd6BwAn=V%1vhDUviM<rxy;oasl5iiD z8_KEI$;uF^C>*D=(HN`ODT3G_twT(bBY4gF2mx^APU#^j6XZ_o<B;{4$t1b-)5Ele zK`Ihv4&h8&M7V=<lPr(s6V&lq{d_&;M8X8(=&94oWirI}3EiQo^l*m^F@G=71zfl* zS=u0&J-Ry17KB4k^0Iv$uPqflKo9P6y0o}(Yjf%9Gr}Vq5>LQ(kQigIZWx3w(4if4 z`OVpJ<IAC*0K!NfOMxNr;%fs9MK>^OZs6LLqP3IdvRtl(OKhmT5?`ohB6!cy9^mc- zk98!vr-Kem1YF5%=y{s*S$EPTgvv5nrO|*IY8lyhnQrn7WWHm}8nL&!y$xcbr%SrU zp^G8nX4Vk=Ko>yw;HZd}nQILu-ni5<vD&7LrgX10(4xqtS?S!lv*x*T2+pxIORjI> zj&}AU35^`mX%Q9_IH=%4@dCm{+2Juew%;VI6QtigWT)FX6W5`k*XdjZ>p;q&k0a*U zv**r9DfB2+Q!R4@{gTd}eGZ@b_q)srrPp+=qT&>wZ{pG2k;JGo5wWyh5(A#Md&Rya z?~F>+f_O-u=@|zrp7L)*$bM7XTqo2@5O=6ad;{swh^cIZ%?g<bpq=B?4&)tG0RQ+U ztwow(TroSnp!GmDpc-Q!ae*0>f=l$pesXt|q%u`Hv^qSZFZPqW5LU(+R$ow?W6jvW zDvIaqOE(h&aB>LKrz;)tw&6m!r^YA8XQuf|nm~&mkKDSN=+g)R@Kk0rBgxL>D$>fO zbLSwYVxS33veH;?a%O7!yi4Bt;}R+fqN-zFi3c9koPLEu>fRwEFkvA25XMu@79<LF z#68M9n>r}~vNlwdWta2bJhW;EncUjCc}Ovvh9quAZymPOOpCo`m(|nvtSH1T*u(X{ zxFp>`MxYV*nCjJmP#RFBE=qd(VpH*Wnt(JTn=2`1mu@mZNG&be5D7{FtTd=<xXa!g z$&FWR-H5ODv%Bm)E_?61#TSGQLp3%>_*<OM=)C2JHB$8KuB6o~8L#GKZHaM+0*Z+Y zuC(xhqHOw}W4j))qGjK6w$<*a<bGreWq_yRrCXbuYpWD6$_cg%zYTI{NJS0T0juTR zd{W%Q@FX%s7s;)In-};Muqp9@--;k5==$E8TB#^VzCLoXe{`JNSaH|2^HKBGoGqV0 zyJXK$gevr1Uy8vnvYSAZofEqs+L$A}9zsHJ$?PH5|G-hf>kBJlKzX6ToQvDAG2})Z zW=%Jke;!5+>r=N$!yb7I8uskeoFOU4k4Iz!%o(P1hcaRqg?%Ordm6g|<A(Yu&6h4b zY~$sFX1#p;<LAzK?3a&!eAYm$^#|LE!3^<UvSIk}^ja|8Plf%`{q&@*7a~+&3kE2? zix!O2+RzpZBi;MJez~%=vHUI?FbL?`jl+WRz!}7Zfms*9Bk?YKXt;xh_paNR;m<tQ z41YMdIYXNW9U?@b2YiViOb-oTe&#vFedY~+9J_tf1@=)IINgYRFx@l%JPn-Vs{~S! zG>yEMtQ>oodd(cqV`1lb9uH#ZbdxRA)!<oRbzC)9FcJ2*b_lVU%^e`_+DG!bY&s1N zZSim-4rcNY^*T-)d^@JwrUTErZ#B$DnTJ`}H(QaL^0vbH)Wb@$(|8QHb=H}H1I5OJ zMXx<}TEdG7T@cjy>*8{`uE<EIE?xyT%ba4KwwXiBS2{SfxH5r&Ub$5(HZ&a358cfV z-5d2Z4dP!TaMB8a>p^?Ik?%v2NCQL%yF)Z7N!;-l2!=rUu^Z;nQBQ5=AP;P+dwaoK zjS#UNl*C+evF@p6hp+S=0zn6)fp9&aU?*eDnxa?<sb(nEd?K(_s^w{m9RjwmaKXi8 z*pn>d;<B=7W(A)!_|nTgoDeBgfDzB2=x7v4%4Vf23eNH1E?}hSs7xSdN~_Ipd*vM@ zltOW>8d^izuD7)&F7z-|xekle!2SR`8ZGUZTC<PGn4lwK3DN;aJ`P`ow&bA-<tZZY zDOR!9W~hA~uxN-_5~(3palnQIXHs;FFttp|!A1JeUiR>Z2i6Hx6(pJgF+Tyyf`w2t zm}Wh;nxGH}BxniS-)A=rhu!MS<T0>=(7DnsHYMrc2!%OPN*|?(yRNY$Q#z+w%|7W@ zF%kp86K4V>D=ALB*jJ<?-3O?*OXSM&+zsNedH{f=J-Ryg4>Ro3gCgMcHGH=v;C9#G zaE$=;a6L41+tzN6%^Y!n-?{oY6!jkR>fF%kHgeFn?)zB-A;-mZ*St#&)0I<!?FCSY z^h?sdpK3Vn^9x|(XSpp^gLZ)3{#DH<`RLA2t`Jo9rzT0|us^wrUD81>1rw%Ak6EFo zRB&T6up5Ee%#OISEjrP<ufAs#+dJO@NO}r7UoB0mmt+HX-ZMqXqv|p^-MU}2Uv);l zQ)%D8u1v~qOyCw`z<4W3b5Eqx{DyR7#HuJ&8R@E!8cIXlq=bv-ZTrH0U}p#t-}p|v zVx+6}Ho|P}!kA`UGLIZBofqA&x~{1w@#jD8+GVYEXsFvYOKP?2^>kgSBIK+e*=grn z)FYF`*XO6696Ns@;0{GkK@srV)b=xnu$cXj1hEC`cK^r{YiaumHajjIIyp~R4_Ig1 z1fi+}bm%4rCzWtruOAOFzuN>9cg|Bh$ZR&dzrUZ^S4!ip!wj-}WfSxKi%_rvd2eUB zzq`N9Ww``|X#)=(g=CVXQ3|#lgtTxw1an!>AD0B$6-=WXV6}Q0<o8($D|N@rmLShK zwjsANrFOGYS2Bpw$m}qC)l)S|=CjL40!NS4GADJ~L11#wX8Xy6O;leox8B&+wC%c5 zglSbjq+n0n@*aLF3OywTEr`PXc*7VsD1%7GJe2k^$wAY_oq&4b9HJB{`2^jjob8BM zXRLMLBVmBWmkFuo#L&5&yvC^2A;9hA>~oNr@-7U@rONE>q>t7C*g2gHpnafKnn>Oi zDBKl>x<>*L4~L}lGCFrvuA6qc`;ci0T!ge&4ly(lZ(=p-_~6A`|E|LKoH=twYg<@k z>EB(*;L99S?NV~7iR7t^hM^hBd8A&T8>(UL;+cfv6o_fa&22^hp2GK|5>bbxHPyej z@E;yKbH+(?Dy15lX@TQq#M~lwvtCEGGSg!A@l_;kk`h^@Ei}w*t$nDL&<3K@aE{Yx z+%&Wu<ajl+?WUz#b)}N!11QUucUe#uD3y`(5#enh3!MU&#>Xy<l11Km$(DP{fl^MD z%UIHZe9b-8(3%ZkLrjQ<0xmH{_!NcXHqGqD%`62mn^|$Ssq-O2R2R5S&M?&G-~?&o z&^bfwx#!rj{_fq#m~dj$!HG89QKpL)lViNWVsTpm0hLCv$l5d%t8Fxip$KZLS4Xzg zJCAo*JsZyH$Mx?kd>>eCHsuz~5KI65yZYm)!gu3Q>kyIL`VSN=e6~XoCo<ES+^jS( zbHVy7k5iOV$Zl9w4+gJ1qW@swyU;Xcl+=Hy@RRtsf@sJMr6r9|N@J6=lM}P!Q_^^D zY)1cKCh%2k!YZczFYf3+lDez^Xo^**9Af&96)vOtz-Widr2a2CP@G29f4uNGfOe!( z|5xlCjRyTE3g7sSGiSJX=I2OA?bu{Vh>9dzQtn`EtW=s9FHPr=w$B+iNcK6T7>><% zje-1g$%W*sB*r{<osigO7Lq8LTv&akxOUZ70+~2fP+P-UP`d;xys@!#ZS^A?R9vLJ zkrwQStU#-ES!-6+?d}rdDJz1T0)5Sq!HbsY6_vT<E5I<m#9!JcXF|$|w+znOm1jbV z(HmA|J*2=of6W3cLyGWsfC4Td+8fy_6eFJ;R<wrEHBj%k2DPH(jf6A%*h_-BC$6kr z-hAffB0_`NR6tYw7EFZHwk0hs5{^w%$+#8}{b!HFi2kqH_$TFS>OXl`|EbjSe=Pho zWS!<i0C#CyO0&DFHI-TY-z@(pHb$uo{kRL|rRVPIKfU~)3s2fWTranh#UhD*v6#HW zl3s$I`p+!?7dC5o08v@;&)8-0tuy-YO#j*C|H_mZRkMu4S^ejh|64(_+hnjp<_!Jc zF8}w!j|k)r%1X<Uu5WJMoYke}|55lM7X(9AO+|lV`F}bDQF!rnXX;|J>#Uww{$GVf zSIsA-ipKoYN)vNEvIax1Nhz&VZDa1oEpf~>s$u=0(s?!yIQ_{sQ!aIQrSuP>S4=au z8!i3pUHz$4;RnzVCHb|$GxSkUGG5HFM`_HR&cLO&^Ey}XZ1U7c3Kdj-H*}PKj^XKI zzW(7t4R*z;x(d?Omtt2}`e?g-S5K#EKUTO6o}Z-B(lfOmXJb*!cY3z=69vqPXHp}2 zt_H0#mRe30{ym=fl$vX+kS$qO<vsXJ23oIR(c)UNH03?vW5q{;!T+S|%;jKzLC#U6 z%}zHeQfWI~#Sy!TwA04nx$2?tBBsgA?VP-WCUM-ZS!elgL&Kp9BzUaAWdfUeKRuO` z8b+G(04L@jy!^(4H@|xH##i3{=Bp2%|K!nczJC9cFC4x2cMsnB(!+bN;os3qpY2+- zWBghcY#!S!W4FK~`Hh6c*F$!?dv*s+n!n2@;CiV;$siRsCUiNC?9;Fp^NA-ph*f#- zilMbCNa&k@w@#H=N0B|>%qPN1a4ISAd{k+XV%KAS-h5(H+r~nasH<)>1G=*+BVw5# zaBwHmDvo=wB{_;X{v}%Du%5e~xLi&gMc~Z)NNM0$XF+b{i{q|Qe>Xa?fKj{d!3X7e z_5Qp^k9;ex@#R$E2?#eim5XGT+Y6Q!))MeWU^9WT+icyL)hCum3OSSn6k5^n0<H;~ zp3{%7iOJ=2g%8;kF$vT4kgTPVxk-XeJD=?P)&yFaTK;h1x?Px{^=b**7A|6>8TP)` z&o7S_e%u8R81UA{(AxBJx-jl~8Pp=*<nY0rS<W~UFIA%-TKei2ma~O*7ff#tx+Dyh zFd{p{1OvRe8@30k&o1Y>tO5^c-Y*1&=ogpA3g>#_;Oo!a@_2vPIl#^@PZXAV!0u86 z)W2+9b&IfHK<1Yx*{YpL$X1~G&o56EKGmZQ;h3NrK~hi=N}{XbAX-bJsI7rQY5xn$ z=lj!#Xuq&LU8wiKU1&C@dGZO-zO9##x0s!SgS!Zc!tIA%73Om^>z9^i`eR4jyS#j% zp!C4b%RSJ{rN9KTX;KVcK@J%DSC(g)b|F5|57RPcyCf7%XWTEgYad$9)nF7}#Y}&V zX8KD&bJ&^Q?|{&+V?HM<)8%>4moTOO44yHcLw>F<KYO?-C9%h@ZZ~NqrRK*+^pDVF zznoh6<HrgpdPcvo^2Ns-B4a~BVi0A^GKxh82$wCu#vhs0S606CSRsiztkd{qdpR(b zQE_&K5c77}HT2b$S0Ah0Sb6QS!q3{Z9QfQ<V#8Mfd~M~+k2y9xH4xxJ(QmH&2?2cl zF^BvPKoh<qEJOsvQE3N2Kf3a#owkF4&hFgN*H^v*uwWH%AYN^xm@C0H;Nis4H`$^? zEa34ZIj`ShMn82}{}|JmUV`gS7hp`EQS}1*JFY*|ZYyjlr;w?j{~~Lp;}+7lnA=2Q zH*n~;3qOU*<bMlx3EpAKg|BwtBGZ5Au3k*BXT@S!#${#2qW*D)A}t7YS-gT{(8Q|} zn?6L3I!K^nWm~XV&Vd69g)1F6iv1E%L0m@kYGDG1&e2^hS|z;?uYU`BSy&7@MUZ5$ zDs`H$T`%+cHnT`k5H3cvQe*ZgmZoaqdjXN2Lk9I7?l5)MPP`$ADSI6PdRKtZ$^cO> z{2Tx#H|P?pW|`s%ydKs}Qg1No7mJFH8cp7)zf<%!tUnrKDAv!&Z!c4iT7@wpjURPU zA_RNgMrE6rXoR6cZ^KYAnM686S%v*Zu&lyNFt6+}Y?ljz+7@_G=k`MJ!rL$i`!>rl zA=CilfZ1LFvcunpK{>Rc(8dCwJR1guzYl}*T;WHVn6Xk&-^^YCxL;<*QvlaI1&Mhq zO*{`rpV#l&<RR~g{wrbRVZN0R#{WA3fx7j4D1;sa{)7#oNjUs!7zBD7MwU<7LkD*O z0mQErQo$n3Ui(P!f;|MV7276#tiKpG1Vo7tO8h$0xa3h{fRqEkdZ{oOjEk#K2)N&{ zCB{%%q*Fc>CNcbd7-@dfR(>X*@c`)4Vam@b5(eutg&$<nhk_K~N3{Aa4$QAEI%Pt- z_p(iP6QOuo6`)=TBfBUO0_eAG=40Lgl+PBjL~y?rWUs?|_BmVkh#^(ev|RxEolunQ zp~uS+VqK%^^K7On7R`2xU0YS`%uBz^W>dCHr~jTUFwQ0!n*9C3j}iXPBWLFM12&;i zV2u8UY;H&)$}(i8O^%M}Unu-A0PU+*t>^&L|EMrU(7o*HE)_!OKjx~mu3>w^)W3LF z{}SIGVdliE!REwkHDO46xy{&Q2TbUHQtoUiJdPlyV!PQw;(@yIxc>U3haW$4=70Ym z{345YevZW`;g5m;aSe}kNLTb#5m}PnSI7%9TS9t;i`Z$x2DV&JV+&%tIcsSx+?7PZ zLhPPVSIxkJv!c{IYm@PZ$20I3lp#7A2AwTI(S+#2Ac$<-j0X#dO_b&Z?d^=%vEWix zD^XA(lQ5q4>neP4QBW8g$KECW8;b`INH82`$jTB07qO`v6Dry+@?k~6Lr6%J(P`&c zL(EB$1&&8)-{DERGAUn}9Gjj@Pgkd_>B))7N?M*~zs4uemo7|Cm!>9;gDnE1C^{et zlCdzUqBW4z=8-iI*9WB)dSvZWq?*>OA3ib!8uCFJu@sN2{g!Oi9$DkaP1H6XUEeWP zQi{h|x*z9U=F(thD++cU^;MoyCeKgis_AlNd@4P8p*o$GFO(+JO8NX)X?#W*yHG8i zs;|g)*s1zDRbNpCXe?9r`#^o|D|Hw+ku-cqhm}f`Q@JwKS9xsaLV9vaQDB12$mt6+ zx$5MFDW#;0otj{f!ia0hQyq4y!~R+8usBUK#E3<r)iJzH6z^ADxO{o>=4O<p*|7wQ z!W?zQc4iOg$%hZTPaE}%dOnxAFse4ND4`hmmi<v~HMd94WzVtqGqKEHu8tKKS1+$! zSz5gorH9+ksx721R;m=aI4YIk`CuMCx{?j>BC16<b~hGQuiaX>wipGwXKU%ptE11> zY{DwdxG8vf;qvvx;^no~&Goe#Q82WZp!r;Ubi2H^w!9RHT&}eb^WNk;cEBL6n2X4F z%kuV<`^UCETp$K9CAvVEEm!S<7E`gw-u1PONCVy>*z8O$7b8z^uCEoIAvs%Jyu7)z zwi-p$b`_;XuJk>agmI10^~I};>x=7A(6P@cc2kUw*g%=kdDJZ1ACC{!TQ{$*FI-tH zF0F1XUcR-ySX^KH=&i+#&5bC?$Kx+%YVOv?;(8JKZ8eg>t!U4x2z1O&WpYw#1^44N zEzPW5M4*GE)FnKS);6R9GN~8GCW_}rqy=nVC{HV;W!1_~O-yGd&P%D~>zgY#=v>vV zB3)C;yV{6!xrX!_O7{E=eB%?7lW>sd&Py9|6>*_<wfGoQC_=^Kn%~vp#}?N&A`16p z2B^k@)6Ip=>kyKwYf<Ea<X8CdV-#Qr>iRRqjm`Clvve$kSzlaP+gvOzT)7fyygLIu zPGoMbtw$O*Q@Qc+@t6={TBNwLxOsi;N)(y7wummoppZ8%uP@!)EUqrBM4J5L!C`S7 zgE%q{4Y`a%)4RwSfo<P75sE4&vCZO8@<bTS<C|-jqnU~{TV%&#+N!ki*;u=}`Siki zB!OAi%Dajsjb+9&=VRd&6eptAkgm^&v?ul4Q%@d@PhT81tktzLV<&t$lu;=LXtoWU zjS(cX%WZ&n<D$BA!nxRzjffkfLy|of)XNQQGryPOAb^k7VrRvpOaxEWt&1O%>usbX zv(EwND!Hi(%FL`}%eLC$qBLtur!%K^OIS-YEK!g&m=NY|SrLyZ_Ch?SqZRv_Q4#O> z-*fDTe-<T8vtBGyR8E!7#5=%vA%D@9q3%&o8S+8$mjZ8p(Xt!_xC=`xD(Orp#esK2 zV>jU7elf+!v{btn0^_>2-M<zJbz_7Bl@@a4$rV$y<i-SfM0&lI4|=>s0tDd64y+2$ z{BPIP*Nu%GVO2!ja9b%-?3}1NCAw*;4F$Ox#PczS<z}sI(UGpAr-W0}WLiA*HP^=i zF8@2^Q0J8drs#c1Go2o=uq^Qo*BmKMAG+Q^lA2agp%fJkOS%eFlu{d~&GwYKz;(h! z1Euafb~CcX(-4RnT>x8kgk}W3;VA}ripyYRjJ8vgL*TzfH%;9BN0}iE0p5)h3*7US z=t2$Gh&fbpS49q#G7?@0s9kkTts4Fk_=Z-b7du)h5GZ0Gal&7`;(z&X(bblr(U>(T zOkR|8qio6ME{<S|S6wJKwe7YV_=a@8c(KJl@ZU%##y>Q*lH6=|DBJ}YqNEsAWHE7o zxKRQzisqq7X*7t?PMIzcj7wz=!VFifK!ugK`_#5|F_zh_QYza1v`FR<!gW(4@gPED z3n$RGqfBayD6ycy!b{(0779&GMY&A51ELV`y}N(l>R1t{Su{$(8Ks9Ovwz^mPGro9 zg562(A21x*4VNsI9C4#jFpPKqfa8P}xC$RJ?cj8xv!Uwz!PuS{YnS`~gS&sgXjnrg ztSA(84Ep%?4;Vg}hYt=(&YDQH6*25C=KTYP7t%i=VInpShZi=gk35In6g!#y1BPn5 zh1BL1rHET7S>z-R1;HSPfe;1xc=iuCURY8TVTDACV}5_{A20$O6rtkj#`hw0RMeQ# z`1TJ}v$(@<VT~de@mWhiqjd-u_wWNNW*l0P;=5x-!o;nx<w!HyCK3h2V!Sesc9Euq zNcy5XOqic&nw_oUXVy`GA$an_UG9aRC1+>DloN+kRc3Otvoq5Zv*%|nD6{9QW98W~ zMG12O^GZm)n;D;)%uG*Z#>T_;>FlDRM{?qfC8E%KsPd{7WrUp2E+3{7;}G|h(-FWZ zXoav<98MeTe4U{*kOms3cPf!)<$lr_2^sQdMj=RiyL`e0#}A=K!6mL;K7mQwP@|x6 zLZZvlB{R2X6s%&AT$gJ#3J!y4$l;{dMkuQE#<uq;@Gvw>Lt3mT#EEt9(Z+{dlKa?i zih@t<dyhQ3E4)k5PGk+~5|2gRZIq8;^p0o7rZZz{oczZfCm*IA0(@+=GL$|ylf%FB zncP?=H=daao85;S5c}q~n&D3TC`_mQv7)MFHsR=AT6@~g@k0ASdD{t$0;YxiV}qQq z{Fy{oQQ7bJ?MK34Wk0^Pc{M#_Lx{_H%eu-^nA*8$qIQ_4=;qiFP^_3UZA-0ZuEMWw z)8Hg<XO}TWMVh#Dsa>VDePtcnXh_Aw*fe%NHt#qia079IDtsGo<wr8B<6C8P(BYeZ zQ79MNVuK+=`xqMX3`M~tX1cVEdXcuYq8&z}MSeUAlhn^K)Md~jtoK^UztV|w4MS|U z_e7&G`TeF&c}D2>r#i(_6W1;rhfD8*IxW7p)G0^jJ)%yF?;Ukod=IJ9<G5T;Qk}-B zW?^kA&8U85I_ee6<i!JVqG*sI*CrId?gRvqyC5F)5n>W`<0-y_Alr4sg}@e3Eab#L zUjC#g*>O$-Tm!H9=@Pip09RMCv(o@qu^GUZxFWpkG{E(uAjN5b>uG>1ZudS7a6Juh zbprZN16+smOS9nd(*V~fChcjoi<6m_MckZ5yHJwe(`c9XR<z5b-71XJ8G}Ja`vH%5 zw+C3*N0f&TuZwM$2S^}$t5t1B+R=}1iwAf(=ar)Pr{cwgOyNh1#iNfA!rk>zNI;kB zQV>8!d`M9sz^HU#6qoCc;&$CpX>tOeadvQe`ohH2g?Nq^8S;MgQ@n8`P9Ox1<>aN~ zW3hNi;n|PExDyKMYFp)#k)-q8f^>d59zml0&?w}ijZl7f0j1;4+`x@hPj6gX5|=aE zXR)U)j8!JeGl2mNT{E2ir!VMVS=YbHF8dJI$mxGpd;QWkaRJc(`#OFd`xXSc?LBH& zDL7+;1(`0bdHPtArz#gFgZmg|bx>wUi6Twb-Md4>t>;|lkWO<r_r6Z!GzI->3i>FD zB%WQt4?qt3uBm}jI&xY}+-0XWaA{$*{5ahjl^?cv?zs@Vg}=V*Pcai`e<(gOhRK2B zN=6XfVWpO{J7#u=9j3_a0DNF-Enl6oX=aghN@-SPBZDu4)<auPwZU6MExslX!Z216 z<EF(&cgF<XFo@H6C586fky}W%v`D8)LYOg}RY1tFtEQspJESGU4QU8Do<t}YE)tH% z-p8p;#Zb!>c1{NvV;c+Sd<2VArnWT=saA?|Q?4IkxS2@z8ik~>t(s~q!Z-%v4JS{9 z^i6G_BAnBgBH7|x0h}nO=qlkTtO=Sbf}T}MKJ@uAfveYEo}G>YM)(I0`UsBm=`Fb& zOb~7lKK1wapZ`Rh_^}%jeE_54_s(Db{yWcq>A|-?cl5^Z`+y#Uie;8l!Uu5>G#}pk zr-%1m^Hm)Z8O}_R#g||FjLF#twl_w@jYas}<l_taaBa$M+%+6&I(r7^k)>6fTan21 zaHzF^K{>#=o4S(0g&lzohA4|~P`+%aEFE1G(#R54?{x_`tV$T6KJG=qh)s7<ZGfkh z(s=7o!XN3X0ooyB-EJ&cAv+yqzl$_~5dRu-%i~6wlxIq%TrQB4u}VFTHr36drBQTp z6dniZ&0o5`|KZ!2*5QXjh|4wZFF9I!$l^@NXG1H+NuCx?+uMhOqMoR>ua1ZlE8(0f zzeg^ubns!mI^>9HunTUHB&Nvn=|z#N*i1VQa>uwXCw7#uNg_u+@GSbpfRK+eaFIIP zd?aAfsyYhO#Cag+q>0>wcaR_4<KdUbjU=}*G_$!}C5!u`I>~#|gIw<r^D##^z36me z6q?0G5hriLK$M78Ug(zlD1D#GO;=}TDihUed1icKYHG4ln#@g9a}(#!kI$53|Jk=F zCWBy7v?b;vq$;x2Mir_~pNlc81_UkaDv=iJu|+M2&NXDD*rX%eQA96bHE|r_f{hym zi(bpyXsX+Ue+;R-igfjS6pXm)k7F*WY5TA%wK|fsMnNP-(!izLj%1sU$8-UY*)CbC z6>Uzv|M|bZ|CxJ7Z+`B<z1JSR@}iUyW^+6{-g{~^$rV^Qca>xUUpz51WOp#R0X z{+EUCJ#*%aJ&N_e!mjrJ{XXn!AK}-rceQCn9Yxx@modW)J!Vp3*C5(e#1rRZ60#c7 z&rqK9DBYi#7*{3~IhRJ#rit`qHHS~RsfqMVX{Mx1pU2(lljT?}2J9tR#XZ$jBb{Ux zQANGNi^dUVG>zzxvGMWT`FO?%5?U#Z5^^L)v+&~6WNqZViNfAvNjD-|B83!Hk(l!r zD$F4ji|9nO-(qPysvUOptykavhu??=1w+|ZY5R!uOvLSy`0<FSZel_Nhj6j)#c!U7 zs`+9;g~nx65!rxoV!-w0F}b=XPCn)%Z~7B@#ce}tM+<sBj`kRjqOKnP{R<D?{3^G1 oj(*#}wGl>}u;)<>d)!7EZA}~KCF;UVf8z!H-n#y^c02R`0b!l#N&o-= literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-44-19.84f7abe3-18fe-4f9b-a4b7-d8596f94e745 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-44-19.84f7abe3-18fe-4f9b-a4b7-d8596f94e745 new file mode 100644 index 0000000000000000000000000000000000000000..76e1c693458fb84ca1cddf67ef6e3de0f6b4bc81 GIT binary patch literal 49169 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-44-24.a3cc5eb0-12d6-42cb-9edb-1dd1ea099be4 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.14-44-24.a3cc5eb0-12d6-42cb-9edb-1dd1ea099be4 new file mode 100644 index 0000000000000000000000000000000000000000..f70821ec4c81fbdfdf8181548107ab1dd08ace9f GIT binary patch literal 49167 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.15-39-52.78464803-e59b-4281-abde-3d9d9ba30b48 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.15-39-52.78464803-e59b-4281-abde-3d9d9ba30b48 new file mode 100644 index 0000000000000000000000000000000000000000..6ac5a92bcbb48cefebc8e8bb4160cf7fd6844664 GIT binary patch literal 46667 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.15-45-28.d03a6dea-77d5-4c23-968b-10584836bcfe b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.15-45-28.d03a6dea-77d5-4c23-968b-10584836bcfe new file mode 100644 index 0000000000000000000000000000000000000000..6651c31d67b692c28f8fe6e17596dc0b61956db0 GIT binary patch literal 45566 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 P_`46|?-lU(eLwzxc@u^j literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.15-46-03.06370395-4251-4ae6-9451-f4f0c8a8360c b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.15-46-03.06370395-4251-4ae6-9451-f4f0c8a8360c new file mode 100644 index 0000000000000000000000000000000000000000..a8d6cf2a190e564c0fe155b2af3e5fabf6c3f8f7 GIT binary patch literal 44574 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 Y+zkY&sM3R(9sm6k_#evnAA=zIf5Zkn9{>OV literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.15-55-43.353ebf99-44a3-4394-b8c0-d124d53b7261 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.15-55-43.353ebf99-44a3-4394-b8c0-d124d53b7261 new file mode 100644 index 0000000000000000000000000000000000000000..7a2db5c8225c7d3661b97d1b1a45d5664a85de87 GIT binary patch literal 44936 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 YxTFN4PNl9t*ztEC#osI8@B6;||9ktnwg3PC literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.16-12-59.611f4e4c-c450-49a6-94ae-2d5da784db45 b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.16-12-59.611f4e4c-c450-49a6-94ae-2d5da784db45 new file mode 100644 index 0000000000000000000000000000000000000000..b3ede6f755f1bcb17b67910e7bdfe0be3d3ffee7 GIT binary patch literal 49715 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 Kb@1uB(f<d5c&B~< literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.16-13-29.ede170a4-af38-44b8-84f2-1dacf2e878cf b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.16-13-29.ede170a4-af38-44b8-84f2-1dacf2e878cf new file mode 100644 index 0000000000000000000000000000000000000000..f6ff7456da0e32f5f92ff42ef6306cb4fdf4c327 GIT binary patch literal 49532 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 J@aej-{|ACCaOVI3 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-24.16-14-39.315150f0-6b1c-45a7-87d6-a7392658336b b/web2py/applications/SP/errors/127.0.0.1.2018-09-24.16-14-39.315150f0-6b1c-45a7-87d6-a7392658336b new file mode 100644 index 0000000000000000000000000000000000000000..399c8d425805b0f2c0a549c6c11c27261a019081 GIT binary patch literal 56588 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 Uxo_Z%@4RUI#isEe94Gz%0fx~&rvLx| literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-02-25.d6a63215-ff4c-4e8d-b71f-0659e31a4c51 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-02-25.d6a63215-ff4c-4e8d-b71f-0659e31a4c51 new file mode 100644 index 0000000000000000000000000000000000000000..a6d2dde7e62c18fc680fbdb5e2745d91fa3ff3bc GIT binary patch literal 47485 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 bloU(+cMQ!mVdf4|r)ZcuMI-PT1oHm_7G6yr literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-03-10.8ae61366-bacc-4809-b5b5-baf0e30a7fe3 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-03-10.8ae61366-bacc-4809-b5b5-baf0e30a7fe3 new file mode 100644 index 0000000000000000000000000000000000000000..c233ed434828a59e55d86979f9f688b8e9096f7d GIT binary patch literal 47484 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 X?--hC!pt3_PSG%Ribmjf5Xk=z^^;8R literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-03-19.7a82fece-b4ca-4815-a7ce-11eae326b3a6 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-03-19.7a82fece-b4ca-4815-a7ce-11eae326b3a6 new file mode 100644 index 0000000000000000000000000000000000000000..221802f7d55ce9c344dcdcd2421611039f3a203c GIT binary patch literal 47484 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 SGk1tOMZ?r78iC(IApbv_zfC#- literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-05-05.23021373-02eb-419f-bd2e-c7b583f6a8d2 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-05-05.23021373-02eb-419f-bd2e-c7b583f6a8d2 new file mode 100644 index 0000000000000000000000000000000000000000..07333ef9f9bb462062b752d74883c0e55cf898f8 GIT binary patch literal 49391 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 P3q=+eic0w1ZfE{K%mI7w literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-05-08.7916431d-3acb-4a7a-a60c-32e78a641411 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-05-08.7916431d-3acb-4a7a-a60c-32e78a641411 new file mode 100644 index 0000000000000000000000000000000000000000..48a1291bac8c61063404323f651bc6fc43d2cbd9 GIT binary patch literal 49391 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 Qp9@6>7mCXG-EL?8KZpr@asU7T literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-06-10.4ac1637e-5f02-429d-88d8-578007e1888c b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-06-10.4ac1637e-5f02-429d-88d8-578007e1888c new file mode 100644 index 0000000000000000000000000000000000000000..72680fc53efe492f1b0fa07aa32877f577286894 GIT binary patch literal 48436 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-07-16.553808ae-96e0-4aae-9dcf-e20697568be5 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-07-16.553808ae-96e0-4aae-9dcf-e20697568be5 new file mode 100644 index 0000000000000000000000000000000000000000..c5301d6a421830179ab1421f3fb3ed3110a34b29 GIT binary patch literal 48724 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 Naiwt`pY3+$_W%znzzYBX literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-08-05.00e6160b-f867-439d-afee-21f5a2a5fc8e b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-08-05.00e6160b-f867-439d-afee-21f5a2a5fc8e new file mode 100644 index 0000000000000000000000000000000000000000..a90f3768dd954260edbcbf3e87b0e9d14b355e8b GIT binary patch literal 43465 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-08-57.98ec4506-1d72-4711-bd06-e340a7e0c79a b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-08-57.98ec4506-1d72-4711-bd06-e340a7e0c79a new file mode 100644 index 0000000000000000000000000000000000000000..6c42b3e73e6dc5c3deef9cc408d92ebcc60f2e39 GIT binary patch literal 48808 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 Pl*U!2G_Jw#c3b`b!}{95 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-09-22.8caf72a1-2f42-4991-bf4d-bd33bba63c59 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-09-22.8caf72a1-2f42-4991-bf4d-bd33bba63c59 new file mode 100644 index 0000000000000000000000000000000000000000..9e8488a3e824acc990187338673dafcc4e233d4e GIT binary patch literal 48770 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�ASW#`G$`WxZt5#AAh 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 Z7lCA3`Tb{<KEjN~HD)xf!|yOu|38kz&?5i< literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-09-34.afec10d7-3824-499d-bbaf-276de70b3d87 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-09-34.afec10d7-3824-499d-bbaf-276de70b3d87 new file mode 100644 index 0000000000000000000000000000000000000000..793dfcea5c471171d6ab1e7f699a0c99b741d24d GIT binary patch literal 48480 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 SqVy(aG-}LfoQKaKQ2!r!QFt@} literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-09-41.832aeb08-c4dc-41bc-9391-8de5b0317053 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-09-41.832aeb08-c4dc-41bc-9391-8de5b0317053 new file mode 100644 index 0000000000000000000000000000000000000000..3c1a6f9fe8b3a5c886d9e285817c73fd1cb13937 GIT binary patch literal 48480 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 Uxkr@V#EeFb8IAMs83gM81ETJDTmS$7 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-10-09.6bcc0e58-a110-47a4-b9b6-cb7946f4f502 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-10-09.6bcc0e58-a110-47a4-b9b6-cb7946f4f502 new file mode 100644 index 0000000000000000000000000000000000000000..44268cfb5e30081e5e35eed0981e524c0e4ad6ff GIT binary patch literal 49683 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-13-41.476ab4ad-3c08-47ce-9ece-15c067a40fff b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-13-41.476ab4ad-3c08-47ce-9ece-15c067a40fff new file mode 100644 index 0000000000000000000000000000000000000000..c350d75df70480350aad8df6cc4bab63791df1fa GIT binary patch literal 48791 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-14-30.69b37db6-d641-46a7-aa9e-244648ac1286 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-14-30.69b37db6-d641-46a7-aa9e-244648ac1286 new file mode 100644 index 0000000000000000000000000000000000000000..53245bcf3d2cf36675b6cb26147b80e804832d2b GIT binary patch literal 48725 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 F{{W8;#Ebv{ literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-15-40.c8b163ae-744e-4d7c-a430-61bdc80ebd87 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-15-40.c8b163ae-744e-4d7c-a430-61bdc80ebd87 new file mode 100644 index 0000000000000000000000000000000000000000..4fb5bd04ffe1f272197de2de97218fac2d476b11 GIT binary patch literal 48701 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-16-49.4a4fd7fe-cd96-40c0-8553-ebe34c5adff7 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-16-49.4a4fd7fe-cd96-40c0-8553-ebe34c5adff7 new file mode 100644 index 0000000000000000000000000000000000000000..7b34e445da6db9e7a540a4e9ea67c530d5be1fe4 GIT binary patch literal 46477 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 HJTLYC)01a! literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-27-50.a2c2c6c9-43ff-407c-a879-470acd711175 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-27-50.a2c2c6c9-43ff-407c-a879-470acd711175 new file mode 100644 index 0000000000000000000000000000000000000000..3d25d0a04a0daed5e83ef581b945337a80e8b769 GIT binary patch literal 43147 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 BBXj@& literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-42-41.91d05dfd-c594-47aa-ad9b-272756af2f28 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-42-41.91d05dfd-c594-47aa-ad9b-272756af2f28 new file mode 100644 index 0000000000000000000000000000000000000000..5d76b2699541f08471f47903645ef60da59a014f GIT binary patch literal 46582 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 adJ1m-fMi*jtw)r8=QjGki}e3IFZKT+K9N=c literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-43-33.3f9c933e-96cb-487b-9057-731ef99df91d b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-43-33.3f9c933e-96cb-487b-9057-731ef99df91d new file mode 100644 index 0000000000000000000000000000000000000000..acb9502a060541038f657f0c26081fe65e6b446a GIT binary patch literal 61820 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 G_5T4pkQQhF literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-53-29.38843298-d223-4ae2-957e-6bd410bbaaa4 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-53-29.38843298-d223-4ae2-957e-6bd410bbaaa4 new file mode 100644 index 0000000000000000000000000000000000000000..220591dbe0916327bf2b23054a9f8253c2978cb7 GIT binary patch literal 42941 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 H2;~0<Ixz38 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-58-56.60d0f3ea-7fbb-4b9a-90fe-751f620d8048 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.19-58-56.60d0f3ea-7fbb-4b9a-90fe-751f620d8048 new file mode 100644 index 0000000000000000000000000000000000000000..9d58aa2eb580c89545cc18d485aa5f223f122e1e GIT binary patch literal 44583 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-02-59.39add73b-deca-4b57-b448-9aeba108bb41 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-02-59.39add73b-deca-4b57-b448-9aeba108bb41 new file mode 100644 index 0000000000000000000000000000000000000000..6f082af9519db8226250e4fa40282bb416f15237 GIT binary patch literal 63224 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-04-31.aaa03c9b-657e-4f8c-a933-ad5582570937 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-04-31.aaa03c9b-657e-4f8c-a933-ad5582570937 new file mode 100644 index 0000000000000000000000000000000000000000..9d0a1e43337fe9e3bb65cedea1eb43aaa60a96df GIT binary patch literal 63419 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-05-02.fa395f45-73e8-4ca2-8e4c-48209c73d459 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-05-02.fa395f45-73e8-4ca2-8e4c-48209c73d459 new file mode 100644 index 0000000000000000000000000000000000000000..64224e8a5a4542feae60c269b50a0270a927bb07 GIT binary patch literal 63415 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-06-15.77652992-fce3-4e80-945b-c735eb163038 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-06-15.77652992-fce3-4e80-945b-c735eb163038 new file mode 100644 index 0000000000000000000000000000000000000000..05e590d83c06601db9f43841fd318f89f03220ee GIT binary patch literal 63401 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-07-12.132807a5-f507-428f-8605-fbd5fbcdfbec b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-07-12.132807a5-f507-428f-8605-fbd5fbcdfbec new file mode 100644 index 0000000000000000000000000000000000000000..cc1787718ff86e8cd118db0ee86b947683f8a03e GIT binary patch literal 63397 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-09-28.2a653b8a-d7ab-41d3-b51b-c1f0187e093d b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-09-28.2a653b8a-d7ab-41d3-b51b-c1f0187e093d new file mode 100644 index 0000000000000000000000000000000000000000..921c9269c1350f6c6b84288ca4d8e67afdbea77a GIT binary patch literal 63555 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 UxQ9K$?Zij9o%k4jHyVlm2l7YV4*&oF literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-09-31.953fa082-038a-4d3d-9991-e2244f844fd8 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-09-31.953fa082-038a-4d3d-9991-e2244f844fd8 new file mode 100644 index 0000000000000000000000000000000000000000..696658ea95381065d1473881543ec1ffac0c5eb3 GIT binary patch literal 63555 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 Ra69o)ZYMs5-;GA%{{aO<+++X% literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-10-43.f904246c-b69a-4c66-a870-bae6abc2eefc b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-10-43.f904246c-b69a-4c66-a870-bae6abc2eefc new file mode 100644 index 0000000000000000000000000000000000000000..ac38613f146b685824f99516c9f2ae1d6f1867d9 GIT binary patch literal 63525 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-12-33.f82834a1-af69-409c-b737-c8c4945ecc19 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-12-33.f82834a1-af69-409c-b737-c8c4945ecc19 new file mode 100644 index 0000000000000000000000000000000000000000..35455adea0dd6eca1fa8334f5d622c569266634b GIT binary patch literal 63506 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 Vxz~q1%I(A-aXaxb{BAT7{~ukM!ngnc literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-12-49.00ad86af-27cb-406f-8205-b6c4888e0488 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-12-49.00ad86af-27cb-406f-8205-b6c4888e0488 new file mode 100644 index 0000000000000000000000000000000000000000..ab5b8c1d8f28f029e63a85e61f182d718b57a6d2 GIT binary patch literal 63506 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 aq2P+JF8BJdN4cH&BW@=?hTn}w;{O8=`NCxY literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-13-22.93478285-44ba-461a-b0f2-82323013df66 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-13-22.93478285-44ba-461a-b0f2-82323013df66 new file mode 100644 index 0000000000000000000000000000000000000000..1775ff5e7a9e5cd9154496ff71a073c54eb86b7b GIT binary patch literal 63341 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-14-29.d2c0dc37-32a3-4f4e-ae26-ac6e1a57f559 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-14-29.d2c0dc37-32a3-4f4e-ae26-ac6e1a57f559 new file mode 100644 index 0000000000000000000000000000000000000000..c9328eadd08b87ebb6d1de03c14f16e75ffbdf0a GIT binary patch literal 44724 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 QlJ7l0zQ00#;QQ(S2Q`E_j{pDw literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-19-55.dc2245da-3bc3-4942-a146-6e8e0881cd6f b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-19-55.dc2245da-3bc3-4942-a146-6e8e0881cd6f new file mode 100644 index 0000000000000000000000000000000000000000..417e4f8e6c681027749d52039498b01164b3a588 GIT binary patch literal 44785 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 F{|EGRDjfg- literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-20-21.ad008041-2415-4d80-844f-3877e2b95366 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-20-21.ad008041-2415-4d80-844f-3877e2b95366 new file mode 100644 index 0000000000000000000000000000000000000000..f92c46dd996c0e3daf8b8cbbca0789425c95c4cb GIT binary patch literal 44790 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-20-45.98aaf16b-b5b2-46ce-a976-183c7c2db441 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-20-45.98aaf16b-b5b2-46ce-a976-183c7c2db441 new file mode 100644 index 0000000000000000000000000000000000000000..44b169b1338fd825a38ffb3852f1c7a0d1f1985c GIT binary patch literal 44821 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 IK0Pn_{~HZ5YybcN literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-33-54.f26cedfa-f99e-4e59-89fc-d9f540d46be6 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-33-54.f26cedfa-f99e-4e59-89fc-d9f540d46be6 new file mode 100644 index 0000000000000000000000000000000000000000..3f83397b7097b822191eb4f874dde0b85d8bf827 GIT binary patch literal 43236 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-34-43.ab9f45de-b3cf-4f84-968e-db929cbf8d4f b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-34-43.ab9f45de-b3cf-4f84-968e-db929cbf8d4f new file mode 100644 index 0000000000000000000000000000000000000000..e1e328a00d7c7a7629ac0885e15e8fe24e25cbe4 GIT binary patch literal 43228 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-35-10.df605b80-98e0-475b-9cc6-734e4bda05ef b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-35-10.df605b80-98e0-475b-9cc6-734e4bda05ef new file mode 100644 index 0000000000000000000000000000000000000000..5c69c40a667fb821641117459722a8344a8ba82a GIT binary patch literal 46912 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-35-38.6031b2a4-afbd-4526-9954-b90f5726a2b3 b/web2py/applications/SP/errors/127.0.0.1.2018-09-30.20-35-38.6031b2a4-afbd-4526-9954-b90f5726a2b3 new file mode 100644 index 0000000000000000000000000000000000000000..38cd14c22f395c27f35c0f1a86a306d082ef0e1a GIT binary patch literal 46914 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 aPQhIxkYOux;SnYOb36IpCGvm1pZb6B-{Y?U literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-22-49.5bf3d5d5-8470-4062-b60c-430b0a9324d5 b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-22-49.5bf3d5d5-8470-4062-b60c-430b0a9324d5 new file mode 100644 index 0000000000000000000000000000000000000000..f42eb70742000da5a9fd0694f18de9253a61c5da GIT binary patch literal 93474 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-25-27.fddcdc13-fbc1-4ea9-b973-7ad52f72e5e2 b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-25-27.fddcdc13-fbc1-4ea9-b973-7ad52f72e5e2 new file mode 100644 index 0000000000000000000000000000000000000000..677bcc05c6141692bcf31a4c038e7d0d59cb797a GIT binary patch literal 93503 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 J;CH*7`v2Xcc<cZG literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-25-40.b26b714d-b34a-469f-9711-71bbc4b4c87f b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-25-40.b26b714d-b34a-469f-9711-71bbc4b4c87f new file mode 100644 index 0000000000000000000000000000000000000000..515f940651b9d32f2a210b4876043fe93d45ee6b GIT binary patch literal 93503 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�po{2 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 O&ofi?3;5k`r~W^m+j=Vi literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-25-52.f4ce8ead-bf69-44d7-ad4c-d37e82b27262 b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-25-52.f4ce8ead-bf69-44d7-ad4c-d37e82b27262 new file mode 100644 index 0000000000000000000000000000000000000000..80356217f6194cbe5c488f2b025bbb492dc09875 GIT binary patch literal 93474 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 <=1c4-Ie}(?oGUMf44_@ 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 Mrs|jQyVJ@1e^K{tPyhe` literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-27-08.37769d06-1bd1-4ed2-8261-01021011a4ce b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-27-08.37769d06-1bd1-4ed2-8261-01021011a4ce new file mode 100644 index 0000000000000000000000000000000000000000..d15b646e1a4d2aa366891eeac372f70ff3b9ad76 GIT binary patch literal 86162 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 ahucq(AZ$QZAN>!X)Bk8q|Kn~q_x}Ngw}JHl literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-28-46.a83d25c8-3c52-4de7-8161-7b3458958b62 b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-28-46.a83d25c8-3c52-4de7-8161-7b3458958b62 new file mode 100644 index 0000000000000000000000000000000000000000..552f673368708d4ab96eebaf52026e405a38425f GIT binary patch literal 86143 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�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 E2k0t!1^@s6 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-29-11.42987dac-81f9-425a-95fb-f1480209eec7 b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-29-11.42987dac-81f9-425a-95fb-f1480209eec7 new file mode 100644 index 0000000000000000000000000000000000000000..f82d6edcbe1592eead1813aa588f9a0f8540859c GIT binary patch literal 86206 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 Q{K2!v%WKBHUa#=~0j9`^QUCw| literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-31-09.9ba3c512-1afe-4804-bce8-7f3045cbb1ec b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-31-09.9ba3c512-1afe-4804-bce8-7f3045cbb1ec new file mode 100644 index 0000000000000000000000000000000000000000..46c173377396f7bd7ecc572e7d445cc644dd2ee3 GIT binary patch literal 87277 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 Sr~lh$^?$df|NBlS_x}Mx)9MER literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-31-28.b65aad29-b9c7-4d94-8f3e-e1e85df927a1 b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-31-28.b65aad29-b9c7-4d94-8f3e-e1e85df927a1 new file mode 100644 index 0000000000000000000000000000000000000000..ac59956e53de4073df03471546007004f587fa74 GIT binary patch literal 93910 zcmeHw34j~NbtU5~iE=xRb0;mx6fpDvn3Eh1XC@w!AUT@TGoS>Sq~Qk87=Q%O=;{WC zBbtePDe@`BM{LKAZ8=Vy*b!~Vw<KG+kKN7Qn`?7yb~U85o89b{J+sIARb7onqZ`09 zo2C@ch?)Vae*OCO>({SezkXHS|NJY)zC`YY`}XatsoNSez9DxOpVOyJjhX36Yr9&g zHa631+r^5?>T66tuN5sb-D+4>tEQFGTUuePxt&&<&04jnT2;Marp;#hVpZERDOD}i zs}1Kvs$$h^#`AJ7Kov#3q#4i8{p~O9+s8DsiGo^ci&ZTx5udsJ`0BCjy=xhT;OEXZ zW^PX=&s57wV$)I<GRonh*WR93$PAsEql`IahQO3!O*PHgSVK>qH)BdoZEViQ;=_t& z7S*OUdqS<5+R$yDs<J7ySk#)9R?1U>mb$4aI#c3WBi;oYkD(^iH*@<Ltx>9$&!OtG z4F$DpYKecs=elO83h~O+tl3!0DkrC6G7n{yt*xz8v(l_;rBqR`r;9o;5!cjO65s1u z!!nbFnqIt+Ea_W~ny!}2v|?8T^n_x*wxw>HN?B(`4b8MPlQV^ZD2<`B6s@sYZD>TA z{gcoxY7M1I|1739G;2t?Q#n>)dR<daFtzT6UDxXRMNP3PRZ{`SxAm6NGU>afp!bMd zrs*Pxx3^+h&7@|usuyQtx#a2j<T1V8gfJ9pT1-I`Ei`L3wvd_CN}F20E@|kN!hj6T zN>$A~c%jx5wNX;y!$nT=>}Z_#k#7%)R&zcn%X*<&)0Dd*i%p$b%8BYF7gLn;sd_VA z=P)F$9OO==q+YC+3aGQ9w;H^U#zsa*xIhy`k{WEOn{GrU?P9g4CAX?2t1_*u7K^Rs zwo-1@Y6?$M^fG6kS!9~s4VI}CTMRvBp(R!P;UmY5v)X`IKqw%*Xu_;Ani>IDEVbG& zl~NUQV$x7Uhng0okE*y&*D=&K6}@Fq$2CcmD_V84VkvWqAkqHrt_OX~cqJ-23-xSk zrlQtr`j*LQrfkL1IdT%9wj}b7Z$NftW0HHWzUB>|bu(rd#a&IBMT4Ay!F9=8Kf!Q@ zE(a$OkYeJ}KHZ~sCN0p5R&&W9d7VzDL0)QWJf*YEG%1kDbX{c^T966wIYmw5>dL>( zt}2rR>S}xcb_n5iq3EXC;SG)Wji#nv;C)+GPU`w*O&eB9dgE-|A}z3~S=2>PI5b+B zVnT;1t>(0=o9zZ~^0Hj0p||TQWQTPPX3?htG)cIU7ok?lwsv>5vxCHHqgZQ|G{v;G zYnoZnG>CXxSZdYA1@u;JHrCFMDHW!bXJbU0iQXud8t2Vav8K05<(kSgPNsTZy_Bw1 z3ud|uHIh`fG!sfIJ&`(;8c7$;&g2y2KZV3tT58;0_4ezg)9Xu#xJe_k7$1&PT?JjY zOeoN%tSCO@({VScaxu{+9U3O6r2`XCf$A!fVt_W5jNcsts&yz7@Eht8I8ylKTe)Iw zW3r8L==7x|udll|Nc6R&rMHR|0b<L-4UyDrZ2FQUs~2-;O}R_GsBRQlwP`6TMh+&n zf^J!Q9j3x1vIS^NVeY_W+Nj>gl&wm&Sizi13et3qsZ-hIrAbArX?)Vggj&{AtHm_v zT8nHXm-s{TQ*9<I_P0nn#qPX`8Oo+4IhLAAjdR&M@89!tGigzkyU8a+kGbgS$L08p zO|a-oOS@#H&x2_qHO7rD!H9HP$yPL&2NzXV<qT3Va>-yQDTQs$TOqf38pwH?0WdK( zie&N7bmGcPoi~+);594{GJFV!hM8z6B`WJj_WZ`i!pW7pHWIgOjWtDukkoRO)$?^2 zEi@m_D%nJQ9u$&UV^U|)hb<NJFf?choe9;+O&`5LhVGBWhlbnON>!8EnBS^el}?oR z=#2DpDwXOi0OKqVX{tlcc-8ywP42HJ_m{e$EKKRXkjnm3)BBgF_is=U&P0tdo#iJ- zMhInU8SQB(JWbJIc`&UstYC1d=#(>OpmM=TWxsju9PbP=3gSb`eubn=Wt--#Glk;I zFm+=)3G+&x5{7Q`QFF5Yq2pab7u-c<SYl=h=8DFw#K>@$l%L0($hIK_9YeUI)TpNv zsbsQ_8YPu=DZ`GEW1f;2RZhWPHI8?e6B6sC)1Lhx6qcHB%?UD{Q{&FC7dmGf!5p(e zgv~F^aWTi5io>j7#np~9F@amk4v}pg)VCh$(3!Nel$j~$rERH3O4W;Ubwxu9)3aHD zm58nszmpgl^(uxK8T^CWaRLu5w|q?bnKWvZ1d!@pQ7;x$rpylZ({A}pLv^UfN5Ucg zBx~F_w!dhXnpk8c>rgtI$uieI=Ub*#EpKCC##b=OA`EqnNwWuQs~Odvx6&|+?A0f) zAz8pOtE7~Y<(hU$*-B21D0P-pTb3T1yZ+Fl*B|@%&ZEEZ)R#Z<^!;zxdF#inz2Qwe z4}AXm;~#$d>Ld8K^WZyY(yHBbs-@7v^wjXwVCkE%16j<Ta0N^Z%NI+<#7cRyv7%n9 zsZA5csYu3%r&Z}4qRA`j#p6tG(mFE+wOv(tLz!NqMKo_lH-zAlR+^2KX+3S1tEo`b zv#~6%mbhEp<O>=XtI!M+4EAq?Z6-jG0L0bsv}lzp#U+V?M9?hSh;^p@VJkU0G7?j& zAhNp|ZCs$J)pi<)ZUa1e3&oYbeUFam8dGFA<Y6(_X>N0tE3gk*v|2fHZu&M_kUJTU z5};J^(}j|fv6_RHOK{9XGZTc17RmhknQ<E{0rtW?Q>(g|pX5~f)@Iizu#dX1`_-Ug zD!<shq$g1M(}Y)sx0@2Y6n01m@-d>?0|^7PaUsxJmH0g<1>IxkhI-T)*lu53BRz0+ z3{;{Yixszsb;}5mtzqa0S)gy8O5<W`r5xb%>9vv^v>g@s@lKJTwnn%KyzEpsvOZfc zR8;u&nyuz+%wjF6EW9eDd%h4&?_!MT+1>O8c;ZqRk~p|<8ZEEj`HW^s1|QXCs~`t< z_qZd-UcE^9ZOL}%AcTFp#0PiYCgzM=%6;JAund%RA8-e)o5enGaj(!5OwWpXssOjR zgH5h!pYT%3AVZ2EooagZg)gDJWN@jObc?*uR0sWZp@4#pV{)&=N$+pg^aAF_#85wN z-#PtAqlBiQdX3u(0aFnS-cISgIZEOVX*Jl!gcRFdjqNtm0$4}MU>|WWMb5@Rwdg=_ z&z#Wiz4hqRS3majr(W09S%Q!OrG>=LWs32#fjXtFZb`!=8JU-zJw@ex2^xq69Ww)= z3ae8*lFk=nC9SNsY8G5w_3a9LY_txeI_Sp(-%GD}K(X9@>Pw$^>aoYJzvpew{Om`2 zA?;>#0I!H58gbZVX>4kF8oOIME5*4{gaODU1>R5#D{>S2JA6|rZ!g|UZ2|LZnO9!J za@YsAhsz}FX>Su;JomxSi|;<*;Qh4^eD2!2zbppA&Zi!D=AA$9?g5`NH&wUaEP>^$ ztm&KB`EWPSBZ|Ga=K%%hp1J@2ou7QnRw1r#@jwpFuim;UD!KEJ=O=SuR293M5smH$ zIYi<}<C<xkRoa<&E)Hmib{BvBhS}~cGaAWH-hb_Lk9Tw15BaV%DIstSCqHan(e$0a zsG#UO3;UTDpW9j)`>dWuMBbZk{_4&LKJ@I-%Yl9BNQOtTcubMLR(n4Sn&hXa5$>*G zCJiGQ_PCHtzN5R0y-f054(1+gI|sWO?%&P<!E91sgAC@R1XP<8Uic_<UqkHO+g?W( zfNL#FnTQ3z-hH{&s+N>GzHs*)Piz~V0}yU+_PBO+&cBj;@rjaNY|-A<P>O-G+X=aG zlNh=zIB&znEb{xNOl&dI2gM@Sv0|~<P^zwDZbmo>OE}v;i6N!4IJvfmQfjGmj6A4` zSOsP?_sqtIjwn|oj+WII1>=z`{#cH5P>hXpf0C#5Qt52mMa|i`NEx&|1=@HJ*h#=} zWeC60>CP<^1UI?*mFZie^W2H>Y{D;{937)9pDhC@Ub&4U`)GDHUPU<2rFhUHbfz-y z?;P+9fNUbR^YA-%9{P05)`6aU7(l>8-0c!Idrlx%CApsq*pf2a*0%?bQ_o*N@!+*z zdF0v$-+b*opT73?t2>XqYv`|^c(bhC(G&E+gM#a%?nQMHRU;mZ+`;wjtXdFEr1G#w zyWMNp-jrVbJIJuCHp;qZB@Bdae?NCqD#8;A_x`(o@!Er5eCo+ZuD$M4G!b{WF9xV@ zfVyNQ*Wds6&R5<Ot}074v12(<(_(W^J^uL4TOJ8l5f*8sDmEB8HYWTy7@NEH(8EtX z_OWo)Y%;yo9JoQEldeDh#&DI@wR!=OGnHy{pmy1{{mdIt;m%jyx$~J11yl=(3>rmz zQ44=6wispI3Et*B1bfW(HIYdB4GKyZKYauckzeQ<?9>j_E(|7sb_w}FHC1%|!eF(W zB1oS~d^tsR_q17TLxdETTg9T)a+|Nm<Vo0}Y;U+PyftIj3*K?kQ0)$I`5R|=pU907 z@rD0RA{wdM)I9FMK*o?GyHp?_CC$}ZDdDJPm;6v0d&^KDekw|J2ntb+ga1saa4yA@ zT{8fI(@*c(0)~VrDt;Smdp5q`OyOU(G&d68pC}cEd2Q`Qu7tng%B(_dwxeBVcunUV zXIW%5LDDebRm)-tR5~2bHyOgJ*!Bf&JMQVQLF*iVnS=^8qsEl0!uGr^tCD~FF;u|y zlo^SN{vuq*w9vv?5OBsr#F>$E-E5YHBc=l^kffw242nk08H58;fHi!i6cZKq?2SrF z<ln(48n8<wQkSgnH*cSf#az-p>`+WGoZYf7anRqvh#R=uI=x%&isa|PD!dVHbd3C4 z$O~$*GY84$yZ`oQ#Xx-T&GY`1aFPb9i6FV)#k;heY*+v42CgZPcm3)Zs0Lr`y)e&M z%rzHNduObQh;v313`HfI)%&z*MCc!y)apmt=7VI-olG@a`VoKAP6E+i4;Ax?7@yQ) zh}Ub+Xv29PHZ20^5U^OpmJN^Oqd9h%2k@1uMJvJM>1NSuL-^_HHcwSu?i{Pq)n<9b zrA={PetT+}Pe6Yr;LKdnwv=_PNSii8L+%EN_`r69#4LUeFm_Z(!D=Y@KWR^e?q#8* z%TsB0(>fc1;{l!h+qYF+64a~4p4d7t1!Dn;WNAA+;`W7go3U+UQrOr|u|QHhH7~8s zA5X*)qRr24p;VkB!Uu{!oy{VY!zEFk!VbGTi43gUVL>1smv;ngNK*6UVw;=H&LZ7u zC`rODZDuOaDF#BEFx2f8{lal{gLhPjnksX)C->pE_kh{C`sC9O_5!&6_!B!1Ke+SY z1MqzGz;o@FKl;>{AAb5X5A=ZXWw(dJ&S<>$MXc^W;u(qX$K@qw5qjKb{CQBrDdb@l z5<1!IOCc>DXmOQiTse@<)i$-`r9%8%d&zQ!e@}66B6KKaa&0K%E~sm~WC<sr=vn&h zO9W+z`b|VwQxG(vN9=l8Pq>KV(F&b*R_N-W%^Ft1uC%SJ`{DB!SrX-vzi&@8t>dhv zT`3k$!S$l^I&~)Dp`S1n5i@(UEz;^3PQ`tVT4rKGb6MTq-ix$Z1x;<-<Yqbg;i)ID zB8b4FAMD5lM@85+h!iK;%RW=LiLp%~``hlxdmv^FrbI|E`_3v{dP7dD)V5A5Z`YHJ z|8zr>P4Ah6Pe&j8@Xpl_?R@-QI|0*;n6o~=^XS9Ry#DI-tDgbe{N^p9q2jM6JiXya zLeH5Zf?2}umCl(WKuyzJA=UKFo+qMIv~pzJ<k2e!;@42sYS@IV-Q;FDqS#L<$u)%J zgJk>7RY(D{dec>svzv2cHZbV)6Lr!PVhgC3%Gr7F13QmDcI~}ic;>yI^Hn*7=Gudw zxc2BrdjJuugl5`#==D#1=^Y3i3^s=)<kh!bdk|Yk13*6bk!RljF<<JOdVP(;U28<@ zk(;Lx1LVx36YKd>Awj?3dN(gP1~Qi28Y^tiIyos^Oh6|UVQXtH$Fir*&dQE+inHFU zsM|TaH$X!wDw37mSLSZ8;~Vj|7h>XX_J*qyVcUYkH@iYQD<sukQ`2!6w8wHiqDH#w zEa~BE-A!jYbHNTD)gA*?9OljQap*BltEF>ppV+|t9*VeL6IBp#UCZqVZDtyyzABC~ zZmQkf-lD(JSt@9fa<=sYoHfESruYo(#6SJmC!c!!D}i%C2kf<n9(wx8Ag4?Zb>I;# zM`8mFY0e|B?LzX}B@!MFsHZ0Kz;r7wB>JgrUvcovB?I|kIQ7mvvx}*OWRKYBN1e#) z!DIsPG+(N}P+kpD;cf=ItPW>q!#DuKS6IU3R&=!lu2TqMc<;VmM}T{2wZUaLyjrtK z_m}5T`pxYd#5f7%aBs)v+%*4yh#%T{(`T=L_VMda{PfO4U-Z>rZS57H3W<SjpzHm7 z3Lfys-#8fBfwZiz`tb~CNALnQC$75SXU-#1p4}dko2@+C!V_MD`m&Pxj+VdNg$<YX zK&qSyz$uJCX6a?&4sS%8wW&+-cmrH(K{e2ir_;Jt3<4^UNUk_`MI|rcA=Ack<8(gf zrz6qnVI2FSqjoa|Is)c8p6MqN7)9N7iKvc#@1{yQ>pC4CD2EYN+LqDO*KD?TlwYq| zcUSuFxi|63?c^@yq16zo<rDrcb^`<B-yv$1v4Onbx#cB0ZXtHu4r9lKO1N&1VlS|V zv40+`ZTm()T%v>^wa$nJio$ndF#I$mBIw8Xim0n?G$ME`UOW8G7eP=gKb7|sK=ehH zsYR`z7U7=?R^3im|4fs~$OB*ceCn_Y!FYM#ZCc_C#MpBo>RXEVL`GY0R{0k7X@WE4 z1`Jj4N&qLN$Es~u$&>n+joJ71^y-NMOV7>FFV4FPQ=A(Hch&E)b-L6OTP0ayQ}4|; zAa-i>x28LT&pbkAPyB&rOnexQ^B<f(F{}{M+>0Z0<fIRMR7FoA@^6->Ay@?4yT_gk z(ZZRg6O@g3&}6-Zpz45=ou2YE3~}*bj7Mo9^c(kf(M7r9E?}iry?{LKw?$Wt!p_oa zrP0~hv+;{+t)-of$5P4$&gkRl6fS%Xf|ljSMES88=>i<_=R%+=8?Rha?pj?~!IgDl zxOzy8w>b=6`VJgV2{h_7uANKZ8oZ%9`EMQ$KEHB&SR}r-ow&M=a3Wlh_2VLm1Fo!Q z=^DO5t6IZ}Hf*MYC3UzjFDb;PD(;VqlGIqMNe*wp{Dz|QRWz;|#{D#C7hSJwbJphm z*?2?SYV-eITpU<b8+5u!AfjuToEro+hu657SLJ*Tq&?lV{b8KpF0Rj1CI*_JFm{{? z2?98*G;oZ}4C>W1u!_a5Z=XVs;?h%Q&5Z<V(s_#E1CuURalDV_LaL5mD~My;P510) zPr}0g>eZ3$SVdmpEdPxo4O)|e0{aL2^&Z~-63bhsH)lA9dN;6vAsun!UVhUXM?DeP ztoC}0A3)((@y^ERcxD;bY)&J%2~n!z7VD{z{q9IsUr8YqOE+|3$j;&(@_M19D&=9t z8dlgezhE*h1_la?09CI5C~R0MpBo|*r_ArfQet<+0*!dbK@&(!t4X(A&WcM9?Az0A zcYvqr-u4MK%wK#c!=v<|Mzixrmof=r{jlK2u%KjE?zB<Jq?BlJ^i<d?^8Akdt-#@N z?WsIUD^-S1wXVK&-Ix@}nm%KtTk{NHWq23?EwoUlE7H@MOY}$1;2tn>VAQSU<Z(-1 z;ytB#-xke_{@vOg{!9m%<z9~mRopql=?y9#ROw=-Ksyx`m${o4aa^QrRe7tDH!=*; zM6x*uAEpz!7t_D*eNF)fErjftYM~Xpgb9;!u!RshST2Bq`qqEccq$!iy%f-JVuvpm zp+ub1Qe@x;o|p1a;|wHUtW+JJ|7m-AmRt4iV^LV__0?B_cuNJ2)T5fh<KxtIqa3{f z63HZma_5-OIDEiSzMvCP;-Ln9E{O{;&g6t|kf*00e|?uO{<1;6=s`B0aM%@Su!s)o zQY!XQ!~N!dlOMh!mWzW5{FB3`Vd5UG{QJ!|z7jIX0xMuB_%t_S-gU_AXotgNK$A}# zPw6<dX<^pXI(;eAxZyA?1BnYgr#;8-61YzF$PAd+b_WEhK<+qkrZ?ZN^`Pyw$m}W~ zq~*QwxHS4?FS#y-=m_f%o)Q8C3p#c%oIVoh=vnf-jn9c&;lw$3v8UsBoB}EzY(R8l z7f#cD*!xNg5T9C?$G%Q1EM+t6)42V*Sy2;uQ!Q4l?OEI#jAMt5s#%dKBg4YT9v`B2 zGio}Uz2orIp<>~%va#^0%xsT~Gj6hs@E3G?^komfX+Zb%mJJ)<pmO29+2UqNhr5mr z8R@Y&{(6uSQV~2b$zOxmiiSf(s6br!1`rZ{A4$Z5!R-OtGeRWLPv;gOZB9XVNuM8X zlx*V7wCQRCt3KR&FK<bq(-LA9=-%t{Y$D^UE6|`z*$X22Ok>Yp#YE)$w#i>tbW0W? z@F+ri8u3L-;5}yit};P$DUATW&ljX6ZAt}9goD71Fu3iMLsO^|?H2JsaHHN+jP`3a zxKNA4!r5gFu&->%aKIuI4iC<O<wIOM!~=$IqM%%NRkJ5FZK1JUpuuu5=r;78_eGkk zv~Q5Y6*0JCeb4{mxshhi|AG}5HcPoDW>Ei2fR*B-VKE5T`O$Q_`uBl}``bJ|kn;)n zKW52`)FImREQFA4w`WT3rF6a8bp}on;iGb6+4DMCDPk3c<Fq##BlS9k5F1=r5s~D` zzUFO&0Jv_2=^-iOJrBOz$if#39udT}3ujse;SSC_xFVWQa>r}+i}jQf3DafD`;4w$ zZna%(pU?}SS`T-~F6QqAdOi#<Ju4f8vqw{R&B<f-W5Tvn^gunh%jsxl{&aTX#J$oZ z8xT*xcaV6;VBIiCzd(n!$rX1|L`|>2dJ_o74Ym{*5-q(p(m-;3@BH;$yHd1vyjWC= zm0*btlvnB(DjD<NbF>Gz`|8RXuIZ<P4qOCW*Yr?&l5XQ}-;)ri6;LaU29&54&ETqq z*vcSKZ-toX>4|Z9=wcUfGph)Gpy#W5^r(!MnQ0Ct-guHTw$h?YTIp48kVTP8)5?JZ z`^^If5S(M_mRdW57v_0J92(hot8>N)3-TRQaG`h+;hFE?m>t`164VGE{Yh_&#!f*) zuhY2--hc$7k3;7E{Ra*x3A89tsaoa`+NJE@e;J>}_bc2ArEGc>QgZ<4n@qYg6dQJS z2Kj|$3P(O`w~Bv>pBq-F2AN2oDNUf2sp1<kvfoBqo2TG|nC*5oiErSdH|kVA!ltFn z`0&oz?C|Y7DuDhIPt4|Nf^o&{^upGISf66N1F09dK`DEQzSt>OhDj<Dg>9?dNA$%` zxdLJ3J;TdOZVRe;H}HZooqy@<1Rt6l#`I}QTfA+&5bnvbiLt3eVkJ$e<&W1^kR40; zf&33B%y~wVof;`A%SR6!fSAgGCMiiPqazbjlZOtv<ShW*pv|S?j_0x;uD~{R?vN3h zVAcd8@hN5t5`{YA73eBn`>biC0La>?q6+@B@Y=RjLCEBpGi%!vv&j_su6uL4Sxq&0 zZVHdpr|ElI0`cbo@i;M_cxSj0XvjULd?<1F*^~SZPWrRp#xwzGMm|?k%r3pdfRI{R zv>_6d0$6EKRrD5KP97O6*}4&5?X)XAA5Yb{bMXbC!%&TlA(4yo8SPwgSR+AcR}{Tg zN_jOWuS<?Y0B9!erlo}s6lJ3;9ozLdyin{)=UeTLO76$Dzz*;fJbF5tU0tDoQNgf9 z_-$}6hLYFum~pjuVKy#bk+=hQU+2lKgLfmu1GWkILA>dp#OU$iO0`tdaG(6pk^a$f zZezt=*1l<5)VAx1z@DLqROq|D9D`wGSAnPiCw4!Oe~$2a7zxoAiftFx&HDVZ98g|t zFz2E+Y?xY)!mQ~;^LN9j;ce<PX?T*ypy6qI<_sx*{CGsx$DH9xcUMLX=Wv$^!&4(S zVBA=5rTNl9hi$xky;(1>dCh?X9{c4rubF0uwf_3HVlYEIn`{^{JiQi7XR5ScI#X}9 z^+Js5Yr%k|ub~Cw)V6C2hO_QDV80w+*jW4;8ZZdxxe$c~<H0kC34@4^5FUxIv4=)D zXhiEejTw>Vv1UZ#;N}c?;P|}4@dLiZuTKw+Sbok5j(3?iA~|yVrUUJ*G;lfz`TBIv z{M|HgZd@ghilk}e*<|I|!_;f$c#@@^<4GRG(CK7bpsT^Nz-qf{j$<P1Z|x9a5t}<8 z+_jJ7b=kBl+_l9cm^hfpL)>dSZSd^|-8OA}-hHdxY?OIA3;SlvYD3-BL_hVgl6JRs z*2fC*P|<6TotE%&LYEA6{<?a(SkqM8r!KR6rIkCyJau!2SQoT^XmM#A0ljLolCSGH zq93@MAGkN_sT#~bN$8YiLf3=$z3+7y>}Axrq6o)dS6hk0^wUk<ir&8Ei>~~jH+B`g z=mL)`za&kP>{FV%*nO+&++Ofh3MwU?d<c_^^<vd*_bcT?An1TJ2(Hb>_{kWvqG?u4 zsW7cP8}qG|N_pzyhk)(JY49W)T2#c7Y(>*d%YIJbOE33uOkSY^io^|yjz&?GbXqyC z;T#WMGR74hrExH@*%EKqwzrl7X)QCou58v?dIJxVu&P>vMar;0z>h{N=S{uQ$74(l zM#PfRfNaqVB!M+~xI*_75&8r#*lRP?e#}@_L|qc9B3^L7ie%3u=nZ75nUsTz^?|MI z;ScvM<Etu2G<{-ze3S(bp{R4sdc$ghLLhKKOVIv4510yiub9iDZv&xol?&LEq+K`) zbENUDHSkh5mSkG{RIAzN`c;fXU-Z;7K9Uuer(W!Lj&a=wxOairH6reAkcZWM5X9}# z)qYu-Q=c4^0H>|NyDdHs*7}EQ_>hMUP3X2W7kX^w$OHV&YtDhB_mEfT?OC^xgSK_P zJnM@&s!n&!yHqhfrsZ3o50^;4#O;^2cGvsjY1`<#+?J|A8^GT+E6>Ko=uXjHAt>5? zHA!Lw`;!;2OFHOtXVP@(5pK{^Dul7=+YDcAW=CAvMyjm6tGs6v2k)JG0G+RvuGb1G zOYouYq~dhzR^HBPk9;S4i(ywLVOJ(;3ou~3g_N1wlSyH$z+Ne7Wfj*|;c6%yag$0i zDYb~5VBZiVzloiAjU~&q7Q$?8U`#VEna3S1?TpSW9M4VGOUcnOH-HzUxy`DZ6-#Nh zYPDodD<kBrAKPi?Ter)RNz&EkJMS1hc-ZH4NDrV4_-*K0scl%y-Iye^Y3zz0#}aGm zTN*Yyj&3`5p70j%#&ovVM}|Fwph0T_ol?L<#NBkr`Q4^LUhhKjAk*pe*49>PODl{u zw^O*?D;=8?U!;O{NbgvJk+C2~iH+3tZ6+-wAV?c{$d{5yl15jsokvKEutPAH_55*3 zpk2UZMIWoxQ=xdNQ(CF#&2$0sjAI*WGgW9cN;NHoD2>#4Zm)WZ#>sqk8A)Kn4b?1I zopcD87_{1cLT)p)3yd3B_Iq=iy1rS{@-VGx+Z61HtAvA3MWLnCLGu#0U*GVK8?=K+ zhCH0^>LiCuSMT_g3+^GhB4sv4??k8DBGw*jZTz?}z!J-Z#AP{j&c;u2ZnYV3Ha>kB zGE=+&gL0uXeKy|3Yai;IM*8sH*D8(0uSgQENJHHtfry90rSmEpcS5b1_I39G(-aNc zf?nFj&_uk6Rj=WLmu}+)xfku*w@+_bSY#P5%)J6%X1Hos;`4a>yowt#wG3lAi_a<X z6}_Ql!C9QlEu6>wt90iNR!R!JlFlKOc(oKaUX=T0pdo(oi%yMi%)RLw_U&^nK2;KR z-LxPBMMU8unzL5J{bi=bE#?!r#z~2#agiZ2)0NhCwE&JIUJWNZS$&P^RI8b8HLR*t z(@JSEq|$uBmj=H<MiI9_BH#^-qI2QO*y!P5veDa_d;zFk(u#><5sN%9v~jV@^hO=j zP`895!L__M(`GYGVa;Y*KI7_qNKrpX+C~qLa@uC#7ir;zSxy<nYG1xQ3n#}qt~4Xk zv$WQT4PCj?K8A5yXWvW@+BLTs-<10%^o`k2o3JD-<D0J-w<U5fL{f7b!Pv&P<Scx) zqY1}Thf*Wc%D}yWzCwH<4@6Ahg2Hn3(%^-MjBm}o09DhakjA&=z7HSoL43d}glud= z85@}%ADteX!iUi*<J-B+ma&hjnZ|dVGrlu%#rUoSFHYBh886NqL-B#h4i+Ngy9H7l zC^cS^yA4R&Vq|;|&m-|QUYh&j^Y-l%@-#a`QY8n7>{<*FW#rQ6Na^r+sWdi%oA(?+ z$9<i`Ei|~?%ykIu?B)1;d|HviR(L;1&QkMnK*r}+?#-{B=z_pynpJRH$8k;@f&*`C zESy}qYlFb$%{9uroyY;2&0~6_T;1%1kf|I5kH~gaM>Z>JqAY?r+6BNVJ}NTp!!H3a zGMD37J$`Qh80Bz~^#Fi%k<DWy13*L`u%MR^u#F2RG&URGt!V8=IY2|>DbtcR%VN$1 zVq5hyw;x|Umc4f^gXmta&1sfCgIPYYX(<aCqOoCWDc2gH{{#>lGQO9Of6|tw@qJf} z?@uiLLGA}3>olbSxl29LO}R7&OdCJ2_=kLq5)A#gfo7G<SBxKA{G;3*HWF9nnRq@= zqMy&l&+&UJ!B69d7XLVx@`oiCiw%pC?a_xc<A)djgex<u-(uU-#*Zxi%ba54;Y0-} zdE-YH|1|fVvcgM6t!XKzve~t1Ls|T@+_$+fFtuuG#_fxL?l43X;Oov@!zagSBewV# zxs0pi9ZE^Z)M$Y-n67d0FZ7y{&<o`jrf)p-#=V<5mH<^clIB5Y+|lC7r3S~6@iMfE zYsOZ+Y3#pZ+?mLI3o4>}dM)%B+GxaiU(E2NBxVd};8O0KArw5H?Tn#Z35CBFI?6b} z>2!6z@$y^+hQOY>^3&BvBUe|(aI1C2NG2*T&YeY{-%O=tq$)4rV^Pj`M!NFS9OlG* zi6LX80<AKdSo}gxMeozV^eQ%K^}3w}(m}TO+WanGn>WT5znFU!SntDW=VE<v7YY0a z?xV{c*VFa71lky1{8H|Oe-$BKpEo8JznojN(UGs!_0T&Rz_3!(f{LST;??<qUZFQ8 z7az+_**JYT;rQbykAAvVMh6!k&rNn9zzgH00bivz4lO=$W7SVBekJ!(SM{B*)EkEv zznaUsvV(?{XdIS;0k6CHJ^5lxFFu)z1tXVFzu+|@<H+K#cFcQTIszYm@vV4f@z-*R z{uR@6H)I(M8MBMO9%1!!i@%Y3S^w(!tM<l^E&gVNRlj2Kw{rXYS1n$-H|7_AJHon; zF8<CS&E~J(8^;!ZH^QoqFaBQca&WU9eI+h6^5`r3x+ju`YNM=s-yV}v;`0!QIMjtB zZ`g`AGOfzX7N4xZv^tUCb5>>CILTcYa1ipX=#p_NhpB5{)>z<1?TlDs)zrpj3qc@e z3cikp2@?;xOL#`+jJr6h0y7pXr&=wI+t?bprHrNAw*yz_3f@@eYg&!JaA2(D;(!>` z-LlGQ6^1E}#~W)`j8`UjT0UP?!G(O@Sm!1r+3v=M%!1R!L{?T9j{!~}<21M8fQe3d zU$Ri(?l!J_>`cUAkPir%x!fU;K0~i#=%wTq{H#sv9>8{YK;S$oE1j)(n07BWA^;3G z4v@Wy^AM|vGr4aBR!XNj&gRCb4#(UTl__?15A^3G8odZKujcx-?dIa<dRa%Or{YGQ z_eVaj8Gw9^sIa?Hl-sL4Dt8)S$%9+PRccXzPbog6ONbuS7j2R@sY6RaBvEcJk~F^Z z$>%pUIK^$Z9q^TNGyeV73D*nrrlgM=S_z~NxxKJdZ4rQLu>w5ja})k_iTqxeF4&mJ z#S2WeAWR~^7p8jdySVsqNV8SoV+AN1L4xQ3q)z3Rc1z`;+pMC6u+a=+6<;Rz5C}tJ zq2{qbEPWVm+E^Myixq^0a(l6;We+X9(gHLW`7G`u<~+NL9b5J=!6sR&NMu|J8YU8= z2UoWF3Z9$=9GP|r`0nGjm=8TJpdKhM+mghzCh4Eo21%00@5QDow!$>U=mWAJ4^o&8 zNH2Upk^5FInE<9xEaKh$0%5myY{T?u>g(*TFcCPVmx1o}L0ussdLVm)Efny}1JfIG z<NiaLXZLF5n{1sWhh9b3F96{Kxluys(^7kg3OFLLWAy!G?j?e0ttNkL$Thb;$meOk zw_?2679?jQ1695y_hPEjNpfbcxAIAm!WoRW<%R*1hz&S@$A*WDw{w$Vt7=v94r=2a zxx;?V>xAmT{fAn7WY=`~s7>SHE5=VHxD_*Rypzv-{tjc~U0m3u%hz~!?z@Q!$E74Q z=8X4nY)6fs4#Ea!uJK-uP2Of?yf62|gv~ZKT&`*ffg<nctR#Pk@iV#a4*=)h65|8h zKsdT?d@%RD0f2Dw8b8Y!AtJ1e4{=|f9|^Xz*Z438KbBd+E#t;Vg1|*Sus@P}KI%R; zpEW+(VM@7LhfDze9B<gM)#DlCV?hn0T!8+(z`43){6Zkk)g=Iaob&hC>e9*e)zfRn zF9z{fLZHYmaoooj?lwLVgd3Rv{3PdYX4&}VAns<C0rn^#GnwV1nd8RQ+z<Ho1J4HV zr#QVQ7BWl6H!@k{(?Rq~2o(7YXWNO@^=0E%g4jm60R1ed_|&NJxgd&9jRNfR0&L9q zLLk@}z`iKJ#*Hrpf{g?0%K~h|cq|ZX0$`5|uu0>IK(I-GeMNvBG`<=Lb`W4sa;BWh z%pW&?HHayc3(#K^7}t$o55!1=<TnJy?DCTFn}HaS3(()<BY(m8?Vypr0HELDqiEp- z&TeLm-whf?A|K$t$E9*%`K0mpf}|3e0Q~!0+!j{WPG^mO5F~Cq8^FKMftTiwW|oY9 z7zE6-0sN0R#Y>r!nU&+lKMtZ;<OBSlaK0`r82>bguS>*-f5!Q`w6L;h{PQ5bQZ7LM z1;>a%{|7-B`I!Gh4t9FU_@f}O)6`3U%xB-_`Sr!+g%#sZazErhGHn195c>?vnU&MV zp9WD%xd8n$-l*kFcHa2&V9+c!AdSD^TwOhSSLRsO_*X$(75M=FOTmK`<6rYC=<zP& z-v|_I*@e{=<EcOtJRc}_xOlD^*Mh`z4M5kqysfQgjHiR-4VeIZhF89EY<*!ZYy8`w z%0)iF{~cFwt7}=IkpC)3!AS@d`S+rR%o1_vKLpmm^8x<XoG}|~^DD-G4B|cI0`xx# z%-QwTm6OJQ4#dp!0sde3XxYf#yOc5hYtU%n*#Q0<4$NO)GyYo;FwX|?f9KrJ&Yv{? zhoHhWIp*_7&*vRe>VI+x$R0QTSCDvTNv-{F&gg6=mz`hF%o~3j#ApeDBL7EVK4tvh zK+LBA_Wwl7NPV(>@cRTdPAFLR4Fp3m6j?G_*z<Z75!*cM`A(4&tE*Y|f?h=kB0k4n z=oDGVE@jw@dKDoE6!}Jip<S5lI{PO29AG46q5s)8JHT0XTQ6WD=35AW%pQbpv2Ud> z<kM<fiAbJf-$v=gm)t4L8|>TZYk+ycA%OQgBwoZjv+txY6ba&EtRWxZ-$f7<Y;>t! z6LC@O#gs($eVZ63bB=vC<&rN+!xe$0gA?o}l)!Cz$HKL<=Gga89)(AV_z3n=`hGj1 z?yz5d0x8({5-8PkY$-Fpa(az@A0?1aJ+Q0|iB^3-!4lt&t>3$rWj{b)m7YZj4h4UZ zAio2U3mf_QrL|M2c{#JbaE$#BWgO^*!czjsewfP8E;+J}&u26Fg_ZpJ{L0A;`w_}{ zc^_;YMS$){sSt6*M#mIN=*bZq5`}LkSn5<eDZ8-jq9;bV=>h2JC<e55P(j*EccEo3 zqr^K0#0Dh$37*zSgd}rpVR?S3&8j;olVTeJyWOW0kjAMTMQR~Cvpm1B#1fQ35f!~K zaZnT=B4F}aq4?6mMi%iu0?h_HKv}dv?S-ea3=qDYO4*#sEU#q|QMAs6DX|}?Bs7pD z3EmcgOm1zRr6{4F2oNL+rwP_>(g_?U$hMh0LRtNq)L8}yN2!#}VsskhdW=%~v6zFR z__(|HO8)p!HZf3f0!8sj0w&Fc9>T!FT8JH_B-(!J)iVMX2o4dnJ=PaiT-=zVjDBO? zT>{7sQyIHw7S`^bVAGV)uV)Ang^zR=KFDSUER1ywn<ZHCVG$qJ=8qp=&unb4IZBQ9 zV}%3<njfPAHanLxD<`w3*efWhA3Fss5X=)aMfkNx3_D6`v?<rCL+qgf6vqhM7O17w zdot_nIHmLxC=QC^8CUV;`RuV%?8G3&IVg&sBw#s0UwIlzD7(r|QDWZ_YC{9b0>Rt8 zv9g+l&cIM-cTsA;-f+NyX3>KNLW}XSG$<Ml4m8VD!0wZk(@RUFb5<y=Z;NaV1stmc zZ%g*Z(&>|IjS~7vHbJ8BD+$(?sts-=vvo@9CshI#2sT``)8xalgVautD14e=$uxmT zo?fH#Q+d36ms!Djn%zx#$v&d#DFl@FP%&FXPp_>(L}{tiS424|ir-7XFS03u;rA-~ zetSPE*2z*kL!fp)+_kZ~!p>4czkVP{6h23=B$oL+clP4SPx$v=O{u?+UkE6}v8M{Q z=c+{!tKN==_2y7O=sd1PX1GeZ(FNR@!C~bdSr=?)1`jkvj7o;b2LiV%p!8@*I){W) zmY*e9^`brM$>GpUzo0eNs!cl*zumf{o*WL{Dwj3Zh1ZqJq3GJ-dsNmye7&1gcQU~p zt5j<x1l|{M_qrEncOEaHHyVi22Mgx$q&A}QyNdY(pezO1vOIO`3((mVlF42}-~61w zRx?EakPekVNT{)yg9~ws7AsInr`uZQ&9Ne7($eMl{1PkC7xxmQxm{9gDT+2qAs^T^ zf*@o31ifs+%JkLk!xjbXTYpj<2&Fb<DLhaP)kk5Ey{oAb1T_K$L`~-htLXxP(ZHgD z@Pe`$CHyE7I%h4@sPPDE8w@noT~+dRI%`mh(yOSwo@Y8iQYVpGVomx+wn%%;Md@?Q zpbX;m+P!0p;Y;PsT%THczJZGaaN@uuh|cAjlR3vM$|bHKjo+ZeT9ne+wK8vxU8GFX z*Ej@82O;Yw+v<j&sj2lsNu8Txmnf6;nb-zo+w`5UP@O#`XH_Ub=Gc9*%q7HpY-;Q> zedler7lk|-?0qdVDg(!huq%Xz<g7@~0I(mYubdR&DdDN9W0WTyCF~~%hPvK9oyhK| zgc1^FHV}$J*OOevP4^dRe76%eGV6C|*7F;yC$jgzbArtHItE^qphR7D+^L*eQt#Wo zXXE68U7PCw!^DI(GIwQ;y^d-V<4znhW3Q)_MrZxBE!i@Gd<^fiDsk~J0e!z5&n4}n zj7ijw6berP2zL4S@g5?m1}d^j{MvgyeeLa6cOHA!^{bCufA|3<ArICJ#fg$PNJiL? zIj}eSFrtij7dn<;*OKQ!hKQfGTxn$xf<v$8kaQ+q9GRRtJUMkRIWjp>NKR<#!DL~w zG@jH(MvDi_2M=mv<K_4{RR1Qbjix8Q)s`2RO|S<jl`s7q86v4F<y{fcsTr|5H-`^W zD1Va55nE-XJbRE*UX7HSd+>n0xm~k}yJv5q6!HOhgYVf}DTjvIygd2A-bP8CL)pok zV{fNi(in6EguR2lb^C(cheX&z1VhpI2tC4ilNP`9uE8FrWD@eraYzAr>T;Z@#fSJk zS`DXK=}di`dKZV*ka#aH|5jE2fxd<GF$-~Q)aUWhI8JoL#o;`T#yJ&;!;u6KzjB5B z6xH@T)K)66chYB47x8+&REV>8(RXSRRmR>;-}p==Mp3&h&VYRnfzTSZ*fK4>E<})@ z%x6DMS$yd7<6a^JmLk}cM71=mPz#3@8PPV(udCleI4Ykr1!L$ks9_4N)~r082&8P8 zwuu)$Y$yb6&awAO$}!Yy?0vqJFC)vL{Qa^(9z171BfrJXW}JP1zLCJv*)6Mzt1v!D zDZDY_WSbI~S#gEm&=OC#OqS-dpFXD5YAO>4$IwM|stcrFNZ*ag0Y-$G#xb-sZm749 zmeDtf4d?uzXn$5xL%qU2MBn)IhxuD+u`2GmF>06$aQYccC#{$&6=HMj!vsj;g$SoS zaW+pugzO`f%q;?E*meNSu}27k+AGu9M=7OqQj&Rd?B^(x%y^lEv$qZL!YTV0<#B7G ztFkuK9Q%0!qrv7xLbG3>q%4vy$03T)l)<eP&5x07#^tsrFtO$e`#52z$tX{=DEmeF zN)EO&QX%u{h>lP3PzhkBGmj7relJkkegx+n`z47-2>B=IE43qz8<Ef#+i~_uN+Juv zVB74M=?n3Z6PmJtQq|JjNSr+?A+17<U8OH$fSeJ-#Re6Fg@QeBMGHnTh7A8rp{q!N zY(n@yMP+HF%x3@*%*;MbiCkoH>=G)4Yk)CZk>u;-6J}<mO8RDIL$j1bjF;wGCEh*g zxcWe8rgaQGp;hMCXQ(zYbMv5b_A8V?s)S}I_E~&uou}En*xo0(4KD9|tI@=@{Wa}2 z_BrGp{T<8-fBEb9MJFfbW;mDehvEN{d@a3<z|G{AMmHx+7w|s85m;SVD5<q14ghX8 zrY*gBBsNF4ZSYuaS4m&MX$dvQ>*W0}t_KhqX<mC63fdQB$tq+M1|h_3MneT6c*0aK zd2c@{9SJSPYAFmUBtp^DU#sFwbQlsw$8d5O|BXgN2PBy3H9Tt)h8C%nA|ge<fCr_* z&><xx%;>c3TIjMo*RWygclsnbQXU%}Jv?4cs@m9Ca$;nBG&xl+O(qXbj*O|AS{y%A zICLY_!Um(m^kImMq?1ZItzd3h_1dK-y~}gU>Zhw-^hRy_mJv`_FC}4S-Lm?ds#UpV zmE&khi`}}mW2z*pIg;i_IhVOK7|qmH$!($xGQYRg*Hn3GVzO8sNlqO+bP(!m@=#JO z9@3JBi(_L4504c}ns#_keTBBe_SDy&`U*2ZBbmCN1L|u_IGMt*sI9}s3L}Trk?}*x z;vw~La-ujfnk*br)#TJz`CxHue6%oisJy4c_H<a-#q^#D_IKL^i_$d1enc2$b|dPE zc5d_Y$Bt#zvSF&`_xjOp<}eob@>ccqB}#cYf;~G^>$M}s>`3bH@PYIJ{%I<bnab6K zd}am5b{1AnhH1;@ebpvj`qi*KWkut*aZ|R0fX&m0Z3{!$eU)Sp3kmL7<OX|ab<8O` zwz{%{0C$A&hau*IrZvf7c`-sB9a~*pTnNP)*J_6QV`kek`ykGhBX|OqKV?r29kb~w zJ;>UoqqJ>}xKIpaT13{Xr&c#Y4Pl32(^DfOBhg9OdgerCJ+mH0#Oy0_J1L`m4f`r& z=v?zcbd;W6JGnl8oWhtlGRID@XY%WrSDwynWH-Xl9*v`wkJHl#5XeJitc2><W&OS? z_Vdz{sSzcytQM;cOE)V=lm*-#QB#nhtZpbdyy2Z69nT*eQs$w+wR^O}V%16?9GOgw zrbZ`~#3CISpc_0dXv#^gctIah?iP-X^ynBcZ>VLJRh<HnbjsR%_7pnf#A+D+cWi%E zacu}TQzB5D5Qz1A^9UylIk`ka#Cm3V72*FBn;V8T&UlKFn6=gQP~v%TbZq=^M1=6s zn#UQqQ>(|rFy>?iO^859#L=@n#f63;BN`e+P*GSK>S__!Vqd_k0N9s|lAy4164|6= zM_a9}uVz<q20Kg#kycJaFGk518T}Q8o^`~oVh4OQHI_OU2~9BKaYGIsWMiQ=O)lSg z$EC4DM{ekTL)(l>3sl2O1SnxRM2JlURz!$!W6dTH*GfmAgj@?T6X8cJ<o@3-J24W{ zi*@X(KAX1vL66>~0P0Y~;m(?M<ZiXr!t+)3rPG>r5b-)wh?EoZQ*DaB)3%s9GjykT zH4(in0ZAXqQL(9NGFik@if=OJOy-Hd2l$WpED@MyEnlP{lrlYt<{%S5-JrPn@FHDp zgZMU)De3M8EvkNqJE+8pi!LChfVxg>Wd0)x3?ArIvs&uJUDG%FmjX~{Dcs(RxIjEZ zWy+e|l;GWoUb*U}9=U=}#87)1(J_&BQey`R=Z%)u((-hBkECi+b_@kb;VA%_KI(M2 zS!r1%eXEi8KsY5$J|_fb3+*oPiod%Y>Y|XO6unf?O{WER6q<lBT2;+yLq`t3Lo=_@ za|TYAbO4mJLJQAiT-0ik)^QgP5U41V-5psFcizja4us7bA`yIZM3k_2649R+)^bV; z4C1$Bfr(IXdNzPb^lqB?B|%*f9i-v>hr=azQA9)+@f?E0+EK>T%fXqTH?SaOoYxD! zNJV(B%o2aaZ`sr)(`n2yy8lnYxk;vlIi5<ASsf%d^vzb)H-~h-%s3-Hh~Id8N_=SO z1r>)`{1IdLYOIVmE*vColE93-xoskPGEa<lU^-~yy;Rg8%m|l|q;QBUcWzooBAMMv zg}m)-3N@P`nm92O4IwnPaNYT47@LzbB@!}tK;?7HLZPWCuNLW|`Y_CUHn_`OO~3&N zJa7<F5TbXNyD5`5x`yF$bnbFa5wxOxj4li@5xdK6iYWFm3^guq_t&qxob#}Pmyg15 z&@s`YbC+{^@JbJ!rVABUOXYE<qLZ?l;x6ZuwwicDx}@Rkgov=i{hqL7F|&qZXCzaJ zpo>n9VEPUh@A}+zmsidFdH&W@82(2$or8?#_Smz4hGwXE+ejH<;-p(Kl!B&P)*=}a z;shjVxlrS>Gp0bCFc}?5jU7ylO&m;(9tzqh6p+)?K|WHMU&hb0qp<>7EP%_})Cdqx zj2xbxoSf9AixX4Yv{ndWlPJ`&{O*Z9n20DtJ17#GA8QLUKyK2W7PL0o&eKzU;g$jc zY?Wt)20QM=v^t)(#bJt4sJSn=_rjd+u!$jmTbO=|Zcj_Ph{Q$rVQ7hJPfJpQ^P6GF zxJjZbo`2<Tw=h&iBDpTtUl<w&(NMb^N;W}Zr8lyjHc1E5EgjEEhha{nJ8d>S<TBgB zen=R4BHw8fPhG<M5$=G@E?u^f$h%E4d}LwIwT!`VNR1|O5e42+eK~os@v+`a(OaUa z5&S!t8W~NEjHM={+0NWDH>)Y(WDe8mw11PY>ZvRou?wsB*e|G%tAEyZQUbuVuv^N= zNhs139JH7DTXvFkv)IK>XHO)jYz$F37kN|pdye)?FJT)j?oJWZ5mKy6Q!T4n!-YBs z4-!1M8MId$c=tFg(bP*v`MpY7X&u`<xU7M9)9As-ytkaebzDhOg%6zWU<yNPbc>8O zIbw4v3^kFhH8?TkXV)9yRy`5(rNwG_+H$Ff()Hv_h(=+O`ndsh>AMCCpiHcKx>sdU zu3@N~?LE6N;`Urqr{a0s=cYQvQuEobPV>($bt=etmZ;PGvqzogpGE34|14FfQL0&3 zn_45RiA^VO0;Y)FEha^vNEki8%e4tzRwPdjndB~rhJ1uTP~cXW21FM%zF9-u0&Ee@ z!UN$qcAZTach+7wC+;9M)2#--#junXE7(qf+Y9IP<547Ia4(!wUcMw2%rcm1FP!s; zWW`=M=UzCcS=kHc+zaP4aZ#jDlY8NuyR+1JsPtYqXBY!{FLcJac9e(j?1j$I4Xk^i zGkuSM3U_mG@I{pVkXyU&7-dT^#%Ocl7H=Ja3j1{L?(hDKY|98l;AT#%+zJ&Q5Z!(e z=x`3_gz*(cO9@%Rx0Z@qA8^#rx5BW%xrttWNKjP4Fz&Y)R>mgqKmLx7;xEz;P8~jc z_+T`LX_&ed{>*9==Y5HQ8*&-bVW~*`J=iA*({nc|M66{MZ;~jD;x>9mln&!O?r1ck zMEk2@7)Tqd1HTvJ8xYYk$+6GlLi;zdFW~n&`yzgyr`Kf8^K0(^>PPnN`<v_db;H-( z7xYr7IBmI$yurg(7goDp#VH-0nDT99m=!`1mtox6YsU93>Fxbq!rmR@dv}b7(VEfh zGkzUhGTt#c2u_E-f3T$0s&#r3F4P*xFCgmj<pA47EK#p?U#b#idnn>EvZjzBM31yp zi|O-b`aD0Lkvb3bzPG}N_PNRwO*4&4o3utrWhs0av>fVkiVa>HN{NNJABB;!m|lwu zGr$AdzdPqD-l3}JYidEGU3}c8qvEloTS|;+ZP!ADHNvN3(c5Fq2?U4Lsu9`zIBtmt z9*Y#nj!_-%o*chneW0uNqLeA|)Lh>E%v_jGjcny)zr`4ahEC?~PPp68J{}EaiwgyC zQ+o=}*R*b&EkajzvPz^m?^$-WLaY`9R4*@2TMr}LMnseN2N3lZ;9wG;zWUXtuRe04 z^a;x31*#>@#EWB?Ji5?^rSke)zHsgS*L9)00WQ*1*zK4IOW!k}eBU$ofB5<n@7j6v zeNj>=UfAox7(`}JdYH8-e0A!LkB!}_4Dp(0m|C6JKNVWSZ|kjBXqRyKr>3RwN>ya* zbqIEmRr#H5VTe=}Eck0mL)%g?n!9>6OfT^nGOXEfk5(9KZY%hsoRIHvMnV;?aHD5Q zL)os>e|5Fl<$0MLEl&A+ULuuxoUf{xdAv1^5a}>|>^BX(`s~)r&*Bl&mjy6aXy;cu z8h)4Hd_qVE7K)NRO`Q0*Pbh^w)@?st86{Qn-kIXF<RL?c9`4@DLjyIj9YsOcd4B0! z7`ckf8uSo%1J6K3P7*zP8~W6>Y!^r3V|s+qt`a9L#KUx&bSFEf2h|1~isJO32uHfn zaCVzQGd(h?rbo+@?R$Fg)?@$o(;_}=>E;(5kqpDL$T;G}4-CYK0M)!Z`$e|D64I$K zcDR7I=toO<+HQ1mvNT!5jjnk2Zmd`u8`Gu^MRTLMBr@Eqv$v3|xY9MOP_^5PcQ_*L zY6Lr6&_cc68(Fl2Y+PN%J(P5YI?S+(m@Tkz!%)#{DI9Jn+Hb+<>9O!I6baSu>m%JI zK^1)qcBNj!4W?lTiI6o|`nE#Z=3@~(;bOK5{LoAoJ~%#=>sKGS{_q1zLYmFdY?EKC zhLc=L1)cxl-jI~<VYv>omwk!vg@2jvg+E5y;BR#H!ryuu_QD^)uN&SAr$u!bMt81c zb|>uIs>EJHxFd4o2P2ZR3a-JS`^3XEUsVqmaUobCdGPRLF*z|lHI<y2m?$Mjr=|{< zrw$b-)rmuq%p}->u<{qHW;N6W6*3?xB|m(vB9n0cLA`)G5yM$|(P^_5F5n5%zc(b_ zcz8TiG*TJ&aK56%ol=p=PDmRrlDfm%VmnWK<f$*cIT8|>wppcJCsH(cV=a^z`0s!2 zPTh6T5mMho#1NbY#&(%$lK(BN>WhRF8kb>3WCI2Y>wc54WAYT89XeKk$jfgsy%jEC z`bM+|Zm-;ZZ1nYq9^Lu)yCdnDu`u;N{e?GOf9&JJ=GytG?oE!Mz6nYX<Bq}Gnc+6; zBlA@8xf&x2&r*akDxxKX$8dz{%u*pmR$-n7K?;wc;GVFNF45}fIrca=RiEId>R0f) H)k^(;xiR@C literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-33-13.e9cae406-ac2c-452f-a3b0-410ed9627864 b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-33-13.e9cae406-ac2c-452f-a3b0-410ed9627864 new file mode 100644 index 0000000000000000000000000000000000000000..13e5695fac49b5afa8aebfa947360580bb2bc76b GIT binary patch literal 93733 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 aP;gIJpUZuWuP{^fF=nbhj^FKe=Klkx^~Hq% literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-35-13.70c4b5df-9b5b-4a0e-879b-30a4c10a50b3 b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-35-13.70c4b5df-9b5b-4a0e-879b-30a4c10a50b3 new file mode 100644 index 0000000000000000000000000000000000000000..7b630b962cc25471ffd616ebdf221dd0c9c11a2c GIT binary patch literal 85859 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-35-32.d61a4243-a147-4607-952c-33ff8a7c3c1b b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-35-32.d61a4243-a147-4607-952c-33ff8a7c3c1b new file mode 100644 index 0000000000000000000000000000000000000000..fd1d35215bb981ffb2d04b5ff8f085b5a539ff5e GIT binary patch literal 93670 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�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 Yq)W6qdX9aOo2p;prs|jRyVXklf0)pqIsgCw literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-35-53.9396c4f0-dcb1-4bb5-86e0-651b9c426f64 b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-35-53.9396c4f0-dcb1-4bb5-86e0-651b9c426f64 new file mode 100644 index 0000000000000000000000000000000000000000..767263eb8a9210cc345ff774016d4e11c097f775 GIT binary patch literal 93763 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 X!@i^E*yG$(eS({+U%>BHEA{^Y6P~$D literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-36-10.4b60b067-1e28-4f1f-89cb-c85be3ad678e b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-36-10.4b60b067-1e28-4f1f-89cb-c85be3ad678e new file mode 100644 index 0000000000000000000000000000000000000000..63705cd2b240838970ae08b3efeffa34a1c7668e GIT binary patch literal 93763 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 UxexmiH&q|!rs@;;-RWfhKUl@kumAu6 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-45-21.a77fcd2f-d2d4-4d68-ab0c-5b9ac8334211 b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-45-21.a77fcd2f-d2d4-4d68-ab0c-5b9ac8334211 new file mode 100644 index 0000000000000000000000000000000000000000..0157f7ec93d6135e0309050181acb5637655ee2e GIT binary patch literal 62701 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 N+*JK8em5Gi{|jYq9IgNW literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-47-24.5c391f77-5c16-44ef-8ef1-cccaf2d7e509 b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-47-24.5c391f77-5c16-44ef-8ef1-cccaf2d7e509 new file mode 100644 index 0000000000000000000000000000000000000000..670b089f37cc7848b57f885ed4ded97b70274289 GIT binary patch literal 55382 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-49-26.d3b60944-aa93-47c6-912e-c41ac302479e b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-49-26.d3b60944-aa93-47c6-912e-c41ac302479e new file mode 100644 index 0000000000000000000000000000000000000000..6af75ec9531b6a7c7ddf294be292529e30acc76e GIT binary patch literal 62831 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-49-53.b975ddf0-d822-4e87-8b62-0cf6f40e56e3 b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-49-53.b975ddf0-d822-4e87-8b62-0cf6f40e56e3 new file mode 100644 index 0000000000000000000000000000000000000000..574a30651a3c842214e9433aac4c8b5c463e4506 GIT binary patch literal 62575 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 Zxa6$M%|z^1xvBbnZmRwOziYMF{{v;?_6Ps~ literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-50-18.41b82968-5b82-4c33-8b97-5f0e8e543e30 b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-50-18.41b82968-5b82-4c33-8b97-5f0e8e543e30 new file mode 100644 index 0000000000000000000000000000000000000000..0b7590de80d5f02d726f90aeb3082508de7f110b GIT binary patch literal 62575 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 X>v1y?`&DkLexIAFKfv!sBl7<MHVE{! literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-51-00.b0142219-1bc4-417e-aa09-7995210816dd b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-51-00.b0142219-1bc4-417e-aa09-7995210816dd new file mode 100644 index 0000000000000000000000000000000000000000..76b6f72053af07235b89e37f42b0bef99f467af0 GIT binary patch literal 44404 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-51-12.f46779db-4627-4bc1-bd17-988a79ce4bc8 b/web2py/applications/SP/errors/127.0.0.1.2018-10-24.20-51-12.f46779db-4627-4bc1-bd17-988a79ce4bc8 new file mode 100644 index 0000000000000000000000000000000000000000..f9ee7746a60466e299aa16b9981bc93047155596 GIT binary patch literal 62497 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 Qrt0^&srr5VTdybnA2k%?Hvj+t literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/languages/ar.py b/web2py/applications/SP/languages/ar.py new file mode 100644 index 0000000..dce4610 --- /dev/null +++ b/web2py/applications/SP/languages/ar.py @@ -0,0 +1,215 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'ar', +'!langname!': 'Arabic', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN', +'%s %%(shop)': '%s %%(shop)', +'%s %%(shop[0])': '%s %%(shop[0])', +'%s %%{quark[0]}': '%s %%{quark[0]}', +'%s %%{row} deleted': '%s %%{row} deleted', +'%s %%{row} updated': '%s %%{row} updated', +'%s %%{shop[0]}': '%s %%{shop[0]}', +'%s %%{shop}': '%s %%{shop}', +'%s selected': '%s selected', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'@markmin\x01**Hello World**': '**مرحباً بالعالم**', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'نبذة', +'Access Control': 'متحكمات الوصول', +'admin': 'admin', +'Administrative Interface': 'واجهة التحكم', +'Ajax Recipes': 'وصفات أجاكس', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'appadmin is disabled because insecure channel': 'appadmin is disabled because insecure channel', +'Are you sure you want to delete this object?': 'هل أنت متأكد بحذف هذا الكائن ؟', +'Available Databases and Tables': 'Available Databases and Tables', +'Buy this book': 'أشتري هذا الكتاب', +"Buy web2py's book": "Buy web2py's book", +'cache': 'cache', +'Cache': 'Cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'Cannot be empty': 'لا يمكن بأن يكون خالي', +'Check to delete': 'أختر للحذف', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Client IP': 'IP المستخدم', +'Community': 'المجتمع', +'Components and Plugins': 'العناصر والإضافات', +'Config.ini': 'Config.ini', +'Controller': 'متحكم', +'Copyright': 'الحقوق', +'Created By': 'أنشئ بواسطة', +'Created On': 'أنشئ في', +'Current request': 'Current request', +'Current response': 'Current response', +'Current session': 'Current session', +'customize me!': 'التخصيص', +'data uploaded': 'data uploaded', +'Database': 'قاعدة البيانات', +'Database %s select': 'Database %s select', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'db': 'db', +'DB Model': 'نموذج قاعدة البيانات', +'Delete:': 'Delete:', +'Demo': 'تجربة', +'Deployment Recipes': 'الوصفات المنشورة', +'Description': 'الوصف', +'design': 'design', +'Design': 'Design', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'المستندات', +"Don't know what to do?": 'لا تعلم ماذا ستفعل ؟', +'done!': 'done!', +'Download': 'تحميل', +'E-mail': 'البريد الإلكتروني', +'Edit current record': 'Edit current record', +'Email and SMS': 'البريد الإلكتروني والرسالة النصية', +'enter an integer between %(min)g and %(max)g': 'أدخل عدد صحيح بين %(min)g و %(man)g', +'enter date and time as %(format)s': 'أدخل التاريخ والوقت كالنمط %(format)', +'Errors': 'الأخطاء', +'export as csv file': 'export as csv file', +'FAQ': 'الأسئلة الشائعة', +'First name': 'الأسم الأول', +'Forms and Validators': 'الإستمارات والمدققات', +'Free Applications': 'تطبيقات مجانية', +'Graph Model': 'Graph Model', +'Group %(group_id)s created': 'المجموعة %(group_id)s قد أنشئت', +'Group ID': 'هوية المجموعة', +'Group uniquely assigned to user %(id)s': 'المجموعة مخصصة للمستخدم %(id)s', +'Groups': 'مجموعات', +'Hello World': 'مرحباً بالعالم', +'Hello World ## comment': ' مرحباً بالعالم', +'Hello World## comment': 'مرحباً بالعالم', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'الرئيسية', +'How did you get here?': 'كيف أستطعت الوصول إلى هنا ؟', +'import': 'import', +'Import/Export': 'Import/Export', +'Internal State': 'Internal State', +'Introduction': 'مقدمة', +'Invalid email': 'بريد إلكتروني غير صالح', +'Invalid Query': 'Invalid Query', +'invalid request': 'invalid request', +'Is Active': 'نشط', +'Key': 'Key', +'Last name': 'أسم العائلة', +'Layout': 'النسق', +'Layout Plugins': 'نسّق الإضافات', +'Layouts': 'لأنساق', +'Live Chat': 'المحادثة الحيّة', +'Log In': 'Log In', +'Logged in': 'تم تسجيل الدخول', +'Logged out': 'تم تسجيل الخروج', +'Login': 'تسجيل الدخول', +'Logout': 'تسجيل الخروج', +'Lost Password': 'فقدت كلمة المرور', +'Lost password?': 'هل فقدت كلمة المرور ؟', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Manage Cache', +'Memberships': 'Memberships', +'Menu Model': 'قالب القوائم', +'Modified By': 'عًدلت بواسطة', +'Modified On': 'عُدلت في', +'My Sites': 'موقعي', +'Name': 'الأسم', +'New Record': 'New Record', +'new record inserted': 'new record inserted', +'next %s rows': 'next %s rows', +'No databases in this application': 'No databases in this application', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Object or table name': 'أسم الكائن أو الجدول', +'Online book': 'Online book', +'Online examples': 'أمثلة على الأنترنت', +'or import from csv file': 'or import from csv file', +'Origin': 'أصل', +'Other Plugins': 'إضافات أخرى', +'Other Recipes': 'وصفات أخرى', +'Overview': 'نظرة عامة', +'Password': 'كلمة المرور', +"Password fields don't match": 'حقول كلمة المرور لا تتطابق', +'Permission': 'Permission', +'Permissions': 'Permissions', +'please input your password again': 'الرجاء إعادة إدخال كلمة المرور', +'Plugins': 'الإضافات', +'Powered by': 'مدعوم بواسطة', +'Preface': 'المدخل', +'previous %s rows': 'previous %s rows', +'Profile': 'الملف الشخصي', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'بايثون', +'Query:': 'Query:', +'Quick Examples': 'أمثلة سريعة', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'وصفات', +'Record': 'Record', +'record does not exist': 'record does not exist', +'Record ID': 'هوية السجل ', +'Record id': 'Record id', +'Register': 'التسجيل', +'Registration identifier': 'مُعرف التسجيل', +'Registration key': 'رمز التسجيل', +'Registration successful': 'تم التسجيل بنجاح', +'Remember me (for 30 days)': 'تذكرني ( إلى 30 يوم)', +'Reset Password key': 'إعادة ظبط مفتاح كلمة المرور', +'Role': 'دور', +'Roles': 'Roles', +'Rows in Table': 'Rows in Table', +'Rows selected': 'Rows selected', +'Save model as...': 'Save model as...', +'Semantic': 'دليل لفظي', +'Services': 'خدمات', +'Sign Up': 'Sign Up', +'Size of cache:': 'Size of cache:', +'state': 'state', +'Statistics': 'Statistics', +'Stylesheet': 'أسلوب النمط', +'submit': 'submit', +'Support': 'الدعم', +'Table': 'Table', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.', +'The Core': 'النواة', +'The output of the file is a dictionary that was rendered by the view %s': 'نتاج هذا الملف هو قاموس قًدم بواسطة العارض %s', +'The Views': 'المشاهدات', +'This App': 'هذا التطبيق', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'البصمة الزمنية', +'Traceback': 'Traceback', +'Twitter': 'تويتر', +'unable to parse csv file': 'unable to parse csv file', +'Update:': 'Update:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.', +'User': 'User', +'User %(id)s Logged-in': 'المستخدم %(id)s قد سجل دخوله', +'User %(id)s Logged-out': 'المستخدم %(id)s قد سجل خروجه', +'User %(id)s Registered': 'المستخدم %(id)s مسجل', +'User ID': 'هوية المستخدم', +'Users': 'Users', +'value already in database or empty': 'القيمة موجودة مسبقاً أو فارغة', +'Verify Password': 'تأكيد كلمة المرور', +'Videos': 'الفيديوهات', +'View': 'العرض', +'Welcome': 'مرحباً', +'Welcome to web2py!': 'مرحباً بكم في ويب2 باي !', +'Which called the function %s located in the file %s': 'الدالة المسماة %s موجودة في ملف %s', +'Working...': 'Working...', +'You are successfully running web2py': 'أستطعت تثبيت web2py بنجاح !', +'You can modify this application and adapt it to your needs': 'تستطيع تعديل هذا التطبيق لما يناسب إحتياجك', +'You visited the url %s': ' ملقد زرت الرابط %s', +} diff --git a/web2py/applications/SP/languages/ca.py b/web2py/applications/SP/languages/ca.py new file mode 100644 index 0000000..ef6ec70 --- /dev/null +++ b/web2py/applications/SP/languages/ca.py @@ -0,0 +1,512 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'ca', +'!langname!': 'Català', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"actualizi" és una expressió opcional com "camp1=\'nou_valor\'". No es poden actualitzar o eliminar resultats de un JOIN', +'%(nrows)s records found': '%(nrows)s registres trobats', +'%s %%{position}': '%s %%{posició}', +'%s %%{row} deleted': '%s %%{fila} %%{eliminada}', +'%s %%{row} updated': '%s %%{fila} %%{actualitzada}', +'%s selected': '%s %%{seleccionat}', +'%Y-%m-%d': '%d/%m/%Y', +'%Y-%m-%d %H:%M:%S': '%d/%m/%Y %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'(something like "it-it")': '(similar a "això-això")', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'@markmin\x01An error occured, please [[reload %s]] the page': 'Hi ha hagut un error, si us plau [[recarregui %s]] la pàgina', +'@markmin\x01Number of entries: **%s**': "Nombre d'entrades: **%s**", +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'A new version of web2py is available': 'Hi ha una nova versió de wep2py disponible', +'A new version of web2py is available: %s': 'Hi ha una nova versió de wep2py disponible: %s', +'About': 'Sobre', +'about': 'sobre', +'About application': "Sobre l'aplicació", +'Access Control': "Control d'Accés", +'Add': 'Afegir', +'Add Record': 'Afegeix registre', +'additional code for your application': '`codi addicional per a la seva aplicació', +'admin': 'admin', +'admin disabled because no admin password': 'admin inhabilitat per falta de contrasenya', +'admin disabled because not supported on google app engine': 'admin inhabilitat, no és suportat en GAE', +'admin disabled because unable to access password file': 'admin inhabilitat, impossible accedir al fitxer con la contrasenya', +'Admin is disabled because insecure channel': 'Admin inhabilitat, el canal no és segur', +'Admin is disabled because unsecure channel': 'Admin inhabilitat, el canal no és segur', +'Administrative interface': 'Interfície administrativa', +'administrative interface': 'interfície administrativa', +'Administrative Interface': 'Interfície Administrativa', +'Administrator Password:': 'Contrasenya del Administrador:', +'Ajax Recipes': 'Receptes AJAX', +'An error occured, please %s the page': 'Hi ha hagut un error, per favor %s la pàgina', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'And': 'I', +'and rename it (required):': 'i renombri-la (requerit):', +'and rename it:': " i renombri'l:", +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'admin inhabilitat, el canal no és segur', +'application "%s" uninstalled': 'aplicació "%s" desinstal·lada', +'application compiled': 'aplicació compilada', +'application is compiled and cannot be designed': 'la aplicació està compilada i no pot ser modificada', +'Apply changes': 'Aplicar canvis', +'Appointment': 'Nomenament', +'Are you sure you want to delete file "%s"?': 'Està segur que vol eliminar el arxiu "%s"?', +'Are you sure you want to delete this object?': 'Està segur que vol esborrar aquest objecte?', +'Are you sure you want to uninstall application "%s"': '¿Està segur que vol desinstalar la aplicació "%s"', +'Are you sure you want to uninstall application "%s"?': '¿Està segur que vol desinstalar la aplicació "%s"?', +'at': 'a', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATENCIÓ: Inici de sessió requereix una connexió segura (HTTPS) o localhost.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATENCION: NO EJECUTE VARIAS PRUEBAS SIMULTANEAMENTE, NO SON THREAD SAFE.', +'ATTENTION: you cannot edit the running application!': 'ATENCIO: no pot modificar la aplicació que està ejecutant-se!', +'Authentication': 'Autenticació', +'Authentication failed at client DB!': '¡La autenticació ha fallat en la BDD client!', +'Authentication failed at main DB!': '¡La autenticació ha fallat en la BDD principal!', +'Available Databases and Tables': 'Bases de dades i taules disponibles', +'Back': 'Endarrera', +'Buy this book': 'Compra aquest lllibre', +"Buy web2py's book": "Buy web2py's book", +'Cache': 'Caché', +'cache': 'caché', +'Cache Cleared': 'Caché Netejada', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Claus de la Caché', +'cache, errors and sessions cleaned': 'caché, errors i sessions eliminats', +'Cannot be empty': 'No pot estar buit', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'No se pot compilar: hi ha errors en la seva aplicació. Depuri, corregeixi errors i torni a intentar-ho.', +'cannot upload file "%(filename)s"': 'no és possible pujar fitxer "%(filename)s"', +'Change Password': 'Canviï la Contrasenya', +'Change password': 'Canviï la contrasenya', +'change password': 'canviï la contrasenya', +'Changelog': 'Changelog', +'check all': 'marcar tots', +'Check to delete': 'Marqui per a eliminar', +'choose one': 'escolliu un', +'clean': 'neteja', +'Clear': 'Netejar', +'Clear CACHE?': 'Netejar Memòrica Cau?', +'Clear DISK': 'Netejar DISC', +'Clear RAM': 'Netejar RAM', +'Click on the link %(link)s to reset your password': "Cliqui en l'enllaç %(link)s per a reiniciar la seva contrasenya", +'click to check for upgrades': 'feu clic per buscar actualitzacions', +'client': 'cliente', +'Client IP': 'IP del Client', +'Close': 'Tancar', +'Comma-separated export including columns not shown; fields from other tables are exported as raw values for faster export': 'Comma-separated export including columns not shown; fields from other tables are exported as raw values for faster export', +'Comma-separated export of visible columns. Fields from other tables are exported as they appear on-screen but this may be slow for many rows': 'Comma-separated export of visible columns. Fields from other tables are exported as they appear on-screen but this may be slow for many rows', +'Community': 'Comunitat', +'compile': 'compilar', +'compiled application removed': 'aplicació compilada eliminada', +'Components and Plugins': 'Components i Plugins', +'Config.ini': 'Config.ini', +'contains': 'conté', +'Controller': 'Controlador', +'Controllers': 'Controladors', +'controllers': 'controladors', +'Copyright': 'Copyright', +'Correo electrónico invàlid': 'Correu electrònic invàlid', +'create file with filename:': 'crear el fitxer amb el nom:', +'Create new application': 'Crear una nova aplicació', +'create new application:': 'crear una nova aplicació:', +'Create New Page': 'Crear Pàgina Nova', +'Create Page from Slug': 'Create Page from Slug', +'Created By': 'Creat Per', +'Created On': 'Creat a', +'CSV': 'CSV', +'CSV (hidden cols)': 'CSV (columnas ocultes)', +'Current request': 'Sol·licitud en curs', +'Current response': 'Resposta en curs', +'Current session': 'Sessió en curs', +'currently saved or': 'actualment guardat o', +'customize me!': "¡Adapta'm!", +'data uploaded': 'dades pujades', +'Database': 'Base de dades', +'Database %s select': 'selecció a base de dades %s', +'database administration': 'administració de base de dades', +'Database Administration (appadmin)': 'Administració de Base de Dades (appadmin)', +'Date and Time': 'Data i Hora', +'DB': 'BDD', +'db': 'bdd', +'DB Model': 'Model BDD', +'defines tables': 'defineix taules', +'Delete': 'Eliminar', +'delete': 'eliminar', +'delete all checked': 'eliminar marcats', +'Delete:': 'Eliminar:', +'Demo': 'Demostració', +'Deploy on Google App Engine': 'Desplegament a Google App Engine', +'Deployment Recipes': 'Receptes de desplegament', +'Description': 'Descripció', +'design': 'diseny', +'DESIGN': 'DISENY', +'Design': 'Design', +'Design for': 'Diseny per a', +'detecting': 'detectant', +'DISK': 'DISC', +'Disk Cache Keys': 'Claus de Caché en Disc', +'Disk Cleared': 'Disc netejat', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentació', +"Don't know what to do?": 'No sap què fer?', +'done!': '¡fet!', +'Download': 'Descàrregues', +'E-mail': 'Correu electrònic', +'edit': 'editar', +'EDIT': 'EDITAR', +'Edit': 'Editar', +'Edit application': 'Editar aplicació', +'edit controller': 'editar controlador', +'Edit current record': 'Editar el registre actual', +'Edit Menu': 'Editar Menu', +'Edit Page': 'Editar Pàgina', +'Edit Page Media': 'Edit Page Media', +'Edit Profile': 'Editar Perfil', +'edit profile': 'editar perfil', +'Edit This App': 'Editi aquesta App', +'Editing file': 'Editant fitxer', +'Editing file "%s"': 'Editant fitxer "%s"', +'El fitxer ha de ser PDF': 'El fitxer ha de ser PDF', +'El fitxer ha de ser PDF o XML': 'El fitxer ha de ser PDF o XML', +'Email': 'Email', +'Email and SMS': 'Correu electrònic i SMS', +'Email sent': 'Correu electrònic enviat', +'End of impersonation': 'Fi de suplantació', +'enter a number between %(min)g and %(max)g': 'introdueixi un número entre %(min)g i %(max)g', +'Enter a valid email address': 'Entri una adreça email vàlida', +'enter a value': 'entri un valor', +'Enter a value': 'Entri un valor', +'Enter an integer between %(min)g and %(max)g': 'Entri un numero enter entre %(min)g i %(max)g', +'enter an integer between %(min)g and %(max)g': 'entri numero enter entre %(min)g i %(max)g', +'enter date and time as %(format)s': 'entri data i hora com %(format)s', +'Enter from %(min)g to %(max)g characters': 'Entri des de %(min)g a %(max)g caràcters', +'Enter valid filename': 'Entri nom de fitxer vàlid', +'Error logs for "%(app)s"': 'Bitàcora de errors a "%(app)s"', +'errors': 'errors', +'Errors': 'Errors', +'Errors in form, please check it out.': 'Hi ha errors en el formulari, per favor comprovi-ho.', +'export as csv file': 'exportar com fitxer CSV', +'Export:': 'Exportar:', +'exposes': 'exposa', +'extends': 'extén', +'failed to reload module': 'la recàrrega del mòdul ha fallat', +'FAQ': 'FAQ', +'file': 'fitxer', +'file "%(filename)s" created': 'fitxer "%(filename)s" creat', +'file "%(filename)s" deleted': 'fitxer "%(filename)s" eliminat', +'file "%(filename)s" uploaded': 'fitxer "%(filename)s" pujat', +'file "%(filename)s" was not deleted': 'fitxer "%(filename)s" no fou eliminat', +'file "%s" of %s restored': 'fitxer "%s" de %s restaurat', +'file ## download': 'file ', +'file changed on disk': 'fitxer modificat en el disco', +'file does not exist': 'fitxer no existeix', +'file saved on %(time)s': 'fitxer guardat a %(time)s', +'file saved on %s': 'fitxer guardat a %s', +'First name': 'Nom', +'Forgot username?': 'Ha oblidat el nom de usuari?', +'Forms and Validators': 'Formularis i validadors', +'Free Applications': 'Aplicacions Lliures', +'Functions with no doctests will result in [passed] tests.': 'Funcions sense doctests equivalen a pruebas [aceptades].', +'Graph Model': 'Graph Model', +'Group %(group_id)s created': 'Grupo %(group_id)s creat', +'Group ID': 'ID de Grup', +'Group uniquely assigned to user %(id)s': 'Grup assignat únicament al usuari %(id)s', +'Groups': 'Grups', +'Hello': 'Hola', +'Hello World': 'Hola Món', +'help': 'ajuda', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Inici', +'Hosted by': 'Hosted by', +'How did you get here?': 'Com has arribat aquí?', +'HTML': 'HTML', +'HTML export of visible columns': 'HTML export de columnes visibles', +'htmledit': 'htmledit', +'Impersonate': 'Suplantar', +'import': 'importar', +'Import/Export': 'Importar/Exportar', +'in': 'a', +'includes': 'inclou', +'Index': 'Índex', +'insert new': 'inserti nou', +'insert new %s': 'inserti nou %s', +'Installed applications': 'Aplicacions instalades', +'Insufficient privileges': 'Privilegis insuficients', +'internal error': 'error intern', +'Internal State': 'Estat Intern', +'Introduction': 'Introducció', +'Invalid action': 'Acció invàlida', +'Invalid email': 'Correo electrónico invàlid', +'invalid expression': 'expressió invàlida', +'Invalid login': 'Inici de sessió invàlida', +'invalid password': 'contrasenya invàlida', +'Invalid Query': 'Consulta invàlida', +'invalid request': 'sol·licitud invàlida', +'Invalid reset password': 'Reinici de contrasenya invàlid', +'invalid ticket': 'tiquet invàlid', +'Is Active': 'Està Actiu', +'Key': 'Clau', +'language file "%(filename)s" created/updated': 'fitxer de llenguatge "%(filename)s" creat/actualitzat', +'Language files (static strings) updated': 'Fitxers de llenguatge (cadenes estàtiques) actualitzats', +'languages': 'llenguatges', +'Languages': 'Llenguatges', +'languages updated': 'llenguatges actualitzats', +'Last name': 'Cognom', +'Last saved on:': 'Guardat a:', +'Layout': 'Diseny de pàgina', +'Layout Plugins': 'Plugins de disseny', +'Layouts': 'Dissenys de pàgines', +'License for': 'Llicència per a', +'Live Chat': 'Xat en viu', +'loading...': 'carregant...', +'Log In': 'Log In', +'Log Out': 'Log Out', +'Logged in': 'Sessió iniciada', +'Logged out': 'Sessió finalitzada', +'Login': 'Inici de sessió', +'login': 'inici de sessió', +'Login disabled by administrator': 'Inici de sessió inhabilitat pel administrador', +'Login to the Administrative Interface': 'Inici de sessió per a la Interfície Administrativa', +'logout': 'fi de sessió', +'Logout': 'Fi de sessió', +'Lost Password': 'Contrasenya perdida', +'Lost password?': 'Ha oblidat la contrasenya?', +'lost password?': '¿ha oblidat la contrasenya?', +'Main Menu': 'Menú principal', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Gestionar la Caché', +'Memberships': 'Memberships', +'Menu Model': 'Model "menu"', +'merge': 'combinar', +'Models': 'Models', +'models': 'models', +'Modified By': 'Modificat Per', +'Modified On': 'Modificat A', +'Modules': 'Mòduls', +'modules': 'mòduls', +'must be YYYY-MM-DD HH:MM:SS!': '¡debe ser DD/MM/YYYY HH:MM:SS!', +'must be YYYY-MM-DD!': '¡debe ser DD/MM/YYYY!', +'My Sites': 'Els Meus Llocs', +'Name': 'Nombre', +'New': 'Nuevo', +'New %(entity)s': 'Nou %(entity)s', +'new application "%s" created': 'nova aplicació "%s" creada', +'New password': 'Contrasenya nova', +'New Record': 'Registre nou', +'new record inserted': 'nou registre insertat', +'New Search': 'Cerca nova', +'next %s rows': 'següents %s files', +'next 100 rows': '100 files següents', +'NO': 'NO', +'No databases in this application': 'No hi ha bases de dades en esta aplicació', +'No records found': "No s'han trobat registres", +'Not authorized': 'No autoritzat', +'not in': 'no a', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Object or table name': 'Nom del objecte o taula', +'Old password': 'Contrasenya anterior', +'Online book': 'Online book', +'Online examples': 'Ejemples en línia', +'Or': 'O', +'or import from csv file': 'o importar desde fitxer CSV', +'or provide application url:': 'o proveeix URL de la aplicació:', +'Origin': 'Origen', +'Original/Translation': 'Original/Traducció', +'Other Plugins': 'Altres Plugins', +'Other Recipes': 'Altres Receptes', +'Overview': 'Resum', +'pack all': 'empaquetar tot', +'pack compiled': 'empaquetar compilats', +'Password': 'Contrasenya', +'Password changed': 'Contrasenya cambiada', +"Password fields don't match": 'Els camps de contrasenya no coincideixen', +'Password reset': 'Reinici de contrasenya', +'Peeking at file': 'Visualitzant fitxer', +'Permission': 'Permís', +'Permissions': 'Permisos', +'Phone': 'Telèfon', +'please input your password again': 'si us plau, entri un altre cop la seva contrasenya', +'Plugins': 'Plugins', +'Powered by': 'Aquest lloc utilitza', +'Preface': 'Prefaci', +'Presentar Factures': 'Presentar Factures', +'Presentar factures': 'Presentar factures', +'previous %s rows': '%s files prèvies', +'previous 100 rows': '100 files anteriors', +'Profile': 'Perfil', +'Profile updated': 'Perfil actualitzat', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query Not Supported: %s': 'Consulta No Suportada: %s', +'Query:': 'Consulta:', +'Quick Examples': 'Exemple Ràpids', +'RAM': 'RAM', +'RAM Cache Keys': 'Claus de la Caché en RAM', +'Ram Cleared': 'Ram Netjeda', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Receptes', +'Record': 'Registre', +'Record %(id)s created': 'Registre %(id)s creat', +'Record Created': 'Registre Creat', +'record does not exist': 'el registre no existe', +'Record ID': 'ID de Registre', +'Record id': 'Id de registre', +'Ref APB': 'Ref APB', +'register': "registri's", +'Register': "Registri's", +'Registration identifier': 'Identificador de Registre', +'Registration key': 'Clau de registre', +'Registration successful': 'Registre amb èxit', +'reload': 'recarregar', +'Remember me (for 30 days)': "Recordi'm (durant 30 dies)", +'remove compiled': 'eliminar compilades', +'Request reset password': 'Sol·licitud de restabliment de contrasenya', +'Reset password': 'Reiniciar contrasenya', +'Reset Password key': 'Restaurar Clau de la Contrasenya', +'Resolve Conflict file': 'Resolgui el Conflicte de fitxer', +'restore': 'restaurar', +'Retrieve username': 'Recuperar nom de usuari', +'revert': 'revertir', +'Role': 'Rol', +'Roles': 'Rols', +'Rows in Table': 'Files a la taula', +'Rows selected': 'Files seleccionades', +'save': 'guardar', +'Save model as...': 'Save model as...', +'Saved file hash:': 'Hash del fitxer guardat:', +'Search': 'Buscar', +'Search Pages': 'Search Pages', +'Semantic': 'Semàntica', +'Services': 'Serveis', +'session expired': 'sessió expirada', +'shell': 'terminal', +'Sign Up': 'Sign Up', +'site': 'lloc', +'Size of cache:': 'Mida de la Caché:', +'Slug': 'Slug', +'some files could not be removed': 'algunos archivos no pudieron ser removidos', +'Spreadsheet-optimised export of tab-separated content including hidden columns. May be slow': 'Spreadsheet-optimised export of tab-separated content including hidden columns. May be slow', +'Spreadsheet-optimised export of tab-separated content, visible columns only. May be slow.': 'Spreadsheet-optimised export of tab-separated content, visible columns only. May be slow.', +'start': 'inici', +'Start building a new search': 'Start building a new search', +'starts with': 'comença per', +'state': 'estat', +'static': 'estàtics', +'Static files': 'Fitxers estàtics', +'Statistics': 'Estadístiques', +'Stylesheet': "Fulla d'estil", +'Submit': 'Enviar', +'submit': 'enviar', +'Success!': 'Correcte!', +'Support': 'Suport', +'Sure you want to delete this object?': '¿Està segur que vol eliminar aquest objecte?', +'Table': 'taula', +'Table name': 'Nom de la taula', +'test': 'provar', +'Testing application': 'Provant aplicació', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "consulta" és una condición com "db.tabla1.campo1==\'valor\'". Algo com "db.tabla1.campo1==db.tabla2.campo2" resulta en un JOIN SQL.', +'the application logic, each URL path is mapped in one exposed function in the controller': 'la lògica de la aplicació, cada ruta URL es mapeja en una funció exposada en el controlador', +'The Core': 'El Nucli', +'the data representation, define database tables and sets': 'la representació de dades, defineix taules i conjunts de base de dades', +'The output of the file is a dictionary that was rendered by the view %s': 'El resultat de aquesta funció és un diccionari que és desplegat per la vista %s', +'the presentations layer, views are also known as templates': 'la capa de presentació, les vistes també són anomenades plantilles', +'The Views': 'Les Vistes', +'There are no controllers': 'No hi ha controladors', +'There are no models': 'No hi ha models', +'There are no modules': 'No hi ha mòduls', +'There are no static files': 'No hi ha fitxers estàtics', +'There are no translators, only default language is supported': 'No hi ha traductors, només el llenguatge per defecte és suportat', +'There are no views': 'No hi ha vistes', +'these files are served without processing, your images go here': 'aquests fitxers són servits sense processar, les seves imatges van aquí', +'This App': 'Aquesta Aplicació', +'This email already has an account': 'Aquest correu electrònic ja té un compte', +'This is a copy of the scaffolding application': 'Aquesta és una còpia de la aplicació de bastiment', +'This is the %(filename)s template': 'Aquesta és la plantilla %(filename)s', +'Ticket': 'Tiquet', +'Time in Cache (h:m:s)': 'Temps en Caché (h:m:s)', +'Timestamp': 'Marca de temps', +'Title': 'Títol', +'to previous version.': 'a la versió prèvia.', +'To emulate a breakpoint programatically, write:': 'Emular un punto de ruptura programàticament, escribir:', +'to use the debugger!': 'usar el depurador!', +'toggle breakpoint': 'alternar punt de ruptura', +'Toggle comment': 'Alternar comentari', +'Toggle Fullscreen': 'Alternar pantalla completa', +'too short': 'massa curt', +'Traceback': 'Traceback', +'translation strings for the application': 'cadenes de caracters de traducció per a la aplicació', +'try': 'intenti', +'try something like': 'intenti algo com', +'TSV (Excel compatible)': 'TSV (compatible Excel)', +'TSV (Excel compatible, hidden cols)': 'TSV (compatible Excel, columnes ocultes)', +'TSV (Spreadsheets)': 'TSV (Fulls de càlcul)', +'TSV (Spreadsheets, hidden cols)': 'TSV (Fulls de càlcul, columnes amagades)', +'Twitter': 'Twitter', +'Unable to check for upgrades': 'No és possible verificar la existencia de actualitzacions', +'unable to create application "%s"': 'no és possible crear la aplicació "%s"', +'unable to delete file "%(filename)s"': 'no és possible eliminar el fitxer "%(filename)s"', +'Unable to download': 'No és possible la descàrrega', +'Unable to download app': 'No és possible descarregar la aplicació', +'unable to parse csv file': 'no és possible analitzar el fitxer CSV', +'unable to uninstall "%s"': 'no és possible instalar "%s"', +'uncheck all': 'desmarcar tots', +'uninstall': 'desinstalar', +'unknown': 'desconocido', +'update': 'actualitzar', +'update all languages': 'actualitzar tots els llenguatges', +'Update:': 'Actualizi:', +'upload application:': 'pujar aplicació:', +'Upload existing application': 'Puji aquesta aplicació', +'upload file:': 'puji fitxer:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) para AND, (...)|(...) para OR, i ~(...) para NOT, para crear consultas més complexes.', +'User': 'Usuari', +'User %(id)s is impersonating %(other_id)s': 'El usuari %(id)s està suplantant %(other_id)s', +'User %(id)s Logged-in': 'El usuari %(id)s inicià la sessió', +'User %(id)s Logged-out': 'El usuari %(id)s finalitzà la sessió', +'User %(id)s Password changed': 'Contrasenya del usuari %(id)s canviada', +'User %(id)s Password reset': 'Contrasenya del usuari %(id)s reiniciada', +'User %(id)s Profile updated': 'Actualitzat el perfil del usuari %(id)s', +'User %(id)s Registered': 'Usuari %(id)s Registrat', +'User %(id)s Username retrieved': 'Se ha recuperat el nom de usuari del usuari %(id)s', +'User %(username)s Logged-in': 'El usuari %(username)s inicià la sessió', +"User '%(username)s' Logged-in": "El usuari '%(username)s' inicià la sessió", +"User '%(username)s' Logged-out": "El usuari '%(username)s' finalitzà la sessió", +'User Id': 'Id de Usuari', +'User ID': 'ID de Usuari', +'User Logged-out': 'El usuari finalitzà la sessió', +'Username': 'Nom de usuari', +'Username retrieve': 'Recuperar nom de usuari', +'Users': 'Usuaris', +'Value already in database or empty': 'El valor ya existeix en la base de dades o està buit', +'value already in database or empty': 'el valor ya existeix en la base de dades o està buit', +'value not allowed': 'valor no permès', +'Value not in database': 'El valor no està a la base de dades', +'value not in database': 'el valor no està a la base de dades', +'Verify Password': 'Verificar Contrasenya', +'Version': 'Versió', +'versioning': 'versions', +'Videos': 'Videos', +'View': 'Vista', +'view': 'vista', +'View %(entity)s': 'Veure %(entity)s', +'View Page': 'View Page', +'Views': 'Vistes', +'views': 'vistes', +'web2py is up to date': 'web2py està actualitzat', +'web2py Recent Tweets': 'Tweets Recents de web2py', +'Welcome': 'Benvingut', +'Welcome %s': 'Benvingut %s', +'Welcome to web2py': 'Benvingut a web2py', +'Welcome to web2py!': '¡Benvingut a web2py!', +'Which called the function %s located in the file %s': 'La qual va cridar la funció %s localitzada en el fitxer %s', +'Wiki Page': 'Wiki Page', +'Working...': 'Treballant ...', +'XML': 'XML', +'XML export of columns shown': 'XML export of columns shown', +'YES': 'SÍ', +'You are successfully running web2py': 'Vostè està executant web2py amb èxit', +'You can modify this application and adapt it to your needs': 'Vostè pot modificar aquesta aplicació i adaptar-la a les seves necessitats', +'You visited the url %s': 'Vostè va visitar la url %s', +'Your username is: %(username)s': 'El seu nom de usuari és: %(username)s', +} diff --git a/web2py/applications/SP/languages/cs.py b/web2py/applications/SP/languages/cs.py new file mode 100644 index 0000000..75add19 --- /dev/null +++ b/web2py/applications/SP/languages/cs.py @@ -0,0 +1,516 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'cs-cz', +'!langname!': 'čeština', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': 'Kolonka "Upravit" je nepovinný výraz, například "pole1=\'nováhodnota\'". Výsledky databázového JOINu nemůžete mazat ani upravovat.', +'"User Exception" debug mode. An error ticket could be issued!': '"User Exception" debug mode. An error ticket could be issued!', +'%%{Row} in Table': '%%{řádek} v tabulce', +'%%{Row} selected': 'označených %%{řádek}', +'%s %%{row} deleted': '%s smazaných %%{záznam}', +'%s %%{row} updated': '%s upravených %%{záznam}', +'%s selected': '%s označených', +'%Y-%m-%d': '%d.%m.%Y', +'%Y-%m-%d %H:%M:%S': '%d.%m.%Y %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'(requires internet access)': '(vyžaduje připojení k internetu)', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(například "cs-cs")', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(soubor **gluon/contrib/plural_rules/%s.py** nenalezen)', +'@markmin\x01Searching: **%s** %%{file}': 'Hledání: **%s** %%{soubor}', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'O programu', +'About application': 'O aplikaci', +'Access Control': 'Řízení přístupu', +'Add breakpoint': 'Přidat bod přerušení', +'Additional code for your application': 'Další kód pro Vaši aplikaci', +'admin': 'admin', +'Admin design page': 'Admin design page', +'Admin language': 'jazyk rozhraní', +'Administrative interface': 'pro administrátorské rozhraní klikněte sem', +'administrative interface': 'rozhraní pro správu', +'Administrative Interface': 'Administrátorské rozhraní', +'Administrator Password:': 'Administrátorské heslo:', +'Ajax Recipes': 'Recepty s ajaxem', +'An error occured, please %s the page': 'An error occured, please %s the page', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'and rename it:': 'a přejmenovat na:', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'appadmin je zakázaná bez zabezpečeného spojení', +'Application': 'Application', +'application "%s" uninstalled': 'application "%s" odinstalována', +'application compiled': 'aplikace zkompilována', +'Application name:': 'Název aplikace:', +'are not used': 'nepoužita', +'are not used yet': 'ještě nepoužita', +'Are you sure you want to delete this object?': 'Opravdu chcete odstranit tento objekt?', +'Are you sure you want to uninstall application "%s"?': 'Opravdu chcete odinstalovat aplikaci "%s"?', +'arguments': 'arguments', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.', +'Available Databases and Tables': 'Dostupné databáze a tabulky', +'back': 'zpět', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'Begin': 'Začít', +'breakpoint': 'bod přerušení', +'Breakpoints': 'Body přerušení', +'breakpoints': 'body přerušení', +'Buy this book': 'Koupit web2py knihu', +"Buy web2py's book": "Buy web2py's book", +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Klíče cache', +'cache, errors and sessions cleaned': 'cache, chyby a relace byly pročištěny', +'can be a git repo': 'může to být git repo', +'Cancel': 'Storno', +'Cannot be empty': 'Nemůže být prázdné', +'Change Admin Password': 'Změnit heslo pro správu', +'Change admin password': 'Změnit heslo pro správu aplikací', +'Change password': 'Změna hesla', +'check all': 'vše označit', +'Check for upgrades': 'Zkusit aktualizovat', +'Check to delete': 'Označit ke smazání', +'Check to delete:': 'Označit ke smazání:', +'Checking for upgrades...': 'Zjišťuji, zda jsou k dispozici aktualizace...', +'Clean': 'Pročistit', +'Clear CACHE?': 'Vymazat CACHE?', +'Clear DISK': 'Vymazat DISK', +'Clear RAM': 'Vymazat RAM', +'Click row to expand traceback': 'Pro rozbalení stopy, klikněte na řádek', +'Click row to view a ticket': 'Pro zobrazení chyby (ticketu), klikněte na řádku...', +'Client IP': 'IP adresa klienta', +'code': 'code', +'Code listing': 'Code listing', +'collapse/expand all': 'vše sbalit/rozbalit', +'Community': 'Komunita', +'Compile': 'Zkompilovat', +'compiled application removed': 'zkompilovaná aplikace smazána', +'Components and Plugins': 'Komponenty a zásuvné moduly', +'Condition': 'Podmínka', +'Config.ini': 'Config.ini', +'continue': 'continue', +'Controller': 'Kontrolér (Controller)', +'Controllers': 'Kontroléry', +'controllers': 'kontroléry', +'Copyright': 'Copyright', +'Count': 'Počet', +'Create': 'Vytvořit', +'create file with filename:': 'vytvořit soubor s názvem:', +'created by': 'vytvořil', +'Created By': 'Vytvořeno - kým', +'Created On': 'Vytvořeno - kdy', +'crontab': 'crontab', +'Current request': 'Aktuální požadavek', +'Current response': 'Aktuální odpověď', +'Current session': 'Aktuální relace', +'currently running': 'právě běží', +'currently saved or': 'uloženo nebo', +'customize me!': 'upravte mě!', +'data uploaded': 'data nahrána', +'Database': 'Rozhraní databáze', +'Database %s select': 'databáze %s výběr', +'Database administration': 'Database administration', +'database administration': 'správa databáze', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Datum a čas', +'day': 'den', +'db': 'db', +'DB Model': 'Databázový model', +'Debug': 'Ladění', +'defines tables': 'defines tables', +'Delete': 'Smazat', +'delete': 'smazat', +'delete all checked': 'smazat vše označené', +'delete plugin': 'delete plugin', +'Delete this file (you will be asked to confirm deletion)': 'Smazat tento soubor (budete požádán o potvrzení mazání)', +'Delete:': 'Smazat:', +'deleted after first hit': 'smazat po prvním dosažení', +'Demo': 'Demo', +'Deploy': 'Nahrát', +'Deploy on Google App Engine': 'Nahrát na Google App Engine', +'Deploy to OpenShift': 'Nahrát na OpenShift', +'Deployment Recipes': 'Postupy pro deployment', +'Description': 'Popis', +'design': 'návrh', +'Design': 'Design', +'Detailed traceback description': 'Podrobný výpis prostředí', +'details': 'podrobnosti', +'direction: ltr': 'směr: ltr', +'Disable': 'Zablokovat', +'DISK': 'DISK', +'Disk Cache Keys': 'Klíče diskové cache', +'Disk Cleared': 'Disk smazán', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'docs': 'dokumentace', +'Documentation': 'Dokumentace', +"Don't know what to do?": 'Nevíte kudy kam?', +'done!': 'hotovo!', +'Download': 'Stáhnout', +'download layouts': 'stáhnout moduly rozvržení stránky', +'download plugins': 'stáhnout zásuvné moduly', +'E-mail': 'E-mail', +'Edit': 'Upravit', +'edit all': 'edit all', +'Edit application': 'Správa aplikace', +'edit controller': 'edit controller', +'Edit current record': 'Upravit aktuální záznam', +'Edit Profile': 'Upravit profil', +'edit views:': 'upravit pohled:', +'Editing file "%s"': 'Úprava souboru "%s"', +'Editing Language file': 'Úprava jazykového souboru', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Email and SMS': 'Email a SMS', +'Enable': 'Odblokovat', +'enter a number between %(min)g and %(max)g': 'zadejte číslo mezi %(min)g a %(max)g', +'enter an integer between %(min)g and %(max)g': 'zadejte celé číslo mezi %(min)g a %(max)g', +'Error': 'Chyba', +'Error logs for "%(app)s"': 'Seznam výskytu chyb pro aplikaci "%(app)s"', +'Error snapshot': 'Snapshot chyby', +'Error ticket': 'Ticket chyby', +'Errors': 'Chyby', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Prvky instance výjimky', +'Expand Abbreviation': 'Expand Abbreviation', +'export as csv file': 'exportovat do .csv souboru', +'exposes': 'vystavuje', +'exposes:': 'vystavuje funkce:', +'extends': 'rozšiřuje', +'failed to compile file because:': 'soubor se nepodařilo zkompilovat, protože:', +'FAQ': 'Často kladené dotazy', +'File': 'Soubor', +'file': 'soubor', +'file "%(filename)s" created': 'file "%(filename)s" created', +'file saved on %(time)s': 'soubor uložen %(time)s', +'file saved on %s': 'soubor uložen %s', +'Filename': 'Název souboru', +'filter': 'filtr', +'Find Next': 'Najít další', +'Find Previous': 'Najít předchozí', +'First name': 'Křestní jméno', +'Forgot username?': 'Zapomněl jste svoje přihlašovací jméno?', +'forgot username?': 'zapomněl jste svoje přihlašovací jméno?', +'Forms and Validators': 'Formuláře a validátory', +'Frames': 'Frames', +'Free Applications': 'Aplikace zdarma', +'Functions with no doctests will result in [passed] tests.': 'Functions with no doctests will result in [passed] tests.', +'Generate': 'Vytvořit', +'Get from URL:': 'Stáhnout z internetu:', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globální proměnné', +'go!': 'OK!', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Group %(group_id)s created': 'Skupina %(group_id)s vytvořena', +'Group ID': 'ID skupiny', +'Groups': 'Skupiny', +'Hello World': 'Ahoj světe', +'Help': 'Nápověda', +'Helping web2py': 'Helping web2py', +'Hide/Show Translated strings': 'Skrýt/Zobrazit přeložené texty', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Hits': 'Kolikrát dosaženo', +'Home': 'Domovská stránka', +'honored only if the expression evaluates to true': 'brát v potaz jen když se tato podmínka vyhodnotí kladně', +'How did you get here?': 'Jak jste se sem vlastně dostal?', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'import': 'import', +'Import/Export': 'Import/Export', +'includes': 'zahrnuje', +'Index': 'Index', +'insert new': 'vložit nový záznam ', +'insert new %s': 'vložit nový záznam %s', +'inspect attributes': 'inspect attributes', +'Install': 'Instalovat', +'Installed applications': 'Nainstalované aplikace', +'Interaction at %s line %s': 'Interakce v %s, na řádce %s', +'Interactive console': 'Interaktivní příkazová řádka', +'Internal State': 'Vnitřní stav', +'Introduction': 'Úvod', +'Invalid email': 'Neplatný email', +'Invalid password': 'Nesprávné heslo', +'invalid password.': 'neplatné heslo', +'Invalid Query': 'Neplatný dotaz', +'invalid request': 'Neplatný požadavek', +'Is Active': 'Je aktivní', +'It is %s %%{day} today.': 'Dnes je to %s %%{den}.', +'Key': 'Klíč', +'Key bindings': 'Vazby klíčů', +'Key bindings for ZenCoding Plugin': 'Key bindings for ZenCoding Plugin', +'languages': 'jazyky', +'Languages': 'Jazyky', +'Last name': 'Příjmení', +'Last saved on:': 'Naposledy uloženo:', +'Layout': 'Rozvržení stránky (layout)', +'Layout Plugins': 'Moduly rozvržení stránky (Layout Plugins)', +'Layouts': 'Rozvržení stránek', +'License for': 'Licence pro', +'Line number': 'Číslo řádku', +'LineNo': 'Č.řádku', +'Live Chat': 'Online pokec', +'loading...': 'nahrávám...', +'locals': 'locals', +'Locals##debug': 'Lokální proměnné', +'Log In': 'Log In', +'Logged in': 'Přihlášení proběhlo úspěšně', +'Logged out': 'Odhlášení proběhlo úspěšně', +'Login': 'Přihlásit se', +'login': 'přihlásit se', +'Login to the Administrative Interface': 'Přihlásit se do Správce aplikací', +'logout': 'odhlásit se', +'Logout': 'Odhlásit se', +'Lost Password': 'Zapomněl jste heslo', +'Lost password?': 'Zapomněl jste heslo?', +'lost password?': 'zapomněl jste heslo?', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Manage Cache', +'Memberships': 'Memberships', +'Menu Model': 'Model rozbalovací nabídky', +'Models': 'Modely', +'models': 'modely', +'Modified By': 'Změněno - kým', +'Modified On': 'Změněno - kdy', +'Modules': 'Moduly', +'modules': 'moduly', +'My Sites': 'Správa aplikací', +'Name': 'Jméno', +'new application "%s" created': 'nová aplikace "%s" vytvořena', +'New application wizard': 'Nový průvodce aplikací', +'New Application Wizard': 'Nový průvodce aplikací', +'New password': 'Nové heslo', +'New Record': 'Nový záznam', +'new record inserted': 'nový záznam byl založen', +'New simple application': 'Vytvořit primitivní aplikaci', +'next': 'next', +'next %s rows': 'next %s rows', +'next 100 rows': 'dalších 100 řádků', +'No databases in this application': 'V této aplikaci nejsou žádné databáze', +'No Interaction yet': 'Ještě žádná interakce nenastala', +'No ticket_storage.txt found under /private folder': 'Soubor ticket_storage.txt v adresáři /private nenalezen', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Object or table name': 'Objekt či tabulka', +'Old password': 'Původní heslo', +'Online book': 'Online book', +'online designer': 'online návrhář', +'Online examples': 'Příklady online', +'Open new app in new window': 'Open new app in new window', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'nebo importovat z .csv souboru', +'Origin': 'Původ', +'Original/Translation': 'Originál/Překlad', +'Other Plugins': 'Ostatní moduly', +'Other Recipes': 'Ostatní zásuvné moduly', +'Overview': 'Přehled', +'Overwrite installed app': 'Přepsat instalovanou aplikaci', +'Pack all': 'Zabalit', +'Pack compiled': 'Zabalit zkompilované', +'pack plugin': 'pack plugin', +'password': 'heslo', +'Password': 'Heslo', +"Password fields don't match": 'Hesla se neshodují', +'Peeking at file': 'Peeking at file', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Prosím', +'Plugin "%s" in application': 'Plugin "%s" in application', +'plugins': 'zásuvné moduly', +'Plugins': 'Zásuvné moduly', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Množná čísla:', +'Powered by': 'Poháněno', +'Preface': 'Předmluva', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'předchozích 100 řádků', +'Private files': 'Soukromé soubory', +'private files': 'soukromé soubory', +'profile': 'profil', +'Project Progress': 'Vývoj projektu', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query:': 'Dotaz:', +'Quick Examples': 'Krátké příklady', +'RAM': 'RAM', +'RAM Cache Keys': 'Klíče RAM Cache', +'Ram Cleared': 'RAM smazána', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Readme': 'Nápověda', +'Recipes': 'Postupy jak na to', +'Record': 'Záznam', +'record does not exist': 'záznam neexistuje', +'Record ID': 'ID záznamu', +'Record id': 'id záznamu', +'refresh': 'obnovte', +'register': 'registrovat', +'Register': 'Zaregistrovat se', +'Registration identifier': 'Registrační identifikátor', +'Registration key': 'Registrační klíč', +'reload': 'reload', +'Reload routes': 'Znovu nahrát cesty', +'Remember me (for 30 days)': 'Zapamatovat na 30 dní', +'Remove compiled': 'Odstranit zkompilované', +'Removed Breakpoint on %s at line %s': 'Bod přerušení smazán - soubor %s na řádce %s', +'Replace': 'Zaměnit', +'Replace All': 'Zaměnit vše', +'request': 'request', +'Reset Password key': 'Reset registračního klíče', +'response': 'response', +'restart': 'restart', +'restore': 'obnovit', +'Retrieve username': 'Získat přihlašovací jméno', +'return': 'return', +'revert': 'vrátit se k původnímu', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Záznamy v tabulce', +'Rows selected': 'Záznamů zobrazeno', +'rules are not defined': 'pravidla nejsou definována', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Spustí testy v tomto souboru (ke spuštění všech testů, použijte tlačítko 'test')", +'Running on %s': 'Běží na %s', +'Save': 'Uložit', +'Save file:': 'Save file:', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Uložit pomocí Ajaxu', +'Saved file hash:': 'hash uloženého souboru:', +'Semantic': 'Modul semantic', +'Services': 'Služby', +'session': 'session', +'session expired': 'session expired', +'Set Breakpoint on %s at line %s: %s': 'Bod přerušení nastaven v souboru %s na řádce %s: %s', +'shell': 'příkazová řádka', +'Sign Up': 'Sign Up', +'Singular Form': 'Singular Form', +'Site': 'Správa aplikací', +'Size of cache:': 'Velikost cache:', +'skip to generate': 'skip to generate', +'Sorry, could not find mercurial installed': 'Bohužel mercurial není nainstalován.', +'Start a new app': 'Vytvořit novou aplikaci', +'Start searching': 'Začít hledání', +'Start wizard': 'Spustit průvodce', +'state': 'stav', +'Static': 'Static', +'static': 'statické soubory', +'Static files': 'Statické soubory', +'Statistics': 'Statistika', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'Stylesheet': 'CSS styly', +'submit': 'odeslat', +'Submit': 'Odeslat', +'successful': 'úspěšně', +'Support': 'Podpora', +'Sure you want to delete this object?': 'Opravdu chcete smazat tento objekt?', +'Table': 'tabulka', +'Table name': 'Název tabulky', +'Temporary': 'Dočasný', +'test': 'test', +'Testing application': 'Testing application', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"Dotaz" je podmínka, například "db.tabulka1.pole1==\'hodnota\'". Podmínka "db.tabulka1.pole1==db.tabulka2.pole2" pak vytvoří SQL JOIN.', +'The application logic, each URL path is mapped in one exposed function in the controller': 'Logika aplikace: každá URL je mapována na funkci vystavovanou kontrolérem.', +'The Core': 'Jádro (The Core)', +'The data representation, define database tables and sets': 'Reprezentace dat: definovat tabulky databáze a záznamy', +'The output of the file is a dictionary that was rendered by the view %s': 'Výstup ze souboru je slovník, který se zobrazil v pohledu %s.', +'The presentations layer, views are also known as templates': 'Prezentační vrstva: pohledy či templaty (šablony)', +'The Views': 'Pohledy (The Views)', +'There are no controllers': 'There are no controllers', +'There are no modules': 'There are no modules', +'There are no plugins': 'Žádné moduly nejsou instalovány.', +'There are no private files': 'Žádné soukromé soubory neexistují.', +'There are no static files': 'There are no static files', +'There are no translators, only default language is supported': 'There are no translators, only default language is supported', +'There are no views': 'There are no views', +'These files are not served, they are only available from within your app': 'Tyto soubory jsou klientům nepřístupné. K dispozici jsou pouze v rámci aplikace.', +'These files are served without processing, your images go here': 'Tyto soubory jsou servírovány bez přídavné logiky, sem patří např. obrázky.', +'This App': 'Tato aplikace', +'This is a copy of the scaffolding application': 'Toto je kopie aplikace skelet.', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': 'This is the %(filename)s template', +'this page to see if a breakpoint was hit and debug interaction is required.': 'tuto stránku, abyste uviděli, zda se dosáhlo bodu přerušení.', +'Ticket': 'Ticket', +'Ticket ID': 'Ticket ID', +'Time in Cache (h:m:s)': 'Čas v Cache (h:m:s)', +'Timestamp': 'Časové razítko', +'to previous version.': 'k předchozí verzi.', +'To create a plugin, name a file/folder plugin_[name]': 'Zásuvný modul vytvoříte tak, že pojmenujete soubor/adresář plugin_[jméno modulu]', +'To emulate a breakpoint programatically, write:': 'K nastavení bodu přerušení v kódu programu, napište:', +'to use the debugger!': ', abyste mohli ladící program používat!', +'toggle breakpoint': 'vyp./zap. bod přerušení', +'Toggle Fullscreen': 'Na celou obrazovku a zpět', +'too short': 'Příliš krátké', +'Traceback': 'Traceback', +'Translation strings for the application': 'Překlad textů pro aplikaci', +'try something like': 'try something like', +'Try the mobile interface': 'Zkuste rozhraní pro mobilní zařízení', +'try view': 'try view', +'Twitter': 'Twitter', +'Type python statement in here and hit Return (Enter) to execute it.': 'Type python statement in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Unable to check for upgrades', +'unable to parse csv file': 'csv soubor nedá sa zpracovat', +'uncheck all': 'vše odznačit', +'Uninstall': 'Odinstalovat', +'update': 'aktualizovat', +'update all languages': 'aktualizovat všechny jazyky', +'Update:': 'Upravit:', +'Upgrade': 'Upgrade', +'upgrade now': 'upgrade now', +'upgrade now to %s': 'upgrade now to %s', +'upload': 'nahrát', +'Upload': 'Upload', +'Upload a package:': 'Nahrát balík:', +'Upload and install packed application': 'Nahrát a instalovat zabalenou aplikaci', +'upload file:': 'nahrát soubor:', +'upload plugin file:': 'nahrát soubor modulu:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Použijte (...)&(...) pro AND, (...)|(...) pro OR a ~(...) pro NOT pro sestavení složitějších dotazů.', +'User': 'User', +'User %(id)s Logged-in': 'Uživatel %(id)s přihlášen', +'User %(id)s Logged-out': 'Uživatel %(id)s odhlášen', +'User %(id)s Password changed': 'Uživatel %(id)s změnil heslo', +'User %(id)s Profile updated': 'Uživatel %(id)s upravil profil', +'User %(id)s Registered': 'Uživatel %(id)s se zaregistroval', +'User %(id)s Username retrieved': 'Uživatel %(id)s si nachal zaslat přihlašovací jméno', +'User ID': 'ID uživatele', +'Username': 'Přihlašovací jméno', +'Users': 'Users', +'variables': 'variables', +'Verify Password': 'Zopakujte heslo', +'Version': 'Verze', +'Version %s.%s.%s (%s) %s': 'Verze %s.%s.%s (%s) %s', +'Versioning': 'Verzování', +'Videos': 'Videa', +'View': 'Pohled (View)', +'Views': 'Pohledy', +'views': 'pohledy', +'Web Framework': 'Web Framework', +'web2py is up to date': 'Máte aktuální verzi web2py.', +'web2py online debugger': 'Ladící online web2py program', +'web2py Recent Tweets': 'Štěbetání na Twitteru o web2py', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py upgraded; please restart it', +'Welcome': 'Vítejte', +'Welcome to web2py': 'Vitejte ve web2py', +'Welcome to web2py!': 'Vítejte ve web2py!', +'Which called the function %s located in the file %s': 'která zavolala funkci %s v souboru (kontroléru) %s.', +'Working...': 'Working...', +'You are successfully running web2py': 'Úspěšně jste spustili web2py.', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'Nastavovat a mazat body přerušení je též možno v rámci editování zdrojového souboru přes tlačítko Vyp./Zap. bod přerušení', +'You can inspect variables using the console bellow': 'Níže pomocí příkazové řádky si můžete prohlédnout proměnné', +'You can modify this application and adapt it to your needs': 'Tuto aplikaci si můžete upravit a přizpůsobit ji svým potřebám.', +'You need to set up and reach a': 'Je třeba nejprve nastavit a dojít až na', +'You visited the url %s': 'Navštívili jste stránku %s,', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Aplikace bude blokována než se klikne na jedno z tlačítek (další, krok, pokračovat, atd.)', +} diff --git a/web2py/applications/SP/languages/de.py b/web2py/applications/SP/languages/de.py new file mode 100644 index 0000000..2aefeb3 --- /dev/null +++ b/web2py/applications/SP/languages/de.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'de', +'!langname!': 'Deutsch (DE)', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Update" ist ein optionaler Ausdruck wie "feld1=\'newvalue\'". JOIN Ergebnisse können nicht aktualisiert oder gelöscht werden', +'%s %%(shop)': '%s %%(shop)', +'%s %%(shop[0])': '%s %%(shop[0])', +'%s %%{quark[0]}': '%s %%{quark[0]}', +'%s %%{row} deleted': '%s %%{row} gelöscht', +'%s %%{row} updated': '%s %%{row} aktualisiert', +'%s %%{shop[0]}': '%s %%{shop[0]}', +'%s %%{shop}': '%s %%{shop}', +'%s selected': '%s ausgewählt', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**nicht verfügbar** (benötigt die Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] Bibliothek)', +'?': '?', +'@markmin\x01**Hello World**': '**Hallo Welt**', +'@markmin\x01An error occured, please [[reload %s]] the page': 'Ein Fehler ist aufgetreten, bitte [[laden %s]] Sie die Seite neu', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**nicht verfügbar**``:rot (benötigt die Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] Bibliothek)', +'About': 'Über', +'Access Control': 'Zugangskontrolle', +'admin': 'admin', +'Administrative Interface': 'Administrationsoberfläche', +'Ajax Recipes': 'Ajax Rezepte', +'An error occured, please [[reload %s]] the page': 'Ein Fehler ist aufgetreten, bitte [[laden %s]] Sie die Seite neu', +'appadmin is disabled because insecure channel': 'Appadmin ist deaktiviert, wegen der Benutzung eines unsicheren Kanals', +'Are you sure you want to delete this object?': 'Sind Sie sich sicher, dass Sie dieses Objekt löschen wollen?', +'Available Databases and Tables': 'Verfügbare Datenbanken und Tabellen', +'Buy this book': 'Dieses Buch kaufen', +"Buy web2py's book": "web2py's Buch kaufen", +'cache': 'cache', +'Cache': 'Cache', +'Cache Cleared': 'Cache geleert', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache enthält items die bis zu **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} alt sind.', +'Cache Keys': 'Cache Schlüssel', +'Cannot be empty': 'Darf nicht leer sein', +'Check to delete': 'Auswählen um zu löschen', +'Clear CACHE?': 'CACHE löschen?', +'Clear DISK': 'DISK löschen', +'Clear RAM': 'RAM löschen', +'Client IP': 'Client IP', +'Community': 'Community', +'Components and Plugins': 'Komponenten und Plugins', +'Config.ini': 'Config.ini', +'Controller': 'Controller', +'Copyright': 'Copyright', +'Created By': 'Erstellt von', +'Created On': 'Erstellt am', +'Current request': 'Derzeitiger Request', +'Current response': 'Derzeitige Response', +'Current session': 'Derzeitige Session', +'customize me!': 'Pass mich an!', +'data uploaded': 'Datei hochgeladen', +'Database': 'Datenbank', +'Database %s select': 'Datenbank %s ausgewählt', +'Database Administration (appadmin)': 'Datenbankadministration (appadmin)', +'db': 'db', +'DB Model': 'Muster-DB', +'Delete:': 'Lösche:', +'Demo': 'Demo', +'Deployment Recipes': 'Entwicklungsrezepte', +'Description': 'Beschreibung', +'design': 'Design', +'Design': 'Design', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk gelöscht', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK enthält items die bis zu **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} alt sind.', +'Documentation': 'Dokumentation', +"Don't know what to do?": 'Wissen Sie nicht weiter?', +'done!': 'Fertig!', +'Download': 'Download', +'E-mail': 'E-mail', +'Edit current record': 'Diesen Eintrag editieren', +'Email and SMS': 'Email und SMS', +'Enter an integer between %(min)g and %(max)g': 'Eine Zahl zwischen %(min)g und %(max)g eingeben', +'enter an integer between %(min)g and %(max)g': 'eine Zahl zwischen %(min)g und %(max)g eingeben', +'enter date and time as %(format)s': 'ein Datum und eine Uhrzeit als %(format)s eingeben', +'Errors': 'Fehlermeldungen', +'export as csv file': 'als csv Datei exportieren', +'FAQ': 'FAQ', +'First name': 'Vorname', +'Forms and Validators': 'Forms und Validators', +'Free Applications': 'Kostenlose Anwendungen', +'Graph Model': 'Muster-Graph', +'Group %(group_id)s created': 'Gruppe %(group_id)s erstellt', +'Group ID': 'Gruppen ID', +'Group uniquely assigned to user %(id)s': 'Gruppe eindeutigem Benutzer %(id)s zugewiesen', +'Groups': 'Gruppen', +'Hello World': 'Hallo Welt', +'Hello World ## Kommentar': 'Hallo Welt ', +'Hello World## Kommentar': 'Hallo Welt', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Trefferquote: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} und **%(misses)s** %%{miss(misses)})', +'Home': 'Startseite', +'How did you get here?': 'Wie sind Sie hier her gelangt?', +'import': 'Importieren', +'Import/Export': 'Importieren/Exportieren', +'Internal State': 'Innerer Zustand', +'Introduction': 'Einführung', +'Invalid email': 'Ungültige Email', +'Invalid Query': 'Ungültige Query', +'invalid request': 'Ungültiger Request', +'Is Active': 'Ist aktiv', +'Key': 'Schlüssel', +'Last name': 'Nachname', +'Layout': 'Layout', +'Layout Plugins': 'Layout Plugins', +'Layouts': 'Layouts', +'Live Chat': 'Live Chat', +'Log In': 'Log In', +'Logged in': 'Eingeloggt', +'Logged out': 'Ausgeloggt', +'Login': 'Einloggen', +'Logout': 'Ausloggen', +'Lost Password': 'Passwort vergessen', +'Lost password?': 'Passwort vergessen?', +'Manage %(action)s': '%(action)s verwalten', +'Manage Access Control': 'Zugangskontrolle verwalten', +'Manage Cache': 'Cache verwalten', +'Memberships': 'Mitgliedschaften', +'Menu Model': 'Menü-Muster', +'Modified By': 'Verändert von', +'Modified On': 'Verändert am', +'My Sites': 'Meine Seiten', +'Name': 'Name', +'New Record': 'Neuer Eintrag', +'new record inserted': 'neuer Eintrag hinzugefügt', +'next %s rows': 'nächste %s Reihen', +'No databases in this application': 'Keine Datenbank in dieser Anwendung', +'Number of entries: **%s**': 'Nummer der Einträge: **%s**', +'Object or table name': 'Objekt- oder Tabellenname', +'Online book': 'Online Buch', +'Online examples': 'Online Beispiele', +'or import from csv file': 'oder von csv Datei importieren', +'Origin': 'Ursprung', +'Other Plugins': 'Andere Plugins', +'Other Recipes': 'Andere Rezepte', +'Overview': 'Überblick', +'Password': 'Passwort', +"Password fields don't match": 'Passwortfelder sind nicht gleich', +'Permission': 'Erlaubnis', +'Permissions': 'Erlaubnisse', +'please input your password again': 'Bitte geben Sie ihr Passwort erneut ein', +'Plugins': 'Plugins', +'Powered by': 'Unterstützt von', +'Preface': 'Allgemeines', +'previous %s rows': 'vorherige %s Reihen', +'Profile': 'Profil', +'pygraphviz library not found': 'pygraphviz Bibliothek wurde nicht gefunden', +'Python': 'Python', +'Query:': 'Query:', +'Quick Examples': 'Kurze Beispiele', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram gelöscht', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM enthält items die bis zu **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} alt sind.', +'Recipes': 'Rezepte', +'Record': 'Eintrag', +'record does not exist': 'Eintrag existiert nicht', +'Record ID': 'ID des Eintrags', +'Record id': 'id des Eintrags', +'Register': 'Register', +'Registration identifier': 'Registrierungsbezeichnung', +'Registration key': 'Registierungsschlüssel', +'Registration successful': 'Registrierung erfolgreich', +'Remember me (for 30 days)': 'Eingeloggt bleiben (30 Tage lang)', +'Reset Password key': 'Passwortschlüssel zurücksetzen', +'Role': 'Rolle', +'Roles': 'Rollen', +'Rows in Table': 'Tabellenreihen', +'Rows selected': 'Reihen ausgewählt', +'Save model as...': 'Speichere Vorlage als...', +'Semantic': 'Semantik', +'Services': 'Dienste', +'Sign Up': 'Registrieren', +'Size of cache:': 'Cachegröße:', +'state': 'Status', +'Statistics': 'Statistik', +'Stylesheet': 'Stylesheet', +'submit': 'Submit', +'Support': 'Support', +'Table': 'Tabelle', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'Die "query" ist eine Bedingung wie "db.tabelle1.feld1==\'wert\'". So etwas wie "db.tabelle1.feld1==db.tabelle2.feld2" resultiert in einem SQL JOIN.', +'The Core': 'Der Core', +'The output of the file is a dictionary that was rendered by the view %s': 'Die Ausgabe der Datei ist ein "dictionary", welches vom "view" %s gerendert wurde', +'The Views': 'Die Views', +'This App': 'Diese App', +'This email already has an account': 'Diese email besitzt bereits ein Konto', +'Time in Cache (h:m:s)': 'Zeit im Cache (h:m:s)', +'Timestamp': 'Zeitstempel', +'Traceback': 'Zurückverfolgen', +'Twitter': 'Twitter', +'unable to parse csv file': 'csv Datei konnte nicht geparst werden', +'Update:': 'Update:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Benutze (...)&(...) für AND, (...)|(...) für OR, und ~(...) für NOT um komplexere Queries zu erstellen.', +'User': 'Benutzer', +'User %(id)s Logged-in': 'Benutzer %(id)s hat sich eingeloggt', +'User %(id)s Logged-out': 'Benutzer %(id)s hat sich ausgeloggt', +'User %(id)s Registered': 'Benutzer %(id)s hat sich registriert', +'User ID': 'Benutzer ID', +'Users': 'Benutzer', +'value already in database or empty': 'Wert ist bereits in der Datenbank oder leer', +'Verify Password': 'Passwort überprüfen', +'Videos': 'Videos', +'View': 'Ansicht', +'Welcome': 'Willkommen', +'Welcome to web2py!': 'Willkommen bei web2py!', +'Which called the function %s located in the file %s': 'Welche die Funktion %s in der Datei %s aufrief', +'Working...': 'Arbeite...', +'You are successfully running web2py': 'web2py wird erfolgreich ausgeführt', +'You can modify this application and adapt it to your needs': 'Sie können diese Anwendung verändern und Ihren Bedürfnissen anpassen', +'You visited the url %s': 'Sie haben die URL %s besucht', +} diff --git a/web2py/applications/SP/languages/en.py b/web2py/applications/SP/languages/en.py new file mode 100644 index 0000000..cb50eda --- /dev/null +++ b/web2py/applications/SP/languages/en.py @@ -0,0 +1,157 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'en-us', +'!langname!': 'English (US)', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN', +'%s %%{row} deleted': '%s %%{row} deleted', +'%s %%{row} updated': '%s %%{row} updated', +'%s selected': '%s selected', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'About', +'Access Control': 'Access Control', +'admin': 'admin', +'Ajax Recipes': 'Ajax Recipes', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'appadmin is disabled because insecure channel': 'appadmin is disabled because insecure channel', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Available Databases and Tables': 'Available Databases and Tables', +"Buy web2py's book": "Buy web2py's book", +'cache': 'cache', +'Cache': 'Cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'Cannot be empty': 'Cannot be empty', +'Check to delete': 'Check to delete', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Community': 'Community', +'Components and Plugins': 'Components and Plugins', +'Config.ini': 'Config.ini', +'Controller': 'Controller', +'Copyright': 'Copyright', +'Current request': 'Current request', +'Current response': 'Current response', +'Current session': 'Current session', +'data uploaded': 'data uploaded', +'Database': 'Database', +'Database %s select': 'Database %s select', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'db': 'db', +'DB Model': 'DB Model', +'Delete:': 'Delete:', +'Demo': 'Demo', +'Deployment Recipes': 'Deployment Recipes', +'design': 'design', +'Design': 'Design', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentation', +"Don't know what to do?": "Don't know what to do?", +'done!': 'done!', +'Download': 'Download', +'Edit current record': 'Edit current record', +'Email and SMS': 'Email and SMS', +'Errors': 'Errors', +'export as csv file': 'export as csv file', +'FAQ': 'FAQ', +'Forms and Validators': 'Forms and Validators', +'Free Applications': 'Free Applications', +'Graph Model': 'Graph Model', +'Groups': 'Groups', +'Hello World': 'Hello World', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Home', +'How did you get here?': 'How did you get here?', +'import': 'import', +'Import/Export': 'Import/Export', +'Internal State': 'Internal State', +'Introduction': 'Introduction', +'Invalid Query': 'Invalid Query', +'invalid request': 'invalid request', +'Key': 'Key', +'Layout': 'Layout', +'Live Chat': 'Live Chat', +'Log In': 'Log In', +'Lost Password': 'Lost Password', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Manage Cache', +'Memberships': 'Memberships', +'Menu Model': 'Menu Model', +'My Sites': 'My Sites', +'New Record': 'New Record', +'new record inserted': 'new record inserted', +'next %s rows': 'next %s rows', +'No databases in this application': 'No databases in this application', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Online book': 'Online book', +'Online examples': 'Online examples', +'or import from csv file': 'or import from csv file', +'Other Recipes': 'Other Recipes', +'Overview': 'Overview', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Plugins': 'Plugins', +'Powered by': 'Powered by', +'Preface': 'Preface', +'previous %s rows': 'previous %s rows', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query:': 'Query:', +'Quick Examples': 'Quick Examples', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Recipes', +'Record': 'Record', +'record does not exist': 'record does not exist', +'Record id': 'Record id', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Rows in Table', +'Rows selected': 'Rows selected', +'Save model as...': 'Save model as...', +'Services': 'Services', +'Sign Up': 'Sign Up', +'Size of cache:': 'Size of cache:', +'state': 'state', +'Statistics': 'Statistics', +'Stylesheet': 'Stylesheet', +'submit': 'submit', +'Support': 'Support', +'Table': 'Table', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.', +'The Core': 'The Core', +'The output of the file is a dictionary that was rendered by the view %s': 'The output of the file is a dictionary that was rendered by the view %s', +'The Views': 'The Views', +'This App': 'This App', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Traceback': 'Traceback', +'Twitter': 'Twitter', +'unable to parse csv file': 'unable to parse csv file', +'Update:': 'Update:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.', +'User': 'User', +'Users': 'Users', +'Videos': 'Videos', +'View': 'View', +'Welcome to web2py!': 'Welcome to web2py!', +'Which called the function %s located in the file %s': 'Which called the function %s located in the file %s', +'Working...': 'Working...', +'You are successfully running web2py': 'You are successfully running web2py', +'You can modify this application and adapt it to your needs': 'You can modify this application and adapt it to your needs', +'You visited the url %s': 'You visited the url %s', +} diff --git a/web2py/applications/SP/languages/es.py b/web2py/applications/SP/languages/es.py new file mode 100644 index 0000000..7865c42 --- /dev/null +++ b/web2py/applications/SP/languages/es.py @@ -0,0 +1,468 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'es', +'!langname!': 'Español', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"actualice" es una expresión opcional como "campo1=\'nuevo_valor\'". No se puede actualizar o eliminar resultados de un JOIN', +'%(nrows)s records found': '%(nrows)s registros encontrados', +'%s %%{position}': '%s %%{posición}', +'%s %%{row} deleted': '%s %%{fila} %%{eliminada}', +'%s %%{row} updated': '%s %%{fila} %%{actualizada}', +'%s selected': '%s %%{seleccionado}', +'%Y-%m-%d': '%d/%m/%Y', +'%Y-%m-%d %H:%M:%S': '%d/%m/%Y %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'(something like "it-it")': '(algo como "it-it")', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**no disponible** (requiere la libreria [[guppy http://pypi.python.org/pypi/guppy/ popup]] de Python)', +'?': '?', +'@markmin\x01An error occured, please [[reload %s]] the page': 'Ha ocurrido un error, por favor [[recargar %s]] la página', +'@markmin\x01Number of entries: **%s**': 'Número de entradas: **%s**', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**no disponible**``:red (Necesita libreria de Python: [[guppy http://pypi.python.org/pypi/guppy/ popup]])', +'A new version of web2py is available': 'Hay una nueva versión de web2py disponible', +'A new version of web2py is available: %s': 'Hay una nueva versión de web2py disponible: %s', +'About': 'Acerca de', +'about': 'acerca de', +'About application': 'Acerca de la aplicación', +'Access Control': 'Control de Acceso', +'Add': 'Añadir', +'additional code for your application': 'código adicional para su aplicación', +'admin': 'administrar', +'admin disabled because no admin password': 'admin deshabilitado por falta de contraseña', +'admin disabled because not supported on google app engine': 'admin deshabilitado, no es soportado en GAE', +'admin disabled because unable to access password file': 'admin deshabilitado, imposible acceder al archivo con la contraseña', +'Admin is disabled because insecure channel': 'Admin deshabilitado, el canal no es seguro', +'Admin is disabled because unsecure channel': 'Admin deshabilitado, el canal no es seguro', +'Administrative interface': 'Interfaz administrativa', +'Administrative Interface': 'Interfaz Administrativa', +'Administrator Password:': 'Contraseña del Administrador:', +'Ajax Recipes': 'Recetas AJAX', +'An error occured, please %s the page': 'Ha ocurrido un error, por favor %s la página', +'An error occured, please [[reload %s]] the page': 'Ha ocurrido un error, por favor [[reload %s]] la pagina', +'And': 'Y', +'and rename it (required):': 'y renómbrela (requerido):', +'and rename it:': ' y renómbrelo:', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'appadmin deshabilitado, el canal no es seguro', +'application "%s" uninstalled': 'aplicación "%s" desinstalada', +'application compiled': 'aplicación compilada', +'application is compiled and cannot be designed': 'la aplicación está compilada y no puede ser modificada', +'Apply changes': 'Aplicar cambios', +'Appointment': 'Nombramiento', +'Are you sure you want to delete file "%s"?': '¿Está seguro que desea eliminar el archivo "%s"?', +'Are you sure you want to delete this object?': '¿Está seguro que desea borrar este objeto?', +'Are you sure you want to uninstall application "%s"': '¿Está seguro que desea desinstalar la aplicación "%s"', +'Are you sure you want to uninstall application "%s"?': '¿Está seguro que desea desinstalar la aplicación "%s"?', +'at': 'en', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATENCION: Inicio de sesión requiere una conexión segura (HTTPS) o corriendo en localhost.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATENCION: NO EJECUTE VARIAS PRUEBAS SIMULTANEAMENTE, NO SON THREAD SAFE.', +'ATTENTION: you cannot edit the running application!': 'ATENCION: no puede modificar la aplicación que está ejecutandose!', +'Authentication': 'Autenticación', +'Authentication failed at client DB!': '¡La autenticación ha fallado en la BDD cliente!', +'Authentication failed at main DB!': '¡La autenticación ha fallado en la BDD principal!', +'Available Databases and Tables': 'Bases de datos y tablas disponibles', +'Back': 'Atrás', +'Buy this book': 'Compra este libro', +"Buy web2py's book": 'Compra el libro de web2py', +'Cache': 'Caché', +'cache': 'caché', +'Cache Cleared': 'Cache Limpiada', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'La Cache contiene items con **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} de antiguedad.', +'Cache Keys': 'Llaves de la Caché', +'cache, errors and sessions cleaned': 'caché, errores y sesiones eliminados', +'Cannot be empty': 'No puede estar vacío', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'No se puede compilar: hay errores en su aplicación. Depure, corrija errores y vuelva a intentarlo.', +'cannot create file': 'no es posible crear archivo', +'cannot upload file "%(filename)s"': 'no es posible subir archivo "%(filename)s"', +'Change Password': 'Cambie la Contraseña', +'Change password': 'Cambie la contraseña', +'change password': 'cambie la contraseña', +'check all': 'marcar todos', +'Check to delete': 'Marque para eliminar', +'choose one': 'escoja uno', +'clean': 'limpiar', +'Clear': 'Limpiar', +'Clear CACHE?': '¿Limpiar CACHÉ?', +'Clear DISK': 'Limpiar DISCO', +'Clear RAM': 'Limpiar RAM', +'Click on the link %(link)s to reset your password': 'Pulse en el enlace %(link)s para reiniciar su contraseña', +'click to check for upgrades': 'haga clic para buscar actualizaciones', +'client': 'cliente', +'Client IP': 'IP del Cliente', +'Close': 'Cerrar', +'Community': 'Comunidad', +'compile': 'compilar', +'compiled application removed': 'aplicación compilada eliminada', +'Components and Plugins': 'Componentes y Plugins', +'Config.ini': 'Config.ini', +'contains': 'contiene', +'Controller': 'Controlador', +'Controllers': 'Controladores', +'controllers': 'controladores', +'Copyright': 'Copyright', +'create file with filename:': 'cree archivo con nombre:', +'Create new application': 'Cree una nueva aplicación', +'create new application:': 'cree una nueva aplicación:', +'Created By': 'Creado Por', +'Created On': 'Creado En', +'CSV (hidden cols)': 'CSV (columnas ocultas)', +'Current request': 'Solicitud en curso', +'Current response': 'Respuesta en curso', +'Current session': 'Sesión en curso', +'currently saved or': 'actualmente guardado o', +'customize me!': '¡Personalizame!', +'data uploaded': 'datos subidos', +'Database': 'Base de datos', +'Database %s select': 'selección en base de datos %s', +'database administration': 'administración de base de datos', +'Database Administration (appadmin)': 'Administración de Base de Datos (appadmin)', +'Date and Time': 'Fecha y Hora', +'DB': 'BDD', +'db': 'bdd', +'DB Model': 'Modelo BDD', +'defines tables': 'define tablas', +'Delete': 'Eliminar', +'delete': 'eliminar', +'delete all checked': 'eliminar marcados', +'Delete:': 'Eliminar:', +'Demo': 'Demostración', +'Deploy on Google App Engine': 'Despliegue en Google App Engine', +'Deployment Recipes': 'Recetas de despliegue', +'Description': 'Descripción', +'design': 'diseño', +'DESIGN': 'DISEÑO', +'Design': 'Diseño', +'Design for': 'Diseño por', +'detecting': 'detectando', +'DISK': 'DISCO', +'Disk Cache Keys': 'Llaves de Caché en Disco', +'Disk Cleared': 'Disco limpiado', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'El DISCO contiene items con **%(hours)02d** %%{hora(hours)} **%(min)02d** %%{minuto(min)} **%(sec)02d** %%{segundo(sec)} de antiguedad.', +'Documentation': 'Documentación', +"Don't know what to do?": '¿No sabe que hacer?', +'done!': '¡hecho!', +'Download': 'Descargas', +'E-mail': 'Correo electrónico', +'edit': 'editar', +'EDIT': 'EDITAR', +'Edit': 'Editar', +'Edit application': 'Editar aplicación', +'edit controller': 'editar controlador', +'Edit current record': 'Edite el registro actual', +'Edit Profile': 'Editar Perfil', +'edit profile': 'editar perfil', +'Edit This App': 'Edite esta App', +'Editing file': 'Editando archivo', +'Editing file "%s"': 'Editando archivo "%s"', +'Email and SMS': 'Correo electrónico y SMS', +'Email sent': 'Correo electrónico enviado', +'End of impersonation': 'Fin de suplantación', +'enter a number between %(min)g and %(max)g': 'introduzca un numero entre %(min)g y %(max)g', +'enter a value': 'introduzca un valor', +'enter an integer between %(min)g and %(max)g': 'introduzca un número entero entre %(min)g y %(max)g', +'enter date and time as %(format)s': 'introduzca fecha y hora como %(format)s', +'Error logs for "%(app)s"': 'Bitácora de errores para "%(app)s"', +'errors': 'errores', +'Errors': 'Errores', +'Errors in form, please check it out.': 'Hay errores en el formulario, por favor compruébelo.', +'export as csv file': 'exportar como archivo CSV', +'Export:': 'Exportar:', +'exposes': 'expone', +'extends': 'extiende', +'failed to reload module': 'la recarga del módulo ha fallado', +'FAQ': 'Preguntas frecuentes', +'file "%(filename)s" created': 'archivo "%(filename)s" creado', +'file "%(filename)s" deleted': 'archivo "%(filename)s" eliminado', +'file "%(filename)s" uploaded': 'archivo "%(filename)s" subido', +'file "%(filename)s" was not deleted': 'archivo "%(filename)s" no fué eliminado', +'file "%s" of %s restored': 'archivo "%s" de %s restaurado', +'file changed on disk': 'archivo modificado en el disco', +'file does not exist': 'archivo no existe', +'file saved on %(time)s': 'archivo guardado %(time)s', +'file saved on %s': 'archivo guardado %s', +'First name': 'Nombre', +'Forgot username?': '¿Olvidó el nombre de usuario?', +'Forms and Validators': 'Formularios y validadores', +'Free Applications': 'Aplicaciones Libres', +'Functions with no doctests will result in [passed] tests.': 'Funciones sin doctests equivalen a pruebas [aceptadas].', +'Graph Model': 'Modelo en Grafo', +'Group %(group_id)s created': 'Grupo %(group_id)s creado', +'Group ID': 'ID de Grupo', +'Group uniquely assigned to user %(id)s': 'Grupo asignado únicamente al usuario %(id)s', +'Groups': 'Grupos', +'Hello World': 'Hola Mundo', +'help': 'ayuda', +'Helping web2py': 'Ayudando a web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Inicio', +'How did you get here?': '¿Cómo llegaste aquí?', +'htmledit': 'htmledit', +'Impersonate': 'Suplantar', +'import': 'importar', +'Import/Export': 'Importar/Exportar', +'in': 'en', +'includes': 'incluye', +'Index': 'Índice', +'insert new': 'inserte nuevo', +'insert new %s': 'inserte nuevo %s', +'Installed applications': 'Aplicaciones instaladas', +'Insufficient privileges': 'Privilegios insuficientes', +'internal error': 'error interno', +'Internal State': 'Estado Interno', +'Introduction': 'Introducción', +'Invalid action': 'Acción inválida', +'Invalid email': 'Correo electrónico inválido', +'invalid expression': 'expresión inválida', +'Invalid login': 'Inicio de sesión inválido', +'invalid password': 'contraseña inválida', +'Invalid Query': 'Consulta inválida', +'invalid request': 'Solicitud inválida', +'Invalid reset password': 'Reinicio de contraseña inválido', +'invalid ticket': 'Tiquete inválido', +'Is Active': 'Está Activo', +'Key': 'Llave', +'language file "%(filename)s" created/updated': 'archivo de lenguaje "%(filename)s" creado/actualizado', +'Language files (static strings) updated': 'Archivos de lenguaje (cadenas estáticas) actualizados', +'languages': 'lenguajes', +'Languages': 'Lenguajes', +'languages updated': 'lenguajes actualizados', +'Last name': 'Apellido', +'Last saved on:': 'Guardado en:', +'Layout': 'Diseño de página', +'Layout Plugins': 'Plugins de diseño', +'Layouts': 'Diseños de páginas', +'License for': 'Licencia para', +'Live Chat': 'Chat en vivo', +'loading...': 'cargando...', +'Log In': 'Iniciar sesion', +'Logged in': 'Sesión iniciada', +'Logged out': 'Sesión finalizada', +'Login': 'Inicio de sesión', +'login': 'inicio de sesión', +'Login disabled by administrator': 'Inicio de sesión deshabilitado por el administrador', +'Login to the Administrative Interface': 'Inicio de sesión para la Interfaz Administrativa', +'logout': 'fin de sesión', +'Logout': 'Fin de sesión', +'Lost Password': 'Contraseña perdida', +'Lost password?': '¿Olvidó la contraseña?', +'lost password?': '¿olvidó la contraseña?', +'Main Menu': 'Menú principal', +'Manage %(action)s': 'Gestionar %(action)s', +'Manage Access Control': 'Gestionar control de acceso', +'Manage Cache': 'Gestionar la Caché', +'Memberships': 'Membresias', +'Menu Model': 'Modelo "menu"', +'merge': 'Combinar', +'Models': 'Modelos', +'models': 'modelos', +'Modified By': 'Modificado Por', +'Modified On': 'Modificado En', +'Modules': 'Módulos', +'modules': 'módulos', +'must be YYYY-MM-DD HH:MM:SS!': '¡debe ser DD/MM/YYYY HH:MM:SS!', +'must be YYYY-MM-DD!': '¡debe ser DD/MM/YYYY!', +'My Sites': 'Mis Sitios', +'Name': 'Nombre', +'New': 'Nuevo', +'New %(entity)s': 'Nuevo %(entity)s', +'new application "%s" created': 'nueva aplicación "%s" creada', +'New password': 'Contraseña nueva', +'New Record': 'Registro nuevo', +'new record inserted': 'nuevo registro insertado', +'next %s rows': 'siguiente %s filas', +'next 100 rows': '100 filas siguientes', +'NO': 'NO', +'No databases in this application': 'No hay bases de datos en esta aplicación', +'No records found': 'No se han encontrado registros', +'Not authorized': 'No autorizado', +'not in': 'no en', +'Number of entries: **%s**': 'Numero de entradas: **%s**', +'Object or table name': 'Nombre del objeto o tabla', +'Old password': 'Contraseña vieja', +'Online book': 'Libro Online', +'Online examples': 'Ejemplos en línea', +'Or': 'O', +'or import from csv file': 'o importar desde archivo CSV', +'or provide application url:': 'o provea URL de la aplicación:', +'Origin': 'Origen', +'Original/Translation': 'Original/Traducción', +'Other Plugins': 'Otros Plugins', +'Other Recipes': 'Otras Recetas', +'Overview': 'Resumen', +'pack all': 'empaquetar todo', +'pack compiled': 'empaquetar compilados', +'Password': 'Contraseña', +'Password changed': 'Contraseña cambiada', +"Password fields don't match": 'Los campos de contraseña no coinciden', +'Password reset': 'Reinicio de contraseña', +'Peeking at file': 'Visualizando archivo', +'Permission': 'Permiso', +'Permissions': 'Permisos', +'Phone': 'Teléfono', +'please input your password again': 'por favor introduzca su contraseña otra vez', +'Plugins': 'Plugins', +'Powered by': 'Este sitio usa', +'Preface': 'Prefacio', +'previous %s rows': 'fila %s anterior', +'previous 100 rows': '100 filas anteriores', +'Profile': 'Perfil', +'Profile updated': 'Perfil actualizado', +'pygraphviz library not found': 'Libreria pygraphviz no encontrada', +'Python': 'Python', +'Query Not Supported: %s': 'Consulta No Soportada: %s', +'Query:': 'Consulta:', +'Quick Examples': 'Ejemplos Rápidos', +'RAM': 'RAM', +'RAM Cache Keys': 'Llaves de la Caché en RAM', +'Ram Cleared': 'Ram Limpiada', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'La RAM contiene items con **%(hours)02d** %%{hora(hours)} **%(min)02d** %%{minuto(min)} **%(sec)02d** %%{segundo(sec)} de antiguedad.', +'Recipes': 'Recetas', +'Record': 'Registro', +'Record %(id)s created': 'Registro %(id)s creado', +'Record Created': 'Registro Creado', +'record does not exist': 'el registro no existe', +'Record ID': 'ID de Registro', +'Record id': 'Id de registro', +'register': 'regístrese', +'Register': 'Regístrese', +'Registration identifier': 'Identificador de Registro', +'Registration key': 'Llave de registro', +'Registration successful': 'Registro con éxito', +'reload': 'recargar', +'Remember me (for 30 days)': 'Recuérdame (durante 30 días)', +'remove compiled': 'eliminar compiladas', +'Request reset password': 'Solicitar reinicio de contraseña', +'Reset password': 'Reiniciar contraseña', +'Reset Password key': 'Restaurar Llave de la Contraseña', +'Resolve Conflict file': 'archivo Resolución de Conflicto', +'restore': 'restaurar', +'Retrieve username': 'Recuperar nombre de usuario', +'revert': 'revertir', +'Role': 'Rol', +'Roles': 'Roles', +'Rows in Table': 'Filas en la tabla', +'Rows selected': 'Filas seleccionadas', +'save': 'guardar', +'Save model as...': 'Guardar modelo como...', +'Saved file hash:': 'Hash del archivo guardado:', +'Search': 'Buscar', +'Semantic': 'Semántica', +'Services': 'Servicios', +'session expired': 'sesión expirada', +'shell': 'terminal', +'Sign Up': 'Registrarse', +'site': 'sitio', +'Size of cache:': 'Tamaño de la Caché:', +'some files could not be removed': 'algunos archivos no pudieron ser removidos', +'start': 'inicio', +'starts with': 'comienza por', +'state': 'estado', +'static': 'estático', +'Static files': 'Archivos estáticos', +'Statistics': 'Estadísticas', +'Stylesheet': 'Hoja de estilo', +'Submit': 'Enviar', +'submit': 'enviar', +'Success!': '¡Correcto!', +'Support': 'Soporte', +'Sure you want to delete this object?': '¿Está seguro que desea eliminar este objeto?', +'Table': 'tabla', +'Table name': 'Nombre de la tabla', +'test': 'probar', +'Testing application': 'Probando aplicación', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "consulta" es una condición como "db.tabla1.campo1==\'valor\'". Algo como "db.tabla1.campo1==db.tabla2.campo2" resulta en un JOIN SQL.', +'the application logic, each URL path is mapped in one exposed function in the controller': 'la lógica de la aplicación, cada ruta URL se mapea en una función expuesta en el controlador', +'The Core': 'El Núcleo', +'the data representation, define database tables and sets': 'la representación de datos, define tablas y conjuntos de base de datos', +'The output of the file is a dictionary that was rendered by the view %s': 'La salida de dicha función es un diccionario que es desplegado por la vista %s', +'the presentations layer, views are also known as templates': 'la capa de presentación, las vistas también son llamadas plantillas', +'The Views': 'Las Vistas', +'There are no controllers': 'No hay controladores', +'There are no models': 'No hay modelos', +'There are no modules': 'No hay módulos', +'There are no static files': 'No hay archivos estáticos', +'There are no translators, only default language is supported': 'No hay traductores, sólo el lenguaje por defecto es soportado', +'There are no views': 'No hay vistas', +'these files are served without processing, your images go here': 'estos archivos son servidos sin procesar, sus imágenes van aquí', +'This App': 'Esta Aplicación', +'This email already has an account': 'Este correo electrónico ya tiene una cuenta', +'This is a copy of the scaffolding application': 'Esta es una copia de la aplicación de andamiaje', +'This is the %(filename)s template': 'Esta es la plantilla %(filename)s', +'Ticket': 'Tiquete', +'Time in Cache (h:m:s)': 'Tiempo en Caché (h:m:s)', +'Timestamp': 'Marca de tiempo', +'to previous version.': 'a la versión previa.', +'To emulate a breakpoint programatically, write:': 'Emular un punto de ruptura programáticamente, escribir:', +'to use the debugger!': '¡usar el depurador!', +'toggle breakpoint': 'alternar punto de ruptura', +'Toggle comment': 'Alternar comentario', +'Toggle Fullscreen': 'Alternar pantalla completa', +'too short': 'demasiado corto', +'Traceback': 'Rastrear', +'translation strings for the application': 'cadenas de caracteres de traducción para la aplicación', +'try': 'intente', +'try something like': 'intente algo como', +'TSV (Excel compatible)': 'TSV (compatible con Excel)', +'TSV (Excel compatible, hidden cols)': 'TSV (compatible con Excel, columnas ocultas)', +'Twitter': 'Twitter', +'Unable to check for upgrades': 'No es posible verificar la existencia de actualizaciones', +'unable to create application "%s"': 'no es posible crear la aplicación "%s"', +'unable to delete file "%(filename)s"': 'no es posible eliminar el archivo "%(filename)s"', +'Unable to download': 'No es posible la descarga', +'Unable to download app': 'No es posible descargar la aplicación', +'unable to parse csv file': 'no es posible analizar el archivo CSV', +'unable to uninstall "%s"': 'no es posible instalar "%s"', +'uncheck all': 'desmarcar todos', +'uninstall': 'desinstalar', +'unknown': 'desconocido', +'update': 'actualizar', +'update all languages': 'actualizar todos los lenguajes', +'Update:': 'Actualice:', +'upload application:': 'subir aplicación:', +'Upload existing application': 'Suba esta aplicación', +'upload file:': 'suba archivo:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) para AND, (...)|(...) para OR, y ~(...) para NOT, para crear consultas más complejas.', +'User': 'Usuario', +'User %(id)s is impersonating %(other_id)s': 'El usuario %(id)s está suplantando %(other_id)s', +'User %(id)s Logged-in': 'El usuario %(id)s inició la sesión', +'User %(id)s Logged-out': 'El usuario %(id)s finalizó la sesión', +'User %(id)s Password changed': 'Contraseña del usuario %(id)s cambiada', +'User %(id)s Password reset': 'Contraseña del usuario %(id)s reiniciada', +'User %(id)s Profile updated': 'Actualizado el perfil del usuario %(id)s', +'User %(id)s Registered': 'Usuario %(id)s Registrado', +'User %(id)s Username retrieved': 'Se ha recuperado el nombre de usuario del usuario %(id)s', +'User %(username)s Logged-in': 'El usuario %(username)s inició la sesión', +"User '%(username)s' Logged-in": "El usuario '%(username)s' inició la sesión", +"User '%(username)s' Logged-out": "El usuario '%(username)s' finalizó la sesión", +'User Id': 'Id de Usuario', +'User ID': 'ID de Usuario', +'User Logged-out': 'El usuario finalizó la sesión', +'Username': 'Nombre de usuario', +'Username retrieve': 'Recuperar nombre de usuario', +'Users': 'Usuarios', +'value already in database or empty': 'el valor ya existe en la base de datos o está vacío', +'value not allowed': 'valor no permitido', +'value not in database': 'el valor no está en la base de datos', +'Verify Password': 'Verificar Contraseña', +'Version': 'Versión', +'versioning': 'versionado', +'Videos': 'Vídeos', +'View': 'Vista', +'view': 'vista', +'View %(entity)s': 'Ver %(entity)s', +'Views': 'Vistas', +'views': 'vistas', +'web2py is up to date': 'web2py está actualizado', +'web2py Recent Tweets': 'Tweets Recientes de web2py', +'Welcome': 'Bienvenido', +'Welcome %s': 'Bienvenido %s', +'Welcome to web2py': 'Bienvenido a web2py', +'Welcome to web2py!': '¡Bienvenido a web2py!', +'Which called the function %s located in the file %s': 'La cual llamó la función %s localizada en el archivo %s', +'Working...': 'Trabajando...', +'YES': 'SÍ', +'You are successfully running web2py': 'Usted está ejecutando web2py exitosamente', +'You can modify this application and adapt it to your needs': 'Usted puede modificar esta aplicación y adaptarla a sus necesidades', +'You visited the url %s': 'Usted visitó la url %s', +'Your username is: %(username)s': 'Su nombre de usuario es: %(username)s', +} diff --git a/web2py/applications/SP/languages/fr-ca.py b/web2py/applications/SP/languages/fr-ca.py new file mode 100644 index 0000000..611a107 --- /dev/null +++ b/web2py/applications/SP/languages/fr-ca.py @@ -0,0 +1,244 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'fr-ca', +'!langname!': 'Français (Canadien)', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" est une expression optionnelle comme "champ1=\'nouvellevaleur\'". Vous ne pouvez mettre à jour ou supprimer les résultats d\'un JOIN', +'%s %%{row} deleted': '%s lignes supprimées', +'%s %%{row} updated': '%s lignes mises à jour', +'%s selected': '%s sélectionné', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'about': 'à propos', +'About': 'À propos', +'Access Control': "Contrôle d'accès", +'admin': 'admin', +'Administrative Interface': "Interface d'administration", +'Administrative interface': "Interface d'administration", +'Ajax Recipes': 'Recettes Ajax', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'appadmin is disabled because insecure channel': "appadmin est désactivée parce que le canal n'est pas sécurisé", +'Are you sure you want to delete this object?': 'Êtes-vous sûr de vouloir supprimer cet objet?', +'Authentication': 'Authentification', +'Available Databases and Tables': 'Bases de données et tables disponibles', +'Buy this book': 'Acheter ce livre', +"Buy web2py's book": "Buy web2py's book", +'cache': 'cache', +'Cache': 'Cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'Cannot be empty': 'Ne peut pas être vide', +'change password': 'changer le mot de passe', +'Check to delete': 'Cliquez pour supprimer', +'Check to delete:': 'Cliquez pour supprimer:', +'Clear CACHE?': 'Vider le CACHE?', +'Clear DISK': 'Vider le DISQUE', +'Clear RAM': 'Vider la RAM', +'Client IP': 'IP client', +'Community': 'Communauté', +'Components and Plugins': 'Composants et Plugiciels', +'Config.ini': 'Config.ini', +'Controller': 'Contrôleur', +'Copyright': "Droit d'auteur", +'Created By': 'Créé par', +'Created On': 'Créé le', +'Current request': 'Demande actuelle', +'Current response': 'Réponse actuelle', +'Current session': 'Session en cours', +'customize me!': 'personnalisez-moi!', +'data uploaded': 'données téléchargées', +'Database': 'base de données', +'Database %s select': 'base de données %s selectionnée', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'db': 'db', +'DB Model': 'Modèle BD', +'Delete:': 'Supprimer:', +'Demo': 'Démo', +'Deployment Recipes': 'Recettes de déploiement', +'Description': 'Description', +'design': 'design', +'Design': 'Design', +'DISK': 'DISQUE', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disque vidé', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentation', +"Don't know what to do?": 'Vous ne savez pas quoi faire?', +'done!': 'fait!', +'Download': 'Téléchargement', +'E-mail': 'Courriel', +'Edit': 'Éditer', +'Edit current record': "Modifier l'enregistrement courant", +'edit profile': 'modifier le profil', +'Edit This App': 'Modifier cette application', +'Email and SMS': 'Courriel et texto', +'Enter an integer between %(min)g and %(max)g': 'Enter an integer between %(min)g and %(max)g', +'enter an integer between %(min)g and %(max)g': 'entrer un entier compris entre %(min)g et %(max)g', +'Errors': 'Erreurs', +'export as csv file': 'exporter sous forme de fichier csv', +'FAQ': 'FAQ', +'First name': 'Prénom', +'Forms and Validators': 'Formulaires et Validateurs', +'Free Applications': 'Applications gratuites', +'Function disabled': 'Fonction désactivée', +'Graph Model': 'Représentation graphique du modèle', +'Group %(group_id)s created': '%(group_id)s groupe créé', +'Group ID': 'ID du groupe', +'Group uniquely assigned to user %(id)s': "Groupe unique attribué à l'utilisateur %(id)s", +'Groups': 'Groupes', +'Hello World': 'Bonjour le monde', +'Helping web2py': 'Aider web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Accueil', +'How did you get here?': 'How did you get here?', +'import': 'importer', +'Import/Export': 'Importer/Exporter', +'Index': 'Index', +'insert new': 'insérer un nouveau', +'insert new %s': 'insérer un nouveau %s', +'Internal State': 'État interne', +'Introduction': 'Présentation', +'Invalid email': 'Courriel invalide', +'Invalid Query': 'Requête Invalide', +'invalid request': 'requête invalide', +'Is Active': 'Est actif', +'Key': 'Clé', +'Last name': 'Nom', +'Layout': 'Mise en page', +'Layout Plugins': 'Plugins de mise en page', +'Layouts': 'Mises en page', +'Live chat': 'Clavardage en direct', +'Live Chat': 'Clavardage en direct', +'Loading...': 'Chargement...', +'loading...': 'chargement...', +'Log In': 'Connexion', +'Logged in': 'Connecté', +'login': 'connexion', +'Login': 'Connexion', +'logout': 'déconnexion', +'lost password': 'mot de passe perdu', +'Lost Password': 'Mot de passe perdu', +'Lost password?': 'Mot de passe perdu?', +'lost password?': 'mot de passe perdu?', +'Main Menu': 'Menu principal', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Gérer le Cache', +'Memberships': 'Memberships', +'Menu Model': 'Menu modèle', +'Modified By': 'Modifié par', +'Modified On': 'Modifié le', +'My Sites': 'Mes sites', +'Name': 'Nom', +'New Record': 'Nouvel enregistrement', +'new record inserted': 'nouvel enregistrement inséré', +'next %s rows': '%s prochaine lignes', +'next 100 rows': '100 prochaines lignes', +'No databases in this application': "Cette application n'a pas de bases de données", +'Number of entries: **%s**': 'Number of entries: **%s**', +'Object or table name': 'Objet ou nom de table', +'Online book': 'Online book', +'Online examples': 'Exemples en ligne', +'or import from csv file': "ou importer d'un fichier CSV", +'Origin': 'Origine', +'Other Plugins': 'Autres Plugiciels', +'Other Recipes': 'Autres recettes', +'Overview': 'Présentation', +'password': 'mot de passe', +'Password': 'Mot de passe', +"Password fields don't match": 'Les mots de passe ne correspondent pas', +'Permission': 'Permission', +'Permissions': 'Permissions', +'please input your password again': "S'il vous plaît entrer votre mot de passe à nouveau", +'Plugins': 'Plugiciels', +'Powered by': 'Alimenté par', +'Preface': 'Préface', +'previous %s rows': '%s lignes précédentes', +'previous 100 rows': '100 lignes précédentes', +'profile': 'profil', +'pygraphviz library not found': 'Bibliothèque pygraphviz introuvable', +'Python': 'Python', +'Query:': 'Requête:', +'Quick Examples': 'Exemples Rapides', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram vidée', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Readme': 'Lisez-moi', +'Recipes': 'Recettes', +'Record': 'enregistrement', +'Record %(id)s created': 'Enregistrement %(id)s créé', +'Record %(id)s updated': 'Enregistrement %(id)s modifié', +'Record Created': 'Enregistrement créé', +'record does not exist': "l'archive n'existe pas", +'Record ID': "ID de l'enregistrement", +'Record id': "id de l'enregistrement", +'Record Updated': 'Enregistrement modifié', +'Register': "S'inscrire", +'register': "s'inscrire", +'Registration identifier': "Identifiant d'inscription", +'Registration key': "Clé d'enregistrement", +'Registration successful': 'Inscription réussie', +'Remember me (for 30 days)': 'Se souvenir de moi (pendant 30 jours)', +'Request reset password': 'Demande de réinitialiser le mot clé', +'Reset Password key': 'Réinitialiser le mot clé', +'Resources': 'Ressources', +'Role': 'Rôle', +'Roles': 'Rôles', +'Rows in Table': 'Lignes du tableau', +'Rows selected': 'Lignes sélectionnées', +'Save model as...': 'Enregistrer le modèle sous...', +'Semantic': 'Sémantique', +'Services': 'Services', +'Sign Up': "S'inscrire", +'Size of cache:': 'Taille de la mémoire cache:', +'state': 'état', +'Statistics': 'Statistiques', +'Stylesheet': 'Feuille de style', +'submit': 'soumettre', +'Submit': 'Soumettre', +'Support': 'Soutien', +'Sure you want to delete this object?': 'Êtes-vous sûr de vouloir supprimer cet objet?', +'Table': 'tableau', +'Table name': 'Nom du tableau', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "query" est une condition comme "db.table1.champ1==\'valeur\'". Quelque chose comme "db.table1.champ1==db.table2.champ2" résulte en un JOIN SQL.', +'The Core': 'Le noyau', +'The output of the file is a dictionary that was rendered by the view %s': 'La sortie de ce fichier est un dictionnaire qui été restitué par la vue %s', +'The Views': 'Les Vues', +'This App': 'Cette Appli', +'This is a copy of the scaffolding application': "Ceci est une copie de l'application échafaudage", +'Time in Cache (h:m:s)': 'Temps en Cache (h:m:s)', +'Timestamp': 'Horodatage', +'Traceback': 'Traceback', +'Twitter': 'Twitter', +'unable to parse csv file': "incapable d'analyser le fichier cvs", +'Update:': 'Mise à jour:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Employez (...)&(...) pour AND, (...)|(...) pour OR, and ~(...) pour NOT afin de construire des requêtes plus complexes.', +'User': 'Utilisateur', +'User %(id)s Logged-in': 'Utilisateur %(id)s connecté', +'User %(id)s Registered': 'Utilisateur %(id)s enregistré', +'User ID': 'ID utilisateur', +'User Voice': "Voix de l'utilisateur", +'Users': 'Utilisateurs', +'value already in database or empty': 'valeur déjà dans la base ou inexistante', +'Verify Password': 'Vérifiez le mot de passe', +'Videos': 'Vidéos', +'View': 'Vue', +'Web2py': 'Web2py', +'Welcome': 'Bienvenue', +'Welcome %s': 'Bienvenue %s', +'Welcome to web2py': 'Bienvenue à web2py', +'Welcome to web2py!': 'Bienvenue à web2py!', +'Which called the function %s located in the file %s': 'Qui a appelé la fonction %s se trouvant dans le fichier %s', +'Working...': 'Traitement en cours...', +'You are successfully running web2py': 'Vous exécutez avec succès web2py', +'You can modify this application and adapt it to your needs': "Vous pouvez modifier cette application et l'adapter à vos besoins", +'You visited the url %s': "Vous avez visité l'URL %s", +} diff --git a/web2py/applications/SP/languages/fr.py b/web2py/applications/SP/languages/fr.py new file mode 100644 index 0000000..730b048 --- /dev/null +++ b/web2py/applications/SP/languages/fr.py @@ -0,0 +1,243 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'fr', +'!langname!': 'Français', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" est une expression optionnelle comme "champ1=\'nouvellevaleur\'". Vous ne pouvez mettre à jour ou supprimer les résultats d\'un JOIN', +'%s %%{row} deleted': '%s lignes supprimées', +'%s %%{row} updated': '%s lignes mises à jour', +'%s selected': '%s sélectionné', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'about': 'à propos', +'About': 'À propos', +'Access Control': "Contrôle d'accès", +'admin': 'admin', +'Administrative Interface': "Interface d'administration", +'Administrative interface': "Interface d'administration", +'Ajax Recipes': 'Recettes Ajax', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'appadmin is disabled because insecure channel': "appadmin est désactivée parce que le canal n'est pas sécurisé", +'Are you sure you want to delete this object?': 'Êtes-vous sûr de vouloir supprimer cet objet?', +'Authentication': 'Authentification', +'Available Databases and Tables': 'Bases de données et tables disponibles', +'Buy this book': 'Acheter ce livre', +"Buy web2py's book": "Buy web2py's book", +'cache': 'cache', +'Cache': 'Cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'Cannot be empty': 'Ne peut pas être vide', +'change password': 'changer le mot de passe', +'Check to delete': 'Cliquez pour supprimer', +'Check to delete:': 'Cliquez pour supprimer:', +'Clear CACHE?': 'Vider le CACHE?', +'Clear DISK': 'Vider le DISQUE', +'Clear RAM': 'Vider la RAM', +'Client IP': 'IP client', +'Community': 'Communauté', +'Components and Plugins': 'Composants et Plugiciels', +'Config.ini': 'Config.ini', +'Controller': 'Contrôleur', +'Copyright': "Droit d'auteur", +'Created By': 'Créé par', +'Created On': 'Créé le', +'Current request': 'Demande actuelle', +'Current response': 'Réponse actuelle', +'Current session': 'Session en cours', +'customize me!': 'personnalisez-moi!', +'data uploaded': 'données téléchargées', +'Database': 'base de données', +'Database %s select': 'base de données %s selectionnée', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'db': 'db', +'DB Model': 'Modèle BD', +'Delete:': 'Supprimer:', +'Demo': 'Démo', +'Deployment Recipes': 'Recettes de déploiement', +'Description': 'Description', +'design': 'design', +'Design': 'Design', +'DISK': 'DISQUE', +'Disk Cache Keys': 'Clés de cache du disque', +'Disk Cleared': 'Disque vidé', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentation', +"Don't know what to do?": 'Vous ne savez pas quoi faire?', +'done!': 'fait!', +'Download': 'Téléchargement', +'E-mail': 'Courriel', +'Edit': 'Éditer', +'Edit current record': "Modifier l'enregistrement courant", +'edit profile': 'modifier le profil', +'Edit This App': 'Modifier cette application', +'Email and SMS': 'Courriel et texto', +'Enter an integer between %(min)g and %(max)g': 'Enter an integer between %(min)g and %(max)g', +'enter an integer between %(min)g and %(max)g': 'entrez un entier entre %(min)g et %(max)g', +'Errors': 'Erreurs', +'export as csv file': 'exporter sous forme de fichier csv', +'FAQ': 'FAQ', +'First name': 'Prénom', +'Forms and Validators': 'Formulaires et Validateurs', +'Free Applications': 'Applications gratuites', +'Function disabled': 'Fonction désactivée', +'Graph Model': 'Représentation graphique du modèle', +'Group %(group_id)s created': '%(group_id)s groupe créé', +'Group ID': 'ID du groupe', +'Group uniquely assigned to user %(id)s': "Groupe unique attribué à l'utilisateur %(id)s", +'Groups': 'Groupes', +'Hello World': 'Bonjour le monde', +'Helping web2py': 'Aider web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Accueil', +'How did you get here?': 'How did you get here?', +'import': 'importer', +'Import/Export': 'Importer/Exporter', +'Index': 'Index', +'insert new': 'insérer un nouveau', +'insert new %s': 'insérer un nouveau %s', +'Internal State': 'État interne', +'Introduction': 'Présentation', +'Invalid email': 'Courriel invalide', +'Invalid Query': 'Requête Invalide', +'invalid request': 'requête invalide', +'Is Active': 'Est actif', +'Key': 'Clé', +'Last name': 'Nom', +'Layout': 'Mise en page', +'Layout Plugins': 'Plugins de mise en page', +'Layouts': 'Mises en page', +'Live chat': 'Clavardage en direct', +'Live Chat': 'Clavardage en direct', +'Loading...': 'Chargement...', +'loading...': 'chargement...', +'Log In': 'Connexion', +'Logged in': 'Connecté', +'login': 'connexion', +'Login': 'Connexion', +'logout': 'déconnexion', +'lost password': 'mot de passe perdu', +'Lost Password': 'Mot de passe perdu', +'Lost password?': 'Mot de passe perdu?', +'lost password?': 'mot de passe perdu?', +'Main Menu': 'Menu principal', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Gérer le Cache', +'Memberships': 'Memberships', +'Menu Model': 'Menu modèle', +'Modified By': 'Modifié par', +'Modified On': 'Modifié le', +'My Sites': 'Mes sites', +'Name': 'Nom', +'New Record': 'Nouvel enregistrement', +'new record inserted': 'nouvel enregistrement inséré', +'next %s rows': '%s prochaine lignes', +'next 100 rows': '100 prochaines lignes', +'No databases in this application': "Cette application n'a pas de bases de données", +'Number of entries: **%s**': 'Number of entries: **%s**', +'Object or table name': 'Objet ou nom de table', +'Online book': 'Online book', +'Online examples': 'Exemples en ligne', +'or import from csv file': "ou importer d'un fichier CSV", +'Origin': 'Origine', +'Other Plugins': 'Autres Plugiciels', +'Other Recipes': 'Autres recettes', +'Overview': 'Présentation', +'password': 'mot de passe', +'Password': 'Mot de passe', +"Password fields don't match": 'Les mots de passe ne correspondent pas', +'Permission': 'Permission', +'Permissions': 'Permissions', +'please input your password again': "S'il vous plaît entrer votre mot de passe à nouveau", +'Plugins': 'Plugiciels', +'Powered by': 'Alimenté par', +'Preface': 'Préface', +'previous %s rows': '%s lignes précédentes', +'previous 100 rows': '100 lignes précédentes', +'profile': 'profil', +'pygraphviz library not found': 'Bibliothèque pygraphviz introuvable', +'Python': 'Python', +'Query:': 'Requête:', +'Quick Examples': 'Exemples Rapides', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram vidée', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Readme': 'Lisez-moi', +'Recipes': 'Recettes', +'Record': 'enregistrement', +'Record %(id)s created': 'Enregistrement %(id)s créé', +'Record %(id)s updated': 'Enregistrement %(id)s modifié', +'Record Created': 'Enregistrement créé', +'record does not exist': "l'archive n'existe pas", +'Record ID': "ID de l'enregistrement", +'Record id': "id de l'enregistrement", +'Record Updated': 'Enregistrement modifié', +'Register': "S'inscrire", +'register': "s'inscrire", +'Registration identifier': "Identifiant d'inscription", +'Registration key': "Clé d'enregistrement", +'Registration successful': 'Inscription réussie', +'Remember me (for 30 days)': 'Se souvenir de moi (pendant 30 jours)', +'Request reset password': 'Demande de réinitialiser le mot clé', +'Reset Password key': 'Réinitialiser le mot clé', +'Resources': 'Ressources', +'Role': 'Rôle', +'Roles': 'Rôles', +'Rows in Table': 'Lignes du tableau', +'Rows selected': 'Lignes sélectionnées', +'Save model as...': 'Enregistrer le modèle sous...', +'Semantic': 'Sémantique', +'Services': 'Services', +'Sign Up': "S'inscrire", +'Size of cache:': 'Taille de la mémoire cache:', +'state': 'état', +'Statistics': 'Statistiques', +'Stylesheet': 'Feuille de style', +'submit': 'soumettre', +'Submit': 'Soumettre', +'Support': 'Soutien', +'Sure you want to delete this object?': 'Êtes-vous sûr de vouloir supprimer cet objet?', +'Table': 'tableau', +'Table name': 'Nom du tableau', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "requête" est une condition comme "db.table1.champ1==\'valeur\'". Quelque chose comme "db.table1.champ1==db.table2.champ2" résulte en un JOIN SQL.', +'The Core': 'Le noyau', +'The output of the file is a dictionary that was rendered by the view %s': 'La sortie de ce fichier est un dictionnaire qui été restitué par la vue %s', +'The Views': 'Les Vues', +'This App': 'Cette Appli', +'This is a copy of the scaffolding application': "Ceci est une copie de l'application échafaudage", +'Time in Cache (h:m:s)': 'Temps en Cache (h:m:s)', +'Timestamp': 'Horodatage', +'Traceback': 'Traceback', +'Twitter': 'Twitter', +'unable to parse csv file': "incapable d'analyser le fichier cvs", +'Update:': 'Mise à jour:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Employez (...)&(...) pour AND, (...)|(...) pour OR, and ~(...) pour NOT afin de construire des requêtes plus complexes.', +'User': 'User', +'User %(id)s Logged-in': 'Utilisateur %(id)s connecté', +'User %(id)s Registered': 'Utilisateur %(id)s enregistré', +'User ID': 'ID utilisateur', +'User Voice': "Voix de l'utilisateur", +'Users': 'Users', +'Verify Password': 'Vérifiez le mot de passe', +'Videos': 'Vidéos', +'View': 'Présentation', +'Web2py': 'Web2py', +'Welcome': 'Bienvenue', +'Welcome %s': 'Bienvenue %s', +'Welcome to web2py': 'Bienvenue à web2py', +'Welcome to web2py!': 'Bienvenue à web2py!', +'Which called the function %s located in the file %s': 'Qui a appelé la fonction %s se trouvant dans le fichier %s', +'Working...': 'Working...', +'You are successfully running web2py': 'Vous exécutez avec succès web2py', +'You can modify this application and adapt it to your needs': "Vous pouvez modifier cette application et l'adapter à vos besoins", +'You visited the url %s': "Vous avez visité l'URL %s", +} diff --git a/web2py/applications/SP/languages/hi.py b/web2py/applications/SP/languages/hi.py new file mode 100644 index 0000000..5c741e1 --- /dev/null +++ b/web2py/applications/SP/languages/hi.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'hi-in', +'!langname!': 'हिन्दी', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN', +'%s %%{row} deleted': '%s पंक्तियाँ मिटाएँ', +'%s %%{row} updated': '%s पंक्तियाँ अद्यतन', +'%s selected': '%s चुना हुआ', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'About', +'Access Control': 'Access Control', +'admin': 'admin', +'Administrative Interface': 'Administrative Interface', +'Administrative interface': 'प्रशासनिक इंटरफेस के लिए यहाँ क्लिक करें', +'Ajax Recipes': 'Ajax Recipes', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'appadmin is disabled because insecure channel': 'अप आडमिन (appadmin) अक्षम है क्योंकि असुरक्षित चैनल', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Available Databases and Tables': 'उपलब्ध डेटाबेस और तालिका', +'Buy this book': 'Buy this book', +"Buy web2py's book": "Buy web2py's book", +'cache': 'cache', +'Cache': 'Cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'Cannot be empty': 'खाली नहीं हो सकता', +'Change Password': 'पासवर्ड बदलें', +'change password': 'change password', +'Check to delete': 'हटाने के लिए चुनें', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Community': 'Community', +'Components and Plugins': 'Components and Plugins', +'Config.ini': 'Config.ini', +'Controller': 'Controller', +'Copyright': 'Copyright', +'Current request': 'वर्तमान अनुरोध', +'Current response': 'वर्तमान प्रतिक्रिया', +'Current session': 'वर्तमान सेशन', +'customize me!': 'मुझे अनुकूलित (कस्टमाइज़) करें!', +'data uploaded': 'डाटा अपलोड सम्पन्न ', +'Database': 'डेटाबेस', +'Database %s select': 'डेटाबेस %s चुनी हुई', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'db': 'db', +'DB Model': 'DB Model', +'Delete:': 'मिटाना:', +'Demo': 'Demo', +'Deployment Recipes': 'Deployment Recipes', +'design': 'रचना करें', +'Design': 'Design', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentation', +"Don't know what to do?": "Don't know what to do?", +'done!': 'हो गया!', +'Download': 'Download', +'Edit': 'Edit', +'Edit current record': 'वर्तमान रेकॉर्ड संपादित करें ', +'edit profile': 'edit profile', +'Edit Profile': 'प्रोफ़ाइल संपादित करें', +'Edit This App': 'Edit This App', +'Email and SMS': 'Email and SMS', +'Errors': 'Errors', +'export as csv file': 'csv फ़ाइल के रूप में निर्यात', +'FAQ': 'FAQ', +'Forms and Validators': 'Forms and Validators', +'Free Applications': 'Free Applications', +'Graph Model': 'Graph Model', +'Groups': 'Groups', +'Hello from MyApp': 'Hello from MyApp', +'Hello World': 'Hello World', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Home', +'How did you get here?': 'How did you get here?', +'import': 'import', +'Import/Export': 'आयात / निर्यात', +'Index': 'Index', +'insert new': 'नया डालें', +'insert new %s': 'नया %s डालें', +'Internal State': 'आंतरिक स्थिति', +'Introduction': 'Introduction', +'Invalid Query': 'अमान्य प्रश्न', +'invalid request': 'अवैध अनुरोध', +'Key': 'Key', +'Layout': 'Layout', +'Layout Plugins': 'Layout Plugins', +'Layouts': 'Layouts', +'Live Chat': 'Live Chat', +'Log In': 'Log In', +'login': 'login', +'Login': 'लॉग इन', +'logout': 'logout', +'Logout': 'लॉग आउट', +'Lost Password': 'पासवर्ड खो गया', +'Main Menu': 'Main Menu', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Manage Cache', +'Memberships': 'Memberships', +'Menu Model': 'Menu Model', +'My Sites': 'My Sites', +'New Record': 'नया रेकॉर्ड', +'new record inserted': 'नया रेकॉर्ड डाला', +'next %s rows': 'next %s rows', +'next 100 rows': 'अगले 100 पंक्तियाँ', +'No databases in this application': 'इस अनुप्रयोग में कोई डेटाबेस नहीं हैं', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Online book': 'Online book', +'Online examples': 'ऑनलाइन उदाहरण के लिए यहाँ क्लिक करें', +'or import from csv file': 'या csv फ़ाइल से आयात', +'Other Plugins': 'Other Plugins', +'Other Recipes': 'Other Recipes', +'Overview': 'Overview', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Plugins': 'Plugins', +'Powered by': 'Powered by', +'Preface': 'Preface', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'पिछले 100 पंक्तियाँ', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query:': 'प्रश्न:', +'Quick Examples': 'Quick Examples', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Recipes', +'Record': 'Record', +'record does not exist': 'रिकॉर्ड मौजूद नहीं है', +'Record id': 'रिकॉर्ड पहचानकर्ता (आईडी)', +'Register': 'पंजीकृत (रजिस्टर) करना ', +'register': 'register', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'तालिका में पंक्तियाँ ', +'Rows selected': 'चयनित (चुने गये) पंक्तियाँ ', +'Save model as...': 'Save model as...', +'Semantic': 'Semantic', +'Services': 'Services', +'Sign Up': 'Sign Up', +'Size of cache:': 'Size of cache:', +'state': 'स्थिति', +'Statistics': 'Statistics', +'Stylesheet': 'Stylesheet', +'submit': 'submit', +'Support': 'Support', +'Sure you want to delete this object?': 'सुनिश्चित हैं कि आप इस वस्तु को हटाना चाहते हैं?', +'Table': 'तालिका', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.', +'The Core': 'The Core', +'The output of the file is a dictionary that was rendered by the view %s': 'The output of the file is a dictionary that was rendered by the view %s', +'The Views': 'The Views', +'This App': 'This App', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Traceback': 'Traceback', +'Twitter': 'Twitter', +'unable to parse csv file': 'csv फ़ाइल पार्स करने में असमर्थ', +'Update:': 'अद्यतन करना:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.', +'User': 'User', +'Users': 'Users', +'Videos': 'Videos', +'View': 'View', +'Welcome %s': 'Welcome %s', +'Welcome to web2py': 'वेब२पाइ (web2py) में आपका स्वागत है', +'Welcome to web2py!': 'Welcome to web2py!', +'Which called the function %s located in the file %s': 'Which called the function %s located in the file %s', +'Working...': 'Working...', +'You are successfully running web2py': 'You are successfully running web2py', +'You can modify this application and adapt it to your needs': 'You can modify this application and adapt it to your needs', +'You visited the url %s': 'You visited the url %s', +} diff --git a/web2py/applications/SP/languages/hu.py b/web2py/applications/SP/languages/hu.py new file mode 100644 index 0000000..992140e --- /dev/null +++ b/web2py/applications/SP/languages/hu.py @@ -0,0 +1,199 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'hu', +'!langname!': 'Magyar', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN', +'%s %%{row} deleted': '%s sorok törlődtek', +'%s %%{row} updated': '%s sorok frissítődtek', +'%s selected': '%s kiválasztott', +'%Y-%m-%d': '%Y.%m.%d.', +'%Y-%m-%d %H:%M:%S': '%Y.%m.%d. %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'About', +'Access Control': 'Access Control', +'admin': 'admin', +'Administrative Interface': 'Administrative Interface', +'Administrative interface': 'az adminisztrációs felületért kattints ide', +'Ajax Recipes': 'Ajax Recipes', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'appadmin is disabled because insecure channel': 'az appadmin a biztonságtalan csatorna miatt letiltva', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Available Databases and Tables': 'Elérhető adatbázisok és táblák', +'Buy this book': 'Buy this book', +"Buy web2py's book": "Buy web2py's book", +'cache': 'gyorsítótár', +'Cache': 'Cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'Cannot be empty': 'Nem lehet üres', +'change password': 'jelszó megváltoztatása', +'Check to delete': 'Törléshez válaszd ki', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Client IP': 'Client IP', +'Community': 'Community', +'Components and Plugins': 'Components and Plugins', +'Config.ini': 'Config.ini', +'Controller': 'Controller', +'Copyright': 'Copyright', +'Current request': 'Jelenlegi lekérdezés', +'Current response': 'Jelenlegi válasz', +'Current session': 'Jelenlegi folyamat', +'customize me!': 'változtass meg!', +'data uploaded': 'adat feltöltve', +'Database': 'adatbázis', +'Database %s select': 'adatbázis %s kiválasztás', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'db': 'db', +'DB Model': 'DB Model', +'Delete:': 'Töröl:', +'Demo': 'Demo', +'Deployment Recipes': 'Deployment Recipes', +'Description': 'Description', +'design': 'design', +'Design': 'Design', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentation', +"Don't know what to do?": "Don't know what to do?", +'done!': 'kész!', +'Download': 'Download', +'E-mail': 'E-mail', +'Edit': 'Szerkeszt', +'Edit current record': 'Aktuális bejegyzés szerkesztése', +'edit profile': 'profil szerkesztése', +'Edit This App': 'Alkalmazást szerkeszt', +'Email and SMS': 'Email and SMS', +'Errors': 'Errors', +'export as csv file': 'exportál csv fájlba', +'FAQ': 'FAQ', +'First name': 'First name', +'Forms and Validators': 'Forms and Validators', +'Free Applications': 'Free Applications', +'Graph Model': 'Graph Model', +'Group ID': 'Group ID', +'Groups': 'Groups', +'Hello World': 'Hello Világ', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Home', +'How did you get here?': 'How did you get here?', +'import': 'import', +'Import/Export': 'Import/Export', +'Index': 'Index', +'insert new': 'új beillesztése', +'insert new %s': 'új beillesztése %s', +'Internal State': 'Internal State', +'Introduction': 'Introduction', +'Invalid email': 'Invalid email', +'Invalid Query': 'Hibás lekérdezés', +'invalid request': 'hibás kérés', +'Key': 'Key', +'Last name': 'Last name', +'Layout': 'Szerkezet', +'Layout Plugins': 'Layout Plugins', +'Layouts': 'Layouts', +'Live Chat': 'Live Chat', +'Log In': 'Log In', +'login': 'belép', +'logout': 'kilép', +'lost password': 'elveszett jelszó', +'Lost Password': 'Lost Password', +'Main Menu': 'Főmenü', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Manage Cache', +'Memberships': 'Memberships', +'Menu Model': 'Menü model', +'My Sites': 'My Sites', +'Name': 'Name', +'New Record': 'Új bejegyzés', +'new record inserted': 'új bejegyzés felvéve', +'next %s rows': 'next %s rows', +'next 100 rows': 'következő 100 sor', +'No databases in this application': 'Nincs adatbázis ebben az alkalmazásban', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Online book': 'Online book', +'Online examples': 'online példákért kattints ide', +'or import from csv file': 'vagy betöltés csv fájlból', +'Origin': 'Origin', +'Other Plugins': 'Other Plugins', +'Other Recipes': 'Other Recipes', +'Overview': 'Overview', +'Password': 'Password', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Plugins': 'Plugins', +'Powered by': 'Powered by', +'Preface': 'Preface', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'előző 100 sor', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query:': 'Lekérdezés:', +'Quick Examples': 'Quick Examples', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Recipes', +'Record': 'bejegyzés', +'record does not exist': 'bejegyzés nem létezik', +'Record ID': 'Record ID', +'Record id': 'bejegyzés id', +'Register': 'Register', +'register': 'regisztráció', +'Registration key': 'Registration key', +'Reset Password key': 'Reset Password key', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Sorok a táblában', +'Rows selected': 'Kiválasztott sorok', +'Save model as...': 'Save model as...', +'Semantic': 'Semantic', +'Services': 'Services', +'Sign Up': 'Sign Up', +'Size of cache:': 'Size of cache:', +'state': 'állapot', +'Statistics': 'Statistics', +'Stylesheet': 'Stylesheet', +'submit': 'submit', +'Support': 'Support', +'Sure you want to delete this object?': 'Biztos törli ezt az objektumot?', +'Table': 'tábla', +'Table name': 'Table name', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.', +'The Core': 'The Core', +'The output of the file is a dictionary that was rendered by the view %s': 'The output of the file is a dictionary that was rendered by the view %s', +'The Views': 'The Views', +'This App': 'This App', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'Timestamp', +'Traceback': 'Traceback', +'Twitter': 'Twitter', +'unable to parse csv file': 'nem lehet a csv fájlt beolvasni', +'Update:': 'Frissít:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.', +'User': 'User', +'User ID': 'User ID', +'Users': 'Users', +'Videos': 'Videos', +'View': 'Nézet', +'Welcome %s': 'Welcome %s', +'Welcome to web2py': 'Isten hozott a web2py-ban', +'Welcome to web2py!': 'Welcome to web2py!', +'Which called the function %s located in the file %s': 'Which called the function %s located in the file %s', +'Working...': 'Working...', +'You are successfully running web2py': 'You are successfully running web2py', +'You can modify this application and adapt it to your needs': 'You can modify this application and adapt it to your needs', +'You visited the url %s': 'You visited the url %s', +} diff --git a/web2py/applications/SP/languages/id.py b/web2py/applications/SP/languages/id.py new file mode 100644 index 0000000..621d3d8 --- /dev/null +++ b/web2py/applications/SP/languages/id.py @@ -0,0 +1,357 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'id', +'!langname!': 'Indonesian', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN', +'%d days ago': '%d hari yang lalu', +'%d hours ago': '%d jam yang lalu', +'%d minutes ago': '%d menit yang lalu', +'%d months ago': '%d bulan yang lalu', +'%d seconds ago': '%d detik yang lalu', +'%d seconds from now': '%d detik dari sekarang', +'%d weeks ago': '%d minggu yang lalu', +'%d years ago': '%d tahun yang lalu', +'%s %%{row} deleted': '%s %%{row} dihapus', +'%s %%{row} updated': '%s %%{row} diperbarui', +'%s selected': '%s dipilih', +'%Y-%m-%d': '%d-%m-%Y', +'%Y-%m-%d %H:%M:%S': '%d-%m-%Y %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'(requires internet access, experimental)': '(membutuhkan akses internet, eksperimental)', +'(something like "it-it")': '(sesuatu seperti "it-it")', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'1 day ago': '1 hari yang lalu', +'1 hour ago': '1 jam yang lalu', +'1 minute ago': '1 menit yang lalu', +'1 month ago': '1 bulan yang lalu', +'1 second ago': '1 detik yang lalu', +'1 week ago': '1 minggu yang lalu', +'1 year ago': '1 tahun yang lalu', +'< Previous': '< Sebelumnya', +'?': '?', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'Tentang', +'About application': 'Tentang Aplikasi', +'Access Control': 'Access Control', +'Add': 'Tambah', +'Additional code for your application': 'Tambahan kode untuk aplikasi Anda', +'Address': 'Alamat', +'admin': 'admin', +'Admin language': 'Bahasa Admin', +'administrative interface': 'antarmuka administrative', +'Administrator Password:': 'Administrator Kata Sandi:', +'Ajax Recipes': 'Resep Ajax', +'An error occured, please %s the page': 'Terjadi kesalahan, silakan %s halaman', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'And': 'Dan', +'and rename it:': 'dan memberi nama baru itu:', +'Answer': 'Jawaban', +'appadmin is disabled because insecure channel': 'AppAdmin dinonaktifkan karena kanal tidak aman', +'application "%s" uninstalled': 'applikasi "%s" dihapus', +'application compiled': 'aplikasi dikompilasi', +'Application name:': 'Nama Applikasi:', +'are not used yet': 'tidak digunakan lagi', +'Are you sure you want to delete this object?': 'Apakah Anda yakin ingin menghapus ini?', +'Are you sure you want to uninstall application "%s"?': 'Apakah Anda yakin ingin menghapus aplikasi "%s"?', +'Available Databases and Tables': 'Database dan Tabel yang tersedia', +'Back': 'Kembali', +'Buy this book': 'Beli buku ini', +"Buy web2py's book": "Buy web2py's book", +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'cache, kesalahan dan sesi dibersihkan', +'can be a git repo': 'bisa menjadi repo git', +'Cancel': 'Batalkan', +'Cannot be empty': 'Tidak boleh kosong', +'Change admin password': 'Ubah kata sandi admin', +'Change password': 'Ubah kata sandi', +'Check for upgrades': 'Periksa upgrade', +'Check to delete': 'Centang untuk menghapus', +'Checking for upgrades...': 'Memeriksa untuk upgrade...', +'Clean': 'Bersih', +'Clear': 'Hapus', +'Clear CACHE?': 'Hapus CACHE?', +'Clear DISK': 'Hapus DISK', +'Clear RAM': 'Hapus RAM', +'Click row to expand traceback': 'Klik baris untuk memperluas traceback', +'Close': 'Tutup', +'collapse/expand all': 'kempis / memperluas semua', +'Community': 'Komunitas', +'Compile': 'Kompilasi', +'compiled application removed': 'aplikasi yang dikompilasi dihapus', +'Components and Plugins': 'Komponen dan Plugin', +'Config.ini': 'Config.ini', +'contains': 'mengandung', +'Controller': 'Controller', +'Controllers': 'Kontrolir', +'controllers': 'kontrolir', +'Copyright': 'Hak Cipta', +'Count': 'Hitung', +'Create': 'Buat', +'create file with filename:': 'buat file dengan nama:', +'created by': 'dibuat oleh', +'CSV (hidden cols)': 'CSV (kolom tersembunyi)', +'Current request': 'Current request', +'Current response': 'Current response', +'Current session': 'Current session', +'currently running': 'sedang berjalan', +'data uploaded': 'data diunggah', +'Database': 'Database', +'Database %s select': 'Memilih Database %s', +'database administration': 'administrasi database', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'db': 'db', +'DB Model': 'DB Model', +'defines tables': 'mendefinisikan tabel', +'Delete': 'Hapus', +'delete all checked': 'menghapus semua yang di centang', +'Delete this file (you will be asked to confirm deletion)': 'Hapus file ini (Anda akan diminta untuk mengkonfirmasi penghapusan)', +'Delete:': 'Hapus:', +'Demo': 'Demo', +'Deployment Recipes': 'Deployment Recipes', +'Description': 'Keterangan', +'design': 'disain', +'Design': 'Design', +'direction: ltr': 'petunjuk: ltr', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Dihapus', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Dokumentasi', +"Don't know what to do?": 'Tidak tahu apa yang harus dilakukan?', +'done!': 'selesai!', +'Download': 'Unduh', +'Download .w2p': 'Unduh .w2p', +'download layouts': 'unduh layouts', +'download plugins': 'unduh plugins', +'Duration': 'Durasi', +'Edit': 'Mengedit', +'Edit application': 'Mengedit Aplikasi', +'Edit current record': 'Edit current record', +'Email and SMS': 'Email and SMS', +'Email sent': 'Email dikirim', +'enter a valid email address': 'masukkan alamat email yang benar', +'enter a valid URL': 'masukkan URL yang benar', +'enter a value': 'masukkan data', +'Error': 'Kesalahan', +'Error logs for "%(app)s"': 'Catatan kesalahan untuk "%(app)s"', +'Errors': 'Kesalahan', +'export as csv file': 'ekspor sebagai file csv', +'Export:': 'Ekspor:', +'exposes': 'menghadapkan', +'extends': 'meluaskan', +'FAQ': 'FAQ', +'filter': 'menyaring', +'First Name': 'Nama Depan', +'Forgot username?': 'Lupa nama pengguna?', +'Forms and Validators': 'Forms and Validators', +'Free Applications': 'Aplikasi Gratis', +'Gender': 'Jenis Kelamin', +'Graph Model': 'Graph Model', +'Group %(group_id)s created': 'Grup %(group_id)s dibuat', +'Group uniquely assigned to user %(id)s': 'Grup unik yang diberikan kepada pengguna %(id)s', +'Groups': 'Grup', +'Guest': 'Tamu', +'Hello World': 'Halo Dunia', +'Help': 'Bantuan', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Halaman Utama', +'How did you get here?': 'Bagaimana kamu bisa di sini?', +'Image': 'Gambar', +'import': 'impor', +'Import/Export': 'Impor/Ekspor', +'includes': 'termasuk', +'Install': 'Memasang', +'Installation': 'Instalasi', +'Installed applications': 'Aplikasi yang diinstal', +'Internal State': 'Internal State', +'Introduction': 'Pengenalan', +'Invalid email': 'Email tidak benar', +'Invalid Query': 'Invalid Query', +'invalid request': 'invalid request', +'Key': 'Key', +'Language': 'Bahasa', +'languages': 'bahasa', +'Languages': 'Bahasa', +'Last Name': 'Nama Belakang', +'Layout': 'Layout', +'License for': 'Lisensi untuk', +'Live Chat': 'Live Chat', +'loading...': 'sedang memuat...', +'Log In': 'Log In', +'Logged in': 'Masuk', +'Logged out': 'Keluar', +'Login': 'Masuk', +'Login to the Administrative Interface': 'Masuk ke antarmuka Administrasi', +'Logout': 'Keluar', +'Lost Password': 'Lupa Kata Sandi', +'Lost password?': 'Lupa kata sandi?', +'Maintenance': 'Pemeliharaan', +'Manage': 'Mengelola', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Mengelola Cache', +'Memberships': 'Memberships', +'Menu Model': 'Menu Model', +'Models': 'Model', +'models': 'model', +'Modules': 'Modul', +'modules': 'modul', +'My Sites': 'Situs Saya', +'New': 'Baru', +'new application "%s" created': 'aplikasi baru "%s" dibuat', +'New password': 'Kata sandi baru', +'New Record': 'New Record', +'new record inserted': 'new record inserted', +'New simple application': 'Aplikasi baru sederhana', +'News': 'Berita', +'next %s rows': 'next %s rows', +'next 100 rows': '100 baris berikutnya', +'Next >': 'Berikutnya >', +'Next Page': 'Halaman Berikutnya', +'No databases in this application': 'Tidak ada database dalam aplikasi ini', +'No ticket_storage.txt found under /private folder': 'Tidak ditemukan ticket_storage.txt dalam folder /private', +'not a Zip Code': 'bukan Kode Pos', +'Note': 'Catatan', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Old password': 'Kata sandi lama', +'Online book': 'Online book', +'Online examples': 'Contoh Online', +'Or': 'Atau', +'or alternatively': 'atau alternatif', +'Or Get from URL:': 'Atau Dapatkan dari URL:', +'or import from csv file': 'atau impor dari file csv', +'Other Plugins': 'Plugin Lainnya', +'Other Recipes': 'Resep Lainnya', +'Overview': 'Ikhtisar', +'Overwrite installed app': 'Ikhtisar app yang terinstall', +'Pack all': 'Pak semua', +'Pack compiled': 'Pak yang telah dikompilasi', +'Pack custom': 'Pak secara kustomisasi', +'Password': 'Kata sandi', +'Password changed': 'Kata sandi berubah', +"Password fields don't match": 'Kata sandi tidak sama', +'Permission': 'Permission', +'Permissions': 'Permissions', +'please input your password again': 'silahkan masukan kata sandi anda lagi', +'plugins': 'plugin', +'Plugins': 'Plugin', +'Plural-Forms:': 'Bentuk-Jamak:', +'Powered by': 'Didukung oleh', +'Preface': 'Pendahuluan', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '100 baris sebelumnya', +'Previous Page': 'Halaman Sebelumnya', +'Private files': 'File pribadi', +'private files': 'file pribadi', +'Profile': 'Profil', +'Profile updated': 'Profil diperbarui', +'Project Progress': 'Perkembangan Proyek', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query:': 'Query:', +'Quick Examples': 'Contoh Cepat', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Dihapus', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Resep', +'Record': 'Record', +'record does not exist': 'record does not exist', +'Record id': 'Record id', +'Register': 'Daftar', +'Registration successful': 'Pendaftaran berhasil', +'reload': 'memuat kembali', +'Reload routes': 'Memuat rute kembali', +'Remember me (for 30 days)': 'Ingat saya (selama 30 hari)', +'Remove compiled': 'Hapus Kompilasi', +'Request reset password': 'Meminta reset kata sandi', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Baris dalam Tabel', +'Rows selected': 'Baris dipilih', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Jalankan tes di file ini (untuk menjalankan semua file, Anda juga dapat menggunakan tombol berlabel 'test')", +'Running on %s': 'Berjalan di %s', +'Save model as...': 'Simpan model sebagai ...', +'Save profile': 'Simpan profil', +'Search': 'Cari', +'Select Files to Package': 'Pilih Berkas untuk Paket', +'Send Email': 'Kirim Email', +'Service': 'Layanan', +'Services': 'Services', +'Sign Up': 'Sign Up', +'Site': 'Situs', +'Size of cache:': 'Ukuran cache:', +'starts with': 'dimulai dengan', +'state': 'state', +'Static': 'Statis', +'static': 'statis', +'Statistics': 'Statistik', +'Stylesheet': 'Stylesheet', +'submit': 'submit', +'Support': 'Mendukung', +'Table': 'Tabel', +'test': 'tes', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.', +'The application logic, each URL path is mapped in one exposed function in the controller': 'Logika aplikasi, setiap jalur URL dipetakan dalam satu fungsi terpapar di kontrolir', +'The Core': 'The Core', +'The data representation, define database tables and sets': 'Representasi data, mendefinisikan tabel database dan set', +'The output of the file is a dictionary that was rendered by the view %s': 'The output of the file is a dictionary that was rendered by the view %s', +'The Views': 'The Views', +'There are no plugins': 'Tidak ada plugin', +'There are no private files': 'Tidak ada file pribadi', +'These files are not served, they are only available from within your app': 'File-file ini tidak dilayani, mereka hanya tersedia dari dalam aplikasi Anda', +'These files are served without processing, your images go here': 'File-file ini disajikan tanpa pengolahan, gambar Anda di sini', +'This App': 'App Ini', +'Time in Cache (h:m:s)': 'Waktu di Cache (h: m: s)', +'To create a plugin, name a file/folder plugin_[name]': 'Untuk membuat sebuah plugin, nama file / folder plugin_ [nama]', +'too short': 'terlalu pendek', +'Traceback': 'Traceback', +'Translation strings for the application': 'Terjemahan string untuk aplikasi', +'Try the mobile interface': 'Coba antarmuka ponsel', +'Twitter': 'Twitter', +'Unable to download because:': 'Tidak dapat mengunduh karena:', +'unable to parse csv file': 'tidak mampu mengurai file csv', +'update all languages': 'memperbarui semua bahasa', +'Update:': 'Perbarui:', +'Upload': 'Unggah', +'Upload a package:': 'Unggah sebuah paket:', +'Upload and install packed application': 'Upload dan pasang aplikasi yang dikemas', +'upload file:': 'unggah file:', +'upload plugin file:': 'unggah file plugin:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.', +'User': 'User', +'User %(id)s Logged-in': 'Pengguna %(id)s Masuk', +'User %(id)s Logged-out': 'Pengguna %(id)s Keluar', +'User %(id)s Password changed': 'Pengguna %(id)s Kata Sandi berubah', +'User %(id)s Password reset': 'Pengguna %(id)s Kata Sandi telah direset', +'User %(id)s Profile updated': 'Pengguna %(id)s Profil diperbarui', +'User %(id)s Registered': 'Pengguna %(id)s Terdaftar', +'Users': 'Users', +'value already in database or empty': 'data sudah ada dalam database atau kosong', +'value not allowed': 'data tidak benar', +'value not in database': 'data tidak ada dalam database', +'Verify Password': 'Verifikasi Kata Sandi', +'Version': 'Versi', +'Videos': 'Videos', +'View': 'Lihat', +'Views': 'Lihat', +'views': 'lihat', +'Web Framework': 'Kerangka Web', +'web2py is up to date': 'web2py terbaru', +'web2py Recent Tweets': 'Tweet web2py terbaru', +'Website': 'Situs Web', +'Welcome': 'Selamat Datang', +'Welcome to web2py!': 'Selamat Datang di web2py!', +'Which called the function %s located in the file %s': 'Which called the function %s located in the file %s', +'Working...': 'Working...', +'You are successfully running web2py': 'Anda berhasil menjalankan web2py', +'You can modify this application and adapt it to your needs': 'Anda dapat memodifikasi aplikasi ini dan menyesuaikan dengan kebutuhan Anda', +'You visited the url %s': 'Anda mengunjungi url %s', +} diff --git a/web2py/applications/SP/languages/it.py b/web2py/applications/SP/languages/it.py new file mode 100644 index 0000000..2b12399 --- /dev/null +++ b/web2py/applications/SP/languages/it.py @@ -0,0 +1,286 @@ +# -*- coding: utf-8 -*- +{ +'!=': '!=', +'!langcode!': 'it', +'!langname!': 'Italiano', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" è un\'espressione opzionale come "campo1=\'nuovo valore\'". Non si può fare "update" o "delete" dei risultati di un JOIN ', +'%(nrows)s records found': '%(nrows)s record trovati', +'%d seconds ago': '%d secondi fa', +'%s %%{row} deleted': '%s righe ("record") cancellate', +'%s %%{row} updated': '%s righe ("record") modificate', +'%s selected': '%s selezionato', +'%Y-%m-%d': '%d/%m/%Y', +'%Y-%m-%d %H:%M:%S': '%d/%m/%Y %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'<': '<', +'<=': '<=', +'=': '=', +'>': '>', +'>=': '>=', +'?': '?', +'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'@markmin\x01Number of entries: **%s**': 'Numero di entità: **%s**', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'About', +'Access Control': 'Controllo Accessi', +'Add': 'Aggiungi', +'admin': 'admin', +'Administrative Interface': 'Interfaccia Amministrativa', +'Administrative interface': 'Interfaccia amministrativa', +'Ajax Recipes': 'Ajax Recipes', +'An error occured, please %s the page': 'È stato rilevato un errore, prego %s la pagina', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'And': 'E', +'API Example': 'API Example', +'appadmin is disabled because insecure channel': 'Amministrazione (appadmin) disabilitata: comunicazione non sicura', +'Are you sure you want to delete this object?': 'Sicuro di voler cancellare questo oggetto ?', +'Available Databases and Tables': 'Database e tabelle disponibili', +'Back': 'Indietro', +'Buy this book': 'Compra questo libro', +"Buy web2py's book": "Buy web2py's book", +'cache': 'cache', +'Cache': 'Cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'Cannot be empty': 'Non può essere vuoto', +'Change password': 'Cambia Password', +'change password': 'Cambia password', +'Check to delete': 'Seleziona per cancellare', +'Clear': 'Resetta', +'Clear CACHE?': 'Resetta CACHE?', +'Clear DISK': 'Resetta DISK', +'Clear RAM': 'Resetta RAM', +'Client IP': 'Client IP', +'Close': 'Chiudi', +'Cognome': 'Cognome', +'Community': 'Community', +'Components and Plugins': 'Componenti and Plugin', +'Config.ini': 'Config.ini', +'contains': 'contiene', +'Controller': 'Controller', +'Copyright': 'Copyright', +'Created By': 'Creato Da', +'Created On': 'Creato Il', +'CSV': 'CSV', +'CSV (hidden cols)': 'CSV (hidden cols)', +'Current request': 'Richiesta (request) corrente', +'Current response': 'Risposta (response) corrente', +'Current session': 'Sessione (session) corrente', +'customize me!': 'Personalizzami!', +'data uploaded': 'dati caricati', +'Database': 'Database', +'Database %s select': 'Database %s select', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'db': 'db', +'DB Model': 'Modello di DB', +'Delete': 'Cancella', +'Delete:': 'Cancella:', +'Demo': 'Demo', +'Deployment Recipes': 'Deployment Recipes', +'Description': 'Descrizione', +'design': 'progetta', +'Design': 'Design', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentazione', +"Don't know what to do?": 'Non sai cosa fare?', +'done!': 'fatto!', +'Download': 'Download', +'E-mail': 'E-mail', +'Edit': 'Modifica', +'Edit current record': 'Modifica record corrente', +'edit profile': 'modifica profilo', +'Edit This App': 'Modifica questa applicazione', +'Email and SMS': 'Email e SMS', +'Email non valida': 'Email non valida', +'enter a number between %(min)g and %(max)g': 'enter a number between %(min)g and %(max)g', +'Enter an integer between %(min)g and %(max)g': 'Enter an integer between %(min)g and %(max)g', +'enter an integer between %(min)g and %(max)g': 'inserisci un intero tra %(min)g e %(max)g', +'Errors': 'Errori', +'Errors in form, please check it out.': 'Errori nel form, ricontrollalo', +'export as csv file': 'esporta come file CSV', +'Export:': 'Esporta:', +'FAQ': 'FAQ', +'First name': 'Nome', +'Forgot username?': 'Dimenticato lo username?', +'Forms and Validators': 'Forms and Validators', +'Free Applications': 'Free Applications', +'Graph Model': 'Graph Model', +'Grid Example': 'Grid Example', +'Group %(group_id)s created': 'Group %(group_id)s created', +'Group ID': 'ID Gruppo', +'Group uniquely assigned to user %(id)s': 'Group uniquely assigned to user %(id)s', +'Groups': 'Groups', +'hello': 'hello', +'hello world': 'salve mondo', +'Hello World': 'Salve Mondo', +'Hello World in a flash!': 'Salve Mondo in un flash!', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Home', +'How did you get here?': 'Come sei arrivato qui?', +'HTML': 'HTML', +'import': 'importa', +'Import/Export': 'Importa/Esporta', +'Index': 'Indice', +'insert new': 'inserisci nuovo', +'insert new %s': 'inserisci nuovo %s', +'Internal State': 'Stato interno', +'Introduction': 'Introduzione', +'Invalid email': 'Email non valida', +'Invalid login': 'Login non valido', +'Invalid Query': 'Richiesta (query) non valida', +'invalid request': 'richiesta non valida', +'Is Active': "E' attivo", +'Key': 'Chiave', +'Last name': 'Cognome', +'Layout': 'Layout', +'Layout Plugins': 'Layout Plugins', +'Layouts': 'Layouts', +'Live Chat': 'Live Chat', +'Log In': 'Log In', +'Logged in': 'Loggato', +'Logged out': 'Disconnesso', +'login': 'accesso', +'Login': 'Login', +'logout': 'uscita', +'Logout': 'Logout', +'Lost Password': 'Password Smarrita', +'Lost password?': 'Password smarrita?', +'lost password?': 'dimenticato la password?', +'Main Menu': 'Menu principale', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Manage Cache', +'Memberships': 'Memberships', +'Menu Model': 'Menu Modelli', +'Modified By': 'Modificato da', +'Modified On': 'Modificato il', +'My Sites': 'My Sites', +'Name': 'Nome', +'New': 'Nuovo', +'New password': 'Nuova password', +'New Record': 'Nuovo elemento (record)', +'new record inserted': 'nuovo record inserito', +'next %s rows': 'next %s rows', +'next 100 rows': 'prossime 100 righe', +'No databases in this application': 'Nessun database presente in questa applicazione', +'No records found': 'Nessun record trovato', +'Nome': 'Nome', +'Non può essere vuoto': 'Non può essere vuoto', +'not authorized': 'non autorizzato', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Object or table name': 'Oggeto o nome tabella', +'Old password': 'Vecchia password', +'Online book': 'Online book', +'Online examples': 'Vedere gli esempi', +'Or': 'O', +'or import from csv file': 'oppure importa da file CSV', +'Origin': 'Origine', +'Other Plugins': 'Other Plugins', +'Other Recipes': 'Other Recipes', +'Overview': 'Overview', +'Password': 'Password', +"Password fields don't match": 'I campi password non sono uguali', +'Permission': 'Permission', +'Permissions': 'Permissions', +'please input your password again': 'perfavore reimmeti la tua password', +'Plugins': 'Plugins', +'Powered by': 'Powered by', +'Preface': 'Preface', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '100 righe precedenti', +'Profile': 'Profilo', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query:': 'Richiesta (query):', +'Quick Examples': 'Quick Examples', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Recipes', +'Record': 'Record', +'record does not exist': 'il record non esiste', +'Record ID': 'Record ID', +'Record id': 'Record id', +'Register': 'Registrati', +'register': 'registrazione', +'Registration identifier': 'Registration identifier', +'Registration key': 'Chiave di Registazione', +'Registration successful': 'Registrazione avvenuta', +'reload': 'reload', +'Remember me (for 30 days)': 'Ricordami (per 30 giorni)', +'Request reset password': 'Richiedi il reset della password', +'Reset Password key': 'Resetta chiave Password ', +'Role': 'Ruolo', +'Roles': 'Roles', +'Rows in Table': 'Righe nella tabella', +'Rows selected': 'Righe selezionate', +'Save model as...': 'Salva modello come...', +'Save profile': 'Salva profilo', +'Search': 'Ricerca', +'Semantic': 'Semantic', +'Services': 'Servizi', +'Sign Up': 'Sign Up', +'Sign up': 'Sign up', +'Size of cache:': 'Size of cache:', +'starts with': 'comincia con', +'state': 'stato', +'Statistics': 'Statistics', +'Stylesheet': 'Foglio di stile (stylesheet)', +'submit': 'Inviai', +'Submit': 'Invia', +'Support': 'Support', +'Sure you want to delete this object?': 'Vuoi veramente cancellare questo oggetto?', +'Table': 'tabella', +'Table name': 'Nome tabella', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La richiesta (query) è una condizione come ad esempio "db.tabella1.campo1==\'valore\'". Una condizione come "db.tabella1.campo1==db.tabella2.campo2" produce un "JOIN" SQL.', +'The Core': 'The Core', +'The output of the file is a dictionary that was rendered by the view %s': 'L\'output del file è un "dictionary" che è stato visualizzato dalla vista %s', +'The Views': 'The Views', +'This App': 'This App', +'This email already has an account': 'This email already has an account', +'This is a copy of the scaffolding application': "Questa è una copia dell'applicazione di base (scaffold)", +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'Ora (timestamp)', +'too short': 'troppo corto', +'Traceback': 'Traceback', +'TSV (Excel compatible)': 'TSV (Excel compatibile)', +'TSV (Excel compatible, hidden cols)': 'TSV (Excel compatibile, hidden cols)', +'Twitter': 'Twitter', +'unable to parse csv file': 'non riesco a decodificare questo file CSV', +'Update': 'Aggiorna', +'Update:': 'Aggiorna:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Per costruire richieste (query) più complesse si usano (...)&(...) come "e" (AND), (...)|(...) come "o" (OR), e ~(...) come negazione (NOT).', +'User': 'User', +'User %(id)s Logged-in': 'User %(id)s Logged-in', +'User %(id)s Logged-out': 'User %(id)s Logged-out', +'User %(id)s Password changed': 'User %(id)s Password changed', +'User %(id)s Password reset': 'User %(id)s Password reset', +'User %(id)s Profile updated': 'User %(id)s Profile updated', +'User %(id)s Registered': 'User %(id)s Registered', +'User ID': 'ID Utente', +'Users': 'Users', +'value already in database or empty': 'valore già presente nel database o vuoto', +'Verify Password': 'Verifica Password', +'Videos': 'Videos', +'View': 'Vista', +'Welcome': 'Benvenuto', +'Welcome %s': 'Benvenuto %s', +'Welcome to web2py': 'Benvenuto su web2py', +'Welcome to web2py!': 'Benvenuto in web2py!', +'Which called the function %s located in the file %s': 'che ha chiamato la funzione %s presente nel file %s', +'Wiki Example': 'Wiki Example', +'Working...': 'Working...', +'XML': 'XML', +'You are successfully running web2py': 'Stai eseguendo web2py con successo', +'You can modify this application and adapt it to your needs': 'Puoi modificare questa applicazione adattandola alle tue necessità', +'You visited the url %s': "Hai visitato l'URL %s", +} diff --git a/web2py/applications/SP/languages/my-mm.py b/web2py/applications/SP/languages/my-mm.py new file mode 100644 index 0000000..38bd352 --- /dev/null +++ b/web2py/applications/SP/languages/my-mm.py @@ -0,0 +1,299 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'my-mm', +'!langname!': 'မြန်မာ', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN', +'%s %%{row} deleted': '%s %%{row} ဖျက်ပြီးပြီ', +'%s %%{row} updated': '%s %%{row} ပြင်ပြီးပြီ', +'%s selected': '%s ခု ရွေးထားသည်', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(something like "it-it")', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'အကြောင်း', +'Access Control': 'အသုံးပြု ခြင်းဆိုင်ရာ ထိန်းချုပ်ရန်', +'Additional code for your application': 'Additional code for your application', +'admin': 'admin', +'Admin language': 'Admin language', +'administrative interface': 'administrative interface', +'Administrative Interface': 'စီမံခန့်ခွဲရာ အင်တာဖေ့စ်', +'Administrator Password:': 'Administrator Password:', +'Ajax Recipes': 'Ajax Recipes', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'and rename it:': 'and rename it:', +'appadmin is disabled because insecure channel': 'စိတ်မချရသော လမ်းကြောင်းမှ ဝင်ရောက်သဖြင့် appadmin ကို အသုံးပြု၍ မရပါ', +'Application name:': 'Application name:', +'are not used': 'အသုံးမပြုပါ', +'are not used yet': 'အသုံးမပြုသေးပါ', +'Are you sure you want to delete this object?': 'သင် ဒီအရာ ဖျက်ရန် သေချာပါသလား။', +'Available Databases and Tables': 'အသုံးပြုနိုင်သော ဒေတာဘေစ့်များနှင့် ဇယားများ', +'Buy this book': 'ဒီစာအုပ်ကို ဝယ်ပါ', +"Buy web2py's book": "Buy web2py's book", +'cache': 'cache', +'Cache': 'Cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'can be a git repo': 'can be a git repo', +'Cannot be empty': 'အလွတ် မဖြစ်ရပါ', +'Change admin password': 'Change admin password', +'Check to delete': 'ဖျက်ရန် စစ်ဆေးပါ', +'Checking for upgrades...': 'အဆင့်မြှင့်တင်မှုများအတွက် စစ်ဆေးနေသည် ...', +'Clean': 'ရှင်းလင်းရန်', +'Clear CACHE?': 'CACHE ကို ရှင်းလင်းမည်မှာ ဟုတ်ပါသလား။', +'Clear DISK': 'DISK ကို ရှင်းလင်းမည်။', +'Clear RAM': 'RAM ကို ရှင်းလင်းမည်။', +'Client IP': 'Client IP', +'collapse/expand all': 'collapse/expand all', +'Community': 'အသိုင်းအဝိုင်း', +'Compile': 'Compile', +'Components and Plugins': 'Components and Plugins', +'Config.ini': 'Config.ini', +'Controller': 'ကွန်ထရိုလာ', +'Controllers': 'ကွန်ထရိုလာများ', +'controllers': 'controllers', +'Copyright': 'မူပိုင်ခွင့်', +'Create': 'ဖန်တီးရန်', +'create file with filename:': 'create file with filename:', +'Create/Upload': 'Create/Upload', +'created by': 'ဖန်းတီးသူ', +'Created By': 'ပြုလုပ်ဖန်တီးသူ', +'Created On': 'ပြုလုပ်ဖန်တီးသည့်အချိန်', +'crontab': 'crontab', +'Current request': 'Current request', +'Current response': 'Current response', +'Current session': 'Current session', +'currently running': 'လက်ရှိတွင် လုပ်ဆောင်နေသည်', +'data uploaded': 'data uploaded', +'Database': 'ဒေတာဘေစ့်', +'Database %s select': 'Database %s select', +'database administration': 'ဒေတာဘေ့(စ်) စီမံခန့်ခွဲခြင်း', +'Database Administration (appadmin)': 'ဒေတာဘေစ့် စီမံခန့်ခွဲခြင်း (appadmin)', +'db': 'db', +'DB Model': 'DB Model', +'Debug': 'အမှားရှာရန်', +'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)', +'Delete:': 'Delete:', +'Demo': 'အစမ်း၊ သရုပ်ပြမှုများ', +'Deploy': 'Deploy', +'Deploy on Google App Engine': 'Deploy on Google App Engine', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deployment Recipes': 'Deployment Recipes', +'Description': 'ဖော်ပြချက်', +'design': 'design', +'Design': 'Design', +'direction: ltr': 'direction: ltr', +'Disable': 'ပိတ်ရန်', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk ရှင်းလင်းပြီးပြီ', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'စာရွက်စာတမ်း အထောက်အကူများ', +"Don't know what to do?": 'ဘာလုပ်ရမည်မသိ ဖြစ်နေပါသလား။', +'done!': 'လုပ်ငန်း ဆောင်ရွက်ပြီးပြီ!', +'Download': 'Download', +'Download layouts from repository': 'Download layouts from repository', +'Download plugins from repository': 'Download plugins from repository', +'E-mail': 'အီးမေးလ်', +'Edit': 'ပြင်ဆင်ရန်', +'Edit application': 'Application ကို ပြင်ရန်', +'Edit current record': 'လက်ရှိ မှတ်တမ်းကို ပြင်ရန်', +'Email and SMS': 'အီးမေးလ်နှင့် SMS', +'Enable': 'ဖွင့်ရန်', +'enter an integer between %(min)g and %(max)g': 'enter an integer between %(min)g and %(max)g', +'Errors': 'အမှားများ', +'export as csv file': ' csv file အနေနဲ့ ထုတ်ပေးရန်', +'exposes': 'exposes', +'extends': 'extends', +'FAQ': 'ဖြစ်လေ့ရှိသော ပြဿနာများ', +'filter': 'filter', +'First name': 'အမည်၏ ပထမဆုံး စာလုံး', +'Forms and Validators': 'Forms and Validators', +'Free Applications': 'အခမဲ့ Applications', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Group ID': 'Group ID', +'Groups': 'အဖွဲ့များ', +'Hello World': 'မင်္ဂလာပါ ကမ္ဘာကြီး။', +'Help': 'အကူအညီ', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'မူလသို့', +'How did you get here?': 'သင် ဘယ်လို ရောက်လာခဲ့သလဲ။', +'import': 'သွင်းယူရန်', +'Import/Export': 'သွင်းယူရန်/ထုတ်ယူရန်', +'includes': 'includes', +'Install': 'Install', +'Installed applications': 'ထည့်သွင်းပြီး application များ', +'Internal State': 'Internal State', +'Introduction': 'မိတ်ဆက်', +'Invalid email': 'အီးမေးလ် ဖြည့်သွင်းမှုမှားနေသည်', +'Invalid Query': 'Invalid Query', +'invalid request': 'invalid request', +'Is Active': 'Is Active', +'Key': 'Key', +'Language': 'ဘာသာစကား', +'languages': 'ဘာသာစကားများ', +'Languages': 'ဘာသာစကားများ', +'Last name': 'မျိုးနွယ်အမည်', +'Layout': 'အပြင်အဆင်', +'Layout Plugins': 'Layout Plugins', +'Layouts': 'အပြင်အဆင်များ', +'Live Chat': 'တိုက်ရိုက် ဆက်သွယ် ပြောကြားရန်', +'Log In': 'Log In', +'Login': 'ဝင်ရောက်အသုံးပြုရန်', +'Login to the Administrative Interface': 'Login to the Administrative Interface', +'Logout': 'ထွက်ရန်', +'Lost Password': 'စကားဝှက် မသိတော့ပါ', +'Lost password?': 'စကားဝှက် မသိတော့ဘူးလား။', +'Manage': 'စီမံခန့်ခွဲရန်', +'Manage %(action)s': '%(action)s ကို စီမံရန်', +'Manage Access Control': 'အသုံးပြုခြင်းဆိုင်ရာ ထိန်းချုပ်မှု စီမံခန့်ခွဲရန်', +'Manage Cache': 'Manage Cache', +'Memberships': 'အသင်းဝင်များ', +'Menu Model': 'Menu Model', +'models': 'models', +'Models': 'Models', +'Modified By': 'ပြင်ဆင်မွမ်းမံသူ', +'Modified On': 'ပြင်ဆင်မွမ်းမံသည့် အချိန်', +'Modules': 'Modules', +'modules': 'modules', +'My Sites': 'ကျွန်ုပ်၏ Site များ', +'Name': 'အမည်', +'New application wizard': 'New application wizard', +'New Record': 'မှတ်တမ်း အသစ်', +'new record inserted': 'မှတ်တမ်း အသစ် ဖြည့်သွင်းပြီးပြီ', +'New simple application': 'ရိုးရိုး application အသစ်', +'next %s rows': 'နောက်အတန်း %s တန်း', +'No databases in this application': 'ဒီ application တွင် မည်သည့် ဒေတာဘေစ့်မှ မရှိပါ', +'no package selected': 'no package selected', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Object or table name': 'Object or table name', +'Online book': 'Online book', +'Online examples': 'အွန်လိုင်း နမူနာများ', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'or import from csv file', +'Origin': 'မူလ အစ', +'Other Plugins': 'အခြား Plugins', +'Other Recipes': 'အခြား Recipes', +'Overview': 'အပေါ်ယံရှုမြင်ခြင်း', +'Overwrite installed app': 'Overwrite installed app', +'Pack all': 'အားလုံးကို ထုပ်ပိုးရန်', +'Pack custom': 'ရွေးချယ်ထုပ်ပိုးရန်', +'Password': 'စကားဝှက်', +"Password fields don't match": 'စကားဝှက်များ ကိုက်ညီမှု မရှိပါ', +'Permission': 'ခွင့်ပြုချက်', +'Permissions': 'ခွင့်ပြုချက်များ', +'please input your password again': 'ကျေးဇူးပြု၍ စကားဝှက်ကို ထပ်မံ ဖြည့်သွင်းပေးပါ', +'Plugins': 'Plugins', +'plugins': 'plugins', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'အားဖြည့်စွမ်းအားပေးသူ', +'Preface': 'နိဒါန်း', +'previous %s rows': 'previous %s rows', +'Private files': 'Private files', +'private files': 'private files', +'pygraphviz library not found': 'pygraphviz library ကို မတွေ့ပါ', +'Python': 'Python', +'Query:': 'Query:', +'Quick Examples': 'အမြန် အသုံးပြုနိုင်သော နမူနာများ', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram ရှင်းလင်းပြီးပြီ', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Recipes', +'Record': 'မှတ်တမ်း', +'record does not exist': 'မှတ်တမ်း မရှိပါ', +'Record ID': 'Record ID', +'Record id': 'Record id', +'Register': 'မှတ်ပုံတင်ရန်', +'Registration identifier': 'Registration identifier', +'Registration key': 'Registration key', +'Reload routes': 'Reload routes', +'Remember me (for 30 days)': 'Remember me (for 30 days)', +'Request reset password': 'စကားဝှက် အသစ် တောင်းဆိုရန်', +'Reset Password key': 'Reset Password key', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Rows in Table', +'Rows selected': 'ရွေးထားသော အတန်းများ', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'Running on %s', +'Save model as...': 'Save model as...', +'Semantic': 'Semantic', +'Services': 'Services', +'shell': 'shell', +'Sign Up': 'Sign Up', +'Site': 'Site', +'Size of cache:': 'Size of cache:', +'Start wizard': 'Start wizard', +'state': 'state', +'static': 'static', +'Static': 'Static', +'Statistics': 'ကိန်းဂဏန်း အချက်အလက်များ', +'Stylesheet': 'Stylesheet', +'submit': 'ပြုလုပ်ပါ', +'Submit': 'Submit', +'Support': 'အထောက်အပံ့', +'Table': 'ဇယား', +'test': 'test', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.', +'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller', +'The Core': 'The Core', +'The data representation, define database tables and sets': 'The data representation, define database tables and sets', +'The output of the file is a dictionary that was rendered by the view %s': 'The output of the file is a dictionary that was rendered by the view %s', +'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates', +'The Views': 'The Views', +'There are no plugins': 'There are no plugins', +'There are no private files': 'There are no private files', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'These files are served without processing, your images go here', +'This App': 'ဒီ App', +'This email already has an account': 'ဒီအီးမေးလ်တွင် အကောင့် ရှိပြီး ဖြစ်ပါသည်', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'Timestamp', +'To create a plugin, name a file/folder plugin_[name]': 'To create a plugin, name a file/folder plugin_[name]', +'Traceback': 'Traceback', +'Translation strings for the application': 'Translation strings for the application', +'Try the mobile interface': 'Try the mobile interface', +'Twitter': 'Twitter', +'unable to parse csv file': 'unable to parse csv file', +'Uninstall': 'Uninstall', +'update all languages': 'update all languages', +'Update:': 'Update:', +'Upload': 'Upload', +'Upload a package:': 'Upload a package:', +'Upload and install packed application': 'Upload and install packed application', +'upload file:': 'upload file:', +'upload plugin file:': 'upload plugin file:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.', +'User': 'အသုံးပြုသူ', +'User ID': 'User ID', +'Users': 'အသုံးပြုသူများ', +'Verify Password': 'စကားဝှက်ကို အတည်ပြုပါ', +'Version': 'Version', +'Versioning': 'Versioning', +'Videos': 'ဗွီဒီယိုများ', +'View': 'ဗျူး', +'views': 'views', +'Views': 'ဗျူးများ', +'Web Framework': 'Web Framework', +'Welcome': 'ကြိုဆိုပါ၏', +'Welcome to web2py!': 'web2py မှ ကြိုဆိုပါသည်။', +'Which called the function %s located in the file %s': 'Which called the function %s located in the file %s', +'Working...': 'ဆောင်ရွက်နေပါသည် ။ ။ ။', +'You are successfully running web2py': 'သင်သည် web2py ကို အောင်မြင်စွာ လည်ပတ်မောင်းနှင်စေပါသည်။', +'You can modify this application and adapt it to your needs': 'သင် ဒီ application ကို ပြုပြင်မွမ်းမံနိုင်ပါသည်။ ထို့အပြင် သင့်လိုအပ်ချက်များနှင့် ကိုက်ညီစေရန် ပြုလုပ်နိုင်ပါသည်။', +'You visited the url %s': 'သင် လည်ပတ်ခဲ့သော URL %s', +'စကားဝှက် အသစ် တောင်းဆိုရန်': 'စကားဝှက် အသစ် တောင်းဆိုရန်', +'မှတ်ပုံတင်ရန်': 'မှတ်ပုံတင်ရန်', +'ဝင်ရောက်အသုံးပြုရန်': 'ဝင်ရောက်အသုံးပြုရန်', +} diff --git a/web2py/applications/SP/languages/my.py b/web2py/applications/SP/languages/my.py new file mode 100644 index 0000000..ef29f27 --- /dev/null +++ b/web2py/applications/SP/languages/my.py @@ -0,0 +1,309 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'my', +'!langname!': 'Malay', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN', +'%d days ago': '%d hari yang lalu', +'%d hours ago': '%d jam yang lalu', +'%d minutes ago': '%d minit yang lalu', +'%d months ago': '%d bulan yang lalu', +'%d seconds ago': '%d saat yang lalu', +'%d seconds from now': '%d saat dari sekarang', +'%d weeks ago': '%d minggu yang lalu', +'%d years ago': '%d tahun yang lalu', +'%s %%{row} deleted': '%s %%{row} dihapuskan', +'%s %%{row} updated': '%s %%{row} dikemas kini', +'%s selected': '%s dipilih', +'%Y-%m-%d': '%d-%m-%Y', +'%Y-%m-%d %H:%M:%S': '%d-%m-%Y %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'(requires internet access, experimental)': '(memerlukan akses internet, percubaan)', +'(something like "it-it")': '(sesuatu seperti "it-it")', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'1 day ago': '1 hari yang lalu', +'1 hour ago': '1 jam yang lalu', +'1 minute ago': '1 minit yang lalu', +'1 month ago': '1 bulan yang lalu', +'1 second ago': '1 saat yang lalu', +'1 week ago': '1 minggu yang lalu', +'1 year ago': '1 tahun yang lalu', +'< Previous': '< Sebelumnya', +'?': '?', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'Mengenai', +'Access Control': 'Access Control', +'Add': 'Tambah', +'admin': 'admin', +'Admin language': 'Bahasa admin', +'Administrator Password:': 'Kata laluan Administrator:', +'Ajax Recipes': 'Resipi Ajax', +'An error occured, please %s the page': 'Kesilapan telah berlaku, sila %s laman', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'And': 'Dan', +'and rename it:': 'dan menamakan itu:', +'appadmin is disabled because insecure channel': 'appadmin is disabled because insecure channel', +'are not used yet': 'tidak digunakan lagi', +'Are you sure you want to delete this object?': 'Apakah anda yakin anda mahu memadam ini?', +'Available Databases and Tables': 'Available Databases and Tables', +'Back': 'Kembali', +'Buy this book': 'Beli buku ini', +"Buy web2py's book": "Buy web2py's book", +'cache': 'cache', +'Cache': 'Cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'cache, kesilapan dan sesi dibersihkan', +'Cancel': 'Batal', +'Cannot be empty': 'Tidak boleh kosong', +'Change admin password': 'Tukar kata laluan admin', +'Change password': 'Tukar kata laluan', +'Check to delete': 'Check to delete', +'Clean': 'Bersihkan', +'Clear': 'Hapus', +'Clear CACHE?': 'Hapus CACHE?', +'Clear DISK': 'Hapus DISK', +'Clear RAM': 'Hapus RAM', +'Click row to expand traceback': 'Klik baris untuk mengembangkan traceback', +'Close': 'Tutup', +'Community': 'Komuniti', +'Components and Plugins': 'Komponen dan Plugin', +'Config.ini': 'Config.ini', +'contains': 'mengandung', +'Controller': 'Controller', +'Copyright': 'Hak Cipta', +'Create': 'Buat', +'create file with filename:': 'mencipta fail dengan nama:', +'created by': 'dicipta oleh', +'Current request': 'Current request', +'Current response': 'Current response', +'Current session': 'Current session', +'currently running': 'sedang berjalan', +'data uploaded': 'data diunggah', +'Database': 'Database', +'Database %s select': 'Database %s select', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'db': 'db', +'DB Model': 'DB Model', +'Delete': 'Hapus', +'Delete this file (you will be asked to confirm deletion)': 'Padam fail ini (anda akan diminta untuk mengesahkan pemadaman)', +'Delete:': 'Hapus:', +'Demo': 'Demo', +'Deployment Recipes': 'Deployment Recipes', +'design': 'disain', +'Design': 'Design', +'direction: ltr': 'arah: ltr', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Dihapuskan', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Dokumentasi', +"Don't know what to do?": 'Tidak tahu apa yang perlu dilakukan?', +'done!': 'selesai!', +'Download': 'Unduh', +'Duration': 'Tempoh', +'Edit current record': 'Edit current record', +'Email : ': 'Emel : ', +'Email and SMS': 'Email and SMS', +'Email sent': 'Emel dihantar', +'enter a valid email address': 'masukkan alamat emel yang benar', +'enter a valid URL': 'masukkan URL yang benar', +'enter a value': 'masukkan data', +'Error': 'Kesalahan', +'Errors': 'Kesalahan', +'export as csv file': 'eksport sebagai file csv', +'Export:': 'Eksport:', +'FAQ': 'FAQ', +'File': 'Fail', +'filter': 'menapis', +'First Name': 'Nama Depan', +'Forgot username?': 'Lupa nama pengguna?', +'Forms and Validators': 'Forms and Validators', +'Free Applications': 'Aplikasi Percuma', +'Gender': 'Jenis Kelamin', +'Graph Model': 'Graph Model', +'Group %(group_id)s created': 'Kumpulan %(group_id)s dicipta', +'Group uniquely assigned to user %(id)s': 'Kumpulan unik yang diberikan kepada pengguna %(id)s', +'Groups': 'Kumpulan', +'Hello World': 'Halo Dunia', +'Help': 'Bantuan', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Laman Utama', +'How did you get here?': 'Bagaimana kamu boleh di sini?', +'Image': 'Gambar', +'import': 'import', +'Import/Export': 'Import/Eksport', +'includes': 'termasuk', +'Install': 'Pasang', +'Installation': 'Pemasangan', +'Internal State': 'Internal State', +'Introduction': 'Pengenalan', +'Invalid email': 'Emel tidak benar', +'Invalid Query': 'Invalid Query', +'invalid request': 'invalid request', +'Key': 'Key', +'Language': 'Bahasa', +'languages': 'bahasa', +'Languages': 'Bahasa', +'Last Name': 'Nama Belakang', +'Layout': 'Layout', +'License for': 'lesen untuk', +'Live Chat': 'Live Chat', +'loading...': 'sedang memuat...', +'Log In': 'Log In', +'Logged in': 'Masuk', +'Logged out': 'Keluar', +'Login': 'Masuk', +'Logout': 'Keluar', +'Lost Password': 'Lupa Kata Laluan', +'Lost password?': 'Lupa kata laluan?', +'Maintenance': 'Penyelenggaraan', +'Manage': 'Menguruskan', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Menguruskan Cache', +'Memberships': 'Memberships', +'Menu Model': 'Menu Model', +'Models': 'Model', +'models': 'model', +'Modules': 'Modul', +'modules': 'modul', +'My Sites': 'Laman Saya', +'New': 'Baru', +'New password': 'Kata laluan baru', +'New Record': 'New Record', +'new record inserted': 'new record inserted', +'next %s rows': 'next %s rows', +'next 100 rows': '100 baris seterusnya', +'Next >': 'Seterusnya >', +'Next Page': 'Laman Seterusnya', +'No databases in this application': 'No databases in this application', +'No ticket_storage.txt found under /private folder': 'Ticket_storage.txt tidak dijumpai di bawah folder /private', +'not a Zip Code': 'bukan Pos', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Old password': 'Kata laluan lama', +'Online book': 'Online book', +'Online examples': 'Contoh Online', +'Or': 'Atau', +'or alternatively': 'atau sebagai alternatif', +'Or Get from URL:': 'Atau Dapatkan dari URL:', +'or import from csv file': 'atau import dari file csv', +'Other Plugins': 'Plugin Lain', +'Other Recipes': 'Resipi Lain', +'Overview': 'Tinjauan', +'Pack all': 'Mengemaskan semua', +'Password': 'Kata laluan', +'Password changed': 'Kata laluan berubah', +"Password fields don't match": 'Kata laluan tidak sama', +'Permission': 'Permission', +'Permissions': 'Permissions', +'please input your password again': 'sila masukan kata laluan anda lagi', +'plugins': 'plugin', +'Plugins': 'Plugin', +'Powered by': 'Disokong oleh', +'Preface': 'Pendahuluan', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '100 baris sebelumnya', +'Previous Page': 'Laman Sebelumnya', +'Private files': 'Fail peribadi', +'private files': 'fail peribadi', +'Profile': 'Profil', +'Profile updated': 'Profil dikemaskini', +'Project Progress': 'Kemajuan Projek', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query:': 'Query:', +'Quick Examples': 'Contoh Cepat', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Dihapuskan', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Resipi', +'Record': 'Record', +'record does not exist': 'record does not exist', +'Record id': 'Record id', +'Register': 'Daftar', +'Registration successful': 'Pendaftaran berjaya', +'reload': 'memuat kembali', +'Reload routes': 'Memuat laluan kembali', +'Remember me (for 30 days)': 'Ingat saya (selama 30 hari)', +'Request reset password': 'Meminta reset kata laluan', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Rows in Table', +'Rows selected': 'Baris dipilih', +'Running on %s': 'Berjalan pada %s', +'Save model as...': 'Simpan model sebagai ...', +'Save profile': 'Simpan profil', +'Search': 'Cari', +'Select Files to Package': 'Pilih Fail untuk Pakej', +'Send Email': 'Kirim Emel', +'Services': 'Services', +'Sign Up': 'Sign Up', +'Size of cache:': 'Saiz cache:', +'Solution': 'Penyelesaian', +'starts with': 'bermula dengan', +'state': 'state', +'static': 'statik', +'Static': 'Statik', +'Statistics': 'Statistik', +'Stylesheet': 'Stylesheet', +'submit': 'submit', +'Support': 'Menyokong', +'Table': 'Table', +'test': 'ujian', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.', +'The Core': 'The Core', +'The output of the file is a dictionary that was rendered by the view %s': 'The output of the file is a dictionary that was rendered by the view %s', +'The Views': 'The Views', +'There are no plugins': 'Tiada plugin', +'There are no private files': 'Tiada fail peribadi', +'These files are not served, they are only available from within your app': 'Fail-fail ini tidak disampaikan, mereka hanya boleh didapati dari dalam aplikasi anda', +'These files are served without processing, your images go here': 'Ini fail disampaikan tanpa pemprosesan, imej anda di sini', +'This App': 'App Ini', +'Time in Cache (h:m:s)': 'Waktu di Cache (h: m: s)', +'Title': 'Judul', +'To create a plugin, name a file/folder plugin_[name]': 'Untuk mencipta plugin, nama fail/folder plugin_ [nama]', +'too short': 'terlalu pendek', +'Traceback': 'Traceback', +'Twitter': 'Twitter', +'Unable to download because:': 'Tidak dapat memuat turun kerana:', +'unable to parse csv file': 'tidak mampu mengurai file csv', +'update all languages': 'mengemaskini semua bahasa', +'Update:': 'Kemas kini:', +'Upgrade': 'Menaik taraf', +'Upload': 'Unggah', +'Upload a package:': 'Unggah pakej:', +'upload file:': 'unggah fail:', +'upload plugin file:': 'unggah fail plugin:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.', +'User': 'User', +'User %(id)s Logged-in': 'Pengguna %(id)s Masuk', +'User %(id)s Logged-out': 'Pengguna %(id)s Keluar', +'User %(id)s Password changed': 'Pengguna %(id)s Kata Laluan berubah', +'User %(id)s Password reset': 'Pengguna %(id)s Kata Laluan telah direset', +'User %(id)s Profile updated': 'Pengguna %(id)s Profil dikemaskini', +'User %(id)s Registered': 'Pengguna %(id)s Didaftarkan', +'Users': 'Users', +'value not allowed': 'data tidak benar', +'Verify Password': 'Pengesahan Kata Laluan', +'Version': 'Versi', +'Versioning': 'Pembuatan Sejarah', +'Videos': 'Videos', +'View': 'Lihat', +'views': 'Lihat', +'Views': 'Lihat', +'Web Framework': 'Rangka Kerja Web', +'web2py Recent Tweets': 'Tweet terbaru web2py', +'Website': 'Laman Web', +'Welcome': 'Selamat Datang', +'Welcome to web2py!': 'Selamat Datang di web2py!', +'Which called the function %s located in the file %s': 'Which called the function %s located in the file %s', +'Working...': 'Working...', +'You are successfully running web2py': 'Anda berjaya menjalankan web2py', +'You can modify this application and adapt it to your needs': 'Anda boleh mengubah suai aplikasi ini dan menyesuaikan dengan keperluan anda', +'You visited the url %s': 'Anda melawat url %s', +} diff --git a/web2py/applications/SP/languages/nl.py b/web2py/applications/SP/languages/nl.py new file mode 100644 index 0000000..7ff72e4 --- /dev/null +++ b/web2py/applications/SP/languages/nl.py @@ -0,0 +1,413 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'nl', +'!langname!': 'Nederlands', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN', +'%(nrows)s records found': '%(nrows)s records gevonden', +'%d days ago': '%d dagen geleden', +'%d weeks ago': '%d weken gelden', +'%s %%{row} deleted': '%s rijen verwijderd', +'%s %%{row} updated': '%s rijen geupdate', +'%s selected': '%s geselecteerd', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'(something like "it-it")': '(zoiets als "nl-nl")', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'1 day ago': '1 dag geleden', +'1 week ago': '1 week gelden', +'<': '<', +'<=': '<=', +'=': '=', +'>': '>', +'>=': '>=', +'?': '?', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'A new version of web2py is available': 'Een nieuwe versie van web2py is beschikbaar', +'A new version of web2py is available: %s': 'Een nieuwe versie van web2py is beschikbaar: %s', +'About': 'Over', +'about': 'over', +'About application': 'Over applicatie', +'Access Control': 'Toegangscontrole', +'Add': 'Toevoegen', +'additional code for your application': 'additionele code voor je applicatie', +'admin': 'admin', +'admin disabled because no admin password': 'admin is uitgezet omdat er geen admin wachtwoord is', +'admin disabled because not supported on google app engine': 'admin is uitgezet omdat dit niet ondersteund wordt op google app engine', +'admin disabled because unable to access password file': 'admin is uitgezet omdat het wachtwoordbestand niet geopend kan worden', +'Admin is disabled because insecure channel': 'Admin is uitgezet om het kanaal onveilig is', +'Admin is disabled because unsecure channel': 'Admin is uitgezet om het kanaal onveilig is', +'Administration': 'Administratie', +'Administrative Interface': 'Administratieve Interface', +'Administrator Password:': 'Administrator Wachtwoord', +'Ajax Recipes': 'Ajax Recepten', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'And': 'En', +'and rename it (required):': 'en hernoem deze (vereist)', +'and rename it:': 'en hernoem:', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'appadmin is uitgezet vanwege een onveilig kanaal', +'application "%s" uninstalled': 'applicatie "%s" gedeïnstalleerd', +'application compiled': 'applicatie gecompileerd', +'application is compiled and cannot be designed': 'applicatie is gecompileerd en kan niet worden ontworpen', +'Are you sure you want to delete file "%s"?': 'Weet je zeker dat je bestand "%s" wilt verwijderen?', +'Are you sure you want to delete this object?': 'Weet je zeker dat je dit object wilt verwijderen?', +'Are you sure you want to uninstall application "%s"?': 'Weet je zeker dat je applicatie "%s" wilt deïnstalleren?', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'LET OP: Login vereist een beveiligde (HTTPS) connectie of moet draaien op localhost.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'LET OP: TESTEN IS NIET THREAD SAFE, PROBEER NIET GELIJKTIJDIG MEERDERE TESTS TE DOEN.', +'ATTENTION: you cannot edit the running application!': 'LET OP: je kan de applicatie die nu draait niet editen!', +'Authentication': 'Authenticatie', +'Available Databases and Tables': 'Beschikbare databases en tabellen', +'Back': 'Terug', +'Buy this book': 'Koop dit boek', +"Buy web2py's book": "Buy web2py's book", +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'cache, errors en sessies geleegd', +'Cannot be empty': 'Mag niet leeg zijn', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Kan niet compileren: er bevinden zich fouten in je app. Debug, corrigeer de fouten en probeer opnieuw.', +'cannot create file': 'kan bestand niet maken', +'cannot upload file "%(filename)s"': 'kan bestand "%(filename)s" niet uploaden', +'Change Password': 'Wijzig wachtwoord', +'Change password': 'Wijzig Wachtwoord', +'change password': 'wijzig wachtwoord', +'check all': 'vink alles aan', +'Check to delete': 'Vink aan om te verwijderen', +'clean': 'leeg', +'Clear': 'Leeg', +'Clear CACHE?': 'Leeg CACHE?', +'Clear DISK': 'Leeg DISK', +'Clear RAM': 'Clear RAM', +'click to check for upgrades': 'Klik om voor upgrades te controleren', +'Client IP': 'Client IP', +'Community': 'Community', +'compile': 'compileren', +'compiled application removed': 'gecompileerde applicatie verwijderd', +'Components and Plugins': 'Components en Plugins', +'Config.ini': 'Config.ini', +'contains': 'bevat', +'Controller': 'Controller', +'Controllers': 'Controllers', +'controllers': 'controllers', +'Copyright': 'Copyright', +'create file with filename:': 'maak bestand met de naam:', +'Create new application': 'Maak nieuwe applicatie:', +'create new application:': 'maak nieuwe applicatie', +'Created By': 'Gemaakt Door', +'Created On': 'Gemaakt Op', +'crontab': 'crontab', +'Current request': 'Huidige request', +'Current response': 'Huidige response', +'Current session': 'Huidige sessie', +'currently saved or': 'op het moment opgeslagen of', +'customize me!': 'pas me aan!', +'data uploaded': 'data geupload', +'Database': 'Database', +'Database %s select': 'Database %s select', +'database administration': 'database administratie', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Datum en Tijd', +'db': 'db', +'DB Model': 'DB Model', +'defines tables': 'definieer tabellen', +'Delete': 'Verwijder', +'delete': 'verwijder', +'delete all checked': 'verwijder alle aangevinkten', +'Delete:': 'Verwijder:', +'Demo': 'Demo', +'Deploy on Google App Engine': 'Deploy op Google App Engine', +'Deployment Recipes': 'Deployment Recepten', +'Description': 'Beschrijving', +'design': 'design', +'DESIGN': 'DESIGN', +'Design': 'Design', +'Design for': 'Design voor', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Geleegd', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentatie', +"Don't know what to do?": 'Weet je niet wat je moet doen?', +'done!': 'gereed!', +'Download': 'Download', +'E-mail': 'E-mail', +'E-mail invalid': 'E-mail ongeldig', +'edit': 'bewerk', +'EDIT': 'BEWERK', +'Edit': 'Bewerk', +'Edit application': 'Bewerk applicatie', +'edit controller': 'bewerk controller', +'Edit current record': 'Bewerk huidig record', +'Edit Profile': 'Bewerk Profiel', +'edit profile': 'bewerk profiel', +'Edit This App': 'Bewerk Deze App', +'Editing file': 'Bewerk bestand', +'Editing file "%s"': 'Bewerk bestand "%s"', +'Email and SMS': 'E-mail en SMS', +'enter a number between %(min)g and %(max)g': 'geef een getal tussen %(min)g en %(max)g', +'enter an integer between %(min)g and %(max)g': 'geef een integer tussen %(min)g en %(max)g', +'Error logs for "%(app)s"': 'Error logs voor "%(app)s"', +'errors': 'errors', +'Errors': 'Errors', +'Export': 'Export', +'export as csv file': 'exporteer als csv-bestand', +'exposes': 'stelt bloot', +'extends': 'extends', +'failed to reload module': 'niet gelukt om module te herladen', +'False': 'Onwaar', +'FAQ': 'FAQ', +'file "%(filename)s" created': 'bestand "%(filename)s" gemaakt', +'file "%(filename)s" deleted': 'bestand "%(filename)s" verwijderd', +'file "%(filename)s" uploaded': 'bestand "%(filename)s" geupload', +'file "%(filename)s" was not deleted': 'bestand "%(filename)s" was niet verwijderd', +'file "%s" of %s restored': 'bestand "%s" van %s hersteld', +'file changed on disk': 'bestand aangepast op schijf', +'file does not exist': 'bestand bestaat niet', +'file saved on %(time)s': 'bestand bewaard op %(time)s', +'file saved on %s': 'bestand bewaard op %s', +'First name': 'Voornaam', +'Forbidden': 'Verboden', +'Forms and Validators': 'Formulieren en Validators', +'Free Applications': 'Gratis Applicaties', +'Functions with no doctests will result in [passed] tests.': 'Functies zonder doctests zullen resulteren in [passed] tests.', +'Graph Model': 'Graph Model', +'Group %(group_id)s created': 'Groep %(group_id)s gemaakt', +'Group ID': 'Groep ID', +'Group uniquely assigned to user %(id)s': 'Groep is uniek toegekend aan gebruiker %(id)s', +'Groups': 'Groepen', +'Hello World': 'Hallo Wereld', +'help': 'help', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Home', +'How did you get here?': 'Hoe ben je hier gekomen?', +'htmledit': 'Bewerk HTML', +'import': 'import', +'Import/Export': 'Import/Export', +'includes': 'includes', +'Index': 'Index', +'insert new': 'voeg nieuwe', +'insert new %s': 'voeg nieuwe %s', +'Installed applications': 'Geïnstalleerde applicaties', +'internal error': 'interne error', +'Internal State': 'Interne State', +'Introduction': 'Introductie', +'Invalid action': 'Ongeldige actie', +'Invalid email': 'Ongeldig emailadres', +'invalid password': 'ongeldig wachtwoord', +'Invalid password': 'Ongeldig wachtwoord', +'Invalid Query': 'Ongeldige Query', +'invalid request': 'ongeldige request', +'invalid ticket': 'ongeldige ticket', +'Is Active': 'Is Actief', +'Key': 'Key', +'language file "%(filename)s" created/updated': 'taalbestand "%(filename)s" gemaakt/geupdate', +'Language files (static strings) updated': 'Taalbestanden (statische strings) geupdate', +'languages': 'talen', +'Languages': 'Talen', +'languages updated': 'talen geupdate', +'Last name': 'Achternaam', +'Last saved on:': 'Laatst bewaard op:', +'Layout': 'Layout', +'Layout Plugins': 'Layout Plugins', +'Layouts': 'Layouts', +'License for': 'Licentie voor', +'Live Chat': 'Live Chat', +'loading...': 'laden...', +'Log In': 'Log In', +'Logged in': 'Ingelogd', +'Logged out': 'Uitgelogd', +'Login': 'Login', +'login': 'login', +'Login to the Administrative Interface': 'Inloggen op de Administratieve Interface', +'logout': 'logout', +'Logout': 'Logout', +'Lost Password': 'Wachtwoord Kwijt', +'Lost password?': 'Wachtwoord kwijt?', +'Main Menu': 'Hoofdmenu', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Beheer Cache', +'Memberships': 'Memberships', +'Menu Model': 'Menu Model', +'merge': 'samenvoegen', +'Models': 'Modellen', +'models': 'modellen', +'Modified By': 'Aangepast Door', +'Modified On': 'Aangepast Op', +'Modules': 'Modules', +'modules': 'modules', +'My Sites': 'Mijn Sites', +'Name': 'Naam', +'New': 'Nieuw', +'new application "%s" created': 'nieuwe applicatie "%s" gemaakt', +'New password': 'Nieuw wachtwoord', +'New Record': 'Nieuw Record', +'new record inserted': 'nieuw record ingevoegd', +'next %s rows': 'next %s rows', +'next 100 rows': 'volgende 100 rijen', +'NO': 'NEE', +'No databases in this application': 'Geen database in deze applicatie', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Object or table name': 'Object of tabelnaam', +'Old password': 'Oude wachtwoord', +'Online book': 'Online book', +'Online examples': 'Online voorbeelden', +'Or': 'Of', +'or import from csv file': 'of importeer van csv-bestand', +'or provide application url:': 'of geef een applicatie url:', +'Origin': 'Bron', +'Original/Translation': 'Oorspronkelijk/Vertaling', +'Other Plugins': 'Andere Plugins', +'Other Recipes': 'Andere Recepten', +'Overview': 'Overzicht', +'pack all': 'pack all', +'pack compiled': 'pack compiled', +'Password': 'Wachtwoord', +"Password fields don't match": 'Wachtwoordvelden komen niet overeen', +'Peeking at file': 'Naar bestand aan het gluren', +'Permission': 'Permission', +'Permissions': 'Permissions', +'please input your password again': 'geef alstublieft nogmaals uw wachtwoord', +'Plugins': 'Plugins', +'Powered by': 'Powered by', +'Preface': 'Inleiding', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'vorige 100 rijen', +'Profile': 'Profiel', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query': 'Query', +'Query:': 'Query:', +'Quick Examples': 'Snelle Voorbeelden', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Geleegd', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Recepten', +'Record': 'Record', +'record does not exist': 'record bestaat niet', +'Record ID': 'Record ID', +'Record id': 'Record id', +'register': 'registreer', +'Register': 'Registreer', +'Registration identifier': 'Registratie identifier', +'Registration key': 'Registratie sleutel', +'Registration successful': 'Registratie succesvol', +'Remember me (for 30 days)': 'Onthoudt mij (voor 30 dagen)', +'remove compiled': 'verwijder gecompileerde', +'Request reset password': 'Vraag een wachtwoord reset aan', +'Reset Password key': 'Reset Wachtwoord sleutel', +'Resolve Conflict file': 'Los Conflictbestand op', +'restore': 'herstel', +'revert': 'herstel', +'Role': 'Rol', +'Roles': 'Roles', +'Rows in Table': 'Rijen in tabel', +'Rows selected': 'Rijen geselecteerd', +'save': 'bewaar', +'Save model as...': 'Save model as...', +'Save profile': 'Bewaar profiel', +'Saved file hash:': 'Opgeslagen file hash:', +'Search': 'Zoek', +'Semantic': 'Semantisch', +'Services': 'Services', +'session expired': 'sessie verlopen', +'shell': 'shell', +'Sign Up': 'Sign Up', +'site': 'site', +'Size of cache:': 'Grootte van cache:', +'some files could not be removed': 'sommige bestanden konden niet worden verwijderd', +'starts with': 'begint met', +'state': 'state', +'static': 'statisch', +'Static files': 'Statische bestanden', +'Statistics': 'Statistieken', +'Stylesheet': 'Stylesheet', +'Submit': 'Submit', +'submit': 'submit', +'Support': 'Support', +'Sure you want to delete this object?': 'Weet je zeker dat je dit object wilt verwijderen?', +'Table': 'Tabel', +'Table name': 'Tabelnaam', +'test': 'test', +'Testing application': 'Applicatie testen', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'De "query" is een conditie zoals "db.tabel1.veld1==\'waarde\'". Zoiets als "db.tabel1.veld1==db.tabel2.veld2" resulteert in een SQL JOIN.', +'the application logic, each URL path is mapped in one exposed function in the controller': 'the applicatie logica, elk URL pad is gemapped in een blootgestelde functie in de controller', +'The Core': 'De Core', +'the data representation, define database tables and sets': 'de data representatie, definieert database tabellen en sets', +'The output of the file is a dictionary that was rendered by the view %s': 'De output van het bestand is een dictionary die gerenderd werd door de view %s', +'the presentations layer, views are also known as templates': 'de presentatie laag, views zijn ook bekend als templates', +'The Views': 'De Views', +'There are no controllers': 'Er zijn geen controllers', +'There are no models': 'Er zijn geen modellen', +'There are no modules': 'Er zijn geen modules', +'There are no static files': 'Er zijn geen statische bestanden', +'There are no translators, only default language is supported': 'Er zijn geen vertalingen, alleen de standaard taal wordt ondersteund.', +'There are no views': 'Er zijn geen views', +'these files are served without processing, your images go here': 'Deze bestanden worden geserveerd zonder verdere verwerking, je afbeeldingen horen hier', +'This App': 'Deze App', +'This is a copy of the scaffolding application': 'Dit is een kopie van de steiger-applicatie', +'This is the %(filename)s template': 'Dit is de %(filename)s template', +'Ticket': 'Ticket', +'Time in Cache (h:m:s)': 'Tijd in Cache (h:m:s)', +'Timestamp': 'Timestamp (timestamp)', +'to previous version.': 'naar vorige versie.', +'too short': 'te kort', +'Traceback': 'Traceback', +'translation strings for the application': 'vertaalstrings voor de applicatie', +'True': 'Waar', +'try': 'probeer', +'try something like': 'probeer zoiets als', +'Twitter': 'Twitter', +'Unable to check for upgrades': 'Niet mogelijk om te controleren voor upgrades', +'unable to create application "%s"': 'niet mogelijk om applicatie "%s" te maken', +'unable to delete file "%(filename)s"': 'niet mogelijk om bestand "%(filename)s" te verwijderen', +'Unable to download': 'Niet mogelijk om te downloaden', +'Unable to download app': 'Niet mogelijk om app te downloaden', +'unable to parse csv file': 'niet mogelijk om csv-bestand te parsen', +'unable to uninstall "%s"': 'niet mogelijk om "%s" te deïnstalleren', +'uncheck all': 'vink alles uit', +'uninstall': ' deïnstalleer', +'update': 'update', +'update all languages': 'update alle talen', +'Update:': 'Update:', +'upload application:': 'upload applicatie:', +'Upload existing application': 'Upload bestaande applicatie', +'upload file:': 'upload bestand', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Gebruik (...)&(...) voor AND, (...)|(...) voor OR, en ~(...) voor NOT om meer complexe queries te maken.', +'User': 'User', +'User %(id)s Logged-in': 'Gebruiker %(id)s Logged-in', +'User %(id)s Logged-out': 'Gebruiker %(id)s Logged-out', +'User %(id)s Password changed': 'Wachtwoord van gebruiker %(id)s is veranderd', +'User %(id)s Password reset': 'Wachtwoord van gebruiker %(id)s is gereset', +'User %(id)s Profile updated': 'Profiel van Gebruiker %(id)s geupdate', +'User %(id)s Registered': 'Gebruiker %(id)s Geregistreerd', +'User ID': 'User ID', +'Users': 'Users', +'value already in database or empty': 'waarde al in database of leeg', +'Verify Password': 'Verifieer Wachtwoord', +'versioning': 'versionering', +'Videos': 'Videos', +'View': 'View', +'view': 'view', +'Views': 'Vieuws', +'views': 'vieuws', +'web2py is up to date': 'web2py is up to date', +'web2py Recent Tweets': 'web2py Recente Tweets', +'Welcome': 'Welkom', +'Welcome %s': 'Welkom %s', +'Welcome to web2py': 'Welkom bij web2py', +'Welcome to web2py!': 'Welkom bij web2py!', +'Which called the function %s located in the file %s': 'Die functie %s aanriep en zich bevindt in het bestand %s', +'Working...': 'Working...', +'YES': 'JA', +'You are successfully running web2py': 'Je draait web2py succesvol', +'You can modify this application and adapt it to your needs': 'Je kan deze applicatie aanpassen naar je eigen behoeften', +'You visited the url %s': 'Je bezocht de url %s', +} diff --git a/web2py/applications/SP/languages/pl.py b/web2py/applications/SP/languages/pl.py new file mode 100644 index 0000000..f77b6ad --- /dev/null +++ b/web2py/applications/SP/languages/pl.py @@ -0,0 +1,208 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'pl', +'!langname!': 'Polska', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Uaktualnij" jest dodatkowym wyrażeniem postaci "pole1=\'nowawartość\'". Nie możesz uaktualnić lub usunąć wyników z JOIN:', +'%s %%{row} deleted': 'Wierszy usuniętych: %s', +'%s %%{row} updated': 'Wierszy uaktualnionych: %s', +'%s selected': '%s wybranych', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'About', +'Access Control': 'Access Control', +'admin': 'admin', +'Administrative Interface': 'Administrative Interface', +'Administrative interface': 'Kliknij aby przejść do panelu administracyjnego', +'Ajax Recipes': 'Ajax Recipes', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'appadmin is disabled because insecure channel': 'administracja aplikacji wyłączona z powodu braku bezpiecznego połączenia', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Authentication': 'Uwierzytelnienie', +'Available Databases and Tables': 'Dostępne bazy danych i tabele', +'Buy this book': 'Buy this book', +"Buy web2py's book": "Buy web2py's book", +'cache': 'cache', +'Cache': 'Cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'Cannot be empty': 'Nie może być puste', +'Change Password': 'Zmień hasło', +'change password': 'change password', +'Check to delete': 'Zaznacz aby usunąć', +'Check to delete:': 'Zaznacz aby usunąć:', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Client IP': 'IP klienta', +'Community': 'Community', +'Components and Plugins': 'Components and Plugins', +'Config.ini': 'Config.ini', +'Controller': 'Kontroler', +'Copyright': 'Copyright', +'Current request': 'Aktualne żądanie', +'Current response': 'Aktualna odpowiedź', +'Current session': 'Aktualna sesja', +'customize me!': 'dostosuj mnie!', +'data uploaded': 'dane wysłane', +'Database': 'baza danych', +'Database %s select': 'wybór z bazy danych %s', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'db': 'baza danych', +'DB Model': 'Model bazy danych', +'Delete:': 'Usuń:', +'Demo': 'Demo', +'Deployment Recipes': 'Deployment Recipes', +'Description': 'Opis', +'design': 'projektuj', +'Design': 'Design', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentation', +"Don't know what to do?": "Don't know what to do?", +'done!': 'zrobione!', +'Download': 'Download', +'E-mail': 'Adres e-mail', +'Edit': 'Edycja', +'Edit current record': 'Edytuj obecny rekord', +'edit profile': 'edit profile', +'Edit Profile': 'Edytuj profil', +'Edit This App': 'Edytuj tę aplikację', +'Email and SMS': 'Email and SMS', +'Errors': 'Errors', +'export as csv file': 'eksportuj jako plik csv', +'FAQ': 'FAQ', +'First name': 'Imię', +'Forms and Validators': 'Forms and Validators', +'Free Applications': 'Free Applications', +'Function disabled': 'Funkcja wyłączona', +'Graph Model': 'Graph Model', +'Group ID': 'ID grupy', +'Groups': 'Groups', +'Hello World': 'Witaj Świecie', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Home', +'How did you get here?': 'How did you get here?', +'import': 'import', +'Import/Export': 'Importuj/eksportuj', +'Index': 'Indeks', +'insert new': 'wstaw nowy rekord tabeli', +'insert new %s': 'wstaw nowy rekord do tabeli %s', +'Internal State': 'Stan wewnętrzny', +'Introduction': 'Introduction', +'Invalid email': 'Błędny adres email', +'Invalid Query': 'Błędne zapytanie', +'invalid request': 'Błędne żądanie', +'Key': 'Key', +'Last name': 'Nazwisko', +'Layout': 'Układ', +'Layout Plugins': 'Layout Plugins', +'Layouts': 'Layouts', +'Live Chat': 'Live Chat', +'Log In': 'Log In', +'login': 'login', +'Login': 'Zaloguj', +'logout': 'logout', +'Logout': 'Wyloguj', +'Lost Password': 'Przypomnij hasło', +'Main Menu': 'Menu główne', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Manage Cache', +'Memberships': 'Memberships', +'Menu Model': 'Model menu', +'My Sites': 'My Sites', +'Name': 'Nazwa', +'New Record': 'Nowy rekord', +'new record inserted': 'nowy rekord został wstawiony', +'next %s rows': 'next %s rows', +'next 100 rows': 'następne 100 wierszy', +'No databases in this application': 'Brak baz danych w tej aplikacji', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Online book': 'Online book', +'Online examples': 'Kliknij aby przejść do interaktywnych przykładów', +'or import from csv file': 'lub zaimportuj z pliku csv', +'Origin': 'Źródło', +'Other Plugins': 'Other Plugins', +'Other Recipes': 'Other Recipes', +'Overview': 'Overview', +'Password': 'Hasło', +"Password fields don't match": 'Pola hasła nie są zgodne ze sobą', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Plugins': 'Plugins', +'Powered by': 'Zasilane przez', +'Preface': 'Preface', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'poprzednie 100 wierszy', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query:': 'Zapytanie:', +'Quick Examples': 'Quick Examples', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Recipes', +'Record': 'rekord', +'record does not exist': 'rekord nie istnieje', +'Record ID': 'ID rekordu', +'Record id': 'id rekordu', +'Register': 'Zarejestruj', +'register': 'register', +'Registration key': 'Klucz rejestracji', +'Role': 'Rola', +'Roles': 'Roles', +'Rows in Table': 'Wiersze w tabeli', +'Rows selected': 'Wybrane wiersze', +'Save model as...': 'Save model as...', +'Semantic': 'Semantic', +'Services': 'Services', +'Sign Up': 'Sign Up', +'Size of cache:': 'Size of cache:', +'state': 'stan', +'Statistics': 'Statistics', +'Stylesheet': 'Arkusz stylów', +'submit': 'submit', +'Submit': 'Wyślij', +'Support': 'Support', +'Sure you want to delete this object?': 'Czy na pewno chcesz usunąć ten obiekt?', +'Table': 'tabela', +'Table name': 'Nazwa tabeli', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"Zapytanie" jest warunkiem postaci "db.tabela1.pole1==\'wartość\'". Takie coś jak "db.tabela1.pole1==db.tabela2.pole2" oznacza SQL JOIN.', +'The Core': 'The Core', +'The output of the file is a dictionary that was rendered by the view %s': 'The output of the file is a dictionary that was rendered by the view %s', +'The Views': 'The Views', +'This App': 'This App', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'Znacznik czasu', +'Traceback': 'Traceback', +'Twitter': 'Twitter', +'unable to parse csv file': 'nie można sparsować pliku csv', +'Update:': 'Uaktualnij:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Użyj (...)&(...) jako AND, (...)|(...) jako OR oraz ~(...) jako NOT do tworzenia bardziej skomplikowanych zapytań.', +'User': 'User', +'User %(id)s Registered': 'Użytkownik %(id)s został zarejestrowany', +'User ID': 'ID użytkownika', +'Users': 'Users', +'Verify Password': 'Potwierdź hasło', +'Videos': 'Videos', +'View': 'Widok', +'Welcome %s': 'Welcome %s', +'Welcome to web2py': 'Witaj w web2py', +'Welcome to web2py!': 'Welcome to web2py!', +'Which called the function %s located in the file %s': 'Which called the function %s located in the file %s', +'Working...': 'Working...', +'You are successfully running web2py': 'You are successfully running web2py', +'You can modify this application and adapt it to your needs': 'You can modify this application and adapt it to your needs', +'You visited the url %s': 'You visited the url %s', +} diff --git a/web2py/applications/SP/languages/plural-cs.py b/web2py/applications/SP/languages/plural-cs.py new file mode 100644 index 0000000..b994d19 --- /dev/null +++ b/web2py/applications/SP/languages/plural-cs.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +{ +'den': ['dny', 'dn\\xc5\\xaf'], +'dnem': ['dny', 'dny'], +'hodina': ['hodiny', 'hodin'], +'hodinou': ['hodinami', 'hodinami'], +'minuta': ['minuty', 'minut'], +'minutou': ['minutami', 'minutami'], +'měsíc': ['m\\xc4\\x9bs\\xc3\\xadce', 'm\\xc4\\x9bs\\xc3\\xadc\\xc5\\xaf'], +'měsícem': ['m\\xc4\\x9bs\\xc3\\xadci', 'm\\xc4\\x9bs\\xc3\\xadci'], +'rok': ['roky', 'let'], +'rokem': ['roky', 'lety'], +'soubor': ['soubory', 'soubor\\xc5\\xaf'], +'týden': ['t\\xc3\\xbddny', 't\\xc3\\xbddn\\xc5\\xaf'], +'týdnem': ['t\\xc3\\xbddny', 't\\xc3\\xbddny'], +'vteřina': ['vte\\xc5\\x99iny', 'vte\\xc5\\x99in'], +'vteřinou': ['vte\\xc5\\x99inami', 'vte\\xc5\\x99inami'], +'záznam': ['z\\xc3\\xa1znamy', 'z\\xc3\\xa1znam\\xc5\\xaf'], +} diff --git a/web2py/applications/SP/languages/plural-en.py b/web2py/applications/SP/languages/plural-en.py new file mode 100644 index 0000000..cbd345b --- /dev/null +++ b/web2py/applications/SP/languages/plural-en.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +{ +'account': ['accounts'], +'book': ['books'], +'is': ['are'], +'man': ['men'], +'miss': ['misses'], +'person': ['people'], +'quark': ['quarks'], +'shop': ['shops'], +'this': ['these'], +'was': ['were'], +'woman': ['women'], +} diff --git a/web2py/applications/SP/languages/plural-es.py b/web2py/applications/SP/languages/plural-es.py new file mode 100644 index 0000000..a8264d5 --- /dev/null +++ b/web2py/applications/SP/languages/plural-es.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +{ +'actualizada': ['actualizadas'], +'eliminada': ['eliminadas'], +'fila': ['filas'], +'seleccionado': ['seleccionados'], +} diff --git a/web2py/applications/SP/languages/plural-ru.py b/web2py/applications/SP/languages/plural-ru.py new file mode 100644 index 0000000..4cf2d24 --- /dev/null +++ b/web2py/applications/SP/languages/plural-ru.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +{ +'выбрана': ['выбраны','выбрано'], +'год': ['года','лет'], +'день': ['дня', 'дней'], +'запись': ['записи','записей'], +'изменена': ['изменены','изменено'], +'месяц': ['месяца','месяцев'], +'минуту': ['минуты','минут'], +'неделю': ['недели','недель'], +'секунду': ['секунды','секунд'], +'строка': ['строки','строк'], +'удалена': ['удалены','удалено'], +'час': ['часа','часов'], +} diff --git a/web2py/applications/SP/languages/plural-uk.py b/web2py/applications/SP/languages/plural-uk.py new file mode 100644 index 0000000..e6b9146 --- /dev/null +++ b/web2py/applications/SP/languages/plural-uk.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +{ +'байт': ['\\xd0\\xb1\\xd0\\xb0\\xd0\\xb9\\xd1\\x82\\xd0\\xb8', '\\xd0\\xb1\\xd0\\xb0\\xd0\\xb9\\xd1\\x82\\xd1\\x96\\xd0\\xb2'], +'годину': ['\\xd0\\xb3\\xd0\\xbe\\xd0\\xb4\\xd0\\xb8\\xd0\\xbd\\xd0\\xb8', '\\xd0\\xb3\\xd0\\xbe\\xd0\\xb4\\xd0\\xb8\\xd0\\xbd'], +'день': ['\\xd0\\xb4\\xd0\\xbd\\xd1\\x96', '\\xd0\\xb4\\xd0\\xbd\\xd1\\x96\\xd0\\xb2'], +'елемент': ['\\xd0\\xb5\\xd0\\xbb\\xd0\\xb5\\xd0\\xbc\\xd0\\xb5\\xd0\\xbd\\xd1\\x82\\xd0\\xb8', '\\xd0\\xb5\\xd0\\xbb\\xd0\\xb5\\xd0\\xbc\\xd0\\xb5\\xd0\\xbd\\xd1\\x82\\xd1\\x96\\xd0\\xb2'], +'запис': ['\\xd0\\xb7\\xd0\\xb0\\xd0\\xbf\\xd0\\xb8\\xd1\\x81\\xd0\\xb8', '\\xd0\\xb7\\xd0\\xb0\\xd0\\xbf\\xd0\\xb8\\xd1\\x81\\xd1\\x96\\xd0\\xb2'], +'місяць': ['\\xd0\\xbc\\xd1\\x96\\xd1\\x81\\xd1\\x8f\\xd1\\x86\\xd1\\x96', '\\xd0\\xbc\\xd1\\x96\\xd1\\x81\\xd1\\x8f\\xd1\\x86\\xd1\\x96\\xd0\\xb2'], +'поцілювання': ['\\xd0\\xbf\\xd0\\xbe\\xd1\\x86\\xd1\\x96\\xd0\\xbb\\xd1\\x8e\\xd0\\xb2\\xd0\\xb0\\xd0\\xbd\\xd0\\xbd\\xd1\\x8f', '\\xd0\\xbf\\xd0\\xbe\\xd1\\x86\\xd1\\x96\\xd0\\xbb\\xd1\\x8e\\xd0\\xb2\\xd0\\xb0\\xd0\\xbd\\xd1\\x8c'], +'рядок': ['\\xd1\\x80\\xd1\\x8f\\xd0\\xb4\\xd0\\xba\\xd0\\xb8', '\\xd1\\x80\\xd1\\x8f\\xd0\\xb4\\xd0\\xba\\xd1\\x96\\xd0\\xb2'], +'рік': ['\\xd1\\x80\\xd0\\xbe\\xd0\\xba\\xd0\\xb8', '\\xd1\\x80\\xd0\\xbe\\xd0\\xba\\xd1\\x96\\xd0\\xb2'], +'секунду': ['\\xd1\\x81\\xd0\\xb5\\xd0\\xba\\xd1\\x83\\xd0\\xbd\\xd0\\xb4\\xd0\\xb8', '\\xd1\\x81\\xd0\\xb5\\xd0\\xba\\xd1\\x83\\xd0\\xbd\\xd0\\xb4'], +'схибнення': ['\\xd1\\x81\\xd1\\x85\\xd0\\xb8\\xd0\\xb1\\xd0\\xbd\\xd0\\xb5\\xd0\\xbd\\xd0\\xbd\\xd1\\x8f', '\\xd1\\x81\\xd1\\x85\\xd0\\xb8\\xd0\\xb1\\xd0\\xbd\\xd0\\xb5\\xd0\\xbd\\xd1\\x8c'], +'тиждень': ['\\xd1\\x82\\xd0\\xb8\\xd0\\xb6\\xd0\\xbd\\xd1\\x96', '\\xd1\\x82\\xd0\\xb8\\xd0\\xb6\\xd0\\xbd\\xd1\\x96\\xd0\\xb2'], +'хвилину': ['\\xd1\\x85\\xd0\\xb2\\xd0\\xb8\\xd0\\xbb\\xd0\\xb8\\xd0\\xbd\\xd0\\xb8', '\\xd1\\x85\\xd0\\xb2\\xd0\\xb8\\xd0\\xbb\\xd0\\xb8\\xd0\\xbd'], +} diff --git a/web2py/applications/SP/languages/pt-br.py b/web2py/applications/SP/languages/pt-br.py new file mode 100644 index 0000000..b94d317 --- /dev/null +++ b/web2py/applications/SP/languages/pt-br.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'pt-br', +'!langname!': 'Português (do Brasil)', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" é uma expressão opcional como "campo1=\'novovalor\'". Você não pode atualizar ou apagar os resultados de um JOIN', +'%s %%{row} deleted': '%s linha apagadas', +'%s %%{row} updated': '%s linha atualizadas', +'%s selected': '%s selecionado', +'%Y-%m-%d': '%d-%m-%Y', +'%Y-%m-%d %H:%M:%S': '%d-%m-%Y %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'@markmin\x01An error occured, please [[reload %s]] the page': 'Ocorreu um erro, por favor [[reload %s]] a página', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'Sobre', +'Access Control': 'Controle de Acesso', +'admin': 'admin', +'Administrative Interface': 'Interface Administrativa', +'Administrative interface': 'Interface administrativa', +'Ajax Recipes': 'Receitas de Ajax', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'API Example': 'API Example', +'appadmin is disabled because insecure channel': 'Administração desativada porque o canal não é seguro', +'Are you sure you want to delete this object?': 'Você tem certeza que quer apagar este objeto?', +'Available Databases and Tables': 'Bancos de dados e tabelas disponíveis', +'Buy this book': 'Compre o livro', +"Buy web2py's book": 'Compre o livro do web2py', +'cache': 'cache', +'Cache': 'Cache', +'Cache Cleared': 'Cache limpo', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Chaves de cache', +'Cannot be empty': 'Não pode estar vazio', +'change password': 'mudar senha', +'Check to delete': 'Marque para apagar', +'Clear CACHE?': 'Limpar CACHE?', +'Clear DISK': 'Limpar DISCO', +'Clear RAM': 'Limpar memória RAM', +'Client IP': 'IP do cliente', +'Community': 'Comunidade', +'Components and Plugins': 'Componentes e Plugins', +'Config.ini': 'Config.ini', +'Controller': 'Controlador', +'Copyright': 'Copyright', +'Current request': 'Requisição atual', +'Current response': 'Resposta atual', +'Current session': 'Sessão atual', +'customize me!': 'personalize-me!', +'data uploaded': 'dados enviados', +'Database': 'banco de dados', +'Database %s select': 'Selecionar banco de dados %s', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'db': 'bd', +'DB Model': 'Modelo BD', +'Delete:': 'Apagar:', +'Demo': 'Demo', +'Deployment Recipes': 'Receitas de deploy', +'Description': 'Descrição', +'design': 'projeto', +'Design': 'Design', +'DISK': 'DISK', +'Disk Cache Keys': 'Chaves do Cache de Disco', +'Disk Cleared': 'Disco Limpo', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentação', +"Don't know what to do?": 'Não sabe o que fazer?', +'done!': 'concluído!', +'Download': 'Download', +'E-mail': 'E-mail', +'Edit': 'Editar', +'Edit current record': 'Editar o registro atual', +'edit profile': 'editar perfil', +'Edit This App': 'Editar esta aplicação', +'Email and SMS': 'Email e SMS', +'Enter an integer between %(min)g and %(max)g': 'Informe um valor inteiro entre %(min)g e %(max)g', +'Errors': 'Erros', +'export as csv file': 'exportar como um arquivo csv', +'FAQ': 'Perguntas frequentes', +'First name': 'Nome', +'Forms and Validators': 'Formulários e Validadores', +'Free Applications': 'Aplicações gratuitas', +'Graph Model': 'Graph Model', +'Grid Example': 'Exemplo de Grade', +'Group ID': 'ID do Grupo', +'Groups': 'Grupos', +'Hello World': 'Olá Mundo', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Principal', +'How did you get here?': 'Como você chegou aqui?', +'import': 'importar', +'Import/Export': 'Importar/Exportar', +'Index': 'Início', +'insert new': 'inserir novo', +'insert new %s': 'inserir novo %s', +'Internal State': 'Estado Interno', +'Introduction': 'Introdução', +'Invalid email': 'Email inválido', +'Invalid Query': 'Consulta Inválida', +'invalid request': 'requisição inválida', +'Key': 'Chave', +'Last name': 'Sobrenome', +'Layout': 'Layout', +'Layout Plugins': 'Plugins de Layout', +'Layouts': 'Layouts', +'Live chat': 'Chat ao vivo', +'Live Chat': 'Chat ao vivo', +'Log In': 'Entrar', +'login': 'Entrar', +'Login': 'Entrar', +'logout': 'Sair', +'Lost Password': 'Esqueceu sua senha?', +'lost password?': 'esqueceu sua senha?', +'Lost your password?': 'Esqueceu sua senha?', +'Main Menu': 'Menu Principal', +'Manage %(action)s': 'Gerenciar %(action)s', +'Manage Access Control': 'Gerenciar controle de acesso', +'Manage Cache': 'Gerenciar Cache', +'Memberships': 'Grupos', +'Menu Model': 'Modelo de Menu', +'My Sites': 'Meus sites', +'Name': 'Nome', +'New Record': 'Novo Registro', +'new record inserted': 'novo registro inserido', +'next %s rows': 'próximas %s ´linhas', +'next 100 rows': 'próximas 100 linhas', +'No databases in this application': 'Não há bancos de dados nesta aplicação', +'Number of entries: **%s**': 'Número de entradas: **%s**', +'Object or table name': 'Nome do objeto do da tabela', +'Online book': 'Online book', +'Online examples': 'Exemplos online', +'or import from csv file': 'ou importar de um arquivo csv', +'Origin': 'Origem', +'Other Plugins': 'Outros Plugins', +'Other Recipes': 'Outras Receitas', +'Overview': 'Visão Geral', +'Password': 'Senha', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Plugins': 'Plugins', +'Powered by': 'Desenvolvido com', +'Preface': 'Prefácio', +'previous %s rows': '%s linhas anteriores', +'previous 100 rows': '100 linhas anteriores', +'pygraphviz library not found': 'biblioteca pygraphviz não encontrada', +'Python': 'Python', +'Query:': 'Consulta:', +'Quick Examples': 'Exemplos rápidos', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Limpa', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Receitas', +'Record': 'Registro', +'record does not exist': 'registro não existe', +'Record ID': 'ID do Registro', +'Record id': 'id do registro', +'register': 'Registre-se', +'Register': 'Registre-se', +'Registration identifier': 'Idenficador de registro', +'Registration key': 'Chave de registro', +'Remember me (for 30 days)': 'Mantenha-me logado (por 30 dias)', +'Reset Password key': 'Resetar chave de senha', +'Resources': 'Recursos', +'Role': 'Papel', +'Roles': 'Roles', +'Rows in Table': 'Linhas na tabela', +'Rows selected': 'Linhas selecionadas', +'Save model as...': 'Salvar modelo como...', +'Semantic': 'Semântico', +'Services': 'Serviço', +'Sign Up': 'Cadastrar', +'Sign up': 'Cadastrar', +'Size of cache:': 'Tamanho do cache:', +'state': 'estado', +'Statistics': 'Estatísticas', +'Stylesheet': 'Folha de estilo', +'submit': 'enviar', +'Support': 'Suporte', +'Sure you want to delete this object?': 'Está certo(a) que deseja apagar este objeto?', +'Table': 'Tabela', +'Table name': 'Nome da tabela', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'Uma "consulta" é uma condição como "db.tabela1.campo1==\'valor\'". Expressões como "db.tabela1.campo1==db.tabela2.campo2" resultam em um JOIN SQL.', +'The Core': 'The Core', +'The output of the file is a dictionary that was rendered by the view %s': 'A saída do arquivo é um dicionário que foi apresentado pela visão %s', +'The Views': 'As views', +'This App': 'Esta aplicação', +'This email already has an account': 'Este email já tem uma conta', +'This is a copy of the scaffolding application': 'Isto é uma cópia da aplicação modelo', +'Time in Cache (h:m:s)': 'Tempo em Cache (h:m:s)', +'Timestamp': 'Timestamp', +'Traceback': 'Traceback', +'Twitter': 'Twitter', +'unable to parse csv file': 'não foi possível analisar arquivo csv', +'Update:': 'Atualizar:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) para AND, (...)|(...) para OR, e ~(...) para NOT para construir consultas mais complexas.', +'User': 'User', +'User ID': 'ID do Usuário', +'User Voice': 'Opinião dos usuários', +'Users': 'Users', +'Videos': 'Vídeos', +'View': 'Visualização', +'Web2py': 'Web2py', +'Welcome': 'Bem-vindo', +'Welcome %s': 'Bem-vindo %s', +'Welcome to web2py': 'Bem-vindo ao web2py', +'Welcome to web2py!': 'Bem-vindo ao web2py!', +'Which called the function %s located in the file %s': 'Que chamou a função %s localizada no arquivo %s', +'Wiki Example': 'Wiki Example', +'Working...': 'Trabalhando...', +'You are successfully running web2py': 'Você está executando o web2py com sucesso', +'You are successfully running web2py.': 'Você está executando o web2py com sucesso.', +'You can modify this application and adapt it to your needs': 'Você pode modificar esta aplicação e adaptá-la às suas necessidades', +'You visited the url %s': 'Você acessou a url %s', +} diff --git a/web2py/applications/SP/languages/pt.py b/web2py/applications/SP/languages/pt.py new file mode 100644 index 0000000..c71eb7b --- /dev/null +++ b/web2py/applications/SP/languages/pt.py @@ -0,0 +1,238 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'pt', +'!langname!': 'Português', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" é uma expressão opcional como "field1=\'newvalue\'". Não pode actualizar ou eliminar os resultados de um JOIN', +'%s %%{row} deleted': '%s linhas eliminadas', +'%s %%{row} updated': '%s linhas actualizadas', +'%s selected': '%s seleccionado(s)', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'@markmin\x01Number of entries: **%s**': 'Number of entries: **%s**', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'Sobre', +'Access Control': 'Controle de acesso', +'admin': 'administrador', +'Administrative Interface': 'Interface Administrativa', +'Administrative interface': 'Painel Administrativo', +'Ajax Recipes': 'Formulas Ajax', +'An error occured, please [[reload %s]] the page': 'Ocorreu um erro, por favor [[recarregue %s]] a página', +'API Example': 'API Example', +'appadmin is disabled because insecure channel': 'appadmin está desactivada pois o canal é inseguro', +'Are you sure you want to delete this object?': 'Tem a certeza que quer deletar este objeto?', +'Author Reference Auth User': 'Author Reference Auth User', +'Author Reference Auth User.username': 'Author Reference Auth User.username', +'Available Databases and Tables': 'bases de dados e tabelas disponíveis', +'Buy this book': 'Comprar este Livro', +"Buy web2py's book": 'Comprar Livros web2py', +'cache': 'cache', +'Cache': 'Cache', +'Cache Cleared': 'Cache Limpo', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'Cannot be empty': 'não pode ser vazio', +'Category Create': 'Criar Categoria', +'Category Select': 'Selecionar Categoria', +'change password': 'alterar palavra-chave', +'Check to delete': 'seleccione para eliminar', +'Clear CACHE?': 'apagar CACHE?', +'Clear DISK': 'apagar DISK', +'Clear RAM': 'apagar RAM', +'Comment Create': 'Criar Comentário', +'Comment Select': 'Selecionar Comentário', +'Community': 'Comunidade', +'Components and Plugins': 'Componentes e Plugins', +'Config.ini': 'Config.ini', +'Content': 'Conteudo', +'Controller': 'Controlador', +'Copyright': 'Direitos de Autor', +'create new category': 'Criar Nova Categoria', +'create new comment': 'Criar Novo Comentário', +'create new post': 'Criar novo post', +'Created By': 'Creado Por', +'Created On': 'Creado Em', +'Current request': 'Pedido Corrente', +'Current response': 'Resposta Corrente', +'Current session': 'Sessão Corrente', +'customize me!': 'Personaliza-me!', +'data uploaded': 'Informação enviada', +'Database': 'base de dados', +'Database %s select': 'selecção de base de dados %s', +'Database Administration (appadmin)': 'Base de Dados da Administração (appadmin)', +'db': 'bd', +'DB Model': 'Modelo de BD', +'Delete:': 'Eliminar:', +'Demo': 'Demo', +'Deployment Recipes': 'Deployment Recipes', +'design': 'design', +'Design': 'Design', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentação', +"Don't know what to do?": 'Não sabe o que fazer?', +'done!': 'concluído!', +'Download': 'Download', +'E-mail': 'E-mail', +'Edit': 'Editar', +'edit category': 'editar categoria', +'edit comment': 'editar comentário', +'Edit current record': 'Edição de registo currente', +'edit post': 'editar post', +'edit profile': 'Editar perfil', +'Edit This App': 'Edite esta aplicação', +'Email': 'Email', +'Email and SMS': 'Email e SMS', +'Enter an integer between %(min)g and %(max)g': 'Enter an integer between %(min)g and %(max)g', +'Errors': 'Erros', +'export as csv file': 'exportar como ficheiro csv', +'FAQ': 'FAQ', +'First name': 'First name', +'First Name': 'First Name', +'For %s #%s': 'For %s #%s', +'Forms and Validators': 'Forms and Validators', +'Free Applications': 'Free Applications', +'Graph Model': 'Graph Model', +'Grid Example': 'Grid Example', +'Groups': 'Groups', +'Hello World': 'Olá Mundo', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Home', +'How did you get here?': 'How did you get here?', +'import': 'import', +'Import/Export': 'Importar/Exportar', +'Index': 'Índice', +'insert new': 'inserir novo', +'insert new %s': 'inserir novo %s', +'Internal State': 'Estado interno', +'Introduction': 'Introdução', +'Invalid Query': 'Consulta Inválida', +'invalid request': 'Pedido Inválido', +'Key': 'Key', +'Last name': 'Last name', +'Last Name': 'Last Name', +'Layout': 'Esboço', +'Layout Plugins': 'Layout Plugins', +'Layouts': 'Layouts', +'Live Chat': 'Live Chat', +'Log In': 'Log In', +'login': 'login', +'Login': 'Login', +'logout': 'logout', +'Lost Password': 'Perdeu a Senha', +'Main Menu': 'Menu Principal', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Manage Cache', +'Memberships': 'Memberships', +'Menu Model': 'Menu do Modelo', +'Modified By': 'Modified By', +'Modified On': 'Modified On', +'My Sites': 'My Sites', +'Name': 'Nome', +'New Record': 'Novo Registo', +'new record inserted': 'novo registo inserido', +'next %s rows': 'next %s rows', +'next 100 rows': 'próximas 100 linhas', +'No Data': 'No Data', +'No databases in this application': 'Não há bases de dados nesta aplicação', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Online book': 'Livro Online', +'Online examples': 'Exemplos online', +'or import from csv file': 'ou importe a partir de ficheiro csv', +'Other Plugins': 'Other Plugins', +'Other Recipes': 'Other Recipes', +'Overview': 'Overview', +'Password': 'Password', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Plugins': 'Plugins', +'Post Create': 'Post Create', +'Post Select': 'Post Select', +'Powered by': 'Suportado por', +'Preface': 'Preface', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '100 linhas anteriores', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query:': 'Interrogação:', +'Quick Examples': 'Quick Examples', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Receitas', +'Record': 'registo', +'record does not exist': 'registo inexistente', +'Record id': 'id de registo', +'Register': 'Registar', +'register': 'registar', +'Registration identifier': 'Registration identifier', +'Registration key': 'Registration key', +'Remember me (for 30 days)': 'Lembrar de mim (por 30 dias)', +'Replyto Reference Post': 'Replyto Reference Post', +'Reset Password key': 'Reset Password key', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Linhas numa tabela', +'Rows selected': 'Linhas seleccionadas', +'Save model as...': 'Save model as...', +'search category': 'search category', +'search comment': 'search comment', +'search post': 'search post', +'select category': 'select category', +'select comment': 'select comment', +'select post': 'select post', +'Semantic': 'Semantic', +'Services': 'Services', +'show category': 'show category', +'show comment': 'show comment', +'show post': 'show post', +'Sign Up': 'Registar-se', +'Sign up': 'Registar-se', +'Size of cache:': 'Size of cache:', +'state': 'estado', +'Statistics': 'Statistics', +'Stylesheet': 'Folha de estilo', +'submit': 'submeter', +'Submit': 'Submit', +'Support': 'Support', +'Sure you want to delete this object?': 'Tem a certeza que deseja eliminar este objecto?', +'Table': 'tabela', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'A "query" é uma condição do tipo "db.table1.field1==\'value\'". Algo como "db.table1.field1==db.table2.field2" resultaria num SQL JOIN.', +'The Core': 'The Core', +'The output of the file is a dictionary that was rendered by the view %s': 'The output of the file is a dictionary that was rendered by the view %s', +'The Views': 'The Views', +'This App': 'This App', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Title': 'Title', +'Traceback': 'Traceback', +'Twitter': 'Twitter', +'unable to parse csv file': 'não foi possível carregar ficheiro csv', +'Update:': 'Actualização:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Utilize (...)&(...) para AND, (...)|(...) para OR, e ~(...) para NOT para construir interrogações mais complexas.', +'User': 'User', +'Username': 'Username', +'Users': 'Users', +'Videos': 'Videos', +'View': 'Vista', +'Welcome %s': 'Bem-vindo(a) %s', +'Welcome to Gluonization': 'Bem vindo ao Web2py', +'Welcome to web2py': 'Bem-vindo(a) ao web2py', +'Welcome to web2py!': 'Bem-vindo(a) ao web2py!', +'When': 'When', +'Which called the function %s located in the file %s': 'Which called the function %s located in the file %s', +'Wiki Example': 'Wiki Example', +'Working...': 'Working...', +'You are successfully running web2py': 'You are successfully running web2py', +'You can modify this application and adapt it to your needs': 'You can modify this application and adapt it to your needs', +'You visited the url %s': 'You visited the url %s', +} diff --git a/web2py/applications/SP/languages/ro.py b/web2py/applications/SP/languages/ro.py new file mode 100644 index 0000000..059a19b --- /dev/null +++ b/web2py/applications/SP/languages/ro.py @@ -0,0 +1,410 @@ +# -*- coding: utf-8 -*- +{ +'!=': '!=', +'!langcode!': 'ro', +'!langname!': 'Română', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" (actualizează) este o expresie opțională precum "câmp1=\'valoare_nouă\'". Nu puteți actualiza sau șterge rezultatele unui JOIN', +'%(nrows)s records found': '%(nrows)s înregistrări găsite', +'%d days ago': '%d days ago', +'%d weeks ago': '%d weeks ago', +'%s %%{row} deleted': '%s linii șterse', +'%s %%{row} updated': '%s linii actualizate', +'%s selected': '%s selectat(e)', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'(something like "it-it")': '(ceva ce seamănă cu "it-it")', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'1 day ago': '1 day ago', +'1 week ago': '1 week ago', +'<': '<', +'<=': '<=', +'=': '=', +'>': '>', +'>=': '>=', +'?': '?', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'A new version of web2py is available': 'O nouă versiune de web2py este disponibilă', +'A new version of web2py is available: %s': 'O nouă versiune de web2py este disponibilă: %s', +'About': 'Despre', +'about': 'despre', +'About application': 'Despre aplicație', +'Access Control': 'Control acces', +'Add': 'Adaugă', +'additional code for your application': 'cod suplimentar pentru aplicația dvs.', +'admin': 'admin', +'admin disabled because no admin password': 'administrare dezactivată deoarece parola de administrator nu a fost furnizată', +'admin disabled because not supported on google app engine': 'administrare dezactivată deoarece funcționalitatea nu e suportat pe Google App Engine', +'admin disabled because unable to access password file': 'administrare dezactivată deoarece nu există acces la fișierul cu parole', +'Admin is disabled because insecure channel': 'Adminstrarea este dezactivată deoarece conexiunea nu este sigură', +'Admin is disabled because unsecure channel': 'Administrarea este dezactivată deoarece conexiunea nu este securizată', +'Administration': 'Administrare', +'Administrative Interface': 'Interfață administrare', +'Administrator Password:': 'Parolă administrator:', +'Ajax Recipes': 'Rețete Ajax', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'And': 'Și', +'and rename it (required):': 'și renumiți (obligatoriu):', +'and rename it:': ' și renumiți:', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'appadmin dezactivat deoarece conexiunea nu e sigură', +'application "%s" uninstalled': 'aplicația "%s" a fost dezinstalată', +'application compiled': 'aplicația a fost compilată', +'application is compiled and cannot be designed': 'aplicația este compilată și nu poate fi editată', +'Are you sure you want to delete file "%s"?': 'Sigur ștergeți fișierul "%s"?', +'Are you sure you want to delete this object?': 'Sigur ștergeți acest obiect?', +'Are you sure you want to uninstall application "%s"': 'Sigur dezinstalați aplicația "%s"', +'Are you sure you want to uninstall application "%s"?': 'Sigur dezinstalați aplicația "%s"?', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATENȚIE: Nu vă puteți conecta decât utilizând o conexiune securizată (HTTPS) sau rulând aplicația pe computerul local.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATENȚIE: Nu puteți efectua mai multe teste o dată deoarece lansarea în execuție a mai multor subpocese nu este sigură.', +'ATTENTION: you cannot edit the running application!': 'ATENȚIE: nu puteți edita o aplicație în curs de execuție!', +'Authentication': 'Autentificare', +'Available Databases and Tables': 'Baze de date și tabele disponibile', +'Back': 'Înapoi', +'Buy this book': 'Cumpără această carte', +"Buy web2py's book": "Buy web2py's book", +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Chei cache', +'cache, errors and sessions cleaned': 'cache, erori și sesiuni golite', +'Cannot be empty': 'Nu poate fi vid', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Compilare imposibilă: aplicația conține erori. Debogați aplicația și încercați din nou.', +'cannot create file': 'fișier imposibil de creat', +'cannot upload file "%(filename)s"': 'imposibil de încărcat fișierul "%(filename)s"', +'Change Password': 'Schimbare parolă', +'Change password': 'Schimbare parolă', +'change password': 'schimbare parolă', +'check all': 'coșați tot', +'Check to delete': 'Coșați pentru a șterge', +'clean': 'golire', +'Clear': 'Golește', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'click to check for upgrades': 'Clic pentru a verifica dacă există upgrade-uri', +'Client IP': 'IP client', +'Community': 'Comunitate', +'compile': 'compilare', +'compiled application removed': 'aplicația compilată a fost ștearsă', +'Components and Plugins': 'Componente și plugin-uri', +'Config.ini': 'Config.ini', +'contains': 'conține', +'Controller': 'Controlor', +'Controllers': 'Controlori', +'controllers': 'controlori', +'Copyright': 'Drepturi de autor', +'create file with filename:': 'crează fișier cu numele:', +'Create new application': 'Creați aplicație nouă', +'create new application:': 'crează aplicație nouă:', +'crontab': 'crontab', +'Current request': 'Cerere curentă', +'Current response': 'Răspuns curent', +'Current session': 'Sesiune curentă', +'currently saved or': 'în prezent salvat sau', +'customize me!': 'Personalizează-mă!', +'data uploaded': 'date încărcate', +'Database': 'bază de date', +'Database %s select': 'selectare bază de date %s', +'database administration': 'administrare bază de date', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Data și ora', +'db': 'db', +'DB Model': 'Model bază de date', +'defines tables': 'definire tabele', +'Delete': 'Șterge', +'delete': 'șterge', +'delete all checked': 'șterge tot ce e coșat', +'Delete:': 'Șterge:', +'Demo': 'Demo', +'Deploy on Google App Engine': 'Instalare pe Google App Engine', +'Deployment Recipes': 'Rețete de instalare', +'Description': 'Descriere', +'design': 'design', +'DESIGN': 'DESIGN', +'Design': 'Design', +'Design for': 'Design pentru', +'DISK': 'DISK', +'Disk Cache Keys': 'Chei cache de disc', +'Disk Cleared': 'Disk Cleared', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentație', +"Don't know what to do?": 'Nu știți ce să faceți?', +'done!': 'gata!', +'Download': 'Descărcare', +'E-mail': 'E-mail', +'E-mail invalid': 'E-mail invalid', +'edit': 'editare', +'EDIT': 'EDITARE', +'Edit': 'Editare', +'Edit application': 'Editare aplicație', +'edit controller': 'editare controlor', +'Edit current record': 'Editare înregistrare curentă', +'Edit Profile': 'Editare profil', +'edit profile': 'editare profil', +'Edit This App': 'Editați această aplicație', +'Editing file': 'Editare fișier', +'Editing file "%s"': 'Editare fișier "%s"', +'Email and SMS': 'E-mail și SMS', +'enter a number between %(min)g and %(max)g': 'introduceți un număr între %(min)g și %(max)g', +'enter an integer between %(min)g and %(max)g': 'introduceți un întreg între %(min)g și %(max)g', +'Error logs for "%(app)s"': 'Log erori pentru "%(app)s"', +'errors': 'erori', +'Errors': 'Erori', +'Export': 'Export', +'export as csv file': 'exportă ca fișier csv', +'exposes': 'expune', +'extends': 'extinde', +'failed to reload module': 'reîncarcare modul nereușită', +'False': 'Neadevărat', +'FAQ': 'Întrebări frecvente', +'file "%(filename)s" created': 'fișier "%(filename)s" creat', +'file "%(filename)s" deleted': 'fișier "%(filename)s" șters', +'file "%(filename)s" uploaded': 'fișier "%(filename)s" încărcat', +'file "%(filename)s" was not deleted': 'fișierul "%(filename)s" n-a fost șters', +'file "%s" of %s restored': 'fișier "%s" de %s restaurat', +'file changed on disk': 'fișier modificat pe disc', +'file does not exist': 'fișier inexistent', +'file saved on %(time)s': 'fișier salvat %(time)s', +'file saved on %s': 'fișier salvat pe %s', +'First name': 'Prenume', +'Forbidden': 'Interzis', +'Forms and Validators': 'Formulare și validatori', +'Free Applications': 'Aplicații gratuite', +'Functions with no doctests will result in [passed] tests.': 'Funcțiile fără doctests vor genera teste [trecute].', +'Graph Model': 'Graph Model', +'Group %(group_id)s created': 'Grup %(group_id)s creat', +'Group ID': 'ID grup', +'Group uniquely assigned to user %(id)s': 'Grup asociat în mod unic utilizatorului %(id)s', +'Groups': 'Grupuri', +'Hello World': 'Salutare lume', +'help': 'ajutor', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Acasă', +'How did you get here?': 'Cum ați ajuns aici?', +'htmledit': 'editare html', +'import': 'import', +'Import/Export': 'Import/Export', +'includes': 'include', +'Index': 'Index', +'insert new': 'adaugă nou', +'insert new %s': 'adaugă nou %s', +'Installed applications': 'Aplicații instalate', +'internal error': 'eroare internă', +'Internal State': 'Stare internă', +'Introduction': 'Introducere', +'Invalid action': 'Acțiune invalidă', +'Invalid email': 'E-mail invalid', +'invalid password': 'parolă invalidă', +'Invalid password': 'Parolă invalidă', +'Invalid Query': 'Interogare invalidă', +'invalid request': 'cerere invalidă', +'invalid ticket': 'tichet invalid', +'Key': 'Key', +'language file "%(filename)s" created/updated': 'fișier de limbă "%(filename)s" creat/actualizat', +'Language files (static strings) updated': 'Fișierele de limbă (șirurile statice de caractere) actualizate', +'languages': 'limbi', +'Languages': 'Limbi', +'languages updated': 'limbi actualizate', +'Last name': 'Nume', +'Last saved on:': 'Ultima salvare:', +'Layout': 'Șablon', +'Layout Plugins': 'Șablon plugin-uri', +'Layouts': 'Șabloane', +'License for': 'Licență pentru', +'Live Chat': 'Chat live', +'loading...': 'încarc...', +'Log In': 'Log In', +'Logged in': 'Logat', +'Logged out': 'Delogat', +'Login': 'Autentificare', +'login': 'autentificare', +'Login to the Administrative Interface': 'Logare interfață de administrare', +'logout': 'ieșire', +'Logout': 'Ieșire', +'Lost Password': 'Parolă pierdută', +'Lost password?': 'Parolă pierdută?', +'Main Menu': 'Meniu principal', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Manage Cache', +'Memberships': 'Memberships', +'Menu Model': 'Model meniu', +'merge': 'unește', +'Models': 'Modele', +'models': 'modele', +'Modules': 'Module', +'modules': 'module', +'My Sites': 'Site-urile mele', +'Name': 'Nume', +'New': 'Nou', +'new application "%s" created': 'aplicația nouă "%s" a fost creată', +'New password': 'Parola nouă', +'New Record': 'Înregistrare nouă', +'new record inserted': 'înregistrare nouă adăugată', +'next %s rows': 'next %s rows', +'next 100 rows': 'următoarele 100 de linii', +'NO': 'NU', +'No databases in this application': 'Aplicație fără bază de date', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Object or table name': 'Obiect sau nume de tabel', +'Old password': 'Parola veche', +'Online book': 'Online book', +'Online examples': 'Exemple online', +'Or': 'Sau', +'or import from csv file': 'sau importă din fișier csv', +'or provide application url:': 'sau furnizează adresă url:', +'Origin': 'Origine', +'Original/Translation': 'Original/Traducere', +'Other Plugins': 'Alte plugin-uri', +'Other Recipes': 'Alte rețete', +'Overview': 'Prezentare de ansamblu', +'pack all': 'împachetează toate', +'pack compiled': 'pachet compilat', +'Password': 'Parola', +"Password fields don't match": 'Câmpurile de parolă nu se potrivesc', +'Peeking at file': 'Vizualizare fișier', +'Permission': 'Permission', +'Permissions': 'Permissions', +'please input your password again': 'introduceți parola din nou', +'Plugins': 'Plugin-uri', +'Powered by': 'Pus în mișcare de', +'Preface': 'Prefață', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '100 de linii anterioare', +'Profile': 'Profil', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query': 'Interogare', +'Query:': 'Interogare:', +'Quick Examples': 'Exemple rapide', +'RAM': 'RAM', +'RAM Cache Keys': 'Chei cache RAM', +'Ram Cleared': 'Ram Cleared', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Rețete', +'Record': 'înregistrare', +'record does not exist': 'înregistrare inexistentă', +'Record ID': 'ID înregistrare', +'Record id': 'id înregistrare', +'register': 'înregistrare', +'Register': 'Înregistrare', +'Registration identifier': 'Identificator de autentificare', +'Registration key': 'Cheie înregistrare', +'Registration successful': 'Autentificare reușită', +'Remember me (for 30 days)': 'Ține-mă minte (timp de 30 de zile)', +'remove compiled': 'șterge compilate', +'Request reset password': 'Cerere resetare parolă', +'Reset Password key': 'Cheie restare parolă', +'Resolve Conflict file': 'Fișier rezolvare conflict', +'restore': 'restaurare', +'revert': 'revenire', +'Role': 'Rol', +'Roles': 'Roles', +'Rows in Table': 'Linii în tabel', +'Rows selected': 'Linii selectate', +'save': 'salvare', +'Save model as...': 'Save model as...', +'Save profile': 'Salvează profil', +'Saved file hash:': 'Hash fișier salvat:', +'Search': 'Căutare', +'Semantic': 'Semantică', +'Services': 'Servicii', +'session expired': 'sesiune expirată', +'shell': 'line de commandă', +'Sign Up': 'Sign Up', +'site': 'site', +'Size of cache:': 'Size of cache:', +'some files could not be removed': 'anumite fișiere n-au putut fi șterse', +'starts with': 'începe cu', +'state': 'stare', +'static': 'static', +'Static files': 'Fișiere statice', +'Statistics': 'Statistics', +'Stylesheet': 'Foaie de stiluri', +'Submit': 'Înregistrează', +'submit': 'submit', +'Support': 'Suport', +'Sure you want to delete this object?': 'Sigur ștergeți acest obiect?', +'Table': 'tabel', +'Table name': 'Nume tabel', +'test': 'test', +'Testing application': 'Testare aplicație', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"Interogarea (query)" este o condiție de tipul "db.tabel1.câmp1==\'valoare\'". Ceva de genul "db.tabel1.câmp1==db.tabel2.câmp2" generează un JOIN SQL.', +'the application logic, each URL path is mapped in one exposed function in the controller': 'logica aplicației, fiecare rută URL este mapată într-o funcție expusă de controlor', +'The Core': 'Nucleul', +'the data representation, define database tables and sets': 'reprezentarea datelor, definește tabelele bazei de date și seturile (de date)', +'The output of the file is a dictionary that was rendered by the view %s': 'Fișierul produce un dicționar care a fost prelucrat de vederea %s', +'the presentations layer, views are also known as templates': 'nivelul de prezentare, vederile sunt de asemenea numite și șabloane', +'The Views': 'Vederile', +'There are no controllers': 'Nu există controlori', +'There are no models': 'Nu există modele', +'There are no modules': 'Nu există module', +'There are no static files': 'Nu există fișiere statice', +'There are no translators, only default language is supported': 'Nu există traduceri, doar limba implicită este suportată', +'There are no views': 'Nu există vederi', +'these files are served without processing, your images go here': 'aceste fișiere sunt servite fără procesare, imaginea se plasează acolo', +'This App': 'Această aplicație', +'This is a copy of the scaffolding application': 'Aceasta este o copie a aplicației schelet', +'This is the %(filename)s template': 'Aceasta este șablonul fișierului %(filename)s', +'Ticket': 'Tichet', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'Moment în timp (timestamp)', +'to previous version.': 'la versiunea anterioară.', +'too short': 'prea scurt', +'Traceback': 'Traceback', +'translation strings for the application': 'șiruri de caractere folosite la traducerea aplicației', +'True': 'Adevărat', +'try': 'încearcă', +'try something like': 'încearcă ceva de genul', +'Twitter': 'Twitter', +'Unable to check for upgrades': 'Imposibil de verificat dacă există actualizări', +'unable to create application "%s"': 'imposibil de creat aplicația "%s"', +'unable to delete file "%(filename)s"': 'imposibil de șters fișierul "%(filename)s"', +'Unable to download': 'Imposibil de descărcat', +'Unable to download app': 'Imposibil de descărcat aplicația', +'unable to parse csv file': 'imposibil de analizat fișierul csv', +'unable to uninstall "%s"': 'imposibil de dezinstalat "%s"', +'uncheck all': 'decoșează tot', +'uninstall': 'dezinstalează', +'update': 'actualizează', +'update all languages': 'actualizează toate limbile', +'Update:': 'Actualizare:', +'upload application:': 'incarcă aplicația:', +'Upload existing application': 'Încarcă aplicația existentă', +'upload file:': 'încarcă fișier:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Folosiți (...)&(...) pentru AND, (...)|(...) pentru OR, și ~(...) pentru NOT, pentru a crea interogări complexe.', +'User': 'User', +'User %(id)s Logged-in': 'Utilizator %(id)s autentificat', +'User %(id)s Logged-out': 'Utilizator %(id)s delogat', +'User %(id)s Password changed': 'Parola utilizatorului %(id)s a fost schimbată', +'User %(id)s Password reset': 'Resetare parola utilizator %(id)s', +'User %(id)s Profile updated': 'Profil utilizator %(id)s actualizat', +'User %(id)s Registered': 'Utilizator %(id)s înregistrat', +'User ID': 'ID utilizator', +'Users': 'Users', +'value already in database or empty': 'Valoare existentă în baza de date sau vidă', +'Verify Password': 'Verifică parola', +'versioning': 'versiuni', +'Videos': 'Video-uri', +'View': 'Vedere', +'view': 'vedere', +'Views': 'Vederi', +'views': 'vederi', +'web2py is up to date': 'web2py este la zi', +'web2py Recent Tweets': 'Ultimele tweet-uri web2py', +'Welcome': 'Bine ați venit', +'Welcome %s': 'Bine ați venit %s', +'Welcome to web2py': 'Bun venit la web2py', +'Welcome to web2py!': 'Bun venit la web2py!', +'Which called the function %s located in the file %s': 'Care a apelat funcția %s prezentă în fișierul %s', +'Working...': 'Working...', +'YES': 'DA', +'You are successfully running web2py': 'Rulați cu succes web2py', +'You can modify this application and adapt it to your needs': 'Puteți modifica și adapta aplicația nevoilor dvs.', +'You visited the url %s': 'Ați vizitat adresa %s', +} diff --git a/web2py/applications/SP/languages/ru.py b/web2py/applications/SP/languages/ru.py new file mode 100644 index 0000000..0f9e09d --- /dev/null +++ b/web2py/applications/SP/languages/ru.py @@ -0,0 +1,232 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'ru', +'!langname!': 'Русский', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Изменить" - необязательное выражение вида "field1=\'новое значение\'". Результаты операции JOIN нельзя изменить или удалить.', +'%d days ago': '%d %%{день} тому', +'%d hours ago': '%d %%{час} тому', +'%d minutes ago': '%d %%{минуту} тому', +'%d months ago': '%d %%{месяц} тому', +'%d seconds ago': '%d %%{секунду} тому', +'%d weeks ago': '%d %%{неделю} тому', +'%d years ago': '%d %%{год} тому', +'%s %%{row} deleted': '%%{!удалена[0]} %s %%{строка[0]}', +'%s %%{row} updated': '%%{!изменена[0]} %s %%{строка[0]}', +'%s selected': '%%{!выбрана[0]} %s %%{запись[0]}', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'1 day ago': '1 день тому', +'1 hour ago': '1 час тому', +'1 minute ago': '1 минуту тому', +'1 month ago': '1 месяц тому', +'1 second ago': '1 секунду тому', +'1 week ago': '1 неделю тому', +'1 year ago': '1 год тому', +'?': '?', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'About', +'Access Control': 'Access Control', +'admin': 'admin', +'Administrative Interface': 'Administrative Interface', +'Administrative interface': 'административный интерфейс', +'Ajax Recipes': 'Ajax Recipes', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'appadmin is disabled because insecure channel': 'appadmin is disabled because insecure channel', +'Are you sure you want to delete this object?': 'Вы уверены, что хотите удалить этот объект?', +'Available Databases and Tables': 'Базы данных и таблицы', +'Buy this book': 'Buy this book', +"Buy web2py's book": "Buy web2py's book", +'cache': 'cache', +'Cache': 'Cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'Cannot be empty': 'Пустое значение недопустимо', +'Change Password': 'Смените пароль', +'Check to delete': 'Удалить', +'Check to delete:': 'Удалить:', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Client IP': 'Client IP', +'Community': 'Community', +'Components and Plugins': 'Components and Plugins', +'Config.ini': 'Config.ini', +'Controller': 'Controller', +'Copyright': 'Copyright', +'Current request': 'Текущий запрос', +'Current response': 'Текущий ответ', +'Current session': 'Текущая сессия', +'customize me!': 'настройте внешний вид!', +'data uploaded': 'данные загружены', +'Database': 'Database', +'Database %s select': 'выбор базы данных %s', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'db': 'БД', +'DB Model': 'DB Model', +'Delete:': 'Удалить:', +'Demo': 'Demo', +'Deployment Recipes': 'Deployment Recipes', +'Description': 'Описание', +'design': 'дизайн', +'Design': 'Design', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentation', +"Don't know what to do?": "Don't know what to do?", +'done!': 'готово!', +'Download': 'Download', +'E-mail': 'E-mail', +'Edit current record': 'Редактировать текущую запись', +'Edit Profile': 'Редактировать профиль', +'Email and SMS': 'Email and SMS', +'enter an integer between %(min)g and %(max)g': 'enter an integer between %(min)g and %(max)g', +'Errors': 'Errors', +'export as csv file': 'экспорт в csv-файл', +'FAQ': 'FAQ', +'First name': 'Имя', +'Forms and Validators': 'Forms and Validators', +'Free Applications': 'Free Applications', +'Graph Model': 'Graph Model', +'Group ID': 'Group ID', +'Groups': 'Groups', +'Hello World': 'Заработало!', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Home', +'How did you get here?': 'How did you get here?', +'import': 'import', +'Import/Export': 'Импорт/экспорт', +'insert new': 'добавить', +'insert new %s': 'добавить %s', +'Internal State': 'Внутренне состояние', +'Introduction': 'Introduction', +'Invalid email': 'Неверный email', +'Invalid login': 'Неверный логин', +'Invalid password': 'Неверный пароль', +'Invalid Query': 'Неверный запрос', +'invalid request': 'неверный запрос', +'Key': 'Key', +'Last name': 'Фамилия', +'Layout': 'Layout', +'Layout Plugins': 'Layout Plugins', +'Layouts': 'Layouts', +'Live Chat': 'Live Chat', +'Log In': 'Log In', +'Logged in': 'Вход выполнен', +'Logged out': 'Выход выполнен', +'login': 'вход', +'Login': 'Вход', +'logout': 'выход', +'Logout': 'Выход', +'Lost Password': 'Забыли пароль?', +'Lost password?': 'Lost password?', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Manage Cache', +'Memberships': 'Memberships', +'Menu Model': 'Menu Model', +'My Sites': 'My Sites', +'Name': 'Name', +'New password': 'Новый пароль', +'New Record': 'Новая запись', +'new record inserted': 'новая запись добавлена', +'next %s rows': 'next %s rows', +'next 100 rows': 'следующие 100 строк', +'No databases in this application': 'В приложении нет баз данных', +'now': 'сейчас', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Object or table name': 'Object or table name', +'Old password': 'Старый пароль', +'Online book': 'Online book', +'Online examples': 'примеры он-лайн', +'or import from csv file': 'или импорт из csv-файла', +'Origin': 'Происхождение', +'Other Plugins': 'Other Plugins', +'Other Recipes': 'Other Recipes', +'Overview': 'Overview', +'Password': 'Пароль', +'password': 'пароль', +"Password fields don't match": 'Пароли не совпадают', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Plugins': 'Plugins', +'Powered by': 'Powered by', +'Preface': 'Preface', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'предыдущие 100 строк', +'profile': 'профиль', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query:': 'Запрос:', +'Quick Examples': 'Quick Examples', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Recipes', +'Record': 'Record', +'record does not exist': 'запись не найдена', +'Record ID': 'ID записи', +'Record id': 'id записи', +'Register': 'Зарегистрироваться', +'Registration identifier': 'Registration identifier', +'Registration key': 'Ключ регистрации', +'Remember me (for 30 days)': 'Запомнить меня (на 30 дней)', +'Reset Password key': 'Сбросить ключ пароля', +'Role': 'Роль', +'Roles': 'Roles', +'Rows in Table': 'Строк в таблице', +'Rows selected': 'Выделено строк', +'Save model as...': 'Save model as...', +'Semantic': 'Semantic', +'Services': 'Services', +'Sign Up': 'Sign Up', +'Size of cache:': 'Size of cache:', +'state': 'состояние', +'Statistics': 'Statistics', +'Stylesheet': 'Stylesheet', +'submit': 'submit', +'Submit': 'Отправить', +'Support': 'Support', +'Sure you want to delete this object?': 'Подтвердите удаление объекта', +'Table': 'таблица', +'Table name': 'Имя таблицы', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"Запрос" - это условие вида "db.table1.field1==\'значение\'". Выражение вида "db.table1.field1==db.table2.field2" формирует SQL JOIN.', +'The Core': 'The Core', +'The output of the file is a dictionary that was rendered by the view %s': 'The output of the file is a dictionary that was rendered by the view %s', +'The Views': 'The Views', +'This App': 'This App', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'Отметка времени', +'Traceback': 'Traceback', +'Twitter': 'Twitter', +'unable to parse csv file': 'нечитаемый csv-файл', +'Update:': 'Изменить:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Для построение сложных запросов используйте операторы "И": (...)&(...), "ИЛИ": (...)|(...), "НЕ": ~(...).', +'User': 'User', +'User %(id)s Logged-in': 'Пользователь %(id)s вошёл', +'User %(id)s Logged-out': 'Пользователь %(id)s вышел', +'User %(id)s Password changed': 'Пользователь %(id)s сменил пароль', +'User %(id)s Profile updated': 'Пользователь %(id)s обновил профиль', +'User %(id)s Registered': 'Пользователь %(id)s зарегистрировался', +'User ID': 'ID пользователя', +'Users': 'Users', +'Verify Password': 'Повторите пароль', +'Videos': 'Videos', +'View': 'View', +'Welcome': 'Welcome', +'Welcome to web2py': 'Добро пожаловать в web2py', +'Welcome to web2py!': 'Welcome to web2py!', +'Which called the function %s located in the file %s': 'Which called the function %s located in the file %s', +'Working...': 'Working...', +'You are successfully running web2py': 'You are successfully running web2py', +'You can modify this application and adapt it to your needs': 'You can modify this application and adapt it to your needs', +'You visited the url %s': 'You visited the url %s', +} diff --git a/web2py/applications/SP/languages/sk.py b/web2py/applications/SP/languages/sk.py new file mode 100644 index 0000000..01d3106 --- /dev/null +++ b/web2py/applications/SP/languages/sk.py @@ -0,0 +1,208 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'sk', +'!langname!': 'Slovenský', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" je voliteľný výraz ako "field1=\'newvalue\'". Nemôžete upravovať alebo zmazať výsledky JOINu', +'%s %%{row} deleted': '%s zmazaných záznamov', +'%s %%{row} updated': '%s upravených záznamov', +'%s selected': '%s označených', +'%Y-%m-%d': '%d.%m.%Y', +'%Y-%m-%d %H:%M:%S': '%d.%m.%Y %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'O nás', +'Access Control': 'Kontrola prístupu', +'admin': 'admin', +'Administrative Interface': 'Administrátorské rozhranie', +'Administrative interface': 'pre administrátorské rozhranie kliknite sem', +'Ajax Recipes': 'Ajax recepty', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'appadmin is disabled because insecure channel': 'appadmin je zakázaný bez zabezpečeného spojenia', +'Are you sure you want to delete this object?': 'Ste si istý, že chcete vymazať tento objekt?', +'Available Databases and Tables': 'Dostupné databázy a tabuľky', +'Buy this book': 'Kúpte si túto knihu', +"Buy web2py's book": "Kúpte si web2py's knihu", +'cache': 'cache', +'Cache': 'Cache', +'Cache Cleared': 'Cache vymazané', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache kľúče', +'Cannot be empty': 'Nemôže byť prázdne', +'Check to delete': 'Označiť na zmazanie', +'Clear CACHE?': 'Vyčistiť CACHE?', +'Clear DISK': 'Vyčistiť DISK', +'Clear RAM': 'Vyčistiť RAM', +'Community': 'komunita', +'Components and Plugins': 'Komponenty a pluginy', +'Config.ini': 'Config.ini', +'Controller': 'Kontrolér', +'Copyright': 'Copyright', +'Current request': 'Aktuálna požiadavka', +'Current response': 'Aktuálna odpoveď', +'Current session': 'Aktuálne sedenie', +'customize me!': 'prispôsob ma!', +'data uploaded': 'údaje naplnené', +'Database': 'Databáza', +'Database %s select': 'Databáza %s výber', +'Database Administration (appadmin)': 'Správa databázy (appadmin)', +'db': 'db', +'DB Model': 'DB Model', +'Delete:': 'Zmazať:', +'Demo': 'Demo', +'Deployment Recipes': 'Recepty pre nasadenie', +'Description': 'Popis', +'design': 'návrh', +'Design': 'Návrh', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk vyčistený', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Dokumentácia', +"Don't know what to do?": 'Neviete, čo robiť?', +'done!': 'hotovo!', +'Download': 'Stiahnuť', +'Edit': 'Upraviť', +'Edit current record': 'Upraviť aktuálny záznam', +'Edit Profile': 'Upraviť profil', +'Email and SMS': 'Email a SMS', +'Errors': 'Chyby', +'export as csv file': 'exportovať do csv súboru', +'FAQ': 'FAQ', +'First name': 'Krstné meno', +'Forms and Validators': 'Formuláre a schvalovače', +'Free Applications': 'Aplikácie zadarmo', +'Graph Model': 'Model grafu', +'Group ID': 'ID skupiny', +'Groups': 'Skupiny', +'Hello World': 'Ahoj svet', +'Helping web2py': 'Pomáhať web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Domov', +'How did you get here?': 'Ako ste sa sem dostali?', +'import': 'import', +'Import/Export': 'Import/Export', +'Index': 'Index', +'insert new': 'vložiť nový', +'insert new %s': 'vložiť nový%s', +'Internal State': 'Vnútorný stav', +'Introduction': 'Úvod', +'Invalid email': 'Neplatný email', +'Invalid password': 'Nesprávne heslo', +'Invalid Query': 'Neplatná otázka', +'invalid request': 'Neplatná požiadavka', +'Key': 'Kľúč', +'Last name': 'Priezvisko', +'Layout': 'Usporiadanie', +'Layout Plugins': 'Pluginy pre usporiadanie', +'Layouts': 'Usporiadania', +'Live Chat': 'Živý Chat', +'Log In': 'Prihlásiť sa', +'Logged in': 'Prihlásený', +'Logged out': 'Odhlásený', +'login': 'prihlásiť', +'logout': 'odhlásiť', +'Lost Password': 'Stratené heslo?', +'lost password?': 'stratené heslo?', +'Manage %(action)s': 'Spravovať %(action)s', +'Manage Access Control': 'Spravovať kontrolu prístupu', +'Manage Cache': 'Spravovať cache', +'Memberships': 'Členstvá', +'Menu Model': 'Model menu', +'My Sites': 'Moje stránky', +'Name': 'Meno', +'New password': 'Nové heslo', +'New Record': 'Nový záznam', +'new record inserted': 'nový záznam bol vložený', +'next %s rows': 'next %s rows', +'next 100 rows': 'ďalších 100 riadkov', +'No databases in this application': 'V tejto aplikácii nie sú databázy', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Old password': 'Staré heslo', +'Online book': 'Online kniha', +'Online examples': 'online príklady', +'or import from csv file': 'alebo naimportovať z csv súboru', +'Origin': 'Pôvod', +'Other Plugins': 'Ostatné pluginy', +'Other Recipes': 'Ostatné recepty', +'Overview': 'Náhľad', +'password': 'heslo', +'Password': 'Heslo', +'Permission': 'Povolenie', +'Permissions': 'Povolenia', +'Plugins': 'Pluginy', +'Powered by': 'Beží na', +'Preface': 'Predslov', +'previous %s rows': 'predchádzajúce %s riadky', +'previous 100 rows': 'predchádzajúcich 100 riadkov', +'pygraphviz library not found': 'knižnica pygraphviz nenájdená', +'Python': 'Python', +'Query:': 'Otázka:', +'Quick Examples': 'Rýchle príklady', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM cache kľúče', +'Ram Cleared': 'Ram vyčistená', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Recepty', +'Record': 'Záznam', +'record does not exist': 'záznam neexistuje', +'Record ID': 'ID záznamu', +'Record id': 'id záznamu', +'Register': 'Zaregistrovať sa', +'register': 'registrovať', +'Registration key': 'Registračný kľúč', +'Remember me (for 30 days)': 'Zapamätaj si ma (na 30 dní)', +'Reset Password key': 'Nastaviť registračný kľúč', +'Role': 'Rola', +'Roles': 'Role', +'Rows in Table': 'Riadkov v tabuľke', +'Rows selected': 'Označených riadkov', +'Save model as...': 'Uložiť model ako...', +'Semantic': 'Významový', +'Services': 'Služby', +'Sign Up': 'Prihlásiť sa', +'Size of cache:': 'Veľkosť cache:', +'state': 'stav', +'Statistics': 'Štatistiky', +'Stylesheet': 'Stylesheet', +'submit': 'odoslať', +'Submit': 'Odoslať', +'Support': 'Podpora', +'Sure you want to delete this object?': 'Ste si istí, že chcete zmazať tento objekt?', +'Table': 'Tabuľka', +'Table name': 'Názov tabuľky', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"query" je podmienka ako "db.table1.field1==\'value\'". Niečo ako "db.table1.field1==db.table2.field2" má za výsledok SQL JOIN.', +'The Core': 'Jadro', +'The output of the file is a dictionary that was rendered by the view %s': 'Výstup zo súboru je slovník, ktorý bol vykreslený v zobrazení %s', +'The Views': 'Zobrazenia', +'This App': 'Táto aplikácia', +'This is a copy of the scaffolding application': 'Toto je kópia skeletu aplikácie', +'Time in Cache (h:m:s)': 'Čas v cache (h:m:s)', +'Timestamp': 'Časová pečiatka', +'Traceback': 'Vystopovať', +'Twitter': 'Twitter', +'unable to parse csv file': 'nedá sa načítať csv súbor', +'Update:': 'Upraviť:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Použite (...)&(...) pre AND, (...)|(...) pre OR a ~(...) pre NOT na poskladanie komplexnejších otázok.', +'User': 'User', +'User %(id)s Logged-in': 'Používateľ %(id)s prihlásený', +'User %(id)s Logged-out': 'Používateľ %(id)s odhlásený', +'User %(id)s Password changed': 'Používateľ %(id)s zmenil heslo', +'User %(id)s Profile updated': 'Používateľ %(id)s upravil profil', +'User %(id)s Registered': 'Používateľ %(id)s sa zaregistroval', +'User ID': 'ID používateľa', +'Users': 'Používatelia', +'Verify Password': 'Zopakujte heslo', +'Videos': 'Videá', +'View': 'Zobraziť', +'Welcome to web2py': 'Vitajte vo web2py', +'Welcome to web2py!': 'Vitajte vo web2py!', +'Which called the function %s located in the file %s': 'Ktorý zavolal funkciu %s nachádzajúci sa v súbore %s', +'Working...': 'Pracuje...', +'You are successfully running web2py': 'Úspešne ste spustili web2py', +'You can modify this application and adapt it to your needs': 'Môžete upraviť túto aplikáciu a prispôsobiť ju svojim potrebám', +'You visited the url %s': 'Navštívili ste URL %s', +} diff --git a/web2py/applications/SP/languages/tr.py b/web2py/applications/SP/languages/tr.py new file mode 100644 index 0000000..63fb71a --- /dev/null +++ b/web2py/applications/SP/languages/tr.py @@ -0,0 +1,232 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'tr', +'!langname!': 'Türkçe', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"güncelle" ("update") "field1=\'yenideğer\'" gibi isteğe bağlı bir ifadedir. JON sonucu güncelleyemez veya silemzsiniz.', +'%s %%(shop)': '%s %%(shop)', +'%s %%(shop[0])': '%s %%(shop[0])', +'%s %%{quark[0]}': '%s %%{quark[0]}', +'%s %%{row} deleted': '%s %%{row} deleted', +'%s %%{row} updated': '%s %%{row} updated', +'%s %%{shop[0]}': '%s %%{shop[0]}', +'%s %%{shop}': '%s %%{shop}', +'%s selected': '%s selected', +'%Y-%m-%d': '%d-%m-%Y', +'%Y-%m-%d %H:%M:%S': '%d-%m-%Y %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'@markmin\x01**Hello World**': '**Merhaba Dünya**', +'@markmin\x01An error occured, please [[reload %s]] the page': 'Bir hata oluştu, lütfen sayfayı [[yenileyin yükleyin %s]] ', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'Hakkında', +'Access Control': 'Erişim Denetimi', +'admin': 'admin', +'Administrative Interface': 'Yönetim Arayüzü', +'Ajax Recipes': 'Ajax Tarifleri', +'An error occured, please %s the page': 'Bir hata meydana geldi, lütfen sayfayı %s', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'appadmin is disabled because insecure channel': 'appadmin is disabled because insecure channel', +'Apply changes': 'Değişiklikleri uygula', +'Are you sure you want to delete this object?': 'Bu nesneyi silmek istediğinden emin misin?', +'Available Databases and Tables': 'Kullanılabilir Varitabanları ve Tablolar', +'Buy this book': 'Bu kitabı satın alın', +"Buy web2py's book": "Buy web2py's book", +'cache': 'zula', +'Cache': 'Cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'Cannot be empty': 'Boş bırakılamaz', +'Change password': 'Parolayı değiştir', +'Check to delete': 'Silmek için denetle', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Client IP': 'İstemci IP', +'Community': 'Topluluk', +'Components and Plugins': 'Bileşenler ve Eklentiler', +'Config.ini': 'Config.ini', +'Controller': 'Denetçi', +'Copyright': 'Telif', +'Created By': 'Tasarlayan', +'Created On': 'Oluşturma tarihi', +'Current request': 'Current request', +'Current response': 'Current response', +'Current session': 'Current session', +'customize me!': 'burayı değiştir!', +'data uploaded': 'data uploaded', +'Database': 'Veritabanı', +'Database %s select': '%s veritabanı seç', +'Database Administration (appadmin)': 'Veritabanı Yönetimi (appadmin)', +'db': 'db', +'DB Model': 'DB Modeli', +'Delete:': 'Sil:', +'Demo': 'Tanıtım', +'Deployment Recipes': 'Yayınlama tarifleri', +'Description': 'Açıklama', +'design': 'tasarım', +'Design': 'Design', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Kitap', +"Don't know what to do?": 'Neleri nasıl yapacağını bilmiyor musun?', +'done!': 'done!', +'Download': 'İndir', +'E-mail': 'E-posta', +'Edit current record': 'Edit current record', +'Email and SMS': 'E-posta ve kısa mesaj (SMS)', +'enter a value': 'bir değer giriniz', +'enter an integer between %(min)g and %(max)g': '%(min)g ve %(max)g arasında bir sayı girin', +'enter date and time as %(format)s': 'tarih ve saati %(format)s biçiminde girin', +'Errors': 'Hatalar', +'Errors in form, please check it out.': 'Formda hatalar var, lütfen kontrol edin.', +'export as csv file': 'csv dosyası olarak dışa aktar', +'FAQ': 'SSS', +'First name': 'Ad', +'Forgot username?': 'Kullanıcı adını mı unuttun?', +'Forms and Validators': 'Biçimler ve Doğrulayıcılar', +'Free Applications': 'Ücretsiz uygulamalar', +'Giriş': 'Giriş', +'Graph Model': 'Grafik Modeli', +'Group %(group_id)s created': '%(group_id)s takımı oluşturuldu', +'Group ID': 'Takım ID', +'Group uniquely assigned to user %(id)s': 'Grup özgün olarak %(id)s kullanıcılara atandı', +'Groups': 'Gruplar', +'Hello World': 'Merhaba Dünya', +'Hello World ## comment': 'Merhaba Dünya ## yorum ', +'Hello World## comment': 'Merhaba Dünya## yorum ', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Anasayfa', +'How did you get here?': 'Bu sayfayı görüntüleme uğruna neler mi oldu?', +'import': 'import', +'Import/Export': 'Dışa/İçe Aktar', +'Internal State': 'Internal State', +'Introduction': 'Giriş', +'invalid controller': 'geçersiz denetleyici', +'Invalid email': 'Yanlış eposta', +'Invalid Query': 'Invalid Query', +'invalid request': 'invalid request', +'Is Active': 'Etkin', +'Kayıt ol': 'Kayıt ol', +'Key': 'Key', +'Last name': 'Soyad', +'Layout': 'Şablon', +'Layout Plugins': 'Şablon Eklentileri', +'Layouts': 'Şablonlar', +'Live Chat': 'Canlı Sohbet', +'Log In': 'Log In', +'Logged in': 'Giriş yapıldı', +'Logged out': 'Çıkış yapıldı', +'Login': 'Giriş', +'Logout': 'Terket', +'Lost Password': 'Şifremi unuttum', +'Lost password?': 'Şifrenizimi unuttunuz?', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Manage Cache', +'Memberships': 'Memberships', +'Menu Model': 'Model Menü', +'Modified By': 'Değiştiren', +'Modified On': 'Değiştirilme tarihi', +'My Sites': 'Sitelerim', +'Name': 'İsim', +'New password': 'Yeni parola', +'New Record': 'Yeni Kayıt', +'new record inserted': 'new record inserted', +'next %s rows': 'next %s rows', +'No databases in this application': 'No databases in this application', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Object or table name': 'Nesne ya da tablo adı', +'Old password': 'Eski parola', +'Online book': 'Online book', +'Online examples': 'Canlı örnekler', +'or import from csv file': 'veya csv dosyasından içe aktar', +'Origin': 'Asıl', +'Other Plugins': 'Diğer eklentiler', +'Other Recipes': 'Diğer Tarifler', +'Overview': 'Göz gezdir', +'Password': 'Parola', +"Password fields don't match": 'Parolalar uyuşmuyor', +'Permission': 'Permission', +'Permissions': 'Permissions', +'please input your password again': 'lütfen parolanızı tekrar girin', +'Plugins': 'Eklentiler', +'Powered by': 'Yazılım Temeli', +'Preface': 'Önzös', +'previous %s rows': 'previous %s rows', +'Profile': 'Profil', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query:': 'Sorgu:', +'Quick Examples': 'Hızlı Örnekler', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Tarifeler', +'Record': 'Record', +'record does not exist': 'record does not exist', +'Record ID': 'Kayıt ID', +'Record id': 'Record id', +'Register': 'Kayıt ol', +'Registration identifier': 'Kayıt belirleyicisi', +'Registration key': 'Kayıt anahtarı', +'Registration successful': 'Kayıt başarılı', +'reload': 'yeniden yükle', +'Remember me (for 30 days)': 'Beni hatırla (30 gün)', +'Request reset password': 'Parolanı sıfırla', +'Reset Password key': 'Parola anahtarını sıfırla', +'Role': 'Rol', +'Roles': 'Roles', +'Rows in Table': 'Tablodaki Satırlar', +'Rows selected': 'Rows selected', +'Save model as...': 'Modeli farklı kaydet...', +'Semantic': 'Anlamsal', +'Services': 'Hizmetler', +'Sign Up': 'Sign Up', +'Size of cache:': 'Size of cache:', +'state': 'durum', +'Statistics': 'Statistics', +'Stylesheet': 'Stil Şablonu', +'submit': 'gönder', +'Submit': 'Gönder', +'Support': 'Destek', +'Table': 'Tablo', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"sorgulama" "db.table1.field1==\'değer\'" şeklinde bir durumu ifade eder. SQL birleştirmede (JOIN) "db.table1.field1==db.table2.field2" şeklindedir.', +'The Core': 'Çekirdek', +'The output of the file is a dictionary that was rendered by the view %s': 'Son olarak fonksiyonların vs. işlenip %s dosyasıyla tasarıma yedirilmesiyle sayfayı görüntüledin', +'The Views': 'Görünümler', +'This App': 'Bu Uygulama', +'This email already has an account': 'Bu e-postaya ait bir hesap zaten var', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'Zaman damgası', +'Traceback': 'Traceback', +'Twitter': 'Twitter', +'unable to parse csv file': 'unable to parse csv file', +'Update:': 'Güncelle:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Karmaşık sorgularda Ve (AND) için (...)&(...) kullanın, Veya (OR) için (...)|(...) kullanın ve DEĞİL (NOT) için ~(...) kullanın. ', +'User': 'User', +'User %(id)s Logged-in': '%(id)s Giriş yaptı', +'User %(id)s Logged-out': '%(id)s çıkış yaptı', +'User %(id)s Password reset': 'Kullanıc %(id)s Parolasını sıfırla', +'User %(id)s Registered': '%(id)s Kayıt oldu', +'User ID': 'Kullanıcı ID', +'Users': 'Users', +'value already in database or empty': 'değer boş ya da veritabanında zaten mevcut', +'Verify Password': 'Parolanı Onayla', +'Videos': 'Videolar', +'View': 'Görünüm', +'Welcome': 'Hoşgeldin', +'Welcome to web2py!': "web2py'ye hoşgeldiniz!", +'Which called the function %s located in the file %s': 'Bu ziyaretle %s fonksiyonunu %s dosyasından çağırmış oldun ', +'Working...': 'Çalışıyor...', +'You are successfully running web2py': 'web2py çatısını çalıştırmayı başardın', +'You can modify this application and adapt it to your needs': 'Artık uygulamayı istediğin gibi düzenleyebilirsin!', +'You visited the url %s': '%s adresini ziyaret ettin', +} diff --git a/web2py/applications/SP/languages/uk.py b/web2py/applications/SP/languages/uk.py new file mode 100644 index 0000000..eb2678e --- /dev/null +++ b/web2py/applications/SP/languages/uk.py @@ -0,0 +1,260 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'uk', +'!langname!': 'Українська', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Оновити" це додатковий вираз, такий, як "field1=\'нове_значення\'". Ви не можете змінювати або вилучати дані об\'єднаних таблиць.', +'%d days ago': '%d %%{день} тому', +'%d hours ago': '%d %%{годину} тому', +'%d minutes ago': '%d %%{хвилину} тому', +'%d months ago': '%d %%{місяць} тому', +'%d secods ago': '%d %%{секунду} тому', +'%d weeks ago': '%d %%{тиждень} тому', +'%d years ago': '%d %%{рік} тому', +'%s %%{row} deleted': 'Вилучено %s %%{рядок}', +'%s %%{row} updated': 'Змінено %s %%{рядок}', +'%s selected': 'Вибрано %s %%{запис}', +'%Y-%m-%d': '%Y/%m/%d', +'%Y-%m-%d %H:%M:%S': '%Y/%m/%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'1 day ago': '1 день тому', +'1 hour ago': '1 годину тому', +'1 minute ago': '1 хвилину тому', +'1 month ago': '1 місяць тому', +'1 second ago': '1 секунду тому', +'1 week ago': '1 тиждень тому', +'1 year ago': '1 рік тому', +'?': '?', +'@markmin\x01(**%.0d MB**)': '(**``%.0d``:red МБ**)', +'@markmin\x01**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{елемент(items)}, **%(bytes)s** %%{байт(bytes)}', +'@markmin\x01``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**нема в наявності**``:red (потребує Пітонівської бібліотеки [[guppy [посилання відкриється у новому вікні] http://pypi.python.org/pypi/guppy/ popup]])', +'@markmin\x01An error occured, please [[reload %s]] the page': 'Сталась помилка, будь-ласка [[перевантажте %s]] сторінку', +'@markmin\x01Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': "Час життя об'єктів в КЕШІ сягає **%(hours)02d** %%{годину(hours)} **%(min)02d** %%{хвилину(min)} та **%(sec)02d** %%{секунду(sec)}.", +'@markmin\x01DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': "Час життя об'єктів в ДИСКОВОМУ КЕШІ сягає **%(hours)02d** %%{годину(hours)} **%(min)02d** %%{хвилину(min)} та **%(sec)02d** %%{секунду(sec)}.", +'@markmin\x01Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Оцінка поцілювання: **%(ratio)s%%** (**%(hits)s** %%{поцілювання(hits)} та **%(misses)s** %%{схибнення(misses)})', +'@markmin\x01Number of entries: **%s**': 'Кількість входжень: ``**%s**``:red', +'@markmin\x01RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': "Час життя об'єктів в ОЗП-КЕШІ сягає **%(hours)02d** %%{годину(hours)} **%(min)02d** %%{хвилину(min)} та **%(sec)02d** %%{секунду(sec)}.", +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'About': 'Про додаток', +'Access Control': 'Контроль доступу', +'admin': 'admin', +'Administrative Interface': 'Адміністративний інтерфейс', +'Ajax Recipes': 'Рецепти для Ajax', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'appadmin is disabled because insecure channel': 'використовується незахищенний канал (HTTP). Appadmin вимкнено', +'Are you sure you want to delete this object?': "Ви впевнені, що хочете вилучити цей об'єкт?", +'Available Databases and Tables': 'Доступні бази даних та таблиці', +'Buy this book': 'Купити книжку', +"Buy web2py's book": "Buy web2py's book", +'cache': 'кеш', +'Cache': 'Кеш', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Ключі кешу', +'Cannot be empty': 'Порожнє значення неприпустиме', +'Change password': 'Змінити пароль', +'Check to delete': 'Позначити для вилучення', +'Check to delete:': 'Позначте для вилучення:', +'Clear CACHE?': 'Очистити ВЕСЬ кеш?', +'Clear DISK': 'Очистити ДИСКОВИЙ кеш', +'Clear RAM': "Очистити кеш В ПАМ'ЯТІ", +'Client IP': 'IP клієнта', +'Community': 'Спільнота', +'Components and Plugins': 'Компоненти та втулки', +'Config.ini': 'Config.ini', +'Controller': 'Контролер', +'Copyright': 'Правовласник', +'Created By': 'Створив(ла)', +'Created On': 'Створено в', +'Current request': 'Поточний запит (current request)', +'Current response': 'Поточна відповідь (current response)', +'Current session': 'Поточна сесія (current session)', +'customize me!': 'причепуріть мене!', +'data uploaded': 'дані завантажено', +'Database': 'База даних', +'Database %s select': 'Вибірка з бази даних %s', +'Database Administration (appadmin)': 'Адміністрування Бази Даних (appadmin)', +'db': 'база даних', +'DB Model': 'Модель БД', +'Delete:': 'Вилучити:', +'Demo': 'Демо', +'Deployment Recipes': 'Способи розгортання', +'Description': 'Опис', +'design': 'налаштування', +'Design': 'Design', +'DISK': 'ДИСК', +'Disk Cache Keys': 'Ключі дискового кешу', +'Disk Cleared': 'Дисковий кеш очищено', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Документація', +"Don't know what to do?": 'Не знаєте що робити далі?', +'done!': 'зроблено!', +'Download': 'Завантажити', +'E-mail': 'Ел.пошта', +'edit': 'редагувати', +'Edit current record': 'Редагувати поточний запис', +'Edit Page': 'Редагувати сторінку', +'Email and SMS': 'Ел.пошта та SMS', +'enter a value': 'введіть значення', +'enter an integer between %(min)g and %(max)g': 'введіть ціле число між %(min)g та %(max)g', +'Error!': 'Помилка!', +'Errors': 'Помилки', +'Errors in form, please check it out.': 'У формі є помилка. Виправте її, будь-ласка.', +'export as csv file': 'експортувати як файл csv', +'FAQ': 'ЧаПи (FAQ)', +'First name': "Ім'я", +'Forgot username?': "Забули ім'я користувача?", +'Forms and Validators': 'Форми та коректність даних', +'Free Applications': 'Вільні додатки', +'Graph Model': 'Графова Модель', +'Group %(group_id)s created': 'Групу %(group_id)s створено', +'Group ID': 'Ідентифікатор групи', +'Group uniquely assigned to user %(id)s': "Група унікально зв'язана з користувачем %(id)s", +'Groups': 'Групи', +'Hello World': 'Привіт, світ!', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Початок', +'How did you get here?': 'Як цього було досягнуто?', +'import': 'Імпортувати', +'Import/Export': 'Імпорт/Експорт', +'insert new': 'Створити новий запис', +'insert new %s': 'створити новий запис %s', +'Internal State': 'Внутрішній стан', +'Introduction': 'Введення', +'Invalid email': 'Невірна адреса ел.пошти', +'Invalid login': "Невірне ім'я користувача", +'Invalid password': 'Невірний пароль', +'Invalid Query': 'Помилковий запит', +'invalid request': 'хибний запит', +'Is Active': 'Активна', +'Key': 'Ключ', +'Last name': 'Прізвище', +'Layout': 'Макет (Layout)', +'Layout Plugins': 'Втулки макетів', +'Layouts': 'Макети', +'Live Chat': 'Чат', +'Log In': 'Log In', +'Logged in': 'Вхід здійснено', +'Logged out': 'Вихід здійснено', +'Login': 'Вхід', +'Logout': 'Вихід', +'Lost Password': 'Забули пароль', +'Lost password?': 'Забули пароль?', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Управління кешем', +'Memberships': 'Memberships', +'Menu Model': 'Модель меню', +'Modified By': 'Зміни провадив(ла)', +'Modified On': 'Змінено в', +'My Sites': 'Сайт (усі додатки)', +'Name': "Ім'я", +'New password': 'Новий пароль', +'New Record': 'Новий запис', +'new record inserted': 'новий рядок додано', +'next %s rows': 'next %s rows', +'next 100 rows': 'наступні 100 рядків', +'No databases in this application': 'Даний додаток не використовує базу даних', +'now': 'зараз', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Object or table name': "Об'єкт або назва таблиці", +'Old password': 'Старий пароль', +'Online book': 'Online book', +'Online examples': 'Зразковий демо-сайт', +'or import from csv file': 'або імпортувати з csv-файлу', +'Origin': 'Походження', +'Other Plugins': 'Інші втулки', +'Other Recipes': 'Інші рецепти', +'Overview': 'Огляд', +'Page Not Found!': 'Сторінку не знайдено!', +'Page saved': 'Сторінку збережено', +'Password': 'Пароль', +'Password changed': 'Пароль змінено', +"Password fields don't match": 'Пароль не співпав', +'Permission': 'Permission', +'Permissions': 'Permissions', +'please input your password again': 'Будь-ласка введіть пароль ще раз', +'Plugins': 'Втулки (Plugins)', +'Powered by': 'Працює на', +'Preface': 'Передмова', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'попередні 100 рядків', +'Profile': 'Параметри', +'Profile updated': 'Параметри змінено', +'pygraphviz library not found': 'Бібліотека pygraphviz не знайдена (не встановлена)', +'Python': 'Мова Python', +'Query:': 'Запит:', +'Quick Examples': 'Швидкі приклади', +'RAM': "ОПЕРАТИВНА ПАМ'ЯТЬ (ОЗП)", +'RAM Cache Keys': 'Ключі ОЗП-кешу', +'Ram Cleared': 'ОЗП-кеш очищено', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Рецепти', +'Record': 'запис', +'Record %(id)s updated': 'Запис %(id)s змінено', +'record does not exist': 'запису не існує', +'Record ID': 'Ід.запису', +'Record id': 'ід. запису', +'Record Updated': 'Запис змінено', +'Register': 'Реєстрація', +'Registration identifier': 'Реєстраційний ідентифікатор', +'Registration key': 'Реєстраційний ключ', +'Registration successful': 'Реєстрація пройшла успішно', +'Remember me (for 30 days)': "Запам'ятати мене (на 30 днів)", +'Request reset password': 'Запит на зміну пароля', +'Reset Password key': 'Ключ скидання пароля', +'Role': 'Роль', +'Roles': 'Roles', +'Rows in Table': 'Рядки в таблиці', +'Rows selected': 'Відмічено рядків', +'Save model as...': 'Save model as...', +'Save profile': 'Зберегти параметри', +'Semantic': 'Семантика', +'Services': 'Сервіс', +'Sign Up': 'Sign Up', +'Size of cache:': 'Розмір кешу:', +'state': 'стан', +'Statistics': 'Статистика', +'Stylesheet': 'CSS-стилі', +'submit': 'застосувати', +'Submit': 'Застосувати', +'Support': 'Підтримка', +'Table': 'Таблиця', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"Запит" це умова, на зразок "db.table1.field1==\'значення\'". Вираз "db.table1.field1==db.table2.field2" повертає результат об\'єднання (SQL JOIN) таблиць.', +'The Core': 'Ядро', +'The output of the file is a dictionary that was rendered by the view %s': 'Результат функції - словник пар (назва=значення) було відображено з допомогою відображення (view) %s', +'The Views': 'Відображення (Views)', +'This App': 'Цей додаток', +'This email already has an account': 'Вказана адреса ел.пошти вже зареєстрована', +'Time in Cache (h:m:s)': 'Час знаходження в кеші (h:m:s)', +'Timestamp': 'Відмітка часу', +'too short': 'Занадто короткий', +'Traceback': 'Traceback', +'Twitter': 'Твіттер', +'unable to parse csv file': 'не вдається розібрати csv-файл', +'Update:': 'Оновити:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Для створення складних запитів використовуйте (...)&(...) замість AND, (...)|(...) замість OR, та ~(...) замість NOT.', +'User': 'User', +'User %(id)s Logged-in': 'Користувач %(id)s увійшов', +'User %(id)s Logged-out': 'Користувач %(id)s вийшов', +'User %(id)s Password changed': 'Користувач %(id)s змінив свій пароль', +'User %(id)s Password reset': 'Користувач %(id)s скинув пароль', +'User %(id)s Profile updated': 'Параметри користувача %(id)s змінено', +'User %(id)s Registered': 'Користувач %(id)s зареєструвався', +'User ID': 'Ід.користувача', +'Users': 'Users', +'value already in database or empty': 'значення вже в базі даних або порожнє', +'Verify Password': 'Повторити пароль', +'Videos': 'Відео', +'View': 'Відображення (View)', +'Welcome': 'Ласкаво просимо', +'Welcome to web2py!': 'Ласкаво просимо до web2py!', +'Which called the function %s located in the file %s': 'Управління передалось функції %s, яка розташована у файлі %s', +'Working...': 'Працюємо...', +'You are successfully running web2py': 'Ви успішно запустили web2py', +'You can modify this application and adapt it to your needs': 'Ви можете модифікувати цей додаток і адаптувати його до своїх потреб', +'You visited the url %s': 'Ви відвідали наступну адресу: %s', +} diff --git a/web2py/applications/SP/languages/zh-cn.py b/web2py/applications/SP/languages/zh-cn.py new file mode 100644 index 0000000..76330d6 --- /dev/null +++ b/web2py/applications/SP/languages/zh-cn.py @@ -0,0 +1,341 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'zh-cn', +'!langname!': '中文', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" 应为选择表达式, 格式如 "field1=\'value\'". 但是对 JOIN 的结果不可以使用 update 或者 delete"', +'%s %%{row} deleted': '已删除 %s 笔', +'%s %%{row} updated': '已更新 %s 笔', +'%s selected': '%s 已选择', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'(something like "it-it")': '(格式类似 "zh-tw")', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'@markmin\x01Number of entries: **%s**': 'Number of entries: **%s**', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'A new version of web2py is available': '新版 web2py 已推出', +'A new version of web2py is available: %s': '新版 web2py 已推出: %s', +'about': '关于', +'About': '关于', +'About application': '关于本应用程序', +'Access Control': 'Access Control', +'admin': 'admin', +'Admin is disabled because insecure channel': '管理功能(Admin)在非安全连接环境下自动关闭', +'Admin is disabled because unsecure channel': '管理功能(Admin)在非安全连接环境下自动关闭', +'Administrative Interface': 'Administrative Interface', +'Administrative interface': '点击进入管理界面', +'Administrator Password:': '管理员密码:', +'Ajax Recipes': 'Ajax Recipes', +'An error occured, please %s the page': 'An error occured, please %s the page', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'API Example': 'API Example', +'appadmin is disabled because insecure channel': '管理界面在非安全通道下被禁用', +'Apply changes': 'Apply changes', +'Are you sure you want to delete file "%s"?': '确定要删除文件"%s"?', +'Are you sure you want to delete this object?': '确定要删除该对象么?', +'Are you sure you want to uninstall application "%s"': '确定要删除应用程序 "%s"', +'Are you sure you want to uninstall application "%s"?': '确定要删除应用程序 "%s"', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': '注意: 登录管理账号需要安全连接(HTTPS)或是在本地连接(localhost).', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': '注意: 因为在测试模式不保证多线程安全性,所以不可同时执行多个测试案例', +'ATTENTION: you cannot edit the running application!': '注意:不可编辑正在执行的应用程序!', +'Authentication': '验证', +'Available Databases and Tables': '可提供的数据库和数据表', +'Buy this book': '购买本书', +"Buy web2py's book": "Buy web2py's book", +'cache': '高速缓存', +'Cache': 'Cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'Cannot be empty': '不可空白', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': '编译失败:应用程序有错误,请排除错误后再尝试编译.', +'Change Password': '修改密码', +'change password': '修改密码', +'Check to delete': '打勾以示删除', +'Check to delete:': '打勾以示删除:', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Client IP': '客户端网址(IP)', +'Community': 'Community', +'Components and Plugins': 'Components and Plugins', +'Config.ini': 'Config.ini', +'Confirm Password': '确认密码', +'Controller': '控件', +'Controllers': '控件', +'Copyright': '版权所有', +'Create new application': '创建应用程序', +'Created By': 'Created By', +'Created On': 'Created On', +'Current request': '当前网络要求(request)', +'Current response': '当前网络响应(response)', +'Current session': '当前网络连接信息(session)', +'customize me!': '请调整我!', +'data uploaded': '数据已上传', +'Database': '数据库', +'Database %s select': '已选择 %s 数据库', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': '日期和时间', +'db': 'db', +'DB Model': '数据库模型', +'Delete': '删除', +'Delete:': '删除:', +'Demo': 'Demo', +'Deploy on Google App Engine': '发布到 Google App Engine', +'Deployment Recipes': 'Deployment Recipes', +'Description': '描述', +'DESIGN': '设计', +'Design': 'Design', +'design': '设计', +'Design for': '设计用于', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentation', +"Don't know what to do?": "Don't know what to do?", +'done!': '完成!', +'Download': '下载', +'E-mail': '电子邮件', +'EDIT': '编辑', +'Edit': '编辑', +'Edit application': '编辑应用程序', +'Edit current record': '编辑当前记录', +'edit profile': '编辑配置文件', +'Edit Profile': '编辑配置文件', +'Edit This App': '编辑本应用程序', +'Editing file': '编辑文件', +'Editing file "%s"': '编辑文件"%s"', +'Email': '电子邮件地址', +'Email and SMS': 'Email and SMS', +'Enter a number between %(min)g and %(max)g': 'Enter a number between %(min)g and %(max)g', +'enter an integer between %(min)g and %(max)g': 'enter an integer between %(min)g and %(max)g', +'Enter an integer between %(min)g and %(max)g': 'Enter an integer between %(min)g and %(max)g', +'Error logs for "%(app)s"': '"%(app)s"的错误记录', +'Errors': 'Errors', +'Errors in form, please check it out.': 'Errors in form, please check it out.', +'export as csv file': '以CSV格式导出', +'FAQ': 'FAQ', +'First name': '名', +'Forgot username?': '忘记用户名?', +'Forms and Validators': 'Forms and Validators', +'Free Applications': 'Free Applications', +'Functions with no doctests will result in [passed] tests.': '沒有 doctests 的函数会显示 [passed].', +'Graph Model': 'Graph Model', +'Grid Example': 'Grid Example', +'Group ID': '群组编号', +'Group uniquely assigned to user %(id)s': 'Group uniquely assigned to user %(id)s', +'Groups': 'Groups', +'Hello World': 'Hello World', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Home', +'How did you get here?': 'How did you get here?', +'import': 'import', +'Import/Export': '导入/导出', +'Index': '索引', +'insert new': '插入新纪录', +'insert new %s': '插入新纪录 %s', +'Installed applications': '已安裝应用程序', +'Internal State': '內部状态', +'Introduction': 'Introduction', +'Invalid action': '非法操作(action)', +'Invalid email': '不符合电子邮件格式', +'Invalid login': 'Invalid login', +'Invalid Query': '无效的查询请求', +'invalid request': '网络要求无效', +'Is Active': 'Is Active', +'Key': 'Key', +'Language files (static strings) updated': '语言文件已更新', +'Languages': '各国语言', +'Last name': '姓', +'Last saved on:': '最后保存时间:', +'Layout': '网页布局', +'Layout Plugins': 'Layout Plugins', +'Layouts': 'Layouts', +'License for': '软件授权', +'Live Chat': 'Live Chat', +'Log In': '认证', +'Logged in': 'Logged in', +'Logged out': 'Logged out', +'login': '登录', +'Login': '登录', +'Login to the Administrative Interface': '登录到管理员界面', +'logout': '登出', +'Logout': '登出', +'Lost Password': '忘记密码', +'Lost password?': '忘记密码?', +'Lost your password?': 'Lost your password?', +'Main Menu': '主菜单', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Manage Cache', +'Memberships': 'Memberships', +'Menu Model': '菜单模型(menu)', +'Minimum length is %s': '最小密码长度必须为 %s', +'Models': '数据模型', +'Modified By': '修改者', +'Modified On': '修改时间', +'Modules': '程序模块', +'Must include at least %s %s': 'Must include at least %s %s', +'Must include at least %s lowercase': 'Must include at least %s lowercase', +'Must include at least %s of the following: %s': 'Must include at least %s of the following: %s', +'Must include at least %s uppercase': 'Must include at least %s uppercase', +'My Sites': 'My Sites', +'Name': '名字', +'New Record': '新记录', +'new record inserted': '已插入新记录', +'next %s rows': 'next %s rows', +'next 100 rows': '往后 100 笔', +'NO': '否', +'No databases in this application': '该应用程序不含数据库', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Object or table name': 'Object or table name', +'Online book': 'Online book', +'Online examples': '点击进入在线例子', +'or import from csv file': '或导入CSV文件', +'Origin': '原文', +'Original/Translation': '原文/翻译', +'Other Plugins': 'Other Plugins', +'Other Recipes': 'Other Recipes', +'Overview': '概览', +'Password': '密码', +"Password fields don't match": '密码不匹配', +'Peeking at file': '选择文件', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Plugins': 'Plugins', +'Powered by': '基于下列技术构建:', +'Preface': 'Preface', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '往前 100 笔', +'Profile': 'Profile', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query:': '查询:', +'Quick Examples': 'Quick Examples', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Recipes', +'Record': '记录', +'record does not exist': '记录不存在', +'Record ID': '记录编号', +'Record id': '记录编号', +'Register': '注册', +'register': '注册', +'Registration identifier': 'Registration identifier', +'Registration is pending approval': 'Registration is pending approval', +'Registration key': '注册密钥', +'reload': 'reload', +'Remember me (for 30 days)': '记住我(30 天)', +'Request reset password': 'Request reset password', +'Reset Password key': '重置密码', +'Resolve Conflict file': '解决冲突文件', +'Retrieve Password': 'Retrieve Password', +'Role': '角色', +'Roles': 'Roles', +'Rows in Table': '在数据表里的记录', +'Rows selected': '笔记录被选择', +'Save model as...': 'Save model as...', +'Saved file hash:': '已保存文件的哈希值:', +'Semantic': 'Semantic', +'Services': 'Services', +'Sign Up': '注册认证', +'Sign up': 'Sign up', +'Size of cache:': 'Size of cache:', +'state': '状态', +'Static files': '静态文件', +'Statistics': '统计数据', +'Stylesheet': '网页样式表', +'submit': '提交', +'Submit': '提交', +'Success!': 'Success!', +'Support': 'Support', +'Sure you want to delete this object?': '确定要删除此对象?', +'Table': '数据表', +'Table name': '数据表名称', +'Testing application': '测试中的应用程序', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"query"应是类似 "db.table1.field1==\'value\'" 的条件表达式. "db.table1.field1==db.table2.field2"的形式则代表执行 JOIN SQL.', +'The Core': 'The Core', +'The output of the file is a dictionary that was rendered by the view %s': 'The output of the file is a dictionary that was rendered by the view %s', +'The Views': '视图', +'There are no controllers': '沒有控件(controllers)', +'There are no models': '沒有数据库模型(models)', +'There are no modules': '沒有程序模块(modules)', +'There are no static files': '沒有静态文件', +'There are no translators, only default language is supported': '沒有对应的语言文件,仅支持原始语言', +'There are no views': '沒有视图', +'This App': '该应用', +'This is the %(filename)s template': '这是%(filename)s文件的模板(template)', +'Ticket': '问题清单', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': '时间戳', +'Traceback': 'Traceback', +'Twitter': 'Twitter', +'Unable to check for upgrades': '查询新版本失败', +'Unable to download': '无法下载', +'Unable to download app': '无法下载应用程序', +'unable to parse csv file': '无法解析CSV文件', +'Update:': '更新:', +'Upload existing application': '上传已有应用程序', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': '使用下列方式可得到更复杂的条件表达式, (...)&(...) 代表必须都满足, (...)|(...) 代表其一, ~(...)则代表否.', +'User': 'User', +'User %(id)s Logged-in': '用户 %(id)s 已登录', +'User %(id)s Registered': '用户 %(id)s 已注册', +'User ID': '用户编号', +'Username': '认证名', +'Users': 'Users', +'Value already in database or empty': '用户名不能为空或者已经被使用', +'Verify Password': '验证密码', +'Videos': '视频', +'View': '查看', +'Views': '视图', +'Welcome': '欢迎', +'Welcome %s': '欢迎 %s', +'Welcome to web2py': '欢迎使用 web2py', +'Welcome to web2py!': '欢迎使用 web2py!', +'Which called the function %s located in the file %s': 'Which called the function %s located in the file %s', +'Wiki Example': 'Wiki Example', +'Working...': 'Working...', +'YES': '是', +'You are successfully running web2py': '您已成功运行 web2py', +'You can modify this application and adapt it to your needs': '请根据您的需要修改本程序', +'You visited the url %s': 'You visited the url %s', +'个人': '个人', +'个人界面': '个人界面', +'任务': '任务', +'任务界面': '任务界面', +'保持登录状态': '保持登录状态', +'修改': '修改', +'删除': '删除', +'后台': '后台', +'后台管理': '后台管理', +'后台管理界面': '后台管理界面', +'忘记认证密钥': '忘记认证密钥', +'找回密钥': '找回密钥', +'找回认证密钥': '找回认证密钥', +'提交': '提交', +'提交界面': '提交界面', +'数据库': '数据库', +'数据库管理 (appadmin)': '数据库管理 (appadmin)', +'更改认证密钥': '更改认证密钥', +'本计划旨在促进班级同学的学习积极性。': '本计划旨在促进班级同学的学习积极性。', +'注册认证': '注册认证', +'添加': '添加', +'激活认证': '激活认证', +'班级': '班级', +'班级界面': '班级界面', +'登录认证': '登录认证', +'相关数据库信息': '相关数据库信息', +'西北工业大学软件与微电子学院软件工程9班学习考勤情况统计计划': '西北工业大学软件与微电子学院软件工程9班学习考勤情况统计计划', +'西北工业大学软件与微电子学院软件工程9班学习考勤统计计划': '西北工业大学软件与微电子学院软件工程9班学习考勤统计计划', +'认证': '认证', +'退出认证': '退出认证', +'首页': '首页', +} diff --git a/web2py/applications/SP/languages/zh-tw.py b/web2py/applications/SP/languages/zh-tw.py new file mode 100644 index 0000000..2b64c75 --- /dev/null +++ b/web2py/applications/SP/languages/zh-tw.py @@ -0,0 +1,281 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'zh-cn', +'!langname!': '中文', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"更新" 是選擇性的條件式, 格式就像 "欄位1=\'值\'". 但是 JOIN 的資料不可以使用 update 或是 delete"', +'%s %%{row} deleted': '已刪除 %s 筆', +'%s %%{row} updated': '已更新 %s 筆', +'%s selected': '%s 已選擇', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'(something like "it-it")': '(格式類似 "zh-tw")', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'A new version of web2py is available': '新版的 web2py 已發行', +'A new version of web2py is available: %s': '新版的 web2py 已發行: %s', +'about': '關於', +'About': '關於', +'About application': '關於本應用程式', +'Access Control': 'Access Control', +'admin': 'admin', +'Admin is disabled because insecure channel': '管理功能(Admin)在不安全連線環境下自動關閉', +'Admin is disabled because unsecure channel': '管理功能(Admin)在不安全連線環境下自動關閉', +'Administrative Interface': 'Administrative Interface', +'Administrative interface': '點此處進入管理介面', +'Administrator Password:': '管理員密碼:', +'Ajax Recipes': 'Ajax Recipes', +'An error occured, please %s the page': 'An error occured, please %s the page', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'appadmin is disabled because insecure channel': '因為來自非安全通道,管理介面關閉', +'Are you sure you want to delete file "%s"?': '確定要刪除檔案"%s"?', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Are you sure you want to uninstall application "%s"': '確定要移除應用程式 "%s"', +'Are you sure you want to uninstall application "%s"?': '確定要移除應用程式 "%s"', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': '注意: 登入管理帳號需要安全連線(HTTPS)或是在本機連線(localhost).', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': '注意: 因為在測試模式不保證多執行緒安全性,也就是說不可以同時執行多個測試案例', +'ATTENTION: you cannot edit the running application!': '注意:不可編輯正在執行的應用程式!', +'Authentication': '驗證', +'Available Databases and Tables': '可提供的資料庫和資料表', +'Buy this book': 'Buy this book', +"Buy web2py's book": "Buy web2py's book", +'cache': '快取記憶體', +'Cache': 'Cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'Cannot be empty': '不可空白', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': '無法編譯:應用程式中含有錯誤,請除錯後再試一次.', +'Change Password': '變更密碼', +'change password': '變更密碼', +'Check to delete': '打勾代表刪除', +'Check to delete:': '點選以示刪除:', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Client IP': '客戶端網址(IP)', +'Community': 'Community', +'Components and Plugins': 'Components and Plugins', +'Config.ini': 'Config.ini', +'Controller': '控件', +'Controllers': '控件', +'Copyright': '版權所有', +'Create new application': '創建應用程式', +'Created By': 'Created By', +'Created On': 'Created On', +'Current request': '目前網路資料要求(request)', +'Current response': '目前網路資料回應(response)', +'Current session': '目前網路連線資訊(session)', +'customize me!': '請調整我!', +'data uploaded': '資料已上傳', +'Database': '資料庫', +'Database %s select': '已選擇 %s 資料庫', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': '日期和時間', +'db': 'db', +'DB Model': '資料庫模組', +'Delete': '刪除', +'Delete:': '刪除:', +'Demo': 'Demo', +'Deploy on Google App Engine': '配置到 Google App Engine', +'Deployment Recipes': 'Deployment Recipes', +'Description': '描述', +'DESIGN': '設計', +'Design': 'Design', +'design': '設計', +'Design for': '設計為了', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentation', +"Don't know what to do?": "Don't know what to do?", +'done!': '完成!', +'Download': 'Download', +'E-mail': '電子郵件', +'EDIT': '編輯', +'Edit': '編輯', +'Edit application': '編輯應用程式', +'Edit current record': '編輯當前紀錄', +'edit profile': '編輯設定檔', +'Edit Profile': '編輯設定檔', +'Edit This App': '編輯本應用程式', +'Editing file': '編輯檔案', +'Editing file "%s"': '編輯檔案"%s"', +'Email and SMS': 'Email and SMS', +'enter an integer between %(min)g and %(max)g': 'enter an integer between %(min)g and %(max)g', +'Error logs for "%(app)s"': '"%(app)s"的錯誤紀錄', +'Errors': 'Errors', +'export as csv file': '以逗號分隔檔(csv)格式匯出', +'FAQ': 'FAQ', +'First name': '名', +'Forgot username?': 'Forgot username?', +'Forms and Validators': 'Forms and Validators', +'Free Applications': 'Free Applications', +'Functions with no doctests will result in [passed] tests.': '沒有 doctests 的函式會顯示 [passed].', +'Graph Model': 'Graph Model', +'Group ID': '群組編號', +'Groups': 'Groups', +'Hello World': '嗨! 世界', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Home', +'How did you get here?': 'How did you get here?', +'import': 'import', +'Import/Export': '匯入/匯出', +'Index': '索引', +'insert new': '插入新資料', +'insert new %s': '插入新資料 %s', +'Installed applications': '已安裝應用程式', +'Internal State': '內部狀態', +'Introduction': 'Introduction', +'Invalid action': '不合法的動作(action)', +'Invalid email': '不合法的電子郵件', +'Invalid Query': '不合法的查詢', +'invalid request': '不合法的網路要求(request)', +'Is Active': 'Is Active', +'Key': 'Key', +'Language files (static strings) updated': '語言檔已更新', +'Languages': '各國語言', +'Last name': '姓', +'Last saved on:': '最後儲存時間:', +'Layout': '網頁配置', +'Layout Plugins': 'Layout Plugins', +'Layouts': 'Layouts', +'License for': '軟體版權為', +'Live Chat': 'Live Chat', +'Log In': 'Log In', +'login': '登入', +'Login': '登入', +'Login to the Administrative Interface': '登入到管理員介面', +'logout': '登出', +'Logout': '登出', +'Lost Password': '密碼遺忘', +'Lost password?': 'Lost password?', +'Main Menu': '主選單', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Manage Cache', +'Memberships': 'Memberships', +'Menu Model': '選單模組(menu)', +'Models': '資料模組', +'Modified By': 'Modified By', +'Modified On': 'Modified On', +'Modules': '程式模組', +'My Sites': 'My Sites', +'Name': '名字', +'New Record': '新紀錄', +'new record inserted': '已插入新紀錄', +'next %s rows': 'next %s rows', +'next 100 rows': '往後 100 筆', +'NO': '否', +'No databases in this application': '這應用程式不含資料庫', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Object or table name': 'Object or table name', +'Online book': 'Online book', +'Online examples': '點此處進入線上範例', +'or import from csv file': '或是從逗號分隔檔(CSV)匯入', +'Origin': '原文', +'Original/Translation': '原文/翻譯', +'Other Plugins': 'Other Plugins', +'Other Recipes': 'Other Recipes', +'Overview': 'Overview', +'Password': '密碼', +"Password fields don't match": '密碼欄不匹配', +'Peeking at file': '選擇檔案', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Plugins': 'Plugins', +'Powered by': '基於以下技術構建:', +'Preface': 'Preface', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '往前 100 筆', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query:': '查詢:', +'Quick Examples': 'Quick Examples', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Recipes', +'Record': '紀錄', +'record does not exist': '紀錄不存在', +'Record ID': '紀錄編號', +'Record id': '紀錄編號', +'Register': '註冊', +'register': '註冊', +'Registration identifier': 'Registration identifier', +'Registration key': '註冊金鑰', +'reload': 'reload', +'Remember me (for 30 days)': '記住我(30 天)', +'Reset Password key': '重設密碼', +'Resolve Conflict file': '解決衝突檔案', +'Role': '角色', +'Roles': 'Roles', +'Rows in Table': '在資料表裏的資料', +'Rows selected': '筆資料被選擇', +'Save model as...': 'Save model as...', +'Saved file hash:': '檔案雜湊值已紀錄:', +'Semantic': 'Semantic', +'Services': 'Services', +'Sign Up': 'Sign Up', +'Size of cache:': 'Size of cache:', +'state': '狀態', +'Static files': '靜態檔案', +'Statistics': 'Statistics', +'Stylesheet': '網頁風格檔', +'submit': 'submit', +'Submit': '傳送', +'Support': 'Support', +'Sure you want to delete this object?': '確定要刪除此物件?', +'Table': '資料表', +'Table name': '資料表名稱', +'Testing application': '測試中的應用程式', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"查詢"是一個像 "db.表1.欄位1==\'值\'" 的條件式. 以"db.表1.欄位1==db.表2.欄位2"方式則相當於執行 JOIN SQL.', +'The Core': 'The Core', +'The output of the file is a dictionary that was rendered by the view %s': 'The output of the file is a dictionary that was rendered by the view %s', +'The Views': 'The Views', +'There are no controllers': '沒有控件(controllers)', +'There are no models': '沒有資料庫模組(models)', +'There are no modules': '沒有程式模組(modules)', +'There are no static files': '沒有靜態檔案', +'There are no translators, only default language is supported': '沒有翻譯檔,只支援原始語言', +'There are no views': '沒有視圖', +'This App': 'This App', +'This is the %(filename)s template': '這是%(filename)s檔案的樣板(template)', +'Ticket': '問題單', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': '時間標記', +'Traceback': 'Traceback', +'Twitter': 'Twitter', +'Unable to check for upgrades': '無法做升級檢查', +'Unable to download': '無法下載', +'Unable to download app': '無法下載應用程式', +'unable to parse csv file': '無法解析逗號分隔檔(csv)', +'Update:': '更新:', +'Upload existing application': '更新存在的應用程式', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': '使用下列方式來組合更複雜的條件式, (...)&(...) 代表同時存在的條件, (...)|(...) 代表擇一的條件, ~(...)則代表反向條件.', +'User': 'User', +'User %(id)s Logged-in': '使用者 %(id)s 已登入', +'User %(id)s Registered': '使用者 %(id)s 已註冊', +'User ID': '使用者編號', +'Users': 'Users', +'Verify Password': '驗證密碼', +'Videos': 'Videos', +'View': '視圖', +'Views': '視圖', +'Welcome': 'Welcome', +'Welcome %s': '歡迎 %s', +'Welcome to web2py': '歡迎使用 web2py', +'Welcome to web2py!': 'Welcome to web2py!', +'Which called the function %s located in the file %s': 'Which called the function %s located in the file %s', +'Working...': 'Working...', +'YES': '是', +'You are successfully running web2py': 'You are successfully running web2py', +'You can modify this application and adapt it to your needs': 'You can modify this application and adapt it to your needs', +'You visited the url %s': 'You visited the url %s', +} diff --git a/web2py/applications/SP/languages/zh.py b/web2py/applications/SP/languages/zh.py new file mode 100644 index 0000000..9794032 --- /dev/null +++ b/web2py/applications/SP/languages/zh.py @@ -0,0 +1,268 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'zh-tw', +'!langname!': '中文', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"更新" 是選擇性的條件式, 格式就像 "欄位1=\'值\'". 但是 JOIN 的資料不可以使用 update 或是 delete"', +'%s %%{row} deleted': '已刪除 %s 筆', +'%s %%{row} updated': '已更新 %s 筆', +'%s selected': '%s 已選擇', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'(something like "it-it")': '(格式類似 "zh-tw")', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'A new version of web2py is available': '新版的 web2py 已發行', +'A new version of web2py is available: %s': '新版的 web2py 已發行: %s', +'about': '關於', +'About': '關於', +'About application': '關於本應用程式', +'Access Control': 'Access Control', +'admin': 'admin', +'Admin is disabled because insecure channel': '管理功能(Admin)在不安全連線環境下自動關閉', +'Admin is disabled because unsecure channel': '管理功能(Admin)在不安全連線環境下自動關閉', +'Administrative Interface': 'Administrative Interface', +'Administrative interface': '點此處進入管理介面', +'Administrator Password:': '管理員密碼:', +'Ajax Recipes': 'Ajax Recipes', +'An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'appadmin is disabled because insecure channel': '因為來自非安全通道,管理介面關閉', +'Are you sure you want to delete file "%s"?': '確定要刪除檔案"%s"?', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Are you sure you want to uninstall application "%s"': '確定要移除應用程式 "%s"', +'Are you sure you want to uninstall application "%s"?': '確定要移除應用程式 "%s"', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': '注意: 登入管理帳號需要安全連線(HTTPS)或是在本機連線(localhost).', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': '注意: 因為在測試模式不保證多執行緒安全性,也就是說不可以同時執行多個測試案例', +'ATTENTION: you cannot edit the running application!': '注意:不可編輯正在執行的應用程式!', +'Authentication': '驗證', +'Available Databases and Tables': '可提供的資料庫和資料表', +'Buy this book': 'Buy this book', +"Buy web2py's book": "Buy web2py's book", +'cache': '快取記憶體', +'Cache': 'Cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'Cannot be empty': '不可空白', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': '無法編譯:應用程式中含有錯誤,請除錯後再試一次.', +'Change Password': '變更密碼', +'change password': '變更密碼', +'Check to delete': '打勾代表刪除', +'Check to delete:': '點選以示刪除:', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Client IP': '客戶端網址(IP)', +'Community': 'Community', +'Components and Plugins': 'Components and Plugins', +'Config.ini': 'Config.ini', +'Controller': '控件', +'Controllers': '控件', +'Copyright': '版權所有', +'Create new application': '創建應用程式', +'Current request': '目前網路資料要求(request)', +'Current response': '目前網路資料回應(response)', +'Current session': '目前網路連線資訊(session)', +'customize me!': '請調整我!', +'data uploaded': '資料已上傳', +'Database': '資料庫', +'Database %s select': '已選擇 %s 資料庫', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': '日期和時間', +'db': 'db', +'DB Model': '資料庫模組', +'Delete': '刪除', +'Delete:': '刪除:', +'Demo': 'Demo', +'Deploy on Google App Engine': '配置到 Google App Engine', +'Deployment Recipes': 'Deployment Recipes', +'Description': '描述', +'DESIGN': '設計', +'Design': 'Design', +'design': '設計', +'Design for': '設計為了', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Documentation': 'Documentation', +"Don't know what to do?": "Don't know what to do?", +'done!': '完成!', +'Download': 'Download', +'E-mail': '電子郵件', +'EDIT': '編輯', +'Edit': '編輯', +'Edit application': '編輯應用程式', +'Edit current record': '編輯當前紀錄', +'edit profile': '編輯設定檔', +'Edit Profile': '編輯設定檔', +'Edit This App': '編輯本應用程式', +'Editing file': '編輯檔案', +'Editing file "%s"': '編輯檔案"%s"', +'Email and SMS': 'Email and SMS', +'Error logs for "%(app)s"': '"%(app)s"的錯誤紀錄', +'Errors': 'Errors', +'export as csv file': '以逗號分隔檔(csv)格式匯出', +'FAQ': 'FAQ', +'First name': '名', +'Forms and Validators': 'Forms and Validators', +'Free Applications': 'Free Applications', +'Functions with no doctests will result in [passed] tests.': '沒有 doctests 的函式會顯示 [passed].', +'Graph Model': 'Graph Model', +'Group ID': '群組編號', +'Groups': 'Groups', +'Hello World': '嗨! 世界', +'Helping web2py': 'Helping web2py', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Home': 'Home', +'How did you get here?': 'How did you get here?', +'import': 'import', +'Import/Export': '匯入/匯出', +'Index': '索引', +'insert new': '插入新資料', +'insert new %s': '插入新資料 %s', +'Installed applications': '已安裝應用程式', +'Internal State': '內部狀態', +'Introduction': 'Introduction', +'Invalid action': '不合法的動作(action)', +'Invalid email': '不合法的電子郵件', +'Invalid Query': '不合法的查詢', +'invalid request': '不合法的網路要求(request)', +'Key': 'Key', +'Language files (static strings) updated': '語言檔已更新', +'Languages': '各國語言', +'Last name': '姓', +'Last saved on:': '最後儲存時間:', +'Layout': '網頁配置', +'Layout Plugins': 'Layout Plugins', +'Layouts': 'Layouts', +'License for': '軟體版權為', +'Live Chat': 'Live Chat', +'Log In': 'Log In', +'login': '登入', +'Login': '登入', +'Login to the Administrative Interface': '登入到管理員介面', +'logout': '登出', +'Logout': '登出', +'Lost Password': '密碼遺忘', +'Main Menu': '主選單', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Cache': 'Manage Cache', +'Memberships': 'Memberships', +'Menu Model': '選單模組(menu)', +'Models': '資料模組', +'Modules': '程式模組', +'My Sites': 'My Sites', +'Name': '名字', +'New Record': '新紀錄', +'new record inserted': '已插入新紀錄', +'next %s rows': 'next %s rows', +'next 100 rows': '往後 100 筆', +'NO': '否', +'No databases in this application': '這應用程式不含資料庫', +'Number of entries: **%s**': 'Number of entries: **%s**', +'Online book': 'Online book', +'Online examples': '點此處進入線上範例', +'or import from csv file': '或是從逗號分隔檔(CSV)匯入', +'Origin': '原文', +'Original/Translation': '原文/翻譯', +'Other Plugins': 'Other Plugins', +'Other Recipes': 'Other Recipes', +'Overview': 'Overview', +'Password': '密碼', +"Password fields don't match": '密碼欄不匹配', +'Peeking at file': '選擇檔案', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Plugins': 'Plugins', +'Powered by': '基於以下技術構建:', +'Preface': 'Preface', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '往前 100 筆', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'Query:': '查詢:', +'Quick Examples': 'Quick Examples', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Recipes': 'Recipes', +'Record': '紀錄', +'record does not exist': '紀錄不存在', +'Record ID': '紀錄編號', +'Record id': '紀錄編號', +'Register': '註冊', +'register': '註冊', +'Registration key': '註冊金鑰', +'Remember me (for 30 days)': '記住我(30 天)', +'Reset Password key': '重設密碼', +'Resolve Conflict file': '解決衝突檔案', +'Role': '角色', +'Roles': 'Roles', +'Rows in Table': '在資料表裏的資料', +'Rows selected': '筆資料被選擇', +'Save model as...': 'Save model as...', +'Saved file hash:': '檔案雜湊值已紀錄:', +'Semantic': 'Semantic', +'Services': 'Services', +'Sign Up': 'Sign Up', +'Size of cache:': 'Size of cache:', +'state': '狀態', +'Static files': '靜態檔案', +'Statistics': 'Statistics', +'Stylesheet': '網頁風格檔', +'submit': 'submit', +'Submit': '傳送', +'Support': 'Support', +'Sure you want to delete this object?': '確定要刪除此物件?', +'Table': '資料表', +'Table name': '資料表名稱', +'Testing application': '測試中的應用程式', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"查詢"是一個像 "db.表1.欄位1==\'值\'" 的條件式. 以"db.表1.欄位1==db.表2.欄位2"方式則相當於執行 JOIN SQL.', +'The Core': 'The Core', +'The output of the file is a dictionary that was rendered by the view %s': 'The output of the file is a dictionary that was rendered by the view %s', +'The Views': 'The Views', +'There are no controllers': '沒有控件(controllers)', +'There are no models': '沒有資料庫模組(models)', +'There are no modules': '沒有程式模組(modules)', +'There are no static files': '沒有靜態檔案', +'There are no translators, only default language is supported': '沒有翻譯檔,只支援原始語言', +'There are no views': '沒有視圖', +'This App': 'This App', +'This is the %(filename)s template': '這是%(filename)s檔案的樣板(template)', +'Ticket': '問題單', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': '時間標記', +'Traceback': 'Traceback', +'Twitter': 'Twitter', +'Unable to check for upgrades': '無法做升級檢查', +'Unable to download': '無法下載', +'Unable to download app': '無法下載應用程式', +'unable to parse csv file': '無法解析逗號分隔檔(csv)', +'Update:': '更新:', +'Upload existing application': '更新存在的應用程式', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': '使用下列方式來組合更複雜的條件式, (...)&(...) 代表同時存在的條件, (...)|(...) 代表擇一的條件, ~(...)則代表反向條件.', +'User': 'User', +'User %(id)s Logged-in': '使用者 %(id)s 已登入', +'User %(id)s Registered': '使用者 %(id)s 已註冊', +'User ID': '使用者編號', +'Users': 'Users', +'Verify Password': '驗證密碼', +'Videos': 'Videos', +'View': '視圖', +'Views': '視圖', +'Welcome %s': '歡迎 %s', +'Welcome to web2py': '歡迎使用 web2py', +'Welcome to web2py!': 'Welcome to web2py!', +'Which called the function %s located in the file %s': 'Which called the function %s located in the file %s', +'Working...': 'Working...', +'YES': '是', +'You are successfully running web2py': 'You are successfully running web2py', +'You can modify this application and adapt it to your needs': 'You can modify this application and adapt it to your needs', +'You visited the url %s': 'You visited the url %s', +} diff --git a/web2py/applications/SP/models/db.py b/web2py/applications/SP/models/db.py new file mode 100644 index 0000000..285aa38 --- /dev/null +++ b/web2py/applications/SP/models/db.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- + +# ------------------------------------------------------------------------- +# AppConfig configuration made easy. Look inside private/appconfig.ini +# Auth is for authenticaiton and access control +# ------------------------------------------------------------------------- +from gluon.contrib.appconfig import AppConfig +from gluon.tools import Auth + +# ------------------------------------------------------------------------- +# This scaffolding model makes your app work on Google App Engine too +# File is released under public domain and you can use without limitations +# ------------------------------------------------------------------------- + +if request.global_settings.web2py_version < "2.15.5": + raise HTTP(500, "Requires web2py 2.15.5 or newer") + +# ------------------------------------------------------------------------- +# if SSL/HTTPS is properly configured and you want all HTTP requests to +# be redirected to HTTPS, uncomment the line below: +# ------------------------------------------------------------------------- +# request.requires_https() + +# ------------------------------------------------------------------------- +# once in production, remove reload=True to gain full speed +# ------------------------------------------------------------------------- +configuration = AppConfig(reload=True) + +if not request.env.web2py_runtime_gae: + # --------------------------------------------------------------------- + # if NOT running on Google App Engine use SQLite or other DB + # --------------------------------------------------------------------- + db = DAL(configuration.get('db.uri'), + pool_size=configuration.get('db.pool_size'), + migrate_enabled=configuration.get('db.migrate'), + check_reserved=['all']) +else: + # --------------------------------------------------------------------- + # connect to Google BigTable (optional 'google:datastore://namespace') + # --------------------------------------------------------------------- + db = DAL('google:datastore+ndb') + # --------------------------------------------------------------------- + # store sessions and tickets there + # --------------------------------------------------------------------- + session.connect(request, response, db=db) + # --------------------------------------------------------------------- + # or store session in Memcache, Redis, etc. + # from gluon.contrib.memdb import MEMDB + # from google.appengine.api.memcache import Client + # session.connect(request, response, db = MEMDB(Client())) + # --------------------------------------------------------------------- + +# ------------------------------------------------------------------------- +# by default give a view/generic.extension to all actions from localhost +# none otherwise. a pattern can be 'controller/function.extension' +# ------------------------------------------------------------------------- +response.generic_patterns = [] +if request.is_local and not configuration.get('app.production'): + response.generic_patterns.append('*') + +# ------------------------------------------------------------------------- +# choose a style for forms +# ------------------------------------------------------------------------- +response.formstyle = 'bootstrap4_inline' +response.form_label_separator = '' + +# ------------------------------------------------------------------------- +# (optional) optimize handling of static files +# ------------------------------------------------------------------------- +# response.optimize_css = 'concat,minify,inline' +# response.optimize_js = 'concat,minify,inline' + +# ------------------------------------------------------------------------- +# (optional) static assets folder versioning +# ------------------------------------------------------------------------- +# response.static_version = '0.0.0' + +# ------------------------------------------------------------------------- +# Here is sample code if you need for +# - email capabilities +# - authentication (registration, login, logout, ... ) +# - authorization (role based authorization) +# - services (xml, csv, json, xmlrpc, jsonrpc, amf, rss) +# - old style crud actions +# (more options discussed in gluon/tools.py) +# ------------------------------------------------------------------------- + +# host names must be a list of allowed host names (glob syntax allowed) +auth = Auth(db, host_names=configuration.get('host.names')) + +db.define_table( + auth.settings.table_user_name, + Field('name','string',length=64,label="真实姓名"), + Field('username','string',length=16,unique=True,label="用户名"), + Field('password','password',length=512,label="密码"), + Field('email', length=128, default='',label="电子邮件地址"), + Field('registration_key', length=512, + writable=False, readable=False, default=''), + Field('reset_password_key', length=512, + writable=False, readable=False, default=''), + Field('registration_id', length=512, + writable=False, readable=False, default='')); + +custom_auth_table = db[auth.settings.table_user_name] +custom_auth_table.name.requires = IS_NOT_EMPTY(error_message=auth.messages.is_empty) +custom_auth_table.username.requires = [IS_NOT_IN_DB(db, custom_auth_table.username), + IS_NOT_EMPTY(error_message=auth.messages.is_empty)] +custom_auth_table.password.requires = [IS_STRONG(), CRYPT()] +custom_auth_table.email.requires = [ + IS_EMAIL(error_message=auth.messages.invalid_email), + IS_NOT_IN_DB(db, custom_auth_table.email)] +auth.settings.table_user = custom_auth_table + +# ------------------------------------------------------------------------- +# create all tables needed by auth, maybe add a list of extra fields +# ------------------------------------------------------------------------- +auth.settings.extra_fields['auth_user'] = [] +auth.define_tables(username=True, signature=False) + +# ------------------------------------------------------------------------- +# configure email +# ------------------------------------------------------------------------- +mail = auth.settings.mailer +mail.settings.server = 'logging' if request.is_local else configuration.get('smtp.server') +mail.settings.sender = configuration.get('smtp.sender') +mail.settings.login = configuration.get('smtp.login') +mail.settings.tls = configuration.get('smtp.tls') or False +mail.settings.ssl = configuration.get('smtp.ssl') or False + +# ------------------------------------------------------------------------- +# configure auth policy +# ------------------------------------------------------------------------- +auth.settings.registration_requires_verification = False +auth.settings.registration_requires_approval = False +auth.settings.reset_password_requires_verification = True +auth.settings.registration_requires_approval = False +auth.settings.password_min_length = 6 +auth.settings.logged_url = URL('myhome') +auth.settings.long_expiration = 3600*24*15 +auth.settings.remember_me_form = True +auth.messages.label_remember_me = "保持登录状态" + +# ------------------------------------------------------------------------- +# read more at http://dev.w3.org/html5/markup/meta.name.html +# ------------------------------------------------------------------------- +response.meta.author = configuration.get('app.author') +response.meta.description = configuration.get('app.description') +response.meta.keywords = configuration.get('app.keywords') +response.meta.generator = configuration.get('app.generator') +response.show_toolbar = configuration.get('app.toolbar') + +# ------------------------------------------------------------------------- +# your http://google.com/analytics id +# ------------------------------------------------------------------------- +response.google_analytics_id = configuration.get('google.analytics_id') + +# ------------------------------------------------------------------------- +# maybe use the scheduler +# ------------------------------------------------------------------------- +if configuration.get('scheduler.enabled'): + from gluon.scheduler import Scheduler + scheduler = Scheduler(db, heartbeat=configuration.get('scheduler.heartbeat')) + +# ------------------------------------------------------------------------- +# Define your tables below (or better in another model file) for example +# +# >>> db.define_table('mytable', Field('myfield', 'string')) +# +# Fields can be 'string','text','password','integer','double','boolean' +# 'date','time','datetime','blob','upload', 'reference TABLENAME' +# There is an implicit 'id integer autoincrement' field +# Consult manual for more options, validators, etc. +# +# More API examples for controllers: +# +# >>> db.mytable.insert(myfield='value') +# >>> rows = db(db.mytable.myfield == 'value').select(db.mytable.ALL) +# >>> for row in rows: print row.id, row.myfield +# ------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- +# after defining tables, uncomment below to enable auditing +# ------------------------------------------------------------------------- +# auth.enable_record_versioning(db) diff --git a/web2py/applications/SP/models/menu.py b/web2py/applications/SP/models/menu.py new file mode 100644 index 0000000..d5262cc --- /dev/null +++ b/web2py/applications/SP/models/menu.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# this file is released under public domain and you can use without limitations + +# ---------------------------------------------------------------------------------------------------------------------- +# this is the main application menu add/remove items as required +# ---------------------------------------------------------------------------------------------------------------------- + +response.menu = [ + (T('首页'), True, URL('default', 'index'), []) +] + +# ---------------------------------------------------------------------------------------------------------------------- +# provide shortcuts for development. you can remove everything below in production +# ---------------------------------------------------------------------------------------------------------------------- + +if not configuration.get('app.production'): + _app = request.application + response.menu += [ + (T('班级'), False, URL('default', 'myclass')), + (T('个人'), False, URL('default','myhome')), + (T('任务'), False, URL('default', 'task')), + (T('提交'), False, URL('private', 'home')), + ] + if auth.has_membership(group_id=2): + response.menu.append((T('后台'), False, URL('appadmin', 'index'))) + diff --git a/web2py/applications/SP/models/user.py b/web2py/applications/SP/models/user.py new file mode 100644 index 0000000..eaed5ac --- /dev/null +++ b/web2py/applications/SP/models/user.py @@ -0,0 +1,65 @@ +import datetime + +m_db = DAL("sqlite://storage.db") + +m_db.define_table('user_info', + Field('username','string',length=64), + Field('score','double',default=0), + Field('bean','double',default=0), + Field('workrate', 'double', default=100.00,readable=False,writable=False), + Field('room', 'string', default="Unknown"), + Field('showrank','boolean',default=False)); + +m_db.define_table('task', + Field('id','integer',writable=False,unique=True), + Field('name','string',default="没有名称"), + Field('create_date','datetime',default=datetime.datetime.now(),writable=False), + Field('end_date','datetime',default=datetime.datetime.now()), + Field('info', 'text', default="没有备注"), + Field('people','list:string',default=[],length=16), + Field('dopeople', 'list:string',default=[]), + Field('active', 'boolean', default=True), + Field('admindo', 'boolean', default=True), + Field('ifhistory', 'boolean', default=False)) + +m_db.define_table('history', + Field('id','integer',writeable=False,unique=True), + Field('type','string',default=""), + Field('t_id','integer',default=0), + Field('u_id','integer',default=0), + Field('bean','integer',default=0), + Field('time','datetime',default=datetime.datetime.now())) + +def get_user_info(auth): + if m_db(m_db.user_info.username == auth.user.username).count() == 0: + m_db.user_info.insert(username=auth.user.username); + user_info=m_db(m_db.user_info.username == auth.user.username).select().first() + return user_info; + +def get_user(username): + if m_db(m_db.user_info.username == username).count() == 0: + m_db.user_info.insert(username=auth.user.username); + user=db(db.auth_user.username == username).select().first() + return user; + +def get_user_auth(username): + user = db(db.auth_user.username == username).select().first() + return user; + +def get_user_info_by(username): + if m_db(m_db.user_info.username == username).count() == 0: + m_db.user_info.insert(username=username); + user_info=m_db(m_db.user_info.username == username).select().first() + return user_info; + +def get_users_in_group(group_tag): + usr_lst = [] + f_gp = db(db.auth_group.role == group_tag).select().first() + if f_gp is None: + return usr_lst + else: + f_usr_id = db(db.auth_membership.group_id == f_gp.id).select() + for i_usr_id in f_usr_id: + f_isr = db(db.auth_user.id == i_usr_id.user_id).select().first(); + usr_lst.append(f_isr.name) + return usr_lst \ No newline at end of file diff --git a/web2py/applications/SP/modules/__init__.py b/web2py/applications/SP/modules/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/web2py/applications/SP/modules/__init__.py @@ -0,0 +1 @@ + diff --git a/web2py/applications/SP/private/appconfig.ini b/web2py/applications/SP/private/appconfig.ini new file mode 100644 index 0000000..e367e96 --- /dev/null +++ b/web2py/applications/SP/private/appconfig.ini @@ -0,0 +1,34 @@ +; App configuration +[app] +name = Welcome +author = Your Name <you@example.com> +description = a cool new app +keywords = web2py, python, framework +generator = Web2py Web Framework +production = false +toolbar = false + +; Host configuration +[host] +names = localhost:*, 127.0.0.1:*, *:*, * + +; db configuration +[db] +uri = sqlite://storage.sqlite +migrate = true +pool_size = 10 + +; smtp address and credentials +[smtp] +server = smtp.gmail.com:587 +sender = you@gmail.com +login = username:password +tls = true +ssl = true + +[scheduler] +enabled = false +heartbeat = 1 + +[google] +analytics_id = \ No newline at end of file diff --git a/web2py/applications/SP/routes.example.py b/web2py/applications/SP/routes.example.py new file mode 100644 index 0000000..fa2a6c8 --- /dev/null +++ b/web2py/applications/SP/routes.example.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- + +# ---------------------------------------------------------------------------------------------------------------------- +# This is an app-specific example router +# +# This simple router is used for setting languages from app/languages directory +# as a part of the application path: app/<lang>/controller/function +# Language from default.py or 'en' (if the file is not found) is used as +# a default_language +# +# See <web2py-root-dir>/examples/routes.parametric.example.py for parameter's detail +# ---------------------------------------------------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------------------------------------------------- +# To enable this route file you must do the steps: +# 1. rename <web2py-root-dir>/examples/routes.parametric.example.py to routes.py +# 2. rename this APP/routes.example.py to APP/routes.py (where APP - is your application directory) +# 3. restart web2py (or reload routes in web2py admin interface) +# +# YOU CAN COPY THIS FILE TO ANY APPLICATION'S ROOT DIRECTORY WITHOUT CHANGES! +# ---------------------------------------------------------------------------------------------------------------------- + +from gluon.fileutils import abspath +from gluon.languages import read_possible_languages + +possible_languages = read_possible_languages(abspath('applications', app)) +# ---------------------------------------------------------------------------------------------------------------------- +# NOTE! app - is an application based router's parameter with name of an application. E.g.'welcome' +# ---------------------------------------------------------------------------------------------------------------------- + +routers = { + app: dict( + default_language=possible_languages['default'][0], + languages=[lang for lang in possible_languages if lang != 'default'] + ) +} + +# ---------------------------------------------------------------------------------------------------------------------- +# NOTE! To change language in your application using these rules add this line in one of your models files: +# ---------------------------------------------------------------------------------------------------------------------- +# if request.uri_language: T.force(request.uri_language) diff --git a/web2py/applications/SP/sessions/00c/0e7/127.0.0.1-3a55a2c1-03d7-4d77-a0f0-7c5167c6ffaf b/web2py/applications/SP/sessions/00c/0e7/127.0.0.1-3a55a2c1-03d7-4d77-a0f0-7c5167c6ffaf new file mode 100644 index 0000000000000000000000000000000000000000..956b39aed6d828a06b521c021a813fa0c08a060f GIT binary patch literal 193 zcmXBMO$vfQ6ae5BMG!>L8CtZN)Y0^Li>PIU%+DK*Mh8+M7eSkLv+H%0&R5WPfbTJW ze@1_PUfSL@o6<TdY)gK6z_vZRhF)~1wVxO(+KT*${HzdtR}~H3I`YflunROA(c3Pl zhsxDReo+{AtuHtntt-#XiB7*^6=oc^AY-O;ZCIirWFl2DLj`e!031|GewA|25tovM aD$7_B@|=Nzh(XE)h(x258DamVJ#D^+K|t{U literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/00d/0f4/127.0.0.1-c5e4640f-cd25-49f7-a9b4-ec61b28e19fb b/web2py/applications/SP/sessions/00d/0f4/127.0.0.1-c5e4640f-cd25-49f7-a9b4-ec61b28e19fb new file mode 100644 index 0000000000000000000000000000000000000000..f24f50af6d8e3513377f555cae8e7a0f9a28fa4b GIT binary patch literal 2266 zcmZWq%Zg-05cM%S<BU3^Ah=ZMg&@)9`>_$hrRYMJB28pwWOr$IS6fxB&O&gbAl!xG z6<q4dol6n%AN&VV#?SC%RZaWqMRBV-^2Ui1=bZfH+Sk9{cwqZCJ#l<`xja8SK3x_* zUC-0?w`9FuEYIh!=8xwWrbqfIuTSPTrrSq-xjK7K?!JAxJYJl?GrxoX9z@O2MK)Bs zRpeCYRC2cDRd3px>YS<bbYM#AH5pH-bRp+@rJRkUpiHQ``J$RbS<yQCQX<9JnVi&2 z$(2G`CliDAEY-|1J$(gbCC7{PMpk<?p^0)eIZAD`X{}MR-BI=2Gn%R#JKAtbL98$Z zlLN}Sr7T60_l8Z8=9JfHbMuHVHz!Bu^3ewKUmIWM`*f{0%M~BXplkoMqwCt`T2`pK zxZC*ja9Q4!x&f&Vzq$NyPv}F7Hox}ZbnTqaaQx9fe);zIpFW?b8{^>qx3_q6xjLVx zN92qbr}K2HOP5!g9M<L8Jl)w1z2XhFbcBV>(*yJL^h(yUIlAEW`ora_ZGS&`e!Bgy zVzfSa{_@lL&3U?swQi0+SgaQtG;h3-&0+xh`|+#!)tlFUd+gae&%Ai!vs?4-lzeot z*ma&?zw_jD<K&F%4#PpRW{|3gTeIZ4!jtkAD^EpY=&?IU;ntY*=y<ifyjVkEuRS!~ z{`1FA@BRG!y&t~2_r+&_eEH41o^Gw=OwI}l0qOG{;AgIuzTx$IFV&R*^M3EvIoEWB zZj6cKqL0M7Fe$GfPYp4aAunTHjmc*!+M>*OO)2_LsX`z%W~arV4E0WTXip?{azz;` zAv(&fTC2I)+&#*w@pzf{6kM+4LN&x)@RYKW-YXXyQKow4R$?J70h-L5@uG;PH~?0X z;ZRT}P<VoVNhfJ=h$u=5mI983u8vE!D8oP&BDTbClxbgxOY_8>qHu4e>5Q_DQ45Bq zP!fz}LjX3dsHGNttI69s%JA7z&4o%+SQ)#4O*aa_AB|%Z&G3s0u2`=F*$`p!7C=Y` zRA6u|GZ-<$FOP2}1@XzM+=XLy5_|trR*>kORt~pzs=Pj2w3pR9J$1FwCY>)&H}_qf zZ7Q)B3Rwe{xI!rbB*=}*nyR^MQT1MmV^7{ixER?0vu6bYZHwS8SmS`|xvMVQ_B&mz zPZk&dkkE7xq>Mv_nkxod60F;oMm^WyZE```Jo7&wZ$+rnRScG%#9$+_0*jP{e8b1s zu&y<T&O-}c`Jj5RWU&BPB%@5kkkVj18-$@vfc!TxyDoX(#n{RXwHUENO4u>6@j}M7 z-i@#^d4w%`R_`G;i88>nPB{dIP-4o+Kvzxqe;1?oUBuU(vuCQsf{LU9cx~WytEd<_ zvL3UfpaUBrAG;qTL()EKYQ<tr4np6C=znH0X5Xdjggi%mRvjh_kb180QMc@CgH3xy z8iBFe6%;qT2*y-Jw&OA(#l>qFi{Y97&!XeLOE$4a4vvhniJaH43tLahIIRtW%B#_Z zYwcb`(W&7A!;O<+7Z9sL_O^-PDgkBH1O!=RGDd?LV==O|*k-p;w0Aj}gtDHc>i|=t zJM>!syd*eYbVU-ecgl>Wsf$V-msO4y!oej-oN<#jRce!ptC5G}hd@FeM41Af$AKh4 zQB=7pHn<w&FyDW9cJ~>`&H0S1=wNEd(@+Lp3doxbK`8OC;z5;^5D=MsADS`PH)~{G zbkd!Tm0cVOilmeba3lq}>BQh}ZceCFFE&-BdmnF8JvE13q!F2Dsv{hXmm@*D*3D{V z$7r@9PO)#w$qfd2BjijZi)%hZ%POi7jSPjjhA8$<G(o+%Q!);uXnoTGdCNS@_LeyO E3und7zW@LL literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/05a/1f5/127.0.0.1-8f845cf0-8676-4057-ac7e-9c22692bdee9 b/web2py/applications/SP/sessions/05a/1f5/127.0.0.1-8f845cf0-8676-4057-ac7e-9c22692bdee9 new file mode 100644 index 0000000000000000000000000000000000000000..54484f35d48788a3a70100088c0c3c596b3e08f4 GIT binary patch literal 2086 zcmZ`)ON*RE6peB6U=mFt3PQHCaFLo+-Foi?mq8cFQbJRYTQhBXrpJDmWFfeT5cohP zpWsqK$V!(Y;;#|I_%l4!(<WqLFPeUwukO9)o^$G}o$qg6KDT)dZyn6m^W*)4**vG& zavUz*<K=QXKOUcrUydIP7uqZ>564f2-AP)n4kyR_XoYXrCT+erdccoAoy`xX$M?tk z!0vHoQ`tF@y^O*{Rw7Cwp`|R&HkoUoaoCHLl25saqEi+o<tT!dS!AVrHHl4Q1(+jk zJvk$cjCgaZh-66$!z49(Z;2XU#KxGaq)4?UVM5%T=0)%=diF6AYrwoqj&iP|*s5?w za3aOzg$k^TLE$JJVA-*wWQ{0Fp=b$O<m#l*!A9+4Gtu=CwA77QWf4_sI892C$v6>8 zYce)2Wdl>mlk%wul)$9cMG+f$;WAs5Fej-v@^JGdn;VXg_$c#Yc{n|}ZMV!;X;rn! z3T0#kAvi4?3PKvit@&CM6|_}!NRomVkutc*$$(i+A}LRvlCRck)O+vsdg~=GZmVr2 zF9B-C3uzm6SQU$CKn0hqvXt1V?sSrDjXUAmM9>+q^rRU51>-roP_^xJ>XvPBtVOT| z1ZdNHDMnP5T02*mTm?*JW5{L_tkAqMI4#KNP&r{REmf0*zIQr3<A0J}uI7t$z+JN2 zPiK<d>GJ?}^0=ni{ycxiWd&isd3XMBE9&#pI^KC>*f~x|c>LmvKY#rD_ow4<xj(r5 z?Os}~7sumpfsfL3HV#)BH~z5lewiPQ!}SFpOqZ)gTEQt3*kByajl(+&Uh-;kl9tPd z^F`hKet2uR_8J(a4{xoXjCaRj7uH%$zL+kjD-^G3#j9y==+(z(<43!f{@Q*2UG1;_ z+{Uw~_|eJqtn&Er^|y!1hexTL^{|&xEY@-sF4_XRLl6Pxz*a(R!55p1$1Hu$$-!d2 zK3R5?-#I^A`{%bOr++*@{q?8QZ@+%=-4C6fi>KfG^5Xe8u7@iNKGWm`?L9qf{{J;= zwo1w&$W}NAZQ&;a$BP`igZPz_E*707nt_#6)DE3W@3DLBr3j&Vk&^_*24yK=_g6P$ zfmUAR$32fW-#=gT0_5K~n$*0%8Ebmn=KCOdxbaftm0McRR@=6ubR{A^;P43RQb{mz zQ=%mF3H?Rqdioe!35teZE5ipJkz0lLVvWk=9QDR=ToEh5Bt%{xQo?rG=`0eJY}vaQ zxev+B#-xK3GWTR8_$$GqLN;eiCR<teSPA$y1QUd!2D=n=8G>#iP^pQ1uF7>+Mba7+ zAzhg;f+madK8aF-S2d{UWKRR<74QTDJB`?kt%@v>r;eLcs#)(h$(SkYQW7#Q5=J13 z$g;>HHIGKKtrj6Q?8%&i%2+274UUf%r?GXS7?L$uXDRnM27f)#v316qX^ljL4n!qi z9azX#Ijr;5c2;Tm;5PZ~b~q`g6BiL0`Y;k16q3fI&KI9rmZfG?sU^Bp@h1fh(KH95 zR8YV+rL;0F<j!Y9Y8Oy0LM)72L5@XJs))AfkhP6e3}D_OvnUb<a@cUr2>qx?cwJCD z1(|Y(AsI<R6oP~5FkDEHs)pH$)~y+p3GM|f7ZVz`raJ8o3r8wDI3R~Yj-%I|DD5~@ zEL)%gP9tSS)Xj^EsKy<rigR5#39E@v9(v1N5-x!nl*g3={YGuEBET9+2nqAmP{12& s=+Htrkc6q#*w(Dv6g3c-2MrE4rYRQpWK&-FSiFx0BCT!Yjl=i<1<MwSqyPW_ literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/078/122/127.0.0.1-33e760f6-e988-4855-bc05-acaa70a2a64b b/web2py/applications/SP/sessions/078/122/127.0.0.1-33e760f6-e988-4855-bc05-acaa70a2a64b new file mode 100644 index 0000000000000000000000000000000000000000..980ad8167385ffc8f2a73c3e06ad805073834ef3 GIT binary patch literal 153 zcmXBBF$%&k6adf;iXe#K85~^FDx|5sh1gL_`Dv53m?mHvu!G>@_HprhUkBfN&c5&H z4_B=T&c>~A5{xHY6w3SFS^Cg}b~x7td`B1&E-MIQS6Ou*2{%b`N*bjhm@yfq&JBui wU1@h4u4=j%*Y>ugl5o4%S(Y7i%A^3rcr9}VB5j!DM^Q@-xu_e0@S-!tKV@e&oB#j- literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/0e4/1ba/127.0.0.1-eda8a93c-17b3-4956-83d4-6145f10125d9 b/web2py/applications/SP/sessions/0e4/1ba/127.0.0.1-eda8a93c-17b3-4956-83d4-6145f10125d9 new file mode 100644 index 0000000000000000000000000000000000000000..364866b4563b90f8b7ed2dee3e0dfeccb5680edb GIT binary patch literal 487 zcmX|-%Ze3242BgHK@ibrn1!3nsY|LV^%5e^Qiek+l{#~<?S^xKaUr;I*E`F%^I@!> zg;|C#$(R4<i$8y#KYOb6&0)GO^X*|;3Qy<0zPi)%`MAvecmL5ptZ(;iIeq)8-@i=D z;W*#-`_a6yf}uLe;9UxU*a{G%gN9<sSnmSYzTQxZ?5%ph>?~l&3Y=?#STeJtY@C{b zrINKp<H35bfLa--N`ze8m?<TwY#4iy)N+JiV;x6p8{3kAF-0|zs)RDIEF_IHf&@aq z8WM2j1{Di8w8_W3xiz9%$a#>2aT7$~Sa4usOw%kW<$;CbinA2QDKp%t1YoWif=RBB zCZrk$7F{L^9>F2XaPt-jeFaNfQf9-n>-u`n*UQ6x*2ha<-|g-`?W#7uPM6(ruKL*5 zmu=$nL;twG|DXFw56AOGPh0dOQi)Vdh~w)pd{P$3(KA%T6jO>QUOHcY_0RqGAL>ez A`2YX_ literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/10d/091/127.0.0.1-f08a2093-f7db-4845-b460-0836a90b02c4 b/web2py/applications/SP/sessions/10d/091/127.0.0.1-f08a2093-f7db-4845-b460-0836a90b02c4 new file mode 100644 index 0000000000000000000000000000000000000000..973edfd4d1eaf5479cd00c7c89a4b83a21c09b19 GIT binary patch literal 117 zcmZo*nVQ7_0X@9wIi>k|dg(d&Nr^edQ+n8gQ;Ul;^Yf-mo>DtSqlYyuC$TtVieC?Z zd|G}{Zgy&AbWVPHW?t-+*eN|KmPr=oDP|_-x~55{X}Ts!riQwfCP~S<$th`xh9;JV R7AY2HQxZ#Crvy#W0{|%!C-MLQ literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/124/0ee/127.0.0.1-1f01e76d-a832-47ba-b184-eebd13ddb4cc b/web2py/applications/SP/sessions/124/0ee/127.0.0.1-1f01e76d-a832-47ba-b184-eebd13ddb4cc new file mode 100644 index 0000000000000000000000000000000000000000..feab374239ff6e2024ad5c17eec52ce94c518ee0 GIT binary patch literal 225 zcmXBNJxT;Y5I|uA!AQKs1}3%CRR2u(H8hk(y1J`|WycwCFfb5I%sR8Yn&)xA7k}_R zuYZ28{_D5X{I)K~X<oU^oAsMV*|zh#*tdOHzkAm8_2nY(PxCsRmy@0Bz8{*)<V70{ zr6Ty~6J!kt957>Xp+sWqhk`6I<pBbF1y9r<4NgHQb5)l}hq$xA=#X(|ITQG?MJPcc ns9>#GM=n%%Mp(HO^uXlysiq7mH~|zKdGxNhCMMgLJ=pONapy$X literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/127/192/127.0.0.1-144c5c8d-bf7d-440c-b952-879db22d2a07 b/web2py/applications/SP/sessions/127/192/127.0.0.1-144c5c8d-bf7d-440c-b952-879db22d2a07 new file mode 100644 index 0000000000000000000000000000000000000000..e2a53202fc6cb2a9e3b0819c947508ca6661e614 GIT binary patch literal 299 zcmX|*y-Ec!5JnXgD-nDGi(A;tC7VqCUcy34xk!?kSr^w`xa%z}1RJ|_#`kp<@oT>W z=e(bMT^%3&uAcYfVV<`AIOjAjt)AWSvJCUoKHFQnuBS4l<+0t=iwBwa&rke%KhFIy z?b>dAH@-_AebP|GC_v=|a*PJ766&ljh`O}8(K$#7+Cs>}fG7oG)Cf*#S30s;5w4gw z6oaJz$@mNy$w6WXpt$4|LoP_AalQOc*>gWEFTDS&al{HsKnV1sAtDGy5Q<F_SE-6# hR!z#mvEc+xN4H{PAad@&TAg%eLS?(ghmUsKw%@azUO)f< literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/130/151/127.0.0.1-f7b40c44-2670-4091-809e-f8e292d361d8 b/web2py/applications/SP/sessions/130/151/127.0.0.1-f7b40c44-2670-4091-809e-f8e292d361d8 new file mode 100644 index 0000000000000000000000000000000000000000..fc2e025e149131bf41cb7da70091427740f33b83 GIT binary patch literal 292 zcmX|*J4*yH6onNOK@ic-ehQoHX7ZZkPl&jsEJGeQvx9L4<^gLV*x04>`hSfUp7QW< z&i8TleRq2DmweTwbsRQb8l6ou=8GN7b3YFFh3|NuuiH3IuP^ZSoW`yn_P8%)C7Y%R z%5VZ+C?b^fM5|y33(?t7Yw(m}uDI70tY!ov10tNz#DEM1qn<Oz1(S8bBzKGjR|qdD z5z&>knhWAh6Fn$zSfdc~Woy^v&<=21FyCx<kJ|vzu4&o!Lx3aZ^O)>>z=wSMFFirm m&kIby-nlYd(-3SZ+P=I&xzscUV!c(|NLPEM(5|2Ogqt6wzhEZ- literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/13e/046/127.0.0.1-a4b375ce-9ef2-4cb8-b721-1eaff15515ba b/web2py/applications/SP/sessions/13e/046/127.0.0.1-a4b375ce-9ef2-4cb8-b721-1eaff15515ba new file mode 100644 index 0000000000000000000000000000000000000000..9266bbb7765a780b798a90e8fa8100a81df1bb9e GIT binary patch literal 331 zcmX|+u}TCn6h##jK@ibz*uv)RW?nK$rt=F#+)|e1B`=vB9A{u>2i8Kcu}f$CU!#S$ zy@$&^A7|h9rzd|&S8YF!!?Nv1NBxx3#X3w=HxBtLzvsJj9($U0`5|3z<G6o)32)E+ z*mlDvZ%Vsx)C9%M;2A4Wv97=(8bB?ONqA?C%xQr>5NcOLl%zpPhhT+_pamP{Nw5%A z!N~Z^)!sryHG>iYp{Zg69(5$fMoQxfW)PKS-GC%jFj-i~T7!?#A!{qjNDk?8OY>p3 z9m4UD)6HuAxZ)6L?hmVO;Bd_8_Friq+HN|8{jXJ8c;(U7o}e+dNR@Ly$Te^kLQuwA MG&<A#nV<6V2ltC<djJ3c literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/156/086/127.0.0.1-64331f4a-020d-4190-a0cd-db51c3091d10 b/web2py/applications/SP/sessions/156/086/127.0.0.1-64331f4a-020d-4190-a0cd-db51c3091d10 new file mode 100644 index 0000000000000000000000000000000000000000..d03d54eb650f8ea1ae46fdee750fab9c1fdd6c73 GIT binary patch literal 1895 zcmY*aO^aMr5RE!9F;SC<iWm?Vv&g0<_xr<z2rh#zlBI^B?!9$q+RRLk-909=5Zpuv zyoHh{xYU(9mm=b?5kveJdS1^sAr0NUkGfT->YO_L&BhO(UpTk^46p6%9nBB6cJ}6l z_m<;u;f^eqv-!dJc>H?2F`Vyvyxbi>9WHJ2(Q0@5Kpw1ccV)ZJ7yI|*__MwF&g|gs zcy}B&Q*m0UuE^!-Cx%GHs6e3==RKF;os2weOo_(-3olpm1@FjI`1I<e@W#<n7Kl1L zZoIcOFJDMq0p3fu=l4&cy*O**trv!k1K!8+m!JIk)8D^88i$M1!P94Vcy+Wm7>Dz+ z&$GR8xZI`7M@_cse19CSE@Wr6TrGHoez(!gIGh`YHx{y#)%GDTm-pw3wtl{QeYo;m zFiP)UKYBRc9*0X9&}#du*>bi*@y07z%_cz4E+3B{U%K$uEAPFz_4dXG|Bff8<iX+W zr1JR5)z^oMyZc;EFl;*CQ&v7vtQ^SMoQQ1<6iqGBNN=q)^fL9iy|b7f9WFuDtrv$Y z|NQpw=^wv5{q^Uk-+lY!`ya>UaCss7vR@DgNRLhcUpwP&#mjp)jhooJF>JC|scPTJ zm?WUjYAQW48Jo1K$recrmP7ZYC>yAYk3d%y<y<tS?nI1nQMe$i#L$9nnFOH8>Ds4k znM~BWrQ(yZ0b$Db(t}N;jGr_kLaByM$+>K@i&6R%7IUz@_)0mbM$VUjY=tT0-lEdM znPw4YYBs7zL%u0SQKP8fJ@wq34XiOwH-#BssG7-FLAKnPiZ_mm(kvz6YzKjxu5)Uc zBL<=!ITn=fx>3xWTn##?q7W8ZLh6ty3Z~^s&cJ3mxh^{C9F66QFo`OAk9wVp!OK`E zWwzu(Gh%zfh{`C#t7|zyc(N$R)84J`zdVu!<aup>yOph7h<3g>-kP-!QU4j8O*$X# ztxo9#Pn;M6s$hj&D&Q%KBGY1S%{VJ&f|YG@1qjIUguXkCCZ%9B#YNNE1ve2;xnvwb z4$KIw2TRF^L=tS(+2v~8#JX3aC1LShN}gQPU@`_pS{u___RXz}T2o>+ASQ{$1Rw|E zkO0*;?Tk3qcH+r(TN0Z{I`=8edrArf6kD>Y0N0gA7$l`yOo~7Vgo~~zry9v>cuvht za!CkFg$?dC2GYO|XHCp80b91Eu`?-XgfUtO!DjN23pCUrH3>o(fOFM`WOGJX3syBV zg_(?OR-*;m8icE}2Aj!R1v=k3TeefyZq|jsBTgMNYb8Y~sun*k>q6OTL#Eb}luecO z<e2ZDC0Tp$$wn`CXNS)v!zNkyLnUpEo{}|UHHp7l6}c6aT1T?C&XTRy{}~)ufH=e5 zw?e@eDBgN(V@i&)V^_V6h5NK-CAi{CbHvSo7x)43BnFtg^)RV!$`lsG>t+}`SYctV zfojH5P-3f+_AYfV7|}BUpZJkK6|guhnX|#<6Z%P9VGSs%q+&~pYN;DksXn#F5(t(8 zA|M6)>wvEwQ-jJl<vfXmo3t8yChm}iOBqyk1K&w0WQA{H4KVMXO=oSdvx7c=Zpd9n dlWn#nRzYjR5K)2Gv|58H@Mf&s$ZMnB`VYFqV`u;X literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/15a/0e7/127.0.0.1-d444ca1d-5c94-4268-b5d4-f84120a0f1c2 b/web2py/applications/SP/sessions/15a/0e7/127.0.0.1-d444ca1d-5c94-4268-b5d4-f84120a0f1c2 new file mode 100644 index 0000000000000000000000000000000000000000..dac3453be473eae1448b89c175623b29ee1cd8da GIT binary patch literal 193 zcmXBMJqp4w7=U31MG!>r3=S@_`D>coLUa@<X`8ggv;o_K9RwG*Y<^zF^C|ew5AS38 z{!IRbW$6ar?n>t~?K%kaqv^WZxA1~HY{Set-Bl1K5EiK(`YLVBt%tCVj{B%ERu8U^ znz8bYfv`%gzcv>$o}4f1_6+CWVWY4jSQHo~j3~shP)I33kYqe&1&swJ41UaJT-$`A bTuO|1P7|a}mLW+6Cq`;!Ndjhg!U1+)BGf-@ literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/15d/1ba/127.0.0.1-bdb65a41-a01f-4d6a-b6b2-37f998787c20 b/web2py/applications/SP/sessions/15d/1ba/127.0.0.1-bdb65a41-a01f-4d6a-b6b2-37f998787c20 new file mode 100644 index 0000000000000000000000000000000000000000..a8232127efb09bb979c28dddcc8bb732ca5c0960 GIT binary patch literal 107 zcmZo*nVP@=0X@9wIi>k|dg(d&Nr^edQ+n8gQ;Ul;^Yf-mo>Dudhd(|ozbH35wK6&< zKRq)qc1rA&9u<>Bvt(1VL_^)wR3k%OlawT5-NaOj6kRh@<5a_>WJ{yuw3I1{#jR6< Hrsx3xpS2|4 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/15e/1f6/127.0.0.1-d684f46e-042a-42ba-92cd-3d4a5fd5e6e5 b/web2py/applications/SP/sessions/15e/1f6/127.0.0.1-d684f46e-042a-42ba-92cd-3d4a5fd5e6e5 new file mode 100644 index 0000000000000000000000000000000000000000..ceb46da9e6fdda4fd2539e87bc2f1aeb25dccf50 GIT binary patch literal 58 zcmZo*nX1nK0X@9wIi>k|dg(d&Nr^edQ+n8gQ;Ul;^Yf-mo>DudhczuHu{dK&55tt= J)+s?#^Z*o26ypE@ literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/163/02a/127.0.0.1-3992ba2e-ef94-4ddc-8768-75f185e714c5 b/web2py/applications/SP/sessions/163/02a/127.0.0.1-3992ba2e-ef94-4ddc-8768-75f185e714c5 new file mode 100644 index 0000000000000000000000000000000000000000..84ec9a6e64dcbf52b6e5fd65e2c324c1634dfb58 GIT binary patch literal 256 zcmX|)yGjHx6hOC71VM!ThAC|B&SY{Y+5CmLr7X)$CiB3|1m*#5A=ucZ^ZKdwt_Ys~ zob!J5^}YEc-L+wj<E{<SQkXg29Q-`@apX^a<A-$J1e!Ze8&0<;T9@uL`qzciHa|S( zwQpz*OFo>tICxI?rzTFri$6by*!JU*kC#HGJZW7v2tp76I#+_-D+jg|mA2$bIK?Te zNmQt?0Ig60qIEz@2_Umqg+vsUDcPs(|6}rPKQDgz-K5Ob=wwk6Xfg)SND0Pj1G>1# P##>WYl4<?mC*J)4M`2Xi literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/176/091/127.0.0.1-03f20c11-1674-436d-9256-7d3cdf2e9c6b b/web2py/applications/SP/sessions/176/091/127.0.0.1-03f20c11-1674-436d-9256-7d3cdf2e9c6b new file mode 100644 index 0000000000000000000000000000000000000000..aadb81c08897309e653dda957321734ac24c2b0c GIT binary patch literal 1486 zcmYjRJ&znT5TyViArJx~M42K5%^dcOKa2bY3Mf%@8hgf<6Gt}e-U_8aqM_T4<rneC zcs`<tt#0?8J@dZ&$A^Fa^U()SpUY==59h<{o4bd@(1+9Y^6`&;I^7>$U;n!Pe*O0H z(R$F+tLyid&u`b^_{-1!_NRx#-TmvA*O&P3^Ik257@Wi;QkvCicrtQfx0u;V?bplm z978kiOuBSZ8i}conJKp7H3ZAi46wPRYh|Xv0kFcIn$$^?%Q6c-duG6D%soY(v_`<t zgui+*q1wb$T&MQ1Z%dhL987^j#?aD9L!2}$u^8uAasw>&p;>Y!UQ#i14(e^;Knvnc zW0K~81x?Gi4r;a<rJfQE#ceJ1(p$5VR|RaC^b)LKigfHIK#YvZ-u6W$=PZEr6;}?a z6KhzTsS%d0B(ddcBZ$qsht|NxbJ285pwJ_Y<(mwC*HUH(_3D=|-+OcPyZh6lAK%$C zMsJ+q$4a<7K@IE$eJ8gV=V)wW3o3QEcEi21g4<{v4lIWRtq%wy>j?%a>d4+HgcK;n z6iJ5|8LQ4vdCJ%>mQn*0QP@*4R9d92U9tI0*78j3129&spIj-K?daeDwvA+E)`^`> z>sD&54#68juxwzr$<$O5K_^HWTh+E*oYn&;hr4U@SQF9l<P?wsHK?As0H&*YjM1p} zTA=&dg2GDWIW<V{S@v$LG!HTp&6u!YnNF=3+*&n;nY;MfOg+TTGh^|oaM1*?paQy@ zYKgV2Het^<|Fh@hkGF61bo%XZv~AMmxq)sG?CT?9mY0Z3wL-xg=GZ`b)>SW`qKA*S zIOWIj7JdBW>HDu|Kfb+QzOr$n=f_vK=aV0A?(Nx&7tdhq7w-p~FFijzzKcZxWjF*) zlOm*=k!2}@lq{YF$sA)xUL*R&Ay8e#V5A2W2z^4sOyGQrmH<QAwdFjZ&W05zHmWDe zkqh!Uc%~=mqu_4G@jMYS?G36U&{}d4%Qz=H@)Lb(D>ll$VI|<vP~2N9I<UAy<Q<Dr zB_REY%3?^rMx)UTsr1Uj1A-CvP|S8-AQ`!WX;q_E!L;WbW$3bIJ3W>q_z)opRd!^N zBZaT1HKTsB;Q0cq=PA?DqB;at$ue9N3OUD=E7+{K>(m^?7e<x+=3o`HE<zuPL0j#L z7C2(@^?P@oth+lN&Tqbp|Ahii7J6PIRA}fSUQARC+Huwas}Nz7L(hL+f4JWK3p%v3 A(f|Me literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/17c/0b9/127.0.0.1-da5509be-5e08-4d6e-8704-82183b494f1e b/web2py/applications/SP/sessions/17c/0b9/127.0.0.1-da5509be-5e08-4d6e-8704-82183b494f1e new file mode 100644 index 0000000000000000000000000000000000000000..0c34980b05dd561b7def0866522e3d7a4d5b7e3c GIT binary patch literal 756 zcmX|<&1zIZ5QRk)At<8HkcFF?^iOqF_r^yMF-r+UcXjn-aGb&Ufn*`Lad&rKAJVt5 z5{BH>{W<sack0xy7k~dffA)AyZ&sVrZo61*cCBs>^YrRk4~O+`JO7z~&L5_iV^a^e z^QY<Ua_siszv=zg&2F{c-pn`l^%5JpRFJ^C!GMJXaz=y^e36_zv*&rbEF4GlQ~+HQ zK$QwbBtb0bhXx5u-egFz5^@I>H5ug&nKgscE?F|_pkOj3&9xSU-dqP9EYL(42G(3; zG!CJgEc?hlbAiz_0d^&*>KIb-IZzy71TmTP$Q(NvxMV;{9<pN()I2wGu^ObwxY&J` z240-yAWe`95wsS%3lgP_H0$*KX-s=vtq(`tpC{!*jlPqG2{8aBgRVgv^ioonSca2o z$AqA%b98`_Y@jN3g2MqZxRH}ebK_xBOu3{q5=bI*<J_P&OrYFGEinx9Hk#K~-f_9x zcip#pEAis-`Nv83_w)3ww?#c2Z<nWo?icI+(b>Bv{H~*(Hper463nesgwik?J!U8@ z-Wn+0b7q$s85Si!Tz3|2!~yn;(bw7`B^|l7?ue7g99cJ!22g)kht|=C-@3W6`ZlZs zdDt4s0olriPTt(m+tyU?AO}{ILD_6A<i+wa#a8c*7U1go^VOOCYQ61xH=lmbU*^Ss D6u0Kr literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/187/11f/127.0.0.1-7fdbcdd4-97a7-4348-b7ac-df2372d0a84c b/web2py/applications/SP/sessions/187/11f/127.0.0.1-7fdbcdd4-97a7-4348-b7ac-df2372d0a84c new file mode 100644 index 0000000000000000000000000000000000000000..d19b0832dfc7a31a6020d6eec8dd39c5bfa8b92b GIT binary patch literal 721 zcmY+By>3)75QPx}At51XsAyBrOm;jT|Gfs3D2m4RIEk{^jdFJ-D3ECAZijg#o{QNi zLc)a`AD?sPn;$QJ|9SrG@vLvIw#WVM{A#<evR&r->a#A(&3-q3&F}N$`f_Y#xt{B@ zxxT)X<Kg;pr(X|qeYaWeH(iGuw};I^mfN|$y&U_8yIcMCWxKz+*<H*F`+ufYxoeD2 z6Bgj24hj;1M{F?+ti91(&kBhosSTQ!3M{oi_E@1hmpY5`P-n78J|v0^jK!|#8b}}n zRzj~S1)^axQfBTBL3$V9TpryL<TOgsR0^p#S&9;=)($OnXC66%6iMK+`o<PqFq*7J zjU<7gIcK3Qd#F7k_#BE)WpIh75j^@q>M9f`!`u*|5=Y2w3@k%idz57j&bwldt|@S! z4%sDwl%=DH4c+|I^}|1!kJRt<uIj^beRIDFPh>j=*MkIbjNO2+(PGMg>~xIOo1<p6 zn$Loi6BMe(q6!;XPaqbWNKy~sl=uGsyyKz|8~2oy&_sh1U>LT;?i30e3T@R@MBAx9 z;UpYGPryAF!<lXA;?(+OPFiB_KAdp+QA3OBA%|wG_I&En7`meOF*c>xP39^yg-W2# Y$}^i=#u6=AY%q^*AWc2~oS)|TUzxbok^lez literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/18b/0eb/127.0.0.1-df1a50b7-edf5-446c-a054-b101a381e7ee b/web2py/applications/SP/sessions/18b/0eb/127.0.0.1-df1a50b7-edf5-446c-a054-b101a381e7ee new file mode 100644 index 0000000000000000000000000000000000000000..daece0a85b041c7d83e8fc6bb7359a9d92a46ed2 GIT binary patch literal 2014 zcmZ`)J#U;v5T-zigg}S_kf5P(K{L+o?AL6=PoRJjMbYfetYgK_g*&@QfkZ=h9mg-@ z5AnQ*6=S5hu-=nqcV?ci{r%&={(kn+`S1AI)y@6x&E?h2Zs^V7bbR)+9}d^MH>W>O zzn#86etM&ayO+DY`F^}R{doN3{QK8?-@iK@zqWCy_jj*ezV-d>_4(N4wfzuI$1h&4 z-TwBqzx%~}>HW>!i_;6-c9Em4TvVx9Yn0av)N2n^d*Yd5s%!A+cu`W*nv#*M$ds)Z zsdcB2El*iF1<fe)o@yv_QC}r*w^fqHjcN`tS!rX$f-+8Fg(#Vr(JH$d^)V+-)n&D7 zu`p1USm(-7DJ`j#TWmB!Tok<b6~>Hyo-H)y#i5gGL{l+*jjR+kmX&5nD*=Fux#|#Z zMpm0_w_#Hj#^pY=^_9HI)^vpISsO*G1DmqZz=E{AWG@n8uW7qY3wObBUlUCW)|G`l zf_qG51;ctMGnYIEV;HZt-PTA$X~Y$$J<c@xIQj9*_w1b6yFd8;dE6K}Ui1O*O2O7R zNI5$LE1485X(?V;;BeC8w@+`l_1oe5!>jAJ&+`M*BlT(-z2lrpIk}Q{Ta>F{VQ=gu zqF*f0V!<YBDwqZpB;5*e8y-1wlQFmbS;puwQmr{*EPRd87TM@QTI!slqKxZu&W3SI z>$oip(gtvsa1B-@1{Li8)zj&(_PhJX!PRGP#+hQ7kf`KAXaZ%G6w#`3;!Q2f@=yg( zs(Df#4P|w83|?gd`JB#BfA_T2e}I~M*E@eet4ftot<v-nHzhM^7ASc_>qA3rXS9qX ze6r9=DxeI_sRKP?fao?`F5=s4Zi!d#WDylWe33{<)F7&w1S+qaL^tfZC8*Of(3-GM zpAxW<S`7mhoM%u&iE(8iXd4op0kZ)ET4R}_9-~))`aenh3+j_4hmJKHybQ6TA6TPN zI%cb^thwgyn_Xw)R7)@djNn?=gd{*>p5720nC6V^H&2m0i}<k}qQ==3W+Yq%%a{oa z2wbtdMb#BjH7NNpsqXaf`gtr5j7%#z3J8@=c9_Irb5jhZ&={~Pyg9DbIy7M&C=pOc zm{@vaGB0bEY~JQ(b7-j#1GS1Bw$Q+r;6U*)L|U&1zm1WQC8;>AH83-CAsGr<(h5=v z>@c@@jKHyTKuW;W8zY#K!AP$))Y#kFZu@}D&pzLh7z;$G3eK(@84dX)5In4eFkReo zYiQMzBpW$Xi38ZdjtE7VL$KN!$wR3dXSoN|7bbWIOm&2!RGe}S(<*wk9-aix8SF>8 zFi?YF>q_9OAT@IA2^L4r6$GviL9e`N8~@n^6;pIm2Mg&YN%!HQMdudEhj!-&ZdK~U z+mL87j_06-dfrSjIWN2qt$IhRFj5+Z7hrkX9)v9kf;z>9n6HtwL-=r83@LPYH_3u2 zBOZ^=KJnUcx8{AeVVLOi_j<kAU0uI<7^P)U4U3bOfy7qm{G3=Yt#co#CIE+Ew<cYp dQ{@0~8caJF#xLwEaYQKPe)9W2PCuP4{{csFT15Z= literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/18d/0e8/127.0.0.1-540d2395-25f8-4a5a-b8cd-00b5d5a08207 b/web2py/applications/SP/sessions/18d/0e8/127.0.0.1-540d2395-25f8-4a5a-b8cd-00b5d5a08207 new file mode 100644 index 0000000000000000000000000000000000000000..91bc82f5ac0c09f879dc4a33397672c8ce77459a GIT binary patch literal 153 zcmXBBy$ZrG5CGr~iXe#4XK-*yo0eehTZkQ{l&fBUFipTTU<bj)?QrpYUkAVMIs3kY zKU%fgTNAa~)}S5JqCn?*Yxu(t-qO6$;5w#&X<30EyUO5wWD4Wr5MQtXug7?pIy)fK wx@zogxZ-ruw(U*HCDTS_Iifu8MIzH$s615yY6T)mGATi!glxy)Uwq`~2Ts8?ivR!s literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/18e/0e6/127.0.0.1-317bc46a-dbc3-4a32-93ea-e8b53f02ae19 b/web2py/applications/SP/sessions/18e/0e6/127.0.0.1-317bc46a-dbc3-4a32-93ea-e8b53f02ae19 new file mode 100644 index 0000000000000000000000000000000000000000..5c42c5956b4a2c6b9c2817fc7209c93eb780d20d GIT binary patch literal 1161 zcmY*ZyRIBX5H**zuQ3n%T0;DQ1Cm<x`;j0dM1&x)6C`A<x~r>q2X^mVW@fqE07ODI znVX!1&+yM6_z!9y7%{=Bx8`)!sdK94m&I>CFYX<m`Tg~F-(N4++dil5*yhU@G>%<= z-Cnhy+Q;+#x=rJzeKkK`)qdE0M|a<B`*nByvc2TD&rCMLM&m$=>cK>Z5P~sKm5dmI z^j`WlKZ{;hEnNg7GJ+vY5D_itXk;aY$~(z0<8*Sy7a$~txlkZ@3LvOpz+k94#V~Rd zQi=vj76nZ82pQ2sH7P`_*(+5T7Nqtv_z1NG2d0pNM8boOGAO63stOr~MSHJ{W8xUV zpp_7Wm*BGW*$JJPB*T2<bHEG|1^3~|LWs^m&Z-E78e_E#<67ig$l!xjV5H6vONk(i ziatsqq$h?+rhujh@L6%E78PXS1CTe_k&+&zX*555Bl<w=Zk%X1>n>H&vN)DTX)a?~ zf}|)ziP09+u?kFFMk%tzYXL?(wug}U3R6KVQG+GSq8@ZtR#YchA8QWTbQF-K&>*4~ ztXm4HNM`dMkHWO-heAWX<B@oD{Qv!)hPyUjmAp**X|vjoG%UOFiQw29`h{xRZ>KYR zizeil48&|Svo`@Ecg%i9DShz5X2-Ogl~okMtyNutuQ2<R3Rp`u<XnXF2g!wFr?so# z%3-*2F>GZnoXwNWl^w;y3}R5m^XNcvlCv4fGnk}+pgb9@E^u0Ia&c&){ks<9)DLOR zj$OVupH6GBICROVo4b;>%RYZgIPvnl{k*?DFV00*+81xli|e%G>ks~V{rlg4yl(Tu z!^Kl<@%hm40N$rv>b9KgcDSYbX&vek`(2x#oGc&G#M`*y#cT7uHa{I`q-k}N#_^V& zIL0?(e*8Z$m)?l|ukCp|d-Ov$b`uvbX`-n+5c==<s(tq8^3QiZy87_q;_B;mx<x<U zbf?Pg%O@Yq4>!AnCl0)QS+d3z6!Ov-gBp_Oy=NOlw1QY-w*K8ipR4uI?{7x_kgyUD NjuF|$BeCPp@*lIhdEo#6 literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/190/0ef/127.0.0.1-efdbf1a4-bdcc-4cb9-9117-a756917f9703 b/web2py/applications/SP/sessions/190/0ef/127.0.0.1-efdbf1a4-bdcc-4cb9-9117-a756917f9703 new file mode 100644 index 0000000000000000000000000000000000000000..aec31bd3dce0c44fc2fe5c0819488903c359781b GIT binary patch literal 331 zcmX|+y-LJD6h;*kK@ibr*uv)S&VOb)pFqSdWeInFZZ;Sb*d(wPf{opDj_+%<@T)#J zr#T;I-}k2{f6G@*HxK=~=?0J8Sn|a-jbl6X<*U4xyL?U^j{EYEuWK3(uP^ECxf`0c z-<91$SIh{bA`cKPA}C`exWJc3Qjm9885c`l1sM}lT!C|pFHjSpwhW>|Nj6%iO;|Kx ze8sg@ph;^`(nUaCaqzLCD3xGdx<zBgM-mc2l9!+aIq;rY2sR)$D0R}hq<mT9Jnic~ z9jB6SHrvNdOoVecZQ4GjW68JwNr%+5<CG4+Re5E!;W9c7QQ9R%R0P&K56CExs8|rr L6`ViIQ(6B2g+OS| literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/sessions/1d2/1c9/127.0.0.1-b33d3d8c-220e-4e99-ac6e-1d9d4b7eebdc b/web2py/applications/SP/sessions/1d2/1c9/127.0.0.1-b33d3d8c-220e-4e99-ac6e-1d9d4b7eebdc new file mode 100644 index 0000000000000000000000000000000000000000..fc2f748ee415c5834aeffa80e999cedba9ef5fc0 GIT binary patch literal 479 zcmYk2%ZgMn5Qax^5Cm~><pcD>O-(12Tje!$DMM2^sq{2+>@##uqb>wD?y@t!nGa-o z1hLlNf2sfb^IyN8T|HfUwV%(+@peBiiRaqeiw{!kVLA4n{ab(6Uheq3-tUg`W$o=| zTOYSs3ZLh7yK;T#?e(rKr%w;^_2azk568QHH$)q2goP6VQPE(dk3cReprS~7R~*IM z+eTT|(fb5A6$O?>Lt^g$gA1mJWySu2WnmP_K&aBd976QO;E*Y#NaFGZb5ToBWPvS> z&}niIDJU=sBZk5$cpO;7DMr*5lu34U3j|4f3n^w&oK@5l53D4s!(bs8PhiCjUq=&6 z#@OIcC=qpOZ~py%lKr8sa=J{=HpVC}*((q~ls0IFh^zr|a#9eB@wRh&`=7kZx_jhW uKQE{J*F*=&Rv82?qlncd07uGDoKoz38B?ZVa$RPw_q|>9^N;?%-~Is>fRxDq literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/static/403.html b/web2py/applications/SP/static/403.html new file mode 100644 index 0000000..e1a29c1 --- /dev/null +++ b/web2py/applications/SP/static/403.html @@ -0,0 +1 @@ +403 diff --git a/web2py/applications/SP/static/404.html b/web2py/applications/SP/static/404.html new file mode 100644 index 0000000..f1b1cb3 --- /dev/null +++ b/web2py/applications/SP/static/404.html @@ -0,0 +1 @@ +404 diff --git a/web2py/applications/SP/static/500.html b/web2py/applications/SP/static/500.html new file mode 100644 index 0000000..1b79f38 --- /dev/null +++ b/web2py/applications/SP/static/500.html @@ -0,0 +1 @@ +500 diff --git a/web2py/applications/SP/static/503.html b/web2py/applications/SP/static/503.html new file mode 100644 index 0000000..b063a75 --- /dev/null +++ b/web2py/applications/SP/static/503.html @@ -0,0 +1 @@ +<html><body><h1>Temporarily down for maintenance</h1></body></html> \ No newline at end of file diff --git a/web2py/applications/SP/static/css/bootstrap.min.css b/web2py/applications/SP/static/css/bootstrap.min.css new file mode 100644 index 0000000..6561b6f --- /dev/null +++ b/web2py/applications/SP/static/css/bootstrap.min.css @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.0.0 (https://getbootstrap.com) + * Copyright 2011-2018 The Bootstrap Authors + * Copyright 2011-2018 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014 \00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-sm-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-sm-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-sm-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-sm-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-sm-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-sm-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-sm-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-sm-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-sm-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-sm-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-sm-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-sm-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-sm-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-sm-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-md-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-md-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-md-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-md-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-md-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-md-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-md-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-md-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-md-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-md-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-md-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-md-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-md-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-md-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-lg-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-lg-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-lg-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-lg-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-lg-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-lg-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-lg-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-lg-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-lg-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-lg-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-lg-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-lg-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-lg-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-lg-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-xl-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-xl-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-xl-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-xl-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-xl-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-xl-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-xl-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-xl-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-xl-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-xl-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-xl-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-xl-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-xl-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-xl-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;max-width:100%;margin-bottom:1rem;background-color:transparent}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:not([size]):not([multiple]){height:calc(2.25rem + 2px)}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm,.input-group-lg>.form-control-plaintext.form-control,.input-group-lg>.input-group-append>.form-control-plaintext.btn,.input-group-lg>.input-group-append>.form-control-plaintext.input-group-text,.input-group-lg>.input-group-prepend>.form-control-plaintext.btn,.input-group-lg>.input-group-prepend>.form-control-plaintext.input-group-text,.input-group-sm>.form-control-plaintext.form-control,.input-group-sm>.input-group-append>.form-control-plaintext.btn,.input-group-sm>.input-group-append>.form-control-plaintext.input-group-text,.input-group-sm>.input-group-prepend>.form-control-plaintext.btn,.input-group-sm>.input-group-prepend>.form-control-plaintext.input-group-text{padding-right:0;padding-left:0}.form-control-sm,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-sm>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-sm>select.form-control:not([size]):not([multiple]),select.form-control-sm:not([size]):not([multiple]){height:calc(1.8125rem + 2px)}.form-control-lg,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-lg>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-lg>select.form-control:not([size]):not([multiple]),select.form-control-lg:not([size]):not([multiple]){height:calc(2.875rem + 2px)}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(40,167,69,.8);border-radius:.2rem}.custom-select.is-valid,.form-control.is-valid,.was-validated .custom-select:valid,.was-validated .form-control:valid{border-color:#28a745}.custom-select.is-valid:focus,.form-control.is-valid:focus,.was-validated .custom-select:valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{background-color:#71dd8a}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(40,167,69,.25)}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label::before,.was-validated .custom-file-input:valid~.custom-file-label::before{border-color:inherit}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(220,53,69,.8);border-radius:.2rem}.custom-select.is-invalid,.form-control.is-invalid,.was-validated .custom-select:invalid,.was-validated .form-control:invalid{border-color:#dc3545}.custom-select.is-invalid:focus,.form-control.is-invalid:focus,.was-validated .custom-select:invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{background-color:#efa2a9}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(220,53,69,.25)}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label::before,.was-validated .custom-file-input:invalid~.custom-file-label::before{border-color:inherit}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group{width:auto}.form-inline .form-check{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.btn:focus,.btn:hover{text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}.btn:not(:disabled):not(.disabled).active,.btn:not(:disabled):not(.disabled):active{background-image:none}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-primary{color:#007bff;background-color:transparent;background-image:none;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;background-color:transparent;background-image:none;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;background-color:transparent;background-image:none;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;background-color:transparent;background-image:none;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;background-color:transparent;background-image:none;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;background-color:transparent;background-image:none;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;background-color:transparent;background-image:none;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;background-color:transparent;background-image:none;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;background-color:transparent}.btn-link:hover{color:#0056b3;text-decoration:underline;background-color:transparent;border-color:transparent}.btn-link.focus,.btn-link:focus{text-decoration:underline;border-color:transparent;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;transition:opacity .15s linear}.fade.show{opacity:1}.collapse{display:none}.collapse.show{display:block}tr.collapse.show{display:table-row}tbody.collapse.show{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}.dropdown,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropup .dropdown-menu{margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;width:0;height:0;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.btn-group,.btn-group-vertical{position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after{margin-left:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control{position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file:focus,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control{margin-left:-1px}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::before{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label,.input-group>.custom-file:not(:first-child) .custom-file-label::before{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-webkit-box;display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:active~.custom-control-label::before{color:#fff;background-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{margin-bottom:0}.custom-control-label::before{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;pointer-events:none;content:"";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#dee2e6}.custom-control-label::after{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;content:"";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center;background-size:8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:inset 0 1px 2px rgba(0,0,0,.075),0 0 5px rgba(128,189,255,.5)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:125%}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-control{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:focus~.custom-file-control::before{border-color:#80bdff}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(calc(2.25rem + 2px) - 1px * 2);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:1px solid #ced4da;border-radius:0 .25rem .25rem 0}.nav{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler:not(:disabled):not(.disabled){cursor:pointer}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .dropup .dropdown-menu{top:auto;bottom:100%}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .dropup .dropdown-menu{top:auto;bottom:100%}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .dropup .dropdown-menu{top:auto;bottom:100%}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .dropup .dropdown-menu{top:auto;bottom:100%}}.navbar-expand{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .dropup .dropdown-menu{top:auto;bottom:100%}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem}.card-columns .card{display:inline-block;width:100%}}.breadcrumb{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;padding-left:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-webkit-box;display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}.badge-primary[href]:focus,.badge-primary[href]:hover{color:#fff;text-decoration:none;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}.badge-secondary[href]:focus,.badge-secondary[href]:hover{color:#fff;text-decoration:none;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}.badge-success[href]:focus,.badge-success[href]:hover{color:#fff;text-decoration:none;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}.badge-info[href]:focus,.badge-info[href]:hover{color:#fff;text-decoration:none;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}.badge-warning[href]:focus,.badge-warning[href]:hover{color:#212529;text-decoration:none;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}.badge-danger[href]:focus,.badge-danger[href]:hover{color:#fff;text-decoration:none;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}.badge-light[href]:focus,.badge-light[href]:hover{color:#212529;text-decoration:none;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}.badge-dark[href]:focus,.badge-dark[href]:hover{color:#fff;text-decoration:none;background-color:#1d2124}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-webkit-box;display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;background-color:#007bff;transition:width .6s ease}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.media{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.media-body{-webkit-box-flex:1;-ms-flex:1;flex:1}.list-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:focus,.list-group-item:hover{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:focus,.close:hover{color:#000;text-decoration:none;opacity:.75}.close:not(:disabled):not(.disabled){cursor:pointer}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.show .modal-dialog{-webkit-transform:translate(0,0);transform:translate(0,0)}.modal-dialog-centered{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;min-height:calc(100% - (.5rem * 2))}.modal-content{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:1rem;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top] .arrow,.bs-popover-top .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom:0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-top .arrow::after{bottom:1px;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right] .arrow,.bs-popover-right .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left:0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-right .arrow::after{left:1px;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom] .arrow,.bs-popover-bottom .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left] .arrow,.bs-popover-left .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;transition:-webkit-transform .6s ease;transition:transform .6s ease;transition:transform .6s ease,-webkit-transform .6s ease;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translateX(100%);transform:translateX(100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translateX(-100%);transform:translateX(-100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{position:absolute;right:0;bottom:10px;left:0;z-index:15;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{position:relative;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;background-color:rgba(255,255,255,.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-circle{border-radius:50%!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-sm-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-md-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-lg-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-xl-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;-webkit-clip-path:inset(50%);clip-path:inset(50%);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal;-webkit-clip-path:none;clip-path:none}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0062cc!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#545b62!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#1e7e34!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#117a8b!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#d39e00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#bd2130!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#dae0e5!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#1d2124!important}.text-muted{color:#6c757d!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/web2py/applications/SP/static/css/bootstrap.min.css.map b/web2py/applications/SP/static/css/bootstrap.min.css.map new file mode 100644 index 0000000..ee5c523 --- /dev/null +++ b/web2py/applications/SP/static/css/bootstrap.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../../scss/bootstrap.scss","../../scss/_root.scss","../../scss/_reboot.scss","dist/css/bootstrap.css","bootstrap.css","../../scss/mixins/_hover.scss","../../scss/_type.scss","../../scss/mixins/_lists.scss","../../scss/_images.scss","../../scss/mixins/_image.scss","../../scss/mixins/_border-radius.scss","../../scss/_code.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_breakpoints.scss","../../scss/mixins/_grid-framework.scss","../../scss/_tables.scss","../../scss/mixins/_table-row.scss","../../scss/_forms.scss","../../scss/mixins/_transition.scss","../../scss/mixins/_forms.scss","../../scss/mixins/_gradients.scss","../../scss/_buttons.scss","../../scss/mixins/_buttons.scss","../../scss/_transitions.scss","../../scss/_dropdown.scss","../../scss/mixins/_caret.scss","../../scss/mixins/_nav-divider.scss","../../scss/_button-group.scss","../../scss/_input-group.scss","../../scss/_custom-forms.scss","../../scss/_nav.scss","../../scss/_navbar.scss","../../scss/_card.scss","../../scss/_breadcrumb.scss","../../scss/_pagination.scss","../../scss/mixins/_pagination.scss","../../scss/_badge.scss","../../scss/mixins/_badge.scss","../../scss/_jumbotron.scss","../../scss/_alert.scss","../../scss/mixins/_alert.scss","../../scss/_progress.scss","../../scss/_media.scss","../../scss/_list-group.scss","../../scss/mixins/_list-group.scss","../../scss/_close.scss","../../scss/_modal.scss","../../scss/_tooltip.scss","../../scss/mixins/_reset-text.scss","../../scss/_popover.scss","../../scss/_carousel.scss","../../scss/utilities/_align.scss","../../scss/mixins/_background-variant.scss","../../scss/utilities/_background.scss","../../scss/utilities/_borders.scss","../../scss/mixins/_clearfix.scss","../../scss/utilities/_display.scss","../../scss/utilities/_embed.scss","../../scss/utilities/_flex.scss","../../scss/utilities/_float.scss","../../scss/mixins/_float.scss","../../scss/utilities/_position.scss","../../scss/utilities/_screenreaders.scss","../../scss/mixins/_screen-reader.scss","../../scss/utilities/_sizing.scss","../../scss/utilities/_spacing.scss","../../scss/utilities/_text.scss","../../scss/mixins/_text-truncate.scss","../../scss/mixins/_text-emphasis.scss","../../scss/mixins/_text-hide.scss","../../scss/utilities/_visibility.scss","../../scss/mixins/_visibility.scss","../../scss/_print.scss"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Bootstrap v4.0.0 (https://getbootstrap.com)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"root\";\n@import \"reboot\";\n@import \"type\";\n@import \"images\";\n@import \"code\";\n@import \"grid\";\n@import \"tables\";\n@import \"forms\";\n@import \"buttons\";\n@import \"transitions\";\n@import \"dropdown\";\n@import \"button-group\";\n@import \"input-group\";\n@import \"custom-forms\";\n@import \"nav\";\n@import \"navbar\";\n@import \"card\";\n@import \"breadcrumb\";\n@import \"pagination\";\n@import \"badge\";\n@import \"jumbotron\";\n@import \"alert\";\n@import \"progress\";\n@import \"media\";\n@import \"list-group\";\n@import \"close\";\n@import \"modal\";\n@import \"tooltip\";\n@import \"popover\";\n@import \"carousel\";\n@import \"utilities\";\n@import \"print\";\n",":root {\n // Custom variable values only support SassScript inside `#{}`.\n @each $color, $value in $colors {\n --#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$color}: #{$value};\n }\n\n @each $bp, $value in $grid-breakpoints {\n --breakpoint-#{$bp}: #{$value};\n }\n\n // Use `inspect` for lists so that quoted items keep the quotes.\n // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n --font-family-sans-serif: #{inspect($font-family-sans-serif)};\n --font-family-monospace: #{inspect($font-family-monospace)};\n}\n","// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Setting @viewport causes scrollbars to overlap content in IE11 and Edge, so\n// we force a non-overlapping, non-auto-hiding scrollbar to counteract.\n// 6. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -ms-text-size-adjust: 100%; // 4\n -ms-overflow-style: scrollbar; // 5\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0); // 6\n}\n\n// IE10+ doesn't honor `<meta name=\"viewport\">` in some cases.\n@at-root {\n @-ms-viewport {\n width: device-width;\n }\n}\n\n// stylelint-disable selector-list-comma-newline-after\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\narticle, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n// stylelint-enable selector-list-comma-newline-after\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use the\n// the `inherit` value on things like `<th>` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n font-size: $font-size-base;\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Suppress the focus outline on elements that cannot be accessed via keyboard.\n// This prevents an unwanted focus outline from appearing around elements that\n// might still respond to pointer events.\n//\n// Credit: https://github.com/suitcss/base\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n// stylelint-enable selector-list-comma-newline-after\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `<p>`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Remove the bottom border in Firefox 39-.\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Duplicate behavior to the data-* attribute for our tooltip plugin\n\nabbr[title],\nabbr[data-original-title] { // 4\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 1\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic; // Add the correct font style in Android 4.3-\n}\n\n// stylelint-disable font-weight-notation\nb,\nstrong {\n font-weight: bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n// stylelint-enable font-weight-notation\n\nsmall {\n font-size: 80%; // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n -webkit-text-decoration-skip: objects; // Remove gaps in links underline in iOS 8+ and Safari 8+.\n\n @include hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href)\n// which have not been made explicitly keyboard-focusable (without tabindex).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n\n @include hover-focus {\n color: inherit;\n text-decoration: none;\n }\n\n &:focus {\n outline: 0;\n }\n}\n\n\n//\n// Code\n//\n\n// stylelint-disable font-family-no-duplicate-names\npre,\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; // Correct the inheritance and scaling of font size in all browsers.\n font-size: 1em; // Correct the odd `em` font sizing in all browsers.\n}\n// stylelint-enable font-family-no-duplicate-names\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // We have @viewport set which causes scrollbars to overlap content in IE11 and Edge, so\n // we force a non-overlapping, non-auto-hiding scrollbar to counteract.\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg:not(:root) {\n overflow: hidden; // Hide the overflow in IE\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $text-muted;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n // Matches default `<td>` alignment by inheriting from the `<body>`, or the\n // closest parent with a set `text-align`.\n text-align: inherit;\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: .5rem;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n border-radius: 0;\n}\n\n// Work around a Firefox/IE bug where the transparent `button` background\n// results in a loss of the default `button` focus styles.\n//\n// Credit: https://github.com/suitcss/base/\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\nhtml [type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n // Remove the default appearance of temporal inputs to avoid a Mobile Safari\n // bug where setting a custom line-height prevents text from being vertically\n // centered within the input.\n // See https://bugs.webkit.org/show_bug.cgi?id=139848\n // and https://github.com/twbs/bootstrap/issues/11266\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. `<div>`s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding and cancel buttons in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n cursor: pointer;\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","/*!\n * Bootstrap v4.0.0 (https://getbootstrap.com)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n:root {\n --blue: #007bff;\n --indigo: #6610f2;\n --purple: #6f42c1;\n --pink: #e83e8c;\n --red: #dc3545;\n --orange: #fd7e14;\n --yellow: #ffc107;\n --green: #28a745;\n --teal: #20c997;\n --cyan: #17a2b8;\n --white: #fff;\n --gray: #6c757d;\n --gray-dark: #343a40;\n --primary: #007bff;\n --secondary: #6c757d;\n --success: #28a745;\n --info: #17a2b8;\n --warning: #ffc107;\n --danger: #dc3545;\n --light: #f8f9fa;\n --dark: #343a40;\n --breakpoint-xs: 0;\n --breakpoint-sm: 576px;\n --breakpoint-md: 768px;\n --breakpoint-lg: 992px;\n --breakpoint-xl: 1200px;\n --font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n -ms-overflow-style: scrollbar;\n -webkit-tap-highlight-color: transparent;\n}\n\n@-ms-viewport {\n width: device-width;\n}\n\narticle, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n -webkit-text-decoration-skip: objects;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus {\n outline: 0;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: .5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\nbutton,\nhtml [type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: 0.5rem;\n font-family: inherit;\n font-weight: 500;\n line-height: 1.2;\n color: inherit;\n}\n\nh1, .h1 {\n font-size: 2.5rem;\n}\n\nh2, .h2 {\n font-size: 2rem;\n}\n\nh3, .h3 {\n font-size: 1.75rem;\n}\n\nh4, .h4 {\n font-size: 1.5rem;\n}\n\nh5, .h5 {\n font-size: 1.25rem;\n}\n\nh6, .h6 {\n font-size: 1rem;\n}\n\n.lead {\n font-size: 1.25rem;\n font-weight: 300;\n}\n\n.display-1 {\n font-size: 6rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-2 {\n font-size: 5.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-3 {\n font-size: 4.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-4 {\n font-size: 3.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\nhr {\n margin-top: 1rem;\n margin-bottom: 1rem;\n border: 0;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\nsmall,\n.small {\n font-size: 80%;\n font-weight: 400;\n}\n\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline-item {\n display: inline-block;\n}\n\n.list-inline-item:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n.blockquote {\n margin-bottom: 1rem;\n font-size: 1.25rem;\n}\n\n.blockquote-footer {\n display: block;\n font-size: 80%;\n color: #6c757d;\n}\n\n.blockquote-footer::before {\n content: \"\\2014 \\00A0\";\n}\n\n.img-fluid {\n max-width: 100%;\n height: auto;\n}\n\n.img-thumbnail {\n padding: 0.25rem;\n background-color: #fff;\n border: 1px solid #dee2e6;\n border-radius: 0.25rem;\n max-width: 100%;\n height: auto;\n}\n\n.figure {\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: 0.5rem;\n line-height: 1;\n}\n\n.figure-caption {\n font-size: 90%;\n color: #6c757d;\n}\n\ncode,\nkbd,\npre,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\ncode {\n font-size: 87.5%;\n color: #e83e8c;\n word-break: break-word;\n}\n\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.2rem 0.4rem;\n font-size: 87.5%;\n color: #fff;\n background-color: #212529;\n border-radius: 0.2rem;\n}\n\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n}\n\npre {\n display: block;\n font-size: 87.5%;\n color: #212529;\n}\n\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n\n.container {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container {\n max-width: 1140px;\n }\n}\n\n.container-fluid {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n.row {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n min-height: 1px;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -webkit-box-flex: 1;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.col-auto {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n}\n\n.col-1 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n -webkit-box-ordinal-group: 0;\n -ms-flex-order: -1;\n order: -1;\n}\n\n.order-last {\n -webkit-box-ordinal-group: 14;\n -ms-flex-order: 13;\n order: 13;\n}\n\n.order-0 {\n -webkit-box-ordinal-group: 1;\n -ms-flex-order: 0;\n order: 0;\n}\n\n.order-1 {\n -webkit-box-ordinal-group: 2;\n -ms-flex-order: 1;\n order: 1;\n}\n\n.order-2 {\n -webkit-box-ordinal-group: 3;\n -ms-flex-order: 2;\n order: 2;\n}\n\n.order-3 {\n -webkit-box-ordinal-group: 4;\n -ms-flex-order: 3;\n order: 3;\n}\n\n.order-4 {\n -webkit-box-ordinal-group: 5;\n -ms-flex-order: 4;\n order: 4;\n}\n\n.order-5 {\n -webkit-box-ordinal-group: 6;\n -ms-flex-order: 5;\n order: 5;\n}\n\n.order-6 {\n -webkit-box-ordinal-group: 7;\n -ms-flex-order: 6;\n order: 6;\n}\n\n.order-7 {\n -webkit-box-ordinal-group: 8;\n -ms-flex-order: 7;\n order: 7;\n}\n\n.order-8 {\n -webkit-box-ordinal-group: 9;\n -ms-flex-order: 8;\n order: 8;\n}\n\n.order-9 {\n -webkit-box-ordinal-group: 10;\n -ms-flex-order: 9;\n order: 9;\n}\n\n.order-10 {\n -webkit-box-ordinal-group: 11;\n -ms-flex-order: 10;\n order: 10;\n}\n\n.order-11 {\n -webkit-box-ordinal-group: 12;\n -ms-flex-order: 11;\n order: 11;\n}\n\n.order-12 {\n -webkit-box-ordinal-group: 13;\n -ms-flex-order: 12;\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -webkit-box-flex: 1;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-sm-auto {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-sm-1 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n -webkit-box-ordinal-group: 0;\n -ms-flex-order: -1;\n order: -1;\n }\n .order-sm-last {\n -webkit-box-ordinal-group: 14;\n -ms-flex-order: 13;\n order: 13;\n }\n .order-sm-0 {\n -webkit-box-ordinal-group: 1;\n -ms-flex-order: 0;\n order: 0;\n }\n .order-sm-1 {\n -webkit-box-ordinal-group: 2;\n -ms-flex-order: 1;\n order: 1;\n }\n .order-sm-2 {\n -webkit-box-ordinal-group: 3;\n -ms-flex-order: 2;\n order: 2;\n }\n .order-sm-3 {\n -webkit-box-ordinal-group: 4;\n -ms-flex-order: 3;\n order: 3;\n }\n .order-sm-4 {\n -webkit-box-ordinal-group: 5;\n -ms-flex-order: 4;\n order: 4;\n }\n .order-sm-5 {\n -webkit-box-ordinal-group: 6;\n -ms-flex-order: 5;\n order: 5;\n }\n .order-sm-6 {\n -webkit-box-ordinal-group: 7;\n -ms-flex-order: 6;\n order: 6;\n }\n .order-sm-7 {\n -webkit-box-ordinal-group: 8;\n -ms-flex-order: 7;\n order: 7;\n }\n .order-sm-8 {\n -webkit-box-ordinal-group: 9;\n -ms-flex-order: 8;\n order: 8;\n }\n .order-sm-9 {\n -webkit-box-ordinal-group: 10;\n -ms-flex-order: 9;\n order: 9;\n }\n .order-sm-10 {\n -webkit-box-ordinal-group: 11;\n -ms-flex-order: 10;\n order: 10;\n }\n .order-sm-11 {\n -webkit-box-ordinal-group: 12;\n -ms-flex-order: 11;\n order: 11;\n }\n .order-sm-12 {\n -webkit-box-ordinal-group: 13;\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -webkit-box-flex: 1;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-md-auto {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-md-1 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n -webkit-box-ordinal-group: 0;\n -ms-flex-order: -1;\n order: -1;\n }\n .order-md-last {\n -webkit-box-ordinal-group: 14;\n -ms-flex-order: 13;\n order: 13;\n }\n .order-md-0 {\n -webkit-box-ordinal-group: 1;\n -ms-flex-order: 0;\n order: 0;\n }\n .order-md-1 {\n -webkit-box-ordinal-group: 2;\n -ms-flex-order: 1;\n order: 1;\n }\n .order-md-2 {\n -webkit-box-ordinal-group: 3;\n -ms-flex-order: 2;\n order: 2;\n }\n .order-md-3 {\n -webkit-box-ordinal-group: 4;\n -ms-flex-order: 3;\n order: 3;\n }\n .order-md-4 {\n -webkit-box-ordinal-group: 5;\n -ms-flex-order: 4;\n order: 4;\n }\n .order-md-5 {\n -webkit-box-ordinal-group: 6;\n -ms-flex-order: 5;\n order: 5;\n }\n .order-md-6 {\n -webkit-box-ordinal-group: 7;\n -ms-flex-order: 6;\n order: 6;\n }\n .order-md-7 {\n -webkit-box-ordinal-group: 8;\n -ms-flex-order: 7;\n order: 7;\n }\n .order-md-8 {\n -webkit-box-ordinal-group: 9;\n -ms-flex-order: 8;\n order: 8;\n }\n .order-md-9 {\n -webkit-box-ordinal-group: 10;\n -ms-flex-order: 9;\n order: 9;\n }\n .order-md-10 {\n -webkit-box-ordinal-group: 11;\n -ms-flex-order: 10;\n order: 10;\n }\n .order-md-11 {\n -webkit-box-ordinal-group: 12;\n -ms-flex-order: 11;\n order: 11;\n }\n .order-md-12 {\n -webkit-box-ordinal-group: 13;\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -webkit-box-flex: 1;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-lg-auto {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-lg-1 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n -webkit-box-ordinal-group: 0;\n -ms-flex-order: -1;\n order: -1;\n }\n .order-lg-last {\n -webkit-box-ordinal-group: 14;\n -ms-flex-order: 13;\n order: 13;\n }\n .order-lg-0 {\n -webkit-box-ordinal-group: 1;\n -ms-flex-order: 0;\n order: 0;\n }\n .order-lg-1 {\n -webkit-box-ordinal-group: 2;\n -ms-flex-order: 1;\n order: 1;\n }\n .order-lg-2 {\n -webkit-box-ordinal-group: 3;\n -ms-flex-order: 2;\n order: 2;\n }\n .order-lg-3 {\n -webkit-box-ordinal-group: 4;\n -ms-flex-order: 3;\n order: 3;\n }\n .order-lg-4 {\n -webkit-box-ordinal-group: 5;\n -ms-flex-order: 4;\n order: 4;\n }\n .order-lg-5 {\n -webkit-box-ordinal-group: 6;\n -ms-flex-order: 5;\n order: 5;\n }\n .order-lg-6 {\n -webkit-box-ordinal-group: 7;\n -ms-flex-order: 6;\n order: 6;\n }\n .order-lg-7 {\n -webkit-box-ordinal-group: 8;\n -ms-flex-order: 7;\n order: 7;\n }\n .order-lg-8 {\n -webkit-box-ordinal-group: 9;\n -ms-flex-order: 8;\n order: 8;\n }\n .order-lg-9 {\n -webkit-box-ordinal-group: 10;\n -ms-flex-order: 9;\n order: 9;\n }\n .order-lg-10 {\n -webkit-box-ordinal-group: 11;\n -ms-flex-order: 10;\n order: 10;\n }\n .order-lg-11 {\n -webkit-box-ordinal-group: 12;\n -ms-flex-order: 11;\n order: 11;\n }\n .order-lg-12 {\n -webkit-box-ordinal-group: 13;\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -webkit-box-flex: 1;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-xl-auto {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-xl-1 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n -webkit-box-ordinal-group: 0;\n -ms-flex-order: -1;\n order: -1;\n }\n .order-xl-last {\n -webkit-box-ordinal-group: 14;\n -ms-flex-order: 13;\n order: 13;\n }\n .order-xl-0 {\n -webkit-box-ordinal-group: 1;\n -ms-flex-order: 0;\n order: 0;\n }\n .order-xl-1 {\n -webkit-box-ordinal-group: 2;\n -ms-flex-order: 1;\n order: 1;\n }\n .order-xl-2 {\n -webkit-box-ordinal-group: 3;\n -ms-flex-order: 2;\n order: 2;\n }\n .order-xl-3 {\n -webkit-box-ordinal-group: 4;\n -ms-flex-order: 3;\n order: 3;\n }\n .order-xl-4 {\n -webkit-box-ordinal-group: 5;\n -ms-flex-order: 4;\n order: 4;\n }\n .order-xl-5 {\n -webkit-box-ordinal-group: 6;\n -ms-flex-order: 5;\n order: 5;\n }\n .order-xl-6 {\n -webkit-box-ordinal-group: 7;\n -ms-flex-order: 6;\n order: 6;\n }\n .order-xl-7 {\n -webkit-box-ordinal-group: 8;\n -ms-flex-order: 7;\n order: 7;\n }\n .order-xl-8 {\n -webkit-box-ordinal-group: 9;\n -ms-flex-order: 8;\n order: 8;\n }\n .order-xl-9 {\n -webkit-box-ordinal-group: 10;\n -ms-flex-order: 9;\n order: 9;\n }\n .order-xl-10 {\n -webkit-box-ordinal-group: 11;\n -ms-flex-order: 10;\n order: 10;\n }\n .order-xl-11 {\n -webkit-box-ordinal-group: 12;\n -ms-flex-order: 11;\n order: 11;\n }\n .order-xl-12 {\n -webkit-box-ordinal-group: 13;\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 1rem;\n background-color: transparent;\n}\n\n.table th,\n.table td {\n padding: 0.75rem;\n vertical-align: top;\n border-top: 1px solid #dee2e6;\n}\n\n.table thead th {\n vertical-align: bottom;\n border-bottom: 2px solid #dee2e6;\n}\n\n.table tbody + tbody {\n border-top: 2px solid #dee2e6;\n}\n\n.table .table {\n background-color: #fff;\n}\n\n.table-sm th,\n.table-sm td {\n padding: 0.3rem;\n}\n\n.table-bordered {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered th,\n.table-bordered td {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered thead th,\n.table-bordered thead td {\n border-bottom-width: 2px;\n}\n\n.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.table-hover tbody tr:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-primary,\n.table-primary > th,\n.table-primary > td {\n background-color: #b8daff;\n}\n\n.table-hover .table-primary:hover {\n background-color: #9fcdff;\n}\n\n.table-hover .table-primary:hover > td,\n.table-hover .table-primary:hover > th {\n background-color: #9fcdff;\n}\n\n.table-secondary,\n.table-secondary > th,\n.table-secondary > td {\n background-color: #d6d8db;\n}\n\n.table-hover .table-secondary:hover {\n background-color: #c8cbcf;\n}\n\n.table-hover .table-secondary:hover > td,\n.table-hover .table-secondary:hover > th {\n background-color: #c8cbcf;\n}\n\n.table-success,\n.table-success > th,\n.table-success > td {\n background-color: #c3e6cb;\n}\n\n.table-hover .table-success:hover {\n background-color: #b1dfbb;\n}\n\n.table-hover .table-success:hover > td,\n.table-hover .table-success:hover > th {\n background-color: #b1dfbb;\n}\n\n.table-info,\n.table-info > th,\n.table-info > td {\n background-color: #bee5eb;\n}\n\n.table-hover .table-info:hover {\n background-color: #abdde5;\n}\n\n.table-hover .table-info:hover > td,\n.table-hover .table-info:hover > th {\n background-color: #abdde5;\n}\n\n.table-warning,\n.table-warning > th,\n.table-warning > td {\n background-color: #ffeeba;\n}\n\n.table-hover .table-warning:hover {\n background-color: #ffe8a1;\n}\n\n.table-hover .table-warning:hover > td,\n.table-hover .table-warning:hover > th {\n background-color: #ffe8a1;\n}\n\n.table-danger,\n.table-danger > th,\n.table-danger > td {\n background-color: #f5c6cb;\n}\n\n.table-hover .table-danger:hover {\n background-color: #f1b0b7;\n}\n\n.table-hover .table-danger:hover > td,\n.table-hover .table-danger:hover > th {\n background-color: #f1b0b7;\n}\n\n.table-light,\n.table-light > th,\n.table-light > td {\n background-color: #fdfdfe;\n}\n\n.table-hover .table-light:hover {\n background-color: #ececf6;\n}\n\n.table-hover .table-light:hover > td,\n.table-hover .table-light:hover > th {\n background-color: #ececf6;\n}\n\n.table-dark,\n.table-dark > th,\n.table-dark > td {\n background-color: #c6c8ca;\n}\n\n.table-hover .table-dark:hover {\n background-color: #b9bbbe;\n}\n\n.table-hover .table-dark:hover > td,\n.table-hover .table-dark:hover > th {\n background-color: #b9bbbe;\n}\n\n.table-active,\n.table-active > th,\n.table-active > td {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover > td,\n.table-hover .table-active:hover > th {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table .thead-dark th {\n color: #fff;\n background-color: #212529;\n border-color: #32383e;\n}\n\n.table .thead-light th {\n color: #495057;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.table-dark {\n color: #fff;\n background-color: #212529;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th {\n border-color: #32383e;\n}\n\n.table-dark.table-bordered {\n border: 0;\n}\n\n.table-dark.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(255, 255, 255, 0.05);\n}\n\n.table-dark.table-hover tbody tr:hover {\n background-color: rgba(255, 255, 255, 0.075);\n}\n\n@media (max-width: 575.98px) {\n .table-responsive-sm {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-sm > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 767.98px) {\n .table-responsive-md {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-md > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 991.98px) {\n .table-responsive-lg {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-lg > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 1199.98px) {\n .table-responsive-xl {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-xl > .table-bordered {\n border: 0;\n }\n}\n\n.table-responsive {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n}\n\n.table-responsive > .table-bordered {\n border: 0;\n}\n\n.form-control {\n display: block;\n width: 100%;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n\n.form-control:focus {\n color: #495057;\n background-color: #fff;\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.form-control::-webkit-input-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control::-moz-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:-ms-input-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control::-ms-input-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control::placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:disabled, .form-control[readonly] {\n background-color: #e9ecef;\n opacity: 1;\n}\n\nselect.form-control:not([size]):not([multiple]) {\n height: calc(2.25rem + 2px);\n}\n\nselect.form-control:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n.col-form-label {\n padding-top: calc(0.375rem + 1px);\n padding-bottom: calc(0.375rem + 1px);\n margin-bottom: 0;\n font-size: inherit;\n line-height: 1.5;\n}\n\n.col-form-label-lg {\n padding-top: calc(0.5rem + 1px);\n padding-bottom: calc(0.5rem + 1px);\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.col-form-label-sm {\n padding-top: calc(0.25rem + 1px);\n padding-bottom: calc(0.25rem + 1px);\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n margin-bottom: 0;\n line-height: 1.5;\n background-color: transparent;\n border: solid transparent;\n border-width: 1px 0;\n}\n\n.form-control-plaintext.form-control-sm, .input-group-sm > .form-control-plaintext.form-control,\n.input-group-sm > .input-group-prepend > .form-control-plaintext.input-group-text,\n.input-group-sm > .input-group-append > .form-control-plaintext.input-group-text,\n.input-group-sm > .input-group-prepend > .form-control-plaintext.btn,\n.input-group-sm > .input-group-append > .form-control-plaintext.btn, .form-control-plaintext.form-control-lg, .input-group-lg > .form-control-plaintext.form-control,\n.input-group-lg > .input-group-prepend > .form-control-plaintext.input-group-text,\n.input-group-lg > .input-group-append > .form-control-plaintext.input-group-text,\n.input-group-lg > .input-group-prepend > .form-control-plaintext.btn,\n.input-group-lg > .input-group-append > .form-control-plaintext.btn {\n padding-right: 0;\n padding-left: 0;\n}\n\n.form-control-sm, .input-group-sm > .form-control,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\nselect.form-control-sm:not([size]):not([multiple]), .input-group-sm > select.form-control:not([size]):not([multiple]),\n.input-group-sm > .input-group-prepend > select.input-group-text:not([size]):not([multiple]),\n.input-group-sm > .input-group-append > select.input-group-text:not([size]):not([multiple]),\n.input-group-sm > .input-group-prepend > select.btn:not([size]):not([multiple]),\n.input-group-sm > .input-group-append > select.btn:not([size]):not([multiple]) {\n height: calc(1.8125rem + 2px);\n}\n\n.form-control-lg, .input-group-lg > .form-control,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\nselect.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.form-control:not([size]):not([multiple]),\n.input-group-lg > .input-group-prepend > select.input-group-text:not([size]):not([multiple]),\n.input-group-lg > .input-group-append > select.input-group-text:not([size]):not([multiple]),\n.input-group-lg > .input-group-prepend > select.btn:not([size]):not([multiple]),\n.input-group-lg > .input-group-append > select.btn:not([size]):not([multiple]) {\n height: calc(2.875rem + 2px);\n}\n\n.form-group {\n margin-bottom: 1rem;\n}\n\n.form-text {\n display: block;\n margin-top: 0.25rem;\n}\n\n.form-row {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -5px;\n margin-left: -5px;\n}\n\n.form-row > .col,\n.form-row > [class*=\"col-\"] {\n padding-right: 5px;\n padding-left: 5px;\n}\n\n.form-check {\n position: relative;\n display: block;\n padding-left: 1.25rem;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: 0.3rem;\n margin-left: -1.25rem;\n}\n\n.form-check-input:disabled ~ .form-check-label {\n color: #6c757d;\n}\n\n.form-check-label {\n margin-bottom: 0;\n}\n\n.form-check-inline {\n display: -webkit-inline-box;\n display: -ms-inline-flexbox;\n display: inline-flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n padding-left: 0;\n margin-right: 0.75rem;\n}\n\n.form-check-inline .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: 0.3125rem;\n margin-left: 0;\n}\n\n.valid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #28a745;\n}\n\n.valid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: .5rem;\n margin-top: .1rem;\n font-size: .875rem;\n line-height: 1;\n color: #fff;\n background-color: rgba(40, 167, 69, 0.8);\n border-radius: .2rem;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid, .was-validated\n.custom-select:valid,\n.custom-select.is-valid {\n border-color: #28a745;\n}\n\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus, .was-validated\n.custom-select:valid:focus,\n.custom-select.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .form-control:valid ~ .valid-feedback,\n.was-validated .form-control:valid ~ .valid-tooltip, .form-control.is-valid ~ .valid-feedback,\n.form-control.is-valid ~ .valid-tooltip, .was-validated\n.custom-select:valid ~ .valid-feedback,\n.was-validated\n.custom-select:valid ~ .valid-tooltip,\n.custom-select.is-valid ~ .valid-feedback,\n.custom-select.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n color: #28a745;\n}\n\n.was-validated .form-check-input:valid ~ .valid-feedback,\n.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback,\n.form-check-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label {\n color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before {\n background-color: #71dd8a;\n}\n\n.was-validated .custom-control-input:valid ~ .valid-feedback,\n.was-validated .custom-control-input:valid ~ .valid-tooltip, .custom-control-input.is-valid ~ .valid-feedback,\n.custom-control-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before {\n background-color: #34ce57;\n}\n\n.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label::before, .custom-file-input.is-valid ~ .custom-file-label::before {\n border-color: inherit;\n}\n\n.was-validated .custom-file-input:valid ~ .valid-feedback,\n.was-validated .custom-file-input:valid ~ .valid-tooltip, .custom-file-input.is-valid ~ .valid-feedback,\n.custom-file-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.invalid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #dc3545;\n}\n\n.invalid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: .5rem;\n margin-top: .1rem;\n font-size: .875rem;\n line-height: 1;\n color: #fff;\n background-color: rgba(220, 53, 69, 0.8);\n border-radius: .2rem;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid, .was-validated\n.custom-select:invalid,\n.custom-select.is-invalid {\n border-color: #dc3545;\n}\n\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus, .was-validated\n.custom-select:invalid:focus,\n.custom-select.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-control:invalid ~ .invalid-feedback,\n.was-validated .form-control:invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback,\n.form-control.is-invalid ~ .invalid-tooltip, .was-validated\n.custom-select:invalid ~ .invalid-feedback,\n.was-validated\n.custom-select:invalid ~ .invalid-tooltip,\n.custom-select.is-invalid ~ .invalid-feedback,\n.custom-select.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n color: #dc3545;\n}\n\n.was-validated .form-check-input:invalid ~ .invalid-feedback,\n.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback,\n.form-check-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label {\n color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before {\n background-color: #efa2a9;\n}\n\n.was-validated .custom-control-input:invalid ~ .invalid-feedback,\n.was-validated .custom-control-input:invalid ~ .invalid-tooltip, .custom-control-input.is-invalid ~ .invalid-feedback,\n.custom-control-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before {\n background-color: #e4606d;\n}\n\n.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label::before, .custom-file-input.is-invalid ~ .custom-file-label::before {\n border-color: inherit;\n}\n\n.was-validated .custom-file-input:invalid ~ .invalid-feedback,\n.was-validated .custom-file-input:invalid ~ .invalid-tooltip, .custom-file-input.is-invalid ~ .invalid-feedback,\n.custom-file-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.form-inline {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.form-inline .form-check {\n width: 100%;\n}\n\n@media (min-width: 576px) {\n .form-inline label {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n margin-bottom: 0;\n }\n .form-inline .form-group {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-flex: 0;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n margin-bottom: 0;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-plaintext {\n display: inline-block;\n }\n .form-inline .input-group {\n width: auto;\n }\n .form-inline .form-check {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-inline .form-check-input {\n position: relative;\n margin-top: 0;\n margin-right: 0.25rem;\n margin-left: 0;\n }\n .form-inline .custom-control {\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n }\n .form-inline .custom-control-label {\n margin-bottom: 0;\n }\n}\n\n.btn {\n display: inline-block;\n font-weight: 400;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n border: 1px solid transparent;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.btn:hover, .btn:focus {\n text-decoration: none;\n}\n\n.btn:focus, .btn.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.btn.disabled, .btn:disabled {\n opacity: 0.65;\n}\n\n.btn:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.btn:not(:disabled):not(.disabled):active, .btn:not(:disabled):not(.disabled).active {\n background-image: none;\n}\n\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n.btn-primary {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:hover {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n}\n\n.btn-primary:focus, .btn-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-primary.disabled, .btn-primary:disabled {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active,\n.show > .btn-primary.dropdown-toggle {\n color: #fff;\n background-color: #0062cc;\n border-color: #005cbf;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-secondary {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:hover {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n}\n\n.btn-secondary:focus, .btn-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-secondary.disabled, .btn-secondary:disabled {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-secondary.dropdown-toggle {\n color: #fff;\n background-color: #545b62;\n border-color: #4e555b;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-success {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:hover {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n}\n\n.btn-success:focus, .btn-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-success.disabled, .btn-success:disabled {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active,\n.show > .btn-success.dropdown-toggle {\n color: #fff;\n background-color: #1e7e34;\n border-color: #1c7430;\n}\n\n.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-info {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:hover {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n}\n\n.btn-info:focus, .btn-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-info.disabled, .btn-info:disabled {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active,\n.show > .btn-info.dropdown-toggle {\n color: #fff;\n background-color: #117a8b;\n border-color: #10707f;\n}\n\n.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-warning {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:hover {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n}\n\n.btn-warning:focus, .btn-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-warning.disabled, .btn-warning:disabled {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active,\n.show > .btn-warning.dropdown-toggle {\n color: #212529;\n background-color: #d39e00;\n border-color: #c69500;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-danger {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:hover {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n}\n\n.btn-danger:focus, .btn-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-danger.disabled, .btn-danger:disabled {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active,\n.show > .btn-danger.dropdown-toggle {\n color: #fff;\n background-color: #bd2130;\n border-color: #b21f2d;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-light {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:hover {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n}\n\n.btn-light:focus, .btn-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-light.disabled, .btn-light:disabled {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active,\n.show > .btn-light.dropdown-toggle {\n color: #212529;\n background-color: #dae0e5;\n border-color: #d3d9df;\n}\n\n.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-dark {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:hover {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n}\n\n.btn-dark:focus, .btn-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-dark.disabled, .btn-dark:disabled {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active,\n.show > .btn-dark.dropdown-toggle {\n color: #fff;\n background-color: #1d2124;\n border-color: #171a1d;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-primary {\n color: #007bff;\n background-color: transparent;\n background-image: none;\n border-color: #007bff;\n}\n\n.btn-outline-primary:hover {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:focus, .btn-outline-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-primary.disabled, .btn-outline-primary:disabled {\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-primary.dropdown-toggle {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-secondary {\n color: #6c757d;\n background-color: transparent;\n background-image: none;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:hover {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:focus, .btn-outline-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-secondary.disabled, .btn-outline-secondary:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-secondary.dropdown-toggle {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-success {\n color: #28a745;\n background-color: transparent;\n background-image: none;\n border-color: #28a745;\n}\n\n.btn-outline-success:hover {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:focus, .btn-outline-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-success.disabled, .btn-outline-success:disabled {\n color: #28a745;\n background-color: transparent;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active,\n.show > .btn-outline-success.dropdown-toggle {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-info {\n color: #17a2b8;\n background-color: transparent;\n background-image: none;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:hover {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:focus, .btn-outline-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-info.disabled, .btn-outline-info:disabled {\n color: #17a2b8;\n background-color: transparent;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active,\n.show > .btn-outline-info.dropdown-toggle {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-warning {\n color: #ffc107;\n background-color: transparent;\n background-image: none;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:hover {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:focus, .btn-outline-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-warning.disabled, .btn-outline-warning:disabled {\n color: #ffc107;\n background-color: transparent;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active,\n.show > .btn-outline-warning.dropdown-toggle {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-danger {\n color: #dc3545;\n background-color: transparent;\n background-image: none;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:hover {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:focus, .btn-outline-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-danger.disabled, .btn-outline-danger:disabled {\n color: #dc3545;\n background-color: transparent;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active,\n.show > .btn-outline-danger.dropdown-toggle {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-light {\n color: #f8f9fa;\n background-color: transparent;\n background-image: none;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:hover {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:focus, .btn-outline-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-light.disabled, .btn-outline-light:disabled {\n color: #f8f9fa;\n background-color: transparent;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active,\n.show > .btn-outline-light.dropdown-toggle {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-dark {\n color: #343a40;\n background-color: transparent;\n background-image: none;\n border-color: #343a40;\n}\n\n.btn-outline-dark:hover {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:focus, .btn-outline-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-dark.disabled, .btn-outline-dark:disabled {\n color: #343a40;\n background-color: transparent;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active,\n.show > .btn-outline-dark.dropdown-toggle {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-link {\n font-weight: 400;\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-link:hover {\n color: #0056b3;\n text-decoration: underline;\n background-color: transparent;\n border-color: transparent;\n}\n\n.btn-link:focus, .btn-link.focus {\n text-decoration: underline;\n border-color: transparent;\n box-shadow: none;\n}\n\n.btn-link:disabled, .btn-link.disabled {\n color: #6c757d;\n}\n\n.btn-lg, .btn-group-lg > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n.btn-block + .btn-block {\n margin-top: 0.5rem;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n\n.fade {\n opacity: 0;\n transition: opacity 0.15s linear;\n}\n\n.fade.show {\n opacity: 1;\n}\n\n.collapse {\n display: none;\n}\n\n.collapse.show {\n display: block;\n}\n\ntr.collapse.show {\n display: table-row;\n}\n\ntbody.collapse.show {\n display: table-row-group;\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n transition: height 0.35s ease;\n}\n\n.dropup,\n.dropdown {\n position: relative;\n}\n\n.dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n}\n\n.dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 10rem;\n padding: 0.5rem 0;\n margin: 0.125rem 0 0;\n font-size: 1rem;\n color: #212529;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 0.25rem;\n}\n\n.dropup .dropdown-menu {\n margin-top: 0;\n margin-bottom: 0.125rem;\n}\n\n.dropup .dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0;\n border-right: 0.3em solid transparent;\n border-bottom: 0.3em solid;\n border-left: 0.3em solid transparent;\n}\n\n.dropup .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-menu {\n margin-top: 0;\n margin-left: 0.125rem;\n}\n\n.dropright .dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-bottom: 0.3em solid transparent;\n border-left: 0.3em solid;\n}\n\n.dropright .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-toggle::after {\n vertical-align: 0;\n}\n\n.dropleft .dropdown-menu {\n margin-top: 0;\n margin-right: 0.125rem;\n}\n\n.dropleft .dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n}\n\n.dropleft .dropdown-toggle::after {\n display: none;\n}\n\n.dropleft .dropdown-toggle::before {\n display: inline-block;\n width: 0;\n height: 0;\n margin-right: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0.3em solid;\n border-bottom: 0.3em solid transparent;\n}\n\n.dropleft .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle::before {\n vertical-align: 0;\n}\n\n.dropdown-divider {\n height: 0;\n margin: 0.5rem 0;\n overflow: hidden;\n border-top: 1px solid #e9ecef;\n}\n\n.dropdown-item {\n display: block;\n width: 100%;\n padding: 0.25rem 1.5rem;\n clear: both;\n font-weight: 400;\n color: #212529;\n text-align: inherit;\n white-space: nowrap;\n background-color: transparent;\n border: 0;\n}\n\n.dropdown-item:hover, .dropdown-item:focus {\n color: #16181b;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.dropdown-item.active, .dropdown-item:active {\n color: #fff;\n text-decoration: none;\n background-color: #007bff;\n}\n\n.dropdown-item.disabled, .dropdown-item:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n.dropdown-header {\n display: block;\n padding: 0.5rem 1.5rem;\n margin-bottom: 0;\n font-size: 0.875rem;\n color: #6c757d;\n white-space: nowrap;\n}\n\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: -webkit-inline-box;\n display: -ms-inline-flexbox;\n display: inline-flex;\n vertical-align: middle;\n}\n\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n -webkit-box-flex: 0;\n -ms-flex: 0 1 auto;\n flex: 0 1 auto;\n}\n\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover {\n z-index: 1;\n}\n\n.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n z-index: 1;\n}\n\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group,\n.btn-group-vertical .btn + .btn,\n.btn-group-vertical .btn + .btn-group,\n.btn-group-vertical .btn-group + .btn,\n.btn-group-vertical .btn-group + .btn-group {\n margin-left: -1px;\n}\n\n.btn-toolbar {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -webkit-box-pack: start;\n -ms-flex-pack: start;\n justify-content: flex-start;\n}\n\n.btn-toolbar .input-group {\n width: auto;\n}\n\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n padding-right: 0.5625rem;\n padding-left: 0.5625rem;\n}\n\n.dropdown-toggle-split::after {\n margin-left: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n padding-right: 0.375rem;\n padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n padding-right: 0.75rem;\n padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n -webkit-box-align: start;\n -ms-flex-align: start;\n align-items: flex-start;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n}\n\n.btn-group-vertical .btn,\n.btn-group-vertical .btn-group {\n width: 100%;\n}\n\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.btn-group-toggle > .btn,\n.btn-group-toggle > .btn-group > .btn {\n margin-bottom: 0;\n}\n\n.btn-group-toggle > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn input[type=\"checkbox\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n\n.input-group {\n position: relative;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -webkit-box-align: stretch;\n -ms-flex-align: stretch;\n align-items: stretch;\n width: 100%;\n}\n\n.input-group > .form-control,\n.input-group > .custom-select,\n.input-group > .custom-file {\n position: relative;\n -webkit-box-flex: 1;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n width: 1%;\n margin-bottom: 0;\n}\n\n.input-group > .form-control:focus,\n.input-group > .custom-select:focus,\n.input-group > .custom-file:focus {\n z-index: 3;\n}\n\n.input-group > .form-control + .form-control,\n.input-group > .form-control + .custom-select,\n.input-group > .form-control + .custom-file,\n.input-group > .custom-select + .form-control,\n.input-group > .custom-select + .custom-select,\n.input-group > .custom-select + .custom-file,\n.input-group > .custom-file + .form-control,\n.input-group > .custom-file + .custom-select,\n.input-group > .custom-file + .custom-file {\n margin-left: -1px;\n}\n\n.input-group > .form-control:not(:last-child),\n.input-group > .custom-select:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .form-control:not(:first-child),\n.input-group > .custom-select:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group > .custom-file {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.input-group > .custom-file:not(:last-child) .custom-file-label,\n.input-group > .custom-file:not(:last-child) .custom-file-label::before {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .custom-file:not(:first-child) .custom-file-label,\n.input-group > .custom-file:not(:first-child) .custom-file-label::before {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group-prepend,\n.input-group-append {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n}\n\n.input-group-prepend .btn,\n.input-group-append .btn {\n position: relative;\n z-index: 2;\n}\n\n.input-group-prepend .btn + .btn,\n.input-group-prepend .btn + .input-group-text,\n.input-group-prepend .input-group-text + .input-group-text,\n.input-group-prepend .input-group-text + .btn,\n.input-group-append .btn + .btn,\n.input-group-append .btn + .input-group-text,\n.input-group-append .input-group-text + .input-group-text,\n.input-group-append .input-group-text + .btn {\n margin-left: -1px;\n}\n\n.input-group-prepend {\n margin-right: -1px;\n}\n\n.input-group-append {\n margin-left: -1px;\n}\n\n.input-group-text {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n padding: 0.375rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n text-align: center;\n white-space: nowrap;\n background-color: #e9ecef;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.input-group-text input[type=\"radio\"],\n.input-group-text input[type=\"checkbox\"] {\n margin-top: 0;\n}\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group > .input-group-append:not(:last-child) > .btn,\n.input-group > .input-group-append:not(:last-child) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.custom-control {\n position: relative;\n display: block;\n min-height: 1.5rem;\n padding-left: 1.5rem;\n}\n\n.custom-control-inline {\n display: -webkit-inline-box;\n display: -ms-inline-flexbox;\n display: inline-flex;\n margin-right: 1rem;\n}\n\n.custom-control-input {\n position: absolute;\n z-index: -1;\n opacity: 0;\n}\n\n.custom-control-input:checked ~ .custom-control-label::before {\n color: #fff;\n background-color: #007bff;\n}\n\n.custom-control-input:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-control-input:active ~ .custom-control-label::before {\n color: #fff;\n background-color: #b3d7ff;\n}\n\n.custom-control-input:disabled ~ .custom-control-label {\n color: #6c757d;\n}\n\n.custom-control-input:disabled ~ .custom-control-label::before {\n background-color: #e9ecef;\n}\n\n.custom-control-label {\n margin-bottom: 0;\n}\n\n.custom-control-label::before {\n position: absolute;\n top: 0.25rem;\n left: 0;\n display: block;\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n content: \"\";\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n background-color: #dee2e6;\n}\n\n.custom-control-label::after {\n position: absolute;\n top: 0.25rem;\n left: 0;\n display: block;\n width: 1rem;\n height: 1rem;\n content: \"\";\n background-repeat: no-repeat;\n background-position: center center;\n background-size: 50% 50%;\n}\n\n.custom-checkbox .custom-control-label::before {\n border-radius: 0.25rem;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before {\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E\");\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before {\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E\");\n}\n\n.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-radio .custom-control-label::before {\n border-radius: 50%;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::before {\n background-color: #007bff;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E\");\n}\n\n.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: calc(2.25rem + 2px);\n padding: 0.375rem 1.75rem 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n vertical-align: middle;\n background: #fff url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E\") no-repeat right 0.75rem center;\n background-size: 8px 10px;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\n.custom-select:focus {\n border-color: #80bdff;\n outline: 0;\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075), 0 0 5px rgba(128, 189, 255, 0.5);\n}\n\n.custom-select:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.custom-select[multiple], .custom-select[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: 0.75rem;\n background-image: none;\n}\n\n.custom-select:disabled {\n color: #6c757d;\n background-color: #e9ecef;\n}\n\n.custom-select::-ms-expand {\n opacity: 0;\n}\n\n.custom-select-sm {\n height: calc(1.8125rem + 2px);\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n font-size: 75%;\n}\n\n.custom-select-lg {\n height: calc(2.875rem + 2px);\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n font-size: 125%;\n}\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: calc(2.25rem + 2px);\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: calc(2.25rem + 2px);\n margin: 0;\n opacity: 0;\n}\n\n.custom-file-input:focus ~ .custom-file-control {\n border-color: #80bdff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-file-input:focus ~ .custom-file-control::before {\n border-color: #80bdff;\n}\n\n.custom-file-input:lang(en) ~ .custom-file-label::after {\n content: \"Browse\";\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: calc(2.25rem + 2px);\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.custom-file-label::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: calc(calc(2.25rem + 2px) - 1px * 2);\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n content: \"Browse\";\n background-color: #e9ecef;\n border-left: 1px solid #ced4da;\n border-radius: 0 0.25rem 0.25rem 0;\n}\n\n.nav {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: 0.5rem 1rem;\n}\n\n.nav-link:hover, .nav-link:focus {\n text-decoration: none;\n}\n\n.nav-link.disabled {\n color: #6c757d;\n}\n\n.nav-tabs {\n border-bottom: 1px solid #dee2e6;\n}\n\n.nav-tabs .nav-item {\n margin-bottom: -1px;\n}\n\n.nav-tabs .nav-link {\n border: 1px solid transparent;\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n border-color: #e9ecef #e9ecef #dee2e6;\n}\n\n.nav-tabs .nav-link.disabled {\n color: #6c757d;\n background-color: transparent;\n border-color: transparent;\n}\n\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n color: #495057;\n background-color: #fff;\n border-color: #dee2e6 #dee2e6 #fff;\n}\n\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.nav-pills .nav-link {\n border-radius: 0.25rem;\n}\n\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n color: #fff;\n background-color: #007bff;\n}\n\n.nav-fill .nav-item {\n -webkit-box-flex: 1;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n text-align: center;\n}\n\n.nav-justified .nav-item {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -webkit-box-flex: 1;\n -ms-flex-positive: 1;\n flex-grow: 1;\n text-align: center;\n}\n\n.tab-content > .tab-pane {\n display: none;\n}\n\n.tab-content > .active {\n display: block;\n}\n\n.navbar {\n position: relative;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: justify;\n -ms-flex-pack: justify;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n}\n\n.navbar > .container,\n.navbar > .container-fluid {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: justify;\n -ms-flex-pack: justify;\n justify-content: space-between;\n}\n\n.navbar-brand {\n display: inline-block;\n padding-top: 0.3125rem;\n padding-bottom: 0.3125rem;\n margin-right: 1rem;\n font-size: 1.25rem;\n line-height: inherit;\n white-space: nowrap;\n}\n\n.navbar-brand:hover, .navbar-brand:focus {\n text-decoration: none;\n}\n\n.navbar-nav {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.navbar-nav .nav-link {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-nav .dropdown-menu {\n position: static;\n float: none;\n}\n\n.navbar-text {\n display: inline-block;\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n\n.navbar-collapse {\n -ms-flex-preferred-size: 100%;\n flex-basis: 100%;\n -webkit-box-flex: 1;\n -ms-flex-positive: 1;\n flex-grow: 1;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.navbar-toggler {\n padding: 0.25rem 0.75rem;\n font-size: 1.25rem;\n line-height: 1;\n background-color: transparent;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.navbar-toggler:hover, .navbar-toggler:focus {\n text-decoration: none;\n}\n\n.navbar-toggler:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: no-repeat center center;\n background-size: 100% 100%;\n}\n\n@media (max-width: 575.98px) {\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 576px) {\n .navbar-expand-sm {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -webkit-box-pack: start;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-sm .navbar-nav {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-sm .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-sm .navbar-collapse {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-sm .navbar-toggler {\n display: none;\n }\n .navbar-expand-sm .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n@media (max-width: 767.98px) {\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 768px) {\n .navbar-expand-md {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -webkit-box-pack: start;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-md .navbar-nav {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-md .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-md .navbar-collapse {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-md .navbar-toggler {\n display: none;\n }\n .navbar-expand-md .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n@media (max-width: 991.98px) {\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 992px) {\n .navbar-expand-lg {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -webkit-box-pack: start;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-lg .navbar-nav {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-lg .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-lg .navbar-collapse {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-lg .navbar-toggler {\n display: none;\n }\n .navbar-expand-lg .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n@media (max-width: 1199.98px) {\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .navbar-expand-xl {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -webkit-box-pack: start;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-xl .navbar-nav {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-xl .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-xl .navbar-collapse {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-xl .navbar-toggler {\n display: none;\n }\n .navbar-expand-xl .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n.navbar-expand {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -webkit-box-pack: start;\n -ms-flex-pack: start;\n justify-content: flex-start;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-expand .navbar-nav {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-direction: row;\n flex-direction: row;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu {\n position: absolute;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n}\n\n.navbar-expand .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n}\n\n.navbar-expand .navbar-collapse {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n}\n\n.navbar-expand .navbar-toggler {\n display: none;\n}\n\n.navbar-expand .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n}\n\n.navbar-light .navbar-brand {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-nav .nav-link {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus {\n color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar-light .navbar-nav .nav-link.disabled {\n color: rgba(0, 0, 0, 0.3);\n}\n\n.navbar-light .navbar-nav .show > .nav-link,\n.navbar-light .navbar-nav .active > .nav-link,\n.navbar-light .navbar-nav .nav-link.show,\n.navbar-light .navbar-nav .nav-link.active {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-toggler {\n color: rgba(0, 0, 0, 0.5);\n border-color: rgba(0, 0, 0, 0.1);\n}\n\n.navbar-light .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\");\n}\n\n.navbar-light .navbar-text {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-text a {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-dark .navbar-brand {\n color: #fff;\n}\n\n.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus {\n color: #fff;\n}\n\n.navbar-dark .navbar-nav .nav-link {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus {\n color: rgba(255, 255, 255, 0.75);\n}\n\n.navbar-dark .navbar-nav .nav-link.disabled {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.navbar-dark .navbar-nav .show > .nav-link,\n.navbar-dark .navbar-nav .active > .nav-link,\n.navbar-dark .navbar-nav .nav-link.show,\n.navbar-dark .navbar-nav .nav-link.active {\n color: #fff;\n}\n\n.navbar-dark .navbar-toggler {\n color: rgba(255, 255, 255, 0.5);\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.navbar-dark .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\");\n}\n\n.navbar-dark .navbar-text {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-text a {\n color: #fff;\n}\n\n.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus {\n color: #fff;\n}\n\n.card {\n position: relative;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n min-width: 0;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: border-box;\n border: 1px solid rgba(0, 0, 0, 0.125);\n border-radius: 0.25rem;\n}\n\n.card > hr {\n margin-right: 0;\n margin-left: 0;\n}\n\n.card > .list-group:first-child .list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.card > .list-group:last-child .list-group-item:last-child {\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.card-body {\n -webkit-box-flex: 1;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n padding: 1.25rem;\n}\n\n.card-title {\n margin-bottom: 0.75rem;\n}\n\n.card-subtitle {\n margin-top: -0.375rem;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link:hover {\n text-decoration: none;\n}\n\n.card-link + .card-link {\n margin-left: 1.25rem;\n}\n\n.card-header {\n padding: 0.75rem 1.25rem;\n margin-bottom: 0;\n background-color: rgba(0, 0, 0, 0.03);\n border-bottom: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-header:first-child {\n border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;\n}\n\n.card-header + .list-group .list-group-item:first-child {\n border-top: 0;\n}\n\n.card-footer {\n padding: 0.75rem 1.25rem;\n background-color: rgba(0, 0, 0, 0.03);\n border-top: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-footer:last-child {\n border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);\n}\n\n.card-header-tabs {\n margin-right: -0.625rem;\n margin-bottom: -0.75rem;\n margin-left: -0.625rem;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -0.625rem;\n margin-left: -0.625rem;\n}\n\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: 1.25rem;\n}\n\n.card-img {\n width: 100%;\n border-radius: calc(0.25rem - 1px);\n}\n\n.card-img-top {\n width: 100%;\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card-img-bottom {\n width: 100%;\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card-deck {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n}\n\n.card-deck .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-deck {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n margin-right: -15px;\n margin-left: -15px;\n }\n .card-deck .card {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-flex: 1;\n -ms-flex: 1 0 0%;\n flex: 1 0 0%;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n margin-right: 15px;\n margin-bottom: 0;\n margin-left: 15px;\n }\n}\n\n.card-group {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n}\n\n.card-group > .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-group {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n }\n .card-group > .card {\n -webkit-box-flex: 1;\n -ms-flex: 1 0 0%;\n flex: 1 0 0%;\n margin-bottom: 0;\n }\n .card-group > .card + .card {\n margin-left: 0;\n border-left: 0;\n }\n .card-group > .card:first-child {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n .card-group > .card:first-child .card-img-top,\n .card-group > .card:first-child .card-header {\n border-top-right-radius: 0;\n }\n .card-group > .card:first-child .card-img-bottom,\n .card-group > .card:first-child .card-footer {\n border-bottom-right-radius: 0;\n }\n .card-group > .card:last-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .card-group > .card:last-child .card-img-top,\n .card-group > .card:last-child .card-header {\n border-top-left-radius: 0;\n }\n .card-group > .card:last-child .card-img-bottom,\n .card-group > .card:last-child .card-footer {\n border-bottom-left-radius: 0;\n }\n .card-group > .card:only-child {\n border-radius: 0.25rem;\n }\n .card-group > .card:only-child .card-img-top,\n .card-group > .card:only-child .card-header {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n }\n .card-group > .card:only-child .card-img-bottom,\n .card-group > .card:only-child .card-footer {\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) {\n border-radius: 0;\n }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-top,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-header,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-footer {\n border-radius: 0;\n }\n}\n\n.card-columns .card {\n margin-bottom: 0.75rem;\n}\n\n@media (min-width: 576px) {\n .card-columns {\n -webkit-column-count: 3;\n -moz-column-count: 3;\n column-count: 3;\n -webkit-column-gap: 1.25rem;\n -moz-column-gap: 1.25rem;\n column-gap: 1.25rem;\n }\n .card-columns .card {\n display: inline-block;\n width: 100%;\n }\n}\n\n.breadcrumb {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n padding: 0.75rem 1rem;\n margin-bottom: 1rem;\n list-style: none;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.breadcrumb-item + .breadcrumb-item::before {\n display: inline-block;\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n color: #6c757d;\n content: \"/\";\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: underline;\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: none;\n}\n\n.breadcrumb-item.active {\n color: #6c757d;\n}\n\n.pagination {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n padding-left: 0;\n list-style: none;\n border-radius: 0.25rem;\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: 0.5rem 0.75rem;\n margin-left: -1px;\n line-height: 1.25;\n color: #007bff;\n background-color: #fff;\n border: 1px solid #dee2e6;\n}\n\n.page-link:hover {\n color: #0056b3;\n text-decoration: none;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.page-link:focus {\n z-index: 2;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.page-link:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.page-item:first-child .page-link {\n margin-left: 0;\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.page-item:last-child .page-link {\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n}\n\n.page-item.active .page-link {\n z-index: 1;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.page-item.disabled .page-link {\n color: #6c757d;\n pointer-events: none;\n cursor: auto;\n background-color: #fff;\n border-color: #dee2e6;\n}\n\n.pagination-lg .page-link {\n padding: 0.75rem 1.5rem;\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.pagination-lg .page-item:first-child .page-link {\n border-top-left-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.pagination-lg .page-item:last-child .page-link {\n border-top-right-radius: 0.3rem;\n border-bottom-right-radius: 0.3rem;\n}\n\n.pagination-sm .page-link {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.pagination-sm .page-item:first-child .page-link {\n border-top-left-radius: 0.2rem;\n border-bottom-left-radius: 0.2rem;\n}\n\n.pagination-sm .page-item:last-child .page-link {\n border-top-right-radius: 0.2rem;\n border-bottom-right-radius: 0.2rem;\n}\n\n.badge {\n display: inline-block;\n padding: 0.25em 0.4em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25rem;\n}\n\n.badge:empty {\n display: none;\n}\n\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n.badge-pill {\n padding-right: 0.6em;\n padding-left: 0.6em;\n border-radius: 10rem;\n}\n\n.badge-primary {\n color: #fff;\n background-color: #007bff;\n}\n\n.badge-primary[href]:hover, .badge-primary[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #0062cc;\n}\n\n.badge-secondary {\n color: #fff;\n background-color: #6c757d;\n}\n\n.badge-secondary[href]:hover, .badge-secondary[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #545b62;\n}\n\n.badge-success {\n color: #fff;\n background-color: #28a745;\n}\n\n.badge-success[href]:hover, .badge-success[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #1e7e34;\n}\n\n.badge-info {\n color: #fff;\n background-color: #17a2b8;\n}\n\n.badge-info[href]:hover, .badge-info[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #117a8b;\n}\n\n.badge-warning {\n color: #212529;\n background-color: #ffc107;\n}\n\n.badge-warning[href]:hover, .badge-warning[href]:focus {\n color: #212529;\n text-decoration: none;\n background-color: #d39e00;\n}\n\n.badge-danger {\n color: #fff;\n background-color: #dc3545;\n}\n\n.badge-danger[href]:hover, .badge-danger[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #bd2130;\n}\n\n.badge-light {\n color: #212529;\n background-color: #f8f9fa;\n}\n\n.badge-light[href]:hover, .badge-light[href]:focus {\n color: #212529;\n text-decoration: none;\n background-color: #dae0e5;\n}\n\n.badge-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.badge-dark[href]:hover, .badge-dark[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #1d2124;\n}\n\n.jumbotron {\n padding: 2rem 1rem;\n margin-bottom: 2rem;\n background-color: #e9ecef;\n border-radius: 0.3rem;\n}\n\n@media (min-width: 576px) {\n .jumbotron {\n padding: 4rem 2rem;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n border-radius: 0;\n}\n\n.alert {\n position: relative;\n padding: 0.75rem 1.25rem;\n margin-bottom: 1rem;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.alert-heading {\n color: inherit;\n}\n\n.alert-link {\n font-weight: 700;\n}\n\n.alert-dismissible {\n padding-right: 4rem;\n}\n\n.alert-dismissible .close {\n position: absolute;\n top: 0;\n right: 0;\n padding: 0.75rem 1.25rem;\n color: inherit;\n}\n\n.alert-primary {\n color: #004085;\n background-color: #cce5ff;\n border-color: #b8daff;\n}\n\n.alert-primary hr {\n border-top-color: #9fcdff;\n}\n\n.alert-primary .alert-link {\n color: #002752;\n}\n\n.alert-secondary {\n color: #383d41;\n background-color: #e2e3e5;\n border-color: #d6d8db;\n}\n\n.alert-secondary hr {\n border-top-color: #c8cbcf;\n}\n\n.alert-secondary .alert-link {\n color: #202326;\n}\n\n.alert-success {\n color: #155724;\n background-color: #d4edda;\n border-color: #c3e6cb;\n}\n\n.alert-success hr {\n border-top-color: #b1dfbb;\n}\n\n.alert-success .alert-link {\n color: #0b2e13;\n}\n\n.alert-info {\n color: #0c5460;\n background-color: #d1ecf1;\n border-color: #bee5eb;\n}\n\n.alert-info hr {\n border-top-color: #abdde5;\n}\n\n.alert-info .alert-link {\n color: #062c33;\n}\n\n.alert-warning {\n color: #856404;\n background-color: #fff3cd;\n border-color: #ffeeba;\n}\n\n.alert-warning hr {\n border-top-color: #ffe8a1;\n}\n\n.alert-warning .alert-link {\n color: #533f03;\n}\n\n.alert-danger {\n color: #721c24;\n background-color: #f8d7da;\n border-color: #f5c6cb;\n}\n\n.alert-danger hr {\n border-top-color: #f1b0b7;\n}\n\n.alert-danger .alert-link {\n color: #491217;\n}\n\n.alert-light {\n color: #818182;\n background-color: #fefefe;\n border-color: #fdfdfe;\n}\n\n.alert-light hr {\n border-top-color: #ececf6;\n}\n\n.alert-light .alert-link {\n color: #686868;\n}\n\n.alert-dark {\n color: #1b1e21;\n background-color: #d6d8d9;\n border-color: #c6c8ca;\n}\n\n.alert-dark hr {\n border-top-color: #b9bbbe;\n}\n\n.alert-dark .alert-link {\n color: #040505;\n}\n\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n@keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n.progress {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n height: 1rem;\n overflow: hidden;\n font-size: 0.75rem;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.progress-bar {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n color: #fff;\n text-align: center;\n background-color: #007bff;\n transition: width 0.6s ease;\n}\n\n.progress-bar-striped {\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 1rem 1rem;\n}\n\n.progress-bar-animated {\n -webkit-animation: progress-bar-stripes 1s linear infinite;\n animation: progress-bar-stripes 1s linear infinite;\n}\n\n.media {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: start;\n -ms-flex-align: start;\n align-items: flex-start;\n}\n\n.media-body {\n -webkit-box-flex: 1;\n -ms-flex: 1;\n flex: 1;\n}\n\n.list-group {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n}\n\n.list-group-item-action {\n width: 100%;\n color: #495057;\n text-align: inherit;\n}\n\n.list-group-item-action:hover, .list-group-item-action:focus {\n color: #495057;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.list-group-item-action:active {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 0.75rem 1.25rem;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.list-group-item:hover, .list-group-item:focus {\n z-index: 1;\n text-decoration: none;\n}\n\n.list-group-item.disabled, .list-group-item:disabled {\n color: #6c757d;\n background-color: #fff;\n}\n\n.list-group-item.active {\n z-index: 2;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.list-group-flush .list-group-item {\n border-right: 0;\n border-left: 0;\n border-radius: 0;\n}\n\n.list-group-flush:first-child .list-group-item:first-child {\n border-top: 0;\n}\n\n.list-group-flush:last-child .list-group-item:last-child {\n border-bottom: 0;\n}\n\n.list-group-item-primary {\n color: #004085;\n background-color: #b8daff;\n}\n\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n color: #004085;\n background-color: #9fcdff;\n}\n\n.list-group-item-primary.list-group-item-action.active {\n color: #fff;\n background-color: #004085;\n border-color: #004085;\n}\n\n.list-group-item-secondary {\n color: #383d41;\n background-color: #d6d8db;\n}\n\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n color: #383d41;\n background-color: #c8cbcf;\n}\n\n.list-group-item-secondary.list-group-item-action.active {\n color: #fff;\n background-color: #383d41;\n border-color: #383d41;\n}\n\n.list-group-item-success {\n color: #155724;\n background-color: #c3e6cb;\n}\n\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n color: #155724;\n background-color: #b1dfbb;\n}\n\n.list-group-item-success.list-group-item-action.active {\n color: #fff;\n background-color: #155724;\n border-color: #155724;\n}\n\n.list-group-item-info {\n color: #0c5460;\n background-color: #bee5eb;\n}\n\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n color: #0c5460;\n background-color: #abdde5;\n}\n\n.list-group-item-info.list-group-item-action.active {\n color: #fff;\n background-color: #0c5460;\n border-color: #0c5460;\n}\n\n.list-group-item-warning {\n color: #856404;\n background-color: #ffeeba;\n}\n\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n color: #856404;\n background-color: #ffe8a1;\n}\n\n.list-group-item-warning.list-group-item-action.active {\n color: #fff;\n background-color: #856404;\n border-color: #856404;\n}\n\n.list-group-item-danger {\n color: #721c24;\n background-color: #f5c6cb;\n}\n\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n color: #721c24;\n background-color: #f1b0b7;\n}\n\n.list-group-item-danger.list-group-item-action.active {\n color: #fff;\n background-color: #721c24;\n border-color: #721c24;\n}\n\n.list-group-item-light {\n color: #818182;\n background-color: #fdfdfe;\n}\n\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n color: #818182;\n background-color: #ececf6;\n}\n\n.list-group-item-light.list-group-item-action.active {\n color: #fff;\n background-color: #818182;\n border-color: #818182;\n}\n\n.list-group-item-dark {\n color: #1b1e21;\n background-color: #c6c8ca;\n}\n\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n color: #1b1e21;\n background-color: #b9bbbe;\n}\n\n.list-group-item-dark.list-group-item-action.active {\n color: #fff;\n background-color: #1b1e21;\n border-color: #1b1e21;\n}\n\n.close {\n float: right;\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: .5;\n}\n\n.close:hover, .close:focus {\n color: #000;\n text-decoration: none;\n opacity: .75;\n}\n\n.close:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n\n.modal-open {\n overflow: hidden;\n}\n\n.modal {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n display: none;\n overflow: hidden;\n outline: 0;\n}\n\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 0.5rem;\n pointer-events: none;\n}\n\n.modal.fade .modal-dialog {\n transition: -webkit-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out;\n -webkit-transform: translate(0, -25%);\n transform: translate(0, -25%);\n}\n\n.modal.show .modal-dialog {\n -webkit-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n\n.modal-dialog-centered {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n min-height: calc(100% - (0.5rem * 2));\n}\n\n.modal-content {\n position: relative;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n width: 100%;\n pointer-events: auto;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n outline: 0;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n\n.modal-backdrop.fade {\n opacity: 0;\n}\n\n.modal-backdrop.show {\n opacity: 0.5;\n}\n\n.modal-header {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: start;\n -ms-flex-align: start;\n align-items: flex-start;\n -webkit-box-pack: justify;\n -ms-flex-pack: justify;\n justify-content: space-between;\n padding: 1rem;\n border-bottom: 1px solid #e9ecef;\n border-top-left-radius: 0.3rem;\n border-top-right-radius: 0.3rem;\n}\n\n.modal-header .close {\n padding: 1rem;\n margin: -1rem -1rem -1rem auto;\n}\n\n.modal-title {\n margin-bottom: 0;\n line-height: 1.5;\n}\n\n.modal-body {\n position: relative;\n -webkit-box-flex: 1;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n padding: 1rem;\n}\n\n.modal-footer {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: end;\n -ms-flex-pack: end;\n justify-content: flex-end;\n padding: 1rem;\n border-top: 1px solid #e9ecef;\n}\n\n.modal-footer > :not(:first-child) {\n margin-left: .25rem;\n}\n\n.modal-footer > :not(:last-child) {\n margin-right: .25rem;\n}\n\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n@media (min-width: 576px) {\n .modal-dialog {\n max-width: 500px;\n margin: 1.75rem auto;\n }\n .modal-dialog-centered {\n min-height: calc(100% - (1.75rem * 2));\n }\n .modal-sm {\n max-width: 300px;\n }\n}\n\n@media (min-width: 992px) {\n .modal-lg {\n max-width: 800px;\n }\n}\n\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n opacity: 0;\n}\n\n.tooltip.show {\n opacity: 0.9;\n}\n\n.tooltip .arrow {\n position: absolute;\n display: block;\n width: 0.8rem;\n height: 0.4rem;\n}\n\n.tooltip .arrow::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-tooltip-top, .bs-tooltip-auto[x-placement^=\"top\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^=\"top\"] .arrow {\n bottom: 0;\n}\n\n.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^=\"top\"] .arrow::before {\n top: 0;\n border-width: 0.4rem 0.4rem 0;\n border-top-color: #000;\n}\n\n.bs-tooltip-right, .bs-tooltip-auto[x-placement^=\"right\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^=\"right\"] .arrow {\n left: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^=\"right\"] .arrow::before {\n right: 0;\n border-width: 0.4rem 0.4rem 0.4rem 0;\n border-right-color: #000;\n}\n\n.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^=\"bottom\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow {\n top: 0;\n}\n\n.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow::before {\n bottom: 0;\n border-width: 0 0.4rem 0.4rem;\n border-bottom-color: #000;\n}\n\n.bs-tooltip-left, .bs-tooltip-auto[x-placement^=\"left\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^=\"left\"] .arrow {\n right: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^=\"left\"] .arrow::before {\n left: 0;\n border-width: 0.4rem 0 0.4rem 0.4rem;\n border-left-color: #000;\n}\n\n.tooltip-inner {\n max-width: 200px;\n padding: 0.25rem 0.5rem;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 0.25rem;\n}\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: block;\n max-width: 276px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n}\n\n.popover .arrow {\n position: absolute;\n display: block;\n width: 1rem;\n height: 0.5rem;\n margin: 0 0.3rem;\n}\n\n.popover .arrow::before, .popover .arrow::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-popover-top, .bs-popover-auto[x-placement^=\"top\"] {\n margin-bottom: 0.5rem;\n}\n\n.bs-popover-top .arrow, .bs-popover-auto[x-placement^=\"top\"] .arrow {\n bottom: calc((0.5rem + 1px) * -1);\n}\n\n.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^=\"top\"] .arrow::before,\n.bs-popover-top .arrow::after, .bs-popover-auto[x-placement^=\"top\"] .arrow::after {\n border-width: 0.5rem 0.5rem 0;\n}\n\n.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^=\"top\"] .arrow::before {\n bottom: 0;\n border-top-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-top .arrow::after, .bs-popover-auto[x-placement^=\"top\"] .arrow::after {\n bottom: 1px;\n border-top-color: #fff;\n}\n\n.bs-popover-right, .bs-popover-auto[x-placement^=\"right\"] {\n margin-left: 0.5rem;\n}\n\n.bs-popover-right .arrow, .bs-popover-auto[x-placement^=\"right\"] .arrow {\n left: calc((0.5rem + 1px) * -1);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^=\"right\"] .arrow::before,\n.bs-popover-right .arrow::after, .bs-popover-auto[x-placement^=\"right\"] .arrow::after {\n border-width: 0.5rem 0.5rem 0.5rem 0;\n}\n\n.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^=\"right\"] .arrow::before {\n left: 0;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-right .arrow::after, .bs-popover-auto[x-placement^=\"right\"] .arrow::after {\n left: 1px;\n border-right-color: #fff;\n}\n\n.bs-popover-bottom, .bs-popover-auto[x-placement^=\"bottom\"] {\n margin-top: 0.5rem;\n}\n\n.bs-popover-bottom .arrow, .bs-popover-auto[x-placement^=\"bottom\"] .arrow {\n top: calc((0.5rem + 1px) * -1);\n}\n\n.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::before,\n.bs-popover-bottom .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::after {\n border-width: 0 0.5rem 0.5rem 0.5rem;\n}\n\n.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::before {\n top: 0;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-bottom .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::after {\n top: 1px;\n border-bottom-color: #fff;\n}\n\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^=\"bottom\"] .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: 1rem;\n margin-left: -0.5rem;\n content: \"\";\n border-bottom: 1px solid #f7f7f7;\n}\n\n.bs-popover-left, .bs-popover-auto[x-placement^=\"left\"] {\n margin-right: 0.5rem;\n}\n\n.bs-popover-left .arrow, .bs-popover-auto[x-placement^=\"left\"] .arrow {\n right: calc((0.5rem + 1px) * -1);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^=\"left\"] .arrow::before,\n.bs-popover-left .arrow::after, .bs-popover-auto[x-placement^=\"left\"] .arrow::after {\n border-width: 0.5rem 0 0.5rem 0.5rem;\n}\n\n.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^=\"left\"] .arrow::before {\n right: 0;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-left .arrow::after, .bs-popover-auto[x-placement^=\"left\"] .arrow::after {\n right: 1px;\n border-left-color: #fff;\n}\n\n.popover-header {\n padding: 0.5rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n color: inherit;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.popover-header:empty {\n display: none;\n}\n\n.popover-body {\n padding: 0.5rem 0.75rem;\n color: #212529;\n}\n\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n\n.carousel-item {\n position: relative;\n display: none;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n width: 100%;\n transition: -webkit-transform 0.6s ease;\n transition: transform 0.6s ease;\n transition: transform 0.6s ease, -webkit-transform 0.6s ease;\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n perspective: 1000px;\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next,\n.carousel-item-prev {\n position: absolute;\n top: 0;\n}\n\n.carousel-item-next.carousel-item-left,\n.carousel-item-prev.carousel-item-right {\n -webkit-transform: translateX(0);\n transform: translateX(0);\n}\n\n@supports ((-webkit-transform-style: preserve-3d) or (transform-style: preserve-3d)) {\n .carousel-item-next.carousel-item-left,\n .carousel-item-prev.carousel-item-right {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n }\n}\n\n.carousel-item-next,\n.active.carousel-item-right {\n -webkit-transform: translateX(100%);\n transform: translateX(100%);\n}\n\n@supports ((-webkit-transform-style: preserve-3d) or (transform-style: preserve-3d)) {\n .carousel-item-next,\n .active.carousel-item-right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n }\n}\n\n.carousel-item-prev,\n.active.carousel-item-left {\n -webkit-transform: translateX(-100%);\n transform: translateX(-100%);\n}\n\n@supports ((-webkit-transform-style: preserve-3d) or (transform-style: preserve-3d)) {\n .carousel-item-prev,\n .active.carousel-item-left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n width: 15%;\n color: #fff;\n text-align: center;\n opacity: 0.5;\n}\n\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n opacity: .9;\n}\n\n.carousel-control-prev {\n left: 0;\n}\n\n.carousel-control-next {\n right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n background: transparent no-repeat center center;\n background-size: 100% 100%;\n}\n\n.carousel-control-prev-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E\");\n}\n\n.carousel-control-next-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E\");\n}\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 10px;\n left: 0;\n z-index: 15;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n padding-left: 0;\n margin-right: 15%;\n margin-left: 15%;\n list-style: none;\n}\n\n.carousel-indicators li {\n position: relative;\n -webkit-box-flex: 0;\n -ms-flex: 0 1 auto;\n flex: 0 1 auto;\n width: 30px;\n height: 3px;\n margin-right: 3px;\n margin-left: 3px;\n text-indent: -999px;\n background-color: rgba(255, 255, 255, 0.5);\n}\n\n.carousel-indicators li::before {\n position: absolute;\n top: -10px;\n left: 0;\n display: inline-block;\n width: 100%;\n height: 10px;\n content: \"\";\n}\n\n.carousel-indicators li::after {\n position: absolute;\n bottom: -10px;\n left: 0;\n display: inline-block;\n width: 100%;\n height: 10px;\n content: \"\";\n}\n\n.carousel-indicators .active {\n background-color: #fff;\n}\n\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n}\n\n.align-baseline {\n vertical-align: baseline !important;\n}\n\n.align-top {\n vertical-align: top !important;\n}\n\n.align-middle {\n vertical-align: middle !important;\n}\n\n.align-bottom {\n vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n vertical-align: text-top !important;\n}\n\n.bg-primary {\n background-color: #007bff !important;\n}\n\na.bg-primary:hover, a.bg-primary:focus,\nbutton.bg-primary:hover,\nbutton.bg-primary:focus {\n background-color: #0062cc !important;\n}\n\n.bg-secondary {\n background-color: #6c757d !important;\n}\n\na.bg-secondary:hover, a.bg-secondary:focus,\nbutton.bg-secondary:hover,\nbutton.bg-secondary:focus {\n background-color: #545b62 !important;\n}\n\n.bg-success {\n background-color: #28a745 !important;\n}\n\na.bg-success:hover, a.bg-success:focus,\nbutton.bg-success:hover,\nbutton.bg-success:focus {\n background-color: #1e7e34 !important;\n}\n\n.bg-info {\n background-color: #17a2b8 !important;\n}\n\na.bg-info:hover, a.bg-info:focus,\nbutton.bg-info:hover,\nbutton.bg-info:focus {\n background-color: #117a8b !important;\n}\n\n.bg-warning {\n background-color: #ffc107 !important;\n}\n\na.bg-warning:hover, a.bg-warning:focus,\nbutton.bg-warning:hover,\nbutton.bg-warning:focus {\n background-color: #d39e00 !important;\n}\n\n.bg-danger {\n background-color: #dc3545 !important;\n}\n\na.bg-danger:hover, a.bg-danger:focus,\nbutton.bg-danger:hover,\nbutton.bg-danger:focus {\n background-color: #bd2130 !important;\n}\n\n.bg-light {\n background-color: #f8f9fa !important;\n}\n\na.bg-light:hover, a.bg-light:focus,\nbutton.bg-light:hover,\nbutton.bg-light:focus {\n background-color: #dae0e5 !important;\n}\n\n.bg-dark {\n background-color: #343a40 !important;\n}\n\na.bg-dark:hover, a.bg-dark:focus,\nbutton.bg-dark:hover,\nbutton.bg-dark:focus {\n background-color: #1d2124 !important;\n}\n\n.bg-white {\n background-color: #fff !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n\n.border {\n border: 1px solid #dee2e6 !important;\n}\n\n.border-top {\n border-top: 1px solid #dee2e6 !important;\n}\n\n.border-right {\n border-right: 1px solid #dee2e6 !important;\n}\n\n.border-bottom {\n border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-left {\n border-left: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n border: 0 !important;\n}\n\n.border-top-0 {\n border-top: 0 !important;\n}\n\n.border-right-0 {\n border-right: 0 !important;\n}\n\n.border-bottom-0 {\n border-bottom: 0 !important;\n}\n\n.border-left-0 {\n border-left: 0 !important;\n}\n\n.border-primary {\n border-color: #007bff !important;\n}\n\n.border-secondary {\n border-color: #6c757d !important;\n}\n\n.border-success {\n border-color: #28a745 !important;\n}\n\n.border-info {\n border-color: #17a2b8 !important;\n}\n\n.border-warning {\n border-color: #ffc107 !important;\n}\n\n.border-danger {\n border-color: #dc3545 !important;\n}\n\n.border-light {\n border-color: #f8f9fa !important;\n}\n\n.border-dark {\n border-color: #343a40 !important;\n}\n\n.border-white {\n border-color: #fff !important;\n}\n\n.rounded {\n border-radius: 0.25rem !important;\n}\n\n.rounded-top {\n border-top-left-radius: 0.25rem !important;\n border-top-right-radius: 0.25rem !important;\n}\n\n.rounded-right {\n border-top-right-radius: 0.25rem !important;\n border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-left {\n border-top-left-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n\n.clearfix::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n}\n\n.d-inline-flex {\n display: -webkit-inline-box !important;\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: -webkit-inline-box !important;\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-md-inline-flex {\n display: -webkit-inline-box !important;\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: -webkit-inline-box !important;\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: -webkit-inline-box !important;\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-print-inline-flex {\n display: -webkit-inline-box !important;\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n}\n\n.embed-responsive::before {\n display: block;\n content: \"\";\n}\n\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n\n.embed-responsive-21by9::before {\n padding-top: 42.857143%;\n}\n\n.embed-responsive-16by9::before {\n padding-top: 56.25%;\n}\n\n.embed-responsive-4by3::before {\n padding-top: 75%;\n}\n\n.embed-responsive-1by1::before {\n padding-top: 100%;\n}\n\n.flex-row {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n}\n\n.flex-column {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n}\n\n.justify-content-start {\n -webkit-box-pack: start !important;\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n -webkit-box-pack: end !important;\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n -webkit-box-pack: center !important;\n -ms-flex-pack: center !important;\n justify-content: center !important;\n}\n\n.justify-content-between {\n -webkit-box-pack: justify !important;\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n}\n\n.align-items-start {\n -webkit-box-align: start !important;\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n}\n\n.align-items-end {\n -webkit-box-align: end !important;\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n}\n\n.align-items-center {\n -webkit-box-align: center !important;\n -ms-flex-align: center !important;\n align-items: center !important;\n}\n\n.align-items-baseline {\n -webkit-box-align: baseline !important;\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n -webkit-box-align: stretch !important;\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n}\n\n.align-content-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n}\n\n.align-content-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n}\n\n.align-content-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n}\n\n.align-content-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n}\n\n.align-content-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n}\n\n.align-self-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n}\n\n.align-self-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n}\n\n.align-self-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n}\n\n.align-self-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n}\n\n.align-self-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-sm-column {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-sm-start {\n -webkit-box-pack: start !important;\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n -webkit-box-pack: end !important;\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n -webkit-box-pack: center !important;\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-sm-between {\n -webkit-box-pack: justify !important;\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n -webkit-box-align: start !important;\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n -webkit-box-align: end !important;\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n -webkit-box-align: center !important;\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-sm-baseline {\n -webkit-box-align: baseline !important;\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n -webkit-box-align: stretch !important;\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-sm-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-sm-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-sm-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-sm-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-sm-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-md-column {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-md-start {\n -webkit-box-pack: start !important;\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n -webkit-box-pack: end !important;\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n -webkit-box-pack: center !important;\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-md-between {\n -webkit-box-pack: justify !important;\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-md-start {\n -webkit-box-align: start !important;\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-md-end {\n -webkit-box-align: end !important;\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-md-center {\n -webkit-box-align: center !important;\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-md-baseline {\n -webkit-box-align: baseline !important;\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n -webkit-box-align: stretch !important;\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-md-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-md-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-md-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-md-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-md-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-md-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-md-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-md-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-md-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-md-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-lg-column {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-lg-start {\n -webkit-box-pack: start !important;\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n -webkit-box-pack: end !important;\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n -webkit-box-pack: center !important;\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-lg-between {\n -webkit-box-pack: justify !important;\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n -webkit-box-align: start !important;\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n -webkit-box-align: end !important;\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n -webkit-box-align: center !important;\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-lg-baseline {\n -webkit-box-align: baseline !important;\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n -webkit-box-align: stretch !important;\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-lg-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-lg-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-lg-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-lg-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-lg-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-xl-column {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-xl-start {\n -webkit-box-pack: start !important;\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n -webkit-box-pack: end !important;\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n -webkit-box-pack: center !important;\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-xl-between {\n -webkit-box-pack: justify !important;\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n -webkit-box-align: start !important;\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n -webkit-box-align: end !important;\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n -webkit-box-align: center !important;\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-xl-baseline {\n -webkit-box-align: baseline !important;\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n -webkit-box-align: stretch !important;\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-xl-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-xl-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-xl-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-xl-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-xl-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n.float-left {\n float: left !important;\n}\n\n.float-right {\n float: right !important;\n}\n\n.float-none {\n float: none !important;\n}\n\n@media (min-width: 576px) {\n .float-sm-left {\n float: left !important;\n }\n .float-sm-right {\n float: right !important;\n }\n .float-sm-none {\n float: none !important;\n }\n}\n\n@media (min-width: 768px) {\n .float-md-left {\n float: left !important;\n }\n .float-md-right {\n float: right !important;\n }\n .float-md-none {\n float: none !important;\n }\n}\n\n@media (min-width: 992px) {\n .float-lg-left {\n float: left !important;\n }\n .float-lg-right {\n float: right !important;\n }\n .float-lg-none {\n float: none !important;\n }\n}\n\n@media (min-width: 1200px) {\n .float-xl-left {\n float: left !important;\n }\n .float-xl-right {\n float: right !important;\n }\n .float-xl-none {\n float: none !important;\n }\n}\n\n.position-static {\n position: static !important;\n}\n\n.position-relative {\n position: relative !important;\n}\n\n.position-absolute {\n position: absolute !important;\n}\n\n.position-fixed {\n position: fixed !important;\n}\n\n.position-sticky {\n position: -webkit-sticky !important;\n position: sticky !important;\n}\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1030;\n}\n\n@supports ((position: -webkit-sticky) or (position: sticky)) {\n .sticky-top {\n position: -webkit-sticky;\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n}\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n -webkit-clip-path: inset(50%);\n clip-path: inset(50%);\n border: 0;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n -webkit-clip-path: none;\n clip-path: none;\n}\n\n.w-25 {\n width: 25% !important;\n}\n\n.w-50 {\n width: 50% !important;\n}\n\n.w-75 {\n width: 75% !important;\n}\n\n.w-100 {\n width: 100% !important;\n}\n\n.h-25 {\n height: 25% !important;\n}\n\n.h-50 {\n height: 50% !important;\n}\n\n.h-75 {\n height: 75% !important;\n}\n\n.h-100 {\n height: 100% !important;\n}\n\n.mw-100 {\n max-width: 100% !important;\n}\n\n.mh-100 {\n max-height: 100% !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n\n.text-justify {\n text-align: justify !important;\n}\n\n.text-nowrap {\n white-space: nowrap !important;\n}\n\n.text-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.text-left {\n text-align: left !important;\n}\n\n.text-right {\n text-align: right !important;\n}\n\n.text-center {\n text-align: center !important;\n}\n\n@media (min-width: 576px) {\n .text-sm-left {\n text-align: left !important;\n }\n .text-sm-right {\n text-align: right !important;\n }\n .text-sm-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 768px) {\n .text-md-left {\n text-align: left !important;\n }\n .text-md-right {\n text-align: right !important;\n }\n .text-md-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 992px) {\n .text-lg-left {\n text-align: left !important;\n }\n .text-lg-right {\n text-align: right !important;\n }\n .text-lg-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 1200px) {\n .text-xl-left {\n text-align: left !important;\n }\n .text-xl-right {\n text-align: right !important;\n }\n .text-xl-center {\n text-align: center !important;\n }\n}\n\n.text-lowercase {\n text-transform: lowercase !important;\n}\n\n.text-uppercase {\n text-transform: uppercase !important;\n}\n\n.text-capitalize {\n text-transform: capitalize !important;\n}\n\n.font-weight-light {\n font-weight: 300 !important;\n}\n\n.font-weight-normal {\n font-weight: 400 !important;\n}\n\n.font-weight-bold {\n font-weight: 700 !important;\n}\n\n.font-italic {\n font-style: italic !important;\n}\n\n.text-white {\n color: #fff !important;\n}\n\n.text-primary {\n color: #007bff !important;\n}\n\na.text-primary:hover, a.text-primary:focus {\n color: #0062cc !important;\n}\n\n.text-secondary {\n color: #6c757d !important;\n}\n\na.text-secondary:hover, a.text-secondary:focus {\n color: #545b62 !important;\n}\n\n.text-success {\n color: #28a745 !important;\n}\n\na.text-success:hover, a.text-success:focus {\n color: #1e7e34 !important;\n}\n\n.text-info {\n color: #17a2b8 !important;\n}\n\na.text-info:hover, a.text-info:focus {\n color: #117a8b !important;\n}\n\n.text-warning {\n color: #ffc107 !important;\n}\n\na.text-warning:hover, a.text-warning:focus {\n color: #d39e00 !important;\n}\n\n.text-danger {\n color: #dc3545 !important;\n}\n\na.text-danger:hover, a.text-danger:focus {\n color: #bd2130 !important;\n}\n\n.text-light {\n color: #f8f9fa !important;\n}\n\na.text-light:hover, a.text-light:focus {\n color: #dae0e5 !important;\n}\n\n.text-dark {\n color: #343a40 !important;\n}\n\na.text-dark:hover, a.text-dark:focus {\n color: #1d2124 !important;\n}\n\n.text-muted {\n color: #6c757d !important;\n}\n\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n\n@media print {\n *,\n *::before,\n *::after {\n text-shadow: none !important;\n box-shadow: none !important;\n }\n a:not(.btn) {\n text-decoration: underline;\n }\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n @page {\n size: a3;\n }\n body {\n min-width: 992px !important;\n }\n .container {\n min-width: 992px !important;\n }\n .navbar {\n display: none;\n }\n .badge {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*!\n * Bootstrap v4.0.0 (https://getbootstrap.com)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n:root {\n --blue: #007bff;\n --indigo: #6610f2;\n --purple: #6f42c1;\n --pink: #e83e8c;\n --red: #dc3545;\n --orange: #fd7e14;\n --yellow: #ffc107;\n --green: #28a745;\n --teal: #20c997;\n --cyan: #17a2b8;\n --white: #fff;\n --gray: #6c757d;\n --gray-dark: #343a40;\n --primary: #007bff;\n --secondary: #6c757d;\n --success: #28a745;\n --info: #17a2b8;\n --warning: #ffc107;\n --danger: #dc3545;\n --light: #f8f9fa;\n --dark: #343a40;\n --breakpoint-xs: 0;\n --breakpoint-sm: 576px;\n --breakpoint-md: 768px;\n --breakpoint-lg: 992px;\n --breakpoint-xl: 1200px;\n --font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n -ms-overflow-style: scrollbar;\n -webkit-tap-highlight-color: transparent;\n}\n\n@-ms-viewport {\n width: device-width;\n}\n\narticle, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n -webkit-text-decoration-skip: objects;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus {\n outline: 0;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: .5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\nbutton,\nhtml [type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: 0.5rem;\n font-family: inherit;\n font-weight: 500;\n line-height: 1.2;\n color: inherit;\n}\n\nh1, .h1 {\n font-size: 2.5rem;\n}\n\nh2, .h2 {\n font-size: 2rem;\n}\n\nh3, .h3 {\n font-size: 1.75rem;\n}\n\nh4, .h4 {\n font-size: 1.5rem;\n}\n\nh5, .h5 {\n font-size: 1.25rem;\n}\n\nh6, .h6 {\n font-size: 1rem;\n}\n\n.lead {\n font-size: 1.25rem;\n font-weight: 300;\n}\n\n.display-1 {\n font-size: 6rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-2 {\n font-size: 5.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-3 {\n font-size: 4.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-4 {\n font-size: 3.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\nhr {\n margin-top: 1rem;\n margin-bottom: 1rem;\n border: 0;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\nsmall,\n.small {\n font-size: 80%;\n font-weight: 400;\n}\n\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline-item {\n display: inline-block;\n}\n\n.list-inline-item:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n.blockquote {\n margin-bottom: 1rem;\n font-size: 1.25rem;\n}\n\n.blockquote-footer {\n display: block;\n font-size: 80%;\n color: #6c757d;\n}\n\n.blockquote-footer::before {\n content: \"\\2014 \\00A0\";\n}\n\n.img-fluid {\n max-width: 100%;\n height: auto;\n}\n\n.img-thumbnail {\n padding: 0.25rem;\n background-color: #fff;\n border: 1px solid #dee2e6;\n border-radius: 0.25rem;\n max-width: 100%;\n height: auto;\n}\n\n.figure {\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: 0.5rem;\n line-height: 1;\n}\n\n.figure-caption {\n font-size: 90%;\n color: #6c757d;\n}\n\ncode,\nkbd,\npre,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\ncode {\n font-size: 87.5%;\n color: #e83e8c;\n word-break: break-word;\n}\n\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.2rem 0.4rem;\n font-size: 87.5%;\n color: #fff;\n background-color: #212529;\n border-radius: 0.2rem;\n}\n\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n}\n\npre {\n display: block;\n font-size: 87.5%;\n color: #212529;\n}\n\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n\n.container {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container {\n max-width: 1140px;\n }\n}\n\n.container-fluid {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n.row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n min-height: 1px;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n}\n\n.col-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n order: -1;\n}\n\n.order-last {\n order: 13;\n}\n\n.order-0 {\n order: 0;\n}\n\n.order-1 {\n order: 1;\n}\n\n.order-2 {\n order: 2;\n}\n\n.order-3 {\n order: 3;\n}\n\n.order-4 {\n order: 4;\n}\n\n.order-5 {\n order: 5;\n}\n\n.order-6 {\n order: 6;\n}\n\n.order-7 {\n order: 7;\n}\n\n.order-8 {\n order: 8;\n}\n\n.order-9 {\n order: 9;\n}\n\n.order-10 {\n order: 10;\n}\n\n.order-11 {\n order: 11;\n}\n\n.order-12 {\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-sm-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n order: -1;\n }\n .order-sm-last {\n order: 13;\n }\n .order-sm-0 {\n order: 0;\n }\n .order-sm-1 {\n order: 1;\n }\n .order-sm-2 {\n order: 2;\n }\n .order-sm-3 {\n order: 3;\n }\n .order-sm-4 {\n order: 4;\n }\n .order-sm-5 {\n order: 5;\n }\n .order-sm-6 {\n order: 6;\n }\n .order-sm-7 {\n order: 7;\n }\n .order-sm-8 {\n order: 8;\n }\n .order-sm-9 {\n order: 9;\n }\n .order-sm-10 {\n order: 10;\n }\n .order-sm-11 {\n order: 11;\n }\n .order-sm-12 {\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-md-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n order: -1;\n }\n .order-md-last {\n order: 13;\n }\n .order-md-0 {\n order: 0;\n }\n .order-md-1 {\n order: 1;\n }\n .order-md-2 {\n order: 2;\n }\n .order-md-3 {\n order: 3;\n }\n .order-md-4 {\n order: 4;\n }\n .order-md-5 {\n order: 5;\n }\n .order-md-6 {\n order: 6;\n }\n .order-md-7 {\n order: 7;\n }\n .order-md-8 {\n order: 8;\n }\n .order-md-9 {\n order: 9;\n }\n .order-md-10 {\n order: 10;\n }\n .order-md-11 {\n order: 11;\n }\n .order-md-12 {\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-lg-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n order: -1;\n }\n .order-lg-last {\n order: 13;\n }\n .order-lg-0 {\n order: 0;\n }\n .order-lg-1 {\n order: 1;\n }\n .order-lg-2 {\n order: 2;\n }\n .order-lg-3 {\n order: 3;\n }\n .order-lg-4 {\n order: 4;\n }\n .order-lg-5 {\n order: 5;\n }\n .order-lg-6 {\n order: 6;\n }\n .order-lg-7 {\n order: 7;\n }\n .order-lg-8 {\n order: 8;\n }\n .order-lg-9 {\n order: 9;\n }\n .order-lg-10 {\n order: 10;\n }\n .order-lg-11 {\n order: 11;\n }\n .order-lg-12 {\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-xl-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n order: -1;\n }\n .order-xl-last {\n order: 13;\n }\n .order-xl-0 {\n order: 0;\n }\n .order-xl-1 {\n order: 1;\n }\n .order-xl-2 {\n order: 2;\n }\n .order-xl-3 {\n order: 3;\n }\n .order-xl-4 {\n order: 4;\n }\n .order-xl-5 {\n order: 5;\n }\n .order-xl-6 {\n order: 6;\n }\n .order-xl-7 {\n order: 7;\n }\n .order-xl-8 {\n order: 8;\n }\n .order-xl-9 {\n order: 9;\n }\n .order-xl-10 {\n order: 10;\n }\n .order-xl-11 {\n order: 11;\n }\n .order-xl-12 {\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 1rem;\n background-color: transparent;\n}\n\n.table th,\n.table td {\n padding: 0.75rem;\n vertical-align: top;\n border-top: 1px solid #dee2e6;\n}\n\n.table thead th {\n vertical-align: bottom;\n border-bottom: 2px solid #dee2e6;\n}\n\n.table tbody + tbody {\n border-top: 2px solid #dee2e6;\n}\n\n.table .table {\n background-color: #fff;\n}\n\n.table-sm th,\n.table-sm td {\n padding: 0.3rem;\n}\n\n.table-bordered {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered th,\n.table-bordered td {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered thead th,\n.table-bordered thead td {\n border-bottom-width: 2px;\n}\n\n.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.table-hover tbody tr:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-primary,\n.table-primary > th,\n.table-primary > td {\n background-color: #b8daff;\n}\n\n.table-hover .table-primary:hover {\n background-color: #9fcdff;\n}\n\n.table-hover .table-primary:hover > td,\n.table-hover .table-primary:hover > th {\n background-color: #9fcdff;\n}\n\n.table-secondary,\n.table-secondary > th,\n.table-secondary > td {\n background-color: #d6d8db;\n}\n\n.table-hover .table-secondary:hover {\n background-color: #c8cbcf;\n}\n\n.table-hover .table-secondary:hover > td,\n.table-hover .table-secondary:hover > th {\n background-color: #c8cbcf;\n}\n\n.table-success,\n.table-success > th,\n.table-success > td {\n background-color: #c3e6cb;\n}\n\n.table-hover .table-success:hover {\n background-color: #b1dfbb;\n}\n\n.table-hover .table-success:hover > td,\n.table-hover .table-success:hover > th {\n background-color: #b1dfbb;\n}\n\n.table-info,\n.table-info > th,\n.table-info > td {\n background-color: #bee5eb;\n}\n\n.table-hover .table-info:hover {\n background-color: #abdde5;\n}\n\n.table-hover .table-info:hover > td,\n.table-hover .table-info:hover > th {\n background-color: #abdde5;\n}\n\n.table-warning,\n.table-warning > th,\n.table-warning > td {\n background-color: #ffeeba;\n}\n\n.table-hover .table-warning:hover {\n background-color: #ffe8a1;\n}\n\n.table-hover .table-warning:hover > td,\n.table-hover .table-warning:hover > th {\n background-color: #ffe8a1;\n}\n\n.table-danger,\n.table-danger > th,\n.table-danger > td {\n background-color: #f5c6cb;\n}\n\n.table-hover .table-danger:hover {\n background-color: #f1b0b7;\n}\n\n.table-hover .table-danger:hover > td,\n.table-hover .table-danger:hover > th {\n background-color: #f1b0b7;\n}\n\n.table-light,\n.table-light > th,\n.table-light > td {\n background-color: #fdfdfe;\n}\n\n.table-hover .table-light:hover {\n background-color: #ececf6;\n}\n\n.table-hover .table-light:hover > td,\n.table-hover .table-light:hover > th {\n background-color: #ececf6;\n}\n\n.table-dark,\n.table-dark > th,\n.table-dark > td {\n background-color: #c6c8ca;\n}\n\n.table-hover .table-dark:hover {\n background-color: #b9bbbe;\n}\n\n.table-hover .table-dark:hover > td,\n.table-hover .table-dark:hover > th {\n background-color: #b9bbbe;\n}\n\n.table-active,\n.table-active > th,\n.table-active > td {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover > td,\n.table-hover .table-active:hover > th {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table .thead-dark th {\n color: #fff;\n background-color: #212529;\n border-color: #32383e;\n}\n\n.table .thead-light th {\n color: #495057;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.table-dark {\n color: #fff;\n background-color: #212529;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th {\n border-color: #32383e;\n}\n\n.table-dark.table-bordered {\n border: 0;\n}\n\n.table-dark.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(255, 255, 255, 0.05);\n}\n\n.table-dark.table-hover tbody tr:hover {\n background-color: rgba(255, 255, 255, 0.075);\n}\n\n@media (max-width: 575.98px) {\n .table-responsive-sm {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-sm > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 767.98px) {\n .table-responsive-md {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-md > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 991.98px) {\n .table-responsive-lg {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-lg > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 1199.98px) {\n .table-responsive-xl {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-xl > .table-bordered {\n border: 0;\n }\n}\n\n.table-responsive {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n}\n\n.table-responsive > .table-bordered {\n border: 0;\n}\n\n.form-control {\n display: block;\n width: 100%;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n\n.form-control:focus {\n color: #495057;\n background-color: #fff;\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.form-control::placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:disabled, .form-control[readonly] {\n background-color: #e9ecef;\n opacity: 1;\n}\n\nselect.form-control:not([size]):not([multiple]) {\n height: calc(2.25rem + 2px);\n}\n\nselect.form-control:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n.col-form-label {\n padding-top: calc(0.375rem + 1px);\n padding-bottom: calc(0.375rem + 1px);\n margin-bottom: 0;\n font-size: inherit;\n line-height: 1.5;\n}\n\n.col-form-label-lg {\n padding-top: calc(0.5rem + 1px);\n padding-bottom: calc(0.5rem + 1px);\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.col-form-label-sm {\n padding-top: calc(0.25rem + 1px);\n padding-bottom: calc(0.25rem + 1px);\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n margin-bottom: 0;\n line-height: 1.5;\n background-color: transparent;\n border: solid transparent;\n border-width: 1px 0;\n}\n\n.form-control-plaintext.form-control-sm, .input-group-sm > .form-control-plaintext.form-control,\n.input-group-sm > .input-group-prepend > .form-control-plaintext.input-group-text,\n.input-group-sm > .input-group-append > .form-control-plaintext.input-group-text,\n.input-group-sm > .input-group-prepend > .form-control-plaintext.btn,\n.input-group-sm > .input-group-append > .form-control-plaintext.btn, .form-control-plaintext.form-control-lg, .input-group-lg > .form-control-plaintext.form-control,\n.input-group-lg > .input-group-prepend > .form-control-plaintext.input-group-text,\n.input-group-lg > .input-group-append > .form-control-plaintext.input-group-text,\n.input-group-lg > .input-group-prepend > .form-control-plaintext.btn,\n.input-group-lg > .input-group-append > .form-control-plaintext.btn {\n padding-right: 0;\n padding-left: 0;\n}\n\n.form-control-sm, .input-group-sm > .form-control,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\nselect.form-control-sm:not([size]):not([multiple]), .input-group-sm > select.form-control:not([size]):not([multiple]),\n.input-group-sm > .input-group-prepend > select.input-group-text:not([size]):not([multiple]),\n.input-group-sm > .input-group-append > select.input-group-text:not([size]):not([multiple]),\n.input-group-sm > .input-group-prepend > select.btn:not([size]):not([multiple]),\n.input-group-sm > .input-group-append > select.btn:not([size]):not([multiple]) {\n height: calc(1.8125rem + 2px);\n}\n\n.form-control-lg, .input-group-lg > .form-control,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\nselect.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.form-control:not([size]):not([multiple]),\n.input-group-lg > .input-group-prepend > select.input-group-text:not([size]):not([multiple]),\n.input-group-lg > .input-group-append > select.input-group-text:not([size]):not([multiple]),\n.input-group-lg > .input-group-prepend > select.btn:not([size]):not([multiple]),\n.input-group-lg > .input-group-append > select.btn:not([size]):not([multiple]) {\n height: calc(2.875rem + 2px);\n}\n\n.form-group {\n margin-bottom: 1rem;\n}\n\n.form-text {\n display: block;\n margin-top: 0.25rem;\n}\n\n.form-row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -5px;\n margin-left: -5px;\n}\n\n.form-row > .col,\n.form-row > [class*=\"col-\"] {\n padding-right: 5px;\n padding-left: 5px;\n}\n\n.form-check {\n position: relative;\n display: block;\n padding-left: 1.25rem;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: 0.3rem;\n margin-left: -1.25rem;\n}\n\n.form-check-input:disabled ~ .form-check-label {\n color: #6c757d;\n}\n\n.form-check-label {\n margin-bottom: 0;\n}\n\n.form-check-inline {\n display: inline-flex;\n align-items: center;\n padding-left: 0;\n margin-right: 0.75rem;\n}\n\n.form-check-inline .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: 0.3125rem;\n margin-left: 0;\n}\n\n.valid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #28a745;\n}\n\n.valid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: .5rem;\n margin-top: .1rem;\n font-size: .875rem;\n line-height: 1;\n color: #fff;\n background-color: rgba(40, 167, 69, 0.8);\n border-radius: .2rem;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid, .was-validated\n.custom-select:valid,\n.custom-select.is-valid {\n border-color: #28a745;\n}\n\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus, .was-validated\n.custom-select:valid:focus,\n.custom-select.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .form-control:valid ~ .valid-feedback,\n.was-validated .form-control:valid ~ .valid-tooltip, .form-control.is-valid ~ .valid-feedback,\n.form-control.is-valid ~ .valid-tooltip, .was-validated\n.custom-select:valid ~ .valid-feedback,\n.was-validated\n.custom-select:valid ~ .valid-tooltip,\n.custom-select.is-valid ~ .valid-feedback,\n.custom-select.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n color: #28a745;\n}\n\n.was-validated .form-check-input:valid ~ .valid-feedback,\n.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback,\n.form-check-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label {\n color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before {\n background-color: #71dd8a;\n}\n\n.was-validated .custom-control-input:valid ~ .valid-feedback,\n.was-validated .custom-control-input:valid ~ .valid-tooltip, .custom-control-input.is-valid ~ .valid-feedback,\n.custom-control-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before {\n background-color: #34ce57;\n}\n\n.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label::before, .custom-file-input.is-valid ~ .custom-file-label::before {\n border-color: inherit;\n}\n\n.was-validated .custom-file-input:valid ~ .valid-feedback,\n.was-validated .custom-file-input:valid ~ .valid-tooltip, .custom-file-input.is-valid ~ .valid-feedback,\n.custom-file-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.invalid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #dc3545;\n}\n\n.invalid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: .5rem;\n margin-top: .1rem;\n font-size: .875rem;\n line-height: 1;\n color: #fff;\n background-color: rgba(220, 53, 69, 0.8);\n border-radius: .2rem;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid, .was-validated\n.custom-select:invalid,\n.custom-select.is-invalid {\n border-color: #dc3545;\n}\n\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus, .was-validated\n.custom-select:invalid:focus,\n.custom-select.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-control:invalid ~ .invalid-feedback,\n.was-validated .form-control:invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback,\n.form-control.is-invalid ~ .invalid-tooltip, .was-validated\n.custom-select:invalid ~ .invalid-feedback,\n.was-validated\n.custom-select:invalid ~ .invalid-tooltip,\n.custom-select.is-invalid ~ .invalid-feedback,\n.custom-select.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n color: #dc3545;\n}\n\n.was-validated .form-check-input:invalid ~ .invalid-feedback,\n.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback,\n.form-check-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label {\n color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before {\n background-color: #efa2a9;\n}\n\n.was-validated .custom-control-input:invalid ~ .invalid-feedback,\n.was-validated .custom-control-input:invalid ~ .invalid-tooltip, .custom-control-input.is-invalid ~ .invalid-feedback,\n.custom-control-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before {\n background-color: #e4606d;\n}\n\n.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label::before, .custom-file-input.is-invalid ~ .custom-file-label::before {\n border-color: inherit;\n}\n\n.was-validated .custom-file-input:invalid ~ .invalid-feedback,\n.was-validated .custom-file-input:invalid ~ .invalid-tooltip, .custom-file-input.is-invalid ~ .invalid-feedback,\n.custom-file-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center;\n}\n\n.form-inline .form-check {\n width: 100%;\n}\n\n@media (min-width: 576px) {\n .form-inline label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 0;\n }\n .form-inline .form-group {\n display: flex;\n flex: 0 0 auto;\n flex-flow: row wrap;\n align-items: center;\n margin-bottom: 0;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-plaintext {\n display: inline-block;\n }\n .form-inline .input-group {\n width: auto;\n }\n .form-inline .form-check {\n display: flex;\n align-items: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-inline .form-check-input {\n position: relative;\n margin-top: 0;\n margin-right: 0.25rem;\n margin-left: 0;\n }\n .form-inline .custom-control {\n align-items: center;\n justify-content: center;\n }\n .form-inline .custom-control-label {\n margin-bottom: 0;\n }\n}\n\n.btn {\n display: inline-block;\n font-weight: 400;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n user-select: none;\n border: 1px solid transparent;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.btn:hover, .btn:focus {\n text-decoration: none;\n}\n\n.btn:focus, .btn.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.btn.disabled, .btn:disabled {\n opacity: 0.65;\n}\n\n.btn:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.btn:not(:disabled):not(.disabled):active, .btn:not(:disabled):not(.disabled).active {\n background-image: none;\n}\n\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n.btn-primary {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:hover {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n}\n\n.btn-primary:focus, .btn-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-primary.disabled, .btn-primary:disabled {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active,\n.show > .btn-primary.dropdown-toggle {\n color: #fff;\n background-color: #0062cc;\n border-color: #005cbf;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-secondary {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:hover {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n}\n\n.btn-secondary:focus, .btn-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-secondary.disabled, .btn-secondary:disabled {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-secondary.dropdown-toggle {\n color: #fff;\n background-color: #545b62;\n border-color: #4e555b;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-success {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:hover {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n}\n\n.btn-success:focus, .btn-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-success.disabled, .btn-success:disabled {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active,\n.show > .btn-success.dropdown-toggle {\n color: #fff;\n background-color: #1e7e34;\n border-color: #1c7430;\n}\n\n.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-info {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:hover {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n}\n\n.btn-info:focus, .btn-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-info.disabled, .btn-info:disabled {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active,\n.show > .btn-info.dropdown-toggle {\n color: #fff;\n background-color: #117a8b;\n border-color: #10707f;\n}\n\n.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-warning {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:hover {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n}\n\n.btn-warning:focus, .btn-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-warning.disabled, .btn-warning:disabled {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active,\n.show > .btn-warning.dropdown-toggle {\n color: #212529;\n background-color: #d39e00;\n border-color: #c69500;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-danger {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:hover {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n}\n\n.btn-danger:focus, .btn-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-danger.disabled, .btn-danger:disabled {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active,\n.show > .btn-danger.dropdown-toggle {\n color: #fff;\n background-color: #bd2130;\n border-color: #b21f2d;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-light {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:hover {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n}\n\n.btn-light:focus, .btn-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-light.disabled, .btn-light:disabled {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active,\n.show > .btn-light.dropdown-toggle {\n color: #212529;\n background-color: #dae0e5;\n border-color: #d3d9df;\n}\n\n.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-dark {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:hover {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n}\n\n.btn-dark:focus, .btn-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-dark.disabled, .btn-dark:disabled {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active,\n.show > .btn-dark.dropdown-toggle {\n color: #fff;\n background-color: #1d2124;\n border-color: #171a1d;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-primary {\n color: #007bff;\n background-color: transparent;\n background-image: none;\n border-color: #007bff;\n}\n\n.btn-outline-primary:hover {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:focus, .btn-outline-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-primary.disabled, .btn-outline-primary:disabled {\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-primary.dropdown-toggle {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-secondary {\n color: #6c757d;\n background-color: transparent;\n background-image: none;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:hover {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:focus, .btn-outline-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-secondary.disabled, .btn-outline-secondary:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-secondary.dropdown-toggle {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-success {\n color: #28a745;\n background-color: transparent;\n background-image: none;\n border-color: #28a745;\n}\n\n.btn-outline-success:hover {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:focus, .btn-outline-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-success.disabled, .btn-outline-success:disabled {\n color: #28a745;\n background-color: transparent;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active,\n.show > .btn-outline-success.dropdown-toggle {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-info {\n color: #17a2b8;\n background-color: transparent;\n background-image: none;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:hover {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:focus, .btn-outline-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-info.disabled, .btn-outline-info:disabled {\n color: #17a2b8;\n background-color: transparent;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active,\n.show > .btn-outline-info.dropdown-toggle {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-warning {\n color: #ffc107;\n background-color: transparent;\n background-image: none;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:hover {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:focus, .btn-outline-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-warning.disabled, .btn-outline-warning:disabled {\n color: #ffc107;\n background-color: transparent;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active,\n.show > .btn-outline-warning.dropdown-toggle {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-danger {\n color: #dc3545;\n background-color: transparent;\n background-image: none;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:hover {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:focus, .btn-outline-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-danger.disabled, .btn-outline-danger:disabled {\n color: #dc3545;\n background-color: transparent;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active,\n.show > .btn-outline-danger.dropdown-toggle {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-light {\n color: #f8f9fa;\n background-color: transparent;\n background-image: none;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:hover {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:focus, .btn-outline-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-light.disabled, .btn-outline-light:disabled {\n color: #f8f9fa;\n background-color: transparent;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active,\n.show > .btn-outline-light.dropdown-toggle {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-dark {\n color: #343a40;\n background-color: transparent;\n background-image: none;\n border-color: #343a40;\n}\n\n.btn-outline-dark:hover {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:focus, .btn-outline-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-dark.disabled, .btn-outline-dark:disabled {\n color: #343a40;\n background-color: transparent;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active,\n.show > .btn-outline-dark.dropdown-toggle {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-link {\n font-weight: 400;\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-link:hover {\n color: #0056b3;\n text-decoration: underline;\n background-color: transparent;\n border-color: transparent;\n}\n\n.btn-link:focus, .btn-link.focus {\n text-decoration: underline;\n border-color: transparent;\n box-shadow: none;\n}\n\n.btn-link:disabled, .btn-link.disabled {\n color: #6c757d;\n}\n\n.btn-lg, .btn-group-lg > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n.btn-block + .btn-block {\n margin-top: 0.5rem;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n\n.fade {\n opacity: 0;\n transition: opacity 0.15s linear;\n}\n\n.fade.show {\n opacity: 1;\n}\n\n.collapse {\n display: none;\n}\n\n.collapse.show {\n display: block;\n}\n\ntr.collapse.show {\n display: table-row;\n}\n\ntbody.collapse.show {\n display: table-row-group;\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n transition: height 0.35s ease;\n}\n\n.dropup,\n.dropdown {\n position: relative;\n}\n\n.dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n}\n\n.dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 10rem;\n padding: 0.5rem 0;\n margin: 0.125rem 0 0;\n font-size: 1rem;\n color: #212529;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 0.25rem;\n}\n\n.dropup .dropdown-menu {\n margin-top: 0;\n margin-bottom: 0.125rem;\n}\n\n.dropup .dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0;\n border-right: 0.3em solid transparent;\n border-bottom: 0.3em solid;\n border-left: 0.3em solid transparent;\n}\n\n.dropup .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-menu {\n margin-top: 0;\n margin-left: 0.125rem;\n}\n\n.dropright .dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-bottom: 0.3em solid transparent;\n border-left: 0.3em solid;\n}\n\n.dropright .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-toggle::after {\n vertical-align: 0;\n}\n\n.dropleft .dropdown-menu {\n margin-top: 0;\n margin-right: 0.125rem;\n}\n\n.dropleft .dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n}\n\n.dropleft .dropdown-toggle::after {\n display: none;\n}\n\n.dropleft .dropdown-toggle::before {\n display: inline-block;\n width: 0;\n height: 0;\n margin-right: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0.3em solid;\n border-bottom: 0.3em solid transparent;\n}\n\n.dropleft .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle::before {\n vertical-align: 0;\n}\n\n.dropdown-divider {\n height: 0;\n margin: 0.5rem 0;\n overflow: hidden;\n border-top: 1px solid #e9ecef;\n}\n\n.dropdown-item {\n display: block;\n width: 100%;\n padding: 0.25rem 1.5rem;\n clear: both;\n font-weight: 400;\n color: #212529;\n text-align: inherit;\n white-space: nowrap;\n background-color: transparent;\n border: 0;\n}\n\n.dropdown-item:hover, .dropdown-item:focus {\n color: #16181b;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.dropdown-item.active, .dropdown-item:active {\n color: #fff;\n text-decoration: none;\n background-color: #007bff;\n}\n\n.dropdown-item.disabled, .dropdown-item:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n.dropdown-header {\n display: block;\n padding: 0.5rem 1.5rem;\n margin-bottom: 0;\n font-size: 0.875rem;\n color: #6c757d;\n white-space: nowrap;\n}\n\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle;\n}\n\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n flex: 0 1 auto;\n}\n\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover {\n z-index: 1;\n}\n\n.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n z-index: 1;\n}\n\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group,\n.btn-group-vertical .btn + .btn,\n.btn-group-vertical .btn + .btn-group,\n.btn-group-vertical .btn-group + .btn,\n.btn-group-vertical .btn-group + .btn-group {\n margin-left: -1px;\n}\n\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n}\n\n.btn-toolbar .input-group {\n width: auto;\n}\n\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n padding-right: 0.5625rem;\n padding-left: 0.5625rem;\n}\n\n.dropdown-toggle-split::after {\n margin-left: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n padding-right: 0.375rem;\n padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n padding-right: 0.75rem;\n padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n}\n\n.btn-group-vertical .btn,\n.btn-group-vertical .btn-group {\n width: 100%;\n}\n\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.btn-group-toggle > .btn,\n.btn-group-toggle > .btn-group > .btn {\n margin-bottom: 0;\n}\n\n.btn-group-toggle > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn input[type=\"checkbox\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: stretch;\n width: 100%;\n}\n\n.input-group > .form-control,\n.input-group > .custom-select,\n.input-group > .custom-file {\n position: relative;\n flex: 1 1 auto;\n width: 1%;\n margin-bottom: 0;\n}\n\n.input-group > .form-control:focus,\n.input-group > .custom-select:focus,\n.input-group > .custom-file:focus {\n z-index: 3;\n}\n\n.input-group > .form-control + .form-control,\n.input-group > .form-control + .custom-select,\n.input-group > .form-control + .custom-file,\n.input-group > .custom-select + .form-control,\n.input-group > .custom-select + .custom-select,\n.input-group > .custom-select + .custom-file,\n.input-group > .custom-file + .form-control,\n.input-group > .custom-file + .custom-select,\n.input-group > .custom-file + .custom-file {\n margin-left: -1px;\n}\n\n.input-group > .form-control:not(:last-child),\n.input-group > .custom-select:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .form-control:not(:first-child),\n.input-group > .custom-select:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group > .custom-file {\n display: flex;\n align-items: center;\n}\n\n.input-group > .custom-file:not(:last-child) .custom-file-label,\n.input-group > .custom-file:not(:last-child) .custom-file-label::before {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .custom-file:not(:first-child) .custom-file-label,\n.input-group > .custom-file:not(:first-child) .custom-file-label::before {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group-prepend,\n.input-group-append {\n display: flex;\n}\n\n.input-group-prepend .btn,\n.input-group-append .btn {\n position: relative;\n z-index: 2;\n}\n\n.input-group-prepend .btn + .btn,\n.input-group-prepend .btn + .input-group-text,\n.input-group-prepend .input-group-text + .input-group-text,\n.input-group-prepend .input-group-text + .btn,\n.input-group-append .btn + .btn,\n.input-group-append .btn + .input-group-text,\n.input-group-append .input-group-text + .input-group-text,\n.input-group-append .input-group-text + .btn {\n margin-left: -1px;\n}\n\n.input-group-prepend {\n margin-right: -1px;\n}\n\n.input-group-append {\n margin-left: -1px;\n}\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: 0.375rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n text-align: center;\n white-space: nowrap;\n background-color: #e9ecef;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.input-group-text input[type=\"radio\"],\n.input-group-text input[type=\"checkbox\"] {\n margin-top: 0;\n}\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group > .input-group-append:not(:last-child) > .btn,\n.input-group > .input-group-append:not(:last-child) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.custom-control {\n position: relative;\n display: block;\n min-height: 1.5rem;\n padding-left: 1.5rem;\n}\n\n.custom-control-inline {\n display: inline-flex;\n margin-right: 1rem;\n}\n\n.custom-control-input {\n position: absolute;\n z-index: -1;\n opacity: 0;\n}\n\n.custom-control-input:checked ~ .custom-control-label::before {\n color: #fff;\n background-color: #007bff;\n}\n\n.custom-control-input:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-control-input:active ~ .custom-control-label::before {\n color: #fff;\n background-color: #b3d7ff;\n}\n\n.custom-control-input:disabled ~ .custom-control-label {\n color: #6c757d;\n}\n\n.custom-control-input:disabled ~ .custom-control-label::before {\n background-color: #e9ecef;\n}\n\n.custom-control-label {\n margin-bottom: 0;\n}\n\n.custom-control-label::before {\n position: absolute;\n top: 0.25rem;\n left: 0;\n display: block;\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n content: \"\";\n user-select: none;\n background-color: #dee2e6;\n}\n\n.custom-control-label::after {\n position: absolute;\n top: 0.25rem;\n left: 0;\n display: block;\n width: 1rem;\n height: 1rem;\n content: \"\";\n background-repeat: no-repeat;\n background-position: center center;\n background-size: 50% 50%;\n}\n\n.custom-checkbox .custom-control-label::before {\n border-radius: 0.25rem;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before {\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E\");\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before {\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E\");\n}\n\n.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-radio .custom-control-label::before {\n border-radius: 50%;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::before {\n background-color: #007bff;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E\");\n}\n\n.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: calc(2.25rem + 2px);\n padding: 0.375rem 1.75rem 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n vertical-align: middle;\n background: #fff url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E\") no-repeat right 0.75rem center;\n background-size: 8px 10px;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n appearance: none;\n}\n\n.custom-select:focus {\n border-color: #80bdff;\n outline: 0;\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075), 0 0 5px rgba(128, 189, 255, 0.5);\n}\n\n.custom-select:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.custom-select[multiple], .custom-select[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: 0.75rem;\n background-image: none;\n}\n\n.custom-select:disabled {\n color: #6c757d;\n background-color: #e9ecef;\n}\n\n.custom-select::-ms-expand {\n opacity: 0;\n}\n\n.custom-select-sm {\n height: calc(1.8125rem + 2px);\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n font-size: 75%;\n}\n\n.custom-select-lg {\n height: calc(2.875rem + 2px);\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n font-size: 125%;\n}\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: calc(2.25rem + 2px);\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: calc(2.25rem + 2px);\n margin: 0;\n opacity: 0;\n}\n\n.custom-file-input:focus ~ .custom-file-control {\n border-color: #80bdff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-file-input:focus ~ .custom-file-control::before {\n border-color: #80bdff;\n}\n\n.custom-file-input:lang(en) ~ .custom-file-label::after {\n content: \"Browse\";\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: calc(2.25rem + 2px);\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.custom-file-label::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: calc(calc(2.25rem + 2px) - 1px * 2);\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n content: \"Browse\";\n background-color: #e9ecef;\n border-left: 1px solid #ced4da;\n border-radius: 0 0.25rem 0.25rem 0;\n}\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: 0.5rem 1rem;\n}\n\n.nav-link:hover, .nav-link:focus {\n text-decoration: none;\n}\n\n.nav-link.disabled {\n color: #6c757d;\n}\n\n.nav-tabs {\n border-bottom: 1px solid #dee2e6;\n}\n\n.nav-tabs .nav-item {\n margin-bottom: -1px;\n}\n\n.nav-tabs .nav-link {\n border: 1px solid transparent;\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n border-color: #e9ecef #e9ecef #dee2e6;\n}\n\n.nav-tabs .nav-link.disabled {\n color: #6c757d;\n background-color: transparent;\n border-color: transparent;\n}\n\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n color: #495057;\n background-color: #fff;\n border-color: #dee2e6 #dee2e6 #fff;\n}\n\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.nav-pills .nav-link {\n border-radius: 0.25rem;\n}\n\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n color: #fff;\n background-color: #007bff;\n}\n\n.nav-fill .nav-item {\n flex: 1 1 auto;\n text-align: center;\n}\n\n.nav-justified .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n}\n\n.tab-content > .tab-pane {\n display: none;\n}\n\n.tab-content > .active {\n display: block;\n}\n\n.navbar {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n}\n\n.navbar > .container,\n.navbar > .container-fluid {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n}\n\n.navbar-brand {\n display: inline-block;\n padding-top: 0.3125rem;\n padding-bottom: 0.3125rem;\n margin-right: 1rem;\n font-size: 1.25rem;\n line-height: inherit;\n white-space: nowrap;\n}\n\n.navbar-brand:hover, .navbar-brand:focus {\n text-decoration: none;\n}\n\n.navbar-nav {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.navbar-nav .nav-link {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-nav .dropdown-menu {\n position: static;\n float: none;\n}\n\n.navbar-text {\n display: inline-block;\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n align-items: center;\n}\n\n.navbar-toggler {\n padding: 0.25rem 0.75rem;\n font-size: 1.25rem;\n line-height: 1;\n background-color: transparent;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.navbar-toggler:hover, .navbar-toggler:focus {\n text-decoration: none;\n}\n\n.navbar-toggler:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: no-repeat center center;\n background-size: 100% 100%;\n}\n\n@media (max-width: 575.98px) {\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 576px) {\n .navbar-expand-sm {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-sm .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-sm .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-sm .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-sm .navbar-toggler {\n display: none;\n }\n .navbar-expand-sm .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n@media (max-width: 767.98px) {\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 768px) {\n .navbar-expand-md {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-md .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-md .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-md .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-md .navbar-toggler {\n display: none;\n }\n .navbar-expand-md .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n@media (max-width: 991.98px) {\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 992px) {\n .navbar-expand-lg {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-lg .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-lg .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-lg .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-lg .navbar-toggler {\n display: none;\n }\n .navbar-expand-lg .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n@media (max-width: 1199.98px) {\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .navbar-expand-xl {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-xl .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-xl .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-xl .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-xl .navbar-toggler {\n display: none;\n }\n .navbar-expand-xl .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n.navbar-expand {\n flex-flow: row nowrap;\n justify-content: flex-start;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-expand .navbar-nav {\n flex-direction: row;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu {\n position: absolute;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n}\n\n.navbar-expand .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid {\n flex-wrap: nowrap;\n}\n\n.navbar-expand .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n}\n\n.navbar-expand .navbar-toggler {\n display: none;\n}\n\n.navbar-expand .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n}\n\n.navbar-light .navbar-brand {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-nav .nav-link {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus {\n color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar-light .navbar-nav .nav-link.disabled {\n color: rgba(0, 0, 0, 0.3);\n}\n\n.navbar-light .navbar-nav .show > .nav-link,\n.navbar-light .navbar-nav .active > .nav-link,\n.navbar-light .navbar-nav .nav-link.show,\n.navbar-light .navbar-nav .nav-link.active {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-toggler {\n color: rgba(0, 0, 0, 0.5);\n border-color: rgba(0, 0, 0, 0.1);\n}\n\n.navbar-light .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\");\n}\n\n.navbar-light .navbar-text {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-text a {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-dark .navbar-brand {\n color: #fff;\n}\n\n.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus {\n color: #fff;\n}\n\n.navbar-dark .navbar-nav .nav-link {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus {\n color: rgba(255, 255, 255, 0.75);\n}\n\n.navbar-dark .navbar-nav .nav-link.disabled {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.navbar-dark .navbar-nav .show > .nav-link,\n.navbar-dark .navbar-nav .active > .nav-link,\n.navbar-dark .navbar-nav .nav-link.show,\n.navbar-dark .navbar-nav .nav-link.active {\n color: #fff;\n}\n\n.navbar-dark .navbar-toggler {\n color: rgba(255, 255, 255, 0.5);\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.navbar-dark .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\");\n}\n\n.navbar-dark .navbar-text {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-text a {\n color: #fff;\n}\n\n.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus {\n color: #fff;\n}\n\n.card {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: border-box;\n border: 1px solid rgba(0, 0, 0, 0.125);\n border-radius: 0.25rem;\n}\n\n.card > hr {\n margin-right: 0;\n margin-left: 0;\n}\n\n.card > .list-group:first-child .list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.card > .list-group:last-child .list-group-item:last-child {\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.card-body {\n flex: 1 1 auto;\n padding: 1.25rem;\n}\n\n.card-title {\n margin-bottom: 0.75rem;\n}\n\n.card-subtitle {\n margin-top: -0.375rem;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link:hover {\n text-decoration: none;\n}\n\n.card-link + .card-link {\n margin-left: 1.25rem;\n}\n\n.card-header {\n padding: 0.75rem 1.25rem;\n margin-bottom: 0;\n background-color: rgba(0, 0, 0, 0.03);\n border-bottom: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-header:first-child {\n border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;\n}\n\n.card-header + .list-group .list-group-item:first-child {\n border-top: 0;\n}\n\n.card-footer {\n padding: 0.75rem 1.25rem;\n background-color: rgba(0, 0, 0, 0.03);\n border-top: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-footer:last-child {\n border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);\n}\n\n.card-header-tabs {\n margin-right: -0.625rem;\n margin-bottom: -0.75rem;\n margin-left: -0.625rem;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -0.625rem;\n margin-left: -0.625rem;\n}\n\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: 1.25rem;\n}\n\n.card-img {\n width: 100%;\n border-radius: calc(0.25rem - 1px);\n}\n\n.card-img-top {\n width: 100%;\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card-img-bottom {\n width: 100%;\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card-deck {\n display: flex;\n flex-direction: column;\n}\n\n.card-deck .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-deck {\n flex-flow: row wrap;\n margin-right: -15px;\n margin-left: -15px;\n }\n .card-deck .card {\n display: flex;\n flex: 1 0 0%;\n flex-direction: column;\n margin-right: 15px;\n margin-bottom: 0;\n margin-left: 15px;\n }\n}\n\n.card-group {\n display: flex;\n flex-direction: column;\n}\n\n.card-group > .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-group {\n flex-flow: row wrap;\n }\n .card-group > .card {\n flex: 1 0 0%;\n margin-bottom: 0;\n }\n .card-group > .card + .card {\n margin-left: 0;\n border-left: 0;\n }\n .card-group > .card:first-child {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n .card-group > .card:first-child .card-img-top,\n .card-group > .card:first-child .card-header {\n border-top-right-radius: 0;\n }\n .card-group > .card:first-child .card-img-bottom,\n .card-group > .card:first-child .card-footer {\n border-bottom-right-radius: 0;\n }\n .card-group > .card:last-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .card-group > .card:last-child .card-img-top,\n .card-group > .card:last-child .card-header {\n border-top-left-radius: 0;\n }\n .card-group > .card:last-child .card-img-bottom,\n .card-group > .card:last-child .card-footer {\n border-bottom-left-radius: 0;\n }\n .card-group > .card:only-child {\n border-radius: 0.25rem;\n }\n .card-group > .card:only-child .card-img-top,\n .card-group > .card:only-child .card-header {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n }\n .card-group > .card:only-child .card-img-bottom,\n .card-group > .card:only-child .card-footer {\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) {\n border-radius: 0;\n }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-top,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-header,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-footer {\n border-radius: 0;\n }\n}\n\n.card-columns .card {\n margin-bottom: 0.75rem;\n}\n\n@media (min-width: 576px) {\n .card-columns {\n column-count: 3;\n column-gap: 1.25rem;\n }\n .card-columns .card {\n display: inline-block;\n width: 100%;\n }\n}\n\n.breadcrumb {\n display: flex;\n flex-wrap: wrap;\n padding: 0.75rem 1rem;\n margin-bottom: 1rem;\n list-style: none;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.breadcrumb-item + .breadcrumb-item::before {\n display: inline-block;\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n color: #6c757d;\n content: \"/\";\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: underline;\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: none;\n}\n\n.breadcrumb-item.active {\n color: #6c757d;\n}\n\n.pagination {\n display: flex;\n padding-left: 0;\n list-style: none;\n border-radius: 0.25rem;\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: 0.5rem 0.75rem;\n margin-left: -1px;\n line-height: 1.25;\n color: #007bff;\n background-color: #fff;\n border: 1px solid #dee2e6;\n}\n\n.page-link:hover {\n color: #0056b3;\n text-decoration: none;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.page-link:focus {\n z-index: 2;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.page-link:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.page-item:first-child .page-link {\n margin-left: 0;\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.page-item:last-child .page-link {\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n}\n\n.page-item.active .page-link {\n z-index: 1;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.page-item.disabled .page-link {\n color: #6c757d;\n pointer-events: none;\n cursor: auto;\n background-color: #fff;\n border-color: #dee2e6;\n}\n\n.pagination-lg .page-link {\n padding: 0.75rem 1.5rem;\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.pagination-lg .page-item:first-child .page-link {\n border-top-left-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.pagination-lg .page-item:last-child .page-link {\n border-top-right-radius: 0.3rem;\n border-bottom-right-radius: 0.3rem;\n}\n\n.pagination-sm .page-link {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.pagination-sm .page-item:first-child .page-link {\n border-top-left-radius: 0.2rem;\n border-bottom-left-radius: 0.2rem;\n}\n\n.pagination-sm .page-item:last-child .page-link {\n border-top-right-radius: 0.2rem;\n border-bottom-right-radius: 0.2rem;\n}\n\n.badge {\n display: inline-block;\n padding: 0.25em 0.4em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25rem;\n}\n\n.badge:empty {\n display: none;\n}\n\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n.badge-pill {\n padding-right: 0.6em;\n padding-left: 0.6em;\n border-radius: 10rem;\n}\n\n.badge-primary {\n color: #fff;\n background-color: #007bff;\n}\n\n.badge-primary[href]:hover, .badge-primary[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #0062cc;\n}\n\n.badge-secondary {\n color: #fff;\n background-color: #6c757d;\n}\n\n.badge-secondary[href]:hover, .badge-secondary[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #545b62;\n}\n\n.badge-success {\n color: #fff;\n background-color: #28a745;\n}\n\n.badge-success[href]:hover, .badge-success[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #1e7e34;\n}\n\n.badge-info {\n color: #fff;\n background-color: #17a2b8;\n}\n\n.badge-info[href]:hover, .badge-info[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #117a8b;\n}\n\n.badge-warning {\n color: #212529;\n background-color: #ffc107;\n}\n\n.badge-warning[href]:hover, .badge-warning[href]:focus {\n color: #212529;\n text-decoration: none;\n background-color: #d39e00;\n}\n\n.badge-danger {\n color: #fff;\n background-color: #dc3545;\n}\n\n.badge-danger[href]:hover, .badge-danger[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #bd2130;\n}\n\n.badge-light {\n color: #212529;\n background-color: #f8f9fa;\n}\n\n.badge-light[href]:hover, .badge-light[href]:focus {\n color: #212529;\n text-decoration: none;\n background-color: #dae0e5;\n}\n\n.badge-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.badge-dark[href]:hover, .badge-dark[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #1d2124;\n}\n\n.jumbotron {\n padding: 2rem 1rem;\n margin-bottom: 2rem;\n background-color: #e9ecef;\n border-radius: 0.3rem;\n}\n\n@media (min-width: 576px) {\n .jumbotron {\n padding: 4rem 2rem;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n border-radius: 0;\n}\n\n.alert {\n position: relative;\n padding: 0.75rem 1.25rem;\n margin-bottom: 1rem;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.alert-heading {\n color: inherit;\n}\n\n.alert-link {\n font-weight: 700;\n}\n\n.alert-dismissible {\n padding-right: 4rem;\n}\n\n.alert-dismissible .close {\n position: absolute;\n top: 0;\n right: 0;\n padding: 0.75rem 1.25rem;\n color: inherit;\n}\n\n.alert-primary {\n color: #004085;\n background-color: #cce5ff;\n border-color: #b8daff;\n}\n\n.alert-primary hr {\n border-top-color: #9fcdff;\n}\n\n.alert-primary .alert-link {\n color: #002752;\n}\n\n.alert-secondary {\n color: #383d41;\n background-color: #e2e3e5;\n border-color: #d6d8db;\n}\n\n.alert-secondary hr {\n border-top-color: #c8cbcf;\n}\n\n.alert-secondary .alert-link {\n color: #202326;\n}\n\n.alert-success {\n color: #155724;\n background-color: #d4edda;\n border-color: #c3e6cb;\n}\n\n.alert-success hr {\n border-top-color: #b1dfbb;\n}\n\n.alert-success .alert-link {\n color: #0b2e13;\n}\n\n.alert-info {\n color: #0c5460;\n background-color: #d1ecf1;\n border-color: #bee5eb;\n}\n\n.alert-info hr {\n border-top-color: #abdde5;\n}\n\n.alert-info .alert-link {\n color: #062c33;\n}\n\n.alert-warning {\n color: #856404;\n background-color: #fff3cd;\n border-color: #ffeeba;\n}\n\n.alert-warning hr {\n border-top-color: #ffe8a1;\n}\n\n.alert-warning .alert-link {\n color: #533f03;\n}\n\n.alert-danger {\n color: #721c24;\n background-color: #f8d7da;\n border-color: #f5c6cb;\n}\n\n.alert-danger hr {\n border-top-color: #f1b0b7;\n}\n\n.alert-danger .alert-link {\n color: #491217;\n}\n\n.alert-light {\n color: #818182;\n background-color: #fefefe;\n border-color: #fdfdfe;\n}\n\n.alert-light hr {\n border-top-color: #ececf6;\n}\n\n.alert-light .alert-link {\n color: #686868;\n}\n\n.alert-dark {\n color: #1b1e21;\n background-color: #d6d8d9;\n border-color: #c6c8ca;\n}\n\n.alert-dark hr {\n border-top-color: #b9bbbe;\n}\n\n.alert-dark .alert-link {\n color: #040505;\n}\n\n@keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n.progress {\n display: flex;\n height: 1rem;\n overflow: hidden;\n font-size: 0.75rem;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n color: #fff;\n text-align: center;\n background-color: #007bff;\n transition: width 0.6s ease;\n}\n\n.progress-bar-striped {\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 1rem 1rem;\n}\n\n.progress-bar-animated {\n animation: progress-bar-stripes 1s linear infinite;\n}\n\n.media {\n display: flex;\n align-items: flex-start;\n}\n\n.media-body {\n flex: 1;\n}\n\n.list-group {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n}\n\n.list-group-item-action {\n width: 100%;\n color: #495057;\n text-align: inherit;\n}\n\n.list-group-item-action:hover, .list-group-item-action:focus {\n color: #495057;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.list-group-item-action:active {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 0.75rem 1.25rem;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.list-group-item:hover, .list-group-item:focus {\n z-index: 1;\n text-decoration: none;\n}\n\n.list-group-item.disabled, .list-group-item:disabled {\n color: #6c757d;\n background-color: #fff;\n}\n\n.list-group-item.active {\n z-index: 2;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.list-group-flush .list-group-item {\n border-right: 0;\n border-left: 0;\n border-radius: 0;\n}\n\n.list-group-flush:first-child .list-group-item:first-child {\n border-top: 0;\n}\n\n.list-group-flush:last-child .list-group-item:last-child {\n border-bottom: 0;\n}\n\n.list-group-item-primary {\n color: #004085;\n background-color: #b8daff;\n}\n\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n color: #004085;\n background-color: #9fcdff;\n}\n\n.list-group-item-primary.list-group-item-action.active {\n color: #fff;\n background-color: #004085;\n border-color: #004085;\n}\n\n.list-group-item-secondary {\n color: #383d41;\n background-color: #d6d8db;\n}\n\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n color: #383d41;\n background-color: #c8cbcf;\n}\n\n.list-group-item-secondary.list-group-item-action.active {\n color: #fff;\n background-color: #383d41;\n border-color: #383d41;\n}\n\n.list-group-item-success {\n color: #155724;\n background-color: #c3e6cb;\n}\n\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n color: #155724;\n background-color: #b1dfbb;\n}\n\n.list-group-item-success.list-group-item-action.active {\n color: #fff;\n background-color: #155724;\n border-color: #155724;\n}\n\n.list-group-item-info {\n color: #0c5460;\n background-color: #bee5eb;\n}\n\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n color: #0c5460;\n background-color: #abdde5;\n}\n\n.list-group-item-info.list-group-item-action.active {\n color: #fff;\n background-color: #0c5460;\n border-color: #0c5460;\n}\n\n.list-group-item-warning {\n color: #856404;\n background-color: #ffeeba;\n}\n\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n color: #856404;\n background-color: #ffe8a1;\n}\n\n.list-group-item-warning.list-group-item-action.active {\n color: #fff;\n background-color: #856404;\n border-color: #856404;\n}\n\n.list-group-item-danger {\n color: #721c24;\n background-color: #f5c6cb;\n}\n\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n color: #721c24;\n background-color: #f1b0b7;\n}\n\n.list-group-item-danger.list-group-item-action.active {\n color: #fff;\n background-color: #721c24;\n border-color: #721c24;\n}\n\n.list-group-item-light {\n color: #818182;\n background-color: #fdfdfe;\n}\n\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n color: #818182;\n background-color: #ececf6;\n}\n\n.list-group-item-light.list-group-item-action.active {\n color: #fff;\n background-color: #818182;\n border-color: #818182;\n}\n\n.list-group-item-dark {\n color: #1b1e21;\n background-color: #c6c8ca;\n}\n\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n color: #1b1e21;\n background-color: #b9bbbe;\n}\n\n.list-group-item-dark.list-group-item-action.active {\n color: #fff;\n background-color: #1b1e21;\n border-color: #1b1e21;\n}\n\n.close {\n float: right;\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: .5;\n}\n\n.close:hover, .close:focus {\n color: #000;\n text-decoration: none;\n opacity: .75;\n}\n\n.close:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n\n.modal-open {\n overflow: hidden;\n}\n\n.modal {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n display: none;\n overflow: hidden;\n outline: 0;\n}\n\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 0.5rem;\n pointer-events: none;\n}\n\n.modal.fade .modal-dialog {\n transition: transform 0.3s ease-out;\n transform: translate(0, -25%);\n}\n\n.modal.show .modal-dialog {\n transform: translate(0, 0);\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: calc(100% - (0.5rem * 2));\n}\n\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n pointer-events: auto;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n outline: 0;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n\n.modal-backdrop.fade {\n opacity: 0;\n}\n\n.modal-backdrop.show {\n opacity: 0.5;\n}\n\n.modal-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 1rem;\n border-bottom: 1px solid #e9ecef;\n border-top-left-radius: 0.3rem;\n border-top-right-radius: 0.3rem;\n}\n\n.modal-header .close {\n padding: 1rem;\n margin: -1rem -1rem -1rem auto;\n}\n\n.modal-title {\n margin-bottom: 0;\n line-height: 1.5;\n}\n\n.modal-body {\n position: relative;\n flex: 1 1 auto;\n padding: 1rem;\n}\n\n.modal-footer {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n padding: 1rem;\n border-top: 1px solid #e9ecef;\n}\n\n.modal-footer > :not(:first-child) {\n margin-left: .25rem;\n}\n\n.modal-footer > :not(:last-child) {\n margin-right: .25rem;\n}\n\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n@media (min-width: 576px) {\n .modal-dialog {\n max-width: 500px;\n margin: 1.75rem auto;\n }\n .modal-dialog-centered {\n min-height: calc(100% - (1.75rem * 2));\n }\n .modal-sm {\n max-width: 300px;\n }\n}\n\n@media (min-width: 992px) {\n .modal-lg {\n max-width: 800px;\n }\n}\n\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n opacity: 0;\n}\n\n.tooltip.show {\n opacity: 0.9;\n}\n\n.tooltip .arrow {\n position: absolute;\n display: block;\n width: 0.8rem;\n height: 0.4rem;\n}\n\n.tooltip .arrow::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-tooltip-top, .bs-tooltip-auto[x-placement^=\"top\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^=\"top\"] .arrow {\n bottom: 0;\n}\n\n.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^=\"top\"] .arrow::before {\n top: 0;\n border-width: 0.4rem 0.4rem 0;\n border-top-color: #000;\n}\n\n.bs-tooltip-right, .bs-tooltip-auto[x-placement^=\"right\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^=\"right\"] .arrow {\n left: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^=\"right\"] .arrow::before {\n right: 0;\n border-width: 0.4rem 0.4rem 0.4rem 0;\n border-right-color: #000;\n}\n\n.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^=\"bottom\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow {\n top: 0;\n}\n\n.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow::before {\n bottom: 0;\n border-width: 0 0.4rem 0.4rem;\n border-bottom-color: #000;\n}\n\n.bs-tooltip-left, .bs-tooltip-auto[x-placement^=\"left\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^=\"left\"] .arrow {\n right: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^=\"left\"] .arrow::before {\n left: 0;\n border-width: 0.4rem 0 0.4rem 0.4rem;\n border-left-color: #000;\n}\n\n.tooltip-inner {\n max-width: 200px;\n padding: 0.25rem 0.5rem;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 0.25rem;\n}\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: block;\n max-width: 276px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n}\n\n.popover .arrow {\n position: absolute;\n display: block;\n width: 1rem;\n height: 0.5rem;\n margin: 0 0.3rem;\n}\n\n.popover .arrow::before, .popover .arrow::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-popover-top, .bs-popover-auto[x-placement^=\"top\"] {\n margin-bottom: 0.5rem;\n}\n\n.bs-popover-top .arrow, .bs-popover-auto[x-placement^=\"top\"] .arrow {\n bottom: calc((0.5rem + 1px) * -1);\n}\n\n.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^=\"top\"] .arrow::before,\n.bs-popover-top .arrow::after, .bs-popover-auto[x-placement^=\"top\"] .arrow::after {\n border-width: 0.5rem 0.5rem 0;\n}\n\n.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^=\"top\"] .arrow::before {\n bottom: 0;\n border-top-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-top .arrow::after, .bs-popover-auto[x-placement^=\"top\"] .arrow::after {\n bottom: 1px;\n border-top-color: #fff;\n}\n\n.bs-popover-right, .bs-popover-auto[x-placement^=\"right\"] {\n margin-left: 0.5rem;\n}\n\n.bs-popover-right .arrow, .bs-popover-auto[x-placement^=\"right\"] .arrow {\n left: calc((0.5rem + 1px) * -1);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^=\"right\"] .arrow::before,\n.bs-popover-right .arrow::after, .bs-popover-auto[x-placement^=\"right\"] .arrow::after {\n border-width: 0.5rem 0.5rem 0.5rem 0;\n}\n\n.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^=\"right\"] .arrow::before {\n left: 0;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-right .arrow::after, .bs-popover-auto[x-placement^=\"right\"] .arrow::after {\n left: 1px;\n border-right-color: #fff;\n}\n\n.bs-popover-bottom, .bs-popover-auto[x-placement^=\"bottom\"] {\n margin-top: 0.5rem;\n}\n\n.bs-popover-bottom .arrow, .bs-popover-auto[x-placement^=\"bottom\"] .arrow {\n top: calc((0.5rem + 1px) * -1);\n}\n\n.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::before,\n.bs-popover-bottom .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::after {\n border-width: 0 0.5rem 0.5rem 0.5rem;\n}\n\n.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::before {\n top: 0;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-bottom .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::after {\n top: 1px;\n border-bottom-color: #fff;\n}\n\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^=\"bottom\"] .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: 1rem;\n margin-left: -0.5rem;\n content: \"\";\n border-bottom: 1px solid #f7f7f7;\n}\n\n.bs-popover-left, .bs-popover-auto[x-placement^=\"left\"] {\n margin-right: 0.5rem;\n}\n\n.bs-popover-left .arrow, .bs-popover-auto[x-placement^=\"left\"] .arrow {\n right: calc((0.5rem + 1px) * -1);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^=\"left\"] .arrow::before,\n.bs-popover-left .arrow::after, .bs-popover-auto[x-placement^=\"left\"] .arrow::after {\n border-width: 0.5rem 0 0.5rem 0.5rem;\n}\n\n.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^=\"left\"] .arrow::before {\n right: 0;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-left .arrow::after, .bs-popover-auto[x-placement^=\"left\"] .arrow::after {\n right: 1px;\n border-left-color: #fff;\n}\n\n.popover-header {\n padding: 0.5rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n color: inherit;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.popover-header:empty {\n display: none;\n}\n\n.popover-body {\n padding: 0.5rem 0.75rem;\n color: #212529;\n}\n\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n\n.carousel-item {\n position: relative;\n display: none;\n align-items: center;\n width: 100%;\n transition: transform 0.6s ease;\n backface-visibility: hidden;\n perspective: 1000px;\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next,\n.carousel-item-prev {\n position: absolute;\n top: 0;\n}\n\n.carousel-item-next.carousel-item-left,\n.carousel-item-prev.carousel-item-right {\n transform: translateX(0);\n}\n\n@supports (transform-style: preserve-3d) {\n .carousel-item-next.carousel-item-left,\n .carousel-item-prev.carousel-item-right {\n transform: translate3d(0, 0, 0);\n }\n}\n\n.carousel-item-next,\n.active.carousel-item-right {\n transform: translateX(100%);\n}\n\n@supports (transform-style: preserve-3d) {\n .carousel-item-next,\n .active.carousel-item-right {\n transform: translate3d(100%, 0, 0);\n }\n}\n\n.carousel-item-prev,\n.active.carousel-item-left {\n transform: translateX(-100%);\n}\n\n@supports (transform-style: preserve-3d) {\n .carousel-item-prev,\n .active.carousel-item-left {\n transform: translate3d(-100%, 0, 0);\n }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 15%;\n color: #fff;\n text-align: center;\n opacity: 0.5;\n}\n\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n opacity: .9;\n}\n\n.carousel-control-prev {\n left: 0;\n}\n\n.carousel-control-next {\n right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n background: transparent no-repeat center center;\n background-size: 100% 100%;\n}\n\n.carousel-control-prev-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E\");\n}\n\n.carousel-control-next-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E\");\n}\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 10px;\n left: 0;\n z-index: 15;\n display: flex;\n justify-content: center;\n padding-left: 0;\n margin-right: 15%;\n margin-left: 15%;\n list-style: none;\n}\n\n.carousel-indicators li {\n position: relative;\n flex: 0 1 auto;\n width: 30px;\n height: 3px;\n margin-right: 3px;\n margin-left: 3px;\n text-indent: -999px;\n background-color: rgba(255, 255, 255, 0.5);\n}\n\n.carousel-indicators li::before {\n position: absolute;\n top: -10px;\n left: 0;\n display: inline-block;\n width: 100%;\n height: 10px;\n content: \"\";\n}\n\n.carousel-indicators li::after {\n position: absolute;\n bottom: -10px;\n left: 0;\n display: inline-block;\n width: 100%;\n height: 10px;\n content: \"\";\n}\n\n.carousel-indicators .active {\n background-color: #fff;\n}\n\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n}\n\n.align-baseline {\n vertical-align: baseline !important;\n}\n\n.align-top {\n vertical-align: top !important;\n}\n\n.align-middle {\n vertical-align: middle !important;\n}\n\n.align-bottom {\n vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n vertical-align: text-top !important;\n}\n\n.bg-primary {\n background-color: #007bff !important;\n}\n\na.bg-primary:hover, a.bg-primary:focus,\nbutton.bg-primary:hover,\nbutton.bg-primary:focus {\n background-color: #0062cc !important;\n}\n\n.bg-secondary {\n background-color: #6c757d !important;\n}\n\na.bg-secondary:hover, a.bg-secondary:focus,\nbutton.bg-secondary:hover,\nbutton.bg-secondary:focus {\n background-color: #545b62 !important;\n}\n\n.bg-success {\n background-color: #28a745 !important;\n}\n\na.bg-success:hover, a.bg-success:focus,\nbutton.bg-success:hover,\nbutton.bg-success:focus {\n background-color: #1e7e34 !important;\n}\n\n.bg-info {\n background-color: #17a2b8 !important;\n}\n\na.bg-info:hover, a.bg-info:focus,\nbutton.bg-info:hover,\nbutton.bg-info:focus {\n background-color: #117a8b !important;\n}\n\n.bg-warning {\n background-color: #ffc107 !important;\n}\n\na.bg-warning:hover, a.bg-warning:focus,\nbutton.bg-warning:hover,\nbutton.bg-warning:focus {\n background-color: #d39e00 !important;\n}\n\n.bg-danger {\n background-color: #dc3545 !important;\n}\n\na.bg-danger:hover, a.bg-danger:focus,\nbutton.bg-danger:hover,\nbutton.bg-danger:focus {\n background-color: #bd2130 !important;\n}\n\n.bg-light {\n background-color: #f8f9fa !important;\n}\n\na.bg-light:hover, a.bg-light:focus,\nbutton.bg-light:hover,\nbutton.bg-light:focus {\n background-color: #dae0e5 !important;\n}\n\n.bg-dark {\n background-color: #343a40 !important;\n}\n\na.bg-dark:hover, a.bg-dark:focus,\nbutton.bg-dark:hover,\nbutton.bg-dark:focus {\n background-color: #1d2124 !important;\n}\n\n.bg-white {\n background-color: #fff !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n\n.border {\n border: 1px solid #dee2e6 !important;\n}\n\n.border-top {\n border-top: 1px solid #dee2e6 !important;\n}\n\n.border-right {\n border-right: 1px solid #dee2e6 !important;\n}\n\n.border-bottom {\n border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-left {\n border-left: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n border: 0 !important;\n}\n\n.border-top-0 {\n border-top: 0 !important;\n}\n\n.border-right-0 {\n border-right: 0 !important;\n}\n\n.border-bottom-0 {\n border-bottom: 0 !important;\n}\n\n.border-left-0 {\n border-left: 0 !important;\n}\n\n.border-primary {\n border-color: #007bff !important;\n}\n\n.border-secondary {\n border-color: #6c757d !important;\n}\n\n.border-success {\n border-color: #28a745 !important;\n}\n\n.border-info {\n border-color: #17a2b8 !important;\n}\n\n.border-warning {\n border-color: #ffc107 !important;\n}\n\n.border-danger {\n border-color: #dc3545 !important;\n}\n\n.border-light {\n border-color: #f8f9fa !important;\n}\n\n.border-dark {\n border-color: #343a40 !important;\n}\n\n.border-white {\n border-color: #fff !important;\n}\n\n.rounded {\n border-radius: 0.25rem !important;\n}\n\n.rounded-top {\n border-top-left-radius: 0.25rem !important;\n border-top-right-radius: 0.25rem !important;\n}\n\n.rounded-right {\n border-top-right-radius: 0.25rem !important;\n border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-left {\n border-top-left-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n\n.clearfix::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n}\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n}\n\n.embed-responsive::before {\n display: block;\n content: \"\";\n}\n\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n\n.embed-responsive-21by9::before {\n padding-top: 42.857143%;\n}\n\n.embed-responsive-16by9::before {\n padding-top: 56.25%;\n}\n\n.embed-responsive-4by3::before {\n padding-top: 75%;\n}\n\n.embed-responsive-1by1::before {\n padding-top: 100%;\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n}\n\n.float-left {\n float: left !important;\n}\n\n.float-right {\n float: right !important;\n}\n\n.float-none {\n float: none !important;\n}\n\n@media (min-width: 576px) {\n .float-sm-left {\n float: left !important;\n }\n .float-sm-right {\n float: right !important;\n }\n .float-sm-none {\n float: none !important;\n }\n}\n\n@media (min-width: 768px) {\n .float-md-left {\n float: left !important;\n }\n .float-md-right {\n float: right !important;\n }\n .float-md-none {\n float: none !important;\n }\n}\n\n@media (min-width: 992px) {\n .float-lg-left {\n float: left !important;\n }\n .float-lg-right {\n float: right !important;\n }\n .float-lg-none {\n float: none !important;\n }\n}\n\n@media (min-width: 1200px) {\n .float-xl-left {\n float: left !important;\n }\n .float-xl-right {\n float: right !important;\n }\n .float-xl-none {\n float: none !important;\n }\n}\n\n.position-static {\n position: static !important;\n}\n\n.position-relative {\n position: relative !important;\n}\n\n.position-absolute {\n position: absolute !important;\n}\n\n.position-fixed {\n position: fixed !important;\n}\n\n.position-sticky {\n position: sticky !important;\n}\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1030;\n}\n\n@supports (position: sticky) {\n .sticky-top {\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n}\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n clip-path: inset(50%);\n border: 0;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n clip-path: none;\n}\n\n.w-25 {\n width: 25% !important;\n}\n\n.w-50 {\n width: 50% !important;\n}\n\n.w-75 {\n width: 75% !important;\n}\n\n.w-100 {\n width: 100% !important;\n}\n\n.h-25 {\n height: 25% !important;\n}\n\n.h-50 {\n height: 50% !important;\n}\n\n.h-75 {\n height: 75% !important;\n}\n\n.h-100 {\n height: 100% !important;\n}\n\n.mw-100 {\n max-width: 100% !important;\n}\n\n.mh-100 {\n max-height: 100% !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n\n.text-justify {\n text-align: justify !important;\n}\n\n.text-nowrap {\n white-space: nowrap !important;\n}\n\n.text-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.text-left {\n text-align: left !important;\n}\n\n.text-right {\n text-align: right !important;\n}\n\n.text-center {\n text-align: center !important;\n}\n\n@media (min-width: 576px) {\n .text-sm-left {\n text-align: left !important;\n }\n .text-sm-right {\n text-align: right !important;\n }\n .text-sm-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 768px) {\n .text-md-left {\n text-align: left !important;\n }\n .text-md-right {\n text-align: right !important;\n }\n .text-md-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 992px) {\n .text-lg-left {\n text-align: left !important;\n }\n .text-lg-right {\n text-align: right !important;\n }\n .text-lg-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 1200px) {\n .text-xl-left {\n text-align: left !important;\n }\n .text-xl-right {\n text-align: right !important;\n }\n .text-xl-center {\n text-align: center !important;\n }\n}\n\n.text-lowercase {\n text-transform: lowercase !important;\n}\n\n.text-uppercase {\n text-transform: uppercase !important;\n}\n\n.text-capitalize {\n text-transform: capitalize !important;\n}\n\n.font-weight-light {\n font-weight: 300 !important;\n}\n\n.font-weight-normal {\n font-weight: 400 !important;\n}\n\n.font-weight-bold {\n font-weight: 700 !important;\n}\n\n.font-italic {\n font-style: italic !important;\n}\n\n.text-white {\n color: #fff !important;\n}\n\n.text-primary {\n color: #007bff !important;\n}\n\na.text-primary:hover, a.text-primary:focus {\n color: #0062cc !important;\n}\n\n.text-secondary {\n color: #6c757d !important;\n}\n\na.text-secondary:hover, a.text-secondary:focus {\n color: #545b62 !important;\n}\n\n.text-success {\n color: #28a745 !important;\n}\n\na.text-success:hover, a.text-success:focus {\n color: #1e7e34 !important;\n}\n\n.text-info {\n color: #17a2b8 !important;\n}\n\na.text-info:hover, a.text-info:focus {\n color: #117a8b !important;\n}\n\n.text-warning {\n color: #ffc107 !important;\n}\n\na.text-warning:hover, a.text-warning:focus {\n color: #d39e00 !important;\n}\n\n.text-danger {\n color: #dc3545 !important;\n}\n\na.text-danger:hover, a.text-danger:focus {\n color: #bd2130 !important;\n}\n\n.text-light {\n color: #f8f9fa !important;\n}\n\na.text-light:hover, a.text-light:focus {\n color: #dae0e5 !important;\n}\n\n.text-dark {\n color: #343a40 !important;\n}\n\na.text-dark:hover, a.text-dark:focus {\n color: #1d2124 !important;\n}\n\n.text-muted {\n color: #6c757d !important;\n}\n\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n\n@media print {\n *,\n *::before,\n *::after {\n text-shadow: none !important;\n box-shadow: none !important;\n }\n a:not(.btn) {\n text-decoration: underline;\n }\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n @page {\n size: a3;\n }\n body {\n min-width: 992px !important;\n }\n .container {\n min-width: 992px !important;\n }\n .navbar {\n display: none;\n }\n .badge {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n\n/*# sourceMappingURL=bootstrap.css.map */","// stylelint-disable indentation\n\n// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Origally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS—an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular psuedo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover {\n &:hover { @content; }\n}\n\n@mixin hover-focus {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n","// stylelint-disable declaration-no-important, selector-list-comma-newline-after\n\n//\n// Headings\n//\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: $headings-margin-bottom;\n font-family: $headings-font-family;\n font-weight: $headings-font-weight;\n line-height: $headings-line-height;\n color: $headings-color;\n}\n\nh1, .h1 { font-size: $h1-font-size; }\nh2, .h2 { font-size: $h2-font-size; }\nh3, .h3 { font-size: $h3-font-size; }\nh4, .h4 { font-size: $h4-font-size; }\nh5, .h5 { font-size: $h5-font-size; }\nh6, .h6 { font-size: $h6-font-size; }\n\n.lead {\n font-size: $lead-font-size;\n font-weight: $lead-font-weight;\n}\n\n// Type display classes\n.display-1 {\n font-size: $display1-size;\n font-weight: $display1-weight;\n line-height: $display-line-height;\n}\n.display-2 {\n font-size: $display2-size;\n font-weight: $display2-weight;\n line-height: $display-line-height;\n}\n.display-3 {\n font-size: $display3-size;\n font-weight: $display3-weight;\n line-height: $display-line-height;\n}\n.display-4 {\n font-size: $display4-size;\n font-weight: $display4-weight;\n line-height: $display-line-height;\n}\n\n\n//\n// Horizontal rules\n//\n\nhr {\n margin-top: $hr-margin-y;\n margin-bottom: $hr-margin-y;\n border: 0;\n border-top: $hr-border-width solid $hr-border-color;\n}\n\n\n//\n// Emphasis\n//\n\nsmall,\n.small {\n font-size: $small-font-size;\n font-weight: $font-weight-normal;\n}\n\nmark,\n.mark {\n padding: $mark-padding;\n background-color: $mark-bg;\n}\n\n\n//\n// Lists\n//\n\n.list-unstyled {\n @include list-unstyled;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n @include list-unstyled;\n}\n.list-inline-item {\n display: inline-block;\n\n &:not(:last-child) {\n margin-right: $list-inline-padding;\n }\n}\n\n\n//\n// Misc\n//\n\n// Builds on `abbr`\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n// Blockquotes\n.blockquote {\n margin-bottom: $spacer;\n font-size: $blockquote-font-size;\n}\n\n.blockquote-footer {\n display: block;\n font-size: 80%; // back to default font-size\n color: $blockquote-small-color;\n\n &::before {\n content: \"\\2014 \\00A0\"; // em dash, nbsp\n }\n}\n","// Lists\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n@mixin list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n","// Responsive images (ensure images don't scale beyond their parents)\n//\n// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.\n// We previously tried the \"images are responsive by default\" approach in Bootstrap v2,\n// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)\n// which weren't expecting the images within themselves to be involuntarily resized.\n// See also https://github.com/twbs/bootstrap/issues/18178\n.img-fluid {\n @include img-fluid;\n}\n\n\n// Image thumbnails\n.img-thumbnail {\n padding: $thumbnail-padding;\n background-color: $thumbnail-bg;\n border: $thumbnail-border-width solid $thumbnail-border-color;\n @include border-radius($thumbnail-border-radius);\n @include box-shadow($thumbnail-box-shadow);\n\n // Keep them at most 100% wide\n @include img-fluid;\n}\n\n//\n// Figures\n//\n\n.figure {\n // Ensures the caption's text aligns with the image.\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: ($spacer / 2);\n line-height: 1;\n}\n\n.figure-caption {\n font-size: $figure-caption-font-size;\n color: $figure-caption-color;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n@mixin img-fluid {\n // Part 1: Set a maximum relative to the parent\n max-width: 100%;\n // Part 2: Override the height to auto, otherwise images will be stretched\n // when setting a width and height attribute on the img element.\n height: auto;\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size.\n\n// stylelint-disable indentation, media-query-list-comma-newline-after\n@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {\n background-image: url($file-1x);\n\n // Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio,\n // but doesn't convert dppx=>dpi.\n // There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard.\n // Compatibility info: https://caniuse.com/#feat=css-media-resolution\n @media only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx\n only screen and (min-resolution: 2dppx) { // Standardized\n background-image: url($file-2x);\n background-size: $width-1x $height-1x;\n }\n}\n","// Single side border-radius\n\n@mixin border-radius($radius: $border-radius) {\n @if $enable-rounded {\n border-radius: $radius;\n }\n}\n\n@mixin border-top-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-top-right-radius: $radius;\n }\n}\n\n@mixin border-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: $radius;\n border-bottom-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n\n@mixin border-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n","// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: $font-family-monospace;\n}\n\n// Inline code\ncode {\n font-size: $code-font-size;\n color: $code-color;\n word-break: break-word;\n\n // Streamline the style when inside anchors to avoid broken underline and more\n a > & {\n color: inherit;\n }\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: $kbd-padding-y $kbd-padding-x;\n font-size: $kbd-font-size;\n color: $kbd-color;\n background-color: $kbd-bg;\n @include border-radius($border-radius-sm);\n @include box-shadow($kbd-box-shadow);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: $nested-kbd-font-weight;\n @include box-shadow(none);\n }\n}\n\n// Blocks of code\npre {\n display: block;\n font-size: $code-font-size;\n color: $pre-color;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: $pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n .container {\n @include make-container();\n @include make-container-max-widths();\n }\n}\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but with 100% width for\n// fluid, full width layouts.\n\n@if $enable-grid-classes {\n .container-fluid {\n @include make-container();\n }\n}\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n }\n\n // Remove the negative margin from default .row, then the horizontal padding\n // from all immediate children columns (to prevent runaway style inheritance).\n .no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n }\n}\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container() {\n width: 100%;\n padding-right: ($grid-gutter-width / 2);\n padding-left: ($grid-gutter-width / 2);\n margin-right: auto;\n margin-left: auto;\n}\n\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n}\n\n@mixin make-row() {\n display: flex;\n flex-wrap: wrap;\n margin-right: ($grid-gutter-width / -2);\n margin-left: ($grid-gutter-width / -2);\n}\n\n@mixin make-col-ready() {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n min-height: 1px; // Prevent collapsing\n padding-right: ($grid-gutter-width / 2);\n padding-left: ($grid-gutter-width / 2);\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02px, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash infront.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n // Common properties for all breakpoints\n %grid-column {\n position: relative;\n width: 100%;\n min-height: 1px; // Prevent columns from collapsing when empty\n padding-right: ($gutter / 2);\n padding-left: ($gutter / 2);\n }\n\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n // Allow columns to stretch full width below their breakpoints\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @extend %grid-column;\n }\n }\n .col#{$infix},\n .col#{$infix}-auto {\n @extend %grid-column;\n }\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col#{$infix}-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none; // Reset earlier grid tiers\n }\n\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n\n .order#{$infix}-first { order: -1; }\n\n .order#{$infix}-last { order: $columns + 1; }\n\n @for $i from 0 through $columns {\n .order#{$infix}-#{$i} { order: $i; }\n }\n\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n }\n}\n","//\n// Basic Bootstrap table\n//\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: $spacer;\n background-color: $table-bg; // Reset for nesting within parents with `background-color`.\n\n th,\n td {\n padding: $table-cell-padding;\n vertical-align: top;\n border-top: $table-border-width solid $table-border-color;\n }\n\n thead th {\n vertical-align: bottom;\n border-bottom: (2 * $table-border-width) solid $table-border-color;\n }\n\n tbody + tbody {\n border-top: (2 * $table-border-width) solid $table-border-color;\n }\n\n .table {\n background-color: $body-bg;\n }\n}\n\n\n//\n// Condensed table w/ half padding\n//\n\n.table-sm {\n th,\n td {\n padding: $table-cell-padding-sm;\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: $table-border-width solid $table-border-color;\n\n th,\n td {\n border: $table-border-width solid $table-border-color;\n }\n\n thead {\n th,\n td {\n border-bottom-width: (2 * $table-border-width);\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n tbody tr:nth-of-type(odd) {\n background-color: $table-accent-bg;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n tbody tr {\n @include hover {\n background-color: $table-hover-bg;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n@each $color, $value in $theme-colors {\n @include table-row-variant($color, theme-color-level($color, -9));\n}\n\n@include table-row-variant(active, $table-active-bg);\n\n\n// Dark styles\n//\n// Same table markup, but inverted color scheme: dark background and light text.\n\n// stylelint-disable-next-line no-duplicate-selectors\n.table {\n .thead-dark {\n th {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n border-color: $table-dark-border-color;\n }\n }\n\n .thead-light {\n th {\n color: $table-head-color;\n background-color: $table-head-bg;\n border-color: $table-border-color;\n }\n }\n}\n\n.table-dark {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n\n th,\n td,\n thead th {\n border-color: $table-dark-border-color;\n }\n\n &.table-bordered {\n border: 0;\n }\n\n &.table-striped {\n tbody tr:nth-of-type(odd) {\n background-color: $table-dark-accent-bg;\n }\n }\n\n &.table-hover {\n tbody tr {\n @include hover {\n background-color: $table-dark-hover-bg;\n }\n }\n }\n}\n\n\n// Responsive tables\n//\n// Generate series of `.table-responsive-*` classes for configuring the screen\n// size of where your table will overflow.\n\n.table-responsive {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $next: breakpoint-next($breakpoint, $grid-breakpoints);\n $infix: breakpoint-infix($next, $grid-breakpoints);\n\n &#{$infix} {\n @include media-breakpoint-down($breakpoint) {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar; // See https://github.com/twbs/bootstrap/pull/10057\n\n // Prevent double border on horizontal scroll due to use of `display: block;`\n > .table-bordered {\n border: 0;\n }\n }\n }\n }\n}\n","// Tables\n\n@mixin table-row-variant($state, $background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table-#{$state} {\n &,\n > th,\n > td {\n background-color: $background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover {\n $hover-background: darken($background, 5%);\n\n .table-#{$state} {\n @include hover {\n background-color: $hover-background;\n\n > td,\n > th {\n background-color: $hover-background;\n }\n }\n }\n }\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Textual form controls\n//\n\n.form-control {\n display: block;\n width: 100%;\n padding: $input-padding-y $input-padding-x;\n font-size: $font-size-base;\n line-height: $input-line-height;\n color: $input-color;\n background-color: $input-bg;\n background-clip: padding-box;\n border: $input-border-width solid $input-border-color;\n\n // Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.\n @if $enable-rounded {\n // Manually use the if/else instead of the mixin to account for iOS override\n border-radius: $input-border-radius;\n } @else {\n // Otherwise undo the iOS default\n border-radius: 0;\n }\n\n @include box-shadow($input-box-shadow);\n @include transition($input-transition);\n\n // Unstyle the caret on `<select>`s in IE10+.\n &::-ms-expand {\n background-color: transparent;\n border: 0;\n }\n\n // Customize the `:focus` state to imitate native WebKit styles.\n @include form-control-focus();\n\n // Placeholder\n &::placeholder {\n color: $input-placeholder-color;\n // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.\n opacity: 1;\n }\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &:disabled,\n &[readonly] {\n background-color: $input-disabled-bg;\n // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.\n opacity: 1;\n }\n}\n\nselect.form-control {\n &:not([size]):not([multiple]) {\n height: $input-height;\n }\n\n &:focus::-ms-value {\n // Suppress the nested default white text on blue background highlight given to\n // the selected option text when the (still closed) <select> receives focus\n // in IE and (under certain conditions) Edge, as it looks bad and cannot be made to\n // match the appearance of the native widget.\n // See https://github.com/twbs/bootstrap/issues/19398.\n color: $input-color;\n background-color: $input-bg;\n }\n}\n\n// Make file inputs better match text inputs by forcing them to new lines.\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n\n//\n// Labels\n//\n\n// For use with horizontal and inline forms, when you need the label (or legend)\n// text to align with the form controls.\n.col-form-label {\n padding-top: calc(#{$input-padding-y} + #{$input-border-width});\n padding-bottom: calc(#{$input-padding-y} + #{$input-border-width});\n margin-bottom: 0; // Override the `<label>/<legend>` default\n font-size: inherit; // Override the `<legend>` default\n line-height: $input-line-height;\n}\n\n.col-form-label-lg {\n padding-top: calc(#{$input-padding-y-lg} + #{$input-border-width});\n padding-bottom: calc(#{$input-padding-y-lg} + #{$input-border-width});\n font-size: $font-size-lg;\n line-height: $input-line-height-lg;\n}\n\n.col-form-label-sm {\n padding-top: calc(#{$input-padding-y-sm} + #{$input-border-width});\n padding-bottom: calc(#{$input-padding-y-sm} + #{$input-border-width});\n font-size: $font-size-sm;\n line-height: $input-line-height-sm;\n}\n\n\n// Readonly controls as plain text\n//\n// Apply class to a readonly input to make it appear like regular plain\n// text (without any border, background color, focus indicator)\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding-top: $input-padding-y;\n padding-bottom: $input-padding-y;\n margin-bottom: 0; // match inputs if this class comes on inputs with default margins\n line-height: $input-line-height;\n background-color: transparent;\n border: solid transparent;\n border-width: $input-border-width 0;\n\n &.form-control-sm,\n &.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// The `.form-group-* form-control` variations are sadly duplicated to avoid the\n// issue documented in https://github.com/twbs/bootstrap/issues/15074.\n\n.form-control-sm {\n padding: $input-padding-y-sm $input-padding-x-sm;\n font-size: $font-size-sm;\n line-height: $input-line-height-sm;\n @include border-radius($input-border-radius-sm);\n}\n\nselect.form-control-sm {\n &:not([size]):not([multiple]) {\n height: $input-height-sm;\n }\n}\n\n.form-control-lg {\n padding: $input-padding-y-lg $input-padding-x-lg;\n font-size: $font-size-lg;\n line-height: $input-line-height-lg;\n @include border-radius($input-border-radius-lg);\n}\n\nselect.form-control-lg {\n &:not([size]):not([multiple]) {\n height: $input-height-lg;\n }\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: $form-group-margin-bottom;\n}\n\n.form-text {\n display: block;\n margin-top: $form-text-margin-top;\n}\n\n\n// Form grid\n//\n// Special replacement for our grid system's `.row` for tighter form layouts.\n\n.form-row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -5px;\n margin-left: -5px;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: 5px;\n padding-left: 5px;\n }\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.form-check {\n position: relative;\n display: block;\n padding-left: $form-check-input-gutter;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: $form-check-input-margin-y;\n margin-left: -$form-check-input-gutter;\n\n &:disabled ~ .form-check-label {\n color: $text-muted;\n }\n}\n\n.form-check-label {\n margin-bottom: 0; // Override default `<label>` bottom margin\n}\n\n.form-check-inline {\n display: inline-flex;\n align-items: center;\n padding-left: 0; // Override base .form-check\n margin-right: $form-check-inline-margin-x;\n\n // Undo .form-check-input defaults and add some `margin-right`.\n .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: $form-check-inline-input-margin-x;\n margin-left: 0;\n }\n}\n\n\n// Form validation\n//\n// Provide feedback to users when form field values are valid or invalid. Works\n// primarily for client-side validation via scoped `:invalid` and `:valid`\n// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for\n// server side validation.\n\n@include form-validation-state(\"valid\", $form-feedback-valid-color);\n@include form-validation-state(\"invalid\", $form-feedback-invalid-color);\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n\n.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)\n\n // Because we use flex, the initial sizing of checkboxes is collapsed and\n // doesn't occupy the full-width (which is what we want for xs grid tier),\n // so we force that here.\n .form-check {\n width: 100%;\n }\n\n // Kick in the inline\n @include media-breakpoint-up(sm) {\n label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 0;\n }\n\n // Inline-block all the things for \"inline\"\n .form-group {\n display: flex;\n flex: 0 0 auto;\n flex-flow: row wrap;\n align-items: center;\n margin-bottom: 0;\n }\n\n // Allow folks to *not* use `.form-group`\n .form-control {\n display: inline-block;\n width: auto; // Prevent labels from stacking above inputs in `.form-group`\n vertical-align: middle;\n }\n\n // Make static controls behave like regular ones\n .form-control-plaintext {\n display: inline-block;\n }\n\n .input-group {\n width: auto;\n }\n\n // Remove default margin on radios/checkboxes that were used for stacking, and\n // then undo the floating of radios and checkboxes to match.\n .form-check {\n display: flex;\n align-items: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-check-input {\n position: relative;\n margin-top: 0;\n margin-right: $form-check-input-margin-x;\n margin-left: 0;\n }\n\n .custom-control {\n align-items: center;\n justify-content: center;\n }\n .custom-control-label {\n margin-bottom: 0;\n }\n }\n}\n","@mixin transition($transition...) {\n @if $enable-transitions {\n @if length($transition) == 0 {\n transition: $transition-base;\n } @else {\n transition: $transition;\n }\n }\n}\n","// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `$input-focus-border-color` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n@mixin form-control-focus() {\n &:focus {\n color: $input-focus-color;\n background-color: $input-focus-bg;\n border-color: $input-focus-border-color;\n outline: 0;\n // Avoid using mixin so we can pass custom focus shadow properly\n @if $enable-shadows {\n box-shadow: $input-box-shadow, $input-focus-box-shadow;\n } @else {\n box-shadow: $input-focus-box-shadow;\n }\n }\n}\n\n\n@mixin form-validation-state($state, $color) {\n .#{$state}-feedback {\n display: none;\n width: 100%;\n margin-top: $form-feedback-margin-top;\n font-size: $form-feedback-font-size;\n color: $color;\n }\n\n .#{$state}-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%; // Contain to parent when possible\n padding: .5rem;\n margin-top: .1rem;\n font-size: .875rem;\n line-height: 1;\n color: #fff;\n background-color: rgba($color, .8);\n border-radius: .2rem;\n }\n\n .form-control,\n .custom-select {\n .was-validated &:#{$state},\n &.is-#{$state} {\n border-color: $color;\n\n &:focus {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n }\n\n .form-check-input {\n .was-validated &:#{$state},\n &.is-#{$state} {\n ~ .form-check-label {\n color: $color;\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n }\n\n .custom-control-input {\n .was-validated &:#{$state},\n &.is-#{$state} {\n ~ .custom-control-label {\n color: $color;\n\n &::before {\n background-color: lighten($color, 25%);\n }\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n\n &:checked {\n ~ .custom-control-label::before {\n @include gradient-bg(lighten($color, 10%));\n }\n }\n\n &:focus {\n ~ .custom-control-label::before {\n box-shadow: 0 0 0 1px $body-bg, 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n }\n\n // custom file\n .custom-file-input {\n .was-validated &:#{$state},\n &.is-#{$state} {\n ~ .custom-file-label {\n border-color: $color;\n\n &::before { border-color: inherit; }\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n\n &:focus {\n ~ .custom-file-label {\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n }\n}\n","// Gradients\n\n@mixin gradient-bg($color) {\n @if $enable-gradients {\n background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x;\n } @else {\n background-color: $color;\n }\n}\n\n// Horizontal gradient, from left to right\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-x($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n// Vertical gradient, from top to bottom\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-y($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n@mixin gradient-directional($start-color: #555, $end-color: #333, $deg: 45deg) {\n background-image: linear-gradient($deg, $start-color, $end-color);\n background-repeat: repeat-x;\n}\n@mixin gradient-x-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {\n background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-y-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {\n background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-radial($inner-color: #555, $outer-color: #333) {\n background-image: radial-gradient(circle, $inner-color, $outer-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-striped($color: rgba(255,255,255,.15), $angle: 45deg) {\n background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Base styles\n//\n\n.btn {\n display: inline-block;\n font-weight: $btn-font-weight;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n user-select: none;\n border: $btn-border-width solid transparent;\n @include button-size($btn-padding-y, $btn-padding-x, $font-size-base, $btn-line-height, $btn-border-radius);\n @include transition($btn-transition);\n\n // Share hover and focus styles\n @include hover-focus {\n text-decoration: none;\n }\n\n &:focus,\n &.focus {\n outline: 0;\n box-shadow: $btn-focus-box-shadow;\n }\n\n // Disabled comes first so active can properly restyle\n &.disabled,\n &:disabled {\n opacity: $btn-disabled-opacity;\n @include box-shadow(none);\n }\n\n // Opinionated: add \"hand\" cursor to non-disabled .btn elements\n &:not(:disabled):not(.disabled) {\n cursor: pointer;\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active {\n background-image: none;\n @include box-shadow($btn-active-box-shadow);\n\n &:focus {\n @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);\n }\n }\n}\n\n// Future-proof disabling of clicks on `<a>` elements\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n\n//\n// Alternate buttons\n//\n\n@each $color, $value in $theme-colors {\n .btn-#{$color} {\n @include button-variant($value, $value);\n }\n}\n\n@each $color, $value in $theme-colors {\n .btn-outline-#{$color} {\n @include button-outline-variant($value);\n }\n}\n\n\n//\n// Link buttons\n//\n\n// Make a button look and behave like a link\n.btn-link {\n font-weight: $font-weight-normal;\n color: $link-color;\n background-color: transparent;\n\n @include hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n background-color: transparent;\n border-color: transparent;\n }\n\n &:focus,\n &.focus {\n text-decoration: $link-hover-decoration;\n border-color: transparent;\n box-shadow: none;\n }\n\n &:disabled,\n &.disabled {\n color: $btn-link-disabled-color;\n }\n\n // No need for an active state here\n}\n\n\n//\n// Button Sizes\n//\n\n.btn-lg {\n @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);\n}\n\n.btn-sm {\n @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $font-size-sm, $btn-line-height-sm, $btn-border-radius-sm);\n}\n\n\n//\n// Block button\n//\n\n.btn-block {\n display: block;\n width: 100%;\n\n // Vertically space out multiple block buttons\n + .btn-block {\n margin-top: $btn-block-spacing-y;\n }\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n@mixin button-variant($background, $border, $hover-background: darken($background, 7.5%), $hover-border: darken($border, 10%), $active-background: darken($background, 10%), $active-border: darken($border, 12.5%)) {\n color: color-yiq($background);\n @include gradient-bg($background);\n border-color: $border;\n @include box-shadow($btn-box-shadow);\n\n @include hover {\n color: color-yiq($hover-background);\n @include gradient-bg($hover-background);\n border-color: $hover-border;\n }\n\n &:focus,\n &.focus {\n // Avoid using mixin so we can pass custom focus shadow properly\n @if $enable-shadows {\n box-shadow: $btn-box-shadow, 0 0 0 $btn-focus-width rgba($border, .5);\n } @else {\n box-shadow: 0 0 0 $btn-focus-width rgba($border, .5);\n }\n }\n\n // Disabled comes first so active can properly restyle\n &.disabled,\n &:disabled {\n color: color-yiq($background);\n background-color: $background;\n border-color: $border;\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active,\n .show > &.dropdown-toggle {\n color: color-yiq($active-background);\n background-color: $active-background;\n @if $enable-gradients {\n background-image: none; // Remove the gradient for the pressed/active state\n }\n border-color: $active-border;\n\n &:focus {\n // Avoid using mixin so we can pass custom focus shadow properly\n @if $enable-shadows {\n box-shadow: $btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($border, .5);\n } @else {\n box-shadow: 0 0 0 $btn-focus-width rgba($border, .5);\n }\n }\n }\n}\n\n@mixin button-outline-variant($color, $color-hover: color-yiq($color), $active-background: $color, $active-border: $color) {\n color: $color;\n background-color: transparent;\n background-image: none;\n border-color: $color;\n\n &:hover {\n color: $color-hover;\n background-color: $active-background;\n border-color: $active-border;\n }\n\n &:focus,\n &.focus {\n box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n }\n\n &.disabled,\n &:disabled {\n color: $color;\n background-color: transparent;\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active,\n .show > &.dropdown-toggle {\n color: color-yiq($active-background);\n background-color: $active-background;\n border-color: $active-border;\n\n &:focus {\n // Avoid using mixin so we can pass custom focus shadow properly\n @if $enable-shadows and $btn-active-box-shadow != none {\n box-shadow: $btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5);\n } @else {\n box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n }\n }\n }\n}\n\n// Button sizes\n@mixin button-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {\n padding: $padding-y $padding-x;\n font-size: $font-size;\n line-height: $line-height;\n // Manually declare to provide an override to the browser default\n @if $enable-rounded {\n border-radius: $border-radius;\n } @else {\n border-radius: 0;\n }\n}\n","// stylelint-disable selector-no-qualifying-type\n\n.fade {\n opacity: 0;\n @include transition($transition-fade);\n\n &.show {\n opacity: 1;\n }\n}\n\n.collapse {\n display: none;\n &.show {\n display: block;\n }\n}\n\ntr {\n &.collapse.show {\n display: table-row;\n }\n}\n\ntbody {\n &.collapse.show {\n display: table-row-group;\n }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n @include transition($transition-collapse);\n}\n","// The dropdown wrapper (`<div>`)\n.dropup,\n.dropdown {\n position: relative;\n}\n\n.dropdown-toggle {\n // Generate the caret automatically\n @include caret;\n}\n\n// The dropdown menu\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: $zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: $dropdown-min-width;\n padding: $dropdown-padding-y 0;\n margin: $dropdown-spacer 0 0; // override default ul\n font-size: $font-size-base; // Redeclare because nesting can cause inheritance issues\n color: $body-color;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n list-style: none;\n background-color: $dropdown-bg;\n background-clip: padding-box;\n border: $dropdown-border-width solid $dropdown-border-color;\n @include border-radius($dropdown-border-radius);\n @include box-shadow($dropdown-box-shadow);\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n// Just add .dropup after the standard .dropdown class and you're set.\n.dropup {\n .dropdown-menu {\n margin-top: 0;\n margin-bottom: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(up);\n }\n}\n\n.dropright {\n .dropdown-menu {\n margin-top: 0;\n margin-left: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(right);\n &::after {\n vertical-align: 0;\n }\n }\n}\n\n.dropleft {\n .dropdown-menu {\n margin-top: 0;\n margin-right: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(left);\n &::before {\n vertical-align: 0;\n }\n }\n}\n\n// Dividers (basically an `<hr>`) within the dropdown\n.dropdown-divider {\n @include nav-divider($dropdown-divider-bg);\n}\n\n// Links, buttons, and more within the dropdown menu\n//\n// `<button>`-specific styles are denoted with `// For <button>s`\n.dropdown-item {\n display: block;\n width: 100%; // For `<button>`s\n padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n clear: both;\n font-weight: $font-weight-normal;\n color: $dropdown-link-color;\n text-align: inherit; // For `<button>`s\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n background-color: transparent; // For `<button>`s\n border: 0; // For `<button>`s\n\n @include hover-focus {\n color: $dropdown-link-hover-color;\n text-decoration: none;\n @include gradient-bg($dropdown-link-hover-bg);\n }\n\n &.active,\n &:active {\n color: $dropdown-link-active-color;\n text-decoration: none;\n @include gradient-bg($dropdown-link-active-bg);\n }\n\n &.disabled,\n &:disabled {\n color: $dropdown-link-disabled-color;\n background-color: transparent;\n // Remove CSS gradients if they're enabled\n @if $enable-gradients {\n background-image: none;\n }\n }\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: $dropdown-padding-y $dropdown-item-padding-x;\n margin-bottom: 0; // for use with heading elements\n font-size: $font-size-sm;\n color: $dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n","@mixin caret-down {\n border-top: $caret-width solid;\n border-right: $caret-width solid transparent;\n border-bottom: 0;\n border-left: $caret-width solid transparent;\n}\n\n@mixin caret-up {\n border-top: 0;\n border-right: $caret-width solid transparent;\n border-bottom: $caret-width solid;\n border-left: $caret-width solid transparent;\n}\n\n@mixin caret-right {\n border-top: $caret-width solid transparent;\n border-bottom: $caret-width solid transparent;\n border-left: $caret-width solid;\n}\n\n@mixin caret-left {\n border-top: $caret-width solid transparent;\n border-right: $caret-width solid;\n border-bottom: $caret-width solid transparent;\n}\n\n@mixin caret($direction: down) {\n @if $enable-caret {\n &::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: $caret-width * .85;\n vertical-align: $caret-width * .85;\n content: \"\";\n @if $direction == down {\n @include caret-down;\n } @else if $direction == up {\n @include caret-up;\n } @else if $direction == right {\n @include caret-right;\n }\n }\n\n @if $direction == left {\n &::after {\n display: none;\n }\n\n &::before {\n display: inline-block;\n width: 0;\n height: 0;\n margin-right: $caret-width * .85;\n vertical-align: $caret-width * .85;\n content: \"\";\n @include caret-left;\n }\n }\n\n &:empty::after {\n margin-left: 0;\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n@mixin nav-divider($color: #e5e5e5) {\n height: 0;\n margin: ($spacer / 2) 0;\n overflow: hidden;\n border-top: 1px solid $color;\n}\n","// stylelint-disable selector-no-qualifying-type\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle; // match .btn alignment given font-size hack above\n\n > .btn {\n position: relative;\n flex: 0 1 auto;\n\n // Bring the hover, focused, and \"active\" buttons to the front to overlay\n // the borders properly\n @include hover {\n z-index: 1;\n }\n &:focus,\n &:active,\n &.active {\n z-index: 1;\n }\n }\n\n // Prevent double borders when buttons are next to each other\n .btn + .btn,\n .btn + .btn-group,\n .btn-group + .btn,\n .btn-group + .btn-group {\n margin-left: -$btn-border-width;\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n\n .input-group {\n width: auto;\n }\n}\n\n.btn-group {\n > .btn:first-child {\n margin-left: 0;\n }\n\n // Reset rounded corners\n > .btn:not(:last-child):not(.dropdown-toggle),\n > .btn-group:not(:last-child) > .btn {\n @include border-right-radius(0);\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) > .btn {\n @include border-left-radius(0);\n }\n}\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-sm > .btn { @extend .btn-sm; }\n.btn-group-lg > .btn { @extend .btn-lg; }\n\n\n//\n// Split button dropdowns\n//\n\n.dropdown-toggle-split {\n padding-right: $btn-padding-x * .75;\n padding-left: $btn-padding-x * .75;\n\n &::after {\n margin-left: 0;\n }\n}\n\n.btn-sm + .dropdown-toggle-split {\n padding-right: $btn-padding-x-sm * .75;\n padding-left: $btn-padding-x-sm * .75;\n}\n\n.btn-lg + .dropdown-toggle-split {\n padding-right: $btn-padding-x-lg * .75;\n padding-left: $btn-padding-x-lg * .75;\n}\n\n\n// The clickable button for toggling the menu\n// Set the same inset shadow as the :active state\n.btn-group.show .dropdown-toggle {\n @include box-shadow($btn-active-box-shadow);\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n @include box-shadow(none);\n }\n}\n\n\n//\n// Vertical button groups\n//\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n\n .btn,\n .btn-group {\n width: 100%;\n }\n\n > .btn + .btn,\n > .btn + .btn-group,\n > .btn-group + .btn,\n > .btn-group + .btn-group {\n margin-top: -$btn-border-width;\n margin-left: 0;\n }\n\n // Reset rounded corners\n > .btn:not(:last-child):not(.dropdown-toggle),\n > .btn-group:not(:last-child) > .btn {\n @include border-bottom-radius(0);\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) > .btn {\n @include border-top-radius(0);\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n.btn-group-toggle {\n > .btn,\n > .btn-group > .btn {\n margin-bottom: 0; // Override default `<label>` value\n\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n }\n }\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Base styles\n//\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap; // For form validation feedback\n align-items: stretch;\n width: 100%;\n\n > .form-control,\n > .custom-select,\n > .custom-file {\n position: relative; // For focus state's z-index\n flex: 1 1 auto;\n // Add width 1% and flex-basis auto to ensure that button will not wrap out\n // the column. Applies to IE Edge+ and Firefox. Chrome does not require this.\n width: 1%;\n margin-bottom: 0;\n\n // Bring the \"active\" form control to the top of surrounding elements\n &:focus {\n z-index: 3;\n }\n\n + .form-control,\n + .custom-select,\n + .custom-file {\n margin-left: -$input-border-width;\n }\n }\n\n > .form-control,\n > .custom-select {\n &:not(:last-child) { @include border-right-radius(0); }\n &:not(:first-child) { @include border-left-radius(0); }\n }\n\n // Custom file inputs have more complex markup, thus requiring different\n // border-radius overrides.\n > .custom-file {\n display: flex;\n align-items: center;\n\n &:not(:last-child) .custom-file-label,\n &:not(:last-child) .custom-file-label::before { @include border-right-radius(0); }\n &:not(:first-child) .custom-file-label,\n &:not(:first-child) .custom-file-label::before { @include border-left-radius(0); }\n }\n}\n\n\n// Prepend and append\n//\n// While it requires one extra layer of HTML for each, dedicated prepend and\n// append elements allow us to 1) be less clever, 2) simplify our selectors, and\n// 3) support HTML5 form validation.\n\n.input-group-prepend,\n.input-group-append {\n display: flex;\n\n // Ensure buttons are always above inputs for more visually pleasing borders.\n // This isn't needed for `.input-group-text` since it shares the same border-color\n // as our inputs.\n .btn {\n position: relative;\n z-index: 2;\n }\n\n .btn + .btn,\n .btn + .input-group-text,\n .input-group-text + .input-group-text,\n .input-group-text + .btn {\n margin-left: -$input-border-width;\n }\n}\n\n.input-group-prepend { margin-right: -$input-border-width; }\n.input-group-append { margin-left: -$input-border-width; }\n\n\n// Textual addons\n//\n// Serves as a catch-all element for any text or radio/checkbox input you wish\n// to prepend or append to an input.\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: $input-padding-y $input-padding-x;\n margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom\n font-size: $font-size-base; // Match inputs\n font-weight: $font-weight-normal;\n line-height: $input-line-height;\n color: $input-group-addon-color;\n text-align: center;\n white-space: nowrap;\n background-color: $input-group-addon-bg;\n border: $input-border-width solid $input-group-addon-border-color;\n @include border-radius($input-border-radius);\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n\n// Sizing\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n @extend .form-control-lg;\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n @extend .form-control-sm;\n}\n\n\n// Prepend and append rounded corners\n//\n// These rulesets must come after the sizing ones to properly override sm and lg\n// border-radius values when extending. They're more specific than we'd like\n// with the `.input-group >` part, but without it, we cannot override the sizing.\n\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group > .input-group-append:not(:last-child) > .btn,\n.input-group > .input-group-append:not(:last-child) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n @include border-right-radius(0);\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n @include border-left-radius(0);\n}\n","// Embedded icons from Open Iconic.\n// Released under MIT and copyright 2014 Waybury.\n// https://useiconic.com/open\n\n\n// Checkboxes and radios\n//\n// Base class takes care of all the key behavioral aspects.\n\n.custom-control {\n position: relative;\n display: block;\n min-height: (1rem * $line-height-base);\n padding-left: $custom-control-gutter;\n}\n\n.custom-control-inline {\n display: inline-flex;\n margin-right: $custom-control-spacer-x;\n}\n\n.custom-control-input {\n position: absolute;\n z-index: -1; // Put the input behind the label so it doesn't overlay text\n opacity: 0;\n\n &:checked ~ .custom-control-label::before {\n color: $custom-control-indicator-checked-color;\n @include gradient-bg($custom-control-indicator-checked-bg);\n @include box-shadow($custom-control-indicator-checked-box-shadow);\n }\n\n &:focus ~ .custom-control-label::before {\n // the mixin is not used here to make sure there is feedback\n box-shadow: $custom-control-indicator-focus-box-shadow;\n }\n\n &:active ~ .custom-control-label::before {\n color: $custom-control-indicator-active-color;\n background-color: $custom-control-indicator-active-bg;\n @include box-shadow($custom-control-indicator-active-box-shadow);\n }\n\n &:disabled {\n ~ .custom-control-label {\n color: $custom-control-label-disabled-color;\n\n &::before {\n background-color: $custom-control-indicator-disabled-bg;\n }\n }\n }\n}\n\n// Custom control indicators\n//\n// Build the custom controls out of psuedo-elements.\n\n.custom-control-label {\n margin-bottom: 0;\n\n // Background-color and (when enabled) gradient\n &::before {\n position: absolute;\n top: (($line-height-base - $custom-control-indicator-size) / 2);\n left: 0;\n display: block;\n width: $custom-control-indicator-size;\n height: $custom-control-indicator-size;\n pointer-events: none;\n content: \"\";\n user-select: none;\n background-color: $custom-control-indicator-bg;\n @include box-shadow($custom-control-indicator-box-shadow);\n }\n\n // Foreground (icon)\n &::after {\n position: absolute;\n top: (($line-height-base - $custom-control-indicator-size) / 2);\n left: 0;\n display: block;\n width: $custom-control-indicator-size;\n height: $custom-control-indicator-size;\n content: \"\";\n background-repeat: no-repeat;\n background-position: center center;\n background-size: $custom-control-indicator-bg-size;\n }\n}\n\n\n// Checkboxes\n//\n// Tweak just a few things for checkboxes.\n\n.custom-checkbox {\n .custom-control-label::before {\n @include border-radius($custom-checkbox-indicator-border-radius);\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::before {\n @include gradient-bg($custom-control-indicator-checked-bg);\n }\n &::after {\n background-image: $custom-checkbox-indicator-icon-checked;\n }\n }\n\n .custom-control-input:indeterminate ~ .custom-control-label {\n &::before {\n @include gradient-bg($custom-checkbox-indicator-indeterminate-bg);\n @include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);\n }\n &::after {\n background-image: $custom-checkbox-indicator-icon-indeterminate;\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n background-color: $custom-control-indicator-checked-disabled-bg;\n }\n &:indeterminate ~ .custom-control-label::before {\n background-color: $custom-control-indicator-checked-disabled-bg;\n }\n }\n}\n\n// Radios\n//\n// Tweak just a few things for radios.\n\n.custom-radio {\n .custom-control-label::before {\n border-radius: $custom-radio-indicator-border-radius;\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::before {\n @include gradient-bg($custom-control-indicator-checked-bg);\n }\n &::after {\n background-image: $custom-radio-indicator-icon-checked;\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n background-color: $custom-control-indicator-checked-disabled-bg;\n }\n }\n}\n\n\n// Select\n//\n// Replaces the browser default select with a custom one, mostly pulled from\n// http://primercss.io.\n//\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: $custom-select-height;\n padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;\n line-height: $custom-select-line-height;\n color: $custom-select-color;\n vertical-align: middle;\n background: $custom-select-bg $custom-select-indicator no-repeat right $custom-select-padding-x center;\n background-size: $custom-select-bg-size;\n border: $custom-select-border-width solid $custom-select-border-color;\n @if $enable-rounded {\n border-radius: $custom-select-border-radius;\n } @else {\n border-radius: 0;\n }\n appearance: none;\n\n &:focus {\n border-color: $custom-select-focus-border-color;\n outline: 0;\n box-shadow: $custom-select-focus-box-shadow;\n\n &::-ms-value {\n // For visual consistency with other platforms/browsers,\n // suppress the default white text on blue background highlight given to\n // the selected option text when the (still closed) <select> receives focus\n // in IE and (under certain conditions) Edge.\n // See https://github.com/twbs/bootstrap/issues/19398.\n color: $input-color;\n background-color: $input-bg;\n }\n }\n\n &[multiple],\n &[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: $custom-select-padding-x;\n background-image: none;\n }\n\n &:disabled {\n color: $custom-select-disabled-color;\n background-color: $custom-select-disabled-bg;\n }\n\n // Hides the default caret in IE11\n &::-ms-expand {\n opacity: 0;\n }\n}\n\n.custom-select-sm {\n height: $custom-select-height-sm;\n padding-top: $custom-select-padding-y;\n padding-bottom: $custom-select-padding-y;\n font-size: $custom-select-font-size-sm;\n}\n\n.custom-select-lg {\n height: $custom-select-height-lg;\n padding-top: $custom-select-padding-y;\n padding-bottom: $custom-select-padding-y;\n font-size: $custom-select-font-size-lg;\n}\n\n\n// File\n//\n// Custom file input.\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: $custom-file-height;\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: $custom-file-height;\n margin: 0;\n opacity: 0;\n\n &:focus ~ .custom-file-control {\n border-color: $custom-file-focus-border-color;\n box-shadow: $custom-file-focus-box-shadow;\n\n &::before {\n border-color: $custom-file-focus-border-color;\n }\n }\n\n @each $lang, $value in $custom-file-text {\n &:lang(#{$lang}) ~ .custom-file-label::after {\n content: $value;\n }\n }\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: $custom-file-height;\n padding: $custom-file-padding-y $custom-file-padding-x;\n line-height: $custom-file-line-height;\n color: $custom-file-color;\n background-color: $custom-file-bg;\n border: $custom-file-border-width solid $custom-file-border-color;\n @include border-radius($custom-file-border-radius);\n @include box-shadow($custom-file-box-shadow);\n\n &::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: calc(#{$custom-file-height} - #{$custom-file-border-width} * 2);\n padding: $custom-file-padding-y $custom-file-padding-x;\n line-height: $custom-file-line-height;\n color: $custom-file-button-color;\n content: \"Browse\";\n @include gradient-bg($custom-file-button-bg);\n border-left: $custom-file-border-width solid $custom-file-border-color;\n @include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);\n }\n}\n","// Base class\n//\n// Kickstart any navigation component with a set of style resets. Works with\n// `<nav>`s or `<ul>`s.\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: $nav-link-padding-y $nav-link-padding-x;\n\n @include hover-focus {\n text-decoration: none;\n }\n\n // Disabled state lightens text\n &.disabled {\n color: $nav-link-disabled-color;\n }\n}\n\n//\n// Tabs\n//\n\n.nav-tabs {\n border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;\n\n .nav-item {\n margin-bottom: -$nav-tabs-border-width;\n }\n\n .nav-link {\n border: $nav-tabs-border-width solid transparent;\n @include border-top-radius($nav-tabs-border-radius);\n\n @include hover-focus {\n border-color: $nav-tabs-link-hover-border-color;\n }\n\n &.disabled {\n color: $nav-link-disabled-color;\n background-color: transparent;\n border-color: transparent;\n }\n }\n\n .nav-link.active,\n .nav-item.show .nav-link {\n color: $nav-tabs-link-active-color;\n background-color: $nav-tabs-link-active-bg;\n border-color: $nav-tabs-link-active-border-color;\n }\n\n .dropdown-menu {\n // Make dropdown border overlap tab border\n margin-top: -$nav-tabs-border-width;\n // Remove the top rounded corners here since there is a hard edge above the menu\n @include border-top-radius(0);\n }\n}\n\n\n//\n// Pills\n//\n\n.nav-pills {\n .nav-link {\n @include border-radius($nav-pills-border-radius);\n }\n\n .nav-link.active,\n .show > .nav-link {\n color: $nav-pills-link-active-color;\n background-color: $nav-pills-link-active-bg;\n }\n}\n\n\n//\n// Justified variants\n//\n\n.nav-fill {\n .nav-item {\n flex: 1 1 auto;\n text-align: center;\n }\n}\n\n.nav-justified {\n .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n }\n}\n\n\n// Tabbable tabs\n//\n// Hide tabbable panes to start, show them when `.active`\n\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n","// Contents\n//\n// Navbar\n// Navbar brand\n// Navbar nav\n// Navbar text\n// Navbar divider\n// Responsive navbar\n// Navbar position\n// Navbar themes\n\n\n// Navbar\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n display: flex;\n flex-wrap: wrap; // allow us to do the line break for collapsing content\n align-items: center;\n justify-content: space-between; // space out brand from logo\n padding: $navbar-padding-y $navbar-padding-x;\n\n // Because flex properties aren't inherited, we need to redeclare these first\n // few properities so that content nested within behave properly.\n > .container,\n > .container-fluid {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n }\n}\n\n\n// Navbar brand\n//\n// Used for brand, project, or site names.\n\n.navbar-brand {\n display: inline-block;\n padding-top: $navbar-brand-padding-y;\n padding-bottom: $navbar-brand-padding-y;\n margin-right: $navbar-padding-x;\n font-size: $navbar-brand-font-size;\n line-height: inherit;\n white-space: nowrap;\n\n @include hover-focus {\n text-decoration: none;\n }\n}\n\n\n// Navbar nav\n//\n// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).\n\n.navbar-nav {\n display: flex;\n flex-direction: column; // cannot use `inherit` to get the `.navbar`s value\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n\n .nav-link {\n padding-right: 0;\n padding-left: 0;\n }\n\n .dropdown-menu {\n position: static;\n float: none;\n }\n}\n\n\n// Navbar text\n//\n//\n\n.navbar-text {\n display: inline-block;\n padding-top: $nav-link-padding-y;\n padding-bottom: $nav-link-padding-y;\n}\n\n\n// Responsive navbar\n//\n// Custom styles for responsive collapsing and toggling of navbar contents.\n// Powered by the collapse Bootstrap JavaScript plugin.\n\n// When collapsed, prevent the toggleable navbar contents from appearing in\n// the default flexbox row orienation. Requires the use of `flex-wrap: wrap`\n// on the `.navbar` parent.\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n // For always expanded or extra full navbars, ensure content aligns itself\n // properly vertically. Can be easily overridden with flex utilities.\n align-items: center;\n}\n\n// Button for toggling the navbar when in its collapsed state\n.navbar-toggler {\n padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;\n font-size: $navbar-toggler-font-size;\n line-height: 1;\n background-color: transparent; // remove default button style\n border: $border-width solid transparent; // remove default button style\n @include border-radius($navbar-toggler-border-radius);\n\n @include hover-focus {\n text-decoration: none;\n }\n\n // Opinionated: add \"hand\" cursor to non-disabled .navbar-toggler elements\n &:not(:disabled):not(.disabled) {\n cursor: pointer;\n }\n}\n\n// Keep as a separate element so folks can easily override it with another icon\n// or image file as needed.\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: no-repeat center center;\n background-size: 100% 100%;\n}\n\n// Generate series of `.navbar-expand-*` responsive classes for configuring\n// where your navbar collapses.\n.navbar-expand {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $next: breakpoint-next($breakpoint, $grid-breakpoints);\n $infix: breakpoint-infix($next, $grid-breakpoints);\n\n &#{$infix} {\n @include media-breakpoint-down($breakpoint) {\n > .container,\n > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n }\n\n @include media-breakpoint-up($next) {\n flex-flow: row nowrap;\n justify-content: flex-start;\n\n .navbar-nav {\n flex-direction: row;\n\n .dropdown-menu {\n position: absolute;\n }\n\n .dropdown-menu-right {\n right: 0;\n left: auto; // Reset the default from `.dropdown-menu`\n }\n\n .nav-link {\n padding-right: $navbar-nav-link-padding-x;\n padding-left: $navbar-nav-link-padding-x;\n }\n }\n\n // For nesting containers, have to redeclare for alignment purposes\n > .container,\n > .container-fluid {\n flex-wrap: nowrap;\n }\n\n .navbar-collapse {\n display: flex !important; // stylelint-disable-line declaration-no-important\n\n // Changes flex-bases to auto because of an IE10 bug\n flex-basis: auto;\n }\n\n .navbar-toggler {\n display: none;\n }\n\n .dropup {\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n }\n }\n }\n }\n}\n\n\n// Navbar themes\n//\n// Styles for switching between navbars with light or dark background.\n\n// Dark links against a light background\n.navbar-light {\n .navbar-brand {\n color: $navbar-light-active-color;\n\n @include hover-focus {\n color: $navbar-light-active-color;\n }\n }\n\n .navbar-nav {\n .nav-link {\n color: $navbar-light-color;\n\n @include hover-focus {\n color: $navbar-light-hover-color;\n }\n\n &.disabled {\n color: $navbar-light-disabled-color;\n }\n }\n\n .show > .nav-link,\n .active > .nav-link,\n .nav-link.show,\n .nav-link.active {\n color: $navbar-light-active-color;\n }\n }\n\n .navbar-toggler {\n color: $navbar-light-color;\n border-color: $navbar-light-toggler-border-color;\n }\n\n .navbar-toggler-icon {\n background-image: $navbar-light-toggler-icon-bg;\n }\n\n .navbar-text {\n color: $navbar-light-color;\n a {\n color: $navbar-light-active-color;\n\n @include hover-focus {\n color: $navbar-light-active-color;\n }\n }\n }\n}\n\n// White links against a dark background\n.navbar-dark {\n .navbar-brand {\n color: $navbar-dark-active-color;\n\n @include hover-focus {\n color: $navbar-dark-active-color;\n }\n }\n\n .navbar-nav {\n .nav-link {\n color: $navbar-dark-color;\n\n @include hover-focus {\n color: $navbar-dark-hover-color;\n }\n\n &.disabled {\n color: $navbar-dark-disabled-color;\n }\n }\n\n .show > .nav-link,\n .active > .nav-link,\n .nav-link.show,\n .nav-link.active {\n color: $navbar-dark-active-color;\n }\n }\n\n .navbar-toggler {\n color: $navbar-dark-color;\n border-color: $navbar-dark-toggler-border-color;\n }\n\n .navbar-toggler-icon {\n background-image: $navbar-dark-toggler-icon-bg;\n }\n\n .navbar-text {\n color: $navbar-dark-color;\n a {\n color: $navbar-dark-active-color;\n\n @include hover-focus {\n color: $navbar-dark-active-color;\n }\n }\n }\n}\n","//\n// Base styles\n//\n\n.card {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n word-wrap: break-word;\n background-color: $card-bg;\n background-clip: border-box;\n border: $card-border-width solid $card-border-color;\n @include border-radius($card-border-radius);\n\n > hr {\n margin-right: 0;\n margin-left: 0;\n }\n\n > .list-group:first-child {\n .list-group-item:first-child {\n @include border-top-radius($card-border-radius);\n }\n }\n\n > .list-group:last-child {\n .list-group-item:last-child {\n @include border-bottom-radius($card-border-radius);\n }\n }\n}\n\n.card-body {\n // Enable `flex-grow: 1` for decks and groups so that card blocks take up\n // as much space as possible, ensuring footers are aligned to the bottom.\n flex: 1 1 auto;\n padding: $card-spacer-x;\n}\n\n.card-title {\n margin-bottom: $card-spacer-y;\n}\n\n.card-subtitle {\n margin-top: -($card-spacer-y / 2);\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link {\n @include hover {\n text-decoration: none;\n }\n\n + .card-link {\n margin-left: $card-spacer-x;\n }\n}\n\n//\n// Optional textual caps\n//\n\n.card-header {\n padding: $card-spacer-y $card-spacer-x;\n margin-bottom: 0; // Removes the default margin-bottom of <hN>\n background-color: $card-cap-bg;\n border-bottom: $card-border-width solid $card-border-color;\n\n &:first-child {\n @include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);\n }\n\n + .list-group {\n .list-group-item:first-child {\n border-top: 0;\n }\n }\n}\n\n.card-footer {\n padding: $card-spacer-y $card-spacer-x;\n background-color: $card-cap-bg;\n border-top: $card-border-width solid $card-border-color;\n\n &:last-child {\n @include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);\n }\n}\n\n\n//\n// Header navs\n//\n\n.card-header-tabs {\n margin-right: -($card-spacer-x / 2);\n margin-bottom: -$card-spacer-y;\n margin-left: -($card-spacer-x / 2);\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -($card-spacer-x / 2);\n margin-left: -($card-spacer-x / 2);\n}\n\n// Card image\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: $card-img-overlay-padding;\n}\n\n.card-img {\n width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch\n @include border-radius($card-inner-border-radius);\n}\n\n// Card image caps\n.card-img-top {\n width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch\n @include border-top-radius($card-inner-border-radius);\n}\n\n.card-img-bottom {\n width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch\n @include border-bottom-radius($card-inner-border-radius);\n}\n\n\n// Card deck\n\n.card-deck {\n display: flex;\n flex-direction: column;\n\n .card {\n margin-bottom: $card-deck-margin;\n }\n\n @include media-breakpoint-up(sm) {\n flex-flow: row wrap;\n margin-right: -$card-deck-margin;\n margin-left: -$card-deck-margin;\n\n .card {\n display: flex;\n // Flexbugs #4: https://github.com/philipwalton/flexbugs#4-flex-shorthand-declarations-with-unitless-flex-basis-values-are-ignored\n flex: 1 0 0%;\n flex-direction: column;\n margin-right: $card-deck-margin;\n margin-bottom: 0; // Override the default\n margin-left: $card-deck-margin;\n }\n }\n}\n\n\n//\n// Card groups\n//\n\n.card-group {\n display: flex;\n flex-direction: column;\n\n // The child selector allows nested `.card` within `.card-group`\n // to display properly.\n > .card {\n margin-bottom: $card-group-margin;\n }\n\n @include media-breakpoint-up(sm) {\n flex-flow: row wrap;\n // The child selector allows nested `.card` within `.card-group`\n // to display properly.\n > .card {\n // Flexbugs #4: https://github.com/philipwalton/flexbugs#4-flex-shorthand-declarations-with-unitless-flex-basis-values-are-ignored\n flex: 1 0 0%;\n margin-bottom: 0;\n\n + .card {\n margin-left: 0;\n border-left: 0;\n }\n\n // Handle rounded corners\n @if $enable-rounded {\n &:first-child {\n @include border-right-radius(0);\n\n .card-img-top,\n .card-header {\n border-top-right-radius: 0;\n }\n .card-img-bottom,\n .card-footer {\n border-bottom-right-radius: 0;\n }\n }\n\n &:last-child {\n @include border-left-radius(0);\n\n .card-img-top,\n .card-header {\n border-top-left-radius: 0;\n }\n .card-img-bottom,\n .card-footer {\n border-bottom-left-radius: 0;\n }\n }\n\n &:only-child {\n @include border-radius($card-border-radius);\n\n .card-img-top,\n .card-header {\n @include border-top-radius($card-border-radius);\n }\n .card-img-bottom,\n .card-footer {\n @include border-bottom-radius($card-border-radius);\n }\n }\n\n &:not(:first-child):not(:last-child):not(:only-child) {\n @include border-radius(0);\n\n .card-img-top,\n .card-img-bottom,\n .card-header,\n .card-footer {\n @include border-radius(0);\n }\n }\n }\n }\n }\n}\n\n\n//\n// Columns\n//\n\n.card-columns {\n .card {\n margin-bottom: $card-columns-margin;\n }\n\n @include media-breakpoint-up(sm) {\n column-count: $card-columns-count;\n column-gap: $card-columns-gap;\n\n .card {\n display: inline-block; // Don't let them vertically span multiple columns\n width: 100%; // Don't let their width change\n }\n }\n}\n",".breadcrumb {\n display: flex;\n flex-wrap: wrap;\n padding: $breadcrumb-padding-y $breadcrumb-padding-x;\n margin-bottom: $breadcrumb-margin-bottom;\n list-style: none;\n background-color: $breadcrumb-bg;\n @include border-radius($border-radius);\n}\n\n.breadcrumb-item {\n // The separator between breadcrumbs (by default, a forward-slash: \"/\")\n + .breadcrumb-item::before {\n display: inline-block; // Suppress underlining of the separator in modern browsers\n padding-right: $breadcrumb-item-padding;\n padding-left: $breadcrumb-item-padding;\n color: $breadcrumb-divider-color;\n content: \"#{$breadcrumb-divider}\";\n }\n\n // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built\n // without `<ul>`s. The `::before` pseudo-element generates an element\n // *within* the .breadcrumb-item and thereby inherits the `text-decoration`.\n //\n // To trick IE into suppressing the underline, we give the pseudo-element an\n // underline and then immediately remove it.\n + .breadcrumb-item:hover::before {\n text-decoration: underline;\n }\n // stylelint-disable-next-line no-duplicate-selectors\n + .breadcrumb-item:hover::before {\n text-decoration: none;\n }\n\n &.active {\n color: $breadcrumb-active-color;\n }\n}\n",".pagination {\n display: flex;\n @include list-unstyled();\n @include border-radius();\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: $pagination-padding-y $pagination-padding-x;\n margin-left: -$pagination-border-width;\n line-height: $pagination-line-height;\n color: $pagination-color;\n background-color: $pagination-bg;\n border: $pagination-border-width solid $pagination-border-color;\n\n &:hover {\n color: $pagination-hover-color;\n text-decoration: none;\n background-color: $pagination-hover-bg;\n border-color: $pagination-hover-border-color;\n }\n\n &:focus {\n z-index: 2;\n outline: 0;\n box-shadow: $pagination-focus-box-shadow;\n }\n\n // Opinionated: add \"hand\" cursor to non-disabled .page-link elements\n &:not(:disabled):not(.disabled) {\n cursor: pointer;\n }\n}\n\n.page-item {\n &:first-child {\n .page-link {\n margin-left: 0;\n @include border-left-radius($border-radius);\n }\n }\n &:last-child {\n .page-link {\n @include border-right-radius($border-radius);\n }\n }\n\n &.active .page-link {\n z-index: 1;\n color: $pagination-active-color;\n background-color: $pagination-active-bg;\n border-color: $pagination-active-border-color;\n }\n\n &.disabled .page-link {\n color: $pagination-disabled-color;\n pointer-events: none;\n // Opinionated: remove the \"hand\" cursor set previously for .page-link\n cursor: auto;\n background-color: $pagination-disabled-bg;\n border-color: $pagination-disabled-border-color;\n }\n}\n\n\n//\n// Sizing\n//\n\n.pagination-lg {\n @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg);\n}\n\n.pagination-sm {\n @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm);\n}\n","// Pagination\n\n@mixin pagination-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {\n .page-link {\n padding: $padding-y $padding-x;\n font-size: $font-size;\n line-height: $line-height;\n }\n\n .page-item {\n &:first-child {\n .page-link {\n @include border-left-radius($border-radius);\n }\n }\n &:last-child {\n .page-link {\n @include border-right-radius($border-radius);\n }\n }\n }\n}\n","// Base class\n//\n// Requires one of the contextual, color modifier classes for `color` and\n// `background-color`.\n\n.badge {\n display: inline-block;\n padding: $badge-padding-y $badge-padding-x;\n font-size: $badge-font-size;\n font-weight: $badge-font-weight;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n @include border-radius($badge-border-radius);\n\n // Empty badges collapse automatically\n &:empty {\n display: none;\n }\n}\n\n// Quick fix for badges in buttons\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n// Pill badges\n//\n// Make them extra rounded with a modifier to replace v3's badges.\n\n.badge-pill {\n padding-right: $badge-pill-padding-x;\n padding-left: $badge-pill-padding-x;\n @include border-radius($badge-pill-border-radius);\n}\n\n// Colors\n//\n// Contextual variations (linked badges get darker on :hover).\n\n@each $color, $value in $theme-colors {\n .badge-#{$color} {\n @include badge-variant($value);\n }\n}\n","@mixin badge-variant($bg) {\n color: color-yiq($bg);\n background-color: $bg;\n\n &[href] {\n @include hover-focus {\n color: color-yiq($bg);\n text-decoration: none;\n background-color: darken($bg, 10%);\n }\n }\n}\n",".jumbotron {\n padding: $jumbotron-padding ($jumbotron-padding / 2);\n margin-bottom: $jumbotron-padding;\n background-color: $jumbotron-bg;\n @include border-radius($border-radius-lg);\n\n @include media-breakpoint-up(sm) {\n padding: ($jumbotron-padding * 2) $jumbotron-padding;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n @include border-radius(0);\n}\n","//\n// Base styles\n//\n\n.alert {\n position: relative;\n padding: $alert-padding-y $alert-padding-x;\n margin-bottom: $alert-margin-bottom;\n border: $alert-border-width solid transparent;\n @include border-radius($alert-border-radius);\n}\n\n// Headings for larger alerts\n.alert-heading {\n // Specified to prevent conflicts of changing $headings-color\n color: inherit;\n}\n\n// Provide class for links that match alerts\n.alert-link {\n font-weight: $alert-link-font-weight;\n}\n\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissible {\n padding-right: ($close-font-size + $alert-padding-x * 2);\n\n // Adjust close link position\n .close {\n position: absolute;\n top: 0;\n right: 0;\n padding: $alert-padding-y $alert-padding-x;\n color: inherit;\n }\n}\n\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n@each $color, $value in $theme-colors {\n .alert-#{$color} {\n @include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));\n }\n}\n","@mixin alert-variant($background, $border, $color) {\n color: $color;\n @include gradient-bg($background);\n border-color: $border;\n\n hr {\n border-top-color: darken($border, 5%);\n }\n\n .alert-link {\n color: darken($color, 10%);\n }\n}\n","@keyframes progress-bar-stripes {\n from { background-position: $progress-height 0; }\n to { background-position: 0 0; }\n}\n\n.progress {\n display: flex;\n height: $progress-height;\n overflow: hidden; // force rounded corners by cropping it\n font-size: $progress-font-size;\n background-color: $progress-bg;\n @include border-radius($progress-border-radius);\n @include box-shadow($progress-box-shadow);\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n color: $progress-bar-color;\n text-align: center;\n background-color: $progress-bar-bg;\n @include transition($progress-bar-transition);\n}\n\n.progress-bar-striped {\n @include gradient-striped();\n background-size: $progress-height $progress-height;\n}\n\n.progress-bar-animated {\n animation: progress-bar-stripes $progress-bar-animation-timing;\n}\n",".media {\n display: flex;\n align-items: flex-start;\n}\n\n.media-body {\n flex: 1;\n}\n","// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n display: flex;\n flex-direction: column;\n\n // No need to set list-style: none; since .list-group-item is block level\n padding-left: 0; // reset padding because ul and ol\n margin-bottom: 0;\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive\n// list items. Includes an extra `.active` modifier class for selected items.\n\n.list-group-item-action {\n width: 100%; // For `<button>`s (anchors become 100% by default though)\n color: $list-group-action-color;\n text-align: inherit; // For `<button>`s (anchors inherit)\n\n // Hover state\n @include hover-focus {\n color: $list-group-action-hover-color;\n text-decoration: none;\n background-color: $list-group-hover-bg;\n }\n\n &:active {\n color: $list-group-action-active-color;\n background-color: $list-group-action-active-bg;\n }\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: $list-group-item-padding-y $list-group-item-padding-x;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -$list-group-border-width;\n background-color: $list-group-bg;\n border: $list-group-border-width solid $list-group-border-color;\n\n &:first-child {\n @include border-top-radius($list-group-border-radius);\n }\n\n &:last-child {\n margin-bottom: 0;\n @include border-bottom-radius($list-group-border-radius);\n }\n\n @include hover-focus {\n z-index: 1; // Place hover/active items above their siblings for proper border styling\n text-decoration: none;\n }\n\n &.disabled,\n &:disabled {\n color: $list-group-disabled-color;\n background-color: $list-group-disabled-bg;\n }\n\n // Include both here for `<a>`s and `<button>`s\n &.active {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: $list-group-active-color;\n background-color: $list-group-active-bg;\n border-color: $list-group-active-border-color;\n }\n}\n\n\n// Flush list items\n//\n// Remove borders and border-radius to keep list group items edge-to-edge. Most\n// useful within other components (e.g., cards).\n\n.list-group-flush {\n .list-group-item {\n border-right: 0;\n border-left: 0;\n @include border-radius(0);\n }\n\n &:first-child {\n .list-group-item:first-child {\n border-top: 0;\n }\n }\n\n &:last-child {\n .list-group-item:last-child {\n border-bottom: 0;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n@each $color, $value in $theme-colors {\n @include list-group-item-variant($color, theme-color-level($color, -9), theme-color-level($color, 6));\n}\n","// List Groups\n\n@mixin list-group-item-variant($state, $background, $color) {\n .list-group-item-#{$state} {\n color: $color;\n background-color: $background;\n\n &.list-group-item-action {\n @include hover-focus {\n color: $color;\n background-color: darken($background, 5%);\n }\n\n &.active {\n color: #fff;\n background-color: $color;\n border-color: $color;\n }\n }\n }\n}\n",".close {\n float: right;\n font-size: $close-font-size;\n font-weight: $close-font-weight;\n line-height: 1;\n color: $close-color;\n text-shadow: $close-text-shadow;\n opacity: .5;\n\n @include hover-focus {\n color: $close-color;\n text-decoration: none;\n opacity: .75;\n }\n\n // Opinionated: add \"hand\" cursor to non-disabled .close elements\n &:not(:disabled):not(.disabled) {\n cursor: pointer;\n }\n}\n\n// Additional properties for button version\n// iOS requires the button element instead of an anchor tag.\n// If you want the anchor version, it requires `href=\"#\"`.\n// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n// stylelint-disable property-no-vendor-prefix, selector-no-qualifying-type\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n// stylelint-enable\n","// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and stuff\n\n\n// Kill the scroll on the body\n.modal-open {\n overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: $zindex-modal;\n display: none;\n overflow: hidden;\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a\n // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342\n // See also https://github.com/twbs/bootstrap/issues/17695\n\n .modal-open & {\n overflow-x: hidden;\n overflow-y: auto;\n }\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: $modal-dialog-margin;\n // allow clicks to pass through for custom click handling to close modal\n pointer-events: none;\n\n // When fading in the modal, animate it to slide down\n .modal.fade & {\n @include transition($modal-transition);\n transform: translate(0, -25%);\n }\n .modal.show & {\n transform: translate(0, 0);\n }\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: calc(100% - (#{$modal-dialog-margin} * 2));\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`\n // counteract the pointer-events: none; in the .modal-dialog\n pointer-events: auto;\n background-color: $modal-content-bg;\n background-clip: padding-box;\n border: $modal-content-border-width solid $modal-content-border-color;\n @include border-radius($border-radius-lg);\n @include box-shadow($modal-content-box-shadow-xs);\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: $zindex-modal-backdrop;\n background-color: $modal-backdrop-bg;\n\n // Fade for backdrop\n &.fade { opacity: 0; }\n &.show { opacity: $modal-backdrop-opacity; }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n display: flex;\n align-items: flex-start; // so the close btn always stays on the upper right corner\n justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends\n padding: $modal-header-padding;\n border-bottom: $modal-header-border-width solid $modal-header-border-color;\n @include border-top-radius($border-radius-lg);\n\n .close {\n padding: $modal-header-padding;\n // auto on the left force icon to the right even when there is no .modal-title\n margin: (-$modal-header-padding) (-$modal-header-padding) (-$modal-header-padding) auto;\n }\n}\n\n// Title text within header\n.modal-title {\n margin-bottom: 0;\n line-height: $modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n // Enable `flex-grow: 1` so that the body take up as much space as possible\n // when should there be a fixed height on `.modal-dialog`.\n flex: 1 1 auto;\n padding: $modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n display: flex;\n align-items: center; // vertically center\n justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items\n padding: $modal-inner-padding;\n border-top: $modal-footer-border-width solid $modal-footer-border-color;\n\n // Easily place margin between footer elements\n > :not(:first-child) { margin-left: .25rem; }\n > :not(:last-child) { margin-right: .25rem; }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@include media-breakpoint-up(sm) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n max-width: $modal-md;\n margin: $modal-dialog-margin-y-sm-up auto;\n }\n\n .modal-dialog-centered {\n min-height: calc(100% - (#{$modal-dialog-margin-y-sm-up} * 2));\n }\n\n .modal-content {\n @include box-shadow($modal-content-box-shadow-sm-up);\n }\n\n .modal-sm { max-width: $modal-sm; }\n\n}\n\n@include media-breakpoint-up(lg) {\n .modal-lg { max-width: $modal-lg; }\n}\n","// Base class\n.tooltip {\n position: absolute;\n z-index: $zindex-tooltip;\n display: block;\n margin: $tooltip-margin;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n @include reset-text();\n font-size: $tooltip-font-size;\n // Allow breaking very long words so they don't overflow the tooltip's bounds\n word-wrap: break-word;\n opacity: 0;\n\n &.show { opacity: $tooltip-opacity; }\n\n .arrow {\n position: absolute;\n display: block;\n width: $tooltip-arrow-width;\n height: $tooltip-arrow-height;\n\n &::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n }\n }\n}\n\n.bs-tooltip-top {\n padding: $tooltip-arrow-height 0;\n\n .arrow {\n bottom: 0;\n\n &::before {\n top: 0;\n border-width: $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;\n border-top-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-right {\n padding: 0 $tooltip-arrow-height;\n\n .arrow {\n left: 0;\n width: $tooltip-arrow-height;\n height: $tooltip-arrow-width;\n\n &::before {\n right: 0;\n border-width: ($tooltip-arrow-width / 2) $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;\n border-right-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-bottom {\n padding: $tooltip-arrow-height 0;\n\n .arrow {\n top: 0;\n\n &::before {\n bottom: 0;\n border-width: 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;\n border-bottom-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-left {\n padding: 0 $tooltip-arrow-height;\n\n .arrow {\n right: 0;\n width: $tooltip-arrow-height;\n height: $tooltip-arrow-width;\n\n &::before {\n left: 0;\n border-width: ($tooltip-arrow-width / 2) 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;\n border-left-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-auto {\n &[x-placement^=\"top\"] {\n @extend .bs-tooltip-top;\n }\n &[x-placement^=\"right\"] {\n @extend .bs-tooltip-right;\n }\n &[x-placement^=\"bottom\"] {\n @extend .bs-tooltip-bottom;\n }\n &[x-placement^=\"left\"] {\n @extend .bs-tooltip-left;\n }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: $tooltip-max-width;\n padding: $tooltip-padding-y $tooltip-padding-x;\n color: $tooltip-color;\n text-align: center;\n background-color: $tooltip-bg;\n @include border-radius($tooltip-border-radius);\n}\n","@mixin reset-text {\n font-family: $font-family-base;\n // We deliberately do NOT reset font-size or word-wrap.\n font-style: normal;\n font-weight: $font-weight-normal;\n line-height: $line-height-base;\n text-align: left; // Fallback for where `start` is not supported\n text-align: start; // stylelint-disable-line declaration-block-no-duplicate-properties\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n}\n",".popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: $zindex-popover;\n display: block;\n max-width: $popover-max-width;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n @include reset-text();\n font-size: $popover-font-size;\n // Allow breaking very long words so they don't overflow the popover's bounds\n word-wrap: break-word;\n background-color: $popover-bg;\n background-clip: padding-box;\n border: $popover-border-width solid $popover-border-color;\n @include border-radius($popover-border-radius);\n @include box-shadow($popover-box-shadow);\n\n .arrow {\n position: absolute;\n display: block;\n width: $popover-arrow-width;\n height: $popover-arrow-height;\n margin: 0 $border-radius-lg;\n\n &::before,\n &::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n }\n }\n}\n\n.bs-popover-top {\n margin-bottom: $popover-arrow-height;\n\n .arrow {\n bottom: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);\n }\n\n .arrow::before,\n .arrow::after {\n border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;\n }\n\n .arrow::before {\n bottom: 0;\n border-top-color: $popover-arrow-outer-color;\n }\n\n .arrow::after {\n bottom: $popover-border-width;\n border-top-color: $popover-arrow-color;\n }\n}\n\n.bs-popover-right {\n margin-left: $popover-arrow-height;\n\n .arrow {\n left: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);\n width: $popover-arrow-height;\n height: $popover-arrow-width;\n margin: $border-radius-lg 0; // make sure the arrow does not touch the popover's rounded corners\n }\n\n .arrow::before,\n .arrow::after {\n border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;\n }\n\n .arrow::before {\n left: 0;\n border-right-color: $popover-arrow-outer-color;\n }\n\n .arrow::after {\n left: $popover-border-width;\n border-right-color: $popover-arrow-color;\n }\n}\n\n.bs-popover-bottom {\n margin-top: $popover-arrow-height;\n\n .arrow {\n top: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);\n }\n\n .arrow::before,\n .arrow::after {\n border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);\n }\n\n .arrow::before {\n top: 0;\n border-bottom-color: $popover-arrow-outer-color;\n }\n\n .arrow::after {\n top: $popover-border-width;\n border-bottom-color: $popover-arrow-color;\n }\n\n // This will remove the popover-header's border just below the arrow\n .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: $popover-arrow-width;\n margin-left: ($popover-arrow-width / -2);\n content: \"\";\n border-bottom: $popover-border-width solid $popover-header-bg;\n }\n}\n\n.bs-popover-left {\n margin-right: $popover-arrow-height;\n\n .arrow {\n right: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);\n width: $popover-arrow-height;\n height: $popover-arrow-width;\n margin: $border-radius-lg 0; // make sure the arrow does not touch the popover's rounded corners\n }\n\n .arrow::before,\n .arrow::after {\n border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;\n }\n\n .arrow::before {\n right: 0;\n border-left-color: $popover-arrow-outer-color;\n }\n\n .arrow::after {\n right: $popover-border-width;\n border-left-color: $popover-arrow-color;\n }\n}\n\n.bs-popover-auto {\n &[x-placement^=\"top\"] {\n @extend .bs-popover-top;\n }\n &[x-placement^=\"right\"] {\n @extend .bs-popover-right;\n }\n &[x-placement^=\"bottom\"] {\n @extend .bs-popover-bottom;\n }\n &[x-placement^=\"left\"] {\n @extend .bs-popover-left;\n }\n}\n\n\n// Offset the popover to account for the popover arrow\n.popover-header {\n padding: $popover-header-padding-y $popover-header-padding-x;\n margin-bottom: 0; // Reset the default from Reboot\n font-size: $font-size-base;\n color: $popover-header-color;\n background-color: $popover-header-bg;\n border-bottom: $popover-border-width solid darken($popover-header-bg, 5%);\n $offset-border-width: calc(#{$border-radius-lg} - #{$popover-border-width});\n @include border-top-radius($offset-border-width);\n\n &:empty {\n display: none;\n }\n}\n\n.popover-body {\n padding: $popover-body-padding-y $popover-body-padding-x;\n color: $popover-body-color;\n}\n","// Wrapper for the slide container and indicators\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n\n.carousel-item {\n position: relative;\n display: none;\n align-items: center;\n width: 100%;\n @include transition($carousel-transition);\n backface-visibility: hidden;\n perspective: 1000px;\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next,\n.carousel-item-prev {\n position: absolute;\n top: 0;\n}\n\n// CSS3 transforms when supported by the browser\n.carousel-item-next.carousel-item-left,\n.carousel-item-prev.carousel-item-right {\n transform: translateX(0);\n\n @supports (transform-style: preserve-3d) {\n transform: translate3d(0, 0, 0);\n }\n}\n\n.carousel-item-next,\n.active.carousel-item-right {\n transform: translateX(100%);\n\n @supports (transform-style: preserve-3d) {\n transform: translate3d(100%, 0, 0);\n }\n}\n\n.carousel-item-prev,\n.active.carousel-item-left {\n transform: translateX(-100%);\n\n @supports (transform-style: preserve-3d) {\n transform: translate3d(-100%, 0, 0);\n }\n}\n\n\n//\n// Left/right controls for nav\n//\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n // Use flex for alignment (1-3)\n display: flex; // 1. allow flex styles\n align-items: center; // 2. vertically center contents\n justify-content: center; // 3. horizontally center contents\n width: $carousel-control-width;\n color: $carousel-control-color;\n text-align: center;\n opacity: $carousel-control-opacity;\n // We can't have a transition here because WebKit cancels the carousel\n // animation if you trip this while in the middle of another animation.\n\n // Hover/focus state\n @include hover-focus {\n color: $carousel-control-color;\n text-decoration: none;\n outline: 0;\n opacity: .9;\n }\n}\n.carousel-control-prev {\n left: 0;\n @if $enable-gradients {\n background: linear-gradient(90deg, rgba(0, 0, 0, .25), rgba(0, 0, 0, .001));\n }\n}\n.carousel-control-next {\n right: 0;\n @if $enable-gradients {\n background: linear-gradient(270deg, rgba(0, 0, 0, .25), rgba(0, 0, 0, .001));\n }\n}\n\n// Icons for within\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: $carousel-control-icon-width;\n height: $carousel-control-icon-width;\n background: transparent no-repeat center center;\n background-size: 100% 100%;\n}\n.carousel-control-prev-icon {\n background-image: $carousel-control-prev-icon-bg;\n}\n.carousel-control-next-icon {\n background-image: $carousel-control-next-icon-bg;\n}\n\n\n// Optional indicator pips\n//\n// Add an ordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 10px;\n left: 0;\n z-index: 15;\n display: flex;\n justify-content: center;\n padding-left: 0; // override <ol> default\n // Use the .carousel-control's width as margin so we don't overlay those\n margin-right: $carousel-control-width;\n margin-left: $carousel-control-width;\n list-style: none;\n\n li {\n position: relative;\n flex: 0 1 auto;\n width: $carousel-indicator-width;\n height: $carousel-indicator-height;\n margin-right: $carousel-indicator-spacer;\n margin-left: $carousel-indicator-spacer;\n text-indent: -999px;\n background-color: rgba($carousel-indicator-active-bg, .5);\n\n // Use pseudo classes to increase the hit area by 10px on top and bottom.\n &::before {\n position: absolute;\n top: -10px;\n left: 0;\n display: inline-block;\n width: 100%;\n height: 10px;\n content: \"\";\n }\n &::after {\n position: absolute;\n bottom: -10px;\n left: 0;\n display: inline-block;\n width: 100%;\n height: 10px;\n content: \"\";\n }\n }\n\n .active {\n background-color: $carousel-indicator-active-bg;\n }\n}\n\n\n// Optional captions\n//\n//\n\n.carousel-caption {\n position: absolute;\n right: ((100% - $carousel-caption-width) / 2);\n bottom: 20px;\n left: ((100% - $carousel-caption-width) / 2);\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: $carousel-caption-color;\n text-align: center;\n}\n","// stylelint-disable declaration-no-important\n\n.align-baseline { vertical-align: baseline !important; } // Browser default\n.align-top { vertical-align: top !important; }\n.align-middle { vertical-align: middle !important; }\n.align-bottom { vertical-align: bottom !important; }\n.align-text-bottom { vertical-align: text-bottom !important; }\n.align-text-top { vertical-align: text-top !important; }\n","// stylelint-disable declaration-no-important\n\n// Contextual backgrounds\n\n@mixin bg-variant($parent, $color) {\n #{$parent} {\n background-color: $color !important;\n }\n a#{$parent},\n button#{$parent} {\n @include hover-focus {\n background-color: darken($color, 10%) !important;\n }\n }\n}\n\n@mixin bg-gradient-variant($parent, $color) {\n #{$parent} {\n background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important;\n }\n}\n","// stylelint-disable declaration-no-important\n\n@each $color, $value in $theme-colors {\n @include bg-variant(\".bg-#{$color}\", $value);\n}\n\n@if $enable-gradients {\n @each $color, $value in $theme-colors {\n @include bg-gradient-variant(\".bg-gradient-#{$color}\", $value);\n }\n}\n\n.bg-white {\n background-color: $white !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Border\n//\n\n.border { border: $border-width solid $border-color !important; }\n.border-top { border-top: $border-width solid $border-color !important; }\n.border-right { border-right: $border-width solid $border-color !important; }\n.border-bottom { border-bottom: $border-width solid $border-color !important; }\n.border-left { border-left: $border-width solid $border-color !important; }\n\n.border-0 { border: 0 !important; }\n.border-top-0 { border-top: 0 !important; }\n.border-right-0 { border-right: 0 !important; }\n.border-bottom-0 { border-bottom: 0 !important; }\n.border-left-0 { border-left: 0 !important; }\n\n@each $color, $value in $theme-colors {\n .border-#{$color} {\n border-color: $value !important;\n }\n}\n\n.border-white {\n border-color: $white !important;\n}\n\n//\n// Border-radius\n//\n\n.rounded {\n border-radius: $border-radius !important;\n}\n.rounded-top {\n border-top-left-radius: $border-radius !important;\n border-top-right-radius: $border-radius !important;\n}\n.rounded-right {\n border-top-right-radius: $border-radius !important;\n border-bottom-right-radius: $border-radius !important;\n}\n.rounded-bottom {\n border-bottom-right-radius: $border-radius !important;\n border-bottom-left-radius: $border-radius !important;\n}\n.rounded-left {\n border-top-left-radius: $border-radius !important;\n border-bottom-left-radius: $border-radius !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n","@mixin clearfix() {\n &::after {\n display: block;\n clear: both;\n content: \"\";\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Utilities for common `display` values\n//\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .d#{$infix}-none { display: none !important; }\n .d#{$infix}-inline { display: inline !important; }\n .d#{$infix}-inline-block { display: inline-block !important; }\n .d#{$infix}-block { display: block !important; }\n .d#{$infix}-table { display: table !important; }\n .d#{$infix}-table-row { display: table-row !important; }\n .d#{$infix}-table-cell { display: table-cell !important; }\n .d#{$infix}-flex { display: flex !important; }\n .d#{$infix}-inline-flex { display: inline-flex !important; }\n }\n}\n\n\n//\n// Utilities for toggling `display` in print\n//\n\n@media print {\n .d-print-none { display: none !important; }\n .d-print-inline { display: inline !important; }\n .d-print-inline-block { display: inline-block !important; }\n .d-print-block { display: block !important; }\n .d-print-table { display: table !important; }\n .d-print-table-row { display: table-row !important; }\n .d-print-table-cell { display: table-cell !important; }\n .d-print-flex { display: flex !important; }\n .d-print-inline-flex { display: inline-flex !important; }\n}\n","// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n\n &::before {\n display: block;\n content: \"\";\n }\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n }\n}\n\n.embed-responsive-21by9 {\n &::before {\n padding-top: percentage(9 / 21);\n }\n}\n\n.embed-responsive-16by9 {\n &::before {\n padding-top: percentage(9 / 16);\n }\n}\n\n.embed-responsive-4by3 {\n &::before {\n padding-top: percentage(3 / 4);\n }\n}\n\n.embed-responsive-1by1 {\n &::before {\n padding-top: percentage(1 / 1);\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Flex variation\n//\n// Custom styles for additional flex alignment options.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .flex#{$infix}-row { flex-direction: row !important; }\n .flex#{$infix}-column { flex-direction: column !important; }\n .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }\n .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }\n\n .flex#{$infix}-wrap { flex-wrap: wrap !important; }\n .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }\n .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }\n\n .justify-content#{$infix}-start { justify-content: flex-start !important; }\n .justify-content#{$infix}-end { justify-content: flex-end !important; }\n .justify-content#{$infix}-center { justify-content: center !important; }\n .justify-content#{$infix}-between { justify-content: space-between !important; }\n .justify-content#{$infix}-around { justify-content: space-around !important; }\n\n .align-items#{$infix}-start { align-items: flex-start !important; }\n .align-items#{$infix}-end { align-items: flex-end !important; }\n .align-items#{$infix}-center { align-items: center !important; }\n .align-items#{$infix}-baseline { align-items: baseline !important; }\n .align-items#{$infix}-stretch { align-items: stretch !important; }\n\n .align-content#{$infix}-start { align-content: flex-start !important; }\n .align-content#{$infix}-end { align-content: flex-end !important; }\n .align-content#{$infix}-center { align-content: center !important; }\n .align-content#{$infix}-between { align-content: space-between !important; }\n .align-content#{$infix}-around { align-content: space-around !important; }\n .align-content#{$infix}-stretch { align-content: stretch !important; }\n\n .align-self#{$infix}-auto { align-self: auto !important; }\n .align-self#{$infix}-start { align-self: flex-start !important; }\n .align-self#{$infix}-end { align-self: flex-end !important; }\n .align-self#{$infix}-center { align-self: center !important; }\n .align-self#{$infix}-baseline { align-self: baseline !important; }\n .align-self#{$infix}-stretch { align-self: stretch !important; }\n }\n}\n","@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .float#{$infix}-left { @include float-left; }\n .float#{$infix}-right { @include float-right; }\n .float#{$infix}-none { @include float-none; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n@mixin float-left {\n float: left !important;\n}\n@mixin float-right {\n float: right !important;\n}\n@mixin float-none {\n float: none !important;\n}\n","// stylelint-disable declaration-no-important\n\n// Common values\n\n// Sass list not in variables since it's not intended for customization.\n$positions: static, relative, absolute, fixed, sticky;\n\n@each $position in $positions {\n .position-#{$position} { position: $position !important; }\n}\n\n// Shorthand\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: $zindex-fixed;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: $zindex-fixed;\n}\n\n.sticky-top {\n @supports (position: sticky) {\n position: sticky;\n top: 0;\n z-index: $zindex-sticky;\n }\n}\n","//\n// Screenreaders\n//\n\n.sr-only {\n @include sr-only();\n}\n\n.sr-only-focusable {\n @include sr-only-focusable();\n}\n","// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n// See: https://hugogiraudel.com/2016/10/13/css-hide-and-seek/\n\n@mixin sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n clip-path: inset(50%);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n//\n// Useful for \"Skip to main content\" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n//\n// Credit: HTML5 Boilerplate\n\n@mixin sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n clip-path: none;\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Width and height\n\n@each $prop, $abbrev in (width: w, height: h) {\n @each $size, $length in $sizes {\n .#{$abbrev}-#{$size} { #{$prop}: $length !important; }\n }\n}\n\n.mw-100 { max-width: 100% !important; }\n.mh-100 { max-height: 100% !important; }\n","// stylelint-disable declaration-no-important\n\n// Margin and Padding\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $prop, $abbrev in (margin: m, padding: p) {\n @each $size, $length in $spacers {\n\n .#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; }\n .#{$abbrev}t#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-top: $length !important;\n }\n .#{$abbrev}r#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-right: $length !important;\n }\n .#{$abbrev}b#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-bottom: $length !important;\n }\n .#{$abbrev}l#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-left: $length !important;\n }\n }\n }\n\n // Some special margin utils\n .m#{$infix}-auto { margin: auto !important; }\n .mt#{$infix}-auto,\n .my#{$infix}-auto {\n margin-top: auto !important;\n }\n .mr#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-right: auto !important;\n }\n .mb#{$infix}-auto,\n .my#{$infix}-auto {\n margin-bottom: auto !important;\n }\n .ml#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-left: auto !important;\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Text\n//\n\n// Alignment\n\n.text-justify { text-align: justify !important; }\n.text-nowrap { white-space: nowrap !important; }\n.text-truncate { @include text-truncate; }\n\n// Responsive alignment\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .text#{$infix}-left { text-align: left !important; }\n .text#{$infix}-right { text-align: right !important; }\n .text#{$infix}-center { text-align: center !important; }\n }\n}\n\n// Transformation\n\n.text-lowercase { text-transform: lowercase !important; }\n.text-uppercase { text-transform: uppercase !important; }\n.text-capitalize { text-transform: capitalize !important; }\n\n// Weight and italics\n\n.font-weight-light { font-weight: $font-weight-light !important; }\n.font-weight-normal { font-weight: $font-weight-normal !important; }\n.font-weight-bold { font-weight: $font-weight-bold !important; }\n.font-italic { font-style: italic !important; }\n\n// Contextual colors\n\n.text-white { color: #fff !important; }\n\n@each $color, $value in $theme-colors {\n @include text-emphasis-variant(\".text-#{$color}\", $value);\n}\n\n.text-muted { color: $text-muted !important; }\n\n// Misc\n\n.text-hide {\n @include text-hide();\n}\n","// Text truncate\n// Requires inline-block or block for proper styling\n\n@mixin text-truncate() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","// stylelint-disable declaration-no-important\n\n// Typography\n\n@mixin text-emphasis-variant($parent, $color) {\n #{$parent} {\n color: $color !important;\n }\n a#{$parent} {\n @include hover-focus {\n color: darken($color, 10%) !important;\n }\n }\n}\n","// CSS image replacement\n@mixin text-hide() {\n // stylelint-disable-next-line font-family-no-missing-generic-family-keyword\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n","//\n// Visibility utilities\n//\n\n.visible {\n @include invisible(visible);\n}\n\n.invisible {\n @include invisible(hidden);\n}\n","// stylelint-disable declaration-no-important\n\n// Visibility\n\n@mixin invisible($visibility) {\n visibility: $visibility !important;\n}\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type\n\n// Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request:\n// http://www.phpied.com/delay-loading-your-print-css/\n// ==========================================================================\n\n@if $enable-print-styles {\n @media print {\n *,\n *::before,\n *::after {\n // Bootstrap specific; comment out `color` and `background`\n //color: #000 !important; // Black prints faster: http://www.sanbeiji.com/archives/953\n text-shadow: none !important;\n //background: transparent !important;\n box-shadow: none !important;\n }\n\n a {\n &:not(.btn) {\n text-decoration: underline;\n }\n }\n\n // Bootstrap specific; comment the following selector out\n //a[href]::after {\n // content: \" (\" attr(href) \")\";\n //}\n\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n\n // Bootstrap specific; comment the following selector out\n //\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n //\n\n //a[href^=\"#\"]::after,\n //a[href^=\"javascript:\"]::after {\n // content: \"\";\n //}\n\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: $border-width solid #999; // Bootstrap custom code; using `$border-width` instead of 1px\n page-break-inside: avoid;\n }\n\n //\n // Printing Tables:\n // http://css-discuss.incutio.com/wiki/Printing_Tables\n //\n\n thead {\n display: table-header-group;\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Specify a size and min-width to make printing closer across browsers.\n // We don't set margin here because it breaks `size` in Chrome. We also\n // don't use `!important` on `size` as it breaks in Chrome.\n @page {\n size: $print-page-size;\n }\n body {\n min-width: $print-body-min-width !important;\n }\n .container {\n min-width: $print-body-min-width !important;\n }\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .badge {\n border: $border-width solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n\n // Bootstrap specific changes end\n }\n}\n"]} \ No newline at end of file diff --git a/web2py/applications/SP/static/css/calendar.css b/web2py/applications/SP/static/css/calendar.css new file mode 100644 index 0000000..51d68a9 --- /dev/null +++ b/web2py/applications/SP/static/css/calendar.css @@ -0,0 +1,7 @@ +.calendar{z-index:2000;position:relative;display:none;background:#fff;border:2px solid #000;font-size:11px;color:#000;cursor:default;font-family:Arial,Helvetica,sans-serif; +border-radius: 10px; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +}.calendar table{margin:0px;font-size:11px;color:#000;cursor:default;font-family:tahoma,verdana,sans-serif;}.calendar .button{text-align:center;padding:1px;color:#fff;background:#000;}.calendar .nav{background:#000;color:#fff}.calendar thead .title{font-weight:bold;padding:1px;background:#000;color:#fff;text-align:center;}.calendar thead .name{padding:2px;text-align:center;background:#bbb;}.calendar thead .weekend{color:#f00;}.calendar thead .hilite {background-color:#666;}.calendar thead .active{padding:2px 0 0 2px;background-color:#c4c0b8;}.calendar tbody .day{width:2em;text-align:right;padding:2px 4px 2px 2px;}.calendar tbody .day.othermonth{color:#aaa;}.calendar tbody .day.othermonth.oweekend{color:#faa;}.calendar table .wn{padding:2px 3px 2px 2px;background:#bbb;}.calendar tbody .rowhilite td{background:#ddd;}.calendar tbody td.hilite{background:#bbb;}.calendar tbody td.active{background:#bbb;}.calendar tbody td.selected{font-weight:bold;background:#ddd;}.calendar tbody td.weekend{color:#f00;}.calendar tbody td.today{font-weight:bold;color:#00f;}.calendar tbody .disabled{color:#999;}.calendar tbody .emptycell{visibility:hidden;}.calendar tbody .emptyrow{display:none;}.calendar tfoot .ttip{background:#bbb;padding:1px;background:#000;color:#fff;text-align:center;}.calendar tfoot .hilite{background:#ddd;}.calendar tfoot .active{}.calendar .combo{position:absolute;display:none;width:4em;top:0;left:0;cursor:default;background:#e4e0d8;padding:1px;z-index:2001;}.calendar .combo .label,.calendar .combo .label-IEfix{text-align:center;padding:1px;}.calendar .combo .label-IEfix{width:4em;}.calendar .combo .active{background:#c4c0b8;}.calendar .combo .hilite{background:#048;color:#fea;}.calendar td.time{padding:1px 0;text-align:center;background-color:#bbb;}.calendar td.time .hour,.calendar td.time .minute,.calendar td.time .ampm{padding:0 3px 0 4px;font-weight:bold;}.calendar td.time .ampm{text-align:center;}.calendar td.time .colon{padding:0 2px 0 3px;font-weight:bold;}.calendar td.time span.hilite{}.calendar td.time span.active{border-color:#f00;background-color:#000;color:#0f0;}.hour,.minute{font-size:2em;} + +#CP_hourcont{z-index:2000;padding:0;position:absolute;border:1px dashed #666;background-color:#eee;display:none;}#CP_minutecont{z-index:2000;background-color:#ddd;padding:1px;position:absolute;width:45px;display:none;}.floatleft{float:left;}.CP_hour{z-index:2000;padding:1px;font-family:Arial,Helvetica,sans-serif;font-size:9px;white-space:nowrap;cursor:pointer;width:35px;}.CP_minute{z-index:2000;padding:1px;font-family:Arial,Helvetica,sans-serif;font-size:9px;white-space:nowrap;cursor:pointer;width:auto;}.CP_over{background-color:#fff;z-index:2000} diff --git a/web2py/applications/SP/static/css/web2py-bootstrap4.css b/web2py/applications/SP/static/css/web2py-bootstrap4.css new file mode 100644 index 0000000..2586fe9 --- /dev/null +++ b/web2py/applications/SP/static/css/web2py-bootstrap4.css @@ -0,0 +1,350 @@ + +label, th { + font-weigth: bold; + white-space: nowrap; +} +div.w2p_flash { + background-image: none; + border-radius: 4px; + -o-border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + color: #333; + font-weight: 400; + min-width: 28px; + max-width: 300px; + opacity: 1; + vertical-align: baseline; + right: auto; + border-width: 1px; + margin: 0 0 20px; + padding: 15px 35px 15px 15px; +} +div.w2p_flash.alert:hover { + opacity: 1; +} +.ie-lte8 div.w2p_flash { + filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#222222', endColorstr='#000000', GradientType=0); +} +.ie-lte8 div.w2p_flash:hover { + filter: alpha(opacity=25); +} +.main-container { + margin-top: 20px; +} + +div.error { + width: auto; + background: transparent; + border: none; + background-image: none; + color: red; + display: inline-block; + padding: 5px; +} +div.w2p_flash.alert { + display: none; + position: fixed; + top: 70px; + right: 75px; + cursor: pointer; + z-index: 1000; + background-color: #f9edbe; + border-color: #f0c36d; +} +.w2p-toolbar-hidden { + margin: 10px; +} +ul.w2p_list { + margin-left: 0; + padding-left: 0; +} +.w2p_list li { + margin-bottom: 6px; +} +.w2p_list li input { + display: inline-block; + width: 85%; + margin-right: 4px; +} +.w2p_list li a { + margin-bottom: 2px; +} +div[id^=_autocomplete_] { + margin-top: -10px; + z-index: 1; +} +select.autocomplete { + display: block; + font-size: 14px; + line-height: 1.428571429; + color: #555; + vertical-align: middle; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + border-color: #428bca; + padding: 6px 12px; +} +#web2py-logo { + color: #c6cecc; +} +#web2py-logo b { + display: inline-block; + margin-top: -1px; +} +#web2py-logo b>span { + font-size: 22px; + color: #FFF; +} +#web2py-logo:hover { + color: #FFF; +} +.footer > .row { + padding-left: 15px; + padding-right: 15px; + margin-top: 20px; +} +.background { + background: url(../images/background.jpg) no-repeat center center; +} +body { + margin-bottom: 60px; +} +header { + -webkit-box-shadow: 0 0 8px 2px #000; + -moz-box-shadow: 0 0 8px 2px #000; + box-shadow: 0 0 8px 2px #000; + margin-bottom: 10px; +} +html { + position: relative; + min-height: 100%; +} +.footer { + position: absolute; + bottom: 0; + width: 100%; + height: 60px; + background: #f7f7f7; +} +header h1 { + color: #FFF!important; + text-shadow: 0 0 7px #000; +} +header .jumbotron { + background-color: transparent; +} +.w2p_flash { + opacity: 0.9!important; + right: 100px; +} +.right { + float: right; + text-align: right; +} +.left { + float: left; + text-align: left; +} +.center { + width: 100%; + text-align: center; + vertical-align: middle; +} +td.w2p_fw { + padding-bottom: 1px; +} +td.w2p_fl { + text-align: left; +} +td.w2p_fl, +td.w2p_fw { + padding-right: 7px; +} +td.w2p_fl, +td.w2p_fc { + padding-top: 4px; +} +div.w2p_export_menu { + margin: 5px 0; +} +div.w2p_export_menu a, +div.w2p_wiki_tags a, +div.w2p_cloud a { + margin-left: 5px; + padding: 2px 5px; +} +#submit_record__row td { + padding-top: .5em; +} +div.error_wrapper { + display: block; +} +.copyright { + float: left; +} +#poweredBy { + float: right; +} +.web2py_grid tbody td { + vertical-align: middle; + padding: 2px 5px; +} +.web2py_grid thead th, +.web2py_grid tfoot td { + background-color: #EAEAEA; + padding: 10px 5px; +} +.web2py_grid tr.odd { + background-color: #F9F9F9; +} +.web2py_grid tr:hover { + background-color: #F5F5F5; +} +.web2py_console form { + width: 100%; + display: inline; + vertical-align: middle; + margin: 0 0 0 5px; +} +.web2py_console form select { + margin: 0; +} +.web2py_search_actions { + float: left; + text-align: left; + width: 100%; +} +.web2py_grid .row_buttons { + min-height: 25px; + vertical-align: middle; +} +.web2py_grid .row_buttons a { + margin: 3px; +} +.web2py_grid .row_buttons a, +.web2py_paginator ul li a, +.web2py_search_actions a, +.web2py_console input[type=submit], +.web2py_console input[type=button], +.web2py_console button { + line-height: 20px; + margin-right: 2px; + display: inline-block; + padding: 6px 12px; +} +.web2py_counter { + margin-top: 5px; + margin-right: 2px; + width: 35%; + float: right; + text-align: right; +} +.web2py_table { + clear: both; + display: block; +} +.web2py_paginator { + text-align: right; + background-color: #f2f2f2; + padding: 5px; +} +.web2py_paginator ul { + list-style-type: none; + margin: 0; + padding: 0; +} +.web2py_paginator .current { + font-weight: 700; +} +.web2py_breadcrumbs ul { + list-style: none; + margin-bottom: 18px; +} +li.w2p_grid_breadcrumb_elem { + display: inline-block; +} +.web2py_console input, +.web2py_console select, +.web2py_console a { + margin: 2px; + padding: 6px 12px; +} +#wiki_page_body { + width: 600px; + height: auto; + min-height: 400px; +} +.ie-lte7 .topbar .container { + z-index: 2; +} +.ie9 #w2p_query_panel { + padding-bottom: 2px; +} +.web2py_console .form-control { + width: 20%; + display: inline; + height: 32px; +} +.web2py_console #w2p_keywords { + width: 50%; +} +.web2py_search_actions a, +.web2py_console input[type=submit], +.web2py_console input[type=button], +.web2py_console button { + padding: 6px 12px; +} +td.w2p_fl, +td.w2p_fw, +td.w2p_fc, +#web2py_user_form td, +.web2py_grid .web2py_form td { + vertical-align: top; +} +#auth_user_remember__row label, +.web2py_paginator ul li { + display: inline; +} +.web2py_grid, +.web2py_grid table { + width: 100%; +} + +/* form submit block */ +#submit_record__row .btn { + margin-bottom: .25rem; +} +@media (min-width: 577px) { + #submit_record__row .btn { + margin-left: .25rem; + } +} +@media (max-width: 576px) { + #submit_record__row .btn { + width: 100%; + margin-left: 0; + } +} + +/* for backward compatbility with pre-font-awesome */ +.icon.plus,.icon.arrowleft,.icon.download,.icon.trash,.icon.pen,.icon.arrowright,.icon.magnifier { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.icon.plus:before { content: "\f067";} +.icon.arrowleft:before { content: "\f060";} +.icon.download:before { content: "\f019";} +.icon.trash:before { content: "\f1f8";} +.icon.pen:before { content: "\f040";} +.icon.arrowright:before { content: "\f061";} +.icon.magnifier:before { content: "\f002";} diff --git a/web2py/applications/SP/static/css/web2py.css b/web2py/applications/SP/static/css/web2py.css new file mode 100644 index 0000000..4625c51 --- /dev/null +++ b/web2py/applications/SP/static/css/web2py.css @@ -0,0 +1,313 @@ +/** these MUST stay **/ +a {text-decoration:none; white-space:nowrap} +a:hover {text-decoration:underline} +a.button {text-decoration:none} +h1,h2,h3,h4,h5,h6 {margin:0.5em 0 0.25em 0; display:block; + font-family:Helvetica} +h1 {font-size:4.00em} +h2 {font-size:3.00em} +h3 {font-size:2.00em} +h4 {font-size:1.50em} +h5 {font-size:1.25em} +h6 {font-size:1.12em} +th,label {font-weight:bold; white-space:nowrap;} +td,th {text-align:left; padding:2px 5px 2px 5px} +th {vertical-align:middle; border-right:1px solid white} +td {vertical-align:top} +form table tr td label {text-align:left} +p,table,ol,ul {padding:0; margin: 0.75em 0} +p {text-align:justify} +ol, ul {list-style-position:outside; margin-left:2em} +li {margin-bottom:0.5em} +span,input,select,textarea,button,label,a {display:inline} +img {border:0} +blockquote,blockquote p,p blockquote { + font-style:italic; margin:0.5em 30px 0.5em 30px; font-size:0.9em} +i,em {font-style:italic} +strong {font-weight:bold} +small {font-size:0.8em} +code {font-family:Courier} +textarea {width:100%} +video {width:400px} +audio {width:200px} +[type="text"], [type="password"], select { + margin-right: 5px; width: 300px; +} +.w2p_hidden {display:none;visibility:visible} +.right {float:right; text-align:right} +.left {float:left; text-align:left} +.center {width:100%; text-align:center; vertical-align:middle} +/** end **/ + +/* Sticky footer begin */ + +.main { + padding:20px 0 50px 0; +} + +.footer,.push { + height:6em; + padding:1em 0; + clear:both; +} + +.footer-content {position:relative; bottom:-4em; width:100%} + +.auth_navbar { + white-space:nowrap; +} + +/* Sticky footer end */ + +.footer { + border-top:1px #DEDEDE solid; +} +.header { + /* background:<fill here for header image>; */ +} + + +fieldset {padding:16px; border-top:1px #DEDEDE solid} +fieldset legend {text-transform:uppercase; font-weight:bold; padding:4px 16px 4px 16px; background:#f1f1f1} + +/* fix ie problem with menu */ + +td.w2p_fw {padding-bottom:1px} +td.w2p_fl,td.w2p_fw,td.w2p_fc {vertical-align:top} +td.w2p_fl {text-align:left} +td.w2p_fl, td.w2p_fw {padding-right:7px} +td.w2p_fl,td.w2p_fc {padding-top:4px} +div.w2p_export_menu {margin:5px 0} +div.w2p_export_menu a, div.w2p_wiki_tags a, div.w2p_cloud a {margin-left:5px; padding:2px 5px; background-color:#f1f1f1; border-radius:5px; -moz-border-radius:5px; -webkit-border-radius:5px;} + +/* tr#submit_record__row {border-top:1px solid #E5E5E5} */ +#submit_record__row td {padding-top:.5em} + +/* Fix */ +#auth_user_remember__row label {display:inline} +#web2py_user_form td {vertical-align:top} + +/*********** web2py specific ***********/ +div.w2p_flash { + font-weight:bold; + display:none; + position:fixed; + padding:10px; + top:48px; + right:250px; + min-width:280px; + opacity:0.95; + margin:0px 0px 10px 10px; + vertical-align:middle; + cursor:pointer; + color:#fff; + background-color:#000; + border:2px solid #fff; + border-radius:8px; + -o-border-radius: 8px; + -moz-border-radius:8px; + -webkit-border-radius:8px; + background-image: -webkit-linear-gradient(top,#222,#000); + background-image: -o-linear-gradient(top,#222,#000); + background-image: -moz-linear-gradient(90deg, #222, #000); + background-image: linear-gradient(top,#222,#000); + background-repeat: repeat-x; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + -webkit-font-smoothing: antialiased; + z-index:2000; +} + +div.w2p_flash #closeflash{color:inherit; float:right; margin-left:15px;} +.ie-lte7 div.flash #closeflash +{color:expression(this.parentNode.currentStyle['color']);float:none;position:absolute;right:4px;} + +div.w2p_flash:hover { opacity:0.25; } + +div.error_wrapper {display:block} +div.error { + color:red; + padding:5px; + display:inline-block; +} + +.topbar { + padding:10px 0; + width:100%; + color:#959595; + vertical-align:middle; + padding:auto; + background-image:-khtml-gradient(linear,left top,left bottom,from(#333333),to(#222222)); + background-image:-moz-linear-gradient(top,#333333,#222222); + background-image:-ms-linear-gradient(top,#333333,#222222); + background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#333333),color-stop(100%,#222222)); + background-image:-webkit-linear-gradient(top,#333333,#222222); + background-image:-o-linear-gradient(top,#333333,#222222); + background-image:linear-gradient(top,#333333,#222222); + filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333',endColorstr='#222222',GradientType=0); + -webkit-box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1); + -moz-box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1); + box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1); +} + +.topbar a { + color:#e1e1e1; +} + +#navbar {float:right; padding:5px; /* same as superfish */} + +.statusbar { + background-color:#F5F5F5; + margin-top:1em; + margin-bottom:1em; + padding:.5em 1em; + border:1px solid #ddd; + border-radius:5px; + -moz-border-radius:5px; + -webkit-border-radius:5px; +} + +.breadcrumbs {float:left} + +.copyright {float:left} +#poweredBy {float:right} + +/* #MEDIA QUERIES SECTION */ + +/* +*Grid +* +* The default style for SQLFORM.grid even using jquery-iu or another ui framework +* will look better with the declarations below +* if needed to remove base.css consider keeping these following lines in some css file. +*/ +/* .web2py_table {border:1px solid #ccc} */ +.web2py_paginator {} +.web2py_grid {width:100%} +.web2py_grid table {width:100%} +.web2py_grid tbody td {padding:2px 5px 2px 5px; vertical-align: middle;} +.web2py_grid .web2py_form td {vertical-align: top;} + +.web2py_grid thead th,.web2py_grid tfoot td { + background-color:#EAEAEA; + padding:10px 5px 10px 5px; +} + +.web2py_grid tr.odd {background-color:#F9F9F9} +.web2py_grid tr:hover {background-color:#F5F5F5} + +/* +.web2py_breadcrumbs a { + line-height:20px; margin-right:5px; display:inline-block; + padding:3px 5px 3px 5px; + font-family:'lucida grande',tahoma,verdana,arial,sans-serif; + color:#3C3C3D; + text-shadow:1px 1px 0 #FFFFFF; + white-space:nowrap; overflow:visible; cursor:pointer; + background:#ECECEC; + border:1px solid #CACACA; + -webkit-border-radius:2px; -moz-border-radius:2px; + -webkit-background-clip:padding-box; border-radius:2px; + outline:none; position:relative; zoom:1; *display:inline; +} +*/ + +.web2py_console form { + width: 100%; + display: inline; + vertical-align: middle; + margin: 0 0 0 5px; +} + +.web2py_console form select { + margin:0; +} + +.web2py_search_actions { + float:left; + text-align:left; +} + +.web2py_grid .row_buttons { + min-height:25px; + vertical-align:middle; +} +.web2py_grid .row_buttons a { + margin:3px; +} + +.web2py_search_actions { + width:100%; +} + +.web2py_grid .row_buttons a, +.web2py_paginator ul li a, +.web2py_search_actions a, +.web2py_console input[type=submit], +.web2py_console input[type=button], +.web2py_console button { + line-height:20px; + margin-right:2px; display:inline-block; + padding:3px 5px 3px 5px; +} + +.web2py_counter { + margin-top:5px; + margin-right:2px; + width:35%; + float:right; + text-align:right; +} + +/*Fix firefox problem*/ +.web2py_table {clear:both; display:block} + +.web2py_paginator { + padding:5px; + text-align:right; + background-color:#f2f2f2; + +} +.web2py_paginator ul { + list-style-type:none; + margin:0px; + padding:0px; +} + +.web2py_paginator ul li { + display:inline; +} + +.web2py_paginator .current { + font-weight:bold; +} + +.web2py_breadcrumbs ul { + list-style:none; + margin-bottom:18px; +} + +li.w2p_grid_breadcrumb_elem { + display:inline-block; +} + +.web2py_console form { vertical-align: middle; } +.web2py_console input, .web2py_console select, +.web2py_console a { margin: 2px; } + + +#wiki_page_body { + width: 600px; + height: auto; + min-height: 400px; +} + +/* fix some IE problems */ + +.ie-lte7 .topbar .container {z-index:2} +.ie-lte8 div.w2p_flash{ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#222222', endColorstr='#000000', GradientType=0 ); } +.ie-lte8 div.w2p_flash:hover {filter:alpha(opacity=25);} +.ie9 #w2p_query_panel {padding-bottom:2px} + +.web2py_console .form-control {width: 20%; display: inline;} +.web2py_console #w2p_keywords {width: 50%;} +.web2py_search_actions a, .web2py_console input[type=submit], .web2py_console input[type=button], .web2py_console button { padding: 6px 12px; } diff --git a/web2py/applications/SP/static/images/facebook.png b/web2py/applications/SP/static/images/facebook.png new file mode 100644 index 0000000000000000000000000000000000000000..be55deddc3fc615ccd1d49235976cecc8e8d0eab GIT binary patch literal 991 zcmV<510ei~P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#fk{L`RCwCFmrZCBK@`XTvpe~yO&bzh zTeS&MEB!*n3Vzg!DC)^7o<xPVBJ?Jn`~ZuQf?p@EUbG_iD1LzlK?L#ZP(%eis94&n ziPf}eQj#Xw8D}=>q1ouJThj*#d6U`qd-LYKH#-Cc>DbrT<#4*f?uv>K$|&hnYB-yj z2|vHne?#g-er?@<_IfC=yn9E-IyBV#%gM)BB!<T?-r>v0=)kkv=X%JNeP_CY4S|8( zTi4@PVg{qpcv&3?)OoSE%7uqdhcNc-Yd571XLxn60k1#)z>kR}$}Q1Y5=(p@G=+kQ zjE{$@)8PtDCNqe}(^x2p{7Qg(-H>bwqF_9p0%KTEkxa>^M0{m64sbp%gKjrP=k`Xl zHP)a){4SOgm!Hhhvz$P(DPtVkJeR+$)`Q*yYvK1+qN;KcC{+z}wBiK{U9u?ypI7+Z zE)|D6o3Xsk4_|fFALo@~NVbRo1LO8R=xA@is^F5p!gW{)hGbJN!ocRS|C`n<MUBsE zI<FLi>swIR3%jy1P-_^w_23N#AH22X6y@B01bo#lkpoV{_@n2aE!mW8y$Znd%D+l% zG7Tp+mRw{!Vfri~BwqzwB!?o7q>RmNa5^34C0FV>0hMe$0@4Aid2sRgCPNsD<@~XY zhOtvuUd_=JirENosNz(%ng{J|%|)feP3Pnj?&Ta^GV?jWWdw*`5>|vU&DK^G+n3CI z6^K7nVm$)PX4@>buND?fWrvcA#>(qJvHkp_3rVOd)+4a}=*_t`fAx@I&d%Ojrgn7Z zY$sHNqS<UlrFy&-TS{TkG$%qzgpq76XD_sx(E%&ABvZ0!HZ_e*dJ5@e%w7aa<b)Ml znY0SYrpsDd(6qS&xv0GtQl=TpvTfTg)90G%Jcy_&=yZG<saOKB=!DG(tT3JtQS%6- z92}BOiGDlDSAu5aJg{?;x>QAHl6*4CPRQVOJ8UMQX84#%rHkrJovpCk@WfOc0pB9q zNm%?by&VabWJ<QeW|HAgV`HdLa%d0uQ0oyd84mToJ3z%2OWTqmS&}K)`sH*(XWw;C z&C>2xab2qS`$bq3D5^Clj_eH@#;)BRDOoMjxkxOA55pr!{QN#Jbg#dM%ud*_=X96i zstjv{hGbq@&Bv1mTMc8E2HzVyACYfCq6PEZFq@eU58c0@U(bIFFaYf=<8eP8H#h(Q N002ovPDHLkV1lDZ(&+#I literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/static/images/favicon.ico b/web2py/applications/SP/static/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..d2296d5e893eeef0d9c23629b93fc15f0c07de6e GIT binary patch literal 198 zcmZQzU<5(|0VW0z*Z{<0K&%180zj+)#2|SPZ~&7K0-_qiW}p8IF5}9<zyQLv=YX^( z1X}{xAfWkzfguzq7t#mBo<KHGJ_IWF|33o*2=Dq1!A*uh`Wgfu1F}JK*TfkZRsrQ# P7XtA%AR8#Z8Y%|>8KWZe literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/static/images/favicon.png b/web2py/applications/SP/static/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..bd0a414ec86d9994b46676a8d399955a211da224 GIT binary patch literal 323 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b zK-vS0-A-oPfdtD69Mgd`SU*F|v9*VRoE%RV#}JFt$q5VCD$M5pwKtPGcI;St=SBge z2(6Fm%2v{mJ)H9yZ<s7*-lKP5spPYol}G0HxKuOFKK+4BrK%xu@^Y>QYu1}7PYx)% z@f?oav8UOWC*MSf`N75p?Scu5d6r8U#vMo%JQ^oa!N723Q>lXa!beMh_Ntb+MwFx^ zmZVxG7o`Fz1|tJQLtO(4T_cka14}DoLn{MwT?11q1A~nj7xtiN$jwj5OsmAL;ecrd QP(1^Kr>mdKI;Vst0O;yt8UO$Q literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/static/images/gplus-32.png b/web2py/applications/SP/static/images/gplus-32.png new file mode 100644 index 0000000000000000000000000000000000000000..c42eab784578bf4e827722400f125760ebab527a GIT binary patch literal 1513 zcmV<F1s3{=P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F8000HBNkl<ZScSdT zdrVVT90&08$HM-1|7=6?$@~2-3JS<Xz|H99bZ#>~mL-d9E}6-eW&UBZZ2My_Cfm%i zR~F|3K~NBsXK5*=D3)i1wty(22(yB`TUx&RokMTe)+&h3CZC-4{C@YG-#z!-d&`WO zGS-!qz^GkB4wEK=|ACn(NH+1}^K$G@-<MfuW<sJNL)K65oHP+{!k8f=etBo6%tS5p z&k@bnO1zkUW885g@7x%N#`TfVtPMrYnqX8X1fo37|B0xRLeN3uaM#jfJ?2Pp{j6-( zz9Dv^Avpq7vH+;JrK9KgZ@90$4D0w9Ff%hJo7s%kFFzFpU)vCi_VhSGN8jbCF>wCy z0;G7yEEQ9(4no!1aNNo}0oZK9SWg%F&gWvdMeFGE#5OSwZT4<d#QUQqEn1wlq-{eC zs@J;~!1JVd`z$k4W+jOUXK295yLV8(`z@5k`Jp`CPqgZHHi>>7=WNp!v>pB&nq6C< ze0`nBxsnntCUn;FS~TQt1(Z_(Qe0=pMhw?5W1SYR?%xf?>OeHnUTCEOc*}pQcWi=X z_`V}=;&v}o8LJ(6o;0ULd0YW0-e$*UEEaIq(NVfaeqzuTI#|+7zvZ+)8V`O1DVMud zkR$d@vpugu=KqlDG`9lW;+2HW&?e$0dT)r0#3yvukQ|26SYM17+9Bmn4-cU{F$7mA z#&Z;Ilg;<TW~L^=nFsHRGipqY@QANM=g&tV<#V;$Gf_vk9*-;1Vi#5b-^rYHY!np< zLAaV64y^|&x?3)PxD!%7r`fv=YI<hyxN^Y-(ETn^?Z`qc4R~d3*h7?5oZ^iXxa4ok zpaMcfyedB6A<FfxMO9LtGoHh2V<V90kA92tSU+5*r=hd@q)?Hp+MeaewV3`v85O0W zeZb@Hc)xoAd<^$IW*d0`$#|Cmm*NA(^{%4<oR!A-Lif!fM{aNK2`FgOy5~vw%6KY3 z#1exA{+-z#48fU^Hd=AiN-DyiE=Le*=s8eEcfch&+wpFL$QjW!Ly;~M@kgm43b*G# zB|QgJ)bET9R9=K_$mGI!><BK>85BjW5K2>{ar;8Phz&JpAg9TdRG24xRXBc2dwLg0 zaS1Dt1>wf2zhE`pb1~J|3zMc6!_8Vp-#xVw@)UZ+(o)U`-%swOSe3nHmDE`jxdIB> zV8&mL!c?ckkhWg5(}Vr6-Ww1mdpc2>5`#)Qi)W$2-ZD{Hj2}v(R*6CiBUa#i#B!8n zB*97#CrMvn9_@`)v>*JQiBfyZ`0g$vrA~Mu)$eY`^uQg5v5q!eppAGbdX-D=(_$BC zKzF==qBUWdyxxWB{@V_NiVBpZ#)`Yd({XbtacU*3ByuIV3w-Irm!lwT8P0|-Ltf}o zXg>J>)AZ_fHp*|oots5&F&+1`SRoCRPm|?_EJaaLB-H!&K>O8aF#h@@ZqdJ@$?HZ~ z`fj?Iy3vKYkM|*;iY=nT7oyPKvUBw0YdmxirrK&)dV3s3ni?=DFBSNA=a{4}doS{+ zaK0LaPw2cI8*gug<z_b~^g8H|{eYT1Z_`Rd&}CRE<c0VkKhjskc%HMVZaw7hZK2ik z!8uxug<xj-KX^0eIEs>^k<SOBNj=F6_Cd|Qofy-#fFC1yaJ3%!(SDCT)?LAWM%neh zf47|pnLX39bI1)|g2HuC7$_@-x!dT_@Wla~q1ar<JL4xr>R3*sZ}FL+C1UXT$O&4E zv$9~ARC1W<?aA@K@TUV8&wC6f2iPCJuY^+pCSC*|TxzB7o}38qhW!1lFn4wcBXk)~ z1wJ}oB8_X;O1#*2J}<pU)hCjEeirj_k_sqT7Y#H0rRRp}y}|qDdpv0+-h{EHpT2*= zY|ydOf!>R90=>T`dV<F}8SpBqcfCoI>jeH1J4JnS9Y<8;0P&*v_?+xtd)gw|EW3ec P00000NkvXXu0mjf1Z(LN literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/static/images/twitter.png b/web2py/applications/SP/static/images/twitter.png new file mode 100644 index 0000000000000000000000000000000000000000..d94419a4b1011554746d666a133235679dec04a3 GIT binary patch literal 1120 zcmV-m1fTnfP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$0!c(cRCwCFS6gTtRT%!}%<N_M(q)s4 z32QG)BMK@+q%;+R5nuIPe2}!D;H&ZSP(fGfi$3`%RBQu+3O-e(R7I#1q>9nfCllPH zmZqC+wkFx^ZD!6n{%3cR&89Q6O>_C#pV=8^&-b10zn#_K+WSBMHIXvS{6I39!yek5 zN@aefUeAB<{8LjK4?nzo{oJ>+C3&~OB^Po}U13}-EJ=l_u(fx8oSqmx^6>fbBN<3~ z(ByJ21wcgCpwacGxe}&t-act0BH{ew11Z!T0c(%Jl{Fk7Oe97I)0ioh^G3>y<`_|` z*&O?2v{xuhg>4u*BiRLX^<*E7@&O9lFf;<D50~EZ|1nd><fm6rsoO}JA)K8Y!=nce z?3@8%Dr{zR-eTkDZ%+M*Mk0oAwy$-a{Cqm_{q4BIHXI>*cdx8&MiDZ@8~3GZGw}WG z<$@prt^$5$5V(rfy2*GX@cnHOXe+=2cVve2ZbD4oMFofe?-2rh)9#hoH4Ec!|Il;s z1SRa5i4lw(O$Stha2230z9C@U1XwJB{@g=730Rhc)8G7!3vV6op#Tq7fNdo}x70j( zw_GB+Tx+7VW}!bG@>YPm3J59SM?r20!FDX$7f0GuIU~H<Kqm(jxUUKiNFW|!c<0$6 zIBIo|rFCjTZVnIuDSb=JOMy$TJl2x{O<ol14Kz6S39Z`)6bpsztH72SVb?9pu2yzj zg1T%gz#O*%xb$|Vz-Cwb`E}+$-}mp=H##A2C831yDaAO|^P1I>(MUw`#nmE?4X1Xb zfM7}i4z@W7y?pFYqMeAYv#^0Oi{SKyIb2()Vzue`{x-;ErxC4(z&i&{WTUwBZ?)@L zdN75##Z|m_@s{rnV_}9<qXT&Ek!0{NYAYb&Nbe8~#RbL>Cvo{!hXf-f1`qa8*kr5Y zc`oj7OkG>S*l^stx*)q15I$vCt~c@elWE*;aLg`STjs>Q!>Y?d2CBA%srxIyT3xC~ zyb3GJ_~=9iPY=eR(eCfpvwbnd49#=RHm2xwLMLFxtCo5F&JxZX%Rr^WSA`0GDb@qC zJZUg|@=OMWyCt6xxJk&VQ`wHwiirq3L~>kNSVSfo!5dE;z{kf20twhOXs#?2sc+o7 zF?AMHn0)<6X3<TEdSlJ$eKcRJHCn!-KPRM)!faOo7xOpD<=oMsAyjN<UykHS>LrC@ zQH|qyCIrv_e&Z&p)iq>eQOa0qHg0@&(^b-`wH1cKQkV+6HECY_?CW!;89q6B_z;FO z{Zu_6a${F_tzvFFHvU;E<2M4YHLUaBz53FrjZyc)*)J!AhCJ6;js{g=LOzHoRW+%m mAjvL~|Nga?TYu007hnJ&oPNBq52Shk0000<MNUMnLSTZH&J7s= literal 0 HcmV?d00001 diff --git a/web2py/applications/SP/static/js/analytics.min.js b/web2py/applications/SP/static/js/analytics.min.js new file mode 100644 index 0000000..3f59e0c --- /dev/null +++ b/web2py/applications/SP/static/js/analytics.min.js @@ -0,0 +1,8 @@ +(function umd(require){if("object"==typeof exports){module.exports=require("1")}else if("function"==typeof define&&define.amd){define(function(){return require("1")})}else{this["analytics"]=require("1")}})(function outer(modules,cache,entries){var global=function(){return this}();function require(name,jumped){if(cache[name])return cache[name].exports;if(modules[name])return call(name,require);throw new Error('cannot find module "'+name+'"')}function call(id,require){var m=cache[id]={exports:{}};var mod=modules[id];var name=mod[2];var fn=mod[0];fn.call(m.exports,function(req){var dep=modules[id][1][req];return require(dep?dep:req)},m,m.exports,outer,modules,cache,entries);if(name)cache[name]=cache[id];return cache[id].exports}for(var id in entries){if(entries[id]){global[entries[id]]=require(id)}else{require(id)}}require.duo=true;require.cache=cache;require.modules=modules;return require}({1:[function(require,module,exports){var _analytics=window.analytics;var Integrations=require("analytics.js-integrations");var Analytics=require("./analytics");var each=require("each");var analytics=module.exports=exports=new Analytics;analytics.require=require;exports.VERSION=require("../bower.json").version;each(Integrations,function(name,Integration){analytics.use(Integration)})},{"analytics.js-integrations":2,"./analytics":3,each:4,"../bower.json":5}],2:[function(require,module,exports){var each=require("each");var plugins=require("./integrations.js");each(plugins,function(plugin){var name=(plugin.Integration||plugin).prototype.name;exports[name]=plugin})},{each:4,"./integrations.js":6}],4:[function(require,module,exports){var type=require("type");var has=Object.prototype.hasOwnProperty;module.exports=function(obj,fn){switch(type(obj)){case"array":return array(obj,fn);case"object":if("number"==typeof obj.length)return array(obj,fn);return object(obj,fn);case"string":return string(obj,fn)}};function string(obj,fn){for(var i=0;i<obj.length;++i){fn(obj.charAt(i),i)}}function object(obj,fn){for(var key in obj){if(has.call(obj,key)){fn(key,obj[key])}}}function array(obj,fn){for(var i=0;i<obj.length;++i){fn(obj[i],i)}}},{type:7}],7:[function(require,module,exports){var toString=Object.prototype.toString;module.exports=function(val){switch(toString.call(val)){case"[object Date]":return"date";case"[object RegExp]":return"regexp";case"[object Arguments]":return"arguments";case"[object Array]":return"array";case"[object Error]":return"error"}if(val===null)return"null";if(val===undefined)return"undefined";if(val!==val)return"nan";if(val&&val.nodeType===1)return"element";val=val.valueOf?val.valueOf():Object.prototype.valueOf.apply(val);return typeof val}},{}],6:[function(require,module,exports){module.exports=[require("./lib/adroll"),require("./lib/adwords"),require("./lib/alexa"),require("./lib/amplitude"),require("./lib/appcues"),require("./lib/atatus"),require("./lib/autosend"),require("./lib/awesm"),require("./lib/bing-ads"),require("./lib/blueshift"),require("./lib/bronto"),require("./lib/bugherd"),require("./lib/bugsnag"),require("./lib/chartbeat"),require("./lib/churnbee"),require("./lib/clicktale"),require("./lib/clicky"),require("./lib/comscore"),require("./lib/crazy-egg"),require("./lib/curebit"),require("./lib/customerio"),require("./lib/drip"),require("./lib/errorception"),require("./lib/evergage"),require("./lib/extole"),require("./lib/facebook-conversion-tracking"),require("./lib/foxmetrics"),require("./lib/frontleaf"),require("./lib/fullstory"),require("./lib/gauges"),require("./lib/get-satisfaction"),require("./lib/google-analytics"),require("./lib/google-tag-manager"),require("./lib/gosquared"),require("./lib/heap"),require("./lib/hellobar"),require("./lib/hittail"),require("./lib/hubspot"),require("./lib/improvely"),require("./lib/insidevault"),require("./lib/inspectlet"),require("./lib/intercom"),require("./lib/keen-io"),require("./lib/kenshoo"),require("./lib/kissmetrics"),require("./lib/klaviyo"),require("./lib/livechat"),require("./lib/lucky-orange"),require("./lib/lytics"),require("./lib/mixpanel"),require("./lib/mojn"),require("./lib/mouseflow"),require("./lib/mousestats"),require("./lib/navilytics"),require("./lib/nudgespot"),require("./lib/olark"),require("./lib/optimizely"),require("./lib/perfect-audience"),require("./lib/pingdom"),require("./lib/piwik"),require("./lib/preact"),require("./lib/qualaroo"),require("./lib/quantcast"),require("./lib/rollbar"),require("./lib/saasquatch"),require("./lib/satismeter"),require("./lib/segmentio"),require("./lib/sentry"),require("./lib/snapengage"),require("./lib/spinnakr"),require("./lib/tapstream"),require("./lib/trakio"),require("./lib/twitter-ads"),require("./lib/userlike"),require("./lib/uservoice"),require("./lib/vero"),require("./lib/visual-website-optimizer"),require("./lib/webengage"),require("./lib/woopra"),require("./lib/yandex-metrica")]},{"./lib/adroll":8,"./lib/adwords":9,"./lib/alexa":10,"./lib/amplitude":11,"./lib/appcues":12,"./lib/atatus":13,"./lib/autosend":14,"./lib/awesm":15,"./lib/bing-ads":16,"./lib/blueshift":17,"./lib/bronto":18,"./lib/bugherd":19,"./lib/bugsnag":20,"./lib/chartbeat":21,"./lib/churnbee":22,"./lib/clicktale":23,"./lib/clicky":24,"./lib/comscore":25,"./lib/crazy-egg":26,"./lib/curebit":27,"./lib/customerio":28,"./lib/drip":29,"./lib/errorception":30,"./lib/evergage":31,"./lib/extole":32,"./lib/facebook-conversion-tracking":33,"./lib/foxmetrics":34,"./lib/frontleaf":35,"./lib/fullstory":36,"./lib/gauges":37,"./lib/get-satisfaction":38,"./lib/google-analytics":39,"./lib/google-tag-manager":40,"./lib/gosquared":41,"./lib/heap":42,"./lib/hellobar":43,"./lib/hittail":44,"./lib/hubspot":45,"./lib/improvely":46,"./lib/insidevault":47,"./lib/inspectlet":48,"./lib/intercom":49,"./lib/keen-io":50,"./lib/kenshoo":51,"./lib/kissmetrics":52,"./lib/klaviyo":53,"./lib/livechat":54,"./lib/lucky-orange":55,"./lib/lytics":56,"./lib/mixpanel":57,"./lib/mojn":58,"./lib/mouseflow":59,"./lib/mousestats":60,"./lib/navilytics":61,"./lib/nudgespot":62,"./lib/olark":63,"./lib/optimizely":64,"./lib/perfect-audience":65,"./lib/pingdom":66,"./lib/piwik":67,"./lib/preact":68,"./lib/qualaroo":69,"./lib/quantcast":70,"./lib/rollbar":71,"./lib/saasquatch":72,"./lib/satismeter":73,"./lib/segmentio":74,"./lib/sentry":75,"./lib/snapengage":76,"./lib/spinnakr":77,"./lib/tapstream":78,"./lib/trakio":79,"./lib/twitter-ads":80,"./lib/userlike":81,"./lib/uservoice":82,"./lib/vero":83,"./lib/visual-website-optimizer":84,"./lib/webengage":85,"./lib/woopra":86,"./lib/yandex-metrica":87}],8:[function(require,module,exports){var integration=require("analytics.js-integration");var snake=require("to-snake-case");var useHttps=require("use-https");var each=require("each");var is=require("is");var del=require("obj-case").del;var has=Object.prototype.hasOwnProperty;var AdRoll=module.exports=integration("AdRoll").assumesPageview().global("__adroll_loaded").global("adroll_adv_id").global("adroll_pix_id").global("adroll_custom_data").option("advId","").option("pixId","").tag("http",'<script src="http://a.adroll.com/j/roundtrip.js">').tag("https",'<script src="https://s.adroll.com/j/roundtrip.js">').mapping("events");AdRoll.prototype.initialize=function(page){window.adroll_adv_id=this.options.advId;window.adroll_pix_id=this.options.pixId;window.__adroll_loaded=true;var name=useHttps()?"https":"http";this.load(name,this.ready)};AdRoll.prototype.loaded=function(){return window.__adroll};AdRoll.prototype.page=function(page){var name=page.fullName();this.track(page.track(name))};AdRoll.prototype.track=function(track){var event=track.event();var user=this.analytics.user();var events=this.events(event);var total=track.revenue()||track.total()||0;var orderId=track.orderId()||0;var productId=track.id();var sku=track.sku();var customProps=track.properties();var data={};if(user.id())data.user_id=user.id();if(orderId)data.order_id=orderId;if(productId)data.product_id=productId;if(sku)data.sku=sku;del(customProps,"revenue");del(customProps,"total");del(customProps,"orderId");del(customProps,"id");del(customProps,"sku");if(!is.empty(customProps))data.adroll_custom_data=customProps;each(events,function(event){data.adroll_conversion_value_in_dollars=total;data.adroll_segments=snake(event);window.__adroll.record_user(data)});if(!events.length){data.adroll_segments=snake(event);window.__adroll.record_user(data)}}},{"analytics.js-integration":88,"to-snake-case":89,"use-https":90,each:4,is:91,"obj-case":92}],88:[function(require,module,exports){var bind=require("bind");var callback=require("callback");var clone=require("clone");var debug=require("debug");var defaults=require("defaults");var protos=require("./protos");var slug=require("slug");var statics=require("./statics");module.exports=createIntegration;function createIntegration(name){function Integration(options){if(options&&options.addIntegration){return options.addIntegration(Integration)}this.debug=debug("analytics:integration:"+slug(name));this.options=defaults(clone(options)||{},this.defaults);this._queue=[];this.once("ready",bind(this,this.flush));Integration.emit("construct",this);this.ready=bind(this,this.ready);this._wrapInitialize();this._wrapPage();this._wrapTrack()}Integration.prototype.defaults={};Integration.prototype.globals=[];Integration.prototype.templates={};Integration.prototype.name=name;for(var key in statics)Integration[key]=statics[key];for(var key in protos)Integration.prototype[key]=protos[key];return Integration}},{bind:93,callback:94,clone:95,debug:96,defaults:97,"./protos":98,slug:99,"./statics":100}],93:[function(require,module,exports){var bind=require("bind"),bindAll=require("bind-all");module.exports=exports=bind;exports.all=bindAll;exports.methods=bindMethods;function bindMethods(obj,methods){methods=[].slice.call(arguments,1);for(var i=0,method;method=methods[i];i++){obj[method]=bind(obj,obj[method])}return obj}},{bind:101,"bind-all":102}],101:[function(require,module,exports){var slice=[].slice;module.exports=function(obj,fn){if("string"==typeof fn)fn=obj[fn];if("function"!=typeof fn)throw new Error("bind() requires a function");var args=slice.call(arguments,2);return function(){return fn.apply(obj,args.concat(slice.call(arguments)))}}},{}],102:[function(require,module,exports){try{var bind=require("bind");var type=require("type")}catch(e){var bind=require("bind-component");var type=require("type-component")}module.exports=function(obj){for(var key in obj){var val=obj[key];if(type(val)==="function")obj[key]=bind(obj,obj[key])}return obj}},{bind:101,type:7}],94:[function(require,module,exports){var next=require("next-tick");module.exports=callback;function callback(fn){if("function"===typeof fn)fn()}callback.async=function(fn,wait){if("function"!==typeof fn)return;if(!wait)return next(fn);setTimeout(fn,wait)};callback.sync=callback},{"next-tick":103}],103:[function(require,module,exports){"use strict";if(typeof setImmediate=="function"){module.exports=function(f){setImmediate(f)}}else if(typeof process!="undefined"&&typeof process.nextTick=="function"){module.exports=process.nextTick}else if(typeof window=="undefined"||window.ActiveXObject||!window.postMessage){module.exports=function(f){setTimeout(f)}}else{var q=[];window.addEventListener("message",function(){var i=0;while(i<q.length){try{q[i++]()}catch(e){q=q.slice(i);window.postMessage("tic!","*");throw e}}q.length=0},true);module.exports=function(fn){if(!q.length)window.postMessage("tic!","*");q.push(fn)}}},{}],95:[function(require,module,exports){var type;try{type=require("type")}catch(e){type=require("type-component")}module.exports=clone;function clone(obj){switch(type(obj)){case"object":var copy={};for(var key in obj){if(obj.hasOwnProperty(key)){copy[key]=clone(obj[key])}}return copy;case"array":var copy=new Array(obj.length);for(var i=0,l=obj.length;i<l;i++){copy[i]=clone(obj[i])}return copy;case"regexp":var flags="";flags+=obj.multiline?"m":"";flags+=obj.global?"g":"";flags+=obj.ignoreCase?"i":"";return new RegExp(obj.source,flags);case"date":return new Date(obj.getTime());default:return obj}}},{type:7}],96:[function(require,module,exports){if("undefined"==typeof window){module.exports=require("./lib/debug")}else{module.exports=require("./debug")}},{"./lib/debug":104,"./debug":105}],104:[function(require,module,exports){var tty=require("tty");module.exports=debug;var names=[],skips=[];(process.env.DEBUG||"").split(/[\s,]+/).forEach(function(name){name=name.replace("*",".*?");if(name[0]==="-"){skips.push(new RegExp("^"+name.substr(1)+"$"))}else{names.push(new RegExp("^"+name+"$"))}});var colors=[6,2,3,4,5,1];var prev={};var prevColor=0;var isatty=tty.isatty(2);function color(){return colors[prevColor++%colors.length]}function humanize(ms){var sec=1e3,min=60*1e3,hour=60*min;if(ms>=hour)return(ms/hour).toFixed(1)+"h";if(ms>=min)return(ms/min).toFixed(1)+"m";if(ms>=sec)return(ms/sec|0)+"s";return ms+"ms"}function debug(name){function disabled(){}disabled.enabled=false;var match=skips.some(function(re){return re.test(name)});if(match)return disabled;match=names.some(function(re){return re.test(name)});if(!match)return disabled;var c=color();function colored(fmt){fmt=coerce(fmt);var curr=new Date;var ms=curr-(prev[name]||curr);prev[name]=curr;fmt=" [9"+c+"m"+name+" "+"[3"+c+"m"+fmt+"[3"+c+"m"+" +"+humanize(ms)+"";console.error.apply(this,arguments)}function plain(fmt){fmt=coerce(fmt);fmt=(new Date).toUTCString()+" "+name+" "+fmt;console.error.apply(this,arguments)}colored.enabled=plain.enabled=true;return isatty||process.env.DEBUG_COLORS?colored:plain}function coerce(val){if(val instanceof Error)return val.stack||val.message;return val}},{}],105:[function(require,module,exports){module.exports=debug;function debug(name){if(!debug.enabled(name))return function(){};return function(fmt){fmt=coerce(fmt);var curr=new Date;var ms=curr-(debug[name]||curr);debug[name]=curr;fmt=name+" "+fmt+" +"+debug.humanize(ms);window.console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}}debug.names=[];debug.skips=[];debug.enable=function(name){try{localStorage.debug=name}catch(e){}var split=(name||"").split(/[\s,]+/),len=split.length;for(var i=0;i<len;i++){name=split[i].replace("*",".*?");if(name[0]==="-"){debug.skips.push(new RegExp("^"+name.substr(1)+"$"))}else{debug.names.push(new RegExp("^"+name+"$"))}}};debug.disable=function(){debug.enable("")};debug.humanize=function(ms){var sec=1e3,min=60*1e3,hour=60*min;if(ms>=hour)return(ms/hour).toFixed(1)+"h";if(ms>=min)return(ms/min).toFixed(1)+"m";if(ms>=sec)return(ms/sec|0)+"s";return ms+"ms"};debug.enabled=function(name){for(var i=0,len=debug.skips.length;i<len;i++){if(debug.skips[i].test(name)){return false}}for(var i=0,len=debug.names.length;i<len;i++){if(debug.names[i].test(name)){return true}}return false};function coerce(val){if(val instanceof Error)return val.stack||val.message;return val}try{if(window.localStorage)debug.enable(localStorage.debug)}catch(e){}},{}],97:[function(require,module,exports){"use strict";var defaults=function(dest,src,recursive){for(var prop in src){if(recursive&&dest[prop]instanceof Object&&src[prop]instanceof Object){dest[prop]=defaults(dest[prop],src[prop],true)}else if(!(prop in dest)){dest[prop]=src[prop]}}return dest};module.exports=defaults},{}],98:[function(require,module,exports){var loadScript=require("load-script");var loadIframe=require("load-iframe");var events=require("analytics-events");var normalize=require("to-no-case");var callback=require("callback");var Emitter=require("emitter");var tick=require("next-tick");var after=require("after");var each=require("each");var type=require("type");var fmt=require("fmt");function noop(){}var setTimeout=window.setTimeout;var setInterval=window.setInterval;var onerror=window.onerror;var onload=null;Emitter(exports);exports.initialize=function(){var ready=this.ready;tick(ready)};exports.loaded=function(){return false};exports.page=function(page){};exports.track=function(track){};exports.map=function(obj,str){var a=normalize(str);var ret=[];if(!obj)return ret;if("object"==type(obj)){for(var k in obj){var item=obj[k];var b=normalize(k);if(b==a)ret.push(item)}}if("array"==type(obj)){if(!obj.length)return ret;if(!obj[0].key)return ret;for(var i=0;i<obj.length;++i){var item=obj[i];var b=normalize(item.key);if(b==a)ret.push(item.value)}}return ret};exports.invoke=function(method){if(!this[method])return;var args=[].slice.call(arguments,1);if(!this._ready)return this.queue(method,args);var ret;try{this.debug("%s with %o",method,args);ret=this[method].apply(this,args)}catch(e){this.debug("error %o calling %s with %o",e,method,args)}return ret};exports.queue=function(method,args){if("page"==method&&this._assumesPageview&&!this._initialized){return this.page.apply(this,args)}this._queue.push({method:method,args:args})};exports.flush=function(){this._ready=true;var call;while(call=this._queue.shift())this[call.method].apply(this,call.args)};exports.reset=function(){for(var i=0,key;key=this.globals[i];i++)window[key]=undefined;window.setTimeout=setTimeout;window.setInterval=setInterval;window.onerror=onerror;window.onload=onload};exports.load=function(name,locals,fn){if("function"==typeof name)fn=name,locals=null,name=null;if(name&&"object"==typeof name)fn=locals,locals=name,name=null;if("function"==typeof locals)fn=locals,locals=null;name=name||"library";locals=locals||{};locals=this.locals(locals);var template=this.templates[name];if(!template)throw new Error(fmt('template "%s" not defined.',name));var attrs=render(template,locals);var fn=fn||noop;var self=this;var el;switch(template.type){case"img":attrs.width=1;attrs.height=1;el=loadImage(attrs,fn);break;case"script":el=loadScript(attrs,function(err){if(!err)return fn();self.debug('error loading "%s" error="%s"',self.name,err)});delete attrs.src;each(attrs,function(key,val){el.setAttribute(key,val)});break;case"iframe":el=loadIframe(attrs,fn);break}return el};exports.locals=function(locals){locals=locals||{};var cache=Math.floor((new Date).getTime()/36e5);if(!locals.hasOwnProperty("cache"))locals.cache=cache;each(this.options,function(key,val){if(!locals.hasOwnProperty(key))locals[key]=val});return locals};exports.ready=function(){this.emit("ready")};exports._wrapInitialize=function(){var initialize=this.initialize;this.initialize=function(){this.debug("initialize");this._initialized=true;var ret=initialize.apply(this,arguments);this.emit("initialize");return ret};if(this._assumesPageview)this.initialize=after(2,this.initialize)};exports._wrapPage=function(){var page=this.page;this.page=function(){if(this._assumesPageview&&!this._initialized){return this.initialize.apply(this,arguments)}return page.apply(this,arguments)}};exports._wrapTrack=function(){var t=this.track;this.track=function(track){var event=track.event();var called;var ret;for(var method in events){var regexp=events[method];if(!this[method])continue;if(!regexp.test(event))continue;ret=this[method].apply(this,arguments);called=true;break}if(!called)ret=t.apply(this,arguments);return ret}};function loadImage(attrs,fn){fn=fn||function(){};var img=new Image;img.onerror=error(fn,"failed to load pixel",img);img.onload=function(){fn()};img.src=attrs.src;img.width=1;img.height=1;return img}function error(fn,message,img){return function(e){e=e||window.event;var err=new Error(message);err.event=e;err.source=img;fn(err)}}function render(template,locals){var attrs={};each(template.attrs,function(key,val){attrs[key]=val.replace(/\{\{\ *(\w+)\ *\}\}/g,function(_,$1){return locals[$1]})});return attrs}},{"load-script":106,"load-iframe":107,"analytics-events":108,"to-no-case":109,callback:94,emitter:110,"next-tick":103,after:111,each:112,type:113,fmt:114}],106:[function(require,module,exports){var onload=require("script-onload");var tick=require("next-tick");var type=require("type");module.exports=function loadScript(options,fn){if(!options)throw new Error("Cant load nothing...");if("string"==type(options))options={src:options};var https=document.location.protocol==="https:"||document.location.protocol==="chrome-extension:";if(options.src&&options.src.indexOf("//")===0){options.src=https?"https:"+options.src:"http:"+options.src}if(https&&options.https)options.src=options.https;else if(!https&&options.http)options.src=options.http;var script=document.createElement("script");script.type="text/javascript";script.async=true;script.src=options.src;if("function"==type(fn)){onload(script,fn)}tick(function(){var firstScript=document.getElementsByTagName("script")[0];firstScript.parentNode.insertBefore(script,firstScript)});return script}},{"script-onload":115,"next-tick":103,type:7}],115:[function(require,module,exports){module.exports=function(el,fn){return el.addEventListener?add(el,fn):attach(el,fn)};function add(el,fn){el.addEventListener("load",function(_,e){fn(null,e)},false);el.addEventListener("error",function(e){var err=new Error('script error "'+el.src+'"');err.event=e;fn(err)},false)}function attach(el,fn){el.attachEvent("onreadystatechange",function(e){if(!/complete|loaded/.test(el.readyState))return;fn(null,e)});el.attachEvent("onerror",function(e){var err=new Error('failed to load the script "'+el.src+'"');err.event=e||window.event;fn(err)})}},{}],107:[function(require,module,exports){var onload=require("script-onload");var tick=require("next-tick");var type=require("type");module.exports=function loadIframe(options,fn){if(!options)throw new Error("Cant load nothing...");if("string"==type(options))options={src:options};var https=document.location.protocol==="https:"||document.location.protocol==="chrome-extension:";if(options.src&&options.src.indexOf("//")===0){options.src=https?"https:"+options.src:"http:"+options.src}if(https&&options.https)options.src=options.https;else if(!https&&options.http)options.src=options.http;var iframe=document.createElement("iframe");iframe.src=options.src;iframe.width=options.width||1;iframe.height=options.height||1;iframe.style.display="none";if("function"==type(fn)){onload(iframe,fn)}tick(function(){var firstScript=document.getElementsByTagName("script")[0];firstScript.parentNode.insertBefore(iframe,firstScript)});return iframe}},{"script-onload":115,"next-tick":103,type:7}],108:[function(require,module,exports){module.exports={removedProduct:/^[ _]?removed[ _]?product[ _]?$/i,viewedProduct:/^[ _]?viewed[ _]?product[ _]?$/i,viewedProductCategory:/^[ _]?viewed[ _]?product[ _]?category[ _]?$/i,addedProduct:/^[ _]?added[ _]?product[ _]?$/i,completedOrder:/^[ _]?completed[ _]?order[ _]?$/i,startedOrder:/^[ _]?started[ _]?order[ _]?$/i,updatedOrder:/^[ _]?updated[ _]?order[ _]?$/i,refundedOrder:/^[ _]?refunded?[ _]?order[ _]?$/i,viewedProductDetails:/^[ _]?viewed[ _]?product[ _]?details?[ _]?$/i,clickedProduct:/^[ _]?clicked[ _]?product[ _]?$/i,viewedPromotion:/^[ _]?viewed[ _]?promotion?[ _]?$/i,clickedPromotion:/^[ _]?clicked[ _]?promotion?[ _]?$/i,viewedCheckoutStep:/^[ _]?viewed[ _]?checkout[ _]?step[ _]?$/i,completedCheckoutStep:/^[ _]?completed[ _]?checkout[ _]?step[ _]?$/i}},{}],109:[function(require,module,exports){module.exports=toNoCase;var hasSpace=/\s/;var hasSeparator=/[\W_]/;function toNoCase(string){if(hasSpace.test(string))return string.toLowerCase();if(hasSeparator.test(string))return unseparate(string).toLowerCase();return uncamelize(string).toLowerCase()}var separatorSplitter=/[\W_]+(.|$)/g;function unseparate(string){return string.replace(separatorSplitter,function(m,next){return next?" "+next:""})}var camelSplitter=/(.)([A-Z]+)/g;function uncamelize(string){return string.replace(camelSplitter,function(m,previous,uppers){return previous+" "+uppers.toLowerCase().split("").join(" ")})}},{}],110:[function(require,module,exports){var index=require("indexof");module.exports=Emitter;function Emitter(obj){if(obj)return mixin(obj)}function mixin(obj){for(var key in Emitter.prototype){obj[key]=Emitter.prototype[key]}return obj}Emitter.prototype.on=Emitter.prototype.addEventListener=function(event,fn){this._callbacks=this._callbacks||{};(this._callbacks[event]=this._callbacks[event]||[]).push(fn);return this};Emitter.prototype.once=function(event,fn){var self=this;this._callbacks=this._callbacks||{};function on(){self.off(event,on);fn.apply(this,arguments)}fn._off=on;this.on(event,on);return this};Emitter.prototype.off=Emitter.prototype.removeListener=Emitter.prototype.removeAllListeners=Emitter.prototype.removeEventListener=function(event,fn){this._callbacks=this._callbacks||{};if(0==arguments.length){this._callbacks={};return this}var callbacks=this._callbacks[event];if(!callbacks)return this;if(1==arguments.length){delete this._callbacks[event];return this}var i=index(callbacks,fn._off||fn);if(~i)callbacks.splice(i,1);return this};Emitter.prototype.emit=function(event){this._callbacks=this._callbacks||{};var args=[].slice.call(arguments,1),callbacks=this._callbacks[event];if(callbacks){callbacks=callbacks.slice(0);for(var i=0,len=callbacks.length;i<len;++i){callbacks[i].apply(this,args)}}return this};Emitter.prototype.listeners=function(event){this._callbacks=this._callbacks||{};return this._callbacks[event]||[]};Emitter.prototype.hasListeners=function(event){return!!this.listeners(event).length}},{indexof:116}],116:[function(require,module,exports){module.exports=function(arr,obj){if(arr.indexOf)return arr.indexOf(obj);for(var i=0;i<arr.length;++i){if(arr[i]===obj)return i}return-1}},{}],111:[function(require,module,exports){module.exports=function after(times,func){if(times<=0)return func();return function(){if(--times<1){return func.apply(this,arguments)}}}},{}],112:[function(require,module,exports){try{var type=require("type")}catch(err){var type=require("component-type")}var toFunction=require("to-function");var has=Object.prototype.hasOwnProperty;module.exports=function(obj,fn,ctx){fn=toFunction(fn);ctx=ctx||this;switch(type(obj)){case"array":return array(obj,fn,ctx);case"object":if("number"==typeof obj.length)return array(obj,fn,ctx);return object(obj,fn,ctx);case"string":return string(obj,fn,ctx)}};function string(obj,fn,ctx){for(var i=0;i<obj.length;++i){fn.call(ctx,obj.charAt(i),i)}}function object(obj,fn,ctx){for(var key in obj){if(has.call(obj,key)){fn.call(ctx,key,obj[key])}}}function array(obj,fn,ctx){for(var i=0;i<obj.length;++i){fn.call(ctx,obj[i],i)}}},{type:113,"component-type":113,"to-function":117}],113:[function(require,module,exports){var toString=Object.prototype.toString;module.exports=function(val){switch(toString.call(val)){case"[object Function]":return"function";case"[object Date]":return"date";case"[object RegExp]":return"regexp";case"[object Arguments]":return"arguments";case"[object Array]":return"array";case"[object String]":return"string"}if(val===null)return"null";if(val===undefined)return"undefined";if(val&&val.nodeType===1)return"element";if(val===Object(val))return"object";return typeof val}},{}],117:[function(require,module,exports){var expr;try{expr=require("props")}catch(e){expr=require("component-props")}module.exports=toFunction;function toFunction(obj){switch({}.toString.call(obj)){case"[object Object]":return objectToFunction(obj);case"[object Function]":return obj;case"[object String]":return stringToFunction(obj);case"[object RegExp]":return regexpToFunction(obj);default:return defaultToFunction(obj)}}function defaultToFunction(val){return function(obj){return val===obj}}function regexpToFunction(re){return function(obj){return re.test(obj)}}function stringToFunction(str){if(/^ *\W+/.test(str))return new Function("_","return _ "+str);return new Function("_","return "+get(str))}function objectToFunction(obj){var match={};for(var key in obj){match[key]=typeof obj[key]==="string"?defaultToFunction(obj[key]):toFunction(obj[key])}return function(val){if(typeof val!=="object")return false;for(var key in match){if(!(key in val))return false;if(!match[key](val[key]))return false}return true}}function get(str){var props=expr(str);if(!props.length)return"_."+str;var val,i,prop;for(i=0;i<props.length;i++){prop=props[i];val="_."+prop;val="('function' == typeof "+val+" ? "+val+"() : "+val+")";str=stripNested(prop,str,val)}return str}function stripNested(prop,str,val){return str.replace(new RegExp("(\\.)?"+prop,"g"),function($0,$1){return $1?$0:val})}},{props:118,"component-props":118}],118:[function(require,module,exports){var globals=/\b(this|Array|Date|Object|Math|JSON)\b/g;module.exports=function(str,fn){var p=unique(props(str));if(fn&&"string"==typeof fn)fn=prefixed(fn);if(fn)return map(str,p,fn);return p};function props(str){return str.replace(/\.\w+|\w+ *\(|"[^"]*"|'[^']*'|\/([^/]+)\//g,"").replace(globals,"").match(/[$a-zA-Z_]\w*/g)||[]}function map(str,props,fn){var re=/\.\w+|\w+ *\(|"[^"]*"|'[^']*'|\/([^/]+)\/|[a-zA-Z_]\w*/g;return str.replace(re,function(_){if("("==_[_.length-1])return fn(_);if(!~props.indexOf(_))return _;return fn(_)})}function unique(arr){var ret=[];for(var i=0;i<arr.length;i++){if(~ret.indexOf(arr[i]))continue;ret.push(arr[i])}return ret}function prefixed(str){return function(_){return str+_}}},{}],114:[function(require,module,exports){var toString=window.JSON?JSON.stringify:function(_){return String(_)};module.exports=fmt;fmt.o=toString;fmt.s=String;fmt.d=parseInt;function fmt(str){var args=[].slice.call(arguments,1);var j=0;return str.replace(/%([a-z])/gi,function(_,f){return fmt[f]?fmt[f](args[j++]):_+f})}},{}],99:[function(require,module,exports){module.exports=function(str,options){options||(options={});return str.toLowerCase().replace(options.replace||/[^a-z0-9]/g," ").replace(/^ +| +$/g,"").replace(/ +/g,options.separator||"-")}},{}],100:[function(require,module,exports){var after=require("after");var domify=require("domify");var each=require("each");var Emitter=require("emitter");Emitter(exports);exports.option=function(key,value){this.prototype.defaults[key]=value;return this};exports.mapping=function(name){this.option(name,[]);this.prototype[name]=function(str){return this.map(this.options[name],str)};return this};exports.global=function(key){this.prototype.globals.push(key);return this};exports.assumesPageview=function(){this.prototype._assumesPageview=true;return this};exports.readyOnLoad=function(){this.prototype._readyOnLoad=true;return this};exports.readyOnInitialize=function(){this.prototype._readyOnInitialize=true;return this};exports.tag=function(name,str){if(null==str){str=name;name="library"}this.prototype.templates[name]=objectify(str);return this};function objectify(str){str=str.replace(' src="',' data-src="');var el=domify(str);var attrs={};each(el.attributes,function(attr){var name="data-src"==attr.name?"src":attr.name;if(!~str.indexOf(attr.name+"="))return;attrs[name]=attr.value});return{type:el.tagName.toLowerCase(),attrs:attrs}}},{after:111,domify:119,each:112,emitter:110}],119:[function(require,module,exports){module.exports=parse;var div=document.createElement("div");div.innerHTML=' <link/><table></table><a href="/a">a</a><input type="checkbox"/>';var innerHTMLBug=!div.getElementsByTagName("link").length;div=undefined;var map={legend:[1,"<fieldset>","</fieldset>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],_default:innerHTMLBug?[1,"X<div>","</div>"]:[0,"",""]};map.td=map.th=[3,"<table><tbody><tr>","</tr></tbody></table>"];map.option=map.optgroup=[1,'<select multiple="multiple">',"</select>"];map.thead=map.tbody=map.colgroup=map.caption=map.tfoot=[1,"<table>","</table>"];map.text=map.circle=map.ellipse=map.line=map.path=map.polygon=map.polyline=map.rect=[1,'<svg xmlns="http://www.w3.org/2000/svg" version="1.1">',"</svg>"];function parse(html,doc){if("string"!=typeof html)throw new TypeError("String expected");if(!doc)doc=document;var m=/<([\w:]+)/.exec(html);if(!m)return doc.createTextNode(html);html=html.replace(/^\s+|\s+$/g,"");var tag=m[1];if(tag=="body"){var el=doc.createElement("html");el.innerHTML=html;return el.removeChild(el.lastChild)}var wrap=map[tag]||map._default;var depth=wrap[0]; +var prefix=wrap[1];var suffix=wrap[2];var el=doc.createElement("div");el.innerHTML=prefix+html+suffix;while(depth--)el=el.lastChild;if(el.firstChild==el.lastChild){return el.removeChild(el.firstChild)}var fragment=doc.createDocumentFragment();while(el.firstChild){fragment.appendChild(el.removeChild(el.firstChild))}return fragment}},{}],89:[function(require,module,exports){var toSpace=require("to-space-case");module.exports=toSnakeCase;function toSnakeCase(string){return toSpace(string).replace(/\s/g,"_")}},{"to-space-case":120}],120:[function(require,module,exports){var clean=require("to-no-case");module.exports=toSpaceCase;function toSpaceCase(string){return clean(string).replace(/[\W_]+(.|$)/g,function(matches,match){return match?" "+match:""})}},{"to-no-case":121}],121:[function(require,module,exports){module.exports=toNoCase;var hasSpace=/\s/;var hasCamel=/[a-z][A-Z]/;var hasSeparator=/[\W_]/;function toNoCase(string){if(hasSpace.test(string))return string.toLowerCase();if(hasSeparator.test(string))string=unseparate(string);if(hasCamel.test(string))string=uncamelize(string);return string.toLowerCase()}var separatorSplitter=/[\W_]+(.|$)/g;function unseparate(string){return string.replace(separatorSplitter,function(m,next){return next?" "+next:""})}var camelSplitter=/(.)([A-Z]+)/g;function uncamelize(string){return string.replace(camelSplitter,function(m,previous,uppers){return previous+" "+uppers.toLowerCase().split("").join(" ")})}},{}],90:[function(require,module,exports){module.exports=function(url){switch(arguments.length){case 0:return check();case 1:return transform(url)}};function transform(url){return check()?"https:"+url:"http:"+url}function check(){return location.protocol=="https:"||location.protocol=="chrome-extension:"}},{}],91:[function(require,module,exports){var isEmpty=require("is-empty");try{var typeOf=require("type")}catch(e){var typeOf=require("component-type")}var types=["arguments","array","boolean","date","element","function","null","number","object","regexp","string","undefined"];for(var i=0,type;type=types[i];i++)exports[type]=generate(type);exports.fn=exports["function"];exports.empty=isEmpty;exports.nan=function(val){return exports.number(val)&&val!=val};function generate(type){return function(value){return type===typeOf(value)}}},{"is-empty":122,type:7,"component-type":7}],122:[function(require,module,exports){module.exports=isEmpty;var has=Object.prototype.hasOwnProperty;function isEmpty(val){if(null==val)return true;if("number"==typeof val)return 0===val;if(undefined!==val.length)return 0===val.length;for(var key in val)if(has.call(val,key))return false;return true}},{}],92:[function(require,module,exports){var Case=require("case");var identity=function(_){return _};var cases=[identity,Case.upper,Case.lower,Case.snake,Case.pascal,Case.camel,Case.constant,Case.title,Case.capital,Case.sentence];module.exports=module.exports.find=multiple(find);module.exports.replace=function(obj,key,val){multiple(replace).apply(this,arguments);return obj};module.exports.del=function(obj,key){multiple(del).apply(this,arguments);return obj};function multiple(fn){return function(obj,key,val){var keys=key.split(".");if(keys.length===0)return;while(keys.length>1){key=keys.shift();obj=find(obj,key);if(obj===null||obj===undefined)return}key=keys.shift();return fn(obj,key,val)}}function find(obj,key){for(var i=0;i<cases.length;i++){var cased=cases[i](key);if(obj.hasOwnProperty(cased))return obj[cased]}}function del(obj,key){for(var i=0;i<cases.length;i++){var cased=cases[i](key);if(obj.hasOwnProperty(cased))delete obj[cased]}return obj}function replace(obj,key,val){for(var i=0;i<cases.length;i++){var cased=cases[i](key);if(obj.hasOwnProperty(cased))obj[cased]=val}return obj}},{"case":123}],123:[function(require,module,exports){var cases=require("./cases");module.exports=exports=determineCase;function determineCase(string){for(var key in cases){if(key=="none")continue;var convert=cases[key];if(convert(string)==string)return key}return null}exports.add=function(name,convert){exports[name]=cases[name]=convert};for(var key in cases){exports.add(key,cases[key])}},{"./cases":124}],124:[function(require,module,exports){var camel=require("to-camel-case"),capital=require("to-capital-case"),constant=require("to-constant-case"),dot=require("to-dot-case"),none=require("to-no-case"),pascal=require("to-pascal-case"),sentence=require("to-sentence-case"),slug=require("to-slug-case"),snake=require("to-snake-case"),space=require("to-space-case"),title=require("to-title-case");exports.camel=camel;exports.pascal=pascal;exports.dot=dot;exports.slug=slug;exports.snake=snake;exports.space=space;exports.constant=constant;exports.capital=capital;exports.title=title;exports.sentence=sentence;exports.lower=function(string){return none(string).toLowerCase()};exports.upper=function(string){return none(string).toUpperCase()};exports.inverse=function(string){for(var i=0,char;char=string[i];i++){if(!/[a-z]/i.test(char))continue;var upper=char.toUpperCase();var lower=char.toLowerCase();string[i]=char==upper?lower:upper}return string};exports.none=none},{"to-camel-case":125,"to-capital-case":126,"to-constant-case":127,"to-dot-case":128,"to-no-case":121,"to-pascal-case":129,"to-sentence-case":130,"to-slug-case":131,"to-snake-case":132,"to-space-case":133,"to-title-case":134}],125:[function(require,module,exports){var toSpace=require("to-space-case");module.exports=toCamelCase;function toCamelCase(string){return toSpace(string).replace(/\s(\w)/g,function(matches,letter){return letter.toUpperCase()})}},{"to-space-case":133}],133:[function(require,module,exports){var clean=require("to-no-case");module.exports=toSpaceCase;function toSpaceCase(string){return clean(string).replace(/[\W_]+(.|$)/g,function(matches,match){return match?" "+match:""})}},{"to-no-case":121}],126:[function(require,module,exports){var clean=require("to-no-case");module.exports=toCapitalCase;function toCapitalCase(string){return clean(string).replace(/(^|\s)(\w)/g,function(matches,previous,letter){return previous+letter.toUpperCase()})}},{"to-no-case":121}],127:[function(require,module,exports){var snake=require("to-snake-case");module.exports=toConstantCase;function toConstantCase(string){return snake(string).toUpperCase()}},{"to-snake-case":132}],132:[function(require,module,exports){var toSpace=require("to-space-case");module.exports=toSnakeCase;function toSnakeCase(string){return toSpace(string).replace(/\s/g,"_")}},{"to-space-case":133}],128:[function(require,module,exports){var toSpace=require("to-space-case");module.exports=toDotCase;function toDotCase(string){return toSpace(string).replace(/\s/g,".")}},{"to-space-case":133}],129:[function(require,module,exports){var toSpace=require("to-space-case");module.exports=toPascalCase;function toPascalCase(string){return toSpace(string).replace(/(?:^|\s)(\w)/g,function(matches,letter){return letter.toUpperCase()})}},{"to-space-case":133}],130:[function(require,module,exports){var clean=require("to-no-case");module.exports=toSentenceCase;function toSentenceCase(string){return clean(string).replace(/[a-z]/i,function(letter){return letter.toUpperCase()})}},{"to-no-case":121}],131:[function(require,module,exports){var toSpace=require("to-space-case");module.exports=toSlugCase;function toSlugCase(string){return toSpace(string).replace(/\s/g,"-")}},{"to-space-case":133}],134:[function(require,module,exports){var capital=require("to-capital-case"),escape=require("escape-regexp"),map=require("map"),minors=require("title-case-minors");module.exports=toTitleCase;var escaped=map(minors,escape);var minorMatcher=new RegExp("[^^]\\b("+escaped.join("|")+")\\b","ig");var colonMatcher=/:\s*(\w)/g;function toTitleCase(string){return capital(string).replace(minorMatcher,function(minor){return minor.toLowerCase()}).replace(colonMatcher,function(letter){return letter.toUpperCase()})}},{"to-capital-case":126,"escape-regexp":135,map:136,"title-case-minors":137}],135:[function(require,module,exports){module.exports=function(str){return String(str).replace(/([.*+?=^!:${}()|[\]\/\\])/g,"\\$1")}},{}],136:[function(require,module,exports){var each=require("each");module.exports=function map(obj,iterator){var arr=[];each(obj,function(o){arr.push(iterator.apply(null,arguments))});return arr}},{each:112}],137:[function(require,module,exports){module.exports=["a","an","and","as","at","but","by","en","for","from","how","if","in","neither","nor","of","on","only","onto","out","or","per","so","than","that","the","to","until","up","upon","v","v.","versus","vs","vs.","via","when","with","without","yet"]},{}],9:[function(require,module,exports){var integration=require("analytics.js-integration");var domify=require("domify");var each=require("each");var has=Object.prototype.hasOwnProperty;var AdWords=module.exports=integration("AdWords").option("conversionId","").option("remarketing",false).tag('<script src="//www.googleadservices.com/pagead/conversion_async.js">').mapping("events");AdWords.prototype.initialize=function(){this.load(this.ready)};AdWords.prototype.loaded=function(){return!!document.body};AdWords.prototype.page=function(page){var remarketing=!!this.options.remarketing;var id=this.options.conversionId;var props={};window.google_trackConversion({google_conversion_id:id,google_custom_params:props,google_remarketing_only:remarketing})};AdWords.prototype.track=function(track){var id=this.options.conversionId;var events=this.events(track.event());var revenue=track.revenue()||0;each(events,function(label){var props=track.properties();delete props.revenue;window.google_trackConversion({google_conversion_id:id,google_custom_params:props,google_conversion_language:"en",google_conversion_format:"3",google_conversion_color:"ffffff",google_conversion_label:label,google_conversion_value:revenue,google_remarketing_only:false})})}},{"analytics.js-integration":88,domify:119,each:4}],10:[function(require,module,exports){var integration=require("analytics.js-integration");var Alexa=module.exports=integration("Alexa").assumesPageview().global("_atrk_opts").option("account",null).option("domain","").option("dynamic",true).tag('<script src="//d31qbv1cthcecs.cloudfront.net/atrk.js">');Alexa.prototype.initialize=function(page){var self=this;window._atrk_opts={atrk_acct:this.options.account,domain:this.options.domain,dynamic:this.options.dynamic};this.load(function(){window.atrk();self.ready()})};Alexa.prototype.loaded=function(){return!!window.atrk}},{"analytics.js-integration":88}],11:[function(require,module,exports){var integration=require("analytics.js-integration");var utm=require("utm-params");var top=require("top-domain");var umd="function"==typeof define&&define.amd;var src="//d24n15hnbwhuhn.cloudfront.net/libs/amplitude-2.0.3-min.js";var Amplitude=module.exports=integration("Amplitude").global("amplitude").option("apiKey","").option("trackAllPages",false).option("trackNamedPages",true).option("trackCategorizedPages",true).tag('<script src="'+src+'">');Amplitude.prototype.initialize=function(page){(function(h,a){var f=h.amplitude||{};f._q=[];function e(i){f[i]=function(){f._q.push([i].concat(Array.prototype.slice.call(arguments,0)))}}var c=["init","logEvent","setUserId","setUserProperties","setVersionName","setDomain","setDeviceId","setGlobalUserProperties"];for(var d=0;d<c.length;d++){e(c[d])}h.amplitude=f})(window,document);this.setDomain(window.location.href);window.amplitude.init(this.options.apiKey);this.setUserProperties(window.location.search);var self=this;if(umd){window.require([src],function(amplitude){window.amplitude=amplitude;self.ready()});return}this.load(function(){self.ready()})};Amplitude.prototype.loaded=function(){return!!(window.amplitude&&window.amplitude.options)};Amplitude.prototype.page=function(page){var properties=page.properties();var category=page.category();var name=page.fullName();var opts=this.options;if(opts.trackAllPages){this.track(page.track())}if(category&&opts.trackCategorizedPages){this.track(page.track(category))}if(name&&opts.trackNamedPages){this.track(page.track(name))}};Amplitude.prototype.identify=function(identify){var id=identify.userId();var traits=identify.traits();if(id)window.amplitude.setUserId(id);if(traits)window.amplitude.setUserProperties(traits)};Amplitude.prototype.track=function(track){var props=track.properties();var event=track.event();window.amplitude.logEvent(event,props)};Amplitude.prototype.setDomain=function(href){var domain=top(href);window.amplitude.setDomain(domain)};Amplitude.prototype.setDeviceId=function(deviceId){if(deviceId)window.amplitude.setDeviceId(deviceId)};Amplitude.prototype.setUserProperties=function(query){var campaign=utm(query);var campaignName=campaign.name;campaign.campaign=campaignName;delete campaign.name;if(campaign)window.amplitude.setUserProperties(campaign)}},{"analytics.js-integration":88,"utm-params":138,"top-domain":139}],138:[function(require,module,exports){var parse=require("querystring").parse;module.exports=utm;function utm(query){if("?"==query.charAt(0))query=query.substring(1);var query=query.replace(/\?/g,"&");var params=parse(query);var param;var ret={};for(var key in params){if(~key.indexOf("utm_")){param=key.substr(4);if("campaign"==param)param="name";ret[param]=params[key]}}return ret}},{querystring:140}],140:[function(require,module,exports){var encode=encodeURIComponent;var decode=decodeURIComponent;var trim=require("trim");var type=require("type");exports.parse=function(str){if("string"!=typeof str)return{};str=trim(str);if(""==str)return{};if("?"==str.charAt(0))str=str.slice(1);var obj={};var pairs=str.split("&");for(var i=0;i<pairs.length;i++){var parts=pairs[i].split("=");var key=decode(parts[0]);var m;if(m=/(\w+)\[(\d+)\]/.exec(key)){obj[m[1]]=obj[m[1]]||[];obj[m[1]][m[2]]=decode(parts[1]);continue}obj[parts[0]]=null==parts[1]?"":decode(parts[1])}return obj};exports.stringify=function(obj){if(!obj)return"";var pairs=[];for(var key in obj){var value=obj[key];if("array"==type(value)){for(var i=0;i<value.length;++i){pairs.push(encode(key+"["+i+"]")+"="+encode(value[i]))}continue}pairs.push(encode(key)+"="+encode(obj[key]))}return pairs.join("&")}},{trim:141,type:7}],141:[function(require,module,exports){exports=module.exports=trim;function trim(str){if(str.trim)return str.trim();return str.replace(/^\s*|\s*$/g,"")}exports.left=function(str){if(str.trimLeft)return str.trimLeft();return str.replace(/^\s*/,"")};exports.right=function(str){if(str.trimRight)return str.trimRight();return str.replace(/\s*$/,"")}},{}],139:[function(require,module,exports){var parse=require("url").parse;module.exports=domain;var regexp=/[a-z0-9][a-z0-9\-]*[a-z0-9]\.[a-z\.]{2,6}$/i;function domain(url){var host=parse(url).hostname;var match=host.match(regexp);return match?match[0]:""}},{url:142}],142:[function(require,module,exports){exports.parse=function(url){var a=document.createElement("a");a.href=url;return{href:a.href,host:a.host||location.host,port:"0"===a.port||""===a.port?port(a.protocol):a.port,hash:a.hash,hostname:a.hostname||location.hostname,pathname:a.pathname.charAt(0)!="/"?"/"+a.pathname:a.pathname,protocol:!a.protocol||":"==a.protocol?location.protocol:a.protocol,search:a.search,query:a.search.slice(1)}};exports.isAbsolute=function(url){return 0==url.indexOf("//")||!!~url.indexOf("://")};exports.isRelative=function(url){return!exports.isAbsolute(url)};exports.isCrossDomain=function(url){url=exports.parse(url);var location=exports.parse(window.location.href);return url.hostname!==location.hostname||url.port!==location.port||url.protocol!==location.protocol};function port(protocol){switch(protocol){case"http:":return 80;case"https:":return 443;default:return location.port}}},{}],12:[function(require,module,exports){var integration=require("analytics.js-integration");var load=require("load-script");var is=require("is");module.exports=exports=function(analytics){analytics.addIntegration(Appcues)};var Appcues=exports.Integration=integration("Appcues").assumesPageview().global("Appcues").global("AppcuesIdentity").option("appcuesId","").option("userId","").option("userEmail","");Appcues.prototype.initialize=function(){this.load(function(){window.Appcues.init()})};Appcues.prototype.loaded=function(){return is.object(window.Appcues)};Appcues.prototype.load=function(callback){var script=load("//d2dubfq97s02eu.cloudfront.net/appcues-bundle.min.js",callback);script.setAttribute("data-appcues-id",this.options.appcuesId);script.setAttribute("data-user-id",this.options.userId);script.setAttribute("data-user-email",this.options.userEmail)};Appcues.prototype.identify=function(identify){window.Appcues.identify(identify.traits())}},{"analytics.js-integration":88,"load-script":143,is:91}],143:[function(require,module,exports){var onload=require("script-onload");var tick=require("next-tick");var type=require("type");module.exports=function loadScript(options,fn){if(!options)throw new Error("Cant load nothing...");if("string"==type(options))options={src:options};var https=document.location.protocol==="https:"||document.location.protocol==="chrome-extension:";if(options.src&&options.src.indexOf("//")===0){options.src=https?"https:"+options.src:"http:"+options.src}if(https&&options.https)options.src=options.https;else if(!https&&options.http)options.src=options.http;var script=document.createElement("script");script.type="text/javascript";script.async=true;script.src=options.src;if("function"==type(fn)){onload(script,fn)}tick(function(){var firstScript=document.getElementsByTagName("script")[0];firstScript.parentNode.insertBefore(script,firstScript)});return script}},{"script-onload":115,"next-tick":103,type:7}],13:[function(require,module,exports){var integration=require("analytics.js-integration");var is=require("is");var Atatus=module.exports=integration("Atatus").global("atatus").option("apiKey","").tag('<script src="//www.atatus.com/atatus.js">');Atatus.prototype.initialize=function(page){var self=this;this.load(function(){window.atatus.config(self.options.apiKey).install();self.ready()})};Atatus.prototype.loaded=function(){return is.object(window.atatus)};Atatus.prototype.identify=function(identify){window.atatus.setCustomData({person:identify.traits()})}},{"analytics.js-integration":88,is:91}],14:[function(require,module,exports){var integration=require("analytics.js-integration");var Autosend=module.exports=integration("Autosend").global("_autosend").option("appKey","").tag('<script id="asnd-tracker" src="https://d2zjxodm1cz8d6.cloudfront.net/js/v1/autosend.js" data-auth-key="{{ appKey }}">');Autosend.prototype.initialize=function(page){window._autosend=window._autosend||[];(function(){var a,b,c;a=function(f){return function(){window._autosend.push([f].concat(Array.prototype.slice.call(arguments,0)))}};b=["identify","track","cb"];for(c=0;c<b.length;c++){window._autosend[b[c]]=a(b[c])}})();this.load(this.ready)};Autosend.prototype.loaded=function(){return!!window._autosend};Autosend.prototype.identify=function(identify){var id=identify.userId();if(!id)return;var traits=identify.traits();traits.id=id;window._autosend.identify(traits)};Autosend.prototype.track=function(track){window._autosend.track(track.event())}},{"analytics.js-integration":88}],15:[function(require,module,exports){var integration=require("analytics.js-integration");var each=require("each");var Awesm=module.exports=integration("awe.sm").assumesPageview().global("AWESM").option("apiKey","").tag('<script src="//widgets.awe.sm/v3/widgets.js?key={{ apiKey }}&async=true">').mapping("events");Awesm.prototype.initialize=function(page){window.AWESM={api_key:this.options.apiKey};this.load(this.ready)};Awesm.prototype.loaded=function(){return!!(window.AWESM&&window.AWESM._exists)};Awesm.prototype.track=function(track){var user=this.analytics.user();var goals=this.events(track.event());each(goals,function(goal){window.AWESM.convert(goal,track.cents(),null,user.id())})}},{"analytics.js-integration":88,each:4}],16:[function(require,module,exports){var integration=require("analytics.js-integration");var onbody=require("on-body");var domify=require("domify");var extend=require("extend");var bind=require("bind");var when=require("when");var each=require("each");var has=Object.prototype.hasOwnProperty;var noop=function(){};var Bing=module.exports=integration("Bing Ads").global("uetq").option("tagId","").tag('<script src="//bat.bing.com/bat.js">');Bing.prototype.initialize=function(){window.uetq=window.uetq||[];var self=this;self.load(function(){var setup={ti:self.options.tagId,q:window.uetq};window.uetq=new UET(setup);self.ready()})};Bing.prototype.loaded=function(){return!!(window.uetq&&window.uetq.push!==Array.prototype.push)};Bing.prototype.page=function(){window.uetq.push("pageLoad")};Bing.prototype.track=function(track){var event={ea:"track",el:track.event()};if(track.category())event.ec=track.category();if(track.revenue())event.ev=track.revenue();window.uetq.push(event)}},{"analytics.js-integration":88,"on-body":144,domify:119,extend:145,bind:101,when:146,each:4}],144:[function(require,module,exports){var each=require("each");var body=false;var callbacks=[];module.exports=function onBody(callback){if(body){call(callback)}else{callbacks.push(callback)}};var interval=setInterval(function(){if(!document.body)return;body=true;each(callbacks,call);clearInterval(interval)},5);function call(callback){callback(document.body)}},{each:112}],145:[function(require,module,exports){module.exports=function extend(object){var args=Array.prototype.slice.call(arguments,1);for(var i=0,source;source=args[i];i++){if(!source)continue;for(var property in source){object[property]=source[property]}}return object}},{}],146:[function(require,module,exports){var callback=require("callback");module.exports=when;function when(condition,fn,interval){if(condition())return callback.async(fn);var ref=setInterval(function(){if(!condition())return;callback(fn);clearInterval(ref)},interval||10)}},{callback:94}],17:[function(require,module,exports){var integration=require("analytics.js-integration");var Blueshift=module.exports=integration("Blueshift").global("blueshift").global("_blueshiftid").option("apiKey","").option("retarget",false).tag('<script src="https://cdn.getblueshift.com/blueshift.js">');Blueshift.prototype.initialize=function(page){window.blueshift=window.blueshift||[];window.blueshift.load=function(a){window._blueshiftid=a;var d=function(a){return function(){blueshift.push([a].concat(Array.prototype.slice.call(arguments,0)))}},e=["identify","track","click","pageload","capture","retarget"];for(var f=0;f<e.length;f++)blueshift[e[f]]=d(e[f])};window.blueshift.load(this.options.apiKey);this.load(this.ready)};Blueshift.prototype.loaded=function(){return!!(window.blueshift&&window._blueshiftid)};Blueshift.prototype.page=function(page){if(this.options.retarget)window.blueshift.retarget();var properties=page.properties();properties._bsft_source="segment.com";window.blueshift.pageload(properties)};Blueshift.prototype.identify=function(identify){if(!identify.userId())return this.debug("user id required");var traits=identify.traits({created:"created_at"});traits._bsft_source="segment.com";window.blueshift.identify(traits)};Blueshift.prototype.group=function(group){var traits=group.traits({created:"created_at"});traits._bsft_source="segment.com";window.blueshift.track("group",traits)};Blueshift.prototype.track=function(track){var properties=track.properties();properties._bsft_source="segment.com";window.blueshift.track(track.event(),properties)}},{"analytics.js-integration":88}],18:[function(require,module,exports){var integration=require("analytics.js-integration");var Identify=require("facade").Identify;var Track=require("facade").Track;var pixel=require("load-pixel")("http://app.bronto.com/public/");var qs=require("querystring");var each=require("each");var Bronto=module.exports=integration("Bronto").global("__bta").option("siteId","").option("host","").tag('<script src="//p.bm23.com/bta.js">');Bronto.prototype.initialize=function(page){var self=this;var params=qs.parse(window.location.search);if(!params._bta_tid&&!params._bta_c){this.debug("missing tracking URL parameters `_bta_tid` and `_bta_c`.")}this.load(function(){var opts=self.options;self.bta=new window.__bta(opts.siteId);if(opts.host)self.bta.setHost(opts.host);self.ready()})};Bronto.prototype.loaded=function(){return this.bta};Bronto.prototype.completedOrder=function(track){var user=this.analytics.user();var products=track.products();var props=track.properties();var items=[];var identify=new Identify({userId:user.id(),traits:user.traits()});var email=identify.email();each(products,function(product){var track=new Track({properties:product});items.push({item_id:track.id()||track.sku(),desc:product.description||track.name(),quantity:track.quantity(),amount:track.price()})});this.bta.addOrder({order_id:track.orderId(),email:email,items:items})}},{"analytics.js-integration":88,facade:147,"load-pixel":148,querystring:140,each:4}],147:[function(require,module,exports){var Facade=require("./facade");module.exports=Facade;Facade.Alias=require("./alias");Facade.Group=require("./group");Facade.Identify=require("./identify");Facade.Track=require("./track");Facade.Page=require("./page");Facade.Screen=require("./screen")},{"./facade":149,"./alias":150,"./group":151,"./identify":152,"./track":153,"./page":154,"./screen":155}],149:[function(require,module,exports){var traverse=require("isodate-traverse");var isEnabled=require("./is-enabled");var clone=require("./utils").clone;var type=require("./utils").type;var address=require("./address");var objCase=require("obj-case");var newDate=require("new-date");module.exports=Facade;function Facade(obj){if(!obj.hasOwnProperty("timestamp"))obj.timestamp=new Date;else obj.timestamp=newDate(obj.timestamp);traverse(obj);this.obj=obj}address(Facade.prototype);Facade.prototype.proxy=function(field){var fields=field.split(".");field=fields.shift();var obj=this[field]||this.field(field);if(!obj)return obj;if(typeof obj==="function")obj=obj.call(this)||{};if(fields.length===0)return transform(obj);obj=objCase(obj,fields.join("."));return transform(obj)};Facade.prototype.field=function(field){var obj=this.obj[field];return transform(obj)};Facade.proxy=function(field){return function(){return this.proxy(field)}};Facade.field=function(field){return function(){return this.field(field)}};Facade.multi=function(path){return function(){var multi=this.proxy(path+"s");if("array"==type(multi))return multi;var one=this.proxy(path);if(one)one=[clone(one)];return one||[]}};Facade.one=function(path){return function(){var one=this.proxy(path);if(one)return one;var multi=this.proxy(path+"s");if("array"==type(multi))return multi[0]}};Facade.prototype.json=function(){var ret=clone(this.obj);if(this.type)ret.type=this.type();return ret};Facade.prototype.context=Facade.prototype.options=function(integration){var options=clone(this.obj.options||this.obj.context)||{};if(!integration)return clone(options);if(!this.enabled(integration))return;var integrations=this.integrations();var value=integrations[integration]||objCase(integrations,integration);if("boolean"==typeof value)value={};return value||{}};Facade.prototype.enabled=function(integration){var allEnabled=this.proxy("options.providers.all");if(typeof allEnabled!=="boolean")allEnabled=this.proxy("options.all");if(typeof allEnabled!=="boolean")allEnabled=this.proxy("integrations.all");if(typeof allEnabled!=="boolean")allEnabled=true;var enabled=allEnabled&&isEnabled(integration);var options=this.integrations();if(options.providers&&options.providers.hasOwnProperty(integration)){enabled=options.providers[integration]}if(options.hasOwnProperty(integration)){var settings=options[integration];if(typeof settings==="boolean"){enabled=settings}else{enabled=true}}return enabled?true:false};Facade.prototype.integrations=function(){return this.obj.integrations||this.proxy("options.providers")||this.options()};Facade.prototype.active=function(){var active=this.proxy("options.active");if(active===null||active===undefined)active=true;return active};Facade.prototype.sessionId=Facade.prototype.anonymousId=function(){return this.field("anonymousId")||this.field("sessionId")};Facade.prototype.groupId=Facade.proxy("options.groupId");Facade.prototype.traits=function(aliases){var ret=this.proxy("options.traits")||{};var id=this.userId();aliases=aliases||{};if(id)ret.id=id;for(var alias in aliases){var value=null==this[alias]?this.proxy("options.traits."+alias):this[alias]();if(null==value)continue;ret[aliases[alias]]=value;delete ret[alias]}return ret};Facade.prototype.library=function(){var library=this.proxy("options.library");if(!library)return{name:"unknown",version:null};if(typeof library==="string")return{name:library,version:null};return library};Facade.prototype.userId=Facade.field("userId");Facade.prototype.channel=Facade.field("channel");Facade.prototype.timestamp=Facade.field("timestamp");Facade.prototype.userAgent=Facade.proxy("options.userAgent");Facade.prototype.ip=Facade.proxy("options.ip");function transform(obj){var cloned=clone(obj);return cloned}},{"isodate-traverse":156,"./is-enabled":157,"./utils":158,"./address":159,"obj-case":160,"new-date":161}],156:[function(require,module,exports){var is=require("is");var isodate=require("isodate");var each;try{each=require("each")}catch(err){each=require("each-component")}module.exports=traverse;function traverse(input,strict){if(strict===undefined)strict=true;if(is.object(input))return object(input,strict);if(is.array(input))return array(input,strict);return input}function object(obj,strict){each(obj,function(key,val){if(isodate.is(val,strict)){obj[key]=isodate.parse(val)}else if(is.object(val)||is.array(val)){traverse(val,strict)}});return obj}function array(arr,strict){each(arr,function(val,x){if(is.object(val)){traverse(val,strict)}else if(isodate.is(val,strict)){arr[x]=isodate.parse(val)}});return arr}},{is:162,isodate:163,each:4}],162:[function(require,module,exports){var isEmpty=require("is-empty");try{var typeOf=require("type")}catch(e){var typeOf=require("component-type")}var types=["arguments","array","boolean","date","element","function","null","number","object","regexp","string","undefined"];for(var i=0,type;type=types[i];i++)exports[type]=generate(type);exports.fn=exports["function"];exports.empty=isEmpty;exports.nan=function(val){return exports.number(val)&&val!=val};function generate(type){return function(value){return type===typeOf(value)}}},{"is-empty":122,type:7,"component-type":7}],163:[function(require,module,exports){var matcher=/^(\d{4})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:([ T])(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;exports.parse=function(iso){var numericKeys=[1,5,6,7,11,12];var arr=matcher.exec(iso);var offset=0;if(!arr)return new Date(iso);for(var i=0,val;val=numericKeys[i];i++){arr[val]=parseInt(arr[val],10)||0}arr[2]=parseInt(arr[2],10)||1;arr[3]=parseInt(arr[3],10)||1;arr[2]--;arr[8]=arr[8]?(arr[8]+"00").substring(0,3):0;if(arr[4]==" "){offset=(new Date).getTimezoneOffset()}else if(arr[9]!=="Z"&&arr[10]){offset=arr[11]*60+arr[12];if("+"==arr[10])offset=0-offset}var millis=Date.UTC(arr[1],arr[2],arr[3],arr[5],arr[6]+offset,arr[7],arr[8]);return new Date(millis)};exports.is=function(string,strict){if(strict&&false===/^\d{4}-\d{2}-\d{2}/.test(string))return false;return matcher.test(string)}},{}],157:[function(require,module,exports){var disabled={Salesforce:true};module.exports=function(integration){return!disabled[integration]}},{}],158:[function(require,module,exports){try{exports.inherit=require("inherit");exports.clone=require("clone");exports.type=require("type")}catch(e){exports.inherit=require("inherit-component");exports.clone=require("clone-component");exports.type=require("type-component")}},{inherit:164,clone:165,type:7}],164:[function(require,module,exports){module.exports=function(a,b){var fn=function(){}; +fn.prototype=b.prototype;a.prototype=new fn;a.prototype.constructor=a}},{}],165:[function(require,module,exports){var type;try{type=require("component-type")}catch(_){type=require("type")}module.exports=clone;function clone(obj){switch(type(obj)){case"object":var copy={};for(var key in obj){if(obj.hasOwnProperty(key)){copy[key]=clone(obj[key])}}return copy;case"array":var copy=new Array(obj.length);for(var i=0,l=obj.length;i<l;i++){copy[i]=clone(obj[i])}return copy;case"regexp":var flags="";flags+=obj.multiline?"m":"";flags+=obj.global?"g":"";flags+=obj.ignoreCase?"i":"";return new RegExp(obj.source,flags);case"date":return new Date(obj.getTime());default:return obj}}},{"component-type":7,type:7}],159:[function(require,module,exports){var get=require("obj-case");module.exports=function(proto){proto.zip=trait("postalCode","zip");proto.country=trait("country");proto.street=trait("street");proto.state=trait("state");proto.city=trait("city");function trait(a,b){return function(){var traits=this.traits();var props=this.properties?this.properties():{};return get(traits,"address."+a)||get(traits,a)||(b?get(traits,"address."+b):null)||(b?get(traits,b):null)||get(props,"address."+a)||get(props,a)||(b?get(props,"address."+b):null)||(b?get(props,b):null)}}}},{"obj-case":160}],160:[function(require,module,exports){var identity=function(_){return _};module.exports=multiple(find);module.exports.find=module.exports;module.exports.replace=function(obj,key,val,options){multiple(replace).call(this,obj,key,val,options);return obj};module.exports.del=function(obj,key,options){multiple(del).call(this,obj,key,null,options);return obj};function multiple(fn){return function(obj,path,val,options){var normalize=options&&isFunction(options.normalizer)?options.normalizer:defaultNormalize;path=normalize(path);var key;var finished=false;while(!finished)loop();function loop(){for(key in obj){var normalizedKey=normalize(key);if(0===path.indexOf(normalizedKey)){var temp=path.substr(normalizedKey.length);if(temp.charAt(0)==="."||temp.length===0){path=temp.substr(1);var child=obj[key];if(null==child){finished=true;return}if(!path.length){finished=true;return}obj=child;return}}}key=undefined;finished=true}if(!key)return;if(null==obj)return obj;return fn(obj,key,val)}}function find(obj,key){if(obj.hasOwnProperty(key))return obj[key]}function del(obj,key){if(obj.hasOwnProperty(key))delete obj[key];return obj}function replace(obj,key,val){if(obj.hasOwnProperty(key))obj[key]=val;return obj}function defaultNormalize(path){return path.replace(/[^a-zA-Z0-9\.]+/g,"").toLowerCase()}function isFunction(val){return typeof val==="function"}},{}],161:[function(require,module,exports){var is=require("is");var isodate=require("isodate");var milliseconds=require("./milliseconds");var seconds=require("./seconds");module.exports=function newDate(val){if(is.date(val))return val;if(is.number(val))return new Date(toMs(val));if(isodate.is(val))return isodate.parse(val);if(milliseconds.is(val))return milliseconds.parse(val);if(seconds.is(val))return seconds.parse(val);return new Date(val)};function toMs(num){if(num<315576e5)return num*1e3;return num}},{is:166,isodate:163,"./milliseconds":167,"./seconds":168}],166:[function(require,module,exports){var isEmpty=require("is-empty"),typeOf=require("type");var types=["arguments","array","boolean","date","element","function","null","number","object","regexp","string","undefined"];for(var i=0,type;type=types[i];i++)exports[type]=generate(type);exports.fn=exports["function"];exports.empty=isEmpty;exports.nan=function(val){return exports.number(val)&&val!=val};function generate(type){return function(value){return type===typeOf(value)}}},{"is-empty":122,type:7}],167:[function(require,module,exports){var matcher=/\d{13}/;exports.is=function(string){return matcher.test(string)};exports.parse=function(millis){millis=parseInt(millis,10);return new Date(millis)}},{}],168:[function(require,module,exports){var matcher=/\d{10}/;exports.is=function(string){return matcher.test(string)};exports.parse=function(seconds){var millis=parseInt(seconds,10)*1e3;return new Date(millis)}},{}],150:[function(require,module,exports){var inherit=require("./utils").inherit;var Facade=require("./facade");module.exports=Alias;function Alias(dictionary){Facade.call(this,dictionary)}inherit(Alias,Facade);Alias.prototype.type=Alias.prototype.action=function(){return"alias"};Alias.prototype.from=Alias.prototype.previousId=function(){return this.field("previousId")||this.field("from")};Alias.prototype.to=Alias.prototype.userId=function(){return this.field("userId")||this.field("to")}},{"./utils":158,"./facade":149}],151:[function(require,module,exports){var inherit=require("./utils").inherit;var address=require("./address");var isEmail=require("is-email");var newDate=require("new-date");var Facade=require("./facade");module.exports=Group;function Group(dictionary){Facade.call(this,dictionary)}inherit(Group,Facade);Group.prototype.type=Group.prototype.action=function(){return"group"};Group.prototype.groupId=Facade.field("groupId");Group.prototype.created=function(){var created=this.proxy("traits.createdAt")||this.proxy("traits.created")||this.proxy("properties.createdAt")||this.proxy("properties.created");if(created)return newDate(created)};Group.prototype.email=function(){var email=this.proxy("traits.email");if(email)return email;var groupId=this.groupId();if(isEmail(groupId))return groupId};Group.prototype.traits=function(aliases){var ret=this.properties();var id=this.groupId();aliases=aliases||{};if(id)ret.id=id;for(var alias in aliases){var value=null==this[alias]?this.proxy("traits."+alias):this[alias]();if(null==value)continue;ret[aliases[alias]]=value;delete ret[alias]}return ret};Group.prototype.name=Facade.proxy("traits.name");Group.prototype.industry=Facade.proxy("traits.industry");Group.prototype.employees=Facade.proxy("traits.employees");Group.prototype.properties=function(){return this.field("traits")||this.field("properties")||{}}},{"./utils":158,"./address":159,"is-email":169,"new-date":161,"./facade":149}],169:[function(require,module,exports){module.exports=isEmail;var matcher=/.+\@.+\..+/;function isEmail(string){return matcher.test(string)}},{}],152:[function(require,module,exports){var address=require("./address");var Facade=require("./facade");var isEmail=require("is-email");var newDate=require("new-date");var utils=require("./utils");var get=require("obj-case");var trim=require("trim");var inherit=utils.inherit;var clone=utils.clone;var type=utils.type;module.exports=Identify;function Identify(dictionary){Facade.call(this,dictionary)}inherit(Identify,Facade);Identify.prototype.type=Identify.prototype.action=function(){return"identify"};Identify.prototype.traits=function(aliases){var ret=this.field("traits")||{};var id=this.userId();aliases=aliases||{};if(id)ret.id=id;for(var alias in aliases){var value=null==this[alias]?this.proxy("traits."+alias):this[alias]();if(null==value)continue;ret[aliases[alias]]=value;if(alias!==aliases[alias])delete ret[alias]}return ret};Identify.prototype.email=function(){var email=this.proxy("traits.email");if(email)return email;var userId=this.userId();if(isEmail(userId))return userId};Identify.prototype.created=function(){var created=this.proxy("traits.created")||this.proxy("traits.createdAt");if(created)return newDate(created)};Identify.prototype.companyCreated=function(){var created=this.proxy("traits.company.created")||this.proxy("traits.company.createdAt");if(created)return newDate(created)};Identify.prototype.name=function(){var name=this.proxy("traits.name");if(typeof name==="string")return trim(name);var firstName=this.firstName();var lastName=this.lastName();if(firstName&&lastName)return trim(firstName+" "+lastName)};Identify.prototype.firstName=function(){var firstName=this.proxy("traits.firstName");if(typeof firstName==="string")return trim(firstName);var name=this.proxy("traits.name");if(typeof name==="string")return trim(name).split(" ")[0]};Identify.prototype.lastName=function(){var lastName=this.proxy("traits.lastName");if(typeof lastName==="string")return trim(lastName);var name=this.proxy("traits.name");if(typeof name!=="string")return;var space=trim(name).indexOf(" ");if(space===-1)return;return trim(name.substr(space+1))};Identify.prototype.uid=function(){return this.userId()||this.username()||this.email()};Identify.prototype.description=function(){return this.proxy("traits.description")||this.proxy("traits.background")};Identify.prototype.age=function(){var date=this.birthday();var age=get(this.traits(),"age");if(null!=age)return age;if("date"!=type(date))return;var now=new Date;return now.getFullYear()-date.getFullYear()};Identify.prototype.avatar=function(){var traits=this.traits();return get(traits,"avatar")||get(traits,"photoUrl")||get(traits,"avatarUrl")};Identify.prototype.position=function(){var traits=this.traits();return get(traits,"position")||get(traits,"jobTitle")};Identify.prototype.username=Facade.proxy("traits.username");Identify.prototype.website=Facade.one("traits.website");Identify.prototype.websites=Facade.multi("traits.website");Identify.prototype.phone=Facade.one("traits.phone");Identify.prototype.phones=Facade.multi("traits.phone");Identify.prototype.address=Facade.proxy("traits.address");Identify.prototype.gender=Facade.proxy("traits.gender");Identify.prototype.birthday=Facade.proxy("traits.birthday")},{"./address":159,"./facade":149,"is-email":169,"new-date":161,"./utils":158,"obj-case":160,trim:141}],153:[function(require,module,exports){var inherit=require("./utils").inherit;var clone=require("./utils").clone;var type=require("./utils").type;var Facade=require("./facade");var Identify=require("./identify");var isEmail=require("is-email");var get=require("obj-case");module.exports=Track;function Track(dictionary){Facade.call(this,dictionary)}inherit(Track,Facade);Track.prototype.type=Track.prototype.action=function(){return"track"};Track.prototype.event=Facade.field("event");Track.prototype.value=Facade.proxy("properties.value");Track.prototype.category=Facade.proxy("properties.category");Track.prototype.id=Facade.proxy("properties.id");Track.prototype.sku=Facade.proxy("properties.sku");Track.prototype.tax=Facade.proxy("properties.tax");Track.prototype.name=Facade.proxy("properties.name");Track.prototype.price=Facade.proxy("properties.price");Track.prototype.total=Facade.proxy("properties.total");Track.prototype.coupon=Facade.proxy("properties.coupon");Track.prototype.shipping=Facade.proxy("properties.shipping");Track.prototype.discount=Facade.proxy("properties.discount");Track.prototype.description=Facade.proxy("properties.description");Track.prototype.plan=Facade.proxy("properties.plan");Track.prototype.orderId=function(){return this.proxy("properties.id")||this.proxy("properties.orderId")};Track.prototype.subtotal=function(){var subtotal=get(this.properties(),"subtotal");var total=this.total();var n;if(subtotal)return subtotal;if(!total)return 0;if(n=this.tax())total-=n;if(n=this.shipping())total-=n;if(n=this.discount())total+=n;return total};Track.prototype.products=function(){var props=this.properties();var products=get(props,"products");return"array"==type(products)?products:[]};Track.prototype.quantity=function(){var props=this.obj.properties||{};return props.quantity||1};Track.prototype.currency=function(){var props=this.obj.properties||{};return props.currency||"USD"};Track.prototype.referrer=Facade.proxy("properties.referrer");Track.prototype.query=Facade.proxy("options.query");Track.prototype.properties=function(aliases){var ret=this.field("properties")||{};aliases=aliases||{};for(var alias in aliases){var value=null==this[alias]?this.proxy("properties."+alias):this[alias]();if(null==value)continue;ret[aliases[alias]]=value;delete ret[alias]}return ret};Track.prototype.username=function(){return this.proxy("traits.username")||this.proxy("properties.username")||this.userId()||this.sessionId()};Track.prototype.email=function(){var email=this.proxy("traits.email");email=email||this.proxy("properties.email");if(email)return email;var userId=this.userId();if(isEmail(userId))return userId};Track.prototype.revenue=function(){var revenue=this.proxy("properties.revenue");var event=this.event();if(!revenue&&event&&event.match(/completed ?order/i)){revenue=this.proxy("properties.total")}return currency(revenue)};Track.prototype.cents=function(){var revenue=this.revenue();return"number"!=typeof revenue?this.value()||0:revenue*100};Track.prototype.identify=function(){var json=this.json();json.traits=this.traits();return new Identify(json)};function currency(val){if(!val)return;if(typeof val==="number")return val;if(typeof val!=="string")return;val=val.replace(/\$/g,"");val=parseFloat(val);if(!isNaN(val))return val}},{"./utils":158,"./facade":149,"./identify":152,"is-email":169,"obj-case":160}],154:[function(require,module,exports){var inherit=require("./utils").inherit;var Facade=require("./facade");var Track=require("./track");module.exports=Page;function Page(dictionary){Facade.call(this,dictionary)}inherit(Page,Facade);Page.prototype.type=Page.prototype.action=function(){return"page"};Page.prototype.category=Facade.field("category");Page.prototype.name=Facade.field("name");Page.prototype.title=Facade.proxy("properties.title");Page.prototype.path=Facade.proxy("properties.path");Page.prototype.url=Facade.proxy("properties.url");Page.prototype.referrer=function(){return this.proxy("properties.referrer")||this.proxy("context.referrer.url")};Page.prototype.properties=function(){var props=this.field("properties")||{};var category=this.category();var name=this.name();if(category)props.category=category;if(name)props.name=name;return props};Page.prototype.fullName=function(){var category=this.category();var name=this.name();return name&&category?category+" "+name:name};Page.prototype.event=function(name){return name?"Viewed "+name+" Page":"Loaded a Page"};Page.prototype.track=function(name){var props=this.properties();return new Track({event:this.event(name),timestamp:this.timestamp(),context:this.context(),properties:props})}},{"./utils":158,"./facade":149,"./track":153}],155:[function(require,module,exports){var inherit=require("./utils").inherit;var Page=require("./page");var Track=require("./track");module.exports=Screen;function Screen(dictionary){Page.call(this,dictionary)}inherit(Screen,Page);Screen.prototype.type=Screen.prototype.action=function(){return"screen"};Screen.prototype.event=function(name){return name?"Viewed "+name+" Screen":"Loaded a Screen"};Screen.prototype.track=function(name){var props=this.properties();return new Track({event:this.event(name),timestamp:this.timestamp(),context:this.context(),properties:props})}},{"./utils":158,"./page":154,"./track":153}],148:[function(require,module,exports){var stringify=require("querystring").stringify;var sub=require("substitute");module.exports=function(path){return function(query,obj,fn){if("function"==typeof obj)fn=obj,obj={};obj=obj||{};fn=fn||function(){};var url=sub(path,obj);var img=new Image;img.onerror=error(fn,"failed to load pixel",img);img.onload=function(){fn()};query=stringify(query);if(query)query="?"+query;img.src=url+query;img.width=1;img.height=1;return img}};function error(fn,message,img){return function(e){e=e||window.event;var err=new Error(message);err.event=e;err.source=img;fn(err)}}},{querystring:140,substitute:170}],170:[function(require,module,exports){module.exports=substitute;var type=Object.prototype.toString;function substitute(str,obj,expr){if(!obj)throw new TypeError("expected an object");expr=expr||/:(\w+)/g;return str.replace(expr,function(_,prop){switch(type.call(obj)){case"[object Object]":return null!=obj[prop]?obj[prop]:_;case"[object Array]":var val=obj.shift();return null!=val?val:_}})}},{}],19:[function(require,module,exports){var integration=require("analytics.js-integration");var tick=require("next-tick");var BugHerd=module.exports=integration("BugHerd").assumesPageview().global("BugHerdConfig").global("_bugHerd").option("apiKey","").option("showFeedbackTab",true).tag('<script src="//www.bugherd.com/sidebarv2.js?apikey={{ apiKey }}">');BugHerd.prototype.initialize=function(page){window.BugHerdConfig={feedback:{hide:!this.options.showFeedbackTab}};var ready=this.ready;this.load(function(){tick(ready)})};BugHerd.prototype.loaded=function(){return!!window._bugHerd}},{"analytics.js-integration":88,"next-tick":103}],20:[function(require,module,exports){var integration=require("analytics.js-integration");var is=require("is");var extend=require("extend");var onError=require("on-error");var umd="function"==typeof define&&define.amd;var src="//d2wy8f7a9ursnm.cloudfront.net/bugsnag-2.min.js";var Bugsnag=module.exports=integration("Bugsnag").global("Bugsnag").option("apiKey","").tag('<script src="'+src+'">');Bugsnag.prototype.initialize=function(page){var self=this;if(umd){window.require([src],function(bugsnag){bugsnag.apiKey=self.options.apiKey;window.Bugsnag=bugsnag;self.ready()});return}this.load(function(){window.Bugsnag.apiKey=self.options.apiKey;self.ready()})};Bugsnag.prototype.loaded=function(){return is.object(window.Bugsnag)};Bugsnag.prototype.identify=function(identify){window.Bugsnag.metaData=window.Bugsnag.metaData||{};extend(window.Bugsnag.metaData,identify.traits())}},{"analytics.js-integration":88,is:91,extend:145,"on-error":171}],171:[function(require,module,exports){module.exports=onError;var callbacks=[];if("function"==typeof window.onerror)callbacks.push(window.onerror);window.onerror=handler;function handler(){for(var i=0,fn;fn=callbacks[i];i++)fn.apply(this,arguments)}function onError(fn){callbacks.push(fn);if(window.onerror!=handler){callbacks.push(window.onerror);window.onerror=handler}}},{}],21:[function(require,module,exports){var integration=require("analytics.js-integration");var defaults=require("defaults");var onBody=require("on-body");var Chartbeat=module.exports=integration("Chartbeat").assumesPageview().global("_sf_async_config").global("_sf_endpt").global("pSUPERFLY").option("domain","").option("uid",null).tag('<script src="//static.chartbeat.com/js/chartbeat.js">');Chartbeat.prototype.initialize=function(page){var self=this;window._sf_async_config=window._sf_async_config||{};window._sf_async_config.useCanonical=true;defaults(window._sf_async_config,this.options);onBody(function(){window._sf_endpt=(new Date).getTime();self.load(self.ready)})};Chartbeat.prototype.loaded=function(){return!!window.pSUPERFLY};Chartbeat.prototype.page=function(page){var category=page.category();if(category)window._sf_async_config.sections=category;var author=page.proxy("properties.author");if(author)window._sf_async_config.authors=author;var props=page.properties();var name=page.fullName();window.pSUPERFLY.virtualPage(props.path,name||props.title)}},{"analytics.js-integration":88,defaults:172,"on-body":144}],172:[function(require,module,exports){module.exports=defaults;function defaults(dest,defaults){for(var prop in defaults){if(!(prop in dest)){dest[prop]=defaults[prop]}}return dest}},{}],22:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("_cbq");var each=require("each");var has=Object.prototype.hasOwnProperty;var supported={activation:true,changePlan:true,register:true,refund:true,charge:true,cancel:true,login:true};var ChurnBee=module.exports=integration("ChurnBee").global("_cbq").global("ChurnBee").option("apiKey","").tag('<script src="//api.churnbee.com/cb.js">').mapping("events");ChurnBee.prototype.initialize=function(page){push("_setApiKey",this.options.apiKey);this.load(this.ready)};ChurnBee.prototype.loaded=function(){return!!window.ChurnBee};ChurnBee.prototype.track=function(track){var event=track.event();var events=this.events(event);events.push(event);each(events,function(event){if(true!=supported[event])return;push(event,track.properties({revenue:"amount"}))})}},{"analytics.js-integration":88,"global-queue":173,each:4}],173:[function(require,module,exports){module.exports=generate;function generate(name,options){options=options||{};return function(args){args=[].slice.call(arguments);window[name]||(window[name]=[]);options.wrap===false?window[name].push.apply(window[name],args):window[name].push(args)}}},{}],23:[function(require,module,exports){var date=require("load-date");var domify=require("domify");var each=require("each");var integration=require("analytics.js-integration");var is=require("is");var useHttps=require("use-https");var onBody=require("on-body");var ClickTale=module.exports=integration("ClickTale").assumesPageview().global("WRInitTime").global("ClickTale").global("ClickTaleSetUID").global("ClickTaleField").global("ClickTaleEvent").option("httpCdnUrl","http://s.clicktale.net/WRe0.js").option("httpsCdnUrl","").option("projectId","").option("recordingRatio",.01).option("partitionId","").tag('<script src="{{src}}">');ClickTale.prototype.initialize=function(page){var self=this;window.WRInitTime=date.getTime();onBody(function(body){body.appendChild(domify('<div id="ClickTaleDiv" style="display: none;">'))});var http=this.options.httpCdnUrl;var https=this.options.httpsCdnUrl;if(useHttps()&&!https)return this.debug("https option required");var src=useHttps()?https:http;this.load({src:src},function(){window.ClickTale(self.options.projectId,self.options.recordingRatio,self.options.partitionId);self.ready()})};ClickTale.prototype.loaded=function(){return is.fn(window.ClickTale)};ClickTale.prototype.identify=function(identify){var id=identify.userId();window.ClickTaleSetUID(id);each(identify.traits(),function(key,value){window.ClickTaleField(key,value)})};ClickTale.prototype.track=function(track){window.ClickTaleEvent(track.event())}},{"load-date":174,domify:119,each:4,"analytics.js-integration":88,is:91,"use-https":90,"on-body":144}],174:[function(require,module,exports){var time=new Date,perf=window.performance;if(perf&&perf.timing&&perf.timing.responseEnd){time=new Date(perf.timing.responseEnd)}module.exports=time},{}],24:[function(require,module,exports){var Identify=require("facade").Identify;var extend=require("extend");var integration=require("analytics.js-integration");var is=require("is");var Clicky=module.exports=integration("Clicky").assumesPageview().global("clicky").global("clicky_site_ids").global("clicky_custom").option("siteId",null).tag('<script src="//static.getclicky.com/js"></script>');Clicky.prototype.initialize=function(page){var user=this.analytics.user();window.clicky_site_ids=window.clicky_site_ids||[this.options.siteId];this.identify(new Identify({userId:user.id(),traits:user.traits()}));this.load(this.ready)};Clicky.prototype.loaded=function(){return is.object(window.clicky)};Clicky.prototype.page=function(page){var properties=page.properties();var category=page.category();var name=page.fullName();window.clicky.log(properties.path,name||properties.title)};Clicky.prototype.identify=function(identify){window.clicky_custom=window.clicky_custom||{};window.clicky_custom.session=window.clicky_custom.session||{};var traits=identify.traits();var username=identify.username();var email=identify.email();var name=identify.name();if(username||email||name)traits.username=username||email||name;extend(window.clicky_custom.session,traits)};Clicky.prototype.track=function(track){window.clicky.goal(track.event(),track.revenue())}},{facade:147,extend:145,"analytics.js-integration":88,is:91}],25:[function(require,module,exports){var integration=require("analytics.js-integration");var useHttps=require("use-https");var Comscore=module.exports=integration("comScore").assumesPageview().global("_comscore").global("COMSCORE").option("c1","2").option("c2","").tag("http",'<script src="http://b.scorecardresearch.com/beacon.js">').tag("https",'<script src="https://sb.scorecardresearch.com/beacon.js">');Comscore.prototype.initialize=function(page){window._comscore=window._comscore||[this.options];var name=useHttps()?"https":"http";this.load(name,this.ready)};Comscore.prototype.loaded=function(){return!!window.COMSCORE};Comscore.prototype.page=function(page){window.COMSCORE.beacon(this.options)}},{"analytics.js-integration":88,"use-https":90}],26:[function(require,module,exports){var integration=require("analytics.js-integration");var CrazyEgg=module.exports=integration("Crazy Egg").assumesPageview().global("CE2").option("accountNumber","").tag('<script src="//dnn506yrbagrg.cloudfront.net/pages/scripts/{{ path }}.js?{{ cache }}">');CrazyEgg.prototype.initialize=function(page){var number=this.options.accountNumber;var path=number.slice(0,4)+"/"+number.slice(4);var cache=Math.floor((new Date).getTime()/36e5);this.load({path:path,cache:cache},this.ready)};CrazyEgg.prototype.loaded=function(){return!!window.CE2}},{"analytics.js-integration":88}],27:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("_curebitq");var Identify=require("facade").Identify;var throttle=require("throttle");var Track=require("facade").Track;var iso=require("to-iso-string");var clone=require("clone");var each=require("each");var bind=require("bind");var Curebit=module.exports=integration("Curebit").global("_curebitq").global("curebit").option("siteId","").option("iframeWidth","100%").option("iframeHeight","480").option("iframeBorder",0).option("iframeId","curebit_integration").option("responsive",true).option("device","").option("insertIntoId","").option("campaigns",{}).option("server","https://www.curebit.com").tag('<script src="//d2jjzw81hqbuqv.cloudfront.net/integration/curebit-1.0.min.js">');Curebit.prototype.initialize=function(page){push("init",{site_id:this.options.siteId,server:this.options.server});this.load(this.ready);this.page=throttle(bind(this,this.page),250)};Curebit.prototype.loaded=function(){return!!window.curebit};Curebit.prototype.injectIntoId=function(url,id,fn){var server=this.options.server;when(function(){return document.getElementById(id)},function(){var script=document.createElement("script");script.src=url;var parent=document.getElementById(id);parent.appendChild(script);onload(script,fn)})};Curebit.prototype.page=function(page){var user=this.analytics.user();var campaigns=this.options.campaigns;var path=window.location.pathname;if(!campaigns[path])return;var tags=(campaigns[path]||"").split(",");if(!tags.length)return;var settings={responsive:this.options.responsive,device:this.options.device,campaign_tags:tags,iframe:{width:this.options.iframeWidth,height:this.options.iframeHeight,id:this.options.iframeId,frameborder:this.options.iframeBorder,container:this.options.insertIntoId}};var identify=new Identify({userId:user.id(),traits:user.traits()});if(identify.email()){settings.affiliate_member={email:identify.email(),first_name:identify.firstName(),last_name:identify.lastName(),customer_id:identify.userId()}}push("register_affiliate",settings)};Curebit.prototype.completedOrder=function(track){var user=this.analytics.user();var orderId=track.orderId();var products=track.products();var props=track.properties();var items=[];var identify=new Identify({traits:user.traits(),userId:user.id()});each(products,function(product){var track=new Track({properties:product});items.push({product_id:track.id()||track.sku(),quantity:track.quantity(),image_url:product.image,price:track.price(),title:track.name(),url:product.url})});push("register_purchase",{order_date:iso(props.date||new Date),order_number:orderId,coupon_code:track.coupon(),subtotal:track.total(),customer_id:identify.userId(),first_name:identify.firstName(),last_name:identify.lastName(),email:identify.email(),items:items})}},{"analytics.js-integration":88,"global-queue":173,facade:147,throttle:175,"to-iso-string":176,clone:95,each:4,bind:101}],175:[function(require,module,exports){module.exports=throttle;function throttle(func,wait){var rtn;var last=0;return function throttled(){var now=(new Date).getTime();var delta=now-last;if(delta>=wait){rtn=func.apply(this,arguments);last=now}return rtn}}},{}],176:[function(require,module,exports){module.exports=toIsoString;function toIsoString(date){return date.getUTCFullYear()+"-"+pad(date.getUTCMonth()+1)+"-"+pad(date.getUTCDate())+"T"+pad(date.getUTCHours())+":"+pad(date.getUTCMinutes())+":"+pad(date.getUTCSeconds())+"."+String((date.getUTCMilliseconds()/1e3).toFixed(3)).slice(2,5)+"Z"}function pad(number){var n=number.toString();return n.length===1?"0"+n:n}},{}],28:[function(require,module,exports){var alias=require("alias");var convertDates=require("convert-dates");var Identify=require("facade").Identify;var integration=require("analytics.js-integration");var Customerio=module.exports=integration("Customer.io").global("_cio").option("siteId","").tag('<script id="cio-tracker" src="https://assets.customer.io/assets/track.js" data-site-id="{{ siteId }}">');Customerio.prototype.initialize=function(page){window._cio=window._cio||[];(function(){var a,b,c;a=function(f){return function(){window._cio.push([f].concat(Array.prototype.slice.call(arguments,0)))}};b=["identify","track"];for(c=0;c<b.length;c++){window._cio[b[c]]=a(b[c])}})();this.load(this.ready)};Customerio.prototype.loaded=function(){return!!window._cio&&window._cio.push!==Array.prototype.push};Customerio.prototype.identify=function(identify){if(!identify.userId())return this.debug("user id required");var traits=identify.traits({createdAt:"created"});traits=alias(traits,{created:"created_at"});traits=convertDates(traits,convertDate);window._cio.identify(traits)};Customerio.prototype.group=function(group){var traits=group.traits();var user=this.analytics.user();traits=alias(traits,function(trait){return"Group "+trait});this.identify(new Identify({userId:user.id(),traits:traits}))};Customerio.prototype.track=function(track){var properties=track.properties();properties=convertDates(properties,convertDate);window._cio.track(track.event(),properties)};function convertDate(date){return Math.floor(date.getTime()/1e3)}},{alias:177,"convert-dates":178,facade:147,"analytics.js-integration":88}],177:[function(require,module,exports){var type=require("type");try{var clone=require("clone")}catch(e){var clone=require("clone-component")}module.exports=alias;function alias(obj,method){switch(type(method)){case"object":return aliasByDictionary(clone(obj),method);case"function":return aliasByFunction(clone(obj),method)}}function aliasByDictionary(obj,aliases){for(var key in aliases){if(undefined===obj[key])continue;obj[aliases[key]]=obj[key];delete obj[key]}return obj}function aliasByFunction(obj,convert){var output={};for(var key in obj)output[convert(key)]=obj[key];return output}},{type:7,clone:165}],178:[function(require,module,exports){var is=require("is");try{var clone=require("clone")}catch(e){var clone=require("clone-component")}module.exports=convertDates;function convertDates(obj,convert){obj=clone(obj);for(var key in obj){var val=obj[key];if(is.date(val))obj[key]=convert(val);if(is.object(val))obj[key]=convertDates(val,convert)}return obj}},{is:91,clone:95}],29:[function(require,module,exports){var alias=require("alias");var integration=require("analytics.js-integration");var is=require("is");var load=require("load-script");var push=require("global-queue")("_dcq");var Drip=module.exports=integration("Drip").assumesPageview().global("_dc").global("_dcqi").global("_dcq").global("_dcs").option("account","").tag('<script src="//tag.getdrip.com/{{ account }}.js">');Drip.prototype.initialize=function(page){window._dcq=window._dcq||[];window._dcs=window._dcs||{};window._dcs.account=this.options.account;this.load(this.ready)};Drip.prototype.loaded=function(){return is.object(window._dc)};Drip.prototype.track=function(track){var props=track.properties();var cents=track.cents();if(cents)props.value=cents;delete props.revenue;push("track",track.event(),props)};Drip.prototype.identify=function(identify){push("identify",identify.traits())}},{alias:177,"analytics.js-integration":88,is:91,"load-script":143,"global-queue":173}],30:[function(require,module,exports){var extend=require("extend"); +var integration=require("analytics.js-integration");var onError=require("on-error");var push=require("global-queue")("_errs");var Errorception=module.exports=integration("Errorception").assumesPageview().global("_errs").option("projectId","").option("meta",true).tag('<script src="//beacon.errorception.com/{{ projectId }}.js">');Errorception.prototype.initialize=function(page){window._errs=window._errs||[this.options.projectId];onError(push);this.load(this.ready)};Errorception.prototype.loaded=function(){return!!(window._errs&&window._errs.push!==Array.prototype.push)};Errorception.prototype.identify=function(identify){if(!this.options.meta)return;var traits=identify.traits();window._errs=window._errs||[];window._errs.meta=window._errs.meta||{};extend(window._errs.meta,traits)}},{extend:145,"analytics.js-integration":88,"on-error":171,"global-queue":173}],31:[function(require,module,exports){var each=require("each");var integration=require("analytics.js-integration");var push=require("global-queue")("_aaq");var Evergage=module.exports=integration("Evergage").assumesPageview().global("_aaq").option("account","").option("dataset","").tag('<script src="//cdn.evergage.com/beacon/{{ account }}/{{ dataset }}/scripts/evergage.min.js">');Evergage.prototype.initialize=function(page){var account=this.options.account;var dataset=this.options.dataset;window._aaq=window._aaq||[];push("setEvergageAccount",account);push("setDataset",dataset);push("setUseSiteConfig",true);this.load(this.ready)};Evergage.prototype.loaded=function(){return!!(window._aaq&&window._aaq.push!==Array.prototype.push)};Evergage.prototype.page=function(page){var props=page.properties();var name=page.name();if(name)push("namePage",name);each(props,function(key,value){push("setCustomField",key,value,"page")});window.Evergage.init(true)};Evergage.prototype.identify=function(identify){var id=identify.userId();if(!id)return;push("setUser",id);var traits=identify.traits({email:"userEmail",name:"userName"});each(traits,function(key,value){push("setUserField",key,value,"page")})};Evergage.prototype.group=function(group){var props=group.traits();var id=group.groupId();if(!id)return;push("setCompany",id);each(props,function(key,value){push("setAccountField",key,value,"page")})};Evergage.prototype.track=function(track){push("trackAction",track.event(),track.properties())}},{each:4,"analytics.js-integration":88,"global-queue":173}],32:[function(require,module,exports){"use strict";var bind=require("bind");var domify=require("domify");var each=require("each");var extend=require("extend");var integration=require("analytics.js-integration");var json=require("json");var Extole=module.exports=integration("Extole").global("extole").option("clientId","").mapping("events").tag("main",'<script src="//tags.extole.com/{{ clientId }}/core.js">');Extole.prototype.initialize=function(){if(this.loaded())return this.ready();this.load("main",bind(this,this.ready))};Extole.prototype.loaded=function(){return!!window.extole};Extole.prototype.track=function(track){var user=this.analytics.user();var traits=user.traits();var userId=user.id();var email=traits.email;if(!userId&&!email){return this.debug("User must be identified before `#track` calls")}var event=track.event();var extoleEvents=this.events(event);if(!extoleEvents.length){return this.debug("No events found for %s",event)}each(extoleEvents,bind(this,function(extoleEvent){this._registerConversion(this._createConversionTag({type:extoleEvent,params:this._formatConversionParams(event,email,userId,track.properties())}))}))};Extole.prototype._registerConversion=function(conversionTag){if(window.extole.main&&window.extole.main.fireConversion){return window.extole.main.fireConversion(conversionTag)}if(window.extole.initializeGo){window.extole.initializeGo().andWhenItsReady(function(){window.extole.main.fireConversion(conversionTag)})}};Extole.prototype._formatConversionParams=function(event,email,userId,properties){var total;if(properties.total){total=properties.total;delete properties.total;properties["tag:cart_value"]=total}return extend({"tag:segment_event":event,e:email,partner_conversion_id:userId},properties)};Extole.prototype._createConversionTag=function(conversion){return domify('<script type="extole/conversion">'+json.stringify(conversion)+"</script>")}},{bind:101,domify:119,each:4,extend:145,"analytics.js-integration":88,json:179}],179:[function(require,module,exports){var json=window.JSON||{};var stringify=json.stringify;var parse=json.parse;module.exports=parse&&stringify?JSON:require("json-fallback")},{"json-fallback":180}],180:[function(require,module,exports){(function(){"use strict";var JSON=module.exports={};function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()}}var cx,escapable,gap,indent,meta,rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||"null"}v=partial.length===0?"[]":gap?"[\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"]":"["+partial.join(",")+"]";gap=mind;return v}if(rep&&typeof rep==="object"){length=rep.length;for(i=0;i<length;i+=1){if(typeof rep[i]==="string"){k=rep[i];v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}else{for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}v=partial.length===0?"{}":gap?"{\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"}":"{"+partial.join(",")+"}";gap=mind;return v}}if(typeof JSON.stringify!=="function"){escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"};JSON.stringify=function(value,replacer,space){var i;gap="";indent="";if(typeof space==="number"){for(i=0;i<space;i+=1){indent+=" "}}else if(typeof space==="string"){indent=space}rep=replacer;if(replacer&&typeof replacer!=="function"&&(typeof replacer!=="object"||typeof replacer.length!=="number")){throw new Error("JSON.stringify")}return str("",{"":value})}}if(typeof JSON.parse!=="function"){cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==="object"){for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v}else{delete value[k]}}}}return reviver.call(holder,key,value)}text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")}}})()},{}],33:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("_fbq");var each=require("each");var has=Object.prototype.hasOwnProperty;var Facebook=module.exports=integration("Facebook Conversion Tracking").global("_fbq").option("currency","USD").tag('<script src="//connect.facebook.net/en_US/fbds.js">').mapping("events");Facebook.prototype.initialize=function(page){window._fbq=window._fbq||[];this.load(this.ready);window._fbq.loaded=true};Facebook.prototype.loaded=function(){return!!(window._fbq&&window._fbq.loaded)};Facebook.prototype.track=function(track){var event=track.event();var events=this.events(event);var revenue=track.revenue()||0;var self=this;each(events,function(event){push("track",event,{value:String(revenue.toFixed(2)),currency:self.options.currency})});if(!events.length){var data=track.properties();push("track",event,data)}}},{"analytics.js-integration":88,"global-queue":173,each:4}],34:[function(require,module,exports){var push=require("global-queue")("_fxm");var integration=require("analytics.js-integration");var Track=require("facade").Track;var each=require("each");var FoxMetrics=module.exports=integration("FoxMetrics").assumesPageview().global("_fxm").option("appId","").tag('<script src="//d35tca7vmefkrc.cloudfront.net/scripts/{{ appId }}.js">');FoxMetrics.prototype.initialize=function(page){window._fxm=window._fxm||[];this.load(this.ready)};FoxMetrics.prototype.loaded=function(){return!!(window._fxm&&window._fxm.appId)};FoxMetrics.prototype.page=function(page){var properties=page.proxy("properties");var category=page.category();var name=page.name();this._category=category;push("_fxm.pages.view",properties.title,name,category,properties.url,properties.referrer)};FoxMetrics.prototype.identify=function(identify){var id=identify.userId();if(!id)return;push("_fxm.visitor.profile",id,identify.firstName(),identify.lastName(),identify.email(),identify.address(),undefined,undefined,identify.traits())};FoxMetrics.prototype.track=function(track){var props=track.properties();var category=this._category||props.category;push(track.event(),category,props)};FoxMetrics.prototype.viewedProduct=function(track){ecommerce("productview",track)};FoxMetrics.prototype.removedProduct=function(track){ecommerce("removecartitem",track)};FoxMetrics.prototype.addedProduct=function(track){ecommerce("cartitem",track)};FoxMetrics.prototype.completedOrder=function(track){var orderId=track.orderId();push("_fxm.ecommerce.order",orderId,track.subtotal(),track.shipping(),track.tax(),track.city(),track.state(),track.zip(),track.quantity());each(track.products(),function(product){var track=new Track({properties:product});ecommerce("purchaseitem",track,[track.quantity(),track.price(),orderId])})};function ecommerce(event,track,arr){push.apply(null,["_fxm.ecommerce."+event,track.id()||track.sku(),track.name(),track.category()].concat(arr||[]))}},{"global-queue":173,"analytics.js-integration":88,facade:147,each:4}],35:[function(require,module,exports){var integration=require("analytics.js-integration");var bind=require("bind");var when=require("when");var is=require("is");var Frontleaf=module.exports=integration("Frontleaf").global("_fl").global("_flBaseUrl").option("baseUrl","https://api.frontleaf.com").option("token","").option("stream","").option("trackNamedPages",false).option("trackCategorizedPages",false).tag('<script id="_fl" src="{{ baseUrl }}/lib/tracker.js">');Frontleaf.prototype.initialize=function(page){window._fl=window._fl||[];window._flBaseUrl=window._flBaseUrl||this.options.baseUrl;this._push("setApiToken",this.options.token);this._push("setStream",this.options.stream);var loaded=bind(this,this.loaded);var ready=this.ready;this.load({baseUrl:window._flBaseUrl},this.ready)};Frontleaf.prototype.loaded=function(){return is.array(window._fl)&&window._fl.ready===true};Frontleaf.prototype.identify=function(identify){var userId=identify.userId();if(userId){this._push("setUser",{id:userId,name:identify.name()||identify.username(),data:clean(identify.traits())})}};Frontleaf.prototype.group=function(group){var groupId=group.groupId();if(groupId){this._push("setAccount",{id:groupId,name:group.proxy("traits.name"),data:clean(group.traits())})}};Frontleaf.prototype.page=function(page){var category=page.category();var name=page.fullName();var opts=this.options;if(category&&opts.trackCategorizedPages){this.track(page.track(category))}if(name&&opts.trackNamedPages){this.track(page.track(name))}};Frontleaf.prototype.track=function(track){var event=track.event();this._push("event",event,clean(track.properties()))};Frontleaf.prototype._push=function(command){var args=[].slice.call(arguments,1);window._fl.push(function(t){t[command].apply(command,args)})};function clean(obj){var ret={};var excludeKeys=["id","name","firstName","lastName"];var len=excludeKeys.length;for(var i=0;i<len;i++){clear(obj,excludeKeys[i])}obj=flatten(obj);for(var key in obj){var val=obj[key];if(null==val){continue}if(is.array(val)){ret[key]=val.toString();continue}ret[key]=val}return ret}function clear(obj,key){if(obj.hasOwnProperty(key)){delete obj[key]}}function flatten(source){var output={};function step(object,prev){for(var key in object){var value=object[key];var newKey=prev?prev+" "+key:key;if(!is.array(value)&&is.object(value)){return step(value,newKey)}output[newKey]=value}}step(source);return output}},{"analytics.js-integration":88,bind:101,when:146,is:91}],36:[function(require,module,exports){var each=require("each");var is=require("is");var del=require("obj-case").del;var integration=require("analytics.js-integration");var FullStory=module.exports=integration("FullStory").option("org","").option("debug",false).tag('<script src="https://www.fullstory.com/s/fs.js"></script>');FullStory.prototype.initialize=function(){var self=this;window._fs_debug=this.options.debug;window._fs_host="www.fullstory.com";window._fs_org=this.options.org;(function(m,n,e,t,l,o,g,y){g=m[e]=function(a,b){g.q?g.q.push([a,b]):g._api(a,b)};g.q=[];g.identify=function(i,v){g(l,{uid:i});if(v)g(l,v)};g.setUserVars=function(v){FS(l,v)};g.setSessionVars=function(v){FS("session",v)};g.setPageVars=function(v){FS("page",v)};self.ready();self.load()})(window,document,"FS","script","user")};FullStory.prototype.loaded=function(){return!!window.FS};FullStory.prototype.identify=function(identify){var id=identify.userId()||identify.anonymousId();var traits=identify.traits();del(traits,"id");if(identify.name()){traits.displayName=identify.name();del(traits,"name")}each(traits,function(trait,value){if(trait!=="displayName"&&trait!=="email"){var newTrait=convert(trait,value);traits[newTrait]=value;del(traits,trait)}});if(typeof id!=="string")id=""+id;window.FS.identify(id,traits)};function convert(trait,value){if(is.string(value))return trait+="_str";if(isInt(value))return trait+="_int";if(isFloat(value))return trait+="_real";if(is.date(value))return trait+="_date";if(is.boolean(value))return trait+="_bool"}function isFloat(n){return n===+n&&n!==(n|0)}function isInt(n){return n===+n&&n===(n|0)}},{each:4,is:91,"obj-case":92,"analytics.js-integration":88}],37:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("_gauges");var Gauges=module.exports=integration("Gauges").assumesPageview().global("_gauges").option("siteId","").tag('<script id="gauges-tracker" src="//secure.gaug.es/track.js" data-site-id="{{ siteId }}">');Gauges.prototype.initialize=function(page){window._gauges=window._gauges||[];this.load(this.ready)};Gauges.prototype.loaded=function(){return!!(window._gauges&&window._gauges.push!==Array.prototype.push)};Gauges.prototype.page=function(page){push("track")}},{"analytics.js-integration":88,"global-queue":173}],38:[function(require,module,exports){var integration=require("analytics.js-integration");var onBody=require("on-body");var GetSatisfaction=module.exports=integration("Get Satisfaction").assumesPageview().global("GSFN").option("widgetId","").tag('<script src="https://loader.engage.gsfn.us/loader.js">');GetSatisfaction.prototype.initialize=function(page){var self=this;var widget=this.options.widgetId;var div=document.createElement("div");var id=div.id="getsat-widget-"+widget;onBody(function(body){body.appendChild(div)});this.load(function(){window.GSFN.loadWidget(widget,{containerId:id});self.ready()})};GetSatisfaction.prototype.loaded=function(){return!!window.GSFN}},{"analytics.js-integration":88,"on-body":144}],39:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("_gaq");var length=require("object").length;var canonical=require("canonical");var useHttps=require("use-https");var Track=require("facade").Track;var callback=require("callback");var defaults=require("defaults");var load=require("load-script");var keys=require("object").keys;var select=require("select");var dot=require("obj-case");var each=require("each");var type=require("type");var url=require("url");var is=require("is");var group;var user;module.exports=exports=function(analytics){analytics.addIntegration(GA);group=analytics.group();user=analytics.user()};var GA=exports.Integration=integration("Google Analytics").readyOnLoad().global("ga").global("gaplugins").global("_gaq").global("GoogleAnalyticsObject").option("anonymizeIp",false).option("classic",false).option("domain","auto").option("doubleClick",false).option("enhancedEcommerce",false).option("enhancedLinkAttribution",false).option("nonInteraction",false).option("ignoredReferrers",null).option("includeSearch",false).option("siteSpeedSampleRate",1).option("trackingId","").option("trackNamedPages",true).option("trackCategorizedPages",true).option("sendUserId",false).option("metrics",{}).option("dimensions",{}).tag("library",'<script src="//www.google-analytics.com/analytics.js">').tag("double click",'<script src="//stats.g.doubleclick.net/dc.js">').tag("http",'<script src="http://www.google-analytics.com/ga.js">').tag("https",'<script src="https://ssl.google-analytics.com/ga.js">');GA.on("construct",function(integration){if(integration.options.classic){integration.initialize=integration.initializeClassic;integration.loaded=integration.loadedClassic;integration.page=integration.pageClassic;integration.track=integration.trackClassic;integration.completedOrder=integration.completedOrderClassic}else if(integration.options.enhancedEcommerce){integration.viewedProduct=integration.viewedProductEnhanced;integration.clickedProduct=integration.clickedProductEnhanced;integration.addedProduct=integration.addedProductEnhanced;integration.removedProduct=integration.removedProductEnhanced;integration.startedOrder=integration.startedOrderEnhanced;integration.viewedCheckoutStep=integration.viewedCheckoutStepEnhanced;integration.completedCheckoutStep=integration.completedCheckoutStepEnhanced;integration.updatedOrder=integration.updatedOrderEnhanced;integration.completedOrder=integration.completedOrderEnhanced;integration.refundedOrder=integration.refundedOrderEnhanced;integration.viewedPromotion=integration.viewedPromotionEnhanced;integration.clickedPromotion=integration.clickedPromotionEnhanced}});GA.prototype.initialize=function(){var opts=this.options;window.GoogleAnalyticsObject="ga";window.ga=window.ga||function(){window.ga.q=window.ga.q||[];window.ga.q.push(arguments)};window.ga.l=(new Date).getTime();if(window.location.hostname==="localhost")opts.domain="none";window.ga("create",opts.trackingId,{cookieDomain:opts.domain||GA.prototype.defaults.domain,siteSpeedSampleRate:opts.siteSpeedSampleRate,allowLinker:true});if(opts.doubleClick){window.ga("require","displayfeatures")}if(opts.sendUserId&&user.id()){window.ga("set","userId",user.id())}if(opts.anonymizeIp)window.ga("set","anonymizeIp",true);var custom=metrics(user.traits(),opts);if(length(custom))window.ga("set",custom);this.load("library",this.ready)};GA.prototype.loaded=function(){return!!window.gaplugins};GA.prototype.page=function(page){var category=page.category();var props=page.properties();var name=page.fullName();var campaign=page.proxy("context.campaign")||{};var pageview={};var track;this._category=category;pageview.page=path(props,this.options);pageview.title=name||props.title;pageview.location=props.url;if(campaign.name)pageview.campaignName=campaign.name;if(campaign.source)pageview.campaignSource=campaign.source;if(campaign.medium)pageview.campaignMedium=campaign.medium;if(campaign.content)pageview.campaignContent=campaign.content;if(campaign.term)pageview.campaignKeyword=campaign.term;window.ga("send","pageview",pageview);if(category&&this.options.trackCategorizedPages){track=page.track(category);this.track(track,{nonInteraction:1})}if(name&&this.options.trackNamedPages){track=page.track(name);this.track(track,{nonInteraction:1})}};GA.prototype.identify=function(identify){var opts=this.options;if(opts.sendUserId&&identify.userId()){window.ga("set","userId",identify.userId())}var custom=metrics(user.traits(),opts);if(length(custom))window.ga("set",custom)};GA.prototype.track=function(track,options){var contextOpts=track.options(this.name);var interfaceOpts=this.options;var opts=defaults(options||{},contextOpts);opts=defaults(opts,interfaceOpts);var props=track.properties();var campaign=track.proxy("context.campaign")||{};var custom=metrics(props,interfaceOpts);if(length(custom))window.ga("set",custom);var payload={eventAction:track.event(),eventCategory:props.category||this._category||"All",eventLabel:props.label,eventValue:formatValue(props.value||track.revenue()),nonInteraction:!!(props.nonInteraction||opts.nonInteraction)};if(campaign.name)payload.campaignName=campaign.name;if(campaign.source)payload.campaignSource=campaign.source;if(campaign.medium)payload.campaignMedium=campaign.medium;if(campaign.content)payload.campaignContent=campaign.content;if(campaign.term)payload.campaignKeyword=campaign.term;window.ga("send","event",payload)};GA.prototype.completedOrder=function(track){var total=track.total()||track.revenue()||0;var orderId=track.orderId();var products=track.products();var props=track.properties();if(!orderId)return;if(!this.ecommerce){window.ga("require","ecommerce");this.ecommerce=true}window.ga("ecommerce:addTransaction",{affiliation:props.affiliation,shipping:track.shipping(),revenue:total,tax:track.tax(),id:orderId,currency:track.currency()});each(products,function(product){var track=new Track({properties:product});window.ga("ecommerce:addItem",{category:track.category(),quantity:track.quantity(),price:track.price(),name:track.name(),sku:track.sku(),id:orderId,currency:track.currency()})});window.ga("ecommerce:send")};GA.prototype.initializeClassic=function(){var opts=this.options;var anonymize=opts.anonymizeIp;var db=opts.doubleClick;var domain=opts.domain;var enhanced=opts.enhancedLinkAttribution;var ignore=opts.ignoredReferrers;var sample=opts.siteSpeedSampleRate;window._gaq=window._gaq||[];push("_setAccount",opts.trackingId);push("_setAllowLinker",true);if(anonymize)push("_gat._anonymizeIp");if(domain)push("_setDomainName",domain);if(sample)push("_setSiteSpeedSampleRate",sample);if(enhanced){var protocol="https:"===document.location.protocol?"https:":"http:";var pluginUrl=protocol+"//www.google-analytics.com/plugins/ga/inpage_linkid.js";push("_require","inpage_linkid",pluginUrl)}if(ignore){if(!is.array(ignore))ignore=[ignore];each(ignore,function(domain){push("_addIgnoredRef",domain)})}if(this.options.doubleClick){this.load("double click",this.ready)}else{var name=useHttps()?"https":"http";this.load(name,this.ready)}};GA.prototype.loadedClassic=function(){return!!(window._gaq&&window._gaq.push!==Array.prototype.push)};GA.prototype.pageClassic=function(page){var opts=page.options(this.name);var category=page.category();var props=page.properties();var name=page.fullName();var track;push("_trackPageview",path(props,this.options));if(category&&this.options.trackCategorizedPages){track=page.track(category);this.track(track,{nonInteraction:1})}if(name&&this.options.trackNamedPages){track=page.track(name);this.track(track,{nonInteraction:1})}};GA.prototype.trackClassic=function(track,options){var opts=options||track.options(this.name);var props=track.properties();var revenue=track.revenue();var event=track.event();var category=this._category||props.category||"All";var label=props.label;var value=formatValue(revenue||props.value);var nonInteraction=!!(props.nonInteraction||opts.nonInteraction);push("_trackEvent",category,event,label,value,nonInteraction)};GA.prototype.completedOrderClassic=function(track){var total=track.total()||track.revenue()||0;var orderId=track.orderId();var products=track.products()||[];var props=track.properties();var currency=track.currency();if(!orderId)return;push("_addTrans",orderId,props.affiliation,total,track.tax(),track.shipping(),track.city(),track.state(),track.country());each(products,function(product){var track=new Track({properties:product});push("_addItem",orderId,track.sku(),track.name(),track.category(),track.price(),track.quantity())});push("_set","currencyCode",currency);push("_trackTrans")};function path(properties,options){if(!properties)return;var str=properties.path;if(options.includeSearch&&properties.search)str+=properties.search;return str}function formatValue(value){if(!value||value<0)return 0;return Math.round(value)}function metrics(obj,data){var dimensions=data.dimensions;var metrics=data.metrics;var names=keys(metrics).concat(keys(dimensions));var ret={};for(var i=0;i<names.length;++i){var name=names[i];var key=metrics[name]||dimensions[name];var value=dot(obj,name)||obj[name];if(null==value)continue;ret[key]=value}return ret}GA.prototype.loadEnhancedEcommerce=function(track){if(!this.enhancedEcommerceLoaded){window.ga("require","ec");this.enhancedEcommerceLoaded=true}window.ga("set","&cu",track.currency())};GA.prototype.pushEnhancedEcommerce=function(track){ga("send","event",track.category()||"EnhancedEcommerce",track.event(),{nonInteraction:1})};GA.prototype.startedOrderEnhanced=function(track){this.viewedCheckoutStep(track)};GA.prototype.updatedOrderEnhanced=function(track){this.startedOrderEnhanced(track)};GA.prototype.viewedCheckoutStepEnhanced=function(track){var products=track.products();var props=track.properties();var options=extractCheckoutOptions(props);this.loadEnhancedEcommerce(track);each(products,function(product){var trackTemp=new Track({properties:product});enhancedEcommerceTrackProduct(trackTemp)});window.ga("ec:setAction","checkout",{step:props.step||1,option:options||undefined});this.pushEnhancedEcommerce(track)};GA.prototype.completedCheckoutStepEnhanced=function(track){var props=track.properties();var options=extractCheckoutOptions(props);if(!props.step||!options)return;this.loadEnhancedEcommerce(track);window.ga("ec:setAction","checkout_option",{step:props.step||1,option:options});window.ga("send","event","Checkout","Option")};GA.prototype.completedOrderEnhanced=function(track){var total=track.total()||track.revenue()||0;var orderId=track.orderId();var products=track.products();var props=track.properties();if(!orderId)return;this.loadEnhancedEcommerce(track);each(products,function(product){var track=new Track({properties:product});enhancedEcommerceTrackProduct(track)});window.ga("ec:setAction","purchase",{id:orderId,affiliation:props.affiliation,revenue:total,tax:track.tax(),shipping:track.shipping(),coupon:track.coupon()});this.pushEnhancedEcommerce(track)};GA.prototype.refundedOrderEnhanced=function(track){var orderId=track.orderId();var products=track.products();if(!orderId)return;this.loadEnhancedEcommerce(track);each(products,function(product){var track=new Track({properties:product});window.ga("ec:addProduct",{id:track.id()||track.sku(),quantity:track.quantity()})});window.ga("ec:setAction","refund",{id:orderId});this.pushEnhancedEcommerce(track)};GA.prototype.addedProductEnhanced=function(track){this.loadEnhancedEcommerce(track);enhancedEcommerceProductAction(track,"add");this.pushEnhancedEcommerce(track)};GA.prototype.removedProductEnhanced=function(track){this.loadEnhancedEcommerce(track);enhancedEcommerceProductAction(track,"remove");this.pushEnhancedEcommerce(track)};GA.prototype.viewedProductEnhanced=function(track){this.loadEnhancedEcommerce(track);enhancedEcommerceProductAction(track,"detail");this.pushEnhancedEcommerce(track)};GA.prototype.clickedProductEnhanced=function(track){var props=track.properties();this.loadEnhancedEcommerce(track);enhancedEcommerceProductAction(track,"click",{list:props.list});this.pushEnhancedEcommerce(track)};GA.prototype.viewedPromotionEnhanced=function(track){var props=track.properties();this.loadEnhancedEcommerce(track);window.ga("ec:addPromo",{id:track.id(),name:track.name(),creative:props.creative,position:props.position});this.pushEnhancedEcommerce(track)};GA.prototype.clickedPromotionEnhanced=function(track){var props=track.properties();this.loadEnhancedEcommerce(track);window.ga("ec:addPromo",{id:track.id(),name:track.name(),creative:props.creative,position:props.position});ga("ec:setAction","promo_click",{});this.pushEnhancedEcommerce(track)};function enhancedEcommerceTrackProduct(track){var props=track.properties();window.ga("ec:addProduct",{id:track.id()||track.sku(),name:track.name(),category:track.category(),quantity:track.quantity(),price:track.price(),brand:props.brand,variant:props.variant})}function enhancedEcommerceProductAction(track,action,data){enhancedEcommerceTrackProduct(track);window.ga("ec:setAction",action,data||{})}function extractCheckoutOptions(props){var options=[props.paymentMethod,props.shippingMethod];var valid=select(options,function(e){return e});return valid.length>0?valid.join(", "):null}},{"analytics.js-integration":88,"global-queue":173,object:181,canonical:182,"use-https":90,facade:147,callback:94,defaults:172,"load-script":143,select:183,"obj-case":92,each:4,type:113,url:184,is:91}],181:[function(require,module,exports){var has=Object.prototype.hasOwnProperty;exports.keys=Object.keys||function(obj){var keys=[];for(var key in obj){if(has.call(obj,key)){keys.push(key)}}return keys};exports.values=function(obj){var vals=[];for(var key in obj){if(has.call(obj,key)){vals.push(obj[key])}}return vals};exports.merge=function(a,b){for(var key in b){if(has.call(b,key)){a[key]=b[key]}}return a};exports.length=function(obj){return exports.keys(obj).length};exports.isEmpty=function(obj){return 0==exports.length(obj)}},{}],182:[function(require,module,exports){module.exports=function canonical(){var tags=document.getElementsByTagName("link");for(var i=0,tag;tag=tags[i];i++){if("canonical"==tag.getAttribute("rel"))return tag.getAttribute("href")}}},{}],183:[function(require,module,exports){var toFunction=require("to-function");module.exports=function(arr,fn){var ret=[];fn=toFunction(fn);for(var i=0;i<arr.length;++i){if(fn(arr[i],i)){ret.push(arr[i])}}return ret}},{"to-function":185}],185:[function(require,module,exports){var expr;try{expr=require("props")}catch(e){expr=require("component-props")}module.exports=toFunction;function toFunction(obj){switch({}.toString.call(obj)){case"[object Object]":return objectToFunction(obj);case"[object Function]":return obj;case"[object String]":return stringToFunction(obj);case"[object RegExp]":return regexpToFunction(obj);default:return defaultToFunction(obj)}}function defaultToFunction(val){return function(obj){return val===obj}}function regexpToFunction(re){return function(obj){return re.test(obj)}}function stringToFunction(str){if(/^ *\W+/.test(str))return new Function("_","return _ "+str);return new Function("_","return "+get(str))}function objectToFunction(obj){var match={};for(var key in obj){match[key]=typeof obj[key]==="string"?defaultToFunction(obj[key]):toFunction(obj[key])}return function(val){if(typeof val!=="object")return false;for(var key in match){if(!(key in val))return false;if(!match[key](val[key]))return false +}return true}}function get(str){var props=expr(str);if(!props.length)return"_."+str;var val,i,prop;for(i=0;i<props.length;i++){prop=props[i];val="_."+prop;val="('function' == typeof "+val+" ? "+val+"() : "+val+")";str=stripNested(prop,str,val)}return str}function stripNested(prop,str,val){return str.replace(new RegExp("(\\.)?"+prop,"g"),function($0,$1){return $1?$0:val})}},{props:118,"component-props":118}],184:[function(require,module,exports){exports.parse=function(url){var a=document.createElement("a");a.href=url;return{href:a.href,host:a.host,port:a.port,hash:a.hash,hostname:a.hostname,pathname:a.pathname,protocol:a.protocol,search:a.search,query:a.search.slice(1)}};exports.isAbsolute=function(url){if(0==url.indexOf("//"))return true;if(~url.indexOf("://"))return true;return false};exports.isRelative=function(url){return!exports.isAbsolute(url)};exports.isCrossDomain=function(url){url=exports.parse(url);return url.hostname!=location.hostname||url.port!=location.port||url.protocol!=location.protocol}},{}],40:[function(require,module,exports){var push=require("global-queue")("dataLayer",{wrap:false});var integration=require("analytics.js-integration");var GTM=module.exports=integration("Google Tag Manager").assumesPageview().global("dataLayer").global("google_tag_manager").option("containerId","").option("trackNamedPages",true).option("trackCategorizedPages",true).tag('<script src="//www.googletagmanager.com/gtm.js?id={{ containerId }}&l=dataLayer">');GTM.prototype.initialize=function(){push({"gtm.start":+new Date,event:"gtm.js"});this.load(this.ready)};GTM.prototype.loaded=function(){return!!(window.dataLayer&&[].push!=window.dataLayer.push)};GTM.prototype.page=function(page){var category=page.category();var props=page.properties();var name=page.fullName();var opts=this.options;var track;if(opts.trackAllPages){this.track(page.track())}if(category&&opts.trackCategorizedPages){this.track(page.track(category))}if(name&&opts.trackNamedPages){this.track(page.track(name))}};GTM.prototype.track=function(track){var props=track.properties();props.event=track.event();push(props)}},{"global-queue":173,"analytics.js-integration":88}],41:[function(require,module,exports){var integration=require("analytics.js-integration");var Identify=require("facade").Identify;var Track=require("facade").Track;var callback=require("callback");var load=require("load-script");var onBody=require("on-body");var each=require("each");var is=require("is");var pick=require("pick");var omit=require("omit");var GoSquared=module.exports=integration("GoSquared").assumesPageview().global("_gs").option("siteToken","").option("anonymizeIP",false).option("cookieDomain",null).option("useCookies",true).option("trackHash",false).option("trackLocal",false).option("trackParams",true).tag('<script src="//d1l6p2sc9645hc.cloudfront.net/tracker.js">');GoSquared.prototype.initialize=function(page){var self=this;var options=this.options;var user=this.analytics.user();push(options.siteToken);each(options,function(name,value){if("siteToken"==name)return;if(null==value)return;push("set",name,value)});self.identify(new Identify({traits:user.traits(),userId:user.id()}));self.load(this.ready)};GoSquared.prototype.loaded=function(){return!!(window._gs&&window._gs.v)};GoSquared.prototype.page=function(page){var props=page.properties();var name=page.fullName();push("track",props.path,name||props.title)};GoSquared.prototype.identify=function(identify){var traits=identify.traits({createdAt:"created_at",firstName:"first_name",lastName:"last_name",title:"company_position",industry:"company_industry"});var specialKeys=["id","email","name","first_name","last_name","username","description","avatar","phone","created_at","company_name","company_size","company_position","company_industry"];var props=pick.apply(null,[traits].concat(specialKeys));props.custom=omit(specialKeys,traits);var id=identify.userId();if(id){push("identify",id,props)}else{push("properties",props)}var email=identify.email();var username=identify.username();var name=email||username||id;if(name)push("set","visitorName",name)};GoSquared.prototype.track=function(track){push("event",track.event(),track.properties())};GoSquared.prototype.completedOrder=function(track){var products=track.products();var items=[];each(products,function(product){var track=new Track({properties:product});items.push({category:track.category(),quantity:track.quantity(),price:track.price(),name:track.name()})});push("transaction",track.orderId(),{revenue:track.total(),track:true},items)};function push(){var _gs=window._gs=window._gs||function(){(_gs.q=_gs.q||[]).push(arguments)};_gs.apply(null,arguments)}},{"analytics.js-integration":88,facade:147,callback:94,"load-script":143,"on-body":144,each:4,is:91,pick:186,omit:187}],186:[function(require,module,exports){module.exports=pick;function pick(obj){var keys=[].slice.call(arguments,1);var ret={};for(var i=0,key;key=keys[i];i++){if(key in obj)ret[key]=obj[key]}return ret}},{}],187:[function(require,module,exports){module.exports=omit;function omit(keys,object){var ret={};for(var item in object){ret[item]=object[item]}for(var i=0;i<keys.length;i++){delete ret[keys[i]]}return ret}},{}],42:[function(require,module,exports){var integration=require("analytics.js-integration");var alias=require("alias");var Heap=module.exports=integration("Heap").global("heap").option("appId","").tag('<script src="//cdn.heapanalytics.com/js/heap-{{ appId }}.js">');Heap.prototype.initialize=function(page){window.heap=window.heap||[];window.heap.load=function(appid,config){window.heap.appid=appid;window.heap.config=config;var methodFactory=function(type){return function(){heap.push([type].concat(Array.prototype.slice.call(arguments,0)))}};var methods=["clearEventProperties","identify","setEventProperties","track","unsetEventProperty"];for(var i=0;i<methods.length;i++){heap[methods[i]]=methodFactory(methods[i])}};window.heap.load(this.options.appId);this.load(this.ready)};Heap.prototype.loaded=function(){return window.heap&&window.heap.appid};Heap.prototype.identify=function(identify){var traits=identify.traits({email:"_email"});var id=identify.userId();if(id)traits.handle=id;window.heap.identify(traits)};Heap.prototype.track=function(track){window.heap.track(track.event(),track.properties())}},{"analytics.js-integration":88,alias:177}],43:[function(require,module,exports){var integration=require("analytics.js-integration");var Hellobar=module.exports=integration("Hello Bar").assumesPageview().global("_hbq").option("apiKey","").tag('<script src="//s3.amazonaws.com/scripts.hellobar.com/{{ apiKey }}.js">');Hellobar.prototype.initialize=function(page){window._hbq=window._hbq||[];this.load(this.ready)};Hellobar.prototype.loaded=function(){return!!(window._hbq&&window._hbq.push!==Array.prototype.push)}},{"analytics.js-integration":88}],44:[function(require,module,exports){var integration=require("analytics.js-integration");var is=require("is");var HitTail=module.exports=integration("HitTail").assumesPageview().global("htk").option("siteId","").tag('<script src="//{{ siteId }}.hittail.com/mlt.js">');HitTail.prototype.initialize=function(page){this.load(this.ready)};HitTail.prototype.loaded=function(){return is.fn(window.htk)}},{"analytics.js-integration":88,is:91}],45:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("_hsq");var convert=require("convert-dates");var HubSpot=module.exports=integration("HubSpot").assumesPageview().global("_hsq").option("portalId",null).tag('<script id="hs-analytics" src="https://js.hs-analytics.net/analytics/{{ cache }}/{{ portalId }}.js">');HubSpot.prototype.initialize=function(page){window._hsq=[];var cache=Math.ceil(new Date/3e5)*3e5;this.load({cache:cache},this.ready)};HubSpot.prototype.loaded=function(){return!!(window._hsq&&window._hsq.push!==Array.prototype.push)};HubSpot.prototype.page=function(page){push("_trackPageview")};HubSpot.prototype.identify=function(identify){if(!identify.email())return;var traits=identify.traits();traits=convertDates(traits);push("identify",traits)};HubSpot.prototype.track=function(track){var props=track.properties();props=convertDates(props);push("trackEvent",track.event(),props)};function convertDates(properties){return convert(properties,function(date){return date.getTime()})}},{"analytics.js-integration":88,"global-queue":173,"convert-dates":178}],46:[function(require,module,exports){var integration=require("analytics.js-integration");var alias=require("alias");var Improvely=module.exports=integration("Improvely").assumesPageview().global("_improvely").global("improvely").option("domain","").option("projectId",null).tag('<script src="//{{ domain }}.iljmp.com/improvely.js">');Improvely.prototype.initialize=function(page){window._improvely=[];window.improvely={init:function(e,t){window._improvely.push(["init",e,t])},goal:function(e){window._improvely.push(["goal",e])},label:function(e){window._improvely.push(["label",e])}};var domain=this.options.domain;var id=this.options.projectId;window.improvely.init(domain,id);this.load(this.ready)};Improvely.prototype.loaded=function(){return!!(window.improvely&&window.improvely.identify)};Improvely.prototype.identify=function(identify){var id=identify.userId();if(id)window.improvely.label(id)};Improvely.prototype.track=function(track){var props=track.properties({revenue:"amount"});props.type=track.event();window.improvely.goal(props)}},{"analytics.js-integration":88,alias:177}],47:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("_iva");var Track=require("facade").Track;var each=require("each");var is=require("is");var has=Object.prototype.hasOwnProperty;var InsideVault=module.exports=integration("InsideVault").global("_iva").option("clientId","").option("domain","").tag('<script src="//analytics.staticiv.com/iva.js">').mapping("events");InsideVault.prototype.initialize=function(page){var domain=this.options.domain;window._iva=window._iva||[];push("setClientId",this.options.clientId);var userId=this.analytics.user().id();if(userId)push("setUserId",userId);if(domain)push("setDomain",domain);this.load(this.ready)};InsideVault.prototype.loaded=function(){return!!(window._iva&&window._iva.push!==Array.prototype.push)};InsideVault.prototype.identify=function(identify){push("setUserId",identify.userId())};InsideVault.prototype.page=function(page){push("trackEvent","click")};InsideVault.prototype.track=function(track){var user=this.analytics.user();var events=this.events(track.event());var value=track.revenue()||track.value()||0;var eventId=track.orderId()||user.id()||"";each(events,function(event){if(event!="sale"){push("trackEvent",event,value,eventId)}})}},{"analytics.js-integration":88,"global-queue":173,facade:147,each:4,is:91}],48:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("__insp");var alias=require("alias");var clone=require("clone");var Inspectlet=module.exports=integration("Inspectlet").assumesPageview().global("__insp").global("__insp_").option("wid","").tag('<script src="//cdn.inspectlet.com/inspectlet.js">');Inspectlet.prototype.initialize=function(page){push("wid",this.options.wid);this.load(this.ready)};Inspectlet.prototype.loaded=function(){return!!(window.__insp_&&window.__insp)};Inspectlet.prototype.identify=function(identify){var traits=identify.traits({id:"userid"});push("tagSession",traits)};Inspectlet.prototype.track=function(track){push("tagSession",track.event())};Inspectlet.prototype.page=function(){push("virtualPage")}},{"analytics.js-integration":88,"global-queue":173,alias:177,clone:95}],49:[function(require,module,exports){var integration=require("analytics.js-integration");var convertDates=require("convert-dates");var defaults=require("defaults");var del=require("obj-case").del;var isEmail=require("is-email");var load=require("load-script");var empty=require("is-empty");var alias=require("alias");var each=require("each");var when=require("when");var is=require("is");var Intercom=module.exports=integration("Intercom").assumesPageview().global("Intercom").option("activator","#IntercomDefaultWidget").option("appId","").option("inbox",false).tag('<script src="https://static.intercomcdn.com/intercom.v1.js">');Intercom.prototype.initialize=function(page){var self=this;this.load(function(){when(function(){return self.loaded()},self.ready)})};Intercom.prototype.loaded=function(){return is.fn(window.Intercom)};Intercom.prototype.page=function(page){window.Intercom("update")};Intercom.prototype.identify=function(identify){var traits=identify.traits({userId:"user_id"});var activator=this.options.activator;var opts=identify.options(this.name);var companyCreated=identify.companyCreated();var created=identify.created();var email=identify.email();var name=identify.name();var id=identify.userId();var group=this.analytics.group();if(!id&&!traits.email)return;traits.app_id=this.options.appId;if(null!=traits.company&&!is.object(traits.company))delete traits.company;if(traits.company)defaults(traits.company,group.traits());if(name)traits.name=name;if(created){del(traits,"created");del(traits,"createdAt");traits.created_at=created}if(companyCreated){del(traits.company,"created");del(traits.company,"createdAt");traits.company.created_at=companyCreated}traits=convertDates(traits,formatDate);if(opts.increments)traits.increments=opts.increments;if(opts.userHash)traits.user_hash=opts.userHash;if(opts.user_hash)traits.user_hash=opts.user_hash;if("#IntercomDefaultWidget"!=activator){traits.widget={activator:activator}}var method=this._id!==id?"boot":"update";this._id=id;window.Intercom(method,traits)};Intercom.prototype.group=function(group){var props=group.properties();props=alias(props,{createdAt:"created"});props=alias(props,{created:"created_at"});var id=group.groupId();if(id)props.id=id;window.Intercom("update",{company:props})};Intercom.prototype.track=function(track){window.Intercom("trackEvent",track.event(),track.properties())};function formatDate(date){return Math.floor(date/1e3)}},{"analytics.js-integration":88,"convert-dates":178,defaults:172,"obj-case":92,"is-email":169,"load-script":143,"is-empty":122,alias:177,each:4,when:146,is:91}],50:[function(require,module,exports){var integration=require("analytics.js-integration");var clone=require("clone");var Keen=module.exports=integration("Keen IO").global("Keen").option("projectId","").option("readKey","").option("writeKey","").option("ipAddon",false).option("uaAddon",false).option("urlAddon",false).option("referrerAddon",false).option("trackNamedPages",true).option("trackAllPages",false).option("trackCategorizedPages",true).tag('<script src="//d26b395fwzu5fz.cloudfront.net/3.0.7/{{ lib }}.min.js">');Keen.prototype.initialize=function(){var options=this.options;!function(a,b){if(void 0===b[a]){b["_"+a]={},b[a]=function(c){b["_"+a].clients=b["_"+a].clients||{},b["_"+a].clients[c.projectId]=this,this._config=c},b[a].ready=function(c){b["_"+a].ready=b["_"+a].ready||[],b["_"+a].ready.push(c)};for(var c=["addEvent","setGlobalProperties","trackExternalLink","on"],d=0;d<c.length;d++){var e=c[d],f=function(a){return function(){return this["_"+a]=this["_"+a]||[],this["_"+a].push(arguments),this}};b[a].prototype[e]=f(e)}}}("Keen",window);this.client=new window.Keen({projectId:options.projectId,writeKey:options.writeKey,readKey:options.readKey});var lib=this.options.readKey?"keen":"keen-tracker";this.load({lib:lib},this.ready)};Keen.prototype.loaded=function(){return!!(window.Keen&&window.Keen.prototype.configure)};Keen.prototype.page=function(page){var category=page.category();var props=page.properties();var name=page.fullName();var opts=this.options;if(opts.trackAllPages){this.track(page.track())}if(name&&opts.trackNamedPages){this.track(page.track(name))}if(category&&opts.trackCategorizedPages){this.track(page.track(category))}};Keen.prototype.identify=function(identify){var traits=identify.traits();var id=identify.userId();var user={};if(id)user.userId=id;if(traits)user.traits=traits;var props={user:user};this.addons(props,identify);this.client.setGlobalProperties(function(){return clone(props)})};Keen.prototype.track=function(track){var props=track.properties();this.addons(props,track);this.client.addEvent(track.event(),props)};Keen.prototype.addons=function(obj,msg){var options=this.options;var addons=[];if(options.ipAddon){addons.push({name:"keen:ip_to_geo",input:{ip:"ip_address"},output:"ip_geo_info"});obj.ip_address="${keen.ip}"}if(options.uaAddon){addons.push({name:"keen:ua_parser",input:{ua_string:"user_agent"},output:"parsed_user_agent"});obj.user_agent="${keen.user_agent}"}if(options.urlAddon){addons.push({name:"keen:url_parser",input:{url:"page_url"},output:"parsed_page_url"});obj.page_url=document.location.href}if(options.referrerAddon){addons.push({name:"keen:referrer_parser",input:{referrer_url:"referrer_url",page_url:"page_url"},output:"referrer_info"});obj.referrer_url=document.referrer;obj.page_url=document.location.href}obj.keen={timestamp:msg.timestamp(),addons:addons}}},{"analytics.js-integration":88,clone:95}],51:[function(require,module,exports){var integration=require("analytics.js-integration");var indexof=require("indexof");var is=require("is");var Kenshoo=module.exports=integration("Kenshoo").global("k_trackevent").option("cid","").option("subdomain","").option("events",[]).tag('<script src="//{{ subdomain }}.xg4ken.com/media/getpx.php?cid={{ cid }}">');Kenshoo.prototype.initialize=function(page){this.load(this.ready)};Kenshoo.prototype.loaded=function(){return is.fn(window.k_trackevent)};Kenshoo.prototype.track=function(track){var events=this.options.events;var traits=track.traits();var event=track.event();var revenue=track.revenue()||0;if(!~indexof(events,event))return;var params=["id="+this.options.cid,"type=conv","val="+revenue,"orderId="+track.orderId(),"promoCode="+track.coupon(),"valueCurrency="+track.currency(),"GCID=","kw=","product="];window.k_trackevent(params,this.options.subdomain)}},{"analytics.js-integration":88,indexof:116,is:91}],52:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("_kmq");var Track=require("facade").Track;var alias=require("alias");var each=require("each");var is=require("is");var KISSmetrics=module.exports=integration("KISSmetrics").assumesPageview().global("_kmq").global("KM").global("_kmil").option("apiKey","").option("trackNamedPages",true).option("trackCategorizedPages",true).option("prefixProperties",true).tag("library",'<script src="//scripts.kissmetrics.com/{{ apiKey }}.2.js">');exports.isMobile=navigator.userAgent.match(/Android/i)||navigator.userAgent.match(/BlackBerry/i)||navigator.userAgent.match(/iPhone|iPod/i)||navigator.userAgent.match(/iPad/i)||navigator.userAgent.match(/Opera Mini/i)||navigator.userAgent.match(/IEMobile/i);KISSmetrics.prototype.initialize=function(page){var self=this;window._kmq=[];if(exports.isMobile)push("set",{"Mobile Session":"Yes"});this.load("library",function(){self.trackPage(page);self.ready()})};KISSmetrics.prototype.loaded=function(){return is.object(window.KM)};KISSmetrics.prototype.page=function(page){if(!window.KM_SKIP_PAGE_VIEW)window.KM.pageView();this.trackPage(page)};KISSmetrics.prototype.trackPage=function(page){var category=page.category();var name=page.fullName();var opts=this.options;if(name&&opts.trackNamedPages){this.track(page.track(name))}if(category&&opts.trackCategorizedPages){this.track(page.track(category))}};KISSmetrics.prototype.identify=function(identify){var traits=identify.traits();var id=identify.userId();if(id)push("identify",id);if(traits)push("set",traits)};KISSmetrics.prototype.track=function(track){var mapping={revenue:"Billing Amount"};var event=track.event();var properties=track.properties(mapping);if(this.options.prefixProperties)properties=prefix(event,properties);push("record",event,properties)};KISSmetrics.prototype.alias=function(alias){push("alias",alias.to(),alias.from())};KISSmetrics.prototype.completedOrder=function(track){var products=track.products();var event=track.event();push("record",event,prefix(event,track.properties()));window._kmq.push(function(){var km=window.KM;each(products,function(product,i){var item=prefix(event,product);item._t=km.ts()+i;item._d=1;km.set(item)})})};function prefix(event,properties){var prefixed={};each(properties,function(key,val){if(key==="Billing Amount"){prefixed[key]=val}else{prefixed[event+" - "+key]=val}});return prefixed}},{"analytics.js-integration":88,"global-queue":173,facade:147,alias:177,each:4,is:91}],53:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("_learnq");var tick=require("next-tick");var alias=require("alias");var aliases={id:"$id",email:"$email",firstName:"$first_name",lastName:"$last_name",phone:"$phone_number",title:"$title"};var Klaviyo=module.exports=integration("Klaviyo").assumesPageview().global("_learnq").option("apiKey","").tag('<script src="//a.klaviyo.com/media/js/learnmarklet.js">');Klaviyo.prototype.initialize=function(page){var self=this;push("account",this.options.apiKey);this.load(function(){tick(self.ready)})};Klaviyo.prototype.loaded=function(){return!!(window._learnq&&window._learnq.push!==Array.prototype.push)};Klaviyo.prototype.identify=function(identify){var traits=identify.traits(aliases);if(!traits.$id&&!traits.$email)return;push("identify",traits)};Klaviyo.prototype.group=function(group){var props=group.properties();if(!props.name)return;push("identify",{$organization:props.name})};Klaviyo.prototype.track=function(track){push("track",track.event(),track.properties({revenue:"$value"}))}},{"analytics.js-integration":88,"global-queue":173,"next-tick":103,alias:177}],54:[function(require,module,exports){var integration=require("analytics.js-integration");var clone=require("clone");var each=require("each");var Identify=require("facade").Identify;var when=require("when");var LiveChat=module.exports=integration("LiveChat").assumesPageview().global("__lc").global("__lc_inited").global("LC_API").global("LC_Invite").option("group",0).option("license","").tag('<script src="//cdn.livechatinc.com/tracking.js">');LiveChat.prototype.initialize=function(page){var self=this;var user=this.analytics.user();var identify=new Identify({userId:user.id(),traits:user.traits()});window.__lc=clone(this.options);window.__lc.visitor={name:identify.name(),email:identify.email()};this.load(function(){when(function(){return self.loaded()},self.ready)})};LiveChat.prototype.loaded=function(){return!!(window.LC_API&&window.LC_Invite)};LiveChat.prototype.identify=function(identify){var traits=identify.traits({userId:"User ID"});window.LC_API.set_custom_variables(convert(traits))};function convert(traits){var arr=[];each(traits,function(key,value){arr.push({name:key,value:value})});return arr}},{"analytics.js-integration":88,clone:95,each:4,facade:147,when:146}],55:[function(require,module,exports){var integration=require("analytics.js-integration");var Identify=require("facade").Identify;var useHttps=require("use-https");var LuckyOrange=module.exports=integration("Lucky Orange").assumesPageview().global("_loq").global("__wtw_watcher_added").global("__wtw_lucky_site_id").global("__wtw_lucky_is_segment_io").global("__wtw_custom_user_data").option("siteId",null).tag("http",'<script src="http://www.luckyorange.com/w.js?{{ cache }}">').tag("https",'<script src="https://ssl.luckyorange.com/w.js?{{ cache }}">');LuckyOrange.prototype.initialize=function(page){var user=this.analytics.user();window._loq||(window._loq=[]);window.__wtw_lucky_site_id=this.options.siteId;this.identify(new Identify({traits:user.traits(),userId:user.id()}));var cache=Math.floor((new Date).getTime()/6e4);var name=useHttps()?"https":"http";this.load(name,{cache:cache},this.ready)};LuckyOrange.prototype.loaded=function(){return!!window.__wtw_watcher_added};LuckyOrange.prototype.identify=function(identify){var traits=identify.traits();var email=identify.email();var name=identify.name();if(name)traits.name=name;if(email)traits.email=email;window.__wtw_custom_user_data=traits}},{"analytics.js-integration":88,facade:147,"use-https":90}],56:[function(require,module,exports){var integration=require("analytics.js-integration");var alias=require("alias");var Lytics=module.exports=integration("Lytics").global("jstag").option("cid","").option("cookie","seerid").option("delay",2e3).option("sessionTimeout",1800).option("url","//c.lytics.io").tag('<script src="//c.lytics.io/static/io.min.js">');var aliases={sessionTimeout:"sessecs"};Lytics.prototype.initialize=function(page){var options=alias(this.options,aliases);window.jstag=function(){var t={_q:[],_c:options,ts:(new Date).getTime()};t.send=function(){this._q.push(["ready","send",Array.prototype.slice.call(arguments)]);return this};return t}();this.load(this.ready)};Lytics.prototype.loaded=function(){return!!(window.jstag&&window.jstag.bind)};Lytics.prototype.page=function(page){window.jstag.send(page.properties())};Lytics.prototype.identify=function(identify){var traits=identify.traits({userId:"_uid"});window.jstag.send(traits)};Lytics.prototype.track=function(track){var props=track.properties();props._e=track.event();window.jstag.send(props)}},{"analytics.js-integration":88,alias:177}],57:[function(require,module,exports){var alias=require("alias");var clone=require("clone");var dates=require("convert-dates");var integration=require("analytics.js-integration");var is=require("is");var iso=require("to-iso-string");var indexof=require("indexof");var del=require("obj-case").del;var some=require("some");var Mixpanel=module.exports=integration("Mixpanel").global("mixpanel").option("increments",[]).option("cookieName","").option("nameTag",true).option("pageview",false).option("people",false).option("token","").option("trackAllPages",false).option("trackNamedPages",true).option("trackCategorizedPages",true).tag('<script src="//cdn.mxpnl.com/libs/mixpanel-2.2.min.js">');var optionsAliases={cookieName:"cookie_name"};Mixpanel.prototype.initialize=function(){(function(c,a){window.mixpanel=a;var b,d,h,e;a._i=[];a.init=function(b,c,f){function d(a,b){var c=b.split(".");2==c.length&&(a=a[c[0]],b=c[1]);a[b]=function(){a.push([b].concat(Array.prototype.slice.call(arguments,0)))}}var g=a;"undefined"!==typeof f?g=a[f]=[]:f="mixpanel";g.people=g.people||[];h=["disable","track","track_pageview","track_links","track_forms","register","register_once","unregister","identify","alias","name_tag","set_config","people.set","people.increment","people.track_charge","people.append"];for(e=0;e<h.length;e++)d(g,h[e]);a._i.push([b,c,f])};a.__SV=1.2})(document,window.mixpanel||[]);this.options.increments=lowercase(this.options.increments);var options=alias(this.options,optionsAliases);window.mixpanel.init(options.token,options);this.load(this.ready)};Mixpanel.prototype.loaded=function(){return!!(window.mixpanel&&window.mixpanel.config)};Mixpanel.prototype.page=function(page){var category=page.category();var name=page.fullName();var opts=this.options;if(opts.trackAllPages){this.track(page.track())}if(category&&opts.trackCategorizedPages){this.track(page.track(category))}if(name&&opts.trackNamedPages){this.track(page.track(name))}};var traitAliases={created:"$created",email:"$email",firstName:"$first_name",lastName:"$last_name",lastSeen:"$last_seen",name:"$name",username:"$username",phone:"$phone"};Mixpanel.prototype.identify=function(identify){var username=identify.username();var email=identify.email();var id=identify.userId();if(id)window.mixpanel.identify(id);var nametag=email||username||id;if(nametag)window.mixpanel.name_tag(nametag);var traits=identify.traits(traitAliases);if(traits.$created)del(traits,"createdAt");window.mixpanel.register(dates(traits,iso));if(this.options.people)window.mixpanel.people.set(traits)};Mixpanel.prototype.track=function(track){var increments=this.options.increments;var increment=track.event().toLowerCase();var people=this.options.people;var props=track.properties();var revenue=track.revenue();delete props.distinct_id;delete props.ip;delete props.mp_name_tag;delete props.mp_note;delete props.token;for(var key in props){var val=props[key];if(is.array(val)&&some(val,is.object))props[key]=val.length}if(people&&~indexof(increments,increment)){window.mixpanel.people.increment(track.event());window.mixpanel.people.set("Last "+track.event(),new Date)}props=dates(props,iso);window.mixpanel.track(track.event(),props);if(revenue&&people){window.mixpanel.people.track_charge(revenue)}};Mixpanel.prototype.alias=function(alias){var mp=window.mixpanel;var to=alias.to();if(mp.get_distinct_id&&mp.get_distinct_id()===to)return;if(mp.get_property&&mp.get_property("$people_distinct_id")===to)return;mp.alias(to,alias.from())};function lowercase(arr){var ret=new Array(arr.length);for(var i=0;i<arr.length;++i){ret[i]=String(arr[i]).toLowerCase()}return ret}},{alias:177,clone:95,"convert-dates":178,"analytics.js-integration":88,is:91,"to-iso-string":176,indexof:116,"obj-case":92,some:188}],188:[function(require,module,exports){var some=[].some;module.exports=function(arr,fn){if(some)return some.call(arr,fn);for(var i=0,l=arr.length;i<l;++i){if(fn(arr[i],i))return true}return false}},{}],58:[function(require,module,exports){var integration=require("analytics.js-integration");var bind=require("bind");var when=require("when");var is=require("is");var Mojn=module.exports=integration("Mojn").option("customerCode","").global("_mojnTrack").tag('<script src="https://track.idtargeting.com/{{ customerCode }}/track.js">');Mojn.prototype.initialize=function(){window._mojnTrack=window._mojnTrack||[];window._mojnTrack.push({cid:this.options.customerCode});var loaded=bind(this,this.loaded);var ready=this.ready;this.load(function(){when(loaded,ready)})};Mojn.prototype.loaded=function(){return is.object(window._mojnTrack)};Mojn.prototype.identify=function(identify){var email=identify.email();if(!email)return;var img=new Image;img.src="//matcher.idtargeting.com/identify.gif?cid="+this.options.customerCode+"&_mjnctid="+email;img.width=1;img.height=1;return img};Mojn.prototype.track=function(track){var properties=track.properties();var revenue=properties.revenue;var currency=properties.currency||"";var conv=currency+revenue;if(!revenue)return;window._mojnTrack.push({conv:conv});return conv}},{"analytics.js-integration":88,bind:101,when:146,is:91}],59:[function(require,module,exports){var push=require("global-queue")("_mfq");var integration=require("analytics.js-integration");var each=require("each");var Mouseflow=module.exports=integration("Mouseflow").assumesPageview().global("mouseflow").global("_mfq").option("apiKey","").option("mouseflowHtmlDelay",0).tag('<script src="//cdn.mouseflow.com/projects/{{ apiKey }}.js">');Mouseflow.prototype.initialize=function(page){window.mouseflowHtmlDelay=this.options.mouseflowHtmlDelay;this.load(this.ready)};Mouseflow.prototype.loaded=function(){return!!window.mouseflow};Mouseflow.prototype.page=function(page){if(!window.mouseflow)return;if("function"!=typeof mouseflow.newPageView)return;mouseflow.newPageView()};Mouseflow.prototype.identify=function(identify){set(identify.traits())};Mouseflow.prototype.track=function(track){var props=track.properties();props.event=track.event();set(props)};function set(obj){each(obj,function(key,value){push("setVariable",key,value)})}},{"global-queue":173,"analytics.js-integration":88,each:4}],60:[function(require,module,exports){var integration=require("analytics.js-integration");var useHttps=require("use-https");var each=require("each");var is=require("is");var MouseStats=module.exports=integration("MouseStats").assumesPageview().global("msaa").global("MouseStatsVisitorPlaybacks").option("accountNumber","").tag("http",'<script src="http://www2.mousestats.com/js/{{ path }}.js?{{ cache }}">').tag("https",'<script src="https://ssl.mousestats.com/js/{{ path }}.js?{{ cache }}">'); +MouseStats.prototype.initialize=function(page){var number=this.options.accountNumber;var path=number.slice(0,1)+"/"+number.slice(1,2)+"/"+number;var cache=Math.floor((new Date).getTime()/6e4);var name=useHttps()?"https":"http";this.load(name,{path:path,cache:cache},this.ready)};MouseStats.prototype.loaded=function(){return is.array(window.MouseStatsVisitorPlaybacks)};MouseStats.prototype.identify=function(identify){each(identify.traits(),function(key,value){window.MouseStatsVisitorPlaybacks.customVariable(key,value)})}},{"analytics.js-integration":88,"use-https":90,each:4,is:91}],61:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("__nls");var Navilytics=module.exports=integration("Navilytics").assumesPageview().global("__nls").option("memberId","").option("projectId","").tag('<script src="//www.navilytics.com/nls.js?mid={{ memberId }}&pid={{ projectId }}">');Navilytics.prototype.initialize=function(page){window.__nls=window.__nls||[];this.load(this.ready)};Navilytics.prototype.loaded=function(){return!!(window.__nls&&[].push!=window.__nls.push)};Navilytics.prototype.track=function(track){push("tagRecording",track.event())}},{"analytics.js-integration":88,"global-queue":173}],62:[function(require,module,exports){var integration=require("analytics.js-integration");var alias=require("alias");var Identify=require("facade").Identify;var Nudgespot=module.exports=integration("Nudgespot").assumesPageview().option("apiKey","").global("nudgespot").tag('<script id="nudgespot" src="//cdn.nudgespot.com/nudgespot.js">');Nudgespot.prototype.initialize=function(page){window.nudgespot=window.nudgespot||[];window.nudgespot.init=function(n,t){function f(n,m){var a=m.split(".");2==a.length&&(n=n[a[0]],m=a[1]);n[m]=function(){n.push([m].concat(Array.prototype.slice.call(arguments,0)))}}n._version=.1;n._globals=[t];n.people=n.people||[];n.params=n.params||[];m="track register unregister identify set_config people.delete people.create people.update people.create_property people.tag people.remove_Tag".split(" ");for(var i=0;i<m.length;i++)f(n,m[i])};window.nudgespot.init(window.nudgespot,this.options.apiKey);this.load(this.ready)};Nudgespot.prototype.loaded=function(){return!!window.nudgespot&&window.nudgespot.push!==Array.prototype.push};Nudgespot.prototype.identify=function(identify){if(!identify.userId())return this.debug("user id required");var traits=identify.traits({createdAt:"created"});traits=alias(traits,{created:"created_at"});window.nudgespot.identify(identify.userId(),traits)};Nudgespot.prototype.track=function(track){var properties=track.properties();window.nudgespot.track(track.event(),properties)}},{"analytics.js-integration":88,alias:177,facade:147}],63:[function(require,module,exports){var integration=require("analytics.js-integration");var https=require("use-https");var tick=require("next-tick");var Olark=module.exports=integration("Olark").assumesPageview().global("olark").option("identify",true).option("page",true).option("siteId","").option("groupId","").option("track",false);Olark.prototype.initialize=function(page){var self=this;this.load(function(){tick(self.ready)});var groupId=this.options.groupId;if(groupId)api("chat.setOperatorGroup",{group:groupId});api("box.onExpand",function(){self._open=true});api("box.onShrink",function(){self._open=false})};Olark.prototype.loaded=function(){return!!window.olark};Olark.prototype.load=function(callback){var el=document.getElementById("olark");window.olark||function(c){var f=window,d=document,l=https()?"https:":"http:",z=c.name,r="load";var nt=function(){f[z]=function(){(a.s=a.s||[]).push(arguments)};var a=f[z]._={},q=c.methods.length;while(q--){(function(n){f[z][n]=function(){f[z]("call",n,arguments)}})(c.methods[q])}a.l=c.loader;a.i=nt;a.p={0:+new Date};a.P=function(u){a.p[u]=new Date-a.p[0]};function s(){a.P(r);f[z](r)}f.addEventListener?f.addEventListener(r,s,false):f.attachEvent("on"+r,s);var ld=function(){function p(hd){hd="head";return["<",hd,"></",hd,"><",i," onl"+'oad="var d=',g,";d.getElementsByTagName('head')[0].",j,"(d.",h,"('script')).",k,"='",l,"//",a.l,"'",'"',"></",i,">"].join("")}var i="body",m=d[i];if(!m){return setTimeout(ld,100)}a.P(1);var j="appendChild",h="createElement",k="src",n=d[h]("div"),v=n[j](d[h](z)),b=d[h]("iframe"),g="document",e="domain",o;n.style.display="none";m.insertBefore(n,m.firstChild).id=z;b.frameBorder="0";b.id=z+"-loader";if(/MSIE[ ]+6/.test(navigator.userAgent)){b.src="javascript:false"}b.allowTransparency="true";v[j](b);try{b.contentWindow[g].open()}catch(w){c[e]=d[e];o="javascript:var d="+g+".open();d.domain='"+d.domain+"';";b[k]=o+"void(0);"}try{var t=b.contentWindow[g];t.write(p());t.close()}catch(x){b[k]=o+'d.write("'+p().replace(/"/g,String.fromCharCode(92)+'"')+'");d.close();'}a.P(2)};ld()};nt()}({loader:"static.olark.com/jsclient/loader0.js",name:"olark",methods:["configure","extend","declare","identify"]});window.olark.identify(this.options.siteId);callback()};Olark.prototype.page=function(page){if(!this.options.page)return;var props=page.properties();var name=page.fullName();if(!name&&!props.url)return;name=name?name+" page":props.url;this.notify("looking at "+name)};Olark.prototype.identify=function(identify){if(!this.options.identify)return;var username=identify.username();var traits=identify.traits();var id=identify.userId();var email=identify.email();var phone=identify.phone();var name=identify.name()||identify.firstName();if(traits)api("visitor.updateCustomFields",traits);if(email)api("visitor.updateEmailAddress",{emailAddress:email});if(phone)api("visitor.updatePhoneNumber",{phoneNumber:phone});if(name)api("visitor.updateFullName",{fullName:name});var nickname=name||email||username||id;if(name&&email)nickname+=" ("+email+")";if(nickname)api("chat.updateVisitorNickname",{snippet:nickname})};Olark.prototype.track=function(track){if(!this.options.track)return;this.notify('visitor triggered "'+track.event()+'"')};Olark.prototype.notify=function(message){if(!this._open)return;message=message.toLowerCase();api("visitor.getDetails",function(data){if(!data||!data.isConversing)return;api("chat.sendNotificationToOperator",{body:message})})};function api(action,value){window.olark("api."+action,value)}},{"analytics.js-integration":88,"use-https":90,"next-tick":103}],64:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("optimizely");var callback=require("callback");var tick=require("next-tick");var bind=require("bind");var each=require("each");var Optimizely=module.exports=integration("Optimizely").option("variations",true).option("trackNamedPages",true).option("trackCategorizedPages",true);Optimizely.prototype.initialize=function(){if(this.options.variations){var self=this;tick(function(){self.replay()})}this.ready()};Optimizely.prototype.track=function(track){var props=track.properties();if(props.revenue)props.revenue*=100;push("trackEvent",track.event(),props)};Optimizely.prototype.page=function(page){var category=page.category();var name=page.fullName();var opts=this.options;if(category&&opts.trackCategorizedPages){this.track(page.track(category))}if(name&&opts.trackNamedPages){this.track(page.track(name))}};Optimizely.prototype.replay=function(){if(!window.optimizely)return;var data=window.optimizely.data;if(!data)return;var experiments=data.experiments;var map=data.state.variationNamesMap;var traits={};each(map,function(experimentId,variation){var experiment=experiments[experimentId].name;traits["Experiment: "+experiment]=variation});this.analytics.identify(traits)}},{"analytics.js-integration":88,"global-queue":173,callback:94,"next-tick":103,bind:101,each:4}],65:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("_pq");var PerfectAudience=module.exports=integration("Perfect Audience").assumesPageview().global("_pq").option("siteId","").tag('<script src="//tag.perfectaudience.com/serve/{{ siteId }}.js">');PerfectAudience.prototype.initialize=function(page){window._pq=window._pq||[];this.load(this.ready)};PerfectAudience.prototype.loaded=function(){return!!(window._pq&&window._pq.push)};PerfectAudience.prototype.track=function(track){var total=track.total()||track.revenue();var orderId=track.orderId();var props={};var sendProps=false;if(total){props.revenue=total;sendProps=true}if(orderId){props.orderId=orderId;sendProps=true}if(!sendProps)return push("track",track.event());return push("track",track.event(),props)};PerfectAudience.prototype.viewedProduct=function(track){var product=track.sku();push("track",track.event());push("trackProduct",product)};PerfectAudience.prototype.completedOrder=function(track){var total=track.total()||track.revenue();var orderId=track.orderId();var props={};if(total)props.revenue=total;if(orderId)props.orderId=orderId;push("track",track.event(),props)}},{"analytics.js-integration":88,"global-queue":173}],66:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("_prum");var date=require("load-date");var Pingdom=module.exports=integration("Pingdom").assumesPageview().global("_prum").global("PRUM_EPISODES").option("id","").tag('<script src="//rum-static.pingdom.net/prum.min.js">');Pingdom.prototype.initialize=function(page){window._prum=window._prum||[];push("id",this.options.id);push("mark","firstbyte",date.getTime());var self=this;this.load(this.ready)};Pingdom.prototype.loaded=function(){return!!(window._prum&&window._prum.push!==Array.prototype.push)}},{"analytics.js-integration":88,"global-queue":173,"load-date":174}],67:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("_paq");var each=require("each");var is=require("is");var Piwik=module.exports=integration("Piwik").global("_paq").option("url",null).option("siteId","").option("customVariableLimit",5).mapping("goals").tag('<script src="{{ url }}/piwik.js">');Piwik.prototype.initialize=function(){window._paq=window._paq||[];push("setSiteId",this.options.siteId);push("setTrackerUrl",this.options.url+"/piwik.php");push("enableLinkTracking");this.load(this.ready)};Piwik.prototype.loaded=function(){return!!(window._paq&&window._paq.push!=[].push)};Piwik.prototype.page=function(page){push("trackPageView")};Piwik.prototype.track=function(track){var goals=this.goals(track.event());var revenue=track.revenue();var category=track.category()||"All";var action=track.event();var name=track.proxy("properties.name")||track.proxy("properties.label");var value=track.value()||track.revenue();var options=track.options("Piwik");var customVariables=options.customVars||options.cvar;if(!is.object(customVariables)){customVariables={}}for(var i=1;i<=this.options.customVariableLimit;i+=1){if(customVariables[i]){push("setCustomVariable",i.toString(),customVariables[i][0],customVariables[i][1],"page")}}each(goals,function(goal){push("trackGoal",goal,revenue)});push("trackEvent",category,action,name,value)}},{"analytics.js-integration":88,"global-queue":173,each:4,is:91}],68:[function(require,module,exports){var integration=require("analytics.js-integration");var convertDates=require("convert-dates");var push=require("global-queue")("_preactq");var alias=require("alias");var Preact=module.exports=integration("Preact").assumesPageview().global("_preactq").global("_lnq").option("projectCode","").tag('<script src="//d2bbvl6dq48fa6.cloudfront.net/js/preact-4.1.min.js">');Preact.prototype.initialize=function(page){window._preactq=window._preactq||[];window._lnq=window._lnq||[];push("_setCode",this.options.projectCode);this.load(this.ready)};Preact.prototype.loaded=function(){return!!(window._preactq&&window._preactq.push!==Array.prototype.push)};Preact.prototype.identify=function(identify){if(!identify.userId())return;var traits=identify.traits({created:"created_at"});traits=convertDates(traits,convertDate);push("_setPersonData",{name:identify.name(),email:identify.email(),uid:identify.userId(),properties:traits})};Preact.prototype.group=function(group){if(!group.groupId())return;push("_setAccount",group.traits())};Preact.prototype.track=function(track){var props=track.properties();var revenue=track.revenue();var event=track.event();var special={name:event};if(revenue){special.revenue=revenue*100;delete props.revenue}if(props.note){special.note=props.note;delete props.note}push("_logEvent",special,props)};function convertDate(date){return Math.floor(date/1e3)}},{"analytics.js-integration":88,"convert-dates":178,"global-queue":173,alias:177}],69:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("_kiq");var Facade=require("facade");var Identify=Facade.Identify;var bind=require("bind");var when=require("when");var Qualaroo=module.exports=integration("Qualaroo").assumesPageview().global("_kiq").option("customerId","").option("siteToken","").option("track",false).tag('<script src="//s3.amazonaws.com/ki.js/{{ customerId }}/{{ siteToken }}.js">');Qualaroo.prototype.initialize=function(page){window._kiq=window._kiq||[];var loaded=bind(this,this.loaded);var ready=this.ready;this.load(function(){when(loaded,ready)})};Qualaroo.prototype.loaded=function(){return!!(window._kiq&&window._kiq.push!==Array.prototype.push)};Qualaroo.prototype.identify=function(identify){var traits=identify.traits();var id=identify.userId();var email=identify.email();if(email)id=email;if(id)push("identify",id);if(traits)push("set",traits)};Qualaroo.prototype.track=function(track){if(!this.options.track)return;var event=track.event();var traits={};traits["Triggered: "+event]=true;this.identify(new Identify({traits:traits}))}},{"analytics.js-integration":88,"global-queue":173,facade:147,bind:101,when:146}],70:[function(require,module,exports){var push=require("global-queue")("_qevents",{wrap:false});var integration=require("analytics.js-integration");var useHttps=require("use-https");var is=require("is");var reduce=require("reduce");var Quantcast=module.exports=integration("Quantcast").assumesPageview().global("_qevents").global("__qc").option("pCode",null).option("advertise",false).tag("http",'<script src="http://edge.quantserve.com/quant.js">').tag("https",'<script src="https://secure.quantserve.com/quant.js">');Quantcast.prototype.initialize=function(page){window._qevents=window._qevents||[];var opts=this.options;var settings={qacct:opts.pCode};var user=this.analytics.user();if(user.id())settings.uid=user.id();if(page){settings.labels=this._labels("page",page.category(),page.name())}push(settings);var name=useHttps()?"https":"http";this.load(name,this.ready)};Quantcast.prototype.loaded=function(){return!!window.__qc};Quantcast.prototype.page=function(page){var category=page.category();var name=page.name();var customLabels=page.proxy("properties.label");var labels=this._labels("page",category,name,customLabels);var settings={event:"refresh",labels:labels,qacct:this.options.pCode};var user=this.analytics.user();if(user.id())settings.uid=user.id();push(settings)};Quantcast.prototype.identify=function(identify){var id=identify.userId();if(id){window._qevents[0]=window._qevents[0]||{};window._qevents[0].uid=id}};Quantcast.prototype.track=function(track){var name=track.event();var revenue=track.revenue();var orderId=track.orderId();var customLabels=track.proxy("properties.label");var labels=this._labels("event",name,customLabels);var settings={event:"click",labels:labels,qacct:this.options.pCode};var user=this.analytics.user();if(null!=revenue)settings.revenue=revenue+"";if(orderId)settings.orderid=orderId;if(user.id())settings.uid=user.id();push(settings)};Quantcast.prototype.completedOrder=function(track){var name=track.event();var revenue=track.total();var customLabels=track.proxy("properties.label");var labels=this._labels("event",name,customLabels);var category=track.category();if(this.options.advertise&&category){labels+=","+this._labels("pcat",category)}var settings={event:"refresh",labels:labels,revenue:revenue+"",orderid:track.orderId(),qacct:this.options.pCode};push(settings)};Quantcast.prototype._labels=function(type){var args=Array.prototype.slice.call(arguments,1);var advertise=this.options.advertise;if(advertise&&"page"==type)type="event";if(advertise)type="_fp."+type;var separator=advertise?" ":".";var ret=reduce(args,function(ret,arg){if(arg!=null){ret.push(String(arg).replace(/, /g,","))}return ret},[]).join(separator);return[type,ret].join(".")}},{"global-queue":173,"analytics.js-integration":88,"use-https":90,is:91,reduce:189}],189:[function(require,module,exports){module.exports=function(arr,fn,initial){var idx=0;var len=arr.length;var curr=arguments.length==3?initial:arr[idx++];while(idx<len){curr=fn.call(null,curr,arr[idx],++idx,arr)}return curr}},{}],71:[function(require,module,exports){var integration=require("analytics.js-integration");var extend=require("extend");var is=require("is");var RollbarIntegration=module.exports=integration("Rollbar").global("Rollbar").option("identify",true).option("accessToken","").option("environment","unknown").option("captureUncaught",true);RollbarIntegration.prototype.initialize=function(page){var _rollbarConfig=this.config={accessToken:this.options.accessToken,captureUncaught:this.options.captureUncaught,payload:{environment:this.options.environment}};(function(a,b){function c(b){this.shimId=++h,this.notifier=null,this.parentShim=b,this.logger=function(){},a.console&&void 0===a.console.shimId&&(this.logger=a.console.log)}function d(b,c,d){a._rollbarWrappedError&&(d[4]||(d[4]=a._rollbarWrappedError),d[5]||(d[5]=a._rollbarWrappedError._rollbarContext),a._rollbarWrappedError=null),b.uncaughtError.apply(b,d),c&&c.apply(a,d)}function e(b){var d=c;return g(function(){if(this.notifier)return this.notifier[b].apply(this.notifier,arguments);var c=this,e="scope"===b;e&&(c=new d(this));var f=Array.prototype.slice.call(arguments,0),g={shim:c,method:b,args:f,ts:new Date};return a._rollbarShimQueue.push(g),e?c:void 0})}function f(a,b){if(b.hasOwnProperty&&b.hasOwnProperty("addEventListener")){var c=b.addEventListener;b.addEventListener=function(b,d,e){c.call(this,b,a.wrap(d),e)};var d=b.removeEventListener;b.removeEventListener=function(a,b,c){d.call(this,a,b&&b._wrapped?b._wrapped:b,c)}}}function g(a,b){return b=b||this.logger,function(){try{return a.apply(this,arguments)}catch(c){b("Rollbar internal error:",c)}}}var h=0;c.init=function(a,b){var e=b.globalAlias||"Rollbar";if("object"==typeof a[e])return a[e];a._rollbarShimQueue=[],a._rollbarWrappedError=null,b=b||{};var h=new c;return g(function(){if(h.configure(b),b.captureUncaught){var c=a.onerror;a.onerror=function(){var a=Array.prototype.slice.call(arguments,0);d(h,c,a)};var g,i,j="EventTarget,Window,Node,ApplicationCache,AudioTrackList,ChannelMergerNode,CryptoOperation,EventSource,FileReader,HTMLUnknownElement,IDBDatabase,IDBRequest,IDBTransaction,KeyOperation,MediaController,MessagePort,ModalWindow,Notification,SVGElementInstance,Screen,TextTrack,TextTrackCue,TextTrackList,WebSocket,WebSocketWorker,Worker,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload".split(",");for(g=0;g<j.length;++g)i=j[g],a[i]&&a[i].prototype&&f(h,a[i].prototype)}return a[e]=h,h},h.logger)()},c.prototype.loadFull=function(a,b,c,d,e){var f=g(function(){var a=b.createElement("script"),e=b.getElementsByTagName("script")[0];a.src=d.rollbarJsUrl,a.async=!c,a.onload=h,e.parentNode.insertBefore(a,e)},this.logger),h=g(function(){var b;if(void 0===a._rollbarPayloadQueue){var c,d,f,g;for(b=new Error("rollbar.js did not load");c=a._rollbarShimQueue.shift();)for(f=c.args,g=0;g<f.length;++g)if(d=f[g],"function"==typeof d){d(b);break}}"function"==typeof e&&e(b)},this.logger);g(function(){c?f():a.addEventListener?a.addEventListener("load",f,!1):a.attachEvent("onload",f)},this.logger)()},c.prototype.wrap=function(b,c){try{var d;if(d="function"==typeof c?c:function(){return c||{}},"function"!=typeof b)return b;if(b._isWrap)return b;if(!b._wrapped){b._wrapped=function(){try{return b.apply(this,arguments)}catch(c){throw c._rollbarContext=d(),c._rollbarContext._wrappedSource=b.toString(),a._rollbarWrappedError=c,c}},b._wrapped._isWrap=!0;for(var e in b)b.hasOwnProperty(e)&&(b._wrapped[e]=b[e])}return b._wrapped}catch(f){return b}};for(var i="log,debug,info,warn,warning,error,critical,global,configure,scope,uncaughtError".split(","),j=0;j<i.length;++j)c.prototype[i[j]]=e(i[j]);var k="//d37gvrvc0wt4s1.cloudfront.net/js/v1.1/rollbar.min.js";_rollbarConfig.rollbarJsUrl=_rollbarConfig.rollbarJsUrl||k;var l=c.init(a,_rollbarConfig)})(window,document);this.load(this.ready)};RollbarIntegration.prototype.loaded=function(){return is.object(window.Rollbar)&&null==window.Rollbar.shimId};RollbarIntegration.prototype.load=function(callback){window.Rollbar.loadFull(window,document,true,this.config,callback)};RollbarIntegration.prototype.identify=function(identify){if(!this.options.identify)return;var uid=identify.userId();if(uid===null||uid===undefined)return;var rollbar=window.Rollbar;var person={id:uid};extend(person,identify.traits());rollbar.configure({payload:{person:person}})}},{"analytics.js-integration":88,extend:145,is:91}],72:[function(require,module,exports){var integration=require("analytics.js-integration");var SaaSquatch=module.exports=integration("SaaSquatch").option("tenantAlias","").option("referralImage","").global("_sqh").tag('<script src="//d2rcp9ak152ke1.cloudfront.net/assets/javascripts/squatch.min.js">');SaaSquatch.prototype.initialize=function(page){window._sqh=window._sqh||[];this.load(this.ready)};SaaSquatch.prototype.loaded=function(){return window._sqh&&window._sqh.push!=[].push};SaaSquatch.prototype.identify=function(identify){var sqh=window._sqh;var accountId=identify.proxy("traits.accountId");var image=identify.proxy("traits.referralImage")||this.options.referralImage;var opts=identify.options(this.name);var id=identify.userId();var email=identify.email();if(!(id||email))return;if(this.called)return;var init={tenant_alias:this.options.tenantAlias,first_name:identify.firstName(),last_name:identify.lastName(),user_image:identify.avatar(),email:email,user_id:id};if(accountId)init.account_id=accountId;if(opts.checksum)init.checksum=opts.checksum;if(image)init.fb_share_image=image;sqh.push(["init",init]);this.called=true;this.load()};SaaSquatch.prototype.group=function(group){var sqh=window._sqh;var props=group.properties();var id=group.groupId();var image=group.proxy("traits.referralImage")||this.options.referralImage;var opts=group.options(this.name);if(this.called)return;var init={tenant_alias:this.options.tenantAlias,account_id:id};if(opts.checksum)init.checksum=opts.checksum;if(image)init.fb_share_image=image;sqh.push(["init",init]);this.called=true;this.load()}},{"analytics.js-integration":88}],73:[function(require,module,exports){var integration=require("analytics.js-integration");var when=require("when");var SatisMeter=module.exports=integration("SatisMeter").global("satismeter").option("token","").tag('<script src="https://app.satismeter.com/satismeter.js">');SatisMeter.prototype.initialize=function(page){var self=this;this.load(function(){when(function(){return self.loaded()},self.ready)})};SatisMeter.prototype.loaded=function(){return!!window.satismeter};SatisMeter.prototype.identify=function(identify){var traits=identify.traits();traits.token=this.options.token;traits.user={id:identify.userId()};if(identify.name()){traits.user.name=identify.name()}if(identify.email()){traits.user.email=identify.email()}if(identify.created()){traits.user.signUpDate=identify.created().toISOString()}delete traits.id;delete traits.email;delete traits.name;delete traits.created;window.satismeter(traits)}},{"analytics.js-integration":88,when:146}],74:[function(require,module,exports){var integration=require("analytics.js-integration");var localstorage=require("store");var protocol=require("protocol");var utm=require("utm-params");var ads=require("ad-params");var send=require("send-json");var cookie=require("cookie");var clone=require("clone");var uuid=require("uuid");var top=require("top-domain");var extend=require("extend");var json=require("segmentio/json@1.0.0");var options={maxage:31536e6,secure:false,path:"/"};var Segment=exports=module.exports=integration("Segment.io").option("apiKey","");exports.storage=function(){return"file:"==protocol()||"chrome-extension:"==protocol()?localstorage:cookie};exports.global=window;Segment.prototype.initialize=function(page){var self=this;this.ready();this.analytics.on("invoke",function(msg){var action=msg.action();var listener="on"+msg.action();self.debug("%s %o",action,msg);if(self[listener])self[listener](msg);self.ready()})};Segment.prototype.loaded=function(){return true};Segment.prototype.onpage=function(page){this.send("/p",page.json())};Segment.prototype.onidentify=function(identify){this.send("/i",identify.json())};Segment.prototype.ongroup=function(group){this.send("/g",group.json())};Segment.prototype.ontrack=function(track){var json=track.json();delete json.traits;this.send("/t",json)};Segment.prototype.onalias=function(alias){var json=alias.json();var user=this.analytics.user();json.previousId=json.previousId||json.from||user.id()||user.anonymousId();json.userId=json.userId||json.to;delete json.from;delete json.to;this.send("/a",json)};Segment.prototype.normalize=function(msg){this.debug("normalize %o",msg);var user=this.analytics.user();var global=exports.global;var query=global.location.search;var ctx=msg.context=msg.context||msg.options||{};delete msg.options;msg.writeKey=this.options.apiKey;ctx.userAgent=navigator.userAgent;if(!ctx.library)ctx.library={name:"analytics.js",version:this.analytics.VERSION};if(query)ctx.campaign=utm(query);this.referrerId(query,ctx);msg.userId=msg.userId||user.id();msg.anonymousId=user.anonymousId();msg.messageId=uuid();msg.sentAt=new Date;this.debug("normalized %o",msg);return msg};Segment.prototype.send=function(path,msg,fn){var url=scheme()+"//api.segment.io/v1"+path;var headers={"Content-Type":"text/plain"};var fn=fn||noop;var self=this;msg=this.normalize(msg);send(url,msg,headers,function(err,res){self.debug("sent %O, received %O",msg,arguments);if(err)return fn(err);res.url=url;fn(null,res)})};Segment.prototype.cookie=function(name,val){var store=Segment.storage();if(arguments.length===1)return store(name);var global=exports.global;var href=global.location.href;var domain="."+top(href);if("."==domain)domain="";this.debug("store domain %s -> %s",href,domain);var opts=clone(options);opts.domain=domain;this.debug("store %s, %s, %o",name,val,opts);store(name,val,opts);if(store(name))return;delete opts.domain;this.debug("fallback store %s, %s, %o",name,val,opts);store(name,val,opts)};Segment.prototype.referrerId=function(query,ctx){var stored=this.cookie("s:context.referrer");var ad;if(stored)stored=json.parse(stored);if(query)ad=ads(query);ad=ad||stored;if(!ad)return;ctx.referrer=extend(ctx.referrer||{},ad);this.cookie("s:context.referrer",json.stringify(ad))};function scheme(){return"http:"==protocol()?"http:":"https:"}function noop(){}},{"analytics.js-integration":88,store:190,protocol:191,"utm-params":138,"ad-params":192,"send-json":193,cookie:194,clone:95,uuid:195,"top-domain":139,extend:145,"segmentio/json@1.0.0":179}],190:[function(require,module,exports){var unserialize=require("unserialize");var each=require("each");var storage;try{storage=window.localStorage}catch(e){storage=null}module.exports=store;function store(key,value){var length=arguments.length;if(0==length)return all();if(2<=length)return set(key,value);if(1!=length)return;if(null==key)return storage.clear();if("string"==typeof key)return get(key);if("object"==typeof key)return each(key,set)}store.supported=!!storage;function set(key,val){return null==val?storage.removeItem(key):storage.setItem(key,JSON.stringify(val))}function get(key){return unserialize(storage.getItem(key))}function all(){var len=storage.length;var ret={};var key;while(0<=--len){key=storage.key(len);ret[key]=get(key)}return ret}},{unserialize:196,each:112}],196:[function(require,module,exports){module.exports=function(val){try{return JSON.parse(val)}catch(e){return val||undefined}}},{}],191:[function(require,module,exports){var define=Object.defineProperty;var initialProtocol=window.location.protocol;var mockedProtocol;module.exports=function(protocol){if(arguments.length===0)return get();else return set(protocol)};module.exports.http=function(){set("http:")};module.exports.https=function(){set("https:")};module.exports.reset=function(){set(initialProtocol)};function get(){return mockedProtocol||window.location.protocol}function set(protocol){try{define(window.location,"protocol",{get:function(){return protocol}})}catch(err){mockedProtocol=protocol}}},{}],192:[function(require,module,exports){var parse=require("querystring").parse;module.exports=ads;var QUERYIDS={btid:"dataxu",urid:"millennial-media"};function ads(query){var params=parse(query);for(var key in params){for(var id in QUERYIDS){if(key===id){return{id:params[key],type:QUERYIDS[id]}}}}}},{querystring:140}],193:[function(require,module,exports){var encode=require("base64-encode");var cors=require("has-cors");var jsonp=require("jsonp");var JSON=require("json");exports=module.exports=cors?json:base64;exports.callback="callback";exports.prefix="data";exports.json=json;exports.base64=base64;exports.type=cors?"xhr":"jsonp";function json(url,obj,headers,fn){if(3==arguments.length)fn=headers,headers={};var req=new XMLHttpRequest;req.onerror=fn;req.onreadystatechange=done;req.open("POST",url,true);for(var k in headers)req.setRequestHeader(k,headers[k]);req.send(JSON.stringify(obj));function done(){if(4==req.readyState)return fn(null,req)}}function base64(url,obj,_,fn){if(3==arguments.length)fn=_;var prefix=exports.prefix;obj=encode(JSON.stringify(obj));obj=encodeURIComponent(obj);url+="?"+prefix+"="+obj;jsonp(url,{param:exports.callback},function(err,obj){if(err)return fn(err);fn(null,{url:url,body:obj})})}},{"base64-encode":197,"has-cors":198,jsonp:199,json:179}],197:[function(require,module,exports){var utf8Encode=require("utf8-encode");var keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";module.exports=encode;function encode(input){var output="";var chr1,chr2,chr3,enc1,enc2,enc3,enc4;var i=0;input=utf8Encode(input);while(i<input.length){chr1=input.charCodeAt(i++);chr2=input.charCodeAt(i++);chr3=input.charCodeAt(i++);enc1=chr1>>2;enc2=(chr1&3)<<4|chr2>>4;enc3=(chr2&15)<<2|chr3>>6;enc4=chr3&63;if(isNaN(chr2)){enc3=enc4=64}else if(isNaN(chr3)){enc4=64}output=output+keyStr.charAt(enc1)+keyStr.charAt(enc2)+keyStr.charAt(enc3)+keyStr.charAt(enc4)}return output}},{"utf8-encode":200}],200:[function(require,module,exports){module.exports=encode;function encode(string){string=string.replace(/\r\n/g,"\n");var utftext="";for(var n=0;n<string.length;n++){var c=string.charCodeAt(n);if(c<128){utftext+=String.fromCharCode(c)}else if(c>127&&c<2048){utftext+=String.fromCharCode(c>>6|192);utftext+=String.fromCharCode(c&63|128)}else{utftext+=String.fromCharCode(c>>12|224);utftext+=String.fromCharCode(c>>6&63|128);utftext+=String.fromCharCode(c&63|128)}}return utftext}},{}],198:[function(require,module,exports){try{module.exports=typeof XMLHttpRequest!=="undefined"&&"withCredentials"in new XMLHttpRequest}catch(err){module.exports=false}},{}],199:[function(require,module,exports){var debug=require("debug")("jsonp");module.exports=jsonp;var count=0;function noop(){}function jsonp(url,opts,fn){if("function"==typeof opts){fn=opts;opts={}}if(!opts)opts={};var prefix=opts.prefix||"__jp";var param=opts.param||"callback";var timeout=null!=opts.timeout?opts.timeout:6e4;var enc=encodeURIComponent;var target=document.getElementsByTagName("script")[0]||document.head;var script;var timer;var id=prefix+count++;if(timeout){timer=setTimeout(function(){cleanup(); +if(fn)fn(new Error("Timeout"))},timeout)}function cleanup(){script.parentNode.removeChild(script);window[id]=noop}window[id]=function(data){debug("jsonp got",data);if(timer)clearTimeout(timer);cleanup();if(fn)fn(null,data)};url+=(~url.indexOf("?")?"&":"?")+param+"="+enc(id);url=url.replace("?&","?");debug('jsonp req "%s"',url);script=document.createElement("script");script.src=url;target.parentNode.insertBefore(script,target)}},{debug:201}],201:[function(require,module,exports){if("undefined"==typeof window){module.exports=require("./lib/debug")}else{module.exports=require("./debug")}},{"./lib/debug":202,"./debug":203}],202:[function(require,module,exports){var tty=require("tty");module.exports=debug;var names=[],skips=[];(process.env.DEBUG||"").split(/[\s,]+/).forEach(function(name){name=name.replace("*",".*?");if(name[0]==="-"){skips.push(new RegExp("^"+name.substr(1)+"$"))}else{names.push(new RegExp("^"+name+"$"))}});var colors=[6,2,3,4,5,1];var prev={};var prevColor=0;var isatty=tty.isatty(2);function color(){return colors[prevColor++%colors.length]}function humanize(ms){var sec=1e3,min=60*1e3,hour=60*min;if(ms>=hour)return(ms/hour).toFixed(1)+"h";if(ms>=min)return(ms/min).toFixed(1)+"m";if(ms>=sec)return(ms/sec|0)+"s";return ms+"ms"}function debug(name){function disabled(){}disabled.enabled=false;var match=skips.some(function(re){return re.test(name)});if(match)return disabled;match=names.some(function(re){return re.test(name)});if(!match)return disabled;var c=color();function colored(fmt){fmt=coerce(fmt);var curr=new Date;var ms=curr-(prev[name]||curr);prev[name]=curr;fmt=" [9"+c+"m"+name+" "+"[3"+c+"m"+fmt+"[3"+c+"m"+" +"+humanize(ms)+"";console.error.apply(this,arguments)}function plain(fmt){fmt=coerce(fmt);fmt=(new Date).toUTCString()+" "+name+" "+fmt;console.error.apply(this,arguments)}colored.enabled=plain.enabled=true;return isatty||process.env.DEBUG_COLORS?colored:plain}function coerce(val){if(val instanceof Error)return val.stack||val.message;return val}},{}],203:[function(require,module,exports){module.exports=debug;function debug(name){if(!debug.enabled(name))return function(){};return function(fmt){fmt=coerce(fmt);var curr=new Date;var ms=curr-(debug[name]||curr);debug[name]=curr;fmt=name+" "+fmt+" +"+debug.humanize(ms);window.console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}}debug.names=[];debug.skips=[];debug.enable=function(name){try{localStorage.debug=name}catch(e){}var split=(name||"").split(/[\s,]+/),len=split.length;for(var i=0;i<len;i++){name=split[i].replace("*",".*?");if(name[0]==="-"){debug.skips.push(new RegExp("^"+name.substr(1)+"$"))}else{debug.names.push(new RegExp("^"+name+"$"))}}};debug.disable=function(){debug.enable("")};debug.humanize=function(ms){var sec=1e3,min=60*1e3,hour=60*min;if(ms>=hour)return(ms/hour).toFixed(1)+"h";if(ms>=min)return(ms/min).toFixed(1)+"m";if(ms>=sec)return(ms/sec|0)+"s";return ms+"ms"};debug.enabled=function(name){for(var i=0,len=debug.skips.length;i<len;i++){if(debug.skips[i].test(name)){return false}}for(var i=0,len=debug.names.length;i<len;i++){if(debug.names[i].test(name)){return true}}return false};function coerce(val){if(val instanceof Error)return val.stack||val.message;return val}try{if(window.localStorage)debug.enable(localStorage.debug)}catch(e){}},{}],194:[function(require,module,exports){var debug=require("debug")("cookie");module.exports=function(name,value,options){switch(arguments.length){case 3:case 2:return set(name,value,options);case 1:return get(name);default:return all()}};function set(name,value,options){options=options||{};var str=encode(name)+"="+encode(value);if(null==value)options.maxage=-1;if(options.maxage){options.expires=new Date(+new Date+options.maxage)}if(options.path)str+="; path="+options.path;if(options.domain)str+="; domain="+options.domain;if(options.expires)str+="; expires="+options.expires.toUTCString();if(options.secure)str+="; secure";document.cookie=str}function all(){return parse(document.cookie)}function get(name){return all()[name]}function parse(str){var obj={};var pairs=str.split(/ *; */);var pair;if(""==pairs[0])return obj;for(var i=0;i<pairs.length;++i){pair=pairs[i].split("=");obj[decode(pair[0])]=decode(pair[1])}return obj}function encode(value){try{return encodeURIComponent(value)}catch(e){debug("error `encode(%o)` - %o",value,e)}}function decode(value){try{return decodeURIComponent(value)}catch(e){debug("error `decode(%o)` - %o",value,e)}}},{debug:201}],195:[function(require,module,exports){module.exports=function uuid(a){return a?(a^Math.random()*16>>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,uuid)}},{}],75:[function(require,module,exports){var integration=require("analytics.js-integration");var is=require("is");var Sentry=module.exports=integration("Sentry").global("Raven").option("config","").tag('<script src="//cdn.ravenjs.com/1.1.16/native/raven.min.js">');Sentry.prototype.initialize=function(){var dsn=this.options.config;window.RavenConfig={dsn:dsn};this.load(this.ready)};Sentry.prototype.loaded=function(){return is.object(window.Raven)};Sentry.prototype.identify=function(identify){window.Raven.setUser(identify.traits())}},{"analytics.js-integration":88,is:91}],76:[function(require,module,exports){var integration=require("analytics.js-integration");var is=require("is");var SnapEngage=module.exports=integration("SnapEngage").assumesPageview().global("SnapABug").option("apiKey","").tag('<script src="//commondatastorage.googleapis.com/code.snapengage.com/js/{{ apiKey }}.js">');SnapEngage.prototype.initialize=function(page){this.load(this.ready)};SnapEngage.prototype.loaded=function(){return is.object(window.SnapABug)};SnapEngage.prototype.identify=function(identify){var email=identify.email();if(!email)return;window.SnapABug.setUserEmail(email)}},{"analytics.js-integration":88,is:91}],77:[function(require,module,exports){var integration=require("analytics.js-integration");var bind=require("bind");var when=require("when");var Spinnakr=module.exports=integration("Spinnakr").assumesPageview().global("_spinnakr_site_id").global("_spinnakr").option("siteId","").tag('<script src="//d3ojzyhbolvoi5.cloudfront.net/js/so.js">');Spinnakr.prototype.initialize=function(page){window._spinnakr_site_id=this.options.siteId;var loaded=bind(this,this.loaded);var ready=this.ready;this.load(function(){when(loaded,ready)})};Spinnakr.prototype.loaded=function(){return!!window._spinnakr}},{"analytics.js-integration":88,bind:101,when:146}],78:[function(require,module,exports){var integration=require("analytics.js-integration");var slug=require("slug");var push=require("global-queue")("_tsq");var Tapstream=module.exports=integration("Tapstream").assumesPageview().global("_tsq").option("accountName","").option("trackAllPages",true).option("trackNamedPages",true).option("trackCategorizedPages",true).tag('<script src="//cdn.tapstream.com/static/js/tapstream.js">');Tapstream.prototype.initialize=function(page){window._tsq=window._tsq||[];push("setAccountName",this.options.accountName);this.load(this.ready)};Tapstream.prototype.loaded=function(){return!!(window._tsq&&window._tsq.push!==Array.prototype.push)};Tapstream.prototype.page=function(page){var category=page.category();var opts=this.options;var name=page.fullName();if(opts.trackAllPages){this.track(page.track())}if(name&&opts.trackNamedPages){this.track(page.track(name))}if(category&&opts.trackCategorizedPages){this.track(page.track(category))}};Tapstream.prototype.track=function(track){var props=track.properties();push("fireHit",slug(track.event()),[props.url])}},{"analytics.js-integration":88,slug:99,"global-queue":173}],79:[function(require,module,exports){var integration=require("analytics.js-integration");var alias=require("alias");var clone=require("clone");var Trakio=module.exports=integration("trak.io").assumesPageview().global("trak").option("token","").option("trackNamedPages",true).option("trackCategorizedPages",true).tag('<script src="//d29p64779x43zo.cloudfront.net/v1/trak.io.min.js">');var optionsAliases={initialPageview:"auto_track_page_view"};Trakio.prototype.initialize=function(page){var options=this.options;window.trak=window.trak||[];window.trak.io=window.trak.io||{};window.trak.push=window.trak.push||function(){};window.trak.io.load=window.trak.io.load||function(e){var r=function(e){return function(){window.trak.push([e].concat(Array.prototype.slice.call(arguments,0)))}},i=["initialize","identify","track","alias","channel","source","host","protocol","page_view"];for(var s=0;s<i.length;s++)window.trak.io[i[s]]=r(i[s]);window.trak.io.initialize.apply(window.trak.io,arguments)};window.trak.io.load(options.token,alias(options,optionsAliases));this.load(this.ready)};Trakio.prototype.loaded=function(){return!!(window.trak&&window.trak.loaded)};Trakio.prototype.page=function(page){var category=page.category();var props=page.properties();var name=page.fullName();window.trak.io.page_view(props.path,name||props.title);if(name&&this.options.trackNamedPages){this.track(page.track(name))}if(category&&this.options.trackCategorizedPages){this.track(page.track(category))}};var traitAliases={avatar:"avatar_url",firstName:"first_name",lastName:"last_name"};Trakio.prototype.identify=function(identify){var traits=identify.traits(traitAliases);var id=identify.userId();if(id){window.trak.io.identify(id,traits)}else{window.trak.io.identify(traits)}};Trakio.prototype.track=function(track){window.trak.io.track(track.event(),track.properties())};Trakio.prototype.alias=function(alias){if(!window.trak.io.distinct_id)return;var from=alias.from();var to=alias.to();if(to===window.trak.io.distinct_id())return;if(from){window.trak.io.alias(from,to)}else{window.trak.io.alias(to)}}},{"analytics.js-integration":88,alias:177,clone:95}],80:[function(require,module,exports){var integration=require("analytics.js-integration");var each=require("each");var has=Object.prototype.hasOwnProperty;var TwitterAds=module.exports=integration("Twitter Ads").option("page","").tag('<img src="//analytics.twitter.com/i/adsct?txn_id={{ pixelId }}&p_id=Twitter"/>').mapping("events");TwitterAds.prototype.initialize=function(){this.ready()};TwitterAds.prototype.page=function(page){if(this.options.page){this.load({pixelId:this.options.page})}};TwitterAds.prototype.track=function(track){var events=this.events(track.event());var self=this;each(events,function(pixelId){self.load({pixelId:pixelId})})}},{"analytics.js-integration":88,each:4}],81:[function(require,module,exports){var integration=require("analytics.js-integration");var Identify=require("facade").Identify;var clone=require("clone");var Userlike=module.exports=integration("Userlike").assumesPageview().global("userlikeConfig").global("userlikeData").option("secretKey","").tag('<script src="//userlike-cdn-widgets.s3-eu-west-1.amazonaws.com/{{ secretKey }}.js">');Userlike.prototype.initialize=function(page){var self=this;var user=this.analytics.user();var identify=new Identify({userId:user.id(),traits:user.traits()});segment_base_info=clone(this.options);segment_base_info.visitor={name:identify.name(),email:identify.email()};if(!window.userlikeData)window.userlikeData={custom:{}};window.userlikeData.custom.segmentio=segment_base_info;this.load(function(){self.ready()})};Userlike.prototype.loaded=function(){return!!(window.userlikeConfig&&window.userlikeData)}},{"analytics.js-integration":88,facade:147,clone:95}],82:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("UserVoice");var convertDates=require("convert-dates");var unix=require("to-unix-timestamp");var alias=require("alias");var clone=require("clone");var UserVoice=module.exports=integration("UserVoice").assumesPageview().global("UserVoice").global("showClassicWidget").option("apiKey","").option("classic",false).option("forumId",null).option("showWidget",true).option("mode","contact").option("accentColor","#448dd6").option("screenshotEnabled",true).option("smartvote",true).option("trigger",null).option("triggerPosition","bottom-right").option("triggerColor","#ffffff").option("triggerBackgroundColor","rgba(46, 49, 51, 0.6)").option("classicMode","full").option("primaryColor","#cc6d00").option("linkColor","#007dbf").option("defaultMode","support").option("tabLabel","Feedback & Support").option("tabColor","#cc6d00").option("tabPosition","middle-right").option("tabInverted",false).option("customTicketFields",{}).tag('<script src="//widget.uservoice.com/{{ apiKey }}.js">');UserVoice.on("construct",function(integration){if(!integration.options.classic)return;integration.group=undefined;integration.identify=integration.identifyClassic;integration.initialize=integration.initializeClassic});UserVoice.prototype.initialize=function(page){var options=this.options;var opts=formatOptions(options);push("set",opts);push("autoprompt",{});if(options.showWidget){options.trigger?push("addTrigger",options.trigger,opts):push("addTrigger",opts)}this.load(this.ready)};UserVoice.prototype.loaded=function(){return!!(window.UserVoice&&window.UserVoice.push!==Array.prototype.push)};UserVoice.prototype.identify=function(identify){var traits=identify.traits({created:"created_at"});traits=convertDates(traits,unix);push("identify",traits)};UserVoice.prototype.group=function(group){var traits=group.traits({created:"created_at"});traits=convertDates(traits,unix);push("identify",{account:traits})};UserVoice.prototype.initializeClassic=function(){var options=this.options;window.showClassicWidget=showClassicWidget;if(options.showWidget)showClassicWidget("showTab",formatClassicOptions(options));this.load(this.ready)};UserVoice.prototype.identifyClassic=function(identify){push("setCustomFields",identify.traits())};function formatOptions(options){return alias(options,{forumId:"forum_id",accentColor:"accent_color",smartvote:"smartvote_enabled",triggerColor:"trigger_color",triggerBackgroundColor:"trigger_background_color",triggerPosition:"trigger_position",screenshotEnabled:"screenshot_enabled",customTicketFields:"ticket_custom_fields"})}function formatClassicOptions(options){return alias(options,{forumId:"forum_id",classicMode:"mode",primaryColor:"primary_color",tabPosition:"tab_position",tabColor:"tab_color",linkColor:"link_color",defaultMode:"default_mode",tabLabel:"tab_label",tabInverted:"tab_inverted"})}function showClassicWidget(type,options){type=type||"showLightbox";push(type,"classic_widget",options)}},{"analytics.js-integration":88,"global-queue":173,"convert-dates":178,"to-unix-timestamp":204,alias:177,clone:95}],204:[function(require,module,exports){module.exports=toUnixTimestamp;function toUnixTimestamp(date){return Math.floor(date.getTime()/1e3)}},{}],83:[function(require,module,exports){var integration=require("analytics.js-integration");var push=require("global-queue")("_veroq");var cookie=require("component/cookie");var objCase=require("obj-case");var Vero=module.exports=integration("Vero").global("_veroq").option("apiKey","").tag('<script src="//d3qxef4rp70elm.cloudfront.net/m.js">');Vero.prototype.initialize=function(page){if(!cookie("__veroc4"))cookie("__veroc4","[]");push("init",{api_key:this.options.apiKey});this.load(this.ready)};Vero.prototype.loaded=function(){return!!(window._veroq&&window._veroq.push!==Array.prototype.push)};Vero.prototype.page=function(page){push("trackPageview")};Vero.prototype.identify=function(identify){var traits=identify.traits();var email=identify.email();var id=identify.userId();if(!id||!email)return;push("user",traits)};Vero.prototype.track=function(track){var regex=/[uU]nsubscribe/;if(track.event().match(regex)){push("unsubscribe",{id:track.properties().id})}else{push("track",track.event(),track.properties())}};Vero.prototype.alias=function(alias){var to=alias.to();if(alias.from()){push("reidentify",to,alias.from())}else{push("reidentify",to)}}},{"analytics.js-integration":88,"global-queue":173,"component/cookie":194,"obj-case":92}],84:[function(require,module,exports){var integration=require("analytics.js-integration");var tick=require("next-tick");var each=require("each");var VWO=module.exports=integration("Visual Website Optimizer").option("replay",true);VWO.prototype.initialize=function(){if(this.options.replay)this.replay();this.ready()};VWO.prototype.replay=function(){var analytics=this.analytics;tick(function(){experiments(function(err,traits){if(traits)analytics.identify(traits)})})};function experiments(fn){enqueue(function(){var data={};var ids=window._vwo_exp_ids;if(!ids)return fn();each(ids,function(id){var name=variation(id);if(name)data["Experiment: "+id]=name});fn(null,data)})}function enqueue(fn){window._vis_opt_queue=window._vis_opt_queue||[];window._vis_opt_queue.push(fn)}function variation(id){var experiments=window._vwo_exp;if(!experiments)return null;var experiment=experiments[id];var variationId=experiment.combination_chosen;return variationId?experiment.comb_n[variationId]:null}},{"analytics.js-integration":88,"next-tick":103,each:4}],85:[function(require,module,exports){var integration=require("analytics.js-integration");var useHttps=require("use-https");var WebEngage=module.exports=integration("WebEngage").assumesPageview().global("_weq").global("webengage").option("widgetVersion","4.0").option("licenseCode","").tag("http",'<script src="http://cdn.widgets.webengage.com/js/widget/webengage-min-v-4.0.js">').tag("https",'<script src="https://ssl.widgets.webengage.com/js/widget/webengage-min-v-4.0.js">');WebEngage.prototype.initialize=function(page){var _weq=window._weq=window._weq||{};_weq["webengage.licenseCode"]=this.options.licenseCode;_weq["webengage.widgetVersion"]=this.options.widgetVersion;var name=useHttps()?"https":"http";this.load(name,this.ready)};WebEngage.prototype.loaded=function(){return!!window.webengage}},{"analytics.js-integration":88,"use-https":90}],86:[function(require,module,exports){var integration=require("analytics.js-integration");var snake=require("to-snake-case");var isEmail=require("is-email");var extend=require("extend");var each=require("each");var type=require("type");var Woopra=module.exports=integration("Woopra").global("woopra").option("domain","").option("cookieName","wooTracker").option("cookieDomain",null).option("cookiePath","/").option("ping",true).option("pingInterval",12e3).option("idleTimeout",3e5).option("downloadTracking",true).option("outgoingTracking",true).option("outgoingIgnoreSubdomain",true).option("downloadPause",200).option("outgoingPause",400).option("ignoreQueryUrl",true).option("hideCampaign",false).tag('<script src="//static.woopra.com/js/w.js">');Woopra.prototype.initialize=function(page){(function(){var i,s,z,w=window,d=document,a=arguments,q="script",f=["config","track","identify","visit","push","call"],c=function(){var i,self=this;self._e=[];for(i=0;i<f.length;i++){(function(f){self[f]=function(){self._e.push([f].concat(Array.prototype.slice.call(arguments,0)));return self}})(f[i])}};w._w=w._w||{};for(i=0;i<a.length;i++){w._w[a[i]]=w[a[i]]=w[a[i]]||new c}})("woopra");this.load(this.ready);each(this.options,function(key,value){key=snake(key);if(null==value)return;if(""===value)return;window.woopra.config(key,value)})};Woopra.prototype.loaded=function(){return!!(window.woopra&&window.woopra.loaded)};Woopra.prototype.page=function(page){var props=page.properties();var name=page.fullName();if(name)props.title=name;window.woopra.track("pv",props)};Woopra.prototype.identify=function(identify){var traits=identify.traits();if(identify.name())traits.name=identify.name();window.woopra.identify(traits).push()};Woopra.prototype.track=function(track){window.woopra.track(track.event(),track.properties())}},{"analytics.js-integration":88,"to-snake-case":89,"is-email":169,extend:145,each:4,type:113}],87:[function(require,module,exports){var integration=require("analytics.js-integration");var tick=require("next-tick");var bind=require("bind");var when=require("when");var Yandex=module.exports=integration("Yandex Metrica").assumesPageview().global("yandex_metrika_callbacks").global("Ya").option("counterId",null).option("clickmap",false).option("webvisor",false).tag('<script src="//mc.yandex.ru/metrika/watch.js">');Yandex.prototype.initialize=function(page){var id=this.options.counterId;var clickmap=this.options.clickmap;var webvisor=this.options.webvisor;push(function(){window["yaCounter"+id]=new window.Ya.Metrika({id:id,clickmap:clickmap,webvisor:webvisor})});var loaded=bind(this,this.loaded);var ready=this.ready;this.load(function(){when(loaded,function(){tick(ready)})})};Yandex.prototype.loaded=function(){return!!(window.Ya&&window.Ya.Metrika)};function push(callback){window.yandex_metrika_callbacks=window.yandex_metrika_callbacks||[];window.yandex_metrika_callbacks.push(callback)}},{"analytics.js-integration":88,"next-tick":103,bind:101,when:146}],3:[function(require,module,exports){var _analytics=window.analytics;var after=require("after");var bind=require("bind");var callback=require("callback");var clone=require("clone");var cookie=require("./cookie");var debug=require("debug");var defaults=require("defaults");var each=require("each");var Emitter=require("emitter");var group=require("./group");var is=require("is");var isEmail=require("is-email");var isMeta=require("is-meta");var newDate=require("new-date");var on=require("event").bind;var pageDefaults=require("./pageDefaults");var pick=require("pick");var prevent=require("prevent");var querystring=require("querystring");var normalize=require("./normalize");var size=require("object").length;var keys=require("object").keys;var memory=require("./memory");var store=require("./store");var user=require("./user");var Facade=require("facade");var Identify=Facade.Identify;var Group=Facade.Group;var Alias=Facade.Alias;var Track=Facade.Track;var Page=Facade.Page;exports=module.exports=Analytics;exports.cookie=cookie;exports.store=store;exports.memory=memory;function Analytics(){this._options({});this.Integrations={};this._integrations={};this._readied=false;this._timeout=300;this._user=user;this.log=debug("analytics.js");bind.all(this);var self=this;this.on("initialize",function(settings,options){if(options.initialPageview)self.page();self._parseQuery()})}Emitter(Analytics.prototype);Analytics.prototype.use=function(plugin){plugin(this);return this};Analytics.prototype.addIntegration=function(Integration){var name=Integration.prototype.name;if(!name)throw new TypeError("attempted to add an invalid integration");this.Integrations[name]=Integration;return this};Analytics.prototype.init=Analytics.prototype.initialize=function(settings,options){settings=settings||{};options=options||{};this._options(options);this._readied=false;var self=this;each(settings,function(name){var Integration=self.Integrations[name];if(!Integration)delete settings[name]});each(settings,function(name,opts){var Integration=self.Integrations[name];var integration=new Integration(clone(opts));self.log("initialize %o - %o",name,opts);self.add(integration)});var integrations=this._integrations;user.load();group.load();var ready=after(size(integrations),function(){self._readied=true;self.emit("ready")});each(integrations,function(name,integration){if(options.initialPageview&&integration.options.initialPageview===false){integration.page=after(2,integration.page)}integration.analytics=self;integration.once("ready",ready);integration.initialize()});this.initialized=true;this.emit("initialize",settings,options);return this};Analytics.prototype.setAnonymousId=function(id){this.user().anonymousId(id);return this};Analytics.prototype.add=function(integration){this._integrations[integration.name]=integration;return this};Analytics.prototype.identify=function(id,traits,options,fn){if(is.fn(options))fn=options,options=null;if(is.fn(traits))fn=traits,options=null,traits=null;if(is.object(id))options=traits,traits=id,id=user.id();user.identify(id,traits);var msg=this.normalize({options:options,traits:user.traits(),userId:user.id()});this._invoke("identify",new Identify(msg));this.emit("identify",id,traits,options);this._callback(fn);return this};Analytics.prototype.user=function(){return user};Analytics.prototype.group=function(id,traits,options,fn){if(0===arguments.length)return group;if(is.fn(options))fn=options,options=null;if(is.fn(traits))fn=traits,options=null,traits=null;if(is.object(id))options=traits,traits=id,id=group.id();group.identify(id,traits);var msg=this.normalize({options:options,traits:group.traits(),groupId:group.id()});this._invoke("group",new Group(msg));this.emit("group",id,traits,options);this._callback(fn);return this};Analytics.prototype.track=function(event,properties,options,fn){if(is.fn(options))fn=options,options=null;if(is.fn(properties))fn=properties,options=null,properties=null;var plan=this.options.plan||{};var events=plan.track||{};var msg=this.normalize({properties:properties,options:options,event:event});if(plan=events[event]){this.log("plan %o - %o",event,plan);if(false==plan.enabled)return this._callback(fn);defaults(msg.integrations,plan.integrations||{})}this._invoke("track",new Track(msg));this.emit("track",event,properties,options);this._callback(fn);return this};Analytics.prototype.trackClick=Analytics.prototype.trackLink=function(links,event,properties){if(!links)return this;if(is.element(links))links=[links];var self=this;each(links,function(el){if(!is.element(el))throw new TypeError("Must pass HTMLElement to `analytics.trackLink`.");on(el,"click",function(e){var ev=is.fn(event)?event(el):event;var props=is.fn(properties)?properties(el):properties;var href=el.getAttribute("href")||el.getAttributeNS("http://www.w3.org/1999/xlink","href")||el.getAttribute("xlink:href");self.track(ev,props);if(href&&el.target!=="_blank"&&!isMeta(e)){prevent(e);self._callback(function(){window.location.href=href})}})});return this};Analytics.prototype.trackSubmit=Analytics.prototype.trackForm=function(forms,event,properties){if(!forms)return this;if(is.element(forms))forms=[forms];var self=this;each(forms,function(el){if(!is.element(el))throw new TypeError("Must pass HTMLElement to `analytics.trackForm`.");function handler(e){prevent(e);var ev=is.fn(event)?event(el):event;var props=is.fn(properties)?properties(el):properties;self.track(ev,props);self._callback(function(){el.submit()})}var $=window.jQuery||window.Zepto;if($){$(el).submit(handler)}else{on(el,"submit",handler)}});return this};Analytics.prototype.page=function(category,name,properties,options,fn){if(is.fn(options))fn=options,options=null;if(is.fn(properties))fn=properties,options=properties=null;if(is.fn(name))fn=name,options=properties=name=null;if(is.object(category))options=name,properties=category,name=category=null;if(is.object(name))options=properties,properties=name,name=null;if(is.string(category)&&!is.string(name))name=category,category=null;properties=clone(properties)||{};if(name)properties.name=name;if(category)properties.category=category;var defs=pageDefaults();defaults(properties,defs);var overrides=pick(keys(defs),properties);if(!is.empty(overrides)){options=options||{};options.context=options.context||{};options.context.page=overrides}var msg=this.normalize({properties:properties,category:category,options:options,name:name});this._invoke("page",new Page(msg));this.emit("page",category,name,properties,options);this._callback(fn);return this};Analytics.prototype.pageview=function(url,options){var properties={};if(url)properties.path=url;this.page(properties);return this};Analytics.prototype.alias=function(to,from,options,fn){if(is.fn(options))fn=options,options=null;if(is.fn(from))fn=from,options=null,from=null;if(is.object(from))options=from,from=null;var msg=this.normalize({options:options,previousId:from,userId:to});this._invoke("alias",new Alias(msg));this.emit("alias",to,from,options);this._callback(fn);return this};Analytics.prototype.ready=function(fn){if(!is.fn(fn))return this;this._readied?callback.async(fn):this.once("ready",fn);return this};Analytics.prototype.timeout=function(timeout){this._timeout=timeout};Analytics.prototype.debug=function(str){if(0==arguments.length||str){debug.enable("analytics:"+(str||"*"))}else{debug.disable()}};Analytics.prototype._options=function(options){options=options||{};this.options=options;cookie.options(options.cookie);store.options(options.localStorage);user.options(options.user);group.options(options.group);return this};Analytics.prototype._callback=function(fn){callback.async(fn,this._timeout);return this};Analytics.prototype._invoke=function(method,facade){var options=facade.options();this.emit("invoke",facade);each(this._integrations,function(name,integration){if(!facade.enabled(name))return;integration.invoke.call(integration,method,facade)});return this};Analytics.prototype.push=function(args){var method=args.shift();if(!this[method])return;this[method].apply(this,args)};Analytics.prototype.reset=function(){this.user().logout();this.group().logout()};Analytics.prototype._parseQuery=function(){var q=querystring.parse(window.location.search);if(q.ajs_uid)this.identify(q.ajs_uid);if(q.ajs_event)this.track(q.ajs_event);if(q.ajs_aid)user.anonymousId(q.ajs_aid);return this};Analytics.prototype.normalize=function(msg){msg=normalize(msg,keys(this._integrations));if(msg.anonymousId)user.anonymousId(msg.anonymousId);msg.anonymousId=user.anonymousId();msg.context.page=defaults(msg.context.page||{},pageDefaults());return msg};Analytics.prototype.noConflict=function(){window.analytics=_analytics;return this}},{after:111,bind:205,callback:94,clone:95,"./cookie":206,debug:201,defaults:97,each:4,emitter:110,"./group":207,is:91,"is-email":169,"is-meta":208,"new-date":161,event:209,"./pageDefaults":210,pick:211,prevent:212,querystring:213,"./normalize":214,object:181,"./memory":215,"./store":216,"./user":217,facade:147}],205:[function(require,module,exports){try{var bind=require("bind")}catch(e){var bind=require("bind-component")}var bindAll=require("bind-all");module.exports=exports=bind;exports.all=bindAll;exports.methods=bindMethods;function bindMethods(obj,methods){methods=[].slice.call(arguments,1);for(var i=0,method;method=methods[i];i++){obj[method]=bind(obj,obj[method])}return obj}},{bind:101,"bind-all":102}],206:[function(require,module,exports){var debug=require("debug")("analytics.js:cookie");var bind=require("bind");var cookie=require("cookie");var clone=require("clone");var defaults=require("defaults");var json=require("json");var topDomain=require("top-domain");function Cookie(options){this.options(options)}Cookie.prototype.options=function(options){if(arguments.length===0)return this._options;options=options||{};var domain="."+topDomain(window.location.href);this._options=defaults(options,{maxage:31536e6,path:"/",domain:domain});this.set("ajs:test",true);if(!this.get("ajs:test")){debug("fallback to domain=null");this._options.domain=null}this.remove("ajs:test")};Cookie.prototype.set=function(key,value){try{value=json.stringify(value);cookie(key,value,clone(this._options));return true}catch(e){return false}};Cookie.prototype.get=function(key){try{var value=cookie(key);value=value?json.parse(value):null;return value}catch(e){return null}};Cookie.prototype.remove=function(key){try{cookie(key,null,clone(this._options));return true}catch(e){return false}};module.exports=bind.all(new Cookie);module.exports.Cookie=Cookie},{debug:201,bind:205,cookie:194,clone:95,defaults:97,json:179,"top-domain":139}],207:[function(require,module,exports){var debug=require("debug")("analytics:group");var Entity=require("./entity");var inherit=require("inherit");var bind=require("bind");Group.defaults={persist:true,cookie:{key:"ajs_group_id"},localStorage:{key:"ajs_group_properties"}};function Group(options){this.defaults=Group.defaults;this.debug=debug;Entity.call(this,options)}inherit(Group,Entity);module.exports=bind.all(new Group);module.exports.Group=Group},{debug:201,"./entity":218,inherit:219,bind:205}],218:[function(require,module,exports){var debug=require("debug")("analytics:entity"); +var traverse=require("isodate-traverse");var defaults=require("defaults");var memory=require("./memory");var cookie=require("./cookie");var store=require("./store");var extend=require("extend");var clone=require("clone");module.exports=Entity;function Entity(options){this.options(options);this.initialize()}Entity.prototype.initialize=function(){cookie.set("ajs:cookies",true);if(cookie.get("ajs:cookies")){cookie.remove("ajs:cookies");this._storage=cookie;return}if(store.enabled){this._storage=store;return}debug("warning using memory store both cookies and localStorage are disabled");this._storage=memory};Entity.prototype.storage=function(){return this._storage};Entity.prototype.options=function(options){if(arguments.length===0)return this._options;options||(options={});defaults(options,this.defaults||{});this._options=options};Entity.prototype.id=function(id){switch(arguments.length){case 0:return this._getId();case 1:return this._setId(id)}};Entity.prototype._getId=function(){var ret=this._options.persist?this.storage().get(this._options.cookie.key):this._id;return ret===undefined?null:ret};Entity.prototype._setId=function(id){if(this._options.persist){this.storage().set(this._options.cookie.key,id)}else{this._id=id}};Entity.prototype.properties=Entity.prototype.traits=function(traits){switch(arguments.length){case 0:return this._getTraits();case 1:return this._setTraits(traits)}};Entity.prototype._getTraits=function(){var ret=this._options.persist?store.get(this._options.localStorage.key):this._traits;return ret?traverse(clone(ret)):{}};Entity.prototype._setTraits=function(traits){traits||(traits={});if(this._options.persist){store.set(this._options.localStorage.key,traits)}else{this._traits=traits}};Entity.prototype.identify=function(id,traits){traits||(traits={});var current=this.id();if(current===null||current===id)traits=extend(this.traits(),traits);if(id)this.id(id);this.debug("identify %o, %o",id,traits);this.traits(traits);this.save()};Entity.prototype.save=function(){if(!this._options.persist)return false;cookie.set(this._options.cookie.key,this.id());store.set(this._options.localStorage.key,this.traits());return true};Entity.prototype.logout=function(){this.id(null);this.traits({});cookie.remove(this._options.cookie.key);store.remove(this._options.localStorage.key)};Entity.prototype.reset=function(){this.logout();this.options({})};Entity.prototype.load=function(){this.id(cookie.get(this._options.cookie.key));this.traits(store.get(this._options.localStorage.key))}},{debug:201,"isodate-traverse":156,defaults:97,"./memory":215,"./cookie":206,"./store":216,extend:145,clone:95}],215:[function(require,module,exports){var clone=require("clone");var bind=require("bind");var has=Object.prototype.hasOwnProperty;module.exports=bind.all(new Memory);function Memory(){this.store={}}Memory.prototype.set=function(key,value){this.store[key]=clone(value);return true};Memory.prototype.get=function(key){if(!has.call(this.store,key))return;return clone(this.store[key])};Memory.prototype.remove=function(key){delete this.store[key];return true}},{clone:95,bind:205}],216:[function(require,module,exports){var bind=require("bind");var defaults=require("defaults");var store=require("store.js");function Store(options){this.options(options)}Store.prototype.options=function(options){if(arguments.length===0)return this._options;options=options||{};defaults(options,{enabled:true});this.enabled=options.enabled&&store.enabled;this._options=options};Store.prototype.set=function(key,value){if(!this.enabled)return false;return store.set(key,value)};Store.prototype.get=function(key){if(!this.enabled)return null;return store.get(key)};Store.prototype.remove=function(key){if(!this.enabled)return false;return store.remove(key)};module.exports=bind.all(new Store);module.exports.Store=Store},{bind:205,defaults:97,"store.js":220}],220:[function(require,module,exports){var json=require("json"),store={},win=window,doc=win.document,localStorageName="localStorage",namespace="__storejs__",storage;store.disabled=false;store.set=function(key,value){};store.get=function(key){};store.remove=function(key){};store.clear=function(){};store.transact=function(key,defaultVal,transactionFn){var val=store.get(key);if(transactionFn==null){transactionFn=defaultVal;defaultVal=null}if(typeof val=="undefined"){val=defaultVal||{}}transactionFn(val);store.set(key,val)};store.getAll=function(){};store.serialize=function(value){return json.stringify(value)};store.deserialize=function(value){if(typeof value!="string"){return undefined}try{return json.parse(value)}catch(e){return value||undefined}};function isLocalStorageNameSupported(){try{return localStorageName in win&&win[localStorageName]}catch(err){return false}}if(isLocalStorageNameSupported()){storage=win[localStorageName];store.set=function(key,val){if(val===undefined){return store.remove(key)}storage.setItem(key,store.serialize(val));return val};store.get=function(key){return store.deserialize(storage.getItem(key))};store.remove=function(key){storage.removeItem(key)};store.clear=function(){storage.clear()};store.getAll=function(){var ret={};for(var i=0;i<storage.length;++i){var key=storage.key(i);ret[key]=store.get(key)}return ret}}else if(doc.documentElement.addBehavior){var storageOwner,storageContainer;try{storageContainer=new ActiveXObject("htmlfile");storageContainer.open();storageContainer.write("<s"+"cript>document.w=window</s"+'cript><iframe src="/favicon.ico"></iframe>');storageContainer.close();storageOwner=storageContainer.w.frames[0].document;storage=storageOwner.createElement("div")}catch(e){storage=doc.createElement("div");storageOwner=doc.body}function withIEStorage(storeFunction){return function(){var args=Array.prototype.slice.call(arguments,0);args.unshift(storage);storageOwner.appendChild(storage);storage.addBehavior("#default#userData");storage.load(localStorageName);var result=storeFunction.apply(store,args);storageOwner.removeChild(storage);return result}}var forbiddenCharsRegex=new RegExp("[!\"#$%&'()*+,/\\\\:;<=>?@[\\]^`{|}~]","g");function ieKeyFix(key){return key.replace(forbiddenCharsRegex,"___")}store.set=withIEStorage(function(storage,key,val){key=ieKeyFix(key);if(val===undefined){return store.remove(key)}storage.setAttribute(key,store.serialize(val));storage.save(localStorageName);return val});store.get=withIEStorage(function(storage,key){key=ieKeyFix(key);return store.deserialize(storage.getAttribute(key))});store.remove=withIEStorage(function(storage,key){key=ieKeyFix(key);storage.removeAttribute(key);storage.save(localStorageName)});store.clear=withIEStorage(function(storage){var attributes=storage.XMLDocument.documentElement.attributes;storage.load(localStorageName);for(var i=0,attr;attr=attributes[i];i++){storage.removeAttribute(attr.name)}storage.save(localStorageName)});store.getAll=withIEStorage(function(storage){var attributes=storage.XMLDocument.documentElement.attributes;var ret={};for(var i=0,attr;attr=attributes[i];++i){var key=ieKeyFix(attr.name);ret[attr.name]=store.deserialize(storage.getAttribute(key))}return ret})}try{store.set(namespace,namespace);if(store.get(namespace)!=namespace){store.disabled=true}store.remove(namespace)}catch(e){store.disabled=true}store.enabled=!store.disabled;module.exports=store},{json:179}],219:[function(require,module,exports){module.exports=function(a,b){var fn=function(){};fn.prototype=b.prototype;a.prototype=new fn;a.prototype.constructor=a}},{}],208:[function(require,module,exports){module.exports=function isMeta(e){if(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)return true;var which=e.which,button=e.button;if(!which&&button!==undefined){return!button&1&&!button&2&&button&4}else if(which===2){return true}return false}},{}],209:[function(require,module,exports){exports.bind=function(el,type,fn,capture){if(el.addEventListener){el.addEventListener(type,fn,capture||false)}else{el.attachEvent("on"+type,fn)}return fn};exports.unbind=function(el,type,fn,capture){if(el.removeEventListener){el.removeEventListener(type,fn,capture||false)}else{el.detachEvent("on"+type,fn)}return fn}},{}],210:[function(require,module,exports){var canonical=require("canonical");var url=require("url");function pageDefaults(){return{path:canonicalPath(),referrer:document.referrer,search:location.search,title:document.title,url:canonicalUrl(location.search)}}function canonicalPath(){var canon=canonical();if(!canon)return window.location.pathname;var parsed=url.parse(canon);return parsed.pathname}function canonicalUrl(search){var canon=canonical();if(canon)return~canon.indexOf("?")?canon:canon+search;var url=window.location.href;var i=url.indexOf("#");return-1===i?url:url.slice(0,i)}module.exports=pageDefaults},{canonical:182,url:184}],211:[function(require,module,exports){"use strict";var objToString=Object.prototype.toString;var existy=function(val){return val!=null};var isArray=function(val){return objToString.call(val)==="[object Array]"};var isString=function(val){return typeof val==="string"||objToString.call(val)==="[object String]"};var isObject=function(val){return val!=null&&typeof val==="object"};var pick=function pick(props,object){if(!existy(object)||!isObject(object)){return{}}if(isString(props)){props=[props]}if(!isArray(props)){props=[]}var result={};for(var i=0;i<props.length;i+=1){if(isString(props[i])&&props[i]in object){result[props[i]]=object[props[i]]}}return result};module.exports=pick},{}],212:[function(require,module,exports){module.exports=function(e){e=e||window.event;return e.preventDefault?e.preventDefault():e.returnValue=false}},{}],213:[function(require,module,exports){var encode=encodeURIComponent;var decode=decodeURIComponent;var trim=require("trim");var type=require("type");exports.parse=function(str){if("string"!=typeof str)return{};str=trim(str);if(""==str)return{};if("?"==str.charAt(0))str=str.slice(1);var obj={};var pairs=str.split("&");for(var i=0;i<pairs.length;i++){var parts=pairs[i].split("=");var key=decode(parts[0]);var m;if(m=/(\w+)\[(\d+)\]/.exec(key)){obj[m[1]]=obj[m[1]]||[];obj[m[1]][m[2]]=decode(parts[1]);continue}obj[parts[0]]=null==parts[1]?"":decode(parts[1])}return obj};exports.stringify=function(obj){if(!obj)return"";var pairs=[];for(var key in obj){var value=obj[key];if("array"==type(value)){for(var i=0;i<value.length;++i){pairs.push(encode(key+"["+i+"]")+"="+encode(value[i]))}continue}pairs.push(encode(key)+"="+encode(obj[key]))}return pairs.join("&")}},{trim:141,type:7}],214:[function(require,module,exports){var debug=require("debug")("analytics.js:normalize");var indexof=require("component/indexof");var defaults=require("defaults");var map=require("component/map");var each=require("each");var is=require("is");var has=Object.prototype.hasOwnProperty;module.exports=normalize;var toplevel=["integrations","anonymousId","timestamp","context"];function normalize(msg,list){var lower=map(list,function(s){return s.toLowerCase()});var opts=msg.options||{};var integrations=opts.integrations||{};var providers=opts.providers||{};var context=opts.context||{};var ret={};debug("<-",msg);each(opts,function(key,value){if(!integration(key))return;if(!has.call(integrations,key))integrations[key]=value;delete opts[key]});delete opts.providers;each(providers,function(key,value){if(!integration(key))return;if(is.object(integrations[key]))return;if(has.call(integrations,key)&&"boolean"==typeof providers[key])return;integrations[key]=value});each(opts,function(key){if(~indexof(toplevel,key)){ret[key]=opts[key]}else{context[key]=opts[key]}});delete msg.options;ret.integrations=integrations;ret.context=context;ret=defaults(ret,msg);debug("->",ret);return ret;function integration(name){return!!(~indexof(list,name)||"all"==name.toLowerCase()||~indexof(lower,name.toLowerCase()))}}},{debug:201,"component/indexof":116,defaults:97,"component/map":221,each:4,is:91}],221:[function(require,module,exports){var toFunction=require("to-function");module.exports=function(arr,fn){var ret=[];fn=toFunction(fn);for(var i=0;i<arr.length;++i){ret.push(fn(arr[i],i))}return ret}},{"to-function":185}],217:[function(require,module,exports){var debug=require("debug")("analytics:user");var Entity=require("./entity");var inherit=require("inherit");var bind=require("bind");var cookie=require("./cookie");var uuid=require("uuid");var rawCookie=require("cookie");User.defaults={persist:true,cookie:{key:"ajs_user_id",oldKey:"ajs_user"},localStorage:{key:"ajs_user_traits"}};function User(options){this.defaults=User.defaults;this.debug=debug;Entity.call(this,options)}inherit(User,Entity);User.prototype.id=function(id){var prev=this._getId();var ret=Entity.prototype.id.apply(this,arguments);if(null==prev)return ret;if(prev!=id&&id)this.anonymousId(null);return ret};User.prototype.anonymousId=function(anonId){var store=this.storage();if(arguments.length){store.set("ajs_anonymous_id",anonId);return this}if(anonId=store.get("ajs_anonymous_id")){return anonId}if(anonId=rawCookie("_sio")){anonId=anonId.split("----")[0];store.set("ajs_anonymous_id",anonId);store.remove("_sio");return anonId}anonId=uuid();store.set("ajs_anonymous_id",anonId);return store.get("ajs_anonymous_id")};User.prototype.logout=function(){Entity.prototype.logout.call(this);this.anonymousId(null)};User.prototype.load=function(){if(this._loadOldCookie())return;Entity.prototype.load.call(this)};User.prototype._loadOldCookie=function(){var user=cookie.get(this._options.cookie.oldKey);if(!user)return false;this.id(user.id);this.traits(user.traits);cookie.remove(this._options.cookie.oldKey);return true};module.exports=bind.all(new User);module.exports.User=User},{debug:201,"./entity":218,inherit:219,bind:205,"./cookie":206,uuid:195,cookie:194}],5:[function(require,module,exports){module.exports={name:"analytics",version:"2.8.0",main:"analytics.js",dependencies:{},devDependencies:{}}},{}]},{},{1:""})); \ No newline at end of file diff --git a/web2py/applications/SP/static/js/bootstrap.bundle.min.js b/web2py/applications/SP/static/js/bootstrap.bundle.min.js new file mode 100644 index 0000000..7d50e87 --- /dev/null +++ b/web2py/applications/SP/static/js/bootstrap.bundle.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.0.0 (https://getbootstrap.com) + * Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery")):"function"==typeof define&&define.amd?define(["exports","jquery"],e):e(t.bootstrap={},t.jQuery)}(this,function(t,e){"use strict";function n(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function i(t,e,i){return e&&n(t.prototype,e),i&&n(t,i),t}function r(){return(r=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}for(var o,s,a,l,c,h,f,u,d,p,g,m,_,v,E,y,b,T,C,w,I,A,D,S,O,N,k=function(t){var e=!1;function n(e){var n=this,r=!1;return t(this).one(i.TRANSITION_END,function(){r=!0}),setTimeout(function(){r||i.triggerTransitionEnd(n)},e),this}var i={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},getSelectorFromElement:function(e){var n,i=e.getAttribute("data-target");i&&"#"!==i||(i=e.getAttribute("href")||""),"#"===i.charAt(0)&&(n=i,i=n="function"==typeof t.escapeSelector?t.escapeSelector(n).substr(1):n.replace(/(:|\.|\[|\]|,|=|@)/g,"\\$1"));try{return t(document).find(i).length>0?i:null}catch(t){return null}},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(n){t(n).trigger(e.end)},supportsTransitionEnd:function(){return Boolean(e)},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var r in n)if(Object.prototype.hasOwnProperty.call(n,r)){var o=n[r],s=e[r],a=s&&i.isElement(s)?"element":(l=s,{}.toString.call(l).match(/\s([a-zA-Z]+)/)[1].toLowerCase());if(!new RegExp(o).test(a))throw new Error(t.toUpperCase()+': Option "'+r+'" provided type "'+a+'" but expected type "'+o+'".')}var l}};return e=("undefined"==typeof window||!window.QUnit)&&{end:"transitionend"},t.fn.emulateTransitionEnd=n,i.supportsTransitionEnd()&&(t.event.special[i.TRANSITION_END]={bindType:e.end,delegateType:e.end,handle:function(e){if(t(e.target).is(this))return e.handleObj.handler.apply(this,arguments)}}),i}(e=e&&e.hasOwnProperty("default")?e.default:e),L=(s="alert",l="."+(a="bs.alert"),c=(o=e).fn[s],h={CLOSE:"close"+l,CLOSED:"closed"+l,CLICK_DATA_API:"click"+l+".data-api"},f="alert",u="fade",d="show",p=function(){function t(t){this._element=t}var e=t.prototype;return e.close=function(t){t=t||this._element;var e=this._getRootElement(t);this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},e.dispose=function(){o.removeData(this._element,a),this._element=null},e._getRootElement=function(t){var e=k.getSelectorFromElement(t),n=!1;return e&&(n=o(e)[0]),n||(n=o(t).closest("."+f)[0]),n},e._triggerCloseEvent=function(t){var e=o.Event(h.CLOSE);return o(t).trigger(e),e},e._removeElement=function(t){var e=this;o(t).removeClass(d),k.supportsTransitionEnd()&&o(t).hasClass(u)?o(t).one(k.TRANSITION_END,function(n){return e._destroyElement(t,n)}).emulateTransitionEnd(150):this._destroyElement(t)},e._destroyElement=function(t){o(t).detach().trigger(h.CLOSED).remove()},t._jQueryInterface=function(e){return this.each(function(){var n=o(this),i=n.data(a);i||(i=new t(this),n.data(a,i)),"close"===e&&i[e](this)})},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},i(t,null,[{key:"VERSION",get:function(){return"4.0.0"}}]),t}(),o(document).on(h.CLICK_DATA_API,'[data-dismiss="alert"]',p._handleDismiss(new p)),o.fn[s]=p._jQueryInterface,o.fn[s].Constructor=p,o.fn[s].noConflict=function(){return o.fn[s]=c,p._jQueryInterface},p),P=(m="button",v="."+(_="bs.button"),E=".data-api",y=(g=e).fn[m],b="active",T="btn",C="focus",w='[data-toggle^="button"]',I='[data-toggle="buttons"]',A="input",D=".active",S=".btn",O={CLICK_DATA_API:"click"+v+E,FOCUS_BLUR_DATA_API:"focus"+v+E+" blur"+v+E},N=function(){function t(t){this._element=t}var e=t.prototype;return e.toggle=function(){var t=!0,e=!0,n=g(this._element).closest(I)[0];if(n){var i=g(this._element).find(A)[0];if(i){if("radio"===i.type)if(i.checked&&g(this._element).hasClass(b))t=!1;else{var r=g(n).find(D)[0];r&&g(r).removeClass(b)}if(t){if(i.hasAttribute("disabled")||n.hasAttribute("disabled")||i.classList.contains("disabled")||n.classList.contains("disabled"))return;i.checked=!g(this._element).hasClass(b),g(i).trigger("change")}i.focus(),e=!1}}e&&this._element.setAttribute("aria-pressed",!g(this._element).hasClass(b)),t&&g(this._element).toggleClass(b)},e.dispose=function(){g.removeData(this._element,_),this._element=null},t._jQueryInterface=function(e){return this.each(function(){var n=g(this).data(_);n||(n=new t(this),g(this).data(_,n)),"toggle"===e&&n[e]()})},i(t,null,[{key:"VERSION",get:function(){return"4.0.0"}}]),t}(),g(document).on(O.CLICK_DATA_API,w,function(t){t.preventDefault();var e=t.target;g(e).hasClass(T)||(e=g(e).closest(S)),N._jQueryInterface.call(g(e),"toggle")}).on(O.FOCUS_BLUR_DATA_API,w,function(t){var e=g(t.target).closest(S)[0];g(e).toggleClass(C,/^focus(in)?$/.test(t.type))}),g.fn[m]=N._jQueryInterface,g.fn[m].Constructor=N,g.fn[m].noConflict=function(){return g.fn[m]=y,N._jQueryInterface},N),x=function(t){var e="carousel",n="bs.carousel",o="."+n,s=t.fn[e],a={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0},l={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean"},c="next",h="prev",f="left",u="right",d={SLIDE:"slide"+o,SLID:"slid"+o,KEYDOWN:"keydown"+o,MOUSEENTER:"mouseenter"+o,MOUSELEAVE:"mouseleave"+o,TOUCHEND:"touchend"+o,LOAD_DATA_API:"load"+o+".data-api",CLICK_DATA_API:"click"+o+".data-api"},p="carousel",g="active",m="slide",_="carousel-item-right",v="carousel-item-left",E="carousel-item-next",y="carousel-item-prev",b={ACTIVE:".active",ACTIVE_ITEM:".active.carousel-item",ITEM:".carousel-item",NEXT_PREV:".carousel-item-next, .carousel-item-prev",INDICATORS:".carousel-indicators",DATA_SLIDE:"[data-slide], [data-slide-to]",DATA_RIDE:'[data-ride="carousel"]'},T=function(){function s(e,n){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this._config=this._getConfig(n),this._element=t(e)[0],this._indicatorsElement=t(this._element).find(b.INDICATORS)[0],this._addEventListeners()}var T=s.prototype;return T.next=function(){this._isSliding||this._slide(c)},T.nextWhenVisible=function(){!document.hidden&&t(this._element).is(":visible")&&"hidden"!==t(this._element).css("visibility")&&this.next()},T.prev=function(){this._isSliding||this._slide(h)},T.pause=function(e){e||(this._isPaused=!0),t(this._element).find(b.NEXT_PREV)[0]&&k.supportsTransitionEnd()&&(k.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},T.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},T.to=function(e){var n=this;this._activeElement=t(this._element).find(b.ACTIVE_ITEM)[0];var i=this._getItemIndex(this._activeElement);if(!(e>this._items.length-1||e<0))if(this._isSliding)t(this._element).one(d.SLID,function(){return n.to(e)});else{if(i===e)return this.pause(),void this.cycle();var r=e>i?c:h;this._slide(r,this._items[e])}},T.dispose=function(){t(this._element).off(o),t.removeData(this._element,n),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},T._getConfig=function(t){return t=r({},a,t),k.typeCheckConfig(e,t,l),t},T._addEventListeners=function(){var e=this;this._config.keyboard&&t(this._element).on(d.KEYDOWN,function(t){return e._keydown(t)}),"hover"===this._config.pause&&(t(this._element).on(d.MOUSEENTER,function(t){return e.pause(t)}).on(d.MOUSELEAVE,function(t){return e.cycle(t)}),"ontouchstart"in document.documentElement&&t(this._element).on(d.TOUCHEND,function(){e.pause(),e.touchTimeout&&clearTimeout(e.touchTimeout),e.touchTimeout=setTimeout(function(t){return e.cycle(t)},500+e._config.interval)}))},T._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},T._getItemIndex=function(e){return this._items=t.makeArray(t(e).parent().find(b.ITEM)),this._items.indexOf(e)},T._getItemByDirection=function(t,e){var n=t===c,i=t===h,r=this._getItemIndex(e),o=this._items.length-1;if((i&&0===r||n&&r===o)&&!this._config.wrap)return e;var s=(r+(t===h?-1:1))%this._items.length;return-1===s?this._items[this._items.length-1]:this._items[s]},T._triggerSlideEvent=function(e,n){var i=this._getItemIndex(e),r=this._getItemIndex(t(this._element).find(b.ACTIVE_ITEM)[0]),o=t.Event(d.SLIDE,{relatedTarget:e,direction:n,from:r,to:i});return t(this._element).trigger(o),o},T._setActiveIndicatorElement=function(e){if(this._indicatorsElement){t(this._indicatorsElement).find(b.ACTIVE).removeClass(g);var n=this._indicatorsElement.children[this._getItemIndex(e)];n&&t(n).addClass(g)}},T._slide=function(e,n){var i,r,o,s=this,a=t(this._element).find(b.ACTIVE_ITEM)[0],l=this._getItemIndex(a),h=n||a&&this._getItemByDirection(e,a),p=this._getItemIndex(h),T=Boolean(this._interval);if(e===c?(i=v,r=E,o=f):(i=_,r=y,o=u),h&&t(h).hasClass(g))this._isSliding=!1;else if(!this._triggerSlideEvent(h,o).isDefaultPrevented()&&a&&h){this._isSliding=!0,T&&this.pause(),this._setActiveIndicatorElement(h);var C=t.Event(d.SLID,{relatedTarget:h,direction:o,from:l,to:p});k.supportsTransitionEnd()&&t(this._element).hasClass(m)?(t(h).addClass(r),k.reflow(h),t(a).addClass(i),t(h).addClass(i),t(a).one(k.TRANSITION_END,function(){t(h).removeClass(i+" "+r).addClass(g),t(a).removeClass(g+" "+r+" "+i),s._isSliding=!1,setTimeout(function(){return t(s._element).trigger(C)},0)}).emulateTransitionEnd(600)):(t(a).removeClass(g),t(h).addClass(g),this._isSliding=!1,t(this._element).trigger(C)),T&&this.cycle()}},s._jQueryInterface=function(e){return this.each(function(){var i=t(this).data(n),o=r({},a,t(this).data());"object"==typeof e&&(o=r({},o,e));var l="string"==typeof e?e:o.slide;if(i||(i=new s(this,o),t(this).data(n,i)),"number"==typeof e)i.to(e);else if("string"==typeof l){if("undefined"==typeof i[l])throw new TypeError('No method named "'+l+'"');i[l]()}else o.interval&&(i.pause(),i.cycle())})},s._dataApiClickHandler=function(e){var i=k.getSelectorFromElement(this);if(i){var o=t(i)[0];if(o&&t(o).hasClass(p)){var a=r({},t(o).data(),t(this).data()),l=this.getAttribute("data-slide-to");l&&(a.interval=!1),s._jQueryInterface.call(t(o),a),l&&t(o).data(n).to(l),e.preventDefault()}}},i(s,null,[{key:"VERSION",get:function(){return"4.0.0"}},{key:"Default",get:function(){return a}}]),s}();return t(document).on(d.CLICK_DATA_API,b.DATA_SLIDE,T._dataApiClickHandler),t(window).on(d.LOAD_DATA_API,function(){t(b.DATA_RIDE).each(function(){var e=t(this);T._jQueryInterface.call(e,e.data())})}),t.fn[e]=T._jQueryInterface,t.fn[e].Constructor=T,t.fn[e].noConflict=function(){return t.fn[e]=s,T._jQueryInterface},T}(e),R=function(t){var e="collapse",n="bs.collapse",o="."+n,s=t.fn[e],a={toggle:!0,parent:""},l={toggle:"boolean",parent:"(string|element)"},c={SHOW:"show"+o,SHOWN:"shown"+o,HIDE:"hide"+o,HIDDEN:"hidden"+o,CLICK_DATA_API:"click"+o+".data-api"},h="show",f="collapse",u="collapsing",d="collapsed",p="width",g="height",m={ACTIVES:".show, .collapsing",DATA_TOGGLE:'[data-toggle="collapse"]'},_=function(){function o(e,n){this._isTransitioning=!1,this._element=e,this._config=this._getConfig(n),this._triggerArray=t.makeArray(t('[data-toggle="collapse"][href="#'+e.id+'"],[data-toggle="collapse"][data-target="#'+e.id+'"]'));for(var i=t(m.DATA_TOGGLE),r=0;r<i.length;r++){var o=i[r],s=k.getSelectorFromElement(o);null!==s&&t(s).filter(e).length>0&&(this._selector=s,this._triggerArray.push(o))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var s=o.prototype;return s.toggle=function(){t(this._element).hasClass(h)?this.hide():this.show()},s.show=function(){var e,i,r=this;if(!this._isTransitioning&&!t(this._element).hasClass(h)&&(this._parent&&0===(e=t.makeArray(t(this._parent).find(m.ACTIVES).filter('[data-parent="'+this._config.parent+'"]'))).length&&(e=null),!(e&&(i=t(e).not(this._selector).data(n))&&i._isTransitioning))){var s=t.Event(c.SHOW);if(t(this._element).trigger(s),!s.isDefaultPrevented()){e&&(o._jQueryInterface.call(t(e).not(this._selector),"hide"),i||t(e).data(n,null));var a=this._getDimension();t(this._element).removeClass(f).addClass(u),this._element.style[a]=0,this._triggerArray.length>0&&t(this._triggerArray).removeClass(d).attr("aria-expanded",!0),this.setTransitioning(!0);var l=function(){t(r._element).removeClass(u).addClass(f).addClass(h),r._element.style[a]="",r.setTransitioning(!1),t(r._element).trigger(c.SHOWN)};if(k.supportsTransitionEnd()){var p="scroll"+(a[0].toUpperCase()+a.slice(1));t(this._element).one(k.TRANSITION_END,l).emulateTransitionEnd(600),this._element.style[a]=this._element[p]+"px"}else l()}}},s.hide=function(){var e=this;if(!this._isTransitioning&&t(this._element).hasClass(h)){var n=t.Event(c.HIDE);if(t(this._element).trigger(n),!n.isDefaultPrevented()){var i=this._getDimension();if(this._element.style[i]=this._element.getBoundingClientRect()[i]+"px",k.reflow(this._element),t(this._element).addClass(u).removeClass(f).removeClass(h),this._triggerArray.length>0)for(var r=0;r<this._triggerArray.length;r++){var o=this._triggerArray[r],s=k.getSelectorFromElement(o);if(null!==s)t(s).hasClass(h)||t(o).addClass(d).attr("aria-expanded",!1)}this.setTransitioning(!0);var a=function(){e.setTransitioning(!1),t(e._element).removeClass(u).addClass(f).trigger(c.HIDDEN)};this._element.style[i]="",k.supportsTransitionEnd()?t(this._element).one(k.TRANSITION_END,a).emulateTransitionEnd(600):a()}}},s.setTransitioning=function(t){this._isTransitioning=t},s.dispose=function(){t.removeData(this._element,n),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},s._getConfig=function(t){return(t=r({},a,t)).toggle=Boolean(t.toggle),k.typeCheckConfig(e,t,l),t},s._getDimension=function(){return t(this._element).hasClass(p)?p:g},s._getParent=function(){var e=this,n=null;k.isElement(this._config.parent)?(n=this._config.parent,"undefined"!=typeof this._config.parent.jquery&&(n=this._config.parent[0])):n=t(this._config.parent)[0];var i='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]';return t(n).find(i).each(function(t,n){e._addAriaAndCollapsedClass(o._getTargetFromElement(n),[n])}),n},s._addAriaAndCollapsedClass=function(e,n){if(e){var i=t(e).hasClass(h);n.length>0&&t(n).toggleClass(d,!i).attr("aria-expanded",i)}},o._getTargetFromElement=function(e){var n=k.getSelectorFromElement(e);return n?t(n)[0]:null},o._jQueryInterface=function(e){return this.each(function(){var i=t(this),s=i.data(n),l=r({},a,i.data(),"object"==typeof e&&e);if(!s&&l.toggle&&/show|hide/.test(e)&&(l.toggle=!1),s||(s=new o(this,l),i.data(n,s)),"string"==typeof e){if("undefined"==typeof s[e])throw new TypeError('No method named "'+e+'"');s[e]()}})},i(o,null,[{key:"VERSION",get:function(){return"4.0.0"}},{key:"Default",get:function(){return a}}]),o}();return t(document).on(c.CLICK_DATA_API,m.DATA_TOGGLE,function(e){"A"===e.currentTarget.tagName&&e.preventDefault();var i=t(this),r=k.getSelectorFromElement(this);t(r).each(function(){var e=t(this),r=e.data(n)?"toggle":i.data();_._jQueryInterface.call(e,r)})}),t.fn[e]=_._jQueryInterface,t.fn[e].Constructor=_,t.fn[e].noConflict=function(){return t.fn[e]=s,_._jQueryInterface},_}(e),j="undefined"!=typeof window&&"undefined"!=typeof document,H=["Edge","Trident","Firefox"],M=0,W=0;W<H.length;W+=1)if(j&&navigator.userAgent.indexOf(H[W])>=0){M=1;break}var U=j&&window.Promise?function(t){var e=!1;return function(){e||(e=!0,window.Promise.resolve().then(function(){e=!1,t()}))}}:function(t){var e=!1;return function(){e||(e=!0,setTimeout(function(){e=!1,t()},M))}};function B(t){return t&&"[object Function]"==={}.toString.call(t)}function F(t,e){if(1!==t.nodeType)return[];var n=getComputedStyle(t,null);return e?n[e]:n}function K(t){return"HTML"===t.nodeName?t:t.parentNode||t.host}function V(t){if(!t)return document.body;switch(t.nodeName){case"HTML":case"BODY":return t.ownerDocument.body;case"#document":return t.body}var e=F(t),n=e.overflow,i=e.overflowX,r=e.overflowY;return/(auto|scroll)/.test(n+r+i)?t:V(K(t))}function Q(t){var e=t&&t.offsetParent,n=e&&e.nodeName;return n&&"BODY"!==n&&"HTML"!==n?-1!==["TD","TABLE"].indexOf(e.nodeName)&&"static"===F(e,"position")?Q(e):e:t?t.ownerDocument.documentElement:document.documentElement}function Y(t){return null!==t.parentNode?Y(t.parentNode):t}function G(t,e){if(!(t&&t.nodeType&&e&&e.nodeType))return document.documentElement;var n=t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING,i=n?t:e,r=n?e:t,o=document.createRange();o.setStart(i,0),o.setEnd(r,0);var s,a,l=o.commonAncestorContainer;if(t!==l&&e!==l||i.contains(r))return"BODY"===(a=(s=l).nodeName)||"HTML"!==a&&Q(s.firstElementChild)!==s?Q(l):l;var c=Y(t);return c.host?G(c.host,e):G(t,Y(e).host)}function q(t){var e="top"===(arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top")?"scrollTop":"scrollLeft",n=t.nodeName;if("BODY"===n||"HTML"===n){var i=t.ownerDocument.documentElement;return(t.ownerDocument.scrollingElement||i)[e]}return t[e]}function z(t,e){var n="x"===e?"Left":"Top",i="Left"===n?"Right":"Bottom";return parseFloat(t["border"+n+"Width"],10)+parseFloat(t["border"+i+"Width"],10)}var X=void 0,Z=function(){return void 0===X&&(X=-1!==navigator.appVersion.indexOf("MSIE 10")),X};function J(t,e,n,i){return Math.max(e["offset"+t],e["scroll"+t],n["client"+t],n["offset"+t],n["scroll"+t],Z()?n["offset"+t]+i["margin"+("Height"===t?"Top":"Left")]+i["margin"+("Height"===t?"Bottom":"Right")]:0)}function $(){var t=document.body,e=document.documentElement,n=Z()&&getComputedStyle(e);return{height:J("Height",t,e,n),width:J("Width",t,e,n)}}var tt=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},et=function(){function t(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}}(),nt=function(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t},it=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t};function rt(t){return it({},t,{right:t.left+t.width,bottom:t.top+t.height})}function ot(t){var e={};if(Z())try{e=t.getBoundingClientRect();var n=q(t,"top"),i=q(t,"left");e.top+=n,e.left+=i,e.bottom+=n,e.right+=i}catch(t){}else e=t.getBoundingClientRect();var r={left:e.left,top:e.top,width:e.right-e.left,height:e.bottom-e.top},o="HTML"===t.nodeName?$():{},s=o.width||t.clientWidth||r.right-r.left,a=o.height||t.clientHeight||r.bottom-r.top,l=t.offsetWidth-s,c=t.offsetHeight-a;if(l||c){var h=F(t);l-=z(h,"x"),c-=z(h,"y"),r.width-=l,r.height-=c}return rt(r)}function st(t,e){var n=Z(),i="HTML"===e.nodeName,r=ot(t),o=ot(e),s=V(t),a=F(e),l=parseFloat(a.borderTopWidth,10),c=parseFloat(a.borderLeftWidth,10),h=rt({top:r.top-o.top-l,left:r.left-o.left-c,width:r.width,height:r.height});if(h.marginTop=0,h.marginLeft=0,!n&&i){var f=parseFloat(a.marginTop,10),u=parseFloat(a.marginLeft,10);h.top-=l-f,h.bottom-=l-f,h.left-=c-u,h.right-=c-u,h.marginTop=f,h.marginLeft=u}return(n?e.contains(s):e===s&&"BODY"!==s.nodeName)&&(h=function(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=q(e,"top"),r=q(e,"left"),o=n?-1:1;return t.top+=i*o,t.bottom+=i*o,t.left+=r*o,t.right+=r*o,t}(h,e)),h}function at(t,e,n,i){var r,o,s,a,l,c,h,f={top:0,left:0},u=G(t,e);if("viewport"===i)o=(r=u).ownerDocument.documentElement,s=st(r,o),a=Math.max(o.clientWidth,window.innerWidth||0),l=Math.max(o.clientHeight,window.innerHeight||0),c=q(o),h=q(o,"left"),f=rt({top:c-s.top+s.marginTop,left:h-s.left+s.marginLeft,width:a,height:l});else{var d=void 0;"scrollParent"===i?"BODY"===(d=V(K(e))).nodeName&&(d=t.ownerDocument.documentElement):d="window"===i?t.ownerDocument.documentElement:i;var p=st(d,u);if("HTML"!==d.nodeName||function t(e){var n=e.nodeName;return"BODY"!==n&&"HTML"!==n&&("fixed"===F(e,"position")||t(K(e)))}(u))f=p;else{var g=$(),m=g.height,_=g.width;f.top+=p.top-p.marginTop,f.bottom=m+p.top,f.left+=p.left-p.marginLeft,f.right=_+p.left}}return f.left+=n,f.top+=n,f.right-=n,f.bottom-=n,f}function lt(t,e,n,i,r){var o=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0;if(-1===t.indexOf("auto"))return t;var s=at(n,i,o,r),a={top:{width:s.width,height:e.top-s.top},right:{width:s.right-e.right,height:s.height},bottom:{width:s.width,height:s.bottom-e.bottom},left:{width:e.left-s.left,height:s.height}},l=Object.keys(a).map(function(t){return it({key:t},a[t],{area:(e=a[t],e.width*e.height)});var e}).sort(function(t,e){return e.area-t.area}),c=l.filter(function(t){var e=t.width,i=t.height;return e>=n.clientWidth&&i>=n.clientHeight}),h=c.length>0?c[0].key:l[0].key,f=t.split("-")[1];return h+(f?"-"+f:"")}function ct(t,e,n){return st(n,G(e,n))}function ht(t){var e=getComputedStyle(t),n=parseFloat(e.marginTop)+parseFloat(e.marginBottom),i=parseFloat(e.marginLeft)+parseFloat(e.marginRight);return{width:t.offsetWidth+i,height:t.offsetHeight+n}}function ft(t){var e={left:"right",right:"left",bottom:"top",top:"bottom"};return t.replace(/left|right|bottom|top/g,function(t){return e[t]})}function ut(t,e,n){n=n.split("-")[0];var i=ht(t),r={width:i.width,height:i.height},o=-1!==["right","left"].indexOf(n),s=o?"top":"left",a=o?"left":"top",l=o?"height":"width",c=o?"width":"height";return r[s]=e[s]+e[l]/2-i[l]/2,r[a]=n===a?e[a]-i[c]:e[ft(a)],r}function dt(t,e){return Array.prototype.find?t.find(e):t.filter(e)[0]}function pt(t,e,n){return(void 0===n?t:t.slice(0,function(t,e,n){if(Array.prototype.findIndex)return t.findIndex(function(t){return t[e]===n});var i=dt(t,function(t){return t[e]===n});return t.indexOf(i)}(t,"name",n))).forEach(function(t){t.function&&console.warn("`modifier.function` is deprecated, use `modifier.fn`!");var n=t.function||t.fn;t.enabled&&B(n)&&(e.offsets.popper=rt(e.offsets.popper),e.offsets.reference=rt(e.offsets.reference),e=n(e,t))}),e}function gt(t,e){return t.some(function(t){var n=t.name;return t.enabled&&n===e})}function mt(t){for(var e=[!1,"ms","Webkit","Moz","O"],n=t.charAt(0).toUpperCase()+t.slice(1),i=0;i<e.length-1;i++){var r=e[i],o=r?""+r+n:t;if("undefined"!=typeof document.body.style[o])return o}return null}function _t(t){var e=t.ownerDocument;return e?e.defaultView:window}function vt(t,e,n,i){n.updateBound=i,_t(t).addEventListener("resize",n.updateBound,{passive:!0});var r=V(t);return function t(e,n,i,r){var o="BODY"===e.nodeName,s=o?e.ownerDocument.defaultView:e;s.addEventListener(n,i,{passive:!0}),o||t(V(s.parentNode),n,i,r),r.push(s)}(r,"scroll",n.updateBound,n.scrollParents),n.scrollElement=r,n.eventsEnabled=!0,n}function Et(){var t,e;this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=(t=this.reference,e=this.state,_t(t).removeEventListener("resize",e.updateBound),e.scrollParents.forEach(function(t){t.removeEventListener("scroll",e.updateBound)}),e.updateBound=null,e.scrollParents=[],e.scrollElement=null,e.eventsEnabled=!1,e))}function yt(t){return""!==t&&!isNaN(parseFloat(t))&&isFinite(t)}function bt(t,e){Object.keys(e).forEach(function(n){var i="";-1!==["width","height","top","right","bottom","left"].indexOf(n)&&yt(e[n])&&(i="px"),t.style[n]=e[n]+i})}function Tt(t,e,n){var i=dt(t,function(t){return t.name===e}),r=!!i&&t.some(function(t){return t.name===n&&t.enabled&&t.order<i.order});if(!r){var o="`"+e+"`",s="`"+n+"`";console.warn(s+" modifier is required by "+o+" modifier in order to work, be sure to include it before "+o+"!")}return r}var Ct=["auto-start","auto","auto-end","top-start","top","top-end","right-start","right","right-end","bottom-end","bottom","bottom-start","left-end","left","left-start"],wt=Ct.slice(3);function It(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=wt.indexOf(t),i=wt.slice(n+1).concat(wt.slice(0,n));return e?i.reverse():i}var At={FLIP:"flip",CLOCKWISE:"clockwise",COUNTERCLOCKWISE:"counterclockwise"};function Dt(t,e,n,i){var r=[0,0],o=-1!==["right","left"].indexOf(i),s=t.split(/(\+|\-)/).map(function(t){return t.trim()}),a=s.indexOf(dt(s,function(t){return-1!==t.search(/,|\s/)}));s[a]&&-1===s[a].indexOf(",")&&console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");var l=/\s*,\s*|\s+/,c=-1!==a?[s.slice(0,a).concat([s[a].split(l)[0]]),[s[a].split(l)[1]].concat(s.slice(a+1))]:[s];return(c=c.map(function(t,i){var r=(1===i?!o:o)?"height":"width",s=!1;return t.reduce(function(t,e){return""===t[t.length-1]&&-1!==["+","-"].indexOf(e)?(t[t.length-1]=e,s=!0,t):s?(t[t.length-1]+=e,s=!1,t):t.concat(e)},[]).map(function(t){return function(t,e,n,i){var r=t.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),o=+r[1],s=r[2];if(!o)return t;if(0===s.indexOf("%")){var a=void 0;switch(s){case"%p":a=n;break;case"%":case"%r":default:a=i}return rt(a)[e]/100*o}if("vh"===s||"vw"===s)return("vh"===s?Math.max(document.documentElement.clientHeight,window.innerHeight||0):Math.max(document.documentElement.clientWidth,window.innerWidth||0))/100*o;return o}(t,r,e,n)})})).forEach(function(t,e){t.forEach(function(n,i){yt(n)&&(r[e]+=n*("-"===t[i-1]?-1:1))})}),r}var St={placement:"bottom",eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(t){var e=t.placement,n=e.split("-")[0],i=e.split("-")[1];if(i){var r=t.offsets,o=r.reference,s=r.popper,a=-1!==["bottom","top"].indexOf(n),l=a?"left":"top",c=a?"width":"height",h={start:nt({},l,o[l]),end:nt({},l,o[l]+o[c]-s[c])};t.offsets.popper=it({},s,h[i])}return t}},offset:{order:200,enabled:!0,fn:function(t,e){var n=e.offset,i=t.placement,r=t.offsets,o=r.popper,s=r.reference,a=i.split("-")[0],l=void 0;return l=yt(+n)?[+n,0]:Dt(n,o,s,a),"left"===a?(o.top+=l[0],o.left-=l[1]):"right"===a?(o.top+=l[0],o.left+=l[1]):"top"===a?(o.left+=l[0],o.top-=l[1]):"bottom"===a&&(o.left+=l[0],o.top+=l[1]),t.popper=o,t},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(t,e){var n=e.boundariesElement||Q(t.instance.popper);t.instance.reference===n&&(n=Q(n));var i=at(t.instance.popper,t.instance.reference,e.padding,n);e.boundaries=i;var r=e.priority,o=t.offsets.popper,s={primary:function(t){var n=o[t];return o[t]<i[t]&&!e.escapeWithReference&&(n=Math.max(o[t],i[t])),nt({},t,n)},secondary:function(t){var n="right"===t?"left":"top",r=o[n];return o[t]>i[t]&&!e.escapeWithReference&&(r=Math.min(o[n],i[t]-("right"===t?o.width:o.height))),nt({},n,r)}};return r.forEach(function(t){var e=-1!==["left","top"].indexOf(t)?"primary":"secondary";o=it({},o,s[e](t))}),t.offsets.popper=o,t},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(t){var e=t.offsets,n=e.popper,i=e.reference,r=t.placement.split("-")[0],o=Math.floor,s=-1!==["top","bottom"].indexOf(r),a=s?"right":"bottom",l=s?"left":"top",c=s?"width":"height";return n[a]<o(i[l])&&(t.offsets.popper[l]=o(i[l])-n[c]),n[l]>o(i[a])&&(t.offsets.popper[l]=o(i[a])),t}},arrow:{order:500,enabled:!0,fn:function(t,e){var n;if(!Tt(t.instance.modifiers,"arrow","keepTogether"))return t;var i=e.element;if("string"==typeof i){if(!(i=t.instance.popper.querySelector(i)))return t}else if(!t.instance.popper.contains(i))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),t;var r=t.placement.split("-")[0],o=t.offsets,s=o.popper,a=o.reference,l=-1!==["left","right"].indexOf(r),c=l?"height":"width",h=l?"Top":"Left",f=h.toLowerCase(),u=l?"left":"top",d=l?"bottom":"right",p=ht(i)[c];a[d]-p<s[f]&&(t.offsets.popper[f]-=s[f]-(a[d]-p)),a[f]+p>s[d]&&(t.offsets.popper[f]+=a[f]+p-s[d]),t.offsets.popper=rt(t.offsets.popper);var g=a[f]+a[c]/2-p/2,m=F(t.instance.popper),_=parseFloat(m["margin"+h],10),v=parseFloat(m["border"+h+"Width"],10),E=g-t.offsets.popper[f]-_-v;return E=Math.max(Math.min(s[c]-p,E),0),t.arrowElement=i,t.offsets.arrow=(nt(n={},f,Math.round(E)),nt(n,u,""),n),t},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(t,e){if(gt(t.instance.modifiers,"inner"))return t;if(t.flipped&&t.placement===t.originalPlacement)return t;var n=at(t.instance.popper,t.instance.reference,e.padding,e.boundariesElement),i=t.placement.split("-")[0],r=ft(i),o=t.placement.split("-")[1]||"",s=[];switch(e.behavior){case At.FLIP:s=[i,r];break;case At.CLOCKWISE:s=It(i);break;case At.COUNTERCLOCKWISE:s=It(i,!0);break;default:s=e.behavior}return s.forEach(function(a,l){if(i!==a||s.length===l+1)return t;i=t.placement.split("-")[0],r=ft(i);var c,h=t.offsets.popper,f=t.offsets.reference,u=Math.floor,d="left"===i&&u(h.right)>u(f.left)||"right"===i&&u(h.left)<u(f.right)||"top"===i&&u(h.bottom)>u(f.top)||"bottom"===i&&u(h.top)<u(f.bottom),p=u(h.left)<u(n.left),g=u(h.right)>u(n.right),m=u(h.top)<u(n.top),_=u(h.bottom)>u(n.bottom),v="left"===i&&p||"right"===i&&g||"top"===i&&m||"bottom"===i&&_,E=-1!==["top","bottom"].indexOf(i),y=!!e.flipVariations&&(E&&"start"===o&&p||E&&"end"===o&&g||!E&&"start"===o&&m||!E&&"end"===o&&_);(d||v||y)&&(t.flipped=!0,(d||v)&&(i=s[l+1]),y&&(o="end"===(c=o)?"start":"start"===c?"end":c),t.placement=i+(o?"-"+o:""),t.offsets.popper=it({},t.offsets.popper,ut(t.instance.popper,t.offsets.reference,t.placement)),t=pt(t.instance.modifiers,t,"flip"))}),t},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(t){var e=t.placement,n=e.split("-")[0],i=t.offsets,r=i.popper,o=i.reference,s=-1!==["left","right"].indexOf(n),a=-1===["top","left"].indexOf(n);return r[s?"left":"top"]=o[n]-(a?r[s?"width":"height"]:0),t.placement=ft(e),t.offsets.popper=rt(r),t}},hide:{order:800,enabled:!0,fn:function(t){if(!Tt(t.instance.modifiers,"hide","preventOverflow"))return t;var e=t.offsets.reference,n=dt(t.instance.modifiers,function(t){return"preventOverflow"===t.name}).boundaries;if(e.bottom<n.top||e.left>n.right||e.top>n.bottom||e.right<n.left){if(!0===t.hide)return t;t.hide=!0,t.attributes["x-out-of-boundaries"]=""}else{if(!1===t.hide)return t;t.hide=!1,t.attributes["x-out-of-boundaries"]=!1}return t}},computeStyle:{order:850,enabled:!0,fn:function(t,e){var n=e.x,i=e.y,r=t.offsets.popper,o=dt(t.instance.modifiers,function(t){return"applyStyle"===t.name}).gpuAcceleration;void 0!==o&&console.warn("WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!");var s=void 0!==o?o:e.gpuAcceleration,a=ot(Q(t.instance.popper)),l={position:r.position},c={left:Math.floor(r.left),top:Math.floor(r.top),bottom:Math.floor(r.bottom),right:Math.floor(r.right)},h="bottom"===n?"top":"bottom",f="right"===i?"left":"right",u=mt("transform"),d=void 0,p=void 0;if(p="bottom"===h?-a.height+c.bottom:c.top,d="right"===f?-a.width+c.right:c.left,s&&u)l[u]="translate3d("+d+"px, "+p+"px, 0)",l[h]=0,l[f]=0,l.willChange="transform";else{var g="bottom"===h?-1:1,m="right"===f?-1:1;l[h]=p*g,l[f]=d*m,l.willChange=h+", "+f}var _={"x-placement":t.placement};return t.attributes=it({},_,t.attributes),t.styles=it({},l,t.styles),t.arrowStyles=it({},t.offsets.arrow,t.arrowStyles),t},gpuAcceleration:!0,x:"bottom",y:"right"},applyStyle:{order:900,enabled:!0,fn:function(t){var e,n;return bt(t.instance.popper,t.styles),e=t.instance.popper,n=t.attributes,Object.keys(n).forEach(function(t){!1!==n[t]?e.setAttribute(t,n[t]):e.removeAttribute(t)}),t.arrowElement&&Object.keys(t.arrowStyles).length&&bt(t.arrowElement,t.arrowStyles),t},onLoad:function(t,e,n,i,r){var o=ct(0,e,t),s=lt(n.placement,o,e,t,n.modifiers.flip.boundariesElement,n.modifiers.flip.padding);return e.setAttribute("x-placement",s),bt(e,{position:"absolute"}),n},gpuAcceleration:void 0}}},Ot=function(){function t(e,n){var i=this,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};tt(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=U(this.update.bind(this)),this.options=it({},t.Defaults,r),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=e&&e.jquery?e[0]:e,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(it({},t.Defaults.modifiers,r.modifiers)).forEach(function(e){i.options.modifiers[e]=it({},t.Defaults.modifiers[e]||{},r.modifiers?r.modifiers[e]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(t){return it({name:t},i.options.modifiers[t])}).sort(function(t,e){return t.order-e.order}),this.modifiers.forEach(function(t){t.enabled&&B(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)}),this.update();var o=this.options.eventsEnabled;o&&this.enableEventListeners(),this.state.eventsEnabled=o}return et(t,[{key:"update",value:function(){return function(){if(!this.state.isDestroyed){var t={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};t.offsets.reference=ct(this.state,this.popper,this.reference),t.placement=lt(this.options.placement,t.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),t.originalPlacement=t.placement,t.offsets.popper=ut(this.popper,t.offsets.reference,t.placement),t.offsets.popper.position="absolute",t=pt(this.modifiers,t),this.state.isCreated?this.options.onUpdate(t):(this.state.isCreated=!0,this.options.onCreate(t))}}.call(this)}},{key:"destroy",value:function(){return function(){return this.state.isDestroyed=!0,gt(this.modifiers,"applyStyle")&&(this.popper.removeAttribute("x-placement"),this.popper.style.left="",this.popper.style.position="",this.popper.style.top="",this.popper.style[mt("transform")]=""),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}.call(this)}},{key:"enableEventListeners",value:function(){return function(){this.state.eventsEnabled||(this.state=vt(this.reference,this.options,this.state,this.scheduleUpdate))}.call(this)}},{key:"disableEventListeners",value:function(){return Et.call(this)}}]),t}();Ot.Utils=("undefined"!=typeof window?window:global).PopperUtils,Ot.placements=Ct,Ot.Defaults=St;var Nt=function(t){var e="dropdown",n="bs.dropdown",o="."+n,s=t.fn[e],a=new RegExp("38|40|27"),l={HIDE:"hide"+o,HIDDEN:"hidden"+o,SHOW:"show"+o,SHOWN:"shown"+o,CLICK:"click"+o,CLICK_DATA_API:"click"+o+".data-api",KEYDOWN_DATA_API:"keydown"+o+".data-api",KEYUP_DATA_API:"keyup"+o+".data-api"},c="disabled",h="show",f="dropup",u="dropright",d="dropleft",p="dropdown-menu-right",g="dropdown-menu-left",m="position-static",_='[data-toggle="dropdown"]',v=".dropdown form",E=".dropdown-menu",y=".navbar-nav",b=".dropdown-menu .dropdown-item:not(.disabled)",T="top-start",C="top-end",w="bottom-start",I="bottom-end",A="right-start",D="left-start",S={offset:0,flip:!0,boundary:"scrollParent"},O={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)"},N=function(){function s(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var v=s.prototype;return v.toggle=function(){if(!this._element.disabled&&!t(this._element).hasClass(c)){var e=s._getParentFromElement(this._element),n=t(this._menu).hasClass(h);if(s._clearMenus(),!n){var i={relatedTarget:this._element},r=t.Event(l.SHOW,i);if(t(e).trigger(r),!r.isDefaultPrevented()){if(!this._inNavbar){if("undefined"==typeof Ot)throw new TypeError("Bootstrap dropdown require Popper.js (https://popper.js.org)");var o=this._element;t(e).hasClass(f)&&(t(this._menu).hasClass(g)||t(this._menu).hasClass(p))&&(o=e),"scrollParent"!==this._config.boundary&&t(e).addClass(m),this._popper=new Ot(o,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===t(e).closest(y).length&&t("body").children().on("mouseover",null,t.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),t(this._menu).toggleClass(h),t(e).toggleClass(h).trigger(t.Event(l.SHOWN,i))}}}},v.dispose=function(){t.removeData(this._element,n),t(this._element).off(o),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},v.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},v._addEventListeners=function(){var e=this;t(this._element).on(l.CLICK,function(t){t.preventDefault(),t.stopPropagation(),e.toggle()})},v._getConfig=function(n){return n=r({},this.constructor.Default,t(this._element).data(),n),k.typeCheckConfig(e,n,this.constructor.DefaultType),n},v._getMenuElement=function(){if(!this._menu){var e=s._getParentFromElement(this._element);this._menu=t(e).find(E)[0]}return this._menu},v._getPlacement=function(){var e=t(this._element).parent(),n=w;return e.hasClass(f)?(n=T,t(this._menu).hasClass(p)&&(n=C)):e.hasClass(u)?n=A:e.hasClass(d)?n=D:t(this._menu).hasClass(p)&&(n=I),n},v._detectNavbar=function(){return t(this._element).closest(".navbar").length>0},v._getPopperConfig=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=r({},e.offsets,t._config.offset(e.offsets)||{}),e}:e.offset=this._config.offset,{placement:this._getPlacement(),modifiers:{offset:e,flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}}},s._jQueryInterface=function(e){return this.each(function(){var i=t(this).data(n);if(i||(i=new s(this,"object"==typeof e?e:null),t(this).data(n,i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}})},s._clearMenus=function(e){if(!e||3!==e.which&&("keyup"!==e.type||9===e.which))for(var i=t.makeArray(t(_)),r=0;r<i.length;r++){var o=s._getParentFromElement(i[r]),a=t(i[r]).data(n),c={relatedTarget:i[r]};if(a){var f=a._menu;if(t(o).hasClass(h)&&!(e&&("click"===e.type&&/input|textarea/i.test(e.target.tagName)||"keyup"===e.type&&9===e.which)&&t.contains(o,e.target))){var u=t.Event(l.HIDE,c);t(o).trigger(u),u.isDefaultPrevented()||("ontouchstart"in document.documentElement&&t("body").children().off("mouseover",null,t.noop),i[r].setAttribute("aria-expanded","false"),t(f).removeClass(h),t(o).removeClass(h).trigger(t.Event(l.HIDDEN,c)))}}}},s._getParentFromElement=function(e){var n,i=k.getSelectorFromElement(e);return i&&(n=t(i)[0]),n||e.parentNode},s._dataApiKeydownHandler=function(e){if((/input|textarea/i.test(e.target.tagName)?!(32===e.which||27!==e.which&&(40!==e.which&&38!==e.which||t(e.target).closest(E).length)):a.test(e.which))&&(e.preventDefault(),e.stopPropagation(),!this.disabled&&!t(this).hasClass(c))){var n=s._getParentFromElement(this),i=t(n).hasClass(h);if((i||27===e.which&&32===e.which)&&(!i||27!==e.which&&32!==e.which)){var r=t(n).find(b).get();if(0!==r.length){var o=r.indexOf(e.target);38===e.which&&o>0&&o--,40===e.which&&o<r.length-1&&o++,o<0&&(o=0),r[o].focus()}}else{if(27===e.which){var l=t(n).find(_)[0];t(l).trigger("focus")}t(this).trigger("click")}}},i(s,null,[{key:"VERSION",get:function(){return"4.0.0"}},{key:"Default",get:function(){return S}},{key:"DefaultType",get:function(){return O}}]),s}();return t(document).on(l.KEYDOWN_DATA_API,_,N._dataApiKeydownHandler).on(l.KEYDOWN_DATA_API,E,N._dataApiKeydownHandler).on(l.CLICK_DATA_API+" "+l.KEYUP_DATA_API,N._clearMenus).on(l.CLICK_DATA_API,_,function(e){e.preventDefault(),e.stopPropagation(),N._jQueryInterface.call(t(this),"toggle")}).on(l.CLICK_DATA_API,v,function(t){t.stopPropagation()}),t.fn[e]=N._jQueryInterface,t.fn[e].Constructor=N,t.fn[e].noConflict=function(){return t.fn[e]=s,N._jQueryInterface},N}(e),kt=function(t){var e="bs.modal",n="."+e,o=t.fn.modal,s={backdrop:!0,keyboard:!0,focus:!0,show:!0},a={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},l={HIDE:"hide"+n,HIDDEN:"hidden"+n,SHOW:"show"+n,SHOWN:"shown"+n,FOCUSIN:"focusin"+n,RESIZE:"resize"+n,CLICK_DISMISS:"click.dismiss"+n,KEYDOWN_DISMISS:"keydown.dismiss"+n,MOUSEUP_DISMISS:"mouseup.dismiss"+n,MOUSEDOWN_DISMISS:"mousedown.dismiss"+n,CLICK_DATA_API:"click.bs.modal.data-api"},c="modal-scrollbar-measure",h="modal-backdrop",f="modal-open",u="fade",d="show",p={DIALOG:".modal-dialog",DATA_TOGGLE:'[data-toggle="modal"]',DATA_DISMISS:'[data-dismiss="modal"]',FIXED_CONTENT:".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",STICKY_CONTENT:".sticky-top",NAVBAR_TOGGLER:".navbar-toggler"},g=function(){function o(e,n){this._config=this._getConfig(n),this._element=e,this._dialog=t(e).find(p.DIALOG)[0],this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._originalBodyPadding=0,this._scrollbarWidth=0}var g=o.prototype;return g.toggle=function(t){return this._isShown?this.hide():this.show(t)},g.show=function(e){var n=this;if(!this._isTransitioning&&!this._isShown){k.supportsTransitionEnd()&&t(this._element).hasClass(u)&&(this._isTransitioning=!0);var i=t.Event(l.SHOW,{relatedTarget:e});t(this._element).trigger(i),this._isShown||i.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),t(document.body).addClass(f),this._setEscapeEvent(),this._setResizeEvent(),t(this._element).on(l.CLICK_DISMISS,p.DATA_DISMISS,function(t){return n.hide(t)}),t(this._dialog).on(l.MOUSEDOWN_DISMISS,function(){t(n._element).one(l.MOUSEUP_DISMISS,function(e){t(e.target).is(n._element)&&(n._ignoreBackdropClick=!0)})}),this._showBackdrop(function(){return n._showElement(e)}))}},g.hide=function(e){var n=this;if(e&&e.preventDefault(),!this._isTransitioning&&this._isShown){var i=t.Event(l.HIDE);if(t(this._element).trigger(i),this._isShown&&!i.isDefaultPrevented()){this._isShown=!1;var r=k.supportsTransitionEnd()&&t(this._element).hasClass(u);r&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),t(document).off(l.FOCUSIN),t(this._element).removeClass(d),t(this._element).off(l.CLICK_DISMISS),t(this._dialog).off(l.MOUSEDOWN_DISMISS),r?t(this._element).one(k.TRANSITION_END,function(t){return n._hideModal(t)}).emulateTransitionEnd(300):this._hideModal()}}},g.dispose=function(){t.removeData(this._element,e),t(window,document,this._element,this._backdrop).off(n),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._scrollbarWidth=null},g.handleUpdate=function(){this._adjustDialog()},g._getConfig=function(t){return t=r({},s,t),k.typeCheckConfig("modal",t,a),t},g._showElement=function(e){var n=this,i=k.supportsTransitionEnd()&&t(this._element).hasClass(u);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.scrollTop=0,i&&k.reflow(this._element),t(this._element).addClass(d),this._config.focus&&this._enforceFocus();var r=t.Event(l.SHOWN,{relatedTarget:e}),o=function(){n._config.focus&&n._element.focus(),n._isTransitioning=!1,t(n._element).trigger(r)};i?t(this._dialog).one(k.TRANSITION_END,o).emulateTransitionEnd(300):o()},g._enforceFocus=function(){var e=this;t(document).off(l.FOCUSIN).on(l.FOCUSIN,function(n){document!==n.target&&e._element!==n.target&&0===t(e._element).has(n.target).length&&e._element.focus()})},g._setEscapeEvent=function(){var e=this;this._isShown&&this._config.keyboard?t(this._element).on(l.KEYDOWN_DISMISS,function(t){27===t.which&&(t.preventDefault(),e.hide())}):this._isShown||t(this._element).off(l.KEYDOWN_DISMISS)},g._setResizeEvent=function(){var e=this;this._isShown?t(window).on(l.RESIZE,function(t){return e.handleUpdate(t)}):t(window).off(l.RESIZE)},g._hideModal=function(){var e=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._isTransitioning=!1,this._showBackdrop(function(){t(document.body).removeClass(f),e._resetAdjustments(),e._resetScrollbar(),t(e._element).trigger(l.HIDDEN)})},g._removeBackdrop=function(){this._backdrop&&(t(this._backdrop).remove(),this._backdrop=null)},g._showBackdrop=function(e){var n=this,i=t(this._element).hasClass(u)?u:"";if(this._isShown&&this._config.backdrop){var r=k.supportsTransitionEnd()&&i;if(this._backdrop=document.createElement("div"),this._backdrop.className=h,i&&t(this._backdrop).addClass(i),t(this._backdrop).appendTo(document.body),t(this._element).on(l.CLICK_DISMISS,function(t){n._ignoreBackdropClick?n._ignoreBackdropClick=!1:t.target===t.currentTarget&&("static"===n._config.backdrop?n._element.focus():n.hide())}),r&&k.reflow(this._backdrop),t(this._backdrop).addClass(d),!e)return;if(!r)return void e();t(this._backdrop).one(k.TRANSITION_END,e).emulateTransitionEnd(150)}else if(!this._isShown&&this._backdrop){t(this._backdrop).removeClass(d);var o=function(){n._removeBackdrop(),e&&e()};k.supportsTransitionEnd()&&t(this._element).hasClass(u)?t(this._backdrop).one(k.TRANSITION_END,o).emulateTransitionEnd(150):o()}else e&&e()},g._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},g._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},g._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},g._setScrollbar=function(){var e=this;if(this._isBodyOverflowing){t(p.FIXED_CONTENT).each(function(n,i){var r=t(i)[0].style.paddingRight,o=t(i).css("padding-right");t(i).data("padding-right",r).css("padding-right",parseFloat(o)+e._scrollbarWidth+"px")}),t(p.STICKY_CONTENT).each(function(n,i){var r=t(i)[0].style.marginRight,o=t(i).css("margin-right");t(i).data("margin-right",r).css("margin-right",parseFloat(o)-e._scrollbarWidth+"px")}),t(p.NAVBAR_TOGGLER).each(function(n,i){var r=t(i)[0].style.marginRight,o=t(i).css("margin-right");t(i).data("margin-right",r).css("margin-right",parseFloat(o)+e._scrollbarWidth+"px")});var n=document.body.style.paddingRight,i=t("body").css("padding-right");t("body").data("padding-right",n).css("padding-right",parseFloat(i)+this._scrollbarWidth+"px")}},g._resetScrollbar=function(){t(p.FIXED_CONTENT).each(function(e,n){var i=t(n).data("padding-right");"undefined"!=typeof i&&t(n).css("padding-right",i).removeData("padding-right")}),t(p.STICKY_CONTENT+", "+p.NAVBAR_TOGGLER).each(function(e,n){var i=t(n).data("margin-right");"undefined"!=typeof i&&t(n).css("margin-right",i).removeData("margin-right")});var e=t("body").data("padding-right");"undefined"!=typeof e&&t("body").css("padding-right",e).removeData("padding-right")},g._getScrollbarWidth=function(){var t=document.createElement("div");t.className=c,document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},o._jQueryInterface=function(n,i){return this.each(function(){var s=t(this).data(e),a=r({},o.Default,t(this).data(),"object"==typeof n&&n);if(s||(s=new o(this,a),t(this).data(e,s)),"string"==typeof n){if("undefined"==typeof s[n])throw new TypeError('No method named "'+n+'"');s[n](i)}else a.show&&s.show(i)})},i(o,null,[{key:"VERSION",get:function(){return"4.0.0"}},{key:"Default",get:function(){return s}}]),o}();return t(document).on(l.CLICK_DATA_API,p.DATA_TOGGLE,function(n){var i,o=this,s=k.getSelectorFromElement(this);s&&(i=t(s)[0]);var a=t(i).data(e)?"toggle":r({},t(i).data(),t(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||n.preventDefault();var c=t(i).one(l.SHOW,function(e){e.isDefaultPrevented()||c.one(l.HIDDEN,function(){t(o).is(":visible")&&o.focus()})});g._jQueryInterface.call(t(i),a,this)}),t.fn.modal=g._jQueryInterface,t.fn.modal.Constructor=g,t.fn.modal.noConflict=function(){return t.fn.modal=o,g._jQueryInterface},g}(e),Lt=function(t){var e="tooltip",n="bs.tooltip",o="."+n,s=t.fn[e],a=new RegExp("(^|\\s)bs-tooltip\\S+","g"),l={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)"},c={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},h={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent"},f="show",u="out",d={HIDE:"hide"+o,HIDDEN:"hidden"+o,SHOW:"show"+o,SHOWN:"shown"+o,INSERTED:"inserted"+o,CLICK:"click"+o,FOCUSIN:"focusin"+o,FOCUSOUT:"focusout"+o,MOUSEENTER:"mouseenter"+o,MOUSELEAVE:"mouseleave"+o},p="fade",g="show",m=".tooltip-inner",_=".arrow",v="hover",E="focus",y="click",b="manual",T=function(){function s(t,e){if("undefined"==typeof Ot)throw new TypeError("Bootstrap tooltips require Popper.js (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var T=s.prototype;return T.enable=function(){this._isEnabled=!0},T.disable=function(){this._isEnabled=!1},T.toggleEnabled=function(){this._isEnabled=!this._isEnabled},T.toggle=function(e){if(this._isEnabled)if(e){var n=this.constructor.DATA_KEY,i=t(e.currentTarget).data(n);i||(i=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(n,i)),i._activeTrigger.click=!i._activeTrigger.click,i._isWithActiveTrigger()?i._enter(null,i):i._leave(null,i)}else{if(t(this.getTipElement()).hasClass(g))return void this._leave(null,this);this._enter(null,this)}},T.dispose=function(){clearTimeout(this._timeout),t.removeData(this.element,this.constructor.DATA_KEY),t(this.element).off(this.constructor.EVENT_KEY),t(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&t(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,null!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},T.show=function(){var e=this;if("none"===t(this.element).css("display"))throw new Error("Please use show on visible elements");var n=t.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){t(this.element).trigger(n);var i=t.contains(this.element.ownerDocument.documentElement,this.element);if(n.isDefaultPrevented()||!i)return;var r=this.getTipElement(),o=k.getUID(this.constructor.NAME);r.setAttribute("id",o),this.element.setAttribute("aria-describedby",o),this.setContent(),this.config.animation&&t(r).addClass(p);var a="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,l=this._getAttachment(a);this.addAttachmentClass(l);var c=!1===this.config.container?document.body:t(this.config.container);t(r).data(this.constructor.DATA_KEY,this),t.contains(this.element.ownerDocument.documentElement,this.tip)||t(r).appendTo(c),t(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new Ot(this.element,r,{placement:l,modifiers:{offset:{offset:this.config.offset},flip:{behavior:this.config.fallbackPlacement},arrow:{element:_},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){e._handlePopperPlacementChange(t)}}),t(r).addClass(g),"ontouchstart"in document.documentElement&&t("body").children().on("mouseover",null,t.noop);var h=function(){e.config.animation&&e._fixTransition();var n=e._hoverState;e._hoverState=null,t(e.element).trigger(e.constructor.Event.SHOWN),n===u&&e._leave(null,e)};k.supportsTransitionEnd()&&t(this.tip).hasClass(p)?t(this.tip).one(k.TRANSITION_END,h).emulateTransitionEnd(s._TRANSITION_DURATION):h()}},T.hide=function(e){var n=this,i=this.getTipElement(),r=t.Event(this.constructor.Event.HIDE),o=function(){n._hoverState!==f&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),t(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()};t(this.element).trigger(r),r.isDefaultPrevented()||(t(i).removeClass(g),"ontouchstart"in document.documentElement&&t("body").children().off("mouseover",null,t.noop),this._activeTrigger[y]=!1,this._activeTrigger[E]=!1,this._activeTrigger[v]=!1,k.supportsTransitionEnd()&&t(this.tip).hasClass(p)?t(i).one(k.TRANSITION_END,o).emulateTransitionEnd(150):o(),this._hoverState="")},T.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},T.isWithContent=function(){return Boolean(this.getTitle())},T.addAttachmentClass=function(e){t(this.getTipElement()).addClass("bs-tooltip-"+e)},T.getTipElement=function(){return this.tip=this.tip||t(this.config.template)[0],this.tip},T.setContent=function(){var e=t(this.getTipElement());this.setElementContent(e.find(m),this.getTitle()),e.removeClass(p+" "+g)},T.setElementContent=function(e,n){var i=this.config.html;"object"==typeof n&&(n.nodeType||n.jquery)?i?t(n).parent().is(e)||e.empty().append(n):e.text(t(n).text()):e[i?"html":"text"](n)},T.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},T._getAttachment=function(t){return c[t.toUpperCase()]},T._setListeners=function(){var e=this;this.config.trigger.split(" ").forEach(function(n){if("click"===n)t(e.element).on(e.constructor.Event.CLICK,e.config.selector,function(t){return e.toggle(t)});else if(n!==b){var i=n===v?e.constructor.Event.MOUSEENTER:e.constructor.Event.FOCUSIN,r=n===v?e.constructor.Event.MOUSELEAVE:e.constructor.Event.FOCUSOUT;t(e.element).on(i,e.config.selector,function(t){return e._enter(t)}).on(r,e.config.selector,function(t){return e._leave(t)})}t(e.element).closest(".modal").on("hide.bs.modal",function(){return e.hide()})}),this.config.selector?this.config=r({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},T._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},T._enter=function(e,n){var i=this.constructor.DATA_KEY;(n=n||t(e.currentTarget).data(i))||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(i,n)),e&&(n._activeTrigger["focusin"===e.type?E:v]=!0),t(n.getTipElement()).hasClass(g)||n._hoverState===f?n._hoverState=f:(clearTimeout(n._timeout),n._hoverState=f,n.config.delay&&n.config.delay.show?n._timeout=setTimeout(function(){n._hoverState===f&&n.show()},n.config.delay.show):n.show())},T._leave=function(e,n){var i=this.constructor.DATA_KEY;(n=n||t(e.currentTarget).data(i))||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(i,n)),e&&(n._activeTrigger["focusout"===e.type?E:v]=!1),n._isWithActiveTrigger()||(clearTimeout(n._timeout),n._hoverState=u,n.config.delay&&n.config.delay.hide?n._timeout=setTimeout(function(){n._hoverState===u&&n.hide()},n.config.delay.hide):n.hide())},T._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},T._getConfig=function(n){return"number"==typeof(n=r({},this.constructor.Default,t(this.element).data(),n)).delay&&(n.delay={show:n.delay,hide:n.delay}),"number"==typeof n.title&&(n.title=n.title.toString()),"number"==typeof n.content&&(n.content=n.content.toString()),k.typeCheckConfig(e,n,this.constructor.DefaultType),n},T._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},T._cleanTipClass=function(){var e=t(this.getTipElement()),n=e.attr("class").match(a);null!==n&&n.length>0&&e.removeClass(n.join(""))},T._handlePopperPlacementChange=function(t){this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},T._fixTransition=function(){var e=this.getTipElement(),n=this.config.animation;null===e.getAttribute("x-placement")&&(t(e).removeClass(p),this.config.animation=!1,this.hide(),this.show(),this.config.animation=n)},s._jQueryInterface=function(e){return this.each(function(){var i=t(this).data(n),r="object"==typeof e&&e;if((i||!/dispose|hide/.test(e))&&(i||(i=new s(this,r),t(this).data(n,i)),"string"==typeof e)){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}})},i(s,null,[{key:"VERSION",get:function(){return"4.0.0"}},{key:"Default",get:function(){return h}},{key:"NAME",get:function(){return e}},{key:"DATA_KEY",get:function(){return n}},{key:"Event",get:function(){return d}},{key:"EVENT_KEY",get:function(){return o}},{key:"DefaultType",get:function(){return l}}]),s}();return t.fn[e]=T._jQueryInterface,t.fn[e].Constructor=T,t.fn[e].noConflict=function(){return t.fn[e]=s,T._jQueryInterface},T}(e),Pt=function(t){var e="popover",n="bs.popover",o="."+n,s=t.fn[e],a=new RegExp("(^|\\s)bs-popover\\S+","g"),l=r({},Lt.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),c=r({},Lt.DefaultType,{content:"(string|element|function)"}),h="fade",f="show",u=".popover-header",d=".popover-body",p={HIDE:"hide"+o,HIDDEN:"hidden"+o,SHOW:"show"+o,SHOWN:"shown"+o,INSERTED:"inserted"+o,CLICK:"click"+o,FOCUSIN:"focusin"+o,FOCUSOUT:"focusout"+o,MOUSEENTER:"mouseenter"+o,MOUSELEAVE:"mouseleave"+o},g=function(r){var s,g;function m(){return r.apply(this,arguments)||this}g=r,(s=m).prototype=Object.create(g.prototype),s.prototype.constructor=s,s.__proto__=g;var _=m.prototype;return _.isWithContent=function(){return this.getTitle()||this._getContent()},_.addAttachmentClass=function(e){t(this.getTipElement()).addClass("bs-popover-"+e)},_.getTipElement=function(){return this.tip=this.tip||t(this.config.template)[0],this.tip},_.setContent=function(){var e=t(this.getTipElement());this.setElementContent(e.find(u),this.getTitle());var n=this._getContent();"function"==typeof n&&(n=n.call(this.element)),this.setElementContent(e.find(d),n),e.removeClass(h+" "+f)},_._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},_._cleanTipClass=function(){var e=t(this.getTipElement()),n=e.attr("class").match(a);null!==n&&n.length>0&&e.removeClass(n.join(""))},m._jQueryInterface=function(e){return this.each(function(){var i=t(this).data(n),r="object"==typeof e?e:null;if((i||!/destroy|hide/.test(e))&&(i||(i=new m(this,r),t(this).data(n,i)),"string"==typeof e)){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}})},i(m,null,[{key:"VERSION",get:function(){return"4.0.0"}},{key:"Default",get:function(){return l}},{key:"NAME",get:function(){return e}},{key:"DATA_KEY",get:function(){return n}},{key:"Event",get:function(){return p}},{key:"EVENT_KEY",get:function(){return o}},{key:"DefaultType",get:function(){return c}}]),m}(Lt);return t.fn[e]=g._jQueryInterface,t.fn[e].Constructor=g,t.fn[e].noConflict=function(){return t.fn[e]=s,g._jQueryInterface},g}(e),xt=function(t){var e="scrollspy",n="bs.scrollspy",o="."+n,s=t.fn[e],a={offset:10,method:"auto",target:""},l={offset:"number",method:"string",target:"(string|element)"},c={ACTIVATE:"activate"+o,SCROLL:"scroll"+o,LOAD_DATA_API:"load"+o+".data-api"},h="dropdown-item",f="active",u={DATA_SPY:'[data-spy="scroll"]',ACTIVE:".active",NAV_LIST_GROUP:".nav, .list-group",NAV_LINKS:".nav-link",NAV_ITEMS:".nav-item",LIST_ITEMS:".list-group-item",DROPDOWN:".dropdown",DROPDOWN_ITEMS:".dropdown-item",DROPDOWN_TOGGLE:".dropdown-toggle"},d="offset",p="position",g=function(){function s(e,n){var i=this;this._element=e,this._scrollElement="BODY"===e.tagName?window:e,this._config=this._getConfig(n),this._selector=this._config.target+" "+u.NAV_LINKS+","+this._config.target+" "+u.LIST_ITEMS+","+this._config.target+" "+u.DROPDOWN_ITEMS,this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,t(this._scrollElement).on(c.SCROLL,function(t){return i._process(t)}),this.refresh(),this._process()}var g=s.prototype;return g.refresh=function(){var e=this,n=this._scrollElement===this._scrollElement.window?d:p,i="auto"===this._config.method?n:this._config.method,r=i===p?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),t.makeArray(t(this._selector)).map(function(e){var n,o=k.getSelectorFromElement(e);if(o&&(n=t(o)[0]),n){var s=n.getBoundingClientRect();if(s.width||s.height)return[t(n)[i]().top+r,o]}return null}).filter(function(t){return t}).sort(function(t,e){return t[0]-e[0]}).forEach(function(t){e._offsets.push(t[0]),e._targets.push(t[1])})},g.dispose=function(){t.removeData(this._element,n),t(this._scrollElement).off(o),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},g._getConfig=function(n){if("string"!=typeof(n=r({},a,n)).target){var i=t(n.target).attr("id");i||(i=k.getUID(e),t(n.target).attr("id",i)),n.target="#"+i}return k.typeCheckConfig(e,n,l),n},g._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},g._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},g._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},g._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var r=this._offsets.length;r--;){this._activeTarget!==this._targets[r]&&t>=this._offsets[r]&&("undefined"==typeof this._offsets[r+1]||t<this._offsets[r+1])&&this._activate(this._targets[r])}}},g._activate=function(e){this._activeTarget=e,this._clear();var n=this._selector.split(",");n=n.map(function(t){return t+'[data-target="'+e+'"],'+t+'[href="'+e+'"]'});var i=t(n.join(","));i.hasClass(h)?(i.closest(u.DROPDOWN).find(u.DROPDOWN_TOGGLE).addClass(f),i.addClass(f)):(i.addClass(f),i.parents(u.NAV_LIST_GROUP).prev(u.NAV_LINKS+", "+u.LIST_ITEMS).addClass(f),i.parents(u.NAV_LIST_GROUP).prev(u.NAV_ITEMS).children(u.NAV_LINKS).addClass(f)),t(this._scrollElement).trigger(c.ACTIVATE,{relatedTarget:e})},g._clear=function(){t(this._selector).filter(u.ACTIVE).removeClass(f)},s._jQueryInterface=function(e){return this.each(function(){var i=t(this).data(n);if(i||(i=new s(this,"object"==typeof e&&e),t(this).data(n,i)),"string"==typeof e){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}})},i(s,null,[{key:"VERSION",get:function(){return"4.0.0"}},{key:"Default",get:function(){return a}}]),s}();return t(window).on(c.LOAD_DATA_API,function(){for(var e=t.makeArray(t(u.DATA_SPY)),n=e.length;n--;){var i=t(e[n]);g._jQueryInterface.call(i,i.data())}}),t.fn[e]=g._jQueryInterface,t.fn[e].Constructor=g,t.fn[e].noConflict=function(){return t.fn[e]=s,g._jQueryInterface},g}(e),Rt=function(t){var e=".bs.tab",n=t.fn.tab,r={HIDE:"hide"+e,HIDDEN:"hidden"+e,SHOW:"show"+e,SHOWN:"shown"+e,CLICK_DATA_API:"click.bs.tab.data-api"},o="dropdown-menu",s="active",a="disabled",l="fade",c="show",h=".dropdown",f=".nav, .list-group",u=".active",d="> li > .active",p='[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',g=".dropdown-toggle",m="> .dropdown-menu .active",_=function(){function e(t){this._element=t}var n=e.prototype;return n.show=function(){var e=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&t(this._element).hasClass(s)||t(this._element).hasClass(a))){var n,i,o=t(this._element).closest(f)[0],l=k.getSelectorFromElement(this._element);if(o){var c="UL"===o.nodeName?d:u;i=(i=t.makeArray(t(o).find(c)))[i.length-1]}var h=t.Event(r.HIDE,{relatedTarget:this._element}),p=t.Event(r.SHOW,{relatedTarget:i});if(i&&t(i).trigger(h),t(this._element).trigger(p),!p.isDefaultPrevented()&&!h.isDefaultPrevented()){l&&(n=t(l)[0]),this._activate(this._element,o);var g=function(){var n=t.Event(r.HIDDEN,{relatedTarget:e._element}),o=t.Event(r.SHOWN,{relatedTarget:i});t(i).trigger(n),t(e._element).trigger(o)};n?this._activate(n,n.parentNode,g):g()}}},n.dispose=function(){t.removeData(this._element,"bs.tab"),this._element=null},n._activate=function(e,n,i){var r=this,o=("UL"===n.nodeName?t(n).find(d):t(n).children(u))[0],s=i&&k.supportsTransitionEnd()&&o&&t(o).hasClass(l),a=function(){return r._transitionComplete(e,o,i)};o&&s?t(o).one(k.TRANSITION_END,a).emulateTransitionEnd(150):a()},n._transitionComplete=function(e,n,i){if(n){t(n).removeClass(c+" "+s);var r=t(n.parentNode).find(m)[0];r&&t(r).removeClass(s),"tab"===n.getAttribute("role")&&n.setAttribute("aria-selected",!1)}if(t(e).addClass(s),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!0),k.reflow(e),t(e).addClass(c),e.parentNode&&t(e.parentNode).hasClass(o)){var a=t(e).closest(h)[0];a&&t(a).find(g).addClass(s),e.setAttribute("aria-expanded",!0)}i&&i()},e._jQueryInterface=function(n){return this.each(function(){var i=t(this),r=i.data("bs.tab");if(r||(r=new e(this),i.data("bs.tab",r)),"string"==typeof n){if("undefined"==typeof r[n])throw new TypeError('No method named "'+n+'"');r[n]()}})},i(e,null,[{key:"VERSION",get:function(){return"4.0.0"}}]),e}();return t(document).on(r.CLICK_DATA_API,p,function(e){e.preventDefault(),_._jQueryInterface.call(t(this),"show")}),t.fn.tab=_._jQueryInterface,t.fn.tab.Constructor=_,t.fn.tab.noConflict=function(){return t.fn.tab=n,_._jQueryInterface},_}(e);!function(t){if("undefined"==typeof t)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var e=t.fn.jquery.split(" ")[0].split(".");if(e[0]<2&&e[1]<9||1===e[0]&&9===e[1]&&e[2]<1||e[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}(e),t.Util=k,t.Alert=L,t.Button=P,t.Carousel=x,t.Collapse=R,t.Dropdown=Nt,t.Modal=kt,t.Popover=Pt,t.Scrollspy=xt,t.Tab=Rt,t.Tooltip=Lt,Object.defineProperty(t,"__esModule",{value:!0})}); +//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/web2py/applications/SP/static/js/bootstrap.bundle.min.js.map b/web2py/applications/SP/static/js/bootstrap.bundle.min.js.map new file mode 100644 index 0000000..c234ff2 --- /dev/null +++ b/web2py/applications/SP/static/js/bootstrap.bundle.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../../rollupPluginBabelHelpers","../../node_modules/popper.js/dist/esm/popper.js","../../js/src/util.js","../../js/src/alert.js","../../js/src/button.js","../../js/src/carousel.js","../../js/src/collapse.js","../../js/src/dropdown.js","../../js/src/modal.js","../../js/src/tooltip.js","../../js/src/popover.js","../../js/src/scrollspy.js","../../js/src/tab.js","../../js/src/index.js"],"names":["_defineProperties","target","props","i","length","descriptor","enumerable","configurable","writable","Object","defineProperty","key","_createClass","Constructor","protoProps","staticProps","prototype","_extends","assign","arguments","source","hasOwnProperty","call","apply","this","$","NAME","DATA_KEY","EVENT_KEY","JQUERY_NO_CONFLICT","Event","ClassName","Alert","DATA_API_KEY","Selector","Button","Util","transition","transitionEndEmulator","duration","called","one","TRANSITION_END","triggerTransitionEnd","_this","prefix","Math","random","document","getElementById","element","selector","getAttribute","charAt","escapeSelector","substr","replace","find","err","offsetHeight","trigger","end","Boolean","obj","nodeType","componentName","config","configTypes","property","expectedTypes","value","valueType","isElement","toString","match","toLowerCase","RegExp","test","Error","toUpperCase","window","QUnit","fn","emulateTransitionEnd","supportsTransitionEnd","event","special","is","handleObj","handler","_element","close","rootElement","_getRootElement","_triggerCloseEvent","isDefaultPrevented","_removeElement","dispose","removeData","getSelectorFromElement","parent","closest","closeEvent","CLOSE","removeClass","hasClass","_destroyElement","detach","CLOSED","remove","_jQueryInterface","each","$element","data","_handleDismiss","alertInstance","preventDefault","on","CLICK_DATA_API","noConflict","toggle","triggerChangeEvent","addAriaPressed","input","type","checked","activeElement","hasAttribute","classList","contains","focus","setAttribute","toggleClass","button","FOCUS_BLUR_DATA_API","Carousel","Default","DefaultType","Direction","_items","_interval","_activeElement","_isPaused","_isSliding","touchTimeout","_config","_getConfig","_indicatorsElement","INDICATORS","_addEventListeners","next","_slide","nextWhenVisible","hidden","css","prev","pause","NEXT_PREV","cycle","interval","setInterval","visibilityState","bind","to","index","ACTIVE_ITEM","activeIndex","_getItemIndex","SLID","direction","off","typeCheckConfig","keyboard","KEYDOWN","_this2","_keydown","MOUSEENTER","MOUSELEAVE","documentElement","TOUCHEND","setTimeout","tagName","which","makeArray","ITEM","indexOf","_getItemByDirection","isNextDirection","isPrevDirection","lastItemIndex","wrap","itemIndex","_triggerSlideEvent","relatedTarget","eventDirectionName","targetIndex","fromIndex","slideEvent","SLIDE","_setActiveIndicatorElement","ACTIVE","nextIndicator","children","addClass","directionalClassName","orderClassName","activeElementIndex","nextElement","nextElementIndex","isCycling","slidEvent","reflow","_this3","action","slide","TypeError","_dataApiClickHandler","slideIndex","DATA_SLIDE","LOAD_DATA_API","DATA_RIDE","$carousel","Collapse","Dimension","_isTransitioning","_triggerArray","id","tabToggles","DATA_TOGGLE","elem","filter","_selector","push","_parent","_getParent","_addAriaAndCollapsedClass","hide","show","actives","activesData","ACTIVES","not","startEvent","SHOW","dimension","_getDimension","style","attr","setTransitioning","complete","SHOWN","scrollSize","slice","HIDE","getBoundingClientRect","HIDDEN","isTransitioning","jquery","_getTargetFromElement","triggerArray","isOpen","$this","currentTarget","$trigger","$target","isBrowser","longerTimeoutBrowsers","timeoutDuration","navigator","userAgent","debounce","Promise","resolve","then","scheduled","isFunction","functionToCheck","getStyleComputedProperty","getComputedStyle","getParentNode","nodeName","parentNode","host","getScrollParent","body","ownerDocument","_getStyleComputedProp","overflow","overflowX","overflowY","getOffsetParent","offsetParent","getRoot","node","findCommonOffsetParent","element1","element2","order","compareDocumentPosition","Node","DOCUMENT_POSITION_FOLLOWING","start","range","createRange","setStart","setEnd","commonAncestorContainer","firstElementChild","element1root","getScroll","upperSide","undefined","html","scrollingElement","getBordersSize","styles","axis","sideA","sideB","parseFloat","isIE10","isIE10$1","appVersion","getSize","computedStyle","max","getWindowSizes","height","width","classCallCheck","instance","createClass","defineProperties","getClientRect","offsets","right","left","bottom","top","rect","scrollTop","scrollLeft","result","sizes","clientWidth","clientHeight","horizScrollbar","offsetWidth","vertScrollbar","getOffsetRectRelativeToArbitraryNode","isHTML","childrenRect","parentRect","scrollParent","borderTopWidth","borderLeftWidth","marginTop","marginLeft","subtract","modifier","includeScroll","getBoundaries","popper","reference","padding","boundariesElement","relativeOffset","boundaries","innerWidth","innerHeight","boundariesNode","isFixed","_getWindowSizes","computeAutoPlacement","placement","refRect","rects","sortedAreas","keys","map","area","_ref","sort","a","b","filteredAreas","_ref2","computedPlacement","variation","split","getReferenceOffsets","state","getOuterSizes","x","marginBottom","y","marginRight","getOppositePlacement","hash","matched","getPopperOffsets","referenceOffsets","popperRect","popperOffsets","isHoriz","mainSide","secondarySide","measurement","secondaryMeasurement","arr","check","Array","runModifiers","modifiers","ends","prop","findIndex","cur","forEach","console","warn","enabled","isModifierEnabled","modifierName","some","name","getSupportedPropertyName","prefixes","upperProp","toCheck","getWindow","defaultView","setupEventListeners","options","updateBound","addEventListener","passive","scrollElement","attachToScrollParents","callback","scrollParents","isBody","eventsEnabled","disableEventListeners","cancelAnimationFrame","scheduleUpdate","removeEventListener","isNumeric","n","isNaN","isFinite","setStyles","unit","isModifierRequired","requestingName","requestedName","requesting","isRequired","_requesting","requested","placements","validPlacements","clockwise","counter","concat","reverse","BEHAVIORS","FLIP","CLOCKWISE","COUNTERCLOCKWISE","parseOffset","offset","basePlacement","useHeight","fragments","frag","trim","divider","search","splitRegex","ops","op","mergeWithPrevious","reduce","str","toValue","index2","Defaults","removeOnDestroy","onCreate","onUpdate","shift","shiftvariation","_data$offsets","isVertical","side","shiftOffsets","preventOverflow","priority","primary","escapeWithReference","secondary","min","keepTogether","floor","opSide","arrow","_data$offsets$arrow","arrowElement","querySelector","len","sideCapitalized","altSide","arrowElementSize","center","popperMarginSide","popperBorderSide","sideValue","round","flip","flipped","originalPlacement","placementOpposite","flipOrder","behavior","step","refOffsets","overlapsRef","overflowsLeft","overflowsRight","overflowsTop","overflowsBottom","overflowsBoundaries","flippedVariation","flipVariations","inner","subtractLength","bound","attributes","computeStyle","legacyGpuAccelerationOption","gpuAcceleration","offsetParentRect","position","prefixedProperty","willChange","invertTop","invertLeft","x-placement","arrowStyles","applyStyle","removeAttribute","onLoad","modifierOptions","Popper","requestAnimationFrame","update","isDestroyed","isCreated","enableEventListeners","removeChild","Utils","global","PopperUtils","Dropdown","REGEXP_KEYDOWN","ARROW_UP_KEYCODE","AttachmentMap","_popper","_menu","_getMenuElement","_inNavbar","_detectNavbar","disabled","_getParentFromElement","isActive","_clearMenus","showEvent","boundary","_getPopperConfig","noop","destroy","CLICK","stopPropagation","constructor","_getPlacement","$parentDropdown","offsetConf","toggles","context","dropdownMenu","hideEvent","_dataApiKeydownHandler","items","get","KEYDOWN_DATA_API","KEYUP_DATA_API","e","Modal","_dialog","DIALOG","_backdrop","_isShown","_isBodyOverflowing","_ignoreBackdropClick","_originalBodyPadding","_scrollbarWidth","_checkScrollbar","_setScrollbar","_adjustDialog","_setEscapeEvent","_setResizeEvent","CLICK_DISMISS","DATA_DISMISS","MOUSEDOWN_DISMISS","MOUSEUP_DISMISS","_showBackdrop","_showElement","FOCUSIN","_hideModal","handleUpdate","ELEMENT_NODE","appendChild","display","_enforceFocus","shownEvent","transitionComplete","_this4","has","KEYDOWN_DISMISS","RESIZE","_this6","_resetAdjustments","_resetScrollbar","_this7","_removeBackdrop","animate","backdrop","doAnimate","createElement","className","appendTo","_this8","callbackRemove","isModalOverflowing","scrollHeight","paddingLeft","paddingRight","_getScrollbarWidth","FIXED_CONTENT","actualPadding","calculatedPadding","_this9","STICKY_CONTENT","actualMargin","calculatedMargin","NAVBAR_TOGGLER","margin","scrollDiv","scrollbarWidth","Tooltip","BSCLS_PREFIX_REGEX","HoverState","Trigger","_isEnabled","_timeout","_hoverState","_activeTrigger","tip","_setListeners","enable","disable","toggleEnabled","dataKey","_getDelegateConfig","click","_isWithActiveTrigger","_enter","_leave","getTipElement","isWithContent","isInTheDom","tipId","getUID","setContent","animation","attachment","_getAttachment","addAttachmentClass","container","INSERTED","fallbackPlacement","_handlePopperPlacementChange","_fixTransition","prevHoverState","_TRANSITION_DURATION","_cleanTipClass","getTitle","CLASS_PREFIX","template","$tip","setElementContent","content","empty","append","text","title","eventIn","eventOut","FOCUSOUT","_fixTitle","titleType","delay","tabClass","join","initConfigAnimation","Popover","subClass","superClass","create","__proto__","_getContent","ScrollSpy","OffsetMethod","_scrollElement","NAV_LINKS","LIST_ITEMS","DROPDOWN_ITEMS","_offsets","_targets","_activeTarget","_scrollHeight","SCROLL","_process","refresh","autoMethod","offsetMethod","method","offsetBase","_getScrollTop","_getScrollHeight","targetSelector","targetBCR","item","pageYOffset","_getOffsetHeight","maxScroll","_activate","_clear","queries","$link","DROPDOWN","DROPDOWN_TOGGLE","parents","NAV_LIST_GROUP","NAV_ITEMS","ACTIVATE","scrollSpys","DATA_SPY","$spy","Tab","previous","listElement","itemSelector","hiddenEvent","active","_transitionComplete","dropdownChild","dropdownElement","version"],"mappings":"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","sourcesContent":["export { _createClass as createClass, _extends as extends, _inheritsLoose as inheritsLoose };\n\nfunction _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n return Constructor;\n}\n\nfunction _extends() {\n _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n };\n\n return _extends.apply(this, arguments);\n}\n\nfunction _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n subClass.__proto__ = superClass;\n}","/**!\n * @fileOverview Kickass library to create and place poppers near their reference elements.\n * @version 1.12.9\n * @license\n * Copyright (c) 2016 Federico Zivolo and contributors\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nvar isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';\nvar longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];\nvar timeoutDuration = 0;\nfor (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {\n if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {\n timeoutDuration = 1;\n break;\n }\n}\n\nfunction microtaskDebounce(fn) {\n var called = false;\n return function () {\n if (called) {\n return;\n }\n called = true;\n window.Promise.resolve().then(function () {\n called = false;\n fn();\n });\n };\n}\n\nfunction taskDebounce(fn) {\n var scheduled = false;\n return function () {\n if (!scheduled) {\n scheduled = true;\n setTimeout(function () {\n scheduled = false;\n fn();\n }, timeoutDuration);\n }\n };\n}\n\nvar supportsMicroTasks = isBrowser && window.Promise;\n\n/**\n* Create a debounced version of a method, that's asynchronously deferred\n* but called in the minimum time possible.\n*\n* @method\n* @memberof Popper.Utils\n* @argument {Function} fn\n* @returns {Function}\n*/\nvar debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce;\n\n/**\n * Check if the given variable is a function\n * @method\n * @memberof Popper.Utils\n * @argument {Any} functionToCheck - variable to check\n * @returns {Boolean} answer to: is a function?\n */\nfunction isFunction(functionToCheck) {\n var getType = {};\n return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';\n}\n\n/**\n * Get CSS computed property of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Eement} element\n * @argument {String} property\n */\nfunction getStyleComputedProperty(element, property) {\n if (element.nodeType !== 1) {\n return [];\n }\n // NOTE: 1 DOM access here\n var css = getComputedStyle(element, null);\n return property ? css[property] : css;\n}\n\n/**\n * Returns the parentNode or the host of the element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} parent\n */\nfunction getParentNode(element) {\n if (element.nodeName === 'HTML') {\n return element;\n }\n return element.parentNode || element.host;\n}\n\n/**\n * Returns the scrolling parent of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} scroll parent\n */\nfunction getScrollParent(element) {\n // Return body, `getScroll` will take care to get the correct `scrollTop` from it\n if (!element) {\n return document.body;\n }\n\n switch (element.nodeName) {\n case 'HTML':\n case 'BODY':\n return element.ownerDocument.body;\n case '#document':\n return element.body;\n }\n\n // Firefox want us to check `-x` and `-y` variations as well\n\n var _getStyleComputedProp = getStyleComputedProperty(element),\n overflow = _getStyleComputedProp.overflow,\n overflowX = _getStyleComputedProp.overflowX,\n overflowY = _getStyleComputedProp.overflowY;\n\n if (/(auto|scroll)/.test(overflow + overflowY + overflowX)) {\n return element;\n }\n\n return getScrollParent(getParentNode(element));\n}\n\n/**\n * Returns the offset parent of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} offset parent\n */\nfunction getOffsetParent(element) {\n // NOTE: 1 DOM access here\n var offsetParent = element && element.offsetParent;\n var nodeName = offsetParent && offsetParent.nodeName;\n\n if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {\n if (element) {\n return element.ownerDocument.documentElement;\n }\n\n return document.documentElement;\n }\n\n // .offsetParent will return the closest TD or TABLE in case\n // no offsetParent is present, I hate this job...\n if (['TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') {\n return getOffsetParent(offsetParent);\n }\n\n return offsetParent;\n}\n\nfunction isOffsetContainer(element) {\n var nodeName = element.nodeName;\n\n if (nodeName === 'BODY') {\n return false;\n }\n return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;\n}\n\n/**\n * Finds the root node (document, shadowDOM root) of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} node\n * @returns {Element} root node\n */\nfunction getRoot(node) {\n if (node.parentNode !== null) {\n return getRoot(node.parentNode);\n }\n\n return node;\n}\n\n/**\n * Finds the offset parent common to the two provided nodes\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element1\n * @argument {Element} element2\n * @returns {Element} common offset parent\n */\nfunction findCommonOffsetParent(element1, element2) {\n // This check is needed to avoid errors in case one of the elements isn't defined for any reason\n if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {\n return document.documentElement;\n }\n\n // Here we make sure to give as \"start\" the element that comes first in the DOM\n var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;\n var start = order ? element1 : element2;\n var end = order ? element2 : element1;\n\n // Get common ancestor container\n var range = document.createRange();\n range.setStart(start, 0);\n range.setEnd(end, 0);\n var commonAncestorContainer = range.commonAncestorContainer;\n\n // Both nodes are inside #document\n\n if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {\n if (isOffsetContainer(commonAncestorContainer)) {\n return commonAncestorContainer;\n }\n\n return getOffsetParent(commonAncestorContainer);\n }\n\n // one of the nodes is inside shadowDOM, find which one\n var element1root = getRoot(element1);\n if (element1root.host) {\n return findCommonOffsetParent(element1root.host, element2);\n } else {\n return findCommonOffsetParent(element1, getRoot(element2).host);\n }\n}\n\n/**\n * Gets the scroll value of the given element in the given side (top and left)\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @argument {String} side `top` or `left`\n * @returns {number} amount of scrolled pixels\n */\nfunction getScroll(element) {\n var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';\n\n var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';\n var nodeName = element.nodeName;\n\n if (nodeName === 'BODY' || nodeName === 'HTML') {\n var html = element.ownerDocument.documentElement;\n var scrollingElement = element.ownerDocument.scrollingElement || html;\n return scrollingElement[upperSide];\n }\n\n return element[upperSide];\n}\n\n/*\n * Sum or subtract the element scroll values (left and top) from a given rect object\n * @method\n * @memberof Popper.Utils\n * @param {Object} rect - Rect object you want to change\n * @param {HTMLElement} element - The element from the function reads the scroll values\n * @param {Boolean} subtract - set to true if you want to subtract the scroll values\n * @return {Object} rect - The modifier rect object\n */\nfunction includeScroll(rect, element) {\n var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n var scrollTop = getScroll(element, 'top');\n var scrollLeft = getScroll(element, 'left');\n var modifier = subtract ? -1 : 1;\n rect.top += scrollTop * modifier;\n rect.bottom += scrollTop * modifier;\n rect.left += scrollLeft * modifier;\n rect.right += scrollLeft * modifier;\n return rect;\n}\n\n/*\n * Helper to detect borders of a given element\n * @method\n * @memberof Popper.Utils\n * @param {CSSStyleDeclaration} styles\n * Result of `getStyleComputedProperty` on the given element\n * @param {String} axis - `x` or `y`\n * @return {number} borders - The borders size of the given axis\n */\n\nfunction getBordersSize(styles, axis) {\n var sideA = axis === 'x' ? 'Left' : 'Top';\n var sideB = sideA === 'Left' ? 'Right' : 'Bottom';\n\n return parseFloat(styles['border' + sideA + 'Width'], 10) + parseFloat(styles['border' + sideB + 'Width'], 10);\n}\n\n/**\n * Tells if you are running Internet Explorer 10\n * @method\n * @memberof Popper.Utils\n * @returns {Boolean} isIE10\n */\nvar isIE10 = undefined;\n\nvar isIE10$1 = function () {\n if (isIE10 === undefined) {\n isIE10 = navigator.appVersion.indexOf('MSIE 10') !== -1;\n }\n return isIE10;\n};\n\nfunction getSize(axis, body, html, computedStyle) {\n return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE10$1() ? html['offset' + axis] + computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')] + computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')] : 0);\n}\n\nfunction getWindowSizes() {\n var body = document.body;\n var html = document.documentElement;\n var computedStyle = isIE10$1() && getComputedStyle(html);\n\n return {\n height: getSize('Height', body, html, computedStyle),\n width: getSize('Width', body, html, computedStyle)\n };\n}\n\nvar classCallCheck = function (instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n};\n\nvar createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n}();\n\n\n\n\n\nvar defineProperty = function (obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n};\n\nvar _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n};\n\n/**\n * Given element offsets, generate an output similar to getBoundingClientRect\n * @method\n * @memberof Popper.Utils\n * @argument {Object} offsets\n * @returns {Object} ClientRect like output\n */\nfunction getClientRect(offsets) {\n return _extends({}, offsets, {\n right: offsets.left + offsets.width,\n bottom: offsets.top + offsets.height\n });\n}\n\n/**\n * Get bounding client rect of given element\n * @method\n * @memberof Popper.Utils\n * @param {HTMLElement} element\n * @return {Object} client rect\n */\nfunction getBoundingClientRect(element) {\n var rect = {};\n\n // IE10 10 FIX: Please, don't ask, the element isn't\n // considered in DOM in some circumstances...\n // This isn't reproducible in IE10 compatibility mode of IE11\n if (isIE10$1()) {\n try {\n rect = element.getBoundingClientRect();\n var scrollTop = getScroll(element, 'top');\n var scrollLeft = getScroll(element, 'left');\n rect.top += scrollTop;\n rect.left += scrollLeft;\n rect.bottom += scrollTop;\n rect.right += scrollLeft;\n } catch (err) {}\n } else {\n rect = element.getBoundingClientRect();\n }\n\n var result = {\n left: rect.left,\n top: rect.top,\n width: rect.right - rect.left,\n height: rect.bottom - rect.top\n };\n\n // subtract scrollbar size from sizes\n var sizes = element.nodeName === 'HTML' ? getWindowSizes() : {};\n var width = sizes.width || element.clientWidth || result.right - result.left;\n var height = sizes.height || element.clientHeight || result.bottom - result.top;\n\n var horizScrollbar = element.offsetWidth - width;\n var vertScrollbar = element.offsetHeight - height;\n\n // if an hypothetical scrollbar is detected, we must be sure it's not a `border`\n // we make this check conditional for performance reasons\n if (horizScrollbar || vertScrollbar) {\n var styles = getStyleComputedProperty(element);\n horizScrollbar -= getBordersSize(styles, 'x');\n vertScrollbar -= getBordersSize(styles, 'y');\n\n result.width -= horizScrollbar;\n result.height -= vertScrollbar;\n }\n\n return getClientRect(result);\n}\n\nfunction getOffsetRectRelativeToArbitraryNode(children, parent) {\n var isIE10 = isIE10$1();\n var isHTML = parent.nodeName === 'HTML';\n var childrenRect = getBoundingClientRect(children);\n var parentRect = getBoundingClientRect(parent);\n var scrollParent = getScrollParent(children);\n\n var styles = getStyleComputedProperty(parent);\n var borderTopWidth = parseFloat(styles.borderTopWidth, 10);\n var borderLeftWidth = parseFloat(styles.borderLeftWidth, 10);\n\n var offsets = getClientRect({\n top: childrenRect.top - parentRect.top - borderTopWidth,\n left: childrenRect.left - parentRect.left - borderLeftWidth,\n width: childrenRect.width,\n height: childrenRect.height\n });\n offsets.marginTop = 0;\n offsets.marginLeft = 0;\n\n // Subtract margins of documentElement in case it's being used as parent\n // we do this only on HTML because it's the only element that behaves\n // differently when margins are applied to it. The margins are included in\n // the box of the documentElement, in the other cases not.\n if (!isIE10 && isHTML) {\n var marginTop = parseFloat(styles.marginTop, 10);\n var marginLeft = parseFloat(styles.marginLeft, 10);\n\n offsets.top -= borderTopWidth - marginTop;\n offsets.bottom -= borderTopWidth - marginTop;\n offsets.left -= borderLeftWidth - marginLeft;\n offsets.right -= borderLeftWidth - marginLeft;\n\n // Attach marginTop and marginLeft because in some circumstances we may need them\n offsets.marginTop = marginTop;\n offsets.marginLeft = marginLeft;\n }\n\n if (isIE10 ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {\n offsets = includeScroll(offsets, parent);\n }\n\n return offsets;\n}\n\nfunction getViewportOffsetRectRelativeToArtbitraryNode(element) {\n var html = element.ownerDocument.documentElement;\n var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);\n var width = Math.max(html.clientWidth, window.innerWidth || 0);\n var height = Math.max(html.clientHeight, window.innerHeight || 0);\n\n var scrollTop = getScroll(html);\n var scrollLeft = getScroll(html, 'left');\n\n var offset = {\n top: scrollTop - relativeOffset.top + relativeOffset.marginTop,\n left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,\n width: width,\n height: height\n };\n\n return getClientRect(offset);\n}\n\n/**\n * Check if the given element is fixed or is inside a fixed parent\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @argument {Element} customContainer\n * @returns {Boolean} answer to \"isFixed?\"\n */\nfunction isFixed(element) {\n var nodeName = element.nodeName;\n if (nodeName === 'BODY' || nodeName === 'HTML') {\n return false;\n }\n if (getStyleComputedProperty(element, 'position') === 'fixed') {\n return true;\n }\n return isFixed(getParentNode(element));\n}\n\n/**\n * Computed the boundaries limits and return them\n * @method\n * @memberof Popper.Utils\n * @param {HTMLElement} popper\n * @param {HTMLElement} reference\n * @param {number} padding\n * @param {HTMLElement} boundariesElement - Element used to define the boundaries\n * @returns {Object} Coordinates of the boundaries\n */\nfunction getBoundaries(popper, reference, padding, boundariesElement) {\n // NOTE: 1 DOM access here\n var boundaries = { top: 0, left: 0 };\n var offsetParent = findCommonOffsetParent(popper, reference);\n\n // Handle viewport case\n if (boundariesElement === 'viewport') {\n boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent);\n } else {\n // Handle other cases based on DOM element used as boundaries\n var boundariesNode = void 0;\n if (boundariesElement === 'scrollParent') {\n boundariesNode = getScrollParent(getParentNode(reference));\n if (boundariesNode.nodeName === 'BODY') {\n boundariesNode = popper.ownerDocument.documentElement;\n }\n } else if (boundariesElement === 'window') {\n boundariesNode = popper.ownerDocument.documentElement;\n } else {\n boundariesNode = boundariesElement;\n }\n\n var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent);\n\n // In case of HTML, we need a different computation\n if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {\n var _getWindowSizes = getWindowSizes(),\n height = _getWindowSizes.height,\n width = _getWindowSizes.width;\n\n boundaries.top += offsets.top - offsets.marginTop;\n boundaries.bottom = height + offsets.top;\n boundaries.left += offsets.left - offsets.marginLeft;\n boundaries.right = width + offsets.left;\n } else {\n // for all the other DOM elements, this one is good\n boundaries = offsets;\n }\n }\n\n // Add paddings\n boundaries.left += padding;\n boundaries.top += padding;\n boundaries.right -= padding;\n boundaries.bottom -= padding;\n\n return boundaries;\n}\n\nfunction getArea(_ref) {\n var width = _ref.width,\n height = _ref.height;\n\n return width * height;\n}\n\n/**\n * Utility used to transform the `auto` placement to the placement with more\n * available space.\n * @method\n * @memberof Popper.Utils\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {\n var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;\n\n if (placement.indexOf('auto') === -1) {\n return placement;\n }\n\n var boundaries = getBoundaries(popper, reference, padding, boundariesElement);\n\n var rects = {\n top: {\n width: boundaries.width,\n height: refRect.top - boundaries.top\n },\n right: {\n width: boundaries.right - refRect.right,\n height: boundaries.height\n },\n bottom: {\n width: boundaries.width,\n height: boundaries.bottom - refRect.bottom\n },\n left: {\n width: refRect.left - boundaries.left,\n height: boundaries.height\n }\n };\n\n var sortedAreas = Object.keys(rects).map(function (key) {\n return _extends({\n key: key\n }, rects[key], {\n area: getArea(rects[key])\n });\n }).sort(function (a, b) {\n return b.area - a.area;\n });\n\n var filteredAreas = sortedAreas.filter(function (_ref2) {\n var width = _ref2.width,\n height = _ref2.height;\n return width >= popper.clientWidth && height >= popper.clientHeight;\n });\n\n var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;\n\n var variation = placement.split('-')[1];\n\n return computedPlacement + (variation ? '-' + variation : '');\n}\n\n/**\n * Get offsets to the reference element\n * @method\n * @memberof Popper.Utils\n * @param {Object} state\n * @param {Element} popper - the popper element\n * @param {Element} reference - the reference element (the popper will be relative to this)\n * @returns {Object} An object containing the offsets which will be applied to the popper\n */\nfunction getReferenceOffsets(state, popper, reference) {\n var commonOffsetParent = findCommonOffsetParent(popper, reference);\n return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent);\n}\n\n/**\n * Get the outer sizes of the given element (offset size + margins)\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Object} object containing width and height properties\n */\nfunction getOuterSizes(element) {\n var styles = getComputedStyle(element);\n var x = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom);\n var y = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight);\n var result = {\n width: element.offsetWidth + y,\n height: element.offsetHeight + x\n };\n return result;\n}\n\n/**\n * Get the opposite placement of the given one\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement\n * @returns {String} flipped placement\n */\nfunction getOppositePlacement(placement) {\n var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };\n return placement.replace(/left|right|bottom|top/g, function (matched) {\n return hash[matched];\n });\n}\n\n/**\n * Get offsets to the popper\n * @method\n * @memberof Popper.Utils\n * @param {Object} position - CSS position the Popper will get applied\n * @param {HTMLElement} popper - the popper element\n * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)\n * @param {String} placement - one of the valid placement options\n * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper\n */\nfunction getPopperOffsets(popper, referenceOffsets, placement) {\n placement = placement.split('-')[0];\n\n // Get popper node sizes\n var popperRect = getOuterSizes(popper);\n\n // Add position, width and height to our offsets object\n var popperOffsets = {\n width: popperRect.width,\n height: popperRect.height\n };\n\n // depending by the popper placement we have to compute its offsets slightly differently\n var isHoriz = ['right', 'left'].indexOf(placement) !== -1;\n var mainSide = isHoriz ? 'top' : 'left';\n var secondarySide = isHoriz ? 'left' : 'top';\n var measurement = isHoriz ? 'height' : 'width';\n var secondaryMeasurement = !isHoriz ? 'height' : 'width';\n\n popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;\n if (placement === secondarySide) {\n popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];\n } else {\n popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];\n }\n\n return popperOffsets;\n}\n\n/**\n * Mimics the `find` method of Array\n * @method\n * @memberof Popper.Utils\n * @argument {Array} arr\n * @argument prop\n * @argument value\n * @returns index or -1\n */\nfunction find(arr, check) {\n // use native find if supported\n if (Array.prototype.find) {\n return arr.find(check);\n }\n\n // use `filter` to obtain the same behavior of `find`\n return arr.filter(check)[0];\n}\n\n/**\n * Return the index of the matching object\n * @method\n * @memberof Popper.Utils\n * @argument {Array} arr\n * @argument prop\n * @argument value\n * @returns index or -1\n */\nfunction findIndex(arr, prop, value) {\n // use native findIndex if supported\n if (Array.prototype.findIndex) {\n return arr.findIndex(function (cur) {\n return cur[prop] === value;\n });\n }\n\n // use `find` + `indexOf` if `findIndex` isn't supported\n var match = find(arr, function (obj) {\n return obj[prop] === value;\n });\n return arr.indexOf(match);\n}\n\n/**\n * Loop trough the list of modifiers and run them in order,\n * each of them will then edit the data object.\n * @method\n * @memberof Popper.Utils\n * @param {dataObject} data\n * @param {Array} modifiers\n * @param {String} ends - Optional modifier name used as stopper\n * @returns {dataObject}\n */\nfunction runModifiers(modifiers, data, ends) {\n var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));\n\n modifiersToRun.forEach(function (modifier) {\n if (modifier['function']) {\n // eslint-disable-line dot-notation\n console.warn('`modifier.function` is deprecated, use `modifier.fn`!');\n }\n var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation\n if (modifier.enabled && isFunction(fn)) {\n // Add properties to offsets to make them a complete clientRect object\n // we do this before each modifier to make sure the previous one doesn't\n // mess with these values\n data.offsets.popper = getClientRect(data.offsets.popper);\n data.offsets.reference = getClientRect(data.offsets.reference);\n\n data = fn(data, modifier);\n }\n });\n\n return data;\n}\n\n/**\n * Updates the position of the popper, computing the new offsets and applying\n * the new style.<br />\n * Prefer `scheduleUpdate` over `update` because of performance reasons.\n * @method\n * @memberof Popper\n */\nfunction update() {\n // if popper is destroyed, don't perform any further update\n if (this.state.isDestroyed) {\n return;\n }\n\n var data = {\n instance: this,\n styles: {},\n arrowStyles: {},\n attributes: {},\n flipped: false,\n offsets: {}\n };\n\n // compute reference element offsets\n data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference);\n\n // compute auto placement, store placement inside the data object,\n // modifiers will be able to edit `placement` if needed\n // and refer to originalPlacement to know the original value\n data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding);\n\n // store the computed placement inside `originalPlacement`\n data.originalPlacement = data.placement;\n\n // compute the popper offsets\n data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement);\n data.offsets.popper.position = 'absolute';\n\n // run the modifiers\n data = runModifiers(this.modifiers, data);\n\n // the first `update` will call `onCreate` callback\n // the other ones will call `onUpdate` callback\n if (!this.state.isCreated) {\n this.state.isCreated = true;\n this.options.onCreate(data);\n } else {\n this.options.onUpdate(data);\n }\n}\n\n/**\n * Helper used to know if the given modifier is enabled.\n * @method\n * @memberof Popper.Utils\n * @returns {Boolean}\n */\nfunction isModifierEnabled(modifiers, modifierName) {\n return modifiers.some(function (_ref) {\n var name = _ref.name,\n enabled = _ref.enabled;\n return enabled && name === modifierName;\n });\n}\n\n/**\n * Get the prefixed supported property name\n * @method\n * @memberof Popper.Utils\n * @argument {String} property (camelCase)\n * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)\n */\nfunction getSupportedPropertyName(property) {\n var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];\n var upperProp = property.charAt(0).toUpperCase() + property.slice(1);\n\n for (var i = 0; i < prefixes.length - 1; i++) {\n var prefix = prefixes[i];\n var toCheck = prefix ? '' + prefix + upperProp : property;\n if (typeof document.body.style[toCheck] !== 'undefined') {\n return toCheck;\n }\n }\n return null;\n}\n\n/**\n * Destroy the popper\n * @method\n * @memberof Popper\n */\nfunction destroy() {\n this.state.isDestroyed = true;\n\n // touch DOM only if `applyStyle` modifier is enabled\n if (isModifierEnabled(this.modifiers, 'applyStyle')) {\n this.popper.removeAttribute('x-placement');\n this.popper.style.left = '';\n this.popper.style.position = '';\n this.popper.style.top = '';\n this.popper.style[getSupportedPropertyName('transform')] = '';\n }\n\n this.disableEventListeners();\n\n // remove the popper if user explicity asked for the deletion on destroy\n // do not use `remove` because IE11 doesn't support it\n if (this.options.removeOnDestroy) {\n this.popper.parentNode.removeChild(this.popper);\n }\n return this;\n}\n\n/**\n * Get the window associated with the element\n * @argument {Element} element\n * @returns {Window}\n */\nfunction getWindow(element) {\n var ownerDocument = element.ownerDocument;\n return ownerDocument ? ownerDocument.defaultView : window;\n}\n\nfunction attachToScrollParents(scrollParent, event, callback, scrollParents) {\n var isBody = scrollParent.nodeName === 'BODY';\n var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent;\n target.addEventListener(event, callback, { passive: true });\n\n if (!isBody) {\n attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);\n }\n scrollParents.push(target);\n}\n\n/**\n * Setup needed event listeners used to update the popper position\n * @method\n * @memberof Popper.Utils\n * @private\n */\nfunction setupEventListeners(reference, options, state, updateBound) {\n // Resize event listener on window\n state.updateBound = updateBound;\n getWindow(reference).addEventListener('resize', state.updateBound, { passive: true });\n\n // Scroll event listener on scroll parents\n var scrollElement = getScrollParent(reference);\n attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);\n state.scrollElement = scrollElement;\n state.eventsEnabled = true;\n\n return state;\n}\n\n/**\n * It will add resize/scroll events and start recalculating\n * position of the popper element when they are triggered.\n * @method\n * @memberof Popper\n */\nfunction enableEventListeners() {\n if (!this.state.eventsEnabled) {\n this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);\n }\n}\n\n/**\n * Remove event listeners used to update the popper position\n * @method\n * @memberof Popper.Utils\n * @private\n */\nfunction removeEventListeners(reference, state) {\n // Remove resize event listener on window\n getWindow(reference).removeEventListener('resize', state.updateBound);\n\n // Remove scroll event listener on scroll parents\n state.scrollParents.forEach(function (target) {\n target.removeEventListener('scroll', state.updateBound);\n });\n\n // Reset state\n state.updateBound = null;\n state.scrollParents = [];\n state.scrollElement = null;\n state.eventsEnabled = false;\n return state;\n}\n\n/**\n * It will remove resize/scroll events and won't recalculate popper position\n * when they are triggered. It also won't trigger onUpdate callback anymore,\n * unless you call `update` method manually.\n * @method\n * @memberof Popper\n */\nfunction disableEventListeners() {\n if (this.state.eventsEnabled) {\n cancelAnimationFrame(this.scheduleUpdate);\n this.state = removeEventListeners(this.reference, this.state);\n }\n}\n\n/**\n * Tells if a given input is a number\n * @method\n * @memberof Popper.Utils\n * @param {*} input to check\n * @return {Boolean}\n */\nfunction isNumeric(n) {\n return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);\n}\n\n/**\n * Set the style to the given popper\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element - Element to apply the style to\n * @argument {Object} styles\n * Object with a list of properties and values which will be applied to the element\n */\nfunction setStyles(element, styles) {\n Object.keys(styles).forEach(function (prop) {\n var unit = '';\n // add unit if the value is numeric and is one of the following\n if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {\n unit = 'px';\n }\n element.style[prop] = styles[prop] + unit;\n });\n}\n\n/**\n * Set the attributes to the given popper\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element - Element to apply the attributes to\n * @argument {Object} styles\n * Object with a list of properties and values which will be applied to the element\n */\nfunction setAttributes(element, attributes) {\n Object.keys(attributes).forEach(function (prop) {\n var value = attributes[prop];\n if (value !== false) {\n element.setAttribute(prop, attributes[prop]);\n } else {\n element.removeAttribute(prop);\n }\n });\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} data.styles - List of style properties - values to apply to popper element\n * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The same data object\n */\nfunction applyStyle(data) {\n // any property present in `data.styles` will be applied to the popper,\n // in this way we can make the 3rd party modifiers add custom styles to it\n // Be aware, modifiers could override the properties defined in the previous\n // lines of this modifier!\n setStyles(data.instance.popper, data.styles);\n\n // any property present in `data.attributes` will be applied to the popper,\n // they will be set as HTML attributes of the element\n setAttributes(data.instance.popper, data.attributes);\n\n // if arrowElement is defined and arrowStyles has some properties\n if (data.arrowElement && Object.keys(data.arrowStyles).length) {\n setStyles(data.arrowElement, data.arrowStyles);\n }\n\n return data;\n}\n\n/**\n * Set the x-placement attribute before everything else because it could be used\n * to add margins to the popper margins needs to be calculated to get the\n * correct popper offsets.\n * @method\n * @memberof Popper.modifiers\n * @param {HTMLElement} reference - The reference element used to position the popper\n * @param {HTMLElement} popper - The HTML element used as popper.\n * @param {Object} options - Popper.js options\n */\nfunction applyStyleOnLoad(reference, popper, options, modifierOptions, state) {\n // compute reference element offsets\n var referenceOffsets = getReferenceOffsets(state, popper, reference);\n\n // compute auto placement, store placement inside the data object,\n // modifiers will be able to edit `placement` if needed\n // and refer to originalPlacement to know the original value\n var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding);\n\n popper.setAttribute('x-placement', placement);\n\n // Apply `position` to popper before anything else because\n // without the position applied we can't guarantee correct computations\n setStyles(popper, { position: 'absolute' });\n\n return options;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction computeStyle(data, options) {\n var x = options.x,\n y = options.y;\n var popper = data.offsets.popper;\n\n // Remove this legacy support in Popper.js v2\n\n var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) {\n return modifier.name === 'applyStyle';\n }).gpuAcceleration;\n if (legacyGpuAccelerationOption !== undefined) {\n console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');\n }\n var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration;\n\n var offsetParent = getOffsetParent(data.instance.popper);\n var offsetParentRect = getBoundingClientRect(offsetParent);\n\n // Styles\n var styles = {\n position: popper.position\n };\n\n // floor sides to avoid blurry text\n var offsets = {\n left: Math.floor(popper.left),\n top: Math.floor(popper.top),\n bottom: Math.floor(popper.bottom),\n right: Math.floor(popper.right)\n };\n\n var sideA = x === 'bottom' ? 'top' : 'bottom';\n var sideB = y === 'right' ? 'left' : 'right';\n\n // if gpuAcceleration is set to `true` and transform is supported,\n // we use `translate3d` to apply the position to the popper we\n // automatically use the supported prefixed version if needed\n var prefixedProperty = getSupportedPropertyName('transform');\n\n // now, let's make a step back and look at this code closely (wtf?)\n // If the content of the popper grows once it's been positioned, it\n // may happen that the popper gets misplaced because of the new content\n // overflowing its reference element\n // To avoid this problem, we provide two options (x and y), which allow\n // the consumer to define the offset origin.\n // If we position a popper on top of a reference element, we can set\n // `x` to `top` to make the popper grow towards its top instead of\n // its bottom.\n var left = void 0,\n top = void 0;\n if (sideA === 'bottom') {\n top = -offsetParentRect.height + offsets.bottom;\n } else {\n top = offsets.top;\n }\n if (sideB === 'right') {\n left = -offsetParentRect.width + offsets.right;\n } else {\n left = offsets.left;\n }\n if (gpuAcceleration && prefixedProperty) {\n styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';\n styles[sideA] = 0;\n styles[sideB] = 0;\n styles.willChange = 'transform';\n } else {\n // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties\n var invertTop = sideA === 'bottom' ? -1 : 1;\n var invertLeft = sideB === 'right' ? -1 : 1;\n styles[sideA] = top * invertTop;\n styles[sideB] = left * invertLeft;\n styles.willChange = sideA + ', ' + sideB;\n }\n\n // Attributes\n var attributes = {\n 'x-placement': data.placement\n };\n\n // Update `data` attributes, styles and arrowStyles\n data.attributes = _extends({}, attributes, data.attributes);\n data.styles = _extends({}, styles, data.styles);\n data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles);\n\n return data;\n}\n\n/**\n * Helper used to know if the given modifier depends from another one.<br />\n * It checks if the needed modifier is listed and enabled.\n * @method\n * @memberof Popper.Utils\n * @param {Array} modifiers - list of modifiers\n * @param {String} requestingName - name of requesting modifier\n * @param {String} requestedName - name of requested modifier\n * @returns {Boolean}\n */\nfunction isModifierRequired(modifiers, requestingName, requestedName) {\n var requesting = find(modifiers, function (_ref) {\n var name = _ref.name;\n return name === requestingName;\n });\n\n var isRequired = !!requesting && modifiers.some(function (modifier) {\n return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;\n });\n\n if (!isRequired) {\n var _requesting = '`' + requestingName + '`';\n var requested = '`' + requestedName + '`';\n console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!');\n }\n return isRequired;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction arrow(data, options) {\n var _data$offsets$arrow;\n\n // arrow depends on keepTogether in order to work\n if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {\n return data;\n }\n\n var arrowElement = options.element;\n\n // if arrowElement is a string, suppose it's a CSS selector\n if (typeof arrowElement === 'string') {\n arrowElement = data.instance.popper.querySelector(arrowElement);\n\n // if arrowElement is not found, don't run the modifier\n if (!arrowElement) {\n return data;\n }\n } else {\n // if the arrowElement isn't a query selector we must check that the\n // provided DOM node is child of its popper node\n if (!data.instance.popper.contains(arrowElement)) {\n console.warn('WARNING: `arrow.element` must be child of its popper element!');\n return data;\n }\n }\n\n var placement = data.placement.split('-')[0];\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var isVertical = ['left', 'right'].indexOf(placement) !== -1;\n\n var len = isVertical ? 'height' : 'width';\n var sideCapitalized = isVertical ? 'Top' : 'Left';\n var side = sideCapitalized.toLowerCase();\n var altSide = isVertical ? 'left' : 'top';\n var opSide = isVertical ? 'bottom' : 'right';\n var arrowElementSize = getOuterSizes(arrowElement)[len];\n\n //\n // extends keepTogether behavior making sure the popper and its\n // reference have enough pixels in conjuction\n //\n\n // top/left side\n if (reference[opSide] - arrowElementSize < popper[side]) {\n data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);\n }\n // bottom/right side\n if (reference[side] + arrowElementSize > popper[opSide]) {\n data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];\n }\n data.offsets.popper = getClientRect(data.offsets.popper);\n\n // compute center of the popper\n var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;\n\n // Compute the sideValue using the updated popper offsets\n // take popper margin in account because we don't have this info available\n var css = getStyleComputedProperty(data.instance.popper);\n var popperMarginSide = parseFloat(css['margin' + sideCapitalized], 10);\n var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width'], 10);\n var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;\n\n // prevent arrowElement from being placed not contiguously to its popper\n sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);\n\n data.arrowElement = arrowElement;\n data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow);\n\n return data;\n}\n\n/**\n * Get the opposite placement variation of the given one\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement variation\n * @returns {String} flipped placement variation\n */\nfunction getOppositeVariation(variation) {\n if (variation === 'end') {\n return 'start';\n } else if (variation === 'start') {\n return 'end';\n }\n return variation;\n}\n\n/**\n * List of accepted placements to use as values of the `placement` option.<br />\n * Valid placements are:\n * - `auto`\n * - `top`\n * - `right`\n * - `bottom`\n * - `left`\n *\n * Each placement can have a variation from this list:\n * - `-start`\n * - `-end`\n *\n * Variations are interpreted easily if you think of them as the left to right\n * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`\n * is right.<br />\n * Vertically (`left` and `right`), `start` is top and `end` is bottom.\n *\n * Some valid examples are:\n * - `top-end` (on top of reference, right aligned)\n * - `right-start` (on right of reference, top aligned)\n * - `bottom` (on bottom, centered)\n * - `auto-right` (on the side with more space available, alignment depends by placement)\n *\n * @static\n * @type {Array}\n * @enum {String}\n * @readonly\n * @method placements\n * @memberof Popper\n */\nvar placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start'];\n\n// Get rid of `auto` `auto-start` and `auto-end`\nvar validPlacements = placements.slice(3);\n\n/**\n * Given an initial placement, returns all the subsequent placements\n * clockwise (or counter-clockwise).\n *\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement - A valid placement (it accepts variations)\n * @argument {Boolean} counter - Set to true to walk the placements counterclockwise\n * @returns {Array} placements including their variations\n */\nfunction clockwise(placement) {\n var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n var index = validPlacements.indexOf(placement);\n var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index));\n return counter ? arr.reverse() : arr;\n}\n\nvar BEHAVIORS = {\n FLIP: 'flip',\n CLOCKWISE: 'clockwise',\n COUNTERCLOCKWISE: 'counterclockwise'\n};\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction flip(data, options) {\n // if `inner` modifier is enabled, we can't use the `flip` modifier\n if (isModifierEnabled(data.instance.modifiers, 'inner')) {\n return data;\n }\n\n if (data.flipped && data.placement === data.originalPlacement) {\n // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides\n return data;\n }\n\n var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement);\n\n var placement = data.placement.split('-')[0];\n var placementOpposite = getOppositePlacement(placement);\n var variation = data.placement.split('-')[1] || '';\n\n var flipOrder = [];\n\n switch (options.behavior) {\n case BEHAVIORS.FLIP:\n flipOrder = [placement, placementOpposite];\n break;\n case BEHAVIORS.CLOCKWISE:\n flipOrder = clockwise(placement);\n break;\n case BEHAVIORS.COUNTERCLOCKWISE:\n flipOrder = clockwise(placement, true);\n break;\n default:\n flipOrder = options.behavior;\n }\n\n flipOrder.forEach(function (step, index) {\n if (placement !== step || flipOrder.length === index + 1) {\n return data;\n }\n\n placement = data.placement.split('-')[0];\n placementOpposite = getOppositePlacement(placement);\n\n var popperOffsets = data.offsets.popper;\n var refOffsets = data.offsets.reference;\n\n // using floor because the reference offsets may contain decimals we are not going to consider here\n var floor = Math.floor;\n var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom);\n\n var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);\n var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);\n var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);\n var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);\n\n var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;\n\n // flip the variation if required\n var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;\n var flippedVariation = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom);\n\n if (overlapsRef || overflowsBoundaries || flippedVariation) {\n // this boolean to detect any flip loop\n data.flipped = true;\n\n if (overlapsRef || overflowsBoundaries) {\n placement = flipOrder[index + 1];\n }\n\n if (flippedVariation) {\n variation = getOppositeVariation(variation);\n }\n\n data.placement = placement + (variation ? '-' + variation : '');\n\n // this object contains `position`, we want to preserve it along with\n // any additional property we may add in the future\n data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));\n\n data = runModifiers(data.instance.modifiers, data, 'flip');\n }\n });\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction keepTogether(data) {\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var placement = data.placement.split('-')[0];\n var floor = Math.floor;\n var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;\n var side = isVertical ? 'right' : 'bottom';\n var opSide = isVertical ? 'left' : 'top';\n var measurement = isVertical ? 'width' : 'height';\n\n if (popper[side] < floor(reference[opSide])) {\n data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];\n }\n if (popper[opSide] > floor(reference[side])) {\n data.offsets.popper[opSide] = floor(reference[side]);\n }\n\n return data;\n}\n\n/**\n * Converts a string containing value + unit into a px value number\n * @function\n * @memberof {modifiers~offset}\n * @private\n * @argument {String} str - Value + unit string\n * @argument {String} measurement - `height` or `width`\n * @argument {Object} popperOffsets\n * @argument {Object} referenceOffsets\n * @returns {Number|String}\n * Value in pixels, or original string if no values were extracted\n */\nfunction toValue(str, measurement, popperOffsets, referenceOffsets) {\n // separate value from unit\n var split = str.match(/((?:\\-|\\+)?\\d*\\.?\\d*)(.*)/);\n var value = +split[1];\n var unit = split[2];\n\n // If it's not a number it's an operator, I guess\n if (!value) {\n return str;\n }\n\n if (unit.indexOf('%') === 0) {\n var element = void 0;\n switch (unit) {\n case '%p':\n element = popperOffsets;\n break;\n case '%':\n case '%r':\n default:\n element = referenceOffsets;\n }\n\n var rect = getClientRect(element);\n return rect[measurement] / 100 * value;\n } else if (unit === 'vh' || unit === 'vw') {\n // if is a vh or vw, we calculate the size based on the viewport\n var size = void 0;\n if (unit === 'vh') {\n size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);\n } else {\n size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);\n }\n return size / 100 * value;\n } else {\n // if is an explicit pixel unit, we get rid of the unit and keep the value\n // if is an implicit unit, it's px, and we return just the value\n return value;\n }\n}\n\n/**\n * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.\n * @function\n * @memberof {modifiers~offset}\n * @private\n * @argument {String} offset\n * @argument {Object} popperOffsets\n * @argument {Object} referenceOffsets\n * @argument {String} basePlacement\n * @returns {Array} a two cells array with x and y offsets in numbers\n */\nfunction parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) {\n var offsets = [0, 0];\n\n // Use height if placement is left or right and index is 0 otherwise use width\n // in this way the first offset will use an axis and the second one\n // will use the other one\n var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;\n\n // Split the offset string to obtain a list of values and operands\n // The regex addresses values with the plus or minus sign in front (+10, -20, etc)\n var fragments = offset.split(/(\\+|\\-)/).map(function (frag) {\n return frag.trim();\n });\n\n // Detect if the offset string contains a pair of values or a single one\n // they could be separated by comma or space\n var divider = fragments.indexOf(find(fragments, function (frag) {\n return frag.search(/,|\\s/) !== -1;\n }));\n\n if (fragments[divider] && fragments[divider].indexOf(',') === -1) {\n console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');\n }\n\n // If divider is found, we divide the list of values and operands to divide\n // them by ofset X and Y.\n var splitRegex = /\\s*,\\s*|\\s+/;\n var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments];\n\n // Convert the values with units to absolute pixels to allow our computations\n ops = ops.map(function (op, index) {\n // Most of the units rely on the orientation of the popper\n var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width';\n var mergeWithPrevious = false;\n return op\n // This aggregates any `+` or `-` sign that aren't considered operators\n // e.g.: 10 + +5 => [10, +, +5]\n .reduce(function (a, b) {\n if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {\n a[a.length - 1] = b;\n mergeWithPrevious = true;\n return a;\n } else if (mergeWithPrevious) {\n a[a.length - 1] += b;\n mergeWithPrevious = false;\n return a;\n } else {\n return a.concat(b);\n }\n }, [])\n // Here we convert the string values into number values (in px)\n .map(function (str) {\n return toValue(str, measurement, popperOffsets, referenceOffsets);\n });\n });\n\n // Loop trough the offsets arrays and execute the operations\n ops.forEach(function (op, index) {\n op.forEach(function (frag, index2) {\n if (isNumeric(frag)) {\n offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);\n }\n });\n });\n return offsets;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @argument {Number|String} options.offset=0\n * The offset value as described in the modifier description\n * @returns {Object} The data object, properly modified\n */\nfunction offset(data, _ref) {\n var offset = _ref.offset;\n var placement = data.placement,\n _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var basePlacement = placement.split('-')[0];\n\n var offsets = void 0;\n if (isNumeric(+offset)) {\n offsets = [+offset, 0];\n } else {\n offsets = parseOffset(offset, popper, reference, basePlacement);\n }\n\n if (basePlacement === 'left') {\n popper.top += offsets[0];\n popper.left -= offsets[1];\n } else if (basePlacement === 'right') {\n popper.top += offsets[0];\n popper.left += offsets[1];\n } else if (basePlacement === 'top') {\n popper.left += offsets[0];\n popper.top -= offsets[1];\n } else if (basePlacement === 'bottom') {\n popper.left += offsets[0];\n popper.top += offsets[1];\n }\n\n data.popper = popper;\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction preventOverflow(data, options) {\n var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);\n\n // If offsetParent is the reference element, we really want to\n // go one step up and use the next offsetParent as reference to\n // avoid to make this modifier completely useless and look like broken\n if (data.instance.reference === boundariesElement) {\n boundariesElement = getOffsetParent(boundariesElement);\n }\n\n var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement);\n options.boundaries = boundaries;\n\n var order = options.priority;\n var popper = data.offsets.popper;\n\n var check = {\n primary: function primary(placement) {\n var value = popper[placement];\n if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {\n value = Math.max(popper[placement], boundaries[placement]);\n }\n return defineProperty({}, placement, value);\n },\n secondary: function secondary(placement) {\n var mainSide = placement === 'right' ? 'left' : 'top';\n var value = popper[mainSide];\n if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {\n value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height));\n }\n return defineProperty({}, mainSide, value);\n }\n };\n\n order.forEach(function (placement) {\n var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';\n popper = _extends({}, popper, check[side](placement));\n });\n\n data.offsets.popper = popper;\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction shift(data) {\n var placement = data.placement;\n var basePlacement = placement.split('-')[0];\n var shiftvariation = placement.split('-')[1];\n\n // if shift shiftvariation is specified, run the modifier\n if (shiftvariation) {\n var _data$offsets = data.offsets,\n reference = _data$offsets.reference,\n popper = _data$offsets.popper;\n\n var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;\n var side = isVertical ? 'left' : 'top';\n var measurement = isVertical ? 'width' : 'height';\n\n var shiftOffsets = {\n start: defineProperty({}, side, reference[side]),\n end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])\n };\n\n data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]);\n }\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction hide(data) {\n if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {\n return data;\n }\n\n var refRect = data.offsets.reference;\n var bound = find(data.instance.modifiers, function (modifier) {\n return modifier.name === 'preventOverflow';\n }).boundaries;\n\n if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {\n // Avoid unnecessary DOM access if visibility hasn't changed\n if (data.hide === true) {\n return data;\n }\n\n data.hide = true;\n data.attributes['x-out-of-boundaries'] = '';\n } else {\n // Avoid unnecessary DOM access if visibility hasn't changed\n if (data.hide === false) {\n return data;\n }\n\n data.hide = false;\n data.attributes['x-out-of-boundaries'] = false;\n }\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction inner(data) {\n var placement = data.placement;\n var basePlacement = placement.split('-')[0];\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;\n\n var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;\n\n popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);\n\n data.placement = getOppositePlacement(placement);\n data.offsets.popper = getClientRect(popper);\n\n return data;\n}\n\n/**\n * Modifier function, each modifier can have a function of this type assigned\n * to its `fn` property.<br />\n * These functions will be called on each update, this means that you must\n * make sure they are performant enough to avoid performance bottlenecks.\n *\n * @function ModifierFn\n * @argument {dataObject} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {dataObject} The data object, properly modified\n */\n\n/**\n * Modifiers are plugins used to alter the behavior of your poppers.<br />\n * Popper.js uses a set of 9 modifiers to provide all the basic functionalities\n * needed by the library.\n *\n * Usually you don't want to override the `order`, `fn` and `onLoad` props.\n * All the other properties are configurations that could be tweaked.\n * @namespace modifiers\n */\nvar modifiers = {\n /**\n * Modifier used to shift the popper on the start or end of its reference\n * element.<br />\n * It will read the variation of the `placement` property.<br />\n * It can be one either `-end` or `-start`.\n * @memberof modifiers\n * @inner\n */\n shift: {\n /** @prop {number} order=100 - Index used to define the order of execution */\n order: 100,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: shift\n },\n\n /**\n * The `offset` modifier can shift your popper on both its axis.\n *\n * It accepts the following units:\n * - `px` or unitless, interpreted as pixels\n * - `%` or `%r`, percentage relative to the length of the reference element\n * - `%p`, percentage relative to the length of the popper element\n * - `vw`, CSS viewport width unit\n * - `vh`, CSS viewport height unit\n *\n * For length is intended the main axis relative to the placement of the popper.<br />\n * This means that if the placement is `top` or `bottom`, the length will be the\n * `width`. In case of `left` or `right`, it will be the height.\n *\n * You can provide a single value (as `Number` or `String`), or a pair of values\n * as `String` divided by a comma or one (or more) white spaces.<br />\n * The latter is a deprecated method because it leads to confusion and will be\n * removed in v2.<br />\n * Additionally, it accepts additions and subtractions between different units.\n * Note that multiplications and divisions aren't supported.\n *\n * Valid examples are:\n * ```\n * 10\n * '10%'\n * '10, 10'\n * '10%, 10'\n * '10 + 10%'\n * '10 - 5vh + 3%'\n * '-10px + 5vh, 5px - 6%'\n * ```\n * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap\n * > with their reference element, unfortunately, you will have to disable the `flip` modifier.\n * > More on this [reading this issue](https://github.com/FezVrasta/popper.js/issues/373)\n *\n * @memberof modifiers\n * @inner\n */\n offset: {\n /** @prop {number} order=200 - Index used to define the order of execution */\n order: 200,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: offset,\n /** @prop {Number|String} offset=0\n * The offset value as described in the modifier description\n */\n offset: 0\n },\n\n /**\n * Modifier used to prevent the popper from being positioned outside the boundary.\n *\n * An scenario exists where the reference itself is not within the boundaries.<br />\n * We can say it has \"escaped the boundaries\" — or just \"escaped\".<br />\n * In this case we need to decide whether the popper should either:\n *\n * - detach from the reference and remain \"trapped\" in the boundaries, or\n * - if it should ignore the boundary and \"escape with its reference\"\n *\n * When `escapeWithReference` is set to`true` and reference is completely\n * outside its boundaries, the popper will overflow (or completely leave)\n * the boundaries in order to remain attached to the edge of the reference.\n *\n * @memberof modifiers\n * @inner\n */\n preventOverflow: {\n /** @prop {number} order=300 - Index used to define the order of execution */\n order: 300,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: preventOverflow,\n /**\n * @prop {Array} [priority=['left','right','top','bottom']]\n * Popper will try to prevent overflow following these priorities by default,\n * then, it could overflow on the left and on top of the `boundariesElement`\n */\n priority: ['left', 'right', 'top', 'bottom'],\n /**\n * @prop {number} padding=5\n * Amount of pixel used to define a minimum distance between the boundaries\n * and the popper this makes sure the popper has always a little padding\n * between the edges of its container\n */\n padding: 5,\n /**\n * @prop {String|HTMLElement} boundariesElement='scrollParent'\n * Boundaries used by the modifier, can be `scrollParent`, `window`,\n * `viewport` or any DOM element.\n */\n boundariesElement: 'scrollParent'\n },\n\n /**\n * Modifier used to make sure the reference and its popper stay near eachothers\n * without leaving any gap between the two. Expecially useful when the arrow is\n * enabled and you want to assure it to point to its reference element.\n * It cares only about the first axis, you can still have poppers with margin\n * between the popper and its reference element.\n * @memberof modifiers\n * @inner\n */\n keepTogether: {\n /** @prop {number} order=400 - Index used to define the order of execution */\n order: 400,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: keepTogether\n },\n\n /**\n * This modifier is used to move the `arrowElement` of the popper to make\n * sure it is positioned between the reference element and its popper element.\n * It will read the outer size of the `arrowElement` node to detect how many\n * pixels of conjuction are needed.\n *\n * It has no effect if no `arrowElement` is provided.\n * @memberof modifiers\n * @inner\n */\n arrow: {\n /** @prop {number} order=500 - Index used to define the order of execution */\n order: 500,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: arrow,\n /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */\n element: '[x-arrow]'\n },\n\n /**\n * Modifier used to flip the popper's placement when it starts to overlap its\n * reference element.\n *\n * Requires the `preventOverflow` modifier before it in order to work.\n *\n * **NOTE:** this modifier will interrupt the current update cycle and will\n * restart it if it detects the need to flip the placement.\n * @memberof modifiers\n * @inner\n */\n flip: {\n /** @prop {number} order=600 - Index used to define the order of execution */\n order: 600,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: flip,\n /**\n * @prop {String|Array} behavior='flip'\n * The behavior used to change the popper's placement. It can be one of\n * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid\n * placements (with optional variations).\n */\n behavior: 'flip',\n /**\n * @prop {number} padding=5\n * The popper will flip if it hits the edges of the `boundariesElement`\n */\n padding: 5,\n /**\n * @prop {String|HTMLElement} boundariesElement='viewport'\n * The element which will define the boundaries of the popper position,\n * the popper will never be placed outside of the defined boundaries\n * (except if keepTogether is enabled)\n */\n boundariesElement: 'viewport'\n },\n\n /**\n * Modifier used to make the popper flow toward the inner of the reference element.\n * By default, when this modifier is disabled, the popper will be placed outside\n * the reference element.\n * @memberof modifiers\n * @inner\n */\n inner: {\n /** @prop {number} order=700 - Index used to define the order of execution */\n order: 700,\n /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */\n enabled: false,\n /** @prop {ModifierFn} */\n fn: inner\n },\n\n /**\n * Modifier used to hide the popper when its reference element is outside of the\n * popper boundaries. It will set a `x-out-of-boundaries` attribute which can\n * be used to hide with a CSS selector the popper when its reference is\n * out of boundaries.\n *\n * Requires the `preventOverflow` modifier before it in order to work.\n * @memberof modifiers\n * @inner\n */\n hide: {\n /** @prop {number} order=800 - Index used to define the order of execution */\n order: 800,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: hide\n },\n\n /**\n * Computes the style that will be applied to the popper element to gets\n * properly positioned.\n *\n * Note that this modifier will not touch the DOM, it just prepares the styles\n * so that `applyStyle` modifier can apply it. This separation is useful\n * in case you need to replace `applyStyle` with a custom implementation.\n *\n * This modifier has `850` as `order` value to maintain backward compatibility\n * with previous versions of Popper.js. Expect the modifiers ordering method\n * to change in future major versions of the library.\n *\n * @memberof modifiers\n * @inner\n */\n computeStyle: {\n /** @prop {number} order=850 - Index used to define the order of execution */\n order: 850,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: computeStyle,\n /**\n * @prop {Boolean} gpuAcceleration=true\n * If true, it uses the CSS 3d transformation to position the popper.\n * Otherwise, it will use the `top` and `left` properties.\n */\n gpuAcceleration: true,\n /**\n * @prop {string} [x='bottom']\n * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.\n * Change this if your popper should grow in a direction different from `bottom`\n */\n x: 'bottom',\n /**\n * @prop {string} [x='left']\n * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.\n * Change this if your popper should grow in a direction different from `right`\n */\n y: 'right'\n },\n\n /**\n * Applies the computed styles to the popper element.\n *\n * All the DOM manipulations are limited to this modifier. This is useful in case\n * you want to integrate Popper.js inside a framework or view library and you\n * want to delegate all the DOM manipulations to it.\n *\n * Note that if you disable this modifier, you must make sure the popper element\n * has its position set to `absolute` before Popper.js can do its work!\n *\n * Just disable this modifier and define you own to achieve the desired effect.\n *\n * @memberof modifiers\n * @inner\n */\n applyStyle: {\n /** @prop {number} order=900 - Index used to define the order of execution */\n order: 900,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: applyStyle,\n /** @prop {Function} */\n onLoad: applyStyleOnLoad,\n /**\n * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier\n * @prop {Boolean} gpuAcceleration=true\n * If true, it uses the CSS 3d transformation to position the popper.\n * Otherwise, it will use the `top` and `left` properties.\n */\n gpuAcceleration: undefined\n }\n};\n\n/**\n * The `dataObject` is an object containing all the informations used by Popper.js\n * this object get passed to modifiers and to the `onCreate` and `onUpdate` callbacks.\n * @name dataObject\n * @property {Object} data.instance The Popper.js instance\n * @property {String} data.placement Placement applied to popper\n * @property {String} data.originalPlacement Placement originally defined on init\n * @property {Boolean} data.flipped True if popper has been flipped by flip modifier\n * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper.\n * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier\n * @property {Object} data.styles Any CSS property defined here will be applied to the popper, it expects the JavaScript nomenclature (eg. `marginBottom`)\n * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow, it expects the JavaScript nomenclature (eg. `marginBottom`)\n * @property {Object} data.boundaries Offsets of the popper boundaries\n * @property {Object} data.offsets The measurements of popper, reference and arrow elements.\n * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values\n * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values\n * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0\n */\n\n/**\n * Default options provided to Popper.js constructor.<br />\n * These can be overriden using the `options` argument of Popper.js.<br />\n * To override an option, simply pass as 3rd argument an object with the same\n * structure of this object, example:\n * ```\n * new Popper(ref, pop, {\n * modifiers: {\n * preventOverflow: { enabled: false }\n * }\n * })\n * ```\n * @type {Object}\n * @static\n * @memberof Popper\n */\nvar Defaults = {\n /**\n * Popper's placement\n * @prop {Popper.placements} placement='bottom'\n */\n placement: 'bottom',\n\n /**\n * Whether events (resize, scroll) are initially enabled\n * @prop {Boolean} eventsEnabled=true\n */\n eventsEnabled: true,\n\n /**\n * Set to true if you want to automatically remove the popper when\n * you call the `destroy` method.\n * @prop {Boolean} removeOnDestroy=false\n */\n removeOnDestroy: false,\n\n /**\n * Callback called when the popper is created.<br />\n * By default, is set to no-op.<br />\n * Access Popper.js instance with `data.instance`.\n * @prop {onCreate}\n */\n onCreate: function onCreate() {},\n\n /**\n * Callback called when the popper is updated, this callback is not called\n * on the initialization/creation of the popper, but only on subsequent\n * updates.<br />\n * By default, is set to no-op.<br />\n * Access Popper.js instance with `data.instance`.\n * @prop {onUpdate}\n */\n onUpdate: function onUpdate() {},\n\n /**\n * List of modifiers used to modify the offsets before they are applied to the popper.\n * They provide most of the functionalities of Popper.js\n * @prop {modifiers}\n */\n modifiers: modifiers\n};\n\n/**\n * @callback onCreate\n * @param {dataObject} data\n */\n\n/**\n * @callback onUpdate\n * @param {dataObject} data\n */\n\n// Utils\n// Methods\nvar Popper = function () {\n /**\n * Create a new Popper.js instance\n * @class Popper\n * @param {HTMLElement|referenceObject} reference - The reference element used to position the popper\n * @param {HTMLElement} popper - The HTML element used as popper.\n * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)\n * @return {Object} instance - The generated Popper.js instance\n */\n function Popper(reference, popper) {\n var _this = this;\n\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n classCallCheck(this, Popper);\n\n this.scheduleUpdate = function () {\n return requestAnimationFrame(_this.update);\n };\n\n // make update() debounced, so that it only runs at most once-per-tick\n this.update = debounce(this.update.bind(this));\n\n // with {} we create a new object with the options inside it\n this.options = _extends({}, Popper.Defaults, options);\n\n // init state\n this.state = {\n isDestroyed: false,\n isCreated: false,\n scrollParents: []\n };\n\n // get reference and popper elements (allow jQuery wrappers)\n this.reference = reference && reference.jquery ? reference[0] : reference;\n this.popper = popper && popper.jquery ? popper[0] : popper;\n\n // Deep merge modifiers options\n this.options.modifiers = {};\n Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {\n _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});\n });\n\n // Refactoring modifiers' list (Object => Array)\n this.modifiers = Object.keys(this.options.modifiers).map(function (name) {\n return _extends({\n name: name\n }, _this.options.modifiers[name]);\n })\n // sort the modifiers by order\n .sort(function (a, b) {\n return a.order - b.order;\n });\n\n // modifiers have the ability to execute arbitrary code when Popper.js get inited\n // such code is executed in the same order of its modifier\n // they could add new properties to their options configuration\n // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!\n this.modifiers.forEach(function (modifierOptions) {\n if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {\n modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);\n }\n });\n\n // fire the first update to position the popper in the right place\n this.update();\n\n var eventsEnabled = this.options.eventsEnabled;\n if (eventsEnabled) {\n // setup event listeners, they will take care of update the position in specific situations\n this.enableEventListeners();\n }\n\n this.state.eventsEnabled = eventsEnabled;\n }\n\n // We can't use class properties because they don't get listed in the\n // class prototype and break stuff like Sinon stubs\n\n\n createClass(Popper, [{\n key: 'update',\n value: function update$$1() {\n return update.call(this);\n }\n }, {\n key: 'destroy',\n value: function destroy$$1() {\n return destroy.call(this);\n }\n }, {\n key: 'enableEventListeners',\n value: function enableEventListeners$$1() {\n return enableEventListeners.call(this);\n }\n }, {\n key: 'disableEventListeners',\n value: function disableEventListeners$$1() {\n return disableEventListeners.call(this);\n }\n\n /**\n * Schedule an update, it will run on the next UI update available\n * @method scheduleUpdate\n * @memberof Popper\n */\n\n\n /**\n * Collection of utilities useful when writing custom modifiers.\n * Starting from version 1.7, this method is available only if you\n * include `popper-utils.js` before `popper.js`.\n *\n * **DEPRECATION**: This way to access PopperUtils is deprecated\n * and will be removed in v2! Use the PopperUtils module directly instead.\n * Due to the high instability of the methods contained in Utils, we can't\n * guarantee them to follow semver. Use them at your own risk!\n * @static\n * @private\n * @type {Object}\n * @deprecated since version 1.8\n * @member Utils\n * @memberof Popper\n */\n\n }]);\n return Popper;\n}();\n\n/**\n * The `referenceObject` is an object that provides an interface compatible with Popper.js\n * and lets you use it as replacement of a real DOM node.<br />\n * You can use this method to position a popper relatively to a set of coordinates\n * in case you don't have a DOM node to use as reference.\n *\n * ```\n * new Popper(referenceObject, popperNode);\n * ```\n *\n * NB: This feature isn't supported in Internet Explorer 10\n * @name referenceObject\n * @property {Function} data.getBoundingClientRect\n * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.\n * @property {number} data.clientWidth\n * An ES6 getter that will return the width of the virtual reference element.\n * @property {number} data.clientHeight\n * An ES6 getter that will return the height of the virtual reference element.\n */\n\n\nPopper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils;\nPopper.placements = placements;\nPopper.Defaults = Defaults;\n\nexport default Popper;\n//# sourceMappingURL=popper.js.map\n","import $ from 'jquery'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.0.0): util.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Util = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Private TransitionEnd Helpers\n * ------------------------------------------------------------------------\n */\n\n let transition = false\n\n const MAX_UID = 1000000\n\n // Shoutout AngusCroll (https://goo.gl/pxwQGp)\n function toType(obj) {\n return {}.toString.call(obj).match(/\\s([a-zA-Z]+)/)[1].toLowerCase()\n }\n\n function getSpecialTransitionEndEvent() {\n return {\n bindType: transition.end,\n delegateType: transition.end,\n handle(event) {\n if ($(event.target).is(this)) {\n return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params\n }\n return undefined // eslint-disable-line no-undefined\n }\n }\n }\n\n function transitionEndTest() {\n if (typeof window !== 'undefined' && window.QUnit) {\n return false\n }\n\n return {\n end: 'transitionend'\n }\n }\n\n function transitionEndEmulator(duration) {\n let called = false\n\n $(this).one(Util.TRANSITION_END, () => {\n called = true\n })\n\n setTimeout(() => {\n if (!called) {\n Util.triggerTransitionEnd(this)\n }\n }, duration)\n\n return this\n }\n\n function setTransitionEndSupport() {\n transition = transitionEndTest()\n\n $.fn.emulateTransitionEnd = transitionEndEmulator\n\n if (Util.supportsTransitionEnd()) {\n $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()\n }\n }\n\n function escapeId(selector) {\n // We escape IDs in case of special selectors (selector = '#myId:something')\n // $.escapeSelector does not exist in jQuery < 3\n selector = typeof $.escapeSelector === 'function' ? $.escapeSelector(selector).substr(1)\n : selector.replace(/(:|\\.|\\[|\\]|,|=|@)/g, '\\\\$1')\n\n return selector\n }\n\n /**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\n const Util = {\n\n TRANSITION_END: 'bsTransitionEnd',\n\n getUID(prefix) {\n do {\n // eslint-disable-next-line no-bitwise\n prefix += ~~(Math.random() * MAX_UID) // \"~~\" acts like a faster Math.floor() here\n } while (document.getElementById(prefix))\n return prefix\n },\n\n getSelectorFromElement(element) {\n let selector = element.getAttribute('data-target')\n if (!selector || selector === '#') {\n selector = element.getAttribute('href') || ''\n }\n\n // If it's an ID\n if (selector.charAt(0) === '#') {\n selector = escapeId(selector)\n }\n\n try {\n const $selector = $(document).find(selector)\n return $selector.length > 0 ? selector : null\n } catch (err) {\n return null\n }\n },\n\n reflow(element) {\n return element.offsetHeight\n },\n\n triggerTransitionEnd(element) {\n $(element).trigger(transition.end)\n },\n\n supportsTransitionEnd() {\n return Boolean(transition)\n },\n\n isElement(obj) {\n return (obj[0] || obj).nodeType\n },\n\n typeCheckConfig(componentName, config, configTypes) {\n for (const property in configTypes) {\n if (Object.prototype.hasOwnProperty.call(configTypes, property)) {\n const expectedTypes = configTypes[property]\n const value = config[property]\n const valueType = value && Util.isElement(value)\n ? 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new Error(\n `${componentName.toUpperCase()}: ` +\n `Option \"${property}\" provided type \"${valueType}\" ` +\n `but expected type \"${expectedTypes}\".`)\n }\n }\n }\n }\n }\n\n setTransitionEndSupport()\n\n return Util\n})($)\n\nexport default Util\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.0.0): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Alert = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'alert'\n const VERSION = '4.0.0'\n const DATA_KEY = 'bs.alert'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const TRANSITION_DURATION = 150\n\n const Selector = {\n DISMISS : '[data-dismiss=\"alert\"]'\n }\n\n const Event = {\n CLOSE : `close${EVENT_KEY}`,\n CLOSED : `closed${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n ALERT : 'alert',\n FADE : 'fade',\n SHOW : 'show'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n element = element || this._element\n\n const rootElement = this._getRootElement(element)\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = $(selector)[0]\n }\n\n if (!parent) {\n parent = $(element).closest(`.${ClassName.ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(Event.CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(ClassName.SHOW)\n\n if (!Util.supportsTransitionEnd() ||\n !$(element).hasClass(ClassName.FADE)) {\n this._destroyElement(element)\n return\n }\n\n $(element)\n .one(Util.TRANSITION_END, (event) => this._destroyElement(element, event))\n .emulateTransitionEnd(TRANSITION_DURATION)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(Event.CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document).on(\n Event.CLICK_DATA_API,\n Selector.DISMISS,\n Alert._handleDismiss(new Alert())\n )\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Alert._jQueryInterface\n $.fn[NAME].Constructor = Alert\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n }\n\n return Alert\n})($)\n\nexport default Alert\n","import $ from 'jquery'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.0.0): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Button = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'button'\n const VERSION = '4.0.0'\n const DATA_KEY = 'bs.button'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n\n const ClassName = {\n ACTIVE : 'active',\n BUTTON : 'btn',\n FOCUS : 'focus'\n }\n\n const Selector = {\n DATA_TOGGLE_CARROT : '[data-toggle^=\"button\"]',\n DATA_TOGGLE : '[data-toggle=\"buttons\"]',\n INPUT : 'input',\n ACTIVE : '.active',\n BUTTON : '.btn'\n }\n\n const Event = {\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,\n FOCUS_BLUR_DATA_API : `focus${EVENT_KEY}${DATA_API_KEY} ` +\n `blur${EVENT_KEY}${DATA_API_KEY}`\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Button {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n toggle() {\n let triggerChangeEvent = true\n let addAriaPressed = true\n const rootElement = $(this._element).closest(\n Selector.DATA_TOGGLE\n )[0]\n\n if (rootElement) {\n const input = $(this._element).find(Selector.INPUT)[0]\n\n if (input) {\n if (input.type === 'radio') {\n if (input.checked &&\n $(this._element).hasClass(ClassName.ACTIVE)) {\n triggerChangeEvent = false\n } else {\n const activeElement = $(rootElement).find(Selector.ACTIVE)[0]\n\n if (activeElement) {\n $(activeElement).removeClass(ClassName.ACTIVE)\n }\n }\n }\n\n if (triggerChangeEvent) {\n if (input.hasAttribute('disabled') ||\n rootElement.hasAttribute('disabled') ||\n input.classList.contains('disabled') ||\n rootElement.classList.contains('disabled')) {\n return\n }\n input.checked = !$(this._element).hasClass(ClassName.ACTIVE)\n $(input).trigger('change')\n }\n\n input.focus()\n addAriaPressed = false\n }\n }\n\n if (addAriaPressed) {\n this._element.setAttribute('aria-pressed',\n !$(this._element).hasClass(ClassName.ACTIVE))\n }\n\n if (triggerChangeEvent) {\n $(this._element).toggleClass(ClassName.ACTIVE)\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n\n if (!data) {\n data = new Button(this)\n $(this).data(DATA_KEY, data)\n }\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document)\n .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {\n event.preventDefault()\n\n let button = event.target\n\n if (!$(button).hasClass(ClassName.BUTTON)) {\n button = $(button).closest(Selector.BUTTON)\n }\n\n Button._jQueryInterface.call($(button), 'toggle')\n })\n .on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {\n const button = $(event.target).closest(Selector.BUTTON)[0]\n $(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type))\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Button._jQueryInterface\n $.fn[NAME].Constructor = Button\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Button._jQueryInterface\n }\n\n return Button\n})($)\n\nexport default Button\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.0.0): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Carousel = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'carousel'\n const VERSION = '4.0.0'\n const DATA_KEY = 'bs.carousel'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const TRANSITION_DURATION = 600\n const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key\n const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key\n const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\n\n const Default = {\n interval : 5000,\n keyboard : true,\n slide : false,\n pause : 'hover',\n wrap : true\n }\n\n const DefaultType = {\n interval : '(number|boolean)',\n keyboard : 'boolean',\n slide : '(boolean|string)',\n pause : '(string|boolean)',\n wrap : 'boolean'\n }\n\n const Direction = {\n NEXT : 'next',\n PREV : 'prev',\n LEFT : 'left',\n RIGHT : 'right'\n }\n\n const Event = {\n SLIDE : `slide${EVENT_KEY}`,\n SLID : `slid${EVENT_KEY}`,\n KEYDOWN : `keydown${EVENT_KEY}`,\n MOUSEENTER : `mouseenter${EVENT_KEY}`,\n MOUSELEAVE : `mouseleave${EVENT_KEY}`,\n TOUCHEND : `touchend${EVENT_KEY}`,\n LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n CAROUSEL : 'carousel',\n ACTIVE : 'active',\n SLIDE : 'slide',\n RIGHT : 'carousel-item-right',\n LEFT : 'carousel-item-left',\n NEXT : 'carousel-item-next',\n PREV : 'carousel-item-prev',\n ITEM : 'carousel-item'\n }\n\n const Selector = {\n ACTIVE : '.active',\n ACTIVE_ITEM : '.active.carousel-item',\n ITEM : '.carousel-item',\n NEXT_PREV : '.carousel-item-next, .carousel-item-prev',\n INDICATORS : '.carousel-indicators',\n DATA_SLIDE : '[data-slide], [data-slide-to]',\n DATA_RIDE : '[data-ride=\"carousel\"]'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Carousel {\n constructor(element, config) {\n this._items = null\n this._interval = null\n this._activeElement = null\n\n this._isPaused = false\n this._isSliding = false\n\n this.touchTimeout = null\n\n this._config = this._getConfig(config)\n this._element = $(element)[0]\n this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0]\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n next() {\n if (!this._isSliding) {\n this._slide(Direction.NEXT)\n }\n }\n\n nextWhenVisible() {\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden &&\n ($(this._element).is(':visible') && $(this._element).css('visibility') !== 'hidden')) {\n this.next()\n }\n }\n\n prev() {\n if (!this._isSliding) {\n this._slide(Direction.PREV)\n }\n }\n\n pause(event) {\n if (!event) {\n this._isPaused = true\n }\n\n if ($(this._element).find(Selector.NEXT_PREV)[0] &&\n Util.supportsTransitionEnd()) {\n Util.triggerTransitionEnd(this._element)\n this.cycle(true)\n }\n\n clearInterval(this._interval)\n this._interval = null\n }\n\n cycle(event) {\n if (!event) {\n this._isPaused = false\n }\n\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n\n if (this._config.interval && !this._isPaused) {\n this._interval = setInterval(\n (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),\n this._config.interval\n )\n }\n }\n\n to(index) {\n this._activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0]\n\n const activeIndex = this._getItemIndex(this._activeElement)\n\n if (index > this._items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n $(this._element).one(Event.SLID, () => this.to(index))\n return\n }\n\n if (activeIndex === index) {\n this.pause()\n this.cycle()\n return\n }\n\n const direction = index > activeIndex\n ? Direction.NEXT\n : Direction.PREV\n\n this._slide(direction, this._items[index])\n }\n\n dispose() {\n $(this._element).off(EVENT_KEY)\n $.removeData(this._element, DATA_KEY)\n\n this._items = null\n this._config = null\n this._element = null\n this._interval = null\n this._isPaused = null\n this._isSliding = null\n this._activeElement = null\n this._indicatorsElement = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n $(this._element)\n .on(Event.KEYDOWN, (event) => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n $(this._element)\n .on(Event.MOUSEENTER, (event) => this.pause(event))\n .on(Event.MOUSELEAVE, (event) => this.cycle(event))\n if ('ontouchstart' in document.documentElement) {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n $(this._element).on(Event.TOUCHEND, () => {\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n this.touchTimeout = setTimeout((event) => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n })\n }\n }\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault()\n this.prev()\n break\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault()\n this.next()\n break\n default:\n }\n }\n\n _getItemIndex(element) {\n this._items = $.makeArray($(element).parent().find(Selector.ITEM))\n return this._items.indexOf(element)\n }\n\n _getItemByDirection(direction, activeElement) {\n const isNextDirection = direction === Direction.NEXT\n const isPrevDirection = direction === Direction.PREV\n const activeIndex = this._getItemIndex(activeElement)\n const lastItemIndex = this._items.length - 1\n const isGoingToWrap = isPrevDirection && activeIndex === 0 ||\n isNextDirection && activeIndex === lastItemIndex\n\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement\n }\n\n const delta = direction === Direction.PREV ? -1 : 1\n const itemIndex = (activeIndex + delta) % this._items.length\n\n return itemIndex === -1\n ? this._items[this._items.length - 1] : this._items[itemIndex]\n }\n\n _triggerSlideEvent(relatedTarget, eventDirectionName) {\n const targetIndex = this._getItemIndex(relatedTarget)\n const fromIndex = this._getItemIndex($(this._element).find(Selector.ACTIVE_ITEM)[0])\n const slideEvent = $.Event(Event.SLIDE, {\n relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n })\n\n $(this._element).trigger(slideEvent)\n\n return slideEvent\n }\n\n _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n $(this._indicatorsElement)\n .find(Selector.ACTIVE)\n .removeClass(ClassName.ACTIVE)\n\n const nextIndicator = this._indicatorsElement.children[\n this._getItemIndex(element)\n ]\n\n if (nextIndicator) {\n $(nextIndicator).addClass(ClassName.ACTIVE)\n }\n }\n }\n\n _slide(direction, element) {\n const activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0]\n const activeElementIndex = this._getItemIndex(activeElement)\n const nextElement = element || activeElement &&\n this._getItemByDirection(direction, activeElement)\n const nextElementIndex = this._getItemIndex(nextElement)\n const isCycling = Boolean(this._interval)\n\n let directionalClassName\n let orderClassName\n let eventDirectionName\n\n if (direction === Direction.NEXT) {\n directionalClassName = ClassName.LEFT\n orderClassName = ClassName.NEXT\n eventDirectionName = Direction.LEFT\n } else {\n directionalClassName = ClassName.RIGHT\n orderClassName = ClassName.PREV\n eventDirectionName = Direction.RIGHT\n }\n\n if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {\n this._isSliding = false\n return\n }\n\n const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)\n if (slideEvent.isDefaultPrevented()) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return\n }\n\n this._isSliding = true\n\n if (isCycling) {\n this.pause()\n }\n\n this._setActiveIndicatorElement(nextElement)\n\n const slidEvent = $.Event(Event.SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n })\n\n if (Util.supportsTransitionEnd() &&\n $(this._element).hasClass(ClassName.SLIDE)) {\n $(nextElement).addClass(orderClassName)\n\n Util.reflow(nextElement)\n\n $(activeElement).addClass(directionalClassName)\n $(nextElement).addClass(directionalClassName)\n\n $(activeElement)\n .one(Util.TRANSITION_END, () => {\n $(nextElement)\n .removeClass(`${directionalClassName} ${orderClassName}`)\n .addClass(ClassName.ACTIVE)\n\n $(activeElement).removeClass(`${ClassName.ACTIVE} ${orderClassName} ${directionalClassName}`)\n\n this._isSliding = false\n\n setTimeout(() => $(this._element).trigger(slidEvent), 0)\n })\n .emulateTransitionEnd(TRANSITION_DURATION)\n } else {\n $(activeElement).removeClass(ClassName.ACTIVE)\n $(nextElement).addClass(ClassName.ACTIVE)\n\n this._isSliding = false\n $(this._element).trigger(slidEvent)\n }\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n let _config = {\n ...Default,\n ...$(this).data()\n }\n\n if (typeof config === 'object') {\n _config = {\n ..._config,\n ...config\n }\n }\n\n const action = typeof config === 'string' ? config : _config.slide\n\n if (!data) {\n data = new Carousel(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'number') {\n data.to(config)\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(`No method named \"${action}\"`)\n }\n data[action]()\n } else if (_config.interval) {\n data.pause()\n data.cycle()\n }\n })\n }\n\n static _dataApiClickHandler(event) {\n const selector = Util.getSelectorFromElement(this)\n\n if (!selector) {\n return\n }\n\n const target = $(selector)[0]\n\n if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {\n return\n }\n\n const config = {\n ...$(target).data(),\n ...$(this).data()\n }\n const slideIndex = this.getAttribute('data-slide-to')\n\n if (slideIndex) {\n config.interval = false\n }\n\n Carousel._jQueryInterface.call($(target), config)\n\n if (slideIndex) {\n $(target).data(DATA_KEY).to(slideIndex)\n }\n\n event.preventDefault()\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document)\n .on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler)\n\n $(window).on(Event.LOAD_DATA_API, () => {\n $(Selector.DATA_RIDE).each(function () {\n const $carousel = $(this)\n Carousel._jQueryInterface.call($carousel, $carousel.data())\n })\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Carousel._jQueryInterface\n $.fn[NAME].Constructor = Carousel\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Carousel._jQueryInterface\n }\n\n return Carousel\n})($)\n\nexport default Carousel\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.0.0): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Collapse = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'collapse'\n const VERSION = '4.0.0'\n const DATA_KEY = 'bs.collapse'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const TRANSITION_DURATION = 600\n\n const Default = {\n toggle : true,\n parent : ''\n }\n\n const DefaultType = {\n toggle : 'boolean',\n parent : '(string|element)'\n }\n\n const Event = {\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n SHOW : 'show',\n COLLAPSE : 'collapse',\n COLLAPSING : 'collapsing',\n COLLAPSED : 'collapsed'\n }\n\n const Dimension = {\n WIDTH : 'width',\n HEIGHT : 'height'\n }\n\n const Selector = {\n ACTIVES : '.show, .collapsing',\n DATA_TOGGLE : '[data-toggle=\"collapse\"]'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Collapse {\n constructor(element, config) {\n this._isTransitioning = false\n this._element = element\n this._config = this._getConfig(config)\n this._triggerArray = $.makeArray($(\n `[data-toggle=\"collapse\"][href=\"#${element.id}\"],` +\n `[data-toggle=\"collapse\"][data-target=\"#${element.id}\"]`\n ))\n const tabToggles = $(Selector.DATA_TOGGLE)\n for (let i = 0; i < tabToggles.length; i++) {\n const elem = tabToggles[i]\n const selector = Util.getSelectorFromElement(elem)\n if (selector !== null && $(selector).filter(element).length > 0) {\n this._selector = selector\n this._triggerArray.push(elem)\n }\n }\n\n this._parent = this._config.parent ? this._getParent() : null\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray)\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle() {\n if ($(this._element).hasClass(ClassName.SHOW)) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning ||\n $(this._element).hasClass(ClassName.SHOW)) {\n return\n }\n\n let actives\n let activesData\n\n if (this._parent) {\n actives = $.makeArray(\n $(this._parent)\n .find(Selector.ACTIVES)\n .filter(`[data-parent=\"${this._config.parent}\"]`)\n )\n if (actives.length === 0) {\n actives = null\n }\n }\n\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY)\n if (activesData && activesData._isTransitioning) {\n return\n }\n }\n\n const startEvent = $.Event(Event.SHOW)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')\n if (!activesData) {\n $(actives).data(DATA_KEY, null)\n }\n }\n\n const dimension = this._getDimension()\n\n $(this._element)\n .removeClass(ClassName.COLLAPSE)\n .addClass(ClassName.COLLAPSING)\n\n this._element.style[dimension] = 0\n\n if (this._triggerArray.length > 0) {\n $(this._triggerArray)\n .removeClass(ClassName.COLLAPSED)\n .attr('aria-expanded', true)\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n $(this._element)\n .removeClass(ClassName.COLLAPSING)\n .addClass(ClassName.COLLAPSE)\n .addClass(ClassName.SHOW)\n\n this._element.style[dimension] = ''\n\n this.setTransitioning(false)\n\n $(this._element).trigger(Event.SHOWN)\n }\n\n if (!Util.supportsTransitionEnd()) {\n complete()\n return\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(TRANSITION_DURATION)\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning ||\n !$(this._element).hasClass(ClassName.SHOW)) {\n return\n }\n\n const startEvent = $.Event(Event.HIDE)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n Util.reflow(this._element)\n\n $(this._element)\n .addClass(ClassName.COLLAPSING)\n .removeClass(ClassName.COLLAPSE)\n .removeClass(ClassName.SHOW)\n\n if (this._triggerArray.length > 0) {\n for (let i = 0; i < this._triggerArray.length; i++) {\n const trigger = this._triggerArray[i]\n const selector = Util.getSelectorFromElement(trigger)\n if (selector !== null) {\n const $elem = $(selector)\n if (!$elem.hasClass(ClassName.SHOW)) {\n $(trigger).addClass(ClassName.COLLAPSED)\n .attr('aria-expanded', false)\n }\n }\n }\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n this.setTransitioning(false)\n $(this._element)\n .removeClass(ClassName.COLLAPSING)\n .addClass(ClassName.COLLAPSE)\n .trigger(Event.HIDDEN)\n }\n\n this._element.style[dimension] = ''\n\n if (!Util.supportsTransitionEnd()) {\n complete()\n return\n }\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(TRANSITION_DURATION)\n }\n\n setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._parent = null\n this._element = null\n this._triggerArray = null\n this._isTransitioning = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n config.toggle = Boolean(config.toggle) // Coerce string values\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _getDimension() {\n const hasWidth = $(this._element).hasClass(Dimension.WIDTH)\n return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT\n }\n\n _getParent() {\n let parent = null\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent\n\n // It's a jQuery object\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0]\n }\n } else {\n parent = $(this._config.parent)[0]\n }\n\n const selector =\n `[data-toggle=\"collapse\"][data-parent=\"${this._config.parent}\"]`\n\n $(parent).find(selector).each((i, element) => {\n this._addAriaAndCollapsedClass(\n Collapse._getTargetFromElement(element),\n [element]\n )\n })\n\n return parent\n }\n\n _addAriaAndCollapsedClass(element, triggerArray) {\n if (element) {\n const isOpen = $(element).hasClass(ClassName.SHOW)\n\n if (triggerArray.length > 0) {\n $(triggerArray)\n .toggleClass(ClassName.COLLAPSED, !isOpen)\n .attr('aria-expanded', isOpen)\n }\n }\n }\n\n // Static\n\n static _getTargetFromElement(element) {\n const selector = Util.getSelectorFromElement(element)\n return selector ? $(selector)[0] : null\n }\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n const _config = {\n ...Default,\n ...$this.data(),\n ...typeof config === 'object' && config\n }\n\n if (!data && _config.toggle && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n if (!data) {\n data = new Collapse(this, _config)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {\n // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault()\n }\n\n const $trigger = $(this)\n const selector = Util.getSelectorFromElement(this)\n $(selector).each(function () {\n const $target = $(this)\n const data = $target.data(DATA_KEY)\n const config = data ? 'toggle' : $trigger.data()\n Collapse._jQueryInterface.call($target, config)\n })\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Collapse._jQueryInterface\n $.fn[NAME].Constructor = Collapse\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Collapse._jQueryInterface\n }\n\n return Collapse\n})($)\n\nexport default Collapse\n","import $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.0.0): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Dropdown = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'dropdown'\n const VERSION = '4.0.0'\n const DATA_KEY = 'bs.dropdown'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key\n const TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key\n const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key\n const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key\n const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)\n const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)\n\n const Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n CLICK : `click${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,\n KEYDOWN_DATA_API : `keydown${EVENT_KEY}${DATA_API_KEY}`,\n KEYUP_DATA_API : `keyup${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n DISABLED : 'disabled',\n SHOW : 'show',\n DROPUP : 'dropup',\n DROPRIGHT : 'dropright',\n DROPLEFT : 'dropleft',\n MENURIGHT : 'dropdown-menu-right',\n MENULEFT : 'dropdown-menu-left',\n POSITION_STATIC : 'position-static'\n }\n\n const Selector = {\n DATA_TOGGLE : '[data-toggle=\"dropdown\"]',\n FORM_CHILD : '.dropdown form',\n MENU : '.dropdown-menu',\n NAVBAR_NAV : '.navbar-nav',\n VISIBLE_ITEMS : '.dropdown-menu .dropdown-item:not(.disabled)'\n }\n\n const AttachmentMap = {\n TOP : 'top-start',\n TOPEND : 'top-end',\n BOTTOM : 'bottom-start',\n BOTTOMEND : 'bottom-end',\n RIGHT : 'right-start',\n RIGHTEND : 'right-end',\n LEFT : 'left-start',\n LEFTEND : 'left-end'\n }\n\n const Default = {\n offset : 0,\n flip : true,\n boundary : 'scrollParent'\n }\n\n const DefaultType = {\n offset : '(number|string|function)',\n flip : 'boolean',\n boundary : '(string|element)'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Dropdown {\n constructor(element, config) {\n this._element = element\n this._popper = null\n this._config = this._getConfig(config)\n this._menu = this._getMenuElement()\n this._inNavbar = this._detectNavbar()\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n toggle() {\n if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this._element)\n const isActive = $(this._menu).hasClass(ClassName.SHOW)\n\n Dropdown._clearMenus()\n\n if (isActive) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const showEvent = $.Event(Event.SHOW, relatedTarget)\n\n $(parent).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n // Disable totally Popper.js for Dropdown in Navbar\n if (!this._inNavbar) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap dropdown require Popper.js (https://popper.js.org)')\n }\n let element = this._element\n // For dropup with alignment we use the parent as popper container\n if ($(parent).hasClass(ClassName.DROPUP)) {\n if ($(this._menu).hasClass(ClassName.MENULEFT) || $(this._menu).hasClass(ClassName.MENURIGHT)) {\n element = parent\n }\n }\n // If boundary is not `scrollParent`, then set position to `static`\n // to allow the menu to \"escape\" the scroll parent's boundaries\n // https://github.com/twbs/bootstrap/issues/24251\n if (this._config.boundary !== 'scrollParent') {\n $(parent).addClass(ClassName.POSITION_STATIC)\n }\n this._popper = new Popper(element, this._menu, this._getPopperConfig())\n }\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement &&\n $(parent).closest(Selector.NAVBAR_NAV).length === 0) {\n $('body').children().on('mouseover', null, $.noop)\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n $(this._menu).toggleClass(ClassName.SHOW)\n $(parent)\n .toggleClass(ClassName.SHOW)\n .trigger($.Event(Event.SHOWN, relatedTarget))\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._element).off(EVENT_KEY)\n this._element = null\n this._menu = null\n if (this._popper !== null) {\n this._popper.destroy()\n this._popper = null\n }\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Private\n\n _addEventListeners() {\n $(this._element).on(Event.CLICK, (event) => {\n event.preventDefault()\n event.stopPropagation()\n this.toggle()\n })\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this._element).data(),\n ...config\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getMenuElement() {\n if (!this._menu) {\n const parent = Dropdown._getParentFromElement(this._element)\n this._menu = $(parent).find(Selector.MENU)[0]\n }\n return this._menu\n }\n\n _getPlacement() {\n const $parentDropdown = $(this._element).parent()\n let placement = AttachmentMap.BOTTOM\n\n // Handle dropup\n if ($parentDropdown.hasClass(ClassName.DROPUP)) {\n placement = AttachmentMap.TOP\n if ($(this._menu).hasClass(ClassName.MENURIGHT)) {\n placement = AttachmentMap.TOPEND\n }\n } else if ($parentDropdown.hasClass(ClassName.DROPRIGHT)) {\n placement = AttachmentMap.RIGHT\n } else if ($parentDropdown.hasClass(ClassName.DROPLEFT)) {\n placement = AttachmentMap.LEFT\n } else if ($(this._menu).hasClass(ClassName.MENURIGHT)) {\n placement = AttachmentMap.BOTTOMEND\n }\n return placement\n }\n\n _detectNavbar() {\n return $(this._element).closest('.navbar').length > 0\n }\n\n _getPopperConfig() {\n const offsetConf = {}\n if (typeof this._config.offset === 'function') {\n offsetConf.fn = (data) => {\n data.offsets = {\n ...data.offsets,\n ...this._config.offset(data.offsets) || {}\n }\n return data\n }\n } else {\n offsetConf.offset = this._config.offset\n }\n const popperConfig = {\n placement: this._getPlacement(),\n modifiers: {\n offset: offsetConf,\n flip: {\n enabled: this._config.flip\n },\n preventOverflow: {\n boundariesElement: this._config.boundary\n }\n }\n }\n\n return popperConfig\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data) {\n data = new Dropdown(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n\n static _clearMenus(event) {\n if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||\n event.type === 'keyup' && event.which !== TAB_KEYCODE)) {\n return\n }\n\n const toggles = $.makeArray($(Selector.DATA_TOGGLE))\n for (let i = 0; i < toggles.length; i++) {\n const parent = Dropdown._getParentFromElement(toggles[i])\n const context = $(toggles[i]).data(DATA_KEY)\n const relatedTarget = {\n relatedTarget: toggles[i]\n }\n\n if (!context) {\n continue\n }\n\n const dropdownMenu = context._menu\n if (!$(parent).hasClass(ClassName.SHOW)) {\n continue\n }\n\n if (event && (event.type === 'click' &&\n /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&\n $.contains(parent, event.target)) {\n continue\n }\n\n const hideEvent = $.Event(Event.HIDE, relatedTarget)\n $(parent).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n continue\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $('body').children().off('mouseover', null, $.noop)\n }\n\n toggles[i].setAttribute('aria-expanded', 'false')\n\n $(dropdownMenu).removeClass(ClassName.SHOW)\n $(parent)\n .removeClass(ClassName.SHOW)\n .trigger($.Event(Event.HIDDEN, relatedTarget))\n }\n }\n\n static _getParentFromElement(element) {\n let parent\n const selector = Util.getSelectorFromElement(element)\n\n if (selector) {\n parent = $(selector)[0]\n }\n\n return parent || element.parentNode\n }\n\n // eslint-disable-next-line complexity\n static _dataApiKeydownHandler(event) {\n // If not input/textarea:\n // - And not a key in REGEXP_KEYDOWN => not a dropdown command\n // If input/textarea:\n // - If space key => not a dropdown command\n // - If key is other than escape\n // - If key is not up or down => not a dropdown command\n // - If trigger inside the menu => not a dropdown command\n if (/input|textarea/i.test(event.target.tagName)\n ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&\n (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||\n $(event.target).closest(Selector.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this)\n const isActive = $(parent).hasClass(ClassName.SHOW)\n\n if (!isActive && (event.which !== ESCAPE_KEYCODE || event.which !== SPACE_KEYCODE) ||\n isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {\n if (event.which === ESCAPE_KEYCODE) {\n const toggle = $(parent).find(Selector.DATA_TOGGLE)[0]\n $(toggle).trigger('focus')\n }\n\n $(this).trigger('click')\n return\n }\n\n const items = $(parent).find(Selector.VISIBLE_ITEMS).get()\n\n if (items.length === 0) {\n return\n }\n\n let index = items.indexOf(event.target)\n\n if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up\n index--\n }\n\n if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down\n index++\n }\n\n if (index < 0) {\n index = 0\n }\n\n items[index].focus()\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document)\n .on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler)\n .on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler)\n .on(`${Event.CLICK_DATA_API} ${Event.KEYUP_DATA_API}`, Dropdown._clearMenus)\n .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {\n event.preventDefault()\n event.stopPropagation()\n Dropdown._jQueryInterface.call($(this), 'toggle')\n })\n .on(Event.CLICK_DATA_API, Selector.FORM_CHILD, (e) => {\n e.stopPropagation()\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Dropdown._jQueryInterface\n $.fn[NAME].Constructor = Dropdown\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Dropdown._jQueryInterface\n }\n\n return Dropdown\n})($, Popper)\n\nexport default Dropdown\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.0.0): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Modal = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'modal'\n const VERSION = '4.0.0'\n const DATA_KEY = 'bs.modal'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const TRANSITION_DURATION = 300\n const BACKDROP_TRANSITION_DURATION = 150\n const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n\n const Default = {\n backdrop : true,\n keyboard : true,\n focus : true,\n show : true\n }\n\n const DefaultType = {\n backdrop : '(boolean|string)',\n keyboard : 'boolean',\n focus : 'boolean',\n show : 'boolean'\n }\n\n const Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n FOCUSIN : `focusin${EVENT_KEY}`,\n RESIZE : `resize${EVENT_KEY}`,\n CLICK_DISMISS : `click.dismiss${EVENT_KEY}`,\n KEYDOWN_DISMISS : `keydown.dismiss${EVENT_KEY}`,\n MOUSEUP_DISMISS : `mouseup.dismiss${EVENT_KEY}`,\n MOUSEDOWN_DISMISS : `mousedown.dismiss${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n SCROLLBAR_MEASURER : 'modal-scrollbar-measure',\n BACKDROP : 'modal-backdrop',\n OPEN : 'modal-open',\n FADE : 'fade',\n SHOW : 'show'\n }\n\n const Selector = {\n DIALOG : '.modal-dialog',\n DATA_TOGGLE : '[data-toggle=\"modal\"]',\n DATA_DISMISS : '[data-dismiss=\"modal\"]',\n FIXED_CONTENT : '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',\n STICKY_CONTENT : '.sticky-top',\n NAVBAR_TOGGLER : '.navbar-toggler'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Modal {\n constructor(element, config) {\n this._config = this._getConfig(config)\n this._element = element\n this._dialog = $(element).find(Selector.DIALOG)[0]\n this._backdrop = null\n this._isShown = false\n this._isBodyOverflowing = false\n this._ignoreBackdropClick = false\n this._originalBodyPadding = 0\n this._scrollbarWidth = 0\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isTransitioning || this._isShown) {\n return\n }\n\n if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {\n this._isTransitioning = true\n }\n\n const showEvent = $.Event(Event.SHOW, {\n relatedTarget\n })\n\n $(this._element).trigger(showEvent)\n\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = true\n\n this._checkScrollbar()\n this._setScrollbar()\n\n this._adjustDialog()\n\n $(document.body).addClass(ClassName.OPEN)\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(this._element).on(\n Event.CLICK_DISMISS,\n Selector.DATA_DISMISS,\n (event) => this.hide(event)\n )\n\n $(this._dialog).on(Event.MOUSEDOWN_DISMISS, () => {\n $(this._element).one(Event.MOUSEUP_DISMISS, (event) => {\n if ($(event.target).is(this._element)) {\n this._ignoreBackdropClick = true\n }\n })\n })\n\n this._showBackdrop(() => this._showElement(relatedTarget))\n }\n\n hide(event) {\n if (event) {\n event.preventDefault()\n }\n\n if (this._isTransitioning || !this._isShown) {\n return\n }\n\n const hideEvent = $.Event(Event.HIDE)\n\n $(this._element).trigger(hideEvent)\n\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = false\n\n const transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)\n\n if (transition) {\n this._isTransitioning = true\n }\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(document).off(Event.FOCUSIN)\n\n $(this._element).removeClass(ClassName.SHOW)\n\n $(this._element).off(Event.CLICK_DISMISS)\n $(this._dialog).off(Event.MOUSEDOWN_DISMISS)\n\n if (transition) {\n $(this._element)\n .one(Util.TRANSITION_END, (event) => this._hideModal(event))\n .emulateTransitionEnd(TRANSITION_DURATION)\n } else {\n this._hideModal()\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n $(window, document, this._element, this._backdrop).off(EVENT_KEY)\n\n this._config = null\n this._element = null\n this._dialog = null\n this._backdrop = null\n this._isShown = null\n this._isBodyOverflowing = null\n this._ignoreBackdropClick = null\n this._scrollbarWidth = null\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _showElement(relatedTarget) {\n const transition = Util.supportsTransitionEnd() &&\n $(this._element).hasClass(ClassName.FADE)\n\n if (!this._element.parentNode ||\n this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.scrollTop = 0\n\n if (transition) {\n Util.reflow(this._element)\n }\n\n $(this._element).addClass(ClassName.SHOW)\n\n if (this._config.focus) {\n this._enforceFocus()\n }\n\n const shownEvent = $.Event(Event.SHOWN, {\n relatedTarget\n })\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._element.focus()\n }\n this._isTransitioning = false\n $(this._element).trigger(shownEvent)\n }\n\n if (transition) {\n $(this._dialog)\n .one(Util.TRANSITION_END, transitionComplete)\n .emulateTransitionEnd(TRANSITION_DURATION)\n } else {\n transitionComplete()\n }\n }\n\n _enforceFocus() {\n $(document)\n .off(Event.FOCUSIN) // Guard against infinite focus loop\n .on(Event.FOCUSIN, (event) => {\n if (document !== event.target &&\n this._element !== event.target &&\n $(this._element).has(event.target).length === 0) {\n this._element.focus()\n }\n })\n }\n\n _setEscapeEvent() {\n if (this._isShown && this._config.keyboard) {\n $(this._element).on(Event.KEYDOWN_DISMISS, (event) => {\n if (event.which === ESCAPE_KEYCODE) {\n event.preventDefault()\n this.hide()\n }\n })\n } else if (!this._isShown) {\n $(this._element).off(Event.KEYDOWN_DISMISS)\n }\n }\n\n _setResizeEvent() {\n if (this._isShown) {\n $(window).on(Event.RESIZE, (event) => this.handleUpdate(event))\n } else {\n $(window).off(Event.RESIZE)\n }\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._isTransitioning = false\n this._showBackdrop(() => {\n $(document.body).removeClass(ClassName.OPEN)\n this._resetAdjustments()\n this._resetScrollbar()\n $(this._element).trigger(Event.HIDDEN)\n })\n }\n\n _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove()\n this._backdrop = null\n }\n }\n\n _showBackdrop(callback) {\n const animate = $(this._element).hasClass(ClassName.FADE)\n ? ClassName.FADE : ''\n\n if (this._isShown && this._config.backdrop) {\n const doAnimate = Util.supportsTransitionEnd() && animate\n\n this._backdrop = document.createElement('div')\n this._backdrop.className = ClassName.BACKDROP\n\n if (animate) {\n $(this._backdrop).addClass(animate)\n }\n\n $(this._backdrop).appendTo(document.body)\n\n $(this._element).on(Event.CLICK_DISMISS, (event) => {\n if (this._ignoreBackdropClick) {\n this._ignoreBackdropClick = false\n return\n }\n if (event.target !== event.currentTarget) {\n return\n }\n if (this._config.backdrop === 'static') {\n this._element.focus()\n } else {\n this.hide()\n }\n })\n\n if (doAnimate) {\n Util.reflow(this._backdrop)\n }\n\n $(this._backdrop).addClass(ClassName.SHOW)\n\n if (!callback) {\n return\n }\n\n if (!doAnimate) {\n callback()\n return\n }\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callback)\n .emulateTransitionEnd(BACKDROP_TRANSITION_DURATION)\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(ClassName.SHOW)\n\n const callbackRemove = () => {\n this._removeBackdrop()\n if (callback) {\n callback()\n }\n }\n\n if (Util.supportsTransitionEnd() &&\n $(this._element).hasClass(ClassName.FADE)) {\n $(this._backdrop)\n .one(Util.TRANSITION_END, callbackRemove)\n .emulateTransitionEnd(BACKDROP_TRANSITION_DURATION)\n } else {\n callbackRemove()\n }\n } else if (callback) {\n callback()\n }\n }\n\n // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n\n _adjustDialog() {\n const isModalOverflowing =\n this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = `${this._scrollbarWidth}px`\n }\n\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = `${this._scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n _checkScrollbar() {\n const rect = document.body.getBoundingClientRect()\n this._isBodyOverflowing = rect.left + rect.right < window.innerWidth\n this._scrollbarWidth = this._getScrollbarWidth()\n }\n\n _setScrollbar() {\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n\n // Adjust fixed content padding\n $(Selector.FIXED_CONTENT).each((index, element) => {\n const actualPadding = $(element)[0].style.paddingRight\n const calculatedPadding = $(element).css('padding-right')\n $(element).data('padding-right', actualPadding).css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n })\n\n // Adjust sticky content margin\n $(Selector.STICKY_CONTENT).each((index, element) => {\n const actualMargin = $(element)[0].style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element).data('margin-right', actualMargin).css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)\n })\n\n // Adjust navbar-toggler margin\n $(Selector.NAVBAR_TOGGLER).each((index, element) => {\n const actualMargin = $(element)[0].style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element).data('margin-right', actualMargin).css('margin-right', `${parseFloat(calculatedMargin) + this._scrollbarWidth}px`)\n })\n\n // Adjust body padding\n const actualPadding = document.body.style.paddingRight\n const calculatedPadding = $('body').css('padding-right')\n $('body').data('padding-right', actualPadding).css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n }\n }\n\n _resetScrollbar() {\n // Restore fixed content padding\n $(Selector.FIXED_CONTENT).each((index, element) => {\n const padding = $(element).data('padding-right')\n if (typeof padding !== 'undefined') {\n $(element).css('padding-right', padding).removeData('padding-right')\n }\n })\n\n // Restore sticky content and navbar-toggler margin\n $(`${Selector.STICKY_CONTENT}, ${Selector.NAVBAR_TOGGLER}`).each((index, element) => {\n const margin = $(element).data('margin-right')\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right')\n }\n })\n\n // Restore body padding\n const padding = $('body').data('padding-right')\n if (typeof padding !== 'undefined') {\n $('body').css('padding-right', padding).removeData('padding-right')\n }\n }\n\n _getScrollbarWidth() { // thx d.walsh\n const scrollDiv = document.createElement('div')\n scrollDiv.className = ClassName.SCROLLBAR_MEASURER\n document.body.appendChild(scrollDiv)\n const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth\n document.body.removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n // Static\n\n static _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = {\n ...Modal.Default,\n ...$(this).data(),\n ...typeof config === 'object' && config\n }\n\n if (!data) {\n data = new Modal(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config](relatedTarget)\n } else if (_config.show) {\n data.show(relatedTarget)\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {\n let target\n const selector = Util.getSelectorFromElement(this)\n\n if (selector) {\n target = $(selector)[0]\n }\n\n const config = $(target).data(DATA_KEY)\n ? 'toggle' : {\n ...$(target).data(),\n ...$(this).data()\n }\n\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault()\n }\n\n const $target = $(target).one(Event.SHOW, (showEvent) => {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return\n }\n\n $target.one(Event.HIDDEN, () => {\n if ($(this).is(':visible')) {\n this.focus()\n }\n })\n })\n\n Modal._jQueryInterface.call($(target), config, this)\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Modal._jQueryInterface\n $.fn[NAME].Constructor = Modal\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Modal._jQueryInterface\n }\n\n return Modal\n})($)\n\nexport default Modal\n","import $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.0.0): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Tooltip = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'tooltip'\n const VERSION = '4.0.0'\n const DATA_KEY = 'bs.tooltip'\n const EVENT_KEY = `.${DATA_KEY}`\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const TRANSITION_DURATION = 150\n const CLASS_PREFIX = 'bs-tooltip'\n const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\n const DefaultType = {\n animation : 'boolean',\n template : 'string',\n title : '(string|element|function)',\n trigger : 'string',\n delay : '(number|object)',\n html : 'boolean',\n selector : '(string|boolean)',\n placement : '(string|function)',\n offset : '(number|string)',\n container : '(string|element|boolean)',\n fallbackPlacement : '(string|array)',\n boundary : '(string|element)'\n }\n\n const AttachmentMap = {\n AUTO : 'auto',\n TOP : 'top',\n RIGHT : 'right',\n BOTTOM : 'bottom',\n LEFT : 'left'\n }\n\n const Default = {\n animation : true,\n template : '<div class=\"tooltip\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<div class=\"tooltip-inner\"></div></div>',\n trigger : 'hover focus',\n title : '',\n delay : 0,\n html : false,\n selector : false,\n placement : 'top',\n offset : 0,\n container : false,\n fallbackPlacement : 'flip',\n boundary : 'scrollParent'\n }\n\n const HoverState = {\n SHOW : 'show',\n OUT : 'out'\n }\n\n const Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n INSERTED : `inserted${EVENT_KEY}`,\n CLICK : `click${EVENT_KEY}`,\n FOCUSIN : `focusin${EVENT_KEY}`,\n FOCUSOUT : `focusout${EVENT_KEY}`,\n MOUSEENTER : `mouseenter${EVENT_KEY}`,\n MOUSELEAVE : `mouseleave${EVENT_KEY}`\n }\n\n const ClassName = {\n FADE : 'fade',\n SHOW : 'show'\n }\n\n const Selector = {\n TOOLTIP : '.tooltip',\n TOOLTIP_INNER : '.tooltip-inner',\n ARROW : '.arrow'\n }\n\n const Trigger = {\n HOVER : 'hover',\n FOCUS : 'focus',\n CLICK : 'click',\n MANUAL : 'manual'\n }\n\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Tooltip {\n constructor(element, config) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap tooltips require Popper.js (https://popper.js.org)')\n }\n\n // private\n this._isEnabled = true\n this._timeout = 0\n this._hoverState = ''\n this._activeTrigger = {}\n this._popper = null\n\n // Protected\n this.element = element\n this.config = this._getConfig(config)\n this.tip = null\n\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle(event) {\n if (!this._isEnabled) {\n return\n }\n\n if (event) {\n const dataKey = this.constructor.DATA_KEY\n let context = $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n context._activeTrigger.click = !context._activeTrigger.click\n\n if (context._isWithActiveTrigger()) {\n context._enter(null, context)\n } else {\n context._leave(null, context)\n }\n } else {\n if ($(this.getTipElement()).hasClass(ClassName.SHOW)) {\n this._leave(null, this)\n return\n }\n\n this._enter(null, this)\n }\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n $.removeData(this.element, this.constructor.DATA_KEY)\n\n $(this.element).off(this.constructor.EVENT_KEY)\n $(this.element).closest('.modal').off('hide.bs.modal')\n\n if (this.tip) {\n $(this.tip).remove()\n }\n\n this._isEnabled = null\n this._timeout = null\n this._hoverState = null\n this._activeTrigger = null\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n this._popper = null\n this.element = null\n this.config = null\n this.tip = null\n }\n\n show() {\n if ($(this.element).css('display') === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n const showEvent = $.Event(this.constructor.Event.SHOW)\n if (this.isWithContent() && this._isEnabled) {\n $(this.element).trigger(showEvent)\n\n const isInTheDom = $.contains(\n this.element.ownerDocument.documentElement,\n this.element\n )\n\n if (showEvent.isDefaultPrevented() || !isInTheDom) {\n return\n }\n\n const tip = this.getTipElement()\n const tipId = Util.getUID(this.constructor.NAME)\n\n tip.setAttribute('id', tipId)\n this.element.setAttribute('aria-describedby', tipId)\n\n this.setContent()\n\n if (this.config.animation) {\n $(tip).addClass(ClassName.FADE)\n }\n\n const placement = typeof this.config.placement === 'function'\n ? this.config.placement.call(this, tip, this.element)\n : this.config.placement\n\n const attachment = this._getAttachment(placement)\n this.addAttachmentClass(attachment)\n\n const container = this.config.container === false ? document.body : $(this.config.container)\n\n $(tip).data(this.constructor.DATA_KEY, this)\n\n if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {\n $(tip).appendTo(container)\n }\n\n $(this.element).trigger(this.constructor.Event.INSERTED)\n\n this._popper = new Popper(this.element, tip, {\n placement: attachment,\n modifiers: {\n offset: {\n offset: this.config.offset\n },\n flip: {\n behavior: this.config.fallbackPlacement\n },\n arrow: {\n element: Selector.ARROW\n },\n preventOverflow: {\n boundariesElement: this.config.boundary\n }\n },\n onCreate: (data) => {\n if (data.originalPlacement !== data.placement) {\n this._handlePopperPlacementChange(data)\n }\n },\n onUpdate: (data) => {\n this._handlePopperPlacementChange(data)\n }\n })\n\n $(tip).addClass(ClassName.SHOW)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n $('body').children().on('mouseover', null, $.noop)\n }\n\n const complete = () => {\n if (this.config.animation) {\n this._fixTransition()\n }\n const prevHoverState = this._hoverState\n this._hoverState = null\n\n $(this.element).trigger(this.constructor.Event.SHOWN)\n\n if (prevHoverState === HoverState.OUT) {\n this._leave(null, this)\n }\n }\n\n if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {\n $(this.tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(Tooltip._TRANSITION_DURATION)\n } else {\n complete()\n }\n }\n }\n\n hide(callback) {\n const tip = this.getTipElement()\n const hideEvent = $.Event(this.constructor.Event.HIDE)\n const complete = () => {\n if (this._hoverState !== HoverState.SHOW && tip.parentNode) {\n tip.parentNode.removeChild(tip)\n }\n\n this._cleanTipClass()\n this.element.removeAttribute('aria-describedby')\n $(this.element).trigger(this.constructor.Event.HIDDEN)\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n if (callback) {\n callback()\n }\n }\n\n $(this.element).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n $(tip).removeClass(ClassName.SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $('body').children().off('mouseover', null, $.noop)\n }\n\n this._activeTrigger[Trigger.CLICK] = false\n this._activeTrigger[Trigger.FOCUS] = false\n this._activeTrigger[Trigger.HOVER] = false\n\n if (Util.supportsTransitionEnd() &&\n $(this.tip).hasClass(ClassName.FADE)) {\n $(tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(TRANSITION_DURATION)\n } else {\n complete()\n }\n\n this._hoverState = ''\n }\n\n update() {\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Protected\n\n isWithContent() {\n return Boolean(this.getTitle())\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const $tip = $(this.getTipElement())\n this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle())\n $tip.removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)\n }\n\n setElementContent($element, content) {\n const html = this.config.html\n if (typeof content === 'object' && (content.nodeType || content.jquery)) {\n // Content is a DOM node or a jQuery\n if (html) {\n if (!$(content).parent().is($element)) {\n $element.empty().append(content)\n }\n } else {\n $element.text($(content).text())\n }\n } else {\n $element[html ? 'html' : 'text'](content)\n }\n }\n\n getTitle() {\n let title = this.element.getAttribute('data-original-title')\n\n if (!title) {\n title = typeof this.config.title === 'function'\n ? this.config.title.call(this.element)\n : this.config.title\n }\n\n return title\n }\n\n // Private\n\n _getAttachment(placement) {\n return AttachmentMap[placement.toUpperCase()]\n }\n\n _setListeners() {\n const triggers = this.config.trigger.split(' ')\n\n triggers.forEach((trigger) => {\n if (trigger === 'click') {\n $(this.element).on(\n this.constructor.Event.CLICK,\n this.config.selector,\n (event) => this.toggle(event)\n )\n } else if (trigger !== Trigger.MANUAL) {\n const eventIn = trigger === Trigger.HOVER\n ? this.constructor.Event.MOUSEENTER\n : this.constructor.Event.FOCUSIN\n const eventOut = trigger === Trigger.HOVER\n ? this.constructor.Event.MOUSELEAVE\n : this.constructor.Event.FOCUSOUT\n\n $(this.element)\n .on(\n eventIn,\n this.config.selector,\n (event) => this._enter(event)\n )\n .on(\n eventOut,\n this.config.selector,\n (event) => this._leave(event)\n )\n }\n\n $(this.element).closest('.modal').on(\n 'hide.bs.modal',\n () => this.hide()\n )\n })\n\n if (this.config.selector) {\n this.config = {\n ...this.config,\n trigger: 'manual',\n selector: ''\n }\n } else {\n this._fixTitle()\n }\n }\n\n _fixTitle() {\n const titleType = typeof this.element.getAttribute('data-original-title')\n if (this.element.getAttribute('title') ||\n titleType !== 'string') {\n this.element.setAttribute(\n 'data-original-title',\n this.element.getAttribute('title') || ''\n )\n this.element.setAttribute('title', '')\n }\n }\n\n _enter(event, context) {\n const dataKey = this.constructor.DATA_KEY\n\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER\n ] = true\n }\n\n if ($(context.getTipElement()).hasClass(ClassName.SHOW) ||\n context._hoverState === HoverState.SHOW) {\n context._hoverState = HoverState.SHOW\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HoverState.SHOW\n\n if (!context.config.delay || !context.config.delay.show) {\n context.show()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HoverState.SHOW) {\n context.show()\n }\n }, context.config.delay.show)\n }\n\n _leave(event, context) {\n const dataKey = this.constructor.DATA_KEY\n\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER\n ] = false\n }\n\n if (context._isWithActiveTrigger()) {\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HoverState.OUT\n\n if (!context.config.delay || !context.config.delay.hide) {\n context.hide()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HoverState.OUT) {\n context.hide()\n }\n }, context.config.delay.hide)\n }\n\n _isWithActiveTrigger() {\n for (const trigger in this._activeTrigger) {\n if (this._activeTrigger[trigger]) {\n return true\n }\n }\n\n return false\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this.element).data(),\n ...config\n }\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n if (this.config) {\n for (const key in this.config) {\n if (this.constructor.Default[key] !== this.config[key]) {\n config[key] = this.config[key]\n }\n }\n }\n\n return config\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n _handlePopperPlacementChange(data) {\n this._cleanTipClass()\n this.addAttachmentClass(this._getAttachment(data.placement))\n }\n\n _fixTransition() {\n const tip = this.getTipElement()\n const initConfigAnimation = this.config.animation\n if (tip.getAttribute('x-placement') !== null) {\n return\n }\n $(tip).removeClass(ClassName.FADE)\n this.config.animation = false\n this.hide()\n this.show()\n this.config.animation = initConfigAnimation\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Tooltip(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Tooltip._jQueryInterface\n $.fn[NAME].Constructor = Tooltip\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tooltip._jQueryInterface\n }\n\n return Tooltip\n})($, Popper)\n\nexport default Tooltip\n","import $ from 'jquery'\nimport Tooltip from './tooltip'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.0.0): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Popover = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'popover'\n const VERSION = '4.0.0'\n const DATA_KEY = 'bs.popover'\n const EVENT_KEY = `.${DATA_KEY}`\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const CLASS_PREFIX = 'bs-popover'\n const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\n const Default = {\n ...Tooltip.Default,\n placement : 'right',\n trigger : 'click',\n content : '',\n template : '<div class=\"popover\" role=\"tooltip\">' +\n '<div class=\"arrow\"></div>' +\n '<h3 class=\"popover-header\"></h3>' +\n '<div class=\"popover-body\"></div></div>'\n }\n\n const DefaultType = {\n ...Tooltip.DefaultType,\n content : '(string|element|function)'\n }\n\n const ClassName = {\n FADE : 'fade',\n SHOW : 'show'\n }\n\n const Selector = {\n TITLE : '.popover-header',\n CONTENT : '.popover-body'\n }\n\n const Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n INSERTED : `inserted${EVENT_KEY}`,\n CLICK : `click${EVENT_KEY}`,\n FOCUSIN : `focusin${EVENT_KEY}`,\n FOCUSOUT : `focusout${EVENT_KEY}`,\n MOUSEENTER : `mouseenter${EVENT_KEY}`,\n MOUSELEAVE : `mouseleave${EVENT_KEY}`\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Popover extends Tooltip {\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Overrides\n\n isWithContent() {\n return this.getTitle() || this._getContent()\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const $tip = $(this.getTipElement())\n\n // We use append for html objects to maintain js events\n this.setElementContent($tip.find(Selector.TITLE), this.getTitle())\n let content = this._getContent()\n if (typeof content === 'function') {\n content = content.call(this.element)\n }\n this.setElementContent($tip.find(Selector.CONTENT), content)\n\n $tip.removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)\n }\n\n // Private\n\n _getContent() {\n return this.element.getAttribute('data-content') ||\n this.config.content\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data && /destroy|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Popover(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Popover._jQueryInterface\n $.fn[NAME].Constructor = Popover\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Popover._jQueryInterface\n }\n\n return Popover\n})($)\n\nexport default Popover\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.0.0): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst ScrollSpy = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'scrollspy'\n const VERSION = '4.0.0'\n const DATA_KEY = 'bs.scrollspy'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n\n const Default = {\n offset : 10,\n method : 'auto',\n target : ''\n }\n\n const DefaultType = {\n offset : 'number',\n method : 'string',\n target : '(string|element)'\n }\n\n const Event = {\n ACTIVATE : `activate${EVENT_KEY}`,\n SCROLL : `scroll${EVENT_KEY}`,\n LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n DROPDOWN_ITEM : 'dropdown-item',\n DROPDOWN_MENU : 'dropdown-menu',\n ACTIVE : 'active'\n }\n\n const Selector = {\n DATA_SPY : '[data-spy=\"scroll\"]',\n ACTIVE : '.active',\n NAV_LIST_GROUP : '.nav, .list-group',\n NAV_LINKS : '.nav-link',\n NAV_ITEMS : '.nav-item',\n LIST_ITEMS : '.list-group-item',\n DROPDOWN : '.dropdown',\n DROPDOWN_ITEMS : '.dropdown-item',\n DROPDOWN_TOGGLE : '.dropdown-toggle'\n }\n\n const OffsetMethod = {\n OFFSET : 'offset',\n POSITION : 'position'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class ScrollSpy {\n constructor(element, config) {\n this._element = element\n this._scrollElement = element.tagName === 'BODY' ? window : element\n this._config = this._getConfig(config)\n this._selector = `${this._config.target} ${Selector.NAV_LINKS},` +\n `${this._config.target} ${Selector.LIST_ITEMS},` +\n `${this._config.target} ${Selector.DROPDOWN_ITEMS}`\n this._offsets = []\n this._targets = []\n this._activeTarget = null\n this._scrollHeight = 0\n\n $(this._scrollElement).on(Event.SCROLL, (event) => this._process(event))\n\n this.refresh()\n this._process()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n refresh() {\n const autoMethod = this._scrollElement === this._scrollElement.window\n ? OffsetMethod.OFFSET : OffsetMethod.POSITION\n\n const offsetMethod = this._config.method === 'auto'\n ? autoMethod : this._config.method\n\n const offsetBase = offsetMethod === OffsetMethod.POSITION\n ? this._getScrollTop() : 0\n\n this._offsets = []\n this._targets = []\n\n this._scrollHeight = this._getScrollHeight()\n\n const targets = $.makeArray($(this._selector))\n\n targets\n .map((element) => {\n let target\n const targetSelector = Util.getSelectorFromElement(element)\n\n if (targetSelector) {\n target = $(targetSelector)[0]\n }\n\n if (target) {\n const targetBCR = target.getBoundingClientRect()\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [\n $(target)[offsetMethod]().top + offsetBase,\n targetSelector\n ]\n }\n }\n return null\n })\n .filter((item) => item)\n .sort((a, b) => a[0] - b[0])\n .forEach((item) => {\n this._offsets.push(item[0])\n this._targets.push(item[1])\n })\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._scrollElement).off(EVENT_KEY)\n\n this._element = null\n this._scrollElement = null\n this._config = null\n this._selector = null\n this._offsets = null\n this._targets = null\n this._activeTarget = null\n this._scrollHeight = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n\n if (typeof config.target !== 'string') {\n let id = $(config.target).attr('id')\n if (!id) {\n id = Util.getUID(NAME)\n $(config.target).attr('id', id)\n }\n config.target = `#${id}`\n }\n\n Util.typeCheckConfig(NAME, config, DefaultType)\n\n return config\n }\n\n _getScrollTop() {\n return this._scrollElement === window\n ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop\n }\n\n _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight\n )\n }\n\n _getOffsetHeight() {\n return this._scrollElement === window\n ? window.innerHeight : this._scrollElement.getBoundingClientRect().height\n }\n\n _process() {\n const scrollTop = this._getScrollTop() + this._config.offset\n const scrollHeight = this._getScrollHeight()\n const maxScroll = this._config.offset +\n scrollHeight -\n this._getOffsetHeight()\n\n if (this._scrollHeight !== scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n const target = this._targets[this._targets.length - 1]\n\n if (this._activeTarget !== target) {\n this._activate(target)\n }\n return\n }\n\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null\n this._clear()\n return\n }\n\n for (let i = this._offsets.length; i--;) {\n const isActiveTarget = this._activeTarget !== this._targets[i] &&\n scrollTop >= this._offsets[i] &&\n (typeof this._offsets[i + 1] === 'undefined' ||\n scrollTop < this._offsets[i + 1])\n\n if (isActiveTarget) {\n this._activate(this._targets[i])\n }\n }\n }\n\n _activate(target) {\n this._activeTarget = target\n\n this._clear()\n\n let queries = this._selector.split(',')\n // eslint-disable-next-line arrow-body-style\n queries = queries.map((selector) => {\n return `${selector}[data-target=\"${target}\"],` +\n `${selector}[href=\"${target}\"]`\n })\n\n const $link = $(queries.join(','))\n\n if ($link.hasClass(ClassName.DROPDOWN_ITEM)) {\n $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE)\n $link.addClass(ClassName.ACTIVE)\n } else {\n // Set triggered link as active\n $link.addClass(ClassName.ACTIVE)\n // Set triggered links parents as active\n // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n $link.parents(Selector.NAV_LIST_GROUP).prev(`${Selector.NAV_LINKS}, ${Selector.LIST_ITEMS}`).addClass(ClassName.ACTIVE)\n // Handle special case when .nav-link is inside .nav-item\n $link.parents(Selector.NAV_LIST_GROUP).prev(Selector.NAV_ITEMS).children(Selector.NAV_LINKS).addClass(ClassName.ACTIVE)\n }\n\n $(this._scrollElement).trigger(Event.ACTIVATE, {\n relatedTarget: target\n })\n }\n\n _clear() {\n $(this._selector).filter(Selector.ACTIVE).removeClass(ClassName.ACTIVE)\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data) {\n data = new ScrollSpy(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(window).on(Event.LOAD_DATA_API, () => {\n const scrollSpys = $.makeArray($(Selector.DATA_SPY))\n\n for (let i = scrollSpys.length; i--;) {\n const $spy = $(scrollSpys[i])\n ScrollSpy._jQueryInterface.call($spy, $spy.data())\n }\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = ScrollSpy._jQueryInterface\n $.fn[NAME].Constructor = ScrollSpy\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return ScrollSpy._jQueryInterface\n }\n\n return ScrollSpy\n})($)\n\nexport default ScrollSpy\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.0.0): tab.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Tab = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'tab'\n const VERSION = '4.0.0'\n const DATA_KEY = 'bs.tab'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const TRANSITION_DURATION = 150\n\n const Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n DROPDOWN_MENU : 'dropdown-menu',\n ACTIVE : 'active',\n DISABLED : 'disabled',\n FADE : 'fade',\n SHOW : 'show'\n }\n\n const Selector = {\n DROPDOWN : '.dropdown',\n NAV_LIST_GROUP : '.nav, .list-group',\n ACTIVE : '.active',\n ACTIVE_UL : '> li > .active',\n DATA_TOGGLE : '[data-toggle=\"tab\"], [data-toggle=\"pill\"], [data-toggle=\"list\"]',\n DROPDOWN_TOGGLE : '.dropdown-toggle',\n DROPDOWN_ACTIVE_CHILD : '> .dropdown-menu .active'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Tab {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n show() {\n if (this._element.parentNode &&\n this._element.parentNode.nodeType === Node.ELEMENT_NODE &&\n $(this._element).hasClass(ClassName.ACTIVE) ||\n $(this._element).hasClass(ClassName.DISABLED)) {\n return\n }\n\n let target\n let previous\n const listElement = $(this._element).closest(Selector.NAV_LIST_GROUP)[0]\n const selector = Util.getSelectorFromElement(this._element)\n\n if (listElement) {\n const itemSelector = listElement.nodeName === 'UL' ? Selector.ACTIVE_UL : Selector.ACTIVE\n previous = $.makeArray($(listElement).find(itemSelector))\n previous = previous[previous.length - 1]\n }\n\n const hideEvent = $.Event(Event.HIDE, {\n relatedTarget: this._element\n })\n\n const showEvent = $.Event(Event.SHOW, {\n relatedTarget: previous\n })\n\n if (previous) {\n $(previous).trigger(hideEvent)\n }\n\n $(this._element).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented() ||\n hideEvent.isDefaultPrevented()) {\n return\n }\n\n if (selector) {\n target = $(selector)[0]\n }\n\n this._activate(\n this._element,\n listElement\n )\n\n const complete = () => {\n const hiddenEvent = $.Event(Event.HIDDEN, {\n relatedTarget: this._element\n })\n\n const shownEvent = $.Event(Event.SHOWN, {\n relatedTarget: previous\n })\n\n $(previous).trigger(hiddenEvent)\n $(this._element).trigger(shownEvent)\n }\n\n if (target) {\n this._activate(target, target.parentNode, complete)\n } else {\n complete()\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _activate(element, container, callback) {\n let activeElements\n if (container.nodeName === 'UL') {\n activeElements = $(container).find(Selector.ACTIVE_UL)\n } else {\n activeElements = $(container).children(Selector.ACTIVE)\n }\n\n const active = activeElements[0]\n const isTransitioning = callback &&\n Util.supportsTransitionEnd() &&\n (active && $(active).hasClass(ClassName.FADE))\n\n const complete = () => this._transitionComplete(\n element,\n active,\n callback\n )\n\n if (active && isTransitioning) {\n $(active)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(TRANSITION_DURATION)\n } else {\n complete()\n }\n }\n\n _transitionComplete(element, active, callback) {\n if (active) {\n $(active).removeClass(`${ClassName.SHOW} ${ClassName.ACTIVE}`)\n\n const dropdownChild = $(active.parentNode).find(\n Selector.DROPDOWN_ACTIVE_CHILD\n )[0]\n\n if (dropdownChild) {\n $(dropdownChild).removeClass(ClassName.ACTIVE)\n }\n\n if (active.getAttribute('role') === 'tab') {\n active.setAttribute('aria-selected', false)\n }\n }\n\n $(element).addClass(ClassName.ACTIVE)\n if (element.getAttribute('role') === 'tab') {\n element.setAttribute('aria-selected', true)\n }\n\n Util.reflow(element)\n $(element).addClass(ClassName.SHOW)\n\n if (element.parentNode &&\n $(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) {\n const dropdownElement = $(element).closest(Selector.DROPDOWN)[0]\n if (dropdownElement) {\n $(dropdownElement).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE)\n }\n\n element.setAttribute('aria-expanded', true)\n }\n\n if (callback) {\n callback()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n\n if (!data) {\n data = new Tab(this)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document)\n .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {\n event.preventDefault()\n Tab._jQueryInterface.call($(this), 'show')\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Tab._jQueryInterface\n $.fn[NAME].Constructor = Tab\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tab._jQueryInterface\n }\n\n return Tab\n})($)\n\nexport default Tab\n","import $ from 'jquery'\nimport Alert from './alert'\nimport Button from './button'\nimport Carousel from './carousel'\nimport Collapse from './collapse'\nimport Dropdown from './dropdown'\nimport Modal from './modal'\nimport Popover from './popover'\nimport Scrollspy from './scrollspy'\nimport Tab from './tab'\nimport Tooltip from './tooltip'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.0.0-alpha.6): index.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n(($) => {\n if (typeof $ === 'undefined') {\n throw new TypeError('Bootstrap\\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\\'s JavaScript.')\n }\n\n const version = $.fn.jquery.split(' ')[0].split('.')\n const minMajor = 1\n const ltMajor = 2\n const minMinor = 9\n const minPatch = 1\n const maxMajor = 4\n\n if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {\n throw new Error('Bootstrap\\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0')\n }\n})($)\n\nexport {\n Util,\n Alert,\n Button,\n Carousel,\n Collapse,\n Dropdown,\n Modal,\n Popover,\n Scrollspy,\n Tab,\n Tooltip\n}\n"]} \ No newline at end of file diff --git a/web2py/applications/SP/static/js/calendar.js b/web2py/applications/SP/static/js/calendar.js new file mode 100644 index 0000000..4bdb8c7 --- /dev/null +++ b/web2py/applications/SP/static/js/calendar.js @@ -0,0 +1,29 @@ +/* Copyright Notice for Dynarch Date Time Picker */ +/* Copyright Mihai Bazon, 2002-2005 | www.bazon.net/mishoo + * ----------------------------------------------------------- + * + * The DHTML Calendar, version 1.0 "It is happening again" + * + * Details and latest version at: + * www.dynarch.com/projects/calendar + * + * This script is developed by Dynarch.com. Visit us at www.dynarch.com. + * + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html + */ + +// Calendar EN language +// Author: Mihai Bazon, <mihai_bazon@yahoo.com> +// Encoding: any +// Distributed under the same terms as the calendar itself. +/* End Copyright Notice for Dynarch Date Time Picker */ + +Calendar=function(J,K,H,G){this.activeDiv=null;this.currentDateEl=null;this.getDateStatus=null;this.getDateToolTip=null;this.getDateText=null;this.timeout=null;this.onSelected=H||null;this.onClose=G||null;this.dragging=false;this.hidden=false;this.minYear=1970;this.maxYear=2050;this.dateFormat=Calendar._TT.DEF_DATE_FORMAT;this.ttDateFormat=Calendar._TT.TT_DATE_FORMAT;this.isPopup=true;this.weekNumbers=true;this.firstDayOfWeek=typeof J=="number"?J:Calendar._FD;this.showsOtherMonths=false;this.dateStr=K;this.ar_days=null;this.showsTime=false;this.time24=true;this.yearStep=2;this.hiliteToday=true;this.multiple=null;this.table=null;this.element=null;this.tbody=null;this.firstdayname=null;this.monthsCombo=null;this.yearsCombo=null;this.hilitedMonth=null;this.activeMonth=null;this.hilitedYear=null;this.activeYear=null;this.dateClicked=false;if(typeof Calendar._SDN=="undefined"){if(typeof Calendar._SDN_len=="undefined"){Calendar._SDN_len=3}var L=new Array();for(var I=8;I>0;){L[--I]=Calendar._DN[I].substr(0,Calendar._SDN_len)}Calendar._SDN=L;if(typeof Calendar._SMN_len=="undefined"){Calendar._SMN_len=3}L=new Array();for(var I=12;I>0;){L[--I]=Calendar._MN[I].substr(0,Calendar._SMN_len)}Calendar._SMN=L}};Calendar._C=null;Calendar.is_ie=(/msie/i.test(navigator.userAgent)&&!/opera/i.test(navigator.userAgent));Calendar.is_ie5=(Calendar.is_ie&&/msie 5\.0/i.test(navigator.userAgent));Calendar.is_opera=/opera/i.test(navigator.userAgent);Calendar.is_khtml=/Konqueror|Safari|KHTML/i.test(navigator.userAgent);Calendar.getAbsolutePos=function(I){var G=0,J=0;var K=/^div$/i.test(I.tagName);if(K&&I.scrollLeft){G=I.scrollLeft}if(K&&I.scrollTop){J=I.scrollTop}var H={x:I.offsetLeft-G,y:I.offsetTop-J};if(I.offsetParent){var L=this.getAbsolutePos(I.offsetParent);H.x+=L.x;H.y+=L.y}return H};Calendar.isRelated=function(G,E){var F=E.relatedTarget;if(!F){var H=E.type;if(H=="mouseover"){F=E.fromElement}else{if(H=="mouseout"){F=E.toElement}}}while(F){if(F==G){return true}F=F.parentNode}return false};Calendar.removeClass=function(G,H){if(!(G&&G.className)){return }var F=G.className.split(" ");var J=new Array();for(var I=F.length;I>0;){if(F[--I]!=H){J[J.length]=F[I]}}G.className=J.join(" ")};Calendar.addClass=function(D,C){Calendar.removeClass(D,C);D.className+=" "+C};Calendar.getElement=function(C){var D=Calendar.is_ie?window.event.srcElement:C.currentTarget;while(D.nodeType!=1||/^div$/i.test(D.tagName)){D=D.parentNode}return D};Calendar.getTargetElement=function(C){var D=Calendar.is_ie?window.event.srcElement:C.target;while(D.nodeType!=1){D=D.parentNode}return D};Calendar.stopEvent=function(B){B||(B=window.event);if(Calendar.is_ie){B.cancelBubble=true;B.returnValue=false}else{B.preventDefault();B.stopPropagation()}return false};Calendar.addEvent=function(D,E,F){if(D.attachEvent){D.attachEvent("on"+E,F)}else{if(D.addEventListener){D.addEventListener(E,F,true)}else{D["on"+E]=F}}};Calendar.removeEvent=function(D,E,F){if(D.detachEvent){D.detachEvent("on"+E,F)}else{if(D.removeEventListener){D.removeEventListener(E,F,true)}else{D["on"+E]=null}}};Calendar.createElement=function(E,F){var D=null;if(document.createElementNS){D=document.createElementNS("http://www.w3.org/1999/xhtml",E)}else{D=document.createElement(E)}if(typeof F!="undefined"){F.appendChild(D)}return D};Calendar._add_evs=function(el){with(Calendar){addEvent(el,"mouseover",dayMouseOver);addEvent(el,"mousedown",dayMouseDown);addEvent(el,"mouseout",dayMouseOut);if(is_ie){addEvent(el,"dblclick",dayMouseDblClick);el.setAttribute("unselectable",true)}}};Calendar.findMonth=function(B){if(typeof B.month!="undefined"){return B}else{if(typeof B.parentNode.month!="undefined"){return B.parentNode}}return null};Calendar.findYear=function(B){if(typeof B.year!="undefined"){return B}else{if(typeof B.parentNode.year!="undefined"){return B.parentNode}}return null};Calendar.showMonthsCombo=function(){var I=Calendar._C;if(!I){return false}var I=I;var H=I.activeDiv;var J=I.monthsCombo;if(I.hilitedMonth){Calendar.removeClass(I.hilitedMonth,"hilite")}if(I.activeMonth){Calendar.removeClass(I.activeMonth,"active")}var K=I.monthsCombo.getElementsByTagName("div")[I.date.getMonth()];Calendar.addClass(K,"active");I.activeMonth=K;var L=J.style;L.display="block";if(H.navtype<0){L.left=H.offsetLeft+"px"}else{var G=J.offsetWidth;if(typeof G=="undefined"){G=50}L.left=(H.offsetLeft+H.offsetWidth-G)+"px"}L.top=(H.offsetTop+H.offsetHeight)+"px"};Calendar.showYearsCombo=function(K){var N=Calendar._C;if(!N){return false}var N=N;var L=N.activeDiv;var S=N.yearsCombo;if(N.hilitedYear){Calendar.removeClass(N.hilitedYear,"hilite")}if(N.activeYear){Calendar.removeClass(N.activeYear,"active")}N.activeYear=null;var M=N.date.getFullYear()+(K?1:-1);var P=S.firstChild;var Q=false;for(var T=12;T>0;--T){if(M>=N.minYear&&M<=N.maxYear){P.innerHTML=M;P.year=M;P.style.display="block";Q=true}else{P.style.display="none"}P=P.nextSibling;M+=K?N.yearStep:-N.yearStep}if(Q){var O=S.style;O.display="block";if(L.navtype<0){O.left=L.offsetLeft+"px"}else{var R=S.offsetWidth;if(typeof R=="undefined"){R=50}O.left=(L.offsetLeft+L.offsetWidth-R)+"px"}O.top=(L.offsetTop+L.offsetHeight)+"px"}};Calendar.tableMouseUp=function(ev){var cal=Calendar._C;if(!cal){return false}if(cal.timeout){clearTimeout(cal.timeout)}var el=cal.activeDiv;if(!el){return false}var target=Calendar.getTargetElement(ev);ev||(ev=window.event);Calendar.removeClass(el,"active");if(target==el||target.parentNode==el){Calendar.cellClick(el,ev)}var mon=Calendar.findMonth(target);var date=null;if(mon){date=new Date(cal.date);if(mon.month!=date.getMonth()){date.setMonth(mon.month);cal.setDate(date);cal.dateClicked=false;cal.callHandler()}}else{var year=Calendar.findYear(target);if(year){date=new Date(cal.date);if(year.year!=date.getFullYear()){date.c_setFullYear(year.year);cal.setDate(date);cal.dateClicked=false;cal.callHandler()}}}with(Calendar){removeEvent(document,"mouseup",tableMouseUp);removeEvent(document,"mouseover",tableMouseOver);removeEvent(document,"mousemove",tableMouseOver);cal._hideCombos();_C=null;return stopEvent(ev)}};Calendar.tableMouseOver=function(X){var T=Calendar._C;if(!T){return }var R=T.activeDiv;var b=Calendar.getTargetElement(X);if(b==R||b.parentNode==R){Calendar.addClass(R,"hilite active");Calendar.addClass(R.parentNode,"rowhilite")}else{if(typeof R.navtype=="undefined"||(R.navtype!=50&&(R.navtype==0||Math.abs(R.navtype)>2))){Calendar.removeClass(R,"active")}Calendar.removeClass(R,"hilite");Calendar.removeClass(R.parentNode,"rowhilite")}X||(X=window.event);if(R.navtype==50&&b!=R){var Y=Calendar.getAbsolutePos(R);var V=R.offsetWidth;var W=X.clientX;var U;var Z=true;if(W>Y.x+V){U=W-Y.x-V;Z=false}else{U=Y.x-W}if(U<0){U=0}var e=R._range;var c=R._current;var d=Math.floor(U/10)%e.length;for(var f=e.length;--f>=0;){if(e[f]==c){break}}while(d-->0){if(Z){if(--f<0){f=e.length-1}}else{if(++f>=e.length){f=0}}}var S=e[f];R.innerHTML=S;T.onUpdateTime()}var Q=Calendar.findMonth(b);if(Q){if(Q.month!=T.date.getMonth()){if(T.hilitedMonth){Calendar.removeClass(T.hilitedMonth,"hilite")}Calendar.addClass(Q,"hilite");T.hilitedMonth=Q}else{if(T.hilitedMonth){Calendar.removeClass(T.hilitedMonth,"hilite")}}}else{if(T.hilitedMonth){Calendar.removeClass(T.hilitedMonth,"hilite")}var a=Calendar.findYear(b);if(a){if(a.year!=T.date.getFullYear()){if(T.hilitedYear){Calendar.removeClass(T.hilitedYear,"hilite")}Calendar.addClass(a,"hilite");T.hilitedYear=a}else{if(T.hilitedYear){Calendar.removeClass(T.hilitedYear,"hilite")}}}else{if(T.hilitedYear){Calendar.removeClass(T.hilitedYear,"hilite")}}}return Calendar.stopEvent(X)};Calendar.tableMouseDown=function(B){if(Calendar.getTargetElement(B)==Calendar.getElement(B)){return Calendar.stopEvent(B)}};Calendar.calDragIt=function(J){var I=Calendar._C;if(!(I&&I.dragging)){return false}var G;var H;if(Calendar.is_ie){H=window.event.clientY+document.body.scrollTop;G=window.event.clientX+document.body.scrollLeft}else{G=J.pageX;H=J.pageY}I.hideShowCovered();var F=I.element.style;F.left=(G-I.xOffs)+"px";F.top=(H-I.yOffs)+"px";return Calendar.stopEvent(J)};Calendar.calDragEnd=function(ev){var cal=Calendar._C;if(!cal){return false}cal.dragging=false;with(Calendar){removeEvent(document,"mousemove",calDragIt);removeEvent(document,"mouseup",calDragEnd);tableMouseUp(ev)}cal.hideShowCovered()};Calendar.dayMouseDown=function(ev){var el=Calendar.getElement(ev);if(el.disabled){return false}var cal=el.calendar;cal.activeDiv=el;Calendar._C=cal;if(el.navtype!=300){with(Calendar){if(el.navtype==50){el._current=el.innerHTML;addEvent(document,"mousemove",tableMouseOver)}else{addEvent(document,Calendar.is_ie5?"mousemove":"mouseover",tableMouseOver)}addClass(el,"hilite active");addEvent(document,"mouseup",tableMouseUp)}}else{if(cal.isPopup){cal._dragStart(ev)}}if(el.navtype==-1||el.navtype==1){if(cal.timeout){clearTimeout(cal.timeout)}cal.timeout=setTimeout("Calendar.showMonthsCombo()",250)}else{if(el.navtype==-2||el.navtype==2){if(cal.timeout){clearTimeout(cal.timeout)}cal.timeout=setTimeout((el.navtype>0)?"Calendar.showYearsCombo(true)":"Calendar.showYearsCombo(false)",250)}else{cal.timeout=null}}return Calendar.stopEvent(ev)};Calendar.dayMouseDblClick=function(B){Calendar.cellClick(Calendar.getElement(B),B||window.event);if(Calendar.is_ie){document.selection.empty()}};Calendar.dayMouseOver=function(D){var C=Calendar.getElement(D);if(Calendar.isRelated(C,D)||Calendar._C||C.disabled){return false}if(C.ttip){if(C.ttip.substr(0,1)=="_"){C.ttip=C.caldate.c_print(C.calendar.ttDateFormat)+C.ttip.substr(1)}C.calendar.tooltips.innerHTML=C.ttip}if(C.navtype!=300){Calendar.addClass(C,"hilite");if(C.caldate){Calendar.addClass(C.parentNode,"rowhilite")}}return Calendar.stopEvent(D)};Calendar.dayMouseOut=function(ev){with(Calendar){var el=getElement(ev);if(isRelated(el,ev)||_C||el.disabled){return false}removeClass(el,"hilite");if(el.caldate){removeClass(el.parentNode,"rowhilite")}if(el.calendar){el.calendar.tooltips.innerHTML=_TT.SEL_DATE}return stopEvent(ev)}};Calendar.cellClick=function(d,U){var Q=d.calendar;var a=false;var X=false;var c=null;if(typeof d.navtype=="undefined"){if(Q.currentDateEl){Calendar.removeClass(Q.currentDateEl,"selected");Calendar.addClass(d,"selected");a=(Q.currentDateEl==d);if(!a){Q.currentDateEl=d}}Q.date.c_setDateOnly(d.caldate);c=Q.date;var R=!(Q.dateClicked=!d.otherMonth);if(!R&&!Q.currentDateEl){Q._toggleMultipleDate(new Date(c))}else{X=!d.disabled}if(R){Q._init(Q.firstDayOfWeek,c)}}else{if(d.navtype==200){Calendar.removeClass(d,"hilite");Q.callCloseHandler();return }c=new Date(Q.date);if(d.navtype==0){c.c_setDateOnly(new Date())}Q.dateClicked=false;var V=c.getFullYear();var b=c.getMonth();function S(B){var A=c.getDate();var C=c.c_getMonthDays(B);if(A>C){c.setDate(C)}c.setMonth(B)}switch(d.navtype){case 400:Calendar.removeClass(d,"hilite");var T=Calendar._TT.ABOUT;if(typeof T!="undefined"){T+=Q.showsTime?Calendar._TT.ABOUT_TIME:""}else{T='Help and about box text is not translated into this language.\nIf you know this language and you feel generous please update\nthe corresponding file in "lang" subdir to match calendar-en.js\nand send it back to <mihai_bazon@yahoo.com> to get it into the distribution ;-)\n\nThank you!\nhttp://dynarch.com/mishoo/calendar.epl\n'}alert(T);return ;case -2:if(V>Q.minYear){c.c_setFullYear(V-1)}break;case -1:if(b>0){S(b-1)}else{if(V-->Q.minYear){c.c_setFullYear(V);S(11)}}break;case 1:if(b<11){S(b+1)}else{if(V<Q.maxYear){c.c_setFullYear(V+1);S(0)}}break;case 2:if(V<Q.maxYear){c.c_setFullYear(V+1)}break;case 100:Q.setFirstDayOfWeek(d.fdow);return ;case 50:var Y=d._range;var W=d.innerHTML;for(var Z=Y.length;--Z>=0;){if(Y[Z]==W){break}}if(U&&U.shiftKey){if(--Z<0){Z=Y.length-1}}else{if(++Z>=Y.length){Z=0}}var P=Y[Z];d.innerHTML=P;Q.onUpdateTime();return ;case 0:if((typeof Q.getDateStatus=="function")&&Q.getDateStatus(c,c.getFullYear(),c.getMonth(),c.getDate())){return false}break}if(!c.c_equalsTo(Q.date)){Q.setDate(c);X=true}else{if(d.navtype==0){X=a=true}}}if(X){U&&Q.callHandler()}if(a){Calendar.removeClass(d,"hilite");U&&Q.callCloseHandler()}};Calendar.prototype.create=function(Y){var Z=null;if(!Y){Z=document.getElementsByTagName("body")[0];this.isPopup=true}else{Z=Y;this.isPopup=false}this.date=this.dateStr?new Date(this.dateStr):new Date();var V=Calendar.createElement("table");this.table=V;V.cellSpacing=0;V.cellPadding=0;V.calendar=this;Calendar.addEvent(V,"mousedown",Calendar.tableMouseDown);var T=Calendar.createElement("div");this.element=T;T.className="calendar";if(this.isPopup){T.style.position="absolute";T.style.display="none"}T.appendChild(V);var b=Calendar.createElement("thead",V);var X=null;var U=null;var S=this;var f=function(A,B,C){X=Calendar.createElement("td",U);X.colSpan=B;X.className="button";if(C!=0&&Math.abs(C)<=2){X.className+=" nav"}Calendar._add_evs(X);X.calendar=S;X.navtype=C;X.innerHTML="<div unselectable='on'>"+A+"</div>";return X};U=Calendar.createElement("tr",b);var R=6;(this.isPopup)&&--R;(this.weekNumbers)&&++R;f("?",1,400).ttip=Calendar._TT.INFO;this.title=f("",R,300);this.title.className="title";if(this.isPopup){this.title.ttip=Calendar._TT.DRAG_TO_MOVE;this.title.style.cursor="move";f("×",1,200).ttip=Calendar._TT.CLOSE}U=Calendar.createElement("tr",b);U.className="headrow";this._nav_py=f("«",1,-2);this._nav_py.ttip=Calendar._TT.PREV_YEAR;this._nav_pm=f("‹",1,-1);this._nav_pm.ttip=Calendar._TT.PREV_MONTH;this._nav_now=f(Calendar._TT.TODAY,this.weekNumbers?4:3,0);this._nav_now.ttip=Calendar._TT.GO_TODAY;this._nav_nm=f("›",1,1);this._nav_nm.ttip=Calendar._TT.NEXT_MONTH;this._nav_ny=f("»",1,2);this._nav_ny.ttip=Calendar._TT.NEXT_YEAR;U=Calendar.createElement("tr",b);U.className="daynames";if(this.weekNumbers){X=Calendar.createElement("td",U);X.className="name wn";X.innerHTML=Calendar._TT.WK}for(var c=7;c>0;--c){X=Calendar.createElement("td",U);if(!c){X.navtype=100;X.calendar=this;Calendar._add_evs(X)}}this.firstdayname=(this.weekNumbers)?U.firstChild.nextSibling:U.firstChild;this._displayWeekdays();var d=Calendar.createElement("tbody",V);this.tbody=d;for(c=6;c>0;--c){U=Calendar.createElement("tr",d);if(this.weekNumbers){X=Calendar.createElement("td",U)}for(var e=7;e>0;--e){X=Calendar.createElement("td",U);X.calendar=this;Calendar._add_evs(X)}}if(this.showsTime){U=Calendar.createElement("tr",d);U.className="time";X=Calendar.createElement("td",U);X.className="time";X.colSpan=2;X.innerHTML=Calendar._TT.TIME||" ";X=Calendar.createElement("td",U);X.className="time";X.colSpan=this.weekNumbers?4:3;(function(){function F(P,N,O,L){var K=Calendar.createElement("span",X);K.className=P;K.innerHTML=N;K.calendar=S;K.ttip=Calendar._TT.TIME_PART;K.navtype=50;K._range=[];if(typeof O!="number"){K._range=O}else{for(var J=O;J<=L;++J){var M;if(J<10&&L>=10){M="0"+J}else{M=""+J}K._range[K._range.length]=M}}Calendar._add_evs(K);return K}var B=S.date.getHours();var I=S.date.getMinutes();var A=!S.time24;var H=(B>12);if(A&&H){B-=12}var D=F("hour",B,A?1:0,A?12:23);var E=Calendar.createElement("span",X);E.innerHTML=":";E.className="colon";var G=F("minute",I,0,59);var C=null;X=Calendar.createElement("td",U);X.className="time";X.colSpan=2;if(A){C=F("ampm",H?"pm":"am",["am","pm"])}else{X.innerHTML=" "}S.onSetTime=function(){var K,L=this.date.getHours(),J=this.date.getMinutes();if(A){K=(L>=12);if(K){L-=12}if(L==0){L=12}C.innerHTML=K?"pm":"am"}D.innerHTML=(L<10)?("0"+L):L;G.innerHTML=(J<10)?("0"+J):J};S.onUpdateTime=function(){var K=this.date;var J=parseInt(D.innerHTML,10);if(A){if(/pm/i.test(C.innerHTML)&&J<12){J+=12}else{if(/am/i.test(C.innerHTML)&&J==12){J=0}}}var N=K.getDate();var M=K.getMonth();var L=K.getFullYear();K.setHours(J);K.setMinutes(parseInt(G.innerHTML,10));K.c_setFullYear(L);K.setMonth(M);K.setDate(N);this.dateClicked=false;this.callHandler()}})()}else{this.onSetTime=this.onUpdateTime=function(){}}var a=Calendar.createElement("tfoot",V);U=Calendar.createElement("tr",a);U.className="footrow";X=f(Calendar._TT.SEL_DATE,this.weekNumbers?8:7,300);X.className="ttip";if(this.isPopup){X.ttip=Calendar._TT.DRAG_TO_MOVE;X.style.cursor="move"}this.tooltips=X;T=Calendar.createElement("div",this.element);this.monthsCombo=T;T.className="combo";for(c=0;c<Calendar._MN.length;++c){var Q=Calendar.createElement("div");Q.className=Calendar.is_ie?"label-IEfix":"label";Q.month=c;Q.innerHTML=Calendar._SMN[c];T.appendChild(Q)}T=Calendar.createElement("div",this.element);this.yearsCombo=T;T.className="combo";for(c=12;c>0;--c){var W=Calendar.createElement("div");W.className=Calendar.is_ie?"label-IEfix":"label";T.appendChild(W)}this._init(this.firstDayOfWeek,this.date);Z.appendChild(this.element)};Calendar._keyEvent=function(T){var Q=window._dynarch_popupCalendar;if(!Q||Q.multiple){return false}(Calendar.is_ie)&&(T=window.event);var V=(Calendar.is_ie||T.type=="keypress"),S=T.keyCode;if(T.ctrlKey){switch(S){case 37:V&&Calendar.cellClick(Q._nav_pm);break;case 38:V&&Calendar.cellClick(Q._nav_py);break;case 39:V&&Calendar.cellClick(Q._nav_nm);break;case 40:V&&Calendar.cellClick(Q._nav_ny);break;default:return false}}else{switch(S){case 32:Calendar.cellClick(Q._nav_now);break;case 27:V&&Q.callCloseHandler();break;case 37:case 38:case 39:case 40:if(V){var Z,R,U,X,O,K;Z=S==37||S==38;K=(S==37||S==39)?1:7;function P(){O=Q.currentDateEl;var A=O.pos;R=A&15;U=A>>4;X=Q.ar_days[U][R]}P();function Y(){var A=new Date(Q.date);A.setDate(A.getDate()-K);Q.setDate(A)}function W(){var A=new Date(Q.date);A.setDate(A.getDate()+K);Q.setDate(A)}while(1){switch(S){case 37:if(--R>=0){X=Q.ar_days[U][R]}else{R=6;S=38;continue}break;case 38:if(--U>=0){X=Q.ar_days[U][R]}else{Y();P()}break;case 39:if(++R<7){X=Q.ar_days[U][R]}else{R=0;S=40;continue}break;case 40:if(++U<Q.ar_days.length){X=Q.ar_days[U][R]}else{W();P()}break}break}if(X){if(!X.disabled){Calendar.cellClick(X)}else{if(Z){Y()}else{W()}}}}break;case 13:if(V){Calendar.cellClick(Q.currentDateEl,T)}break;default:return false}}return Calendar.stopEvent(T)};Calendar.prototype._init=function(q,e){var f=new Date(),l=f.getFullYear(),c=f.getMonth(),AB=f.getDate();this.table.style.visibility="hidden";var v=e.getFullYear();if(v<this.minYear){v=this.minYear;e.c_setFullYear(v)}else{if(v>this.maxYear){v=this.maxYear;e.c_setFullYear(v)}}this.firstDayOfWeek=q;this.date=new Date(e);var d=e.getMonth();var a=e.getDate();var b=e.c_getMonthDays();e.setDate(1);var k=(e.getDay()-this.firstDayOfWeek)%7;if(k<0){k+=7}e.setDate(0-k);e.setDate(e.getDate()+1);var y=this.tbody.firstChild;var s=Calendar._SMN[d];var o=this.ar_days=new Array();var p=Calendar._TT.WEEKEND;var z=this.multiple?(this.datesCells={}):null;for(var i=0;i<6;++i,y=y.nextSibling){var AC=y.firstChild;if(this.weekNumbers){AC.className="day wn";AC.innerHTML=e.c_getWeekNumber();AC=AC.nextSibling}y.className="daysrow";var g=false,x,AA=o[i]=[];for(var j=0;j<7;++j,AC=AC.nextSibling,e.setDate(x+1)){x=e.getDate();var w=e.getDay();AC.className="day";AC.pos=i<<4|j;AA[j]=AC;var r=(e.getMonth()==d);if(!r){if(this.showsOtherMonths){AC.className+=" othermonth";AC.otherMonth=true}else{AC.className="emptycell";AC.innerHTML=" ";AC.disabled=true;continue}}else{AC.otherMonth=false;g=true}AC.disabled=false;AC.innerHTML=this.getDateText?this.getDateText(e,x):x;if(z){z[e.c_print("%Y%m%d")]=AC}if(this.getDateStatus){var n=this.getDateStatus(e,v,d,x);if(this.getDateToolTip){var u=this.getDateToolTip(e,v,d,x);if(u){AC.title=u}}if(n===true){AC.className+=" disabled";AC.disabled=true}else{if(/disabled/i.test(n)){AC.disabled=true}AC.className+=" "+n}}if(!AC.disabled){AC.caldate=new Date(e);AC.ttip="_";if(!this.multiple&&r&&x==a&&this.hiliteToday){AC.className+=" selected";this.currentDateEl=AC}if(e.getFullYear()==l&&e.getMonth()==c&&x==AB){AC.className+=" today";AC.ttip+=Calendar._TT.PART_TODAY}if(p.indexOf(w.toString())!=-1){AC.className+=AC.otherMonth?" oweekend":" weekend"}}}if(!(g||this.showsOtherMonths)){y.className="emptyrow"}}this.title.innerHTML=Calendar._MN[d]+", "+v;this.onSetTime();this.table.style.visibility="visible";this._initMultipleDates()};Calendar.prototype._initMultipleDates=function(){if(this.multiple){for(var F in this.multiple){var D=this.datesCells[F];var E=this.multiple[F];if(!E){continue}if(D){D.className+=" selected"}}}};Calendar.prototype._toggleMultipleDate=function(H){if(this.multiple){var G=H.c_print("%Y%m%d");var E=this.datesCells[G];if(E){var F=this.multiple[G];if(!F){Calendar.addClass(E,"selected");this.multiple[G]=H}else{Calendar.removeClass(E,"selected");delete this.multiple[G]}}}};Calendar.prototype.setDateToolTipHandler=function(B){this.getDateToolTip=B};Calendar.prototype.setDate=function(B){if(!B.c_equalsTo(this.date)){this._init(this.firstDayOfWeek,B)}};Calendar.prototype.refresh=function(){this._init(this.firstDayOfWeek,this.date)};Calendar.prototype.setFirstDayOfWeek=function(B){this._init(B,this.date);this._displayWeekdays()};Calendar.prototype.setDateStatusHandler=Calendar.prototype.setDisabledHandler=function(B){this.getDateStatus=B};Calendar.prototype.setRange=function(C,D){this.minYear=C;this.maxYear=D};Calendar.prototype.callHandler=function(){if(this.onSelected){this.onSelected(this,this.date.c_print(this.dateFormat))}};Calendar.prototype.callCloseHandler=function(){if(this.onClose){this.onClose(this)}this.hideShowCovered()};Calendar.prototype.destroy=function(){var B=this.element.parentNode;B.removeChild(this.element);Calendar._C=null;window._dynarch_popupCalendar=null};Calendar.prototype.reparent=function(D){var C=this.element;C.parentNode.removeChild(C);D.appendChild(C)};Calendar._checkCalendar=function(F){var E=window._dynarch_popupCalendar;if(!E){return false}var D=Calendar.is_ie?Calendar.getElement(F):Calendar.getTargetElement(F);for(;D!=null&&D!=E.element;D=D.parentNode){}if(D==null){window._dynarch_popupCalendar.callCloseHandler();return Calendar.stopEvent(F)}};Calendar.prototype.show=function(){var I=this.table.getElementsByTagName("tr");for(var J=I.length;J>0;){var H=I[--J];Calendar.removeClass(H,"rowhilite");var K=H.getElementsByTagName("td");for(var L=K.length;L>0;){var G=K[--L];Calendar.removeClass(G,"hilite");Calendar.removeClass(G,"active")}}this.element.style.display="block";this.hidden=false;if(this.isPopup){window._dynarch_popupCalendar=this;Calendar.addEvent(document,"keydown",Calendar._keyEvent);Calendar.addEvent(document,"keypress",Calendar._keyEvent);Calendar.addEvent(document,"mousedown",Calendar._checkCalendar)}this.hideShowCovered()};Calendar.prototype.hide=function(){if(this.isPopup){Calendar.removeEvent(document,"keydown",Calendar._keyEvent);Calendar.removeEvent(document,"keypress",Calendar._keyEvent);Calendar.removeEvent(document,"mousedown",Calendar._checkCalendar)}this.element.style.display="none";this.hidden=true;this.hideShowCovered()};Calendar.prototype.showAt=function(D,E){var F=this.element.style;F.left=D+"px";F.top=E+"px";this.show()};Calendar.prototype.showAtElement=function(I,H){var F=this;var G=Calendar.getAbsolutePos(I);if(!H||typeof H!="string"){this.showAt(G.x,G.y+I.offsetHeight);return true}function J(B){if(B.x<0){B.x=0}if(B.y<0){B.y=0}var A=document.createElement("div");var C=A.style;C.position="absolute";C.right=C.bottom=C.width=C.height="0px";document.body.appendChild(A);var D=Calendar.getAbsolutePos(A);document.body.removeChild(A);if(Calendar.is_ie){D.y+=document.body.scrollTop;D.x+=document.body.scrollLeft}else{D.y+=window.scrollY;D.x+=window.scrollX}var E=B.x+B.width-D.x;if(E>0){B.x-=E}E=B.y+B.height-D.y;if(E>0){B.y-=E}}this.element.style.display="block";Calendar.continuation_for_the_fucking_khtml_browser=function(){var D=F.element.offsetWidth;var B=F.element.offsetHeight;F.element.style.display="none";var C=H.substr(0,1);var A="l";if(H.length>1){A=H.substr(1,1)}switch(C){case"T":G.y-=B;break;case"B":G.y+=I.offsetHeight;break;case"C":G.y+=(I.offsetHeight-B)/2;break;case"t":G.y+=I.offsetHeight-B;break;case"b":break}switch(A){case"L":G.x-=D;break;case"R":G.x+=I.offsetWidth;break;case"C":G.x+=(I.offsetWidth-D)/2;break;case"l":G.x+=I.offsetWidth-D;break;case"r":break}G.width=D;G.height=B+40;F.monthsCombo.style.display="none";J(G);F.showAt(G.x,G.y)};if(Calendar.is_khtml){setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()",10)}else{Calendar.continuation_for_the_fucking_khtml_browser()}};Calendar.prototype.setDateFormat=function(B){this.dateFormat=B};Calendar.prototype.setTtDateFormat=function(B){this.ttDateFormat=B};Calendar.prototype.parseDate=function(D,C){if(!C){C=this.dateFormat}this.setDate(Date.parseDate(D,C))};Calendar.prototype.hideShowCovered=function(){if(!Calendar.is_ie&&!Calendar.is_opera){return }function S(A){var B=A.style.visibility;if(!B){if(document.defaultView&&typeof (document.defaultView.getComputedStyle)=="function"){if(!Calendar.is_khtml){B=document.defaultView.getComputedStyle(A,"").getPropertyValue("visibility")}else{B=""}}else{if(A.currentStyle){B=A.currentStyle.visibility}else{B=""}}}return B}var U=new Array("applet","iframe","select");var R=this.element;var T=Calendar.getAbsolutePos(R);var e=T.x;var Q=R.offsetWidth+e;var V=T.y;var W=R.offsetHeight+V;for(var c=U.length;c>0;){var d=document.getElementsByTagName(U[--c]);var f=null;for(var a=d.length;a>0;){f=d[--a];T=Calendar.getAbsolutePos(f);var X=T.x;var Y=f.offsetWidth+X;var Z=T.y;var b=f.offsetHeight+Z;if(this.hidden||(X>Q)||(Y<e)||(Z>W)||(b<V)){if(!f.__msh_save_visibility){f.__msh_save_visibility=S(f)}f.style.visibility=f.__msh_save_visibility}else{if(!f.__msh_save_visibility){f.__msh_save_visibility=S(f)}f.style.visibility="hidden"}}}};Calendar.prototype._displayWeekdays=function(){var J=this.firstDayOfWeek;var F=this.firstdayname;var H=Calendar._TT.WEEKEND;for(var I=0;I<7;++I){F.className="day name";var G=(I+J)%7;if(I){F.ttip=Calendar._TT.DAY_FIRST.replace("%s",Calendar._DN[G]);F.navtype=100;F.calendar=this;F.fdow=G;Calendar._add_evs(F)}if(H.indexOf(G.toString())!=-1){Calendar.addClass(F,"weekend")}F.innerHTML=Calendar._SDN[(I+J)%7];F=F.nextSibling}};Calendar.prototype._hideCombos=function(){this.monthsCombo.style.display="none";this.yearsCombo.style.display="none"};Calendar.prototype._dragStart=function(ev){if(this.dragging){return }this.dragging=true;var posX;var posY;if(Calendar.is_ie){posY=window.event.clientY+document.body.scrollTop;posX=window.event.clientX+document.body.scrollLeft}else{posY=ev.clientY+window.scrollY;posX=ev.clientX+window.scrollX}var st=this.element.style;this.xOffs=posX-parseInt(st.left);this.yOffs=posY-parseInt(st.top);with(Calendar){addEvent(document,"mousemove",calDragIt);addEvent(document,"mouseup",calDragEnd)}};Date._MD=new Array(31,28,31,30,31,30,31,31,30,31,30,31);Date.SECOND=1000;Date.MINUTE=60*Date.SECOND;Date.HOUR=60*Date.MINUTE;Date.DAY=24*Date.HOUR;Date.WEEK=7*Date.DAY;Date.parseDate=function(X,Q){var W=new Date();var V=0;var P=-1;var Y=0;var T=X.split(/\W+/);var U=Q.match(/%./g);var Z=0,N=0;var S=0;var O=0;for(Z=0;Z<T.length;++Z){if(!T[Z]){continue}switch(U[Z]){case"%d":case"%e":Y=parseInt(T[Z],10);break;case"%m":P=parseInt(T[Z],10)-1;break;case"%Y":case"%y":V=parseInt(T[Z],10);(V<100)&&(V+=(V>29)?1900:2000);break;case"%b":case"%B":for(N=0;N<12;++N){if(Calendar._MN[N].substr(0,T[Z].length).toLowerCase()==T[Z].toLowerCase()){P=N;break}}break;case"%H":case"%I":case"%k":case"%l":S=parseInt(T[Z],10);break;case"%P":case"%p":if(/pm/i.test(T[Z])&&S<12){S+=12}else{if(/am/i.test(T[Z])&&S>=12){S-=12}}break;case"%M":O=parseInt(T[Z],10);break}}if(isNaN(V)){V=W.getFullYear()}if(isNaN(P)){P=W.getMonth()}if(isNaN(Y)){Y=W.getDate()}if(isNaN(S)){S=W.getHours()}if(isNaN(O)){O=W.getMinutes()}if(V!=0&&P!=-1&&Y!=0){return new Date(V,P,Y,S,O,0)}V=0;P=-1;Y=0;for(Z=0;Z<T.length;++Z){if(T[Z].search(/[a-zA-Z]+/)!=-1){var R=-1;for(N=0;N<12;++N){if(Calendar._MN[N].substr(0,T[Z].length).toLowerCase()==T[Z].toLowerCase()){R=N;break}}if(R!=-1){if(P!=-1){Y=P+1}P=R}}else{if(parseInt(T[Z],10)<=12&&P==-1){P=T[Z]-1}else{if(parseInt(T[Z],10)>31&&V==0){V=parseInt(T[Z],10);(V<100)&&(V+=(V>29)?1900:2000)}else{if(Y==0){Y=T[Z]}}}}}if(V==0){V=W.getFullYear()}if(P!=-1&&Y!=0){return new Date(V,P,Y,S,O,0)}return W};Date.prototype.c_getMonthDays=function(D){var C=this.getFullYear();if(typeof D=="undefined"){D=this.getMonth()}if(((0==(C%4))&&((0!=(C%100))||(0==(C%400))))&&D==1){return 29}else{return Date._MD[D]}};Date.prototype.c_getDayOfYear=function(){var D=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var E=new Date(this.getFullYear(),0,0,0,0,0);var F=D-E;return Math.floor(F/Date.DAY)};Date.prototype.c_getWeekNumber=function(){var E=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var F=E.getDay();E.setDate(E.getDate()-(F+6)%7+3);var D=E.valueOf();E.setMonth(0);E.setDate(4);return Math.round((D-E.valueOf())/(7*86400000))+1};Date.prototype.c_equalsTo=function(B){return((this.getFullYear()==B.getFullYear())&&(this.getMonth()==B.getMonth())&&(this.getDate()==B.getDate())&&(this.getHours()==B.getHours())&&(this.getMinutes()==B.getMinutes()))};Date.prototype.c_setDateOnly=function(C){var D=new Date(C);this.setDate(1);this.c_setFullYear(D.getFullYear());this.setMonth(D.getMonth());this.setDate(D.getDate())};Date.prototype.c_print=function(d){var U=this.getMonth();var e=this.getDate();var c=this.getFullYear();var a=this.c_getWeekNumber();var Z=this.getDay();var V={};var Y=this.getHours();var T=(Y>=12);var g=(T)?(Y-12):Y;var W=this.c_getDayOfYear();if(g==0){g=12}var S=this.getMinutes();var f=this.getSeconds();V["%a"]=Calendar._SDN[Z];V["%A"]=Calendar._DN[Z];V["%b"]=Calendar._SMN[U];V["%B"]=Calendar._MN[U];V["%C"]=1+Math.floor(c/100);V["%d"]=(e<10)?("0"+e):e;V["%e"]=e;V["%H"]=(Y<10)?("0"+Y):Y;V["%I"]=(g<10)?("0"+g):g;V["%j"]=(W<100)?((W<10)?("00"+W):("0"+W)):W;V["%k"]=Y;V["%l"]=g;V["%m"]=(U<9)?("0"+(1+U)):(1+U);V["%M"]=(S<10)?("0"+S):S;V["%n"]="\n";V["%p"]=T?"PM":"AM";V["%P"]=T?"pm":"am";V["%s"]=Math.floor(this.getTime()/1000);V["%S"]=(f<10)?("0"+f):f;V["%t"]="\t";V["%U"]=V["%W"]=V["%V"]=(a<10)?("0"+a):a;V["%u"]=Z+1;V["%w"]=Z;V["%y"]=(""+c).substr(2,2);V["%Y"]=c;V["%%"]="%";var X=/%./g;if(!Calendar.is_ie5&&!Calendar.is_khtml){return d.replace(X,function(A){return V[A]||A})}var b=d.match(X);for(var i=0;i<b.length;i++){var R=V[b[i]];if(R){X=new RegExp(b[i],"g");d=d.replace(X,R)}}return d};Date.prototype.__msh_oldSetFullYear=Date.prototype.setFullYear;Date.prototype.c_setFullYear=function(D){var C=new Date(this);C.__msh_oldSetFullYear(D);if(C.getMonth()!=this.getMonth()){this.setDate(28)}this.__msh_oldSetFullYear(D)};window._dynarch_popupCalendar=null;Calendar._DN=new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday");Calendar._SDN=new Array("Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun");Calendar._FD=0;Calendar._MN=new Array("January","February","March","April","May","June","July","August","September","October","November","December");Calendar._SMN=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");Calendar._TT={};Calendar._TT.INFO="About the calendar";Calendar._TT.ABOUT="DHTML Date/Time Selector\n(c) dynarch.com 2002-2005 / Author: Mihai Bazon\nFor latest version visit: http://www.dynarch.com/projects/calendar/\nDistributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details.\n\nDate selection:\n- Use the \xab, \xbb buttons to select year\n- Use the "+String.fromCharCode(8249)+", "+String.fromCharCode(8250)+" buttons to select month\n- Hold mouse button on any of the above buttons for faster selection.";Calendar._TT.ABOUT_TIME="\n\nTime selection:\n- Click on any of the time parts to increase it\n- or Shift-click to decrease it\n- or click and drag for faster selection.";Calendar._TT.PREV_YEAR="Prev. year (hold for menu)";Calendar._TT.PREV_MONTH="Prev. month (hold for menu)";Calendar._TT.GO_TODAY="Go Today";Calendar._TT.NEXT_MONTH="Next month (hold for menu)";Calendar._TT.NEXT_YEAR="Next year (hold for menu)";Calendar._TT.SEL_DATE="Select date";Calendar._TT.DRAG_TO_MOVE="Drag to move";Calendar._TT.PART_TODAY=" (today)";Calendar._TT.DAY_FIRST="Display %s first";Calendar._TT.WEEKEND="0,6";Calendar._TT.CLOSE="Close";Calendar._TT.TODAY="Today";Calendar._TT.TIME_PART="(Shift-)Click or drag to change value";Calendar._TT.DEF_DATE_FORMAT="%Y-%m-%d";Calendar._TT.TT_DATE_FORMAT="%a, %b %e";Calendar._TT.WK="wk";Calendar._TT.TIME="Time:";Calendar.setup=function(I){function J(B,A){if(typeof I[B]=="undefined"){I[B]=A}}J("inputField",null);J("displayArea",null);J("button",null);J("eventName","click");J("ifFormat","%Y/%m/%d");J("daFormat","%Y/%m/%d");J("singleClick",true);J("disableFunc",null);J("dateStatusFunc",I.disableFunc);J("dateText",null);J("firstDay",null);J("align","Br");J("range",[1900,2999]);J("weekNumbers",true);J("flat",null);J("flatCallback",null);J("onSelect",null);J("onClose",null);J("onUpdate",null);J("date",null);J("showsTime",false);J("timeFormat","24");J("electric",true);J("step",2);J("position",null);J("cache",false);J("showOthers",false);J("multiple",null);var M=["inputField","displayArea","button"];for(var N in M){if(typeof I[M[N]]=="string"){I[M[N]]=document.getElementById(I[M[N]])}}if(!(I.flat||I.multiple||I.inputField||I.displayArea||I.button)){alert("Calendar.setup:\n Nothing to setup (no fields found). Please check your code");return false}function H(B){var C=B.params;var A=(B.dateClicked||C.electric);if(A&&C.inputField){C.inputField.value=B.date.c_print(C.ifFormat);if(typeof C.inputField.onchange=="function"){C.inputField.onchange()}}if(A&&C.displayArea){C.displayArea.innerHTML=B.date.c_print(C.daFormat)}if(A&&typeof C.onUpdate=="function"){C.onUpdate(B)}if(A&&C.flat){if(typeof C.flatCallback=="function"){C.flatCallback(B)}}if(A&&C.singleClick&&B.dateClicked){B.callCloseHandler()}}if(I.flat!=null){if(typeof I.flat=="string"){I.flat=document.getElementById(I.flat)}if(!I.flat){alert("Calendar.setup:\n Flat specified but can't find parent.");return false}var K=new Calendar(I.firstDay,I.date,I.onSelect||H);K.showsOtherMonths=I.showOthers;K.showsTime=I.showsTime;K.time24=(I.timeFormat=="24");K.params=I;K.weekNumbers=I.weekNumbers;K.setRange(I.range[0],I.range[1]);K.setDateStatusHandler(I.dateStatusFunc);K.getDateText=I.dateText;if(I.ifFormat){K.setDateFormat(I.ifFormat)}if(I.inputField&&typeof I.inputField.value=="string"){K.parseDate(I.inputField.value)}K.create(I.flat);K.show();return false}var L=I.button||I.displayArea||I.inputField;L["on"+I.eventName]=function(){var E=I.inputField||I.displayArea;var C=I.inputField?I.ifFormat:I.daFormat;var F=false;var A=window.calendar;if(E){I.date=Date.parseDate(E.value||E.innerHTML,C)}if(!(A&&I.cache)){window.calendar=A=new Calendar(I.firstDay,I.date,I.onSelect||H,I.onClose||function(P){P.hide()});A.showsTime=I.showsTime;A.time24=(I.timeFormat=="24");A.weekNumbers=I.weekNumbers;F=true}else{if(I.date){A.setDate(I.date)}A.hide()}if(I.multiple){A.multiple={};for(var D=I.multiple.length;--D>=0;){var G=I.multiple[D];var B=G.c_print("%Y%m%d");A.multiple[B]=G}}A.showsOtherMonths=I.showOthers;A.yearStep=I.step;A.setRange(I.range[0],I.range[1]);A.params=I;A.setDateStatusHandler(I.dateStatusFunc);A.getDateText=I.dateText;A.setDateFormat(C);if(F){A.create()}A.refresh();if(!I.position){A.showAtElement(I.button||I.displayArea||I.inputField,I.align)}else{A.showAt(I.position[0],I.position[1])}return false};return K}; + +/* http://keith-wood.name/timeEntry.html + Time entry for jQuery v1.5.1. + Written by Keith Wood (kbwood{at}iinet.com.au) June 2007. + Licensed under the MIT (https://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt) license. + Please attribute the author if you use it. */ +(function($){function TimeEntry(){this._disabledInputs=[];this.regional=[];this.regional['']={show24Hours:true,separator:':',ampmPrefix:'',ampmNames:['AM','PM'],spinnerTexts:['Now','Previous field','Next field','Increment','Decrement']};this._defaults={appendText:'',showSeconds:true,timeSteps:[1,1,1],initialField:0,noSeparatorEntry:false,useMouseWheel:true,defaultTime:null,minTime:null,maxTime:null,spinnerImage:'spinnerDefault.png',spinnerSize:[20,20,8],spinnerBigImage:'',spinnerBigSize:[40,40,16],spinnerIncDecOnly:false,spinnerRepeat:[500,250],beforeShow:null,beforeSetTime:null};$.extend(this._defaults,this.regional[''])}$.extend(TimeEntry.prototype,{markerClassName:'hasTimeEntry',propertyName:'timeEntry',_appendClass:'timeEntry_append',_controlClass:'timeEntry_control',_expandClass:'timeEntry_expand',setDefaults:function(a){$.extend(this._defaults,a||{});return this},_attachPlugin:function(b,c){var d=$(b);if(d.hasClass(this.markerClassName)){return}var e={options:$.extend({},this._defaults,c),input:d,_field:0,_selectedHour:0,_selectedMinute:0,_selectedSecond:0};d.data(this.propertyName,e).addClass(this.markerClassName).bind('focus.'+this.propertyName,this._doFocus).bind('blur.'+this.propertyName,this._doBlur).bind('click.'+this.propertyName,this._doClick).bind('keydown.'+this.propertyName,this._doKeyDown).bind('keypress.'+this.propertyName,this._doKeyPress).bind('paste.'+this.propertyName,function(a){setTimeout(function(){n._parseTime(e)},1)});this._optionPlugin(b,c)},_optionPlugin:function(a,b,c){a=$(a);var d=a.data(this.propertyName);if(!b||(typeof b=='string'&&c==null)){var e=b;b=(d||{}).options;return(b&&e?b[e]:b)}if(!a.hasClass(this.markerClassName)){return}b=b||{};if(typeof b=='string'){var e=b;b={};b[e]=c}var f=this._extractTime(d);$.extend(d.options,b);d._field=0;if(f){this._setTime(d,new Date(0,0,0,f[0],f[1],f[2]))}a.next('span.'+this._appendClass).remove();a.parent().find('span.'+this._controlClass).remove();if($.fn.mousewheel){a.unmousewheel()}var g=(!d.options.spinnerImage?null:$('<span class="'+this._controlClass+'" style="display: inline-block; '+'background: url(\''+d.options.spinnerImage+'\') 0 0 no-repeat; width: '+d.options.spinnerSize[0]+'px; height: '+d.options.spinnerSize[1]+'px;"></span>'));a.after(d.options.appendText?'<span class="'+this._appendClass+'">'+d.options.appendText+'</span>':'').after(g||'');if(d.options.useMouseWheel&&$.fn.mousewheel){a.mousewheel(this._doMouseWheel)}if(g){g.mousedown(this._handleSpinner).mouseup(this._endSpinner).mouseover(this._expandSpinner).mouseout(this._endSpinner).mousemove(this._describeSpinner)}},_enablePlugin:function(a){this._enableDisable(a,false)},_disablePlugin:function(a){this._enableDisable(a,true)},_enableDisable:function(b,c){var d=$.data(b,this.propertyName);if(!d){return}b.disabled=c;if(b.nextSibling&&b.nextSibling.nodeName.toLowerCase()=='span'){n._changeSpinner(d,b.nextSibling,(c?5:-1))}n._disabledInputs=$.map(n._disabledInputs,function(a){return(a==b?null:a)});if(c){n._disabledInputs.push(b)}},_isDisabledPlugin:function(a){return $.inArray(a,this._disabledInputs)>-1},_destroyPlugin:function(b){b=$(b);if(!b.hasClass(this.markerClassName)){return}b.removeClass(this.markerClassName).removeData(this.propertyName).unbind('.'+this.propertyName);if($.fn.mousewheel){b.unmousewheel()}this._disabledInputs=$.map(this._disabledInputs,function(a){return(a==b[0]?null:a)});b.siblings('.'+this._appendClass+',.'+this._controlClass).remove()},_setTimePlugin:function(a,b){var c=$.data(a,this.propertyName);if(c){if(b===null||b===''){c.input.val('')}else{this._setTime(c,b?(typeof b=='object'?new Date(b.getTime()):b):null)}}},_getTimePlugin:function(a){var b=$.data(a,this.propertyName);var c=(b?this._extractTime(b):null);return(!c?null:new Date(0,0,0,c[0],c[1],c[2]))},_getOffsetPlugin:function(a){var b=$.data(a,this.propertyName);var c=(b?this._extractTime(b):null);return(!c?0:(c[0]*3600+c[1]*60+c[2])*1000)},_doFocus:function(a){var b=(a.nodeName&&a.nodeName.toLowerCase()=='input'?a:this);if(n._lastInput==b||n._isDisabledPlugin(b)){n._focussed=false;return}var c=$.data(b,n.propertyName);n._focussed=true;n._lastInput=b;n._blurredInput=null;$.extend(c.options,($.isFunction(c.options.beforeShow)?c.options.beforeShow.apply(b,[b]):{}));n._parseTime(c);setTimeout(function(){n._showField(c)},10)},_doBlur:function(a){n._blurredInput=n._lastInput;n._lastInput=null},_doClick:function(b){var c=b.target;var d=$.data(c,n.propertyName);if(!n._focussed){var e=d.options.separator.length+2;d._field=0;if(c.selectionStart!=null){for(var f=0;f<=Math.max(1,d._secondField,d._ampmField);f++){var g=(f!=d._ampmField?(f*e)+2:(d._ampmField*e)+d.options.ampmPrefix.length+d.options.ampmNames[0].length);d._field=f;if(c.selectionStart<g){break}}}else if(c.createTextRange){var h=$(b.srcElement);var i=c.createTextRange();var j=function(a){return{thin:2,medium:4,thick:6}[a]||a};var k=b.clientX+document.documentElement.scrollLeft-(h.offset().left+parseInt(j(h.css('border-left-width')),10))-i.offsetLeft;for(var f=0;f<=Math.max(1,d._secondField,d._ampmField);f++){var g=(f!=d._ampmField?(f*e)+2:(d._ampmField*e)+d.options.ampmPrefix.length+d.options.ampmNames[0].length);i.collapse();i.moveEnd('character',g);d._field=f;if(k<i.boundingWidth){break}}}}n._showField(d);n._focussed=false},_doKeyDown:function(a){if(a.keyCode>=48){return true}var b=$.data(a.target,n.propertyName);switch(a.keyCode){case 9:return(a.shiftKey?n._changeField(b,-1,true):n._changeField(b,+1,true));case 35:if(a.ctrlKey){n._setValue(b,'')}else{b._field=Math.max(1,b._secondField,b._ampmField);n._adjustField(b,0)}break;case 36:if(a.ctrlKey){n._setTime(b)}else{b._field=0;n._adjustField(b,0)}break;case 37:n._changeField(b,-1,false);break;case 38:n._adjustField(b,+1);break;case 39:n._changeField(b,+1,false);break;case 40:n._adjustField(b,-1);break;case 46:n._setValue(b,'');break;default:return true}return false},_doKeyPress:function(a){var b=String.fromCharCode(a.charCode==undefined?a.keyCode:a.charCode);if(b<' '){return true}var c=$.data(a.target,n.propertyName);n._handleKeyPress(c,b);return false},_doMouseWheel:function(a,b){if(n._isDisabledPlugin(a.target)){return}var c=$.data(a.target,n.propertyName);c.input.focus();if(!c.input.val()){n._parseTime(c)}n._adjustField(c,b);a.preventDefault()},_expandSpinner:function(b){var c=n._getSpinnerTarget(b);var d=$.data(n._getInput(c),n.propertyName);if(n._isDisabledPlugin(d.input[0])){return}if(d.options.spinnerBigImage){d._expanded=true;var e=$(c).offset();var f=null;$(c).parents().each(function(){var a=$(this);if(a.css('position')=='relative'||a.css('position')=='absolute'){f=a.offset()}return!f});$('<div class="'+n._expandClass+'" style="position: absolute; left: '+(e.left-(d.options.spinnerBigSize[0]-d.options.spinnerSize[0])/2-(f?f.left:0))+'px; top: '+(e.top-(d.options.spinnerBigSize[1]-d.options.spinnerSize[1])/2-(f?f.top:0))+'px; width: '+d.options.spinnerBigSize[0]+'px; height: '+d.options.spinnerBigSize[1]+'px; background: transparent url('+d.options.spinnerBigImage+') no-repeat 0px 0px; z-index: 10;"></div>').mousedown(n._handleSpinner).mouseup(n._endSpinner).mouseout(n._endExpand).mousemove(n._describeSpinner).insertAfter(c)}},_getInput:function(a){return $(a).siblings('.'+n.markerClassName)[0]},_describeSpinner:function(a){var b=n._getSpinnerTarget(a);var c=$.data(n._getInput(b),n.propertyName);b.title=c.options.spinnerTexts[n._getSpinnerRegion(c,a)]},_handleSpinner:function(a){var b=n._getSpinnerTarget(a);var c=n._getInput(b);if(n._isDisabledPlugin(c)){return}if(c==n._blurredInput){n._lastInput=c;n._blurredInput=null}var d=$.data(c,n.propertyName);n._doFocus(c);var e=n._getSpinnerRegion(d,a);n._changeSpinner(d,b,e);n._actionSpinner(d,e);n._timer=null;n._handlingSpinner=true;if(e>=3&&d.options.spinnerRepeat[0]){n._timer=setTimeout(function(){n._repeatSpinner(d,e)},d.options.spinnerRepeat[0]);$(b).one('mouseout',n._releaseSpinner).one('mouseup',n._releaseSpinner)}},_actionSpinner:function(a,b){if(!a.input.val()){n._parseTime(a)}switch(b){case 0:this._setTime(a);break;case 1:this._changeField(a,-1,false);break;case 2:this._changeField(a,+1,false);break;case 3:this._adjustField(a,+1);break;case 4:this._adjustField(a,-1);break}},_repeatSpinner:function(a,b){if(!n._timer){return}n._lastInput=n._blurredInput;this._actionSpinner(a,b);this._timer=setTimeout(function(){n._repeatSpinner(a,b)},a.options.spinnerRepeat[1])},_releaseSpinner:function(a){clearTimeout(n._timer);n._timer=null},_endExpand:function(a){n._timer=null;var b=n._getSpinnerTarget(a);var c=n._getInput(b);var d=$.data(c,n.propertyName);$(b).remove();d._expanded=false},_endSpinner:function(a){n._timer=null;var b=n._getSpinnerTarget(a);var c=n._getInput(b);var d=$.data(c,n.propertyName);if(!n._isDisabledPlugin(c)){n._changeSpinner(d,b,-1)}if(n._handlingSpinner){n._lastInput=n._blurredInput}if(n._lastInput&&n._handlingSpinner){n._showField(d)}n._handlingSpinner=false},_getSpinnerTarget:function(a){return a.target||a.srcElement},_getSpinnerRegion:function(a,b){var c=this._getSpinnerTarget(b);var d=$(c).offset();var e=[document.documentElement.scrollLeft||document.body.scrollLeft,document.documentElement.scrollTop||document.body.scrollTop];var f=(a.options.spinnerIncDecOnly?99:b.clientX+e[0]-d.left);var g=b.clientY+e[1]-d.top;var h=a.options[a._expanded?'spinnerBigSize':'spinnerSize'];var i=(a.options.spinnerIncDecOnly?99:h[0]-1-f);var j=h[1]-1-g;if(h[2]>0&&Math.abs(f-i)<=h[2]&&Math.abs(g-j)<=h[2]){return 0}var k=Math.min(f,g,i,j);return(k==f?1:(k==i?2:(k==g?3:4)))},_changeSpinner:function(a,b,c){$(b).css('background-position','-'+((c+1)*a.options[a._expanded?'spinnerBigSize':'spinnerSize'][0])+'px 0px')},_parseTime:function(a){var b=this._extractTime(a);if(b){a._selectedHour=b[0];a._selectedMinute=b[1];a._selectedSecond=b[2]}else{var c=this._constrainTime(a);a._selectedHour=c[0];a._selectedMinute=c[1];a._selectedSecond=(a.options.showSeconds?c[2]:0)}a._secondField=(a.options.showSeconds?2:-1);a._ampmField=(a.options.show24Hours?-1:(a.options.showSeconds?3:2));a._lastChr='';a._field=Math.max(0,Math.min(Math.max(1,a._secondField,a._ampmField),a.options.initialField));if(a.input.val()!=''){this._showTime(a)}},_extractTime:function(a,b){b=b||a.input.val();var c=b.split(a.options.separator);if(a.options.separator==''&&b!=''){c[0]=b.substring(0,2);c[1]=b.substring(2,4);c[2]=b.substring(4,6)}if(c.length>=2){var d=!a.options.show24Hours&&(b.indexOf(a.options.ampmNames[0])>-1);var e=!a.options.show24Hours&&(b.indexOf(a.options.ampmNames[1])>-1);var f=parseInt(c[0],10);f=(isNaN(f)?0:f);f=((d||e)&&f==12?0:f)+(e?12:0);var g=parseInt(c[1],10);g=(isNaN(g)?0:g);var h=(c.length>=3?parseInt(c[2],10):0);h=(isNaN(h)||!a.options.showSeconds?0:h);return this._constrainTime(a,[f,g,h])}return null},_constrainTime:function(a,b){var c=(b!=null);if(!c){var d=this._determineTime(a.options.defaultTime,a)||new Date();b=[d.getHours(),d.getMinutes(),d.getSeconds()]}var e=false;for(var i=0;i<a.options.timeSteps.length;i++){if(e){b[i]=0}else if(a.options.timeSteps[i]>1){b[i]=Math.round(b[i]/a.options.timeSteps[i])*a.options.timeSteps[i];e=true}}return b},_showTime:function(a){var b=(this._formatNumber(a.options.show24Hours?a._selectedHour:((a._selectedHour+11)%12)+1)+a.options.separator+this._formatNumber(a._selectedMinute)+(a.options.showSeconds?a.options.separator+this._formatNumber(a._selectedSecond):'')+(a.options.show24Hours?'':a.options.ampmPrefix+a.options.ampmNames[(a._selectedHour<12?0:1)]));this._setValue(a,b);this._showField(a)},_showField:function(a){var b=a.input[0];if(a.input.is(':hidden')||n._lastInput!=b){return}var c=a.options.separator.length+2;var d=(a._field!=a._ampmField?(a._field*c):(a._ampmField*c)-a.options.separator.length+a.options.ampmPrefix.length);var e=d+(a._field!=a._ampmField?2:a.options.ampmNames[0].length);if(b.setSelectionRange){b.setSelectionRange(d,e)}else if(b.createTextRange){var f=b.createTextRange();f.moveStart('character',d);f.moveEnd('character',e-a.input.val().length);f.select()}if(!b.disabled){b.focus()}},_formatNumber:function(a){return(a<10?'0':'')+a},_setValue:function(a,b){if(b!=a.input.val()){a.input.val(b).trigger('change')}},_changeField:function(a,b,c){var d=(a.input.val()==''||a._field==(b==-1?0:Math.max(1,a._secondField,a._ampmField)));if(!d){a._field+=b}this._showField(a);a._lastChr='';return(d&&c)},_adjustField:function(a,b){if(a.input.val()==''){b=0}this._setTime(a,new Date(0,0,0,a._selectedHour+(a._field==0?b*a.options.timeSteps[0]:0)+(a._field==a._ampmField?b*12:0),a._selectedMinute+(a._field==1?b*a.options.timeSteps[1]:0),a._selectedSecond+(a._field==a._secondField?b*a.options.timeSteps[2]:0)))},_setTime:function(a,b){b=this._determineTime(b,a);var c=this._constrainTime(a,b?[b.getHours(),b.getMinutes(),b.getSeconds()]:null);b=new Date(0,0,0,c[0],c[1],c[2]);var b=this._normaliseTime(b);var d=this._normaliseTime(this._determineTime(a.options.minTime,a));var e=this._normaliseTime(this._determineTime(a.options.maxTime,a));b=(d&&b<d?d:(e&&b>e?e:b));if($.isFunction(a.options.beforeSetTime)){b=a.options.beforeSetTime.apply(a.input[0],[this._getTimePlugin(a.input[0]),b,d,e])}a._selectedHour=b.getHours();a._selectedMinute=b.getMinutes();a._selectedSecond=b.getSeconds();this._showTime(a)},_determineTime:function(i,j){var k=function(a){var b=new Date();b.setTime(b.getTime()+a*1000);return b};var l=function(a){var b=n._extractTime(j,a);var c=new Date();var d=(b?b[0]:c.getHours());var e=(b?b[1]:c.getMinutes());var f=(b?b[2]:c.getSeconds());if(!b){var g=/([+-]?[0-9]+)\s*(s|S|m|M|h|H)?/g;var h=g.exec(a);while(h){switch(h[2]||'s'){case's':case'S':f+=parseInt(h[1],10);break;case'm':case'M':e+=parseInt(h[1],10);break;case'h':case'H':d+=parseInt(h[1],10);break}h=g.exec(a)}}c=new Date(0,0,10,d,e,f,0);if(/^!/.test(a)){if(c.getDate()>10){c=new Date(0,0,10,23,59,59)}else if(c.getDate()<10){c=new Date(0,0,10,0,0,0)}}return c};return(i?(typeof i=='string'?l(i):(typeof i=='number'?k(i):i)):null)},_normaliseTime:function(a){if(!a){return null}a.setFullYear(1900);a.setMonth(0);a.setDate(0);return a},_handleKeyPress:function(a,b){if(b==a.options.separator){this._changeField(a,+1,false)}else if(b>='0'&&b<='9'){var c=parseInt(b,10);var d=parseInt(a._lastChr+b,10);var e=(a._field!=0?a._selectedHour:(a.options.show24Hours?(d<24?d:c):(d>=1&&d<=12?d:(c>0?c:a._selectedHour))%12+(a._selectedHour>=12?12:0)));var f=(a._field!=1?a._selectedMinute:(d<60?d:c));var g=(a._field!=a._secondField?a._selectedSecond:(d<60?d:c));var h=this._constrainTime(a,[e,f,g]);this._setTime(a,new Date(0,0,0,h[0],h[1],h[2]));if(a.options.noSeparatorEntry&&a._lastChr){this._changeField(a,+1,false)}else{a._lastChr=b}}else if(!a.options.show24Hours){b=b.toLowerCase();if((b==a.options.ampmNames[0].substring(0,1).toLowerCase()&&a._selectedHour>=12)||(b==a.options.ampmNames[1].substring(0,1).toLowerCase()&&a._selectedHour<12)){var i=a._field;a._field=a._ampmField;this._adjustField(a,+1);a._field=i;this._showField(a)}}}});var m=['getOffset','getTime','isDisabled'];function isNotChained(a,b){if(a=='option'&&(b.length==0||(b.length==1&&typeof b[0]=='string'))){return true}return $.inArray(a,m)>-1}$.fn.timeEntry=function(b){var c=Array.prototype.slice.call(arguments,1);if(isNotChained(b,c)){return n['_'+b+'Plugin'].apply(n,[this[0]].concat(c))}return this.each(function(){if(typeof b=='string'){if(!n['_'+b+'Plugin']){throw'Unknown command: '+b;}n['_'+b+'Plugin'].apply(n,[this].concat(c))}else{var a=($.fn.metadata?$(this).metadata():{});n._attachPlugin(this,$.extend({},a,b||{}))}})};var n=$.timeEntry=new TimeEntry()})(jQuery); \ No newline at end of file diff --git a/web2py/applications/SP/static/js/jquery.js b/web2py/applications/SP/static/js/jquery.js new file mode 100644 index 0000000..644d35e --- /dev/null +++ b/web2py/applications/SP/static/js/jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(a,b){"use strict";"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){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.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||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=Array.isArray(d)))?(e?(e=!1,f=c&&Array.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;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;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(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 qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(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){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.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===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!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 ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.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},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.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=ga.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=ga.selectors={cacheLength:50,createPseudo:ia,match:V,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(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===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]||ga.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]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.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(_,aa).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("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.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.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},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,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(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),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).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:oa(!1),disabled:oa(!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 X.test(a.nodeName)},input:function(a){return W.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:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function ua(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 va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(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?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,N,e),g(f,c,O,e)):(f++,j.call(a,g(f,c,N,e),g(f,c,O,e),g(f,c,N,c.notifyWith))):(d!==N&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S), +a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;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},U=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function V(){this.expando=r.expando+V.uid++}V.uid=1,V.prototype={cache:function(a){var b=a[this.expando];return b||(b={},U(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){Array.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(L)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var W=new V,X=new V,Y=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function $(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:Y.test(a)?JSON.parse(a):a)}function _(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Z,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=$(c)}catch(e){}X.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return X.hasData(a)||W.hasData(a)},data:function(a,b,c){return X.access(a,b,c)},removeData:function(a,b){X.remove(a,b)},_data:function(a,b,c){return W.access(a,b,c)},_removeData:function(a,b){W.remove(a,b)}}),r.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=X.get(f),1===f.nodeType&&!W.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),_(f,d,e[d])));W.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){X.set(this,a)}):T(this,function(b){var c;if(f&&void 0===b){if(c=X.get(f,a),void 0!==c)return c;if(c=_(f,a),void 0!==c)return c}else this.each(function(){X.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.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 W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=W.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var aa=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ba=new RegExp("^(?:([+-])=|)("+aa+")([a-z%]*)$","i"),ca=["Top","Right","Bottom","Left"],da=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ea=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function fa(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&ba.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ga={};function ha(a){var b,c=a.ownerDocument,d=a.nodeName,e=ga[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ga[d]=e,e)}function ia(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=W.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&da(d)&&(e[f]=ha(d))):"none"!==c&&(e[f]="none",W.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ia(this,!0)},hide:function(){return ia(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){da(this)?r(this).show():r(this).hide()})}});var ja=/^(?:checkbox|radio)$/i,ka=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c<d;c++)W.set(a[c],"globalEval",!b||W.get(b[c],"globalEval"))}var pa=/<|&#?\w+;/;function qa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(pa.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ka.exec(f)||["",""])[1].toLowerCase(),i=ma[h]||ma._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g,h=[],i=b.delegateCount,j=a.target;if(i&&j.nodeType&&!("click"===a.type&&a.button>=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c<i;c++)d=b[c],e=d.selector+" ",void 0===g[e]&&(g[e]=d.needsContext?r(e,this).index(j)>-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i<b.length&&h.push({elem:j,handlers:b.slice(i)}),h},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==xa()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===xa()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&B(this,"input"))return this.click(),!1},_default:function(a){return B(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?va:wa,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:wa,isPropagationStopped:wa,isImmediatePropagationStopped:wa,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=va,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=va,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=va,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&sa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ta.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return ya(this,a,b,c,d)},one:function(a,b,c,d){return ya(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=wa),this.each(function(){r.event.remove(this,a,c,b)})}});var za=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/<script|<style|<link/i,Ba=/checked\s*(?:[^=]|=\s*.checked.)/i,Ca=/^true\/(.*)/,Da=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}X.hasData(a)&&(h=X.access(a),i=r.extend({},h),X.set(b,i))}}function Ia(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ja.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ja(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,na(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ga),l=0;l<i;l++)j=h[l],la.test(j.type||"")&&!W.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Da,""),k))}return a}function Ka(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(na(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&oa(na(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(za,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d<e;d++)Ia(f[d],g[d]);if(b)if(c)for(f=f||na(a),g=g||na(h),d=0,e=f.length;d<e;d++)Ha(f[d],g[d]);else Ha(a,h);return g=na(h,"script"),g.length>0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(na(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ja(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(na(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var La=/^margin/,Ma=new RegExp("^("+aa+")(?!px)[a-z%]+$","i"),Na=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",ra.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,ra.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Oa(a,b,c){var d,e,f,g,h=a.style;return c=c||Na(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ma.test(g)&&La.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Pa(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Qa=/^(none|table(?!-c[ea]).+)/,Ra=/^--/,Sa={position:"absolute",visibility:"hidden",display:"block"},Ta={letterSpacing:"0",fontWeight:"400"},Ua=["Webkit","Moz","ms"],Va=d.createElement("div").style;function Wa(a){if(a in Va)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ua.length;while(c--)if(a=Ua[c]+b,a in Va)return a}function Xa(a){var b=r.cssProps[a];return b||(b=r.cssProps[a]=Wa(a)||a),b}function Ya(a,b,c){var d=ba.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Za(a,b,c,d,e){var f,g=0;for(f=c===(d?"border":"content")?4:"width"===b?1:0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+ca[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+ca[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+ca[f]+"Width",!0,e))):(g+=r.css(a,"padding"+ca[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+ca[f]+"Width",!0,e)));return g}function $a(a,b,c){var d,e=Na(a),f=Oa(a,b,e),g="border-box"===r.css(a,"boxSizing",!1,e);return Ma.test(f)?f:(d=g&&(o.boxSizingReliable()||f===a.style[b]),"auto"===f&&(f=a["offset"+b[0].toUpperCase()+b.slice(1)]),f=parseFloat(f)||0,f+Za(a,b,c||(g?"border":"content"),d,e)+"px")}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Oa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=Ra.test(b),j=a.style;return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:j[b]:(f=typeof c,"string"===f&&(e=ba.exec(c))&&e[1]&&(c=fa(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(j[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i?j.setProperty(b,c):j[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b),i=Ra.test(b);return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Oa(a,b,d)),"normal"===e&&b in Ta&&(e=Ta[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Qa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?$a(a,b,d):ea(a,Sa,function(){return $a(a,b,d)})},set:function(a,c,d){var e,f=d&&Na(a),g=d&&Za(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=ba.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ya(a,c,g)}}}),r.cssHooks.marginLeft=Pa(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Oa(a,"marginLeft"))||a.getBoundingClientRect().left-ea(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+ca[d]+b]=f[d]||f[d-2]||f[0];return e}},La.test(a)||(r.cssHooks[a+b].set=Ya)}),r.fn.extend({css:function(a,b){return T(this,function(a,b,c){var d,e,f={},g=0;if(Array.isArray(b)){for(d=Na(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&da(a),q=W.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],cb.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=W.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ia([a],!0),j=a.style.display||j,k=r.css(a,"display"),ia([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=W.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ia([a],!0),m.done(function(){p||ia([a]),W.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=hb(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],Array.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=kb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=ab||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(i||h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:ab||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);f<g;f++)if(d=kb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,hb,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j}r.Animation=r.extend(kb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return fa(c.elem,a,ba.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(L);for(var c,d=0,e=a.length;d<e;d++)c=a[d],kb.tweeners[c]=kb.tweeners[c]||[],kb.tweeners[c].unshift(b)},prefilters:[ib],prefilter:function(a,b){b?kb.prefilters.unshift(a):kb.prefilters.push(a)}}),r.speed=function(a,b,c){var d=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off?d.duration=0:"number"!=typeof d.duration&&(d.duration in r.fx.speeds?d.duration=r.fx.speeds[d.duration]:d.duration=r.fx.speeds._default),null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){r.isFunction(d.old)&&d.old.call(this),d.queue&&r.dequeue(this,d.queue)},d},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(da).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=kb(this,r.extend({},a),f);(e||W.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=W.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&db.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=W.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),r.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(ab=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),ab=void 0},r.fx.timer=function(a){r.timers.push(a),r.fx.start()},r.fx.interval=13,r.fx.start=function(){bb||(bb=!0,eb())},r.fx.stop=function(){bb=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var lb,mb=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return T(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), +null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!B(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Tb=[],Ub=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Tb.pop()||r.expando+"_"+ub++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Ub.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ub.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Ub,"$1"+e):b.jsonp!==!1&&(b.url+=(vb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Tb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=C.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=qa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=pb(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length},r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),b=f.ownerDocument,c=b.documentElement,e=b.defaultView,{top:d.top+e.pageYOffset-c.clientTop,left:d.left+e.pageXOffset-c.clientLeft}):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),B(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||ra})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return T(this,function(a,d,e){var f;return r.isWindow(a)?f=a:9===a.nodeType&&(f=a.defaultView),void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Pa(o.pixelPosition,function(a,c){if(c)return c=Oa(a,b),Ma.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return T(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.holdReady=function(a){a?r.readyWait++:r.ready(!0)},r.isArray=Array.isArray,r.parseJSON=JSON.parse,r.nodeName=B,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Vb=a.jQuery,Wb=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Wb),b&&a.jQuery===r&&(a.jQuery=Vb),r},b||(a.jQuery=a.$=r),r}); diff --git a/web2py/applications/SP/static/js/modernizr-2.8.3.min.js b/web2py/applications/SP/static/js/modernizr-2.8.3.min.js new file mode 100644 index 0000000..81aafb7 --- /dev/null +++ b/web2py/applications/SP/static/js/modernizr-2.8.3.min.js @@ -0,0 +1,4 @@ +/* Modernizr 2.8.3 (Custom Build) | MIT & BSD + * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-mq-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load + */ +;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a){var e=a[d];if(!G(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b,"string")||F(b,"undefined")?H(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),I(e,b,c))}function K(){e.input=function(c){for(var d=0,e=c.length;d<e;d++)u[c[d]]=c[d]in k;return u.list&&(u.list=!!b.createElement("datalist")&&!!a.HTMLDataListElement),u}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),e.inputtypes=function(a){for(var d=0,e,f,h,i=a.length;d<i;d++)k.setAttribute("type",f=a[d]),e=k.type!=="text",e&&(k.value=l,k.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(f)&&k.style.WebkitAppearance!==c?(g.appendChild(k),h=b.defaultView,e=h.getComputedStyle&&h.getComputedStyle(k,null).WebkitAppearance!=="textfield"&&k.offsetHeight!==0,g.removeChild(k)):/^(search|tel)$/.test(f)||(/^(url|email)$/.test(f)?e=k.checkValidity&&k.checkValidity()===!1:e=k.value!=l)),t[a[d]]=!!e;return t}("search tel url email datetime date month week time datetime-local number range color".split(" "))}var d="2.8.3",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k=b.createElement("input"),l=":)",m={}.toString,n=" -webkit- -moz- -o- -ms- ".split(" "),o="Webkit Moz O ms",p=o.split(" "),q=o.toLowerCase().split(" "),r={svg:"http://www.w3.org/2000/svg"},s={},t={},u={},v=[],w=v.slice,x,y=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["­",'<style id="s',h,'">',a,"</style>"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b)&&c(b).matches||!1;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return J("flexWrap")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return D("background-color:rgba(150,255,150,.5)"),G(j.backgroundColor,"rgba")},s.hsla=function(){return D("background-color:hsla(120,40%,100%,.5)"),G(j.backgroundColor,"rgba")||G(j.backgroundColor,"hsla")},s.multiplebgs=function(){return D("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return J("backgroundSize")},s.borderimage=function(){return J("borderImage")},s.borderradius=function(){return J("borderRadius")},s.boxshadow=function(){return J("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return E("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return J("animationName")},s.csscolumns=function(){return J("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return D((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),G(j.backgroundImage,"gradient")},s.cssreflections=function(){return J("boxReflect")},s.csstransforms=function(){return!!J("transform")},s.csstransforms3d=function(){var a=!!J("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return J("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="<svg/>",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var L in s)C(s,L)&&(x=L.toLowerCase(),e[x]=s[L](),v.push((e[x]?"":"no-")+x));return e.input||K(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)C(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},D(""),i=k=null,function(a,b){function l(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e<g;e++)d.createElement(f[e]);return d}function q(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return s.shivMethods?o(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(s,b.frag)}function r(a){a||(a=b);var c=n(a);return s.shivCSS&&!g&&!c.hasCSS&&(c.hasCSS=!!l(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),k||q(a,c),a}var c="3.7.0",d=a.html5||{},e=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,f=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,g,h="_html5shiv",i=0,j={},k;(function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,e.prefixed=function(a,b,c){return b?J(a,b,c):J(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))}; diff --git a/web2py/applications/SP/static/js/web2py-bootstrap4.js b/web2py/applications/SP/static/js/web2py-bootstrap4.js new file mode 100644 index 0000000..91f3d8f --- /dev/null +++ b/web2py/applications/SP/static/js/web2py-bootstrap4.js @@ -0,0 +1,82 @@ +(function($, undefined) { + $.web2py.ajax_fields = function(target) { + /* + *this attaches something to a newly loaded fragment/page + * Ideally all events should be bound to the document, so we can avoid calling + * this over and over... all will be bound to the document + */ + /*adds btn class to buttons*/ + $('button:not([class^="btn"])', target).addClass('btn btn-default'); + $("p.w2p-autocomplete-widget input").addClass('form-control'); + $('form input[type="submit"]:not([class^="btn"]), form input[type="button"]:not([class^="btn"])', target).addClass('btn btn-default'); + /* javascript for PasswordWidget*/ + $('input[type=password][data-w2p_entropy]', target).each(function() { + $.web2py.validate_entropy($(this)); + }); + /* javascript for ListWidget*/ + $('ul.w2p_list', target).each(function() { + function pe(ul, e) { + var new_line = ml(ul); + rel(ul); + if ($(e.target).closest('li').is(':visible')) { + /* make sure we didn't delete the element before we insert after */ + new_line.insertAfter($(e.target).closest('li')); + } else { + /* the line we clicked on was deleted, just add to end of list */ + new_line.appendTo(ul); + } + new_line.find(":text").focus(); + return false; + } + + function rl(ul, e) { + if ($(ul).find('li').length > 1) { + /* only remove if we have more than 1 item so the list is never empty */ + $(e.target).closest('li').remove(); + } + } + + function ml(ul) { + /* clone the first field */ + var line = $(ul).find("li:first").clone(true); + line.find(':text').val(''); + return line; + } + + function rel(ul) { + /* keep only as many as needed*/ + $(ul).find("li").each(function() { + var trimmed = $.trim($(this).find(":text").val()); + if (trimmed == '') $(this).remove(); + else $(this).find(":text").val(trimmed); + }); + } + var ul = this; + $(ul).find(":text").addClass('form-control').wrap("<div class='input-group'></div>").after('<div class="input-group-addon"><i class="glyphicon glyphicon-plus"></i></div><div class="input-group-addon"><i class="glyphicon glyphicon-minus"></i></div>').keypress(function(e) { + return (e.which == 13) ? pe(ul, e) : true; + }).next().click(function(e) { + pe(ul, e); + e.preventDefault(); + }).next().click(function(e) { + rl(ul, e); + e.preventDefault(); + }); + }); + } + + $(function() { + $(".nav ul.dropdown-menu").each(function() { + var toggle = jQuery(this).parent(); + if (toggle.parent().hasClass("nav")) { + toggle.attr("data-w2pmenulevel", "l0"); + toggle.children("a") + .addClass("dropdown-toggle") + .append('<span class="caret"> </span>') + .attr("data-toggle", "dropdown"); + } else { + toggle.addClass("dropdown-submenu").removeClass("dropdown"); + }; + }); + }); + +})(jQuery); \ No newline at end of file diff --git a/web2py/applications/SP/static/js/web2py.js b/web2py/applications/SP/static/js/web2py.js new file mode 100644 index 0000000..22b9f25 --- /dev/null +++ b/web2py/applications/SP/static/js/web2py.js @@ -0,0 +1,828 @@ +(function ($, undefined) { + /* + * Unobtrusive scripting adapter for jQuery, largely taken from + * the wonderful https://github.com/rails/jquery-ujs + * + * + * Released under the MIT license + * + */ + 'use strict'; + if ($.web2py !== undefined) { + $.error('web2py.js has already been loaded!'); + } + + var FORMDATA_IS_SUPPORTED = typeof(FormData) !== 'undefined'; + var animateIn = 'fadeIn'; + // var animateIn = 'slideDown'; + + String.prototype.reverse = function () { + return this.split('').reverse().join(''); + }; + var web2py; + + $.web2py = web2py = { + + isUndefined: function (obj) { + /* grabbed from underscore.js */ + return obj === void 0; + }, + popup: function (url) { + /* popup a window */ + var newwindow = window.open(url, 'name', 'height=400,width=600'); + if (window.focus) newwindow.focus(); + return false; + }, + collapse: function (id) { + /* toggle an element */ + $('#' + id).slideToggle(); + }, + fade: function (id, value) { + /*fade something*/ + if (value > 0) $('#' + id).hide().fadeIn('slow'); + else $('#' + id).show().fadeOut('slow'); + }, + ajax: function (u, s, t, options) { + /*simple ajax function*/ + + // set options default value + options = typeof options !== 'undefined' ? options : {}; + + var query = ''; + if (typeof s == 'string') { + var d = $(s).serialize(); + if (d) { + query = d; + } + } else { + var pcs = []; + if (s !== null && !web2py.isUndefined(s)) + for (var i = 0; i < s.length; i++) { + var q = $('[name=' + s[i] + ']').serialize(); + if (q) { + pcs.push(q); + } + } + if (pcs.length > 0) { + query = pcs.join('&'); + } + } + + // default success action + var success_function = function (msg) { + if (t) { + if (t == ':eval') eval(msg); + else if (typeof t == 'string') $('#' + t).html(msg); + else t(msg); + } + }; + + // declare success actions as array + var success = [success_function]; + + // add user success actions + if ($.isArray(options.done)){ + success = $.merge(success, options.done); + } else { + success.push(options.done); + } + + // default jquery ajax options + var ajax_options = { + type: 'POST', + url: u, + data: query, + success: success + }; + + //remove custom "done" option if exists + delete options.done; + + // merge default ajax options with user custom options + for (var attrname in options) { + ajax_options[attrname] = options[attrname]; + } + + // call ajax function + $.ajax(ajax_options); + }, + ajax_fields: function (target) { + /* + *this attaches something to a newly loaded fragment/page + * Ideally all events should be bound to the document, so we can avoid calling + * this over and over... all will be bound to the document + */ + /*adds btn class to buttons*/ + $('button:not([class^="btn"])', target).addClass('btn'); + $( + 'form input[type="submit"]:not([class^="btn"]), form input[type="button"]:not([class^="btn"])', + target).addClass('btn'); + /* javascript for PasswordWidget*/ + $('input[type=password][data-w2p_entropy]', target).each(function () { + web2py.validate_entropy($(this)); + }); + /* javascript for ListWidget*/ + $('ul.w2p_list', target).each(function () { + function pe(ul, e) { + var new_line = ml(ul); + rel(ul); + if ($(e.target).parent().is(':visible')) { + /* make sure we didn't delete the element before we insert after */ + new_line.insertAfter($(e.target).parent()); + } else { + /* the line we clicked on was deleted, just add to end of list */ + new_line.appendTo(ul); + } + new_line.find(':text').focus(); + return false; + } + + function rl(ul, e) { + if ($(ul).children().length > 1) { + /* only remove if we have more than 1 item so the list is never empty */ + $(e.target).parent().remove(); + } + } + + function ml(ul) { + /* clone the first field */ + var line = $(ul).find('li:first').clone(true); + line.find(':text').val(''); + return line; + } + + function rel(ul) { + /* keep only as many as needed*/ + $(ul).find('li').each(function () { + var trimmed = $.trim($(this.firstChild).val()); + if (trimmed === '') $(this).remove(); + else $(this.firstChild).val(trimmed); + }); + } + var ul = this; + $(ul).find(':text').after('<a href="#">+</a> <a href="#">-</a>').keypress( + function (e) { + return (e.which == 13) ? pe(ul, e) : true; + }).next().click(function (e) { + pe(ul, e); + e.preventDefault(); + }).next().click(function (e) { + rl(ul, e); + e.preventDefault(); + }); + }); + }, + ajax_init: function (target) { + /*called whenever a fragment gets loaded */ + $('.w2p_hidden', target).hide(); + web2py.manage_errors(target); + web2py.ajax_fields(target); + web2py.show_if_handler(target); + web2py.component_handler(target); + }, + /* manage errors in forms */ + manage_errors: function (target) { + $('div.error', target).hide()[animateIn]('slow'); + }, + after_ajax: function (xhr) { + /* called whenever an ajax request completes */ + var command = xhr.getResponseHeader('web2py-component-command'); + var flash = xhr.getResponseHeader('web2py-component-flash'); + if (command !== null) { + eval(decodeURIComponent(command)); + } + if (flash) { + web2py.flash(decodeURIComponent(flash)); + } + }, + event_handlers: function () { + /* + * This is called once for page + * Ideally it should bound all the things that are needed + * and require no dom manipulations + */ + var doc = $(document); + doc.on('click', '.w2p_flash', function (event) { + event.preventDefault(); + var t = $(this); + if (t.css('top') == '0px') t.slideUp('slow'); + else t.fadeOut(); + }); + doc.on('keyup', 'input.integer', function () { + var nvalue = this.value.reverse().replace(/[^0-9\-]|\-(?=.)/g, '').reverse(); + if (this.value != nvalue) this.value = nvalue; + }); + doc.on('keyup', 'input.double, input.decimal', function () { + var nvalue = this.value.reverse().replace( + /[^0-9\-\.,]|[\-](?=.)|[\.,](?=[0-9]*[\.,])/g, '').reverse(); + if (this.value != nvalue) this.value = nvalue; + }); + var confirm_message = !web2py.isUndefined(w2p_ajax_confirm_message) ? w2p_ajax_confirm_message : + 'Are you sure you want to delete this object?'; + doc.on('click', 'input[type="checkbox"].delete', function () { + if (this.checked) + if (!web2py.confirm(confirm_message)) this.checked = false; + }); + var datetime_format = !web2py.isUndefined(w2p_ajax_datetime_format) ? w2p_ajax_datetime_format : + '%Y-%m-%d %H:%M:%S'; + doc.on('click', 'input.datetime', function () { + var tformat = $(this).data('w2p_datetime_format'); + var active = $(this).data('w2p_datetime'); + var format = !web2py.isUndefined(tformat) ? tformat : datetime_format; + if (active === undefined) { + Calendar.setup({ + inputField: this, + ifFormat: format, + showsTime: true, + timeFormat: '24' + }); + $(this).attr('autocomplete', 'off'); + $(this).data('w2p_datetime', 1); + $(this).trigger('click'); + } + }); + var date_format = !web2py.isUndefined(w2p_ajax_date_format) ? w2p_ajax_date_format : '%Y-%m-%d'; + doc.on('click', 'input.date', function () { + var tformat = $(this).data('w2p_date_format'); + var active = $(this).data('w2p_date'); + var format = !web2py.isUndefined(tformat) ? tformat : date_format; + if (active === undefined) { + Calendar.setup({ + inputField: this, + ifFormat: format, + showsTime: false + }); + $(this).data('w2p_date', 1); + $(this).attr('autocomplete', 'off'); + $(this).trigger('click'); + } + }); + doc.on('focus', 'input.time', function () { + var active = $(this).data('w2p_time'); + if (web2py.isUndefined(active)) { + $(this).timeEntry({ + spinnerImage: '' + }).attr('autocomplete', 'off'); + $(this).data('w2p_time', 1); + } + }); + /* help preventing double form submission for normal form (not LOADed) */ + $(doc).on('submit', 'form', function (e) { + var submit_buttons = $(this).find(web2py.formInputClickSelector); + submit_buttons.each(function() { + web2py.disableElement($(this)); + }) + /* safeguard in case the form doesn't trigger a refresh, + see https://github.com/web2py/web2py/issues/1100 */ + setTimeout(function () { + submit_buttons.each(function() { + web2py.enableElement($(this)); + }); + }, 5000); + }); + doc.ajaxSuccess(function (e, xhr) { + var redirect = xhr.getResponseHeader('web2py-redirect-location'); + if (redirect !== null) { + window.location = redirect; + } + /* run this here only if this Ajax request is NOT for a web2py component. */ + if (xhr.getResponseHeader('web2py-component-content') === null) { + web2py.after_ajax(xhr); + } + }); + + doc.ajaxError(function (e, xhr, settings, exception) { + /*personally I don't like it. + *if there's an error it it flashed and can be removed + *as any other message + *doc.off('click', '.w2p_flash') + */ + switch (xhr.status) { + case 500: + web2py.flash(ajax_error_500); + } + }); + + }, + trap_form: function (action, target) { + /* traps any LOADed form */ + $('#' + target + ' form').each(function () { + var form = $(this); + if (form.hasClass('no_trap')) { + return; + } + + var w2p_target = $(this).attr('data-w2p_target'); + if (web2py.isUndefined(w2p_target) || w2p_target === false) { + form.attr('data-w2p_target', target); + } else { + target = w2p_target; + } + + var url = form.attr('action'); + if ((url === '') || (url === '#') || web2py.isUndefined(url)) { + /* form has no action. Use component url. */ + url = action; + } + + form.submit(function (e) { + web2py.disableElement(form.find(web2py.formInputClickSelector)); + web2py.hide_flash(); + + var formData; + if (FORMDATA_IS_SUPPORTED) { + formData = new FormData(form[0]); // Allows file uploads. + } else { + formData = form.serialize(); // Fallback for older browsers. + } + web2py.ajax_page('post', url, formData, target, form); + + e.preventDefault(); + }); + form.on('click', web2py.formInputClickSelector, function (e) { + e.preventDefault(); + var input_name = $(this).attr('name'); + if (!web2py.isUndefined(input_name)) { + $('<input type="hidden" />').attr('name', input_name) + .attr('value', $(this).val()).appendTo(form); + } + form.trigger('submit'); + }); + }); + }, + ajax_page: function (method, action, data, target, element) { + /* element is a new parameter, but should be put be put in front */ + if (web2py.isUndefined(element)) element = $(document); + /* if target is not there, fill it with something that there isn't in the page*/ + if (web2py.isUndefined(target) || target === '') target = 'w2p_none'; + + /* processData and contentType must be set to false when passing a FormData + object to jQuery.ajax. */ + var isFormData = Object.prototype.toString.call(data) === '[object FormData]'; + var contentType = isFormData ? false : 'application/x-www-form-urlencoded; charset=UTF-8'; + if (web2py.fire(element, 'ajax:before', null, target)) { /*test a usecase, should stop here if returns false */ + $.ajax({ + 'type': method, + 'url': action, + 'data': data, + 'processData': !isFormData, + 'contentType': contentType, + 'beforeSend': function (xhr, settings) { + xhr.setRequestHeader('web2py-component-location', document.location); + xhr.setRequestHeader('web2py-component-element', target); + web2py.fire(element, 'w2p:componentBegin', [xhr, settings], target); + return web2py.fire(element, 'ajax:beforeSend', [xhr, settings], target); //test a usecase, should stop here if returns false + }, + 'success': function (data, status, xhr) { + /*bummer for form submissions....the element is not there after complete + *because it gets replaced by the new response.... + */ + web2py.fire(element, 'ajax:success', [data, status, xhr], target); + }, + 'error': function (xhr, status, error) { + /*bummer for form submissions....in addition to the element being not there after + *complete because it gets replaced by the new response, standard form + *handling just returns the same status code for good and bad + *form submissions (i.e. that triggered a validator error) + */ + web2py.fire(element, 'ajax:error', [xhr, status, error], target); + }, + 'complete': function (xhr, status) { + web2py.fire(element, 'ajax:complete', [xhr, status], target); + web2py.updatePage(xhr, target); /* Parse and load the html received */ + web2py.trap_form(action, target); + web2py.ajax_init('#' + target); + web2py.after_ajax(xhr); + web2py.fire(element, 'w2p:componentComplete', [xhr, status], target); // Let us know the component is finished loading + } + }); + } + }, + component: function (action, target, timeout, times, el) { + /* element is a new parameter, but should be put in front */ + $(function () { + var jelement = $('#' + target); + var element = jelement.get(0); + var statement = 'jQuery("#' + target + '").get(0).reload();'; + element.reload = function () { + /* Continue if times is Infinity or + * the times limit is not reached + */ + if (element.reload_check()) { + web2py.ajax_page('get', action, null, target, el); + } + }; + /* Method to check timing limit */ + element.reload_check = function () { + if (jelement.hasClass('w2p_component_stop')) { + clearInterval(this.timing); + return false; + } + if (this.reload_counter == Infinity) { + return true; + } else { + if (!isNaN(this.reload_counter)) { + this.reload_counter -= 1; + if (this.reload_counter < 0) { + if (!this.run_once) { + clearInterval(this.timing); + return false; + } + } else { + return true; + } + } + } + return false; + }; + if (!isNaN(timeout)) { + element.timeout = timeout; + element.reload_counter = times; + if (times > 1) { + /* Multiple or infinite reload + * Run first iteration + */ + web2py.ajax_page('get', action, null, target, el); + element.run_once = false; + element.timing = setInterval(statement, timeout); + element.reload_counter -= 1; + } else if (times == 1) { + /* Run once with timeout */ + element.run_once = true; + element.setTimeout = setTimeout; + element.timing = setTimeout(statement, timeout); + } + } else { + /* run once (no timeout specified) */ + element.reload_counter = Infinity; + web2py.ajax_page('get', action, null, target, el); + } + }); + }, + updatePage: function (xhr, target) { + var t = $('#' + target); + var html = $.parseHTML(xhr.responseText, document, true); + var title_elements = $(html).filter('title').add($(html).find('title')); + var title = title_elements.last().text(); + if (title) { + title_elements.remove(); /* Remove any title elements from the response */ + document.title = $.trim(title); /* Set the new document title */ + } + var content = xhr.getResponseHeader('web2py-component-content'); + if (content == 'prepend') t.prepend(xhr.responseText); + else if (content == 'append') t.append(xhr.responseText); + else if (content != 'hide') t.html(html); + }, + calc_entropy: function (mystring) { + /* calculate a simple entropy for a given string */ + var csets = new Array( + 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', + '0123456789', '!@#$\%^&*()', '~`-_=+[]{}\|;:\'",.<>?/', + '0123456789abcdefghijklmnopqrstuvwxyz'); + var score = 0, + other = {}, + seen = {}, + lastset = null, + mystringlist = mystring.split(''); + for (var i = 0; i < mystringlist.length; i++) { /* classify this character */ + var c = mystringlist[i], + inset = 5; + for (var j = 0; j < csets.length; j++) + if (csets[j].indexOf(c) != -1) { + inset = j; + break; + } + /*calculate effect of character on alphabet size */ + if (!(inset in seen)) { + seen[inset] = 1; + score += csets[inset].length; + } else if (!(c in other)) { + score += 1; + other[c] = 1; + } + if (inset != lastset) { + score += 1; + lastset = inset; + } + } + var entropy = mystring.length * Math.log(score) / 0.6931471805599453; + return Math.round(entropy * 100) / 100; + }, + validate_entropy: function (myfield, req_entropy) { + if (!web2py.isUndefined(myfield.data('w2p_entropy'))) req_entropy = myfield.data('w2p_entropy'); + var validator = function () { + var v = (web2py.calc_entropy(myfield.val()) || 0) / req_entropy; + var r = 0, + g = 0, + b = 0, + rs = function (x) { + return Math.round(x * 15).toString(16); + }; + if (v <= 0.5) { + r = 1.0; + g = 2.0 * v; + } else { + r = (1.0 - 2.0 * (Math.max(v, 0) - 0.5)); + g = 1.0; + } + var color = '#' + rs(r) + rs(g) + rs(b); + myfield.css('background-color', color); + var entropy_callback = myfield.data('entropy_callback'); + if (entropy_callback) entropy_callback(v); + }; + if (!myfield.hasClass('entropy_check')) myfield.on('keyup', validator).on('keydown', validator) + .addClass('entropy_check'); + }, + web2py_websocket: function (url, onmessage, onopen, onclose) { + if ('WebSocket' in window) { + var ws = new WebSocket(url); + ws.onopen = onopen ? onopen : (function () {}); + ws.onmessage = onmessage; + ws.onclose = onclose ? onclose : (function () {}); + return true; /* supported */ + } else return false; /* not supported */ + }, + /* new from here */ + /* Form input elements bound by web2py.js */ + formInputClickSelector: 'input[type=submit], input[type=image], button[type=submit], button:not([type])', + /* Form input elements disabled during form submission */ + disableSelector: 'input, button, textarea, select', + /* Form input elements re-enabled after form submission */ + enableSelector: 'input:disabled, button:disabled, textarea:disabled, select:disabled', + /* Triggers an event on an element and returns false if the event result is false */ + fire: function (obj, type, data, target) { + var event = $.Event(type, { + 'containerTarget': $('#' + target)[0] + }); + obj.trigger(event, data); + return event.result !== false; + }, + /* Helper function, needed to provide consistent behavior in IE */ + stopEverything: function (e) { + $(e.target).trigger('w2p:everythingStopped'); + e.stopImmediatePropagation(); + return false; + }, + confirm: function (message) { + return confirm(message); + }, + /* replace element's html with the 'data-disable-with' after storing original html + * and prevent clicking on it */ + disableElement: function (el) { + if (!web2py.isUndefined(el.data('w2p_disable'))) { + return false; + } + el.addClass('disabled'); + var method = el.is('input') ? 'val' : 'html'; + //method = el.attr('name') ? 'html' : 'val'; + var disable_with_message = (!web2py.isUndefined(w2p_ajax_disable_with_message)) ? + w2p_ajax_disable_with_message : 'Working...'; + /*store enabled state if not already disabled */ + if (web2py.isUndefined(el.data('w2p_enable_with'))) { + el.data('w2p_enable_with', el[method]()); + } + /*if you don't want to see "working..." on buttons, replace the following + * two lines with this one + * el.data('w2p_disable_with', el[method]()); + */ + if ((el.data('w2p_disable_with') == 'default') || (web2py.isUndefined(el.data( + 'w2p_disable_with')))) { + el.data('w2p_disable_with', disable_with_message); + } + + /* set to disabled state*/ + el[method](el.data('w2p_disable_with')); + + el.bind('click.w2pDisable', function (e) { /* prevent further clicking*/ + return web2py.stopEverything(e); + }); + }, + + /* restore element to its original state which was disabled by 'disableElement' above*/ + enableElement: function (el) { + var method = el.is('input') ? 'val' : 'html'; + if (!web2py.isUndefined(el.data('w2p_enable_with'))) { + /* set to old enabled state */ + el[method](el.data('w2p_enable_with')); + el.removeData('w2p_enable_with'); + } + el.removeClass('disabled'); + el.unbind('click.w2pDisable'); + }, + /*convenience wrapper, internal use only */ + simple_component: function (action, target, element) { + web2py.component(action, target, 0, 1, element); + }, + /*helper for flash messages*/ + flash: function (message, status) { + var flash = $('.w2p_flash'); + web2py.hide_flash(); + flash.text(message).addClass(status); + if (flash.html()) flash.append('<span id="closeflash"> × </span>')[animateIn](); + }, + hide_flash: function () { + $('.w2p_flash').fadeOut(0).html(''); + }, + show_if_handler: function (target) { + var triggers = {}; + var show_if = function () { + var t = $(this); + var id = t.attr('id'); + t.attr('value', t.val()); + for (var k = 0; k < triggers[id].length; k++) { + var dep = $('#' + triggers[id][k], target); + var tr = $('#' + triggers[id][k] + '__row', target); + if (t.is(dep.attr('data-show-if'))) tr[animateIn](); + else tr.hide(); + } + }; + $('[data-show-trigger]', target).each(function () { + var name = $(this).attr('data-show-trigger'); + // The field exists only when creating/editing a row + if ($('#' + name).length) { + if (!triggers[name]) triggers[name] = []; + triggers[name].push($(this).attr('id')); + } + }); + for (var name in triggers) { + $('#' + name, target).change(show_if).keyup(show_if); + show_if.call($('#' + name, target)); + } + }, + component_handler: function (target) { + $('div[data-w2p_remote]', target).each(function () { + var remote, times, timeout, target; + var el = $(this); + remote = el.data('w2p_remote'); + times = el.data('w2p_times'); + timeout = el.data('w2p_timeout'); + target = el.attr('id'); + web2py.component(remote, target, timeout, times, $(this)); + }); + }, + a_handler: function (el, e) { + e.preventDefault(); + var method = el.data('w2p_method'); + var action = el.attr('href'); + var target = el.data('w2p_target'); + var confirm_message = el.data('w2p_confirm'); + + var pre_call = el.data('w2p_pre_call'); + if (!web2py.isUndefined(pre_call)) { + eval(pre_call); + } + if (confirm_message) { + if (confirm_message == 'default') { + confirm_message = !web2py.isUndefined(w2p_ajax_confirm_message) ? + w2p_ajax_confirm_message : 'Are you sure you want to delete this object?'; + } + if (!web2py.confirm(confirm_message)) { + web2py.stopEverything(e); + return; + } + } + if (web2py.isUndefined(target)) { + if (method == 'GET') { + web2py.ajax_page('get', action, [], '', el); + } else if (method == 'POST') { + web2py.ajax_page('post', action, [], '', el); + } + } else { + if (method == 'GET') { + web2py.ajax_page('get', action, [], target, el); + } else if (method == 'POST') { + web2py.ajax_page('post', action, [], target, el); + } + } + }, + a_handlers: function () { + var el = $(document); + el.on('click', 'a[data-w2p_method]', function (e) { + web2py.a_handler($(this), e); + }); + /* removal of element should happen only on success */ + el.on('ajax:success', 'a[data-w2p_method][data-w2p_remove]', function () { + var el = $(this); + var toremove = el.data('w2p_remove'); + if (!web2py.isUndefined(toremove)) { + toremove = el.closest(toremove); + if (!toremove.length) { + /*this enables removal of whatever selector if a closest is not found */ + toremove = $(toremove); + } + toremove.remove(); + } + }); + el.on('ajax:beforeSend', 'a[data-w2p_method][data-w2p_disable_with]', function () { + web2py.disableElement($(this)); + }); + /*re-enable click on completion*/ + el.on('ajax:complete', 'a[data-w2p_method][data-w2p_disable_with]', function () { + web2py.enableElement($(this)); + }); + }, + /* Disables form elements: + - Does not disable elements with 'data-w2p_disable' attribute + - Caches element value in 'w2p_enable_with' data store + - Replaces element text with value of 'data-w2p_disable_with' attribute + - Sets disabled property to true + */ + disableFormElements: function (form) { + form.find(web2py.disableSelector).each(function () { + var element = $(this), + method = element.is('button') ? 'html' : 'val'; + var disable_with = element.data('w2p_disable_with'); + var disable = element.data('w2p_disable'); + if (!web2py.isUndefined(disable)) { + return false; + } + if (!element.is(':file')) { // Altering file input values is not allowed. + if (web2py.isUndefined(disable_with)) { + element.data('w2p_disable_with', element[method]()); + } + if (web2py.isUndefined(element.data('w2p_enable_with'))) { + element.data('w2p_enable_with', element[method]()); + } + element[method](element.data('w2p_disable_with')); + } + element.prop('disabled', true); + }); + }, + + /* Re-enables disabled form elements: + - Replaces element text with cached value from 'w2p_enable_with' data store (created in `disableFormElements`) + - Sets disabled property to false + */ + enableFormElements: function (form) { + form.find(web2py.enableSelector).each(function () { + var element = $(this), + method = element.is('button') ? 'html' : 'val'; + if (element.data('w2p_enable_with')) { + element[method](element.data('w2p_enable_with')); + element.removeData('w2p_enable_with'); + } + element.prop('disabled', false); + }); + }, + form_handlers: function () { + var el = $(document); + el.on('ajax:beforeSend', 'form[data-w2p_target]', function () { + web2py.disableFormElements($(this)); + }); + el.on('ajax:complete', 'form[data-w2p_target]', function () { + web2py.enableFormElements($(this)); + }); + }, + /* Invalidate and force reload of a web2py component + */ + invalidate: function (target) { + $('div[data-w2p_remote]', target).each(function () { + var el = $('#' + $(this).attr('id')).get(0); + if (!web2py.isUndefined(el.timing)) { // Block triggering regular routines + clearInterval(el.timing); + } + }); + $.web2py.component_handler(target); + }, + main_hook: function () { + var flash = $('.w2p_flash'); + flash.hide(); + if (flash.html()) web2py.flash(flash.html()); + web2py.ajax_init(document); + web2py.event_handlers(); + web2py.a_handlers(); + web2py.form_handlers(); + } + }; + /*end of functions */ + /*main hook*/ + $(function () { + web2py.main_hook(); + }); + +})(jQuery); + +/* compatibility code - start */ +ajax = jQuery.web2py.ajax; +web2py_component = jQuery.web2py.component; +web2py_websocket = jQuery.web2py.web2py_websocket; +web2py_ajax_page = jQuery.web2py.ajax_page; +/*needed for IS_STRONG(entropy)*/ +web2py_validate_entropy = jQuery.web2py.validate_entropy; +/*needed for crud.search and SQLFORM.grid's search*/ +web2py_ajax_fields = jQuery.web2py.ajax_fields; +/*used for LOAD(ajax=False)*/ +web2py_trap_form = jQuery.web2py.trap_form; + +/*undocumented - rare*/ +popup = jQuery.web2py.popup; +collapse = jQuery.web2py.collapse; +fade = jQuery.web2py.fade; + +/* internals - shouldn't be needed +web2py_ajax_init = jQuery.web2py.ajax_init; +web2py_event_handlers = jQuery.web2py.event_handlers; +web2py_trap_link = jQuery.web2py.trap_link; +web2py_calc_entropy = jQuery.web2py.calc_entropy; +*/ +/* compatibility code - end*/ diff --git a/web2py/applications/SP/views/__init__.py b/web2py/applications/SP/views/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/web2py/applications/SP/views/__init__.py @@ -0,0 +1 @@ + diff --git a/web2py/applications/SP/views/appadmin/appadmin.html b/web2py/applications/SP/views/appadmin/appadmin.html new file mode 100644 index 0000000..834240b --- /dev/null +++ b/web2py/applications/SP/views/appadmin/appadmin.html @@ -0,0 +1,449 @@ +{{extend 'layout.html'}} +<script><!-- + jQuery(document).ready(function(){ + jQuery("table.sortable tbody tr").mouseover( function() { + jQuery(this).addClass("highlight"); }).mouseout( function() { + jQuery(this).removeClass("highlight"); }); + jQuery('table.sortable tbody tr:odd').addClass('odd'); + jQuery('table.sortable tbody tr:even').addClass('even'); +}); +//--></script> + +<div class="row"> + <div class="col-md-12"> + +{{if request.function=='index':}} +<h3>{{=T("后台")}}</h3> + {{if not databases:}}{{=T("后台(没有数据库))")}}{{pass}} + <ul class="nav nav-tabs" id="myTab"> + + <li class="nav-item"><a href="#userinfo" data-toggle="tab" class="nav-link active">用户信息</a></li> + <li class="nav-item"><a href="#user" data-toggle="tab" class="nav-link">用户登录信息</a></li> + <li class="nav-item"><a href="#taskinfo" data-toggle="tab" class="nav-link">任务信息</a></li> + <li class="nav-item"><a href="#handin" data-toggle="tab" class="nav-link">提交信息</a></li> + <li class="nav-item"><a href="#groupinfo" data-toggle="tab" class="nav-link">用户组信息</a></li> + <li class="nav-item"><a href="#membership" data-toggle="tab" class="nav-link">用户的组归属信息</a></li> + {{if auth.has_membership(group_id=2):}} + <li class="nav-item"><a href="#alltables" data-toggle="tab" class="nav-link">Tables</a></li> + <li class="nav-item"><a href="#hooks" data-toggle="tab" class="nav-link">Hooks</a></li> + {{pass}} + </ul> + + <div class="tab-content"> + {{if auth.has_membership(group_id=2):}} + <div class="tab-pane" id="alltables"> + <table class="table table-striped"> + {{for db in sorted(databases):}} + {{for table in databases[db].tables:}} + {{qry='%s.%s.id>0'%(db,table)}} + {{tbl=databases[db][table]}} + {{if hasattr(tbl,'_primarykey'):}} + {{if tbl._primarykey:}} + {{firstkey=tbl[tbl._primarykey[0]]}} + {{if firstkey.type in ['string','text']:}} + {{qry='%s.%s.%s!=""'%(db,table,firstkey.name)}} + {{else:}} + {{qry='%s.%s.%s>0'%(db,table,firstkey.name)}} + {{pass}} + {{else:}} + {{qry=''}} + {{pass}} + {{pass}} + <tr> + <th style="font-size: 1.75em;"> + » {{=A("%s.%s" % (db,table),_href=URL('select',args=[db],vars=dict(query=qry)))}} + </th> + <td> + {{=A(str(T('New Record')),_href=URL('insert',args=[db,table]),_class="btn btn-primary")}} + </td> + </tr> + {{pass}} + {{pass}} + </table> + </div> + <div class="tab-pane" id="hooks"> + {{=LOAD('appadmin', 'hooks', ajax=True)}} + </div> + {{pass}} + <div class="tab-pane active" id="userinfo"> + <table class="table table-striped"> + <tr> + <th>用户ID</th> + <th>认证名</th> + <th>宿舍</th> + <th>综合分数</th> + <th>欢乐豆</th> + <th>{{=A(str(T('添加')),_href=URL('add_userinfo'),_class="btn btn-primary")}}</th> + </tr> + {{for auth_record in databases['db'](databases['db'].auth_user).select():}} + {{i_records = get_user_info_by(auth_record.username)}} + <tr> + <td>{{=i_records.id}}</td> + <td>{{=i_records.username}}</td> + <td>{{=i_records.room}}</td> + <td>{{=i_records.score}}</td> + <td>{{=i_records.bean}}</td> + <td>{{=A(str(T('修改')),_href=URL('change_userinfo',args=[i_records.username]),_class="btn btn-secondary")}}</td> + </tr> + {{pass}} + </table> + </div> + <div class="tab-pane" id="user"> + <table class="table table-striped"> + <tr> + <th>认证名</th> + <th>真实姓名</th> + <th>电子邮箱</th> + <th>{{=A(str(T('添加')),_href=URL('add_user'),_class="btn btn-primary")}}</th> + </tr> + {{for records in databases['db'](databases['db'].auth_user).select():}} + <tr> + <td>{{=records.username}}</td> + <td>{{=records.name}}</td> + <td>{{=records.email}}</td> + <td>{{=A(str(T('修改')),_href=URL('change_user',args=[records.username]),_class="btn btn-secondary")}}</td> + </tr> + {{pass}} + </table> + </div> + <div class="tab-pane" id="taskinfo"> + <table class="table table-striped"> + <tr> + <th>任务名</th> + <th>创建时间</th> + <th>截止时间</th> + <th>参与人数</th> + <th>完成人数</th> + <th>删除</th> + <th>{{=A(str(T('添加')),_href=URL('add_task'),_class="btn btn-primary")}}</th> + </tr> + {{for records in m_db(m_db.task).select(orderby=m_db.task.create_date):}} + <tr> + <td>{{=records.name}}</td> + <td>{{=records.create_date}}</td> + <td>{{=records.end_date}}</td> + <td>{{=len(records.people)}}</td> + <td>{{=len(records.dopeople)}}</td> + <td>{{=A(str(T('删除')),_href=URL('delete_task',args=[records.id]))}}</td> + <td>{{=A(str(T('修改')),_href=URL('change_task',args=[records.id]),_class="btn btn-secondary")}}</td> + </tr> + {{pass}} + </table> + </div> + <div class="tab-pane" id="groupinfo"> + <table class="table table-striped"> + <tr> + <th>用户组ID</th> + <th>用户组身份</th> + <th>用户组描述</th> + <td>{{=A(str(T('添加')),_href=URL('add_group',args=[records.id]),_class="btn btn-primary")}}</td> + </tr> + {{for records in databases['db'](databases['db'].auth_group).select():}} + <tr> + <td>{{=records.id}}</td> + <td>{{=records.role}}</td> + <td>{{=records.description}}</td> + <td>{{=A(str(T('修改')),_href=URL('change_group',args=[records.id]),_class="btn btn-secondary")}}</td> + </tr> + {{pass}} + + </table> + </div> + <div class="tab-pane" id="membership"> + <table class="table table-striped"> + <tr> + <th>归属关系编号</th> + <th>用户ID</th> + <th>用户真实姓名</th> + <th>用户组ID</th> + <th>用户组身份</th> + <th>{{=A(str(T('添加')),_href=URL('add_relation',args=[records.id]),_class="btn btn-primary")}}</th> + </tr> + {{for records in databases['db'](databases['db'].auth_membership).select():}} + {{user_info = databases['db'](databases['db'].auth_user.id == records.user_id).select().first()}} + {{group_info = databases['db'](databases['db'].auth_group.id == records.group_id).select().first()}} + <tr> + <td>{{=records.id}}</td> + <td>{{=records.user_id}}</td> + <td>{{=user_info.name}}</td> + <td>{{=records.group_id}}</td> + <td>{{=group_info.role}}</td> + <td>{{=A(str(T('修改')),_href=URL('change_relation',args=[records.id]),_class="btn btn-secondary")}}</td> + </tr> + {{pass}} + + </table> + </div> + </div> +{{elif request.function=='select':}} + <h2>{{=XML(str(T("Database %s select"))%A(request.args[0],_href=URL('index'))) }} + </h2> + {{if tb:}} + <h3>{{=T('Traceback')}}</h3> + <pre> + {{=tb}} + </pre> + {{pass}} + {{if table:}} + {{=A(str(T('New Record')),_href=URL('insert',args=[request.args[0],table]),_class="btn btn-primary", _role="button")}}<br/><br/> + <hr /> + <h3>{{=T("Rows in Table")}}</h3><br/> + {{else:}} + <h3>{{=T("Rows selected")}}</h3><br/> + {{pass}} + {{=form}} + <p class="text-muted">{{=T('The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.')}}<br/> + {{=T('Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.')}}<br/> + {{=T('"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN')}}</p> + <br/><br/> + <h4>{{=T("%s selected", nrows)}}</h4> + {{if start>0:}}{{=A(T('previous %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start-step)),_class="btn btn-primary")}}{{pass}} + {{if stop<nrows:}}{{=A(T('next %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start+step)),_class="btn btn-primary")}}{{pass}} + {{if rows:}} + <div style="overflow:auto; width:80%;"> + {{linkto = lambda f, t, r: URL('update', args=[request.args[0], r, f]) if f else "#"}} + {{upload=URL('download',args=request.args[0])}} + {{=SQLTABLE(rows,linkto,upload,orderby=True,_class='table table-striped table-bordered sortable')}} + </div> + {{pass}} + <br/><br/> + <hr /> + <h3>{{=T("Import/Export")}}</h3><br/> + <a href="{{=URL('csv',args=request.args[0],vars=dict(query=query))}}" class="btn btn-primary">{{=T("export as csv file")}}</a> + {{=formcsv or ''}} + +{{elif request.function=='insert':}} + <h2>{{=T("Database")}} {{=A(request.args[0],_href=URL('index'))}} + {{if hasattr(table,'_primarykey'):}} + {{fieldname=table._primarykey[0]}} + {{dbname=request.args[0]}} + {{tablename=request.args[1]}} + {{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}} + {{=T("Table")}} {{=A(tablename,_href=URL('select',args=dbname,vars=dict(query='%s.%s.%s%s'%(dbname,tablename,fieldname,cond))))}} + {{else:}} + {{=T("Table")}} {{=A(request.args[1],_href=URL('select',args=request.args[0],vars=dict(query='%s.%s.id>0'%tuple(request.args[:2]))))}} + {{pass}} + </h2> + <h3>{{=T("New Record")}}</h3><br/> + {{=form}} +{{elif request.function=='change_userinfo' or request.function=='add_userinfo':}} + {{if request.function=='add_userinfo':}} + <h3>个人信息添加</h3> + {{else:}} + <h3>个人信息修改</h3> + {{pass}} + <HR style="FILTER: alpha(opacity=100,finishopacity=0,style=3)" color=#987cb9 SIZE=3> + {{=form}} +{{elif request.function=='change_user' or request.function=='add_user':}} + {{if request.function=='add_user':}} + <h3>个人登录信息添加</h3> + {{else:}} + <h3>个人登录信息修改</h3> + + {{pass}} + <HR style="FILTER: alpha(opacity=100,finishopacity=0,style=3)" color=#987cb9 SIZE=3> + {{=form}} +{{elif request.function=='add_task'or request.function=='change_task':}} + {{if request.function=='add_task':}} + <h3>任务添加</h3> + {{else:}} + <table> + <tr> + <td><h3 class="display:inline">任务修改</h3></td> + </tr> + </table> + {{pass}} + <HR style="FILTER: alpha(opacity=100,finishopacity=0,style=3)" color=#987cb9 SIZE=3> + {{=form}} + {{if request.function=='change_task':}} + {{pass}} +{{elif request.function=='add_group' or request.function=='change_group':}} + {{if request.function=='add_group':}} + <h3>用户组添加</h3> + {{else:}} + <h3>用户组修改</h3> + + {{pass}} + <HR style="FILTER: alpha(opacity=100,finishopacity=0,style=3)" color=#987cb9 SIZE=3> + {{=form}} +{{elif request.function=='add_relation' or request.function=='change_relation':}} + {{if request.function=='add_relation':}} + <h3>用户的组关系添加</h3> + {{else:}} + <h3>用户组的组关系修改</h3> + + {{pass}} + <HR style="FILTER: alpha(opacity=100,finishopacity=0,style=3)" color=#987cb9 SIZE=3> + {{=form}} +{{elif request.function=='update':}} + <h2>{{=T("Database")}} {{=A(request.args[0],_href=URL('index'))}} + {{if hasattr(table,'_primarykey'):}} + {{fieldname=request.vars.keys()[0]}} + {{dbname=request.args[0]}} + {{tablename=request.args[1]}} + {{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}} + {{=T("Table")}} {{=A(tablename,_href=URL('select',args=dbname,vars=dict(query='%s.%s.%s%s'%(dbname,tablename,fieldname,cond))))}} + {{=T("Record")}} {{=A('%s=%s'%request.vars.items()[0],_href=URL('update',args=request.args[:2],vars=request.vars))}} + {{else:}} + {{=T("Table")}} {{=A(request.args[1],_href=URL('select',args=request.args[0],vars=dict(query='%s.%s.id>0'%tuple(request.args[:2]))))}} + {{=T("Record id")}} {{=A(request.args[2],_href=URL('update',args=request.args[:3]))}} + {{pass}} + </h2> + <h3>{{=T("Edit current record")}}</h3><br/><br/>{{=form}} + +{{elif request.function=='state':}} + <h2>{{=T("Internal State")}}</h2> + <h3>{{=T("Current request")}}</h3> + {{=BEAUTIFY(request)}} + <br/><h3>{{=T("Current response")}}</h3> + {{=BEAUTIFY(response)}} + <br/><h3>{{=T("Current session")}}</h3> + {{=BEAUTIFY(session)}} + + +{{elif request.function == 'ccache':}} +<h2>{{T("Cache")}}</h2> +<div class="list"> + + <div class="list-header"> + <h3>{{T("Statistics")}}</h3> + </div> + + <div class="content"> + <h4>{{=T("Overview")}}</h4> + <p>{{=T.M("Number of entries: **%s**", total['entries'])}}</p> + {{if total['entries'] > 0:}} + <p>{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})", + dict( ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}} + </p> + <p> + {{=T("Size of cache:")}} + {{if object_stats:}} + {{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict(items=total['objects'], bytes=total['bytes']))}} + {{if total['bytes'] > 524287:}} + {{=T.M("(**%.0d MB**)", total['bytes'] / 1048576)}} + {{pass}} + {{else:}} + {{=T.M("**not available** (requires the Python [[Pympler https://pypi.python.org/pypi/Pympler popup]] library)")}} + {{pass}} + </p> + <p> + {{=T.M("Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.", + dict(hours=total['oldest'][0], min=total['oldest'][1], sec=total['oldest'][2]))}} + </p> + {{=BUTTON(T('Cache Keys'), _onclick='jQuery("#all_keys").toggle().toggleClass( "w2p_hidden" );')}} + <div class="w2p_hidden" id="all_keys"> + {{=total['keys']}} + </div> + <br /> + {{pass}} + + <h4>{{=T("RAM")}}</h4> + <p>{{=T.M("Number of entries: **%s**", ram['entries'])}}</p> + {{if ram['entries'] > 0:}} + <p>{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})", + dict( ratio=ram['ratio'], hits=ram['hits'], misses=ram['misses']))}} + </p> + <p> + {{=T("Size of cache:")}} + {{if object_stats:}} + {{=T.M("**%(items)s** items, **%(bytes)s** %%{byte(bytes)}", dict(items=ram['objects'], bytes=ram['bytes']))}} + {{if ram['bytes'] > 524287:}} + {{=T.M("(**%.0d MB**)", ram['bytes'] / 10485576)}} + {{pass}} + {{else:}} + {{=T.M("``**not available**``:red (requires the Python [[Pympler https://pypi.python.org/pypi/Pympler popup]] library)")}} + {{pass}} + </p> + <p> + {{=T.M("RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.", + dict(hours=ram['oldest'][0], min=ram['oldest'][1], sec=ram['oldest'][2]))}} + </p> + {{=BUTTON(T('RAM Cache Keys'), _onclick='jQuery("#ram_keys").toggle().toggleClass( "w2p_hidden" );')}} + <div class="w2p_hidden" id="ram_keys"> + {{=ram['keys']}} + </div> + <br /> + {{pass}} + + <h4>{{=T("DISK")}}</h4> + <p>{{=T.M("Number of entries: **%s**", disk['entries'])}}</p> + {{if disk['entries'] > 0:}} + <p> + {{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})", + dict(ratio=disk['ratio'], hits=disk['hits'], misses=disk['misses']))}} + </p> + <p> + {{=T("Size of cache:")}} + {{if object_stats:}} + {{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict( items=disk['objects'], bytes=disk['bytes']))}} + {{if disk['bytes'] > 524287:}} + {{=T.M("(**%.0d MB**)", disk['bytes'] / 1048576)}} + {{pass}} + {{else:}} + {{=T.M("``**not available**``:red (requires the Python [[Pympler https://pypi.python.org/pypi/Pympler popup]] library)")}} + {{pass}} + </p> + <p> + {{=T.M("DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.", + dict(hours=disk['oldest'][0], min=disk['oldest'][1], sec=disk['oldest'][2]))}} + </p> + {{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle().toggleClass( "w2p_hidden" );')}} + <div class="w2p_hidden" id="disk_keys"> + {{=disk['keys']}} + </div> + <br /> + {{pass}} + </div> + + <div class="list-header"> + <h3>{{=T("Manage Cache")}}</h3> + </div> + + <div class="content"> + <p> + {{=form}} + </p> + </div> +</div> +<div class="clear"></div> +{{pass}} + +{{if request.function=='d3_graph_model':}} +<h2>{{=T("Graph Model")}}</h2> + {{if not databases:}} + {{=T("No databases in this application")}} + {{else:}} + <div id="vis"></div> + <link rel="stylesheet" href="{{=URL('admin','static','css/d3_graph.css')}}"/> + <script> + // Define the d3 input data + {{from gluon.serializers import json }} + var nodes = {{=XML(json(nodes))}}; + var links = {{=XML(json(links))}}; + d3_graph(); + </script> + {{pass}} +{{pass}} + +{{if request.function == 'manage':}} +<h2>{{=heading}}</h2> +<ul class="nav nav-tabs"> + {{for k, tablename in enumerate(tablenames):}} + <li{{=XML(' class="active"') if k == 0 else ''}}> + <a href="#table-{{=tablename}}" data-toggle="tab">{{=labels[k]}}</a> + </li> + {{pass}} +</ul> + +<div class="tab-content"> + {{for k, tablename in enumerate(tablenames):}} + <div class="tab-pane{{=XML(' active') if k == 0 else ''}}" id="table-{{=tablename}}"> + {{=LOAD(f='manage.load', args=[request.args(0), k], ajax=True)}} + </div> + {{pass}} +</div> +{{pass}} + + </div> +</div> diff --git a/web2py/applications/SP/views/appadmin/change_userinfo.html b/web2py/applications/SP/views/appadmin/change_userinfo.html new file mode 100644 index 0000000..51b314f --- /dev/null +++ b/web2py/applications/SP/views/appadmin/change_userinfo.html @@ -0,0 +1,3 @@ +{{extend 'layout.html'}} + <h2>修改个人信息</h2> + {{=form}} \ No newline at end of file diff --git a/web2py/applications/SP/views/default/change_settings.html b/web2py/applications/SP/views/default/change_settings.html new file mode 100644 index 0000000..86aab6b --- /dev/null +++ b/web2py/applications/SP/views/default/change_settings.html @@ -0,0 +1,8 @@ +{{extend 'layout.html'}} + <div class="row"> + <div id="web2py_user_form" class="col-lg-6" style="background-color:white; margin: 0 auto 5px auto; box-shadow: 0 0 5px #a1a1a1; border-radius:5px;padding: 20px"> + <h2>个人设置</h2> + <HR style="FILTER: alpha(opacity=100,finishopacity=0,style=3)" color=#987cb9 SIZE=3> + {{=form}} + </div> + </div> \ No newline at end of file diff --git a/web2py/applications/SP/views/default/index.html b/web2py/applications/SP/views/default/index.html new file mode 100644 index 0000000..24b68cd --- /dev/null +++ b/web2py/applications/SP/views/default/index.html @@ -0,0 +1,51 @@ +{{extend 'layout.html'}} + +{{block header}} +<div class="jumbotron jumbotron-fluid" style="background-color: #333; color:white; padding:30px;word-wrap:break-word;"> + <div class="container center"> + <h1 class="display-5">/{{=request.application}}/{{=request.controller}}/{{=request.function}}</h1> + </div> +</div> +{{end}} + +<div class="row"> + <div class="col-md-12"> + {{if 'message' in globals():}} + <h2>{{=message}}</h2> + <p class="lead">{{=T('西北工业大学软件与微电子学院软件工程9班学习考勤情况统计计划')}}</p> + <ol style="word-wrap:break-word;"> + <li>{{=T("本计划旨在促进班级同学的学习积极性。")}}</li> + <li>{{=XML(T('You visited the url %s', A(request.env.path_info,_href=request.env.path_info)))}}</li> + <li>{{=XML(T('Which called the function %s located in the file %s', + (A(request.function+'()',_href='#'), + A('web2py/applications/%(application)s/controllers/%(controller)s.py' % request, + _href=URL('admin','default','peek', args=(request.application,'controllers',request.controller+'.py'))))))}}</li> + <li>{{=XML(T('The output of the file is a dictionary that was rendered by the view %s', + A('web2py/applications/%(application)s/views/%(controller)s/index.html' % request, + _href=URL('admin','default','peek',args=(request.application,'views',request.controller,'index.html')))))}}</li> + <li>{{=T('You can modify this application and adapt it to your needs')}}</li> + </ol> + <div class="jumbotron jumbotron-fluid" style="padding:30px;word-wrap:break-word;"> + <div class="container center"> + <a class="btn btn-primary" href="{{=URL('admin','default','index')}}"> + <i class="fa fa-cog"></i> + {{=T("admin")}} + </a> + <a class="btn btn-secondary" href="{{=URL('examples','default','index')}}">{{=T("Online examples")}}</a> + <a class="btn btn-secondary" href="http://web2py.com">web2py.com</a> + <a class="btn btn-secondary" href="http://web2py.com/book">{{=T('Documentation')}}</a> + <a class="btn btn-secondary" href="{{=URL('default','api_get_user_email')}}">{{=T('API Example')}}</a> + <a class="btn btn-secondary" href="{{=URL('default','grid/auth_user')}}">{{=T('Grid Example')}}</a> + <a class="btn btn-secondary" href="{{=URL('default','wiki')}}">{{=T('Wiki Example')}}</a> + </div> + </div> + {{elif 'content' in globals():}} + {{=content}} + {{else:}} + {{=BEAUTIFY(response._vars)}} + {{pass}} + </div> +</div> + + + diff --git a/web2py/applications/SP/views/default/monitorctl.html b/web2py/applications/SP/views/default/monitorctl.html new file mode 100644 index 0000000..e09b5c2 --- /dev/null +++ b/web2py/applications/SP/views/default/monitorctl.html @@ -0,0 +1,38 @@ +{{extend 'layout.html'}} +<div class="row"> + <div id="web2py_user_form" class="col-lg-6" style="background-color:white; margin: 0 auto 5px auto; box-shadow: 0 0 5px #a1a1a1; border-radius:5px;padding: 20px"> + <h2>{{=t_record.name}}</h2> + <HR style="FILTER: alpha(opacity=100,finishopacity=0,style=3)" color=#987cb9 SIZE=3> + <div class="component_contents"> + <table class="table table-striped"> + <tr> + <th>姓名</th> + <th>用户名</th> + <th>是否完成</th> + <th>操作</th> + </tr> + {{count = 0}} + {{for person in peo_lst:}} + {{if_done = False}} + <tr> + <td>{{=person}}</td> + {{if prcd_lst[count] is not None:}} + <td>{{=prcd_lst[count].username}}</td> + {{pass}} + <td>{{if person in dopeo_lst:}}✔️{{if_done = True}}{{pass}}</td> + <td> + {{if if_done is False:}} + {{if prcd_lst[count] is not None:}} + <a class="btn btn-secondary" href={{=URL('default','finish_task',args=[t_record.id, prcd_lst[count].id,"monitor"])}}>完成任务</a> + {{pass}} + {{pass}} + </td> + </tr> + {{count += 1}} + {{pass}} + </table> + <a class="btn btn-primary" href={{=URL('default','history_task',args=[t_record.id])}}>截止任务</a> + </div> + </div> + </div> + </div> \ No newline at end of file diff --git a/web2py/applications/SP/views/default/myclass.html b/web2py/applications/SP/views/default/myclass.html new file mode 100644 index 0000000..3ce4e63 --- /dev/null +++ b/web2py/applications/SP/views/default/myclass.html @@ -0,0 +1,29 @@ +{{extend 'layout.html'}} + <div class="row"> + <div id="web2py_user_form" class="col-lg-6" style="background-color:white; margin: 0 auto 5px auto; box-shadow: 0 0 5px #a1a1a1; border-radius:5px;padding: 20px"> + <h2>班级信息</h2> + <HR style="FILTER: alpha(opacity=100,finishopacity=0,style=3)" color=#987cb9 SIZE=3> + <div class="component_contents"> + {{=info}} + </div> + + </div> + </div> + <div class="row"> + <div id="web2py_user_form" class="col-lg-6" style="background-color:white; margin: 0 auto 5px auto; box-shadow: 0 0 5px #a1a1a1; border-radius:5px;padding: 20px"> + <h2>班级排名</h2> + <HR style="FILTER: alpha(opacity=100,finishopacity=0,style=3)" color=#987cb9 SIZE=3> + {{rank = 1}} + {{for person in rank_list:}} + + {{if person.showrank == True or rank < 3:}} + <div class="component_contents"> + + 第{{=rank}}名:{{=get_user_auth(person.username).name}} + /综合分数:{{=person.score}} + </div> + {{rank += 1}} + {{pass}} + {{pass}} + </div> + </div> \ No newline at end of file diff --git a/web2py/applications/SP/views/default/myhome.html b/web2py/applications/SP/views/default/myhome.html new file mode 100644 index 0000000..41a200f --- /dev/null +++ b/web2py/applications/SP/views/default/myhome.html @@ -0,0 +1,16 @@ +{{extend 'layout.html'}} + + <div class="row"> + <div id="web2py_user_form" class="col-lg-6" style="background-color:white; margin: 0 auto 5px auto; box-shadow: 0 0 5px #a1a1a1; border-radius:5px;padding: 20px"> + <h2>{{=auth.user.name}}</h2> + <HR style="FILTER: alpha(opacity=100,finishopacity=0,style=3)" color=#987cb9 SIZE=3> + <div class="component_contents"> + {{=info_menu}} + </div> + <div class="jumbotron jumbotron-fluid" style="padding:30px;word-wrap:break-word;"> + <div class="container center"> + <a class="btn btn-secondary" href={{=URL('default','change_settings')}}>个人设置</a> + </div> + </div> + </div> + </div> diff --git a/web2py/applications/SP/views/default/task.html b/web2py/applications/SP/views/default/task.html new file mode 100644 index 0000000..2e899c8 --- /dev/null +++ b/web2py/applications/SP/views/default/task.html @@ -0,0 +1,34 @@ +{{extend 'layout.html'}} + {{for task in m_db(m_db.task.active == True).select():}} + {{if auth.user.name in task.people:}} + <div class="row"> + <div id="web2py_user_form" class="col-lg-6" style="background-color:white; margin: 0 auto 5px auto; box-shadow: 0 0 5px #a1a1a1; border-radius:5px;padding: 20px"> + <h2>{{=task.name}}</h2> + <HR style="FILTER: alpha(opacity=100,finishopacity=0,style=3)" color=#987cb9 SIZE=3> + <div class="component_contents"> + <ul> + <li>是否完成:{{if auth.user.name in task.dopeople:}}{{if_done=True}}已完成{{pass}} + {{else:}}{{if_done = False}}未完成{{pass}}</li> + + <li>截止时间:{{=task.end_date}}</li> + <li>参与人数:{{=len(task.people)}}</li> + <li>已完成人数:{{=len(task.dopeople)}}</li> + <li>任务信息:{{=task.info}}</li> + </ul> + </div> + {{if auth.has_membership(group_id=1) or task.admindo is False:}} + <div class="jumbotron jumbotron-fluid" style="padding:15px;word-wrap:break-word;"> + <div class="container center"> + {{if task.admindo is False and if_done == False:}} + <a class="btn btn-secondary" href={{=URL('default','finish_task',args=[task.id,auth.user.id])}}>完成任务</a> + {{pass}} + {{if auth.has_membership(group_id=1):}} + <a class="btn btn-secondary" href={{=URL('default','monitorctl',args=[task.id])}}>班委管理</a> + {{pass}} + </div> + </div> + {{pass}} + </div> + </div> + {{pass}} + {{pass}} \ No newline at end of file diff --git a/web2py/applications/SP/views/default/user.html b/web2py/applications/SP/views/default/user.html new file mode 100644 index 0000000..b7959ff --- /dev/null +++ b/web2py/applications/SP/views/default/user.html @@ -0,0 +1,33 @@ +{{extend 'layout.html'}} + +<div class="row"> + <div id="web2py_user_form" class="col-lg-6" style="background-color:white; margin: 0 auto 5px auto; box-shadow: 0 0 5px #a1a1a1; border-radius:5px;padding: 20px"> + <h2> + {{=T('激活认证') if request.args(0) == 'register' else T('认证') if request.args(0) == 'login' else T(request.args(0).replace('_',' ').title())}} + </h2> + {{=form}} + {{if request.args(0)=='login' and not 'register' in auth.settings.actions_disabled:}} + <a href="{{=URL('user/register')}}">{{=T('激活认证')}}</a> + <br/> + {{pass}} + {{if request.args(0)=='login' and not 'retrieve_password' in auth.settings.actions_disabled:}} + <a href="{{=URL('user/retrieve_password')}}">{{=T('忘记认证密钥')}}</a> + {{pass}} + {{if request.args(0)=='register':}} + <a href="{{=URL('user/login')}}">{{=T('认证')}}</a> + {{pass}} + </div> +</div> + + + +{{block page_js}} +<script> + jQuery("#web2py_user_form input:visible:enabled:first").focus(); +{{if request.args(0)=='register':}} + web2py_validate_entropy(jQuery('#auth_user_password'),100); +{{elif request.args(0)=='change_password':}} + web2py_validate_entropy(jQuery('#no_table_new_password'),100); +{{pass}} +</script> +{{end page_js}} diff --git a/web2py/applications/SP/views/generic.html b/web2py/applications/SP/views/generic.html new file mode 100644 index 0000000..56e0f78 --- /dev/null +++ b/web2py/applications/SP/views/generic.html @@ -0,0 +1,13 @@ +{{extend 'layout.html'}} +{{""" + +You should not modify this file. +It is used as default when a view is not provided for your controllers + +"""}} +<h2>{{=' '.join(x.capitalize() for x in request.function.split('_'))}}</h2> +{{if len(response._vars)==1:}} +{{=BEAUTIFY(response._vars[next(iter(response._vars))])}} +{{elif len(response._vars)>1:}} +{{=BEAUTIFY(response._vars)}} +{{pass}} diff --git a/web2py/applications/SP/views/generic.ics b/web2py/applications/SP/views/generic.ics new file mode 100644 index 0000000..a812bfe --- /dev/null +++ b/web2py/applications/SP/views/generic.ics @@ -0,0 +1,17 @@ +{{ +### +# response._vars contains the dictionary returned by the controller action +# Assuming something like: +# +# db.define_table('event', +# Field('title'), +# Field('start_datetime','datetime'), +# Field('stop_datetime','datetime')) +# events = db(db.event).select() +# +# Aor this to work the action must return something like +# +# dict(events=events, title='title',link=URL('action'),timeshift=0) +# +### +from gluon.serializers import ics}}{{=XML(ics(**response._vars))}} diff --git a/web2py/applications/SP/views/generic.json b/web2py/applications/SP/views/generic.json new file mode 100644 index 0000000..3bd0e1c --- /dev/null +++ b/web2py/applications/SP/views/generic.json @@ -0,0 +1 @@ +{{from gluon.serializers import json}}{{=XML(json(response._vars))}} diff --git a/web2py/applications/SP/views/generic.jsonp b/web2py/applications/SP/views/generic.jsonp new file mode 100644 index 0000000..b46aaf0 --- /dev/null +++ b/web2py/applications/SP/views/generic.jsonp @@ -0,0 +1,23 @@ +{{ +### +# response._vars contains the dictionary returned by the controller action +### + +# security check! This file is an example for a jsonp view. +# it is not safe to use as a generic.jsonp because of security implications. + +if response.view == 'generic.jsonp': + raise HTTP(501,'generic.jsonp disabled for security reasons') + +try: + from gluon.serializers import json + result = "%s(%s)" % (request.vars['callback'], json(response._vars)) + response.write(result, escape=False) + response.headers['Content-Type'] = 'application/jsonp' +except (TypeError, ValueError): + raise HTTP(405, 'JSON serialization error') +except ImportError: + raise HTTP(405, 'JSON not available') +except: + raise HTTP(405, 'JSON error') +}} diff --git a/web2py/applications/SP/views/generic.load b/web2py/applications/SP/views/generic.load new file mode 100644 index 0000000..03f0416 --- /dev/null +++ b/web2py/applications/SP/views/generic.load @@ -0,0 +1,30 @@ +{{''' +# License: Public Domain +# Author: Iceberg at 21cn dot com + +With this generic.load file, you can use same function to serve two purposes. + += regular action +- ajax callback (when called with .load) + +Example modified from http://www.web2py.com/AlterEgo/default/show/252: + +def index(): + return dict( + part1='hello world', + part2=LOAD(url=URL(r=request,f='auxiliary.load'),ajax=True)) + +def auxiliary(): + form=SQLFORM.factory(Field('name')) + if form.accepts(request.vars): + response.flash = 'ok' + return dict(message="Hello %s" % form.vars.name) + return dict(form=form) + +Notice: + +- no need to set response.headers['web2py-response-flash'] +- no need to return a string +even if the function is called via ajax. + +'''}}{{if len(response._vars)==1:}}{{=response._vars[next(iter(response._vars))]}}{{else:}}{{=BEAUTIFY(response._vars)}}{{pass}} \ No newline at end of file diff --git a/web2py/applications/SP/views/generic.map b/web2py/applications/SP/views/generic.map new file mode 100644 index 0000000..773a8f7 --- /dev/null +++ b/web2py/applications/SP/views/generic.map @@ -0,0 +1,69 @@ +{{""" +this is an example of usage of google map +the web2py action should be something like: + +def map(): + return dict( + googlemap_key='...', + center_latitude = 41.878, + center_longitude = -87.629, + scale = 7, + maker = lambda point: A(row.id,_href='...') + points = db(db.point).select() where a points have latitute and longitude + ) + +the corresponding views/defaut/map.html should be something like: + + \{\{extend 'layout.html'\}\} + <center>\{\{include 'generic.map'\}\}</center> + +"""}} + <script src="http://maps.google.com/maps?file=api&v=2&key={{=googlemap_key}}" type="text/javascript"></script> + <script type="text/javascript"> + //<![CDATA[ + function load() { + if (GBrowserIsCompatible()) { + var map = new GMap2(document.getElementById("map")); + map.addControl(new GSmallMapControl()); + map.addControl(new GMapTypeControl()); + map.setCenter(new GLatLng({{=center_latitude}}, + {{=center_longitude}}), {{=scale}}); + // Create a base icon for all of our markers that specifies the + // shadow, icon dimensions, etc. + var baseIcon = new GIcon(); + baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png"; + baseIcon.iconSize = new GSize(20, 34); + baseIcon.shadowSize = new GSize(37, 34); + baseIcon.iconAnchor = new GPoint(9, 34); + baseIcon.infoWindowAnchor = new GPoint(9, 2); + baseIcon.infoShadowAnchor = new GPoint(18, 14); + var blueIcon = new GIcon(); + blueIcon.image = "http://www.google.com/intl/en_us/mapfiles/ms/micons/blue-dot.png"; + blueIcon.shadow = "http://www.google.com/mapfiles/shadow50.png"; + blueIcon.iconSize = new GSize(37, 34); + blueIcon.shadowSize = new GSize(37, 34); + blueIcon.iconAnchor = new GPoint(9, 34); + blueIcon.infoWindowAnchor = new GPoint(9, 2); + blueIcon.infoShadowAnchor = new GPoint(18, 14); + + function createMarker(point, i, message) { + // Set up our GMarkerOptions object + if(i==0) markerOptions = { icon:blueIcon }; + else markerOptions= {} + var marker = new GMarker(point, markerOptions); + GEvent.addListener(marker, "click", function() { + marker.openInfoWindowHtml(message); + }); + return marker; + } + {{for point in points:}}{{if point.latitude and point.longitude:}} + var point = new GLatLng({{=point.latitude}},{{=point.longitude}}); + map.addOverlay(createMarker(point, 0, + '{{=point.get('map_marker',maker(point))}}')); + {{pass}}{{pass}} + } + } + //]]> + </script> + <div id="map" style="width: 800px; height: 500px"></div> + <script>load();</script> diff --git a/web2py/applications/SP/views/generic.pdf b/web2py/applications/SP/views/generic.pdf new file mode 100644 index 0000000..bc257a3 --- /dev/null +++ b/web2py/applications/SP/views/generic.pdf @@ -0,0 +1,11 @@ +{{ +import os +from gluon.contrib.generics import pdf_from_html +filename = '%s/%s.html' % (request.controller,request.function) +if os.path.exists(os.path.join(request.folder,'views',filename)): + html=response.render(filename) +else: + html=BODY(BEAUTIFY(response._vars)) +pass +=pdf_from_html(html) +}} diff --git a/web2py/applications/SP/views/generic.rss b/web2py/applications/SP/views/generic.rss new file mode 100644 index 0000000..82bb4c4 --- /dev/null +++ b/web2py/applications/SP/views/generic.rss @@ -0,0 +1,10 @@ +{{ +### +# response._vars contains the dictionary returned by the controller action +# for this to work the action must return something like +# +# dict(title=...,link=...,description=...,created_on='...',items=...) +# +# items is a list of dictionaries each with title, link, description, pub_date. +### +from gluon.serializers import rss}}{{=XML(rss(response._vars))}} diff --git a/web2py/applications/SP/views/generic.xml b/web2py/applications/SP/views/generic.xml new file mode 100644 index 0000000..234b405 --- /dev/null +++ b/web2py/applications/SP/views/generic.xml @@ -0,0 +1 @@ +{{from gluon.serializers import xml}}{{=XML(xml(response._vars,quote=False))}} diff --git a/web2py/applications/SP/views/layout.html b/web2py/applications/SP/views/layout.html new file mode 100644 index 0000000..a761a52 --- /dev/null +++ b/web2py/applications/SP/views/layout.html @@ -0,0 +1,128 @@ +<!DOCTYPE html> +<!--[if (gt IE 9)|!(IE)]><!--> <html class="no-js" lang="{{=T.accepted_language or 'en'}}"> <!--<![endif]--> + <head> + <meta charset="utf-8"> + <!-- www.phpied.com/conditional-comments-block-downloads/ --> + <!-- Always force latest IE rendering engine + (even in intranet) & Chrome Frame + Remove this if you use the .htaccess --> + <meta http-equiv="X-UA-Compatible" content="IE=edge{{=not request.is_local and ',chrome=1' or ''}}"> + <!-- Mobile Viewport Fix + j.mp/mobileviewport & davidbcalhoun.com/2010/viewport-metatag + device-width: Occupy full width of the screen in its current orientation + initial-scale = 1.0 retains dimensions instead of zooming out if page height > device height + user-scalable = yes allows the user to zoom in --> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>{{=response.title or request.application}} + + + + + + + + + + + + + + {{include 'web2py_ajax.html'}} + {{block head}}{{end}} + + +
{{=response.flash or ''}}
+ + + + + {{block header}} + {{end}} + + +
+ {{include}} + {{=response.toolbar() if response.show_toolbar else ''}} +
+ + {{block footer}} +
+
+
+ +
+ {{=T('Powered by')}} + web2py +
+
+
+
+ {{end}} + + + + {{block page_js}}{{end page_js}} + {{if response.google_analytics_id:}} + + + + {{pass}} + + diff --git a/web2py/applications/SP/views/web2py_ajax.html b/web2py/applications/SP/views/web2py_ajax.html new file mode 100644 index 0000000..28ec0e0 --- /dev/null +++ b/web2py/applications/SP/views/web2py_ajax.html @@ -0,0 +1,18 @@ + +{{ +response.files.insert(0,URL('static','js/jquery.js')) +response.files.insert(1,URL('static','css/calendar.css')) +response.files.insert(2,URL('static','js/calendar.js')) +response.files.insert(3,URL('static','js/web2py.js')) +response.include_meta() +response.include_files() +}} diff --git a/web2py/applications/__init__.py b/web2py/applications/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/web2py/applications/__init__.py @@ -0,0 +1 @@ + diff --git a/web2py/applications/admin/ABOUT b/web2py/applications/admin/ABOUT new file mode 100644 index 0000000..646a97d --- /dev/null +++ b/web2py/applications/admin/ABOUT @@ -0,0 +1,6 @@ +web2py is an open source full-stack framework for agile development +of secure database-driven web-based applications, written and programmable in +Python. + +Created by Massimo Di Pierro + diff --git a/web2py/applications/admin/LICENSE b/web2py/applications/admin/LICENSE new file mode 100644 index 0000000..07224ec --- /dev/null +++ b/web2py/applications/admin/LICENSE @@ -0,0 +1,118 @@ +## Web2py License + +Web2py is Licensed under the LGPL license version 3 +(http://www.gnu.org/licenses/lgpl.html) + +Copyrighted (c) by Massimo Di Pierro (2007-2011) + +### On Commercial Redistribution + +In accordance with LGPL you may: +- redistribute web2py with your apps (including official web2py binary versions) +- release your applications which use official web2py libraries under any license you wish +But you must: +- make clear in the documentation that your application uses web2py +- release any modification of the web2py libraries under the LGPLv3 license + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL +NECESSARY SERVICING, REPAIR OR CORRECTION. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT +HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, +BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL +DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER +PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +(Earlier versions of web2py, 1.0.*-1.90.*, were released under the GPL2 license plus a +commercial exception which, for practical purposes, was very similar to the current LPGLv3) + +### Licenses for third party contributed software + +web2py contains third party software under the gluon/contrib/ folder. +Each file/module in contrib is distributed with web2py under its original license. +Here we list some of them. + +#### gluon.contrib.rss2.py (originally PyRSS2Gen) LICENSE + +This is copyright (c) by Dalke Scientific Software, LLC and released under the +BSD license. See the file LICENSE in the distribution or + for details. + +#### gluon.contrib.markdown (markdown2) LICENSE + +MIT License from from + +#### gluon.contrib.feedparser LICENSE + +Copyright (c) 2002-2005, Mark Pilgrim + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +#### gluon.wsgiserver.py LICENSE (borrowed from cherrypy) + +Copyright (c) 2004, CherryPy Team (team@cherrypy.org) +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 CherryPy Team 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 OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#### gluon.contrib.pam LICENSE + +Copyright (C) 2007-2009 Chris AtLee Licensed under the MIT license + +#### gluon.contrib.shell LICENSE + +Copyright (C) by Google inc. Apache 2.0 Lincense + +#### The javascript licenses are in the code itself + diff --git a/web2py/applications/admin/__init__.py b/web2py/applications/admin/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/web2py/applications/admin/__init__.py @@ -0,0 +1 @@ + diff --git a/web2py/applications/admin/controllers/appadmin.py b/web2py/applications/admin/controllers/appadmin.py new file mode 100644 index 0000000..da050a5 --- /dev/null +++ b/web2py/applications/admin/controllers/appadmin.py @@ -0,0 +1,693 @@ +# -*- coding: utf-8 -*- + +# ########################################################## +# ## make sure administrator is on localhost +# ########################################################### + +import os +import socket +import datetime +import copy +import gluon.contenttype +import gluon.fileutils +from gluon._compat import iteritems + +is_gae = request.env.web2py_runtime_gae or False + +# ## critical --- make a copy of the environment + +global_env = copy.copy(globals()) +global_env['datetime'] = datetime + +http_host = request.env.http_host.split(':')[0] +remote_addr = request.env.remote_addr +try: + hosts = (http_host, socket.gethostname(), + socket.gethostbyname(http_host), + '::1', '127.0.0.1', '::ffff:127.0.0.1') +except: + hosts = (http_host, ) + +if request.is_https: + session.secure() +elif (remote_addr not in hosts) and (remote_addr != "127.0.0.1") and \ + (request.function != 'manage'): + raise HTTP(200, T('appadmin is disabled because insecure channel')) + +if request.function == 'manage': + if not 'auth' in globals() or not request.args: + redirect(URL(request.controller, 'index')) + manager_action = auth.settings.manager_actions.get(request.args(0), None) + if manager_action is None and request.args(0) == 'auth': + manager_action = dict(role=auth.settings.auth_manager_role, + heading=T('Manage Access Control'), + tables=[auth.table_user(), + auth.table_group(), + auth.table_permission()]) + manager_role = manager_action.get('role', None) if manager_action else None + if not (gluon.fileutils.check_credentials(request) or auth.has_membership(manager_role)): + raise HTTP(403, "Not authorized") + menu = False +elif (request.application == 'admin' and not session.authorized) or \ + (request.application != 'admin' and not gluon.fileutils.check_credentials(request)): + redirect(URL('admin', 'default', 'index', + vars=dict(send=URL(args=request.args, vars=request.vars)))) +else: + response.subtitle = T('Database Administration (appadmin)') + menu = True + +ignore_rw = True +response.view = 'appadmin.html' +if menu: + response.menu = [[T('design'), False, URL('admin', 'default', 'design', + args=[request.application])], [T('db'), False, + URL('index')], [T('state'), False, + URL('state')], [T('cache'), False, + URL('ccache')]] + +# ########################################################## +# ## auxiliary functions +# ########################################################### + +if False and request.tickets_db: + from gluon.restricted import TicketStorage + ts = TicketStorage() + ts._get_table(request.tickets_db, ts.tablename, request.application) + +def get_databases(request): + dbs = {} + for (key, value) in global_env.items(): + try: + cond = isinstance(value, GQLDB) + except: + cond = isinstance(value, SQLDB) + if cond: + dbs[key] = value + return dbs + +databases = get_databases(None) + +def eval_in_global_env(text): + exec ('_ret=%s' % text, {}, global_env) + return global_env['_ret'] + + +def get_database(request): + if request.args and request.args[0] in databases: + return eval_in_global_env(request.args[0]) + else: + session.flash = T('invalid request') + redirect(URL('index')) + +def get_table(request): + db = get_database(request) + if len(request.args) > 1 and request.args[1] in db.tables: + return (db, request.args[1]) + else: + session.flash = T('invalid request') + redirect(URL('index')) + + +def get_query(request): + try: + return eval_in_global_env(request.vars.query) + except Exception: + return None + + +def query_by_table_type(tablename, db, request=request): + keyed = hasattr(db[tablename], '_primarykey') + if keyed: + firstkey = db[tablename][db[tablename]._primarykey[0]] + cond = '>0' + if firstkey.type in ['string', 'text']: + cond = '!=""' + qry = '%s.%s.%s%s' % ( + request.args[0], request.args[1], firstkey.name, cond) + else: + qry = '%s.%s.id>0' % tuple(request.args[:2]) + return qry + + +# ########################################################## +# ## list all databases and tables +# ########################################################### +def index(): + return dict(databases=databases) + + +# ########################################################## +# ## insert a new record +# ########################################################### + + +def insert(): + (db, table) = get_table(request) + form = SQLFORM(db[table], ignore_rw=ignore_rw) + if form.accepts(request.vars, session): + response.flash = T('new record inserted') + return dict(form=form, table=db[table]) + + +# ########################################################## +# ## list all records in table and insert new record +# ########################################################### + + +def download(): + import os + db = get_database(request) + return response.download(request, db) + + +def csv(): + import gluon.contenttype + response.headers['Content-Type'] = \ + gluon.contenttype.contenttype('.csv') + db = get_database(request) + query = get_query(request) + if not query: + return None + response.headers['Content-disposition'] = 'attachment; filename=%s_%s.csv'\ + % tuple(request.vars.query.split('.')[:2]) + return str(db(query, ignore_common_filters=True).select()) + + +def import_csv(table, file): + table.import_from_csv_file(file) + + +def select(): + import re + db = get_database(request) + dbname = request.args[0] + try: + is_imap = db._uri.startswith("imap://") + except (KeyError, AttributeError, TypeError): + is_imap = False + regex = re.compile('(?P\w+)\.(?P\w+)=(?P\d+)') + if len(request.args) > 1 and hasattr(db[request.args[1]], '_primarykey'): + regex = re.compile('(?P
\w+)\.(?P\w+)=(?P.+)') + if request.vars.query: + match = regex.match(request.vars.query) + if match: + request.vars.query = '%s.%s.%s==%s' % (request.args[0], + match.group('table'), match.group('field'), + match.group('value')) + else: + request.vars.query = session.last_query + query = get_query(request) + if request.vars.start: + start = int(request.vars.start) + else: + start = 0 + nrows = 0 + + step = 100 + fields = [] + + if is_imap: + step = 3 + + stop = start + step + + table = None + rows = [] + orderby = request.vars.orderby + if orderby: + orderby = dbname + '.' + orderby + if orderby == session.last_orderby: + if orderby[0] == '~': + orderby = orderby[1:] + else: + orderby = '~' + orderby + session.last_orderby = orderby + session.last_query = request.vars.query + form = FORM(TABLE(TR(T('Query:'), '', INPUT(_style='width:400px', + _name='query', _value=request.vars.query or '', _class="form-control", + requires=IS_NOT_EMPTY( + error_message=T("Cannot be empty")))), TR(T('Update:'), + INPUT(_name='update_check', _type='checkbox', + value=False), INPUT(_style='width:400px', + _name='update_fields', _value=request.vars.update_fields + or '', _class="form-control")), TR(T('Delete:'), INPUT(_name='delete_check', + _class='delete', _type='checkbox', value=False), ''), + TR('', '', INPUT(_type='submit', _value=T('submit'), _class="btn btn-primary"))), + _action=URL(r=request, args=request.args)) + + tb = None + if form.accepts(request.vars, formname=None): + regex = re.compile(request.args[0] + '\.(?P
\w+)\..+') + match = regex.match(form.vars.query.strip()) + if match: + table = match.group('table') + try: + nrows = db(query, ignore_common_filters=True).count() + if form.vars.update_check and form.vars.update_fields: + db(query, ignore_common_filters=True).update( + **eval_in_global_env('dict(%s)' % form.vars.update_fields)) + response.flash = T('%s %%{row} updated', nrows) + elif form.vars.delete_check: + db(query, ignore_common_filters=True).delete() + response.flash = T('%s %%{row} deleted', nrows) + nrows = db(query, ignore_common_filters=True).count() + + if is_imap: + fields = [db[table][name] for name in + ("id", "uid", "created", "to", + "sender", "subject")] + if orderby: + rows = db(query, ignore_common_filters=True).select( + *fields, limitby=(start, stop), + orderby=eval_in_global_env(orderby)) + else: + rows = db(query, ignore_common_filters=True).select( + *fields, limitby=(start, stop)) + except Exception as e: + import traceback + tb = traceback.format_exc() + (rows, nrows) = ([], 0) + response.flash = DIV(T('Invalid Query'), PRE(str(e))) + # begin handle upload csv + csv_table = table or request.vars.table + if csv_table: + formcsv = FORM(str(T('or import from csv file')) + " ", + INPUT(_type='file', _name='csvfile'), + INPUT(_type='hidden', _value=csv_table, _name='table'), + INPUT(_type='submit', _value=T('import'), _class="btn btn-primary")) + else: + formcsv = None + if formcsv and formcsv.process().accepted: + try: + import_csv(db[request.vars.table], + request.vars.csvfile.file) + response.flash = T('data uploaded') + except Exception as e: + response.flash = DIV(T('unable to parse csv file'), PRE(str(e))) + # end handle upload csv + + return dict( + form=form, + table=table, + start=start, + stop=stop, + step=step, + nrows=nrows, + rows=rows, + query=request.vars.query, + formcsv=formcsv, + tb=tb + ) + + +# ########################################################## +# ## edit delete one record +# ########################################################### + + +def update(): + (db, table) = get_table(request) + keyed = hasattr(db[table], '_primarykey') + record = None + db[table]._common_filter = None + if keyed: + key = [f for f in request.vars if f in db[table]._primarykey] + if key: + record = db(db[table][key[0]] == request.vars[key[ + 0]]).select().first() + else: + record = db(db[table].id == request.args( + 2)).select().first() + + if not record: + qry = query_by_table_type(table, db) + session.flash = T('record does not exist') + redirect(URL('select', args=request.args[:1], + vars=dict(query=qry))) + + if keyed: + for k in db[table]._primarykey: + db[table][k].writable = False + + form = SQLFORM( + db[table], record, deletable=True, delete_label=T('Check to delete'), + ignore_rw=ignore_rw and not keyed, + linkto=URL('select', + args=request.args[:1]), upload=URL(r=request, + f='download', args=request.args[:1])) + + if form.accepts(request.vars, session): + session.flash = T('done!') + qry = query_by_table_type(table, db) + redirect(URL('select', args=request.args[:1], + vars=dict(query=qry))) + return dict(form=form, table=db[table]) + + +# ########################################################## +# ## get global variables +# ########################################################### + + +def state(): + return dict() + + +def ccache(): + if is_gae: + form = FORM( + P(TAG.BUTTON(T("Clear CACHE?"), _type="submit", _name="yes", _value="yes"))) + else: + cache.ram.initialize() + cache.disk.initialize() + + form = FORM( + P(TAG.BUTTON( + T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")), + P(TAG.BUTTON( + T("Clear RAM"), _type="submit", _name="ram", _value="ram")), + P(TAG.BUTTON( + T("Clear DISK"), _type="submit", _name="disk", _value="disk")), + ) + + if form.accepts(request.vars, session): + session.flash = "" + if is_gae: + if request.vars.yes: + cache.ram.clear() + session.flash += T("Cache Cleared") + else: + clear_ram = False + clear_disk = False + if request.vars.yes: + clear_ram = clear_disk = True + if request.vars.ram: + clear_ram = True + if request.vars.disk: + clear_disk = True + if clear_ram: + cache.ram.clear() + session.flash += T("Ram Cleared") + if clear_disk: + cache.disk.clear() + session.flash += T("Disk Cleared") + redirect(URL(r=request)) + + try: + from pympler.asizeof import asizeof + except ImportError: + asizeof = False + + import shelve + import os + import copy + import time + import math + from pydal.contrib import portalocker + + ram = { + 'entries': 0, + 'bytes': 0, + 'objects': 0, + 'hits': 0, + 'misses': 0, + 'ratio': 0, + 'oldest': time.time(), + 'keys': [] + } + + disk = copy.copy(ram) + total = copy.copy(ram) + disk['keys'] = [] + total['keys'] = [] + + def GetInHMS(seconds): + hours = math.floor(seconds / 3600) + seconds -= hours * 3600 + minutes = math.floor(seconds / 60) + seconds -= minutes * 60 + seconds = math.floor(seconds) + + return (hours, minutes, seconds) + + if is_gae: + gae_stats = cache.ram.client.get_stats() + try: + gae_stats['ratio'] = ((gae_stats['hits'] * 100) / + (gae_stats['hits'] + gae_stats['misses'])) + except ZeroDivisionError: + gae_stats['ratio'] = T("?") + gae_stats['oldest'] = GetInHMS(time.time() - gae_stats['oldest_item_age']) + total.update(gae_stats) + else: + # get ram stats directly from the cache object + ram_stats = cache.ram.stats[request.application] + ram['hits'] = ram_stats['hit_total'] - ram_stats['misses'] + ram['misses'] = ram_stats['misses'] + try: + ram['ratio'] = ram['hits'] * 100 / ram_stats['hit_total'] + except (KeyError, ZeroDivisionError): + ram['ratio'] = 0 + + for key, value in iteritems(cache.ram.storage): + if asizeof: + ram['bytes'] += asizeof(value[1]) + ram['objects'] += 1 + ram['entries'] += 1 + if value[0] < ram['oldest']: + ram['oldest'] = value[0] + ram['keys'].append((key, GetInHMS(time.time() - value[0]))) + + for key in cache.disk.storage: + value = cache.disk.storage[key] + if key == 'web2py_cache_statistics' and isinstance(value[1], dict): + disk['hits'] = value[1]['hit_total'] - value[1]['misses'] + disk['misses'] = value[1]['misses'] + try: + disk['ratio'] = disk['hits'] * 100 / value[1]['hit_total'] + except (KeyError, ZeroDivisionError): + disk['ratio'] = 0 + else: + if asizeof: + disk['bytes'] += asizeof(value[1]) + disk['objects'] += 1 + disk['entries'] += 1 + if value[0] < disk['oldest']: + disk['oldest'] = value[0] + disk['keys'].append((key, GetInHMS(time.time() - value[0]))) + + ram_keys = list(ram) # ['hits', 'objects', 'ratio', 'entries', 'keys', 'oldest', 'bytes', 'misses'] + ram_keys.remove('ratio') + ram_keys.remove('oldest') + for key in ram_keys: + total[key] = ram[key] + disk[key] + + try: + total['ratio'] = total['hits'] * 100 / (total['hits'] + + total['misses']) + except (KeyError, ZeroDivisionError): + total['ratio'] = 0 + + if disk['oldest'] < ram['oldest']: + total['oldest'] = disk['oldest'] + else: + total['oldest'] = ram['oldest'] + + ram['oldest'] = GetInHMS(time.time() - ram['oldest']) + disk['oldest'] = GetInHMS(time.time() - disk['oldest']) + total['oldest'] = GetInHMS(time.time() - total['oldest']) + + def key_table(keys): + return TABLE( + TR(TD(B(T('Key'))), TD(B(T('Time in Cache (h:m:s)')))), + *[TR(TD(k[0]), TD('%02d:%02d:%02d' % k[1])) for k in keys], + **dict(_class='cache-keys', + _style="border-collapse: separate; border-spacing: .5em;")) + + if not is_gae: + ram['keys'] = key_table(ram['keys']) + disk['keys'] = key_table(disk['keys']) + total['keys'] = key_table(total['keys']) + + return dict(form=form, total=total, + ram=ram, disk=disk, object_stats=asizeof != False) + + +def table_template(table): + from gluon.html import TR, TD, TABLE, TAG + + def FONT(*args, **kwargs): + return TAG.font(*args, **kwargs) + + def types(field): + f_type = field.type + if not isinstance(f_type,str): + return ' ' + elif f_type == 'string': + return field.length + elif f_type == 'id': + return B('pk') + elif f_type.startswith('reference') or \ + f_type.startswith('list:reference'): + return B('fk') + else: + return ' ' + + # This is horribe HTML but the only one graphiz understands + rows = [] + cellpadding = 4 + color = "#000000" + bgcolor = "#FFFFFF" + face = "Helvetica" + face_bold = "Helvetica Bold" + border = 0 + + rows.append(TR(TD(FONT(table, _face=face_bold, _color=bgcolor), + _colspan=3, _cellpadding=cellpadding, + _align="center", _bgcolor=color))) + for row in db[table]: + rows.append(TR(TD(FONT(row.name, _color=color, _face=face_bold), + _align="left", _cellpadding=cellpadding, + _border=border), + TD(FONT(row.type, _color=color, _face=face), + _align="left", _cellpadding=cellpadding, + _border=border), + TD(FONT(types(row), _color=color, _face=face), + _align="center", _cellpadding=cellpadding, + _border=border))) + return "< %s >" % TABLE(*rows, **dict(_bgcolor=bgcolor, _border=1, + _cellborder=0, _cellspacing=0) + ).xml() + +def manage(): + tables = manager_action['tables'] + if isinstance(tables[0], str): + db = manager_action.get('db', auth.db) + db = globals()[db] if isinstance(db, str) else db + tables = [db[table] for table in tables] + if request.args(0) == 'auth': + auth.table_user()._plural = T('Users') + auth.table_group()._plural = T('Roles') + auth.table_membership()._plural = T('Memberships') + auth.table_permission()._plural = T('Permissions') + if request.extension != 'load': + return dict(heading=manager_action.get('heading', + T('Manage %(action)s') % dict(action=request.args(0).replace('_', ' ').title())), + tablenames=[table._tablename for table in tables], + labels=[table._plural.title() for table in tables]) + + table = tables[request.args(1, cast=int)] + formname = '%s_grid' % table._tablename + linked_tables = orderby = None + if request.args(0) == 'auth': + auth.table_group()._id.readable = \ + auth.table_membership()._id.readable = \ + auth.table_permission()._id.readable = False + auth.table_membership().user_id.label = T('User') + auth.table_membership().group_id.label = T('Role') + auth.table_permission().group_id.label = T('Role') + auth.table_permission().name.label = T('Permission') + if table == auth.table_user(): + linked_tables = [auth.settings.table_membership_name] + elif table == auth.table_group(): + orderby = 'role' if not request.args(3) or '.group_id' not in request.args(3) else None + elif table == auth.table_permission(): + orderby = 'group_id' + kwargs = dict(user_signature=True, maxtextlength=1000, + orderby=orderby, linked_tables=linked_tables) + smartgrid_args = manager_action.get('smartgrid_args', {}) + kwargs.update(**smartgrid_args.get('DEFAULT', {})) + kwargs.update(**smartgrid_args.get(table._tablename, {})) + grid = SQLFORM.smartgrid(table, args=request.args[:2], formname=formname, **kwargs) + return grid + +def hooks(): + import functools + import inspect + list_op = ['_%s_%s' %(h,m) for h in ['before', 'after'] for m in ['insert','update','delete']] + tables = [] + with_build_it = False + for db_str in sorted(databases): + db = databases[db_str] + for t in db.tables: + method_hooks = [] + for op in list_op: + functions = [] + for f in getattr(db[t], op): + if hasattr(f, '__call__'): + try: + if isinstance(f, (functools.partial)): + f = f.func + filename = inspect.getsourcefile(f) + details = {'funcname':f.__name__, + 'filename':filename[len(request.folder):] if request.folder in filename else None, + 'lineno': inspect.getsourcelines(f)[1]} + if details['filename']: # Built in functions as delete_uploaded_files are not editable + details['url'] = URL(a='admin',c='default',f='edit', args=[request['application'], details['filename']],vars={'lineno':details['lineno']}) + if details['filename'] or with_build_it: + functions.append(details) + # compiled app and windows build don't support code inspection + except: + pass + if len(functions): + method_hooks.append({'name': op, 'functions':functions}) + if len(method_hooks): + tables.append({'name': "%s.%s" % (db_str, t), 'slug': IS_SLUG()("%s.%s" % (db_str,t))[0], 'method_hooks':method_hooks}) + # Render + ul_main = UL(_class='nav nav-list') + for t in tables: + ul_main.append(A(t['name'], _onclick="collapse('a_%s')" % t['slug'])) + ul_t = UL(_class='nav nav-list', _id="a_%s" % t['slug'], _style='display:none') + for op in t['method_hooks']: + ul_t.append(LI(op['name'])) + ul_t.append(UL([LI(A(f['funcname'], _class="editor_filelink", _href=f['url']if 'url' in f else None, **{'_data-lineno':f['lineno']-1})) for f in op['functions']])) + ul_main.append(ul_t) + return ul_main + + +# ########################################################## +# d3 based model visualizations +# ########################################################### + +def d3_graph_model(): + """ See https://www.facebook.com/web2py/posts/145613995589010 from Bruno Rocha + and also the app_admin bg_graph_model function + + Create a list of table dicts, called "nodes" + """ + + nodes = [] + links = [] + + for database in databases: + db = eval_in_global_env(database) + for tablename in db.tables: + fields = [] + for field in db[tablename]: + f_type = field.type + if not isinstance(f_type, str): + disp = ' ' + elif f_type == 'string': + disp = field.length + elif f_type == 'id': + disp = "PK" + elif f_type.startswith('reference') or \ + f_type.startswith('list:reference'): + disp = "FK" + else: + disp = ' ' + fields.append(dict(name=field.name, type=field.type, disp=disp)) + + if isinstance(f_type, str) and ( + f_type.startswith('reference') or + f_type.startswith('list:reference')): + referenced_table = f_type.split()[1].split('.')[0] + + links.append(dict(source=tablename, target = referenced_table)) + + nodes.append(dict(name=tablename, type="table", fields = fields)) + + # d3 v4 allows individual modules to be specified. The complete d3 library is included below. + response.files.append(URL('admin','static','js/d3.min.js')) + response.files.append(URL('admin','static','js/d3_graph.js')) + return dict(databases=databases, nodes=nodes, links=links) diff --git a/web2py/applications/admin/controllers/debug.py b/web2py/applications/admin/controllers/debug.py new file mode 100644 index 0000000..8306beb --- /dev/null +++ b/web2py/applications/admin/controllers/debug.py @@ -0,0 +1,237 @@ +import os +import sys +import gluon.dal +import gluon.html +import gluon.validators +import code +from gluon.debug import communicate, web_debugger, dbg_debugger +from gluon._compat import thread +from gluon.fileutils import open_file +import pydoc + + +if DEMO_MODE or MULTI_USER_MODE: + session.flash = T('disabled in demo mode') + redirect(URL('default', 'site')) + +FE = 10 ** 9 + + +def index(): + app = request.args(0) or 'admin' + reset() + # read buffer + data = communicate() + return dict(app=app, data=data) + + +def callback(): + app = request.args[0] + command = request.vars.statement + session['debug_commands:' + app].append(command) + output = communicate(command) + k = len(session['debug_commands:' + app]) - 1 + return '[%i] %s%s\n' % (k + 1, command, output) + + +def reset(): + app = request.args(0) or 'admin' + session['debug_commands:' + app] = [] + return 'done' + + +# new implementation using dbg + +def interact(): + app = request.args(0) or 'admin' + reset() + + # process all pending messages in the frontend + web_debugger.run() + + # if debugging, filename and lineno should have valid values + filename = web_debugger.filename + lineno = web_debugger.lineno + if filename: + # prevent IOError 2 on some circuntances (EAFP instead of os.access) + try: + lines = open_file(filename, 'r').readlines() + except: + lines = "" + lines = dict([(i + 1, l) for (i, l) in enumerate( + [l.strip("\n").strip("\r") for l in lines])]) + filename = os.path.basename(filename) + else: + lines = {} + + if filename: + web_debugger.set_burst(2) + env = web_debugger.do_environment() + f_locals = env['locals'] + f_globals = {} + for name, value in env['globals'].items(): + if name not in gluon.html.__all__ and \ + name not in gluon.validators.__all__: + f_globals[name] = pydoc.text.repr(value) + else: + f_locals = {} + f_globals = {} + response.headers['refresh'] = "3" + + if web_debugger.exception_info: + response.flash = T('"User Exception" debug mode. ' + 'An error ticket could be issued!') + + return dict(app=app, data="", + filename=web_debugger.filename, lines=lines, lineno=lineno, + f_globals=f_globals, f_locals=f_locals, + exception=web_debugger.exception_info) + + +def step(): + web_debugger.do_step() + redirect(URL("interact")) + + +def next(): + web_debugger.do_next() + redirect(URL("interact")) + + +def cont(): + web_debugger.do_continue() + redirect(URL("interact")) + + +def ret(): + web_debugger.do_return() + redirect(URL("interact")) + + +def stop(): + web_debugger.do_quit() + redirect(URL("interact")) + + +def execute(): + app = request.args[0] + command = request.vars.statement + session['debug_commands:' + app].append(command) + try: + output = web_debugger.do_exec(command) + if output is None: + output = "" + except Exception as e: + output = T("Exception %s") % str(e) + k = len(session['debug_commands:' + app]) - 1 + return '[%i] %s%s\n' % (k + 1, command, output) + + +def breakpoints(): + "Add or remove breakpoints" + + # Get all .py files + files = listdir(apath('', r=request), '.*\.py$') + files = [filename for filename in files + if filename and 'languages' not in filename + and not filename.startswith("admin") + and not filename.startswith("examples")] + + form = SQLFORM.factory( + Field('filename', requires=IS_IN_SET(files), label=T("Filename")), + Field('lineno', 'integer', label=T("Line number"), + requires=IS_NOT_EMPTY()), + Field('temporary', 'boolean', label=T("Temporary"), + comment=T("deleted after first hit")), + Field('condition', 'string', label=T("Condition"), + comment=T("honored only if the expression evaluates to true")), + ) + + if form.accepts(request.vars, session): + filename = os.path.join(request.env['applications_parent'], + 'applications', form.vars.filename) + err = dbg_debugger.do_set_breakpoint(filename, + form.vars.lineno, + form.vars.temporary, + form.vars.condition) + response.flash = T("Set Breakpoint on %s at line %s: %s") % ( + filename, form.vars.lineno, err or T('successful')) + + for item in request.vars: + if item[:7] == 'delete_': + dbg_debugger.do_clear(item[7:]) + + breakpoints = [{'number': bp[0], 'filename': os.path.basename(bp[1]), + 'path': bp[1], 'lineno': bp[2], + 'temporary': bp[3], 'enabled': bp[4], 'hits': bp[5], + 'condition': bp[6]} + for bp in dbg_debugger.do_list_breakpoint()] + + return dict(breakpoints=breakpoints, form=form) + + +def toggle_breakpoint(): + "Set or clear a breakpoint" + + lineno = None + ok = None + try: + filename = os.path.join(request.env['applications_parent'], + 'applications', request.vars.filename) + # normalize path name: replace slashes, references, etc... + filename = os.path.normpath(os.path.normcase(filename)) + if not request.vars.data: + # ace send us the line number! + lineno = int(request.vars.sel_start) + 1 + else: + # editarea send us the offset, manually check the cursor pos + start = 0 + sel_start = int(request.vars.sel_start) + for lineno, line in enumerate(request.vars.data.split("\n")): + if sel_start <= start: + break + start += len(line) + 1 + else: + lineno = None + if lineno is not None: + for bp in dbg_debugger.do_list_breakpoint(): + no, bp_filename, bp_lineno, temporary, enabled, hits, cond = bp + # normalize path name: replace slashes, references, etc... + bp_filename = os.path.normpath(os.path.normcase(bp_filename)) + if filename == bp_filename and lineno == bp_lineno: + err = dbg_debugger.do_clear_breakpoint(filename, lineno) + response.flash = T("Removed Breakpoint on %s at line %s", ( + filename, lineno)) + ok = False + break + else: + err = dbg_debugger.do_set_breakpoint(filename, lineno) + response.flash = T("Set Breakpoint on %s at line %s: %s") % ( + filename, lineno, err or T('successful')) + ok = True + else: + response.flash = T("Unable to determine the line number!") + except Exception as e: + session.flash = str(e) + return response.json({'ok': ok, 'lineno': lineno}) + +def list_breakpoints(): + "Return a list of linenumbers for current breakpoints" + + breakpoints = [] + ok = False + try: + filename = os.path.join(request.env['applications_parent'], + 'applications', request.vars.filename) + # normalize path name: replace slashes, references, etc... + filename = os.path.normpath(os.path.normcase(filename)) + for bp in dbg_debugger.do_list_breakpoint(): + no, bp_filename, bp_lineno, temporary, enabled, hits, cond = bp + # normalize path name: replace slashes, references, etc... + bp_filename = os.path.normpath(os.path.normcase(bp_filename)) + if filename == bp_filename: + breakpoints.append(bp_lineno) + ok = True + except Exception as e: + session.flash = str(e) + return response.json({'ok': ok, 'breakpoints': breakpoints}) diff --git a/web2py/applications/admin/controllers/default.py b/web2py/applications/admin/controllers/default.py new file mode 100644 index 0000000..28198d2 --- /dev/null +++ b/web2py/applications/admin/controllers/default.py @@ -0,0 +1,2003 @@ +# -*- coding: utf-8 -*- + +EXPERIMENTAL_STUFF = True +MAXNFILES = 1000 + +if EXPERIMENTAL_STUFF: + if is_mobile: + response.view = response.view.replace('default/', 'default.mobile/') + response.menu = [] + +import re +from gluon.admin import * +from gluon.fileutils import abspath, read_file, write_file +from gluon.utils import web2py_uuid +from gluon.tools import Config +from gluon.compileapp import find_exposed_functions +from glob import glob +from gluon._compat import iteritems, PY2, pickle, xrange, urlopen, to_bytes, StringIO, to_native +import gluon.rewrite +import shutil +import platform + +try: + import git + if git.__version__ < '0.3.1': + raise ImportError("Your version of git is %s. Upgrade to 0.3.1 or better." % git.__version__) + have_git = True +except ImportError as e: + have_git = False + GIT_MISSING = 'Requires gitpython module, but not installed or incompatible version: %s' % e + +from gluon.languages import (read_possible_languages, read_dict, write_dict, + read_plural_dict, write_plural_dict) + + +if DEMO_MODE and request.function in ['change_password', 'pack', + 'pack_custom', 'pack_plugin', 'upgrade_web2py', 'uninstall', + 'cleanup', 'compile_app', 'remove_compiled_app', 'delete', + 'delete_plugin', 'create_file', 'upload_file', 'update_languages', + 'reload_routes', 'git_push', 'git_pull', 'install_plugin']: + session.flash = T('disabled in demo mode') + redirect(URL('site')) + +if is_gae and request.function in ('edit', 'edit_language', + 'edit_plurals', 'update_languages', 'create_file', 'install_plugin'): + session.flash = T('disabled in GAE mode') + redirect(URL('site')) + +if not is_manager() and request.function in ['change_password', 'upgrade_web2py']: + session.flash = T('disabled in multi user mode') + redirect(URL('site')) + +if FILTER_APPS and request.args(0) and not request.args(0) in FILTER_APPS: + session.flash = T('disabled in demo mode') + redirect(URL('site')) + + +if not session.token: + session.token = web2py_uuid() + + +def count_lines(data): + return len([line for line in data.split('\n') if line.strip() and not line.startswith('#')]) + + +def log_progress(app, mode='EDIT', filename=None, progress=0): + progress_file = os.path.join(apath(app, r=request), 'progress.log') + now = str(request.now)[:19] + if not os.path.exists(progress_file): + safe_open(progress_file, 'w').write('[%s] START\n' % now) + if filename: + safe_open(progress_file, 'a').write( + '[%s] %s %s: %s\n' % (now, mode, filename, progress)) + + +def safe_open(a, b): + if (DEMO_MODE or is_gae) and ('w' in b or 'a' in b): + class tmp: + + def write(self, data): + pass + + def close(self): + pass + return tmp() + if PY2 or 'b' in b: + return open(a, b) + else: + return open(a, b, encoding="utf8") + + +def safe_read(a, b='r'): + safe_file = safe_open(a, b) + try: + return safe_file.read() + finally: + safe_file.close() + + +def safe_write(a, value, b='w'): + safe_file = safe_open(a, b) + try: + safe_file.write(value) + finally: + safe_file.close() + + +def get_app(name=None): + app = name or request.args(0) + if (app and os.path.exists(apath(app, r=request)) and + (not MULTI_USER_MODE or is_manager() or + db(db.app.name == app)(db.app.owner == auth.user.id).count())): + return app + session.flash = T('App does not exist or you are not authorized') + redirect(URL('site')) + + +def index(): + """ Index handler """ + + send = request.vars.send + if DEMO_MODE: + session.authorized = True + session.last_time = t0 + if not send: + send = URL('site') + if session.authorized: + redirect(send) + elif failed_login_count() >= allowed_number_of_attempts: + time.sleep(2 ** allowed_number_of_attempts) + raise HTTP(403) + elif request.vars.password: + if verify_password(request.vars.password[:1024]): + session.authorized = True + login_record(True) + + if CHECK_VERSION: + session.check_version = True + else: + session.check_version = False + + session.last_time = t0 + if isinstance(send, list): # ## why does this happen? + send = str(send[0]) + + redirect(send) + else: + times_denied = login_record(False) + if times_denied >= allowed_number_of_attempts: + response.flash = \ + T('admin disabled because too many invalid login attempts') + elif times_denied == allowed_number_of_attempts - 1: + response.flash = \ + T('You have one more login attempt before you are locked out') + else: + response.flash = T('invalid password.') + return dict(send=send) + + +def check_version(): + """ Checks if web2py is up to date """ + + session.forget() + session._unlock(response) + + new_version, version = check_new_version(request.env.web2py_version, + WEB2PY_VERSION_URL) + + if new_version == -1: + return A(T('Unable to check for upgrades'), _href=WEB2PY_URL) + elif new_version != True: + return A(T('web2py is up to date'), _href=WEB2PY_URL) + elif platform.system().lower() in ('windows', 'win32', 'win64') and os.path.exists("web2py.exe"): + return SPAN('You should upgrade to %s' % version.split('(')[0]) + else: + return sp_button(URL('upgrade_web2py'), T('upgrade now to %s') % version.split('(')[0]) + + +def logout(): + """ Logout handler """ + session.authorized = None + if MULTI_USER_MODE: + redirect(URL('user/logout')) + redirect(URL('index')) + + +def change_password(): + + if session.pam_user: + session.flash = T( + 'PAM authenticated user, cannot change password here') + redirect(URL('site')) + form = SQLFORM.factory(Field('current_admin_password', 'password'), + Field('new_admin_password', + 'password', requires=IS_STRONG()), + Field('new_admin_password_again', 'password'), + _class="span4 well") + if form.accepts(request.vars): + if not verify_password(request.vars.current_admin_password): + form.errors.current_admin_password = T('invalid password') + elif form.vars.new_admin_password != form.vars.new_admin_password_again: + form.errors.new_admin_password_again = T('no match') + else: + path = abspath('parameters_%s.py' % request.env.server_port) + safe_write(path, 'password="%s"' % CRYPT()( + request.vars.new_admin_password)[0]) + session.flash = T('password changed') + redirect(URL('site')) + return dict(form=form) + + +def site(): + """ Site handler """ + + myversion = request.env.web2py_version + + # Shortcut to make the elif statements more legible + file_or_appurl = 'file' in request.vars or 'appurl' in request.vars + + class IS_VALID_APPNAME(object): + + def __call__(self, value): + if not re.compile('^\w+$').match(value): + return (value, T('Invalid application name')) + if not request.vars.overwrite and \ + os.path.exists(os.path.join(apath(r=request), value)): + return (value, T('Application exists already')) + return (value, None) + + is_appname = IS_VALID_APPNAME() + form_create = SQLFORM.factory(Field('name', requires=is_appname), + table_name='appcreate') + form_update = SQLFORM.factory(Field('name', requires=is_appname), + Field('file', 'upload', uploadfield=False), + Field('url'), + Field('overwrite', 'boolean'), + table_name='appupdate') + form_create.process() + form_update.process() + + if DEMO_MODE: + pass + + elif form_create.accepted: + # create a new application + appname = cleanpath(form_create.vars.name) + created, error = app_create(appname, request, info=True) + if created: + if MULTI_USER_MODE: + db.app.insert(name=appname, owner=auth.user.id) + log_progress(appname) + session.flash = T('new application "%s" created', appname) + gluon.rewrite.load() + redirect(URL('design', args=appname)) + else: + session.flash = \ + DIV(T('unable to create application "%s"', appname), + PRE(error)) + redirect(URL(r=request)) + + elif form_update.accepted: + if (form_update.vars.url or '').endswith('.git'): + if not have_git: + session.flash = GIT_MISSING + redirect(URL(r=request)) + target = os.path.join(apath(r=request), form_update.vars.name) + try: + new_repo = git.Repo.clone_from(form_update.vars.url, target) + session.flash = T('new application "%s" imported', + form_update.vars.name) + gluon.rewrite.load() + except git.GitCommandError as err: + session.flash = T('Invalid git repository specified.') + redirect(URL(r=request)) + + elif form_update.vars.url: + # fetch an application via URL or file upload + try: + f = urlopen(form_update.vars.url) + if f.code == 404: + raise Exception("404 file not found") + except Exception as e: + session.flash = \ + DIV(T('Unable to download app because:'), PRE(repr(e))) + redirect(URL(r=request)) + fname = form_update.vars.url + + elif form_update.accepted and form_update.vars.file: + fname = request.vars.file.filename + f = request.vars.file.file + + else: + session.flash = 'No file uploaded and no URL specified' + redirect(URL(r=request)) + + if f: + appname = cleanpath(form_update.vars.name) + installed = app_install(appname, f, + request, fname, + overwrite=form_update.vars.overwrite) + if f and installed: + msg = 'application %(appname)s installed with md5sum: %(digest)s' + if MULTI_USER_MODE: + db.app.insert(name=appname, owner=auth.user.id) + log_progress(appname) + session.flash = T(msg, dict(appname=appname, + digest=md5_hash(installed))) + gluon.rewrite.load() + else: + msg = 'unable to install application "%(appname)s"' + session.flash = T(msg, dict(appname=form_update.vars.name)) + redirect(URL(r=request)) + + regex = re.compile('^\w+$') + + if is_manager(): + apps = [a for a in os.listdir(apath(r=request)) if regex.match(a) and + a != '__pycache__'] + else: + apps = [a.name for a in db(db.app.owner == auth.user_id).select()] + + if FILTER_APPS: + apps = [a for a in apps if a in FILTER_APPS] + + apps = sorted(apps, key=lambda a: a.upper()) + myplatform = platform.python_version() + return dict(app=None, apps=apps, myversion=myversion, myplatform=myplatform, + form_create=form_create, form_update=form_update) + + +def report_progress(app): + import datetime + progress_file = os.path.join(apath(app, r=request), 'progress.log') + regex = re.compile('\[(.*?)\][^\:]+\:\s+(\-?\d+)') + if not os.path.exists(progress_file): + return [] + matches = regex.findall(open(progress_file, 'r').read()) + events, counter = [], 0 + for m in matches: + if not m: + continue + days = -(request.now - datetime.datetime.strptime(m[0], + '%Y-%m-%d %H:%M:%S')).days + counter += int(m[1]) + events.append([days, counter]) + return events + + +def pack(): + app = get_app() + + try: + if len(request.args) == 1: + fname = 'web2py.app.%s.w2p' % app + filename = app_pack(app, request, raise_ex=True) + else: + fname = 'web2py.app.%s.compiled.w2p' % app + filename = app_pack_compiled(app, request, raise_ex=True) + except Exception as e: + filename = None + + if filename: + response.headers['Content-Type'] = 'application/w2p' + disposition = 'attachment; filename=%s' % fname + response.headers['Content-Disposition'] = disposition + return safe_read(filename, 'rb') + else: + session.flash = T('internal error: %s', e) + redirect(URL('site')) + + +def pack_plugin(): + app = get_app() + if len(request.args) == 2: + fname = 'web2py.plugin.%s.w2p' % request.args[1] + filename = plugin_pack(app, request.args[1], request) + if filename: + response.headers['Content-Type'] = 'application/w2p' + disposition = 'attachment; filename=%s' % fname + response.headers['Content-Disposition'] = disposition + return safe_read(filename, 'rb') + else: + session.flash = T('internal error') + redirect(URL('plugin', args=request.args)) + + +def pack_exe(app, base, filenames=None): + import urllib + import zipfile + # Download latest web2py_win and open it with zipfile + download_url = 'http://www.web2py.com/examples/static/web2py_win.zip' + out = StringIO() + out.write(urlopen(download_url).read()) + web2py_win = zipfile.ZipFile(out, mode='a') + # Write routes.py with the application as default + routes = u'# -*- coding: utf-8 -*-\nrouters = dict(BASE=dict(default_application="%s"))' % app + web2py_win.writestr('web2py/routes.py', routes.encode('utf-8')) + # Copy the application into the zipfile + common_root = os.path.dirname(base) + for filename in filenames: + fname = os.path.join(base, filename) + arcname = os.path.join('web2py/applications', app, filename) + web2py_win.write(fname, arcname) + web2py_win.close() + response.headers['Content-Type'] = 'application/zip' + response.headers['Content-Disposition'] = 'attachment; filename=web2py.app.%s.zip' % app + out.seek(0) + return response.stream(out) + + +def pack_custom(): + app = get_app() + base = apath(app, r=request) + + def ignore(fs): + return [f for f in fs if not ( + f[:1] in '#' or f.endswith('~') or f.endswith('.bak'))] + files = {} + for (r, d, f) in os.walk(base): + files[r] = {'folders': ignore(d), 'files': ignore(f)} + + if request.post_vars.file: + valid_set = set(os.path.relpath(os.path.join(r, f), base) for r in files for f in files[r]['files']) + files = request.post_vars.file + files = [files] if not isinstance(files, list) else files + files = [file for file in files if file in valid_set] + + if request.post_vars.doexe is None: + fname = 'web2py.app.%s.w2p' % app + try: + filename = app_pack(app, request, raise_ex=True, filenames=files) + except Exception as e: + filename = None + if filename: + response.headers['Content-Type'] = 'application/w2p' + disposition = 'attachment; filename=%s' % fname + response.headers['Content-Disposition'] = disposition + return safe_read(filename, 'rb') + else: + session.flash = T('internal error: %s', e) + redirect(URL(args=request.args)) + else: + return pack_exe(app, base, files) + + return locals() + + +def upgrade_web2py(): + dialog = FORM.confirm(T('Upgrade'), + {T('Cancel'): URL('site')}) + if dialog.accepted: + (success, error) = upgrade(request) + if success: + session.flash = T('web2py upgraded; please restart it') + else: + session.flash = T('unable to upgrade because "%s"', error) + redirect(URL('site')) + return dict(dialog=dialog) + + +def uninstall(): + app = get_app() + + dialog = FORM.confirm(T('Uninstall'), + {T('Cancel'): URL('site')}) + dialog['_id'] = 'confirm_form' + dialog['_class'] = 'well' + for component in dialog.components: + component['_class'] = 'btn' + + if dialog.accepted: + if MULTI_USER_MODE: + if is_manager() and db(db.app.name == app).delete(): + pass + elif db(db.app.name == app)(db.app.owner == auth.user.id).delete(): + pass + else: + session.flash = T('no permission to uninstall "%s"', app) + redirect(URL('site')) + try: + filename = app_pack(app, request, raise_ex=True) + except: + session.flash = T('unable to uninstall "%s"', app) + else: + if app_uninstall(app, request): + session.flash = T('application "%s" uninstalled', app) + else: + session.flash = T('unable to uninstall "%s"', app) + redirect(URL('site')) + return dict(app=app, dialog=dialog) + + +def cleanup(): + app = get_app() + clean = app_cleanup(app, request) + if not clean: + session.flash = T("some files could not be removed") + else: + session.flash = T('cache, errors and sessions cleaned') + + redirect(URL('site')) + + +def compile_app(): + app = get_app() + c = app_compile(app, request, + skip_failed_views=(request.args(1) == 'skip_failed_views')) + if not c: + session.flash = T('application compiled') + elif isinstance(c, list): + session.flash = DIV(*[T('application compiled'), BR(), BR(), + T('WARNING: The following views could not be compiled:'), BR()] + + [CAT(BR(), view) for view in c] + + [BR(), BR(), T('DO NOT use the "Pack compiled" feature.')]) + else: + session.flash = DIV(T('Cannot compile: there are errors in your app:'), + CODE(c)) + redirect(URL('site')) + + +def remove_compiled_app(): + """ Remove the compiled application """ + app = get_app() + remove_compiled_application(apath(app, r=request)) + session.flash = T('compiled application removed') + redirect(URL('site')) + + +def delete(): + """ Object delete handler """ + app = get_app() + filename = '/'.join(request.args) + sender = request.vars.sender + + if isinstance(sender, list): # ## fix a problem with Vista + sender = sender[0] + + dialog = FORM.confirm(T('Delete'), + {T('Cancel'): URL(sender, anchor=request.vars.id)}) + + if dialog.accepted: + try: + full_path = apath(filename, r=request) + lineno = count_lines(open(full_path, 'r').read()) + os.unlink(full_path) + log_progress(app, 'DELETE', filename, progress=-lineno) + session.flash = T('file "%(filename)s" deleted', + dict(filename=filename)) + except Exception: + session.flash = T('unable to delete file "%(filename)s"', + dict(filename=filename)) + redirect(URL(sender, anchor=request.vars.id2)) + return dict(dialog=dialog, filename=filename) + +def enable(): + if not URL.verify(request, hmac_key=session.hmac_key): raise HTTP(401) + app = get_app() + filename = os.path.join(apath(app, r=request), 'DISABLED') + if is_gae: + return SPAN(T('Not supported'), _style='color:yellow') + elif os.path.exists(filename): + os.unlink(filename) + return SPAN(T('Disable'), _style='color:green') + else: + safe_open(filename, 'wb').write('disabled: True\ntime-disabled: %s' % request.now) + return SPAN(T('Enable'), _style='color:red') + + +def peek(): + """ Visualize object code """ + app = get_app(request.vars.app) + filename = '/'.join(request.args) + if request.vars.app: + path = abspath(filename) + else: + path = apath(filename, r=request) + try: + data = safe_read(path).replace('\r', '') + except IOError: + session.flash = T('file does not exist') + redirect(URL('site')) + + extension = filename[filename.rfind('.') + 1:].lower() + + return dict(app=app, + filename=filename, + data=data, + extension=extension) + + +def test(): + """ Execute controller tests """ + app = get_app() + if len(request.args) > 1: + file = request.args[1] + else: + file = '.*\.py' + + controllers = listdir( + apath('%s/controllers/' % app, r=request), file + '$') + + return dict(app=app, controllers=controllers) + + +def keepalive(): + return '' + + +def search(): + keywords = request.vars.keywords or '' + app = get_app() + + def match(filename, keywords): + filename = os.path.join(apath(app, r=request), filename) + if keywords in read_file(filename, 'rb'): + return True + return False + path = apath(request.args[0], r=request) + files1 = glob(os.path.join(path, '*/*.py')) + files2 = glob(os.path.join(path, '*/*.html')) + files3 = glob(os.path.join(path, '*/*/*.html')) + files = [x[len(path) + 1:].replace( + '\\', '/') for x in files1 + files2 + files3 if match(x, keywords)] + return response.json(dict(files=files, message=T.M('Searching: **%s** %%{file}', len(files)))) + + +def edit(): + """ File edit handler """ + # Load json only if it is ajax edited... + app = get_app(request.vars.app) + app_path = apath(app, r=request) + preferences = {'theme': 'web2py', 'editor': 'default', 'closetag': 'true', 'codefolding': 'false', 'tabwidth': '4', 'indentwithtabs': 'false', 'linenumbers': 'true', 'highlightline': 'true'} + config = Config(os.path.join(request.folder, 'settings.cfg'), + section='editor', default_values={}) + preferences.update(config.read()) + + if not(request.ajax) and not(is_mobile): + # return the scaffolding, the rest will be through ajax requests + response.title = T('Editing %s') % app + return response.render('default/edit.html', dict(app=app, editor_settings=preferences)) + + # show settings tab and save prefernces + if 'settings' in request.vars: + if request.post_vars: # save new preferences + post_vars = request.post_vars.items() + # Since unchecked checkbox are not serialized, we must set them as false by hand to store the correct preference in the settings + post_vars += [(opt, 'false') for opt in preferences if opt not in request.post_vars] + if config.save(post_vars): + response.headers["web2py-component-flash"] = T('Preferences saved correctly') + else: + response.headers["web2py-component-flash"] = T('Preferences saved on session only') + response.headers["web2py-component-command"] = "update_editor(%s);$('a[href=#editor_settings] button.close').click();" % response.json(config.read()) + return + else: + details = {'realfilename': 'settings', 'filename': 'settings', 'id': 'editor_settings', 'force': False} + details['plain_html'] = response.render('default/editor_settings.html', {'editor_settings': preferences}) + return response.json(details) + + """ File edit handler """ + # Load json only if it is ajax edited... + app = get_app(request.vars.app) + filename = '/'.join(request.args) + realfilename = request.args[-1] + if request.vars.app: + path = abspath(filename) + else: + path = apath(filename, r=request) + # Try to discover the file type + if filename[-3:] == '.py': + filetype = 'python' + elif filename[-5:] == '.html': + filetype = 'html' + elif filename[-5:] == '.load': + filetype = 'html' + elif filename[-4:] == '.css': + filetype = 'css' + elif filename[-3:] == '.js': + filetype = 'javascript' + else: + filetype = 'html' + + # ## check if file is not there + if ('revert' in request.vars) and os.path.exists(path + '.bak'): + try: + data = safe_read(path + '.bak') + data1 = safe_read(path) + except IOError: + session.flash = T('Invalid action') + if 'from_ajax' in request.vars: + return response.json({'error': str(T('Invalid action'))}) + else: + redirect(URL('site')) + + safe_write(path, data) + file_hash = md5_hash(data) + saved_on = time.ctime(os.stat(path)[stat.ST_MTIME]) + safe_write(path + '.bak', data1) + response.flash = T('file "%s" of %s restored', (filename, saved_on)) + else: + try: + data = safe_read(path) + except IOError: + session.flash = T('Invalid action') + if 'from_ajax' in request.vars: + return response.json({'error': str(T('Invalid action'))}) + else: + redirect(URL('site')) + + lineno_old = count_lines(data) + file_hash = md5_hash(data) + saved_on = time.ctime(os.stat(path)[stat.ST_MTIME]) + + if request.vars.file_hash and request.vars.file_hash != file_hash: + session.flash = T('file changed on disk') + data = request.vars.data.replace('\r\n', '\n').strip() + '\n' + safe_write(path + '.1', data) + if 'from_ajax' in request.vars: + return response.json({'error': str(T('file changed on disk')), + 'redirect': URL('resolve', + args=request.args)}) + else: + redirect(URL('resolve', args=request.args)) + elif request.vars.data: + safe_write(path + '.bak', data) + data = request.vars.data.replace('\r\n', '\n').strip() + '\n' + safe_write(path, data) + lineno_new = count_lines(data) + log_progress( + app, 'EDIT', filename, progress=lineno_new - lineno_old) + file_hash = md5_hash(data) + saved_on = time.ctime(os.stat(path)[stat.ST_MTIME]) + response.flash = T('file saved on %s', saved_on) + + data_or_revert = (request.vars.data or request.vars.revert) + + # Check compile errors + highlight = None + if filetype == 'python' and request.vars.data: + import _ast + try: + code = request.vars.data.rstrip().replace('\r\n', '\n') + '\n' + compile(code, path, "exec", _ast.PyCF_ONLY_AST) + except Exception as e: + # offset calculation is only used for textarea (start/stop) + start = sum([len(line) + 1 for l, line + in enumerate(request.vars.data.split("\n")) + if l < e.lineno - 1]) + if e.text and e.offset: + offset = e.offset - (len(e.text) - len( + e.text.splitlines()[-1])) + else: + offset = 0 + highlight = {'start': start, 'end': start + + offset + 1, 'lineno': e.lineno, 'offset': offset} + try: + ex_name = e.__class__.__name__ + except: + ex_name = 'unknown exception!' + response.flash = DIV(T('failed to compile file because:'), BR(), + B(ex_name), ' ' + T('at line %s', e.lineno), + offset and ' ' + + T('at char %s', offset) or '', + PRE(repr(e))) + if data_or_revert and request.args[1] == 'modules': + # Lets try to reload the modules + try: + mopath = '.'.join(request.args[2:])[:-3] + exec('import applications.%s.modules.%s' % ( + request.args[0], mopath)) + reload(sys.modules['applications.%s.modules.%s' + % (request.args[0], mopath)]) + except Exception as e: + response.flash = DIV( + T('failed to reload module because:'), PRE(repr(e))) + + edit_controller = None + editviewlinks = None + view_link = None + if filetype == 'html' and len(request.args) >= 3: + cfilename = os.path.join(request.args[0], 'controllers', + request.args[2] + '.py') + if os.path.exists(apath(cfilename, r=request)): + edit_controller = URL('edit', args=[cfilename.replace(os.sep, "/")]) + view = request.args[3].replace('.html', '') + view_link = URL(request.args[0], request.args[2], view) + elif filetype == 'python' and request.args[1] == 'controllers': + # it's a controller file. + # Create links to all of the associated view files. + app = get_app() + viewname = os.path.splitext(request.args[2])[0] + viewpath = os.path.join(app, 'views', viewname) + aviewpath = apath(viewpath, r=request) + viewlist = [] + if os.path.exists(aviewpath): + if os.path.isdir(aviewpath): + viewlist = glob(os.path.join(aviewpath, '*.html')) + elif os.path.exists(aviewpath + '.html'): + viewlist.append(aviewpath + '.html') + if len(viewlist): + editviewlinks = [] + for v in sorted(viewlist): + vf = os.path.split(v)[-1] + vargs = "/".join([viewpath.replace(os.sep, "/"), vf]) + editviewlinks.append(A(vf.split(".")[0], + _class="editor_filelink", + _href=URL('edit', args=[vargs]))) + + if len(request.args) > 2 and request.args[1] == 'controllers': + controller = (request.args[2])[:-3] + functions = find_exposed_functions(data) + functions = functions and sorted(functions) or [] + else: + (controller, functions) = (None, None) + + if 'from_ajax' in request.vars: + return response.json({'file_hash': file_hash, 'saved_on': saved_on, 'functions': functions, 'controller': controller, 'application': request.args[0], 'highlight': highlight}) + else: + file_details = dict(app=request.args[0], + lineno=request.vars.lineno or 1, + editor_settings=preferences, + filename=filename, + realfilename=realfilename, + filetype=filetype, + data=data, + edit_controller=edit_controller, + file_hash=file_hash, + saved_on=saved_on, + controller=controller, + functions=functions, + view_link=view_link, + editviewlinks=editviewlinks, + id=IS_SLUG()(filename)[0], + force=True if (request.vars.restore or + request.vars.revert) else False) + plain_html = response.render('default/edit_js.html', file_details) + file_details['plain_html'] = plain_html + if is_mobile: + return response.render('default.mobile/edit.html', + file_details, editor_settings=preferences) + else: + return response.json(file_details) + + +def todolist(): + """ Returns all TODO of the requested app + """ + app = request.vars.app or '' + app_path = apath('%(app)s' % {'app': app}, r=request) + dirs = ['models', 'controllers', 'modules', 'private'] + + def listfiles(app, dir, regexp='.*\.py$'): + files = sorted(listdir(apath('%(app)s/%(dir)s/' % {'app': app, 'dir': dir}, r=request), regexp)) + files = [x.replace(os.path.sep, '/') for x in files if not x.endswith('.bak')] + return files + + pattern = '#\s*(todo)+\s+(.*)' + regex = re.compile(pattern, re.IGNORECASE) + + output = [] + for d in dirs: + for f in listfiles(app, d): + matches = [] + filename = apath(os.path.join(app, d, f), r=request) + with safe_open(filename, 'r') as f_s: + src = f_s.read() + for m in regex.finditer(src): + start = m.start() + lineno = src.count('\n', 0, start) + 1 + matches.append({'text': m.group(0), 'lineno': lineno}) + if len(matches) != 0: + output.append({'filename': f, 'matches': matches, 'dir': d}) + + return {'todo': output, 'app': app} + + +def editor_sessions(): + config = Config(os.path.join(request.folder, 'settings.cfg'), + section='editor_sessions', default_values={}) + preferences = config.read() + + if request.vars.session_name and request.vars.files: + session_name = request.vars.session_name + files = request.vars.files + preferences.update({session_name: ','.join(files)}) + if config.save(preferences.items()): + response.headers["web2py-component-flash"] = T('Session saved correctly') + else: + response.headers["web2py-component-flash"] = T('Session saved on session only') + + return response.render('default/editor_sessions.html', {'editor_sessions': preferences}) + + +def resolve(): + """ + """ + + filename = '/'.join(request.args) + # ## check if file is not there + path = apath(filename, r=request) + a = safe_read(path).split('\n') + try: + b = safe_read(path + '.1').split('\n') + except IOError: + session.flash = 'Other file, no longer there' + redirect(URL('edit', args=request.args)) + + d = difflib.ndiff(a, b) + + def leading(line): + """ """ + + # TODO: we really need to comment this + z = '' + for (k, c) in enumerate(line): + if c == ' ': + z += ' ' + elif c == ' \t': + z += ' ' + elif k == 0 and c == '?': + pass + else: + break + + return XML(z) + + def getclass(item): + """ Determine item class """ + operators = {' ': 'normal', '+': 'plus', '-': 'minus'} + + return operators[item[0]] + + if request.vars: + c = '\n'.join([item[2:].rstrip() for (i, item) in enumerate(d) if item[0] + == ' ' or 'line%i' % i in request.vars]) + safe_write(path, c) + session.flash = 'files merged' + redirect(URL('edit', args=request.args)) + else: + # Making the short circuit compatible with <= python2.4 + gen_data = lambda index, item: not item[:1] in ['+', '-'] and "" \ + or INPUT(_type='checkbox', + _name='line%i' % index, + value=item[0] == '+') + + diff = TABLE(*[TR(TD(gen_data(i, item)), + TD(item[0]), + TD(leading(item[2:]), + TT(item[2:].rstrip())), + _class=getclass(item)) + for (i, item) in enumerate(d) if item[0] != '?']) + + return dict(diff=diff, filename=filename) + + +def edit_language(): + """ Edit language file """ + app = get_app() + filename = '/'.join(request.args) + response.title = request.args[-1] + strings = read_dict(apath(filename, r=request)) + + if '__corrupted__' in strings: + form = SPAN(strings['__corrupted__'], _class='error') + return dict(filename=filename, form=form) + + keys = sorted(strings.keys(), key=lambda x: to_native(x).lower()) + rows = [] + rows.append(H2(T('Original/Translation'))) + + for key in keys: + name = md5_hash(key) + s = strings[key] + (prefix, sep, key) = key.partition('\x01') + if sep: + prefix = SPAN(prefix + ': ', _class='tm_ftag') + k = key + else: + (k, prefix) = (prefix, '') + + _class = 'untranslated' if k == s else 'translated' + + if len(s) <= 40: + elem = INPUT(_type='text', _name=name, value=s, + _size=70, _class=_class) + else: + elem = TEXTAREA(_name=name, value=s, _cols=70, + _rows=5, _class=_class) + + # Making the short circuit compatible with <= python2.4 + k = (s != k) and k or B(k) + + new_row = DIV(LABEL(prefix, k, _style="font-weight:normal;"), + CAT(elem, '\n', TAG.BUTTON( + T('delete'), + _onclick='return delkey("%s")' % name, + _class='btn')), _id=name, _class='span6 well well-small') + + rows.append(DIV(new_row, _class="row-fluid")) + rows.append(DIV(INPUT(_type='submit', _value=T('update'), _class="btn btn-primary"), _class='controls')) + form = FORM(*rows) + if form.accepts(request.vars, keepvalues=True): + strs = dict() + for key in keys: + name = md5_hash(key) + if form.vars[name] == chr(127): + continue + strs[key] = form.vars[name] + write_dict(apath(filename, r=request), strs) + session.flash = T('file saved on %(time)s', dict(time=time.ctime())) + redirect(URL(r=request, args=request.args)) + return dict(app=request.args[0], filename=filename, form=form) + + +def edit_plurals(): + """ Edit plurals file """ + app = get_app() + filename = '/'.join(request.args) + plurals = read_plural_dict( + apath(filename, r=request)) # plural forms dictionary + nplurals = int(request.vars.nplurals) - 1 # plural forms quantity + xnplurals = xrange(nplurals) + + if '__corrupted__' in plurals: + # show error message and exit + form = SPAN(plurals['__corrupted__'], _class='error') + return dict(filename=filename, form=form) + + keys = sorted(plurals.keys(), lambda x, y: cmp( + unicode(x, 'utf-8').lower(), unicode(y, 'utf-8').lower())) + tab_rows = [] + for key in keys: + name = md5_hash(key) + forms = plurals[key] + + if len(forms) < nplurals: + forms.extend(None for i in xrange(nplurals - len(forms))) + tab_col1 = DIV(CAT(LABEL(T("Singular Form")), B(key, + _class='fake-input'))) + tab_inputs = [SPAN(LABEL(T("Plural Form #%s", n + 1)), INPUT(_type='text', _name=name + '_' + str(n), value=forms[n], _size=20), _class='span6') for n in xnplurals] + tab_col2 = DIV(CAT(*tab_inputs)) + tab_col3 = DIV(CAT(LABEL(XML(' ')), TAG.BUTTON(T('delete'), _onclick='return delkey("%s")' % name, _class='btn'), _class='span6')) + tab_row = DIV(DIV(tab_col1, '\n', tab_col2, '\n', tab_col3, _class='well well-small'), _id=name, _class='row-fluid tab_row') + tab_rows.append(tab_row) + + tab_rows.append(DIV(TAG['button'](T('update'), _type='submit', + _class='btn btn-primary'), + _class='controls')) + tab_container = DIV(*tab_rows, **dict(_class="row-fluid")) + + form = FORM(tab_container) + if form.accepts(request.vars, keepvalues=True): + new_plurals = dict() + for key in keys: + name = md5_hash(key) + if form.vars[name + '_0'] == chr(127): + continue + new_plurals[key] = [form.vars[name + '_' + str(n)] + for n in xnplurals] + write_plural_dict(apath(filename, r=request), new_plurals) + session.flash = T('file saved on %(time)s', dict(time=time.ctime())) + redirect(URL(r=request, args=request.args, vars=dict( + nplurals=request.vars.nplurals))) + return dict(app=request.args[0], filename=filename, form=form) + + +def about(): + """ Read about info """ + app = get_app() + # ## check if file is not there + about = safe_read(apath('%s/ABOUT' % app, r=request)) + license = safe_read(apath('%s/LICENSE' % app, r=request)) + return dict(app=app, about=MARKMIN(about), license=MARKMIN(license), progress=report_progress(app)) + + +def design(): + """ Application design handler """ + app = get_app() + + if not response.flash and app == request.application: + msg = T('ATTENTION: you cannot edit the running application!') + response.flash = msg + + if request.vars and not request.vars.token == session.token: + redirect(URL('logout')) + + if request.vars.pluginfile is not None and not isinstance(request.vars.pluginfile, str): + filename = os.path.basename(request.vars.pluginfile.filename) + if plugin_install(app, request.vars.pluginfile.file, + request, filename): + session.flash = T('new plugin installed') + redirect(URL('design', args=app)) + else: + session.flash = \ + T('unable to install plugin "%s"', filename) + redirect(URL(r=request, args=app)) + elif isinstance(request.vars.pluginfile, str): + session.flash = T('plugin not specified') + redirect(URL(r=request, args=app)) + + # If we have only pyc files it means that + # we cannot design + if os.path.exists(apath('%s/compiled' % app, r=request)): + session.flash = \ + T('application is compiled and cannot be designed') + redirect(URL('site')) + + # Get all models + models = listdir(apath('%s/models/' % app, r=request), '.*\.py$') + models = [x.replace('\\', '/') for x in models] + defines = {} + for m in models: + data = safe_read(apath('%s/models/%s' % (app, m), r=request)) + defines[m] = regex_tables.findall(data) + defines[m].sort() + + # Get all controllers + controllers = sorted( + listdir(apath('%s/controllers/' % app, r=request), '.*\.py$')) + controllers = [x.replace('\\', '/') for x in controllers] + functions = {} + for c in controllers: + data = safe_read(apath('%s/controllers/%s' % (app, c), r=request)) + items = find_exposed_functions(data) + functions[c] = items and sorted(items) or [] + + # Get all views + views = sorted( + listdir(apath('%s/views/' % app, r=request), '[\w/\-]+(\.\w+)+$')) + views = [x.replace('\\', '/') for x in views if not x.endswith('.bak')] + extend = {} + include = {} + for c in views: + data = safe_read(apath('%s/views/%s' % (app, c), r=request)) + items = regex_extend.findall(data) + + if items: + extend[c] = items[0][1] + + items = regex_include.findall(data) + include[c] = [i[1] for i in items] + + # Get all modules + modules = listdir(apath('%s/modules/' % app, r=request), '.*\.py$') + modules = modules = [x.replace('\\', '/') for x in modules] + modules.sort() + + # Get all private files + privates = listdir(apath('%s/private/' % app, r=request), '[^\.#].*') + privates = [x.replace('\\', '/') for x in privates] + privates.sort() + + # Get all static files + statics = listdir(apath('%s/static/' % app, r=request), '[^\.#].*', + maxnum=MAXNFILES) + statics = [x.replace(os.path.sep, '/') for x in statics] + statics.sort() + + # Get all languages + langpath = os.path.join(apath(app, r=request), 'languages') + languages = dict([(lang, info) for lang, info + in iteritems(read_possible_languages(langpath)) + if info[2] != 0]) # info[2] is langfile_mtime: + # get only existed files + + # Get crontab + cronfolder = apath('%s/cron' % app, r=request) + crontab = apath('%s/cron/crontab' % app, r=request) + if not is_gae: + if not os.path.exists(cronfolder): + os.mkdir(cronfolder) + if not os.path.exists(crontab): + safe_write(crontab, '#crontab') + + plugins = [] + + def filter_plugins(items, plugins): + plugins += [item[7:].split('/')[0].split( + '.')[0] for item in items if item.startswith('plugin_')] + plugins[:] = list(set(plugins)) + plugins.sort() + return [item for item in items if not item.startswith('plugin_')] + + return dict(app=app, + models=filter_plugins(models, plugins), + defines=defines, + controllers=filter_plugins(controllers, plugins), + functions=functions, + views=filter_plugins(views, plugins), + modules=filter_plugins(modules, plugins), + extend=extend, + include=include, + privates=filter_plugins(privates, plugins), + statics=filter_plugins(statics, plugins), + languages=languages, + crontab=crontab, + plugins=plugins) + + +def delete_plugin(): + """ Object delete handler """ + app = request.args(0) + plugin = request.args(1) + plugin_name = 'plugin_' + plugin + + dialog = FORM.confirm( + T('Delete'), + {T('Cancel'): URL('design', args=app)}) + + if dialog.accepted: + try: + for folder in ['models', 'views', 'controllers', 'static', 'modules', 'private']: + path = os.path.join(apath(app, r=request), folder) + for item in os.listdir(path): + if item.rsplit('.', 1)[0] == plugin_name: + filename = os.path.join(path, item) + if os.path.isdir(filename): + shutil.rmtree(filename) + else: + os.unlink(filename) + session.flash = T('plugin "%(plugin)s" deleted', + dict(plugin=plugin)) + except Exception: + session.flash = T('unable to delete file plugin "%(plugin)s"', + dict(plugin=plugin)) + redirect(URL('design', args=request.args(0), anchor=request.vars.id2)) + return dict(dialog=dialog, plugin=plugin) + + +def plugin(): + """ Application design handler """ + app = get_app() + plugin = request.args(1) + + if not response.flash and app == request.application: + msg = T('ATTENTION: you cannot edit the running application!') + response.flash = msg + + # If we have only pyc files it means that + # we cannot design + if os.path.exists(apath('%s/compiled' % app, r=request)): + session.flash = \ + T('application is compiled and cannot be designed') + redirect(URL('site')) + + # Get all models + models = listdir(apath('%s/models/' % app, r=request), '.*\.py$') + models = [x.replace('\\', '/') for x in models] + defines = {} + for m in models: + data = safe_read(apath('%s/models/%s' % (app, m), r=request)) + defines[m] = regex_tables.findall(data) + defines[m].sort() + + # Get all controllers + controllers = sorted( + listdir(apath('%s/controllers/' % app, r=request), '.*\.py$')) + controllers = [x.replace('\\', '/') for x in controllers] + functions = {} + for c in controllers: + data = safe_read(apath('%s/controllers/%s' % (app, c), r=request)) + items = find_exposed_functions(data) + functions[c] = items and sorted(items) or [] + + # Get all views + views = sorted( + listdir(apath('%s/views/' % app, r=request), '[\w/\-]+\.\w+$')) + views = [x.replace('\\', '/') for x in views] + extend = {} + include = {} + for c in views: + data = safe_read(apath('%s/views/%s' % (app, c), r=request)) + items = regex_extend.findall(data) + if items: + extend[c] = items[0][1] + + items = regex_include.findall(data) + include[c] = [i[1] for i in items] + + # Get all modules + modules = listdir(apath('%s/modules/' % app, r=request), '.*\.py$') + modules = modules = [x.replace('\\', '/') for x in modules] + modules.sort() + + # Get all private files + privates = listdir(apath('%s/private/' % app, r=request), '[^\.#].*') + privates = [x.replace('\\', '/') for x in privates] + privates.sort() + + # Get all static files + statics = listdir(apath('%s/static/' % app, r=request), '[^\.#].*', + maxnum=MAXNFILES) + statics = [x.replace(os.path.sep, '/') for x in statics] + statics.sort() + + # Get all languages + languages = sorted([lang + '.py' for lang, info in + iteritems(T.get_possible_languages_info()) + if info[2] != 0]) # info[2] is langfile_mtime: + # get only existed files + + # Get crontab + crontab = apath('%s/cron/crontab' % app, r=request) + if not os.path.exists(crontab): + safe_write(crontab, '#crontab') + + def filter_plugins(items): + regex = re.compile('^plugin_' + plugin + '(/.*|\..*)?$') + return [item for item in items if item and regex.match(item)] + + return dict(app=app, + models=filter_plugins(models), + defines=defines, + controllers=filter_plugins(controllers), + functions=functions, + views=filter_plugins(views), + modules=filter_plugins(modules), + extend=extend, + include=include, + privates=filter_plugins(privates), + statics=filter_plugins(statics), + languages=languages, + crontab=crontab) + + +def create_file(): + """ Create files handler """ + if request.vars and not request.vars.token == session.token: + redirect(URL('logout')) + try: + anchor = '#' + request.vars.id if request.vars.id else '' + if request.vars.app: + app = get_app(request.vars.app) + path = abspath(request.vars.location) + else: + if request.vars.dir: + request.vars.location += request.vars.dir + '/' + app = get_app(name=request.vars.location.split('/')[0]) + path = apath(request.vars.location, r=request) + filename = re.sub('[^\w./-]+', '_', request.vars.filename) + if path[-7:] == '/rules/': + # Handle plural rules files + if len(filename) == 0: + raise SyntaxError + if not filename[-3:] == '.py': + filename += '.py' + lang = re.match('^plural_rules-(.*)\.py$', filename).group(1) + langinfo = read_possible_languages(apath(app, r=request))[lang] + text = dedent(""" + #!/usr/bin/env python + # -*- coding: utf-8 -*- + # Plural-Forms for %(lang)s (%(langname)s) + + nplurals=2 # for example, English language has 2 forms: + # 1 singular and 1 plural + + # Determine plural_id for number *n* as sequence of positive + # integers: 0,1,... + # NOTE! For singular form ALWAYS return plural_id = 0 + get_plural_id = lambda n: int(n != 1) + + # Construct and return plural form of *word* using + # *plural_id* (which ALWAYS>0). This function will be executed + # for words (or phrases) not found in plural_dict dictionary. + # By default this function simply returns word in singular: + construct_plural_form = lambda word, plural_id: word + """)[1:] % dict(lang=langinfo[0], langname=langinfo[1]) + + elif path[-11:] == '/languages/': + # Handle language files + if len(filename) == 0: + raise SyntaxError + if not filename[-3:] == '.py': + filename += '.py' + path = os.path.join(apath(app, r=request), 'languages', filename) + if not os.path.exists(path): + safe_write(path, '') + # create language xx[-yy].py file: + findT(apath(app, r=request), filename[:-3]) + session.flash = T('language file "%(filename)s" created/updated', + dict(filename=filename)) + redirect(request.vars.sender + anchor) + + elif path[-8:] == '/models/': + # Handle python models + if not filename[-3:] == '.py': + filename += '.py' + + if len(filename) == 3: + raise SyntaxError + + text = '# -*- coding: utf-8 -*-\n' + + elif path[-13:] == '/controllers/': + # Handle python controllers + if not filename[-3:] == '.py': + filename += '.py' + + if len(filename) == 3: + raise SyntaxError + + text = '# -*- coding: utf-8 -*-\n# %s\ndef index(): return dict(message="hello from %s")' + text = text % (T('try something like'), filename) + + elif path[-7:] == '/views/': + if request.vars.plugin and not filename.startswith('plugin_%s/' % request.vars.plugin): + filename = 'plugin_%s/%s' % (request.vars.plugin, filename) + # Handle template (html) views + if filename.find('.') < 0: + filename += '.html' + extension = filename.split('.')[-1].lower() + + if len(filename) == 5: + raise SyntaxError + + msg = T( + 'This is the %(filename)s template', dict(filename=filename)) + if extension == 'html': + text = dedent(""" + {{extend 'layout.html'}} +

%s

+ {{=BEAUTIFY(response._vars)}}""" % msg)[1:] + else: + generic = os.path.join(path, 'generic.' + extension) + if os.path.exists(generic): + text = read_file(generic) + else: + text = '' + + elif path[-9:] == '/modules/': + if request.vars.plugin and not filename.startswith('plugin_%s/' % request.vars.plugin): + filename = 'plugin_%s/%s' % (request.vars.plugin, filename) + # Handle python module files + if not filename[-3:] == '.py': + filename += '.py' + + if len(filename) == 3: + raise SyntaxError + + text = dedent(""" + #!/usr/bin/env python + # -*- coding: utf-8 -*- + from gluon import *\n""")[1:] + + elif (path[-8:] == '/static/') or (path[-9:] == '/private/'): + if (request.vars.plugin and + not filename.startswith('plugin_%s/' % request.vars.plugin)): + filename = 'plugin_%s/%s' % (request.vars.plugin, filename) + text = '' + + else: + redirect(request.vars.sender + anchor) + + full_filename = os.path.join(path, filename) + dirpath = os.path.dirname(full_filename) + + if not os.path.exists(dirpath): + os.makedirs(dirpath) + + if os.path.exists(full_filename): + raise SyntaxError + + safe_write(full_filename, text) + log_progress(app, 'CREATE', filename) + if request.vars.dir: + result = T('file "%(filename)s" created', + dict(filename=full_filename[len(path):])) + else: + session.flash = T('file "%(filename)s" created', + dict(filename=full_filename[len(path):])) + vars = {} + if request.vars.id: + vars['id'] = request.vars.id + if request.vars.app: + vars['app'] = request.vars.app + redirect(URL('edit', + args=[os.path.join(request.vars.location, filename)], vars=vars)) + + except Exception as e: + if not isinstance(e, HTTP): + session.flash = T('cannot create file') + + if request.vars.dir: + response.flash = result + response.headers['web2py-component-content'] = 'append' + response.headers['web2py-component-command'] = "%s %s %s" % ( + "$.web2py.invalidate('#files_menu');", + "load_file('%s');" % URL('edit', args=[app, request.vars.dir, filename]), + "$.web2py.enableElement($('#form form').find($.web2py.formInputClickSelector));") + return '' + else: + redirect(request.vars.sender + anchor) + + +def listfiles(app, dir, regexp='.*\.py$'): + files = sorted( + listdir(apath('%(app)s/%(dir)s/' % {'app': app, 'dir': dir}, r=request), regexp)) + files = [x.replace('\\', '/') for x in files if not x.endswith('.bak')] + return files + + +def editfile(path, file, vars={}, app=None): + args = (path, file) if 'app' in vars else (app, path, file) + url = URL('edit', args=args, vars=vars) + return A(file, _class='editor_filelink', _href=url, _style='word-wrap: nowrap;') + + +def files_menu(): + app = request.vars.app or 'welcome' + dirs = [{'name': 'models', 'reg': '.*\.py$'}, + {'name': 'controllers', 'reg': '.*\.py$'}, + {'name': 'views', 'reg': '[\w/\-]+(\.\w+)+$'}, + {'name': 'modules', 'reg': '.*\.py$'}, + {'name': 'static', 'reg': '[^\.#].*'}, + {'name': 'private', 'reg': '.*\.py$'}] + result_files = [] + for dir in dirs: + result_files.append(TAG[''](LI(dir['name'], _class="nav-header component", _onclick="collapse('" + dir['name'] + "_files');"), + LI(UL(*[LI(editfile(dir['name'], f, dict(id=dir['name'] + f.replace('.', '__')), app), _style="overflow:hidden", _id=dir['name'] + "__" + f.replace('.', '__')) + for f in listfiles(app, dir['name'], regexp=dir['reg'])], + _class="nav nav-list small-font"), + _id=dir['name'] + '_files', _style="display: none;"))) + return dict(result_files=result_files) + + +def upload_file(): + """ File uploading handler """ + if request.vars and not request.vars.token == session.token: + redirect(URL('logout')) + try: + filename = None + app = get_app(name=request.vars.location.split('/')[0]) + path = apath(request.vars.location, r=request) + + if request.vars.filename: + filename = re.sub('[^\w\./]+', '_', request.vars.filename) + else: + filename = os.path.split(request.vars.file.filename)[-1] + + if path[-8:] == '/models/' and not filename[-3:] == '.py': + filename += '.py' + + if path[-9:] == '/modules/' and not filename[-3:] == '.py': + filename += '.py' + + if path[-13:] == '/controllers/' and not filename[-3:] == '.py': + filename += '.py' + + if path[-7:] == '/views/' and not filename[-5:] == '.html': + filename += '.html' + + if path[-11:] == '/languages/' and not filename[-3:] == '.py': + filename += '.py' + + filename = os.path.join(path, filename) + dirpath = os.path.dirname(filename) + + if not os.path.exists(dirpath): + os.makedirs(dirpath) + + data = request.vars.file.file.read() + lineno = count_lines(data) + safe_write(filename, data, 'wb') + log_progress(app, 'UPLOAD', filename, lineno) + session.flash = T('file "%(filename)s" uploaded', + dict(filename=filename[len(path):])) + except Exception: + if filename: + d = dict(filename=filename[len(path):]) + else: + d = dict(filename='unknown') + session.flash = T('cannot upload file "%(filename)s"', d) + + redirect(request.vars.sender) + + +def errors(): + """ Error handler """ + import operator + import os + import hashlib + + app = get_app() + if is_gae: + method = 'dbold' if ('old' in + (request.args(1) or '')) else 'dbnew' + else: + method = request.args(1) or 'new' + db_ready = {} + db_ready['status'] = get_ticket_storage(app) + db_ready['errmessage'] = T( + "No ticket_storage.txt found under /private folder") + db_ready['errlink'] = "http://web2py.com/books/default/chapter/29/13#Collecting-tickets" + + if method == 'new': + errors_path = apath('%s/errors' % app, r=request) + + delete_hashes = [] + for item in request.vars: + if item[:7] == 'delete_': + delete_hashes.append(item[7:]) + + hash2error = dict() + + for fn in listdir(errors_path, '^[a-fA-F0-9.\-]+$'): + fullpath = os.path.join(errors_path, fn) + if not os.path.isfile(fullpath): + continue + try: + fullpath_file = safe_open(fullpath, 'rb') + try: + error = pickle.load(fullpath_file) + finally: + fullpath_file.close() + except IOError: + continue + except EOFError: + continue + + hash = hashlib.md5(to_bytes(error['traceback'])).hexdigest() + + if hash in delete_hashes: + os.unlink(fullpath) + else: + try: + hash2error[hash]['count'] += 1 + except KeyError: + error_lines = error['traceback'].split("\n") + last_line = error_lines[-2] if len(error_lines) > 1 else 'unknown' + error_causer = os.path.split(error['layer'])[1] + hash2error[hash] = dict(count=1, pickel=error, + causer=error_causer, + last_line=last_line, + hash=hash, ticket=fn) + + decorated = [(x['count'], x) for x in hash2error.values()] + decorated.sort(key=operator.itemgetter(0), reverse=True) + + return dict(errors=[x[1] for x in decorated], app=app, method=method, db_ready=db_ready) + + elif method == 'dbnew': + errors_path = apath('%s/errors' % app, r=request) + tk_db, tk_table = get_ticket_storage(app) + + delete_hashes = [] + for item in request.vars: + if item[:7] == 'delete_': + delete_hashes.append(item[7:]) + + hash2error = dict() + + for fn in tk_db(tk_table.id > 0).select(): + try: + error = pickle.loads(fn.ticket_data) + hash = hashlib.md5(error['traceback']).hexdigest() + + if hash in delete_hashes: + tk_db(tk_table.id == fn.id).delete() + tk_db.commit() + else: + try: + hash2error[hash]['count'] += 1 + except KeyError: + error_lines = error['traceback'].split("\n") + last_line = error_lines[-2] + error_causer = os.path.split(error['layer'])[1] + hash2error[hash] = dict(count=1, + pickel=error, causer=error_causer, + last_line=last_line, hash=hash, + ticket=fn.ticket_id) + except AttributeError as e: + tk_db(tk_table.id == fn.id).delete() + tk_db.commit() + + decorated = [(x['count'], x) for x in hash2error.values()] + decorated.sort(key=operator.itemgetter(0), reverse=True) + return dict(errors=[x[1] for x in decorated], app=app, + method=method, db_ready=db_ready) + + elif method == 'dbold': + tk_db, tk_table = get_ticket_storage(app) + for item in request.vars: + if item[:7] == 'delete_': + tk_db(tk_table.ticket_id == item[7:]).delete() + tk_db.commit() + tickets_ = tk_db(tk_table.id > 0).select(tk_table.ticket_id, + tk_table.created_datetime, + orderby=~tk_table.created_datetime) + tickets = [row.ticket_id for row in tickets_] + times = dict([(row.ticket_id, row.created_datetime) for + row in tickets_]) + return dict(app=app, tickets=tickets, method=method, + times=times, db_ready=db_ready) + + else: + for item in request.vars: + # delete_all rows doesn't contain any ticket + # Remove anything else as requested + if item[:7] == 'delete_' and (not item == "delete_all}"): + os.unlink(apath('%s/errors/%s' % (app, item[7:]), r=request)) + func = lambda p: os.stat(apath('%s/errors/%s' % + (app, p), r=request)).st_mtime + tickets = sorted( + listdir(apath('%s/errors/' % app, r=request), '^\w.*'), + key=func, + reverse=True) + + return dict(app=app, tickets=tickets, method=method, db_ready=db_ready) + + +def get_ticket_storage(app): + private_folder = apath('%s/private' % app, r=request) + ticket_file = os.path.join(private_folder, 'ticket_storage.txt') + if os.path.exists(ticket_file): + db_string = safe_open(ticket_file).read() + db_string = db_string.strip().replace('\r', '').replace('\n', '') + elif is_gae: + # use Datastore as fallback if there is no ticket_file + db_string = "google:datastore" + else: + return False + tickets_table = 'web2py_ticket' + tablename = tickets_table + '_' + app + db_path = apath('%s/databases' % app, r=request) + ticketsdb = DAL(db_string, folder=db_path, auto_import=True) + if not ticketsdb.get(tablename): + table = ticketsdb.define_table( + tablename, + Field('ticket_id', length=100), + Field('ticket_data', 'text'), + Field('created_datetime', 'datetime'), + ) + return ticketsdb, ticketsdb.get(tablename) + + +def make_link(path): + """ Create a link from a path """ + tryFile = path.replace('\\', '/') + + if os.path.isabs(tryFile) and os.path.isfile(tryFile): + (folder, filename) = os.path.split(tryFile) + (base, ext) = os.path.splitext(filename) + app = get_app() + + editable = {'controllers': '.py', 'models': '.py', 'views': '.html'} + for key in editable.keys(): + check_extension = folder.endswith("%s/%s" % (app, key)) + if ext.lower() == editable[key] and check_extension: + return to_native(A('"' + tryFile + '"', + _href=URL(r=request, + f='edit/%s/%s/%s' % (app, key, filename))).xml()) + return '' + + +def make_links(traceback): + """ Make links using the given traceback """ + + lwords = traceback.split('"') + + # Making the short circuit compatible with <= python2.4 + result = (len(lwords) != 0) and lwords[0] or '' + + i = 1 + + while i < len(lwords): + link = make_link(lwords[i]) + + if link == '': + result += '"' + lwords[i] + else: + result += link + + if i + 1 < len(lwords): + result += lwords[i + 1] + i = i + 1 + + i = i + 1 + + return result + + +class TRACEBACK(object): + """ Generate the traceback """ + + def __init__(self, text): + """ TRACEBACK constructor """ + + self.s = make_links(CODE(text).xml()) + + def xml(self): + """ Returns the xml """ + + return self.s + + +def ticket(): + """ Ticket handler """ + + if len(request.args) != 2: + session.flash = T('invalid ticket') + redirect(URL('site')) + + app = get_app() + myversion = request.env.web2py_version + ticket = request.args[1] + e = RestrictedError() + e.load(request, app, ticket) + + return dict(app=app, + ticket=ticket, + output=e.output, + traceback=(e.traceback and TRACEBACK(e.traceback)), + snapshot=e.snapshot, + code=e.code, + layer=e.layer, + myversion=myversion) + + +def ticketdb(): + """ Ticket handler """ + + if len(request.args) != 2: + session.flash = T('invalid ticket') + redirect(URL('site')) + + app = get_app() + myversion = request.env.web2py_version + ticket = request.args[1] + e = RestrictedError() + request.tickets_db = get_ticket_storage(app)[0] + e.load(request, app, ticket) + response.view = 'default/ticket.html' + return dict(app=app, + ticket=ticket, + output=e.output, + traceback=(e.traceback and TRACEBACK(e.traceback)), + snapshot=e.snapshot, + code=e.code, + layer=e.layer, + myversion=myversion) + + +def error(): + """ Generate a ticket (for testing) """ + raise RuntimeError('admin ticket generator at your service') + + +def update_languages(): + """ Update available languages """ + + app = get_app() + update_all_languages(apath(app, r=request)) + session.flash = T('Language files (static strings) updated') + redirect(URL('design', args=app, anchor='languages')) + + +def user(): + if MULTI_USER_MODE: + if not db(db.auth_user).count(): + auth.settings.registration_requires_approval = False + return dict(form=auth()) + else: + return dict(form=T("Disabled")) + + +def reload_routes(): + """ Reload routes.py """ + gluon.rewrite.load() + redirect(URL('site')) + + +def manage_students(): + if not (MULTI_USER_MODE and is_manager()): + session.flash = T('Not Authorized') + redirect(URL('site')) + db.auth_user.registration_key.writable = True + grid = SQLFORM.grid(db.auth_user) + return locals() + + +def bulk_register(): + if not (MULTI_USER_MODE and is_manager()): + session.flash = T('Not Authorized') + redirect(URL('site')) + form = SQLFORM.factory(Field('emails', 'text')) + if form.process().accepted: + emails = [x.strip() for x in form.vars.emails.split('\n') if x.strip()] + n = 0 + for email in emails: + if not db.auth_user(email=email): + n += db.auth_user.insert(email=email) and 1 or 0 + session.flash = T('%s students registered', n) + redirect(URL('site')) + return locals() + +# Begin experimental stuff need fixes: +# 1) should run in its own process - cannot os.chdir +# 2) should not prompt user at console +# 3) should give option to force commit and not reuqire manual merge + + +def git_pull(): + """ Git Pull handler """ + app = get_app() + if not have_git: + session.flash = GIT_MISSING + redirect(URL('site')) + dialog = FORM.confirm(T('Pull'), + {T('Cancel'): URL('site')}) + if dialog.accepted: + try: + repo = git.Repo(os.path.join(apath(r=request), app)) + origin = repo.remotes.origin + origin.fetch() + origin.pull() + session.flash = T("Application updated via git pull") + redirect(URL('site')) + + except git.CheckoutError: + session.flash = T("Pull failed, certain files could not be checked out. Check logs for details.") + redirect(URL('site')) + except git.UnmergedEntriesError: + session.flash = T("Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.") + redirect(URL('site')) + except git.GitCommandError: + session.flash = T( + "Pull failed, git exited abnormally. See logs for details.") + redirect(URL('site')) + except AssertionError: + session.flash = T("Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.") + redirect(URL('site')) + elif 'cancel' in request.vars: + redirect(URL('site')) + return dict(app=app, dialog=dialog) + + +def git_push(): + """ Git Push handler """ + app = get_app() + if not have_git: + session.flash = GIT_MISSING + redirect(URL('site')) + form = SQLFORM.factory(Field('changelog', requires=IS_NOT_EMPTY())) + form.element('input[type=submit]')['_value'] = T('Push') + form.add_button(T('Cancel'), URL('site')) + form.process() + if form.accepted: + try: + repo = git.Repo(os.path.join(apath(r=request), app)) + index = repo.index + index.add([apath(r=request) + app + '/*']) + new_commit = index.commit(form.vars.changelog) + origin = repo.remotes.origin + origin.push() + session.flash = T( + "Git repo updated with latest application changes.") + redirect(URL('site')) + except git.UnmergedEntriesError: + session.flash = T("Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.") + redirect(URL('site')) + return dict(app=app, form=form) + + +def plugins(): + app = request.args(0) + from gluon.serializers import loads_json + if not session.plugins: + try: + rawlist = urlopen("http://www.web2pyslices.com/" + + "public/api.json/action/list/content/Package?package" + + "_type=plugin&search_index=false").read() + session.plugins = loads_json(rawlist) + except: + response.flash = T('Unable to download the list of plugins') + session.plugins = [] + return dict(plugins=session.plugins["results"], app=request.args(0)) + + +def install_plugin(): + app = request.args(0) + source = request.vars.source + plugin = request.vars.plugin + if not (source and app): + raise HTTP(500, T("Invalid request")) + # make sure no XSS attacks in source + if not source.lower().split('://')[0] in ('http','https'): + raise HTTP(500, T("Invalid request")) + form = SQLFORM.factory() + result = None + if form.process().accepted: + # get w2p plugin + if "web2py.plugin." in source: + filename = "web2py.plugin.%s.w2p" % \ + source.split("web2py.plugin.")[-1].split(".w2p")[0] + else: + filename = "web2py.plugin.%s.w2p" % cleanpath(plugin) + if plugin_install(app, urlopen(source), + request, filename): + session.flash = T('New plugin installed: %s', filename) + else: + session.flash = \ + T('unable to install plugin "%s"', filename) + redirect(URL(f="plugins", args=[app, ])) + return dict(form=form, app=app, plugin=plugin, source=source) diff --git a/web2py/applications/admin/controllers/gae.py b/web2py/applications/admin/controllers/gae.py new file mode 100644 index 0000000..96dfc36 --- /dev/null +++ b/web2py/applications/admin/controllers/gae.py @@ -0,0 +1,105 @@ +### this works on linux only + +import re +try: + import fcntl + import subprocess + import signal + import os + import shutil + from gluon.fileutils import read_file, write_file +except: + session.flash = 'sorry, only on Unix systems' + redirect(URL(request.application, 'default', 'site')) + +if MULTI_USER_MODE and not is_manager(): + session.flash = 'Not Authorized' + redirect(URL('default', 'site')) + +from gluon.settings import settings +if not settings.is_source: + session.flash = 'Requires running web2py from source' + redirect(URL(request.application, 'default', 'site')) + +forever = 10 ** 8 + + +def kill(): + p = cache.ram('gae_upload', lambda: None, forever) + if not p or p.poll() is not None: + return 'oops' + os.kill(p.pid, signal.SIGKILL) + cache.ram('gae_upload', lambda: None, -1) + + +class EXISTS(object): + def __init__(self, error_message='file not found'): + self.error_message = error_message + + def __call__(self, value): + if os.path.exists(value): + return (value, None) + return (value, self.error_message) + + +def deploy(): + regex = re.compile('^\w+$') + apps = sorted( + file for file in os.listdir(apath(r=request)) if regex.match(file)) + form = SQLFORM.factory( + Field('appcfg', default=GAE_APPCFG, label=T('Path to appcfg.py'), + requires=EXISTS(error_message=T('file not found'))), + Field('google_application_id', requires=IS_MATCH( + '[\w\-]+'), label=T('Google Application Id')), + Field('applications', 'list:string', + requires=IS_IN_SET(apps, multiple=True), + label=T('web2py apps to deploy')), + Field('email', requires=IS_EMAIL(), label=T('GAE Email')), + Field('password', 'password', requires=IS_NOT_EMPTY(), label=T('GAE Password'))) + cmd = output = errors = "" + if form.accepts(request, session): + try: + kill() + except: + pass + ignore_apps = [item for item in apps + if not item in form.vars.applications] + regex = re.compile('\(applications/\(.*') + yaml = apath('../app.yaml', r=request) + if not os.path.exists(yaml): + example = apath('../app.example.yaml', r=request) + shutil.copyfile(example, yaml) + data = read_file(yaml) + data = re.sub('application:.*', 'application: %s' % + form.vars.google_application_id, data) + data = regex.sub( + '(applications/(%s)/.*)|' % '|'.join(ignore_apps), data) + write_file(yaml, data) + + path = request.env.applications_parent + cmd = '%s --email=%s --passin update %s' % \ + (form.vars.appcfg, form.vars.email, path) + p = cache.ram('gae_upload', + lambda s=subprocess, c=cmd: s.Popen(c, shell=True, + stdin=s.PIPE, + stdout=s.PIPE, + stderr=s.PIPE, close_fds=True), -1) + p.stdin.write(form.vars.password + '\n') + fcntl.fcntl(p.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) + fcntl.fcntl(p.stderr.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) + return dict(form=form, command=cmd) + + +def callback(): + p = cache.ram('gae_upload', lambda: None, forever) + if not p or p.poll() is not None: + return '' + try: + output = p.stdout.read() + except: + output = '' + try: + errors = p.stderr.read() + except: + errors = '' + return (output + errors).replace('\n', '
') diff --git a/web2py/applications/admin/controllers/mercurial.py b/web2py/applications/admin/controllers/mercurial.py new file mode 100644 index 0000000..4c8c9f2 --- /dev/null +++ b/web2py/applications/admin/controllers/mercurial.py @@ -0,0 +1,85 @@ +from gluon.fileutils import read_file, write_file + +if DEMO_MODE or MULTI_USER_MODE: + session.flash = T('disabled in demo mode') + redirect(URL('default', 'site')) +if not have_mercurial: + session.flash = T("Sorry, could not find mercurial installed") + redirect(URL('default', 'design', args=request.args(0))) + +_hgignore_content = """\ +syntax: glob +*~ +*.pyc +*.pyo +*.bak +*.bak2 +cache/* +private/* +uploads/* +databases/* +sessions/* +errors/* +""" + + +def hg_repo(path): + import os + uio = ui.ui() + uio.quiet = True + if not os.environ.get('HGUSER') and not uio.config("ui", "username"): + os.environ['HGUSER'] = 'web2py@localhost' + try: + repo = hg.repository(ui=uio, path=path) + except: + repo = hg.repository(ui=uio, path=path, create=True) + hgignore = os.path.join(path, '.hgignore') + if not os.path.exists(hgignore): + write_file(hgignore, _hgignore_content) + return repo + + +def commit(): + app = request.args(0) + path = apath(app, r=request) + repo = hg_repo(path) + form = FORM(T('Comment:'), INPUT(_name='comment', requires=IS_NOT_EMPTY()), + INPUT(_type='submit', _value=T('Commit'))) + if form.accepts(request.vars, session): + oldid = repo[repo.lookup('.')] + addremove(repo) + repo.commit(text=form.vars.comment) + if repo[repo.lookup('.')] == oldid: + response.flash = T('no changes') + try: + files = TABLE(*[TR(file) for file in repo[repo.lookup('.')].files()]) + changes = TABLE(TR(TH('revision'), TH('description'))) + for change in repo.changelog: + ctx = repo.changectx(change) + revision, description = ctx.rev(), ctx.description() + changes.append(TR(A(revision, _href=URL('revision', + args=(app, revision))), + description)) + except: + files = [] + changes = [] + return dict(form=form, files=files, changes=changes, repo=repo) + + +def revision(): + app = request.args(0) + path = apath(app, r=request) + repo = hg_repo(path) + revision = request.args(1) + ctx = repo.changectx(revision) + form = FORM(INPUT(_type='submit', _value=T('Revert'))) + if form.accepts(request.vars): + hg.update(repo, revision) + session.flash = T("reverted to revision %s") % ctx.rev() + redirect(URL('default', 'design', args=app)) + return dict( + files=ctx.files(), + rev=str(ctx.rev()), + desc=ctx.description(), + form=form + ) diff --git a/web2py/applications/admin/controllers/openshift.py b/web2py/applications/admin/controllers/openshift.py new file mode 100644 index 0000000..d1887df --- /dev/null +++ b/web2py/applications/admin/controllers/openshift.py @@ -0,0 +1,69 @@ +import os +try: + from distutils import dir_util +except ImportError: + session.flash = T('requires distutils, but not installed') + redirect(URL('default', 'site')) +try: + from git import * +except ImportError: + session.flash = T('requires python-git, but not installed') + redirect(URL('default', 'site')) + +from gluon.settings import settings +if not settings.is_source: + session.flash = 'Requires running web2py from source' + redirect(URL(request.application, 'default', 'site')) + +def deploy(): + apps = sorted(file for file in os.listdir(apath(r=request))) + form = SQLFORM.factory( + Field( + 'osrepo', default='/tmp', label=T('Path to local openshift repo root.'), + requires=EXISTS(error_message=T('directory not found'))), + Field('osname', default='web2py', label=T('WSGI reference name')), + Field('applications', 'list:string', + requires=IS_IN_SET(apps, multiple=True), + label=T('web2py apps to deploy'))) + + cmd = output = errors = "" + if form.accepts(request, session): + try: + kill() + except: + pass + + ignore_apps = [ + item for item in apps if not item in form.vars.applications] + regex = re.compile('\(applications/\(.*') + w2p_origin = os.getcwd() + osrepo = form.vars.osrepo + osname = form.vars.osname + #Git code starts here + repo = Repo(form.vars.osrepo) + index = repo.index + assert repo.bare == False + + for i in form.vars.applications: + appsrc = os.path.join(apath(r=request), i) + appdest = os.path.join(osrepo, 'wsgi', osname, 'applications', i) + dir_util.copy_tree(appsrc, appdest) + #shutil.copytree(appsrc,appdest) + index.add(['wsgi/' + osname + '/applications/' + i]) + new_commit = index.commit("Deploy from Web2py IDE") + + origin = repo.remotes.origin + origin.push + origin.push() + #Git code ends here + return dict(form=form, command=cmd) + + +class EXISTS(object): + def __init__(self, error_message='file not found'): + self.error_message = error_message + + def __call__(self, value): + if os.path.exists(value): + return (value, None) + return (value, self.error_message) diff --git a/web2py/applications/admin/controllers/plugin_jqmobile.py b/web2py/applications/admin/controllers/plugin_jqmobile.py new file mode 100644 index 0000000..18fc67d --- /dev/null +++ b/web2py/applications/admin/controllers/plugin_jqmobile.py @@ -0,0 +1,10 @@ +response.files = response.files[:3] +response.menu = [] + + +def index(): + return locals() + + +def about(): + return locals() diff --git a/web2py/applications/admin/controllers/pythonanywhere.py b/web2py/applications/admin/controllers/pythonanywhere.py new file mode 100644 index 0000000..2ebb980 --- /dev/null +++ b/web2py/applications/admin/controllers/pythonanywhere.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +import base64 +import os +import re +import gzip +import tarfile +from gluon.contrib.simplejsonrpc import ServerProxy +from gluon._compat import StringIO, ProtocolError, urlencode, urllib2 + +def deploy(): + response.title = T('Deploy to pythonanywhere') + return {} + + +def create_account(): + """ Create a PythonAnywhere account """ + if not request.vars: + raise HTTP(400) + + if request.vars.username and request.vars.web2py_admin_password: + # Check if web2py is already there otherwise we get an error 500 too. + client = ServerProxy('https://%(username)s:%(web2py_admin_password)s@%(username)s.pythonanywhere.com/admin/webservices/call/jsonrpc' % request.vars) + try: + if client.login() is True: + return response.json({'status': 'ok'}) + except ProtocolError as error: + pass + + url = 'https://www.pythonanywhere.com/api/web2py/create_account' + data = urlencode(request.vars) + req = urllib2.Request(url, data) + + try: + reply = urllib2.urlopen(req) + except urllib2.HTTPError as error: + if error.code == 400: + reply = error + elif error.code == 500: + return response.json({'status':'error', 'errors':{'username': ['An App other than web2py is installed in the domain %(username)s.pythonanywhere.com' % request.vars]}}) + else: + raise + response.headers['Content-Type'] = 'application/json' + return reply.read() + + +def list_apps(): + """ Get a list of apps both remote and local """ + if not request.vars.username or not request.vars.password: + raise HTTP(400) + client = ServerProxy('https://%(username)s:%(password)s@%(username)s.pythonanywhere.com/admin/webservices/call/jsonrpc' % request.vars) + regex = re.compile('^\w+$') + local = [f for f in os.listdir(apath(r=request)) if regex.match(f)] + try: + pythonanywhere = client.list_apps() + except ProtocolError as error: + raise HTTP(error.errcode) + return response.json({'local': local, 'pythonanywhere': pythonanywhere}) + + +def bulk_install(): + """ Install a list of apps """ + + def b64pack(app): + """ + Given an app's name, return the base64 representation of its packed version. + """ + folder = apath(app, r=request) + tmpfile = StringIO() + tar = tarfile.TarFile(fileobj=tmpfile, mode='w') + try: + filenames = listdir(folder, '^[\w\.\-]+$', add_dirs=True, + exclude_content_from=['cache', 'sessions', 'errors']) + for fname in filenames: + tar.add(os.path.join(folder, fname), fname, False) + finally: + tar.close() + tmpfile.seek(0) + gzfile = StringIO() + w2pfp = gzip.GzipFile(fileobj=gzfile, mode='wb') + w2pfp.write(tmpfile.read()) + w2pfp.close() + gzfile.seek(0) + return base64.b64encode(gzfile.read()) + + request.vars.apps = request.vars['apps[]'] + if not request.vars.apps or not request.vars.username or not request.vars.password: + raise HTTP(400) + if not isinstance(request.vars.apps, list): + request.vars.apps = [request.vars.apps] # Only one app selected + + client = ServerProxy('https://%(username)s:%(password)s@%(username)s.pythonanywhere.com/admin/webservices/call/jsonrpc' % request.vars) + + for app in request.vars.apps: + try: + client.install(app, app+'.w2p', b64pack(app)) + except ProtocolError as error: + raise HTTP(error.errcode) + + return response.json({'status': 'ok'}) diff --git a/web2py/applications/admin/controllers/toolbar.py b/web2py/applications/admin/controllers/toolbar.py new file mode 100644 index 0000000..83a25f8 --- /dev/null +++ b/web2py/applications/admin/controllers/toolbar.py @@ -0,0 +1,31 @@ +import os +from gluon.settings import global_settings, read_file +# + + +def index(): + app = request.args(0) + return dict(app=app) + + +def profiler(): + """ + to use the profiler start web2py with -F profiler.log + """ + KEY = 'web2py_profiler_size' + filename = global_settings.cmd_options.profiler_filename + data = 'profiler disabled' + if filename: + if KEY in request.cookies: + size = int(request.cookies[KEY].value) + else: + size = 0 + if os.path.exists(filename): + data = read_file('profiler.log', 'rb') + if size < len(data): + data = data[size:] + else: + size = 0 + size += len(data) + response.cookies[KEY] = size + return data diff --git a/web2py/applications/admin/controllers/webservices.py b/web2py/applications/admin/controllers/webservices.py new file mode 100644 index 0000000..9ae704d --- /dev/null +++ b/web2py/applications/admin/controllers/webservices.py @@ -0,0 +1,127 @@ +from gluon.admin import * +from gluon.fileutils import abspath, read_file, write_file +from gluon.tools import Service +from glob import glob +import shutil +import platform +import time +import base64 +import os +from gluon._compat import StringIO + + +service = Service(globals()) + +@service.jsonrpc +def login(): + "dummy function to test credentials" + return True + + +@service.jsonrpc +def list_apps(): + "list installed applications" + regex = re.compile('^\w+$') + apps = [f for f in os.listdir(apath(r=request)) if regex.match(f)] + return apps + + +@service.jsonrpc +def list_files(app, pattern='.*\.py$'): + files = listdir(apath('%s/' % app, r=request), pattern) + return [x.replace('\\', '/') for x in files] + + +@service.jsonrpc +def read_file(filename, b64=False): + """ Visualize object code """ + f = open(apath(filename, r=request), "rb") + try: + data = f.read() + if not b64: + data = data.replace('\r', '') + else: + data = base64.b64encode(data) + finally: + f.close() + return data + + +@service.jsonrpc +def write_file(filename, data, b64=False): + f = open(apath(filename, r=request), "wb") + try: + if not b64: + data = data.replace('\r\n', '\n').strip() + '\n' + else: + data = base64.b64decode(data) + f.write(data) + finally: + f.close() + + +@service.jsonrpc +def hash_file(filename): + data = read_file(filename) + file_hash = md5_hash(data) + path = apath(filename, r=request) + saved_on = os.stat(path)[stat.ST_MTIME] + size = os.path.getsize(path) + return dict(saved_on=saved_on, file_hash=file_hash, size=size) + + +@service.jsonrpc +def install(app_name, filename, data, overwrite=True): + f = StringIO(base64.b64decode(data)) + installed = app_install(app_name, f, request, filename, + overwrite=overwrite) + + return installed + + +@service.jsonrpc +def attach_debugger(host='localhost', port=6000, authkey='secret password'): + import gluon.contrib.dbg as dbg + import gluon.debug + from multiprocessing.connection import Listener + + if isinstance(authkey, unicode): + authkey = authkey.encode('utf8') + + if not hasattr(gluon.debug, 'dbg_listener'): + # create a remote debugger server and wait for connection + address = (host, port) # family is deduced to be 'AF_INET' + gluon.debug.dbg_listener = Listener(address, authkey=authkey) + gluon.debug.dbg_connection = gluon.debug.dbg_listener.accept() + # create the backend + gluon.debug.dbg_debugger = dbg.Qdb(gluon.debug.dbg_connection) + gluon.debug.dbg = gluon.debug.dbg_debugger + # welcome message (this should be displayed on the frontend) + print('debugger connected to', gluon.debug.dbg_listener.last_accepted) + return True # connection successful! + + +@service.jsonrpc +def detach_debugger(): + import gluon.contrib.dbg as dbg + import gluon.debug + # stop current debugger + if gluon.debug.dbg_debugger: + try: + gluon.debug.dbg_debugger.do_quit() + except: + pass + if hasattr(gluon.debug, 'dbg_listener'): + if gluon.debug.dbg_connection: + gluon.debug.dbg_connection.close() + del gluon.debug.dbg_connection + if gluon.debug.dbg_listener: + gluon.debug.dbg_listener.close() + del gluon.debug.dbg_listener + gluon.debug.dbg_debugger = None + return True + + +def call(): + session.forget() + return service() diff --git a/web2py/applications/admin/controllers/wizard.py b/web2py/applications/admin/controllers/wizard.py new file mode 100644 index 0000000..c3d5354 --- /dev/null +++ b/web2py/applications/admin/controllers/wizard.py @@ -0,0 +1,607 @@ +# -*- coding: utf-8 -*- + +import os +import uuid +import re +import pickle +import urllib +import glob +from gluon.admin import app_create, plugin_install +from gluon.fileutils import abspath, read_file, write_file, open_file + + +def reset(session): + session.app = { + 'name': '', + 'params': [('title', 'My New App'), + ('subtitle', 'powered by web2py'), + ('author', 'you'), + ('author_email', 'you@example.com'), + ('keywords', ''), + ('description', ''), + ('layout_theme', 'Default'), + ('database_uri', 'sqlite://storage.sqlite'), + ('security_key', str(uuid.uuid4())), + ('email_server', 'localhost'), + ('email_sender', 'you@example.com'), + ('email_login', ''), + ('login_method', 'local'), + ('login_config', ''), + ('plugins', [])], + 'tables': ['auth_user'], + 'table_auth_user': ['username', 'first_name', + 'last_name', 'email', 'password'], + 'pages': ['index', 'error'], + 'page_index': '# Welcome to my new app', + 'page_error': '# Error: the document does not exist', + } + +if not session.app: + reset(session) + + +def listify(x): + if not isinstance(x, (list, tuple)): + return x and [x] or [] + return x + + +def clean(name): + return re.sub('\W+', '_', name.strip().lower()) + + +def index(): + response.view = 'wizard/step.html' + reset(session) + apps = os.listdir(os.path.join(request.folder, '..')) + form = SQLFORM.factory(Field('name', requires=[IS_NOT_EMPTY(), + IS_ALPHANUMERIC()]), _class='span5 well well-small') + if form.accepts(request.vars): + app = form.vars.name + session.app['name'] = app + if MULTI_USER_MODE and db(db.app.name == app)(db.app.owner != auth.user.id).count(): + session.flash = 'App belongs already to other user' + elif app in apps: + meta = os.path.normpath( + os.path.join(os.path.normpath(request.folder), + '..', app, 'wizard.metadata')) + if os.path.exists(meta): + try: + metafile = open_file(meta, 'rb') + try: + session.app = pickle.load(metafile) + finally: + metafile.close() + session.flash = T("The app exists, was created by wizard, continue to overwrite!") + except: + session.flash = T("The app exists, was NOT created by wizard, continue to overwrite!") + redirect(URL('step1')) + return dict(step='Start', form=form) + + +def step1(): + from json import loads + import urllib + if not session.themes: + #url = LAYOUTS_APP + '/default/layouts.json' + #try: + # data = urllib.urlopen(url).read() + # session.themes = ['Default'] + loads(data)['layouts'] + #except: + session.themes = ['Default'] + themes = session.themes + if not session.plugins: + #url = PLUGINS_APP + '/default/plugins.json' + #try: + # data = urllib.urlopen(url).read() + # session.plugins = loads(data)['plugins'] + #except: + session.plugins = [] + plugins = [x.split('.')[2] for x in session.plugins] + response.view = 'wizard/step.html' + params = dict(session.app['params']) + form = SQLFORM.factory( + Field('title', default=params.get('title', None), + requires=IS_NOT_EMPTY()), + Field('subtitle', default=params.get('subtitle', None)), + Field('author', default=params.get('author', None)), + Field( + 'author_email', default=params.get('author_email', None)), + Field('keywords', default=params.get('keywords', None)), + Field('description', 'text', + default=params.get('description', None)), + Field('layout_theme', requires=IS_IN_SET(themes), + default=params.get('layout_theme', themes[0])), + Field( + 'database_uri', default=params.get('database_uri', None)), + Field( + 'security_key', default=params.get('security_key', None)), + Field( + 'email_server', default=params.get('email_server', None)), + Field( + 'email_sender', default=params.get('email_sender', None)), + Field('email_login', default=params.get('email_login', None)), + Field('login_method', requires=IS_IN_SET(('local', 'janrain')), + default=params.get('login_method', 'local')), + Field( + 'login_config', default=params.get('login_config', None)), + Field('plugins', 'list:string', requires=IS_IN_SET(plugins, multiple=True)), + _class='span7 well well-small') + + if form.accepts(request.vars): + session.app['params'] = [(key, form.vars.get(key, None)) + for key, value in session.app['params']] + redirect(URL('step2') + '/#xwizard_form') + return dict(step='1: Setting Parameters', form=form) + + +def step2(): + response.view = 'wizard/step.html' + form = SQLFORM.factory(Field('table_names', 'list:string', + default=session.app['tables']), _class="span7 well well-small") + if form.accepts(request.vars): + table_names = [clean(t) for t in listify(form.vars.table_names) + if t.strip()] + if [t for t in table_names if t.startswith('auth_') and + not t == 'auth_user']: + form.error.table_names = \ + T('invalid table names (auth_* tables already defined)') + else: + session.app['tables'] = table_names + for table in session.app['tables']: + if not 'table_' + table in session.app: + session.app['table_' + table] = ['name'] + if not table == 'auth_user': + name = table + '_manage' + if not name in session.app['pages']: + session.app['pages'].append(name) + session.app['page_' + name] = \ + '## Manage %s\n\n{{=form}}' % (table) + if session.app['tables']: + redirect(URL('step3', args=0) + '/#xwizard_form') + else: + redirect(URL('step4') + '/#xwizard_form') + return dict(step='2: Tables', form=form) + + +def step3(): + response.view = 'wizard/step.html' + n = int(request.args(-1) or 0) + m = len(session.app['tables']) + if n >= m: + redirect(URL('step2')) + table = session.app['tables'][n] + form = SQLFORM.factory(Field('field_names', 'list:string', + default=session.app.get('table_' + table, [])), _class="span7 well well-small") + if form.accepts(request.vars) and form.vars.field_names: + fields = listify(form.vars.field_names) + if table == 'auth_user': + for field in ['first_name', 'last_name', 'username', 'email', 'password']: + if not field in fields: + fields.append(field) + session.app['table_' + table] = [t.strip().lower() + for t in listify(form.vars.field_names) + if t.strip()] + try: + tables = sort_tables(session.app['tables']) + except RuntimeError: + response.flash = T('invalid circular reference') + else: + if n < m - 1: + redirect(URL('step3', args=n + 1) + '/#xwizard_form') + else: + redirect(URL('step4') + '/#xwizard_form') + return dict(step='3: Fields for table "%s" (%s of %s)' + % (table, n + 1, m), table=table, form=form) + + +def step4(): + response.view = 'wizard/step.html' + form = SQLFORM.factory(Field('pages', 'list:string', + default=session.app['pages']), _class="span7 well well-small") + if form.accepts(request.vars): + session.app['pages'] = [clean(t) + for t in listify(form.vars.pages) + if t.strip()] + if session.app['pages']: + redirect(URL('step5', args=0) + '/#xwizard_form') + else: + redirect(URL('step6') + '/#xwizard_form') + return dict(step='4: Pages', form=form) + + +def step5(): + response.view = 'wizard/step.html' + n = int(request.args(-1) or 0) + m = len(session.app['pages']) + if n >= m: + redirect(URL('step4')) + page = session.app['pages'][n] + markmin_url = 'http://web2py.com/examples/static/markmin.html' + form = SQLFORM.factory(Field('content', 'text', + default=session.app.get('page_' + page, []), + comment=A('use markmin', + _href=markmin_url, _target='_blank')), + formstyle='table2cols', _class="span7 well well-small") + if form.accepts(request.vars): + session.app['page_' + page] = form.vars.content + if n < m - 1: + redirect(URL('step5', args=n + 1) + '/#xwizard_form') + else: + redirect(URL('step6') + '/#xwizard_form') + return dict(step='5: View for page "%s" (%s of %s)' % (page, n + 1, m), form=form) + + +def step6(): + response.view = 'wizard/step.html' + params = dict(session.app['params']) + app = session.app['name'] + form = SQLFORM.factory( + Field('generate_model', 'boolean', default=True), + Field('generate_controller', 'boolean', default=True), + Field('generate_views', 'boolean', default=True), + Field('generate_menu', 'boolean', default=True), + Field('apply_layout', 'boolean', default=True), + Field('erase_database', 'boolean', default=True), + Field('populate_database', 'boolean', default=True), + _id="generate_form", _class="form-horizontal span7 well well-small") + if form.accepts(request.vars): + if DEMO_MODE: + session.flash = T('Application cannot be generated in demo mode') + redirect(URL('index')) + create(form.vars) + session.flash = 'Application %s created' % app + redirect(URL('generated')) + return dict(step='6: Generate app "%s"' % app, form=form) + + +def generated(): + return dict(app=session.app['name']) + + +def sort_tables(tables): + import re + regex = re.compile('(%s)' % '|'.join(tables)) + is_auth_user = 'auth_user' in tables + d = {} + for table in tables: + d[table] = [] + for field in session.app['table_%s' % table]: + d[table] += regex.findall(field) + tables = [] + if is_auth_user: + tables.append('auth_user') + + def append(table, trail=[]): + if table in trail: + raise RuntimeError + for t in d[table]: + # if not t==table: (problem, no dropdown for self references) + append(t, trail=trail + [table]) + if not table in tables: + tables.append(table) + for table in d: + append(table) + return tables + + +def make_table(table, fields): + rawtable = table + if table != 'auth_user': + table = 't_' + table + s = '' + s += '\n' + '#' * 40 + '\n' + s += "db.define_table('%s',\n" % table + first_field = 'id' + for field in fields: + items = [x.lower() for x in field.split()] + has = {} + keys = [] + for key in ['notnull', 'unique', 'integer', 'double', 'boolean', 'float', + 'boolean', 'date', 'time', 'datetime', 'text', 'wiki', + 'html', 'file', 'upload', 'image', 'true', + 'hidden', 'readonly', 'writeonly', 'multiple', + 'notempty', 'required']: + if key in items[1:]: + keys.append(key) + has[key] = True + tables = session.app['tables'] + refs = [t for t in tables if t in items] + items = items[:1] + [x for x in items[1:] + if not x in keys and not x in tables] + barename = name = '_'.join(items) + if table[:2] == 't_': name = 'f_' + name + if first_field == 'id': + first_field = name + + ### determine field type + ftype = 'string' + deftypes = {'integer': 'integer', 'double': 'double', 'boolean': 'boolean', + 'float': 'double', 'bool': 'boolean', + 'date': 'date', 'time': 'time', 'datetime': 'datetime', + 'text': 'text', 'file': 'upload', 'image': 'upload', + 'upload': 'upload', 'wiki': 'text', 'html': 'text'} + for key, t in deftypes.items(): + if key in has: + ftype = t + if refs: + key = refs[0] + if not key == 'auth_user': + key = 't_' + key + if 'multiple' in has: + ftype = 'list:reference %s' % key + else: + ftype = 'reference %s' % key + if ftype == 'string' and 'multiple' in has: + ftype = 'list:string' + elif ftype == 'integer' and 'multiple' in has: + ftype = 'list:integer' + elif name == 'password': + ftype = 'password' + s += " Field('%s', type='%s'" % (name, ftype) + + ### determine field attributes + if 'notnull' in has or 'notempty' in has or 'required' in has: + s += ', notnull=True' + if 'unique' in has: + s += ', unique=True' + if ftype == 'boolean' and 'true' in has: + s += ",\n default=True" + + ### determine field representation + elif 'wiki' in has: + s += ",\n represent=lambda x, row: MARKMIN(x)" + s += ",\n comment='WIKI (markmin)'" + elif 'html' in has: + s += ",\n represent=lambda x, row: XML(x,sanitize=True)" + s += ",\n comment='HTML (sanitized)'" + ### determine field access + if name == 'password' or 'writeonly' in has: + s += ",\n readable=False" + elif 'hidden' in has: + s += ",\n writable=False, readable=False" + elif 'readonly' in has: + s += ",\n writable=False" + + ### make up a label + s += ",\n label=T('%s')),\n" % \ + ' '.join(x.capitalize() for x in barename.split('_')) + if table == 'auth_user': + s += " Field('created_on','datetime',default=request.now,\n" + s += " label=T('Created On'),writable=False,readable=False),\n" + s += " Field('modified_on','datetime',default=request.now,\n" + s += " label=T('Modified On'),writable=False,readable=False,\n" + s += " update=request.now),\n" + s += " Field('registration_key',default='',\n" + s += " writable=False,readable=False),\n" + s += " Field('reset_password_key',default='',\n" + s += " writable=False,readable=False),\n" + s += " Field('registration_id',default='',\n" + s += " writable=False,readable=False),\n" + elif 'auth_user' in session.app['tables']: + s += " auth.signature,\n" + s += " format='%(" + first_field + ")s',\n" + s += " migrate=settings.migrate)\n\n" + if table == 'auth_user': + s += """ +db.auth_user.first_name.requires = IS_NOT_EMPTY( + error_message=auth.messages.is_empty) +db.auth_user.last_name.requires = IS_NOT_EMPTY( + error_message=auth.messages.is_empty) +db.auth_user.password.requires = CRYPT( + key=auth.settings.hmac_key, min_length=4) +db.auth_user.username.requires = IS_NOT_IN_DB(db, db.auth_user.username) +db.auth_user.email.requires = ( + IS_EMAIL(error_message=auth.messages.invalid_email), + IS_NOT_IN_DB(db, db.auth_user.email)) +""" + else: + s += "db.define_table('%s_archive',db.%s,Field('current_record','reference %s',readable=False,writable=False))\n" % (table, table, table) + return s + + +def fix_db(filename): + params = dict(session.app['params']) + content = read_file(filename, 'r') + if 'auth_user' in session.app['tables']: + auth_user = make_table('auth_user', session.app['table_auth_user']) + content = content.replace('sqlite://storage.sqlite', + params['database_uri']) + content = content.replace('auth.define_tables()', + auth_user + 'auth.define_tables(migrate = settings.migrate)') + content += """ +mail.settings.server = settings.email_server +mail.settings.sender = settings.email_sender +mail.settings.login = settings.email_login +""" + if params['login_method'] == 'janrain': + content += """ +from gluon.contrib.login_methods.rpx_account import RPXAccount +auth.settings.actions_disabled=['register','change_password', + 'request_reset_password'] +auth.settings.login_form = RPXAccount(request, + api_key = settings.login_config.split(':')[-1], + domain = settings.login_config.split(':')[0], + url = "http://%s/%s/default/user/login" % (request.env.http_host,request.application)) +""" + write_file(filename, content, 'w') + + +def make_menu(pages): + s = '' + s += 'response.title = settings.title\n' + s += 'response.subtitle = settings.subtitle\n' + s += "response.meta.author = '%(author)s <%(author_email)s>' % settings\n" + s += 'response.meta.keywords = settings.keywords\n' + s += 'response.meta.description = settings.description\n' + s += 'response.menu = [\n' + for page in pages: + if not page.startswith('error'): + if page.endswith('_manage'): + page_name = page[:-7] + else: + page_name = page + page_name = ' '.join(x.capitalize() for x in page_name.split('_')) + s += "(T('%s'),URL('default','%s')==URL(),URL('default','%s'),[]),\n" \ + % (page_name, page, page) + s += ']' + return s + + +def make_page(page, contents): + if 'auth_user' in session.app['tables'] and not page in ('index', 'error'): + s = "@auth.requires_login()\ndef %s():\n" % page + else: + s = "def %s():\n" % page + items = page.rsplit('_', 1) + if items[0] in session.app['tables'] and len(items) == 2 and items[1] == 'manage': + s += " form = SQLFORM.smartgrid(db.t_%s,onupdate=auth.archive)\n" % items[0] + s += " return locals()\n\n" + else: + s += " return dict()\n\n" + return s + + +def make_view(page, contents): + s = "{{extend 'layout.html'}}\n\n" + s += str(MARKMIN(contents)) + return s + + +def populate(tables): + s = 'from gluon.contrib.populate import populate\n' + s += 'if db(db.auth_user).isempty():\n' + for table in sort_tables(tables): + t = table == 'auth_user' and 'auth_user' or 't_' + table + s += " populate(db.%s,10)\n" % t + return s + + +def create(options): + if DEMO_MODE: + session.flash = T('disabled in demo mode') + redirect(URL('step6')) + params = dict(session.app['params']) + app = session.app['name'] + if app_create(app, request, force=True, key=params['security_key']): + if MULTI_USER_MODE: + db.app.insert(name=app, owner=auth.user.id) + else: + session.flash = 'Failure to create application' + redirect(URL('step6')) + + ### save metadata in newapp/wizard.metadata + try: + meta = os.path.join(request.folder, '..', app, 'wizard.metadata') + file = open_file(meta, 'wb') + pickle.dump(session.app, file) + file.close() + except IOError: + session.flash = 'Failure to write wizard metadata' + redirect(URL('step6')) + + ### apply theme + if options.apply_layout and params['layout_theme'] != 'Default': + try: + fn = 'web2py.plugin.layout_%s.w2p' % params['layout_theme'] + theme = urllib.urlopen( + LAYOUTS_APP + '/static/plugin_layouts/plugins/' + fn) + plugin_install(app, theme, request, fn) + except: + session.flash = T("unable to download layout") + + ### apply plugins + for plugin in params['plugins']: + try: + plugin_name = 'web2py.plugin.' + plugin + '.w2p' + stream = urllib.urlopen(PLUGINS_APP + '/static/' + plugin_name) + plugin_install(app, stream, request, plugin_name) + except Exception as e: + session.flash = T("unable to download plugin: %s" % plugin) + + ### write configuration file into newapp/models/0.py + model = os.path.join(request.folder, '..', app, 'models', '0.py') + file = open_file(model, 'w') + try: + file.write("from gluon.storage import Storage\n") + file.write("settings = Storage()\n\n") + file.write("settings.migrate = True\n") + for key, value in session.app['params']: + file.write("settings.%s = %s\n" % (key, repr(value))) + finally: + file.close() + + ### write configuration file into newapp/models/menu.py + if options.generate_menu: + model = os.path.join(request.folder, '..', app, 'models', 'menu.py') + file = open_file(model, 'w') + try: + file.write(make_menu(session.app['pages'])) + finally: + file.close() + + ### customize the auth_user table + model = os.path.join(request.folder, '..', app, 'models', 'db.py') + fix_db(model) + + ### create newapp/models/db_wizard.py + if options.generate_model: + model = os.path.join( + request.folder, '..', app, 'models', 'db_wizard.py') + file = open_file(model, 'w') + try: + file.write('### we prepend t_ to tablenames and f_ to fieldnames for disambiguity\n\n') + tables = sort_tables(session.app['tables']) + for table in tables: + if table == 'auth_user': + continue + file.write(make_table(table, session.app['table_' + table])) + finally: + file.close() + + model = os.path.join(request.folder, '..', app, + 'models', 'db_wizard_populate.py') + if os.path.exists(model): + os.unlink(model) + if options.populate_database and session.app['tables']: + file = open_file(model, 'w') + try: + file.write(populate(session.app['tables'])) + finally: + file.close() + + ### create newapp/controllers/default.py + if options.generate_controller: + controller = os.path.join( + request.folder, '..', app, 'controllers', 'default.py') + file = open_file(controller, 'w') + try: + file.write("""# -*- coding: utf-8 -*- +### required - do no delete +def user(): return dict(form=auth()) +def download(): return response.download(request,db) +def call(): return service() +### end requires +""") + for page in session.app['pages']: + file.write( + make_page(page, session.app.get('page_' + page, ''))) + finally: + file.close() + + ### create newapp/views/default/*.html + if options.generate_views: + for page in session.app['pages']: + view = os.path.join( + request.folder, '..', app, 'views', 'default', page + '.html') + file = open_file(view, 'w') + try: + file.write( + make_view(page, session.app.get('page_' + page, ''))) + finally: + file.close() + + if options.erase_database: + path = os.path.join(request.folder, '..', app, 'databases', '*') + for file in glob.glob(path): + os.unlink(file) diff --git a/web2py/applications/admin/cron/crontab b/web2py/applications/admin/cron/crontab new file mode 100644 index 0000000..3a32c0d --- /dev/null +++ b/web2py/applications/admin/cron/crontab @@ -0,0 +1,2 @@ +10 * * * * root **applications/admin/cron/expire_sessions.py + diff --git a/web2py/applications/admin/cron/expire_sessions.py b/web2py/applications/admin/cron/expire_sessions.py new file mode 100644 index 0000000..34b1609 --- /dev/null +++ b/web2py/applications/admin/cron/expire_sessions.py @@ -0,0 +1,28 @@ + +import os, time, stat, logging +from gluon._compat import pickle + +EXPIRATION_MINUTES = 60 + +path = os.path.join(request.folder, 'sessions') +if not os.path.exists(path): + os.mkdir(path) +now = time.time() +for path, dirs, files in os.walk(path, topdown=False): + for x in files: + fullpath = os.path.join(path, x) + try: + filetime = os.stat(fullpath)[stat.ST_MTIME] # get it before our io + try: + session_data = pickle.load(open(fullpath, 'rb+')) + expiration = session_data['auth']['expiration'] + except: + expiration = EXPIRATION_MINUTES * 60 + if (now - filetime) > expiration: + os.unlink(fullpath) + except: + logging.exception('failure to check %s' % fullpath) + for d in dirs: + dd = os.path.join(path, d) + if not os.listdir(dd): + os.rmdir(dd) diff --git a/web2py/applications/admin/errors/127.0.0.1.2018-09-22.18-10-57.651cbadf-fbcf-432a-b809-60471a5a6391 b/web2py/applications/admin/errors/127.0.0.1.2018-09-22.18-10-57.651cbadf-fbcf-432a-b809-60471a5a6391 new file mode 100644 index 0000000000000000000000000000000000000000..bbdbc3c1df5328c47ecc237b14c5d6f7019a170d GIT binary patch literal 42608 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/admin/errors/127.0.0.1.2018-09-22.18-12-47.2de91eb7-be71-4410-8c6f-f0addca46ccd b/web2py/applications/admin/errors/127.0.0.1.2018-09-22.18-12-47.2de91eb7-be71-4410-8c6f-f0addca46ccd new file mode 100644 index 0000000000000000000000000000000000000000..3619cef106b38aa1a523bb65c77c2d404d5e7ef4 GIT binary patch literal 42625 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/admin/languages/af.py b/web2py/applications/admin/languages/af.py new file mode 100644 index 0000000..6351ae0 --- /dev/null +++ b/web2py/applications/admin/languages/af.py @@ -0,0 +1,582 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'af', +'!langname!': 'Afrikaanse', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s rows deleted', +'%s %%{row} updated': '%s rows updated', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(requires internet access)': '(vereis internet toegang)', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(iets soos "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01Searching: **%s** %%{file}': 'Soek: **%s** lêre', +'Abort': 'Abort', +'About': 'oor', +'About application': 'Oor program', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Add breakpoint', +'Additional code for your application': 'Additionele kode vir u application', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'admin disabled because no admin password', +'admin disabled because not supported on google app engine': 'admin disabled because not supported on google app engine', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'admin disabled because unable to access password file', +'Admin is disabled because insecure channel': 'Admin is disabled because insecure channel', +'Admin language': 'Admin taal', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'administrative interface', +'Administrator Password:': 'Administrator Password:', +'and rename it:': 'en verander die naam:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'appadmin is disabled because insecure channel', +'Application': 'Application', +'application "%s" uninstalled': 'application "%s" uninstalled', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'application compiled', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'application is compiled and cannot be designed', +'Application name:': 'Program naam:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'are not used', +'are not used yet': 'are not used yet', +'Are you sure you want to delete file "%s"?': 'Are you sure you want to delete file "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Are you sure you want to delete plugin "%s"?', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Are you sure you want to uninstall application "%s"?': 'Are you sure you want to uninstall application "%s"?', +'Are you sure?': 'Are you sure?', +'arguments': 'arguments', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.', +'ATTENTION: you cannot edit the running application!': 'ATTENTION: you cannot edit the running application!', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available Databases and Tables': 'Available Databases and Tables', +'back': 'back', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'Begin': 'Begin', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'cache, errors and sessions cleaned', +'can be a git repo': 'can be a git repo', +'Cancel': 'Cancel', +'Cannot be empty': 'Cannot be empty', +'Cannot compile: there are errors in your app:': 'Cannot compile: there are errors in your app:', +'cannot create file': 'cannot create file', +'cannot upload file "%(filename)s"': 'cannot upload file "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'verander admin wagwoord', +'change editor settings': 'change editor settings', +'Changelog': 'Changelog', +'check all': 'check all', +'Check for upgrades': 'soek vir upgrades', +'Check to delete': 'Check to delete', +'Checking for upgrades...': 'Checking for upgrades...', +'Clean': 'maak skoon', +'Clear': 'Clear', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Click row to expand traceback': 'Click row to expand traceback', +'Click row to view a ticket': 'Click row to view a ticket', +'code': 'code', +'Code listing': 'Code listing', +'collapse/expand all': 'collapse/expand all', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'kompileer', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'compiled application removed', +'Condition': 'Condition', +'continue': 'continue', +'Controllers': 'Beheerders', +'controllers': 'beheerders', +'Count': 'Count', +'Create': 'skep', +'create file with filename:': 'skep lêer met naam:', +'Create/Upload': 'Create/Upload', +'created by': 'geskep deur', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Current request', +'Current response': 'Current response', +'Current session': 'Current session', +'currently running': 'loop tans', +'currently saved or': 'currently saved or', +'data uploaded': 'data uploaded', +'Database': 'Database', +'Database %s select': 'Database %s select', +'Database administration': 'Database administration', +'database administration': 'database administration', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Date and Time', +'db': 'db', +'Debug': 'Debug', +'defines tables': 'defines tables', +'Delete': 'Delete', +'delete': 'delete', +'delete all checked': 'delete all checked', +'delete plugin': 'delete plugin', +'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)', +'Delete:': 'Delete:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'deploy', +'Deploy on Google App Engine': 'Stuur na Google App Engine toe', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description:': 'Description:', +'design': 'design', +'Detailed traceback description': 'Detailed traceback description', +'details': 'details', +'direction: ltr': 'direction: ltr', +'directory not found': 'directory not found', +'Disable': 'Disable', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'docs', +'Docs': 'Docs', +'done!': 'done!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'aflaai layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'aflaai plugins', +'Download plugins from repository': 'Download plugins from repository', +'Edit': 'wysig', +'edit all': 'edit all', +'Edit application': 'Wysig program', +'edit controller:': 'edit controller:', +'Edit current record': 'Edit current record', +'edit views:': 'edit views:', +'Editing %s': 'Editing %s', +'Editing Language file': 'Editing Language file', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Enable', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Error': 'Error', +'Error logs for "%(app)s"': 'Error logs for "%(app)s"', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Error ticket', +'Errors': 'foute', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Exception instance attributes', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'export as csv file', +'Exports:': 'Exports:', +'exposes': 'exposes', +'exposes:': 'exposes:', +'extends': 'extends', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module because:': 'failed to reload module because:', +'File': 'File', +'file "%(filename)s" created': 'file "%(filename)s" created', +'file "%(filename)s" deleted': 'file "%(filename)s" deleted', +'file "%(filename)s" uploaded': 'file "%(filename)s" uploaded', +'file "%s" of %s restored': 'file "%s" of %s restored', +'file changed on disk': 'file changed on disk', +'file does not exist': 'file does not exist', +'file not found': 'file not found', +'file saved on %(time)s': 'file saved on %(time)s', +'file saved on %s': 'file saved on %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'filter', +'Find Next': 'Find Next', +'Find Previous': 'Find Previous', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': 'Functions with no doctests will result in [passed] tests.', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Help': 'hulp', +'here': 'here', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Import/Export', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'includes', +'Indent with tabs': 'Indent with tabs', +'inspect attributes': 'inspect attributes', +'Install': 'installeer', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Geinstalleerde apps', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'internal error', +'internal error: %s': 'internal error: %s', +'Internal State': 'Internal State', +'Invalid action': 'Invalid action', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'invalid password', +'invalid password.': 'invalid password.', +'Invalid Query': 'Invalid Query', +'invalid request': 'invalid request', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'invalid ticket', +'Key': 'Key', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'language file "%(filename)s" created/updated', +'Language files (static strings) updated': 'Language files (static strings) updated', +'languages': 'tale', +'Languages': 'Tale', +'Last Revision': 'Last Revision', +'Last saved on:': 'Last saved on:', +'License for': 'Lisensie vir', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Loading...': 'Loading...', +'loading...': 'laai...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'Login': 'Login', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Login to the Administrative Interface', +'Login/Register': 'Login/Register', +'Logout': 'logout', +'lost password': 'lost password', +'Main Menu': 'Main Menu', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Memberships': 'Memberships', +'merge': 'merge', +'Models': 'Modelle', +'models': 'modelle', +'Modified On': 'Modified On', +'Modules': 'Modules', +'modules': 'modules', +'Multi User Mode': 'Multi User Mode', +'new application "%s" created': 'new application "%s" created', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'New Application Wizard', +'New application wizard': 'Nuwe app wizard', +'new plugin installed': 'new plugin installed', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'New Record', +'new record inserted': 'new record inserted', +'New simple application': 'Nuwe eenvoudige app', +'next': 'next', +'next %s rows': 'next %s rows', +'NO': 'NO', +'no changes': 'no changes', +'No databases in this application': 'No databases in this application', +'No Interaction yet': 'No Interaction yet', +'no match': 'no match', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'or import from csv file', +'Original/Translation': 'Original/Translation', +'Overview': 'Overview', +'Overwrite installed app': 'skryf oor geinstalleerde program', +'Pack all': 'pack alles', +'Pack compiled': 'Pack compiled', +'Pack custom': 'Pack custom', +'pack plugin': 'pack plugin', +'password changed': 'password changed', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Peeking at file', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Please', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" deleted', +'Plugin "%s" in application': 'Plugin "%s" in application', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'plugins', +'Plugins': 'Plugins', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Aangedryf deur', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Project Progress', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Query:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Record': 'Record', +'record does not exist': 'record does not exist', +'Record id': 'Record id', +'refresh': 'refresh', +'register': 'register', +'Reload routes': 'Reload routes', +'Remove compiled': 'Remove compiled', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Replace', +'Replace All': 'Replace All', +'Repository (%s)': 'Repository (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Resolve Conflict file': 'Resolve Conflict file', +'response': 'response', +'restart': 'restart', +'restore': 'restore', +'return': 'return', +'Revert': 'Revert', +'revert': 'revert', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Rows in Table', +'Rows selected': 'Rows selected', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'Running on %s', +'Save': 'Save', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Save via Ajax', +'Saved file hash:': 'Saved file hash:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'session': 'session', +'session expired': 'session expired', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'shell', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'site', +'Size of cache:': 'Size of cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': 'some files could not be removed', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Start a new app', +'Start searching': 'Start searching', +'Start wizard': 'start wizard', +'state': 'state', +'Static': 'Static', +'static': 'static', +'Static files': 'Static files', +'Statistics': 'Statistics', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'submit': 'submit', +'Submit': 'Submit', +'successful': 'successful', +'Sure you want to delete this object?': 'Is jy seker jy will hierde object verwyder?', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'Table': 'Table', +'Temporary': 'Temporary', +'test': 'toets', +'Testing application': 'Testing application', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller', +'The data representation, define database tables and sets': 'The data representation, define database tables and sets', +'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates', +'Theme': 'Theme', +'There are no controllers': 'There are no controllers', +'There are no models': 'There are no models', +'There are no modules': 'There are no modules', +'There are no plugins': 'Daar is geen plugins', +'There are no private files': 'There are no private files', +'There are no static files': 'There are no static files', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'There are no translators, only default language is supported', +'There are no views': 'There are no views', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'Hierdie lêre is sonder veranderinge geserved, jou images gaan hier', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Ticket', +'Ticket ID': 'Ticket ID', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'to previous version.': 'to previous version.', +'To create a plugin, name a file/folder plugin_[name]': 'Om n plugin te skep, noem n lêer/gids plugin_[name]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'Translation strings for the application': 'Vertaling woorde vir die program', +'try something like': 'try something like', +'Try the mobile interface': 'Try the mobile interface', +'try view': 'try view', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Unable to check for upgrades', +'unable to create application "%s"': 'unable to create application "%s"', +'unable to delete file "%(filename)s"': 'unable to delete file "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'unable to delete file plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download app because:': 'Unable to download app because:', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'unable to parse csv file', +'unable to uninstall "%s"': 'unable to uninstall "%s"', +'unable to upgrade because "%s"': 'unable to upgrade because "%s"', +'uncheck all': 'uncheck all', +'Uninstall': 'verwyder', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'update', +'update all languages': 'update all languages', +'Update:': 'Update:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'upgrade now to %s', +'upload': 'oplaai', +'Upload': 'Upload', +'Upload & install packed application': 'Oplaai & install gepakte program', +'Upload a package:': 'Oplaai n package:', +'Upload and install packed application': 'Upload and install packed application', +'upload file:': 'oplaai lêer:', +'upload plugin file:': 'upload plugin lêer:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.', +'Use an url:': 'Gebruik n url:', +'User': 'User', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'variables', +'Version': 'Version', +'Versioning': 'Versioning', +'versioning': 'versioning', +'Views': 'Views', +'views': 'views', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py is up to date', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'web2py Onlangse Tweets', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py upgraded; please restart it', +'Working...': 'Working...', +'WSGI reference name': 'WSGI reference name', +'YES': 'YES', +'Yes': 'Yes', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/bg.py b/web2py/applications/admin/languages/bg.py new file mode 100644 index 0000000..c841bec --- /dev/null +++ b/web2py/applications/admin/languages/bg.py @@ -0,0 +1,640 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'bg', +'!langname!': 'Български', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s записите бяха изтрити', +'%s %%{row} updated': '%s записите бяха обновени', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(requires internet access)': '(requires internet access)', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(something like "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files', +'A new version of web2py is available': 'A new version of web2py is available', +'A new version of web2py is available: %s': 'A new version of web2py is available: %s', +'Abort': 'Abort', +'About': 'about', +'About application': 'About application', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Add breakpoint', +'additional code for your application': 'additional code for your application', +'Additional code for your application': 'Additional code for your application', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'admin disabled because no admin password', +'admin disabled because not supported on google app engine': 'admin disabled because not supported on google apps engine', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'admin disabled because unable to access password file', +'Admin is disabled because insecure channel': 'Admin is disabled because insecure channel', +'Admin is disabled because unsecure channel': 'Admin is disabled because unsecure channel', +'Admin language': 'Admin language', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'administrative interface', +'Administrator Password:': 'Administrator Password:', +'and rename it (required):': 'and rename it (required):', +'and rename it:': 'and rename it:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'appadmin is disabled because insecure channel', +'Application': 'Application', +'application "%s" uninstalled': 'application "%s" uninstalled', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'application compiled', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'application is compiled and cannot be designed', +'Application name:': 'Application name:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'are not used', +'are not used yet': 'are not used yet', +'Are you sure you want to delete file "%s"?': 'Are you sure you want to delete file "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Are you sure you want to delete plugin "%s"?', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Are you sure you want to uninstall application "%s"': 'Are you sure you want to uninstall application "%s"', +'Are you sure you want to uninstall application "%s"?': 'Are you sure you want to uninstall application "%s"?', +'Are you sure you want to upgrade web2py now?': 'Are you sure you want to upgrade web2py now?', +'Are you sure?': 'Are you sure?', +'arguments': 'arguments', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.', +'ATTENTION: you cannot edit the running application!': 'ATTENTION: you cannot edit the running application!', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available databases and tables': 'Available databases and tables', +'Available Databases and Tables': 'Available Databases and Tables', +'back': 'back', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'Begin': 'Begin', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'cache, errors and sessions cleaned', +'can be a git repo': 'can be a git repo', +'Cancel': 'Cancel', +'Cannot be empty': 'Cannot be empty', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Cannot compile: there are errors in your app. Debug it, correct errors and try again.', +'Cannot compile: there are errors in your app:': 'Cannot compile: there are errors in your app:', +'cannot create file': 'cannot create file', +'cannot upload file "%(filename)s"': 'cannot upload file "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'change admin password', +'change editor settings': 'change editor settings', +'Changelog': 'Changelog', +'check all': 'check all', +'Check for upgrades': 'check for upgrades', +'Check to delete': 'Check to delete', +'Checking for upgrades...': 'Checking for upgrades...', +'Clean': 'clean', +'Clear': 'Clear', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'click here for online examples': 'щракни тук за онлайн примери', +'click here for the administrative interface': 'щракни тук за административния интерфейс', +'Click row to expand traceback': 'Click row to expand traceback', +'Click row to view a ticket': 'Click row to view a ticket', +'click to check for upgrades': 'click to check for upgrades', +'code': 'code', +'Code listing': 'Code listing', +'collapse/expand all': 'collapse/expand all', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'compile', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'compiled application removed', +'Condition': 'Condition', +'continue': 'continue', +'Controllers': 'Controllers', +'controllers': 'controllers', +'Count': 'Count', +'Create': 'create', +'create file with filename:': 'create file with filename:', +'create new application:': 'create new application:', +'Create new simple application': 'Create new simple application', +'Create/Upload': 'Create/Upload', +'created by': 'created by', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Current request', +'Current response': 'Current response', +'Current session': 'Current session', +'currently running': 'currently running', +'currently saved or': 'currently saved or', +'data uploaded': 'данните бяха качени', +'Database': 'Database', +'database': 'database', +'Database %s select': 'Database %s select', +'database %s select': 'database %s select', +'Database administration': 'Database administration', +'database administration': 'database administration', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Date and Time', +'db': 'дб', +'Debug': 'Debug', +'defines tables': 'defines tables', +'Delete': 'Delete', +'delete': 'delete', +'delete all checked': 'delete all checked', +'delete plugin': 'delete plugin', +'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)', +'Delete:': 'Delete:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'deploy', +'Deploy on Google App Engine': 'Deploy on Google App Engine', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description:': 'Description:', +'design': 'дизайн', +'DESIGN': 'DESIGN', +'Design for': 'Design for', +'Detailed traceback description': 'Detailed traceback description', +'details': 'details', +'direction: ltr': 'direction: ltr', +'directory not found': 'directory not found', +'Disable': 'Disable', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'docs', +'Docs': 'Docs', +'done!': 'готово!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'download layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'download plugins', +'Download plugins from repository': 'Download plugins from repository', +'EDIT': 'EDIT', +'Edit': 'edit', +'edit all': 'edit all', +'Edit application': 'Edit application', +'edit controller': 'edit controller', +'edit controller:': 'edit controller:', +'Edit current record': 'Edit current record', +'edit views:': 'edit views:', +'Editing %s': 'Editing %s', +'Editing file': 'Editing file', +'Editing file "%s"': 'Editing file "%s"', +'Editing Language file': 'Editing Language file', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Enable', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Enterprise Web Framework': 'Enterprise Web Framework', +'Error': 'Error', +'Error logs for "%(app)s"': 'Error logs for "%(app)s"', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Error ticket', +'Errors': 'errors', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Exception instance attributes', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'export as csv file', +'Exports:': 'Exports:', +'exposes': 'exposes', +'exposes:': 'exposes:', +'extends': 'extends', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module': 'failed to reload module', +'failed to reload module because:': 'failed to reload module because:', +'File': 'File', +'file "%(filename)s" created': 'file "%(filename)s" created', +'file "%(filename)s" deleted': 'file "%(filename)s" deleted', +'file "%(filename)s" uploaded': 'file "%(filename)s" uploaded', +'file "%(filename)s" was not deleted': 'file "%(filename)s" was not deleted', +'file "%s" of %s restored': 'file "%s" of %s restored', +'file changed on disk': 'file changed on disk', +'file does not exist': 'file does not exist', +'file not found': 'file not found', +'file saved on %(time)s': 'file saved on %(time)s', +'file saved on %s': 'file saved on %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'filter', +'Find Next': 'Find Next', +'Find Previous': 'Find Previous', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': 'Functions with no doctests will result in [passed] tests.', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Get from URL:': 'Get from URL:', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Hello World': 'Здравей, свят', +'Help': 'help', +'here': 'here', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'htmledit': 'htmledit', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Import/Export', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'includes', +'Indent with tabs': 'Indent with tabs', +'insert new': 'insert new', +'insert new %s': 'insert new %s', +'inspect attributes': 'inspect attributes', +'Install': 'install', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Installed applications', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'internal error', +'internal error: %s': 'internal error: %s', +'Internal State': 'Internal State', +'Invalid action': 'Invalid action', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'invalid password', +'invalid password.': 'invalid password.', +'Invalid Query': 'Невалидна заявка', +'invalid request': 'невалидна заявка', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'invalid ticket', +'Key': 'Key', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'language file "%(filename)s" created/updated', +'Language files (static strings) updated': 'Language files (static strings) updated', +'languages': 'languages', +'Languages': 'Languages', +'languages updated': 'languages updated', +'Last Revision': 'Last Revision', +'Last saved on:': 'Last saved on:', +'License for': 'License for', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Loading...': 'Loading...', +'loading...': 'loading...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'Login': 'Login', +'login': 'login', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Login to the Administrative Interface', +'Login/Register': 'Login/Register', +'Logout': 'logout', +'lost password': 'lost password', +'Main Menu': 'Main Menu', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Memberships': 'Memberships', +'merge': 'merge', +'Models': 'Models', +'models': 'models', +'Modified On': 'Modified On', +'Modules': 'Modules', +'modules': 'modules', +'Multi User Mode': 'Multi User Mode', +'new application "%s" created': 'new application "%s" created', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'New Application Wizard', +'New application wizard': 'New application wizard', +'new plugin installed': 'new plugin installed', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'New Record', +'new record inserted': 'новият запис беше добавен', +'New simple application': 'New simple application', +'next': 'next', +'next %s rows': 'next %s rows', +'next 100 rows': 'next 100 rows', +'NO': 'NO', +'no changes': 'no changes', +'No databases in this application': 'No databases in this application', +'No Interaction yet': 'No Interaction yet', +'no match': 'no match', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'or import from csv file', +'or provide app url:': 'or provide app url:', +'or provide application url:': 'or provide application url:', +'Original/Translation': 'Original/Translation', +'Overview': 'Overview', +'Overwrite installed app': 'overwrite installed app', +'Pack all': 'pack all', +'Pack compiled': 'pack compiled', +'Pack custom': 'Pack custom', +'pack plugin': 'pack plugin', +'PAM authenticated user, cannot change password here': 'PAM authenticated user, cannot change password here', +'password changed': 'password changed', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Peeking at file', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Please', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" deleted', +'Plugin "%s" in application': 'Plugin "%s" in application', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'plugins', +'Plugins': 'Plugins', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Powered by', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'previous 100 rows', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Project Progress', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Query:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Record': 'Record', +'record': 'record', +'record does not exist': 'записът не съществува', +'record id': 'record id', +'Record id': 'Record id', +'refresh': 'refresh', +'register': 'register', +'Reload routes': 'Reload routes', +'Remove compiled': 'remove compiled', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Replace', +'Replace All': 'Replace All', +'Repository (%s)': 'Repository (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Resolve Conflict file': 'Resolve Conflict file', +'response': 'response', +'restart': 'restart', +'restore': 'restore', +'return': 'return', +'Revert': 'Revert', +'revert': 'revert', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Role', +'Roles': 'Roles', +'Rows in table': 'Rows in table', +'Rows in Table': 'Rows in Table', +'Rows selected': 'Rows selected', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'Running on %s', +'Save': 'Save', +'save': 'save', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Save via Ajax', +'Saved file hash:': 'Saved file hash:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'selected': 'selected', +'session': 'session', +'session expired': 'session expired', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'shell', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'site', +'Size of cache:': 'Size of cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': 'some files could not be removed', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Start a new app', +'Start searching': 'Start searching', +'Start wizard': 'start wizard', +'state': 'състояние', +'Static': 'Static', +'static': 'static', +'Static files': 'Static files', +'Statistics': 'Statistics', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'submit': 'submit', +'Submit': 'Submit', +'successful': 'successful', +'Sure you want to delete this object?': 'Сигурен ли си, че искаш да изтриеш този обект?', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': 'table', +'Table': 'Table', +'Temporary': 'Temporary', +'test': 'test', +'Testing application': 'Testing application', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'the application logic, each URL path is mapped in one exposed function in the controller': 'the application logic, each URL path is mapped in one exposed function in the controller', +'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller', +'the data representation, define database tables and sets': 'the data representation, define database tables and sets', +'The data representation, define database tables and sets': 'The data representation, define database tables and sets', +'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates', +'the presentations layer, views are also known as templates': 'the presentations layer, views are also known as templates', +'Theme': 'Theme', +'There are no controllers': 'There are no controllers', +'There are no models': 'There are no models', +'There are no modules': 'There are no modules', +'There are no plugins': 'There are no plugins', +'There are no private files': 'There are no private files', +'There are no static files': 'There are no static files', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'There are no translators, only default language is supported', +'There are no views': 'There are no views', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'These files are served without processing, your images go here', +'these files are served without processing, your images go here': 'these files are served without processing, your images go here', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': 'This is the %(filename)s template', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Ticket', +'Ticket ID': 'Ticket ID', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'TM': 'TM', +'to previous version.': 'to previous version.', +'To create a plugin, name a file/folder plugin_[name]': 'To create a plugin, name a file/folder plugin_[name]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'translation strings for the application': 'translation strings for the application', +'Translation strings for the application': 'Translation strings for the application', +'try': 'try', +'try something like': 'try something like', +'Try the mobile interface': 'Try the mobile interface', +'try view': 'try view', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Unable to check for upgrades', +'unable to create application "%s"': 'unable to create application "%s"', +'unable to delete file "%(filename)s"': 'unable to delete file "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'unable to delete file plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download': 'Unable to download', +'Unable to download app because:': 'Unable to download app because:', +'Unable to download because': 'Unable to download because', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'не е възможна обработката на csv файла', +'unable to uninstall "%s"': 'unable to uninstall "%s"', +'unable to upgrade because "%s"': 'unable to upgrade because "%s"', +'uncheck all': 'uncheck all', +'Uninstall': 'uninstall', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'update', +'update all languages': 'update all languages', +'Update:': 'Update:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'upgrade now to %s', +'upgrade web2py now': 'upgrade web2py now', +'upload': 'upload', +'Upload': 'Upload', +'Upload & install packed application': 'Upload & install packed application', +'Upload a package:': 'Upload a package:', +'Upload and install packed application': 'Upload and install packed application', +'upload application:': 'upload application:', +'Upload existing application': 'Upload existing application', +'upload file:': 'upload file:', +'upload plugin file:': 'upload plugin file:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.', +'Use an url:': 'Use an url:', +'User': 'User', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'variables', +'Version': 'Version', +'Versioning': 'Versioning', +'versioning': 'versioning', +'view': 'view', +'Views': 'Views', +'views': 'views', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py is up to date', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'web2py Recent Tweets', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py upgraded; please restart it', +'Welcome to web2py': 'Добре дошъл в web2py', +'Working...': 'Working...', +'WSGI reference name': 'WSGI reference name', +'YES': 'YES', +'Yes': 'Yes', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/cs.py b/web2py/applications/admin/languages/cs.py new file mode 100644 index 0000000..e4667c2 --- /dev/null +++ b/web2py/applications/admin/languages/cs.py @@ -0,0 +1,716 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'cs-cz', +'!langname!': 'čeština', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': 'Kolonka "Upravit" je nepovinný výraz, například "pole1=\'nováhodnota\'". Výsledky databázového JOINu nemůžete mazat ani upravovat.', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'"User Exception" debug mode. An error ticket could be issued!': '"User Exception" debug mode. An error ticket could be issued!', +'%%{Row} in Table': '%%{řádek} v tabulce', +'%%{Row} selected': 'označených %%{řádek}', +'%s': '%s', +'%s %%{row} deleted': '%s smazaných %%{záznam}', +'%s %%{row} updated': '%s upravených %%{záznam}', +'%s selected': '%s označených', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%d.%m.%Y', +'%Y-%m-%d %H:%M:%S': '%d.%m.%Y %H:%M:%S', +'(requires internet access)': '(vyžaduje připojení k internetu)', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(například "cs-cs")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(soubor **gluon/contrib/plural_rules/%s.py** nenalezen)', +'@markmin\x01Searching: **%s** %%{file}': 'Hledání: **%s** %%{soubor}', +'Abort': 'Abort', +'About': 'O programu', +'About application': 'O aplikaci', +'Accept Terms': 'Accept Terms', +'Access Control': 'Řízení přístupu', +'Add breakpoint': 'Přidat bod přerušení', +'Additional code for your application': 'Další kód pro Vaši aplikaci', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'admin disabled because no admin password', +'admin disabled because not supported on google app engine': 'admin disabled because not supported on google app engine', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'admin disabled because unable to access password file', +'Admin is disabled because insecure channel': 'Admin is disabled because insecure channel', +'Admin language': 'jazyk rozhraní', +'Admin versioning page': 'Admin versioning page', +'Administrative interface': 'pro administrátorské rozhraní klikněte sem', +'Administrative Interface': 'Administrátorské rozhraní', +'administrative interface': 'rozhraní pro správu', +'Administrator Password:': 'Administrátorské heslo:', +'Ajax Recipes': 'Recepty s ajaxem', +'An error occured, please %s the page': 'An error occured, please %s the page', +'and rename it:': 'a přejmenovat na:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'appadmin je zakázaná bez zabezpečeného spojení', +'Application': 'Application', +'application "%s" uninstalled': 'application "%s" odinstalována', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'aplikace zkompilována', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'application is compiled and cannot be designed', +'Application name:': 'Název aplikace:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'nepoužita', +'are not used yet': 'ještě nepoužita', +'Are you sure you want to delete file "%s"?': 'Are you sure you want to delete file "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Are you sure you want to delete plugin "%s"?', +'Are you sure you want to delete this object?': 'Opravdu chcete odstranit tento objekt?', +'Are you sure you want to uninstall application "%s"?': 'Opravdu chcete odinstalovat aplikaci "%s"?', +'Are you sure?': 'Are you sure?', +'arguments': 'arguments', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.', +'ATTENTION: you cannot edit the running application!': 'ATTENTION: you cannot edit the running application!', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available Databases and Tables': 'Dostupné databáze a tabulky', +'back': 'zpět', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'Begin': 'Začít', +'breakpoint': 'bod přerušení', +'Breakpoints': 'Body přerušení', +'breakpoints': 'body přerušení', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Buy this book': 'Koupit web2py knihu', +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Klíče cache', +'cache, errors and sessions cleaned': 'cache, chyby a relace byly pročištěny', +'can be a git repo': 'může to být git repo', +'Cancel': 'Storno', +'Cannot be empty': 'Nemůže být prázdné', +'Cannot compile: there are errors in your app:': 'Cannot compile: there are errors in your app:', +'cannot create file': 'cannot create file', +'cannot upload file "%(filename)s"': 'cannot upload file "%(filename)s"', +'Change Admin Password': 'Změnit heslo pro správu', +'Change admin password': 'Změnit heslo pro správu aplikací', +'change editor settings': 'change editor settings', +'Change password': 'Změna hesla', +'Changelog': 'Changelog', +'check all': 'vše označit', +'Check for upgrades': 'Zkusit aktualizovat', +'Check to delete': 'Označit ke smazání', +'Check to delete:': 'Označit ke smazání:', +'Checking for upgrades...': 'Zjišťuji, zda jsou k dispozici aktualizace...', +'Clean': 'Pročistit', +'Clear': 'Clear', +'Clear CACHE?': 'Vymazat CACHE?', +'Clear DISK': 'Vymazat DISK', +'Clear RAM': 'Vymazat RAM', +'Click row to expand traceback': 'Pro rozbalení stopy, klikněte na řádek', +'Click row to view a ticket': 'Pro zobrazení chyby (ticketu), klikněte na řádku...', +'Client IP': 'IP adresa klienta', +'code': 'code', +'Code listing': 'Code listing', +'collapse/expand all': 'vše sbalit/rozbalit', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Community': 'Komunita', +'Compile': 'Zkompilovat', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'zkompilovaná aplikace smazána', +'Components and Plugins': 'Komponenty a zásuvné moduly', +'Condition': 'Podmínka', +'continue': 'continue', +'Controller': 'Kontrolér (Controller)', +'Controllers': 'Kontroléry', +'controllers': 'kontroléry', +'Copyright': 'Copyright', +'Count': 'Počet', +'Create': 'Vytvořit', +'create file with filename:': 'vytvořit soubor s názvem:', +'Create/Upload': 'Create/Upload', +'created by': 'vytvořil', +'Created By': 'Vytvořeno - kým', +'Created by:': 'Created by:', +'Created On': 'Vytvořeno - kdy', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Aktuální požadavek', +'Current response': 'Aktuální odpověď', +'Current session': 'Aktuální relace', +'currently running': 'právě běží', +'currently saved or': 'uloženo nebo', +'customize me!': 'upravte mě!', +'data uploaded': 'data nahrána', +'Database': 'Rozhraní databáze', +'Database %s select': 'databáze %s výběr', +'Database administration': 'Database administration', +'database administration': 'správa databáze', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Datum a čas', +'day': 'den', +'db': 'db', +'DB Model': 'Databázový model', +'Debug': 'Ladění', +'defines tables': 'defines tables', +'Delete': 'Smazat', +'delete': 'smazat', +'delete all checked': 'smazat vše označené', +'delete plugin': 'delete plugin', +'Delete this file (you will be asked to confirm deletion)': 'Smazat tento soubor (budete požádán o potvrzení mazání)', +'Delete:': 'Smazat:', +'deleted after first hit': 'smazat po prvním dosažení', +'Demo': 'Demo', +'Deploy': 'Nahrát', +'Deploy on Google App Engine': 'Nahrát na Google App Engine', +'Deploy to OpenShift': 'Nahrát na OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Deployment Recipes': 'Postupy pro deployment', +'Description': 'Popis', +'Description:': 'Description:', +'design': 'návrh', +'Detailed traceback description': 'Podrobný výpis prostředí', +'details': 'podrobnosti', +'direction: ltr': 'směr: ltr', +'directory not found': 'directory not found', +'Disable': 'Zablokovat', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Klíče diskové cache', +'Disk Cleared': 'Disk smazán', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'dokumentace', +'Docs': 'Docs', +'Documentation': 'Dokumentace', +"Don't know what to do?": 'Nevíte kudy kam?', +'done!': 'hotovo!', +'Downgrade': 'Downgrade', +'Download': 'Stáhnout', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'stáhnout moduly rozvržení stránky', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'stáhnout zásuvné moduly', +'Download plugins from repository': 'Download plugins from repository', +'E-mail': 'E-mail', +'Edit': 'Upravit', +'edit all': 'edit all', +'Edit application': 'Správa aplikace', +'edit controller': 'edit controller', +'edit controller:': 'edit controller:', +'Edit current record': 'Upravit aktuální záznam', +'Edit Profile': 'Upravit profil', +'edit views:': 'upravit pohled:', +'Editing %s': 'Editing %s', +'Editing file "%s"': 'Úprava souboru "%s"', +'Editing Language file': 'Úprava jazykového souboru', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Email and SMS': 'Email a SMS', +'Enable': 'Odblokovat', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'enter a number between %(min)g and %(max)g': 'zadejte číslo mezi %(min)g a %(max)g', +'enter an integer between %(min)g and %(max)g': 'zadejte celé číslo mezi %(min)g a %(max)g', +'Error': 'Chyba', +'Error logs for "%(app)s"': 'Seznam výskytu chyb pro aplikaci "%(app)s"', +'Error snapshot': 'Snapshot chyby', +'Error ticket': 'Ticket chyby', +'Errors': 'Chyby', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Prvky instance výjimky', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation': 'Expand Abbreviation', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'exportovat do .csv souboru', +'Exports:': 'Exports:', +'exposes': 'vystavuje', +'exposes:': 'vystavuje funkce:', +'extends': 'rozšiřuje', +'failed to compile file because:': 'soubor se nepodařilo zkompilovat, protože:', +'failed to reload module because:': 'failed to reload module because:', +'FAQ': 'Často kladené dotazy', +'File': 'Soubor', +'file': 'soubor', +'file "%(filename)s" created': 'file "%(filename)s" created', +'file "%(filename)s" deleted': 'file "%(filename)s" deleted', +'file "%(filename)s" uploaded': 'file "%(filename)s" uploaded', +'file "%s" of %s restored': 'file "%s" of %s restored', +'file changed on disk': 'file changed on disk', +'file does not exist': 'file does not exist', +'file not found': 'file not found', +'file saved on %(time)s': 'soubor uložen %(time)s', +'file saved on %s': 'soubor uložen %s', +'filename': 'filename', +'Filename': 'Název souboru', +'Files added': 'Files added', +'filter': 'filtr', +'Find Next': 'Najít další', +'Find Previous': 'Najít předchozí', +'First name': 'Křestní jméno', +'Forgot username?': 'Zapomněl jste svoje přihlašovací jméno?', +'forgot username?': 'zapomněl jste svoje přihlašovací jméno?', +'Form has errors': 'Form has errors', +'Forms and Validators': 'Formuláře a validátory', +'Frames': 'Frames', +'Free Applications': 'Aplikace zdarma', +'Functions with no doctests will result in [passed] tests.': 'Functions with no doctests will result in [passed] tests.', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Vytvořit', +'Get from URL:': 'Stáhnout z internetu:', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globální proměnné', +'go!': 'OK!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Group %(group_id)s created': 'Skupina %(group_id)s vytvořena', +'Group ID': 'ID skupiny', +'Groups': 'Skupiny', +'Hello World': 'Ahoj světe', +'Help': 'Nápověda', +'here': 'here', +'Hide/Show Translated strings': 'Skrýt/Zobrazit přeložené texty', +'Highlight current line': 'Highlight current line', +'Hits': 'Kolikrát dosaženo', +'Home': 'Domovská stránka', +'honored only if the expression evaluates to true': 'brát v potaz jen když se tato podmínka vyhodnotí kladně', +'How did you get here?': 'Jak jste se sem vlastně dostal?', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Import/Export', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'zahrnuje', +'Indent with tabs': 'Indent with tabs', +'Index': 'Index', +'insert new': 'vložit nový záznam ', +'insert new %s': 'vložit nový záznam %s', +'inspect attributes': 'inspect attributes', +'Install': 'Instalovat', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Nainstalované aplikace', +'Interaction at %s line %s': 'Interakce v %s, na řádce %s', +'Interactive console': 'Interaktivní příkazová řádka', +'internal error': 'internal error', +'internal error: %s': 'internal error: %s', +'Internal State': 'Vnitřní stav', +'Introduction': 'Úvod', +'Invalid action': 'Invalid action', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid email': 'Neplatný email', +'Invalid git repository specified.': 'Invalid git repository specified.', +'Invalid password': 'Nesprávné heslo', +'invalid password': 'invalid password', +'invalid password.': 'neplatné heslo', +'Invalid Query': 'Neplatný dotaz', +'invalid request': 'Neplatný požadavek', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'invalid ticket', +'Is Active': 'Je aktivní', +'It is %s %%{day} today.': 'Dnes je to %s %%{den}.', +'Key': 'Klíč', +'Key bindings': 'Vazby klíčů', +'Key bindings for ZenCoding Plugin': 'Key bindings for ZenCoding Plugin', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'language file "%(filename)s" created/updated', +'Language files (static strings) updated': 'Language files (static strings) updated', +'languages': 'jazyky', +'Languages': 'Jazyky', +'Last name': 'Příjmení', +'Last Revision': 'Last Revision', +'Last saved on:': 'Naposledy uloženo:', +'Layout': 'Rozvržení stránky (layout)', +'Layout Plugins': 'Moduly rozvržení stránky (Layout Plugins)', +'Layouts': 'Rozvržení stránek', +'License for': 'Licence pro', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Číslo řádku', +'LineNo': 'Č.řádku', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Live Chat': 'Online pokec', +'Loading...': 'Loading...', +'loading...': 'nahrávám...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Lokální proměnné', +'Logged in': 'Přihlášení proběhlo úspěšně', +'Logged out': 'Odhlášení proběhlo úspěšně', +'login': 'přihlásit se', +'Login': 'Přihlásit se', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Přihlásit se do Správce aplikací', +'Login/Register': 'Login/Register', +'logout': 'odhlásit se', +'Logout': 'Odhlásit se', +'lost password': 'lost password', +'Lost Password': 'Zapomněl jste heslo', +'Lost password?': 'Zapomněl jste heslo?', +'lost password?': 'zapomněl jste heslo?', +'Main Menu': 'Main Menu', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Memberships': 'Memberships', +'Menu Model': 'Model rozbalovací nabídky', +'merge': 'merge', +'Models': 'Modely', +'models': 'modely', +'Modified By': 'Změněno - kým', +'Modified On': 'Změněno - kdy', +'Modules': 'Moduly', +'modules': 'moduly', +'Multi User Mode': 'Multi User Mode', +'My Sites': 'Správa aplikací', +'Name': 'Jméno', +'new application "%s" created': 'nová aplikace "%s" vytvořena', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'Nový průvodce aplikací', +'New application wizard': 'Nový průvodce aplikací', +'New password': 'Nové heslo', +'new plugin installed': 'new plugin installed', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'Nový záznam', +'new record inserted': 'nový záznam byl založen', +'New simple application': 'Vytvořit primitivní aplikaci', +'next': 'next', +'next %s rows': 'next %s rows', +'next 100 rows': 'dalších 100 řádků', +'NO': 'NO', +'no changes': 'no changes', +'No databases in this application': 'V této aplikaci nejsou žádné databáze', +'No Interaction yet': 'Ještě žádná interakce nenastala', +'no match': 'no match', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'No ticket_storage.txt found under /private folder': 'Soubor ticket_storage.txt v adresáři /private nenalezen', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +'Object or table name': 'Objekt či tabulka', +'Old password': 'Původní heslo', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'online designer': 'online návrhář', +'Online examples': 'Příklady online', +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'nebo importovat z .csv souboru', +'Origin': 'Původ', +'Original/Translation': 'Originál/Překlad', +'Other Plugins': 'Ostatní moduly', +'Other Recipes': 'Ostatní zásuvné moduly', +'Overview': 'Přehled', +'Overwrite installed app': 'Přepsat instalovanou aplikaci', +'Pack all': 'Zabalit', +'Pack compiled': 'Zabalit zkompilované', +'Pack custom': 'Pack custom', +'pack plugin': 'pack plugin', +'Password': 'Heslo', +'password': 'heslo', +'password changed': 'password changed', +"Password fields don't match": 'Hesla se neshodují', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Peeking at file', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Prosím', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" deleted', +'Plugin "%s" in application': 'Plugin "%s" in application', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'zásuvné moduly', +'Plugins': 'Zásuvné moduly', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Množná čísla:', +'Powered by': 'Poháněno', +'Preface': 'Předmluva', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'předchozích 100 řádků', +'Private files': 'Soukromé soubory', +'private files': 'soukromé soubory', +'profile': 'profil', +'Project Progress': 'Vývoj projektu', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Dotaz:', +'Quick Examples': 'Krátké příklady', +'RAM': 'RAM', +'RAM Cache Keys': 'Klíče RAM Cache', +'Ram Cleared': 'RAM smazána', +'Rapid Search': 'Rapid Search', +'Readme': 'Nápověda', +'Recipes': 'Postupy jak na to', +'Record': 'Záznam', +'record does not exist': 'záznam neexistuje', +'Record ID': 'ID záznamu', +'Record id': 'id záznamu', +'refresh': 'obnovte', +'register': 'registrovat', +'Register': 'Zaregistrovat se', +'Registration identifier': 'Registrační identifikátor', +'Registration key': 'Registrační klíč', +'reload': 'reload', +'Reload routes': 'Znovu nahrát cesty', +'Remember me (for 30 days)': 'Zapamatovat na 30 dní', +'Remove compiled': 'Odstranit zkompilované', +'Removed Breakpoint on %s at line %s': 'Bod přerušení smazán - soubor %s na řádce %s', +'Replace': 'Zaměnit', +'Replace All': 'Zaměnit vše', +'Repository (%s)': 'Repository (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Reset Password key': 'Reset registračního klíče', +'Resolve Conflict file': 'Resolve Conflict file', +'response': 'response', +'restart': 'restart', +'restore': 'obnovit', +'Retrieve username': 'Získat přihlašovací jméno', +'return': 'return', +'Revert': 'Revert', +'revert': 'vrátit se k původnímu', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Záznamy v tabulce', +'Rows selected': 'Záznamů zobrazeno', +'rules are not defined': 'pravidla nejsou definována', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Spustí testy v tomto souboru (ke spuštění všech testů, použijte tlačítko 'test')", +'Running on %s': 'Běží na %s', +'Save': 'Uložit', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Uložit pomocí Ajaxu', +'Saved file hash:': 'hash uloženého souboru:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'Semantic': 'Modul semantic', +'Services': 'Služby', +'session': 'session', +'session expired': 'session expired', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Bod přerušení nastaven v souboru %s na řádce %s: %s', +'shell': 'příkazová řádka', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'Správa aplikací', +'Size of cache:': 'Velikost cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': 'some files could not be removed', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Bohužel mercurial není nainstalován.', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Vytvořit novou aplikaci', +'Start searching': 'Začít hledání', +'Start wizard': 'Spustit průvodce', +'state': 'stav', +'Static': 'Static', +'static': 'statické soubory', +'Static files': 'Statické soubory', +'Statistics': 'Statistika', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'Stylesheet': 'CSS styly', +'submit': 'odeslat', +'Submit': 'Odeslat', +'successful': 'úspěšně', +'Support': 'Podpora', +'Sure you want to delete this object?': 'Opravdu chcete smazat tento objekt?', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'Table': 'tabulka', +'Table name': 'Název tabulky', +'Temporary': 'Dočasný', +'test': 'test', +'Testing application': 'Testing application', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"Dotaz" je podmínka, například "db.tabulka1.pole1==\'hodnota\'". Podmínka "db.tabulka1.pole1==db.tabulka2.pole2" pak vytvoří SQL JOIN.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'The application logic, each URL path is mapped in one exposed function in the controller': 'Logika aplikace: každá URL je mapována na funkci vystavovanou kontrolérem.', +'The Core': 'Jádro (The Core)', +'The data representation, define database tables and sets': 'Reprezentace dat: definovat tabulky databáze a záznamy', +'The output of the file is a dictionary that was rendered by the view %s': 'Výstup ze souboru je slovník, který se zobrazil v pohledu %s.', +'The presentations layer, views are also known as templates': 'Prezentační vrstva: pohledy či templaty (šablony)', +'The Views': 'Pohledy (The Views)', +'Theme': 'Theme', +'There are no controllers': 'There are no controllers', +'There are no models': 'There are no models', +'There are no modules': 'There are no modules', +'There are no plugins': 'Žádné moduly nejsou instalovány.', +'There are no private files': 'Žádné soukromé soubory neexistují.', +'There are no static files': 'There are no static files', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'There are no translators, only default language is supported', +'There are no views': 'There are no views', +'These files are not served, they are only available from within your app': 'Tyto soubory jsou klientům nepřístupné. K dispozici jsou pouze v rámci aplikace.', +'These files are served without processing, your images go here': 'Tyto soubory jsou servírovány bez přídavné logiky, sem patří např. obrázky.', +'This App': 'Tato aplikace', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is a copy of the scaffolding application': 'Toto je kopie aplikace skelet.', +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': 'This is the %(filename)s template', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'tuto stránku, abyste uviděli, zda se dosáhlo bodu přerušení.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Ticket', +'Ticket ID': 'Ticket ID', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Čas v Cache (h:m:s)', +'Timestamp': 'Časové razítko', +'to previous version.': 'k předchozí verzi.', +'To create a plugin, name a file/folder plugin_[name]': 'Zásuvný modul vytvoříte tak, že pojmenujete soubor/adresář plugin_[jméno modulu]', +'To emulate a breakpoint programatically, write:': 'K nastavení bodu přerušení v kódu programu, napište:', +'to use the debugger!': ', abyste mohli ladící program používat!', +'toggle breakpoint': 'vyp./zap. bod přerušení', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Na celou obrazovku a zpět', +'too short': 'Příliš krátké', +'Traceback': 'Traceback', +'Translation strings for the application': 'Překlad textů pro aplikaci', +'try something like': 'try something like', +'Try the mobile interface': 'Zkuste rozhraní pro mobilní zařízení', +'try view': 'try view', +'Twitter': 'Twitter', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type python statement in here and hit Return (Enter) to execute it.': 'Type python statement in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Unable to check for upgrades', +'unable to create application "%s"': 'unable to create application "%s"', +'unable to delete file "%(filename)s"': 'unable to delete file "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'unable to delete file plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download app because:': 'Unable to download app because:', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'csv soubor nedá sa zpracovat', +'unable to uninstall "%s"': 'unable to uninstall "%s"', +'unable to upgrade because "%s"': 'unable to upgrade because "%s"', +'uncheck all': 'vše odznačit', +'Uninstall': 'Odinstalovat', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'aktualizovat', +'update all languages': 'aktualizovat všechny jazyky', +'Update:': 'Upravit:', +'Upgrade': 'Upgrade', +'upgrade now': 'upgrade now', +'upgrade now to %s': 'upgrade now to %s', +'upload': 'nahrát', +'Upload': 'Upload', +'Upload a package:': 'Nahrát balík:', +'Upload and install packed application': 'Nahrát a instalovat zabalenou aplikaci', +'upload file:': 'nahrát soubor:', +'upload plugin file:': 'nahrát soubor modulu:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Použijte (...)&(...) pro AND, (...)|(...) pro OR a ~(...) pro NOT pro sestavení složitějších dotazů.', +'User': 'User', +'User %(id)s Logged-in': 'Uživatel %(id)s přihlášen', +'User %(id)s Logged-out': 'Uživatel %(id)s odhlášen', +'User %(id)s Password changed': 'Uživatel %(id)s změnil heslo', +'User %(id)s Profile updated': 'Uživatel %(id)s upravil profil', +'User %(id)s Registered': 'Uživatel %(id)s se zaregistroval', +'User %(id)s Username retrieved': 'Uživatel %(id)s si nachal zaslat přihlašovací jméno', +'User ID': 'ID uživatele', +'Username': 'Přihlašovací jméno', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'variables', +'Verify Password': 'Zopakujte heslo', +'Version': 'Verze', +'Version %s.%s.%s (%s) %s': 'Verze %s.%s.%s (%s) %s', +'Versioning': 'Verzování', +'Videos': 'Videa', +'View': 'Pohled (View)', +'Views': 'Pohledy', +'views': 'pohledy', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'Máte aktuální verzi web2py.', +'web2py online debugger': 'Ladící online web2py program', +'web2py Recent Tweets': 'Štěbetání na Twitteru o web2py', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py upgraded; please restart it', +'Welcome': 'Vítejte', +'Welcome to web2py': 'Vitejte ve web2py', +'Welcome to web2py!': 'Vítejte ve web2py!', +'Which called the function %s located in the file %s': 'která zavolala funkci %s v souboru (kontroléru) %s.', +'Working...': 'Working...', +'WSGI reference name': 'WSGI reference name', +'YES': 'YES', +'Yes': 'Yes', +'You are successfully running web2py': 'Úspěšně jste spustili web2py.', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'Nastavovat a mazat body přerušení je též možno v rámci editování zdrojového souboru přes tlačítko Vyp./Zap. bod přerušení', +'You can inspect variables using the console bellow': 'Níže pomocí příkazové řádky si můžete prohlédnout proměnné', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You can modify this application and adapt it to your needs': 'Tuto aplikaci si můžete upravit a přizpůsobit ji svým potřebám.', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'Je třeba nejprve nastavit a dojít až na', +'You only need these if you have already registered': 'You only need these if you have already registered', +'You visited the url %s': 'Navštívili jste stránku %s,', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Aplikace bude blokována než se klikne na jedno z tlačítek (další, krok, pokračovat, atd.)', +} diff --git a/web2py/applications/admin/languages/de.py b/web2py/applications/admin/languages/de.py new file mode 100644 index 0000000..da4fa1a --- /dev/null +++ b/web2py/applications/admin/languages/de.py @@ -0,0 +1,714 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'de', +'!langname!': 'Deutsch', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Update" ist ein optionaler Ausdruck wie "Feld1 = \'newvalue". JOIN Ergebnisse können nicht aktualisiert oder gelöscht werden', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s %%{row} Zeilen gelöscht', +'%s %%{row} updated': '%s %%{row} Zeilen aktualisiert', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%d.%m.%Y', +'%Y-%m-%d %H:%M:%S': '%d.%m.%Y %H:%M:%S', +'(requires internet access)': '(Benötigt Internetzugang)', +'(requires internet access, experimental)': '(Benötigt Internetzugang)', +'(something like "it-it")': '(so etwas wie "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(Datei **gluon/contrib/plural_rules/%s.py** wurde nicht gefunden)', +'@markmin\x01An error occured, please [[reload %s]] the page': 'Ein Fehler ist aufgetreten, bitte [[reload %s]] sie die Seite erneut', +'@markmin\x01Searching: **%s** %%{file}': '@markmin\x01Suche: **%s** Dateien', +'A new version of web2py is available': 'Eine neue Version von web2py ist verfügbar', +'A new version of web2py is available: %s': 'Eine neue Version von web2py ist verfügbar: %s', +'Abort': 'Abbrechen', +'About': 'Über', +'About application': 'Über die Anwendung', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Add breakpoint', +'Additional code for your application': 'Zusätzlicher Code für Ihre Anwendung', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'admin ist deaktiviert, weil kein Admin-Passwort gesetzt ist', +'admin disabled because not supported on google app engine': 'admin disabled because not supported on google app engine', +'admin disabled because not supported on google apps engine': 'admin ist deaktiviert, es existiert dafür keine Unterstützung auf der google apps engine', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'admin ist deaktiviert, weil kein Zugriff auf die Passwortdatei besteht', +'Admin is disabled because insecure channel': 'Appadmin ist deaktiviert, wegen der Benutzung eines unsicheren Kanals', +'Admin is disabled because unsecure channel': 'Appadmin ist deaktiviert, wegen der Benutzung eines unsicheren Kanals', +'Admin language': 'Admin-Sprache', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'Administrative Schnittstelle', +'Administrator Password:': 'Administrator Passwort:', +'An error occured, please %s the page': 'Ein Fehler ist aufgetereten, bitte %s die Seite', +'and rename it (required):': 'und benenne sie um (erforderlich):', +'and rename it:': ' und benenne sie um:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'Appadmin ist deaktiviert, wegen der Benutzung eines unsicheren Kanals', +'Application': 'Anwendung', +'application "%s" uninstalled': 'Anwendung "%s" deinstalliert', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'Anwendung kompiliert', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'Die Anwendung ist kompiliert und kann deswegen nicht mehr geändert werden', +'Application name:': 'Name der Anwendung:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'werden nicht verwendet', +'are not used yet': 'werden bisher nicht verwendet', +'Are you sure you want to delete file "%s"?': 'Sind Sie sich sicher, dass Sie diese Datei löschen wollen "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Are you sure you want to delete plugin "%s"?', +'Are you sure you want to delete this object?': 'Sind Sie sich sicher, dass Sie dieses Objekt löschen wollen?', +'Are you sure you want to uninstall application "%s"': 'Sind Sie sich sicher, dass Sie diese Anwendung deinstallieren wollen "%s"', +'Are you sure you want to uninstall application "%s"?': 'Sind Sie sich sicher, dass Sie diese Anwendung deinstallieren wollen "%s"?', +'Are you sure you want to upgrade web2py now?': 'Sind Sie sich sicher, dass Sie web2py jetzt upgraden möchten?', +'Are you sure?': 'Are you sure?', +'arguments': 'arguments', +'at char %s': 'bei Zeichen %s', +'at line %s': 'in Linie %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ACHTUNG: Die Einwahl benötigt eine sichere (HTTPS) Verbindung. Es sei denn sie läuft Lokal (localhost).', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ACHTUNG: Testen ist nicht threadsicher. Führen Sie also nicht mehrere Tests gleichzeitig aus.', +'ATTENTION: This is an experimental feature and it needs more testing.': 'ACHTUNG: Dies ist eine experimentelle Funktion und benötigt noch weitere Tests.', +'ATTENTION: you cannot edit the running application!': 'ACHTUNG: Eine laufende Anwendung kann nicht editiert werden!', +'Authentication': 'Authentifizierung', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available databases and tables': 'Verfügbare Datenbanken und Tabellen', +'Available Databases and Tables': 'Available Databases and Tables', +'back': 'Zurück', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'beautify': 'Verschönern', +'Begin': 'Begin', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': 'Zwischenspeicher', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'Zwischenspeicher (cache), Fehler und Sitzungen (sessions) gelöscht', +'call': 'Aufruf', +'can be a git repo': 'kann ein git Repository sein', +'Cancel': 'Abbrechen', +'Cannot be empty': 'Darf nicht leer sein', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Nicht Kompilierbar: Es sind Fehler in der Anwendung. Beseitigen Sie die Fehler und versuchen Sie es erneut.', +'Cannot compile: there are errors in your app:': 'Cannot compile: there are errors in your app:', +'cannot create file': 'Kann Datei nicht erstellen', +'cannot upload file "%(filename)s"': 'Kann Datei nicht Hochladen "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'Administrator-Passwort ändern', +'change editor settings': 'Editoreinstellungen ändern', +'Change Password': 'Passwort ändern', +'change password': 'Passwort ändern', +'Changelog': 'Changelog', +'check all': 'alles auswählen', +'Check for upgrades': 'Versionsüberprüfung', +'Check to delete': 'Markiere zum löschen', +'Checking for upgrades...': 'Überprüfe auf Updates...', +'Clean': 'Leeren', +'Clear': 'Clear', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'click here for online examples': 'hier klicken für online Beispiele', +'click here for the administrative interface': 'hier klicken für die Administrationsoberfläche ', +'Click row to expand traceback': 'Klicke auf die Zeile für Fehlerverfolgung', +'Click row to view a ticket': 'Click row to view a ticket', +'click to check for upgrades': 'hier klicken um nach Upgrades zu suchen', +'Client IP': 'Client IP', +'code': 'code', +'Code listing': 'Code listing', +'collapse/expand all': 'alles zu- bzw. aufklappen', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'kompilieren', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'kompilierte Anwendung gelöscht', +'Condition': 'Condition', +'continue': 'continue', +'Controller': 'Controller', +'Controllers': 'Controllers', +'controllers': 'controllers', +'Copyright': 'Urheberrecht', +'Count': 'Anzahl', +'Create': 'Erstellen', +'create file with filename:': 'Erzeuge Datei mit Dateinamen:', +'create new application:': 'Erzeuge neue Anwendung:', +'Create new simple application': 'Erzeuge neue Anwendung', +'Create/Upload': 'Create/Upload', +'created by': 'Erstellt von', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Aktuelle Anfrage (request)', +'Current response': 'Aktuelle Antwort (response)', +'Current session': 'Aktuelle Sitzung (session)', +'currently running': 'aktuell in Betrieb', +'currently saved or': 'des derzeit gespeicherten oder', +'customize me!': 'Pass mich an!', +'data uploaded': 'Daten hochgeladen', +'Database': 'Datenbank', +'database': 'Datenbank', +'Database %s select': 'Database %s select', +'database %s select': 'Datenbank %s ausgewählt', +'Database administration': 'Database administration', +'database administration': 'Datenbankadministration', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Datum und Uhrzeit', +'db': 'db', +'DB Model': 'DB Modell', +'Debug': 'Debug', +'defines tables': 'definiere Tabellen', +'Delete': 'löschen', +'delete': 'löschen', +'delete all checked': 'lösche alle markierten', +'delete plugin': 'Plugin löschen', +'Delete this file (you will be asked to confirm deletion)': 'Diese Datei löschen (mit Bestätigungsdialog)', +'Delete:': 'Löschen:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'Installieren', +'Deploy on Google App Engine': 'Auf Google App Engine installieren', +'Deploy to OpenShift': 'Auf OpenShift installieren', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description': 'Beschreibung', +'Description:': 'Description:', +'design': 'design', +'DESIGN': 'DESIGN', +'Design for': 'Design für', +'Detailed traceback description': 'Detaillierte traceback Beschreibung', +'details': 'details', +'direction: ltr': 'direction: ltr', +'directory not found': 'directory not found', +'Disable': 'Deaktivieren', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'docs', +'Docs': 'Docs', +'documentation': 'Dokumentation', +'done!': 'fertig!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'Layouts herunterladen', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'Plugins herunterladen', +'Download plugins from repository': 'Download plugins from repository', +'E-mail': 'E-mail', +'EDIT': 'BEARBEITEN', +'Edit': 'Bearbeiten', +'edit all': 'edit all', +'Edit application': 'Bearbeite Anwendung', +'edit controller': 'Bearbeite Controller', +'edit controller:': 'bearbeite Controller:', +'Edit current record': 'Bearbeite aktuellen Datensatz', +'Edit Profile': 'Bearbeite Profil', +'edit profile': 'bearbeite Profil', +'Edit This App': 'Bearbeite diese Anwendung', +'edit views:': 'Views bearbeiten:', +'Editing %s': 'Bearbeite %s', +'Editing file': 'Bearbeite Datei', +'Editing file "%s"': 'Bearbeite Datei "%s"', +'Editing Language file': 'Sprachdatei bearbeiten', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Aktivieren', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Enterprise Web Framework': 'Enterprise Web Framework', +'Error': 'Fehler', +'Error logs for "%(app)s"': 'Fehlerprotokoll für "%(app)s"', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Error ticket', +'Errors': 'Fehlermeldungen', +'escape': 'escape', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Attribute der Ausnahmeinstanz', +'Exit Fullscreen': 'Vollbild beenden', +'Expand Abbreviation': 'Kürzel erweitern', +'Expand Abbreviation (html files only)': 'Abkürzungen ausschreiben (nur HTML Dateien)', +'export as csv file': 'Exportieren als CSV-Datei', +'Exports:': 'Exports:', +'exposes': 'stellt zur Verfügung', +'exposes:': 'stellt folgendes zur Verfügung:', +'extends': 'erweitert', +'failed to compile file because:': 'Datei konnte nicht kompiliert werden, da:', +'failed to reload module': 'neu laden des Moduls fehlgeschlagen', +'failed to reload module because:': 'failed to reload module because:', +'File': 'Datei', +'file "%(filename)s" created': 'Datei "%(filename)s" erstellt', +'file "%(filename)s" deleted': 'Datei "%(filename)s" gelöscht', +'file "%(filename)s" uploaded': 'Datei "%(filename)s" hochgeladen', +'file "%(filename)s" was not deleted': 'Datei "%(filename)s" wurde nicht gelöscht', +'file "%s" of %s restored': 'Datei "%s" von %s wiederhergestellt', +'file changed on disk': 'Datei auf Festplatte geändert', +'file does not exist': 'Datei existiert nicht', +'file not found': 'file not found', +'file saved on %(time)s': 'Datei gespeichert am %(time)s', +'file saved on %s': 'Datei gespeichert auf %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'Filter', +'Find Next': 'Nächster', +'Find Previous': 'Vorheriger', +'First name': 'Vorname', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': 'Funktionen ohne doctests erzeugen [passed] in Tests', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Get from URL:': 'Get from URL:', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'Go to Matching Pair': 'Gehe zum übereinstimmenden Paar', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Group ID': 'Gruppen ID', +'Hello World': 'Hallo Welt', +'Help': 'Hilfe', +'here': 'here', +'Hide/Show Translated strings': 'Zeige/Verstecke übersetzte Strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Startseite', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'htmledit': 'htmledit', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Falls der obere Test eine Fehler-Ticketnummer enthält deutet das auf einen Fehler in der Ausführung des Controllers hin, noch bevor der Doctest ausgeführt werden konnte. Gewöhnlich Führen fehlerhafte Einrückungen oder fehlerhafter Code ausserhalb der Funktion zu solchen Fehlern. Ein grüner Titel deutet darauf hin, dass alle Test(wenn sie vorhanden sind) erfolgreich durchlaufen wurden. In diesem Fall werden die Testresultate nicht angezeigt.', +'If you answer "yes", be patient, it may take a while to download': 'Wenn Sie mit "Ja" antworten, seien Sie bitte geduldig. Der Download könnte eine Weile dauern.', +'If you answer yes, be patient, it may take a while to download': 'Wenn Sie mit Ja antworten, seien Sie bitte geduldig. Der Download könnte eine Weile dauern.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Importieren/Exportieren', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'Einfügen', +'Indent with tabs': 'Indent with tabs', +'Index': 'Index', +'index': 'index', +'insert new': 'neu Einfügen', +'insert new %s': 'neu Einfügen %s', +'inspect attributes': 'Attribute inspizieren', +'Install': 'Installieren', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Installierte Anwendungen', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'Interner Fehler', +'internal error: %s': 'internal error: %s', +'Internal State': 'Interner Status', +'Invalid action': 'Ungültige Aktion', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid email': 'Ungültige Email', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'Ungültiges Passwort', +'invalid password.': 'invalid password.', +'Invalid Query': 'Ungültige Abfrage', +'invalid request': 'Ungültige Anfrage', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'Ungültiges Ticket', +'Key': 'Key', +'Key bindings': 'Tastenbelegungen', +'Key bindings for ZenCoding Plugin': 'Key bindings for ZenCoding Plugin', +'Key bindings for ZenConding Plugin': 'Tastenbelegungen für das ZenConding Plugin', +'Keyboard shortcuts': 'Tastenkombination', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'Sprachdatei "%(filename)s" erstellt/aktualisiert', +'Language files (static strings) updated': 'Sprachdatei (statisch Strings) aktualisiert', +'languages': 'Sprachen', +'Languages': 'Sprachen', +'languages updated': 'Sprachen aktualisiert', +'Last name': 'Nachname', +'Last Revision': 'Last Revision', +'Last saved on:': 'Zuletzt gespeichert am:', +'Layout': 'Layout', +'License for': 'Lizenz für', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'nach Ticket aufgelistet', +'Loading...': 'Loading...', +'loading...': 'lade...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'located in the file': 'befindet sich in der Datei', +'login': 'anmelden', +'Login': 'Anmelden', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'An das Administrations-Interface anmelden', +'Login/Register': 'Login/Register', +'Logout': 'Abmelden', +'lost password': 'lost password', +'Lost Password': 'Passwort vergessen', +'lost password?': 'Passwort vergessen?', +'Main Menu': 'Hauptmenü', +'Manage': 'Verwalten', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Match Pair': 'Paare finden', +'Memberships': 'Memberships', +'Menu Model': 'Menü Modell', +'merge': 'verbinden', +'Merge Lines': 'Zeilen zusammenfügen', +'Models': 'Modelle', +'models': 'Modelle', +'Modified On': 'Modified On', +'Modules': 'Module', +'modules': 'Module', +'Multi User Mode': 'Multi User Mode', +'Name': 'Name', +'new application "%s" created': 'neue Anwendung "%s" erzeugt', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'New Application Wizard', +'New application wizard': 'Neue Anwendung per Assistent', +'new plugin installed': 'Neues Plugin wurde installiert', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'Neuer Datensatz', +'new record inserted': 'Neuer wurde Datensatz eingefügt', +'New simple application': 'Neue einfache Anwendung', +'next': 'next', +'next %s rows': 'next %s rows', +'next 100 rows': 'nächsten 100 Zeilen', +'Next Edit Point': 'nächster Bearbeitungsschritt', +'NO': 'NEIN', +'no changes': 'no changes', +'No databases in this application': 'Keine Datenbank in dieser Anwendung', +'No Interaction yet': 'No Interaction yet', +'no match': 'no match', +'no package selected': 'Kein Paket ausgewählt', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'No ticket_storage.txt found under /private folder': 'Kein ticket_storage.txt unter /private folder gefunden', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'online designer': 'Online Designer', +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'oder Alternativ', +'Or Get from URL:': 'oder von folgender URL herunterladen:', +'or import from csv file': 'oder importieren von cvs Datei', +'or provide app url:': 'oder geben Sie eine Anwendungs-URL an:', +'or provide application url:': 'oder geben Sie eine Anwendungs-URL an:', +'Origin': 'Herkunft', +'Original/Translation': 'Original/übersetzung', +'Overview': 'Overview', +'Overwrite installed app': 'Installierte Anwendungen überschreiben', +'Pack all': 'Verpacke alles', +'Pack compiled': 'Verpacke kompiliert', +'Pack custom': 'Verpacke individuell', +'pack plugin': 'Plugin verpacken', +'Password': 'Passwort', +'password changed': 'password changed', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Dateiansicht', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Please', +'please wait!': 'Bitte warten!', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" deleted', +'Plugin "%s" in application': 'Plugin "%s" in Anwendung', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'plugins', +'Plugins': 'Plugins', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Unterstützt von', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'vorherige 100 zeilen', +'Previous Edit Point': 'vorheriger Bearbeitungsschritt', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Projekt Fortschritt', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Abfrage:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Schnelle Suche', +'Record': 'Record', +'record': 'Datensatz', +'record does not exist': 'Datensatz existiert nicht', +'record id': 'Datensatz id', +'Record ID': 'Datensatz ID', +'Record id': 'Record id', +'refresh': 'refresh', +'Register': 'Registrieren', +'register': 'Registrierung', +'Registration key': 'Registrierungsschlüssel', +'reload': 'Neu laden', +'Reload routes': 'Routen neu laden', +'Remove compiled': 'Bytecode löschen', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Ersetzen', +'Replace All': 'Alle Ersetzen', +'Repository (%s)': 'Repository (%s)', +'request': 'Anfrage', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Reset Password key': 'Passwortschlüssel zurücksetzen', +'Resolve Conflict file': 'bereinige Konflikt-Datei', +'response': 'Antwort', +'restart': 'restart', +'restore': 'wiederherstellen', +'return': 'return', +'Revert': 'Revert', +'revert': 'zurückkehren', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Rolle', +'Roles': 'Roles', +'Rows in table': 'Zeilen in Tabelle', +'Rows in Table': 'Rows in Table', +'Rows selected': 'Zeilen ausgewählt', +'rules are not defined': 'Regeln sind nicht definiert', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Tests in dieser Datei ausführen (um alle Dateien auszuführen, kann auch der Button 'test' genutzt werden)", +'Running on %s': 'läuft auf %s', +'Save': 'Speichern', +'save': 'Speichern', +'Save file:': 'Speichere Datei:', +'Save file: %s': 'Speichere Datei: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'via Ajax speichern', +'Saved file hash:': 'Gespeicherter Datei-Hash:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Dateien zum Paketieren wählen', +'selected': 'ausgewählt(e)', +'session': 'Sitzung', +'session expired': 'Sitzung abgelaufen', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'Shell', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'Seite', +'Size of cache:': 'Size of cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': 'einige Dateien konnten nicht gelöscht werden', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'Quelle : Dateisystem', +'Start a new app': 'Start a new app', +'Start searching': 'Suche beginnen', +'Start wizard': 'Assistent starten', +'state': 'Status', +'Static': 'Statisch', +'static': 'statische Dateien', +'Static files': 'statische Dateien', +'Statistics': 'Statistics', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'Stylesheet': 'Stylesheet', +'submit': 'Absenden', +'Submit': 'Submit', +'successful': 'successful', +'Sure you want to delete this object?': 'Wollen Sie das Objekt wirklich löschen?', +'switch to : db': 'wechsel zu : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': 'Tabelle', +'Table': 'Table', +'Table name': 'Tabellen Name', +'Temporary': 'Temporary', +'test': 'Test', +'test_def': 'test_def', +'test_for': 'test_for', +'test_if': 'test_if', +'test_try': 'test_try', +'Testing application': 'Teste die Anwendung', +'Testing controller': 'Teste Controller', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'Die "query" ist eine Bedingung wie "db.table1.field1 == \'Wert\'". Etwas wie "db.table1.field1 db.table2.field2 ==" führt zu einem SQL JOIN.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'the application logic, each URL path is mapped in one exposed function in the controller': 'Die Logik der Anwendung, jeder URL-Pfad wird auf eine Funktion abgebildet die der Controller zur Verfügung stellt', +'The application logic, each URL path is mapped in one exposed function in the controller': 'Die Logik der Anwendung, jeder URL-Pfad wird auf eine Funktion abgebildet die der Controller zur Verfügung stellt', +'the data representation, define database tables and sets': 'Die Datenrepräsentation definiert Mengen von Tabellen und Datenbanken', +'The data representation, define database tables and sets': 'Die Datenrepräsentation definiert Mengen von Tabellen und Datenbanken', +'The output of the file is a dictionary that was rendered by the view': 'Die Ausgabe der Datei ist ein "dictionary" und wurde vom "view" gerendert', +'The presentations layer, views are also known as templates': 'Die Präsentationsschicht, Views sind auch bekannt als Vorlagen/Templates', +'the presentations layer, views are also known as templates': 'Die Präsentationsschicht, Views sind auch bekannt als Vorlagen/Templates', +'Theme': 'Theme', +'There are no controllers': 'Keine Controller vorhanden', +'There are no models': 'Keine Modelle vorhanden', +'There are no modules': 'Keine Module vorhanden', +'There are no plugins': 'Keine Plugins vorhanden', +'There are no private files': 'Keine privaten Dateien vorhanden', +'There are no static files': 'Keine statischen Dateien vorhanden', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'Keine übersetzungen vorhanden, nur die voreingestellte Sprache wird Unterstützt', +'There are no views': 'Keine Views vorhanden', +'These files are not served, they are only available from within your app': 'Diese Dateien werden nicht ausgeliefert, sie sind nur innerhalb Ihrer App verfügbar', +'These files are served without processing, your images go here': 'Diese Dateien werden ohne Verarbeitung ausgeliefert. Beispielsweise Bilder kommen hier hin.', +'these files are served without processing, your images go here': 'Diese Dateien werden ohne Verarbeitung ausgeliefert. Beispielsweise Bilder kommen hier hin.', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is a copy of the scaffolding application': 'Dies ist eine Kopie einer Grundgerüst-Anwendung', +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': 'Dies ist das Template %(filename)s', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Ticket', +'Ticket ID': 'Ticket ID', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'Zeitstempel', +'TM': 'TM', +'to previous version.': 'zu einer früheren Version.', +'To create a plugin, name a file/folder plugin_[name]': 'Um ein Plugin zu erstellen benennen Sie eine(n) Datei/Ordner plugin_[Name]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'Breakpoint aktivieren/deaktivieren', +'Toggle comment': ' Kommentar ein-/ausblenden', +'Toggle Fullscreen': 'Vollbild ein-/ausschalten', +'Traceback': 'Traceback', +'translation strings for the application': 'übersetzungs-Strings für die Anwendung', +'Translation strings for the application': 'übersetzungs-Strings für die Anwendung', +'try': 'versuche', +'try something like': 'Versuchen Sie so etwas wie', +'Try the mobile interface': 'Testen Sie das Interface für Handys', +'try view': 'Versuche view', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Überprüfen von Upgrades nicht möglich', +'unable to create application "%s"': 'Erzeugen von Anwendung "%s" nicht möglich', +'unable to delete file "%(filename)s"': 'Löschen von Dateien "%(filename)s" nicht möglich', +'unable to delete file plugin "%(plugin)s"': 'unable to delete file plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download': 'Herunterladen nicht möglich', +'Unable to download app': 'Herunterladen der Anwendung nicht möglich', +'Unable to download app because:': 'Unable to download app because:', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'Analysieren der cvs Datei nicht möglich', +'unable to uninstall "%s"': 'Deinstallieren von "%s" nicht möglich', +'unable to upgrade because "%s"': 'unable to upgrade because "%s"', +'uncheck all': 'Auswahl entfernen', +'Uninstall': 'Deinstallieren', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'Aktualisieren', +'update all languages': 'Aktualisiere alle Sprachen', +'Update:': 'Aktualisiere:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'upgrade now to %s', +'upgrade web2py now': 'web2py jetzt upgraden', +'upload': 'upload', +'Upload': 'Upload', +'Upload & install packed application': 'Verpackte Anwendung hochladen und installieren', +'Upload a package:': 'Ein Packet hochladen:', +'Upload and install packed application': 'Verpackte Anwendung hochladen und installieren', +'upload application:': 'Lade Anwendung hoch:', +'Upload existing application': 'Lade existierende Anwendung hoch', +'upload file:': 'Lade Datei hoch:', +'upload plugin file:': 'Plugin-Datei hochladen:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Benutze (...)&(...) für AND, (...)|(...) für OR, und ~(...) für NOT, um komplexe Abfragen zu erstellen.', +'Use an url:': 'Verwende URL:', +'user': 'Nutzer', +'User': 'User', +'User ID': 'Benutzer ID', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'Variablen', +'Version': 'Version', +'Version %s.%s.%s (%s) %s': 'Version %s.%s.%s (%s) %s', +'Versioning': 'Versionsverwaltung', +'versioning': 'Versionsverwaltung', +'View': 'Ansicht', +'view': 'Ansicht', +'Views': 'Ansichten', +'views': 'Ansichten', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py ist aktuell', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'Neuste Tweets von web2py', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py upgraded; please restart it', +'Welcome %s': 'Willkommen %s', +'Welcome to web2py': 'Willkommen zu web2py', +'Which called the function': 'welche die Funktion aufrief', +'Working...': 'Working...', +'Wrap with Abbreviation': 'mit Kürzel einhüllen', +'WSGI reference name': 'WSGI reference name', +'xml': 'xml', +'YES': 'JA', +'Yes': 'Yes', +'You are successfully running web2py': 'web2by wird erfolgreich ausgeführt', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You can modify this application and adapt it to your needs': 'Sie können diese Anwendung verändern und Ihren Bedürfnissen anpassen', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'You visited the url': 'Sie besuchten die URL', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/en.py b/web2py/applications/admin/languages/en.py new file mode 100644 index 0000000..0d5dcf5 --- /dev/null +++ b/web2py/applications/admin/languages/en.py @@ -0,0 +1,574 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'en-us', +'!langname!': 'English (US)', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s %%{row} deleted', +'%s %%{row} updated': '%s %%{row} updated', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(something like "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'Abort': 'Abort', +'About': 'About', +'About application': 'About application', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Add breakpoint', +'Additional code for your application': 'Additional code for your application', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'admin disabled because no admin password', +'admin disabled because not supported on google app engine': 'admin disabled because not supported on google app engine', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'admin disabled because unable to access password file', +'Admin is disabled because insecure channel': 'Admin is disabled because insecure channel', +'Admin language': 'Admin language', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'administrative interface', +'Administrator Password:': 'Administrator Password:', +'and rename it:': 'and rename it:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'appadmin is disabled because insecure channel', +'Application': 'Application', +'application "%s" uninstalled': 'application "%s" uninstalled', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'application compiled', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'application is compiled and cannot be designed', +'Application name:': 'Application name:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'are not used', +'are not used yet': 'are not used yet', +'Are you sure you want to delete file "%s"?': 'Are you sure you want to delete file "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Are you sure you want to delete plugin "%s"?', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Are you sure you want to uninstall application "%s"?': 'Are you sure you want to uninstall application "%s"?', +'Are you sure?': 'Are you sure?', +'arguments': 'arguments', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.', +'ATTENTION: you cannot edit the running application!': 'ATTENTION: you cannot edit the running application!', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available Databases and Tables': 'Available Databases and Tables', +'back': 'back', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'Begin': 'Begin', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'cache, errors and sessions cleaned', +'can be a git repo': 'can be a git repo', +'Cancel': 'Cancel', +'Cannot be empty': 'Cannot be empty', +'Cannot compile: there are errors in your app:': 'Cannot compile: there are errors in your app:', +'cannot create file': 'cannot create file', +'cannot upload file "%(filename)s"': 'cannot upload file "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'Change admin password', +'change editor settings': 'change editor settings', +'Changelog': 'Changelog', +'check all': 'check all', +'Check for upgrades': 'Check for upgrades', +'Check to delete': 'Check to delete', +'Checking for upgrades...': 'Checking for upgrades...', +'Clean': 'Clean', +'Clear': 'Clear', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Click row to expand traceback': 'Click row to expand traceback', +'Click row to view a ticket': 'Click row to view a ticket', +'code': 'code', +'Code listing': 'Code listing', +'collapse/expand all': 'collapse/expand all', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'Compile', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'compiled application removed', +'Condition': 'Condition', +'continue': 'continue', +'Controllers': 'Controllers', +'controllers': 'controllers', +'Count': 'Count', +'Create': 'Create', +'create file with filename:': 'create file with filename:', +'Create/Upload': 'Create/Upload', +'created by': 'created by', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Current request', +'Current response': 'Current response', +'Current session': 'Current session', +'currently running': 'currently running', +'currently saved or': 'currently saved or', +'data uploaded': 'data uploaded', +'Database': 'Database', +'Database %s select': 'Database %s select', +'Database administration': 'Database administration', +'database administration': 'database administration', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Date and Time', +'db': 'db', +'Debug': 'Debug', +'defines tables': 'defines tables', +'Delete': 'Delete', +'delete': 'delete', +'delete all checked': 'delete all checked', +'delete plugin': 'delete plugin', +'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)', +'Delete:': 'Delete:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'Deploy', +'Deploy on Google App Engine': 'Deploy on Google App Engine', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description:': 'Description:', +'design': 'design', +'Detailed traceback description': 'Detailed traceback description', +'details': 'details', +'direction: ltr': 'direction: ltr', +'directory not found': 'directory not found', +'Disable': 'Disable', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'docs', +'Docs': 'Docs', +'done!': 'done!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'download layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'download plugins', +'Download plugins from repository': 'Download plugins from repository', +'Edit': 'Edit', +'edit all': 'edit all', +'Edit application': 'Edit application', +'edit controller:': 'edit controller:', +'Edit current record': 'Edit current record', +'edit views:': 'edit views:', +'Editing %s': 'Editing %s', +'Editing Language file': 'Editing Language file', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Enable', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Error': 'Error', +'Error logs for "%(app)s"': 'Error logs for "%(app)s"', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Error ticket', +'Errors': 'Errors', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Exception instance attributes', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'export as csv file', +'Exports:': 'Exports:', +'exposes': 'exposes', +'exposes:': 'exposes:', +'extends': 'extends', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module because:': 'failed to reload module because:', +'File': 'File', +'file "%(filename)s" created': 'file "%(filename)s" created', +'file "%(filename)s" deleted': 'file "%(filename)s" deleted', +'file "%(filename)s" uploaded': 'file "%(filename)s" uploaded', +'file "%s" of %s restored': 'file "%s" of %s restored', +'file changed on disk': 'file changed on disk', +'file does not exist': 'file does not exist', +'file not found': 'file not found', +'file saved on %(time)s': 'file saved on %(time)s', +'file saved on %s': 'file saved on %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'filter', +'Find Next': 'Find Next', +'Find Previous': 'Find Previous', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': 'Functions with no doctests will result in [passed] tests.', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'Graph Model': 'Graph Model', +'graph model': 'graph model', +'Help': 'Help', +'here': 'here', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Import/Export', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'includes', +'Indent with tabs': 'Indent with tabs', +'inspect attributes': 'inspect attributes', +'Install': 'Install', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Installed applications', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'internal error', +'internal error: %s': 'internal error: %s', +'Internal State': 'Internal State', +'Invalid action': 'Invalid action', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'invalid password', +'invalid password.': 'invalid password.', +'Invalid Query': 'Invalid Query', +'invalid request': 'invalid request', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'invalid ticket', +'Key': 'Key', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'language file "%(filename)s" created/updated', +'Language files (static strings) updated': 'Language files (static strings) updated', +'languages': 'languages', +'Languages': 'Languages', +'Last Revision': 'Last Revision', +'Last saved on:': 'Last saved on:', +'License for': 'License for', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Loading...': 'Loading...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'Login': 'Login', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Login to the Administrative Interface', +'Login/Register': 'Login/Register', +'Logout': 'Logout', +'lost password': 'lost password', +'Main Menu': 'Main Menu', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Memberships': 'Memberships', +'merge': 'merge', +'Models': 'Models', +'models': 'models', +'Modified On': 'Modified On', +'Modules': 'Modules', +'modules': 'modules', +'Multi User Mode': 'Multi User Mode', +'new application "%s" created': 'new application "%s" created', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'New Application Wizard', +'New application wizard': 'New application wizard', +'new plugin installed': 'new plugin installed', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'New Record', +'new record inserted': 'new record inserted', +'New simple application': 'New simple application', +'next': 'next', +'next %s rows': 'next %s rows', +'NO': 'NO', +'no changes': 'no changes', +'No databases in this application': 'No databases in this application', +'No Interaction yet': 'No Interaction yet', +'no match': 'no match', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'or import from csv file', +'Original/Translation': 'Original/Translation', +'Overview': 'Overview', +'Overwrite installed app': 'Overwrite installed app', +'Pack all': 'Pack all', +'Pack compiled': 'Pack compiled', +'Pack custom': 'Pack custom', +'pack plugin': 'pack plugin', +'password changed': 'password changed', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Peeking at file', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Please', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" deleted', +'Plugin "%s" in application': 'Plugin "%s" in application', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'plugins', +'Plugins': 'Plugins', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Powered by', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Project Progress', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Query:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Record': 'Record', +'record does not exist': 'record does not exist', +'Record id': 'Record id', +'refresh': 'refresh', +'register': 'register', +'Reload routes': 'Reload routes', +'Remove compiled': 'Remove compiled', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Replace', +'Replace All': 'Replace All', +'Repository (%s)': 'Repository (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Resolve Conflict file': 'Resolve Conflict file', +'response': 'response', +'restart': 'restart', +'restore': 'restore', +'return': 'return', +'Revert': 'Revert', +'revert': 'revert', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Rows in Table', +'Rows selected': 'Rows selected', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'Running on %s', +'Save': 'Save', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Save via Ajax', +'Saved file hash:': 'Saved file hash:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'session': 'session', +'session expired': 'session expired', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'shell', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'Site', +'Size of cache:': 'Size of cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': 'some files could not be removed', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Start a new app', +'Start searching': 'Start searching', +'Start wizard': 'Start wizard', +'state': 'state', +'static': 'static', +'Static': 'Static', +'Static files': 'Static files', +'Statistics': 'Statistics', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'Submit': 'Submit', +'submit': 'submit', +'successful': 'successful', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'Table': 'Table', +'Temporary': 'Temporary', +'test': 'test', +'Testing application': 'Testing application', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller', +'The data representation, define database tables and sets': 'The data representation, define database tables and sets', +'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates', +'Theme': 'Theme', +'There are no controllers': 'There are no controllers', +'There are no models': 'There are no models', +'There are no modules': 'There are no modules', +'There are no plugins': 'There are no plugins', +'There are no private files': 'There are no private files', +'There are no static files': 'There are no static files', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'There are no translators, only default language is supported', +'There are no views': 'There are no views', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'These files are served without processing, your images go here', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Ticket', +'Ticket ID': 'Ticket ID', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'to previous version.': 'to previous version.', +'To create a plugin, name a file/folder plugin_[name]': 'To create a plugin, name a file/folder plugin_[name]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'Translation strings for the application': 'Translation strings for the application', +'try something like': 'try something like', +'Try the mobile interface': 'Try the mobile interface', +'try view': 'try view', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Unable to check for upgrades', +'unable to create application "%s"': 'unable to create application "%s"', +'unable to delete file "%(filename)s"': 'unable to delete file "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'unable to delete file plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download app because:': 'Unable to download app because:', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'unable to parse csv file', +'unable to uninstall "%s"': 'unable to uninstall "%s"', +'unable to upgrade because "%s"': 'unable to upgrade because "%s"', +'uncheck all': 'uncheck all', +'Uninstall': 'Uninstall', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'update', +'update all languages': 'update all languages', +'Update:': 'Update:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'upgrade now to %s', +'upload': 'upload', +'Upload': 'Upload', +'Upload a package:': 'Upload a package:', +'Upload and install packed application': 'Upload and install packed application', +'upload file:': 'upload file:', +'upload plugin file:': 'upload plugin file:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.', +'User': 'User', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'variables', +'Version': 'Version', +'Versioning': 'Versioning', +'Views': 'Views', +'views': 'views', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py is up to date', +'web2py online debugger': 'web2py online debugger', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py upgraded; please restart it', +'Working...': 'Working...', +'WSGI reference name': 'WSGI reference name', +'YES': 'YES', +'Yes': 'Yes', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/es.py b/web2py/applications/admin/languages/es.py new file mode 100644 index 0000000..46ee5a2 --- /dev/null +++ b/web2py/applications/admin/languages/es.py @@ -0,0 +1,694 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'es', +'!langname!': 'Español', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"actualice" es una expresión opcional como "campo1=\'nuevo_valor\'". No se puede actualizar o eliminar resultados de un JOIN', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s filas eliminadas', +'%s %%{row} updated': '%s filas actualizadas', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(requires internet access, experimental)': '(requiere acceso a internet, experimental)', +'(something like "it-it")': '(algo como "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(archivo **gluon/contrib/plural_rules/%s.py** no se ha encontrado)', +'@markmin\x01An error occured, please [[reload %s]] the page': 'Ocurrió un error, por favor [[recargue %s]] la página', +'@markmin\x01Number of entries: **%s**': 'Número de entradas: **%s**', +'@markmin\x01Searching: **%s** %%{file}': 'Buscando: **%s** archivos', +'A new version of web2py is available': 'Hay una nueva versión de web2py disponible', +'A new version of web2py is available: %s': 'Hay una nueva versión de web2py disponible: %s', +'Abort': 'Abort', +'About': 'Acerca de', +'About application': 'Acerca de la aplicación', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Add breakpoint', +'additional code for your application': 'código adicional para su aplicación', +'Additional code for your application': 'Código adicional para su aplicación', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'admin deshabilitado por falta de contraseña', +'admin disabled because not supported on google app engine': 'admin deshabilitado, no es soportado en GAE', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'admin deshabilitado, imposible acceder al archivo con la contraseña', +'Admin is disabled because insecure channel': 'Admin deshabilitado, el canal no es seguro', +'Admin is disabled because unsecure channel': 'Admin deshabilitado, el canal no es seguro', +'Admin language': 'Lenguaje de administración', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'interfaz administrativa', +'Administrator Password:': 'Contraseña del Administrador:', +'An error occured, please %s the page': 'Ha ocurrido un error, por favor %s la página', +'and rename it (required):': 'y renombrela (requerido):', +'and rename it:': ' y renombrelo:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'admin deshabilitado, el canal no es seguro', +'Application': 'Application', +'application "%s" uninstalled': 'aplicación "%s" desinstalada', +'application %(appname)s installed with md5sum: %(digest)s': 'application %(appname)s installed with md5sum: %(digest)s', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'aplicación compilada', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'la aplicación está compilada y no puede ser modificada', +'Application name:': 'Nombre de la aplicación:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'are not used', +'are not used yet': 'are not used yet', +'Are you sure you want to delete file "%s"?': '¿Está seguro que desea eliminar el archivo "%s"?', +'Are you sure you want to delete plugin "%s"?': '¿Está seguro que quiere eliminar el plugin "%s"?', +'Are you sure you want to delete this object?': '¿Está seguro que quiere eliminar este objeto?', +'Are you sure you want to uninstall application "%s"': '¿Está seguro que desea desinstalar la aplicación "%s"', +'Are you sure you want to uninstall application "%s"?': '¿Está seguro que desea desinstalar la aplicación "%s"?', +'Are you sure you want to upgrade web2py now?': '¿Está seguro que desea actualizar web2py ahora?', +'Are you sure?': '¿Está seguro?', +'arguments': 'argumentos', +'at char %s': 'en el carácter %s', +'at line %s': 'en la línea %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATENCIÓN: Inicio de sesión requiere una conexión segura (HTTPS) o localhost.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATENCIÓN: NO EJECUTE VARIAS PRUEBAS SIMULTANEAMENTE, NO SON THREAD SAFE.', +'ATTENTION: you cannot edit the running application!': 'ATENCIÓN: ¡no puede modificar la aplicación que se ejecuta!', +'Autocomplete': 'Autocompletar', +'Autocomplete Python Code': 'Autocompletar código Python', +'Available databases and tables': 'Bases de datos y tablas disponibles', +'Available Databases and Tables': 'Bases de Datos y Tablas Disponibles', +'back': 'atrás', +'Back to the plugins list': 'Regresar a la lista de plugins', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'Begin': 'Begin', +'breakpoint': 'punto de ruptura', +'Breakpoints': 'Breakpoints', +'breakpoints': 'puntos de ruptura', +'browse': 'navegar', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Caché', +'cache': 'caché', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'caché, errores y sesiones eliminados', +'can be a git repo': 'puede ser un repositorio git', +'Cancel': 'Cancelar', +'Cannot be empty': 'No puede estar vacío', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'No se puede compilar: hay errores en su aplicación. Depure, corrija errores y vuelva a intentarlo.', +'Cannot compile: there are errors in your app:': 'No se puede compilar: hay errores en su aplicación:', +'cannot create file': 'no es posible crear archivo', +'cannot upload file "%(filename)s"': 'no es posible subir archivo "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'cambie contraseña admin', +'change editor settings': 'cambiar la configuración del editor', +'Change Password': 'Cambie Contraseña', +'Changelog': 'Changelog', +'check all': 'marcar todos', +'Check for upgrades': 'buscar actualizaciones', +'Check to delete': 'Marque para eliminar', +'Checking for upgrades...': 'Buscando actualizaciones...', +'Clean': 'Limpiar', +'Clear': 'Clear', +'Clear CACHE?': '¿Limpiar CACHÉ?', +'Clear DISK': 'Limpiar DISCO', +'Clear RAM': 'Limpiar RAM', +'click here for online examples': 'haga click aquí para ver ejemplos en línea', +'click here for the administrative interface': 'haga click aquí para usar la interfaz administrativa', +'Click row to expand traceback': 'Click en la fila para expandir el rastreo', +'Click row to view a ticket': 'Click row to view a ticket', +'click to check for upgrades': 'haga clic para buscar actualizaciones', +'click to open': 'click para abrir', +'Client IP': 'IP del Cliente', +'code': 'código', +'Code listing': 'Listado de código', +'collapse/expand all': 'contraer/expandir todo', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'commit (mercurial)': 'confirmar (mercurial)', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'Compilar', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'aplicación compilada removida', +'Condition': 'Condition', +'continue': 'continuar', +'Controllers': 'Controladores', +'controllers': 'controladores', +'Count': 'Contar', +'Create': 'Crear', +'create file with filename:': 'cree archivo con nombre:', +'Create new application using the Wizard': 'Crear nueva aplicación utilizando el asistente', +'create new application:': 'nombre de la nueva aplicación:', +'Create new simple application': 'Cree una nueva aplicación', +'Create/Upload': 'Crear/Subir', +'created by': 'creado por', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Solicitud en curso', +'Current response': 'Respuesta en curso', +'Current session': 'Sesión en curso', +'currently running': 'actualmente en ejecución', +'currently saved or': 'actualmente guardado o', +'customize me!': 'Adáptame!', +'data uploaded': 'datos subidos', +'Database': 'Database', +'database': 'base de datos', +'Database %s select': 'Database %s select', +'database %s select': 'selección en base de datos %s', +'Database administration': 'Database administration', +'database administration': 'administración base de datos', +'Database Administration (appadmin)': 'Administración de Base de Datos (appadmin)', +'Date and Time': 'Fecha y Hora', +'db': 'db', +'Debug': 'Depurar', +'defines tables': 'definir tablas', +'Delete': 'Eliminar', +'delete': 'eliminar', +'delete all checked': 'eliminar marcados', +'delete plugin': 'eliminar plugin', +'Delete this file (you will be asked to confirm deletion)': 'Elimine este fichero (se le pedirá confirmación)', +'Delete:': 'Eliminar:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'Deploy', +'Deploy on Google App Engine': 'Instale en Google App Engine', +'Deploy to OpenShift': 'Instale en OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description': 'Descripción', +'Description:': 'Description:', +'design': 'modificar', +'DESIGN': 'DISEÑO', +'Design for': 'Diseño para', +'Detailed traceback description': 'Descripción detallada del rastreo', +'details': 'detalles', +'direction: ltr': 'dirección: ltr', +'directory not found': 'directory not found', +'Disable': 'Deshabilitar', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISCO', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'documentos', +'Docs': 'Documentos', +'Done!': 'Listo!', +'done!': 'listo!', +'Downgrade': 'Downgrade', +'Download': 'Descargar', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download files via http:': 'descargar archivos via http:', +'download layouts': 'descargar layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'descargar plugins', +'Download plugins from repository': 'Download plugins from repository', +'E-mail': 'Correo electrónico', +'EDIT': 'EDITAR', +'Edit': 'editar', +'edit all': 'edit all', +'Edit application': 'Editar aplicación', +'edit controller': 'editar controlador', +'edit controller:': 'editar controlador:', +'Edit current record': 'Edite el registro actual', +'Edit Profile': 'Editar Perfil', +'edit views:': 'editar vistas:', +'Editing %s': 'Editando %s', +'Editing file': 'Editando archivo', +'Editing file "%s"': 'Editando archivo "%s"', +'Editing Language file': 'Editando archivo de lenguaje', +'Editing myclientapi': 'Editando myclientapi', +'Editing myemail': 'Editando myemail', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editing rbare': 'Editando rbare', +'Editing ul': 'Editando ul', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Habilitar', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Enterprise Web Framework': 'Framework Web Empresarial', +'Error': 'Error', +'Error logs for "%(app)s"': 'Bitácora de errores en "%(app)s"', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Error ticket', +'Errors': 'errores', +'Errors in form, please check it out.': 'Errores en el formulario, verifique por favor.', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Atributos de la instancia de Excepción', +'Exit Fullscreen': 'Salir de pantalla completa', +'Expand Abbreviation': 'Expandir abreviación', +'Expand Abbreviation (html files only)': 'Expandir Abreviación (sólo archivos html)', +'export as csv file': 'exportar como archivo CSV', +'Exports:': 'Exports:', +'exposes': 'expone', +'exposes:': 'expone:', +'extends': 'extiende', +'failed to compile file because:': 'falló la compilación de archivos debido a:', +'failed to reload module': 'recarga del módulo ha fallado', +'failed to reload module because:': 'no es posible recargar el módulo por:', +'File': 'Archivo', +'file "%(filename)s" created': 'archivo "%(filename)s" creado', +'file "%(filename)s" deleted': 'archivo "%(filename)s" eliminado', +'file "%(filename)s" uploaded': 'archivo "%(filename)s" subido', +'file "%(filename)s" was not deleted': 'archivo "%(filename)s" no fue eliminado', +'file "%s" of %s restored': 'archivo "%s" de %s restaurado', +'file changed on disk': 'archivo modificado en el disco', +'file does not exist': 'archivo no existe', +'file not found': 'file not found', +'file saved on %(time)s': 'archivo guardado %(time)s', +'file saved on %s': 'archivo guardado %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'filter', +'Find Next': 'Buscar próximo', +'Find Previous': 'Bucar anterior', +'First name': 'Nombre', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': 'Funciones sin doctests equivalen a pruebas [aceptadas].', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graficación del modelo', +'Graph Model': 'Graph Model', +'Group ID': 'ID de Grupo', +'Hello World': 'Hola Mundo', +'Help': 'ayuda', +'here': 'aquí', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'htmledit': 'htmledit', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Si el reporte anterior contiene un número de tiquete este indica un falla en la ejecución del controlador, antes de cualquier intento de ejecutat doctests. Esto generalmente se debe a un error en la indentación o un error por fuera del código de la función.\r\nUn titulo verde indica que todas las pruebas pasaron (si existen). En dicho caso los resultados no se muestran.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'Image': 'Imagen', +'import': 'import', +'Import/Export': 'Importar/Exportar', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'incluye', +'Indent with tabs': 'Indent with tabs', +'insert new': 'inserte nuevo', +'insert new %s': 'inserte nuevo %s', +'inspect attributes': 'inspeccionar atributos', +'Install': 'Instalar', +'Installation of %(plugin)s for %(app)s': 'Instalación de %(plugin)s para %(app)s', +'Installation of %(plugin)s for %(app)s app': 'Instalación de %(plugin)s para %(app)s app', +'Installed applications': 'Aplicaciones instaladas', +'Interaction at %s line %s': 'Interacción en %s línea %s', +'Interactive console': 'Terminal interactiva', +'internal error': 'error interno', +'internal error: %s': 'internal error: %s', +'Internal State': 'Estado Interno', +'Invalid action': 'Acción inválida', +'Invalid application name': 'Nombre de aplicación no válido', +'invalid circular reference': 'invalid circular reference', +'Invalid email': 'Correo inválido', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'contraseña inválida', +'invalid password.': 'contraseña inválida.', +'Invalid Query': 'Consulta inválida', +'invalid request': 'solicitud inválida', +'Invalid request': 'Petición inválida', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'tiquete inválido', +'Key': 'Key', +'Key bindings': 'Key bindings', +'Key bindings for ZenCoding Plugin': 'Key bindings para el Plugin ZenCoding', +'Keyboard shortcuts': 'Atajos de teclado', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'archivo de lenguaje "%(filename)s" creado/actualizado', +'Language files (static strings) updated': 'Archivos de lenguaje (cadenas estáticas) actualizados', +'languages': 'lenguajes', +'Languages': 'Lenguajes', +'languages updated': 'lenguajes actualizados', +'Last name': 'Apellido', +'Last Revision': 'Last Revision', +'Last saved on:': 'Guardado en:', +'License for': 'Licencia para', +'License:': 'Licencia:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'listas por ticket', +'Loading...': 'Loading...', +'loading...': 'cargando...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals', +'login': 'inicio de sesión', +'Login': 'Inicio de sesión', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Inicio de sesión para la Interfaz Administrativa', +'Login/Register': 'Login/Register', +'Logout': 'fin de sesión', +'lost password': 'lost password', +'Lost Password': 'Contraseña perdida', +'Main Menu': 'Main Menu', +'manage': 'gestionar', +'Manage': 'Gestionar', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Administrar Caché', +'Manage Students': 'Manage Students', +'Memberships': 'Memberships', +'merge': 'combinar', +'models': 'modelos', +'Models': 'Modelos', +'Modified On': 'Modified On', +'Modules': 'Módulos', +'modules': 'módulos', +'Multi User Mode': 'Multi User Mode', +'Name': 'Nombre', +'new application "%s" created': 'nueva aplicación "%s" creada', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'New Application Wizard', +'New application wizard': 'Asistente para nueva aplicación', +'new plugin installed': 'nuevo plugin instalado', +'New plugin installed: %s': 'Nuevo plugin instalado: %s', +'New plugin installed: web2py.plugin.attachment.w2p': 'Nuevo plugin instalado: web2py.plugin.attachment.w2p', +'New plugin installed: web2py.plugin.dialog.w2p': 'Nuevo plugin instalado: web2py.plugin.dialog.w2p', +'New plugin installed: web2py.plugin.math2py.w2p': 'Nuevo plugin instalado: web2py.plugin.math2py.w2p', +'New plugin installed: web2py.plugin.timezone.w2p': 'Nuevo plugin instalado: web2py.plugin.timezone.w2p', +'New Record': 'Registro nuevo', +'new record inserted': 'nuevo registro insertado', +'New simple application': 'Nueva aplicación', +'next': 'siguiente', +'next %s rows': 'next %s rows', +'next 100 rows': '100 filas siguientes', +'NO': 'NO', +'no changes': 'no changes', +'No databases in this application': 'No hay bases de datos en esta aplicación', +'No Interaction yet': 'No hay interacción', +'no match': 'no encontrado', +'no package selected': 'ningún paquete seleccionado', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'No ticket_storage.txt found under /private folder': 'No se encontró ticket_storage.txt en la carpeta /private', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'online designer': 'diseñador en línea', +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'o alternativamente', +'Or Get from URL:': 'O obtener desde una URL:', +'or import from csv file': 'o importar desde archivo CSV', +'or provide app url:': 'o provea URL de la aplicación:', +'or provide application url:': 'o provea URL de la aplicación:', +'Origin': 'Origen', +'Original/Translation': 'Original/Traducción', +'Overview': 'Revisión general', +'Overwrite installed app': 'sobreescriba la aplicación instalada', +'Pack all': 'empaquetar todo', +'Pack compiled': 'empaquete compiladas', +'Pack custom': 'empaquetar personalizado', +'pack plugin': 'empaquetar plugin', +'PAM authenticated user, cannot change password here': 'usuario autenticado por PAM, no puede cambiar la contraseña aquí', +'Password': 'Contraseña', +'password changed': 'contraseña cambiada', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Visualizando archivo', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Por favor', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'Plugin': 'Plugin', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" eliminado', +'Plugin "%s" in application': 'Plugin "%s" en aplicación', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Página del plugin', +'plugins': 'plugins', +'Plugins': 'Plugins', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Este sitio usa', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '100 filas anteriores', +'Private files': 'Archivos privados', +'private files': 'archivos privados', +'Project Progress': 'Progreso del Proyecto', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Consulta:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Búsqueda rápida', +'Record': 'Record', +'record': 'registro', +'record does not exist': 'el registro no existe', +'record id': 'id de registro', +'Record ID': 'ID de Registro', +'Record id': 'Record id', +'refresh': 'recargar', +'register': 'register', +'Register': 'Regístrese', +'Registration key': 'Contraseña de Registro', +'reload': 'recargar', +'Reload routes': 'Recargar rutas', +'Remove compiled': 'eliminar compilados', +'Removed Breakpoint on %s at line %s': 'Eliminado punto de ruptura en %s en la línea %s', +'Replace': 'Reemplazar', +'Replace All': 'Reemplazar todos', +'Repository (%s)': 'Repositorio (%s)', +'Repository: %s': 'Repositorio: %s', +'request': 'petición', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Resolve Conflict file': 'archivo Resolución de Conflicto', +'response': 'respuesta', +'restart': 'restart', +'restore': 'restaurar', +'return': 'return', +'Revert': 'Revert', +'revert': 'revertir', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Rol', +'Roles': 'Roles', +'Rows in table': 'Filas en la tabla', +'Rows in Table': 'Rows in Table', +'Rows selected': 'Filas seleccionadas', +'rules are not defined': 'reglas no están definidas', +'Run tests': 'Run tests', +'Run tests in this file': 'Ejecute tests en este archivo', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Ejecute tests en este archivo (para ejecutarlo en todos los archivos, podrías usar el botón etiquetado como 'test')", +'Running on %s': 'Ejecutando en %s', +'Save': 'Guardar', +'save': 'guardar', +'Save file:': 'Guardar archivo:', +'Save file: %s': 'Guardar archivo: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Guardar vía Ajax', +'Saved file hash:': 'Hash del archivo guardado:', +'Screenshot %s': 'Screenshot %s', +'Screenshots': 'Screenshots', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'selected': 'seleccionado(s)', +'session': 'sesión', +'session expired': 'sesión expirada', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Establecer punto de ruptura en %s en la línea %s: %s', +'shell': 'shell', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'sitio', +'Size of cache:': 'Size of cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': 'algunos archivos no pudieron ser removidos', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'fuente : sistema de archivos', +'Start a new app': 'Start a new app', +'Start searching': 'Iniciar búsqueda', +'Start wizard': 'Iniciar asistente', +'state': 'estado', +'Static': 'Estáticos', +'static': 'estáticos', +'Static files': 'Archivos estáticos', +'Statistics': 'Estadísticas', +'Step': 'Step', +'step': 'paso', +'stop': 'parar', +'submit': 'enviar', +'Submit': 'Enviar', +'Success!': '¡Éxito!', +'successful': 'exitoso', +'Sure you want to delete this object?': '¿Está seguro que desea eliminar este objeto?', +'switch to : db': 'cambiar a : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': 'tabla', +'Table': 'Table', +'Table name': 'Nombre de la tabla', +'Temporary': 'Temporary', +'test': 'probar', +'Testing application': 'Probando aplicación', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "consulta" es una condición como "db.tabla1.campo1==\'valor\'". Algo como "db.tabla1.campo1==db.tabla2.campo2" resulta en un JOIN SQL.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'The application logic, each URL path is mapped in one exposed function in the controller': 'La lógica de la aplicación, cada ruta URL se mapea en una función expuesta en el controlador', +'the application logic, each URL path is mapped in one exposed function in the controller': 'la lógica de la aplicación, cada ruta URL se mapea en una función expuesta en el controlador', +'the data representation, define database tables and sets': 'la representación de datos, define tablas y conjuntos de base de datos', +'The data representation, define database tables and sets': 'La representación de datos, define tablas y conjuntos de base de datos', +'The presentations layer, views are also known as templates': 'La capa de presentación, las vistas también son llamadas plantillas', +'the presentations layer, views are also known as templates': 'la capa de presentación, las vistas también son llamadas plantillas', +'Theme': 'Theme', +'There are no controllers': 'No hay controladores', +'There are no models': 'No hay modelos', +'There are no modules': 'No hay módulos', +'There are no plugins': 'No hay plugins', +'There are no private files': 'No hay archivos privados', +'There are no static files': 'No hay archivos estáticos', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'No hay traductores, sólo el lenguaje por defecto es soportado', +'There are no views': 'No hay vistas', +'These files are not served, they are only available from within your app': 'Estos archivos no se proveen, ellos sólo están disponibles para su aplicación', +'These files are served without processing, your images go here': 'Estos archivos se proveen sin procesar, sus imágenes van aquí', +'these files are served without processing, your images go here': 'estos archivos se proveen sin procesar, sus imágenes van aquí', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': 'Está es la plantilla %(filename)s', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'esta página para ver si un punto de ruptura fue configurado y la depuración es requerida.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Ticket', +'Ticket ID': 'Ticket ID', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'Timestamp', +'TM': 'MR', +'to previous version.': 'a la versión previa.', +'To create a plugin, name a file/folder plugin_[name]': 'Para crear un plugin, nombre un archivo/carpeta plugin_[nombre]', +'To emulate a breakpoint programatically, write:': 'Para emular un punto de ruptura programáticamente, escriba', +'to use the debugger!': '¡usar el debugger!', +'toggle breakpoint': 'alternar punto de ruptura', +'Toggle comment': 'Alternar comentario', +'Toggle Fullscreen': 'Alternar pantalla completa', +'Traceback': 'Rastreo', +'translation strings for the application': 'cadenas de caracteres de traducción para la aplicación', +'Translation strings for the application': 'Cadenas de caracteres de traducción para la aplicación', +'try': 'intente', +'try something like': 'intente algo como', +'Try the mobile interface': 'Pruebe la interfaz móvil', +'try view': 'Pruebe la vista', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Escriba algún código Python aquí y teclee la tecla Enter para ejecutarlo', +'Unable to check for upgrades': 'No es posible verificar la existencia de actualizaciones', +'unable to create application "%s"': 'no es posible crear la aplicación "%s"', +'unable to delete file "%(filename)s"': 'no es posible eliminar el archivo "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'no es posible eliminar plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download': 'No es posible la descarga', +'Unable to download app': 'No es posible descargar la aplicación', +'Unable to download app because:': 'No es posible descargar la aplicación porque:', +'Unable to download because': 'No es posible descargar porque', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'no es posible analizar el archivo CSV', +'unable to uninstall "%s"': 'no es posible instalar "%s"', +'unable to upgrade because "%s"': 'no es posible actualizar porque "%s"', +'uncheck all': 'desmarcar todos', +'Uninstall': 'desinstalar', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'actualizar', +'update all languages': 'actualizar todos los lenguajes', +'Update:': 'Actualice:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'upgrade now to %s', +'upgrade web2py now': 'actualize web2py ahora', +'upload': 'upload', +'Upload': 'Subir', +'Upload & install packed application': 'Suba e instale aplicación empaquetada', +'Upload a package:': 'Subir un paquete:', +'Upload and install packed application': 'Suba e instale una aplicación empaquetada', +'upload application:': 'subir aplicación:', +'Upload existing application': 'Suba esta aplicación', +'upload file:': 'suba un archivo:', +'upload plugin file:': 'suba un archivo de plugin:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) para AND, (...)|(...) para OR, y ~(...) para NOT, para crear consultas más complejas.', +'User': 'User', +'User ID': 'ID de Usuario', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'variables', +'Version': 'Versión', +'Versioning': 'Versiones', +'versioning': 'versiones', +'view': 'vista', +'Views': 'Vistas', +'views': 'vistas', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py está actualizado', +'web2py online debugger': 'web2py debugger en línea', +'web2py Recent Tweets': 'Tweets Recientes de web2py', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py actualizado; favor reiniciar', +'Welcome to web2py': 'Bienvenido a web2py', +'Working...': 'Working...', +'WSGI reference name': 'WSGI reference name', +'YES': 'SÍ', +'Yes': 'Sí', +'You are going to install': 'Vas a instalar', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'Puedes inspeccionar las variables utilizando la terminal de abajo', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'Necesitas configurar y obtener un', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Tu aplicación será bloqueada hasta que des click en un botón de acción (siguiente, paso, continuar, etc.)', +} diff --git a/web2py/applications/admin/languages/fr.py b/web2py/applications/admin/languages/fr.py new file mode 100644 index 0000000..0588e8b --- /dev/null +++ b/web2py/applications/admin/languages/fr.py @@ -0,0 +1,649 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'fr', +'!langname!': 'Français', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" est une expression en option tels que "field1 = \'newvalue\'". Vous ne pouvez pas mettre à jour ou supprimer les résultats d\'une jointure "a JOIN"', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': 'lignes %s supprimées', +'%s %%{row} updated': 'lignes %s mises à jour', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%d-%m-%Y', +'%Y-%m-%d %H:%M:%S': '%d-%m-%Y %H:%M:%S', +'(**%.0d MB**)': '(**%.0d MB**)', +'(file **gluon/contrib/plural_rules/%s.py** is not found)': '(file **gluon/contrib/plural_rules/%s.py** is not found)', +'(requires internet access)': '(nécessite un accès Internet)', +'(requires internet access, experimental)': '(nécessite un accès Internet, expérimentale)', +'(something like "it-it")': '(quelque chose comme "it-it") ', +'(version %s)': '(version %s)', +'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}', +'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** items, **%(bytes)s** %%{byte(bytes)}', +'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'?': '?', +'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'@markmin\x01Searching: **%s** %%{file}': 'Cherche: **%s** fichiers', +'``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)', +'A new version of web2py is available: %s': 'Une nouvelle version de web2py est disponible: %s ', +'A new version of web2py is available: Version 1.68.2 (2009-10-21 09:59:29)\n': 'Une nouvelle version de web2py est disponible: Version 1.68.2 (2009-10-21 09:59:29)\r\n', +'Abort': 'Abort', +'About': 'À propos', +'About application': "À propos de l'application", +'Accept Terms': 'Termes acceptés', +'Add breakpoint': 'Ajouter une interruption', +'additional code for your application': 'code supplémentaire pour votre application', +'Additional code for your application': 'Code additionnel pour votre application', +'Admin design page': 'Page de conception admin', +'admin disabled because no admin password': 'admin désactivée car aucun mot de passe admin', +'admin disabled because not supported on google app engine': 'admin désactivée car non prise en charge sur Google Apps engine', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': "admin désactivée car incapable d'accéder au fichier mot de passe", +'Admin is disabled because insecure channel': 'Admin est désactivé parce que canal non sécurisé', +'Admin language': "Language de l'admin", +'Admin versioning page': 'Admin versioning page', +'administrative interface': "interface d'administration", +'Administrator Password:': "Mot de passe de l'administrateur:", +'An error occured, please [[reload %s]] the page': 'Une erreur c’est produite, s’il vous plait [[reload %s]] la page', +'and rename it (required):': 'et renommez-la (obligatoire):', +'and rename it:': 'et renommez-le:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'appadmin est désactivé parce que canal non sécurisé', +'Application': 'Application', +'application "%s" uninstalled': 'application "%s" désinstallée', +'application %(appname)s installed with md5sum: %(digest)s': 'application %(appname)s installée avec md5sum: %(digest)s', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'application compilée', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': "l'application est compilée et ne peut être modifiée", +'Application name:': "Nom de l'application:", +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'ne sont pas utilisé', +'are not used yet': 'ne sont pas encore utilisé', +'Are you sure you want to delete file "%s"?': 'Êtes-vous sûr de vouloir supprimer le fichier «%s»?', +'Are you sure you want to delete plugin "%s"?': 'Êtes-vous sûr de vouloir supprimer le plugin "%s"?', +'Are you sure you want to delete this object?': 'Êtes-vous sûr de vouloir supprimer cet objet?', +'Are you sure you want to uninstall application "%s"?': "Êtes-vous sûr de vouloir désinstaller l'application «%s»?", +'Are you sure you want to upgrade web2py now?': 'Êtes-vous sûr de vouloir mettre à jour web2py maintenant?', +'Are you sure?': 'Êtes vous sûr?', +'arguments': 'arguments', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATTENTION: nécessite une connexion sécurisée (HTTPS) ou être en localhost. ', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATTENTION: les tests ne sont pas thread-safe DONC NE PAS EFFECTUER DES TESTS MULTIPLES SIMULTANÉMENT.', +'ATTENTION: you cannot edit the running application!': "ATTENTION: vous ne pouvez pas modifier l'application qui tourne!", +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available databases and tables': 'Bases de données et tables disponibles', +'Available Databases and Tables': 'Available Databases and Tables', +'back': 'retour', +'Back to the plugins list': 'Retour à la liste de plugins', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'Begin': 'Début', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'cache, erreurs et sessions nettoyés', +'can be a git repo': 'can be a git repo', +'Cancel': 'Annuler', +'Cannot be empty': 'Ne peut pas être vide', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Ne peut pas compiler: il y a des erreurs dans votre application. corriger les erreurs et essayez à nouveau.', +'Cannot compile: there are errors in your app:': 'Ne peut pas compiler: il y a des erreurs dans votre application:', +'cannot create file': 'ne peut pas créer de fichier', +'cannot upload file "%(filename)s"': 'ne peut pas charger le fichier "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'Changer le mot de passe admin', +'change editor settings': 'change editor settings', +'Changelog': 'Changelog', +'check all': 'tout sélectionner', +'Check for upgrades': 'Vérifier les mises à jour', +'Check to delete': 'Cocher pour supprimer', +'Checking for upgrades...': 'Vérification des mises à jour ... ', +'Clean': 'nettoyer', +'Clear': 'Effacer', +'Clear CACHE?': 'Effacer le CACHE?', +'Clear DISK': 'Effacer le DISQUE', +'Clear RAM': 'Effacer la RAM', +'Click row to expand traceback': 'Click row to expand traceback', +'Click row to view a ticket': 'Click row to view a ticket', +'click to check for upgrades': 'Cliquez pour vérifier les mises jour', +'code': 'code', +'Code listing': 'Code listing', +'collapse/expand all': 'tout réduire/agrandir', +'Command': 'Commande', +'Comment:': 'Commentaire:', +'Commit': 'Valider', +'Commit form': 'Valider le formulaire', +'Committed files': 'Fichiers validés', +'Compile': 'compiler', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'application compilée enlevée', +'Condition': 'Condition', +'continue': 'continuer', +'Controllers': 'Contrôleurs', +'controllers': 'contrôleurs', +'Count': 'Compte', +'Create': 'Créer', +'create file with filename:': 'créer un fichier avec nom de fichier:', +'create new application:': 'créer une nouvelle application:', +'Create new simple application': 'Créer une nouvelle application', +'Create/Upload': 'Create/Upload', +'created by': 'créé par', +'Created by:': 'Créé par:', +'Created On': 'Créé le', +'Created on:': 'Créé le:', +'crontab': 'crontab', +'Current request': 'Requête actuelle', +'Current response': 'Réponse actuelle', +'Current session': 'Session en cours', +'currently running': 'tourne actuellement', +'currently saved or': 'actuellement enregistré ou', +'data uploaded': 'données téléversées', +'Database': 'Base de données', +'database': 'base de données', +'Database %s select': 'Database %s select', +'database %s select': 'base de données %s sélectionner', +'Database administration': 'Administration base de données', +'database administration': 'administration base de données', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Date et heure', +'db': 'bd', +'Debug': 'Debug', +'defines tables': 'définit les tables', +'Delete': 'Supprimer', +'delete': 'supprimer', +'delete all checked': 'supprimer tout ce qui est coché', +'delete plugin': ' supprimer le plugin', +'Delete this file (you will be asked to confirm deletion)': 'Supprimer ce fichier (on vous demandera de confirmer la suppression)', +'Delete:': 'Supprimer:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Démo', +'Deploy': 'Déployer', +'Deploy on Google App Engine': 'Déployer sur Google App Engine', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description:': 'Description:', +'design': 'conception', +'Detailed traceback description': 'Detailed traceback description', +'details': 'détails', +'direction: ltr': 'direction: ltr', +'directory not found': 'directory not found', +'Disable': 'Désactiver', +'Disabled': 'Désactivé', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISQUE', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disque effacé', +'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'documents', +'Docs': 'Documents', +'done!': 'fait!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'télécharger layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'télécharger plugins', +'Download plugins from repository': 'Download plugins from repository', +'EDIT': 'MODIFIER', +'Edit': 'Modifier', +'edit all': 'tout modifier', +'Edit application': "Modifier l'application", +'edit controller': 'modifier contrôleur', +'edit controller:': 'modifier le contrôleur:', +'Edit current record': 'Modifier cet enregistrement', +'edit views:': 'modifier les vues:', +'Editing %s': 'Modifier %s', +'Editing file': 'Modifier le fichier', +'Editing file "%s"': 'Modifier le fichier "% s" ', +'Editing Language file': 'Modifier le fichier de langue', +'Editing Plural Forms File': 'Modifier le fichier du formulaire pluriel', +'Editor': 'Éditeur', +'Email Address': 'Adresse courriel', +'Enable': 'Activer', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Enterprise Web Framework': 'Enterprise Web Framework', +'Error': 'Error', +'Error logs for "%(app)s"': 'Journal d\'erreurs pour "%(app)s"', +'Error snapshot': 'Error snapshot', +'Error ticket': "Billet d'erreur", +'Errors': 'Erreurs', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': "Attributs d'instance Exception", +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'export au format CSV', +'Exports:': 'Exportions:', +'exposes': 'expose', +'exposes:': 'expose:', +'extends': 'étend', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module': 'impossible de recharger le module', +'failed to reload module because:': 'impossible de recharger le module car:', +'File': 'Fichier', +'file "%(filename)s" created': 'fichier "%(filename)s" créé', +'file "%(filename)s" deleted': 'fichier "%(filename)s" supprimé', +'file "%(filename)s" uploaded': 'fichier "%(filename)s" chargé', +'file "%s" of %s restored': 'fichier "%s" de %s restauré', +'file changed on disk': 'fichier modifié sur le disque', +'file does not exist': "fichier n'existe pas", +'file not found': 'file not found', +'file saved on %(time)s': 'fichier enregistré le %(time)s', +'file saved on %s': 'fichier enregistré le %s', +'filename': 'nom de fichier', +'Filename': 'Nom de fichier', +'Files added': 'Fichiers ajoutés', +'filter': 'filtre', +'Find Next': 'Trouver les suivants', +'Find Previous': 'Trouver les précédents', +'Form has errors': 'Le formulaire comporte des erreurs', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': 'Des fonctions sans doctests entraîneront des tests [passed] .', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'Mot de passe GAE', +'Generate': 'Générer', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'représentation graphique du modèle', +'Graph Model': 'Représentation graphique du modèle', +'Help': 'aide', +'here': 'ici', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})', +'Hits': 'Hits', +'Home': 'Accueil', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'htmledit': 'edition html', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': "Si le rapport ci-dessus contient un numéro de ticket, cela indique une défaillance dans l'exécution du contrôleur, avant toute tentative d'exécuter les doctests. Cela est généralement dû à une erreur d'indentation ou une erreur à l'extérieur du code de la fonction.\r\nUn titre vert indique que tous les tests (si définis) sont passés. Dans ce cas, les résultats des essais ne sont pas affichées.", +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'importer', +'Import/Export': 'Importer/Exporter', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'inclus', +'Indent with tabs': 'Indent with tabs', +'index': 'index', +'insert new': 'insérer nouveau', +'insert new %s': 'insérer nouveau %s', +'inspect attributes': 'inspect attributes', +'Install': 'Installer', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Applications installées', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'erreur interne', +'internal error: %s': 'internal error: %s', +'Internal State': 'État Interne', +'Invalid action': 'Action non valide', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'mot de passe invalide', +'invalid password.': 'invalid password.', +'Invalid Query': 'Requête non valide', +'invalid request': 'Demande incorrecte', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'ticket non valide', +'Key': 'Clé', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'fichier de langue "%(filename)s" créé/mis à jour', +'Language files (static strings) updated': 'Fichiers de langue (chaînes statiques) mis à jour ', +'languages': 'langues', +'Languages': 'Langues', +'Last Revision': 'Dernière révision', +'Last saved on:': 'Dernière sauvegarde le:', +'License for': 'Licence pour', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Loading...': 'Chargement...', +'loading...': 'chargement ...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'Login': 'Connexion', +'login': 'connexion', +'Login successful': 'Login successful', +'Login to the Administrative Interface': "Se connecter à l'interface d'administration", +'Login/Register': 'Login/Register', +'Logout': 'déconnexion', +'lost password': 'mot de passe perdu', +'Main Menu': 'Main Menu', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Memberships': 'Memberships', +"Mercurial Version Control System Interface[[NEWLINE]]for application '%s'": "Mercurial Version Control System Interface[[NEWLINE]]for application '%s'", +'merge': 'fusionner', +'Models': 'Modèles', +'models': 'modèles', +'Modified On': 'Modifié le', +'Modules': 'Modules', +'modules': 'modules', +'Multi User Mode': 'Multi User Mode', +'new application "%s" created': 'nouvelle application "%s" créée', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'New Application Wizard', +'New application wizard': 'Assistant nouvelle application', +'new plugin installed': 'nouveau plugin installé', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'Nouvelle Entrée', +'new record inserted': 'nouvelle entrée insérée', +'New simple application': 'Nouvelle application simple', +'next': 'suivant', +'next %s rows': '%s lignes suivantes', +'next 100 rows': '100 lignes suivantes', +'NO': 'NON', +'no changes': 'no changes', +'No databases in this application': 'Aucune base de données dans cette application', +'No Interaction yet': 'No Interaction yet', +'no match': 'aucune correspondance', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'Node:': 'Node:', +'Not Authorized': 'Pas autorisé', +'Not supported': 'Pas supporté', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +'Number of entries: **%s**': 'Number of entries: **%s**', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'ou importer depuis un fichier CSV ', +'or provide app url:': "ou fournir l'URL de l'app:", +'or provide application url:': "ou fournir l'URL de l'application:", +'Original/Translation': 'Original / Traduction', +'Overview': 'Overview', +'Overwrite installed app': "Écraser l'application installée", +'Pack all': 'tout empaqueter', +'Pack compiled': 'paquet compilé', +'Pack custom': 'Pack custom', +'pack plugin': 'paquet plugin', +'PAM authenticated user, cannot change password here': 'Utilisateur authentifié par PAM, vous ne pouvez pas changer le mot de passe ici', +'password changed': 'mot de passe modifié', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Jeter un oeil au fichier', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'SVP', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" supprimé', +'Plugin "%s" in application': 'Plugin "%s" dans l\'application', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'plugiciels', +'Plugins': 'Plugiciels', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Propulsé par', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '100 lignes précédentes', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Project Progress', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Pousser', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Requête: ', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.', +'Rapid Search': 'Recherche rapide', +'Record': 'Enregistrement', +'record': 'enregistrement', +'record does not exist': "l'entrée n'existe pas", +'record id': 'id entrée', +'Record id': 'Record id', +'refresh': 'refresh', +'register': 'register', +'Reload routes': 'Reload routes', +'Remove compiled': 'retirer compilé', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Remplacer', +'Replace All': 'Tout remplacer', +'Repository (%s)': 'Repository (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Resolve Conflict file': 'Résoudre les conflits de fichiers', +'response': 'response', +'restart': 'redémarrer', +'restore': 'restaurer', +'return': 'retour', +'Revert': "Revenir vers l'arrière", +'revert': "revenir vers l'arrière", +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Révision %s', +'Revision:': 'Révision:', +'Role': 'Rôle', +'Roles': 'Rôles', +'Rows in Table': 'Rows in Table', +'Rows in table': 'Lignes de la table', +'Rows selected': 'Lignes sélectionnées', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Lancer les tests dans ce fichier (pour lancer tous les fichiers, vous pouvez également utiliser le bouton nommé 'test')", +'Running on %s': 'Running on %s', +'Save': 'Sauvegarder', +'save': 'sauvegarder', +'Save file:': 'Sauvegarder le fichier:', +'Save file: %s': 'Sauvegarder le fichier : %s', +'Save model as...': 'Sauvegarder le modèle sous...', +'Save via Ajax': 'Sauvegarder via Ajax', +'Saved file hash:': 'Hash du Fichier enregistré:', +'Screenshot %s': "Capture d'écran %s", +'Search': 'Rechercher', +'Searching: **%s** %%{file}': 'Searching: **%s** %%{file}', +'Select Files to Package': 'Select Files to Package', +'selected': 'sélectionnés', +'session': 'session', +'session expired': 'la session a expiré ', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'shell', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'Site', +'Size of cache:': 'Taille de la mémoire cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': 'certains fichiers ne peuvent pas être supprimés', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'source : système de fichier', +'Start a new app': 'Commencer une nouvelle application', +'Start searching': 'Débuté la recherche', +'Start wizard': "Démarrer l'assistant", +'state': 'état', +'Static': 'Statique', +'static': 'statique', +'Static files': 'Fichiers statiques', +'Statistics': 'Statistics', +'Step': 'Step', +'step': 'step', +'stop': 'arrêt', +'submit': 'envoyer', +'Submit': 'Envoyer', +'successful': 'réussi', +'Sure you want to delete this object?': 'Vous êtes sûr de vouloir supprimer cet objet?', +'switch to : db': 'transférer dans : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': 'table', +'Table': 'Table', +'Temporary': 'Temporaire', +'test': 'tester', +'Testing application': "Test de l'application", +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La "requête" est une condition comme "db.table1.field1==\'value\'". Quelque chose comme "db.table1.field1==db.table2.field2" aboutit à un JOIN SQL.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'the application logic, each URL path is mapped in one exposed function in the controller': "la logique de l'application, chaque chemin d'URL est mappé dans une fonction exposée dans le contrôleur", +'The application logic, each URL path is mapped in one exposed function in the controller': "La logique de l'application, chaque chemin d'URL est mappé avec une fonction exposée dans le contrôleur", +'the data representation, define database tables and sets': 'La représentation des données, définir les tables et ensembles de la base de données', +'The data representation, define database tables and sets': 'La représentation des données, définir les tables et ensembles de la base de données', +'The presentations layer, views are also known as templates': 'Les couches de présentation, les vues sont également appelées modples', +'the presentations layer, views are also known as templates': 'la couche de présentation, les vues sont également appelées modèles', +'Theme': 'Thème', +'There are no controllers': "Il n'y a pas de contrôleurs", +'There are no models': "Il n'y a pas de modèles", +'There are no modules': "Il n'y a pas de modules", +'There are no plugins': "Il n'y a pas de plugins", +'There are no private files': "Il n'y a pas de fichiers privés", +'There are no static files': "Il n'y a pas de fichiers statiques", +'There are no translators': "Il n'y a pas de traducteurs", +'There are no translators, only default language is supported': "Il n'y a pas de traducteurs, seule la langue par défaut est prise en charge", +'There are no views': "Il n'y a pas de vues", +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'Ces fichiers sont renvoyés sans traitement, vos images viennent ici', +'these files are served without processing, your images go here': 'ces fichiers sont servis sans transformation, vos images vont ici', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': 'Ceci est le modèle %(filename)s ', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Billet', +'Ticket ID': 'Identifiant du Billet', +'Ticket Missing': 'Billet manquant', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'TM': 'MD', +'to previous version.': 'à la version précédente.', +'To create a plugin, name a file/folder plugin_[name]': 'Pour créer un plugin, créer un fichier /dossier plugin_[nom]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'translation strings for the application': "chaînes de traduction de l'application", +'Translation strings for the application': "Chaînes de traduction pour l'application", +'try': 'essayer', +'try something like': 'essayez quelque chose comme', +'Try the mobile interface': "Essayer l'interface pour mobile", +'try view': 'essayer la vue', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Impossible de vérifier les mises à jour', +'unable to create application "%s"': 'impossible de créer l\'application "%s"', +'unable to delete file "%(filename)s"': 'impossible de supprimer le fichier "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'impossible de supprimer le plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download': 'Impossible de télécharger', +'Unable to download app': "Impossible de télécharger l'app", +'Unable to download app because:': "Impossible de télécharger l'app car:", +'Unable to download because': 'Impossible de télécharger car', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': "impossible d'analyser les fichiers CSV", +'unable to uninstall "%s"': 'impossible de désinstaller "%s"', +'unable to upgrade because "%s"': 'impossible de mettre à jour car "%s"', +'uncheck all': 'tout décocher', +'Uninstall': 'désinstaller', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'mettre à jour', +'update all languages': 'mettre à jour toutes les langues', +'Update:': 'Mise à jour:', +'Upgrade': 'Mese à jour de version', +'upgrade now': 'mettre à jour maintenant', +'upgrade now to %s': 'mettre à jour maintenant à %s', +'upgrade web2py now': 'mettre à jour web2py maintenant', +'upload': 'téléversé', +'Upload': 'Téléversé', +'Upload & install packed application': "Charger & installer l'application empaquetée", +'Upload a package:': 'Téléverser un paquet:', +'Upload and install packed application': 'Téléversement et installation du paquet applicatif', +'upload application:': "téléverser l'application:", +'Upload existing application': 'Téléverser une application existante', +'upload file:': 'téléverser le fichier:', +'upload plugin file:': 'charger fichier plugin:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Utilisez (...)&(...) pour AND, (...)|(...) pour OR, et ~(...) pour NOT afin de construire des requêtes plus complexes. ', +'Use an url:': 'Utiliser une url:', +'user': 'utilisateur', +'User': 'Utilisateur', +'Username': "Nom d'utilisateur", +'Users': 'Utilisateurs', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'variables', +'Version': 'Version', +'Versioning': 'Versioning', +'versioning': 'versioning', +'view': 'vue', +'Views': 'Vues', +'views': 'vues', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Cadre Web', +'web2py Admin Password': 'Mot de passe admin web2py', +'web2py apps to deploy': 'applications web2py à deployer', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py est à jour', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'Tweets récents sur web2py ', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py mis à jour; veuillez le redémarrer', +'Working...': 'Travail en cours...', +'WSGI reference name': 'WSGI reference name', +'YES': 'OUI', +'Yes': 'Oui', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/he.py b/web2py/applications/admin/languages/he.py new file mode 100644 index 0000000..1135398 --- /dev/null +++ b/web2py/applications/admin/languages/he.py @@ -0,0 +1,622 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'he-il', +'!langname!': 'עברית', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"עדכן" הוא ביטוי אופציונאלי, כגון "field1=newvalue". אינך יוכל להשתמש בjoin, בעת שימוש ב"עדכן" או "מחק".', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s רשומות נמחקו', +'%s %%{row} updated': '%s רשומות עודכנו', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(requires internet access)': '(requires internet access)', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(למשל "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files', +'A new version of web2py is available: %s': 'גירסא חדשה של web2py זמינה: %s', +'Abort': 'Abort', +'About': 'אודות', +'About application': 'אודות אפליקציה', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Add breakpoint', +'additional code for your application': 'קוד נוסף עבור האפליקציה שלך', +'Additional code for your application': 'Additional code for your application', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'ממשק המנהל מנוטרל כי לא הוגדרה סיסמת מנהל', +'admin disabled because not supported on google app engine': 'ממשק המנהל נוטרל, כי אין תמיכה בGoogle app engine', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'ממשק מנהל נוטרל, כי לא ניתן לגשת לקובץ הסיסמאות', +'Admin is disabled because insecure channel': 'ממשק האדמין נוטרל בשל גישה לא מאובטחת', +'Admin language': 'Admin language', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'administrative interface', +'Administrator Password:': 'סיסמת מנהל', +'and rename it (required):': 'ושנה את שמו (חובה):', +'and rename it:': 'ושנה את שמו:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'מנהל מסד הנתונים', +'appadmin is disabled because insecure channel': 'מנהל מסד הנתונים נוטרל בשל ערוץ לא מאובטח', +'Application': 'Application', +'application "%s" uninstalled': 'אפליקציה "%s" הוסרה', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'אפליקציה קומפלה', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'לא ניתן לערוך אפליקציה מקומפלת', +'Application name:': 'Application name:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'are not used', +'are not used yet': 'are not used yet', +'Are you sure you want to delete file "%s"?': 'האם אתה בטוח שברצונך למחוק את הקובץ "%s"?', +'Are you sure you want to delete plugin "%s"?': 'האם אתה בטוח שברצונך למחוק את התוסף "%s"?', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Are you sure you want to uninstall application "%s"?': 'האם אתה בטוח שברצונך להסיר את האפליקציה "%s"?', +'Are you sure you want to upgrade web2py now?': 'האם אתה בטוח שאתה רוצה לשדרג את web2py עכשיו?', +'Are you sure?': 'Are you sure?', +'arguments': 'פרמטרים', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'לתשומת ליבך: ניתן להתחבר רק בערוץ מאובטח (HTTPS) או מlocalhost', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'לתשומת ליבך: אין לערוך מספר בדיקות במקביל, שכן הן עשויות להפריע זו לזו', +'ATTENTION: you cannot edit the running application!': 'לתשומת ליבך: לא ניתן לערוך אפליקציה בזמן הרצתה', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available databases and tables': 'מסדי נתונים וטבלאות זמינים', +'Available Databases and Tables': 'Available Databases and Tables', +'back': 'אחורה', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'Begin': 'Begin', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': 'מטמון', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'מטמון, שגיאות וסשן נוקו', +'can be a git repo': 'can be a git repo', +'Cancel': 'Cancel', +'Cannot be empty': 'אינו יכול להישאר ריק', +'Cannot compile: there are errors in your app:': 'לא ניתן לקמפל: ישנן שגיאות באפליקציה שלך:', +'cannot create file': 'לא מצליח ליצור קובץ', +'cannot upload file "%(filename)s"': 'לא הצלחתי להעלות את הקובץ "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'סיסמת מנהל שונתה', +'change editor settings': 'change editor settings', +'Changelog': 'Changelog', +'check all': 'סמן הכל', +'Check for upgrades': 'check for upgrades', +'Check to delete': 'סמן כדי למחוק', +'Checking for upgrades...': 'מחפש עדכונים', +'Clean': 'נקה', +'Clear': 'Clear', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Click row to expand traceback': 'Click row to expand traceback', +'Click row to view a ticket': 'Click row to view a ticket', +'click to check for upgrades': 'לחץ כדי לחפש עדכונים', +'code': 'קוד', +'Code listing': 'Code listing', +'collapse/expand all': 'collapse/expand all', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'קמפל', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'אפליקציה מקומפלת הוסרה', +'Condition': 'Condition', +'continue': 'continue', +'Controllers': 'בקרים', +'controllers': 'בקרים', +'Count': 'Count', +'Create': 'צור', +'create file with filename:': 'צור קובץ בשם:', +'create new application:': 'צור אפליקציה חדשה:', +'Create new simple application': 'צור אפליקציה חדשה', +'Create/Upload': 'Create/Upload', +'created by': 'נוצר ע"י', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'משימות מתוזמנות', +'Current request': 'בקשה נוכחית', +'Current response': 'מענה נוכחי', +'Current session': 'סשן זה', +'currently running': 'currently running', +'currently saved or': 'נשמר כעת או', +'data uploaded': 'המידע הועלה', +'Database': 'Database', +'database': 'מסד נתונים', +'Database %s select': 'Database %s select', +'database %s select': 'מסד הנתונים %s נבחר', +'Database administration': 'Database administration', +'database administration': 'ניהול מסד נתונים', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'תאריך ושעה', +'db': 'מסד נתונים', +'Debug': 'Debug', +'defines tables': 'הגדר טבלאות', +'Delete': 'מחק', +'delete': 'מחק', +'delete all checked': 'סמן הכל למחיקה', +'delete plugin': 'מחק תוסף', +'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)', +'Delete:': 'מחק:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'deploy', +'Deploy on Google App Engine': 'העלה ל Google App Engine', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description:': 'Description:', +'design': 'עיצוב', +'Detailed traceback description': 'Detailed traceback description', +'details': 'details', +'direction: ltr': 'direction: rtl', +'directory not found': 'directory not found', +'Disable': 'Disable', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'docs', +'Docs': 'Docs', +'done!': 'הסתיים!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'download layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'download plugins', +'Download plugins from repository': 'Download plugins from repository', +'EDIT': 'ערוך!', +'Edit': 'ערוך', +'edit all': 'edit all', +'Edit application': 'ערוך אפליקציה', +'edit controller': 'ערוך בקר', +'edit controller:': 'edit controller:', +'Edit current record': 'ערוך רשומה נוכחית', +'edit views:': 'ערוך קיבצי תצוגה:', +'Editing %s': 'Editing %s', +'Editing file "%s"': 'עורך את הקובץ "%s"', +'Editing Language file': 'עורך את קובץ השפה', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Enable', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Enterprise Web Framework': 'סביבת הפיתוח לרשת', +'Error': 'Error', +'Error logs for "%(app)s"': 'דו"ח שגיאות עבור אפליקציה "%(app)s"', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Error ticket', +'Errors': 'שגיאות', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'נתוני החריגה', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'יצא לקובץ csv', +'Exports:': 'Exports:', +'exposes': 'חושף את', +'exposes:': 'exposes:', +'extends': 'הרחבה של', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module because:': 'נכשל בטעינה חוזרת של מודול בגלל:', +'File': 'File', +'file "%(filename)s" created': 'הקובץ "%(filename)s" נוצר', +'file "%(filename)s" deleted': 'הקובץ "%(filename)s" נמחק', +'file "%(filename)s" uploaded': 'הקובץ "%(filename)s" הועלה', +'file "%s" of %s restored': 'הקובץ "%s" of %s שוחזר', +'file changed on disk': 'קובץ שונה על גבי הדיסק', +'file does not exist': 'קובץ לא נמצא', +'file not found': 'file not found', +'file saved on %(time)s': 'הקובץ נשמר בשעה %(time)s', +'file saved on %s': 'הקובץ נשמר ב%s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'filter', +'Find Next': 'Find Next', +'Find Previous': 'Find Previous', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': 'פונקציות שלא הוגדר להן doctest ירשמו כבדיקות ש[עברו בהצלחה].', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Help': 'עזרה', +'here': 'here', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'htmledit': 'עורך ויזואלי', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'אם בדו"ח לעיל מופיע מספר דו"ח שגיאה, זה מצביע על שגיאה בבקר, עוד לפני שניתן היה להריץ את הdoctest. לרוב מדובר בשגיאת הזחה, או שגיאה שאינה בקוד של הפונקציה.\r\nכותרת ירוקה מצביע על כך שכל הבדיקות (אם הוגדרו) עברו בהצלחה, במידה ותוצאות הבדיקה אינן מופיעות.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'יבא\\יצא', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'מכיל', +'Indent with tabs': 'Indent with tabs', +'insert new': 'הכנס נוסף', +'insert new %s': 'הכנס %s נוסף', +'inspect attributes': 'inspect attributes', +'Install': 'התקן', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'אפליקציות מותקנות', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'שגיאה מובנית', +'internal error: %s': 'internal error: %s', +'Internal State': 'מצב מובנה', +'Invalid action': 'הוראה לא קיימת', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'סיסמא שגויה', +'invalid password.': 'invalid password.', +'Invalid Query': 'שאילתה לא תקינה', +'invalid request': 'בקשה לא תקינה', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'דו"ח שגיאה לא קיים', +'Key': 'Key', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'קובץ השפה "%(filename)s" נוצר\\עודכן', +'Language files (static strings) updated': 'קובץ השפה (מחרוזות סטאטיות) עודכן', +'languages': 'שפות', +'Languages': 'שפות', +'Last Revision': 'Last Revision', +'Last saved on:': 'לאחרונה נשמר בתאריך:', +'License for': 'רשיון עבור', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Loading...': 'Loading...', +'loading...': 'טוען...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'Login': 'התחבר', +'login': 'התחבר', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'התחבר לממשק המנהל', +'Login/Register': 'Login/Register', +'Logout': 'התנתק', +'lost password': 'lost password', +'Main Menu': 'Main Menu', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Memberships': 'Memberships', +'merge': 'מזג', +'Models': 'מבני נתונים', +'models': 'מבני נתונים', +'Modified On': 'Modified On', +'Modules': 'מודולים', +'modules': 'מודולים', +'Multi User Mode': 'Multi User Mode', +'new application "%s" created': 'האפליקציה "%s" נוצרה', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'New Application Wizard', +'New application wizard': 'New application wizard', +'new plugin installed': 'פלאגין חדש הותקן', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'רשומה חדשה', +'new record inserted': 'הרשומה נוספה', +'New simple application': 'New simple application', +'next': 'next', +'next %s rows': 'next %s rows', +'next 100 rows': '100 הרשומות הבאות', +'NO': 'לא', +'no changes': 'no changes', +'No databases in this application': 'אין מסדי נתונים לאפליקציה זו', +'No Interaction yet': 'No Interaction yet', +'no match': 'לא נמצאה התאמה', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'או יבא מקובץ csv', +'or provide app url:': 'או ספק כתובת url של אפליקציה', +'Original/Translation': 'מקור\\תרגום', +'Overview': 'Overview', +'Overwrite installed app': 'התקן על גבי אפלקציה מותקנת', +'Pack all': 'ארוז הכל', +'Pack compiled': 'ארוז מקומפל', +'Pack custom': 'Pack custom', +'pack plugin': 'ארוז תוסף', +'PAM authenticated user, cannot change password here': 'שינוי סיסמא באמצעות PAM אינו יכול להתבצע כאן', +'password changed': 'סיסמא שונתה', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'מעיין בקובץ', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Please', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'תוסף "%(plugin)s" נמחק', +'Plugin "%s" in application': 'פלאגין "%s" של אפליקציה', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'plugins', +'Plugins': 'תוספים', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'מופעל ע"י', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '100 הרשומות הקודמות', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Project Progress', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'שאילתה:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Record': 'Record', +'record': 'רשומה', +'record does not exist': 'הרשומה אינה קיימת', +'record id': 'מזהה רשומה', +'Record id': 'Record id', +'refresh': 'refresh', +'register': 'register', +'Reload routes': 'Reload routes', +'Remove compiled': 'הסר מקומפל', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Replace', +'Replace All': 'Replace All', +'Repository (%s)': 'Repository (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Resolve Conflict file': 'הסר קובץ היוצר קונפליקט', +'response': 'response', +'restart': 'restart', +'restore': 'שחזר', +'return': 'return', +'Revert': 'Revert', +'revert': 'חזור לגירסא קודמת', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Rows in Table', +'Rows in table': 'רשומות בטבלה', +'Rows selected': 'רשומות נבחרו', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'Running on %s', +'Save': 'Save', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Save via Ajax', +'Saved file hash:': 'גיבוב הקובץ השמור:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'selected': 'נבחרו', +'session': 'session', +'session expired': 'תם הסשן', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'שורת פקודה', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'אתר', +'Size of cache:': 'Size of cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': 'לא ניתן היה להסיר חלק מהקבצים', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Start a new app', +'Start searching': 'Start searching', +'Start wizard': 'start wizard', +'state': 'מצב', +'Static': 'Static', +'static': 'קבצים סטאטיים', +'Static files': 'קבצים סטאטיים', +'Statistics': 'Statistics', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'submit': 'שלח', +'Submit': 'Submit', +'successful': 'successful', +'Sure you want to delete this object?': 'האם אתה בטוח שברצונך למחוק אובייקט זה?', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': 'טבלה', +'Table': 'Table', +'Temporary': 'Temporary', +'test': 'בדיקות', +'Testing application': 'בודק את האפליקציה', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"שאליתה" היא תנאי כגון "db1.table1.filed1=\'value\'" ביטוי כמו db.table1.field1=db.table2.field1 יחולל join', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'the application logic, each URL path is mapped in one exposed function in the controller': 'הלוגיקה של האפליקציה, כל url ממופה לפונקציה חשופה בבקר', +'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller', +'the data representation, define database tables and sets': 'ייצוג המידע, בו מוגדרים טבלאות ומבנים', +'The data representation, define database tables and sets': 'The data representation, define database tables and sets', +'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates', +'the presentations layer, views are also known as templates': 'שכבת התצוגה, המכונה גם template', +'Theme': 'Theme', +'There are no controllers': 'אין בקרים', +'There are no models': 'אין מבני נתונים', +'There are no modules': 'אין מודולים', +'There are no plugins': 'There are no plugins', +'There are no private files': 'There are no private files', +'There are no static files': 'אין קבצים סטאטיים', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'אין תרגומים. רק שפת ברירת המחדל נתמכת', +'There are no views': 'אין קבצי תצוגה', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'These files are served without processing, your images go here', +'these files are served without processing, your images go here': 'אלו הם קבצים הנשלחים מהשרת ללא עיבוד. הכנס את התמונות כאן', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': 'זוהי תבנית הקובץ %(filename)s ', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'דו"ח שגיאה', +'Ticket ID': 'Ticket ID', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'TM': 'סימן רשום', +'to previous version.': 'אין גירסא קודמת', +'To create a plugin, name a file/folder plugin_[name]': 'כדי ליצור תוסף, קרא לקובץ או סיפריה בשם לפי התבנית plugin_[name]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'translation strings for the application': 'מחרוזות תרגום עבור האפליקציה', +'Translation strings for the application': 'Translation strings for the application', +'try': 'נסה', +'try something like': 'נסה משהו כמו', +'Try the mobile interface': 'Try the mobile interface', +'try view': 'try view', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'לא ניתן היה לבדוק אם יש שדרוגים', +'unable to create application "%s"': 'נכשל ביצירת האפליקציה "%s"', +'unable to delete file "%(filename)s"': 'נכשל במחיקת הקובץ "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'נכשל במחיקת התוסף "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download app because:': 'לא ניתן היה להוריד את האפליקציה כי:', +'Unable to download because': 'לא הצלחתי להוריד כי', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'לא הצלחתי לנתח את הקלט של קובץ csv', +'unable to uninstall "%s"': 'לא ניתן להסיר את "%s"', +'unable to upgrade because "%s"': 'לא ניתן היה לשדרג כי "%s"', +'uncheck all': 'הסר סימון מהכל', +'Uninstall': 'הסר התקנה', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'עדכן', +'update all languages': 'עדכן את כלל קיבצי השפה', +'Update:': 'עדכן:', +'Upgrade': 'Upgrade', +'upgrade now': 'upgrade now', +'upgrade now to %s': 'upgrade now to %s', +'upgrade web2py now': 'שדרג את web2py עכשיו', +'upload': 'upload', +'Upload': 'Upload', +'Upload & install packed application': 'העלה והתקן אפליקציה ארוזה', +'Upload a package:': 'Upload a package:', +'Upload and install packed application': 'Upload and install packed application', +'upload application:': 'העלה אפליקציה:', +'upload file:': 'העלה קובץ:', +'upload plugin file:': 'העלה קובץ תוסף:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'השתמש ב (...)&(...) עבור תנאי AND, (...)|(...) עבור תנאי OR ו~(...) עבור תנאי NOT ליצירת שאילתות מורכבות', +'Use an url:': 'Use an url:', +'User': 'User', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'משתנים', +'Version': 'גירסא', +'Versioning': 'Versioning', +'versioning': 'מנגנון גירסאות', +'view': 'הצג', +'Views': 'מראה', +'views': 'מראה', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py מותקנת בגירסתה האחרונה', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'ציוצים אחרונים של web2py', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py שודרגה; נא אתחל אותה', +'Working...': 'Working...', +'WSGI reference name': 'WSGI reference name', +'YES': 'כן', +'Yes': 'Yes', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/it.py b/web2py/applications/admin/languages/it.py new file mode 100644 index 0000000..64d16f5 --- /dev/null +++ b/web2py/applications/admin/languages/it.py @@ -0,0 +1,649 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'it', +'!langname!': 'Italiano', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" è un\'espressione opzionale come "campo1=\'nuovo valore\'". Non si può fare "update" o "delete" dei risultati di un JOIN ', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s righe ("record") cancellate', +'%s %%{row} updated': '%s righe ("record") modificate', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%d/%m/%Y', +'%Y-%m-%d %H:%M:%S': '%d/%m/%Y %H:%M:%S', +'(requires internet access)': '(requires internet access)', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(qualcosa simile a "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(file **gluon/contrib/plural_rules/%s.py** is not found)', +'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files', +'A new version of web2py is available: %s': 'È disponibile una nuova versione di web2py: %s', +'Abort': 'Abort', +'About': 'informazioni', +'About application': "Informazioni sull'applicazione", +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Add breakpoint', +'additional code for your application': 'righe di codice aggiuntive per la tua applicazione', +'Additional code for your application': 'Additional code for your application', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'amministrazione disabilitata per mancanza di password amministrativa', +'admin disabled because not supported on google app engine': 'amministrazione non supportata da Google Apps Engine', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'amministrazione disabilitata per impossibilità di leggere il file delle password', +'Admin is disabled because insecure channel': 'amministrazione disabilitata: comunicazione non sicura', +'Admin language': 'Admin language', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'administrative interface', +'Administrator Password:': 'Password Amministratore:', +'An error occured, please %s the page': 'An error occured, please %s the page', +'and rename it (required):': 'e rinominala (obbligatorio):', +'and rename it:': 'e rinominala:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'appadmin ', +'appadmin is disabled because insecure channel': 'amministrazione app (appadmin) disabilitata: comunicazione non sicura', +'Application': 'Application', +'application "%s" uninstalled': 'applicazione "%s" disinstallata', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'applicazione compilata', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': "l'applicazione è compilata e non si può modificare", +'Application name:': 'Application name:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'are not used', +'are not used yet': 'are not used yet', +'Are you sure you want to delete file "%s"?': 'Confermi di voler cancellare il file "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Confermi di voler cancellare il plugin "%s"?', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Are you sure you want to uninstall application "%s"?': 'Confermi di voler disinstallare l\'applicazione "%s"?', +'Are you sure you want to upgrade web2py now?': 'Confermi di voler aggiornare web2py ora?', +'Are you sure?': 'Are you sure?', +'arguments': 'arguments', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': "ATTENZIONE: L'accesso richiede una connessione sicura (HTTPS) o l'esecuzione di web2py in locale (connessione su localhost)", +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATTENTZIONE: NON ESEGUIRE PIÙ TEST IN PARALLELO (I TEST NON SONO "THREAD SAFE")', +'ATTENTION: you cannot edit the running application!': "ATTENZIONE: non puoi modificare l'applicazione correntemente in uso ", +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available databases and tables': 'Database e tabelle disponibili', +'Available Databases and Tables': 'Available Databases and Tables', +'back': 'indietro', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'Begin': 'Begin', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'pulitura cache, errori and sessioni ', +'can be a git repo': 'can be a git repo', +'Cancel': 'Cancel', +'Cannot be empty': 'Non può essere vuoto', +'Cannot compile: there are errors in your app:': "Compilazione fallita: ci sono errori nell'applicazione.", +'cannot create file': 'impossibile creare il file', +'cannot upload file "%(filename)s"': 'impossibile caricare il file "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'change admin password', +'change editor settings': 'change editor settings', +'change password': 'cambia password', +'Changelog': 'Changelog', +'check all': 'controlla tutto', +'Check for upgrades': 'check for upgrades', +'Check to delete': 'Seleziona per cancellare', +'Checking for upgrades...': 'Controllo aggiornamenti in corso...', +'Clean': 'pulisci', +'Clear': 'Clear', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'click here for online examples': 'clicca per vedere gli esempi', +'click here for the administrative interface': "clicca per l'interfaccia amministrativa", +'Click row to expand traceback': 'Click row to expand traceback', +'Click row to view a ticket': 'Click row to view a ticket', +'click to check for upgrades': 'clicca per controllare presenza di aggiornamenti', +'code': 'code', +'Code listing': 'Code listing', +'collapse/expand all': 'collapse/expand all', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'compila', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': "rimosso il codice compilato dell'applicazione", +'Condition': 'Condition', +'continue': 'continue', +'Controller': 'Controller', +'Controllers': 'Controllers', +'controllers': 'controllers', +'Copyright': 'Copyright', +'Count': 'Count', +'Create': 'crea', +'create file with filename:': 'crea un file col nome:', +'create new application:': 'create new application:', +'Create new simple application': 'Crea nuova applicazione', +'Create/Upload': 'Create/Upload', +'created by': 'creato da', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Richiesta (request) corrente', +'Current response': 'Risposta (response) corrente', +'Current session': 'Sessione (session) corrente', +'currently running': 'currently running', +'currently saved or': 'attualmente salvato o', +'customize me!': 'Personalizzami!', +'data uploaded': 'dati caricati', +'Database': 'Database', +'database': 'database', +'Database %s select': 'Database %s select', +'database %s select': 'database %s select', +'Database administration': 'Database administration', +'database administration': 'amministrazione database', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Data and Ora', +'db': 'db', +'DB Model': 'Modello di DB', +'Debug': 'Debug', +'defines tables': 'defininisce le tabelle', +'Delete': 'Cancella', +'delete': 'Cancella', +'delete all checked': 'cancella tutti i selezionati', +'delete plugin': 'cancella plugin', +'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)', +'Delete:': 'Cancella:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'deploy', +'Deploy on Google App Engine': 'Installa su Google App Engine', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description:': 'Description:', +'design': 'progetta', +'Detailed traceback description': 'Detailed traceback description', +'details': 'details', +'direction: ltr': 'direction: ltr', +'directory not found': 'directory not found', +'Disable': 'Disable', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'docs', +'Docs': 'Docs', +'done!': 'fatto!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'download layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'download plugins', +'Download plugins from repository': 'Download plugins from repository', +'EDIT': 'MODIFICA', +'Edit': 'modifica', +'edit all': 'edit all', +'Edit application': 'Modifica applicazione', +'edit controller': 'modifica controller', +'edit controller:': 'edit controller:', +'Edit current record': 'Modifica record corrente', +'edit profile': 'modifica profilo', +'Edit This App': 'Modifica questa applicazione', +'edit views:': 'modifica viste (view):', +'Editing %s': 'Editing %s', +'Editing Language file': 'Editing Language file', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Enable', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Enterprise Web Framework': 'Enterprise Web Framework', +'Error': 'Error', +'Error logs for "%(app)s"': 'Log degli errori per "%(app)s"', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Error ticket', +'Errors': 'errori', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Exception instance attributes', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation': 'Expand Abbreviation', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'esporta come file CSV', +'Exports:': 'Exports:', +'exposes': 'espone', +'exposes:': 'exposes:', +'extends': 'estende', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module because:': 'ricaricamento modulo fallito perché:', +'File': 'File', +'file "%(filename)s" created': 'creato il file "%(filename)s"', +'file "%(filename)s" deleted': 'cancellato il file "%(filename)s"', +'file "%(filename)s" uploaded': 'caricato il file "%(filename)s"', +'file "%s" of %s restored': 'ripristinato "%(filename)s"', +'file changed on disk': 'il file ha subito una modifica su disco', +'file does not exist': 'file inesistente', +'file not found': 'file not found', +'file saved on %(time)s': "file salvato nell'istante %(time)s", +'file saved on %s': 'file salvato: %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'filter', +'Find Next': 'Find Next', +'Find Previous': 'Find Previous', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': 'I test delle funzioni senza "doctests" risulteranno sempre [passed].', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Get from URL:': 'Get from URL:', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Hello World': 'Salve Mondo', +'Help': 'aiuto', +'here': 'here', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'htmledit': 'modifica come html', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Importa/Esporta', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'include', +'Indent with tabs': 'Indent with tabs', +'Index': 'Indice', +'insert new': 'inserisci nuovo', +'insert new %s': 'inserisci nuovo %s', +'inspect attributes': 'inspect attributes', +'Install': 'installa', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Applicazioni installate', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'errore interno', +'internal error: %s': 'internal error: %s', +'Internal State': 'Stato interno', +'Invalid action': 'Azione non valida', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'password non valida', +'invalid password.': 'invalid password.', +'Invalid Query': 'Richiesta (query) non valida', +'invalid request': 'richiesta non valida', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'ticket non valido', +'Key': 'Key', +'Key bindings': 'Key bindings', +'Key bindings for ZenCoding Plugin': 'Key bindings for ZenCoding Plugin', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'file linguaggio "%(filename)s" creato/aggiornato', +'Language files (static strings) updated': 'Linguaggi (documenti con stringhe statiche) aggiornati', +'languages': 'linguaggi', +'Languages': 'Linguaggi', +'Last Revision': 'Last Revision', +'Last saved on:': 'Ultimo salvataggio:', +'Layout': 'Layout', +'License for': 'Licenza relativa a', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Loading...': 'Loading...', +'loading...': 'caricamento...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'Login': 'Accesso', +'login': 'accesso', +'Login successful': 'Login successful', +'Login to the Administrative Interface': "Accesso all'interfaccia amministrativa", +'Login/Register': 'Login/Register', +'Logout': 'uscita', +'lost password': 'lost password', +'Main Menu': 'Menu principale', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Memberships': 'Memberships', +'Menu Model': 'Menu Modelli', +'merge': 'unisci', +'Models': 'Modelli', +'models': 'modelli', +'Modified On': 'Modified On', +'Modules': 'Moduli', +'modules': 'moduli', +'Multi User Mode': 'Multi User Mode', +'new application "%s" created': 'creata la nuova applicazione "%s"', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'New Application Wizard', +'New application wizard': 'New application wizard', +'new plugin installed': 'installato nuovo plugin', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'Nuovo elemento (record)', +'new record inserted': 'nuovo record inserito', +'New simple application': 'New simple application', +'next': 'next', +'next %s rows': 'next %s rows', +'next 100 rows': 'prossime 100 righe', +'NO': 'NO', +'no changes': 'no changes', +'No databases in this application': 'Nessun database presente in questa applicazione', +'No Interaction yet': 'No Interaction yet', +'no match': 'nessuna corrispondenza', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'online designer': 'online designer', +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'oppure importa da file CSV', +'or provide app url:': "oppure fornisci url dell'applicazione:", +'Original/Translation': 'Originale/Traduzione', +'Overview': 'Overview', +'Overwrite installed app': 'sovrascrivi applicazione installata', +'Pack all': 'crea pacchetto', +'Pack compiled': 'crea pacchetto del codice compilato', +'Pack custom': 'Pack custom', +'pack plugin': 'crea pacchetto del plugin', +'PAM authenticated user, cannot change password here': 'utente autenticato tramite PAM, impossibile modificare password qui', +'password changed': 'password modificata', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Uno sguardo al file', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Please', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" cancellato', +'Plugin "%s" in application': 'Plugin "%s" nell\'applicazione', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'plugins', +'Plugins': 'I Plugins', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Powered by', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '100 righe precedenti', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Project Progress', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Richiesta (query):', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Record': 'Record', +'record': 'record', +'record does not exist': 'il record non esiste', +'record id': 'ID del record', +'Record id': 'Record id', +'refresh': 'refresh', +'register': 'registrazione', +'reload': 'reload', +'Reload routes': 'Reload routes', +'Remove compiled': 'rimozione codice compilato', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Replace', +'Replace All': 'Replace All', +'Repository (%s)': 'Repository (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Resolve Conflict file': 'File di risoluzione conflitto', +'response': 'response', +'restart': 'restart', +'restore': 'ripristino', +'return': 'return', +'Revert': 'Revert', +'revert': 'versione precedente', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Role', +'Roles': 'Roles', +'Rows in table': 'Righe nella tabella', +'Rows in Table': 'Rows in Table', +'Rows selected': 'Righe selezionate', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'Running on %s', +'Save': 'Save', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Save via Ajax', +'Saved file hash:': 'Hash del file salvato:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'selected': 'selezionato', +'session': 'session', +'session expired': 'sessions scaduta', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'shell', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'sito', +'Size of cache:': 'Size of cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': 'non è stato possibile rimuovere alcuni files', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Start a new app', +'Start searching': 'Start searching', +'Start wizard': 'start wizard', +'state': 'stato', +'Static': 'Static', +'static': 'statico', +'Static files': 'Files statici', +'Statistics': 'Statistics', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'Stylesheet': 'Foglio di stile (stylesheet)', +'submit': 'invia', +'Submit': 'Submit', +'successful': 'successful', +'Sure you want to delete this object?': 'Vuoi veramente cancellare questo oggetto?', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': 'tabella', +'Table': 'Table', +'Temporary': 'Temporary', +'test': 'test', +'Testing application': 'Test applicazione in corsg', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'La richiesta (query) è una condizione come ad esempio "db.tabella1.campo1==\'valore\'". Una condizione come "db.tabella1.campo1==db.tabella2.campo2" produce un "JOIN" SQL.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'the application logic, each URL path is mapped in one exposed function in the controller': 'logica dell\'applicazione, ogni percorso "URL" corrisponde ad una funzione esposta da un controller', +'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller', +'the data representation, define database tables and sets': 'rappresentazione dei dati, definizione di tabelle di database e di "set" ', +'The data representation, define database tables and sets': 'The data representation, define database tables and sets', +'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates', +'the presentations layer, views are also known as templates': 'Presentazione dell\'applicazione, viste (views, chiamate anche "templates")', +'Theme': 'Theme', +'There are no controllers': 'Non ci sono controller', +'There are no models': 'Non ci sono modelli', +'There are no modules': 'Non ci sono moduli', +'There are no plugins': 'There are no plugins', +'There are no private files': 'There are no private files', +'There are no static files': 'Non ci sono file statici', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'Non ci sono traduzioni, viene solo supportato il linguaggio di base', +'There are no views': 'Non ci sono viste ("view")', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'These files are served without processing, your images go here', +'these files are served without processing, your images go here': 'questi files vengono serviti così come sono, le immagini vanno qui', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': 'Questo è il template %(filename)s', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Ticket', +'Ticket ID': 'Ticket ID', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'TM': 'TM', +'to previous version.': 'torna a versione precedente', +'To create a plugin, name a file/folder plugin_[name]': 'Per creare un plugin, chiamare un file o cartella plugin_[nome]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'translation strings for the application': "stringhe di traduzioni per l'applicazione", +'Translation strings for the application': 'Translation strings for the application', +'try': 'prova', +'try something like': 'prova qualcosa come', +'Try the mobile interface': 'Try the mobile interface', +'try view': 'try view', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Impossibile controllare presenza di aggiornamenti', +'unable to create application "%s"': 'impossibile creare applicazione "%s"', +'unable to delete file "%(filename)s"': 'impossibile rimuovere file "%(plugin)s"', +'unable to delete file plugin "%(plugin)s"': 'impossibile rimuovere file di plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download app because:': 'Impossibile scaricare applicazione perché', +'Unable to download because': 'Impossibile scaricare perché', +'Unable to download because:': 'Unable to download because:', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'non riesco a decodificare questo file CSV', +'unable to uninstall "%s"': 'impossibile disinstallare "%s"', +'unable to upgrade because "%s"': 'impossibile aggiornare perché "%s"', +'uncheck all': 'smarca tutti', +'Uninstall': 'Disinstalla', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'aggiorna', +'update all languages': 'aggiorna tutti i linguaggi', +'Update:': 'Aggiorna:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'upgrade now to %s', +'upgrade web2py now': 'upgrade web2py now', +'upload': 'upload', +'Upload': 'Upload', +'Upload & install packed application': 'Carica ed installa pacchetto con applicazione', +'Upload a package:': 'Upload a package:', +'Upload and install packed application': 'Upload and install packed application', +'upload application:': 'carica applicazione:', +'upload file:': 'carica file:', +'upload plugin file:': 'carica file di plugin:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Per costruire richieste (query) più complesse si usano (...)&(...) come "e" (AND), (...)|(...) come "o" (OR), e ~(...) come negazione (NOT).', +'Use an url:': 'Use an url:', +'User': 'User', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'variables', +'Version': 'Versione', +'Version %s.%s.%s %s (%s)': 'Version %s.%s.%s %s (%s)', +'Version %s.%s.%s (%s) %s': 'Version %s.%s.%s (%s) %s', +'Versioning': 'Versioning', +'versioning': 'sistema di versioni', +'View': 'Vista', +'view': 'vista', +'Views': 'Viste', +'views': 'viste', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py è aggiornato', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'Tweets recenti per web2py', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py aggiornato; prego riavviarlo', +'Welcome %s': 'Benvenuto %s', +'Welcome to web2py': 'Benvenuto su web2py', +'Working...': 'Working...', +'WSGI reference name': 'WSGI reference name', +'YES': 'SI', +'Yes': 'Yes', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/ja.py b/web2py/applications/admin/languages/ja.py new file mode 100644 index 0000000..551c795 --- /dev/null +++ b/web2py/applications/admin/languages/ja.py @@ -0,0 +1,586 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'ja-jp', +'!langname!': '日本語', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s rows deleted', +'%s %%{row} updated': '%s rows updated', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(requires internet access)': '(インターネットアクセスが必要)', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(例: "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'@markmin\x01Searching: **%s** %%{file}': '検索中: **%s** ファイル', +'Abort': '中断', +'About': 'About', +'About application': 'アプリケーションについて', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Add breakpoint', +'Additional code for your application': 'アプリケーションに必要な追加記述', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'admin disabled because no admin password', +'admin disabled because not supported on google app engine': 'admin disabled because not supported on google app engine', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'admin disabled because unable to access password file', +'Admin is disabled because insecure channel': 'Admin is disabled because insecure channel', +'Admin language': '管理画面の言語', +'Admin versioning page': 'Admin versioning page', +'administrative interface': '管理画面', +'Administrator Password:': '管理者パスワード:', +'and rename it:': 'ファイル名を変更:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'アプリ管理画面', +'appadmin is disabled because insecure channel': 'appadmin is disabled because insecure channel', +'Application': 'Application', +'application "%s" uninstalled': '"%s"アプリケーションが削除されました', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'アプリケーションがコンパイルされました', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'application is compiled and cannot be designed', +'Application name:': 'アプリケーション名:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'are not used', +'are not used yet': 'are not used yet', +'Are you sure you want to delete file "%s"?': 'Are you sure you want to delete file "%s"?', +'Are you sure you want to delete plugin "%s"?': '"%s"プラグインを削除してもよろしいですか?', +'Are you sure you want to delete this object?': 'このオブジェクトを削除してもよろしいですか?', +'Are you sure you want to uninstall application "%s"?': '"%s"アプリケーションを削除してもよろしいですか?', +'Are you sure?': 'Are you sure?', +'arguments': '引数', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': '注意: 安全(HTTPS)な接続でログインするかlocalhostで実行されている必要があります。', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': '注意: テストはスレッドセーフではないので複数のテストを同時に実行しないでください。', +'ATTENTION: you cannot edit the running application!': '注意: 実行中のアプリケーションは編集できません!', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available databases and tables': '利用可能なデータベースとテーブル一覧', +'Available Databases and Tables': 'Available Databases and Tables', +'back': '戻る', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': '基本情報', +'Begin': '開始', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'cache, errors and sessions cleaned', +'can be a git repo': 'can be a git repo', +'Cancel': 'Cancel', +'Cannot be empty': 'Cannot be empty', +'Cannot compile: there are errors in your app:': 'Cannot compile: there are errors in your app:', +'cannot create file': 'cannot create file', +'cannot upload file "%(filename)s"': '"%(filename)s"ファイルをアップロードできません', +'Change Admin Password': 'Change Admin Password', +'Change admin password': '管理者パスワード変更', +'change editor settings': 'change editor settings', +'Changelog': 'Changelog', +'check all': '全てを選択', +'Check for upgrades': '更新チェック', +'Check to delete': 'Check to delete', +'Checking for upgrades...': '更新を確認中...', +'Clean': '一時データ削除', +'Clear': 'Clear', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Click row to expand traceback': '列をクリックしてトレースバックを展開', +'Click row to view a ticket': 'Click row to view a ticket', +'code': 'コード', +'Code listing': 'Code listing', +'collapse/expand all': '全て開閉する', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'コンパイル', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'コンパイル済みのアプリケーションが削除されました', +'Condition': 'Condition', +'continue': 'continue', +'Controllers': 'コントローラ', +'controllers': 'コントローラ', +'Count': '回数', +'Create': '作成', +'create file with filename:': 'ファイル名:', +'Create/Upload': 'Create/Upload', +'created by': '作成者', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Current request', +'Current response': 'Current response', +'Current session': 'Current session', +'currently running': '現在実行中', +'currently saved or': '現在保存されているデータ または', +'data uploaded': 'data uploaded', +'Database': 'Database', +'Database %s select': 'Database %s select', +'Database administration': 'Database administration', +'database administration': 'データベース管理', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Date and Time', +'db': 'db', +'Debug': 'Debug', +'defines tables': 'テーブル定義', +'Delete': '削除', +'delete': 'delete', +'delete all checked': '選択したデータを全て削除', +'delete plugin': 'プラグイン削除', +'Delete this file (you will be asked to confirm deletion)': 'ファイルの削除(確認画面が出ます)', +'Delete:': 'Delete:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'デプロイ', +'Deploy on Google App Engine': 'Google App Engineにデプロイ', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description:': 'Description:', +'design': 'デザイン', +'Detailed traceback description': '詳細なトレースバック内容', +'details': '詳細', +'direction: ltr': 'direction: ltr', +'directory not found': 'directory not found', +'Disable': '無効', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'ドキュメント', +'Docs': 'Docs', +'done!': 'done!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'レイアウトのダウンロード', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'プラグインのダウンロード', +'Download plugins from repository': 'Download plugins from repository', +'Edit': '編集', +'edit all': '全て編集', +'Edit application': 'アプリケーションを編集', +'edit controller:': 'edit controller:', +'Edit current record': 'Edit current record', +'edit views:': 'ビューの編集:', +'Editing %s': 'Editing %s', +'Editing file "%s"': '"%s"ファイルを編集中', +'Editing Language file': 'Editing Language file', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': '有効', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Error': 'エラー', +'Error logs for "%(app)s"': '"%(app)s"のエラーログ', +'Error snapshot': 'エラー発生箇所', +'Error ticket': 'エラーチケット', +'Errors': 'エラー', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': '例外インスタンス引数', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'export as csv file', +'Exports:': 'Exports:', +'exposes': '公開', +'exposes:': '公開:', +'extends': '継承', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module because:': 'failed to reload module because:', +'File': 'ファイル', +'file "%(filename)s" created': 'file "%(filename)s" created', +'file "%(filename)s" deleted': 'file "%(filename)s" deleted', +'file "%(filename)s" uploaded': 'file "%(filename)s" uploaded', +'file "%s" of %s restored': 'file "%s" of %s restored', +'file changed on disk': 'file changed on disk', +'file does not exist': 'file does not exist', +'file not found': 'file not found', +'file saved on %(time)s': 'file saved on %(time)s', +'file saved on %s': 'file saved on %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'フィルタ', +'Find Next': 'Find Next', +'Find Previous': 'Find Previous', +'Form has errors': 'Form has errors', +'Frames': 'フレーム', +'Functions with no doctests will result in [passed] tests.': 'doctestsのない関数は自動的にテストをパスします。', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'アプリ生成', +'Get from URL:': 'URLから取得:', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'go!': '実行!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Help': 'ヘルプ', +'here': 'here', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'もし上記のレポートにチケット番号が含まれる場合は、doctestを実行する前に、コントローラの実行で問題があったことを示します。これはインデントの問題やその関数の外部で問題があった場合に起きるが一般的です。\n緑色のタイトルは全てのテスト(もし定義されていれば)をパスしたことを示します。その場合、テスト結果は表示されません。', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Import/Export', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'インクルード', +'Indent with tabs': 'Indent with tabs', +'index': 'index', +'inspect attributes': '引数の検査', +'Install': 'インストール', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'アプリケーション一覧', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'internal error', +'internal error: %s': 'internal error: %s', +'Internal State': 'Internal State', +'Invalid action': 'Invalid action', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'invalid password', +'invalid password.': 'invalid password.', +'Invalid Query': 'Invalid Query', +'invalid request': 'invalid request', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'invalid ticket', +'Key': 'Key', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'language file "%(filename)s" created/updated', +'Language files (static strings) updated': 'Language files (static strings) updated', +'languages': '言語', +'Languages': '言語', +'Last Revision': 'Last Revision', +'Last saved on:': '最終保存日時:', +'License for': 'License for', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Loading...': 'Loading...', +'loading...': 'ロードしています...', +'Local Apps': 'Local Apps', +'locals': 'ローカル', +'Locals##debug': 'Locals##debug', +'Login': 'ログイン', +'Login successful': 'Login successful', +'Login to the Administrative Interface': '管理画面へログイン', +'Login/Register': 'Login/Register', +'Logout': 'ログアウト', +'lost password': 'lost password', +'Main Menu': 'Main Menu', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Memberships': 'Memberships', +'merge': 'merge', +'Models': 'モデル', +'models': 'モデル', +'Modified On': 'Modified On', +'Modules': 'モジュール', +'modules': 'モジュール', +'Multi User Mode': 'Multi User Mode', +'new application "%s" created': 'new application "%s" created', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': '新規アプリケーション作成ウィザード', +'New application wizard': '新規アプリケーション作成ウィザード', +'new plugin installed': '新しいプラグインがインストールされました', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'New Record', +'new record inserted': 'new record inserted', +'New simple application': '新規アプリケーション', +'next': 'next', +'next %s rows': 'next %s rows', +'NO': 'いいえ', +'no changes': 'no changes', +'No databases in this application': 'このアプリケーションにはデータベースが存在しません', +'No Interaction yet': 'No Interaction yet', +'no match': 'no match', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'online designer': 'オンラインデザイナー', +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'or import from csv file', +'Original/Translation': 'Original/Translation', +'Overview': 'Overview', +'Overwrite installed app': 'アプリケーションを上書き', +'Pack all': 'パッケージ化', +'Pack compiled': 'コンパイルデータのパッケージ化', +'Pack custom': 'Pack custom', +'pack plugin': 'プラグインのパッケージ化', +'password changed': 'password changed', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'ファイルを参照', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Please', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': '"%(plugin)s"プラグインは削除されました', +'Plugin "%s" in application': '"%s"プラグイン', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'プラグイン', +'Plugins': 'プラグイン', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Powered by', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Project Progress', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Query:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Record': 'Record', +'record does not exist': 'record does not exist', +'Record id': 'Record id', +'refresh': 'refresh', +'register': 'register', +'Reload routes': 'ルーティング再読み込み', +'Remove compiled': 'コンパイルデータの削除', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Replace', +'Replace All': 'Replace All', +'Repository (%s)': 'Repository (%s)', +'request': 'リクエスト', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Resolve Conflict file': 'Resolve Conflict file', +'response': 'レスポンス', +'restart': '最初からやり直し', +'restore': '復元', +'return': 'return', +'Revert': 'Revert', +'revert': '一つ前に戻す', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Rows in Table', +'Rows selected': 'Rows selected', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "このファイルのテストを実行(全てのファイルに対して実行する場合は、'テスト'というボタンを使用できます)", +'Running on %s': 'Running on %s', +'Save': '保存', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Save via Ajax', +'Saved file hash:': '保存されたファイルハッシュ:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'session': 'セッション', +'session expired': 'セッションの有効期限が切れました', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'shell', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'サイト', +'Size of cache:': 'Size of cache:', +'skip to generate': 'スキップしてアプリ生成画面へ移動', +'some files could not be removed': 'some files could not be removed', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'インストールされているmercurialが見つかりません', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': '新規アプリの作成', +'Start searching': 'Start searching', +'Start wizard': 'ウィザードの開始', +'state': 'state', +'Static': 'Static', +'static': '静的ファイル', +'Static files': '静的ファイル', +'Statistics': 'Statistics', +'Step': 'ステップ', +'step': 'step', +'stop': 'stop', +'submit': 'submit', +'Submit': 'Submit', +'successful': 'successful', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'Table': 'Table', +'Temporary': 'Temporary', +'test': 'テスト', +'Testing application': 'アプリケーションをテスト中', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'The application logic, each URL path is mapped in one exposed function in the controller': 'アプリケーションロジック、それぞれのURLパスはコントローラで公開されている各関数にマッピングされています', +'The data representation, define database tables and sets': 'データの表示方法, テーブルとセットの定義', +'The presentations layer, views are also known as templates': 'プレゼンテーション層、ビューはテンプレートとしても知られています', +'Theme': 'Theme', +'There are no controllers': 'コントローラがありません', +'There are no models': 'There are no models', +'There are no modules': 'モジュールがありません', +'There are no plugins': 'プラグインはありません', +'There are no private files': 'There are no private files', +'There are no static files': 'There are no static files', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': '翻訳がないためデフォルト言語のみをサポートします', +'There are no views': 'ビューがありません', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'これらのファイルは直接参照されます, ここに画像が入ります', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Ticket', +'Ticket ID': 'チケットID', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'to previous version.': '前のバージョンへ戻す。', +'To create a plugin, name a file/folder plugin_[name]': 'ファイル名/フォルダ名 plugin_[名称]としてプラグインを作成してください', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'トレースバック', +'Translation strings for the application': 'アプリケーションの翻訳文字列', +'try something like': 'try something like', +'Try the mobile interface': 'Try the mobile interface', +'try view': 'try view', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Unable to check for upgrades', +'unable to create application "%s"': 'unable to create application "%s"', +'unable to delete file "%(filename)s"': 'unable to delete file "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'unable to delete file plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download app because:': 'Unable to download app because:', +'Unable to download because:': '以下の理由でダウンロードできません:', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'unable to parse csv file', +'unable to uninstall "%s"': 'unable to uninstall "%s"', +'unable to upgrade because "%s"': 'unable to upgrade because "%s"', +'uncheck all': '全ての選択を解除', +'Uninstall': 'アプリ削除', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'update', +'update all languages': '全ての言語を更新', +'Update:': 'Update:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'upgrade now to %s', +'upload': 'アップロード', +'Upload': 'Upload', +'Upload a package:': 'パッケージをアップロード:', +'Upload and install packed application': 'パッケージのアップロードとインストール', +'upload file:': 'ファイルをアップロード:', +'upload plugin file:': 'プラグインファイルをアップロード:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.', +'user': 'ユーザー', +'User': 'User', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': '変数', +'Version': 'バージョン', +'Versioning': 'バージョン管理', +'Views': 'ビュー', +'views': 'ビュー', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2pyは最新です', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': '最近のweb2pyTweets', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py upgraded; please restart it', +'Working...': 'Working...', +'WSGI reference name': 'WSGI reference name', +'YES': 'はい', +'Yes': 'Yes', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/my-mm.py b/web2py/applications/admin/languages/my-mm.py new file mode 100644 index 0000000..cffed4c --- /dev/null +++ b/web2py/applications/admin/languages/my-mm.py @@ -0,0 +1,660 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'my-mm', +'!langname!': 'မြန်မာ', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s %%{row} ဖျက်ပြီးပြီ', +'%s %%{row} updated': '%s %%{row} ပြင်ပြီးပြီ', +'%s selected': '%s ခု ရွေးထားသည်', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(something like "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'Abort': 'Abort', +'About': 'အကြောင်း', +'About application': 'About application', +'Accept Terms': 'Accept Terms', +'Access Control': 'အသုံးပြု ခြင်းဆိုင်ရာ ထိန်းချုပ်ရန်', +'Add breakpoint': 'Add breakpoint', +'Additional code for your application': 'Additional code for your application', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'admin disabled because no admin password', +'admin disabled because not supported on google app engine': 'admin disabled because not supported on google app engine', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'admin disabled because unable to access password file', +'Admin is disabled because insecure channel': 'Admin is disabled because insecure channel', +'Admin language': 'Admin language', +'Admin versioning page': 'Admin versioning page', +'Administrative Interface': 'စီမံခန့်ခွဲရာ အင်တာဖေ့စ်', +'administrative interface': 'administrative interface', +'Administrator Password:': 'Administrator Password:', +'Ajax Recipes': 'Ajax Recipes', +'and rename it:': 'and rename it:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'စိတ်မချရသော လမ်းကြောင်းမှ ဝင်ရောက်သဖြင့် appadmin ကို အသုံးပြု၍ မရပါ', +'Application': 'Application', +'application "%s" uninstalled': 'application "%s" uninstalled', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'application compiled', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'application is compiled and cannot be designed', +'Application name:': 'Application name:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'အသုံးမပြုပါ', +'are not used yet': 'အသုံးမပြုသေးပါ', +'Are you sure you want to delete file "%s"?': 'Are you sure you want to delete file "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Are you sure you want to delete plugin "%s"?', +'Are you sure you want to delete this object?': 'သင် ဒီအရာ ဖျက်ရန် သေချာပါသလား။', +'Are you sure you want to uninstall application "%s"?': 'Are you sure you want to uninstall application "%s"?', +'Are you sure?': 'Are you sure?', +'arguments': 'arguments', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.', +'ATTENTION: you cannot edit the running application!': 'ATTENTION: you cannot edit the running application!', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available Databases and Tables': 'အသုံးပြုနိုင်သော ဒေတာဘေစ့်များနှင့် ဇယားများ', +'back': 'back', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'Begin': 'Begin', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Buy this book': 'ဒီစာအုပ်ကို ဝယ်ပါ', +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'cache, errors and sessions cleaned', +'can be a git repo': 'can be a git repo', +'Cancel': 'Cancel', +'Cannot be empty': 'အလွတ် မဖြစ်ရပါ', +'Cannot compile: there are errors in your app:': 'Cannot compile: there are errors in your app:', +'cannot create file': 'cannot create file', +'cannot upload file "%(filename)s"': 'cannot upload file "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'Change admin password', +'change editor settings': 'change editor settings', +'Changelog': 'Changelog', +'check all': 'check all', +'Check for upgrades': 'Check for upgrades', +'Check to delete': 'ဖျက်ရန် စစ်ဆေးပါ', +'Checking for upgrades...': 'အဆင့်မြှင့်တင်မှုများအတွက် စစ်ဆေးနေသည် ...', +'Clean': 'ရှင်းလင်းရန်', +'Clear': 'Clear', +'Clear CACHE?': 'CACHE ကို ရှင်းလင်းမည်မှာ ဟုတ်ပါသလား။', +'Clear DISK': 'DISK ကို ရှင်းလင်းမည်။', +'Clear RAM': 'RAM ကို ရှင်းလင်းမည်။', +'Click row to expand traceback': 'Click row to expand traceback', +'Click row to view a ticket': 'Click row to view a ticket', +'Client IP': 'Client IP', +'code': 'code', +'Code listing': 'Code listing', +'collapse/expand all': 'collapse/expand all', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Community': 'အသိုင်းအဝိုင်း', +'Compile': 'Compile', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'compiled application removed', +'Components and Plugins': 'Components and Plugins', +'Condition': 'Condition', +'continue': 'continue', +'Controller': 'ကွန်ထရိုလာ', +'Controllers': 'ကွန်ထရိုလာများ', +'controllers': 'controllers', +'Copyright': 'မူပိုင်ခွင့်', +'Count': 'Count', +'Create': 'ဖန်တီးရန်', +'create file with filename:': 'create file with filename:', +'Create/Upload': 'Create/Upload', +'created by': 'ဖန်းတီးသူ', +'Created By': 'ပြုလုပ်ဖန်တီးသူ', +'Created by:': 'Created by:', +'Created On': 'ပြုလုပ်ဖန်တီးသည့်အချိန်', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Current request', +'Current response': 'Current response', +'Current session': 'Current session', +'currently running': 'လက်ရှိတွင် လုပ်ဆောင်နေသည်', +'currently saved or': 'currently saved or', +'data uploaded': 'data uploaded', +'Database': 'ဒေတာဘေစ့်', +'Database %s select': 'Database %s select', +'Database administration': 'Database administration', +'database administration': 'ဒေတာဘေ့(စ်) စီမံခန့်ခွဲခြင်း', +'Database Administration (appadmin)': 'ဒေတာဘေစ့် စီမံခန့်ခွဲခြင်း (appadmin)', +'Date and Time': 'Date and Time', +'db': 'db', +'DB Model': 'DB Model', +'Debug': 'အမှားရှာရန်', +'defines tables': 'defines tables', +'Delete': 'Delete', +'delete': 'delete', +'delete all checked': 'delete all checked', +'delete plugin': 'delete plugin', +'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)', +'Delete:': 'Delete:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'အစမ်း၊ သရုပ်ပြမှုများ', +'Deploy': 'Deploy', +'Deploy on Google App Engine': 'Deploy on Google App Engine', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Deployment Recipes': 'Deployment Recipes', +'Description': 'ဖော်ပြချက်', +'Description:': 'Description:', +'design': 'design', +'Detailed traceback description': 'Detailed traceback description', +'details': 'details', +'direction: ltr': 'direction: ltr', +'directory not found': 'directory not found', +'Disable': 'ပိတ်ရန်', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk ရှင်းလင်းပြီးပြီ', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'docs', +'Docs': 'Docs', +'Documentation': 'စာရွက်စာတမ်း အထောက်အကူများ', +"Don't know what to do?": 'ဘာလုပ်ရမည်မသိ ဖြစ်နေပါသလား။', +'done!': 'လုပ်ငန်း ဆောင်ရွက်ပြီးပြီ!', +'Downgrade': 'Downgrade', +'Download': 'Download', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'download layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'download plugins', +'Download plugins from repository': 'Download plugins from repository', +'E-mail': 'အီးမေးလ်', +'Edit': 'ပြင်ဆင်ရန်', +'edit all': 'edit all', +'Edit application': 'Application ကို ပြင်ရန်', +'edit controller:': 'edit controller:', +'Edit current record': 'လက်ရှိ မှတ်တမ်းကို ပြင်ရန်', +'edit views:': 'edit views:', +'Editing %s': 'Editing %s', +'Editing Language file': 'Editing Language file', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Email and SMS': 'အီးမေးလ်နှင့် SMS', +'Enable': 'ဖွင့်ရန်', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'enter an integer between %(min)g and %(max)g': 'enter an integer between %(min)g and %(max)g', +'Error': 'Error', +'Error logs for "%(app)s"': 'Error logs for "%(app)s"', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Error ticket', +'Errors': 'အမှားများ', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Exception instance attributes', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': ' csv file အနေနဲ့ ထုတ်ပေးရန်', +'Exports:': 'Exports:', +'exposes': 'exposes', +'exposes:': 'exposes:', +'extends': 'extends', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module because:': 'failed to reload module because:', +'FAQ': 'ဖြစ်လေ့ရှိသော ပြဿနာများ', +'File': 'File', +'file "%(filename)s" created': 'file "%(filename)s" created', +'file "%(filename)s" deleted': 'file "%(filename)s" deleted', +'file "%(filename)s" uploaded': 'file "%(filename)s" uploaded', +'file "%s" of %s restored': 'file "%s" of %s restored', +'file changed on disk': 'file changed on disk', +'file does not exist': 'file does not exist', +'file not found': 'file not found', +'file saved on %(time)s': 'file saved on %(time)s', +'file saved on %s': 'file saved on %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'filter', +'Find Next': 'Find Next', +'Find Previous': 'Find Previous', +'First name': 'အမည်၏ ပထမဆုံး စာလုံး', +'Form has errors': 'Form has errors', +'Forms and Validators': 'Forms and Validators', +'Frames': 'Frames', +'Free Applications': 'အခမဲ့ Applications', +'Functions with no doctests will result in [passed] tests.': 'Functions with no doctests will result in [passed] tests.', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Group ID': 'Group ID', +'Groups': 'အဖွဲ့များ', +'Hello World': 'မင်္ဂလာပါ ကမ္ဘာကြီး။', +'Help': 'အကူအညီ', +'here': 'here', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'မူလသို့', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'How did you get here?': 'သင် ဘယ်လို ရောက်လာခဲ့သလဲ။', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'သွင်းယူရန်', +'Import/Export': 'သွင်းယူရန်/ထုတ်ယူရန်', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'includes', +'Indent with tabs': 'Indent with tabs', +'inspect attributes': 'inspect attributes', +'Install': 'Install', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'ထည့်သွင်းပြီး application များ', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'internal error', +'internal error: %s': 'internal error: %s', +'Internal State': 'Internal State', +'Introduction': 'မိတ်ဆက်', +'Invalid action': 'Invalid action', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid email': 'အီးမေးလ် ဖြည့်သွင်းမှုမှားနေသည်', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'invalid password', +'invalid password.': 'invalid password.', +'Invalid Query': 'Invalid Query', +'invalid request': 'invalid request', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'invalid ticket', +'Is Active': 'Is Active', +'Key': 'Key', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'Language': 'ဘာသာစကား', +'language file "%(filename)s" created/updated': 'language file "%(filename)s" created/updated', +'Language files (static strings) updated': 'Language files (static strings) updated', +'languages': 'ဘာသာစကားများ', +'Languages': 'ဘာသာစကားများ', +'Last name': 'မျိုးနွယ်အမည်', +'Last Revision': 'Last Revision', +'Last saved on:': 'Last saved on:', +'Layout': 'အပြင်အဆင်', +'Layout Plugins': 'Layout Plugins', +'Layouts': 'အပြင်အဆင်များ', +'License for': 'License for', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Live Chat': 'တိုက်ရိုက် ဆက်သွယ် ပြောကြားရန်', +'Loading...': 'Loading...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'Login': 'ဝင်ရောက်အသုံးပြုရန်', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Login to the Administrative Interface', +'Login/Register': 'Login/Register', +'Logout': 'ထွက်ရန်', +'Lost Password': 'စကားဝှက် မသိတော့ပါ', +'lost password': 'lost password', +'Lost password?': 'စကားဝှက် မသိတော့ဘူးလား။', +'Main Menu': 'Main Menu', +'Manage': 'စီမံခန့်ခွဲရန်', +'Manage %(action)s': '%(action)s ကို စီမံရန်', +'Manage Access Control': 'အသုံးပြုခြင်းဆိုင်ရာ ထိန်းချုပ်မှု စီမံခန့်ခွဲရန်', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Memberships': 'အသင်းဝင်များ', +'Menu Model': 'Menu Model', +'merge': 'merge', +'Models': 'Models', +'models': 'models', +'Modified By': 'ပြင်ဆင်မွမ်းမံသူ', +'Modified On': 'ပြင်ဆင်မွမ်းမံသည့် အချိန်', +'Modules': 'Modules', +'modules': 'modules', +'Multi User Mode': 'Multi User Mode', +'My Sites': 'ကျွန်ုပ်၏ Site များ', +'Name': 'အမည်', +'new application "%s" created': 'new application "%s" created', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'New Application Wizard', +'New application wizard': 'New application wizard', +'new plugin installed': 'new plugin installed', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'မှတ်တမ်း အသစ်', +'new record inserted': 'မှတ်တမ်း အသစ် ဖြည့်သွင်းပြီးပြီ', +'New simple application': 'ရိုးရိုး application အသစ်', +'next': 'next', +'next %s rows': 'နောက်အတန်း %s တန်း', +'NO': 'NO', +'no changes': 'no changes', +'No databases in this application': 'ဒီ application တွင် မည်သည့် ဒေတာဘေစ့်မှ မရှိပါ', +'No Interaction yet': 'No Interaction yet', +'no match': 'no match', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +'Object or table name': 'Object or table name', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'Online examples': 'အွန်လိုင်း နမူနာများ', +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'or import from csv file', +'Origin': 'မူလ အစ', +'Original/Translation': 'Original/Translation', +'Other Plugins': 'အခြား Plugins', +'Other Recipes': 'အခြား Recipes', +'Overview': 'အပေါ်ယံရှုမြင်ခြင်း', +'Overwrite installed app': 'Overwrite installed app', +'Pack all': 'အားလုံးကို ထုပ်ပိုးရန်', +'Pack compiled': 'Pack compiled', +'Pack custom': 'ရွေးချယ်ထုပ်ပိုးရန်', +'pack plugin': 'pack plugin', +'Password': 'စကားဝှက်', +'password changed': 'password changed', +"Password fields don't match": 'စကားဝှက်များ ကိုက်ညီမှု မရှိပါ', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Peeking at file', +'Permission': 'ခွင့်ပြုချက်', +'Permissions': 'ခွင့်ပြုချက်များ', +'Please': 'Please', +'please input your password again': 'ကျေးဇူးပြု၍ စကားဝှက်ကို ထပ်မံ ဖြည့်သွင်းပေးပါ', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" deleted', +'Plugin "%s" in application': 'Plugin "%s" in application', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'plugins', +'Plugins': 'Plugins', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'အားဖြည့်စွမ်းအားပေးသူ', +'Preface': 'နိဒါန်း', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Project Progress', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library ကို မတွေ့ပါ', +'Python': 'Python', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Query:', +'Quick Examples': 'အမြန် အသုံးပြုနိုင်သော နမူနာများ', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram ရှင်းလင်းပြီးပြီ', +'Rapid Search': 'Rapid Search', +'Recipes': 'Recipes', +'Record': 'မှတ်တမ်း', +'record does not exist': 'မှတ်တမ်း မရှိပါ', +'Record ID': 'Record ID', +'Record id': 'Record id', +'refresh': 'refresh', +'register': 'register', +'Register': 'မှတ်ပုံတင်ရန်', +'Registration identifier': 'Registration identifier', +'Registration key': 'Registration key', +'Reload routes': 'Reload routes', +'Remember me (for 30 days)': 'Remember me (for 30 days)', +'Remove compiled': 'Remove compiled', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Replace', +'Replace All': 'Replace All', +'Repository (%s)': 'Repository (%s)', +'request': 'request', +'Request reset password': 'စကားဝှက် အသစ် တောင်းဆိုရန်', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Reset Password key': 'Reset Password key', +'Resolve Conflict file': 'Resolve Conflict file', +'response': 'response', +'restart': 'restart', +'restore': 'restore', +'return': 'return', +'Revert': 'Revert', +'revert': 'revert', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Rows in Table', +'Rows selected': 'ရွေးထားသော အတန်းများ', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'Running on %s', +'Save': 'Save', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Save via Ajax', +'Saved file hash:': 'Saved file hash:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'Semantic': 'Semantic', +'Services': 'Services', +'session': 'session', +'session expired': 'session expired', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'shell', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'Site', +'Size of cache:': 'Size of cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': 'some files could not be removed', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Start a new app', +'Start searching': 'Start searching', +'Start wizard': 'Start wizard', +'state': 'state', +'Static': 'Static', +'static': 'static', +'Static files': 'Static files', +'Statistics': 'ကိန်းဂဏန်း အချက်အလက်များ', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'Stylesheet': 'Stylesheet', +'submit': 'ပြုလုပ်ပါ', +'Submit': 'Submit', +'successful': 'successful', +'Support': 'အထောက်အပံ့', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'Table': 'ဇယား', +'Temporary': 'Temporary', +'test': 'test', +'Testing application': 'Testing application', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller', +'The Core': 'The Core', +'The data representation, define database tables and sets': 'The data representation, define database tables and sets', +'The output of the file is a dictionary that was rendered by the view %s': 'The output of the file is a dictionary that was rendered by the view %s', +'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates', +'The Views': 'The Views', +'Theme': 'Theme', +'There are no controllers': 'There are no controllers', +'There are no models': 'There are no models', +'There are no modules': 'There are no modules', +'There are no plugins': 'There are no plugins', +'There are no private files': 'There are no private files', +'There are no static files': 'There are no static files', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'There are no translators, only default language is supported', +'There are no views': 'There are no views', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'These files are served without processing, your images go here', +'This App': 'ဒီ App', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This email already has an account': 'ဒီအီးမေးလ်တွင် အကောင့် ရှိပြီး ဖြစ်ပါသည်', +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Ticket', +'Ticket ID': 'Ticket ID', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'Timestamp', +'to previous version.': 'to previous version.', +'To create a plugin, name a file/folder plugin_[name]': 'To create a plugin, name a file/folder plugin_[name]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'Translation strings for the application': 'Translation strings for the application', +'try something like': 'try something like', +'Try the mobile interface': 'Try the mobile interface', +'try view': 'try view', +'Twitter': 'Twitter', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Unable to check for upgrades', +'unable to create application "%s"': 'unable to create application "%s"', +'unable to delete file "%(filename)s"': 'unable to delete file "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'unable to delete file plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download app because:': 'Unable to download app because:', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'unable to parse csv file', +'unable to uninstall "%s"': 'unable to uninstall "%s"', +'unable to upgrade because "%s"': 'unable to upgrade because "%s"', +'uncheck all': 'uncheck all', +'Uninstall': 'Uninstall', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'update', +'update all languages': 'update all languages', +'Update:': 'Update:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'upgrade now to %s', +'upload': 'upload', +'Upload': 'Upload', +'Upload a package:': 'Upload a package:', +'Upload and install packed application': 'Upload and install packed application', +'upload file:': 'upload file:', +'upload plugin file:': 'upload plugin file:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.', +'User': 'အသုံးပြုသူ', +'User ID': 'User ID', +'Username': 'Username', +'Users': 'အသုံးပြုသူများ', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'variables', +'Verify Password': 'စကားဝှက်ကို အတည်ပြုပါ', +'Version': 'Version', +'Versioning': 'Versioning', +'Videos': 'ဗွီဒီယိုများ', +'View': 'ဗျူး', +'Views': 'ဗျူးများ', +'views': 'views', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py is up to date', +'web2py online debugger': 'web2py online debugger', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py upgraded; please restart it', +'Welcome': 'ကြိုဆိုပါ၏', +'Welcome to web2py!': 'web2py မှ ကြိုဆိုပါသည်။', +'Which called the function %s located in the file %s': 'Which called the function %s located in the file %s', +'Working...': 'ဆောင်ရွက်နေပါသည် ။ ။ ။', +'WSGI reference name': 'WSGI reference name', +'YES': 'YES', +'Yes': 'Yes', +'You are successfully running web2py': 'သင်သည် web2py ကို အောင်မြင်စွာ လည်ပတ်မောင်းနှင်စေပါသည်။', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You can modify this application and adapt it to your needs': 'သင် ဒီ application ကို ပြုပြင်မွမ်းမံနိုင်ပါသည်။ ထို့အပြင် သင့်လိုအပ်ချက်များနှင့် ကိုက်ညီစေရန် ပြုလုပ်နိုင်ပါသည်။', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'You visited the url %s': 'သင် လည်ပတ်ခဲ့သော URL %s', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +'စကားဝှက် အသစ် တောင်းဆိုရန်': 'စကားဝှက် အသစ် တောင်းဆိုရန်', +'မှတ်ပုံတင်ရန်': 'မှတ်ပုံတင်ရန်', +'ဝင်ရောက်အသုံးပြုရန်': 'ဝင်ရောက်အသုံးပြုရန်', +} diff --git a/web2py/applications/admin/languages/nl.py b/web2py/applications/admin/languages/nl.py new file mode 100644 index 0000000..9998ee6 --- /dev/null +++ b/web2py/applications/admin/languages/nl.py @@ -0,0 +1,655 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'nl', +'!langname!': 'Nederlands', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is een optionele expressie zoals "veld1=\'nieuwewaarde\'". Je kan de resultaten van een JOIN niet updaten of verwijderen.', +'"User Exception" debug mode. ': '"Gebruiker Exceptie" debug mode.', +'"User Exception" debug mode. An error ticket could be issued!': '"Gebruiker Exceptie" debug mode. Een error ticket kan worden aangemaakt!', +'%s': '%s', +'%s %%{row} deleted': '%s %%{row} verwijderd', +'%s %%{row} updated': '%s %%{row} geupdate', +'%s Recent Tweets': '%s Recente Tweets', +'%s selected': '%s selected', +'%s students registered': '%s studenten geregistreerd', +'%Y-%m-%d': '%Y/%m/%d', +'%Y-%m-%d %H:%M:%S': '%Y/%m/%d %H:%M:%S', +'(requires internet access)': '(vereist internettoegang)', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(zoiets als "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01Searching: **%s** %%{file}': '@markmin: zoeken: **%s** %%{file}', +'Abort': 'Afbreken', +'About': 'Over', +'about': 'over', +'About application': 'Over applicatie', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Voeg breakpoint toe', +'Additional code for your application': 'Additionele code voor je applicatie', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'admin uitgezet omdat er geen admin wachtwoord is', +'admin disabled because not supported on google app engine': 'admin uitgezet omdat dit niet ondersteund wordt op google app engine', +'admin disabled because too many invalid login attempts': 'admin is uitgezet omdat er te veel ongeldige login attempts zijn geweest', +'admin disabled because unable to access password file': 'admin is uitgezet omdat er geen toegang was tot het wachtwoordbestand', +'Admin is disabled because insecure channel': 'Admin is uitgezet vanwege onveilig kanaal', +'Admin language': 'Admintaal', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'administratieve interface', +'Administrator Password:': 'Administrator Wachtwoord:', +'and rename it:': 'en hernoem het:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'App does not exist or your are not authorized': 'App bestaat niet of je bent niet geautoriseerd', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'appadmin is uitgezet vanwege een onveilig kanaal', +'Application': 'Application', +'application "%s" uninstalled': 'applicatie "%s" gedeïnstalleerd', +'application %(appname)s installed with md5sum: %(digest)s': 'applicatie %(appname)s geïnstalleerd met md5sum: %(digest)s', +'Application cannot be generated in demo mode': 'Applicatie kan niet gegenereerd worden in demo-mode', +'application compiled': 'applicatie gecompileerd', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'applicatie is gecompileerd en kan niet worden ontworpen', +'Application name:': 'Applicatienaam:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'worden niet gebruikt', +'are not used yet': 'worden nog niet gebruikt', +'Are you sure you want to delete file "%s"?': 'Weet je zeker dat je bestand "%s" wilt verwijderen?', +'Are you sure you want to delete plugin "%s"?': 'Weet je zeker dat je plugin "%s"? wilt verwijderen?', +'Are you sure you want to delete this object?': 'Weet je zeker dat je dit object wilt verwijderen?', +'Are you sure you want to uninstall application "%s"?': 'Weet je zeker dat je applicatie "%s" wilt deïnstalleren?', +'Are you sure?': 'Are you sure?', +'arguments': 'argumenten', +'at char %s': 'bij karakter %s', +'at line %s': 'op regel %s', +'ATTENTION:': 'LET OP:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'LET OP: Login heeft beveiligde (HTTPS) verbinding nodig of moet draaien op localhost.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'LET OP: TESTEN IS NIET THREAD SAFE EN PROBEER NIET MEERDERE TESTEN TEGELIJK TE DOEN.', +'ATTENTION: you cannot edit the running application!': 'LET OP: je kan de draaiende applicatie niet bewerken!', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available databases and tables': 'Beschikbare databases en tabellen', +'Available Databases and Tables': 'Available Databases and Tables', +'back': 'terug', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'bad_resource': 'slechte_resource', +'Basics': 'Basics', +'Begin': 'Begin', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Registreer', +'Bulk Student Registration': 'Bulk Studentenregistratie', +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'cache, errors en sessies geleegd', +'can be a git repo': 'can een git repo zijn', +'Cancel': 'Cancel', +'Cannot be empty': 'Kan niet leeg zijn', +'Cannot compile: there are errors in your app:': 'Kan niet compileren: er bevinden zich fouten in je app:', +'cannot create file': 'kan bestand niet maken', +'cannot upload file "%(filename)s"': 'kan bestand "%(filename)s" niet uploaden', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'Verander admin wachtwoord', +'change editor settings': 'change editor settings', +'Changelog': 'Changelog', +'check all': 'vink alles aan', +'Check for upgrades': 'Controleer voor upgrades', +'Check to delete': 'Vink aan om te verwijderen', +'Checking for upgrades...': 'Controleren voor upgrades...', +'Clean': 'Clean', +'Clear': 'Clear', +'Clear CACHE?': 'Leeg CACHE?', +'Clear DISK': 'Leeg DISK', +'Clear RAM': 'Leeg RAM', +'Click row to expand traceback': 'Klik rij om traceback uit te klappen', +'Click row to view a ticket': 'Klik rij om ticket te bekijken', +'code': 'code', +'Code listing': 'Code listing', +'collapse/expand all': 'klap in/klap alles uit', +'Command': 'Commando', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'Compileer', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'Gecompileerde applicatie verwijderd', +'Condition': 'Conditie', +'contact_admin': 'contact_admin', +'continue': 'ga door', +'Controllers': 'Controllers', +'controllers': 'controllers', +'Count': 'Count', +'Create': 'Maak', +'create': 'maak', +'create file with filename:': 'maak bestand met naam:', +'create plural-form': 'maak meervoudsvorm', +'Create rules': 'Maak regels', +'Create/Upload': 'Create/Upload', +'created by': 'gemaakt door:', +'Created by:': 'Created by:', +'Created On': 'Gemaakt Op', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Huidige request', +'Current response': 'Huidige response', +'Current session': 'Huidige sessie', +'currently running': 'draait op het moment', +'currently saved or': 'op het moment opgeslagen of', +'data uploaded': 'data geupload', +'Database': 'Database', +'database': 'database', +'Database %s select': 'Database %s select', +'database %s select': 'database %s select', +'Database administration': 'Database administration', +'database administration': 'database administratie', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Datum en Tijd', +'db': 'db', +'Debug': 'Debug', +'defines tables': 'definieert tabellen', +'Delete': 'Verwijder', +'delete': 'verwijder', +'delete all checked': 'verwijder alle aangevinkten', +'delete plugin': 'verwijder plugin', +'Delete this file (you will be asked to confirm deletion)': 'Verwijder dit bestand (je zal worden gevraagd om de verwijdering te bevestigen)', +'Delete:': 'Verwijder:', +'deleted after first hit': 'verwijder na eerste hit', +'Demo': 'Demo', +'Deploy': 'Deploy', +'Deploy on Google App Engine': 'Deploy op Google App Engine (GAE)', +'Deploy to OpenShift': 'Deploy op OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deploymentformulier', +'Deployment Interface': 'Deployment Interface', +'Description:': 'Description:', +'design': 'design', +'Detailed traceback description': 'Gedetailleerde traceback beschrijving', +'details': 'details', +'direction: ltr': 'directie: ltr', +'directory not found': 'directory niet gevonden', +'Disable': 'Zet uit', +'Disabled': 'Uitgezet', +'disabled in demo mode': 'uitgezet in demo-modus', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'uitgezet in multi-usermodus', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'docs', +'Docs': 'Docs', +'done!': 'gereed!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'download layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'download plugins', +'Download plugins from repository': 'Download plugins from repository', +'Edit': 'Bewerk', +'edit all': 'bewerk alles', +'Edit application': 'Bewerk applicatie', +'edit controller': 'bewerk controller', +'edit controller:': 'edit controller:', +'Edit current record': 'Bewerk huidige record', +'edit views:': 'bewerk views:', +'Editing %s': 'Editing %s', +'Editing file "%s"': 'Bewerk bestand "%s"', +'Editing Language file': 'Taalbestand aan het bewerken', +'Editing Plural Forms File': 'Meervoudsvormenbestand aan het bewerken', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Zet aan', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'enter a value': 'geef een waarde', +'Error': 'Error', +'Error logs for "%(app)s"': 'Error logs voor "%(app)s"', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Errorticket', +'Errors': 'Errors', +'Exception %(extype)s: %(exvalue)s': 'Exceptie %(extype)s: %(exvalue)s', +'Exception %s': 'Exceptie %s', +'Exception instance attributes': 'Exceptie instantie attributen', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation': 'Klap Afkorting uit', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'exporteer als csv-bestand', +'Exports:': 'Exports:', +'exposes': 'stelt bloot', +'exposes:': 'stelt bloot:', +'extends': 'extends', +'failed to compile file because:': 'niet gelukt om bestand te compileren omdat:', +'failed to reload module because:': 'niet gelukt om module te herladen omdat:', +'faq': 'faq', +'File': 'Bestand', +'file "%(filename)s" created': 'bestand "%(filename)s" gemaakt', +'file "%(filename)s" deleted': 'bestand "%(filename)s" verwijderd', +'file "%(filename)s" uploaded': 'bestand "%(filename)s" geupload', +'file "%s" of %s restored': 'bestand "%s" van %s hersteld', +'file changed on disk': 'bestand veranderd op schijf', +'file does not exist': 'bestand bestaat niet', +'file not found': 'bestand niet gevonden', +'file saved on %(time)s': 'bestand opgeslagen op %(time)s', +'file saved on %s': 'bestand bewaard op %s', +'filename': 'filename', +'Filename': 'Bestandsnaam', +'Files added': 'Files added', +'filter': 'filter', +'Find Next': 'Find Next', +'Find Previous': 'Find Previous', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': 'Functies zonder doctests zullen resulteren in [passed] tests.', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Genereer', +'Get from URL:': 'Krijg van URL:', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'Go to Matching Pair': 'Ga naar Matchende Paar', +'go!': 'ga!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Ga naar', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Help': 'Help', +'here': 'here', +'Hide/Show Translated strings': 'Verberg/Toon Vertaalde strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'wordt alleen gerespecteerd als expressie waar is', +'If start the downgrade, be patient, it may take a while to rollback': 'Wees geduldig na het starten van de downgrade, het kan een tijd duren om de rollback uit te voeren', +'If start the upgrade, be patient, it may take a while to download': 'Wees geduldig na het starten van de upgrade, het kan een tijd duren om de download te voltooien', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Als de bovenstaande report een ticketnummer bevat indiceert dit een fout in het uitvoeren van de controller, nog voor een poging wordt gedaan om de doctests uit te voeren. Dit wordt meestal veroorzaak door een inspringfout of een fout buiten de functie-code. Een groene titel indiceert dat alle tests (wanneer gedefinieerd) geslaagd zijn. In dit geval worden testresultaten niet getoond.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Import/Export', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'Binnen ontwikkeling, gebruik de default Rocket webserver die op het moment ondersteund wordt door deze debugger.', +'includes': 'includes', +'Indent with tabs': 'Indent with tabs', +'index': 'index', +'insert new': 'insert new', +'insert new %s': 'insert new %s', +'inspect attributes': 'inspecteer attributen', +'Install': 'Install', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Geïnstalleerde applicaties', +'Interaction at %s line %s': 'Interactie op %s regel %s', +'Interactive console': 'Interactieve console', +'internal error': 'interne error', +'internal error: %s': 'interne error: %s', +'Internal State': 'Interne State', +'Invalid action': 'Ongeldige actie', +'Invalid application name': 'Invalid application name', +'invalid circual reference': 'ongeldige cirkelreferentie', +'invalid circular reference': 'Ongeldige circulaire referentie', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'ongeldig wachtwoord', +'invalid password.': 'ongeldig wachtwoord.', +'Invalid Query': 'Ongeldige Query', +'invalid request': 'ongeldige request', +'Invalid request': 'Invalid request', +'invalid request ': 'ongeldige request', +'invalid table names (auth_* tables already defined)': 'ongeldige tabelnamen (auth_* tabellen zijn al gedefinieerd)', +'invalid ticket': 'ongeldige ticket', +'Key': 'Key', +'Key bindings': 'Key bindings', +'Key bindings for ZenCoding Plugin': 'Key bindings voor ZenCoding Plugin', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill proces', +'language file "%(filename)s" created/updated': 'taalbestand "%(filename)s" gemaakt/geupdate', +'Language files (static strings) updated': 'Taalbestanden (statische strings) geupdate', +'languages': 'talen', +'Languages': 'Talen', +'Last Revision': 'Last Revision', +'Last saved on:': 'Laatst opgeslagen op:', +'License for': 'Licentie voor', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Regelnummer', +'LineNo': 'RegelNr', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Loading...': 'Loading...', +'loading...': 'laden...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'Login': 'Login', +'login': 'Login', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Login op de Administratieve Interface', +'Login/Register': 'Login/Register', +'Logout': 'Logout', +'lost password': 'lost password', +'Main Menu': 'Hoofdmenu', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Beheer Admin Gebruikers/Studenten', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Beheer Studenten', +'Match Pair': 'Match Pair', +'Memberships': 'Memberships', +'merge': 'samenvoegen', +'Merge Lines': 'Voeg Regels Samen', +'Minimum length is %s': 'Minimale lengte is %s', +'Models': 'Modellen', +'models': 'modellen', +'Modified On': 'Verandert Op', +'Modules': 'Modules', +'modules': 'modules', +'Multi User Mode': 'Multi User Mode', +'Must include at least %s %s': 'Moet ten minste bevatten %s %s', +'Must include at least %s lowercase': 'Moet ten minste bevatten %s kleine letter', +'Must include at least %s of the following : %s': 'Moet ten minste bevatten %s van het volgende : %s', +'Must include at least %s uppercase': 'Moet ten minste bevatten %s hoofdletter', +'new application "%s" created': 'nieuwe applicatie "%s" gemaakt', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'Nieuwe Applicatie Wizard', +'New application wizard': 'Nieuwe applicatie wizard', +'new plugin installed': 'nieuwe plugin geïnstalleerd', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'Nieuw Record', +'new record inserted': 'nieuw record ingevoegd', +'New simple application': 'Nieuwe eenvoudige applicatie', +'next': 'volgende', +'next %s rows': 'next %s rows', +'next 100 rows': 'volgende 100 rijen', +'Next Edit Point': 'Volgende Bewerkpunt', +'NO': 'NEE', +'no changes': 'no changes', +'No databases in this application': 'Geen databases in deze applicatie', +'No Interaction yet': 'Nog geen interactie', +'no match': 'geen match', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'geen permissie om "%s" te deïnstalleren', +'No ticket_storage.txt found under /private folder': 'Geen ticket_storage.txt gevonden onder /private directory', +'Node:': 'Node:', +'Not Authorized': 'Geen Rechten', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Notitie: Bij een Github error status code 128, zorg ervoor dat het systeem en het account dat je aan het deployen bent een correspondeerde ssh key geconfigureerd heeft in het openshift account. ', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": 'Om op productie deze debugger te gebruiken, moet je webserver configureren om een proces en meerdere threads te gebruiken.', +'online designer': 'online designer', +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'of importeer van csv-bestand', +'Original/Translation': 'Oorspronkelijk/Vertaling', +'Overview': 'Overview', +'Overwrite installed app': 'Overschrijf geïnstalleerde app', +'Pack all': 'Pack all', +'Pack compiled': 'Pack compiled', +'Pack custom': 'Pack custom', +'pack plugin': 'pack plugin', +'PAM authenticated user, cannot change password here': 'PAM geauthenticeerde gebruiker, kan wachtwoord hier niet wijzigen', +'password changed': 'wachtwoord gewijzigd', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Pad naar appcfg.py', +'Path to local openshift repo root.': 'Pad naar lokale openshift repo root.', +'peek': 'gluur', +'Peeking at file': 'Gluren naar bestand', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Alstublieft', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin': 'plugin', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" gedetecteerd', +'Plugin "%s" in application': 'Plugin "%s" in applicatie', +'plugin not specified': 'plugin niet gespecialiseerd', +'Plugin page': 'Plugin page', +'plugins': 'plugins', +'Plugins': 'Plugins', +'Plural Form #%s': 'Meervoudsvorm #%s', +'Plural-Forms:': 'Meervoudsvormen', +'Powered by': 'Powered by', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'vorige 100 rijen', +'Previous Edit Point': 'Vorige Bewerkpunt', +'Private files': 'Privébestanden', +'private files': 'privébestanden', +'Project Progress': 'Projectvoortgang', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Query:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Record': 'Record', +'record': 'record', +'record does not exist': 'record bestaat niet', +'record id': 'record id', +'Record id': 'Record id', +'refresh': 'ververs', +'register': 'register', +'Reload routes': 'Herlaadt routes', +'Remove compiled': 'Verwijder gecompileerde', +'Removed Breakpoint on %s at line %s': 'Verwijder Breakpoint op %s op regel %s', +'Replace': 'Replace', +'Replace All': 'Replace All', +'Repository (%s)': 'Repository (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'vereist python-git, maar niet geïnstalleerd', +'resolve': 'oplossen', +'Resolve Conflict file': 'Los Conflictbestand op', +'response': 'antwoord', +'restart': 'herstart', +'restore': 'herstel', +'return': 'keer terug', +'Revert': 'Revert', +'revert': 'herstel', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Rows in Table', +'Rows in table': 'Rijen in tabel', +'Rows selected': 'Rijen geselecteerd', +'rules are not defined': 'regels zijn niet gedefinieerd', +'rules parsed with errors': 'regels geparsed met errors', +'rules:': 'regels:', +'Run tests': 'Draai testen', +'Run tests in this file': 'Draai testen in dit bestand', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Draai testen in dit bestand (om alle bestanden te draaien, kun je ook de button genaamd 'test' gebruiken)", +'Running on %s': 'Draait op %s', +'runonce': 'runonce', +'Save': 'Bewaar', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Bewaar via Ajax', +'Saved file hash:': 'Opgeslagen bestandhash:', +'Screenshot %s': 'Screenshot %s', +'search': 'zoek', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'selected': 'Geselecteerd', +'session': 'sessie', +'session expired': 'sessie verlopen', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Zet Breakpoint op %s op regel %s: %s', +'shell': 'shell', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'signup': 'signup', +'signup_requested': 'signup_requested', +'Singular Form': 'Enkelvoudsvorm', +'site': 'site', +'Site': 'Site', +'Size of cache:': 'Size of cache:', +'skip to generate': 'sla over om te genereren', +'some files could not be removed': 'sommige bestanden konden niet worden verwijderd', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, mercurial is niet geïnstalleerd', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Start een nieuwe app', +'Start searching': 'Start searching', +'Start wizard': 'Start wizard', +'state': 'state', +'Static': 'Static', +'static': 'statisch', +'Static files': 'Statische bestanden', +'Statistics': 'Statistics', +'Step': 'Stap', +'step': 'stap', +'stop': 'stop', +'submit': 'submit', +'Submit': 'Submit', +'successful': 'succesvol', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': 'tabel', +'Table': 'Table', +'tags': 'tags', +'Temporary': 'tijdelijk', +'test': 'test', +'Testing application': 'Applicatie Testen', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'De "query" is een conditie zoals "db.tabel1.veld1==\'waarde\'". Zoiets als "db.tabel1.veld1==db.tabel2.veld2" resulteert in een SQL JOIN. ', +'The app exists, was created by wizard, continue to overwrite!': 'De app bestaat, was gemaakt door de wizard, ga door om te overschrijven!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'De app bestaat, wat NIET gemaakt door de wizard, ga door om te overschrijven!', +'The application logic, each URL path is mapped in one exposed function in the controller': 'De applicatie logica, elk URL pad is gemapped in een blootgestelde functie in de controller', +'The data representation, define database tables and sets': 'De data representatie, definieer database tabellen en sets', +'The presentations layer, views are also known as templates': 'De presentatielaag, views ook bekend als templates', +'Theme': 'Theme', +'There are no controllers': 'Er zijn geen controllers', +'There are no models': 'Er zijn geen modellen', +'There are no modules': 'Er zijn geen modules', +'There are no plugins': 'Er zijn geen plugins', +'There are no private files': 'There are no private files', +'There are no static files': 'Er zijn geen statische bestanden', +'There are no translators': 'Er zijn geen vertalingen', +'There are no translators, only default language is supported': 'Er zijn geen vertalingen, alleen de standaardtaal wordt ondersteund.', +'There are no views': 'Er zijn geen views', +'These files are not served, they are only available from within your app': 'Deze bestanden worden niet geserveerd, ze zijn alleen beschikbaar vanuit binnen je app.', +'These files are served without processing, your images go here': 'Deze bestanden worden geserveerd zonder verwerkingen, je afbeeldingen horen hier', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": 'Deze debugger werkt misschien niet goed, of je hebt geen threaded webserver, of je gebruikt multiple daemon processen.', +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'Dit is een experimentele feature en heeft meer tests nodig. Downgraden op eigen risico.', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'Dit is een experimentele feature en heeft meer tests nodig. Upgraden op eigen risico.', +'This is the %(filename)s template': 'Dit is de %(filename)s template', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": 'Op deze pagina kan je veranderingen naar een openshift app repo committen en pushen naar je cloud-instantie. Dit gaat er vanuit dat je de applicatie-instantie al gemaakt hebt met de web2py skeleton en de repo ergens op een bestandssysteem hebt waar de web2py-instantie toegang tot heeft. Deze functionaliteit vereist ook een geïnstalleerde GitPython welke beschikbaar is in het python pad van de runtime waar web2py ook in opereert.', +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'Op deze pagina kan je applicatie uploaden naar Google App Engine. Let op, dat je eerst je indexes lokaal aanmaakt. Dit kun je doen door de Google appserver te installeren en de app lokaal eenmaal te draaien, anders krijg je error wanneer je records selecteert. Attentie: deployment kan een lange tijd duren, afhankelijk van de netwerksnelheid. Attentie: het overschrijft je app.yaml. SUBMIT NIET TWEE KEER!', +'this page to see if a breakpoint was hit and debug interaction is required.': 'deze pagina om te zien of een breakpoint geraakt is en debug-interactie nodig is', +'This will pull changes from the remote repo for application "%s"?': 'Dit zal veranderingen van de remote repo for applicatie "%s" pullen. ', +'This will push changes to the remote repo for application "%s".': 'Dit zal veranderingen naar de remote repo for applicatie "%s" pushen. ', +'ticket': 'ticket', +'Ticket': 'Ticket', +'Ticket ID': 'Ticket ID', +'Ticket Missing': 'Ticket Missing', +'tickets': 'tickets', +'Time in Cache (h:m:s)': 'Tijd in Cache (u:m:s)', +'to previous version.': 'naar vorige versie.', +'To create a plugin, name a file/folder plugin_[name]': 'Om een plugin te maken, neem een bestand/directory plugin_[naam]', +'To emulate a breakpoint programatically, write:': 'Om een breakpoint programmatische te emuleren, schrijf:', +'to use the debugger!': 'om de debugger te gebruiken!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'Translation strings for the application': 'Vertaalstrings van de applicatie', +'try something like': 'probeer zoiets als', +'Try the mobile interface': 'Try the mobile interface', +'try view': 'try view', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger commando hier en druk op Return (Enter) om het uit te voeren.', +'Type python statement in here and hit Return (Enter) to execute it.': 'Type python statement hier en druk op Return (Enter) om het uit te voeren.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Onmogelijk om voor upgrades te checken', +'unable to create application "%s"': 'onmogelijk om applicatie "%s" te maken', +'unable to create application "%s" (it may exist already)': 'onmogelijk om applicatie "%s" te maken (mogelijk bestaat deze al)', +'unable to delete file "%(filename)s"': 'onmogelijk om bestand "%(filename)s" te verwijderen', +'unable to delete file plugin "%(plugin)s"': 'onmogelijk om pluginbestand "%(plugin)s" te verwijderen', +'Unable to determine the line number!': 'Onmogelijk om regelnummer te bepalen!', +'Unable to download app because:': 'Onmogelijk om app the downloaden omdat:', +'Unable to download because:': 'Onmogelijk om te downloaden omdat:', +'unable to download layout': 'onmogelijk om layout te downloaden', +'unable to download plugin: %s': 'onmogelijk om plugin te downloaden: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install application "%(appname)s"': 'onmogelijk om applicatie "%(appname)s" te installeren', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'onmogelijk om csv-bestand te parsen', +'unable to uninstall "%s"': 'onmogelijk om te deïnstalleren "%s"', +'unable to upgrade because "%s"': 'onmogelijk om te upgraden omdat "%s"', +'unauthorized': 'niet geautoriseerd ', +'uncheck all': 'vink alles uit', +'uninstall': 'deïnstalleer', +'Uninstall': 'Deïnstalleer', +'Unsupported webserver working mode: %s': 'Niet ondersteunde webserver werkmodus: %s', +'update': 'update', +'update all languages': 'update alle talen', +'Update:': 'Update:', +'Upgrade': 'Upgrade', +'upgrade now': 'upgrade now', +'upgrade now to %s': 'upgrade now to %s', +'upgrade_web2py': 'upgrade_web2py', +'upload': 'upload', +'Upload': 'Upload', +'Upload a package:': 'Upload een package:', +'Upload and install packed application': 'Upload en installeer packed applicatie', +'upload file:': 'upload bestand:', +'upload plugin file:': 'upload pluginbestand:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Gebruik (...)&(...) voor AND, (...)|(...) voor OR, en ~(...) voor NOT om meer complexe queries te maken.', +'user': 'gebruiker', +'User': 'User', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Het gebruik van de shell kan database locken voor andere gebruikers van deze app.', +'value not allowed': 'waarde is niet toegestaan', +'variables': 'variabelen', +'Version': 'Versie', +'Version %s.%s.%s (%s) %s': 'Versie %s.%s.%s (%s) %s', +'Versioning': 'Versionering', +'view': 'view', +'Views': 'Views', +'views': 'views', +'Warning!': 'Warning!', +'WARNING:': 'WAARSCHUWING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps om te deployen', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py is up to date', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'web2py Recente Tweets', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py geupgrade; herstart alstublieft', +'Working...': 'Working...', +'Wrap with Abbreviation': 'Wrap met Afkorting', +'WSGI reference name': 'WSGI reference name', +'YES': 'JA', +'Yes': 'Yes', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'Je kan ook een breakpoint zetten of verwijderen in het bewerkscherm met de Toggle Breakpoint-knop', +'You can inspect variables using the console bellow': 'Je kan je variabelen inspecteren in de console hieronder', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'Je hebt nog een poging om in te loggen voor je buitengesloten wordt.', +'you must specify a name for the uploaded application': 'je moet een naam specificeren voor de geuploade applicatie', +'You need to set up and reach a': 'Je moet het volgende opzetten en bereiken:', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Je applicatie zal geblokkeerd zijn tot je een actie button aanklikt (volgende, step, ga door, etc.)', +} diff --git a/web2py/applications/admin/languages/pl.py b/web2py/applications/admin/languages/pl.py new file mode 100644 index 0000000..8f943f3 --- /dev/null +++ b/web2py/applications/admin/languages/pl.py @@ -0,0 +1,640 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'pl', +'!langname!': 'Polska', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Uaktualnij" jest dodatkowym wyrażeniem postaci "pole1=\'nowawartość\'". Nie możesz uaktualnić lub usunąć wyników z JOIN:', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': 'Wierszy usuniętych: %s', +'%s %%{row} updated': 'Wierszy uaktualnionych: %s', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(requires internet access)': '(requires internet access)', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(coś podobnego do "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files', +'A new version of web2py is available': 'Nowa wersja web2py jest dostępna', +'A new version of web2py is available: %s': 'Nowa wersja web2py jest dostępna: %s', +'Abort': 'Abort', +'About': 'informacje', +'About application': 'Informacje o aplikacji', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Add breakpoint', +'additional code for your application': 'dodatkowy kod Twojej aplikacji', +'Additional code for your application': 'Additional code for your application', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'panel administracyjny wyłączony z powodu braku hasła administracyjnego', +'admin disabled because not supported on google app engine': 'panel administracyjny wyłączony z powodu braku wsparcia na google apps engine', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'panel administracyjny wyłączony z powodu braku dostępu do pliku z hasłem', +'Admin is disabled because insecure channel': 'Panel administracyjny wyłączony z powodu braku bezpiecznego połączenia', +'Admin is disabled because unsecure channel': 'Panel administracyjny wyłączony z powodu braku bezpiecznego połączenia', +'Admin language': 'Admin language', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'administrative interface', +'Administrator Password:': 'Hasło administratora:', +'and rename it (required):': 'i nadaj jej nową nazwę (wymagane):', +'and rename it:': 'i nadaj mu nową nazwę:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'administracja aplikacji', +'appadmin is disabled because insecure channel': 'administracja aplikacji wyłączona z powodu braku bezpiecznego połączenia', +'Application': 'Application', +'application "%s" uninstalled': 'aplikacja "%s" została odinstalowana', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'aplikacja została skompilowana', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'aplikacja jest skompilowana i nie może być projektowana', +'Application name:': 'Application name:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'are not used', +'are not used yet': 'are not used yet', +'Are you sure you want to delete file "%s"?': 'Czy na pewno chcesz usunąć plik "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Czy na pewno chcesz usunąć wtyczkę "%s"?', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Are you sure you want to uninstall application "%s"': 'Czy na pewno chcesz usunąć aplikację "%s"', +'Are you sure you want to uninstall application "%s"?': 'Czy na pewno chcesz usunąć aplikację "%s"?', +'Are you sure you want to upgrade web2py now?': 'Are you sure you want to upgrade web2py now?', +'Are you sure?': 'Are you sure?', +'arguments': 'arguments', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'UWAGA: Wymagane jest bezpieczne (HTTPS) połączenie lub połączenie z lokalnego adresu.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'UWAGA: TESTOWANIE NIE JEST BEZPIECZNE W ŚRODOWISKU WIELOWĄTKOWYM, TAK WIĘC NIE URUCHAMIAJ WIELU TESTÓW JEDNOCZEŚNIE.', +'ATTENTION: you cannot edit the running application!': 'UWAGA: nie można edytować uruchomionych aplikacji!', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available databases and tables': 'Dostępne bazy danych i tabele', +'Available Databases and Tables': 'Available Databases and Tables', +'back': 'wstecz', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'Begin': 'Begin', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'pamięć podręczna, bilety błędów oraz pliki sesji zostały wyczyszczone', +'can be a git repo': 'can be a git repo', +'Cancel': 'Cancel', +'Cannot be empty': 'Nie może być puste', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Nie można skompilować: w Twojej aplikacji są błędy . Znajdź je, popraw a następnie spróbój ponownie.', +'Cannot compile: there are errors in your app:': 'Cannot compile: there are errors in your app:', +'cannot create file': 'nie można utworzyć pliku', +'cannot upload file "%(filename)s"': 'nie można wysłać pliku "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'change admin password', +'change editor settings': 'change editor settings', +'Changelog': 'Changelog', +'check all': 'zaznacz wszystko', +'Check for upgrades': 'check for upgrades', +'Check to delete': 'Zaznacz aby usunąć', +'Checking for upgrades...': 'Sprawdzanie aktualizacji...', +'Clean': 'oczyść', +'Clear': 'Clear', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'click here for online examples': 'kliknij aby przejść do interaktywnych przykładów', +'click here for the administrative interface': 'kliknij aby przejść do panelu administracyjnego', +'Click row to expand traceback': 'Click row to expand traceback', +'Click row to view a ticket': 'Click row to view a ticket', +'click to check for upgrades': 'kliknij aby sprawdzić aktualizacje', +'code': 'code', +'Code listing': 'Code listing', +'collapse/expand all': 'collapse/expand all', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'skompiluj', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'skompilowana aplikacja została usunięta', +'Condition': 'Condition', +'continue': 'continue', +'Controllers': 'Kontrolery', +'controllers': 'kontrolery', +'Count': 'Count', +'Create': 'create', +'create file with filename:': 'utwórz plik o nazwie:', +'create new application:': 'utwórz nową aplikację:', +'Create new simple application': 'Utwórz nową aplikację', +'Create/Upload': 'Create/Upload', +'created by': 'utworzone przez', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Aktualne żądanie', +'Current response': 'Aktualna odpowiedź', +'Current session': 'Aktualna sesja', +'currently running': 'currently running', +'currently saved or': 'aktualnie zapisany lub', +'data uploaded': 'dane wysłane', +'Database': 'Database', +'database': 'baza danych', +'Database %s select': 'Database %s select', +'database %s select': 'wybór z bazy danych %s', +'Database administration': 'Database administration', +'database administration': 'administracja bazy danych', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Data i godzina', +'db': 'baza danych', +'Debug': 'Debug', +'defines tables': 'zdefiniuj tabele', +'Delete': 'Usuń', +'delete': 'usuń', +'delete all checked': 'usuń wszystkie zaznaczone', +'delete plugin': 'usuń wtyczkę', +'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)', +'Delete:': 'Usuń:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'deploy', +'Deploy on Google App Engine': 'Umieść na Google App Engine', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description:': 'Description:', +'design': 'projektuj', +'DESIGN': 'PROJEKTUJ', +'Design for': 'Projekt dla', +'Detailed traceback description': 'Detailed traceback description', +'details': 'details', +'direction: ltr': 'direction: ltr', +'directory not found': 'directory not found', +'Disable': 'Disable', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'docs', +'Docs': 'Docs', +'done!': 'zrobione!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'download layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'download plugins', +'Download plugins from repository': 'Download plugins from repository', +'EDIT': 'EDYTUJ', +'Edit': 'edytuj', +'edit all': 'edit all', +'Edit application': 'Edycja aplikacji', +'edit controller': 'edytuj kontroler', +'edit controller:': 'edit controller:', +'Edit current record': 'Edytuj aktualny rekord', +'edit views:': 'edit views:', +'Editing %s': 'Editing %s', +'Editing file': 'Edycja pliku', +'Editing file "%s"': 'Edycja pliku "%s"', +'Editing Language file': 'Edytuj plik tłumaczeń', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Enable', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Enterprise Web Framework': 'Enterprise Web Framework', +'Error': 'Error', +'Error logs for "%(app)s"': 'Wpisy błędów dla "%(app)s"', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Error ticket', +'Errors': 'błędy', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Exception instance attributes', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'eksportuj jako plik csv', +'Exports:': 'Exports:', +'exposes': 'eksponuje', +'exposes:': 'exposes:', +'extends': 'rozszerza', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module': 'nie udało się przeładować modułu', +'failed to reload module because:': 'failed to reload module because:', +'File': 'File', +'file "%(filename)s" created': 'plik "%(filename)s" został utworzony', +'file "%(filename)s" deleted': 'plik "%(filename)s" został usunięty', +'file "%(filename)s" uploaded': 'plik "%(filename)s" został wysłany', +'file "%(filename)s" was not deleted': 'plik "%(filename)s" nie został usunięty', +'file "%s" of %s restored': 'plik "%s" z %s został odtworzony', +'file changed on disk': 'plik na dysku został zmieniony', +'file does not exist': 'plik nie istnieje', +'file not found': 'file not found', +'file saved on %(time)s': 'plik zapisany o %(time)s', +'file saved on %s': 'plik zapisany o %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'filter', +'Find Next': 'Find Next', +'Find Previous': 'Find Previous', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': 'Funkcje bez doctestów będą dołączone do [zaliczonych] testów.', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Hello World': 'Witaj Świecie', +'Help': 'pomoc', +'here': 'here', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'htmledit': 'edytuj HTML', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Jeżeli powyższy raport zawiera numer biletu błędu, oznacza to błąd podczas wykonywania kontrolera przez próbą uruchomienia doctestów. Zazwyczaj jest to spowodowane nieprawidłowymi wcięciami linii kodu lub błędami w module poza ciałem funkcji.\nTytuł w kolorze zielonym oznacza, ze wszystkie (zdefiniowane) testy zakończyły się sukcesem. W tej sytuacji ich wyniki nie są pokazane.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Importuj/eksportuj', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'zawiera', +'Indent with tabs': 'Indent with tabs', +'insert new': 'wstaw nowy rekord tabeli', +'insert new %s': 'wstaw nowy rekord do tabeli %s', +'inspect attributes': 'inspect attributes', +'Install': 'install', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Zainstalowane aplikacje', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'wewnętrzny błąd', +'internal error: %s': 'internal error: %s', +'Internal State': 'Stan wewnętrzny', +'Invalid action': 'Błędna akcja', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'błędne hasło', +'invalid password.': 'invalid password.', +'Invalid Query': 'Błędne zapytanie', +'invalid request': 'błędne zapytanie', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'błędny bilet', +'Key': 'Key', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'plik tłumaczeń "%(filename)s" został utworzony/uaktualniony', +'Language files (static strings) updated': 'Pliki tłumaczeń (ciągi statyczne) zostały uaktualnione', +'languages': 'pliki tłumaczeń', +'Languages': 'Tłumaczenia', +'languages updated': 'pliki tłumaczeń zostały uaktualnione', +'Last Revision': 'Last Revision', +'Last saved on:': 'Ostatnio zapisany:', +'License for': 'Licencja dla', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Loading...': 'Loading...', +'loading...': 'wczytywanie...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'Login': 'Zaloguj', +'login': 'zaloguj', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Logowanie do panelu administracyjnego', +'Login/Register': 'Login/Register', +'Logout': 'wyloguj', +'lost password': 'lost password', +'Main Menu': 'Main Menu', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Memberships': 'Memberships', +'merge': 'zespól', +'Models': 'Modele', +'models': 'modele', +'Modified On': 'Modified On', +'Modules': 'Moduły', +'modules': 'moduły', +'Multi User Mode': 'Multi User Mode', +'new application "%s" created': 'nowa aplikacja "%s" została utworzona', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'New Application Wizard', +'New application wizard': 'New application wizard', +'new plugin installed': 'nowa wtyczka została zainstalowana', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'Nowy rekord', +'new record inserted': 'nowy rekord został wstawiony', +'New simple application': 'New simple application', +'next': 'next', +'next %s rows': 'next %s rows', +'next 100 rows': 'następne 100 wierszy', +'NO': 'NIE', +'no changes': 'no changes', +'No databases in this application': 'Brak baz danych w tej aplikacji', +'No Interaction yet': 'No Interaction yet', +'no match': 'no match', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'lub zaimportuj z pliku csv', +'or provide app url:': 'or provide app url:', +'or provide application url:': 'lub podaj url aplikacji:', +'Original/Translation': 'Oryginał/tłumaczenie', +'Overview': 'Overview', +'Overwrite installed app': 'overwrite installed app', +'Pack all': 'spakuj wszystko', +'Pack compiled': 'spakuj skompilowane', +'Pack custom': 'Pack custom', +'pack plugin': 'spakuj wtyczkę', +'PAM authenticated user, cannot change password here': 'PAM authenticated user, cannot change password here', +'password changed': 'password changed', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Podgląd pliku', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Please', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'wtyczka "%(plugin)s" została usunięta', +'Plugin "%s" in application': 'Wtyczka "%s" w aplikacji', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'plugins', +'Plugins': 'Wtyczki', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Zasilane przez', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'poprzednie 100 wierszy', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Project Progress', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Zapytanie:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Record': 'Record', +'record': 'rekord', +'record does not exist': 'rekord nie istnieje', +'record id': 'ID rekordu', +'Record id': 'Record id', +'refresh': 'refresh', +'register': 'register', +'Reload routes': 'Reload routes', +'Remove compiled': 'usuń skompilowane', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Replace', +'Replace All': 'Replace All', +'Repository (%s)': 'Repository (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Resolve Conflict file': 'Rozwiąż konflikt plików', +'response': 'response', +'restart': 'restart', +'restore': 'odtwórz', +'return': 'return', +'Revert': 'Revert', +'revert': 'przywróć', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Role', +'Roles': 'Roles', +'Rows in table': 'Wiersze w tabeli', +'Rows in Table': 'Rows in Table', +'Rows selected': 'Wierszy wybranych', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'Running on %s', +'Save': 'Save', +'save': 'zapisz', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Save via Ajax', +'Saved file hash:': 'Suma kontrolna zapisanego pliku:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'selected': 'zaznaczone', +'session': 'session', +'session expired': 'sesja wygasła', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'powłoka', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'strona główna', +'Size of cache:': 'Size of cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': 'niektóre pliki nie mogły zostać usunięte', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Start a new app', +'Start searching': 'Start searching', +'Start wizard': 'start wizard', +'state': 'stan', +'Static': 'Static', +'static': 'pliki statyczne', +'Static files': 'Pliki statyczne', +'Statistics': 'Statistics', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'submit': 'wyślij', +'Submit': 'Submit', +'successful': 'successful', +'Sure you want to delete this object?': 'Czy na pewno chcesz usunąć ten obiekt?', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': 'tabela', +'Table': 'Table', +'Temporary': 'Temporary', +'test': 'testuj', +'Testing application': 'Testowanie aplikacji', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"Zapytanie" jest warunkiem postaci "db.tabela1.pole1==\'wartość\'". Takie coś jak "db.tabela1.pole1==db.tabela2.pole2" oznacza SQL JOIN.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'the application logic, each URL path is mapped in one exposed function in the controller': 'logika aplikacji, każda ścieżka URL jest mapowana na jedną z funkcji eksponowanych w kontrolerze', +'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller', +'the data representation, define database tables and sets': 'reprezentacja danych, definicje zbiorów i tabel bazy danych', +'The data representation, define database tables and sets': 'The data representation, define database tables and sets', +'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates', +'the presentations layer, views are also known as templates': 'warstwa prezentacji, widoki zwane są również szablonami', +'Theme': 'Theme', +'There are no controllers': 'Brak kontrolerów', +'There are no models': 'Brak modeli', +'There are no modules': 'Brak modułów', +'There are no plugins': 'There are no plugins', +'There are no private files': 'There are no private files', +'There are no static files': 'Brak plików statycznych', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'Brak plików tłumaczeń, wspierany jest tylko domyślny język', +'There are no views': 'Brak widoków', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'These files are served without processing, your images go here', +'these files are served without processing, your images go here': 'pliki obsługiwane bez interpretacji, to jest miejsce na Twoje obrazy', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': 'To jest szablon %(filename)s', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Bilet', +'Ticket ID': 'Ticket ID', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'TM': 'TM', +'to previous version.': 'do poprzedniej wersji.', +'To create a plugin, name a file/folder plugin_[name]': 'Aby utworzyć wtyczkę, nazwij plik/katalog plugin_[nazwa]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'translation strings for the application': 'ciągi tłumaczeń dla aplikacji', +'Translation strings for the application': 'Translation strings for the application', +'try': 'spróbój', +'try something like': 'spróbój czegos takiego jak', +'Try the mobile interface': 'Try the mobile interface', +'try view': 'try view', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Nie można sprawdzić aktualizacji', +'unable to create application "%s"': 'nie można utworzyć aplikacji "%s"', +'unable to delete file "%(filename)s"': 'nie można usunąć pliku "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'nie można usunąc pliku wtyczki "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download': 'Nie można ściągnąć', +'Unable to download app': 'Nie można ściągnąć aplikacji', +'Unable to download app because:': 'Unable to download app because:', +'Unable to download because': 'Unable to download because', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'nie można sparsować pliku csv', +'unable to uninstall "%s"': 'nie można odinstalować "%s"', +'unable to upgrade because "%s"': 'unable to upgrade because "%s"', +'uncheck all': 'odznacz wszystko', +'Uninstall': 'odinstaluj', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'uaktualnij', +'update all languages': 'uaktualnij wszystkie pliki tłumaczeń', +'Update:': 'Uaktualnij:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'upgrade now to %s', +'upgrade web2py now': 'upgrade web2py now', +'upload': 'upload', +'Upload': 'Upload', +'Upload & install packed application': 'Upload & install packed application', +'Upload a package:': 'Upload a package:', +'Upload and install packed application': 'Upload and install packed application', +'upload application:': 'wyślij plik aplikacji:', +'Upload existing application': 'Wyślij istniejącą aplikację', +'upload file:': 'wyślij plik:', +'upload plugin file:': 'wyślij plik wtyczki:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Użyj (...)&(...) jako AND, (...)|(...) jako OR oraz ~(...) jako NOT do tworzenia bardziej skomplikowanych zapytań.', +'Use an url:': 'Use an url:', +'User': 'User', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'variables', +'Version': 'Wersja', +'Versioning': 'Versioning', +'versioning': 'versioning', +'view': 'widok', +'Views': 'Widoki', +'views': 'widoki', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py jest aktualne', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'najnowsze tweety web2py', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py upgraded; please restart it', +'Welcome to web2py': 'Witaj w web2py', +'Working...': 'Working...', +'WSGI reference name': 'WSGI reference name', +'YES': 'TAK', +'Yes': 'Yes', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/plural-en.py b/web2py/applications/admin/languages/plural-en.py new file mode 100644 index 0000000..3c711a3 --- /dev/null +++ b/web2py/applications/admin/languages/plural-en.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +{ +# "singular form (0)": ["first plural form (1)", "second plural form (2)", ...], +'file': ['files'], +} diff --git a/web2py/applications/admin/languages/plural-ru.py b/web2py/applications/admin/languages/plural-ru.py new file mode 100644 index 0000000..0900bc9 --- /dev/null +++ b/web2py/applications/admin/languages/plural-ru.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +{ +# "singular form (0)": ["first plural form (1)", "second plural form (2)", ...], +'файл': ['файла','файлов'], +} diff --git a/web2py/applications/admin/languages/plural-uk.py b/web2py/applications/admin/languages/plural-uk.py new file mode 100644 index 0000000..cbb014a --- /dev/null +++ b/web2py/applications/admin/languages/plural-uk.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +{ +# "singular form (0)": ["first plural form (1)", "second plural form (2)", ...], +'останній': ['останні','останніх'], +'файл': ['файли','файлів'], +'твіт': ['твіти','твітів'], +} diff --git a/web2py/applications/admin/languages/pt-br.py b/web2py/applications/admin/languages/pt-br.py new file mode 100644 index 0000000..7969551 --- /dev/null +++ b/web2py/applications/admin/languages/pt-br.py @@ -0,0 +1,664 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'pt-br', +'!langname!': 'Português Brasileiro', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" é uma expressão opcional como "campo1=\'novo_valor\'". Não é permitido atualizar ou apagar resultados de um JOIN', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s registros apagados', +'%s %%{row} updated': '%s registros atualizados', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%d/%m/%Y', +'%Y-%m-%d %H:%M:%S': '%d/%m/%Y %H:%M:%S', +'(requires internet access, experimental)': '(requer acesso à internet, experimental)', +'(something like "it-it")': '(algo como "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'@markmin\x01Searching: **%s** %%{file}': 'Buscando: **%s** arquivos', +'A new version of web2py is available': 'Está disponível uma nova versão do web2py', +'A new version of web2py is available: %s': 'Está disponível uma nova versão do web2py: %s', +'Abort': 'Abort', +'About': 'sobre', +'About application': 'Sobre a aplicação', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Add breakpoint', +'additional code for your application': 'código adicional para sua aplicação', +'Additional code for your application': 'Código adicional para sua aplicação', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': ' admin desabilitado por falta de senha definida', +'admin disabled because not supported on google app engine': 'admin desabilitado porque não é suportado no GAE', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'admin desabilitado porque não foi possível ler o arquivo de senha', +'Admin is disabled because insecure channel': 'Admin desabilitado pois o canal não é seguro', +'Admin is disabled because unsecure channel': 'Admin desabilitado pois o canal não é seguro', +'Admin language': 'Idioma do Admin', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'interface administrativa', +'Administrator Password:': 'Senha de administrador:', +'and rename it (required):': 'e renomeie (requerido):', +'and rename it:': ' e renomeie:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'admin desabilitado porque o canal não é seguro', +'Application': 'Application', +'application "%s" uninstalled': 'aplicação "%s" desinstalada', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'aplicação compilada', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'A aplicação está compilada e não pode ser modificada', +'Application name:': 'Nome da aplicação:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'are not used', +'are not used yet': 'are not used yet', +'Are you sure you want to delete file "%s"?': 'Tem certeza que deseja apagar o arquivo "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Tem certeza que deseja apagar o plugin "%s"?', +'Are you sure you want to delete this object?': 'Tem certeza que deseja apagar esse objeto?', +'Are you sure you want to uninstall application "%s"': 'Tem certeza que deseja desinstalar a aplicação "%s"?', +'Are you sure you want to uninstall application "%s"?': 'Tem certeza que deseja desinstalar a aplicação "%s"?', +'Are you sure you want to upgrade web2py now?': 'Tem certeza que deseja atualizar o web2py agora?', +'Are you sure?': 'Are you sure?', +'arguments': 'argumentos', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATENÇÃO: o login requer uma conexão segura (HTTPS) ou executar de localhost.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATENÇÃO OS TESTES NÃO SÃO THREAD SAFE, NÃO EFETUE MÚLTIPLOS TESTES AO MESMO TEMPO.', +'ATTENTION: you cannot edit the running application!': 'ATENÇÃO: Não pode modificar a aplicação em execução!', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available databases and tables': 'Bancos de dados e tabelas disponíveis', +'Available Databases and Tables': 'Available Databases and Tables', +'back': 'voltar', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Informações básicas', +'Begin': 'Iniciar', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'browse': 'navegar', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'cache, erros e sessões eliminadas', +'can be a git repo': 'pode ser um repositório git', +'Cancel': 'Cancel', +'Cannot be empty': 'Não pode ser vazio', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Não é possível compilar: Existem erros em sua aplicação. Depure, corrija os errros e tente novamente', +'Cannot compile: there are errors in your app:': 'Não é possível compilar: Existem erros em sua aplicação', +'cannot create file': 'Não é possível criar o arquivo', +'cannot upload file "%(filename)s"': 'não é possível fazer upload do arquivo "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'mudar senha de administrador', +'change editor settings': 'change editor settings', +'Change Password': 'Mudar Senha', +'Changelog': 'Changelog', +'check all': 'marcar todos', +'Check for upgrades': 'Verificar se existem atualizações', +'Check to delete': 'Marque para apagar', +'Checking for upgrades...': 'Buscando atualizações...', +'Clean': 'Limpo', +'Clear': 'Clear', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'click here for online examples': 'clique para ver exemplos online', +'click here for the administrative interface': 'Clique aqui para acessar a interface administrativa', +'Click row to expand traceback': 'Clique na linha para expandir o traceback', +'Click row to view a ticket': 'Click row to view a ticket', +'click to check for upgrades': 'clique aqui para verificar se existem atualizações', +'click to open': 'clique para abrir', +'Client IP': 'IP do cliente', +'code': 'código', +'Code listing': 'Code listing', +'collapse/expand all': 'fechar/abrir todos', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'commit (mercurial)': 'commit (mercurial)', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'Compilar', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'a aplicação compilada foi removida', +'Condition': 'Condition', +'continue': 'continue', +'Controllers': 'Controladores', +'controllers': 'controladores', +'Count': 'Contagem', +'Create': 'Criar', +'create file with filename:': 'criar um arquivo com o nome:', +'Create new application using the Wizard': 'Criar nova aplicação utilizando o Assistente', +'create new application:': 'nome da nova aplicação:', +'Create new simple application': 'Crie uma nova aplicação', +'Create/Upload': 'Create/Upload', +'created by': 'criado por', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Requisição atual', +'Current response': 'Resposta atual', +'Current session': 'Sessão atual', +'currently running': 'Executando', +'currently saved or': 'Atualmente salvo ou', +'customize me!': 'Modifique-me!', +'data uploaded': 'Dados enviados', +'Database': 'Database', +'database': 'banco de dados', +'Database %s select': 'Database %s select', +'database %s select': 'Select no banco de dados %s', +'Database administration': 'Database administration', +'database administration': 'administração do banco de dados', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Data e Hora', +'db': 'db', +'Debug': 'Debug', +'defines tables': 'define as tabelas', +'Delete': 'Apague', +'delete': 'apagar', +'delete all checked': 'apagar marcados', +'delete plugin': 'apagar plugin', +'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)', +'Delete:': 'Apague:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'Publicar', +'Deploy on Google App Engine': 'Publicar no Google App Engine', +'Deploy to OpenShift': 'Publicar no OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description': 'Descrição', +'Description:': 'Description:', +'design': 'projeto', +'DESIGN': 'Projeto', +'Design for': 'Projeto de', +'Detailed traceback description': 'Descrição detalhada do traceback', +'details': 'details', +'direction: ltr': 'direção: ltr', +'directory not found': 'directory not found', +'Disable': 'Desabilitar', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'docs', +'Docs': 'Docs', +'done!': 'feito!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'download de layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'download de plugins', +'Download plugins from repository': 'Download plugins from repository', +'E-mail': 'E-mail', +'EDIT': 'EDITAR', +'Edit': 'Editar', +'edit all': 'editar todos', +'Edit application': 'Editar aplicação', +'edit controller': 'editar controlador', +'edit controller:': 'edit controller:', +'Edit current record': 'Editar o registro atual', +'Edit Profile': 'Editar Perfil', +'edit views:': 'editar visões:', +'Editing %s': 'Editing %s', +'Editing file': 'Editando arquivo', +'Editing file "%s"': 'Editando arquivo "%s"', +'Editing Language file': 'Editando arquivo de idioma', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Enable', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Enterprise Web Framework': 'Framework Web Corporativo', +'Error': 'Erro', +'Error logs for "%(app)s"': 'Logs de erro para "%(app)s"', +'Error snapshot': 'Momento do Erro', +'Error ticket': 'Tiquete de Erro', +'Errors': 'Erros', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Atributos de instância da Exception', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'exportar como arquivo CSV', +'Exports:': 'Exports:', +'exposes': 'expõe', +'exposes:': 'exposes:', +'extends': 'estende', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module': 'Falha ao recarregar o módulo', +'failed to reload module because:': 'falha ao recarregar o módulo porque:', +'File': 'Arquivo', +'file "%(filename)s" created': 'arquivo "%(filename)s" criado', +'file "%(filename)s" deleted': 'arquivo "%(filename)s" apagado', +'file "%(filename)s" uploaded': 'arquivo "%(filename)s" enviado', +'file "%(filename)s" was not deleted': 'arquivo "%(filename)s" não foi apagado', +'file "%s" of %s restored': 'arquivo "%s" de %s restaurado', +'file changed on disk': 'arquivo modificado no disco', +'file does not exist': 'arquivo não existe', +'file not found': 'file not found', +'file saved on %(time)s': 'arquivo salvo em %(time)s', +'file saved on %s': 'arquivo salvo em %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'filtro', +'Find Next': 'Find Next', +'Find Previous': 'Find Previous', +'First name': 'Nome', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': 'Funções sem doctests resultarão em testes [aceitos].', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Gerar', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'go!': 'vai!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Group ID': 'ID do Grupo', +'Hello World': 'Olá Mundo', +'Help': 'Ajuda', +'here': 'here', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'htmledit': 'htmledit', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Se o relatório acima contém um número de ticket, isso indica uma falha no controlador em execução, antes de tentar executar os doctests. Isto acontece geralmente por erro de identação ou um erro fora do código da função.\nO título em verde indica que os testes (se definidos) passaram. Neste caso o resultado dos testes não são mostrados.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Importar/Exportar', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'inclui', +'Indent with tabs': 'Indent with tabs', +'insert new': 'inserir novo', +'insert new %s': 'inserir novo %s', +'inspect attributes': 'inspeciona atributos', +'Install': 'instalar', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Aplicações instaladas', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'erro interno', +'internal error: %s': 'internal error: %s', +'Internal State': 'Estado Interno', +'Invalid action': 'Ação inválida', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid email': 'E-mail inválido', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'senha inválida', +'invalid password.': 'invalid password.', +'Invalid Query': 'Consulta inválida', +'invalid request': 'solicitação inválida', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'ticket inválido', +'Key': 'Key', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'arquivo de idioma "%(filename)s" criado/atualizado', +'Language files (static strings) updated': 'Arquivos de idioma (textos estáticos) atualizados', +'languages': 'idiomas', +'Languages': 'Idiomas', +'languages updated': 'idiomas atualizados', +'Last name': 'Sobrenome', +'Last Revision': 'Last Revision', +'Last saved on:': 'Salvo pela última vez em:', +'License for': 'Licença para', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Loading...': 'Loading...', +'loading...': 'carregando...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'login': 'início de sessão', +'Login': 'Entrar', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Entrar na interface adminitrativa', +'Login/Register': 'Login/Register', +'Logout': 'finalizar sessão', +'Lost Password': 'Perdi a senha', +'lost password': 'lost password', +'Main Menu': 'Main Menu', +'Manage': 'Gerenciar', +'manage': 'gerenciar', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Memberships': 'Memberships', +'merge': 'juntar', +'models': 'modelos', +'Models': 'Modelos', +'Modified On': 'Modified On', +'Modules': 'Módulos', +'modules': 'módulos', +'Multi User Mode': 'Multi User Mode', +'Name': 'Nome', +'new application "%s" created': 'nova aplicação "%s" criada', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'Assistente para novas aplicações ', +'New application wizard': 'Assistente para novas aplicações', +'new plugin installed': 'novo plugin instalado', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'Novo registro', +'new record inserted': 'novo registro inserido', +'New simple application': 'Nova aplicação básica', +'next': 'next', +'next %s rows': 'next %s rows', +'next 100 rows': 'próximos 100 registros', +'NO': 'NÃO', +'no changes': 'no changes', +'No databases in this application': 'Não existem bancos de dados nesta aplicação', +'No Interaction yet': 'No Interaction yet', +'no match': 'não encontrado', +'no package selected': 'nenhum pacote selecionado', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Ou baixa da URL:', +'or import from csv file': 'ou importar de um arquivo CSV', +'or provide app url:': 'ou forneça a url de uma aplicação:', +'or provide application url:': 'ou forneça a url de uma aplicação:', +'Origin': 'Origem', +'Original/Translation': 'Original/Tradução', +'Overview': 'Overview', +'Overwrite installed app': 'Sobrescrever aplicação instalada', +'Pack all': 'Criar pacote', +'Pack compiled': 'Criar pacote compilado', +'Pack custom': 'Customizar pacote', +'pack plugin': 'empacotar plugin', +'PAM authenticated user, cannot change password here': 'usuário autenticado por PAM não pode alterar a senha aqui', +'Password': 'Senha', +'password changed': 'senha alterada', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Visualizando arquivo', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Please', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" apagado', +'Plugin "%s" in application': 'Plugin "%s" na aplicação', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'plugins', +'Plugins': 'Plugins', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Este site utiliza', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '100 registros anteriores', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Project Progress', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Consulta:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Record': 'Record', +'record': 'registro', +'record does not exist': 'o registro não existe', +'record id': 'id do registro', +'Record ID': 'ID do Registro', +'Record id': 'Record id', +'refresh': 'refresh', +'register': 'register', +'Register': 'Registrar-se', +'Registration key': 'Chave de registro', +'Reload routes': 'Recarregar routes', +'Remove compiled': 'Eliminar compilados', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Replace', +'Replace All': 'Replace All', +'Repository (%s)': 'Repository (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Resolve Conflict file': 'Arquivo de resolução de conflito', +'response': 'response', +'restart': 'reiniciar', +'restore': 'restaurar', +'return': 'return', +'Revert': 'Revert', +'revert': 'reverter', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Papel', +'Roles': 'Roles', +'Rows in table': 'Registros na tabela', +'Rows in Table': 'Rows in Table', +'Rows selected': 'Registros selecionados', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'Rodando em %s', +'Save': 'Save', +'save': 'salvar', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Save via Ajax', +'Saved file hash:': 'Hash do arquivo salvo:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Selecione arquivos para empacotar', +'selected': 'selecionado(s)', +'session': 'session', +'session expired': 'sessão expirada', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'Terminal', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'Site', +'Size of cache:': 'Size of cache:', +'skip to generate': 'pular para a gerar a aplicação', +'some files could not be removed': 'alguns arquivos não puderam ser removidos', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Inicie uma nova aplicação', +'Start searching': 'Start searching', +'Start wizard': 'Iniciar assistente', +'state': 'estado', +'Static': 'Static', +'static': 'estáticos', +'Static files': 'Arquivos estáticos', +'Statistics': 'Statistics', +'Step': 'Passo', +'step': 'step', +'stop': 'stop', +'submit': 'enviar', +'Submit': 'Enviar', +'successful': 'successful', +'Sure you want to delete this object?': 'Tem certeza que deseja apagar este objeto?', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': 'tabela', +'Table': 'Table', +'Table name': 'Nome da tabela', +'Temporary': 'Temporary', +'test': 'testar', +'Testing application': 'Testando a aplicação', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'A "consulta" é uma condição como "db.tabela.campo1==\'valor\'". Algo como "db.tabela1.campo1==db.tabela2.campo2" resulta em um JOIN SQL.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'the application logic, each URL path is mapped in one exposed function in the controller': 'A lógica da aplicação, cada URL é mapeada para uma função exposta pelo controlador', +'The application logic, each URL path is mapped in one exposed function in the controller': 'A lógica da aplicação, cada URL é mapeada para uma função exposta pelo controlador', +'the data representation, define database tables and sets': 'A representação dos dados, define tabelas do banco de dados e conjuntos', +'The data representation, define database tables and sets': 'A representação dos dados, define tabelas do banco de dados e conjuntos', +'The presentations layer, views are also known as templates': 'A camada de apresentação, as visões também são chamadas de templates', +'the presentations layer, views are also known as templates': 'A camada de apresentação, as visões também são chamadas de templates', +'Theme': 'Theme', +'There are no controllers': 'Não existem controladores', +'There are no models': 'Não existem modelos', +'There are no modules': 'Não existem módulos', +'There are no plugins': 'Não existem plugins', +'There are no private files': 'There are no private files', +'There are no static files': 'Não existem arquicos estáticos', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'Não há tradutores, somente a linguagem padrão é suportada', +'There are no views': 'Não existem visões', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'Estes arquivos são servidos sem processamento, suas imagens ficam aqui', +'these files are served without processing, your images go here': 'Estes arquivos são servidos sem processamento, suas imagens ficam aqui', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': 'Este é o template %(filename)s', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Ticket', +'Ticket ID': 'Número do Ticket', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'Momento de geração', +'TM': 'MR', +'to previous version.': 'para a versão anterior.', +'To create a plugin, name a file/folder plugin_[name]': 'Para criar um plugin, nomeie um arquivo/pasta como plugin_[nome]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'translation strings for the application': 'textos traduzidos para a aplicação', +'Translation strings for the application': 'textos traduzidos para a aplicação', +'try': 'tente', +'try something like': 'tente algo como', +'Try the mobile interface': 'Experimente a interface para smartphones e tablets', +'try view': 'try view', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Não é possível checar as atualizações', +'unable to create application "%s"': 'não é possível criar a aplicação "%s"', +'unable to delete file "%(filename)s"': 'não é possível criar o arquivo "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'não é possível criar o plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download': 'Não é possível efetuar o download', +'Unable to download app': 'Não é possível baixar a aplicação', +'Unable to download app because:': 'Não é possível baixar a aplicação porque:', +'Unable to download because': 'Não é possível baixar porque', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'não é possível analisar o arquivo CSV', +'unable to uninstall "%s"': 'não é possível desinstalar "%s"', +'unable to upgrade because "%s"': 'não é possível atualizar porque "%s"', +'uncheck all': 'desmarcar todos', +'Uninstall': 'Desinstalar', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'alterar', +'update all languages': 'alterar todos os idiomas', +'Update:': 'Alterar:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'Atualize agora para %s', +'upgrade web2py now': 'atualize o web2py agora', +'upload': 'upload', +'Upload': 'Upload', +'Upload a package:': 'Faça upload de um pacote:', +'Upload and install packed application': 'Faça upload e instale uma aplicação empacotada', +'upload application:': 'Fazer upload de uma aplicação:', +'Upload existing application': 'Faça upload de uma aplicação existente', +'upload file:': 'Enviar arquivo:', +'upload plugin file:': 'Enviar arquivo de plugin:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) para AND, (...)|(...) para OR, e ~(...) para NOT, para criar consultas mais complexas.', +'Use an url:': 'Use uma url:', +'User': 'User', +'User ID': 'ID do Usuário', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'variáveis', +'Version': 'Versão', +'Versioning': 'Versionamento', +'versioning': 'versionamento', +'view': 'visão', +'Views': 'Visões', +'views': 'visões', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py está atualizado', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'Tweets Recentes de @web2py', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py atualizado; favor reiniciar', +'Welcome to web2py': 'Bem-vindo ao web2py', +'Working...': 'Working...', +'WSGI reference name': 'WSGI reference name', +'YES': 'SIM', +'Yes': 'Yes', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/pt.py b/web2py/applications/admin/languages/pt.py new file mode 100644 index 0000000..e27c6ea --- /dev/null +++ b/web2py/applications/admin/languages/pt.py @@ -0,0 +1,670 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'pt', +'!langname!': 'Português', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" é uma expressão opcional como "campo1=\'novo_valor\'". Não é permitido atualizar ou apagar resultados de um JOIN', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s registros apagados', +'%s %%{row} updated': '%s registros atualizados', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%d/%m/%Y', +'%Y-%m-%d %H:%M:%S': '%d/%m/%Y %H:%M:%S', +'(requires internet access)': '(requer acesso à internet)', +'(requires internet access, experimental)': '(requer acesso à internet, experimental)', +'(something like "it-it")': '(algo como "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(file **gluon/contrib/plural_rules/%s.py** is not found)', +'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files', +'A new version of web2py is available': 'Está disponível uma nova versão do web2py', +'A new version of web2py is available: %s': 'Está disponível uma nova versão do web2py: %s', +'Abort': 'Abort', +'About': 'sobre', +'About application': 'Sobre a aplicação', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Add breakpoint', +'additional code for your application': 'código adicional para sua aplicação', +'Additional code for your application': 'Código adicional para a sua aplicação', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': ' admin desabilitado por falta de senha definida', +'admin disabled because not supported on google app engine': 'admin dehabilitado, não é soportado no GAE', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'admin desabilitado, não foi possível ler o arquivo de senha', +'Admin is disabled because insecure channel': 'Admin desabilitado pois o canal não é seguro', +'Admin is disabled because unsecure channel': 'Admin desabilitado pois o canal não é seguro', +'Admin language': 'Linguagem do Admin', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'interface administrativa', +'Administrator Password:': 'Senha de administrador:', +'and rename it (required):': 'e renomeie (requerido):', +'and rename it:': ' e renomeie:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'admin desabilitado, canal inseguro', +'Application': 'Application', +'application "%s" uninstalled': 'aplicação "%s" desinstalada', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'aplicação compilada', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'A aplicação está compilada e não pode ser modificada', +'Application name:': 'Nome da aplicação:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'não usadas', +'are not used yet': 'ainda não usadas', +'Are you sure you want to delete file "%s"?': 'Tem certeza que deseja apagar o arquivo "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Tem certeza que deseja apagar o plugin "%s"?', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Are you sure you want to uninstall application "%s"': 'Tem certeza que deseja apagar a aplicação "%s"?', +'Are you sure you want to uninstall application "%s"?': 'Tem certeza que deseja apagar a aplicação "%s"?', +'Are you sure you want to upgrade web2py now?': 'Tem certeza que deseja atualizar o web2py agora?', +'Are you sure?': 'Are you sure?', +'arguments': 'argumentos', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATENÇÃO o login requer uma conexão segura (HTTPS) ou executar de localhost.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATENÇÃO OS TESTES NÃO THREAD SAFE, NÃO EFETUE MÚLTIPLOS TESTES AO MESMO TEMPO.', +'ATTENTION: you cannot edit the running application!': 'ATENÇÃO: Não pode modificar a aplicação em execução!', +'Autocomplete Python Code': 'Autocompletar Código Python', +'Available databases and tables': 'Bancos de dados e tabelas disponíveis', +'Available Databases and Tables': 'Available Databases and Tables', +'back': 'voltar', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'Begin': 'Begin', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'browse': 'buscar', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'cache, erros e sessões eliminadas', +'can be a git repo': 'can be a git repo', +'Cancel': 'Cancel', +'Cannot be empty': 'Não pode ser vazio', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Não é possível compilar: Existem erros em sua aplicação. Depure, corrija os errros e tente novamente', +'Cannot compile: there are errors in your app:': 'Não é possível compilar: Existem erros em sua aplicação', +'cannot create file': 'Não é possível criar o arquivo', +'cannot upload file "%(filename)s"': 'não é possível fazer upload do arquivo "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'mudar senha de administrador', +'change editor settings': 'mudar definições do editor', +'Change Password': 'Trocar Senha', +'Changelog': 'Changelog', +'check all': 'marcar todos', +'Check for upgrades': 'checar por atualizações', +'Check to delete': 'Marque para apagar', +'Checking for upgrades...': 'Buscando atualizações...', +'Clean': 'limpar', +'Clear': 'Clear', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'click here for online examples': 'clique para ver exemplos online', +'click here for the administrative interface': 'Clique aqui para acessar a interface administrativa', +'Click row to expand traceback': 'Clique em uma coluna para expandir o log do erro', +'Click row to view a ticket': 'Click row to view a ticket', +'click to check for upgrades': 'clique aqui para checar por atualizações', +'click to open': 'clique para abrir', +'Client IP': 'IP do cliente', +'code': 'código', +'Code listing': 'Code listing', +'collapse/expand all': 'colapsar/expandir tudo', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'commit (mercurial)': 'commit (mercurial)', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'compilar', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'aplicação compilada removida', +'Condition': 'Condition', +'continue': 'continue', +'Controllers': 'Controladores', +'controllers': 'controladores', +'Count': 'Contagem', +'Create': 'criar', +'create file with filename:': 'criar um arquivo com o nome:', +'Create new application using the Wizard': 'Criar nova aplicação utilizando o assistente', +'create new application:': 'nome da nova aplicação:', +'Create new simple application': 'Crie uma nova aplicação', +'Create/Upload': 'Create/Upload', +'created by': 'criado por', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Requisição atual', +'Current response': 'Resposta atual', +'Current session': 'Sessão atual', +'currently running': 'Executando', +'currently saved or': 'Atualmente salvo ou', +'customize me!': 'Modifique-me', +'data uploaded': 'Dados enviados', +'Database': 'Database', +'database': 'banco de dados', +'Database %s select': 'Database %s select', +'database %s select': 'Seleção no banco de dados %s', +'Database administration': 'Database administration', +'database administration': 'administração de banco de dados', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Data e Hora', +'db': 'db', +'Debug': 'Debug', +'defines tables': 'define as tabelas', +'Delete': 'Apague', +'delete': 'apagar', +'delete all checked': 'apagar marcados', +'delete plugin': 'apagar plugin', +'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)', +'Delete:': 'Apague:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'publicar', +'Deploy on Google App Engine': 'Publicar no Google App Engine', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description': 'Descrição', +'Description:': 'Description:', +'design': 'modificar', +'DESIGN': 'Projeto', +'Design for': 'Projeto de', +'Detailed traceback description': 'Detailed traceback description', +'details': 'details', +'direction: ltr': 'direção: ltr', +'directory not found': 'directory not found', +'Disable': 'Disable', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'docs', +'Docs': 'Docs', +'done!': 'feito!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'download layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'download plugins', +'Download plugins from repository': 'Download plugins from repository', +'E-mail': 'E-mail', +'EDIT': 'EDITAR', +'Edit': 'editar', +'edit all': 'edit all', +'Edit application': 'Editar aplicação', +'edit controller': 'editar controlador', +'edit controller:': 'edit controller:', +'Edit current record': 'Editar o registro atual', +'Edit Profile': 'Editar Perfil', +'edit views:': 'editar visões:', +'Editing %s': 'A Editar %s', +'Editing file': 'Editando arquivo', +'Editing file "%s"': 'Editando arquivo "%s"', +'Editing Language file': 'Editando arquivo de linguagem', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Enable', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Enterprise Web Framework': 'Framework web empresarial', +'Error': 'Erro', +'Error logs for "%(app)s"': 'Logs de erro para "%(app)s"', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Error ticket', +'Errors': 'erros', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Atributos da instancia de excessão', +'Exit Fullscreen': 'Sair de Ecrã Inteiro', +'Expand Abbreviation (html files only)': 'Expandir Abreviação (só para ficheiros html)', +'export as csv file': 'exportar como arquivo CSV', +'Exports:': 'Exports:', +'exposes': 'expõe', +'exposes:': 'exposes:', +'extends': 'estende', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module': 'Falha ao recarregar o módulo', +'failed to reload module because:': 'falha ao recarregar o módulo por:', +'File': 'Arquivo', +'file "%(filename)s" created': 'arquivo "%(filename)s" criado', +'file "%(filename)s" deleted': 'arquivo "%(filename)s" apagado', +'file "%(filename)s" uploaded': 'arquivo "%(filename)s" enviado', +'file "%(filename)s" was not deleted': 'arquivo "%(filename)s" não foi apagado', +'file "%s" of %s restored': 'arquivo "%s" de %s restaurado', +'file changed on disk': 'arquivo modificado no disco', +'file does not exist': 'arquivo não existe', +'file not found': 'file not found', +'file saved on %(time)s': 'arquivo salvo em %(time)s', +'file saved on %s': 'arquivo salvo em %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'filtro', +'Find Next': 'Localizar Seguinte', +'Find Previous': 'Localizar Anterior', +'First name': 'Nome', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': 'Funções sem doctests resultarão em testes [aceitos].', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Group ID': 'ID do Grupo', +'Hello World': 'Olá Mundo', +'Help': 'ajuda', +'here': 'here', +'Hide/Show Translated strings': '', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'htmledit': 'htmledit', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Se o relatório acima contém um número de ticket, isso indica uma falha no controlador em execução, antes de tantar executar os doctests. Isto acontece geralmente por erro de endentação ou erro fora do código da função.\r\nO titulo em verde indica que os testes (se definidos) passaram. Neste caso os testes não são mostrados.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Importar/Exportar', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'inclui', +'Indent with tabs': 'Indent with tabs', +'insert new': 'inserir novo', +'insert new %s': 'inserir novo %s', +'inspect attributes': 'inspecionar atributos', +'Install': 'instalar', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Aplicações instaladas', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'erro interno', +'internal error: %s': 'internal error: %s', +'Internal State': 'Estado Interno', +'Invalid action': 'Ação inválida', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid email': 'E-mail inválido', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'senha inválida', +'invalid password.': 'invalid password.', +'Invalid Query': 'Consulta inválida', +'invalid request': 'solicitação inválida', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'ticket inválido', +'Key': 'Key', +'Keyboard shortcuts': 'Atalhos de teclado', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'arquivo de linguagem "%(filename)s" criado/atualizado', +'Language files (static strings) updated': 'Arquivos de linguagem (textos estáticos) atualizados', +'languages': 'linguagens', +'Languages': 'Linguagens', +'languages updated': 'linguagens atualizadas', +'Last name': 'Sobrenome', +'Last Revision': 'Last Revision', +'Last saved on:': 'Salvo em:', +'License for': 'Licença para', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Loading...': 'Loading...', +'loading...': 'carregando...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'login': 'inicio de sessão', +'Login': 'Entrar', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Entrar na interface adminitrativa', +'Login/Register': 'Login/Register', +'Logout': 'finalizar sessão', +'Lost Password': 'Senha perdida', +'lost password': 'lost password', +'Main Menu': 'Main Menu', +'Manage': 'Manage', +'manage': 'gerenciar', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Memberships': 'Memberships', +'merge': 'juntar', +'models': 'modelos', +'Models': 'Modelos', +'Modified On': 'Modified On', +'Modules': 'Módulos', +'modules': 'módulos', +'Multi User Mode': 'Multi User Mode', +'Name': 'Nome', +'new application "%s" created': 'nova aplicação "%s" criada', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'New Application Wizard', +'New application wizard': 'Assistente para novas aplicações ', +'new plugin installed': 'novo plugin instalado', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'Novo registro', +'new record inserted': 'novo registro inserido', +'New simple application': 'Nova aplicação básica', +'next': 'next', +'next %s rows': 'next %s rows', +'next 100 rows': 'próximos 100 registros', +'NO': 'NÃO', +'no changes': 'no changes', +'No databases in this application': 'Não existem bancos de dados nesta aplicação', +'No Interaction yet': 'No Interaction yet', +'no match': 'não encontrado', +'no package selected': 'nenhum pacote selecionado', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'No ticket_storage.txt found under /private folder': 'No ticket_storage.txt found under /private folder', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'online designer': 'online designer', +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Ou Obtenha do URL:', +'or import from csv file': 'ou importar de um arquivo CSV', +'or provide app url:': 'ou forneça a url de uma aplicação:', +'or provide application url:': 'ou forneça a url de uma aplicação:', +'Origin': 'Origem', +'Original/Translation': 'Original/Tradução', +'Overview': 'Overview', +'Overwrite installed app': 'sobrescrever aplicação instalada', +'Pack all': 'criar pacote', +'Pack compiled': 'criar pacote compilado', +'Pack custom': 'Pack custom', +'pack plugin': 'empacotar plugin', +'PAM authenticated user, cannot change password here': 'usuario autenticado por PAM, não pode alterar a senha por aqui', +'Password': 'Senha', +'password changed': 'senha alterada', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Visualizando arquivo', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Please', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" eliminado', +'Plugin "%s" in application': 'Plugin "%s" na aplicação', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'plugins', +'Plugins': 'Plugins', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Este site utiliza', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '100 registros anteriores', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Project Progress', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Consulta:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Read': 'Read', +'Record': 'Record', +'record': 'registro', +'record does not exist': 'o registro não existe', +'record id': 'id do registro', +'Record ID': 'ID do Registro', +'Record id': 'Record id', +'refresh': 'refresh', +'register': 'register', +'Register': 'Registrar-se', +'Registration key': 'Chave de registro', +'Reload routes': 'Reload routes', +'Remove compiled': 'eliminar compilados', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Substituir', +'Replace All': 'Substituir Tudo', +'Repository (%s)': 'Repository (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Resolve Conflict file': 'Arquivo de resolução de conflito', +'response': 'response', +'restart': 'restart', +'restore': 'restaurar', +'return': 'return', +'Revert': 'Revert', +'revert': 'reverter', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Papel', +'Roles': 'Roles', +'Rows in table': 'Registros na tabela', +'Rows in Table': 'Rows in Table', +'Rows selected': 'Registros selecionados', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'A correr em %s', +'Save': 'Save', +'save': 'salvar', +'Save file:': 'Gravar ficheiro:', +'Save file: %s': 'Gravar ficheiro: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Gravar via Ajax', +'Saved file hash:': 'Hash do arquivo salvo:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'selected': 'selecionado(s)', +'session': 'session', +'session expired': 'sessão expirada', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'Terminal', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'site', +'Size of cache:': 'Size of cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': 'alguns arquicos não puderam ser removidos', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Start a new app', +'Start searching': 'Start searching', +'Start wizard': 'iniciar assistente', +'state': 'estado', +'Static': 'Static', +'static': 'estáticos', +'Static files': 'Arquivos estáticos', +'Statistics': 'Statistics', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'submit': 'enviar', +'Submit': 'Submit', +'successful': 'successful', +'Sure you want to delete this object?': 'Tem certeza que deseja apaagr este objeto?', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': 'tabela', +'Table': 'Table', +'Table name': 'Nome da tabela', +'Temporary': 'Temporary', +'test': 'testar', +'Testing application': 'Testando a aplicação', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'A "consulta" é uma condição como "db.tabela.campo1==\'valor\'". Algo como "db.tabela1.campo1==db.tabela2.campo2" resulta em um JOIN SQL.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'the application logic, each URL path is mapped in one exposed function in the controller': 'A lógica da aplicação, cada URL é mapeada para uma função exposta pelo controlador', +'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller', +'the data representation, define database tables and sets': 'A representação dos dadps, define tabelas e estruturas de dados', +'The data representation, define database tables and sets': 'The data representation, define database tables and sets', +'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates', +'the presentations layer, views are also known as templates': 'A camada de apresentação, As visões também são chamadas de templates', +'Theme': 'Theme', +'There are no controllers': 'Não existem controllers', +'There are no models': 'Não existem modelos', +'There are no modules': 'Não existem módulos', +'There are no plugins': 'There are no plugins', +'There are no private files': '', +'There are no static files': 'Não existem arquicos estáticos', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'Não há traduções, somente a linguagem padrão é suportada', +'There are no views': 'Não existem visões', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'These files are served without processing, your images go here', +'these files are served without processing, your images go here': 'Estes arquivos são servidos sem processamento, suas imagens ficam aqui', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': 'Este é o template %(filename)s', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Ticket', +'Ticket ID': 'Ticket ID', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'Data Atual', +'TM': 'MR', +'to previous version.': 'para a versão anterior.', +'To create a plugin, name a file/folder plugin_[name]': 'Para criar um plugin, nomeio um arquivo/pasta como plugin_[nome]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'translation strings for the application': 'textos traduzidos para a aplicação', +'Translation strings for the application': 'Translation strings for the application', +'try': 'tente', +'try something like': 'tente algo como', +'Try the mobile interface': 'Try the mobile interface', +'try view': 'try view', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Não é possível checar as atualizações', +'unable to create application "%s"': 'não é possível criar a aplicação "%s"', +'unable to delete file "%(filename)s"': 'não é possível criar o arquico "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'não é possível criar o plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download': 'Não é possível efetuar o download', +'Unable to download app': 'Não é possível baixar a aplicação', +'Unable to download app because:': 'Não é possível baixar a aplicação porque:', +'Unable to download because': 'Não é possível baixar porque', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'não é possível analisar o arquivo CSV', +'unable to uninstall "%s"': 'não é possível instalar "%s"', +'unable to upgrade because "%s"': 'não é possível atualizar porque "%s"', +'uncheck all': 'desmarcar todos', +'Uninstall': 'desinstalar', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'atualizar', +'update all languages': 'atualizar todas as linguagens', +'Update:': 'Atualizar:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'upgrade now to %s', +'upgrade web2py now': 'atualize o web2py agora', +'upload': 'upload', +'Upload': 'Upload', +'Upload & install packed application': 'Faça upload e instale uma aplicação empacotada', +'Upload a package:': 'Faça upload de um pacote:', +'Upload and install packed application': 'Upload and install packed application', +'upload application:': 'Fazer upload de uma aplicação:', +'Upload existing application': 'Faça upload de uma aplicação existente', +'upload file:': 'Enviar arquivo:', +'upload plugin file:': 'Enviar arquivo de plugin:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) para AND, (...)|(...) para OR, y ~(...) para NOT, para criar consultas mais complexas.', +'Use an url:': 'Use uma url:', +'User': 'User', +'User ID': 'ID do Usuario', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'variáveis', +'Version': 'Versão', +'Versioning': 'Versioning', +'versioning': 'versionamento', +'view': 'visão', +'Views': 'Visões', +'views': 'visões', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py está atualizado', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'Tweets Recentes de @web2py', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py atualizado; favor reiniciar', +'Welcome to web2py': 'Bem-vindo ao web2py', +'Working...': 'Working...', +'WSGI reference name': 'WSGI reference name', +'YES': 'SIM', +'Yes': 'Yes', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/ro.py b/web2py/applications/admin/languages/ro.py new file mode 100644 index 0000000..bc8c5a0 --- /dev/null +++ b/web2py/applications/admin/languages/ro.py @@ -0,0 +1,788 @@ +# -*- coding: utf-8 -*- +{ +'!=': '!=', +'!langcode!': 'ro', +'!langname!': 'Română', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" (actualizează) este o expresie opțională precum "câmp1=\'valoare_nouă\'". Nu puteți actualiza sau șterge rezultatele unui JOIN', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%(nrows)s records found': '%(nrows)s înregistrări găsite', +'%s': '%s', +'%s %%{row} deleted': '%s linii șterse', +'%s %%{row} updated': '%s linii actualizate', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(requires internet access)': '(are nevoie de acces internet)', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(ceva ce seamănă cu "it-it")', +'(version %s)': '(version %s)', +'<': '<', +'<=': '<=', +'=': '=', +'>': '>', +'>=': '>=', +'?': '?', +'@markmin\x01Searching: **%s** %%{file}': 'Căutare: **%s** fișiere', +'A new version of web2py is available': 'O nouă versiune de web2py este disponibilă', +'A new version of web2py is available: %s': 'O nouă versiune de web2py este disponibilă: %s', +'Abort': 'Anulează', +'About': 'Despre', +'about': 'despre', +'About application': 'Despre aplicație', +'Accept Terms': 'Accept Terms', +'Access Control': 'Control acces', +'Add': 'Adaugă', +'Add breakpoint': 'Add breakpoint', +'additional code for your application': 'cod suplimentar pentru aplicația dvs.', +'Additional code for your application': 'Cod suplimentar pentru aplicație', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'administrare dezactivată deoarece parola de administrator nu a fost furnizată', +'admin disabled because not supported on google app engine': 'administrare dezactivată deoarece funcționalitatea nu e suportat pe Google App Engine', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'administrare dezactivată deoarece nu există acces la fișierul cu parole', +'Admin is disabled because insecure channel': 'Adminstrarea este dezactivată deoarece conexiunea nu este sigură', +'Admin is disabled because unsecure channel': 'Administrarea este dezactivată deoarece conexiunea nu este securizată', +'Admin language': 'Limba de administrare', +'Admin versioning page': 'Admin versioning page', +'Administration': 'Administrare', +'administrative interface': 'interfață de administrare', +'Administrative Interface': 'Interfață administrare', +'Administrator Password:': 'Parolă administrator:', +'Ajax Recipes': 'Rețete Ajax', +'And': 'Și', +'and rename it (required):': 'și renumește (obligatoriu):', +'and rename it:': ' și renumește:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'appadmin dezactivat deoarece conexiunea nu e sigură', +'Application': 'Application', +'application "%s" uninstalled': 'aplicația "%s" a fost dezinstalată', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'aplicația a fost compilată', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'aplicația este compilată și nu poate fi editată', +'Application name:': 'Nume aplicație:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'are not used', +'are not used yet': 'are not used yet', +'Are you sure you want to delete file "%s"?': 'Sigur ștergeți fișierul "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Are you sure you want to delete plugin "%s"?', +'Are you sure you want to delete this object?': 'Sigur ștergeți acest obiect?', +'Are you sure you want to uninstall application "%s"': 'Sigur dezinstalați aplicația "%s"', +'Are you sure you want to uninstall application "%s"?': 'Sigur dezinstalați aplicația "%s"?', +'Are you sure?': 'Are you sure?', +'arguments': 'argumente', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATENȚIE: Nu vă puteți conecta decât utilizând o conexiune securizată (HTTPS) sau rulând aplicația pe computerul local.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATENȚIE: Nu puteți efectua mai multe teste o dată deoarece lansarea în execuție a mai multor subpocese nu este sigură.', +'ATTENTION: you cannot edit the running application!': 'ATENȚIE: nu puteți edita o aplicație în curs de execuție!', +'Authentication': 'Autentificare', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available databases and tables': 'Baze de date și tabele disponibile', +'Available Databases and Tables': 'Available Databases and Tables', +'Back': 'Înapoi', +'back': 'înapoi', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'Begin': 'Început', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Buy this book': 'Cumpără această carte', +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Chei cache', +'cache, errors and sessions cleaned': 'cache, erori și sesiuni golite', +'can be a git repo': 'can be a git repo', +'Cancel': 'Cancel', +'Cannot be empty': 'Nu poate fi vid', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Compilare imposibilă: aplicația conține erori. Debogați aplicația și încercați din nou.', +'Cannot compile: there are errors in your app:': 'Cannot compile: there are errors in your app:', +'cannot create file': 'fișier imposibil de creat', +'cannot upload file "%(filename)s"': 'imposibil de încărcat fișierul "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'Schimbă parola de administrare', +'change editor settings': 'change editor settings', +'Change Password': 'Schimbare parolă', +'Change password': 'Schimbare parolă', +'change password': 'schimbare parolă', +'Changelog': 'Changelog', +'check all': 'coșează tot', +'Check for upgrades': 'Verifică dacă există upgrade-uri', +'Check to delete': 'Coșați pentru a șterge', +'Checking for upgrades...': 'Verifică dacă există actualizări...', +'clean': 'golire', +'Clean': 'Curăță', +'Clear': 'Golește', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Click row to expand traceback': 'Clic pe linie pentru a extinde mesajul de trasabilitate', +'Click row to view a ticket': 'Click row to view a ticket', +'click to check for upgrades': 'Clic pentru a verifica dacă există upgrade-uri', +'Client IP': 'IP client', +'code': 'code', +'Code listing': 'Code listing', +'collapse/expand all': 'restrânge/extinde tot', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Community': 'Comunitate', +'Compile': 'Compilează', +'compile': 'compilare', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'aplicația compilată a fost ștearsă', +'Components and Plugins': 'Componente și plugin-uri', +'Condition': 'Condition', +'contains': 'conține', +'continue': 'continue', +'Controller': 'Controlor', +'Controllers': 'Controlori', +'controllers': 'controlori', +'Copyright': 'Drepturi de autor', +'Count': 'Număr', +'Create': 'Crează', +'create file with filename:': 'crează fișier cu numele:', +'Create new application': 'Creați aplicație nouă', +'create new application:': 'crează aplicație nouă:', +'Create/Upload': 'Create/Upload', +'created by': 'creat de', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Cerere curentă', +'Current response': 'Răspuns curent', +'Current session': 'Sesiune curentă', +'currently running': 'acum în funcționare', +'currently saved or': 'în prezent salvat sau', +'customize me!': 'Personalizează-mă!', +'data uploaded': 'date încărcate', +'Database': 'Baza de date', +'database': 'bază de date', +'Database %s select': 'Database %s select', +'database %s select': 'selectare bază de date %s', +'Database administration': 'Database administration', +'database administration': 'administrare bază de date', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Data și ora', +'db': 'db', +'DB Model': 'Model bază de date', +'Debug': 'Debogare', +'defines tables': 'definire tabele', +'Delete': 'Șterge', +'delete': 'șterge', +'delete all checked': 'șterge tot ce e coșat', +'delete plugin': 'delete plugin', +'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)', +'Delete:': 'Șterge:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'Instalare', +'Deploy on Google App Engine': 'Instalare pe Google App Engine', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Deployment Recipes': 'Rețete de instalare', +'Description': 'Descriere', +'Description:': 'Description:', +'design': 'design', +'DESIGN': 'DESIGN', +'Design for': 'Design pentru', +'Detailed traceback description': 'Descriere detaliată a mesajului de trasabilitate', +'details': 'detalii', +'direction: ltr': 'direcție: stânga-sus-dreapta', +'directory not found': 'directory not found', +'Disable': 'Dezactivează', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Chei cache de disc', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'documentație', +'Docs': 'Docs', +'Documentation': 'Documentație', +"Don't know what to do?": 'Nu știți ce să faceți?', +'done!': 'gata!', +'Downgrade': 'Downgrade', +'Download': 'Descărcare', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'descărcare șabloane', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'descărcare plugin-uri', +'Download plugins from repository': 'Download plugins from repository', +'E-mail': 'E-mail', +'E-mail invalid': 'E-mail invalid', +'edit': 'editare', +'EDIT': 'EDITARE', +'Edit': 'Editare', +'edit all': 'edit all', +'Edit application': 'Editare aplicație', +'edit controller': 'editare controlor', +'edit controller:': 'edit controller:', +'Edit current record': 'Editare înregistrare curentă', +'Edit Profile': 'Editare profil', +'edit profile': 'editare profil', +'Edit This App': 'Editați această aplicație', +'edit views:': 'editează vederi:', +'Editing %s': 'Editing %s', +'Editing file': 'Editare fișier', +'Editing file "%s"': 'Editare fișier "%s"', +'Editing Language file': 'Editing Language file', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Email and SMS': 'E-mail și SMS', +'Enable': 'Enable', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'enter a number between %(min)g and %(max)g': 'introduceți un număr între %(min)g și %(max)g', +'enter an integer between %(min)g and %(max)g': 'introduceți un întreg între %(min)g și %(max)g', +'Error': 'Eroare', +'Error logs for "%(app)s"': 'Log erori pentru "%(app)s"', +'Error snapshot': 'Instantaneu eroare', +'Error ticket': 'Tichet eroare', +'errors': 'erori', +'Errors': 'Erori', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Exception instance attributes', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation': 'Extinde abreviația', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'Export': 'Export', +'export as csv file': 'exportă ca fișier csv', +'Exports:': 'Exports:', +'exposes': 'expune', +'exposes:': 'expune:', +'extends': 'extinde', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module': 'reîncarcare modul nereușită', +'failed to reload module because:': 'failed to reload module because:', +'False': 'Neadevărat', +'FAQ': 'Întrebări frecvente', +'File': 'Fișier', +'file "%(filename)s" created': 'fișier "%(filename)s" creat', +'file "%(filename)s" deleted': 'fișier "%(filename)s" șters', +'file "%(filename)s" uploaded': 'fișier "%(filename)s" încărcat', +'file "%(filename)s" was not deleted': 'fișierul "%(filename)s" n-a fost șters', +'file "%s" of %s restored': 'fișier "%s" de %s restaurat', +'file changed on disk': 'fișier modificat pe disc', +'file does not exist': 'fișier inexistent', +'file not found': 'file not found', +'file saved on %(time)s': 'fișier salvat %(time)s', +'file saved on %s': 'fișier salvat pe %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'filtru', +'Find Next': 'Find Next', +'Find Previous': 'Find Previous', +'First name': 'Prenume', +'Forbidden': 'Interzis', +'Form has errors': 'Form has errors', +'Forms and Validators': 'Formulare și validatori', +'Frames': 'Frames', +'Free Applications': 'Aplicații gratuite', +'Functions with no doctests will result in [passed] tests.': 'Funcțiile fără doctests vor genera teste [trecute].', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Get from URL:': 'Obține de la adresa:', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'Go to Matching Pair': 'Mergi la perechea care se potrivește', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Group %(group_id)s created': 'Grup %(group_id)s creat', +'Group ID': 'ID grup', +'Group uniquely assigned to user %(id)s': 'Grup asociat în mod unic utilizatorului %(id)s', +'Groups': 'Grupuri', +'Hello World': 'Salutare lume', +'help': 'ajutor', +'Help': 'Ajutor', +'here': 'here', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Acasă', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'How did you get here?': 'Cum ați ajuns aici?', +'htmledit': 'editare html', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\r\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Dacă raportul de deasupra conține un număr de tichet, asta indică un eșec în executarea controlorului, înainte de orice încercare de a executa doctests-urile. Aceasta se întâmplă de obicei din cauza unei erori de identare sau a unei erori din afara corpului funcției.\r\nUn titlu în verde arată ca toate testele (dacă definite) au fost trecute. În acest caz rezultatele testelor nu sunt arătate.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Import/Export', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'include', +'Indent with tabs': 'Indent with tabs', +'Index': 'Index', +'index': 'index', +'insert new': 'adaugă nou', +'insert new %s': 'adaugă nou %s', +'inspect attributes': 'inspectare atribute', +'Install': 'Instalează', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Aplicații instalate', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'eroare internă', +'internal error: %s': 'internal error: %s', +'Internal State': 'Stare internă', +'Introduction': 'Introducere', +'Invalid action': 'Acțiune invalidă', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid email': 'E-mail invalid', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'parolă invalidă', +'Invalid password': 'Parolă invalidă', +'invalid password.': 'invalid password.', +'Invalid Query': 'Interogare invalidă', +'invalid request': 'cerere invalidă', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'tichet invalid', +'Key': 'Key', +'Key bindings': 'Combinație taste', +'Key bindings for ZenCoding Plugin': 'Key bindings for ZenCoding Plugin', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'fișier de limbă "%(filename)s" creat/actualizat', +'Language files (static strings) updated': 'Fișierele de limbă (șirurile statice de caractere) actualizate', +'languages': 'limbi', +'Languages': 'Limbi', +'languages updated': 'limbi actualizate', +'Last name': 'Nume', +'Last Revision': 'Last Revision', +'Last saved on:': 'Ultima salvare:', +'Layout': 'Șablon', +'Layout Plugins': 'Șablon plugin-uri', +'Layouts': 'Șabloane', +'License for': 'Licență pentru', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Live Chat': 'Chat live', +'Loading...': 'Loading...', +'loading...': 'încarc...', +'Local Apps': 'Local Apps', +'locals': 'localizare', +'Locals##debug': 'Locals##debug', +'located in the file': 'prezentă în fișierul', +'Logged in': 'Logat', +'Logged out': 'Delogat', +'login': 'autentificare', +'Login': 'Autentificare', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Logare interfață de administrare', +'Login/Register': 'Login/Register', +'logout': 'ieșire', +'Logout': 'Ieșire', +'Lost Password': 'Parolă pierdută', +'lost password': 'lost password', +'Lost password?': 'Parolă pierdută?', +'Main Menu': 'Meniu principal', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Match Pair': 'Potrivește pereche', +'Memberships': 'Memberships', +'Menu Model': 'Model meniu', +'merge': 'unește', +'Merge Lines': 'Unește linii', +'Models': 'Modele', +'models': 'modele', +'Modified On': 'Modified On', +'Modules': 'Module', +'modules': 'module', +'Multi User Mode': 'Multi User Mode', +'My Sites': 'Site-urile mele', +'Name': 'Nume', +'New': 'Nou', +'new application "%s" created': 'aplicația nouă "%s" a fost creată', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'New Application Wizard', +'New application wizard': 'Magician aplicație nouă', +'New password': 'Parola nouă', +'new plugin installed': 'new plugin installed', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'Înregistrare nouă', +'new record inserted': 'înregistrare nouă adăugată', +'New simple application': 'O nouă aplicație simplă', +'next': 'next', +'next %s rows': 'next %s rows', +'next 100 rows': 'următoarele 100 de linii', +'Next Edit Point': 'Următorul punct de editare', +'NO': 'NU', +'no changes': 'no changes', +'No databases in this application': 'Aplicație fără bază de date', +'No Interaction yet': 'No Interaction yet', +'no match': 'no match', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'No ticket_storage.txt found under /private folder': 'No ticket_storage.txt found under /private folder', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +'Object or table name': 'Obiect sau nume de tabel', +'Old password': 'Parola veche', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'online designer': 'designer online', +'Online examples': 'Exemple online', +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'Or': 'Sau', +'OR': 'SAU', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'sau importă din fișier csv', +'or provide application url:': 'sau furnizează adresă url:', +'Origin': 'Origine', +'Original/Translation': 'Original/Traducere', +'Other Plugins': 'Alte plugin-uri', +'Other Recipes': 'Alte rețete', +'Overview': 'Prezentare de ansamblu', +'Overwrite installed app': 'Suprascrie aplicație instalată', +'pack all': 'împachetează toate', +'Pack all': 'Împachetează tot', +'Pack compiled': 'Pack compiled', +'pack compiled': 'împachetează ce e compilat', +'Pack custom': 'Pack custom', +'pack plugin': 'pack plugin', +'Password': 'Parola', +'password changed': 'password changed', +"Password fields don't match": 'Câmpurile de parolă nu se potrivesc', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Vizualizare fișier', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Please', +'please input your password again': 'introduceți parola din nou', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" deleted', +'Plugin "%s" in application': 'Plugin "%s" in application', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'plugin-uri', +'Plugins': 'Plugin-uri', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Pus în mișcare de', +'Preface': 'Prefață', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '100 de linii anterioare', +'Previous Edit Point': 'Punct de editare anterior', +'Private files': 'Private files', +'private files': 'private files', +'Profile': 'Profil', +'Project Progress': 'Progres proiect', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'Python': 'Python', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query': 'Interogare', +'Query:': 'Interogare:', +'Quick Examples': 'Exemple rapide', +'RAM': 'RAM', +'RAM Cache Keys': 'Chei cache RAM', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Recipes': 'Rețete', +'Record': 'Record', +'record': 'înregistrare', +'record does not exist': 'înregistrare inexistentă', +'record id': 'id înregistrare', +'Record ID': 'ID înregistrare', +'Record id': 'Record id', +'refresh': 'refresh', +'register': 'înregistrare', +'Register': 'Înregistrare', +'Registration identifier': 'Identificator de autentificare', +'Registration key': 'Cheie înregistrare', +'Registration successful': 'Autentificare reușită', +'Reload routes': 'Reîncarcare rute', +'Remember me (for 30 days)': 'Ține-mă minte (timp de 30 de zile)', +'Remove compiled': 'Remove compiled', +'remove compiled': 'șterge compilate', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Replace', +'Replace All': 'Replace All', +'Repository (%s)': 'Repository (%s)', +'request': 'cerere', +'Request reset password': 'Cerere resetare parolă', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Reset Password key': 'Cheie resetare parolă', +'Resolve Conflict file': 'Rezolvă conflict fișier', +'response': 'răspuns', +'restart': 'restart', +'restore': 'restaurare', +'return': 'return', +'Revert': 'Revert', +'revert': 'revenire', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Rol', +'Roles': 'Roles', +'Rows in Table': 'Rows in Table', +'Rows in table': 'Linii în tabel', +'Rows selected': 'Linii selectate', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'Running on %s', +'Save': 'Salvează', +'save': 'salvare', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save profile': 'Salvează profil', +'Save via Ajax': 'Salvează utilizând Ajax', +'Saved file hash:': 'Hash fișier salvat:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Căutare', +'Select Files to Package': 'Select Files to Package', +'selected': 'selectat', +'Semantic': 'Semantică', +'Services': 'Servicii', +'session': 'sesiune', +'session expired': 'sesiune expirată', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'line de commandă', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'site': 'site', +'Site': 'Site', +'Size of cache:': 'Size of cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': 'anumite fișiere n-au putut fi șterse', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Scuze, dar n-am gasit unde este instalat mercurial', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Începe o nouă aplicație', +'Start searching': 'Start searching', +'Start wizard': 'Startează magician', +'starts with': 'începe cu', +'state': 'stare', +'Static': 'Static', +'static': 'static', +'Static files': 'Fișiere statice', +'Statistics': 'Statistics', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'Stylesheet': 'Foaie de stiluri', +'submit': 'submit', +'Submit': 'Înregistrează', +'successful': 'cu succes', +'Support': 'Suport', +'Sure you want to delete this object?': 'Sigur ștergeți acest obiect?', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': 'tabel', +'Table': 'Table', +'Table name': 'Nume tabel', +'Temporary': 'Temporary', +'test': 'test', +'Testing application': 'Testare aplicație', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"Interogarea (query)" este o condiție de tipul "db.tabel1.câmp1==\'valoare\'". Ceva de genul "db.tabel1.câmp1==db.tabel2.câmp2" generează un JOIN SQL.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'the application logic, each URL path is mapped in one exposed function in the controller': 'logica aplicației, fiecare rută URL este mapată într-o funcție expusă de controlor', +'The application logic, each URL path is mapped in one exposed function in the controller': 'Logica aplicației, fiecare rută URL este mapată într-o funcție expusă de controlor', +'The Core': 'Nucleul', +'the data representation, define database tables and sets': 'reprezentarea datelor, definește tabelele bazei de date și seturile (de date)', +'The data representation, define database tables and sets': 'Reprezentarea datelor, definește tabele și seturi de date', +'The output of the file is a dictionary that was rendered by the view': 'Fișierul produce un dicționar care a fost prelucrat de vederea', +'The presentations layer, views are also known as templates': 'Nivelul de prezentare, vederile sunt cunoscute de asemenea ca șabloane', +'the presentations layer, views are also known as templates': 'nivelul de prezentare, vederile sunt de asemenea numite și șabloane', +'The Views': 'Vederile', +'Theme': 'Theme', +'There are no controllers': 'Nu există controlori', +'There are no models': 'Nu există modele', +'There are no modules': 'Nu există module', +'There are no plugins': 'Nu există plugin-uri', +'There are no private files': 'There are no private files', +'There are no static files': 'Nu există fișiere statice', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'Nu există traduceri, doar limba implicită este suportată', +'There are no views': 'Nu există vederi', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'Aceste fișiere sunt servite fără procesare, fișierele imagine se pun aici', +'these files are served without processing, your images go here': 'aceste fișiere sunt servite fără procesare, imaginea se plasează acolo', +'This App': 'Această aplicație', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is a copy of the scaffolding application': 'Aceasta este o copie a aplicației schelet', +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': 'Aceasta este șablonul fișierului %(filename)s', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Tichet', +'Ticket ID': 'ID tichet', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'Moment în timp (timestamp)', +'to previous version.': 'la versiunea anterioară.', +'To create a plugin, name a file/folder plugin_[name]': 'Pentru a crea un plugin, numește un fișier/director plugin_[nume]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'comutare breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'too short': 'prea scurt', +'Traceback': 'Trasabilitate', +'translation strings for the application': 'șiruri de caractere folosite la traducerea aplicației', +'Translation strings for the application': 'Șiruri de traducere pentru aplicație', +'True': 'Adevărat', +'try': 'încearcă', +'try something like': 'încearcă ceva de genul', +'Try the mobile interface': 'Try the mobile interface', +'try view': 'try view', +'Twitter': 'Twitter', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Imposibil de verificat dacă există actualizări', +'unable to create application "%s"': 'imposibil de creat aplicația "%s"', +'unable to delete file "%(filename)s"': 'imposibil de șters fișierul "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'unable to delete file plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download': 'Imposibil de descărcat', +'Unable to download app': 'Imposibil de descărcat aplicația', +'Unable to download app because:': 'Unable to download app because:', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'imposibil de analizat fișierul csv', +'unable to uninstall "%s"': 'imposibil de dezinstalat "%s"', +'unable to upgrade because "%s"': 'unable to upgrade because "%s"', +'uncheck all': 'decoșează tot', +'uninstall': 'dezinstalează', +'Uninstall': 'Dezinstalează', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'actualizează', +'update all languages': 'actualizează toate limbile', +'Update:': 'Actualizare:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'upgrade now to %s', +'upload': 'încarcă', +'Upload': 'Upload', +'Upload a package:': 'Încarcă un pachet:', +'Upload and install packed application': 'Încarcă și instalează aplicație împachetată', +'upload application:': 'incarcă aplicația:', +'Upload existing application': 'Încarcă aplicația existentă', +'upload file:': 'încărcă fișier:', +'upload plugin file:': 'încarcă fișier plugin:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Folosiți (...)&(...) pentru ȘI, (...)|(...) pentru SAU, și ~(...) pentru NEGARE, pentru a crea interogări complexe.', +'user': 'utilizator', +'User': 'User', +'User %(id)s Logged-in': 'Utilizator %(id)s autentificat', +'User %(id)s Logged-out': 'Utilizator %(id)s delogat', +'User %(id)s Password changed': 'Parola utilizatorului %(id)s a fost schimbată', +'User %(id)s Password reset': 'Resetare parola utilizator %(id)s', +'User %(id)s Profile updated': 'Profil utilizator %(id)s actualizat', +'User %(id)s Registered': 'Utilizator %(id)s înregistrat', +'User ID': 'ID utilizator', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'value already in database or empty': 'Valoare existentă în baza de date sau vidă', +'variables': 'variables', +'Verify Password': 'Verifică parola', +'VERSION': 'VERSIUNE', +'Version': 'Version', +'Version %s.%s.%s (%s) %s': 'Versiune %s.%s.%s (%s) %s', +'Versioning': 'Versiuni', +'versioning': 'versiuni', +'Videos': 'Video-uri', +'View': 'Vedere', +'view': 'vedere', +'Views': 'Vederi', +'views': 'vederi', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Framework web', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py este la zi', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'Ultimele tweet-uri web2py', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py upgraded; please restart it', +'Welcome': 'Bine ați venit', +'Welcome %s': 'Bine ați venit %s', +'Welcome to web2py': 'Bun venit la web2py', +'Welcome to web2py!': 'Bun venit la web2py!', +'Which called the function': 'Care a apelat funcția', +'Working...': 'Working...', +'Wrap with Abbreviation': 'Încadrează cu abreviația', +'WSGI reference name': 'WSGI reference name', +'YES': 'DA', +'Yes': 'Yes', +'You are successfully running web2py': 'Rulați cu succes web2py', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You can modify this application and adapt it to your needs': 'Puteți modifica și adapta aplicația nevoilor dvs.', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'You visited the url': 'Ați vizitat adresa', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/ru.py b/web2py/applications/admin/languages/ru.py new file mode 100644 index 0000000..88f9d70 --- /dev/null +++ b/web2py/applications/admin/languages/ru.py @@ -0,0 +1,708 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'ru', +'!langname!': 'Русский', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Update" ist ein optionaler Ausdruck wie "Feld1 = \'newvalue". JOIN Ergebnisse können nicht aktualisiert oder gelöscht werden', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s %%{строкa} %%{удаленa}', +'%s %%{row} updated': '%s %%{строкa} %%{обновленa}', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(requires internet access)': '(требует подключения к интернету)', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(наподобие "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01Searching: **%s** %%{file}': 'Найдено: **%s** %%{файл}', +'A new version of web2py is available': 'Доступна новая версия web2py', +'A new version of web2py is available: %s': 'Доступна новая версия web2py: %s', +'Abort': 'Отмена', +'About': 'О', +'About application': 'О приложении', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Add breakpoint', +'additional code for your application': 'добавочный код для вашего приложения', +'Additional code for your application': 'Допольнительный код для вашего приложения', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'админка отключена, потому что отсутствует пароль администратора', +'admin disabled because not supported on google app engine': 'admin disabled because not supported on google app engine', +'admin disabled because not supported on google apps engine': 'админка отключена, т.к. не поддерживается на google app engine', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'админка отключена, т.к. невозможно получить доступ к файлу с паролями ', +'Admin is disabled because insecure channel': 'Админпанель выключена из-за небезопасного соединения', +'Admin is disabled because unsecure channel': 'Админпанель выключен из-за небезопасного соединения', +'Admin language': 'Язык админпанели', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'интерфейс администратора', +'Administrator Password:': 'Пароль администратора:', +'and rename it (required):': 'и переименуйте его (необходимо):', +'and rename it:': ' и переименуйте его:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'Appadmin отключен, т.к. соединение не безопасно', +'Application': 'Application', +'application "%s" uninstalled': 'Приложение "%s" удалено', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'Приложение скомпилировано', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'Приложение скомпилировано и дизайн не может быть изменен', +'Application name:': 'Название приложения:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'are not used', +'are not used yet': 'are not used yet', +'Are you sure you want to delete file "%s"?': 'Вы действительно хотите удалить файл "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Are you sure you want to delete plugin "%s"?', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Are you sure you want to uninstall application "%s"': 'Вы действительно хотите удалить приложение "%s"', +'Are you sure you want to uninstall application "%s"?': 'Вы действительно хотите удалить приложение "%s"?', +'Are you sure you want to upgrade web2py now?': 'Вы действительно хотите обновить web2py сейчас?', +'Are you sure?': 'Are you sure?', +'arguments': 'аргументы', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ВНИМАНИЕ: Для входа требуется бесопасное (HTTPS) соединение либо запуск на localhost.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ВНИМАНИЕ: Тестирование не потокобезопасно, поэтому не запускайте несколько тестов параллельно.', +'ATTENTION: This is an experimental feature and it needs more testing.': 'ВНИМАНИЕ: Это экспериментальная возможность и требует тестирования.', +'ATTENTION: you cannot edit the running application!': 'ВНИМАНИЕ: Вы не можете редактировать работающее приложение!', +'Authentication': 'Аутентификация', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available databases and tables': 'Доступные базы данных и таблицы', +'Available Databases and Tables': 'Available Databases and Tables', +'back': 'назад', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'beautify': 'Раскрасить', +'Begin': 'Begin', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': 'кэш', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'Кэш, ошибки и сессии очищены', +'call': 'вызов', +'can be a git repo': 'can be a git repo', +'Cancel': 'Cancel', +'Cannot be empty': 'Не может быть пустым', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Невозможно компилировать: в приложении присутствуют ошибки. Отладьте его, исправьте ошибки и попробуйте заново.', +'Cannot compile: there are errors in your app:': 'Cannot compile: there are errors in your app:', +'cannot create file': 'Невозможно создать файл', +'cannot upload file "%(filename)s"': 'Невозможно загрузить файл "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'Изменить пароль администратора', +'change editor settings': 'change editor settings', +'Change Password': 'Изменить пароль', +'change password': 'изменить пароль', +'Changelog': 'Changelog', +'check all': 'проверить все', +'Check for upgrades': 'проверить обновления', +'Check to delete': 'Поставьте для удаления', +'Checking for upgrades...': 'Проверка обновлений...', +'Clean': 'Очистить', +'Clear': 'Clear', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'click here for online examples': 'нажмите здесь для онлайн примеров', +'click here for the administrative interface': 'нажмите здесь для интерфейса администратора', +'Click row to expand traceback': 'Click row to expand traceback', +'Click row to view a ticket': 'Click row to view a ticket', +'click to check for upgrades': 'нажмите для проверки обновления', +'Client IP': 'IP клиента', +'code': 'код', +'Code listing': 'Code listing', +'collapse/expand all': 'свернуть/развернуть все', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'Компилировать', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'скомпилированное приложение удалено', +'Condition': 'Condition', +'continue': 'continue', +'Controller': 'Контроллер', +'Controllers': 'Контроллеры', +'controllers': 'контроллеры', +'Copyright': 'Copyright', +'Count': 'Count', +'Create': 'Создать', +'create file with filename:': 'Создать файл с названием:', +'create new application:': 'создать новое приложение:', +'Create new simple application': 'Создать новое простое приложение', +'Create/Upload': 'Create/Upload', +'created by': 'создано', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Текущий запрос', +'Current response': 'Текущий ответ', +'Current session': 'Текущая сессия', +'currently running': 'сейчас работает', +'currently saved or': 'сейчас сохранено или', +'customize me!': 'настрой меня!', +'data uploaded': 'дата загрузки', +'Database': 'База данных', +'database': 'база данных', +'Database %s select': 'Database %s select', +'database %s select': 'Выбор базы данных %s ', +'Database administration': 'Database administration', +'database administration': 'администрирование базы данных', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Дата и время', +'db': 'бд', +'DB Model': 'Модель БД', +'Debug': 'Debug', +'defines tables': 'определить таблицы', +'Delete': 'Удалить', +'delete': 'удалить', +'delete all checked': 'удалить выбранные', +'delete plugin': 'удалить плагин', +'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)', +'Delete:': 'Удалить:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'Развернуть', +'Deploy on Google App Engine': 'Развернуть на Google App Engine', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description': 'Описание', +'Description:': 'Description:', +'design': 'дизайн', +'DESIGN': 'ДИЗАЙН', +'Design for': 'Дизайн для', +'Detailed traceback description': 'Detailed traceback description', +'details': 'details', +'direction: ltr': 'направление: ltr', +'directory not found': 'directory not found', +'Disable': 'Disable', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'docs', +'Docs': 'Docs', +'documentation': 'документация', +'done!': 'выполнено!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'загрузить шаблоны', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'загрузить плагины', +'Download plugins from repository': 'Download plugins from repository', +'E-mail': 'E-mail', +'EDIT': 'ПРАВКА', +'Edit': 'Правка', +'edit all': 'edit all', +'Edit application': 'Правка приложения', +'edit controller': 'правка контроллера', +'edit controller:': 'edit controller:', +'Edit current record': 'Правка текущей записи', +'Edit Profile': 'Правка профиля', +'edit profile': 'правка профиля', +'Edit This App': 'Правка данного приложения', +'edit views:': 'правка видов:', +'Editing %s': 'Editing %s', +'Editing file': 'Правка файла', +'Editing file "%s"': 'Правка файла "%s"', +'Editing Language file': 'Правка языкового файла', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Enable', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Enterprise Web Framework': 'Enterprise Web Framework', +'Error': 'Error', +'Error logs for "%(app)s"': 'Журнал ошибок для "%(app)s"', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Error ticket', +'Errors': 'Ошибка', +'escape': 'escape', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Атрибуты объекта исключения', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation': 'Раскрыть аббревиатуру', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'Экспорт в CSV', +'Exports:': 'Exports:', +'exposes': 'открывает', +'exposes:': 'exposes:', +'extends': 'расширяет', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module': 'невозможно загрузить модуль', +'failed to reload module because:': 'failed to reload module because:', +'File': 'File', +'file "%(filename)s" created': 'файл "%(filename)s" создан', +'file "%(filename)s" deleted': 'файл "%(filename)s" удален', +'file "%(filename)s" uploaded': 'файл "%(filename)s" загружен', +'file "%(filename)s" was not deleted': 'файл "%(filename)s" не был удален', +'file "%s" of %s restored': 'файл "%s" из %s восстановлен', +'file changed on disk': 'файл изменился на диске', +'file does not exist': 'файл не существует', +'file not found': 'file not found', +'file saved on %(time)s': 'файл сохранен %(time)s', +'file saved on %s': 'файл сохранен %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'фильтр', +'Find Next': 'Find Next', +'Find Previous': 'Find Previous', +'First name': 'Имя', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': 'Функции без doctest будут давать [прошел] в тестах.', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Get from URL:': 'Get from URL:', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'Go to Matching Pair': 'К подходящей паре', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Group ID': 'ID группы', +'Hello World': 'Привет, Мир', +'Help': 'Помощь', +'here': 'here', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'htmledit': 'htmledit', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Если отчет выше содержит номер ошибки, это указывает на ошибку при работе контроллера, до попытки выполнить doctest. Причиной чаще является неверные отступы или ошибки в коде вне функции. \nЗеленый заголовок указывает на успешное выполнение всех тестов. В этом случае результаты тестов не показываются.', +'If you answer "yes", be patient, it may take a while to download': 'Если вы ответили "Да", потерпите, загрузка может потребовать времени', +'If you answer yes, be patient, it may take a while to download': 'Если вы ответили "Да", потерпите, загрузка может потребовать времени', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Импорт/Экспорт', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'включает', +'Indent with tabs': 'Indent with tabs', +'Index': 'Индекс', +'index': 'index', +'insert new': 'вставить новый', +'insert new %s': 'вставить новый %s', +'inspect attributes': 'inspect attributes', +'Install': 'Установить', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Установленные приложения', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'внутренняя ошибка', +'internal error: %s': 'internal error: %s', +'Internal State': 'Внутренний статус', +'Invalid action': 'Неверное действие', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid email': 'Неверный email', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'неверный пароль', +'invalid password.': 'invalid password.', +'Invalid Query': 'Неверный запрос', +'invalid request': 'неверный запрос', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'неверный тикет', +'Key': 'Key', +'Key bindings': 'Комбинации клавиш', +'Key bindings for ZenConding Plugin': 'Комбинации клавиш для плагина ZenConding', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'Языковой файл "%(filename)s" создан/обновлен', +'Language files (static strings) updated': 'Языковые файлы (статичные строки) обновлены', +'languages': 'языки', +'Languages': 'Языки', +'languages updated': 'языки обновлены', +'Last name': 'Фамилия', +'Last Revision': 'Last Revision', +'Last saved on:': 'Последнее сохранение:', +'Layout': 'Верстка', +'License for': 'Лицензия для', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Loading...': 'Loading...', +'loading...': 'загрузка...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'located in the file': 'расположенный в файле', +'login': 'логин', +'Login': 'Логин', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Вход в интерфейс администратора', +'Login/Register': 'Login/Register', +'Logout': 'выход', +'Lost Password': 'Забыли пароль', +'lost password': 'lost password', +'lost password?': 'Пароль утерян?', +'Main Menu': 'Главное меню', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Match Pair': 'Найти пару', +'Memberships': 'Memberships', +'Menu Model': 'Модель меню', +'merge': 'объединить', +'Merge Lines': 'Объединить линии', +'Models': 'Модели', +'models': 'модели', +'Modified On': 'Modified On', +'Modules': 'Модули', +'modules': 'модули', +'Multi User Mode': 'Multi User Mode', +'Name': 'Название', +'new application "%s" created': 'новое приложение "%s" создано', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'New Application Wizard', +'New application wizard': 'Мастер нового приложения', +'new plugin installed': 'new plugin installed', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'Новая запись', +'new record inserted': 'новая запись вставлена', +'New simple application': 'Новое простое приложение', +'next': 'next', +'next %s rows': 'next %s rows', +'next 100 rows': 'следующие 100 строк', +'Next Edit Point': 'Следующее место правки', +'NO': 'НЕТ', +'no changes': 'no changes', +'No databases in this application': 'В приложении нет базы данных', +'No Interaction yet': 'No Interaction yet', +'no match': 'no match', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'или испорт из cvs файла', +'or provide app url:': 'или URL приложения:', +'or provide application url:': 'или URL приложения:', +'Origin': 'Оригинал', +'Original/Translation': 'Оригинал/Перевод', +'Overview': 'Overview', +'Overwrite installed app': 'Переписать на установленное приложение', +'Pack all': 'упаковать все', +'Pack compiled': 'Архив скомпилирован', +'Pack custom': 'Pack custom', +'pack plugin': 'Упаковать плагин', +'Password': 'Пароль', +'password changed': 'password changed', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Просмотр', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Please', +'please wait!': 'подождите, пожалуйста!', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" deleted', +'Plugin "%s" in application': 'Плагин "%s" в приложении', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'плагины', +'Plugins': 'Плагины', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Обеспечен', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'предыдущие 100 строк', +'Previous Edit Point': 'Предыдущее место правки', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Project Progress', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Запрос:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Record': 'Record', +'record': 'запись', +'record does not exist': 'запись не существует', +'record id': 'id записи', +'Record ID': 'ID записи', +'Record id': 'Record id', +'refresh': 'refresh', +'Register': 'Зарегистрироваться', +'register': 'зарегистрироваться', +'Registration key': 'Ключ регистрации', +'Reload routes': 'Reload routes', +'Remove compiled': 'Удалить скомпилированное', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Replace', +'Replace All': 'Replace All', +'Repository (%s)': 'Repository (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Reset Password key': 'Сброс пароля', +'Resolve Conflict file': 'Решить конфликт в файле', +'response': 'response', +'restart': 'restart', +'restore': 'восстановить', +'return': 'return', +'Revert': 'Revert', +'revert': 'откатиться', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Роль', +'Roles': 'Roles', +'Rows in table': 'Строк в таблице', +'Rows in Table': 'Rows in Table', +'Rows selected': 'Выбрано строк', +'rules are not defined': 'rules are not defined', +'rules:': 'rules:', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'Running on %s', +'Save': 'Save', +'save': 'сохранить', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Сохранить через Ajax', +'Saved file hash:': 'Хэш сохраненного файла:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'selected': 'выбрано', +'session': 'session', +'session expired': 'сессия истекла', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'shell', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'сайт', +'Size of cache:': 'Size of cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': 'некоторые файлы нельзя удалить', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Start a new app', +'Start searching': 'Start searching', +'Start wizard': 'запустить мастер', +'state': 'статус', +'Static': 'Static', +'static': 'статичные файлы', +'Static files': 'Статические файлы', +'Statistics': 'Statistics', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'Stylesheet': 'Таблицы стилей', +'submit': 'Отправить', +'Submit': 'Submit', +'successful': 'successful', +'Sure you want to delete this object?': 'Действительно хотите удалить данный объект?', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': 'таблица', +'Table': 'Table', +'Table name': 'Название таблицы', +'Temporary': 'Temporary', +'test': 'тест', +'test_def': 'test_def', +'test_for': 'test_for', +'test_if': 'test_if', +'test_try': 'test_try', +'Testing application': 'Тест приложения', +'Testing controller': 'Тест контроллера', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"query" является условием вида "db.table1.field1 == \'значение\'". Что-либо типа "db.table1.field1 db.table2.field2 ==" ведет к SQL JOIN.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'the application logic, each URL path is mapped in one exposed function in the controller': 'Логика приложения, каждый URL отображается в открытую функцию в контроллере', +'The application logic, each URL path is mapped in one exposed function in the controller': 'Логика приложения, каждый URL отображается к одной функции в контроллере', +'the data representation, define database tables and sets': 'представление данных, определить таблицы и наборы', +'The data representation, define database tables and sets': 'Представление данных, определите таблицы базы данных и наборы', +'The output of the file is a dictionary that was rendered by the view': 'Выводом файла является словарь, который создан в виде', +'The presentations layer, views are also known as templates': 'Слой презентации, виды так же известны, как шаблоны', +'the presentations layer, views are also known as templates': 'слой представления, виды известные так же как шаблоны', +'Theme': 'Theme', +'There are no controllers': 'Отсутствуют контроллеры', +'There are no models': 'Отсутствуют модели', +'There are no modules': 'Отсутствуют модули', +'There are no plugins': 'Отсутствуют плагины', +'There are no private files': 'There are no private files', +'There are no static files': 'Отсутствуют статичные файлы', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'Отсутствуют переводчики, поддерживается только стандартный язык', +'There are no views': 'Отсутствуют виды', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'Эти файлы обслуживаются без обработки, ваши изображения попадут сюда', +'these files are served without processing, your images go here': 'Эти файлы обслуживаются без обработки, ваши изображения попадут сюда', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is a copy of the scaffolding application': 'Это копия сгенерированного приложения', +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': 'Это шаблон %(filename)s', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Тикет', +'Ticket ID': 'Ticket ID', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'Время', +'TM': 'TM', +'to previous version.': 'на предыдущую версию.', +'To create a plugin, name a file/folder plugin_[name]': 'Для создания плагина назовите файл/папку plugin_[название]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'translation strings for the application': 'строки перевода для приложения', +'Translation strings for the application': 'Строки перевода для приложения', +'try': 'try', +'try something like': 'попробовать что-либо вида', +'Try the mobile interface': 'Try the mobile interface', +'try view': 'try view', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Невозможно проверить обновления', +'unable to create application "%s"': 'невозможно создать приложение "%s" nicht möglich', +'unable to delete file "%(filename)s"': 'невозможно удалить файл "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'unable to delete file plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download': 'Невозможно загрузить', +'Unable to download app': 'Невозможно загрузить', +'Unable to download app because:': 'Unable to download app because:', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'невозможно разобрать файл csv', +'unable to uninstall "%s"': 'невозможно удалить "%s"', +'unable to upgrade because "%s"': 'unable to upgrade because "%s"', +'uncheck all': 'снять выбор всего', +'Uninstall': 'Удалить', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'обновить', +'update all languages': 'обновить все языки', +'Update:': 'Обновить:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'upgrade now to %s', +'upgrade web2py now': 'обновить web2py сейчас', +'upload': 'загрузить', +'Upload': 'Upload', +'Upload & install packed application': 'Загрузить и установить приложение в архиве', +'Upload a package:': 'Загрузить пакет:', +'Upload and install packed application': 'Upload and install packed application', +'upload application:': 'загрузить файл:', +'Upload existing application': 'Загрузить существующее приложение', +'upload file:': 'загрузить файл:', +'upload plugin file:': 'загрузить файл плагина:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Используйте (...)&(...) для AND, (...)|(...) для OR, и ~(...) для NOT при создании сложных запросов.', +'Use an url:': 'Используйте url:', +'user': 'пользователь', +'User': 'User', +'User ID': 'ID пользователя', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'переменные', +'Version': 'Версия', +'Versioning': 'Versioning', +'versioning': 'версии', +'View': 'Вид', +'view': 'вид', +'Views': 'Виды', +'views': 'виды', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py обновлен', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'последние твиты по web2py', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py upgraded; please restart it', +'Welcome %s': 'Добро пожаловать, %s', +'Welcome to web2py': 'Добро пожаловать в web2py', +'Which called the function': 'Который вызвал функцию', +'Working...': 'Working...', +'Wrap with Abbreviation': 'Заключить в аббревиатуру', +'WSGI reference name': 'WSGI reference name', +'xml': 'xml', +'YES': 'ДА', +'Yes': 'Yes', +'You are successfully running web2py': 'Вы успешно запустили web2by', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You can modify this application and adapt it to your needs': 'Вы можете изменить это приложение и подогнать под свои нужды', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'You visited the url': 'Вы посетили URL', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/sl.py b/web2py/applications/admin/languages/sl.py new file mode 100644 index 0000000..c6767b9 --- /dev/null +++ b/web2py/applications/admin/languages/sl.py @@ -0,0 +1,707 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'sl', +'!langname!': 'Slovenski', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Popravi" je izbirni izraz kot npr.: "stolpec1 = \'novavrednost\'". Rezultatov JOIN operacije ne morete popravljati ali brisati', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s vrstic izbrisanih', +'%s %%{row} updated': '%s vrstic popravljeno', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(requires internet access)': '(zahteva internetni dostop)', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(nekaj kot "sl-SI" ali samo "sl")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01Searching: **%s** %%{file}': 'Iskanje: **%s** datoteke', +'A new version of web2py is available': 'Nova različica web2py je na voljo', +'A new version of web2py is available: %s': 'Nova različica web2py je na voljo: %s', +'Abort': 'Preklic', +'About': 'Vizitka', +'About application': 'O aplikaciji', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Add breakpoint', +'additional code for your application': 'dodatna koda za vašo aplikacijo', +'Additional code for your application': 'Dodatna koda za vašo aplikacijo', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'skrbnik izključen, ker ni skrbniškega gesla', +'admin disabled because not supported on google app engine': 'admin disabled because not supported on google app engine', +'admin disabled because not supported on google apps engine': 'skrbnik izključen, ker ni podprt na Google App sistemu', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'skrbnik izključen, ker ne morem dostopati do datoteke z gesli', +'Admin is disabled because insecure channel': 'Skrbnik je izključen zaradi nezavarovane povezave', +'Admin is disabled because unsecure channel': 'Skrbnik je izključen zaradi nezavarovane povezave', +'Admin language': 'Skrbniški jezik', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'skrbniški vmesnik', +'Administrator Password:': 'Skrbniško geslo:', +'and rename it (required):': 'in jo preimenujte (obvezno):', +'and rename it:': ' in jo preimenujte:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'Appadmin izključen, ker zahteva varno (HTTPS) povezavo', +'Application': 'Application', +'application "%s" uninstalled': 'Aplikacija "%s" odstranjena', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'aplikacija prevedena', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'aplikacija je prevedena in je ne morete popravljati', +'Application name:': 'Ime aplikacije:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'are not used', +'are not used yet': 'are not used yet', +'Are you sure you want to delete file "%s"?': 'Ali res želite pobrisati datoteko "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Are you sure you want to delete plugin "%s"?', +'Are you sure you want to delete this object?': 'Ali res želite izbrisati ta predmet?', +'Are you sure you want to uninstall application "%s"': 'Ali res želite odstraniti program "%s"', +'Are you sure you want to uninstall application "%s"?': 'Ali res želite odstraniti program "%s"?', +'Are you sure you want to upgrade web2py now?': 'Ali želite sedaj nadgraditi web2py?', +'Are you sure?': 'Are you sure?', +'arguments': 'argumenti', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'POZOR: Prijava zahteva varno povezavo (HTTPS) ali lokalni (localhost) dostop.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'POZOR: Testiranje ni večopravilno, zato ne poganjajte več testov hkrati.', +'ATTENTION: This is an experimental feature and it needs more testing.': 'POZOR: To je preizkusni fazi in potrebuje več testiranja.', +'ATTENTION: you cannot edit the running application!': 'POZOR: Ne morete urejati aplikacije, ki že teče!', +'Authentication': 'Avtentikacija', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available databases and tables': 'Podatkovne baze in tabele', +'Available Databases and Tables': 'Available Databases and Tables', +'back': 'nazaj', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'beautify': 'olepšaj', +'Begin': 'Začni', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': 'predpomnilnik', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'Predpomnilnik, napake in seja so očiščeni', +'call': 'kliči', +'can be a git repo': 'can be a git repo', +'Cancel': 'Cancel', +'Cannot be empty': 'Ne sme biti prazno', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Nemogoče prevajanje: napake v programu. Odpravite napake in poskusite ponovno.', +'Cannot compile: there are errors in your app:': 'Cannot compile: there are errors in your app:', +'cannot create file': 'ne morem ustvariti datoteke', +'cannot upload file "%(filename)s"': 'ne morem naložiti datoteke "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'Spremenite skrbniško geslo', +'change editor settings': 'change editor settings', +'Change Password': 'Spremeni geslo', +'change password': 'spremeni geslo', +'Changelog': 'Changelog', +'check all': 'označi vse', +'Check for upgrades': 'Preveri za posodobitve', +'Check to delete': 'Odkljukajte, če želite izbrisati', +'Checking for upgrades...': 'Preverjam posodobitve...', +'Clean': 'Počisti', +'Clear': 'Clear', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'click here for online examples': 'kliknite za spletne primere', +'click here for the administrative interface': 'kliknite za skrbniški vmesnik', +'Click row to expand traceback': 'Kliknite vrstico da razširite sledenje', +'Click row to view a ticket': 'Kliknite vrstico za ogled listka', +'click to check for upgrades': 'kliknite za preverjanje nadgradenj', +'Client IP': 'IP klienta', +'code': 'koda', +'Code listing': 'Code listing', +'collapse/expand all': 'zapri/odpri vse', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'Prevedi', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'prevedena aplikacija je odstranjena', +'Condition': 'Condition', +'continue': 'continue', +'Controller': 'Krmilnik', +'Controllers': 'Krmilniki', +'controllers': 'krmilniki', +'Copyright': 'Copyright', +'Count': 'Število', +'Create': 'Ustvari', +'create file with filename:': 'Ustvari datoteko z imenom:', +'create new application:': 'Ustvari novo aplikacijo:', +'Create new simple application': 'Ustvari novo enostavno aplikacijo', +'Create/Upload': 'Create/Upload', +'created by': 'ustvaril', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Trenutna zahteva', +'Current response': 'Trenutni odgovor', +'Current session': 'Trenutna seja', +'currently running': 'trenutno teče', +'currently saved or': 'trenutno shranjeno ali', +'customize me!': 'Spremeni me!', +'data uploaded': 'podatki naloženi', +'Database': 'Podatkovna baza', +'database': 'podatkovna baza', +'Database %s select': 'Database %s select', +'database %s select': 'izberi podatkovno bazo %s ', +'Database administration': 'Database administration', +'database administration': 'upravljanje s podatkovno bazo', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Datum in čas', +'db': 'db', +'DB Model': 'Podatkovni model', +'Debug': 'Debug', +'defines tables': 'definiraj tabele', +'Delete': 'Izbriši', +'delete': 'izbriši', +'delete all checked': 'izbriši vse označene', +'delete plugin': 'izbriši vtičnik', +'Delete this file (you will be asked to confirm deletion)': 'Izbriši to datoteko (izbris boste morali potrditi)', +'Delete:': 'Izbriši:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'Namesti', +'Deploy on Google App Engine': 'Prenesi na Google App sistem', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description': 'Opis', +'Description:': 'Description:', +'design': 'oblikuj', +'DESIGN': 'Izgled', +'Design for': 'Oblikuj za', +'Detailed traceback description': 'Natačen opis sledenja', +'details': 'podrobnosti', +'direction: ltr': 'smer: ltr', +'directory not found': 'directory not found', +'Disable': 'Izključi', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'docs', +'Docs': 'Docs', +'documentation': 'dokumentacija', +'done!': 'Narejeno!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'prenesi postavitev', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'prenesi vtičnik', +'Download plugins from repository': 'Download plugins from repository', +'E-mail': 'E-mail', +'EDIT': 'UREDI', +'Edit': 'Uredi', +'edit all': 'edit all', +'Edit application': 'Uredi program', +'edit controller': 'uredi krmilnik', +'edit controller:': 'edit controller:', +'Edit current record': 'Uredi trenutni zapis', +'Edit Profile': 'Uredi profil', +'edit profile': 'uredi profil', +'Edit This App': 'Uredi ta program', +'edit views:': 'urejaj poglede:', +'Editing %s': 'Editing %s', +'Editing file': 'Urejanje datoteke', +'Editing file "%s"': 'Urejanje datoteke "%s"', +'Editing Language file': 'Uredi jezikovno datoteko', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Enable', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Enterprise Web Framework': 'Enterprise Web Framework', +'Error': 'Napaka', +'Error logs for "%(app)s"': 'Dnevnik napak za "%(app)s"', +'Error snapshot': 'Posnetek napake', +'Error ticket': 'Listek napake', +'Errors': 'Napake', +'escape': 'escape', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Lastnosti instance izjeme', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation': 'Razširi okrajšave', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'izvozi kot CSV', +'Exports:': 'Exports:', +'exposes': 'objavlja', +'exposes:': 'exposes:', +'extends': 'razširja', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module': 'nisem uspel ponovno naložiti modula', +'failed to reload module because:': 'failed to reload module because:', +'File': 'Datoteka', +'file "%(filename)s" created': 'datoteka "%(filename)s" ustvarjena', +'file "%(filename)s" deleted': 'datoteka "%(filename)s" izbrisana', +'file "%(filename)s" uploaded': 'datoteka "%(filename)s" prenešena', +'file "%(filename)s" was not deleted': 'datoteka "%(filename)s" ni bila izbrisana', +'file "%s" of %s restored': 'datoteka "%s" od %s obnovljena', +'file changed on disk': 'datoteka je bila spremenjena', +'file does not exist': 'datoteka ne obstaja', +'file not found': 'file not found', +'file saved on %(time)s': 'datoteka shranjena %(time)s', +'file saved on %s': 'datoteka shranjena %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'fiter', +'Find Next': 'Find Next', +'Find Previous': 'Find Previous', +'First name': 'Ime', +'Form has errors': 'Form has errors', +'Frames': 'Okvirji', +'Functions with no doctests will result in [passed] tests.': 'Funkcije brez doctest bodo opravile teste brez preverjanja.', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Get from URL:': 'Naloži iz URL:', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'Go to Matching Pair': 'Pojdi k ujemalnemu paru', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Group ID': 'ID skupine', +'Hello World': 'Pozdravljen, Svet!', +'Help': 'Pomoč', +'here': 'here', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'htmledit': 'htmledit', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Če poročilo zgoraj vsebuje številko listka to pomeni napako pri izvajanju krmilnika, še preden so se izvedli doctesti. To ponavadi pomeni napako pri zamiku programske vrstice ali izven funkcije.\nZelen naslov označuje, da so vsi testi opravljeni. V tem primeru testi niso prikazani.', +'If you answer "yes", be patient, it may take a while to download': 'Če odgovorite z "DA", potrpite. Prenos traja nekaj časa', +'If you answer yes, be patient, it may take a while to download': 'Če odgovorite z "DA", potrpite. Prenos traja nekaj časa', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Uvoz/Izvoz', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'vključuje', +'Indent with tabs': 'Indent with tabs', +'Index': 'Indeks', +'index': 'indeks', +'insert new': 'vstavi nov', +'insert new %s': 'vstavi nov %s', +'inspect attributes': 'pregled lastnosti', +'Install': 'Namesti', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Nameščene aplikacije', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'notranja napaka', +'internal error: %s': 'internal error: %s', +'Internal State': 'Notranje stanje', +'Invalid action': 'Napačno dejanje', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid email': 'Napačen e-naslov', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'napačno geslo', +'invalid password.': 'invalid password.', +'Invalid Query': 'Napačno povpraševanje', +'invalid request': 'napačna zahteva', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'napačen kartonček', +'Key': 'Key', +'Key bindings': 'Povezave tipk', +'Key bindings for ZenConding Plugin': 'Povezave tipk za ZenConding vtičnik', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'jezikovna datoteka "%(filename)s" ustvarjena/posodobljena', +'Language files (static strings) updated': 'Jezikovna datoteka (statično besedilo) posodobljeno', +'languages': 'jeziki', +'Languages': 'Jeziki', +'languages updated': 'jeziki posodobljeni', +'Last name': 'Priimek', +'Last Revision': 'Last Revision', +'Last saved on:': 'Zadnjič shranjeno:', +'Layout': 'Postavitev', +'License for': 'Licenca za', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Loading...': 'Loading...', +'loading...': 'nalaganje...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'located in the file': 'se nahaja v datoteki', +'login': 'prijava', +'Login': 'Prijava', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Prijava v skrbniški vmesnik', +'Login/Register': 'Login/Register', +'Logout': 'Odjava', +'Lost Password': 'Izgubljeno geslo', +'lost password': 'lost password', +'lost password?': 'Izgubljeno geslo?', +'Main Menu': 'Glavni meni', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Match Pair': 'Ujemalni par', +'Memberships': 'Memberships', +'Menu Model': 'Model menija', +'merge': 'združi', +'Merge Lines': 'Združi vrstice', +'Models': 'Modeli', +'models': 'modeli', +'Modified On': 'Modified On', +'Modules': 'Moduli', +'modules': 'moduli', +'Multi User Mode': 'Multi User Mode', +'Name': 'Ime', +'new application "%s" created': 'ustvarjen nov program "%s"', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'Čarovnik za novo aplikacijo', +'New application wizard': 'Čarovnik za novo aplikacijo', +'new plugin installed': 'new plugin installed', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'Nov zapis', +'new record inserted': 'vstavljen nov zapis', +'New simple application': 'Nova enostavna aplikacija', +'next': 'next', +'next %s rows': 'next %s rows', +'next 100 rows': 'naslednjih 100 zapisov', +'Next Edit Point': 'Naslednja točka urejanja', +'NO': 'NE', +'no changes': 'no changes', +'No databases in this application': 'V tem programu ni podatkovnih baz', +'No Interaction yet': 'No Interaction yet', +'no match': 'no match', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'ali uvozi iz CSV datoteke', +'or provide app url:': 'ali vpišite URL programa:', +'or provide application url:': 'ali vpišite URL programa:', +'Origin': 'Izvor', +'Original/Translation': 'Izvor/Prevod', +'Overview': 'Overview', +'Overwrite installed app': 'Prepiši obstoječi program', +'Pack all': 'Zapakiraj vse', +'Pack compiled': 'Paket preveden', +'Pack custom': 'Pack custom', +'pack plugin': 'zapakiraj vtičnik', +'Password': 'Geslo', +'password changed': 'password changed', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Vpogled v datoteko', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Please', +'please wait!': 'Prosim počakajte!', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" deleted', +'Plugin "%s" in application': 'Vtičnik "%s" v aplikaciji', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'vtičniki', +'Plugins': 'Vtičniki', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Narejeno z', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'prejšnjih 100 zapisov', +'Previous Edit Point': 'Prejšnja točka urejanja', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Project Progress', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Vprašanje:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Record': 'Record', +'record': 'zapis', +'record does not exist': 'zapis ne obstaja', +'record id': 'id zapisa', +'Record ID': 'ID zapisa', +'Record id': 'Record id', +'refresh': 'refresh', +'Register': 'Registracija', +'register': 'registracija', +'Registration key': 'Registracijski ključ', +'Reload routes': 'Ponovno naloži preusmeritve', +'Remove compiled': 'Odstrani prevedeno', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Replace', +'Replace All': 'Replace All', +'Repository (%s)': 'Repository (%s)', +'request': 'zahteva', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Reset Password key': 'Ponastavi ključ gesla', +'Resolve Conflict file': 'Datoteka za razrešitev problemov', +'response': 'odgovor', +'restart': 'restart', +'restore': 'obnovi', +'return': 'return', +'Revert': 'Revert', +'revert': 'povrni', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Vloga', +'Roles': 'Roles', +'Rows in table': 'Vrstic v tabeli', +'Rows in Table': 'Rows in Table', +'Rows selected': 'Izbranih vrstic', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Poženi teste v tej datoteki (za vse teste uporabite gumb 'test')", +'Running on %s': 'Running on %s', +'Save': 'Save', +'save': 'shrani', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Shrani preko AJAX', +'Saved file hash:': 'Koda shranjene datoteke:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'selected': 'izbrano', +'session': 'seja', +'session expired': 'seja pretekla', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'lupina', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'Spletišče', +'Size of cache:': 'Size of cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': 'nekaterih datotek se ni dalo izbrisati', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Oprostite. Mercurial ni nameščen.', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Začnite z novo aplikacijo', +'Start searching': 'Start searching', +'Start wizard': 'Zaženi čarovnika', +'state': 'stanje', +'Static': 'Static', +'static': 'statično', +'Static files': 'Statične datoteke', +'Statistics': 'Statistics', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'Stylesheet': 'CSS datoteka', +'submit': 'pošlji', +'Submit': 'Submit', +'successful': 'successful', +'Sure you want to delete this object?': 'Ali res želite izbrisati ta predmet?', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': 'tabela', +'Table': 'Table', +'Table name': 'Ime tabele', +'Temporary': 'Temporary', +'test': 'test', +'test_def': 'test_def', +'test_for': 'test_for', +'test_if': 'test_if', +'test_try': 'test_try', +'Testing application': 'Testiranje programa', +'Testing controller': 'Testiranje krmilnika', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"vprašanje" je pogoj kot npr. "db.table1.field1 == \'vrednost\'". Nekaj kot "db.table1.field1 == db.table2.field2" izvede SQL operacijo JOIN.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'the application logic, each URL path is mapped in one exposed function in the controller': 'krmilna logika, vsaka URL pot je preslikana v eno funkcijo v krmilniku', +'The application logic, each URL path is mapped in one exposed function in the controller': 'Logika delovanja aplikacije. Vsak URL je povezan z eno objavljeno funkcijo v krmilniku', +'the data representation, define database tables and sets': 'podatkovna predstavitev, definirajte tabele in množice', +'The data representation, define database tables and sets': 'Predstavitev podatkov. Definirajte podatkovne tabele in množice', +'The output of the file is a dictionary that was rendered by the view': 'Rezultat datoteke je slovar, ki ga predela pogled', +'The presentations layer, views are also known as templates': 'Predstavitveni nivo. Pogledi so znani tudi kot predloge', +'the presentations layer, views are also known as templates': 'predstavitveni nivo, pogledi so tudi znani kot predloge', +'Theme': 'Theme', +'There are no controllers': 'Ni krmilnikov', +'There are no models': 'Ni modelov', +'There are no modules': 'Ni modulov', +'There are no plugins': 'Ni vtičnikov', +'There are no private files': 'There are no private files', +'There are no static files': 'Ni statičnih datotek', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'Ni prevodov. Podprt je samo privzeti jezik', +'There are no views': 'Ni pogledov', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'Te datoteke so poslane brez obdelave. Vaše slike shranite tu.', +'these files are served without processing, your images go here': 'te datoteke so poslane brez posredovanja in obdelave, svoje slike shranite tu', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is a copy of the scaffolding application': 'To je kopija okvirne aplikacije', +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': 'To je predloga %(filename)s', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Listek', +'Ticket ID': 'ID listka', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': 'Časovni žig', +'TM': 'TM', +'to previous version.': 'na prejšnjo različico.', +'To create a plugin, name a file/folder plugin_[name]': 'Če želite ustvariti vtičnik, poimenujte datoteko/mapo plugin_[ime]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Sledljivost', +'translation strings for the application': 'prevodna besedila za program', +'Translation strings for the application': 'Prevajalna besedila za aplikacijo', +'try': 'poskusi', +'try something like': 'poskusite na primer', +'Try the mobile interface': 'Try the mobile interface', +'try view': 'try view', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Ne morem preveriti posodobitev', +'unable to create application "%s"': 'ne morem ustvariti programa "%s" ', +'unable to delete file "%(filename)s"': 'ne morem izbrisati datoteke "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'unable to delete file plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download': 'Ne morem prenesti datoteke', +'Unable to download app': 'Ne morem prenesti programa', +'Unable to download app because:': 'Unable to download app because:', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'ne morem obdelati csv datoteke', +'unable to uninstall "%s"': 'ne morem odstraniti "%s"', +'unable to upgrade because "%s"': 'unable to upgrade because "%s"', +'uncheck all': 'odznači vse', +'Uninstall': 'Odstrani', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'posodobi', +'update all languages': 'posodobi vse jezike', +'Update:': 'Posodobitev:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'upgrade now to %s', +'upgrade web2py now': 'posodobi web2py', +'upload': 'naloži', +'Upload': 'Upload', +'Upload & install packed application': 'Naloži in namesti pakirano aplikacijo', +'Upload a package:': 'Naloži paket:', +'Upload and install packed application': 'Naloži in namesti pakirano aplikacijo', +'upload application:': 'naloži program:', +'Upload existing application': 'Naloži obstoječo aplikacijo', +'upload file:': 'naloži datoteko:', +'upload plugin file:': 'naloži vtičnik:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Uporabie (...)&(...) za AND, (...)|(...) za OR, in ~(...) za NOT pri gradnji kompleksnih povpraševanj.', +'Use an url:': 'Uporabite URL:', +'user': 'uporabnik', +'User': 'User', +'User ID': 'ID uporabnika', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'spremenljivke', +'Version': 'Različica', +'Versioning': 'Versioning', +'versioning': 'različice', +'View': 'Pogled', +'view': 'pogled', +'Views': 'Pogledi', +'views': 'pogledi', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py je ažuren', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'zadnji tviti na web2py', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py upgraded; please restart it', +'Welcome %s': 'Dobrodošli, %s', +'Welcome to web2py': 'Dobrodošli v web2py', +'Which called the function': 'Ki je klical funkcijo', +'Working...': 'Working...', +'Wrap with Abbreviation': 'Ovij z okrajšavo', +'WSGI reference name': 'WSGI reference name', +'xml': 'xml', +'YES': 'DA', +'Yes': 'Yes', +'You are successfully running web2py': 'Uspešno ste pognali web2py', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You can modify this application and adapt it to your needs': 'Lahko spremenite to aplikacijo in jo prilagodite vašim potrebam', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'You visited the url': 'Obiskali ste URL', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/sr-cr.py b/web2py/applications/admin/languages/sr-cr.py new file mode 100644 index 0000000..882819b --- /dev/null +++ b/web2py/applications/admin/languages/sr-cr.py @@ -0,0 +1,595 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'sr-cr', +'!langname!': 'Српски (Ћирилица)', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s %%{row} је избрисан', +'%s %%{row} updated': '%s %%{row} је ажуриран', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%d-%m-%Y', +'%Y-%m-%d %H:%M:%S': '%d-%m-%Y %H:%M:%S', +'(requires internet access)': '(захтијева приступ интернету)', +'(requires internet access, experimental)': '(захтијева приступ интернету, експериментално)', +'(something like "it-it")': '(на примјер "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(датотека **gluon/contrib/plural_rules/%s.py** није пронађена)', +'Abort': 'Одустани', +'About': 'Информације', +'About application': 'О апликацији', +'Accept Terms': 'Прихватање услова коришћења', +'Add breakpoint': 'Add breakpoint', +'Additional code for your application': 'Додатни код за апликацију', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'администрација онемогућена јер нема лозинке', +'admin disabled because not supported on google app engine': 'администрација онемогућена на google app engine', +'admin disabled because too many invalid login attempts': 'администрација онемогућена због већег броја неуспјелих покушаја', +'admin disabled because unable to access password file': 'администрација онемогућена јер не могу приступити датотеци са лозинком', +'Admin is disabled because insecure channel': 'Администрација онемогућена због несигурне везе', +'Admin language': 'Језик администратора', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'административно окружење', +'Administrator Password:': 'Лозинка администратора:', +'and rename it:': 'и преименуј у:', +'App does not exist or you are not authorized': 'Апликација не постоји или немате права приступа', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'администрација онемогућена због несигурне везе', +'Application': 'Апликација', +'application "%s" uninstalled': 'апликација "%s" је деинсталирана', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'апликација је компајлирана', +'Application exists already': 'Апликација већ постоји', +'application is compiled and cannot be designed': 'апликација је компајлирана и не може се даље уређивати', +'Application name:': 'Назив апликације:', +'Application updated via git pull': 'Апликација ажурирана преко git pull', +'are not used': 'није кориштено', +'are not used yet': 'није још кориштено', +'Are you sure you want to delete file "%s"?': 'Да ли сте сигурни да желите избрисати датотеку "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Да ли сте сигурни да желите избрисати помоћни модул "%s"?', +'Are you sure you want to delete this object?': 'Да ли сте сигурни да желите обрисати?', +'Are you sure you want to uninstall application "%s"?': 'Да ли сте сигурни да желите деинсталирати апликацију "%s"?', +'Are you sure?': 'Да ли сте сигурни?', +'arguments': 'arguments', +'at char %s': 'код слова %s', +'at line %s': 'на линији %s', +'ATTENTION:': 'ПАЖЊА:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.', +'ATTENTION: you cannot edit the running application!': 'ПАЖЊА: не можете уређивати покренуту апликацију!', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available Databases and Tables': 'Доступне базе података и табеле', +'back': 'назад', +'Back to the plugins list': 'Назад на листу помоћних модула', +'Back to wizard': 'Back to wizard', +'Basics': 'Основе', +'Begin': 'Почетак', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Кеш', +'cache': 'кеш', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'кеш, грешке и сесије су обрисани', +'can be a git repo': 'може бити git репозиторијум', +'Cancel': 'Откажи', +'Cannot be empty': 'Не може бити празно', +'Cannot compile: there are errors in your app:': 'Не могу компајлирати: грешка у апликацији:', +'cannot create file': 'не могу креирати датотеку', +'cannot upload file "%(filename)s"': 'не мофу отпремити датотеку "%(filename)s"', +'Change Admin Password': 'Промијени лозинку администратора', +'Change admin password': 'Промијени лозинку администратора', +'change editor settings': 'change editor settings', +'Changelog': 'Changelog', +'check all': 'check all', +'Check for upgrades': 'Провјери могућност надоградње', +'Check to delete': 'Check to delete', +'Checking for upgrades...': 'Провјеравам могућност надоградње...', +'Clean': 'Прочисти', +'Clear': 'Обриши', +'Clear CACHE?': 'Обриши CACHE?', +'Clear DISK': 'Обриши DISK', +'Clear RAM': 'Обриши RAM', +'Click row to expand traceback': 'Click row to expand traceback', +'Click row to view a ticket': 'Click row to view a ticket', +'code': 'код', +'Code listing': 'Приказ кода', +'collapse/expand all': 'сакрити/приказати све', +'Command': 'Наредба', +'Comment:': 'Коментар:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'Компајлирај', +'Compile (all or nothing)': 'Компајлирај (све или ништа)', +'Compile (skip failed views)': 'Компајлирај (игнориши грешке)', +'compiled application removed': 'компајлирана апликација је уклоњена', +'Condition': 'Стање', +'continue': 'настави', +'Controllers': 'Контролери', +'controllers': 'контролери', +'Count': 'Редни број', +'Create': 'Креирај', +'create file with filename:': 'Креирај датотеку под називом:', +'Create rules': 'Креирај правила', +'Create/Upload': 'Креирај/Преузми', +'created by': 'израдио', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Тренутни захтјев', +'Current response': 'Тренутни одговор', +'Current session': 'Тренутна сесија', +'currently running': 'тренутно покренут', +'currently saved or': 'тренутно сачувано или', +'data uploaded': 'data uploaded', +'Database': 'База података', +'Database %s select': 'Database %s select', +'Database administration': 'Администрација базе података', +'database administration': 'администрација базе података', +'Database Administration (appadmin)': 'Администрација базе података (appadmin)', +'Date and Time': 'Датум и вријеме', +'db': 'db', +'Debug': 'Отклони грешку', +'defines tables': 'дефинише табеле', +'Delete': 'Обриши', +'delete': 'обриши', +'delete all checked': 'избриши све означено', +'delete plugin': 'избриши помоћни модул', +'Delete this file (you will be asked to confirm deletion)': 'Обриши ову датотеку (бићете упитани за потврду брисања)', +'Delete:': 'Избриши:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'Постави', +'Deploy on Google App Engine': 'Постави на Google App Engine', +'Deploy to OpenShift': 'Постави на OpenShift', +'Deploy to pythonanywhere': 'Постави на pythonanywhere', +'Deploy to PythonAnywhere': 'Постави на PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description:': 'Description:', +'design': 'design', +'Detailed traceback description': 'Detailed traceback description', +'details': 'details', +'direction: ltr': 'direction: ltr', +'directory not found': 'directory not found', +'Disable': 'Искључи', +'Disabled': 'Искључено', +'disabled in demo mode': 'онемогућено у демо моду', +'disabled in GAE mode': 'онемогућено у GAE моду', +'disabled in multi user mode': 'онемогућено у вишекорисничком моду', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'документација', +'Docs': 'Docs', +'done!': 'done!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Преузми као .w2p', +'Download as .exe': 'Преузми као .exe', +'download layouts': 'преузми layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'преузми помоћне модуле', +'Download plugins from repository': 'Преузми помоћне модуле из репозиторијум', +'Edit': 'Уреди', +'edit all': 'уреди све', +'Edit application': 'Уреди апликацију', +'edit controller': 'уреди контролер', +'edit controller:': 'edit controller:', +'Edit current record': 'Edit current record', +'edit views:': 'уреди приказ:', +'Editing %s': 'Уређивање %s', +'Editing file "%s"': 'Уређивање датотеке "%s"', +'Editing Language file': 'Уређивање језичке датотеке', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Enable', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Error': 'Грешка', +'Error logs for "%(app)s"': 'Преглед грешака за "%(app)s"', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Error ticket', +'Errors': 'Грешке', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Exception instance attributes', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation': 'Expand Abbreviation', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'извези као csv датотеку', +'Exports:': 'Извози:', +'exposes': 'приказује', +'exposes:': 'приказује:', +'extends': 'проширује', +'failed to compile file because:': 'нисам могао да компајлирам због:', +'failed to reload module because:': 'failed to reload module because:', +'File': 'Датотека', +'file "%(filename)s" created': 'датотека "%(filename)s" је креирана', +'file "%(filename)s" deleted': 'датотека "%(filename)s" је избрисана', +'file "%(filename)s" uploaded': 'датотека "%(filename)s" је отпремљена', +'file "%s" of %s restored': 'датотека "%s" од %s е враћено у претходно стање', +'file changed on disk': 'file changed on disk', +'file does not exist': 'датотека не постоји', +'file not found': 'датотека није пронађена', +'file saved on %(time)s': 'file saved on %(time)s', +'file saved on %s': 'датотека сачувана на %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'филтер', +'Find Next': 'Пронађи сљедећи', +'Find Previous': 'Пронађи претходни', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': 'Functions with no doctests will result in [passed] tests.', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Get from URL:': 'Преузми са странице:', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'Go to Matching Pair': 'Go to Matching Pair', +'go!': 'крени!', +'Google App Engine Deployment Interface': 'Google App Engine Dинсталационо окружење', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Help': 'Помоћ', +'here': 'here', +'Hide/Show Translated strings': 'Сакрити/Приказати преведене ријечи', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'инсталационо окружење', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'укључује', +'Indent with tabs': 'Indent with tabs', +'inspect attributes': 'inspect attributes', +'Install': 'Инсталирај', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Инсталиране апликације', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'унутрашња грешка', +'internal error: %s': 'унутрашња грешка: %s', +'Internal State': 'Internal State', +'Invalid action': 'Invalid action', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'Неважећа лозинка', +'invalid password.': 'неважећа лозинка.', +'Invalid Query': 'Погрешан упит', +'invalid request': 'invalid request', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'погрешан тикет', +'Key': 'Key', +'Key bindings': 'Пречице', +'Key bindings for ZenCoding Plugin': 'Пречице за ZenCoding Plugin', +'Keyboard shortcuts': 'Пречице на тастатури', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'језичка датотека "%(filename)s" је креирана/ажурирана', +'Language files (static strings) updated': 'Језичке датотеке су ажуриране', +'languages': 'језици', +'Languages': 'Језици', +'Last Revision': 'Last Revision', +'Last saved on:': 'Посљедња измјена:', +'License for': 'Лиценца за', +'License:': 'Лиценца:', +'Line Nr': 'Line Nr', +'Line number': 'Линија број', +'lists by exception': 'прикажи грешке', +'lists by ticket': 'прикажи тикете', +'Loading...': 'Преузимам...', +'loading...': 'преузимам...', +'Local Apps': 'Локалне апликације', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'Login': 'Пријава', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Пријава за административно окружење', +'Login/Register': 'Пријава/Регистрација', +'Logout': 'Одјава', +'lost password': 'изгубљена лозинка', +'Main Menu': 'Главни мени', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Match Pair': 'Match Pair', +'Memberships': 'Memberships', +'merge': 'споји', +'Merge Lines': 'Споји линије', +'Models': 'Модели', +'models': 'Модели', +'Modified On': 'Modified On', +'Modules': 'Модули', +'modules': 'модули', +'Multi User Mode': 'Вишекориснички режим рада', +'new application "%s" created': 'нова апликација "%s" је креирана', +'new application "%s" imported': 'нова апликација "%s" је увежена', +'New Application Wizard': 'Чаробњак за нове апликације', +'New application wizard': 'Чаробњак за нове апликације', +'new plugin installed': 'нови помоћни модул је инсталиран', +'New plugin installed: %s': 'Инсталиран нови помоћни модул: %s', +'New Record': 'Нови запис', +'new record inserted': 'унешен нови запис', +'New simple application': 'Нова једноставна апликација', +'next': 'следећи', +'next %s rows': 'next %s rows', +'Next Edit Point': 'Next Edit Point', +'NO': 'НЕ', +'no changes': 'нема промјена', +'No databases in this application': 'Нема базе података у апликацији', +'No Interaction yet': 'Нема још интеракције', +'no match': 'нема подударања', +'no package selected': 'пакет није одабран', +'no permission to uninstall "%s"': 'немате овлаштење да деинсталирате "%s"', +'No ticket_storage.txt found under /private folder': 'No ticket_storage.txt found under /private folder', +'Node:': 'Node:', +'Not Authorized': 'Немате овлашћење', +'Not supported': 'Није подржано', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'online designer': 'онлајн дизајнер', +'Open new app in new window': 'Отвори нову апликацију у новом прозору', +'OpenShift Deployment Interface': 'OpenShift инсталационо окружење', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'или алтернативно', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'или увези помоћу csv датотеке', +'Original/Translation': 'Оргинал/Превод', +'Overview': 'Преглед', +'Overwrite installed app': 'Замјени већ постојећу апликацију', +'Pack all': 'Запакуј све', +'Pack compiled': 'Запакуј компајлирано', +'Pack custom': 'Прилагођено паковање', +'pack plugin': 'запакуј помоћни модул', +'password changed': 'лозинка је промијењена', +'Past revisions': 'Претходне корекције', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Преглед датотеке', +'Permission': 'Дозвола', +'Permissions': 'Дозволе', +'Please': 'Молим', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'помоћни модул "%(plugin)s" је избрисан', +'Plugin "%s" in application': 'Помоћни модул "%s" у апликацији', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Страница помоћних модула', +'plugins': 'помоћни модули', +'Plugins': 'Помоћни модули', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Омогућио', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'Previous Edit Point': 'Previous Edit Point', +'Private files': 'Приватне датотеке', +'private files': 'приватне датотеке', +'Project Progress': 'Напредак пројекта', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Упит:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Record': 'Record', +'record does not exist': 'record does not exist', +'Record id': 'Record id', +'refresh': 'refresh', +'register': 'register', +'Reload routes': 'Обнови преусмјерења', +'Remove compiled': 'Уклони компајлирано', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Замијени', +'Replace All': 'Замијени све', +'Repository (%s)': 'Репозиторијум (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Resolve Conflict file': 'Resolve Conflict file', +'response': 'response', +'restart': 'restart', +'restore': 'restore', +'return': 'return', +'Revert': 'Revert', +'revert': 'revert', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Улога', +'Roles': 'Улоге', +'Rows in Table': 'Записи у табели', +'Rows selected': 'Rows selected', +'rules are not defined': 'правила нису дефинисана', +'rules:': 'правила:', +'Run tests': 'Покрени тестове', +'Run tests in this file': 'Покрени тестове у датотеци', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'Покренути на %s', +'Save': 'Сачувај', +'Save file:': 'Сачувај датотеку:', +'Save file: %s': 'Сачувај датотеку: %s', +'Save model as...': 'Сачувај модел као...', +'Save via Ajax': 'Сачувај преко Ajax', +'Saved file hash:': 'Сачувано као хаш:', +'Screenshot %s': 'Снимак екрана %s', +'Search': 'Претрага', +'Select Files to Package': 'Одабери датотеке за паковање', +'session': 'сесија', +'session expired': 'сесија је истекла', +'Session saved correctly': 'Сесија је уредно сачувана', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'shell', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'Сајт', +'Size of cache:': 'Size of cache:', +'skip to generate': 'прескочи генерисање', +'some files could not be removed': 'неке датотеке не могу бити уклоњене', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Жалим, mercurial није инсталиран', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Покрени нову апликацију', +'Start searching': 'Покрени претрагу', +'Start wizard': 'Покрени чаробњака', +'state': 'state', +'Static': 'Static', +'static': 'static', +'Static files': 'Static files', +'Statistics': 'Statistics', +'Step': 'Корак', +'step': 'kорак', +'stop': 'stop', +'submit': 'прихвати', +'Submit': 'Прихвати', +'successful': 'успјешан', +'switch to : db': 'пређи на : db', +'switch to : filesystem': 'пређи на : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'Table': 'Табела', +'Temporary': 'Temporary', +'test': 'тест', +'Testing application': 'Тестирање апликације', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller', +'The data representation, define database tables and sets': 'The data representation, define database tables and sets', +'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates', +'Theme': 'Табела', +'There are no controllers': 'Нема контолера', +'There are no models': 'Нема модела', +'There are no modules': 'Нема модула', +'There are no plugins': 'Нема помоћних модула', +'There are no private files': 'Нема приватних датотека', +'There are no static files': 'Нема статичних датотека', +'There are no translators': 'Нема преводиоца', +'There are no translators, only default language is supported': 'There are no translators, only default language is supported', +'There are no views': 'Нема преводиоца', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'These files are served without processing, your images go here', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Тикет', +'Ticket ID': 'Тикет ID', +'Ticket Missing': 'Недостаје тикет', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'to previous version.': 'на претходну верзију.', +'To create a plugin, name a file/folder plugin_[name]': 'To create a plugin, name a file/folder plugin_[name]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'Translation strings for the application': 'Ријечи у апликацији које треба превести', +'try something like': 'на примјер', +'Try the mobile interface': 'Пробај мобилнo окружење', +'try view': 'пробај приказ', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Не могу да провјерим могућност надоградње', +'unable to create application "%s"': 'unable to create application "%s"', +'unable to delete file "%(filename)s"': 'не могу избрисати датотеку "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'не могу избрисати помоћни модул "%(plugin)s"', +'Unable to determine the line number!': 'Не могу да утврдим број реда!', +'Unable to download app because:': 'Не могу да преузмем апликацију због:', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Не могу да преузмем списак помоћних модула', +'unable to install plugin "%s"': 'не могу да инсталирам помоћни модул "%s"', +'unable to parse csv file': 'не могу да расчланим csv датотеку', +'unable to uninstall "%s"': 'не могу да деинсталирам "%s"', +'unable to upgrade because "%s"': 'не могу да ажуримам због "%s"', +'uncheck all': 'uncheck all', +'Uninstall': 'Деинсталирај', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'ажурирај', +'update all languages': 'ажурирај све језике', +'Update:': 'Ажурирај:', +'Upgrade': 'Надоградња', +'upgrade now to %s': 'ажуриран на %s', +'upload': 'Отпреми', +'Upload': 'Преузми', +'Upload a package:': 'Преузми пакет:', +'Upload and install packed application': 'Преузми и инсталирај запаковану апликацију', +'upload file:': 'преузми датотеку:', +'upload plugin file:': 'преузми датотеку помоћног модула:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.', +'User': 'Корисник', +'Username': 'Корисничко име', +'Users': 'Корисници', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'variables', +'Version': 'Верзија', +'Version %s.%s.%s (%s) %s': 'Верзија %s.%s.%s (%s) %s', +'Versioning': 'Креирање верзија', +'Views': 'Прикази', +'views': 'прикази', +'Warning!': 'Упозорење!', +'WARNING:': 'УПОЗОРЕЊЕ:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py администраторска лозинка', +'web2py apps to deploy': 'web2py апликација за инсталацију', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py је ажуран', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'web2py Recent Tweets', +'web2py upgrade': 'web2py надоградња', +'web2py upgraded; please restart it': 'web2py је ажуриран; молим да рестартујете', +'Working...': 'Извршавам...', +'Wrap with Abbreviation': 'Wrap with Abbreviation', +'WSGI reference name': 'WSGI reference name', +'YES': 'ДА', +'Yes': 'Да', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/sr-lt.py b/web2py/applications/admin/languages/sr-lt.py new file mode 100644 index 0000000..a807b8c --- /dev/null +++ b/web2py/applications/admin/languages/sr-lt.py @@ -0,0 +1,596 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'sr-lt', +'!langname!': 'Srpski (Latinica)', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s %%{row} je izbrisan', +'%s %%{row} updated': '%s %%{row} je ažuriran', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%d-%m-%Y', +'%Y-%m-%d %H:%M:%S': '%d-%m-%Y %H:%M:%S', +'(requires internet access)': '(zahtijeva pristup internetu)', +'(requires internet access, experimental)': '(zahtijeva pristup internetu, eksperimentalno)', +'(something like "it-it")': '(na primjer "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(datoteka **gluon/contrib/plural_rules/%s.py** nije pronađena)', +'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'Abort': 'Odustani', +'About': 'Informacije', +'About application': 'O aplikaciji', +'Accept Terms': 'Prihvatanje uslova korišćenja', +'Add breakpoint': 'Add breakpoint', +'Additional code for your application': 'Dodatni kod za aplikaciju', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'administracija onemogućena jer nema lozinke', +'admin disabled because not supported on google app engine': 'administracija onemogućena na google app engine', +'admin disabled because too many invalid login attempts': 'administracija onemogućena jer zbog većeg broja neuspjelih pokušaja', +'admin disabled because unable to access password file': 'administracija onemogućena jer ne mogu pristupiti datoteci sa lozinkom', +'Admin is disabled because insecure channel': 'Administracija onemogućena zbog nesigurne veze', +'Admin language': 'Jezik administratora', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'administrativno okruženje', +'Administrator Password:': 'Lozinka administratora:', +'and rename it:': 'i preimenuj u:', +'App does not exist or you are not authorized': 'Aplikacija ne postoji ili nemate prava pristupa', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'administracija onemogućena zbog nesigurne veze', +'Application': 'Aplikacija', +'application "%s" uninstalled': 'aplikacija "%s" je deinstalirana', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'aplikacija je kompajlirana', +'Application exists already': 'Aplikacija već postoji', +'application is compiled and cannot be designed': 'aplikacija je kompajlirana i ne može se dalje uređivati', +'Application name:': 'Naziv aplikacije:', +'Application updated via git pull': 'Aplikacija ažurirana preko git pull', +'are not used': 'nije korišteno', +'are not used yet': 'nije još korišteno', +'Are you sure you want to delete file "%s"?': 'Da li ste sigurni da želite izbrisati datoteku "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Da li ste sigurni da želite izbrisati pomoćni modul "%s"?', +'Are you sure you want to delete this object?': 'Da li ste sigurni da želite obrisati?', +'Are you sure you want to uninstall application "%s"?': 'Da li ste sigurni da želite deinstalirati aplikaciju "%s"?', +'Are you sure?': 'Da li ste sigurni?', +'arguments': 'arguments', +'at char %s': 'kod slova %s', +'at line %s': 'na liniji %s', +'ATTENTION:': 'PAŽNJA:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.', +'ATTENTION: you cannot edit the running application!': 'ATTENTION: ne možete uređivati pokrenutu aplikaciju!', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available Databases and Tables': 'Dostupne baze podataka i tabele', +'back': 'nazad', +'Back to the plugins list': 'Nazad na listu pomoćnih modula', +'Back to wizard': 'Back to wizard', +'Basics': 'Osnove', +'Begin': 'Početak', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Keš', +'cache': 'keš', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'keš, greške i sesije su obrisani', +'can be a git repo': 'može biti git repozitorijum', +'Cancel': 'Otkaži', +'Cannot be empty': 'Ne može biti prazno', +'Cannot compile: there are errors in your app:': 'Ne mogu kompajlirati: greška u aplikaciji:', +'cannot create file': 'ne mogu kreirati datoteku', +'cannot upload file "%(filename)s"': 'ne mogu otpremiti datoteku "%(filename)s"', +'Change admin password': 'Promijeni lozinku administratora', +'Change Admin Password': 'Promijeni lozinku administratora', +'change editor settings': 'change editor settings', +'Changelog': 'Changelog', +'check all': 'check all', +'Check for upgrades': 'Provjeri mogućnost nadogradnje', +'Check to delete': 'Check to delete', +'Checking for upgrades...': 'Provjeravam mogućnost nadogradnje...', +'Clean': 'Pročisti', +'Clear': 'Obriši', +'Clear CACHE?': 'Obriši CACHE?', +'Clear DISK': 'Obriši DISK', +'Clear RAM': 'Obriši RAM', +'Click row to expand traceback': 'Click row to expand traceback', +'Click row to view a ticket': 'Click row to view a ticket', +'code': 'kod', +'Code listing': 'Prikaz koda', +'collapse/expand all': 'sakriti/prikazati sve', +'Command': 'Naredba', +'Comment:': 'Komentar:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'Kompajliraj', +'Compile (all or nothing)': 'Kompajliraj (sve ili ništa)', +'Compile (skip failed views)': 'Kompajliraj (ignoriši greške)', +'compiled application removed': 'kompajlirana aplikacija je uklonjena', +'Condition': 'Stanje', +'continue': 'nastavi', +'Controllers': 'Kontroleri', +'controllers': 'kontroleri', +'Count': 'Redni broj', +'Create': 'Kreiraj', +'create file with filename:': 'Kreiraj datoteku pod nazivom:', +'Create rules': 'Kreiraj pravila', +'Create/Upload': 'Kreiraj/Preuzmi', +'created by': 'izradio', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'crontab', +'Current request': 'Trenutni zahtjev', +'Current response': 'Trenutni odgovor', +'Current session': 'Trenutna sesija', +'currently running': 'trenutno pokrenut', +'currently saved or': 'trenutno sačuvano ili', +'data uploaded': 'data uploaded', +'Database': 'Baza podataka', +'Database %s select': 'Database %s select', +'database administration': 'administracija baze podataka', +'Database administration': 'Administracija baze podataka', +'Database Administration (appadmin)': 'Administracija baze podataka (appadmin)', +'Date and Time': 'Datum i vrijeme', +'db': 'db', +'Debug': 'Otkloni grešku', +'defines tables': 'definiše tabele', +'delete': 'Izbriši', +'Delete': 'Izbriši', +'delete all checked': 'izbriši sve označeno', +'delete plugin': 'izbriši pomoćni modul', +'Delete this file (you will be asked to confirm deletion)': 'Izbriši ovu datoteku (bićete upitani za potvrdu brisanja)', +'Delete:': 'Izbriši:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'Postavi', +'Deploy on Google App Engine': 'Postavi na Google App Engine', +'Deploy to OpenShift': 'Postavi na OpenShift', +'Deploy to pythonanywhere': 'Postavi na pythonanywhere', +'Deploy to PythonAnywhere': 'Postavi na PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description:': 'Description:', +'design': 'design', +'Detailed traceback description': 'Detailed traceback description', +'details': 'details', +'direction: ltr': 'direction: ltr', +'directory not found': 'directory not found', +'Disable': 'Isključi', +'Disabled': 'Isključeno', +'disabled in demo mode': 'onemogućeno u demo modu', +'disabled in GAE mode': 'onemogućeno u GAE modu', +'disabled in multi user mode': 'onemogućeno u višekorisničkom modu', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'Docs': 'Docs', +'docs': 'dokumentacija', +'done!': 'done!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Preuzmi kao .w2p', +'Download as .exe': 'Preuzmi kao .exe', +'download layouts': 'preuzmi layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'preuzmi pomoćne module', +'Download plugins from repository': 'Preuzmi pomoćne module iz repozitorijum', +'Edit': 'Uredi', +'edit all': 'uredi sve', +'Edit application': 'Uredi aplikaciju', +'edit controller': 'uredi controller', +'edit controller:': 'edit controller:', +'Edit current record': 'Edit current record', +'edit views:': 'uredi prikaz:', +'Editing %s': 'Uređivanje %s', +'Editing file "%s"': 'Uređivanje datoteke "%s"', +'Editing Language file': 'Uređivanje jezičke datoteke', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Enable', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Error': 'Greška', +'Error logs for "%(app)s"': 'Pregled grešaka za "%(app)s"', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Error ticket', +'Errors': 'Greške', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Exception instance attributes', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation': 'Expand Abbreviation', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'izvezi kao csv datoteku', +'Exports:': 'Izvozi:', +'exposes': 'prikazuje', +'exposes:': 'prikazuje:', +'extends': 'proširuje', +'failed to compile file because:': 'nisam mogao da kompajliram zbog:', +'failed to reload module because:': 'failed to reload module because:', +'File': 'Datoteka', +'file "%(filename)s" created': 'datoteka "%(filename)s" je kreirana', +'file "%(filename)s" deleted': 'datoteka "%(filename)s" je izbrisana', +'file "%(filename)s" uploaded': 'datoteka "%(filename)s" je otpremljena', +'file "%s" of %s restored': 'datoteka "%s" od %s je vraćeno u prethodno stanje', +'file changed on disk': 'file changed on disk', +'file does not exist': 'datoteka ne postoji', +'file not found': 'datoteka nije pronađena', +'file saved on %(time)s': 'file saved on %(time)s', +'file saved on %s': 'datoteka sačuvana na %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'filter', +'Find Next': 'Pronađi sljedeći', +'Find Previous': 'Pronađi prethodni', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': 'Functions with no doctests will result in [passed] tests.', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Get from URL:': 'Preuzmi sa stranice:', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'Go to Matching Pair': 'Go to Matching Pair', +'go!': 'kreni!', +'Google App Engine Deployment Interface': 'Google App Engine instalaciono okruženje', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'Graph Model': 'Graph Model', +'graph model': 'graph model', +'Help': 'Pomoć', +'here': 'here', +'Hide/Show Translated strings': 'Sakriti/Prikazati prevedene riječi', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Uvoz/Izvoz', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'uključuje', +'Indent with tabs': 'Indent with tabs', +'inspect attributes': 'inspect attributes', +'Install': 'Instaliraj', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Instalirane aplikacije', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'unutrašnja greška', +'internal error: %s': 'unutrašnja greška: %s', +'Internal State': 'Internal State', +'Invalid action': 'Invalid action', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'Nevažeća lozinka', +'invalid password.': 'nevažeća lozinka.', +'Invalid Query': 'Pogrešan upit', +'invalid request': 'invalid request', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'pogrešan tiket', +'Key': 'Key', +'Key bindings': 'Prečice', +'Key bindings for ZenCoding Plugin': 'Prečice za ZenCoding Plugin', +'Keyboard shortcuts': 'Prečice na tastaturi', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': 'jezička datoteka "%(filename)s" je kreirana/ažurirana', +'Language files (static strings) updated': 'Jezičke datoteke su ažurirane', +'Languages': 'Jezici', +'languages': 'jezici', +'Last Revision': 'Last Revision', +'Last saved on:': 'Posljednja izmjena:', +'License for': 'Licenca za', +'License:': 'Licenca:', +'Line Nr': 'Linija broj', +'Line number': 'Linija broj', +'lists by exception': 'prikaži greške', +'lists by ticket': 'prikaži tikete', +'Loading...': 'Preuzimam...', +'loading...': 'preuzimam...', +'Local Apps': 'Lokalne aplikacije', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'Login': 'Prijava', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Prijava za administrativno okruženje', +'Login/Register': 'Prijava/Registracija', +'Logout': 'Odjava', +'lost password': 'izgubljena lozinka', +'Main Menu': 'Glavni meni', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Match Pair': 'Match Pair', +'Memberships': 'Memberships', +'merge': 'spoji', +'Merge Lines': 'Spoji linije', +'Models': 'Modeli', +'models': 'modeli', +'Modified On': 'Modified On', +'modules': 'moduli', +'Modules': 'Moduli', +'Multi User Mode': 'Višekorisnički režim rada', +'new application "%s" created': 'nova aplikacija "%s" je kreirana', +'new application "%s" imported': 'nova aplikacija "%s" je uvežena', +'New application wizard': 'Čarobnjak za nove aplikacije', +'New Application Wizard': 'Čarobnjak za nove aplikacije', +'new plugin installed': 'novi pomoćni modul je instaliran', +'New plugin installed: %s': 'Instaliran novi pomoćni modul: %s', +'New Record': 'Novi zapis', +'new record inserted': 'unešen novi zapis', +'New simple application': 'Nova jednostavna aplikacija', +'next': 'sledeći', +'next %s rows': 'next %s rows', +'Next Edit Point': 'Next Edit Point', +'NO': 'NE', +'no changes': 'nema promjena', +'No databases in this application': 'Nema baze podataka u aplikaciji', +'No Interaction yet': 'Nema još interakcije', +'no match': 'nema podudaranja', +'no package selected': 'paket nije odabran', +'no permission to uninstall "%s"': 'nemate ovlaštenje da deinstalirate "%s"', +'No ticket_storage.txt found under /private folder': 'No ticket_storage.txt found under /private folder', +'Node:': 'Node:', +'Not Authorized': 'Nemate ovlašćenje', +'Not supported': 'Nije podržano', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'online designer': 'onlajn dizajner', +'Open new app in new window': 'Otvori novu aplikaciju u novom prozoru', +'OpenShift Deployment Interface': 'OpenShift instalaciono okruženje', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'ili alternativno', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': 'ili uvezi pomoću csv datoteke', +'Original/Translation': 'Original/Prevod', +'Overview': 'Pregled', +'Overwrite installed app': 'Zamjeni već postojeću aplikaciju', +'Pack all': 'Zapakuj sve', +'Pack compiled': 'Zapakuj kompajlirano', +'Pack custom': 'Prilagođeno pakovanje', +'pack plugin': 'zapakuj pomoćni modul', +'password changed': 'lozinka je promijenjena', +'Past revisions': 'Prethodne korekcije', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': 'Pregled datoteke', +'Permission': 'Dozvola', +'Permissions': 'Dozvole', +'Please': 'Molim', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'Pomoćni modul "%(plugin)s" je izbrisan', +'Plugin "%s" in application': 'Pomoćni modul "%s" u aplikaciji', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Stranica pomoćnih modula', +'Plugins': 'Pomoćni moduli', +'plugins': 'pomoćni moduli', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': 'Omogućio', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'Previous Edit Point': 'Previous Edit Point', +'private files': 'privatne datoteke', +'Private files': 'Privatne datoteke', +'Project Progress': 'Napredak projekta', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz biblioteka nije pronađena', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Upit:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Record': 'Record', +'record does not exist': 'record does not exist', +'Record id': 'Record id', +'refresh': 'refresh', +'register': 'register', +'Reload routes': 'Obnovi preusmjerenja', +'Remove compiled': 'Remove compiled', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Zamijeni', +'Replace All': 'Zamijeni sve', +'Repository (%s)': 'Repozitorijum (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Resolve Conflict file': 'Resolve Conflict file', +'response': 'response', +'restart': 'restart', +'restore': 'restore', +'return': 'return', +'Revert': 'Revert', +'revert': 'revert', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Uloga', +'Roles': 'Uloge', +'Rows in Table': 'Zapisi u tabeli', +'Rows selected': 'Rows selected', +'rules are not defined': 'pravila nisu definisana', +'rules:': 'pravila:', +'Run tests': 'Pokreni testove', +'Run tests in this file': 'Pokreni testove u datoteci', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'Pokrenuto na %s', +'Save': 'Sačuvaj', +'Save file:': 'Sačuvaj datoteku:', +'Save file: %s': 'Sačuvaj datoteku: %s', +'Save model as...': 'Sačuvaj model kao...', +'Save via Ajax': 'Sačuvaj preko Ajax', +'Saved file hash:': 'Sačuvano kao haš:', +'Screenshot %s': 'Snimak ekrana %s', +'Search': 'Pretraga', +'Select Files to Package': 'Odaberi datoteke za pakovanje', +'session': 'sesija', +'session expired': 'sesija je istekla', +'Session saved correctly': 'Sesija je uredno sačuvana', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': 'shell', +'Showing %s to %s of %s %s found': 'Prikazujem %s do %s od %s %s pronađenih', +'Singular Form': 'Singular Form', +'Site': 'Početna', +'Size of cache:': 'Size of cache:', +'skip to generate': 'preskoči generisanje', +'some files could not be removed': 'neke datoteke ne mogu biti uklonjene', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Žalim, mercurial nije instaliran', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Pokreni novu aplikaciju', +'Start searching': 'Pokreni pretragu', +'Start wizard': 'Pokreni čarobnjaka', +'state': 'state', +'static': 'static', +'Static': 'Static', +'Static files': 'Static files', +'Statistics': 'Statistics', +'Step': 'Korak', +'step': 'korak', +'stop': 'stop', +'Submit': 'Prihvati', +'submit': 'prihvati', +'successful': 'uspješan', +'switch to : db': 'pređi na : db', +'switch to : filesystem': 'pređi na : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'Table': 'Tabela', +'Temporary': 'Temporary', +'test': 'test', +'Testing application': 'Testiranje aplikacije', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': 'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller', +'The data representation, define database tables and sets': 'The data representation, define database tables and sets', +'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates', +'Theme': 'Teme', +'There are no controllers': 'Nema kontolera', +'There are no models': 'Nema modela', +'There are no modules': 'Nema modula', +'There are no plugins': 'Nema pomoćnih modula', +'There are no private files': 'Nema privatnih datoteka', +'There are no static files': 'Nema statičnih datoteka', +'There are no translators': 'Nema prevodioca', +'There are no translators, only default language is supported': 'There are no translators, only default language is supported', +'There are no views': 'Nema stranica prikaza', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'These files are served without processing, your images go here', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Tiket', +'Ticket ID': 'Tiket ID', +'Ticket Missing': 'Nedostaje tiket', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'to previous version.': 'na prethodnu verziju.', +'To create a plugin, name a file/folder plugin_[name]': 'To create a plugin, name a file/folder plugin_[name]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'Translation strings for the application': 'Riječi u aplikaciji koje treba prevesti', +'try something like': 'na primjer', +'Try the mobile interface': 'Probaj mobilno okruženje', +'try view': 'probaj prikaz', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Ne mogu da provjerim mogućnost nadogradnje', +'unable to create application "%s"': 'unable to create application "%s"', +'unable to delete file "%(filename)s"': 'ne mogu izbrisati datoteku "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'ne mogu izbrisati pomoćni modul "%(plugin)s"', +'Unable to determine the line number!': 'Ne mogu da utvrdim broj reda!', +'Unable to download app because:': 'Ne mogu da preuzmem aplikaciju zbog:', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Ne mogu da preuzmem spisak pomoćnih modula', +'unable to install plugin "%s"': 'ne mogu da instaliram pomoćni modul "%s"', +'unable to parse csv file': 'ne mogu da rasčlanim csv datoteku', +'unable to uninstall "%s"': 'ne mogu da deinstaliram "%s"', +'unable to upgrade because "%s"': 'ne mogu da ažurimam zbog "%s"', +'uncheck all': 'uncheck all', +'Uninstall': 'Deinstaliraj', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'ažuriraj', +'update all languages': 'ažuriraj sve jezike', +'Update:': 'Ažuriraj:', +'Upgrade': 'Nadogradnja', +'upgrade now to %s': 'ažuriran na %s', +'upload': 'Otpremi', +'Upload': 'Preuzmi', +'Upload a package:': 'Preuzmi paket:', +'Upload and install packed application': 'Preuzmi i instaliraj zapakovanu aplikaciju', +'upload file:': 'preuzmi datoteku:', +'upload plugin file:': 'preuzmi datoteku pomoćnog modula:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.', +'User': 'Korisnik', +'Username': 'Korisničko ime', +'Users': 'Korisnici', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'promenljive', +'Version': 'Verzija', +'Version %s.%s.%s (%s) %s': 'Verzija %s.%s.%s (%s) %s', +'Versioning': 'Kreiranje verzija', +'views': 'prikazi', +'Views': 'Prikazi', +'Warning!': 'Upozorenje!', +'WARNING:': 'UPOZORENJE:', +'WARNING: The following views could not be compiled:': 'WARNING: Sledeći prikazi ne mogu biti kompajlirani:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py administratorska lozinka', +'web2py apps to deploy': 'web2py aplikacija za instalaciju', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py je ažuran', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'web2py Recent Tweets', +'web2py upgrade': 'web2py nadogradnja', +'web2py upgraded; please restart it': 'web2py je ažuriran; molim da restartujete', +'Working...': 'Izvršavam...', +'Wrap with Abbreviation': 'Wrap with Abbreviation', +'WSGI reference name': 'WSGI referentni naziv', +'YES': 'DA', +'Yes': 'Da', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/tr.py b/web2py/applications/admin/languages/tr.py new file mode 100644 index 0000000..50e52d8 --- /dev/null +++ b/web2py/applications/admin/languages/tr.py @@ -0,0 +1,646 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'tr', +'!langname!': 'Türkçe', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"güncelleme" ("update") "field1 = \'yenideğer\'" gibi seçeneğe bağlı bir ifadedir. JOIN sonuçlarını silemez veya silemezsiniz.', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s %%{row} silindi', +'%s %%{row} updated': '%s %%{row} güncellendi', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%d-%m-%Y', +'%Y-%m-%d %H:%M:%S': '%d-%m-%Y %H:%M:%S', +'(requires internet access)': '(Internet erişimi gerekir)', +'(requires internet access, experimental)': '(internet erişimi gerekir, deneysel)', +'(something like "it-it")': '("it-it" şeklinde birşeyler) ', +'(version %s)': '(version %s)', +'1: Setting Parameters': '1: Parametrelerin Yapılandırılması', +'?': '?', +'@markmin\x01An error occured, please [[reload %s]] the page': '@markmin\x01Bir hata oluştu, lütfen sayfayı [[reload %s]]', +"@markmin\x01Mercurial Version Control System Interface[[NEWLINE]]for application '%s'": "'%s' uygulaması için[[NEWLINE]]Mercurial Sürüm Kontrol Sistemi Arayüzü", +'@markmin\x01Searching: **%s** %%{file}': '@markmin\x01Aranıyor: **%s** %%{file}', +'A new version of web2py is available: %s': "web2py'nin yeni sürümü mevcut: %s ", +'A new version of web2py is available: Version 1.68.2 (2009-10-21 09:59:29)\n': "web2py'nin yeni sürümü mevcut: Sürüm 1.68.2 (2009-10-21 09:59:29)\r\n", +'Abort': 'Abort', +'About': 'Hakkında', +'About application': 'Uygulama hakkında', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Kesme noktası ekle', +'additional code for your application': 'uygulamanız için fazladan kod', +'Additional code for your application': 'Uygulamanız için fazladan kod', +'Admin design page': 'Yönetici tasarım sayfası', +'admin disabled because no admin password': 'yönetici parolası olmadığından admin etkinsiz', +'admin disabled because not supported on google app engine': 'Google App Motoru tafaından desteklenmediğinden admin etkinsizleştirildi', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': 'parola dosyasına erişielemdiğinden admin etkinsizleştirildi', +'Admin is disabled because insecure channel': 'güvenzis kanal olduğundan admin etkinsizleştirildi', +'Admin language': 'Admin dilleri', +'Admin versioning page': 'Yönetici sürümleme sayfası', +'administrative interface': 'yönetsel arayüz', +'Administrator Password:': 'Yönetici Parolası:', +'and rename it (required):': 've yeniden adlandır (gerekli):', +'and rename it:': 'yeniden adlandır:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': 'appadmin', +'appadmin is disabled because insecure channel': 'güvenzis kanal olduğundan admin etkinsizleştirildi', +'Application': 'Uygulama', +'application "%s" uninstalled': '"%s" uygulaması kaldırıldı', +'application %(appname)s installed with md5sum: %(digest)s': '%(appname)s uygulaması md5sum %(digest)s ile kuruldu', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': 'uygulama derlendi', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': 'uygulama derlenmiş ve tasarlanamaz', +'Application name:': 'Uygulama adı:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'kullanılamıyor', +'are not used yet': 'şimdilik kullanılamıyor', +'Are you sure you want to delete file "%s"?': '«%s» dosyasını silmek istediğinize emin misiniz?', +'Are you sure you want to delete plugin "%s"?': '"%s" eklentisini kaldırmak istediğinizden emin misiniz?', +'Are you sure you want to delete this object?': 'Bu nesneyi silmek istediğinizden emin misiniz?', +'Are you sure you want to uninstall application "%s"?': '«%s» uygulamasını kaldırmak istediğinizden emin misiniz?', +'Are you sure you want to upgrade web2py now?': "web2py'yi güncellemek istediğinizden emin misiniz?", +'Are you sure?': 'Are you sure?', +'arguments': 'argümanlar', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': 'UYARI: Giriş günceli bağlantı (HTTPS) gerektirmekte veya yerel makinada çalışılmalıdır.', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'UYARI: ÇOKLU TEST GÜVENLİ DEĞİL. BİRDEN ÇOK TESTİ AYNI ANDA YAPMAYIN.', +'ATTENTION: you cannot edit the running application!': 'UYARI: çalışan uygulamayı düzenleyemezsiniz!', +'Autocomplete Python Code': 'Python Kodlarını Otomatik Tamamla', +'Available databases and tables': 'Kullanılabilir veritabanları ve tablolar', +'Available Databases and Tables': 'Available Databases and Tables', +'back': 'geri', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Sihirbaza geri dön', +'Basics': 'Temeller', +'Begin': 'Başla', +'breakpoint': 'kesme noktası', +'breakpoints': 'kesme noktaları', +'Breakpoints': 'Kesme Noktaları', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': 'zula', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': 'zula, hatalar ve oturumlar temizlendi', +'can be a git repo': 'git deposu olabilir', +'Cancel': 'Vazgeç', +'Cannot be empty': 'Boş olamaz', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': 'Derlenemiyor: uygulamanızda hata(lar) var. Hataları düzeltin ve tekrar deneyin.', +'Cannot compile: there are errors in your app:': 'Derlenemiyor: uygulamanızda hata(lar) var:', +'cannot create file': 'dosya oluşturulamıyor', +'cannot upload file "%(filename)s"': '"%(filename)s" dosyalarını yükleyemiyor', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'admin parolasını değiştir', +'change editor settings': 'düzenleyici ayarlarını değiştir', +'Changelog': 'Changelog', +'check all': 'tümünü kontrol et', +'Check for upgrades': 'Güncellemeleri kontrol et', +'Check to delete': 'Silmek için kontrok et', +'Checking for upgrades...': 'Güncellemeler denetleniyor ... ', +'Clean': 'Temizle', +'Clear': 'Clear', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'Click row to expand traceback': 'Takibi genişletmek için satır üzerine tıkla', +'Click row to view a ticket': 'Click row to view a ticket', +'click to check for upgrades': 'güncellemeleri denetlemek için tıklayın', +'code': 'kod', +'Code listing': 'Code listing', +'collapse/expand all': 'sıkıştır/tümünü aç', +'Command': 'Command', +'Comment:': 'Yorum:', +'Commit': 'Öneri', +'Commit form': 'Tarafından öneri', +'Committed files': 'Committed files', +'Compile': 'Derle', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'derlenmiş uygulama kaldırıldı', +'Condition': 'Durum', +'continue': 'continue', +'Controllers': 'Denetçiler', +'controllers': 'denetçiler', +'Count': 'Sayı', +'Create': 'Oluştur', +'create file with filename:': 'dosya adı ile dosya oluştur:', +'create new application:': 'yeni uygulama oluştur:', +'Create new simple application': 'Yeni basit uygulama oluştur', +'Create/Upload': 'Oluştur/Yükle', +'created by': 'yazan:', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': 'krontab', +'Current request': 'Şimdiki istek', +'Current response': 'Şimdiki yanıt', +'Current session': 'Şimdiki oturum', +'currently running': 'şimdiki çalışan', +'currently saved or': 'şimdiki kaydedilen veya', +'data uploaded': 'veri yüklendi', +'Database': 'Database', +'database': 'veritabı', +'Database %s select': 'Database %s select', +'database %s select': '%s veritabanı seçildi', +'Database administration': 'Veritabanı yönetimi', +'database administration': 'veritabı yönetimi', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Tarih ve Zaman', +'db': 'db', +'Debug': 'Hata Ayıkla', +'defines tables': 'tablolar tanımlı', +'Delete': 'Sil', +'delete': 'sil', +'delete all checked': 'tüm kontrol edilenleri sil', +'delete plugin': ' eklentiyi sil', +'Delete this file (you will be asked to confirm deletion)': 'Bu dosyayı sil (silmek için onay istenecek)', +'Delete:': 'Sil:', +'deleted after first hit': 'ilk vuruşta silinir', +'Demo': 'Demo', +'Deploy': 'Yayımla', +'Deploy on Google App Engine': 'Google App Motorunda Yayınla', +'Deploy to OpenShift': "OpenShift'e Yayınla ", +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Yayınlama formu', +'Deployment Interface': 'Deployment Interface', +'Description:': 'Description:', +'design': 'tadarla', +'Detailed traceback description': 'Ayrıntılı nedenin bulma tanımı', +'details': 'details', +'direction: ltr': 'yön: ltr', +'directory not found': 'directory not found', +'Disable': 'Devre Dışı', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'dokümanlar', +'Docs': 'Docs', +'done!': 'bitti!', +'Downgrade': 'Downgrade', +'Download .w2p': '.w2p İndir', +'Download as .exe': 'Download as .exe', +'download layouts': 'düzenleri indir', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'eklentileri indir', +'Download plugins from repository': 'Download plugins from repository', +'EDIT': 'DÜZENLE', +'Edit': 'Düzenle', +'edit all': 'tümünü düzenle', +'Edit application': 'Uygulamayı düzenle', +'edit controller': 'denetçiyi düzenle', +'edit controller:': 'denetçiyi düzenle:', +'Edit current record': 'Şimdiki kaydı düzenle', +'edit views:': 'görünümleri düzenle:', +'Editing %s': '%s Düzenleniyor', +'Editing file': 'Dosya düzenleniyor', +'Editing file "%s"': '"%s" dosyası düzenleniyor ', +'Editing Language file': 'Dil dosyası düzenleniyor', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Etkinleştir', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'enter a valid email address': 'geçerli e-posta adresi girin', +'enter a value': 'bir değer girin', +'enter only letters, numbers, and underscore': 'sadece harf, sayı ve alt çizgi giriniz', +'Enterprise Web Framework': 'Enterprise Web Çatısı', +'Error': 'Hata', +'Error logs for "%(app)s"': '"%(app)s" uygulaması için hata kayıtları', +'Error snapshot': 'Hata resmi', +'Error ticket': 'Hata bileti', +'Errors': 'Hatalar', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Hata durumu özellikleri', +'Exit Fullscreen': 'Tam Ekrandan Çık', +'Expand Abbreviation': 'Kısıtlamayı Aç', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'CSV olarak dışa ver', +'Exports:': 'Exports:', +'exposes': 'sergileniyor', +'exposes:': 'sergile:', +'extends': 'genişlet', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module': 'modül yüklenemedi', +'failed to reload module because:': 'modü yüklenemedi çünkü:', +'File': 'Dosya', +'file "%(filename)s" created': '"%(filename)s" dosyaları oluşturuldu', +'file "%(filename)s" deleted': '"%(filename)s" dosyaları silindi', +'file "%(filename)s" uploaded': '"%(filename)s" dosyaları yüklendi', +'file "%s" of %s restored': '"%s" dosyasının %s kısmı geri alındı', +'file changed on disk': 'dosya disk üzerinde değişti', +'file does not exist': 'dosya bulunamıyor', +'file not found': 'dosya bulanamadı', +'file saved on %(time)s': 'dosyası %(time)s zamanında kaydedildi', +'file saved on %s': 'dosyası kaydedildi: %s', +'filename': 'filename', +'Filename': 'Dosya adı', +'Files added': 'Files added', +'filter': 'filtre', +'Find Next': 'Sonrakini Bul', +'Find Previous': 'Öncekini Bul', +'Form has errors': 'Form has errors', +'Frames': 'Çerçeveler', +'Functions with no doctests will result in [passed] tests.': '[passed] testlerdeki işlevlerde doctest yok', +'GAE Email': 'GAE E-postası', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Parolası', +'Generate': 'Oluştur', +'Git Pull': 'Git Çek', +'Git Push': 'Git İtele', +'Globals##debug': 'Geneller', +'go!': 'git!', +'Google App Engine Deployment Interface': 'Google App Motoru Yayınlama Arayüzü', +'Google Application Id': 'Google Uygulama Id', +'Goto': 'Git', +'graph model': 'grafik modeli', +'Graph Model': 'Graph Model', +'Help': 'Yardım', +'here': 'here', +'Hide/Show Translated strings': 'Çevrilmiş cümleleri Gizle/Görüntüle', +'Highlight current line': 'Highlight current line', +'Hits': 'Vuruşlar', +'Home': 'Anasayfa', +'honored only if the expression evaluates to true': 'sadece deyim doğru sonucunu verirse', +'htmledit': 'html dğzenleyici', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Doküman testi yapılmadan önce, eğer yukarıdaki rapor bir bilet numarası içeriyorsa bu denetleyici çalıştırılırken bir hata oluşturğunu gösterir. Bu genellikle girinti/çıkıntı (indentation) hatası veya işlev dışındaki bir hatadan kaynaklanır.\nYeşil başlık geçilen tüm testleri (eğer tanımlanmışsa) gösterir. Bu durumda test sonuçları görüntülenmez.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'İçe/Dışa Aktarıcı', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': 'içerir', +'Indent with tabs': 'Indent with tabs', +'index': 'indeks', +'insert new': 'yeni ekle', +'insert new %s': '%s yeni ekle', +'inspect attributes': 'özellikleri denetleyin', +'Install': 'Kurucu', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Kurulu uygulamalar', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': 'dahili hata', +'internal error: %s': 'internal error: %s', +'Internal State': 'Dahili Durum', +'Invalid action': 'Geçersiz eylem', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'invalid expression': 'geçersiz ifade', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'Parola geçersiz', +'invalid password.': 'geçersiz parola.', +'Invalid Query': 'Geçersiz Sorgu', +'invalid request': 'geçersiz istek', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': 'geçersiz bilet', +'Key': 'Key', +'Key bindings': 'Anahtarlar', +'Key bindings for ZenCoding Plugin': 'ZenCoding Eklentisi için anahtarlar', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': '"%(filename)s" dil dosyası/dosyaları güncellendi', +'Language files (static strings) updated': 'Dil dosyası (statik cümleler) güncellendi', +'languages': 'diller', +'Languages': 'Diller', +'Last Revision': 'Last Revision', +'Last saved on:': 'Son kaydedilme:', +'License for': 'için lisanslanmış', +'License:': 'License:', +'Line Nr': 'Satır Nr', +'Line number': 'Satır numarası', +'lists by exception': 'istisnaya göre sırala', +'lists by ticket': 'bilete göre sırala', +'Loading...': 'Loading...', +'loading...': 'yükleniyor ...', +'Local Apps': 'Local Apps', +'locals': 'yereller', +'Locals##debug': 'Yereller', +'Login': 'Giriş', +'login': 'giriş', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Yönetsel Arayüze Giriş\t', +'Login/Register': 'Login/Register', +'Logout': 'Çıkış', +'lost password': 'lost password', +'Main Menu': 'Main Menu', +'Manage': 'Yönet', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Memberships': 'Memberships', +'merge': 'birleştir', +'Models': 'Modeller', +'models': 'modeller', +'Modified On': 'Modified On', +'Modules': 'Modüller', +'modules': 'modüller', +'Multi User Mode': 'Multi User Mode', +'new application "%s" created': 'yeni uygulama "%s" oluşturuldu', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'Yeni Uygulama Sihirbazı', +'New application wizard': 'Yeni uygulama sihirbazı', +'new plugin installed': 'yeni eklenti kuruldu', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'Yeni Kayıt', +'new record inserted': 'yeni kayıt eklendi', +'New simple application': 'Yeni basit uygulama', +'next': 'next', +'next %s rows': 'next %s rows', +'next 100 rows': 'sonraki 100 satır', +'NO': 'HAYIR', +'no changes': 'no changes', +'No databases in this application': 'Bu uygulamada veritabanı yok', +'No Interaction yet': 'Henüz etkileşim yok', +'no match': 'eşlenen yok', +'no package selected': 'hiç paket seçilmemiş', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'No ticket_storage.txt found under /private folder': '/private dizininde ticket_storage.txt dosyası bulunamadı', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Not: Eğer github hata kodu 128 durumunu bildiren bir ileti alırsanız, OpenShift hesabınızı ait ssh anahtarının doğru yapılandırıldığından emin olun.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'online designer': 'çevirimiçi tasarlayıcı', +'Open new app in new window': 'Yeni pencerede yeni uygualama aç', +'OpenShift Deployment Interface': 'OpenShift Yayınlama Arayüzü', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'veya seçenek olarak', +'Or Get from URL:': 'Veya şu URL den alın:', +'or import from csv file': 'veya CSV dsoyasından içerin', +'or provide app url:': "veya uygulama URL'si verin:", +'or provide application url:': "veya uygulama URL'si verin:", +'Original/Translation': 'Orjinal / Çeviri', +'Overview': 'Overview', +'Overwrite installed app': 'Kurulu uygulama üzerine yaz', +'Pack all': 'Tümünü paketle', +'Pack compiled': 'Derlenenleri paketle', +'Pack custom': 'Tercihli paketle', +'pack plugin': 'eklentiyi paketle', +'PAM authenticated user, cannot change password here': 'PAM onaylı kullanıcı, parola buradan değiştirilemiyor', +'password changed': 'parola değiştirilidi', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'appcfg.py dosyasının patikası', +'Path to local openshift repo root.': 'Yerel openshift repo kökünün patikası.', +'Peeking at file': 'Dosya gözetleniyor', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Lütfen', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': '"%(plugin)s" eklentisi silindi', +'Plugin "%s" in application': '"%s" uygulamasında eklenti', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'eklentiler', +'Plugins': 'Eklentiler', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Çoğul-Kipler:', +'Powered by': 'Yazılım Temeli:', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'önceki 100 satır', +'Private files': 'Özel dosyalar', +'private files': 'özel dosyalar', +'Project Progress': 'Proje İlerlemesi', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz kütüphanesi yok', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Sorgu: ', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Hızlı Arama', +'Record': 'Record', +'record': 'kayıt', +'record does not exist': 'kayıt bulunamıyor', +'record id': 'kayıt id', +'Record id': 'Record id', +'refresh': 'yeniden yükle', +'register': 'register', +'Reload routes': 'Yönelendirmeyi yeniden yükle', +'Remove compiled': 'Derlemeyi kaldır', +'Removed Breakpoint on %s at line %s': ' %s üzerindeki kesme noktası %s satırında değiştrildi.', +'Replace': 'Değiştir', +'Replace All': 'Tümünü değiştir', +'Repository (%s)': 'Repository (%s)', +'request': 'istek', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'python-git gerekyior, fakat kurulu değil', +'Resolve Conflict file': 'Dosyadaki çakışmayı çöz', +'response': 'tepki', +'restart': 'yeniden başla', +'restore': 'geri al', +'return': 'return', +'Revert': 'Revert', +'revert': 'geri al', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Rows in Table', +'Rows in table': 'Tablosundaki satırlar', +'Rows selected': 'Seçilen satırlar', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Bu dosyadaki testleri çalıştırır (tüm dosyaları çalıştırmak için, 'test' etiketli düğmeyi kullanabilirsiniz)", +'Running on %s': '%s üzerinde çalışıyor', +'Save': 'Kaydet', +'save': 'kaydet', +'Save file:': 'Dosyayı kaydet:', +'Save file: %s': 'Dosyayı farklı kaydet: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Ajax üzerinden kaydet', +'Saved file hash:': 'Kaydedilen dosyanın parmak izi:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Paketlenecek Dosyaları Seç', +'selected': 'seçildi', +'session': 'oturum', +'session expired': 'oturum zamanaşımına uğradı', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': "%s'nin %s satırındaki kesme noktasını: %s yap", +'shell': 'kabuk', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': 'Site', +'Size of cache:': 'Size of cache:', +'skip to generate': 'oluşturmak için atla', +'some files could not be removed': 'bazı dosyalar kaldırılamadı', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'kaynak : dosyasistemi', +'Start a new app': 'Yeni uygualama başla', +'Start searching': 'Aramaya başla', +'Start wizard': 'Başlatma sihirbazı', +'state': 'durum', +'Static': 'Statik', +'static': 'statik', +'Static files': 'Statik dosyalar', +'Statistics': 'Statistics', +'Step': 'Basamak', +'step': 'step', +'stop': 'stop', +'submit': 'gönder', +'Submit': 'Gönder', +'successful': 'başarılı', +'Sure you want to delete this object?': 'Bu nesneyi silmek istediğinizden emin misiniz? ', +'switch to : db': 'geç : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': 'tablo', +'Table': 'Table', +'Temporary': 'Geçici', +'test': 'test', +'Testing application': 'Uygulama test ediliyor', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"sorgulama" "db.table1.field1==\'değer\'" şeklinde bir durumu ifade eder. SQL birleştirmede (JOIN) "db.table1.field1==db.table2.field2" şeklindedir.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'the application logic, each URL path is mapped in one exposed function in the controller': 'uygulama mantığı: her URL denetleyicideki bir işleve eşlenir', +'The application logic, each URL path is mapped in one exposed function in the controller': 'Uygulama mantığı: her URL denetleyicideki bir işleve eşlenir', +'the data representation, define database tables and sets': 'veri gösterimi, veritabanı tablolarını ve setlerini tanımla', +'The data representation, define database tables and sets': 'Veri gösterimi, veritabanı tablolarını ve setlerini tanımla', +'The presentations layer, views are also known as templates': 'Sunum katmanı, görünümler şablon olarakda biliniyor.', +'the presentations layer, views are also known as templates': 'sunum katmanı, görünümler şablon olarakda biliniyor.', +'Theme': 'Theme', +'There are no controllers': 'Denetçiler yok', +'There are no models': 'Modeller yok', +'There are no modules': 'Modüller yok', +'There are no plugins': 'Eklentiler yok', +'There are no private files': 'Özel dosyalar yok', +'There are no static files': 'Statik dosyalar yok', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': 'Çeviriler, sadeceön tanmlı dil destekleniyor.', +'There are no views': 'Görünümler yok', +'These files are not served, they are only available from within your app': 'Bu dosyalar servis yapılmıyor, bunlar sadece uygulamanız içerisinden erişilebilir.', +'These files are served without processing, your images go here': 'Bu dosyalarda işlem yapılmadan kaydedildi, resimler buraya gidiyor:', +'these files are served without processing, your images go here': 'bu dosyalarda işlem yapılmadan kaydedildi, resimler buraya gidiyor:', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': 'Bu şablonlar %(filename)s: ', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "Bu sayfa uygulamanızı OpenShif uygulama reposuna koyar. Uygulamanızın web2py iskeleti ile oluşturulduğunuz ve web2py dosya sisteminizdeki ropoya erişilebileceği varsayılmıştır. Bu işlev web2py'nin çalıştığı ortamda GitPython'e ihtiyaç duyar.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'Bu sayfa uygulamanızı Google App Motoru bilişim bulutuna yükleyecektir. İndeksleri yerel olarak oluştırmanız gerektiğini aklınızda tutun, Google uygulama sunucusunu yerel olarak kurup çalıştırın, aksi halde bazı kayıtlarda hatalar olacaktır. Uyarı: yayınlama ağ hızınıza bağlı olarak uzun zaman alabilir. Uyarı: bu sizin app.yaml dosyasını yeniden yazar. LÜTFEN BİRDEN FAZLA GÖNDERMEYİN.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'bu sayfayı, kesme noktasına geldiğini görmek için ve hata ayıklama etkileşmesi gerekiyor..', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': 'Bilet', +'Ticket ID': "Bile ID'si", +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'TM': 'TM', +'to previous version.': 'önceki sürüme.', +'To create a plugin, name a file/folder plugin_[name]': 'Eklenti oluşturmak için dosyayı dosya/klasör plugin_[isim] şeklinde isimlendir. ', +'To emulate a breakpoint programatically, write:': 'Program ile kesme noktasını öykünmek için, yazın:', +'to use the debugger!': 'hata ayıklayıcısını kullanmak için!', +'toggle breakpoint': 'kesme noktasını değiştir', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Tam Ekrana Geç', +'Traceback': 'Nedenin bul', +'translation strings for the application': 'uygulama için çeviri cümleleri', +'Translation strings for the application': 'Uygulama için çeviri cümleleri', +'try': 'dene', +'try something like': 'gibi birşey dene', +'Try the mobile interface': 'Mobil arayüzü dene', +'try view': 'görünümü dene', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Güncellemeler denetlenemiyor', +'unable to create application "%s"': '"%s" uygulaması oluşturulamıyor', +'unable to delete file "%(filename)s"': '"%(filename)s" dosylaları silinemiyor', +'unable to delete file plugin "%(plugin)s"': '"%(plugin)s" eklenti dosyasyaları silenemiyor', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download': 'İndirilemiyor', +'Unable to download app': 'Uygulamanız indirilemiyor', +'Unable to download app because:': 'Uygulamanız indirilemiyor çünkü:', +'Unable to download because': 'İndirilemiyor çünkü:', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': "impossible d'analyser les fichiers CSV", +'unable to uninstall "%s"': 'kladıramıyor çünkü "%s"', +'unable to upgrade because "%s"': 'güncelleyemiyor çünkü "%s"', +'uncheck all': 'tümünü kladır', +'Uninstall': 'Kaldır', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': 'güncelle', +'update all languages': 'tüm delleri yükle', +'Update:': 'Güncelle:', +'Upgrade': 'Upgrade', +'upgrade now': 'şimdi güncelle', +'upgrade now to %s': 'upgrade now to %s', +'upgrade web2py now': "web2py'yi güncelle", +'upload': 'yükle', +'Upload': 'Yükle', +'Upload & install packed application': 'Paketlenmiş uygulamayı yükle ve kur', +'Upload a package:': 'Paket yükle:', +'Upload and install packed application': 'Paketlenmiş uygulamayı yükle ve kur', +'upload application:': 'uygulamayı yükle:', +'Upload existing application': 'Var olan uygulamayı yükle', +'upload file:': 'dosyayı yükle:', +'upload plugin file:': 'eklenti dosyasını yükle:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Karmaşık sorgularda Ve (AND) için (...)&(...) kullanın, Veya (OR) için (...)|(...) kullanın ve DEĞİL (NOT) için ~(...) kullanın. ', +'Use an url:': "Url'yi kullan:", +'user': 'kullanıcı', +'User': 'User', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'değişkenler', +'Version': 'Sürüm', +'Versioning': 'Sürümleme', +'versioning': 'sürümleme', +'view': 'görüntü', +'Views': 'Görüntüler', +'views': 'görüntüler', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Çatısı', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'Yayınlanacak web2py uygulaması', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py güncel', +'web2py online debugger': 'çevirimiçi web2py hata ayıklayıcı', +'web2py Recent Tweets': 'web2py Son Twitler', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py güncellendi, lütfen yeniden başlatın', +'Working...': 'Working...', +'WSGI reference name': 'WSGI referans ismi', +'YES': 'EVET', +'Yes': 'Yes', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': '"kesme noktaları" düğmesini kullanarak düzenleme penceresine geçebilir ve kesme nokatalarını hem ekeleyebilir hemde kaldırabilirsiniz', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'Gelinceye kadar kurmalısınız', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/uk.py b/web2py/applications/admin/languages/uk.py new file mode 100644 index 0000000..e146284 --- /dev/null +++ b/web2py/applications/admin/languages/uk.py @@ -0,0 +1,660 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'uk', +'!langname!': 'Українська', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Оновити" це додатковий вираз, такий, як "field1=\'нове_значення\'". Ви не можете змінювати або вилучати дані об\'єднаних таблиць', +'"User Exception" debug mode. ': 'Режим ладнання "Сигнали від користувачів" ("User Exception" debug mode) ', +'"User Exception" debug mode. An error ticket could be issued!': 'Режим ладнання "Сигнали від користувачів" ("User Exception" debug mode). Користувачі можуть залишати позначки про помилки!', +'%s': '%s', +'%s %%{row} deleted': 'Вилучено %s %%{рядок}', +'%s %%{row} updated': 'Вилучено %s %%{рядок}', +'%s Recent Tweets': '%s %%{останній} %%{твіт}', +'%s selected': '%s selected', +'%s students registered': '%s студентів зареєстровано', +'%Y-%m-%d': '%Y/%m/%d', +'%Y-%m-%d %H:%M:%S': '%Y/%m/%d %H:%M:%S', +'(requires internet access)': '(потрібно мати доступ в інтернет)', +'(requires internet access, experimental)': '(потрібно мати доступ в інтернет, експериментально)', +'(something like "it-it")': '(щось схоже на "uk-ua")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(не існує файлу **gluon/contrib/plural_rules/%s.py**)', +'@markmin\x01An error occured, please [[reload %s]] the page': 'Сталась помилка, будь-ласка [[переватажте %s]] сторінку', +"@markmin\x01Mercurial Version Control System Interface[[NEWLINE]]for application '%s'": "Інтерфейс системи контролю версій Mercurial[[NEWLINE]]для додатку '%s'", +'@markmin\x01Searching: **%s** %%{file}': 'Знайдено: **%s** %%{файл}', +'Abort': 'Припинити', +'About': 'Про', +'about': 'про', +'About application': 'Про додаток', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Додати точку зупинки', +'Additional code for your application': 'Додатковий код для вашого додатку', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': 'адмін.інтерфейс відключено, бо не вказано пароль адміністратора', +'admin disabled because not supported on google app engine': 'адмін.інтерфейс відключено через те, що Google Application Engine його не підтримує', +'admin disabled because too many invalid login attempts': 'адмін.інтерфейс заблоковано, бо кількість хибних спроб входу перевищило граничний рівень', +'admin disabled because unable to access password file': 'адмін.інтерфейс відключено через відсутність доступу до файлу паролів', +'Admin is disabled because insecure channel': "Адмін.інтерфейс відключено через використання ненадійного каналу звя'зку", +'Admin language': 'Мова інтерфейсу:', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'інтерфейс адміністратора', +'Administrator Password:': 'Пароль адміністратора:', +'and rename it:': 'i змінити назву на:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'App does not exist or your are not authorized': 'Додаток не існує, або ви не авторизовані', +'appadmin': 'Aдм.панель', +'appadmin is disabled because insecure channel': "адмін.панель відключено через використання ненадійного каналу зв'язку", +'Application': 'Додаток (Application)', +'application "%s" uninstalled': 'додаток "%s" вилучено', +'application %(appname)s installed with md5sum: %(digest)s': 'додаток %(appname)s встановлено з md5sum: %(digest)s', +'Application cannot be generated in demo mode': 'В демо-режимі генерувати додатки не можна', +'application compiled': 'додаток скомпільовано', +'Application exists already': 'Додаток вже існує', +'application is compiled and cannot be designed': 'додаток скомпільований. налаштування змінювати не можна', +'Application name:': 'Назва додатку:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'не використовуються', +'are not used yet': 'поки що не використовуються', +'Are you sure you want to delete file "%s"?': 'Ви впевнені, що хочете вилучити файл "%s"?', +'Are you sure you want to delete plugin "%s"?': 'Ви впевнені, що хочете вилучити втулку "%s"?"', +'Are you sure you want to delete this object?': "Ви впевнені, що хочете вилучити цей об'єкт?", +'Are you sure you want to uninstall application "%s"?': 'Ви впевнені, що хочете вилучити (uninstall) додаток "%s"?', +'Are you sure?': 'Are you sure?', +'arguments': 'аргументи', +'at char %s': 'на символі %s', +'at line %s': 'в рядку %s', +'ATTENTION:': 'УВАГА:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': "УВАГА: Вхід потребує надійного (HTTPS) з'єднання або запуску на локальному комп'ютері.", +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': 'ОБЕРЕЖНО: ТЕСТУВАННЯ НЕ Є ПОТОКО-БЕЗПЕЧНИМ, ТОЖ НЕ ЗАПУСКАЙТЕ ДЕКІЛЬКА ТЕСТІВ ОДНОЧАСНО.', +'ATTENTION: you cannot edit the running application!': 'УВАГА: Ви не можете редагувати додаток, який зараз виконуєте!', +'Autocomplete Python Code': 'Автозавершення коду на Python', +'Available databases and tables': 'Доступні бази даних та таблиці', +'Available Databases and Tables': 'Available Databases and Tables', +'back': '<< назад', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'bad_resource': 'поганий_ресурс', +'Basics': 'Початок', +'Begin': 'Початок', +'breakpoint': 'точку зупинки', +'Breakpoints': 'Точки зупинок', +'breakpoints': 'точки зупинок', +'Bulk Register': 'Масова реєстрація', +'Bulk Student Registration': 'Масова реєстрація студентів', +'Cache': 'Cache', +'cache': 'кеш', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Ключі кешу', +'cache, errors and sessions cleaned': 'кеш, список зареєстрованих помилок та сесії очищенні', +'can be a git repo': 'може бути git-репозитарієм', +'Cancel': 'Відмінити', +'Cannot be empty': 'Не може бути порожнім', +'Cannot compile: there are errors in your app:': 'Не вдається скомпілювати: є помилки у вашому додатку:', +'cannot create file': 'не можу створити файл', +'cannot upload file "%(filename)s"': 'не можу завантажити файл "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'Змінити пароль адміністратора', +'change editor settings': 'змінити налаштування редактора', +'Changelog': 'Changelog', +'check all': 'відмітити всі', +'Check for upgrades': 'Перевірити оновлення', +'Check to delete': 'Помітити на вилучення', +'Checking for upgrades...': 'Відбувається пошук оновлень...', +'Clean': 'Очистити', +'Clear': 'Clear', +'Clear CACHE?': 'Очистити ВЕСЬ кеш?', +'Clear DISK': 'Очистити ДИСКОВИЙ КЕШ', +'Clear RAM': "Очистити КЕШ В ПАМ'ЯТІ", +'Click row to expand traceback': '"Клацніть" мишкою по рядку, щоб розгорнути стек викликів (traceback)', +'Click row to view a ticket': 'Для перегляду позначки (ticket) "клацніть" мишкою по рядку', +'code': 'код', +'Code listing': 'Лістинг', +'collapse/expand all': 'згорнути/розгорнути все', +'Command': 'Команда', +'Comment:': 'Пояснення:', +'Commit': 'Комміт', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': 'Компілювати', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': 'скомпільований додаток вилучено', +'Condition': 'Умова', +'contact_admin': "зв'язатись_з_адміністратором", +'continue': 'продовжити', +'Controllers': 'Контролери', +'controllers': 'контролери', +'Count': 'К-сть', +'Create': 'Створити', +'create': 'створити', +'create file with filename:': 'створити файл з назвою:', +'create plural-form': 'створити форму множини', +'Create rules': 'Створити правила', +'Create/Upload': 'Створити/Завантажити', +'created by': 'Автор:', +'Created by:': 'Created by:', +'Created On': 'Створено в', +'Created on:': 'Created on:', +'crontab': 'таблиця cron', +'Current request': 'Поточний запит', +'Current response': 'Поточна відповідь', +'Current session': 'Поточна сесія', +'currently running': 'наразі, активний додаток', +'currently saved or': 'останній збережений, або', +'data uploaded': 'дані завантажено', +'Database': 'Database', +'database': 'база даних', +'Database %s select': 'Database %s select', +'database %s select': 'Вибірка з бази даних %s', +'Database administration': 'Database administration', +'database administration': 'адміністрування бази даних', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': 'Дата і час', +'db': 'база даних', +'Debug': 'Ладнати (Debug)', +'defines tables': "об'являє таблиці", +'Delete': 'Вилучити', +'delete': 'вилучити', +'delete all checked': 'вилучити всі відмічені', +'delete plugin': 'вилучити втулку', +'Delete this file (you will be asked to confirm deletion)': 'Вилучити цей файл (буде відображено запит на підтвердження операції)', +'Delete:': 'Вилучити:', +'deleted after first hit': 'автоматично вилучається після першого спрацювання', +'Demo': 'Demo', +'Deploy': 'Розгорнути', +'Deploy on Google App Engine': 'Розгорнути на Google App Engine (GAE)', +'Deploy to OpenShift': 'Розгорнути на OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Форма розгортання (deployment form)', +'Deployment Interface': 'Deployment Interface', +'Description:': 'Description:', +'design': 'налаштування', +'Detailed traceback description': 'Детальний опис стеку викликів (traceback)', +'details': 'детальніше', +'direction: ltr': 'напрямок: зліва-направо (ltr)', +'directory not found': 'каталог не знайдено', +'Disable': 'Вимкнути', +'Disabled': 'Вимкнено', +'disabled in demo mode': 'відключено в демо-режимі', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'відключено в багато-користувацькому режимі', +'DISK': 'DISK', +'Disk Cache Keys': 'Ключі дискового кешу', +'Disk Cleared': 'Дисковий кеш очищено', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'док.', +'Docs': 'Docs', +'done!': 'зроблено!', +'Downgrade': 'Повернути попередню версію', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'завантажити макет (layout)', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'завантажити втулки', +'Download plugins from repository': 'Download plugins from repository', +'Edit': 'Редагувати', +'edit all': 'редагувати всі', +'Edit application': 'Налаштування додатку', +'edit controller': 'редагувати контролер', +'edit controller:': 'редагувати контролер:', +'Edit current record': 'Редагувати поточний запис', +'edit views:': 'редагувати відображення (views):', +'Editing %s': 'Редагується %s', +'Editing file "%s"': 'Редагується файл "%s"', +'Editing Language file': 'Редагується файл перекладу', +'Editing Plural Forms File': 'Редагується файл форм множини', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Увімкнути', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'enter a value': 'введіть значення', +'Error': 'Помилка', +'Error logs for "%(app)s"': 'Список зареєстрованих помилок додатку "%(app)s"', +'Error snapshot': 'Розгорнутий знімок стану (Error snapshot)', +'Error ticket': 'Позначка (ticket) про помилку', +'Errors': 'Помилки', +'Errors in form, please check it out.': 'Помилка у формі, будь-ласка перевірте її.', +'Exception %(extype)s: %(exvalue)s': 'Виключення %(extype)s: %(exvalue)s', +'Exception %s': 'Виключення %s', +'Exception instance attributes': 'Атрибути примірника класу Exception (виключення)', +'Exit Fullscreen': 'Вийти з повноекранного режиму', +'Expand Abbreviation': 'Розгорнути абревіатуру', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': 'експортувати як файл csv', +'Exports:': 'Exports:', +'exposes': 'обслуговує', +'exposes:': 'обслуговує:', +'extends': 'розширює', +'failed to compile file because:': 'не вдалось скомпілювати файл через:', +'failed to reload module because:': 'не вдалось перевантажити модуль через:', +'faq': 'ЧаПи (faq)', +'File': 'Файл', +'file "%(filename)s" created': 'файл "%(filename)s" створено', +'file "%(filename)s" deleted': 'файл "%(filename)s" вилучено', +'file "%(filename)s" uploaded': 'файл "%(filename)s" завантажено', +'file "%s" of %s restored': 'файл "%s" з %s відновлено', +'file changed on disk': 'файл змінено на диску', +'file does not exist': 'файлу не існує', +'file not found': 'файл не знайдено', +'file saved on %(time)s': 'файл збережено в %(time)s', +'file saved on %s': 'файл збережено в %s', +'filename': 'filename', +'Filename': "Ім'я файлу", +'Files added': 'Files added', +'filter': 'фільтр', +'Find Next': 'Шукати наступний', +'Find Previous': 'Шукати попередній', +'Form has errors': 'Form has errors', +'Frames': 'Стек викликів', +'Functions with no doctests will result in [passed] tests.': 'Функції, в яких відсутні док-тести відносяться до функцій, які успішно пройшли тести.', +'GAE Email': 'Ел.пошта GAE', +'GAE Output': 'Відповідь GAE', +'GAE Password': 'Пароль GAE', +'Generate': 'Генерувати', +'Get from URL:': 'Отримати з URL:', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Глобальні змінні', +'Go to Matching Pair': 'Перейти до відповідної пари', +'go!': 'почали!', +'Google App Engine Deployment Interface': 'Інтерфейс розгортання Google App Engine', +'Google Application Id': 'Ідентифікатор Google Application', +'Goto': 'Перейти до', +'graph model': 'графова модель', +'Graph Model': 'Graph Model', +'Help': 'Допомога', +'here': 'here', +'Hide/Show Translated strings': 'Сховати/показати ВЖЕ ПЕРЕКЛАДЕНІ рядки', +'Highlight current line': 'Highlight current line', +'Hits': 'Спрацьовувань', +'Home': 'Домівка', +'honored only if the expression evaluates to true': 'точка зупинки активується тільки за істинності умови', +'If start the downgrade, be patient, it may take a while to rollback': 'Запустивши повернення на попередню версію, будьте терплячими, це може зайняти трохи часу', +'If start the upgrade, be patient, it may take a while to download': 'Запустивши оновлення, будьте терплячими, потрібен час для завантаження необхідних даних', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'Якщо в наданому вище звіті присутня позначка про помилку (ticket number), то це вказує на збій у виконанні контролера ще до початку запуску док-тестів. Це, зазвичай, сигналізує про помилку вирівнювання тексту програми (indention error) або помилку за межами функції (error outside function code).\n\t\tЗелений заголовок сигналізує, що всі тести (з наявних) пройшли успішно. В цьому випадку результат тестів показано не буде.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': 'Імпорт/Експорт', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'Під час розробки , використовуйте вбудований веб-сервер Rocket, він найкраще налаштований на спільну роботу з інтерактивним ладначем.', +'includes': 'включає', +'Indent with tabs': 'Indent with tabs', +'index': 'індекс', +'insert new': 'вставити новий', +'insert new %s': 'вставити новий %s', +'inspect attributes': 'інспектувати атрибути', +'Install': 'Встановлення', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': 'Встановлені додатки (applications)', +'Interaction at %s line %s': 'Виконується %s рядок %s', +'Interactive console': 'Інтерактивна консоль', +'internal error': 'внутрішня помилка', +'internal error: %s': 'внутрішня помилка: %s', +'Internal State': 'Внутрішній стан', +'Invalid action': 'Помилкова дія', +'Invalid application name': 'Invalid application name', +'invalid circual reference': 'помилкове циклічне посилання', +'invalid circular reference': 'помилкове циклічне посилання', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': 'неправильний пароль', +'invalid password.': 'неправильний пароль.', +'Invalid Query': 'Помилковий запит', +'invalid request': 'хибний запит', +'Invalid request': 'Invalid request', +'invalid request ': 'Хибний запит', +'invalid table names (auth_* tables already defined)': 'хибна назва таблиці (таблиці auth_* вже оголошено)', +'invalid ticket': 'недійсна позначка про помилку (ticket)', +'Key': 'Ключ', +'Key bindings': 'Клавіатурні скорочення:', +'Key bindings for ZenCoding Plugin': 'Клавіатурні скорочення для втулки ZenCoding plugin', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'вбити процес', +'language file "%(filename)s" created/updated': 'Файл перекладу "%(filename)s" створено/оновлено', +'Language files (static strings) updated': 'Файли перекладів (із статичних рядків в першоджерелах) оновлено', +'languages': 'переклади', +'Languages': 'Переклади', +'Last Revision': 'Last Revision', +'Last saved on:': 'Востаннє збережено:', +'License for': 'Ліцензія додатку', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': '№ рядка', +'LineNo': '№ рядка', +'lists by exception': 'список виключень (exceptions)', +'lists by ticket': 'список позначок (tickets)', +'Loading...': 'Loading...', +'loading...': 'завантаження...', +'Local Apps': 'Local Apps', +'locals': 'локальні', +'Locals##debug': 'Локальні змінні', +'Login': 'Вхід', +'login': 'вхід', +'Login successful': 'Login successful', +'Login to the Administrative Interface': 'Вхід в адміністративний інтерфейс', +'Login/Register': 'Login/Register', +'Logout': 'Вихід', +'lost password': 'lost password', +'Main Menu': 'Основне меню', +'Manage': 'Керувати', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Адміністратор керування користувачами/студентами', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Керувати студентами', +'Match Pair': 'Знайти пару', +'Memberships': 'Memberships', +'merge': "з'єднати", +'Merge Lines': "З'єднати рядки", +'Minimum length is %s': 'Мінімальна довжина становить %s', +'Models': 'Моделі', +'models': 'моделі', +'Modified On': 'Змінено в', +'Modules': 'Модулі', +'modules': 'модулі', +'Multi User Mode': 'Multi User Mode', +'Must include at least %s %s': 'Має вміщувати щонайменше %s %s', +'Must include at least %s lowercase': 'Повинен включати щонайменше %s малих букв', +'Must include at least %s of the following : %s': 'Має включати не менше %s таких символів : %s', +'Must include at least %s uppercase': 'Повинен включати щонайменше %s великих букв', +'new application "%s" created': 'новий додаток "%s" створено', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'Майстер створення нового додатку', +'New application wizard': 'Майстер створення нового додатку', +'new plugin installed': 'нова втулка (plugin) встановлена', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': 'Новий запис', +'new record inserted': 'новий рядок додано', +'New simple application': 'Новий простий додаток', +'next': 'наступний', +'next %s rows': 'next %s rows', +'next 100 rows': 'наступні 100 рядків', +'Next Edit Point': 'Наступне місце редагування', +'NO': 'НІ', +'no changes': 'no changes', +'No databases in this application': 'Даний додаток не використовує бази даних', +'No Interaction yet': 'Ладнач не активовано', +'no match': 'співпадань нема', +'no package selected': 'пакет не вибрано', +'no permission to uninstall "%s"': 'нема прав на вилучення (uninstall) "%s"', +'No ticket_storage.txt found under /private folder': 'В каталозі /private відсутній файл ticket_storage.txt', +'Node:': 'Node:', +'Not Authorized': 'Не дозволено', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Примітка: Якщо ви отримали повідомлення про помилку з кодом стану github рівним 128, переконайтесь, що система та обліковий запис, з якого відбувається розгортання використовують відповідний ключ ssh, налаштований в обліковому записі openshift.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": 'У промисловій експлуатації, ви повинні налаштувати ваш веб-сервер на використання одного процесу та багатьох потоків, якщо бажаєте скористатись цим ладначем.', +'online designer': 'дизайнер БД', +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift: Інтерфейс розгортання', +'OpenShift Output': 'Вивід OpenShift', +'or alternatively': 'або альтернативно', +'Or Get from URL:': 'Або Отримати з мережі (ч/з URL):', +'or import from csv file': 'або імпортувати через csv-файл', +'Original/Translation': 'Оригінал/переклад', +'Overview': 'Overview', +'Overwrite installed app': 'Перезаписати встановлений додаток', +'Pack all': 'Пакувати все', +'Pack compiled': 'Пакувати зкомпільоване', +'Pack custom': 'Пакувати вибране', +'pack plugin': 'запакувати втулку', +'PAM authenticated user, cannot change password here': 'Ввімкнена система ідентифікації користувачів PAM. Для зміни паролю скористайтесь командами вашої ОС ', +'password changed': 'пароль змінено', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Шлях до appcfg.py', +'Path to local openshift repo root.': 'Шлях до локального корня репозитарія openshift.', +'peek': 'глянути', +'Peeking at file': 'Перегляд файлу', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Будь-ласка', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin': 'втулка', +'plugin "%(plugin)s" deleted': 'втулку "%(plugin)s" вилучено', +'Plugin "%s" in application': 'Втулка "%s" в додатку', +'plugin not specified': 'втулку не визначено', +'Plugin page': 'Plugin page', +'plugins': 'втулки (plugins)', +'Plugins': 'Втулки (Plugins)', +'Plural Form #%s': 'Форма множини #%s', +'Plural-Forms:': 'Форми множини:', +'Powered by': 'Працює на', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': 'попередні 100 рядків', +'Previous Edit Point': 'Попереднє місце редагування', +'Private files': 'Приватні файли', +'private files': 'приватні файли', +'Project Progress': 'Поступ проекту', +'Pull': 'Втягнути', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Проштовхнути', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': 'Запит:', +'RAM': 'RAM', +'RAM Cache Keys': 'Ключ ОЗП-кешу (RAM Cache)', +'Ram Cleared': "Кеш в пам'яті очищено", +'Rapid Search': 'Миттєвий пошук', +'Record': 'Record', +'record': 'запис', +'record does not exist': 'запису не існує', +'record id': 'Ід.запису', +'Record id': 'Record id', +'refresh': 'оновіть', +'register': 'register', +'reload': 'перевантажити', +'Reload routes': 'Перезавантажити маршрути', +'Remove compiled': 'Вилуч.компл', +'Removed Breakpoint on %s at line %s': 'Вилучено точку зупинки у %s в рядку %s', +'Replace': 'Замінити', +'Replace All': 'Замінити все', +'Repository (%s)': 'Repository (%s)', +'request': 'запит', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'Для розгортання необхідний пакет python-git, але він не встановлений', +'resolve': "розв'язати", +'Resolve Conflict file': "Файл розв'язування конфлікту", +'response': 'відповідь', +'restart': 'перезапустити майстра', +'restore': 'повернути', +'return': 'повернутись', +'Revert': 'Revert', +'revert': 'відновитись', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': 'Role', +'Roles': 'Roles', +'Rows in Table': 'Rows in Table', +'Rows in table': 'Рядків у таблиці', +'Rows selected': 'Рядків вибрано', +'rules are not defined': 'правила не визначені', +'rules parsed with errors': 'в правилах є помилка', +'rules:': 'правила:', +'Run tests': 'Запустити всі тести', +'Run tests in this file': 'Запустити тести у цьому файлі', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Запустити тести з цього файлу (для тестування всіх файлів, вам необхідно натиснути кнопку з назвою 'тестувати всі')", +'Running on %s': 'Запущено на %s', +'runonce': 'одноразово', +'Save': 'Зберегти', +'Save file:': 'Зберегти файл:', +'Save file: %s': 'Зберегти файл: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'зберегти через Ajax', +'Saved file hash:': 'Хеш збереженого файлу:', +'Screenshot %s': 'Screenshot %s', +'search': 'пошук', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'selected': 'відмічено', +'session': 'сесія', +'session expired': 'час даної сесії вичерпано', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Додано точку зупинки в %s на рядок %s: %s', +'shell': 'консоль', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'signup': 'підписатись', +'signup_requested': 'необхідна_реєстрація', +'Singular Form': 'Форма однини', +'site': 'сайт', +'Site': 'Сайт', +'Size of cache:': 'Size of cache:', +'skip to generate': 'перейти до генерування результату', +'some files could not be removed': 'деякі файли не можна вилучити', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Не вдалось виявити встановлену систему контролю версій Mercurial', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Створюється новий додаток', +'Start searching': 'Розпочати пошук', +'Start wizard': 'Активувати майстра', +'state': 'стан', +'Static': 'Статичні', +'static': 'статичні', +'Static files': 'Статичні файли', +'Statistics': 'Statistics', +'Step': 'Крок', +'step': 'крок', +'stop': 'зупинити', +'submit': 'застосувати', +'Submit': 'Застосувати', +'successful': 'успішно', +'switch to : db': 'перемкнути на : БД', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': 'таблиця', +'Table': 'Table', +'tags': 'мітки (tags)', +'Temporary': 'Тимчасово', +'test': 'тестувати всі', +'Testing application': 'Тестування додатку', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"Запит" це умова, на зразок "db.table1.field1==\'значення\'". Вираз "db.table1.field1==db.table2.field2" повертає результат об\'єднання (SQL JOIN) таблиць.', +'The app exists, was created by wizard, continue to overwrite!': 'Додаток вже існує і його було створено майстром. Продовжуємо переписування!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'Додаток вже існує, і його НЕ було створено майстром. Продовжуємо перезаписування!', +'The application logic, each URL path is mapped in one exposed function in the controller': 'Логіка додатку, кожний шлях URL проектується на одну з функцій обслуговування в контролері', +'The data representation, define database tables and sets': 'Представлення даних, опис таблиць БД та наборів', +'The presentations layer, views are also known as templates': 'Презентаційний рівень, відображення, відомі також як шаблони', +'Theme': 'Theme', +'There are no controllers': 'Жодного контролера, наразі, не існує', +'There are no models': 'Моделей, наразі, нема', +'There are no modules': 'Модулів поки що нема', +'There are no plugins': 'Жодної втулки, наразі, не встановлено', +'There are no private files': 'Приватних файлів поки що нема', +'There are no static files': 'Статичних файлів, наразі, нема', +'There are no translators': 'Перекладів нема', +'There are no translators, only default language is supported': 'Перекладів нема, підтримується тільки мова оригіналу', +'There are no views': 'Відображень нема', +'These files are not served, they are only available from within your app': 'Ці файли ніяк не обробляються, вони доступні тільки в межах вашого додатку', +'These files are served without processing, your images go here': 'Ці файли обслуговуються "як є", без обробки, ваші графічні файли та інші супутні файли даних можуть знаходитись тут', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": 'Цей ладнач може працювати некоректно, якщо ви використовуєте веб-сервер без підтримки потоків або використовуєте декілька сервісних процесів.', +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'Це експериментальна властивість, яка вимагає подальшого тестування. Якщо ви вирішили повернутись на попередню версію, ви це робити на ваш власний розсуд.', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'Це експериментальна властивість, яка вимагає подальшого тестування. Якщо ви вирішили розпочати оновлення, ви це робите на ваш власний розсуд', +'This is the %(filename)s template': 'Це шаблон %(filename)s', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": 'На цій сторінці можна закомітити ваші зміни в репозитарій додатків openshift та проштовхнути їх у ваш примірник в хмарі. Це передбачає, що ви вже створили примірник додатку, використовуючи базовий додаток web2py, як скелет, і маєте репозитарій десь на вашій файловій системі, причому екземпляр web2py має до нього доступ. Ця властивість вимагає наявності встановленого модулю GitPython так, щоб web2py міг його викликати.', +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'На цій сторінці ви можете завантажити свій додаток в сервіс хмарних обчислень Google App Engine. Майте на увазі, що спочатку необхідно локально створити індекси, і це можна зробити встановивши сервер додатків Google appserver та запустивши в ньому додаток один раз, інакше при виборі записів виникатимуть помилки. Увага: розгортання може зайняти тривалий час, в залежності від швидкості мережі. Увага: це призведе до перезапису app.yaml. НЕ ПУБЛІКУЙТЕ ДВІЧІ.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'цю сторінку, щоб побачити, чи була досягнута точка зупинки і процес ладнання розпочато.', +'This will pull changes from the remote repo for application "%s"?': '"Втягнути" (pull) зміни з віддаленого репозитарію для додатку "%s"?', +'This will push changes to the remote repo for application "%s".': 'Проштовхнути (push) зміни у віддалений репозитарій для додатку "%s"?', +'ticket': 'позначка', +'Ticket': 'Позначка (Ticket)', +'Ticket ID': 'Ід.позначки (Ticket ID)', +'Ticket Missing': 'Позначка (ticket) відсутня', +'tickets': 'позначки (tickets)', +'Time in Cache (h:m:s)': 'Час в кеші (г:хв:сек)', +'to previous version.': 'до попередньої версії.', +'To create a plugin, name a file/folder plugin_[name]': 'Для створення втулки, назвіть файл/каталог plugin_[name]', +'To emulate a breakpoint programatically, write:': 'Для встановлення точки зупинки програмним чином напишіть:', +'to use the debugger!': 'щоб активувати ладнач!', +'toggle breakpoint': '+/- точку зупинки', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Перемкнути на весь екран', +'Traceback': 'Стек викликів (Traceback)', +'Translation strings for the application': 'Пари рядків <оригінал>:<переклад> для вибраної мови', +'try something like': 'спробуйте щось схоже на', +'Try the mobile interface': 'Спробуйте мобільний інтерфейс', +'try view': 'дивитись результат', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'наберіть тут будь-які команди ладнача PDB і натисніть клавішу [Return] ([Enter]), щоб запустити їх на виконання.', +'Type python statement in here and hit Return (Enter) to execute it.': 'Наберіть тут будь-які вирази Python і натисніть клавішу [Return] ([Enter]), щоб запустити їх на виконання.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': 'Неможливо перевірити оновлення', +'unable to create application "%s"': 'не можу створити додаток "%s"', +'unable to create application "%s" (it may exist already)': 'не можу створити додаток "%s" (можливо його вже створено)', +'unable to delete file "%(filename)s"': 'не можу вилучити файл "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'не можу вилучити файл втулки "%(plugin)s"', +'Unable to determine the line number!': 'Не можу визначити номер рядка!', +'Unable to download app because:': 'Не можу завантажити додаток через:', +'Unable to download because:': 'Неможливо завантажити через:', +'unable to download layout': 'не вдається завантажити макет', +'unable to download plugin: %s': 'не вдається завантажити втулку: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install application "%(appname)s"': 'не вдається встановити додаток "%(appname)s"', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': 'не вдається розібрати csv-файл', +'unable to uninstall "%s"': 'не вдається вилучити "%s"', +'unable to upgrade because "%s"': 'не вдається оновити, тому що "%s"', +'unauthorized': 'неавторизовано', +'uncheck all': 'зняти відмітку з усіх', +'uninstall': 'вилучити', +'Uninstall': 'Вилучити', +'Unsupported webserver working mode: %s': 'Веб-сервер знаходиться в режимі, який не підтримується: %s', +'update': 'оновити', +'update all languages': 'оновити всі переклади', +'Update:': 'Поновити:', +'Upgrade': 'Оновити', +'upgrade now': 'оновитись зараз', +'upgrade now to %s': 'оновити зараз до %s', +'upgrade_web2py': 'оновити web2py', +'upload': 'завантажити', +'Upload': 'Завантажити', +'Upload a package:': 'Завантажити пакет:', +'Upload and install packed application': 'Завантажити та встановити запакований додаток', +'upload file:': 'завантажити файл:', +'upload plugin file:': 'завантажити файл втулки:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Для створення складних запитів використовуйте (...)&(...) замість AND, (...)|(...) замість OR, та ~(...) замість NOT.', +'user': 'користувач', +'User': 'User', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Використання оболонки може заблокувати базу даних від сумісного використання іншими користувачами цього додатку.', +'value not allowed': 'недопустиме значення', +'variables': 'змінні', +'Version': 'Версія', +'Version %s.%s.%s (%s) %s': 'Версія %s.%s.%s (%s) %s', +'Versioning': 'Контроль версій', +'view': 'перегляд', +'Views': 'Відображення (Views)', +'views': 'відображення', +'Warning!': 'Warning!', +'WARNING:': 'ПОПЕРЕДЖЕННЯ:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Веб-каркас (Web Framework)', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'Готові до розгортання додатки web2py', +'web2py Debugger': 'Ладнач web2py', +'web2py downgrade': 'повернення на попередню версію web2py', +'web2py is up to date': 'web2py оновлено до актуальної версії', +'web2py online debugger': 'оперативний ладнач (online debugger) web2py', +'web2py Recent Tweets': 'Останні твіти web2py', +'web2py upgrade': 'оновлення web2py', +'web2py upgraded; please restart it': 'web2py оновлено; будь-ласка перезапустіть його', +'Working...': 'Working...', +'Wrap with Abbreviation': 'Загорнути з абревіатурою', +'WSGI reference name': "ім'я посилання WSGI", +'YES': 'ТАК', +'Yes': 'Yes', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'Ви також можете встановлювати/вилучати точки зупинок під час редагування першоджерел (sources), використовуючи кнопку "+/- точку зупинки"', +'You can inspect variables using the console bellow': 'Ви можете досліджувати змінні, використовуючи інтерактивну консоль', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'У вас є ще одна спроба перед тим, як вхід буде заблоковано', +'you must specify a name for the uploaded application': "ви повинні вказати ім'я додатка, перед ти, як завантажити його", +'You need to set up and reach a': 'Треба встановити та досягнути', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Ваш додаток буде заблоковано, поки ви не клацнете по одній з кнопок керування ("наступний", "крок", "продовжити", та ін.)', +} diff --git a/web2py/applications/admin/languages/zh-tw.py b/web2py/applications/admin/languages/zh-tw.py new file mode 100644 index 0000000..b8d564f --- /dev/null +++ b/web2py/applications/admin/languages/zh-tw.py @@ -0,0 +1,682 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'zh-tw', +'!langname!': '台灣中文', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"更新" 是選擇性的條件式, 格式就像 "欄位1=\'值\'". 但是 JOIN 的資料不可以使用 update 或是 delete"', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '已刪除 %s 筆', +'%s %%{row} updated': '已更新 %s 筆', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(格式類似 "zh-tw")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files', +'A new version of web2py is available': '新版的 web2py 已發行', +'A new version of web2py is available: %s': '新版的 web2py 已發行: %s', +'Abort': 'Abort', +'About': '關於', +'About application': '關於本應用程式', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Add breakpoint', +'additional code for your application': '應用程式額外的程式碼', +'Additional code for your application': 'Additional code for your application', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': '管理介面關閉原因是沒有設定管理員密碼 ', +'admin disabled because not supported on google app engine': '管理介面關閉原因是不支援在google apps engine環境下運作', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': '管理介面關閉原因是無法存取密碼檔', +'Admin is disabled because insecure channel': '管理功能(Admin)在不安全連線環境下自動關閉', +'Admin is disabled because unsecure channel': '管理功能(Admin)在不安全連線環境下自動關閉', +'Admin language': 'Admin language', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'administrative interface', +'Administrator Password:': '管理員密碼:', +'amy_ajax': 'amy_ajax', +'and rename it (required):': '同時更名為(必要的):', +'and rename it:': '同時更名為:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': '應用程式管理員', +'appadmin is disabled because insecure channel': '管理介面關閉理由是連線方式不安全', +'Application': 'Application', +'application "%s" uninstalled': '已移除應用程式 "%s"', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': '已編譯應用程式', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': '應用程式已經編譯無法重新設計', +'Application name:': 'Application name:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'are not used', +'are not used yet': 'are not used yet', +'Are you sure you want to delete file "%s"?': '確定要刪除檔案"%s"?', +'Are you sure you want to delete plugin "%s"?': '確定要刪除插件 "%s"?', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Are you sure you want to uninstall application "%s"': '確定要移除應用程式 "%s"', +'Are you sure you want to uninstall application "%s"?': '確定要移除應用程式 "%s"', +'Are you sure you want to upgrade web2py now?': '確定現在要升級 web2py?', +'Are you sure?': 'Are you sure?', +'arguments': 'arguments', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': '注意: 登入管理帳號需要安全連線(HTTPS)或是在本機連線(localhost).', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': '注意: 因為在測試模式不保證多執行緒安全性,也就是說不可以同時執行多個測試案例', +'ATTENTION: you cannot edit the running application!': '注意:不可編輯正在執行的應用程式!', +'Authentication': '驗證', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available databases and tables': '可提供的資料庫和資料表', +'Available Databases and Tables': 'Available Databases and Tables', +'back': '回復(back)', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'Begin': 'Begin', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': '快取記憶體', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': '快取記憶體,錯誤紀錄,連線紀錄已清除', +'can be a git repo': 'can be a git repo', +'Cancel': 'Cancel', +'Cannot be empty': '不可空白', +'Cannot compile: there are errors in your app. Debug it, correct errors and try again.': '無法編譯:應用程式中含有錯誤,請除錯後再試一次.', +'Cannot compile: there are errors in your app:': '無法編譯: 在你的應用程式存在錯誤:', +'cannot create file': '無法創建檔案', +'cannot upload file "%(filename)s"': '無法上傳檔案 "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'change admin password', +'change editor settings': 'change editor settings', +'Change Password': '變更密碼', +'change_password': '變更密碼', +'Changelog': 'Changelog', +'check all': '全選', +'Check for upgrades': 'Check for upgrades', +'Check to delete': '打勾代表刪除', +'Check to delete:': '打勾代表刪除:', +'Checking for upgrades...': '檢查新版本中...', +'Clean': '清除', +'Clear': 'Clear', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'click here for online examples': '點此處進入線上範例', +'click here for the administrative interface': '點此處進入管理介面', +'Click row to expand traceback': 'Click row to expand traceback', +'Click row to view a ticket': 'Click row to view a ticket', +'click to check for upgrades': '點擊打勾以便升級', +'Client IP': '客戶端網址(IP)', +'code': 'code', +'Code listing': 'Code listing', +'collapse/expand all': 'collapse/expand all', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': '編譯', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': '已移除已編譯的應用程式', +'Condition': 'Condition', +'continue': 'continue', +'Controller': '控件', +'Controllers': '控件', +'controllers': '控件', +'Copyright': '版權所有', +'Count': 'Count', +'Create': '創建', +'create file with filename:': '創建檔案:', +'create new application:': '創建新應用程式:', +'Create new simple application': '創建應用程式', +'Create/Upload': 'Create/Upload', +'created by': '創建自', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': '定時執行表', +'Current request': '目前網路資料要求(request)', +'Current response': '目前網路資料回應(response)', +'Current session': '目前網路連線資訊(session)', +'currently running': 'currently running', +'currently saved or': '現在存檔或', +'customize me!': '請調整我!', +'data uploaded': '資料已上傳', +'Database': '資料庫', +'database': '資料庫', +'Database %s select': 'Database %s select', +'database %s select': '已選擇 %s 資料庫', +'Database administration': 'Database administration', +'database administration': '資料庫管理', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': '日期和時間', +'db': 'db', +'DB Model': '資料庫模組', +'Debug': 'Debug', +'defines tables': '定義資料表', +'Delete': '刪除', +'delete': '刪除', +'delete all checked': '刪除所有已選擇項目', +'delete plugin': '刪除插件', +'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)', +'Delete:': '刪除:', +'delete_plugin': '刪除插件', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'Deploy', +'Deploy on Google App Engine': '配置到 Google App Engine', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description': '描述', +'Description:': 'Description:', +'design': '設計', +'DESIGN': '設計', +'Design for': '設計為了', +'Detailed traceback description': 'Detailed traceback description', +'details': 'details', +'direction: ltr': 'direction: ltr', +'directory not found': 'directory not found', +'Disable': 'Disable', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'docs', +'Docs': 'Docs', +'done!': '完成!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'download layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'download plugins', +'Download plugins from repository': 'Download plugins from repository', +'E-mail': '電子郵件', +'EDIT': '編輯', +'Edit': '編輯', +'edit all': 'edit all', +'Edit application': '編輯應用程式', +'edit controller': '編輯控件', +'edit controller:': 'edit controller:', +'Edit current record': '編輯當前紀錄', +'Edit Profile': '編輯設定檔', +'Edit This App': '編輯本應用程式', +'edit views:': '編輯視圖', +'edit_language': '編輯語言檔', +'Editing %s': 'Editing %s', +'Editing file': '編輯檔案', +'Editing file "%s"': '編輯檔案"%s"', +'Editing Language file': '編輯語言檔案', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Enable', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Enterprise Web Framework': '企業網站平台', +'Error': 'Error', +'Error logs for "%(app)s"': '"%(app)s"的錯誤紀錄', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Error ticket', +'Errors': '錯誤紀錄', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Exception instance attributes', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': '以逗號分隔檔(csv)格式匯出', +'Exports:': 'Exports:', +'exposes': '外顯', +'exposes:': 'exposes:', +'extends': '擴展', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module because:': '因為下列原因無法重新載入程式模組:', +'File': 'File', +'file "%(filename)s" created': '檔案 "%(filename)s" 已創建', +'file "%(filename)s" deleted': '檔案 "%(filename)s" 已刪除', +'file "%(filename)s" uploaded': '檔案 "%(filename)s" 已上傳', +'file "%s" of %s restored': '檔案 %s 的 "%s" 已回存', +'file changed on disk': '在磁碟上檔案已改變', +'file does not exist': '檔案不存在', +'file not found': 'file not found', +'file saved on %(time)s': '檔案已於 %(time)s 儲存', +'file saved on %s': '檔案在 %s 已儲存', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'filter', +'Find Next': 'Find Next', +'Find Previous': 'Find Previous', +'First name': '名', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': '沒有 doctests 的函式會顯示 [passed].', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Group ID': '群組編號', +'Hello World': '嗨! 世界', +'Help': '說明檔', +'here': 'here', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'htmledit': 'html編輯', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': '匯入/匯出', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': '包含', +'Indent with tabs': 'Indent with tabs', +'Index': '索引', +'index': '索引', +'insert new': '插入新資料', +'insert new %s': '插入新資料 %s', +'inspect attributes': 'inspect attributes', +'Install': '安裝', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': '已安裝應用程式', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': '內部錯誤', +'internal error: %s': 'internal error: %s', +'Internal State': '內部狀態', +'Invalid action': '不合法的動作(action)', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid email': '不合法的電子郵件', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': '密碼錯誤', +'invalid password.': 'invalid password.', +'Invalid Query': '不合法的查詢', +'invalid request': '不合法的網路要求(request)', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': '不合法的問題單號', +'Key': 'Key', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': '語言檔"%(filename)s"已創建或更新', +'Language files (static strings) updated': '語言檔已更新', +'languages': '語言檔', +'Languages': '各國語言', +'Last name': '姓', +'Last Revision': 'Last Revision', +'Last saved on:': '最後儲存時間:', +'Layout': '網頁配置', +'License for': '許可證', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Loading...': 'Loading...', +'loading...': '載入中...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'login': '登入', +'Login': '登入', +'Login successful': 'Login successful', +'Login to the Administrative Interface': '登入到管理員介面', +'Login/Register': 'Login/Register', +'Logout': '登出', +'Lost Password': '密碼遺忘', +'lost password': 'lost password', +'Main Menu': '主選單', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Memberships': 'Memberships', +'Menu Model': '選單模組(menu)', +'merge': '合併', +'Models': '資料模組', +'models': '資料庫模組', +'Modified On': 'Modified On', +'Modules': '程式模組', +'modules': '程式模組', +'Multi User Mode': 'Multi User Mode', +'Name': '名字', +'new application "%s" created': '已創建新的應用程式 "%s"', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'New Application Wizard', +'New application wizard': 'New application wizard', +'new plugin installed': '已安裝新插件', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': '新紀錄', +'new record inserted': '已新增新紀錄', +'New simple application': 'New simple application', +'next': 'next', +'next %s rows': 'next %s rows', +'next 100 rows': '往後 100 筆', +'NO': '否', +'no changes': 'no changes', +'No databases in this application': '這應用程式不含資料庫', +'No Interaction yet': 'No Interaction yet', +'no match': '無法匹配', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': '或是從逗號分隔檔(CSV)匯入', +'or provide app url:': '或是提供應用程式的安裝網址:', +'Origin': '原文', +'Original/Translation': '原文/翻譯', +'Overview': 'Overview', +'Overwrite installed app': '覆蓋已安裝的應用程式', +'Pack all': '全部打包', +'Pack compiled': '打包已編譯資料', +'Pack custom': 'Pack custom', +'pack plugin': '打包插件', +'PAM authenticated user, cannot change password here': 'PAM 授權使用者, 無法在此變更密碼', +'Password': '密碼', +'password changed': '密碼已變更', +"Password fields don't match": '密碼欄不匹配', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'peek': '選取', +'Peeking at file': '選個文件', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Please', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin': '插件', +'plugin "%(plugin)s" deleted': '已刪除插件"%(plugin)s"', +'Plugin "%s" in application': '在應用程式的插件 "%s"', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'plugins', +'Plugins': '插件', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': '基於以下技術構建:', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '往前 100 筆', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Project Progress', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': '查詢:', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Record': 'Record', +'record': '紀錄', +'record does not exist': '紀錄不存在', +'record id': '紀錄編號', +'Record ID': '紀錄編號', +'Record id': 'Record id', +'refresh': 'refresh', +'register': '註冊', +'Register': '註冊', +'Registration key': '註冊金鑰', +'Reload routes': 'Reload routes', +'Remember me (for 30 days)': '記住帳號(30 天)', +'Remove compiled': '編譯檔案已移除', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Replace', +'Replace All': 'Replace All', +'Repository (%s)': 'Repository (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Reset Password key': '重設密碼', +'resolve': '解決', +'Resolve Conflict file': '解決衝突檔案', +'response': 'response', +'restart': 'restart', +'restore': '回存', +'return': 'return', +'Revert': 'Revert', +'revert': '反向恢復', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': '角色', +'Roles': 'Roles', +'Rows in table': '在資料表裏的資料', +'Rows in Table': 'Rows in Table', +'Rows selected': '筆資料被選擇', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'Running on %s', +'Save': 'Save', +'save': '儲存', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Save via Ajax', +'Saved file hash:': '檔案雜湊值已紀錄:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'selected': '已選擇', +'session': 'session', +'session expired': '連線(session)已過時', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': '命令列操作介面', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': '網站', +'Size of cache:': 'Size of cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': '部份檔案無法移除', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Start a new app', +'Start searching': 'Start searching', +'Start wizard': 'Start wizard', +'state': '狀態', +'Static': 'Static', +'static': '靜態檔案', +'Static files': '靜態檔案', +'Statistics': 'Statistics', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'Stylesheet': '網頁風格檔', +'submit': '傳送', +'Submit': '傳送', +'successful': 'successful', +'Sure you want to delete this object?': '確定要刪除此物件?', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': '資料表', +'Table': 'Table', +'Table name': '資料表名稱', +'Temporary': 'Temporary', +'test': '測試', +'Testing application': '測試中的應用程式', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '"查詢"是一個像 "db.表1.欄位1==\'值\'" 的條件式. 以"db.表1.欄位1==db.表2.欄位2"方式則相當於執行 JOIN SQL.', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'the application logic, each URL path is mapped in one exposed function in the controller': '應用程式邏輯 - 每個網址路徑對應到一個控件的函式', +'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller', +'the data representation, define database tables and sets': '資料展現層 - 用來定義資料表和集合', +'The data representation, define database tables and sets': 'The data representation, define database tables and sets', +'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates', +'the presentations layer, views are also known as templates': '外觀展現層 - 視圖有時也被稱為樣板', +'Theme': 'Theme', +'There are no controllers': '沒有控件(controllers)', +'There are no models': '沒有資料庫模組(models)', +'There are no modules': '沒有程式模組(modules)', +'There are no plugins': 'There are no plugins', +'There are no private files': 'There are no private files', +'There are no static files': '沒有靜態檔案', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': '沒有翻譯檔,只支援原始語言', +'There are no views': '沒有視圖', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'These files are served without processing, your images go here', +'these files are served without processing, your images go here': '這些檔案保留未經處理,你的影像檔在此', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': '這是%(filename)s檔案的樣板(template)', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'ticket': '問題單', +'Ticket': '問題單', +'Ticket ID': 'Ticket ID', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': '時間標記', +'TM': 'TM', +'to previous version.': '到前一個版本', +'To create a plugin, name a file/folder plugin_[name]': '檔案或目錄名稱以 plugin_開頭來創建插件', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'translation strings for the application': '翻譯此應用程式的字串', +'Translation strings for the application': 'Translation strings for the application', +'try': '嘗試', +'try something like': '嘗試如', +'Try the mobile interface': 'Try the mobile interface', +'try view': 'try view', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': '無法做升級檢查', +'unable to create application "%s"': '無法創建應用程式 "%s"', +'unable to delete file "%(filename)s"': '無法刪除檔案 "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': '無法刪查插件檔 "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download': '無法下載', +'Unable to download app': '無法下載應用程式', +'Unable to download app because:': '無法下載應用程式因為:', +'Unable to download because': '因為下列原因無法下載:', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': '無法解析逗號分隔檔(csv)', +'unable to uninstall "%s"': '無法移除安裝 "%s"', +'unable to upgrade because "%s"': '無法升級因為 "%s"', +'uncheck all': '全不選', +'Uninstall': '解除安裝', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': '更新', +'update all languages': '將程式中待翻譯語句更新到所有的語言檔', +'Update:': '更新:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'upgrade now to %s', +'upgrade web2py now': 'upgrade web2py now', +'upgrade_web2py': '升級 web2py', +'upload': 'upload', +'Upload': 'Upload', +'Upload & install packed application': '上傳並安裝已打包的應用程式', +'Upload a package:': 'Upload a package:', +'Upload and install packed application': 'Upload and install packed application', +'upload application:': '上傳應用程式:', +'Upload existing application': '更新存在的應用程式', +'upload file:': '上傳檔案:', +'upload plugin file:': '上傳插件檔:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': '使用下列方式來組合更複雜的條件式, (...)&(...) 代表同時存在的條件, (...)|(...) 代表擇一的條件, ~(...)則代表反向條件.', +'User': 'User', +'User %(id)s Logged-in': '使用者 %(id)s 已登入', +'User %(id)s Registered': '使用者 %(id)s 已註冊', +'User ID': '使用者編號', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'variables', +'Verify Password': '驗證密碼', +'Version': '版本', +'Versioning': 'Versioning', +'versioning': '版本管理', +'View': '視圖', +'view': '視圖', +'Views': '視圖', +'views': '視圖', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py 已經是最新版', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'web2py 最近的 Tweets', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': '已升級 web2py ; 請重新啟動', +'Welcome %s': '歡迎 %s', +'Welcome to web2py': '歡迎使用 web2py', +'Working...': 'Working...', +'WSGI reference name': 'WSGI reference name', +'YES': '是', +'Yes': 'Yes', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/languages/zh.py b/web2py/applications/admin/languages/zh.py new file mode 100644 index 0000000..ae5971c --- /dev/null +++ b/web2py/applications/admin/languages/zh.py @@ -0,0 +1,667 @@ +# -*- coding: utf-8 -*- +{ +'!langcode!': 'zh-cn', +'!langname!': '中文', +'"browse"': '游览', +'"save"': '"保存"', +'"submit"': '"提交"', +'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"更新"是可配置项 如 "field1=\'newvalue\'",你无法在JOIN 中更新或删除', +'"User Exception" debug mode. ': '"User Exception" debug mode. ', +'%s': '%s', +'%s %%{row} deleted': '%s 行已删', +'%s %%{row} updated': '%s 行更新', +'%s selected': '%s selected', +'%s students registered': '%s students registered', +'%Y-%m-%d': '%Y-%m-%d', +'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S', +'(requires internet access)': '(requires internet access)', +'(requires internet access, experimental)': '(requires internet access, experimental)', +'(something like "it-it")': '(就酱 "it-it")', +'(version %s)': '(version %s)', +'?': '?', +'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page', +'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files', +'A new version of web2py is available': '新版本web2py已经可用', +'A new version of web2py is available: %s': '新版本web2py已经可用: %s', +'Abort': 'Abort', +'About': '关于', +'About application': '关于这个应用', +'Accept Terms': 'Accept Terms', +'Add breakpoint': 'Add breakpoint', +'additional code for your application': '给你的应用附加代码', +'Additional code for your application': 'Additional code for your application', +'Admin design page': 'Admin design page', +'admin disabled because no admin password': '管理员需要设定密码,否则无法管理', +'admin disabled because not supported on google app engine': '未支持GAE,无法管理', +'admin disabled because too many invalid login attempts': 'admin disabled because too many invalid login attempts', +'admin disabled because unable to access password file': '需要可以操作密码文件,否则无法进行管理', +'Admin is disabled because insecure channel': '管理因不安全通道而关闭', +'Admin is disabled because unsecure channel': '管理因不稳定通道而关闭', +'Admin language': 'Admin language', +'Admin versioning page': 'Admin versioning page', +'administrative interface': 'administrative interface', +'Administrator Password:': '管理员密码:', +'and rename it (required):': '重命名为 (必须):', +'and rename it:': ' 重命名为:', +'App does not exist or you are not authorized': 'App does not exist or you are not authorized', +'appadmin': '应用管理', +'appadmin is disabled because insecure channel': '应用管理因非法通道失效', +'Application': 'Application', +'application "%s" uninstalled': '应用"%s" 已被卸载', +'Application cannot be generated in demo mode': 'Application cannot be generated in demo mode', +'application compiled': '应用已编译完', +'Application exists already': 'Application exists already', +'application is compiled and cannot be designed': '应用已编译完无法设计', +'Application name:': 'Application name:', +'Application updated via git pull': 'Application updated via git pull', +'are not used': 'are not used', +'are not used yet': 'are not used yet', +'Are you sure you want to delete file "%s"?': '你真想删除文件"%s"?', +'Are you sure you want to delete plugin "%s"?': 'Are you sure you want to delete plugin "%s"?', +'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?', +'Are you sure you want to uninstall application "%s"': '你真确定要卸载应用 "%s"', +'Are you sure you want to uninstall application "%s"?': '你真确定要卸载应用 "%s" ?', +'Are you sure you want to upgrade web2py now?': 'Are you sure you want to upgrade web2py now?', +'Are you sure?': 'Are you sure?', +'arguments': 'arguments', +'at char %s': 'at char %s', +'at line %s': 'at line %s', +'ATTENTION:': 'ATTENTION:', +'ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.': '', +'ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.': '', +'ATTENTION: you cannot edit the running application!': '注意: 不能修改正在运行中的应用!', +'Autocomplete Python Code': 'Autocomplete Python Code', +'Available databases and tables': '可用数据库/表', +'Available Databases and Tables': 'Available Databases and Tables', +'back': 'back', +'Back to the plugins list': 'Back to the plugins list', +'Back to wizard': 'Back to wizard', +'Basics': 'Basics', +'Begin': 'Begin', +'breakpoint': 'breakpoint', +'Breakpoints': 'Breakpoints', +'breakpoints': 'breakpoints', +'Bulk Register': 'Bulk Register', +'Bulk Student Registration': 'Bulk Student Registration', +'Cache': 'Cache', +'cache': 'cache', +'Cache Cleared': 'Cache Cleared', +'Cache Keys': 'Cache Keys', +'cache, errors and sessions cleaned': '缓存、错误、sesiones已被清空', +'can be a git repo': 'can be a git repo', +'Cancel': 'Cancel', +'Cannot be empty': '不能不填', +'Cannot compile: there are errors in your app. \xa0 \xa0 \xa0 \xa0Debug it, correct errors and try again.': '无法编译: 应用中有错误,请修订后再试.', +'Cannot compile: there are errors in your app:': 'Cannot compile: there are errors in your app:', +'cannot create file': '无法创建文件', +'cannot upload file "%(filename)s"': '无法上传文件 "%(filename)s"', +'Change Admin Password': 'Change Admin Password', +'Change admin password': 'change admin password', +'change editor settings': 'change editor settings', +'Change Password': '修改密码', +'Changelog': 'Changelog', +'check all': '检查所有', +'Check for upgrades': 'check for upgrades', +'Check to delete': '检验删除', +'Checking for upgrades...': '是否有升级版本检查ing...', +'Clean': '清除', +'Clear': 'Clear', +'Clear CACHE?': 'Clear CACHE?', +'Clear DISK': 'Clear DISK', +'Clear RAM': 'Clear RAM', +'click here for online examples': '猛击此处,查看在线实例', +'click here for the administrative interface': '猛击此处,进入管理界面', +'Click row to expand traceback': 'Click row to expand traceback', +'Click row to view a ticket': 'Click row to view a ticket', +'click to check for upgrades': '猛击查看是否有升级版本', +'Client IP': '客户端IP', +'code': 'code', +'Code listing': 'Code listing', +'collapse/expand all': 'collapse/expand all', +'Command': 'Command', +'Comment:': 'Comment:', +'Commit': 'Commit', +'Commit form': 'Commit form', +'Committed files': 'Committed files', +'Compile': '编译', +'Compile (all or nothing)': 'Compile (all or nothing)', +'Compile (skip failed views)': 'Compile (skip failed views)', +'compiled application removed': '已编译应用已移走', +'Condition': 'Condition', +'continue': 'continue', +'Controllers': '控制器s', +'controllers': '控制器', +'Count': 'Count', +'Create': 'create', +'create file with filename:': '创建文件用这名:', +'create new application:': '创建新应用:', +'Create new simple application': '创建一个新应用', +'Create/Upload': 'Create/Upload', +'created by': '创建自', +'Created by:': 'Created by:', +'Created On': 'Created On', +'Created on:': 'Created on:', +'crontab': '定期事务', +'Current request': '当前请求', +'Current response': '当前返回', +'Current session': '当前会话', +'currently running': 'currently running', +'currently saved or': '保存当前的或', +'customize me!': '定制俺!', +'data uploaded': '数据已上传', +'Database': 'Database', +'database': '数据库', +'Database %s select': 'Database %s select', +'database %s select': '数据库 %s 选择', +'Database administration': 'Database administration', +'database administration': '数据库管理', +'Database Administration (appadmin)': 'Database Administration (appadmin)', +'Date and Time': '时间日期', +'db': '', +'Debug': 'Debug', +'defines tables': '已定义表', +'Delete': '删除', +'delete': '删除', +'delete all checked': '删除所有选择的', +'delete plugin': 'delete plugin', +'Delete this file (you will be asked to confirm deletion)': 'Delete this file (you will be asked to confirm deletion)', +'Delete:': '删除:', +'deleted after first hit': 'deleted after first hit', +'Demo': 'Demo', +'Deploy': 'deploy', +'Deploy on Google App Engine': '部署到GAE', +'Deploy to OpenShift': 'Deploy to OpenShift', +'Deploy to pythonanywhere': 'Deploy to pythonanywhere', +'Deploy to PythonAnywhere': 'Deploy to PythonAnywhere', +'Deployment form': 'Deployment form', +'Deployment Interface': 'Deployment Interface', +'Description': '描述', +'Description:': 'Description:', +'design': '设计', +'DESIGN': '设计', +'Design for': '设计:', +'Detailed traceback description': 'Detailed traceback description', +'details': 'details', +'direction: ltr': 'direction: ltr', +'directory not found': 'directory not found', +'Disable': 'Disable', +'Disabled': 'Disabled', +'disabled in demo mode': 'disabled in demo mode', +'disabled in GAE mode': 'disabled in GAE mode', +'disabled in multi user mode': 'disabled in multi user mode', +'DISK': 'DISK', +'Disk Cache Keys': 'Disk Cache Keys', +'Disk Cleared': 'Disk Cleared', +'Display line numbers': 'Display line numbers', +'DO NOT use the "Pack compiled" feature.': 'DO NOT use the "Pack compiled" feature.', +'docs': 'docs', +'Docs': 'Docs', +'done!': '搞定!', +'Downgrade': 'Downgrade', +'Download .w2p': 'Download .w2p', +'Download as .exe': 'Download as .exe', +'download layouts': 'download layouts', +'Download layouts from repository': 'Download layouts from repository', +'download plugins': 'download plugins', +'Download plugins from repository': 'Download plugins from repository', +'E-mail': '邮箱:', +'EDIT': '编辑', +'Edit': '修改', +'edit all': 'edit all', +'Edit application': '修订应用', +'edit controller': '修订控制器', +'edit controller:': 'edit controller:', +'Edit current record': '修订当前记录', +'Edit Profile': '修订配置', +'edit views:': 'edit views:', +'Editing %s': 'Editing %s', +'Editing file': '修订文件', +'Editing file "%s"': '修订文件 %s', +'Editing Language file': '修订语言文件', +'Editing Plural Forms File': 'Editing Plural Forms File', +'Editor': 'Editor', +'Email Address': 'Email Address', +'Enable': 'Enable', +'Enable Close-Tag': 'Enable Close-Tag', +'Enable Code Folding': 'Enable Code Folding', +'Enterprise Web Framework': '强悍的网络开发框架', +'Error': 'Error', +'Error logs for "%(app)s"': '"%(app)s" 的错误日志', +'Error snapshot': 'Error snapshot', +'Error ticket': 'Error ticket', +'Errors': '错误', +'Exception %(extype)s: %(exvalue)s': 'Exception %(extype)s: %(exvalue)s', +'Exception %s': 'Exception %s', +'Exception instance attributes': 'Exception instance attributes', +'Exit Fullscreen': 'Exit Fullscreen', +'Expand Abbreviation (html files only)': 'Expand Abbreviation (html files only)', +'export as csv file': '导出为CSV文件', +'Exports:': 'Exports:', +'exposes': '暴露', +'exposes:': 'exposes:', +'extends': '扩展', +'failed to compile file because:': 'failed to compile file because:', +'failed to reload module': '重新加载模块失败', +'failed to reload module because:': 'failed to reload module because:', +'File': 'File', +'file "%(filename)s" created': '文件 "%(filename)s" 已创建', +'file "%(filename)s" deleted': '文件 "%(filename)s" 已删除', +'file "%(filename)s" uploaded': '文件 "%(filename)s" 已上传', +'file "%(filename)s" was not deleted': '文件 "%(filename)s" 没删除', +'file "%s" of %s restored': '文件"%s" 有关 %s 已重存', +'file changed on disk': '硬盘上的文件已经修改', +'file does not exist': '文件并不存在', +'file not found': 'file not found', +'file saved on %(time)s': '文件保存于 %(time)s', +'file saved on %s': '文件保存在 %s', +'filename': 'filename', +'Filename': 'Filename', +'Files added': 'Files added', +'filter': 'filter', +'Find Next': 'Find Next', +'Find Previous': 'Find Previous', +'First name': '姓', +'Form has errors': 'Form has errors', +'Frames': 'Frames', +'Functions with no doctests will result in [passed] tests.': '', +'GAE Email': 'GAE Email', +'GAE Output': 'GAE Output', +'GAE Password': 'GAE Password', +'Generate': 'Generate', +'Get from URL:': 'Get from URL:', +'Git Pull': 'Git Pull', +'Git Push': 'Git Push', +'Globals##debug': 'Globals##debug', +'go!': 'go!', +'Google App Engine Deployment Interface': 'Google App Engine Deployment Interface', +'Google Application Id': 'Google Application Id', +'Goto': 'Goto', +'graph model': 'graph model', +'Graph Model': 'Graph Model', +'Group ID': '组ID', +'Hello World': '道可道,非常道;名可名,非常名', +'Help': '帮助', +'here': 'here', +'Hide/Show Translated strings': 'Hide/Show Translated strings', +'Highlight current line': 'Highlight current line', +'Hits': 'Hits', +'Home': 'Home', +'honored only if the expression evaluates to true': 'honored only if the expression evaluates to true', +'htmledit': 'html编辑', +'If start the downgrade, be patient, it may take a while to rollback': 'If start the downgrade, be patient, it may take a while to rollback', +'If start the upgrade, be patient, it may take a while to download': 'If start the upgrade, be patient, it may take a while to download', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\n\t\tA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.': 'If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.\nA green title indicates that all tests (if defined) passed. In this case test results are not shown.', +'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.': 'if your application uses a database other than sqlite you will then have to configure its DAL in pythonanywhere.', +'import': 'import', +'Import/Export': '导入/导出', +'In development, use the default Rocket webserver that is currently supported by this debugger.': 'In development, use the default Rocket webserver that is currently supported by this debugger.', +'includes': '包含', +'Indent with tabs': 'Indent with tabs', +'insert new': '新插入', +'insert new %s': '新插入 %s', +'inspect attributes': 'inspect attributes', +'Install': 'install', +'Installation of %(plugin)s for %(app)s': 'Installation of %(plugin)s for %(app)s', +'Installed applications': '已安装的应用', +'Interaction at %s line %s': 'Interaction at %s line %s', +'Interactive console': 'Interactive console', +'internal error': '内部错误', +'internal error: %s': 'internal error: %s', +'Internal State': '内部状态', +'Invalid action': '无效动作', +'Invalid application name': 'Invalid application name', +'invalid circular reference': 'invalid circular reference', +'Invalid email': '无效的email', +'Invalid git repository specified.': 'Invalid git repository specified.', +'invalid password': '无效密码', +'invalid password.': 'invalid password.', +'Invalid Query': '无效查询', +'invalid request': '无效请求', +'Invalid request': 'Invalid request', +'invalid table names (auth_* tables already defined)': 'invalid table names (auth_* tables already defined)', +'invalid ticket': '无效传票', +'Key': 'Key', +'Keyboard shortcuts': 'Keyboard shortcuts', +'kill process': 'kill process', +'language file "%(filename)s" created/updated': '语言文件 "%(filename)s"被创建/更新', +'Language files (static strings) updated': '语言文件(静态部分)已更新', +'languages': '语言', +'Languages': '语言', +'languages updated': '语言已被刷新', +'Last name': '名', +'Last Revision': 'Last Revision', +'Last saved on:': '最后保存于:', +'License for': '许可证', +'License:': 'License:', +'Line Nr': 'Line Nr', +'Line number': 'Line number', +'lists by exception': 'lists by exception', +'lists by ticket': 'lists by ticket', +'Loading...': 'Loading...', +'loading...': '载入中...', +'Local Apps': 'Local Apps', +'locals': 'locals', +'Locals##debug': 'Locals##debug', +'login': '登录', +'Login': '登录', +'Login successful': 'Login successful', +'Login to the Administrative Interface': '登录到管理员界面', +'Login/Register': 'Login/Register', +'Logout': '注销', +'Lost Password': '忘记密码', +'lost password': 'lost password', +'Main Menu': 'Main Menu', +'Manage': 'Manage', +'Manage %(action)s': 'Manage %(action)s', +'Manage Access Control': 'Manage Access Control', +'Manage Admin Users/Students': 'Manage Admin Users/Students', +'Manage Cache': 'Manage Cache', +'Manage Students': 'Manage Students', +'Memberships': 'Memberships', +'merge': '合并', +'Models': '模型s', +'models': '模型s', +'Modified On': 'Modified On', +'Modules': '模块s', +'modules': '模块s', +'Multi User Mode': 'Multi User Mode', +'Name': '姓名', +'new application "%s" created': '新应用 "%s"已被创建', +'new application "%s" imported': 'new application "%s" imported', +'New Application Wizard': 'New Application Wizard', +'New application wizard': 'New application wizard', +'new plugin installed': 'new plugin installed', +'New plugin installed: %s': 'New plugin installed: %s', +'New Record': '新记录', +'new record inserted': '新记录被插入', +'New simple application': 'New simple application', +'next': 'next', +'next %s rows': 'next %s rows', +'next 100 rows': '后100行', +'NO': '不', +'no changes': 'no changes', +'No databases in this application': '这应用没有数据库', +'No Interaction yet': 'No Interaction yet', +'no match': 'no match', +'no package selected': 'no package selected', +'no permission to uninstall "%s"': 'no permission to uninstall "%s"', +'Node:': 'Node:', +'Not Authorized': 'Not Authorized', +'Not supported': 'Not supported', +'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.': 'Note: If you receive an error with github status code of 128, ensure the system and account you are deploying from has a cooresponding ssh key configured in the openshift account.', +"On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.": "On production, you'll have to configure your webserver to use one process and multiple threads to use this debugger.", +'Open new app in new window': 'Open new app in new window', +'OpenShift Deployment Interface': 'OpenShift Deployment Interface', +'OpenShift Output': 'OpenShift Output', +'or alternatively': 'or alternatively', +'Or Get from URL:': 'Or Get from URL:', +'or import from csv file': '或者,从csv文件导入', +'or provide app url:': 'or provide app url:', +'or provide application url:': '或者,提供应用所在地址链接:', +'Origin': '起源', +'Original/Translation': '原始文件/翻译文件', +'Overview': 'Overview', +'Overwrite installed app': 'overwrite installed app', +'Pack all': '全部打包', +'Pack compiled': '包编译完', +'Pack custom': 'Pack custom', +'pack plugin': 'pack plugin', +'PAM authenticated user, cannot change password here': 'PAM authenticated user, cannot change password here', +'Password': '密码', +'password changed': 'password changed', +'Past revisions': 'Past revisions', +'Path to appcfg.py': 'Path to appcfg.py', +'Path to local openshift repo root.': 'Path to local openshift repo root.', +'Peeking at file': '选个文件', +'Permission': 'Permission', +'Permissions': 'Permissions', +'Please': 'Please', +'Please wait, giving pythonanywhere a moment...': 'Please wait, giving pythonanywhere a moment...', +'plugin "%(plugin)s" deleted': 'plugin "%(plugin)s" deleted', +'Plugin "%s" in application': 'Plugin "%s" in application', +'plugin not specified': 'plugin not specified', +'Plugin page': 'Plugin page', +'plugins': 'plugins', +'Plugins': 'Plugins', +'Plural Form #%s': 'Plural Form #%s', +'Plural-Forms:': 'Plural-Forms:', +'Powered by': '', +'Preferences saved correctly': 'Preferences saved correctly', +'Preferences saved on session only': 'Preferences saved on session only', +'previous %s rows': 'previous %s rows', +'previous 100 rows': '前100行', +'Private files': 'Private files', +'private files': 'private files', +'Project Progress': 'Project Progress', +'Pull': 'Pull', +'Pull failed, certain files could not be checked out. Check logs for details.': 'Pull failed, certain files could not be checked out. Check logs for details.', +'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.': 'Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.', +'Push': 'Push', +'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.': 'Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.', +'pygraphviz library not found': 'pygraphviz library not found', +'PythonAnywhere Apps': 'PythonAnywhere Apps', +'PythonAnywhere Password': 'PythonAnywhere Password', +'Query:': '查询', +'RAM': 'RAM', +'RAM Cache Keys': 'RAM Cache Keys', +'Ram Cleared': 'Ram Cleared', +'Rapid Search': 'Rapid Search', +'Record': 'Record', +'record': 'record', +'record does not exist': '记录并不存在', +'record id': '记录ID', +'Record ID': '记录ID', +'Record id': 'Record id', +'refresh': 'refresh', +'register': 'register', +'Register': '注册', +'Registration key': '注册密匙', +'Reload routes': 'Reload routes', +'Remove compiled': '已移除', +'Removed Breakpoint on %s at line %s': 'Removed Breakpoint on %s at line %s', +'Replace': 'Replace', +'Replace All': 'Replace All', +'Repository (%s)': 'Repository (%s)', +'request': 'request', +'requires distutils, but not installed': 'requires distutils, but not installed', +'requires python-git, but not installed': 'requires python-git, but not installed', +'Resolve Conflict file': '解决冲突文件', +'response': 'response', +'restart': 'restart', +'restore': '重存', +'return': 'return', +'Revert': 'Revert', +'revert': '恢复', +'reverted to revision %s': 'reverted to revision %s', +'Revision %s': 'Revision %s', +'Revision:': 'Revision:', +'Role': '角色', +'Roles': 'Roles', +'Rows in table': '表行', +'Rows in Table': 'Rows in Table', +'Rows selected': '行选择', +'rules are not defined': 'rules are not defined', +'Run tests': 'Run tests', +'Run tests in this file': 'Run tests in this file', +"Run tests in this file (to run all files, you may also use the button labelled 'test')": "Run tests in this file (to run all files, you may also use the button labelled 'test')", +'Running on %s': 'Running on %s', +'Save': 'Save', +'save': '保存', +'Save file:': 'Save file:', +'Save file: %s': 'Save file: %s', +'Save model as...': 'Save model as...', +'Save via Ajax': 'Save via Ajax', +'Saved file hash:': '已存文件Hash:', +'Screenshot %s': 'Screenshot %s', +'Search': 'Search', +'Select Files to Package': 'Select Files to Package', +'selected': '已选', +'session': 'session', +'session expired': '会话过期', +'Session saved correctly': 'Session saved correctly', +'Session saved on session only': 'Session saved on session only', +'Set Breakpoint on %s at line %s: %s': 'Set Breakpoint on %s at line %s: %s', +'shell': '', +'Showing %s to %s of %s %s found': 'Showing %s to %s of %s %s found', +'Singular Form': 'Singular Form', +'Site': '总站', +'Size of cache:': 'Size of cache:', +'skip to generate': 'skip to generate', +'some files could not be removed': '有些文件无法被移除', +'Something went wrong please wait a few minutes before retrying': 'Something went wrong please wait a few minutes before retrying', +'Sorry, could not find mercurial installed': 'Sorry, could not find mercurial installed', +'source : db': 'source : db', +'source : filesystem': 'source : filesystem', +'Start a new app': 'Start a new app', +'Start searching': 'Start searching', +'Start wizard': 'start wizard', +'state': '状态', +'Static': 'Static', +'static': '静态文件', +'Static files': '静态文件', +'Statistics': 'Statistics', +'Step': 'Step', +'step': 'step', +'stop': 'stop', +'submit': '提交', +'Submit': 'Submit', +'successful': 'successful', +'Sure you want to delete this object?': '真的要删除这个对象?', +'switch to : db': 'switch to : db', +'switch to : filesystem': 'switch to : filesystem', +'Tab width (# characters)': 'Tab width (# characters)', +'table': '表', +'Table': 'Table', +'Table name': '表名', +'Temporary': 'Temporary', +'test': '测试', +'Testing application': '应用测试', +'The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.': '', +'The app exists, was created by wizard, continue to overwrite!': 'The app exists, was created by wizard, continue to overwrite!', +'The app exists, was NOT created by wizard, continue to overwrite!': 'The app exists, was NOT created by wizard, continue to overwrite!', +'the application logic, each URL path is mapped in one exposed function in the controller': '应用逻辑:每个URL由控制器暴露的函式完成映射', +'The application logic, each URL path is mapped in one exposed function in the controller': 'The application logic, each URL path is mapped in one exposed function in the controller', +'the data representation, define database tables and sets': '数据表达式,定义数据库/表', +'The data representation, define database tables and sets': 'The data representation, define database tables and sets', +'The presentations layer, views are also known as templates': 'The presentations layer, views are also known as templates', +'the presentations layer, views are also known as templates': '提交层/视图都在模板中可知', +'Theme': 'Theme', +'There are no controllers': '冇控制器', +'There are no models': '冇模型s', +'There are no modules': '冇模块s', +'There are no plugins': 'There are no plugins', +'There are no private files': 'There are no private files', +'There are no static files': '冇静态文件', +'There are no translators': 'There are no translators', +'There are no translators, only default language is supported': '没有找到相应翻译,只能使用默认语言', +'There are no views': '冇视图', +'These files are not served, they are only available from within your app': 'These files are not served, they are only available from within your app', +'These files are served without processing, your images go here': 'These files are served without processing, your images go here', +'these files are served without processing, your images go here': '', +"This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.": "This debugger may not work properly if you don't have a threaded webserver or you're using multiple daemon processes.", +'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk', +'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk': 'This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk', +'This is the %(filename)s template': '这是 %(filename)s 模板', +"This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.": "This page can commit your changes to an openshift app repo and push them to your cloud instance. This assumes that you've already created the application instance using the web2py skeleton and have that repo somewhere on a filesystem that this web2py instance can access. This functionality requires GitPython installed and on the python path of the runtime that web2py is operating in.", +'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.': 'This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.', +'this page to see if a breakpoint was hit and debug interaction is required.': 'this page to see if a breakpoint was hit and debug interaction is required.', +'This will pull changes from the remote repo for application "%s"?': 'This will pull changes from the remote repo for application "%s"?', +'This will push changes to the remote repo for application "%s".': 'This will push changes to the remote repo for application "%s".', +'Ticket': '传票', +'Ticket ID': 'Ticket ID', +'Ticket Missing': 'Ticket Missing', +'Time in Cache (h:m:s)': 'Time in Cache (h:m:s)', +'Timestamp': '时间戳', +'TM': '', +'to previous version.': 'to previous version.', +'To create a plugin, name a file/folder plugin_[name]': 'To create a plugin, name a file/folder plugin_[name]', +'To emulate a breakpoint programatically, write:': 'To emulate a breakpoint programatically, write:', +'to use the debugger!': 'to use the debugger!', +'to \xa0previous version.': '退回前一版本', +'toggle breakpoint': 'toggle breakpoint', +'Toggle comment': 'Toggle comment', +'Toggle Fullscreen': 'Toggle Fullscreen', +'Traceback': 'Traceback', +'translation strings for the application': '应用的翻译字串', +'Translation strings for the application': 'Translation strings for the application', +'try': '尝试', +'try something like': '尝试', +'Try the mobile interface': 'Try the mobile interface', +'try view': 'try view', +'Type PDB debugger command in here and hit Return (Enter) to execute it.': 'Type PDB debugger command in here and hit Return (Enter) to execute it.', +'Type some Python code in here and hit Return (Enter) to execute it.': 'Type some Python code in here and hit Return (Enter) to execute it.', +'Unable to check for upgrades': '无法检查是否需要升级', +'unable to create application "%s"': '无法创建应用 "%s"', +'unable to delete file "%(filename)s"': '无法删除文件 "%(filename)s"', +'unable to delete file plugin "%(plugin)s"': 'unable to delete file plugin "%(plugin)s"', +'Unable to determine the line number!': 'Unable to determine the line number!', +'Unable to download': '无法下载', +'Unable to download app': '无法下载应用', +'Unable to download app because:': 'Unable to download app because:', +'Unable to download because': 'Unable to download because', +'unable to download layout': 'unable to download layout', +'unable to download plugin: %s': 'unable to download plugin: %s', +'Unable to download the list of plugins': 'Unable to download the list of plugins', +'unable to install plugin "%s"': 'unable to install plugin "%s"', +'unable to parse csv file': '无法生成 cvs', +'unable to uninstall "%s"': '无法卸载 "%s"', +'unable to upgrade because "%s"': 'unable to upgrade because "%s"', +'uncheck all': '反选全部', +'Uninstall': '卸载', +'Unsupported webserver working mode: %s': 'Unsupported webserver working mode: %s', +'update': '更新', +'update all languages': '更新所有语言', +'Update:': '更新:', +'Upgrade': 'Upgrade', +'upgrade now to %s': 'upgrade now to %s', +'upgrade web2py now': 'upgrade web2py now', +'upload': 'upload', +'Upload': 'Upload', +'Upload & install packed application': 'Upload & install packed application', +'Upload a package:': 'Upload a package:', +'Upload and install packed application': 'Upload and install packed application', +'upload application:': '提交已有的应用:', +'Upload existing application': '上传已有应用', +'upload file:': '提交文件:', +'upload plugin file:': 'upload plugin file:', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.': 'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.', +'Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) \xa0for NOT to build more complex queries.': '', +'Use an url:': 'Use an url:', +'User': 'User', +'User ID': '用户ID', +'Username': 'Username', +'Users': 'Users', +'Using the shell may lock the database to other users of this app.': 'Using the shell may lock the database to other users of this app.', +'variables': 'variables', +'Version': '版本', +'Versioning': 'Versioning', +'versioning': '版本', +'view': '视图', +'Views': '视图', +'views': '视图s', +'Warning!': 'Warning!', +'WARNING:': 'WARNING:', +'WARNING: The following views could not be compiled:': 'WARNING: The following views could not be compiled:', +'Web Framework': 'Web Framework', +'web2py Admin Password': 'web2py Admin Password', +'web2py apps to deploy': 'web2py apps to deploy', +'web2py Debugger': 'web2py Debugger', +'web2py downgrade': 'web2py downgrade', +'web2py is up to date': 'web2py现在已经是最新的版本了', +'web2py online debugger': 'web2py online debugger', +'web2py Recent Tweets': 'twitter上的web2py进展实播', +'web2py upgrade': 'web2py upgrade', +'web2py upgraded; please restart it': 'web2py upgraded; please restart it', +'Welcome to web2py': '欢迎使用web2py', +'Working...': 'Working...', +'WSGI reference name': 'WSGI reference name', +'YES': '是', +'Yes': 'Yes', +'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button': 'You can also set and remove breakpoint in the edit window, using the Toggle Breakpoint button', +'You can inspect variables using the console below': 'You can inspect variables using the console below', +'You have one more login attempt before you are locked out': 'You have one more login attempt before you are locked out', +'You need to set up and reach a': 'You need to set up and reach a', +'You only need these if you have already registered': 'You only need these if you have already registered', +'Your application will be blocked until you click an action button (next, step, continue, etc.)': 'Your application will be blocked until you click an action button (next, step, continue, etc.)', +} diff --git a/web2py/applications/admin/models/0.py b/web2py/applications/admin/models/0.py new file mode 100644 index 0000000..d9f8d27 --- /dev/null +++ b/web2py/applications/admin/models/0.py @@ -0,0 +1,50 @@ +EXPIRATION = 60 * 60 # logout after 60 minutes of inactivity +CHECK_VERSION = True +WEB2PY_URL = 'http://web2py.com' +WEB2PY_VERSION_URL = WEB2PY_URL + '/examples/default/version' + +########################################################################### +# Preferences for EditArea +# the user-interface feature that allows you to edit files in your web +# browser. + +# if demo mode is True then admin works readonly and does not require login +DEMO_MODE = False + +# if visible_apps is not empty only listed apps will be accessible +FILTER_APPS = [] + +# To upload on google app engine this has to point to the proper appengine +# config file +import os +# extract google_appengine_x.x.x.zip to web2py root directory +#GAE_APPCFG = os.path.abspath(os.path.join('appcfg.py')) +# extract google_appengine_x.x.x.zip to applications/admin/private/ +GAE_APPCFG = os.path.abspath(os.path.join('/usr/local/bin/appcfg.py')) + +# To use web2py as a teaching tool, set MULTI_USER_MODE to True +MULTI_USER_MODE = False +EMAIL_SERVER = 'localhost' +EMAIL_SENDER = 'professor@example.com' +EMAIL_LOGIN = None + +# configurable twitterbox, set to None/False to suppress +TWITTER_HASH = "web2py" + +# parameter for downloading LAYOUTS +LAYOUTS_APP = 'http://web2py.com/layouts' +#LAYOUTS_APP = 'http://127.0.0.1:8000/layouts' + + +# parameter for downloading PLUGINS +PLUGINS_APP = 'http://web2py.com/plugins' +#PLUGINS_APP = 'http://127.0.0.1:8000/plugins' + +# set the language +if 'adminLanguage' in request.cookies and not (request.cookies['adminLanguage'] is None): + T.force(request.cookies['adminLanguage'].value) + +#set static_version +from gluon.settings import global_settings +response.static_version = global_settings.web2py_version.split('-')[0] +response.static_version_urls = True diff --git a/web2py/applications/admin/models/0_imports.py b/web2py/applications/admin/models/0_imports.py new file mode 100644 index 0000000..b911c0e --- /dev/null +++ b/web2py/applications/admin/models/0_imports.py @@ -0,0 +1,30 @@ +import time +import os +import sys +import re +import urllib +import cgi +import difflib +import shutil +import stat +import socket + +from textwrap import dedent + +try: + from mercurial import ui, hg, cmdutil + try: + from mercurial.scmutil import addremove + except: + from mercurial.cmdutil import addremove + have_mercurial = True +except ImportError: + have_mercurial = False + +from gluon.utils import md5_hash +from gluon.fileutils import listdir, cleanpath, up +from gluon.fileutils import tar, tar_compiled, untar, fix_newlines +from gluon.languages import findT, update_all_languages +from gluon.myregex import * +from gluon.restricted import * +from gluon.compileapp import compile_application, remove_compiled_application diff --git a/web2py/applications/admin/models/access.py b/web2py/applications/admin/models/access.py new file mode 100644 index 0000000..ded471c --- /dev/null +++ b/web2py/applications/admin/models/access.py @@ -0,0 +1,190 @@ +import base64 +import os +import time +from gluon.admin import apath +from gluon.fileutils import read_file +from gluon.utils import web2py_uuid +from pydal.contrib import portalocker +# ########################################################### +# ## make sure administrator is on localhost or https +# ########################################################### + + +http_host = request.env.http_host.split(':')[0] + +if request.env.web2py_runtime_gae: + session_db = DAL('gae') + session.connect(request, response, db=session_db) + hosts = (http_host, ) + is_gae = True +else: + is_gae = False + +if request.is_https: + session.secure() +elif not request.is_local and not DEMO_MODE: + raise HTTP(200, T('Admin is disabled because insecure channel')) + +try: + _config = {} + port = int(request.env.server_port or 0) + restricted( + read_file(apath('../parameters_%i.py' % port, request)), _config) + + if not 'password' in _config or not _config['password']: + raise HTTP(200, T('admin disabled because no admin password')) +except IOError: + import gluon.fileutils + if is_gae: + if gluon.fileutils.check_credentials(request): + session.authorized = True + session.last_time = time.time() + else: + raise HTTP(200, + T('admin disabled because not supported on google app engine')) + else: + raise HTTP( + 200, T('admin disabled because unable to access password file')) + + +def verify_password(password): + session.pam_user = None + if DEMO_MODE: + ret = True + elif not _config.get('password'): + ret = False + elif _config['password'].startswith('pam_user:'): + session.pam_user = _config['password'][9:].strip() + import gluon.contrib.pam + ret = gluon.contrib.pam.authenticate(session.pam_user, password) + else: + ret = _config['password'] == CRYPT()(password)[0] + if ret: + session.hmac_key = web2py_uuid() + return ret + + +# ########################################################### +# ## handle brute-force login attacks +# ########################################################### + +deny_file = os.path.join(request.folder, 'private', 'hosts.deny') +allowed_number_of_attempts = 5 +expiration_failed_logins = 3600 + + +def read_hosts_deny(): + import datetime + hosts = {} + if os.path.exists(deny_file): + hosts = {} + f = open(deny_file, 'r') + portalocker.lock(f, portalocker.LOCK_SH) + for line in f.readlines(): + if not line.strip() or line.startswith('#'): + continue + fields = line.strip().split() + if len(fields) > 2: + hosts[fields[0].strip()] = ( # ip + int(fields[1].strip()), # n attemps + int(fields[2].strip()) # last attempts + ) + portalocker.unlock(f) + f.close() + return hosts + + +def write_hosts_deny(denied_hosts): + f = open(deny_file, 'w') + portalocker.lock(f, portalocker.LOCK_EX) + for key, val in denied_hosts.items(): + if time.time() - val[1] < expiration_failed_logins: + line = '%s %s %s\n' % (key, val[0], val[1]) + f.write(line) + portalocker.unlock(f) + f.close() + +def login_record(success=True): + denied_hosts = read_hosts_deny() + val = (0, 0) + if success and request.client in denied_hosts: + del denied_hosts[request.client] + elif not success: + val = denied_hosts.get(request.client, (0, 0)) + if time.time() - val[1] < expiration_failed_logins \ + and val[0] >= allowed_number_of_attempts: + return val[0] # locked out + time.sleep(2 ** val[0]) + val = (val[0] + 1, int(time.time())) + denied_hosts[request.client] = val + write_hosts_deny(denied_hosts) + return val[0] + +def failed_login_count(): + denied_hosts = read_hosts_deny() + val = denied_hosts.get(request.client, (0, 0)) + return val[0] + + +# ########################################################### +# ## session expiration +# ########################################################### + +t0 = time.time() +if session.authorized: + + if session.last_time and session.last_time < t0 - EXPIRATION: + session.flash = T('session expired') + session.authorized = False + else: + session.last_time = t0 + + +if request.vars.is_mobile in ('true', 'false', 'auto'): + session.is_mobile = request.vars.is_mobile or 'auto' +if request.controller == 'default' and request.function == 'index': + if not request.vars.is_mobile: + session.is_mobile = 'auto' +if not session.is_mobile: + session.is_mobile = 'auto' +if session.is_mobile == 'true': + is_mobile = True +elif session.is_mobile == 'false': + is_mobile = False +else: + is_mobile = request.user_agent().get('is_mobile',False) + +if DEMO_MODE: + session.authorized = True + session.forget() + +if request.controller == "webservices": + basic = request.env.http_authorization + if not basic or not basic[:6].lower() == 'basic ': + raise HTTP(401, "Wrong credentials") + (username, password) = base64.b64decode(basic[6:]).split(':') + if not verify_password(password) or MULTI_USER_MODE: + time.sleep(10) + raise HTTP(403, "Not authorized") +elif not session.authorized and not \ + (request.controller + '/' + request.function in + ('default/index', 'default/user', 'plugin_jqmobile/index', 'plugin_jqmobile/about')): + + if request.env.query_string: + query_string = '?' + request.env.query_string + else: + query_string = '' + + if request.env.web2py_original_uri: + url = request.env.web2py_original_uri + else: + url = request.env.path_info + query_string + redirect(URL(request.application, 'default', 'index', vars=dict(send=url))) +elif session.authorized and \ + request.controller == 'default' and \ + request.function == 'index': + redirect(URL(request.application, 'default', 'site')) + +if request.controller == 'appadmin' and DEMO_MODE: + session.flash = 'Appadmin disabled in demo mode' + redirect(URL('default', 'sites')) diff --git a/web2py/applications/admin/models/buttons.py b/web2py/applications/admin/models/buttons.py new file mode 100644 index 0000000..67d9ec9 --- /dev/null +++ b/web2py/applications/admin/models/buttons.py @@ -0,0 +1,40 @@ +# Template helpers + +import os + + +def A_button(*a, **b): + b['_data-role'] = 'button' + b['_data-inline'] = 'true' + return A(*a, **b) + +def button(href, label): + if is_mobile: + ret = A_button(SPAN(label), _href=href) + else: + ret = A(SPAN(label), _class='button btn', _href=href) + return ret + +def button_enable(href, app): + if os.path.exists(os.path.join(apath(app, r=request), 'DISABLED')): + label = SPAN(T('Enable'), _style='color:red') + else: + label = SPAN(T('Disable'), _style='color:green') + id = 'enable_' + app + return A(label, _class='button btn', _id=id, callback=href, target=id) + +def sp_button(href, label): + if request.user_agent().get('is_mobile'): + ret = A_button(SPAN(label), _href=href) + else: + ret = A(SPAN(label), _class='button special btn btn-inverse', _href=href) + return ret + +def helpicon(): + return IMG(_src=URL('static', 'images/help.png'), _alt='help') + +def searchbox(elementid): + return SPAN(LABEL(IMG(_id="search_start", _src=URL('static', 'images/search.png'), _alt=T('filter')), + _class='icon', _for=elementid), ' ', + INPUT(_id=elementid, _type='text', _size=12, _class="input-medium"), + _class="searchbox") diff --git a/web2py/applications/admin/models/db.py b/web2py/applications/admin/models/db.py new file mode 100644 index 0000000..d6871cb --- /dev/null +++ b/web2py/applications/admin/models/db.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# this file is released under public domain and you can use without limitations + +if MULTI_USER_MODE: + db = DAL('sqlite://storage.sqlite') # if not, use SQLite or other DB + from gluon.tools import * + auth = Auth( + globals(), db) # authentication/authorization + crud = Crud( + globals(), db) # for CRUD helpers using auth + service = Service( + globals()) # for json, xml, jsonrpc, xmlrpc, amfrpc + plugins = PluginManager() + + mail = auth.settings.mailer + mail.settings.server = EMAIL_SERVER + mail.settings.sender = EMAIL_SENDER + mail.settings.login = EMAIL_LOGIN + + auth.settings.extra_fields['auth_user'] = \ + [Field('is_manager', 'boolean', default=False, writable=False)] + auth.define_tables() # creates all needed tables + auth.settings.registration_requires_verification = False + auth.settings.registration_requires_approval = True + auth.settings.reset_password_requires_verification = True + + db.define_table('app', Field('name'), Field('owner', db.auth_user)) + +if not session.authorized and MULTI_USER_MODE: + if auth.user and not request.function == 'user': + session.authorized = True + elif not request.function == 'user': + redirect(URL('default', 'user/login')) + + +def is_manager(): + if not MULTI_USER_MODE: + return True + elif auth.user and (auth.user.id == 1 or auth.user.is_manager): + return True + else: + return False diff --git a/web2py/applications/admin/models/menu.py b/web2py/applications/admin/models/menu.py new file mode 100644 index 0000000..f29f904 --- /dev/null +++ b/web2py/applications/admin/models/menu.py @@ -0,0 +1,36 @@ +# ########################################################### +# ## generate menu +# ########################################################### + +_a = request.application +_c = request.controller +_f = request.function +response.title = '%s %s' % (_f, '/'.join(request.args)) +response.subtitle = 'admin' +response.menu = [(T('Site'), _f == 'site', URL(_a, 'default', 'site'))] + +if request.vars.app or request.args: + _t = request.vars.app or request.args[0] + response.menu.append((T('Edit'), _c == 'default' and _f == 'design', + URL(_a, 'default', 'design', args=_t))) + response.menu.append((T('About'), _c == 'default' and _f == 'about', + URL(_a, 'default', 'about', args=_t,))) + response.menu.append((T('Errors'), _c == 'default' and _f == 'errors', + URL(_a, 'default', 'errors', args=_t))) + response.menu.append((T('Versioning'), + _c == 'mercurial' and _f == 'commit', + URL(_a, 'mercurial', 'commit', args=_t))) + +if os.path.exists('applications/examples'): + response.menu.append( + (T('Help'), False, URL('examples', 'default', 'documentation'))) +else: + response.menu.append((T('Help'), False, 'http://web2py.com/examples/default/documentation')) + +if not session.authorized: + response.menu = [(T('Login'), True, URL('site'))] +else: + response.menu.append((T('Logout'), False, + URL(_a, 'default', f='logout'))) + response.menu.append((T('Debug'), False, + URL(_a, 'debug', 'interact'))) diff --git a/web2py/applications/admin/models/plugin_multiselect.py b/web2py/applications/admin/models/plugin_multiselect.py new file mode 100644 index 0000000..39fa2a1 --- /dev/null +++ b/web2py/applications/admin/models/plugin_multiselect.py @@ -0,0 +1,4 @@ +response.files.append( + URL('static', 'plugin_multiselect/jquery.multi-select.js')) +response.files.append(URL('static', 'plugin_multiselect/multi-select.css')) +response.files.append(URL('static', 'plugin_multiselect/start.js')) diff --git a/web2py/applications/admin/models/plugin_statebutton.py b/web2py/applications/admin/models/plugin_statebutton.py new file mode 100644 index 0000000..21d0377 --- /dev/null +++ b/web2py/applications/admin/models/plugin_statebutton.py @@ -0,0 +1,16 @@ +response.files.append(URL('static','plugin_statebutton/js/bootstrap-switch.js')) +response.files.append(URL('static','plugin_statebutton/css/bootstrap-switch.css')) + +def stateWidget(field, value, data={'on-label':'Enabled', 'off-label':'Disabled', 'on':"primary", 'off':"default" }): + try: + fieldName = str(field).split('.')[1] + except: + fieldName = field + + div = DIV(INPUT( _type='checkbox', _name='%s' % fieldName, _checked= 'checked' if value == 'true' else None, _value='true'), + _class='make-bootstrap-switch', + data=data) + script = SCRIPT(""" + jQuery(".make-bootstrap-switch input[name='%s']").parent().bootstrapSwitch(); + """ % fieldName) + return DIV(div, script) diff --git a/web2py/applications/admin/modules/__init__.py b/web2py/applications/admin/modules/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/web2py/applications/admin/modules/__init__.py @@ -0,0 +1 @@ + diff --git a/web2py/applications/admin/private/hosts.deny b/web2py/applications/admin/private/hosts.deny new file mode 100644 index 0000000..e69de29 diff --git a/web2py/applications/admin/sessions/037/09c/127.0.0.1-1c8a258c-88c4-42f9-b14c-8f5ca542f25b b/web2py/applications/admin/sessions/037/09c/127.0.0.1-1c8a258c-88c4-42f9-b14c-8f5ca542f25b new file mode 100644 index 0000000000000000000000000000000000000000..15b2b84e82b101601e768f0b409c069b2967c1bf GIT binary patch literal 347 zcmX|+Jx{|h5Qh0kQzBHsPw2qFk|;@&HvJI@L>9K_Qk)Or_>k?C35kWFk~fb3iyH$s zozBnu-1)=%emFgu$}CzwqKI0KHE=~{UNWV66!b;!bZdfMRRh*NXJkAWHIlikM#W?W zEfbpl@=Bw$lVkq3bNP!`4!S`(P!}A1o`Atp{vGU=_oc=6Oit@e@U%?gC|N~o8b9fg z%o(aF)GbV4@m^?D9jWQ3n6sfL;}D|X?T#up~Y-0ZTr*{&N1A{rTXt(=}h;Z4UizdAI2!ZN@e~x-H|l?sx57 zd()oGSL<=L?c;h=+Pt8{)VKM|)nP2ditfs8Y9ILH)DQgS$p3G3=3nkNG}V6Cw(jbv zx7g8^Q5Qc_di?a3;V;T?vYW4dc`U_J>ZNUm-`dY@{=6Sgr0#mYV)%MD^<&q@)4vC? zpW55`qHgF#Kb*B0_mFX{+I`i1eb#sshyEp}{fM}@rAot^A@f42r8s+ai?^pqCyJZG z!e{csslP9~Hs9o=1rlm7IUB$#4TO>eWOCVLp%M|c`EpO&Q#I|U`Lf$mTHTjd%r-U^ zozR1qA_1DLfwGHW$*1hB(7Mz%f5GK;{jh#ra{FVxPF+d&s}JRHx($ufYFcx7KYahs z``=%F`|R)eo7J&dc6mnoeHsc)<-7Cad3(-f-zcpsR)ri_SwImy1hfh$6f1R(A_U@u zlqH7Z0!WoKFn|+Anfd0lLgj=`yk|EFMJoIbK9>SWDFUI-5QH^88)H!khDk46^ie|+ z7y$zsh(-};>1whjRzW=PjfpWK>I^aX$}r=As!^b-L5tPd!cCM7AM23CY&XXmaM<7-R{n6X4V##EIC2K z(quF-|H?nYzk=Fb8woMV^i02R)mu;ZyNka*KKSDF%r|$NL%&-{E8wI8;v zTO8|M?9!H1S5H%Z{L>4TzoOyPZeINSSc;|8OVT?q*)Fe7&3cv1{XL z?*aBxdp}>*O?uT2=i02hWF1%S9(CWGYdplEf6ZzCRa`ykhMp62kLDW}mSU-m;jZFS z)9&K^Y2+#4hPcDI%H`DG)2_|8)ncG16CfrJMwxcCl{`h0Q$sOhU)n`haZj;7o zHLZDuAAk7panU{f``7uBIWU`N^S7%bYi{>T+VAr~X`=7Xub1s5BvOd(Sj~u(d@K%%tDMb;2&q`6E435O_@bR- znUGmoZ7WD51%_0Gh*Cq~4Ix4iQP)QQMRC}d|DkYB-}+#swkV-!A}~BJM8hY{$0{>cqoqfd743~T z#KdCY8C~TW1r`uSlS|%MgNkL*vOM#6RTA?@GJwh&5QsUe5M?BP%x1LErc@|FF#k%H Tvjv123ezfHij*6jF7fgogGo#> literal 0 HcmV?d00001 diff --git a/web2py/applications/admin/sessions/0dc/1e5/127.0.0.1-0f21193f-ae22-4031-8fd5-7502aeac37b7 b/web2py/applications/admin/sessions/0dc/1e5/127.0.0.1-0f21193f-ae22-4031-8fd5-7502aeac37b7 new file mode 100644 index 0000000000000000000000000000000000000000..e53c66339000ed73f29d41ca6bf8ea10e298abab GIT binary patch literal 603 zcmZ9Iy^ho{6ot`}ot=P2P$H@=C}>coG%~+}N_u`OfvZ3BJEOxi>Gn*>wjsM7vHg=(MwETd8%c2KUWfyXQ7+ zb=51@cGB4Z4n{fqusUctRj`wTad&=g)Z}lD{y(S1zaBd=dWj8i62(ha6Wq=}HNZOQ!HfCSsJ$GVeU@^;aZFQG z;*y{&BRQgFf)OD#;lOE;7yeJ{5&F3r_r|W99(c8vpS&AtL6bC3kxYsdWgL5sV1V+J zB{eNEmL+!ffiJgFQ~Oy8_tkEABl*6%E5}dQfi{(CeR;25{`~dC{0NDCS{aB@$(r UU<9HN9z!z#%qZrGgSoTlH%8>yHUIzs literal 0 HcmV?d00001 diff --git a/web2py/applications/admin/sessions/10d/1c5/127.0.0.1-35682bd4-e9cf-4132-a1ee-1a04633eae7e b/web2py/applications/admin/sessions/10d/1c5/127.0.0.1-35682bd4-e9cf-4132-a1ee-1a04633eae7e new file mode 100644 index 0000000000000000000000000000000000000000..95c9125e7c71ad471a9436788f11a4d5c7424f7f GIT binary patch literal 761 zcmZXS&2H2%6opZl{tT#sHLEVV03i=fY$x%O6)QlZ8zfXk*Y`F-IIKpefza{XS(9?MYjp7#YGnkbVG`VXE+RPSf#J& zV|pCt?NBd+X**1D2AeUYc)#8Z*w=7@t1;dBhcWbYvi1LY+WC*x9gIHo%hb%bd9xKP zNp&cH+8k|fTue8G3Kn%T{?=?JDn3f`Ib$8d?O z6i-V8#T``4YMnC)2ARn+%{1n@DODx2N~U+w%xSJU!!q+s zBIRfis!e=U zZ=0nl?_j;QJ;I33cDM6%PGz5J?>VA(%qc9GEXthG`kEAo{C;XRcvv&VcNolROXjooZ zqVfo=%7kay3Y&A`Orf{qOi?MxMZpBGkj80X#vo_TRMy$D(q7Y_bXr;mLeqN6Sk0t0 VlHh&DiV9_B3qX;pgwq#Y{07XY2ipJu literal 0 HcmV?d00001 diff --git a/web2py/applications/admin/sessions/127.0.0.1-0f21193f-ae22-4031-8fd5-7502aeac37b7 b/web2py/applications/admin/sessions/127.0.0.1-0f21193f-ae22-4031-8fd5-7502aeac37b7 new file mode 100644 index 0000000000000000000000000000000000000000..fc4024f727ff47f9fc48d3a788a567ec6170e889 GIT binary patch literal 693 zcmZXR*>BT85XRG{N19UZvs{4|2*;*bJ3jW22gDOpN?uk%ku_egYb(cQd=!CH2_aP? z{~&(};+e5SB_y8KJNwP=`#kfld4`Ry+-Wo#X&%f>m`*jW$ql+gSr}ZGyYv~9xy}MO z(enbE>SS7)c`q+aMwRyH?}-~{xY?C0k}sxE#3q~JRzk(?ZjGD6Ok+!K(fbEbo#PSi z$Zfiu>MT#q9NTpW+2Q>jw|g$`mgjhBhJ0HoZB&?vp5s$_NE};5iuZ-heC|7J zFmPNZe2X*3i5&$>c&?}MU^O_H)uYD4kM%v7feI%23qGq!5J$qYU7Kmkv)Mp#Vn!h_ z*AA^%_?&B><8#?2Q(9hPvh=Ht@Wl_gM-`Q5H3=@J-CgCMLS6(#N}GB4{_W3S`@avq zzmxl<4yyf;^Cws=RHmWON2_Cuug3U#6-R`9=yR7TUjW4ckBPpknSw|}mK}Ma7vmfF rk5?|De|c<-y_&}zC-OxYGFv#B4Y|Pfpi-eYZLEyXD=cPq-P|{P>o} zaoz9QZ|zO{a=u!Rt8Jgw8*1|c4^!XfC#%Cq!wTZkT@zNi~~)eq-v);(e!r*@xppPw@xr=fq%ZU0qV++xLH&60T`)l!^ib&GeW zO(#qn;^4FS(bV75uFW@|(29Zqa*PTLCW0hogh)yyZ-bG+wE1$6+Y_4h!+hCoF|Y3F zCwAv3OB7K6d0D{_=R~0mcnlm{3wfv7{3*lj`eFSumGs42#bICmhr*bgYo-J$WJXa5AxK>zW}TJLCAoOqF}Yxk&$Dr F<=;IoNSy!x literal 0 HcmV?d00001 diff --git a/web2py/applications/admin/sessions/127.0.0.1-7d4172c5-b4c3-41ec-a61b-eb366480f74d b/web2py/applications/admin/sessions/127.0.0.1-7d4172c5-b4c3-41ec-a61b-eb366480f74d new file mode 100644 index 0000000000000000000000000000000000000000..b0fe7a43a0f8526ddaeedecbcb8785b5719110f2 GIT binary patch literal 603 zcmZXQPm9zr7{+Do&dw-ytava_e1t(0#mXwSd-mceYi=G`jcS{3rj! ztr}BwS~RWlE`o#A-rX+_MvVpRRB!z)Z>%1}&5{3en)&6>g01w}`FeHqi+bpSYViW( z`KxV^U#W45bE~)K1ji(aGk^Hv-*|VT%>>nJw+iy6x7yU+OmBCEw*JN~sur&FIC}@( zY0w4N`a%70_Ba!xejld&t5|HIg0Tq_7ZDocIjfFtrk`36tqR67d}{Sx_1-K39%v~LFR4UA z5tUM!;~WBgFO*yBvH7S<|JAK!t>nJAEhkLZg0Y2dLU|X@fBquXkI&ECqvF_XNO=dt zAV&pOJ)O5pe|b!nB1w6O+T#DwyM;f#6s*XA&k|Jjs8(NbZAmE0i4 WfFKT#p-izVSEbBxntPZ!i+=;!gV-tn literal 0 HcmV?d00001 diff --git a/web2py/applications/admin/sessions/127.0.0.1-d4a94174-7f7f-434d-a74d-a7246b977b53 b/web2py/applications/admin/sessions/127.0.0.1-d4a94174-7f7f-434d-a74d-a7246b977b53 new file mode 100644 index 0000000000000000000000000000000000000000..2936a05e6c6392436f4b8cc53f736a67c3f2bfe6 GIT binary patch literal 1147 zcmZWn*^XO95S?VQOdP_#hHZdA%u-J8x0^S_0}>KJa$c^4Mpm!6*4VyN*VjQHMdBq= z=41FBK7y~H+$ItdFWp_;r>f35)qfm6#iMC^>*(lcxm~RLuv}%l(q5z3@5UalwzuiH z*lqK$@Q?Fm#N+sQwd*&t?br`=GkNsyj@O>z^=W%T@QalnOFyjfMn{)7r?uS1uQQ&s zH|YH*A5VXNgtyw86gHIU!&kS@@U=O<-X0Sy^dr7;S$mX~f6@>5=05AKDWzRMG^W09cav^k{hc|!TPcL0 z|CI#ddwcNRJ$TRZ`)=ro^84MSy+fg~Gd7b-5j|$`1Iqt!jvsYbE?<~8`mo9)etbz! zr*r(Ib{zZjyunY~dsLz5V6)>MLhubJsT|niJVc#LP|*e(5`K1Y(66iKc<*72yS0yt z^ZXlrUMrczl90s#*R&|5Em&hMh>``DUb`qce$h^-DNV8Khvn}%;r-`TNbGVvU%aq= z`n>XA`R%wEm!$X0AHMtR@B4rLcs8v9$VYPdtB37fDz?~9m1z9pFD~Mc{g@vdwlnVNz+KUG|Z?bNn?;#DC1FRsSEIs1*j|vxWFY?dSJ{Z=43&U|L4>0 zBK_AVd4}rXlQAq>Mc;u5W~g@x;FZ^qwWqUbN-+g>?JdcfTxph*4O_U2f1FxGKq{N(GW-G^mm_akT-8O=M?kIP(#| H&AZt@fFdsz literal 0 HcmV?d00001 diff --git a/web2py/applications/admin/sessions/127.0.0.1-dfc090b6-f2b7-41a3-88e4-1e2f94a9ee5f b/web2py/applications/admin/sessions/127.0.0.1-dfc090b6-f2b7-41a3-88e4-1e2f94a9ee5f new file mode 100644 index 0000000000000000000000000000000000000000..b5997134b4124434b14596862ff68a8ef71673c4 GIT binary patch literal 612 zcmZ9J!H&}~5Qfpxc3V(^Gp7~ez{Mp_T-!PBi4%)NFCesv#*WiOP2(zY7J;-97bI5l z4f71V5l0??r(l|}NZ^Yt`~Sb0`Tc3~?d{2(Vfp2@?rpQ$)>c8?1%J9RU02yAd=1y( znO{_0wzsOPP4E-woelne)_11OU~3u|ZvCCJE#4gce@>%+eyG6}w%vzvapX-J*rRIp z67<=t4a%=fJCyT_H)k|j(PYI#|2e!4{={~Jsa*O6%B#lNt_y1J{lRPsH#7yxs@PjUf@K(P8VA$LE literal 0 HcmV?d00001 diff --git a/web2py/applications/admin/sessions/179/0e6/127.0.0.1-dfc090b6-f2b7-41a3-88e4-1e2f94a9ee5f b/web2py/applications/admin/sessions/179/0e6/127.0.0.1-dfc090b6-f2b7-41a3-88e4-1e2f94a9ee5f new file mode 100644 index 0000000000000000000000000000000000000000..71c9eb48b40729ca834339595416a5a81ba6d56b GIT binary patch literal 461 zcmX|-y-ve06ovUoe*%i&5jrriBudgWX-6g|K%xsJY7$qmQv?zc3sNh2|d!CHf_uZZ5C~KD2ymV$cCy)zNy(twU<0Zb}Bc3WV6LG;w zmQz#))RLn*jB7!w7-qDTxYY~ED_z;>|8A|mzsNzRyeg2H8$Y9jLQ~xfNCsC^jW21{ zv{UBIz;hjM=!955<29;1E*cTDl&SHolw2?r&EG!Z64$Dm=CI^d>#ezt=Cmt2V#lpV zk5v3lPy0`Fr;tLGX+#;G@3?I*W~`e{C6JtI<5t{}d`?SLC&P$P8id3ilc8q^egrl^ zGPXy46a`Tdc%eT=)n7o-M1z;A&k9K5Ilb3v>ZL*AlF)XO)U^W$C-!8dpCdByeHzl# tPd!uzI$Xx9?1A3mN?8e`$vobMvr=XbLdG)F;hmp-et*4LKOfDM&MyQJtR(;d literal 0 HcmV?d00001 diff --git a/web2py/applications/admin/sessions/1f0/1bf/127.0.0.1-7d4172c5-b4c3-41ec-a61b-eb366480f74d b/web2py/applications/admin/sessions/1f0/1bf/127.0.0.1-7d4172c5-b4c3-41ec-a61b-eb366480f74d new file mode 100644 index 0000000000000000000000000000000000000000..ad6ee905d89efdb15b04e27b22488b3cee54ed9c GIT binary patch literal 461 zcmX|-yH3L}6o$E^mw+mGgboZyC{g03myApd2$1N)7TK;-M@{0&c8fqlVnJ#pZyYAx zhKJxG5Gy-wLh)qT-}fK;e|FwJc6X{}I@5e1N`IOQf^!9?HD*d>qJ&p?f>YyWDk%iX zat6l13oXDLCJV)6f~Tz1u=SM|(w=Pmzg_LO=Q-A?kOgpeljoGUuvGI3)9%gK;!7s0 zamKythJhdU`~fUp;1YN0r&>TaJ14Qta(bG#I?&bC~`ayFG8@#8w9 zMWnd5ul*;QW1M1{S;ROY@`HL7ch=QUH6}T;!L{7bV#Z1^Cutf}iiVLFpkUxdan$!n z8X*q_tRD>`ibg{Orai|+RSjI5HZL$uX6(V*VK9l~2qBO3!r0oBc<}^LkFb#S5gG*} sZ0!SEE*CO;WD{7K4&{u_l5IIF#p27RW}&?1P;9m{%(2buq|PYyFT3TyWX{QbL9Uyjr`fZf!?}y8>;zHZ?c0ep{7qk zpFdv_{0iH_&d*<-$I&uQmw7mR3@?H|aos?w7Jg3fde^(I3f=H_Te&`5`>Ac<%C)05 z;Z6xhs@1*f{-|-LTKAgL{zXhzV4hX1B~k&n95|%VwoDjwd9#G!O!-v9jXb>{H)r7E;smw*ohWgV4gB7(}ZywAyW~F z<;vP5icFRl#J)r2R<5nzq6we;LRY9agdQJ_+hw?8Dq~!6 U$s}^Y48)P)SjfbX-S7v?-!8iIjsO4v literal 0 HcmV?d00001 diff --git a/web2py/applications/admin/settings.cfg b/web2py/applications/admin/settings.cfg new file mode 100644 index 0000000..4127b27 --- /dev/null +++ b/web2py/applications/admin/settings.cfg @@ -0,0 +1,10 @@ +[DEFAULT] + +[editor] +theme = web2py +editor = default +closetag = true + +[editor_sessions] +welcome = welcome/models/db.py,welcome/controllers/default.py,welcome/views/default/index.html + diff --git a/web2py/applications/admin/static/codemirror/addon/comment/comment.js b/web2py/applications/admin/static/codemirror/addon/comment/comment.js new file mode 100644 index 0000000..2dd114d --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/comment/comment.js @@ -0,0 +1,183 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var noOptions = {}; + var nonWS = /[^\s\u00a0]/; + var Pos = CodeMirror.Pos; + + function firstNonWS(str) { + var found = str.search(nonWS); + return found == -1 ? 0 : found; + } + + CodeMirror.commands.toggleComment = function(cm) { + var minLine = Infinity, ranges = cm.listSelections(), mode = null; + for (var i = ranges.length - 1; i >= 0; i--) { + var from = ranges[i].from(), to = ranges[i].to(); + if (from.line >= minLine) continue; + if (to.line >= minLine) to = Pos(minLine, 0); + minLine = from.line; + if (mode == null) { + if (cm.uncomment(from, to)) mode = "un"; + else { cm.lineComment(from, to); mode = "line"; } + } else if (mode == "un") { + cm.uncomment(from, to); + } else { + cm.lineComment(from, to); + } + } + }; + + CodeMirror.defineExtension("lineComment", function(from, to, options) { + if (!options) options = noOptions; + var self = this, mode = self.getModeAt(from); + var commentString = options.lineComment || mode.lineComment; + if (!commentString) { + if (options.blockCommentStart || mode.blockCommentStart) { + options.fullLines = true; + self.blockComment(from, to, options); + } + return; + } + var firstLine = self.getLine(from.line); + if (firstLine == null) return; + var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1); + var pad = options.padding == null ? " " : options.padding; + var blankLines = options.commentBlankLines || from.line == to.line; + + self.operation(function() { + if (options.indent) { + var baseString = firstLine.slice(0, firstNonWS(firstLine)); + for (var i = from.line; i < end; ++i) { + var line = self.getLine(i), cut = baseString.length; + if (!blankLines && !nonWS.test(line)) continue; + if (line.slice(0, cut) != baseString) cut = firstNonWS(line); + self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut)); + } + } else { + for (var i = from.line; i < end; ++i) { + if (blankLines || nonWS.test(self.getLine(i))) + self.replaceRange(commentString + pad, Pos(i, 0)); + } + } + }); + }); + + CodeMirror.defineExtension("blockComment", function(from, to, options) { + if (!options) options = noOptions; + var self = this, mode = self.getModeAt(from); + var startString = options.blockCommentStart || mode.blockCommentStart; + var endString = options.blockCommentEnd || mode.blockCommentEnd; + if (!startString || !endString) { + if ((options.lineComment || mode.lineComment) && options.fullLines != false) + self.lineComment(from, to, options); + return; + } + + var end = Math.min(to.line, self.lastLine()); + if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end; + + var pad = options.padding == null ? " " : options.padding; + if (from.line > end) return; + + self.operation(function() { + if (options.fullLines != false) { + var lastLineHasText = nonWS.test(self.getLine(end)); + self.replaceRange(pad + endString, Pos(end)); + self.replaceRange(startString + pad, Pos(from.line, 0)); + var lead = options.blockCommentLead || mode.blockCommentLead; + if (lead != null) for (var i = from.line + 1; i <= end; ++i) + if (i != end || lastLineHasText) + self.replaceRange(lead + pad, Pos(i, 0)); + } else { + self.replaceRange(endString, to); + self.replaceRange(startString, from); + } + }); + }); + + CodeMirror.defineExtension("uncomment", function(from, to, options) { + if (!options) options = noOptions; + var self = this, mode = self.getModeAt(from); + var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end); + + // Try finding line comments + var lineString = options.lineComment || mode.lineComment, lines = []; + var pad = options.padding == null ? " " : options.padding, didSomething; + lineComment: { + if (!lineString) break lineComment; + for (var i = start; i <= end; ++i) { + var line = self.getLine(i); + var found = line.indexOf(lineString); + if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1; + if (found == -1 && (i != end || i == start) && nonWS.test(line)) break lineComment; + if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment; + lines.push(line); + } + self.operation(function() { + for (var i = start; i <= end; ++i) { + var line = lines[i - start]; + var pos = line.indexOf(lineString), endPos = pos + lineString.length; + if (pos < 0) continue; + if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length; + didSomething = true; + self.replaceRange("", Pos(i, pos), Pos(i, endPos)); + } + }); + if (didSomething) return true; + } + + // Try block comments + var startString = options.blockCommentStart || mode.blockCommentStart; + var endString = options.blockCommentEnd || mode.blockCommentEnd; + if (!startString || !endString) return false; + var lead = options.blockCommentLead || mode.blockCommentLead; + var startLine = self.getLine(start), endLine = end == start ? startLine : self.getLine(end); + var open = startLine.indexOf(startString), close = endLine.lastIndexOf(endString); + if (close == -1 && start != end) { + endLine = self.getLine(--end); + close = endLine.lastIndexOf(endString); + } + if (open == -1 || close == -1 || + !/comment/.test(self.getTokenTypeAt(Pos(start, open + 1))) || + !/comment/.test(self.getTokenTypeAt(Pos(end, close + 1)))) + return false; + + // Avoid killing block comments completely outside the selection. + // Positions of the last startString before the start of the selection, and the first endString after it. + var lastStart = startLine.lastIndexOf(startString, from.ch); + var firstEnd = lastStart == -1 ? -1 : startLine.slice(0, from.ch).indexOf(endString, lastStart + startString.length); + if (lastStart != -1 && firstEnd != -1 && firstEnd + endString.length != from.ch) return false; + // Positions of the first endString after the end of the selection, and the last startString before it. + firstEnd = endLine.indexOf(endString, to.ch); + var almostLastStart = endLine.slice(to.ch).lastIndexOf(startString, firstEnd - to.ch); + lastStart = (firstEnd == -1 || almostLastStart == -1) ? -1 : to.ch + almostLastStart; + if (firstEnd != -1 && lastStart != -1 && lastStart != to.ch) return false; + + self.operation(function() { + self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)), + Pos(end, close + endString.length)); + var openEnd = open + startString.length; + if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length; + self.replaceRange("", Pos(start, open), Pos(start, openEnd)); + if (lead) for (var i = start + 1; i <= end; ++i) { + var line = self.getLine(i), found = line.indexOf(lead); + if (found == -1 || nonWS.test(line.slice(0, found))) continue; + var foundEnd = found + lead.length; + if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length; + self.replaceRange("", Pos(i, found), Pos(i, foundEnd)); + } + }); + return true; + }); +}); diff --git a/web2py/applications/admin/static/codemirror/addon/comment/continuecomment.js b/web2py/applications/admin/static/codemirror/addon/comment/continuecomment.js new file mode 100644 index 0000000..b11d51e --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/comment/continuecomment.js @@ -0,0 +1,85 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + var modes = ["clike", "css", "javascript"]; + + for (var i = 0; i < modes.length; ++i) + CodeMirror.extendMode(modes[i], {blockCommentContinue: " * "}); + + function continueComment(cm) { + if (cm.getOption("disableInput")) return CodeMirror.Pass; + var ranges = cm.listSelections(), mode, inserts = []; + for (var i = 0; i < ranges.length; i++) { + var pos = ranges[i].head, token = cm.getTokenAt(pos); + if (token.type != "comment") return CodeMirror.Pass; + var modeHere = CodeMirror.innerMode(cm.getMode(), token.state).mode; + if (!mode) mode = modeHere; + else if (mode != modeHere) return CodeMirror.Pass; + + var insert = null; + if (mode.blockCommentStart && mode.blockCommentContinue) { + var end = token.string.indexOf(mode.blockCommentEnd); + var full = cm.getRange(CodeMirror.Pos(pos.line, 0), CodeMirror.Pos(pos.line, token.end)), found; + if (end != -1 && end == token.string.length - mode.blockCommentEnd.length && pos.ch >= end) { + // Comment ended, don't continue it + } else if (token.string.indexOf(mode.blockCommentStart) == 0) { + insert = full.slice(0, token.start); + if (!/^\s*$/.test(insert)) { + insert = ""; + for (var j = 0; j < token.start; ++j) insert += " "; + } + } else if ((found = full.indexOf(mode.blockCommentContinue)) != -1 && + found + mode.blockCommentContinue.length > token.start && + /^\s*$/.test(full.slice(0, found))) { + insert = full.slice(0, found); + } + if (insert != null) insert += mode.blockCommentContinue; + } + if (insert == null && mode.lineComment && continueLineCommentEnabled(cm)) { + var line = cm.getLine(pos.line), found = line.indexOf(mode.lineComment); + if (found > -1) { + insert = line.slice(0, found); + if (/\S/.test(insert)) insert = null; + else insert += mode.lineComment + line.slice(found + mode.lineComment.length).match(/^\s*/)[0]; + } + } + if (insert == null) return CodeMirror.Pass; + inserts[i] = "\n" + insert; + } + + cm.operation(function() { + for (var i = ranges.length - 1; i >= 0; i--) + cm.replaceRange(inserts[i], ranges[i].from(), ranges[i].to(), "+insert"); + }); + } + + function continueLineCommentEnabled(cm) { + var opt = cm.getOption("continueComments"); + if (opt && typeof opt == "object") + return opt.continueLineComment !== false; + return true; + } + + CodeMirror.defineOption("continueComments", null, function(cm, val, prev) { + if (prev && prev != CodeMirror.Init) + cm.removeKeyMap("continueComment"); + if (val) { + var key = "Enter"; + if (typeof val == "string") + key = val; + else if (typeof val == "object" && val.key) + key = val.key; + var map = {name: "continueComment"}; + map[key] = continueComment; + cm.addKeyMap(map); + } + }); +}); diff --git a/web2py/applications/admin/static/codemirror/addon/dialog/dialog.css b/web2py/applications/admin/static/codemirror/addon/dialog/dialog.css new file mode 100644 index 0000000..2e7c0fc --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/dialog/dialog.css @@ -0,0 +1,32 @@ +.CodeMirror-dialog { + position: absolute; + left: 0; right: 0; + background: white; + z-index: 15; + padding: .1em .8em; + overflow: hidden; + color: #333; +} + +.CodeMirror-dialog-top { + border-bottom: 1px solid #eee; + top: 0; +} + +.CodeMirror-dialog-bottom { + border-top: 1px solid #eee; + bottom: 0; +} + +.CodeMirror-dialog input { + border: none; + outline: none; + background: transparent; + width: 20em; + color: inherit; + font-family: monospace; +} + +.CodeMirror-dialog button { + font-size: 70%; +} diff --git a/web2py/applications/admin/static/codemirror/addon/dialog/dialog.js b/web2py/applications/admin/static/codemirror/addon/dialog/dialog.js new file mode 100644 index 0000000..e0e8ad4 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/dialog/dialog.js @@ -0,0 +1,155 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Open simple dialogs on top of an editor. Relies on dialog.css. + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + function dialogDiv(cm, template, bottom) { + var wrap = cm.getWrapperElement(); + var dialog; + dialog = wrap.appendChild(document.createElement("div")); + if (bottom) + dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom"; + else + dialog.className = "CodeMirror-dialog CodeMirror-dialog-top"; + + if (typeof template == "string") { + dialog.innerHTML = template; + } else { // Assuming it's a detached DOM element. + dialog.appendChild(template); + } + return dialog; + } + + function closeNotification(cm, newVal) { + if (cm.state.currentNotificationClose) + cm.state.currentNotificationClose(); + cm.state.currentNotificationClose = newVal; + } + + CodeMirror.defineExtension("openDialog", function(template, callback, options) { + if (!options) options = {}; + + closeNotification(this, null); + + var dialog = dialogDiv(this, template, options.bottom); + var closed = false, me = this; + function close(newVal) { + if (typeof newVal == 'string') { + inp.value = newVal; + } else { + if (closed) return; + closed = true; + dialog.parentNode.removeChild(dialog); + me.focus(); + + if (options.onClose) options.onClose(dialog); + } + } + + var inp = dialog.getElementsByTagName("input")[0], button; + if (inp) { + if (options.value) { + inp.value = options.value; + inp.select(); + } + + if (options.onInput) + CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);}); + if (options.onKeyUp) + CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);}); + + CodeMirror.on(inp, "keydown", function(e) { + if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; } + if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) { + inp.blur(); + CodeMirror.e_stop(e); + close(); + } + if (e.keyCode == 13) callback(inp.value, e); + }); + + if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close); + + inp.focus(); + } else if (button = dialog.getElementsByTagName("button")[0]) { + CodeMirror.on(button, "click", function() { + close(); + me.focus(); + }); + + if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close); + + button.focus(); + } + return close; + }); + + CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) { + closeNotification(this, null); + var dialog = dialogDiv(this, template, options && options.bottom); + var buttons = dialog.getElementsByTagName("button"); + var closed = false, me = this, blurring = 1; + function close() { + if (closed) return; + closed = true; + dialog.parentNode.removeChild(dialog); + me.focus(); + } + buttons[0].focus(); + for (var i = 0; i < buttons.length; ++i) { + var b = buttons[i]; + (function(callback) { + CodeMirror.on(b, "click", function(e) { + CodeMirror.e_preventDefault(e); + close(); + if (callback) callback(me); + }); + })(callbacks[i]); + CodeMirror.on(b, "blur", function() { + --blurring; + setTimeout(function() { if (blurring <= 0) close(); }, 200); + }); + CodeMirror.on(b, "focus", function() { ++blurring; }); + } + }); + + /* + * openNotification + * Opens a notification, that can be closed with an optional timer + * (default 5000ms timer) and always closes on click. + * + * If a notification is opened while another is opened, it will close the + * currently opened one and open the new one immediately. + */ + CodeMirror.defineExtension("openNotification", function(template, options) { + closeNotification(this, close); + var dialog = dialogDiv(this, template, options && options.bottom); + var closed = false, doneTimer; + var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000; + + function close() { + if (closed) return; + closed = true; + clearTimeout(doneTimer); + dialog.parentNode.removeChild(dialog); + } + + CodeMirror.on(dialog, 'click', function(e) { + CodeMirror.e_preventDefault(e); + close(); + }); + + if (duration) + doneTimer = setTimeout(close, duration); + + return close; + }); +}); diff --git a/web2py/applications/admin/static/codemirror/addon/display/fullscreen.css b/web2py/applications/admin/static/codemirror/addon/display/fullscreen.css new file mode 100644 index 0000000..437acd8 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/display/fullscreen.css @@ -0,0 +1,6 @@ +.CodeMirror-fullscreen { + position: fixed; + top: 0; left: 0; right: 0; bottom: 0; + height: auto; + z-index: 9; +} diff --git a/web2py/applications/admin/static/codemirror/addon/display/fullscreen.js b/web2py/applications/admin/static/codemirror/addon/display/fullscreen.js new file mode 100644 index 0000000..cd3673b --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/display/fullscreen.js @@ -0,0 +1,41 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineOption("fullScreen", false, function(cm, val, old) { + if (old == CodeMirror.Init) old = false; + if (!old == !val) return; + if (val) setFullscreen(cm); + else setNormal(cm); + }); + + function setFullscreen(cm) { + var wrap = cm.getWrapperElement(); + cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset, + width: wrap.style.width, height: wrap.style.height}; + wrap.style.width = ""; + wrap.style.height = "auto"; + wrap.className += " CodeMirror-fullscreen"; + document.documentElement.style.overflow = "hidden"; + cm.refresh(); + } + + function setNormal(cm) { + var wrap = cm.getWrapperElement(); + wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, ""); + document.documentElement.style.overflow = ""; + var info = cm.state.fullScreenRestore; + wrap.style.width = info.width; wrap.style.height = info.height; + window.scrollTo(info.scrollLeft, info.scrollTop); + cm.refresh(); + } +}); diff --git a/web2py/applications/admin/static/codemirror/addon/display/panel.js b/web2py/applications/admin/static/codemirror/addon/display/panel.js new file mode 100644 index 0000000..22c0453 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/display/panel.js @@ -0,0 +1,94 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + CodeMirror.defineExtension("addPanel", function(node, options) { + if (!this.state.panels) initPanels(this); + + var info = this.state.panels; + if (options && options.position == "bottom") + info.wrapper.appendChild(node); + else + info.wrapper.insertBefore(node, info.wrapper.firstChild); + var height = (options && options.height) || node.offsetHeight; + this._setSize(null, info.heightLeft -= height); + info.panels++; + return new Panel(this, node, options, height); + }); + + function Panel(cm, node, options, height) { + this.cm = cm; + this.node = node; + this.options = options; + this.height = height; + this.cleared = false; + } + + Panel.prototype.clear = function() { + if (this.cleared) return; + this.cleared = true; + var info = this.cm.state.panels; + this.cm._setSize(null, info.heightLeft += this.height); + info.wrapper.removeChild(this.node); + if (--info.panels == 0) removePanels(this.cm); + }; + + Panel.prototype.changed = function(height) { + var newHeight = height == null ? this.node.offsetHeight : height; + var info = this.cm.state.panels; + this.cm._setSize(null, info.height += (newHeight - this.height)); + this.height = newHeight; + }; + + function initPanels(cm) { + var wrap = cm.getWrapperElement(); + var style = window.getComputedStyle ? window.getComputedStyle(wrap) : wrap.currentStyle; + var height = parseInt(style.height); + var info = cm.state.panels = { + setHeight: wrap.style.height, + heightLeft: height, + panels: 0, + wrapper: document.createElement("div") + }; + wrap.parentNode.insertBefore(info.wrapper, wrap); + var hasFocus = cm.hasFocus(); + info.wrapper.appendChild(wrap); + if (hasFocus) cm.focus(); + + cm._setSize = cm.setSize; + if (height != null) cm.setSize = function(width, newHeight) { + if (newHeight == null) return this._setSize(width, newHeight); + info.setHeight = newHeight; + if (typeof newHeight != "number") { + var px = /^(\d+\.?\d*)px$/.exec(newHeight); + if (px) { + newHeight = Number(px[1]); + } else { + info.wrapper.style.height = newHeight; + newHeight = info.wrapper.offsetHeight; + info.wrapper.style.height = ""; + } + } + cm._setSize(width, info.heightLeft += (newHeight - height)); + height = newHeight; + }; + } + + function removePanels(cm) { + var info = cm.state.panels; + cm.state.panels = null; + + var wrap = cm.getWrapperElement(); + info.wrapper.parentNode.replaceChild(wrap, info.wrapper); + wrap.style.height = info.setHeight; + cm.setSize = cm._setSize; + cm.setSize(); + } +}); diff --git a/web2py/applications/admin/static/codemirror/addon/display/placeholder.js b/web2py/applications/admin/static/codemirror/addon/display/placeholder.js new file mode 100644 index 0000000..bb0c393 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/display/placeholder.js @@ -0,0 +1,58 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + CodeMirror.defineOption("placeholder", "", function(cm, val, old) { + var prev = old && old != CodeMirror.Init; + if (val && !prev) { + cm.on("blur", onBlur); + cm.on("change", onChange); + onChange(cm); + } else if (!val && prev) { + cm.off("blur", onBlur); + cm.off("change", onChange); + clearPlaceholder(cm); + var wrapper = cm.getWrapperElement(); + wrapper.className = wrapper.className.replace(" CodeMirror-empty", ""); + } + + if (val && !cm.hasFocus()) onBlur(cm); + }); + + function clearPlaceholder(cm) { + if (cm.state.placeholder) { + cm.state.placeholder.parentNode.removeChild(cm.state.placeholder); + cm.state.placeholder = null; + } + } + function setPlaceholder(cm) { + clearPlaceholder(cm); + var elt = cm.state.placeholder = document.createElement("pre"); + elt.style.cssText = "height: 0; overflow: visible"; + elt.className = "CodeMirror-placeholder"; + elt.appendChild(document.createTextNode(cm.getOption("placeholder"))); + cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild); + } + + function onBlur(cm) { + if (isEmpty(cm)) setPlaceholder(cm); + } + function onChange(cm) { + var wrapper = cm.getWrapperElement(), empty = isEmpty(cm); + wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : ""); + + if (empty) setPlaceholder(cm); + else clearPlaceholder(cm); + } + + function isEmpty(cm) { + return (cm.lineCount() === 1) && (cm.getLine(0) === ""); + } +}); diff --git a/web2py/applications/admin/static/codemirror/addon/display/rulers.js b/web2py/applications/admin/static/codemirror/addon/display/rulers.js new file mode 100644 index 0000000..13185d3 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/display/rulers.js @@ -0,0 +1,64 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineOption("rulers", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + clearRulers(cm); + cm.off("refresh", refreshRulers); + } + if (val && val.length) { + setRulers(cm); + cm.on("refresh", refreshRulers); + } + }); + + function clearRulers(cm) { + for (var i = cm.display.lineSpace.childNodes.length - 1; i >= 0; i--) { + var node = cm.display.lineSpace.childNodes[i]; + if (/(^|\s)CodeMirror-ruler($|\s)/.test(node.className)) + node.parentNode.removeChild(node); + } + } + + function setRulers(cm) { + var val = cm.getOption("rulers"); + var cw = cm.defaultCharWidth(); + var left = cm.charCoords(CodeMirror.Pos(cm.firstLine(), 0), "div").left; + var minH = cm.display.scroller.offsetHeight + 30; + for (var i = 0; i < val.length; i++) { + var elt = document.createElement("div"); + elt.className = "CodeMirror-ruler"; + var col, cls = null, conf = val[i]; + if (typeof conf == "number") { + col = conf; + } else { + col = conf.column; + if (conf.className) elt.className += " " + conf.className; + if (conf.color) elt.style.borderColor = conf.color; + if (conf.lineStyle) elt.style.borderLeftStyle = conf.lineStyle; + if (conf.width) elt.style.borderLeftWidth = conf.width; + cls = val[i].className; + } + elt.style.left = (left + col * cw) + "px"; + elt.style.top = "-50px"; + elt.style.bottom = "-20px"; + elt.style.minHeight = minH + "px"; + cm.display.lineSpace.insertBefore(elt, cm.display.cursorDiv); + } + } + + function refreshRulers(cm) { + clearRulers(cm); + setRulers(cm); + } +}); diff --git a/web2py/applications/admin/static/codemirror/addon/edit/closebrackets.js b/web2py/applications/admin/static/codemirror/addon/edit/closebrackets.js new file mode 100644 index 0000000..ff4bb3f --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/edit/closebrackets.js @@ -0,0 +1,161 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + var DEFAULT_BRACKETS = "()[]{}''\"\""; + var DEFAULT_TRIPLES = "'\""; + var DEFAULT_EXPLODE_ON_ENTER = "[]{}"; + var SPACE_CHAR_REGEX = /\s/; + + var Pos = CodeMirror.Pos; + + CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) { + if (old != CodeMirror.Init && old) + cm.removeKeyMap("autoCloseBrackets"); + if (!val) return; + var pairs = DEFAULT_BRACKETS, triples = DEFAULT_TRIPLES, explode = DEFAULT_EXPLODE_ON_ENTER; + if (typeof val == "string") pairs = val; + else if (typeof val == "object") { + if (val.pairs != null) pairs = val.pairs; + if (val.triples != null) triples = val.triples; + if (val.explode != null) explode = val.explode; + } + var map = buildKeymap(pairs, triples); + if (explode) map.Enter = buildExplodeHandler(explode); + cm.addKeyMap(map); + }); + + function charsAround(cm, pos) { + var str = cm.getRange(Pos(pos.line, pos.ch - 1), + Pos(pos.line, pos.ch + 1)); + return str.length == 2 ? str : null; + } + + // Project the token type that will exists after the given char is + // typed, and use it to determine whether it would cause the start + // of a string token. + function enteringString(cm, pos, ch) { + var line = cm.getLine(pos.line); + var token = cm.getTokenAt(pos); + if (/\bstring2?\b/.test(token.type)) return false; + var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4); + stream.pos = stream.start = token.start; + for (;;) { + var type1 = cm.getMode().token(stream, token.state); + if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1); + stream.start = stream.pos; + } + } + + function buildKeymap(pairs, triples) { + var map = { + name : "autoCloseBrackets", + Backspace: function(cm) { + if (cm.getOption("disableInput")) return CodeMirror.Pass; + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) return CodeMirror.Pass; + var around = charsAround(cm, ranges[i].head); + if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; + } + for (var i = ranges.length - 1; i >= 0; i--) { + var cur = ranges[i].head; + cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1)); + } + } + }; + var closingBrackets = ""; + for (var i = 0; i < pairs.length; i += 2) (function(left, right) { + closingBrackets += right; + map["'" + left + "'"] = function(cm) { + if (cm.getOption("disableInput")) return CodeMirror.Pass; + var ranges = cm.listSelections(), type, next; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i], cur = range.head, curType; + var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1)); + if (!range.empty()) { + curType = "surround"; + } else if (left == right && next == right) { + if (cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == left + left + left) + curType = "skipThree"; + else + curType = "skip"; + } else if (left == right && cur.ch > 1 && triples.indexOf(left) >= 0 && + cm.getRange(Pos(cur.line, cur.ch - 2), cur) == left + left && + (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != left)) { + curType = "addFour"; + } else if (left == '"' || left == "'") { + if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, left)) curType = "both"; + else return CodeMirror.Pass; + } else if (cm.getLine(cur.line).length == cur.ch || closingBrackets.indexOf(next) >= 0 || SPACE_CHAR_REGEX.test(next)) { + curType = "both"; + } else { + return CodeMirror.Pass; + } + if (!type) type = curType; + else if (type != curType) return CodeMirror.Pass; + } + + cm.operation(function() { + if (type == "skip") { + cm.execCommand("goCharRight"); + } else if (type == "skipThree") { + for (var i = 0; i < 3; i++) + cm.execCommand("goCharRight"); + } else if (type == "surround") { + var sels = cm.getSelections(); + for (var i = 0; i < sels.length; i++) + sels[i] = left + sels[i] + right; + cm.replaceSelections(sels, "around"); + } else if (type == "both") { + cm.replaceSelection(left + right, null); + cm.execCommand("goCharLeft"); + } else if (type == "addFour") { + cm.replaceSelection(left + left + left + left, "before"); + cm.execCommand("goCharRight"); + } + }); + }; + if (left != right) map["'" + right + "'"] = function(cm) { + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (!range.empty() || + cm.getRange(range.head, Pos(range.head.line, range.head.ch + 1)) != right) + return CodeMirror.Pass; + } + cm.execCommand("goCharRight"); + }; + })(pairs.charAt(i), pairs.charAt(i + 1)); + return map; + } + + function buildExplodeHandler(pairs) { + return function(cm) { + if (cm.getOption("disableInput")) return CodeMirror.Pass; + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) return CodeMirror.Pass; + var around = charsAround(cm, ranges[i].head); + if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; + } + cm.operation(function() { + cm.replaceSelection("\n\n", null); + cm.execCommand("goCharLeft"); + ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var line = ranges[i].head.line; + cm.indentLine(line, null, true); + cm.indentLine(line + 1, null, true); + } + }); + }; + } +}); diff --git a/web2py/applications/admin/static/codemirror/addon/edit/closetag.js b/web2py/applications/admin/static/codemirror/addon/edit/closetag.js new file mode 100644 index 0000000..e68d52d --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/edit/closetag.js @@ -0,0 +1,166 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +/** + * Tag-closer extension for CodeMirror. + * + * This extension adds an "autoCloseTags" option that can be set to + * either true to get the default behavior, or an object to further + * configure its behavior. + * + * These are supported options: + * + * `whenClosing` (default true) + * Whether to autoclose when the '/' of a closing tag is typed. + * `whenOpening` (default true) + * Whether to autoclose the tag when the final '>' of an opening + * tag is typed. + * `dontCloseTags` (default is empty tags for HTML, none for XML) + * An array of tag names that should not be autoclosed. + * `indentTags` (default is block tags for HTML, none for XML) + * An array of tag names that should, when opened, cause a + * blank line to be added inside the tag, and the blank line and + * closing line to be indented. + * + * See demos/closetag.html for a usage example. + */ + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../fold/xml-fold")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../fold/xml-fold"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) { + if (old != CodeMirror.Init && old) + cm.removeKeyMap("autoCloseTags"); + if (!val) return; + var map = {name: "autoCloseTags"}; + if (typeof val != "object" || val.whenClosing) + map["'/'"] = function(cm) { return autoCloseSlash(cm); }; + if (typeof val != "object" || val.whenOpening) + map["'>'"] = function(cm) { return autoCloseGT(cm); }; + cm.addKeyMap(map); + }); + + var htmlDontClose = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", + "source", "track", "wbr"]; + var htmlIndent = ["applet", "blockquote", "body", "button", "div", "dl", "fieldset", "form", "frameset", "h1", "h2", "h3", "h4", + "h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"]; + + function autoCloseGT(cm) { + if (cm.getOption("disableInput")) return CodeMirror.Pass; + var ranges = cm.listSelections(), replacements = []; + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) return CodeMirror.Pass; + var pos = ranges[i].head, tok = cm.getTokenAt(pos); + var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state; + if (inner.mode.name != "xml" || !state.tagName) return CodeMirror.Pass; + + var opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html"; + var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose); + var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent); + + var tagName = state.tagName; + if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch); + var lowerTagName = tagName.toLowerCase(); + // Don't process the '>' at the end of an end-tag or self-closing tag + if (!tagName || + tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) || + tok.type == "tag" && state.type == "closeTag" || + tok.string.indexOf("/") == (tok.string.length - 1) || // match something like + dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1 || + closingTagExists(cm, tagName, pos, state, true)) + return CodeMirror.Pass; + + var indent = indentTags && indexOf(indentTags, lowerTagName) > -1; + replacements[i] = {indent: indent, + text: ">" + (indent ? "\n\n" : "") + "", + newPos: indent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1)}; + } + + for (var i = ranges.length - 1; i >= 0; i--) { + var info = replacements[i]; + cm.replaceRange(info.text, ranges[i].head, ranges[i].anchor, "+insert"); + var sel = cm.listSelections().slice(0); + sel[i] = {head: info.newPos, anchor: info.newPos}; + cm.setSelections(sel); + if (info.indent) { + cm.indentLine(info.newPos.line, null, true); + cm.indentLine(info.newPos.line + 1, null, true); + } + } + } + + function autoCloseCurrent(cm, typingSlash) { + var ranges = cm.listSelections(), replacements = []; + var head = typingSlash ? "/" : ""; + else if (cm.getMode().name == "htmlmixed" && inner.mode.name == "css") + replacements[i] = head + "style>"; + else + return CodeMirror.Pass; + } else { + if (!state.context || !state.context.tagName || + closingTagExists(cm, state.context.tagName, pos, state)) + return CodeMirror.Pass; + replacements[i] = head + state.context.tagName + ">"; + } + } + cm.replaceSelections(replacements); + ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) + if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line) + cm.indentLine(ranges[i].head.line); + } + + function autoCloseSlash(cm) { + if (cm.getOption("disableInput")) return CodeMirror.Pass; + return autoCloseCurrent(cm, true); + } + + CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); }; + + function indexOf(collection, elt) { + if (collection.indexOf) return collection.indexOf(elt); + for (var i = 0, e = collection.length; i < e; ++i) + if (collection[i] == elt) return i; + return -1; + } + + // If xml-fold is loaded, we use its functionality to try and verify + // whether a given tag is actually unclosed. + function closingTagExists(cm, tagName, pos, state, newTag) { + if (!CodeMirror.scanForClosingTag) return false; + var end = Math.min(cm.lastLine() + 1, pos.line + 500); + var nextClose = CodeMirror.scanForClosingTag(cm, pos, null, end); + if (!nextClose || nextClose.tag != tagName) return false; + var cx = state.context; + // If the immediate wrapping context contains onCx instances of + // the same tag, a closing tag only exists if there are at least + // that many closing tags of that type following. + for (var onCx = newTag ? 1 : 0; cx && cx.tagName == tagName; cx = cx.prev) ++onCx; + pos = nextClose.to; + for (var i = 1; i < onCx; i++) { + var next = CodeMirror.scanForClosingTag(cm, pos, null, end); + if (!next || next.tag != tagName) return false; + pos = next.to; + } + return true; + } +}); diff --git a/web2py/applications/admin/static/codemirror/addon/edit/continuelist.js b/web2py/applications/admin/static/codemirror/addon/edit/continuelist.js new file mode 100644 index 0000000..ca8d267 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/edit/continuelist.js @@ -0,0 +1,51 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var listRE = /^(\s*)(>[> ]*|[*+-]\s|(\d+)\.)(\s*)/, + emptyListRE = /^(\s*)(>[> ]*|[*+-]|(\d+)\.)(\s*)$/, + unorderedListRE = /[*+-]\s/; + + CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) { + if (cm.getOption("disableInput")) return CodeMirror.Pass; + var ranges = cm.listSelections(), replacements = []; + for (var i = 0; i < ranges.length; i++) { + var pos = ranges[i].head, match; + var eolState = cm.getStateAfter(pos.line); + var inList = eolState.list !== false; + var inQuote = eolState.quote !== false; + + if (!ranges[i].empty() || (!inList && !inQuote) || !(match = cm.getLine(pos.line).match(listRE))) { + cm.execCommand("newlineAndIndent"); + return; + } + if (cm.getLine(pos.line).match(emptyListRE)) { + cm.replaceRange("", { + line: pos.line, ch: 0 + }, { + line: pos.line, ch: pos.ch + 1 + }); + replacements[i] = "\n"; + + } else { + var indent = match[1], after = match[4]; + var bullet = unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0 + ? match[2] + : (parseInt(match[3], 10) + 1) + "."; + + replacements[i] = "\n" + indent + bullet + after; + } + } + + cm.replaceSelections(replacements); + }; +}); diff --git a/web2py/applications/admin/static/codemirror/addon/edit/matchbrackets.js b/web2py/applications/admin/static/codemirror/addon/edit/matchbrackets.js new file mode 100644 index 0000000..fa1ae03 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/edit/matchbrackets.js @@ -0,0 +1,120 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + var ie_lt8 = /MSIE \d/.test(navigator.userAgent) && + (document.documentMode == null || document.documentMode < 8); + + var Pos = CodeMirror.Pos; + + var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"}; + + function findMatchingBracket(cm, where, strict, config) { + var line = cm.getLineHandle(where.line), pos = where.ch - 1; + var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)]; + if (!match) return null; + var dir = match.charAt(1) == ">" ? 1 : -1; + if (strict && (dir > 0) != (pos == where.ch)) return null; + var style = cm.getTokenTypeAt(Pos(where.line, pos + 1)); + + var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config); + if (found == null) return null; + return {from: Pos(where.line, pos), to: found && found.pos, + match: found && found.ch == match.charAt(0), forward: dir > 0}; + } + + // bracketRegex is used to specify which type of bracket to scan + // should be a regexp, e.g. /[[\]]/ + // + // Note: If "where" is on an open bracket, then this bracket is ignored. + // + // Returns false when no bracket was found, null when it reached + // maxScanLines and gave up + function scanForBracket(cm, where, dir, style, config) { + var maxScanLen = (config && config.maxScanLineLength) || 10000; + var maxScanLines = (config && config.maxScanLines) || 1000; + + var stack = []; + var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/; + var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1) + : Math.max(cm.firstLine() - 1, where.line - maxScanLines); + for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) { + var line = cm.getLine(lineNo); + if (!line) continue; + var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1; + if (line.length > maxScanLen) continue; + if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0); + for (; pos != end; pos += dir) { + var ch = line.charAt(pos); + if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) { + var match = matching[ch]; + if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch); + else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch}; + else stack.pop(); + } + } + } + return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null; + } + + function matchBrackets(cm, autoclear, config) { + // Disable brace matching in long lines, since it'll cause hugely slow updates + var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000; + var marks = [], ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config); + if (match && cm.getLine(match.from.line).length <= maxHighlightLen) { + var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket"; + marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style})); + if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen) + marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style})); + } + } + + if (marks.length) { + // Kludge to work around the IE bug from issue #1193, where text + // input stops going to the textare whever this fires. + if (ie_lt8 && cm.state.focused) cm.display.input.focus(); + + var clear = function() { + cm.operation(function() { + for (var i = 0; i < marks.length; i++) marks[i].clear(); + }); + }; + if (autoclear) setTimeout(clear, 800); + else return clear; + } + } + + var currentlyHighlighted = null; + function doMatchBrackets(cm) { + cm.operation(function() { + if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} + currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); + }); + } + + CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) + cm.off("cursorActivity", doMatchBrackets); + if (val) { + cm.state.matchBrackets = typeof val == "object" ? val : {}; + cm.on("cursorActivity", doMatchBrackets); + } + }); + + CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);}); + CodeMirror.defineExtension("findMatchingBracket", function(pos, strict, config){ + return findMatchingBracket(this, pos, strict, config); + }); + CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){ + return scanForBracket(this, pos, dir, style, config); + }); +}); diff --git a/web2py/applications/admin/static/codemirror/addon/edit/matchtags.js b/web2py/applications/admin/static/codemirror/addon/edit/matchtags.js new file mode 100644 index 0000000..fb1911a --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/edit/matchtags.js @@ -0,0 +1,66 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../fold/xml-fold")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../fold/xml-fold"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineOption("matchTags", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + cm.off("cursorActivity", doMatchTags); + cm.off("viewportChange", maybeUpdateMatch); + clear(cm); + } + if (val) { + cm.state.matchBothTags = typeof val == "object" && val.bothTags; + cm.on("cursorActivity", doMatchTags); + cm.on("viewportChange", maybeUpdateMatch); + doMatchTags(cm); + } + }); + + function clear(cm) { + if (cm.state.tagHit) cm.state.tagHit.clear(); + if (cm.state.tagOther) cm.state.tagOther.clear(); + cm.state.tagHit = cm.state.tagOther = null; + } + + function doMatchTags(cm) { + cm.state.failedTagMatch = false; + cm.operation(function() { + clear(cm); + if (cm.somethingSelected()) return; + var cur = cm.getCursor(), range = cm.getViewport(); + range.from = Math.min(range.from, cur.line); range.to = Math.max(cur.line + 1, range.to); + var match = CodeMirror.findMatchingTag(cm, cur, range); + if (!match) return; + if (cm.state.matchBothTags) { + var hit = match.at == "open" ? match.open : match.close; + if (hit) cm.state.tagHit = cm.markText(hit.from, hit.to, {className: "CodeMirror-matchingtag"}); + } + var other = match.at == "close" ? match.open : match.close; + if (other) + cm.state.tagOther = cm.markText(other.from, other.to, {className: "CodeMirror-matchingtag"}); + else + cm.state.failedTagMatch = true; + }); + } + + function maybeUpdateMatch(cm) { + if (cm.state.failedTagMatch) doMatchTags(cm); + } + + CodeMirror.commands.toMatchingTag = function(cm) { + var found = CodeMirror.findMatchingTag(cm, cm.getCursor()); + if (found) { + var other = found.at == "close" ? found.open : found.close; + if (other) cm.extendSelection(other.to, other.from); + } + }; +}); diff --git a/web2py/applications/admin/static/codemirror/addon/edit/trailingspace.js b/web2py/applications/admin/static/codemirror/addon/edit/trailingspace.js new file mode 100644 index 0000000..fa7b56b --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/edit/trailingspace.js @@ -0,0 +1,27 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) { + if (prev == CodeMirror.Init) prev = false; + if (prev && !val) + cm.removeOverlay("trailingspace"); + else if (!prev && val) + cm.addOverlay({ + token: function(stream) { + for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {} + if (i > stream.pos) { stream.pos = i; return null; } + stream.pos = l; + return "trailingspace"; + }, + name: "trailingspace" + }); + }); +}); diff --git a/web2py/applications/admin/static/codemirror/addon/fold/brace-fold.js b/web2py/applications/admin/static/codemirror/addon/fold/brace-fold.js new file mode 100644 index 0000000..1605f6c --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/fold/brace-fold.js @@ -0,0 +1,105 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.registerHelper("fold", "brace", function(cm, start) { + var line = start.line, lineText = cm.getLine(line); + var startCh, tokenType; + + function findOpening(openCh) { + for (var at = start.ch, pass = 0;;) { + var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1); + if (found == -1) { + if (pass == 1) break; + pass = 1; + at = lineText.length; + continue; + } + if (pass == 1 && found < start.ch) break; + tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)); + if (!/^(comment|string)/.test(tokenType)) return found + 1; + at = found - 1; + } + } + + var startToken = "{", endToken = "}", startCh = findOpening("{"); + if (startCh == null) { + startToken = "[", endToken = "]"; + startCh = findOpening("["); + } + + if (startCh == null) return; + var count = 1, lastLine = cm.lastLine(), end, endCh; + outer: for (var i = line; i <= lastLine; ++i) { + var text = cm.getLine(i), pos = i == line ? startCh : 0; + for (;;) { + var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos); + if (nextOpen < 0) nextOpen = text.length; + if (nextClose < 0) nextClose = text.length; + pos = Math.min(nextOpen, nextClose); + if (pos == text.length) break; + if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) { + if (pos == nextOpen) ++count; + else if (!--count) { end = i; endCh = pos; break outer; } + } + ++pos; + } + } + if (end == null || line == end && endCh == startCh) return; + return {from: CodeMirror.Pos(line, startCh), + to: CodeMirror.Pos(end, endCh)}; +}); + +CodeMirror.registerHelper("fold", "import", function(cm, start) { + function hasImport(line) { + if (line < cm.firstLine() || line > cm.lastLine()) return null; + var start = cm.getTokenAt(CodeMirror.Pos(line, 1)); + if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1)); + if (start.type != "keyword" || start.string != "import") return null; + // Now find closing semicolon, return its position + for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) { + var text = cm.getLine(i), semi = text.indexOf(";"); + if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)}; + } + } + + var start = start.line, has = hasImport(start), prev; + if (!has || hasImport(start - 1) || ((prev = hasImport(start - 2)) && prev.end.line == start - 1)) + return null; + for (var end = has.end;;) { + var next = hasImport(end.line + 1); + if (next == null) break; + end = next.end; + } + return {from: cm.clipPos(CodeMirror.Pos(start, has.startCh + 1)), to: end}; +}); + +CodeMirror.registerHelper("fold", "include", function(cm, start) { + function hasInclude(line) { + if (line < cm.firstLine() || line > cm.lastLine()) return null; + var start = cm.getTokenAt(CodeMirror.Pos(line, 1)); + if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1)); + if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8; + } + + var start = start.line, has = hasInclude(start); + if (has == null || hasInclude(start - 1) != null) return null; + for (var end = start;;) { + var next = hasInclude(end + 1); + if (next == null) break; + ++end; + } + return {from: CodeMirror.Pos(start, has + 1), + to: cm.clipPos(CodeMirror.Pos(end))}; +}); + +}); diff --git a/web2py/applications/admin/static/codemirror/addon/fold/comment-fold.js b/web2py/applications/admin/static/codemirror/addon/fold/comment-fold.js new file mode 100644 index 0000000..b75db7e --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/fold/comment-fold.js @@ -0,0 +1,57 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.registerGlobalHelper("fold", "comment", function(mode) { + return mode.blockCommentStart && mode.blockCommentEnd; +}, function(cm, start) { + var mode = cm.getModeAt(start), startToken = mode.blockCommentStart, endToken = mode.blockCommentEnd; + if (!startToken || !endToken) return; + var line = start.line, lineText = cm.getLine(line); + + var startCh; + for (var at = start.ch, pass = 0;;) { + var found = at <= 0 ? -1 : lineText.lastIndexOf(startToken, at - 1); + if (found == -1) { + if (pass == 1) return; + pass = 1; + at = lineText.length; + continue; + } + if (pass == 1 && found < start.ch) return; + if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)))) { + startCh = found + startToken.length; + break; + } + at = found - 1; + } + + var depth = 1, lastLine = cm.lastLine(), end, endCh; + outer: for (var i = line; i <= lastLine; ++i) { + var text = cm.getLine(i), pos = i == line ? startCh : 0; + for (;;) { + var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos); + if (nextOpen < 0) nextOpen = text.length; + if (nextClose < 0) nextClose = text.length; + pos = Math.min(nextOpen, nextClose); + if (pos == text.length) break; + if (pos == nextOpen) ++depth; + else if (!--depth) { end = i; endCh = pos; break outer; } + ++pos; + } + } + if (end == null || line == end && endCh == startCh) return; + return {from: CodeMirror.Pos(line, startCh), + to: CodeMirror.Pos(end, endCh)}; +}); + +}); diff --git a/web2py/applications/admin/static/codemirror/addon/fold/foldcode.js b/web2py/applications/admin/static/codemirror/addon/fold/foldcode.js new file mode 100644 index 0000000..62911f9 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/fold/foldcode.js @@ -0,0 +1,149 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + function doFold(cm, pos, options, force) { + if (options && options.call) { + var finder = options; + options = null; + } else { + var finder = getOption(cm, options, "rangeFinder"); + } + if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0); + var minSize = getOption(cm, options, "minFoldSize"); + + function getRange(allowFolded) { + var range = finder(cm, pos); + if (!range || range.to.line - range.from.line < minSize) return null; + var marks = cm.findMarksAt(range.from); + for (var i = 0; i < marks.length; ++i) { + if (marks[i].__isFold && force !== "fold") { + if (!allowFolded) return null; + range.cleared = true; + marks[i].clear(); + } + } + return range; + } + + var range = getRange(true); + if (getOption(cm, options, "scanUp")) while (!range && pos.line > cm.firstLine()) { + pos = CodeMirror.Pos(pos.line - 1, 0); + range = getRange(false); + } + if (!range || range.cleared || force === "unfold") return; + + var myWidget = makeWidget(cm, options); + CodeMirror.on(myWidget, "mousedown", function(e) { + myRange.clear(); + CodeMirror.e_preventDefault(e); + }); + var myRange = cm.markText(range.from, range.to, { + replacedWith: myWidget, + clearOnEnter: true, + __isFold: true + }); + myRange.on("clear", function(from, to) { + CodeMirror.signal(cm, "unfold", cm, from, to); + }); + CodeMirror.signal(cm, "fold", cm, range.from, range.to); + } + + function makeWidget(cm, options) { + var widget = getOption(cm, options, "widget"); + if (typeof widget == "string") { + var text = document.createTextNode(widget); + widget = document.createElement("span"); + widget.appendChild(text); + widget.className = "CodeMirror-foldmarker"; + } + return widget; + } + + // Clumsy backwards-compatible interface + CodeMirror.newFoldFunction = function(rangeFinder, widget) { + return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); }; + }; + + // New-style interface + CodeMirror.defineExtension("foldCode", function(pos, options, force) { + doFold(this, pos, options, force); + }); + + CodeMirror.defineExtension("isFolded", function(pos) { + var marks = this.findMarksAt(pos); + for (var i = 0; i < marks.length; ++i) + if (marks[i].__isFold) return true; + }); + + CodeMirror.commands.toggleFold = function(cm) { + cm.foldCode(cm.getCursor()); + }; + CodeMirror.commands.fold = function(cm) { + cm.foldCode(cm.getCursor(), null, "fold"); + }; + CodeMirror.commands.unfold = function(cm) { + cm.foldCode(cm.getCursor(), null, "unfold"); + }; + CodeMirror.commands.foldAll = function(cm) { + cm.operation(function() { + for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) + cm.foldCode(CodeMirror.Pos(i, 0), null, "fold"); + }); + }; + CodeMirror.commands.unfoldAll = function(cm) { + cm.operation(function() { + for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) + cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold"); + }); + }; + + CodeMirror.registerHelper("fold", "combine", function() { + var funcs = Array.prototype.slice.call(arguments, 0); + return function(cm, start) { + for (var i = 0; i < funcs.length; ++i) { + var found = funcs[i](cm, start); + if (found) return found; + } + }; + }); + + CodeMirror.registerHelper("fold", "auto", function(cm, start) { + var helpers = cm.getHelpers(start, "fold"); + for (var i = 0; i < helpers.length; i++) { + var cur = helpers[i](cm, start); + if (cur) return cur; + } + }); + + var defaultOptions = { + rangeFinder: CodeMirror.fold.auto, + widget: "\u2194", + minFoldSize: 0, + scanUp: false + }; + + CodeMirror.defineOption("foldOptions", null); + + function getOption(cm, options, name) { + if (options && options[name] !== undefined) + return options[name]; + var editorOptions = cm.options.foldOptions; + if (editorOptions && editorOptions[name] !== undefined) + return editorOptions[name]; + return defaultOptions[name]; + } + + CodeMirror.defineExtension("foldOption", function(options, name) { + return getOption(this, options, name); + }); +}); diff --git a/web2py/applications/admin/static/codemirror/addon/fold/foldgutter.css b/web2py/applications/admin/static/codemirror/addon/fold/foldgutter.css new file mode 100644 index 0000000..ad19ae2 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/fold/foldgutter.css @@ -0,0 +1,20 @@ +.CodeMirror-foldmarker { + color: blue; + text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px; + font-family: arial; + line-height: .3; + cursor: pointer; +} +.CodeMirror-foldgutter { + width: .7em; +} +.CodeMirror-foldgutter-open, +.CodeMirror-foldgutter-folded { + cursor: pointer; +} +.CodeMirror-foldgutter-open:after { + content: "\25BE"; +} +.CodeMirror-foldgutter-folded:after { + content: "\25B8"; +} diff --git a/web2py/applications/admin/static/codemirror/addon/fold/foldgutter.js b/web2py/applications/admin/static/codemirror/addon/fold/foldgutter.js new file mode 100644 index 0000000..199120c --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/fold/foldgutter.js @@ -0,0 +1,144 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("./foldcode")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "./foldcode"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineOption("foldGutter", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + cm.clearGutter(cm.state.foldGutter.options.gutter); + cm.state.foldGutter = null; + cm.off("gutterClick", onGutterClick); + cm.off("change", onChange); + cm.off("viewportChange", onViewportChange); + cm.off("fold", onFold); + cm.off("unfold", onFold); + cm.off("swapDoc", updateInViewport); + } + if (val) { + cm.state.foldGutter = new State(parseOptions(val)); + updateInViewport(cm); + cm.on("gutterClick", onGutterClick); + cm.on("change", onChange); + cm.on("viewportChange", onViewportChange); + cm.on("fold", onFold); + cm.on("unfold", onFold); + cm.on("swapDoc", updateInViewport); + } + }); + + var Pos = CodeMirror.Pos; + + function State(options) { + this.options = options; + this.from = this.to = 0; + } + + function parseOptions(opts) { + if (opts === true) opts = {}; + if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter"; + if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open"; + if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded"; + return opts; + } + + function isFolded(cm, line) { + var marks = cm.findMarksAt(Pos(line)); + for (var i = 0; i < marks.length; ++i) + if (marks[i].__isFold && marks[i].find().from.line == line) return true; + } + + function marker(spec) { + if (typeof spec == "string") { + var elt = document.createElement("div"); + elt.className = spec + " CodeMirror-guttermarker-subtle"; + return elt; + } else { + return spec.cloneNode(true); + } + } + + function updateFoldInfo(cm, from, to) { + var opts = cm.state.foldGutter.options, cur = from; + var minSize = cm.foldOption(opts, "minFoldSize"); + var func = cm.foldOption(opts, "rangeFinder"); + cm.eachLine(from, to, function(line) { + var mark = null; + if (isFolded(cm, cur)) { + mark = marker(opts.indicatorFolded); + } else { + var pos = Pos(cur, 0); + var range = func && func(cm, pos); + if (range && range.to.line - range.from.line >= minSize) + mark = marker(opts.indicatorOpen); + } + cm.setGutterMarker(line, opts.gutter, mark); + ++cur; + }); + } + + function updateInViewport(cm) { + var vp = cm.getViewport(), state = cm.state.foldGutter; + if (!state) return; + cm.operation(function() { + updateFoldInfo(cm, vp.from, vp.to); + }); + state.from = vp.from; state.to = vp.to; + } + + function onGutterClick(cm, line, gutter) { + var state = cm.state.foldGutter; + if (!state) return; + var opts = state.options; + if (gutter != opts.gutter) return; + cm.foldCode(Pos(line, 0), opts.rangeFinder); + } + + function onChange(cm) { + var state = cm.state.foldGutter; + if (!state) return; + var opts = state.options; + state.from = state.to = 0; + clearTimeout(state.changeUpdate); + state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600); + } + + function onViewportChange(cm) { + var state = cm.state.foldGutter; + if (!state) return; + var opts = state.options; + clearTimeout(state.changeUpdate); + state.changeUpdate = setTimeout(function() { + var vp = cm.getViewport(); + if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) { + updateInViewport(cm); + } else { + cm.operation(function() { + if (vp.from < state.from) { + updateFoldInfo(cm, vp.from, state.from); + state.from = vp.from; + } + if (vp.to > state.to) { + updateFoldInfo(cm, state.to, vp.to); + state.to = vp.to; + } + }); + } + }, opts.updateViewportTimeSpan || 400); + } + + function onFold(cm, from) { + var state = cm.state.foldGutter; + if (!state) return; + var line = from.line; + if (line >= state.from && line < state.to) + updateFoldInfo(cm, line, line + 1); + } +}); diff --git a/web2py/applications/admin/static/codemirror/addon/fold/indent-fold.js b/web2py/applications/admin/static/codemirror/addon/fold/indent-fold.js new file mode 100644 index 0000000..e29f15e --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/fold/indent-fold.js @@ -0,0 +1,44 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.registerHelper("fold", "indent", function(cm, start) { + var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line); + if (!/\S/.test(firstLine)) return; + var getIndent = function(line) { + return CodeMirror.countColumn(line, null, tabSize); + }; + var myIndent = getIndent(firstLine); + var lastLineInFold = null; + // Go through lines until we find a line that definitely doesn't belong in + // the block we're folding, or to the end. + for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) { + var curLine = cm.getLine(i); + var curIndent = getIndent(curLine); + if (curIndent > myIndent) { + // Lines with a greater indent are considered part of the block. + lastLineInFold = i; + } else if (!/\S/.test(curLine)) { + // Empty lines might be breaks within the block we're trying to fold. + } else { + // A non-empty line at an indent equal to or less than ours marks the + // start of another block. + break; + } + } + if (lastLineInFold) return { + from: CodeMirror.Pos(start.line, firstLine.length), + to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length) + }; +}); + +}); diff --git a/web2py/applications/admin/static/codemirror/addon/fold/markdown-fold.js b/web2py/applications/admin/static/codemirror/addon/fold/markdown-fold.js new file mode 100644 index 0000000..ce84c94 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/fold/markdown-fold.js @@ -0,0 +1,49 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.registerHelper("fold", "markdown", function(cm, start) { + var maxDepth = 100; + + function isHeader(lineNo) { + var tokentype = cm.getTokenTypeAt(CodeMirror.Pos(lineNo, 0)); + return tokentype && /\bheader\b/.test(tokentype); + } + + function headerLevel(lineNo, line, nextLine) { + var match = line && line.match(/^#+/); + if (match && isHeader(lineNo)) return match[0].length; + match = nextLine && nextLine.match(/^[=\-]+\s*$/); + if (match && isHeader(lineNo + 1)) return nextLine[0] == "=" ? 1 : 2; + return maxDepth; + } + + var firstLine = cm.getLine(start.line), nextLine = cm.getLine(start.line + 1); + var level = headerLevel(start.line, firstLine, nextLine); + if (level === maxDepth) return undefined; + + var lastLineNo = cm.lastLine(); + var end = start.line, nextNextLine = cm.getLine(end + 2); + while (end < lastLineNo) { + if (headerLevel(end + 1, nextLine, nextNextLine) <= level) break; + ++end; + nextLine = nextNextLine; + nextNextLine = cm.getLine(end + 2); + } + + return { + from: CodeMirror.Pos(start.line, firstLine.length), + to: CodeMirror.Pos(end, cm.getLine(end).length) + }; +}); + +}); diff --git a/web2py/applications/admin/static/codemirror/addon/fold/xml-fold.js b/web2py/applications/admin/static/codemirror/addon/fold/xml-fold.js new file mode 100644 index 0000000..504727f --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/fold/xml-fold.js @@ -0,0 +1,182 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var Pos = CodeMirror.Pos; + function cmp(a, b) { return a.line - b.line || a.ch - b.ch; } + + var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD"; + var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040"; + var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g"); + + function Iter(cm, line, ch, range) { + this.line = line; this.ch = ch; + this.cm = cm; this.text = cm.getLine(line); + this.min = range ? range.from : cm.firstLine(); + this.max = range ? range.to - 1 : cm.lastLine(); + } + + function tagAt(iter, ch) { + var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch)); + return type && /\btag\b/.test(type); + } + + function nextLine(iter) { + if (iter.line >= iter.max) return; + iter.ch = 0; + iter.text = iter.cm.getLine(++iter.line); + return true; + } + function prevLine(iter) { + if (iter.line <= iter.min) return; + iter.text = iter.cm.getLine(--iter.line); + iter.ch = iter.text.length; + return true; + } + + function toTagEnd(iter) { + for (;;) { + var gt = iter.text.indexOf(">", iter.ch); + if (gt == -1) { if (nextLine(iter)) continue; else return; } + if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; } + var lastSlash = iter.text.lastIndexOf("/", gt); + var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); + iter.ch = gt + 1; + return selfClose ? "selfClose" : "regular"; + } + } + function toTagStart(iter) { + for (;;) { + var lt = iter.ch ? iter.text.lastIndexOf("<", iter.ch - 1) : -1; + if (lt == -1) { if (prevLine(iter)) continue; else return; } + if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; } + xmlTagStart.lastIndex = lt; + iter.ch = lt; + var match = xmlTagStart.exec(iter.text); + if (match && match.index == lt) return match; + } + } + + function toNextTag(iter) { + for (;;) { + xmlTagStart.lastIndex = iter.ch; + var found = xmlTagStart.exec(iter.text); + if (!found) { if (nextLine(iter)) continue; else return; } + if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; } + iter.ch = found.index + found[0].length; + return found; + } + } + function toPrevTag(iter) { + for (;;) { + var gt = iter.ch ? iter.text.lastIndexOf(">", iter.ch - 1) : -1; + if (gt == -1) { if (prevLine(iter)) continue; else return; } + if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; } + var lastSlash = iter.text.lastIndexOf("/", gt); + var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); + iter.ch = gt + 1; + return selfClose ? "selfClose" : "regular"; + } + } + + function findMatchingClose(iter, tag) { + var stack = []; + for (;;) { + var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0); + if (!next || !(end = toTagEnd(iter))) return; + if (end == "selfClose") continue; + if (next[1]) { // closing tag + for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) { + stack.length = i; + break; + } + if (i < 0 && (!tag || tag == next[2])) return { + tag: next[2], + from: Pos(startLine, startCh), + to: Pos(iter.line, iter.ch) + }; + } else { // opening tag + stack.push(next[2]); + } + } + } + function findMatchingOpen(iter, tag) { + var stack = []; + for (;;) { + var prev = toPrevTag(iter); + if (!prev) return; + if (prev == "selfClose") { toTagStart(iter); continue; } + var endLine = iter.line, endCh = iter.ch; + var start = toTagStart(iter); + if (!start) return; + if (start[1]) { // closing tag + stack.push(start[2]); + } else { // opening tag + for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) { + stack.length = i; + break; + } + if (i < 0 && (!tag || tag == start[2])) return { + tag: start[2], + from: Pos(iter.line, iter.ch), + to: Pos(endLine, endCh) + }; + } + } + } + + CodeMirror.registerHelper("fold", "xml", function(cm, start) { + var iter = new Iter(cm, start.line, 0); + for (;;) { + var openTag = toNextTag(iter), end; + if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return; + if (!openTag[1] && end != "selfClose") { + var start = Pos(iter.line, iter.ch); + var close = findMatchingClose(iter, openTag[2]); + return close && {from: start, to: close.from}; + } + } + }); + CodeMirror.findMatchingTag = function(cm, pos, range) { + var iter = new Iter(cm, pos.line, pos.ch, range); + if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return; + var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch); + var start = end && toTagStart(iter); + if (!end || !start || cmp(iter, pos) > 0) return; + var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]}; + if (end == "selfClose") return {open: here, close: null, at: "open"}; + + if (start[1]) { // closing tag + return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"}; + } else { // opening tag + iter = new Iter(cm, to.line, to.ch, range); + return {open: here, close: findMatchingClose(iter, start[2]), at: "open"}; + } + }; + + CodeMirror.findEnclosingTag = function(cm, pos, range) { + var iter = new Iter(cm, pos.line, pos.ch, range); + for (;;) { + var open = findMatchingOpen(iter); + if (!open) break; + var forward = new Iter(cm, pos.line, pos.ch, range); + var close = findMatchingClose(forward, open.tag); + if (close) return {open: open, close: close}; + } + }; + + // Used by addon/edit/closetag.js + CodeMirror.scanForClosingTag = function(cm, pos, name, end) { + var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null); + return findMatchingClose(iter, name); + }; +}); diff --git a/web2py/applications/admin/static/codemirror/addon/hint/anyword-hint.js b/web2py/applications/admin/static/codemirror/addon/hint/anyword-hint.js new file mode 100644 index 0000000..8e74a92 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/hint/anyword-hint.js @@ -0,0 +1,41 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var WORD = /[\w$]+/, RANGE = 500; + + CodeMirror.registerHelper("hint", "anyword", function(editor, options) { + var word = options && options.word || WORD; + var range = options && options.range || RANGE; + var cur = editor.getCursor(), curLine = editor.getLine(cur.line); + var end = cur.ch, start = end; + while (start && word.test(curLine.charAt(start - 1))) --start; + var curWord = start != end && curLine.slice(start, end); + + var list = [], seen = {}; + var re = new RegExp(word.source, "g"); + for (var dir = -1; dir <= 1; dir += 2) { + var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir; + for (; line != endLine; line += dir) { + var text = editor.getLine(line), m; + while (m = re.exec(text)) { + if (line == cur.line && m[0] === curWord) continue; + if ((!curWord || m[0].lastIndexOf(curWord, 0) == 0) && !Object.prototype.hasOwnProperty.call(seen, m[0])) { + seen[m[0]] = true; + list.push(m[0]); + } + } + } + } + return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)}; + }); +}); diff --git a/web2py/applications/admin/static/codemirror/addon/hint/css-hint.js b/web2py/applications/admin/static/codemirror/addon/hint/css-hint.js new file mode 100644 index 0000000..488da34 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/hint/css-hint.js @@ -0,0 +1,56 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../../mode/css/css")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../../mode/css/css"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1, + "first-letter": 1, "first-line": 1, "first-child": 1, + before: 1, after: 1, lang: 1}; + + CodeMirror.registerHelper("hint", "css", function(cm) { + var cur = cm.getCursor(), token = cm.getTokenAt(cur); + var inner = CodeMirror.innerMode(cm.getMode(), token.state); + if (inner.mode.name != "css") return; + + var start = token.start, end = cur.ch, word = token.string.slice(0, end - start); + if (/[^\w$_-]/.test(word)) { + word = ""; start = end = cur.ch; + } + + var spec = CodeMirror.resolveMode("text/css"); + + var result = []; + function add(keywords) { + for (var name in keywords) + if (!word || name.lastIndexOf(word, 0) == 0) + result.push(name); + } + + var st = inner.state.state; + if (st == "pseudo" || token.type == "variable-3") { + add(pseudoClasses); + } else if (st == "block" || st == "maybeprop") { + add(spec.propertyKeywords); + } else if (st == "prop" || st == "parens" || st == "at" || st == "params") { + add(spec.valueKeywords); + add(spec.colorKeywords); + } else if (st == "media" || st == "media_parens") { + add(spec.mediaTypes); + add(spec.mediaFeatures); + } + + if (result.length) return { + list: result, + from: CodeMirror.Pos(cur.line, start), + to: CodeMirror.Pos(cur.line, end) + }; + }); +}); diff --git a/web2py/applications/admin/static/codemirror/addon/hint/html-hint.js b/web2py/applications/admin/static/codemirror/addon/hint/html-hint.js new file mode 100644 index 0000000..c6769bc --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/hint/html-hint.js @@ -0,0 +1,348 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("./xml-hint")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "./xml-hint"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var langs = "ab aa af ak sq am ar an hy as av ae ay az bm ba eu be bn bh bi bs br bg my ca ch ce ny zh cv kw co cr hr cs da dv nl dz en eo et ee fo fj fi fr ff gl ka de el gn gu ht ha he hz hi ho hu ia id ie ga ig ik io is it iu ja jv kl kn kr ks kk km ki rw ky kv kg ko ku kj la lb lg li ln lo lt lu lv gv mk mg ms ml mt mi mr mh mn na nv nb nd ne ng nn no ii nr oc oj cu om or os pa pi fa pl ps pt qu rm rn ro ru sa sc sd se sm sg sr gd sn si sk sl so st es su sw ss sv ta te tg th ti bo tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa cy wo fy xh yi yo za zu".split(" "); + var targets = ["_blank", "_self", "_top", "_parent"]; + var charsets = ["ascii", "utf-8", "utf-16", "latin1", "latin1"]; + var methods = ["get", "post", "put", "delete"]; + var encs = ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"]; + var media = ["all", "screen", "print", "embossed", "braille", "handheld", "print", "projection", "screen", "tty", "tv", "speech", + "3d-glasses", "resolution [>][<][=] [X]", "device-aspect-ratio: X/Y", "orientation:portrait", + "orientation:landscape", "device-height: [X]", "device-width: [X]"]; + var s = { attrs: {} }; // Simple tag, reused for a whole lot of tags + + var data = { + a: { + attrs: { + href: null, ping: null, type: null, + media: media, + target: targets, + hreflang: langs + } + }, + abbr: s, + acronym: s, + address: s, + applet: s, + area: { + attrs: { + alt: null, coords: null, href: null, target: null, ping: null, + media: media, hreflang: langs, type: null, + shape: ["default", "rect", "circle", "poly"] + } + }, + article: s, + aside: s, + audio: { + attrs: { + src: null, mediagroup: null, + crossorigin: ["anonymous", "use-credentials"], + preload: ["none", "metadata", "auto"], + autoplay: ["", "autoplay"], + loop: ["", "loop"], + controls: ["", "controls"] + } + }, + b: s, + base: { attrs: { href: null, target: targets } }, + basefont: s, + bdi: s, + bdo: s, + big: s, + blockquote: { attrs: { cite: null } }, + body: s, + br: s, + button: { + attrs: { + form: null, formaction: null, name: null, value: null, + autofocus: ["", "autofocus"], + disabled: ["", "autofocus"], + formenctype: encs, + formmethod: methods, + formnovalidate: ["", "novalidate"], + formtarget: targets, + type: ["submit", "reset", "button"] + } + }, + canvas: { attrs: { width: null, height: null } }, + caption: s, + center: s, + cite: s, + code: s, + col: { attrs: { span: null } }, + colgroup: { attrs: { span: null } }, + command: { + attrs: { + type: ["command", "checkbox", "radio"], + label: null, icon: null, radiogroup: null, command: null, title: null, + disabled: ["", "disabled"], + checked: ["", "checked"] + } + }, + data: { attrs: { value: null } }, + datagrid: { attrs: { disabled: ["", "disabled"], multiple: ["", "multiple"] } }, + datalist: { attrs: { data: null } }, + dd: s, + del: { attrs: { cite: null, datetime: null } }, + details: { attrs: { open: ["", "open"] } }, + dfn: s, + dir: s, + div: s, + dl: s, + dt: s, + em: s, + embed: { attrs: { src: null, type: null, width: null, height: null } }, + eventsource: { attrs: { src: null } }, + fieldset: { attrs: { disabled: ["", "disabled"], form: null, name: null } }, + figcaption: s, + figure: s, + font: s, + footer: s, + form: { + attrs: { + action: null, name: null, + "accept-charset": charsets, + autocomplete: ["on", "off"], + enctype: encs, + method: methods, + novalidate: ["", "novalidate"], + target: targets + } + }, + frame: s, + frameset: s, + h1: s, h2: s, h3: s, h4: s, h5: s, h6: s, + head: { + attrs: {}, + children: ["title", "base", "link", "style", "meta", "script", "noscript", "command"] + }, + header: s, + hgroup: s, + hr: s, + html: { + attrs: { manifest: null }, + children: ["head", "body"] + }, + i: s, + iframe: { + attrs: { + src: null, srcdoc: null, name: null, width: null, height: null, + sandbox: ["allow-top-navigation", "allow-same-origin", "allow-forms", "allow-scripts"], + seamless: ["", "seamless"] + } + }, + img: { + attrs: { + alt: null, src: null, ismap: null, usemap: null, width: null, height: null, + crossorigin: ["anonymous", "use-credentials"] + } + }, + input: { + attrs: { + alt: null, dirname: null, form: null, formaction: null, + height: null, list: null, max: null, maxlength: null, min: null, + name: null, pattern: null, placeholder: null, size: null, src: null, + step: null, value: null, width: null, + accept: ["audio/*", "video/*", "image/*"], + autocomplete: ["on", "off"], + autofocus: ["", "autofocus"], + checked: ["", "checked"], + disabled: ["", "disabled"], + formenctype: encs, + formmethod: methods, + formnovalidate: ["", "novalidate"], + formtarget: targets, + multiple: ["", "multiple"], + readonly: ["", "readonly"], + required: ["", "required"], + type: ["hidden", "text", "search", "tel", "url", "email", "password", "datetime", "date", "month", + "week", "time", "datetime-local", "number", "range", "color", "checkbox", "radio", + "file", "submit", "image", "reset", "button"] + } + }, + ins: { attrs: { cite: null, datetime: null } }, + kbd: s, + keygen: { + attrs: { + challenge: null, form: null, name: null, + autofocus: ["", "autofocus"], + disabled: ["", "disabled"], + keytype: ["RSA"] + } + }, + label: { attrs: { "for": null, form: null } }, + legend: s, + li: { attrs: { value: null } }, + link: { + attrs: { + href: null, type: null, + hreflang: langs, + media: media, + sizes: ["all", "16x16", "16x16 32x32", "16x16 32x32 64x64"] + } + }, + map: { attrs: { name: null } }, + mark: s, + menu: { attrs: { label: null, type: ["list", "context", "toolbar"] } }, + meta: { + attrs: { + content: null, + charset: charsets, + name: ["viewport", "application-name", "author", "description", "generator", "keywords"], + "http-equiv": ["content-language", "content-type", "default-style", "refresh"] + } + }, + meter: { attrs: { value: null, min: null, low: null, high: null, max: null, optimum: null } }, + nav: s, + noframes: s, + noscript: s, + object: { + attrs: { + data: null, type: null, name: null, usemap: null, form: null, width: null, height: null, + typemustmatch: ["", "typemustmatch"] + } + }, + ol: { attrs: { reversed: ["", "reversed"], start: null, type: ["1", "a", "A", "i", "I"] } }, + optgroup: { attrs: { disabled: ["", "disabled"], label: null } }, + option: { attrs: { disabled: ["", "disabled"], label: null, selected: ["", "selected"], value: null } }, + output: { attrs: { "for": null, form: null, name: null } }, + p: s, + param: { attrs: { name: null, value: null } }, + pre: s, + progress: { attrs: { value: null, max: null } }, + q: { attrs: { cite: null } }, + rp: s, + rt: s, + ruby: s, + s: s, + samp: s, + script: { + attrs: { + type: ["text/javascript"], + src: null, + async: ["", "async"], + defer: ["", "defer"], + charset: charsets + } + }, + section: s, + select: { + attrs: { + form: null, name: null, size: null, + autofocus: ["", "autofocus"], + disabled: ["", "disabled"], + multiple: ["", "multiple"] + } + }, + small: s, + source: { attrs: { src: null, type: null, media: null } }, + span: s, + strike: s, + strong: s, + style: { + attrs: { + type: ["text/css"], + media: media, + scoped: null + } + }, + sub: s, + summary: s, + sup: s, + table: s, + tbody: s, + td: { attrs: { colspan: null, rowspan: null, headers: null } }, + textarea: { + attrs: { + dirname: null, form: null, maxlength: null, name: null, placeholder: null, + rows: null, cols: null, + autofocus: ["", "autofocus"], + disabled: ["", "disabled"], + readonly: ["", "readonly"], + required: ["", "required"], + wrap: ["soft", "hard"] + } + }, + tfoot: s, + th: { attrs: { colspan: null, rowspan: null, headers: null, scope: ["row", "col", "rowgroup", "colgroup"] } }, + thead: s, + time: { attrs: { datetime: null } }, + title: s, + tr: s, + track: { + attrs: { + src: null, label: null, "default": null, + kind: ["subtitles", "captions", "descriptions", "chapters", "metadata"], + srclang: langs + } + }, + tt: s, + u: s, + ul: s, + "var": s, + video: { + attrs: { + src: null, poster: null, width: null, height: null, + crossorigin: ["anonymous", "use-credentials"], + preload: ["auto", "metadata", "none"], + autoplay: ["", "autoplay"], + mediagroup: ["movie"], + muted: ["", "muted"], + controls: ["", "controls"] + } + }, + wbr: s + }; + + var globalAttrs = { + accesskey: ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"], + "class": null, + contenteditable: ["true", "false"], + contextmenu: null, + dir: ["ltr", "rtl", "auto"], + draggable: ["true", "false", "auto"], + dropzone: ["copy", "move", "link", "string:", "file:"], + hidden: ["hidden"], + id: null, + inert: ["inert"], + itemid: null, + itemprop: null, + itemref: null, + itemscope: ["itemscope"], + itemtype: null, + lang: ["en", "es"], + spellcheck: ["true", "false"], + style: null, + tabindex: ["1", "2", "3", "4", "5", "6", "7", "8", "9"], + title: null, + translate: ["yes", "no"], + onclick: null, + rel: ["stylesheet", "alternate", "author", "bookmark", "help", "license", "next", "nofollow", "noreferrer", "prefetch", "prev", "search", "tag"] + }; + function populate(obj) { + for (var attr in globalAttrs) if (globalAttrs.hasOwnProperty(attr)) + obj.attrs[attr] = globalAttrs[attr]; + } + + populate(s); + for (var tag in data) if (data.hasOwnProperty(tag) && data[tag] != s) + populate(data[tag]); + + CodeMirror.htmlSchema = data; + function htmlHint(cm, options) { + var local = {schemaInfo: data}; + if (options) for (var opt in options) local[opt] = options[opt]; + return CodeMirror.hint.xml(cm, local); + } + CodeMirror.registerHelper("hint", "html", htmlHint); +}); diff --git a/web2py/applications/admin/static/codemirror/addon/hint/javascript-hint.js b/web2py/applications/admin/static/codemirror/addon/hint/javascript-hint.js new file mode 100644 index 0000000..7bcbf4a --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/hint/javascript-hint.js @@ -0,0 +1,146 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + var Pos = CodeMirror.Pos; + + function forEach(arr, f) { + for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); + } + + function arrayContains(arr, item) { + if (!Array.prototype.indexOf) { + var i = arr.length; + while (i--) { + if (arr[i] === item) { + return true; + } + } + return false; + } + return arr.indexOf(item) != -1; + } + + function scriptHint(editor, keywords, getToken, options) { + // Find the token at the cursor + var cur = editor.getCursor(), token = getToken(editor, cur); + if (/\b(?:string|comment)\b/.test(token.type)) return; + token.state = CodeMirror.innerMode(editor.getMode(), token.state).state; + + // If it's not a 'word-style' token, ignore the token. + if (!/^[\w$_]*$/.test(token.string)) { + token = {start: cur.ch, end: cur.ch, string: "", state: token.state, + type: token.string == "." ? "property" : null}; + } else if (token.end > cur.ch) { + token.end = cur.ch; + token.string = token.string.slice(0, cur.ch - token.start); + } + + var tprop = token; + // If it is a property, find out what it is a property of. + while (tprop.type == "property") { + tprop = getToken(editor, Pos(cur.line, tprop.start)); + if (tprop.string != ".") return; + tprop = getToken(editor, Pos(cur.line, tprop.start)); + if (!context) var context = []; + context.push(tprop); + } + return {list: getCompletions(token, context, keywords, options), + from: Pos(cur.line, token.start), + to: Pos(cur.line, token.end)}; + } + + function javascriptHint(editor, options) { + return scriptHint(editor, javascriptKeywords, + function (e, cur) {return e.getTokenAt(cur);}, + options); + }; + CodeMirror.registerHelper("hint", "javascript", javascriptHint); + + function getCoffeeScriptToken(editor, cur) { + // This getToken, it is for coffeescript, imitates the behavior of + // getTokenAt method in javascript.js, that is, returning "property" + // type and treat "." as indepenent token. + var token = editor.getTokenAt(cur); + if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') { + token.end = token.start; + token.string = '.'; + token.type = "property"; + } + else if (/^\.[\w$_]*$/.test(token.string)) { + token.type = "property"; + token.start++; + token.string = token.string.replace(/\./, ''); + } + return token; + } + + function coffeescriptHint(editor, options) { + return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options); + } + CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint); + + var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " + + "toUpperCase toLowerCase split concat match replace search").split(" "); + var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " + + "lastIndexOf every some filter forEach map reduce reduceRight ").split(" "); + var funcProps = "prototype apply call bind".split(" "); + var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " + + "if in instanceof new null return switch throw true try typeof var void while with").split(" "); + var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " + + "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" "); + + function getCompletions(token, context, keywords, options) { + var found = [], start = token.string, global = options && options.globalScope || window; + function maybeAdd(str) { + if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str); + } + function gatherCompletions(obj) { + if (typeof obj == "string") forEach(stringProps, maybeAdd); + else if (obj instanceof Array) forEach(arrayProps, maybeAdd); + else if (obj instanceof Function) forEach(funcProps, maybeAdd); + for (var name in obj) maybeAdd(name); + } + + if (context && context.length) { + // If this is a property, see if it belongs to some object we can + // find in the current environment. + var obj = context.pop(), base; + if (obj.type && obj.type.indexOf("variable") === 0) { + if (options && options.additionalContext) + base = options.additionalContext[obj.string]; + if (!options || options.useGlobalScope !== false) + base = base || global[obj.string]; + } else if (obj.type == "string") { + base = ""; + } else if (obj.type == "atom") { + base = 1; + } else if (obj.type == "function") { + if (global.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') && + (typeof global.jQuery == 'function')) + base = global.jQuery(); + else if (global._ != null && (obj.string == '_') && (typeof global._ == 'function')) + base = global._(); + } + while (base != null && context.length) + base = base[context.pop().string]; + if (base != null) gatherCompletions(base); + } else { + // If not, just look in the global object and any local scope + // (reading into JS mode internals to get at the local and global variables) + for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name); + for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name); + if (!options || options.useGlobalScope !== false) + gatherCompletions(global); + forEach(keywords, maybeAdd); + } + return found; + } +}); diff --git a/web2py/applications/admin/static/codemirror/addon/hint/python-hint.js b/web2py/applications/admin/static/codemirror/addon/hint/python-hint.js new file mode 100644 index 0000000..eebfcc7 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/hint/python-hint.js @@ -0,0 +1,99 @@ +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + function forEach(arr, f) { + for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); + } + + function arrayContains(arr, item) { + if (!Array.prototype.indexOf) { + var i = arr.length; + while (i--) { + if (arr[i] === item) { + return true; + } + } + return false; + } + return arr.indexOf(item) != -1; + } + + function scriptHint(editor, _keywords, getToken) { + // Find the token at the cursor + var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token; + // If it's not a 'word-style' token, ignore the token. + + if (!/^[\w$_]*$/.test(token.string)) { + token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state, + className: token.string == ":" ? "python-type" : null}; + } + + if (!context) var context = []; + context.push(tprop); + + var completionList = getCompletions(token, context); + completionList = completionList.sort(); + + return {list: completionList, + from: CodeMirror.Pos(cur.line, token.start), + to: CodeMirror.Pos(cur.line, token.end)}; + } + + function pythonHint(editor) { + return scriptHint(editor, pythonKeywordsU, function (e, cur) {return e.getTokenAt(cur);}); + } + CodeMirror.registerHelper("hint", "python", pythonHint); + + var pythonKeywords = "and del from not while as elif global or with assert else if pass yield" ++ "break except import print class exec in raise continue finally is return def for lambda try"; + var pythonKeywordsL = pythonKeywords.split(" "); + var pythonKeywordsU = pythonKeywords.toUpperCase().split(" "); + + var pythonBuiltins = "abs divmod input open staticmethod all enumerate int ord str " ++ "any eval isinstance pow sum basestring execfile issubclass print super" ++ "bin file iter property tuple bool filter len range type" ++ "bytearray float list raw_input unichr callable format locals reduce unicode" ++ "chr frozenset long reload vars classmethod getattr map repr xrange" ++ "cmp globals max reversed zip compile hasattr memoryview round __import__" ++ "complex hash min set apply delattr help next setattr buffer" ++ "dict hex object slice coerce dir id oct sorted intern "; + var pythonBuiltinsL = pythonBuiltins.split(" ").join("() ").split(" "); + var pythonBuiltinsU = pythonBuiltins.toUpperCase().split(" ").join("() ").split(" "); + + function getCompletions(token, context) { + var found = [], start = token.string; + function maybeAdd(str) { + if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str); + } + + function gatherCompletions(_obj) { + forEach(pythonBuiltinsL, maybeAdd); + forEach(pythonBuiltinsU, maybeAdd); + forEach(pythonKeywordsL, maybeAdd); + forEach(pythonKeywordsU, maybeAdd); + } + + if (context) { + // If this is a property, see if it belongs to some object we can + // find in the current environment. + var obj = context.pop(), base; + + if (obj.type == "variable") + base = obj.string; + else if(obj.type == "variable-3") + base = ":" + obj.string; + + while (base != null && context.length) + base = base[context.pop().string]; + if (base != null) gatherCompletions(base); + } + return found; + } +}); diff --git a/web2py/applications/admin/static/codemirror/addon/hint/show-hint.css b/web2py/applications/admin/static/codemirror/addon/hint/show-hint.css new file mode 100644 index 0000000..924e638 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/hint/show-hint.css @@ -0,0 +1,38 @@ +.CodeMirror-hints { + position: absolute; + z-index: 10; + overflow: hidden; + list-style: none; + + margin: 0; + padding: 2px; + + -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); + -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); + box-shadow: 2px 3px 5px rgba(0,0,0,.2); + border-radius: 3px; + border: 1px solid silver; + + background: white; + font-size: 90%; + font-family: monospace; + + max-height: 20em; + overflow-y: auto; +} + +.CodeMirror-hint { + margin: 0; + padding: 0 4px; + border-radius: 2px; + max-width: 19em; + overflow: hidden; + white-space: pre; + color: black; + cursor: pointer; +} + +li.CodeMirror-hint-active { + background: #08f; + color: white; +} diff --git a/web2py/applications/admin/static/codemirror/addon/hint/show-hint.js b/web2py/applications/admin/static/codemirror/addon/hint/show-hint.js new file mode 100644 index 0000000..f544619 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/hint/show-hint.js @@ -0,0 +1,394 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var HINT_ELEMENT_CLASS = "CodeMirror-hint"; + var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active"; + + // This is the old interface, kept around for now to stay + // backwards-compatible. + CodeMirror.showHint = function(cm, getHints, options) { + if (!getHints) return cm.showHint(options); + if (options && options.async) getHints.async = true; + var newOpts = {hint: getHints}; + if (options) for (var prop in options) newOpts[prop] = options[prop]; + return cm.showHint(newOpts); + }; + + var asyncRunID = 0; + function retrieveHints(getter, cm, options, then) { + if (getter.async) { + var id = ++asyncRunID; + getter(cm, function(hints) { + if (asyncRunID == id) then(hints); + }, options); + } else { + then(getter(cm, options)); + } + } + + CodeMirror.defineExtension("showHint", function(options) { + // We want a single cursor position. + if (this.listSelections().length > 1 || this.somethingSelected()) return; + + if (this.state.completionActive) this.state.completionActive.close(); + var completion = this.state.completionActive = new Completion(this, options); + var getHints = completion.options.hint; + if (!getHints) return; + + CodeMirror.signal(this, "startCompletion", this); + return retrieveHints(getHints, this, completion.options, function(hints) { completion.showHints(hints); }); + }); + + function Completion(cm, options) { + this.cm = cm; + this.options = this.buildOptions(options); + this.widget = this.onClose = null; + } + + Completion.prototype = { + close: function() { + if (!this.active()) return; + this.cm.state.completionActive = null; + + if (this.widget) this.widget.close(); + if (this.onClose) this.onClose(); + CodeMirror.signal(this.cm, "endCompletion", this.cm); + }, + + active: function() { + return this.cm.state.completionActive == this; + }, + + pick: function(data, i) { + var completion = data.list[i]; + if (completion.hint) completion.hint(this.cm, data, completion); + else this.cm.replaceRange(getText(completion), completion.from || data.from, + completion.to || data.to, "complete"); + CodeMirror.signal(data, "pick", completion); + this.close(); + }, + + showHints: function(data) { + if (!data || !data.list.length || !this.active()) return this.close(); + + if (this.options.completeSingle && data.list.length == 1) + this.pick(data, 0); + else + this.showWidget(data); + }, + + showWidget: function(data) { + this.widget = new Widget(this, data); + CodeMirror.signal(data, "shown"); + + var debounce = 0, completion = this, finished; + var closeOn = this.options.closeCharacters; + var startPos = this.cm.getCursor(), startLen = this.cm.getLine(startPos.line).length; + + var requestAnimationFrame = window.requestAnimationFrame || function(fn) { + return setTimeout(fn, 1000/60); + }; + var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout; + + function done() { + if (finished) return; + finished = true; + completion.close(); + completion.cm.off("cursorActivity", activity); + if (data) CodeMirror.signal(data, "close"); + } + + function update() { + if (finished) return; + CodeMirror.signal(data, "update"); + retrieveHints(completion.options.hint, completion.cm, completion.options, finishUpdate); + } + function finishUpdate(data_) { + data = data_; + if (finished) return; + if (!data || !data.list.length) return done(); + if (completion.widget) completion.widget.close(); + completion.widget = new Widget(completion, data); + } + + function clearDebounce() { + if (debounce) { + cancelAnimationFrame(debounce); + debounce = 0; + } + } + + function activity() { + clearDebounce(); + var pos = completion.cm.getCursor(), line = completion.cm.getLine(pos.line); + if (pos.line != startPos.line || line.length - pos.ch != startLen - startPos.ch || + pos.ch < startPos.ch || completion.cm.somethingSelected() || + (pos.ch && closeOn.test(line.charAt(pos.ch - 1)))) { + completion.close(); + } else { + debounce = requestAnimationFrame(update); + if (completion.widget) completion.widget.close(); + } + } + this.cm.on("cursorActivity", activity); + this.onClose = done; + }, + + buildOptions: function(options) { + var editor = this.cm.options.hintOptions; + var out = {}; + for (var prop in defaultOptions) out[prop] = defaultOptions[prop]; + if (editor) for (var prop in editor) + if (editor[prop] !== undefined) out[prop] = editor[prop]; + if (options) for (var prop in options) + if (options[prop] !== undefined) out[prop] = options[prop]; + return out; + } + }; + + function getText(completion) { + if (typeof completion == "string") return completion; + else return completion.text; + } + + function buildKeyMap(completion, handle) { + var baseMap = { + Up: function() {handle.moveFocus(-1);}, + Down: function() {handle.moveFocus(1);}, + PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);}, + PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);}, + Home: function() {handle.setFocus(0);}, + End: function() {handle.setFocus(handle.length - 1);}, + Enter: handle.pick, + Tab: handle.pick, + Esc: handle.close + }; + var custom = completion.options.customKeys; + var ourMap = custom ? {} : baseMap; + function addBinding(key, val) { + var bound; + if (typeof val != "string") + bound = function(cm) { return val(cm, handle); }; + // This mechanism is deprecated + else if (baseMap.hasOwnProperty(val)) + bound = baseMap[val]; + else + bound = val; + ourMap[key] = bound; + } + if (custom) + for (var key in custom) if (custom.hasOwnProperty(key)) + addBinding(key, custom[key]); + var extra = completion.options.extraKeys; + if (extra) + for (var key in extra) if (extra.hasOwnProperty(key)) + addBinding(key, extra[key]); + return ourMap; + } + + function getHintElement(hintsElement, el) { + while (el && el != hintsElement) { + if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el; + el = el.parentNode; + } + } + + function Widget(completion, data) { + this.completion = completion; + this.data = data; + var widget = this, cm = completion.cm; + + var hints = this.hints = document.createElement("ul"); + hints.className = "CodeMirror-hints"; + this.selectedHint = data.selectedHint || 0; + + var completions = data.list; + for (var i = 0; i < completions.length; ++i) { + var elt = hints.appendChild(document.createElement("li")), cur = completions[i]; + var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS); + if (cur.className != null) className = cur.className + " " + className; + elt.className = className; + if (cur.render) cur.render(elt, data, cur); + else elt.appendChild(document.createTextNode(cur.displayText || getText(cur))); + elt.hintId = i; + } + + var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null); + var left = pos.left, top = pos.bottom, below = true; + hints.style.left = left + "px"; + hints.style.top = top + "px"; + // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor. + var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth); + var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight); + (completion.options.container || document.body).appendChild(hints); + var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH; + if (overlapY > 0) { + var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top); + if (curTop - height > 0) { // Fits above cursor + hints.style.top = (top = pos.top - height) + "px"; + below = false; + } else if (height > winH) { + hints.style.height = (winH - 5) + "px"; + hints.style.top = (top = pos.bottom - box.top) + "px"; + var cursor = cm.getCursor(); + if (data.from.ch != cursor.ch) { + pos = cm.cursorCoords(cursor); + hints.style.left = (left = pos.left) + "px"; + box = hints.getBoundingClientRect(); + } + } + } + var overlapX = box.right - winW; + if (overlapX > 0) { + if (box.right - box.left > winW) { + hints.style.width = (winW - 5) + "px"; + overlapX -= (box.right - box.left) - winW; + } + hints.style.left = (left = pos.left - overlapX) + "px"; + } + + cm.addKeyMap(this.keyMap = buildKeyMap(completion, { + moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); }, + setFocus: function(n) { widget.changeActive(n); }, + menuSize: function() { return widget.screenAmount(); }, + length: completions.length, + close: function() { completion.close(); }, + pick: function() { widget.pick(); }, + data: data + })); + + if (completion.options.closeOnUnfocus) { + var closingOnBlur; + cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); }); + cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); }); + } + + var startScroll = cm.getScrollInfo(); + cm.on("scroll", this.onScroll = function() { + var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect(); + var newTop = top + startScroll.top - curScroll.top; + var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop); + if (!below) point += hints.offsetHeight; + if (point <= editor.top || point >= editor.bottom) return completion.close(); + hints.style.top = newTop + "px"; + hints.style.left = (left + startScroll.left - curScroll.left) + "px"; + }); + + CodeMirror.on(hints, "dblclick", function(e) { + var t = getHintElement(hints, e.target || e.srcElement); + if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();} + }); + + CodeMirror.on(hints, "click", function(e) { + var t = getHintElement(hints, e.target || e.srcElement); + if (t && t.hintId != null) { + widget.changeActive(t.hintId); + if (completion.options.completeOnSingleClick) widget.pick(); + } + }); + + CodeMirror.on(hints, "mousedown", function() { + setTimeout(function(){cm.focus();}, 20); + }); + + CodeMirror.signal(data, "select", completions[0], hints.firstChild); + return true; + } + + Widget.prototype = { + close: function() { + if (this.completion.widget != this) return; + this.completion.widget = null; + this.hints.parentNode.removeChild(this.hints); + this.completion.cm.removeKeyMap(this.keyMap); + + var cm = this.completion.cm; + if (this.completion.options.closeOnUnfocus) { + cm.off("blur", this.onBlur); + cm.off("focus", this.onFocus); + } + cm.off("scroll", this.onScroll); + }, + + pick: function() { + this.completion.pick(this.data, this.selectedHint); + }, + + changeActive: function(i, avoidWrap) { + if (i >= this.data.list.length) + i = avoidWrap ? this.data.list.length - 1 : 0; + else if (i < 0) + i = avoidWrap ? 0 : this.data.list.length - 1; + if (this.selectedHint == i) return; + var node = this.hints.childNodes[this.selectedHint]; + node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, ""); + node = this.hints.childNodes[this.selectedHint = i]; + node.className += " " + ACTIVE_HINT_ELEMENT_CLASS; + if (node.offsetTop < this.hints.scrollTop) + this.hints.scrollTop = node.offsetTop - 3; + else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight) + this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3; + CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node); + }, + + screenAmount: function() { + return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1; + } + }; + + CodeMirror.registerHelper("hint", "auto", function(cm, options) { + var helpers = cm.getHelpers(cm.getCursor(), "hint"), words; + if (helpers.length) { + for (var i = 0; i < helpers.length; i++) { + var cur = helpers[i](cm, options); + if (cur && cur.list.length) return cur; + } + } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) { + if (words) return CodeMirror.hint.fromList(cm, {words: words}); + } else if (CodeMirror.hint.anyword) { + return CodeMirror.hint.anyword(cm, options); + } + }); + + CodeMirror.registerHelper("hint", "fromList", function(cm, options) { + var cur = cm.getCursor(), token = cm.getTokenAt(cur); + var found = []; + for (var i = 0; i < options.words.length; i++) { + var word = options.words[i]; + if (word.slice(0, token.string.length) == token.string) + found.push(word); + } + + if (found.length) return { + list: found, + from: CodeMirror.Pos(cur.line, token.start), + to: CodeMirror.Pos(cur.line, token.end) + }; + }); + + CodeMirror.commands.autocomplete = CodeMirror.showHint; + + var defaultOptions = { + hint: CodeMirror.hint.auto, + completeSingle: true, + alignWithWord: true, + closeCharacters: /[\s()\[\]{};:>,]/, + closeOnUnfocus: true, + completeOnSingleClick: false, + container: null, + customKeys: null, + extraKeys: null + }; + + CodeMirror.defineOption("hintOptions", null); +}); diff --git a/web2py/applications/admin/static/codemirror/addon/hint/sql-hint.js b/web2py/applications/admin/static/codemirror/addon/hint/sql-hint.js new file mode 100644 index 0000000..5b0cc76 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/hint/sql-hint.js @@ -0,0 +1,240 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../../mode/sql/sql")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../../mode/sql/sql"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var tables; + var defaultTable; + var keywords; + var CONS = { + QUERY_DIV: ";", + ALIAS_KEYWORD: "AS" + }; + var Pos = CodeMirror.Pos; + + function getKeywords(editor) { + var mode = editor.doc.modeOption; + if (mode === "sql") mode = "text/x-sql"; + return CodeMirror.resolveMode(mode).keywords; + } + + function getText(item) { + return typeof item == "string" ? item : item.text; + } + + function getItem(list, item) { + if (!list.slice) return list[item]; + for (var i = list.length - 1; i >= 0; i--) if (getText(list[i]) == item) + return list[i]; + } + + function shallowClone(object) { + var result = {}; + for (var key in object) if (object.hasOwnProperty(key)) + result[key] = object[key]; + return result; + } + + function match(string, word) { + var len = string.length; + var sub = getText(word).substr(0, len); + return string.toUpperCase() === sub.toUpperCase(); + } + + function addMatches(result, search, wordlist, formatter) { + for (var word in wordlist) { + if (!wordlist.hasOwnProperty(word)) continue; + if (Array.isArray(wordlist)) { + word = wordlist[word]; + } + if (match(search, word)) { + result.push(formatter(word)); + } + } + } + + function cleanName(name) { + // Get rid name from backticks(`) and preceding dot(.) + if (name.charAt(0) == ".") { + name = name.substr(1); + } + return name.replace(/`/g, ""); + } + + function insertBackticks(name) { + var nameParts = getText(name).split("."); + for (var i = 0; i < nameParts.length; i++) + nameParts[i] = "`" + nameParts[i] + "`"; + var escaped = nameParts.join("."); + if (typeof name == "string") return escaped; + name = shallowClone(name); + name.text = escaped; + return name; + } + + function nameCompletion(cur, token, result, editor) { + // Try to complete table, colunm names and return start position of completion + var useBacktick = false; + var nameParts = []; + var start = token.start; + var cont = true; + while (cont) { + cont = (token.string.charAt(0) == "."); + useBacktick = useBacktick || (token.string.charAt(0) == "`"); + + start = token.start; + nameParts.unshift(cleanName(token.string)); + + token = editor.getTokenAt(Pos(cur.line, token.start)); + if (token.string == ".") { + cont = true; + token = editor.getTokenAt(Pos(cur.line, token.start)); + } + } + + // Try to complete table names + var string = nameParts.join("."); + addMatches(result, string, tables, function(w) { + return useBacktick ? insertBackticks(w) : w; + }); + + // Try to complete columns from defaultTable + addMatches(result, string, defaultTable, function(w) { + return useBacktick ? insertBackticks(w) : w; + }); + + // Try to complete columns + string = nameParts.pop(); + var table = nameParts.join("."); + + // Check if table is available. If not, find table by Alias + if (!getItem(tables, table)) + table = findTableByAlias(table, editor); + + var columns = getItem(tables, table); + if (columns && Array.isArray(tables) && columns.columns) + columns = columns.columns; + + if (columns) { + addMatches(result, string, columns, function(w) { + if (typeof w == "string") { + w = table + "." + w; + } else { + w = shallowClone(w); + w.text = table + "." + w.text; + } + return useBacktick ? insertBackticks(w) : w; + }); + } + + return start; + } + + function eachWord(lineText, f) { + if (!lineText) return; + var excepted = /[,;]/g; + var words = lineText.split(" "); + for (var i = 0; i < words.length; i++) { + f(words[i]?words[i].replace(excepted, '') : ''); + } + } + + function convertCurToNumber(cur) { + // max characters of a line is 999,999. + return cur.line + cur.ch / Math.pow(10, 6); + } + + function convertNumberToCur(num) { + return Pos(Math.floor(num), +num.toString().split('.').pop()); + } + + function findTableByAlias(alias, editor) { + var doc = editor.doc; + var fullQuery = doc.getValue(); + var aliasUpperCase = alias.toUpperCase(); + var previousWord = ""; + var table = ""; + var separator = []; + var validRange = { + start: Pos(0, 0), + end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length) + }; + + //add separator + var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV); + while(indexOfSeparator != -1) { + separator.push(doc.posFromIndex(indexOfSeparator)); + indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator+1); + } + separator.unshift(Pos(0, 0)); + separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length)); + + //find valid range + var prevItem = 0; + var current = convertCurToNumber(editor.getCursor()); + for (var i=0; i< separator.length; i++) { + var _v = convertCurToNumber(separator[i]); + if (current > prevItem && current <= _v) { + validRange = { start: convertNumberToCur(prevItem), end: convertNumberToCur(_v) }; + break; + } + prevItem = _v; + } + + var query = doc.getRange(validRange.start, validRange.end, false); + + for (var i = 0; i < query.length; i++) { + var lineText = query[i]; + eachWord(lineText, function(word) { + var wordUpperCase = word.toUpperCase(); + if (wordUpperCase === aliasUpperCase && getItem(tables, previousWord)) + table = previousWord; + if (wordUpperCase !== CONS.ALIAS_KEYWORD) + previousWord = word; + }); + if (table) break; + } + return table; + } + + CodeMirror.registerHelper("hint", "sql", function(editor, options) { + tables = (options && options.tables) || {}; + var defaultTableName = options && options.defaultTable; + defaultTable = (defaultTableName && getItem(tables, defaultTableName)) || []; + keywords = keywords || getKeywords(editor); + + var cur = editor.getCursor(); + var result = []; + var token = editor.getTokenAt(cur), start, end, search; + if (token.end > cur.ch) { + token.end = cur.ch; + token.string = token.string.slice(0, cur.ch - token.start); + } + + if (token.string.match(/^[.`\w@]\w*$/)) { + search = token.string; + start = token.start; + end = token.end; + } else { + start = end = cur.ch; + search = ""; + } + if (search.charAt(0) == "." || search.charAt(0) == "`") { + start = nameCompletion(cur, token, result, editor); + } else { + addMatches(result, search, tables, function(w) {return w;}); + addMatches(result, search, defaultTable, function(w) {return w;}); + addMatches(result, search, keywords, function(w) {return w.toUpperCase();}); + } + + return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)}; + }); +}); diff --git a/web2py/applications/admin/static/codemirror/addon/hint/xml-hint.js b/web2py/applications/admin/static/codemirror/addon/hint/xml-hint.js new file mode 100644 index 0000000..9b9baa0 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/hint/xml-hint.js @@ -0,0 +1,110 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var Pos = CodeMirror.Pos; + + function getHints(cm, options) { + var tags = options && options.schemaInfo; + var quote = (options && options.quoteChar) || '"'; + if (!tags) return; + var cur = cm.getCursor(), token = cm.getTokenAt(cur); + if (token.end > cur.ch) { + token.end = cur.ch; + token.string = token.string.slice(0, cur.ch - token.start); + } + var inner = CodeMirror.innerMode(cm.getMode(), token.state); + if (inner.mode.name != "xml") return; + var result = [], replaceToken = false, prefix; + var tag = /\btag\b/.test(token.type) && !/>$/.test(token.string); + var tagName = tag && /^\w/.test(token.string), tagStart; + + if (tagName) { + var before = cm.getLine(cur.line).slice(Math.max(0, token.start - 2), token.start); + var tagType = /<\/$/.test(before) ? "close" : /<$/.test(before) ? "open" : null; + if (tagType) tagStart = token.start - (tagType == "close" ? 2 : 1); + } else if (tag && token.string == "<") { + tagType = "open"; + } else if (tag && token.string == ""); + } else { + // Attribute completion + var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs; + var globalAttrs = tags["!attrs"]; + if (!attrs && !globalAttrs) return; + if (!attrs) { + attrs = globalAttrs; + } else if (globalAttrs) { // Combine tag-local and global attributes + var set = {}; + for (var nm in globalAttrs) if (globalAttrs.hasOwnProperty(nm)) set[nm] = globalAttrs[nm]; + for (var nm in attrs) if (attrs.hasOwnProperty(nm)) set[nm] = attrs[nm]; + attrs = set; + } + if (token.type == "string" || token.string == "=") { // A value + var before = cm.getRange(Pos(cur.line, Math.max(0, cur.ch - 60)), + Pos(cur.line, token.type == "string" ? token.start : token.end)); + var atName = before.match(/([^\s\u00a0=<>\"\']+)=$/), atValues; + if (!atName || !attrs.hasOwnProperty(atName[1]) || !(atValues = attrs[atName[1]])) return; + if (typeof atValues == 'function') atValues = atValues.call(this, cm); // Functions can be used to supply values for autocomplete widget + if (token.type == "string") { + prefix = token.string; + var n = 0; + if (/['"]/.test(token.string.charAt(0))) { + quote = token.string.charAt(0); + prefix = token.string.slice(1); + n++; + } + var len = token.string.length; + if (/['"]/.test(token.string.charAt(len - 1))) { + quote = token.string.charAt(len - 1); + prefix = token.string.substr(n, len - 2); + } + replaceToken = true; + } + for (var i = 0; i < atValues.length; ++i) if (!prefix || atValues[i].lastIndexOf(prefix, 0) == 0) + result.push(quote + atValues[i] + quote); + } else { // An attribute name + if (token.type == "attribute") { + prefix = token.string; + replaceToken = true; + } + for (var attr in attrs) if (attrs.hasOwnProperty(attr) && (!prefix || attr.lastIndexOf(prefix, 0) == 0)) + result.push(attr); + } + } + return { + list: result, + from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur, + to: replaceToken ? Pos(cur.line, token.end) : cur + }; + } + + CodeMirror.registerHelper("hint", "xml", getHints); +}); diff --git a/web2py/applications/admin/static/codemirror/addon/mode/loadmode.js b/web2py/applications/admin/static/codemirror/addon/mode/loadmode.js new file mode 100644 index 0000000..10117ec --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/mode/loadmode.js @@ -0,0 +1,64 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), "cjs"); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], function(CM) { mod(CM, "amd"); }); + else // Plain browser env + mod(CodeMirror, "plain"); +})(function(CodeMirror, env) { + if (!CodeMirror.modeURL) CodeMirror.modeURL = "../mode/%N/%N.js"; + + var loading = {}; + function splitCallback(cont, n) { + var countDown = n; + return function() { if (--countDown == 0) cont(); }; + } + function ensureDeps(mode, cont) { + var deps = CodeMirror.modes[mode].dependencies; + if (!deps) return cont(); + var missing = []; + for (var i = 0; i < deps.length; ++i) { + if (!CodeMirror.modes.hasOwnProperty(deps[i])) + missing.push(deps[i]); + } + if (!missing.length) return cont(); + var split = splitCallback(cont, missing.length); + for (var i = 0; i < missing.length; ++i) + CodeMirror.requireMode(missing[i], split); + } + + CodeMirror.requireMode = function(mode, cont) { + if (typeof mode != "string") mode = mode.name; + if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont); + if (loading.hasOwnProperty(mode)) return loading[mode].push(cont); + + var file = CodeMirror.modeURL.replace(/%N/g, mode); + if (env == "plain") { + var script = document.createElement("script"); + script.src = file; + var others = document.getElementsByTagName("script")[0]; + var list = loading[mode] = [cont]; + CodeMirror.on(script, "load", function() { + ensureDeps(mode, function() { + for (var i = 0; i < list.length; ++i) list[i](); + }); + }); + others.parentNode.insertBefore(script, others); + } else if (env == "cjs") { + require(file); + cont(); + } else if (env == "amd") { + requirejs([file], cont); + } + }; + + CodeMirror.autoLoadMode = function(instance, mode) { + if (!CodeMirror.modes.hasOwnProperty(mode)) + CodeMirror.requireMode(mode, function() { + instance.setOption("mode", instance.getOption("mode")); + }); + }; +}); diff --git a/web2py/applications/admin/static/codemirror/addon/mode/multiplex.js b/web2py/applications/admin/static/codemirror/addon/mode/multiplex.js new file mode 100644 index 0000000..6a95b32 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/mode/multiplex.js @@ -0,0 +1,118 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.multiplexingMode = function(outer /*, others */) { + // Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects + var others = Array.prototype.slice.call(arguments, 1); + var n_others = others.length; + + function indexOf(string, pattern, from) { + if (typeof pattern == "string") return string.indexOf(pattern, from); + var m = pattern.exec(from ? string.slice(from) : string); + return m ? m.index + from : -1; + } + + return { + startState: function() { + return { + outer: CodeMirror.startState(outer), + innerActive: null, + inner: null + }; + }, + + copyState: function(state) { + return { + outer: CodeMirror.copyState(outer, state.outer), + innerActive: state.innerActive, + inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner) + }; + }, + + token: function(stream, state) { + if (!state.innerActive) { + var cutOff = Infinity, oldContent = stream.string; + for (var i = 0; i < n_others; ++i) { + var other = others[i]; + var found = indexOf(oldContent, other.open, stream.pos); + if (found == stream.pos) { + stream.match(other.open); + state.innerActive = other; + state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0); + return other.delimStyle; + } else if (found != -1 && found < cutOff) { + cutOff = found; + } + } + if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff); + var outerToken = outer.token(stream, state.outer); + if (cutOff != Infinity) stream.string = oldContent; + return outerToken; + } else { + var curInner = state.innerActive, oldContent = stream.string; + if (!curInner.close && stream.sol()) { + state.innerActive = state.inner = null; + return this.token(stream, state); + } + var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos) : -1; + if (found == stream.pos) { + stream.match(curInner.close); + state.innerActive = state.inner = null; + return curInner.delimStyle; + } + if (found > -1) stream.string = oldContent.slice(0, found); + var innerToken = curInner.mode.token(stream, state.inner); + if (found > -1) stream.string = oldContent; + + if (curInner.innerStyle) { + if (innerToken) innerToken = innerToken + ' ' + curInner.innerStyle; + else innerToken = curInner.innerStyle; + } + + return innerToken; + } + }, + + indent: function(state, textAfter) { + var mode = state.innerActive ? state.innerActive.mode : outer; + if (!mode.indent) return CodeMirror.Pass; + return mode.indent(state.innerActive ? state.inner : state.outer, textAfter); + }, + + blankLine: function(state) { + var mode = state.innerActive ? state.innerActive.mode : outer; + if (mode.blankLine) { + mode.blankLine(state.innerActive ? state.inner : state.outer); + } + if (!state.innerActive) { + for (var i = 0; i < n_others; ++i) { + var other = others[i]; + if (other.open === "\n") { + state.innerActive = other; + state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "") : 0); + } + } + } else if (state.innerActive.close === "\n") { + state.innerActive = state.inner = null; + } + }, + + electricChars: outer.electricChars, + + innerMode: function(state) { + return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer}; + } + }; +}; + +}); diff --git a/web2py/applications/admin/static/codemirror/addon/mode/multiplex_test.js b/web2py/applications/admin/static/codemirror/addon/mode/multiplex_test.js new file mode 100644 index 0000000..d339434 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/mode/multiplex_test.js @@ -0,0 +1,33 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + CodeMirror.defineMode("markdown_with_stex", function(){ + var inner = CodeMirror.getMode({}, "stex"); + var outer = CodeMirror.getMode({}, "markdown"); + + var innerOptions = { + open: '$', + close: '$', + mode: inner, + delimStyle: 'delim', + innerStyle: 'inner' + }; + + return CodeMirror.multiplexingMode(outer, innerOptions); + }); + + var mode = CodeMirror.getMode({}, "markdown_with_stex"); + + function MT(name) { + test.mode( + name, + mode, + Array.prototype.slice.call(arguments, 1), + 'multiplexing'); + } + + MT( + "stexInsideMarkdown", + "[strong **Equation:**] [delim $][inner&tag \\pi][delim $]"); +})(); diff --git a/web2py/applications/admin/static/codemirror/addon/mode/overlay.js b/web2py/applications/admin/static/codemirror/addon/mode/overlay.js new file mode 100644 index 0000000..e1b9ed3 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/mode/overlay.js @@ -0,0 +1,85 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Utility function that allows modes to be combined. The mode given +// as the base argument takes care of most of the normal mode +// functionality, but a second (typically simple) mode is used, which +// can override the style of text. Both modes get to parse all of the +// text, but when both assign a non-null style to a piece of code, the +// overlay wins, unless the combine argument was true and not overridden, +// or state.overlay.combineTokens was true, in which case the styles are +// combined. + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.overlayMode = function(base, overlay, combine) { + return { + startState: function() { + return { + base: CodeMirror.startState(base), + overlay: CodeMirror.startState(overlay), + basePos: 0, baseCur: null, + overlayPos: 0, overlayCur: null, + streamSeen: null + }; + }, + copyState: function(state) { + return { + base: CodeMirror.copyState(base, state.base), + overlay: CodeMirror.copyState(overlay, state.overlay), + basePos: state.basePos, baseCur: null, + overlayPos: state.overlayPos, overlayCur: null + }; + }, + + token: function(stream, state) { + if (stream != state.streamSeen || + Math.min(state.basePos, state.overlayPos) < stream.start) { + state.streamSeen = stream; + state.basePos = state.overlayPos = stream.start; + } + + if (stream.start == state.basePos) { + state.baseCur = base.token(stream, state.base); + state.basePos = stream.pos; + } + if (stream.start == state.overlayPos) { + stream.pos = stream.start; + state.overlayCur = overlay.token(stream, state.overlay); + state.overlayPos = stream.pos; + } + stream.pos = Math.min(state.basePos, state.overlayPos); + + // state.overlay.combineTokens always takes precedence over combine, + // unless set to null + if (state.overlayCur == null) return state.baseCur; + else if (state.baseCur != null && + state.overlay.combineTokens || + combine && state.overlay.combineTokens == null) + return state.baseCur + " " + state.overlayCur; + else return state.overlayCur; + }, + + indent: base.indent && function(state, textAfter) { + return base.indent(state.base, textAfter); + }, + electricChars: base.electricChars, + + innerMode: function(state) { return {state: state.base, mode: base}; }, + + blankLine: function(state) { + if (base.blankLine) base.blankLine(state.base); + if (overlay.blankLine) overlay.blankLine(state.overlay); + } + }; +}; + +}); diff --git a/web2py/applications/admin/static/codemirror/addon/mode/simple.js b/web2py/applications/admin/static/codemirror/addon/mode/simple.js new file mode 100644 index 0000000..795328b --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/mode/simple.js @@ -0,0 +1,213 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineSimpleMode = function(name, states) { + CodeMirror.defineMode(name, function(config) { + return CodeMirror.simpleMode(config, states); + }); + }; + + CodeMirror.simpleMode = function(config, states) { + ensureState(states, "start"); + var states_ = {}, meta = states.meta || {}, hasIndentation = false; + for (var state in states) if (state != meta && states.hasOwnProperty(state)) { + var list = states_[state] = [], orig = states[state]; + for (var i = 0; i < orig.length; i++) { + var data = orig[i]; + list.push(new Rule(data, states)); + if (data.indent || data.dedent) hasIndentation = true; + } + } + var mode = { + startState: function() { + return {state: "start", pending: null, + local: null, localState: null, + indent: hasIndentation ? [] : null}; + }, + copyState: function(state) { + var s = {state: state.state, pending: state.pending, + local: state.local, localState: null, + indent: state.indent && state.indent.slice(0)}; + if (state.localState) + s.localState = CodeMirror.copyState(state.local.mode, state.localState); + if (state.stack) + s.stack = state.stack.slice(0); + for (var pers = state.persistentStates; pers; pers = pers.next) + s.persistentStates = {mode: pers.mode, + spec: pers.spec, + state: pers.state == state.localState ? s.localState : CodeMirror.copyState(pers.mode, pers.state), + next: s.persistentStates}; + return s; + }, + token: tokenFunction(states_, config), + innerMode: function(state) { return state.local && {mode: state.local.mode, state: state.localState}; }, + indent: indentFunction(states_, meta) + }; + if (meta) for (var prop in meta) if (meta.hasOwnProperty(prop)) + mode[prop] = meta[prop]; + return mode; + }; + + function ensureState(states, name) { + if (!states.hasOwnProperty(name)) + throw new Error("Undefined state " + name + "in simple mode"); + } + + function toRegex(val, caret) { + if (!val) return /(?:)/; + var flags = ""; + if (val instanceof RegExp) { + if (val.ignoreCase) flags = "i"; + val = val.source; + } else { + val = String(val); + } + return new RegExp((caret === false ? "" : "^") + "(?:" + val + ")", flags); + } + + function asToken(val) { + if (!val) return null; + if (typeof val == "string") return val.replace(/\./g, " "); + var result = []; + for (var i = 0; i < val.length; i++) + result.push(val[i] && val[i].replace(/\./g, " ")); + return result; + } + + function Rule(data, states) { + if (data.next || data.push) ensureState(states, data.next || data.push); + this.regex = toRegex(data.regex); + this.token = asToken(data.token); + this.data = data; + } + + function tokenFunction(states, config) { + return function(stream, state) { + if (state.pending) { + var pend = state.pending.shift(); + if (state.pending.length == 0) state.pending = null; + stream.pos += pend.text.length; + return pend.token; + } + + if (state.local) { + if (state.local.end && stream.match(state.local.end)) { + var tok = state.local.endToken || null; + state.local = state.localState = null; + return tok; + } else { + var tok = state.local.mode.token(stream, state.localState), m; + if (state.local.endScan && (m = state.local.endScan.exec(stream.current()))) + stream.pos = stream.start + m.index; + return tok; + } + } + + var curState = states[state.state]; + for (var i = 0; i < curState.length; i++) { + var rule = curState[i]; + var matches = (!rule.data.sol || stream.sol()) && stream.match(rule.regex); + if (matches) { + if (rule.data.next) { + state.state = rule.data.next; + } else if (rule.data.push) { + (state.stack || (state.stack = [])).push(state.state); + state.state = rule.data.push; + } else if (rule.data.pop && state.stack && state.stack.length) { + state.state = state.stack.pop(); + } + + if (rule.data.mode) + enterLocalMode(config, state, rule.data.mode, rule.token); + if (rule.data.indent) + state.indent.push(stream.indentation() + config.indentUnit); + if (rule.data.dedent) + state.indent.pop(); + if (matches.length > 2) { + state.pending = []; + for (var j = 2; j < matches.length; j++) + if (matches[j]) + state.pending.push({text: matches[j], token: rule.token[j - 1]}); + stream.backUp(matches[0].length - (matches[1] ? matches[1].length : 0)); + return rule.token[0]; + } else if (rule.token && rule.token.join) { + return rule.token[0]; + } else { + return rule.token; + } + } + } + stream.next(); + return null; + }; + } + + function cmp(a, b) { + if (a === b) return true; + if (!a || typeof a != "object" || !b || typeof b != "object") return false; + var props = 0; + for (var prop in a) if (a.hasOwnProperty(prop)) { + if (!b.hasOwnProperty(prop) || !cmp(a[prop], b[prop])) return false; + props++; + } + for (var prop in b) if (b.hasOwnProperty(prop)) props--; + return props == 0; + } + + function enterLocalMode(config, state, spec, token) { + var pers; + if (spec.persistent) for (var p = state.persistentStates; p && !pers; p = p.next) + if (spec.spec ? cmp(spec.spec, p.spec) : spec.mode == p.mode) pers = p; + var mode = pers ? pers.mode : spec.mode || CodeMirror.getMode(config, spec.spec); + var lState = pers ? pers.state : CodeMirror.startState(mode); + if (spec.persistent && !pers) + state.persistentStates = {mode: mode, spec: spec.spec, state: lState, next: state.persistentStates}; + + state.localState = lState; + state.local = {mode: mode, + end: spec.end && toRegex(spec.end), + endScan: spec.end && spec.forceEnd !== false && toRegex(spec.end, false), + endToken: token && token.join ? token[token.length - 1] : token}; + } + + function indexOf(val, arr) { + for (var i = 0; i < arr.length; i++) if (arr[i] === val) return true; + } + + function indentFunction(states, meta) { + return function(state, textAfter, line) { + if (state.local && state.local.mode.indent) + return state.local.mode.indent(state.localState, textAfter, line); + if (state.indent == null || state.local || meta.dontIndentStates && indexOf(state.state, meta.dontIndentStates) > -1) + return CodeMirror.Pass; + + var pos = state.indent.length - 1, rules = states[state.state]; + scan: for (;;) { + for (var i = 0; i < rules.length; i++) { + var rule = rules[i]; + if (rule.data.dedent && rule.data.dedentIfLineStart !== false) { + var m = rule.regex.exec(textAfter); + if (m && m[0]) { + pos--; + if (rule.next || rule.push) rules = states[rule.next || rule.push]; + textAfter = textAfter.slice(m[0].length); + continue scan; + } + } + } + break; + } + return pos < 0 ? 0 : state.indent[pos]; + }; + } +}); diff --git a/web2py/applications/admin/static/codemirror/addon/search/match-highlighter.js b/web2py/applications/admin/static/codemirror/addon/search/match-highlighter.js new file mode 100644 index 0000000..e9a2272 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/search/match-highlighter.js @@ -0,0 +1,128 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Highlighting text that matches the selection +// +// Defines an option highlightSelectionMatches, which, when enabled, +// will style strings that match the selection throughout the +// document. +// +// The option can be set to true to simply enable it, or to a +// {minChars, style, wordsOnly, showToken, delay} object to explicitly +// configure it. minChars is the minimum amount of characters that should be +// selected for the behavior to occur, and style is the token style to +// apply to the matches. This will be prefixed by "cm-" to create an +// actual CSS class name. If wordsOnly is enabled, the matches will be +// highlighted only if the selected text is a word. showToken, when enabled, +// will cause the current token to be highlighted when nothing is selected. +// delay is used to specify how much time to wait, in milliseconds, before +// highlighting the matches. + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + var DEFAULT_MIN_CHARS = 2; + var DEFAULT_TOKEN_STYLE = "matchhighlight"; + var DEFAULT_DELAY = 100; + var DEFAULT_WORDS_ONLY = false; + + function State(options) { + if (typeof options == "object") { + this.minChars = options.minChars; + this.style = options.style; + this.showToken = options.showToken; + this.delay = options.delay; + this.wordsOnly = options.wordsOnly; + } + if (this.style == null) this.style = DEFAULT_TOKEN_STYLE; + if (this.minChars == null) this.minChars = DEFAULT_MIN_CHARS; + if (this.delay == null) this.delay = DEFAULT_DELAY; + if (this.wordsOnly == null) this.wordsOnly = DEFAULT_WORDS_ONLY; + this.overlay = this.timeout = null; + } + + CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + var over = cm.state.matchHighlighter.overlay; + if (over) cm.removeOverlay(over); + clearTimeout(cm.state.matchHighlighter.timeout); + cm.state.matchHighlighter = null; + cm.off("cursorActivity", cursorActivity); + } + if (val) { + cm.state.matchHighlighter = new State(val); + highlightMatches(cm); + cm.on("cursorActivity", cursorActivity); + } + }); + + function cursorActivity(cm) { + var state = cm.state.matchHighlighter; + clearTimeout(state.timeout); + state.timeout = setTimeout(function() {highlightMatches(cm);}, state.delay); + } + + function highlightMatches(cm) { + cm.operation(function() { + var state = cm.state.matchHighlighter; + if (state.overlay) { + cm.removeOverlay(state.overlay); + state.overlay = null; + } + if (!cm.somethingSelected() && state.showToken) { + var re = state.showToken === true ? /[\w$]/ : state.showToken; + var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start; + while (start && re.test(line.charAt(start - 1))) --start; + while (end < line.length && re.test(line.charAt(end))) ++end; + if (start < end) + cm.addOverlay(state.overlay = makeOverlay(line.slice(start, end), re, state.style)); + return; + } + var from = cm.getCursor("from"), to = cm.getCursor("to"); + if (from.line != to.line) return; + if (state.wordsOnly && !isWord(cm, from, to)) return; + var selection = cm.getRange(from, to).replace(/^\s+|\s+$/g, ""); + if (selection.length >= state.minChars) + cm.addOverlay(state.overlay = makeOverlay(selection, false, state.style)); + }); + } + + function isWord(cm, from, to) { + var str = cm.getRange(from, to); + if (str.match(/^\w+$/) !== null) { + if (from.ch > 0) { + var pos = {line: from.line, ch: from.ch - 1}; + var chr = cm.getRange(pos, from); + if (chr.match(/\W/) === null) return false; + } + if (to.ch < cm.getLine(from.line).length) { + var pos = {line: to.line, ch: to.ch + 1}; + var chr = cm.getRange(to, pos); + if (chr.match(/\W/) === null) return false; + } + return true; + } else return false; + } + + function boundariesAround(stream, re) { + return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) && + (stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos))); + } + + function makeOverlay(query, hasBoundary, style) { + return {token: function(stream) { + if (stream.match(query) && + (!hasBoundary || boundariesAround(stream, hasBoundary))) + return style; + stream.next(); + stream.skipTo(query.charAt(0)) || stream.skipToEnd(); + }}; + } +}); diff --git a/web2py/applications/admin/static/codemirror/addon/search/matchesonscrollbar.css b/web2py/applications/admin/static/codemirror/addon/search/matchesonscrollbar.css new file mode 100644 index 0000000..77932cc --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/search/matchesonscrollbar.css @@ -0,0 +1,8 @@ +.CodeMirror-search-match { + background: gold; + border-top: 1px solid orange; + border-bottom: 1px solid orange; + -moz-box-sizing: border-box; + box-sizing: border-box; + opacity: .5; +} diff --git a/web2py/applications/admin/static/codemirror/addon/search/matchesonscrollbar.js b/web2py/applications/admin/static/codemirror/addon/search/matchesonscrollbar.js new file mode 100644 index 0000000..dbd67a4 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/search/matchesonscrollbar.js @@ -0,0 +1,95 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("./searchcursor"), require("../scroll/annotatescrollbar")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "./searchcursor", "../scroll/annotatescrollbar"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineExtension("showMatchesOnScrollbar", function(query, caseFold, options) { + if (typeof options == "string") options = {className: options}; + if (!options) options = {}; + return new SearchAnnotation(this, query, caseFold, options); + }); + + function SearchAnnotation(cm, query, caseFold, options) { + this.cm = cm; + var annotateOptions = {listenForChanges: false}; + for (var prop in options) annotateOptions[prop] = options[prop]; + if (!annotateOptions.className) annotateOptions.className = "CodeMirror-search-match"; + this.annotation = cm.annotateScrollbar(annotateOptions); + this.query = query; + this.caseFold = caseFold; + this.gap = {from: cm.firstLine(), to: cm.lastLine() + 1}; + this.matches = []; + this.update = null; + + this.findMatches(); + this.annotation.update(this.matches); + + var self = this; + cm.on("change", this.changeHandler = function(_cm, change) { self.onChange(change); }); + } + + var MAX_MATCHES = 1000; + + SearchAnnotation.prototype.findMatches = function() { + if (!this.gap) return; + for (var i = 0; i < this.matches.length; i++) { + var match = this.matches[i]; + if (match.from.line >= this.gap.to) break; + if (match.to.line >= this.gap.from) this.matches.splice(i--, 1); + } + var cursor = this.cm.getSearchCursor(this.query, CodeMirror.Pos(this.gap.from, 0), this.caseFold); + while (cursor.findNext()) { + var match = {from: cursor.from(), to: cursor.to()}; + if (match.from.line >= this.gap.to) break; + this.matches.splice(i++, 0, match); + if (this.matches.length > MAX_MATCHES) break; + } + this.gap = null; + }; + + function offsetLine(line, changeStart, sizeChange) { + if (line <= changeStart) return line; + return Math.max(changeStart, line + sizeChange); + } + + SearchAnnotation.prototype.onChange = function(change) { + var startLine = change.from.line; + var endLine = CodeMirror.changeEnd(change).line; + var sizeChange = endLine - change.to.line; + if (this.gap) { + this.gap.from = Math.min(offsetLine(this.gap.from, startLine, sizeChange), change.from.line); + this.gap.to = Math.max(offsetLine(this.gap.to, startLine, sizeChange), change.from.line); + } else { + this.gap = {from: change.from.line, to: endLine + 1}; + } + + if (sizeChange) for (var i = 0; i < this.matches.length; i++) { + var match = this.matches[i]; + var newFrom = offsetLine(match.from.line, startLine, sizeChange); + if (newFrom != match.from.line) match.from = CodeMirror.Pos(newFrom, match.from.ch); + var newTo = offsetLine(match.to.line, startLine, sizeChange); + if (newTo != match.to.line) match.to = CodeMirror.Pos(newTo, match.to.ch); + } + clearTimeout(this.update); + var self = this; + this.update = setTimeout(function() { self.updateAfterChange(); }, 250); + }; + + SearchAnnotation.prototype.updateAfterChange = function() { + this.findMatches(); + this.annotation.update(this.matches); + }; + + SearchAnnotation.prototype.clear = function() { + this.cm.off("change", this.changeHandler); + this.annotation.clear(); + }; +}); diff --git a/web2py/applications/admin/static/codemirror/addon/search/search.js b/web2py/applications/admin/static/codemirror/addon/search/search.js new file mode 100644 index 0000000..0251067 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/search/search.js @@ -0,0 +1,164 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Define search commands. Depends on dialog.js or another +// implementation of the openDialog method. + +// Replace works a little oddly -- it will do the replace on the next +// Ctrl-G (or whatever is bound to findNext) press. You prevent a +// replace by making sure the match is no longer selected when hitting +// Ctrl-G. + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("./searchcursor"), require("../dialog/dialog")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "./searchcursor", "../dialog/dialog"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + function searchOverlay(query, caseInsensitive) { + if (typeof query == "string") + query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g"); + else if (!query.global) + query = new RegExp(query.source, query.ignoreCase ? "gi" : "g"); + + return {token: function(stream) { + query.lastIndex = stream.pos; + var match = query.exec(stream.string); + if (match && match.index == stream.pos) { + stream.pos += match[0].length; + return "searching"; + } else if (match) { + stream.pos = match.index; + } else { + stream.skipToEnd(); + } + }}; + } + + function SearchState() { + this.posFrom = this.posTo = this.query = null; + this.overlay = null; + } + function getSearchState(cm) { + return cm.state.search || (cm.state.search = new SearchState()); + } + function queryCaseInsensitive(query) { + return typeof query == "string" && query == query.toLowerCase(); + } + function getSearchCursor(cm, query, pos) { + // Heuristic: if the query string is all lowercase, do a case insensitive search. + return cm.getSearchCursor(query, pos, queryCaseInsensitive(query)); + } + function dialog(cm, text, shortText, deflt, f) { + if (cm.openDialog) cm.openDialog(text, f, {value: deflt}); + else f(prompt(shortText, deflt)); + } + function confirmDialog(cm, text, shortText, fs) { + if (cm.openConfirm) cm.openConfirm(text, fs); + else if (confirm(shortText)) fs[0](); + } + function parseQuery(query) { + var isRE = query.match(/^\/(.*)\/([a-z]*)$/); + if (isRE) { + try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); } + catch(e) {} // Not a regular expression after all, do a string search + } + if (typeof query == "string" ? query == "" : query.test("")) + query = /x^/; + return query; + } + var queryDialog = + 'Search: (Use /re/ syntax for regexp search)'; + function doSearch(cm, rev) { + var state = getSearchState(cm); + if (state.query) return findNext(cm, rev); + dialog(cm, queryDialog, "Search for:", cm.getSelection(), function(query) { + cm.operation(function() { + if (!query || state.query) return; + state.query = parseQuery(query); + cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query)); + state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query)); + cm.addOverlay(state.overlay); + if (cm.showMatchesOnScrollbar) { + if (state.annotate) { state.annotate.clear(); state.annotate = null; } + state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query)); + } + state.posFrom = state.posTo = cm.getCursor(); + findNext(cm, rev); + }); + }); + } + function findNext(cm, rev) {cm.operation(function() { + var state = getSearchState(cm); + var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo); + if (!cursor.find(rev)) { + cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0)); + if (!cursor.find(rev)) return; + } + cm.setSelection(cursor.from(), cursor.to()); + cm.scrollIntoView({from: cursor.from(), to: cursor.to()}); + state.posFrom = cursor.from(); state.posTo = cursor.to(); + });} + function clearSearch(cm) {cm.operation(function() { + var state = getSearchState(cm); + if (!state.query) return; + state.query = null; + cm.removeOverlay(state.overlay); + if (state.annotate) { state.annotate.clear(); state.annotate = null; } + });} + + var replaceQueryDialog = + 'Replace: (Use /re/ syntax for regexp search)'; + var replacementQueryDialog = 'With: '; + var doReplaceConfirm = "Replace? "; + function replace(cm, all) { + if (cm.getOption("readOnly")) return; + dialog(cm, replaceQueryDialog, "Replace:", cm.getSelection(), function(query) { + if (!query) return; + query = parseQuery(query); + dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) { + if (all) { + cm.operation(function() { + for (var cursor = getSearchCursor(cm, query); cursor.findNext();) { + if (typeof query != "string") { + var match = cm.getRange(cursor.from(), cursor.to()).match(query); + cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];})); + } else cursor.replace(text); + } + }); + } else { + clearSearch(cm); + var cursor = getSearchCursor(cm, query, cm.getCursor()); + var advance = function() { + var start = cursor.from(), match; + if (!(match = cursor.findNext())) { + cursor = getSearchCursor(cm, query); + if (!(match = cursor.findNext()) || + (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return; + } + cm.setSelection(cursor.from(), cursor.to()); + cm.scrollIntoView({from: cursor.from(), to: cursor.to()}); + confirmDialog(cm, doReplaceConfirm, "Replace?", + [function() {doReplace(match);}, advance]); + }; + var doReplace = function(match) { + cursor.replace(typeof query == "string" ? text : + text.replace(/\$(\d)/g, function(_, i) {return match[i];})); + advance(); + }; + advance(); + } + }); + }); + } + + CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);}; + CodeMirror.commands.findNext = doSearch; + CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);}; + CodeMirror.commands.clearSearch = clearSearch; + CodeMirror.commands.replace = replace; + CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);}; +}); diff --git a/web2py/applications/admin/static/codemirror/addon/search/searchcursor.js b/web2py/applications/admin/static/codemirror/addon/search/searchcursor.js new file mode 100644 index 0000000..55c108b --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/search/searchcursor.js @@ -0,0 +1,189 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + var Pos = CodeMirror.Pos; + + function SearchCursor(doc, query, pos, caseFold) { + this.atOccurrence = false; this.doc = doc; + if (caseFold == null && typeof query == "string") caseFold = false; + + pos = pos ? doc.clipPos(pos) : Pos(0, 0); + this.pos = {from: pos, to: pos}; + + // The matches method is filled in based on the type of query. + // It takes a position and a direction, and returns an object + // describing the next occurrence of the query, or null if no + // more matches were found. + if (typeof query != "string") { // Regexp match + if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g"); + this.matches = function(reverse, pos) { + if (reverse) { + query.lastIndex = 0; + var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start; + for (;;) { + query.lastIndex = cutOff; + var newMatch = query.exec(line); + if (!newMatch) break; + match = newMatch; + start = match.index; + cutOff = match.index + (match[0].length || 1); + if (cutOff == line.length) break; + } + var matchLen = (match && match[0].length) || 0; + if (!matchLen) { + if (start == 0 && line.length == 0) {match = undefined;} + else if (start != doc.getLine(pos.line).length) { + matchLen++; + } + } + } else { + query.lastIndex = pos.ch; + var line = doc.getLine(pos.line), match = query.exec(line); + var matchLen = (match && match[0].length) || 0; + var start = match && match.index; + if (start + matchLen != line.length && !matchLen) matchLen = 1; + } + if (match && matchLen) + return {from: Pos(pos.line, start), + to: Pos(pos.line, start + matchLen), + match: match}; + }; + } else { // String query + var origQuery = query; + if (caseFold) query = query.toLowerCase(); + var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;}; + var target = query.split("\n"); + // Different methods for single-line and multi-line queries + if (target.length == 1) { + if (!query.length) { + // Empty string would match anything and never progress, so + // we define it to match nothing instead. + this.matches = function() {}; + } else { + this.matches = function(reverse, pos) { + if (reverse) { + var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig); + var match = line.lastIndexOf(query); + if (match > -1) { + match = adjustPos(orig, line, match); + return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)}; + } + } else { + var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig); + var match = line.indexOf(query); + if (match > -1) { + match = adjustPos(orig, line, match) + pos.ch; + return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)}; + } + } + }; + } + } else { + var origTarget = origQuery.split("\n"); + this.matches = function(reverse, pos) { + var last = target.length - 1; + if (reverse) { + if (pos.line - (target.length - 1) < doc.firstLine()) return; + if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return; + var to = Pos(pos.line, origTarget[last].length); + for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln) + if (target[i] != fold(doc.getLine(ln))) return; + var line = doc.getLine(ln), cut = line.length - origTarget[0].length; + if (fold(line.slice(cut)) != target[0]) return; + return {from: Pos(ln, cut), to: to}; + } else { + if (pos.line + (target.length - 1) > doc.lastLine()) return; + var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length; + if (fold(line.slice(cut)) != target[0]) return; + var from = Pos(pos.line, cut); + for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln) + if (target[i] != fold(doc.getLine(ln))) return; + if (fold(doc.getLine(ln).slice(0, origTarget[last].length)) != target[last]) return; + return {from: from, to: Pos(ln, origTarget[last].length)}; + } + }; + } + } + } + + SearchCursor.prototype = { + findNext: function() {return this.find(false);}, + findPrevious: function() {return this.find(true);}, + + find: function(reverse) { + var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to); + function savePosAndFail(line) { + var pos = Pos(line, 0); + self.pos = {from: pos, to: pos}; + self.atOccurrence = false; + return false; + } + + for (;;) { + if (this.pos = this.matches(reverse, pos)) { + this.atOccurrence = true; + return this.pos.match || true; + } + if (reverse) { + if (!pos.line) return savePosAndFail(0); + pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length); + } + else { + var maxLine = this.doc.lineCount(); + if (pos.line == maxLine - 1) return savePosAndFail(maxLine); + pos = Pos(pos.line + 1, 0); + } + } + }, + + from: function() {if (this.atOccurrence) return this.pos.from;}, + to: function() {if (this.atOccurrence) return this.pos.to;}, + + replace: function(newText) { + if (!this.atOccurrence) return; + var lines = CodeMirror.splitLines(newText); + this.doc.replaceRange(lines, this.pos.from, this.pos.to); + this.pos.to = Pos(this.pos.from.line + lines.length - 1, + lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0)); + } + }; + + // Maps a position in a case-folded line back to a position in the original line + // (compensating for codepoints increasing in number during folding) + function adjustPos(orig, folded, pos) { + if (orig.length == folded.length) return pos; + for (var pos1 = Math.min(pos, orig.length);;) { + var len1 = orig.slice(0, pos1).toLowerCase().length; + if (len1 < pos) ++pos1; + else if (len1 > pos) --pos1; + else return pos1; + } + } + + CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) { + return new SearchCursor(this.doc, query, pos, caseFold); + }); + CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) { + return new SearchCursor(this, query, pos, caseFold); + }); + + CodeMirror.defineExtension("selectMatches", function(query, caseFold) { + var ranges = [], next; + var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold); + while (next = cur.findNext()) { + if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break; + ranges.push({anchor: cur.from(), head: cur.to()}); + } + if (ranges.length) + this.setSelections(ranges, 0); + }); +}); diff --git a/web2py/applications/admin/static/codemirror/addon/selection/active-line.js b/web2py/applications/admin/static/codemirror/addon/selection/active-line.js new file mode 100644 index 0000000..22da2e0 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/selection/active-line.js @@ -0,0 +1,71 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Because sometimes you need to style the cursor's line. +// +// Adds an option 'styleActiveLine' which, when enabled, gives the +// active line's wrapping
the CSS class "CodeMirror-activeline", +// and gives its background
the class "CodeMirror-activeline-background". + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + var WRAP_CLASS = "CodeMirror-activeline"; + var BACK_CLASS = "CodeMirror-activeline-background"; + + CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) { + var prev = old && old != CodeMirror.Init; + if (val && !prev) { + cm.state.activeLines = []; + updateActiveLines(cm, cm.listSelections()); + cm.on("beforeSelectionChange", selectionChange); + } else if (!val && prev) { + cm.off("beforeSelectionChange", selectionChange); + clearActiveLines(cm); + delete cm.state.activeLines; + } + }); + + function clearActiveLines(cm) { + for (var i = 0; i < cm.state.activeLines.length; i++) { + cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS); + cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS); + } + } + + function sameArray(a, b) { + if (a.length != b.length) return false; + for (var i = 0; i < a.length; i++) + if (a[i] != b[i]) return false; + return true; + } + + function updateActiveLines(cm, ranges) { + var active = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (!range.empty()) continue; + var line = cm.getLineHandleVisualStart(range.head.line); + if (active[active.length - 1] != line) active.push(line); + } + if (sameArray(cm.state.activeLines, active)) return; + cm.operation(function() { + clearActiveLines(cm); + for (var i = 0; i < active.length; i++) { + cm.addLineClass(active[i], "wrap", WRAP_CLASS); + cm.addLineClass(active[i], "background", BACK_CLASS); + } + cm.state.activeLines = active; + }); + } + + function selectionChange(cm, sel) { + updateActiveLines(cm, sel.ranges); + } +}); diff --git a/web2py/applications/admin/static/codemirror/addon/selection/mark-selection.js b/web2py/applications/admin/static/codemirror/addon/selection/mark-selection.js new file mode 100644 index 0000000..5c42d21 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/selection/mark-selection.js @@ -0,0 +1,118 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +// Because sometimes you need to mark the selected *text*. +// +// Adds an option 'styleSelectedText' which, when enabled, gives +// selected text the CSS class given as option value, or +// "CodeMirror-selectedtext" when the value is not a string. + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) { + var prev = old && old != CodeMirror.Init; + if (val && !prev) { + cm.state.markedSelection = []; + cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext"; + reset(cm); + cm.on("cursorActivity", onCursorActivity); + cm.on("change", onChange); + } else if (!val && prev) { + cm.off("cursorActivity", onCursorActivity); + cm.off("change", onChange); + clear(cm); + cm.state.markedSelection = cm.state.markedSelectionStyle = null; + } + }); + + function onCursorActivity(cm) { + cm.operation(function() { update(cm); }); + } + + function onChange(cm) { + if (cm.state.markedSelection.length) + cm.operation(function() { clear(cm); }); + } + + var CHUNK_SIZE = 8; + var Pos = CodeMirror.Pos; + var cmp = CodeMirror.cmpPos; + + function coverRange(cm, from, to, addAt) { + if (cmp(from, to) == 0) return; + var array = cm.state.markedSelection; + var cls = cm.state.markedSelectionStyle; + for (var line = from.line;;) { + var start = line == from.line ? from : Pos(line, 0); + var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line; + var end = atEnd ? to : Pos(endLine, 0); + var mark = cm.markText(start, end, {className: cls}); + if (addAt == null) array.push(mark); + else array.splice(addAt++, 0, mark); + if (atEnd) break; + line = endLine; + } + } + + function clear(cm) { + var array = cm.state.markedSelection; + for (var i = 0; i < array.length; ++i) array[i].clear(); + array.length = 0; + } + + function reset(cm) { + clear(cm); + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) + coverRange(cm, ranges[i].from(), ranges[i].to()); + } + + function update(cm) { + if (!cm.somethingSelected()) return clear(cm); + if (cm.listSelections().length > 1) return reset(cm); + + var from = cm.getCursor("start"), to = cm.getCursor("end"); + + var array = cm.state.markedSelection; + if (!array.length) return coverRange(cm, from, to); + + var coverStart = array[0].find(), coverEnd = array[array.length - 1].find(); + if (!coverStart || !coverEnd || to.line - from.line < CHUNK_SIZE || + cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0) + return reset(cm); + + while (cmp(from, coverStart.from) > 0) { + array.shift().clear(); + coverStart = array[0].find(); + } + if (cmp(from, coverStart.from) < 0) { + if (coverStart.to.line - from.line < CHUNK_SIZE) { + array.shift().clear(); + coverRange(cm, from, coverStart.to, 0); + } else { + coverRange(cm, from, coverStart.from, 0); + } + } + + while (cmp(to, coverEnd.to) < 0) { + array.pop().clear(); + coverEnd = array[array.length - 1].find(); + } + if (cmp(to, coverEnd.to) > 0) { + if (to.line - coverEnd.from.line < CHUNK_SIZE) { + array.pop().clear(); + coverRange(cm, coverEnd.from, to); + } else { + coverRange(cm, coverEnd.to, to); + } + } + } +}); diff --git a/web2py/applications/admin/static/codemirror/addon/selection/selection-pointer.js b/web2py/applications/admin/static/codemirror/addon/selection/selection-pointer.js new file mode 100644 index 0000000..ef5e404 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/addon/selection/selection-pointer.js @@ -0,0 +1,98 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + CodeMirror.defineOption("selectionPointer", false, function(cm, val) { + var data = cm.state.selectionPointer; + if (data) { + CodeMirror.off(cm.getWrapperElement(), "mousemove", data.mousemove); + CodeMirror.off(cm.getWrapperElement(), "mouseout", data.mouseout); + CodeMirror.off(window, "scroll", data.windowScroll); + cm.off("cursorActivity", reset); + cm.off("scroll", reset); + cm.state.selectionPointer = null; + cm.display.lineDiv.style.cursor = ""; + } + if (val) { + data = cm.state.selectionPointer = { + value: typeof val == "string" ? val : "default", + mousemove: function(event) { mousemove(cm, event); }, + mouseout: function(event) { mouseout(cm, event); }, + windowScroll: function() { reset(cm); }, + rects: null, + mouseX: null, mouseY: null, + willUpdate: false + }; + CodeMirror.on(cm.getWrapperElement(), "mousemove", data.mousemove); + CodeMirror.on(cm.getWrapperElement(), "mouseout", data.mouseout); + CodeMirror.on(window, "scroll", data.windowScroll); + cm.on("cursorActivity", reset); + cm.on("scroll", reset); + } + }); + + function mousemove(cm, event) { + var data = cm.state.selectionPointer; + if (event.buttons == null ? event.which : event.buttons) { + data.mouseX = data.mouseY = null; + } else { + data.mouseX = event.clientX; + data.mouseY = event.clientY; + } + scheduleUpdate(cm); + } + + function mouseout(cm, event) { + if (!cm.getWrapperElement().contains(event.relatedTarget)) { + var data = cm.state.selectionPointer; + data.mouseX = data.mouseY = null; + scheduleUpdate(cm); + } + } + + function reset(cm) { + cm.state.selectionPointer.rects = null; + scheduleUpdate(cm); + } + + function scheduleUpdate(cm) { + if (!cm.state.selectionPointer.willUpdate) { + cm.state.selectionPointer.willUpdate = true; + setTimeout(function() { + update(cm); + cm.state.selectionPointer.willUpdate = false; + }, 50); + } + } + + function update(cm) { + var data = cm.state.selectionPointer; + if (!data) return; + if (data.rects == null && data.mouseX != null) { + data.rects = []; + if (cm.somethingSelected()) { + for (var sel = cm.display.selectionDiv.firstChild; sel; sel = sel.nextSibling) + data.rects.push(sel.getBoundingClientRect()); + } + } + var inside = false; + if (data.mouseX != null) for (var i = 0; i < data.rects.length; i++) { + var rect = data.rects[i]; + if (rect.left <= data.mouseX && rect.right >= data.mouseX && + rect.top <= data.mouseY && rect.bottom >= data.mouseY) + inside = true; + } + var cursor = inside ? data.value : ""; + if (cm.display.lineDiv.style.cursor != cursor) + cm.display.lineDiv.style.cursor = cursor; + } +}); diff --git a/web2py/applications/admin/static/codemirror/emmet.min.js b/web2py/applications/admin/static/codemirror/emmet.min.js new file mode 100644 index 0000000..dc7c617 --- /dev/null +++ b/web2py/applications/admin/static/codemirror/emmet.min.js @@ -0,0 +1,304 @@ +var _=function(){function h(a,b,c){if(a===b)return a!==0||1/a==1/b;if(a==null||b==null)return a===b;if(a._chain)a=a._wrapped;if(b._chain)b=b._wrapped;if(a.isEqual&&k.isFunction(a.isEqual))return a.isEqual(b);if(b.isEqual&&k.isFunction(b.isEqual))return b.isEqual(a);var e=g.call(a);if(e!=g.call(b))return!1;switch(e){case "[object String]":return a==String(b);case "[object Number]":return a!=+a?b!=+b:a==0?1/a==1/b:a==+b;case "[object Date]":case "[object Boolean]":return+a==+b;case "[object RegExp]":return a.source== +b.source&&a.global==b.global&&a.multiline==b.multiline&&a.ignoreCase==b.ignoreCase}if(typeof a!="object"||typeof b!="object")return!1;for(var d=c.length;d--;)if(c[d]==a)return!0;c.push(a);var d=0,j=!0;if(e=="[object Array]"){if(d=a.length,j=d==b.length)for(;d--;)if(!(j=d in a==d in b&&h(a[d],b[d],c)))break}else{if("constructor"in a!="constructor"in b||a.constructor!=b.constructor)return!1;for(var f in a)if(k.has(a,f)&&(d++,!(j=k.has(b,f)&&h(a[f],b[f],c))))break;if(j){for(f in b)if(k.has(b,f)&&!d--)break; +j=!d}}c.pop();return j}var d=this,f=d._,i={},b=Array.prototype,c=Object.prototype,a=b.slice,e=b.unshift,g=c.toString,j=c.hasOwnProperty,l=b.forEach,m=b.map,n=b.reduce,o=b.reduceRight,q=b.filter,s=b.every,r=b.some,u=b.indexOf,p=b.lastIndexOf,c=Array.isArray,v=Object.keys,w=Function.prototype.bind,k=function(a){return new y(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=k;exports._=k}else d._=k;k.VERSION="1.3.3";var t=k.each=k.forEach=function(a, +b,c){if(a!=null)if(l&&a.forEach===l)a.forEach(b,c);else if(a.length===+a.length)for(var g=0,e=a.length;g2;a==null&&(a=[]);if(n&& +a.reduce===n)return g&&(b=k.bind(b,g)),e?a.reduce(b,c):a.reduce(b);t(a,function(a,d,j){e?c=b.call(g,c,a,d,j):(c=a,e=!0)});if(!e)throw new TypeError("Reduce of empty array with no initial value");return c};k.reduceRight=k.foldr=function(a,b,c,g){var e=arguments.length>2;a==null&&(a=[]);if(o&&a.reduceRight===o)return g&&(b=k.bind(b,g)),e?a.reduceRight(b,c):a.reduceRight(b);var d=k.toArray(a).reverse();g&&!e&&(b=k.bind(b,g));return e?k.reduce(d,b,c,g):k.reduce(d,b)};k.find=k.detect=function(a,b,c){var g; +z(a,function(a,e,d){if(b.call(c,a,e,d))return g=a,!0});return g};k.filter=k.select=function(a,b,c){var g=[];if(a==null)return g;if(q&&a.filter===q)return a.filter(b,c);t(a,function(a,e,d){b.call(c,a,e,d)&&(g[g.length]=a)});return g};k.reject=function(a,b,c){var g=[];if(a==null)return g;t(a,function(a,e,d){b.call(c,a,e,d)||(g[g.length]=a)});return g};k.every=k.all=function(a,b,c){var g=!0;if(a==null)return g;if(s&&a.every===s)return a.every(b,c);t(a,function(a,e,d){if(!(g=g&&b.call(c,a,e,d)))return i}); +return!!g};var z=k.some=k.any=function(a,b,c){b||(b=k.identity);var g=!1;if(a==null)return g;if(r&&a.some===r)return a.some(b,c);t(a,function(a,e,d){if(g||(g=b.call(c,a,e,d)))return i});return!!g};k.include=k.contains=function(a,b){var c=!1;return a==null?c:u&&a.indexOf===u?a.indexOf(b)!=-1:c=z(a,function(a){return a===b})};k.invoke=function(b,c){var g=a.call(arguments,2);return k.map(b,function(a){return(k.isFunction(c)?c||a:a[c]).apply(a,g)})};k.pluck=function(a,b){return k.map(a,function(a){return a[b]})}; +k.max=function(a,b,c){if(!b&&k.isArray(a)&&a[0]===+a[0])return Math.max.apply(Math,a);if(!b&&k.isEmpty(a))return-Infinity;var g={computed:-Infinity};t(a,function(a,e,d){e=b?b.call(c,a,e,d):a;e>=g.computed&&(g={value:a,computed:e})});return g.value};k.min=function(a,b,c){if(!b&&k.isArray(a)&&a[0]===+a[0])return Math.min.apply(Math,a);if(!b&&k.isEmpty(a))return Infinity;var g={computed:Infinity};t(a,function(a,e,d){e=b?b.call(c,a,e,d):a;eg?1:0}),"value")};k.groupBy=function(a,b){var c={},g=k.isFunction(b)?b:function(a){return a[b]};t(a,function(a,b){var e=g(a,b);(c[e]||(c[e]=[])).push(a)}); +return c};k.sortedIndex=function(a,b,c){c||(c=k.identity);for(var g=0,e=a.length;g>1;c(a[d])=0})})};k.difference=function(b){var c=k.flatten(a.call(arguments,1),!0);return k.filter(b,function(a){return!k.include(c,a)})};k.zip=function(){for(var b=a.call(arguments),c=k.max(k.pluck(b,"length")), +g=Array(c),e=0;e=0;c--)b=[a[c].apply(this,b)];return b[0]}};k.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};k.keys=v||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var b=[],c;for(c in a)k.has(a,c)&&(b[b.length]=c);return b};k.values=function(a){return k.map(a,k.identity)};k.functions=k.methods=function(a){var b=[],c;for(c in a)k.isFunction(a[c])&&b.push(c);return b.sort()};k.extend=function(b){t(a.call(arguments, +1),function(a){for(var c in a)b[c]=a[c]});return b};k.pick=function(b){var c={};t(k.flatten(a.call(arguments,1)),function(a){a in b&&(c[a]=b[a])});return c};k.defaults=function(b){t(a.call(arguments,1),function(a){for(var c in a)b[c]==null&&(b[c]=a[c])});return b};k.clone=function(a){return!k.isObject(a)?a:k.isArray(a)?a.slice():k.extend({},a)};k.tap=function(a,b){b(a);return a};k.isEqual=function(a,b){return h(a,b,[])};k.isEmpty=function(a){if(a==null)return!0;if(k.isArray(a)||k.isString(a))return a.length=== +0;for(var b in a)if(k.has(a,b))return!1;return!0};k.isElement=function(a){return!!(a&&a.nodeType==1)};k.isArray=c||function(a){return g.call(a)=="[object Array]"};k.isObject=function(a){return a===Object(a)};k.isArguments=function(a){return g.call(a)=="[object Arguments]"};if(!k.isArguments(arguments))k.isArguments=function(a){return!(!a||!k.has(a,"callee"))};k.isFunction=function(a){return g.call(a)=="[object Function]"};k.isString=function(a){return g.call(a)=="[object String]"};k.isNumber=function(a){return g.call(a)== +"[object Number]"};k.isFinite=function(a){return k.isNumber(a)&&isFinite(a)};k.isNaN=function(a){return a!==a};k.isBoolean=function(a){return a===!0||a===!1||g.call(a)=="[object Boolean]"};k.isDate=function(a){return g.call(a)=="[object Date]"};k.isRegExp=function(a){return g.call(a)=="[object RegExp]"};k.isNull=function(a){return a===null};k.isUndefined=function(a){return a===void 0};k.has=function(a,b){return j.call(a,b)};k.noConflict=function(){d._=f;return this};k.identity=function(a){return a}; +k.times=function(a,b,c){for(var g=0;g/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};k.result=function(a,b){if(a==null)return null;var c=a[b];return k.isFunction(c)?c.call(a):c};k.mixin=function(a){t(k.functions(a),function(b){F(b,k[b]=a[b])})};var G=0;k.uniqueId=function(a){var b=G++;return a?a+b:b};k.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g, +escape:/<%-([\s\S]+?)%>/g};var B=/.^/,A={"\\":"\\","'":"'",r:"\r",n:"\n",t:"\t",u2028:"\u2028",u2029:"\u2029"},C;for(C in A)A[A[C]]=C;var H=/\\|'|\r|\n|\t|\u2028|\u2029/g,I=/\\(\\|'|r|n|t|u2028|u2029)/g,D=function(a){return a.replace(I,function(a,b){return A[b]})};k.template=function(a,b,c){c=k.defaults(c||{},k.templateSettings);a="__p+='"+a.replace(H,function(a){return"\\"+A[a]}).replace(c.escape||B,function(a,b){return"'+\n_.escape("+D(b)+")+\n'"}).replace(c.interpolate||B,function(a,b){return"'+\n("+ +D(b)+")+\n'"}).replace(c.evaluate||B,function(a,b){return"';\n"+D(b)+"\n;__p+='"})+"';\n";c.variable||(a="with(obj||{}){\n"+a+"}\n");var a="var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n"+a+"return __p;\n",g=new Function(c.variable||"obj","_",a);if(b)return g(b,k);b=function(a){return g.call(this,a,k)};b.source="function("+(c.variable||"obj")+"){\n"+a+"}";return b};k.chain=function(a){return k(a).chain()};var y=function(a){this._wrapped=a};k.prototype=y.prototype; +var E=function(a,b){return b?k(a).chain():a},F=function(b,c){y.prototype[b]=function(){var b=a.call(arguments);e.call(b,this._wrapped);return E(c.apply(k,b),this._chain)}};k.mixin(k);t(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=b[a];y.prototype[a]=function(){var b=this._wrapped;c.apply(b,arguments);var g=b.length;(a=="shift"||a=="splice")&&g===0&&delete b[0];return E(b,this._chain)}});t(["concat","join","slice"],function(a){var c=b[a];y.prototype[a]=function(){return E(c.apply(this._wrapped, +arguments),this._chain)}});y.prototype.chain=function(){this._chain=!0;return this};y.prototype.value=function(){return this._wrapped};return k}.call({}),emmet=function(h){function d(a,b,d){var f;f=b&&b.hasOwnProperty("constructor")?b.constructor:function(){a.apply(this,arguments)};_.extend(f,a);c.prototype=a.prototype;f.prototype=new c;b&&_.extend(f.prototype,b);d&&_.extend(f,d);f.prototype.constructor=f;f.__super__=a.prototype;return f}function f(c){!(c in b)&&a&&a(c);return b[c]}if(typeof _=="undefined")try{_= +h.require("underscore")}catch(i){}if(typeof _=="undefined")throw"Cannot access to Underscore.js lib";var b={_:_},c=function(){},a=null;return{define:function(a,c){a in b||(b[a]=_.isFunction(c)?this.exec(c):c)},require:f,exec:function(a,b){return a.call(b||h,_.bind(f,this),_,this)},extend:function(a,b){var c=d(this,a,b);c.extend=this.extend;if(a.hasOwnProperty("toString"))c.prototype.toString=a.toString;return c},expandAbbreviation:function(a,b,c,d){if(!a)return"";var b=b||"html",h=f("filters"),i= +f("abbreviationParser"),c=f("profile").get(c,b);f("tabStops").resetTabstopIndex();a=h.extractFromAbbreviation(a);d=i.parse(a[0],{syntax:b,contextNode:d});b=h.composeList(b,c,a[1]);h.apply(d,b,c);return d.toString()},defaultSyntax:function(){return"html"},defaultProfile:function(){return"plain"},log:function(){h.console&&h.console.log&&h.console.log.apply(h.console,arguments)},setModuleLoader:function(b){a=b}}}(this); +if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=emmet;exports.emmet=emmet} +emmet.define("abbreviationParser",function(h,d){function f(){this.parent=null;this.children=[];this._attributes=[];this.abbreviation="";this.counter=1;this._name=null;this._text="";this.repeatCount=1;this.hasImplicitRepeat=!1;this._data={};this.padding=this.content=this.end=this.start=""}function i(a){return a.substring(1,a.length-1)}function b(a){for(var a=h("utils").trim(a),c=new f,g=c.addChild(),e,j=h("stringStream").create(a),a=1E3,l;!j.eol()&&--a>0;)switch(e=j.peek(),e){case "(":j.start=j.pos; +if(j.skipToPair("(",")"))e=b(i(j.current())),(l=j.match(/^\*(\d+)?/,!0))&&g._setRepeat(l[1]),d.each(e.children,function(a){g.addChild(a)});else throw'Invalid abbreviation: mo matching ")" found for character at '+j.pos;break;case ">":g=g.addChild();j.next();break;case "+":g=g.parent.addChild();j.next();break;case "^":e=g.parent||g;g=(e.parent||e).addChild();j.next();break;default:j.start=j.pos,j.eatWhile(function(a){if(a=="["||a=="{"){if(j.skipToPair(a,q[a]))return j.backUp(1),!0;throw'Invalid abbreviation: mo matching "'+ +q[a]+'" found for character at '+j.pos;}return a=="+"?(j.next(),a=j.eol()||~"+>^*".indexOf(j.peek()),j.backUp(1),a):a!="("&&m(a)}),g.setAbbreviation(j.current()),j.start=j.pos}if(a<1)throw"Endless loop detected";return c}function c(a){var a=h("utils").trim(a),b=[],a=h("stringStream").create(a);for(a.eatSpace();!a.eol();)if(a.start=a.pos,a.eatWhile(o)){var c=a.current(),g="";if(a.peek()=="="){a.next();a.start=a.pos;var e=a.peek();if(e=='"'||e=="'"){a.next();a:{for(var g=a,d=void 0;d=g.next();)if(d=== +e){g=!0;break a}g=!1}if(g)g=a.current(),g=g.substring(1,g.length-1);else throw"Invalid attribute value";}else if(a.eatWhile(/[^\s\]]/))g=a.current();else throw"Invalid attribute value";}b.push({name:c,value:g});a.eatSpace()}else break;return b}function a(a){for(var b=[],g={"#":"id",".":"class"},d=null,j=h("stringStream").create(a);!j.eol();)switch(j.peek()){case "#":case ".":if(d===null)d=j.pos;var f=g[j.peek()];j.next();j.start=j.pos;j.eatWhile(o);b.push({name:f,value:j.current()});break;case "[":if(d=== +null)d=j.pos;j.start=j.pos;if(!j.skipToPair("[","]"))throw"Invalid attribute set definition";b=b.concat(c(i(j.current())));break;default:j.next()}return!b.length?null:{element:a.substring(0,d),attributes:e(b)}}function e(a){var a=d.map(a,function(a){return d.clone(a)}),b={};return d.filter(a,function(a){if(!(a.name in b))return b[a.name]=a;var c=b[a.name];a.name.toLowerCase()=="class"?c.value+=(c.value.length?" ":"")+a.value:c.value=a.value;return!1})}function g(a){if(!~a.indexOf("{"))return null; +for(var b=h("stringStream").create(a);!b.eol();)switch(b.peek()){case "[":case "(":b.skipToPair(b.peek(),q[b.peek()]);break;case "{":return b.start=b.pos,b.skipToPair("{","}"),{element:a.substring(0,b.start),text:i(b.current())};default:b.next()}}function j(a){for(var b=a.children.length-1,c,g;b>=0;b--)if(g=a.children[b],g.isRepeating()){c=g.repeatCount;g.repeatCount=1;for(g.updateProperty("counter",1);--c>0;)g.parent.addChild(g.clone(),b+1).updateProperty("counter",c+1)}d.each(a.children,j);return a} +function l(a){for(var b=a.children.length-1;b>=0;b--){var c=a.children[b];c.isGroup()?c.replace(l(c).children):c.isEmpty()&&c.remove()}d.each(a.children,l);return a}function m(a){var b=a.charCodeAt(0);return b>64&&b<91||b>96&&b<123||b>47&&b<58||"#.*:$-_!@|%".indexOf(a)!=-1}var n=/^[\w\-\$\:@\!%]+\+?$/i,o=/[\w\-:\$]/,q={"[":"]","(":")","{":"}"},s=Array.prototype.splice,r=[],u=[],p=[];f.prototype={addChild:function(a,b){a=a||new f;a.parent=this;d.isUndefined(b)?this.children.push(a):this.children.splice(b, +0,a);return a},clone:function(){var a=new f;d.each(["abbreviation","counter","_name","_text","repeatCount","hasImplicitRepeat","start","end","content","padding"],function(b){a[b]=this[b]},this);a._attributes=d.map(this._attributes,function(a){return d.clone(a)});a._data=d.clone(this._data);a.children=d.map(this.children,function(b){b=b.clone();b.parent=a;return b});return a},remove:function(){if(this.parent)this.parent.children=d.without(this.parent.children,this);return this},replace:function(){var a= +this.parent,b=d.indexOf(a.children,this),c=d.flatten(arguments);s.apply(a.children,[b,1].concat(c));d.each(c,function(b){b.parent=a})},updateProperty:function(a,b){this[a]=b;d.each(this.children,function(c){c.updateProperty(a,b)})},find:function(a){return this.findAll(a)[0]},findAll:function(a){if(!d.isFunction(a))var b=a.toLowerCase(),a=function(a){return a.name().toLowerCase()==b};var c=[];d.each(this.children,function(b){a(b)&&c.push(b);c=c.concat(b.findAll(a))});return d.compact(c)},data:function(a, +b){if(arguments.length==2&&(this._data[a]=b,a=="resource"&&h("elements").is(b,"snippet")&&(this.content=b.data,this._text)))this.content=h("abbreviationUtils").insertChildContent(b.data,this._text);return this._data[a]},name:function(){var a=this.matchedResource();return h("elements").is(a,"element")?a.name:this._name},attributeList:function(){var a=[],b=this.matchedResource();h("elements").is(b,"element")&&d.isArray(b.attributes)&&(a=a.concat(b.attributes));return e(a.concat(this._attributes))}, +attribute:function(a,b){if(arguments.length==2){var c=d.indexOf(d.pluck(this._attributes,"name"),a.toLowerCase());~c?this._attributes[c].value=b:this._attributes.push({name:a,value:b})}return(d.find(this.attributeList(),function(b){return b.name==a})||{}).value},matchedResource:function(){return this.data("resource")},index:function(){return this.parent?d.indexOf(this.parent.children,this):-1},_setRepeat:function(a){a?this.repeatCount=parseInt(a,10)||1:this.hasImplicitRepeat=!0},setAbbreviation:function(b){var c= +this;this.abbreviation=b=(b||"").replace(/\*(\d+)?$/,function(a,b){c._setRepeat(b);return""});var e=g(b);if(e)b=e.element,this.content=this._text=e.text;if(e=a(b))b=e.element,this._attributes=e.attributes;if((this._name=b)&&!n.test(this._name))throw"Invalid abbreviation";},toString:function(){var a=h("utils"),b=this.start,c=this.end,g=this.content,e=this;d.each(p,function(a){b=a(b,e,"start");g=a(g,e,"content");c=a(c,e,"end")});var j=d.map(this.children,function(a){return a.toString()}).join(""),g= +h("abbreviationUtils").insertChildContent(g,j,{keepVariable:!1});return b+a.padString(g,this.padding)+c},hasEmptyChildren:function(){return!!d.find(this.children,function(a){return a.isEmpty()})},hasImplicitName:function(){return!this._name&&!this.isTextNode()},isGroup:function(){return!this.abbreviation},isEmpty:function(){return!this.abbreviation&&!this.children.length},isRepeating:function(){return this.repeatCount>1||this.hasImplicitRepeat},isTextNode:function(){return!this.name()&&!this.attributeList().length}, +isElement:function(){return!this.isEmpty()&&!this.isTextNode()},deepestChild:function(){if(!this.children.length)return null;for(var a=this;a.children.length;)a=d.last(a.children);return a}};p.push(function(a,b){return h("utils").replaceCounter(a,b.counter)});return{parse:function(a,c){var c=c||{},g=b(a);if(c.contextNode){g._name=c.contextNode.name;var e={};d.each(g._attributes,function(a){e[a.name]=a});d.each(c.contextNode.attributes,function(a){a.name in e?e[a.name].value=a.value:(a=d.clone(a), +g._attributes.push(a),e[a.name]=a)})}d.each(r,function(a){a(g,c)});g=l(j(g));d.each(u,function(a){a(g,c)});return g},AbbreviationNode:f,addPreprocessor:function(a){d.include(r,a)||r.push(a)},removeFilter:function(a){preprocessor=d.without(r,a)},addPostprocessor:function(a){d.include(u,a)||u.push(a)},removePostprocessor:function(a){u=d.without(u,a)},addOutputProcessor:function(a){d.include(p,a)||p.push(a)},removeOutputProcessor:function(a){p=d.without(p,a)},isAllowedChar:function(a){a=String(a);return m(a)|| +~">+^[](){}".indexOf(a)}}}); +emmet.exec(function(h,d){function f(i,b){var c=h("resources"),a=h("elements"),e=h("abbreviationParser");d.each(d.clone(i.children),function(g){var j=c.getMatchedResource(g,b);if(d.isString(j))g.data("resource",a.create("snippet",j));else if(a.is(j,"reference")){j=e.parse(j.data,{syntax:b});if(g.repeatCount>1){var h=j.findAll(function(a){return a.hasImplicitRepeat});d.each(h,function(a){a.repeatCount=g.repeatCount;a.hasImplicitRepeat=!1})}var i=j.deepestChild();i&&d.each(g.children,function(a){i.addChild(a)}); +d.each(j.children,function(a){d.each(g.attributeList(),function(b){a.attribute(b.name,b.value)})});g.replace(j.children)}else g.data("resource",j);f(g,b)})}h("abbreviationParser").addPreprocessor(function(d,b){var c=b.syntax||emmet.defaultSyntax();f(d,c)})}); +emmet.exec(function(h,d){function f(a){for(var b=h("range"),c=[],a=h("stringStream").create(a);!a.eol();){if(a.peek()=="\\")a.next();else if(a.start=a.pos,a.match(e,!0)){c.push(b.create(a.start,e));continue}a.next()}return c}function i(a,b){var c=h("utils"),e=f(a);e.reverse();d.each(e,function(e){a=c.replaceSubstring(a,b,e)});return a}function b(a){return f(a.content).length?!0:!!d.find(a.attributeList(),function(a){return!!f(a.value).length})}function c(a,c,e){var f=a.findAll(function(a){return b(a)}); +b(a)&&f.unshift(a);f.length?d.each(f,function(a){a.content=i(a.content,c);d.each(a._attributes,function(a){a.value=i(a.value,c)})}):(a=a.deepestChild()||a,a.content=e?c:h("abbreviationUtils").insertChildContent(a.content,c))}var a=h("abbreviationParser"),e="$#";a.addPreprocessor(function(a,b){if(b.pastedContent){var c=h("utils"),e=d.map(c.splitByLines(b.pastedContent,!0),c.trim);a.findAll(function(a){if(a.hasImplicitRepeat)return a.data("paste",e),a.repeatCount=e.length})}});a.addPostprocessor(function(a, +b){!a.findAll(function(a){var b=a.data("paste"),g="";d.isArray(b)?g=b[a.counter-1]:d.isFunction(b)?g=b(a.counter-1,a.content):b&&(g=b);g&&c(a,g,!!a.data("pasteOverwrites"));a.data("paste",null);return!!b}).length&&b.pastedContent&&c(a,b.pastedContent)})});emmet.exec(function(h,d){function f(i){var b=h("tagName");d.each(i.children,function(c){if(c.hasImplicitName()||c.data("forceNameResolving"))c._name=b.resolve(c.parent.name());f(c)});return i}h("abbreviationParser").addPostprocessor(f)}); +emmet.define("cssParser",function(h,d){function f(a){return typeof a!=="undefined"}function i(){return{"char":g.chnum,line:g.linenum}}function b(a,b,c){var e=g,c=c||{};j.push({charstart:f(c["char"])?c["char"]:e.chnum,charend:f(c.charend)?c.charend:e.chnum,linestart:f(c.line)?c.line:e.linenum,lineend:f(c.lineend)?c.lineend:e.linenum,value:a,type:b||a})}function c(a,b){var c=g,e=b||{},d=f(e["char"])?e["char"]:c.chnum,e=f(e.line)?e.line:c.linenum;return{name:"ParseError",message:a+" at line "+(e+1)+ +" char "+(d+1),walker:c,tokens:j}}function a(a){var c=g,e=c.ch,d=i(),j=a?a+e:e,e=c.nextChar();for(a&&(d["char"]-=a.length);m(e)||n(e);)j+=e,e=c.nextChar();b(j,"identifier",d)}function e(){var e=g.ch;if(e===" "||e==="\t"){for(var d=g.ch,j="",f=i();d===" "||d==="\t";)j+=d,d=g.nextChar();b(j,"white",f)}else{if(e==="/"){var d=g,e=f=d.ch,h,p=i();h=d.nextChar();if(h!=="*")p.charend=p["char"],p.lineend=p.line,j=b(e,e,p);else{for(;!(f==="*"&&h==="/");)e+=h,f=h,h=d.nextChar();e+=h;d.nextChar();b(e,"comment", +p)}return j}if(e==='"'||e==="'"){d=g;e=f=j=d.ch;p=i();for(j=d.nextChar();j!==f;){if(j==="\n")if(h=d.nextChar(),h==="\\")e+=j+h;else throw c("Unterminated string",p);else e+=j==="\\"?j+d.nextChar():j;j=d.nextChar()}e+=j;d.nextChar();b(e,"string",p)}else if(e==="("){d=g;j=d.ch;f=0;e=j;h=i();for(j=d.nextChar();j!==")"&&!f;){if(j==="(")f++;else if(j===")")f--;else if(j===!1)throw c("Unterminated brace",h);e+=j;j=d.nextChar()}e+=j;d.nextChar();b(e,"brace",h)}else{if(e==="-"||e==="."||n(e)){j=g;f=j.ch; +e=i();h=f;var p=h===".",v,f=j.nextChar();v=!n(f);if(p&&v)e.charend=e["char"],e.lineend=e.line,d=b(h,".",e);else if(h==="-"&&v)d=a("-");else{for(;f!==!1&&(n(f)||!p&&f===".");)f==="."&&(p=!0),h+=f,f=j.nextChar();b(h,"number",e)}return d}if(m(e))return a();if(l(e))return d=g,e=d.ch,j=i(),h=d.nextChar(),h==="="&&l(e,!0)?(e+=h,b(e,"match",j),d.nextChar(),f=void 0):(j.charend=j["char"]+1,j.lineend=j.line,b(e,e,j)),f;if(e==="\n")b("line"),g.nextChar();else throw c("Unrecognized character");}}}var g,j=[], +l,m,n;g={lines:null,total_lines:0,linenum:-1,line:"",ch:"",chnum:-1,init:function(a){var b=g;b.lines=a.replace(/\r\n/g,"\n").replace(/\r/g,"\n").split("\n");b.total_lines=b.lines.length;b.chnum=-1;b.linenum=-1;b.ch="";b.line="";b.nextLine();b.nextChar()},nextLine:function(){this.linenum+=1;this.line=this.total_lines<=this.linenum?!1:this.lines[this.linenum];if(this.chnum!==-1)this.chnum=0;return this.line},nextChar:function(){for(this.chnum+=1;this.line.charAt(this.chnum)==="";){if(this.nextLine()=== +!1)return this.ch=!1;this.chnum=-1;return this.ch="\n"}return this.ch=this.line.charAt(this.chnum)},peek:function(){return this.line.charAt(this.chnum+1)}};m=function(a){return a=="&"||a==="_"||a==="-"||a>="a"&&a<="z"||a>="A"&&a<="Z"};n=function(a){return a!==!1&&a>="0"&&a<="9"};l=function(){for(var a="{}[]()+*=.,;:>~|\\%$#@^!".split(""),b="*^|$~".split(""),c={},e={},g=0;g")):null:a.match("--")?g(b("comment","--\>")):a.match("DOCTYPE",!0,!0)?(a.eatWhile(/[\w\._\-]/),g(c(1))):null;else if(a.eat("?"))return a.eatWhile(/[\w\._\-]/),e.tokenize=b("meta","?>"),"meta";else{w=a.eat("/")?"closeTag":"openTag";a.eatSpace();for(v="";d=a.eat(/[^\s\u00a0=<>\"\'\/?]/);)v+=d;e.tokenize=f;return"tag"}else return d== +"&"?(a.eat("#")?a.eat("x")?a.eatWhile(/[a-fA-F\d]/)&&a.eat(";"):a.eatWhile(/[\d]/)&&a.eat(";"):a.eatWhile(/[\w\.\-:]/)&&a.eat(";"))?"atom":"error":(a.eatWhile(/[^&<]/),"text")}function f(a,b){var c=a.next();return c==">"||c=="/"&&a.eat(">")?(b.tokenize=d,w=c==">"?"endTag":"selfcloseTag","tag"):c=="="?(w="equals",null):/[\'\"]/.test(c)?(b.tokenize=i(c),b.tokenize(a,b)):(a.eatWhile(/[^\s\u00a0=<>\"\'\/?]/),"word")}function i(a){return function(b,c){for(;!b.eol();)if(b.next()==a){c.tokenize=f;break}return"string"}} +function b(a,b){return function(c,e){for(;!c.eol();){if(c.match(b)){e.tokenize=d;break}c.next()}return a}}function c(a){return function(b,e){for(var g;(g=b.next())!=null;)if(g=="<")return e.tokenize=c(a+1),e.tokenize(b,e);else if(g==">")if(a==1){e.tokenize=d;break}else return e.tokenize=c(a-1),e.tokenize(b,e);return"meta"}}function a(){for(var a=arguments.length-1;a>=0;a--)k.cc.push(arguments[a])}function e(){a.apply(null,arguments);return!0}function g(){if(k.context)k.context=k.context.prev}function j(a){if(a== +"openTag")return k.tagName=v,e(o,l(k.startOfLine));else if(a=="closeTag")return a=!1,k.context?k.context.tagName!=v&&(p.implicitlyClosed.hasOwnProperty(k.context.tagName.toLowerCase())&&g(),a=!k.context||k.context.tagName!=v):a=!0,a&&(t="error"),e(m(a));return e()}function l(a){return function(b){if(b=="selfcloseTag"||b=="endTag"&&p.autoSelfClosers.hasOwnProperty(k.tagName.toLowerCase()))return n(k.tagName.toLowerCase()),e();if(b=="endTag"){n(k.tagName.toLowerCase());var b=k.tagName,c=p.doNotIndent.hasOwnProperty(b)|| +k.context&&k.context.noIndent;k.context={prev:k.context,tagName:b,indent:k.indented,startOfLine:a,noIndent:c}}return e()}}function m(a){return function(b){a&&(t="error");if(b=="endTag")return g(),e();t="error";return e(arguments.callee)}}function n(a){for(var b;;){if(!k.context)break;b=k.context.tagName.toLowerCase();if(!p.contextGrabbers.hasOwnProperty(b)||!p.contextGrabbers[b].hasOwnProperty(a))break;g()}}function o(b){if(b=="word")return t="attribute",e(q,o);if(b=="endTag"||b=="selfcloseTag")return a(); +t="error";return e(o)}function q(b){if(b=="equals")return e(s,o);p.allowMissing||(t="error");return b=="endTag"||b=="selfcloseTag"?a():e()}function s(b){if(b=="string")return e(r);if(b=="word"&&p.allowUnquoted)return t="string",e();t="error";return b=="endTag"||b=="selfCloseTag"?a():e()}function r(b){return b=="string"?e(r):a()}function u(a,b){if(a.sol())b.startOfLine=!0,b.indented=0;if(a.eatSpace())return null;t=w=v=null;var c=b.tokenize(a,b);b.type=w;if((c||w)&&c!="comment")for(k=b;;)if((b.cc.pop()|| +j)(w||c))break;b.startOfLine=!1;return t||c}var p={autoSelfClosers:{},implicitlyClosed:{},contextGrabbers:{},doNotIndent:{},allowUnquoted:!0,allowMissing:!0},v=null,w=null,k=null,t;return{parse:function(a,b){for(var b=b||0,c={tokenize:d,cc:[],indented:0,startOfLine:!0,tagName:null,context:null},e=h("stringStream").create(a),g=[];!e.eol();)g.push({type:u(e,c),start:e.start+b,end:e.pos+b}),e.start=e.pos;return g}}}); +emmet.define("string-score",function(){return{score:function(h,d,f){if(h==d)return 1;if(d=="")return 0;for(var i=0,b=d.length,c=h.length,a,e=1,g=0,j,l,m,n;g-1?n:Math.max(j,l);if(l===-1)if(f){e+=1-f;continue}else return 0;else j=0.1;h[l]===m&&(j+=0.1);l===0?(j+=0.6,g===0&&(a=1)):h.charAt(l-1)===" "&&(j+=0.8);h=h.substring(l+1,c);i+=j}h=i/b;b=(h*(b/c)+h)/2;b/=e;a&&b+0.15<1&&(b+=0.15);return b}}}); +emmet.define("utils",function(h,d){function f(b){this._data=[];this.length=0;b&&this.append(b)}var i="${0}";f.prototype={append:function(b){this._data.push(b);this.length+=b.length},toString:function(){return this._data.join("")},valueOf:function(){return this.toString()}};return{reTag:/<\/?[\w:\-]+(?:\s+[\w\-:]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*\s*(\/?)>$/,endsWithTag:function(b){return this.reTag.test(b)},isNumeric:function(b){typeof b=="string"&&(b=b.charCodeAt(0));return b&&b>47&& +b<58},trim:function(b){return(b||"").replace(/^\s+|\s+$/g,"")},getNewline:function(){var b=h("resources");if(!b)return"\n";b=b.getVariable("newline");return d.isString(b)?b:"\n"},setNewline:function(b){var c=h("resources");c.setVariable("newline",b);c.setVariable("nl",b)},splitByLines:function(b,c){var a=this.getNewline(),a=(b||"").replace(/\r\n/g,"\n").replace(/\n\r/g,"\n").replace(/\r/g,"\n").replace(/\n/g,a).split(a);c&&(a=d.filter(a,function(a){return a.length&&!!this.trim(a)},this));return a}, +normalizeNewline:function(b){return this.splitByLines(b).join(this.getNewline())},repeatString:function(b,c){for(var a=[],e=0;ee++;)a+="0";return a+b},unindentString:function(b, +c){for(var a=this.splitByLines(b),e=0;eb.length?b:b.substring(0,a)+c+b.substring(e)},narrowToNonSpace:function(b,c,a){c=h("range").create(c,a);for(a=/[\s\n\r\u00a0]/;c.start +c.start;)if(c.end--,!a.test(b.charAt(c.end))){c.end++;break}return c},findNewlineBounds:function(b,c){for(var a=b.length,e=0,g=a-1,d=c-1;d>0;d--){var f=b.charAt(d);if(f=="\n"||f=="\r"){e=d+1;break}}for(d=c;d":return b>c;case "gte":case ">=":return b>=c}}function i(b,c){d.isObject(b)&&"start"in b?(this.start=Math.min(b.start,b.end),this.end=Math.max(b.start,b.end)):d.isArray(b)?(this.start=b[0],this.end=b[1]):(c=d.isString(c)?c.length:+c,this.start=b,this.end=b+c)}i.prototype={length:function(){return Math.abs(this.end-this.start)}, +equal:function(b){return this.cmp(b,"eq","eq")},shift:function(b){this.start+=b;this.end+=b;return this},overlap:function(b){return b.start<=this.end&&b.end>=this.start},intersection:function(b){if(this.overlap(b)){var c=Math.max(b.start,this.start);return new i(c,Math.min(b.end,this.end)-c)}return null},union:function(b){if(this.overlap(b)){var c=Math.min(b.start,this.start);return new i(c,Math.max(b.end,this.end)-c)}return null},inside:function(b){return this.cmp(b,"lte","gt")},contains:function(b){return this.cmp(b, +"lt","gt")},include:function(){return this.cmp(loc,"lte","gte")},cmp:function(b,c,a){var e;b instanceof i?(e=b.start,b=b.end):e=b;return f(this.start,e,c||"<=")&&f(this.end,b,a||">")},substring:function(b){return this.length()>0?b.substring(this.start,this.end):""},clone:function(){return new i(this.start,this.length())},toArray:function(){return[this.start,this.end]},toString:function(){return"{"+this.start+", "+this.length()+"}"}};return{create:function(b,c){if(d.isUndefined(b)||b===null)return null; +if(b instanceof i)return b;if(d.isObject(b)&&"start"in b&&"end"in b)c=b.end-b.start,b=b.start;return new i(b,c)},create2:function(b,c){d.isNumber(b)&&d.isNumber(c)&&(c-=b);return this.create(b,c)}}}); +emmet.define("handlerList",function(h,d){function f(){this._list=[]}f.prototype={add:function(f,b){this._list.push(d.extend({order:0},b||{},{fn:f}))},remove:function(f){this._list=d.without(this._list,d.find(this._list,function(b){return b.fn===f}))},list:function(){return d.sortBy(this._list,"order").reverse()},listFn:function(){return d.pluck(this.list(),"fn")},exec:function(f,b){var b=b||[],c=null;d.find(this.list(),function(a){c=a.fn.apply(a,b);if(c!==f)return!0});return c}};return{create:function(){return new f}}}); +emmet.define("tokenIterator",function(h,d){function f(d){this.tokens=d;this._position=0;this.reset()}f.prototype={next:function(){if(this.hasNext()){var d=this.tokens[++this._i];this._position=d.start;return d}return null},current:function(){return this.tokens[this._i]},position:function(){return this._position},hasNext:function(){return this._i=this.string.length},sol:function(){return this.pos==0},peek:function(){return this.string.charAt(this.pos)},next:function(){if(this.posf},eatSpace:function(){for(var d=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>d},skipToEnd:function(){this.pos=this.string.length},skipTo:function(d){d=this.string.indexOf(d,this.pos);if(d>-1)return this.pos=d,!0},skipToPair:function(d,f){for(var h=0,b,c=this.pos,a=this.string.length;c/,c={},a={},e=h("handlerList").create();return{setVocabulary:function(b,e){i={};e== +"system"?c=b:a=b},getVocabulary:function(b){return b=="system"?c:a},getMatchedResource:function(a,b){return e.exec(null,d.toArray(arguments))||this.findSnippet(b,a.name())},getVariable:function(a){return(this.getSection("variables")||{})[a]},setVariable:function(a,b){var c=this.getVocabulary("user")||{};if(!("variables"in c))c.variables={};c.variables[a]=b;this.setVocabulary(c,"user")},hasSyntax:function(a){return a in this.getVocabulary("user")||a in this.getVocabulary("system")},addResolver:function(a, +b){e.add(a,b)},removeResolver:function(a){e.remove(a)},getSection:function(b){if(!b)return null;b in i||(i[b]=h("utils").deepMerge({},c[b],a[b]));for(var e=i[b],f=d.rest(arguments),m;e&&(m=f.shift());)if(m in e)e=e[m];else return null;return e},findItem:function(a,b){for(var c=this.getSection(a);c;){if(b in c)return c[b];c=this.getSection(c["extends"])}},findSnippet:function(a,b,c){if(!a||!b)return null;var c=c||[],e=[b];~b.indexOf("-")&&e.push(b.replace(/\-/g,":"));var h=this.getSection(a),i=null; +d.find(["snippets","abbreviations"],function(b){var c=this.getSection(a,b);if(c)return d.find(e,function(a){if(c[a])return i=f(a,c[a],b)})},this);c.push(a);return!i&&h["extends"]&&!d.include(c,h["extends"])?this.findSnippet(h["extends"],b,c):i},fuzzyFindSnippet:function(a,b,c){var c=c||0.3,a=this.getAllSnippets(a),e=h("string-score"),b=b.replace(/:$/,"").replace(/:/g,"-"),f=d.map(a,function(a,c){return{key:c,score:e.score(a.nk,b,0.1)}});if((f=d.last(d.sortBy(f,"score")))&&f.score>=c)return a[f.key].parsedValue}, +getAllSnippets:function(a){var b="all-"+a;if(!i[b]){var c=[],e=[];do{var h=this.getSection(a);if(!h)break;d.each(["snippets","abbreviations"],function(a){var b={};d.each(h[a]||null,function(c,e){b[e]={nk:e.replace(/:$/,"").replace(/:/g,"-"),value:c,parsedValue:f(e,c,a),type:a}});c.push(b)});e.push(a);a=h["extends"]}while(a&&!d.include(e,a));i[b]=d.extend.apply(d,c.reverse())}return i[b]}}}); +emmet.define("actions",function(h,d){function f(b){return h("utils").trim(b.charAt(0).toUpperCase()+b.substring(1).replace(/_[a-z]/g,function(b){return" "+b.charAt(1).toUpperCase()}))}var i={};return{add:function(b,c,a){b=b.toLowerCase();a=a||{};if(!a.label)a.label=f(b);i[b]={name:b,fn:c,options:a}},get:function(b){return i[b.toLowerCase()]},run:function(b,c){d.isArray(c)||(c=d.rest(arguments));var a=this.get(b);return a?a.fn.apply(emmet,c):(emmet.log('Action "%s" is not defined',b),!1)},getAll:function(){return i}, +getList:function(){return d.values(this.getAll())},getMenu:function(b){var c=[],b=b||[];d.each(this.getList(),function(a){if(!a.options.hidden&&!d.include(b,a.name)){var e=f(a.name),g=c;if(a.options.label)for(var j=a.options.label.split("/"),e=j.pop(),h,i;h=j.shift();)i=d.find(g,function(a){return a.type=="submenu"&&a.name==h}),i||(i={name:h,type:"submenu",items:[]},g.push(i)),g=i.items;g.push({type:"action",name:a.name,label:e})}});return c},getActionNameForMenuTitle:function(b,c){var a=null;d.find(c|| +this.getMenu(),function(c){if(c.type=="action"){if(c.label==b||c.name==b)return a=c.name}else return a=this.getActionNameForMenuTitle(b,c.items)},this);return a||null}}}); +emmet.define("profile",function(h,d){function f(a){d.extend(this,e,a)}function i(a,b){switch(String(b||"").toLowerCase()){case "lower":return a.toLowerCase();case "upper":return a.toUpperCase()}return a}function b(b,c){return a[b.toLowerCase()]=new f(c)}function c(){b("xhtml");b("html",{self_closing_tag:!1});b("xml",{self_closing_tag:!0,tag_nl:!0});b("plain",{tag_nl:!1,indent:!1,place_cursor:!1});b("line",{tag_nl:!1,indent:!1,extraFilters:"s"})}var a={},e={tag_case:"asis",attr_case:"asis",attr_quotes:"double", +tag_nl:"decide",tag_nl_leaf:!1,place_cursor:!0,indent:!0,inline_break:3,self_closing_tag:"xhtml",filters:"",extraFilters:""};f.prototype={tagName:function(a){return i(a,this.tag_case)},attributeName:function(a){return i(a,this.attr_case)},attributeQuote:function(){return this.attr_quotes=="single"?"'":'"'},selfClosing:function(){return this.self_closing_tag=="xhtml"?" /":this.self_closing_tag===!0?"/":""},cursor:function(){return this.place_cursor?h("utils").getCaretPlaceholder():""}};c();return{create:function(a, +c){return arguments.length==2?b(a,c):new f(d.defaults(a||{},e))},get:function(b,c){if(!b&&c){var e=h("resources").findItem(c,"profile");e&&(b=e)}return!b?a.plain:b instanceof f?b:d.isString(b)&&b.toLowerCase()in a?a[b.toLowerCase()]:this.create(b)},remove:function(b){b=(b||"").toLowerCase();b in a&&delete a[b]},reset:function(){a={};c()},stringCase:i}}); +emmet.define("editorUtils",function(h){return{isInsideTag:function(d,f){for(var h=/^<\/?\w[\w\:\-]*.*?>/,b=f;b>-1;){if(d.charAt(b)=="<")break;b--}return b!=-1&&(h=h.exec(d.substring(b)))&&f>b&&f"&&e.endsWithTag(d.substring(0,f+1)))){i=f+1;break}}return i!=-1&&!a&&!c&&!b?d.substring(i).replace(/^[\*\+\>\^]+/,""):""},getImageSize:function(d){var f=function(){return d.charCodeAt(h++)};if(d.substr(0,8)==="\u0089PNG\r\n\u001a\n"){var h=d.indexOf("IHDR")+4;return{width:f()<<24|f()<<16|f()<<8|f(),height:f()<<24|f()<<16|f()<<8|f()}}else if(d.substr(0,4)==="GIF8")return h=6,{width:f()|f()<<8,height:f()|f()<<8};else if(d.substr(0,2)==="\u00ff\u00d8")for(var h=2,b=d.length;h< +b;){if(f()!=255)break;var c=f();if(c==218)break;var a=f()<<8|f();if(c>=192&&c<=207&&!(c&4)&&!(c&8))return h+=1,{height:f()<<8|f(),width:f()<<8|f()};else h+=a-2}},captureContext:function(d){if(String(d.getSyntax())in{html:1,xml:1,xsl:1}){var f=String(d.getContent()),i=h("htmlMatcher").find(f,d.getCaretPos());if(i&&i.type=="tag"){for(var d=/([\w\-:]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g,i=i.open,f=i.range.substring(f).replace(/^<[\w\-\:]+/,""),i={name:i.name,attributes:[]}, +b;b=d.exec(f);)i.attributes.push({name:b[1],value:b[2]});return i}}return null},findExpressionBounds:function(d,f){for(var i=String(d.getContent()),b=i.length,c=d.getCaretPos()-1,a=c+1;c>=0&&f(i.charAt(c),c,i);)c--;for(;ac)return h("range").create([++c,a])},compoundUpdate:function(d,f){if(f){var h=d.getSelectionRange();d.replaceContent(f.data,f.start,f.end,!0);d.createSelection(f.caret,f.caret+h.end-h.start);return!0}return!1},detectSyntax:function(d,f){var i=f||"html"; +h("resources").hasSyntax(i)||(i="html");if(i=="html"&&(this.isStyle(d)||this.isInlineCSS(d)))i="css";return i},detectProfile:function(d){var f=d.getSyntax(),i=h("resources").findItem(f,"profile");if(i)return i;switch(f){case "xml":case "xsl":return"xml";case "css":if(this.isInlineCSS(d))return"line";break;case "html":return(i=h("resources").getVariable("profile"))||(i=this.isXHTML(d)?"xhtml":"html"),i}return"xhtml"},isXHTML:function(d){return d.getContent().search(/]+XHTML/i)!=-1},isStyle:function(d){var f= +String(d.getContent()),d=d.getCaretPos();return(f=h("htmlMatcher").tag(f,d))&&f.open.name.toLowerCase()=="style"&&f.innerRange.cmp(d,"lte","gte")},isInlineCSS:function(d){var f=String(d.getContent()),d=d.getCaretPos();return(f=h("xmlEditTree").parseFromPosition(f,d,!0))?(f=f.itemFromPosition(d,!0))&&f.name().toLowerCase()=="style"&&f.valueRange(!0).cmp(d,"lte","gte"):!1}}}); +emmet.define("abbreviationUtils",function(h,d){return{isSnippet:function(d){return h("elements").is(d.matchedResource(),"snippet")},isUnary:function(d){var i=d.matchedResource();return d.children.length||this.isSnippet(d)?!1:i&&i.is_empty||h("tagName").isEmptyElement(d.name())},isInline:function(d){return d.isTextNode()||!d.name()||h("tagName").isInlineLevel(d.name())},isBlock:function(d){return this.isSnippet(d)||!this.isInline(d)},isSnippet:function(d){return h("elements").is(d.matchedResource(), +"snippet")},hasTagsInContent:function(d){return h("utils").matchesTag(d.content)},hasBlockChildren:function(h){return this.hasTagsInContent(h)&&this.isBlock(h)||d.any(h.children,function(d){return this.isBlock(d)},this)},insertChildContent:function(f,i,b){var b=d.extend({keepVariable:!0,appendIfNoChild:!0},b||{}),c=!1,a=h("utils"),f=a.replaceVariables(f,function(e,d,h){var l=e;d=="child"&&(l=a.padString(i,a.getLinePaddingFromPosition(f,h.start)),c=!0,b.keepVariable&&(l+=e));return l});!c&&b.appendIfNoChild&& +(f+=i);return f}}}); +emmet.define("base64",function(){return{encode:function(h){for(var d=[],f,i,b,c,a,e,g=0,j=h.length;g>2,f=(f&3)<<4|i>>4,i=(i&15)<<2|b>>6,b&=63,isNaN(a)?i=b=64:isNaN(e)&&(b=64),d.push("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(c)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(f)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(i)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(b)); +return d.join("")},decode:function(h){var d,f,i,b,c,a=0,e=0,g=[],j=h.length;if(!h)return h;h+="";do d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(h.charAt(a++)),f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(h.charAt(a++)),b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(h.charAt(a++)),c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(h.charAt(a++)),i=d<<18|f<<12|b<<6|c,d=i>>16& +255,f=i>>8&255,i&=255,b==64?g[e++]=String.fromCharCode(d):c==64?g[e++]=String.fromCharCode(d,f):g[e++]=String.fromCharCode(d,f,i);while(a")){n=h+3;break}if(h=b.matches(n))if(h.type=="open"&&!h.selfClose)c.push(h.name);else if(h.type=="close"){if(!c.length)return h.name==a.name?h:null;if(d.last(c)==h.name)c.pop();else{for(var q=!1;c.length&&!q;)c.pop()==h.name&&(q=!0);if(!c.length&&!q)return h.name==a.name?h:null}}}}var c=/^<([\w\:\-]+)((?:\s+[\w\-:]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/, +a=/^<\/([\w\:\-]+)[^>]*>/;return{find:function(a,c){for(var j=h("range"),l=f(a),m=null,n=null,o=c;o>=0;o--)if(m=l.open(o)){if(m.selfClose&&m.range.cmp(c,"lt","gt"))break;if(n=b(m,l)){if(j.create2(m.range.start,n.range.end).contains(c))break}else if(m.range.contains(c))break;m=null}else if(i(a,o,"--\>"))for(var q=o-1;q>=0;q--)if(i(a,q,"--\>"))break;else{if(i(a,q,"<\!--")){o=q;break}}else if(i(a,o,"<\!--")){q=o+4;for(m=a.length;q")){q+=3;break}m={range:h("range").create(o,d.isNumber(q)? +q-o:q[0]),type:"comment"};break}if(m)return q=o=null,n?(o=j.create2(m.range.start,n.range.end),q=j.create2(m.range.end,n.range.start)):o=q=j.create2(m.range.start,m.range.end),m.type=="comment"&&(j=o.substring(a),q.start+=j.length-j.replace(/^<\!--\s*/,"").length,q.end-=j.length-j.replace(/\s*--\>$/,"").length),{open:m,close:n,type:m.type=="comment"?"comment":"tag",innerRange:q,innerContent:function(){return this.innerRange.substring(a)},outerRange:o,outerContent:function(){return this.outerRange.substring(a)}, +range:!q.length()||!q.cmp(c,"lte","gte")?o:q,content:function(){return this.range.substring(a)},source:a}},tag:function(a,b){var c=this.find(a,b);if(c&&c.type=="tag")return c}}}); +emmet.define("tabStops",function(h,d){var f=100,i=0,b={replaceCarets:!1,escape:function(b){return"\\"+b},tabstop:function(b){return b.token},variable:function(b){return b.token}};h("abbreviationParser").addOutputProcessor(function(b,a){var e=0,d=h("tabStops"),f=h("utils"),l={tabstop:function(a){var b=parseInt(a.group);if(b==0)return"${0}";b>e&&(e=b);return a.placeholder?(b+=i,a=d.processText(a.placeholder,l),"${"+b+":"+a+"}"):"${"+(b+i)+"}"}},b=d.processText(b,l),b=f.replaceVariables(b,d.variablesResolver(a)); +i+=e+1;return b});return{extract:function(c,a){var e=h("utils"),g={carets:""},f=[],a=d.extend({},b,a,{tabstop:function(a){var b=a.token,c="";if(a.placeholder=="cursor")f.push({start:a.start,end:a.start+b.length,group:"carets",value:""});else{if("placeholder"in a)g[a.group]=a.placeholder;a.group in g&&(c=g[a.group]);f.push({start:a.start,end:a.start+b.length,group:a.group,value:c})}return b}});a.replaceCarets&&(c=c.replace(RegExp(e.escapeForRegexp(e.getCaretPlaceholder()),"g"),"${0:cursor}"));var c= +this.processText(c,a),i=e.stringBuilder(),m=0,e=d.map(f,function(a){i.append(c.substring(m,a.start));var b=i.length,e=g[a.group]||"";i.append(e);m=a.end;return{group:a.group,start:b,end:b+e.length}});i.append(c.substring(m));return{text:i.toString(),tabstops:d.sortBy(e,"start")}},processText:function(c,a){for(var a=d.extend({},b,a),e=h("utils").stringBuilder(),g=h("stringStream").create(c),f,i;f=g.next();)if(f=="\\"&&!g.eol())e.append(a.escape(g.next()));else{i=f;if(f=="$")if(g.start=g.pos-1,g.match(/^[0-9]+/))i= +a.tabstop({start:e.length,group:g.current().substr(1),token:g.current()});else if(f=g.match(/^\{([a-z_\-][\w\-]*)\}/))i=a.variable({start:e.length,name:f[1],token:g.current()});else if(f=g.match(/^\{([0-9]+)(:.+?)?\}/,!1)){g.skipToPair("{","}");i={start:e.length,group:f[1],token:g.current()};if(f=i.token.substring(i.group.length+2,i.token.length-1))i.placeholder=f.substr(1);i=a.tabstop(i)}e.append(i)}return e.toString()},upgrade:function(b,a){var e=0,g={tabstop:function(b){var c=parseInt(b.group); +c>e&&(e=c);return b.placeholder?"${"+(c+a)+":"+b.placeholder+"}":"${"+(c+a)+"}"}};d.each(["start","end","content"],function(a){b[a]=this.processText(b[a],g)},this);return e},variablesResolver:function(b){var a={},e=h("resources");return function(g,j){if(j=="child")return g;if(j=="cursor")return h("utils").getCaretPlaceholder();var i=b.attribute(j);if(!d.isUndefined(i))return i;if(i=e.getVariable(j))return i;a[j]||(a[j]=f++);return"${"+a[j]+":"+j+"}"}},resetPlaceholderCounter:function(){console.log("deprecated"); +f=100},resetTabstopIndex:function(){i=0;f=100}}}); +emmet.define("preferences",function(h,d){var f={},i={},b=null,c=null;return{define:function(a,b,c){var h=a;d.isString(a)&&(h={},h[a]={value:b,description:c});d.each(h,function(a,b){i[b]=d.isObject(a)&&"value"in a&&d.keys(a).length<3?a:{value:a}})},set:function(a,b){var c=a;d.isString(a)&&(c={},c[a]=b);d.each(c,function(a,b){if(!(b in i))throw'Property "'+b+'" is not defined. You should define it first with `define` method of current module';if(a!==i[b].value){switch(typeof i[b].value){case "boolean":var c= +a;d.isString(c)?(c=c.toLowerCase(),a=c=="yes"||c=="true"||c=="1"):a=!!c;break;case "number":a=parseInt(a+"",10)||0;break;default:a+=""}f[b]=a}else b in f&&delete f[b]})},get:function(a){if(a in f)return f[a];if(a in i)return i[a].value},getArray:function(a){a=this.get(a);d.isUndefined(a)||(a=d.map(a.split(","),h("utils").trim),a.length||(a=null));return a},getDict:function(a){var b={};d.each(this.getArray(a),function(a){a=a.split(":");b[a[0]]=a[1]});return b},description:function(a){return a in i? +i[a].description:void 0},remove:function(a){d.isArray(a)||(a=[a]);d.each(a,function(a){a in f&&delete f[a];a in i&&delete i[a]})},list:function(){return d.map(d.keys(i).sort(),function(a){return{name:a,value:this.get(a),type:typeof i[a].value,description:i[a].description}},this)},load:function(a){d.each(a,function(a,b){this.set(b,a)},this)},exportModified:function(){return d.clone(f)},reset:function(){f={}},_startTest:function(){b=i;c=f;i={};f={}},_stopTest:function(){i=b;f=c}}}); +emmet.define("filters",function(h,d){function f(b){return!b?[]:d.isString(b)?b.split(/[\|,]/g):b}var i={};return{add:function(b,c){i[b]=c},apply:function(b,c,a){var e=h("utils"),a=h("profile").get(a);d.each(f(c),function(c){(c=e.trim(c.toLowerCase()))&&c in i&&(b=i[c](b,a))});return b},composeList:function(b,c,a){c=h("profile").get(c);b=f(c.filters||h("resources").findItem(b,"filters")||"html");c.extraFilters&&(b=b.concat(f(c.extraFilters)));a&&(b=b.concat(f(a)));if(!b||!b.length)b=f("html");return b}, +extractFromAbbreviation:function(b){var c="",b=b.replace(/\|([\w\|\-]+)$/,function(a,b){c=b;return""});return[b,f(c)]}}}); +emmet.define("elements",function(h,d){function f(a){return{data:a}}var i={},b=/([\w\-]+)\s*=\s*(['"])(.*?)\2/g,c={add:function(a,b){var c=this;i[a]=function(){var d=b.apply(c,arguments);if(d)d.type=a;return d}},get:function(a){return i[a]},create:function(a){var b=[].slice.call(arguments,1),c=this.get(a);return c?c.apply(this,b):null},is:function(a,b){return a&&a.type===b}};c.add("element",function(a,c,g){var h={name:a,is_empty:!!g};if(c)if(h.attributes=[],d.isArray(c))h.attributes=c;else if(d.isString(c))for(;a= +b.exec(c);)h.attributes.push({name:a[1],value:a[3]});else d.each(c,function(a,b){h.attributes.push({name:b,value:a})});return h});c.add("snippet",f);c.add("reference",f);c.add("empty",function(){return{}});return c}); +emmet.define("editTree",function(h,d,f){function i(a,b){this.options=d.extend({offset:0},b);this.source=a;this._children=[];this._positions={name:0};this.initialize.apply(this,arguments)}function b(a,b,c){this.parent=a;this._name=b.value;this._value=c?c.value:"";this._positions={name:b.start,value:c?c.start:-1};this.initialize.apply(this,arguments)}var c=h("range").create;i.extend=f.extend;i.prototype={initialize:function(){},_updateSource:function(a,b,g){var f=c(b,d.isUndefined(g)?0:g-b),i=a.length- +f.length(),m=function(a){d.each(a,function(b,c){b>=f.end&&(a[c]+=i)})};m(this._positions);d.each(this.list(),function(a){m(a._positions)});this.source=h("utils").replaceSubstring(this.source,a,f)},add:function(a,c){var d=new b(a,c);this._children.push(d);return d},get:function(a){return d.isNumber(a)?this.list()[a]:d.isString(a)?d.find(this.list(),function(b){return b.name()===a}):a},getAll:function(a){d.isArray(a)||(a=[a]);var b=[],c=[];d.each(a,function(a){d.isString(a)?b.push(a):d.isNumber(a)&& +c.push(a)});return d.filter(this.list(),function(a,h){return d.include(c,h)||d.include(b,a.name())})},value:function(a,b,c){var h=this.get(a);if(h)return h.value(b);if(!d.isUndefined(b))return this.add(a,b,c)},values:function(a){return d.map(this.getAll(a),function(a){return a.value()})},remove:function(a){if(a=this.get(a))this._updateSource("",a.fullRange()),this._children=d.without(this._children,a)},list:function(){return this._children},indexOf:function(a){return d.indexOf(this.list(),this.get(a))}, +name:function(a){if(!d.isUndefined(a)&&this._name!==(a=String(a)))this._updateSource(a,this._positions.name,this._positions.name+this._name.length),this._name=a;return this._name},nameRange:function(a){return c(this._positions.name+(a?this.options.offset:0),this.name())},range:function(a){return c(a?this.options.offset:0,this.toString())},itemFromPosition:function(a,b){return d.find(this.list(),function(c){return c.range(b).inside(a)})},toString:function(){return this.source}};b.extend=f.extend;b.prototype= +{initialize:function(){},_pos:function(a,b){return a+(b?this.parent.options.offset:0)},value:function(a){if(!d.isUndefined(a)&&this._value!==(a=String(a)))this.parent._updateSource(a,this.valueRange()),this._value=a;return this._value},name:function(a){if(!d.isUndefined(a)&&this._name!==(a=String(a)))this.parent._updateSource(a,this.nameRange()),this._name=a;return this._name},namePosition:function(a){return this._pos(this._positions.name,a)},valuePosition:function(a){return this._pos(this._positions.value, +a)},range:function(a){return c(this.namePosition(a),this.toString())},fullRange:function(a){return this.range(a)},nameRange:function(a){return c(this.namePosition(a),this.name())},valueRange:function(a){return c(this.valuePosition(a),this.value())},toString:function(){return this.name()+this.value()},valueOf:function(){return this.toString()}};return{EditContainer:i,EditElement:b,createToken:function(a,b,c){a={start:a||0,value:b||"",type:c};a.end=a.start+a.value.length;return a}}}); +emmet.define("cssEditTree",function(h,d){function f(a,b){return h("range").create(a,b)}function i(a,b){var b=b||e|g,c=["white","line"];if((b&g)==g)for(;a.length&&d.include(c,d.last(a).type);)a.pop();if((b&e)==e)for(;a.length&&d.include(c,a[0].type);)a.shift();return a}function b(a){var b=["white","line",":"],c=[],h,j;a.nextUntil(function(){return!d.include(b,this.itemNext().type)});for(j=a.current().end;h=a.next();){if(h.type=="}"||h.type==";")return i(c,e|(h.type=="}"?g:0)),c.length?(j=c[0].start, +a=d.last(c).end):a=j,f(j,a-j);c.push(h)}if(c.length)return f(c[0].start,d.last(c).end-c[0].start)}function c(a){var b=h("stringStream").create(a),c=[],e=/[\s\u00a0,]/,g=function(){b.next();c.push(f(b.start,b.current()));b.start=b.pos};b.eatSpace();for(b.start=b.pos;a=b.next();)if(a=='"'||a=="'"){b.next();if(!b.skipTo(a))break;g()}else if(a=="("){b.backUp(1);if(!b.skipToPair("(",")"))break;b.backUp(1);g()}else if(e.test(a))c.push(f(b.start,b.current().length-1)),b.eatWhile(e),b.start=b.pos;g();return d.chain(c).filter(function(a){return!!a.length()}).uniq(!1, +function(a){return a.toString()}).value()}var a={styleBefore:"\n\t",styleSeparator:": ",offset:0},e=1,g=2,j=h("editTree").EditContainer.extend({initialize:function(c){d.defaults(this.options,a);var e=h("editTree"),g=h("tokenIterator").create(h("cssParser").parse(c)),j,s=[],r;for(j=g.position();r=g.next();){if(r.type=="{")break;s.push(r)}i(s);s.length?(j=s[0].start,s=d.last(s).end):s=j;j=f(j,s-j);this._positions.name=j.start;this._name=j.substring(c);if(!g.current()||g.current().type!="{")throw"Invalid CSS rule"; +for(this._positions.contentStart=g.position()+1;j=g.next();){if(s=j.type=="identifier")a:{s=g.tokens;r=g._i+1;for(var u=s.length;r1)e.styleBefore="\n"+d.last(g);e.styleSeparator=b.substring(e.nameRange().end,e.valuePosition());e.styleBefore=d.last(e.styleBefore.split("*/"));e.styleSeparator=e.styleSeparator.replace(/\/\*.*?\*\//g,"");a=e.range().end})},add:function(a,b,c){var e=this.list(),g=this._positions.contentStart,f=d.pick(this.options,"styleBefore", +"styleSeparator"),j=h("editTree");if(d.isUndefined(c))c=e.length;var i=e[c];if(i)g=i.fullRange().start;else if(i=e[c-1])i.end(";"),g=i.range().end;i&&(f=d.pick(i,"styleBefore","styleSeparator"));a=j.createToken(g+f.styleBefore.length,a);b=j.createToken(a.end+f.styleSeparator.length,b);j=new l(this,a,b,j.createToken(b.end,";"));d.extend(j,f);this._updateSource(j.styleBefore+j.toString(),g);this._children.splice(c,0,j);return j}}),l=h("editTree").EditElement.extend({initialize:function(a,b,c,d){this.styleBefore= +a.options.styleBefore;this.styleSeparator=a.options.styleSeparator;this._end=d.value;this._positions.end=d.start},valueParts:function(a){var b=c(this.value());if(a){var e=this.valuePosition(!0);d.each(b,function(a){a.shift(e)})}return b},end:function(a){if(!d.isUndefined(a)&&this._end!==a)this.parent._updateSource(a,this._positions.end,this._positions.end+this._end.length),this._end=a;return this._end},fullRange:function(a){a=this.range(a);a.start-=this.styleBefore.length;return a},toString:function(){return this.name()+ +this.styleSeparator+this.value()+this.end()}});return{parse:function(a,b){return new j(a,b)},parseFromPosition:function(a,b,c){c=this.extractRule(a,b,c);return!c||!c.inside(b)?null:this.parse(c.substring(a),{offset:c.start})},extractRule:function(a,b,c){for(var d="",e=a.length,g=-1,f;b>=0;){f=a.charAt(b);if(f=="{"){g=b;break}else if(f=="}"&&!c){b++;break}b--}for(;b=0;){f=a.charAt(b);if("{}/\\<>\n\r".indexOf(f)!= +-1)break;b--}c=a.substring(b+1,g).replace(/^[\s\n\r]+/m,"");return h("range").create(g-c.length,d.length+c.length)}return null},baseName:function(a){return a.replace(/^\s*\-\w+\-/,"")},findParts:c}}); +emmet.define("xmlEditTree",function(h,d){var f={styleBefore:" ",styleSeparator:"=",styleQuote:'"',offset:0},i=/^<([\w\:\-]+)((?:\s+[\w\-:]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/m,b=h("editTree").EditContainer.extend({initialize:function(a){d.defaults(this.options,f);this._positions.name=1;var b=null,g=h("xmlParser").parse(a),j=h("range");d.each(g,function(d){d.value=j.create(d).substring(a);switch(d.type){case "tag":if(/^<[^\/]+/.test(d.value))this._name=d.value.substring(1); +break;case "attribute":b&&this._children.push(new c(this,b));b=d;break;case "string":this._children.push(new c(this,b,d)),b=null}},this);b&&this._children.push(new c(this,b));this._saveStyle()},_saveStyle:function(){var a=this.nameRange().end,b=this.source;d.each(this.list(),function(c){c.styleBefore=b.substring(a,c.namePosition());if(c.valuePosition()!==-1)c.styleSeparator=b.substring(c.namePosition()+c.name().length,c.valuePosition()-c.styleQuote.length);a=c.range().end})},add:function(a,b,g){var f= +this.list(),i=this.nameRange().end,m=h("editTree"),n=d.pick(this.options,"styleBefore","styleSeparator","styleQuote");if(d.isUndefined(g))g=f.length;var o=f[g];if(o)i=o.fullRange().start;else if(o=f[g-1])i=o.range().end;o&&(n=d.pick(o,"styleBefore","styleSeparator","styleQuote"));b=n.styleQuote+b+n.styleQuote;a=new c(this,m.createToken(i+n.styleBefore.length,a),m.createToken(i+n.styleBefore.length+a.length+n.styleSeparator.length,b));d.extend(a,n);this._updateSource(a.styleBefore+a.toString(),i); +this._children.splice(g,0,a);return a}}),c=h("editTree").EditElement.extend({initialize:function(a,b,c){this.styleBefore=a.options.styleBefore;this.styleSeparator=a.options.styleSeparator;b="";a=a.options.styleQuote;if(c)b=c.value,a=b.charAt(0),a=='"'||a=="'"?b=b.substring(1):a="",a&&b.charAt(b.length-1)==a&&(b=b.substring(0,b.length-1));this.styleQuote=a;this._value=b;this._positions.value=c?c.start+a.length:-1},fullRange:function(a){a=this.range(a);a.start-=this.styleBefore.length;return a},toString:function(){return this.name()+ +this.styleSeparator+this.styleQuote+this.value()+this.styleQuote}});return{parse:function(a,c){return new b(a,c)},parseFromPosition:function(a,b,c){c=this.extractTag(a,b,c);return!c||!c.inside(b)?null:this.parse(c.substring(a),{offset:c.start})},extractTag:function(a,b,c){var d=a.length,f,m=h("range"),n=Math.min(2E3,d),o=null,q=function(b){var c;if(a.charAt(b)=="<"&&(c=a.substr(b,n).match(i)))return m.create(b,c[0])};for(f=b;f>=0;f--)if(o=q(f))break;if(o&&(o.inside(b)||c))return o;if(!o&&c)return null; +for(f=b;f=a++;)if(b.substr(a,g.length)==g){i=a+g.length;break}}return f!=-1&&i!=-1?h("range").create(f,i-f):null}function b(b,a,d,g){function f(b){return b.replace(RegExp("^"+q.escapeForRegexp(a)+"\\s*"), +function(a){n-=a.length;return""}).replace(RegExp("\\s*"+q.escapeForRegexp(d)+"$"),"")}var l=h("editorUtils"),m=l.outputInfo(b).content,n=b.getCaretPos(),o=null,q=h("utils");(o=i(m,n,a,d))&&o.overlap(g)?(g=o,o=f(g.substring(m))):(o=a+" "+g.substring(m).replace(RegExp(q.escapeForRegexp(a)+"\\s*|\\s*"+q.escapeForRegexp(d),"g"),"")+" "+d,n+=a.length+1);return o!==null?(o=q.escapeText(o),b.setCaretPos(g.start),b.replaceContent(l.unindent(b,o),g.start,g.end),b.setCaretPos(n),!0):!1}h("actions").add("toggle_comment", +function(c){var a=h("editorUtils").outputInfo(c);if(a.syntax=="css"){var d=c.getCaretPos(),g=h("htmlMatcher").tag(a.content,d);if(g&&g.open.range.inside(d))a.syntax="html"}if(a.syntax=="css"){g=h("range").create(c.getSelectionRange());a=h("editorUtils").outputInfo(c);if(!g.length()&&(d=h("cssEditTree").parseFromPosition(a.content,c.getCaretPos())))g=(g=f(d,c.getCaretPos()))?g.range(!0):h("range").create(d.nameRange(!0).start,d.source);g.length()||(g=h("range").create(c.getCurrentLineRange()),h("utils").narrowToNonSpace(a.content, +g));c=b(c,"/*","*/",g)}else{a=h("range").create(c.getSelectionRange());d=h("editorUtils").outputInfo(c);if(!a.length()&&(d=h("htmlMatcher").tag(d.content,c.getCaretPos())))a=d.outerRange;c=b(c,"<\!--","--\>",a)}return c})}); +emmet.exec(function(h){function d(d,h,b){function c(b){for(var c=b;c>=0;){var d=a.charAt(c);if(d=="\n"||d=="\r")break;c--}return a.substring(c,b)}for(var h=h||1,b=d.getCaretPos()+(b||0),a=String(d.getContent()),d=a.length,e=-1,g=/^\s+$/;b<=d&&b>=0;){b+=h;var j=a.charAt(b),l=a.charAt(b+1),m=a.charAt(b-1);switch(j){case '"':case "'":l==j&&m=="="&&(e=b+1);break;case ">":l=="<"&&(e=b+1);break;case "\n":case "\r":g.test(c(b-1))&&(e=b)}if(e!=-1)break}return e}h=h("actions");h.add("prev_edit_point",function(f){var h= +f.getCaretPos(),b=d(f,-1);b==h&&(b=d(f,-1,-2));return b!=-1?(f.setCaretPos(b),!0):!1},{label:"Previous Edit Point"});h.add("next_edit_point",function(f){var h=d(f,1);return h!=-1?(f.setCaretPos(h),!0):!1})}); +emmet.exec(function(h,d){function f(a,b,c,d){var e=h("range"),g=h("editorUtils").outputInfo(a).content,f=g.length,j,i=e.create(-1,0),l=e.create(a.getSelectionRange());j=l.start;for(var o=1E5;j>=0&&j0;){if(e=c(g,j,b)){if(i.equal(e))break;i=e.clone();if(j=d(e.substring(g),e.start,l.clone()))return a.createSelection(j.start,j.end),!0;else j=b?e.start:e.end-1}j+=b?-1:1}return!1}function i(a){var b=!0;return f(a,!1,function(a,c){if(b){b=!1;var d;a:{d=c;for(var e;d>=0;){if(e=g(a,d)){d=e;break a}d--}d= +null}return d}else return g(a,c)},function(a,b,c){return e(a,b,c,!1)})}function b(a){return f(a,!0,g,function(a,b,c){return e(a,b,c,!0)})}function c(b,c,e){var e=e||0,g=h("range"),f=[],i=-1,l="",z="",x,o;d.each(c,function(c){switch(c.type){case "tag":o=b.substring(c.start,c.end);/^<[\w\:\-]/.test(o)&&f.push(g.create({start:c.start+1,end:c.end}));break;case "attribute":i=c.start;l=b.substring(c.start,c.end);break;case "string":f.push(g.create(i,c.end-i)),x=g.create(c),z=x.substring(b),j(z.charAt(0))&& +x.start++,j(z.charAt(z.length-1))&&x.end--,f.push(x),l=="class"&&(f=f.concat(a(x.substring(b),x.start)))}});d.each(f,function(a){a.shift(e)});return d.chain(f).filter(function(a){return!!a.length()}).uniq(!1,function(a){return a.toString()}).value()}function a(a,b){var b=b||0,c=[],d=h("stringStream").create(a),e=h("range");d.eatSpace();d.start=d.pos;for(var g;g=d.next();)if(/[\s\u00a0]/.test(g))c.push(e.create(d.start+b,d.pos-d.start-1)),d.eatSpace(),d.start=d.pos;c.push(e.create(d.start+b,d.pos- +d.start));return c}function e(a,b,e,g){a=c(a,h("xmlParser").parse(a),b);g&&a.reverse();return(b=d.find(a,function(a){return a.equal(e)}))?(g=d.indexOf(a,b),g1)?g[1]:d.find(a,function(a){return a.end>e.end})}function g(a,b){var c;if(a.charAt(b)=="<"&&(c=a.substring(b,a.length).match(q)))return h("range").create(b,c[0])}function j(a){return a=='"'||a=="'"}function l(a){var b= +a.valueRange(!0),c=[a.range(!0),b],e=h("stringStream"),g=h("cssEditTree"),f=h("range"),j=a.value();d.each(a.valueParts(),function(a){var h=a.clone();c.push(h.shift(b.start));var i=e.create(a.substring(j));if(i.match(/^[\w\-]+\(/,!0)){i.start=i.pos;i.skipToPair("(",")");var l=i.current();c.push(f.create(h.start+i.start,l));d.each(g.findParts(l),function(a){c.push(f.create(h.start+i.start+a.start,a.substring(l)))})}});return d.chain(c).filter(function(a){return!!a.length()}).uniq(!1,function(a){return a.toString()}).value()} +function m(a,b,c){var e=null,g=null,f=a.list(),h,j;c?(f.reverse(),h=function(a){return a.range(!0).start<=b.start},j=function(a){return a.start=b.end},j=function(a){return a.end>b.start});for(;e=d.find(f,h);){a=l(e);c&&a.reverse();if(g=d.find(a,function(a){return a.equal(b)})){if(g=d.indexOf(a,g),g!=a.length-1){g=a[g+1];break}}else{g=d.filter(a,function(a){return a.inside(b.end)});if(g.length>1){g=g[1];break}if(g=d.find(a,j))break}g=null;b.start=b.end= +c?e.range(!0).start-1:e.range(!0).end+1}return g}function n(a,b,c){a=h("cssEditTree").parse(a,{offset:b});b=a.nameRange(!0);return c.endb.start)?b:a}var q=/^<([\w\:\-]+)((?:\s+[\w\-:]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/,s=h("actions");s.add("select_next_item",function(a){return a.getSyntax()=="css"?f(a,!1,h("cssEditTree").extractRule,n):i(a)});s.add("select_previous_item", +function(a){return a.getSyntax()=="css"?f(a,!0,h("cssEditTree").extractRule,o):b(a)})}); +emmet.exec(function(h){function d(c,a){var a=String((a||"out").toLowerCase()),d=h("editorUtils").outputInfo(c),g=h("range").create(c.getSelectionRange()),d=d.content;b&&!b.range.equal(g)&&(b=null);if(b&&g.length())if(a=="in")if(b.type=="tag"&&!b.close)return!1;else if(b.range.equal(b.outerRange))b.range=b.innerRange;else{var f=h("utils").narrowToNonSpace(d,b.innerRange);if((b=i.find(d,f.start+1))&&b.range.equal(g)&&b.outerRange.equal(g))b.range=b.innerRange}else if(!b.innerRange.equal(b.outerRange)&& +b.range.equal(b.innerRange)&&g.equal(b.range))b.range=b.outerRange;else{if((b=i.find(d,g.start))&&b.range.equal(g)&&b.innerRange.equal(g))b.range=b.outerRange}else b=i.find(d,g.start);if(b&&!b.range.equal(g))return c.createSelection(b.range.start,b.range.end),!0;b=null;return!1}var f=h("actions"),i=h("htmlMatcher"),b=null;f.add("match_pair",d,{hidden:!0});f.add("match_pair_inward",function(b){return d(b,"in")},{label:"HTML/Match Pair Tag (inward)"});f.add("match_pair_outward",function(b){return d(b, +"out")},{label:"HTML/Match Pair Tag (outward)"});f.add("matching_pair",function(b){var a=String(b.getContent()),d=b.getCaretPos();a.charAt(d)=="<"&&d++;return(a=i.tag(a,d))&&a.close?(a.open.range.inside(d)?b.setCaretPos(a.close.range.start):b.setCaretPos(a.open.range.start),!0):!1},{label:"HTML/Go To Matching Tag Pair"})}); +emmet.exec(function(h){h("actions").add("remove_tag",function(d){var f=h("utils"),i=h("editorUtils").outputInfo(d),b=h("htmlMatcher").tag(i.content,d.getCaretPos());if(b){if(b.close){var c=f.narrowToNonSpace(i.content,b.innerRange),a=f.findNewlineBounds(i.content,c.start),a=f.getLinePadding(a.substring(i.content)),i=c.substring(i.content),i=f.unindentString(i,a);d.replaceContent(f.getCaretPlaceholder()+f.escapeText(i),b.outerRange.start,b.outerRange.end)}else d.replaceContent(f.getCaretPlaceholder(), +b.range.start,b.range.end);return!0}return!1},{label:"HTML/Remove Tag"})}); +emmet.exec(function(h){h("actions").add("split_join_tag",function(d,f){var i=h("htmlMatcher"),b=h("editorUtils").outputInfo(d,null,f),c=h("profile").get(b.profile);if(i=i.tag(b.content,d.getCaretPos())){if(i.close){var b=h("utils"),c=c.selfClosing()||" /",c=i.open.range.substring(i.source).replace(/\s*>$/,c+">"),a=d.getCaretPos();c.length+i.outerRange.start$/,">"),a=i.outerRange.start+e.length;e+=c+"";e=b.escapeText(e);d.replaceContent(e,i.outerRange.start,i.outerRange.end)}d.setCaretPos(a);i=!0}else i=!1;return i},{label:"HTML/Split\\Join Tag Declaration"})}); +emmet.define("reflectCSSValue",function(h,d){function f(c){var a=h("cssEditTree"),d=h("editorUtils").outputInfo(c),c=c.getCaretPos();if(a=a.parseFromPosition(d.content,c))if(d=a.itemFromPosition(c,!0)){var g=a.source,f=a.options.offset,c=c-f-d.range().start;b.exec(!1,[d]);if(g!==a.source)return{data:a.source,start:f,end:f+g.length,caret:f+d.range().start+c}}}function i(b){var b=h("cssEditTree").baseName(b),a;if(b=="opacity"||b=="filter")return/^(?:\-\w+\-)?(?:opacity|filter)$/;else if(a=b.match(/^border-radius-(top|bottom)(left|right)/))return RegExp("^(?:\\-\\w+\\-)?(?:"+ +b+"|border-"+a[1]+"-"+a[2]+"-radius)$");else if(a=b.match(/^border-(top|bottom)-(left|right)-radius/))return RegExp("^(?:\\-\\w+\\-)?(?:"+b+"|border-radius-"+a[1]+a[2]+")$");return RegExp("^(?:\\-\\w+\\-)?"+b+"$")}var b=h("handlerList").create();h("actions").add("reflect_css_value",function(b){return b.getSyntax()!="css"?!1:h("actionUtils").compoundUpdate(b,f(b))},{label:"CSS/Reflect Value"});b.add(function(b){var a=i(b.name());d.each(b.parent.list(),function(d){if(a.test(d.name())){var g;var f=b.name(), +i=b.value(),m=d.name();g=d.value();var n=h("cssEditTree"),o=h("utils"),f=n.baseName(f),m=n.baseName(m);g=f=="opacity"&&m=="filter"?g.replace(/opacity=[^)]*/i,"opacity="+Math.floor(parseFloat(i)*100)):f=="filter"&&m=="opacity"?(f=i.match(/opacity=([^)]*)/i))?o.prettifyNumber(parseInt(f[1])/100):g:i;d.value(g)}})},{order:-1});return{addHandler:function(c,a){b.add(c,a)},removeHandler:function(c){b.remove(c,options)}}}); +emmet.exec(function(h){h("actions").add("evaluate_math_expression",function(d){var f=h("actionUtils"),i=h("utils"),b=String(d.getContent()),c=h("range").create(d.getSelectionRange());c.length()||(c=f.findExpressionBounds(d,function(a){return i.isNumeric(a)||".+-*/\\".indexOf(a)!=-1}));if(c&&c.length()){f=c.substring(b);f=f.replace(/([\d\.\-]+)\\([\d\.\-]+)/g,"Math.round($1/$2)");try{var a=i.prettifyNumber((new Function("return "+f))());d.replaceContent(a,c.start,c.end);d.setCaretPos(c.start+a.length); +return!0}catch(e){}}return!1},{label:"Numbers/Evaluate Math Expression"})}); +emmet.exec(function(h,d){function f(b,a){var e=h("utils"),g=!1,f=!1,l=h("actionUtils").findExpressionBounds(b,function(a,b,c){return e.isNumeric(a)?!0:a=="."?!e.isNumeric(c.charAt(b+1))?!1:f?!1:f=!0:a=="-"?g?!1:g=!0:!1});if(l&&l.length()){var m=l.substring(String(b.getContent())),n=parseFloat(m);if(!d.isNaN(n)){n=e.prettifyNumber(n+a);if(/^(\-?)0+[1-9]/.test(m)){var o="";RegExp.$1&&(o="-",n=n.substring(1));n=n.split(".");n[0]=e.zeroPadString(n[0],i(m));n=o+n.join(".")}b.replaceContent(n,l.start,l.end); +b.createSelection(l.start,l.start+n.length);return!0}}return!1}function i(b){b=b.replace(/^\-/,"");return~b.indexOf(".")?b.split(".")[0].length:b.length}var b=h("actions");d.each([1,-1,10,-10,0.1,-0.1],function(c){var a=c>0?"increment":"decrement";b.add(a+"_number_by_"+String(Math.abs(c)).replace(".","").substring(0,2),function(a){return f(a,c)},{label:"Numbers/"+a.charAt(0).toUpperCase()+a.substring(1)+" number by "+Math.abs(c)})})}); +emmet.exec(function(h,d){var f=h("actions"),i=h("preferences");i.define("css.closeBraceIndentation","\n","Indentation before closing brace of CSS rule. Some users prefere indented closing brace of CSS rule for better readability. This preference\u2019s value will be automatically inserted before closing brace when user adds newline in newly created CSS rule (e.g. when \u201cInsert formatted linebreak\u201d action will be performed in CSS file). If you\u2019re such user, you may want to write put a value like \\n\\t in this preference."); +f.add("insert_formatted_line_break_only",function(b){var c=h("utils"),a=h("resources"),e=h("editorUtils").outputInfo(b),g=b.getCaretPos(),f=c.getNewline();if(d.include(["html","xml","xsl"],e.syntax)){if(a=a.getVariable("indentation"),(e=h("htmlMatcher").tag(e.content,g))&&!e.innerRange.length())return b.replaceContent(f+a+c.getCaretPlaceholder()+f,g),!0}else if(e.syntax=="css"&&(e=e.content,g&&e.charAt(g-1)=="{")){var l=i.get("css.closeBraceIndentation"),a=a.getVariable("indentation"),m=e.charAt(g)== +"}";if(!m)for(var n=g,o=e.length,q;na.length?b.replaceContent(c+l,g,g,!0):b.replaceContent(c,g)}return!0},{hidden:!0})}); +emmet.exec(function(h){h("actions").add("merge_lines",function(d){var f=h("htmlMatcher"),i=h("utils"),b=h("editorUtils").outputInfo(d),c=h("range").create(d.getSelectionRange());if(!c.length()&&(f=f.find(b.content,d.getCaretPos())))c=f.outerRange;if(c.length()){b=c.substring(b.content);b=i.splitByLines(b);for(f=1;f=0;)if(d("src=",c,b)){if(c=c.substr(b).match(/^(src=(["'])?)([^'"<>\s]+)\1?/))i=c[3],b+=c[1].length;break}else if(d("url(",c,b)){if(c=c.substr(b).match(/^(url\((['"])?)([^'"\)\s]+)\1?/))i=c[3],b+=c[1].length;break}if(i)if(d("data:",i))if(c=String(f.prompt("Enter path to file (absolute or relative)"))){var a= +h("file"),e=a.createPath(f.getFilePath(),c);if(!e)throw"Can't save file";a.save(e,h("base64").decode(i.replace(/^data\:.+?;.+?,/,"")));f.replaceContent("$0"+c,b,b+i.length);f=!0}else f=!1;else{c=h("file");a=h("actionUtils");e=f.getFilePath();if(e===null)throw"You should save your file before using this action";e=c.locateFile(e,i);if(e===null)throw"Can't find "+i+" file";var g=h("base64").encode(String(c.read(e)));if(!g)throw"Can't encode file content to base64";g="data:"+(a.mimeTypes[String(c.getExt(e))]|| +"application/octet-stream")+";base64,"+g;f.replaceContent("$0"+g,b,b+i.length);f=!0}else f=!1;return f},{label:"Encode\\Decode data:URL image"})}); +emmet.exec(function(h,d){function f(d,b){var c;if(b){if(/^data:/.test(b))c=h("base64").decode(b.replace(/^data\:.+?;.+?,/,""));else{c=h("file");var a=c.locateFile(d.getFilePath(),b);if(a===null)throw"Can't find "+b+" file";c=String(c.read(a))}return h("actionUtils").getImageSize(c)}}h("actions").add("update_image_size",function(i){var b;if(String(i.getSyntax())=="css")a:{b=i.getCaretPos();var c=h("editorUtils").outputInfo(i);if(c=h("cssEditTree").parseFromPosition(c.content,b,!0)){var a=c.itemFromPosition(b, +!0),e;if(a&&(e=/url\((["']?)(.+?)\1\)/i.exec(a.value()||"")))if(e=f(i,e[2])){a=c.range(!0);c.value("width",e.width+"px");c.value("height",e.height+"px",c.indexOf("width")+1);b=d.extend(a,{data:c.toString(),caret:b});break a}}b=null}else a:{b=i.getCaretPos();c=h("editorUtils").outputInfo(i);if((c=h("xmlEditTree").parseFromPosition(c.content,b,!0))&&(c.name()||"").toLowerCase()=="img")if(e=f(i,c.value("src"))){a=c.range(!0);c.value("width",e.width);c.value("height",e.height,c.indexOf("width")+1);b= +d.extend(a,{data:c.toString(),caret:b});break a}b=null}return h("actionUtils").compoundUpdate(i,b)})}); +emmet.define("cssResolver",function(h,d){function f(a){var b=a&&a.charCodeAt(0);return a&&a=="."||b>47&&b<58}function i(a){a=h("utils").trim(a);if(~a.indexOf("/*")||/[\n\r]/.test(a))return!1;if(!/^[a-z0-9\-]+\s*\:/i.test(a))return!1;a=h("tabStops").processText(a,{replaceCarets:!0,tabstop:function(){return"value"}});return a.split(":").length==2}function b(a){a.charAt(0);if(a.charAt(0)=="#"){var b=a.replace(/^#+/,"")||"0",d=h("utils").repeatString,a=null;switch(b.length){case 1:a=d(b,6);break;case 2:a= +d(b,3);break;case 3:a=b.charAt(0)+b.charAt(0)+b.charAt(1)+b.charAt(1)+b.charAt(2)+b.charAt(2);break;case 4:a=b+b.substr(0,2);break;case 5:a=b+b.charAt(0);break;default:a=b.substr(0,6)}p.get("css.color.short")&&(b=a.split(""),b[0]==b[1]&&b[2]==b[3]&&b[4]==b[5]&&(a=b[0]+b[2]+b[4]));switch(p.get("css.color.case")){case "upper":a=a.toUpperCase();break;case "lower":a=a.toLowerCase()}a="#"+a}else a=c(a);return a}function c(a){var b=p.getDict("css.keywordAliases");return a in b?b[a]:a}function a(a){return d.include(p.getArray("css.keywords"), +c(a))}function e(a){var b=h("utils"),a=b.trim(a);if(a.indexOf(":")==-1)return{name:a,value:u};a=a.split(":");return{name:b.trim(a.shift()),value:b.trim(a.join(":")).replace(/^(\$\{0\}|\$0)(\s*;?)$/,"${1}$2")}}function g(a,b){var c=r[b];c||(c=d.find(r,function(a){return a.prefix==b}));return c&&c.supports(a)}function j(a,b){var c=[];d.each(r,function(b,d){g(a,d)&&c.push(d)});!c.length&&!b&&d.each(r,function(a,b){a.obsolete||c.push(b)});return c}function l(a,b){d.isString(b)&&(b={prefix:b});r[a]=d.extend({}, +s,b)}function m(a,b){if(b){var c=p.get(b+"."+a);if(!d.isUndefined(c))return c}return p.get("css."+a)}function n(a,b,c){if(!d.isString(a))a=a.data;if(!i(a))return a;b&&(~a.indexOf(";")?a=a.split(";").join(" !important;"):a+=" !important");b=a.indexOf(":");a=a.substring(0,b).replace(/\s+$/,"")+m("valueSeparator",c)+h("utils").trim(a.substring(b+1));return a.replace(/\s*;\s*$/,m("propertyEnd",c))}function o(a){var b=p.getArray(a);d.each(p.getArray(a+"Addon"),function(a){a.charAt(0)=="-"?b=d.without(b, +a.substr(1)):(a.charAt(0)=="+"&&(a=a.substr(1)),b.push(a))});return b}var q=null,s={prefix:"emmet",obsolete:!1,transformName:function(a){return"-"+this.prefix+"-"+a},properties:function(){return o("css."+this.prefix+"Properties")||[]},supports:function(a){return d.include(this.properties(),a)}},r={},u="${1};",p=h("preferences");p.define("css.valueSeparator",": ","Defines a symbol that should be placed between CSS property and value when expanding CSS abbreviations.");p.define("css.propertyEnd",";", +"Defines a symbol that should be placed at the end of CSS property when expanding CSS abbreviations.");p.define("stylus.valueSeparator"," ","Defines a symbol that should be placed between CSS property and value when expanding CSS abbreviations in Stylus dialect.");p.define("stylus.propertyEnd","","Defines a symbol that should be placed at the end of CSS property when expanding CSS abbreviations in Stylus dialect.");p.define("sass.propertyEnd","","Defines a symbol that should be placed at the end of CSS property when expanding CSS abbreviations in SASS dialect."); +p.define("css.autoInsertVendorPrefixes",!0,"Automatically generate vendor-prefixed copies of expanded CSS property. By default, Emmet will generate vendor-prefixed properties only when you put dash before abbreviation (e.g. -bxsh). With this option enabled, you don\u2019t need dashes before abbreviations: Emmet will produce vendor-prefixed properties for you.");var v=d.template("A comma-separated list of CSS properties that may have <%= vendor %> vendor prefix. This list is used to generate a list of prefixed properties when expanding -property abbreviations. Empty list means that all possible CSS values may have <%= vendor %> prefix."), +w=d.template("A comma-separated list of additional CSS properties for css.<%= vendor %>Preperties preference. You should use this list if you want to add or remove a few CSS properties to original set. To add a new property, simply write its name, to remove it, precede property with hyphen.
For example, to add foo property and remove border-radius one, the preference value will look like this: foo, -border-radius.");d.each({webkit:"animation, animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, appearance, backface-visibility, background-clip, background-composite, background-origin, background-size, border-fit, border-horizontal-spacing, border-image, border-vertical-spacing, box-align, box-direction, box-flex, box-flex-group, box-lines, box-ordinal-group, box-orient, box-pack, box-reflect, box-shadow, color-correction, column-break-after, column-break-before, column-break-inside, column-count, column-gap, column-rule-color, column-rule-style, column-rule-width, column-span, column-width, dashboard-region, font-smoothing, highlight, hyphenate-character, hyphenate-limit-after, hyphenate-limit-before, hyphens, line-box-contain, line-break, line-clamp, locale, margin-before-collapse, margin-after-collapse, marquee-direction, marquee-increment, marquee-repetition, marquee-style, mask-attachment, mask-box-image, mask-box-image-outset, mask-box-image-repeat, mask-box-image-slice, mask-box-image-source, mask-box-image-width, mask-clip, mask-composite, mask-image, mask-origin, mask-position, mask-repeat, mask-size, nbsp-mode, perspective, perspective-origin, rtl-ordering, text-combine, text-decorations-in-effect, text-emphasis-color, text-emphasis-position, text-emphasis-style, text-fill-color, text-orientation, text-security, text-stroke-color, text-stroke-width, transform, transition, transform-origin, transform-style, transition-delay, transition-duration, transition-property, transition-timing-function, user-drag, user-modify, user-select, writing-mode, svg-shadow, box-sizing, border-radius", +moz:"animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, appearance, backface-visibility, background-inline-policy, binding, border-bottom-colors, border-image, border-left-colors, border-right-colors, border-top-colors, box-align, box-direction, box-flex, box-ordinal-group, box-orient, box-pack, box-shadow, box-sizing, column-count, column-gap, column-rule-color, column-rule-style, column-rule-width, column-width, float-edge, font-feature-settings, font-language-override, force-broken-image-icon, hyphens, image-region, orient, outline-radius-bottomleft, outline-radius-bottomright, outline-radius-topleft, outline-radius-topright, perspective, perspective-origin, stack-sizing, tab-size, text-blink, text-decoration-color, text-decoration-line, text-decoration-style, text-size-adjust, transform, transform-origin, transform-style, transition, transition-delay, transition-duration, transition-property, transition-timing-function, user-focus, user-input, user-modify, user-select, window-shadow, background-clip, border-radius", +ms:"accelerator, backface-visibility, background-position-x, background-position-y, behavior, block-progression, box-align, box-direction, box-flex, box-line-progression, box-lines, box-ordinal-group, box-orient, box-pack, content-zoom-boundary, content-zoom-boundary-max, content-zoom-boundary-min, content-zoom-chaining, content-zoom-snap, content-zoom-snap-points, content-zoom-snap-type, content-zooming, filter, flow-from, flow-into, font-feature-settings, grid-column, grid-column-align, grid-column-span, grid-columns, grid-layer, grid-row, grid-row-align, grid-row-span, grid-rows, high-contrast-adjust, hyphenate-limit-chars, hyphenate-limit-lines, hyphenate-limit-zone, hyphens, ime-mode, interpolation-mode, layout-flow, layout-grid, layout-grid-char, layout-grid-line, layout-grid-mode, layout-grid-type, line-break, overflow-style, perspective, perspective-origin, perspective-origin-x, perspective-origin-y, scroll-boundary, scroll-boundary-bottom, scroll-boundary-left, scroll-boundary-right, scroll-boundary-top, scroll-chaining, scroll-rails, scroll-snap-points-x, scroll-snap-points-y, scroll-snap-type, scroll-snap-x, scroll-snap-y, scrollbar-arrow-color, scrollbar-base-color, scrollbar-darkshadow-color, scrollbar-face-color, scrollbar-highlight-color, scrollbar-shadow-color, scrollbar-track-color, text-align-last, text-autospace, text-justify, text-kashida-space, text-overflow, text-size-adjust, text-underline-position, touch-action, transform, transform-origin, transform-origin-x, transform-origin-y, transform-origin-z, transform-style, transition, transition-delay, transition-duration, transition-property, transition-timing-function, user-select, word-break, word-wrap, wrap-flow, wrap-margin, wrap-through, writing-mode", +o:"dashboard-region, animation, animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, border-image, link, link-source, object-fit, object-position, tab-size, table-baseline, transform, transform-origin, transition, transition-delay, transition-duration, transition-property, transition-timing-function, accesskey, input-format, input-required, marquee-dir, marquee-loop, marquee-speed, marquee-style"}, +function(a,b){p.define("css."+b+"Properties",a,v({vendor:b}));p.define("css."+b+"PropertiesAddon","",w({vendor:b}))});p.define("css.unitlessProperties","z-index, line-height, opacity, font-weight, zoom","The list of properties whose values \u200b\u200bmust not contain units.");p.define("css.intUnit","px","Default unit for integer values");p.define("css.floatUnit","em","Default unit for float values");p.define("css.keywords","auto, inherit","A comma-separated list of valid keywords that can be used in CSS abbreviations."); +p.define("css.keywordAliases","a:auto, i:inherit, s:solid, da:dashed, do:dotted","A comma-separated list of keyword aliases, used in CSS abbreviation. Each alias should be defined as alias:keyword_name.");p.define("css.unitAliases","e:em, p:%, x:ex, r:rem","A comma-separated list of unit aliases, used in CSS abbreviation. Each alias should be defined as alias:unit_value.");p.define("css.color.short",!0,"Should color values like #ffffff be shortened to #fff after abbreviation with color was expanded."); +p.define("css.color.case","keep","Letter case of color values generated by abbreviations with color (like c#0). Possible values are upper, lower and keep.");p.define("css.fuzzySearch",!0,"Enable fuzzy search among CSS snippet names. When enabled, every unknown snippet will be scored against available snippet names (not values or CSS properties!). The match with best score will be used to resolve snippet value. For example, with this preference enabled, the following abbreviations are equal: ov:h == ov-h == o-h == oh"); +p.define("css.fuzzySearchMinScore",0.3,"The minium score (from 0 to 1) that fuzzy-matched abbreviation should achive. Lower values may produce many false-positive matches, higher values may reduce possible matches.");l("w",{prefix:"webkit"});l("m",{prefix:"moz"});l("s",{prefix:"ms"});l("o",{prefix:"o"});var k=["css","less","sass","scss","stylus"];h("resources").addResolver(function(a,b){return d.include(k,b)&&a.isElement()?q.expandToSnippet(a.abbreviation,b):null});var t=h("expandAbbreviation");t.addHandler(function(a, +b,c){if(!d.include(k,b))return!1;var e=a.getSelectionRange().end,g=t.findAbbreviation(a);return g&&(b=emmet.expandAbbreviation(g,b,c))?(g=e-g.length,c=e,a.getContent().charAt(e)==";"&&b.charAt(b.length-1)==";"&&c++,a.replaceContent(b,g,c),!0):!1});return q={addPrefix:l,supportsPrefix:g,prefixed:function(a,b){return g(a,b)?"-"+b+"-"+a:a},listPrefixes:function(){return d.map(r,function(a){return a.prefix})},getPrefix:function(a){return r[a]},removePrefix:function(a){a in r&&delete r[a]},extractPrefixes:function(a){if(a.charAt(0)!= +"-")return{property:a,prefixes:null};for(var b=1,c=a.length,d,e=[];bbackground-color property with gradient first color as fallback for old browsers."); +h("expandAbbreviation").addHandler(function(a,b,c){var e=h("editorUtils").outputInfo(a,b,c);if(!d.include(s,e.syntax))return!1;var c=a.getCaretPos(),g=e.content,e=n(g,c);if(e.property){var f=l(e.property);if(f){var b=e.rule.options.offset||0,i=b+e.rule.toString().length;if(/[\n\r]/.test(e.property.value())){var o=e.property.valueRange(!0).start+f.valueRange.end,g=h("utils").replaceSubstring(g,";",o),c=n(g,c);c.property&&(f=l(c.property),e=c)}e.property.end(";");j(e.property,f.gradient,f.valueRange); +a.replaceContent(e.rule.toString(),b,i,!0);return!0}}return m(a,b)});h("reflectCSSValue").addHandler(function(a){var b=h("utils"),c=l(a);if(!c)return!1;var g=a.value(),f=function(a){return b.replaceSubstring(g,a,c.valueRange)};d.each(a.parent.getAll(e(a.name())),function(b){if(b!==a){var d=b.value().match(/^\s*(\-([a-z]+)\-)?linear\-gradient/);d?b.value(f(q.toString(c.gradient,d[2]||""))):b.value().match(/\s*\-webkit\-gradient/)&&b.value(f(q.oldWebkitLinearGradient(c.gradient)))}});return!0});return q= +{parse:function(a){var b=null;h("utils").trim(a).replace(/^([\w\-]+)\((.+?)\)$/,function(a,c,e){c=c.toLowerCase().replace(/^\-[a-z]+\-/,"");if(c=="linear-gradient"||c=="lg"){for(var a=o[0],e=h("stringStream").create(h("utils").trim(e)),c=[],g;g=e.next();)e.peek()==","?(c.push(e.current()),e.next(),e.eatSpace(),e.start=e.pos):g=="("&&e.skipTo(")");c.push(e.current());c=d.compact(d.map(c,f));if(c.length){if(r.test(c[0])||u.test(c[0]))a=c.shift();b={type:"linear",direction:a,colorStops:d.map(c,i)}}else b= +null;return""}return a});return b},oldWebkitLinearGradient:function(c){d.isString(c)&&(c=this.parse(c));if(!c)return null;var e=d.map(c.colorStops,d.clone);d.each(e,function(a){if("position"in a)if(~a.position.indexOf(".")||a.unit=="%")a.position=parseFloat(a.position)/(a.unit=="%"?100:1);else throw"Can't convert color stop '"+(a.position+(a.unit||""))+"'";});b(e);e=d.map(e,function(a,b){return!a.position&&!b?"from("+a.color+")":a.position==1&&b==e.length-1?"to("+a.color+")":"color-stop("+a.position.toFixed(2).replace(/\.?0+$/, +"")+", "+a.color+")"});return"-webkit-gradient(linear, "+a(c.direction)+", "+e.join(", ")+")"},toString:function(a,b){if(a.type=="linear"){var c=(b?"-"+b+"-":"")+"linear-gradient",e=d.map(a.colorStops,function(a){return a.color+("position"in a?" "+a.position+(a.unit||""):"")});a.direction&&(!p.get("css.gradient.omitDefaultDirection")||!d.include(o,a.direction))&&e.unshift(a.direction);return c+"("+e.join(", ")+")"}}}}); +emmet.exec(function(h,d){var f=h("handlerList").create(),i=h("resources");d.extend(i,{addGenerator:function(b,c,a){d.isString(b)&&(b=RegExp(b));f.add(function(a,d){var f;return(f=b.exec(a.name()))?c(f,a,d):null},a)}});i.addResolver(function(b,c){return f.exec(null,d.toArray(arguments))})}); +emmet.define("tagName",function(h,d){var f={empty:"area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,keygen,command".split(","),blockLevel:"address,applet,blockquote,button,center,dd,del,dir,div,dl,dt,fieldset,form,frameset,hr,iframe,ins,isindex,li,link,map,menu,noframes,noscript,object,ol,p,pre,script,table,tbody,td,tfoot,th,thead,tr,ul,h1,h2,h3,h4,h5,h6".split(","),inlineLevel:"a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var".split(",")}, +i={p:"span",ul:"li",ol:"li",table:"tr",tr:"td",tbody:"tr",thead:"tr",tfoot:"tr",colgroup:"col",select:"option",optgroup:"option",audio:"source",video:"source",object:"param",map:"area"};return{resolve:function(b){b=(b||"").toLowerCase();return b in i?this.getMapping(b):this.isInlineLevel(b)?"span":"div"},getMapping:function(b){return i[b.toLowerCase()]},isInlineLevel:function(b){return this.isTypeOf(b,"inlineLevel")},isBlockLevel:function(b){return this.isTypeOf(b,"blockLevel")},isEmptyElement:function(b){return this.isTypeOf(b, +"empty")},isTypeOf:function(b,c){return d.include(f[c],b)},addMapping:function(b,c){i[b]=c},removeMapping:function(b){b in i&&delete i[b]},addElementToCollection:function(b,c){f[c]||(f[c]=[]);var a=this.getCollection(c);d.include(a,b)||a.push(b)},removeElementFromCollection:function(b,c){c in f&&(f[c]=d.without(this.getCollection(c),b))},getCollection:function(b){return f[b]}}}); +emmet.exec(function(h,d){function f(){return{element:e.get("bem.elementSeparator"),modifier:e.get("bem.modifierSeparator")}}function i(a){if(h("abbreviationUtils").isSnippet(a))return a;a.__bem={block:"",element:"",modifier:""};var e=b(a.attribute("class")).split(" "),g=/^[a-z]\-/i;a.__bem.block=d.find(e,function(a){return g.test(a)});if(!a.__bem.block)g=/^[a-z]/i,a.__bem.block=d.find(e,function(a){return g.test(a)})||"";(e=d.chain(e).map(function(b){var d;d=c(b,a,"element");d=c(d,a,"modifier");var e= +"",g="",h="",b=f();~d.indexOf(b.element)?(e=d.split(b.element),h=e[1].split(b.modifier),e=e[0],g=h.shift(),h=h.join(b.modifier)):~d.indexOf(b.modifier)&&(h=d.split(b.modifier),e=h.shift(),h=h.join(b.modifier));if(e||g||h){if(!e)e=a.__bem.block;d=e;var i=[];g&&(d+=b.element+g);i.push(d);h&&i.push(d+b.modifier+h);a.__bem.block=e;a.__bem.element=g;a.__bem.modifier=h;b=i}else b=d;return b}).flatten().uniq().value().join(" "))&&a.attribute("class",e);return a}function b(a){var b=h("utils"),a=(" "+(a|| +"")+" ").replace(/\s+/g," "),c=e.get("bem.shortElementPrefix");c&&(c=RegExp("\\s("+b.escapeForRegexp(c)+"+)","g"),a=a.replace(c,function(a,c){return" "+b.repeatString(f().element,c.length)}));return b.trim(a)}function c(a,b,c){var d=f(),e=RegExp("^("+d[c]+")+","g");if(e.test(a)){for(var g=0,e=a.replace(e,function(a){g=a.length/d[c].length;return""}),h=b;h.parent&&g--;)h=h.parent;if(!h||!h.__bem)h=b;if(h&&h.__bem)return a=h.__bem.block,c=="modifier"&&h.__bem.element&&(a+=d.element+h.__bem.element), +a+d[c]+e}return a}function a(b,c){b.name&&i(b,c);var e=h("abbreviationUtils");d.each(b.children,function(b){a(b,c);!e.isSnippet(b)&&b.start&&(g=!0)});return b}var e=h("preferences");e.define("bem.elementSeparator","__","Class name\u2019s element separator.");e.define("bem.modifierSeparator","_","Class name\u2019s modifier separator.");e.define("bem.shortElementPrefix","-","Symbol for describing short \u201cblock-element\u201d notation. Class names prefixed with this symbol will be treated as element name for parent\u2018s block name. Each symbol instance traverses one level up in parsed tree for block name lookup. Empty value will disable short notation."); +var g=!1;h("filters").add("bem",function(b,c){g=!1;b=a(b,c);g&&(b=h("filters").apply(b,"html",c));return b})}); +emmet.exec(function(h,d){function f(c,a,e){var g=h("utils"),f=b.get("filter.commentTrigger");if(f=="*"||d.find(f.split(","),function(a){return!!c.attribute(g.trim(a))}))f={node:c,name:c.name(),padding:c.parent?c.parent.padding:"",attr:function(a,b,d){return(a=c.attribute(a))?(b||"")+a+(d||""):""}},a=g.normalizeNewline(a?a(f):""),e=g.normalizeNewline(e?e(f):""),c.start=c.start.replace(//,">"+e)}function i(b,a,e){var g=h("abbreviationUtils");d.each(b.children,function(b){g.isBlock(b)&& +f(b,a,e);i(b,a,e)});return b}var b=h("preferences");b.define("filter.commentAfter",'\n<\!-- /<%= attr("id", "#") %><%= attr("class", ".") %> --\>',"A definition of comment that should be placed after matched element when comment filter is applied. This definition is an ERB-style template passed to _.template() function (see Underscore.js docs for details). In template context, the following properties and functions are availabe:\n
  • attr(name, before, after) \u2013 a function that outputsspecified attribute value concatenated with before and after strings. If attribute doesn't exists, the empty string will be returned.
  • node \u2013 current node (instance of AbbreviationNode)
  • name \u2013 name of current tag
  • padding \u2013 current string padding, can be used for formatting
"); +b.define("filter.commentBefore","","A definition of comment that should be placed before matched element when comment filter is applied. For more info, read description of filter.commentAfter property");b.define("filter.commentTrigger","id, class","A comma-separated list of attribute names that should exist in abbreviatoin where comment should be added. If you wish to add comment for every element, set this option to *");h("filters").add("c",function(c){var a= +d.template(b.get("filter.commentBefore")),e=d.template(b.get("filter.commentAfter"));return i(c,a,e)})});emmet.exec(function(h,d){function f(b){return b.replace(/([<>&])/g,function(b,a){return i[a]})}var i={"<":"<",">":">","&":"&"};h("filters").add("e",function c(a){d.each(a.children,function(a){a.start=f(a.start);a.end=f(a.end);a.content=f(a.content);c(a)});return a})}); +emmet.exec(function(h,d){function f(){return h("resources").getVariable("indentation")}function i(a){return a.parent&&!a.parent.parent&&!a.index()}function b(a,b){var d=h("abbreviationUtils");return b.tag_nl===!0||d.isBlock(a)?!0:!a.parent||!b.inline_break?!1:c(a.parent,b)}function c(a,b){var c=0,f=h("abbreviationUtils");return!!d.find(a.children,function(a){a.isTextNode()||!f.isInline(a)?c=0:f.isInline(a)&&c++;if(c>=b.inline_break)return!0})}function a(a,b){var f=h("abbreviationUtils");return!d.any(a.children, +function(a){return f.isSnippet(a)?!1:!f.isInline(a)})?c(a,b):!0}h("filters").add("_format",function g(c,l,m){var m=m||0,n=h("abbreviationUtils");d.each(c.children,function(c){if(n.isSnippet(c)){if(c.start=c.end="",!i(c)&&l.tag_nl!==!1&&b(c,l)&&!h("abbreviationUtils").isInline(c.parent))c.start=h("utils").getNewline()+c.start}else{c.start=c.end="%s";var d=h("utils"),j=h("abbreviationUtils"),r=j.isUnary(c),d=d.getNewline();if(l.tag_nl!==!1){var u=l.tag_nl===!0&&(l.tag_nl_leaf||c.children.length);if(!c.isTextNode()){if(b(c, +l)){if(!i(c)&&(!j.isSnippet(c.parent)||c.index()))c.start=d+c.start;if(j.hasBlockChildren(c)||c.children.length&&b(c.children[0],l)||u&&!r)c.end=d+c.end;if(j.hasTagsInContent(c)||u&&!c.children.length&&!r)c.start+=d+f()}else if(j.isInline(c)&&c.parent&&h("abbreviationUtils").hasBlockChildren(c.parent)&&!i(c))c.start=d+c.start;else if(j.isInline(c)&&a(c,l))c.end=d+c.end;c.padding=f()}}}g(c,l,m+1)});return c})}); +emmet.exec(function(h,d){function f(f,b){var c="",a=[],e=b.attributeQuote(),g=b.cursor();d.each(f.attributeList(),function(d){var f=b.attributeName(d.name);switch(f.toLowerCase()){case "id":c+="#"+(d.value||g);break;case "class":c+="."+h("utils").trim(d.value||g).replace(/\s+/g,".");break;default:a.push(":"+f+" => "+e+(d.value||g)+e)}});a.length&&(c+="{"+a.join(", ")+"}");return c}h("filters").add("haml",function b(c,a,e){var e=e||0,g=h("abbreviationUtils");e||(c=h("filters").apply(c,"_format",a)); +d.each(c.children,function(c){if(!g.isSnippet(c)&&c.parent){var d=h("abbreviationUtils"),m=h("utils"),n=f(c,a),o=a.cursor(),d=d.isUnary(c),q=a.self_closing_tag&&d?"/":"",s="",s="%"+a.tagName(c.name());s.toLowerCase()=="%div"&&n&&n.indexOf("{")==-1&&(s="");c.end="";c.start=m.replaceSubstring(c.start,s+n+q+" ",c.start.indexOf("%s"),"%s");!c.children.length&&!d&&(c.start+=o)}b(c,a,e+1)});return c})}); +emmet.exec(function(h,d){function f(f,b){var c=b.attributeQuote(),a=b.cursor();return d.map(f.attributeList(),function(d){return" "+b.attributeName(d.name)+"="+c+(d.value||a)+c}).join("")}h("filters").add("html",function b(c,a,e){var e=e||0,g=h("abbreviationUtils");e||(c=h("filters").apply(c,"_format",a));d.each(c.children,function(c){if(!g.isSnippet(c)&&c.parent){var d=h("abbreviationUtils"),m=h("utils"),n=f(c,a),o=a.cursor(),d=d.isUnary(c),q="",s="";if(!c.isTextNode()){var r=a.tagName(c.name()); +d?(q="<"+r+n+a.selfClosing()+">",c.end=""):(q="<"+r+n+">",s="")}c.start=m.replaceSubstring(c.start,q,c.start.indexOf("%s"),"%s");c.end=m.replaceSubstring(c.end,s,c.end.indexOf("%s"),"%s");!c.children.length&&!d&&c.content.indexOf(o)==-1&&(c.start+=o)}b(c,a,e+1)});return c})}); +emmet.exec(function(h,d){var f=/^\s+/,i=/[\n\r]/g;h("filters").add("s",function c(a){var e=h("abbreviationUtils");d.each(a.children,function(a){if(!e.isSnippet(a))a.start=a.start.replace(f,""),a.end=a.end.replace(f,"");a.start=a.start.replace(i,"");a.end=a.end.replace(i,"");a.content=a.content.replace(i,"");c(a)});return a})}); +emmet.exec(function(h,d){function f(h,b){d.each(h.children,function(c){if(c.content)c.content=c.content.replace(b,"");f(c,b)});return h}h("preferences").define("filter.trimRegexp","[\\s|\\u00a0]*[\\d|#|\\-|*|\\u2022]+\\.?\\s*","Regular expression used to remove list markers (numbers, dashes, bullets, etc.) in t (trim) filter. The trim filter is useful for wrapping with abbreviation lists, pased from other documents (for example, Word documents).");h("filters").add("t",function(d){var b= +RegExp(h("preferences").get("filter.trimRegexp"));return f(d,b)})});emmet.exec(function(h,d){var f={"xsl:variable":1,"xsl:with-param":1};h("filters").add("xsl",function b(c){var a=h("abbreviationUtils");d.each(c.children,function(c){if(!a.isSnippet(c)&&(c.name()||"").toLowerCase()in f&&c.children.length)c.start=c.start.replace(/\s+select\s*=\s*(['"]).*?\1/,"");b(c)});return c})}); +emmet.exec(function(h,d){function f(a,b){return Math.round(Math.random()*(b-a)+a)}function i(a,b){for(var c=a.length,e=Math.min(c,b),h=[];h.length3&&b<=6?f(0,1):b>6&&b<=12?f(0,2):f(1,4);d.each(i(d.range(c)),function(b){a[b]+= +","})}h("abbreviationParser").addPreprocessor(function(d){var h=/^(?:lorem|lipsum)(\d*)$/i,l;d.findAll(function(d){if(d._name&&(l=d._name.match(h))){var g=l[1]||30;d._name="";d.data("forceNameResolving",d.isRepeating()||d.attributeList().length);d.data("pasteOverwrites",!0);d.data("paste",function(d){var h=g,j=!d,d=[],l=0,h=parseInt(h,10);j&&(j=a.slice(0,h),j.length>5&&(j[4]+=","),l+=j.length,d.push(b(j,".")));for(;l","cc:ie6":"<\!--[if lte IE 6]>\n\t${child}|\n","cc:ie":"<\!--[if IE]>\n\t${child}|\n","cc:noie":"<\!--[if !IE]><\!--\>\n\t${child}|\n<\!--","html:4t":'\n\n\n\t\n\t${1:Document}\n\n\n\t${child}${2}\n\n', +"html:4s":'\n\n\n\t\n\t${1:Document}\n\n\n\t${child}${2}\n\n',"html:xt":'\n\n\n\t\n\t\n\n\n\t${child}${2}\n\n', +"html:xs":'\n\n\n\t\n\t${1:Document}\n\n\n\t${child}${2}\n\n',"html:xxs":'\n\n\n\t\n\t${1:Document}\n\n\n\t${child}${2}\n\n', +"html:5":'\n\n\n\t\n\t${1:Document}\n\n\n\t${child}${2}\n\n'},abbreviations:{"!":"html:5",a:'',"a:link":'',"a:mail":'',abbr:'',acronym:'',base:'',bdo:'',"bdo:r":'',"bdo:l":'',link:'',"link:css":'', +"link:print":'',"link:favicon":'',"link:touch":'',"link:rss":'',"link:atom":'',"meta:utf":'', +"meta:win":'',"meta:compat":'',style:""].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return J("flexWrap")},s.flexboxlegacy=function(){return J("boxDirection")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return D("background-color:rgba(150,255,150,.5)"),G(j.backgroundColor,"rgba")},s.hsla=function(){return D("background-color:hsla(120,40%,100%,.5)"),G(j.backgroundColor,"rgba")||G(j.backgroundColor,"hsla")},s.multiplebgs=function(){return D("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return J("backgroundSize")},s.borderimage=function(){return J("borderImage")},s.borderradius=function(){return J("borderRadius")},s.boxshadow=function(){return J("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return E("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return J("animationName")},s.csscolumns=function(){return J("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return D((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),G(j.backgroundImage,"gradient")},s.cssreflections=function(){return J("boxReflect")},s.csstransforms=function(){return!!J("transform")},s.csstransforms3d=function(){var a=!!J("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return J("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var L in s)C(s,L)&&(x=L.toLowerCase(),e[x]=s[L](),v.push((e[x]?"":"no-")+x));return e.input||K(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)C(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},D(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f + (MIT license) + + Example: + + + +**/ + +jQuery(function(){ + var script_source = jQuery('script[src*="share.js"]').attr('src'); + var params = function(name,default_value) { + var match = RegExp('[?&]' + name + '=([^&]*)').exec(script_source); + return match && decodeURIComponent(match[1].replace(/\+/g, ' '))||default_value; + } + var path = params('static','social'); + var url = encodeURIComponent(window.location.href); + var host = window.location.hostname; + var title = escape(jQuery('title').text()); + var twit = 'http://twitter.com/home?status='+title+'%20'+url; + var facebook = 'http://www.facebook.com/sharer.php?u='+url; + var gplus = 'https://plus.google.com/share?url='+url; + var tbar = ''; + // Add the share tool bar. + jQuery('body').append(tbar); + var st = jQuery('#socialdrawer'); + st.css({'opacity':'.7','z-index':'3000','background':'#FFF','border':'solid 1px #666','border-width':' 1px 0 0 1px','height':'20px','width':'40px','position':'fixed','bottom':'0','right':'0','padding':'2px 5px','overflow':'hidden','-webkit-border-top-left-radius':' 12px','-moz-border-radius-topleft':' 12px','border-top-left-radius':' 12px','-moz-box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)','-webkit-box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)','box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)'}); + jQuery('#socialdrawer a').css({'float':'left','width':'32px','margin':'3px 2px 2px 2px','padding':'0','cursor':'pointer'}); + jQuery('#socialdrawer span').css({'float':'left','margin':'2px 3px','text-shadow':' 1px 1px 1px #FFF','color':'#444','font-size':'12px','line-height':'1em'}); + jQuery('#socialdrawer img').hide(); + // hover + st.click(function(){ + jQuery(this).animate({height:'40px', width:'160px', opacity: 0.95}, 300); + jQuery('#socialdrawer img').show(); + }); + //leave + st.mouseleave(function(){ + st.animate({height:'20px', width: '40px', opacity: .7}, 300); + jQuery('#socialdrawer img').hide(); + return false; + } ); + }); diff --git a/web2py/applications/admin/static/js/typeahead.min.js b/web2py/applications/admin/static/js/typeahead.min.js new file mode 100644 index 0000000..c6d4298 --- /dev/null +++ b/web2py/applications/admin/static/js/typeahead.min.js @@ -0,0 +1,7 @@ +/*! + * typeahead.js 0.9.2 + * https://github.com/twitter/typeahead + * Copyright 2013 Twitter, Inc. and other contributors; Licensed MIT + */ + +(function(t){var e="0.9.2",i={isMsie:function(){var t=/(msie) ([\w.]+)/i.exec(navigator.userAgent);return t?parseInt(t[2],10):!1},isBlankString:function(t){return!t||/^\s*$/.test(t)},escapeRegExChars:function(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isString:function(t){return"string"==typeof t},isNumber:function(t){return"number"==typeof t},isArray:t.isArray,isFunction:t.isFunction,isObject:t.isPlainObject,isUndefined:function(t){return t===void 0},bind:t.proxy,bindAll:function(e){var i;for(var n in e)t.isFunction(i=e[n])&&(e[n]=t.proxy(i,e))},indexOf:function(t,e){for(var i=0;t.length>i;i++)if(t[i]===e)return i;return-1},each:t.each,map:t.map,filter:t.grep,every:function(e,i){var n=!0;return e?(t.each(e,function(t,s){return(n=i.call(null,s,t,e))?void 0:!1}),!!n):n},some:function(e,i){var n=!1;return e?(t.each(e,function(t,s){return(n=i.call(null,s,t,e))?!1:void 0}),!!n):n},mixin:t.extend,getUniqueId:function(){var t=0;return function(){return t++}}(),defer:function(t){setTimeout(t,0)},debounce:function(t,e,i){var n,s;return function(){var r,o,u=this,a=arguments;return r=function(){n=null,i||(s=t.apply(u,a))},o=i&&!n,clearTimeout(n),n=setTimeout(r,e),o&&(s=t.apply(u,a)),s}},throttle:function(t,e){var i,n,s,r,o,u;return o=0,u=function(){o=new Date,s=null,r=t.apply(i,n)},function(){var a=new Date,c=e-(a-o);return i=this,n=arguments,0>=c?(clearTimeout(s),s=null,o=a,r=t.apply(i,n)):s||(s=setTimeout(u,c)),r}},tokenizeQuery:function(e){return t.trim(e).toLowerCase().split(/[\s]+/)},tokenizeText:function(e){return t.trim(e).toLowerCase().split(/[\s\-_]+/)},getProtocol:function(){return location.protocol},noop:function(){}},n=function(){var t=/\s+/;return{on:function(e,i){var n;if(!i)return this;for(this._callbacks=this._callbacks||{},e=e.split(t);n=e.shift();)this._callbacks[n]=this._callbacks[n]||[],this._callbacks[n].push(i);return this},trigger:function(e,i){var n,s;if(!this._callbacks)return this;for(e=e.split(t);n=e.shift();)if(s=this._callbacks[n])for(var r=0;s.length>r;r+=1)s[r].call(this,{type:n,data:i});return this}}}(),s=function(){function e(e){e&&e.el||t.error("EventBus initialized without el"),this.$el=t(e.el)}var n="typeahead:";return i.mixin(e.prototype,{trigger:function(t){var e=[].slice.call(arguments,1);this.$el.trigger(n+t,e)}}),e}(),r=function(){function t(t){this.prefix=["__",t,"__"].join(""),this.ttlKey="__ttl__",this.keyMatcher=RegExp("^"+this.prefix)}function e(){return(new Date).getTime()}function n(t){return JSON.stringify(i.isUndefined(t)?null:t)}function s(t){return JSON.parse(t)}var r,o;try{r=window.localStorage}catch(u){r=null}return o=r&&window.JSON?{_prefix:function(t){return this.prefix+t},_ttlKey:function(t){return this._prefix(t)+this.ttlKey},get:function(t){return this.isExpired(t)&&this.remove(t),s(r.getItem(this._prefix(t)))},set:function(t,s,o){return i.isNumber(o)?r.setItem(this._ttlKey(t),n(e()+o)):r.removeItem(this._ttlKey(t)),r.setItem(this._prefix(t),n(s))},remove:function(t){return r.removeItem(this._ttlKey(t)),r.removeItem(this._prefix(t)),this},clear:function(){var t,e,i=[],n=r.length;for(t=0;n>t;t++)(e=r.key(t)).match(this.keyMatcher)&&i.push(e.replace(this.keyMatcher,""));for(t=i.length;t--;)this.remove(i[t]);return this},isExpired:function(t){var n=s(r.getItem(this._ttlKey(t)));return i.isNumber(n)&&e()>n?!0:!1}}:{get:i.noop,set:i.noop,remove:i.noop,clear:i.noop,isExpired:i.noop},i.mixin(t.prototype,o),t}(),o=function(){function t(t){i.bindAll(this),t=t||{},this.sizeLimit=t.sizeLimit||10,this.cache={},this.cachedKeysByAge=[]}return i.mixin(t.prototype,{get:function(t){return this.cache[t]},set:function(t,e){var i;this.cachedKeysByAge.length===this.sizeLimit&&(i=this.cachedKeysByAge.shift(),delete this.cache[i]),this.cache[t]=e,this.cachedKeysByAge.push(t)}}),t}(),u=function(){function e(t){i.bindAll(this),t=i.isString(t)?{url:t}:t,a=a||new o,u=i.isNumber(t.maxParallelRequests)?t.maxParallelRequests:u||6,this.url=t.url,this.wildcard=t.wildcard||"%QUERY",this.filter=t.filter,this.replace=t.replace,this.ajaxSettings={type:"get",cache:t.cache,timeout:t.timeout,dataType:t.dataType||"json",beforeSend:t.beforeSend},this._get=(/^throttle$/i.test(t.rateLimitFn)?i.throttle:i.debounce)(this._get,t.rateLimitWait||300)}function n(){c++}function s(){c--}function r(){return u>c}var u,a,c=0,h={};return i.mixin(e.prototype,{_get:function(t,e){function i(i){var s=n.filter?n.filter(i):i;e&&e(s),a.set(t,i)}var n=this;r()?this._sendRequest(t).done(i):this.onDeckRequestArgs=[].slice.call(arguments,0)},_sendRequest:function(e){function i(){s(),h[e]=null,r.onDeckRequestArgs&&(r._get.apply(r,r.onDeckRequestArgs),r.onDeckRequestArgs=null)}var r=this,o=h[e];return o||(n(),o=h[e]=t.ajax(e,this.ajaxSettings).always(i)),o},get:function(t,e){var n,s,r=this,o=encodeURIComponent(t||"");return e=e||i.noop,n=this.replace?this.replace(this.url,o):this.url.replace(this.wildcard,o),(s=a.get(n))?i.defer(function(){e(r.filter?r.filter(s):s)}):this._get(n,e),!!s}}),e}(),a=function(){function n(e){i.bindAll(this),i.isString(e.template)&&!e.engine&&t.error("no template engine specified"),e.local||e.prefetch||e.remote||t.error("one of local, prefetch, or remote is required"),this.name=e.name||i.getUniqueId(),this.limit=e.limit||5,this.minLength=e.minLength||1,this.header=e.header,this.footer=e.footer,this.valueKey=e.valueKey||"value",this.template=s(e.template,e.engine,this.valueKey),this.local=e.local,this.prefetch=e.prefetch,this.remote=e.remote,this.itemHash={},this.adjacencyList={},this.storage=e.name?new r(e.name):null}function s(t,e,n){var s,r;return i.isFunction(t)?s=t:i.isString(t)?(r=e.compile(t),s=i.bind(r.render,r)):s=function(t){return"

"+t[n]+"

"},s}var o={thumbprint:"thumbprint",protocol:"protocol",itemHash:"itemHash",adjacencyList:"adjacencyList"};return i.mixin(n.prototype,{_processLocalData:function(t){this._mergeProcessedData(this._processData(t))},_loadPrefetchData:function(n){function s(t){var e=n.filter?n.filter(t):t,s=d._processData(e),r=s.itemHash,u=s.adjacencyList;d.storage&&(d.storage.set(o.itemHash,r,n.ttl),d.storage.set(o.adjacencyList,u,n.ttl),d.storage.set(o.thumbprint,p,n.ttl),d.storage.set(o.protocol,i.getProtocol(),n.ttl)),d._mergeProcessedData(s)}var r,u,a,c,h,l,d=this,p=e+(n.thumbprint||"");return this.storage&&(r=this.storage.get(o.thumbprint),u=this.storage.get(o.protocol),a=this.storage.get(o.itemHash),c=this.storage.get(o.adjacencyList)),h=r!==p||u!==i.getProtocol(),n=i.isString(n)?{url:n}:n,n.ttl=i.isNumber(n.ttl)?n.ttl:864e5,a&&c&&!h?(this._mergeProcessedData({itemHash:a,adjacencyList:c}),l=t.Deferred().resolve()):l=t.getJSON(n.url).done(s),l},_transformDatum:function(t){var e=i.isString(t)?t:t[this.valueKey],n=t.tokens||i.tokenizeText(e),s={value:e,tokens:n};return i.isString(t)?(s.datum={},s.datum[this.valueKey]=t):s.datum=t,s.tokens=i.filter(s.tokens,function(t){return!i.isBlankString(t)}),s.tokens=i.map(s.tokens,function(t){return t.toLowerCase()}),s},_processData:function(t){var e=this,n={},s={};return i.each(t,function(t,r){var o=e._transformDatum(r),u=i.getUniqueId(o.value);n[u]=o,i.each(o.tokens,function(t,e){var n=e.charAt(0),r=s[n]||(s[n]=[u]);!~i.indexOf(r,u)&&r.push(u)})}),{itemHash:n,adjacencyList:s}},_mergeProcessedData:function(t){var e=this;i.mixin(this.itemHash,t.itemHash),i.each(t.adjacencyList,function(t,i){var n=e.adjacencyList[t];e.adjacencyList[t]=n?n.concat(i):i})},_getLocalSuggestions:function(t){var e,n=this,s=[],r=[],o=[];return i.each(t,function(t,e){var n=e.charAt(0);!~i.indexOf(s,n)&&s.push(n)}),i.each(s,function(t,i){var s=n.adjacencyList[i];return s?(r.push(s),(!e||s.length").css({position:"absolute",left:"-9999px",visibility:"hidden",whiteSpace:"nowrap",fontFamily:e.css("font-family"),fontSize:e.css("font-size"),fontStyle:e.css("font-style"),fontVariant:e.css("font-variant"),fontWeight:e.css("font-weight"),wordSpacing:e.css("word-spacing"),letterSpacing:e.css("letter-spacing"),textIndent:e.css("text-indent"),textRendering:e.css("text-rendering"),textTransform:e.css("text-transform")}).insertAfter(e)}function r(t,e){return t=(t||"").replace(/^\s*/g,"").replace(/\s{2,}/g," "),e=(e||"").replace(/^\s*/g,"").replace(/\s{2,}/g," "),t===e}return i.mixin(e.prototype,n,{_handleFocus:function(){this.trigger("focused")},_handleBlur:function(){this.trigger("blured")},_handleSpecialKeyEvent:function(t){var e=this.specialKeyCodeMap[t.which||t.keyCode];e&&this.trigger(e+"Keyed",t)},_compareQueryToInputValue:function(){var t=this.getInputValue(),e=r(this.query,t),i=e?this.query.length!==t.length:!1;i?this.trigger("whitespaceChanged",{value:this.query}):e||this.trigger("queryChanged",{value:this.query=t})},destroy:function(){this.$hint.off(".tt"),this.$input.off(".tt"),this.$hint=this.$input=this.$overflowHelper=null},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getQuery:function(){return this.query},setQuery:function(t){this.query=t},getInputValue:function(){return this.$input.val()},setInputValue:function(t,e){this.$input.val(t),!e&&this._compareQueryToInputValue()},getHintValue:function(){return this.$hint.val()},setHintValue:function(t){this.$hint.val(t)},getLanguageDirection:function(){return(this.$input.css("direction")||"ltr").toLowerCase()},isOverflow:function(){return this.$overflowHelper.text(this.getInputValue()),this.$overflowHelper.width()>this.$input.width()},isCursorAtEnd:function(){var t,e=this.$input.val().length,n=this.$input[0].selectionStart;return i.isNumber(n)?n===e:document.selection?(t=document.selection.createRange(),t.moveStart("character",-e),e===t.text.length):!0}}),e}(),h=function(){function e(e){i.bindAll(this),this.isOpen=!1,this.isEmpty=!0,this.isMouseOverDropdown=!1,this.$menu=t(e.menu).on("mouseenter.tt",this._handleMouseenter).on("mouseleave.tt",this._handleMouseleave).on("click.tt",".tt-suggestion",this._handleSelection).on("mouseover.tt",".tt-suggestion",this._handleMouseover)}function s(t){return t.data("suggestion")}var r={suggestionsList:''},o={suggestionsList:{display:"block"},suggestion:{whiteSpace:"nowrap",cursor:"pointer"},suggestionChild:{whiteSpace:"normal"}};return i.mixin(e.prototype,n,{_handleMouseenter:function(){this.isMouseOverDropdown=!0},_handleMouseleave:function(){this.isMouseOverDropdown=!1},_handleMouseover:function(e){var i=t(e.currentTarget);this._getSuggestions().removeClass("tt-is-under-cursor"),i.addClass("tt-is-under-cursor")},_handleSelection:function(e){var i=t(e.currentTarget);this.trigger("suggestionSelected",s(i))},_show:function(){this.$menu.css("display","block")},_hide:function(){this.$menu.hide()},_moveCursor:function(t){var e,i,n,r;if(this.isVisible()){if(e=this._getSuggestions(),i=e.filter(".tt-is-under-cursor"),i.removeClass("tt-is-under-cursor"),n=e.index(i)+t,n=(n+1)%(e.length+1)-1,-1===n)return this.trigger("cursorRemoved"),void 0;-1>n&&(n=e.length-1),r=e.eq(n).addClass("tt-is-under-cursor"),this.trigger("cursorMoved",s(r))}},_getSuggestions:function(){return this.$menu.find(".tt-suggestions > .tt-suggestion")},destroy:function(){this.$menu.off(".tt"),this.$menu=null},isVisible:function(){return this.isOpen&&!this.isEmpty},closeUnlessMouseIsOverDropdown:function(){this.isMouseOverDropdown||this.close()},close:function(){this.isOpen&&(this.isOpen=!1,this._hide(),this.$menu.find(".tt-suggestions > .tt-suggestion").removeClass("tt-is-under-cursor"),this.trigger("closed"))},open:function(){this.isOpen||(this.isOpen=!0,!this.isEmpty&&this._show(),this.trigger("opened"))},setLanguageDirection:function(t){var e={left:"0",right:"auto"},i={left:"auto",right:" 0"};"ltr"===t?this.$menu.css(e):this.$menu.css(i)},moveCursorUp:function(){this._moveCursor(-1)},moveCursorDown:function(){this._moveCursor(1)},getSuggestionUnderCursor:function(){var t=this._getSuggestions().filter(".tt-is-under-cursor").first();return t.length>0?s(t):null},getFirstSuggestion:function(){var t=this._getSuggestions().first();return t.length>0?s(t):null},renderSuggestions:function(e,n){var s,u,a,c,h,l="tt-dataset-"+e.name,d='
%body
',p=this.$menu.find("."+l);0===p.length&&(u=t(r.suggestionsList).css(o.suggestionsList),p=t("
").addClass(l).append(e.header).append(u).append(e.footer).appendTo(this.$menu)),n.length>0?(this.isEmpty=!1,this.isOpen&&this._show(),a=document.createElement("div"),c=document.createDocumentFragment(),i.each(n,function(i,n){s=e.template(n.datum),a.innerHTML=d.replace("%body",s),h=t(a.firstChild).css(o.suggestion).data("suggestion",n),h.children().each(function(){t(this).css(o.suggestionChild)}),c.appendChild(h[0])}),p.show().find(".tt-suggestions").html(c)):this.clearSuggestions(e.name),this.trigger("suggestionsRendered")},clearSuggestions:function(t){var e=t?this.$menu.find(".tt-dataset-"+t):this.$menu.find('[class^="tt-dataset-"]'),i=e.find(".tt-suggestions");e.hide(),i.empty(),0===this._getSuggestions().length&&(this.isEmpty=!0,this._hide())}}),e}(),l=function(){function e(t){var e,n,r;i.bindAll(this),this.$node=s(t.input),this.datasets=t.datasets,this.dir=null,this.eventBus=t.eventBus,e=this.$node.find(".tt-dropdown-menu"),n=this.$node.find(".tt-query"),r=this.$node.find(".tt-hint"),this.dropdownView=new h({menu:e}).on("suggestionSelected",this._handleSelection).on("cursorMoved",this._clearHint).on("cursorMoved",this._setInputValueToSuggestionUnderCursor).on("cursorRemoved",this._setInputValueToQuery).on("cursorRemoved",this._updateHint).on("suggestionsRendered",this._updateHint).on("opened",this._updateHint).on("closed",this._clearHint).on("opened closed",this._propagateEvent),this.inputView=new c({input:n,hint:r}).on("focused",this._openDropdown).on("blured",this._closeDropdown).on("blured",this._setInputValueToQuery).on("enterKeyed",this._handleSelection).on("queryChanged",this._clearHint).on("queryChanged",this._clearSuggestions).on("queryChanged",this._getSuggestions).on("whitespaceChanged",this._updateHint).on("queryChanged whitespaceChanged",this._openDropdown).on("queryChanged whitespaceChanged",this._setLanguageDirection).on("escKeyed",this._closeDropdown).on("escKeyed",this._setInputValueToQuery).on("tabKeyed upKeyed downKeyed",this._managePreventDefault).on("upKeyed downKeyed",this._moveDropdownCursor).on("upKeyed downKeyed",this._openDropdown).on("tabKeyed leftKeyed rightKeyed",this._autocomplete)}function s(e){var i=t(o.wrapper),n=t(o.dropdown),s=t(e),r=t(o.hint);i=i.css(u.wrapper),n=n.css(u.dropdown),r.css(u.hint).css({backgroundAttachment:s.css("background-attachment"),backgroundClip:s.css("background-clip"),backgroundColor:s.css("background-color"),backgroundImage:s.css("background-image"),backgroundOrigin:s.css("background-origin"),backgroundPosition:s.css("background-position"),backgroundRepeat:s.css("background-repeat"),backgroundSize:s.css("background-size")}),s.data("ttAttrs",{dir:s.attr("dir"),autocomplete:s.attr("autocomplete"),spellcheck:s.attr("spellcheck"),style:s.attr("style")}),s.addClass("tt-query").attr({autocomplete:"off",spellcheck:!1}).css(u.query);try{!s.attr("dir")&&s.attr("dir","auto")}catch(a){}return s.wrap(i).parent().prepend(r).append(n)}function r(t){var e=t.find(".tt-query");i.each(e.data("ttAttrs"),function(t,n){i.isUndefined(n)?e.removeAttr(t):e.attr(t,n)}),e.detach().removeData("ttAttrs").removeClass("tt-query").insertAfter(t),t.remove()}var o={wrapper:'',hint:'',dropdown:''},u={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none"},query:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},dropdown:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"}};return i.isMsie()&&i.mixin(u.query,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),i.isMsie()&&7>=i.isMsie()&&(i.mixin(u.wrapper,{display:"inline",zoom:"1"}),i.mixin(u.query,{marginTop:"-1px"})),i.mixin(e.prototype,n,{_managePreventDefault:function(t){var e,i,n=t.data,s=!1;switch(t.type){case"tabKeyed":e=this.inputView.getHintValue(),i=this.inputView.getInputValue(),s=e&&e!==i;break;case"upKeyed":case"downKeyed":s=!n.shiftKey&&!n.ctrlKey&&!n.metaKey}s&&n.preventDefault()},_setLanguageDirection:function(){var t=this.inputView.getLanguageDirection();t!==this.dir&&(this.dir=t,this.$node.css("direction",t),this.dropdownView.setLanguageDirection(t))},_updateHint:function(){var t,e,n,s,r,o=this.dropdownView.getFirstSuggestion(),u=o?o.value:null,a=this.dropdownView.isVisible(),c=this.inputView.isOverflow();u&&a&&!c&&(t=this.inputView.getInputValue(),e=t.replace(/\s{2,}/g," ").replace(/^\s+/g,""),n=i.escapeRegExChars(e),s=RegExp("^(?:"+n+")(.*$)","i"),r=s.exec(u),this.inputView.setHintValue(t+(r?r[1]:"")))},_clearHint:function(){this.inputView.setHintValue("")},_clearSuggestions:function(){this.dropdownView.clearSuggestions()},_setInputValueToQuery:function(){this.inputView.setInputValue(this.inputView.getQuery())},_setInputValueToSuggestionUnderCursor:function(t){var e=t.data;this.inputView.setInputValue(e.value,!0)},_openDropdown:function(){this.dropdownView.open()},_closeDropdown:function(t){this.dropdownView["blured"===t.type?"closeUnlessMouseIsOverDropdown":"close"]()},_moveDropdownCursor:function(t){var e=t.data;e.shiftKey||e.ctrlKey||e.metaKey||this.dropdownView["upKeyed"===t.type?"moveCursorUp":"moveCursorDown"]()},_handleSelection:function(t){var e="suggestionSelected"===t.type,n=e?t.data:this.dropdownView.getSuggestionUnderCursor();n&&(this.inputView.setInputValue(n.value),e?this.inputView.focus():t.data.preventDefault(),e&&i.isMsie()?i.defer(this.dropdownView.close):this.dropdownView.close(),this.eventBus.trigger("selected",n.datum))},_getSuggestions:function(){var t=this,e=this.inputView.getQuery();i.isBlankString(e)||i.each(this.datasets,function(i,n){n.getSuggestions(e,function(i){e===t.inputView.getQuery()&&t.dropdownView.renderSuggestions(n,i)})})},_autocomplete:function(t){var e,i,n,s,r;("rightKeyed"!==t.type&&"leftKeyed"!==t.type||(e=this.inputView.isCursorAtEnd(),i="ltr"===this.inputView.getLanguageDirection()?"leftKeyed"===t.type:"rightKeyed"===t.type,e&&!i))&&(n=this.inputView.getQuery(),s=this.inputView.getHintValue(),""!==s&&n!==s&&(r=this.dropdownView.getFirstSuggestion(),this.inputView.setInputValue(r.value),this.eventBus.trigger("autocompleted",r.datum)))},_propagateEvent:function(t){this.eventBus.trigger(t.type)},destroy:function(){this.inputView.destroy(),this.dropdownView.destroy(),r(this.$node),this.$node=null},setQuery:function(t){this.inputView.setQuery(t),this.inputView.setInputValue(t),this._clearHint(),this._clearSuggestions(),this._getSuggestions()}}),e}();(function(){var e,n={},r="ttView";e={initialize:function(e){function o(){var e,n=t(this),o=new s({el:n});e=i.map(u,function(t){return t.initialize()}),n.data(r,new l({input:n,eventBus:o=new s({el:n}),datasets:u})),t.when.apply(t,e).always(function(){i.defer(function(){o.trigger("initialized")})})}var u;return e=i.isArray(e)?e:[e],0===e.length&&t.error("no datasets provided"),u=i.map(e,function(t){var e=n[t.name]?n[t.name]:new a(t);return t.name&&(n[t.name]=e),e}),this.each(o)},destroy:function(){function e(){var e=t(this),i=e.data(r);i&&(i.destroy(),e.removeData(r))}return this.each(e)},setQuery:function(e){function i(){var i=t(this).data(r);i&&i.setQuery(e)}return this.each(i)}},jQuery.fn.typeahead=function(t){return e[t]?e[t].apply(this,[].slice.call(arguments,1)):e.initialize.apply(this,arguments)}})()})(window.jQuery); \ No newline at end of file diff --git a/web2py/applications/admin/static/js/web2py.js b/web2py/applications/admin/static/js/web2py.js new file mode 100644 index 0000000..22b9f25 --- /dev/null +++ b/web2py/applications/admin/static/js/web2py.js @@ -0,0 +1,828 @@ +(function ($, undefined) { + /* + * Unobtrusive scripting adapter for jQuery, largely taken from + * the wonderful https://github.com/rails/jquery-ujs + * + * + * Released under the MIT license + * + */ + 'use strict'; + if ($.web2py !== undefined) { + $.error('web2py.js has already been loaded!'); + } + + var FORMDATA_IS_SUPPORTED = typeof(FormData) !== 'undefined'; + var animateIn = 'fadeIn'; + // var animateIn = 'slideDown'; + + String.prototype.reverse = function () { + return this.split('').reverse().join(''); + }; + var web2py; + + $.web2py = web2py = { + + isUndefined: function (obj) { + /* grabbed from underscore.js */ + return obj === void 0; + }, + popup: function (url) { + /* popup a window */ + var newwindow = window.open(url, 'name', 'height=400,width=600'); + if (window.focus) newwindow.focus(); + return false; + }, + collapse: function (id) { + /* toggle an element */ + $('#' + id).slideToggle(); + }, + fade: function (id, value) { + /*fade something*/ + if (value > 0) $('#' + id).hide().fadeIn('slow'); + else $('#' + id).show().fadeOut('slow'); + }, + ajax: function (u, s, t, options) { + /*simple ajax function*/ + + // set options default value + options = typeof options !== 'undefined' ? options : {}; + + var query = ''; + if (typeof s == 'string') { + var d = $(s).serialize(); + if (d) { + query = d; + } + } else { + var pcs = []; + if (s !== null && !web2py.isUndefined(s)) + for (var i = 0; i < s.length; i++) { + var q = $('[name=' + s[i] + ']').serialize(); + if (q) { + pcs.push(q); + } + } + if (pcs.length > 0) { + query = pcs.join('&'); + } + } + + // default success action + var success_function = function (msg) { + if (t) { + if (t == ':eval') eval(msg); + else if (typeof t == 'string') $('#' + t).html(msg); + else t(msg); + } + }; + + // declare success actions as array + var success = [success_function]; + + // add user success actions + if ($.isArray(options.done)){ + success = $.merge(success, options.done); + } else { + success.push(options.done); + } + + // default jquery ajax options + var ajax_options = { + type: 'POST', + url: u, + data: query, + success: success + }; + + //remove custom "done" option if exists + delete options.done; + + // merge default ajax options with user custom options + for (var attrname in options) { + ajax_options[attrname] = options[attrname]; + } + + // call ajax function + $.ajax(ajax_options); + }, + ajax_fields: function (target) { + /* + *this attaches something to a newly loaded fragment/page + * Ideally all events should be bound to the document, so we can avoid calling + * this over and over... all will be bound to the document + */ + /*adds btn class to buttons*/ + $('button:not([class^="btn"])', target).addClass('btn'); + $( + 'form input[type="submit"]:not([class^="btn"]), form input[type="button"]:not([class^="btn"])', + target).addClass('btn'); + /* javascript for PasswordWidget*/ + $('input[type=password][data-w2p_entropy]', target).each(function () { + web2py.validate_entropy($(this)); + }); + /* javascript for ListWidget*/ + $('ul.w2p_list', target).each(function () { + function pe(ul, e) { + var new_line = ml(ul); + rel(ul); + if ($(e.target).parent().is(':visible')) { + /* make sure we didn't delete the element before we insert after */ + new_line.insertAfter($(e.target).parent()); + } else { + /* the line we clicked on was deleted, just add to end of list */ + new_line.appendTo(ul); + } + new_line.find(':text').focus(); + return false; + } + + function rl(ul, e) { + if ($(ul).children().length > 1) { + /* only remove if we have more than 1 item so the list is never empty */ + $(e.target).parent().remove(); + } + } + + function ml(ul) { + /* clone the first field */ + var line = $(ul).find('li:first').clone(true); + line.find(':text').val(''); + return line; + } + + function rel(ul) { + /* keep only as many as needed*/ + $(ul).find('li').each(function () { + var trimmed = $.trim($(this.firstChild).val()); + if (trimmed === '') $(this).remove(); + else $(this.firstChild).val(trimmed); + }); + } + var ul = this; + $(ul).find(':text').after('+ -').keypress( + function (e) { + return (e.which == 13) ? pe(ul, e) : true; + }).next().click(function (e) { + pe(ul, e); + e.preventDefault(); + }).next().click(function (e) { + rl(ul, e); + e.preventDefault(); + }); + }); + }, + ajax_init: function (target) { + /*called whenever a fragment gets loaded */ + $('.w2p_hidden', target).hide(); + web2py.manage_errors(target); + web2py.ajax_fields(target); + web2py.show_if_handler(target); + web2py.component_handler(target); + }, + /* manage errors in forms */ + manage_errors: function (target) { + $('div.error', target).hide()[animateIn]('slow'); + }, + after_ajax: function (xhr) { + /* called whenever an ajax request completes */ + var command = xhr.getResponseHeader('web2py-component-command'); + var flash = xhr.getResponseHeader('web2py-component-flash'); + if (command !== null) { + eval(decodeURIComponent(command)); + } + if (flash) { + web2py.flash(decodeURIComponent(flash)); + } + }, + event_handlers: function () { + /* + * This is called once for page + * Ideally it should bound all the things that are needed + * and require no dom manipulations + */ + var doc = $(document); + doc.on('click', '.w2p_flash', function (event) { + event.preventDefault(); + var t = $(this); + if (t.css('top') == '0px') t.slideUp('slow'); + else t.fadeOut(); + }); + doc.on('keyup', 'input.integer', function () { + var nvalue = this.value.reverse().replace(/[^0-9\-]|\-(?=.)/g, '').reverse(); + if (this.value != nvalue) this.value = nvalue; + }); + doc.on('keyup', 'input.double, input.decimal', function () { + var nvalue = this.value.reverse().replace( + /[^0-9\-\.,]|[\-](?=.)|[\.,](?=[0-9]*[\.,])/g, '').reverse(); + if (this.value != nvalue) this.value = nvalue; + }); + var confirm_message = !web2py.isUndefined(w2p_ajax_confirm_message) ? w2p_ajax_confirm_message : + 'Are you sure you want to delete this object?'; + doc.on('click', 'input[type="checkbox"].delete', function () { + if (this.checked) + if (!web2py.confirm(confirm_message)) this.checked = false; + }); + var datetime_format = !web2py.isUndefined(w2p_ajax_datetime_format) ? w2p_ajax_datetime_format : + '%Y-%m-%d %H:%M:%S'; + doc.on('click', 'input.datetime', function () { + var tformat = $(this).data('w2p_datetime_format'); + var active = $(this).data('w2p_datetime'); + var format = !web2py.isUndefined(tformat) ? tformat : datetime_format; + if (active === undefined) { + Calendar.setup({ + inputField: this, + ifFormat: format, + showsTime: true, + timeFormat: '24' + }); + $(this).attr('autocomplete', 'off'); + $(this).data('w2p_datetime', 1); + $(this).trigger('click'); + } + }); + var date_format = !web2py.isUndefined(w2p_ajax_date_format) ? w2p_ajax_date_format : '%Y-%m-%d'; + doc.on('click', 'input.date', function () { + var tformat = $(this).data('w2p_date_format'); + var active = $(this).data('w2p_date'); + var format = !web2py.isUndefined(tformat) ? tformat : date_format; + if (active === undefined) { + Calendar.setup({ + inputField: this, + ifFormat: format, + showsTime: false + }); + $(this).data('w2p_date', 1); + $(this).attr('autocomplete', 'off'); + $(this).trigger('click'); + } + }); + doc.on('focus', 'input.time', function () { + var active = $(this).data('w2p_time'); + if (web2py.isUndefined(active)) { + $(this).timeEntry({ + spinnerImage: '' + }).attr('autocomplete', 'off'); + $(this).data('w2p_time', 1); + } + }); + /* help preventing double form submission for normal form (not LOADed) */ + $(doc).on('submit', 'form', function (e) { + var submit_buttons = $(this).find(web2py.formInputClickSelector); + submit_buttons.each(function() { + web2py.disableElement($(this)); + }) + /* safeguard in case the form doesn't trigger a refresh, + see https://github.com/web2py/web2py/issues/1100 */ + setTimeout(function () { + submit_buttons.each(function() { + web2py.enableElement($(this)); + }); + }, 5000); + }); + doc.ajaxSuccess(function (e, xhr) { + var redirect = xhr.getResponseHeader('web2py-redirect-location'); + if (redirect !== null) { + window.location = redirect; + } + /* run this here only if this Ajax request is NOT for a web2py component. */ + if (xhr.getResponseHeader('web2py-component-content') === null) { + web2py.after_ajax(xhr); + } + }); + + doc.ajaxError(function (e, xhr, settings, exception) { + /*personally I don't like it. + *if there's an error it it flashed and can be removed + *as any other message + *doc.off('click', '.w2p_flash') + */ + switch (xhr.status) { + case 500: + web2py.flash(ajax_error_500); + } + }); + + }, + trap_form: function (action, target) { + /* traps any LOADed form */ + $('#' + target + ' form').each(function () { + var form = $(this); + if (form.hasClass('no_trap')) { + return; + } + + var w2p_target = $(this).attr('data-w2p_target'); + if (web2py.isUndefined(w2p_target) || w2p_target === false) { + form.attr('data-w2p_target', target); + } else { + target = w2p_target; + } + + var url = form.attr('action'); + if ((url === '') || (url === '#') || web2py.isUndefined(url)) { + /* form has no action. Use component url. */ + url = action; + } + + form.submit(function (e) { + web2py.disableElement(form.find(web2py.formInputClickSelector)); + web2py.hide_flash(); + + var formData; + if (FORMDATA_IS_SUPPORTED) { + formData = new FormData(form[0]); // Allows file uploads. + } else { + formData = form.serialize(); // Fallback for older browsers. + } + web2py.ajax_page('post', url, formData, target, form); + + e.preventDefault(); + }); + form.on('click', web2py.formInputClickSelector, function (e) { + e.preventDefault(); + var input_name = $(this).attr('name'); + if (!web2py.isUndefined(input_name)) { + $('').attr('name', input_name) + .attr('value', $(this).val()).appendTo(form); + } + form.trigger('submit'); + }); + }); + }, + ajax_page: function (method, action, data, target, element) { + /* element is a new parameter, but should be put be put in front */ + if (web2py.isUndefined(element)) element = $(document); + /* if target is not there, fill it with something that there isn't in the page*/ + if (web2py.isUndefined(target) || target === '') target = 'w2p_none'; + + /* processData and contentType must be set to false when passing a FormData + object to jQuery.ajax. */ + var isFormData = Object.prototype.toString.call(data) === '[object FormData]'; + var contentType = isFormData ? false : 'application/x-www-form-urlencoded; charset=UTF-8'; + if (web2py.fire(element, 'ajax:before', null, target)) { /*test a usecase, should stop here if returns false */ + $.ajax({ + 'type': method, + 'url': action, + 'data': data, + 'processData': !isFormData, + 'contentType': contentType, + 'beforeSend': function (xhr, settings) { + xhr.setRequestHeader('web2py-component-location', document.location); + xhr.setRequestHeader('web2py-component-element', target); + web2py.fire(element, 'w2p:componentBegin', [xhr, settings], target); + return web2py.fire(element, 'ajax:beforeSend', [xhr, settings], target); //test a usecase, should stop here if returns false + }, + 'success': function (data, status, xhr) { + /*bummer for form submissions....the element is not there after complete + *because it gets replaced by the new response.... + */ + web2py.fire(element, 'ajax:success', [data, status, xhr], target); + }, + 'error': function (xhr, status, error) { + /*bummer for form submissions....in addition to the element being not there after + *complete because it gets replaced by the new response, standard form + *handling just returns the same status code for good and bad + *form submissions (i.e. that triggered a validator error) + */ + web2py.fire(element, 'ajax:error', [xhr, status, error], target); + }, + 'complete': function (xhr, status) { + web2py.fire(element, 'ajax:complete', [xhr, status], target); + web2py.updatePage(xhr, target); /* Parse and load the html received */ + web2py.trap_form(action, target); + web2py.ajax_init('#' + target); + web2py.after_ajax(xhr); + web2py.fire(element, 'w2p:componentComplete', [xhr, status], target); // Let us know the component is finished loading + } + }); + } + }, + component: function (action, target, timeout, times, el) { + /* element is a new parameter, but should be put in front */ + $(function () { + var jelement = $('#' + target); + var element = jelement.get(0); + var statement = 'jQuery("#' + target + '").get(0).reload();'; + element.reload = function () { + /* Continue if times is Infinity or + * the times limit is not reached + */ + if (element.reload_check()) { + web2py.ajax_page('get', action, null, target, el); + } + }; + /* Method to check timing limit */ + element.reload_check = function () { + if (jelement.hasClass('w2p_component_stop')) { + clearInterval(this.timing); + return false; + } + if (this.reload_counter == Infinity) { + return true; + } else { + if (!isNaN(this.reload_counter)) { + this.reload_counter -= 1; + if (this.reload_counter < 0) { + if (!this.run_once) { + clearInterval(this.timing); + return false; + } + } else { + return true; + } + } + } + return false; + }; + if (!isNaN(timeout)) { + element.timeout = timeout; + element.reload_counter = times; + if (times > 1) { + /* Multiple or infinite reload + * Run first iteration + */ + web2py.ajax_page('get', action, null, target, el); + element.run_once = false; + element.timing = setInterval(statement, timeout); + element.reload_counter -= 1; + } else if (times == 1) { + /* Run once with timeout */ + element.run_once = true; + element.setTimeout = setTimeout; + element.timing = setTimeout(statement, timeout); + } + } else { + /* run once (no timeout specified) */ + element.reload_counter = Infinity; + web2py.ajax_page('get', action, null, target, el); + } + }); + }, + updatePage: function (xhr, target) { + var t = $('#' + target); + var html = $.parseHTML(xhr.responseText, document, true); + var title_elements = $(html).filter('title').add($(html).find('title')); + var title = title_elements.last().text(); + if (title) { + title_elements.remove(); /* Remove any title elements from the response */ + document.title = $.trim(title); /* Set the new document title */ + } + var content = xhr.getResponseHeader('web2py-component-content'); + if (content == 'prepend') t.prepend(xhr.responseText); + else if (content == 'append') t.append(xhr.responseText); + else if (content != 'hide') t.html(html); + }, + calc_entropy: function (mystring) { + /* calculate a simple entropy for a given string */ + var csets = new Array( + 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', + '0123456789', '!@#$\%^&*()', '~`-_=+[]{}\|;:\'",.<>?/', + '0123456789abcdefghijklmnopqrstuvwxyz'); + var score = 0, + other = {}, + seen = {}, + lastset = null, + mystringlist = mystring.split(''); + for (var i = 0; i < mystringlist.length; i++) { /* classify this character */ + var c = mystringlist[i], + inset = 5; + for (var j = 0; j < csets.length; j++) + if (csets[j].indexOf(c) != -1) { + inset = j; + break; + } + /*calculate effect of character on alphabet size */ + if (!(inset in seen)) { + seen[inset] = 1; + score += csets[inset].length; + } else if (!(c in other)) { + score += 1; + other[c] = 1; + } + if (inset != lastset) { + score += 1; + lastset = inset; + } + } + var entropy = mystring.length * Math.log(score) / 0.6931471805599453; + return Math.round(entropy * 100) / 100; + }, + validate_entropy: function (myfield, req_entropy) { + if (!web2py.isUndefined(myfield.data('w2p_entropy'))) req_entropy = myfield.data('w2p_entropy'); + var validator = function () { + var v = (web2py.calc_entropy(myfield.val()) || 0) / req_entropy; + var r = 0, + g = 0, + b = 0, + rs = function (x) { + return Math.round(x * 15).toString(16); + }; + if (v <= 0.5) { + r = 1.0; + g = 2.0 * v; + } else { + r = (1.0 - 2.0 * (Math.max(v, 0) - 0.5)); + g = 1.0; + } + var color = '#' + rs(r) + rs(g) + rs(b); + myfield.css('background-color', color); + var entropy_callback = myfield.data('entropy_callback'); + if (entropy_callback) entropy_callback(v); + }; + if (!myfield.hasClass('entropy_check')) myfield.on('keyup', validator).on('keydown', validator) + .addClass('entropy_check'); + }, + web2py_websocket: function (url, onmessage, onopen, onclose) { + if ('WebSocket' in window) { + var ws = new WebSocket(url); + ws.onopen = onopen ? onopen : (function () {}); + ws.onmessage = onmessage; + ws.onclose = onclose ? onclose : (function () {}); + return true; /* supported */ + } else return false; /* not supported */ + }, + /* new from here */ + /* Form input elements bound by web2py.js */ + formInputClickSelector: 'input[type=submit], input[type=image], button[type=submit], button:not([type])', + /* Form input elements disabled during form submission */ + disableSelector: 'input, button, textarea, select', + /* Form input elements re-enabled after form submission */ + enableSelector: 'input:disabled, button:disabled, textarea:disabled, select:disabled', + /* Triggers an event on an element and returns false if the event result is false */ + fire: function (obj, type, data, target) { + var event = $.Event(type, { + 'containerTarget': $('#' + target)[0] + }); + obj.trigger(event, data); + return event.result !== false; + }, + /* Helper function, needed to provide consistent behavior in IE */ + stopEverything: function (e) { + $(e.target).trigger('w2p:everythingStopped'); + e.stopImmediatePropagation(); + return false; + }, + confirm: function (message) { + return confirm(message); + }, + /* replace element's html with the 'data-disable-with' after storing original html + * and prevent clicking on it */ + disableElement: function (el) { + if (!web2py.isUndefined(el.data('w2p_disable'))) { + return false; + } + el.addClass('disabled'); + var method = el.is('input') ? 'val' : 'html'; + //method = el.attr('name') ? 'html' : 'val'; + var disable_with_message = (!web2py.isUndefined(w2p_ajax_disable_with_message)) ? + w2p_ajax_disable_with_message : 'Working...'; + /*store enabled state if not already disabled */ + if (web2py.isUndefined(el.data('w2p_enable_with'))) { + el.data('w2p_enable_with', el[method]()); + } + /*if you don't want to see "working..." on buttons, replace the following + * two lines with this one + * el.data('w2p_disable_with', el[method]()); + */ + if ((el.data('w2p_disable_with') == 'default') || (web2py.isUndefined(el.data( + 'w2p_disable_with')))) { + el.data('w2p_disable_with', disable_with_message); + } + + /* set to disabled state*/ + el[method](el.data('w2p_disable_with')); + + el.bind('click.w2pDisable', function (e) { /* prevent further clicking*/ + return web2py.stopEverything(e); + }); + }, + + /* restore element to its original state which was disabled by 'disableElement' above*/ + enableElement: function (el) { + var method = el.is('input') ? 'val' : 'html'; + if (!web2py.isUndefined(el.data('w2p_enable_with'))) { + /* set to old enabled state */ + el[method](el.data('w2p_enable_with')); + el.removeData('w2p_enable_with'); + } + el.removeClass('disabled'); + el.unbind('click.w2pDisable'); + }, + /*convenience wrapper, internal use only */ + simple_component: function (action, target, element) { + web2py.component(action, target, 0, 1, element); + }, + /*helper for flash messages*/ + flash: function (message, status) { + var flash = $('.w2p_flash'); + web2py.hide_flash(); + flash.text(message).addClass(status); + if (flash.html()) flash.append(' × ')[animateIn](); + }, + hide_flash: function () { + $('.w2p_flash').fadeOut(0).html(''); + }, + show_if_handler: function (target) { + var triggers = {}; + var show_if = function () { + var t = $(this); + var id = t.attr('id'); + t.attr('value', t.val()); + for (var k = 0; k < triggers[id].length; k++) { + var dep = $('#' + triggers[id][k], target); + var tr = $('#' + triggers[id][k] + '__row', target); + if (t.is(dep.attr('data-show-if'))) tr[animateIn](); + else tr.hide(); + } + }; + $('[data-show-trigger]', target).each(function () { + var name = $(this).attr('data-show-trigger'); + // The field exists only when creating/editing a row + if ($('#' + name).length) { + if (!triggers[name]) triggers[name] = []; + triggers[name].push($(this).attr('id')); + } + }); + for (var name in triggers) { + $('#' + name, target).change(show_if).keyup(show_if); + show_if.call($('#' + name, target)); + } + }, + component_handler: function (target) { + $('div[data-w2p_remote]', target).each(function () { + var remote, times, timeout, target; + var el = $(this); + remote = el.data('w2p_remote'); + times = el.data('w2p_times'); + timeout = el.data('w2p_timeout'); + target = el.attr('id'); + web2py.component(remote, target, timeout, times, $(this)); + }); + }, + a_handler: function (el, e) { + e.preventDefault(); + var method = el.data('w2p_method'); + var action = el.attr('href'); + var target = el.data('w2p_target'); + var confirm_message = el.data('w2p_confirm'); + + var pre_call = el.data('w2p_pre_call'); + if (!web2py.isUndefined(pre_call)) { + eval(pre_call); + } + if (confirm_message) { + if (confirm_message == 'default') { + confirm_message = !web2py.isUndefined(w2p_ajax_confirm_message) ? + w2p_ajax_confirm_message : 'Are you sure you want to delete this object?'; + } + if (!web2py.confirm(confirm_message)) { + web2py.stopEverything(e); + return; + } + } + if (web2py.isUndefined(target)) { + if (method == 'GET') { + web2py.ajax_page('get', action, [], '', el); + } else if (method == 'POST') { + web2py.ajax_page('post', action, [], '', el); + } + } else { + if (method == 'GET') { + web2py.ajax_page('get', action, [], target, el); + } else if (method == 'POST') { + web2py.ajax_page('post', action, [], target, el); + } + } + }, + a_handlers: function () { + var el = $(document); + el.on('click', 'a[data-w2p_method]', function (e) { + web2py.a_handler($(this), e); + }); + /* removal of element should happen only on success */ + el.on('ajax:success', 'a[data-w2p_method][data-w2p_remove]', function () { + var el = $(this); + var toremove = el.data('w2p_remove'); + if (!web2py.isUndefined(toremove)) { + toremove = el.closest(toremove); + if (!toremove.length) { + /*this enables removal of whatever selector if a closest is not found */ + toremove = $(toremove); + } + toremove.remove(); + } + }); + el.on('ajax:beforeSend', 'a[data-w2p_method][data-w2p_disable_with]', function () { + web2py.disableElement($(this)); + }); + /*re-enable click on completion*/ + el.on('ajax:complete', 'a[data-w2p_method][data-w2p_disable_with]', function () { + web2py.enableElement($(this)); + }); + }, + /* Disables form elements: + - Does not disable elements with 'data-w2p_disable' attribute + - Caches element value in 'w2p_enable_with' data store + - Replaces element text with value of 'data-w2p_disable_with' attribute + - Sets disabled property to true + */ + disableFormElements: function (form) { + form.find(web2py.disableSelector).each(function () { + var element = $(this), + method = element.is('button') ? 'html' : 'val'; + var disable_with = element.data('w2p_disable_with'); + var disable = element.data('w2p_disable'); + if (!web2py.isUndefined(disable)) { + return false; + } + if (!element.is(':file')) { // Altering file input values is not allowed. + if (web2py.isUndefined(disable_with)) { + element.data('w2p_disable_with', element[method]()); + } + if (web2py.isUndefined(element.data('w2p_enable_with'))) { + element.data('w2p_enable_with', element[method]()); + } + element[method](element.data('w2p_disable_with')); + } + element.prop('disabled', true); + }); + }, + + /* Re-enables disabled form elements: + - Replaces element text with cached value from 'w2p_enable_with' data store (created in `disableFormElements`) + - Sets disabled property to false + */ + enableFormElements: function (form) { + form.find(web2py.enableSelector).each(function () { + var element = $(this), + method = element.is('button') ? 'html' : 'val'; + if (element.data('w2p_enable_with')) { + element[method](element.data('w2p_enable_with')); + element.removeData('w2p_enable_with'); + } + element.prop('disabled', false); + }); + }, + form_handlers: function () { + var el = $(document); + el.on('ajax:beforeSend', 'form[data-w2p_target]', function () { + web2py.disableFormElements($(this)); + }); + el.on('ajax:complete', 'form[data-w2p_target]', function () { + web2py.enableFormElements($(this)); + }); + }, + /* Invalidate and force reload of a web2py component + */ + invalidate: function (target) { + $('div[data-w2p_remote]', target).each(function () { + var el = $('#' + $(this).attr('id')).get(0); + if (!web2py.isUndefined(el.timing)) { // Block triggering regular routines + clearInterval(el.timing); + } + }); + $.web2py.component_handler(target); + }, + main_hook: function () { + var flash = $('.w2p_flash'); + flash.hide(); + if (flash.html()) web2py.flash(flash.html()); + web2py.ajax_init(document); + web2py.event_handlers(); + web2py.a_handlers(); + web2py.form_handlers(); + } + }; + /*end of functions */ + /*main hook*/ + $(function () { + web2py.main_hook(); + }); + +})(jQuery); + +/* compatibility code - start */ +ajax = jQuery.web2py.ajax; +web2py_component = jQuery.web2py.component; +web2py_websocket = jQuery.web2py.web2py_websocket; +web2py_ajax_page = jQuery.web2py.ajax_page; +/*needed for IS_STRONG(entropy)*/ +web2py_validate_entropy = jQuery.web2py.validate_entropy; +/*needed for crud.search and SQLFORM.grid's search*/ +web2py_ajax_fields = jQuery.web2py.ajax_fields; +/*used for LOAD(ajax=False)*/ +web2py_trap_form = jQuery.web2py.trap_form; + +/*undocumented - rare*/ +popup = jQuery.web2py.popup; +collapse = jQuery.web2py.collapse; +fade = jQuery.web2py.fade; + +/* internals - shouldn't be needed +web2py_ajax_init = jQuery.web2py.ajax_init; +web2py_event_handlers = jQuery.web2py.event_handlers; +web2py_trap_link = jQuery.web2py.trap_link; +web2py_calc_entropy = jQuery.web2py.calc_entropy; +*/ +/* compatibility code - end*/ diff --git a/web2py/applications/admin/static/js/web2py_bootstrap.js b/web2py/applications/admin/static/js/web2py_bootstrap.js new file mode 100644 index 0000000..7206cb1 --- /dev/null +++ b/web2py/applications/admin/static/js/web2py_bootstrap.js @@ -0,0 +1,33 @@ +// this code improves bootstrap menus and adds dropdown support +jQuery(function(){ + jQuery('.nav>li>a').each(function(){ + if(jQuery(this).parent().find('ul').length) + jQuery(this).attr({'class':'dropdown-toggle','data-toggle':'dropdown'}).append(''); + }); + jQuery('.nav li li').each(function(){ + if(jQuery(this).find('ul').length) + jQuery(this).addClass('dropdown-submenu'); + }); + function adjust_height_of_collapsed_nav() { + var cn = jQuery('div.collapse'); + if (cn.get(0)) { + var cnh = cn.get(0).style.height; + if (cnh>'0px'){ + cn.css('height','auto'); + } + } + } + function hoverMenu(){ + jQuery('ul.nav a.dropdown-toggle').parent().hover(function(){ + adjust_height_of_collapsed_nav(); + var mi = jQuery(this).addClass('open'); + mi.children('.dropdown-menu').stop(true, true).delay(200).fadeIn(400); + }, function(){ + var mi = jQuery(this); + mi.children('.dropdown-menu').stop(true, true).delay(200).fadeOut(function(){mi.removeClass('open')}); + }); + } + hoverMenu(); // first page load + jQuery(window).resize(hoverMenu); // on resize event + jQuery('ul.nav li.dropdown a').click(function(){window.location=jQuery(this).attr('href');}); +}); diff --git a/web2py/applications/admin/static/plugin_jqmobile/dd_belatedpng.js b/web2py/applications/admin/static/plugin_jqmobile/dd_belatedpng.js new file mode 100644 index 0000000..fa131fe --- /dev/null +++ b/web2py/applications/admin/static/plugin_jqmobile/dd_belatedpng.js @@ -0,0 +1,13 @@ +/** +* DD_belatedPNG: Adds IE6 support: PNG images for CSS background-image and HTML . +* Author: Drew Diller +* Email: drew.diller@gmail.com +* URL: http://www.dillerdesign.com/experiment/DD_belatedPNG/ +* Version: 0.0.8a +* Licensed under the MIT License: http://dillerdesign.com/experiment/DD_belatedPNG/#license +* +* Example usage: +* DD_belatedPNG.fix('.png_bg'); // argument is a CSS selector +* DD_belatedPNG.fixPng( someNode ); // argument is an HTMLDomElement +**/ +var DD_belatedPNG={ns:"DD_belatedPNG",imgSize:{},delay:10,nodesFixed:0,createVmlNameSpace:function(){if(document.namespaces&&!document.namespaces[this.ns]){document.namespaces.add(this.ns,"urn:schemas-microsoft-com:vml")}},createVmlStyleSheet:function(){var b,a;b=document.createElement("style");b.setAttribute("media","screen");document.documentElement.firstChild.insertBefore(b,document.documentElement.firstChild.firstChild);if(b.styleSheet){b=b.styleSheet;b.addRule(this.ns+"\\:*","{behavior:url(#default#VML)}");b.addRule(this.ns+"\\:shape","position:absolute;");b.addRule("img."+this.ns+"_sizeFinder","behavior:none; border:none; position:absolute; z-index:-1; top:-10000px; visibility:hidden;");this.screenStyleSheet=b;a=document.createElement("style");a.setAttribute("media","print");document.documentElement.firstChild.insertBefore(a,document.documentElement.firstChild.firstChild);a=a.styleSheet;a.addRule(this.ns+"\\:*","{display: none !important;}");a.addRule("img."+this.ns+"_sizeFinder","{display: none !important;}")}},readPropertyChange:function(){var b,c,a;b=event.srcElement;if(!b.vmlInitiated){return}if(event.propertyName.search("background")!=-1||event.propertyName.search("border")!=-1){DD_belatedPNG.applyVML(b)}if(event.propertyName=="style.display"){c=(b.currentStyle.display=="none")?"none":"block";for(a in b.vml){if(b.vml.hasOwnProperty(a)){b.vml[a].shape.style.display=c}}}if(event.propertyName.search("filter")!=-1){DD_belatedPNG.vmlOpacity(b)}},vmlOpacity:function(b){if(b.currentStyle.filter.search("lpha")!=-1){var a=b.currentStyle.filter;a=parseInt(a.substring(a.lastIndexOf("=")+1,a.lastIndexOf(")")),10)/100;b.vml.color.shape.style.filter=b.currentStyle.filter;b.vml.image.fill.opacity=a}},handlePseudoHover:function(a){setTimeout(function(){DD_belatedPNG.applyVML(a)},1)},fix:function(a){if(this.screenStyleSheet){var c,b;c=a.split(",");for(b=0;bn.H){i.B=n.H}d.vml.image.shape.style.clip="rect("+i.T+"px "+(i.R+a)+"px "+i.B+"px "+(i.L+a)+"px)"}else{d.vml.image.shape.style.clip="rect("+f.T+"px "+f.R+"px "+f.B+"px "+f.L+"px)"}},figurePercentage:function(d,c,f,a){var b,e;e=true;b=(f=="X");switch(a){case"left":case"top":d[f]=0;break;case"center":d[f]=0.5;break;case"right":case"bottom":d[f]=1;break;default:if(a.search("%")!=-1){d[f]=parseInt(a,10)/100}else{e=false}}d[f]=Math.ceil(e?((c[b?"W":"H"]*d[f])-(c[b?"w":"h"]*d[f])):parseInt(a,10));if(d[f]%2===0){d[f]++}return d[f]},fixPng:function(c){c.style.behavior="none";var g,b,f,a,d;if(c.nodeName=="BODY"||c.nodeName=="TD"||c.nodeName=="TR"){return}c.isImg=false;if(c.nodeName=="IMG"){if(c.src.toLowerCase().search(/\.png$/)!=-1){c.isImg=true;c.style.visibility="hidden"}else{return}}else{if(c.currentStyle.backgroundImage.toLowerCase().search(".png")==-1){return}}g=DD_belatedPNG;c.vml={color:{},image:{}};b={shape:{},fill:{}};for(a in c.vml){if(c.vml.hasOwnProperty(a)){for(d in b){if(b.hasOwnProperty(d)){f=g.ns+":"+d;c.vml[a][d]=document.createElement(f)}}c.vml[a].shape.stroked=false;c.vml[a].shape.appendChild(c.vml[a].fill);c.parentNode.insertBefore(c.vml[a].shape,c)}}c.vml.image.shape.fillcolor="none";c.vml.image.fill.type="tile";c.vml.color.fill.on=false;g.attachHandlers(c);g.giveLayout(c);g.giveLayout(c.offsetParent);c.vmlInitiated=true;g.applyVML(c)}};try{document.execCommand("BackgroundImageCache",false,true)}catch(r){}DD_belatedPNG.createVmlNameSpace();DD_belatedPNG.createVmlStyleSheet(); diff --git a/web2py/applications/admin/static/plugin_jqmobile/images/ajax-loader.png b/web2py/applications/admin/static/plugin_jqmobile/images/ajax-loader.png new file mode 100644 index 0000000000000000000000000000000000000000..0973ae040f5069c91f145fa872a2305946527d8b GIT binary patch literal 366 zcmeAS@N?(olHy`uVBq!ia0vp^${@_a3?wz#owI?IL4Z$)>;M1%Kav98@9{_i>g6v9 z@(X4VR5Er6O)Kx1xoY>ByYJkzzRmAFpIDN;bH$2_7L`|`UhiF^I_ufioUB=sI*zz23*9?(=HcnHN1nfE`&1pec9*8h z^U_$;vm3IeB(={f)Hh?6zO0vPm^qo{vqbl|ZbjoCIR|)_KkxF;)MR_z+T}Je!fwXN z4XSea0yV}HrlvSgteBC`lHb^IndQitly-~RDhk^?c3*rp-AYkivE*@*@BS literal 0 HcmV?d00001 diff --git a/web2py/applications/admin/static/plugin_jqmobile/images/icons-18-black.png b/web2py/applications/admin/static/plugin_jqmobile/images/icons-18-black.png new file mode 100644 index 0000000000000000000000000000000000000000..77392864064e2108fb47b1fef0a45049d9dcc174 GIT binary patch literal 2152 zcmah~dpMK*8y}`d$t;I9I&2b36vZ~YSTp9;)ND0}YL>BekW;+<2r&{lM#z#PGcP&D zB!%>|IZR?G%L^KtGU9O-%vKKmgpz($W&(6o_k-`U8N)&7Vwi1S$OksDA;V zcn$a;paKB6JObAc9UTo&7yLxc8i1Q@9asavwe~4wOKm#vD}n}&wzk$^SPhlEK=5U>+**!mtO$N#j+wt& zJ=w;Z7^u3=aN6tq)u67MZpohD8Xn$dHqCIUSV#VG4YrBE6z9lCSSAOLOmM(c7L57Ju;0d+{bv`M|X(#@n`Y z)(}4Q5^D~ZZ5K`FI_CA`=@0mIFZ=Z6Y%PS6+-^jgZnX(+}mnbO79hTf!oC|NB=F8s}Dv8)biM1M%6GH{3aT|R$eGYG-i>tfY=zMTv*iFI% zSBL8loG?^duwTz|_N6Mb+)%~&`+t&}Jg^6;RtQkKxsF53=) z)y}2(fHpK!l8}ataJtz-ws%ts+)@;;MmRQ3+HJsM^Fhn;b6uNbAlu|rPBP0iPE*r~ zY-MUwr18#@_IX6uydSbB?)sgS_%A&Mhrs9V#(V#1nzdT;ho8=doWY6F8K+3^ho*@3 zQwGW>+naJ`B)dooDp%FC;a2Jzt(+ry;DWrnG9frs2fZXMut7=LX7biVL)Q#nT{-7P z9i%(;u_Y%v1bvL|`{=FNebiawcS^!&oOhqP$1GQ)1fWg@sWP|eE#Nf0u%l^) zF)a;K-tW=kw!`s`HW9aNHbI8-l^c{G&6m0w`FBSwZ+)s)Bd>ILsc#@<=g_FQ?B6xt z2D7faamnE?tzHGAnzkrYV)wMbs~LKBe;M*~%PJKYwQuXRGi4_z>!?ClHF`M}?zBaO z*9iv~v-O-I63Q2r!FgqrgW=AhFlg55(Jvq8x-d1+2WatB#Q_9HoJtU5kD)aNjf`x! zjuki&QWIfuRHi&tx}~L00*Tqq*_E0&nwDfIC-5C*8sp0n48}it3LNT7I?U5Dvvr&E zotEaDdkV;0nDiTiObBvGlLBcWAI`k%)%)yoPpIAMx68j(NSPR80=6my==X`ev8x2* zmO(L3v*}5HBi}8uTm_kO+?;YCt%o-zTXiOXzhc0jDI>#P+s0%ir2^TD;<88N(DY}V zuG-}LUjnQO2@N({o-{<{5ch~W>iS}Z3BLUq?_^6d=DGICw%Bqog=gBOUTMw^`8+)s zYhplH!f@#3Wgj~HzmH5!$xhK(CKN(Uc??y2j8jKWl}CpJow;8vvKj4-wr&`*&~*KZ zu(`Z{Nm8q{8*4#2ZRf9NSe?5B`zraSxA1sU3uHqVqT-!;oaBC&k?=QDlzKMlwOL8AWbGm0i^NjV3(DWQ%A*0tBvzxd%Ve^dsc8|p&mOfYC^ayZ@)RJ_;GsDXt;tk zH{&yxbI|qNNU(r#Df{8Y;Wsi{o?MOkf|%T1IJ$0jB6BPW`1OE@)+GD`96kJRoc+dT literal 0 HcmV?d00001 diff --git a/web2py/applications/admin/static/plugin_jqmobile/images/icons-18-white.png b/web2py/applications/admin/static/plugin_jqmobile/images/icons-18-white.png new file mode 100644 index 0000000000000000000000000000000000000000..f4e6787a124eb983017b748cf242915dd30a48ac GIT binary patch literal 1958 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/admin/static/plugin_jqmobile/images/icons-36-white.png b/web2py/applications/admin/static/plugin_jqmobile/images/icons-36-white.png new file mode 100644 index 0000000000000000000000000000000000000000..3f342ccbeea0d794eb1c36447193ebb1bed918b5 GIT binary patch literal 3746 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 Cu)~)C literal 0 HcmV?d00001 diff --git a/web2py/applications/admin/static/plugin_jqmobile/images/iphone.jpg b/web2py/applications/admin/static/plugin_jqmobile/images/iphone.jpg new file mode 100644 index 0000000000000000000000000000000000000000..92fe9394f504e300cecb582552ec2dcb2353723f GIT binary patch literal 99964 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ÛLgYCc%BpWr!__1C^O1VO(b@~Ul<=(ZM z>yoK0BOk}ZzRs&Te3Ef3lsM2Ls-;mrGavWb^y3B;R!1s4n&%DP%^PHzX_U|M?R+iA z_=PUZ$(;eoUG_WPr-Q$?DD;mbSt?1l-^<2q>hd_FAw^24ShCk=`eqt&_U#@^W5(1^ zTer?edEK%Y^S+?*D&m6L)u`ClrZG>m_Y6!pIK-h$-?z&zyNKHTZu3FiY56Bj^DA)| zDWo!+dpatSZ_|x$Ze~eXKELWJ=in~On7@^AD2vPD7n(G$j^dMYVNB_0Zt9_rxBTwD zTO0j-?^N#dm}r~(2Ss%3DT~4B%{xB|x|zK9Wkqk6J`}~o{OE`~M|d2shu^OubIw+; z)N%}cm`uM&X8NQ8fI8pr$ey$_yyb1VT*11CGJW3MSf2Xy#;~dU#{B6gH%8{)CTu!3 zD><5}$E}G>NgvQJ*OsHTq*(7=zMr*|+ywbw3|EjTq>cSq5Ku9F`dhor4`#4tTHh{L zB+DRe*+M+vrOHJ=c?T&+*E9Mons&ly_w5*w%x`iHQz?;N>%DHd1%&twsFo(T-?^9A z2&h5T?)Na$Wo@d_rHA-979VLMA6f1zgqlS&%lrneY?TtlLOqZ+%8`E&Fr!}AQNchOeOJ~jrSj^F>V*tG+3iS4B$!&(G#)&JgB|w~L!EID*V*{V)Z;OeF@pq7qBJ6Od9!#YJ z$|qZRO5bw0VzaA@v<;d}x@8CajJMwP#AXQH>CMwG)*kqsBNO{JoV3H=>uvOa8-;&r zUX2bSk9Ow{RC3K;=Zjj7j!~;xi{Zf#d=c=7Y6)8q?^7I`54X@$N~(_*SzPDz&TOao z4?ZgJz{lWXZN53NgM8=1*J#!LDC>CYoC=iaif*?UsmNwm^D<&8v)*Y&BU62PSw^-X z$ht#Cv!ZM39Iw2vl)jL}t}ApOw%9sB*_V4Gy461aF?WB4U!$BS2uV*^x4vw*eBW}{ zS&f`?Xdop_xz^y>zu!nu#L+d8grEaCNokDgr9$QJBlI(LNu=SnoL0pyE@g@L$j6d; zGzUNO*ED@=VOL^9ezTKwU>?b4Icu2kl$IY7f?CP-(SlWF+0-X*1S2OWOPS~S%)`u~ z7y*6BbHU0qiDhp%)|!w{!t}d1A$8%6&GIX=Q~f_9Zv=g*N=Y~L61%5R)5W8e#UDiG zIN^imO418iuU`K4%BF>&c28CHMsCrVV8%;`Q`rF^X3cBYCre3@ql4Zy_5IlA)h<3z zWh5BKI_MMlI!84&T+7-|5}C?A{BY!zqDG(1TiUc22!tfVvvdyhiI@QI(0GADss6>M zI~T0KQDhPG?g5^L5N92eeeB(Es=Xm+dCQ)&r62Rc zcBMu4U9x6K?-=VZfZJZq zITieK4|sKon0xXr#!~2#!xGoF4&Gg^kSCoLTmEE?ZM1klh-R!K3)LujA zNM%Qp`@s3l`E+T7x01`Mnot1?06%GsU!hOf2mVB71g{dzQ3(FSvFoOhiZN4J&L7)p0n z=ueay!Xy$Y+yBRhqd$rVqMeQ1Y(aV}5dPLvoqC2XS?#bXY0OMTuR74SFXzXi_2Vt= z1XM&i3(bNDY4C5Fq^)Fo#Ol4fAAxf;zvqMfHmrxn2lkgK9XZ%q<8JsHP~|#=n_@DD zxF%3K*`V{o&}~#((uR300-pQXX#J>G|DyPTZ{s5$B9pB{BkXS@!_ae(geLHwc0(RC z#wp%oq(A#dIg|auKW@eBQWAE>3tiSPBk^6Apg~Q}W7dyxP5TwDxykuX(odIYv)(?Z zam@af7b8=2NseM=&@85ouNAn>Lwy2e!@7(4M|a6?wOp5>wp`15=tmc1AS>PZh3{ zl(Kk%b~3dEnIS;g-2(H_zy-jp^X+>-m1G3Gz$R98U`LX(eprZ@eO-ejiCJvZglP(R>7N}4Trd^|8VGx(fkMtXvaP9V3_RP~&F z*2W{auN|fXVmj%~+0{u7aX?G;TZJC&&wLS7z9l88%ulEJpxKKH@kj5N8d^?T)+%gS z%FNxpF0kVv3r9|&X~p5S;tn+cNPu9C)+hZQwzyaF{xY;Q(TdyZb?6G1DA22!G%!5S z(&tY&nFikJl=~Fm@!`f7S>@v~Yj@jMcpV~Y#T{OLG26A~KVh4C*wWZW#YEN7KJ>t3 zqxDt(alGQ|hG)h$G_7L1R`CG<`(?hD8%S1OdN-904ZQpBh6UvtpmzZrq6%MDA`hGx6GmSeCqYyHJ*%xV#w@oKY7jwjS3UQjv&+jMc zmDh!Mt3%8~h3I~$@^6rbIb6O51V|hai#IA&jPIyfhtHO+(29F$i@O9gmrh@JBq%7? zO5Ts0Qf}Pp_|=8PpOXJ@u(`da&T`84BDJX6kdy}{N`@Uy7bHVBiNE;gh(xzqw3nN^ zl3NJl{d8G7nA0mqUziX)Lyzm5@O81$dUNK9nh?KFDsTj7M*DwGv)NKEFO*XAAoG!;S0Z9RB^C{+w z#XM-3_6$TBNQX6+b5wtiKCPNUdPe2hWi=Pjb`JQD*TP#LRk?J|jd~phGPd>f&q!n7 zc|7a;q&^~k+gyX)^yl7Q&nC*RlPo{Zy&;<<$rrZ#3#K%De`L!L%=6&hz9^Vh=Y5cf zlYX&mH3C<6fAcAOvQs;fStC|_9TF`DX(XcjK)(GzA(#FlhZT^IeM~(ihUvH4PW7-X z-M17ZzH@Mn)4Q%N34M|(=GcykJW-V|?o4;N>#5Pg!`E(B%7-SJ3%NdT8qNzu4rVXD z)bQAA6J7M@mFygB?+D+5ud*et7z;k|C*ikpnZC#uU;kcSG9J*n+qzUi5+oKE=6rqnfW)7nN*?vnsJFPbMx!v&g=Chd9vZrAsA?~xSC-gb1zpD0($g8L1 z52%>n^=!E_+uOFY+-vZP%iIZ$MEa+$ggCKJKl>fbNw+0Y(cN#USYHoyVyOc-S?f3) z@x$5U9!!Zt*XQlDi@Mqq;{EuHVgPjEI)sTriwW&ZK= z?hm(*fvEQ23qz$u&)a1t$h7CJ3;}IsHv!39%#(XP)e--mt#2h`|6B?3p9LCX$&wm@ z|J9Ma>^1DAdb_SQiS?~#rNE7{bK*$pIyi} zwfI`3&5~e$=Ptn>7bMP9#}7zIYmFS2vNufd`7q@xb>%6=dGu$+WoTxWo?S5a2)}k= zL;P6|EnJh|x{aYQH-WFTC^S=;M3 z)5_dsBQU!g*6#X+m^?$!hozJQbK}=#e+Dmy9Unq)gL-Xwxq>8ppCMIz-=Q8}ynW3? zcZ>rch`jn53-mrnNqFcON>N&Mu9VKz zI4eRWYax~t7Lh|3>``R|pJPDba9)2$pxAF7z)<_x2a3OPK-et44BI(A1Is1T*ijy^ zDrV&tyGOrF1f-qHAsrRq3{c#qNlz+dWoawUAThB!lg7@fSUY~3(`*e(e#L_20 zO_Js~Z|d1iP}=;4e^@mSp`Hf`1gd+XH8j{mW#m~$Ya%gx&0AK?8b2obpb&3U-TIzb zj&aZ-?W(!^;d>&)!VUK^PMd6ID=S0ye3`R7VW=_UeVdI=2FB4cO@=KtAt9sfi;7O% zIA2UL4fsdlfTk*tl^WnhI-xlC)pb%RGf(hRwMeT3+D?R0QARNfYmQ3e!#=)+l;cn( z;6GR9daTyIxSH83b^_@dB1FKyl}pL@=o8;f9Mh25pOU4@FS|(2EGuR)xW$-$ww1!EMf&e=7A{(JzXa_3 z7vAU(fqTO@f!msef2wlL=Z^}8j&DtgV3f4Dy%tgSY7N|7EOmdSJ&U#1{x7-z{#>k^ zgzO`QDzKTTL^x0WBM^gj?~uNF3ux(zhht6bfx`IuchR@U9DHR7elAd6H8r}TcAoOvR1e4QpX`Z z$L{$#=#vs1YbJKbqtd-}_z67t5*C$@MXOz+7-IbEc#sY%m|lJXLP1^bQ6C0=kI=dP zCv!#9bLAlL$vx-n=dg|SLyFRb3H#ViXjuk$>b+Utn`7S#>Z!4lme3W82^m6yL@OsO zI@O{S2KkO}9%q)lryhX9f?xjKtz2Qmhu$al*Vu?wVmWZVA`9;o28h(o#no3uL!FLz z!TQY9lA^r>x3%7sau*!@E!f6D9FdQ5hD~LQKPGrLFo+~aSH1>R6vjlRdaB^PiAIHe zFt@kY^Nq}yEqaQZHEg?L^fTEts4Ic5=AJu+-&=kxml|)@Ug+=_lckvtqumu*bRydn^i3f6|`seB!z~2dcRVr%bdyAujUnZUVA)- zbrTbvnvX&&?l$EqeHhI&p*`C0fMxJD{Xw@>0FQav0)wAk4`^SyOMw$ zqko}EeB~Al#l8(T?hoN-Hnl?|Wu8Bk4+n-!qB^rf`>*+5KkqL8c)W${l#pn817nq` zt81eh6XLP8j%}nrOCPm0$U!9~SMoB@c^m08B7a`07!@ri89TUXHU9|(+%fF(#+r@_ zaqsC@*^Q?1Uv5Ney88F{aSlaOxWHt9l^s9ry0hCwA)M^QuJR1L^7Bq~%Fyn&#JST< zZR|lKF%Fj0I66c{6zDZU>mPrChl1RT&6sokfs>%jMDUrj^GRPFO|Ov`QE@ifkT9Bd zlb<7vt+-8d#CYF3udRebL_##PCKEI~HGWbbAX#L&mo?phAC* zk%Y8q0oRuEdZS`yWi@xJyW20d5{_ZGT%+U8n>ydU4H5gI^Lpb-@z52+;1SYp#DcYP zh#-k%RpW13&r6zDl;q75<~qY*w$jhmSE%$+Qw)Uj&rW=7n-UqZt#jW~0PUTf-|rsvf7UCRLoq|xZ|~U?6rucaO@OuX7>oZETP%DG7d_2dyr+QQi?DN47jOAu@t{1mF{%>yql6C1Z*f!;W zH~j9NZvYW$PfpJZGI6Lm_g$F}B|dJ1-Sk5hO&Cp*~=v*r1-Rx+h5V3}=6s4J^BaWk1T-lL_;ipxHLUt#>b)|&wfqnC* z*-&lkE~wF>xbHhq3u}y{;05P9c$rOtl;gGs;V8h@plF~X5s@C6)K}$eyS3hyjD6={ zIM%5^Rzu;53S+<{+l#jhkTL~J!R?D1M($#sn?FNZqZD?qgF3+0M8 z+pfyFP%tntYj#DOpDSRZ_k8Y3-9m1C=4-b!e$*CdedNPHwcOR#$&D2szE}IO+GlO3 z%dZ#tso0C^C73I#LIFap(z1Mu_qB}4ihYrIrh`Xj2lP2|4D8ETv~Tn-C&ACm~>nP4IHc#Y?hUJJH4(yS_+i6nF;*7oNSA6K|YZ zp+%?dxZQBvBlD@!NPCik$C8&fXYwRF*RKUXV9`Q71_cmwvyG146I1&PjEtRaX5(UW z3gg!ApO*aedF`E+{I2Am2PQ8G<+N9>mM7x#Rab>%#_p4gO3J!n>t~wr|G>~668uD` z3dN=PVrte-HPLt6zMOhB{_< zN=)IlrIZ@}fu^(0zu#>gF`oxkjKJ-!+IUp=gLG2^6L7|01}g|yy%sutSQDuzukrk0 zE3hUPQ~$Z9go*MLBTWu_f4}JC1nzH~{rK~4hFtKPT`lelb(gui-*yDo|L=gPM;zE! zcR}PVroki#Xx(Ag4+rdZQ@R+_3DL0DX_M89_0;EG!w;^Tp4JEP2+00lSH;(Kr;y#J z_o^cu!D{a!LZ}3h zw+Zk*?KKU3S5KTdI06ANNL%^Iq9|doDCcivz-8R8?=5&02d6-Y)?Xm3{NR@V`Q+@Z0ci4UEIJK_ zC7sjvJbH9ifc|4d0#148b_{%W)BiY&@#+Gbif)Ylgbrv|8#{)?#KTOZoMOW3g$YW* zN*JM(Fi2S0Vn&n;I&Qft@&C=u_7!R?UA}f$9aIUvu>spT+%fcWeMC0aJ4E=cZ*l(S z>JGF4V$hNt6FN*3Tih^KP-sI40vhEcoq!06_DYUox}<8o$(>(&Nc|yRH_0v?V_h00 zX_MUL*v#03xen@qOZcb6o#h4!Pkgdfjf$y0btT&0>-l+FfT-U*XT(CCn4bsMf72&8 z<%Z+8e6RP=h5~Fot%;kF{nFIkM%hzGqf74rEd#u83!ql&eY+J{%J;-e56m1bjuG8; z{Sovz2}n)4wzT@(kwrnFy$1G`u!C}JYRl~aKm3ak{rLVZWG~g&?k6Yk4<+r<84)hrK(e zb@!H7SLei0s1&X${IvIZjJd|V&xr%WP>*@m9%x14>SV`q-UnB~U8Y9tL{YMX!ONMX zI9GQnKbPJJw9Bm=K;2sS&H zV1+F+tOx<>yBLlaD1q3X5f#yavGW`bEJzY4fMTyg=+*d) zZx}3Yh_Bxtd!zeM7c__ZU{45a@9;wq+XRYKJGcxL6wm}RUHx%pi3Oi5n)OW)HxvE` zAn;zqi*B60u;=P{`t4F`m{ir2=YfLxoti|Nzm42G9ezf4CRFA1`+4}9-1R+Qw?Z29 z*Sxmyu3ogYp-YFGbE%&kxe_)=7}A7RM5ufOMvd_7L|Cx4UVsv@{Zw$u7_IKTh!Jb| z3M4*5RUSgzf*5{@10iAmb02V)w|O}v?>!2K>8&XL1xg~jfP9uA%mHTMfaAgcQ#XTh zLejjLv(+*r?zdnIVyzp2Ci$ihF>8UlqWE8W-t&jF$7H@{a52TXiJZ0A4xoQu`vc2A zT!^ayZuNia%VT4tCWBauQPh&zc3A|K2X^yupl2XSP=A^FU;2V$%*+?}lxU4eDxC6B z3^6BS_eU@c=$~yS|D`85J`Eq?Srg(pCXmse|A{>RsT(-;Ou06b38@Z8V*fu$|Gz`h zGRgLrzaGmG!FIS4#_NT+{i{rJTHjONR7*N^4`pF9-f?FJ(0ldEM9@03>{ENvxOY5Dxz|I~EzcnD+Ss1Edh8VWTm~3fOd)pP|fMjvSuuXTG zk~N*J2U_JmAH=u9&XSi1o0U4}Xi5N8E_VX+2@V+NaxRg0Xx;a9%>y#OA`u4(0 zmTx%Glh9As_P{cH{PR6MW9ZJ}t813C?xZ@)hn zd%|yu5KiLQR;|>2PIUg%U!l{R<_)56bWi|&1-(y;H}oXxcY(!R?JahIn{iA$cH8d=}pgz3c3 zI*J{I`&T_4snLc0e()?!AG}fV8j5Rxk4^52r z6}1>OJzTowHzQb}0gLMdT~Y96EE2!YGl>4NL=Rpcc9a-?2z&(5@kJca<5wAuQN;tK0-~ zh`Y12{;a$%ZP}%wyxSmfu|fxYectAgZS?8^GtGY+^MiwG1V?D_5s@1!#C^YxeRTw> zhV(4r%qdRT^o-+g{XNZaArXx%#PlKdiPmK^$r-T1&dSGyxb_A5;+!CDQ7=g0b7Byy zGm6od@kFBtoa2&k_%fYBxZ0pxazNm=Y8bFBNspR2_ju9m`Ud1+vijTp=79HSnLb`! z@pnLqttdNCtgbaeS3aA>S3x$NaJ$-piVQitYi|=-iRJrL(J|dDM+?3$)@~?O$nlFz zW3xsxR*ag$$7!GTqg~5X{xQ_N(@>sl+*Rn=n2?ss?)sp`0jYy~tx+&99r#hZTd zOVg92wbSw(uWGY`DB=Y>&y>+_O?R}w?a_2dBU&;so?A9unq^g8nclU0wZIF5j7 zf+gGZdu{Q$V+6Hq^ETQc5U$Tu|9{R=Z{T1*FISB<_5S=CvmxR}&;Q2TdxkZYes81W zI96mB3!orIMM0_3m6qSAfQX2VULqn=LWqd;z@AY7=>rM~2pJ0^HByq$qg3flh$KMh zNC^o+Qb@Aref+)WI_Em)%X|IX`5+%mxUx6d&sz7o*S+qQO?^?`hux}%+!)OS!{HlI z78Y+mlhun{)eIYkyL;~6z*d(kPk?(P+tVmS<@m(ZMbq7+YR+IFHz9L5daUyYe;<9g z2aVND3rjkT*Eu8L83>7UGb*P3H&^-CT`N99oB6ZCcO$yaU2&93k1vXG)p4)JX9>Jv zN}X$Rt^rNWV>oT6|1~@VUKgW;wl|q0JUcjq``EEJCqu1u&cDP}e@Wgs>{T^p-B9<* zKR<_mmX;2yXUT~gp}VIb%%RR%S+3nfGcHw@HZ<8DiR zm#PP|=SL*0%yYWIQCeC}Co#uGs5%GO_vFnBqg`hv2CpNHOjTSfmjY$3AF}Yg3-n@; z4vxa>r3vDf*wzm}#32L8^RaM*{``;Xk`Z-$;^gf5Z#}xP{=AztAs9j)LGj-6og%;oh>$pYD^sUt(+9L~5Y;wlju>wKc%jQUKoPeT^}BckW`^7(bO%fq=84}l&-u7xf-^{Q z?nF9J87M)ZP*reLU7*l>L#Oxw)4>U1C#TPa@X|W~)&T!LkS8ZJ{;<=Z5uwaT5tfRV z1cBU2Pa@xaTCmlh9MiOnXZinG9EMR`2q;)53gv9b)6gT7aI+x=PD!TpH^aX^_5jo> z#Q$uAT+74k4-+~Y$pr-1+5+_r1gjlL1w7k=5w|$hG5pXLe0*NR z;XD=TrSQsiCX!5<=aqLduzO=9YQibK= z?3=XDi3IZeI$Bf!63Qb6CqwFM1l)P`F$mRNsHGhMZvg=(xYl2&;=eaeV3PLeqwzd~ zVyUNQuu_d*Sh*Hz0`&^^gQ_grm{yMUc|O=OrEC`Zavd4ONK6D{5)T#FiU^{M=*;1u0L{V zKIZhDzYH%KXbMZ$HDM#v3vQbF7tO7v8h268#7jc#WIjffPUe`5JKbBg-Z+KbU{%Mjw!qt zIva{@w)%S%uVcTqlQVcmDBlIEWc58?Y?_)-De-CH3)^8Wlx!%~Y4|O1U0u}Xd;#tR zli6i5X6Ph+M+|j^Cn0S9=O=4ZY@H*SJ)s?$*K2)#!r0#}dYV}p7ts?f8ELI{j~GBOn8$BNbv@ITa*D>Q}XNArTerT1uN@n za`|1O!3pcm9u>g6uG_cf8BwZ)(jpnMq>c|S;BzvbGw@D4!4kzfe!-8L5>(%u^2dFe zF&f%4)HE=5_3E%0GFWDmSKKEv^)^jq&4}S>)1?TEmWQUxVqACCkM6zT6yfK5CWfcdUbTIH=)!q)Z97 zSl&$6_k)Oj3{0Q8GFli+1JJqpgW8HG#r#bII@x-(?!;|0#&qgFqqzpXVscu`OTNAQ zC{i=$jL^^@UIB>J1W6@4J*)pYozjbV&q> zpW50__cb+C(}Kh%6b=S02K3bAH-g~ej#f>fgb!+S&jt)J%J=+kswz@TS-|q~K6Nj^ zoHT1jP%IP!PWkN)k?)S_wAbw50d#K^81Q&orNco}5m^21>jI zy^kca0HM5?#mfXdm2{k2t4$m}XK+xpADpd6P5+G|1*xwn{!xM`KY@D`uyQ^nT66V5XO30D{_y~rtdf{wqf zYq@w8nT|7I2VGGwTS`hBtg}G#TweO~*Wbsw`tEDN6eleU_-P+0}?60A@nEd3R zXFf^6)Guy3)}AL1q~qrZeUhq<@{eN1+x1v(zpnj~VZO_KUE)Ynqf@eW-*aKO);#id z}9!_=2Mw-TtuutA{s?471x@ z&(+wSA(q~>Bg$q}_#(VCc|R*m1l?yZJ3&v=OQEU^#Bb+~Tc3#MQPWP}j03{<$oXYg z1y4^?=Wbb`RGIRWMY0e%PT00aiYILb`tBvChxsLF>skbAlSNek>;5~y}hc_OWlZ_jOmd*%p z?j>;|+v(-5V%1Cj_^zQc1oL_>oy&Bs&=jwe>hUdxL{Yf)a16n?-^|BH34ffjS(y1? z44ll56x{HF6YJ^fyIOLcfvLww`gN$jScL>Qy{uyXM;G7h=OIU2Um9loP5zw@yVCU1 zkf1?)j^G_WP~ee3)v%?_pY_0=lEJ*;JM+_lU(5Vr;fsk|Wdrs%-THCKa4?9=1f-d;lAlH0HS#0%NP zO$uh;SI1qp>Wa6=ak=0zjI^JT0=-5TA5$5+Q-@wl+v=vYcyU~WaaQi0LFftanszR$ zH%zyR!J1p8C)ol0LCK10| zDU^3=Z95)>Mk~}rib&y{GKk^7{IynP6r5Fm;Vl6+(hI(87qryXgU=0pu>y4EQ{wCJ z)x6_Cstka`4}|i&bb|Adqc>_tUKhN7wz<2V;8f7k*XtuX_5V-wzX3er9sp|ZkvTks z5jVd9IbmXg(gXa_K%zbEE(YS!H{Xz(Zs~9up8a53`zXkSf1!xRd8vy)ffwn^C6*8q zt+g4vX!ztNVqTd&3(7VAowl2gxjj8UWE=tL$eR3X;d%k#IELq-E*)BRZvP==_Fi1S zSkdMj(~8SO9|=+13_OKDiujX+myQ!|yl!66kY; z%L5x*_cVrNCC#i-TZb?2Hzhr<#ryL2x7;^7p;g5=C&(#{6tfxasq#wY89w@kWo-yf z52XQ>I)NC;#br1qMe0pbWPAMY(2;$00ffs>7)=j>T;GDVuma*?bk#DKG>ny5nvk|l z$Fp>UHe(CuPQHe=d6oI&>Lcl4>xxoSf+!}W&5(>b)xAzXjYMu%gsjX{JRwgOZOcOe z)tpkDylz!v>-bu|4#ews#P4S>H+HNecC?(cvZ7f`n|{h3xip(*wgI9Gjyfo}y;xlO zW^psRk{KvrJ^}1)UZQJV(_8lXh8q_Ly>?4UrShS#1^gY?liL<-*`f-6gHwb5Vle$Y zv7#Wm23p)@6^r=|l(Cc7itG~&x#cF>wr2hL>=9$26O|scKg8xrliA2<#bldv`<1d#F!$; z?$rpxzxULQD!BSm>ZP6!rj+PDbrx8)jvLt4Cl4!Xhf(gWD@27iug&$8Cs~*#9I#Ay8b68_21Vr-Sux}9#FGTqKOX#A1L>k}9LYx!1e5lzgdH(EdeCw?D9f=WZ z3Sjv@23Jsf`Y`Von;199jg{^XO4<;U-~lks5fkbFRZSfxJALHG`8=f7#w1`KB-7Qr zs)fen2hf2=6mVk&U1sz=OWx&^e6IfBNs>@`>~?4tWq|;L2W(4;&rp2S0K&@r%@dQC zDJQ8!Bl(=rDcVS8&-x``x50%*2`5JMb{t3P;pWJmW5BA-X8O%j&zdmG;Gsq=uef8i z(cAW24!_tb@mpferJ$Qiy!f+s9R}d@$T}o13 z0@dB{gMkdIr>SpJGcer&0hIYN@4C(f3xnG5zS#X*?efmehbPwk1?WY_HnreB2@8Kp z$o#1g`ySJs#3cV?$=>!|pWN$L35CY`MQQYdQz$J%zno41x<6*&Sz;mU$m8kL1;l|> z4O!vM&QXyjiIRunpXSBAsZIDq(UxUPnn>KKKHDT&8_fX8uHJd4I!2@%` zbmYlQWDAA1mk9~yDK$2H!}4y3ZHfQw@t4qo%OX)uJR|mwV0La8zjYcVs)cLch+g9^ zhM;A=zJPv?Q%h;z-j~Y;&_&=2gmws8vE^q8=8)0gWL|UlZ`7D<5z2y_0Bq88LR1T$ zd;L2?tN~OAmni&mY8Ro&zmQdH_;gEMAUx@8EroIlM88?UHyVWdpiv7z`qZGsM=6tY zVS9iM0oWDmKpY*pwXF~P30r>9TzIkWI4%vxN55Q3Q_EZ&JDgQMsCA)@s zWF{)}9!MM+svz)>G+(-S{UASwPZ=lVcHe<6d+H%W_LKU{&T%5>Qhh<;CePlUKikFh zJZzutaOL`)Y-DW|Pe>ed8dDWS+@+Nv*BI-yjTX|ewhCDr&kGd4evf#UG~*T7){uD- zm^_94efaD?Kad`o2)Nb9*kk72WUj}ijNL;`x3&qZ2EWR=ZgEZ2k2C|G)c*o~%I>pw0$-X>!)(QiqF zxW1bdd-lfs<7owz-_^ooug`nJr$!r{;7C}S-#K#?Z}p{QW7n~0Zt;we0+bLHRF-D5 zjSLvv=;k|-ZB8VBIfROK9mKR<3TR7!E1`Yr%Wx@}t-qcgdHHIUsZ138+x^nUq<7~V z_U#1UklYu7KL0`~)O3N}_sOtQp)aVQ2_c?C0m|N!U`cRt#z*%Wrvbw7)?feG5wRUH zd&0?Gs2%X=5rZVZ?>1YUKTnUW5Xa{ktL=5(AaoV4Qomj5SjZOP`K|BA_;u4>iB`06 zi|y&AUl_dLBI*&HiP+PtY$n17MYCGT!%U9rn^>9U*rdwM+)4<^0?7gJREERza*Sw^ zmM*8+WNs?eF?|MA-6N)LoIXBM>US@#=WR@{2$Qau;QP5)WEui@xt*TwDm>Ou9czD#N2*DIXo}cz8jHp%cQ~LbD{lo-|TLikN_XVGYYR#O8j&E1=Qa2G3vtG<^s2h zhj)ilUZ-12>8{z%y?Xrl!u`AV#?t2oT@JpxW!?2aenF|O)Xwq7Ot;5j=$;^kH9gLu z8h&EQkPx4?VgPxW}YRv3#*$f{n((F!RrYjycNIR8E+OeUsNP2 zvzSWEAmrt4s6T_(?Jwl19fQZRpI07&3N$8~nR( zG!S2p>)b>(XXBnY={U9%r9>iJGf?|0PGQXVD&vDBTWhs(y(nLTP>;FkpYMS|D-7N7 z{$P45bN-*7qH5s-_h(LGZ1nl8X{$(`W@=H#;fSFH$2$TNL1@c25t^a#?2M?6a&(+R zWgA{zPvRC$*l5e1%K^f&O{~y~Kl%{AXNh`$!sU30UuWiya7a4J(2YSV01=SS9$x-T z0OUm*^M={hRXo3-WSOjb**|b4C8eh*!ti+^FO`Y<;9~04n)2lO)b_r;KFAQ5@`|v! z75Sawq}V9H~hB*IQrzkJ~5G13CE!$w_B?eFk@$KK?gBzqkz~_|q2i(5GWapQ}QD zUC^#bj|l(gCj%D$C?v{msO()9 zBy8_N%zc_t_?Pu-`lopeCq(_>_Ju5DBwRv$9%?6C;gR)mdCsNb`}R~u#IIFCz3}ZR1l5b5@6qUubD_lCw$WE)U~nbdg<teoM9`{J#Cy%?nMkgO+Ok9HzsMsLc4ZKPT|OP5rxxBF09aXq6CSta{8x&h#A{ zP^b)blpSA*Yw3SIe*U11Iy@Y7d+k@7z&EJ~P%lYrSoqA4Q(zNH$O#n7o+-8BICE~U zA;r8A`HePSmF@RfJTE}AyQZ=-JCg4--8J+13#uxwgqVh6S8;Zke^tsMZ=M_K+41qF zR}gKTO9riEl=beH#V-W@N1IEo9(ilCIK=e|%bDcGFjo~hvmery7_guw6+N-s9<}v_ z^HfpkyFQnhD_Hb8GX`^k{)73r!U0M zde51_y_99ubxljYjd%a&Ro-696a!Ei<|T-bK#Gn}Dn7;Gvv8{5b|=m?R7YvfR}kBZmWsVwTV7q|Tr8WOu|>_)a$G!@Bc!ZQQ=N#G&f})6)1L+s zYo2Gtmi0~d$z&P-KI`iw_2lLDe~7=YciywKlnU#+^L9Ie|`0{fHG0kH6Nxn(75<= zl@4%!QEP4qIrEzNKwGIOf>P&le=N)9)z@z_)UAFwZ=#{v;ZbMj$k(?G%z>}6UYr;A zsb|_*5v8JuqJgB9QUAqpe|aLcZQ$raP)M80+XsPp#Hn26tC8itd%xCe)X%W&or^=Y zC)%yExlMQfcpVmBA?|GLFYAtSzSt#?n7TE7buBh7gMPX89!eK8yUHoH)azm$xqAG; zJaRjL)Nf36)-+OHEs;ik9cnK`W~w4qSFv>{Rk{GrW-)%Iw;x$VPGNi{0chMv3P%C| zhnBT5^;P^Kjto4r${Ke=y}h!ZyPu8fsd+ZtGXu>vpxsEW(pFNcL8h|0?-#NLQVg20 z-NLQhU9q-E8B?jMzoMANR_{O#Z<2$Dz!faB1ZH~h_FZdHpo)84rpoUZ|3MlPIq@%2 zWq;OEep-cp1~c3VEA8;FpMZ67x?I}h=#;i>B%DzF{&QppP;6Z2T9dQqy5S4q8+m|G z|EqOj82Y}&VYr+C1b}YqOO(x>CE?$Ta98-dq21st{{7+gf1hLBR;~`b6J)W|PU3jv z${TOQ4~ixQxYwtEqxDO&_?3MbRyRegnM~=Ghj&VYH{Sm7##i5c?;n4?2D!amYqHIAk zja?d3WS;q2cx`TMCT(cW&XdMyb+Q}y+#4N^DUof+quEzclBYZ8WoTW)=A<>-o%!cpxq?69Q7{@jzbXMR6EZM1msd(I*I zE)1Q7u|sl)i(6am=Il(e1Nt|h-7mh8PZ%Kzr)V~A^TzvDSN?fhKJEvJ&9mTMC4FFfwP=Fj;TA)CZeCV?>xmeR z<_ATrAI+=bDP?Br+DlvKr7yEHEFB(s>S}_<<4LJKi&U+rs~+Ta1&DU<-jBQLU*6wL zTTP!RnBQt&1&sn_ygkj~;|I8!yPT|di8agj*qkyV4 z&D!e&|HkGLrd{o9G}_JnEIZjgfhp#cZhhiHOSI|Jq^Y)DLsRx^s2$gKZJ&DLeETsR zt}%}l1)C90l16lkRb_|OJw_4(DysB9h!!7o3xmNlmvN@JXg;Q<5bZ=No|c!1IlJMU z@j~x=#9mz6I2pT!E1~EGhm#0vQWw#uRtUOQhgt$v^oVaS_eiJ+7!mwnCPCYu^+K#F z5$)i8en&hX<}_cgug<*T+$U9QHGe{K&kcGL-F`mVrhX9O>aF#)APzXYOsI4e>Ax+% z+<Pm<7?sQ5QouUBiAJU&2g@eK0&V%kn#srMxJXaCi-yL=>BL?!qlgr>%vbfF8(9 zF!aI#$AniZV#R@S&<}KrLno_p=Js?|G-|Bf;z7RNJ)0d53_XOyD-$MbCwuy` z4jdh;Yn;DG$l35ITh&nTu&sKY=PI;2JTPCgfvbNy85Dtz(~z6Sf&OlY7NertSs3G? zGIkyrF*MI`jUrTM-HwRydFx;3@|F0caQ#JnKRHuosqpf|V#hhUorkk*H9B-&JQko( zG(7GT{D`(F8Z~BBDfI)x-G6?%Q}pTe`y@FVK0mOw&cv|Q$@^8U<(_AnUE*?BD! z84{s&6Mwp)V8W&O=MDrd;do#J*ZwcujkQ~LwbsqrZ713%Y}e8K{;$zz)!SxvBYWnp zd6GD^@OZ!d%`>5ozW$MQKKspbzzbE6Wrb?747I~(~{6( ziW2@z0}Pm(c(-rHVG&*Skc}=kjWcHoiyz%}fVFW46E~i<8ahjf4z{C4V?_#Kb+E$q z_x?iA=geM2Zf+Zg4kA9h$i^ljx6Qk}h>Ztx6=y9_fTj>BM1Tb#1r5LonPCa242|N$ z8HX$3y2D2lp)NcdE)ZCv8626qO#=Lf>Ty!N*^ln+KR@we;YX@6bxR=LtNc&I`#@L{ z1`bcs&$#N>sqp@BkaA{wpnL<-;X_mNYZjt?^qJlyIo%YKk>_7+C!pD53Q&%+NPap8 zB)d{nd0x1b+#+Sulrl``e&?GQwD*m|;1zL6#+mWZb;rS#H)(SQZ;^`$ib$&ONJVg> zbw%w!eq7?*;H7_lLX6u?LMa5IGHJkAld#0we|4b!fIh|hYbg(p742ZzFH%>wzC!U0 zruveOtlMb0`G(k49={T-SFBcPv2Foa=Vf6Dzg&0#?m@DzrhHwV>1%}~`S<8I_{9NJ z3F9aA7E7aB)-1!ew^`YOoR2avD(1Vh7m^=Rq8U3L7T1(vFl8Ekim5Yg^QqaJn~mtF z0sFZw1dq-AkF`Q^kv_Khh*bvVCIWbn+B6|$O?pdW34H#FJ{$$X4vr1tvJM_e4N}t z8faCIGy<~^cDo;!dBP}AWV?Q@UGcex}Lwoo|Y%gzA$>cm;JMhhH;|tY@Y)jXUT9VKuVHTC0+gxDrT{VZ z-{rh!tRH8B$lsV$IDhsAAa_EGd3m5wq~^>=fA5FSrJr^Kyg-?V8$c*xBl})(>(9NUK=!u40wGag)SY zsg3xxd7*OBqCwQ2s$?vY9-6#>i?}3IIz*uX$sas?Zz)PUN#1JkyI4jr6>r_IpD!c; znJirg+9zUwAQ49}%bvLqKQ1@DbZ!HU+|a~eIojk2*WvYo7HF?i{XnZ%q~2UoLh;TQ ztDYFf5~Yt<{JBu+JJRga4cmJSL!BZNVac9qAiM6vy;k-jDd-F-vj4*TMM@AfR|J$h zC|S`3N>x4Og>`@w_o4Ot<-Mj|3mOao@MmB(B7v_7R->^i=pF6s7`vV>W6cPeBRp+9 z$HXm18bKlSjhVKq`jY_qXyn(KUM}Hf zkm{(Xl5;5FOIsfzeJ+VU9YdJ{AMbaLw3b0j-B^~G*8AqH zr-qNq*bsAdLxOVowReV9zyo<+o`;CCGV*I|fo1Ms>8E5stKR*@sU=9VDJGJI{O=GN9QgvK)wZ@z^<}GhND2=j)hw=<0})o za}F#M^TztkTnwqGAJaP5e&nR0urkEu9` zl@6`o+&m&!D0e=j{+(|C1$ji@MQtt(i>w@r2rC_v{6V`^i)2=2p#HqzVL}jA6z0^J z?Y5yG6=bz{qy8bK?nKmI@FzeQtc6DHX*>%)xEQ3k!EejLBS5zFfiic1mVyhV|L?TN zUlKpEGXvI3HvZ?KCabqFa&dsl1tk8CJ6^DYO`#V-q(rlU{|s_Dq<1weD>PQV6VHck ziVBSXUn%kbn;}&|hBW-2$dGlgK+WUClU7W#Vh(ibd=8E3iR?2Dc5|(fK@?esxVdYlF+>oX%+AsiWv>t!MyWr2kN}3`2YsWoG2G6it4bkXUb1 z;Q92pkB(&M=@Oco5ZwdJNxiPr!1)0#}X6DmY;&s|$5*ayF za=c^898dH55USjyS!C>oA*($GY(#it89TN)!aj5g?%onV{Db~91jOxGJ4BW}CNiJB z@G(#}y0vWK1xA>&yuS22KR#0jX_Ft1E6|&?c{Ffu*O6|li7J!zlSm_`g;wbt{gpV# zSN^2q^ul_$oGxWXCpGr5?f<~!>yw|+#HsVHA2$T(k!H_;f}*(g_@0wL^O_O6T7TY= zOxKw5=!wKnF(m0ToruVDNM6tVBhvjx%O{Q{bZ#MQMs^Q>&y2fnM;Dp)!h77aqpb;>YF$RFNR0Ip!JC72&Iibg{G`Tow7R3 zz_}fd^%7U108ok}Y?V1VW6{S_7Thb%MPAEkCXZ0L5Bzd2XBfQ&wXnVb6pzcz5s8A8 zCW%8=ucvN4GK^&Qn0YNaJuxiHaWAB66Nw^K?HO_YxRdlZd~U!>BTSoJMwT> z*3O6Od^&P+P2O@&Kg+kffKN8)q<|3xL!WXIQQOz;RQ4Ky7?Or50W9qc24_SM=8Y3- zA-|M;F6~}Zh#ih@mR?H5I&N2N4Wd?&958W>_u|U$T$Qzsy_G7@+@(7h=A0Qa2A;u4 zAna+5PfsC#J|lYGP_Ql)8BXJNy6$KVu6-MB_SDm{WXMBzFaI`za_>5wD3khoEj8WhO;>LLVRS?rZydtHOV!X?7c^w8K0h zy?BNozoh*tOwVzGW1T>}uu22XLqC2(;b&?{hT)a2J(omAlBJ|ZN9vR7Jtv-NW@&=v zSXgnIF1Ci7T6H{tM@tO3(JrUf-zshqGQkuPb$?M6RaWwsfYQ3V_du{3rO?V^Z)CeG z=l-It_5_y*H8_lz-o@xxM(uzk%MBI zk1Rresj$Fv@SO37QBKi8rDl|g|XY28*oxIw<;8IitEFIdA z+90+zfe{)=F$5%m?h4++xrfyGkf6N;C~aVvEd zd)EPL0t#177WUJ`uPDqSs{fWiYr&CVOx$LST)u~JiP+QS00XV9O~Si*5s5>05d*5n|iE?-Lo>aOZ4l zi`iXn*R+PjTZ%=`{jUF5Fx%NX;^2h=159u;^ z&L-uoL-g+t?K0JVeVH40=M6LurZij`(js>yVlhLn1%BAuqa-Cn)&C%=%EfuOlP3mT zL(>*`4^X5phzTcloq`gpZ9=oMzvR{>tcHP$0q>1)cypAEp2{4Z98xRA7|_k*iR)nv zHXdfzlh=pw12vvfWp@-%mHUU`gP}(vMqj6whWsXdQ@kWr;oGv8{zWQOPo3zhDKyTyJjjzXa$x!jSa#E#=`OIjd8S<`^>7XNGwYGqM{N%=)tjF|SX}+>H&StYHKIBYP6w;m)zA8J6CPbwqKK!BXEC0OR(Wu~ZF1?sItTCK&_YU(?tFNyg1GGRZb`4yf|%F-;X4 zXQP51!nkzOLuU=nyt}XvO6LT3VlSpx^{NTBrK&I-h!U7W$Om-J8bjnaz9!4 zV;1$EFVAhIA+1qOoD(#k&}w?3e-=?kAvuGS6)ppiZ8|r;Y*=E^b?;aHSW|3y>9H@@ z&8|27N8|<4`=g&7tJ459{m+Hyo<{Z1a-94m@;CJH>)61<>W3v6-Pm+*mE3c7&pr09 zV`ntu3IGQ!zPh9rL>$a2xtJ)tljH$7u@w7UN4MYKeB8tgH*ARLqB_SXbpsHM4pV=$ zc7~sq*VI>JZyM$Np*~)AJPCiNy9cfWxoq5)pyX;kGL_Lg*yHav>-~mf%uUk+I-zx_ zl0%|#*7jAU41M?_Eq$Dr1oQbT<-Kmv1sP7_OS}oYti2xYn;d%rY*;ccDFH#p@DCF_AE7Z_T%vCeU)YFZdUP zhWwMt)oT{5tbGpOxOK?6_)6`bhm4iB(s{B_^(0iL`AO;te2_2AhNhrTDck6!gy<+) zZ@X~G_`G-W&JUxlpelNZUPRbkl(H6E6qIzW;Od{85RtU&We}l(#lHWxj{?(!%Uyqp zkl(cJ1uBb|(nP9n2dzNVw?**PsBNrRiX=3dhaky3p0;+Hwnn!?QhG_I zw9a9i;Ki6@$L=~!5!eMBv5cB?EvWd!_L`z&0Q!@TUg)ZWL^U+BXor~gJ^#kqoM~X} zx89t@d_+(Of`I=JSxab5dF)3C0_q0PKzkS@b_LfqisvL~3h`A0@%}JW$HIzoK;<<4 zlM)~m;~zreb9CxPB&Za<)Y+Hrd{J5| z9+oR-{)oGo6l>-Z6erS&D>P$cjjFrORlDP14VF?PH2kS#(tS8m)@FG zB6FYcl7|SeXW>O*mWc(F8sOT+rHOOd6OR>2pBudrl-tz@vfC~Ak0*1nO-`-x zt`5uBFt=b$9X<-)dbLbO+X5dm?fYCA;iK9j5{t7MHMrzA(Mx1S4`}uLRzdZG#d<#n^Q4c93)X)@Q)^ATyA#P@nuCtV0*c$0+u z_nMlS>QyAI-lc`x4S(ii^=;CJ?jt7v^r#HV`9dOD_|!02uG+C4^X^wyHn4xnEt{={ zG-r6-h6kOaJ3t<%nG*)h#?zerfyYX(`1vbW>~!9n;%%0%`oE9nC=0unh?}=x&;rPZ zuyyc;cS>5{%gE}@Q?DPl{zv3UiVwaXyE^#uB((`oM8z|1e9^`KvPj+!wbaO=n+WCR ztaMx-H_A!q>^59lrJ#6i1ba}uELQ@|f->q*DVuGSuo;_uOW{>bR?A7@_p}=bY~HPErHd(_a;1l0VAe#LYI`PPl+zJb(6g;)gSu&K zprh1U9pg#s1UbFb&CD_oA7Z{_@fq4%R#w$;W0fiyAR+3k=vco{H~#|yPcfe2eZOSS z1WkV)84o6j2dE?Xy&K@2C$Du+IsS$#fWtska?+w1lU6Yw_rM!Ni-vwt z*Pgc4PHHSI+uQ!XzD;%cDX@_B6;7u%TN!9WtSE3`FwrP4s=*-H`uvOd#yFEpMM0M7g;=B73>>L!Wf~%MSP2ycjYHb(?x^UPu<7B zfpGcfr`{!@eTzX+21heT_%VtHfCHhMKy!A8QP5|H<%HDfg9);I#hS2*!*GhK-U4pK zv;`Dsey02JiAc6xK0nTQpUWcR=X%XzbUfYEHf_qIJOzA3;fuw>67f3-ZEZBwP?kT1 z*kbKd#HY$DRgax`Y=zAUG~j{I;l+=#Bg`zoJNJ8(!M(^zN*gM7}F-dRFo z>|TVrvQ3^h4Zy;C)6-@sVKAYer4Y*QS+I=6jdU8W3cI^F;QRdZ#~#zIWksXe(WaOD zal=;+hLH?ym!V&k!CkU%^gYdvsS~QeL*NM~y(;s~PKja3%`Yv@FmLoI^)(Lua3cGEkW5T6@1B%}NfVO>;08qwV{_-Sa zG=a+n#Kr~Ozd~QJW1A$hh&dz5=nu)gGk34&^_|Fb@epqcJ-C_TcLXFFDA_49noNa2 z4blj7fLKFRm3K9_(RVfNA&K+)#9wD0`B@qzym6gv5mypT&KO)xxKpOe;eFf` zkvb&Qa<)&1mls)*p}m*n#svTTq$_N6;=gwnj0$h`i#@2Or*^P4p8dVZNkGex#T=*) za4HY^Hr5~32+_s{5#Gje?|W$MjP*B5BL3*Ji1fw#GJKMY7SPVCLezmOxa$;Zi0DR}!Pcm$y<(Sa~k zXuByfskuv>Jh*c=22)qGk@Bc&%~SfzeQd^PlsU`+c;30Vq2HZe?%`Tt2m~y6L!^HD zOjIR1S3lFYWZxmhaXI^oBubqJxg%A6wonZd<*>QRa!zw<|FA0jTK2X5xgcx!`H3j= zC`Qyz#Gwt!cAWJGqL$iPSHF|K1gLg7_CyQ3r8B z<*7+uHWPXQvS-?=8k(6oUt9SF4AYSUnON~5lr-F}d@X)t^A`bFIct+6PWN43Qr_Lp zxLqVht0m?S;QzjGBYvz3)5IK8jbBTND^MOE?g5%=i_5D&LOAv_vaav-dXq%?L7Awrs;!f`VZ>Wh3Fe4-tDwY zVnuOc{g!~Kz8F0Fxo<`c-F~gBv^|5t=^T%8cm@julu28zQizP{#*Ma-iKgC(&OzOn zkye?5*P%acgNuecy%ubj>u=57_#Iex-1$G@*#G-==D4hJ&ASmLO6ekec!0IhVOt-BskByA>pF3!UF0|8 zaS6ycVG}1f8*zWUoeBPqAzH?~7 z>)YtPz3!*YC8p18RIk|4rl%*C^po~eM3vZ8>R za1@!<8B@Yd@yWpc95I0tS;-NgM~7d?34*U?v5u#4q9^M?+y zcs4~A6_#>xq`!`V*_)}gaqE~j=SW0wUSKwgRgdoyuX|*aW-*mi(wr{I z_~3)w;yV)Gch0?oHN)Q=@^|Sk9hrR5l9%ksz{+>k9u>%nB(1lUo zFwG=sTGO|f@#Cw__A~8F%fh9nw};d<>bpuW2RS^B91*XMQ`kzLD4`Fkl<`~H3Gz^x zeYa=Iy;U#?EVx;Ep@84V{fqDZ+Rf#>ZkMDZmT-`p%n$>Vem=%O)p8G;2oN@ycDsLJ=3ql`j-m?5gSWR~YQma^{4;VCATO^nHKz*I(X_HsEh# zgp^T2PNSMAxTZQHOPzR9W?ctE7c-f4KNuO*o>0oP9jnU4CbBM^+GpRc60W$y7GNvm zzCl$5t>#qYEi=VRsp;>^Q}2%#bF$CP#!g|IgKYPEp=t#bX75M?r482lU$nhzwPHb75@;@z2nMjhEhf z$}nU5j>{QpFVygEml;WKwZauhW^NSc)cGRvw}S)peH&!eyFZtUxv&cgQZ*ZXrfa4noY-ffwKqML93hvZ#6msM?TinQ z!zOafk4TT06KY(KKoQj2l^80ChP}%DY2+{ULx;_>CCDsd1IO%r>1T_E!i?h&g;m|# z;1l>)DjNeR*C|CO?ElKsD&E}qnsmgsaW1FW&!D{8Vd-W0XB{w{c&r5u=+9*>Rl}4| z8>Ghh$K$hLEABLNIai+#yPrqDIZ)0w6dwn|F3YIWL6H7Cy2bN&Pxq}Os4<9t_;1T! zC)MYn`^fK8KG>#RQjq1aJd=b=jRo1gKGZ;#hrY_im*qKOwuz#DjZJwbj7Xsf9%SN>A7>!+p@r?3M9d<^%Ru z*^l%j6@T2xunXB5%frF5(y*~8ZOCR_OSuuX^)Tj$E@GAR6(-a~&!NerAJ(x?KrEG> zcyIcpX7hJ{*N?7X*)BIflC*`TP4<$Vu(OgjMom9Ovsk1BQ(U;?xTH{k;hx67Mz3}O za@Wxq&{cK7&vua*8M-}PNk7AtYe-ig=Ds-h2HJJQKhoQ1VWMr}S%jbyM=se(tf21DUZ z#3fzKQS9=t|H&-PO42J>3(XqHSwaaJG*K; zzAF8Cintud&|-^1h;IDUcdiTU!)@=sac?dXy+zg8yc-POXq4u()Rjd#g>gHPYMG+w zt8h4{K%(6w(ggeN_*CYZ!s10)!l`3(c<;%sOQhL&OgKQcM%nobtM9%D0=u?w6n`A5 z!Q`p2;DtGjCb1)ijaHgd0v;28Hxn}GI9IOh-@p4#dph2qAVh%sDSX$mrGW=*vW!>$ zjZ_N4-SfU$vcIM~K&1kq5`UiBjA?QS9&Hq-Slkb>v)*=( zMKoEo9j$$Gf9(c&)SyIzH)4t? zym>T#NTLZm(8$x-H}NT>2ABvhPuv*bGL2rnT*xZ%r1G9^;@bY%p}1t>%fudj|FS&Q zl)*o^D43*JY1t|dee~@dk58U}(@jWC;hHlU@Zvt;OR1!ATdsB-wo(B)_<6`xtC zwB&f~qoI5UuJ@vNBh_y6CHw#$&I=z$55 zSx)~`$R}byXX9%eJmAe=ZfTs1Xe~;gLv6j=pVw^IFRw*q=ldP%dVixpkVL*8UmWHl zzS=Ib%DJERtT2x$9=X=Qv>z6CS9oW1N(RsYk?7u9;Cwa$D2hyWAf#fg$Gu)N{{zmU`2 zhW^<(iJyJd|2~mA*#&-;U zlPHW7_=e2wJvxqelRr}p??hgxEB7KE=69F4h2c7#LjPRGjFJr&$`-!$PJR^i?X{*_ z)l3O-yA2aW!2wK`?Qfd~e(&>AR}e5dh5>8FRe(f{KUv&y=G#U3&%=^o&e8`@udGX? zQMa3<#Ro8+b0AnR_{sG24dQVt=r5mB$)h-$`wL7s0RaOhdLN7z^ywI8m#K`8>O5%fa0K(f>qeS~_lj-uc(lBdb5=)!8Laf=>xYFPW%&0eaCP(naV)>qI#> zca%COYJS24x++^wBg_g&0TN8hox8=S=8QNO<>zeOZ|#Xe4?>Tv5Y_l&2(|wH+=GKE zR0MXzMyJLv#nRXVyvrgdSuOx-s+~Xw&Uw+T&!aes6N|N)^6tYh$LN*4A>*- zBh=n3&#?bXFYFWGYF6q%Lj#|~DQD+ki|@8|@3Ed}&l~O$=M_?1EgJWl_6xH<{W@1m zO+#DrrRncxQWV3OBYIIc#t^@B&>tmQt2qFj1e8{CvMEu%)mMQ@J^)vDfzkx%HK32~ z4(>}B)E|8ns9~yE&=4R zXoiv85*~UHvinoKqo|XJa__2*V+yE7tZvxbO>4c_)Q7*;gR{Fq-6PBK7+W*FjIvZS zd9yRVyRn*e`jPd-7E4g3hJ3lH)?;J%kTn}}F^N3CVwdIk$(D#@b_MeMD*k#enKDBU z=E5V+KJY!!|65;UV@AiL99itKXKEJ2ulOc|*|H3~3SC4(rs*|Au{f=~ZMY+@e_z|v z;GnUk&CF#BUjwod6B>&Mx?*=}@$O>cVTWp7>aS;pb<_bZ2M?jt6fI|_enQ}O^+%b4 zmJIKDruallZ90<wtXf3kk*&-J@@~hTnT>4n z^du1+=RE5U8}KCBpj!!j=AM~H@PQo<1lfhqAd;rvuZQdMqRz+b++1!DsT;#4tFBaN zJP!9pl3hk4(g4Ejf-3&b_#3AB%AK(v@D;%X!#-HD0_MZOPa@0FjRgNsZC|O1F$smR zrd7a^WRcuWF9SXPQAwe8&#LpsW=u0)5Iu!_PEa~D9Gr7dG3oSuQWk>5Mr`|+=Br99 z%Ccwir*F6|?9LWm`sSoT-LQC7eGT8uSpi|;oZ?u-48At8O9l^JvNgnqdp|eTV9>7V zUJJ<7az@_Zy1I9VS_w(eUE{vx?>?R9ANuydrhu0&W2Nsgd@LYB^>d=k z?1OJvVIeu~DM7%LivEKB5U|3}<7ioC8dUT1Ej|Do{U%s^3DZgyVy4Enb`N9uxOI}) zkZ!+bDE!X6hS~igEwzs#IXmQx74GeZ4Q<;$I+OUp1F@!T(JLu!f5sM7LQkiPLvDE$vQyfD}6t1*j8Z94JllqEj3! zYbOX{J;p!DG3>58Pg9`uP0nJeX75#q%hLf zqh!Me(BA2QsGPcqVmNKWq}o-y`|S=?jxxtne0bj;Mq$2MxhOUT8$xJ)lIP&%WHhcWjukVIu}M;Ajt%`B?9MF9AP}-ZFO`k~V>l2ZyoWpA zeP_YQE&l7}lLS{xA8gBe&0uk>G_13)AAKacZ{DoDB-gQg$*K&#mGKO}Yi*9CQT3gq z>b_(h!%}16#;m_Err+|%+ml5Xxl*D~^f^w4LrvDzHQ0oxnIMFNdwzWSOh#$TTsEYp{UkcxHJb^c>DbE0<`nlddu`} zcJjaJG%Un~BZ??4FxvI^6pCu5Iyj;1{+Q%of!KLoq%OVp)ljmQ$dS2YZ1X(wi#e}w zn@*jP8BObY%gahHc@$h>aiS<^k}bTKz$3AyN*4A&QN3h6WR)!j3@*bj#!dE%)m1)dNU4iUj@32g6P%B^T@MAwC!iamq zxx)#?_4_=qvo%x??OC6e_IC_|+>n738v6$3lcZxUnI^(+qeQGficv=n@EPjwo>?Vm zbyE6C?GhI1`7{E~8o%pm5muqs`WPqDUm)s_y`<9U`|DLS#SA9MvJqzqbUWmDa)$+( zDf%=~@R5wG-`>}@ytzp;W1X1MH7m^{dP8VM)Ew&1&lBE?XE1C{Z)Y;LwvII+;i=oY zt*QqQ?>S<=Jm1vxQA^<^(mxl3@0m-^@Mp8_tv%MTn%PROrJ(&<8Gp4v829oIHF*r0 z1|-!jsj%-9v2zLJ^f-6ZFZg%c98dV+@9TN_R#ZSIebb|PTHxVfsI-(bFXHBg7QAgv zckec5;#nFV6VI&AX}`WqyjCRlc_@_y@r=1Hs;TyL!_fUcHbFfJ4ZlsIUU@!@Vr-O- z7QfR=Q7+D0(>*^Ry?aZyQn<6fvZ(%*N%c3i_ko{&}We~F~|^O{8&(@mTn zy_nydGQ3zI`E0c~daK>+i(hW%nv#A1ro`0>`ch%GW_3j(Q?4p!e?+pea@tc6CM=VX zEzVShxI6re*TA-QJS@u8H%OpdpH5OA=9g8*NZsZ?2(dhL&fjC{b~Zw1<;uxD^v3E= z(H>3}@lHyz4=zHKJ$K&faF;7dF*SkhUizj8bJZ&YRI z-Hj4a5)Jc3?Jz?Y{e#6Um}JJ40l+u>m%jKUrj-U=jb|U=5+qs&GXSS)m?ok~KJX5a zI$?jpApmm!Rr9Z(4Hg63+X^~p@YDM-6IX_z>$FIlWXxfZg2DtOcm!rjY`yxKt1XJv zhw!?Aeexgy1vu4{G;=W*h;riEaJK+tj49-pZ)f2?{pEks#{U;TyOU=lk@`Rd6U$I> zO10%7T;5ru_ZJ#d*LOY97wdtSO~G=k$|(nvF_^{WCTa!4nxjT9o&zb^CmfAj%$zPy zxJf&S&G>u13h?`z9H(3>t8gda;82Q2?{3Wgc>VW=;9x=8B|q_Dj&u_0J5DZzZY={3 z`Dceu0A7QYD12TAZXYPPE%9y%8s?|oS0&wY5ScGQ!2J5?H{y3353uOt0q}FUrAp`M zV#3qFJnI!42T*q~b$;>Y^D&~frDwjglUD51Mc7QW zMJRq6GmKmjHKCn0v9WzSI}wLVUq4W69^@&4L|uT!}!r zg?s#>5|yrHQf&%G4(L-D_r=D6HZr2Kk)cY}+w@PdP@?roHfi{+7tnb5CD>mP=)Mvx!>}0u2M$Woj_rQNknvP-%&BKbU6kChUYm#M!uBL9# zctq4b@*mDn8cY;H{9c?FTsYGFSo1`|{X8@q{MPNYfL`SRGM64iWST;#_DRXBmuE>m zDhB!ejmaTRP&&;)$M>KNW#4HgN}OR09Np)ah0@jkrP!>bw4Mt}$_H-d~ZQ;U^m9&d2K)Sw?<)axU^f`MYId zfOv84RbvgK_4AATlAf>{`zOs<9f#37nc=vdqj<{@7Yid0N6D<+pn1t*v?iMCrLD8k zVD|UP10I6yug{*fpH#mQICpv1b;{suT~NY&{c1)N=+d1Me0@(@J}y!0z^WY)!Cgjl zkqo_IFZsmLl3RHPtg5^PvW>oPDkc}*@dVczFt}1v>d|CWwb50)b(&< z*=Gh1IwHpd?R{0MW$OueLE)j5ZFTQw$I5Z2&+Crf1pj%TZmvzG=5N(bxD3rk$C{w6 zdrm>2`;;wTZ$6*iPL3-|QLPv1boaWNC$_*Z_5FS9r#`rR;u1^q60PohH@{T#uAR`7 zMTF(3LfLm0>J(3cs*>Sb06KHKcYfz2Pv*iS38K-=&bUbdmbsFFG{A<>^~|y@6i5e& zh6|1E{LQ(`*4Bx?MavyvbddDXv!a`sF*!N{sCN1&zgT$Nq0gInJviPW1at^yKo$g~ zqMi;9l!I<5p}EY*VSCy_y;+AS_@Ed+ zYnfc>k3aFbt>xN9vPfg4Wk8=>7oA59vvjPls-ZqgMtlNP_~Ef#!wAlvHh>;Vuy?md zifY5$&h^7#7zc-*(_3R96^d6m-Bb7aF?07vNb5<~IQVyaA6vc_pxFEopt>LC9g*x^ zQl*%lN1aHhnE{D`w%~JEXfu+e1E{o;4uTDS=;Zjg?Gb4pv;n!06^+q_aI70J%uSRu zjLk1LM{Wm~6+!sM1j(JGuSvqQTS!SZejoMpka=f-Py*Q)h0NlZ$~g~~h5yd2B>hLO zx303!Qs+G;viaq(y3X}gWWvw&km~NlGp_>>ZDjV8GcSN0Jnq}wN!-nFWFs` zsL{?hB`sRS0eHAh8K$No)LsBCTx%U;H3K`LEoo;6;g>NL-d#I$%)gEkULY{*F{}7& z-h-oxe@!Oc8(P*3q8eM7_KwkqhFa~;PCY|hAGP-@6(Vp`dn5r*hg+s1)o;z{6u`xW;!UUKm7k+&mgsDymDRZ=BVFAWCWKy%uv=q5WlAO9Z~>B z)lQ$moPGbXLUm<^dYCYf)Z$h)g;C(wn6-V2*sLn*Kr;*I_M&~wy}d)sg?xu;P?!C9 z|LoW;GJ*HphrgRy9YytPqA_-F;ZxAUb2miA`C*|8^2vHyisytpfs1L8C_7!c?bdWs}ZHns0r#&fzLePESdnLaLZI_1x%+Q79-R>()@a zx=TeSb-8i`3Qo<~UuFCosr}?!d{|~k!dv1kj$!oc^3%Wf>=ldy&xv%ceEAs7Gl?zr z1y|BG6ktxCvwbyCEHXqMk2{lcxzlWPfJTMg(Z$|w0mWVe{-T6wbQ2`*&9EG)7vfIi28IhPEK@tKRvGGSeLoy^&Vc?1jai_CTS1q z7labLP0v~$J=>*I7DQU4)Zah+{=&0q&4(>ZX=4?*`{&&pbSSRBs!e_mZGn&>V3XP_ z$jP;1jdwb2(hSh8e;-+mAg&4mU_VRp(vXaS6_uWU|l@*dg<;pWDWV~V~q?sDWtcsT}Wd3wT+r+Rcq#S zz97Fs>LAE9JcNWC5fiOn`DW1NtnfF(vwhlqHDXF{{bvcSa8V(>o^aTC!m?o!6%P>_ zmpz@p-s2uG2ja5sLv(Y`%Q+R;FVpXBv%_N_)CTl|_gbSL7W#a{0Wsfl-lg5oBgFMt z6N*I!H3O_bB#4ezW0V*3xZa3aw(w z^hPfgbd60G2SUk5Tup@8`@WQ0={R`Qr!ePeh1ufY%_OXl^l>+jfZ7XD954!I6|+CC zsok3yl-2w4+jxqL#+@>wwXF3D>HZo-wYj2k0z)%A7du;?u6ZEWgJH0^u6b}O%edUU z@v6hyzTC6CJk(Q_x_O80=Pl1gaw^mTU#;r7{ExIZdW z$bN1(cIaJhN6ytIJ)l=e-no*B6xB|at&Vl*XlElunh%A)NEXNROU)m}(OnYOSg@5b zR!*b1`eKJq#RbG)n26fr^HGlXD@|gWv-HEy!9WDTZ%uDLbcmCa&7q?-kR?zrONhyKtbgFju!Lb*(5?;*h#FoeIk$ z)ncMSd#zbsEYzzw+}m#n8g9}Z{R;h}S}!~y3m#rqIVZ%gVY-mJ>q@3rSE$Q%3n$*& z(eAiDu5|b5dnM8xU)Iu7e5xDOjTjxE``xiPUU59zRIwknrxpw){YW z6XkCvbn#(?D`ssKYNSt3*|$4TF83Lfm0+gp#`IYaF8N%|QXRNgUUlqQhZyuEe`4sr zkWQe#YgcB4a&IL9q_F#^@pW)2?+F9$QXQ1kCpN#q2?^mH7*Q8I636}?Z3>bA1Dz{- zq+fu1G>{E6f)Skn)0eZK_@TKZPIWCqY~Ux8ZmktQDS-V%uN~iLko;Tk+Bq)*Wa}?Z zofWukruf0y_Bix!%?IPIK+z-hzo6(ruVPy3b`V4|OPkiPt;8b$%h!x=4T#*JTm$~O z+_Gs!jQC_TZWVOmPyPPcF?$|Tog|L-1YL$jnb7;=`$w9}lBli4pp@xM&-QAUc^)_~#4Ih_+F~*aEv#k#T+7W%S z1@YczE232R+EiIV*HjNXKm_-m)-EqZ%Mr*gKwqXt&rHCe4Vb9 zr*HXx5w%doaMr+1ejuVhGVevlbO0F@1JT|Lm`k5$)4$A!3_0|(?zii@i+jIJxYfMn zpZf9DEsuU*!i(|Rh1_E`FV$MV&#c2p1to{++FUR@6-{pS1RNwLu0<{A;5qlb%|{9} zLRBtTK7a--(?t3kv45^-D*3c=-p9DFF5@)7=92UjbAOM_yY~HX$){0p782}%Vd=A% zWj)i@mq=FVX&_Mq@bN+m?1fAwV@;{}EA7&J4gN{Lhc)jYxnCa65E*(fVYM1}(|6AI zV>(@UF}26uI=hyfDnHu~Fu_KWG{yN{4D;s!mH1x6h;`q=SyM&DxXqZ2H;*4&be65^ zHtMd=3$)97F6S1O5mwet z_hVr#u!`l!^_P#ca37)13~GEO8el2mBVk@$OUf@;j?vfdhf#(HNa%uF>~^v{@_vA_ zc1FPCQxob%0Kp2iPEW#p-`{EaO+%ao$gcER%HoyJ#>+K52Oioe{nopWcw&pXKHHg6PHoe47$3 z1?5&E)Au64wac6b-~RuY=Jw~>Cm}A#e_#5 ztD`lmE`T}e&T1aNN0f}YK9*4mdf8+SPWBIF57zGC9r9OK3@rlnjDdO>Tr#h6{<58H zi$Oq-u7&9wcq*lom27_S;Yn>?T*+AGzFm=Wk$%3ePjtNkQT>!8RgVb=d$s9WCnNs~ z_Vn_M0vo2vT->Tal2MOBIs7zJ9R=25-P}Ar9}aoRINE&tB^@^L;~$Z}irzwXNvQoC zyAyXX{0wvIs75-Dj2=h%aVmr3g@Xz;w@eWvj+$tKUp&>Zs^zhIYhfb2x|QUuqh{D3 zh^}-gC)oLuBKzlv!_}^&1EzA?;dsP#%uHbd%6(ehu6jIcq-bm{99JI%f5g~tD*OKH zwUR|mP$$sA@6C1IfYP6X1Z^pYHngrt8a%+xi0R9RNUM1#FgHn@P?9Jg zI>ivb$}#*mf;51=&!lk)U(3R`$6+$x7+a4LNd*kP@x0^?mcx62>FgcGtWQL_WEyr2 zsCTGVK$l9PeW@TOLB0u0dNAMc&K+#lCW53lY^2y8}L+^Yj9GK1qJwmTt9&85i^^d^d^H&BLLN$y zuOImJ-9{KoWHEjAMT)cb)>v(#Es(N_*+AwJ2cvj*rUQ!otmucTX#2a(ocTXZ@B^k! z`Wqc_WMJh?X@c<2hKi0VcVLb;yH_r5Rp$R-V6Uxw>^_2i?=h+uXbHkF%L!k#W%wx+ zXadnN3+{t=_F)AndRs|?n;-Yo!GsG1U>1rpFxGLP5PMbGZ**UFpU&H({cNkdm9Aj$ zT&C)_ypaGFTt+uBo|?$V2Hi1Z7;^5p$q!F82LH3ed`*UjdQBDCt|Om_8vYd9C){8u$#MOY!==+6 z(p_$p0Wn64>-&Oaru)39P5qF2;?LiXKL5f3&piD7XV&H?tLEg&_BvaMCVp2-VWl_^ z)%^uOxNxZFKzZ50(FP?q46Sl8plU6+HqQK46$4JuH;P$ucVCkb|8eP#`N6T&6)TWV zyBNa^)ys9i9BA~}5wUV=&7em?kTzI8k*57z&h!Y~{65#ab$k~oXk62qAZhvy+)U6wi~hv`5Em_ne`WX4(21*Kvc-a7UzXZ0;G~taqESEiJJeZJ-yt+ z;@VNW;sIcT{^dXWdx-G!TGPHs``K~Uxq`lY(XElnDMGv7l}mtJ1;2ZI(HeU8__98y zm=!;WzV&9=h@SX&%1RcL z)-K(rlhizf=`>=kXj$_Z3uzTX$;iw@Yz;t;FmMUXTlVbah+J&CeFkI`NNmZr#dp zKiz+!$B?p9*Wyu0%UmYW4#Pt)Zg>3a#%?1+cPhf3EBkJ1unj2k_GHgB=rj|iE!o8b z?t!PKs?<*8(Zhc(Z3Yth?F1oZ)ujOFf}26={xb_ObPg4y`q!`3DP0RBIOSVhj2S!iZhFpd8CN^^(iP$GHR&^0 z4Jou8Xq{=3z(AUvRkQ8g$u;iXy6Egk#pmhr3K(oC2w^1f;dzOklj9)Q>Ul;`p{Jq^l3_Hr@ zUPQ%qj9JxH1+`rEH$<~UAI+BagVMR(isf`zO8s1{tXlAKLnD@fS4ZkiDq*9ttrOu4 zH^*Kq1-7b)dRGJHF*`3uW!r4FSNYZQs|q~_0y|e_grtaqWn@aUP>Za-V^8VRdoF{Ymp%zGF|YN40%l6pQ~85MML4cn=b zkps}hiFA^qiEFW#*k)+f-!n4a3O%}h1bKQSVa#q4p8G~$2WLZr?m=Jjee6s8xuz-M z3NEV;W)t>Mzq<|gS6)q{mHR!UD76ZwEiTc6s+flltY|5NSC-YH-1hi7V-NZe>kumn z=HQQ6`qV{CIozUx`YZ4B3(}f{*hw4{itC2_u}BI=+5aC3HyQJlox|XO>k|uF#kXmo z3tp(+BE7Nx66^#`g8gs?(UcUghsJJ*r7-3YPUy!0(UGfDRLtnj?ehE1?vi##_;C<$ zphc<#B3&)ye?X;U^Un_kmwo#6!>`@qK&SS~#YT%Qti0vdq`yH{Q6~83Kkf4WGX(Je z{@!=Of$iFg>4gC{Nm_USDoM41eRBs8d|z1ZS{saGjXVsuJB;3f99~FgOL`}-1|MXD zTSxC${)2#PukiF0EhGe&V_%FtAj}e8AJDcBRqDAdODW{s#E%! zg|G)A*#g~}f)Fy*{mk_9CQGlNAeThP4V<>qJNim`QQ;T{!M-m3o$u)@E_?SYG)-9G z3RV~{jJIO;0BOWaz4SBJ8&f44=$okB`0x=zGq^Rh$x8tWUD@$iL8yr%ozETMgaaY5RrxysmIK3k+8 z}nDv6GLfoq6xNM)wS*!_ikYN9~&Ae**L7=L|mrl-} z_=oNz^PEq4#@9-mr7tj3*;Wz01}pZWZ^Z0S_XI}AkM-UtcfXtY z?Xw^fSQ#pdp;TOD)U zKeGN6rfI$c{n1g~+}l5amn>t2)(^X<8c#gKhqm9Kdl;pc9St;>^b%f!4;odTCNyc0 zxY#PG9)hAF@t7t)Ev$M7l# z3i5rA#1nTT;ne<*)A(zUj%{bDF<1*u`YnYi>ME=K!54}W z+RV9v7|%d^V(^Opf^-HHd}sv(idaMZBoNDR{(V8RiamH z^JeMmtJ1b_Wr`hT^7q9QbYY!!mBn1QPCrAHN6;qUUH}K9Ps})A30S(FK+Q~4 z=T|+jGcbFYCV>bSi7QRlGj@DY7SW!tWz<~a?$w7GeI&?qDFTqfv zGCqvBAW#Qy@=B$9E8#At?QgzOZ&;MO1HgJGOk3JF-w*M^ykV*07(c;4n_-iw6zZfW zwAl*j1QR6>FHze+jaa|zD0={!4Oi=lq%Wpk+0)q8i&QqI&GqeeM3TN3yyI5JB&JnY zqKKKW1Z9}<&VDUixQmd<9r)@DVRA!a!SCOhhg(pW90Ve{S3amq;GO=fwAb7&>vi|d zRfPbbA8x5c;zBSxf%@!rebj0fLRm1ud%eLXA7%%jeckys50%mp8QX2 zcmKuD?qP%c_}_u5$R0c4lGD$iRDYk7i6-kF2S&zIB+y9kjrMQW8DdTlr6m1Emqist zsI!CAPD+-l8l_@BQ>qcbFsa5`(k7jhk;FI1vBb2(FrKKxP^PcyEfSZl83i7MU1Wa3 zyRat7zD^;G()Z3~lFCQA5Qc1^t7OFbQrPC0d^Al_dGVsMlmcJky=ncdS-sTa^blDc zy?PA{fouC#YcL`?hhCaj+~DP?wMMZVIU!@ z!coqn4`eN0$gqR2n@RB!qYd_4`oT$9?UX0AJ&KV|G8ZXwbNoGqgJp!q*NTija#d+r zmrH9f47D=Y6Qx7kg3TBP3Y@*v0paL|VKh;7GJoP|md#Av+)iPI>nmTM!0AVEq-M-j z*{zV|X?16WjdhqET`YUu%Ua+=YIl-#lO56X<%SW3TMa}!NrdsjzH zY(6Ob@VweJT1Mixm2|D@P`d(-)=hTNN}U=X!WGu~G`C>+APi}V5+TmLNTswaM(EB| z>CBBxfqhPP108gQF}+N=`DVQ5RT7d6_A+f!KvcmB-T=$Yv9!vv8o*su`WtJ&W>`qT zO{-*wt86yw+npV#>`}IhCRx%MZ>9f`TuX|VtBb~j&b#Rtf?=1*uY-SNT)xzabzii( zlJCcPUpI<_a%IboA3E>i%?C>>3PyvyuTZrv{0yuHAW+Gd8Ghi@*kCiYDf1P8GVm3g zB>JA3U-uZa3J08RXZRTv{IToLhf$}cQ+GlHEI>iI!%FryA<4X^@fh?c%)y`eo*dGz zpJ|8m<7ps_}EHj_q5K1B~{v`g7l)NfBaV)&ed{6mVut3{_UX@ zWl!oqJ9d=48dGly743df^0rxYI!8NNW{7CYyiCOdk?*^%#9V#)wn-~PtB7)!1 zqMEEp*?!u*I^a{u=hKQ9J{Y-Xq`ROxzanFXe471!s2c@`u#U9(BDTGO;sET9I=n~wUX zp^>6c1j3QhQ&@>b)m#k@Fd;gb&4)13h#ObK^CsxB@Um}nDRb@Y_JgzddTOISO}v!|P&bUp*;H{>*D^mJFCeOW@!|6B zG$d&TSE^5z)ra>TVO*qYr7ay$K*ANGc4v3NxNNsSgy}^t| ztB7DenJ>=5DfX3Ub|hO7=3L45W@<*~>cgEN>+VjL-jBv?G@Hzi`-i-jXpRyUP=gl( z4$Y(`l);Vd>&2{QxPJADfE3rF@M(*tnZY~PGXBCo!&&@Rv7$mR_m&A^;9pF3lwqHy zX14b0N|G|B#;`MC;~aeq*z zwB=uuP_VEyy&5s^sO&gF3Y|AU!&q6_h9%SZh6fJLr5#l(_?+r)A-?;r8~w3R5+SF+f@?vomZCP`lJB{SjkH}OWXBdpzRh+ zW_;{Jxpv7(7sijRNyRWejf|OP2e-`l4NHrH{dgIAx`a1GmoY0LgXfo!Gt|9#8QMb) zuJJ1ts*%_1Lf%p6jeCb+lRxv~$u!UzChyJ=6(tb5!QsiV4wpw8qW0KHq-A|b|Dvq1e3S3McYYY=2eP=j)SN#k!!uD^+Cr9AvBK2F9%|yow2_J+ z?&?5)DW37ALFZi89XWp^`%i6#E>+OH^J_!h!wOn>y~CLYqEXmxwq|6;Q`9emlW%LF zwACKS_IgIxY2Q%Jvn$8NpVUW8G)u3_47nVUkk8$Hls5S7PTIg=(syALOZl%C=v7~+ z@sKH70g0a_d55{5MA=Q9wr-;tTaRj00Ay;yd0;NJjNlc)1l|Df^a408(M3U-XB=g( zQ`N=2VkL1Z)W;PwCD)-X&2PHam|~$3S3XAFteAnW4pAjP;0G;)x~qaWDDm5^=ieVm}&yS&b#lw+Q z@i)>}%?2=4Y+$PE`k^|lwZJNyiT2CV?UxE~6<24@nd&sJ293kmA4wn)_)ei_w@5>N zLp_Y!D6ayZX79-DQLL5d#z-^uD%_u13=P0EiRW-w!~+7pjyU3o862#8O7hN>j3QK{ zq}}&uUGM83<=QpYF`1uTu9yAnQVon9{w(|=rdqlUVa|jlfsf|*rLl72K8{OM9$;Iw zGqBp}B+dzH*@xy6Uy(;paIU!c&*lreKFC%36Pu}Xt=@2vm8y_oKoL)Jk!i@tB20l&`ZAWMetU0b`pTJxfNaYPI>B)T;>MH52W!pNO_sO$e7&gdR0 z{5f`wS9&9aMwRAC?Lhw~88`Cm%H*a@+rYyWG;h%5Q?5zQPzl}u(p_|v%xer?$DtVu z2YN_-u$A#i3_&ZUuQE*02G$g?s{^A=7dSd^%a>vvdSw2UVF%`oKKDb`u7U)*nFsDY zx*O$j#dU4N#t8;v@Sc^*lfo0k48)p7!9z?_UBV5hwq;|Ib<*uo?YzTQvu4%3i&ZQn za8gbQh#N*@>SU*j`NPxju)EL;JQC=@nw-<^D4d32a;j60yBAr73|V=BrNx6bKH~k0 z@C3gBS_89jwY_-3Xm+enbz(#Pwe9apHYTOy*&2g6At@42nKdxIMT%Al^9*-aVyYLV zb8IeJ=`63b%-CQKIfdwDXhtEK(A|qhpXwf9?Q4a0b@Bx<7n?_FTp5OM7<4KRzQ619 zf~nLnULCSmTq>nCSh0dD2%+<`(c4_`_kcDI8NGsCQ=D2{6{*f4pP`TWIUzbgBA8Qm z@;mrXhr0ixbIN2JRx5;dZfR;YjFnttROiMjcQ7j;=ft z3&2h=nDSB5xY7w3tU$6}Y=1&sDT#-6n!(+H{!!dQBx z3?pNO{Oem0zJcP4@g{dRXKyC2f~pbGqa2eqdEE&GhL2|qBVahrU0|tO_-}7n{q3E&Z2+qu7jji zfjNg9AB3CH+-!p1T`m|h_aE#zgANqksbsgfJ(*HWXq-gq^!!W|e+-dmX8E;m8MjwnX!PVh^W*68AWOc z5s@Bv$5BB+KtQ?@k){NQlqB>hRhmeRBtWFs5Fn63iob`MZ=b!-xvq2VZ=Y+QKak>^ ztHWAL^C=ZS`*u6@uaFYZ64 z6z}KXfTp6T|6iJl)_(>&cKZe-l-kDel-aB`9Gmt@Z~#1yrBrZGKNW+)G$0a_#6vb= zi$;G?k=*sqBjEO`0CO0A1^LTgAHzG}w#n!*PB9~;v?Sr5>srD4J+G6R$AJU=R)mw+ zDROAOsLhBX86cl%b73nzQYDB0jDU|)7O^h_RzDyv`y1_L>S{QA<{mRTJY)xR!G~;g z&$p*0zoF{cjh{O{_goEGEFKw{M+I9<^8GT`M$P=zw?5*>A$l<;%Q9`$teNyTEhkIC zn8O-}HtuJP*2z!fC#9-i>GGU{tqxu>ghv$kP4O)6Jy?T9_>0=!(z#F>@+wc+E&(`d zOTKt^vO=ST1lGa2y-QPB6Z$K{E=^N@?CQh;_WEG z1>HmfRG+o1lvQmGqyP`y0){7sf|1%V&Y<;%AyMTBXq357C7@JBz^ld6pqBaP29DUU z#{3cM6#Ck0eb2l6;V|5_l6arZEc#@5sDmD0)Ii_Syy0j{^KQMdz`LMmzn)VySe2RIv=Vd|eQK^NbthSoGhfV^HT1omZ%;@5 z0)nl~e@im|t9T6iC7ez>I})T)UllQB-HRDKL>QqT0cFw!BLAbS|E|3qBd%*rF`sAx z+-)J{B*Gs(0?Xq6)fMWc9wfg;)a$pwQnm^5wJ$`s~%WxW~`si-F68|t@>+lcKy7G95H=BUniPn5ISW@;|DMkG7o zT1pS!M$amRC8}x-Z6}3gdl$A7*dU7gHmjT0~`1z@?4#D&zN*{{e+!HuTjBgleJJ67Bq*SF(x|{1KPkpSwSG^!SM9!DFP( zYi|f?>IlFqy`Xt9JrnG=4kYLbKyr(v9<%eixc>8{mPUnR98_YthQ!gJiW8`70>Dds1j=X$m@EmueN5Z(lxD`dB3V~s=%}|}&>>C=qnnY3)w(e*>^aStC(1q7J zu5k4XPmr}^GXj&3VulOo{+45O8|j-7a?onfM64P8SQ(j1iFzx_laslX?lzP%?pa93 zBilI|8$LPZ6~tcLnK^FordZtX<0ymcbe@+z(E!J|rN zt3c!ZiD7Qbtw#sur_95va{+j#h+YwEWzw<}hG~XRUy+YU4~kh}V3%DWRDH6by%Ki+ z4|&1H=<(QoztAQ>)E{NEuAQ39%kh8}oE9s`WKmA@L$ebn9abxZtxB=KcO+s7;4pwy!S)Vee5QMgH)1a-+R?u(r#w7-Bsx zyfn0|4Cra-Z+d!9l~;8u4rUJ6>5T!{8(qAc{I2csls+%m`Z*ow zCQzwSL7hB{A>7N86x{IS_!zk^ah;IcM=tL&%tV{4tKgqFn||MvdAHLCq`8*!G!Yq`3+%!5olPh*>e~49IdNJ2={m~lGRM7oo`&f+hq0} z%-zaRsYWxr%2zsT8n_6#drYxBK%I-;tT(4kJ4~2Ck$=4=k@=9?TjQ(@}OTE*uE(R3!ycrAKQMcI&^kdsey=UctcHPf%0 zF-G;?$ClBHhxVzo#=_I?;hcV6@#^yYBI)YEdHIMBjS${qVTTfS+DYfP^|LV%ubaDp zU!HbPy64#K5o8J*lYh0;ukt#!g$CcPnnwzi!Pd4h)KQ#ij_vXQA&;lxy!0gM{N=ae zULRXQ2VM>uFDVMQ#>xPwL(luGkCqb=R#ZueqS%EW^jr^*nm^ROyXI5@|B1d2-Xs{hWf_M~6^BE|_ZH`;0l@+{DGNoSv6XD3Q9l2?v2IpE-x60maNT@cAr1LQiR(UW$)V!p$A&Ki7}@cQaB`!nY0dZ(wx zB)E^#rvBYaZM?p_9hh)@cy)HRy!P_-$5IzA>+9yhYn{Ullt-4F5GP-J zCR@gkJKghX#O5r2g>j$|t3~auOF?m7oxNa(QGo08vgoZs_>xqiu~M-1;IVY$qPIuz zng%{>J==>UPFYwLYBqUb9IIAQ{3(krgtNj|D&0#~d0kJk-#K*pdb;?+QpwNxBlpd@ zs#F2M++a|`Se;P?IURlZO0PFdmUaC>z=j_t*9W-<2e{8w*?LblP9Siayu^9~ zpTylUocElnfr|BLb5SN^dGS3H-6~!Y&G9YAnzP?I&G~idtTj;wU&mad3?ow}F97Po zhbGwE9N)kRWuCo^crtEYC-lQO(QUaqz!svN{@AQ>guPPYjp`~g(N2ADfQnM14YImg zRM1>r*E%~YO*2tgb}DLYRqN{+Gi;$##OWH~Vw9-`=@JhG5RNs*fcBe<8xtK?DRIe* z=FVg2&Y*BqY8RJMLs?+bk@~3j7wJkBn#yclra2t z^;nJF1PcGu!~>Dn$za+LU$VXQF43UHTd6)q=%M}&+N>{q2hOy0%^PW*LbM#skW-nW?&&ixU}k%A}WxKZtK-wsn_6!uK)vakfInWSI&2aaXfZ9nguH=vx+id zHSMqw(5n5`eEZj4#FMd9X2pYTT*Q2o zS7n!_;2lTukFX2c}+6^#o<(T8R00XpgJ%+OL zAArWltYwU0q6q{35_BX_`A~RZbKC=I%WXWgckDuL7LcTzfa?@0@NW){1XDs|*Rvd!cB+5rc47WCZM;kI)z$To}TEdG0$!WL=bf-Nq7p-z{R+gRLj9>apfF*BT{B< z6H2j1ZJ(H&3I8nqk!LxI*!k)Pa=9g1jfqBQ#dRf&X20(%mT^I{!lzl*{n78X#8VS* z#_YOtOk-mRoWu5|c4So*A{1dh4kc^fVwVaFIzcK86SA> znj*36Ko=M;Z54orh-}+e;27@t@6>pVD~|+IcFu#^6DT7uwg3D_l>E~}r@M}xE@q7K zUBFty!%vi5w7C9azMAgB#pa*MifJ+1{rLMPa@@ovP`r}1;qLnKT2olbC)?D;kMa+D zr&2;*p;rImp5+CPx8BLP(feyJLCG+EteZp;u^rOQ7Fu4OCVrp7|bl2#*9uI55M${?w5AoIuW;X5_eJ4=cKnDi|W z6ABe26SCp%61-#N1;J>His`ax$ym|3u|8Xs>BG-1U~XwH3Stf+=WPiignoj=jI3V7 z{b=L;4eL&saXEI%DL>VgJKwY-ydf-6d%msk8^+=L#$xsJqps&hAT`A}SI@jbhgr_G z28_E$^q~_6X$5$$7xRE^MfmmM`v2k3(;w>YoE$0&m*kCoM!@8F^Oh+cnt54@=cU2W zzaF@{1LZ)tCfy`%IlB1^-dxbmL4rw3 z@1IU16*Dpf#4PuGI&mTT9on;y>X+SFDGAY#EE|gqL}3XjOQ*p;o19U`vRDySp06zQzNuHrp%otNr|Z0 zZ}-^e2vuFEMAR+MNf+E18Ey~wj6p7bDI1hPUFF$eMa)}y82*O&H zZ4B?>%~+r~Ni>hSBOzyYI&!fbTJ06RqT^*2gS#CIS`v8i#WlYTtmlHKrjfuh2&Nmc zl&9=Kpe`*0Y5fm`ggV8!c|ZKYedcP}-7+<~E$y=8&IxE7DBrAs!yZvZzWtEe(R+xn zZXcYY#tVu+g;l_Baa>X$79$b#Ip=`roVjbAzMN#yJOKKkfdWJT)%c>mLd^C8Uz4r8 zC(ECEF5fSyr!>Uz_S<&S^3vYTo49F<;+;v8iJ~MzrIFKUt%jwOebH21#BpT1&8Y=s z6{QK}Pk`5$lsKSjfW7^75i6{esB|bpB|E$-z%GB`f8m9D>NrvN1t$wKK>RIo&u;Mg z@oWB~n~#Km_{DixDli61Q3ExM6{w62E%aZtC`Bj0lQ?|bTJOelF-~OOnpaUU4(!az z3Y%frFq~yWtf3dXR8(QqhlIs|%>e!BU^2{U%~ttFD8TH3+eRnsjgFP96$eXo zbOz;{4nZ?PUcOT$FToSrD%YME*eULpb)5}%JK{8AK5O53q?Yosba9Y)ssA9hi@7~7 z0+5Qz+MSq*3Q=1}h8vOtf#qId*n#wevujz6VX_lI6*)OS>l!p`kIl%Ossg zmrE$qZ_2O)=kSsSU*olEz2veZrEq~Y)iZFP>N0)0y{gvrf)^AMtf`K)-f&(YpNvcpi^kZmTfU^IQi z4O2@&*=WX@`dPnQ%nO$W>+7Yo*GseX$wk5Kf^h*b#0Z$xbRRWqI0l0RsGEQ>`+$%Y zZ3UR}mAa9Jv>-5k!!ez|meX1`ifphH?DoQ~TevvK%IamYP2dM;EvE2cI9RT}Wmr^? zM}7cuop!j?%shy}KhLiN=KdkTmyw-O@}32|=T2mXy-lJ*jfcYS-y{uv{u4()|L-DW8t1t_%}WtT)CK%bns zM_;~&^Jd0MReA`^?fp2(bKm0L0QgX<1OEB*f9ngL#o+05!IpT)!RbVtij@%h;zn58 zBYLwsqY#@c)j~SCJam9!^x>B4WqVi;@$|`-8Du@#&$u>67=)sMlFBhJyqVBab_6)F!05Oib~bU!s}O;U2QjbWFNxodh2*L zZ$Vq-y!avHra`mgZL^7z>oi?NZuT;?S?tG&jp5a*kU&pB6xe6aRrwI}9Oh`&L$)-Z zH_@uso9W#tqI9vLk>Z%fFZMq_i!e7LPWPkME_1Gm%80PY>$BpWyog=~?+Bag>&Wb= z!s0-!yBG@e4>Lu^OmdHg>oqy5&WQyQ@|MG1Dmxo8f9=Lv=h)AW$oH3v+%Hj_z6=2$ ztfnJiA?~ks9_2r@83LTfmjB5_hVv~6W@jY%#{?I@Hei+sPHLEgp)c$spy&;8aw&B_ zaj7t$*I+wIW+vtp;Tq{Xzi-miK?o!nD_Ahjqan|1w^vWmHVCb{K!~B!St#|MK$kL?GW<~ISSS#Z=+`~D zHUgS{R^kmgQpt9q1sCBTT;A2=yLT$URdn5R?Q(|yDTbp1-3Wd6x<-PzuBdHNhq=vx zn%r=$j-E5CrTlgA@bIK|%%P&AC}jb>h7Zw(o#Xf53O!4UalwaB_$w5{4nayQW)0%+ zNBfx^8AvK##cg9&V9KrxylxwAMy88+q1eYoJ0WYfbU*m$`q3%}!0A0cP`8w^3{nN zG8c3icr2HmP;{d!nu}TONVw3nmx-PxCeSeIr~$f8y{I(>(+1X;GO`y~)*LG5&0hrt zHBYxdzf32eukJg<&+WFc5>1UTHl)dQ#>-l#D=UY90PHK_z0v(fl?y*nXrs0Qb!a{p zTQc_He9!RDHBILxr;CRv>a?keNweIOFH4McMP{k@f-TeFBL!!XX%6RN<|`>9MZ<2# zSuPc~j`~(X(#y7|y^h*Ez*Z{88$;2eg4Ly!Nu!sREaj}+=|g5mS}Kb&?!p&{j_86S zU+$d;DHDZXt+D*0yAL}uUubYqZ-_+mqt-+lYXPt~&M(n6NI6D^Rx{!>ynB^qKv!_P zO{`9=NBANb>;eOtI)DFoMDV~00v~+O{Vv2G1EH!Zj5hASy%O;k5EZ~W`~iv#twV}Z z0);zD?u&a3-;#1XXEi&GKRykP`8+CSh6W^U`C@jcK$o0C26G$BoDriu)iG83nl-;_ zh>H*q=V@-OJwLabPAoRhz0x&^mexhx@m~9B{FXO?8;Gq&p)PsE|MB?Fiux)SbQdN8 zggW91DltCqieyjA7rm-4;J4B3AZdZl?&KHbeLwgr5?_t2#EWh;qKMlsp{IP`D8V+=Yg%e9EYYXD|qH0a?fn(9ef$6|8*QetghP#V^8lU-x`U)|>B z|71p;I5eQ<&3h<5Crtsl=$CCeF-}CWen{EaTkJmyVbiSt0nq&KKnNk z?j^}nYG$#FeX(%#fko1b zZspGEwiU8kFs0t z-?W>t} zEFprK6ES2av3N(p$v;#*KTU)`A;@pD;;FVD+Ku)(`+zO6NVRhRHp}eYQJh6ZF~LJ` zzBJOjfUg?+=N#ZdV*@~$#kMJ%?Qs};9XvZ$fNxZi7s;kpK zk0K-@`SUQrWh4o7N+&-aXYBT@JFz6HAM#v(vj`ipX*tPY+K#K`KkhzeufXs-!W`c4 zRh$J=h%_pAfn%3ZsOX2v5yU}k^%E}B?hd*dEEHcL-~xQt|D|y+yI8S3E6SOMYYb1d zvZ^1un0#@F8c{fbk*}N8KwMtZS1EGT_E)F0RoF zfhn3{>4PbEk$evZNL%Xys9`xnh3|rQwH3KiP|dT|UIjo%%fe}i`2^*Xni$JBUwpx)qfs36@{P@=bCd%EBS|0O7DK+xduA|Qa9fLK5dnF?g}bNF|V z+(0$`%c(2D!7>vxQkHykTK>F+oSA=Ni$5yt^Y={#=10NhX$e>)B-J<_Yc2!^PwCUw z%AVdzY!~#RhXIxY7<*lF-aJE!Y}<>N)eWI(-*#6BrMHq>L4oTESLNg)VcRn4-JTQ| zjxp?B`GBBU4i<7D*<8;@tdV?ykIy8v1jw&A^7l89zEIM(#1|%z+gf45GFPz@5PQ{K zS$@&$VCD~_sUIcQgwf$Opa7U(gSqn=PUlLY2fDC41Kl)d2&;DYi|2*B!8lo%? zAb&I@zOJ??wNtSLy_zit$zc_L?_bqreQW}0 zsW84&!w_FKSbb=yaCLiev0_?Id`$)Pcs{M~j$5#j>*Tf(F=sA@xOIhWN|}=bJ%M(1 z!qm1Qjr3y5VQ`q0pU2NNc)zbI#Le~8VlGn9bH}_Ls+oQpUGh)N;9n=o*iskd()F4` zu14PPdD9|uJA3j9NWF9G(0iifEuG1ojo0lzjrgx>fN*U?QeDW8NmZ@R9h`O%ZuH2= z+9#M7_MDrr_>pM_Qh|(cH1VsYG%#5Sw;U|iEAtVvp+K-FUMT@v6$favN>PFJ{vlq{W?$i^l_Ajd^e5{kg>fM=HA9)9S z8v=B=dd%r6R=vWnPye*FYm5{T(roHvd$!TSrG;A8O~fD$Z&*MLoAESFPL>xvdn&L5 zg}j-}3p}>K7*HKwMzc3GNAP9B?6g>7bC=N2ahsNNX zx&DoDV~{#s218Oe|HsB8Xy)B4avjsB;+Pi7pt?Mane!|7+st@sc@La~DG`DC|LZ7V z|FriPTIaI-cBE*Njha7|H#yf8*8s+EnLGiA;nUauty1X5`-r39-v$W$D;f(tt&b0H z0BO}H-7!i<7f&DFL><{KdLDjoo(82JjcksmS8t=Q40(j)zy*JYNuavOQ{jXfK`kUa zpu(%u#od%|a~Ze6F!?%3O04;jM2lr~bRL86(SvYA6nx(_;boWGb%`-B9sawdk-yFc zA1pi})X@^!^IoiHmK^QjAshU3CfiPrkat&4MuUnU$j;W=mlzI%{>KAi^6uCigQ`K7 z2{Zhb5cVGWA;@{>cKKNHTXaR$4WXuP{~%yc3aE62AC^_!Mz@rr@6RLCYm7W9kHh*8 znsx18n;$j7yJI*`zlHJEp;{zJ|Mp<7eV`w1hjvAa`@@xhLC20}?<{+<9aw%{9YhCs zR^y?;w@HYIDC?WU4-vQMd3UGISbBsP4z`g4YW+!oPCZCW*mFUNZcg2%LAzSlo6d3y@k%OBc0>&Qe#d< zQ!RJ1MXVHXQV2!-p^-|$RgH6_zN^NMJHVA(_hCn%hwJ^Y41|}E!dnYcX6g+08t#Ob%#z|~W$)+$_h*esc5!&02_iVD&N_zj z^iJG8Aj%|j@oL1Mg)rqPMa2F7V)b7W2Bw^K&y zvB}|aqb@BXff`k1QC^*R+h@g|@);l=EPLEsLv75?tqc|VOq8kpf^V_Q50Vx?{=NI) z3Qk{m*4_lP(q>H6SkNPfksQ<{?0}PYLc2C~ZwWLGU*8>eZ2V~+F{x%&%2S(>5<(I& z!1_~4ZLL%8I~?P$68tpAsiqO);M41776ov{R{xmmmgU;2ZSSXFi#0g-45yA2iz5pj zS10o3Q!-r}lvCJ>*e*L5?O6{x)?!5wU0kR*X_gVqi)}W1;zK%FJT?vP+C1De8iS^< zl#h7h8YxWMW2n22@VnA}6!sU8{m}90#@)H0dy~fQ(bEGBb_UDt>o`m++g*)!mU?{t z_C?_ghshAprW7j^Rv28IMnd&p{Y+gCn%!Uu$_BRCc(dQN626Twqq>rxD4Js$skbY) zSF7o@&5Qg0V5n+2-~l92SQ2)M*DOZ)>H3J)=Y<6J@nQ#D2_-YWN}YmDLNewwUI&Y?Z4b#+crF6?wdLQ z1DJX>QNRG#;+D8-UwA;>t|d-o)(BRM=bJ-E4i0f)YTFl56^oziW{P@jXtdqMmE^f;Nt41F4>_#W2^5%;S7{#5UWZaRd4k(lj zQ4yF87qk@`rNQ@To&pvx8bDP9w_g`95JP zW^RUsTXo*1T0pVRg?t0pmM|b_l#GA-@3av7o7?;#l7c=K7RB*Y^*;QjyNEKjCEOC> zbbXQiT|#*)!8s3-f`TZ6;`Wv>9@=?!YP`AXC7`5@m|Xj>WRW;wjPioO(}{!wiucdQ zNR*th-Coh8f$QfBVPpW`_6l#+E;EFZmgCM3`~o={P^3+Wb2KWB@4hPlrOOb^jhO;^ zgUZj!$!a1_CLvuFiTy4>4g7@J<5wXoY{&M z7NRRrD~9#yW9A$W)4QFdx(1%#*j8dS$x4Z#ROQh<&|>Z3rvm%ZQg11(F_=2@QllaeGIJe;qGAMwgPFS|tp`Mbw=l*Cp3~ zEH>%h^BUgWCDNv|q48?eU_`Fo;QT6X`Xb7xV z;$n58AIBH2DQP((!l%OnK?gTwT{28&Y%1|WZC~=-NY}Lz^DIOth$6{QRigJ!aR)9C zsK5{NKCc)WqV!V{!xtBO4E2WM?E^p?`eiWzOakok^ODPijWJz1!062kKc#*^eYyK% z2glQ77Z}+sM^b;oB-g^5Qd-ed$!@1HA}ZG!_(e%A+Z0j*l;%5V1Jft~ejL|edR0DS zS-}dw5I-FhS#@+#)0) z=pQtVGqN=NrIKhcd~!1P4@J3g-;K(QQ!IZ|+~#ePlL3j$q=T)nPYg}vC2E$#oK>d; zYg3_&BP?(!r^SX%IU78vya>qKrc!%v*9$3>-xzq;+k>yAg!deVyXV^Sgj zzz&1T?EC(5w>JF1AxMmD-{q%ukb~`2=AwGaBVzIs^i4ci()ZPzWwM7)GJNR7TLMu3 zTc8%ske`uNl!YZ3Q(g*gC&z zQ#xwK!U-y0J*^FCyp;MKL;@KoqArLR>A&ME@*<)&dCCMDOq}AMFvXpoZo7JQK^zSC z*-47gK))2WA>e>$@e;z$(gY_~0j>Ku{89K2bvLKztlo_&v*{CXV5$@M5Yz(YFx*kX zWeM02ZfDwMn#&*1MWA2}s_R;2ae{7r-*he@=KH4HCF&{*tkHi$ZQ6B*LWLH+AXshq zFvtKrIG=%OAq*~u#PKe#Vnk07$FfDrnT(8 z2Ve5y0XpfY2;OeRd;3~!#;FG0>6I{DFc15@jqCWWFq##~$w6v8E=wJpMGf z7lzu#1ysRVLRyRp{vsHjezm1$hTXM`)KN5>g02=vzpJ)8zwy0Ha699)fmto z!U0$#K;XY>JGoiL_b#@wucHR%LidKxuDdVcn^wL$H?tiN*qhvj1_=Yu!#d++3+2uT zL1#i|b_IyJErGV*;1B!_ zTW5Es;Uk%0GFYC z8BEw&N9%#IC73ZcH|Gx11v@I~KT3jwcGtQRpN6+@qGpYL`FHQYx5{=?=7+ku)N%CtKffS3*KV5@wlt-~bdR%Xf4a@qYZ3H!AvAp@wGPB{&Mn)3r+ z-K;&2~zH$apHPJ!5^oxKh zA_znM!*Z9EZ4q(h4$YW;FCk$Y7u-iFX!q-m z2?losFjd}*CSN1YN3zU*fZc-wZ9j(}=^LI*kj%Kx7fm1mS`Mj2HKkbi`}yu5q)ZS} zRi=l%7N?NfmDB0d&ngFVk-m;&J~^6>j_8b5vSkWfpk|KIscI@?wakmA3h7UC9+j10 zDZ_=ha@7PMdm|hN=$M-omW-;tOqrI)lV7^Uo-H8ud9Ej(lM7D7_6XmJ*ZfE^2bP2H znN^(!+TS(Lp9j+rK7)s_{UfhFZ^vuZ5i?G;RFci(aH6>qSGJ@1uk++-z%*8dN+syg zk7hU!Q?$0H1c+@)->JxUb8omi_o$q&nK~1W;qAU(WoV(CcGQ>uX|7sM91PkKqlW74 zEehT_T}|}EU;=&Gpr?5FQ~66p-E#vcNA759nNKMSKS1qXYefn$M*YA__~Nvm0j#zf zvrb@(=2mL=c+f7}+(=WX{c*(YhA+pTUB?2wb4G(uRHc`qQ`hY>TtFHuZ3kKi1E zcfDuw@pJWy1%N^5JGfmFf$rnx&~k0h6E{U3iwSQ_Q$kS+X3tG+_`g! z`3#A_-`!l40WMhAW0q(gvy>gr+2cQyd%;=U-WLZS1k>=o{=e)nh}*7Sk$JDeA?C*E zQ|375g3~w8`uj}%v&W`UU&L+w@EN(c(BB_#xln5kT2T&uWRzpC*dw24Q%oZ zW~t-w)s0uiEfn1lKlqQ!|E~*GB(dZMwCLd^#E7u@HWoXL+H&s4Z;J#J&hh_vUI(EQ5;j>hxSt(P*s)raGMFZ1p@yUe>~P0O@4l4Q#iEuvgN`U^1Gp?>&8A z=fSl7D0H#j&3+wuuj$K6U6I`c;`dFz3^$KLJXeXaz+5fiSkF>U(r-=&yGgQWAQ*Qlw3nN7lHEK$FfOdO#e}B;;<@$ zS&%c4x=xoa#OP@fmWaVEv%FzhLzPgwTcwefy&97KmoY;_h^qoUO<^}!vVYugi29+} zy~*Y}inF`eA^U9h@L$E%IZ?ENuTwI`Z*-`Ri&r{^siCwd$j? zGIt(M(>ldPqzykfB3P!_44I(6#v3K%U&U0L1?J)2GX@)ANj}~6ourEZRH7N&fjNmE zH`+7AicV&(p6WRH;o|H=W=vRR45>v+ucMk0JtaQIM~%bf=+4fqe)tTTBe5r3*lv5l z{eKI4tt^&m)32UBHL_xve8p@z>STx>8iZUw%cIL$dS){!zgFfp&OGZyxmRa%MQgw0gZ{`jYK{veWH17p2ULbx9`ETvYJUO^EooMJn7~`&50=4KoN65n-;2 zC(V7fnhr@WjPEu->RWASPRy7p+O2o313yWc)wA8KGsfDB_i^g)_XN3`aZT%`o2xpx z@F1?568~m{7F31$S{_Odj!OWKlldinms!O)7oE0$>PRhgp~_xLHwIgoglz!a0erC7 zB;OWZ?Kgm)7`4%VgwpGX`@YG9$qj@)Y@FRcsSkvADl#n$F#K6Cu){eEg~ue_381|V zJV>ePpJW`g(e3uZG-lrHQEtO646KfJ+;YYiib1-C?ouB+(Kc@4o(i$@2v6(weVQLT zI2iIt3yBCH41D5KT=Y3SV2Hu(wf)4{9$;RSI)Ev=8j`-4ovX#}sK*JsEobt@+xriV zb7Dm=$q?+>eE_-*WW{+K*&C3BF=3IRbzGt9hEttIRT8AeSh{+iP4R#aj%X=&N<^;$ zran{zUXTmioq@V5vVoNWU-sJ=D>P@Fym{;?cKH3vb!s_QbH^#; z<8K~BY|A~U@WSf1t^fHQv^xIBZyRlo|M9g+e=6!(bCklE=j(EkB}Ek%D58C+TE38@ z+MaKh!=#}IujEAix%bAmDQ3T^Fc;bqq!gSOgDK+F=3gE5Hz^!B`moST^EFeI;o;yo zW1L}FrIPrt>Di9Fcln6VFy1%h3DD6gM6zsexT=wIcO`g|w_~I9YP>R(qh~EHjUGQE z@g_avH`R!-<>9*Vh*M4{~``>;4mt1Wd3n!EVF!V$Opz7!8 zb|44#CW=4?^s%255AyPl>T7Q&5>d)eR;PZX#3FgR?qZM=3iLt$QyvHldC>*pKKQp8 z3yB+4=v$h@a9u`z2LJG~+lyWte;Si!)Ld+^cF0{uValw?W1aBj`z9?YVm;e3&^PDO zVAY@HS?I)%@^BksaSM2n4lB(1YI;Dc?4yIpv2r~`5*JgBtH9nyC zu`}>~7)c?=JB0k_{hd$U>eZV8<=04^ff|gra+-}zhAteX1`1rBnsL)>;G@tZ?*uy^ z_0hOQq4oOarInVm<<-Qxq@tq5h2|N{We@`P+xl$Hez9=Zt%Bmdf1&G#);yuXQn@a7 ze@=S&wZ%keBqj}2Z{)swcHA~CdMNv3TiY`e8_YVuf5tL(i!>&7`!`q=RG$At9eZpk zx`CXYl&(wfykxyn$g~yonEzdL6UYfp0o)>%70T803Q@}n%i+qx3#6S#F@6ey-6mHw zx^}4zSgw0+97wOJ>^)rCIJ-&)Rm0GZOM?T7@2ktrWt;pQp(}4X$I-z<_oKSD(~mP~ zPXtSqyHlvb#^ObjUZSoT8*RJsuWxb3t%OHj;)%Mkj0I-?!0Nk#i^6fujsiF9u-xAO zVRx?U-|h$?Xybp;yl8E;b*go4qu~YHAH~CPCV4F7`nbq$p8M~$D_EEDTvVv58Ev^m zXaSCvpPZLdDSevy=Lbv8B3W(m2^f(4ljE4%;7yb#10z2y6^-jf7{OGZr`aY|q`gT? zqpZjhfREyDIdKNVs>iIjmgp75`OEB z(_z+7((hmd^MS%Wq&La)t$jurqha3d3R!tDjj5FT7L^F`mLjCq$xNDK4?O$cP@Rmk zg7&R19LiSukhAANeCw`z7I}rw7H$MEa6XfSOG~20?nlXn2N!e7cC%e>lNbOOe@bfP z?Z1v-?fmNOlVKt5{tK|da@b}XzD&ICuzER&d!*rQgGq+(z4-bx0scstE=w?(TqU6_ zS!LL{`7&zWL#8+-bn9dEZ7A6^Qk1?7cueW!bmEIdGq3yAkDPMqGmI)FGbR#2`LSo=5@5@EgZB}ye)rLxqYW6fRNR_GG$?bk6Xvw~k4WIx(1AyXe^s&@LRi6&j=yDc>xR+k#f4(sw?tNGs~+o`fxu zxu`|l(-dZye{gV^mLn-kSyQiTN{^dFc?!`$m;qBHuv*JM07=*-@^kT`7Qm&|j#@*j zW2+|Tm#@Tl3QCSX)fDCnN^Kv`+wKd_R)Zx>KZif2R6C2t0_|+ZbO@P77Y?}tLmd~{ zYawaYjx!U*O8d3*%yo0N`QLnMkNdnESdkP0L-&+`sbRKF?TdJprQu@w`XTMgH(23p zsFsyB=lY?rX?}sr?vb5l+`sx~rmb(07pJ3ogV(M|d88tCE zmNj@s;gOMVW})?5 zQ4k^o$S49r3>ieKA$u%2>Eha;XxlQ}pQXiY5jQ6I>d?1~yKPJVP;kY)snMA%@xCQ_!e9->fwEHyv}FYfzeq zksb5VaVCpC3;729mnWP5FK7Heem$}GVc&j=No1$hCWT-LuliQ7^2oYiKK|!h9#mzw z1+(2`SFdi02K(f{%a{oV6#(~HeRSc@^WH?QvLcxZ6DYx9nOmyv&Vn|tH< zz0gqRs{_AAk_3)3Ymdh$UfwA(DxSmRv#!58zojGj!uE;+Yb|BZVT<;PQnQN_#|#!w z0K)~fDu&4sLQ*f9NB9mN%2t#jFHI`MxBe$~yE-Lne8N^q#Gtw5&u7m6@np5ev$td1>_e2q91T+~S9uUo#vS3l-=;Sk^ zW{CKrTmLbus@(P**ZRT^dQBD43zNja3k;y38g{{<39Xf%p;p$At|LaK?N; z^0TTq=PQ!Cm4H(4*Z*6C4p9a^dKqYtRvYMsE2o)DzSWe4Y!#iT0q9Ja`t`x1m^j1! zD?%E{(72r5cx$MvgEP^JP+V-s@IZ92vO54Q2&8%i&BOtSDQAkTI)?N~wPdcnjpwNY zrW2q8wzyt@?YTAZYQc|l4o_h>Ou2M+VubV%xe;Gukmv4>U4qiXb+W$1mYy#eq!!3C zq+M(PT8#{H2Ut7Fy`vd%HNSwO<;Q-ZD9;;0TqoFC^q+^Z|%}+z%8$w!)SCVb%zsuHL83qZ86x9(E ztiS{@j~9V(_XSdTg|d9wz$1^?Is6CfH*cTH4`1&H{z~L26ltCSb3>`vuqu!8@XghW z_?HUhsvRDG+a$H8e}#`&0koyg;OB6yt*%ClA|bnBv?y99HlWD&xeFg@(m}q{+s2i4 zaV2C4Wdx(#j32doSU4M~_AE{EPITJktW!dpd2)RV(qt|j8=6?m=ibK;E2v9T=l^pe zv?y<4;m5103{8*2$RK;#yUq~1`ZwA__ov>Y+|@r^Fj4n(j{H7CEqh?}J{DAy*HGY2 zH?yrM|M~f(#s7c(`s&>wDUDjz5#??+?)~`j-h1I%CgrXjop6B}P`76Af3->XcrD8i z={9iJTIv+aS{kK&k}zV*2BD6`vJ{A^UZ|g+b(hJ$8Jjx4dURRLJ%zm6KZQ* zzfF_Z9G+h7QNT<&{zB}e!4X@esD`*r?m$|O@7caZ0&f_toY+b%LCF%78{#B$+U6fQjLh6GP|o zIa&_aM;sc@aXKLwG-Da!IvkoAWgVTnNCs5)>o?sehyDNb==`TbAqFO9y5Y>KkN zi6aFq+G$mLj0+VL|F{=|f62p=&QTwe)wtLb%f`E$>{?$%-IU)%LWBclKr)Mp)8!-X^cmhtRGb>naUxyt* zTreOMzo;%tJ1DK{P9pAd zHGa!G7wb7H7jZ;!45IcD|#H6Fmzi{)NqB}u~wS^jx zaH`dx%5aOq1-Uo~Hf&QqMtvEbHg=dS!FmKWTmL;pyHhDA=a*lj%x#kK>Ba1|hgi&)u@i{J{ZeQsE8%=UT=fp5G|LMI%vQoChl3SnJA&QA3cY;t^JTm~k9ZIC5~<#c&E-MSuiu6R!DH2)=OT=ne-Ym9h;^*;R2f969e zVzBQ)^bt=-@nKQAB;U6Bk=58RBtU{jus2rgn-fFo2dueG;ae2o;AUS4G(Y?SoTQdC z#@{mAd%H!kkAKY?tA3|EES|l^$YT~jT%b*(q7%;Hw1lkz^#zxrTF5y=80?g8#syQK z>QGMH09#qiO#wXP;}YTV;Pv-={x(t%7y$}Fhnf}RKLAhF$l^dpkZRBvDTv5Lk=1Vz zZUYB->c1sG2tW9e$Thh4OEFW>CeKh9h3>-5c6Pazfp+}GX^>^NBxnD-%)O^SQ6Dc; zgCAm#MJ^QjEC!|Qv5_(uz*7$i-f|EM@5;EV{0h5iCB2dpQH9ZA=@JZwNdQgd=0 z8i&tvw!#cjQfZ1JW5Fn8(uPA=jH)Baj9015R4**g1E$cW;H?$N6H2fVD^h@; z%L$oma`|^zG!@Col|)l(`-^W?hkymz=sML`68fy?PUP@9>)#-Ywiqck%}!>3S8g3& z!I216xtN>EHUc`F<~K1|STtWDNP*>)u7A>3Z)?7dnAswNZzcvC*%cu3yW_Z8j9pNj z4RVCry&3LdQk}A_b`!s3d}wKEN3Qu{W%g!8ILiJ@;CUnE%<)#uWR6~ZD;<7`ns3=3 z9Ar|3I{t7D*7!N06^;eSv9tNlKm#GXvJV7vqW*di%<0-uCN-=UAO-m}WQw6Y#09I=j$_wC{4TX4kOU?q!V-doVC<=<>uj{Noc2aE% zH1phFEJdH-=ypp{c$L_m_5M`!z8pYD+4n!OP5>((UjGJ69$~^=r{R~=8B2a?%w7)( z{cGU@CL+aUV&R{YnJz=F7OJueFT67F7Da3fYA2rW018uwVR|z{BG+GK&L;(8ew+o{ zabK1&{HyATBV{D`<6_;vfX8T(NPb|0Pz_h z+f>WS-XCa}E>M)A#W^6kYDpz8fiI8#x)n-5DO^f$U#{2Xw*0#+F*r$C2@j+M%pgEl zTu|Zru0CxiCs;%L9r#!5QZKl~?Hj!>i_%C3sSaNuM4m_Y`x=r#M3)}nTQVGH(EyB z4h3R!T?R4k9Tk$~^F6J*0E5k!dDsj>A}hT4fdQhZMhnJjVdvs-1~Bc`8F$>R+g16y z%M47xxv+!nS2!Ov?xc|v2hBp!p^b<&GX9}x}7Pf@0Cpf0uyGm1vfpejuCSH*x zoz~~mSjBtk71i;#BF_h#rW2a~SD3k+vQ{T^BQCdoHiuowZ50txctY_qb8nW=<$q@c!72=9{T7=19gGtBIGlT z=KgamQ-z&LYgKIV4KNUv>Ij7bCs*C>5*GK)`$TeNg;TIbT1$k~*Gc$P$*N53bk^j- zh$IF-)U?NMRt07zg(*Vr+xGFtzff(a(iR~87_We;V=X`Bx*CN?|Y>cZS5Im7r!yOm*-KLy5o+s zF8=5I=1@XY@%yf+8y4|gti7$b#nPJg1Ni9kJZNi(%jF!m zzPri7)R$#o+-JiwHYHFjMP#eC!g~RJR`P8EKMT7+{(9V@ijQT09|vgkw4D{ zqbsXt`R%TD;%WZO$rTRGC>Nw8yd&Oa=t6k%)jdrupU7ZR)66(V%k~~U+1c{bpr72j z-F5Lq!|ho@_*jf~2=5Q?gZ-WG{s$-1eN+ZhTAVjrBeG{fZ^)rrQ@7doA2Y8hz7hn3y&c$w$tVwYC??AOmC|HE`^tmofFKP6^$ zaLucqlf*q$PuN32Iuq!*ep}79=z+mo#cd>q?&Ly7MbY8)rOib!%g4rdzOm=>$5y{r zo35abUgh2ItN9_=au8{deeI|q-&b|n`OffY+G)d>s{4*d|Cm=&+1)Mn3T*E6x2uy# z_aY3A**F_pChi_h$SKdho1C`Ug_c~vxXdNY6?s;&19~X5`k=R7Z-f&J^fM&@;HyVejuS*;)%{f2hV}? zBSyVjJ-ips4Mv(mw@;W~=pJ)@NSG_jtkN&Gz|;liqvQGvRTg&o|* z`GNj9*le(0sk3QRO=gE2Nf@^3Guq(Lpf#Lcuxo&RxAivwS@V72XFdWyyg~IWUWMghZ0OW2CL*5L36-)sUOQ_l&4%`e!WMJuNc2rnJ|2n=G7M~ z0X$HQ@YuuJ#{>^xIbS~fpCzCyCx`#hD}OxfcJ^kK2cgK1O!qKNAe4a9QNuOzQl65X z5S<=9E092q8OuX5>nzYH1itspfZjTK3KrT7-b!`!btl{xdgy!q*hhjxDjr6r!TOmY zEb)F4X_SG&NxqNb(2wEmqO4=6CzgT2=C$FPjpo&{<)}Bld`~KK9xd}C;XBcv-LozG7T1ePm zDZL_CN^{8F?3-H;o=)3bb5 zx~=b@U~{Ll=4pO|+(UDeID!M%iOZ@KD(a2x+9rgC(%4f`kRs{#e-FA((QcjpE`toL zldsvGKEk`kBPakgSXT-O?RE3HP`!3O+=19^sn4^J_|bC+XL>dI9cV)e`b!qW6PRB% z*P>HQV4Xyc41h`0mwvGWbiFd!FRYiOC)LL?QsxRO`0YwGx##Di>4$_3Z^FNYdof#0 z>9-@lfnJZNUrkhHm9dbB9oG;4o{x*yndCc*c8{4`&i1NntGH<*5PRult1=wqw#f2) z=paquEwioz(sP$gWO@-&}HCc|HwGwTiC(zaKfhtSc_32oap|TA5)Y*78OT4AbS&>a$VH*ZtvS4mltWV%&#Ar zvn_}ekQLIeqJRGoGo19jX$QLLPH3C?qSHrtb?=Y&RdMM*MP~kscy9cuHkZ9!1I{;* zLL;uyR&%ut8JP`ai45x2kAeO7j->Kv;u}IJ%FF;@z}+YM0#1X@C$eG{*#5;3wvK*1 zvrG`BamO|wxWM;6i-RR~ctC@R#XQ6ay_g@{f#Zorl;`p{-S^7rZD6lpJn}vo6D%+( zW-+9SgHvTDDjKB{IWhvp1})|CjYdtPoGjK#5E1Ye5}*8f*sbY%neA?n(BD9Zr5z0P zKN!7rqV<$LGKCwx1*&%zrOo&xV2&-`{5aRq##Godt0*#a#b~e0PO{=rlQbxHMR#Lu z7|sEJd~a}D@0!4totS!)i1DvAsPWhf{A7bzv^_TG(SE?FF^mTZ)AtLzC=0+iKMYdp zQDu7+n#x~f5Y{gljB@`xUj2Lpr>b~+4hRYfpQy8wft%m8551~#L;5(pR9s!dcfwSU z{|yL$ug|K_ulf@4ztvIyN9gwd_Itd~ zKR=W2L$pgXfN=C+z&waM#;Pw5PGiMoeh*J#6<+D4=y#DulM&RPo4Bj&^z8U1%V|0 zq;D-5!otzzqmXm+40RLDGo&FvqY(KO@&9V9z)odnZrS{ z196+pN!>95S8KomhWG>yT9s5t*0D@4x;*5Bvl3sf62H5qt#Q^1G;Ua&>g84U8urFR;5a7y?O>Di#%+m;D`hSiu@+an`twIn zMMY^SH1L7!^2vA$e1h;JDTxMAtE)&+?%QH6N6y&SL|i$7j%hKW;y4qr=%31IDUIx; zTF^0Cqn~ex-%HjiqO!^eiKftjIlO>CAWrhzUvhyJ?N73XkL@n#qug1KppSEB@6@L|A&IRUD7? zi|4xVQ(1F2Jz+t*iq8ezJnn{U#@nUz?p*W?3YDDMk-Y73;k=3HV&Tu$&Bi|ee1R+L zOZlB}Wai-MF#{h%)Ro@;Yf&oCLb?$lBV7Q9GJI$V%=j8xZ#B%}BYYXufji9kdaqzF zpq`5nB9dz^_BI~dOFiWN!`$kRhn~lSqK4b`MWGq9{RM1UnJqQ?sD^r?YnfYzRJYR+ zyeXFBK(`B2_^-Cw@9c82#559h`l(MS#-?=bqEo{IKtQi`V1f*7v5=C#Gqrxi)5{$W zMA6P+n9RWNfieDRr+#&`JtJ+@zheKbl2O*RIg*t28+l4%dHIRhA*^{=4Y@bRaY zfjIcfh8I9&SR}CK#{Xt!HK-8Hw=<0eYujh`O zhHBfnuWWPpdwV*eVX@fx;-|m@%(ajevUzPturl2DxF4A$zl}v*rCRdJ__A`{aog!TD8XpVFr9Njm5GW_w#t zD_{E_xkb8lpKO1+$^q9h(902^3TUfO{BD1AJ34qs8cufPU3cHFYl4;12u0P@P3sEH z4eNpfp)p`l$nM`B>vwHF->9l{K&S9Gr^erT%CL^xL;sylyf#!(NOxTu6yNbIIrPMQv5clu02K)3~!4lWM>(XjwzS%fD|7yiTylN|C1gPc}L^ra#Td^}$VC zen6N2;ZHJqvc!?pUg@j}wQm7!@zdV}jm(eC-H4k;8lTZ&%s|xtke(|&go}bZ6kKf1 zZFv3ZC4d7ihq0BTt{2{Lv9eDpSRBVd);?I3oz?_!ed88YXPey6@fX1i5PzTePJ z?wDgGHUclnj$?K_8nt*DsP+J{O{=Amyf-Ds_wG;XuKz($)f5xwCZGXQ&`(9#OWY3_ zJ~XEGjU$Pa-4HP^SS;m6{e>J@lDxj7xSXHWNiF^Z17?eON5N_5s9*S26sI1Ucgg6* zsD7a(Xe^q414oVLDm8Q^NBWsJksQG|tzJ9E=1I-b&?4J{kTBjgj-<$HDh(S95S-(| zz?v{kUObYbZb9|TA<6;(H6BW#I`f~?Tvyns;%amh&cu!c7g^a@cSDh;0(<^Vo#g=G z?7Py|zx)2?%hPzsW7e@mF}~7K^*si|vjy}MTGS%W=2X97R&QXeu@|i>(w3eX4@FHV zxI=?XgYXG?P(S@*=8HQ7)2aE3yuhtjT{i!>;?}|DbKwR*FawVyi6ZW7i3nvadpF{o z4DCtocj&!^dyds84gaAB;B2CoGjbx`Trft-*qZQ*Y0p0kW3SMUtKMJA>>|xkBtfco z@Mai5h-x^iKL~&J?@C)03sFr6c=MD6XLZy)2Wyo;!h9M;6QRmFvo`5MnWN0AXE@4; zVsuqA=_yF@m7YH1-H#c6_E~CFYW~?7IS6Hq> zND^fJc~i%plkTvkk?$|ycz8iLppcwXaD!|?TN*v8BNO>dME=VY@n{$s5c#t9j5hP) z-#vHl{oX=bGhbX(|&=denEgqDI<{+lce9#wPL&MG}ymBqDG-1`YSczB_ zU322sL0@J$vwr{X1=`m!rWYVsJN?e#6|I1TFv zEusSP8Zx>|FTr9oL(N(e)2?V`bpLjcGCas#0;nvI{#D)vCxJ!mWUQ-5x0Bh9a@7fL zV7?8#O=KLK>j#R2v3JS3CL-dbf+gFfxB?F%5J;@i#r;-#Aup#Go60JE3<)Q4B55C} z@C**0b^#gHflp0BDX6VaI(Df=Irtv2K!#a=!3eJkIPi?5P^9O+OolrF&?U8c)FsKR z^$Yf5AJ6gYUJ~ql7ST?HYJV#Dn;Z%*@njFk>17ro3*~AC=-k|XbBz`6-n6sNrl~|zGyBfLx*8XaG}@u2a5FFsw=6FK_gRb#>+1p zkgePqj|Hj1KmCh30CL|B(yMd#F#jM{ngVJOZL}iS+oVzO%>0zN@%gDXL8gpo?pAV$ zvQ$wSPZTIc51~;Gre2OiH=;hY8Ya3<2Pepp$MBv$Rx>6FLry9*;Ja|wcf;MltN`Aj z%Lj9ax#0f#koO52NrEbuu_NU4?A_LE-(%$lkcA`qcn~^()0i>~ti%WpKF5kVCg|DpAzr49$9VSMQ~MKlt0b1@ z>Ix$5EF4qP#?1M>tnB$C-Xvbi1o7R@V#67A{`B3TWAoKJyLPBrK|UesKL6jdivMS} zQ5I->uG^-(@@t?09eaH38S&mUZ+3}^G*9bm_~KXdE4IObhE5U*m}bK~pCU`GC5yTx zjVh{lzg~^ZS?GaIXzn@jW%}6bOn$-?(R02CU=pCmh+EOmkF&f1g6{Q`iL4B&j*w)GGG`SN z)UtW}?%RGN-7h{X)02P*`LrC>L_BJfXFRKc4e@(7^kGXC12qI}XU5#u;XSff!w0@> zNP_%zl1p+LKQL1i`I=aZc9>7l5$QJL@ZtB)&a;Qm=3mqH4$*;oAZy7=Mm|Wteikv~ zCKCA6wHI>Wo~O({6A{p5c~&7}WEKxLh4lk2KtDg-hx(_y2tvy`5r``vphU5*urt0*2;~XQ=ZH{ zy{@Dcu1bY_^MU#Y1c`^ofrGrI)n?)JW{9GcopGEp3CnzJLuSQGts1 z9vGm6UbQZPh9Q+teZ%eiN7Y5QY_X&1nAuu;bsys*irMj__UZtSOE!|yAWZ;foR&qr zo9Q#>-|K^XNnQBiEbeU%+zw*tsUJ6ls;0D-8`vV}=`K#q_hf@76@cDd@H;Q=mg1v|EkE5@dWLr`VEavE zB-7ezmygqCy;AhIfjs2?Aw?hXcfO3>BEXrmj5ey+Zsj%K+{AHBN^sG!;90jFtFNce zysD^txcyLo8&F*|-5&g@b9WlZdY88U zN4>|Ve{6cxW78)E>}Qbn=nU=n-J&hf`ama*LmbN+gpTkzgD-R~w6+{k>0qBYAh3gZ;N;k`>7=^62-L`QqnJ4yev_7%>d4sdH>4NNMQwcutv@#s{^r_Y1n6*ptIj9#BJ za@l5oWbPd-P=ZpXS6LqRcYP5e9zj!^O)`nAG3BaTYQC4lCZB=#dRp|FGW>Oy8@CoC zNeLv76^94`40?}|m0C!;lSXylOTy4fcMVrLD*;9_Y zDX=T8s<1uYy!KFed${)@1CtDYo+?OP4}H;fMb?CZ?^%^ zxlRVcEuwWDZT3s?pYfjiM;y}wY&>?8?Q-cRqI0FEmA2Xh)`IMIyGGS}{ytcrC(r(UWD+Vd`3MIQ z%?Qh6EsA5ZZWp0iGdJqZe%bvo!G?Cp{qz$ky9Ab#-5fvp$N)5A1NRU4&L6C~%W-5@ zt1V};q8hkV3*{yOyjFb_^xGhHEcHhW?4In@dq8Z-mNB-O);go{gS~;bnSuAkhoP3D zj#z2Ur*Q>U9t2qGCT<(VFkj=dXC%+v2O6XdaFUWwlmK+; zlb52SQ|wrf;pIN{{am6fGan99X!gX$Okuu8H3BzbngXx6F+#6Gj{ZWI9T(kgwfHl+ z!9BXmjVVz~D7mu*v|$BHWb%YLG6bsVxsl3G-&IMAofn5YC4w^g!*H&&-CQ73YrmGO zDT$cn&SyNmhnnfg5T2yS40afI>(2&@_CJJrU(IrtjL5H;;FKW1^E;Faxwlnu45K+o zuOA0&S!CQ_C31(e#FQbZZU=HC*Sts}_|`uj^ZUQcszzVi{zRQ4OF8gr5Ui~*x&n=_ zgHJrXPl=#n;KP?kJ;Vvos?DIrb`IRyMjeeTiQ@kzUl20LE%3=4s399Ul6^JPPZbT_ z&PB}1FjqhT^6vfUQM3~=_)&a@%j%DN8Hx;eH5%Mpi@Kqd*aVgP{!EOcrCg;~X%=|s zo8Zo;cOfliv5GV2Rtael0;a4}Q}^}!pv*T~;bkY=OXJHP-D8%jwSW^iV5J3Gqmq0d zGliEaoKkfoli5Vk7}8_3efnt3psX)?2_%busd0QxdMFH(K>xxAZVbS&z*+x!U2gTzzm-DfNH(a-uLfJpR*8mCa8o-MK77qn6$xV5|NMdWjbTRIiAKB2J|L zhv7m$DAt|a`2xl0R_MdMA1qS*6;?_YTB6{_f(;;dd@e|8nWZbvb4*h8KVqWu1*%wo zn-|?|tCpy*ccPB&;ML~X4YZG|7_9UWW|O+NHUqaaEDykj(w6I84MP0b8JysKw?li^ z9!Ex0!WZ`f?lSl&Fd%vXW5>alD^I7G!ng1d=!>=tBnl5hr{&jGnX{pu>eJxoL<^wm zzvKV>#eU+i1l;LzH3Z36 zeYWh`9`LuO3$7>fCl-lO* z<{ijGz|OV51G3Jt$>tL_Yv&8Y)_(_+;uP)fAOXV5_Gl`%29KRd{wzaEj>~3(Xq{9q zu>Q2CXjQ)UgiB=G66wJcV~XiQ!|sJxEE`Dkx@Q z+D$mU@P?bRt3us|enc47tRx?MK5mH1Q~ z-~wg(a2CCiQ(*?Hi}hfwACNaNzI$0MO?J;V!JnYg4PeS}|Pdtbt;Ka--@20~9z$FmxywYU|nR7`M&Ct)PGmcLrW#;f8|d1Wm^nq4YOjbz9$p9@gmpPLKKDXKPRn z$+AVK>zKbQjq*d7&DB&!O4hf%bIh7}W);YEL-P(K9d%04(-r8Do={c#4aaO@dhzhj z!Rf9zQ}Km*Fo$9U#Sc_?VwqYD&IogPyH$p8zRxS}+BNxNY$5j$O-kg4rttL@?jh1~ zI5#jCJ-sCa^HJE*bA75^k+0_n?`IBE;@>9unaXo2#htYv|38pF{DcdLbY-{)P^nd zl>l`NtKNdUb>~J&Wp&yrn!G3n8H`tgG!1B-thk=sxvw(Kt*IC-z40y)+sx%sjIWkR zi^Df{*UTH|R7aFWR5CAUgxc`EA{>JqAE zTG34wF~S3)j3>yAJzZnsa|x=fisP9TjFV-ZZXE#5F#0)-sDp4(7K;y>ALf8oQH*uP z`BaG@QN|Qd7BhqgWawtV*E`b}d*|6_RjRq%|8+N_gA0ax)S)-$DGGl?YG!ba2&Y67 zZPO0!KK(eIMJ5V4|Apu)k7~+L2Mk?NtNuXXFY{n2!m1$65MIERUC|otP|;7>CWk2cQ-4KTWvI-G1tG{ zit5j6*LHmimVvx&`cO^6(dI@(gWC~bx64|xm!FnQ>USPbJi`dCrqRC68e41kLW%mI z=%l4UjdsUs_~4wnmb9M;i}al5Hxh1L_dxFnVKC0$=>Yl!S1y~uC6|8*C45e%lqMTg}cfV0~+8ib{W}cDVj5U zK_``g_9&mTEz*Yk$vnzK_=r#?E^5GHJj!1BrL;!6iOpFYxVs&5%QtN?r)2bpZu)fw zE9V?X5)rMI3QgrI%)(k6-n`=Lj&(n|047@myConyL62`UZ27ePg5H<8=L9m$C%y>D zY+ze|!>^}2)2r~=5|BAimI;*>X|`7|3`CNIb<*3_Nik<)sap+xhHuM@U10gtIm|7Y zc9TZw{?ybUGJ(bGS^4+-!}F7AOBPLO%XzkKJ;r=aT8+hZ?D@S(n}SNO^+cq;J{#ol z5E1Wk@kddRvR-3;oYUT~Ma#~(lfaLol`o2QT+R(4d>8U4)MG z&olmA23~%*6*Y&?cXVpCAe3T^+y~Ug99yTz6SWOSxq^dYu$}B;x}9@Pp0c$D7>zo| z?ExE)@}Y3Wk08-}F1Tdw>meV$;d5)moD;5{u3}HUi&GCIDOfkPue$*8-@!6E0SJ!E zeIEt9AlW$0JB@AE?$$0-8i^r^S=r8%9k*T1kKeXy%cFiaw2_3|nbVEC{aHy?I^ONS zFl55s+8U?@NL|dxocmf|WHByAF{f_K6PSBixOiZ&y=u1?It}l0E@D0A4uMQScwq9* z2>Obs(8_&r2<8X5Smjj&%^O^hMBtcJKnV44Smes=_c2FxE2))Ytw~Bdt-bh7w{2y0 z&-_k(>H5W#wn4>FY@djllz6Nzm?&kxbIu%DgAz;b#IDnV;lEuvkD?JKv7hG^CgE|#YSKY;f*H_R8Z zoyY;BGx?fu?F6ZP2%e3m&W(yKo{(yK7m-FSf4}ia>6ZRINs3pXM=6}c@Y=wUJRH!Y z`9pSkRDiJF3LPJkVb43IGKasIO>JimUq_CZ@!fZVm?sXZL-Dk!h;JFA&t_=k_OVza zrXZOX4~?M7LZ=yc%@)y2-Sf%joxjNVqetKwTOdJI^pOs+D^i)Fi6Jo0x)%qH6c6uy zY?u%tZge^TLf0jyr+H^-|1R4DyZp#?Ieg!GN&ZG}G$vbl@h<5T{L}~<0d`X8Xw&rM z8+cDnFm?!=-7(U%G;PA|T`fW_nbj~(gWSEEf-YbegZiC4l% z-d`nwH$?jppJy{@DN6NubFkS_x0NO@K)@-&UxZXe*XEETZ;?V&%vP~BygF(mH3d#p z+V^AwnJ<=73|^cS$$eYBVNHvN(1=UcRu)*n&moT{t`p5d)}y$N593fkYG7POnn^l- z9)8Gy*Bl3z_{2h?;P@B!e3w^Si!?8SRO2fTT$u#bT^lC_b}Ki>{jiWGjv0gJkj?QZ zlU;T)Ba0`Q;Y?u_j41PfAO3w6q14E1x}J#8tXZxM7x0hldj_5z{3jqQWT$?0F=Yh$ z&m_DC?D>i_aVKWLe|yhb3zd!Ew+0MpkJ#j@bf)Y;lv4fj@?ksWW)cc1J$Rx8j)}q% zx10vofJ&Qa17hlhn0N)2-Jj2I+B-9ig^-5+69AfdAIki{<+v}ZAYm9$}G z2PT#3PXs@A;XvRKj4XIsvxfqo1~BE`5@X~@AybGt>#Poqy!7X^elv9`YJtDHD6trs z5$)Lv9qyJIO}Z*wwjVs_ifT~^a^AiMoJEOh#Xi==@H1$W$~RZan1HQk%vzM{BzWz% z&L_~wD-Cneq-?>~*8v>5PFJcxsoo2(Mc^lOi670)@5Fu%v2NTYF!!0?*Ck4+JA7n<#J}<)JpbHe%dRIczDk5-cemW`ReH82<$* z0JJ>PR&nz7-w$F=fMM3+%|#B1mSIS^q$V@?ew;?E`x6>nJqD?gecKU2=WdyyI{ni; zvElP2idYW<{}wFYJ3n7p8H|V+*9EsrdBlN--{zVqHP<$8m)G1F0g26;hXqF-)7~K( zGq7ky3%3FiqVci=ul$=N-7@`Pw(&tlM~Fky6~E#%F1+>u_y~Jq0|LN#=wr&A%#gHV8fUHl^>XCBLADYSyk&d zk38S4)U<)utlH*S4X*o3R_!pIJggf7kc1hpZg_3J;%|eSGw|xr@v8Ii_p}9sY{rL= zd8r1Tpk5T}L2n#Z11FY}cK~GD4@X0ug$uTZn4w_CNH$*=8Xhc?yb6PT`R%QY9Rqje7Es{PnRy?u$u1H> zN)vGdupXEXd+dN6Xy~I6;C(`8{1UillAOsyh)rgC1twL9Vt|Va-A&l)SsbKtbD|_V z_P!id{g}C=kwEhJ>z09vv82o~70x z)U8zC4gUCVYAkntrw|XXs=EpZ5tA*vO)Ylmq0q=aReluM1<|(F3a~UWiodKEzz7%# z_E_2^ycRDyNDN29t04u(6{!ddY{bZ<-)2OsR5QU^ zZ6sunx&Zi{{FC|;6Xj;_v9t8?@7UOzVqf4MtDDWht65M+cTti`_-*%jA&YRR3qt0oqCQZU8G2En<{95|Ej#MXt8&u0Ebh0v!DB>}n$u z$*8If-s5USd+;-4Rq85IrkTPOSx-aEh>iCtop5lU>a;;hhLeU=74tEcG$?TfB!izZlrs^J9;<%Jg z8n@emJvLaR%HH!PeT8ZQr2QI0rxVAgeYP(4PiD8@k7?(sv_2-IH=H!32SFhd!dNkMF>FA_7G0KJbj~Gr2yas<` zMf8;WUe!~k$LqU$;xHS1oesLl(i_vTgii0wAM*q@;qC#7K#&=m?b|;K%?^Mw zRG}gvz3etkxg&+rhIZ}~?zVgPIEdI99E6NEd-5F_TEweTu~HNjCC$wH6ABLV9REwS z-yJ`X?zT@zL2|K$m5=x$$~$n~ub4*f4sL16Y^+dCa!_WSNzhWgR<6noQL9Vy7iX)! zr=Y^JJE9q$6BCWh+Nw9U;iX>{ePgxntl8&oheSpllHh94$ZsQDK#myW` z(mfk+eyZ*-vd8rOV+ZLc`X%YAJmn_EQCXNlk&8uNjbo9T$)%nfuC1WFZQh5MSb#w{ zO1=`UdQZ3^N^dFy@83qV^r!EFRh^{>^WknDu0)O;22?u(aG;(NO+~|0lc$#0v2@aA ztk#P+9=3tvOU#8<6ztrh0>KJaRWQn9&6@aqr?CjfHbo64uV5E~x%O0dbKPws#A?Nc zlMUsifuY5|QNHBeL+IwE@QDQjy}PS##LTGx-7u-p?P}mYuSCZRu`z=^%iUA4$f4uG zC|p~A&zz15$OE%?#(S=&+X6HnT>bW=3`e?Wgx>`^NIr=RXbQ&`6DZ(ERod5FUE9DN zM%sfubac>H8k?do=b$(?UyHLMl$GC6xL%7yD!@eC;xcjz|2+TxHjg&zyo}%5`byM{!o2a9M z%vqY$*8qj8x*8o9ttAkH%#3mo-iBA7iVRV`w4Lo!8AYK^JjV>DawCCNNa<{uu!)Huy_};&2xwCh7DsnXBAR&v@(6 zrM_Fi_J$?aCLMI53a|F(Y7LFyRxwb?ztwuD_wYZ8y-<3f>lF7|C<{w>d#zJDXkL_# zezg*DBKQr0#ppD=Ywd5`j{qUfI;{IiPhE7^m!XqUEp6Okmzf3CsoUs#e};-YUVd5>Eo zsYmV|9!TjFn*;osDtj>6={j_FZNX_TP){)CE|$=wfM=I$sXu=ETZ5;+_xg#x;k}B& z4kq9JRrR(mH?@8;`KiE^^;HA0e!5IwuxDVU)Cms;KVpu_y5>ghZ-2J-DN#26yX*{` z!yGR5_=wzEe*d*m(VQV`PN$}7Sxpjfc>ojTxW`gLl3N^l{-On?@%A}L|L)e?oWq3= zloij#b1u`&NRO3)YA^fkFPEP0Qj}iiv*uf348MFy+r!yswzPgMb}#OvvDOJ=yHe)8 zvNIqSd|*TX9KdxQC4-02rKLL$ac1ITFP|>Tne9&Yh;z&^*g39rWVv+i)eH#5s@PR| zQ-|yH)Af#A?@ungm(&rfQJKImbT4i?du-nmzuv!jy- zJo7NctoOU)no>WpxgW1~?FGir4(w`0h7qRx$h7@5=~5Y~mEFe-UFvuC-WG8e5N^A8 z#XIZA%wmJYdj)CLd0CaImQ1<#A%4+R_shv+MxCY~;SXf52UpoH@s zgbC=SjcTHRZCiF;>j3>K;m}X9ZW zZpuQ(+(YLKOs=oYTi|l7cVygNU*l9}ZOADcPjg^ONvd!C3RZ5Jp_sIB+9*4#c+ zWyAl`+I2-WmF|1z%&0S#!&m^7rh@25Q>s$0!ysLxg$|=2Jw)j}qXVdDKtRAyl@2Kg zgai^uRHTN`A&`(DEeMj(gn%h?Ki}@UFZVp$=OkfeIz`dv{ESCO2@bX&b#t^dmL%yTH z(NH6<87DQ|p+GxxwEnvz`ezRmvH6cY$sC%dW^sE+R-Ws~yx&1;=mT-zs!u_4c@M#f!iG#0})7x$x_DW~SNa$OeG%FqJ zZdzb9N7LV%NTTny(&yUWKI_kp&QYWaD3|GMW5q&!sK8F#OpgGBgMaVVDU;}*5E)lB zsIGJVi(^mj%qEANB1+{3!Or6*AR7kUX?c_OO-y8b+T+SN8)}7{&A^xLDFXaRE~#SD zOs8VQl0OgP*sz0hyR}W0y6}_0$yO<<2qxKjD@CL3dSIljT-h;Jkb6k-;;SD+q^V+r zc-)b$-L4iTF}?gP@z84B$^WYTXP+7XJ`N?lak)xMb9Hl~0IOm2l#~pfh;YThjs%zT z#5@#|uY4`g=abB=$38^R@f*jn5R(_7f<6qG-+cLOAa{-Vn(T4MqBguFLqls%yp7 zd{IbE5r2ux8rw34QWrASy9kdlV=QKQjIO98CcGJl2a!RQq*7SE92g!kn%Nim9%`W<&oXx zC{Kl1!T7d!;jAD5p>L-w6BnjN_5+j$)F!IJzrR8^YYOtz*lP$=~2nwRpRqnutH&5lvxWvP_~(P`QE9n6W3Edzwaw825T3<;Yvn|-zzjYcXzX* zC7!^4)s6!&k2L+0sI%!ne-~vza)W>Y-aVER<&Ftxm!FEY*^`MjyM*c$d6`|W6RJZ@ zn-b?P4BsQT{`+bMyw~FVwyU$W!ynwGN@q)t20`4F|1Rso?@ZvA7tM}@2vxi@qzVf; zSsR8oN*v3I&uFj{UZRD^J_%F;Rk?<0ugydJrLGORb*4J|G~Ud_QZO(=&-xA_=gU!qbDP-Gz`K&T$s(ATkm?j zJN4f3pM5`me=6aLJmp3Sz> z9aP}wEt#n7iB0PYJS;~-MF_C74f}DUtbWxu8Jh+$wnaUE91gk@f0C`9O=>=Elvl6D zK|*dE2FU}Pz7&w;LR0*AS2y?g@|U>asTlw0$YL?Hd0Y)!8pZKc>#VFJ3Nv01`e#^s zsMi_nxy@P7%UNt;irp;;+%1&@GS8B9d2&|W3r`I@Tc2BQb!_R;#9aMMwpK!cLr()^ zs;7ZgbMqM<+K{*oreQkoRv5Tni>-7ruIK9Z$`H9;OtRMu7wV=GKKJd?UFh#BRrd%{ zM1hS~D7>kszY%oYgOI)Cd*Ux@iL>*t6FaM7OcQ1}-{Z8gclt=~dB+9?ORZC|3}l zOyjdOBXDQA?H`Ay6?u`0L0O5FUKlZ*>Z2Ar+BM?&v2VnDv7WXdF^df~^GMup#;je| zukWT+>XoMnO={_m2$y$bW7ryp|6(q%1A?iA*XHWqw%@6?0}NrbV-ChfYvV# zmRByZS6>EdKE=&lZ!XXLsv8wURt}T0F0x2CvxJRu3-B7wyz6k$*(h2r(v|<~L;DX71K|;xh$cUz!w9RUKfd(W+%NE9Lf9lFA%>5_;x{HLsIuWcws`q; zAh{-{+2mx^B@GTgEB$rZ{Z*UGcpEjJ!4v}Nw1_zi)k&68ezLHRK|r zJY$v_GlfrN!r9o)wot;q^x`TIOkNGIfz{3vPn&1ns>o% zAOfYJRobp0+`@W~Y_9mtCR0N)+ks3e&=r0(L)|QAkUf*=qPi8G%+|FtjNpzCgQPm! z5gStC;P<)}!(DLe+bfBH%~Gb&t(*)=TsCa`P7CTb+kzd=ERmgKT8ybrI`*z*z1g8SMczaVLa8mE2GA~(dbxMRhEAPA=|JY zo@i!2hONS-&D?0p;U2C1KF}%wK@=s|$1o@VX4w9BI3QQCu;JFVHPPh(2by+T(Zxax%sBT@ zS;HKHhmZQrBP3}B{-{%*XV*GnzIHO{4P2 z+Od{w9Yzo7XpDQ=O$O2PdOto33&M>X!Nq9K+D+|~z!?p{BH)T?55{s?v^bn`!bXSr zPLN`T5j#9W%%}M%`MlTJ!5pb0DasIB#*#JLfNaW`vVVrf>@6*Cx&1jZUSEzAkeo~1 zf?eT*nTcw1G`1hmSg%m9dw#T`wXfQBz1~<~{ z(wxOgoG0Ice{vr2kEL}LzdfDK-I7ODm2d*H6t|?|;?ylTSARL`$^2Gq3KZoYs@ssM zUE}n9bn!j#GIBGU_y~P{>^l)t|-H?AW z+A7e;em*b)P&f~WYS@Vu=SOBOmVQ3@;uf8Rbl2$%A9Ic^!o2MS&d&{vN9-Qdnr=?J zLt)=OH+zyd?DI8S5l7oXIoES@e6=FPTM%*S88j-A5~(|0_l=OJgm6^3kJ!@S1IFdw zmIyx&xR&Tn7VsWYak3xwVBlZ(iTx*c=oNvwjlWBoXbj{8^nr$)Zc;hL-2{ge)fpd^ zS9-o1_CP_GXV@Aj+1!eG!{mG-taCZ-Hw~V}LQf~Q_s@nrPcijFDNSw8%Q%V{WyEKm zR7KHh+9qDKDBf~dGS!I95YDvqsqt@AR}ZF4_kj)gw})V)xGG9H*d@a?0fVqkIi37j zcD`O=h~EY%$lc8tRFW8pT@xLuNq(o$kdO!;f3v~=sHV(k|R$L}*em`8i%K6^pD4vUtm6zSA{35=^<=Ee2q)dtR}I8tpX2+1*T&1@8|T zBI_O9Xhu|ply3Ae!<})yTQ*R)>~eh{$|bN2ILq_@U(G3nkC<=BCVqIYyKI*|0;cZ! z(G3;^<=tj>!jk>0ALplCjkBR}9XXAUdvO`A)em23zxyR-G01^i^;~67zlo^&NG0W; zeNH3*w}8J3nfI>#`m!>@Jy!1A=Ee4wkVMrWO-~pEi@-1@*lam#>oN5T!5_vp%gUT= z6CSu&0I;U5`}tyHLy*Sp-~ulkJ)Q8=DQuY!3w{LZZhWzYyv|FNq9|ptVuOEyhC%F) zn_apJrrqP%o)PlGEy#FoRITsRuV6G|sR4!Kqznvp@3Lpw_8`BNi&uIHocilv`aD0n z2E$^d!8t8z^wxC81N8xq=|oT)aHnbbx>$kt2rRT2_4!ktPFoZ)E%x9G8fn)pWKlwP zH+@bKR);%$vcdL|7HPl>wWTL;8r^X}zStM}Z4JRyT}ZdK^fSvX?9ID4NnuaUa1+P3 zGM@^=vDrpn_r}g=wX!ISXuIRF1w7xnL8zjVo(UP;eH5jSK2UOjKI4FV{_u6)RnnrE z8$qx6W&83j{o|8O>#I4OTz**nAv&0y9{!CmMepetq^mYY`-lAKNLOr3I?nmrb!IB2 z3};B(-m}t^zkfMPh(>H)a8DC(f5=-oEq#Zvv>W3@xbl&DWY&(&bVS=U#tj!~9vw#q zHDw~V&k!Hg^X3D2(t<|?i(%!P9MJ+C;7U$ZsQ0X$@_)q(Mqt_qzCSSPH?z#F?wv4I z(rq+dWW%LrzOy4n)H<$;)~C@-0{yq2Ui|KUy(1-JaW=Rgb<%@OC55Vx3c7Bu9t>^N zzJysy=2a34PNpjZj}Ip5dHSrMnE>MU>cJmcwr8f}f*;EnI8lBWg@9 z|K@rUYcSDejtL^1@TI2Sf&RS)gs7Hm5pHELwhc2*&HG;E%(Xx_XWvwM*svG31dm^B zxS_CS%nJ$ZektKH$~a}8_&Fqe;+u|^O}D{;p;CcP99j>vFQoTX&p%b!rNWRY$^! zK>EzP>0c~H|6`G7F5$in2!nQ4ALqBCv>Y9@yIyQsflRker4F7oKCzo>@-49dws9I1 z4(}ju2%}KHW&)F6besREJo4Xo-4T&~=PVY~d;?lRc=w8EhoUbv_ns{wN_rbH(;?e9zsj=P%M?Zj<`(o%=e1RPdnwqoU*nOyHaob{{g+fF| zG#>^+C*$hRVD|^b_5EI=V3|K6WbQTcL?NSz2Gw=gwY>m+uA-=}ru)@sY;kGoYPM}* zo(@bH-%hn|${6^WlNsl?M-JYi9AP-ES6nI|6nAw-`E0}HoHF%3T`BNsA;6Wo0p#;A@Dv)Z=@);?K&l%Vro0KxOc zO!`T9ZL_ml4%5s zR`?P}7=+1+j9HWD4dEKtp-r@TOk~~4MX@*KSq~ue>n^gyRJBm? zM@j>vT;RA{Ht#eMg|QXih7{TrOK)R5-1^TuYgiRc?_3mJGV~x5byG^ z?U%BtSa^r~nV&!5Q+2su?F*ZW4s%15A5K}~S0q0Eb>qvz!zxUiD8L69UoBvG5%8hpF$RC Date: Tue Sep 25 10:38:12 2012 -0700 jquerymobile.com | jquery.org/license !*/ +.ui-bar-a{border:1px solid #333;background:#111;color:#fff;font-weight:bold;text-shadow:0 -1px 1px #000;background-image:-webkit-gradient(linear,left top,left bottom,from( #3c3c3c ),to( #111 ));background-image:-webkit-linear-gradient( #3c3c3c,#111 );background-image:-moz-linear-gradient( #3c3c3c,#111 );background-image:-ms-linear-gradient( #3c3c3c,#111 );background-image:-o-linear-gradient( #3c3c3c,#111 );background-image:linear-gradient( #3c3c3c,#111 )}.ui-bar-a,.ui-bar-a input,.ui-bar-a select,.ui-bar-a textarea,.ui-bar-a button{font-family:Helvetica,Arial,sans-serif}.ui-bar-a .ui-link-inherit{color:#fff}.ui-bar-a a.ui-link{color:#7cc4e7;font-weight:bold}.ui-bar-a a.ui-link:visited{color:#2489ce}.ui-bar-a a.ui-link:hover{color:#2489ce}.ui-bar-a a.ui-link:active{color:#2489ce}.ui-body-a,.ui-overlay-a{border:1px solid #444;background:#222;color:#fff;text-shadow:0 1px 1px #111;font-weight:normal;background-image:-webkit-gradient(linear,left top,left bottom,from( #444 ),to( #222 ));background-image:-webkit-linear-gradient( #444,#222 );background-image:-moz-linear-gradient( #444,#222 );background-image:-ms-linear-gradient( #444,#222 );background-image:-o-linear-gradient( #444,#222 );background-image:linear-gradient( #444,#222 )}.ui-overlay-a{background-image:none;border-width:0}.ui-body-a,.ui-body-a input,.ui-body-a select,.ui-body-a textarea,.ui-body-a button{font-family:Helvetica,Arial,sans-serif}.ui-body-a .ui-link-inherit{color:#fff}.ui-body-a .ui-link{color:#2489ce;font-weight:bold}.ui-body-a .ui-link:visited{color:#2489ce}.ui-body-a .ui-link:hover{color:#2489ce}.ui-body-a .ui-link:active{color:#2489ce}.ui-btn-up-a{border:1px solid #111;background:#333;font-weight:bold;color:#fff;text-shadow:0 1px 1px #111;background-image:-webkit-gradient(linear,left top,left bottom,from( #444 ),to( #2d2d2d ));background-image:-webkit-linear-gradient( #444,#2d2d2d );background-image:-moz-linear-gradient( #444,#2d2d2d );background-image:-ms-linear-gradient( #444,#2d2d2d );background-image:-o-linear-gradient( #444,#2d2d2d );background-image:linear-gradient( #444,#2d2d2d )}.ui-btn-up-a:visited,.ui-btn-up-a a.ui-link-inherit{color:#fff}.ui-btn-hover-a{border:1px solid #000;background:#444;font-weight:bold;color:#fff;text-shadow:0 1px 1px #111;background-image:-webkit-gradient(linear,left top,left bottom,from( #555 ),to( #383838 ));background-image:-webkit-linear-gradient( #555,#383838 );background-image:-moz-linear-gradient( #555,#383838 );background-image:-ms-linear-gradient( #555,#383838 );background-image:-o-linear-gradient( #555,#383838 );background-image:linear-gradient( #555,#383838 )}.ui-btn-hover-a:visited,.ui-btn-hover-a:hover,.ui-btn-hover-a a.ui-link-inherit{color:#fff}.ui-btn-down-a{border:1px solid #000;background:#222;font-weight:bold;color:#fff;text-shadow:0 1px 1px #111;background-image:-webkit-gradient(linear,left top,left bottom,from( #202020 ),to( #2c2c2c ));background-image:-webkit-linear-gradient( #202020,#2c2c2c );background-image:-moz-linear-gradient( #202020,#2c2c2c );background-image:-ms-linear-gradient( #202020,#2c2c2c );background-image:-o-linear-gradient( #202020,#2c2c2c );background-image:linear-gradient( #202020,#2c2c2c )}.ui-btn-down-a:visited,.ui-btn-down-a:hover,.ui-btn-down-a a.ui-link-inherit{color:#fff}.ui-btn-up-a,.ui-btn-hover-a,.ui-btn-down-a{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-b{border:1px solid #456f9a;background:#5e87b0;color:#fff;font-weight:bold;text-shadow:0 1px 1px #3e6790;background-image:-webkit-gradient(linear,left top,left bottom,from( #6facd5 ),to( #497bae ));background-image:-webkit-linear-gradient( #6facd5,#497bae );background-image:-moz-linear-gradient( #6facd5,#497bae );background-image:-ms-linear-gradient( #6facd5,#497bae );background-image:-o-linear-gradient( #6facd5,#497bae );background-image:linear-gradient( #6facd5,#497bae )}.ui-bar-b,.ui-bar-b input,.ui-bar-b select,.ui-bar-b textarea,.ui-bar-b button{font-family:Helvetica,Arial,sans-serif}.ui-bar-b .ui-link-inherit{color:#fff}.ui-bar-b a.ui-link{color:#ddf0f8;font-weight:bold}.ui-bar-b a.ui-link:visited{color:#ddf0f8}.ui-bar-b a.ui-link:hover{color:#ddf0f8}.ui-bar-b a.ui-link:active{color:#ddf0f8}.ui-body-b,.ui-overlay-b{border:1px solid #999;background:#f3f3f3;color:#222;text-shadow:0 1px 0 #fff;font-weight:normal;background-image:-webkit-gradient(linear,left top,left bottom,from( #ddd ),to( #ccc ));background-image:-webkit-linear-gradient( #ddd,#ccc );background-image:-moz-linear-gradient( #ddd,#ccc );background-image:-ms-linear-gradient( #ddd,#ccc );background-image:-o-linear-gradient( #ddd,#ccc );background-image:linear-gradient( #ddd,#ccc )}.ui-overlay-b{background-image:none;border-width:0}.ui-body-b,.ui-body-b input,.ui-body-b select,.ui-body-b textarea,.ui-body-b button{font-family:Helvetica,Arial,sans-serif}.ui-body-b .ui-link-inherit{color:#333}.ui-body-b .ui-link{color:#2489ce;font-weight:bold}.ui-body-b .ui-link:visited{color:#2489ce}.ui-body-b .ui-link:hover{color:#2489ce}.ui-body-b .ui-link:active{color:#2489ce}.ui-btn-up-b{border:1px solid #044062;background:#396b9e;font-weight:bold;color:#fff;text-shadow:0 1px 1px #194b7e;background-image:-webkit-gradient(linear,left top,left bottom,from( #5f9cc5 ),to( #396b9e ));background-image:-webkit-linear-gradient( #5f9cc5,#396b9e );background-image:-moz-linear-gradient( #5f9cc5,#396b9e );background-image:-ms-linear-gradient( #5f9cc5,#396b9e );background-image:-o-linear-gradient( #5f9cc5,#396b9e );background-image:linear-gradient( #5f9cc5,#396b9e )}.ui-btn-up-b:visited,.ui-btn-up-b a.ui-link-inherit{color:#fff}.ui-btn-hover-b{border:1px solid #00415e;background:#4b88b6;font-weight:bold;color:#fff;text-shadow:0 1px 1px #194b7e;background-image:-webkit-gradient(linear,left top,left bottom,from( #6facd5 ),to( #4272a4 ));background-image:-webkit-linear-gradient( #6facd5,#4272a4 );background-image:-moz-linear-gradient( #6facd5,#4272a4 );background-image:-ms-linear-gradient( #6facd5,#4272a4 );background-image:-o-linear-gradient( #6facd5,#4272a4 );background-image:linear-gradient( #6facd5,#4272a4 )}.ui-btn-hover-b:visited,.ui-btn-hover-b:hover,.ui-btn-hover-b a.ui-link-inherit{color:#fff}.ui-btn-down-b{border:1px solid #225377;background:#4e89c5;font-weight:bold;color:#fff;text-shadow:0 1px 1px #194b7e;background-image:-webkit-gradient(linear,left top,left bottom,from( #295b8e ),to( #3e79b5 ));background-image:-webkit-linear-gradient( #295b8e,#3e79b5 );background-image:-moz-linear-gradient( #295b8e,#3e79b5 );background-image:-ms-linear-gradient( #295b8e,#3e79b5 );background-image:-o-linear-gradient( #295b8e,#3e79b5 );background-image:linear-gradient( #295b8e,#3e79b5 )}.ui-btn-down-b:visited,.ui-btn-down-b:hover,.ui-btn-down-b a.ui-link-inherit{color:#fff}.ui-btn-up-b,.ui-btn-hover-b,.ui-btn-down-b{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-c{border:1px solid #b3b3b3;background:#eee;color:#3e3e3e;font-weight:bold;text-shadow:0 1px 1px #fff;background-image:-webkit-gradient(linear,left top,left bottom,from( #f0f0f0 ),to( #ddd ));background-image:-webkit-linear-gradient( #f0f0f0,#ddd );background-image:-moz-linear-gradient( #f0f0f0,#ddd );background-image:-ms-linear-gradient( #f0f0f0,#ddd );background-image:-o-linear-gradient( #f0f0f0,#ddd );background-image:linear-gradient( #f0f0f0,#ddd )}.ui-bar-c .ui-link-inherit{color:#3e3e3e}.ui-bar-c a.ui-link{color:#7cc4e7;font-weight:bold}.ui-bar-c a.ui-link:visited{color:#2489ce}.ui-bar-c a.ui-link:hover{color:#2489ce}.ui-bar-c a.ui-link:active{color:#2489ce}.ui-bar-c,.ui-bar-c input,.ui-bar-c select,.ui-bar-c textarea,.ui-bar-c button{font-family:Helvetica,Arial,sans-serif}.ui-body-c,.ui-overlay-c{border:1px solid #aaa;color:#333;text-shadow:0 1px 0 #fff;background:#f9f9f9;background-image:-webkit-gradient(linear,left top,left bottom,from( #f9f9f9 ),to( #eee ));background-image:-webkit-linear-gradient( #f9f9f9,#eee );background-image:-moz-linear-gradient( #f9f9f9,#eee );background-image:-ms-linear-gradient( #f9f9f9,#eee );background-image:-o-linear-gradient( #f9f9f9,#eee );background-image:linear-gradient( #f9f9f9,#eee )}.ui-overlay-c{background-image:none;border-width:0}.ui-body-c,.ui-body-c input,.ui-body-c select,.ui-body-c textarea,.ui-body-c button{font-family:Helvetica,Arial,sans-serif}.ui-body-c .ui-link-inherit{color:#333}.ui-body-c .ui-link{color:#2489ce;font-weight:bold}.ui-body-c .ui-link:visited{color:#2489ce}.ui-body-c .ui-link:hover{color:#2489ce}.ui-body-c .ui-link:active{color:#2489ce}.ui-btn-up-c{border:1px solid #ccc;background:#eee;font-weight:bold;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from( #fff ),to( #f1f1f1 ));background-image:-webkit-linear-gradient( #fff,#f1f1f1 );background-image:-moz-linear-gradient( #fff,#f1f1f1 );background-image:-ms-linear-gradient( #fff,#f1f1f1 );background-image:-o-linear-gradient( #fff,#f1f1f1 );background-image:linear-gradient( #fff,#f1f1f1 )}.ui-btn-up-c:visited,.ui-btn-up-c a.ui-link-inherit{color:#2f3e46}.ui-btn-hover-c{border:1px solid #bbb;background:#dfdfdf;font-weight:bold;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from( #f6f6f6 ),to( #e0e0e0 ));background-image:-webkit-linear-gradient( #f6f6f6,#e0e0e0 );background-image:-moz-linear-gradient( #f6f6f6,#e0e0e0 );background-image:-ms-linear-gradient( #f6f6f6,#e0e0e0 );background-image:-o-linear-gradient( #f6f6f6,#e0e0e0 );background-image:linear-gradient( #f6f6f6,#e0e0e0 )}.ui-btn-hover-c:visited,.ui-btn-hover-c:hover,.ui-btn-hover-c a.ui-link-inherit{color:#2f3e46}.ui-btn-down-c{border:1px solid #bbb;background:#d6d6d6;font-weight:bold;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from( #d0d0d0 ),to( #dfdfdf ));background-image:-webkit-linear-gradient( #d0d0d0,#dfdfdf );background-image:-moz-linear-gradient( #d0d0d0,#dfdfdf );background-image:-ms-linear-gradient( #d0d0d0,#dfdfdf );background-image:-o-linear-gradient( #d0d0d0,#dfdfdf );background-image:linear-gradient( #d0d0d0,#dfdfdf )}.ui-btn-down-c:visited,.ui-btn-down-c:hover,.ui-btn-down-c a.ui-link-inherit{color:#2f3e46}.ui-btn-up-c,.ui-btn-hover-c,.ui-btn-down-c{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-d{border:1px solid #bbb;background:#bbb;color:#333;font-weight:bold;text-shadow:0 1px 0 #eee;background-image:-webkit-gradient(linear,left top,left bottom,from( #ddd ),to( #bbb ));background-image:-webkit-linear-gradient( #ddd,#bbb );background-image:-moz-linear-gradient( #ddd,#bbb );background-image:-ms-linear-gradient( #ddd,#bbb );background-image:-o-linear-gradient( #ddd,#bbb );background-image:linear-gradient( #ddd,#bbb )}.ui-bar-d,.ui-bar-d input,.ui-bar-d select,.ui-bar-d textarea,.ui-bar-d button{font-family:Helvetica,Arial,sans-serif}.ui-bar-d .ui-link-inherit{color:#333}.ui-bar-d a.ui-link{color:#2489ce;font-weight:bold}.ui-bar-d a.ui-link:visited{color:#2489ce}.ui-bar-d a.ui-link:hover{color:#2489ce}.ui-bar-d a.ui-link:active{color:#2489ce}.ui-body-d,.ui-overlay-d{border:1px solid #bbb;color:#333;text-shadow:0 1px 0 #fff;background:#fff;background-image:-webkit-gradient(linear,left top,left bottom,from( #fff ),to( #fff ));background-image:-webkit-linear-gradient( #fff,#fff );background-image:-moz-linear-gradient( #fff,#fff );background-image:-ms-linear-gradient( #fff,#fff );background-image:-o-linear-gradient( #fff,#fff );background-image:linear-gradient( #fff,#fff )}.ui-overlay-d{background-image:none;border-width:0}.ui-body-d,.ui-body-d input,.ui-body-d select,.ui-body-d textarea,.ui-body-d button{font-family:Helvetica,Arial,sans-serif}.ui-body-d .ui-link-inherit{color:#333}.ui-body-d .ui-link{color:#2489ce;font-weight:bold}.ui-body-d .ui-link:visited{color:#2489ce}.ui-body-d .ui-link:hover{color:#2489ce}.ui-body-d .ui-link:active{color:#2489ce}.ui-btn-up-d{border:1px solid #bbb;background:#fff;font-weight:bold;color:#333;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from( #fafafa ),to( #f6f6f6 ));background-image:-webkit-linear-gradient( #fafafa,#f6f6f6 );background-image:-moz-linear-gradient( #fafafa,#f6f6f6 );background-image:-ms-linear-gradient( #fafafa,#f6f6f6 );background-image:-o-linear-gradient( #fafafa,#f6f6f6 );background-image:linear-gradient( #fafafa,#f6f6f6 )}.ui-btn-up-d:visited,.ui-btn-up-d a.ui-link-inherit{color:#333}.ui-btn-hover-d{border:1px solid #aaa;background:#eee;font-weight:bold;color:#333;cursor:pointer;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from( #eee ),to( #fff ));background-image:-webkit-linear-gradient( #eee,#fff );background-image:-moz-linear-gradient( #eee,#fff );background-image:-ms-linear-gradient( #eee,#fff );background-image:-o-linear-gradient( #eee,#fff );background-image:linear-gradient( #eee,#fff )}.ui-btn-hover-d:visited,.ui-btn-hover-d:hover,.ui-btn-hover-d a.ui-link-inherit{color:#333}.ui-btn-down-d{border:1px solid #aaa;background:#eee;font-weight:bold;color:#333;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from( #e5e5e5 ),to( #f2f2f2 ));background-image:-webkit-linear-gradient( #e5e5e5,#f2f2f2 );background-image:-moz-linear-gradient( #e5e5e5,#f2f2f2 );background-image:-ms-linear-gradient( #e5e5e5,#f2f2f2 );background-image:-o-linear-gradient( #e5e5e5,#f2f2f2 );background-image:linear-gradient( #e5e5e5,#f2f2f2 )}.ui-btn-down-d:visited,.ui-btn-down-d:hover,.ui-btn-down-d a.ui-link-inherit{color:#333}.ui-btn-up-d,.ui-btn-hover-d,.ui-btn-down-d{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-e{border:1px solid #f7c942;background:#fadb4e;color:#333;font-weight:bold;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from( #fceda7 ),to( #fbef7e ));background-image:-webkit-linear-gradient( #fceda7,#fbef7e );background-image:-moz-linear-gradient( #fceda7,#fbef7e );background-image:-ms-linear-gradient( #fceda7,#fbef7e );background-image:-o-linear-gradient( #fceda7,#fbef7e );background-image:linear-gradient( #fceda7,#fbef7e )}.ui-bar-e,.ui-bar-e input,.ui-bar-e select,.ui-bar-e textarea,.ui-bar-e button{font-family:Helvetica,Arial,sans-serif}.ui-bar-e .ui-link-inherit{color:#333}.ui-bar-e a.ui-link{color:#2489ce;font-weight:bold}.ui-bar-e a.ui-link:visited{color:#2489ce}.ui-bar-e a.ui-link:hover{color:#2489ce}.ui-bar-e a.ui-link:active{color:#2489ce}.ui-body-e,.ui-overlay-e{border:1px solid #f7c942;color:#222;text-shadow:0 1px 0 #fff;background:#fff9df;background-image:-webkit-gradient(linear,left top,left bottom,from( #fffadf ),to( #fff3a5 ));background-image:-webkit-linear-gradient( #fffadf,#fff3a5 );background-image:-moz-linear-gradient( #fffadf,#fff3a5 );background-image:-ms-linear-gradient( #fffadf,#fff3a5 );background-image:-o-linear-gradient( #fffadf,#fff3a5 );background-image:linear-gradient( #fffadf,#fff3a5 )}.ui-overlay-e{background-image:none;border-width:0}.ui-body-e,.ui-body-e input,.ui-body-e select,.ui-body-e textarea,.ui-body-e button{font-family:Helvetica,Arial,sans-serif}.ui-body-e .ui-link-inherit{color:#222}.ui-body-e .ui-link{color:#2489ce;font-weight:bold}.ui-body-e .ui-link:visited{color:#2489ce}.ui-body-e .ui-link:hover{color:#2489ce}.ui-body-e .ui-link:active{color:#2489ce}.ui-btn-up-e{border:1px solid #f4c63f;background:#fadb4e;font-weight:bold;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from( #ffefaa ),to( #ffe155 ));background-image:-webkit-linear-gradient( #ffefaa,#ffe155 );background-image:-moz-linear-gradient( #ffefaa,#ffe155 );background-image:-ms-linear-gradient( #ffefaa,#ffe155 );background-image:-o-linear-gradient( #ffefaa,#ffe155 );background-image:linear-gradient( #ffefaa,#ffe155 )}.ui-btn-up-e:visited,.ui-btn-up-e a.ui-link-inherit{color:#222}.ui-btn-hover-e{border:1px solid #f2c43d;background:#fbe26f;font-weight:bold;color:#111;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from( #fff5ba ),to( #fbdd52 ));background-image:-webkit-linear-gradient( #fff5ba,#fbdd52 );background-image:-moz-linear-gradient( #fff5ba,#fbdd52 );background-image:-ms-linear-gradient( #fff5ba,#fbdd52 );background-image:-o-linear-gradient( #fff5ba,#fbdd52 );background-image:linear-gradient( #fff5ba,#fbdd52 )}.ui-btn-hover-e:visited,.ui-btn-hover-e:hover,.ui-btn-hover-e a.ui-link-inherit{color:#333}.ui-btn-down-e{border:1px solid #f2c43d;background:#fceda7;font-weight:bold;color:#111;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from( #f8d94c ),to( #fadb4e ));background-image:-webkit-linear-gradient( #f8d94c,#fadb4e );background-image:-moz-linear-gradient( #f8d94c,#fadb4e );background-image:-ms-linear-gradient( #f8d94c,#fadb4e );background-image:-o-linear-gradient( #f8d94c,#fadb4e );background-image:linear-gradient( #f8d94c,#fadb4e )}.ui-btn-down-e:visited,.ui-btn-down-e:hover,.ui-btn-down-e a.ui-link-inherit{color:#333}.ui-btn-up-e,.ui-btn-hover-e,.ui-btn-down-e{font-family:Helvetica,Arial,sans-serif;text-decoration:none}a.ui-link-inherit{text-decoration:none!important}.ui-btn-active{border:1px solid #2373a5;background:#5393c5;font-weight:bold;color:#fff;cursor:pointer;text-shadow:0 1px 1px #3373a5;text-decoration:none;background-image:-webkit-gradient(linear,left top,left bottom,from( #5393c5 ),to( #6facd5 ));background-image:-webkit-linear-gradient( #5393c5,#6facd5 );background-image:-moz-linear-gradient( #5393c5,#6facd5 );background-image:-ms-linear-gradient( #5393c5,#6facd5 );background-image:-o-linear-gradient( #5393c5,#6facd5 );background-image:linear-gradient( #5393c5,#6facd5 );font-family:Helvetica,Arial,sans-serif}.ui-btn-active:visited,.ui-btn-active:hover,.ui-btn-active a.ui-link-inherit{color:#fff}.ui-btn-inner{border-top:1px solid #fff;border-color:rgba(255,255,255,.3)}.ui-corner-tl{-moz-border-radius-topleft:.6em;-webkit-border-top-left-radius:.6em;border-top-left-radius:.6em}.ui-corner-tr{-moz-border-radius-topright:.6em;-webkit-border-top-right-radius:.6em;border-top-right-radius:.6em}.ui-corner-bl{-moz-border-radius-bottomleft:.6em;-webkit-border-bottom-left-radius:.6em;border-bottom-left-radius:.6em}.ui-corner-br{-moz-border-radius-bottomright:.6em;-webkit-border-bottom-right-radius:.6em;border-bottom-right-radius:.6em}.ui-corner-top{-moz-border-radius-topleft:.6em;-webkit-border-top-left-radius:.6em;border-top-left-radius:.6em;-moz-border-radius-topright:.6em;-webkit-border-top-right-radius:.6em;border-top-right-radius:.6em}.ui-corner-bottom{-moz-border-radius-bottomleft:.6em;-webkit-border-bottom-left-radius:.6em;border-bottom-left-radius:.6em;-moz-border-radius-bottomright:.6em;-webkit-border-bottom-right-radius:.6em;border-bottom-right-radius:.6em}.ui-corner-right{-moz-border-radius-topright:.6em;-webkit-border-top-right-radius:.6em;border-top-right-radius:.6em;-moz-border-radius-bottomright:.6em;-webkit-border-bottom-right-radius:.6em;border-bottom-right-radius:.6em}.ui-corner-left{-moz-border-radius-topleft:.6em;-webkit-border-top-left-radius:.6em;border-top-left-radius:.6em;-moz-border-radius-bottomleft:.6em;-webkit-border-bottom-left-radius:.6em;border-bottom-left-radius:.6em}.ui-corner-all{-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em}.ui-corner-none{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.ui-br{border-bottom:rgb(130,130,130);border-bottom:rgba(130,130,130,.3);border-bottom-width:1px;border-bottom-style:solid}.ui-disabled{filter:Alpha(Opacity=30);opacity:.3;zoom:1}.ui-disabled,.ui-disabled a{cursor:default!important;pointer-events:none}.ui-icon,.ui-icon-searchfield:after{background:#666;background:rgba(0,0,0,.4);background-image:url(images/icons-18-white.png);background-repeat:no-repeat;-moz-border-radius:9px;-webkit-border-radius:9px;border-radius:9px}.ui-icon-alt{background:#fff;background:rgba(255,255,255,.3);background-image:url(images/icons-18-black.png);background-repeat:no-repeat}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min--moz-device-pixel-ratio:1.5),only screen and (min-resolution:240dpi){.ui-icon-plus,.ui-icon-minus,.ui-icon-delete,.ui-icon-arrow-r,.ui-icon-arrow-l,.ui-icon-arrow-u,.ui-icon-arrow-d,.ui-icon-check,.ui-icon-gear,.ui-icon-refresh,.ui-icon-forward,.ui-icon-back,.ui-icon-grid,.ui-icon-star,.ui-icon-alert,.ui-icon-info,.ui-icon-home,.ui-icon-search,.ui-icon-searchfield:after,.ui-icon-checkbox-off,.ui-icon-checkbox-on,.ui-icon-radio-off,.ui-icon-radio-on{background-image:url(images/icons-36-white.png);-moz-background-size:776px 18px;-o-background-size:776px 18px;-webkit-background-size:776px 18px;background-size:776px 18px}.ui-icon-alt{background-image:url(images/icons-36-black.png)}}.ui-icon-plus{background-position:-0 50%}.ui-icon-minus{background-position:-36px 50%}.ui-icon-delete{background-position:-72px 50%}.ui-icon-arrow-r{background-position:-108px 50%}.ui-icon-arrow-l{background-position:-144px 50%}.ui-icon-arrow-u{background-position:-180px 50%}.ui-icon-arrow-d{background-position:-216px 50%}.ui-icon-check{background-position:-252px 50%}.ui-icon-gear{background-position:-288px 50%}.ui-icon-refresh{background-position:-324px 50%}.ui-icon-forward{background-position:-360px 50%}.ui-icon-back{background-position:-396px 50%}.ui-icon-grid{background-position:-432px 50%}.ui-icon-star{background-position:-468px 50%}.ui-icon-alert{background-position:-504px 50%}.ui-icon-info{background-position:-540px 50%}.ui-icon-home{background-position:-576px 50%}.ui-icon-search,.ui-icon-searchfield:after{background-position:-612px 50%}.ui-icon-checkbox-off{background-position:-684px 50%}.ui-icon-checkbox-on{background-position:-648px 50%}.ui-icon-radio-off{background-position:-756px 50%}.ui-icon-radio-on{background-position:-720px 50%}.ui-checkbox .ui-icon,.ui-selectmenu-list .ui-icon{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.ui-icon-checkbox-off,.ui-icon-radio-off{background-color:transparent}.ui-checkbox-on .ui-icon,.ui-radio-on .ui-icon{background-color:#4596ce}.ui-icon-loading{background:url(images/ajax-loader.gif);background-size:46px 46px}.ui-btn-corner-tl{-moz-border-radius-topleft:1em;-webkit-border-top-left-radius:1em;border-top-left-radius:1em}.ui-btn-corner-tr{-moz-border-radius-topright:1em;-webkit-border-top-right-radius:1em;border-top-right-radius:1em}.ui-btn-corner-bl{-moz-border-radius-bottomleft:1em;-webkit-border-bottom-left-radius:1em;border-bottom-left-radius:1em}.ui-btn-corner-br{-moz-border-radius-bottomright:1em;-webkit-border-bottom-right-radius:1em;border-bottom-right-radius:1em}.ui-btn-corner-top{-moz-border-radius-topleft:1em;-webkit-border-top-left-radius:1em;border-top-left-radius:1em;-moz-border-radius-topright:1em;-webkit-border-top-right-radius:1em;border-top-right-radius:1em}.ui-btn-corner-bottom{-moz-border-radius-bottomleft:1em;-webkit-border-bottom-left-radius:1em;border-bottom-left-radius:1em;-moz-border-radius-bottomright:1em;-webkit-border-bottom-right-radius:1em;border-bottom-right-radius:1em}.ui-btn-corner-right{-moz-border-radius-topright:1em;-webkit-border-top-right-radius:1em;border-top-right-radius:1em;-moz-border-radius-bottomright:1em;-webkit-border-bottom-right-radius:1em;border-bottom-right-radius:1em}.ui-btn-corner-left{-moz-border-radius-topleft:1em;-webkit-border-top-left-radius:1em;border-top-left-radius:1em;-moz-border-radius-bottomleft:1em;-webkit-border-bottom-left-radius:1em;border-bottom-left-radius:1em}.ui-btn-corner-all{-moz-border-radius:1em;-webkit-border-radius:1em;border-radius:1em}.ui-corner-tl,.ui-corner-tr,.ui-corner-bl,.ui-corner-br,.ui-corner-top,.ui-corner-bottom,.ui-corner-right,.ui-corner-left,.ui-corner-all,.ui-btn-corner-tl,.ui-btn-corner-tr,.ui-btn-corner-bl,.ui-btn-corner-br,.ui-btn-corner-top,.ui-btn-corner-bottom,.ui-btn-corner-right,.ui-btn-corner-left,.ui-btn-corner-all{-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.ui-overlay{background:#666;filter:Alpha(Opacity=50);opacity:.5;position:absolute;width:100%;height:100%}.ui-overlay-shadow{-moz-box-shadow:0 0 12px rgba(0,0,0,.6);-webkit-box-shadow:0 0 12px rgba(0,0,0,.6);box-shadow:0 0 12px rgba(0,0,0,.6)}.ui-shadow{-moz-box-shadow:0 1px 4px rgba(0,0,0,.3);-webkit-box-shadow:0 1px 4px rgba(0,0,0,.3);box-shadow:0 1px 4px rgba(0,0,0,.3)}.ui-bar-a .ui-shadow,.ui-bar-b .ui-shadow,.ui-bar-c .ui-shadow{-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.ui-shadow-inset{-moz-box-shadow:inset 0 1px 4px rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 4px rgba(0,0,0,.2);box-shadow:inset 0 1px 4px rgba(0,0,0,.2)}.ui-icon-shadow{-moz-box-shadow:0 1px 0 rgba(255,255,255,.4);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.4);box-shadow:0 1px 0 rgba(255,255,255,.4)}.ui-btn:focus,.ui-link-inherit:focus{outline:0}.ui-btn.ui-focus{z-index:1}.ui-focus,.ui-btn:focus{-moz-box-shadow:inset 0 0 3px #387bbe,0px 0 9px #387bbe;-webkit-box-shadow:inset 0 0 3px #387bbe,0px 0 9px #387bbe;box-shadow:inset 0 0 3px #387bbe,0px 0 9px #387bbe}.ui-input-text.ui-focus,.ui-input-search.ui-focus{-moz-box-shadow:0 0 12px #387bbe;-webkit-box-shadow:0 0 12px #387bbe;box-shadow:0 0 12px #387bbe}.ui-mobile-nosupport-boxshadow *{-moz-box-shadow:none!important;-webkit-box-shadow:none!important;box-shadow:none!important}.ui-mobile-nosupport-boxshadow .ui-focus,.ui-mobile-nosupport-boxshadow .ui-btn:focus,.ui-mobile-nosupport-boxshadow .ui-link-inherit:focus{outline-width:1px;outline-style:auto}.ui-mobile,.ui-mobile body{height:99.9%}.ui-mobile fieldset,.ui-page{padding:0;margin:0}.ui-mobile a img,.ui-mobile fieldset{border-width:0}.ui-mobile-viewport{margin:0;overflow-x:visible;-webkit-text-size-adjust:100%;-ms-text-size-adjust:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}body.ui-mobile-viewport,div.ui-mobile-viewport{overflow-x:hidden}.ui-mobile [data-role=page],.ui-mobile [data-role=dialog],.ui-page{top:0;left:0;width:100%;min-height:100%;position:absolute;display:none;border:0}.ui-mobile .ui-page-active{display:block;overflow:visible}.ui-page{outline:none}@media screen and (orientation:portrait){.ui-mobile,.ui-mobile .ui-page{min-height:420px}}@media screen and (orientation:landscape){.ui-mobile,.ui-mobile .ui-page{min-height:300px}}.ui-loading .ui-loader{display:block}.ui-loader{display:none;z-index:9999999;position:fixed;top:50%;left:50%;border:0}.ui-loader-default{background:none;filter:Alpha(Opacity=18);opacity:.18;width:46px;height:46px;margin-left:-23px;margin-top:-23px}.ui-loader-verbose{width:200px;filter:Alpha(Opacity=88);opacity:.88;box-shadow:0 1px 1px -1px #fff;height:auto;margin-left:-110px;margin-top:-43px;padding:10px}.ui-loader-default h1{font-size:0;width:0;height:0;overflow:hidden}.ui-loader-verbose h1{font-size:16px;margin:0;text-align:center}.ui-loader .ui-icon{background-color:#000;display:block;margin:0;width:44px;height:44px;padding:1px;-webkit-border-radius:36px;-moz-border-radius:36px;border-radius:36px}.ui-loader-verbose .ui-icon{margin:0 auto 10px;filter:Alpha(Opacity=75);opacity:.75}.ui-loader-textonly{padding:15px;margin-left:-115px}.ui-loader-textonly .ui-icon{display:none}.ui-loader-fakefix{position:absolute}.ui-mobile-rendering > *{visibility:hidden}.ui-bar,.ui-body{position:relative;padding:.4em 15px;overflow:hidden;display:block;clear:both}.ui-bar{font-size:16px;margin:0}.ui-bar h1,.ui-bar h2,.ui-bar h3,.ui-bar h4,.ui-bar h5,.ui-bar h6{margin:0;padding:0;font-size:16px;display:inline-block}.ui-header,.ui-footer{position:relative;border-left-width:0;border-right-width:0;zoom:1}.ui-header .ui-btn-left,.ui-header .ui-btn-right,.ui-footer .ui-btn-left,.ui-footer .ui-btn-right{position:absolute;top:3px}.ui-header .ui-btn-left,.ui-footer .ui-btn-left{left:5px}.ui-header .ui-btn-right,.ui-footer .ui-btn-right{right:5px}.ui-footer .ui-btn-icon-notext,.ui-header .ui-btn-icon-notext{top:6px}.ui-header .ui-title,.ui-footer .ui-title{min-height:1.1em;text-align:center;font-size:16px;display:block;margin:.6em 30% .8em;padding:0;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;outline:0!important}.ui-footer .ui-title{margin:.6em 15px .8em}.ui-content{border-width:0;overflow:visible;overflow-x:hidden;padding:15px}.ui-icon{width:18px;height:18px}.ui-nojs{position:absolute;left:-9999px}.ui-hide-label label.ui-input-text,.ui-hide-label label.ui-select,.ui-hide-label label.ui-slider,.ui-hide-label label.ui-submit,.ui-hide-label .ui-controlgroup-label,.ui-hidden-accessible{position:absolute!important;left:-9999px;clip:rect(1px);clip:rect(1px,1px,1px,1px)}.ui-mobile-viewport-transitioning,.ui-mobile-viewport-transitioning .ui-page{width:100%;height:100%;overflow:hidden;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.ui-page-pre-in{opacity:0}.in{-webkit-animation-timing-function:ease-out;-webkit-animation-duration:350ms;-moz-animation-timing-function:ease-out;-moz-animation-duration:350ms}.out{-webkit-animation-timing-function:ease-in;-webkit-animation-duration:225ms;-moz-animation-timing-function:ease-in;-moz-animation-duration:225ms}@-webkit-keyframes fadein{from{opacity:0}to{opacity:1}}@-moz-keyframes fadein{from{opacity:0}to{opacity:1}}@-webkit-keyframes fadeout{from{opacity:1}to{opacity:0}}@-moz-keyframes fadeout{from{opacity:1}to{opacity:0}}.fade.out{opacity:0;-webkit-animation-duration:125ms;-webkit-animation-name:fadeout;-moz-animation-duration:125ms;-moz-animation-name:fadeout}.fade.in{opacity:1;-webkit-animation-duration:225ms;-webkit-animation-name:fadein;-moz-animation-duration:225ms;-moz-animation-name:fadein}.pop{-webkit-transform-origin:50% 50%;-moz-transform-origin:50% 50%}.pop.in{-webkit-transform:scale(1);-moz-transform:scale(1);opacity:1;-webkit-animation-name:popin;-moz-animation-name:popin;-webkit-animation-duration:350ms;-moz-animation-duration:350ms}.pop.out{-webkit-animation-name:fadeout;-moz-animation-name:fadeout;opacity:0;-webkit-animation-duration:100ms;-moz-animation-duration:100ms}.pop.in.reverse{-webkit-animation-name:fadein;-moz-animation-name:fadein}.pop.out.reverse{-webkit-transform:scale(.8);-moz-transform:scale(.8);-webkit-animation-name:popout;-moz-animation-name:popout}@-webkit-keyframes popin{from{-webkit-transform:scale(.8);opacity:0}to{-webkit-transform:scale(1);opacity:1}}@-moz-keyframes popin{from{-moz-transform:scale(.8);opacity:0}to{-moz-transform:scale(1);opacity:1}}@-webkit-keyframes popout{from{-webkit-transform:scale(1);opacity:1}to{-webkit-transform:scale(.8);opacity:0}}@-moz-keyframes popout{from{-moz-transform:scale(1);opacity:1}to{-moz-transform:scale(.8);opacity:0}}@-webkit-keyframes slideinfromright{from{-webkit-transform:translateX(100%)}to{-webkit-transform:translateX(0)}}@-moz-keyframes slideinfromright{from{-moz-transform:translateX(100%)}to{-moz-transform:translateX(0)}}@-webkit-keyframes slideinfromleft{from{-webkit-transform:translateX(-100%)}to{-webkit-transform:translateX(0)}}@-moz-keyframes slideinfromleft{from{-moz-transform:translateX(-100%)}to{-moz-transform:translateX(0)}}@-webkit-keyframes slideouttoleft{from{-webkit-transform:translateX(0)}to{-webkit-transform:translateX(-100%)}}@-moz-keyframes slideouttoleft{from{-moz-transform:translateX(0)}to{-moz-transform:translateX(-100%)}}@-webkit-keyframes slideouttoright{from{-webkit-transform:translateX(0)}to{-webkit-transform:translateX(100%)}}@-moz-keyframes slideouttoright{from{-moz-transform:translateX(0)}to{-moz-transform:translateX(100%)}}.slide.out,.slide.in{-webkit-animation-timing-function:ease-out;-webkit-animation-duration:350ms;-moz-animation-timing-function:ease-out;-moz-animation-duration:350ms}.slide.out{-webkit-transform:translateX(-100%);-webkit-animation-name:slideouttoleft;-moz-transform:translateX(-100%);-moz-animation-name:slideouttoleft}.slide.in{-webkit-transform:translateX(0);-webkit-animation-name:slideinfromright;-moz-transform:translateX(0);-moz-animation-name:slideinfromright}.slide.out.reverse{-webkit-transform:translateX(100%);-webkit-animation-name:slideouttoright;-moz-transform:translateX(100%);-moz-animation-name:slideouttoright}.slide.in.reverse{-webkit-transform:translateX(0);-webkit-animation-name:slideinfromleft;-moz-transform:translateX(0);-moz-animation-name:slideinfromleft}.slidefade.out{-webkit-transform:translateX(-100%);-webkit-animation-name:slideouttoleft;-moz-transform:translateX(-100%);-moz-animation-name:slideouttoleft;-webkit-animation-duration:225ms;-moz-animation-duration:225ms}.slidefade.in{-webkit-transform:translateX(0);-webkit-animation-name:fadein;-moz-transform:translateX(0);-moz-animation-name:fadein;-webkit-animation-duration:200ms;-moz-animation-duration:200ms}.slidefade.out.reverse{-webkit-transform:translateX(100%);-webkit-animation-name:slideouttoright;-moz-transform:translateX(100%);-moz-animation-name:slideouttoright;-webkit-animation-duration:200ms;-moz-animation-duration:200ms}.slidefade.in.reverse{-webkit-transform:translateX(0);-webkit-animation-name:fadein;-moz-transform:translateX(0);-moz-animation-name:fadein;-webkit-animation-duration:200ms;-moz-animation-duration:200ms}.slidedown.out{-webkit-animation-name:fadeout;-moz-animation-name:fadeout;-webkit-animation-duration:100ms;-moz-animation-duration:100ms}.slidedown.in{-webkit-transform:translateY(0);-webkit-animation-name:slideinfromtop;-moz-transform:translateY(0);-moz-animation-name:slideinfromtop;-webkit-animation-duration:250ms;-moz-animation-duration:250ms}.slidedown.in.reverse{-webkit-animation-name:fadein;-moz-animation-name:fadein;-webkit-animation-duration:150ms;-moz-animation-duration:150ms}.slidedown.out.reverse{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-webkit-animation-name:slideouttotop;-moz-animation-name:slideouttotop;-webkit-animation-duration:200ms;-moz-animation-duration:200ms}@-webkit-keyframes slideinfromtop{from{-webkit-transform:translateY(-100%)}to{-webkit-transform:translateY(0)}}@-moz-keyframes slideinfromtop{from{-moz-transform:translateY(-100%)}to{-moz-transform:translateY(0)}}@-webkit-keyframes slideouttotop{from{-webkit-transform:translateY(0)}to{-webkit-transform:translateY(-100%)}}@-moz-keyframes slideouttotop{from{-moz-transform:translateY(0)}to{-moz-transform:translateY(-100%)}}.slideup.out{-webkit-animation-name:fadeout;-moz-animation-name:fadeout;-webkit-animation-duration:100ms;-moz-animation-duration:100ms}.slideup.in{-webkit-transform:translateY(0);-webkit-animation-name:slideinfrombottom;-moz-transform:translateY(0);-moz-animation-name:slideinfrombottom;-webkit-animation-duration:250ms;-moz-animation-duration:250ms}.slideup.in.reverse{-webkit-animation-name:fadein;-moz-animation-name:fadein;-webkit-animation-duration:150ms;-moz-animation-duration:150ms}.slideup.out.reverse{-webkit-transform:translateY(100%);-moz-transform:translateY(100%);-webkit-animation-name:slideouttobottom;-moz-animation-name:slideouttobottom;-webkit-animation-duration:200ms;-moz-animation-duration:200ms}@-webkit-keyframes slideinfrombottom{from{-webkit-transform:translateY(100%)}to{-webkit-transform:translateY(0)}}@-moz-keyframes slideinfrombottom{from{-moz-transform:translateY(100%)}to{-moz-transform:translateY(0)}}@-webkit-keyframes slideouttobottom{from{-webkit-transform:translateY(0)}to{-webkit-transform:translateY(100%)}}@-moz-keyframes slideouttobottom{from{-moz-transform:translateY(0)}to{-moz-transform:translateY(100%)}}.viewport-flip{-webkit-perspective:1000;-moz-perspective:1000;position:absolute}.flip{-webkit-backface-visibility:hidden;-webkit-transform:translateX(0);-moz-backface-visibility:hidden;-moz-transform:translateX(0)}.flip.out{-webkit-transform:rotateY(-90deg) scale(.9);-webkit-animation-name:flipouttoleft;-webkit-animation-duration:175ms;-moz-transform:rotateY(-90deg) scale(.9);-moz-animation-name:flipouttoleft;-moz-animation-duration:175ms}.flip.in{-webkit-animation-name:flipintoright;-webkit-animation-duration:225ms;-moz-animation-name:flipintoright;-moz-animation-duration:225ms}.flip.out.reverse{-webkit-transform:rotateY(90deg) scale(.9);-webkit-animation-name:flipouttoright;-moz-transform:rotateY(90deg) scale(.9);-moz-animation-name:flipouttoright}.flip.in.reverse{-webkit-animation-name:flipintoleft;-moz-animation-name:flipintoleft}@-webkit-keyframes flipouttoleft{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(.9)}}@-moz-keyframes flipouttoleft{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(-90deg) scale(.9)}}@-webkit-keyframes flipouttoright{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(.9)}}@-moz-keyframes flipouttoright{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(90deg) scale(.9)}}@-webkit-keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoleft{from{-moz-transform:rotateY(-90deg) scale(.9)}to{-moz-transform:rotateY(0)}}@-webkit-keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoright{from{-moz-transform:rotateY(90deg) scale(.9)}to{-moz-transform:rotateY(0)}}.viewport-turn{-webkit-perspective:1000;-moz-perspective:1000;position:absolute}.turn{-webkit-backface-visibility:hidden;-webkit-transform:translateX(0);-webkit-transform-origin:0;-moz-backface-visibility:hidden;-moz-transform:translateX(0);-moz-transform-origin:0}.turn.out{-webkit-transform:rotateY(-90deg) scale(.9);-webkit-animation-name:flipouttoleft;-moz-transform:rotateY(-90deg) scale(.9);-moz-animation-name:flipouttoleft;-webkit-animation-duration:125ms;-moz-animation-duration:125ms}.turn.in{-webkit-animation-name:flipintoright;-moz-animation-name:flipintoright;-webkit-animation-duration:250ms;-moz-animation-duration:250ms}.turn.out.reverse{-webkit-transform:rotateY(90deg) scale(.9);-webkit-animation-name:flipouttoright;-moz-transform:rotateY(90deg) scale(.9);-moz-animation-name:flipouttoright}.turn.in.reverse{-webkit-animation-name:flipintoleft;-moz-animation-name:flipintoleft}@-webkit-keyframes flipouttoleft{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(.9)}}@-moz-keyframes flipouttoleft{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(-90deg) scale(.9)}}@-webkit-keyframes flipouttoright{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(.9)}}@-moz-keyframes flipouttoright{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(90deg) scale(.9)}}@-webkit-keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoleft{from{-moz-transform:rotateY(-90deg) scale(.9)}to{-moz-transform:rotateY(0)}}@-webkit-keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoright{from{-moz-transform:rotateY(90deg) scale(.9)}to{-moz-transform:rotateY(0)}}.flow{-webkit-transform-origin:50% 30%;-moz-transform-origin:50% 30%;-webkit-box-shadow:0 0 20px rgba(0,0,0,.4);-moz-box-shadow:0 0 20px rgba(0,0,0,.4)}.ui-dialog.flow{-webkit-transform-origin:none;-moz-transform-origin:none;-webkit-box-shadow:none;-moz-box-shadow:none}.flow.out{-webkit-transform:translateX(-100%) scale(.7);-webkit-animation-name:flowouttoleft;-webkit-animation-timing-function:ease;-webkit-animation-duration:350ms;-moz-transform:translateX(-100%) scale(.7);-moz-animation-name:flowouttoleft;-moz-animation-timing-function:ease;-moz-animation-duration:350ms}.flow.in{-webkit-transform:translateX(0) scale(1);-webkit-animation-name:flowinfromright;-webkit-animation-timing-function:ease;-webkit-animation-duration:350ms;-moz-transform:translateX(0) scale(1);-moz-animation-name:flowinfromright;-moz-animation-timing-function:ease;-moz-animation-duration:350ms}.flow.out.reverse{-webkit-transform:translateX(100%);-webkit-animation-name:flowouttoright;-moz-transform:translateX(100%);-moz-animation-name:flowouttoright}.flow.in.reverse{-webkit-animation-name:flowinfromleft;-moz-animation-name:flowinfromleft}@-webkit-keyframes flowouttoleft{0%{-webkit-transform:translateX(0) scale(1)}60%,70%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(-100%) scale(.7)}}@-moz-keyframes flowouttoleft{0%{-moz-transform:translateX(0) scale(1)}60%,70%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(-100%) scale(.7)}}@-webkit-keyframes flowouttoright{0%{-webkit-transform:translateX(0) scale(1)}60%,70%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(100%) scale(.7)}}@-moz-keyframes flowouttoright{0%{-moz-transform:translateX(0) scale(1)}60%,70%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(100%) scale(.7)}}@-webkit-keyframes flowinfromleft{0%{-webkit-transform:translateX(-100%) scale(.7)}30%,40%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(0) scale(1)}}@-moz-keyframes flowinfromleft{0%{-moz-transform:translateX(-100%) scale(.7)}30%,40%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(0) scale(1)}}@-webkit-keyframes flowinfromright{0%{-webkit-transform:translateX(100%) scale(.7)}30%,40%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(0) scale(1)}}@-moz-keyframes flowinfromright{0%{-moz-transform:translateX(100%) scale(.7)}30%,40%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(0) scale(1)}}.ui-grid-a,.ui-grid-b,.ui-grid-c,.ui-grid-d{overflow:hidden}.ui-block-a,.ui-block-b,.ui-block-c,.ui-block-d,.ui-block-e{margin:0;padding:0;border:0;float:left;min-height:1px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.ui-grid-solo .ui-block-a{display:block;float:none}.ui-grid-a .ui-block-a,.ui-grid-a .ui-block-b{width:49.95%}.ui-grid-a >:nth-child(n){width:50%;margin-right:-.5px}.ui-grid-a .ui-block-a{clear:left}.ui-grid-b .ui-block-a,.ui-grid-b .ui-block-b,.ui-grid-b .ui-block-c{width:33.25%}.ui-grid-b >:nth-child(n){width:33.333%;margin-right:-.5px}.ui-grid-b .ui-block-a{clear:left}.ui-grid-c .ui-block-a,.ui-grid-c .ui-block-b,.ui-grid-c .ui-block-c,.ui-grid-c .ui-block-d{width:24.925%}.ui-grid-c >:nth-child(n){width:25%;margin-right:-.5px}.ui-grid-c .ui-block-a{clear:left}.ui-grid-d .ui-block-a,.ui-grid-d .ui-block-b,.ui-grid-d .ui-block-c,.ui-grid-d .ui-block-d,.ui-grid-d .ui-block-e{width:19.925%}.ui-grid-d >:nth-child(n){width:20%}.ui-grid-d .ui-block-a{clear:left}.ui-header-fixed,.ui-footer-fixed{left:0;right:0;width:100%;position:fixed;z-index:1000}.ui-header-fixed{top:0}.ui-footer-fixed{bottom:0}.ui-header-fullscreen,.ui-footer-fullscreen{filter:Alpha(Opacity=90);opacity:.9}.ui-page-header-fixed{padding-top:2.6875em}.ui-page-footer-fixed{padding-bottom:2.6875em}.ui-page-header-fullscreen .ui-content,.ui-page-footer-fullscreen .ui-content{padding:0}.ui-fixed-hidden{position:absolute}.ui-page-header-fullscreen .ui-fixed-hidden,.ui-page-footer-fullscreen .ui-fixed-hidden{left:-9999px}.ui-header-fixed .ui-btn,.ui-footer-fixed .ui-btn{z-index:10}.ui-navbar{max-width:100%}.ui-navbar.ui-mini{margin:0}.ui-navbar ul:before,.ui-navbar ul:after{content:" ";display:table}.ui-navbar ul:after{clear:both}.ui-navbar ul{list-style:none;margin:0;padding:0;position:relative;display:block;border:0;max-width:100%;overflow:visible;zoom:1}.ui-navbar li .ui-btn{display:block;text-align:center;margin:0 -1px 0 0;border-right-width:0}.ui-navbar li .ui-btn-icon-right .ui-icon{right:6px}.ui-navbar li:last-child .ui-btn,.ui-navbar .ui-grid-duo .ui-block-b .ui-btn{margin-right:0;border-right-width:1px}.ui-header .ui-navbar li:last-child .ui-btn,.ui-footer .ui-navbar li:last-child .ui-btn,.ui-header .ui-navbar .ui-grid-duo .ui-block-b .ui-btn,.ui-footer .ui-navbar .ui-grid-duo .ui-block-b .ui-btn{margin-right:-1px;border-right-width:0}.ui-navbar .ui-grid-duo li.ui-block-a:last-child .ui-btn{margin-right:-1px;border-right-width:1px}.ui-header .ui-navbar li .ui-btn,.ui-footer .ui-navbar li .ui-btn{border-top-width:0;border-bottom-width:0}.ui-header .ui-navbar .ui-grid-b li.ui-block-c .ui-btn,.ui-footer .ui-navbar .ui-grid-b li.ui-block-c .ui-btn{margin-right:-5px}.ui-header .ui-navbar .ui-grid-c li.ui-block-d .ui-btn,.ui-footer .ui-navbar .ui-grid-c li.ui-block-d .ui-btn,.ui-header .ui-navbar .ui-grid-d li.ui-block-e .ui-btn,.ui-footer .ui-navbar .ui-grid-d li.ui-block-e .ui-btn{margin-right:-4px}.ui-header .ui-navbar .ui-grid-b li.ui-block-c .ui-btn-icon-right .ui-icon,.ui-footer .ui-navbar .ui-grid-b li.ui-block-c .ui-btn-icon-right .ui-icon,.ui-header .ui-navbar .ui-grid-c li.ui-block-d .ui-btn-icon-right .ui-icon,.ui-footer .ui-navbar .ui-grid-c li.ui-block-d .ui-btn-icon-right .ui-icon,.ui-header .ui-navbar .ui-grid-d li.ui-block-e .ui-btn-icon-right .ui-icon,.ui-footer .ui-navbar .ui-grid-d li.ui-block-e .ui-btn-icon-right .ui-icon{right:8px}.ui-navbar li .ui-btn .ui-btn-inner{padding-top:.7em;padding-bottom:.8em}.ui-navbar li .ui-btn-icon-top .ui-btn-inner{padding-top:30px}.ui-navbar li .ui-btn-icon-bottom .ui-btn-inner{padding-bottom:30px}.ui-btn{display:block;text-align:center;cursor:pointer;position:relative;margin:.5em 0;padding:0}.ui-mini{margin-top:.25em;margin-bottom:.25em}.ui-btn-left,.ui-btn-right,.ui-input-clear,.ui-btn-inline,.ui-grid-a .ui-btn,.ui-grid-b .ui-btn,.ui-grid-c .ui-btn,.ui-grid-d .ui-btn,.ui-grid-e .ui-btn,.ui-grid-solo .ui-btn{margin-right:5px;margin-left:5px}.ui-btn-inner{font-size:16px;padding:.6em 20px;min-width:.75em;display:block;position:relative;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;zoom:1}.ui-btn input,.ui-btn button{z-index:2}.ui-btn-left,.ui-btn-right,.ui-btn-inline{display:inline-block;vertical-align:middle}.ui-mobile .ui-btn-left,.ui-mobile .ui-btn-right{margin:0}.ui-btn-block{display:block}.ui-header > .ui-btn,.ui-footer > .ui-btn{display:inline-block;margin:0}.ui-header .ui-btn-block,.ui-footer .ui-btn-block{display:block}.ui-header .ui-btn-inner,.ui-footer .ui-btn-inner,.ui-mini .ui-btn-inner{font-size:12.5px;padding:.55em 11px .5em}.ui-fullsize .ui-btn-inner,.ui-fullsize .ui-btn-inner{font-size:16px;padding:.6em 20px}.ui-btn-icon-notext{width:24px;height:24px}.ui-btn-icon-notext .ui-btn-inner{padding:0;height:100%}.ui-btn-icon-notext .ui-btn-inner .ui-icon{margin:2px 1px 2px 3px;float:left}.ui-btn-text{position:relative;z-index:1;width:100%;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.ui-btn-icon-notext .ui-btn-text{position:absolute;left:-9999px}.ui-btn-icon-left .ui-btn-inner{padding-left:40px}.ui-btn-icon-right .ui-btn-inner{padding-right:40px}.ui-btn-icon-top .ui-btn-inner{padding-top:40px}.ui-btn-icon-bottom .ui-btn-inner{padding-bottom:40px}.ui-header .ui-btn-icon-left .ui-btn-inner,.ui-footer .ui-btn-icon-left .ui-btn-inner,.ui-mini.ui-btn-icon-left .ui-btn-inner,.ui-mini .ui-btn-icon-left .ui-btn-inner{padding-left:30px}.ui-header .ui-btn-icon-right .ui-btn-inner,.ui-footer .ui-btn-icon-right .ui-btn-inner,.ui-mini.ui-btn-icon-right .ui-btn-inner,.ui-mini .ui-btn-icon-right .ui-btn-inner{padding-right:30px}.ui-header .ui-btn-icon-top .ui-btn-inner,.ui-footer .ui-btn-icon-top .ui-btn-inner{padding:30px 3px .5em 3px}.ui-mini.ui-btn-icon-top .ui-btn-inner,.ui-mini .ui-btn-icon-top .ui-btn-inner{padding-top:30px}.ui-header .ui-btn-icon-bottom .ui-btn-inner,.ui-footer .ui-btn-icon-bottom .ui-btn-inner{padding:.55em 3px 30px 3px}.ui-mini.ui-btn-icon-bottom .ui-btn-inner,.ui-mini .ui-btn-icon-bottom .ui-btn-inner{padding-bottom:30px}.ui-btn-icon-notext .ui-icon{display:block;z-index:0}.ui-btn-icon-left > .ui-btn-inner > .ui-icon,.ui-btn-icon-right > .ui-btn-inner > .ui-icon{position:absolute;top:50%;margin-top:-9px}.ui-btn-icon-top .ui-btn-inner .ui-icon,.ui-btn-icon-bottom .ui-btn-inner .ui-icon{position:absolute;left:50%;margin-left:-9px}.ui-btn-icon-left .ui-icon{left:10px}.ui-btn-icon-right .ui-icon{right:10px}.ui-btn-icon-top .ui-icon{top:10px}.ui-btn-icon-bottom .ui-icon{top:auto;bottom:10px}.ui-header .ui-btn-icon-left .ui-icon,.ui-footer .ui-btn-icon-left .ui-icon,.ui-mini.ui-btn-icon-left .ui-icon,.ui-mini .ui-btn-icon-left .ui-icon{left:5px}.ui-header .ui-btn-icon-right .ui-icon,.ui-footer .ui-btn-icon-right .ui-icon,.ui-mini.ui-btn-icon-right .ui-icon,.ui-mini .ui-btn-icon-right .ui-icon{right:5px}.ui-header .ui-btn-icon-top .ui-icon,.ui-footer .ui-btn-icon-top .ui-icon,.ui-mini.ui-btn-icon-top .ui-icon,.ui-mini .ui-btn-icon-top .ui-icon{top:5px}.ui-header .ui-btn-icon-bottom .ui-icon,.ui-footer .ui-btn-icon-bottom .ui-icon,.ui-mini.ui-btn-icon-bottom .ui-icon,.ui-mini .ui-btn-icon-bottom .ui-icon{bottom:5px}.ui-btn-hidden{position:absolute;top:0;left:0;width:100%;height:100%;-webkit-appearance:none;cursor:pointer;background:#fff;background:rgba(255,255,255,0);filter:Alpha(Opacity=0);opacity:.1;font-size:1px;border:none;text-indent:-9999px}.ui-disabled .ui-btn-hidden{display:none}.ui-disabled{z-index:1}.ui-field-contain .ui-btn.ui-submit{margin:0}label.ui-submit{font-size:16px;line-height:1.4;font-weight:normal;margin:0 0 .3em;display:block}@media all and (min-width:450px){.ui-field-contain label.ui-submit{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain .ui-btn.ui-submit{width:78%;display:inline-block;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.ui-hide-label .ui-btn.ui-submit{width:auto;display:block}}.ui-collapsible-inset{margin:.5em 0}.ui-collapsible-heading{font-size:16px;display:block;margin:0 -15px;padding:0;position:relative}.ui-collapsible-inset .ui-collapsible-heading{margin:0}.ui-collapsible-heading .ui-btn{text-align:left;margin:0;border-left-width:0;border-right-width:0}.ui-collapsible-inset .ui-collapsible-heading .ui-btn{border-right-width:1px;border-left-width:1px}.ui-collapsible-collapsed + .ui-collapsible:not(.ui-collapsible-inset) .ui-collapsible-heading .ui-btn{border-top-width:0}.ui-collapsible-set .ui-collapsible:not(.ui-collapsible-inset) .ui-collapsible-heading .ui-btn{border-top-width:1px}.ui-collapsible-heading .ui-btn-inner,.ui-collapsible-heading .ui-btn-icon-left .ui-btn-inner{padding-left:40px}.ui-collapsible-heading .ui-btn-icon-right .ui-btn-inner{padding-left:12px;padding-right:40px}.ui-collapsible-heading .ui-btn-icon-top .ui-btn-inner,.ui-collapsible-heading .ui-btn-icon-bottom .ui-btn-inner{padding-right:40px;text-align:center}.ui-collapsible-heading .ui-btn span.ui-btn{position:absolute;left:6px;top:50%;margin:-12px 0 0 0;width:20px;height:20px;padding:1px 0 1px 2px;text-indent:-9999px}.ui-collapsible-heading .ui-btn span.ui-btn .ui-btn-inner{padding:10px 0}.ui-collapsible-heading .ui-btn span.ui-btn .ui-icon{left:0;margin-top:-10px}.ui-collapsible-heading-status{position:absolute;top:-9999px;left:0}.ui-collapsible-content{display:block;margin:0 -15px;padding:10px 15px;border-left-width:0;border-right-width:0;border-top:none;background-image:none}.ui-collapsible-inset .ui-collapsible-content{margin:0;border-right-width:1px;border-left-width:1px}.ui-collapsible-content-collapsed{display:none}.ui-collapsible-set{margin:.5em 0}.ui-collapsible-set .ui-collapsible{margin:-1px 0 0}.ui-collapsible-set .ui-collapsible:first-child{margin-top:0}.ui-controlgroup,fieldset.ui-controlgroup{padding:0;margin:.5em 0;zoom:1}.ui-controlgroup.ui-mini,fieldset.ui-controlgroup.ui-mini{margin:.25em 0}.ui-field-contain .ui-controlgroup,.ui-field-contain fieldset.ui-controlgroup{margin:0}.ui-bar .ui-controlgroup{margin:0 5px}.ui-controlgroup-label{font-size:16px;line-height:1.4;font-weight:normal;margin:0 0 .4em}.ui-controlgroup li{list-style:none}.ui-controlgroup-vertical .ui-btn,.ui-controlgroup-vertical .ui-checkbox,.ui-controlgroup-vertical .ui-radio{margin:0;border-bottom-width:0}.ui-controlgroup-vertical .ui-controlgroup-last{border-bottom-width:1px}.ui-controlgroup-controls label.ui-select{position:absolute;left:-9999px}.ui-controlgroup .ui-btn-icon-notext{width:auto;height:auto;top:auto}.ui-controlgroup .ui-btn-icon-notext .ui-btn-inner{height:20px;padding:.6em 20px .6em 20px}.ui-controlgroup-horizontal .ui-btn-icon-notext .ui-btn-inner{width:18px}.ui-controlgroup.ui-mini .ui-btn-icon-notext .ui-btn-inner,.ui-header .ui-controlgroup .ui-btn-icon-notext .ui-btn-inner,.ui-footer .ui-controlgroup .ui-btn-icon-notext .ui-btn-inner{height:16px;padding:.55em 11px .5em 11px}.ui-controlgroup .ui-btn-icon-notext .ui-btn-inner .ui-icon{position:absolute;top:50%;right:50%;margin:-9px -9px 0 0}.ui-controlgroup-horizontal .ui-controlgroup-controls:before,.ui-controlgroup-horizontal .ui-controlgroup-controls:after{content:"";display:table}.ui-controlgroup-horizontal .ui-controlgroup-controls:after{clear:both}.ui-controlgroup-horizontal .ui-controlgroup-controls{display:inline-block;vertical-align:middle;zoom:1}.ui-controlgroup-horizontal .ui-btn-inner{text-align:center}.ui-controlgroup-horizontal.ui-mini .ui-btn-inner{height:16px;line-height:16px}.ui-controlgroup-horizontal .ui-btn,.ui-controlgroup-horizontal .ui-select,.ui-controlgroup-horizontal .ui-checkbox,.ui-controlgroup-horizontal .ui-radio{float:left;clear:none;margin:0 -1px 0 0}.ui-controlgroup-horizontal .ui-select .ui-btn,.ui-controlgroup-horizontal .ui-checkbox .ui-btn,.ui-controlgroup-horizontal .ui-radio .ui-btn{float:none;margin:0}.ui-controlgroup-horizontal .ui-controlgroup-last,.ui-controlgroup-horizontal .ui-select:last-child,.ui-controlgroup-horizontal .ui-checkbox:last-child,.ui-controlgroup-horizontal .ui-radio:last-child{margin-right:0}.ui-controlgroup .ui-checkbox label,.ui-controlgroup .ui-radio label{font-size:16px}@media all and (min-width:450px){.ui-field-contain .ui-controlgroup-label{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain .ui-controlgroup-controls{width:78%;display:inline-block}.ui-field-contain .ui-controlgroup .ui-select{width:100%;display:block}.ui-field-contain .ui-controlgroup-horizontal .ui-select{width:auto}.ui-hide-label .ui-controlgroup-controls{width:100%}}.ui-dialog{background:none!important}.ui-dialog-contain{width:92.5%;max-width:500px;margin:10% auto 15px auto;padding:0;position:relative;top:-15px}.ui-dialog-contain > .ui-header,.ui-dialog-contain > .ui-content,.ui-dialog-contain > .ui-footer{display:block;position:relative;width:auto;margin:0}.ui-dialog-contain > .ui-header{border:none;overflow:hidden;z-index:10;padding:0}.ui-dialog-contain > .ui-content{padding:15px}.ui-dialog-contain > .ui-footer{z-index:10;padding:0 15px}.ui-popup-open .ui-header-fixed,.ui-popup-open .ui-footer-fixed{position:absolute!important}.ui-popup-screen{background-image:url(data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==);top:0;left:0;right:0;bottom:1px;position:absolute;filter:Alpha(Opacity=0);opacity:0;z-index:1099}.ui-popup-screen.in{opacity:0.5;filter:Alpha(Opacity=50)}.ui-popup-screen.out{opacity:0;filter:Alpha(Opacity=0)}.ui-popup-container{z-index:1100;display:inline-block;position:absolute;padding:0;outline:0}.ui-popup{position:relative}.ui-popup.ui-content,.ui-popup .ui-content{overflow:visible}.ui-popup > p,.ui-popup > h1,.ui-popup > h2,.ui-popup > h3,.ui-popup > h4,.ui-popup > h5,.ui-popup > h6{margin:.5em 7px}.ui-popup > span{display:block;margin:.5em 7px}.ui-popup .ui-title{font-size:16px;font-weight:bold;margin-top:.5em;margin-bottom:.5em}.ui-popup-container .ui-content > p,.ui-popup-container .ui-content > h1,.ui-popup-container .ui-content > h2,.ui-popup-container .ui-content > h3,.ui-popup-container .ui-content > h4,.ui-popup-container .ui-content > h5,.ui-popup-container .ui-content > h6{margin:.5em 0}.ui-popup-container .ui-content > span{margin:0}.ui-popup-container .ui-content > p:first-child,.ui-popup-container .ui-content > h1:first-child,.ui-popup-container .ui-content > h2:first-child,.ui-popup-container .ui-content > h3:first-child,.ui-popup-container .ui-content > h4:first-child,.ui-popup-container .ui-content > h5:first-child,.ui-popup-container .ui-content > h6:first-child{margin-top:0}.ui-popup-container .ui-content > p:last-child,.ui-popup-container .ui-content > h1:last-child,.ui-popup-container .ui-content > h2:last-child,.ui-popup-container .ui-content > h3:last-child,.ui-popup-container .ui-content > h4:last-child,.ui-popup-container .ui-content > h5:last-child,.ui-popup-container .ui-content > h6:last-child{margin-bottom:0}.ui-popup > img{width:auto;height:auto;max-width:100%;max-height:100%;vertical-align:middle}.ui-popup iframe{vertical-align:middle}@media all and (min-width:450px){.ui-popup .ui-field-contain label.ui-submit,.ui-popup .ui-field-contain .ui-controlgroup-label,.ui-popup .ui-field-contain label.ui-select,.ui-popup .ui-field-contain label.ui-input-text{font-size:16px;line-height:1.4;display:block;font-weight:normal;margin:0 0 .3em}.ui-popup .ui-field-contain .ui-btn.ui-submit,.ui-popup .ui-field-contain .ui-controlgroup-controls,.ui-popup .ui-field-contain .ui-select,.ui-popup .ui-field-contain input.ui-input-text,.ui-popup .ui-field-contain textarea.ui-input-text,.ui-popup .ui-field-contain .ui-input-search{width:100%;display:block}}.ui-popup > .ui-btn-left,.ui-popup > .ui-btn-right{position:absolute;top:-9px;margin:0;z-index:1101}.ui-popup > .ui-btn-left{left:-9px}.ui-popup > .ui-btn-right{right:-9px}.ui-popup.ui-corner-all > .ui-header,.ui-popup.ui-corner-all ~ .ui-content,.ui-popup.ui-corner-all > .ui-content:first-child{-webkit-border-top-left-radius:inherit;border-top-left-radius:inherit;-webkit-border-top-right-radius:inherit;border-top-right-radius:inherit}.ui-popup.ui-corner-all > .ui-content,.ui-popup.ui-corner-all > .ui-footer,.ui-popup.ui-corner-all > .ui-header:nth-child(n):last-child{-webkit-border-bottom-left-radius:inherit;border-bottom-left-radius:inherit;-webkit-border-bottom-right-radius:inherit;border-bottom-right-radius:inherit}.ui-popup.ui-corner-all > .ui-content:nth-child(2),.ui-popup.ui-corner-all > .ui-header:nth-child(2){-webkit-border-top-left-radius:0;border-top-left-radius:0;-webkit-border-top-right-radius:0;border-top-right-radius:0}.ui-popup.ui-corner-all > .ui-content:nth-last-child(1n+2),.ui-popup.ui-corner-all > .ui-footer:nth-last-child(1n+2){-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0}.ui-popup.ui-corner-all > .ui-header:only-child,.ui-popup.ui-corner-all > .ui-footer:only-child{-webkit-border-radius:inherit;border-radius:inherit}.ui-checkbox,.ui-radio{position:relative;clear:both;margin:0;z-index:1}.ui-checkbox .ui-btn,.ui-radio .ui-btn{margin-top:.5em;margin-bottom:.5em;text-align:left;z-index:2}.ui-checkbox .ui-btn.ui-mini,.ui-radio .ui-btn.ui-mini{margin:.25em 0}.ui-controlgroup .ui-checkbox .ui-btn,.ui-controlgroup .ui-radio .ui-btn{margin:0}.ui-checkbox .ui-btn-inner,.ui-radio .ui-btn-inner{white-space:normal}.ui-checkbox .ui-btn-icon-left .ui-btn-inner,.ui-radio .ui-btn-icon-left .ui-btn-inner{padding-left:45px}.ui-checkbox .ui-mini.ui-btn-icon-left .ui-btn-inner,.ui-radio .ui-mini.ui-btn-icon-left .ui-btn-inner{padding-left:36px}.ui-checkbox .ui-btn-icon-right .ui-btn-inner,.ui-radio .ui-btn-icon-right .ui-btn-inner{padding-right:45px}.ui-checkbox .ui-mini.ui-btn-icon-right .ui-btn-inner,.ui-radio .ui-mini.ui-btn-icon-right .ui-btn-inner{padding-right:36px}.ui-checkbox .ui-btn-icon-top .ui-btn-inner,.ui-radio .ui-btn-icon-top .ui-btn-inner{padding-right:0;padding-left:0;text-align:center}.ui-checkbox .ui-btn-icon-bottom .ui-btn-inner,.ui-radio .ui-btn-icon-bottom .ui-btn-inner{padding-right:0;padding-left:0;text-align:center}.ui-checkbox .ui-icon,.ui-radio .ui-icon{top:1.1em}.ui-checkbox .ui-btn-icon-left .ui-icon,.ui-radio .ui-btn-icon-left .ui-icon{left:15px}.ui-checkbox .ui-mini.ui-btn-icon-left .ui-icon,.ui-radio .ui-mini.ui-btn-icon-left .ui-icon{left:9px}.ui-checkbox .ui-btn-icon-right .ui-icon,.ui-radio .ui-btn-icon-right .ui-icon{right:15px}.ui-checkbox .ui-mini.ui-btn-icon-right .ui-icon,.ui-radio .ui-mini.ui-btn-icon-right .ui-icon{right:9px}.ui-checkbox .ui-btn-icon-top .ui-icon,.ui-radio .ui-btn-icon-top .ui-icon{top:10px}.ui-checkbox .ui-btn-icon-bottom .ui-icon,.ui-radio .ui-btn-icon-bottom .ui-icon{top:auto;bottom:10px}.ui-checkbox .ui-btn-icon-right .ui-icon,.ui-radio .ui-btn-icon-right .ui-icon{right:15px}.ui-checkbox .ui-mini.ui-btn-icon-right .ui-icon,.ui-radio .ui-mini.ui-btn-icon-right .ui-icon{right:9px}.ui-checkbox input,.ui-radio input{position:absolute;left:20px;top:50%;width:10px;height:10px;margin:-5px 0 0 0;outline:0!important;z-index:1}.ui-field-contain,fieldset.ui-field-contain{padding:.8em 0;margin:0;border-width:0 0 1px 0;overflow:visible}.ui-field-contain:last-child{border-bottom-width:0}.ui-field-contain{max-width:100%}@media all and (min-width:450px){.ui-field-contain,.ui-mobile fieldset.ui-field-contain{border-width:0;padding:0;margin:1em 0}}.ui-select{display:block;position:relative}.ui-select select{position:absolute;left:-9999px;top:-9999px}.ui-select .ui-btn{overflow:hidden;opacity:1}.ui-field-contain .ui-select .ui-btn{margin:0}.ui-select .ui-btn select{cursor:pointer;-webkit-appearance:none;left:0;top:0;width:100%;min-height:1.5em;min-height:100%;height:3em;max-height:100%;filter:Alpha(Opacity=0);opacity:0;z-index:2}.ui-select .ui-disabled{opacity:.3}.ui-select .ui-disabled select{display:none}@-moz-document url-prefix(){.ui-select .ui-btn select{opacity:0.0001}}.ui-select .ui-btn.ui-select-nativeonly{border-radius:0;border:0}.ui-select .ui-btn.ui-select-nativeonly select{opacity:1;text-indent:0;display:block}.ui-select .ui-disabled.ui-select-nativeonly .ui-btn-inner{opacity:0}.ui-select .ui-btn-icon-right .ui-btn-inner,.ui-select .ui-li-has-count .ui-btn-inner{padding-right:45px}.ui-select .ui-mini.ui-btn-icon-right .ui-btn-inner{padding-right:32px}.ui-select .ui-btn-icon-right.ui-li-has-count .ui-btn-inner{padding-right:80px}.ui-select .ui-mini.ui-btn-icon-right.ui-li-has-count .ui-btn-inner{padding-right:67px}.ui-select .ui-btn-icon-right .ui-icon{right:15px}.ui-select .ui-mini.ui-btn-icon-right .ui-icon{right:7px}.ui-select .ui-btn-icon-right.ui-li-has-count .ui-li-count{right:45px}.ui-select .ui-mini.ui-btn-icon-right.ui-li-has-count .ui-li-count{right:32px}label.ui-select{font-size:16px;line-height:1.4;font-weight:normal;margin:0 0 .3em;display:block}.ui-select .ui-btn-text,.ui-selectmenu .ui-btn-text{display:block;min-height:1em;overflow:hidden!important}.ui-select .ui-btn-text{text-overflow:ellipsis}.ui-selectmenu{padding:6px;min-width:160px}.ui-selectmenu .ui-listview{margin:0}.ui-selectmenu .ui-btn.ui-li-divider{cursor:default}.ui-selectmenu-hidden{top:-99999px;left:-9999px}.ui-screen-hidden,.ui-selectmenu-list .ui-li .ui-icon{display:none}.ui-selectmenu-list .ui-li .ui-icon{display:block}.ui-li.ui-selectmenu-placeholder{display:none}.ui-selectmenu .ui-header{margin:0;padding:0}.ui-selectmenu .ui-header .ui-title{margin:0.6em 46px 0.8em}@media all and (min-width:450px){.ui-field-contain label.ui-select{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain .ui-select{width:78%;display:inline-block}.ui-hide-label .ui-select{width:100%}}.ui-selectmenu .ui-header h1:after{content:'.';visibility:hidden}label.ui-input-text{font-size:16px;line-height:1.4;display:block;font-weight:normal;margin:0 0 .3em}input.ui-input-text,textarea.ui-input-text{background-image:none;padding:.4em;margin:.5em 0;line-height:1.4;font-size:16px;display:block;width:100%;outline:0}input.ui-input-text.ui-mini,textarea.ui-input-text.ui-mini{margin:.25em 0}.ui-field-contain input.ui-input-text,.ui-field-contain textarea.ui-input-text{margin:0}input.ui-input-text,textarea.ui-input-text,.ui-input-search{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}input.ui-input-text{-webkit-appearance:none}textarea.ui-input-text{height:50px;-webkit-transition:height 200ms linear;-moz-transition:height 200ms linear;-o-transition:height 200ms linear;transition:height 200ms linear}.ui-input-search{padding:0 30px;margin:.5em 0;background-image:none;position:relative}.ui-input-search.ui-mini{margin:.25em 0}.ui-field-contain .ui-input-search{margin:0}.ui-icon-searchfield:after{position:absolute;left:7px;top:50%;margin-top:-9px;content:"";width:18px;height:18px;opacity:.5}.ui-input-search input.ui-input-text{border:none;width:98%;padding:.4em 0;margin:0;display:block;background:transparent none;outline:0!important}.ui-input-search .ui-input-clear{position:absolute;right:0;top:50%;margin-top:-13px}.ui-mini .ui-input-clear{right:-3px}.ui-input-search .ui-input-clear-hidden{display:none}input.ui-mini,.ui-mini input,textarea.ui-mini{font-size:14px}textarea.ui-mini{height:45px}@media all and (min-width:450px){.ui-field-contain label.ui-input-text{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain input.ui-input-text,.ui-field-contain textarea.ui-input-text,.ui-field-contain .ui-input-search{width:78%;display:inline-block}.ui-hide-label input.ui-input-text,.ui-hide-label textarea.ui-input-text,.ui-hide-label .ui-input-search{width:100%}.ui-input-search input.ui-input-text{width:98%}}.ui-listview{margin:0}ol.ui-listview,ol.ui-listview .ui-li-divider{counter-reset:listnumbering}.ui-content .ui-listview{margin:-15px}.ui-collapsible-content > .ui-listview{margin:-10px -15px}.ui-content .ui-listview-inset{margin:1em 0}.ui-collapsible-content .ui-listview-inset{margin:.5em 0}.ui-listview,.ui-li{list-style:none;padding:0}.ui-li,.ui-li.ui-field-contain{display:block;margin:0;position:relative;overflow:visible;text-align:left;border-width:0;border-top-width:1px}.ui-li.ui-btn{margin:0}.ui-li .ui-btn-text a.ui-link-inherit{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.ui-li-static{background-image:none}.ui-li-divider{padding:.5em 15px;font-size:14px;font-weight:bold}ol.ui-listview .ui-link-inherit:before,ol.ui-listview .ui-li-static:before,.ui-li-dec{font-size:.8em;display:inline-block;padding-right:.3em;font-weight:normal;counter-increment:listnumbering;content:counter(listnumbering) ". "}ol.ui-listview .ui-li-jsnumbering:before{content:""!important}.ui-listview-inset .ui-li{border-right-width:1px;border-left-width:1px}.ui-li-last,.ui-li.ui-field-contain.ui-li-last{border-bottom-width:1px}.ui-collapsible [class*="ui-body"] > .ui-listview:not(.ui-listview-inset) .ui-li-last{border-bottom-width:0}.ui-collapsible-content > .ui-listview:not(.ui-listview-inset) .ui-li:first-child{border-top-width:0}.ui-collapsible-content > .ui-listview:not(.ui-listview-inset),.ui-collapsible-content > .ui-listview:not(.ui-listview-inset) .ui-li-last{-webkit-border-bottom-left-radius:inherit;-webkit-border-bottom-right-radius:inherit;border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.ui-collapsible-content > .ui-listview:not(.ui-listview-inset) .ui-li-last .ui-li-link-alt{-webkit-border-bottom-right-radius:inherit;border-bottom-right-radius:inherit}.ui-li>.ui-btn-inner{display:block;position:relative;padding:0}.ui-li .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li{padding:.7em 15px;display:block}.ui-li-has-thumb .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-thumb{min-height:60px;padding-left:100px}.ui-li-has-icon .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-icon{min-height:20px;padding-left:40px}.ui-li-has-count .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-count,.ui-li-divider.ui-li-has-count{padding-right:45px}.ui-li-has-arrow .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-arrow{padding-right:40px}.ui-li-has-arrow.ui-li-has-count .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-arrow.ui-li-has-count{padding-right:75px}.ui-li-heading{font-size:16px;font-weight:bold;display:block;margin:.6em 0;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.ui-li-desc{font-size:12px;font-weight:normal;display:block;margin:-.5em 0 .6em;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.ui-li-thumb,.ui-listview .ui-li-icon{position:absolute;left:1px;top:0;max-height:80px;max-width:80px}.ui-listview .ui-li-icon{max-height:16px;max-width:16px;left:10px;top:.9em}.ui-li-thumb,.ui-listview .ui-li-icon,.ui-li-content{float:left;margin-right:10px}.ui-li-aside{float:right;width:50%;text-align:right;margin:.3em 0}@media all and (min-width:480px){.ui-li-aside{width:45%}}.ui-li-divider{cursor:default}.ui-li-has-alt .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-alt{padding-right:53px}.ui-li-has-alt.ui-li-has-count .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-alt.ui-li-has-count{padding-right:88px}.ui-li-has-count .ui-li-count{position:absolute;font-size:11px;font-weight:bold;padding:.2em .5em;top:50%;margin-top:-.9em;right:10px}.ui-li-has-count.ui-li-divider .ui-li-count,.ui-li-has-count .ui-link-inherit .ui-li-count{margin-top:-.95em}.ui-li-has-arrow.ui-li-has-count .ui-li-count{right:40px}.ui-li-has-alt.ui-li-has-count .ui-li-count{right:53px}.ui-li-link-alt{position:absolute;width:40px;height:100%;border-width:0;border-left-width:1px;top:0;right:0;margin:0;padding:0;z-index:2}.ui-li-link-alt .ui-btn{overflow:hidden;position:absolute;right:8px;top:50%;margin:-13px 0 0 0;border-bottom-width:1px;z-index:-1}.ui-li-link-alt .ui-btn-inner{padding:0;height:100%;position:absolute;width:100%;top:0;left:0}.ui-li-link-alt .ui-btn .ui-icon{right:50%;margin-right:-9px}.ui-li-link-alt .ui-btn-icon-notext .ui-btn-inner .ui-icon{position:absolute;top:50%;margin-top:-9px}.ui-listview * .ui-btn-inner > .ui-btn > .ui-btn-inner{border-top:0}.ui-listview-filter{border-width:0;overflow:hidden;margin:-15px -15px 15px -15px}.ui-collapsible-content .ui-listview-filter{margin:-10px -15px 10px -15px;border-bottom:inherit}.ui-listview-filter-inset{margin:-15px -5px;background:transparent}.ui-collapsible-content .ui-listview-filter-inset{margin:-5px;border-bottom-width:0}.ui-listview-filter .ui-input-search{margin:5px;width:auto;display:block}.ui-li.ui-screen-hidden{display:none}@media only screen and (min-device-width:768px) and (max-device-width:1024px){.ui-li .ui-btn-text{overflow:visible}}label.ui-slider{font-size:16px;line-height:1.4;font-weight:normal;margin:0 0 .3em;display:block}input.ui-slider-input,.ui-field-contain input.ui-slider-input{display:inline-block;width:50px;background-image:none;padding:.4em;margin:.5em 0;line-height:1.4;font-size:16px;outline:0}input.ui-slider-input.ui-mini,.ui-field-contain input.ui-slider-input.ui-mini{width:45px;margin:.25em 0;font-size:14px}.ui-field-contain input.ui-slider-input{margin:0}input.ui-slider-input,.ui-field-contain input.ui-slider-input{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;-ms-box-sizing:content-box;box-sizing:content-box}.ui-slider-input::-webkit-outer-spin-button{margin:0}select.ui-slider-switch{display:none}div.ui-slider{position:relative;display:inline-block;overflow:visible;height:15px;padding:0;margin:0 2% 0 20px;top:4px;width:65%}div.ui-slider-mini{height:12px;margin-left:10px;top:2px}div.ui-slider-bg{border:none;height:100%;padding-right:8px}.ui-controlgroup a.ui-slider-handle,a.ui-btn.ui-slider-handle{position:absolute;z-index:1;top:50%;width:28px;height:28px;margin:-15px 0 0 -15px;outline:0}a.ui-btn.ui-slider-handle .ui-btn-inner{padding:0;height:100%}div.ui-slider-mini a.ui-slider-handle{height:14px;width:14px;margin:-8px 0 0 -7px}div.ui-slider-mini a.ui-slider-handle .ui-btn-inner{height:30px;width:30px;padding:0;margin:-9px 0 0 -9px;border-top:none}@media all and (min-width:450px){.ui-field-contain label.ui-slider{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain div.ui-slider{width:43%}.ui-field-contain div.ui-slider-switch{width:5.5em}}div.ui-slider-switch{height:32px;margin-left:0;width:5.8em}a.ui-slider-handle-snapping{-webkit-transition:left 70ms linear;-moz-transition:left 70ms linear}div.ui-slider-switch .ui-slider-handle{margin:1px 0 0 -15px}.ui-slider-inneroffset{margin:0 16px;position:relative;z-index:1}div.ui-slider-switch.ui-slider-mini{width:5em;height:29px}div.ui-slider-switch.ui-slider-mini .ui-slider-inneroffset{margin:0 15px 0 14px}div.ui-slider-switch.ui-slider-mini .ui-slider-handle{width:25px;height:25px;margin:1px 0 0 -13px}div.ui-slider-switch.ui-slider-mini a.ui-slider-handle .ui-btn-inner{height:30px;width:30px;padding:0;margin:0}span.ui-slider-label{position:absolute;text-align:center;width:100%;overflow:hidden;font-size:16px;top:0;line-height:2;min-height:100%;border-width:0;white-space:nowrap}.ui-slider-mini span.ui-slider-label{font-size:14px}span.ui-slider-label-a{z-index:1;left:0;text-indent:-1.5em}span.ui-slider-label-b{z-index:0;right:0;text-indent:1.5em}.ui-slider-inline{width:120px;display:inline-block} \ No newline at end of file diff --git a/web2py/applications/admin/static/plugin_jqmobile/jquery.mobile-1.2.0.min.js b/web2py/applications/admin/static/plugin_jqmobile/jquery.mobile-1.2.0.min.js new file mode 100644 index 0000000..83f0bd3 --- /dev/null +++ b/web2py/applications/admin/static/plugin_jqmobile/jquery.mobile-1.2.0.min.js @@ -0,0 +1,2 @@ +/*! jQuery Mobile vGit Build: SHA1: c2d61e2e592c67519d9a9ed0ba796fa44787e136 <> Date: Tue Sep 25 10:38:12 2012 -0700 jquerymobile.com | jquery.org/license !*/ +(function(a,b,c){typeof define=="function"&&define.amd?define(["jquery"],function(d){return c(d,a,b),d.mobile}):c(a.jQuery,a,b)})(this,document,function(a,b,c,d){(function(a,b,d){var e={};a.mobile=a.extend({},{version:"1.2.0",ns:"",subPageUrlKey:"ui-page",activePageClass:"ui-page-active",activeBtnClass:"ui-btn-active",focusClass:"ui-focus",ajaxEnabled:!0,hashListeningEnabled:!0,linkBindingEnabled:!0,defaultPageTransition:"fade",maxTransitionWidth:!1,minScrollBack:250,touchOverflowEnabled:!1,defaultDialogTransition:"pop",pageLoadErrorMessage:"Error Loading Page",pageLoadErrorMessageTheme:"e",phonegapNavigationEnabled:!1,autoInitializePage:!0,pushStateEnabled:!0,ignoreContentEnabled:!1,orientationChangeEnabled:!0,buttonMarkup:{hoverDelay:200},keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91},silentScroll:function(d){a.type(d)!=="number"&&(d=a.mobile.defaultHomeScroll),a.event.special.scrollstart.enabled=!1,setTimeout(function(){b.scrollTo(0,d),a(c).trigger("silentscroll",{x:0,y:d})},20),setTimeout(function(){a.event.special.scrollstart.enabled=!0},150)},nsNormalizeDict:e,nsNormalize:function(b){if(!b)return;return e[b]||(e[b]=a.camelCase(a.mobile.ns+b))},getInheritedTheme:function(a,b){var c=a[0],d="",e=/ui-(bar|body|overlay)-([a-z])\b/,f,g;while(c){f=c.className||"";if(f&&(g=e.exec(f))&&(d=g[2]))break;c=c.parentNode}return d||b||"a"},closestPageData:function(a){return a.closest(':jqmData(role="page"), :jqmData(role="dialog")').data("page")},enhanceable:function(a){return this.haveParents(a,"enhance")},hijackable:function(a){return this.haveParents(a,"ajax")},haveParents:function(b,c){if(!a.mobile.ignoreContentEnabled)return b;var d=b.length,e=a(),f,g,h;for(var i=0;i").text(a(this).text()).html()},a.fn.jqmEnhanceable=function(){return a.mobile.enhanceable(this)},a.fn.jqmHijackable=function(){return a.mobile.hijackable(this)};var f=a.find,g=/:jqmData\(([^)]*)\)/g;a.find=function(b,c,d,e){return b=b.replace(g,"[data-"+(a.mobile.ns||"")+"$1]"),f.call(this,b,c,d,e)},a.extend(a.find,f),a.find.matches=function(b,c){return a.find(b,null,null,c)},a.find.matchesSelector=function(b,c){return a.find(c,null,null,[b]).length>0}})(a,this),function(a,b){var c=0,d=Array.prototype.slice,e=a.cleanData;a.cleanData=function(b){for(var c=0,d;(d=b[c])!=null;c++)try{a(d).triggerHandler("remove")}catch(f){}e(b)},a.widget=function(b,c,d){var e,f,g,h,i=b.split(".")[0];b=b.split(".")[1],e=i+"-"+b,d||(d=c,c=a.Widget),a.expr[":"][e]=function(b){return!!a.data(b,e)},a[i]=a[i]||{},f=a[i][b],g=a[i][b]=function(a,b){if(!this._createWidget)return new g(a,b);arguments.length&&this._createWidget(a,b)},a.extend(g,f,{version:d.version,_proto:a.extend({},d),_childConstructors:[]}),h=new c,h.options=a.widget.extend({},h.options),a.each(d,function(b,e){a.isFunction(e)&&(d[b]=function(){var a=function(){return c.prototype[b].apply(this,arguments)},d=function(a){return c.prototype[b].apply(this,a)};return function(){var b=this._super,c=this._superApply,f;return this._super=a,this._superApply=d,f=e.apply(this,arguments),this._super=b,this._superApply=c,f}}())}),g.prototype=a.widget.extend(h,{widgetEventPrefix:b},d,{constructor:g,namespace:i,widgetName:b,widgetBaseClass:e,widgetFullName:e}),f?(a.each(f._childConstructors,function(b,c){var d=c.prototype;a.widget(d.namespace+"."+d.widgetName,g,c._proto)}),delete f._childConstructors):c._childConstructors.push(g),a.widget.bridge(b,g)},a.widget.extend=function(c){var e=d.call(arguments,1),f=0,g=e.length,h,i;for(;f",options:{disabled:!1,create:null},_createWidget:function(b,d){d=a(d||this.defaultElement||this)[0],this.element=a(d),this.uuid=c++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=a.widget.extend({},this.options,this._getCreateOptions(),b),this.bindings=a(),this.hoverable=a(),this.focusable=a(),d!==this&&(a.data(d,this.widgetName,this),a.data(d,this.widgetFullName,this),this._on({remove:"destroy"}),this.document=a(d.style?d.ownerDocument:d.document||d),this.window=a(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:a.noop,_getCreateEventData:a.noop,_create:a.noop,_init:a.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(a.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:a.noop,widget:function(){return this.element},option:function(c,d){var e=c,f,g,h;if(arguments.length===0)return a.widget.extend({},this.options);if(typeof c=="string"){e={},f=c.split("."),c=f.shift();if(f.length){g=e[c]=a.widget.extend({},this.options[c]);for(h=0;h"+""+"

"+"
",fakeFixLoader:function(){var b=a("."+a.mobile.activeBtnClass).first();this.element.css({top:a.support.scrollTop&&f.scrollTop()+f.height()/2||b.length&&b.offset().top||100})},checkLoaderPosition:function(){var b=this.element.offset(),c=f.scrollTop(),d=a.mobile.getScreenHeight();if(b.topd)this.element.addClass("ui-loader-fakefix"),this.fakeFixLoader(),f.unbind("scroll",this.checkLoaderPosition).bind("scroll",this.fakeFixLoader)},resetHtml:function(){this.element.html(a(this.defaultHtml).html())},show:function(b,g,h){var i,j,k,l;this.resetHtml(),a.type(b)==="object"?(l=a.extend({},this.options,b),b=l.theme||a.mobile.loadingMessageTheme):(l=this.options,b=b||a.mobile.loadingMessageTheme||l.theme),j=g||a.mobile.loadingMessage||l.text,e.addClass("ui-loading");if(a.mobile.loadingMessage!==!1||l.html)a.mobile.loadingMessageTextVisible!==d?i=a.mobile.loadingMessageTextVisible:i=l.textVisible,this.element.attr("class",c+" ui-corner-all ui-body-"+b+" ui-loader-"+(i||g||b.text?"verbose":"default")+(l.textonly||h?" ui-loader-textonly":"")),l.html?this.element.html(l.html):this.element.find("h1").text(j),this.element.appendTo(a.mobile.pageContainer),this.checkLoaderPosition(),f.bind("scroll",a.proxy(this.checkLoaderPosition,this))},hide:function(){e.removeClass("ui-loading"),a.mobile.loadingMessage&&this.element.removeClass("ui-loader-fakefix"),a(b).unbind("scroll",a.proxy(this.fakeFixLoader,this)),a(b).unbind("scroll",a.proxy(this.checkLoaderPosition,this))}}),f.bind("pagecontainercreate",function(){a.mobile.loaderWidget=a.mobile.loaderWidget||a(a.mobile.loader.prototype.defaultHtml).loader()})}(a,this),function(a,b,c,d){function x(a){while(a&&typeof a.originalEvent!="undefined")a=a.originalEvent;return a}function y(b,c){var e=b.type,f,g,i,k,l,m,n,o,p;b=a.Event(b),b.type=c,f=b.originalEvent,g=a.event.props,e.search(/^(mouse|click)/)>-1&&(g=j);if(f)for(n=g.length,k;n;)k=g[--n],b[k]=f[k];e.search(/mouse(down|up)|click/)>-1&&!b.which&&(b.which=1);if(e.search(/^touch/)!==-1){i=x(f),e=i.touches,l=i.changedTouches,m=e&&e.length?e[0]:l&&l.length?l[0]:d;if(m)for(o=0,p=h.length;oe||Math.abs(c.pageY-n)>e,o&&!d&&H("vmousecancel",b,f),H("vmousemove",b,f),F()}function M(a){if(r)return;C();var b=z(a.target),c;H("vmouseup",a,b);if(!o){var d=H("vclick",a,b);d&&d.isDefaultPrevented()&&(c=x(a).changedTouches[0],p.push({touchID:v,x:c.clientX,y:c.clientY}),q=!0)}H("vmouseout",a,b),o=!1,F()}function N(b){var c=a.data(b,e),d;if(c)for(d in c)if(c[d])return!0;return!1}function O(){}function P(b){var c=b.substr(1);return{setup:function(d,f){N(this)||a.data(this,e,{});var g=a.data(this,e);g[b]=!0,k[b]=(k[b]||0)+1,k[b]===1&&t.bind(c,I),a(this).bind(c,O),s&&(k.touchstart=(k.touchstart||0)+1,k.touchstart===1&&t.bind("touchstart",J).bind("touchend",M).bind("touchmove",L).bind("scroll",K))},teardown:function(d,f){--k[b],k[b]||t.unbind(c,I),s&&(--k.touchstart,k.touchstart||t.unbind("touchstart",J).unbind("touchmove",L).unbind("touchend",M).unbind("scroll",K));var g=a(this),h=a.data(this,e);h&&(h[b]=!1),g.unbind(c,O),N(this)||g.removeData(e)}}}var e="virtualMouseBindings",f="virtualTouchID",g="vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split(" "),h="clientX clientY pageX pageY screenX screenY".split(" "),i=a.event.mouseHooks?a.event.mouseHooks.props:[],j=a.event.props.concat(i),k={},l=0,m=0,n=0,o=!1,p=[],q=!1,r=!1,s="addEventListener"in c,t=a(c),u=1,v=0,w;a.vmouse={moveDistanceThreshold:10,clickDistanceThreshold:10,resetTimerDuration:1500};for(var Q=0;Qa.event.special.swipe.scrollSupressionThreshold&&b.preventDefault()}var e=b.originalEvent.touches?b.originalEvent.touches[0]:b,f={time:(new Date).getTime(),coords:[e.pageX,e.pageY],origin:a(b.target)},g;c.bind(i,j).one(h,function(b){c.unbind(i,j),f&&g&&g.time-f.timea.event.special.swipe.horizontalDistanceThreshold&&Math.abs(f.coords[1]-g.coords[1])g.coords[0]?"swipeleft":"swiperight"),f=g=d})})}},a.each({scrollstop:"scrollstart",taphold:"tap",swipeleft:"swipe",swiperight:"swipe"},function(b,c){a.event.special[b]={setup:function(){a(this).bind(c,a.noop)}}})}(a,this),function(a,c){a.extend(a.support,{orientation:"orientation"in b&&"onorientationchange"in b})}(a),function(a){a.event.special.throttledresize={setup:function(){a(this).bind("resize",c)},teardown:function(){a(this).unbind("resize",c)}};var b=250,c=function(){f=(new Date).getTime(),g=f-d,g>=b?(d=f,a(this).trigger("throttledresize")):(e&&clearTimeout(e),e=setTimeout(c,b-g))},d=0,e,f,g}(a),function(a,b){function o(){var a=g();a!==h&&(h=a,d.trigger(e))}var d=a(b),e="orientationchange",f,g,h,i,j,k={0:!0,180:!0};if(a.support.orientation){var l=b.innerWidth||a(b).width(),m=b.innerHeight||a(b).height(),n=50;i=l>m&&l-m>n,j=k[b.orientation];if(i&&j||!i&&!j)k={"-90":!0,90:!0}}a.event.special.orientationchange=a.extend({},a.event.special.orientationchange,{setup:function(){if(a.support.orientation&&!a.event.special.orientationchange.disabled)return!1;h=g(),d.bind("throttledresize",o)},teardown:function(){if(a.support.orientation&&!a.event.special.orientationchange.disabled)return!1;d.unbind("throttledresize",o)},add:function(a){var b=a.handler;a.handler=function(a){return a.orientation=g(),b.apply(this,arguments)}}}),a.event.special.orientationchange.orientation=g=function(){var d=!0,e=c.documentElement;return a.support.orientation?d=k[b.orientation]:d=e&&e.clientWidth/e.clientHeight<1.1,d?"portrait":"landscape"},a.fn[e]=function(a){return a?this.bind(e,a):this.trigger(e)},a.attrFn&&(a.attrFn[e]=!0)}(a,this),function(a,d){var e=a(b),f=a("html");a.mobile.media=function(){var b={},d=a("
"),e=a("").append(d);return function(a){if(!(a in b)){var g=c.createElement("style"),h="@media "+a+" { #jquery-mediatest { position:absolute; } }";g.type="text/css",g.styleSheet?g.styleSheet.cssText=h:g.appendChild(c.createTextNode(h)),f.prepend(e).prepend(g),b[a]=d.css("position")==="absolute",e.add(g).remove()}return b[a]}}()}(a),function(a,d){function e(a){var b=a.charAt(0).toUpperCase()+a.substr(1),c=(a+" "+h.join(b+" ")+b).split(" ");for(var e in c)if(g[c[e]]!==d)return!0}function m(a,b,d){var e=c.createElement("div"),f=function(a){return a.charAt(0).toUpperCase()+a.substr(1)},g=function(a){return"-"+a.charAt(0).toLowerCase()+a.substr(1)+"-"},i=function(c){var d=g(c)+a+": "+b+";",h=f(c),i=h+f(a);e.setAttribute("style",d),!e.style[i]||(k=!0)},j=d?[d]:h,k;for(var l=0;l",{href:b}).appendTo("head"),g=a("").prependTo(f),h=g[0].href,c[0].href=e||location.pathname,d&&d.remove(),h.indexOf(b)===0}function p(){var a=c.createElement("x"),d=c.documentElement,e=b.getComputedStyle,f;return"pointerEvents"in a.style?(a.style.pointerEvents="auto",a.style.pointerEvents="x",d.appendChild(a),f=e&&e(a,"").pointerEvents==="auto",d.removeChild(a),!!f):!1}function q(){var a=c.createElement("div");return typeof a.getBoundingClientRect!="undefined"}var f=a("").prependTo("html"),g=f[0].style,h=["Webkit","Moz","O"],i="palmGetResource"in b,j=b.opera,k=b.operamini&&{}.toString.call(b.operamini)==="[object OperaMini]",l=b.blackberry&&!e("-webkit-transform");a.extend(a.mobile,{browser:{}}),a.mobile.browser.ie=function(){var a=3,b=c.createElement("div"),d=b.all||[];do b.innerHTML="";while(d[0]);return a>4?a:!a}(),a.extend(a.support,{cssTransitions:"WebKitTransitionEvent"in b||m("transition","height 100ms linear")&&!j,pushState:"pushState"in history&&"replaceState"in history,mediaquery:a.mobile.media("only all"),cssPseudoElement:!!e("content"),touchOverflow:!!e("overflowScrolling"),cssTransform3d:n(),boxShadow:!!e("boxShadow")&&!l,scrollTop:("pageXOffset"in b||"scrollTop"in c.documentElement||"scrollTop"in f[0])&&!i&&!k,dynamicBaseTag:o(),cssPointerEvents:p(),boundingRect:q()}),f.remove();var r=function(){var a=b.navigator.userAgent;return a.indexOf("Nokia")>-1&&(a.indexOf("Symbian/3")>-1||a.indexOf("Series60/5")>-1)&&a.indexOf("AppleWebKit")>-1&&a.match(/(BrowserNG|NokiaBrowser)\/7\.[0-3]/)}();a.mobile.gradeA=function(){return(a.support.mediaquery||a.mobile.browser.ie&&a.mobile.browser.ie>=7)&&(a.support.boundingRect||a.fn.jquery.match(/1\.[0-7+]\.[0-9+]?/)!==null)},a.mobile.ajaxBlacklist=b.blackberry&&!b.WebKitPoint||k||r,r&&a(function(){a("head link[rel='stylesheet']").attr("rel","alternate stylesheet").attr("rel","stylesheet")}),a.support.boxShadow||a("html").addClass("ui-mobile-nosupport-boxshadow")}(a),function(a,b){a.widget("mobile.page",a.mobile.widget,{options:{theme:"c",domCache:!1,keepNativeDefault:":jqmData(role='none'), :jqmData(role='nojs')"},_create:function(){var a=this;if(a._trigger("beforecreate")===!1)return!1;a.element.attr("tabindex","0").addClass("ui-page ui-body-"+a.options.theme).bind("pagebeforehide",function(){a.removeContainerBackground()}).bind("pagebeforeshow",function(){a.setContainerBackground()})},removeContainerBackground:function(){a.mobile.pageContainer.removeClass("ui-overlay-"+a.mobile.getInheritedTheme(this.element.parent()))},setContainerBackground:function(b){this.options.theme&&a.mobile.pageContainer.addClass("ui-overlay-"+(b||this.options.theme))},keepNativeSelector:function(){var b=this.options,c=b.keepNative&&a.trim(b.keepNative);return c&&b.keepNative!==b.keepNativeDefault?[b.keepNative,b.keepNativeDefault].join(", "):b.keepNativeDefault}})}(a),function(a,b,d){function k(a){return a=a||location.href,"#"+a.replace(/^[^#]*#?(.*)$/,"$1")}var e="hashchange",f=c,g,h=a.event.special,i=f.documentMode,j="on"+e in b&&(i===d||i>7);a.fn[e]=function(a){return a?this.bind(e,a):this.trigger(e)},a.fn[e].delay=50,h[e]=a.extend(h[e],{setup:function(){if(j)return!1;a(g.start)},teardown:function(){if(j)return!1;a(g.stop)}}),g=function(){function n(){var c=k(),d=m(h);c!==h?(l(h=c,d),a(b).trigger(e)):d!==h&&(location.href=location.href.replace(/#.*/,"")+d),g=setTimeout(n,a.fn[e].delay)}var c={},g,h=k(),i=function(a){return a},l=i,m=i;return c.start=function(){g||n()},c.stop=function(){g&&clearTimeout(g),g=d},a.browser.msie&&!j&&function(){var b,d;c.start=function(){b||(d=a.fn[e].src,d=d&&d+k(),b=a(' + +
+

web2py plugin

+

for jQuery Mobile

+

Try click on a button on the left, it is a demo!

+

License

+ MIT (same as jQuery Mobile) +

Instructions

+
    +
  • Download +and install the plugin in a web2py app.
  • +
  • Replace extend "layout.html" with extend "plugin_jqmobile/layout.html" in all your views.
  • +
  • Only link pages that extend this layout.
  • +
  • Link external pages with <a rel="external" ...>.
  • +
  • Optional: make a different response.menu for each action.
  • +
+

Created by

+
    +
  • Jason Blum
  • +
  • Timothy Stockman
  • +
  • Harkirat Singh
  • +
  • Massimo Di Pierro
  • +
+
+ + + diff --git a/web2py/applications/admin/views/plugin_jqmobile/index.html b/web2py/applications/admin/views/plugin_jqmobile/index.html new file mode 100644 index 0000000..bdee8f8 --- /dev/null +++ b/web2py/applications/admin/views/plugin_jqmobile/index.html @@ -0,0 +1,34 @@ +{{extend 'plugin_jqmobile/layout.html'}} + +{{block header}} +{{if 'auth' in globals():}} +{{if not auth.user:}} +Login +{{else:}} +Logout +{{pass}} +{{pass}} +{{=T("Home")}} +{{end}} + + +
Search results for tag: {{='tag'}}
+ +
    + {{if True:}} +
  • Pages
  • + {{for child in ('dog','cat','mouse'):}} + {{title = child}} +
  • {{=child}}
  • + {{pass}} + {{pass}} +
+ +
+ {{for tag in ('dog','cat','mouse'):}} + {{=tag}} + {{pass}} +
+ + + diff --git a/web2py/applications/admin/views/plugin_jqmobile/layout.html b/web2py/applications/admin/views/plugin_jqmobile/layout.html new file mode 100644 index 0000000..1f6419c --- /dev/null +++ b/web2py/applications/admin/views/plugin_jqmobile/layout.html @@ -0,0 +1,119 @@ + + + + + + + + + + {{=response.title or request.application}} + + + + + + + + + + + + + + + + + + + + + {{include 'web2py_ajax.html'}} + + + + + + + + + + + + + + + +
+
+

{{=response.title}}

+ {{block header}} + {{if 'auth' in globals():}} + {{if not auth.user:}} + Login + {{else:}} + Logout + {{pass}} + {{pass}} + {{=T("Home")}} + {{end}} +
+
+ {{if response.flash:}}
{{=response.flash}}
{{pass}} + {{if response.menu:}} +
    +
  • {{=T("Main Menu")}}
  • + {{for _ in response.menu:}} +
  • {{=_[0]}}
  • + {{pass}} +
+ {{pass}} + {{include}} +
+
+ {{block footer}} + powered by web2py - @{{=request.now.year}} + {{end}} +
+
+ + + + + + + diff --git a/web2py/applications/admin/views/pythonanywhere/deploy.html b/web2py/applications/admin/views/pythonanywhere/deploy.html new file mode 100644 index 0000000..9261061 --- /dev/null +++ b/web2py/applications/admin/views/pythonanywhere/deploy.html @@ -0,0 +1,176 @@ +{{extend 'layout.html'}} +

pythonanywhere {{=T('Deployment Interface')}}

+ + +
+

{{=T('Login/Register')}}

+
+ +
+ +
+ * + +
+
+ +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+ +
+ * + +
+
+ +
+ +
+ +
+
+ +
+
+ + +

* {{=T('You only need these if you have already registered')}}

+
+ + + + + diff --git a/web2py/applications/admin/views/toolbar/index.html b/web2py/applications/admin/views/toolbar/index.html new file mode 100644 index 0000000..641355c --- /dev/null +++ b/web2py/applications/admin/views/toolbar/index.html @@ -0,0 +1,18 @@ + + + {{response.files.append(URL('static','js/jquery.js'))}} + {{include 'web2py_ajax.html'}} + + +
+ URL: {{=URL(app,'default','index')}} + + +
+ + + + diff --git a/web2py/applications/admin/views/web2py_ajax.html b/web2py/applications/admin/views/web2py_ajax.html new file mode 100644 index 0000000..28ec0e0 --- /dev/null +++ b/web2py/applications/admin/views/web2py_ajax.html @@ -0,0 +1,18 @@ + +{{ +response.files.insert(0,URL('static','js/jquery.js')) +response.files.insert(1,URL('static','css/calendar.css')) +response.files.insert(2,URL('static','js/calendar.js')) +response.files.insert(3,URL('static','js/web2py.js')) +response.include_meta() +response.include_files() +}} diff --git a/web2py/applications/admin/views/wizard/generated.html b/web2py/applications/admin/views/wizard/generated.html new file mode 100644 index 0000000..914012a --- /dev/null +++ b/web2py/applications/admin/views/wizard/generated.html @@ -0,0 +1,15 @@ +{{extend 'layout.html'}} +{{block sectionclass}}generated{{end}} + +
+ {{=button(URL(app,'default','index'), T('Open new app in new window'))}} + {{=button(URL('step1'), T('Back to wizard'))}} + {{=button(URL('default','design',args=app), T('Admin design page'))}} + {{if have_mercurial:}} + {{=button(URL('mercurial','commit',args=app), T('Admin versioning page'))}} + {{pass}} + {{=button(URL(app,'appadmin','index'), T('Database administration'))}} +
+

+ + \ No newline at end of file diff --git a/web2py/applications/admin/views/wizard/step.html b/web2py/applications/admin/views/wizard/step.html new file mode 100644 index 0000000..48abd6d --- /dev/null +++ b/web2py/applications/admin/views/wizard/step.html @@ -0,0 +1,183 @@ +{{extend 'layout.html'}} +{{block sectionclass}}step{{end}} + +

{{=T('New Application Wizard')}}

+
+
+ {{if request.function=='index':}} +

{{=T('Start a new app')}}

+ {{else:}} +
+

{{=T('Basics')}}

+

{{=button(URL('index'), T('restart'))}}

+

App Name: {{=session.app['name']}}

+
+
+

Current settings

+

{{=button(URL('step1')+'/#xwizard_form', T('Edit'))}}

+
    + {{for key,value in session.app['params']:}} +
  • {{=key}}: {{=value}}
  • + {{pass}} +
+
+
+

Tables

+

{{=button(URL('step2')+'/#xwizard_form', T('edit all'))}}

+
    + {{for i,table in enumerate(session.app['tables']):}} +
  • {{=button(URL('step3',args=[i])+'/#xwizard_form', T('Edit'))}} {{=table}}
  • + {{pass}} +
+
+
+

Pages

+

{{=button(URL('step4')+'/#xwizard_form', T('edit all'))}}

+
    + {{for i,page in enumerate(session.app['pages']):}} +
  • {{=button(URL('step5',args=i)+'/#xwizard_form', T('Edit'))}} {{=page}}
  • + {{pass}} +
+
+
+

{{=T('Generate')}}

+

{{=button(URL('step6')+'/#xwizard_form', T('go!'))}}

+
+ {{pass}} +
+
  + + {{if 'step' in request.function:}} +

{{=T('Step')}} {{=step}}

+ {{if request.function!='step1':}} + {{=button(URL('step' + str(int(request.function[-1])-1)) + '/#xwizard_form', T('back'))}} + {{pass}} + {{else:}} +

{{=T('Begin')}}

+ {{pass}} + {{if request.function in ('step1','step2','step3','step4','step5'):}} + {{=button(URL('step6') + '/#xwizard_form', T('skip to generate'))}} + {{pass}} +

+ {{if request.function in ('step1','step6'):}} + {{pass}} + {{if request.function!='step6':}} +
+ {{=form.custom.begin}} + {{ for fieldname in form.table.fields: }} + {{if fieldname is not 'id':}} + + {{=form.custom.widget[fieldname]}} + {{if fieldname=='layout_theme':}} + + + + {{pass}} + {{pass}} + {{pass}} +
+ {{=form.custom.end}} +
+ + {{else:}} +
+ {{=form.custom.begin}} + {{ for fieldname in form.table.fields: }} + {{if fieldname is not 'id':}} +
+ +
+ +
+
+ {{pass}} + {{pass}} +
+ +
+ +
+
+ {{=form.custom.end}} +
+ {{pass}} + +
+

Instructions

+
+
+ {{if request.function=='index':}} +
    +
  • Insert the name of a new app.
  • +
  • If the app exists and was created with the wizard, you will be able to edit it, but any manual editing to the app will be lost.
  • +
+ {{elif request.function=='step1':}} +
    +
  • This Wizard will help you build a new web2py app.
  • +
  • You can create an app with a name that already exists.
  • +
  • If you do not have an email server set email server to "logging".
  • +
  • If you want to use Janrain Engage for login: 1) Sign up for a Janrain Engage account; 2) Register you hostname, domain, and obtain an api key; 3) Set Login Config above to "domain:api_key".
  • +
  • ATTENTION: you can use the wizard to download plugins BUT we cannot guarantee the stability or backward compatibility of plugins. Moreover plugins may conflict with each other. Anyway, we do recommend installing plugin "wiki" which adds CMS-like capabilities to your app.
  • +
+ {{elif request.function=='step2':}} +
    +
  • List the names of table that you need.
  • +
  • If you do not need authentication remove the table "auth_user".
  • +
  • Press enter to create a new input row.
  • +
  • Empty rows are ignored.
  • +
  • Other tables for role based access control will be created automatically, and do not need to be listed.
  • +
  • You will be able to add fields later.
  • +
+ {{elif request.function=='step3':}} +
    +
  • List the fields for this table (do not include an id field, it is automatic), for example "name unique" or "birthday date" or "image upload" or "comments multiple" or "description wiki required"
  • +
  • The first keyword(s) for each entry will be used to generate a name for the table field and its label. You can use spaces an other unicode characters.
  • +
  • Keywords "string" (default), "text", "integer", "boolean", "float", "double", "file", "date", "time", "datetime", "file", "upload" will be used to determine the field type and they will not be made part of the field name. +
  • For a reference field use a field name, followed by the name of the referenced table.
  • +
  • Other special keywords are "required", "notnull" or "notempty", "unique". They map into equivalent validators but (at this time) should only be used with string and text types.
  • +
  • The keywords "html" and "wiki" force a text type and set a representation for the field value as sanitized HTML and MARKMIN resepectively.
  • +
  • string, integer and reference fields can be "multiple", i.e. multiple values will be allowed
  • +
  • For the "auth_user" table do not add attributes to the default fields (username, first_name, last_name, password and email). They are handled automatically.
  • +
  • Some fields will be added automatically upon creation and handled automatically: "created_by", "created_on", "modified_by", "modified_on", "active" (only active fields can be selected).
  • +
  • For every table "table" another table "table_archive" is created and it contains the previous versions of each record. This is only accessible via appadmin or programmatically.
  • +
+ {{elif request.function=='step4':}} +
    +
  • List the names of the pages you want to create.
  • +
  • Some pages are listed automatically because they expose Create/Read/Update/Delete for each tables you have created.
  • +
  • All pages, except "error" and those with name starting in underscore willbe listed in the menu. You will be able to edit the menu later.
  • +
  • You should have page "index", the starting point of your app, and page "error", where web2py will redirect to in case of error.
  • +
+ {{elif request.function=='step5':}} +
    +
  • Use the markmin syntax to add text to your pages.
  • +
+ {{elif request.function=='step6':}} +
    +
  • Almost done. Click on the button above to create your new app.
  • +
  • Once done you will be able to edit it as any normal web2py app.
  • +
+ {{pass}} +
+
+
+
+
+ + \ No newline at end of file diff --git a/web2py/applications/examples/ABOUT b/web2py/applications/examples/ABOUT new file mode 100644 index 0000000..646a97d --- /dev/null +++ b/web2py/applications/examples/ABOUT @@ -0,0 +1,6 @@ +web2py is an open source full-stack framework for agile development +of secure database-driven web-based applications, written and programmable in +Python. + +Created by Massimo Di Pierro + diff --git a/web2py/applications/examples/DISABLED b/web2py/applications/examples/DISABLED new file mode 100644 index 0000000..e69de29 diff --git a/web2py/applications/examples/LICENSE b/web2py/applications/examples/LICENSE new file mode 100644 index 0000000..53e03dc --- /dev/null +++ b/web2py/applications/examples/LICENSE @@ -0,0 +1,137 @@ +## Web2py License + +Web2py is Licensed under the LGPL license version 3 +(http://www.gnu.org/licenses/lgpl.html) + +Copyrighted (c) by Massimo Di Pierro (2007-2011) + +### On Commercial Redistribution + +In accordance with LGPL you may: +- redistribute web2py with your apps (including official web2py binary versions) +- release your applications which use official web2py libraries under any license you wish +But you must: +- make clear in the documentation that your application uses web2py +- release any modification of the web2py libraries under the LGPLv3 license + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL +NECESSARY SERVICING, REPAIR OR CORRECTION. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT +HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, +BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL +DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES +OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER +PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +(Earlier versions of web2py, 1.0.*-1.90.*, were released under the GPL2 license plus a +commercial exception which, for practical purposes, was very similar to the current LPGLv3) + +### Licenses for third party contributed software + +web2py contains third party software under the gluon/contrib/ folder. +Each file/module in contrib is distributed with web2py under its original license. +Here we list some of them. + +#### gluon.contrib.simplejson LICENSE + +Copyright (c) 2006 Bob Ippolito - 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. + +#### gluon.contrib.rss2.py (originally PyRSS2Gen) LICENSE + +This is copyright (c) by Dalke Scientific Software, LLC and released under the +BSD license. See the file LICENSE in the distribution or + for details. + +#### gluon.contrib.markdown (markdown2) LICENSE + +MIT License from from + +#### gluon.contrib.feedparser LICENSE + +Copyright (c) 2002-2005, Mark Pilgrim + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +#### gluon.wsgiserver.py LICENSE (borrowed from cherrypy) + +Copyright (c) 2004, CherryPy Team (team@cherrypy.org) +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 CherryPy Team 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 OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#### gluon.contrib.pam LICENSE + +Copyright (C) 2007-2009 Chris AtLee Licensed under the MIT license + +#### gluon.contrib.shell LICENSE + +Copyright (C) by Google inc. Apache 2.0 Lincense + +#### The javascript licenses are in the code itself + diff --git a/web2py/applications/examples/__init__.py b/web2py/applications/examples/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/web2py/applications/examples/__init__.py @@ -0,0 +1 @@ + diff --git a/web2py/applications/examples/controllers/ajax_examples.py b/web2py/applications/examples/controllers/ajax_examples.py new file mode 100644 index 0000000..d575962 --- /dev/null +++ b/web2py/applications/examples/controllers/ajax_examples.py @@ -0,0 +1,21 @@ +def index(): + return dict() + + +def data(): + if not session.m: + session.m = [] + if request.vars.q: + if len(session.m) == 10: + del(session.m[0]) + session.m.append(request.vars.q) + return TABLE(*[TR(v) for v in sorted(session.m)]).xml() + + +def flash(): + response.flash = 'this text should appear!' + return dict() + + +def fade(): + return dict() diff --git a/web2py/applications/examples/controllers/appadmin.py b/web2py/applications/examples/controllers/appadmin.py new file mode 100644 index 0000000..da050a5 --- /dev/null +++ b/web2py/applications/examples/controllers/appadmin.py @@ -0,0 +1,693 @@ +# -*- coding: utf-8 -*- + +# ########################################################## +# ## make sure administrator is on localhost +# ########################################################### + +import os +import socket +import datetime +import copy +import gluon.contenttype +import gluon.fileutils +from gluon._compat import iteritems + +is_gae = request.env.web2py_runtime_gae or False + +# ## critical --- make a copy of the environment + +global_env = copy.copy(globals()) +global_env['datetime'] = datetime + +http_host = request.env.http_host.split(':')[0] +remote_addr = request.env.remote_addr +try: + hosts = (http_host, socket.gethostname(), + socket.gethostbyname(http_host), + '::1', '127.0.0.1', '::ffff:127.0.0.1') +except: + hosts = (http_host, ) + +if request.is_https: + session.secure() +elif (remote_addr not in hosts) and (remote_addr != "127.0.0.1") and \ + (request.function != 'manage'): + raise HTTP(200, T('appadmin is disabled because insecure channel')) + +if request.function == 'manage': + if not 'auth' in globals() or not request.args: + redirect(URL(request.controller, 'index')) + manager_action = auth.settings.manager_actions.get(request.args(0), None) + if manager_action is None and request.args(0) == 'auth': + manager_action = dict(role=auth.settings.auth_manager_role, + heading=T('Manage Access Control'), + tables=[auth.table_user(), + auth.table_group(), + auth.table_permission()]) + manager_role = manager_action.get('role', None) if manager_action else None + if not (gluon.fileutils.check_credentials(request) or auth.has_membership(manager_role)): + raise HTTP(403, "Not authorized") + menu = False +elif (request.application == 'admin' and not session.authorized) or \ + (request.application != 'admin' and not gluon.fileutils.check_credentials(request)): + redirect(URL('admin', 'default', 'index', + vars=dict(send=URL(args=request.args, vars=request.vars)))) +else: + response.subtitle = T('Database Administration (appadmin)') + menu = True + +ignore_rw = True +response.view = 'appadmin.html' +if menu: + response.menu = [[T('design'), False, URL('admin', 'default', 'design', + args=[request.application])], [T('db'), False, + URL('index')], [T('state'), False, + URL('state')], [T('cache'), False, + URL('ccache')]] + +# ########################################################## +# ## auxiliary functions +# ########################################################### + +if False and request.tickets_db: + from gluon.restricted import TicketStorage + ts = TicketStorage() + ts._get_table(request.tickets_db, ts.tablename, request.application) + +def get_databases(request): + dbs = {} + for (key, value) in global_env.items(): + try: + cond = isinstance(value, GQLDB) + except: + cond = isinstance(value, SQLDB) + if cond: + dbs[key] = value + return dbs + +databases = get_databases(None) + +def eval_in_global_env(text): + exec ('_ret=%s' % text, {}, global_env) + return global_env['_ret'] + + +def get_database(request): + if request.args and request.args[0] in databases: + return eval_in_global_env(request.args[0]) + else: + session.flash = T('invalid request') + redirect(URL('index')) + +def get_table(request): + db = get_database(request) + if len(request.args) > 1 and request.args[1] in db.tables: + return (db, request.args[1]) + else: + session.flash = T('invalid request') + redirect(URL('index')) + + +def get_query(request): + try: + return eval_in_global_env(request.vars.query) + except Exception: + return None + + +def query_by_table_type(tablename, db, request=request): + keyed = hasattr(db[tablename], '_primarykey') + if keyed: + firstkey = db[tablename][db[tablename]._primarykey[0]] + cond = '>0' + if firstkey.type in ['string', 'text']: + cond = '!=""' + qry = '%s.%s.%s%s' % ( + request.args[0], request.args[1], firstkey.name, cond) + else: + qry = '%s.%s.id>0' % tuple(request.args[:2]) + return qry + + +# ########################################################## +# ## list all databases and tables +# ########################################################### +def index(): + return dict(databases=databases) + + +# ########################################################## +# ## insert a new record +# ########################################################### + + +def insert(): + (db, table) = get_table(request) + form = SQLFORM(db[table], ignore_rw=ignore_rw) + if form.accepts(request.vars, session): + response.flash = T('new record inserted') + return dict(form=form, table=db[table]) + + +# ########################################################## +# ## list all records in table and insert new record +# ########################################################### + + +def download(): + import os + db = get_database(request) + return response.download(request, db) + + +def csv(): + import gluon.contenttype + response.headers['Content-Type'] = \ + gluon.contenttype.contenttype('.csv') + db = get_database(request) + query = get_query(request) + if not query: + return None + response.headers['Content-disposition'] = 'attachment; filename=%s_%s.csv'\ + % tuple(request.vars.query.split('.')[:2]) + return str(db(query, ignore_common_filters=True).select()) + + +def import_csv(table, file): + table.import_from_csv_file(file) + + +def select(): + import re + db = get_database(request) + dbname = request.args[0] + try: + is_imap = db._uri.startswith("imap://") + except (KeyError, AttributeError, TypeError): + is_imap = False + regex = re.compile('(?P
\w+)\.(?P\w+)=(?P\d+)') + if len(request.args) > 1 and hasattr(db[request.args[1]], '_primarykey'): + regex = re.compile('(?P
\w+)\.(?P\w+)=(?P.+)') + if request.vars.query: + match = regex.match(request.vars.query) + if match: + request.vars.query = '%s.%s.%s==%s' % (request.args[0], + match.group('table'), match.group('field'), + match.group('value')) + else: + request.vars.query = session.last_query + query = get_query(request) + if request.vars.start: + start = int(request.vars.start) + else: + start = 0 + nrows = 0 + + step = 100 + fields = [] + + if is_imap: + step = 3 + + stop = start + step + + table = None + rows = [] + orderby = request.vars.orderby + if orderby: + orderby = dbname + '.' + orderby + if orderby == session.last_orderby: + if orderby[0] == '~': + orderby = orderby[1:] + else: + orderby = '~' + orderby + session.last_orderby = orderby + session.last_query = request.vars.query + form = FORM(TABLE(TR(T('Query:'), '', INPUT(_style='width:400px', + _name='query', _value=request.vars.query or '', _class="form-control", + requires=IS_NOT_EMPTY( + error_message=T("Cannot be empty")))), TR(T('Update:'), + INPUT(_name='update_check', _type='checkbox', + value=False), INPUT(_style='width:400px', + _name='update_fields', _value=request.vars.update_fields + or '', _class="form-control")), TR(T('Delete:'), INPUT(_name='delete_check', + _class='delete', _type='checkbox', value=False), ''), + TR('', '', INPUT(_type='submit', _value=T('submit'), _class="btn btn-primary"))), + _action=URL(r=request, args=request.args)) + + tb = None + if form.accepts(request.vars, formname=None): + regex = re.compile(request.args[0] + '\.(?P
\w+)\..+') + match = regex.match(form.vars.query.strip()) + if match: + table = match.group('table') + try: + nrows = db(query, ignore_common_filters=True).count() + if form.vars.update_check and form.vars.update_fields: + db(query, ignore_common_filters=True).update( + **eval_in_global_env('dict(%s)' % form.vars.update_fields)) + response.flash = T('%s %%{row} updated', nrows) + elif form.vars.delete_check: + db(query, ignore_common_filters=True).delete() + response.flash = T('%s %%{row} deleted', nrows) + nrows = db(query, ignore_common_filters=True).count() + + if is_imap: + fields = [db[table][name] for name in + ("id", "uid", "created", "to", + "sender", "subject")] + if orderby: + rows = db(query, ignore_common_filters=True).select( + *fields, limitby=(start, stop), + orderby=eval_in_global_env(orderby)) + else: + rows = db(query, ignore_common_filters=True).select( + *fields, limitby=(start, stop)) + except Exception as e: + import traceback + tb = traceback.format_exc() + (rows, nrows) = ([], 0) + response.flash = DIV(T('Invalid Query'), PRE(str(e))) + # begin handle upload csv + csv_table = table or request.vars.table + if csv_table: + formcsv = FORM(str(T('or import from csv file')) + " ", + INPUT(_type='file', _name='csvfile'), + INPUT(_type='hidden', _value=csv_table, _name='table'), + INPUT(_type='submit', _value=T('import'), _class="btn btn-primary")) + else: + formcsv = None + if formcsv and formcsv.process().accepted: + try: + import_csv(db[request.vars.table], + request.vars.csvfile.file) + response.flash = T('data uploaded') + except Exception as e: + response.flash = DIV(T('unable to parse csv file'), PRE(str(e))) + # end handle upload csv + + return dict( + form=form, + table=table, + start=start, + stop=stop, + step=step, + nrows=nrows, + rows=rows, + query=request.vars.query, + formcsv=formcsv, + tb=tb + ) + + +# ########################################################## +# ## edit delete one record +# ########################################################### + + +def update(): + (db, table) = get_table(request) + keyed = hasattr(db[table], '_primarykey') + record = None + db[table]._common_filter = None + if keyed: + key = [f for f in request.vars if f in db[table]._primarykey] + if key: + record = db(db[table][key[0]] == request.vars[key[ + 0]]).select().first() + else: + record = db(db[table].id == request.args( + 2)).select().first() + + if not record: + qry = query_by_table_type(table, db) + session.flash = T('record does not exist') + redirect(URL('select', args=request.args[:1], + vars=dict(query=qry))) + + if keyed: + for k in db[table]._primarykey: + db[table][k].writable = False + + form = SQLFORM( + db[table], record, deletable=True, delete_label=T('Check to delete'), + ignore_rw=ignore_rw and not keyed, + linkto=URL('select', + args=request.args[:1]), upload=URL(r=request, + f='download', args=request.args[:1])) + + if form.accepts(request.vars, session): + session.flash = T('done!') + qry = query_by_table_type(table, db) + redirect(URL('select', args=request.args[:1], + vars=dict(query=qry))) + return dict(form=form, table=db[table]) + + +# ########################################################## +# ## get global variables +# ########################################################### + + +def state(): + return dict() + + +def ccache(): + if is_gae: + form = FORM( + P(TAG.BUTTON(T("Clear CACHE?"), _type="submit", _name="yes", _value="yes"))) + else: + cache.ram.initialize() + cache.disk.initialize() + + form = FORM( + P(TAG.BUTTON( + T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")), + P(TAG.BUTTON( + T("Clear RAM"), _type="submit", _name="ram", _value="ram")), + P(TAG.BUTTON( + T("Clear DISK"), _type="submit", _name="disk", _value="disk")), + ) + + if form.accepts(request.vars, session): + session.flash = "" + if is_gae: + if request.vars.yes: + cache.ram.clear() + session.flash += T("Cache Cleared") + else: + clear_ram = False + clear_disk = False + if request.vars.yes: + clear_ram = clear_disk = True + if request.vars.ram: + clear_ram = True + if request.vars.disk: + clear_disk = True + if clear_ram: + cache.ram.clear() + session.flash += T("Ram Cleared") + if clear_disk: + cache.disk.clear() + session.flash += T("Disk Cleared") + redirect(URL(r=request)) + + try: + from pympler.asizeof import asizeof + except ImportError: + asizeof = False + + import shelve + import os + import copy + import time + import math + from pydal.contrib import portalocker + + ram = { + 'entries': 0, + 'bytes': 0, + 'objects': 0, + 'hits': 0, + 'misses': 0, + 'ratio': 0, + 'oldest': time.time(), + 'keys': [] + } + + disk = copy.copy(ram) + total = copy.copy(ram) + disk['keys'] = [] + total['keys'] = [] + + def GetInHMS(seconds): + hours = math.floor(seconds / 3600) + seconds -= hours * 3600 + minutes = math.floor(seconds / 60) + seconds -= minutes * 60 + seconds = math.floor(seconds) + + return (hours, minutes, seconds) + + if is_gae: + gae_stats = cache.ram.client.get_stats() + try: + gae_stats['ratio'] = ((gae_stats['hits'] * 100) / + (gae_stats['hits'] + gae_stats['misses'])) + except ZeroDivisionError: + gae_stats['ratio'] = T("?") + gae_stats['oldest'] = GetInHMS(time.time() - gae_stats['oldest_item_age']) + total.update(gae_stats) + else: + # get ram stats directly from the cache object + ram_stats = cache.ram.stats[request.application] + ram['hits'] = ram_stats['hit_total'] - ram_stats['misses'] + ram['misses'] = ram_stats['misses'] + try: + ram['ratio'] = ram['hits'] * 100 / ram_stats['hit_total'] + except (KeyError, ZeroDivisionError): + ram['ratio'] = 0 + + for key, value in iteritems(cache.ram.storage): + if asizeof: + ram['bytes'] += asizeof(value[1]) + ram['objects'] += 1 + ram['entries'] += 1 + if value[0] < ram['oldest']: + ram['oldest'] = value[0] + ram['keys'].append((key, GetInHMS(time.time() - value[0]))) + + for key in cache.disk.storage: + value = cache.disk.storage[key] + if key == 'web2py_cache_statistics' and isinstance(value[1], dict): + disk['hits'] = value[1]['hit_total'] - value[1]['misses'] + disk['misses'] = value[1]['misses'] + try: + disk['ratio'] = disk['hits'] * 100 / value[1]['hit_total'] + except (KeyError, ZeroDivisionError): + disk['ratio'] = 0 + else: + if asizeof: + disk['bytes'] += asizeof(value[1]) + disk['objects'] += 1 + disk['entries'] += 1 + if value[0] < disk['oldest']: + disk['oldest'] = value[0] + disk['keys'].append((key, GetInHMS(time.time() - value[0]))) + + ram_keys = list(ram) # ['hits', 'objects', 'ratio', 'entries', 'keys', 'oldest', 'bytes', 'misses'] + ram_keys.remove('ratio') + ram_keys.remove('oldest') + for key in ram_keys: + total[key] = ram[key] + disk[key] + + try: + total['ratio'] = total['hits'] * 100 / (total['hits'] + + total['misses']) + except (KeyError, ZeroDivisionError): + total['ratio'] = 0 + + if disk['oldest'] < ram['oldest']: + total['oldest'] = disk['oldest'] + else: + total['oldest'] = ram['oldest'] + + ram['oldest'] = GetInHMS(time.time() - ram['oldest']) + disk['oldest'] = GetInHMS(time.time() - disk['oldest']) + total['oldest'] = GetInHMS(time.time() - total['oldest']) + + def key_table(keys): + return TABLE( + TR(TD(B(T('Key'))), TD(B(T('Time in Cache (h:m:s)')))), + *[TR(TD(k[0]), TD('%02d:%02d:%02d' % k[1])) for k in keys], + **dict(_class='cache-keys', + _style="border-collapse: separate; border-spacing: .5em;")) + + if not is_gae: + ram['keys'] = key_table(ram['keys']) + disk['keys'] = key_table(disk['keys']) + total['keys'] = key_table(total['keys']) + + return dict(form=form, total=total, + ram=ram, disk=disk, object_stats=asizeof != False) + + +def table_template(table): + from gluon.html import TR, TD, TABLE, TAG + + def FONT(*args, **kwargs): + return TAG.font(*args, **kwargs) + + def types(field): + f_type = field.type + if not isinstance(f_type,str): + return ' ' + elif f_type == 'string': + return field.length + elif f_type == 'id': + return B('pk') + elif f_type.startswith('reference') or \ + f_type.startswith('list:reference'): + return B('fk') + else: + return ' ' + + # This is horribe HTML but the only one graphiz understands + rows = [] + cellpadding = 4 + color = "#000000" + bgcolor = "#FFFFFF" + face = "Helvetica" + face_bold = "Helvetica Bold" + border = 0 + + rows.append(TR(TD(FONT(table, _face=face_bold, _color=bgcolor), + _colspan=3, _cellpadding=cellpadding, + _align="center", _bgcolor=color))) + for row in db[table]: + rows.append(TR(TD(FONT(row.name, _color=color, _face=face_bold), + _align="left", _cellpadding=cellpadding, + _border=border), + TD(FONT(row.type, _color=color, _face=face), + _align="left", _cellpadding=cellpadding, + _border=border), + TD(FONT(types(row), _color=color, _face=face), + _align="center", _cellpadding=cellpadding, + _border=border))) + return "< %s >" % TABLE(*rows, **dict(_bgcolor=bgcolor, _border=1, + _cellborder=0, _cellspacing=0) + ).xml() + +def manage(): + tables = manager_action['tables'] + if isinstance(tables[0], str): + db = manager_action.get('db', auth.db) + db = globals()[db] if isinstance(db, str) else db + tables = [db[table] for table in tables] + if request.args(0) == 'auth': + auth.table_user()._plural = T('Users') + auth.table_group()._plural = T('Roles') + auth.table_membership()._plural = T('Memberships') + auth.table_permission()._plural = T('Permissions') + if request.extension != 'load': + return dict(heading=manager_action.get('heading', + T('Manage %(action)s') % dict(action=request.args(0).replace('_', ' ').title())), + tablenames=[table._tablename for table in tables], + labels=[table._plural.title() for table in tables]) + + table = tables[request.args(1, cast=int)] + formname = '%s_grid' % table._tablename + linked_tables = orderby = None + if request.args(0) == 'auth': + auth.table_group()._id.readable = \ + auth.table_membership()._id.readable = \ + auth.table_permission()._id.readable = False + auth.table_membership().user_id.label = T('User') + auth.table_membership().group_id.label = T('Role') + auth.table_permission().group_id.label = T('Role') + auth.table_permission().name.label = T('Permission') + if table == auth.table_user(): + linked_tables = [auth.settings.table_membership_name] + elif table == auth.table_group(): + orderby = 'role' if not request.args(3) or '.group_id' not in request.args(3) else None + elif table == auth.table_permission(): + orderby = 'group_id' + kwargs = dict(user_signature=True, maxtextlength=1000, + orderby=orderby, linked_tables=linked_tables) + smartgrid_args = manager_action.get('smartgrid_args', {}) + kwargs.update(**smartgrid_args.get('DEFAULT', {})) + kwargs.update(**smartgrid_args.get(table._tablename, {})) + grid = SQLFORM.smartgrid(table, args=request.args[:2], formname=formname, **kwargs) + return grid + +def hooks(): + import functools + import inspect + list_op = ['_%s_%s' %(h,m) for h in ['before', 'after'] for m in ['insert','update','delete']] + tables = [] + with_build_it = False + for db_str in sorted(databases): + db = databases[db_str] + for t in db.tables: + method_hooks = [] + for op in list_op: + functions = [] + for f in getattr(db[t], op): + if hasattr(f, '__call__'): + try: + if isinstance(f, (functools.partial)): + f = f.func + filename = inspect.getsourcefile(f) + details = {'funcname':f.__name__, + 'filename':filename[len(request.folder):] if request.folder in filename else None, + 'lineno': inspect.getsourcelines(f)[1]} + if details['filename']: # Built in functions as delete_uploaded_files are not editable + details['url'] = URL(a='admin',c='default',f='edit', args=[request['application'], details['filename']],vars={'lineno':details['lineno']}) + if details['filename'] or with_build_it: + functions.append(details) + # compiled app and windows build don't support code inspection + except: + pass + if len(functions): + method_hooks.append({'name': op, 'functions':functions}) + if len(method_hooks): + tables.append({'name': "%s.%s" % (db_str, t), 'slug': IS_SLUG()("%s.%s" % (db_str,t))[0], 'method_hooks':method_hooks}) + # Render + ul_main = UL(_class='nav nav-list') + for t in tables: + ul_main.append(A(t['name'], _onclick="collapse('a_%s')" % t['slug'])) + ul_t = UL(_class='nav nav-list', _id="a_%s" % t['slug'], _style='display:none') + for op in t['method_hooks']: + ul_t.append(LI(op['name'])) + ul_t.append(UL([LI(A(f['funcname'], _class="editor_filelink", _href=f['url']if 'url' in f else None, **{'_data-lineno':f['lineno']-1})) for f in op['functions']])) + ul_main.append(ul_t) + return ul_main + + +# ########################################################## +# d3 based model visualizations +# ########################################################### + +def d3_graph_model(): + """ See https://www.facebook.com/web2py/posts/145613995589010 from Bruno Rocha + and also the app_admin bg_graph_model function + + Create a list of table dicts, called "nodes" + """ + + nodes = [] + links = [] + + for database in databases: + db = eval_in_global_env(database) + for tablename in db.tables: + fields = [] + for field in db[tablename]: + f_type = field.type + if not isinstance(f_type, str): + disp = ' ' + elif f_type == 'string': + disp = field.length + elif f_type == 'id': + disp = "PK" + elif f_type.startswith('reference') or \ + f_type.startswith('list:reference'): + disp = "FK" + else: + disp = ' ' + fields.append(dict(name=field.name, type=field.type, disp=disp)) + + if isinstance(f_type, str) and ( + f_type.startswith('reference') or + f_type.startswith('list:reference')): + referenced_table = f_type.split()[1].split('.')[0] + + links.append(dict(source=tablename, target = referenced_table)) + + nodes.append(dict(name=tablename, type="table", fields = fields)) + + # d3 v4 allows individual modules to be specified. The complete d3 library is included below. + response.files.append(URL('admin','static','js/d3.min.js')) + response.files.append(URL('admin','static','js/d3_graph.js')) + return dict(databases=databases, nodes=nodes, links=links) diff --git a/web2py/applications/examples/controllers/cache_examples.py b/web2py/applications/examples/controllers/cache_examples.py new file mode 100644 index 0000000..33c9e44 --- /dev/null +++ b/web2py/applications/examples/controllers/cache_examples.py @@ -0,0 +1,49 @@ +import time + +response.view = 'cache_examples/generic.html' + +def cache_in_ram(): + """cache the output of the lambda function in ram""" + + t = cache.ram('time', lambda: time.ctime(), time_expire=5) + return dict(time=t, link=A('click to reload', _href=URL(r=request))) + + +def cache_on_disk(): + """cache the output of the lambda function on disk""" + + t = cache.disk('time', lambda: time.ctime(), time_expire=5) + return dict(time=t, link=A('click to reload', _href=URL(r=request))) + + +def cache_in_ram_and_disk(): + """cache the output of the lambda function on disk and in ram""" + + t = cache.ram('time', lambda: cache.disk('time', lambda: + time.ctime(), time_expire=5), time_expire=5) + return dict(time=t, link=A('click to reload', _href=URL(r=request))) + + +@cache(request.env.path_info, time_expire=5, cache_model=cache.ram) +def cache_controller_in_ram(): + """cache the output of the controller in ram""" + + t = time.ctime() + return dict(time=t, link=A('click to reload', _href=URL(r=request))) + + +@cache(request.env.path_info, time_expire=5, cache_model=cache.disk) +def cache_controller_on_disk(): + """cache the output of the controller on disk""" + + t = time.ctime() + return dict(time=t, link=A('click to reload', _href=URL(r=request))) + + +@cache(request.env.path_info, time_expire=5, cache_model=cache.ram) +def cache_controller_and_view(): + """cache the output of the controller rendered by the view in ram""" + + t = time.ctime() + d = dict(time=t, link=A('click to reload', _href=URL(r=request))) + return response.render(d) diff --git a/web2py/applications/examples/controllers/default.py b/web2py/applications/examples/controllers/default.py new file mode 100644 index 0000000..129c071 --- /dev/null +++ b/web2py/applications/examples/controllers/default.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- + +from gluon.fileutils import read_file + +response.title = T('web2py Web Framework') +response.keywords = T('web2py, Python, Web Framework') +response.description = T('web2py Web Framework') + +session.forget() +cache_expire = not request.is_local and 300 or 0 + + +# @cache.action(time_expire=300, cache_model=cache.ram, quick='P') +def index(): + return response.render() + + +@cache.action(time_expire=300, cache_model=cache.ram, quick='P') +def what(): + import urllib + try: + images = XML(urllib.urlopen('http://www.web2py.com/poweredby/default/images').read()) + except: + images = [] + return response.render(images=images) + + +# @cache.action(time_expire=300, cache_model=cache.ram, quick='P') +def download(): + return response.render() + + +@cache.action(time_expire=300, cache_model=cache.ram, quick='P') +def who(): + return response.render() + + +@cache.action(time_expire=300, cache_model=cache.ram, quick='P') +def support(): + return response.render() + + +@cache.action(time_expire=300, cache_model=cache.ram, quick='P') +def documentation(): + return response.render() + + +@cache.action(time_expire=300, cache_model=cache.ram, quick='P') +def usergroups(): + return response.render() + + +def contact(): + redirect(URL('default', 'usergroups')) + + +@cache.action(time_expire=300, cache_model=cache.ram, quick='P') +def videos(): + return response.render() + + +def security(): + redirect('http://www.web2py.com/book/default/chapter/01#Security') + + +def api(): + redirect('http://www.web2py.com/book/default/chapter/04#API') + + +@cache.action(time_expire=300, cache_model=cache.ram, quick='P') +def license(): + import os + filename = os.path.join(request.env.gluon_parent, 'LICENSE') + return response.render(dict(license=MARKMIN(read_file(filename)))) + + +def version(): + if request.args(0) == 'raw': + return request.env.web2py_version + from gluon.fileutils import parse_version + (a, b, c, pre_release, build) = parse_version(request.env.web2py_version) + return 'Version %i.%i.%i (%.4i-%.2i-%.2i %.2i:%.2i:%.2i) %s' % \ + (a, b, c, build.year, build.month, build.day, build.hour, build.minute, build.second, pre_release) + + +@cache.action(time_expire=300, cache_model=cache.ram, quick='P') +def examples(): + return response.render() + + +@cache.action(time_expire=300, cache_model=cache.ram, quick='P') +def changelog(): + import os + filename = os.path.join(request.env.gluon_parent, 'CHANGELOG') + return response.render(dict(changelog=MARKMIN(read_file(filename)))) diff --git a/web2py/applications/examples/controllers/form_examples.py b/web2py/applications/examples/controllers/form_examples.py new file mode 100644 index 0000000..944aa08 --- /dev/null +++ b/web2py/applications/examples/controllers/form_examples.py @@ -0,0 +1,22 @@ +def form(): + """ a simple entry form with various types of objects """ + + form = FORM(TABLE( + TR('Your name:', INPUT(_type='text', _name='name', + requires=IS_NOT_EMPTY())), + TR('Your email:', INPUT(_type='text', _name='email', + requires=IS_EMAIL())), + TR('Admin', INPUT(_type='checkbox', _name='admin')), + TR('Sure?', SELECT('yes', 'no', _name='sure', + requires=IS_IN_SET(['yes', 'no']))), + TR('Profile', TEXTAREA(_name='profile', + value='write something here')), + TR('', INPUT(_type='submit', _value='SUBMIT')), + )) + if form.process().accepted: + response.flash = 'form accepted' + elif form.errors: + response.flash = 'form is invalid' + else: + response.flash = 'please fill the form' + return dict(form=form, vars=form.vars) diff --git a/web2py/applications/examples/controllers/global.py b/web2py/applications/examples/controllers/global.py new file mode 100644 index 0000000..72b1ea1 --- /dev/null +++ b/web2py/applications/examples/controllers/global.py @@ -0,0 +1,52 @@ +session.forget() + +def get(args): + if args[0].startswith('__'): + return None + try: + obj = globals(),get(args[0]) + for k in range(1,len(args)): + obj = getattr(obj,args[k]) + return obj + except: + return None + +def vars(): + """the running controller function!""" + title = '.'.join(request.args) + attributes = {} + if not request.args: + (doc,keys,t,c,d,value)=('Global variables',globals(),None,None,[],None) + elif len(request.args) < 3: + obj = get(request.args) + if obj: + doc = getattr(obj,'__doc__','no documentation') + keys = dir(obj) + t = type(obj) + c = getattr(obj,'__class__',None) + d = getattr(obj,'__bases__',None) + + for key in keys: + a = getattr(obj,key,None) + if a and not isinstance(a,DAL): + doc1 = getattr(a, '__doc__', '') + t1 = type(a) + c1 = getattr(a,'__class__',None) + d1 = getattr(a,'__bases__',None) + key = '.'.join(request.args)+'.'+key + attributes[key] = (doc1, t1, c1, d1) + else: + doc = 'Unkown' + keys = [] + t = c = d = None + else: + raise HTTP(400) + return dict( + title=title, + args=request.args, + t=t, + c=c, + d=d, + doc=doc, + attributes=attributes, + ) diff --git a/web2py/applications/examples/controllers/layout_examples.py b/web2py/applications/examples/controllers/layout_examples.py new file mode 100644 index 0000000..b05ac9d --- /dev/null +++ b/web2py/applications/examples/controllers/layout_examples.py @@ -0,0 +1,22 @@ +def civilized(): + response.menu = [['civilized', True, URL('civilized' + )], ['slick', False, URL('slick')], + ['basic', False, URL('basic')]] + response.flash = 'you clicked on civilized' + return dict(message='you clicked on civilized') + + +def slick(): + response.menu = [['civilized', False, URL('civilized' + )], ['slick', True, URL('slick')], + ['basic', False, URL('basic')]] + response.flash = 'you clicked on slick' + return dict(message='you clicked on slick') + + +def basic(): + response.menu = [['civilized', False, URL('civilized' + )], ['slick', False, URL('slick')], + ['basic', True, URL('basic')]] + response.flash = 'you clicked on basic' + return dict(message='you clicked on basic') diff --git a/web2py/applications/examples/controllers/session_examples.py b/web2py/applications/examples/controllers/session_examples.py new file mode 100644 index 0000000..1160b21 --- /dev/null +++ b/web2py/applications/examples/controllers/session_examples.py @@ -0,0 +1,7 @@ +def counter(): + """ every time you reload, it increases the session.counter """ + + if not session.counter: + session.counter = 0 + session.counter += 1 + return dict(counter=session.counter) diff --git a/web2py/applications/examples/controllers/simple_examples.py b/web2py/applications/examples/controllers/simple_examples.py new file mode 100644 index 0000000..5a6d8c7 --- /dev/null +++ b/web2py/applications/examples/controllers/simple_examples.py @@ -0,0 +1,124 @@ +def hello1(): + """ simple page without template """ + + return 'Hello World' + + +def hello2(): + """ simple page without template but with internationalization """ + + return T('Hello World') + + +def hello3(): + """ page rendered by template simple_examples/index3.html or generic.html""" + + return dict(message='Hello World') + + +def hello4(): + """ page rendered by template simple_examples/index3.html or generic.html""" + + response.view = 'simple_examples/hello3.html' + return dict(message=T('Hello World')) + + +def hello5(): + """ generates full page in controller """ + + return HTML(BODY(H1(T('Hello World'), _style='color: red;'))).xml() # .xml to serialize + + +def hello6(): + """ page rendered with a flash""" + + response.flash = 'Hello World in a flash!' + return dict(message=T('Hello World')) + +def redirectme(): + """ redirects to /{{=request.application}}/{{=request.controller}}/hello3 """ + + redirect(URL('hello3')) + + +def raisehttp(): + """ returns an HTTP 400 ERROR page """ + + raise HTTP(400, 'internal error') + + +def servejs(): + """ serves a js document """ + + import gluon.contenttype + response.headers['Content-Type'] = \ + gluon.contenttype.contenttype('.js') + return 'alert("This is a Javascript document, it is not supposed to run!");' + +def makejson(): + return response.json(['foo', {'bar': ('baz', None, 1.0, 2)}]) + + +def makertf(): + import gluon.contrib.pyrtf as q + doc = q.Document() + section = q.Section() + doc.Sections.append(section) + section.append('Section Title') + section.append('web2py is great. ' * 100) + response.headers['Content-Type'] = 'text/rtf' + return q.dumps(doc) + + +def rss_aggregator(): + import datetime + import gluon.contrib.rss2 as rss2 + import gluon.contrib.feedparser as feedparser + d = feedparser.parse('http://rss.slashdot.org/Slashdot/slashdot/to') + + rss = rss2.RSS2(title=d.channel.title, link=d.channel.link, + description=d.channel.description, + lastBuildDate=datetime.datetime.now(), + items=[rss2.RSSItem(title=entry.title, + link=entry.link, description=entry.description, + pubDate=datetime.datetime.now()) for entry in + d.entries]) + response.headers['Content-Type'] = 'application/rss+xml' + return rss.to_xml(encoding='utf-8') + + +def ajaxwiki(): + default = """ +# section + +## subsection + +### sub subsection + +- **bold** text +- ''italic'' +- [[link http://google.com]] + +`` +def index: return 'hello world' +`` + +----------- +Quoted text +----------- + +--------- +0 | 0 | 1 +0 | 2 | 0 +3 | 0 | 0 +--------- +""" + form = FORM(TEXTAREA(_id='text', _name='text', value=default), + INPUT(_type='button', + _value='markmin', + _onclick="ajax('ajaxwiki_onclick',['text'],'html')")) + return dict(form=form, html=DIV(_id='html')) + + +def ajaxwiki_onclick(): + return MARKMIN(request.vars.text).xml() diff --git a/web2py/applications/examples/controllers/soap_examples.py b/web2py/applications/examples/controllers/soap_examples.py new file mode 100644 index 0000000..170fe72 --- /dev/null +++ b/web2py/applications/examples/controllers/soap_examples.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- + +# SOAP webservices (server and client) example and basic test +# (using pysimplesoap contrib included in web2py) +# for more info see: https://code.google.com/p/pysimplesoap/wiki/Web2Py + +from gluon.tools import Service +service = Service(globals()) + +# define the procedures to be exposed: + +@service.soap('AddStrings', returns={'AddResult': str}, args={'a': str, 'b': str}) +@service.soap('AddIntegers', returns={'AddResult': int}, args={'a': int, 'b': int}) +def add(a, b): + "Add two values" + return a+b + +@service.soap('SubIntegers', returns={'SubResult': int}, args={'a': int, 'b': int}) +def sub(a, b): + "Substract two values" + return a-b + +@service.soap('Division', returns={'divisionResult': float}, args={'a': float, 'b': float}) +def division(a, b): + "Divide two values " + return a / b + +@service.soap('DummyCustomElement', returns={'out0': str}, args={'in0': str}, response_element_name='customResponseTag') +def dummy(in0): + return in0 + +# expose the soap methods + +def call(): + return service() + +# sample function to test the SOAP RPC + +def test_soap_sub(): + from gluon.contrib.pysimplesoap.client import SoapClient, SoapFault + # build the url to the WSDL (web service description) + # like "http://localhost:8000/webservices/sample/call/soap?WSDL" + url = URL(f="call/soap", vars={"WSDL": ""}, scheme=True) + # create a SOAP client + client = SoapClient(wsdl=url) + # call the SOAP remote method + try: + ret = client.SubIntegers(a=3, b=2) + result = ret['SubResult'] + except SoapFault as sf: + result = sf + response.view = "soap_examples/generic.html" + return dict(xml_request=client.xml_request, + xml_response=client.xml_response, + result=result) + +def test_custom_response_element_name(): + from gluon.contrib.pysimplesoap.client import SoapClient, SoapFault + # build the url to the WSDL (web service description) + # like "http://localhost:8000/webservices/sample/call/soap?WSDL" + url = URL(f="call/soap", vars={"WSDL": ""}, scheme=True) + # create a SOAP client + client = SoapClient(wsdl=url) + # call the SOAP remote method + try: + ret = client.DummyCustomElement(in0="Hello World!") + result = ret['out0'] + except SoapFault as sf: + result = sf + response.view = "soap_examples/generic.html" + return dict(xml_request=client.xml_request, + xml_response=client.xml_response, + result=result) diff --git a/web2py/applications/examples/controllers/spreadsheet.py b/web2py/applications/examples/controllers/spreadsheet.py new file mode 100644 index 0000000..90868c9 --- /dev/null +++ b/web2py/applications/examples/controllers/spreadsheet.py @@ -0,0 +1,10 @@ +from gluon.contrib.spreadsheet import Sheet + +def callback(): + return cache.ram('sheet1', lambda: None, None).process(request) + + +def index(): + sheet = cache.ram('sheet1', lambda: Sheet(10, 10, URL('callback')), 0) + #sheet.cell('r0c3',value='=r0c0+r0c1+r0c2',readonly=True) + return dict(sheet=sheet) diff --git a/web2py/applications/examples/controllers/template_examples.py b/web2py/applications/examples/controllers/template_examples.py new file mode 100644 index 0000000..94b7c6e --- /dev/null +++ b/web2py/applications/examples/controllers/template_examples.py @@ -0,0 +1,30 @@ +def variables(): + return dict(a=10, b=20) + + +def test_for(): + return dict() + + +def test_if(): + return dict() + + +def test_try(): + return dict() + + +def test_def(): + return dict() + + +def escape(): + return dict(message='

text is scaped

') + + +def xml(): + return dict(message=XML('

text is not escaped

')) + + +def beautify(): + return dict(message=BEAUTIFY(dict(a=1,b=[2,3,dict(hello='world')]))) diff --git a/web2py/applications/examples/cron/crontab b/web2py/applications/examples/cron/crontab new file mode 100644 index 0000000..6ab4ea8 --- /dev/null +++ b/web2py/applications/examples/cron/crontab @@ -0,0 +1 @@ +#crontab \ No newline at end of file diff --git a/web2py/applications/examples/languages/README b/web2py/applications/examples/languages/README new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/web2py/applications/examples/languages/README @@ -0,0 +1 @@ + diff --git a/web2py/applications/examples/models/feeds_reader.py b/web2py/applications/examples/models/feeds_reader.py new file mode 100644 index 0000000..865fa04 --- /dev/null +++ b/web2py/applications/examples/models/feeds_reader.py @@ -0,0 +1,44 @@ +def group_feed_reader(group, mode='div', counter='5'): + """parse group feeds""" + + url = "http://groups.google.com/group/%s/feed/rss_v2_0_topics.xml?num=%s" %\ + (group, counter) + from gluon.contrib import feedparser + g = feedparser.parse(url) + + if mode == 'div': + html = XML(TAG.BLOCKQUOTE(UL(*[LI(A(entry['title'] + ' - ' + + entry['author'][ + entry['author'].rfind('('):], + _href=entry['link'], _target='_blank')) + for entry in g['entries']]), + _class="boxInfo", + _style="padding-bottom:5px;")) + + else: + html = XML(UL(*[LI(A(entry['title'] + ' - ' + + entry['author'][entry['author'].rfind('('):], + _href=entry['link'], _target='_blank')) + for entry in g['entries']])) + + return html + + +def code_feed_reader(project, mode='div'): + """parse code feeds""" + + url = "http://code.google.com/feeds/p/%s/hgchanges/basic" % project + from gluon.contrib import feedparser + g = feedparser.parse(url) + if mode == 'div': + html = XML(DIV(UL(*[LI(A(entry['title'], _href=entry['link'], + _target='_blank')) + for entry in g['entries'][0:5]]), + _class="boxInfo", + _style="padding-bottom:5px;")) + else: + html = XML(UL(*[LI(A(entry['title'], _href=entry['link'], + _target='_blank')) + for entry in g['entries'][0:5]])) + + return html diff --git a/web2py/applications/examples/models/markmin.py b/web2py/applications/examples/models/markmin.py new file mode 100644 index 0000000..11f9f2a --- /dev/null +++ b/web2py/applications/examples/models/markmin.py @@ -0,0 +1,42 @@ +import gluon.template +from gluon.fileutils import open_file + +markmin_dict = dict( + code_python=lambda code: str(CODE(code)), + template=lambda + code: gluon.template.render(code, context=globals()), + sup=lambda + code: '%s' % code, + br=lambda n: '
' * int(n), + groupdates=lambda group: group_feed_reader(group), +) + + +def get_content(b=None, + c=request.controller, + f=request.function, + l='en', + format='markmin'): + """Gets and renders the file in + /private/content////. + """ + + def openfile(): + import os + path = os.path.join( + request.folder, 'private', 'content', l, c, f, b + '.' + format) + return open_file(path, mode='r') + + try: + openedfile = openfile() + except (Exception, IOError): + l = 'en' + openedfile = openfile() + + if format == 'markmin': + html = MARKMIN(str(T(openedfile.read())), markmin_dict) + else: + html = str(T(openedfile.read())) + openedfile.close() + + return html diff --git a/web2py/applications/examples/models/menu.py b/web2py/applications/examples/models/menu.py new file mode 100644 index 0000000..3f331c4 --- /dev/null +++ b/web2py/applications/examples/models/menu.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- + +response.menu = [ + (T('Home'), request.controller == 'default' and request.function == 'index', URL('default', 'index')), + (T('About'), request.controller == 'default' and request.function == 'what', URL('default', 'what')), + (T('Download'), request.controller == 'default' and request.function == 'download', URL('default', 'download')), + (T('Docs & Resources'), request.controller == 'default' and request.function == 'documentation', URL('default', 'documentation')), + (T('Support'), request.controller == 'default' and request.function == 'support', URL('default', 'support')), + (T('Contributors'), request.controller == 'default' and request.function == 'who', URL('default', 'who'))] + +######################################################################### +## Changes the menu active item +######################################################################### + + +def toggle_menuclass(cssclass='pressed', menuid='headermenu'): + """This function changes the menu class to put pressed appearance""" + + positions = dict( + index='', + what='-108px -115px', + download='-211px -115px', + who='-315px -115px', + support='-418px -115px', + documentation='-520px -115px' + ) + + if request.function in positions.keys(): + jscript = """ + + """ % dict(cssclass=cssclass, + menuid=menuid, + function=request.function, + cssposition=positions[request.function] + ) + + return XML(jscript) + else: + return '' diff --git a/web2py/applications/examples/models/session.py b/web2py/applications/examples/models/session.py new file mode 100644 index 0000000..0939ad0 --- /dev/null +++ b/web2py/applications/examples/models/session.py @@ -0,0 +1,3 @@ +from gluon.utils import web2py_uuid +cookie_key = cache.ram('cookie_key',lambda: web2py_uuid(),None) +session.connect(request,response,cookie_key=cookie_key) diff --git a/web2py/applications/examples/private/content/en/default/documentation/community.markmin b/web2py/applications/examples/private/content/en/default/documentation/community.markmin new file mode 100644 index 0000000..810ddc5 --- /dev/null +++ b/web2py/applications/examples/private/content/en/default/documentation/community.markmin @@ -0,0 +1,6 @@ +### Community Documentation + +- [[Roadmap https://trello.com/b/d3aqBbBl/web2py-roadmap]] +- [[Sitio en español http://www.web2py.com.ar popup]] +- [[Documentación en español http://www.web2py.com.ar/examples/default/docs popup]] +- [[Chrome extension to display tickets https://github.com/agarden/web2py-devmode-chrome]] diff --git a/web2py/applications/examples/private/content/en/default/documentation/main.markmin b/web2py/applications/examples/private/content/en/default/documentation/main.markmin new file mode 100644 index 0000000..ec40b84 --- /dev/null +++ b/web2py/applications/examples/private/content/en/default/documentation/main.markmin @@ -0,0 +1,4 @@ +## web2py``TM``:sup Documentation & Resources + +Here is a list of known sources of documentation and other resources for web2py. +You can submit your own source [[here contact]]. diff --git a/web2py/applications/examples/private/content/en/default/documentation/more.markmin b/web2py/applications/examples/private/content/en/default/documentation/more.markmin new file mode 100644 index 0000000..2b4010f --- /dev/null +++ b/web2py/applications/examples/private/content/en/default/documentation/more.markmin @@ -0,0 +1,27 @@ +### More Resources + +#### Social +- [[User Groups http://www.web2py.com/examples/default/usergroups popup]] +- [[Live Chat (IRC) http://webchat.freenode.net/?channels=web2py popup]] +- [[Twitter http://twitter.com/#!/web2py]] +- [[User Voice http://web2py.uservoice.com/ popup]] + +#### Learning and Demos +- [[Intro video http://www.youtube.com/watch?v=BXzqmHx6edY]] and [[code examples https://github.com/mjhea0/web2py]] +- [[Step by step tutorial https://milesm.pythonanywhere.com/wiki]] +- [[web2py Reference Project http://www.web2pyref.com/]] +- [[Killer Web Development Tutorial http://killer-web-development.com/]] +- [[Real Python for the Web http://www.realpython.com]] (web development with web2py and more!) +- [[Videos http://www.web2py.com/examples/default/videos/]] +- [[FAQ http://www.web2py.com/AlterEgo popup]] + +#### Code +- [[web2pyslices (recipes) http://www.web2pyslices.com popup]] +- [[Dashboard welcome app https://github.com/mjbeller/web2py-starter]] +- [[stupid.css theme https://github.com/mdipierro/web2py-welcome-theme-stupid]] +- [[Plugins http://www.web2py.com/plugins popup]] +- [[Appliances http://www.web2py.com/appliances popup]] +- [[web2py utils http://packages.python.org/web2py_utils/ popup]] +- [[Sublime text 3 plugin https://bitbucket.org/kfog/w2p popup]] + +#### [[Sites Powered by web2py http://www.web2py.com/poweredby popup]] diff --git a/web2py/applications/examples/private/content/en/default/documentation/official.markmin b/web2py/applications/examples/private/content/en/default/documentation/official.markmin new file mode 100644 index 0000000..8d6a30a --- /dev/null +++ b/web2py/applications/examples/private/content/en/default/documentation/official.markmin @@ -0,0 +1,10 @@ +### Official Documentation + +- [[**web2py Online Book (english)** http://web2py.com/book popup]] +- [[web2py Online Book (translations in several languages) http://www.web2py.com/books/default/index popup]] +- [[Buy E-book/Printed Version http://stores.lulu.com/web2py popup]] +- [[web2py Application Development Cookbook http://www.packtpub.com/web2py-application-development-recipes-to-master-python-web-framework-cookbook/book?utm_source=web2py.com&utm_medium=link&utm_content=pod&utm_campaign=mdb_009617]] +- [[Quick Examples http://www.web2py.com/examples/default/examples]] +- [[API http://web2py.com/book/default/chapter/04#API popup]] +- [[Sphinx (source code documentation) http://web2py.readthedocs.org/en/latest/ popup]] +- [[Videos https://vimeo.com/album/3016728]] (edited by Nico Zanferrari) diff --git a/web2py/applications/examples/private/content/en/default/index/maincontent.markmin b/web2py/applications/examples/private/content/en/default/index/maincontent.markmin new file mode 100644 index 0000000..dbf9be7 --- /dev/null +++ b/web2py/applications/examples/private/content/en/default/index/maincontent.markmin @@ -0,0 +1,7 @@ +## web2py``TM``:sup Web Framework + +------- +[[Bossie Awards 2011 for Best Open Source Development Software http://bit.ly/o2G0Ik]] +------ + +Free open source full-stack framework for rapid development of fast, scalable, [[secure http://www.web2py.com/book/default/chapter/01#security popup]] and portable database-driven web-based applications. Written and programmable in [[Python http://www.python.org popup]]. [[LGPLv3 License http://www.gnu.org/licenses/lgpl.html]] diff --git a/web2py/applications/examples/private/content/en/default/index/whyweb2py.markmin b/web2py/applications/examples/private/content/en/default/index/whyweb2py.markmin new file mode 100644 index 0000000..79db94c --- /dev/null +++ b/web2py/applications/examples/private/content/en/default/index/whyweb2py.markmin @@ -0,0 +1,89 @@ +## What is web2py? + +- **Created by a community of professionals** and University professors in Computer Science and Software Engineering. +- **Always backward compatible.** We have not broken backward compatibility since version 1.0 in 2007, and we pledge not to break it in the future. +- **Easy to run.** It requires no installation and no configuration. +- **Runs on** Windows, Mac, Unix/Linux, Google App Engine, Amazon EC2, and almost any web hosting via Python 2.5/2.6/2.7, or Java with Jython. +- **Runs with** Apache, Lighttpd, Cherokee and almost any other web server via CGI, FastCGI, WSGI, mod_proxy, and/or mod_python. It can embed third party WSGI apps and middleware. +- **Talks to** SQLite, PostgreSQL, MySQL, MSSQL, FireBird, Oracle, IBM DB2, Informix, Ingres, and Google App Engine. +- **Secure** [[It prevents the most common types of vulnerabilities http://web2py.com/examples/default/security]] including Cross Site Scripting, Injection Flaws, and Malicious File Execution. +- **Enforces good Software Engineering practices** (Model-View-Controller design, Server-side form validation, postbacks) that make the code more readable, scalable, and maintainable. +- **Speaks multiple protocols** HTML/XML, RSS/ATOM, RTF, PDF, JSON, AJAX, XML-RPC, CSV, REST, WIKI, Flash/AMF, and Linked Data (RDF). +- **Includes** a SSL-enabled and streaming-capable web server, a relational database, a web-based integrated development environment and web-based management interface, a Database Abstraction Layer that writes SQL for you in real time, internationalization support, multiple authentication methods, role based access control, an error logging and ticketing system, multiple caching methods for scalability, the jQuery library for AJAX and effects. [[Read more... http://web2py.com/examples/default/what]] + +The best way to understand web2py is to try it; try it online [[here http://www.web2py.com/demo_admin]]. (We have disabled some functions for security.) + +**web2py makes it easier** to develop, read and maintain web applications. + +web2py, like Ruby on Rails, focuses on rapid development and follows a Model-View-Controller design. + +Unlike Rails, web2py is based on Python for speed and scalability. web2py's complete web-based administrative interface eliminates shell commands unless you wish to use them. web2py also includes libraries for more protocols (for example XML-RPC and RSS feeds), and runs on the Google App Engine. + +web2py, like Django, generates forms from database tables and includes an extensive set of validators. web2py is more compact than Django, easier to learn and has no project-level configuration files. + +web2py is less verbose than Java-based frameworks and its syntax is much cleaner than PHP-based frameworks. + +[[Here http://www.web2py.com/examples/static/web2py_vs_others.pdf]] you can compare features of web2py and other popular web frameworks. + +You can download a source code version for any Operating System that runs Python, or get a binary version for OSX and Windows. After that, you do not need to install web2py.Just unzip it, click on it, choose a one-time administrator password and you're done. web2py then opens your browser at the administrative interface. + +You can do everything via the admin interface: +- create a new application +- design an application +- maintain an existing application +- pack and download an application +- upload a packed application, or +- bytecode-compile an application + +Use the admin interface for everyday maintenance tasks. Edit your application files, +clear temp files, browse past tickets/errors, run +tests or work with the database. + +You can also interact with web2py via the Operating System shell or the Python shell. + +For more power, customize your applications to use your preferred web-server (for example Apache) and your preferred database engine (for example PostgreSQL or Oracle). Create your own models, views and controllers. + +web2py application Models describe the data representation, Views describe the data presentation, Controllers describe the business logic and workflow. Cron Jobs regularly run background jobs. web2py Modules are collections of reusable classes and functions and Static Files are images, scripts, stylesheets and the like. + +Controllers consist of functions associated with a URL. web2py calls the function when the user visits the URL. web2py executes an application's models before calling the function, independent of the visited URL. web2py calls views when the function returns data other than a string, and renders the data in the proper format, such as html. + +A web2py application can be as simple as a single file (controllers/default.py) containing: + +`` +def index(): return "Hello World" +`` + +When http://localhost:8000/app/default/index is visited the function is called and it displays the message "Hello World". + +Here is a more complex complete application that lets the visitor upload images into a database: + +### In Model +`` +db=DAL('sqlite://storage.db') +db.define_table('image', + Field('name'), + Field('file','upload')) +``:code_python + +### In Controller + +`` +def index(): + form = SQLFORM(db.image) + if form.process().accepted: + response.flash = 'image uploaded' + return dict(form = form)""",counter=None,_class='boxCode')}} +``:code_python + +### In View + +`` +{{extend 'layout.html'}} +

Image upload form

+{{form}} +``:code_python + + Uploaded images are safely renamed to avoid directory traversal vulnerabilities, stored on the filesystem (or database) and a corresponding entry is inserted in the database, linking the file. + +A built-in mechanism prevents involuntary double form submission. All DB IO is transaction-safe by default. Any exception in the code causes the transaction to rollback. + diff --git a/web2py/applications/examples/private/content/en/default/usergroups/grouplist.markmin b/web2py/applications/examples/private/content/en/default/usergroups/grouplist.markmin new file mode 100644 index 0000000..8beac97 --- /dev/null +++ b/web2py/applications/examples/private/content/en/default/usergroups/grouplist.markmin @@ -0,0 +1,46 @@ +# web2py usergroups + +## International Group (English) + +Main group managed by Massimo Di Pierro + +- [[https://groups.google.com/forum/?fromgroups#!forum/web2py/ https://groups.google.com/forum/?fromgroups#!forum/web2py/ popup]] + +``web2py``:groupdates + +## Brazilian Group + +Portuguese speakers group + +- [[https://groups.google.com/forum/?fromgroups#!forum/web2py-users-brazil https://groups.google.com/forum/?fromgroups#!forum/web2py-users-brazil popup]] + +``web2py-users-brazil``:groupdates + +## French Group + +French speakers group + +- [[https://groups.google.com/forum/?fromgroups#!forum/web2py-fr https://groups.google.com/forum/?fromgroups#!forum/web2py-fr popup]] + +``web2py-fr``:groupdates + +## Italian Group + +- [[https://groups.google.com/forum/?fromgroups#!forum/web2py-it https://groups.google.com/forum/?fromgroups#!forum/web2py-it popup]] + +## Japanese Group + +Japanese speakers group + +- [[https://groups.google.com/forum/?fromgroups#!forum/web2py-japan https://groups.google.com/forum/?fromgroups#!forum/web2py-japan popup]] + +``web2py-japan``:groupdates + +## Spanish Group + +Spanish speakers group + +- [[https://groups.google.com/forum/?fromgroups#!forum/web2py-usuarios https://groups.google.com/forum/?fromgroups#!forum/web2py-usuarios popup]] + +``web2py-usuarios``:groupdates + diff --git a/web2py/applications/examples/private/content/en/default/what/whyweb2py.markmin b/web2py/applications/examples/private/content/en/default/what/whyweb2py.markmin new file mode 100644 index 0000000..358a81c --- /dev/null +++ b/web2py/applications/examples/private/content/en/default/what/whyweb2py.markmin @@ -0,0 +1,73 @@ +## What is web2py? + +- **Created by a community of professionals** and University professors in Computer Science and Software Engineering. +- **Always backward compatible.** We have not broken backward compatibility since version 1.0 in 2007, and we pledge not to break it in the future. +- **Easy to run.** It requires no installation and no configuration. +- **Runs on** Windows, Mac, Unix/Linux, Google App Engine, Amazon EC2, and almost any web hosting via Python 2.7/3.5/3.6/pypy. +- **Runs with** Apache, Nginx, Lighttpd, Cherokee and almost any other web server via CGI, FastCGI, WSGI, mod_proxy, and/or mod_python. It can embed third party WSGI apps and middleware. +- **Talks to** SQLite, PostgreSQL, MySQL, MSSQL, FireBird, Sybase, Oracle, IBM DB2, Informix, Ingres, MongoDB, and Google App Engine. +- **Secure** [[It prevents the most common types of vulnerabilities http://web2py.com/examples/default/security]] including Cross Site Scripting, Injection Flaws, and Malicious File Execution. +- **Enforces good Software Engineering practices** (Model-View-Controller design, Server-side form validation, postbacks) that make the code more readable, scalable, and maintainable. +- **Speaks multiple protocols** HTML/XML, RSS/ATOM, RTF, PDF, JSON, AJAX, XML-RPC, CSV, REST, WIKI, Flash/AMF, and Linked Data (RDF). +- **Includes** an SSL-enabled and streaming-capable web server, a relational database, a web-based integrated development environment and web-based management interface, a Database Abstraction Layer that writes SQL for you in real time, internationalization support, multiple authentication methods, role based access control, an error logging and ticketing system, multiple caching methods for scalability, the jQuery library for AJAX and effects, and a [[scaffolding application http://www.web2py.com/welcome]] to jumpstart development. + +The best way to understand web2py is to try it. You can try it online [[here http://www.web2py.com/demo_admin]] (this online version is identical to the actual web2py although some functions are disabled for security reasons). + +web2py was inspired by Ruby on Rails and, as Rails, it focuses on rapid development and follows a Model View Controller design. web2py differs from Rails because it is based on Python (thus it is faster and more scalable), because it provides a comprehensive web-based administrative interface (thus there is no need to ever type shell commands unless you wish), includes libraries to handle more protocols (for example XML-RPC and RSS feeds), and can run on the Google App Engine. + +web2py was also inspired by Django and, as Django, it has the ability to generate forms from database tables and it includes an extensive set of validators. web2py differs from Django because it is more compact, easier to learn and does not have any project-level configuration files. + +web2py is less verbose than Java-based frameworks and its syntax is much cleaner than PHP-based frameworks. This makes applications simpler to develop, and easier to read +and maintain. + + +[[Here http://www.web2py.com/examples/static/web2py_vs_others.pdf]] is a features comparison of web2py vs other popular web frameworks. + +web2py comes in source code version (for any Operating System that runs Python) and in binary versions for OSX and Windows. web2py does not need to be installed. You unzip it, click on it, and choose a one-time administrator password. It then opens the browser for you and directs you to the administrative interface. Everything it needs to make this happen (the Python interpreter, the web-server, the relational database, etc.) is already packaged with web2py. If you need more power you customize your applications to use your preferred web-server (for example Apache) and your preferred database engine (for example PostgreSQL or Oracle). + +Via the admin interface you can upload a packed application, create a new application, design an application, maintain an existing application, bytecode-compile an application, pack and download an application. Everything can be done via the web-based admin interface, including editing the files that comprise your applications, clearing temp files, browsing past tickets/errors, run tests, interact with the database. If you so choose, it is also possible to interact with web2py via the Operating System shell or the Python shell. + +Any web2py application is comprised of Models (files that contain a description of the data representation), Views (files that contain a description of the data presentation), Controllers (files that contain a description of the business logic and workflow), Cron Jobs (tasks that need to be executed regularly in background), Modules (collections of reusable classes and functions), and Static Files (images, scripts, stylesheets, etc.). + + +Controllers consist of functions that are associated to a URL and are called when the associated URL is visited. Models are executed before the function is called, independently on the visited URL (for each app). Views are called when the function returns data other than a string, and renders the data in the proper format (for example html). + + +A web2py application can be as simple as a single file (controllers/default.py) containing: + +`` +def index(): return "Hello World" +`` + +When http://localhost:8000/app/default/index is visited the function is called and it displays the message "Hello World". + +Here is a more complex complete application that lets the visitor upload images into a database: + +### In Model +`` +db=DAL('sqlite://storage.db') +db.define_table('image', + Field('name', notnull=True), + Field('file','upload')) +``:code_python + +### In Controller + +`` +def index(): + form = SQLFORM(db.image).process() + if form.accepted: + response.flash = 'image uploaded' + return locals() +``:code_python + +### In View + +`` +{{extend 'layout.html'}} +

Image upload form

+{{=form}} +``:code_python + + Uploaded images are safely renamed to avoid directory traversal vulnerabilities, stored on the filesystem (or database) and a corresponding entry is inserted in the database, linking the file. A built-in mechanism prevents involuntary double form submission. All DB IO is transaction safe by default. Any exception in the code causes the transaction to rollback. + diff --git a/web2py/applications/examples/static/403.html b/web2py/applications/examples/static/403.html new file mode 100644 index 0000000..e1a29c1 --- /dev/null +++ b/web2py/applications/examples/static/403.html @@ -0,0 +1 @@ +403 diff --git a/web2py/applications/examples/static/404.html b/web2py/applications/examples/static/404.html new file mode 100644 index 0000000..f1b1cb3 --- /dev/null +++ b/web2py/applications/examples/static/404.html @@ -0,0 +1 @@ +404 diff --git a/web2py/applications/examples/static/500.html b/web2py/applications/examples/static/500.html new file mode 100644 index 0000000..1b79f38 --- /dev/null +++ b/web2py/applications/examples/static/500.html @@ -0,0 +1 @@ +500 diff --git a/web2py/applications/examples/static/503.html b/web2py/applications/examples/static/503.html new file mode 100644 index 0000000..b063a75 --- /dev/null +++ b/web2py/applications/examples/static/503.html @@ -0,0 +1 @@ +

Temporarily down for maintenance

\ No newline at end of file diff --git a/web2py/applications/examples/static/artwork.tar.gz b/web2py/applications/examples/static/artwork.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..f63d82c2c465b95d0116aee6b3722f4295ae0da5 GIT binary patch literal 1883628 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� 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

|J1x0HeW(OV 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

' + else: + tr = '' if rownum == 0 else '' + tout.append(tr + ''.join(['%s' % ( + ' class="num"' + if regex_num.match(f) else '', + f.strip() + ) for f in s.split('|')]) + '' + pp) + rownum += 1 + lineno += 1 + + t_cls = ' class="%s%s"' % (class_prefix, t_cls) \ + if t_cls and t_cls != 'id' else '' + t_id = ' id="%s%s"' % (id_prefix, t_id) if t_id else '' + s = '' + if thead: + s += '' + pp + ''.join([l for l in thead]) + '' + pp + if not tbody: # tbody strings are in tout list + tbody = tout + tout = [] + if tbody: # if tbody list is not empty: + s += '' + pp + ''.join([l for l in tbody]) + '' + pp + if tout: # tfoot is not empty: + s += '' + pp + ''.join([l for l in tout]) + '' + pp + s = '%s%s
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⩔xK8z4EB^N@iT&K(v(+el&xRX1kzr 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
y*RXK`LN=Glxl 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 z�?&grH#u#S_K&gXUfvLnB1?`T zfkA#xT$W90J+E~3z@b9*atX!CAOYSqbm367^e;AT4Gb z0_R$05WWjBWFKGaw`f`6Q#+w*3>g{?OGoHxN)xgEqX3pwK1I;zm-bc#K+x6Pv{v<@ z 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

uMEUJKU=!f9S6-&HpB0-yI+C|2xByH z1tdT7Ret4Fk18d=p@S^4z+iFE3}(0IkZ%+93h8VOb7fQnWf!CTsBay&2QWyE2Xe1J zQGf;yO*bcbOHKA<-Vl(_5@STec3%j$s4cz0C(ALbmjG3E8>oO(`=xF~f1F3%6E){Y z&;(h47l^;`@=mO89-c%rvQ(p6;08n}EvA>CB&SGJ#E3__`&@1K!vcDMV!OvyUwai% z-eZ70NUk3A)~8#E$X85MCt;ZKvr2%G;wM#XUCd9!8FvAJIw@@n$dEa9{fvQq9#VvS ze|&}Rl)>!btkCpiesK#3tmK|pB4vHj1EKaz0$U0ixPnkmrm6Uo%uq@irV~&Uob2$@ zUvtF5(TFu}eB4y(L65fTDN_3knQERIGW{nlt?+#e(A1&qxBEyJ zYC{7k780L|`rCVJw+TLY$|wx|JbrQh*xk&N0}zwoYv!kr=ao`ZS;uV1q<5eM1PF{0 z1&ZNr#E7KiK_-;EaMX@suBQoHSoDbkK|YZRMZeTWmKc6xz$%UJqf>W6Hs>g{-hCn0LeUcIo76!FC+^+F(A9s~@?hJvqz13dHy#cV`6B?uTA zTsgAxYSv5|w~B#(&X_@0flCeOm72OZ92nV0z$I%sw-!!I3YD5qZf>Yb7bqS9_}a9G z0K}ZsA_ZSKL7_$5WJ)T4Kq8m81=ctvtP`|MDh>`Y2b_AvH?wr5G~FYQ*=);{04wJY zMPpzsJA9B-k*F3tUWND`d%m(R5W-X!s>>57fJ#$`B8;RDyASQ>>0t>)bBdFOB9}C zgBUQP5fqV5VmE%n1487g-0G#MO{V%Vua+Oh!xWmx&cb3s%Z2H(n3Kg zW{{l%Ly_;#Zl26U^$An}E3iV<7M1s(ZRcA7#uKQQ9XVuDq|B}6pSeeg*T18HGLfX5 z%dvnTfFTN2VF*NW6sM%-6PQE81c8;P8=?VHn?nIaqdGb9Aqd41i@pnzkr@%n7Q7OT z@t+MG6je`9HBmy{!k1JM%J~7opg;j%3e6~O@5`c2!9|nHVHInrEDy|yp!5rlcUpMO zNf@CwNkPd-FWA(y#}fljI6%}Q>9Y{nm#2OP-aI8c!HPe-AcQhmN#hrnhnWEVQfcW= zrFdBJL=QnZE{_mWRp#Sg$hl0eb_D~=gG>Tv)sM?}R{WHfbxb>r^fB2biqVa76T%P( z2{R}_X5u%`1%OboN(~Uu>lKVr5}{z#`3D-x55Nk2u)G!({3iwB7mm5T#l`JjYbv!^P5LQ1b3DlD3xnfbA5>l><~ z{mK2q*;rao@WBPCp!8jUyckVvpfw0EH+3WgW$guSH{ zWibk-kJ1hRH86S36VXf!ebx2}Xi1rd28Fl3dVbC1U_a1rpTTKWd@f-C?fn)B!j_1V zKl{MZmF9K)3R00|b^e*VcwmWS^%WjKY7&)mcXlj=D6u5FLOOpo@yMeWdb$nF@l8|7 zP}Q03r@TaLm+ec%3^T;x#zFmT7^1K$MoKjx}37x4Vn#&scrs3@kXczH@ zeF??RTqq5Zb0FZ9q!!iA?0sMTxfD&z8K{#+){#&EyJ)R!!np?Hs+2R1)bL;%YQn3JQ9$V)rD{k+UNon19F0$Uk+-b2yqX@p_yfX@nJPz|r6r`k!5G%XX|< zsD3T+Y>Wz|Nc{FDDfh5%0C8vC?3klGuGrCC}#bb4a$-D#}%tWJIsOd z93UJTZJC0B(Y-LQvtX@z;EH0E6 zD7xFuOTb{*Zi+`*aTnjlZX{C%ix92bK%cn6Qv+YaLtCSj{22wS@^ix3KEkgO#qv56 zpF@(i#XsM4lyfY#4OOloj)kM;1dd2}fR&i~aMIC876j;LYWV3dS$RMi@dd|}ibjKv=KiOQLxvsP7^IgUOeS&F1tMlM1K>U~%0F`#_7$nO+O%v>+ zh35W%BC%1ESN6~^@Px_47QD))`h6qxP}^d+sS2`3dy#9FV2oMxVR<1|z0Kefs5s?1 z*?K;;5C;|uq#0=n;PE8MR^o$`ZQNN(L{a#){9SS;vMQ$maxFbOd%~MYBdTsVj|Z6{BSO>%%PXTi%aodN zc}I~tx;)u1fiq$C9dxkuC3L?Y056E8M4O-*cX*rkOoKTiUBYg`M6+7A)cL;l<^)%l zKaUyR=I8LQrr#Z0vS7pJ@&vgaEnR-A)9`S*pFf)Mlw(hR-a){=pmn4~VHU_O9?OHyE@8fc@Dr$NOk+!s+=hudJ&oi*@TAu*PX=C+^l4Q(;ycQ(o0`avNPiXH}8q$wkDd z3aj&@#32=*d&0#@R!dA7UR<}2`AMn^v%JWCP4?b?P#CkKzn4ci&5!e#G3>g=PmXkn zM8Zhir)8v9OU(A?ne5EXk3h@JUz?SskKQFWz4mn_ni}XkKtdH%dA3&{9Qv!dKL<|5 zby_knmE2x^z4gu~W^y9-?P9NjSN{8zk$-NFJc<&k|~}O=7459 zPsd8g;~oR6ay!h*0d3d#^&kBZCAuet(vt*ljgHOr!sQ8`{lL|!kMa5z|AYP66bW6zE&Jn&jQU8KYx^N_U!93 zu*sr2|mq zUQM!yqo~ii6|rt|y#S-vZWCh&r&jePW#p2kMxBvq@2B2SxFf1q{GvM&tOSR--Yiww+sEn|a;fJl zL`?ozdHg0zhfIWO>Bv%w3G)(qJUea!!M+a^ylL)1IzyNI=xM;o0jtL+Jt6u0ntKg> zXIi~6!hYZ{qZ556+j&)_%H#z0=T?Lyoz(j=ozzlaj(KaTztHLkKtsEGkPBDH&Rw}!$m7NYp zO+4f|z(8B?DF@{XoD@)O!3M+!A+MQI~O4~Nn6BYIO@*`0)1-7iD5{S z7PfrWVKiwF<37j2!zfJPnsN*OZ+#tj5tVGIv?Eewx;sAuK>;63dgV}c&g9bj(e&YA zl_DMt2YL5ijhuTGqU7h;z7Vk4kO)^IOta^l4X+J2{CFZkEY@oGlsw2^juG(&7OO5NihCAzEtaz_E-qWQW z59ctow$X)?H%fJKTe?D-9Mg;onFbQm>uQYxFIXk4>Jukb(8rCcC!z7*Z6E7Fu~X(8 zl>k#0Z&>2JE_0kW12$idL!}<2&CJ@YjWpjc**vk)N~^guOOCCJHW=_{8wJhUsyLb#MZ>i%oT}}aH=R}tR>ykU1`4ruiA!zwI?Qwuc}rZP$#bI2ZigUy;WyN zr)$i8_qZ}{inYAsZ}7^0U9{lFzxB+h1Z+n(&cdC0OC7pUGM3cQtz*YK&7H)mexU06 z!;6BYF_$@Kq;2$)Xd}tli)il8!PD29CwAgKUx8h^KMLgN3n1YzKozb3gsQg2m&jQ#z_<(7dWVO=b6nc80)L>?>zlN@S^8aA(uj8WrzQ$3M zknZk~5Rnp48U|FP1Ox=6QA9*Qx?=!ALRz{*KpLcT2Pr&IcHvP_IvHM*Is+od&kVIfqQBa8m&<~y!zNhIIO(D@&|)5OKRdsd z6$0OR^HE74Y;l^uZm!sN-?c7uNwlIbt)7|BM#7UnhS+Jrl$=}M{7mO`g6!j_zx&~* zNx~bv*sW2mmOV3>(G3r=jt4JdOh~8;es#>KRguKZZii&(MXk=JYFC!<`Qq#QgF9~d z$oZ`TD%U<8U$R#dVET8YzZ*DCRS1gw3{*Bw`C;J5{n4S|ty|=T?o$k-yVh#cCehV^}8UC#HOqOWqd17A^oh+$pWf&tv>e?wQoAS2pDnvEUmTl%J~aX49A=MBNQXupgk1h&^HN|vl)F4 z$4QWb(0+kxX;DD4rtp_6URe=w)5|e_vTv_Uts6`}ZY)AsBypfaNUt*9vPlV7=W~O% zpTGplN%%iJtQ%_jyiQ?aBv4x`c~S63t$mTYser_ORenrQ`VIPr)rl`_m7_zaDO;WL zs8`{woaSRs^G-!7x-E<`cSY7_n}u~^z0{`5 zSb9+4$%vD+OV0qBdD;0ZOMaxq=4!LLgiaI3FGrt$dxlV4I#IVe)X#zR(3= z@N?m5jbIBn+`#Cyb%TfzaazkXJ`Tn6XM>pPx1?HkJ3#V%0VimA=Y8mw@Mn_do$@BW zws)PL<&!pcU@vR(OnuT!VtjIPf_~)W*IMq5t;3Nl-(7O>UNz%%fz%u)Xf1`S;g{N_ zICwUDp+ar)DNz`K{&xi>-v=}Jw0hdr<}+7%UPd*65jowt_ht7`Y@EyuWsGvyq>(_E z-4H-Gm_o~zCOK&7J?|#q`yxM;)(y&VcbUOW*wy5^ zM|tejH-1*X6mPxEa6uJap&B$n{=0}H()6@72Y$yh_i0}a1OI7{zZoEhvjyC91qJ@G zU#1FR`rPr8UtetPFNAvwxigN*FFAc_%pNuaZzHmotOZ-xy?XDXzUNkb5^S(IFYkHk z7*hG{u+=R?*vzGj3U*vyj?6|37M`GLpF&`>W{d7AtMFOjcK0D37hRL@3h;=C|7Fd6-O2u^zd}a6 zO_0IRLQ^IEZsJ<8;Xaq>pmJkvHart|FEff}Aw0+_G5cAJWEE3g@}s8?75w@U3|~4b z>elUr_Z-jd&H1g$`#%e&+h|HLHC$EY2$q@@i{CDl-piPP%#7V`KgBeRaK2863>O?! zBM!&0n4c~cR-D!xbKu{VugYCKekqm0$UpXAHjUZc=REYF=;N#MnDml~=w839l4gRc zuWraW=bvpeqacS^w~-ktQ`xRiK01IpQ|QPvPm!QTMWnOQILzLDt~7Pq)zA1VpkRTA z=Af?S(c3>l`yXf>-On9a*jVL_cn9pT9Q}Re@^%R`&9;`4Kd)91_QeJ?WHgwegvqkX z{+Q2dS1N*kce&KjdmB6tE_Y;jx@I&yy(qsRQhwBEeJ|(5la7~bdg~v63*n-5;>P{I zi_e|uPaDKK#E;t#{Kg%`n<39!_M*AiWzM<3>dJ2nE*b05H&ewc{n}6J)02(JOs^PA zkI0Ph5EIYP?*Fk@s^wTr)HuV&G23D_V!uxZdqnf~nZV@7wBMrU!h?k4b*yv;1B7w~ z3xV}zjr1&E=$yaHNJlod+!)3q<=I)=JLK4>cb?kV)5kU;Q+Lm?(f*^py)v%Xh7z>- zBoKX#=gXIw87CmF^=r55+q2!1RP;@vt8IU~bk#9W@F^ixy2+mFI&k67#JWw>K0MoR zT!hDT6%nwx+TT_&Sg;xof&wpveerUh$_Igrw6D-nIegdO0`g%+NW`9Chk(#znqHrc~lXgVucOp0xObDo4r z5@9%0>NewQ85Xj(e|t-P4`l|sLK9p7;K@^d1r**H!NBV}+34uKA(W>R&;U{9bFP{~ zk%ncT{J07g&D#d1?zk+;Yq**_jyYyM(+%baDKBN!C#$r`Udg8RsQchP5HADAK>TO8 zzS$3B6t$y#G5yglK$z?&A?eH%fpDkJ_N&N#aGVfqX7Th!?d{S*m0!*5`%PKc8_&K? znT|8ya~hxuf?%0MTx+`hr2Ui@d`;hQAYp?bm$<==y=J(sjIjqhp=cU^^#Ha}%;b== z`=YpT`czb9|6!1cckSP-5er$F{i%pUjcDm@%J!@<$5J>7`?szpnmG z?xzHW25T2zpz1H-21(iTd8%`w!(mS`d5` zsW{hsjA+#NZd8FbVrRjVJpb}`WpG0u>8~D9-8v}l`fsoN<*|a72mF5592LOw_-_`- zKcfBEymolAdNgt4pa}g-mj&N#(~Q|{)cczy(uke+m*3x1770SsQpw*;l%>FN#NX7E zJH;c$Rhl9XL9;nCj=@fZ?aRN<%lh;szt3{7nJf&SdJ=nIsgL{A()CM7MLz0WwOh_A zt*x{;Xoxq>*I`-|As)nAp20h@*vwMAUtjljyAEpryaG|`aFhP2&|_eUuM zFO;7&z+bt^D?rRP_$gb8jwBU##pTw6pWYt4+)cGR{_C?lt)Rq}^m%}{8@7%uR0V*~ z7aQ^cB5;zT4u>t$Z_Ba_ew6_#Ip|7D4`$E)@IPXiLQDXgs8;FNq`+3%oahrz@^Z3x z88e4dZ}OiR8@Ih=yJDBem-I-_wgc>JQ7FBX+ch!Rr;AX@>x{xLK)*h=Z5~sReL)UF z$lo^Jzsy>F_^b`GzLMbu?_aI6N`#Y-ed!})x0QW6=o?+1x4t}j>pBRU?deuHSygNW z)V9ar;kD+&`s|ISh>Zlr1Eozky)S!bv*%u*;;$l|HO&oyzsV`82rAB47~dUv)PBcX z098P$zjaV;X)iCjGIbskjBol71d^_VtPnSje%_~dYzBX>>=SjEovdqb{j^C-y2%&N z==*dk&mDeZ;|E7E-hM5oCePscq6vFQT3xXnu{4;<{_|0P4;ug4 ztOx1YR?99>LqQb5Cp2ORT+yfXL)9mx^~Unfy#*P`LJDgrTpWkG*EJph_*TWxP zyxiqI+2wgHnJgmHfwFh-_%O930^3Jl9puy`>MS4!96b-E23NlL~#tk(mwZ@C$HJ1?8TTc)k?`{V;BI+zacCd^MzEUO3XKVG7c1 zh7lyT>6SEFufR5u+L@OfhR_hlkpSi1fb+%}RHZLe9(PrI?VqAC78}%v#J6E%4)E z3x=h?Mahd^_8<9dTuF9BP&JmKV*M4K9E$mZ#X}HrNbXUr!*QAfgyPu%lk*4ZE>S4c zp$y-o9B8WI+pdof7wSrKLI6~?lW3abH!wr|1gJ^1-tKfoCRT?7r3G_uFLNYp>jAei zTj!$eK46|iJ{e15ZKblyI-gHnRt4GzoZIbxPoD;EdwhcufUfhOc4OF{O#kTuRJ0>N zPOO(54xD>1!cgkuYGfM;yKWUYEp$u&19kpMBfpqY$F@UMgKSdLij{oFr;_GngQYW} zS&t>e>bF(EvAkkyzy|3e9yrbdZ*r#Kv^=tJ#$=9Uud%9e9gXnHi0?b|mlO z%_RaYD*WvOTK%iE8GHEq3LdF2oHn}?l~GwZmwn;@9cXeow$8#NK>plg&+EMtFmoMR zWm`IL%e|If&v=^LT3}`y=V&&8XS_V45ep zBexXdpk6bV<+ZAb`D`9f`v^QZH#Tpj*RlSw57W~4<+h*7;*u_#rgDGQ1o*lAoDUc^ z$FO{1isA4HLn3p=yHoVtiDn+iX0==V7WL7F|2vbZks05XixR0 zYq;+b{Vi~8Zk3b;c7~pdeFobsS@$mUc(!m8DE!FS+AFMP4NB%YDvdGos160Ry{iIC zua33H=6H>n&F*xrEEbY_IJerRpijzR7RDMU+#t~Kvv1zHuh{~I6u$mm9`i*G%wREO zVuR+!S4(-_GHgvivyZJ+k_%j(O-h5YD04DT*}7t0+N;#L{Bcs&>0A9{WELS#i&}Z* za3kSU-Ux+9$^J+eF^W!v95uUdjMmG&t4a+kU*QPYKIqOU`&=2oApJKv#=7Zmatvwl zTdyU3CujN20EebBm-#9(%w;)QWBldH@#kSkmC?I}nC^D~FrQ$~``;OrsyCPSPp^F4 zOaatYl{65mQ}*vb|F_Hj+X&5a#V?kp8yD!CgW<0|KfVv&$lV=yl{TlkY(r-~rEo9l zyqdpnifmrfPaf4nIjfmk{Tr1NzdV)lO)Ei1PUWmjODqziNV{M$8-g9gV#O~?Du!a^wn()RBCW3@JgXyvYEJEin-@hWmDB%o&eHtF-b&0+s_x63W zQ-AuRbsZAbI8oYuXjaecZcZ3{%m@1Y2UHUE2O8VV4F4_&ae*`ZY;r{LZ~qmy^XC1kDq7LusXH(2A+TY^NK>M$2CeDo>s%Y1`9MQ%gB-G=EEEIAuW@? z!D;Yy!H`IWXmgBPWoJo~TsFtk)Ip)yOU=&&wY07^*<}R+{04B3cjFtqaGI>BJ+Jw* z6coB}|1+6p^Ibm#;DgM)Mc+(eS2?*5m@o01jfi+Zip2XG{-*Fb)%_y!m-cMR_794R zOub&DjqXSw?JLF@(CK~&gD17As`_RHe;y*`vSN2;o{F29iAz2p0ocVyoSaLU1Xx5m z>kK|AP%p|#>LBa2PtY9P&Vhtom2JvA&B_LpcT}|=C1CC~9s$h0FRiw2L)uIfq-3oP z{f><>7n#Put9uNC-lC60jk6VUERuP@0B?JdXW(ba-=})8-3Rt4Z9)d#0EUNk>927N z2_wY&-Ci0`i8#NUVpt#H?66VPO)}18&vh>*V0;w&?Qn(S8{a*q;^L6nrgP5n=z9SJ z9U&k1*`j`pT-D-Gh*fSEP?;YOo_q=@u?8g?eVpD{(+CG#Cx{}}&?#~XR`CIYg<{>q zOyJNT1?p3CMS`wBs1vPQ90k#%Dc#u=D`~&0L=#DH`xFIaNuG?Ac7MXu4VtzT54Psds1*R)VV{>oqI8+q)h$%xH{}a!`Wn?gtuPP=1$k6( z5yh1XDq;@B_X*~j_Dq}mm_Frq`tmG2z+1&(Fs?Fq7uhkOpI7df@sLxU`RmwrLqzvg z;e@jJbwiiXg~k)joeqZw&pny#GBh(rT_H=Q7LmI1Vhc~6^r}lR&ebhno$C_)KoqGt z+=hnGt3#e-!M~RamW?I;{PgbCIJ2>OJ62G1(Wnwd^Z%2r@_*ZGm5 zJPAJ|UMaqbOS~j|hnCUAFDdhA7CH5`?7K83*ZjiKvVZ$D{lpm>>cJY5ju~(u5C~sWtL068@D{tKG*}Ez zO^Hh8KF&BNoArD((Ff*CO@@C`V8)q)zDv-NJpa+TYEMm6WE7&scw<1~fK!A8x1{?0 zo$AHzJ=5ne%-)Pp{^7XSJ|f#@7NV6bMv+!QN>ew}iMwAX9YL6-F15zWNd1IdvQ*Gq zIHFyTDvt&)<#8xi8{5OIU}yLE=@7msdQ$q6tMLbZWA#Um1C(j9?wRAWS-eTb!I0o2 zZg%|qo7fbb@>UCV!r*0O`6|8Wl`>7{J%WYK(YS#izD9i9heE$1G-++P@Rdy|?{%Sc zr>B)xH0`OSOBmpW-c>lSh(Bvk&`ta)B4escG%kn-jntVj#AlBB|R9|XAB66)d{8; zsZ}+e6?{LLFsVR~omiOP&mPl^n7ychLHxwzWzAEm{;@E(!K2(C!+5-_?K)OmqJrAZJJ z&r92x`0AdA%4Tczvtk`bc9UmH3zU?(>eP%lre#OtKL==uzt7i>KjIm+EDzPm|Ne7; zUa&Zpn5mqYls3pFjofmlM(FK)u!OaBj%Ba(vX;!-)cyv`2uz?(SS79w!@YgAvUC-t zq>P<)HF^;>%3$3`5BY7G)q>@@9ycmc_wG((4~mM%20yapzkX6k>dzNMQB-XdCh^qv zJI`)_$+7%jkvvI>Y?VAg!Ssq-iPkZ-4@>h;%!Bc^XWH;?X2jH}IUib3)qTX_;U!9) z#MfOGQ^LMv$ey~gHNH=zOZm3$6A2@`4<%2m3o)Dh{XY7Ar3lf7UwM=YwB2^Q7)=IB zAAj`wq5kI+79jr2FizaK{@j!yjl-8WG(H@lcZe1I-m+_4oQr~#(2od>ngaESenOl}_uvz%st8Dh|c-Y=txGtQpekVT%yh6YJddQXW8Y9hS^Dp_$ms;fhTIGIbB1 zQKuKsg%bKJDYipGcY0TVCNrga^IIYoxlkr_cQ+mw!&sVO2Dallpn=b|FXO?z4#3QqihnFR5)2 z%GfPi-hmH{ONcX`I5KfZ{OJ^mCL1%*>u#SO{6!GV#Y1Jy!K%oR#7d;6?V>&q5qD4S z=MxRPY1&nRTu0;A_jsA!+$*9bB-d27dB&%wOi8Px_VOM<5c0P&F@#qym6EnlZ#MDe z&p%j7i)Zv(UncyYD(gHFlxD#5*5u4fBp9uav~GQTJvs1zn>Fu+I=^d3aS~CWU6O4v z&m968!awwRKhR!ms_3hbvSPQsB4PUTO2UGWHGWOC4%p7vG$7$57ryLG`^Tl1!F0e6l zxeoZ|^c58{Of*lP(DsA**5HW3pK>jlq#@e-KQ#8d3f*Lk^-cw;g1MtYhjMi0Z5}%R zpr_TOR%#p~WIIU1j zac5EdZ8A-4KB@<2w=Z}0?B(w%*E8nMSZCuh_WY!sFVIYRulRcFjrhXcpTn{}`pDZC z>0P_?Wgks{=tom15os3ai~X7u_@dv5GyLeg5{Cm(KqftHv;IRoQPPqzs0fvwRU405 zM-1xG3=O00GvczJ!RcJmS=iE4{b9T;Z>=60U{idfIhf22-w+s+4#|HSM{uu*i|B>S zS?LS&Qy^WsPLO4MW^_nu_$m!`y7j)Xo@(Y8)q&sxxO6-x8)-bw*b{tZ^qZ|er0T{R zYn`OYJSEh!{Cpdiv_X2#-VgN;3%rY7!QYrV=c!3npI}+P!OIZl56%pq!QFp1C{q_U zJoG_EYTCIOZ(AmaI?pF;^6bz4lna*@cqW=L`Q0a-k$Ar1PyI5&4R7_%a;R}RAjwtt z?v?zGyMINM$$E%Y=`5_}^m5)n&(PA-+6VojzeFlcl9DPuRp(LG`)PqRDK%+1lN;|( zCC`WSsw4iuH-4uk+8`c)#>QtwNcV#s5`}Gj>bM8IRh`LP9qv^t@8Y;Wck3WL*Su+bu zvC`qc{QRl5*my4T!ik982R}xXW z#E+YVjV|hOM_VOpo?lqB-G~tSB>%PdEuXN1(-i_x)VYbAfhr{Q{I6w=hDrHL6NfZq zd_Qv0>QD;}x<4K^y?FZ8I^8doQ2Em!`Nf-2gY7Mr3N^$_nsq{um}Tycf5~hi_82-W79_y~iKR6-?dv)ax1?G;3bH zvqaS+rghTC#+ouqMt`Kbhx2O%e|{s@jn|x7=Zd7Gefd?wnr`iWlf)bPxvpP)@tkfQ z!4@QHN_8SMY{Wj14^3Y`;fPy^Q^`x$InjxKvB(w4u=c^W9#3xTceP@Yw~s<~I2V4e z`&Ap(lSG+^4z0T~k<5uZcta1csPg^QC5qFGsY1yjiyCujGYpNSOpMdW&AvbU!l_i3 zAo}x{hOsR+b$Z|YL#Nm2@*Y&3=?#RPmTKArv^rag!I=Oz7xf1?Y(9WU)NY2MI4W2qaK;B<4RN zdH&)#$?+5xKbM?w>xCpQ;YD6_%(#`HJ2(8lu;HA{tyuAlPIDx4y*6ab|f)=mr+R67#(p>Gb^|*^s}&f+^?txN>z=> zei5>_aX(8nE!Vzez0=i|3*;4=D=p>wME*ovEGws0G-ceh-KP73$?=(@`yrdTR+Sem zq46xdTXZX#7;h@!y@Jxy2Wh3xc-^p!A5P-=dxXCJG$fJo+rUJdrfrX!yS4ivtC+S<3AYqCwfSfMMi)@kb?PyFU_x!vn(nteNH>>(I5= z%-lXy6R=W$Ttn{2pzT?{w8zU!NbD%UGTnCk{2Oachz))7tB&=Dl`Oc!4{2fVH@D-= zICs=>WEt9S&Vl1{7y~PH0dt=4Yj;TPrIK_t4m@SLI&)RpCOaXhOMVCO27r!MOG7FLxMHj-tYVtq-$fM40JIpO^@``$xSWc|xwa4w{ zwipy+Fw{@kIPlC+)<2MQr!U>j;qa4nQHE}7bLF?}yk;+<$>)xBVl!D2%YhX|>55OI zsb#VVI4Y*&ut9}C2Uaz3VAaYcGN0tqkH$U)5Oh78$M2dCFbei^s}BCukzq&cR&V(g zPC8-aGkAB@)LS*0U2YF7&8nLi)C6+!KkDGO74@tX@O?xXIR4=cfo~+SlX_|8uzh`f zpS-;$QaPCHM@yIw#`%|vzE$fa3^N0}wR zlT!KJ@aM%e4;&inFqc7{KN7XUWj}~@l2Y#z1`lh1nPRybngbf^LpT>dI;rns_oaHKU8L9CWVtdk4W>ieHo$P**9z&q=Rg|fFZ!{Otu~DEeZD>78+t%`a#kt@7>_-dzJ+4(*2L5mgsj+ z>#{`2>mo!gk=RFOuT&Zj{zp>F^*f3f1$U6jS9E`InA=WV={AGkPqT=VDVv$OLWKD^ zwGEn|0zjC~;cjRPl$>$89=2|JBz{pwyh4t|SPaJ?;9iX=(5%N2=3wXx0vLS<*ts^M zRxR!Wv2HM63E5r4Rv3Wo%wS$S48B)=jltge#cY5tkVcG!h1KC;_e{?#(@blaJoqu? z;V9&U2J365&QRIAGW^f?96#B2>;HK0u@>`XxaX^D+Th68#}8S|g3Jo}+H6kI?3dzZ z%0;4t@Ha$-6R|j-&kPDSuf!I=*3}8M2j&udb=oB>a`$dLEyPxFN_70df^ToharHr@ z!CGO^gIIc=8f^AsZfrn_nf5o5X{97pV)UZ%WO-pBTP2C6=j$6^7SStJB7{za{U236 znMm7-uQAzWtG%&KGw&GrUZlw|{=~CrVYeuHUbC!>g@xmBr^%b!u^}{80Bg_x*?-#e z_vMv&G%s)WMu`@G4V$E*j`~H-1>byla5PZqbv0#8-5VAGJ0)ML!#{mveck0n5uC=? zLAjLC4+C;v=;$Pt+oZNO@rW+idw5C=x~}mjFJ-2sxO(n1=&3vWWjT(g zD2Ctu*jR7fs)^nsRtXT*XK#3=G6gDKVd#;hS`8a68S(R+IgVZ*JXfGO4nx_VmacGr zg;&QzZu%!D^;-?`GZ0@-_%kUorq1+RZ45*p+vZQlLfJ~-r7N;1@2sI_;T$MO*ycME zWA7Pr0s--vYx*yt&q=t=bY{#chJERc*Im7s#zM?U3J%LYS49_!gE4!K-80o9_QryL z^xqu0>$-J-S2V51AfX5Amh)$z6a3fpbM5ilh{dBf$M%5kDJT9z&GwZQe4To@Wx)XS zQVv2>vXupPoLYY=#pEH(FdbKV)lse@eIU0aeK00DFS4%l2(ua1bH)CfNqJ_qtX?o@ zLPok#H|+pYGII6ZNj#I>*N3d&+01H>^XyH`sygrH;ErcDEYnq?R#Orz@{QZp3I1D0 z|45$w%6=?GJacz49qw0oDv;#r72pZc*cJ@9pQ*mh-cTRg&fcGHvWa#Z6u%Moqp;8$ zggxJM@XA*2^VF60G*jc9s$G8}6?cpH)>2fq@&)(58zR#u3|_xVn^LTwe8a-RPWx8` z0y_Rp5x4{pe({dBZ++?^B~>UMQBuM)!OkWbCuKfmR4;-9($p5le1|**_)QKc$1D zqYfPZ7tnCjY|GIBlc`m3O!gY%@%~gkcY|y^^-KPaYha%n^-~bRr&k%H+S9Gr%ya(# zlt}5dr)QFlKrOpb$LSVq<|T)JN}Yd7gJ~b~@#`H7S*kMn>I%FkxZg%HdF^3!D!f(| zm|8^i-?buV51^;{74zH^HT63uG5yO)oiqO?CyjRzbw0+ztvLj_wJ7e+_3bK>EK6^$ z_}s z<^SqF;?irJl%AHBh7o+Xn5ML|KrKFqe1$esFJd&R-rIuSoCy%z0HUBLSxg^03a``4 zo#{~{c10q+0z2Mg#tQFc(ps77^iBt0XhK&JBk|XnqLHXXr5C5K1l1?(i?2QX%W)2f z=wtJx)lM^=R~VX3A)2T5cR(TxD0CjSSD|R}x&!lkL=mqAM-shlCR3_tc!zkfBi@S; zsca2CL%|BXa=P8M*ZMHL-L)KI(P!VPp$uY|zmqoL3WqnL8ttsycQ>tex%+MKP%ZOW zahec$(D>l@%!tlxi|eiJ2k)*-I7M7$abc+SA4z5-pYU3+CDCB&Y=40d+cfXMVB$Ud zk7(*EWO~6T)F$J8w=c-rX$&mkb>;9?9oqrLdSnw~K?>=7#GGd&b}RNeUss9L=!-nQInFipb%^ z6#txe!9abSQ;}Lw#s=(X5K#FqY|-(Z8l6Pc2^vAGedO)}$zWfn*kF_=iT*(%j~q2+ zx*C@9*_26PXdbh-@WbImWJK?-a(W2ipbX!2bf_E}-X5D49@H4CO# z)bJr7d;cD0$m`JJBha<qS;_t?I zPWD%3_M6yLjsJvFz^KcQ|A_tPPSIGrzu4^S*wkS>nVVyaW8v!!BJ0ZUe#a1v=*?D) zaO^`n%@0>VO9P$F>tl|Q!mp8|0Yu2Kun{!w8^IF}dNIUyZ6EU^`fG~s;mzv3xR`en z&wKxxrAKM(dVmS?;1T;ZMOe5kx7iwi^}`hh&)uE$!xhHTAVK(q1E0z@<01%ic1hbOx3VD0A{+a=O<~x!0Q>5$IF*@ae+{_7BvK4`O*lO3UM~3mcYdz;5i97)} zo?BPFdS?&L7m_U)g5YjcK{P+-i$3g$K{j}PfOl6jmXdJzJ| z+>Lq0nk$Y(|6uKPGG<*1d3t=Tc!sDtM`F`$S@r?o*0%|AM|eo2e0uc1bmDp zu(?E9!$Ia(9}`M|cPfB{TCEMh79JSTrbWV!C3^{sCaPfL&_)3o93#(welKvlWYfw{ zE^}pi{k>w#5dwXmbM(a<)&J|?98bu%? z4OZLLuh(NCH~={x85_83KI0(3)cSID|3$6BbD|YYl^vJp#dDg()|+#*W0BP%rj(3X^+Lox}zs1$J(<$ zr&I>n%X-%XxUi<0eMfVx0{DkJEBeaJoeF#yMG6!R!}QWaoxg!ndobJo1-$xxF7=lW z$K^k=x?aN>(eJN4>t}#r#F)x&psGXkGN$8%p$Am94kH1IB3qf!|JPN2BQSbbstK2G zJ%CHmJO?$HufXI>M)dV&EGEw)W2&0HhXaT_1zgyQ9>3(r=j{ATegibt4%JCYfnfa|^D zJ?{K4%g5AmzwR>(Dt-JC?{#WPuH%eNr{rcj&idj-@7IT4lwK%7pKm4v#)PMT;)+Rs z_{*95%fnBg3rx@Bkq;e(Wn~8k0c-ML3w;Z?o1vj0F5d4ywj+CaOp6NRU*)IUwOE3^ zDmm;u(mifDx&0Zso#of9iW@W0!>T#>rTqC>&&Ud<$SzN4k6A-;AM}`+@OOv05-C068!Ew0V4w zZ?`}9k3|^Kmi(1#EXHO)1Zubelb+bKD0a-{_)3krK566Y&$NgD+3@+HO_nf=L-AJY zU>}#!n{9SX{fP}~u|r!)`mAXxV;t^JJVaG_;|hU8nK9y7=%5aWp3ax$oeSX$RCc7x zSNGUvDAFYwLtG4b?Gn)32P9D+6MdI|6nm<#Z|d5*mNSv$W4+vu;Uau zFCq<++XNBwLQ`Ckuop}S>3$%^S>-8M8a@1aAL$Z4L77U0{=7(JbTSTU++S&W@R zg8pd&Dh}S|+x46Fk%Y5t5 z^81Gxy_Xt??Uo#CzRC2i0W3BPrxC$yvqpy(()PVM2W_A=xS+T<<0(SdIPClZ%+qM- z=F}uBy@$RM&nm~v2L<(i zllV#lDq+b&mL?;v_GPA67>{C)R~frx#n8|562V@+#%0SCzK&ki6oYTcmb@M~Q9AF> zm%l$cdRYmT%GR#5wJ4V{_#V|+6<@K9^pLDRMXFvIePB6Ufo+%u*x|C=00P~EChOPf zBboukyt6l1E8}B^T=TZko0e6@Q;(sZZqH5nx$o)%mQ}I7+ZUfmOk%@8V9qp>y1wt# zlJIk1v$@Gt{&&6=UFp&q@YZkc0U9QYzO~iu$!po+9n&$kH2S#p*3)~A14np5UAGT4 zta3K4A=4Abs9+D1^@qj&)k)`@sn+bEy%wNEg5%uVb+`HQ^CgFJwTulA9T ziurJE*PdL9QpzxV3MzhAH5TjXJ9qC27hw{zO7N2$_TnU?u?_~slsw1jXkuIUH7+K1 z4Vb;_cztR7$t!^MmTh=CEwEkT*tFPz>ICmxwcMLrnxTjsj+}J~IF#>r*3A^dM>WgA z-=lCm35DeK&L1W?^##@wEu(6-D>>r+5W70nW+A_g z-sk(eycY_F#;o7VH8WPG)FNA{`T+bc^xe?rpZe16LTle|2)7Gpi7p-bX<-MB$xeM# zgw85b%7U{u&VqgEh_H~i+=VX(>Kz0{@ew?kHCXqrR7<*CX(D78_O7*6rL3@1xo_B4 zT(C>1#2V=|OyO0@PA|zGxt$xThm1M&Q@RF-Bbxe)?943HPwa=^kHPS;EvBu#UM^ml zzfccRScMsQL2Q_cAZ`)gXX*F z4@(`VC7tO+cJ2WqHx5ZoFQ2zes}=|MHnKDuGSQtVvn;O0t74b53MFj#9B>oa)P;Ed zTs+Lu?R=lbu?dU~5jUQ^iupi%f?ASrO)2u?z?c%*xaE$r**c`2AEfuh2%%?jsmFE+ zeR-aY;(hK}rLTds?U$+*LwPeN;w9vD>*5a`xOro0D&@0yK233}u?(&nP&3co2&Fi^ z#7e(Xo!Vj@xN7+E8V@w4o>b(&`Lvm&p--Wgb=#eKj8OFldrA7+k(-(^7%jF%$WOJ{ z4?^!R8pwrWNUx=5H_}|x| z0d~@WK43&3fM<13s zC-29+QDS^KL4Sx9ZHY^`971PFMAC^v(iv?@5yHFv@iph`x2bfB6tA0##EVqhKs!N8WP$cvh1kAZTdz5kQUCg&L3-wfJ0*KwYvcZXf?e+7|L@4qRC(jy!W9#i6( zsWPkG=jVz38AqG&Qa2nRacw1Muewn4;X0jw)GcnKX81W*Jw%`|QCFS+Z-JVF!{O+I z13UFl$k*TODX$RJdlq{7IV)czx6jXAF}Jt3t^vdD#q9dCLi!y*Z*S>&tAmTGiVF+^ zfe=x5FZTfyU~CcKHB6dP1{f$Z9%bRKaiYwDi2yf+i@0Qt+!S<&TWqA;Xe1e$&DCV5jVc?l zpIO-toeP>2<-Ex>Vo_~<({VQ(c|*nx=IH3?BqrS7s|eozirZf)gR^aNBlAiHnQg!} zEZLS4Zw~iY_+dMl-SS%q%6h$v&avIW9LoA_f- z4W{x$or7cc#-5y$-Fgef2a}JSy#|DiraJCHZ@vT`)x5hpILx?c_mgCdrn^x{M*;fd zF7%Umhh@uP)Uo*$$XJn6hpYN*EuhHmrdmw>0{r8-&g@sDkMF>#+|-AWJ&C;!Xp0 z6kq8F)trr);chQeiL+g}Md81`Q<#Tl9xuowUF;f1TEv>z9W zb^1jM z=gbR@7#gL_2~<2r#acnd9}VcmFafX7aUL6)?MyM(;+Vm=Gy$L6Z!=STajt#d6kjMc zYMX=4hN>qNXyCN~*DUYYA-~Fo6Cgx|Kj(FkoQUYGXn>Lski*p__AC{11LQh?c!^lS)QaVlS)swrY_b;t3GPCdr~Lk3LE*!44f@xjtu~Ae zTPPXmyFRCl_t3hhzFF7e@Q1NUUx9X~_Z|2ghO!q1Fa=^c=fVR4CbRthDv+_3_puXi zm6u;tLFZ5lh^};}?&STXchg^+e!!vak{M3lXR%ih`YOeDC`TM`)pW!j~SHbj``#^9e78bVNzhX{5;@=c=v+K5B zEor~$5I9p2I8!n>Q~m{N+JZwbK(8Mm^;MyTQB(>&%u@&P`4v+ zC4^b9Vnjs9QMx|FZtqiU8u9@+SE=CE<6q>3^Bm>&3sx zyc74yu{bGlyAYVK&aVZpXhWhHA#Qs5dDe2(*r*AP|Ai|DgwQsgJzcp~IWzo;LqO{676>=JGzbP{Kb$R0YuI%3>?znKjx|Jn4pVO${|-cu-$z1%W&_Z#_E)bz2s5>W~5b<&MI z(cP|u%lwY;7DR8C${pmy*xSsCYovY6x2PXVX}NWDT~qn!d{Jg_lkgq0X0^j22F5K# zZta6cgJ5Yl@l|Hq!W`(Yjj5s^4VH%urH4{5YfpDvcglYWylx&S#z+u!SbzLu8d6&8 zhj4VYeCq1=$Ng6ef5=_K>|?!6A>|pRJS0IAfgJc%Yy-2tN$3S+meBB}Npxw&vs*wa z?)Ar?AiO>PI?S4lnEOU6cZJ%FsVI`b%73TVD7iH6{S8HcO@O8F_updrG`$xb$Wi2A zCX1DGX?)}n;5u|+)Rg_5f9W9aI$*vJ*=ss{$l{k&`Yz#&4wg^awv1|s zrF(4*l~y0|Bb7!It{V7Zk4@6JyF>Df)ewu{JktzS5k&s#i&GM7CSCX+y~7pXJhIhZ z3WoJT;;-Va6Y6rz6h+pxc1EyHe`!vdd*D5Nb|^9dQ~r{0HGwz%js1!vp_Jz+k7Sn@ z8F69MsXWQv61+-vLB+Nw`#4E;5x|ifdt&_&2(Bqnnq0lXa>qu}FCR)vJXKwkwOBI| z4ImjiVaeX$J<8BNRCs>G?I3Im_WKG6W_L~OXG{{b1w9M&?6&d4FR@hfrNfaU33&PO z_|JXxGyR`G+llc42*v>(v7py<{I)sIey5EHwuJulB@I(sEEuSjuWn)i4mA{9dYzTnUCxyUOmSd;q{-84>3A$7jys3?Ake2q)hRy!hHjG zu$%*;d73SF6!C^!(4Fi<-?L*8?(=}Q&@K50vNQG@;8#0NaRwJG49Qb8Jtx6Q#hMKC z;f_Ei6d{-f#kK|fbis1pATh&DtBJ$SN!ZJazZ7cj%HPk5@wMWM>8-zlK?jf`s=oKVIXaPf#x^mmDn+rx5RIShaU(&J zzgA^V%|7gis3AB*D=606KSf#zy3*e6I(PVv!m%=NhfBufzezQg?f3?c292WL9zyBI z4nti1bXY2H*s<)hu6-JvK9oc#8bczSTgP}8WB6TOScgJ`;*QiOj}q!D%Bvaewmu9peCz>Ki`e}%#D5HS26xOSUXxH zcH4pFC(HS01TNyxQ#7SPROvO}9T%21nhj*WtMN5w;lj^L&}->Hclcu=n8#?I%6>^wGPTT3c?V%TD0u@}ga{BVQ z0*d`Js)7cfxxS;d{KEKLEv;*Tn}GCmT=|#mt}JkIUglKjx!mES5#*E+hqtA#nyBad zoQM(o5~dFwm%EJ}ev0Il7D09*{8z=7st~yApILm<{XdOAq;boC!rA~gK*+zEQf4L_ zqgXo+<7-RWA1|@C4-}$~t;qYw?p1Qr%YWofTR74THR>D4pw5Bo2rvn_IrMZI&&BU8 zF%_nvKu5ezEB8Awm}NAxA+M9Xs4EuyZ16V1d2HR|5gdqHuQ4rpVjkkV91}bzL-lI~ zq(}qKN>$#5yI-WL5X{Pj4UNH1=b6_xFEGsONguK!e27e~R38KFkkVwkh27qeLV0M+ zP*C9o1kN>0s)4EeDjl`->Alcye{M4C{GaD@KOa}u<4<_o!@-Q;7S;WwtX)NdNY%mLBF{C1 z1Rimdd^X>~oEV~W(I*)4OS`O|^fksS>qx7=6f#j^1Wv57{cl+)Mzm`vj?N8PU_akl zmq#;5d6dRtUsS^@LY=#PcEQ*knx`6(Q&D$)f@u*G3Ssr9-jN6Ph0ZIIA8WnE@u#p9I%%ZkW47DG zuEb3Rx>L+Y{=!TCO?1otSoO5!FAeEGG;rF#Qg)l)vGL6iuDug$a}C=MZSz+VJpO=Z zcke5Lo$ z7Ymhh(78(@XeE9plz))qTawKXfxF&jkttE`r#SG}9nV*_?XvnOErsIj(tg|-xBGnH z@?zGzJmOvCaJ2hr_sl^3^sIC_Q3r^n{7x3N0avV;f{OFE%%(ku)%1N-nE>}sIsNHt ztehQG!d6T!77hn@qJpS8mW&zsswETU^@rFyjo0{QyQSV^IZ&)gOZtU@AJ6uZ7~Y@L zGlAATcuUgOYs{#^8rVSK7T(dxY#!7=aIzwADHO?F8FXiEFlhdcQ)ZxCtS&qddMEXt zvhgddSsc$|sl~SpBBmrL6jrvobHkl2rRbVPR2Oii@R#pQ!`+~`gqu(Qwm~N75FYv<4*q& zAE8fi?+fZ5#^e$_gb_p?lM@YDIzEK0zP<|Nh=V;N99Z~msh-Gvt&D%qqQ+6*(AJrb7!gHJ4>HP*y*r#!OFaM-XF*%zYOyOs=mhe zEtQTb_33PgfKm*t%auMym?q=fEif2;-w1a;3Dlg;mwNx;EG?*%y;G)>-BsUD^v+&R z0H=;S$t*46e&0oCcO=F(A+7# z4rXo^e+v=A_BXI*3kI-MwE8m5q3re zo-@9DAcUx4%v#L}{d?G)+Hf4ViF_@+)LlV?>vPbhAO4E$_RTWIlEy}4{oQaofU$^Q zR^(^d)%gS`Y0W93Q>Jtl)s0#+xKb2RtG(R(jh@okK@5^Vd-D{aov&CkhidR zc61UP@;c*zm)@8WI4v)J7KxDk+a*xPV(pMWU@G&oJ~H=@-?zt65u=i}ZpHIVhqA4o6;jI%o% zEW>I};)gvUU>>|5&>8O^P7@?>!(tTXD{KdJZ^VwP(Rj1ZNu-K-?GLp0z1F)#ewQSXMqQR zEXka3!}>9sEfCo<&CY6iI>9{;Iox)4Ma%xsag)2sNhVo6DzGy-di*R9h%M;>fR?ib z_hVrZJo(ph_x<1XmRFYAFSfhoE>@~nN{IG_5(jZ)YAENUhr!{hMvfC z=4&%>eYhVU-WQ5XZCYX!&OGk+p4E!_&9qc5j9<(7LCix1u=bLZ!ihmMaFyb>3;J|SHZ8U>9Ck(qMcNzFe$Gybr)t?w=6r|MWkLZK<{Y`hw zOwULoQ$;H=lvjA!hl~t0_op$2`kqpK%Jzhp9Oi2#G0s#h&rtp1Yv58EHJsyFut12g31w+{R*X;3Wnv$|}0zC74hKuLwgY9_gvuoDz08aSV@*F~;JD zA2}!LgE8iQIkpy@IF83U8Er-W)+sXf=N;5Tvb;&hsWv2t61l=-KcMAS>lZ|Yts0vB z1D2z}Z$z#`RH>b_M^=GeL4ZFvm%GXucgZZ~)n%$mE|1KKD?0Hr zDvaW!WZyE(OU;y?$70HG4{(vP{{-Qr_F)bBLAM<<&*1glzlnz{6|@eu)U>F_oZxsa zhP~qY{qi#H4NN`+-gCmLDpK9r*+2Nx9CQDWBvUdb?GHAZ4CzND6{vy}jd3^foN$VAfP^oY=S=N(#2WaKNxf4x9EX1qxiO(eMwZw^|6UK27 zIC7t3>645OjY5FFOfonv;qOJK@;a{^lLG-&q`FL9^Km5{xP-KGMDaG*EkL z`kaL5Ai_eQAl>?TDNfFV-g*l{3_-S4GFb_+UpnI*Z)jlj$A!2@ojF0;G(C6JuETuY zzKSf(nj1a=n;|uL7T#kI`NU+aG)%#cldRRN4|v76PpsF#e=d;EhC<9OmjXrfJaa7c z>C8F7(T)@uy&sQ7Lfrf4=p*7wEQQD|9&Ec}ntVI;@SEfJI%98C4t*%zWd(V@pm;hE z`wBlGYWq$iXkU(F90$?YW{!YY>R^$dN2Q3VV$}za`I zyn}KUt1RK;tCu&5i_S2SkhjO0>7x9dt?egfa&jOwl!_by&q&7B@}q!k3)SA{(|*3Y zS{r}IUF|JFrADgcpg+A|+04{A3BTTvYO*x;iBUDIyLE0e1Od3ZKSA<}z%N;%0x{e@ zZ<;0Oi<47GcIOY@PMVSg4yo&JDkgHExN7_m5r5TuX3{i*!j-vzyC9Sk*CG2x>_^uI znb`3K-XWIbib%iWbrA2MCAZCu+CbjMiyOI!V zG?`hz3(8*Hy$MZJ3-FM$9h;dn2aE8O>vb4Zym}p*H<9cgpkM#1MKC}bAI~q*@h1xy zWo=!mIUyh>xK^-+5{8-2QuQ6`A`?g>eSexEkfr-3GbIycVyue|;HoiJC&PeCQ8bnl)hc*qF(n8CqW3rO%9OHSakN6Y@5;3e!aM!D>+$#wrYS#Y!U z34wCCo`o8Uj6&p{yoQLA42L@C7**if`K(Rsk~*^xAM|th&Mk~nts6Z(2Vmx`=R; zD3!a2`t9XX8+R;OyPFt0gTJ;6lo7ZeK0k*tTA}CNU72pZT*n%<$t^J=))wXe`2Myk`_)%ZWamjCvrO;VjSxwJL-m)b)~ceUbwnI^vR-(;E|Q8Fwn zQrz5I$(6xfa#hv;4MAZ=>3{RJzkv<1x?m>|@%#JvD(SyO&ItcEiG1hH9!1*cT}PPx z?nz~G+pdsHiFX}}+^P5%vqMX;Yu1c8UM(Q%at?T#fgdqtaR=t0i+_cS|Hdbx|M^Ni!NPZc+`aelhcFfvG1b59l8yW~ z*(J+pKwqD>-|+KS;|SF!sYE&xSo{eI6nMe!($k|!N1OYXGyryn)_ta9v#U*9}LJhzd4Q&9ed{WI7 zVe)=We%z5mUXd(97X!2B~0b@ntZyAs)vY_aT8QryufMMpJaa;?IWVwwzH5NJb zuTt8@1u;hxpFLzKi)N;Vz>PyX9t#WzH!Xi^`~z=(kSB8Z zn3-wKkUm+%aRs6VVAdo#5y0)?sjqE>VL)*NzyU}-?W-p;mUSu{2$PI)zFVZ3Mpygf z0mA!P&b*`B??%td+QEnM*B!Hu4!<*8%NR=ctEC?tZzIo=7~2o_ERL21+cPcF#w7#9 zWcsH1)4f%Eqya2>v8J1QRu!zgd$&a?=K_ZBFY;4TF2$Zt`UCADVub!%z5vOxZ6oQX z1ElHY*NG1z+6VWZYPI`=+T%Dl1e-f+qtFT0(tsj=zS|)K4jX|j1+{bL8vpc%*Z3xR zRh)({39YR&H9BtB=FeH&sQLm;R#qw^PhTQl^v{1s)B2LT=)Av(sO@*pD;abA?o^>P zVe^{LJ*0N-vRd6O3N_B%ZRi=?;hI)9mE`nucj(59$M%c-m1omKQJ=UHcLNyu1+Z*< z>t}ATr*koQ-T59PiD0q)VGYYMm@y#r5P{WVo}Pcz?T=t zM(1~CY40qOc~??4w5eWDMeCRIomvf|HIC&nnZA!S-2@m*EjpGxwpc$3=^;KW{mu|# zMWO#EqdScx^X+>>wrZq?P_QTiVUCD!P1$EHh81bR(sk_p-`q5P%a^)}OtjwOoMV8f?tMr_iUUxJMm z=Y-by8k#4QA)#evRvn8QmKKtVY>%eQ2YJyaHu-D5W+CF;#nSVP-Fe;KIXObtDWi3j zp_JccS?x*R1)r=GZczinQv6xhJ19?7=e%~VM@E%emVR4b({&`hQ`S2O?i(7 z@$S?rCyO;o3g2O`XV?2bpKnmqty=5wY<<)^t!pG~aHXzT+_XLSQ-inGfFR1@6D!$Q zJ3+PWKte;Ua(w~$BX*k$zO`(%49-u7c8YF;Y|0VR){)I2nk))c#ro0+v zR?tar@(vv7zZQnws?lcb6=bw^GLGa!20@L7$(k*UXTAJ1W7I-cZ%9CzE|)ap{G2z=$yvW8Pp z@sanFP&>Il*Qna-yJsdK$0Gjm72JE?w2yi{5)fj#<{slAHg}_Rt=&F8@sZ^*-|wR^ z=9j~4M}N}J?zYZwx-)nEtgx=^U|Y6%$&*pxHX*-y$F!ED^Fdtyh*8ObAg$kZ6zZ8v9Znpx9I{`q z&5f}7I>E4)d{ryDZ$bv8?;f?!cJo(i5nFS3WAq*V4n-Y7Z%IdMDu`d3G(K+{3$qT` zf11BwO04 zEb6oTE@8mMug6k)Z&B3PrJMv{qomX{6HpC^At`W zaXg*GD+(LSge_T$S9#`_1FV-B9Ixallc35H90Xy z1zm!NHBTxKOI;?W?V`EN3)7GL@EuQUvUA2O|Lk%fsQ$rrbe7=lsKPIJd}ZOt60W)? zWZpJ7oJjJ4vJdS~4Xv;;JbB>xd;?+smg3x8M>5I>QK)lMwyKc5$tB#7hrV-uHR1Tz?39!)%g2nQ_+S6)wgy1nULI^i!8t&`4Hp$DO>vzgd;J5 zuDr6i)VcLYD*7>Z1i8sFdvjL4bAjz8%PpdlnJRTu_J_TC&{=aMY`9%7q&!%=D@lymAohrS)5D@Oti zKF(tHfLU!pBj|m{UwQ_fhpavZ{u9C*Uq!|hegy={8Mt_~C@Kuy2f*p{vrsp2;9&?8 z1}4hT)QjGgyXC$--YP^Vq5Ro4IveKY(JxIn?^F!=o>rRhNu#j9QGBzx zHSohUv>o}%QNYBsSLmvk&8`);MfTy!5Eup!-7jJLj!Y2NboR78lUw=hLJBv#!h!FI zYt2qfd>`ySpT7w1Wnb8bmT?!cn?Z~I=eJ=P*zaFRnUs=?y%x6r3KJPAc*+WJ^vtnK zz9~dNO6dHFfA3Oux7GHa!nfcL&OyHK_0jtabUCxmsj=N9W0kv28xFAhWql20HjlhIdsF?h5{%wr^mK_i3 z6&LE4iEFf1J{i%uI2e9cnjVUHEb{efcQIV1eWK?G5)ftvqJr<-jru zSc(fSO8}+_nB*~+t-ZVm==H`^Ei-+U67Y|}W7?Bp1yP?UE}mwu)PrJ}vaj9{6kmbp z_8r%l6FsZ^^gc3FB9^1*p`WxU7`2lIpd@C|;E zaBaOY67Sy!`nNy+N-wrLW{o?4ok?_HNGUi~+&)aCa7w#i z)#=SyKOa!BLK~-)BD2m+`$|XlZ)4j2u;};ElpjK}8t<8nOx}oG%N${Lhrr?=pt6Hy zGB(eo2XwQd2QFZKDuw|`DaUi3Ol4wa2eM}$edLt-W8)!_Hiw56dqAi?)y-}3FoX9v zDh51>&hFi)J(I7>stwUko4I837MIWFWWgkvTu4|PA(|I4;%53Ni{ax#80$qT#%|RN zQ?&y$!_58u58kVvF@Z5c3g6aq-2C>g1yXFEqRW=QU;?w(%f@nST8u}H{Nyf0wY+=F z{gfrqcDMhb3A`F`SviaG5wXiyo>SP8O9x}*qsQX?wQ@$cTN#7KLT|FMnUD(G?%Rgm z6(7on$}6iTKlrfz*TeH@ci9wRDAlP_kT5*Q!GR6lz%gn?u#e2h1fwRwFX(K_uBky}s<#0&$e0ocf1 z3PQg?Cfjir9X+L5%qnXq=aSG>V90wQ95Zmd3ApXoHrQ*EziBdFus9#}O=xIrG) zNWl88NAsALg<&5it2TzN^b+K-M? zEI&@>!#f)aalYYyZgo0igk7)PJ8|^WIjyd8$XizhC6p)NPWq5S!;}K?sr>a66<^`< zBlG#Z-yrjUu~MR^Bmd2c_B^RsJ@-ZE=s#F8m0)nyj`#!PCtiyOvb6N;eONY zis&Q)aW6|&ex-5y%!_sLfW`?S>!_%3n~^w>x`+S9bUFql!2Z1E2fq9xSlVEjUn)rD zM4e5$>G{w$uA$jYGM!h9sBmo>tUi}Q+Cn*JyryJ>tQ}>5a_&cCUjm0V`8_5dLVs=M z4#oR}4?!j>+xJdy*gSt_<{bC8;IJ)SZ2Agqe098NXI<7~`!JVeF`Nw>oBKM1z82e_ zW|Osj^B~9b5oFBsHmou2hYbESeoJwGzs+1l!w)^QcHSm|>&W5i=h&6~78tK_v`K)) zaMg#s*~-SBr@sZVGG|XOnnyg%7BG_k>E!Fy+yh24@Uk8I!jW2(dt8Trb@3~+GHTe^ zY%mPlQOP_OT74`lucDh*3&_OU^Ej-kp`VqNgVSGl2RCv$(#P^>9gDI+>%!$_Ace1w z4L0epv)ywF)Fq6Gj($D)cn_ZYQmi$h|DRJU@>f>oP#+xcnAt|FW=Z?}(X?o-gkAt8r*> z%xJ*j+i-q=SaFm;^?mr*CCkzpc(`xq~ z8Zn<82?Abt>u*zZR+^XIW?MeR6l6O^wGeF6BkY=w!yM}YGCx^ohAUBn&-=;in~yyg z1_^+b$eiH=1;CVs2Y6dXsR4cNuPoCzFlJHqg;l_J0_~3Jkw2_D2kkGrR2SH3V+aw3H@1f=R&)V< z{F{Vqe}v?+$vunOgi*2L&LjRw6r0&VK95rO6Hgw4nuPK%%s(bP*3TaPcKO}XjcKZU z8Uqt6X%E+vHEjAmgt3dV0BcNu6VEH8o{12wbY*?I*;NM5VNNoUTL zJ;xX`L;-_*?4B6Gg?;R^DQgJ>f9orFb9i<|*_kftVdMN>&+z&xkpUWFJ#=OKhBfaX z}j9@hZCGh3c=nA|8ync3>(h`f4^Ts)(QV$87!{D}}$svh*av43a zYhZ=R1F$?2_z@Fh;`a>$r?`Z>R{I>khVnD1>~8Nabd~!18qbA}iI>%;eUa?_jAn2` z7@mX1JU?!`UBQ}^L7w0nh)I9@oa|S4Xbr~F9`OHug7~l734EQ(cVYo?5#JR+gDJmi zukD|N*iu4DgqI!7F8ocsA>2w_;06bQ-eK|K$5=}{H<(P_zH709Z) zgZpY>PoYr|{MqrO;>^?ca^~ADJ7w4`%gXPtSBQHz@?{Q&yZdJYV(u0{ucFH_Qu9^G z+j}{m9kT(gi!8tGfUCnVZm%Jbn!GEZL)$kL%9CJP;i8B9kh?P1zhr5ce(thSS*H9@ zdnr#_Rt{5+am_+{r(_)GP5WnHFJ^SuMfeBYMjhA8_|6k%Y8)k7BKv~2PdX+KTK4#!TpPWfojx1FC;L@Dhx9g@ZuHHICES``D9iSFNA#D55y=t6==p8?dK#5~PT3B- z+Y;$4k%D%B7({X|^*f>!wf+JE)~TM-^1}jtIh2r0lk7rdNYnVkUQTEs#>L?2CL<>C zHfG@+h6TsMUQ6R*Kncl=xeO~;l^-Fy2t7Vo_aGFW0=LwvocmbF5btgF^o-{^svj_# zGO7V3F6GIGJzv@O3U&`V*MX(Zjj$W8zpwxu&VK!N^Be(lIlne?5s2J9NY>kKqdAAn zp?&MUmtU>ZDPCL-r5z~ItOC}M=X>H?l7bU+{5C0Iyepa;(4xgZuTWM=upJX4EIEFQCQ1;gA^OM#7e zHrB7{nYiKc_Jg^sVlOKh{F0QUKV-IwJ^cD#S=9W)p8er0{yjdKN6%bzHRCOVCZhOvh&1{6*VNRcwbfyii-!V9+xL!@uIS>h7ZK4eD-~(^I zlV?o2QoI-wJ@GjqMz%*j*f`fii=H%ho=Zw)m!F9%k&f~2ker-ygWrXZ>E0BF*|=4{ zgfEZn$|V6w4byYF5Z@-!9$^^ALVh6lPBw)z8^s0UdZobz%xzlkqvAbd-?g7@^ zeb*}7e7P@yV1}KxqK8AF(2L_29p}CIrdm%xFFIUt^ZhD=fe^la@AvWFQsQhZUjJNw ze=fN-hac{C5_P=1h!s!XfXzy=^MsyqZ_RVL$tE}AdihRxGtNX{mJ!jmh0Sr$S(Uh-&6}IK6!*IxA92s-3Ao;SkuYQCm^x^R zZXiA`g2-i^3e5Bm@pa$M{Mx@#u#EWeJ^4EtE||ieOTl+LCp+|{R>?(LMC+%uG_tL8 z_pj6tS_5) z)_Fd1s)kAd{Nq5};wGhM@Z=C)z`P)U*;l52bKsT8?_mcrusj)ujx&)MjkN=B z{SosUihkmAtTU4-9rU)#w;LY6FU3Q5z0hwhSKkN3>|dTIVw_G|15DOkZ^-^Yi;z>D z9jMx!`(7rPryJsW=O7@s_C)v<#nfk2+EBc>#<9)A)bg{ut$BlkmGCU$!DDNamdd#e!eZs$E(pL%q1 zenrtxyW=}YbJW%>QV{9tp)4cXEwT6;qEJ#^Y;@TyAl;PNI<(F5M65#2H+yq&hAC0G z2%L?W%npWW#tO&2%0c0~DrD}84c0BVTI@5nyhza~8V(Tmb3BXx`&193KfOrNPR@~E zLSit-vPc3V$I(Y!qLH3hSlDF$TA<3f{!I(iKVL(^y4OWEd@pLWG5nMt+GQ93dfN|BJ%R-CD+yK$Yn>mR~ZH!QJB59no*n0r<4SIk!Z4PbEaA7yb3uvTS#Mx%KI^41l zJG-vh-2#hlJp_9=)0-oCGeQlJ`@6mF9DdI9}+rr_GEh$FV zeFN=U$6+@5Hq(Kl*unah4nDV>aVUg44o9N(v`hOWxnXw=8L#2AI z7<29@0y8>Wxn(!qw`-BOtn>;Q-aYzE0N$}t%{ocG>S#@dpJyS#^QW{Q=Tmk(45o3bQoGkVohtSLml6jlAoZN>Vcu*Z^9mS6;n?|-p zQuwp%H2SmS!-X{SA&C3Mug#!J46gg9_O%WNK#aeyS=6|2z<~d_hXov?E_>hwbsVu# zzdE=uGD}#kJpd{;?BNO@mhq>pJ30fOCnG^W0R9jK#eT%woX#;w>KUI95^HN}5c9Cz zFdhKDy3P1q)As$McZmUdySj&e5wS$n(%Zu5f$mELfe*H{Gl$YHbkUh}H$7;NLlX^v ziIRUIKnUe|b+lbS?JzMDkMfsO8L-;c2uT8o`iHj_yKkR*?Y#0?En;WaNB2A?{d>K( zGC9mZ$|-#v@+-M*w1f1W}IanDBoYK3VPjlykrA)J#5?*>HowrAAhPw z*6)T|4q%w`jX#6lelaih4{CrJ?_5)~c)!R#NI3@|Hl9D-4d25+-wpx`F@_!|7lp;z zY%KgoT! zCoAIhjbV0u%=Hp!v4`I%4ZyIKy&hSvdb-kTdSueR>Fu|=fWz1Wz5Ej`l{F1sxz4e{ z+CqSahiYE=ZUIRD!!%Gvi#0p(j!x(|g}Q{zYn&XGrR6?`Yo9IVvcYQ{i?3P8euitL zsUCWh#80l0AM@TXD7JS9D%sKbUqSsvxIW44;2Y~ZAT_}L58V9uW)g(T!>*!yzMZ>r z?amn1h`3{ZOr5x#xcMBx5=%pKx7|tk2m2c{=nTZl*9afV#lw>iq5sxYz+J4rK)i2almi-{#ld-3XK z{EL749P}(bqzpz9uQCKVh^fI(pZnwE7Dv@&?g7~n;|Bs{4ITPiE}v#0*&Mg5t~hFQ z&}u%1fZLAL*m&(@xQ`b+%D4H!eE)q!sCBcCFuDZUipoMxF--SzO;k-B{RCc+HLr*w zX=l&3x=vMW<}gRT0+X@0jS0Xxc6)@U95zbcUuC8JaPei|uQ>BtevZqmpoT*qH8!U$ z6;KkAq-s;+5UYGPbIfJpdy?q^l$W<3+{x`j;xIz|K|0X}0bT9~n}9D1d}P zGw2on^2*VJv&_nX?01L%<+18?6Zbk$hQNvBwVsD_c@OMxXSU+Xdn^=6%+?NA4UPxK z`ZG4ApWMMS|Di#}&n2MvY8l zS&xbxcVw{nfr=DOLY8yILi3W}kq>>xSZW|u8G4gP#Vfb1idEh9+mOo~jV+io$L=w5 zHWxJ5^aH3sA(Qi^OMH(GN^D_*v3LYLaB!=(ayaaHuCV3&6QhT&i+=UvnzElz?l%BR zE%zlqcB1ObeN4B4JRG_rch)A+50t&x>@T};MZ$N{%l~7!@?G;9j!HA_1+GS}AoiWu zyr2z$$8+D?7`QP{vmtBOK0Eyrv1wneKxRd?zw^Av&2RVZ!_L}rlPJdfAJWWyys5#+ z1aRaO4Nol;m}A@L+EVm>fj(uHuBt6z$TsW;2Q-?>(k=l!&|hLwj#{sv2@=*LE`^W@ z6zE+4yUM+O;Le9|LY@mmh#>@qLhlqsB-RQvsCf{kcvVJupJ;PBd;!(0$YNh^MnrFuufb4BzS8nt+Mp**|egcqhp9n z*AZH%jkiM@`zfyce0$~^7#q`o4XBuZhQyKobS>!r#ok{)#kp+z;wTQmElAKnf(3W) zAi*U-2ojv&?oLDS;1(PL!JQD?8VQ78!QBImHw0;*q5E~#-skLd*1q??|Gjs;G5&9i z)dRk+`l@RFrq!IYprvIK!rn%|;%uzh0drrYGocxUHrhu8M>4gX1TeVnwr$<;i}{2I zr_s*x{NSc7@aOVA7Kc5%A3}UO|EwOcrk6o~p9oViXsa`X)_gx`Dl&W85=U@6RqQC1 z7|}@zPCw3X&Z3>In_$+Q(Di?|*Q<*FNSxf0-FPH`SKej^(|ez7Xtd-+$>)JZIJgbK zRW#4M#i#wOBrdK+M}kU&_Ytds5iOse^(U`IXu!pQpEg!OLFoaqgZa#!SatiE^S&oZ z+p{$uiTcAm4s~%l)eNtXbMAO%!5v;IQZ5JhiuXOIlCiTLYOIJ)pU>5*e~AbJ_^Kk%4owWty$!b`i=-@}jkt%F2msLb`hsouZ!G6?jr*OQBcsF z{-uou>Ay%DOX^kXT2$DltmyBPsfU$Vu&|2pM|r^xnd~6KgOr)*=n-eedkXdhGqtzWA1O9Xp`| zpT(TIeZ{2)-yL-;y<3X@%bAletUlA*Btb2i=~T64-epqkjfkVn&orYu|LESNc_*-U z^d4yzdVzb$?TM{fiQaEQB4Y}lie)rh6cNU(v^rfs`bs~~3UHxR}EW$b!TfXje z_&qLA`1AIMMyW_hlQC%N`%w??=j}NUo)vUBIA}@Y^ZJ~JxKzw7T}$OCJbm)GnV|#J zw5kkNY*|+Pe$#??*Ft2ser@0Jt;7>>;Io>|57T44SW+b%s$Z^N^>ILw6D^!K`7G3h z*8%ED7jScxt&`e$?Mrm0BZjxrW;+tD5%7KZg8u-z_THdfyyVCDXRaWk4$%5{le=%l z3b2uWS0c9W)V?(R9+UhfcXel4GmxHUgLdJX@7#^7_xK$kei)J3(dYTJb+HUTN_}hK zjp@v8#S8E3XALU_2+q|^LyI9X@{umQ!1M%l=LSgHdPl~YSp6uRhvtVV#9+?YtZg?Z zb@>o5G<{CBhWTOm(9;wB_KnZ(x!C`%V>~D5LHU7p9UgOE%7@&Bum6kVCHzH>H&>`G zuSFa=`An(&9S55^CRS)6M)m?z^HU5=#@P5!JTEmM(aIjswEvgwU=IaT?rlQ)gv7et}GX_6P%KqT^bG z^7R_LyEFZ;Wa$vlSpidAKEAhXGy42{8N9QsdHFuJ1gW;p{h{@=bIULDK;J4$uX%*v zUV%Eo@z!P36H@A!__(;Zc+M=K7A*H9KY#yb1~C(D z=&>)Y8!-Q%o*UA^{c0B+B%F`3)R@dQIImz9^{F4t)%Yu>1Il_taR0dl-9{)bF={g| z&5!&iy*{g{iw)tuXJdgLcV}`gDCs$?GS6n+1e&`YH6N01_~t#|WZUOGHE*kX27o>w z{kZaqv)D8qy-p;w)x#)nd2J%oMAngy{Z5YLJbj9Y=-G_JGTVuQp9YiY<%hQ~=;5Gi}*e z+66Jp^0a2bgzp6DB!f{R@V?NCi0B;9gbrfpC6W$r+KMwKm!sJU_#%X za?6%#48O;tauBC_;EU0VfTOhgvqj8jZh3b9{)jIQX_Q7PUex&sG@3iHlBQHk2{@P}L_+dtp zh;v`~%0uw$CI~nul;gi)aSA9dQeimVxH6)Vq}HTWf2zsMCh}8wL%fVa>Oo%R!ToeB zwt>tiXkVBTL30&OlG;ZP;hb@F^)UT|Z#S}*`gtrvnJQgmo)}gg+~2QA@5(102yj!` zTd}200A?fsd0c$^Ph9gfQKeAsfxhIANaOGjOZN{Lj3re(`wClL+vH@M1uAn&{%lPT z+E6$r)Ur4J;qvs&OY_Nl)M(**Dt%Ieo-xTy%1Qunxq*uKj9)t7J~2nBN_w0hfEjYD@MIqQ-|(A*)17 zPkq7+qwV|^Uio5$5?_QrAqlN>czGq7^P(lm>DToGdl}8FvzhtZwUDZOTIpbTO61PU z#zJIrJJ!Ce*lp9+gGju&Vl+|RnkrRVLb-nLFZLFPL~3|@J7Bp^G)RbF9cCdOm_A;j z*oo2}?|x)554=zp@uIIUMBrkjyf-a5Jw?>_P!|-T^8K#OgEa9I zX-vLRcq0zs-f%&}GYPC9Yz&VYDh1+gIxRMORppu!XsP~cPWWIsZW|xo$SwStYT|AA z-dp`R24e}8flmn#OPpxmCwXP^lk+WWM8x?;Wcp@y^Yn~I<%g5R&mBh-VeZcLPESJ1 z2TkV1#={~0vWgS=AGM?&4mw*C|8xkKKe(#4lE9TLzrUt1pT3jkY}zWy&#@nbI7IQv z7Q6sMK)kYp|nBkRS|P`a2S=5h-bY~MuC4kKW~0Sl^z-M#*mU)Tv~ES z{kh5~v2(P0wCb%V({9EOQ43Lmq?95k@EtIIzy$`sQ?+l`-RysE_w3P1l>)v)<$NGA zIE2---f@3)0QMjlkWShz61Z-LtgQ&YDV?-QFVDc&R*PSVuPnbIsR2;7u;ItE_^fh^ z$T0`Y2H?CiuA9c4-^$RP(L?);FOoII2efwxerJ_tso2ruPBAic!|-EUeu0~YRO(_x z^~=i1A3i$+~!brC|i-?U6)7DwP2ptS_l75@19J&v8 zgkSt()gUmBd^=F2DA4vaKC+X!iXE`mIq?J&)q{a{{QzZDizRjm|6Z@b7T?qfhZIQF?~bh^IKH z4Nil{d$9_~j%mMT;SlY7idAIarJV^N75VORI`Y-|ZTWTaUd!obdcbq{%a@tb#Dflf zK5-87UEPIv%&kNY`jpmw$)s~HhM?KsWGcpF`^5UZ)QRht*92cmwV7f}JEkNJ+UO<3;Cl|rOX5a*>{uGycLt}b6Ke(G=$c*!1p z{pHPu$*l19+|v2B86#KrTNcty4yop+1EBBL1}Ty~CMjVHEoP>|dFAWh0&VG9M-MRt z77C?9!uc7gU$zt9x*_I8updq&G~(UQ65erYcy!x$C}c^=HodpIp{ZFnpqh7PS|sLaVilAlaLDOKC8{xfZVn?e`;&h|A_pSImD z{%6AHOHHS0MVb3m;+Bi4An|67N8KZ2Uibsnmul&3 zPOwkfK`pb~Rn&CV{SDF2ElM-d?aps&$yX&$i|xDzbCwHm^m7*@dgPD!wn z^VX3nH#Gp@7z~Z*gm?)mTZ;uTKfTl|2cSAlm8#(BErSyHmvrH@dz=7cuKJ&x&l_ zH<1d*4!I@5>zM?D_cmZ-~hT)*6vl3#Owq;4#UzIcQfpP5T!4M~Q?Wks+B;cd7) z_*&)E+4($f%6~9Gxc#MR762c$nc&4C&D1K@58K9~tM#@|Vg24k zyQ)?AJTTdPCiN-!XIlx-{Mp$pB^cvJL!nF0A-jz>niFIHlWL(JPR6tsVZL{4fJ$+) zW*d<1VN(R9LZ@JU)&Yp|!QKW1&Uw>%TmK8exKOOe9~#{N#Ew5Rv6C)kYA*?+3n&b{ zznpl8J89EbvMFLC>J8WZmK5E>pZV~Tuxt3kuE3jK(FPY>Us=-268At%MFzwVq*#?B z@5kxFL{D4xr~*2&oT6#ec!I;*5~;)b9>WudUg zALHUw+&YGaxvv`NV%x^AZy$O+)TtcEH@9FXKqkW$cvI$0Y|Zx-ovdVzKtnYoI$I4i zR`qC!yWnv85HRJwXx#56tMk!>*@fa4oZB(vDTY7V)>ddNLEQkR|#Ea-fj)1g(vmSi;IEh)vlI|yjbd|@+q6yBfaC(ji&~N zkXoaVf+h2rlHzTlB+VLo_j00<$+L=UFD9|=IoSn&*Rav*Id8|38b>L-Fych|hr_J~ zM|(ql1rJxcg*?&kBTA=8@aCOfgoXO&Kf9}>gQ(LqbjM1UtMxbxNyWOm;|s>4-y9v3 z-I4Ry+!JNL0J)RGLBTI0sY;z?*WY}sHL`j0Frct1D#hl}r)`5}bZ_kfJyx2?DBJ)A zt9mCs$Qo)~03O<^Pd7HY8e&!=iB6=PVoRD(3u{h2(b0 z>+5qN54k;Zx!DG%+%pDIC91G(E9)~z+n^_Y%DCi96+^^DLjCiwL`c%jw-v-5U10}> zV4iAVZ6dQ7A!QJyd4U6ow#F9XBWp&mvhL$PhhKWAA)#t@|hSKs_DHYn9$Ke z-EA!VPq`BV(EC-1FWEMuq!6`Wb2j6hy0yo$_TGDJlh(h6E*U=cv|SjroXhTD2BpY& zDM7Uhi$9WJjiaH=+8jbNPadf=oZyv9ibUaS#Ll!S?0uE6IwT>Gu-hc{ z?e4^fZokYY&Y6A>R)@I0P0YY3E*5ZAg^#Nj6*rfJl~)CvbEA0T)iM>LpF4YIKLU_# z9LB%3JFB-Cl@o3}m#Y8%;z1+zNBSE2S;7d;kP@27TFq~`pK~vH+ic<9Q6tC`Mv4Tz zR6FES{q@rlvMXrL_sVGZyD}8e&pyFCB`N|sQTLyVGgzue@gc*$?Z+~-7vkUf36@B# zK-?A8sPn4@yc&`=d51s4uCrL9OTV9t34hv;dfMBsILbFS*Wwg(QfOjd>wG-bHLY{c zi!bMo8as5XrXMMApZiTW>?&Mc!US^*Zt^f#-?F|dAq3SN_0gU;x}p-M7t6)GFx^(4V~yFt8KAV2zYy*L9@D!PS@V$LI;h0?(>y5M$6-6-F6#k zw&}ys&~Zipj)0#m|3FeeU^fC&sIjayDriL7H^7a}yyx@s2Q_`Qk(3A>xFQ?|t^#C(J_IgbirkkslT> zR0kzV?eRB1!Z9uMmqera#K+9q&!-z$1nbNT#E8*Y`G-;S2Vysxl^<5W7!uVVzE*ah z9l#YVC;PzRmw#`;FaeAm>70JV!yH54TfaKFA~DFXjnrplEb8SJ_1vbW$i#7xEhKd| zQ#aw<1gFdab=oNa)w3}*QU$t;iD=m$%FP|o&7fAq<0HPOV6h5Jx&K)sc0c9Gn)DoTfGHHHgsos+` z&t{1%N#~=yaxD~!ifvu|QtbFhphV}6X(8`G?W8MOKj|O>oLBW`Q^@J6@R|_6y+;d0 zipeYJDtXX#B9p^6-r{ODru}3)W1HDd{aNG9^A5wuNe|#H6Scwi8&d{ptJM#wk_*2~ zJ)s8(y-)w>gynhQ6>ZEI^)%sm0(3P(oKVnKbUCawv#`U{>xfbSByo#7o~&8SC&S|& z+k?@ag^5cuNHU?#Ap}CEw2>pb6&8DD3A8zxPHL<7xe28CCd(01bVQTf(QLx}t_S&0cw6u2s&9g~SLK>e-0 z3ED3_8F2s~P7$`m!l*5eDpme#S=LKz{5x+=XHo|02@D0DU++4H@h`Ckix27{qib3L zQVzBvSs+UFojQ<@zSfQFoslH||Erhnrulkb_q*7`WGv*SF841rZyvk*_k^1l6$|M!j5*I`d}@p)VeTWBycZPk zOI#6Vs(koyO8fp`@?t$qF7%xi#!e55bnBbMPG($L6s57DuJr)#LaPnTc?Zq@`B%e^ zZfuFVO6aF!O}2?d_#LZhqQvc-&pqp#uDK_!paJJ6Z80350x{RN#QCYoskpAm~X%!dO$E>hYyrp`}3fi2; zJ#dK0bx(=f1!<;R179%7A+cQ2x?CzE?K)pBRje=p$3`Qbu1?!?2iso^xC{Wf)F&+u zU?v~VJO>h?Jz{U!l0_+Au0|LyHD`aC_jyBFgzDo+wLc-z6!$iL#yMj?^1@|YwQ4W^ z?G3)tqtdl-Hu>ASh&rT9&UebAjOvi>J5x54o6t@|>eENLDO4w?LhQn%N<3GWqXuJq zQLT&(TH3pD4h)>mBXcl)rLG#R?=h!@$zk6|0OZmLs_eJcsTinW7U4$V-CdW-3*bYQ z4^FY9k|WCnTdH-t_;6Rpi`hNkRcoYEiFM2lkw@qJYxB<4M(?)+uWhb#=^pfU$8p9 z^gc5TWY5*cs6|*g+J~a~_5;@(#$2zs#(VMyZxzcjMoQEd;U#A~*U&=c2d}Rcr5g3F zfsaw$h4*uOCY1!v8>l)cU{kJ4XLR$+v6T3zZH4bXG1~}p_?CzSOsB8Tq9eVzo?yBLJz za%mY$l6|ilTY9|tcqhLNcB(Kz@AjNHNWi*K`}!$eM`pas!vQ3*gik-P-0S2of1SaJ zo{eY(9vO@o++`&Q-`mqx43{1h>5u%ifvd zJ6?}ZY{b1{h-48-5Y;L)ceT14I)g;+T}2Bqin(}{sxSFvJh)WF;F?_adSC2CA-21M zE&JA2L@DZZR`=WjOQ|VQd0pOPxnG|gQK@Xy2pJK)f-w!i7C#**T1ikK+-Z|6FeS*_28k;uF=DUTG51Tn$mp{mI=qNdK52KV7k;7%yrr`G;(r- z0MEC+L$nu>*J@^QgQ22jmxudrZ9HCW0f^LvgE;ZgO!Kl+85uqpy>nQs##p<~ck~<& zcdYaH7%T3?#6Q0+)M9~ZWn_$F^b3C^XXR&rulc%~OIxhgG|=&-kE%%g(LR#UNl6Tf zi8<#igDKq6f^7!G7X>)$ISj)(J|~3_jo-5kQS^;ts5gKkrE?NO3sVn14$xt+0f{;9C2Q+{ppy%Fb5j*dSzwE;IqoT! zlflQVC$NXjkqr}<=wdOYic%zBUVit5C08jhX7$HL@1D>*wd5Ftq~LHE zfnLQzpNmxuXT^Kg%2*}V_8zDi*!`Ywd~0d%VHk7v7}7trbv`^=B_=ayPh1D47|PQ9 zupJ2e;QP5n>HIl?@UnrwogRZ@xQ`ZDFFpzFX3#r7HzG=pjhdsz$7WTH48eZPMO>Ox zt9Y}?l~*l=%0>F=&?Kk15fXA>Cmj2%eAI8^EOhd+AP{oL!Rzw8D3r!{IW@+F&Fm!+ z$#=Kos=hGq<{B&O7S#O-?-SN+O&KZK5Ey-2*y=mipAflJ6=vMda$@|s{QSf+gj@Qq zPy>PXWd8|ed&ps^&ufXtV5FCMwn4(!)+D>g$~^WUn= zclNi>8I16@h>y%#TL5oYmMQuC8q;>X)R%<^n?w!ujYa#fOk0->6#T4UY)2B15xp|4pL#RK}sp#YCPHhEPLqWBD*J&-O zSVIAwwB)D_+4S@h5_7={AFotT1Vnx~WRrgw^^(MKy=r>p<#DMnF_(F*u}V-VRU?fPN+yn<2UBm6(vqOnv776Upr25VQ7#& zl9Vw@h|4w-PJDa1cdt;o;l{8rQ8*l-74v4RiBHm@{A5+5UwRFZq4PBG@ZI>2bchG) zE3ZLEtKQ2Li)@)7nbyPIV~YH-FL1u?dm3JlOaQ~M>P_nROd9g(_D)axN$g)kKi*QP zDNDKMKOiA0dZ}%54jVc*RkLW-Zv3=Q@HPLC*bz{*m6Vpx{h`G1?B1WSNRc~{3l4*vej5-w1%B(p$dH0j)(3d}UNg6bp}kgF}-Z5^PLK!h-yiH zL_ti)v!U_xiV9^-Pki+~%a@G#?#M-PUncy6nv%&dVu{EBZ7}(9LRuRoerT=b&zy+K ztjmV8m529t_mnRjofP}Z%%u|XC~a|mQS_C|Dw^(kMKsPEI2#^S)hHNvFka~HH!(f* zSEpea5g%DqbZ$kR@H*zcl-G}W6gDiR?@Ugc-CKBtmLsti)I3x5R9_R&70l0av${Zg z(u%F%Zf{>iLRCZ;AsU^7=O^=h@FyilgC6k%lEOx^n2?GoV&$YMl1wN@su)jOnb$iD z_RCPiMn@{~Lwt|TPQo@u(a$(SAdt#swsbJU?n`KHXwr}KOl8R=hrDCLzGi~x#o}#~ zBAt2P>^HG{*q`S-2t#TVDqSnu`M^Y2CvELC|Z zAB>b4D9&^&CBY-(NhkeTESc~*hS)gQCxI)77Qf>c1#WEFe%P6BE;~Qdx|!{me-zOl z=v>_hCPwtai@UXJOMdX|4hPt#*hZX_YtGb z$zG%ybhZI2Hk3r?w*XJK%KT`jW6qr-uc9|lgTC`67f%FM;j@bn^2b%S)=OY+e&eIn zHb4|hdajSmrgrp~ZiW7V?!)G85?!mBcU9O=@AKYHj5wmvG}>K<#xB9#;2G*3EMVa* z{Tv?(E|zh63WMYB2m!W|nk+@JLFx4*j<(QR8+H1>%De*8{!( z>J~Tz9w-#^*>L`iIcpq6^QlyMx+MrfIHfGkAfe2;gSxF*hJgTQm^ZicYF zDeVcCL969om*;d3Awy1>AKo}E=E`A*M;!=RQ?lLRtIz$MThy>a?@2Jw|KaD{mM@vfa8dKgGgV)x-Drvw z#3OS@r4=4BV^bRa4IeXj-R_OHKWijaXEyer;=_FAI`8C+pe5-NfL^dGL!HOOM?gNp zp>a(HI$t=756Y*3(k8yA9<6|TquEn4PI;QWpO>R4s1Pr~)! zAV;V5u*}r=)&Rl$`_2yWu3w{}M5(5qX41SFVTp7w^$iJ!d~w&YIpAjo!Y$f()47{X z5Br4#Hy`6C3Q?beXc0vZJN&8$=I3FY7F4XWd-WPo<8Y}Nm$s|9iy2-{+{^MIM0>|p z@P|S5So*L57_LFO_LrCv!7bruj}y~^o(FqH+1Fco=E=?6Zd|_P{%XK>?~9mENc`9} z@81LvA>|#^(^pve)a^op9!JyFQWq=WPZ%5eK7r7 z_*AbE<9xyR#PRl_jTa~JcxOv%whtE%#l^b7a>-5m*|A3b@s>VYjwL}@!t|EQr8LT+N<~wHI084`2Z=lnsO}OO zPKT${27%t6Xm%}@R>N(AZCsGpUywB@cRcz`I_pRP680<|^ImB1(6|`OEiWp3z_rw# z71zB^tf^B${#!MBusHtq9$9-qhM1z$%2BE>e@e*>7r+DSgS)vRlb^S4W2mdSgfa zq0cW(l-Q-aU78NRC3DvfbmAn>G)pP@bx@0Z(fPuqj@E^{iABan^*GZuoyB<3%|(IWcG4>&8reC+s-7x4IiI9)BG<{>_3?J&8Q5cq|hWYA-Wt zDT38)$bkFPSQ<~T%f{jgci`du*`>z=em!lEhpIN{$HHqkyI=xV4^cM;8vnCbuim6- z=e+S5KpA6Kj?ECe7V<4gSkbe;Um{>md+e<7%>QM|z)~97)`MPEVwr%=ZN3ly-Q>MwZgkMTA%VTyv~&wiN7g- znPn;1Gnl({{$rKnZFssY^W&g3gq8G=hq;q&VH@H=QNYp!Ouw5U>LqsG*_2MR)f&D2 zZbEn8FDgn_!WxgsAjwW@PQDCJ>iZV$yI#TMQ0 zNMnRJ_j4z=r?tI%QE3gx>SkISi_!~#&HW)!yl&52_ONrVeRP!Q1+yY;m<_9+ewF+V z!YfKgul;A%(0h6IxJ-V&`N<~gnAc6w<~DlO8!r8k;4RF!X; z8y`|Vo{03^2&&+89`w^wQ1!-1>m7`KUvgc)*-cdD;BC-62VIFK6^?(49*5~P*n z+pF8QPllDtqrQB%hCa}@87h^BS3Fzqdf)whR|@<-35R~%#P?Q~Vk8ktxwfS0TU9pw z{Pa!IuW{w9?imAFV~SUmrCa$)*jb5S#OksyD&ok@n@eGM`Z~I+KpNYs_#1cXR9Nii-*D^%MMw>YVg+YrAylDrtbI7d5(d) zG81*gk|elAZ6krDpC7+#m1rmJ70oi`Td~>qSc|_Ilq-lr^!#MRlRkJY8xy?C+1yr3 z{c$AI6v1Mh^>fzV^^8YvaVGw|k2%VXCSzxIy%IjD!0<8*-i@kkmig_M*TT)ij>}fQ zgR$aaSPRa#2`B=%^UU<-yI%LN^t!9TEU}fTQ0XYCCY=m=x{QFo{(&u7V2}(J7klF=$ShIuEq82JJA9st?aks z&c0SCz>z39Jmi!{iePFG0uhen{sYKGQ#4|Y%>QS?ay~Cqq?ItUOmH|8yqSTjQ&<&2 zFXn-H$N!Pi-vEi7%L)ZOLvJp+#Pl|oy5rv%`tjno*z~uUJ40&h<2I?t9`%cSp1fU@ z1cY~q@~$fYv`-fTXV z@t*_&A={8NRHJ$B*GQexoPI~CwOgXz?A=_e&@p{^h4 zo~A+l!#;G?jO*KepuTMW#G|nDXTNSME*97a3^zz>q^>$6?t0jzyg3>OUE`5bI?G>G zU$j=F$=0zG@JBT<&S_lN%uZRB{g~Sa+jVV*ofCHQhin78kyBqYL8mk5MbcYKgVd11 z<0V0s-G-66r>~HM*Hg^M-8AS#3lRjvc3)MnMjnT$t zzd>ie?8j4;u+dE)xi)X_VU)RdbINqTz?Ro#c`&A5`J9$RWh-4)t! zQ-j1dq>%y#;uhd)$1F>T37zd;3M)a zkIo{&GPK+)bkRh*nI%gi7^|qz17>j9Q&7;uZXt<^GZBMffv%V0@8M0fjF+;K1ce+5$-(d5uW?Eko)P0 zscy;zf?9Oa?}-Jn)tGCXUPBCJUe9s6*pZF3mZ5IOD10-iL)ec8NNH~HrKv$(HCEa_ zcbob3s$7{60ZsekhA7Brb%E$_1sun@`dkOahyU6Zd2`uA>DxR*2RwT!sNh)L|3BNFKPn$_Rz~ znbGwpu4Nq5AD(tCK1KIcXq`ptaI@aymE;cz3az17$eY+qMy;U`6*!4f#JYf?O-wFX zPB2{`J@6pZuW2g7?G9JOI;9p?&8rB*M$XLb7tI)(M^2#%zK1R*u=L&L(RQrt{b?!yop zxn%i0)^yH?55)QdI<%|sZhWcU1~k48&a7&(d3}fd6%)Fl zug6J+f`W$guN=5u_ZQ{B6^X<+H>$x+)*>b*!>4pb+8jdmPqy%)aU1|f$!-x3!3v=1tGqPA5)Rg_wLkTo&RKlm60162d)}&wr`49s+a>Kz zw>-4Cb<)6|PQQ@sQu5e0sOjvuFPk6y@+`0VB(J55a=ON|EV!rbzHBJ+3p1TM<<#-P z6eaNWIbkiP$?y88@Fh_IL!$LvDMTazMw~kG$5)5oZf~0A)o7=VX4o-N6|AN^o4Z6{Uuh{-m|)SP zXC^HjAIr->%D&{qcqsF7OGOaXINWiIg%RuByK5#IbX4QF zmP~I8nWBrXWdkSmjMYY$Kc2-TBvYkQG4#sEzn{}A8OqN;$qzV&Ln;Kyq_106jS=fD z&a-X0UM~)I;2-H^5L8pU9|NeYlf<6xb$ra5>T>dGlqlaj3(%fnkO7l+mWO48JxWo4 zd%R1)3R>QV7PA<^OnFDkW0u3ZlLdd7(hII_w-lE{!-NUf-YljW0m1&*Ojd32~z?4h2-; znmAcy77jGY0Ae)Y6b`|btiezm!>f1W{ye3zYu%9>3;V$Ub*j=?PK#^bTS0i0nI(H_0=0{19o*sorU?aDrw ziZzjUR4D}ZWNrQ68-tfetWb|0mGzUp2!22AaSZ5>IYc&Q;jRx}e_S}|z9tJVHuZ_L zMC0r8{!W*)4Mi2n$B3Q2t)q`U114iGl>Ko7t=bk`(OC$Nn4k*pQr&QAH-i2+46!F} z)gu-i3pr5p6(DMFEV&F=bXbD&9nj9kaA&FDfrHd{_p$+aRCWByZyj@M_D1Dc0D>V@Oq5sl6@35&g8ope?tlmnzIj%b4yZudA`hi zoAsLHM3;zv)D>rLjJ&A8?je#<>0Ue+GZ&uDFR#yOSbaB>ODtSmT$uOR-%-;0X&qhO zZ<9iwTHo3fEL7dlCAIR1O*7!VONb3F)qRE0C3D)xocO-RfkAf6g}NUDX2EsAh4+^bLH zX&x&=z1PD_SsGs-Slwcuv#QQZhi9*=AZgybbgVgZsXcGJJsC`UzDjplR+*bgJYQeKGe4P~WK6h07;>ZH{0d648Q@hpNKzO!%;u}Pzg;e9 z6^f+r4Vk7P{bKSrv`~2O{q&YNV7Eg}D%2}@ZrrmkxcCxj_+RY{hp;nXS3Xi~S7G|A z5qlfM*JED6pMF~vS|GfR=kkIe29h&&L6o0kP$1nz<^EU_f!L3ji zi_A^p*u%S1ps~_vAI$=@Rl}}NIMUh_%A=+d(;W6nM~(dVjao;?5Tpw~K&s6Q7*&#O zdQJ<~`Rz?x;ypFwtbrCzK+3rrspoEetPy)QhA*O?6l_Z?aUMhZL@%Eu5I9ece|i6i z6#Oi!w=mD{Au^EA4Pmv|BIQKx-lV|N>5r4+P1Wx|>WNXbDoD(KMnYi@qfgj^4He2Y z&GXicQn2$U$D89`p2I?{LOi}Saxss>7|f|RXpbF7a00Y{WoghNZ+aYC8gKEApnz?` z5_#`G+UUnmlp|a9gHRU3LxH86D^mMlU&uG&noH{AxUxgox!8%(7lD(f)ygIs4t`j+ zHY@7oH*`eVV-Efb7ak`pGj~_S%Xu-j;FV{HyAuWJB{3fz>7g$AFCHgP;$T;NG#m0rB2kxzU}W zurZt*@6av3+4P$Tw2u|2v9(#_mc zQ!$==tExPzK@i9`e{Q@rcXr!n#C<*cv9jWH#06s)j~7dA$)T0tIS66tv6PWeMpH5_ zcaEQ>Nfdhz$>G|6S>c1x$?Zi^`$3%Ys>if+dQ%&cXgf|gc5W`U{y;7N*sgX)f+_oa zdp%f_x2^eu|Io;?HrTA@oGH~sQC#Ohif_!o?eZoBzEE&d%xZP5_7Rwn?k}7P@qg@T z?NYIhdNDs^mcrEg%mXv|# zzl2goo!QBCO5#T42Nk}*90q{~^s!QaGS(?fPs`Hq1LIr!!b1bS*~wBZxge_|WdY-D zHeKL>4k*O$Ktvo$IOo51A6(ryv8>5{$;rS4n{vN0ls2H(zeUSx32e-zn~EKuhCurf zpQ)g*(a-mF6T6%|DG4yl5s8tfBTKf-9UyY}Ip68Z=dsV@zeI)Lh?WfC4!mT?@Jpz% zg$g3S?1Myw7)2)oo*cY%(6>f}E9Voz5vjmw!F*^+0AQ}5c(+qe5ZO%(y&)->rSO5w zw{cAldL>ie=ndb`o3@SZgmAsM_4&Yt+-TuS zjMJVX7}1C653`dB=_qi;-5~qjc5o2^$Adc}^?W;{rs^2s@+YT&nXUq;i@}^?j?SZN z(+`RtIzGft4yNJ2u~T}cSE!v-DmH-ZQX@1YbGC9SSP0d_wYr=BtHxIZa6~J@N{q@$ zo*)_qb?91$Ftk*^7cRmIzlYtd+1#>zA}D{Lh47o$jd-h)x?1ZbQdooNGwQZhH^2VL4hl4C;kg z`V25E#(fBz@K}|bL`yH9>6!4kgASJ!eXYcBOpy`C>+ zL<}wcmyr!qnmdOupwnp`0lcaA|L<<*P{4ucD%$r?>Rg(GP*6}${4p2t8aHxt4_Hj4)`wgvIfxnBlSm|b%VKWd-S_47aL7HYec^XlL4?RErG3SBm}%5DoUG~P z?D4Wd&w7|m@T@NU7%>CPe_h!QgslNn>NQ7nSGuLnVKn(qj;7sp3+^YVx4#&Ey$6KP z|D&-S5Ii9;XxDVK++q`a49)L~b2H?E!6E&2-}#-`VesRu0_YvRMpjF~+WE4kK`EEj zTF?C)FiSv{W~38|f#A3KApF4(ah1P5ooleP;8f&eE@JbcSvZ0Df7dk6BY^Whah=2( z$!*90Kl7iK4?)lVi!8r7_WQGJhR&q4wegdZ9>?$twdt^1SwAOb&!Xbslf@cX82w2| zRj7s!Nf?M;wA$G5R~?oZR;8VoZaDN5hvs(8Nwv%c1+VL@1I(ZmUUMc6$6ZzS`M^Al zC|p9|@#*|ub=jxb zxF%X)#Ur50l6Y9pt1h@S(VdwS$h6c12x%6I=~26fOH(JC*{l*reDs~6zdf7eCrzzR2~ z*)e@1az?bwhOm~hC4fJs*;zlrqw58{b-HtKz(piAogrR%K{55V7;1&#V?dC}UH|Od z`VgY(I;yIsrw+4g5MbnV-?ctxcqf;>1pyBbZ8B7n0}IfNh5)bF;n2#HU=+BU${Exv zq~JP=J57@VkP>^h2VXdN7~d`6^Ii$J}TOFIPOBZzly3;F=^ zZE(s{BCUj;0`#_MVD#yH!kMYWE@EltmSN!cV8`k2HLsCtwkP1Gx$bv}FHJ)|*V@PT zLC;Okh;+t*2%WqBv;znPW9QB%SNp!KdIZUz%^l$VZ;nj$X^@lNcNN?t@+}g9XC(>u z6Q@MF2P+UPcp*|yDB$?F=!pCE>e=h4%9@^nn{16g0Osz;w;5`i;qahqb)@=^7Z7Yi z^oT8oZQzJ_Eb!Y>?Tr+1kJVNpPIT7`~o`D4Vo6oKw&;LU$0eX93T@{ zoh>YbR!DX)*CCn-(@5CECZNt!$@y4dbhaBJy~%0i>YB0u27~2Jj71@->FKRD8b3SD z8130f?rKRyymJ`}T-r7bzIKS}@%}FtRVY!C(T^U8=#i(n%&u6>^P7=Yu9 zEH35&0O$mkPZ}M%D9b13*Re-%KiAfyM<70GuNK2&AP)V?YB#h60%W=7^EK0gt*y5s z77bvEQ2TY*@)d&Pn#b3@=c=p63UQZ@c;hPAS^+J1g>VFl`QCgy>FO~?R5f0?V7DMS zIRF5b18f$NH`Nh-uvDvvLnPh(0;u0j09>l78FH_<4p=TABCMJ2hB9~|1gu~lh(fPr zDE!lL!TkMtZ?gIlvVBx=e7@Ks|_s;ivh zEO5`N0aWS(tHrF9zCOqtL|jcqJ_}B0zvw>^aSYkB=GB;x?wMeYaLg(xJ9-fA~AS#9TiCUNm{m_Qflx% z+IHa61NSsITx@I_UpLrj^#>#jdvadeklP@{c);+j@EDLT@l4EoedbWhe?|O0g?ABM zOf#0%amSi8VHuv@vmB`93<#5pE`g+y7b;(`7E_e_un&D>h^y}XH-LN6(VI?}ohF_* zIL5^L;j;8os*EE0l%4kXWlH}U!fFT4^?3evY_wM3>Pbc}2|{Iad8CuzqS7lR()!j8 znnYRs@QVGq*E54vT7p9EE6}6e$X+k+=-OWQogmKi?K7^@k1#B@liXm%kw3;8&2LE~ z*xW{fdu5x5Q;K(WSZ^$J^b+BoSo2L=lqZpf7xA0+YX=)FFtI}j3=4-sT7_h4sH2QH$65xm2L(DdKSMsv@-hz}2$^#);6nt@o&tEBTiLrB}kBw|Wgq!v?7=`~~ zAl@y5vWHv`#LU)SGE3z2ir&6Io>gS*V9t7lYs!1g$e}>!!=6p5RUI?fkEXbtk9z#p%%?U#+QO<_y_f+&BPu7AFnN2XrM!w1R>I1A!%HFo%R-#cnhds5#6BH zL+rRw^*;{dm~;|QOitW&JUwX=w-F?&=pL$hoUgE8GwtSJwH`=7JZx!S2l$1q^kNms zo3l=Ir%=B{7K@tP0t4vn^ts;$taI>~{OR!7-9maY^-jG`{)563d3=H6dZKGs9hOUP zO4MZ#{ax^;{&9wTUnbE0na}Yeiz5~d30%MDk10?hnh6vnui=LI9!8IoJJNXGoecQz z7sf5J2=(r=FG8teSs~z(f~S*W^OPx5Ung?sg>nH!H(pPEOG|wDe%NAM7u|bD?_KU- z=sF~aM_h4f^Gbyb3RQ@^ugT(R2=tliuC>|C#kj*Xq+S(7*_!i^uwvym*Jc|Ne(E7m zf3XIMuBrATLr^D4Z_-?KpF^yI4u1j|n&EO!V&AgKaZzuZ-$*s~4f6 zeTMk!EARkc=U^%cp1DiJ%TO9R1wW956(}QC&iuTjopR*+cpo}7bbt*O56YThqTz@(m)CX2eiqK6m}l)J#tOC zb)ci8tBFy@i|9fW8b15YE&7W&-PN+6)2o+2Y#u$0K69=P%$HRlVc38x*f>!MbBTk&mgr|66DZy|Ll&k>$LIy*F>idnFf$7WPP(QH!c|Fwhjhs*j>*TQJEl zQ?%M<84s;BwKMj4f2sRONlPtQc0-Dyx(|AtY9zB6ZdcHWYhSV|5hBAJ4IC_TU6Q8J zsC&-|hQqvPx_)HjsVgirN2uBP)WXPB*IRJT2d^nwU8jNgbm4`EOX+IWqz{Wi-r&kO z7=RU_3J`o=YY(@|Bvb}rz;o__ujg@BV~=C}6?3lYxB7aGuiU-H0KvfQu9g;|t;+3b zT__5OGTzDHegWo6mAmS<0M!N^m1BPjE9b!m?UZAmQ_J%)6j0fc2R^f_@Z-nPiH`{|O{ zE&c+CwU$6x>H3A&h7h>ETOgxRR}t}y1RS^CpiBS+C;H`zWX2`DA8TnRO#zKIcsE9U#jmnJc=4SIYrCRb zQ`A9(*yJx~8k(7_Bk-KZ1FQHsIy|tpa6QCSl#`yD__@S~(cP7G`98%TI1&iW{xsz) zFDv{A8EZWk5)zVG7gUJL%YC3b;#y*ut#bLE5BA`T|#zSnuIG!Ve5kXvG3 zHx~iLgwSHhep3JG9v}N}yn+R@Bm&vMasL;z7#-SEYR(SP7|}e6kZm^mSKF`+xp1R; z^EalUC;#R{4LG>qyE!cQi3ZmqzWKBc>}b?C4vZvsaZ%C3lgzZTE%G^Z17bdfKrnBa zAf9*XQmFPmOO3dQ-O@fYPYV;)GWQZsz+rhROQ>$m(CXjin-H82=~$KN+uta(#FJMc z93S<}!F$M}XP_>WWpKj)wvJ=pu*>wz1>@AExnJVD&7uKn>s*X2GK*-H&JXVmVwj)# zwZoZZ-~BY_wl8!WVn_@z{i}k6oogG#It&=tdUzYK*4(;p)$I3V|lzGY?Mhq&co zKUqUt5sJ_ngsQbc@&K(#!>GIvryTgMVRYY%#ppX$Z4kHU%M@KfT0Ut0<_n|z5#TA~ z6Q|38*NfoWh`jo5zlcK1?jpi9LL*J^yg@o%c LSp?qOrkeZd_g1PK*>M9>aL&7K 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%0AioSW2OMP^wS})a8fq5g4tWC_nrw-Jmgq(& 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 z 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�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

2ppYK|Z$ynHvB5I&3I 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%0A^D`; zRX*|=LA$a9delfmzMQG!ambeT3YJ+u7mG2p*7wbO3LWBkTHD*RvNhZ!ze0w7YeBu` z>sf&3rNvcsI!Z{1MT^+}^$9mUsA*DnzigXpvM(k9=KRIP*q)Zii~ko&^ntEGFXnjTiZ<2bJ2St&>=@ zI(_`#W+^AXm3Sj8YpAqYjrW+sLW|%Rw{qYV`WmC%ZL~{hUO=Kly{4s2SSY6w+Qp|9OxL%KQ zWqFa7}j51Xl4z?;dBLA%6vbHM( z|ENs1(LR|jkMRTJXK-O84f|bvDVF6q7RRit39mIzuvkry&+}F{+5P5~ydgbApi9g( zj(_`*iwFx147$A7=6JmuDVZQg+p2qZPE9XW-7HCv=;zNJR%%!s`~Vm8E$7Bf=-&yR z`?aw zWJzcJS3#A~YwYqEZHyg_>eqTH-Q}{}=4TQ*7b=a+(Y~|((>-7H)EXL^if$T?kL_<5 zp#q(Ewg=zU#AUIb6JJR~!By)3OUJLcWs=Fx@v#__v{&3j!5pM#%)@`)i38ji2T}IP zl3jkXpqlH&oWI}rUoA6t;T7jBrMtZ@EYzf=fF`P{yEg%kV-aLsZ(`HRP#7Y}-XtEu z;Eub(2!@<7x9cSD;@Q`aQwXLG$p>r{`fMOPb82M4eHv>!JH5XnBds3R1M-X?qCYek zFsBKzuuRRYt#x4C=kv%j{)^hHoH;O`^2@t4rAJj8GSkSB0e-h$_qd%t}7sLi{|ea-_u@1jtFI{(v9pBU1qg zq*OJAoAC0k%(kAX(|+y!Kusj71g1b=6MDx> zDl|W!C+==d$X&tvfefOU*_Jt5GK+Nz7%+wC%`Ge}I-b|AapvWF>Qe{_QEh*k<6Me|rRXfLulIgG8vOR_WikP;``i>YbdgWhFa47_x)uH1H(b>r z&ZI=r4(><7pf52D{h(bC-fv><_kVj@!VtHCkb$p~l9EqWP1VtL!xS;Za!H6W}>r&)X`j(wsHA`SoWpKs5&faZaA@;`}2+KEknchW`F$RDV$~Gj*jLo8TYF-ITo+Jz#DDavXqmX~m>Z|a zQDzvDm_I!wGs9ietIRX(Ek>MkMLl=l;^H!&pQ_E$@i;LGgW-c-JKJY-Ke*19z?Rgk zcpXq^pRD`Qq^>+BN#837wx2bY#y%62Scr{{TO6dV(s(%(QExQAp+RR}SFW7jF&@aQ z-C}jX&BOrDY0Y<>ZZ`YcbRMOn%w%*s89I`zWs8_%9D4*w@$#d`AAeq8Kj1bkENp-T zJRe0KwnFG@aSbejmuOOQ?-;-HG0WT6eKh`xvr|+4i6GVbK1)z6R+vR7h23uTKIppr z?AH8#yRdEZKo2JS^(YGGX*O?ZhXKwmzLoUDlGI7#IzzgmvmND z?KN^tBF0Cj+OUQ-Y#zSsS9*?Lj6(hH`XRP-BLV2aIdd8QTXpxi=GgKQr)5-gru>m0 z6vOQPp?r#-7)@Zsm+7Z-`+EFg`C)MkORM?EB!wlNwvGB?k2DexGec$^Fm{Us9oAb; z`=KgvBssRW8d>eAax-I`_9;Mn0j|xk_ApX|L?uSI5?99;Yk}M@k3}WS6OQ`(#}+V2 z_Cov;e9=#EYvoxeRpynXS6J|X%5T>;klbDp@QqJibT4|JHrLzoHh6$#{o9PjRo4gu zofkF?fO`Ud-BLhyuCXw{z?3pMB_-uzM&PXaY!h2ZCiuzX88eBD$|uF{bnbt>0JpXA z%4x`vjp`BZao0{gkGaEsnr|hQ=)F%hKf23tT?oDq@vKQ%&X>rFasYZttEx`GD_}hn zeE1jsS5d2jIfs z0*LxrKgQc9&^lZ%vw4%FQ6?@qeZsyZG^mIF-t@bJQVL(QABS7(j28m{pt!E^!nUPr zeDGU$5H|Ak^%WrCrHTVgrKbY|bN!y9$drV(uL(LkI|U#V!jWo0Mh_tc=jEgbWk6s} z&>Ua)0RZT^kHS*w!{?!$v%`=^bbI;8hfw+Q zhjYUV+!0P>CsHx~L8^lwdV9S6&U`9GHg3Wi0~Ks;VfVw~>+j%iX9k9yl;Doa+iF=A zWK79NXyA=fgqd5qg*^W3?5r%CL9qjUveqs>;Q8$bj+>f?sX3+ZX2T&0O9CAWLjqko z$=4~Tfb*b`7@4>>-If)!A$%=@Vx6+1M^f%ArX3mmPtXu3FiacUxxWrU_vkS;f(bm? zJP&nFn(F`H7IQhf$4$|wUpb|ItAo{RgtLIKQxmTc?lYycfJ)E_2lGaNwMMgDh>sug zSx;A2YiDPV1W)OY4D`UK0V#;5JweXZaT{&5%5LiDs;(CJP(rbpJK13KFF>~Y?~m|G zEc5oT9X#6L8pds3NK_m#aK|#xGy7nf>2rLPF1)+GzGoXehva7Sn#=ZP0N}_fLt%(8 zCy@E$jLs31G4cuHAH!k}%&|8pF+xTCL+3*2;yIK@SEGQNg*yy!f_LawbxuM6Y(*Bt zk0RVkFk~m~b!0)bd!F`t8lvh{L)Lab1-;RFw0rf&TjYaaQ&(y=>M3G{s zl}$#~Ha1sHP49o6Ak|umSy20nuHsiAH7zaA5|nA3VD{tWs>~|O3~K@{$ zsn;$__bvC1#1RHt+Hir#Y=r_mAJ|Nfm8PXs;pe`qZoTW#XqM5zcpx0cD4U{dL$OUV zgzMcxRTifMK1%Vv6TRR4B6!oYvE@#z)Bphyh^D>bzac#1Ds{cqE6KMH7pd$cghNrI zM??0a2NnA2*dbW?CiYK_F2LQKIq8ziduRs~VPUuL@KtiV7oudZLJY6k1yYi-Fda-zP%C&_7vZ}2ZN3R9X8ZeE%1vm z3rx|85{8mzHWoLovSOHt!MWH<)4@wnQrD}nkL{wwxq|4ZEYm}}%3ipF5208Tjbwo3 zZ3EmejLVI*6&V3sbND~WTfl!s6WREW*rpb&T?q;A@eyd+fdc%ZtyG# z*l9m=j4(RpMN+=DgbVHmPS$qGmmrMw(-Rdh9=w#r?)!LmIt(p{5ugY$wNntv*O2AOs7z|QK0l+B86u4B&lzNjx5 zk7FPHqUq6aa$*dG7j!j1qBwVBGZ&yyee^gKZUR8*`lB$d-r=H)2z1Q9MYK z_Di!Gk@Xz#>){qGO%XZ>CF(DTjE%;%urNVDka4=PVVIm8X2l6l(2K*u@^-o_;3zSf+$V93|I>7y#?oY_j-OiRgKOJlr4=J4`b zLmDCj0N@aR76ur#*<@{tl|cl$hs->=*-6P%jmqz2>v<`S?gx}5 z?im|5L;n3z`((K)5J0TEXz=KKGh7xc7qm^lFN80vF|%mim5D^w^GzhliURDW~hMzvueZRQ!MM zJ1}jLJvUn+;|Hxdg&6dG0#&Pm-8!pKsS^embkp?vD1+V0{q$=w65!wWfI{nx-Q;l!&cN<)T%K(GB+~J(>)a55dFl>SCpRx2#B;h6 zrAPsQUwRG#t8^-3Y2a&oe${rS1@@N0ZZ_CCI95zo|~RtSzn%idKk)?gVru=Bzze`Hq?e|F@YWxQc=S;|3olytNc(F zY3#4cDmf*r_A%#LT+>(CUX;G{Dmw%n5w=vJPuB8{D}5IadzYJ=hbPB=HiFZx^JU>S z!>;+ris8dl_B6%KJMGV) z0R;s=8=LF?=I4u0Q2`%7dL;Gv4Gr9Y6Hlo}L`n)_VvL_War0iY6#^)USuj#HR*&fx znA^*QM`zVcRIyM1J*Pd@4Kea+5p+cBxO0A^*ws_llcmmrt;h%UQ+R8rI2wEHh>%)f zcU1ppwIHSap3Fn?us#P=09QZ61}ba(IMlq{j?(69)12f5^xfZUX}c{f&U*+72&@#S zuMB_V@pSGivN)XXLmPwfmBCo{w4J|@b;+9!)ZOo)?Wz+1{5=9klB)nt)I{?np7lz7lnqVjE|RJ4@BYmz*&2tb~o6hh3`UjQAgBH>LMTaLp!hC&AnF+3V@)aew3dgE+!UH~jwYnC!Qw%`9JF z1uqz(OXy7#ESaiPThh@s%8sU_RBH@QmUQlao>R=2!w7@dJG zkyM~j8LYn(isF);Nqm=6)nQBXSr%`7syu|3L{J`|w%GYV;f3WY+c~>r^2*CNJEQ%; zMuIIf!4Dt)F46GjH=%Q1ePbib#MoGyC;q`#{KseCoocGs-v9upyA^|$kiv>vfW#pd z3f+=;#OA9vbVK%!_O{DDrr_yU{GDU>RH^sjs)y5+<9~){%yTR$oObh^%g@_&Q+@&$ zyGf>!UAqYdjYUN_qh$w5?>h-1XG(@5OceE%2wp1@{Z5Wu6b{xK59VIUU+;#y8(!*N zfX2bo=FtvXnPXhmY=i&o`J6$S$nZ?XANWA+|DZ|qmFch}x5#TnM|tQmk;=$1by(%z zI5cENRE~CwkpPgtccl6@%Qv&IurMUM4>#-%C8*Xq&Tc%QW1>BqNn~ozb!wKYf(sq7ocC+p7Z@>~j8niZ4gGcuqzU_892JY&EH~Gn zln*d!ij#acCr?YAvb;`7j)RR>nzt~&r}IJcjyoG2;0We{}c6 zD@Yvc@VP5EL0nEw?&8*Fm9gr#-#opp-RHZVIH6VwiLew549%mSH;!i1?wsSSXA$|f zs89Ik7R*2e9Gn}hPl`;f&-t63uanw#yn#1P;d?UE zz&2pPu;zBlxPYC2+X8*>51Ro-JM(lk%XCv4*eN2s_c@;Y z*cYd$$f&Gt+##u6J|#)B(}FiD0oF9>%BzoRl!7bes7P!k;0`o}Mp8M5QLA}v16zet zGwyU-HK#!gozC?&n&$Fyc5G~HBOR{b_SYPT>EKs4J>bo(rKCVvYSw%Q6_A}~E%#@B z50jmu;$#~B&M9KvtOg$4?C&Cr#}{9!jXg*}kwYZd^U>j$%P$eOVk}_+fDGF)IRC;l zi%8R_Mw_huPx9s15n1KevX9#%`@lGAjZ?Pe_HuB|N^Cp$QaVT5CM+6SP=8STEaR-@ zse34e>GdFAU9Ei8YSTwuAagS4E6}3?)UXU7{Kk?9AM=#VoAJHKp&U zeS~X*n@UQSm4RjQv5&jU@1Q|l_Xb)|7SCnSC`N?#ZiZ^yWKjw@cqQGZjdavwRZxXd z!j&F;Ws}dIiXczj4{^!=hvjbn8_CH#$seqJV5LK-k)_3))jY~iXx@D#Z>OIOJSWU8 zzmbIHCyu?Uv9OJE6YtH-Enx$-6z4po)n%CALrI`a`m;aYg6zC2Dk@?+)yRZrg$?ML z8OO#(N5ACoS$u;JUNG~Yeq_c1Z0&8W2j!E0RH%(S8MbYj8Z1itQ6-K(vp(Ozxnc6( z80HjtA)qVdlyNc(2OveHAc(~^N52j#dTYn#1AkF zbyEVI;0;>5?3(kvKT%b$V|ty0q8^vpJZ(OHK&}n|8+k5OaBb){BfVj0)t^5$bBDFP zW_Uuk9#-=5tkrOzRHoDMh6nY9=l_n=UF!?j-(E>x7kU>#E{DGNbj^aMG;Ariva-@s zXEDihzfgmt(tGXqeo;|M7^&Cwc3+%OKH@#F2^jU2G)0M$b5HQ-3J`9zOFe@-Cq+1) zdwP1qJ!EQZ%*3JKR8VBWNu?1Q+^-G3iD6)#@VM>?>+-&6IVkISe6ZX5e!k%_iP_iZ zp(oHWW%)y3stS6WlbAx7B4T0Kxw7UCLevW`9pr%rF+~5NUPTd$Z*N7iyHqm2$085g zLn*~d^6D`$0+v#LFu7kM6+=EPzNlqe2UoNGMmMK#tD05skwX|JXjmhhP*q&~g?7D& zcEaz_wT+~Kn|mVlr|&W~W!jBBZ3006%kghYCvbHjCr3|*Bn%Xw-2JM-Ie1#K&|=_% zW!nDe=;#8}TIu5IT2q9f`ro*P^QsB&d)OG3gC6PdH>?)6k!;UBUow3nju{yZ5m;aK zla=OllQ5<)bdPs8i``{aeC`ITZesrQK%lQC`^Cj z2_@#V<~F}DX7)0FSdD_EF2MSU=F$Ljwu_+h_vEq1)L0l4fK}^$cdWHCwYc{Oc$rjb z1;V)>fIwi7I7W62vf=v(%ug*}0JNrtvMd=yW8cd@M8=Clu`7Z2!XPq$oWqk-7(&>5)+UD6!Cz z{y2)KqNT0f_U!9NK3J?^obwYycf99|5bf18NoB=~_g47cwX8D=pnk;b?5Ojl2LaW` zdSpAy?%~eI>Nbt%wC*}O`igx}PyuKS5yNrYCZ%`a347zD#|(e~&qAY`-odt1lrQY7 zxx&maYswM}vh^4f(@ZuC8j9OACaprAGQ>B9AMX~+od(5;J~qQ+8*oBu4j)h`e6{`I zAUTFbK1k2|!^ZV#{@;xXSm%V?$;%vLgx^x~%BlRM(17cg!JI*Nq3j{ZMMww6ZvcTi zQ{$t~U9H{&k6l0ShQN=Hj~WFHCej7KR|GrQmU*r-4obn(P5pmQfbI<_E7c8>W)yvKmRaHtItU7t`!IR3z zQiFNhU$tYN}=a(H-pcz77&#*ghltF_%Sf9SN~56h^Mh3CDX^qX_Y z=?xgg;s>cUw>QrNk_`EwXpceDCa`I`X@^C6Olzf5?dmC~i%t$(q28ASwmCI*FJXTE zG*;o8T}woqWaD6$8Rw#1MCOej;Bs(eu(JvQRIm3f1g3rsmO7z~*?z=4K5Ki*Zal|-pagrb>0vFJyB!<_&>1fl3I!DIA@9<=-u_*(G+}< z--H4f6(SzlbT*z+AbE;bnq14~q*|%hchKErLvOlom*-6O@$@mN{?J0P1E7{62KhBLmRQ`Qz<^6mwM1?M!{`lW2 zGnAxSogR8RY1%{zHK0~S*dm7{fluec!Wn)JPhJom6|BnF9)>D9X^gW&CpGI}{?W{u zkGowLXMUvTONlgStez$Vyk>gdGezSkC-UrrP(ZFGieRChqg8H&4~^P5awG?H17`$~Ic>#A;2|BViJL7a9G7dL3(FHRHZl;Vl`7LoG=&md6QK){P|^IMOPRDa2b=PS zi>S9KG6fedU~r&8(m?sU&iYSv?ZrnRnyBk7ZOs{4iU!Mku6C#Ma;bG3E$=ZNrZ`~- z3W-^c+hjI6gJKv};?=D-Kf?7374V1}1B|y|hoEiAUaywkYcRub@c2HmkuoAIGwc-=cl0-4l0wfQ=;E@5`$3;Ufo;^=I9EDs{2bt6*5 zd-kjoq4zgc%zB8uyonMz#S(88rWQ?cHrriMFrO1NkuvKIRLOjzhK2;Pi-y(wt zA*#j>DA&AMRswguKJuU=cvL|5w`1s+>({CNOXGgbibaD`6(OJXPbz|hj3>WGyZyOG z3dNj&@+Hu7LFDPQ?O@wPK5pvP{bzShkMiiTd*=az*wGG^zYxwQcDY~s~cjk`vmaf{6b=#51imsgg3PAkceXz?qFZmMizHP zo4F}zHf!>wgn-yCq_x?5iLX11+1N;T-_zq1d9o6yZjVe(PA>VaKrN#)tVDRKM-e8f zQ9dgNJ0;9S^Nu@46RL6`7`4Mt{2&BDqu?k28>+eh*~N6x18 z58gK_t-;|*DcSo=K2yT-z}Z=6L?4Yh(xvvl&+d0gha37?v}uAF@wwyUg)r6n1u#yOTiZB^;D{R2Uvd+L zwu;i5k|s9{tLaHCNp5_isgAMaR|OFw)0CwvSqcjfBj$IFh(A%BchilaUV^a0OC5 zW-6@`dHDR{ur4#QH|Ca~>EqsKaBeO)&yVMQsO@iC2xtf(xBRi9q*cOT#V69}nlR4u z=*$Kj^0_!FQ8{p($1m`i{Jg8x@_!I5_{W5YT=sij4Fu2L642N|^DlPJR3& z=-&`l%hA!Y$!3V6-_Wt}5l6wS%zIn(2^!&80RW~KHX1b+ZvyFZM30--ZDmwVRDo+B z{5X;N^GVQi)C}{Ie3pjhfHSl#m2fmS!bz03Ns$QQcXWjDP- zi`QZvBLYg+Td0rLX8gx z98cT~WM$te>_*+P?cmWFN|J)Hc$+K{Li!ipUyclN(Gf*4TKoMKhBj<;5QXSCGBT=e ze_Y_<6x{jH2(y%5YYr<=g{8-r-=eCUZ7xc@Db>hK_eEaA8bbgzRL?f?A6j?oUwGfS zx6ZeoNX|(SkX@0*f@L}ngT!9=hk#Czoy9N`9#TMOpmI=tPvxkT-zZ{0zBHZ3M}K7_ zXCV-`9;UZX3UPI)4u7=_guW%2^PFX7|S+^+>MVpw4W8%POEVzOS#4i zvv_`(r1XnC_zMJf!1oIabM=D6iax->$V&HAssC0bW#aDczOFU?AbiFI57mYV(t8T{ zNlU|5`Sbn5U?-NPE;O65-_%`K!3Gbw&H9mX`Y!*=uvT<_D27}dz&k^%cxUyjm6MT2>Wk0i<<(VLS!roi zv*iYTK&QV4NWo7Jq0QGRDGTL>z7rYH0=gMJFYe`h$9OmF=ajY13*| z55788@TV}3wL+u!1u0uy-4*cugrDEg?P*6hZkDEqzd0^(0^6h~S*y9ub+&Ut$>edS zY$Za?$|qn_q-?~IkOrk7JivR8CUri`b?}HNN}hYEb8HX(9d%N` z>DlqE`dNwf>G3i0t4zB;devgAvLqS{+S(m>zD_BNv#G7EjfR<-S#u*N_BO}0TLYj0 zccSZX?bA!t(2X^t`BWiLReh}64o1Ko552fY+L`Lbx06OZ#RWl2rHgg5EtbF5fBN4P zCNEx6+BtY?!B^9^X*I4FpY~4AhF~^Ul^vGO(Jf74|3JD0(nl-N5iXvKQbsFG{W)v+Oq?;yHg0N0ppPXO+&`V>! zAC)U9D(*v2;8Gl4qSYK$qq(5hIBtSal7cE9W_Vc!aw)kt_>Tm!P=M2>w^w>m0lt)9 zF{C<;KC8E*9*g5Sbv7Wi&8sP)HX4brlpDLFcPDWi%}p$x1^S@I>%r>MwvP6@s6`rB zpO!czul0WJks3#)$M<&0xaqw!zu3;kMG}6;koHeN9=~|eW1C-zuj$gvUBdHx<Qm7^~nZ@(Y zQ&|j6O^bZ?Fw_b?A)s(^2g#9-_y9(X1`r+VW?($R$~5fx__w$-b)1DG*Ez^C{^Id0 z!_G%1D+>kEmOG6xfbwIbm)1NPjdyc@H9=i(ohbbzio+QDyS~d7|D@`8rX>WFB*_$& z+BN(kx6)&Yt3!4%N%t!&GfDEzkX7~@<^K<(Kdo};efA#Kpk4sG?JSp#rFA5(W~)Hk zb4*N3ds>it59VW1>ZeCius4SVRhB!_Vfj>b|8?)S;VO<_v#sUPZ}u(+zN|3wbelr%>V1w@_a0Fq+s>mOc0Mmr z;I1cKoi~<`UC}J57=2P6*43Z~>K%kASeHwo@ET?!yaVK;Rgh(@W81o0G&aS$Huxqv zhBV7-(Z;R(=WWg(7xe6S7GQ#s>*K9`QE=)JIvwWhNGo=1eD<%?X4y_o;Y>1Q7{Kdg z6szt6SH&FH#0p{x6-#|n!%Zfam#aNCx6&>ZoVY-atmFYwxY#MepvZ!ozm^i8vyLbt z;N*fOj7cP?3c?htdYX-aq%OT2lO1Qtce5uAoTH18bsK}t4 z?7st?s{pUJm*tnYRyWS@5N86t;Ir}}tWiy1ydtJ8?NK4Q8pJGY zFyjNxTZ(g3m!}uL8T>YNt5v$mKD{XX^QV|UVDk_b-&(`CUrep<2ldBDN$0d|$qVD$ zXHmP=c0m9(L=?BRsXYjfJ5E~_772+6pI_wK^)aU6Yojq2n?-K=d(p^r?(fS>bbkaN zogJSE?oNLmgZf8=*g<kO>xyD%zz&qhLsoG&1R2aD?geCO} z5V-=mfD#>#fv|yYqBE=b65tOD!|-ZVCQ^==c0>@rfc+O5+%k+sJ=6IFc0&PNf7)rA zg>vm+?I>yHdrCGLDDiN7#%BSO0z&dTbbpM;UN?-Pztj_8UPj z-mHm?O#-Mr;mDay3;S15&{4UVAlm{C1PCzo0b)FD!WO1M3Os{1ams#=0|%3Dr*L?k z_w(ru6X*gQK6Jik_PH{Dfv;rpeV?O!sF}zxZPq$Xrq`@F?VJG3@YcdElZn@{w3Y)UnOCC(Z=o zG?u{mTzG*0ZEWnKvkq&x3V*(|ibH}7kc$gch!y3}Y_1U_)Z|Ia1=e7~AbrPT4yXo} zM_n#`!mal9_9*s2y`gI2zQL@0*Y=yo3?ev9jTrJ2@jayDppPrF1M&=RXKTv~v$K=} zW)dnIKYwwTI{&B~+NlX@|0n!w=BRxJyPSYn<3Pzd9(a`bp-nd^{u&}lryi~|K<#av zSXe3Sc4}aGY|j%*nr*UDLguhD*SEJOND-eW`1nGj+klkR{CF0QoL@#g$_hR))}Tp!ddmiZIaC`AR-WOprV&Q)cyAU_RLAR4>6ydoRIw-)h)A?uJf8qei8w#<$Du8Q}0!O{(6PfQ*6LtlpDYC z`w%-dC3#Qeak?+#uTHs_|49cG<`lEnH;CaUs*Zq3=*mC*cj3H{F=fX1My{cB)GE)y0o}THeVVH0cDjU+ z<74`oG^XpjcL}O|@jbb}U|k}Kg<%^!#W%`HZ`EP{>CMb+gBk|xyzIE^)P#VRsF-^V z_Qv&J2pzb^Mixn#`~mhr%EbbTk+#guupVFK%t_Q)RZHgh#qgp-QR3gvID0K7#8FMbj6goO2drZ+lD z!i<;Adl$8_p&PWM(B!2d0yRd45yN7Jbd>Lsf;e@hdgxOgkj;@*{GW{?IeDfc4}_%~ zBML*|`-mygtCP~u+Xd!OgL;~$AK>&N(36s&{>OxVtHRmAD6?UAs%a>Ar4W+mUntGA zhI>)~fSz|pBY=Vn)#xPBEx`Ei-%8ubTlZPM@9hXp7BKx^4!B=`qx2|=zU~&h`>RWH z9d#~qOY;-H({WB$uj7ai?Fi$?Y{UhNY*|GFSB*O?)?tF@Q||jcKf^uRy8)1IUXUIl z;9uc)Q!o^u1u?I;`4>arHQeL4l89DIhaV@#={K&t9JKbAa-ni?B(ZMU0o03DNW!gN zA#(kTA;zSi{Gz-nEB1wdc^LlE?YF#eo^ms`7U4qz?@5n?SGC2PAPQHT(-P%x-?kt6 zxV!Y`yGF43f`(x=4iyKwm!^nDdISz+#d!Qj#>Q66_KYr{zgE8SA7nZ?qKa&v_X)MM z6favh`asx#DDCTSi`bn{Fnf}A` z8qaR-_dFtNc7-t#h+IScHC`eQANT2`sVWqmVVY~Ada?qafhBcpxhoPPV*PSMBo1@m zmQ2Q6C^Jep|I#U)w}_Lw3~SNtJ` zFX@Ctg5DLKXJxE8cLWVlbH46Ve%XE!l~=(IGv>}4C9a;%t@n850;@I(xOSPH~Qnq68k zYet?raZ%T`W=^)j3=E03foi5c(}`nNH+$Eb=#TzOvJr%SFk>BW?FVIblfnn-5TjpO ze|;u+qk9hHJhcq4>> z#iT&S>wVu*eW;C?eQ=cLD)5?VCUZkcgvejEAV)kOOjpCuqQA^I^EOoLP|L$g+8Id6 zUwynpb+x8YWL86YV;~%*xk`~EYQ5p^FUWk#ioY|FUPOZ5fGM3;q20&>VGn*$y&KIB z3B;9v$rTwlh7^?1X%kr&B7?oCi+%@3K}+bz@jf)CEceGF&P!zEeZI^|7z_y`_Q8oz zgCB%N%ehp){(v4gS|=k97_dLTTV~M6$cU%Qh@V==+aqXIA7Whqq}wg{ z(|~;n>&HwNO{i?#)u4C>v6S4&*%(=g=c)G$U{L_N${?EbA)?RnLhRJLqouD?^z52A z_|UCCfk6Hv-1LE_Jz*=Kz|q)j3S+PC_?h-nQ@T7J75%|t18RwvnUxG4@Vxw{#=PLt zA+%iV>DIO$OS0<5mFe~Bfh9&P1d-2v2}X*UFS2IbDNswH@sn6q@qJr-L>WcAiU(wv ze@skTScTst;F6g*NXrK?tF~l_ssenH1zoRQ>zlxbM@JMvKamt3?k_3Z)@|SB#eq)# ztS2*fA?8T5XjypvdW#ij1+OGPii?ZwPE)N`wslhQDYV1f8;Qy5 zMYM#qhq-2iX|76P8zk)#e2T7K1BNF`t48B4%^y|{?fSM5vqA| zO)}ON7?bY1<>)*c+B!H~aP+Y;B))%{E+XvX_>_9Z$_Atb%p7rfin5+lQc(v;3E1gz zP_-gxcpSDnzZmZo?|l3gCCIGsb~=A0PwIV}_VE7L$*swv?$cGtOhHcl@~Ibu(HBHr zywV_${j=r}h_2#}h8vY4rxncW%45R1Ij6yuU2J-g+Pwew~*nWGDw zwxQ}Oe}u^vuuMEE-}=B3J0pf( zOu(Vi3ctx|DhAZo9-b_`@E5=dppo+NJaGT>1DZxhsKsWKuFMYsM$r$;-jTb(v)_eN}Xy%M5|a37BK+bWp-UETs!}Q$OiD;maH2;=j(Kv&jNuv ztYo4hZ*Eunek(cDf`sDKu}KmF;NO%`x}Ws>JSS;_POD27Ic^eC!^|@NEPy?)6ACUr zAhR?sTO*JwjPWWsl^Nj2=%>%OR)YUPa-%biWwzt6jEE1&C2e znAZ-pBxT1C@yx{#2=ajIlT54b_d!*w0WT-}E`?Yww>uAb9KJ}xBtlbYm@cr!F82iu z3;6wVyIp@?(neSlsUKGjQ|koD}P4 zc$iowC>?6-K`mnH_j}ya^?DAyzd^6^0%L?}ORK&*kWDQs{AdTd zLD8n#WmUcXvF9z-YO;i|33Sh43YXh>wSG+O=h-`DL&ZU zEnHljZ_0Lh^)SK}x;{7k$Ez!4NY0o=OQ{v}^#D#1DN7(y4-$a*C>jz?Yeyzz%n$kcViuY7AxHC<+bn$@xM|s1hBEm2 z$8QGCu3YjfNEChoyGAb2%3&!897y;)WF_-kWUUSN~y}vNOAl&GEG?t7Zz*PoJ{>UW0e%ZDPvYPy&q|`OV zHDL$IR(iehU1Ly61&YyN>_perRx=oOikX&ME(7BDZQO1?*Pb za$`}VeVkw2kq#)yJuX zwopF#8BqaN!KmXK`CmkQsQ2&Ys3<6MC%b3Hkf1s$u zsl<1a^D3D-)i&z`NfWX;7az1}2P1~)rS(=5tIwutMOGIdSYd-a%UwTYu~;6Q-(E;t z)Itl^^RZygV&O1iWYNYat(FVblN8%#tuP== z7MP_yZtZN^o2SE8DT0t{Mn>v^X4B&sS&mNiKdZONEcj|0WcdE-bFX`VW zfAwgCZ*Xw%OhjLY16gr}YwQuubGFn36sL2x9w?c*dPm9F|F+jF+wJ9?2Ro}FnCH%F z6khiUEf@-jnfv1c0KShGG6ijIPcFs4v}<1d_t%9w8-)o#sSd+K0T6siBuUHd}T$Rv2N=2khSl@oNunL}R z^L%wk=#6esYb8OLe3c%~*^nK}co|PgC zIZn<@%7%-lm)HH!LENU*Q_ro45VFe0!vezUMxuNS^&S_2W+u#84={N{x^!~WIrM40 zFpQya+DWEFo-7m7sys`R7mL0*06uueR9t?C5RW-evf~ z*Tma$W9sZC4NvA$9Y4#E<_LwUYDeG7A0`}8Q+84B`J|Xf9+i``jOC&|Yl0ShZ`L4q z?Ta$lOhWMsXP{OpIe(i{NnKqXj3Gm&dOupbH~%uyE=FlZ9cwrY9Z$D{DBWo3MbI3syv+&=D$C2VhZsl39s6)*fv!Qg6LJB+ z*3|mRHiX4_Arh7nKY2_I%XaTqd{q}aB^XQDg1){BGyaanzPF^M+UDJh{Q*>v12UVH(2BVI6VM(W#awO~=K$jn6FGHzQ(63fLr1xY0c z2msMXXIy;Jpa0Nd*YqsT)`Hdx5T~i!Hm^u8e4RJUoy&5$NlH-Re~-8<-~Eb|4wyOk zg)!gP;Dj6^K@n79L<$Y4KMMnYvPy3h9Big(l=@zch%4@ca<&*?5{F^B=x|L6}*}7(C@T1lh$KO~Ah> z;6qiS&C)ym)Nybw7IX5S!6J7(^)kL!d)pzhKIUri3w1xF!CS&uH)arLMN5+wE?LXJA9tpx$Q$m*nwS9~v7Pk~2{g7hUrfJq#1(eN#&Mu~H>XC?kq1!W+XU zby$f67kI!*enQo`&G(dT6Rxo2yId$n1rZL(p*8YIhmn#+jisfP&Gq$%QA#2&x65!J z7BGOVS0|`8dc*(N;V-yO)C$_&B?RO%&5-We^|@P6$s3Ktc2(%Gkr|C&(CC;MGwdLZ zO96Nr;h2V<7|lq=TU1(G`&f{Uulc`SfB+dXftP!#INzd{zb&ar$+l!@E?J)rzbCTy z=&uSl$EdeItSkljy?}-k`mSTKDLN(=7dkwEMWI#)dUd$vt1@b@NLJEB*8N5H(o0*cbe{Z_Jc#X{@t|6VAJoyC+F6Xy! z#6pG6)56RU$OYzU;Jg1F8EZaSK+&hO4J;_A zuHGT|3k541{F)+jL5_;#IBUPTtt#35fhDJrPs4aFXIpp7Aa-c|@jBeuGXp1{T|YHf zku;-Tj>&;5`8CdXfT3g%i_k)Qz-uGkV?V`Mb`BvzbczJT3U%$jjeEk;c}K?3GXnhn&X05rgPXWb2~!s9xQgIer_ z3Lpov@%+YLJWO}>x2^m0Ls+$t)VFJM^X$rnFH>>I=x*a~KV7xV^2u$)d9sG^W`HP} zg>Z%@eNuRBMvu~K@VKAJ3RHd)Baw%%d2THc4n98{Mf+gQvr2%!V^c$)E|C)0+Z#9; z8yl;>>3Oxrd60RV^Vr&Y_Nvo&VRi(D?|mjEVC>~Y{tX>_w&UjJ zv^dj#`->$nqpi3o*khZ=j)ypH(ueXbm^MA^<7nYRay;p$8C>9zKNDbe7$QcSK2Pgc zkpFZaX`FN1Vf-Uv=*W5HcGd6g#IEyIfNwjU`%>*TYx=VfFBkLp^fZ*i<69(kxjyr+ zU)VW;?3I#;r=%fH(lJ$CTIvecwa~rw7={FNjGqU!$>zen?*kCJ1YY|!v$HxnR)su3tfbYzh(~HC6s&U)@Bz=df2r0FpPmFrtN@hDo*KZ|sYZ8@n&-^8&5Fw5!Nl#H>uh4RTMcbr!*T{11PbC6>!iDl1XSxrN zXeS*vZmPT#NmK=n(E#Y(_)YwfMDbuwW;!Aum^91Qsz+UV1u!a5V{0PmUW=%$M&R|= zT&fzLejofMNmkwB*K)dW>45bqbH}x9N*sbL@BGrYRC4r~{Y6Zj`a^@Ns!Pkm1AolT z#y%~X_j%O*;2V0eLYGZ%uxH$l8JPYc86dVcj;H^lBmGB`b{I8YBk?@i9GUz zOOp|AFQqI`cEGiHx~o3dhayC>)Umx2y@9AyW?`ROBwChJb31TI52wOqHcWmq1`2aY zo%ggjNoQrIpXz>0)5ddkkp*0O5e`kAF75lcENT;sHr{q}sq~a|XvRCmy44VHsIr}Z zmp%3s%yQ}Cp5K~0Np0zt0BI+ayb%Y(&RX>Y0DmQsv*4H*lFnmDwydAJ3O3p7ZsUWvz`e;Ej4R}w0| zOK?e}%{Q8C9d9{$WJT6z-2MPg>$RlQL_(>@CxB?qullScj5(YUm?`+0%W7-vmr?AE z6M~-lTyXF4d0(lZGfZ}6L1`zwaSbNF#{)v=-HANwSHAsbqc;OLzS|=Z=xHPkx~{lp zsoCIj)`aOI_-)Y#N3z!Z2OX<|sj(?vz9$=szn$Q=36>#EK3bv9)gnmdRK#R-#J1^4 zsL;YoKf3IFOo2Z7{d+TGVnpTSWM%f**~a+E$vAH+^V7+M$rx_{pGa?10={JWI3in` z%2B?v8rx4U=&#s!HJ4Vux(bx(+{3-m)y6IK9R#u#4WfC;gQaEa{3G*bSWC*}4j3A!HOSb72Nw zzt3PamzU4@X)~{-A@^0MJGQOH8z;rD`%1X{8GFW>PmOc$+#72p4p}z}bGDCM*HEDQ zADQ=bP_AF;U7_DypatRn_-9ml1pnOMin_EfsB(;3Q(uJ4I#Mx9gsxrJg0@+ibWWrZ z6`&O4)9E)lZgg{id-ZR3L1-EHZ63YYWfwyqq%Q~!%5^1S9(dKQJ-wznZiPgVQ;E6T zZ#EjESUZfHAi43JFB*Y6YjTE={f`cFNt`3bC1+Z4r;~sV*d+SKM@Yd1Z*&rS&Tpuw zqN4JNeLxT_o)tMw!Vc(ni8b4lqljvJsQ<2zlOu%ZVMk9P+!>4|hQ(i3{uJ@G;LXaj zo()OqC*HCIO(`u|y$&XlD96;71txZ9pAW_2(u@2iIoJuIH(%ia{xaF_)+Z5lN}W7Z zR6ATCG|E}A} z<*eka>qi;MgNK0KSMgN@Qt#@W`m4#T6ulqLArq#8*lcI)3Qh>U&8ooqkz9+UFn1DU zsh=f(%ge_Y>CWfo=eRo0@3Hhe-4u)%BQvVE>72XMb&G?>ptirODVr%|5&k3AGlsG7 z`b1P;q#_b8!R}adDLgFnlcHl|(VKO!Srb_Q>)PTw9HgsQTUuK~>U_scr1jikXXRnh z`}pqZ$h!Ri0jw!u2MiPd2;$nlHhb*gKw6{I$3FAgWoxW3SJjce!5rQ>Q!k;jI*4N7 zewIBr5^R?;{n0WWer>;zL>jBq3)(eP^>eqN3e*TcGR}?t7+-T~0O$sF>Ah`>bDI6k zKKb5puysq7{fRA@@Uv&eC#`MrmRJA)mH&GB zGeArRkw$?$cj5qad~!maV_Xi19fyfo981Tm#v~kgYp-|T6FuuVs4B8>HBV0=2#}8v z2*qGCBNnP72B>{5xuONm^fUaP!lahU(ipyi3ErTc!H)io>ZqbJLmYj<6FhCJB4GFR z-3d9h>D<23Z#>+|SVn&-wqY*1)kHeF7MXdP9ih)DAC-(cER=;~YsRx=ct#ruRXvZU zv8`T!y6^ZpV)h|_;Yg|VWBt9Q30`t{w!6j)ZT)&42s%q~g&J$g6}j)yV$o=826MBkOKNC+DtM6z7!l)L%YJ@u1RT4JLql zi3`M~v#Gtv#hv~&!I_Jji>qzTwpdVj{b4pq>E#ZHCRz^N8Lqg3nXS`9PRh)}N%>V; zwiwPMC7vbyOEOM3?!z@8@Am71D6-TsCDku&AN9EaG$_EM{Eed<>Dp}c9uo>L4Q;sHb@BB6Lm;%f z=Ci|YotM?-=$0eR5D^&@OSCBe=UxxJO~=f9DinP&g_svqVEtFp5 zjq$wSO6U?=m2!rp>-zb_hBmmp;1l|x)mM2XQF0D-BAqW|qnFM)i=Vz`{_Zrn+E>&^ zxRAc_b%=~z8C@3ofgY^ftdyl_Li_&UVX&X#H_hA8pZoU)|_jnQu zkyUllWB0*90e*T8?D4DX`pnDyF)=wn;2sEQ zNu1U)x>0dMfQklicIDEt)!9nd55pWaqcXjtWJr<$XWJ~6g+ z6Ko1j85Zd`gc2>S6DikqxAfAVbh5H^vPejD;H0D;z+JC{2lCmzp28YYhxr=e!;{0X z)p9Cp5XnF~;%JP)tB2QL<-ptn_2ZT)o|dELI1_gNGXub1IDO8;M-~zdQv7fsh$~Vz z%;|d4`~(xwZJ9CQDm(Y3B%IFU;o;#wL&Dw2G1G>6t~(*`w;<6TmZx4q<B!TQ970`x$rfYAqFr&s31gCizKw9IT6F{8@M%YzK;gCb~fVFhPv&i>~5U7&-o8UWM&kltLIJg!RmzxQ<*PFKub1R#5q-}p^KAte%4nZZ!)HL1Xrtn~h z2W1lN))%C?H2X0vaC!c$0jTjQj_VP??I6>y4zGOWmEzNwm)Y=D^FjSvN1N%q?IQcx z$Yt6oRJXssm+fP@1)&68!&Ak(>oXY005uAVXkPdClAveDPh!^h-EbRwV`O(L zMxEA52+)^|As-=!XZ@aZWYEC1`-k@YaFCOo;rcH?PISJFmX@}HtAGiiUxFvgmIi*b z9V?xtwC=KB03f2=7)i2PL>W8^AZHCdczZj^a&sq=dK}tZS8bw^XQ{ywoIr}7j&poI zB!)ue`*O%keeGFa(5Hfxs2mFu>-Z}em)sfAp5hmEFt!B4kt^onQpyhHh(Zd}>GNy& zB0-#~sd}Te{D^n9SB2AL>bLwvQEyZIW{ zIb}x<4sbmd7?PvsJ|bmCb6fe8QY1$1K59`M_l{W%O}jQG$B{X~;I_{Wk>)yy##pfx_0 zXr!=YQXmDxAxj+>Sw)ze+{QlrG`u)ZVXx9==cYeNPYOKXbDE=|K3ab zT?z3Khn`VT+v6+Xx5lx5AAy3 zmNxHJdB{#aHO1$A<4I5;=v-*fvH$vq@__=cEY_69DXlQ3stENr$;C#a(Petp4rkf3 z_#WQ$uSIoGd1~B*74bMGegno|meU?!p#lEsB&r+bnbvWHF{N*5JU)}54OXCl)93}P zX$u2Ss`_mVpk~2BO!$!yMV4B2%_z6pGL1Fq4nD@H#VrfL0~oDMZH>L;V=431=G4q2)0=7P#Z*G8TSmz7cBlZCP7>GUcd4C2}v$G{Ex2& zO{-{f{la(L1h!3m3H#LoS&HACoSYD*iMV$~SXtv8>f2%a1=0jE&1GG~UI+nn2>yXk ze15&>Pu?~tC@4MqMV~4Xhawy(!xLtq#XkzMXEprWBh)oB-=omQ+kzH&_>2GZUtz@v zS0J@yBDK5qWzv&8CV4#d+`|JRwH#(5jof@MwdS`AHYv4y9fMlp)1PIL`I0npYB*A{ zqqXIhQHC5+G;$J<-8n82l@*! z!GiWR@fwps2;O4F3;XM=JWxqwC;B@u>&R_1(lM7Xrc$P~wctwoklqIT0hU{^w0-iU zdit^$VwU)H-DnCa!I&XdWxmQdxJoefSfk7E9?rj(p-ALr6I^g{7!UI#94gX^tK0l?|Ajr;JNpgmmPpB9T&{2%8 zd3Y4^ou~++e_a{aG$x+JmL!Ukd>}iI9B-~ROxLa{=_@3w9PSRmvOc8Kwqrh@!$6HbwLj$}p5l~^7e3D#_YQz1 z6QlP07JE7xq+}eN&I`QEMeZ@AQy`j-!HUSVsBl2ofVXd80%~p>UF97=@=B+eey};$ z3UQ3|YC@@+TrF|6R>eatQ=2u9_NX`fU)JSD7b}IWLlqCRx0~oV#!<$=TrihmgTgQd z2GbCxl9*Y8$N5!lWsC`L;?~8Sx~BuvOh^hUp60(%B0FaipKT=drPEt&@x(Ptu2!VK zmIdW>Ue9xBfxCbZZXi}LWdD2<%(3Z z+c;e$9M<>e>XZq?m%@@vXveB!=W0cx{+3vQ3s1r`^Sb!=Bxa8J5jr4u zb~bSeRp>C6=(|s;o2J^Y&uC9THYV9Az5=Acb~X;hKh`@JObNB39AU74^Yyr^%tY$b zAau)8eUE=I^wOPWkj#%@6 z9V8xaZB~!3E-y2yx*oMWH09(#AiF8P26OotU3Lkd{$Y$h%Tg;#UEi064=h4v&j^AH zZuO3dpkyf>@Z>q4q(oI~bayEh<-6ZD7ERuqOO1FaI&5 z02!g>C(97~5J?7-bKk@vZ;oaGa7Pnh$Y_9>{yDc;ISbuS;JNw=Ljos}`p@_sQo&4k ztK$QBPXqmGePG)h4o_b4AmZ3lv9hw+PxxgVQ!@o9*h@l#)cztOrSkRi6@i!y_7Gf( zagmwKx;??!?sUt;+8?y*-13P$SnXzq{|UBh6K}27V{9_?@iBIiyf$$k$qPC_A8&th zAeec#GmzQ+cXY*wlwt79sEQVUNfRqNB5WWvIsV5`h_2l7>-jcpo${Lfg3*y(#ASL=hzb@h|!l1~SmnOe!YdC#-xV~1g^L-q-qRnyejL4^>EtxS-pdN$U z_Bsp{4uD{kuAfoCreV$RrgA;K%iWGUpU0jIy9yf{3#8B11Y#iLz9&WVU=4GF@;`n0 z0xQF8vj!8Gr#HdQfW|&8#3SLp>hKaQrIcl{lPgmwlZOHgo3iXjtAScKrt-V6g->P; ztAB?y>nvVI5J;V;!?GkENiCd$`?d~`Rm;jKNk|Ug7kHiyUeH(wdAxtOHJ6mQ=2lgR zo*R2|2$L!ewvqYRX9M?Ydu{#D&OR8PCcRPttGD_{l)h#;#tm3HWH6^NNvX^}y;VM@ zKDM@g>Y7?~9l8I2ds0$v9j5WdrBIdEkUBi+S(w$AKA6SLk@ac(${J&V8=0a5O)k`8 z1EN&?iH+=bXKVI!*pJJ`93(=3#b3${j0~VpU(=hxvjg(JLF;#P7_08Tvo*{mWsRA4 zTSk1;OcVGVF32^RQX&A#9{^7@|J+}CR9VHsd_@8ahZPD)0*ne`&A-g$ zmx}UH1rm3cF^v_cFw~PGkhFmo4?H6FnQ8T1C!3FZyP9#)z^_MrkRb znRF=U`rcP zbNqPNIT@Y4P-AKu@nqaB5!heCqbcU_Jp4_b)=cT-G&23OzNPVam=s5LP;mi&34dVn z@to$Co+o1h8BiG*2z~!AY1vFqcx%*-=$I(5+H2IUKvr{EbDy;E?C#gyDT7uqrf%GJ09!z$zjm}Tf_2U~Ep^8T zug-yXo5zl_Tp}`t1ij7hy?3XYdg$2gfLV^Z8+;9egDxBkI-+Zg#3IN(WRXnB3p&?p z8Ggx5_S|Sj(nVgqGmF$+ zrcJ7BSrPGgoEt$6+j)j4lZO)SEaT`HQJs_HY*)q=ipV))$8Aokd>9(pezW&>a@YxT zpeG-3BPk^H5QN`mqnMLea?XQ#a$GxP2nYzyA2O?|##!n31m-qKW#yGv4-3W=2;Z}2 zoixs8`%mf=GYf+yoag#@or-yWt1iNhyQGt2Xr}w>H)Enm+CmsyY06_Z)DbR@Eay&2 zfS8gnyT|$ynV&{wsih8sl1gH7*6HZ*u>F!X&!3JCoi@E$drr!1P>dq&fRq23G=+lL z(4CwoBkJ}lCZLIUuWr>&siLcX*RdiMj`a5X$AYynWf&Eql2 zl#P!D0Bm~S+@$iZIbPY6mhz0%o}A22++od_OA23>6okTbbA)r_$L!;&!O&|8W-7<* zueGnqV@Rx0%Mk*{cF^b=bnTob_FrzAbp_===$`c%x8IHk+5%x5&!jPRAc5N=#T{$o67|y(x8iu4+*sTc( zjh+$|7RJyi(m|gHZ`H(p5nEVbp-T|a$bCuMaD;gOofo$aok_V~O!$#N1ywqzi7;%5J8FJ1=~x1!;#YnpP_`H8oR0LqpN=vBo{JzL;B>2MXzL zh0DrBD%ZP-V&r=^?W9fYJH?lt{lcdCGjJXKvFSyWQ*Q}iZ3b8r#L_k!#qF-Il$3 z%YdOA!JDTN5`55BPY^=e+1rqC7t|kXl(4>IVYiK&q2b;H0;AhaKV=BpuAaJ%0d#D; z;vwlUudJu%w?%^&_gxj|)nS!HzS;jHscCN_Q&b6T?z=0T1?_#%_G6cl64Ygur%UojgIKAqDLf(2n$s;!zw=57>w;U}O}|8XwIV4IorCeCB+>!< zProaLNTxAb7%>aVxYgAAm)8`?1rTsBon<|OZ$5<&?5!{Ku@V;VNAlCN5U{xwj$=#3U+~r3uc6hYZ z>{qZ=m@yima}Lv3F@>rQ?SGWYN?u;R`@n9L^jDHe-D-tj`OlWUA-m4?+JgN27EUAu zSp+tgY~YDndR=R=glD@%TeiPqn<7Qwov3Fgz6}{`n@13XhA*Y0b=~WC90->^*j#K5 z00T6u-3)hM2K%T1{uWarNnXprV_?_TpI8C{0z74d8+ik zdu(v?P2=WFm->S{l@uwx0i&5x75<2pYUYf1=A@UX8~XxQb&NG}SeWXJT+ z#@BmMfic3_Fb(4Hsh6dTk_=g(0nUB%ip_-5LgoVBr1l(N5ndwc6zt32E2 z@qsxeK{`zrf2E{&Zi=GJj9ZJn_uG= z>5;n6$P1k-FTBG)9Ic4ZXUa>qqt8S73OQ1Dv1^y_Ecb^9^OWJwW#2UdG0T9sNB?Ge zHM)%E4enjGZb&@V0m5Z=8k7Q75E>PFT&pVxjUj&U&!^i-D6K>QbfM3{{rw8z8Qz6? z?%&L~b&OPfIM!A+UZ8=vl;=)kITtg`wWe+@_iYaO=udqf`8@K^3s@63{jP;hx+zMb z`*8*l`}L5!%~?mWig&NIT7(30&&;k?jFqJwa9-hta=xSAvZ3IZLcB%wTyc;9yRC0L z-HE=MZyLo3o-q`Uc_>n2UWE2-8Ac5_Dx*zhCGusltTs9AV}HJT#`&&(3Nb-##?Nq~ zZ_VaCnj|D!v4MG?ogQBdpVBa>WIi%7GM6>q^*pg6!anD@ZKSv0M4dgJ?CadE3A@fV zsOxEhZfr?}jAg$}1zQGd*;Q;FIW89|rL~@i9K1H5ED6NuYKPOfUrDE4ZJS$YZnt6( z!BqvB-x8r41nS0rH53rL6Rj^ZT&{O8s;{UxWrSSgIpF8_-rAVF4hWxn)O1W>t_H96pH3HOs ze0AYITDt#ya48^wf_65aCx zZ!(is5S`n90(;Lbd^HutPTk8nlm$OQ%nYK64y4IEroG>o zTA@z^mMPr|W!kdh$a?5CQKB1OWZn3Eq}i;fGy>3DYZ8 z#5_l_66x^6z#m00#>-@2|J0nYW{1Jdf?RkZmVqUYym zX2+fZygzR{8(xaUB98qy5HUZOrT#`5A!*5sD?d6emQKe20pu*j;+q?FU7+_B*J`zu zg{9?jv+K61Xy?u3YO(cZV}Gt8hCnW0le0g<;NwIE`^U@P$mF>5`T+xj;djsp7lB;+|gfXr9MGMEUD@oBR zLZOk+pF?Ki%(ysV3-R}We&?Yr9)IX=%LsQ(V& zw1}0A!4_dygb|1K5>hI^3NR#agdc2br}+oG9#`!qrq6=R>iY#q`wyK1{QF_s#=Hm& zL5SZZhwcjc9Vn~4Bn8CEFJe|daS4XhV+7|yJQys@c8&qKYh>ufi+bi()m1@2${=dqF#T;uNlHoR@(})CQ&990LOI56yTzL3 zYB~7NkWpRr2^PRpr@u~4(g%ljgpVT&`wu!Gw=0{=)=8&slPE^otq>w(wdHhS#J9zH zJQ)gSnLKOZ@rqbung+(1UzP`VJhQn%3^{U4e?4M&sC zt0@y1+5~bMC|{{!ScM(3RGVQEvW4^(8|FPb^gfdCoFtHLy!uZo>um}d%=W(s4mblm z!G;||M)iG2prvlvq!LuxdTBE2GA2=IfFrfsXw;RvoK(f)>Q9`Ad+{zzGybn|(Bf|O z2}j`?R;%guu|!XR>p?;OV~HYbB4#Iy6zR{qMi7gBC==O)t!jog>L7eISFfk*d+`TT z@td$rB1SQ$-50k7>~N+7G^?C;Q{jL>)6}FJviaLjw=@9%RI?60X)Vu3AVB|n!OTr< zKJmm=@CVqD;Yx7s(=!37Qt0|tHSgT~{LA?SFJsDEYjbTy12?p_`0sQW5UeERqfIl2Vy%;s{Y$-G5@GRJ|q%OD;CAx`)2Jo>7*pdYp zE-z%D(rR)oim$j@<)L_0-A3GEnkbsn{G-hscrskb9KOw9bX)A0gg0-=s8CJST zIg$J6&!O~@lrjY>&+9ub$TOfHhSXEjB7W0)B#IC>t{!SdDPf*WE$63rUh{<0v})va z^XIL+NV0~Q+qfN)DzVV(GKEQ@U9cxd>)hsp^`>_5E+3D68b+Yj3$5bq6}&SuVqlMc zb5ZMHPFhy7?`jP1)YGe<6Uf=O7i(055>IK#5DC=2Gfk{k4$?!$4W#h2Q~F@pF6{3&evBJ3Y1Cj!kS#RY$mEa0 zdlTv^uj%Y0Su$js=*kVL8%6HmR#J|0`}85(sHNBh-NQy`6GeHU{8CQoD-Mt2^R$2* z!O`{DC0@d-nzy6?=&dKNxS^wdv(B3cTAcSMORD!2%pD%F-z-wt?g1WgT1vKS?tmcy z{a7s{HnL5uBqcKm2?@7anM?VEsi0$S6|ZK=YD?W8%c0n!i42|wG3#advZ~g3InlTC zoyosSUtbL_um75*+OjUQJN_^b7u}TT;xyb1H{hP<=H@i(@Jg7sOW>#1_ z^`wW?Z-?8VfnRI2C`%C)|!jw6OO zKLG%fc!|xx$Tq6G^rzbi;^{dgypnwpwHvec~wkuZq4W5uw`P<_>%cY(*S) zALFgzpQ@@eB{K!U$f(HlfS1le;8tOAmLj0_03~z7nJ{1UZx2U*F2_8~!Wx&09 zzw_7f(MfXM?A(qi2r=VAEZ3}mY;WZy3RxN{jc?hDq7(LvwDG^ak_}q(VQ+?hr}vg* zX4%o;TQ^YtLtXXZ&GlF>^`yK41!fiZPXmp6?{5{Aa@xS;Y^ctR!|8CB{9Gs%G5;YddzL|A$;BOf1~k`Ccrh^8^&Mm132TWbjU^`!s# zfTwm(M6?=kszl!B@d`&Z`BOMgtE!xhL!g6p+vAs`uNr~b+@ge&M$#5naEJBBwJwPi zFjp74lH|~f_)32FStG`4&KA||#nsH@pO-uLj;IgZ+g%$U_^(dtGK(`kEjI!X$ha6d z8LgUuY1wvlt6|#X`$7Z8qlqT`3W?M-#K_4~stxpnF`>O%)r+QeEfs1YC`fkY+EE;x zKX_LZ+%3}{fO$8b8F9x;yMA}xxS5VKjSyw>g30dIyWN7ifDn> zJZVq>h-y2R&07*3S{+-xj}mv;Eq$$a2IB?03GHE_Mq01%0Qw4up39P*F%t(m*(KWR=L(uOS zUAy5D-_Hw#gT{Q$I4TT^C|{Htp24lhAYjUXA#XgP8e{9IRfe=GSfoOCd6k=g6hXpd z?V?sUoZpLaAoPid51Nx3yjWos*4ZY(8MTt%S}bw1E1#^=B5qLhy6Hn>sTCxif|Br6 zRplLvtW{U~!yxP1yJg=D=|s8-Cd+9FTO1h^DaWIu>EO%g6*F<)LaO zTH}_v1P@p;6Ng7BN*%kNS!*`k#--1fsUe7MzD-^Zl>u@Ub2wZ&maPLowyg#~Kl}Lj zsJXhjzHO?!8PqM80{|7w%oAP-@s-h{S0`WySJ_jL=mD?szcCdf9WdnykwSIwZpwl8 zIT0FtB-+d%j{iE*7#j$M$c`QdQMxN;+%c#ZZ($@FM!{8+rqzi8>9{Yeoi>6ZmugC4 zac<56^w}`DVc|x=TRHO%i4o@?dFTE?s6y}nrbKFz{5$W&5dY0hEuHz}p+NUQa^=R0 z`f}v#d3>6k5vSQo@u#W=J|w{O%6!>Dtl-U@47voQqFT1SkYPS^5vmMjd5-!5s*#rh z728P^-GOaGz%5vVr}|S;6~5AQ%3$RdYB?iMr_6xCE&Jc15C@4OS&cCSE5@3WCsvJ6 z5R*AQN~g6f6DvC;-p{VF`C&KtFQ4%;-DM?2;;z|6a;h5swDA8<$u@1fNC$Q1@ZNc? z)Soe_=uABfM{+XM?rgFxSS=oAki*P=@7Tgb29aRW@dGlzwaICuL07XIi`iYG zHKDezq?>e#mRcjfMYkpR>4!P06?yNu4|(q}UjP&XBLm@u&(}5SaW+G}MCv&kBK$4K z6Y%xqazlm3YB*odM#Q@9CfX*Rp@-pnlj#dZn`%G4M7l~StsS+}B_OL4eW)2)gdix_ zi`_w{&-eyqiBQC(68{IZ`HeE z=^IezcYXoDFc%qplI2y2OhJVLtf;l$WCfuK?`FI|yHcVLGQ{jq8FV&r7Gj8D!Sg@G!D zOIN5&rFgOW5BEQGK=o_ImKMmIjvqI@l9E+*`x2R0Yv{>_|IzGVw{Yt9-)F~2H%B5g zs;fXT^6&xJwkt%XlN9~bn##OA_HRN%r_fqMlxk*_-{SvsMk=aYZz8YIGo6=awOC%! za`Q;!XJ=zGKWd3mz=K_}E+$~*Nu@!6({PQu&_GyQrU_~z_2_r%ra%xa{QVURLjnZo zW@7v@TCW7>B?2iu=J$620RXOHeP^S?_N&CG+Abz06LFiqZQieIV0po$+RG2DU#GeN z-FHg(7$qKiPz1I=$m5QQQ{70@HwVJeq`h$cPeB!OlB+z5p{PVD{L_n&rk5DBUsQCv zC!d;(XG3p!`qA)VUeiRxrR9z6j>*+)Erlvh;5b*AZmyFzdSxSNS?lKsiHM`*Bo3a= zf zh6FlJe+iJKt`$x$_Pl#~u_?~+7(7&jpnu^flFeqPjOS1RdHn;V*uoOjU(SHGoGy%u z_@kexCJ!0_bK?P8BHymAf#j_(PxpOs4B>QY6a!YxwV5)~l5PujBUThUT!lA&xS zI3?vJ=a9@)X({O73{TdRy~w9>yB)Q`nT=1k)BqzEQqv zp3vWA{kBfi-VZau(Ee}~KUl_U?^#;)yWhdKF(rj3X{6BD*wnL}CxdxzgOrJt{_oG{ ztLF(T^~&-XX-XkI7_mF=ajkP_rcD?z>kZ>QqYiI7jirA~(vr>{PPJ!!!_fWdOvV0) zFkjl=A$+^gc=cAGY{Jy@IYDO86@KPewAOoZ)P2LPST$#A(f8v1L#Iyl?&5V|9^3-} zAfc?J@Qw-)==CD)1P7401Un0B2V%Ee*r&7E8fV;fxGX%}oZz2s412*+ew_}ZF8hs& z4$3{H#Q*qeT%&OdJ^;zlk;c(ZB%erqU^ZoVN zN;+=_isl9sRW$r^kK(S$JBdQ|=(GJ)(cNIPzCSO2-vT{ z1^peQ^+KmG+8;A30_Cn4pjQ9dg`o1PdYhvevm6qR_Udzyfx@4Er3=bTr1&8oE)PDA z5uN(i;NxSfvX_^J%GXFi;7+3;ajY^M{+jO3pN+<^fn<@qHkKblBvxp#G*G{%xKBnI z?b#KGz-ztk^B3=+43Uf?Y7a5y0xQQ3Idg@r^iN9}#ZDh)=>$z86elv}|4)c0dNIK+N z(g!Vzw)#r?Pn|Ve_ky%F4*51L5+y;ubH!Gb4a^~5sJ#3a5x#%jFrwhNC=jFLmE(F$ zOw5E?jHuagx!VRK=%XorgGGUv1*L#pJu|3ny17I)i04>*l_z*;rv;IsUMjKhbIhx0 zZi0!FZu{ZlH$}{px*=IOC9A^=WKS)DOTuB$;UE>7Q2jQrs!K8jeMDl}Pd*(ftX?eL8f8t>FP^DjvJA8Acqs6B^`x zcwc@g`CEAbt^;>^;F#>)3`h+G*f+!2g>C&iHOqzxS%?Kpau-iqz;x&Zik@q=)TQcYO3^`JBxSCYUt@Ll70+@lsq@5px|nD z%Dy=od=O}{e7Vv4qKd{uyXm2Ci;dau-%|(9l*K8luE;#-UWpMc8gX43Pt9||!(tI9 z&Ms6{WcHcyYfhA6^LyccRMu5nz>krfcQYGjf@vgMlkMmwf%@70ht9rle$n^-Xi;xN ztD(Ts%UArh#J5#Sob~U`!s97w+g^~{rrt}h)7uLC^<`Aa1A`PL7DUqWAHC3wLa2P;iSeKVas`pA zyUZ%Z%UHJwVkWiyYhtP!{&V0b`976-$GeUWVaKskKhettL0dt`3)ZMnz5B(hj8~1i z#xz+{JA$tQCiQH(+99-)H3Bb*uB0B`D>vU)Iq>Um=?TzM_1r3q*3!&6$;U325%XdU zzqpC}iH9F(s%1=U%&x7~Iy_ufl=(hYwAZ_rZFUbkWs{MUUSuYlHSAPh^2^8bP#WGz zV#m>Dy4h~L#NU1ON)ao!*u$>!#=Nb52hhOC%gaHZ+jY0;d(NpxN_0d?@_)!A92i_3*V#TU_a#_Y_lsugfP&ukPm?PYW=cu8{{i zTQTHjNQYeFS$A2^Yq|ysr;2qZvJ_b+P4S3rg=n&->?Hm(%GtbbwtU#gFP0o>-&*52 z)5b3$=Jtm_+)+&XA0KcUp6Q$gsu zj{wgYNlYs1=3!X>hy`az6k8{qUKDtV5dpSxiMO2RZG}=QUuTuBe3>W$El|l6#T1?h2Vm2URU>ygFL zksUw+N~}a2@hGsf@VgM2whd2|ASWl#uwi9IOMCTIqs0=K2zS+F!^&{$_G#V*Hp z-GI}qnK)Luhc9xvvH}*DhC{n^1p3SfD1W_R13HtN@gv;@^t=2}K;$PgCENDlu5OB1 zv(-I`Z>4ngVo9#>p(T> zNbGn`@Sw-ee|%UlC58z1?WoN;K{l-Q{kCeLPaFk>+iL|)$oBneT!zMW zLV(E5)#?+O?>U^RYMF_qVgz`RF;b5I{9n)&#jOt9zbHxJBYTO-M}IOR{~SM0Ejc*? z+dCY@yyQgcmzJ<0eEau-qrSQLKB%grXkx$HQRMtmcCn37Zad=$8Y*BMk@hOp^z%Ox z&30FS#fS4?=alt#?;i;JjnDH3YIo%fzH8X}^T~&)x4i&AkvRdM(Ya00*Yg5~NhM8G zeBCyQDkC;u>z~~mvuYGoQLZsu8n>?M!q-bqQ+uc+?9aMM%iaxyF_jqKTR%Jo`fq}* ztSl_*G%9eF)YMYex9lO#zp+B=R(obP zf?TlOh#@XS+LPtRTyC>am-~XyjR-TzgO7;!?k$Lar6zMjLvz_&ewWJCO94e3Gf{lc zASlWxdAN|N8*{w6e0}PsLfcdU-Qe!+@BO*fFBVSFXT!He=6XL+P-yz;wo|LGtvrx_ z(fZp|$^5NlqyDUrjWn)Aku+>IBFHJL+>MlOb+-eU9Y)?$omn>mZPD(^%=!x2v_h9S zg|y%@`2AVT&n8kP>n^+-Z178y)*R71vua9A(QelS6AqQM&A@jXg#%C~9I}JYEI+Y6 z2m?#{4xe`@o4)xWErGA=i+4`YLOMbc#63*DXH z%ylvlI`)@lC)sE!REU?ubx1X zYC(x!=F{UiSRG8K+ZKc?Gy5F@t?uPx)Ld(3DIcBhVic^%vKFiXM(;wQ+Ip zBjK;xX`ee*7*|aj<3jcdU;X)(_2d22*O%Twf~u~I$kiQ!_PRz_dB3%$Za(gL?pFv; zrZBQ}I(JST07akx(;Zlp%M`yCm*a?~Y>koKs2sS6;y;ywEMz5QmA)mK7`KwHL{0CN zzw8z)pH96U4CE+$0+v9v76qfnNY5F?iB_TmQa+b+W<2|HD*fZ6%)aVGQgABWd8!|m z{Q!1Fi_9kuK`-UGWJ(P9zXNR6dkj6Vmm+uXw%@PLZkVkA&K>B25Il!?Nt=r?)! zu~gKsopC<0F@J-mRc4x1dCRJH%h^LnC#g96xUj)0q-VYbGrt83C72WM{Nj5Nxd|_y z$c0H^%nNDq1BJhL^>A63iX~?@R93uf`Y#yJPbLnRp^SxWicnD0Jfs;x{W z*;uY#JxyVMiX$QZ2;W!1T(L#3q$GHB+jeH{dGX*^b?fZ%Y+l}`@&_NO zneB%wd4@0Y8UCB3W_uLLN$_z)i|t%oIWYRGp1#Ob1sxt%8@W&&n>CYv-E@V!KG;Ex z@({rP;v?)m!+GyTTNM}ZjtB=Wy3dPUsV}wq1~7+7z+K&bM%a9G!rZ z{C3Z(kk6l2Ol71oby)|#`}2ln>wVCt_1co6RsmS&)kxFt@nE=$0;6E8R78iYPldn} z3W~yF#1ZNuE5l!nDAPKHz3)p~CVx!8F$9A9JFjj1{YlALr(fjd>x>U}H9(-_z;4&* ztA3{x^5OJeLbqQ@n_p55)ITlWYAT}Y96a2XMixMcB~Ty5zlRdz{7L(LGZU&ybe2HU z>Ei`5R|j%-bX@U2YDT2zR`(cj|H(H{9Jkf``--s6J|l9=CH}&UEs~Xyx&CbwM}i7q z3=rX%mGw1%WXm(UT^JUJXm#TS2p-_yt5PsX72NnG@mKBU?)$+TMhI11RW{qj!6bP{ zyLeGv1n3>#Q~VV{?g(PPc*R(U%#W_O>+KWtAPqp@zenmunGW0IIPHj5sr``wOob*= ze{#2(!dqI3EM_+apoyj>CU98l*JeEzu(ld9TKKH=a_}c1=mYXAv)n93X=x?SrZnDl zust8KZFyA{0>HlYr()f*H9Vl+1-M@uBKpi$~Et7XJ-GLyxXSlLEuSd=5;}w@cvrL{(h-*F=tm*PLRLCObRo1nx>{j z@!Q_7s?jgVB)CIxhu|&=78u;!U4y#@cXxMp z2o52*y9^p!2Y1=wd++V;`~g)|Q8f3S^Rqs;n*olYSG%SGPDYg4d&`6KlfD7PAHhTF z_#Z&7Z!I_$mjy93ubZ>WQ`6IRBi5WGg0VOYN)Sn;S=F-O3Q<74E(R0n75`eE)K zLY9#mwZ=s|CngAa$)h)W9uD2arN01*7mQOcy(k!ncz3qVF(XBzD#J@Y4zSCjM9F0 zT%y2NCHe&#*A{u{cirF_NQ%2aB&C27Zf6*kxSj7uyyZXY(6y70kYHyNSc^Mz;$_5+ za0eyl*K>3;GwZy79PDT?XNpmGn_ArSc^I>@LuHY+n+k@UDmM-g_8U2f?Ub+g!nQiD z4jv@_VNGA`OTPLFBb4+{qn#>2E>Dt$kB*+;d!GDtbB3)3tQSdJwy;$A_V3sU^!bYo z*Q|!3B3K>!+twT(p*QN$ypWf}%-h>rkBsr;wZ+MAXrl}N3~NBAbsIjjj6wK z#nrKlDEV0j3_951eDGA2KuwRGsL#4S!Ach(vrhD(!20W?7wyTFx}&QUeq`oHcH6nWtmAxOQ0f?0suk?JxVD?FAo9o z#EX5n!p}aw(i6Fvk;^1rzXL;A$x!0AI^bw4rX_qHpl^8(R0$S( zu#IBgyM%Uv_|#3FXC{- zkFUdTPkW$$=IkS*!h-2NPn!I(|(V-RCd z1LTqKE>|--^v(0tF9?P*Gt%hGO3C~6=)WgvPypNR!v#HmFqav^{!XZVx|=LwcH@TP z%Q=^}_vxUX*V9dIrbyszgeX}RRRV1lI6K(S*y?9pi~U@wNXxqYtgDchPz}m`Gqy$d zl&DQd0_=lNY{7I?=)T7{fr=~m$%*_max_R=iyxZB%K!%n#@S20W}`p>=$4ybnjp0I zQuxO7^#bxwg;38X*w$$#+S5cLZB*KQOE4t03wK?gTVPkn;wVR+%w#X=YDNYCYPxO) z^nb*|!T2@o%N6^U)l^v7TG*mIcy&cjkZOLX&!)^CC{&G|nGmxwo~cHnvEqLt1^Cs+ z&!idMk~}5VmBbUW!$SAYPH=nAHOywO2f!wP`Jg@E(aGJ#?2hh4ow*MmPodz6+&%$B z-zUYRkttR%!3{#s_9A9zlNJUP-Lc^2cMtvn0_n1d!6@T!0Gf40<(uoP$t>rY-wBKS z4?{*3bR(l$xI$ab)$ue2ZrnAFI1iqk6FP-Lx%4julLCAWZU$Rd^$a9T#m+eA2e)fi zm6gDRVPlk#zC4o%>?*D1^OVcBl@(5XJ_dI~Mj14&nE@z6EjdxMu>Ho3THb?(+o->I zpVzjrmTs!QGiTm)pEp}rsp29q%f4Tkz<*n$e=t=!E6e{dD?`B54Cp*#sXy;hsJbJv zN?JNo?N&}qk(l6lv73CWJ>U0*1}s@~q6K)o$!jP~%d3{P1DG&)I zssOy4>6aeCoo<99Ahs=>mavkanTfrqyt=x*usXTbBf8sv(^A?%4;3$%wh7OVTySUj zArcHa#myA@JKHLa(fHHcy)QI$J%vct5JHFV8QYI|r%Z@dcT!eWzF#Gd@g6Uqm&p>T zM9jIVp1BMZCS`$R>^{#7euw0x(IwY0p9elG*T-m{+a>R=#|^H&_eu7RH*Ro<=4Qn9 zJ*N!j{_@6s^TKjcW6p&f&6bVAuYQX`5dc6**Tdo@HV^hK2{0o9JZ2*O7}B>TY-D6a zfgaYjYMZib-AwvxYC$GL%J*Sw5Zr=;1K*?GE{YT*!N65dk>F-afsAK%ec#!MLXLF$ zmS;1&&|!ma@clj6BdKlry_AuZmF2Tv)#5$*d1jdRBhC*CD**##yK>iZ=B~DKI)|HI zVY8;*{7-d~6f^%^+6Qmf5-U$FqZrQMRB@d@zLnY&KnzxLqt-iSJr zD`{OtLruM8=@(7+TXX860BAY9o!2+{?;;mB7{~&Q*14?pDF0a?%j(8hlmFwbx)?$% z5qYtpK-Z`#FHgB@FC^n)USu4tciLMv+lA^@3XAJ7aw_C?2j*7(h>Yxj0>m0?K)eA% zFtIRtgL&_tnF*Phue~D#3^3o2F#e;|uSX1pLDMq{78-+wMOg1jI-G^ZHI}+BD-JtK zd_JvVz5Tk{6TFUkK*nRGRr4}@lvysavQlZJ1S+4L%)D59Hu#PM_+}7W*c(r=d-q!Q zQ86pHt?lt>WTYJOomWg1vtiz{Y@@Ydt00Z7yZboZYQyb3SxYGU;gWt7vUyLr?cWo3 z-Keul8p{O8e=-qeNq^8f?oTk-`GaUy^ks4$3Sc1RvCw*Rwib$!eoLfq`KBL5#r7|j zlNA?=<|q60GyVT$Ct48^o$og{(=V4Wx_xdhs5yFWV;aP-;=h%}eIBUvi2PI_d(mn5 z0PY%&5qOOpw{(7dd3E-_wf`W0Ty?{zBm2~%H@SQdv8ulXjg&>XX0`%WsZX&ApxbX> z*=Hg9P;8C7A65{ zKp&$)6wZusMF|ObfTt6K9DfN9Yb4@fVQw_dPd9POw}R?(o(1$aT?z#)Jb-W@NBHuq z+Ys8K4cB^o=*Ke8dmXy~NSurVZH9_(^(goyLP% zcdIXpebL;8=Pz%+Jr$f)oC#`eEWI)ohtsK>t(-q~#kj7kh8bB5emBc>&3;*xX6hQZ zY*-6WcCM1Ka)6w!|CPWlsr z_X;3?XW}a)MAi~HAIs@>wvB3l2a*5N1cyQVB3|@KX+QeRjX1{aQ8klk=aa69(f7Wn zx2%T+`mTY2rtGn??-(y$w=My_`nX>{==t0}Jc8`HoH-6a8Xib?s?ZSC2Qm#ic@N|0 z4VMLb5Xe8@jsW5#4SA8OK1bV;1B4|=e0KglCJS>Xm3WY7aI>nZs9cxyp*p_3f-VOp z^wa%9F;LXV#s%mKfsXHrMjrhl^c#6YPVxd^5Vq?&4n^VfHl#_5C59^St zx>f^kD#Vqln@7RvZU>~`+z^I~A7iilN6+!8aRrD-M=lE-#Ez?VMnaFzvtt-<;3d>A z%~d}d{7ojl6%UFz@ylAJm_KoA@?rrt-(^zFVvvst zrpbAawxS^oGyR79eAD8|-ILv@FU;)_fIpIhH;WQ|rnqqdW6lEf5$X6=2;gVTnZXR@ zrwG7ZX`r5d+u1>J5O_G)9{og7gk|l4tgf2(BX}FqwN;D1|1MS@pFO@+w>l`^O!(Qg zhtDM|f1bU9+jp;2t$4@{M0KgsYhePM#QiHYVqQm~_Sg_Fi5lwt!uRr*bo4R}Apbo= z8jEZ?wC#Gae>bb0T>|cb_}H0g8vE;byD%D3P4yNJoyAW;-2)r(_w`aE#dpE;LlUC& z#~}7YURPIlA=pNYYr}J2NHFK=)Kx{er6_7?ekGu`N$MBOUqrLQ(rAEi*Qq~zFp0;` z=NhT{6OoS`BjFCBdi?Mrm(%iUY9uH@-=Z7YL)gg4`;1xXv5F`;^t{fuYJ4lz6(DOz zCfs5G_=hptbS*w}X-$`G4+L?>2U|Z4(q|tNeFvwjcXPy};2KmmDG(%@WyEg@|2Z3ZlbQc%#KU@*?{8SKEGzie&c*Nn_7n_2X)*H4DtQa zD?yvNLyK1dO6UWBpL#r$yPTw|a9hrey{9J_QQ~t2(Sjbh0CPiLCgWLgqyt9&i%h5Z z(xq0n0N&HL14K{5Bg_bf(LvH*bQEDl98@?>>zcl8Y-@sd?O+#l1#yBoaS!(^QRf+Z zQi9(X*oAJmX?AU|4f?e<)$^u&K^N-rDD7*u?|hKubUOdE>Nu!F&lhMxKHOyAIYHSm zeHeCR|BbAQeuW(vU-;!?USjq?@1fW)c<=c^jVOzSQ~jq8>ttvj4Gr)PjYBXsz0u{? z#0=*UX#X2&Dnx_ul4Zkk<@;%{*&NS3Z83$e*V|*Bq@FYV5rQOHTXKLruUt@!;$V<- zl&#D5T8uy&cqtIoMO=W_bDV$bVpeo=SxiE1babH;*vbo=uR`O;5wLmCae zc;}!GfEf-o*~i_!Nx@d%)v^-)nUxjI%;e-`)`m+e@^@8GUnyx8$>(g_LlUa5;I<~W zBC+Gyhu(Vg>!6C=&v`?T;YJACjtHvtR?%>ky#;=@$bT(j~y0h0kH4 ziZ11Ml_%C}nwsg(a|a3*pcWfDxMuqju9;-2`~>KHDIQLn$4(k2oH748Q~)4F=C@%a z#Sf|<@zE!{+Xr0lN3D&Fz9V6aTK%d+&LJuChX5C^wmCU9ljDdhl%j30wm zo=9N5%6Bd3r^cGv_iK+dd~u z>$#75$9KiV|2x>_c9oU3`1%r@Ve0jIXts+6ipy9Xz=3s{N4n?KT{I`3)R@StW=ECF zaoIU|85j#KpFXW;KpNa39+9nS;hdTNJbdn^Z5q)Z4w%cAA)rrYd^S10%_r;bo!%F~ za$t62N+LKh&6v$6CzTmn|+K3TZ)3v`K%F0#SYDtbD)c3G+UQ zp`^3z%B#~{L9Na6{!|-y(&nx&iwp*dn9LTlwgjJNqC#^SggyfHkh-4#MEE}Xyvm(H z1j_U6t$yvQX$$Ii?RJL$n*{)$vVjQxi%-=VinXe{09Qb$zkm9a#7;CgsuM9qPH0YH zKxJXe9UtWFC%}w&LmhzFJ6L)Fah8T{!MEtnVahe#mzw8w!*WasCOl?-)n$wC8H8Qb zqHF)(F!CI)>pJAxW5MCL7J#)vEY+u(OyWlNMk5#}9B9bT3QJL#Qmo?3%Rwd@6Gs<; z2WG6Rwoeibrd8V%c^vEJusn>>s|!}w(4SEgxm9;%t(@Y&c`Uy1cwf#{H3&YKOR(ct z$t9uC1YSDmSXfwamdsjM+S;B0whM-~iL$DlDWFDvqJ0hywaH9nX;}6WR8+_+EUZo? z4inFp#$m2LTQ%85^~%|gB-{SW4u%$C;LpqC>P(Dl8#Lc%@{&PfI~u}#SN-UD2uDge z-jDf>*VoMJo=;h)wOTvkX!Pj`e|TDv|8k;%)_BvQ0Ujr4`p#r&W)ujXchk}CWCiHeuB+lYMqPU*E#d>rQF_MVsCPT8d> zOFT{XAFkh^fmE}HAM@JQg~DFH;C>3$!DD)lO|_&%>kv6~0~O^uHp8%X>?{^VtoVO!^|}2?^Gcjs;`^<%CF}GZQ1N`_-Zz_UW%RXTb7nVU&0Y z!U>@61~GbPY=}jG{iY1*{iW0=2M09u>I}YT1zMQb7+dz-ClJgpn=U;X8?s*^LebK) zvKk#R8RcY1>&|V=Z)BfJOXO69N2OkL%kY0D!dp}lNvHNA_%Z1CeCadUz9$;KFP_az zF91&UI2D{)F0Rrr=&(mOC_#Lmu~e+@G&Yl!ZN5r@MQRcBdJC+8ASrI!B6Z zYXG^R1J;7@9?civBhI|fU+vk^m-SgQPzg7!jz9nJ^AGp-b~UUz*Gc~(t})b24Pk;A z6h4P?(9Ud6;>m#+m1@*mOiL+#z{XP`AKe5VP(vhzd97wu@nwCzz8P9o9`@w7@P8cx z?7BVBb;TUNhmZ4g3W(S6Yj2!y^l&~gx{daL8V@BPo&^p5PoK-n5`~iD|8#%i7I`o#Gc!H2?{-!iMop)~3?Bqf$^vzE zd1;HSK!vd=Xj-nDjZQH>xEe;3CC&<>2_!DMOlnPiYVeoOWFGvJnMuLe zvcdlT*OlyUgp5S;GY88Ve~90;pAQA3rRYcLk3ynwvjrZe2lwCZlGLPm3(Rlu4>9&1 zI3X6>BfqVAk{4cs8RqW-4>)LXC&RUr>mInv$L*;2jArPm9&+W`7EywG9fna z=80s_r>2R+jWamgE`rK!kjqh zY1MsFDEUWxqJTWkqSpUA5|`z98;e)dU8W+)4wc1~#35~L7S&M{)m7w8kKc`b>Ff99 z;bEWr*ND=g)>M7vPz274=0IpM)}Gt%I5?&X;Ubk!ZXOE{?pS>8r`iTM0R4euI|g^_ zkp#3T@fO-})^x{?!d^(N?I7c2ZaMKL?d_Rr!eiwAI&`L)K92o^K0k~?-H1of_DbEp z=F?POo?)UPSiA^ z98HfO@o3O+jKJh&mLJ-#W2KqFW}DmWQN>|7mmxNp@lu z-vJ^A{*6ZE0y(-DeSl!$|0+p1z|h$6aAQf)vR1m5CictyY4SDMCqYLGntEpB?lWO2!G;mL;Auz$tO^;|2;d+_3T5rqRZdV_8^ zVO%$!cCMJauk8S_zfva#w6>8y5wrfixkO@S%6RDwnODag6*OdI=*_qlBEVYu@im)r zuEEQk;Y*gOQQV!(_a*ipQuPssAD5J<5|rr40m3)V&Uz@stj1D8I(j+s-3`@;c4j#O zmXIAzhJGO!Z=7xx7js(P{0iXXYL)SP)vr^ZkZH0L+27l3GwZn6lM`jBV(BA@tqi7F zo-z#!?igs)4NU1EUJ*R?C3|E005}k0?pS&}-;S~M)4}qQ3O$7V9%9jV`{^6nB}csRR6ZOzCMU1?-rnaGwJk(gZbej;=kYP3D%SP(C`WR z@@027topi)Vdsp?bS&51v75QLf9sCYVp2RlR#dtG;WYji+Becshkc)Ywt%xk!|0e7 zU9e_b2x?{Tdw8g`_+@bJt0%_F+br>?;B}9eDA?N3R5K2`#_YMqU_cGjx6u^wqc57| zfKaFR3{O%4qGv}eENpE(jyqc>`QIuXy93t9r+(&X5Bxdj?wQ$?tgX<62E?AZ|GV&9 zO-nN?pEfTTwkBSt<|31%L3Vb&$$K*ccl2%3Ou)VBF0TD3QEH)F)}PfXMTp%&^7?{+ z_6__?mk9maN3@TfzhW@azagP{gvcZRivHSsh?`+Zux)$eL48=5P<`U#D_SuYweD(q z=Hxn)wSUL|baFPfdUmot#%H&@Ohg>^ApN52tD&(xbbfyRIB%7n<9Tu+79sRl%9tjp zAN^fHABR3-d36a~>u?CyIExT%<`C(0lyvxQP3!jc+@yBHZ^u&39uMZ?0*s?Hh)c~u9nj;pW7n#y7& zKod0%w!#Ee*O-@FpqGdmY8ynUg<2^Sam_*;cb0#XPCKTIT3iu3bCK=w9M;10`#!%L zX9lQ6oB}#sz0l(0VEHk3qONeBiHaL;x*HCC^lYu=LRvSoxty}6x?gtI9|{sZcXRqmi|Fg)M#Spa5P?9=o=j8C4^u4XxB}4+#S+99Ddz zfxGK5>u;p|>7qPRZo48)cDVAJsl^tVPA3;68tvBD4aJz1PFa3bcUmrt36ylQj54nZ z7C8CTjwZpdw@*%k6y;s`QQ`%((EP-5!$U)o){~ug>n~?d;8VW+Yqou;R{4RtH6Ev|0>DHG*j};jl950|!DgA$D^LeY zTD3sFvpnRA(mteTq_=tdbPp;i{_8k^@Ylm4hFo*N3O9qtQcezL4_p@pFr5aC4l%YI z$eTOB?srj#&X>`8-9Q<5x8b;9Vm86^R0G4CoBfR)KMHmPhSIL%_Obl9x^3@x+Bi+O zkBP2EuVf|ATAY`|D$9Z(-*A&rP%6dP{dN!$7A~ehQeiwbZ}X78=~mEJA&e|vTxbAbuk&GH^!@BcwJnrC@SzHh_T#%P83u+DM*6&m3Xcu{%W={3%KB zBKV*|l`B8cz-65S>x<%X4y01qeux%Kt4ljNPF_Dgj`#|^{{0u>a|N2zf5s)pZ&3+6 zOdDfTMJUv=dsadSH>~Z_zilG~=<7Q6CspV$EsDJt#TI1mvq_8#CIc z+3n}3o$t+Y|9hpbAk9V6m+lp~7*ONUsIyn-0XjE#}ZPXV*jYPF<0M+~H^VT$~X1Vj7t$TK^ z8_D#o>N_r(nr>ZQeRH;v*_;4@)$`?*=X3ibouqz4?2&tVy@ZA)C>i=e~|>UF+Ie zPI@rUt-$HG!o0e=e=GFWkD=1ZJPOL$3j|sqYtDvPy(_`+QaR|*z;&`fn9=Q)y6sUy zGcN&-hrsy#dQN{l9Od)O^rq^S=KII<8!WtxblL!mbhMa3j0bMD&qMa(G{FX`001XJ zji9W~iA(#MX~VL_u{8_;7Y`2);U>7U<*4V}-U%1bv+K~B$&^x%5BU@p{$=Cg$Zi8> z2--ZhHCZj{I4qllbhhYktyQR1nRfdR!_7P_AJE`vyYB`i&ChShP@x;N3^r&)mskBr zP-nnCK07$LczDs3`w?d5MuYFY-?W(Q)nTt7?W>o=@kBVwXmVRys?8bj4}&(P$|!V3 z<3(%t6)K);bbnU3Hfk9r_nfb?!lXwykHuL4k`DAMgyb8>)^-mcUhLI>sfCI zvBPMw;P*Ae!j?w%yZ4h|BmwFhd0xuuXjzw@MOWvrsN05)NI^eD-Y&K3M!=;TcHs+?m6VUdVX z28oL;IL+>ucA}$iqiZL@R~?s^qo>-*W2sm?C^RM_#`;DkfPqDS3C^B|T|g+j902ew zFZL^8RM+0ETNgdgLSpanOX}C!A^Z?BEh6jyrhUHNG1HC=02*N zM!)xFSpH|-@k9h^`8)O;Mq_@7RUId_rIxx52dpq_8c?>T)F<=DpI5ocwP9?9SbqU3 zXY0+Gx<`X2{3!IMrlzw~*VQj9RuPONoFMClp0RPR3W$iVWI%NBVnZOI0EE=9I*z3`?x^B2l_`I6x9Y$Gn&*5Hlx*pn+Fk3CKn zA>jGL^rl?J1}iD4DA*!(Kihd?w5H?Q0lsuO_=KAtG1|~y!6(OeoR5PXkN$gSGhc!} zZ;!7Y*tTEl#LK@ymglsgwdVEd5&SZF_tr%VKL^s(d>p&H*oRmNPjx9X+ zteeJ^Z=~d-9=DD(#My2-{U{5iFa$xS*jy|?Pj|MP!~Fsu_!Gf@j5xW^L>Li7|tGB+x9gVA&yT*O>4FrRMIIqu8)s@zK`p1+|hUa z%kpIrEwn#>DM`&GG+_N6s7O`jjrH)2w#r)I!A9onGwsZ?y5Gwn-2hFpM3KQuN)-+V zvBK#OHjduM4xnzBaVw2I^pK{pvEh??CkH+yFCQO9))jBa-lS)UuOGJG^rFxGHp%>n zZx2)kxZ`+&4c}}mQXOnazhg}4y^|!V|Z?>QgnS!+fH4VUKh#x`i=!CDKqGa8))uLcSoYbN2E3k z;EA3Ur5&$W62uO^A?zE;YggdXyB?b^<7V2(I>?@g+ZWcHT z-um=iKOPPe1lKjjcERcpfAS#d01HmjuZ#U5@}xt+cqKC;!l<_EJ4Y8W`WyP~s|njm}H*ycBT=(NDap4iyjC@QjQY620+rqv+-pC26t4Z!3# zJqT_Pg8kHYK)0jsVPj*n2{D)Vi4fj1Q4a9+>ZWN{`=As}u;WS)*!hzlxfwP zpZdC}?RP^t!h&@}&EO~7xehF1ta||bb18V+EjxxM!V?$)i~b0+ss!C=(8+v{HtduIVD ztntDH-k1;2{ymS*#|v4my$>ObsY2a07t}eoAH!n~|6r-8Px_CRs|zlvYAssZb>Rub!s;FB>6v1S;eT8=Bk`U?uw>OMtSFEC?4`@wJ+8XRzs3u# z7%V643U$UUoER4sLkIFoFa6X!;4`_e)ZI5y9=YKW`5#14;YSTEV$$f+4U}g4;_T9f06@bF{rh&; zzTtbhhPv)(-O_i9V=V=BgEgAsdjI0Hcu1Z7%!whn53Z6d$@kJeI{OS|`KhDuCa&j5kNJCG(-N zQUkv5Qmal{e_X3G>Nl(la%u0>UuQ!51Sjq3=?VX?Y=imi+PyhSn=Fp7&gf9{)sc?n z;~)xq{k%j7ju2%~wpio$hP0iX6__3=F{$Ggti~&mAnM(}BDc6~e3M`(veSW%hnIRH z?;fDKC!aXXRymRW{QZTw{wFoYcA}+ps(;U-Tr!o^A`n@W6<}q@+S=bt4Y7A0hJMZ@ ziM0t>ILL&1CrDE0Z?z-w;&iod$^hINnwuBA2YAeEyw43n&JLLwvleF8)_B-4i7KnA z(#~jUY10aM_oK$m#?$8)Ru){wNvhwrdY?${Gjk7o%?kA{+qdyeC!R(4v5)T_y^!5Y zi-QeV(D6Rq-QFgtDSwa}m3qnXzMj6s$@V&`ke8eM7@2Ymz(5jIdaRV}MuY8Y_-vfA zTZAE6a#{9O2Ah3wfWOO{7v!Z`{3Ki$HZn94K4sMYuA89#Y}pr96g1Qrh#MuX*|xmw zzP)n44G$7;Of4=Bc8#kv>u(EWPkq~YLP`E5f`IG`_iyZq!C z!>rd}d3=<96bP{of4A%t!$)v<>AQ88TOTSllBkItpDV!39?b0NV@Ifo*^*7jBOziB z9m*utJ*I7=E8(SU>O;57PBKu62N2@>z&3{w_7}d`!UN*cAh`ZWS3xHYZyt&hCm06m{2NFKZak}IdTRrNkFm!f)lZU@J^qkR7^xQj6LZL%f@SGX2j z!=XmLQXX%llKl`6k*0NKg{Sniz4eL6G{Wa7^_0L&hOj4~)+ zEKX~yb?}cTO8io0sbB9vjKl({AFt*}_xd_y}V^is6Upnfj$c{|%!H`*tU7CcJW&-N)spk*zlo@_mD z5n8prJ@GaqCx;R2?iS3sS)DsPJ30A5l`uR~Uan7;Ey?e*;SKhBe1&JMi~AhsT~2mK z`w~ARAoi4RR8d@%z}zP5qMbhiU8g#|=+>F>h+J4VUSiUQs-135LJ(26Jv?R9_Fht- z7izRNY}4W9WHPW%z+jTLfBV$qzQ<8qRX^AhJByD%eb1O3sAOvpRQi{8m@iy51n!N# zdv-%u72KsRmL$I3ez9|Vh*HbT&o^WS_!%OX);xQdn0dck_b^XpUoAYlUwJ?+y8B6% zcxgPpNp?=?T(7vy>$eXHQO$(aS$#0hky*r~3Bm+&8F-<^ekz3VTb`Z0a-WsAmJ4mJN){Ylr8n3tV>P67Ml*q9>+mj>_33NH~#$lCtZQ?mEP!%@5K;Pv@@^BXoGN@!=6*yob;A6#(KaQE# zP{1~agMvEG#i{)8@*3Z=?q;;Cz$xs_V&F8B8Z(GS~5H672cqmneuejZv{T5k|zL08j$d33iY zc;^K_9%aej0Lt#y(^9BXpwCDTOrMeE}tl^C!GU4>5cFF4t(7Agcm!S zZ7eok)-t2 ztA^ZiBbh+pjD-oWFRztG`bnFp5vmZ%u#<^T-a+;H{X&oFM1=h>u*} zpzV9~Nap0?6#V%32sb)9`qCS&zdV3^+-}=-SQGIc3hzym&EbkOk_mj9-=Or^)VsB` zod#YzQRPEmNr?C=^_-+LQmfq+y!k99gWjmWl!{$VGzGNVkSWPB2><6)$T5NA= zB2o@vbJp&!(cF(TEo)m#y{72|jxI3uKu0AdS1}WlWq5EW30e41q=EHR5-r*xQ%_~x zOyfSxe4Y6!TT4n~ zLVCW-Vv?u`plwyEd=vRX8h=s$72ZlHaf{B1Z4P%}kv7X}2FR$qg1>8?yMk%rWq6vv z_3eRUW1`V(2KdX#G&kb%p4EtRHX%l!>kOhjx(~yxs@ESH+2n-kD;g?>kFS!Gl9S=` zLTPAeFDi8!iceFz1;IU@XC0p7=jXLIj546RSJw?ZA-S~^za?Un3MT`54?%rn+B;AjHkSez8Qg=W7b%F(wU=Ev0`KmFNI1p;^s_IQQ)q?yI zd(V(nQGWBI5e827jRY8HXkKmSn(HNspBfpJpWKmM<5oe$s?x9Iy}jzZyaP!Y8yWXn zGWC_kMV!{-Xg=)q%f*at|LYeN*0pbi^r6-gbRT8MIR{5d_y}}%$hX0;5lO+zpWvpT zoGZL8n=|Yz-0imV+1_3TtR_)EePW;u{tv2rH7v^Z%OC>$D1Ed>TQD8i#EjJmG*R&G z`KB6dgZkW6+Er;gq)Xy*%AhGn2aU*>YWwG&loVf*WR26)(<7&}tg4m2rfH0(Tong6zf3b4e~eiZHvoIRl{v=c!^M(Ni~*Gf04 z!)3m&v`PB{q(w^n$&6n}Yox8L8eIBm!PoCcAY}wj_iOjlscWYJZq>UY@3Q+n=-SoE z17LuDHbCo=I~Q@74y0NF5#IZV2-??=H-iX2#|);lLEy^4aksUkxta6ackyKlg9*=Z z4|kPwo|=YoRX4XUxs5yLMbP005}*(PQ$*ex~EVrf{JI{EQ<6 z0a})=&kuya?pFzS8+HWI;uylC%GQyC*WcsF31^p8Mie}L@LDb3i$qb=HFNNtl^zH^ zbN9ay^I<2W25cC(FLlvGt&|K*0|zw)nEr?3AT`ZJh=SU>#v~zQVYqjC?_<_%FdpM%QzAvv7~NF>R$gd?UFh4L}K~G31$F(RLsscak-FA(BpRfd@0qT zl6k33Z3gcs$Ggq#JnxBwAN*HIuFFDSe{;6JzCPdvMpw!(>}^ ztlrJ~@-&{{F^;2)8>C)?gt={F#W?wNZrZ2RbEn_{ES+7iJI1Wb)-50cN9WV!Vi!%F z&08&7jY@Ux{?cMXwA3jT1m)U5CeGXj_wq%3jFXZ?fyXIwPM6ydPW<4{Oo{p)-;Iot zW)GdL+h1Hv^qBRgQSbXm)$zL-J+%T)+ZGKKUwb)|a6?9tT+hHDegGWne&oF~5>QN%;Vq~InSLPvq zgSkAP58;R?W$aBKB+0IDThZn3${J`VfrX!PVv+`jl=m06>;BW)5cAI)5}Z%YlrpP8 z{3+SPTUU-|j<43d_Ya4h;O%{Re~uSEJ|3Qd^9M^{{IY-jS9LKQv`!5Lc0L_SWG$sG z)XFnJ*|uQ&-q)?}w(j0a6Q~s!Yg5BlbO{i?Y%Z;H8^R0vSkx@bq|Rev38=HVoGnFAW0BtIi-dt-u&6VwgK@a zuvg)C_S}RQPcM`)0?+1bDM5JEdL)os3 zDJ=7fhSzo?xXYsYQ$J!Qbf`C~2}fotmn?-PD~Q#;;VXggyzspFWe`K^gsl-OF9-_Y z<9k6#!l2jOag$C^{bnK|F_^B;q7J@r>)tRIJolAY}9GAIu+T908YThINjG5l_LOJSlEK2vK{en9!m z=_>>{{~DW>HnH*nu5iHo-tUnc^si+HG001)wJKi^*n&uQ%2*+s*QHzcZ&;w~<@AcmZK8wqJ@MX( zxdR~rk^yVXON-3}l6XnWhtDw7J7d>5g!Vm?pZd%lxe2xQ_sSjRP8-|m`D{CFXj39- zQ{h?|6@_U``t_rg4ni?$>9gXoQdxh%PK&_>kA>#$p!g!EKa224)O`)bPXX+}AvVP{ zeHLzhXfu3BFGHQLF6HbiRzN{ci<4>+@tboopN|?hT7=NpXV|d^b`2H*%G}qXK-8+k zv$NOPoVVM>hLDhu?=J0YPOaKq4D+5d|A``vrnbX#jA)@+Hq2XsVdFo$4oN_l&hW5> zy}jsq;U2J4D`Cv)%VbL^X&Z16JL-z=l1J;1>?yTAg*Jq%=1Trf)C6izos1}ACX7Z0 znZl&Di2)gevy5NQTEAhzjvqx8bA5Az{0RjGMJyzryx1aDH>c(=_|Egir+ZRQ^N0wK zILv0LHt%X1RmjrA;%qf)v|H0u#w%|5;JM2@lP$KXyz9#>vKxT{M=8@IvNLg94NNTRoNk%-tetnk%uj>^e3qYj zV0_ej2$ArMuZWxp0I7UujoW#3>L-pZpiV8@8bMDtZ{53!Hy@Lt+>a*wMgdq#RHA>9 zH7os9oP4Y|hcPWTNgO|&b%TBA+u;734jb36?K+$a`aAAMtynnw3zKd-dh$mv4Ta9% zLH$L|*6($E-9oQqzIcgx`w&0`$gMBGjD^r51ooVcvB1pZ-gPhsE;Noz1}~vUYH+|x z8#xYTFp_hO=m=2-i{VC0es<$uV@$B{P76mupyb!V%&s|KsT)2GVpE0+TqLhHTL~qk zIKeOR8e|fo2aI^E-;;#|?GL>=?|H4*F~l(0af(2p-s|EGP=2TLDQ|0+5Aj7@U7hx? zSOERxloT8<79s$tLBssDM2K{JnA_4mGqS9UcX-g*#Ds3itOYYI?a%JpKdUkOosUP4 z2UGHd=Reb0#LAk0gNcXP<+2jM!Q2sjXDl0|Hk9HL+;|R?KKVA5B6=mOB-Y$mxOfNk zuF}X8*Ytm+w9NU_=9fQQ)zst|h~)r)$WJkU>Nqm-?Arw|!97RyIJUZt_N?@e?tOVHhMo`7yWs{%gV9AhY zC&-dgS}wUpjg!se#nzJdcRJR+sPQrbn~e0eieXB&^sFSqK5f*R%uIi$B?&x=bea~W z=n{N(EYT#F>&FCgeVH#a;IIX`J5HQ(KmIoAW|x^&4efOT_`P;@9lX6Bgfwj3 zox@H+ee>C?GEZ)^-{biiS@%3MQ~!cI`*HWSyg>re8}l+5sy=T*V4ZQ3i$6qu*s7!xNCbsma=o}9m~mw5hN+&@8d@>it6F{EDoT6RoCv1p#NrCy=i5nBaM zHE%RA7eWlcSRksvU$7IeD~n76{heA4!JoXTskWxPJpb3%4=G}_tIAJV}Z zdFWC+uBDgHco+z#LjH+ZJbcTJPz_82o_aK)JA8J(&JR-q)!9|UBH_AhSYI<&4 z8U9_bxKl0^%sFD0>G50EZ6h%9X~hvoQbofjHo`MvNP5Jv+e6J_59Lq7h5m(v$;@=* zPg&w@yGy?fzSmfcWYF$0=X!lCH<7{UF(o)9=hXDB^&fwhQ%esG&!bgcwM}WLFE2*~ z^xUKV$k_lpQlp2tL5htE{bI|UePMQ%ZL0C75qJQZ;Eyym^P%qZFm>Mgy6$l=5B4-} zFIZ_i#yW!pW4WnZNW_%cu(@E!RJo2kA>c~UBUn->_ly!2OPPz5BX=U1EA{lv8Z+cg zX|C%NnauoP&soKX@v@E375eU|CcM|jd#jWpi|}9Hkc%7ABj$yN)0zQ*Joy8?`T2RA z{XAQqJbv8kB-oJ-tfZtfc{?ymA>8>V`3!gI&VM?bSDchA?$brx6+gL&*ldEU^t&P! zXI590G&NQ0k236nL&;LVOcoo#bpQ{_KNurPu+>k>`#h&}wK}KdAS%X_* z{ov@}MChwI?I z+gH;%aeYIZ&2?ShZjdUOv5-=~1m1Yhds4B|D4YFKe1kFtnqR^=cR$?r)jY6|oi{Dy zH&e1kKWr#D8yuH`o`N2xT2_VhD?hhOiMtm*FQ%IYC6|l z`ir{XK&P%7&RS*?gY_$IZAA5IH_!D>%ZTUh-ctl9?bPi|L9z_k5zb95cfg988jWVB z!<7;eA7cwO2?@*{qgJ3`gmH5c*R+~};{KnbB1@dmYeQ9V?*Nl7>c82#`ueXSBWi2# zOfro*(YmDp#9Ukgh`fJ5Q%ksB&v6pnJ(o*<7!5Y{PtW+HB%=*8l|HP^c5GGZ9#XLp zYn$uO|313FoLzFVCd?ZkpI$1i54Gl0Ari$#!$}(5F%U|#{Xzg1OFiGfO_UPOstOSk z8MVajV^KaU01jfj?9WxKn)KcRozyGGYZpmZ%w{>nfO&AUDw2n}jyayMMQoEiPwC$v zJF(W-rf+8l?)efz#QOp;lKxeDi+ARB-A41Yp2{N)JjuqOvj?EAE z1u>i~?Wuqrc)+wDy&`MrhC%d)qi3=}0gTGG7y-BkzzEW$AlKW8-WV-o;p;z#b|Nji zhH8{H#wCX}o02WhQ&Z{9e{;rwr3omM%#dNE0c~iNQV8`y~ zf6}LZ^v85IstdPY#TIE;3lbH{#OmQ3Sq;M}yD7wd6DB@6$BE<(lh7e@7d0Ba5$#Eu z&KiqT?uJgxEzJRmSllP}48$3!YQB;uCy7-)*BN7wC{qtY<$~B%T%&>w^P}m2zKyqa z%SXz>-auckqYG*->&|h`l(!?UeLXCcphZ~vfCeh{!45-QI0lVoXdp`-7h(3v5hg!T zRh3THj3P6jN5{AQAxUoCb8@DW){MMZO(|M3txvvxIgH_SWximaosx|}R@e7KKsj%irJs&iO|KK#iO0QF@|qIydW~(7feAA1 zTe|BlS92n~S2$9fPjNnurbRs|FUNNsZ26KE(xB-T$v&H?el3U=FwF=#^VNr$>g5j{Qc5d}PU85@URqJX$Nf3R6-N=` z$@B6q|LDE#=`d+f+|!t3;ru4slG_dY1ZAlu${Eyz0N69Z(L?8bsboum7Vf=H(P%K6 zM}~ZS@18blJdUHdc>T^u>L+na;U*rszTOJmdv$gGyWr;g-j#cBa&SO$K!S@9^6i9v zoz~=|Qmq&YyHs62=9nRj(vn7>j`8nOT+({HBQmjRDWl`^VWIME^lsTfnmrIMV4b>d zTj6Hzw8$RqkSkFMip^FG1$EkWL=>*d+-vi=X4)7@qlXA7T?_R5J^hE|JWka$rswfv zMUBp5p!Z!?`x*-9jV4a=6K|I6nB?P5b0tXGUkl;D@5|y2;Bbxm|$yL;bMion&bpPEQ)qlwUPxbbH zFu^crZXBBE-6@fTQ>g#ICp2&8+&yO;5bj;Y+FTm#ojM+K6BKqpuCB?s9@KP+D2*&x$H>NZ8J;-|DO=UW8LL%4FdG|9A~*&8?=B%b(qvd z_<#8+=n`MAyWR=t1*}T`#r#yBRY9{v1;Fg1pJjnnOdQydz$&4r5x(4z9fVe&`}!c3 zpjYcDTNDb)P0SY9zix!KH-uI)cAjFZ%B&Ef(= ztc^h`)pOVqlM}jmZs0=|Cp(?z;Mf>Zd~uYrJ&>w zW%rbkacz?SacSnJLhUZfbT~kORpLudwrmf7Rz2PR{vg^2lYUE`XKsE@X|ew|{2Yl> zn7H86iUarZ?F?dgjtpq!w=Em95u7gxS!6tk(J~ar`{^<%PAh?x44ixNhpfK-;Wd7z zYKcN}#ToJ*0pVx)n%P1m3o-5*y}AU>-L*D88ZcnLTSazb`8tW8r9OWl2jN2)$OO87z2FlQ0Iao z0_tQQxUk0(#Z9jlP){UWtgM$sgWJm-B{&)65S-T+GYNWIF3GVli7ylE11pXE4rhx} zsSSq(Lg5VKkFoUbL`mlTU0@}rSge;w5G)VQv_66EA(FA?-3|Q{JzQdNlTc(ug#(e9 z#=nQAl7`8qVFXjP4JTn(y1XsfTg9>E_iv=Fw5~VzxYsTlFYSm{>~~8GDj+w%y!^S&6YRa;=?-r6OYe}8 zz)9r6YPhgbj8j5SI3#-!N`RdK7A(-20BBJq1tB&{1M7OJWP0jFiGqtQNsdehQM z{?U@1A#KDb=|Y@yJ#0Wa4LQ|92;-26EKA&lP+=qK;diYMa7_sjV+N_z=xz;gFGsrO zmk-^(ugZI~A%7Y+BctM^q4AVI@XP61?6r*}<6}QA&@3pe$qw4@VgIeY?yaS}-Mq{q zy$)hrVE|4pPPbVO1BW1{)VDKF(rkn;8SW9V$PZ~P&!4oHTtGIcVS|QMvLy{)TGY}7 z%B`%RV+5bi)x!H#;0=JS@+u?lUu=5ZL}ZW!mw$ojY29(M-!j${7djErrxW#k;hcJtX z=p`^P@N2(XhtUg^lDH@$cg+bVlJW)?9@n#=i=IZ1!p_NG=wq^=xb8Piyi70AOA-PS znxGszN4S)f2|H>-C(B|K<)^%z*d!{XOnFwsjJoUzYMNSzDQzXqN;^!0n;mo-Kd$cZ zxabWbuJ1X%QIXr#Z!^F>?_Z?v{Qz+gY=tJ<1I=xZkLmp+UbWA|@Wl80bF+M(8hwB~ z4>azh$39e>^_&Skyh#%CG4+AV4t_gO^{RD3%Fftv>xK2G0p6C@BXiMY-$RKLPnXzs#xnif~G%6 ztsv;Et>Dcb1iO%3*(8~51jkGjQ%dSlT;s85ehEv$kg_`(aQGaU(Y&>_wWE@v^K*3V zZsTbOBAHVLx66hvIgEpl8LOtI*9y85vY`q##7Sr`JOu7mpYIk0H5*Hb6axp!+Z@|u zMWtWUNl`0H*!Z%_G4#xU$yeL(E~tQkQC|gOQg^Tafom$dz}<+EA)k_IbH%(zT2qM# zYctj6upLIq24xdeRlBHQu_Bv7KJ2go_K~xal_tw`1@_yDM`#tFzBko5E{(N-Zl5?o zfVL*DdUqf6(LxuNw%JRT%g}RX(1-bE7Ca`1_>Ktop-VVc?*wREEtV|*rMcGUjiD^O zZ>-y0ZJ6-c?O)Vwon(nrZC}&Pxx<%@4IUVvgLs9fg$X|RuKVXJmd##~X)9Q<4GEl= zg^mkm-<6R=r-kLy+j=i;E6xLJ@Buu)+{S_kPv#FM3Q*thiAgce_l2I8O~cJJPr0=00r)tA*lkKgOYeQFq1Kr1L&QtHmSJe%p4AYB`qUl% zZx*2b<>*|HD)U@*$MewA^`PejA{y|hbK2Z`CBPXM zZeDexyDI|l&O^Mry}6V7cdZpxmi%ivI(>e891q?KLb2Y^29?_1jrv~e+$u}t0}tP^ z+dJ=Eo&x;`>#*`uKPGXdTq$n(iQtlTv!S9C4do}Th{PXh(6kQq;ay+Y&tBQAWPI|@ z+NIjeSLMGViVmQt!mp`@!^FKB*zeN7C{uV=+E_QYm1{#6GU3Zq#|qewz>n3j&vSjz zKsCaj6nYs8G|PF4c>3R2KiL!X`cWLcnh!ZGqVO}bq}UPt-`3W=P5k}dAQ-M)yE)Fq zMV0VF3Y^4~Rwf*K;$P%+DY~DBt&sI#wX@qgY~5g$)(JJl* zZO-mc>O;RW@QhlHilo5FNj19U*iesDQ6pY}$boHOk+$^2nuD>>OxumgF%V%brr>VL zxT4yL66e#iAx%8(ONv--1m%o0nv$tFNp|fUzCxHG{!&8LU0<0Mwu0jeRPcs^w0haH zC~dPoFXeB=4?5hKk7_0=^UPPO6%4Z*i#RVi-nVJ60BJuIv|_fa7 z=r8WS|5l zpCkI$TR^A1gxT~Jb21f3x3{+_gg@uvkl#A4syTW(bfD(e{|MiF-m<{uI4MAOJY+r>hnlfo_9iP%9iy}oi!oK?Q|OasmUnOK*Z z38ZJ1afp;mKF!#eS$=OK8S^Xrq?+bsxEpKkQV8UPN}ww57EeG{hB@>~HxK4*SHH!5 z(k~_goTTVoKGnzyzBD?Ai5k+NeLRVOpfpao8E0g{j5^Xyf!kVN7c3dwCB!F;Tz^>X z?rQM4N%zS$DV2;Vz}8^VzL^!G^LILOBuwM(@drVi{_R%|@vsqthv#MnIm(=Gclc4J z|4N6Te4Qi{E)_5?Z!g>2&`o;W^N)tgjob2c~tt=q~|4NXpbZlQ^ z%aS$Iv#nwBY;0)?k&@!Cu2HMRr3lxD&XC!M?HDrfqlNPlbg`DgD>=%bU-C&%T%3rG ze!|Bmu$$a!ZIE>}Q+qRzAga4DXIX=`0xA1x-}3zWiJGbHa)afWT8!uF$=~4M8?E`4q)Jo#``}&9Jd~LK6C`%4Oce|ymS-hfd!kolr!8vyo%s0gi%yWPDMR>7 zsh5Jg#u~d4{CsoYC=}2(3|crbb1*>QaENlPi~S*>g|bYTH-|bs%l0rK`E~dx?-u!Z zp}XzjL?Z;)akTtpZV`1<)dyzRpY`Jn)>y+_f|Qk`<6t91Y;oy%JS0$`b-#^H8;{Y- z49hVvuBo*c^*YTjA1dSPF=MSMsSNg?APLVX4^Uf^e0Zw=8b=qHH%J{t)gEg6OA;Py zSoX+(97_PZp?}!}Ixq1DDxzm9>b~9=25##19Fn;bw zcqOM85&bJtQc|Y-Tj&knSkqVppY?~~s1PtBpY_Y}8~^+gy3tbT3MWgnS?cOVIXmGQ ze4Jnco!+}l>iep&rfHwrb2pC}bk+xtp1Rn!&a2M)`8dJ|mwV+tLSyN3-Jh=AEp2a_ zv$wT1HafKs>S|8B=OW;v6T;1SvC||)d(l%8CAR@uJ~3?h!9-V=jP8;X&Kf}Z5DwO0 zrPP!Z8;7KXf5{4ddyXw$62FWA*{l#tYp!8qcxF1QJH>3;yEnlQ<0QzUi+}~y;T>6% zuGLp8`8}#X`RwF{yuO48t#g~vbsPy0%k^B^sU8Zqk=3a)EUYc#U8W>IW_z6XKGaNl z|2#EM4u{d8ViSYVuX#^kUX2R0|&fNVOy`_o~~6Zwy}gNn-qe@Y^b}6O((b zqFQa>ps4a%HpJ<7arvX5S8}k+?5ea5nf`l|^m_M)A;IS48!jn$Nou)W?Rp>TS*&{- zc}X0D01x4{fSfE{;H%uUK#7x(RmLUT`BU0oV`H1p@|uH3_6(MObf6h*>iqBFO;Ug` zH>OAZ`;5uj^1SaqT59n9QeO-^6cIaDDF5`B)-}h1mTlAg>xElKOKia54Ki|)@9)PI z)ZfN&!kDysWF=5kJ2^VD&YUKZ(ll6fCy&Bn7;xVX8wI~LbH)x7R| z;X8%zP^U}KN<(A^yoEZOt0z8JmM*aoN3`sM=^CWn-KU<$l;jxUIf}l`1&d8^c6};l zz@jf-3|>=PZ(@)Odi81puw`%{p8ggNd@t?Ye9BGaJrSPFgg=B*CGaH&;&I3``No4+IW!HxQjZw2AZ<6$$k5(Bo zWzCY-Z147-|2PP<<3}aIkG`O;-}UfPX%wCt=MTxl(dxM<`5$d08V(W=0k*;2V@oAx z-6+L4a7%AwPc@=Okw;%uRswC=f?z4_{6PCA7<(V{0z@%%mK@Dn6A8j!vdhPK<@Sl? z2MbJ#8bDrX-r6igfHD8q*CN4gUqupaVqC&s&IB2`bNllRGnBtPJ)b%R^@i(@!W^lL>C8T8sMT)Ca)!9>{KOo_##E zq|o?^UuXT-AyP<4dIsFLIDh{gb9B?l(GPq*ZesWtJ?eN;pJQq19?++(H#S=alic@D z-IMI*7 ztxNc|H5V*wEstOUptdHfkW^z00@YItWs>0;NkJph;aVc`*m{ zR(_?fWRxk?Zrfi3%80@h0)=`bm8FVH;bK|fsW{*)*jt5flE7Y@tD={+er*V4yhZcW z1A=uoH{n<{;FnIYPKv^5!(RxZ22N__!yKajXJV|Z==ZvBALD%muF;-MspE8k!=lR- zOLcyzBtSLy`Sz2hfqK$5NpQ&kvZXeZZN|o+ao0$*rC<=T5qo-Bpk%dvy{Iwxk~Plb zw0$H{jLv!5Tsf`@X9NyCDnZ?|a7Ot=h%R^hG4@`crakK{AWO+fp#I4(?$pQf@S&ca ze(i%_zFU7gvUT~LZZS^y3f}y!+w$03wh*%(jsoAmnjZyFe*ch*8=xa>uAeK`bE+!K zdAaPGMp)llj;EX7wFI)AFDRi|T;*(b%lcdDEU(n?g!U(!o15vvq_xtzObkeg@PS<+ zByQ(O{r@^x_JZmy1&j1yB5}?VbN7S1x_)tT48Z_W&9WUdpT2~UH21PZ>ZXh~sbwFr zf5HEs!>Qg8j4jtS8lAk*Z{EVcJbr)Bf39>qi9*>X=C&}mzPDvfi`+S0sgGJatDW>b zu5vDD&%c$xi(JseuEpZnUJ_KWmS3b);uVu37e4adyA$iiI<3GZPA}^d{UloHYqs5y z{zu&S{&IkcDna?0iU_y}G*J#X@)FM4NbW=qoBuKR`-#NW`%>uXM9Bb>{K&mV_>o;f*W!)|G>Q}d^R0>->KWAKBc>?&!rot2mOWG)JRp%c)5ZmpGJm%6-#GeRtbwX|${hK@)&E;+{?K z!IPiHJ|E(`O7rzB*~PGc`>>xWQwMlwpCZ;hZ({pU+pFdEZnA+?ky)-F=i=QgI^Xti+{}u+M@3 zCJ=kNwn%4m9NlR3veQWu_yiO;aBbz{e!5X}jTbyk5Hr{=EhW`Fn)`~!h91$2L$CTR ztsB$hTb@^TTdui{?b*ijLQI{N)`4COOQH=;N{_0ixFU zR3&vBlm%iQl_Q)z_pj9PFKJ7I9-pSo5n~%s^RWEX?oR#A(suEajSY;nKh6vZr|4V4cvrn};E$0E74b~79 zPh#F;1Kc;sX=;q#aJp9 z$lq=U?brIVFSw*-&8IzQzrtZTx4Xv9{4IyLc9-PMzRw{yaG$Ew8^s?i4HBzA9o56#pSqt^(3Bmu)!c#I0#5~Hgn%_tt<8;wJfs)l- zBy@chC7X@|Qo&;#$8o6EYyg;2q~T`}3?VXgZfy;|*kawG@2#`Wba#X$)LBopS)um? z7qSAf}9_V=7(2`{WLdz!1&?nPjb9XmVh@wmHOjm2kw=Qrfbf#1A84U%a=YKsF7?k(_!p_^)!FRi z_-}R?t6QH(CPhvvL(7ZE|W%Uti}Ae*OQ-;pM;-t z5xV6%tDv4f1=ytMxV{Vzo!ghn2Ohe#_q{G0*VGWLVKoV9JYn;f1R^fTGu!5-%9WPHUuog|e}xYLAj0gx+_N z6i9Ab+P=7l3t7|65`kQS5W0Wy0_VAh^ribsz!&U@emL?tbN+0}^^1L>aXTwpybpE2 z?Hirx<9V?S!4yU>9t{>9lRV?b@--w;e6*)$PRWTjDhc}k4gFN6g z3~(+`B6T(K;cH`cn?>ySoBFPL{ZBLkArm9!UAg#&H01%$*Ix8#u<}HOM--+~o?Lpa z>32-l@;BrnlFJ8WcPt^Oh3uKU)K?rC6q;t#{4icpy@?Nit0pzwEUOj}!TTvF_frR9 zUp>9+o{4_h#8elkUllEaxU+T^T| zgL@Ynmed8Y*z5XY_8IZ<@#W7tDz~_&%t`OUQ`Xf!?>8=OkHh0|eHfV_$d782X)0imgIeR9s!j|W<&J26II?(p5V<`$rvmUhTL6$ga#PnIL z`L~jX=<4oAT+iw;Nl5}7gLgt{XMTs!iGqLto9y8Q1eRsW6=pc)>gk>4uW2Z;M5R)&x7p3MGgS9kC_QGN5&@}!X`K4*NhOxs1y|3Jy7e|4Bx$Ba~6K?gW-uj8$^ zNXP@kzEBb(3g{?lc^YLOvwiVsYloK=*uEy(7rf(t>WP$M(ZO_sxc`d?y_ZX^VvB&q z{fxAl<6)|C8JSMvn8DV|;~K_6Qa|<23K}%~c-Yz`i!q#WYJ?`?<=;gL6U(zD*qWx_ z;;1r)0?<<9${=2R0Aaod(N6NXxn>w==@?I?ZiV)ZPD1rf0wR~$*&D0t%N?LgWMit= zbq`R2dQKg7PcwtQF=L5eo@M_Zy{4+C<)UDh^me7;ZK<<=y*K zlDV3wJ7EV?FSCre#Ay#o6^yV^I;ayaSibJr3Gb~m@#%0fX3Htr8QnZ8pRP5Yp%OKs z%%Qr(FxX`QG0mQa5yMoVCJopb0h3J^14aaA#K^Yat(9W5D|0$!p76>`y#%0Yl0m+7JuFFSkt+Wzee z%(2cN5RD$+pTqHaIn@x^kG?lm>6hAo%2nA_IA)mF7o}XqqwBeCxrvr#YkyK7-*{)IB_6a9$LhC0u`D2_vct=k!_YzN#zh61IF>j0$(r4kj-LzOIMYu967)I-Z*}y6k*;RpnJ_4Ck8tW{@N*C zRLOp@vcAx~a_X{wdZjtqr2&hzyUW7Q8egM?{b3>Uy7=ap@6Bs|9?7GvEyUpYZKOub zA74;1aNIUwTs{UyAVbFamM57Ci6KprXZg<^SAsM=l}?jyF(`xsU&i3u@JG6+oKiAG zuLxrf`V3k;#`v|w$a(3X%xM$mY7YW>C{M`F{DN6CKkhXS=|G1EFl2h9e%fle&0mZ2 zqe(05>H=PHs9FXtOSknsD2s3uPlXF5u&;dchFSY@frE(*<(UY8y#_g<7v_+@uNCtD zWgi^&JJS+2NdN4FE5;gS5O96WCI#*Y@Q6|NFBGZ9t{)%6J;AU04on&pG_)dPsQ;D( zb4+Q7Gk9|>v#4P(0Ap4)9p%h%l3pgb;)4_ml#Hh1*(z$9nnxg;n6*);H$vzK;V_Cx z&dx3$oQyTqSS9!TX>;oM8y^%aLS(57Pps9KHS4e4`a8<%&Zpi*|gKzy&SjIb0$Ip;6zO6tD!Psz& zu8pfpzm4K&wA7P7&;eexXbA}&V`IwI$3%Uq2w z>Vm)3o1kz^Z_3gF>Pg8};e;7>W)*N95H|EGn|Ro{uiMs4nKORznv4bC5b*9lU#=3R zQZzHGKjp&%2gZRyRueo8YqqXp8XC)y{Mz6C^R+e>wkTB^ou(hn_i>6lh92d4U;M$2 z?~n9Ldpu{=5(_r!{`}%XcPN@JgAsR1T2J6dPd=Nam`qLVSxJ4D0*4kcxRv32oI9q6 zcp*wgQo`_Yz_hSNYw=>gqS~XSyM`IXZ7S6cUYRrtvE#fKXXIx#@}SSR`l^3u`!y;> zQA$Rz$%6$ZUE&QEfrpVNoO?L{3YqIE3@rBjMLLIh(vd?k=K7!+4ADoJoRrPW+Gc41 z{*coOLBDtl08uDA>4-dLdbPZyvrLN9GgN)*$L5$Ogg8`xNatFyThx_#v8@H1QqXRc z9)Q7~tn#`(n%Tz*Sf>A%%Yl7_Dt&f~Qb6JfgWel>uLK|2e|P+Bu$|0wynTQ7%po(Q z%@}yzSXPgle{OXS(=gsxR!eF~QLauAg?$>sWsXOM2;rgU!(#>`mEPVqs*u;?ApD7M zkVX0nX9ilO9%b(OEhYcUVd8S6iGgIa0Mk5hnM=PTw}fyoA!rQ162o_SkPLx*&N#{Qn%SIs z<;A(gd6^9C%F;?F7{TMrM+RsTbrR6JLq*jskP7|6OHY~;*Sp_y{QI3y58Q0ss|a3! zx_#ydM$+dS7{~&@Kd^9En4`4xQHx%uP_52_CyP!HV)cTPRnL7Y~a~cR!WE)hu(#HTiw^)Bnci8t;2?e5(|eeR#rb3@gTO=-#ivbE1YA* zj$q6j8!41#!DTpo&pB_dXF1K{%R*$A*nM2uhyW)-ORhPV-5YvZnyQ=vi_VjbaWK%!EdB9dMYr7iENpu0ZKLKvUe(Hbh2JndYJMf;%Hgl zj$a{d06Ru4Qf1PG80S?0eWYx!gZ)8f-+;0cb27dLz@KDBW^%uQ_xGy`cGqO6S7>5Q z%uxlV`)mw{J2lQ5tq`X5@#>>k~3=d)S%5d4jUvqQo%JQlT`VG@| zo0ozgb6m57oikaJeCN42vR4l;9KGS2rVky#VN+}K98>EH#4EKv-cIa4Olq-t>OL9D z?BZ!B-Pc>=`*xKf>b2DI+NpQH{w$eoJ*AkVHG&j%Fbdyg=&7HN5zM1L0_n@nb;HE- z#O9`c%Hna=2w259#&zApQ-(FIFj7JP_A4c>BbDMy5Z(7A5N7to9ApWj#Fex|ojk|R zHfNV9%~06~4Sy~ztrVLTv9a4NEuFcv>)dU)JpIY*?d9I|ptHLh&OC%G^hwC{$Z9_t zb5y9+ao)pk$A(Q2ZR52+>?u4XZF{$3bE(5ATZ{FuNW9_3d{|D#CgluEWhpXdY33~1 zb|uQ~QZ1dPnmCodrPp75DsdkE(KdF~TKEm$0gXGw6S%^8Qlk-U|5Fk9t~mTA5DSEK zp#uJ&BnMmYVNR*}*M+|m-xSo}pCY#ndzn{4dF%2Cqq~>8SNK!`YiG60sY1S4xuHY; zVz7X(LBguR4%|bxP|Fk4%Dy7-CCAkrd(r@wgs`2IhqCp*w5V_|Y+M_ayttp*{LWCH z1s}0P1iIVrQ1ick_kO7K<+Olo;qUEakSh9e;?*amBe4hd9Qi{D*eDC^XUhN9upkYW zwH+h0$-TE9#~rFCts=b2$`)>x{igC-K{F$r_qbTDqU|nOYh9}%~5a1IOXu@xf4JoBNoGqD4dCrQl#Mj9e7rP zVZIoltBj)|uS=<3!@F*TRCFBb<)Zus%_KzRt2ccQ%Yh-@0y~~qlp1)5S!geGvrpZG z|HDWnuj@#F7c=VRTta9CdH@~gnPgNepwI#KGg(;Kp2Kb*SR zbo;fxM`|z;AuhkF{I8L-qO%|n3kYD*^Szmm6D7MSGr)gI(D|bB?jJG2e*N5>^x?H( zNAN5aZCrxtIlFquR8di3TeFqx<+uJ*?=rqJAxXhne^OCHM#?D)HM~E1iO7{BLA#gV z^hPejU?b*G#M8?&re0gs(p#w^J4sOLcS}o6c`?=ffe<+D?M7|%Tfs1yj_Tfr zmfHurLL(7-g&x8uWNg1d=<7tsY=?LytIY*#Uf&!iG@XL!9Yo!;a}cX<5JN80mD+(A zbF20Ya(o4o@>Bma2rh+6>;4j(RgXL97S@tIJ-|@uQ!&iPUpJeZo1-Wp1ypY;>D*1T zN6=AhX3Fq^B37I**uwjIdRg_Ivn^dJ#FeF~#5Bw`qffBLLv2mRydIt&@W~9Xk%%XT zfkHX5w5W+Qd6!yo=>D{bsb5%@V@DK9xvqcpZKZPX%#TE_XJ-$69VD6T%GPB^BJ$qc zc}DVWH)2f#Dl4m6XHT}7ML?*XA@%J{lPZi$blFMcY2XpQMmr+Wk)boUZrS11RP}$D zB?!JquMT8n!kHuBiN6!7a=Z}Ow>8x;14YWp!m@MoAcfuaa*G4*dN92*XRYZroG^_m z$jG6T^&TWd%2#TbFWbP=_Ti0oXK-U`h=Up~xW3JwKIXt5PZUwf4joXBJ1KxZ8wDRdRgtDp&`k?`&TM^bw?OvaiIj#f=`ucKjM+k0l)tV(~{=r ze(~fN)G1a6a_ssaF_-2$P8^zbnYVzfkjiSf31y#}K{i}O2d{uJ!8dGp0>Baq|3Qi8 z&FyvVX;p42r?q?YWVPTT4oB9PVQs!*a1<#^V1j9Ot&Re|&uWsl(6ws45!|)km5&BBHH> zsi`3wuGfpcgDH9F9T(D~{SoM+dSTw%PNyS+Lv=vb3lm?vKHIFAKdAyhsvoL4Ya6m! zIP$MwM{?-tjH;rhZPo|B#J}bL^h4B@b@5YW4r(vNIFWVzoHh9EMxAViwgOV(u>HmO zKzOu|x4lD~+8N_}6TV4Q(UV|DyQZ53x{Y50x-YgF>+;?1U%Zjp3OdP8-rsrB@u*3i zQj{;MFV!HakeswX3aH=9Bg9rh7(x3=9yi41k|Dr?;5?FgbG+c1<#U^+#rES_i*RYN zql5vT=(zzdXHrd9MQ1Iw1<@=H(urQrTOl$)^m#$rlKe`NGMf9ue}bl~M}BSpqwdIp z=NvO-_ZO&Ay_J2aC=z}wEzOj_SCy5LQpqIvj{iP}Zv%ey^$#>ze$PiN`IcrCv$TlI z(xCE`@bS?zn8?LZ|IyiZnfPr-x^IT1b)c94*d=mO@yJS}mkV*FU@=OX$!|p8Z}}pf zMy=kPuAcV8tc-02`iW7%+pL_R`^cfwnRzrj7fH2UQ+c?eBRN-T5!w++*1q&%Y6Y&Q@A_2p(Rx7U9p8Q@^z zBso#F?B8!M(^XWA=J@^_mQ!WY!p4``yU~eLN=MB#@^@CS&txvZmmCbZ_1Yw^D4{9s z)8lKG#aSPO=wbF{@&1_L2OnBJQm}8TBtVDRLqW&ktI?XKy7CbzADmcm_xlRx>nnXM zR!UvHU1EJKzq<(&HGJ4nwlQpMY7Um=y-7S3evZ2S+50C!j?WoJCZN z27W*Ox9OI5eqR&|rL0&tYlieGumHnsVk~VHqus2ny?mV{ zo!9IxyXm`g`Qh2d-Bp>K%4vDErht;w&H8c69aHFux^e{Lt~N;3t!54m05G@E)BsY? zJd-joGOh`W4!3D3Q|dlmrVvRC(k;|;(=aoAZY}BFd|;03ovTmF%F;R6SlaNO-&G@w zM;U%oQh^n&b_=zt)>fg76C(H%mXMiMU$uJck-ua2yT0SOfjcTpN>5Ku&6KL)dMn0f z=R=;lZDP1mXS?VQ|636A!Rhfa!NDFFh zZ4;n+WK$zeY&D-&N?&$KaqoX{$oRb1Hhr+#xhq@#?{0gc`QTT(>gQ8{dW=1^N5x}d z)Km!utg}^uz6HKkIlwUNi{wyzGh}-cgg;YDntkh(#2HNI0J(NtlLK0 z5A$SaZ-h+_eN`%hzyg)ba?TI7=di22n?k#}xt_Wlk>X$m$pdA8W7jq(;I_*@;PnR0zw^#NRu-EO zWFo3!ZSljHkPgauTdn!NTH#eYhDcE?x(t~m|CTs4?43bG`e9YqF|W|?I_s|8HQ~gl zlMRD}{j-evc$x}QPl%dgK()`3Ac+*zj;C(IYkoUlav43Mnd#{`Vj{e>*PW6{ca)1H z8x48aw`XR-x1+F&F!HEtrUOy3!*%a{9e9qCP^@3VbPZ*j<>D2i`}X8hHn(BRx~TR( zUu;vBJohSepFV!x?aaSZ_a3XrT<_{arWV>yv@y0VB)&=F%5h$hW@Tez`vlX1}x&O;hsYsJLAZ7MKlw(CA3GKssMVZ4@eu#z$>|o1vCwEFYjM-V`YfVp& zyXM>5Yn$%--2yqGi@yw2HjBSNoNTOzywT!1)*H^%<=+#EfguIU&7Z;6p<2d&1B$S) zRR*yTpL@Ra^zITk@q9nKgZ8tOmx&`L;{gEX;#6^F!`OwmrKP18F%-(ruvPp|6gl4} zT(i7+FOqD@$}V5()w=#YjE=Sjd*EDOP!kH-@0z55lfqT7jPsiUbSVGnCrU+HC&*Bi ze5MnY=#~)7>7GP==9z_GKnm1?e?kxY^|a8^&6rvLV!oY#o3q^NXtuxETm@QLS>ZEc zX))xlIoNn=-$4DmA&(iChrL`cGUSQ%==O-{RzXjI?D7!A>xh*UBL+Z zi&XBs{XGO#NsCwP3Mpc~&A9I?hoB&z*ZJmOnMEC(X1rF;w2m69wX-ytMk z2P?{SH~+*lkG%Dd^(UK8L0q?XtGF(3XavKQSZ7fgoJ}_C9q#(u#WETHYMTgAPJ~zl zxwu-Kz+kWf!fywY{*;jdpoY$9xFTugqUZm^-d{k)*>r8fC=xulB*B9R4epvogS(U9 z?ykW?0|A1&ySrO(cc*c8ck9#S`QG>cM$XKdwdTxP|5;O^=Z;nc_r9)ORX52E zxy<|l^t->mC%_8sMyga-p~@yFXC--#jz||X|M*;x{|inM?CBqgkfFrra}V@AJU+G^xvfNpZ#t@N?g(RykMChhd>(Jmqe3d9|HJ%nr1LNK!RW_Mjg^<+EP_CwvgU__Rk`qpq3ZI&MS~*e)H44f_c+@W%3=a^YNs$K4ECbItxDaz{_0U z{-u?~wVi8*mkzJ(IQ7(Z;%a)@(lbuX1fn0y@w%SDGSmnfmh~U3GVo(ZDY=wIs`;>V zIg2tPk$^OJ8@mF6I`nwy7ksBeOYjR-PN3PBHi-Wi^I1pf?#`V@M1Ah&zpj~*&4RZ| zF|J;CdcIxZt!ZhY7l__S3h3@A7HJ}`L==-st} z0}h**O5&IwgMJpa*T*CG%zElQbkENZL%R7i!nx!M96sh~lpQ2et3`F1sxLn1DB@vN zFw;?26IA7wTVjqqQw{${e0w#kUh!>$3FnRXmmP+`;+W;NUV@+gP-a)e!$g|3HX%;j z$QLV>IswrZ7wbLgbkD(0uwGtXl9>%TcFR+s=#@r`-J6^6@SFG2^r7dK=L@5wqjdz{ zPtkV!zoq(F!&t^C#Tx<;HZTAG=esfCEH%jrlnYeoO3aT+H)J=3{!YY`&nhie>yR3S3e`T4vT5qfB!ik0Yc9qqeJtjRBgW+SnMJY&s@jj{p$-@@U(ZZf`4M0;&O-e9Q# zRh_!P{Re{2P5$oDxtC81X1@Dsqs5%@oYOMv>K%fX#6EY|?ai zWR&q3)U1Xx84FWxoQyr;l+}39;Au5gup%ZxeO7)id%Ns#icV0vDfuz|cI7FqT9$GI z@t2(ELCQP1Uvkp5wYBWhLD9bs#?JVcPe%<3-|0{xT ztr$i;Ix}vT3+L1+XM%pD?@Mfju*+(9|!BZfopM~zt)972j50!AbpmhGZ}*5oUPZw{_yg~kLp*PFKH5mql(x}s645%|ZFzve13 z6}P)he3<8%pMs=?m6a3Zsf?fo0HEA+hAzFirY0t|qa`FUb!1Bnjf8k;+rH@2%Jy!| z;oB^%J}WOV_FPIy5XR&yL6Mg^pro}W|GE9lp7jv@c-uw^QE3?f$_$(FT|ef*(O$+< z)l<>gj)|qCqxt5}NUNHz>pD~Jm%N)qPi=uQV|>?CS7K2BHP7r$)XI=H}SBnYnKh!7mF+rpG|kUAO%7*_n1b1Mm)m)`J0ijWj$wLNim_ zSr#>WzU^4H*>spWThnO1C0Lj_MUPogzsr8R9Plc0PhL ztC|8-xqh%?uDS4<(%qsm0=N@y`&_GJ%I|ivOD`dCD0t1H zS7rk!C3a2=+LAmVkgmZFM2xs(+w zJuF<7WBe_TW)D=iq0hd>)Ps=E~H@o9pqw zyyT8`9h(4dWbV%c$C2SA zY3Y;{sx)Aa`U0Pn!?!m_k)-avWsqdcDhRk|171IEUcCvg*TZ?!q0W-%`6cis_A{S* z01q#(nVnf-QoI!+8VNqWjfKtE=PPl+MJA%E;|9Xqa9WZ%D-czGBj8Q3gkAGu~E1xK3+!HaR~Z8{74{ocBgd z`$K0uF*Tjq+&*AN(klrt& zqt@(Bl-w#5fi@L2Y&YB4%0cU$E~hi2b@b(lWrlcQtiT4U2>U~NhmFzeI@g+(5wvN6+O#{{ci6W z0jP{hgtp2uxyz(Rn`>@Zwe@>qM^zTGs!@L!iyxxC-;Zfcja;9O%Tl63iau7IDCTe8_NZHa5QS311X|cb zSK(D`V`JkXgcO54_>5!wUQvb|d@C;ZxPZzTK4E@wz<=s-nz8Hlazn%mzfs3T3ki9v z2{;_KZw>UoE*`tB}GQWEhIp||9Hb_6p_(h1$9vRqN(G{M;*&yoAQ zElWgBuL4VySHm?}_pWvk5VeH)#*k+cb|^t+U49(`;ppyX88{-6q42pou8*K4A`-6)XSgRXFaf#>$!pu^pW9V zde5^60mr8UkIZNA!#a9;!qB#A-CN6r_w`UPwofJ6E zIJ?TFVyqVQcQ(>zMazrD>s_=Sww-OaKQ)~`W|tjWmq&-;MoLgDziYh{1xemnr@z>w zyY0_Ml21{mdR~NcSZoZ+_ zD8U-qny}Bj%fTx4G!|^J-rF2`0z(NQ?6Qs|#QM2uvw|9s-|$_xc2G zIIWJYP77my%L3RqxFz?MoABaw=cIpyjl2;Sidgai$2b;X*(F+-h&95$qi%fuJUigm zq@FH2zWBZXYkUav0U9a{?%mh$-uJ+Lh)%xe3itmY3T66PQ$uPie1W2_n?dE?yb%RpS!Z%l92sT-c_d?2Wo1n-N(mAf*lXb4}^R75A9Ef z&v^MsV#|xbL)!1DY;$qqCjL+Zu=VCvK-&bod{W^1mEtol8dyQ%t)`57Wdn?XwKkEwKn&1`EGvyIwCp4?Os?A+uJ|9C?i zp3GF-srHLn@C^7|?rGq@(D7j=ZC8dedLRjLe@yngO`4AGUQ^q9IZ99C6J$_F?RQ#W zZ;wj#UyA9|wSAUl*++cB76uvbSG&F3IM6D;D5~p0LZeZ!84jonHwC1Fzi~i@SWQ(z znIHB7EE)33(*r9>s&)d=1)ojJM4tQU(s&~AQeADlYCC9PjN1q_y)~^pY^=d5z##x? z%&b0s$NB7;GEEMrEYc_osK=dA>C7~9{9#EQ|JF>|P!B1ZUzjoe(M?MWl-P<;i~Fy$ z0F@eek>TOtSH8~(z2L1BIf2_ypOBhmpTX=*8W9ELXf^ZUYq&cduW5W zs#Si8u4sA46EpA3w_ZlR_$BGWSU7%Mo>I4GtJpJqh!ABpdKU$xAEkNC+GQ)eeHbg-4$_SSQR7Y=&Hx7W9g1_1c!Dsj8W=-pm z+u+K|M4~<-&bxgkuX91Khp&3{+&f&d{08tF*ifX-e5-OeA-a0vOF#b#knJNXHO>rD zC9`%En}()#OIvI9=CxB@zP|IxVy&B*nc23CNvoTZoSfXGlg@1bw%j~^y-pn@VleLO z4IgG;q<0-&FM!E3qj>#)NXknIB3I~xahFXigamdYgNU1+oNQdXcJa;dfV zz^wAr9E(%(C8FhK; z`B{c~%76epK*GO++&r~^b!cv~Q7tVyCQm!#F7ue$MdDuyI=NLJO|m~UjJR6@yknERCd+*v97MD@Ol-i&!4up*FnZd5kvS2hU7 zO0|}h&BhMA0#IFD-PPJ`M_qi&Rc@bAeASR0NEwa4wKa9u>v1V4kZe?~!6XrTSjHR2 zD8wZ;VdcoLi3X~Yd@i6?ssKye&7Lg10S&I`EN#hD&W#~Nb7UF`@rV7Im=3SZ-OIrB z`(#4e;|!WMy7!ex)7T))eM*qeRUgU1Sv~m7<#f5lXvhQzY|*#NAr^VKkV=cQ=a$0N zY&Apwmt3adYZ~0RBKaXfHu|df4J#z<3E~?|wyY^!2?pxE6sZx5UmZ!DHds|s#t&_C zS})E!&1|a?$DrAX)Jk@TvTV#!upFEWEEHnRBvW#GUU{Gq;a|kX$J;yulm^YQ>cJ$ZKBNk~vdYaE>HTerV7kwlc@C8jAw&oi{s=};FXKMm$Z zOIF|cp+$f0A#!2g9U_b6^0F6l_EVuL8aUl~lYxsVt{G$z1njpF5Y{o|@20wUfqor+ zw2wpfc$e31S`djV2r`9NoZ*{q@sIhG zv>G|pkyI2FB)D;*iXM13yO0*L012ym9eGkI$PNw;%oFBlh=_^PB&n26Uc4UdLzEoJ zb)7oXMwCxeFeF0kWn+{VK=eQ&xz6VwK)>}bU*ZLJr*~h(Un#@ZU3X`Yz=b$dQflgm z^-@D6owY|63$uVgy57LM-QC^L$&VT(s{EVV(&uH^Yh7LwXfugegQdh> z?N3SK0%@05Ra5*lo=8IURajr-pgwnm^`bo&YY17wluB`@es`Q|;ROI(R(-~JWd*il z+U;~)lq%IdSyE+fY%DB1tQJ(`IwH@J4vtKN643rV{fNN*T>Wne8B?;?-g|2u7U?dF zW+a6{b~8EuLD^HKaa-$lHM{A63AL}{1zl= z$^xbhm0HO;pyfkGrcVHXQMh<*$BX1q_sgJ%hsRZ-H^TD$?|y<7LGXtRSwV(7I|a=a zUkK~r|21k&7~sA+*ZOCO(yzX>+weJ_1n!bRP^C^`1%W7P#P|}RVNSv9by!#0DtLEM z>r!%Z5LK9E+lRE2LRv=48hog2uU0o=jHALz^)uo{C!}Ws77$~J!|b(NrjzW@sNLr9 z#e~OND=TWiFwWiGgQv}Bq_(SAR2u<(=F)u1m*N2Dlp=QMu}GGB(+LXQ1J)Li)nJd*TdkV4gQ;UE;cELNY!xZ*iVf0rvDUK@A!lF%Sr(7b#8UGTR{=ci$swPZ-4FaA}wLuaQHs@ncL~SCCu# z*pAc=fgfyE8`x82IhT}AVg3F2?_)hbTJu^iwA+9I;NBNhmu0)YUyc%#=8uzh)&P1= z7|uaN=h)8!A4zO_BUJ{&slSGXays8$dD0SB4;tK!k54QFINHfcOZIZ&5`zv@>Qb#;y~WTHWsS?TICQ0u4j)4A65>tmm17w{$S81HdSy^E7eY9eH`I2ZT+ z5b|-~CO9`cdo$Va7MI)6HK2*ZQA8TyUn4h1?7lKt$8uUMT)91Q+qrm`dcKi9+tpw` zxw^V4?*N5|>~>nX+#Io0#huPQ9J~l{kCda#I1En=a9nO2`FTXA?e|!4y7V-ZTJB?^617W~i$94FoHCWLEt*o?#e`RXB`<@BJF55;UEkgU0r-9#ao0VMFw;Y{t zY%EL&O=~k`p)edZWLPP+ga)Lkd`LWdK%%9T1f-oc+G;`Whp2AULYb;GOiYfzKyVMM zwYBwR)#sXyy6t6{Rj=7?Xh+R*zGA&67@)6(@n(o_XlM*FddWV!MaBKAPoJ`!*g=z5 zNA$T$g$*PBp7kVr;J$kdxi$CzMQ_n-s@!H2H?*e}5+Zq!Gk@lq_j;*szx=(u&modI zf~ch>oGQV9bs)CJf!#FG-C-hdp1*nO1%AAFY-=B<(RcUp@#$)%tNu_x!Ig;%sy7~SI)%b?$aEXsE7 zuAiT4{L&7UA#&4adyJvL+QQ0zUQ)-nYdW z2qc^{GhDS@IWMb5AnH30rm+RW*r)ulBNWsI(%96 zVY0|GqB$gO7blP%tc%mC)AAp?<&*oa^pDnGE8qn`@`~`g#{fNUE!^w~?sN<%PI0 z6WZ7ViCjgm0mCZJL@6g~tl%;L*+jeqg*##2K4exT0W~cxPlgz8+*WVZApTH#?NPU> z^f*A7$H|^{nJc?x7Z0yrrlBSQ5{MxGYkJ0~g`@?4(!*n&lUqlGhjFold!n~FmV>i2smG*^bxyVCC#;* z)TWn5TQNvNpk? z^k(c*Y)8Doq=?~ZN?(<45i)Qi#WNwY$^%WJaym##kVV=uweJ*F58c!2!>Y?|**E4p z_Q9@>JqWMC2@Cb;Gk*n0j$PvE^qI-k*QN>qrdL*0a8fhHdwUCuu}{DLKkf&$+mSV; zpZGs5Q?TT@m!qbprtVvmwLCCq_Nx+ZiS-wC3oT1H#m>`!NLSkv#WRK=oMIMn9{?}` z>)C*K8$a`IxUJwk&gXE|LfY zYR@s;dQ_wr2mMBaq6xg@g-nn3oK{L&W>QbbsQ4u9?CZ>abBK$)^@pqmoLlr`6JK z87-@9W9-YnwYQofPqQQkxWL)UK$iX$F@{dW$JW}?Lf`KE!$V*Q0{7QNu*>%xovoGx z_5YAj3cj)ITwF7HMoL zz5K-+by64+JUzTFWkm*(ba#LE$AxAFhR320d0h2)prC%_347xH-PQQx4y)fpBo%ok zQ|{H(C5%CjiyVk>7vX1rzr5^15)~qyt>vWOBx$Hd#2Qwoa*SQQEL{+wP^Z)p8?R%R zzsY5lwtHL}?ZqJc%6V7k+t)Wxn0QEWiqq`w)nm|Tn!>4z#s+W6jkOs6iC5tBj9I1^ zRxs;7{M(a#g<@VN-tOOwjg18%Dz&P`9)s#{eZU76w^}LY))BVn;5iBd7k;_Y?7xR9`zj5y$itAB~y)= zm>H^9D3u=^6D>yaZ#pILJazu~iK-*x-qR9z7Kff#@ARgt+Xe0*ei3@@;kS#?Ko zPV){2Z*6+QssA>n@{yHO{MgD$nFeo@1MXj4FhwHGyR;>X(Pkt@K_ljJWrxTiMVhL5 zdUiJMVIZQ6myBrRNg)Hm9gN>KcCvYWU`v}SW~<(X8-Pr&?lxOX5Q2}E*bxuPB6fBUzyT~1AGn- zS6#Uf{Rkng|2nU%49xTo%G=%9QU1c#MAb001D| z9JjN?N~J2GcO@liGsdqrT9|-q)pWc}Yb7|bbXJ&LAaSrQu~UdkYI{u)$=^<>GqduF zmxUVh{i_S|OykH*5$yWo=w*%0-0fBN)R?#%%!S;0M@Q1jc8@kc)m&7vn^a(kIE!Z4 z%x8@;#q&VO0i`s^_Nf?BFKBv?gKFtFUOxD#va|-SrZlW9o~}0o)Xq#uJw>|{H}{+} z=Vg~n$)8q&rP6~`Pk}K1Xv5M4OP=e$UHSoHwpL5lH$Li*Tv(0}tfawlAWNp7PJH7;kU6gEx^+^V726}6 zoBk^zOeaNxB0RLOq?Z~JOzA&N7wemt?_Aa&;~KvdT6KPk>vdh;f`1VsAXzF%y15(4_+!D zKq>Y6BC+=l45UT!-?R43pZ#?xa{og*Hg+<5DHOUX|OxmM#tD{Nph~A zELE@>z7N4x8tr6@=Yj7~8hWxQBAqdrWeQmQM4uH;ckLVrG z{KDEJ(($-#tQ@$Db*`d^dH7=E%yC0C0_#E95D%wfJZFzegCbi=_Vz3tqknx*sgwOhHCTA3wHx zN+x|x9Bj#vyn1<+HW0gQwEWmFL*D6>^=-OvN#*vF$(0oyDa!7~O;Y=mPJ81f)tr+H zyzpl|^v$He^~}uS{`JVl=f|6EAQ-gBSDq(JzGQl3FX|Be&!#dIy~b$yn%DlnTTg}1 zYcXo&fn7KN&RcX;J%|UAD-W_8>0Dd;c6%-OBFWX$43wPaK=Pu+&qpxLFq@KKBC4SE?`RaE2!RFeKYwd4f11><}(6#;p@fz2xUxNrn;-@&Sv&&_BY) z#0?Rp#R>VZ^j=X&nu$bK2o*@WA8+|AE-o{gUkTT&@e z)S8aQE`-;yhjquoIchknEfaL=eJTovzj)pKWgX*laAQg2YrHXLM|iwFN!ErW?gp@s ztesShEcJGa;Ib;0+OnPr6BJa5haai!MjbTNc+)Tgy}XHs$A9+62;Gjnj@d%nuQcgr z&`(Bb3M}gBj=G=JsZ!L|_dQH#h@wlYYLv74VjwYGXql`GbG=$m!Ygs=+ZP zOOI13`sA3GKE_9Ix&5gq;fzyCN`g`pSbcp4s+$!yrz?dJZ+TP%vEYReB*TY_Y~9*-|Z*ld*~t=$a_urT*_B9t zbr3#KBr-&o*_!pQkJ$BVw1=QX_DHCI()USwjA~&GA?b2LS$T+!G_3KiHg?&iI3os{ zJD)5qfLlWuy?-9L)9(XX3r>HihShCb$}bqfKx@cAW>pWot!D%Y=LCk=GE6{qR;{c2 zU_TR87nL!S=}#+-21{*L`PdMY{O9<@2b>Vm!CjR9>>CLoGt-BEzUSvKHiUa||M(H- z;uq0}EPVpD?kr5$355+h|lUiHwbse#GKNjdE~B49_}&u`!r zuV@sM&>{3C7ce1_hrk!E4y_fA*nPm2x!gG#_-{i%iA;Hlu}f1oBT8$f*E!P68Y17j zaNHY*1Q$-dANyhm;%=?3@StWHFs8CUs_p!WZ3qq?u=qT~J9cDAb=$ou_bXDMLF|JS z!8XzO3>HF%rX>#vA^+|u$mh}k;w9n!dP)2+k;=8z`($1;g?-i!0&^PzyPQiv2kVJ@ zRdz`H51sxOB;+e9Y9t_(?H@r*-!}05~(h^RE)>f?{svq4AK` zz3n1dKH!oi$aB~G`nobYX5C;XSc==Kve5_$QCNDKONAslxpTOKa;)S-6adfjL15SJ z+vj!t%7$iLF?K9o=cB#Wi>jfUC|x!+q+Je?CbORiu@QwwK-#n}pTF{9qo+6elq%I@ z^%`2q%Q=!Y6-Ku+QfFd&Lq4moafK7|T5YnqXw&aj>`TB2jX+>UXO;`%!pGW^$96Ao zJ<@^-SKwF@hZXgF^mbL$w7CH{Q}ywzi?fbIvJ@1wMAt)bW@VjdzT;_8?Q{0l_jqJd zy(Xg%hOd(s8v2#4z4h?qZ6a?}!Ho)$5|>Xk?wm@PDkSP?8bp8k8}12_)wdAVzpAqk zzx*~CaCYZC@W=s;gXraB2`rQlP8#lXPl8N$--+!=>er;PWFE1|9WE#p1buf$#!`v^l8H&6aw7C60qy?AKo=wrjiEN+USPIY8%)0hoB6HF~=A4Xv(*75lvOd$vz zT`wL2Sm7OcPBIg8?zc}TE=_3EMY10i@*H*rvawczr@gx{du-OU{)+JJ!V(K*^qva@ zc{28yoo09A3Sjs&2+6ycAr!=o&_t$W`(ke0E^0Jv5_*sW{8mT?B18fyTH87BU0*#{ z_*7WoN<^e=ePes$@eQmY9)cB|U^0sir50b1sg=AMQV`-aUz04gh4&g`^Oi>hwnC;n z4WB&8CB8oqugi^|$IQ%_yyJwnOIkjc+ziI{lf(>kFGX6H-rvrVRkc)!$S#S!zOSVY zQ6CLv$V<_UK?83%L3HqJ@1h%EaXHoG(0Df-d{V>}?uu%T+A2VaGSr^LfERlE z*cMT^5=`?S1aQhI-qVI@KTuE$dO}sX9upKi3-64n!(ESh^#*{W4dHkTA_8Di%$$n7#MLoZ7J_c4E6T-8| zLq6kRD17E;cT$0bbD6V0*&7_SD%EoJmSs;%$P?oz~HE0q;X zlM8{m?qwnFY2PJUhb^p)R%&bsoCvv;VfL5^boXC1T+%6&fADn?jKqn;B z($zhOM4=!eh)z};49e_X;4YDVaMJ?B-+m#6lzYpy1++_?(s#T!TDDV+*{{G|gr*^2 z>$eaO?n(zApFSk* zePUpG8oh6KCNyF7+|uAcx7@#+Bx-;P`$|$>xrpanrS^&&h$cxQ!1?v6vuO%$Z z0+DVz`~2h!md?5P^(J2g($U4l#EduUQ2t7nLj^7f{rxn_QEE!b~yPa4F$wxS#R46~xL!(Ly0m3U}iXWk?(SS4w zX-RE{-)z_Dt~ng}nIW=~tj~?Ef4bOVRzy%!xI-yWc8m}FV!cX%Vc(H*SSi&hAla97 z^#dl?whbFYp`xMTjzmXinFMG^sKfuSvjBZ1*IiFbOOt8&>1oNSsUz5W`)g@FqjJhb zs>+h6)S zpF|>oeyBP+pXQvfTfMxV?Le=TVj9`x7_rYBHSObu0}kyvp&x`@s*|>`E{iGG@4wB( zo-@jNYY*T*S zizszt_t{zT3NE}|#2Nz5_8O_=(`=;(FaPPkIv@{kVpwS3yaAyEimc0$Nl{}3D{Xvc zw0?Ma;A!`{p2?J;ftQ)dBG4(uhIb;N{P~o&no*JdrxvU$?LJIM}7u|5#@#JRD#Lq=;-SDr;VNEIc=wzHtO{GR*9dH_WWM0rqz&fn&Ng60vT`B zM)$Og@i8biy!P=5lm|(UPFqYJ(%*VHW9-A{JVnef)FzTLp}_sZ*JX;tYug zUiSJIQKg`|m(z#D2JeLAWUal!)5A7M;Bu>A2B)E0EH*dj_nn(8v*=bSW};R*FbNU5 zNgLqHudbncufh`RsW8mZ)BE)Fw6V9>ugsB*n(rF_+(l8~(AhL-Q?yPUdxadstMU&C zAarnWK=~RP+L)VrB*l{|b#rs=R9jzPUt3#S`YZgG?5g)+>Ep|0kRXrax7C-U1M#gK zzW5w;Ah7POwG|T%^3c9xQ#P93>naowJ5^$In-!*~QJXQ4ASYwUYW@cwDHJKKOf-s) z7eB(gh{g}9R`9k9Z&xOr0mgOEuO!_8M;2ETSujRY+s#W;5J@-U=*=&ubm9b9|>YQ!6CdR+Uvo-@dN8tqR@xIxb$e;zK2a0hg_EWH8Q%IGv|_&MakVx_wS*MpqX1a zfH0X2a^PJHaLZjFlh3{a*@dQzv>XNY$?3_<@l=g-hzkg_zUUSJdZVBE+nV(NuQhp4 z{K)Rz%Q4r-*E1Q{<*wJTN}&#r$c#Tuf=XB2#lpbQ+}^&axY?sC_nl6QORa=Ahm5x( z&P}KxaVl|cXI4?m@4SB=AN>BFh=_=qY|zMoPIyhJQ>MX+=(rG-fWy(*#l>dtWPj!N z&~}_dfIZwrFqG%3|+{aXW+^Q@8>;b z(1P=akPhD9PsTuSh%{@4BZPL$GKom#U3<@+bPb2>qaS7wAv>l%M*$1Q6kQ($PRQ%} z!0_0J&Q!bIX8fVa#>2PWG93_O)7qwBj)|xMS(|?GVQEfsQ&ZHfFm`FF&>;*nf}ev? z4B|nL{<$~VfuuZ{Zt=nJtCG*p&*PMOsWlC#8It@K&v!U2nYa&^5}I@3`zV_Di;&=J zIGpg>{>xt?1VyM69X)j~l1UR^PG7#|waS}hYeyKg$jh_X^=t*IL&d_pZ#%udy}jMJ zyl+vXcUOv5s*c9Sz9c6ncX)jyV$TNRE9{T@BXJey9308XyS-HO({QIy?mMdvIeMgj zzfu|`4e9v6B%1Q_O@O1FARu;i+?S9PDnrrp^3&nFKBxZ67F*Kz_cki0GHToTPD!Zs z0Y03uYqFgJm>cW`WEfM2UxJmu8+qyAD_D|;auP=!m*R7O;fgXAYK3DBFBf=BO#W(< zv6nt#H?}WN{f@ChrdVJ{vP|0d#k8{k3%YS_m|vz=Kj0_Uc~ZCl0C6#KrujyTInMnB zaQ3~(VZR*hc_afY>@)c47JO!)NtbuXlhXg9&&#vyT;yVxOwlYICaWSUCa`OYkfUFD zx2a5fov+*@we9XMAktlUL?mvbi}9uxg2U{6lDUeKS&CpdsA-aYug|`xkHQ#lyj|qv z>f4bqBTpZ_A>@uX9GiYOPOWO;Xt48XX>#dE+u7Qhk&~4_b-C5!_R6Zg$;s2v5I`Lj zzqBH6EVTx}n<8o1O>4Dre*~=BmM0|H;1c_ zMnQoHvv@f@HHN{IH>Cf|d@U?2V{{w7vE?V@ZvG%P4Ac*Hh`!X#Jeg?thisIY*vwaC zZcd03f5@J^qw7^I+r;Kf_?i#0Z9-!{q#-r-uM*y@#!&Gy`LZ0P+PQHNDq&*>H+O~T>+6C*#`U86X{rFYsaP|I)x_y&bE;t z+r8x8Caqxb1wC-=&8-g>IKIfW(1S|bI5~9eqWZ&0bj3~@?ENDQ)GT%B9dG#j8_n2) z7whQP5KlW%Ryux6K}XyOA*iUd2oyKuxZ8g#tb+(q$hWu2l)I=6+L_klVO(U2!zTUr zXm*hiL$FwuZ%9vt~FQ*Z{D6wxy87a1 zXdt$`uel?(ZUA z*vWw>%Cl^#ZS7)4dqrtfW$+==QzjK6HonHwoGB+|qFBqz$%|_zA8hONoJ*BQD0PU} z_qOeb#D;79(-VA{#nlg|on^4`Z5~8}6VNbGryW7AvJn7M^U`xmM;UF(Ah@BO43mA= zBf|W72-mjE&r;KI61Q37l@_(whG|Ub>SRZKg%1U7Q>ZjbVJVnB#n6Q>Ijg&ES&sJ<(WKJ;W_u;7 zv(yTQ=S7#>4?y+N8Q+Gw0NPJETFFOP>x;HL9ZM8>4t-mXLa(d(e=;A4l(q$>H-1^2 ze2HIO^A6(Hf`-aiNnk@!kdNOaS1{w(Aq3#)YH2?@O7kl2D{QcD*S*c}+Pj#^y)nFkDb7w=uJ|~nAXAoBAMYqT*{35>n6L21v) zz;=KAmaROlBBPSmEl(j&+v|7Hz|m9#@|>aF!aA!m6IeCzb%5iH-HeGu<=8Sdq!8jd zAjOuU{;;c-&&#HfoJhq@=%lS`q#qLoswnXNS7q3tEfz-AVD7=sX!fw9-H*UIT!##O zM&%ak7_$|X#c*2P;_$~|r{M5s-Gr-T`$cJ}_r3|b{98iej?!!EFsScvL_g}h)ztrh zw4K65vzUz>k~L2eQCBOO*AFUs47Ip##ya;^P+Ok~lb%ya*gj069c|jeD?rPN*c()d zg_|JhCUMiCXTL|}to3O1q-ZH`h_g~qiOE7fP{?zeTUOhq?miOteQYm&<5VX7iorej**$yzs??%Y%`HS|D22$&RQpEBbd1Xl{ZS?F=UgcO`sJFy zK7w9IqntuUyj9#Wts1CuABwWi-c4&xVDknV2+@wa-#sL$rV@_yu9!sFn88xw>ObdV z=QawY+}vHx{+ZO%(i_c zo?Ey&o$t710dw~f4f78`DT&znY_iAF`Kj z^F%~U@NE^5cHrc62U!dJ?b`ye9EWNg43(R|EQ-|IGMdqTSw^jQCRy2N$!@0BiDU3O zk_N^dM_8wJY~i&`fHJRKfhGu%H7~H5piu})h#hGYnX^J-)R%XdnVSS3Yo}{lgIni2 z?-F{sN%W=iw&8XH!)dXx61&W8S;)f0DsmHQ!6yhmjyS5RGJT&$uJ*obbG=TTD&$M1 zkVG+P!(-A&0eEOcam&R*sQ_Hq`Aiw@X`GDR>_nCs_U-*Pkz|TI;(@>Vcf=ePovskm z<7(Q|A+n}D@{5=iyF0{stEq%7{Me>X_FEJCP4HA|_v@DA#?6`q8#zzX5E0Dqj%@Ez zwit_OMmsVzisvoSMSBo$J-&|Yn^#70@jUS+)?txDgVVItvX`a&jDoaZQ(2jX=3yPg z$<}Zbt@7E)`_j87Uj%#~{W2Ojzr(k+lrg9a1y#U7i9A1mY2nu@u@_g7>T1$af1G?}m{MHkeON-w4gTu0L`K%gYi1x3j*Hhxo7C z+39iWuybzAUZpvz*uEVC-gP4dJ*66128hT~OshnxoB~27LnZ4Z>moo1vEMhzHySU% z9r2@)qKfC5MTIS0hlwlEx^g6#5q4pcja3=g)7*mN*H@c7DYmK7hO6sO1%zA3WNM@L z*_H&DV7~rX$x4_{a+gf1R74}1lsVYvt8hq$P_u#%B#xMWlN2lUyig}YPNG!HwB;pB zU(a3ET>ndUX%=ZOhnq@oNL6B2=m{F?$E@FDX_eWogBwONG+dt9s#Bw|+s7U4DHn*X z5!sI_5pn^P@gITV+q^1na#({#-5v4vo~$FIv^(uRwT#|}7c)&Q?C;teS78~65ACOC z2K8W}m|JCm!jU*2jt)i2#lZAfh_#Tjb$KmIe9fvAj`~{gTR!ixO*^qLiymGRlu?W| zEt9_Mo_0Xnci|%MB_~f@6=A!*bV;sCF?f!t0buA8SH5MVL{bSJw>?IAEb7e})pKNJ z-&=_ls}}P~(0* zB%wvuk^9)3*gy-tZfuZ1h_9n`OEhfGd&f>8V+VA%K{U4ma~(NyW}!j;2uBdDR(Gv- z9#-d;7o(7U$4nlz63+U#@^|Gcr}p?VKud2_u=VT%pqlcZt8@? z1GViM8EO3nS-yxWnVPy2>|9-lC&_StwEsGNnTfnL`c~mX%PuW{HC9JX--A{P^Vaj`0(jkD!uJH7-hzmC72s%w`Ts zQxQ~XhL)FOEL`QJ&?K{has)`6i&>>69<+0`akD)brB3w_SoHDJW3al0f{K*%DdrTV z_mHSJnlwLA&t-S*Q+;J)xq2dwc+QYW)1CD13c1dtf-CN|HUzAGs1hH|^IPIdBsShU zZz~?TSowFiPQlK}Zz34a4T?PMoJ>A6jus_{4d+#7&{o0=zdms$PT43DOJjilK4Zwg zpiEAh+oXKN1%k}LRJyBEV6d&9d&07s>6$dyi zuSs&h6nj$}HUqSbFsg+ON%Q8=bt>Kt^?Wm?!}~e6M(d@`lx^=%L5;t-n5Q}9mq|N+ z;8$KsQ-Iu{U7-S}^JZbO3#nx00@Kce{~lyhQ=BAxL&%`@A3E!_M9H=$%&{6*a zSr*^OfL@D8use`)+>0y^$7-J_7%@RXDWfoh2e#WKEAbpMSjudPZ$p%prBfi^&XAhG zxR?_Psw2vjhNV<_Kw}0~rT*nm52VNe>unM=F9E(^@hTkWV&B~_w<~zy7e-NU@X!|h zDStqtQqY<4AE>d#wPidDaTb@%@x5601e8fAZ;-Fo(Wj_xkYDs0+UcMbbr;dU41$V& zW*kxLH--TjA2SB?%s&diF4bul#_+22gXQiUG3a9STj*~;$Wul}{$-B%*r2UOTJG$x zD|?GyE(FxZHp;9}=JKi+W@GIvmN{OrGW*f$DzP>t|8p?wcej{1P~;i6N}K$x2Pzbl zLdAd&R%sY-o@axr*FEbJovc^Ym`BJQTBHF-{%HXladd$-WJ(tmv^|iS36$SJNMi|C*{_%*yhz1Rb1M60dF`|u53_1eS4k=X@3UF zWF!V}OmXZEUXv{ES{+DVXgbjkJ_BbTYRy+whgvni(@YGF#JT%5TS1|1)vhMk1JG&}1?-U2_ z#K-FLZ9sah7kuaCHX42wkP-Q?XfVf$?C*)fLu?fwV8;^mVKw_@)>PLbwUD1S1$ZRa`US!w{D0fphhx!i< z4)_+IboHE?AM(=b1Py%`AJKxv_yF9$7JmC{i6cmoKE^-uJ;wGQI^C~tf3;OmReg=? z?{6(IY%q){^BcU@-RKtPzFS1x)3(JGm9if3{h{rZ^#FX*KJ=tms(Xbf-1^`Jyt#|I zq7p^H%EFjE&yMNe(<%~vj~}WoPP1jsq`L$Ubl0`Jrlggl-nb> zw~({91RDquU3?aLRV{g;pv*&4it#poSqovtqoc>4@mv6}3b<{t20K0a>x%WA8)mmt z>1JFk7xn)dsw+m1h@D;lHp+HRAU$5lM$>ywqxF`QiMT2&sx0N0#&1I^hAR9C%CSZ| z88dL&$rN}63{)hTfpV!40qIV;wWH#WC<@n}0gt-&A9ks$+HJ>b%j(kygB-&otgS9} zqyv0>k_|4v(m37QkD;*=%MPTs{V}}6m@_YbCs*j1roJtUPL0xPi-$H#3CerQZ`iTiy{ObKQSGr*Y2iS<@oR%UK!aFl2a+(r!asr@BRG~*gZ}MM*P-nO z4>d<3Kv?NF8=Ne59%&xd+u&jTge>F$4&QejwF1*!;xM$OI3+G5>vh>26f(G2spUXO z$k}h9(^Z8qtp@t{mh{Sb4qsS_u9OTl+Hz7VN|&e^vu#I*0|bGV@2djo(|8Dc`x5$MdOMKIY+vC+zmD6(aa z{2Hcgt>ik4a7%=uK9QB44`I6t^B7IMhV$+SdjfJo>jUj$k&pH!eT+Nd-x5mda2g zzdlC{C3KllG?cK24B^~OQDqF>sRm8rIMRM@F%RJf4JV$jCB&`?@`wC^eOwA+qjq~2 zB-=a4+{uve9IJt_f%cYRm#fh?p0-q?wx8p7MQQO=@)gm903(=?(%2zgVOdWFUPu(e zoEWM;Qy@@AtJ8GKw14#0#d}Z|R>KS38gqDr#EKm;I8k#=X<{4aG*e!Cw0+tc;u)pr z+jqb_?P7rZsCeff{4RObZ(SP_Osm*im9hLHg+g-x)&j~N&qo~-huYuZx$PCD@cfJG zZdq)Fe5djoFv+Wap6hG%twpgd*_EvrN}Wv?jpkx^S_L|)EC&_CX6i!b>JNPKs+7u! zKX6P(ncPI8=B5n_N*<|*Fu!P}WGYPBe{id%o_6`C zO->Vpch!fnWAHK%^>kf(10WFQ2fY2gQAbGHxL+E4wm$qKMY9Pb};rQLASrqEnL)e+`*`AcIz=bch46 zEe1#Y=eLj}soy{;hZfw+F^?7E7c%O0u_X)}lVV0T3bYg3&(#hpz{&<+WC-ExH4);eVbo#Dd-HMPnr5gswWiJVSx!;JxVu29~>a&8`OLRZu z7!l>E)f81lrh@$(a3RBTe7qEW24gz-Y6`=lPxo66Y9LZ=6yQpVG}yxJ=V3AW99`e|at z2r&7j>=Ud1D$!w(6eKvpn9iQgm%cd&Pd+GU;;Ac>cCwldh1{K2v?hjt$AG`B(IEpm z43sIqiOQlBTi z;y`K(Jw)}QxEYpMQbkafvzeIg-2!Ga+WWnvAz9LU~nF|b^ra}Z7B5ZX)ViWW*)m%ZOqoVR6Hl6C3Z{R z_gSwxFCu!AzVSeSCpj3>lTcqV>*vpu#0_r%?CunaWhPZ$oV=B#$!Zx3yWx6hpyQe&imJke z2uNnGB56|Pm2WF#c#;OKD);-pFV>Y>&MN~f2bG=UzQlmr3+c_JYo5V}FMa=LAbxUz z(+2_tZ58X}twLj73UmIx7>O@`mz>xORNE>DGsUjCqft{BprF2mmSzy2l;=Oyhg|2J zlN$Rc{SdSE`Xo*tGh`*|bmE}!=1NnLKp{%1Nr>*W7^dXlfn$L7&EkWC6-gzooE4lF zfmU&FX?lYD&cfaAgM@439<0Q%KHWvxG&GrqYOf%@Z~p9DMDX_f5zWqV678%u3?Cp>Wwx&j_`(UnI0 zGxCrnjPCSAY%GPSWiT1>;*DvMG9lYSASq-Pu~fFblEXh0jqMjW8+Gk8SQ*HvAu)T6 z_LiAH23uj(rAXzF%5H``Z|t?dJeCe0 zYe(NDh1<=+K;r!Zlb5NyB|{~g!4GU^m)zZ!7<8svz2c3~O7zvJ-m%D{b-Q~NNSfP- z2TjlRuq7jQ@>*HI_&NbBqiHv8++g=Rpr>x5xBezM2gl5yoFy2%-75~Vn4j18_80pOH;X?03+&4&#^!2<^c-sloelENz= zrZ`R!&%X=FEy|khpG?@?8l42SXcKi1$X*{Ka#tAAmS_}d8F_}_vtril93AFtDk&-pC=>bS2lfB{^xfXk#m3%($@sgonSqTpqph{c|MoUMLlOrY+v_Vc zC;R9B{QCNqjg5r`ikX>>osEN?g_)BB>N7JdCp#My>F59LJ^Ak>CkMyx_N1gx`u0xN zHvfZi|Fir5FHOPnvf`-7_^;0$ph`*r6d|wnuNm=mX(VDf&i08>D$zx)~Ule8`K2@2}H`712BrW~ib*%Hoq z?F#bWLiuwuzh8PM`Fo8Li?3VD5NCi#iW{eob|9*HMUm`Yx~edzsxCUrd2Yo%JOsNZ zJhv)UJu;QcPNUdKBiuUV7By-O&W{3U@Z-bVoi{s2iTls60RVe<*|&&DNpiR^e?0h4 zoo;Wh4{yCsZ@n4LpmqMJ{m_FQ#xGTs$XA3yM25p1{Cd#aIua2ek_jd38zcL*&`=SE z5qcHIn^rQ4M5w{;$_AFHXxhBGa`tCyEu4}LgS$VpFowL@G%2D6ZIL`yl=2zB3>6l| zCK6dDhCn>QT&!@^Ku(M_g*Vbu8HJ<)Oa%;=WzE8{h4bkjb&KS&sd9OE#Q_R6k1>{M zm$V$3HZsY{Y~-~F74urRYkm+NnKwYbNZHZqpkrbJ{tQTpSRC^QJDOex(3XVkxWaD-=(EXbq-wle#YI928;IcV;k}I`2{>B3*IBs@$eX3_EJ&Z^@gr~ALrJbMDjfF4RXDRToo#m zCzVwE8Tbi5;@m&|IcDzWn4$2=quz3JNbUtqDo|wB-O20>-{&fR_4jk>jG^&zNbEd= zYD)*y1i&xJ99FeDH>0W8(S3a1MiQkjivkd7b?6T4*-UA2ZKL$*K!C-Ht_5>+cxD0VZQvmVtU$fzxpyh-?;A1${6{*w~G=VJ7uZg%Hai_mAl zSFbN(O`5sJT}3lBoE)s{x0sUMl^P|KGd{d3Jp7O!eMJiV2#4E6C$4422l$8Jo=wVl zt?_TWgJ&2oLP8vJxeArvXAYuhPfe|b^Jk24F(Hiw)262N@`z7tTTGj465uPCZGnmf zF}~S4ZpGC=gdOB^+@WnifrDgFzi6CR!ji38SP3$hq==r@u(H&3c!%#~e5*|ZhjhQ# z);g`Rt!1d>#jhFmlS=%Y(|v4*;a8K6TZDsb!$S4_N!HM*rL}OW;)JpuQ?i~(rTyA; z@GZD}_HbdMI#}KnKY9WnQ=7TR6Pla1_(L^6J8$sMiHw$fu@pfa4#k$Q618a!FXEdo zRrdyINX}ME+K$^U40^)!k^LUpY?vm8I)|Z*K6AYz8U#|L@3Ut0xBC;PPV);@%oX=> zjH3%PF7i94-iQeEtw=7kOSVS{(InIp)=Gt`=8Kjp+Ra^@bTXcBAY-v4N-?wT3@^6! zVg+Z}IHu10>{8Vlmtjqou3=-tTka`6)s8GS5EhlHf zz>0yqas4O}LZ$-Y&$(F85!^lxmjI>gme_w56%n9gR)#q1%Wpi3PoCNzblJ`Yyr=>_Eq zw{wCrj|`uSeEhI)P{+al0PJ*zwKh4g5ZW-(%@#ZrnajQ2x4de0T_w8zWth+%DTJ z1AfczSrd`vs&DTw-w1!Z$YXpqHZMY@iIpn4RuPTWna0>3-(M+F3M(q2jbp3DQI=Kn zK!~Ck2&X#6Ly<^qH!CTpW{{+}IbGYRE#@AYD`2O$vNBjozc+;4W7kBxNgLMaomoG; z`y#AZh|`wwG@pS3dBZsN1}~cXkU3HvM@a@X)Aq*Y`WWZ>smMCF|s} zHF~!7yG`N(y z6-Mt>(F5`&s;zY7WFz>RXF`_sd)6yVw)WXIWzz)vD%+~}*cX3!26f4{E{8LZ0lY4g zYAL2JI7P}Q>@Paq6!$O6g|@!r&s3RRYZet>ap&u3*8cnx^OV9*Ac}Io5}ZwMVHJP; za8%1tLWRAPbfgrbL%^|~Vw*j8z;dB^NHFhlgcu~39#!jmP|K5o%?PponA)cYO^?~1 zFyo4=e-06DO`e}UGgJ%r%n#SvN_h*a7lBk*Ra58*Zh}S1QX+8SAts+RCGtTdIjhv5 z>-}0D_|$Am-D-}*)6)e~pBuOTGUjAKdbNyi5!v}I_*ty<5mW!xhig#sbP^_v^FC7+pj*0rp zDk>A&TJbY?6;3+n9cOH_i_)M9EV#ah(P6E6bLPZ7OY_W*lMJbRaz?6z5I{nRSV192 z#?&tHAAr8XFuRznUX#4zGG(KCi_;w`L-=qR`X7CcshJgD+2s51!+l**TXRikHVq37 zhz(5Kf_)zQKbkWnez}5ZV5E8s1X~v#K=}BDWo2CFoF85Cn<&gYxP2KEP zL7zU`_jotWD@_IjIU`NY@DzTT*x`&GU5o5d^X#^p*+{doL6s_0xQvDMwfM)?AvYQO zf*7eL-uR0@;T{!QC4dd)EBEIVyp*1t{+v~DdVJAhRfoMRN%ya=Oe@j@BDx=l$v#pU zHqXuGQPpUohTSyXPTg3pbkGeIUPHF;9C&rAZoCi`k!(kYK!=ok z2F@FICY`mgFOPOI?otP`HhG30v9tOYhMpIi)#^i22?P>Ot<-CiGJYM~&hK|`pRb)8 z;YacdkaX;STIj`kD_4D-XVwo9wY}L{(orLTTwxS%p|p;Zy*k?jdtDtTS5u{;YlgnM z)9qP6zmkTh7Cu*`Bf-RP?xuZ+An1mb?}VN#PRM#^E92>*04lVsG^kJOH&O1+?^?R`6^d$kYRuVv<$pg@M_iJWgZ((sPBxc> zzzhby_RQ4nvnXoi8H$DP?PLsp;fzpWqgCTpPxLo!FTcspH=Kh{K0LS|VDgEq4R?tk z-f@WV;UQnPWWfp-QwP=hwfTB4;wS$}U0|f9YGu>3aNvkb)|g%CsH#H~iTqsa#<$y@ zBVlWfT&oz|*b9`+PSk)Q*y~F*8fVuVmh3lV83-&^Gt5>>kP&MU79>zBHJ&9JKl^p~2rB0})U}GOGw7|8>1~I+=ZAG(goA9**;~d7* zAO9Fll|iFdnIff{4mX<2_Zvp&1Y%V8Jze~VWLqZSvvVBx>9gx~YQ3plzek}Ptg!Qy zrT%slCF0<4(UULK^IZ9M%fN(dN+vV)x-A#EoIG-gPTR&$&NQu?Tj$U~*nAd#XlwD} zi3+P{co?P36f)TdFNu9NB!#V!E(F)deqk}~O%z(P7~y^cFO$#sMMlf4S1RtRj?Vhb zNrvLldFHSPhIvHxP6>uo^QAH}?@{4Z9UTYV3Eud9w4_3z9!($8>Ps>j3hvdfzuR95 zpF8c!m~%KfGDAz@k);WWo=wf8Z>}8GYZPI_8j&b3uFb^3xf)Ve$~u2fG{SHs7zs98 z@HnEe3X`d#V}$)Or$8H9wF3Vl^aC;;U-=Wtk6%=9iAG8_;@iH70ia!<{|KaDU&w() z6!AWSFaLP3nb^sd)z~x zIS3%$gatQklt=vPu7&1}uYW6bu#sK4w&`FM!C`l!K-<%nPbATAU}4Tt&6i+51Cucv z?Y_jX@63KLaC~DA;ZT@X(D%%T<(g(BWUFN2SF;Ry3((S--5RL}co)&r+~B zgMYfx@#}RzC7hDlXjhy5$U-v(Fznv4a77&GwBnUwuTRKX1jP|6Gz~BQ|jJ5dTTtNT?d^){&34ona~B z{v-h5HX64<|0_IGlQv-PfM%Jl0Bv=g=DY9Te&n*8ZN z3nveL#CJ|DZl}sSqvWo953>@7e%UY9c^C*=8p^b|Nun5Oc_ktz{N6E5^p9VR6R&l` zdhJ6$263*LxO&nT>oItam$rFr$qO6N;)J*@^th)isusTt$&@9)ReR8Sc94#N_b9`!aZhv= z(R4je4%ue7CB7>5_7NJ7J&y0|w!L)L?<$YAAQdVWo{5Hl5cFhYkSURcg-Yc!6$(Gk zOrOn|2=t{3f*D4y-t9OEymQoKXn!2&`%MvC`6s939qga$bxeHoUF(|k`m)+-FYj%# zSlN$xQGo9EzI$v6%(5)88;wja0w50-&Vjh(K4RAdB7OqQTt`{VIYzC~Q1H2pL)odp zWjM~%r>swrreq!I0?*RIzVTAq9jUix!N!`_bxR~zKt&ahC0NY`O0Ey(w zM`()N9|=+ywI+gs`Dau0)ovr2X)mR6b~_ijDP$aTv*$aRuq_T(whITk80FcAUF7%Z zNw7Z;%+0ObJcB05#Jq69hhKgA9ai1iNF#2wOLP}|NIZ9{wcoc$c@%r@B|$=+TCpLf z6%Q9#T`YV0e(XkXH%{a?iUWqiKEVJ#0GY5Nj>C)OJ{!bmLC~NyqcdY*!B59X&~Yf9)~_q^f8>zYoAQ-;lV-LwN=?-D+nA#5g9l6rfZ7tX1t59#==Fx$&?+x z?ZP9SoFUiDJPMr@Zp|?~I*y|4qO^UqIWSWhuk<&RuRPEOd^kj7?@7uUD{H`>{J}Zm z^2)}G)`YM%x$?b?=W!xa#*FD_jVkd6Tb{lNi(1diMk z@Eukq<-470Ds5-oN{%j!16n8X0?#gpdL;zD1Cg9lmtn$c;f8HK(4~v?4498PyS5a%)}qayrt1~eQ{{| zDWZNQ(kXpaq`k!V(ZU(Rt>)qUZwHu0TIdw6xOP1Oqo?-W%q@69l z!mOuaFYw6HS~y#EN}Z`aTl2@;At@~jR^P%;ZSI>yTtlr|b#|+D$6T#xORC8aVr`Gn zBn}(edJARbB%zuT5a@qL>=Wgn246*-tw>{JfWXGizJ?xnx5%pZN1v_IV``c2aUNUS zA$+HHvE}Jf?dwaEZlUMhZFFq^!%6JZij81+22`x7H*WwbA`LEbH@z@vNiCkDU8JDb z!v_c>w7nVJPQmup3XAlj4qvvz{O%io^Tro^-y_)Hyj!lWEJdlp!_PjW0@ROsSwEcS zJuvi#f^AsFp0253;bNnw`>k6{J~$kmD)*{%_mLJ)YbJsWyOg-YeuxVoJ?)rY5d|9D zH{{=`@|EYU>Pk4h@sbCI>1?F6G}tMbJSBe*`SvB!`r6_8?cVTYDE&00G^20CNq4{&xs7cC&Z_P zOP{ah(r^9ab-j$J%3S#pm4+c!Uvi}0x%xaL=uis8V7(m3O7aG5GJC#!P|~K2B}_mWh0dKCZFPQyi8IL!7+Rsv3^hTPa zA(Fsr{k{Vlbju^Do{A>4F0Rj*BKTb32-vjqn^J1^=i82NGXGJ$L4Ou&V_wJ+$*~C@H-*T-pi&@-IN8;Ea}j`5eLS(<0>iNNZPK8XPIO zLcqPtxM~CI63`?@5z!B(^2gY$>YXhXnhZ1rjv^0(%;VGFRbdJq@~s%MPa&V$J@hlj z@D}2rNKd$GLx*>21+ZecZo{j za9{86c6UWqP)J6g{D5=S$W;|oo|_ffeP}MI^yU)q*7%6c9QlWrr}xi*uD+7edQO6; zSX2(l2tE#huMJGZ0qTs3d1|$&od;0|5vh%0?)INsb-Iox&T<; zMDlO`_1g_>VXOS_&;QD=*M9wW|8K6peuwgZs=u?p1`Yt){x{|PgKWUN`|JPB_1Av< z*Y%6bQo*r_{(o~sv?tigUKRW^#2&nNumLtO{rW$xKQ%i99vtoXn`h=n!0Vffe_szz zcEFW2+5gk}|GEE`b}HcWt7Gus@E@?dw-I=K3k1&2kNF?ge;w!6&hp=Uc)Sf>T%H7* z+bI6M@9k&)w@h4Oz<;;CtEc|ocK&lVw^sZw`fTT{33hPN`ETl*LCS?idVo!>-P_}foJAMz^#8OA@k+%cij6&TVQ(^ZLn{ECAa|c9l%h>zkUDLJpQZw zS2^z=Zi0cooc_wVx-Ji*2Pxoz;dXFZR`}ntj;=c3-_c&+y!=>jR!$^jybAxWACuq@ zo?RIETW(=#;;*jw{j>(BXGegC$GX5Kknz0A?e+fa`@*6Gh-?l2UB9le5S$0;-|PJ% zNV^N539zA=G}y)CJ9u?{9_;OF`nUhDZ5Kf5zK;D>Mz8gi)CB&E`T75rjm)LN)(&c5 z%l~9wuXd}fF1GS&gUbI4`L+COyRWwYf67Pw-}L{h^e_B(a5OWpFtXQkuyL|CF#6wn z4CsG||7@%r9FX__;6Eoj8#5~e|JhkN*#9s7|DQGDaTqPHUxdR>AB9_6uH}I1C&8qQPcH+fhdNw0o>DXA{v9=-wua!^KU0XbtC)GuhE<|l?RZ6SY(;s)0Kw>CI z!-{rL?)!d;IFF%P$6&~{5U2Td)lW>^`K&HnmpHWIsf@42KG=iend8bhaK@7YS~Nz+ z*s`5HbT2A zxRtlwruDKq`OpTl5a}ZUZTWPMi6sOHI!wsl2Bvc|B5ErdCw7qE)>H<9ZS^SnUU!3pV^FmLF@)J%Z^m zp(u;1(c?&+8r-Md+_xnf()B(Nu5$WZU9mE?NH1kq79=7LReuZFX9^^o7SQQYEX%=R z`q4SUv`$ykxJ|d#zH)}$X$3G)#+1?~I`%MjzilO6H>S_)XtiVrM3z<=|5`K&^P>W8 z**nDC6G;K_mrW;Uh^wZP1UfUMNi&^0h);kL&IDw%aFGxl{o=Lo@3ZI!P`z^1uksH`#;4LVuxLZEFkJj`EWc$(dLC@jJLWJZ~ ze+M8J7^AGnHH}VdG>%Aq-xKfSda^;FHd|KO?&Tk_DHt|CF7R+5galGA0g1yEvinaT zgMcm-#BYqG{KDK5E3gb5CL@u=dA2%ezmXlAe+l%q&(^ZW*P19kzU$x$Zy;IL(2Js&XhO&XFPmk_Y0|u>R*nZ z-AuEF?!%t|LfKigBYGtm@kIA1gpIB{3HhZ1_K{EK@HeV>-w>TDa|YxCGAgwYj#1YX zBNCS6!m~S|O%N~MYs^XRUGQ?m1jyHV@}__FYwP&G&V_)%Ld2Yi0(o0Bzi#E8 zd?-++4qH~+iGWf(=b-V%`sd!>cvv>HUzzauqh}%$FaA_zX;3hk=hFI9Pvl4XpXpg~ z7j1dk*4SyrB%QK=wlIFmmbFDxnWsz4A1DWtTLt0IY0(y~t=KoCtD5KsR9~Wko!QSy zR?3z|R>V)x-?LePl?Ur2<}UaJdHUlQYg#ACfBNuD(@N1;A{W&vs$NtM$5^^_AS8SH zZwM5O-@|fe_-)TkbaE@zc}p}TzBq3A1c;nI(ekj+u6AR3Vc2#jl)Eu?1UaWDI_~1{ z_2wxn=cYt>2J)rhPoL|4#74Om^m5liEn2J zaPjd7K$kMqZkE(#$;=|}8yh5?mC)ie{~S4D{!W;epO+-$>S^g{=vtwG4zv&)GbFEx zCImHqSo--PJ{p-^|%tySRS5G8_~qBrBN&+(+WNW%ARp z=3z78HPf?xQaKzwj;yP^s03Nxvpr-)NPoin+Ate-7zj?ZdS{un(whEpnkAzSU#LT#?sU8S zTB$#_8Ob0%0%}bf^7_L?Jn9!tNVW4O6JMYSJ5(6cnQ)K=e$i}whhM-!(f)o08a zH65v~snTS+FkHzIshz#~ZuqPHUGBFZ{m{tYI=*4_|LV&oNeqMw)$Q#vtxHSP z_Zai`{|<6#@~}9TZ}xK2W3e0yCW66)e%dQM@k{hwp_*0uytSg)u6!K-7UZC>p$E67 zt{+Sp_uu{1_UVEX^Z7Y`WV^N*Y#y?`PMvkbgk@8%+t}E4(~YttIK3+A8KaKNT?W2q zO8052b+W#`h&^%ssQs(mNebwb@-pl~AcCQ8HOocjWA6(i)=>1u zSt4)s?@Kkk_JvA;gG=}}o6VP<@CP}@OYppq#|H5x5$m%31rL;Fqw^+AEp_)&n-6CX z1Ii&7+Y)@A$ZdCj6z1@*yiE7x#Xo?X`D0nAN+sE7YO7~>$g(C_#ZFioJOA7ZcALe$ zE!+iLU-wt=ZiBaQif9D0=|aS0Tln$W4(Y>4D5Z8Q18+M&FtMz&>Tm^%>Vh<~WFHry8wYC4X^eKlm z6AH?p#>zrj3BsMdG@=PO>!|W=nwO)tOPjNIzw6>Kvog!=!2KpTQ!mbOW@s@ShwF>aPdEqfv_?nQt3C2RIaIiuKNMZ=jux<k z+KZ!|0pi+=Uz(IVLAy~&4z6Vq!|QIH$p%Nt^EAzprmQx;Bl%zFuXqKWy?fgvO%@Yd z=tM5&B7RS$LE9!et+a&R^lLQLzVy2Q#8*mQ=*Qi}pOKgs0sbfNvk@r8JpSzB{+{n^ z7lbX{rBwA{tknG0fJS8Qf||xxdv|tDBfxWghDj_Ce1VzNviV*K@1qf>6oW{iC`~H5 z`|6@D(c81{e4XJAkMI3ExKHQbbVW$LWy;V2!+AY^=reGKr<=?$J@k#q3s4N}B@p7C z#gkg`G5AJ1g*GfF^%*_Gmg&r8;hxwQl~>Ry&Bgl@bgP=uAj#Q%-)MwIN6dCXtfa+a zJed`7o&HG0NPuY6{g2-%s9F))xmpH^rbd<0TZRTlv*>&J`k7M(p-Wdugvgbn+C>Zl zWkiM`m@AU^`SFf%2=Yl9KelMbOEr)pE8d6Ap(-neHdr%%oV6w6piEIOw1z4$S}uY= zsDrJE$R;PwV45pRWSc8CnX^!~5gU6^*1ux6>_`@K3=!&q$u~&V6N`7hE8y)j83)xL z3C`=0Jx9>Cq*coa{_KTn6iP;$x5nBAPllX)ZOOssB*Vk-W?s?Gom>*(plAL{Wo7|t ze9q`bRpF=+iYi>^#|fz}slp5h3|wzYoS~+0ifkD# zW8M1xuJsOn9AACEf&RRvkL|i(4Cq2q-3>cWjY~t)k%mfsYJxt2Rbx-p92Uv0B(An1 z+%i^FUeH8vE8!s7jP*$Qgp%4*LF8<|n1oN)qr{5dTfjBVf%tBP<`lhHb(RJCKTdX3?aQ) z{fwHZqUU8ad3d75`eC1qzl3IM`WsLUviV}EcfruNx&*MnD&Uq>} zu~kDUDzuc`>0oHJRI}C3fhIQFQ}^L~JxqU&n3j`Fjuxm&rm*FZb#E%9Dq`v?(ZzW@2rDWt zwj0Ad6&LM!m_ycg+24LL0Q3;U-Y5m-s@1KCy(Pf5WFXCzo=qxDJRkQfl9KPE?Jt)Z zB#dNVibTXNviLqjS+)qnJBv4OhjgSKbk5_o*NnabRUcG@&e$=17|(3heyW(_zwM}_ zq}D*OT>2+nTC;;BXOH%3ZnU|qKQ*os{{eMaFeVLJNl=(wJNpsygeobfZ4- z)*J4WV6;%4dGL_qB_es+xd+dl%gWb=08EYYzRN^)0|XsESPIW6#|b+JO>LqQ9ssRu zmv?93fYwOgXWG}^6ZZrfl#VTIUHDvpNwY33PW+rFb9K1(){TsAv!UeeR>gHFqa|LE z4K&f!S98X8>~Z^9i2=sWedxjXyPA@+s!O63 zvAyi>ghw;>z@9>;AHl?L?Z%cKRo*`zm8i^QAG(PC1Z`-L)4I^>S&6?uGk#2ad@Msky+82+p?3P+?98; znRPmrB*Wq<8P7>;OnGiB#0>P`O1JMa)qHjpzA0v)mkfrKoMa@c3iZjs^Rmb}{*p@6Se7aoA>KWSttyMT1 zf|)eTcM9xS*nl|%r9(yC-9^YB+F`1dMZ*)+O5og(3v{b8UlNIIcjJ8I{Sq9}>S=7~ z7E7|tuqP?nLN{R%Rm>zrYrZCbTKq^!MZ#o{VbmnE*fdy(q0ccTvMbpnk)zqdyLkp z7Av0M^LdYR7oPm7Vu0lB6j!KO*<@(pZe?lH26X6f(zYk7)pJ8giqDq(4)+hHc!`p^ zg+n@^mPx+TCKmUg|1^eL^6;OMNzKF6w{iY|-utCbV>~g*Zt!hM_w>HE*SGcWDZ>pn z3jVA_-#@NitBux$VbPal3%hPkuWtEIDr8cx!G2(J~e;C*v-+G2S<{H-c zaLq0!fB~x%ez)%TjUyksIi{#opR+2seBPI{r?Ae5aiJd;;>#2i^JXiJ7(X@VTd%qs z?Ya&~pOh{tC*GJ0_OGUsq!YHa@|3lked}FjSqoS)Dg`?BF5C4w;0xM{^Xs_f9EBU8 z^jB{GGzjfF$Fw-N1OJxWzdf$(bH4n=ak=S^V?vJ{mmzsgE~iGkP$oIZfs`z+ z5-K3>(L3YWoip9bS^Ft{4)LD10c`PswK(T__U|suK@tCSJ}FKUE`-+=1zj zFYIHlUgY!Ty>T3=Ja%WS<&Qscw@$7!^;koF6f7sy?NGNA*fk4vSP9n2U2@u|(rG#? z{i!Wjt!~Oir}ShEp2B^sKP($|R;xQKwQ?`+lig~#AuiNNT(*5oFPm@IvB9mY57Du) zn$qg~)t}SZbv>y6PaOs;kFTfh7SSsY4M(Nf7pW|Q%}@%8L}}%I^3%WLtnw;Hn!J&p#o!lEUa9YXjB{UQ zlsNEw0bhIcoZn}9|V3kR^9vmF!vY0aV$}TCMsEMG0S3Ru$ak`EV3+% zEw&|#nVBtSW@fgSnVFff#Vw{*cR$}dGwz~R-RLt(fvh# zuZQ!CrJP!aF$#;O>62tiQ>hq)n6tAya}&S!Nx>iK zEn>B0@(fk(u4FlFa5n&4sdx2kg)Z!HWvS@RG1|Lfe7RHcq13141 zlL+QsSvj%(_est2jIJAIg%PN3Owv>Pi(57FG7cN)6N|H#isziA+!hoSbDsWQmpT1&G+%g)(B7)cHu_POZ6!l~X`Bwi)(XTQ?q98cX}- z-<@~#d5qvq&}X$*ugB0r!9nz$To=DHJLmKz!SYIXvewu;*O_{s;z+`!!=yu<|9oVm zMCE4H{D9{U_d?99-QD=zsr;|q5lB1d$A+@EPbbgUmrHXFHU>`PmN&m6GsY0sM|$jD zqPaB5ApH@amajuABzAIU^4(rMmkYOdFPHZEu)%k9r4cbg+y>)Hk9R2VuyhH0w7apM zuXkCp9!BPysYk2yLGf;vOg-Kg@_;{`$9`@#LI@O7!Z>~fg+hkAcSK$%xR;sNBtLi_ z@dc=#IS#l{-&h=ecTaV7Z0m}601ECzEdnI{_-AI6lF5oYZNQf zu5?PZ)^eKqYR>h$88mWW@|D?hcz0N~W)WadffB`?ux&S>C<|oMlsk#M?gu@@>zY!?e){NjDbq$UPplZlC@2UNfL|CfqR}R zAVr}Dn2C|BhVL9dH9@F!-h(&>N$IgAk1I78HKfNULPY;x7nnr=(6b zCNJB24IEa3{w^u50SHz{5fSi!Lv!I&+qHMY{bS0j!O`3IYPl-KtXrqN zZZG+%f@Q#gEa%0~e^7i5Vtf_M1jsi??sACn>h!-_CoBNNWWUABzOh_Xa&M?*`I)9h zrntS74G&;ieVH8Wf;HRGJ-#550usFre-Juc|0m};GOL8<)AQ@Z&f~%-(#snYYC19} z9Mf$P^VN;C>)?b;wq^GOQ!z&D*yD&_*mb+^F1o>K6#w5`O!i8hQ?6F6PmeKxOn65? z*zCU+^N&hA1rTq=4sXWfyP^3kpk@Etk#NYif4l1k-2*j?AncL28H}BKm&_?ysx>n{YQoEz--URcn6tm4<>0>W#@*&eN5qo z{XMYquXq{=C;X3si%w&J((22Tibsnv;3**6E!pi~%jiFx>?j{?#pLfGg=}kVU;blM z=Er+r=|8H0a8m!YMe8y?L6D-@XPt-Y_-Tqe|M=i}BSo^~VYbDti`i#alDKd8&f`^Q z)w7ErR7e1gx%bLTYvioz9I(D3$G%F3-kR@w#hlHuEHcI=OD{p$fxqSSdOy36tmHCd zvZ7FV+p*9j5=L92ymCL>{&_p>72j%up}2YJ^6N=7q-~MEf+b|@d1|JaE?~IoQD&fh z#juuvSZqY!tDvK;*|3m-IjFAdPFm~kE(jqvFyG3&2TtnAAyo16eaqBrer=oazk}&`rnOT_MM(^{NcK37Tvx zc~l8(7e8Bv^?YbumN|279)9|eW*c}1Xz@3>SUYEXrf^^O*)$$z`*U$kcJ&bPA@KRo z@EKBKNugZ_)!I6R^L-4xuVr`$n*R8sQ+#*LryJyCHqSKgyeqIwxz-fioHsw)r>^6SLKh;`rw(P9dI9c!4f{Y-zJdA<|{Len$5 z8Nqg+dmqBO^LZ6Y=H{azgGe{x3K2a#tp+E-Gvc<>kmtI-5&z)mivKdg5J$b5iftmU zN@2Qb)-uPRNwudNqcV`ZQ+H1h@HR0%%{KD&K*BS#@=8JLiYml8<>6tOSaLIK|2gWR z&#?nOPGwX&&JD*$<|xrgl@cmfI+CW~Gf-gPdLKr8%=Kck8kpja(u zrntSfy841THU}K~cah#m##7mHecQQ&>#t4;wVM21m)vw7?$3cZVm|ua(EHqK_gA3s z)yPk+p}|Tlt%J5+ufhV;JQttnQAui7;S6o1raG~TGw~@e6HD|*k;VD z)JAFM+=_7H>o8{;qXz;g>#KL)|VhD2(dqR>^`62So$_Pk@Py%P?Px`!Fxl zJ5kBj#HH+;w-cin$v<=@kXBvA&9}i8&i#}*Xw_tBd&{I4tLSf0IY_uEO!EoKkWZfb zA(~)4sd45ln(G$BxVvwuKKk6$z4Y6uU7;4_`xMifn6~$hDV`i@X5FPci{Ijq0WeX# z-F>{H_ZhbaIiDCdqMf3>5EzHRu!);fsi+OWpJ2#V_VA@O-jF;|1^yB+6%Z@QN#ndd z(Cza9C+>VRTr7eFZ=7BMy<@eawUfkQsCJg$T#lBY;g^5z`WrO;D9K{Y`@7x;gl;y} z5?iwKlewLVlDjF*coEWEH%!wso|{eQ>EEKgxJ31P@~~H!i+BJ%sUY_cd~eZR53g%3 zQ*Jc-fQpP`4)+3f(5Fi1t?<778GovS&lCB~tZ_zH2x-{i#lzINPC%0EZj^@>SC6Tl ziR{A^-jjuxvAZJV<&~kwV;h{c<`REib7%Wq$?V-Scw^j3OKWY&{YetAfziba3bmSj zr&jZ`(08UXtKR6b_`!x|`Q3bCmT?=lRc}ctOy;B*oga#uexrxEL5|0%f7a+P#BVAh3xZ1Wi$(DRh- zO7 z2b=K>n$}NlgC5PC=j#2MZhEg<_jbc933^9@YwJw9))B#WW^c8gmOEk?FI7N$3OCJ; z?N_UVWbxDud!Ig=nFqhsx^oQhy8Y8tz{q9_h2OzB8kqU=+>b@2+gZuGI3KMhteS^* z$8tdffA4MHwmLtXccYs3?Xrq@G2n6Q@+@1t=6l`3Wd9Y|-i$TZ`pss>9`cyxe#g7R zKQlOSj^U=)d9c4jPS|27??J+{uIX@->wk;-c*a1KZ@Z-9v%@#{6vaKxx4_BH9b2M_ zVy_iaaW)CDNV&s+X-Kkp_%RV$!S?Ta)QMa zh1dpjr*4HI%Y=QEkND~#%giNu<(wwR<)cCEf*-folj||Xx(L)xg)l7F&q)0utFAK2 z@tn?UGRH10IM?k$cX@QU+r;@Sjs1LN%F{HdEwkPvy)IVfWr@jf&)I4;>Jv-(7;+d!i(QNLf+q$_VNj>qP{LK1}2US5QDwU3xz*=tR?|88(8HtZJ0 zSToCC9BR)_#htG107XE$zdD9MOw1Hs&4P}VA#V4OxF^)XBYDpCM^Da%Qf!T% z^V@GeDABB-ly&UI3M$T1Y@ZmM*SxXxOqoM0B10qa*L4zKsH+p#F1Y|v*1U-<5}apR zgB{}i<*(iya>J~IxDmn>c#QN`ISc5JF8fP{xbQK(nDEh~;k`C#P0>`tfGC0Q8`?Xe zyM~4POMFOM=QyA{Dv>0RqPM`Fk_5{ne)E_h!9tJW(M41bD7l?CkWE zl~|FG0D;MI$AfLaF9=QDej$k=#D4%Mk!B5*9QD6Fk4U_^`X^^V%4x|MG3B~maAHz! z8W|CK2g2E*uavnxX5yvp8N(;_WJT9*G8Jr<|dIbL3DZ^tnbAQ z-oOi!+%EEVRwUaw$k)!!qr1%wX#JD|aGq-5>GENSlC}l2%@h+qv6E}*=Vy zeL+1x|0Od&^(&=v@>S^JV5INi@U*BPbFX9g6f}FYEmqLa0EYp1L}IW$_rlBFeFWLw zxYnq*eDo-Aw4y4W-eqChY`)(KAyPC8l5$M%ut;FQA-`{l>xQz03W2Jcz#31loB z_S{_Vq^*)uZa;Hd9F1*C1Z8wQ`Lm*Bny0bg!_|jloq5i%$ zB{ONPfJKS@uD}|nX2vPt9{EE1qYs{pE6DBE z4cE^fgwRBdNKztg*?-ahTKgCrvL~pz^5@-kn0j%$bsFsuf4Dq2WNNo%Eu^l*3U^@$ z4P2BUOYeEt_b~{V3eB|Ob5u5^D8``S{t*M8H;hILT){uG%OkeL8ldHGs zn%{_}7?_^hgR?5H6}&loDqr0gea8|5*X4FlgZ7es>b=?|H1sz!#p|Q&X_H&21@fUJ z0**d1&&qz5J6%swUH#R_n)RN++?Z-%v!^!0!fS^WNF4Mvj7hcvKco=L_8DiGD3F>3 z$Re!;!{XiYLxR`7p63XhkY4^=D(9jj4NNuuDA^Qo%jpyWM&s#C2#){8n@nOdNB4*O zq=MZpbvoqH^@JJ$f2jnaN@p&u@d@t380%br-+Oc^kwT4qPyPYqX*FZ-?+t5ZzcpMJ zMC4s?Iyjt}3EMd7WcJEoE50rSM}+e*XqbHGhI_}=W=}KipXbQdfP=^=6;El2k;IxC zZBzL}hewW0;aeNbP+n>yH^Vc#vn1cxV+|}vNzpHSxOB8-Y6&>8tS-BncGWTSTr)vi zRN-W%D1*T^g`8~G!U9k^_L2LML)Dx$VD?#1bY4RoTSxR zXg^oaqF|%)BX8xP?q0St%;_hdN1?&fgl!vbgPDY1<-#8CXy zXFFp4+Xl6zaHUjljt%G6k6h#POS|bQ1`IP86 z&dw}sUB+>P2uIy{Xku{pVh(}7w0fV0p33t236t&$O|IsgB}t9v35YBVzrotYw~dbn zw4nF>`Jy5?oC-%$INzB-(}CEYJ2Hgk!x@sqRqib=fY_hbi7-o}jFH9p&DMx?_7@d; zRuh4~_#?ueYiwv5-nSs87_+9Evo!nCkJ zwLVTsZbPg!B&-B0?68o@%2+2K#N2|hMJ;v8sK=df_tcOPcs~g3%<+59 zQHsT@ROjT)G_q_@V3UxZ7*UZIib5qA$4d)O>yWQ=V7zY%%PBk3R$(E3$B| zVbI?g3zdE=OB2`dy@O9xWdPD9Uv$bKynKNtG3;&nIv<>wL{rAg_UEx}^qUAOwA?bj zfPh}c`9%4*@@GUiMIx2x*d%J!7=?mBZ!Ruk4ApqeDntf^X@|&1cl9I`fvl7BamB#g z68N$nnOr3w$&Y6C2{@%ODCHhs$FcBv?hpcw$Gp`88JA#a2xa9w)sy7k3kj}sAjHRJ zH4&MqzB+0ie>Mu-on#f3WpN_Lwn!>Aj|-WL_|`mcAKaVw?fTpPK9?az&ODwGmE3%1 zJ)X+B_yd^uJplb3>E3R^W-#NAr2Rk@i#|Rldsb7D&(d4=eO@n4JRy-C!&mKi6&Y_C~iO5YnF03;z(ziv2FTm!w4Et z7RqRrmlTmQ3gi#rzQzrl5a^g`2rx2@hY}Kyc{ji~eMOmQv|p!1fRCrZBILP8m^n~?*5F`CO5@z5h1SO2_N5BZ>N5pc4fB9CMDUEmOz`L{uF;6N3j!dR6| z$GziD@yUZK#!w3p6X$z>(uS%ppEVr)bxWcn>i7@QQX6$q;dP6%s#xAn|ByXm#pFlB zJsoGk8T^s;95McZBO1C{G@a3#FLnN9F->CnS9sj+lSz#z&QuWn(9jpDz`<`bTa~|~ zPxc$aZ)pxEKM8*Md}Q3WH-#I}%0w?40;klE$@*K7(ek%^7~4EixnztUmrUE&s7z!= zEZe@^*oxTuLcaQFM1zD#Yu-lT=yw0Ogx>@m9y-+YNI{KbKL!eacPW#~@kAC%Qad>O z-FTyUPzKv;2;spU(#JB#qYX2A^P!l{)X^x>{i0rCJA5|A&!>5lJDm?lX2oxdW6PPK zs6>9o`dnf=NysxprYf`#!gw+`Y~w!PkoO}1it+VqNK=mh!?VcfBMPn9k&5$tHD<(z zr<{!vcl|HNf^)n>ybglC89DS4w4Lb*a{_Njn2mAV=)Cd^g9VvwU(IWp!b(;tN0jFW z%-9?SEdEX>F`9RyX=$u-a|6Y)@HSaZGamGsgV_bFv{*)eet$yKMb7&v>uew$&WNff zilsB$ZNLUI&v<#098#rT`OJF8hXbD>@9b>i>qs8M z(wMHGN$@~{*jyY;y5pm*EsK)~w`}fMv8%=+9Z`>iM4~-7J>4#}RRa5rQR3BMhZ}Vhvm$t+{tN4&zum!UfXKC& zy?*|0*9Uf9;`GpV@<4NJsOMWO;DXrmXzRbAbu#tsyk#7;6_*Fj# zme1gj&HDS*%y~6CbL1GT6;E7T2$B^3ME&g#RRIeN(qexRo~Z!3g7>4RKTSj$C*ZE~ z5^$c6(@`&HE#%`rGq6#O05B9%`Yby}F{BWty*BSy-(C4ny!XV9G$%Dxl4j`sEF(d7 zZ5ZaClxSQgr)T!pgBK;4RQ1(Wl3@9VPuq~)gKnGb1vdqP#qw9wMIxBrZGUu+aE`C= zr)GNYcJS-G_MjqBNw^=B6+fc56xmAX-v1S&Atta}uKA_?N|){W z-OqvaT}_M_7k=2B5tY`Xzi9gO@B?Y9hXY6Jb$Jjx><=B+!JSgSMo4WoalVqRY1y>5g%QL)b}r69G2%#w?` zIL1*7();yNEMhDB5ED(5f(+fn5vS*M02VQbp7+$qmv}iWN)A<0k+#4&rF=cgBM_*K zD(Nw5`QxpVFGxAS)Oqo&_hnbUj@GR(*Af>eTXrIVQZ_WIw$jkZ9LG{$*?0+31Igu8DTDn!+f%pAc#QTWsA2(#nVL$c+23c$=N8NszvtxIv z;lq^LgXU=s*pVb9v80a*kq5H070b`6zs(uRBfl@mOP;_r3j7h05s@Vz_@iQ<3w~u+ z7duyJIe;P4RD?!d<=6O8-e(yS(|3jhmSsQCS-8e%1*r0$Ihh&D*mc|Nsp*kpmtpWV zD)E1`SM1{d3MP`4Jwgv+_$`_^nDSK=TPKL?z)}p2B5pb$P=G#fOnK1q1|{%k8Uw34 zr?J5jqneC8aqbV|5Rd*O0@o7TNBrN4=`^^p51|1w7z5}%l7F2_Fqw$b)rx8~*U~?| zX!9Gdzmv{WMMLWzIieH#pD*;uk@KJ|QxWcL=`ly5FMPduc<&$EEwP2ruWTFnPy*jn z4F*`CQK*s@$>^ip(IiPfzl|&6TyjS3$EQ|MW7?zK&vExuw-Sr*Fn zMGcKNsbNbtnp+N87P}dM54TAioTnAXjX5M8IODvKB1mifP{yU1_Y4BLXhw?PveJIG zQTYByxiE;S_bTky?C0Ehwu;Mz`RS^I%Z2;tYP*}}$-08(PY*Q7+A-{;R3O@Jy^31* z?N1@nlt_&+4&IOCb@+pL^NKc`o&Joer}Ner)ZwaU=HI(JKAF9jjKP_6(>i%)s-u{C zfbZ&3yBvO}Shaie&0|WV?ilAc)%z|wJoY=9D3oz)%K$dy*YgOjFj`(F)=Gutl`L`zTG}6NXn^n<9YUc zN;WJKOdXUS5R{YmW*Wv@YAi`gYE>xUmWbOAW=zoRCMG;3!YL@=zQEcKW_Z7D-00*q zcZ8f$pr-S;fF7CNsc|s5X7=1rnnxdl%J+L<7~WocW}%FtIkO1+;LJOtxG_u1XaahB z>`&@p;_(s=8coPq3V;ZnjA(x>4!pU0TjV1yO%x7dm60<3$cWLm9HMPo7~$q&?6 zWm=ML7q<@Z8tj9G%5pdTn9Qx}7Q7q`Va^3FV#qh2Fm>P%z>XF|k_#5}#41t|sQ~SI z+xUsGS+<7p1kOk~s>)^BAw)G>_UcQTXrE8BVQL!j8WVfE{lbqZl7z@QN-4q#RvSyk zxi~zvq9OAPnWtN;3<%M3T9K@^^vF6f0d>l#845HAqe2_j0x>>DloMa*?6OT zEN8>|o4!<7zBcplVvGi)h|nsuipc1WlY-vzT)xtw*Johc%I_HGQt>3uF^?nLm?{j5 z$(ZXO$?-K<8Ryc;VQ4&P3U)SYx?bGDk1>^rn5kuolZSu9*rZew)zZcMC34$lv^Euu zOqtpe;FPkp9!7d=mwEU+Q(Sb`pDkB7#x**z3|mdx1*Q!rJo@yly9SWV>aWf|f6|*4 zQnXiDu~X)ug;lhIj$Vw1GC%i9gv@mwQc;ln;UnqXQ>4VK&KV`97|So`KB2>? zWzO^h3z_CA6~P0S!HOhXjTv~s#3qqiH093ERw$I_?bBC`o(_4l1?Zm|TwLSeE#lKo zNVlDdvE+WFYEXB`C&-j0Qp(oc;mBbqamcW&Q_5A}>Bz;YsMq2X;ytq|I@n9YAPi2Z zFJj%-qz>HJ1(ELbS%dYk05`I`m(7U8jv}wf-oR!uOipr-X9o!@(cfuHRPyIPVVQij z6Di1=$V#vdv}oMpb##~g@%%IgQHeJkiHh8l_C{)LKH#g0bYDxIF2jrCis?T8^sx$p zMv}P3`wIrP?_m&bj6~ie;8U+ldL8q2)iLoDc1Xb=%^6Edsw_p z)q(%jjSbvB`lbTCzFeXi*NJ?gQP4J)3O}PAc_is*T7VaXVrr3M*bh-bGx`e$I4-^4 zfkW+LPg^W7dI}b|Ui=pz060i+s0Z*GrsWcoy>{}g5>l=Np;+VtLj?v(h%nIUtk0C$ zj}65I8zCpgulhIzmykJsg$w|=PYtIBYJLNUB>GyN2!8!F9LB)?_|n42A$)MA)g!xP zC)%@bXqmTT>baKQ9v%r6g&^dCMR|nM&t4#Vi4&F1-F}`5;=l&Kh^>Ja$ZnW2@pbIl z#m0vyFc`PvC4nEwtQbZZp?(L@77I2;G>4{vY@w4^r1$n$?%j3_N{<{>_mKfzW97+a z{K}7I$!4K%k(B>EwIQF#7CJI+i?cqd`{V8uhYuVB?gFBKD~39#Y5l;+f|m|G)~^`r zG-jvEuQWT@WF8H#4H5vd2Zlj&T=aJ1DDott%Nx685qM1=CTROz=iu24ohB;UO1{)( zOuwED??w=+cnh7GgP`OA{@=zLiejO>-=Lfqr7ToVkIt5`58)(MfMC z@nM=j{>ie8w(;dVZ8|3M*xH|m(ctq%f(dDsNE2!X65|$M2|`@dY;xVhl9j`6VJ^q2 zHuA2Qlp6$j&|ZP29$_6M#wk__N4%5es^49IcVYgTEN9Z zY}++ZCQk`z2{RD#zh^eEesljCz-joE(A=E8fvK?h%|r^7Ha%l1{(|#GEnp`yIxef2 zjTJDd{q>eX=bg5LE($G(b|sdkkKcY9IX=@xaTDp&@+;kyl%H{!_&$ZhO1kSL8QS?D6gJdJ3oeS3aDs?pkg%I)y*0XlkZE$63Efp)Sn!^H|@5W0^J&Pg79$ zGZ0NY5uVO}0vg|VE;}s`B5d}BMy=OP>m_**Uq~?9Oh@va&6D(54O2O3*u;>i_sS_Y0 zu-x~mhO#WE^dSjrtG546>u7x|&5d`nSsBJs%%dYXuitFJPIe5gw;{ur-x zys0}V=7Ls5zX-mdkGQ zRmUg4CegPo@pj+bR@y0BXT26vd?nGL3?-23IxI`AG3#2Ngloju9ij6#Y>?$Zw(O@^zb(72C;z^W6gg)&EJ^x-2d^rc*DA;OV3MvGhlgd&z||QNK1?B|2AU7 z5Pik}gz+KJs?;Y_dd2FJ*LYPuYL*n5oJOyd7USa7Yczh5!4xU<#g@p<@ob4jICt;&ZkS3q>3oTMWBF;Vw_r7`HpOcr?>*|x&qB|6$bloYZp%<|Y`L8= z+T|zjqU8Ad*VT}aO!P-PqM3)~p_bX|GerIyI>jkc-mf8u@y>-V+R16(HK-1>exy{4 zV&6qHQ7XeODe^6fH^5zO-eM|XB~I@V9NEZZy71V1${2KW@P^4}MlTO@wcsu$aqNq& zj^2hZ1)*kPA&D9B0}Rixt$03OrjQGc{?Y>sM+Sgbc-G}b_u?QL z(SXiu2$I0ooh^EeFJ+0fUZFL~{5@4zA(LAudSEGLq-uGPxt=t09uYZWGKG}h?EuK# z#pd^NcspT%@pJtVEZzr@74<}#sPh?8csYAsr#i(*1{&rY@62-ETsa=5P;XMb?l^Sq zT58smw;pa@&Ah$+?0HbUPthp%{ng>CXx&5C;k!|^BgO=(HiQuL$N4$+0lSnd#4LsW z0VtZ!=khP-_G)DLPv<~Oaz$-0wq?F~+Zbdivvf5}xcjJDUlZLDO+PdcTZmcVbcFj&7c2j;R_B{?iG}iSA9n*y73(-g%X0;XtM3Vz5`sd1>8c z=}k>8-)X6rhP|xu5PKX3-0e{OM@mD|wVE0F<{A19v5nyhpQ(q81-i=S|JtpUrI%Iv zd9_X8<+f2y;7mW0o&n?Y)SC!PS`F}A>oO7?=jCEW1-EkH(6I50~pgdFn zx+=h?VYKp}?hjEm6}X__*-QS(uz47L_5MuRGDF-b@;PMZ5GQa`j`kC+P*G5@B&;^k zYyO03&^tRyLn*q6R01pZhF~xEYy9a~V+$GV zugf*y(T>L?L+-~Sr|$-LJ;GYqfw9MA;o@^D*&Np%QKI+Zk4n$_9K@jaq}Xq%H|YqF zWPwjR$J_cqwwyYrxtHM4uFeC$b7bHosENDhxJlklXlB9*D#3O;4QX|4W-;(I393EI zC`d$DA(cFPY7H?U?Nv0XJNf{@w|Pz5F})Kl-Px=y>pDC)(9)va#>afNiL4cd>UsFO zhYn>DV@|B_qqlt;+`G5iB%#ubtgIkdo>mTI=m}l!{Ba-@ecxZ&#I4-Mc&GHzf2hbe zamD;W&m>jcL#QjSfHmqcC*?1fkScL$%VyOH@8;w?oKl2%CC}xKaOjPp*YO z;Fvb`eCwBG-IGZ_Ft_x(Jlh?I<&e#~R^!pvw({`bQh7Nrn8k^Dql#@?{U2f%B}e}~ zcA?5G=2odT!EIQ*xOzSAwUoTqiZSyhF0r3$4&{96PvZVsJH9P2B5EMvc3C;&>;Dxp zN&~@vTuQ%Wnig+Bm73`ARyW=Z<()Q(*!Ir`CSSa<#dg^_!~)&^;R{I2PJaE1LvT8y zhIIE#&XP6#Lt5+z$d(GnZ2v}voHSu6n`}mpn+2p@{!^$4faiD0JoblV3ZLuGoS#dL{Rrqz-wepczV0Hvc}=@ zUm)WEjm+`#pB&iB^aN1}qOZ93#OL49lg zRQqe37jEtAlbT11@ySy_{y&Vy-vPM~%*S*fIQ6R*ucQ$AgVyz&9}VnmuuZKF-Q{19 zzu^xM@nN&>GKiESBSqZa@&TTG&vpUpfr!TtI*MTV7iaW~orW?Pw2w#Ok$<%mczw+! z_iV2(ziRssKVR{7<;;dzFTPT0VP-8ge)xc>~*J0m$l`@!#f=Q1px z$64t!_pt>0;90QewAsYaUdaXF^(^2b+7MQD<`ozJe$7PG9`Y#s(V4=n^_R5Y1{&FG z#=qA89n`kKbCZ);LhtqTs-qL-E(7n;852L+6B#z!4q)}G(}-F}Nv9UzZ7trp$PR=a)r-Ii-oHuEVq&OkNtQx11{k9i^eSKayE zR)T0DL{Y)voKX7MVx(Q_p#5&vki+cR}?@^Dar+-in?byz8 zzdcZ9g%1xs)X=3A^LdS8z9(l9Q)oaU7UFOA)O0eFEk8lJf+WzsEoJoh(0B;T6DAx-5g8He!uPTKJn_`7X_At$zlAxMk}JR>%?2vo&pxW!?b11pbhg;%-uUd} zi|G|+wo|WZh>7}zg+Ojwn84iAAa`M{WAEnC7?3b>b^cOF4&$@f;qLWtap><`a6{6O z&hc2z+Te9M;4M#YQdFaM929)irP)RyDC}CT3XGT&1Bx7*y|@k9C*8fJH~qens`3_H z7b|bn?{Zt;K7R30@-cYy*;I(1X=iPiO3roo)z!x9^ItF!9+DGzCkUvf5vcs2L83b} z6k(Ik>Hx#^-hnJ%*xbePN7(~TgUsPW~R!$V!l6u{ZcG()|( zCV1dc=BmNUKQMh$+LLL}HZ${5pT*X~%f0dI+Dwm$wpH9T>NN^rLvR-q=oM&m*U^+X zrR+^|0!e0kRo1wYPIC6*7Bv!`mmD z{=p^~ZqRmzLy}ni_WGhRKPHS&oO4Th0~E$M68$nxZ`4pQBuU_IJyTTYo&56Yr)|`u=ptUyI^bP84(nwEC202!g}9b=j+Bsf8$8 zhh`IQZw^v~nbBli=iS+aY7Ro}(RF@|^I8wWcqAKZSch8pY=ph|6VU)Z6k$8{MFEoV z%uL4adeGUvgBSU0VRQFLy?{zy(7R!ljmNi8lk7#78YVyOYM=Wj+wF7X=3_jiZ){c3 zY!~gnk5&s>)jBA|&TUqAO&2Miy>`Yx$$HWJ2Va7wK9T$bVC)=OiUZ$6my~_nL~oeZ zUlLYwS7|USh0biWXJbFlKM4?ri-M+{_6*Z+2-u!u8jNZ^9-uDn%jbvuoVElXuXa}S zpr%{v#gw&9!`w|gz@uR(xo%fzB#rL*MiOtRWzSfDjNkdI?iY}9x}6udISnsLiH z?&$K@HKRmjSK$M{B{k5a!>E~0D5$kz{bAXVr1q_CGX%f6MU>>FbQ*RCYSwt|!V9Op z(}KP-DUeX#DaH3nZ8PrYDR9;_`dHM8>11mrf?b5#tN+S{Wl=D`Qb)luJ zn7gPz+wj(D)9Sr%SeAaFY3V;1=1mmb@aOdz+D4BQh^8LZQFMP6$eE6cjq1+P%Mh z&oA8G+L>^70HMmA2W}Y0ULJq2IVPNW+%Z@q@$;9>5AD9_%*w^+_V#*k!33Cd`svwn zAntr3&pF*k$=Tl@+dIxF<*A}?@@O(si91O~Oaf#K zt*jw>0a9Q4d;{15$=?*c-s{!bq2Bp#Fzt%HAm-&>_ynmu9nrK;Ep!j{ID3Ab%`p^u z#K-A<{hfQb_&9e8Yc;-ydledlOPnrCd$p@5uj7?k zu}rJGkAY_LtrPnDbaywcy@`L9+gYo)e3Z9)!Q+H;Nuz-A)_Gg_{j`9N(1C!!fq=-t z{r(5UAgqSUB9>nXCZ@j3wAGBl_!0c7tI>_6jD@J)4I_9lKCo2d2Kj#o;V#xVx%-E< zbGAk&DmiVIjx-`J1tgPBpU7cY1{#HatLy|iB`2}YJS;+qQ2`L9okfbGoiLQfR$xD0yrr!iuc6nD z!=1Tm6RK26K%B#1T+Pshk~g$sc@rS_s*8HWd?^z2+R-kF_%l z67fn#?7%V;|0A+uVC_GbtmtoGfQza8uVe+|KV-#&_x~JOF+%$P2eP7;ATInYLz*RV zGWX#mMP?h{{9D3wPd<=qs=Zv5sZ+;Rl|HhDr)@H_UcOaq2B9D}2%@z}(fl(}Th*x2 zp^eX8nfg*8(KbJEGwDPj7(~5US3QoWlZ_WVYf_0bm+V15m)fiW!<8%_-=>*g+W6&5 z{+p?inZ+9Gt^WdTbbqqhNxmM2W3lc*G$9IsJk6y)>%H zXZ1f5@OEhFA4vFuc1%fzGisE+5OUuqD&WMohM=q|U9ZZk@=2f6;L)?GdKsfJCLeO0 zl*XqW9r>7O!5ZSLX}^Pq<4$h76Yjtv&Jq$i@xYamJ*`}JUzZl#%73O)es4+R!+{o} z7UFQ)B0v3pqeR-3?zfpol@iK2?U$U?fiek-4^+igY6?FS=j!d5v+|;Yzc@j=ElVza z8al1egs4hL%QcB&KDF*C5*Z^$RCU&3>BClCZw10G^^VOaJt>-&?B`N1Szvb=#`M82 zF^`W-GCgw7!YC4a{b(Z;Uv7^Qp7SLB|>KU`7HJ1pHpba zqlf*`0&s!jO_K^ld1x|$WrE-8z4@A}11;t#n;0dJ-r)rq%ui?ScFZEI(Qb4gcBUmH zXrTS#`W^{`{%rr)-FBuxSLl;-)XH{I{jXq0NKV_{y=Q3!z1IQaX9KZ z7J00h1tBreMBnS)T4x^yE^r!Kr8n5eM7rTGUd5*N3QVlm3)@B|W`eMm! z47`N8cFu7!?3jrboZgYnFD%G9L0$8~T^|St*5Xa6nMEw+ejT`h1kt(n=uBtj%0VWF{8$kK(o7nQc^qCxA;45 z0+MknMwM$Yi36P3&}d)~zV zd|zgfAHg`I^jnz0@dvw zF{q-1{v=v1kmrWy`BK`NH{imX;+!-RAisS1eFM``vvobX+sia(w5t4DS(+$UketCy zZh$8!I4Xj9PWo9IzTf|7w!%@N7mnw;Fp3Xb4BMi09T`hcA-gkCz5b2>|BxHo+8cI7 zNS@GEH70Mlv3DInEp@~CR$3twp_7I;moJVj_Td8>>rZK3G1Z7a0?gs>Z^uT>1>|IO z>WH)O1V-4_4^&j>ckK&mSvXL9GjQ@C1U`HZ2z^<7@(Ni(^hL*lOj7EzlZ5aY40kFh z1?q57dZbjRf15C!9GdswNsBoy8)eC#PH3l-grfvVTX3$_hJO;;nW7Mb6jj`kF1cI3Dh(nwn{2i?uhswtOvK= zqo{q_+2f<~SPnT&_Hd@KhhYIx1lq+J366QYzX_C2q%aC~&9gQ3@`@NK48A*GPraKI zq+?y^w@AdplJ=F*o1G<;F5KxYwhs_8G4AVB0q4A2(V`SYeXq!-eAbgGh$LVm1_jpF zz?)PuYiWH$L`*mcq|eV|Rr5Gv4(~*zVc*Z`opfW6$4cfXN~Ua0U8nVkG`JJYnjiYu zIL=fg$M_mNK#I+S^AE2ogeko$9mBR{h*k@rj>*RqrB??)+3&p7BRxy4jm`L|2a3{6x zQH}>Q1CNj!9R){9)D7s!R}eWvKOP&$je7L)Lvk!aD8DlNen}eX2Mit*@jqDX`DNJj zRLye6MTmlqV|YhGoVL_?60Hb+VijWZvFoFJ#P0I!^-Hr?JZJAdDd6Z_99x8^k)qAh z2cgH}Jc>C`&auWIh7S(C81r%;2H^E;oPI-#%M_`Q<|3-RUZc$t9f{#djtf_Bi93kZ z_#JaiQ>@59{YU-qQ?om}UlsMP6j6FRr{Szf?BWe4eNbJ*NA#cmuE&Lp=Ern7QU0WU zRV9=rK`JTgj*h>D9AZ-Xe&`D(;>Alj$)Z~(^?vvica)H^$Vzu0Wr)yK`#wYZ3jrnm zdt&TM9(-ppYQ!K(ss)7AU0gDJNej$AfFOMwl$VXO>RRT7XmVo`RHm!OuWK8O_hK8^TFKOq6AioQ&`ZM`|m z0IN2@B$dUcC-DAuba(l9PBI1l3pyq;b6SbKjHyfr7IlOZ&fyB05);e)L!fc+^Z@}U z3Xb(5Rc~CoHvy4&D2Tcsh!y45>d)x!&;^R`c|3HO^z0+bwSDjeC6vZ{tXA*gu%d~n z802dE@(c2q%LUQwuXRRI>a8kEl8qfDNYK@IDovwl=FPiXC5eZ;kO{L=HSL=m^ipz3 zq-c0ZS@u4&vdeF@=2*m)j?BKBLIq?3q*w4(29KUCJTqY8uT2#`A6!$2%zm2YS)^6M zjkG-$%5Phy&M*oh6_>}%Z5rJx`a7MTqmU_$jp`|7FjL8~8y%L#0O{Yc-6HDaB*OY| z-g8=0`G=6rd0^8Ou-ZRJn129y7L#&Gw1;87vD!bD-BK#z$Wq49@Z_+v(?7iAPzUii za0e#=w7y-M+nI>@{UKwS|5B`x4NpEX_(F5{LQ^Q6wcNkvk-<0VtST*Qd3=Y2uNbaJ zQdhPihhNkm}we3NO9_i3dNRlhr5iJt3eei^VCij zi1wm+{0?@Un5%_ydtDX%t&iW<}O(pSeITus&}eiWAdpTvYX-#)R2nhTvTLK5I2cR0o1$b<176~_6K;c zzYWxG7%Pz72X>j}Wh&l96zzhB!8iSY=&bieQGAg+1{K(7O}+F_L*JIlrn7K=!LJ++ zbE^j{ll-vC*j~0JAMI_eC<@kK_g<$IRR5aNN*Q4uWa+T)7{!5v?jKMV$T`m1l$OHy zSIkKy*Is4<{h44w{($qohxCWii}@EUqQZRExI>ggq0&S%``zQAuHF7p3>;NZUt}&8MZQ>kr{SVz zgJ+8mo7XO}adp@D ziY00V_2P~dWYxm$z#$^%gep`X+ka-CC@89h0|rF|%o^iQzn6R`$Cq<6D;6DRQq8bU zXC(R@;gN}PS4c5Xj8nj@rrD?mbH8ZR_)3nZjh0BbE8 z!3S8itpSuf@%e4i*IzYYvidI-6W!ZL;SnUUl4GgSoJ`q@D_TCuMAA_)h6QS}D~F*3 zez0VA+&}a$kC?#H3$l~(=F>*XvCg=O`X&?4lo~{gZ?Y9s~CJqfbiAoKPAxt;L04d#n zsxXn*%~$Q?{BDq;igX|4LsRhhnT}Oh+Fxgq-|?x8C+9a2VsU4NWnj5~B_2F#VxHt2 zvk9_J#vi#^v*fvAK~bK{XmSK@0+yApGVpT+<@lA!+a3>zUUq|Xf*ee-UGPIg5?5r5 zj-3!XM%?n>UMS;Hq^Y+~Mj=PO&jH%?UV`IS(eK?}9Pyyp`ci_bG;Lmj3LB|~av(>% zy`Bce=n~VD?KK3|`r6vvCe(*i7YqIF)_v4;#f%wF!51&trMkjm48j-2M}vm0rd}Pwl_6Ytr>B_PP&hVyVe-G&$V8E6^)ZY!D2iRVXj~ z`EvC>n+aY}L3&3&A2rQ_O+Q9!b*W2-VVa{Za75~eS8FIk5i5l8KIK~)+QgHh9Fa%H z#TTRV6e~v=Em{km8gb2tgv}31Af35|pJz=1Dw$OI=90d(D3NO)H?R)#fJwUNz^Cmm zXil|bLd(DE;ALuIBhpC;s=wvbekW2|pz2B<@7kvNA!F$J5q=87>KN7dO?{*b6&bat zjHldGk(TXx;(!H#O6EoN1pHpZH~v@;2NxYcNq19Bq^7=*p{lyi96k*r89`Ver}JW| zS7a;~7BT%tDvU6P(L8o;dP*jh=6l3f3&}9T49c|0IUKF_Pqlv7bIyXlpMRoItNuQ> zjUiymFTZZZ5=RY_q^~UJ)k*7>K~|xHNWUA>SfaLP&Ssf6=X>|5^PBWS2UXGpB_%V} zjwt&;dj;-$_k%K7kP5al4M zs5v^`{Y3F8yi#epximVHL5|s2y9_&nRLdl@;xH?9aFtFX9?6%sw#MdIo<|f(ny(r% znrxwVD8N+)czsH9UhONn8XK)xABEY@M>k>EPTs$6XeYX0}3`%oB#9=WubLMC~ z%5&?6J%PvY09Nju=EaYX<&re-SGdY6PB-Qk1t^hpZsQpDZt-lGoG$KymIae} zMlCf-*o~GyH;Ho*?^cAZgpQBBdZt7hbh_5M|S} z6_w;?l`c)aZ@Vq5Lw(q=cvu{2DpIo@1{fnf=#Jh<4G&I|StAqyEgQt*BtBdA8mQeW*sq7=(X`@r=oDg8iMwixRtx_`xVJN>&s!zb@&Ywn(U^ zjL_uzopRXedy3=F_z5Pa<+xPO&= z=Qr+*quMCXVv#mj2fX zjKGgr7gIaexG+JzD&v(uD-kW>?aZzFH4^Df8=$rm13^ydW0TXSzp{y0iNy+($?T)a zAGq~pN;r|9)KQA(V&7TbY8D-AaySi&PO>EkV?4q zpd5oxgvDG?OitzYP^|sZPa+2CbRnW51jBZ6!xE{wO&J&%c#pq#qW(HP4uSC#82VrR zcawh(_pHl|aGUdwSP1%Z#PU>3w9!RzcnP0X!^HWXjYX{G*6MyeXCR?D$L-fmNKrTK zuoNe$Dlq+X03?(UqRudlC8z7sB`#C+FboM3GVYgnRO`&@#T;-B%S zyRPQ!?7*x5n1vcdWW4x$0TkByt_<-G95oXwH0rUS3{a$AtN~mpqMp zq4AN-r0ksE&w7-7%h4p8;O|V0H+b?9OSG8JX|HDkkUpP4axIRb7s5U{UlgAITztQz zA5kCw_QVZV-=?X(-zg(AgVtOtP*5ztSYuFbxoE<$$+b5nWE3DNjJ@i-BQx=-XJrUsgO%RRY zvdC@LV?TG>bdC+}lYyWada9Qo{U5gm`pylZiS+Yum)Hl><&4*M)!-+g<*qL*Hd-V1 zAL6tO3du_cJ?Wn0Q@gH;xpE7yQmyR@Au~E8&8FhrRy>bdotqhEb-n^H0X;T^&R5_XbalFm0M{HnQ0>vzV}UV zVSBh?@(Jn*n-FQ%c;@UdBWgYb3jux(+wU6z8hO34pShnHW0QmYtZt}m7;MIK)<&U) zT)B7bqrSS!Og^$Z)9psFbKhk)ztjR&z-yqs4Ez3+v*e$PL2X4Ke!%S#<`!KNqTTmB|J5P?J?Se6WB;cg@xq4`p{X&J{3ZJIFfho! z|04(q=KUuHp)IdCO=D6d`zKu-dVH#o4~SOIGQ1HrMUD(5AJmAsPYjsj!#<7L=w)yY zXX||mj^JzKR{cp-sG6yMZeeA$=Gw9hJb%evGc(kG%DT$|WbFWBXD+(!F1^@yo;Gs< zFAuyX#Xe&$hdT42dP+64T5%Jj#Z~;LGM)+K7u3tyE_B(WFGX+`%IiYw4X#!Ag5f;W zNby}2m6hjb&aa^JG4=Z2taRduhGQIW+tkfzhKl_0TLbiQ9i#4!3~fQ1)8Zou8>2*A z8PP^GYsg$tXjDOCY=`u&+#d!J@1P_S?eW}W@wO0`XLh`6Kv(ZtEj`O9v#NAT{LZSX zFWVL?U*hBsVEyT#&4})y5?^#zpMhCzyw>VO*3jLB3}C0^h9`$kYApEhIqroY032HT*@!a=bEMZ8nVkrt2{Msss2w;b=HOjMUsGzDf+qGMX+4tU3guJffTZ zo}?JTx$qOCJ^DpbzMtC%OpamJ(76mi_(f`Q`K#NF?AFfsg7efEGe!Qg`;+kur%v!B z#STSQr1!6j$DDh|;=X41pRc-O*2XOx1lWhMPP2l;S35y7J9D@6U02DxE34-bDcFa8 z=j^vyzJ0DlM~}5HrKpaty{iY!#~he7useXw3@gY!rQfC>arsMR(MC`ILwgQ%;-Rf> zCaZrNy70Deit5O3QTPJT*Zu^d(tUP2JX(PGW!~Y=$T7S7a@J;!n#!u4b1#3=QC;F>jb5E; ze!x>!EgiBES*! zM^Z7h{ABo6n4h-7Ff7>XkY85^@-J$b)`Af2AUp(hb2Wb+7d{jX(P3(cBJ25B?P})p zql#eBLK2-Zi)DGn9dh-|@k|<}_M6lHBf%FGJ3@cX0KU@At18T>mAj}qV|`Ma`W|q{ z3!q|u2JKf@49qgktAsLVb2rIZ;}UKPR8vh&xU7G%hAPRmLx=FYfgaqR5X^|*CaM7K z!3)cj;nFn46TCe~S^P0age|ll;pKpw>I$8I@l9s#%>=au8h9Z72-WU^s5SX0k#jds zcl-wRRPaRwL;wQZ>7zh?+C5N~v6w4VgmZKkO#8PHu(&l;Dasa_@I!Q8@VYR=kKV?p zI7Vr@=Rok|S-EkQdlvNk#jttu7dNSUv@4~+)qx;?4H%JV;~3!*26OW7{c?+X$LK=o z%3c!i2Ufo!85B-!!2526I`gmk1G4_e0%i+R&Zw2Q7*3AXyN=d#PI<^@3vPjG{cf6U5O z!1lOFN6=-b$G!j_p^}%iDgU?zo)+YJvVq4BIJ5+{BDJV}@lqav#ke@Kuo5GhrOY+a2QHdxP;GR?x;o}MQoMZc(W5yf^5$3Wi z5vnTk!`R11jF_o1<&alBqC)HZx`*~<;SbBjVv!(zBIt!%eOjqtXesZ^A~_smwPx`* zY+ZRx`{Pmb?79QqWZ@4XQ$3rDi;@F8sW&`Y*Y}Yk-zk1te-X6KrF(0Lx_kc!Ryi~r z%heuUKrKnWca$|zUQyC%c@wykc?`4Ytz>B@-DgLSUB!pq~iIm zc6@B7dLjL9{_W84boR}}-s)B}9ZCUuc+R!S=&}Br`gn7_$acx0yin_ZW86S(56{Gu zuh)}bLXK?lOXUgoj3{8`&1CkiFwq%g{Ld=qXs3rVp6B6nLMR3d46NFJtVcA$|C81u z%X=0Q%^bq1ielu$tveiO>R#;?aEJf`YTSPBTgA5BQqC7VAiL_E*FA{dJ%(>k7$0~q0Yd1<7A(PpRUzY zAkikjCH@{r^p#=rxtFHkdG3*Cwhw4{t*6~!0X*T<4K#$V06cux#aAw%J|-KUS1Z7c zX7KCe6QBp&Q~OH3@>KaGQM2R*%92^iC0nuj{~GoBg!n&w|IZTQ?_a7~Mb*p0{_Z*B z|6_Q6a{MO^@8+e_rUaJ%Pa%JdFG#a}bFinoWt6k9r~b}Ageb|NtUed@HQ>Cw~<$ix@n6xV~+Y4a;7qn(G~iQcX*)!PT^7k2KKL7P7i&2Ag|9n&H< zMNelv01f~Q(G(ljp;__C(|n@2tb`M^<9?Yghl&^FeDIom9`$yF?Efbh*t zj-N}0HBH*9-*=K`*PGoA$&XisUIPHWx=t5rlGT<+&$Z)br@V*#o;lZ5N}6C%<2#y9 zRvT7-Y&5~1#xros#IppAvge`8fNeANbB})R?qzkq@QyEFx0udlk$vsjT5e;_^|LTxR}LeXur`KDzkJvUNRbw@|9!@5ZJvX<`1$a1o#;IQzMVpS6aXT1wIGyZM) z&ee9(;?B9}2&e}=y2^z~M~_)^|@?6rqv#5QY0*Q(dP>+u3Ke|-Vhv=epq;apty@;I#c zEEgpFr^P1O;mtK}paH08EUb!YwL|D(cY=4`b3SbTmAy1-%y8HxHHOLto#?m>&Sm~} z$zI<>9U{v0r1;mq%y65AM=+A?j=YpETu767&|Tzm?W>Cns3l=1FSM@t6<|r>kvgFR zS0g;}+==xo%S?p7-lc!w#*Tjjm zo$2pSVj@-&w6za4@^<5!9CazLK!OU;M@K7(Uv^CKUS@6Cd!Axe;3HvW{i({}^XD6F^@MO)bHK@&(R}o&QMsEK_5E?wH^ir$f-k8?7Oc0dJ5K_ay&hgScU7>zvp* zW&|pp8B2xl@w?CtCPEOCDT`R?bG1>rQIk>l{!TLmq_}na&njdyY{&&_R|noIj=+xy zj>u)|&U3fh6aVlaE~?2F00lyTRZTOnP<3y$8`~j= zU??rj(+HzjS!=(ySe8xYK+4ZQO&E|Kn`S=@;^uXO{#d;t_YR*OI8Bv$eq zePe(cB`J*LTkIaYj}if5abs@*dj{4j^I-$Rps z*4Kcsk0Uwo2{*!DEP;3Df}4D3#BH{ZP)NyhRQ8h>i>qdoRus#d8(GI$hVhd!KB1rS zlNI%<2tfR0z`Frtmbs+`erq#MaQwJ%0qNMky(1Fyo4tT+L=ZBSWX{ySzBmnUxqvZM zvhoCWp0(Mf>O8sq#5D6BycKVBhT!mU@!dk87>~VT`$of#wvC}E?FL@V-#ya=cmJ9y}PMQ>gPB7VNnMkSA$_NJRIz~w9Y!IU`8xtdx2vci^2P%9Bz(F}kaO8a$3QZ3DL zhm7Vk0A#DFXXLf}@eWQ#mM={Si$+vlFDCZbR}DVX&`u9a*?aWu%LR8jaEpLk_#OQiuw`cFse>v-nSsqo_Iip*}V2#|RweSi8OG;+b&_-^Kkn8s7lIGQ{&GUXRH+N(o?(tZK!g{ z!fQqLkB2u0Cy~b>;on}KuJ%3oBZcR<#F%SRmZo+RaCUROGw-fhTwEzK{CH?yTV@{( zXxL}YO)r+7z1%-L5_>LvE#G}A3iL{+fF$iZI+)$rU_Vn}l>$5E9a;tSEdcLdo+y#1 zdSu)_9eh5=C>Jh9zGZ1#g2S6p$)dXwLCfB`^EjWp>Zx_l+?Q}LvuQd1NCW=*`hEtt zR9v+GQDTX72yt^k)~$ViX8*QsmJbt})j*i;L#DR3j`2h?S9i*ByeUQFTenZ;GcE3$ zDuU?~>brGhS{fAaQtFo~0zBB?x4sqel&c79(0%DLCj*2&_x{-8v$!F?(lLHXMuz2l-Ihy+`Ld4W-Fi1abQ>z#P!SwS8||j| z3?n1QK7qWwkvVC70v4kUnAw*rb?oet{f@tmqL#afN$JHpEp-O>(>!Q@Reh7wBO~0v z+#1=t>*QcDp!#Z7dfY9#th@=aI_?=oIWePWD1gXU4Yn;=V5;J${Sb@Nxe~?~$JVmK zJiSAjaxFX97w;)?57?J%w$-SW6nRo+`j?fNeLJ?K26zKI{)gBf#b287x40|ZA#MTut(923s z$l*&dGs3L;nEQF^+1x=#P|U>(BXRa_Daa|pJu)qm`}v~R6==pIz>>c7OAKV>u)bYL zJ4N2{H78ZnUrf6Diw)@%&rv(4kJkd;3|B|br+xEwn9C@qBXtK4lZuDMIx&hm^t#^U zeM`do636D^O~pw_QR*3wL))YTEhPNqIHEE?pGH~9U0=v&nU|{wmm7{#QE%%xM!PX0 zH}fux6m{zCMCfYF&*9d~85c}O|vIjJx=&~LpR9dDh}@Ozuh zXcrK<@Te;ARI#7ide*alPc^M;TGTG8C7mM+rS(noRoL&E2|^@OL$gO>V9|#g)i?Q86R={H<-^|a z&(9nA1u3N(RtL5!c?hmWoQATklnDqoUcCz~+12)Yuopl1GS>K+m%wN6Hg`FTJJhwT zJknC`ke>`L-jsisR1uNUi&5eA>*^O@hv_Q1$Lx~6`6KaG$nmlC6IlW%dF+l)`WZYa z^AX9vd*FijLT;GA+4pV-%7BHWXmy({Y1vb3?I=_bFh%C6tt zL2!9i*lOfvJ(~5hptXGXmW}|;VyYYN|b>FV!=)bqCby`9xczz z55*tJDSeMgCHPBcav;b?<(j-kXM!i^4fuvFKGN35zzx(F-Sj6qQ#v;pW$BHL?ekSx zue^9azm;di1|}YMBYyEaaz~$X{I{=q)&64rbFZ}D{ieP4Wv?XlDEEv-9~oTUU>#nm z#E$dC_Pux@{F$P4h$n84Ej-03Qz?+vJyl~;OT{%l9Orcp~8`J(M(JMyo6NSS% zZxfBTn)puS(x^CTG72~EG5iLCm)FvlS&#w(We|WAvy;vJ&{6bs1z29Jb zZtuVSc)Cx;2`U6`;yicMc^r$BYtPX*R`~2(`HVi9zZplOnw)I+(M-|Lt+bLbE@#2> z;$Kl8>gBT4xGLvF1B?A0e>EuHXA?bL=AUu{qqh^M=XW{g85%vlMNmMEdk2AsCCc+dZnh#49EN zYZTnw(N30GV_8UM>*Qe${GX>D@rn275Iy;fH>-UrMLF8p-Mr%g50+%&c+gI@u;NPWScb`Zzx@F;&R)%JI3;LG#5RY6&7d#`j*YwXBr^A@v zTK2$F20_s`-GxLF91=TwUuhhbUI&0DD$4$`%+Ip2psszI{b@H#J(|;-EYuTDP&zm- z(I6G3r7*y!dpsxEjouMR;3EC#gwbZeo%b|5BDWoREV;cfolSc$`E7#1RGRy+DrU}a z4h8X&-@y)6?8+zM@rx~gUxxj$+D;Z9qOb%FjV-+)AP4StWY#4R3+o^!ZD=LSY5Xn( z?gkicikVpKGi6)=7Hx#}i=9q@f36uJXz+P_K^@Ar8}wq@(U@hk_vJ1nH2NI+0r{-h zod3|~5T3JfT~pF0yfx)HX-(wH=Oj3N)7B{Ex0l_u!Le)^iJqkuMIp3X!ye?~(G0|?8UD)iN#etS>JUP4Px3n<9-7x2!$4Ej0~_$qevD#rEt zctS^uF{QDfh~6puE;_)#$F$d*LY5J7iXiPr57_O>l1=-&gx*B3`-oF*n77D zS1EMZBUXD4tS#aQXs2B_5T87LK%Lc|L%xCAMChy9Mkl)k0(XfT!G}A#t9EySV0cS} z`*=s?-KM_+fczX$I@M3a``Lb$3L_s6ck1t%N@Gba@=Z;4NwPs%;7C_|9M zU?4-@V?P>&$2xDov|l5<c>M-cC4>eaLi_vu<{94r(fiQ5&)gu)WT+QN zy!<+s^*z+%Zzuf!Ph6Hjxy?=fpCPH^vtVT;LP(;t@Ec}KV80)*?{3BmCPp=j^Bq)I zR+1YsL-@3P+wYfQo(g4Ca^F#X=3x9U2Xf#BY|Pz-At|sv58ugyo zyBOjoO8gb)QcEhfDG>3WUJ%9jX=M@q?*5>qP&alw% zd*Uol=Pu z@iwWi6fRJW&!CSb@t3&|;_Z+<&z_yOi`grY8xLb|zr6dmRDyGHvb8wrI=5j|Fy^w~ zb!Uu#EzQWYaTIUfKh}+y?2~_d7L`Cizqg}!3U}K5IeMcxD*=7P&Ve(;1xUEBES?J= z>pn1jUDq*m_!X$gqUa?11I)3b#@AcqHb7#Tb8;1^K-Ux^!u7TZ%GyTXj0 z#mK67)U`<5>(?|$=~mB&g#atbzYp$m6~u46>?F!43M~%yI=vTHc)Aeo_o2!{-Sg>d zKhnNYf+j-2e&>JX|8q0&W5JFxcQs7?U||9b%=_5?nBX4q|49=(+apTf1%E`pECQ8T zhDX)S247v;A>51BeA8Y_BEOY{prtH+kmvx%L23verTJY%-skY)FwSyad=;GtE8QXl zr1w(FEZOO*p*B zBHi4ojKc!84d;GUTXhZl0eJtu92hh;eT%&1JmR?w+s=88epL6k4T|r4hN2bvDtQ_& z<^tH}EACpDbdznSiw0(J$6HfFH#$XhZrmi z?%Fi#;3~dQb$#VMjn1}7>QQ!)FZH^*W`TBhTs|Z4uMm}c&{>{Bt0{BKpyAbNgRMdW2O_XtsPlbcGR|O zIw>D0EQKsabug{Et8jBuUNLzui3>PvV0LPxZ|>5c~8VJVCze>i6iR0ytajndD_CIR7)WnZ(e(J&!vqbEbfu3kzt2S6`ld^h%9e9Ik3KD!-mfs%N-bv*bQBnx}}g! zREoJHBQFfYZ(^0+sxL{7DYxmASsHr__~YEqS*zQmch`2zJNS23Z+h0*F%%t#ZHZ>3{oeGMLVM*&6;VXph?MTa6Uy@tjlMDgRP-%f^`tn6k;3YJx;*5sl2oiYm0FIzML7Ed*(u!*KRs*f8aw zKU&ACe7*4;_BL_~x*tjP4R;K=6|jT5iho^sZxVO|XZ-mXV`A`aKMK|J6!mNws(Q3F zzE|#NIMJ)JJ-z=>x?`emp$m84L;H}65B@+%dSG*D0=eMlm4I4;#RVRKEbgzlRh`N& zbuDmPHJHVaAXH;%qqndJVcnO%8%0DpFcRUh=979(nfJGs^#4*oaU52QLxLJ3$1?r# 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 z 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

    {v>0|f#JL>=F=w*lEjEVW7uB(xT7q}WTtDp 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

    UnTitJMC~(o5kxidMoonn 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

    1q3&<*+W4Lq;%e*FGizI>wP^V|#q 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%0A&(oZZWa&KJ-!}$28VP}MagnNaH?N@s!8xRW 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/css/artwork.css b/web2py/applications/examples/static/css/artwork.css new file mode 100644 index 0000000..e9cf37a --- /dev/null +++ b/web2py/applications/examples/static/css/artwork.css @@ -0,0 +1,141 @@ + +/*---------------------------------- ARTWORK E STICKERS -----------------------------------------*/ +/*logo*/ +.logosDow{ + border-width: 1px; + border-style: solid; + border-color:#CCC; + border-radius:3px; + background-color:#FFF; + -webkit-border-radius: 3px; + -moz-border-radius:3px; + margin:20px auto; + background: -moz-linear-gradient(top, #fbfbfb, #f1f1f1) repeat-X; + background: -webkit-gradient(linear, left top, left bottom, from(#fbfbfb), to(#f1f1f1)) repeat-X; + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#666, endColorstr=#FFFFFFFF)"; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#fbfbfb, endColorstr=#f1f1f1); + border-width: 1px; + border-style: solid; + border-color:#CCC; + border-radius:3px; + background-color:#FFF; + -webkit-border-radius: 3px; + -moz-border-radius:3px; + width:100%; + + padding:10px 10px 0 10px; + padding-bottom:0 + } +.WH1{ + height:190px; + } +.WH2{ + height:90px; + + } +.logosDow span{ + margin:8px 15px; + float:left; + width:700px; height:20px; + color:#555555; + font:bold 18px/30px Arial,Helvetica,sans-serif; + letter-spacing:-1px; +} +.box-A{ + margin:10px; + float:left; + border-width: 1px; + border-style: solid; + border-color:#CCC; + border-radius:3px; + background-color:#FFF; + -webkit-border-radius: 3px; + -moz-border-radius:3px; + width:250px; height:130px; +} +a.box-A span{ + display:none; + position:relative; + top:-55px; + left:-10px; + width:235px; + height:50px; + background-image:url(../img/tipDownloads2.png); + background-position:center; + background-repeat:no-repeat; +} +a.box-A:hover span{ + display:block; +} +.logoDow1{ + background-image:url(../img/logo3Tones.png); + background-repeat:no-repeat; + background-position:-10px -155px; +} +.logoDow2{ + background-image:url(../img/logo3Tones.png); + background-repeat:no-repeat; + background-position:-10px 0px; +} +.logoDow3{ + background-image:url(../img/logo3Tones.png); + background-repeat:no-repeat; + background-position:-10px -312px; +} +/*fim logo*/ +/*Stick*/ +.stikImage{ + float:left; + width:100px; + height:50px; + margin-left:15px; + background-repeat:no-repeat; + background-position:center; + + } +.stikimage1{ + background-image:url(../img/Stickers1.png); + background-position:center; +} +.stikimage2{ + background-image:url(../img/Stickers2.png); + background-position:center; +} +.stikimage3{ + background-image:url(../img/Stickers3.png); + background-position:center; +} +.stikimage4{ + background-image:url(../img/Stickers8.png); + background-position:center; +} +.stikimage5{ + background-image:url(../img/Stickers5.png); + background-position:center; +} +.stikimage6{ + background-image:url(../img/Stickers6.png); + background-position:center; +} +.stikimage7{ + background-image:url(../img/Stickers7.png); + background-position:center; +} +a.stikImage span{ + display:none; + position:relative; + top:-50px; + left:-50px; + width:180px; + height:50px; + background-image:url(../img/tipDownloads.png); + background-position:center; + background-repeat:no-repeat; +} +a.stikImage:hover span{ + display:block; +} +/*fim do Stick*/ + +/*------------------------------ FIM ARTWORK E STICKERS -----------------------------------------*/ + diff --git a/web2py/applications/examples/static/css/calendar.css b/web2py/applications/examples/static/css/calendar.css new file mode 100644 index 0000000..1d3cb3e --- /dev/null +++ b/web2py/applications/examples/static/css/calendar.css @@ -0,0 +1,11 @@ +.calendar {z-index:2000;position:relative;margin-top:140px;display:none;background-color:white;border:1px solid #000;color:#000;cursor:default;box-shadow:0 0 10px #666}.calendar * {text-align: center;font-size:10px!important} +.calendar table {border-collapse:collapse} +.calendar tbody tr:hover {background-color:#fbf6d9} +.calendar td, th {padding:5px; vertical-align:top; text-align:left; border:0} +.calendar thead tr {background-color:#f1f1f1} +.calendar tbody tr {border-bottom:2px solid #f1f1f1} +.calendar th {font-weight:string; padding:5px; vertical-align:bottom; text-align:left} +.calendar thead th {vertical-align:bottom} +.calendar tbody th {vertical-align:top} + +#CP_hourcont{z-index:2000;padding:0;position:absolute;border:1px dashed #666;background-color:#eee;display:none;}#CP_minutecont{z-index:2000;background-color:#ddd;padding:1px;position:absolute;width:45px;display:none;}.floatleft{float:left;}.CP_hour{z-index:2000;padding:1px;font-family:Arial,Helvetica,sans-serif;font-size:9px;white-space:nowrap;cursor:pointer;width:35px;}.CP_minute{z-index:2000;padding:1px;font-family:Arial,Helvetica,sans-serif;font-size:9px;white-space:nowrap;cursor:pointer;width:auto;}.CP_over{background-color:#fff;z-index:2000} diff --git a/web2py/applications/examples/static/css/examples.css b/web2py/applications/examples/static/css/examples.css new file mode 100644 index 0000000..cb5894a --- /dev/null +++ b/web2py/applications/examples/static/css/examples.css @@ -0,0 +1,69 @@ +/* Gray the black as suggested by Anthony */ +h1,h2,h3,h4,h5,h6 {color: rgb(35, 35, 35); text-transform:none} +.black { + color: rgb(35, 35, 35); + background-color: rgb(35, 35, 35); +} + +/* Spacing between thead and tbody */ +/* Ref: http://stackoverflow.com/questions/9258754/spacing-between-thead-and-tbody */ +tbody:before { + content: "-"; + display: block; + line-height: 1em; + color: transparent; +} + +/* Improve buttons in download page */ +th, td {padding: 0} + + +tbody tr:hover {background-color:transparent} +tbody tr {border-bottom: none} +p {text-align: left} +p, li { line-height: 1.6em} + +/* Improve CODE() display though padding has no effect as some PRE are hardcoded somewhere can't find it */ +/* padding of 10px should make it... */ +pre {background-color: rgb(35, 35, 35)!important; border-radius:5px; color:white; padding: 10px} + +/* Improve buttons in download page */ +a.btn.btn180 {padding:10px; font-size:1.2em; width:200px} + +.menu .web2py-menu-active a { + color: #26a69a; +} + +.spaced-vertical { + margin: 0 0.5em 0.5em 0; +} + +.btn:hover, +a.noeffect img:hover { + transition: scale .5s; + transform: scale(1.05); +} + +.btn, +a.noeffect img { + transition: all .2s ease-in-out; +} + +/* Lower saturation of color #26a69a - 20 points lower */ +/* The below change to color #26a69a should come before other color change or they override all buttons background-color */ +/* The color should maybe change at stupid.css level as it herited from there also in stupid.css it would be better + to define this color at one place actually color is defined all over the place */ +a {color:#47a69d} +.btn, button, [type=button], [type=submit] {background-color:#47a69d} +.progress .determinate {background-color:#47a69d} +.progress .indeterminate {background-color:#47a69d} +a:not(.btn):not(.noeffect):hover {color:#47a69d} +a:not(.btn):not(.noeffect):after {background-color:#47a69d} +.tags > span {background-color:#47a69d} +.tags.dismissible > span.off:hover {background-color:#47a69d} +.aquamarine{background-color:#47a69d} + +/* Lower the saturation of 20 points */ +.green {background-color: #58cc65} +.yellow {background-color: #ffe333} +.red {background-color: #cc4229} diff --git a/web2py/applications/examples/static/css/stupid.css b/web2py/applications/examples/static/css/stupid.css new file mode 100644 index 0000000..3e68bed --- /dev/null +++ b/web2py/applications/examples/static/css/stupid.css @@ -0,0 +1,375 @@ +/************ + Created by Massimo Di Pierro + Stupid.css is what the names says, take it with a grain of salt + License: BSD +************/ + +/*** basic styles ***/ +html {box-sizing:border-box;} +*, *:after, *:before {border:0; margin:0; padding:0; box-sizing:inherit;} +html, body {max-width: 100vw; overflow-x: hidden} +body {font-family:"HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif} +p, li {margin-bottom:0.5em} +p {text-align:justify} +label, strong {font-weight:bold} +ul {list-style-type:none; padding-left:20px} +a {text-decoration:none; color:#26a69a; white-space:nowrap} +a:hover {cursor:pointer} +h1,h2,h3,h4,h5,h6{font-weight:bold} +h1{font-size:4em; margin:1.0em 0 0.25em 0} +h2{font-size:2.4em; margin:0.9em 0 0.25em 0} +h3{font-size:1.8em; margin:0.8em 0 0.25em 0} +h4{font-size:1.6em; margin:0.7em 0 0.25em 0} +h5{font-size:1.4em; margin:0.6em 0 0.25em 0} +h6{font-size:1.2em; margin:0.5em 0 0.25em 0} +table {border-collapse:collapse} +tbody tr:hover {background-color:#fbf6d9} +thead tr {background-color:#f1f1f1} +tbody tr {border-bottom:2px solid #f1f1f1} +td, th {padding: 5px; text-align: left; vertical-align:top} +thead th {vertical-align:bottom} +header, main, footer {display:block; with:100%} /* IE fix */ + +@media all and (max-width:599px) { + h1{font-size:2em} + h2{font-size:1.8em} + h3{font-size:1.6em} + h4{font-size:1.4em} + h5{font-size:1.2em} + h6{font-size:1.0em} +} + +/*** buttons ***/ +.btn, button, [type=button], [type=submit] {padding:0.5em 1em; margin:0 0.5em 0.5em 0; display:inline-block; background-color:#26a69a; color:white} +.btn:hover, button:hover, [type=button]:hover, [type=submit]:hover {box-shadow:0 0 10px #666; text-decoration:none; cursor:pointer} +.btn.small, table .btn {padding:0.25em 0.5em; font-size:0.8em} +.btn.large {padding:1em 2em; font-size:1.2em} +.oval {border-radius:50%} + +/*** helpers ***/ +.rounded {-moz-border-radius:5px; border-radius:5px} +.padded {padding:10px 20px} +.center {text-align:center; margin-left:auto; margin-right:auto} +.center>div {text-align:left} +.right {right:0; text-align:right} +.middle div {vertical-align:middle} +.bottom div {vertical-align:bottom} +.xscroll {overflow-x:scroll !important} +.yscroll {overflow-y:scroll !important} +.nowrap {white-space:nowrap; overflow-x:hidden} +.fill {width:100%} +.lifted {box-shadow:5px 5px 10px #666} +.relative {position:relative} +.relative>div {position:absolute} +.spaced {margin-bottom:20px; margin-top:20px} +.hidden {display:none !important} + +/*** forms ***/ +input:not([type]), input:not([type=checkbox]):not([type=radio]):not([type=button]):not([type=submit]), [type=file]:before {outline:none; padding:0.5em 1em; margin:0.5px; border-bottom:1px solid #ddd; width:100%} +textarea {width:100%; border:1px solid #ddd; padding:4px 8px; outline:none; outline:none} +select {-webkit-appearance:none; outline:none; padding:0.5em 1em; border-radius:0; margin:0.5px; border-bottom:1px solid #ddd; width:100%;background-color:transparent} +input, textarea, select, button, .btn {font-size:12px} +input:not([type]):hover, input:not([type=checkbox]):not([type=radio]):not([type=button]):not([type=submit]):hover, select:hover, textarea:hover {background-color:#fbf6d9; transition:background-color 1s ease} +input:invalid, input.error, textarea:invalid, textarea.error {background: #ffdfdf} + +/*** grid ***/ +.container {margin-right:-20px} +.container>.quarter, .container>.half, .container>.third, .container>.twothirds, .container>.threequarters {display:inline-block; padding: 0 20px 0 0; vertical-align:top} +.container>.fill{display: inline-block; padding-right: 20px; margin-right:-10px} +.container img, .container video {max-width:100%} +.max900 {margin-left:auto; margin-right:auto} + +@media all and (min-width:800px) { + .max900 {max-width:900px} + .quarter {width:25%; margin-right:-5px} + .half {width:50%; margin-right:-10px} + .third {width:33.33%; margin-right:-6.66px} + .twothirds {width:66.66%; margin-right:-13.33px} + .threequarters {width:75%; margin-right:-15px} +} +@media all and (min-width:600px) and (max-width:799px) { + .quarter.compressible {width:25%; margin-right:-5px} + .half.compressible {width:50%; margin-right:-10px} + .threequarters.compressible {width:75%; margin-right:-15px} + .quarter:not(.compressible), .half:not(.compressible), .threequarters:not(.compressible) {width:100%; margin-right:-20px} + .third {width:33.33%; margin-right:-6.66px} + .twothirds {width:66.66%; margin-right:-13.33px} + label.quarter:not(.compressible).right, label.half:not(.compressible).right, label.threequarters:not(.compressible).right {float:left; text-align:left} +} +@media all and (max-width:599px) { + .quarter:not(.compressible), .half:not(.compressible), .third:not(.compressible), .twothirds:not(.compressible), .threequarters:not(.compressible) {width:100%;} + label.quarter:not(.compressible).right, label.half:not(.compressible).right, label.threequarters:not(.compressible).right, + label.third:not(.compressible).right, label.twothirds:not(.compressible).right {float:left; text-align:left} + .quarter.compressible {width:25%; margin-right:-5px} + .half.compressible {width:50%; margin-right:-10px} + .third.compressible {width:33.33%; margin-right:-6.66px} + .twothirds.compressible {width:66.66%; margin-right:-13.33px} + .threequarters.compressible {width:75%; margin-right:-15px} +} + +/*** progress bar from http://codepen.io/holdencreative/details/pvxGxy ***/ +.progress { + position:relative; + height:8px; + display:block; + background-color:#acece6; + background-clip:padding-box; + overflow:hidden; +} +.progress .determinate { + position:absolute; + background-color:inherit; + top:0; + bottom:0; + background-color:#26a69a; + transition:width .3s linear; +} +.progress .indeterminate { + background-color:#26a69a; +} +.progress .indeterminate:before { + content:''; + position:absolute; + background-color:inherit; + top:0; + left:0; + bottom:0; + will-change:left, right; + animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; +} +.progress .indeterminate:after { + content:''; + position:absolute; + background-color:inherit; + top:0; + left:0; + bottom:0; + will-change:left, right; + animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite; + animation-delay:1.15s; +} +@-webkit-keyframes indeterminate { + 0% {left:-35%; right:100%} + 60% {left:100%; right:-90%} + 100% {left:100%; right:-90%} +} +@-moz-keyframes indeterminate { + 0% {left:-35%; right:100%} + 60% {left:100%; right:-90%} + 100% {left:100%; right:-90%} +} +@keyframes indeterminate { + 0% {left:-35%; right:100%} + 60% {left:100%; right:-90%} + 100% {left:100%; right:-90%} +} +@-webkit-keyframes indeterminate-short { + 0% {left:-200%; right:100%} + 60% {left:107%; right:-8%} + 100% {left:107%; right:-8%} +} +@-moz-keyframes indeterminate-short { + 0% {left:-200%; right:100%} + 60% {left:107%; right:-8%} + 100% {left:107%; right:-8%} +} +@keyframes indeterminate-short { + 0% {left:-200%; right:100%} + 60% {left:107%; right:-8%} + 100% {left:107%; right:-8%} +} + +/**** dropdown menu from http://codepen.io/philhoyt/pen/ujHzd ***/ +.menu {list-style:none; position:relative; margin:0; padding:0} +.menu.right {float:right} +.menu a {padding:0 15px; text-decoration:none;text-align:left;font-family:"HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; text-align:left} +.menu li {position:relative; float:left; margin:0; padding:0} +.menu ul {background:white; border:1px solid #e1e1e1; visibility:hidden; opacity:0; position:absolute; top:110%; padding:0; z-index:1000; transition:all 0.2s ease-out; list-style-type:none; box-shadow:5px 5px 10px #666} +.menu ul a {padding:10px 15px; color:#333; font-weight:700; font-size:12px; line-height:16px; display: block} +.menu ul li {float:none} +.menu ul ul {top:0; left:80%; z-index:1100} +.menu li:hover > ul {visibility:visible; opacity:1} +.menu>li>ul>li:first-child:before{content:''; position:absolute; width:1px; height:1px; border:10px solid transparent; left:50px; top:-20px; margin-left:-10px; border-bottom-color:white} +.menu.dark ul {background:#111111; border:1px solid #111111} +.menu.dark ul a {color:white} +.menu.dark>li>ul>li:first-child:before{border-bottom-color:#111111} + +@media all and (max-width:599px) { + header .menu li, header .menu ul {width: 100%} + header .menu.right {float:left; text-align:left} + header .menu ul ul {top:2.5em; left:-1px} +} + +@media all and (min-width:600px) { + .ham {display:none!important} + .burger.accordion * {max-height:1000px; overflow:visible} +} + +/*** sliding sidebar ***/ +.sidebar { + position:fixed; + z-index:1000; + -webkit-transition:all 0.5s, -webkit-transform 0.5s; + transition:all 0.5s, transform 0.5s; + left:0; + top:0; + height:100vh; + box-shadow:0 0 10px #666; + width:220px; + padding:0 10px 0 10px; + margin-left:-210px; +} +.sidebar:hover {margin-left:0} +.sidebar.right {text-align: left; left: auto; right: 0; margin-right: -210px} +.sidebar.right:hover {margin-right:0} + +/*** pulsating ring from https://jsfiddle.net/mandynicole/7xrKP/ *******/ +.pulse:after { + content:""; + border:3px solid #00e6ac; + -webkit-border-radius:30px; + height:40px; + width:40px; + position:absolute; + margin-left:-20px; + margin-top:-20px; + -webkit-animation:pulsate 1s ease-out; + -webkit-animation-iteration-count:infinite; + opacity:0.0 +} +@-webkit-keyframes pulsate { + 0% {-webkit-transform:scale(0.1, 0.1); opacity:0.0} + 50% {opacity:1.0} + 100% {-webkit-transform:scale(1.2, 1.2); opacity:0.0} +} + +/**** underline effect ***/ +a:not(.btn):not(.noeffect) {position:relative} +a:not(.btn):not(.noeffect):hover {color:#26a69a} +a:not(.btn):not(.noeffect):hover:after {width:100%} +a:not(.btn):not(.noeffect):after { + display:block; + position:absolute; + left:0; + bottom:-1px; + width:0; + height:2px; + background-color:#26a69a; + content:""; + transition:width 0.2s; +} + +/**** modal ***/ +.modal { + position:fixed; + z-index:9999; + top:0; + bottom:0; + left:0; + right:0; + background-color:rgba(0,0,0,0.8); + padding-top:20vh; + transition:opacity 500ms; + visibility:hidden; + opacity:0; +} +.modal:target {visibility:visible; opacity:1} +.modal div {margin-left:auto; margin-right:auto} +.modal .close:not(.btn) {position:absolute; top:10px; right:10px; font-size:20px} +.modal .close {transition:all 200ms} + +/*** tooltips from http://codepen.io/trezy/pen/Khnzy ***/ +[data-tooltip] {position:relative} +[data-tooltip]:before, [data-tooltip]:after {display:none; position:absolute; top:0} +[data-tooltip]:hover:after,[data-tooltip]:hover:before {display:block} +[data-tooltip]:hover:before { + border-bottom:.6em solid #111111; + border-bottom:.6em solid #111111; + border-left:7px solid transparent; + border-right:7px solid transparent; + content:""; + left:0; + margin-top:12px; + z-index:2000; +} +[data-tooltip]:hover:after { + z-index:2000; + background-color:rgba(0,0,0,0.8); + border:4px solid rgba(0,0,0,0.8); + border-radius:7px; + color:white; + text-transform:none; + font-size: 12px; + content:attr(data-tooltip); + left:0; + top:2px; + margin-left:-20px; + margin-top:1.5em; + padding:5px 15px; + white-space:pre-wrap; + min-width:100px; +} + +/*** accordion ***/ +.accordion>label{cursor:pointer} +.accordion>input ~ label:before {content:"\25b2"; color:#ddd} +.accordion>input:checked ~ label:before {content:"\25bc"; color:#ddd} +.accordion>input {display:none} +.accordion>input:checked ~ *:not(label) { + max-height: 1000px !important; + overflow:hidden !important; + -webkit-transition: max-height .3s ease-in; + transition: max-height .3s ease-in; +} +.accordion>*:not(label) { + max-height: 0; + overflow: hidden; + margin: 0; + padding: 0; + -webkit-transition: max-height .3s ease-out; + transition: max-height .3s ease-out; +} + + +/*** cards from http://codepen.io/edeesims/pen/iGDzk ***/ +.card {perspective: 500px; max-width:100%} +.card>div { + position: absolute; + width: 100%; + height: 100%; + box-shadow: 0 0 15px rgba(0,0,0,0.1); + transition: transform 1s; + transform-style: preserve-3d; +} +.card:hover>div { + transform: rotateY( 180deg ) ; + transition: transform 0.5s; +} +.card>div>div { + position: absolute; + height: 100%; + width: 100%; + backface-visibility: hidden; +} +.card>div>div:nth-child(2) { + transform: rotateY( 180deg ); +} + +/**** tags ****/ +.tags > span { + padding: 4px 9px; + white-space: nowrap; + color: white; + background-color: #26a69a; + border-radius: 5px; + font-size:12px; + margin: 2px 5px 2px 0; + display: inline-block; +} +.tags.dismissible > span:hover {opacity: 0.5} +.tags.dismissible > span:not(.off):after {content:" ✕"} +.tags > span.off {background-color: #ccc} +.tags.dismissible > span.off:hover {background-color:#26a69a} + +/*** colors from http://clrs.cc/ ***/ +.navy{background-color:#001f3f;color:white}.blue{background-color:#0074d9;color:white}.aqua{background-color:#7fdbff;color:#111111}.teal{background-color:#39cccc;color:white}.olive{background-color:#3d9970;color:white}.green{background-color:#2ecc40;color:white}.aquamarine{background-color:#26a69a;color:white}.lime{background-color:#01ff70;color:#111111}.yellow{background-color:#ffdc00;color:#111111}.orange{background-color:#ff851b;color:white}.red{background-color:#cc1f00;color:white}.fuchsia{background-color:#f012be;color:white}.pink{background-color:#ee6e73;color:white}.purple{background-color:#b10dc9;color:white}.maroon{background-color:#85144b;color:white}.white{background-color:#fff;color:#111111;-webkit-box-shadow:inset 0px 0px 0px 1px #ddd;-moz-box-shadow:inset 0px 0px 0px 1px #ddd;box-shadow:inset 0px 0px 0px 1px #ddd}.gray{background-color:#aaa;color:white}.silver{background-color:#f1f1f1;color:#111111}.black{background-color:#111111;color:white}.glass{background:rgba(255,255,255,0.5);color:#111111} diff --git a/web2py/applications/examples/static/css/web2py.css b/web2py/applications/examples/static/css/web2py.css new file mode 100644 index 0000000..24f75d0 --- /dev/null +++ b/web2py/applications/examples/static/css/web2py.css @@ -0,0 +1,204 @@ +header a {color: white; font-size:1.1em} +main {min-height: 70vh} +.form-group {padding-bottom: 10px !important;} +.w2p_hidden {display:none;visibility:visible} +.right {float:right; text-align:right} +.left {float:left; text-align:left} +.center {width:100%; text-align:center; vertical-align:middle} +td.w2p_fw {padding-bottom:1px} +td.w2p_fl,td.w2p_fw,td.w2p_fc {vertical-align:top} +td.w2p_fl {text-align:left} +td.w2p_fl, td.w2p_fw {padding-right:7px} +td.w2p_fl,td.w2p_fc {padding-top:4px} +div.w2p_export_menu {white-space: wrap; margin:5px 0} +div.w2p_export_menu a, div.w2p_wiki_tags a, div.w2p_cloud a {margin-left:5px; padding:2px 5px; background-color:#f1f1f1; border-radius:5px; -moz-border-radius:5px; -webkit-border-radius:5px; font-size:0.7em; color: black} + +/* tr#submit_record__row {border-top:1px solid #E5E5E5} */ +#submit_record__row td {padding-top:.5em} + +/* Fix */ +#auth_user_remember__row label {display:inline} +#web2py_user_form td {vertical-align:top} + +/*********** web2py specific ***********/ +div.w2p_flash { + font-weight:bold; + display:none; + padding:20px 20px 20px 50px; + width:100%; + opacity:0.95; + vertical-align:middle; + cursor:pointer; + color:#000; + background-color:#ffdc00; + z-index:2000; +} + +div.w2p_flash:before{content:"×";float:right; margin-right:100px; color:black;} +.ie-lte7 div.flash #closeflash +{color:expression(this.parentNode.currentStyle['color']);float:none;position:absolute;right:4px;} + +div.w2p_flash:hover { opacity:0.80; } + +div.error_wrapper {display:block} +div.error { + color:red; + padding:5px; + display:inline-block; +} + +.topbar { + padding:10px 0; + width:100%; + color:#959595; + vertical-align:middle; + padding:auto; + background-image:-khtml-gradient(linear,left top,left bottom,from(#333333),to(#222222)); + background-image:-moz-linear-gradient(top,#333333,#222222); + background-image:-ms-linear-gradient(top,#333333,#222222); + background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#333333),color-stop(100%,#222222)); + background-image:-webkit-linear-gradient(top,#333333,#222222); + background-image:-o-linear-gradient(top,#333333,#222222); + background-image:linear-gradient(top,#333333,#222222); + filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333',endColorstr='#222222',GradientType=0); + -webkit-box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1); + -moz-box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1); + box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1); +} + +.topbar a { + color:#e1e1e1; +} + +#navbar {float:right; padding:5px; /* same as superfish */} + +.statusbar { + background-color:#F5F5F5; + margin-top:1em; + margin-bottom:1em; + padding:.5em 1em; + border:1px solid #ddd; + border-radius:5px; + -moz-border-radius:5px; + -webkit-border-radius:5px; +} + +.breadcrumbs {float:left} + +.copyright {float:left} +#poweredBy {float:right} + +/* #MEDIA QUERIES SECTION */ + +/* +*Grid +* +* The default style for SQLFORM.grid even using jquery-iu or another ui framework +* will look better with the declarations below +* if needed to remove base.css consider keeping these following lines in some css file. +*/ +/* .web2py_table {border:1px solid #ccc} */ +.web2py_paginator {} +.web2py_grid table {width:100%} +.web2py_grid td {color: black;} + +.web2py_console form { + width: 100%; + display: inline; + vertical-align: middle; + margin: 0 0 0 5px; +} + +.web2py_console form select { + margin:0; +} + +.web2py_search_actions { + float:left; + text-align:left; +} + +.web2py_grid .row_buttons { + min-height:25px; + vertical-align:middle; +} +.web2py_grid .row_buttons a { + margin:3px; +} + +.web2py_search_actions { + width:100%; +} + +.web2py_grid .row_buttons a, +.web2py_paginator ul li a, +.web2py_search_actions a, +.web2py_console input[type=submit], +.web2py_console input[type=button], +.web2py_console button { + line-height:20px; + margin-right:2px; display:inline-block; + padding:3px 5px 3px 5px; +} + +.web2py_counter { + margin-top:5px; + margin-right:2px; + width:35%; + float:right; + text-align:right; +} + +/*Fix firefox problem*/ +.web2py_table {clear:both; display:block} + +.web2py_paginator { + padding:5px; + text-align:right; + background-color:#f2f2f2; + +} +.web2py_paginator ul { + list-style-type:none; + margin:0px; + padding:0px; +} + +.web2py_paginator ul li { + display:inline; +} + +.web2py_paginator .current { + font-weight:bold; +} + +.web2py_breadcrumbs ul { + list-style:none; + margin-bottom:18px; +} + +li.w2p_grid_breadcrumb_elem { + display:inline-block; +} + +.web2py_console form { vertical-align: middle; } +.web2py_console input, .web2py_console select, +.web2py_console a { margin: 2px; } + + +#wiki_page_body { + width: 600px; + height: auto; + min-height: 400px; +} + +/* fix some IE problems */ + +.ie-lte7 .topbar .container {z-index:2} +.ie-lte8 div.w2p_flash{ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#222222', endColorstr='#000000', GradientType=0 ); } +.ie-lte8 div.w2p_flash:hover {filter:alpha(opacity=25);} +.ie9 #w2p_query_panel {padding-bottom:2px} + +.web2py_console .form-control {width: 20%; display: inline;} +.web2py_console #w2p_keywords {width: 50%;} +.web2py_search_actions a, .web2py_console input[type=submit], .web2py_console input[type=button], .web2py_console button { padding: 6px 12px; } diff --git a/web2py/applications/examples/static/favicon.ico b/web2py/applications/examples/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..5abc35d8fcfd77dde589161ba4b66ef216cba684 GIT binary patch literal 1150 zcmb7E?MqWp7(YROfS>x@$NmO`J_eC#I?E6ZQm1!wPTj1jTcf#Q%T`XNsi6i=Hm4v+ zA@rd#B1qi|m6`J;Th8TN7D`{`*LjZI+uoqOm)|}2Jm>j6ulKo(o#J<19^=omOghcj z8OGQ-4ld%7V>w?K<7b&y#m%DS!jk+W4x9v6it~@uQu%w;jSHx%yCmRpx1qkNRN2dN zlDXXNS#q*bn!=AKzQW;b%F?snZ^ZXRG)qqLX7VSehS4`@7wGm_&|tWZ&MpIX_r9T8 zx}0Vs7k_zW0rMZ<3WQffh;FZe*5uDPreApf$xn@6*L)2JzxOd8oJG4;jc9BgUVpD* zBbR^5GZxbB>CH~$4J60kgp%>X$6yHim zrykF|-3WeqhdQ1Q)s1RM?}3Q{Uf&vpKl3sGACHgDC%E6p`XXvH1u&U!VJo@{t4$K| zlkaiPr8-cJD1KGh-}#YylxtOM3!pcaL662fY{mlQtN%wyM DT3Try literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/Stickers1.png b/web2py/applications/examples/static/images/Stickers1.png new file mode 100644 index 0000000000000000000000000000000000000000..7d0c56d4b465612057a769bae57ef817bf8c3035 GIT binary patch literal 4131 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/Stickers2.png b/web2py/applications/examples/static/images/Stickers2.png new file mode 100644 index 0000000000000000000000000000000000000000..a767243799bdcb63b8803d2a1d39158b98d8ebfa GIT binary patch literal 4150 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 F{y!#q;Mo8G literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/Stickers4.png b/web2py/applications/examples/static/images/Stickers4.png new file mode 100644 index 0000000000000000000000000000000000000000..8e0ac586f971b35b77d9806c6ebe2f5df684b08b GIT binary patch literal 3358 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/Stickers6.png b/web2py/applications/examples/static/images/Stickers6.png new file mode 100644 index 0000000000000000000000000000000000000000..a7b3763f3d2acb9d5240124d51c82bf072fc2413 GIT binary patch literal 3300 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/Stickers8.png b/web2py/applications/examples/static/images/Stickers8.png new file mode 100644 index 0000000000000000000000000000000000000000..8e0ac586f971b35b77d9806c6ebe2f5df684b08b GIT binary patch literal 3358 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 O0000x6H4G8LTI6PuuU@^g8>6J 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/facebook.png b/web2py/applications/examples/static/images/facebook.png new file mode 100644 index 0000000000000000000000000000000000000000..be55deddc3fc615ccd1d49235976cecc8e8d0eab GIT binary patch literal 991 zcmV<510ei~P)q1ouJThj*#d6U`qd-LYKH#-Cc>DbrT<#4*f?uv>K$|&hnYB-yj z2|vHne?#g-er?@<_IfC=yn9E-IyBV#%gM)BB!v0=)kkv=X%JNeP_CY4S|8( zTi4@PVg{qpcv&3?)OoSE%7uqdhcNc-Yd571XLxn60k1#)z>kR}$}Q1Y5=(p@G=+kQ zjE{$@)8PtDCNqe}(^x2p{7Qg(-H>bwqF_9p0%KTEkxa>^M0{m64sbp%gKjrP=k`Xl zHP)a){4SOgm!Hhhvz$P(DPtVkJeR+$)`Q*yYvK1+qN;KcC{+z}wBiK{U9u?ypI7+Z zE)|D6o3Xsk4_|fFALo@~NVbRo1LO8R=xA@is^F5p!gW{)hGbJN!ocRS|C`nswIR3%jy1P-_^w_23N#AH22X6y@B01bo#lkpoV{_@n2aE!mW8y$Znd%D+l% zG7Tp+mRw{!Vfri~BwqzwB!?o7q>RmNa5^34C0FV>0hMe$0@4Aid2sRgCPNsD<@~XY zhOtvuUd_=JirENosNz(%ng{J|%|)feP3Pnj?&Ta^GV?jWWdw*`5>|vU&DK^G+n3CI z6^K7nVm$)PX4@>buND?fWrvcA#>(qJvHkp_3rVOd)+4a}=*_t`fAx@I&d%Ojrgn7Z zY$sHNqSQAHl6*4CPRQVOJ8UMQX84#%rHkrJovpCk@WfOc0pB9q zNm%?by&VabWJ2xab2qS`$bq3D5^Clj_eH@#;)BRDOoMjxkxOA55pr!{QN#Jbg#dM%ud*_=X96i zstjv{hGbq@&Bv1mTMc8E2HzVyACYfCq6PEZFq@eU58c0@U(bIFFaYf=<8eP8H#h(Q N002ovPDHLkV1lDZ(&+#I literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/favicon.ico b/web2py/applications/examples/static/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..d2296d5e893eeef0d9c23629b93fc15f0c07de6e GIT binary patch literal 198 zcmZQzU<5(|0VW0z*Z{<0K&%180zj+)#2|SPZ~&7K0-_qiW}p8IF5}98KWZe literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/favicon.png b/web2py/applications/examples/static/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..bd0a414ec86d9994b46676a8d399955a211da224 GIT binary patch literal 323 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b zK-vS0-A-oPfdtD69Mgd`SU*F|v9*VRoE%RV#}JFt$q5VCD$M5pwKtPGcI;St=SBge z2(6Fm%2v{mJ)H9yZQYu1}7PYx)% z@f?oav8UOWC*MSf`N75p?Scu5d6r8U#vMo%JQ^oa!N723Q>lXa!beMh_Ntb+MwFx^ zmZVxG7o`Fz1|tJQLtO(4T_cka14}DoLn{MwT?11q1A~nj7xtiN$jwj5OsmAL;ecrd QP(1^Kr>mdKI;Vst0O;yt8UO$Q literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/gplus-32.png b/web2py/applications/examples/static/images/gplus-32.png new file mode 100644 index 0000000000000000000000000000000000000000..c42eab784578bf4e827722400f125760ebab527a GIT binary patch literal 1513 zcmV~mL-d9E}6-eW&UBZZ2My_Cfm%i zR~F|3K~NBsXK5*=D3)i1wty(22(yB`TUx&RokMTe)+&h3CZC-4{C@YG-#z!-d&`WO zGS-!qz^GkB4wEK=|ACn(NH+1}^K$G@-wCy z0;G7yEEQ9(4no!1aNNo}0oZK9SWg%F&gWvdMeFGE#5OSwZT4>7=WNp!v>pB&nq6C< ze0`nBxsnntCUn;FS~TQt1(Z_(Qe0=pMhw?5W1SYR?%xf?>OeHnUTCEOc*}pQcWi=X z_`V}=;&v}o8LJ(6o;0ULd0YW0-e$*UEEaIq(NVfaeqzuTI#|+7zvZ+)8V`O1DVMud zkR$d@vpugu=KqlDG`9lW;+2HW&?e$0dT)r0#3yvukQ|26SYM17+9Bmn4-cU{F$7mA z#&Z;Ilg;85BjW5K2>{ar;8Phz&JpAg9TdRG24xRXBc2dwLg0 zaS1Dt1>wf2zhE`pb1~J|3zMc6!_8Vp-#xVw@)UZ+(o)U`-%swOSe3nHmDE`jxdIB> zV8&mL!c?ckkhWg5(}Vr6-Ww1mdpc2>5`#)Qi)W$2-ZD{Hj2}v(R*6CiBUa#i#B!8n zB*97#CrMvn9_@`)v>*JQiBfyZ`0g$vrA~Mu)$eY`^uQg5v5q!eppAGbdX-D=(_$BC zKzF==qBUWdyxxWB{@V_NiVBpZ#)`Yd({XbtacU*3ByuIV3w-Irm!lwT8P0|-Ltf}o zXg>J>)AZ_fHp*|oots5&F&+1`SRoCRPm|?_EJaaLB-H!&K>O8aF#h@@ZqdJ@$?HZ~ z`fj?Iy3vKYkM|*;iY=nT7oyPKvUBw0YdmxirrK&)dV3s3ni?=DFBSNA=a{4}doS{+ zaK0LaPw2cI8*gug^kR3*sZ}FL+C1UXT$O&4E zv$9~ARC1WR90=>T`dVjeH1J4JnS9Y<8;0P&*v_?+xtd)gw|EW3ec P00000NkvXXu0mjf1Z(LN literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/infoworld2012.jpeg b/web2py/applications/examples/static/images/infoworld2012.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..bda145b706c35cc7d35d8cd477897e3266a6fbcd GIT binary patch literal 25202 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­U=hVS|7YfDWa@!DNmC?W8{8JgOETBU%La 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/logo_db.png b/web2py/applications/examples/static/images/logo_db.png new file mode 100644 index 0000000000000000000000000000000000000000..5db3ca24938f33c9eb925b9acf256722637812a0 GIT binary patch literal 237373 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

b2>g9 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

M<3LV`g5WvF_ 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

-&DP?%Vs1qN1WK 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⋙~{s+pFgYDa8pQ>gA7x#Kk3JB6>gP#-mtv-7By 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�N4qZ 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ÿ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 DQ(;4F literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/menu.png b/web2py/applications/examples/static/images/menu.png new file mode 100644 index 0000000000000000000000000000000000000000..9b39321153a3bdcfd6e186fb8586afa8d3a93eb2 GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^tU#>7!2~4F{Y_T{QkkAEjv*SNsS_>=HW=_YJ&yf; z{|sY^DD%fZ+UNfTa!inUUVHW1wI1_`)l793cGI$*@;@}qm;T&bnen5Z5mG2%z z&$R#2KL0@U%$}(of#bivGKuk}T3=BR)CXG1 N;OXk;vd$@?2>^>3L#qG) literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/poweredby.png b/web2py/applications/examples/static/images/poweredby.png new file mode 100644 index 0000000000000000000000000000000000000000..a767243799bdcb63b8803d2a1d39158b98d8ebfa GIT binary patch literal 4150 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/shadow-bottom.png b/web2py/applications/examples/static/images/shadow-bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..4b5bbe584ffae60fee14703f2fdc96a277fe18ce GIT binary patch literal 9677 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 P00000NkvXXu0mjfnM$2F literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/stripes.png b/web2py/applications/examples/static/images/stripes.png new file mode 100644 index 0000000000000000000000000000000000000000..7f87c03769eb4aad70032d4f28090376fedeece6 GIT binary patch literal 79322 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

Z9pY2H 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/tag-cloud-color-small.png b/web2py/applications/examples/static/images/tag-cloud-color-small.png new file mode 100644 index 0000000000000000000000000000000000000000..18ff781adbe0d0f8bca7e26da53062935556ad0f GIT binary patch literal 59563 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 BQy>5U literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/images/twitter.png b/web2py/applications/examples/static/images/twitter.png new file mode 100644 index 0000000000000000000000000000000000000000..d94419a4b1011554746d666a133235679dec04a3 GIT binary patch literal 1120 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/js/analytics.min.js b/web2py/applications/examples/static/js/analytics.min.js new file mode 100644 index 0000000..c6af396 --- /dev/null +++ b/web2py/applications/examples/static/js/analytics.min.js @@ -0,0 +1,4 @@ +// Analytics.js 0.2.2 +// (c) 2012 Segment.io Inc. +// Analytics.js may be freely distributed under the MIT license. +(function(){var e={userId:null,date:new Date,loaded:!1,initialized:!1,initializableProviders:{},providers:[],addProvider:function(e,t){this.initializableProviders[e]=t},initialize:function(e){this.providers=[],this.userId=null;for(var t in e){var n=this.initializableProviders[t],r=e[t];if(!n)throw new Error('Could not find a provider named "'+t+'"');n.initialize(r),this.providers.push(n)}this.initialized=!0;var i=this.utils.getUrlParameter(window.location.search,"ajs_uid");i&&this.identify(i);var s=this.utils.getUrlParameter(window.location.search,"ajs_event");s&&this.track(s)},identify:function(e,t){if(!this.initialized)return;this.utils.isObject(e)&&(t=e,e=null),e!==null?this.userId=e:e=this.userId;for(var n=0,r;r=this.providers[n];n++){if(!r.identify)continue;r.identify(e,this.utils.clone(t))}},track:function(e,t){if(!this.initialized)return;for(var n=0,r;r=this.providers[n];n++){if(!r.track)continue;r.track(e,this.utils.clone(t))}},pageview:function(){if(!this.initialized)return;for(var e=0,t;t=this.providers[e];e++){if(!t.pageview)continue;t.pageview()}},utils:{getSeconds:function(e){return Math.floor(new Date(e)/1e3)},clone:function(e){if(!e)return;var t={};for(var n in e)t[n]=e[n];return t},extend:function(e){var t=Array.prototype.slice.call(arguments,1);for(var n=0,r;r=t[n];n++)for(var i in r)e[i]=r[i];return e},alias:function(e,t){for(var n in t){var r=t[n];e[n]!==undefined&&(e[r]=e[n],delete e[n])}},isObject:function(e){return e===Object(e)},isString:function(e){return Object.prototype.toString.call(e)==="[object String]"},isFunction:function(e){return Object.prototype.toString.call(e)==="[object Function]"},isNumber:function(e){return Object.prototype.toString.call(e)==="[object Number]"},isEmail:function(e){return/.+\@.+\..+/.test(e)},resolveSettings:function(e,t){if(!this.isString(e)&&!this.isObject(e))throw new Error("Could not resolve settings.");if(!t)throw new Error("You must provide an api key field name.");if(this.isString(e)){var n=e;e={},e[t]=n}return e},getUrlParameter:function(e,t){var n=e.replace("?","").split("&");for(var r=0;r<",s,' onload="var d=',y,";d.getElementsByTagName('head')[0].",a,"(d.",f,"('script')).",h,"='",r,"//",u.l,"'",'"',">"].join("")}var s="body",o=n[s];if(!o)return setTimeout(p,100);u.P(1);var a="appendChild",f="createElement",h="src",v=n[f]("div"),m=v[a](n[f](i)),g=n[f]("iframe"),y="document",b="domain",w;v.style.display="none",o.insertBefore(v,o.firstChild).id=i,g.frameBorder="0",g.id=i+"-loader",/MSIE[ ]+6/.test(navigator.userAgent)&&(g.src="javascript:false"),g.allowTransparency="true",m[a](g);try{g.contentWindow[y].open()}catch(E){e[b]=n[b],w="javascript:var d="+y+".open();d.domain='"+n.domain+"';",g[h]=w+"void(0);"}try{var S=g.contentWindow[y];S.write(t()),S.close()}catch(x){g[h]=w+'d.write("'+t().replace(/"/g,String.fromCharCode(92)+'"')+'");d.close();'}u.P(2)};p()};o()}({loader:"static.olark.com/jsclient/loader0.js",name:"olark",methods:["configure","extend","declare","identify"]}),window.olark.identify(this.settings.siteId)},identify:function(e,t){var n=e;t&&t.email&&(n=t.email),t&&t.name&&(n=t.name),t&&t.name&&t.email&&(n+=" ("+t.email+")");if(!n)return;window.olark("api.chat.updateVisitorNickname",{snippet:n})},track:function(e,t){if(!this.settings.track)return;window.olark("api.chat.sendNotificationToOperator",{body:'visitor triggered "'+e+'"'})},pageview:function(){if(!this.settings.pageview)return;window.olark("api.chat.sendNotificationToOperator",{body:"looking at "+window.location.href})}}); \ No newline at end of file diff --git a/web2py/applications/examples/static/js/calendar.js b/web2py/applications/examples/static/js/calendar.js new file mode 100644 index 0000000..4bdb8c7 --- /dev/null +++ b/web2py/applications/examples/static/js/calendar.js @@ -0,0 +1,29 @@ +/* Copyright Notice for Dynarch Date Time Picker */ +/* Copyright Mihai Bazon, 2002-2005 | www.bazon.net/mishoo + * ----------------------------------------------------------- + * + * The DHTML Calendar, version 1.0 "It is happening again" + * + * Details and latest version at: + * www.dynarch.com/projects/calendar + * + * This script is developed by Dynarch.com. Visit us at www.dynarch.com. + * + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html + */ + +// Calendar EN language +// Author: Mihai Bazon, +// Encoding: any +// Distributed under the same terms as the calendar itself. +/* End Copyright Notice for Dynarch Date Time Picker */ + +Calendar=function(J,K,H,G){this.activeDiv=null;this.currentDateEl=null;this.getDateStatus=null;this.getDateToolTip=null;this.getDateText=null;this.timeout=null;this.onSelected=H||null;this.onClose=G||null;this.dragging=false;this.hidden=false;this.minYear=1970;this.maxYear=2050;this.dateFormat=Calendar._TT.DEF_DATE_FORMAT;this.ttDateFormat=Calendar._TT.TT_DATE_FORMAT;this.isPopup=true;this.weekNumbers=true;this.firstDayOfWeek=typeof J=="number"?J:Calendar._FD;this.showsOtherMonths=false;this.dateStr=K;this.ar_days=null;this.showsTime=false;this.time24=true;this.yearStep=2;this.hiliteToday=true;this.multiple=null;this.table=null;this.element=null;this.tbody=null;this.firstdayname=null;this.monthsCombo=null;this.yearsCombo=null;this.hilitedMonth=null;this.activeMonth=null;this.hilitedYear=null;this.activeYear=null;this.dateClicked=false;if(typeof Calendar._SDN=="undefined"){if(typeof Calendar._SDN_len=="undefined"){Calendar._SDN_len=3}var L=new Array();for(var I=8;I>0;){L[--I]=Calendar._DN[I].substr(0,Calendar._SDN_len)}Calendar._SDN=L;if(typeof Calendar._SMN_len=="undefined"){Calendar._SMN_len=3}L=new Array();for(var I=12;I>0;){L[--I]=Calendar._MN[I].substr(0,Calendar._SMN_len)}Calendar._SMN=L}};Calendar._C=null;Calendar.is_ie=(/msie/i.test(navigator.userAgent)&&!/opera/i.test(navigator.userAgent));Calendar.is_ie5=(Calendar.is_ie&&/msie 5\.0/i.test(navigator.userAgent));Calendar.is_opera=/opera/i.test(navigator.userAgent);Calendar.is_khtml=/Konqueror|Safari|KHTML/i.test(navigator.userAgent);Calendar.getAbsolutePos=function(I){var G=0,J=0;var K=/^div$/i.test(I.tagName);if(K&&I.scrollLeft){G=I.scrollLeft}if(K&&I.scrollTop){J=I.scrollTop}var H={x:I.offsetLeft-G,y:I.offsetTop-J};if(I.offsetParent){var L=this.getAbsolutePos(I.offsetParent);H.x+=L.x;H.y+=L.y}return H};Calendar.isRelated=function(G,E){var F=E.relatedTarget;if(!F){var H=E.type;if(H=="mouseover"){F=E.fromElement}else{if(H=="mouseout"){F=E.toElement}}}while(F){if(F==G){return true}F=F.parentNode}return false};Calendar.removeClass=function(G,H){if(!(G&&G.className)){return }var F=G.className.split(" ");var J=new Array();for(var I=F.length;I>0;){if(F[--I]!=H){J[J.length]=F[I]}}G.className=J.join(" ")};Calendar.addClass=function(D,C){Calendar.removeClass(D,C);D.className+=" "+C};Calendar.getElement=function(C){var D=Calendar.is_ie?window.event.srcElement:C.currentTarget;while(D.nodeType!=1||/^div$/i.test(D.tagName)){D=D.parentNode}return D};Calendar.getTargetElement=function(C){var D=Calendar.is_ie?window.event.srcElement:C.target;while(D.nodeType!=1){D=D.parentNode}return D};Calendar.stopEvent=function(B){B||(B=window.event);if(Calendar.is_ie){B.cancelBubble=true;B.returnValue=false}else{B.preventDefault();B.stopPropagation()}return false};Calendar.addEvent=function(D,E,F){if(D.attachEvent){D.attachEvent("on"+E,F)}else{if(D.addEventListener){D.addEventListener(E,F,true)}else{D["on"+E]=F}}};Calendar.removeEvent=function(D,E,F){if(D.detachEvent){D.detachEvent("on"+E,F)}else{if(D.removeEventListener){D.removeEventListener(E,F,true)}else{D["on"+E]=null}}};Calendar.createElement=function(E,F){var D=null;if(document.createElementNS){D=document.createElementNS("http://www.w3.org/1999/xhtml",E)}else{D=document.createElement(E)}if(typeof F!="undefined"){F.appendChild(D)}return D};Calendar._add_evs=function(el){with(Calendar){addEvent(el,"mouseover",dayMouseOver);addEvent(el,"mousedown",dayMouseDown);addEvent(el,"mouseout",dayMouseOut);if(is_ie){addEvent(el,"dblclick",dayMouseDblClick);el.setAttribute("unselectable",true)}}};Calendar.findMonth=function(B){if(typeof B.month!="undefined"){return B}else{if(typeof B.parentNode.month!="undefined"){return B.parentNode}}return null};Calendar.findYear=function(B){if(typeof B.year!="undefined"){return B}else{if(typeof B.parentNode.year!="undefined"){return B.parentNode}}return null};Calendar.showMonthsCombo=function(){var I=Calendar._C;if(!I){return false}var I=I;var H=I.activeDiv;var J=I.monthsCombo;if(I.hilitedMonth){Calendar.removeClass(I.hilitedMonth,"hilite")}if(I.activeMonth){Calendar.removeClass(I.activeMonth,"active")}var K=I.monthsCombo.getElementsByTagName("div")[I.date.getMonth()];Calendar.addClass(K,"active");I.activeMonth=K;var L=J.style;L.display="block";if(H.navtype<0){L.left=H.offsetLeft+"px"}else{var G=J.offsetWidth;if(typeof G=="undefined"){G=50}L.left=(H.offsetLeft+H.offsetWidth-G)+"px"}L.top=(H.offsetTop+H.offsetHeight)+"px"};Calendar.showYearsCombo=function(K){var N=Calendar._C;if(!N){return false}var N=N;var L=N.activeDiv;var S=N.yearsCombo;if(N.hilitedYear){Calendar.removeClass(N.hilitedYear,"hilite")}if(N.activeYear){Calendar.removeClass(N.activeYear,"active")}N.activeYear=null;var M=N.date.getFullYear()+(K?1:-1);var P=S.firstChild;var Q=false;for(var T=12;T>0;--T){if(M>=N.minYear&&M<=N.maxYear){P.innerHTML=M;P.year=M;P.style.display="block";Q=true}else{P.style.display="none"}P=P.nextSibling;M+=K?N.yearStep:-N.yearStep}if(Q){var O=S.style;O.display="block";if(L.navtype<0){O.left=L.offsetLeft+"px"}else{var R=S.offsetWidth;if(typeof R=="undefined"){R=50}O.left=(L.offsetLeft+L.offsetWidth-R)+"px"}O.top=(L.offsetTop+L.offsetHeight)+"px"}};Calendar.tableMouseUp=function(ev){var cal=Calendar._C;if(!cal){return false}if(cal.timeout){clearTimeout(cal.timeout)}var el=cal.activeDiv;if(!el){return false}var target=Calendar.getTargetElement(ev);ev||(ev=window.event);Calendar.removeClass(el,"active");if(target==el||target.parentNode==el){Calendar.cellClick(el,ev)}var mon=Calendar.findMonth(target);var date=null;if(mon){date=new Date(cal.date);if(mon.month!=date.getMonth()){date.setMonth(mon.month);cal.setDate(date);cal.dateClicked=false;cal.callHandler()}}else{var year=Calendar.findYear(target);if(year){date=new Date(cal.date);if(year.year!=date.getFullYear()){date.c_setFullYear(year.year);cal.setDate(date);cal.dateClicked=false;cal.callHandler()}}}with(Calendar){removeEvent(document,"mouseup",tableMouseUp);removeEvent(document,"mouseover",tableMouseOver);removeEvent(document,"mousemove",tableMouseOver);cal._hideCombos();_C=null;return stopEvent(ev)}};Calendar.tableMouseOver=function(X){var T=Calendar._C;if(!T){return }var R=T.activeDiv;var b=Calendar.getTargetElement(X);if(b==R||b.parentNode==R){Calendar.addClass(R,"hilite active");Calendar.addClass(R.parentNode,"rowhilite")}else{if(typeof R.navtype=="undefined"||(R.navtype!=50&&(R.navtype==0||Math.abs(R.navtype)>2))){Calendar.removeClass(R,"active")}Calendar.removeClass(R,"hilite");Calendar.removeClass(R.parentNode,"rowhilite")}X||(X=window.event);if(R.navtype==50&&b!=R){var Y=Calendar.getAbsolutePos(R);var V=R.offsetWidth;var W=X.clientX;var U;var Z=true;if(W>Y.x+V){U=W-Y.x-V;Z=false}else{U=Y.x-W}if(U<0){U=0}var e=R._range;var c=R._current;var d=Math.floor(U/10)%e.length;for(var f=e.length;--f>=0;){if(e[f]==c){break}}while(d-->0){if(Z){if(--f<0){f=e.length-1}}else{if(++f>=e.length){f=0}}}var S=e[f];R.innerHTML=S;T.onUpdateTime()}var Q=Calendar.findMonth(b);if(Q){if(Q.month!=T.date.getMonth()){if(T.hilitedMonth){Calendar.removeClass(T.hilitedMonth,"hilite")}Calendar.addClass(Q,"hilite");T.hilitedMonth=Q}else{if(T.hilitedMonth){Calendar.removeClass(T.hilitedMonth,"hilite")}}}else{if(T.hilitedMonth){Calendar.removeClass(T.hilitedMonth,"hilite")}var a=Calendar.findYear(b);if(a){if(a.year!=T.date.getFullYear()){if(T.hilitedYear){Calendar.removeClass(T.hilitedYear,"hilite")}Calendar.addClass(a,"hilite");T.hilitedYear=a}else{if(T.hilitedYear){Calendar.removeClass(T.hilitedYear,"hilite")}}}else{if(T.hilitedYear){Calendar.removeClass(T.hilitedYear,"hilite")}}}return Calendar.stopEvent(X)};Calendar.tableMouseDown=function(B){if(Calendar.getTargetElement(B)==Calendar.getElement(B)){return Calendar.stopEvent(B)}};Calendar.calDragIt=function(J){var I=Calendar._C;if(!(I&&I.dragging)){return false}var G;var H;if(Calendar.is_ie){H=window.event.clientY+document.body.scrollTop;G=window.event.clientX+document.body.scrollLeft}else{G=J.pageX;H=J.pageY}I.hideShowCovered();var F=I.element.style;F.left=(G-I.xOffs)+"px";F.top=(H-I.yOffs)+"px";return Calendar.stopEvent(J)};Calendar.calDragEnd=function(ev){var cal=Calendar._C;if(!cal){return false}cal.dragging=false;with(Calendar){removeEvent(document,"mousemove",calDragIt);removeEvent(document,"mouseup",calDragEnd);tableMouseUp(ev)}cal.hideShowCovered()};Calendar.dayMouseDown=function(ev){var el=Calendar.getElement(ev);if(el.disabled){return false}var cal=el.calendar;cal.activeDiv=el;Calendar._C=cal;if(el.navtype!=300){with(Calendar){if(el.navtype==50){el._current=el.innerHTML;addEvent(document,"mousemove",tableMouseOver)}else{addEvent(document,Calendar.is_ie5?"mousemove":"mouseover",tableMouseOver)}addClass(el,"hilite active");addEvent(document,"mouseup",tableMouseUp)}}else{if(cal.isPopup){cal._dragStart(ev)}}if(el.navtype==-1||el.navtype==1){if(cal.timeout){clearTimeout(cal.timeout)}cal.timeout=setTimeout("Calendar.showMonthsCombo()",250)}else{if(el.navtype==-2||el.navtype==2){if(cal.timeout){clearTimeout(cal.timeout)}cal.timeout=setTimeout((el.navtype>0)?"Calendar.showYearsCombo(true)":"Calendar.showYearsCombo(false)",250)}else{cal.timeout=null}}return Calendar.stopEvent(ev)};Calendar.dayMouseDblClick=function(B){Calendar.cellClick(Calendar.getElement(B),B||window.event);if(Calendar.is_ie){document.selection.empty()}};Calendar.dayMouseOver=function(D){var C=Calendar.getElement(D);if(Calendar.isRelated(C,D)||Calendar._C||C.disabled){return false}if(C.ttip){if(C.ttip.substr(0,1)=="_"){C.ttip=C.caldate.c_print(C.calendar.ttDateFormat)+C.ttip.substr(1)}C.calendar.tooltips.innerHTML=C.ttip}if(C.navtype!=300){Calendar.addClass(C,"hilite");if(C.caldate){Calendar.addClass(C.parentNode,"rowhilite")}}return Calendar.stopEvent(D)};Calendar.dayMouseOut=function(ev){with(Calendar){var el=getElement(ev);if(isRelated(el,ev)||_C||el.disabled){return false}removeClass(el,"hilite");if(el.caldate){removeClass(el.parentNode,"rowhilite")}if(el.calendar){el.calendar.tooltips.innerHTML=_TT.SEL_DATE}return stopEvent(ev)}};Calendar.cellClick=function(d,U){var Q=d.calendar;var a=false;var X=false;var c=null;if(typeof d.navtype=="undefined"){if(Q.currentDateEl){Calendar.removeClass(Q.currentDateEl,"selected");Calendar.addClass(d,"selected");a=(Q.currentDateEl==d);if(!a){Q.currentDateEl=d}}Q.date.c_setDateOnly(d.caldate);c=Q.date;var R=!(Q.dateClicked=!d.otherMonth);if(!R&&!Q.currentDateEl){Q._toggleMultipleDate(new Date(c))}else{X=!d.disabled}if(R){Q._init(Q.firstDayOfWeek,c)}}else{if(d.navtype==200){Calendar.removeClass(d,"hilite");Q.callCloseHandler();return }c=new Date(Q.date);if(d.navtype==0){c.c_setDateOnly(new Date())}Q.dateClicked=false;var V=c.getFullYear();var b=c.getMonth();function S(B){var A=c.getDate();var C=c.c_getMonthDays(B);if(A>C){c.setDate(C)}c.setMonth(B)}switch(d.navtype){case 400:Calendar.removeClass(d,"hilite");var T=Calendar._TT.ABOUT;if(typeof T!="undefined"){T+=Q.showsTime?Calendar._TT.ABOUT_TIME:""}else{T='Help and about box text is not translated into this language.\nIf you know this language and you feel generous please update\nthe corresponding file in "lang" subdir to match calendar-en.js\nand send it back to to get it into the distribution ;-)\n\nThank you!\nhttp://dynarch.com/mishoo/calendar.epl\n'}alert(T);return ;case -2:if(V>Q.minYear){c.c_setFullYear(V-1)}break;case -1:if(b>0){S(b-1)}else{if(V-->Q.minYear){c.c_setFullYear(V);S(11)}}break;case 1:if(b<11){S(b+1)}else{if(V=0;){if(Y[Z]==W){break}}if(U&&U.shiftKey){if(--Z<0){Z=Y.length-1}}else{if(++Z>=Y.length){Z=0}}var P=Y[Z];d.innerHTML=P;Q.onUpdateTime();return ;case 0:if((typeof Q.getDateStatus=="function")&&Q.getDateStatus(c,c.getFullYear(),c.getMonth(),c.getDate())){return false}break}if(!c.c_equalsTo(Q.date)){Q.setDate(c);X=true}else{if(d.navtype==0){X=a=true}}}if(X){U&&Q.callHandler()}if(a){Calendar.removeClass(d,"hilite");U&&Q.callCloseHandler()}};Calendar.prototype.create=function(Y){var Z=null;if(!Y){Z=document.getElementsByTagName("body")[0];this.isPopup=true}else{Z=Y;this.isPopup=false}this.date=this.dateStr?new Date(this.dateStr):new Date();var V=Calendar.createElement("table");this.table=V;V.cellSpacing=0;V.cellPadding=0;V.calendar=this;Calendar.addEvent(V,"mousedown",Calendar.tableMouseDown);var T=Calendar.createElement("div");this.element=T;T.className="calendar";if(this.isPopup){T.style.position="absolute";T.style.display="none"}T.appendChild(V);var b=Calendar.createElement("thead",V);var X=null;var U=null;var S=this;var f=function(A,B,C){X=Calendar.createElement("td",U);X.colSpan=B;X.className="button";if(C!=0&&Math.abs(C)<=2){X.className+=" nav"}Calendar._add_evs(X);X.calendar=S;X.navtype=C;X.innerHTML="

";return X};U=Calendar.createElement("tr",b);var R=6;(this.isPopup)&&--R;(this.weekNumbers)&&++R;f("?",1,400).ttip=Calendar._TT.INFO;this.title=f("",R,300);this.title.className="title";if(this.isPopup){this.title.ttip=Calendar._TT.DRAG_TO_MOVE;this.title.style.cursor="move";f("×",1,200).ttip=Calendar._TT.CLOSE}U=Calendar.createElement("tr",b);U.className="headrow";this._nav_py=f("«",1,-2);this._nav_py.ttip=Calendar._TT.PREV_YEAR;this._nav_pm=f("‹",1,-1);this._nav_pm.ttip=Calendar._TT.PREV_MONTH;this._nav_now=f(Calendar._TT.TODAY,this.weekNumbers?4:3,0);this._nav_now.ttip=Calendar._TT.GO_TODAY;this._nav_nm=f("›",1,1);this._nav_nm.ttip=Calendar._TT.NEXT_MONTH;this._nav_ny=f("»",1,2);this._nav_ny.ttip=Calendar._TT.NEXT_YEAR;U=Calendar.createElement("tr",b);U.className="daynames";if(this.weekNumbers){X=Calendar.createElement("td",U);X.className="name wn";X.innerHTML=Calendar._TT.WK}for(var c=7;c>0;--c){X=Calendar.createElement("td",U);if(!c){X.navtype=100;X.calendar=this;Calendar._add_evs(X)}}this.firstdayname=(this.weekNumbers)?U.firstChild.nextSibling:U.firstChild;this._displayWeekdays();var d=Calendar.createElement("tbody",V);this.tbody=d;for(c=6;c>0;--c){U=Calendar.createElement("tr",d);if(this.weekNumbers){X=Calendar.createElement("td",U)}for(var e=7;e>0;--e){X=Calendar.createElement("td",U);X.calendar=this;Calendar._add_evs(X)}}if(this.showsTime){U=Calendar.createElement("tr",d);U.className="time";X=Calendar.createElement("td",U);X.className="time";X.colSpan=2;X.innerHTML=Calendar._TT.TIME||" ";X=Calendar.createElement("td",U);X.className="time";X.colSpan=this.weekNumbers?4:3;(function(){function F(P,N,O,L){var K=Calendar.createElement("span",X);K.className=P;K.innerHTML=N;K.calendar=S;K.ttip=Calendar._TT.TIME_PART;K.navtype=50;K._range=[];if(typeof O!="number"){K._range=O}else{for(var J=O;J<=L;++J){var M;if(J<10&&L>=10){M="0"+J}else{M=""+J}K._range[K._range.length]=M}}Calendar._add_evs(K);return K}var B=S.date.getHours();var I=S.date.getMinutes();var A=!S.time24;var H=(B>12);if(A&&H){B-=12}var D=F("hour",B,A?1:0,A?12:23);var E=Calendar.createElement("span",X);E.innerHTML=":";E.className="colon";var G=F("minute",I,0,59);var C=null;X=Calendar.createElement("td",U);X.className="time";X.colSpan=2;if(A){C=F("ampm",H?"pm":"am",["am","pm"])}else{X.innerHTML=" "}S.onSetTime=function(){var K,L=this.date.getHours(),J=this.date.getMinutes();if(A){K=(L>=12);if(K){L-=12}if(L==0){L=12}C.innerHTML=K?"pm":"am"}D.innerHTML=(L<10)?("0"+L):L;G.innerHTML=(J<10)?("0"+J):J};S.onUpdateTime=function(){var K=this.date;var J=parseInt(D.innerHTML,10);if(A){if(/pm/i.test(C.innerHTML)&&J<12){J+=12}else{if(/am/i.test(C.innerHTML)&&J==12){J=0}}}var N=K.getDate();var M=K.getMonth();var L=K.getFullYear();K.setHours(J);K.setMinutes(parseInt(G.innerHTML,10));K.c_setFullYear(L);K.setMonth(M);K.setDate(N);this.dateClicked=false;this.callHandler()}})()}else{this.onSetTime=this.onUpdateTime=function(){}}var a=Calendar.createElement("tfoot",V);U=Calendar.createElement("tr",a);U.className="footrow";X=f(Calendar._TT.SEL_DATE,this.weekNumbers?8:7,300);X.className="ttip";if(this.isPopup){X.ttip=Calendar._TT.DRAG_TO_MOVE;X.style.cursor="move"}this.tooltips=X;T=Calendar.createElement("div",this.element);this.monthsCombo=T;T.className="combo";for(c=0;c0;--c){var W=Calendar.createElement("div");W.className=Calendar.is_ie?"label-IEfix":"label";T.appendChild(W)}this._init(this.firstDayOfWeek,this.date);Z.appendChild(this.element)};Calendar._keyEvent=function(T){var Q=window._dynarch_popupCalendar;if(!Q||Q.multiple){return false}(Calendar.is_ie)&&(T=window.event);var V=(Calendar.is_ie||T.type=="keypress"),S=T.keyCode;if(T.ctrlKey){switch(S){case 37:V&&Calendar.cellClick(Q._nav_pm);break;case 38:V&&Calendar.cellClick(Q._nav_py);break;case 39:V&&Calendar.cellClick(Q._nav_nm);break;case 40:V&&Calendar.cellClick(Q._nav_ny);break;default:return false}}else{switch(S){case 32:Calendar.cellClick(Q._nav_now);break;case 27:V&&Q.callCloseHandler();break;case 37:case 38:case 39:case 40:if(V){var Z,R,U,X,O,K;Z=S==37||S==38;K=(S==37||S==39)?1:7;function P(){O=Q.currentDateEl;var A=O.pos;R=A&15;U=A>>4;X=Q.ar_days[U][R]}P();function Y(){var A=new Date(Q.date);A.setDate(A.getDate()-K);Q.setDate(A)}function W(){var A=new Date(Q.date);A.setDate(A.getDate()+K);Q.setDate(A)}while(1){switch(S){case 37:if(--R>=0){X=Q.ar_days[U][R]}else{R=6;S=38;continue}break;case 38:if(--U>=0){X=Q.ar_days[U][R]}else{Y();P()}break;case 39:if(++R<7){X=Q.ar_days[U][R]}else{R=0;S=40;continue}break;case 40:if(++Uthis.maxYear){v=this.maxYear;e.c_setFullYear(v)}}this.firstDayOfWeek=q;this.date=new Date(e);var d=e.getMonth();var a=e.getDate();var b=e.c_getMonthDays();e.setDate(1);var k=(e.getDay()-this.firstDayOfWeek)%7;if(k<0){k+=7}e.setDate(0-k);e.setDate(e.getDate()+1);var y=this.tbody.firstChild;var s=Calendar._SMN[d];var o=this.ar_days=new Array();var p=Calendar._TT.WEEKEND;var z=this.multiple?(this.datesCells={}):null;for(var i=0;i<6;++i,y=y.nextSibling){var AC=y.firstChild;if(this.weekNumbers){AC.className="day wn";AC.innerHTML=e.c_getWeekNumber();AC=AC.nextSibling}y.className="daysrow";var g=false,x,AA=o[i]=[];for(var j=0;j<7;++j,AC=AC.nextSibling,e.setDate(x+1)){x=e.getDate();var w=e.getDay();AC.className="day";AC.pos=i<<4|j;AA[j]=AC;var r=(e.getMonth()==d);if(!r){if(this.showsOtherMonths){AC.className+=" othermonth";AC.otherMonth=true}else{AC.className="emptycell";AC.innerHTML=" ";AC.disabled=true;continue}}else{AC.otherMonth=false;g=true}AC.disabled=false;AC.innerHTML=this.getDateText?this.getDateText(e,x):x;if(z){z[e.c_print("%Y%m%d")]=AC}if(this.getDateStatus){var n=this.getDateStatus(e,v,d,x);if(this.getDateToolTip){var u=this.getDateToolTip(e,v,d,x);if(u){AC.title=u}}if(n===true){AC.className+=" disabled";AC.disabled=true}else{if(/disabled/i.test(n)){AC.disabled=true}AC.className+=" "+n}}if(!AC.disabled){AC.caldate=new Date(e);AC.ttip="_";if(!this.multiple&&r&&x==a&&this.hiliteToday){AC.className+=" selected";this.currentDateEl=AC}if(e.getFullYear()==l&&e.getMonth()==c&&x==AB){AC.className+=" today";AC.ttip+=Calendar._TT.PART_TODAY}if(p.indexOf(w.toString())!=-1){AC.className+=AC.otherMonth?" oweekend":" weekend"}}}if(!(g||this.showsOtherMonths)){y.className="emptyrow"}}this.title.innerHTML=Calendar._MN[d]+", "+v;this.onSetTime();this.table.style.visibility="visible";this._initMultipleDates()};Calendar.prototype._initMultipleDates=function(){if(this.multiple){for(var F in this.multiple){var D=this.datesCells[F];var E=this.multiple[F];if(!E){continue}if(D){D.className+=" selected"}}}};Calendar.prototype._toggleMultipleDate=function(H){if(this.multiple){var G=H.c_print("%Y%m%d");var E=this.datesCells[G];if(E){var F=this.multiple[G];if(!F){Calendar.addClass(E,"selected");this.multiple[G]=H}else{Calendar.removeClass(E,"selected");delete this.multiple[G]}}}};Calendar.prototype.setDateToolTipHandler=function(B){this.getDateToolTip=B};Calendar.prototype.setDate=function(B){if(!B.c_equalsTo(this.date)){this._init(this.firstDayOfWeek,B)}};Calendar.prototype.refresh=function(){this._init(this.firstDayOfWeek,this.date)};Calendar.prototype.setFirstDayOfWeek=function(B){this._init(B,this.date);this._displayWeekdays()};Calendar.prototype.setDateStatusHandler=Calendar.prototype.setDisabledHandler=function(B){this.getDateStatus=B};Calendar.prototype.setRange=function(C,D){this.minYear=C;this.maxYear=D};Calendar.prototype.callHandler=function(){if(this.onSelected){this.onSelected(this,this.date.c_print(this.dateFormat))}};Calendar.prototype.callCloseHandler=function(){if(this.onClose){this.onClose(this)}this.hideShowCovered()};Calendar.prototype.destroy=function(){var B=this.element.parentNode;B.removeChild(this.element);Calendar._C=null;window._dynarch_popupCalendar=null};Calendar.prototype.reparent=function(D){var C=this.element;C.parentNode.removeChild(C);D.appendChild(C)};Calendar._checkCalendar=function(F){var E=window._dynarch_popupCalendar;if(!E){return false}var D=Calendar.is_ie?Calendar.getElement(F):Calendar.getTargetElement(F);for(;D!=null&&D!=E.element;D=D.parentNode){}if(D==null){window._dynarch_popupCalendar.callCloseHandler();return Calendar.stopEvent(F)}};Calendar.prototype.show=function(){var I=this.table.getElementsByTagName("tr");for(var J=I.length;J>0;){var H=I[--J];Calendar.removeClass(H,"rowhilite");var K=H.getElementsByTagName("td");for(var L=K.length;L>0;){var G=K[--L];Calendar.removeClass(G,"hilite");Calendar.removeClass(G,"active")}}this.element.style.display="block";this.hidden=false;if(this.isPopup){window._dynarch_popupCalendar=this;Calendar.addEvent(document,"keydown",Calendar._keyEvent);Calendar.addEvent(document,"keypress",Calendar._keyEvent);Calendar.addEvent(document,"mousedown",Calendar._checkCalendar)}this.hideShowCovered()};Calendar.prototype.hide=function(){if(this.isPopup){Calendar.removeEvent(document,"keydown",Calendar._keyEvent);Calendar.removeEvent(document,"keypress",Calendar._keyEvent);Calendar.removeEvent(document,"mousedown",Calendar._checkCalendar)}this.element.style.display="none";this.hidden=true;this.hideShowCovered()};Calendar.prototype.showAt=function(D,E){var F=this.element.style;F.left=D+"px";F.top=E+"px";this.show()};Calendar.prototype.showAtElement=function(I,H){var F=this;var G=Calendar.getAbsolutePos(I);if(!H||typeof H!="string"){this.showAt(G.x,G.y+I.offsetHeight);return true}function J(B){if(B.x<0){B.x=0}if(B.y<0){B.y=0}var A=document.createElement("div");var C=A.style;C.position="absolute";C.right=C.bottom=C.width=C.height="0px";document.body.appendChild(A);var D=Calendar.getAbsolutePos(A);document.body.removeChild(A);if(Calendar.is_ie){D.y+=document.body.scrollTop;D.x+=document.body.scrollLeft}else{D.y+=window.scrollY;D.x+=window.scrollX}var E=B.x+B.width-D.x;if(E>0){B.x-=E}E=B.y+B.height-D.y;if(E>0){B.y-=E}}this.element.style.display="block";Calendar.continuation_for_the_fucking_khtml_browser=function(){var D=F.element.offsetWidth;var B=F.element.offsetHeight;F.element.style.display="none";var C=H.substr(0,1);var A="l";if(H.length>1){A=H.substr(1,1)}switch(C){case"T":G.y-=B;break;case"B":G.y+=I.offsetHeight;break;case"C":G.y+=(I.offsetHeight-B)/2;break;case"t":G.y+=I.offsetHeight-B;break;case"b":break}switch(A){case"L":G.x-=D;break;case"R":G.x+=I.offsetWidth;break;case"C":G.x+=(I.offsetWidth-D)/2;break;case"l":G.x+=I.offsetWidth-D;break;case"r":break}G.width=D;G.height=B+40;F.monthsCombo.style.display="none";J(G);F.showAt(G.x,G.y)};if(Calendar.is_khtml){setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()",10)}else{Calendar.continuation_for_the_fucking_khtml_browser()}};Calendar.prototype.setDateFormat=function(B){this.dateFormat=B};Calendar.prototype.setTtDateFormat=function(B){this.ttDateFormat=B};Calendar.prototype.parseDate=function(D,C){if(!C){C=this.dateFormat}this.setDate(Date.parseDate(D,C))};Calendar.prototype.hideShowCovered=function(){if(!Calendar.is_ie&&!Calendar.is_opera){return }function S(A){var B=A.style.visibility;if(!B){if(document.defaultView&&typeof (document.defaultView.getComputedStyle)=="function"){if(!Calendar.is_khtml){B=document.defaultView.getComputedStyle(A,"").getPropertyValue("visibility")}else{B=""}}else{if(A.currentStyle){B=A.currentStyle.visibility}else{B=""}}}return B}var U=new Array("applet","iframe","select");var R=this.element;var T=Calendar.getAbsolutePos(R);var e=T.x;var Q=R.offsetWidth+e;var V=T.y;var W=R.offsetHeight+V;for(var c=U.length;c>0;){var d=document.getElementsByTagName(U[--c]);var f=null;for(var a=d.length;a>0;){f=d[--a];T=Calendar.getAbsolutePos(f);var X=T.x;var Y=f.offsetWidth+X;var Z=T.y;var b=f.offsetHeight+Z;if(this.hidden||(X>Q)||(YW)||(b29)?1900:2000);break;case"%b":case"%B":for(N=0;N<12;++N){if(Calendar._MN[N].substr(0,T[Z].length).toLowerCase()==T[Z].toLowerCase()){P=N;break}}break;case"%H":case"%I":case"%k":case"%l":S=parseInt(T[Z],10);break;case"%P":case"%p":if(/pm/i.test(T[Z])&&S<12){S+=12}else{if(/am/i.test(T[Z])&&S>=12){S-=12}}break;case"%M":O=parseInt(T[Z],10);break}}if(isNaN(V)){V=W.getFullYear()}if(isNaN(P)){P=W.getMonth()}if(isNaN(Y)){Y=W.getDate()}if(isNaN(S)){S=W.getHours()}if(isNaN(O)){O=W.getMinutes()}if(V!=0&&P!=-1&&Y!=0){return new Date(V,P,Y,S,O,0)}V=0;P=-1;Y=0;for(Z=0;Z31&&V==0){V=parseInt(T[Z],10);(V<100)&&(V+=(V>29)?1900:2000)}else{if(Y==0){Y=T[Z]}}}}}if(V==0){V=W.getFullYear()}if(P!=-1&&Y!=0){return new Date(V,P,Y,S,O,0)}return W};Date.prototype.c_getMonthDays=function(D){var C=this.getFullYear();if(typeof D=="undefined"){D=this.getMonth()}if(((0==(C%4))&&((0!=(C%100))||(0==(C%400))))&&D==1){return 29}else{return Date._MD[D]}};Date.prototype.c_getDayOfYear=function(){var D=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var E=new Date(this.getFullYear(),0,0,0,0,0);var F=D-E;return Math.floor(F/Date.DAY)};Date.prototype.c_getWeekNumber=function(){var E=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var F=E.getDay();E.setDate(E.getDate()-(F+6)%7+3);var D=E.valueOf();E.setMonth(0);E.setDate(4);return Math.round((D-E.valueOf())/(7*86400000))+1};Date.prototype.c_equalsTo=function(B){return((this.getFullYear()==B.getFullYear())&&(this.getMonth()==B.getMonth())&&(this.getDate()==B.getDate())&&(this.getHours()==B.getHours())&&(this.getMinutes()==B.getMinutes()))};Date.prototype.c_setDateOnly=function(C){var D=new Date(C);this.setDate(1);this.c_setFullYear(D.getFullYear());this.setMonth(D.getMonth());this.setDate(D.getDate())};Date.prototype.c_print=function(d){var U=this.getMonth();var e=this.getDate();var c=this.getFullYear();var a=this.c_getWeekNumber();var Z=this.getDay();var V={};var Y=this.getHours();var T=(Y>=12);var g=(T)?(Y-12):Y;var W=this.c_getDayOfYear();if(g==0){g=12}var S=this.getMinutes();var f=this.getSeconds();V["%a"]=Calendar._SDN[Z];V["%A"]=Calendar._DN[Z];V["%b"]=Calendar._SMN[U];V["%B"]=Calendar._MN[U];V["%C"]=1+Math.floor(c/100);V["%d"]=(e<10)?("0"+e):e;V["%e"]=e;V["%H"]=(Y<10)?("0"+Y):Y;V["%I"]=(g<10)?("0"+g):g;V["%j"]=(W<100)?((W<10)?("00"+W):("0"+W)):W;V["%k"]=Y;V["%l"]=g;V["%m"]=(U<9)?("0"+(1+U)):(1+U);V["%M"]=(S<10)?("0"+S):S;V["%n"]="\n";V["%p"]=T?"PM":"AM";V["%P"]=T?"pm":"am";V["%s"]=Math.floor(this.getTime()/1000);V["%S"]=(f<10)?("0"+f):f;V["%t"]="\t";V["%U"]=V["%W"]=V["%V"]=(a<10)?("0"+a):a;V["%u"]=Z+1;V["%w"]=Z;V["%y"]=(""+c).substr(2,2);V["%Y"]=c;V["%%"]="%";var X=/%./g;if(!Calendar.is_ie5&&!Calendar.is_khtml){return d.replace(X,function(A){return V[A]||A})}var b=d.match(X);for(var i=0;i=0;){var G=I.multiple[D];var B=G.c_print("%Y%m%d");A.multiple[B]=G}}A.showsOtherMonths=I.showOthers;A.yearStep=I.step;A.setRange(I.range[0],I.range[1]);A.params=I;A.setDateStatusHandler(I.dateStatusFunc);A.getDateText=I.dateText;A.setDateFormat(C);if(F){A.create()}A.refresh();if(!I.position){A.showAtElement(I.button||I.displayArea||I.inputField,I.align)}else{A.showAt(I.position[0],I.position[1])}return false};return K}; + +/* http://keith-wood.name/timeEntry.html + Time entry for jQuery v1.5.1. + Written by Keith Wood (kbwood{at}iinet.com.au) June 2007. + Licensed under the MIT (https://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt) license. + Please attribute the author if you use it. */ +(function($){function TimeEntry(){this._disabledInputs=[];this.regional=[];this.regional['']={show24Hours:true,separator:':',ampmPrefix:'',ampmNames:['AM','PM'],spinnerTexts:['Now','Previous field','Next field','Increment','Decrement']};this._defaults={appendText:'',showSeconds:true,timeSteps:[1,1,1],initialField:0,noSeparatorEntry:false,useMouseWheel:true,defaultTime:null,minTime:null,maxTime:null,spinnerImage:'spinnerDefault.png',spinnerSize:[20,20,8],spinnerBigImage:'',spinnerBigSize:[40,40,16],spinnerIncDecOnly:false,spinnerRepeat:[500,250],beforeShow:null,beforeSetTime:null};$.extend(this._defaults,this.regional[''])}$.extend(TimeEntry.prototype,{markerClassName:'hasTimeEntry',propertyName:'timeEntry',_appendClass:'timeEntry_append',_controlClass:'timeEntry_control',_expandClass:'timeEntry_expand',setDefaults:function(a){$.extend(this._defaults,a||{});return this},_attachPlugin:function(b,c){var d=$(b);if(d.hasClass(this.markerClassName)){return}var e={options:$.extend({},this._defaults,c),input:d,_field:0,_selectedHour:0,_selectedMinute:0,_selectedSecond:0};d.data(this.propertyName,e).addClass(this.markerClassName).bind('focus.'+this.propertyName,this._doFocus).bind('blur.'+this.propertyName,this._doBlur).bind('click.'+this.propertyName,this._doClick).bind('keydown.'+this.propertyName,this._doKeyDown).bind('keypress.'+this.propertyName,this._doKeyPress).bind('paste.'+this.propertyName,function(a){setTimeout(function(){n._parseTime(e)},1)});this._optionPlugin(b,c)},_optionPlugin:function(a,b,c){a=$(a);var d=a.data(this.propertyName);if(!b||(typeof b=='string'&&c==null)){var e=b;b=(d||{}).options;return(b&&e?b[e]:b)}if(!a.hasClass(this.markerClassName)){return}b=b||{};if(typeof b=='string'){var e=b;b={};b[e]=c}var f=this._extractTime(d);$.extend(d.options,b);d._field=0;if(f){this._setTime(d,new Date(0,0,0,f[0],f[1],f[2]))}a.next('span.'+this._appendClass).remove();a.parent().find('span.'+this._controlClass).remove();if($.fn.mousewheel){a.unmousewheel()}var g=(!d.options.spinnerImage?null:$(''));a.after(d.options.appendText?''+d.options.appendText+'':'').after(g||'');if(d.options.useMouseWheel&&$.fn.mousewheel){a.mousewheel(this._doMouseWheel)}if(g){g.mousedown(this._handleSpinner).mouseup(this._endSpinner).mouseover(this._expandSpinner).mouseout(this._endSpinner).mousemove(this._describeSpinner)}},_enablePlugin:function(a){this._enableDisable(a,false)},_disablePlugin:function(a){this._enableDisable(a,true)},_enableDisable:function(b,c){var d=$.data(b,this.propertyName);if(!d){return}b.disabled=c;if(b.nextSibling&&b.nextSibling.nodeName.toLowerCase()=='span'){n._changeSpinner(d,b.nextSibling,(c?5:-1))}n._disabledInputs=$.map(n._disabledInputs,function(a){return(a==b?null:a)});if(c){n._disabledInputs.push(b)}},_isDisabledPlugin:function(a){return $.inArray(a,this._disabledInputs)>-1},_destroyPlugin:function(b){b=$(b);if(!b.hasClass(this.markerClassName)){return}b.removeClass(this.markerClassName).removeData(this.propertyName).unbind('.'+this.propertyName);if($.fn.mousewheel){b.unmousewheel()}this._disabledInputs=$.map(this._disabledInputs,function(a){return(a==b[0]?null:a)});b.siblings('.'+this._appendClass+',.'+this._controlClass).remove()},_setTimePlugin:function(a,b){var c=$.data(a,this.propertyName);if(c){if(b===null||b===''){c.input.val('')}else{this._setTime(c,b?(typeof b=='object'?new Date(b.getTime()):b):null)}}},_getTimePlugin:function(a){var b=$.data(a,this.propertyName);var c=(b?this._extractTime(b):null);return(!c?null:new Date(0,0,0,c[0],c[1],c[2]))},_getOffsetPlugin:function(a){var b=$.data(a,this.propertyName);var c=(b?this._extractTime(b):null);return(!c?0:(c[0]*3600+c[1]*60+c[2])*1000)},_doFocus:function(a){var b=(a.nodeName&&a.nodeName.toLowerCase()=='input'?a:this);if(n._lastInput==b||n._isDisabledPlugin(b)){n._focussed=false;return}var c=$.data(b,n.propertyName);n._focussed=true;n._lastInput=b;n._blurredInput=null;$.extend(c.options,($.isFunction(c.options.beforeShow)?c.options.beforeShow.apply(b,[b]):{}));n._parseTime(c);setTimeout(function(){n._showField(c)},10)},_doBlur:function(a){n._blurredInput=n._lastInput;n._lastInput=null},_doClick:function(b){var c=b.target;var d=$.data(c,n.propertyName);if(!n._focussed){var e=d.options.separator.length+2;d._field=0;if(c.selectionStart!=null){for(var f=0;f<=Math.max(1,d._secondField,d._ampmField);f++){var g=(f!=d._ampmField?(f*e)+2:(d._ampmField*e)+d.options.ampmPrefix.length+d.options.ampmNames[0].length);d._field=f;if(c.selectionStart=48){return true}var b=$.data(a.target,n.propertyName);switch(a.keyCode){case 9:return(a.shiftKey?n._changeField(b,-1,true):n._changeField(b,+1,true));case 35:if(a.ctrlKey){n._setValue(b,'')}else{b._field=Math.max(1,b._secondField,b._ampmField);n._adjustField(b,0)}break;case 36:if(a.ctrlKey){n._setTime(b)}else{b._field=0;n._adjustField(b,0)}break;case 37:n._changeField(b,-1,false);break;case 38:n._adjustField(b,+1);break;case 39:n._changeField(b,+1,false);break;case 40:n._adjustField(b,-1);break;case 46:n._setValue(b,'');break;default:return true}return false},_doKeyPress:function(a){var b=String.fromCharCode(a.charCode==undefined?a.keyCode:a.charCode);if(b<' '){return true}var c=$.data(a.target,n.propertyName);n._handleKeyPress(c,b);return false},_doMouseWheel:function(a,b){if(n._isDisabledPlugin(a.target)){return}var c=$.data(a.target,n.propertyName);c.input.focus();if(!c.input.val()){n._parseTime(c)}n._adjustField(c,b);a.preventDefault()},_expandSpinner:function(b){var c=n._getSpinnerTarget(b);var d=$.data(n._getInput(c),n.propertyName);if(n._isDisabledPlugin(d.input[0])){return}if(d.options.spinnerBigImage){d._expanded=true;var e=$(c).offset();var f=null;$(c).parents().each(function(){var a=$(this);if(a.css('position')=='relative'||a.css('position')=='absolute'){f=a.offset()}return!f});$('
').mousedown(n._handleSpinner).mouseup(n._endSpinner).mouseout(n._endExpand).mousemove(n._describeSpinner).insertAfter(c)}},_getInput:function(a){return $(a).siblings('.'+n.markerClassName)[0]},_describeSpinner:function(a){var b=n._getSpinnerTarget(a);var c=$.data(n._getInput(b),n.propertyName);b.title=c.options.spinnerTexts[n._getSpinnerRegion(c,a)]},_handleSpinner:function(a){var b=n._getSpinnerTarget(a);var c=n._getInput(b);if(n._isDisabledPlugin(c)){return}if(c==n._blurredInput){n._lastInput=c;n._blurredInput=null}var d=$.data(c,n.propertyName);n._doFocus(c);var e=n._getSpinnerRegion(d,a);n._changeSpinner(d,b,e);n._actionSpinner(d,e);n._timer=null;n._handlingSpinner=true;if(e>=3&&d.options.spinnerRepeat[0]){n._timer=setTimeout(function(){n._repeatSpinner(d,e)},d.options.spinnerRepeat[0]);$(b).one('mouseout',n._releaseSpinner).one('mouseup',n._releaseSpinner)}},_actionSpinner:function(a,b){if(!a.input.val()){n._parseTime(a)}switch(b){case 0:this._setTime(a);break;case 1:this._changeField(a,-1,false);break;case 2:this._changeField(a,+1,false);break;case 3:this._adjustField(a,+1);break;case 4:this._adjustField(a,-1);break}},_repeatSpinner:function(a,b){if(!n._timer){return}n._lastInput=n._blurredInput;this._actionSpinner(a,b);this._timer=setTimeout(function(){n._repeatSpinner(a,b)},a.options.spinnerRepeat[1])},_releaseSpinner:function(a){clearTimeout(n._timer);n._timer=null},_endExpand:function(a){n._timer=null;var b=n._getSpinnerTarget(a);var c=n._getInput(b);var d=$.data(c,n.propertyName);$(b).remove();d._expanded=false},_endSpinner:function(a){n._timer=null;var b=n._getSpinnerTarget(a);var c=n._getInput(b);var d=$.data(c,n.propertyName);if(!n._isDisabledPlugin(c)){n._changeSpinner(d,b,-1)}if(n._handlingSpinner){n._lastInput=n._blurredInput}if(n._lastInput&&n._handlingSpinner){n._showField(d)}n._handlingSpinner=false},_getSpinnerTarget:function(a){return a.target||a.srcElement},_getSpinnerRegion:function(a,b){var c=this._getSpinnerTarget(b);var d=$(c).offset();var e=[document.documentElement.scrollLeft||document.body.scrollLeft,document.documentElement.scrollTop||document.body.scrollTop];var f=(a.options.spinnerIncDecOnly?99:b.clientX+e[0]-d.left);var g=b.clientY+e[1]-d.top;var h=a.options[a._expanded?'spinnerBigSize':'spinnerSize'];var i=(a.options.spinnerIncDecOnly?99:h[0]-1-f);var j=h[1]-1-g;if(h[2]>0&&Math.abs(f-i)<=h[2]&&Math.abs(g-j)<=h[2]){return 0}var k=Math.min(f,g,i,j);return(k==f?1:(k==i?2:(k==g?3:4)))},_changeSpinner:function(a,b,c){$(b).css('background-position','-'+((c+1)*a.options[a._expanded?'spinnerBigSize':'spinnerSize'][0])+'px 0px')},_parseTime:function(a){var b=this._extractTime(a);if(b){a._selectedHour=b[0];a._selectedMinute=b[1];a._selectedSecond=b[2]}else{var c=this._constrainTime(a);a._selectedHour=c[0];a._selectedMinute=c[1];a._selectedSecond=(a.options.showSeconds?c[2]:0)}a._secondField=(a.options.showSeconds?2:-1);a._ampmField=(a.options.show24Hours?-1:(a.options.showSeconds?3:2));a._lastChr='';a._field=Math.max(0,Math.min(Math.max(1,a._secondField,a._ampmField),a.options.initialField));if(a.input.val()!=''){this._showTime(a)}},_extractTime:function(a,b){b=b||a.input.val();var c=b.split(a.options.separator);if(a.options.separator==''&&b!=''){c[0]=b.substring(0,2);c[1]=b.substring(2,4);c[2]=b.substring(4,6)}if(c.length>=2){var d=!a.options.show24Hours&&(b.indexOf(a.options.ampmNames[0])>-1);var e=!a.options.show24Hours&&(b.indexOf(a.options.ampmNames[1])>-1);var f=parseInt(c[0],10);f=(isNaN(f)?0:f);f=((d||e)&&f==12?0:f)+(e?12:0);var g=parseInt(c[1],10);g=(isNaN(g)?0:g);var h=(c.length>=3?parseInt(c[2],10):0);h=(isNaN(h)||!a.options.showSeconds?0:h);return this._constrainTime(a,[f,g,h])}return null},_constrainTime:function(a,b){var c=(b!=null);if(!c){var d=this._determineTime(a.options.defaultTime,a)||new Date();b=[d.getHours(),d.getMinutes(),d.getSeconds()]}var e=false;for(var i=0;i1){b[i]=Math.round(b[i]/a.options.timeSteps[i])*a.options.timeSteps[i];e=true}}return b},_showTime:function(a){var b=(this._formatNumber(a.options.show24Hours?a._selectedHour:((a._selectedHour+11)%12)+1)+a.options.separator+this._formatNumber(a._selectedMinute)+(a.options.showSeconds?a.options.separator+this._formatNumber(a._selectedSecond):'')+(a.options.show24Hours?'':a.options.ampmPrefix+a.options.ampmNames[(a._selectedHour<12?0:1)]));this._setValue(a,b);this._showField(a)},_showField:function(a){var b=a.input[0];if(a.input.is(':hidden')||n._lastInput!=b){return}var c=a.options.separator.length+2;var d=(a._field!=a._ampmField?(a._field*c):(a._ampmField*c)-a.options.separator.length+a.options.ampmPrefix.length);var e=d+(a._field!=a._ampmField?2:a.options.ampmNames[0].length);if(b.setSelectionRange){b.setSelectionRange(d,e)}else if(b.createTextRange){var f=b.createTextRange();f.moveStart('character',d);f.moveEnd('character',e-a.input.val().length);f.select()}if(!b.disabled){b.focus()}},_formatNumber:function(a){return(a<10?'0':'')+a},_setValue:function(a,b){if(b!=a.input.val()){a.input.val(b).trigger('change')}},_changeField:function(a,b,c){var d=(a.input.val()==''||a._field==(b==-1?0:Math.max(1,a._secondField,a._ampmField)));if(!d){a._field+=b}this._showField(a);a._lastChr='';return(d&&c)},_adjustField:function(a,b){if(a.input.val()==''){b=0}this._setTime(a,new Date(0,0,0,a._selectedHour+(a._field==0?b*a.options.timeSteps[0]:0)+(a._field==a._ampmField?b*12:0),a._selectedMinute+(a._field==1?b*a.options.timeSteps[1]:0),a._selectedSecond+(a._field==a._secondField?b*a.options.timeSteps[2]:0)))},_setTime:function(a,b){b=this._determineTime(b,a);var c=this._constrainTime(a,b?[b.getHours(),b.getMinutes(),b.getSeconds()]:null);b=new Date(0,0,0,c[0],c[1],c[2]);var b=this._normaliseTime(b);var d=this._normaliseTime(this._determineTime(a.options.minTime,a));var e=this._normaliseTime(this._determineTime(a.options.maxTime,a));b=(d&&be?e:b));if($.isFunction(a.options.beforeSetTime)){b=a.options.beforeSetTime.apply(a.input[0],[this._getTimePlugin(a.input[0]),b,d,e])}a._selectedHour=b.getHours();a._selectedMinute=b.getMinutes();a._selectedSecond=b.getSeconds();this._showTime(a)},_determineTime:function(i,j){var k=function(a){var b=new Date();b.setTime(b.getTime()+a*1000);return b};var l=function(a){var b=n._extractTime(j,a);var c=new Date();var d=(b?b[0]:c.getHours());var e=(b?b[1]:c.getMinutes());var f=(b?b[2]:c.getSeconds());if(!b){var g=/([+-]?[0-9]+)\s*(s|S|m|M|h|H)?/g;var h=g.exec(a);while(h){switch(h[2]||'s'){case's':case'S':f+=parseInt(h[1],10);break;case'm':case'M':e+=parseInt(h[1],10);break;case'h':case'H':d+=parseInt(h[1],10);break}h=g.exec(a)}}c=new Date(0,0,10,d,e,f,0);if(/^!/.test(a)){if(c.getDate()>10){c=new Date(0,0,10,23,59,59)}else if(c.getDate()<10){c=new Date(0,0,10,0,0,0)}}return c};return(i?(typeof i=='string'?l(i):(typeof i=='number'?k(i):i)):null)},_normaliseTime:function(a){if(!a){return null}a.setFullYear(1900);a.setMonth(0);a.setDate(0);return a},_handleKeyPress:function(a,b){if(b==a.options.separator){this._changeField(a,+1,false)}else if(b>='0'&&b<='9'){var c=parseInt(b,10);var d=parseInt(a._lastChr+b,10);var e=(a._field!=0?a._selectedHour:(a.options.show24Hours?(d<24?d:c):(d>=1&&d<=12?d:(c>0?c:a._selectedHour))%12+(a._selectedHour>=12?12:0)));var f=(a._field!=1?a._selectedMinute:(d<60?d:c));var g=(a._field!=a._secondField?a._selectedSecond:(d<60?d:c));var h=this._constrainTime(a,[e,f,g]);this._setTime(a,new Date(0,0,0,h[0],h[1],h[2]));if(a.options.noSeparatorEntry&&a._lastChr){this._changeField(a,+1,false)}else{a._lastChr=b}}else if(!a.options.show24Hours){b=b.toLowerCase();if((b==a.options.ampmNames[0].substring(0,1).toLowerCase()&&a._selectedHour>=12)||(b==a.options.ampmNames[1].substring(0,1).toLowerCase()&&a._selectedHour<12)){var i=a._field;a._field=a._ampmField;this._adjustField(a,+1);a._field=i;this._showField(a)}}}});var m=['getOffset','getTime','isDisabled'];function isNotChained(a,b){if(a=='option'&&(b.length==0||(b.length==1&&typeof b[0]=='string'))){return true}return $.inArray(a,m)>-1}$.fn.timeEntry=function(b){var c=Array.prototype.slice.call(arguments,1);if(isNotChained(b,c)){return n['_'+b+'Plugin'].apply(n,[this[0]].concat(c))}return this.each(function(){if(typeof b=='string'){if(!n['_'+b+'Plugin']){throw'Unknown command: '+b;}n['_'+b+'Plugin'].apply(n,[this].concat(c))}else{var a=($.fn.metadata?$(this).metadata():{});n._attachPlugin(this,$.extend({},a,b||{}))}})};var n=$.timeEntry=new TimeEntry()})(jQuery); \ No newline at end of file diff --git a/web2py/applications/examples/static/js/jquery.js b/web2py/applications/examples/static/js/jquery.js new file mode 100644 index 0000000..644d35e --- /dev/null +++ b/web2py/applications/examples/static/js/jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(a,b){"use strict";"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){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(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 qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(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){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="
",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.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===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!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 ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.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},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.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=ga.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=ga.selectors={cacheLength:50,createPseudo:ia,match:V,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(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===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]||ga.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]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.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(_,aa).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("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.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.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},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,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(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),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).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:oa(!1),disabled:oa(!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 X.test(a.nodeName)},input:function(a){return W.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:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S), +a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.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 W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), +null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(" + +**/ + +jQuery(function(){ + var script_source = jQuery('script[src*="share.js"]').attr('src'); + var params = function(name,default_value) { + var match = RegExp('[?&]' + name + '=([^&]*)').exec(script_source); + return match && decodeURIComponent(match[1].replace(/\+/g, ' '))||default_value; + } + var path = params('static','social'); + var url = encodeURIComponent(window.location.href); + var host = window.location.hostname; + var title = escape(jQuery('title').text()); + var twit = 'http://twitter.com/home?status='+title+'%20'+url; + var facebook = 'http://www.facebook.com/sharer.php?u='+url; + var gplus = 'https://plus.google.com/share?url='+url; + var tbar = '
Share
Share on TwitterShare on facebookShare on Google Plus
'; + // Add the share tool bar. + jQuery('body').append(tbar); + var st = jQuery('#socialdrawer'); + st.css({'opacity':'.7','z-index':'3000','background':'#FFF','border':'solid 1px #666','border-width':' 1px 0 0 1px','height':'20px','width':'40px','position':'fixed','bottom':'0','right':'0','padding':'2px 5px','overflow':'hidden','-webkit-border-top-left-radius':' 12px','-moz-border-radius-topleft':' 12px','border-top-left-radius':' 12px','-moz-box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)','-webkit-box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)','box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)'}); + jQuery('#socialdrawer a').css({'float':'left','width':'32px','margin':'3px 2px 2px 2px','padding':'0','cursor':'pointer'}); + jQuery('#socialdrawer span').css({'float':'left','margin':'2px 3px','text-shadow':' 1px 1px 1px #FFF','color':'#444','font-size':'12px','line-height':'1em'}); + jQuery('#socialdrawer img').hide(); + // hover + st.click(function(){ + jQuery(this).animate({height:'40px', width:'160px', opacity: 0.95}, 300); + jQuery('#socialdrawer img').show(); + }); + //leave + st.mouseleave(function(){ + st.animate({height:'20px', width: '40px', opacity: .7}, 300); + jQuery('#socialdrawer img').hide(); + return false; + } ); + }); diff --git a/web2py/applications/examples/static/js/web2py.js b/web2py/applications/examples/static/js/web2py.js new file mode 100644 index 0000000..22b9f25 --- /dev/null +++ b/web2py/applications/examples/static/js/web2py.js @@ -0,0 +1,828 @@ +(function ($, undefined) { + /* + * Unobtrusive scripting adapter for jQuery, largely taken from + * the wonderful https://github.com/rails/jquery-ujs + * + * + * Released under the MIT license + * + */ + 'use strict'; + if ($.web2py !== undefined) { + $.error('web2py.js has already been loaded!'); + } + + var FORMDATA_IS_SUPPORTED = typeof(FormData) !== 'undefined'; + var animateIn = 'fadeIn'; + // var animateIn = 'slideDown'; + + String.prototype.reverse = function () { + return this.split('').reverse().join(''); + }; + var web2py; + + $.web2py = web2py = { + + isUndefined: function (obj) { + /* grabbed from underscore.js */ + return obj === void 0; + }, + popup: function (url) { + /* popup a window */ + var newwindow = window.open(url, 'name', 'height=400,width=600'); + if (window.focus) newwindow.focus(); + return false; + }, + collapse: function (id) { + /* toggle an element */ + $('#' + id).slideToggle(); + }, + fade: function (id, value) { + /*fade something*/ + if (value > 0) $('#' + id).hide().fadeIn('slow'); + else $('#' + id).show().fadeOut('slow'); + }, + ajax: function (u, s, t, options) { + /*simple ajax function*/ + + // set options default value + options = typeof options !== 'undefined' ? options : {}; + + var query = ''; + if (typeof s == 'string') { + var d = $(s).serialize(); + if (d) { + query = d; + } + } else { + var pcs = []; + if (s !== null && !web2py.isUndefined(s)) + for (var i = 0; i < s.length; i++) { + var q = $('[name=' + s[i] + ']').serialize(); + if (q) { + pcs.push(q); + } + } + if (pcs.length > 0) { + query = pcs.join('&'); + } + } + + // default success action + var success_function = function (msg) { + if (t) { + if (t == ':eval') eval(msg); + else if (typeof t == 'string') $('#' + t).html(msg); + else t(msg); + } + }; + + // declare success actions as array + var success = [success_function]; + + // add user success actions + if ($.isArray(options.done)){ + success = $.merge(success, options.done); + } else { + success.push(options.done); + } + + // default jquery ajax options + var ajax_options = { + type: 'POST', + url: u, + data: query, + success: success + }; + + //remove custom "done" option if exists + delete options.done; + + // merge default ajax options with user custom options + for (var attrname in options) { + ajax_options[attrname] = options[attrname]; + } + + // call ajax function + $.ajax(ajax_options); + }, + ajax_fields: function (target) { + /* + *this attaches something to a newly loaded fragment/page + * Ideally all events should be bound to the document, so we can avoid calling + * this over and over... all will be bound to the document + */ + /*adds btn class to buttons*/ + $('button:not([class^="btn"])', target).addClass('btn'); + $( + 'form input[type="submit"]:not([class^="btn"]), form input[type="button"]:not([class^="btn"])', + target).addClass('btn'); + /* javascript for PasswordWidget*/ + $('input[type=password][data-w2p_entropy]', target).each(function () { + web2py.validate_entropy($(this)); + }); + /* javascript for ListWidget*/ + $('ul.w2p_list', target).each(function () { + function pe(ul, e) { + var new_line = ml(ul); + rel(ul); + if ($(e.target).parent().is(':visible')) { + /* make sure we didn't delete the element before we insert after */ + new_line.insertAfter($(e.target).parent()); + } else { + /* the line we clicked on was deleted, just add to end of list */ + new_line.appendTo(ul); + } + new_line.find(':text').focus(); + return false; + } + + function rl(ul, e) { + if ($(ul).children().length > 1) { + /* only remove if we have more than 1 item so the list is never empty */ + $(e.target).parent().remove(); + } + } + + function ml(ul) { + /* clone the first field */ + var line = $(ul).find('li:first').clone(true); + line.find(':text').val(''); + return line; + } + + function rel(ul) { + /* keep only as many as needed*/ + $(ul).find('li').each(function () { + var trimmed = $.trim($(this.firstChild).val()); + if (trimmed === '') $(this).remove(); + else $(this.firstChild).val(trimmed); + }); + } + var ul = this; + $(ul).find(':text').after('+ -').keypress( + function (e) { + return (e.which == 13) ? pe(ul, e) : true; + }).next().click(function (e) { + pe(ul, e); + e.preventDefault(); + }).next().click(function (e) { + rl(ul, e); + e.preventDefault(); + }); + }); + }, + ajax_init: function (target) { + /*called whenever a fragment gets loaded */ + $('.w2p_hidden', target).hide(); + web2py.manage_errors(target); + web2py.ajax_fields(target); + web2py.show_if_handler(target); + web2py.component_handler(target); + }, + /* manage errors in forms */ + manage_errors: function (target) { + $('div.error', target).hide()[animateIn]('slow'); + }, + after_ajax: function (xhr) { + /* called whenever an ajax request completes */ + var command = xhr.getResponseHeader('web2py-component-command'); + var flash = xhr.getResponseHeader('web2py-component-flash'); + if (command !== null) { + eval(decodeURIComponent(command)); + } + if (flash) { + web2py.flash(decodeURIComponent(flash)); + } + }, + event_handlers: function () { + /* + * This is called once for page + * Ideally it should bound all the things that are needed + * and require no dom manipulations + */ + var doc = $(document); + doc.on('click', '.w2p_flash', function (event) { + event.preventDefault(); + var t = $(this); + if (t.css('top') == '0px') t.slideUp('slow'); + else t.fadeOut(); + }); + doc.on('keyup', 'input.integer', function () { + var nvalue = this.value.reverse().replace(/[^0-9\-]|\-(?=.)/g, '').reverse(); + if (this.value != nvalue) this.value = nvalue; + }); + doc.on('keyup', 'input.double, input.decimal', function () { + var nvalue = this.value.reverse().replace( + /[^0-9\-\.,]|[\-](?=.)|[\.,](?=[0-9]*[\.,])/g, '').reverse(); + if (this.value != nvalue) this.value = nvalue; + }); + var confirm_message = !web2py.isUndefined(w2p_ajax_confirm_message) ? w2p_ajax_confirm_message : + 'Are you sure you want to delete this object?'; + doc.on('click', 'input[type="checkbox"].delete', function () { + if (this.checked) + if (!web2py.confirm(confirm_message)) this.checked = false; + }); + var datetime_format = !web2py.isUndefined(w2p_ajax_datetime_format) ? w2p_ajax_datetime_format : + '%Y-%m-%d %H:%M:%S'; + doc.on('click', 'input.datetime', function () { + var tformat = $(this).data('w2p_datetime_format'); + var active = $(this).data('w2p_datetime'); + var format = !web2py.isUndefined(tformat) ? tformat : datetime_format; + if (active === undefined) { + Calendar.setup({ + inputField: this, + ifFormat: format, + showsTime: true, + timeFormat: '24' + }); + $(this).attr('autocomplete', 'off'); + $(this).data('w2p_datetime', 1); + $(this).trigger('click'); + } + }); + var date_format = !web2py.isUndefined(w2p_ajax_date_format) ? w2p_ajax_date_format : '%Y-%m-%d'; + doc.on('click', 'input.date', function () { + var tformat = $(this).data('w2p_date_format'); + var active = $(this).data('w2p_date'); + var format = !web2py.isUndefined(tformat) ? tformat : date_format; + if (active === undefined) { + Calendar.setup({ + inputField: this, + ifFormat: format, + showsTime: false + }); + $(this).data('w2p_date', 1); + $(this).attr('autocomplete', 'off'); + $(this).trigger('click'); + } + }); + doc.on('focus', 'input.time', function () { + var active = $(this).data('w2p_time'); + if (web2py.isUndefined(active)) { + $(this).timeEntry({ + spinnerImage: '' + }).attr('autocomplete', 'off'); + $(this).data('w2p_time', 1); + } + }); + /* help preventing double form submission for normal form (not LOADed) */ + $(doc).on('submit', 'form', function (e) { + var submit_buttons = $(this).find(web2py.formInputClickSelector); + submit_buttons.each(function() { + web2py.disableElement($(this)); + }) + /* safeguard in case the form doesn't trigger a refresh, + see https://github.com/web2py/web2py/issues/1100 */ + setTimeout(function () { + submit_buttons.each(function() { + web2py.enableElement($(this)); + }); + }, 5000); + }); + doc.ajaxSuccess(function (e, xhr) { + var redirect = xhr.getResponseHeader('web2py-redirect-location'); + if (redirect !== null) { + window.location = redirect; + } + /* run this here only if this Ajax request is NOT for a web2py component. */ + if (xhr.getResponseHeader('web2py-component-content') === null) { + web2py.after_ajax(xhr); + } + }); + + doc.ajaxError(function (e, xhr, settings, exception) { + /*personally I don't like it. + *if there's an error it it flashed and can be removed + *as any other message + *doc.off('click', '.w2p_flash') + */ + switch (xhr.status) { + case 500: + web2py.flash(ajax_error_500); + } + }); + + }, + trap_form: function (action, target) { + /* traps any LOADed form */ + $('#' + target + ' form').each(function () { + var form = $(this); + if (form.hasClass('no_trap')) { + return; + } + + var w2p_target = $(this).attr('data-w2p_target'); + if (web2py.isUndefined(w2p_target) || w2p_target === false) { + form.attr('data-w2p_target', target); + } else { + target = w2p_target; + } + + var url = form.attr('action'); + if ((url === '') || (url === '#') || web2py.isUndefined(url)) { + /* form has no action. Use component url. */ + url = action; + } + + form.submit(function (e) { + web2py.disableElement(form.find(web2py.formInputClickSelector)); + web2py.hide_flash(); + + var formData; + if (FORMDATA_IS_SUPPORTED) { + formData = new FormData(form[0]); // Allows file uploads. + } else { + formData = form.serialize(); // Fallback for older browsers. + } + web2py.ajax_page('post', url, formData, target, form); + + e.preventDefault(); + }); + form.on('click', web2py.formInputClickSelector, function (e) { + e.preventDefault(); + var input_name = $(this).attr('name'); + if (!web2py.isUndefined(input_name)) { + $('').attr('name', input_name) + .attr('value', $(this).val()).appendTo(form); + } + form.trigger('submit'); + }); + }); + }, + ajax_page: function (method, action, data, target, element) { + /* element is a new parameter, but should be put be put in front */ + if (web2py.isUndefined(element)) element = $(document); + /* if target is not there, fill it with something that there isn't in the page*/ + if (web2py.isUndefined(target) || target === '') target = 'w2p_none'; + + /* processData and contentType must be set to false when passing a FormData + object to jQuery.ajax. */ + var isFormData = Object.prototype.toString.call(data) === '[object FormData]'; + var contentType = isFormData ? false : 'application/x-www-form-urlencoded; charset=UTF-8'; + if (web2py.fire(element, 'ajax:before', null, target)) { /*test a usecase, should stop here if returns false */ + $.ajax({ + 'type': method, + 'url': action, + 'data': data, + 'processData': !isFormData, + 'contentType': contentType, + 'beforeSend': function (xhr, settings) { + xhr.setRequestHeader('web2py-component-location', document.location); + xhr.setRequestHeader('web2py-component-element', target); + web2py.fire(element, 'w2p:componentBegin', [xhr, settings], target); + return web2py.fire(element, 'ajax:beforeSend', [xhr, settings], target); //test a usecase, should stop here if returns false + }, + 'success': function (data, status, xhr) { + /*bummer for form submissions....the element is not there after complete + *because it gets replaced by the new response.... + */ + web2py.fire(element, 'ajax:success', [data, status, xhr], target); + }, + 'error': function (xhr, status, error) { + /*bummer for form submissions....in addition to the element being not there after + *complete because it gets replaced by the new response, standard form + *handling just returns the same status code for good and bad + *form submissions (i.e. that triggered a validator error) + */ + web2py.fire(element, 'ajax:error', [xhr, status, error], target); + }, + 'complete': function (xhr, status) { + web2py.fire(element, 'ajax:complete', [xhr, status], target); + web2py.updatePage(xhr, target); /* Parse and load the html received */ + web2py.trap_form(action, target); + web2py.ajax_init('#' + target); + web2py.after_ajax(xhr); + web2py.fire(element, 'w2p:componentComplete', [xhr, status], target); // Let us know the component is finished loading + } + }); + } + }, + component: function (action, target, timeout, times, el) { + /* element is a new parameter, but should be put in front */ + $(function () { + var jelement = $('#' + target); + var element = jelement.get(0); + var statement = 'jQuery("#' + target + '").get(0).reload();'; + element.reload = function () { + /* Continue if times is Infinity or + * the times limit is not reached + */ + if (element.reload_check()) { + web2py.ajax_page('get', action, null, target, el); + } + }; + /* Method to check timing limit */ + element.reload_check = function () { + if (jelement.hasClass('w2p_component_stop')) { + clearInterval(this.timing); + return false; + } + if (this.reload_counter == Infinity) { + return true; + } else { + if (!isNaN(this.reload_counter)) { + this.reload_counter -= 1; + if (this.reload_counter < 0) { + if (!this.run_once) { + clearInterval(this.timing); + return false; + } + } else { + return true; + } + } + } + return false; + }; + if (!isNaN(timeout)) { + element.timeout = timeout; + element.reload_counter = times; + if (times > 1) { + /* Multiple or infinite reload + * Run first iteration + */ + web2py.ajax_page('get', action, null, target, el); + element.run_once = false; + element.timing = setInterval(statement, timeout); + element.reload_counter -= 1; + } else if (times == 1) { + /* Run once with timeout */ + element.run_once = true; + element.setTimeout = setTimeout; + element.timing = setTimeout(statement, timeout); + } + } else { + /* run once (no timeout specified) */ + element.reload_counter = Infinity; + web2py.ajax_page('get', action, null, target, el); + } + }); + }, + updatePage: function (xhr, target) { + var t = $('#' + target); + var html = $.parseHTML(xhr.responseText, document, true); + var title_elements = $(html).filter('title').add($(html).find('title')); + var title = title_elements.last().text(); + if (title) { + title_elements.remove(); /* Remove any title elements from the response */ + document.title = $.trim(title); /* Set the new document title */ + } + var content = xhr.getResponseHeader('web2py-component-content'); + if (content == 'prepend') t.prepend(xhr.responseText); + else if (content == 'append') t.append(xhr.responseText); + else if (content != 'hide') t.html(html); + }, + calc_entropy: function (mystring) { + /* calculate a simple entropy for a given string */ + var csets = new Array( + 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', + '0123456789', '!@#$\%^&*()', '~`-_=+[]{}\|;:\'",.<>?/', + '0123456789abcdefghijklmnopqrstuvwxyz'); + var score = 0, + other = {}, + seen = {}, + lastset = null, + mystringlist = mystring.split(''); + for (var i = 0; i < mystringlist.length; i++) { /* classify this character */ + var c = mystringlist[i], + inset = 5; + for (var j = 0; j < csets.length; j++) + if (csets[j].indexOf(c) != -1) { + inset = j; + break; + } + /*calculate effect of character on alphabet size */ + if (!(inset in seen)) { + seen[inset] = 1; + score += csets[inset].length; + } else if (!(c in other)) { + score += 1; + other[c] = 1; + } + if (inset != lastset) { + score += 1; + lastset = inset; + } + } + var entropy = mystring.length * Math.log(score) / 0.6931471805599453; + return Math.round(entropy * 100) / 100; + }, + validate_entropy: function (myfield, req_entropy) { + if (!web2py.isUndefined(myfield.data('w2p_entropy'))) req_entropy = myfield.data('w2p_entropy'); + var validator = function () { + var v = (web2py.calc_entropy(myfield.val()) || 0) / req_entropy; + var r = 0, + g = 0, + b = 0, + rs = function (x) { + return Math.round(x * 15).toString(16); + }; + if (v <= 0.5) { + r = 1.0; + g = 2.0 * v; + } else { + r = (1.0 - 2.0 * (Math.max(v, 0) - 0.5)); + g = 1.0; + } + var color = '#' + rs(r) + rs(g) + rs(b); + myfield.css('background-color', color); + var entropy_callback = myfield.data('entropy_callback'); + if (entropy_callback) entropy_callback(v); + }; + if (!myfield.hasClass('entropy_check')) myfield.on('keyup', validator).on('keydown', validator) + .addClass('entropy_check'); + }, + web2py_websocket: function (url, onmessage, onopen, onclose) { + if ('WebSocket' in window) { + var ws = new WebSocket(url); + ws.onopen = onopen ? onopen : (function () {}); + ws.onmessage = onmessage; + ws.onclose = onclose ? onclose : (function () {}); + return true; /* supported */ + } else return false; /* not supported */ + }, + /* new from here */ + /* Form input elements bound by web2py.js */ + formInputClickSelector: 'input[type=submit], input[type=image], button[type=submit], button:not([type])', + /* Form input elements disabled during form submission */ + disableSelector: 'input, button, textarea, select', + /* Form input elements re-enabled after form submission */ + enableSelector: 'input:disabled, button:disabled, textarea:disabled, select:disabled', + /* Triggers an event on an element and returns false if the event result is false */ + fire: function (obj, type, data, target) { + var event = $.Event(type, { + 'containerTarget': $('#' + target)[0] + }); + obj.trigger(event, data); + return event.result !== false; + }, + /* Helper function, needed to provide consistent behavior in IE */ + stopEverything: function (e) { + $(e.target).trigger('w2p:everythingStopped'); + e.stopImmediatePropagation(); + return false; + }, + confirm: function (message) { + return confirm(message); + }, + /* replace element's html with the 'data-disable-with' after storing original html + * and prevent clicking on it */ + disableElement: function (el) { + if (!web2py.isUndefined(el.data('w2p_disable'))) { + return false; + } + el.addClass('disabled'); + var method = el.is('input') ? 'val' : 'html'; + //method = el.attr('name') ? 'html' : 'val'; + var disable_with_message = (!web2py.isUndefined(w2p_ajax_disable_with_message)) ? + w2p_ajax_disable_with_message : 'Working...'; + /*store enabled state if not already disabled */ + if (web2py.isUndefined(el.data('w2p_enable_with'))) { + el.data('w2p_enable_with', el[method]()); + } + /*if you don't want to see "working..." on buttons, replace the following + * two lines with this one + * el.data('w2p_disable_with', el[method]()); + */ + if ((el.data('w2p_disable_with') == 'default') || (web2py.isUndefined(el.data( + 'w2p_disable_with')))) { + el.data('w2p_disable_with', disable_with_message); + } + + /* set to disabled state*/ + el[method](el.data('w2p_disable_with')); + + el.bind('click.w2pDisable', function (e) { /* prevent further clicking*/ + return web2py.stopEverything(e); + }); + }, + + /* restore element to its original state which was disabled by 'disableElement' above*/ + enableElement: function (el) { + var method = el.is('input') ? 'val' : 'html'; + if (!web2py.isUndefined(el.data('w2p_enable_with'))) { + /* set to old enabled state */ + el[method](el.data('w2p_enable_with')); + el.removeData('w2p_enable_with'); + } + el.removeClass('disabled'); + el.unbind('click.w2pDisable'); + }, + /*convenience wrapper, internal use only */ + simple_component: function (action, target, element) { + web2py.component(action, target, 0, 1, element); + }, + /*helper for flash messages*/ + flash: function (message, status) { + var flash = $('.w2p_flash'); + web2py.hide_flash(); + flash.text(message).addClass(status); + if (flash.html()) flash.append(' × ')[animateIn](); + }, + hide_flash: function () { + $('.w2p_flash').fadeOut(0).html(''); + }, + show_if_handler: function (target) { + var triggers = {}; + var show_if = function () { + var t = $(this); + var id = t.attr('id'); + t.attr('value', t.val()); + for (var k = 0; k < triggers[id].length; k++) { + var dep = $('#' + triggers[id][k], target); + var tr = $('#' + triggers[id][k] + '__row', target); + if (t.is(dep.attr('data-show-if'))) tr[animateIn](); + else tr.hide(); + } + }; + $('[data-show-trigger]', target).each(function () { + var name = $(this).attr('data-show-trigger'); + // The field exists only when creating/editing a row + if ($('#' + name).length) { + if (!triggers[name]) triggers[name] = []; + triggers[name].push($(this).attr('id')); + } + }); + for (var name in triggers) { + $('#' + name, target).change(show_if).keyup(show_if); + show_if.call($('#' + name, target)); + } + }, + component_handler: function (target) { + $('div[data-w2p_remote]', target).each(function () { + var remote, times, timeout, target; + var el = $(this); + remote = el.data('w2p_remote'); + times = el.data('w2p_times'); + timeout = el.data('w2p_timeout'); + target = el.attr('id'); + web2py.component(remote, target, timeout, times, $(this)); + }); + }, + a_handler: function (el, e) { + e.preventDefault(); + var method = el.data('w2p_method'); + var action = el.attr('href'); + var target = el.data('w2p_target'); + var confirm_message = el.data('w2p_confirm'); + + var pre_call = el.data('w2p_pre_call'); + if (!web2py.isUndefined(pre_call)) { + eval(pre_call); + } + if (confirm_message) { + if (confirm_message == 'default') { + confirm_message = !web2py.isUndefined(w2p_ajax_confirm_message) ? + w2p_ajax_confirm_message : 'Are you sure you want to delete this object?'; + } + if (!web2py.confirm(confirm_message)) { + web2py.stopEverything(e); + return; + } + } + if (web2py.isUndefined(target)) { + if (method == 'GET') { + web2py.ajax_page('get', action, [], '', el); + } else if (method == 'POST') { + web2py.ajax_page('post', action, [], '', el); + } + } else { + if (method == 'GET') { + web2py.ajax_page('get', action, [], target, el); + } else if (method == 'POST') { + web2py.ajax_page('post', action, [], target, el); + } + } + }, + a_handlers: function () { + var el = $(document); + el.on('click', 'a[data-w2p_method]', function (e) { + web2py.a_handler($(this), e); + }); + /* removal of element should happen only on success */ + el.on('ajax:success', 'a[data-w2p_method][data-w2p_remove]', function () { + var el = $(this); + var toremove = el.data('w2p_remove'); + if (!web2py.isUndefined(toremove)) { + toremove = el.closest(toremove); + if (!toremove.length) { + /*this enables removal of whatever selector if a closest is not found */ + toremove = $(toremove); + } + toremove.remove(); + } + }); + el.on('ajax:beforeSend', 'a[data-w2p_method][data-w2p_disable_with]', function () { + web2py.disableElement($(this)); + }); + /*re-enable click on completion*/ + el.on('ajax:complete', 'a[data-w2p_method][data-w2p_disable_with]', function () { + web2py.enableElement($(this)); + }); + }, + /* Disables form elements: + - Does not disable elements with 'data-w2p_disable' attribute + - Caches element value in 'w2p_enable_with' data store + - Replaces element text with value of 'data-w2p_disable_with' attribute + - Sets disabled property to true + */ + disableFormElements: function (form) { + form.find(web2py.disableSelector).each(function () { + var element = $(this), + method = element.is('button') ? 'html' : 'val'; + var disable_with = element.data('w2p_disable_with'); + var disable = element.data('w2p_disable'); + if (!web2py.isUndefined(disable)) { + return false; + } + if (!element.is(':file')) { // Altering file input values is not allowed. + if (web2py.isUndefined(disable_with)) { + element.data('w2p_disable_with', element[method]()); + } + if (web2py.isUndefined(element.data('w2p_enable_with'))) { + element.data('w2p_enable_with', element[method]()); + } + element[method](element.data('w2p_disable_with')); + } + element.prop('disabled', true); + }); + }, + + /* Re-enables disabled form elements: + - Replaces element text with cached value from 'w2p_enable_with' data store (created in `disableFormElements`) + - Sets disabled property to false + */ + enableFormElements: function (form) { + form.find(web2py.enableSelector).each(function () { + var element = $(this), + method = element.is('button') ? 'html' : 'val'; + if (element.data('w2p_enable_with')) { + element[method](element.data('w2p_enable_with')); + element.removeData('w2p_enable_with'); + } + element.prop('disabled', false); + }); + }, + form_handlers: function () { + var el = $(document); + el.on('ajax:beforeSend', 'form[data-w2p_target]', function () { + web2py.disableFormElements($(this)); + }); + el.on('ajax:complete', 'form[data-w2p_target]', function () { + web2py.enableFormElements($(this)); + }); + }, + /* Invalidate and force reload of a web2py component + */ + invalidate: function (target) { + $('div[data-w2p_remote]', target).each(function () { + var el = $('#' + $(this).attr('id')).get(0); + if (!web2py.isUndefined(el.timing)) { // Block triggering regular routines + clearInterval(el.timing); + } + }); + $.web2py.component_handler(target); + }, + main_hook: function () { + var flash = $('.w2p_flash'); + flash.hide(); + if (flash.html()) web2py.flash(flash.html()); + web2py.ajax_init(document); + web2py.event_handlers(); + web2py.a_handlers(); + web2py.form_handlers(); + } + }; + /*end of functions */ + /*main hook*/ + $(function () { + web2py.main_hook(); + }); + +})(jQuery); + +/* compatibility code - start */ +ajax = jQuery.web2py.ajax; +web2py_component = jQuery.web2py.component; +web2py_websocket = jQuery.web2py.web2py_websocket; +web2py_ajax_page = jQuery.web2py.ajax_page; +/*needed for IS_STRONG(entropy)*/ +web2py_validate_entropy = jQuery.web2py.validate_entropy; +/*needed for crud.search and SQLFORM.grid's search*/ +web2py_ajax_fields = jQuery.web2py.ajax_fields; +/*used for LOAD(ajax=False)*/ +web2py_trap_form = jQuery.web2py.trap_form; + +/*undocumented - rare*/ +popup = jQuery.web2py.popup; +collapse = jQuery.web2py.collapse; +fade = jQuery.web2py.fade; + +/* internals - shouldn't be needed +web2py_ajax_init = jQuery.web2py.ajax_init; +web2py_event_handlers = jQuery.web2py.event_handlers; +web2py_trap_link = jQuery.web2py.trap_link; +web2py_calc_entropy = jQuery.web2py.calc_entropy; +*/ +/* compatibility code - end*/ diff --git a/web2py/applications/examples/static/markmin.html b/web2py/applications/examples/static/markmin.html new file mode 100644 index 0000000..a3be74d --- /dev/null +++ b/web2py/applications/examples/static/markmin.html @@ -0,0 +1,96 @@ + + + + + +Markmin markup language + + +

Markmin markup language

About

This is a new markup language that we call markmin designed to produce high quality scientific papers and books and also put them online. We provide serializers for html, latex and pdf. It is implemented in the markmin2html function in the markmin2html.py.

Example of usage:

m = "Hello **world** [[link http://web2py.com]]"
+from markmin2html import markmin2html
+print markmin2html(m)
+from markmin2latex import markmin2latex
+print markmin2latex(m)
+from markmin2pdf import markmin2pdf # requires pdflatex
+print markmin2pdf(m)
+ +

Why?

We wanted a markup language with the following requirements:

  • less than 300 lines of functional code
  • easy to read
  • secure
  • support table, ul, ol, code
  • support html5 video and audio elements (html serialization only)
  • can align images and resize them
  • can specify class for tables and code elements
  • can add anchors
  • does not use _ for markup (since it creates odd behavior)
  • automatically links urls
  • fast
  • easy to extend
  • supports latex and pdf including references
  • allows to describe the markup in the markup (this document is generated from markmin syntax)

(results depend on text but in average for text ~100K markmin is 30% faster than markdown, for text ~10K it is 10x faster)

The web2py book published by lulu, for example, was entirely generated with markmin2pdf from the online web2py wiki

Download

markmin2html.py and markmin2latex.py are single files and have no web2py dependence. Their license is BSD.

Examples

Bold, italic, code and links

SOURCEOUTPUT
# titletitle
## sectionsection
### subsectionsubsection
**bold**bold
''italic''italic
~~strikeout~~strikeout
``verbatim``verbatim
``color with **bold**``:redcolor with bold
``many colors``:color[blue:#ffff00]many colors
http://google.comhttp://google.com
[[**click** me #myanchor]]click me
[[click me [extra info] #myanchor popup]]click me

More on links

The format is always [[title link]] or [[title [extra] link]]. Notice you can nest bold, italic, strikeout and code inside the link title.

Anchors

You can place an anchor anywhere in the text using the syntax [[name]] where name is the name of the anchor. You can then link the anchor with link, i.e. [[link #myanchor]] or link with an extra info, i.e. [[link with an extra info [extra info] #myanchor]].

Images

alt-string for the image This paragraph has an image aligned to the right with a width of 200px. Its is placed using the code

[[alt-string for the image [the image title] http://www.web2py.com/examples/static/web2py_logo.png right 200px]].

Unordered Lists

- Dog
+- Cat
+- Mouse

is rendered as

  • Dog
  • Cat
  • Mouse

Two new lines between items break the list in two lists.

Ordered Lists

+ Dog
++ Cat
++ Mouse

is rendered as

  1. Dog
  2. Cat
  3. Mouse

Multilevel Lists

+ Dogs
+ -- red
+ -- brown
+ -- black
++ Cats
+ -- fluffy
+ -- smooth
+ -- bald
++ Mice
+ -- small
+ -- big
+ -- huge

is rendered as

  1. Dogs
    • red
    • brown
    • black
  2. Cats
    • fluffy
    • smooth
    • bald
  3. Mice
    • small
    • big
    • huge

Tables (with optional header and/or footer)

Something like this

-----------------
+**A**|**B**|**C**
+=================
+  0  |  0  |  X
+  0  |  X  |  0
+  X  |  0  |  0
+=================
+**D**|**F**|**G**
+-----------------:abc[id]
is a table and is rendered as
ABC
00X
0X0
X00
DFG
Four or more dashes delimit the table and | separates the columns. The :abc, :id[abc_1] or :abc[abc_1] at the end sets the class and/or id for the table and it is optional.

Blockquote

A table with a single cell is rendered as a blockquote:

Hello world

Blockquote can contain headers, paragraphs, lists and tables:

-----
+  This is a paragraph in a blockquote
+
+  + item 1
+  + item 2
+  -- item 2.1
+  -- item 2.2
+  + item 3
+
+  ---------
+  0 | 0 | X
+  0 | X | 0
+  X | 0 | 0
+  ---------:tableclass1
+-----

is rendered as:

This is a paragraph in a blockquote
  1. item 1
  2. item 2
    • item 2.1
    • item 2.2
  3. item 3
00X
0X0
X00

Code, <code>, escaping and extra stuff

def test():
+    return "this is Python code"

Optionally a ` inside a ``...`` block can be inserted escaped with !`!.

NOTE: You can escape markmin constructions ('',``,**,~~,[,{,]},$,@) with '\' character: so \`\` can replace !`!`! escape string

The :python after the markup is also optional. If present, by default, it is used to set the class of the <code> block. The behavior can be overridden by passing an argument extra to the render function. For example:

markmin2html("``aaa``:custom",
+             extra=dict(custom=lambda text: 'x'+text+'x'))

generates

'xaaax'

(the ``...``:custom block is rendered by the custom=lambda function passed to render).

Html5 support

Markmin also supports the <video> and <audio> html5 tags using the notation:

[[message link video]]
+[[message link audio]]
+
+[[message [title] link video]]
+[[message [title] link audio]]
where message will be shown in brousers without HTML5 video/audio tags support.

Latex and other extensions

Formulas can be embedded into HTML with $$formula$$. You can use Google charts to render the formula:

LATEX = '<img src="http://chart.apis.google.com/chart?cht=tx&chl=%s" />'
+markmin2html(text,{'latex':lambda code: LATEX % code.replace('"','\"')})

Code with syntax highlighting

This requires a syntax highlighting tool, such as the web2py CODE helper.

extra={'code_cpp':lambda text: CODE(text,language='cpp').xml(),
+       'code_java':lambda text: CODE(text,language='java').xml(),
+       'code_python':lambda text: CODE(text,language='python').xml(),
+       'code_html':lambda text: CODE(text,language='html').xml()}
or simple:
extra={'code':lambda text,lang='python': CODE(text,language=lang).xml()}
markmin2html(text,extra=extra)

Code can now be marked up as in this example:

``
+<html><body>example</body></html>
+``:code_html
OR
``
+<html><body>example</body></html>
+``:code[html]

Citations and References

Citations are treated as internal links in html and proper citations in latex if there is a final section called "References". Items like

- [[key]] value

in the References will be translated into Latex

\bibitem{key} value

Here is an example of usage:

As shown in Ref.``mdipierro``:cite
+
+

This is a test block with new features:

This is a blockquote with a list with tables in it:

This is a paragraph before list. You can continue paragraph on the next lines.
This is an ordered list with tables:
  1. Item 1
  2. Item 2
  3. aabbcc
    112233
  4. Item 4
    T1T2t3
    aaabbbccc
    dddfffggg
    12305.0

This this a new paragraph with a table. Table has header, footer, sections, odd and even rows:

Title 1Title 2Title 3
data 1data 22.00
data 3data4(long)23.00
data 533.50
New sectionNew data5.00
data 1data2(long)100.45
data 312.50
data 4data 5.33
data 6data7(long)8.01
data 8514
Total:9 items698,79

Multilevel lists

Now lists can be multilevel:

  1. Ordered item 1 on level 1. You can continue item text on next strings
    1. Ordered item 1 of sublevel 2 with a paragraph (paragraph can start with point after plus or minus characters, e.g. ++. or --.)

    2. This is another item. But with 3 paragraphs, blockquote and sublists:

      This is the second paragraph in the item. You can add paragraphs to an item, using point notation, where first characters in the string are sequence of points with space between them and another string. For example, this paragraph (in sublevel 2) starts with two points:

      .. This is the second paragraph...

      this is a blockquote in a list

      You can use blockquote with headers, paragraphs, tables and lists in it:
      Tables can have or have not header and footer. This table is defined without any header and footer in it:
      redfox0
      bluedolphin1000
      greenleaf10000

      This is yet another paragraph in the item.

      • This is an item of unordered list (sublevel 3)
      • This is the second item of the unordered list (sublevel 3)
            1. This is a single item of ordered list in sublevel 6

          and this is a paragraph in sublevel 4

      • This is a new item with paragraph in sublevel 3.

        1. Start ordered list in sublevel 4 with code block:
          line 1
          +  line 2
          +     line 3
        2. Yet another item with code block:

            line 1
          +line 2
          +  line 3
          This item finishes with this paragraph.

        Item in sublevel 3 can be continued with paragraphs.

          this is another
        +code block
        +    in the
        +  sublevel 3 item
      1. The last item in sublevel 3

      This is a continuous paragraph for item 2 in sublevel 2. You can use such structure to create difficult structured documents.

    3. item 3 in sublevel 2
    • item 1 in sublevel 2 (new unordered list)
    • item 2 in sublevel 2
    • item 3 in sublevel 2
    1. item 1 in sublevel 2 (new ordered list)
    2. item 2 in sublevel 2
    3. item 3 in sublevle 2
  2. item 2 in level 1
  3. item 3 in level 1
  • new unordered list (item 1 in level 1)
  • level 2 in level 1
  • level 3 in level 1
  • level 4 in level 1

This is the last section of the test

Single paragraph with '----' in it will be turned into separator:


And this is the last paragraph in the test. Be happy!

+ +## References + +- [[mdipierro]] web2py Manual, 5th Edition, lulu.com

Caveats

<ul/>, <ol/>, <code/>, <table/>, <blockquote/>, <h1/>, ..., <h6/> do not have <p>...</p> around them.

+ + diff --git a/web2py/applications/examples/static/robots.txt b/web2py/applications/examples/static/robots.txt new file mode 100644 index 0000000..62bd594 --- /dev/null +++ b/web2py/applications/examples/static/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Disallow: /examples/global/ +Disallow: /welcome +Disallow: /admin diff --git a/web2py/applications/examples/static/title.png b/web2py/applications/examples/static/title.png new file mode 100644 index 0000000000000000000000000000000000000000..6b0658ab44ef56b9a3e96d469142d93c67bfff06 GIT binary patch literal 10937 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/web2py_cheatsheet.pdf b/web2py/applications/examples/static/web2py_cheatsheet.pdf new file mode 100644 index 0000000000000000000000000000000000000000..74b44ad5271871bfd4f9988b829ce6f151ea6aff GIT binary patch literal 126651 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 O2Md6jT1-J4@IL@#rp$~0 literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/web2py_contributor_agreement.pdf b/web2py/applications/examples/static/web2py_contributor_agreement.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c7cfe042ba930db99298ed61a6f20f619034cdb3 GIT binary patch literal 38724 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 I)B9S#0iv21V*mgE literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/static/web2py_logo.png b/web2py/applications/examples/static/web2py_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..96a472f78f2ae79a73fa06c93457ab654da2d98e GIT binary patch literal 9966 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 literal 0 HcmV?d00001 diff --git a/web2py/applications/examples/views/ajax_examples/fade.html b/web2py/applications/examples/views/ajax_examples/fade.html new file mode 100644 index 0000000..0b93e28 --- /dev/null +++ b/web2py/applications/examples/views/ajax_examples/fade.html @@ -0,0 +1,8 @@ +{{extend 'layout.html'}} + +

+ + +
+ +
{{='Hello World '*100}}
diff --git a/web2py/applications/examples/views/ajax_examples/index.html b/web2py/applications/examples/views/ajax_examples/index.html new file mode 100644 index 0000000..46b1997 --- /dev/null +++ b/web2py/applications/examples/views/ajax_examples/index.html @@ -0,0 +1,13 @@ +{{extend 'layout.html'}} + +

Type something and press the button. + The last 10 entries will appear sorted in a table below.

+ +
+ + +
+
+
+ diff --git a/web2py/applications/examples/views/appadmin.html b/web2py/applications/examples/views/appadmin.html new file mode 100644 index 0000000..2ce4262 --- /dev/null +++ b/web2py/applications/examples/views/appadmin.html @@ -0,0 +1,279 @@ +{{extend 'layout.html'}} + + +
+
+ +{{if request.function=='index':}} +

{{=T("Available Databases and Tables")}}

+ {{if not databases:}}{{=T("No databases in this application")}}{{pass}} + +
+
+ + {{for db in sorted(databases):}} + {{for table in databases[db].tables:}} + {{qry='%s.%s.id>0'%(db,table)}} + {{tbl=databases[db][table]}} + {{if hasattr(tbl,'_primarykey'):}} + {{if tbl._primarykey:}} + {{firstkey=tbl[tbl._primarykey[0]]}} + {{if firstkey.type in ['string','text']:}} + {{qry='%s.%s.%s!=""'%(db,table,firstkey.name)}} + {{else:}} + {{qry='%s.%s.%s>0'%(db,table,firstkey.name)}} + {{pass}} + {{else:}} + {{qry=''}} + {{pass}} + {{pass}} + + + + + {{pass}} + {{pass}} +
+ » {{=A("%s.%s" % (db,table),_href=URL('select',args=[db],vars=dict(query=qry)))}} + + {{=A(str(T('New Record')),_href=URL('insert',args=[db,table]),_class="btn btn-primary")}} +
+
+
+ {{=LOAD('appadmin', 'hooks', ajax=True)}} +
+
+{{elif request.function=='select':}} +

{{=XML(str(T("Database %s select"))%A(request.args[0],_href=URL('index'))) }} +

+ {{if tb:}} +

{{=T('Traceback')}}

+
+    {{=tb}}
+  
+ {{pass}} + {{if table:}} + {{=A(str(T('New Record')),_href=URL('insert',args=[request.args[0],table]),_class="btn btn-primary", _role="button")}}

+
+

{{=T("Rows in Table")}}


+ {{else:}} +

{{=T("Rows selected")}}


+ {{pass}} + {{=form}} +

{{=T('The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.')}}
+ {{=T('Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.')}}
+ {{=T('"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN')}}

+

+

{{=T("%s selected", nrows)}}

+ {{if start>0:}}{{=A(T('previous %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start-step)),_class="btn btn-primary")}}{{pass}} + {{if stop + {{linkto = lambda f, t, r: URL('update', args=[request.args[0], r, f]) if f else "#"}} + {{upload=URL('download',args=request.args[0])}} + {{=SQLTABLE(rows,linkto,upload,orderby=True,_class='table table-striped table-bordered sortable')}} +
+ {{pass}} +

+
+

{{=T("Import/Export")}}


+ {{=T("export as csv file")}} + {{=formcsv or ''}} + +{{elif request.function=='insert':}} +

{{=T("Database")}} {{=A(request.args[0],_href=URL('index'))}} + {{if hasattr(table,'_primarykey'):}} + {{fieldname=table._primarykey[0]}} + {{dbname=request.args[0]}} + {{tablename=request.args[1]}} + {{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}} + {{=T("Table")}} {{=A(tablename,_href=URL('select',args=dbname,vars=dict(query='%s.%s.%s%s'%(dbname,tablename,fieldname,cond))))}} + {{else:}} + {{=T("Table")}} {{=A(request.args[1],_href=URL('select',args=request.args[0],vars=dict(query='%s.%s.id>0'%tuple(request.args[:2]))))}} + {{pass}} +

+

{{=T("New Record")}}


+ {{=form}} +{{elif request.function=='update':}} +

{{=T("Database")}} {{=A(request.args[0],_href=URL('index'))}} + {{if hasattr(table,'_primarykey'):}} + {{fieldname=request.vars.keys()[0]}} + {{dbname=request.args[0]}} + {{tablename=request.args[1]}} + {{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}} + {{=T("Table")}} {{=A(tablename,_href=URL('select',args=dbname,vars=dict(query='%s.%s.%s%s'%(dbname,tablename,fieldname,cond))))}} + {{=T("Record")}} {{=A('%s=%s'%request.vars.items()[0],_href=URL('update',args=request.args[:2],vars=request.vars))}} + {{else:}} + {{=T("Table")}} {{=A(request.args[1],_href=URL('select',args=request.args[0],vars=dict(query='%s.%s.id>0'%tuple(request.args[:2]))))}} + {{=T("Record id")}} {{=A(request.args[2],_href=URL('update',args=request.args[:3]))}} + {{pass}} +

+

{{=T("Edit current record")}}



{{=form}} + +{{elif request.function=='state':}} +

{{=T("Internal State")}}

+

{{=T("Current request")}}

+ {{=BEAUTIFY(request)}} +

{{=T("Current response")}}

+ {{=BEAUTIFY(response)}} +

{{=T("Current session")}}

+ {{=BEAUTIFY(session)}} + + +{{elif request.function == 'ccache':}} +

{{T("Cache")}}

+
+ +
+

{{T("Statistics")}}

+
+ +
+

{{=T("Overview")}}

+

{{=T.M("Number of entries: **%s**", total['entries'])}}

+ {{if total['entries'] > 0:}} +

{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})", + dict( ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}} +

+

+ {{=T("Size of cache:")}} + {{if object_stats:}} + {{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict(items=total['objects'], bytes=total['bytes']))}} + {{if total['bytes'] > 524287:}} + {{=T.M("(**%.0d MB**)", total['bytes'] / 1048576)}} + {{pass}} + {{else:}} + {{=T.M("**not available** (requires the Python [[Pympler https://pypi.python.org/pypi/Pympler popup]] library)")}} + {{pass}} +

+

+ {{=T.M("Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.", + dict(hours=total['oldest'][0], min=total['oldest'][1], sec=total['oldest'][2]))}} +

+ {{=BUTTON(T('Cache Keys'), _onclick='jQuery("#all_keys").toggle().toggleClass( "w2p_hidden" );')}} +
+ {{=total['keys']}} +
+
+ {{pass}} + +

{{=T("RAM")}}

+

{{=T.M("Number of entries: **%s**", ram['entries'])}}

+ {{if ram['entries'] > 0:}} +

{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})", + dict( ratio=ram['ratio'], hits=ram['hits'], misses=ram['misses']))}} +

+

+ {{=T("Size of cache:")}} + {{if object_stats:}} + {{=T.M("**%(items)s** items, **%(bytes)s** %%{byte(bytes)}", dict(items=ram['objects'], bytes=ram['bytes']))}} + {{if ram['bytes'] > 524287:}} + {{=T.M("(**%.0d MB**)", ram['bytes'] / 10485576)}} + {{pass}} + {{else:}} + {{=T.M("``**not available**``:red (requires the Python [[Pympler https://pypi.python.org/pypi/Pympler popup]] library)")}} + {{pass}} +

+

+ {{=T.M("RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.", + dict(hours=ram['oldest'][0], min=ram['oldest'][1], sec=ram['oldest'][2]))}} +

+ {{=BUTTON(T('RAM Cache Keys'), _onclick='jQuery("#ram_keys").toggle().toggleClass( "w2p_hidden" );')}} +
+ {{=ram['keys']}} +
+
+ {{pass}} + +

{{=T("DISK")}}

+

{{=T.M("Number of entries: **%s**", disk['entries'])}}

+ {{if disk['entries'] > 0:}} +

+ {{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})", + dict(ratio=disk['ratio'], hits=disk['hits'], misses=disk['misses']))}} +

+

+ {{=T("Size of cache:")}} + {{if object_stats:}} + {{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict( items=disk['objects'], bytes=disk['bytes']))}} + {{if disk['bytes'] > 524287:}} + {{=T.M("(**%.0d MB**)", disk['bytes'] / 1048576)}} + {{pass}} + {{else:}} + {{=T.M("``**not available**``:red (requires the Python [[Pympler https://pypi.python.org/pypi/Pympler popup]] library)")}} + {{pass}} +

+

+ {{=T.M("DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.", + dict(hours=disk['oldest'][0], min=disk['oldest'][1], sec=disk['oldest'][2]))}} +

+ {{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle().toggleClass( "w2p_hidden" );')}} +
+ {{=disk['keys']}} +
+
+ {{pass}} +
+ +
+

{{=T("Manage Cache")}}

+
+ +
+

+ {{=form}} +

+
+
+
+{{pass}} + +{{if request.function=='d3_graph_model':}} +

{{=T("Graph Model")}}

+ {{if not databases:}} + {{=T("No databases in this application")}} + {{else:}} +
+ + + {{pass}} +{{pass}} + +{{if request.function == 'manage':}} +

{{=heading}}

+ + +
+ {{for k, tablename in enumerate(tablenames):}} +
+ {{=LOAD(f='manage.load', args=[request.args(0), k], ajax=True)}} +
+ {{pass}} +
+{{pass}} + +
+ diff --git a/web2py/applications/examples/views/cache_examples/generic.html b/web2py/applications/examples/views/cache_examples/generic.html new file mode 100644 index 0000000..22b41e7 --- /dev/null +++ b/web2py/applications/examples/views/cache_examples/generic.html @@ -0,0 +1,3 @@ +{{extend 'layout.html'}} +

Cache Examples

+{{=BEAUTIFY(response._vars)}} diff --git a/web2py/applications/examples/views/database_examples/buy.html b/web2py/applications/examples/views/database_examples/buy.html new file mode 100644 index 0000000..bd07ad5 --- /dev/null +++ b/web2py/applications/examples/views/database_examples/buy.html @@ -0,0 +1,7 @@ +{{extend 'layout.html'}} +

Purchase form

+ {{=form}} + [ {{=A('delete purchases',_href=URL('delete_purchased'))}} ] +

Current purchases (SQL JOIN!)

+

{{=records}}

+ diff --git a/web2py/applications/examples/views/database_examples/register_dog.html b/web2py/applications/examples/views/database_examples/register_dog.html new file mode 100644 index 0000000..fbb3aeb --- /dev/null +++ b/web2py/applications/examples/views/database_examples/register_dog.html @@ -0,0 +1,7 @@ +{{extend 'layout.html'}} + +

Dog registration form

+{{=form}} +

Current dogs

+{{=records}} + diff --git a/web2py/applications/examples/views/database_examples/register_person.html b/web2py/applications/examples/views/database_examples/register_person.html new file mode 100644 index 0000000..f5cb93f --- /dev/null +++ b/web2py/applications/examples/views/database_examples/register_person.html @@ -0,0 +1,7 @@ +{{extend 'layout.html'}} + +

User registration form

+{{=form}} +

Current users

+{{=records}} + diff --git a/web2py/applications/examples/views/database_examples/register_product.html b/web2py/applications/examples/views/database_examples/register_product.html new file mode 100644 index 0000000..91f245e --- /dev/null +++ b/web2py/applications/examples/views/database_examples/register_product.html @@ -0,0 +1,7 @@ +{{extend 'layout.html'}} + +

Product registration form

+{{=form}} +

Current products

+{{=records}} + diff --git a/web2py/applications/examples/views/default/changelog.html b/web2py/applications/examples/views/default/changelog.html new file mode 100644 index 0000000..b974b8a --- /dev/null +++ b/web2py/applications/examples/views/default/changelog.html @@ -0,0 +1,6 @@ +{{extend 'layout.html'}} + +
+ {{=changelog}} +
+ diff --git a/web2py/applications/examples/views/default/documentation.html b/web2py/applications/examples/views/default/documentation.html new file mode 100644 index 0000000..d29ab1a --- /dev/null +++ b/web2py/applications/examples/views/default/documentation.html @@ -0,0 +1,14 @@ +{{extend 'layout.html'}} + +
+ {{=get_content('main')}} +
+ +
+ {{=get_content('official')}} + {{=get_content('community')}} + {{=get_content('more')}} +
+ + + diff --git a/web2py/applications/examples/views/default/download.html b/web2py/applications/examples/views/default/download.html new file mode 100644 index 0000000..c1ecdec --- /dev/null +++ b/web2py/applications/examples/views/default/download.html @@ -0,0 +1,121 @@ +{{response.files.append(URL('static','css/artwork.css'))}} +{{extend 'layout.html'}} +{{import os}} +{{version = request.env.web2py_version}} + +

web2pyTM Download

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
For Normal UsersFor TestersFor Developers
+ For Windows + + For Windows + + Git Repository +
+ For Mac + + For Mac +
+ Source Code + + Source Code + + Source code docs +
+ Manual + + Change Log + + Report a Bug +
+
+ +

+ The source code version works on all supported platforms, including Linux, but it requires Python 2.6, or 2.7 (recommended). + It runs on Windows and most Unix systems, including Linux and BSD. +

+ +

Instructions

+

After download, unzip it and click on web2py.exe (windows) or web2py.app (osx). + To run from source, type:

+{{=CODE("python2.7 web2py.py", language=None, counter='>', _class='boxCode')}} +

or for more info type:

+{{=CODE("python2.7 web2py.py -h", language=None, counter='>', _class='boxCode')}} + + +

Caveats

+

After installation, every time you run it, web2py asks you to choose a password. This password is your administrative password. If the password is left blank, the administrative interface is disabled. The administrative interface /admin/default/index is only accessible via localhost and always requires a password.

+

Any url /a/b/c maps into a call to application a, controller b.py and function c in that controller.

+

You are strongly advised to also use Apache with mod_proxy or mod_wsgi to access applications in the framework. This allows better security and concurrency.

+ +

License

+

Web2py code is released under LGPLv3 License. This license does not extend to third party libraries distributed with web2py (which can be MIT, BSD or Apache type licenses) nor does it extend to applications built with web2py (under the terms of the LGPL.

+

Applications built with web2py can be released under any license the author wishes as long as they do not contain web2py code. They can link unmodified web2py libraries and they can be distributed with official web2py binaries. In particular web2py applications can be distributed in closed source. The admin interface provides a button to byte-code compile.

+

It is fine to distribute web2py (source or compiled) with your applications as long as you make it clear in the license where your application ends and web2py starts.

+

web2py is copyrighted by Massimo Di Pierro. The web2py trademark is owned by Massimo Di Pierro.

+read more + +

Artwork

+
+ + + +
+

Stickers

+
+ + + + + + + + +
+

+

+ Download WEB2PY artwork pack in editable .png format +

+

+ Logo, Stickers and Layout developed by José V. Sousa and Bruno Rocha (at Blouweb) All rights reserved by Massimo Di Pierro © {{=request.now.year}} +

+

+ Favicon and HTML5 compatibility by Martin Mulone +

+

+ Icon set made by Christian Burprich licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 License +

+ diff --git a/web2py/applications/examples/views/default/examples.html b/web2py/applications/examples/views/default/examples.html new file mode 100644 index 0000000..1dc02a4 --- /dev/null +++ b/web2py/applications/examples/views/default/examples.html @@ -0,0 +1,665 @@ +{{extend 'layout.html'}} +{{import os}} + +
+

web2pyTM Examples

+ +
+ +

Simple Examples

+ +

Here are some working and complete examples that explain the basic syntax of the framework.
+ You can click on the web2py keywords (in the highlighted code!) to get documentation.

+ +

Example {{c=1}}{{=c}}{{c+=1}}

In controller: simple_examples.py + {{=CODE(""" +def hello1(): + return "Hello World" + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} + +

If the controller function returns a string, that is the body of the rendered page.
Try it here: hello1

+ +

Example {{=c}}{{c+=1}}

In controller: simple_examples.py + {{=CODE(""" +def hello2(): + return T("Hello World") + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} + +

The function T() marks strings that need to be translated. Translation dictionaries can be created at /admin/default/design
Try it here: hello2

+ +

Example {{=c}}{{c+=1}}

In controller: simple_examples.py + {{=CODE(""" +def hello3(): + return dict(message=T("Hello World")) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} + + and view: simple_examples/hello3.html + {{=CODE(open(os.path.join(request.folder,'views/simple_examples/hello3.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

If you return a dictionary, the variables defined in the dictionary are visible to the view (template). +
Try it here: hello3

+ +

Actions can also be be rendered in other formats like JSON, hello3.json, and XML, hello3.xml

+ +

Example {{=c}}{{c+=1}}

In controller: simple_examples.py + {{=CODE(""" +def hello4(): + response.view='simple_examples/hello3.html' + return dict(message=T("Hello World")) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

You can change the view, but the default is /[controller]/[function].html. If the default is not found web2py tries to render the page using the generic.html view. +
Try it here: hello4

+ +

Example {{=c}}{{c+=1}}

In controller: simple_examples.py + {{=CODE(""" +def hello5(): + return HTML(BODY(H1(T('Hello World'),_style="color: red;"))).xml() # .xml to serialize + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

You can also generate HTML using helper objects HTML, BODY, H1, etc. Each of these tags is a class and the views know how to render the corresponding objects. The method .xml() serializes them and produces html/xml code for the page. + Each tag, DIV for example, takes three types of arguments:

+
    +
  • unnamed arguments, they correspond to nested tags
  • +
  • named arguments and name starts with '_'. These are mapped blindly into tag attributes and the '_' is removed. attributes without value like "READONLY" can be created with the argument "_readonly=ON".
  • +
  • named arguments and name does not start with '_'. They have a special meaning. See "value=" for INPUT, TEXTAREA, SELECT tags later. +
+

Try it here: hello5

+ +

Example {{=c}}{{c+=1}}

In controller: simple_examples.py + {{=CODE(""" +def hello6(): + response.flash=T("Hello World in a flash!") + return dict(message=T("Hello World")) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} + +

response.flash allows you to flash a message to the user when the page is returned. Use session.flash instead of response.flash to display a message after redirection. With default layout, you can click on the flash to make it disappear. +
Try it here: hello6

+ +

Example {{=c}}{{c+=1}}

In controller: simple_examples.py + {{=CODE(""" +def status(): + return dict(toobar=response.toolbar()) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

Here we are showing the request, session and response objects using the generic.html template. + +

Example {{=c}}{{c+=1}}

In controller: simple_examples.py + {{=CODE(""" +def redirectme(): + redirect(URL('hello3')) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

You can do redirect. +
Try it here: redirectme

+ +

Example {{=c}}{{c+=1}}

In controller: simple_examples.py + {{=CODE(""" +def raisehttp(): + raise HTTP(400,"internal error") + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

You can raise HTTP exceptions to return an error page. +
Try it here: raisehttp

+ +

Example {{=c}}{{c+=1}}

In controller: simple_examples.py + {{=CODE(""" +def raiseexception(): + 1/0 + return 'oops' + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

If an exception occurs (other than HTTP) a ticket is generated and the event is logged for the administrator. These tickets and logs can be accessed, reviewed and deleted at any later time. + +

Example {{=c}}{{c+=1}}

In controller: simple_examples.py + {{=CODE(""" +def servejs(): + import gluon.contenttype + response.headers['Content-Type']=gluon.contenttype.contenttype('.js') + return 'alert("This is a Javascript document, it is not supposed to run!");' + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

You can serve other than HTML pages by changing the contenttype via the response.headers. The gluon.contenttype module can help you figure the type of the file to be served. NOTICE: this is not necessary for static files unless you want to require authorization. +
Try it here: servejs

+ +

Example {{=c}}{{c+=1}}

In controller: simple_examples.py + {{=CODE(""" + def makejson(): + return response.json(['foo', {'bar': ('baz', None, 1.0, 2)}]) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

If you are into Ajax, JSON is fully supported in web2py. Providing a fast and easy way to serve asynchronous content to your Ajax page. Response.json can serialize most Python types into JSON. +
Try it here: makejson

+ +

New in web2py 1.63: Any normal action returning a dict is automatically serialized in JSON if '.json' is appended to the URL.

+ +

Example {{=c}}{{c+=1}}

In controller: simple_examples.py + {{=CODE(""" +def makertf(): + import gluon.contrib.pyrtf as q + doc=q.Document() + section=q.Section() + doc.Sections.append(section) + section.append('Section Title') + section.append('web2py is great. '*100) + response.headers['Content-Type']='text/rtf' + return q.dumps(doc) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

web2py also includes gluon.contrib.pyrtf, developed by Simon Cusack and revised by Grant Edwards. This module allows you to generate Rich Text Format documents including colored formatted text and pictures.
Try it here: makertf

+ +

Example {{=c}}{{c+=1}}

In controller: simple_examples.py + {{=CODE(""" +def rss_aggregator(): + import datetime + import gluon.contrib.rss2 as rss2 + import gluon.contrib.feedparser as feedparser + d = feedparser.parse("http://rss.slashdot.org/Slashdot/slashdot/to") + + rss = rss2.RSS2(title=d.channel.title, + link = d.channel.link, + description = d.channel.description, + lastBuildDate = datetime.datetime.now(), + items = [ + rss2.RSSItem( + title = entry.title, + link = entry.link, + description = entry.description, + # guid = rss2.Guid('unkown'), + pubDate = datetime.datetime.now()) for entry in d.entries] + ) + response.headers['Content-Type']='application/rss+xml' + return rss2.dumps(rss) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

web2py includes gluon.contrib.rss2, developed by Dalke Scientific Software, which generates RSS2 feeds, and + gluon.contrib.feedparser, developed by Mark Pilgrim, which collects RSS and ATOM feeds. The above controller collects a slashdot feed and makes new one. +
Try it here: rss_aggregator

+ + +

Example {{=c}}{{c+=1}}

In controller: simple_examples.py + {{=CODE(""" +def ajaxwiki(): + form=FORM(TEXTAREA(_id='text',_name='text'), + INPUT(_type='button',_value='markmin', + _onclick="ajax('ajaxwiki_onclick',['text'],'html')")) + return dict(form=form,html=DIV(_id='html')) + +def ajaxwiki_onclick(): + return MARKMIN(request.vars.text).xml() + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

The markmin wiki markup is described here. + web2py also includes gluon.contrib.markdown.WIKI helper (markdown2) which converts WIKI markup to HTML following this syntax. In this example we added a fancy ajax effect.
Try it here: ajaxwiki

+ +

Session Examples

+ + +

Example {{=c}}{{c+=1}}

In controller: session_examples.py + {{=CODE(""" +def counter(): + session.counter = (session.counter or 0) + 1 + return dict(counter=session.counter) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}and view: session_examples/counter.html + {{=CODE(open(os.path.join(request.folder,'views/session_examples/counter.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

Click to count. The session.counter is persistent for this user and application. Every application within the system has its own separate session management. +
Try it here: counter

+ +

Template Examples

+ + +

Example {{=c}}{{c+=1}}

In controller: template_examples.py + {{=CODE(""" +def variables(): + return dict(a=10, b=20) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}and view: template_examples/variables.html + {{=CODE(open(os.path.join(request.folder,'views/template_examples/variables.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

A view (also known as template) is just an HTML file with {{...}} tags. You can put ANY python code into the tags, no need to indent but you must use pass to close blocks. The view is transformed into a python code and then executed. {{=a}} prints a.xml() or escape(str(a)). +
Try it here: variables

+ +

Example {{=c}}{{c+=1}}

In controller: template_examples.py + {{=CODE(""" +def test_for(): + return dict() + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}and view: template_examples/test_for.html + {{=CODE(open(os.path.join(request.folder,'views/template_examples/test_for.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

You can do for and while loops. +
Try it here: test_for

+ +

Example {{=c}}{{c+=1}}

In controller: template_examples.py + {{=CODE(""" +def test_if(): + return dict() + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}and view: template_examples/test_if.html + {{=CODE(open(os.path.join(request.folder,'views/template_examples/test_if.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

You can do if, elif, else. +
Try it here: test_if

+ +

Example {{=c}}{{c+=1}}

In controller: template_examples.py + {{=CODE(""" +def test_try(): + return dict() + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}and view: template_examples/test_try.html + {{=CODE(open(os.path.join(request.folder,'views/template_examples/test_try.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

You can do try, except, finally. +
Try it here: test_try

+ +

Example {{=c}}{{c+=1}}

In controller: template_examples.py + {{=CODE(""" +def test_def(): + return dict() + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}and view: template_examples/test_def.html + {{=CODE(open(os.path.join(request.folder,'views/template_examples/test_def.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

You can write functions in HTML too. +
Try it here: test_def

+ +

Example {{=c}}{{c+=1}}

In controller: template_examples.py + {{=CODE(""" +def escape(): + return dict(message='

text is escaped

') + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}and view: template_examples/escape.html + {{=CODE(open(os.path.join(request.folder,'views/template_examples/escape.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

The argument of {{=...}} is always escaped unless it is an object with a .xml() method such as link, A(...), a FORM(...), a XML(...) block, etc. +
Try it here: escape

+ +

Example {{=c}}{{c+=1}}

In controller: template_examples.py + {{=CODE(""" +def xml(): + return dict(message=XML('

text is not escaped

')) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}and view: template_examples/xml.html + {{=CODE(open(os.path.join(request.folder,'views/template_examples/xml.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

If you do not want to escape the argument of {{=...}} mark it as XML. +
Try it here: xml

+ +

Example {{=c}}{{c+=1}}

In controller: template_examples.py + {{=CODE(""" +def beautify(): + dict(message=BEAUTIFY(dict(a=1,b=[2,3,dict(hello='world')]))) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}and view: template_examples/beautify.html + {{=CODE(open(os.path.join(request.folder,'views/template_examples/beautify.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

You can use BEAUTIFY to turn lists and dictionaries into organized HTML. +
Try it here: beautify

+ +

Layout Examples

+ + +

Example {{=c}}{{c+=1}}

In controller: layout_examples.py + {{=CODE(""" +def civilized(): + response.menu=[['civilized',True,URL('civilized')], + ['slick',False,URL('slick')], + ['basic',False,URL('basic')]] + response.flash='you clicked on civilized' + return dict(message="you clicked on civilized") + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}and view: layout_examples/civilized.html + {{=CODE(open(os.path.join(request.folder,'views/layout_examples/civilized.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

You can specify the layout file at the top of your view. civilized Layout file is a view that somewhere in the body contains {{include}}. +
Try it here: civilized

+ +

Example {{=c}}{{c+=1}}

In controller: layout_examples.py + {{=CODE(""" +def slick(): + response.menu = [['civilized',False,URL('civilized')], + ['slick',True,URL('slick')], + ['basic',False,URL('basic')]] + response.flash = 'you clicked on slick' + return dict(message="you clicked on slick") + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}and view: layout_examples/slick.html + {{=CODE(open(os.path.join(request.folder,'views/layout_examples/slick.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

Same here, but using a different template.
Try it here: slick

+ +

Example {{=c}}{{c+=1}}

In controller: layout_examples.py + {{=CODE(""" +def basic(): + response.menu=[['civilized',False,URL('civilized')], + ['slick',False,URL('slick')], + ['basic',True,URL('basic')]] + response.flash='you clicked on basic' + return dict(message="you clicked on basic") + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}and view: layout_examples/basic.html + {{=CODE(open(os.path.join(request.folder,'views/layout_examples/basic.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

'layout.html' is the default template, every application has a copy of it. +
Try it here: basic

+ +

Form Examples

+ + +

Example {{=c}}{{c+=1}}

In controller: form_examples.py + {{=CODE(""" +def form(): + form=FORM(TABLE(TR("Your name:",INPUT(_type="text",_name="name",requires=IS_NOT_EMPTY())), + TR("Your email:",INPUT(_type="text",_name="email",requires=IS_EMAIL())), + TR("Admin",INPUT(_type="checkbox",_name="admin")), + TR("Sure?",SELECT('yes','no',_name="sure",requires=IS_IN_SET(['yes','no']))), + TR("Profile",TEXTAREA(_name="profile",value="write something here")), + TR("",INPUT(_type="submit",_value="SUBMIT")))) + if form.accepts(request,session): + response.flash="form accepted" + elif form.errors: + response.flash="form is invalid" + else: + response.flash="please fill the form" + return dict(form=form,vars=form.vars) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

You can use HTML helpers like FORM, INPUT, TEXTAREA, OPTION, SELECT to build forms. The "value=" attribute sets the initial value of the field (works for TEXTAREA and OPTION/SELECT too) and the requires attribute sets the validators. + FORM.accepts(..) tries to validate the form and, on success, stores vars into form.vars. On failure the error messages are stored into form.errors and shown in the form. +
Try it here: form

+ +

Database Examples

+ +

You can find more examples of the web2py Database Abstraction Layer here

+ +

Let's create a simple model with users, products (sold by users) and purchases (the database of an animal store). Each user can sell many products (ONE TO MANY). A user can buy many products and each product can have many buyers (MANY TO MANY).

+ +

Example {{=c}}{{c+=1}}

in model: db.py + {{=CODE(""" +db.define_table( + 'person', + Field('name'), + Field('email'), + format = '%(name)s') + +# ONE (person) TO MANY (products) + +db.define_table( + 'product', + Field('seller_id',db.person), + Field('name'), + Field('description', 'text'), + Field('picture', 'upload', default=''), + format = '%(name)s') + +# MANY (persons) TO MANY (purchases) + +db.define_table( + 'purchase', + Field('buyer_id', db.person), + Field('product_id', db.product), + Field('quantity', 'integer'), + format = '%(quantity)s %(product_id)s -> %(buyer_id)s') + +purchased = (db.person.id==db.purchase.buyer_id)&(db.product.id==db.purchase.product_id) + +db.person.name.requires = IS_NOT_EMPTY() +db.person.email.requires = [IS_EMAIL(), IS_NOT_IN_DB(db, 'person.email')] +db.product.name.requires = IS_NOT_EMPTY() +db.purchase.quantity.requires = IS_INT_IN_RANGE(0, 10) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

+ Tables are created if they do not exist (try... except). + Here "purchased" is an Query object, "db(purchased)" would be a Set objects. A Set object can be selected, updated, deleted. Sets can also be intersected. Allowed field types are string, integer, password, text, blob, upload, date, time, datetime, references(*), and id(*). The id field is there by default and must not be declared. References are for one to many and many to many as in the example above. For strings you should specify a length or you get length=32.

+ You can use db.tablename.fieldname.requires= to set restrictions on the field values. These restrictions are automatically converted into widgets when generating forms from the table with SQLFORM(db.tablename). +

+ define_tables creates the table and attempts a migration if table has changed or if database name has changed since last time. If you know you already have the table in the database and you do not want to attempt a migration add one last argument to define_table migrate=False.

+ +

Example {{=c}}{{c+=1}}

In controller: database_examples.py + {{=CODE(""" +response.menu = [['Register Person', False, URL('register_person')], + ['Register Product', False, URL('register_product')], + ['Buy product', False, URL('buy')]] + +def register_person(): + # create an insert form from the table + form = SQLFORM(db.person).process() + + # if form correct perform the insert + if form.accepted: + response.flash = 'new record inserted' + + # and get a list of all persons + records = SQLTABLE(db().select(db.person.ALL),headers='fieldname:capitalize') + + return dict(form=form, records=records) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}and view: database_examples/register_person.html + {{=CODE(open(os.path.join(request.folder,'views/database_examples/register_person.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

This is a simple user registration form. SQLFORM takes a table and returns the corresponding entry form with validators, etc. SQLFORM.accepts is similar to FORM.accepts but, if form is validated, the corresponding insert is also performed. SQLFORM can also do update and edit if a record is passed as its second argument. + SQLTABLE instead turns a set of records (result of a select) into an HTML table with links as specified by its optional parameters. + The response.menu on top is just a variable used by the layout to make the navigation menu for all functions in this controller.
+ +

Example {{=c}}{{c+=1}}

In controller: database_examples.py + {{=CODE(""" +def register_product(): + form = SQLFORM(db.product).process() + if form.accepted: + response.flash = 'new record inserted' + records = SQLTABLE(db().select(db.product.ALL), + upload = URL('download'), # allows pics preview + headers='fieldname:capitalize') + return dict(form=form, records=records) + + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}and view: database_examples/register_product.html + {{=CODE(open(os.path.join(request.folder,'views/database_examples/register_product.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

Nothing new here. + +

Example {{=c}}{{c+=1}}

In controller: database_examples.py + {{=CODE(""" + +def buy(): + form = SQLFORM.factory( + Field('buyer_id',requires=IS_IN_DB(db,db.person.id,'%(name)s')), + Field('product_id',requires=IS_IN_DB(db,db.product.id,'%(name)s')), + Field('quantity','integer',requires=IS_INT_IN_RANGE(1,100))).process() + if form.accepted: + # get previous purchase for same product + purchase = db((db.purchase.buyer_id == form.vars.buyer_id)& + (db.purchase.product_id==form.vars.product_id)).select().first() + + if purchase: + # if list contains a record, update that record + purchase.update_record( + quantity = purchase.quantity+form.vars.quantity) + else: + # self insert a new record in table + db.purchase.insert(buyer_id=form.vars.buyer_id, + product_id=form.vars.product_id, + quantity=form.vars.quantity) + response.flash = 'product purchased!' + elif form.errors: + response.flash = 'invalid values in form!' + + # now get a list of all purchases + records = SQLTABLE(db(purchased).select(),headers='fieldname:capitalize') + return dict(form=form, records=records) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}}and view: database_examples/buy.html + {{=CODE(open(os.path.join(request.folder,'views/database_examples/buy.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

Here is a rather sophisticated buy form. It checks that the buyer and the product are in the database and updates the corresponding record or inserts a new purchase. It also does a JOIN to list all purchases. + +

Example {{=c}}{{c+=1}}

In controller: database_examples.py + {{=CODE(""" +def download(): + return response.download(request,db) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

This controller allows users to download the uploaded pictures of products. + Remember the upload=URL('download') statement in the register_product function. Notice that in the URL path /application/controller/function/a/b/etc a, b, etc are passed to the controller as request.args[0], request.args[1], etc. Since the URL is validated request.args[] always contain valid filenames and no '~' or '..' etc. This is useful to allow visitors to link uploaded files.

+ +

Example {{=c}}{{c+=1}}

Using a Smartgrid +

All of the above database examples can be condensed in one simple command using the SQLFORM.smartgrid:

+ {{=CODE(""" +def manage_transactions(): + grid = SQLFORM.smartgrid(db.person,linked_tables=['product','purchase'], + user_signature=False) + return dict(grid=grid) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} + + The SQLFORM.smartgrid allows to create/read/delete persons as well as records in the linked tables (product and purchase). It also allows searching with pagination. It can be highly customized. The user_signature=False disables grid access control features which are beyond this simple example. + +

Cache Examples

+ +

Example {{=c}}{{c+=1}}

In controller: cache_examples.py + {{=CODE(""" +def cache_in_ram(): + import time + t=cache.ram('time',lambda:time.ctime(),time_expire=5) + return dict(time=t,link=A('click to reload',_href=URL(r=request))) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

The output of lambda:time.ctime() is cached in ram for 5 seconds. The string 'time' is used as cache key. +
Try it here: cache_in_ram

+ + +

Example {{=c}}{{c+=1}}

In controller: cache_examples.py + {{=CODE(""" +def cache_on_disk(): + import time + t=cache.disk('time',lambda:time.ctime(),time_expire=5) + return dict(time=t,link=A('click to reload',_href=URL(r=request))) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

The output of lambda:time.ctime() is cached on disk (using the shelve module) for 5 seconds. +
Try it here: cache_on_disk

+ +

Example {{=c}}{{c+=1}}

In controller: cache_examples.py + {{=CODE(""" +def cache_in_ram_and_disk(): + import time + t=cache.ram('time',lambda:cache.disk('time', + lambda:time.ctime(),time_expire=5),time_expire=5) + return dict(time=t,link=A('click to reload',_href=URL(r=request))) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

The output of lambda:time.ctime() is cached on disk (using the shelve module) and then in ram for 5 seconds. web2py looks in ram first and if not there it looks on disk. If it is not on disk it calls the function. This is useful in a multiprocess type of environment. The two times do not have to be the same. +
Try it here: cache_in_ram_and_disk

+ + +

Example {{=c}}{{c+=1}}

In controller: cache_examples.py + {{=CODE(""" +@cache(request.env.path_info,time_expire=5,cache_model=cache.ram) + def cache_controller_in_ram(): + import time + t=time.ctime() + return dict(time=t,link=A('click to reload',_href=URL(r=request)))""".strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

Here the entire controller (dictionary) is cached in ram for 5 seconds. The result of a select cannot be cached unless it is first serialized into a table lambda:SQLTABLE(db().select(db.user.ALL)).xml(). You can read below for an even better way to do it. +
Try it here: cache_controller_in_ram

+ +

Example {{=c}}{{c+=1}}

In controller: cache_examples.py + {{=CODE(""" +@cache(request.env.path_info,time_expire=5,cache_model=cache.disk) +def cache_controller_on_disk(): + import time + t=time.ctime() + return dict(time=t,link=A('click to reload',_href=URL(r=request))) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

Here the entire controller (dictionary) is cached on disk for 5 seconds. This will not work if the dictionary contains unpickleable objects. +
Try it here: cache_controller_on_disk

+ +

Example {{=c}}{{c+=1}}

In controller: cache_examples.py + {{=CODE(""" +@cache(request.env.path_info,time_expire=5,cache_model=cache.ram) +def cache_controller_and_view(): + import time + t=time.ctime() + d=dict(time=t,link=A('click to reload',_href=URL(r=request))) + return response.render(d) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

response.render(d) renders the dictionary inside the controller, so everything is cached now for 5 seconds. This is the best and fastest way of caching! +
Try it here: cache_controller_and_view

+ +

Example {{=c}}{{c+=1}}

In controller: cache_examples.py + {{=CODE(""" +def cache_db_select(): + import time + db.person.insert(name='somebody',email='gluon@mdp.cti.depaul.edu') + records = db().select(db.person.ALL,cache=(cache.ram,5)) + if len(records)>20: db(db.person.id>0).delete() + return dict(records=records) + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

The results of a select are complex unpickleable objects that cannot be cached using the previous method, but the select command takes an argument cache=(cache_model,time_expire) and will cache the result of the query accordingly. Notice that the key is not necessary since key is generated based on the database name and the select string. + +

Ajax Examples

+ + +

Example {{=c}}{{c+=1}}

In controller: ajax_examples.py + {{=CODE(""" +def index(): + return dict() + +def data(): + if not session.m or len(session.m)==10: session.m=[] + if request.vars.q: session.m.append(request.vars.q) + session.m.sort() + return TABLE(*[TR(v) for v in session.m]).xml() + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} + In view: ajax_examples/index.html + {{=CODE(open(os.path.join(request.folder,'views/ajax_examples/index.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

The javascript function "ajax" is provided in "web2py_ajax.html" and included by "layout.html". It takes three arguments, a url, a list of ids and a target id. When called, it sends to the url (via a get) the values of the ids and display the response in the value (of innerHTML) of the target id. +
Try it here: index

+ +

Example {{=c}}{{c+=1}}

In controller: ajax_examples.py + {{=CODE(""" +def flash(): + response.flash='this text should appear!' + return dict() + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

Try it here: flash

+ +

Example {{=c}}{{c+=1}}

In controller: ajax_examples.py + {{=CODE(""" +def fade(): + return dict() + """.strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} + In view: ajax_examples/fade.html
+ {{=CODE(open(os.path.join(request.folder,'views/ajax_examples/fade.html'),'r').read(),language='html',link=URL('global','vars'),_class='boxCode')}} +

Try it here: fade

+ +

Excel-like spreadsheet via Ajax

+ Web2py includes a widget that acts like an Excel-like spreadsheet and can be used to build forms + read more. + +

Testing Examples

+ + +

Example {{=c}}{{c+=1}}

+

Using the Python doctest notation it is possible to write tests for all controller functions. Tests are then run via the administrative interface which generates a report. Here is an example of a test in the code: + {{=CODE(""" +def index(): + ''' + This is a docstring. The following 3 lines are a doctest: + >>> request.vars.name='Max' + >>> index() + {'name': 'Max'} + ''' + return dict(name=request.vars.name) +""".strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

+ +

Streaming Examples

+ + +

Example {{=c}}{{c+=1}}

+

It is very easy in web2py to stream large files. Here is an example of a controller that does so:

+ {{=CODE(""" +def streamer(): + import os + path=os.path.join(request.folder,'private','largefile.mpeg4') + return response.stream(open(path,'rb'),chunk_size=4096) +""".strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} +

By default all static files and files stored in 'upload' fields in the database are streamed when larger than 1 MByte.

+ +

web2py automatically and transparently handles PARTIAL_CONTENT and RANGE requests.

+ +

XML-RPC Examples

+ +

Example {{=c}}{{c+=1}}

+

Web2py has native support for the XMLRPC protocol. Below is a controller function "handler" that exposes two functions, "add" and "sub" via XMLRPC. The controller "tester" executes the two functions remotely via xmlrpc.

+ {{=CODE(""" +from gluon.tools import Service +service = Service(globals()) + +@service.xmlrpc +def add(a,b): return a+b + +@service.xmlrpc +def sub(a,b): return a-b + +def call(): return service() + +def tester(): + import xmlrpclib + server=xmlrpclib.ServerProxy('http://hostname:port/app/controller/call/xmlrpc') + return str(server.add(3,4)+server.sub(3,4)) +""".strip(),language='web2py',link=URL('global','vars'),_class='boxCode')}} + +
+
+{{block sidebar}}{{end}} + diff --git a/web2py/applications/examples/views/default/index.html b/web2py/applications/examples/views/default/index.html new file mode 100644 index 0000000..19708c7 --- /dev/null +++ b/web2py/applications/examples/views/default/index.html @@ -0,0 +1,69 @@ +{{extend 'layout.html'}} + +
+
+
+

Web Framework

+

Free open source full-stack framework for rapid development of fast, scalable, secure and portable database-driven web-based applications. Written and programmable in Python.

+ + + + + + +
+ + + + + + + + + + + +
+

Current version: {{=request.env.web2py_version}} (LGPLv3 License)

+
+
+ +
+
+
+
+
Batteries Included
+

Everything you need in one package including fast multi-threaded web server, SQL database and web-based interface. No third party dependencies but works with third party tools.

+
+
+
+
+
Web-Based IDE
+

Create, modify, deploy and manage application from anywhere using your browser. One web2py instance can run multiple web sites using different databases. Try the interactive demo.

+
+
+
+
+
Extensive Docs
+

Start with some quick examples, then read the manual and the Sphinx docs, watch videos, and join a user group for discussion. Take advantage of the layouts, plugins, appliances, and recipes.

+
+
+
diff --git a/web2py/applications/examples/views/default/license.html b/web2py/applications/examples/views/default/license.html new file mode 100644 index 0000000..a06c784 --- /dev/null +++ b/web2py/applications/examples/views/default/license.html @@ -0,0 +1,8 @@ +{{extend 'layout.html'}} + +
+

web2py License Agreement

+ {{=license}} +
+ + diff --git a/web2py/applications/examples/views/default/support.html b/web2py/applications/examples/views/default/support.html new file mode 100644 index 0000000..b15217e --- /dev/null +++ b/web2py/applications/examples/views/default/support.html @@ -0,0 +1,43 @@ +{{extend 'layout.html'}} +
+

Support for web2pyTM

+ +

You can get a lot of free support by joining our mailing list.

+ +

Affiliated Companies

+ +

For long term professional support, code review, and contract work, you can contact our core developers:

+ + + +

For professional support, you can also contact one of the companies below:

+ + + +
+ +{{block leftbadges}}{{end}} + diff --git a/web2py/applications/examples/views/default/usergroups.html b/web2py/applications/examples/views/default/usergroups.html new file mode 100644 index 0000000..05b3c55 --- /dev/null +++ b/web2py/applications/examples/views/default/usergroups.html @@ -0,0 +1,10 @@ +{{extend 'layout.html'}} + +
+
+ {{=get_content('grouplist')}} +
+
+ + + diff --git a/web2py/applications/examples/views/default/videos.html b/web2py/applications/examples/views/default/videos.html new file mode 100644 index 0000000..30c19ad --- /dev/null +++ b/web2py/applications/examples/views/default/videos.html @@ -0,0 +1,17 @@ +{{extend 'layout.html'}} +

+
+

{{=T('web2py videos')}}

+
+ + + + + + + +
+
+ + + diff --git a/web2py/applications/examples/views/default/what.html b/web2py/applications/examples/views/default/what.html new file mode 100644 index 0000000..9698cb0 --- /dev/null +++ b/web2py/applications/examples/views/default/what.html @@ -0,0 +1,30 @@ +{{right_sidebar_enabled = True}} +{{extend 'layout.html'}} {{import os}} + +{{=get_content('whyweb2py')}} + +{{block right_sidebar}} +
+ +
+ +{{end}} + diff --git a/web2py/applications/examples/views/default/who.html b/web2py/applications/examples/views/default/who.html new file mode 100644 index 0000000..78c899e --- /dev/null +++ b/web2py/applications/examples/views/default/who.html @@ -0,0 +1,175 @@ +{{extend 'layout.html'}} +
+

+ The web2py™ Team +

+

+ Lead Developer +

+
    +
  • + Massimo Di Pierro + (Professor of Computer Science at DePaul University, Chicago) +
  • +
+

+ Contributor Agreement +

+

+ By contributing to web2py you implicitly agree to the + web2py contributor agreement. + Please also send us a signed copy by fax or, scanned, by email. +

+

+ Main Contributors/Developers +

+
    +
  • Alexey Nezhdanov (GAE and database performance) +
  • Alan Etkin (DAL IMAP adapter) +
  • Alvaro Justen (dynamical translations) +
  • Anders Roos (file locking) +
  • Andrew Willimott (documentation, TeraData support) +
  • Andriy Kornatskyy (benchmarks and profiling) +
  • Angelo Compagnucci (mobile devices) +
  • Anthony Bastardi (book, poweredby site, multiple contributions) +
  • Arun K. Rajeevan (plugin_wiki) +
  • Attila Csipa (cron job) +
  • Ben Goosman (keyed table and Oracle adapter) +
  • Bill Ferrett (modular DAL design) +
  • Boris Manojlovic (ajax edit) +
  • Branko Vukelic (new admin app) +
  • Brian Meredyk (SQLite, executesql and scheduler) +
  • Bruno Rocha (book, new website, better forms, grid layout) +
  • Carlos Galindo +
  • Carsten Haese (Informix) +
  • Chris Clark (Ingres, Jython support) +
  • Chris May (new website) +
  • Chris Steel +
  • Christian Foster Howes (GAE support) +
  • Christopher Smiga (Informix) +
  • CJ Lazell (tester) +
  • Corne Dickens (import mechanism) +
  • Craig Younkins (Security) +
  • Daniel Lin (Taiwanese internationalization) +
  • Dave Stoll (DowCommerce payment API, security) +
  • David Wagner (security and cryptography expert) +
  • Denes Lengyel (validators, DB2 support, DAL, custom forms, legacy table support) +
  • Douglas Soares de Andrade (2.4 and 2.6 compliance, docstrings) +
  • Eric Vicenti (email with ssl) +
  • Falko Krause (mysql support) +
  • Farsheed Ashouri +
  • Fran Boon (authorization and authentication) +
  • Francisco Gama (bug fixing) +
  • Fred Yanowski (XHTML compliance) +
  • Gilson Filho +
  • Graham Dumpleton (WSGI) +
  • Gyuris Szabolcs (PGP Mail) +
  • Hamdy Abdel-Badeea (crud) +
  • Hans Donner (GAE support, Google login, widgets, Sphinx documentation) +
  • Hans Murx (Database support) +
  • Hans C. v. Stockhausen (OpenID, Google Wave) +
  • Ian Reinhart Geiser (html helpers) +
  • Ionel Anton (Romanian translation) +
  • Jan Beilicke (markmin) +
  • Jeremy Dillworth +
  • Jonathan Benn (is_url validator and tests) +
  • Jonathan Lundell (multiple contributions) +
  • Josh Goldfoot (xaml/html sanitizer) +
  • Jose Jachuf (Firebird support) +
  • José L. Redrejo Rodríguez (Debian Package, pyfpdf) +
  • Josh Jaques (web2py_ajax) +
  • José Vicente de Sousa (Layout for new website) +
  • Keith Yang (openid) +
  • Kenji Hosoda (plugins) +
  • Kyle Smith (javascript) +
  • Leonel Câmara +
  • Limodou (winservice) +
  • Lucas D'Ávila +
  • Marc Abramowitz (tests and travis continuous integration) +
  • Marcel Leuthi (Oracle support) +
  • Marcel Hellkamp (Bottle developer, multiple web server support) +
  • Marcello Della Longa (italian translation) +
  • Mariano Reingart (pysoaplib, debugger, pyfpdf) +
  • Marin Pranjić (dal) +
  • Mark Larsen (taskbar widget) +
  • Mark Moore (databases and daemon scripts) +
  • Markus Gritsch (bug fixing) +
  • Martin Hufsky (expressions in DAL) +
  • Martin Mulone (new welcome app, grid) +
  • Mateusz Banach (stickers, IS_EMAIL, IS_IMAGE, contenttype) +
  • Michael Willis (shell) +
  • Michele Comitini (facebook) +
  • Michael Toomim (scheduler) +
  • Narendra Bhati (security) +
  • Nathan Freeze (admin design, IS_STRONG, DAL features, web2pyslices.com) +
  • Niall Sweeny (MSSQL support) +
  • Niccolo Polo (epydoc) +
  • Nicolas Bruxer (memcache support) +
  • Olaf Ferger (Informix support) +
  • Omi Chiba (DB2, MSSQL support and Japanese translation) +
  • Ondrej Such (MSSQL support) +
  • Ovidio Marinho Falcao Neto (tests and plugin developer) +
  • Pai (internationalization) +
  • Paolo Caruccio (SQLFORM.grid query) +
  • Paolo Pastori +
  • Patrick Breitenbach +
  • Phyo Arkar Lwin (web hosting and Jython tester) +
  • Pierre Thibault (Eclipse integration and custom import) +
  • Robert Valentak (Slovenian translation) +
  • Robin Bhattacharyya (Google App Engine support) +
  • Ross Peoples (MSSQL, multiple contributions) +
  • Ruijun Luo (a.k.a. Iceberg) (setup_exe.py) +
  • Ryan Seto (template.py) +
  • Scott Roberts (testing, book) +
  • Sergey Podlesnyi (Oracle and migrations tester) +
  • Sharriff Aina (tester and PyAMF integration) +
  • Simone Bizzotto (scheduler, dal, redis, tests, sphinx) +
  • Sriram Durbha (book) +
  • Sterling Hankins (tester, book) +
  • Stuart Rackham (MSSQL support) +
  • Telman Yusupov (Oracle support) +
  • Thadeus Burgess (validators) +
  • Tim Michelsen (Sphinx documentation) +
  • Timothy Farrell (python 2.6 compliance, windows support) +
  • Yair Eshel (internationalizaiton, DAL improvement) +
  • Yannis Aribaud (CAS compliance) +
  • Yarko Tymciurak (design) +
  • Younghyun Jo (internationalization) +
  • Vladyslav Kozlovskyy (internationalization, markmin, admin, and mercurial support) +
  • Vidul Nikolaev Petrov (captcha) +
  • Vinicius Assef +
  • Zahariash (memory management) +
  • + +
+ +

+ Third party software included in web2py +

+
    + +
  • Python created by Guido van Rossum.
  • +
  • Rocket Web Server developed by Timothy Farrell.
  • +
  • CodeMirror
  • + +
  • PyRTF developed by Simon Cusack and revised by Grant Edwards
  • +
  • PyRSS2Gen developed by Dalke Scientific Software
  • +
  • feedparser developed by Mark Pilgrim
  • +
  • markdown2 developed by Trent Mick
  • +
  • fcgi.py developed by Allan Saddi (for production Lighttpd servers)
  • +
  • memcache developed by Evan Martin
  • +
  • jQuery developed by John Resig
  • +
  • A syntax highlighter inspired by the code of Peter Wilkinson
  • +
  • pyUCA developed by James Tauber
  • +
+(... and other third party modules in the contrib folder). + +
+ + + + + + + + diff --git a/web2py/applications/examples/views/form_examples/form.html b/web2py/applications/examples/views/form_examples/form.html new file mode 100644 index 0000000..d1f2232 --- /dev/null +++ b/web2py/applications/examples/views/form_examples/form.html @@ -0,0 +1,9 @@ +{{extend 'layout.html'}} + +

form.vars

+
{{=vars}}
+ +

form

+ +{{=form}} + diff --git a/web2py/applications/examples/views/generic.html b/web2py/applications/examples/views/generic.html new file mode 100644 index 0000000..2ffbd52 --- /dev/null +++ b/web2py/applications/examples/views/generic.html @@ -0,0 +1,16 @@ +{{extend 'layout.html'}} +{{""" + +You should not modify this file. +It is used as default when a view is not provided for your controllers + +"""}} +

{{=' '.join(x.capitalize() for x in request.function.split('_'))}}

+{{if len(response._vars)==1:}} +{{=BEAUTIFY(response._vars[next(iter(response._vars))])}} +{{elif len(response._vars)>1:}} +{{=BEAUTIFY(response._vars)}} +{{pass}} +{{if request.is_local:}} +{{=response.toolbar()}} +{{pass}} diff --git a/web2py/applications/examples/views/generic.json b/web2py/applications/examples/views/generic.json new file mode 100644 index 0000000..e17923a --- /dev/null +++ b/web2py/applications/examples/views/generic.json @@ -0,0 +1,15 @@ +{{ +### +# response._vars contains the dictionary returned by the controller action +### +try: + from gluon.serializers import json + response.write(json(response._vars), escape=False) + response.headers['Content-Type'] = 'application/json; charset=utf-8' +except (TypeError, ValueError): + raise HTTP(405, 'JSON serialization error') +except ImportError: + raise HTTP(405, 'JSON not available') +except: + raise HTTP(405, 'JSON error') +}} diff --git a/web2py/applications/examples/views/generic.load b/web2py/applications/examples/views/generic.load new file mode 100644 index 0000000..921a366 --- /dev/null +++ b/web2py/applications/examples/views/generic.load @@ -0,0 +1 @@ +{{response.headers['web2py-response-flash']=response.flash}}{{if len(response._vars)==1:}}{{=response._vars[next(iter(response._vars))]}}{{else:}}{{=BEAUTIFY(response._vars)}}{{pass}} \ No newline at end of file diff --git a/web2py/applications/examples/views/generic.rss b/web2py/applications/examples/views/generic.rss new file mode 100644 index 0000000..abf0aa8 --- /dev/null +++ b/web2py/applications/examples/views/generic.rss @@ -0,0 +1,20 @@ +{{ +### +# response._vars contains the dictionary returned by the controller action +# for this to work the action must return something like +# +# dict(title=...,link=...,description=...,created_on='...',items=...) +# +# items is a list of dictionaries each with title, link, description, pub_date. +### +try: + from gluon.serializers import rss + response.write(rss(response._vars), escape=False) + response.headers['Content-Type'] = 'application/rss+xml' +except (TypeError, ValueError): + raise HTTP(405, 'RSS serialization error') +except ImportError: + raise HTTP(405, 'RSS not available') +except: + raise HTTP(405, 'RSS error') +}} \ No newline at end of file diff --git a/web2py/applications/examples/views/generic.xml b/web2py/applications/examples/views/generic.xml new file mode 100644 index 0000000..234b405 --- /dev/null +++ b/web2py/applications/examples/views/generic.xml @@ -0,0 +1 @@ +{{from gluon.serializers import xml}}{{=XML(xml(response._vars,quote=False))}} diff --git a/web2py/applications/examples/views/global/vars.html b/web2py/applications/examples/views/global/vars.html new file mode 100644 index 0000000..6615451 --- /dev/null +++ b/web2py/applications/examples/views/global/vars.html @@ -0,0 +1,54 @@ +{{extend 'layout.html'}} +{{import cgi}} + +
+

{{=T('Docs for')}} {{=title}}

+ + + +

{{=T('Description')}}

+ +
+ {{if t:}} + {{=t}}{{if d:}} extends {{=d}}{{pass}} + {{pass}} +
+ {{pass}} + + {{if doc:}}

{{=MARKMIN(doc)}}{{pass}} +

+
+ {{if attributes:}} +

{{=T('Attributes')}}

+ + + + {{for key in sorted(attributes):}} + {{doc1,t1,c1,d1=attributes[key]}} + + + + + + {{pass}} +

+ {{if key.count('.')<2:}} + {{=A(key,_rel="nofollow",_href=URL(args=key.split('.')))}} + {{else:}} + {{=key}} + {{pass}} + + {{if t1:}} + {{=t1}}{{if d1:}} extends {{=d1}}{{pass}} + {{if c1:}} belongs to class {{=c1}}{{pass}} +
+ {{pass}} + {{if doc1:}}{{=MARKMIN(doc1)}}{{pass}} +

+
+ {{pass}} +
diff --git a/web2py/applications/examples/views/images_examples/index.html b/web2py/applications/examples/views/images_examples/index.html new file mode 100644 index 0000000..88a36b5 --- /dev/null +++ b/web2py/applications/examples/views/images_examples/index.html @@ -0,0 +1,5 @@ +{{extend 'layout.html'}} +

Upload page

+{{=form}} + +{{block sidebar end}} diff --git a/web2py/applications/examples/views/layout.html b/web2py/applications/examples/views/layout.html new file mode 100644 index 0000000..3ae35e2 --- /dev/null +++ b/web2py/applications/examples/views/layout.html @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + {{ + left_sidebar_enabled = globals().get('left_sidebar_enabled', False) + right_sidebar_enabled = globals().get('right_sidebar_enabled', False) + middle_column = {0: 'fill', 1: 'threequarters', 2: 'half'}[ + (left_sidebar_enabled and 1 or 0)+(right_sidebar_enabled and 1 or 0)] + }} + {{include "web2py_ajax.html"}} + + +
+
+
+ +
+ + {{=MENU(response.menu,_class='menu')}} +
+
+
+
+ {{if response.flash:}} +
+ {{=response.flash}} +
+ {{pass}} +
+
+ {{if left_sidebar_enabled:}} +
{{block left_sidebar}}{{end}}
+ {{pass}} +
{{include}}
+ {{if right_sidebar_enabled:}} +
{{block right_sidebar}}{{end}}
+ {{pass}} +
+
+ + +
+
+
+
+
+ Copyright @ 2016 - Powered by Web2py +
+
+
+ + + diff --git a/web2py/applications/examples/views/layout_examples/basic.html b/web2py/applications/examples/views/layout_examples/basic.html new file mode 100644 index 0000000..752235f --- /dev/null +++ b/web2py/applications/examples/views/layout_examples/basic.html @@ -0,0 +1,3 @@ +{{extend 'layout.html'}} +

{{=message}}

+{{for i in range(1000):}}bla {{pass}} diff --git a/web2py/applications/examples/views/layout_examples/civilized.html b/web2py/applications/examples/views/layout_examples/civilized.html new file mode 100644 index 0000000..f732765 --- /dev/null +++ b/web2py/applications/examples/views/layout_examples/civilized.html @@ -0,0 +1,3 @@ +{{extend 'layout_examples/layout_civilized.html'}} +

{{=message}}

+

{{for i in range(1000):}}bla {{pass}} 

diff --git a/web2py/applications/examples/views/layout_examples/layout_civilized.html b/web2py/applications/examples/views/layout_examples/layout_civilized.html new file mode 100644 index 0000000..7d0c017 --- /dev/null +++ b/web2py/applications/examples/views/layout_examples/layout_civilized.html @@ -0,0 +1,291 @@ + + + + + +{{=request.application}} + + + + + +
+ + {{if response.menu:}} + + {{pass}} +
+
+
+ {{if response.flash:}}

FLASH: {{=response.flash}}

{{pass}} + {{include}} +
+
+
+
+
+
+ +
+ + + diff --git a/web2py/applications/examples/views/layout_examples/layout_sleek.html b/web2py/applications/examples/views/layout_examples/layout_sleek.html new file mode 100644 index 0000000..c37a79f --- /dev/null +++ b/web2py/applications/examples/views/layout_examples/layout_sleek.html @@ -0,0 +1,253 @@ + + + + + +{{=request.application}} + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+{{if response.flash:}}

FLASH: {{=response.flash}}

{{pass}} +{{include}} +
+ +
+ + + + + diff --git a/web2py/applications/examples/views/layout_examples/slick.html b/web2py/applications/examples/views/layout_examples/slick.html new file mode 100644 index 0000000..276b6a3 --- /dev/null +++ b/web2py/applications/examples/views/layout_examples/slick.html @@ -0,0 +1,3 @@ +{{extend 'layout_examples/layout_sleek.html'}} +

{{=message}}

+{{for i in range(1000):}}bla {{pass}} diff --git a/web2py/applications/examples/views/session_examples/counter.html b/web2py/applications/examples/views/session_examples/counter.html new file mode 100644 index 0000000..0ef633a --- /dev/null +++ b/web2py/applications/examples/views/session_examples/counter.html @@ -0,0 +1,8 @@ +{{extend 'layout.html'}} +

session counter

+ +

{{for i in range(counter):}}{{=i}}... {{pass}}

+ +{{=T('click me to count')}} + +{{block sidebar}} {{end}} diff --git a/web2py/applications/examples/views/simple_examples/ajaxwiki.html b/web2py/applications/examples/views/simple_examples/ajaxwiki.html new file mode 100644 index 0000000..363fd41 --- /dev/null +++ b/web2py/applications/examples/views/simple_examples/ajaxwiki.html @@ -0,0 +1,4 @@ +{{extend 'layout.html'}} +

Ajax Wiki

+{{=form}} +{{=html}} diff --git a/web2py/applications/examples/views/simple_examples/hello3.html b/web2py/applications/examples/views/simple_examples/hello3.html new file mode 100644 index 0000000..4f0a0eb --- /dev/null +++ b/web2py/applications/examples/views/simple_examples/hello3.html @@ -0,0 +1,3 @@ +{{extend 'layout.html'}} +

{{=message}}

+ diff --git a/web2py/applications/examples/views/soap_examples/generic.html b/web2py/applications/examples/views/soap_examples/generic.html new file mode 100644 index 0000000..03ea2fb --- /dev/null +++ b/web2py/applications/examples/views/soap_examples/generic.html @@ -0,0 +1,8 @@ +{{extend 'layout.html'}} +

SOAP Examples

+

Result

+{{=BEAUTIFY(result)}} +

XML Request

+{{=BEAUTIFY(xml_request)}} +

XML Response

+{{=BEAUTIFY(xml_response)}} diff --git a/web2py/applications/examples/views/spreadsheet/index.html b/web2py/applications/examples/views/spreadsheet/index.html new file mode 100644 index 0000000..dc7e2e6 --- /dev/null +++ b/web2py/applications/examples/views/spreadsheet/index.html @@ -0,0 +1,12 @@ +{{extend 'layout.html'}} + +

Excel-like spreadsheet widget

+ +Try insert "=r0c1+1" in cell r0c0 and "2" in r0c1. Formulas start with "=" as in Excel. You can use a subset of python commands and math function, and reference cells by r[row]c[col]. All computations are performed serverside via Ajax (input is validated for security). Cell values and formulas can be set and locked serverside. The shape of the spreadsheet can be modifed serverside and does not need to be tabular (think of it as a graph of css-friendly widgets you can place where you want). Cells can be given arbistrary names. This example is distributed with web2py so look at the source code of the example to learn more. + +{{=sheet}} + diff --git a/web2py/applications/examples/views/template_examples/beautify.html b/web2py/applications/examples/views/template_examples/beautify.html new file mode 100644 index 0000000..d0e5140 --- /dev/null +++ b/web2py/applications/examples/views/template_examples/beautify.html @@ -0,0 +1,5 @@ +{{extend 'layout.html'}} +

BEAUTIFY

+ +

Message is

+{{=message}} diff --git a/web2py/applications/examples/views/template_examples/escape.html b/web2py/applications/examples/views/template_examples/escape.html new file mode 100644 index 0000000..70d7b80 --- /dev/null +++ b/web2py/applications/examples/views/template_examples/escape.html @@ -0,0 +1,5 @@ +{{extend 'layout.html'}} +

Strings are automatically escaped

+ +

Message is

+{{=message}} diff --git a/web2py/applications/examples/views/template_examples/test_def.html b/web2py/applications/examples/views/template_examples/test_def.html new file mode 100644 index 0000000..a8958d3 --- /dev/null +++ b/web2py/applications/examples/views/template_examples/test_def.html @@ -0,0 +1,7 @@ +{{extend 'layout.html'}} +{{def itemlink(name):}}
  • {{=A(name,_href=name)}}
  • {{return}} +
      +{{itemlink('http://www.google.com')}} +{{itemlink('http://www.yahoo.com')}} +{{itemlink('http://www.nyt.com')}} +
    diff --git a/web2py/applications/examples/views/template_examples/test_for.html b/web2py/applications/examples/views/template_examples/test_for.html new file mode 100644 index 0000000..25124cf --- /dev/null +++ b/web2py/applications/examples/views/template_examples/test_for.html @@ -0,0 +1,7 @@ +{{extend 'layout.html'}} +

    For loop

    + +{{for number in ['one','two','three']:}} +

    {{=number.capitalize()}}

    +{{pass}} + diff --git a/web2py/applications/examples/views/template_examples/test_if.html b/web2py/applications/examples/views/template_examples/test_if.html new file mode 100644 index 0000000..71ef08d --- /dev/null +++ b/web2py/applications/examples/views/template_examples/test_if.html @@ -0,0 +1,11 @@ +{{extend 'layout.html'}} +

    If statement

    + +{{a=10}} + +{{if a%2==0:}} +

    {{=a}} is even

    +{{else:}} +

    {{=a}} is odd

    +{{pass}} + diff --git a/web2py/applications/examples/views/template_examples/test_try.html b/web2py/applications/examples/views/template_examples/test_try.html new file mode 100644 index 0000000..cd3857a --- /dev/null +++ b/web2py/applications/examples/views/template_examples/test_try.html @@ -0,0 +1,8 @@ +{{extend 'layout.html'}} +

    Try... except

    + +{{try:}} +

    a={{=1/0}}

    +{{except:}} + infinity +{{pass}} diff --git a/web2py/applications/examples/views/template_examples/variables.html b/web2py/applications/examples/views/template_examples/variables.html new file mode 100644 index 0000000..8367fb3 --- /dev/null +++ b/web2py/applications/examples/views/template_examples/variables.html @@ -0,0 +1,4 @@ +{{extend 'layout.html'}} +

    Your variables

    +

    a={{=a}}

    +

    a={{=b}}

    diff --git a/web2py/applications/examples/views/template_examples/xml.html b/web2py/applications/examples/views/template_examples/xml.html new file mode 100644 index 0000000..07fed5f --- /dev/null +++ b/web2py/applications/examples/views/template_examples/xml.html @@ -0,0 +1,5 @@ +{{extend 'layout.html'}} +

    XML

    + +

    Message is

    +{{=message}} diff --git a/web2py/applications/examples/views/web2py_ajax.html b/web2py/applications/examples/views/web2py_ajax.html new file mode 100644 index 0000000..0f064de --- /dev/null +++ b/web2py/applications/examples/views/web2py_ajax.html @@ -0,0 +1,17 @@ + +{{ +response.files.insert(0,URL('static','js/jquery.js')) +response.files.insert(1,URL('static','css/calendar.css')) +response.files.insert(2,URL('static','js/calendar.js')) +response.files.insert(3,URL('static','js/web2py.js')) +response.include_meta() +response.include_files() +}} diff --git a/web2py/applications/welcome/ABOUT b/web2py/applications/welcome/ABOUT new file mode 100644 index 0000000..184b19c --- /dev/null +++ b/web2py/applications/welcome/ABOUT @@ -0,0 +1,2 @@ +Write something about this app. +Developed with web2py. diff --git a/web2py/applications/welcome/DISABLED b/web2py/applications/welcome/DISABLED new file mode 100644 index 0000000..e69de29 diff --git a/web2py/applications/welcome/LICENSE b/web2py/applications/welcome/LICENSE new file mode 100644 index 0000000..217b7c4 --- /dev/null +++ b/web2py/applications/welcome/LICENSE @@ -0,0 +1,4 @@ +The web2py welcome app is licensed under public domain +(except for the css and js files that it includes, which have their own third party licenses). + +You can modify this license when you add your own code. diff --git a/web2py/applications/welcome/__init__.py b/web2py/applications/welcome/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/web2py/applications/welcome/__init__.py @@ -0,0 +1 @@ + diff --git a/web2py/applications/welcome/controllers/appadmin.py b/web2py/applications/welcome/controllers/appadmin.py new file mode 100644 index 0000000..da050a5 --- /dev/null +++ b/web2py/applications/welcome/controllers/appadmin.py @@ -0,0 +1,693 @@ +# -*- coding: utf-8 -*- + +# ########################################################## +# ## make sure administrator is on localhost +# ########################################################### + +import os +import socket +import datetime +import copy +import gluon.contenttype +import gluon.fileutils +from gluon._compat import iteritems + +is_gae = request.env.web2py_runtime_gae or False + +# ## critical --- make a copy of the environment + +global_env = copy.copy(globals()) +global_env['datetime'] = datetime + +http_host = request.env.http_host.split(':')[0] +remote_addr = request.env.remote_addr +try: + hosts = (http_host, socket.gethostname(), + socket.gethostbyname(http_host), + '::1', '127.0.0.1', '::ffff:127.0.0.1') +except: + hosts = (http_host, ) + +if request.is_https: + session.secure() +elif (remote_addr not in hosts) and (remote_addr != "127.0.0.1") and \ + (request.function != 'manage'): + raise HTTP(200, T('appadmin is disabled because insecure channel')) + +if request.function == 'manage': + if not 'auth' in globals() or not request.args: + redirect(URL(request.controller, 'index')) + manager_action = auth.settings.manager_actions.get(request.args(0), None) + if manager_action is None and request.args(0) == 'auth': + manager_action = dict(role=auth.settings.auth_manager_role, + heading=T('Manage Access Control'), + tables=[auth.table_user(), + auth.table_group(), + auth.table_permission()]) + manager_role = manager_action.get('role', None) if manager_action else None + if not (gluon.fileutils.check_credentials(request) or auth.has_membership(manager_role)): + raise HTTP(403, "Not authorized") + menu = False +elif (request.application == 'admin' and not session.authorized) or \ + (request.application != 'admin' and not gluon.fileutils.check_credentials(request)): + redirect(URL('admin', 'default', 'index', + vars=dict(send=URL(args=request.args, vars=request.vars)))) +else: + response.subtitle = T('Database Administration (appadmin)') + menu = True + +ignore_rw = True +response.view = 'appadmin.html' +if menu: + response.menu = [[T('design'), False, URL('admin', 'default', 'design', + args=[request.application])], [T('db'), False, + URL('index')], [T('state'), False, + URL('state')], [T('cache'), False, + URL('ccache')]] + +# ########################################################## +# ## auxiliary functions +# ########################################################### + +if False and request.tickets_db: + from gluon.restricted import TicketStorage + ts = TicketStorage() + ts._get_table(request.tickets_db, ts.tablename, request.application) + +def get_databases(request): + dbs = {} + for (key, value) in global_env.items(): + try: + cond = isinstance(value, GQLDB) + except: + cond = isinstance(value, SQLDB) + if cond: + dbs[key] = value + return dbs + +databases = get_databases(None) + +def eval_in_global_env(text): + exec ('_ret=%s' % text, {}, global_env) + return global_env['_ret'] + + +def get_database(request): + if request.args and request.args[0] in databases: + return eval_in_global_env(request.args[0]) + else: + session.flash = T('invalid request') + redirect(URL('index')) + +def get_table(request): + db = get_database(request) + if len(request.args) > 1 and request.args[1] in db.tables: + return (db, request.args[1]) + else: + session.flash = T('invalid request') + redirect(URL('index')) + + +def get_query(request): + try: + return eval_in_global_env(request.vars.query) + except Exception: + return None + + +def query_by_table_type(tablename, db, request=request): + keyed = hasattr(db[tablename], '_primarykey') + if keyed: + firstkey = db[tablename][db[tablename]._primarykey[0]] + cond = '>0' + if firstkey.type in ['string', 'text']: + cond = '!=""' + qry = '%s.%s.%s%s' % ( + request.args[0], request.args[1], firstkey.name, cond) + else: + qry = '%s.%s.id>0' % tuple(request.args[:2]) + return qry + + +# ########################################################## +# ## list all databases and tables +# ########################################################### +def index(): + return dict(databases=databases) + + +# ########################################################## +# ## insert a new record +# ########################################################### + + +def insert(): + (db, table) = get_table(request) + form = SQLFORM(db[table], ignore_rw=ignore_rw) + if form.accepts(request.vars, session): + response.flash = T('new record inserted') + return dict(form=form, table=db[table]) + + +# ########################################################## +# ## list all records in table and insert new record +# ########################################################### + + +def download(): + import os + db = get_database(request) + return response.download(request, db) + + +def csv(): + import gluon.contenttype + response.headers['Content-Type'] = \ + gluon.contenttype.contenttype('.csv') + db = get_database(request) + query = get_query(request) + if not query: + return None + response.headers['Content-disposition'] = 'attachment; filename=%s_%s.csv'\ + % tuple(request.vars.query.split('.')[:2]) + return str(db(query, ignore_common_filters=True).select()) + + +def import_csv(table, file): + table.import_from_csv_file(file) + + +def select(): + import re + db = get_database(request) + dbname = request.args[0] + try: + is_imap = db._uri.startswith("imap://") + except (KeyError, AttributeError, TypeError): + is_imap = False + regex = re.compile('(?P\w+)\.(?P\w+)=(?P\d+)') + if len(request.args) > 1 and hasattr(db[request.args[1]], '_primarykey'): + regex = re.compile('(?P
    \w+)\.(?P\w+)=(?P.+)') + if request.vars.query: + match = regex.match(request.vars.query) + if match: + request.vars.query = '%s.%s.%s==%s' % (request.args[0], + match.group('table'), match.group('field'), + match.group('value')) + else: + request.vars.query = session.last_query + query = get_query(request) + if request.vars.start: + start = int(request.vars.start) + else: + start = 0 + nrows = 0 + + step = 100 + fields = [] + + if is_imap: + step = 3 + + stop = start + step + + table = None + rows = [] + orderby = request.vars.orderby + if orderby: + orderby = dbname + '.' + orderby + if orderby == session.last_orderby: + if orderby[0] == '~': + orderby = orderby[1:] + else: + orderby = '~' + orderby + session.last_orderby = orderby + session.last_query = request.vars.query + form = FORM(TABLE(TR(T('Query:'), '', INPUT(_style='width:400px', + _name='query', _value=request.vars.query or '', _class="form-control", + requires=IS_NOT_EMPTY( + error_message=T("Cannot be empty")))), TR(T('Update:'), + INPUT(_name='update_check', _type='checkbox', + value=False), INPUT(_style='width:400px', + _name='update_fields', _value=request.vars.update_fields + or '', _class="form-control")), TR(T('Delete:'), INPUT(_name='delete_check', + _class='delete', _type='checkbox', value=False), ''), + TR('', '', INPUT(_type='submit', _value=T('submit'), _class="btn btn-primary"))), + _action=URL(r=request, args=request.args)) + + tb = None + if form.accepts(request.vars, formname=None): + regex = re.compile(request.args[0] + '\.(?P
    \w+)\..+') + match = regex.match(form.vars.query.strip()) + if match: + table = match.group('table') + try: + nrows = db(query, ignore_common_filters=True).count() + if form.vars.update_check and form.vars.update_fields: + db(query, ignore_common_filters=True).update( + **eval_in_global_env('dict(%s)' % form.vars.update_fields)) + response.flash = T('%s %%{row} updated', nrows) + elif form.vars.delete_check: + db(query, ignore_common_filters=True).delete() + response.flash = T('%s %%{row} deleted', nrows) + nrows = db(query, ignore_common_filters=True).count() + + if is_imap: + fields = [db[table][name] for name in + ("id", "uid", "created", "to", + "sender", "subject")] + if orderby: + rows = db(query, ignore_common_filters=True).select( + *fields, limitby=(start, stop), + orderby=eval_in_global_env(orderby)) + else: + rows = db(query, ignore_common_filters=True).select( + *fields, limitby=(start, stop)) + except Exception as e: + import traceback + tb = traceback.format_exc() + (rows, nrows) = ([], 0) + response.flash = DIV(T('Invalid Query'), PRE(str(e))) + # begin handle upload csv + csv_table = table or request.vars.table + if csv_table: + formcsv = FORM(str(T('or import from csv file')) + " ", + INPUT(_type='file', _name='csvfile'), + INPUT(_type='hidden', _value=csv_table, _name='table'), + INPUT(_type='submit', _value=T('import'), _class="btn btn-primary")) + else: + formcsv = None + if formcsv and formcsv.process().accepted: + try: + import_csv(db[request.vars.table], + request.vars.csvfile.file) + response.flash = T('data uploaded') + except Exception as e: + response.flash = DIV(T('unable to parse csv file'), PRE(str(e))) + # end handle upload csv + + return dict( + form=form, + table=table, + start=start, + stop=stop, + step=step, + nrows=nrows, + rows=rows, + query=request.vars.query, + formcsv=formcsv, + tb=tb + ) + + +# ########################################################## +# ## edit delete one record +# ########################################################### + + +def update(): + (db, table) = get_table(request) + keyed = hasattr(db[table], '_primarykey') + record = None + db[table]._common_filter = None + if keyed: + key = [f for f in request.vars if f in db[table]._primarykey] + if key: + record = db(db[table][key[0]] == request.vars[key[ + 0]]).select().first() + else: + record = db(db[table].id == request.args( + 2)).select().first() + + if not record: + qry = query_by_table_type(table, db) + session.flash = T('record does not exist') + redirect(URL('select', args=request.args[:1], + vars=dict(query=qry))) + + if keyed: + for k in db[table]._primarykey: + db[table][k].writable = False + + form = SQLFORM( + db[table], record, deletable=True, delete_label=T('Check to delete'), + ignore_rw=ignore_rw and not keyed, + linkto=URL('select', + args=request.args[:1]), upload=URL(r=request, + f='download', args=request.args[:1])) + + if form.accepts(request.vars, session): + session.flash = T('done!') + qry = query_by_table_type(table, db) + redirect(URL('select', args=request.args[:1], + vars=dict(query=qry))) + return dict(form=form, table=db[table]) + + +# ########################################################## +# ## get global variables +# ########################################################### + + +def state(): + return dict() + + +def ccache(): + if is_gae: + form = FORM( + P(TAG.BUTTON(T("Clear CACHE?"), _type="submit", _name="yes", _value="yes"))) + else: + cache.ram.initialize() + cache.disk.initialize() + + form = FORM( + P(TAG.BUTTON( + T("Clear CACHE?"), _type="submit", _name="yes", _value="yes")), + P(TAG.BUTTON( + T("Clear RAM"), _type="submit", _name="ram", _value="ram")), + P(TAG.BUTTON( + T("Clear DISK"), _type="submit", _name="disk", _value="disk")), + ) + + if form.accepts(request.vars, session): + session.flash = "" + if is_gae: + if request.vars.yes: + cache.ram.clear() + session.flash += T("Cache Cleared") + else: + clear_ram = False + clear_disk = False + if request.vars.yes: + clear_ram = clear_disk = True + if request.vars.ram: + clear_ram = True + if request.vars.disk: + clear_disk = True + if clear_ram: + cache.ram.clear() + session.flash += T("Ram Cleared") + if clear_disk: + cache.disk.clear() + session.flash += T("Disk Cleared") + redirect(URL(r=request)) + + try: + from pympler.asizeof import asizeof + except ImportError: + asizeof = False + + import shelve + import os + import copy + import time + import math + from pydal.contrib import portalocker + + ram = { + 'entries': 0, + 'bytes': 0, + 'objects': 0, + 'hits': 0, + 'misses': 0, + 'ratio': 0, + 'oldest': time.time(), + 'keys': [] + } + + disk = copy.copy(ram) + total = copy.copy(ram) + disk['keys'] = [] + total['keys'] = [] + + def GetInHMS(seconds): + hours = math.floor(seconds / 3600) + seconds -= hours * 3600 + minutes = math.floor(seconds / 60) + seconds -= minutes * 60 + seconds = math.floor(seconds) + + return (hours, minutes, seconds) + + if is_gae: + gae_stats = cache.ram.client.get_stats() + try: + gae_stats['ratio'] = ((gae_stats['hits'] * 100) / + (gae_stats['hits'] + gae_stats['misses'])) + except ZeroDivisionError: + gae_stats['ratio'] = T("?") + gae_stats['oldest'] = GetInHMS(time.time() - gae_stats['oldest_item_age']) + total.update(gae_stats) + else: + # get ram stats directly from the cache object + ram_stats = cache.ram.stats[request.application] + ram['hits'] = ram_stats['hit_total'] - ram_stats['misses'] + ram['misses'] = ram_stats['misses'] + try: + ram['ratio'] = ram['hits'] * 100 / ram_stats['hit_total'] + except (KeyError, ZeroDivisionError): + ram['ratio'] = 0 + + for key, value in iteritems(cache.ram.storage): + if asizeof: + ram['bytes'] += asizeof(value[1]) + ram['objects'] += 1 + ram['entries'] += 1 + if value[0] < ram['oldest']: + ram['oldest'] = value[0] + ram['keys'].append((key, GetInHMS(time.time() - value[0]))) + + for key in cache.disk.storage: + value = cache.disk.storage[key] + if key == 'web2py_cache_statistics' and isinstance(value[1], dict): + disk['hits'] = value[1]['hit_total'] - value[1]['misses'] + disk['misses'] = value[1]['misses'] + try: + disk['ratio'] = disk['hits'] * 100 / value[1]['hit_total'] + except (KeyError, ZeroDivisionError): + disk['ratio'] = 0 + else: + if asizeof: + disk['bytes'] += asizeof(value[1]) + disk['objects'] += 1 + disk['entries'] += 1 + if value[0] < disk['oldest']: + disk['oldest'] = value[0] + disk['keys'].append((key, GetInHMS(time.time() - value[0]))) + + ram_keys = list(ram) # ['hits', 'objects', 'ratio', 'entries', 'keys', 'oldest', 'bytes', 'misses'] + ram_keys.remove('ratio') + ram_keys.remove('oldest') + for key in ram_keys: + total[key] = ram[key] + disk[key] + + try: + total['ratio'] = total['hits'] * 100 / (total['hits'] + + total['misses']) + except (KeyError, ZeroDivisionError): + total['ratio'] = 0 + + if disk['oldest'] < ram['oldest']: + total['oldest'] = disk['oldest'] + else: + total['oldest'] = ram['oldest'] + + ram['oldest'] = GetInHMS(time.time() - ram['oldest']) + disk['oldest'] = GetInHMS(time.time() - disk['oldest']) + total['oldest'] = GetInHMS(time.time() - total['oldest']) + + def key_table(keys): + return TABLE( + TR(TD(B(T('Key'))), TD(B(T('Time in Cache (h:m:s)')))), + *[TR(TD(k[0]), TD('%02d:%02d:%02d' % k[1])) for k in keys], + **dict(_class='cache-keys', + _style="border-collapse: separate; border-spacing: .5em;")) + + if not is_gae: + ram['keys'] = key_table(ram['keys']) + disk['keys'] = key_table(disk['keys']) + total['keys'] = key_table(total['keys']) + + return dict(form=form, total=total, + ram=ram, disk=disk, object_stats=asizeof != False) + + +def table_template(table): + from gluon.html import TR, TD, TABLE, TAG + + def FONT(*args, **kwargs): + return TAG.font(*args, **kwargs) + + def types(field): + f_type = field.type + if not isinstance(f_type,str): + return ' ' + elif f_type == 'string': + return field.length + elif f_type == 'id': + return B('pk') + elif f_type.startswith('reference') or \ + f_type.startswith('list:reference'): + return B('fk') + else: + return ' ' + + # This is horribe HTML but the only one graphiz understands + rows = [] + cellpadding = 4 + color = "#000000" + bgcolor = "#FFFFFF" + face = "Helvetica" + face_bold = "Helvetica Bold" + border = 0 + + rows.append(TR(TD(FONT(table, _face=face_bold, _color=bgcolor), + _colspan=3, _cellpadding=cellpadding, + _align="center", _bgcolor=color))) + for row in db[table]: + rows.append(TR(TD(FONT(row.name, _color=color, _face=face_bold), + _align="left", _cellpadding=cellpadding, + _border=border), + TD(FONT(row.type, _color=color, _face=face), + _align="left", _cellpadding=cellpadding, + _border=border), + TD(FONT(types(row), _color=color, _face=face), + _align="center", _cellpadding=cellpadding, + _border=border))) + return "< %s >" % TABLE(*rows, **dict(_bgcolor=bgcolor, _border=1, + _cellborder=0, _cellspacing=0) + ).xml() + +def manage(): + tables = manager_action['tables'] + if isinstance(tables[0], str): + db = manager_action.get('db', auth.db) + db = globals()[db] if isinstance(db, str) else db + tables = [db[table] for table in tables] + if request.args(0) == 'auth': + auth.table_user()._plural = T('Users') + auth.table_group()._plural = T('Roles') + auth.table_membership()._plural = T('Memberships') + auth.table_permission()._plural = T('Permissions') + if request.extension != 'load': + return dict(heading=manager_action.get('heading', + T('Manage %(action)s') % dict(action=request.args(0).replace('_', ' ').title())), + tablenames=[table._tablename for table in tables], + labels=[table._plural.title() for table in tables]) + + table = tables[request.args(1, cast=int)] + formname = '%s_grid' % table._tablename + linked_tables = orderby = None + if request.args(0) == 'auth': + auth.table_group()._id.readable = \ + auth.table_membership()._id.readable = \ + auth.table_permission()._id.readable = False + auth.table_membership().user_id.label = T('User') + auth.table_membership().group_id.label = T('Role') + auth.table_permission().group_id.label = T('Role') + auth.table_permission().name.label = T('Permission') + if table == auth.table_user(): + linked_tables = [auth.settings.table_membership_name] + elif table == auth.table_group(): + orderby = 'role' if not request.args(3) or '.group_id' not in request.args(3) else None + elif table == auth.table_permission(): + orderby = 'group_id' + kwargs = dict(user_signature=True, maxtextlength=1000, + orderby=orderby, linked_tables=linked_tables) + smartgrid_args = manager_action.get('smartgrid_args', {}) + kwargs.update(**smartgrid_args.get('DEFAULT', {})) + kwargs.update(**smartgrid_args.get(table._tablename, {})) + grid = SQLFORM.smartgrid(table, args=request.args[:2], formname=formname, **kwargs) + return grid + +def hooks(): + import functools + import inspect + list_op = ['_%s_%s' %(h,m) for h in ['before', 'after'] for m in ['insert','update','delete']] + tables = [] + with_build_it = False + for db_str in sorted(databases): + db = databases[db_str] + for t in db.tables: + method_hooks = [] + for op in list_op: + functions = [] + for f in getattr(db[t], op): + if hasattr(f, '__call__'): + try: + if isinstance(f, (functools.partial)): + f = f.func + filename = inspect.getsourcefile(f) + details = {'funcname':f.__name__, + 'filename':filename[len(request.folder):] if request.folder in filename else None, + 'lineno': inspect.getsourcelines(f)[1]} + if details['filename']: # Built in functions as delete_uploaded_files are not editable + details['url'] = URL(a='admin',c='default',f='edit', args=[request['application'], details['filename']],vars={'lineno':details['lineno']}) + if details['filename'] or with_build_it: + functions.append(details) + # compiled app and windows build don't support code inspection + except: + pass + if len(functions): + method_hooks.append({'name': op, 'functions':functions}) + if len(method_hooks): + tables.append({'name': "%s.%s" % (db_str, t), 'slug': IS_SLUG()("%s.%s" % (db_str,t))[0], 'method_hooks':method_hooks}) + # Render + ul_main = UL(_class='nav nav-list') + for t in tables: + ul_main.append(A(t['name'], _onclick="collapse('a_%s')" % t['slug'])) + ul_t = UL(_class='nav nav-list', _id="a_%s" % t['slug'], _style='display:none') + for op in t['method_hooks']: + ul_t.append(LI(op['name'])) + ul_t.append(UL([LI(A(f['funcname'], _class="editor_filelink", _href=f['url']if 'url' in f else None, **{'_data-lineno':f['lineno']-1})) for f in op['functions']])) + ul_main.append(ul_t) + return ul_main + + +# ########################################################## +# d3 based model visualizations +# ########################################################### + +def d3_graph_model(): + """ See https://www.facebook.com/web2py/posts/145613995589010 from Bruno Rocha + and also the app_admin bg_graph_model function + + Create a list of table dicts, called "nodes" + """ + + nodes = [] + links = [] + + for database in databases: + db = eval_in_global_env(database) + for tablename in db.tables: + fields = [] + for field in db[tablename]: + f_type = field.type + if not isinstance(f_type, str): + disp = ' ' + elif f_type == 'string': + disp = field.length + elif f_type == 'id': + disp = "PK" + elif f_type.startswith('reference') or \ + f_type.startswith('list:reference'): + disp = "FK" + else: + disp = ' ' + fields.append(dict(name=field.name, type=field.type, disp=disp)) + + if isinstance(f_type, str) and ( + f_type.startswith('reference') or + f_type.startswith('list:reference')): + referenced_table = f_type.split()[1].split('.')[0] + + links.append(dict(source=tablename, target = referenced_table)) + + nodes.append(dict(name=tablename, type="table", fields = fields)) + + # d3 v4 allows individual modules to be specified. The complete d3 library is included below. + response.files.append(URL('admin','static','js/d3.min.js')) + response.files.append(URL('admin','static','js/d3_graph.js')) + return dict(databases=databases, nodes=nodes, links=links) diff --git a/web2py/applications/welcome/controllers/default.py b/web2py/applications/welcome/controllers/default.py new file mode 100644 index 0000000..2225081 --- /dev/null +++ b/web2py/applications/welcome/controllers/default.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------- +# This is a sample controller +# this file is released under public domain and you can use without limitations +# ------------------------------------------------------------------------- + +# ---- example index page ---- +def index(): + response.flash = T("Hello World") + return dict(message=T('Welcome to web2py!')) + +# ---- API (example) ----- +@auth.requires_login() +def api_get_user_email(): + if not request.env.request_method == 'GET': raise HTTP(403) + return response.json({'status':'success', 'email':auth.user.email}) + +# ---- Smart Grid (example) ----- +@auth.requires_membership('admin') # can only be accessed by members of admin groupd +def grid(): + response.view = 'generic.html' # use a generic view + tablename = request.args(0) + if not tablename in db.tables: raise HTTP(403) + grid = SQLFORM.smartgrid(db[tablename], args=[tablename], deletable=False, editable=False) + return dict(grid=grid) + +# ---- Embedded wiki (example) ---- +def wiki(): + auth.wikimenu() # add the wiki to the menu + return auth.wiki() + +# ---- Action for login/register/etc (required for auth) ----- +def user(): + """ + exposes: + http://..../[app]/default/user/login + http://..../[app]/default/user/logout + http://..../[app]/default/user/register + http://..../[app]/default/user/profile + http://..../[app]/default/user/retrieve_password + http://..../[app]/default/user/change_password + http://..../[app]/default/user/bulk_register + use @auth.requires_login() + @auth.requires_membership('group name') + @auth.requires_permission('read','table name',record_id) + to decorate functions that need access control + also notice there is http://..../[app]/appadmin/manage/auth to allow administrator to manage users + """ + return dict(form=auth()) + +# ---- action to server uploaded static content (required) --- +@cache.action() +def download(): + """ + allows downloading of uploaded files + http://..../[app]/default/download/[filename] + """ + return response.download(request, db) diff --git a/web2py/applications/welcome/cron/crontab b/web2py/applications/welcome/cron/crontab new file mode 100644 index 0000000..6ab4ea8 --- /dev/null +++ b/web2py/applications/welcome/cron/crontab @@ -0,0 +1 @@ +#crontab \ No newline at end of file diff --git a/web2py/applications/welcome/cron/crontab.example b/web2py/applications/welcome/cron/crontab.example new file mode 100644 index 0000000..6ab4ea8 --- /dev/null +++ b/web2py/applications/welcome/cron/crontab.example @@ -0,0 +1 @@ +#crontab \ No newline at end of file diff --git a/web2py/applications/welcome/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_cas.table b/web2py/applications/welcome/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_cas.table new file mode 100644 index 0000000000000000000000000000000000000000..2e3b45b88ccabf2fc43255af4224d63f189f4420 GIT binary patch literal 684 zcmZXSOK;Oa5P+R`8d4rDr94`?T{t)wq#|+X(Q=nI3U({UNZV87CQH}CtQlvQs0T~E z=3g`G1gOHzvorJUH#@#>l;F6$?l?|5gIWo7m$xyk5_p5YVeoG@Vg+#JB8mvY4z=eOWV=h?$FGg5ujHJa(nEmCdDW zEoFODmmR)qyTmt92sITXFQtVxL*WLZ6KZ{aZzeYcC&=%aEM0FDz!n z_r|_=#t4C@vR66LwE=}^vM;v{?;&xPm>T_wj`OBT;yP7woLY#uEz=8 zUjH#)LnypK@V=?KbUOVmG#r$0xWR47j{G0?7GZW4x@x3wgscOz+M-Zm0i=ZE4OANy j?O$}0=b1 zuX&w~g38VB*U!)U*f*^T9G5p8$5C@=RM2#J7lTaX3oW4)IL$gXxdJ1gz2QBq<}00> zEQ8L5_c1J2g-*X^0=kn1Z(~CLS_|mO25;FaWYFiQcp8T>`@|x06^#Qgx+W8LO}wx1 zs7O*geJ>J2-B2SkB1~rPRIfZ?`XVdAA0zWxpoH_zVTx9`s35z_Z9eT$*+7~zMew$YTLNYM7<3ZCqs+lW5G z$wGV=g~(@uq(;lcPQX*V=L6RM*cq{pEMlS0ri5<0C~>WI=j1XZ7wij*8S%ZT?_DrL z;2G+&j?y~?6rQ81V^eRlD%3*da8kjG9Z?c!`xoE2)V s)hY*4!D$V=**;Jgx2*q*_^E;7S~iFokKqiVBMbe9K;bo#i7{_}1MJhXX#fBK literal 0 HcmV?d00001 diff --git a/web2py/applications/welcome/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_group.table b/web2py/applications/welcome/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_group.table new file mode 100644 index 0000000000000000000000000000000000000000..cb6ec31f5ca9ab8410f8096bf6150ccbfd6c0028 GIT binary patch literal 361 zcmYk1OH0E*5XbXs)2EO6IM+SJi=f~K2xZX_8YM*7o}}8PyAU^>bQkpy=r!Nk$qM3a ze)AuGGjs48a3bb8jw3hVHsD39k5F>8)dKvb<5@OJg5eOfEW}h*TA8whUdslE`>NLK zw~|9Yby2SM&I#cuKNGPM0(*V90tn zSF800hmlngxgjuS!>+yleEp3k!ZkLnE8IG5;3yK^sUm1auND2&6QMnOuWPBca4ZJa zuy~B~=>GQZ8cxK>4v@}3;8aY+)UYvb+3@{)Eq7X03T6$QS@Yq~?4#Mf$iFn4qql>C UvH~tpIYl7<3L;ufm%Zh6CDG>Ew0!S?Y3AXo%RcVkzOh3JyK4w7gOCX3bj@i#v3nrr0wp zSoXwFB1*ng6L7>`di4twksA_`Fd%b;f4VU8)bR^63(<(&k(i*sp9lVkAOy#}qfPir zfZ>F9c~9v7SQok2DptRO!5@|_S;PM~>jwN&^Z-a!*yDrj8WSP8thwh{Uyj&DelI z<>v9sym=mf6f&@Ep0_M396~OGyv@rPL?Rxg5(-@_Z(YI{9)&3tn2x4VwtCmq%&&SUSc?YTbd zGOq_UUc$O04qgS+4T^?C3JbiZuYKC|`CVdW^WvgX>%} zLSRMKc^wh-M}oqtY{*4ryv-Au8LZ7&70^mAc$y|*Jc4!f&~I~Z9N#`aJv)XC#Oea7 z2^2OF*;Hnb+3~=DTN!N4fs3*t|I@aS*3h)yW(qsVY^krEisx}M)EnH*U~djtLRbCW fVVsJQNMIjjb^QI0aDeay4Nrb36b_NStJKLSqMDeV literal 0 HcmV?d00001 diff --git a/web2py/applications/welcome/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_user.table b/web2py/applications/welcome/databases/c8b669d15150d7109e5f7ab36744a5b7_auth_user.table new file mode 100644 index 0000000000000000000000000000000000000000..d21db7790ab2e88657e3bf7ff0ed503a56f7a914 GIT binary patch literal 807 zcmZwF!B5*T6bA6LX`52YfR4fFHYnc4(hCwulektWVpY{LMV(|$Ri=7%w2<;8u@DDK zT>D@1VpP~dZ?T{K`~05rU~5<|FI$!sPEpb*ySzq=NW`;D!X8>>vsQ5kB~V##hpO>B zi&Ye%y5MzMrt>5Ven$eeL5WvrBfGy9aAb+wc@+`r{D{8#qp^4C`JJDBf7tV{I|J{! z)B82P>W?mbZ|IH2SmRYXm&C!1K*LZhoHDHQwR}6cn>>}8vZQ!}w*G`knoZ2{4UIRh zvg<^B#dX+ly$>g{OI}a>DhS~Te88Mq_7u;VOuukhB7CkV2QUh z-u{o<(vh#l9TL}b@%bvlI|5tEG$w9>Fv70J9$_@v=ciVR+V|75F5Z)tkDHl$4ErSQ zDl_uiAWiS)$rNpk4+X4BSo_~*4fc_+d}M5SmEjY4ZN;}}HxaXt<`iV%Jf8d&_c+iv zEV#9mkL-}!%H1Nta76xrGSx(+BAYCuO#;*STu5+MCVZiUou`B%!tj+cnBtqo9_VjA Z*7#NksILrgDPa3m3;B=NCH+{blSjeZ(N_Qf literal 0 HcmV?d00001 diff --git a/web2py/applications/welcome/databases/sql.log b/web2py/applications/welcome/databases/sql.log new file mode 100644 index 0000000..aa91d0b --- /dev/null +++ b/web2py/applications/welcome/databases/sql.log @@ -0,0 +1,55 @@ +timestamp: 2018-09-23T16:05:31.878979 +CREATE TABLE "auth_user"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "first_name" CHAR(128), + "last_name" CHAR(128), + "email" CHAR(512), + "password" CHAR(512), + "registration_key" CHAR(512), + "reset_password_key" CHAR(512), + "registration_id" CHAR(512) +); +success! +timestamp: 2018-09-23T16:05:31.882638 +CREATE TABLE "auth_group"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "role" CHAR(512), + "description" TEXT +); +success! +timestamp: 2018-09-23T16:05:31.885441 +CREATE TABLE "auth_membership"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "user_id" INTEGER REFERENCES "auth_user" ("id") ON DELETE CASCADE , + "group_id" INTEGER REFERENCES "auth_group" ("id") ON DELETE CASCADE +); +success! +timestamp: 2018-09-23T16:05:31.888929 +CREATE TABLE "auth_permission"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "group_id" INTEGER REFERENCES "auth_group" ("id") ON DELETE CASCADE , + "name" CHAR(512), + "table_name" CHAR(512), + "record_id" INTEGER +); +success! +timestamp: 2018-09-23T16:05:31.892277 +CREATE TABLE "auth_event"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "time_stamp" TIMESTAMP, + "client_ip" CHAR(512), + "user_id" INTEGER REFERENCES "auth_user" ("id") ON DELETE CASCADE , + "origin" CHAR(512), + "description" TEXT +); +success! +timestamp: 2018-09-23T16:05:31.895464 +CREATE TABLE "auth_cas"( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "user_id" INTEGER REFERENCES "auth_user" ("id") ON DELETE CASCADE , + "created_on" TIMESTAMP, + "service" CHAR(512), + "ticket" CHAR(512), + "renew" CHAR(1) +); +success! diff --git a/web2py/applications/welcome/databases/storage.sqlite b/web2py/applications/welcome/databases/storage.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..b599301ffb27ca55909713715c101cc889ea9972 GIT binary patch literal 32768 zcmeI#&u-H&90%}Zf11(Ji4)~A&5JlR+Jv+Lf+L|bP_cGf8YFg#veetGHErjls}L8q z@d`Ww@4=NDPr$R_qz&oX454bL=o=}DouA{xAOB*>&4XPYGIHD%z8jLK$^%7Jl~;r) zic*m0l01_msxKrJc~!^Cw-pP@lgD35GOFGCrmXy28I*qC|F!(1_+3_UKmY;|fB*y_ z009Uj0#_wXE3dAq*M8_8wVB%wPaV$6L{Dz(l_HUc&RaUEHEjBp zT4dj<)lKV=yr+l6{9y0Z8uHmXZP=T`w*7z!XZ!(+zM&RvRB3b6anwR5m8e&P>@~;^ z-KFx~RkK+&cPJsFjy%EKkhPp{M<;fzPMfw_-yg+f4;S2HI;p-ht;+MQZDSM&xp&6G z>HC6p*kE*f%P1OGj|y6OeOA`qyE??|$ z8JZlzKf_fsxm^$3|E?=VBiftGO+O9@KmY;|fB*y_009U<00Izz00eR@fc<}tCl^D500bZa0SG_< z0uX=z1Rwwb2#f@<|3@l700Izz00bZa0SG_<0uX=z1oAI{{eS-F7$bxL1Rwwb2tWV= z5P$##AOHafVE>OCfB*y_009U<00Izz00bZa0SM$@0Q>*^&oM>_0SG_<0uX=z1Rwwb i2tWV=5WxN)IRF6&KmY;|fB*y_009U<00I!mzrY_8_TKCO literal 0 HcmV?d00001 diff --git a/web2py/applications/welcome/errors/127.0.0.1.2018-09-23.15-56-32.fefc955a-9a46-4bc3-8ca4-d5816b0a2c0d b/web2py/applications/welcome/errors/127.0.0.1.2018-09-23.15-56-32.fefc955a-9a46-4bc3-8ca4-d5816b0a2c0d new file mode 100644 index 0000000000000000000000000000000000000000..41b39b26a3258c46f08acab18f18f79f9beb821c GIT binary patch literal 48100 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 OFQml_aq->hsQ({;EJVTp literal 0 HcmV?d00001 diff --git a/web2py/applications/welcome/errors/127.0.0.1.2018-09-23.15-59-22.e4fdb3d9-eee4-4157-9821-43eb9f5eaff7 b/web2py/applications/welcome/errors/127.0.0.1.2018-09-23.15-59-22.e4fdb3d9-eee4-4157-9821-43eb9f5eaff7 new file mode 100644 index 0000000000000000000000000000000000000000..532b333af4d5620a9ba70d5c593b0dc979a8df0f GIT binary patch literal 48262 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'] + for row in rows: + hrow = [''] + for cell in row: + hrow.append('') + hrow.append('') + hlines.append(''.join(hrow)) + hlines += ['', '
    ` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n font-size: $font-size-base;\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Suppress the focus outline on elements that cannot be accessed via keyboard.\n// This prevents an unwanted focus outline from appearing around elements that\n// might still respond to pointer events.\n//\n// Credit: https://github.com/suitcss/base\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `

    `-`

    ` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n// stylelint-enable selector-list-comma-newline-after\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `

    `s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Remove the bottom border in Firefox 39-.\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Duplicate behavior to the data-* attribute for our tooltip plugin\n\nabbr[title],\nabbr[data-original-title] { // 4\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 1\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic; // Add the correct font style in Android 4.3-\n}\n\n// stylelint-disable font-weight-notation\nb,\nstrong {\n font-weight: bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n// stylelint-enable font-weight-notation\n\nsmall {\n font-size: 80%; // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n -webkit-text-decoration-skip: objects; // Remove gaps in links underline in iOS 8+ and Safari 8+.\n\n @include hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href)\n// which have not been made explicitly keyboard-focusable (without tabindex).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n\n @include hover-focus {\n color: inherit;\n text-decoration: none;\n }\n\n &:focus {\n outline: 0;\n }\n}\n\n\n//\n// Code\n//\n\n// stylelint-disable font-family-no-duplicate-names\npre,\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; // Correct the inheritance and scaling of font size in all browsers.\n font-size: 1em; // Correct the odd `em` font sizing in all browsers.\n}\n// stylelint-enable font-family-no-duplicate-names\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // We have @viewport set which causes scrollbars to overlap content in IE11 and Edge, so\n // we force a non-overlapping, non-auto-hiding scrollbar to counteract.\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg:not(:root) {\n overflow: hidden; // Hide the overflow in IE\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $text-muted;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n // Matches default `

    ` alignment by inheriting from the ``, or the\n // closest parent with a set `text-align`.\n text-align: inherit;\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: .5rem;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n border-radius: 0;\n}\n\n// Work around a Firefox/IE bug where the transparent `button` background\n// results in a loss of the default `button` focus styles.\n//\n// Credit: https://github.com/suitcss/base/\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\nhtml [type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n // Remove the default appearance of temporal inputs to avoid a Mobile Safari\n // bug where setting a custom line-height prevents text from being vertically\n // centered within the input.\n // See https://bugs.webkit.org/show_bug.cgi?id=139848\n // and https://github.com/twbs/bootstrap/issues/11266\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. `
    `s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding and cancel buttons in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n cursor: pointer;\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","/*!\n * Bootstrap v4.0.0 (https://getbootstrap.com)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n:root {\n --blue: #007bff;\n --indigo: #6610f2;\n --purple: #6f42c1;\n --pink: #e83e8c;\n --red: #dc3545;\n --orange: #fd7e14;\n --yellow: #ffc107;\n --green: #28a745;\n --teal: #20c997;\n --cyan: #17a2b8;\n --white: #fff;\n --gray: #6c757d;\n --gray-dark: #343a40;\n --primary: #007bff;\n --secondary: #6c757d;\n --success: #28a745;\n --info: #17a2b8;\n --warning: #ffc107;\n --danger: #dc3545;\n --light: #f8f9fa;\n --dark: #343a40;\n --breakpoint-xs: 0;\n --breakpoint-sm: 576px;\n --breakpoint-md: 768px;\n --breakpoint-lg: 992px;\n --breakpoint-xl: 1200px;\n --font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n -ms-overflow-style: scrollbar;\n -webkit-tap-highlight-color: transparent;\n}\n\n@-ms-viewport {\n width: device-width;\n}\n\narticle, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n -webkit-text-decoration-skip: objects;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus {\n outline: 0;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: .5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\nbutton,\nhtml [type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: 0.5rem;\n font-family: inherit;\n font-weight: 500;\n line-height: 1.2;\n color: inherit;\n}\n\nh1, .h1 {\n font-size: 2.5rem;\n}\n\nh2, .h2 {\n font-size: 2rem;\n}\n\nh3, .h3 {\n font-size: 1.75rem;\n}\n\nh4, .h4 {\n font-size: 1.5rem;\n}\n\nh5, .h5 {\n font-size: 1.25rem;\n}\n\nh6, .h6 {\n font-size: 1rem;\n}\n\n.lead {\n font-size: 1.25rem;\n font-weight: 300;\n}\n\n.display-1 {\n font-size: 6rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-2 {\n font-size: 5.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-3 {\n font-size: 4.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-4 {\n font-size: 3.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\nhr {\n margin-top: 1rem;\n margin-bottom: 1rem;\n border: 0;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\nsmall,\n.small {\n font-size: 80%;\n font-weight: 400;\n}\n\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline-item {\n display: inline-block;\n}\n\n.list-inline-item:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n.blockquote {\n margin-bottom: 1rem;\n font-size: 1.25rem;\n}\n\n.blockquote-footer {\n display: block;\n font-size: 80%;\n color: #6c757d;\n}\n\n.blockquote-footer::before {\n content: \"\\2014 \\00A0\";\n}\n\n.img-fluid {\n max-width: 100%;\n height: auto;\n}\n\n.img-thumbnail {\n padding: 0.25rem;\n background-color: #fff;\n border: 1px solid #dee2e6;\n border-radius: 0.25rem;\n max-width: 100%;\n height: auto;\n}\n\n.figure {\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: 0.5rem;\n line-height: 1;\n}\n\n.figure-caption {\n font-size: 90%;\n color: #6c757d;\n}\n\ncode,\nkbd,\npre,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\ncode {\n font-size: 87.5%;\n color: #e83e8c;\n word-break: break-word;\n}\n\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.2rem 0.4rem;\n font-size: 87.5%;\n color: #fff;\n background-color: #212529;\n border-radius: 0.2rem;\n}\n\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n}\n\npre {\n display: block;\n font-size: 87.5%;\n color: #212529;\n}\n\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n\n.container {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container {\n max-width: 1140px;\n }\n}\n\n.container-fluid {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n.row {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n min-height: 1px;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -webkit-box-flex: 1;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.col-auto {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n}\n\n.col-1 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n -webkit-box-ordinal-group: 0;\n -ms-flex-order: -1;\n order: -1;\n}\n\n.order-last {\n -webkit-box-ordinal-group: 14;\n -ms-flex-order: 13;\n order: 13;\n}\n\n.order-0 {\n -webkit-box-ordinal-group: 1;\n -ms-flex-order: 0;\n order: 0;\n}\n\n.order-1 {\n -webkit-box-ordinal-group: 2;\n -ms-flex-order: 1;\n order: 1;\n}\n\n.order-2 {\n -webkit-box-ordinal-group: 3;\n -ms-flex-order: 2;\n order: 2;\n}\n\n.order-3 {\n -webkit-box-ordinal-group: 4;\n -ms-flex-order: 3;\n order: 3;\n}\n\n.order-4 {\n -webkit-box-ordinal-group: 5;\n -ms-flex-order: 4;\n order: 4;\n}\n\n.order-5 {\n -webkit-box-ordinal-group: 6;\n -ms-flex-order: 5;\n order: 5;\n}\n\n.order-6 {\n -webkit-box-ordinal-group: 7;\n -ms-flex-order: 6;\n order: 6;\n}\n\n.order-7 {\n -webkit-box-ordinal-group: 8;\n -ms-flex-order: 7;\n order: 7;\n}\n\n.order-8 {\n -webkit-box-ordinal-group: 9;\n -ms-flex-order: 8;\n order: 8;\n}\n\n.order-9 {\n -webkit-box-ordinal-group: 10;\n -ms-flex-order: 9;\n order: 9;\n}\n\n.order-10 {\n -webkit-box-ordinal-group: 11;\n -ms-flex-order: 10;\n order: 10;\n}\n\n.order-11 {\n -webkit-box-ordinal-group: 12;\n -ms-flex-order: 11;\n order: 11;\n}\n\n.order-12 {\n -webkit-box-ordinal-group: 13;\n -ms-flex-order: 12;\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -webkit-box-flex: 1;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-sm-auto {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-sm-1 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n -webkit-box-ordinal-group: 0;\n -ms-flex-order: -1;\n order: -1;\n }\n .order-sm-last {\n -webkit-box-ordinal-group: 14;\n -ms-flex-order: 13;\n order: 13;\n }\n .order-sm-0 {\n -webkit-box-ordinal-group: 1;\n -ms-flex-order: 0;\n order: 0;\n }\n .order-sm-1 {\n -webkit-box-ordinal-group: 2;\n -ms-flex-order: 1;\n order: 1;\n }\n .order-sm-2 {\n -webkit-box-ordinal-group: 3;\n -ms-flex-order: 2;\n order: 2;\n }\n .order-sm-3 {\n -webkit-box-ordinal-group: 4;\n -ms-flex-order: 3;\n order: 3;\n }\n .order-sm-4 {\n -webkit-box-ordinal-group: 5;\n -ms-flex-order: 4;\n order: 4;\n }\n .order-sm-5 {\n -webkit-box-ordinal-group: 6;\n -ms-flex-order: 5;\n order: 5;\n }\n .order-sm-6 {\n -webkit-box-ordinal-group: 7;\n -ms-flex-order: 6;\n order: 6;\n }\n .order-sm-7 {\n -webkit-box-ordinal-group: 8;\n -ms-flex-order: 7;\n order: 7;\n }\n .order-sm-8 {\n -webkit-box-ordinal-group: 9;\n -ms-flex-order: 8;\n order: 8;\n }\n .order-sm-9 {\n -webkit-box-ordinal-group: 10;\n -ms-flex-order: 9;\n order: 9;\n }\n .order-sm-10 {\n -webkit-box-ordinal-group: 11;\n -ms-flex-order: 10;\n order: 10;\n }\n .order-sm-11 {\n -webkit-box-ordinal-group: 12;\n -ms-flex-order: 11;\n order: 11;\n }\n .order-sm-12 {\n -webkit-box-ordinal-group: 13;\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -webkit-box-flex: 1;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-md-auto {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-md-1 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n -webkit-box-ordinal-group: 0;\n -ms-flex-order: -1;\n order: -1;\n }\n .order-md-last {\n -webkit-box-ordinal-group: 14;\n -ms-flex-order: 13;\n order: 13;\n }\n .order-md-0 {\n -webkit-box-ordinal-group: 1;\n -ms-flex-order: 0;\n order: 0;\n }\n .order-md-1 {\n -webkit-box-ordinal-group: 2;\n -ms-flex-order: 1;\n order: 1;\n }\n .order-md-2 {\n -webkit-box-ordinal-group: 3;\n -ms-flex-order: 2;\n order: 2;\n }\n .order-md-3 {\n -webkit-box-ordinal-group: 4;\n -ms-flex-order: 3;\n order: 3;\n }\n .order-md-4 {\n -webkit-box-ordinal-group: 5;\n -ms-flex-order: 4;\n order: 4;\n }\n .order-md-5 {\n -webkit-box-ordinal-group: 6;\n -ms-flex-order: 5;\n order: 5;\n }\n .order-md-6 {\n -webkit-box-ordinal-group: 7;\n -ms-flex-order: 6;\n order: 6;\n }\n .order-md-7 {\n -webkit-box-ordinal-group: 8;\n -ms-flex-order: 7;\n order: 7;\n }\n .order-md-8 {\n -webkit-box-ordinal-group: 9;\n -ms-flex-order: 8;\n order: 8;\n }\n .order-md-9 {\n -webkit-box-ordinal-group: 10;\n -ms-flex-order: 9;\n order: 9;\n }\n .order-md-10 {\n -webkit-box-ordinal-group: 11;\n -ms-flex-order: 10;\n order: 10;\n }\n .order-md-11 {\n -webkit-box-ordinal-group: 12;\n -ms-flex-order: 11;\n order: 11;\n }\n .order-md-12 {\n -webkit-box-ordinal-group: 13;\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -webkit-box-flex: 1;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-lg-auto {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-lg-1 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n -webkit-box-ordinal-group: 0;\n -ms-flex-order: -1;\n order: -1;\n }\n .order-lg-last {\n -webkit-box-ordinal-group: 14;\n -ms-flex-order: 13;\n order: 13;\n }\n .order-lg-0 {\n -webkit-box-ordinal-group: 1;\n -ms-flex-order: 0;\n order: 0;\n }\n .order-lg-1 {\n -webkit-box-ordinal-group: 2;\n -ms-flex-order: 1;\n order: 1;\n }\n .order-lg-2 {\n -webkit-box-ordinal-group: 3;\n -ms-flex-order: 2;\n order: 2;\n }\n .order-lg-3 {\n -webkit-box-ordinal-group: 4;\n -ms-flex-order: 3;\n order: 3;\n }\n .order-lg-4 {\n -webkit-box-ordinal-group: 5;\n -ms-flex-order: 4;\n order: 4;\n }\n .order-lg-5 {\n -webkit-box-ordinal-group: 6;\n -ms-flex-order: 5;\n order: 5;\n }\n .order-lg-6 {\n -webkit-box-ordinal-group: 7;\n -ms-flex-order: 6;\n order: 6;\n }\n .order-lg-7 {\n -webkit-box-ordinal-group: 8;\n -ms-flex-order: 7;\n order: 7;\n }\n .order-lg-8 {\n -webkit-box-ordinal-group: 9;\n -ms-flex-order: 8;\n order: 8;\n }\n .order-lg-9 {\n -webkit-box-ordinal-group: 10;\n -ms-flex-order: 9;\n order: 9;\n }\n .order-lg-10 {\n -webkit-box-ordinal-group: 11;\n -ms-flex-order: 10;\n order: 10;\n }\n .order-lg-11 {\n -webkit-box-ordinal-group: 12;\n -ms-flex-order: 11;\n order: 11;\n }\n .order-lg-12 {\n -webkit-box-ordinal-group: 13;\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -webkit-box-flex: 1;\n -ms-flex-positive: 1;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-xl-auto {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-xl-1 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 8.333333%;\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 16.666667%;\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 25%;\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 41.666667%;\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 58.333333%;\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 75%;\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 83.333333%;\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 91.666667%;\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n -webkit-box-flex: 0;\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n -webkit-box-ordinal-group: 0;\n -ms-flex-order: -1;\n order: -1;\n }\n .order-xl-last {\n -webkit-box-ordinal-group: 14;\n -ms-flex-order: 13;\n order: 13;\n }\n .order-xl-0 {\n -webkit-box-ordinal-group: 1;\n -ms-flex-order: 0;\n order: 0;\n }\n .order-xl-1 {\n -webkit-box-ordinal-group: 2;\n -ms-flex-order: 1;\n order: 1;\n }\n .order-xl-2 {\n -webkit-box-ordinal-group: 3;\n -ms-flex-order: 2;\n order: 2;\n }\n .order-xl-3 {\n -webkit-box-ordinal-group: 4;\n -ms-flex-order: 3;\n order: 3;\n }\n .order-xl-4 {\n -webkit-box-ordinal-group: 5;\n -ms-flex-order: 4;\n order: 4;\n }\n .order-xl-5 {\n -webkit-box-ordinal-group: 6;\n -ms-flex-order: 5;\n order: 5;\n }\n .order-xl-6 {\n -webkit-box-ordinal-group: 7;\n -ms-flex-order: 6;\n order: 6;\n }\n .order-xl-7 {\n -webkit-box-ordinal-group: 8;\n -ms-flex-order: 7;\n order: 7;\n }\n .order-xl-8 {\n -webkit-box-ordinal-group: 9;\n -ms-flex-order: 8;\n order: 8;\n }\n .order-xl-9 {\n -webkit-box-ordinal-group: 10;\n -ms-flex-order: 9;\n order: 9;\n }\n .order-xl-10 {\n -webkit-box-ordinal-group: 11;\n -ms-flex-order: 10;\n order: 10;\n }\n .order-xl-11 {\n -webkit-box-ordinal-group: 12;\n -ms-flex-order: 11;\n order: 11;\n }\n .order-xl-12 {\n -webkit-box-ordinal-group: 13;\n -ms-flex-order: 12;\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 1rem;\n background-color: transparent;\n}\n\n.table th,\n.table td {\n padding: 0.75rem;\n vertical-align: top;\n border-top: 1px solid #dee2e6;\n}\n\n.table thead th {\n vertical-align: bottom;\n border-bottom: 2px solid #dee2e6;\n}\n\n.table tbody + tbody {\n border-top: 2px solid #dee2e6;\n}\n\n.table .table {\n background-color: #fff;\n}\n\n.table-sm th,\n.table-sm td {\n padding: 0.3rem;\n}\n\n.table-bordered {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered th,\n.table-bordered td {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered thead th,\n.table-bordered thead td {\n border-bottom-width: 2px;\n}\n\n.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.table-hover tbody tr:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-primary,\n.table-primary > th,\n.table-primary > td {\n background-color: #b8daff;\n}\n\n.table-hover .table-primary:hover {\n background-color: #9fcdff;\n}\n\n.table-hover .table-primary:hover > td,\n.table-hover .table-primary:hover > th {\n background-color: #9fcdff;\n}\n\n.table-secondary,\n.table-secondary > th,\n.table-secondary > td {\n background-color: #d6d8db;\n}\n\n.table-hover .table-secondary:hover {\n background-color: #c8cbcf;\n}\n\n.table-hover .table-secondary:hover > td,\n.table-hover .table-secondary:hover > th {\n background-color: #c8cbcf;\n}\n\n.table-success,\n.table-success > th,\n.table-success > td {\n background-color: #c3e6cb;\n}\n\n.table-hover .table-success:hover {\n background-color: #b1dfbb;\n}\n\n.table-hover .table-success:hover > td,\n.table-hover .table-success:hover > th {\n background-color: #b1dfbb;\n}\n\n.table-info,\n.table-info > th,\n.table-info > td {\n background-color: #bee5eb;\n}\n\n.table-hover .table-info:hover {\n background-color: #abdde5;\n}\n\n.table-hover .table-info:hover > td,\n.table-hover .table-info:hover > th {\n background-color: #abdde5;\n}\n\n.table-warning,\n.table-warning > th,\n.table-warning > td {\n background-color: #ffeeba;\n}\n\n.table-hover .table-warning:hover {\n background-color: #ffe8a1;\n}\n\n.table-hover .table-warning:hover > td,\n.table-hover .table-warning:hover > th {\n background-color: #ffe8a1;\n}\n\n.table-danger,\n.table-danger > th,\n.table-danger > td {\n background-color: #f5c6cb;\n}\n\n.table-hover .table-danger:hover {\n background-color: #f1b0b7;\n}\n\n.table-hover .table-danger:hover > td,\n.table-hover .table-danger:hover > th {\n background-color: #f1b0b7;\n}\n\n.table-light,\n.table-light > th,\n.table-light > td {\n background-color: #fdfdfe;\n}\n\n.table-hover .table-light:hover {\n background-color: #ececf6;\n}\n\n.table-hover .table-light:hover > td,\n.table-hover .table-light:hover > th {\n background-color: #ececf6;\n}\n\n.table-dark,\n.table-dark > th,\n.table-dark > td {\n background-color: #c6c8ca;\n}\n\n.table-hover .table-dark:hover {\n background-color: #b9bbbe;\n}\n\n.table-hover .table-dark:hover > td,\n.table-hover .table-dark:hover > th {\n background-color: #b9bbbe;\n}\n\n.table-active,\n.table-active > th,\n.table-active > td {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover > td,\n.table-hover .table-active:hover > th {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table .thead-dark th {\n color: #fff;\n background-color: #212529;\n border-color: #32383e;\n}\n\n.table .thead-light th {\n color: #495057;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.table-dark {\n color: #fff;\n background-color: #212529;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th {\n border-color: #32383e;\n}\n\n.table-dark.table-bordered {\n border: 0;\n}\n\n.table-dark.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(255, 255, 255, 0.05);\n}\n\n.table-dark.table-hover tbody tr:hover {\n background-color: rgba(255, 255, 255, 0.075);\n}\n\n@media (max-width: 575.98px) {\n .table-responsive-sm {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-sm > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 767.98px) {\n .table-responsive-md {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-md > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 991.98px) {\n .table-responsive-lg {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-lg > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 1199.98px) {\n .table-responsive-xl {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-xl > .table-bordered {\n border: 0;\n }\n}\n\n.table-responsive {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n}\n\n.table-responsive > .table-bordered {\n border: 0;\n}\n\n.form-control {\n display: block;\n width: 100%;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n\n.form-control:focus {\n color: #495057;\n background-color: #fff;\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.form-control::-webkit-input-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control::-moz-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:-ms-input-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control::-ms-input-placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control::placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:disabled, .form-control[readonly] {\n background-color: #e9ecef;\n opacity: 1;\n}\n\nselect.form-control:not([size]):not([multiple]) {\n height: calc(2.25rem + 2px);\n}\n\nselect.form-control:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n.col-form-label {\n padding-top: calc(0.375rem + 1px);\n padding-bottom: calc(0.375rem + 1px);\n margin-bottom: 0;\n font-size: inherit;\n line-height: 1.5;\n}\n\n.col-form-label-lg {\n padding-top: calc(0.5rem + 1px);\n padding-bottom: calc(0.5rem + 1px);\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.col-form-label-sm {\n padding-top: calc(0.25rem + 1px);\n padding-bottom: calc(0.25rem + 1px);\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n margin-bottom: 0;\n line-height: 1.5;\n background-color: transparent;\n border: solid transparent;\n border-width: 1px 0;\n}\n\n.form-control-plaintext.form-control-sm, .input-group-sm > .form-control-plaintext.form-control,\n.input-group-sm > .input-group-prepend > .form-control-plaintext.input-group-text,\n.input-group-sm > .input-group-append > .form-control-plaintext.input-group-text,\n.input-group-sm > .input-group-prepend > .form-control-plaintext.btn,\n.input-group-sm > .input-group-append > .form-control-plaintext.btn, .form-control-plaintext.form-control-lg, .input-group-lg > .form-control-plaintext.form-control,\n.input-group-lg > .input-group-prepend > .form-control-plaintext.input-group-text,\n.input-group-lg > .input-group-append > .form-control-plaintext.input-group-text,\n.input-group-lg > .input-group-prepend > .form-control-plaintext.btn,\n.input-group-lg > .input-group-append > .form-control-plaintext.btn {\n padding-right: 0;\n padding-left: 0;\n}\n\n.form-control-sm, .input-group-sm > .form-control,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\nselect.form-control-sm:not([size]):not([multiple]), .input-group-sm > select.form-control:not([size]):not([multiple]),\n.input-group-sm > .input-group-prepend > select.input-group-text:not([size]):not([multiple]),\n.input-group-sm > .input-group-append > select.input-group-text:not([size]):not([multiple]),\n.input-group-sm > .input-group-prepend > select.btn:not([size]):not([multiple]),\n.input-group-sm > .input-group-append > select.btn:not([size]):not([multiple]) {\n height: calc(1.8125rem + 2px);\n}\n\n.form-control-lg, .input-group-lg > .form-control,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\nselect.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.form-control:not([size]):not([multiple]),\n.input-group-lg > .input-group-prepend > select.input-group-text:not([size]):not([multiple]),\n.input-group-lg > .input-group-append > select.input-group-text:not([size]):not([multiple]),\n.input-group-lg > .input-group-prepend > select.btn:not([size]):not([multiple]),\n.input-group-lg > .input-group-append > select.btn:not([size]):not([multiple]) {\n height: calc(2.875rem + 2px);\n}\n\n.form-group {\n margin-bottom: 1rem;\n}\n\n.form-text {\n display: block;\n margin-top: 0.25rem;\n}\n\n.form-row {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -5px;\n margin-left: -5px;\n}\n\n.form-row > .col,\n.form-row > [class*=\"col-\"] {\n padding-right: 5px;\n padding-left: 5px;\n}\n\n.form-check {\n position: relative;\n display: block;\n padding-left: 1.25rem;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: 0.3rem;\n margin-left: -1.25rem;\n}\n\n.form-check-input:disabled ~ .form-check-label {\n color: #6c757d;\n}\n\n.form-check-label {\n margin-bottom: 0;\n}\n\n.form-check-inline {\n display: -webkit-inline-box;\n display: -ms-inline-flexbox;\n display: inline-flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n padding-left: 0;\n margin-right: 0.75rem;\n}\n\n.form-check-inline .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: 0.3125rem;\n margin-left: 0;\n}\n\n.valid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #28a745;\n}\n\n.valid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: .5rem;\n margin-top: .1rem;\n font-size: .875rem;\n line-height: 1;\n color: #fff;\n background-color: rgba(40, 167, 69, 0.8);\n border-radius: .2rem;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid, .was-validated\n.custom-select:valid,\n.custom-select.is-valid {\n border-color: #28a745;\n}\n\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus, .was-validated\n.custom-select:valid:focus,\n.custom-select.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .form-control:valid ~ .valid-feedback,\n.was-validated .form-control:valid ~ .valid-tooltip, .form-control.is-valid ~ .valid-feedback,\n.form-control.is-valid ~ .valid-tooltip, .was-validated\n.custom-select:valid ~ .valid-feedback,\n.was-validated\n.custom-select:valid ~ .valid-tooltip,\n.custom-select.is-valid ~ .valid-feedback,\n.custom-select.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n color: #28a745;\n}\n\n.was-validated .form-check-input:valid ~ .valid-feedback,\n.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback,\n.form-check-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label {\n color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before {\n background-color: #71dd8a;\n}\n\n.was-validated .custom-control-input:valid ~ .valid-feedback,\n.was-validated .custom-control-input:valid ~ .valid-tooltip, .custom-control-input.is-valid ~ .valid-feedback,\n.custom-control-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before {\n background-color: #34ce57;\n}\n\n.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label::before, .custom-file-input.is-valid ~ .custom-file-label::before {\n border-color: inherit;\n}\n\n.was-validated .custom-file-input:valid ~ .valid-feedback,\n.was-validated .custom-file-input:valid ~ .valid-tooltip, .custom-file-input.is-valid ~ .valid-feedback,\n.custom-file-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.invalid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #dc3545;\n}\n\n.invalid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: .5rem;\n margin-top: .1rem;\n font-size: .875rem;\n line-height: 1;\n color: #fff;\n background-color: rgba(220, 53, 69, 0.8);\n border-radius: .2rem;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid, .was-validated\n.custom-select:invalid,\n.custom-select.is-invalid {\n border-color: #dc3545;\n}\n\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus, .was-validated\n.custom-select:invalid:focus,\n.custom-select.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-control:invalid ~ .invalid-feedback,\n.was-validated .form-control:invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback,\n.form-control.is-invalid ~ .invalid-tooltip, .was-validated\n.custom-select:invalid ~ .invalid-feedback,\n.was-validated\n.custom-select:invalid ~ .invalid-tooltip,\n.custom-select.is-invalid ~ .invalid-feedback,\n.custom-select.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n color: #dc3545;\n}\n\n.was-validated .form-check-input:invalid ~ .invalid-feedback,\n.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback,\n.form-check-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label {\n color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before {\n background-color: #efa2a9;\n}\n\n.was-validated .custom-control-input:invalid ~ .invalid-feedback,\n.was-validated .custom-control-input:invalid ~ .invalid-tooltip, .custom-control-input.is-invalid ~ .invalid-feedback,\n.custom-control-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before {\n background-color: #e4606d;\n}\n\n.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label::before, .custom-file-input.is-invalid ~ .custom-file-label::before {\n border-color: inherit;\n}\n\n.was-validated .custom-file-input:invalid ~ .invalid-feedback,\n.was-validated .custom-file-input:invalid ~ .invalid-tooltip, .custom-file-input.is-invalid ~ .invalid-feedback,\n.custom-file-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.form-inline {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.form-inline .form-check {\n width: 100%;\n}\n\n@media (min-width: 576px) {\n .form-inline label {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n margin-bottom: 0;\n }\n .form-inline .form-group {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-flex: 0;\n -ms-flex: 0 0 auto;\n flex: 0 0 auto;\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n margin-bottom: 0;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-plaintext {\n display: inline-block;\n }\n .form-inline .input-group {\n width: auto;\n }\n .form-inline .form-check {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-inline .form-check-input {\n position: relative;\n margin-top: 0;\n margin-right: 0.25rem;\n margin-left: 0;\n }\n .form-inline .custom-control {\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n }\n .form-inline .custom-control-label {\n margin-bottom: 0;\n }\n}\n\n.btn {\n display: inline-block;\n font-weight: 400;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n border: 1px solid transparent;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.btn:hover, .btn:focus {\n text-decoration: none;\n}\n\n.btn:focus, .btn.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.btn.disabled, .btn:disabled {\n opacity: 0.65;\n}\n\n.btn:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.btn:not(:disabled):not(.disabled):active, .btn:not(:disabled):not(.disabled).active {\n background-image: none;\n}\n\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n.btn-primary {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:hover {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n}\n\n.btn-primary:focus, .btn-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-primary.disabled, .btn-primary:disabled {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active,\n.show > .btn-primary.dropdown-toggle {\n color: #fff;\n background-color: #0062cc;\n border-color: #005cbf;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-secondary {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:hover {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n}\n\n.btn-secondary:focus, .btn-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-secondary.disabled, .btn-secondary:disabled {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-secondary.dropdown-toggle {\n color: #fff;\n background-color: #545b62;\n border-color: #4e555b;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-success {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:hover {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n}\n\n.btn-success:focus, .btn-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-success.disabled, .btn-success:disabled {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active,\n.show > .btn-success.dropdown-toggle {\n color: #fff;\n background-color: #1e7e34;\n border-color: #1c7430;\n}\n\n.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-info {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:hover {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n}\n\n.btn-info:focus, .btn-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-info.disabled, .btn-info:disabled {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active,\n.show > .btn-info.dropdown-toggle {\n color: #fff;\n background-color: #117a8b;\n border-color: #10707f;\n}\n\n.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-warning {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:hover {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n}\n\n.btn-warning:focus, .btn-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-warning.disabled, .btn-warning:disabled {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active,\n.show > .btn-warning.dropdown-toggle {\n color: #212529;\n background-color: #d39e00;\n border-color: #c69500;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-danger {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:hover {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n}\n\n.btn-danger:focus, .btn-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-danger.disabled, .btn-danger:disabled {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active,\n.show > .btn-danger.dropdown-toggle {\n color: #fff;\n background-color: #bd2130;\n border-color: #b21f2d;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-light {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:hover {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n}\n\n.btn-light:focus, .btn-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-light.disabled, .btn-light:disabled {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active,\n.show > .btn-light.dropdown-toggle {\n color: #212529;\n background-color: #dae0e5;\n border-color: #d3d9df;\n}\n\n.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-dark {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:hover {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n}\n\n.btn-dark:focus, .btn-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-dark.disabled, .btn-dark:disabled {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active,\n.show > .btn-dark.dropdown-toggle {\n color: #fff;\n background-color: #1d2124;\n border-color: #171a1d;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-primary {\n color: #007bff;\n background-color: transparent;\n background-image: none;\n border-color: #007bff;\n}\n\n.btn-outline-primary:hover {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:focus, .btn-outline-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-primary.disabled, .btn-outline-primary:disabled {\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-primary.dropdown-toggle {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-secondary {\n color: #6c757d;\n background-color: transparent;\n background-image: none;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:hover {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:focus, .btn-outline-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-secondary.disabled, .btn-outline-secondary:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-secondary.dropdown-toggle {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-success {\n color: #28a745;\n background-color: transparent;\n background-image: none;\n border-color: #28a745;\n}\n\n.btn-outline-success:hover {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:focus, .btn-outline-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-success.disabled, .btn-outline-success:disabled {\n color: #28a745;\n background-color: transparent;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active,\n.show > .btn-outline-success.dropdown-toggle {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-info {\n color: #17a2b8;\n background-color: transparent;\n background-image: none;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:hover {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:focus, .btn-outline-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-info.disabled, .btn-outline-info:disabled {\n color: #17a2b8;\n background-color: transparent;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active,\n.show > .btn-outline-info.dropdown-toggle {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-warning {\n color: #ffc107;\n background-color: transparent;\n background-image: none;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:hover {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:focus, .btn-outline-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-warning.disabled, .btn-outline-warning:disabled {\n color: #ffc107;\n background-color: transparent;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active,\n.show > .btn-outline-warning.dropdown-toggle {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-danger {\n color: #dc3545;\n background-color: transparent;\n background-image: none;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:hover {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:focus, .btn-outline-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-danger.disabled, .btn-outline-danger:disabled {\n color: #dc3545;\n background-color: transparent;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active,\n.show > .btn-outline-danger.dropdown-toggle {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-light {\n color: #f8f9fa;\n background-color: transparent;\n background-image: none;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:hover {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:focus, .btn-outline-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-light.disabled, .btn-outline-light:disabled {\n color: #f8f9fa;\n background-color: transparent;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active,\n.show > .btn-outline-light.dropdown-toggle {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-dark {\n color: #343a40;\n background-color: transparent;\n background-image: none;\n border-color: #343a40;\n}\n\n.btn-outline-dark:hover {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:focus, .btn-outline-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-dark.disabled, .btn-outline-dark:disabled {\n color: #343a40;\n background-color: transparent;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active,\n.show > .btn-outline-dark.dropdown-toggle {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-link {\n font-weight: 400;\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-link:hover {\n color: #0056b3;\n text-decoration: underline;\n background-color: transparent;\n border-color: transparent;\n}\n\n.btn-link:focus, .btn-link.focus {\n text-decoration: underline;\n border-color: transparent;\n box-shadow: none;\n}\n\n.btn-link:disabled, .btn-link.disabled {\n color: #6c757d;\n}\n\n.btn-lg, .btn-group-lg > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n.btn-block + .btn-block {\n margin-top: 0.5rem;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n\n.fade {\n opacity: 0;\n transition: opacity 0.15s linear;\n}\n\n.fade.show {\n opacity: 1;\n}\n\n.collapse {\n display: none;\n}\n\n.collapse.show {\n display: block;\n}\n\ntr.collapse.show {\n display: table-row;\n}\n\ntbody.collapse.show {\n display: table-row-group;\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n transition: height 0.35s ease;\n}\n\n.dropup,\n.dropdown {\n position: relative;\n}\n\n.dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n}\n\n.dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 10rem;\n padding: 0.5rem 0;\n margin: 0.125rem 0 0;\n font-size: 1rem;\n color: #212529;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 0.25rem;\n}\n\n.dropup .dropdown-menu {\n margin-top: 0;\n margin-bottom: 0.125rem;\n}\n\n.dropup .dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0;\n border-right: 0.3em solid transparent;\n border-bottom: 0.3em solid;\n border-left: 0.3em solid transparent;\n}\n\n.dropup .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-menu {\n margin-top: 0;\n margin-left: 0.125rem;\n}\n\n.dropright .dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-bottom: 0.3em solid transparent;\n border-left: 0.3em solid;\n}\n\n.dropright .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-toggle::after {\n vertical-align: 0;\n}\n\n.dropleft .dropdown-menu {\n margin-top: 0;\n margin-right: 0.125rem;\n}\n\n.dropleft .dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n}\n\n.dropleft .dropdown-toggle::after {\n display: none;\n}\n\n.dropleft .dropdown-toggle::before {\n display: inline-block;\n width: 0;\n height: 0;\n margin-right: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0.3em solid;\n border-bottom: 0.3em solid transparent;\n}\n\n.dropleft .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle::before {\n vertical-align: 0;\n}\n\n.dropdown-divider {\n height: 0;\n margin: 0.5rem 0;\n overflow: hidden;\n border-top: 1px solid #e9ecef;\n}\n\n.dropdown-item {\n display: block;\n width: 100%;\n padding: 0.25rem 1.5rem;\n clear: both;\n font-weight: 400;\n color: #212529;\n text-align: inherit;\n white-space: nowrap;\n background-color: transparent;\n border: 0;\n}\n\n.dropdown-item:hover, .dropdown-item:focus {\n color: #16181b;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.dropdown-item.active, .dropdown-item:active {\n color: #fff;\n text-decoration: none;\n background-color: #007bff;\n}\n\n.dropdown-item.disabled, .dropdown-item:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n.dropdown-header {\n display: block;\n padding: 0.5rem 1.5rem;\n margin-bottom: 0;\n font-size: 0.875rem;\n color: #6c757d;\n white-space: nowrap;\n}\n\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: -webkit-inline-box;\n display: -ms-inline-flexbox;\n display: inline-flex;\n vertical-align: middle;\n}\n\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n -webkit-box-flex: 0;\n -ms-flex: 0 1 auto;\n flex: 0 1 auto;\n}\n\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover {\n z-index: 1;\n}\n\n.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n z-index: 1;\n}\n\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group,\n.btn-group-vertical .btn + .btn,\n.btn-group-vertical .btn + .btn-group,\n.btn-group-vertical .btn-group + .btn,\n.btn-group-vertical .btn-group + .btn-group {\n margin-left: -1px;\n}\n\n.btn-toolbar {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -webkit-box-pack: start;\n -ms-flex-pack: start;\n justify-content: flex-start;\n}\n\n.btn-toolbar .input-group {\n width: auto;\n}\n\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n padding-right: 0.5625rem;\n padding-left: 0.5625rem;\n}\n\n.dropdown-toggle-split::after {\n margin-left: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n padding-right: 0.375rem;\n padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n padding-right: 0.75rem;\n padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n -webkit-box-align: start;\n -ms-flex-align: start;\n align-items: flex-start;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n}\n\n.btn-group-vertical .btn,\n.btn-group-vertical .btn-group {\n width: 100%;\n}\n\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.btn-group-toggle > .btn,\n.btn-group-toggle > .btn-group > .btn {\n margin-bottom: 0;\n}\n\n.btn-group-toggle > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn input[type=\"checkbox\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n\n.input-group {\n position: relative;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -webkit-box-align: stretch;\n -ms-flex-align: stretch;\n align-items: stretch;\n width: 100%;\n}\n\n.input-group > .form-control,\n.input-group > .custom-select,\n.input-group > .custom-file {\n position: relative;\n -webkit-box-flex: 1;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n width: 1%;\n margin-bottom: 0;\n}\n\n.input-group > .form-control:focus,\n.input-group > .custom-select:focus,\n.input-group > .custom-file:focus {\n z-index: 3;\n}\n\n.input-group > .form-control + .form-control,\n.input-group > .form-control + .custom-select,\n.input-group > .form-control + .custom-file,\n.input-group > .custom-select + .form-control,\n.input-group > .custom-select + .custom-select,\n.input-group > .custom-select + .custom-file,\n.input-group > .custom-file + .form-control,\n.input-group > .custom-file + .custom-select,\n.input-group > .custom-file + .custom-file {\n margin-left: -1px;\n}\n\n.input-group > .form-control:not(:last-child),\n.input-group > .custom-select:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .form-control:not(:first-child),\n.input-group > .custom-select:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group > .custom-file {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.input-group > .custom-file:not(:last-child) .custom-file-label,\n.input-group > .custom-file:not(:last-child) .custom-file-label::before {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .custom-file:not(:first-child) .custom-file-label,\n.input-group > .custom-file:not(:first-child) .custom-file-label::before {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group-prepend,\n.input-group-append {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n}\n\n.input-group-prepend .btn,\n.input-group-append .btn {\n position: relative;\n z-index: 2;\n}\n\n.input-group-prepend .btn + .btn,\n.input-group-prepend .btn + .input-group-text,\n.input-group-prepend .input-group-text + .input-group-text,\n.input-group-prepend .input-group-text + .btn,\n.input-group-append .btn + .btn,\n.input-group-append .btn + .input-group-text,\n.input-group-append .input-group-text + .input-group-text,\n.input-group-append .input-group-text + .btn {\n margin-left: -1px;\n}\n\n.input-group-prepend {\n margin-right: -1px;\n}\n\n.input-group-append {\n margin-left: -1px;\n}\n\n.input-group-text {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n padding: 0.375rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n text-align: center;\n white-space: nowrap;\n background-color: #e9ecef;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.input-group-text input[type=\"radio\"],\n.input-group-text input[type=\"checkbox\"] {\n margin-top: 0;\n}\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group > .input-group-append:not(:last-child) > .btn,\n.input-group > .input-group-append:not(:last-child) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.custom-control {\n position: relative;\n display: block;\n min-height: 1.5rem;\n padding-left: 1.5rem;\n}\n\n.custom-control-inline {\n display: -webkit-inline-box;\n display: -ms-inline-flexbox;\n display: inline-flex;\n margin-right: 1rem;\n}\n\n.custom-control-input {\n position: absolute;\n z-index: -1;\n opacity: 0;\n}\n\n.custom-control-input:checked ~ .custom-control-label::before {\n color: #fff;\n background-color: #007bff;\n}\n\n.custom-control-input:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-control-input:active ~ .custom-control-label::before {\n color: #fff;\n background-color: #b3d7ff;\n}\n\n.custom-control-input:disabled ~ .custom-control-label {\n color: #6c757d;\n}\n\n.custom-control-input:disabled ~ .custom-control-label::before {\n background-color: #e9ecef;\n}\n\n.custom-control-label {\n margin-bottom: 0;\n}\n\n.custom-control-label::before {\n position: absolute;\n top: 0.25rem;\n left: 0;\n display: block;\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n content: \"\";\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n background-color: #dee2e6;\n}\n\n.custom-control-label::after {\n position: absolute;\n top: 0.25rem;\n left: 0;\n display: block;\n width: 1rem;\n height: 1rem;\n content: \"\";\n background-repeat: no-repeat;\n background-position: center center;\n background-size: 50% 50%;\n}\n\n.custom-checkbox .custom-control-label::before {\n border-radius: 0.25rem;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before {\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E\");\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before {\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E\");\n}\n\n.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-radio .custom-control-label::before {\n border-radius: 50%;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::before {\n background-color: #007bff;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E\");\n}\n\n.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: calc(2.25rem + 2px);\n padding: 0.375rem 1.75rem 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n vertical-align: middle;\n background: #fff url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E\") no-repeat right 0.75rem center;\n background-size: 8px 10px;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\n.custom-select:focus {\n border-color: #80bdff;\n outline: 0;\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075), 0 0 5px rgba(128, 189, 255, 0.5);\n}\n\n.custom-select:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.custom-select[multiple], .custom-select[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: 0.75rem;\n background-image: none;\n}\n\n.custom-select:disabled {\n color: #6c757d;\n background-color: #e9ecef;\n}\n\n.custom-select::-ms-expand {\n opacity: 0;\n}\n\n.custom-select-sm {\n height: calc(1.8125rem + 2px);\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n font-size: 75%;\n}\n\n.custom-select-lg {\n height: calc(2.875rem + 2px);\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n font-size: 125%;\n}\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: calc(2.25rem + 2px);\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: calc(2.25rem + 2px);\n margin: 0;\n opacity: 0;\n}\n\n.custom-file-input:focus ~ .custom-file-control {\n border-color: #80bdff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-file-input:focus ~ .custom-file-control::before {\n border-color: #80bdff;\n}\n\n.custom-file-input:lang(en) ~ .custom-file-label::after {\n content: \"Browse\";\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: calc(2.25rem + 2px);\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.custom-file-label::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: calc(calc(2.25rem + 2px) - 1px * 2);\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n content: \"Browse\";\n background-color: #e9ecef;\n border-left: 1px solid #ced4da;\n border-radius: 0 0.25rem 0.25rem 0;\n}\n\n.nav {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: 0.5rem 1rem;\n}\n\n.nav-link:hover, .nav-link:focus {\n text-decoration: none;\n}\n\n.nav-link.disabled {\n color: #6c757d;\n}\n\n.nav-tabs {\n border-bottom: 1px solid #dee2e6;\n}\n\n.nav-tabs .nav-item {\n margin-bottom: -1px;\n}\n\n.nav-tabs .nav-link {\n border: 1px solid transparent;\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n border-color: #e9ecef #e9ecef #dee2e6;\n}\n\n.nav-tabs .nav-link.disabled {\n color: #6c757d;\n background-color: transparent;\n border-color: transparent;\n}\n\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n color: #495057;\n background-color: #fff;\n border-color: #dee2e6 #dee2e6 #fff;\n}\n\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.nav-pills .nav-link {\n border-radius: 0.25rem;\n}\n\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n color: #fff;\n background-color: #007bff;\n}\n\n.nav-fill .nav-item {\n -webkit-box-flex: 1;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n text-align: center;\n}\n\n.nav-justified .nav-item {\n -ms-flex-preferred-size: 0;\n flex-basis: 0;\n -webkit-box-flex: 1;\n -ms-flex-positive: 1;\n flex-grow: 1;\n text-align: center;\n}\n\n.tab-content > .tab-pane {\n display: none;\n}\n\n.tab-content > .active {\n display: block;\n}\n\n.navbar {\n position: relative;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: justify;\n -ms-flex-pack: justify;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n}\n\n.navbar > .container,\n.navbar > .container-fluid {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: justify;\n -ms-flex-pack: justify;\n justify-content: space-between;\n}\n\n.navbar-brand {\n display: inline-block;\n padding-top: 0.3125rem;\n padding-bottom: 0.3125rem;\n margin-right: 1rem;\n font-size: 1.25rem;\n line-height: inherit;\n white-space: nowrap;\n}\n\n.navbar-brand:hover, .navbar-brand:focus {\n text-decoration: none;\n}\n\n.navbar-nav {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.navbar-nav .nav-link {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-nav .dropdown-menu {\n position: static;\n float: none;\n}\n\n.navbar-text {\n display: inline-block;\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n\n.navbar-collapse {\n -ms-flex-preferred-size: 100%;\n flex-basis: 100%;\n -webkit-box-flex: 1;\n -ms-flex-positive: 1;\n flex-grow: 1;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.navbar-toggler {\n padding: 0.25rem 0.75rem;\n font-size: 1.25rem;\n line-height: 1;\n background-color: transparent;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.navbar-toggler:hover, .navbar-toggler:focus {\n text-decoration: none;\n}\n\n.navbar-toggler:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: no-repeat center center;\n background-size: 100% 100%;\n}\n\n@media (max-width: 575.98px) {\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 576px) {\n .navbar-expand-sm {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -webkit-box-pack: start;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-sm .navbar-nav {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-sm .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-sm .navbar-collapse {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-sm .navbar-toggler {\n display: none;\n }\n .navbar-expand-sm .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n@media (max-width: 767.98px) {\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 768px) {\n .navbar-expand-md {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -webkit-box-pack: start;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-md .navbar-nav {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-md .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-md .navbar-collapse {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-md .navbar-toggler {\n display: none;\n }\n .navbar-expand-md .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n@media (max-width: 991.98px) {\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 992px) {\n .navbar-expand-lg {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -webkit-box-pack: start;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-lg .navbar-nav {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-lg .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-lg .navbar-collapse {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-lg .navbar-toggler {\n display: none;\n }\n .navbar-expand-lg .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n@media (max-width: 1199.98px) {\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .navbar-expand-xl {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -webkit-box-pack: start;\n -ms-flex-pack: start;\n justify-content: flex-start;\n }\n .navbar-expand-xl .navbar-nav {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-direction: row;\n flex-direction: row;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-xl .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n }\n .navbar-expand-xl .navbar-collapse {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n }\n .navbar-expand-xl .navbar-toggler {\n display: none;\n }\n .navbar-expand-xl .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n.navbar-expand {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n -webkit-box-pack: start;\n -ms-flex-pack: start;\n justify-content: flex-start;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-expand .navbar-nav {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-direction: row;\n flex-direction: row;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu {\n position: absolute;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n}\n\n.navbar-expand .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n}\n\n.navbar-expand .navbar-collapse {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n -ms-flex-preferred-size: auto;\n flex-basis: auto;\n}\n\n.navbar-expand .navbar-toggler {\n display: none;\n}\n\n.navbar-expand .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n}\n\n.navbar-light .navbar-brand {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-nav .nav-link {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus {\n color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar-light .navbar-nav .nav-link.disabled {\n color: rgba(0, 0, 0, 0.3);\n}\n\n.navbar-light .navbar-nav .show > .nav-link,\n.navbar-light .navbar-nav .active > .nav-link,\n.navbar-light .navbar-nav .nav-link.show,\n.navbar-light .navbar-nav .nav-link.active {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-toggler {\n color: rgba(0, 0, 0, 0.5);\n border-color: rgba(0, 0, 0, 0.1);\n}\n\n.navbar-light .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\");\n}\n\n.navbar-light .navbar-text {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-text a {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-dark .navbar-brand {\n color: #fff;\n}\n\n.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus {\n color: #fff;\n}\n\n.navbar-dark .navbar-nav .nav-link {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus {\n color: rgba(255, 255, 255, 0.75);\n}\n\n.navbar-dark .navbar-nav .nav-link.disabled {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.navbar-dark .navbar-nav .show > .nav-link,\n.navbar-dark .navbar-nav .active > .nav-link,\n.navbar-dark .navbar-nav .nav-link.show,\n.navbar-dark .navbar-nav .nav-link.active {\n color: #fff;\n}\n\n.navbar-dark .navbar-toggler {\n color: rgba(255, 255, 255, 0.5);\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.navbar-dark .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\");\n}\n\n.navbar-dark .navbar-text {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-text a {\n color: #fff;\n}\n\n.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus {\n color: #fff;\n}\n\n.card {\n position: relative;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n min-width: 0;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: border-box;\n border: 1px solid rgba(0, 0, 0, 0.125);\n border-radius: 0.25rem;\n}\n\n.card > hr {\n margin-right: 0;\n margin-left: 0;\n}\n\n.card > .list-group:first-child .list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.card > .list-group:last-child .list-group-item:last-child {\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.card-body {\n -webkit-box-flex: 1;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n padding: 1.25rem;\n}\n\n.card-title {\n margin-bottom: 0.75rem;\n}\n\n.card-subtitle {\n margin-top: -0.375rem;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link:hover {\n text-decoration: none;\n}\n\n.card-link + .card-link {\n margin-left: 1.25rem;\n}\n\n.card-header {\n padding: 0.75rem 1.25rem;\n margin-bottom: 0;\n background-color: rgba(0, 0, 0, 0.03);\n border-bottom: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-header:first-child {\n border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;\n}\n\n.card-header + .list-group .list-group-item:first-child {\n border-top: 0;\n}\n\n.card-footer {\n padding: 0.75rem 1.25rem;\n background-color: rgba(0, 0, 0, 0.03);\n border-top: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-footer:last-child {\n border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);\n}\n\n.card-header-tabs {\n margin-right: -0.625rem;\n margin-bottom: -0.75rem;\n margin-left: -0.625rem;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -0.625rem;\n margin-left: -0.625rem;\n}\n\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: 1.25rem;\n}\n\n.card-img {\n width: 100%;\n border-radius: calc(0.25rem - 1px);\n}\n\n.card-img-top {\n width: 100%;\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card-img-bottom {\n width: 100%;\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card-deck {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n}\n\n.card-deck .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-deck {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n margin-right: -15px;\n margin-left: -15px;\n }\n .card-deck .card {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-flex: 1;\n -ms-flex: 1 0 0%;\n flex: 1 0 0%;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n margin-right: 15px;\n margin-bottom: 0;\n margin-left: 15px;\n }\n}\n\n.card-group {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n}\n\n.card-group > .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-group {\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row wrap;\n flex-flow: row wrap;\n }\n .card-group > .card {\n -webkit-box-flex: 1;\n -ms-flex: 1 0 0%;\n flex: 1 0 0%;\n margin-bottom: 0;\n }\n .card-group > .card + .card {\n margin-left: 0;\n border-left: 0;\n }\n .card-group > .card:first-child {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n .card-group > .card:first-child .card-img-top,\n .card-group > .card:first-child .card-header {\n border-top-right-radius: 0;\n }\n .card-group > .card:first-child .card-img-bottom,\n .card-group > .card:first-child .card-footer {\n border-bottom-right-radius: 0;\n }\n .card-group > .card:last-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .card-group > .card:last-child .card-img-top,\n .card-group > .card:last-child .card-header {\n border-top-left-radius: 0;\n }\n .card-group > .card:last-child .card-img-bottom,\n .card-group > .card:last-child .card-footer {\n border-bottom-left-radius: 0;\n }\n .card-group > .card:only-child {\n border-radius: 0.25rem;\n }\n .card-group > .card:only-child .card-img-top,\n .card-group > .card:only-child .card-header {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n }\n .card-group > .card:only-child .card-img-bottom,\n .card-group > .card:only-child .card-footer {\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) {\n border-radius: 0;\n }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-top,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-header,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-footer {\n border-radius: 0;\n }\n}\n\n.card-columns .card {\n margin-bottom: 0.75rem;\n}\n\n@media (min-width: 576px) {\n .card-columns {\n -webkit-column-count: 3;\n -moz-column-count: 3;\n column-count: 3;\n -webkit-column-gap: 1.25rem;\n -moz-column-gap: 1.25rem;\n column-gap: 1.25rem;\n }\n .card-columns .card {\n display: inline-block;\n width: 100%;\n }\n}\n\n.breadcrumb {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n padding: 0.75rem 1rem;\n margin-bottom: 1rem;\n list-style: none;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.breadcrumb-item + .breadcrumb-item::before {\n display: inline-block;\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n color: #6c757d;\n content: \"/\";\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: underline;\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: none;\n}\n\n.breadcrumb-item.active {\n color: #6c757d;\n}\n\n.pagination {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n padding-left: 0;\n list-style: none;\n border-radius: 0.25rem;\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: 0.5rem 0.75rem;\n margin-left: -1px;\n line-height: 1.25;\n color: #007bff;\n background-color: #fff;\n border: 1px solid #dee2e6;\n}\n\n.page-link:hover {\n color: #0056b3;\n text-decoration: none;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.page-link:focus {\n z-index: 2;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.page-link:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.page-item:first-child .page-link {\n margin-left: 0;\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.page-item:last-child .page-link {\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n}\n\n.page-item.active .page-link {\n z-index: 1;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.page-item.disabled .page-link {\n color: #6c757d;\n pointer-events: none;\n cursor: auto;\n background-color: #fff;\n border-color: #dee2e6;\n}\n\n.pagination-lg .page-link {\n padding: 0.75rem 1.5rem;\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.pagination-lg .page-item:first-child .page-link {\n border-top-left-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.pagination-lg .page-item:last-child .page-link {\n border-top-right-radius: 0.3rem;\n border-bottom-right-radius: 0.3rem;\n}\n\n.pagination-sm .page-link {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.pagination-sm .page-item:first-child .page-link {\n border-top-left-radius: 0.2rem;\n border-bottom-left-radius: 0.2rem;\n}\n\n.pagination-sm .page-item:last-child .page-link {\n border-top-right-radius: 0.2rem;\n border-bottom-right-radius: 0.2rem;\n}\n\n.badge {\n display: inline-block;\n padding: 0.25em 0.4em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25rem;\n}\n\n.badge:empty {\n display: none;\n}\n\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n.badge-pill {\n padding-right: 0.6em;\n padding-left: 0.6em;\n border-radius: 10rem;\n}\n\n.badge-primary {\n color: #fff;\n background-color: #007bff;\n}\n\n.badge-primary[href]:hover, .badge-primary[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #0062cc;\n}\n\n.badge-secondary {\n color: #fff;\n background-color: #6c757d;\n}\n\n.badge-secondary[href]:hover, .badge-secondary[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #545b62;\n}\n\n.badge-success {\n color: #fff;\n background-color: #28a745;\n}\n\n.badge-success[href]:hover, .badge-success[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #1e7e34;\n}\n\n.badge-info {\n color: #fff;\n background-color: #17a2b8;\n}\n\n.badge-info[href]:hover, .badge-info[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #117a8b;\n}\n\n.badge-warning {\n color: #212529;\n background-color: #ffc107;\n}\n\n.badge-warning[href]:hover, .badge-warning[href]:focus {\n color: #212529;\n text-decoration: none;\n background-color: #d39e00;\n}\n\n.badge-danger {\n color: #fff;\n background-color: #dc3545;\n}\n\n.badge-danger[href]:hover, .badge-danger[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #bd2130;\n}\n\n.badge-light {\n color: #212529;\n background-color: #f8f9fa;\n}\n\n.badge-light[href]:hover, .badge-light[href]:focus {\n color: #212529;\n text-decoration: none;\n background-color: #dae0e5;\n}\n\n.badge-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.badge-dark[href]:hover, .badge-dark[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #1d2124;\n}\n\n.jumbotron {\n padding: 2rem 1rem;\n margin-bottom: 2rem;\n background-color: #e9ecef;\n border-radius: 0.3rem;\n}\n\n@media (min-width: 576px) {\n .jumbotron {\n padding: 4rem 2rem;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n border-radius: 0;\n}\n\n.alert {\n position: relative;\n padding: 0.75rem 1.25rem;\n margin-bottom: 1rem;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.alert-heading {\n color: inherit;\n}\n\n.alert-link {\n font-weight: 700;\n}\n\n.alert-dismissible {\n padding-right: 4rem;\n}\n\n.alert-dismissible .close {\n position: absolute;\n top: 0;\n right: 0;\n padding: 0.75rem 1.25rem;\n color: inherit;\n}\n\n.alert-primary {\n color: #004085;\n background-color: #cce5ff;\n border-color: #b8daff;\n}\n\n.alert-primary hr {\n border-top-color: #9fcdff;\n}\n\n.alert-primary .alert-link {\n color: #002752;\n}\n\n.alert-secondary {\n color: #383d41;\n background-color: #e2e3e5;\n border-color: #d6d8db;\n}\n\n.alert-secondary hr {\n border-top-color: #c8cbcf;\n}\n\n.alert-secondary .alert-link {\n color: #202326;\n}\n\n.alert-success {\n color: #155724;\n background-color: #d4edda;\n border-color: #c3e6cb;\n}\n\n.alert-success hr {\n border-top-color: #b1dfbb;\n}\n\n.alert-success .alert-link {\n color: #0b2e13;\n}\n\n.alert-info {\n color: #0c5460;\n background-color: #d1ecf1;\n border-color: #bee5eb;\n}\n\n.alert-info hr {\n border-top-color: #abdde5;\n}\n\n.alert-info .alert-link {\n color: #062c33;\n}\n\n.alert-warning {\n color: #856404;\n background-color: #fff3cd;\n border-color: #ffeeba;\n}\n\n.alert-warning hr {\n border-top-color: #ffe8a1;\n}\n\n.alert-warning .alert-link {\n color: #533f03;\n}\n\n.alert-danger {\n color: #721c24;\n background-color: #f8d7da;\n border-color: #f5c6cb;\n}\n\n.alert-danger hr {\n border-top-color: #f1b0b7;\n}\n\n.alert-danger .alert-link {\n color: #491217;\n}\n\n.alert-light {\n color: #818182;\n background-color: #fefefe;\n border-color: #fdfdfe;\n}\n\n.alert-light hr {\n border-top-color: #ececf6;\n}\n\n.alert-light .alert-link {\n color: #686868;\n}\n\n.alert-dark {\n color: #1b1e21;\n background-color: #d6d8d9;\n border-color: #c6c8ca;\n}\n\n.alert-dark hr {\n border-top-color: #b9bbbe;\n}\n\n.alert-dark .alert-link {\n color: #040505;\n}\n\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n@keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n.progress {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n height: 1rem;\n overflow: hidden;\n font-size: 0.75rem;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.progress-bar {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n color: #fff;\n text-align: center;\n background-color: #007bff;\n transition: width 0.6s ease;\n}\n\n.progress-bar-striped {\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 1rem 1rem;\n}\n\n.progress-bar-animated {\n -webkit-animation: progress-bar-stripes 1s linear infinite;\n animation: progress-bar-stripes 1s linear infinite;\n}\n\n.media {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: start;\n -ms-flex-align: start;\n align-items: flex-start;\n}\n\n.media-body {\n -webkit-box-flex: 1;\n -ms-flex: 1;\n flex: 1;\n}\n\n.list-group {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n}\n\n.list-group-item-action {\n width: 100%;\n color: #495057;\n text-align: inherit;\n}\n\n.list-group-item-action:hover, .list-group-item-action:focus {\n color: #495057;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.list-group-item-action:active {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 0.75rem 1.25rem;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.list-group-item:hover, .list-group-item:focus {\n z-index: 1;\n text-decoration: none;\n}\n\n.list-group-item.disabled, .list-group-item:disabled {\n color: #6c757d;\n background-color: #fff;\n}\n\n.list-group-item.active {\n z-index: 2;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.list-group-flush .list-group-item {\n border-right: 0;\n border-left: 0;\n border-radius: 0;\n}\n\n.list-group-flush:first-child .list-group-item:first-child {\n border-top: 0;\n}\n\n.list-group-flush:last-child .list-group-item:last-child {\n border-bottom: 0;\n}\n\n.list-group-item-primary {\n color: #004085;\n background-color: #b8daff;\n}\n\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n color: #004085;\n background-color: #9fcdff;\n}\n\n.list-group-item-primary.list-group-item-action.active {\n color: #fff;\n background-color: #004085;\n border-color: #004085;\n}\n\n.list-group-item-secondary {\n color: #383d41;\n background-color: #d6d8db;\n}\n\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n color: #383d41;\n background-color: #c8cbcf;\n}\n\n.list-group-item-secondary.list-group-item-action.active {\n color: #fff;\n background-color: #383d41;\n border-color: #383d41;\n}\n\n.list-group-item-success {\n color: #155724;\n background-color: #c3e6cb;\n}\n\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n color: #155724;\n background-color: #b1dfbb;\n}\n\n.list-group-item-success.list-group-item-action.active {\n color: #fff;\n background-color: #155724;\n border-color: #155724;\n}\n\n.list-group-item-info {\n color: #0c5460;\n background-color: #bee5eb;\n}\n\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n color: #0c5460;\n background-color: #abdde5;\n}\n\n.list-group-item-info.list-group-item-action.active {\n color: #fff;\n background-color: #0c5460;\n border-color: #0c5460;\n}\n\n.list-group-item-warning {\n color: #856404;\n background-color: #ffeeba;\n}\n\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n color: #856404;\n background-color: #ffe8a1;\n}\n\n.list-group-item-warning.list-group-item-action.active {\n color: #fff;\n background-color: #856404;\n border-color: #856404;\n}\n\n.list-group-item-danger {\n color: #721c24;\n background-color: #f5c6cb;\n}\n\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n color: #721c24;\n background-color: #f1b0b7;\n}\n\n.list-group-item-danger.list-group-item-action.active {\n color: #fff;\n background-color: #721c24;\n border-color: #721c24;\n}\n\n.list-group-item-light {\n color: #818182;\n background-color: #fdfdfe;\n}\n\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n color: #818182;\n background-color: #ececf6;\n}\n\n.list-group-item-light.list-group-item-action.active {\n color: #fff;\n background-color: #818182;\n border-color: #818182;\n}\n\n.list-group-item-dark {\n color: #1b1e21;\n background-color: #c6c8ca;\n}\n\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n color: #1b1e21;\n background-color: #b9bbbe;\n}\n\n.list-group-item-dark.list-group-item-action.active {\n color: #fff;\n background-color: #1b1e21;\n border-color: #1b1e21;\n}\n\n.close {\n float: right;\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: .5;\n}\n\n.close:hover, .close:focus {\n color: #000;\n text-decoration: none;\n opacity: .75;\n}\n\n.close:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n\n.modal-open {\n overflow: hidden;\n}\n\n.modal {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n display: none;\n overflow: hidden;\n outline: 0;\n}\n\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 0.5rem;\n pointer-events: none;\n}\n\n.modal.fade .modal-dialog {\n transition: -webkit-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out;\n -webkit-transform: translate(0, -25%);\n transform: translate(0, -25%);\n}\n\n.modal.show .modal-dialog {\n -webkit-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n\n.modal-dialog-centered {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n min-height: calc(100% - (0.5rem * 2));\n}\n\n.modal-content {\n position: relative;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n width: 100%;\n pointer-events: auto;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n outline: 0;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n\n.modal-backdrop.fade {\n opacity: 0;\n}\n\n.modal-backdrop.show {\n opacity: 0.5;\n}\n\n.modal-header {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: start;\n -ms-flex-align: start;\n align-items: flex-start;\n -webkit-box-pack: justify;\n -ms-flex-pack: justify;\n justify-content: space-between;\n padding: 1rem;\n border-bottom: 1px solid #e9ecef;\n border-top-left-radius: 0.3rem;\n border-top-right-radius: 0.3rem;\n}\n\n.modal-header .close {\n padding: 1rem;\n margin: -1rem -1rem -1rem auto;\n}\n\n.modal-title {\n margin-bottom: 0;\n line-height: 1.5;\n}\n\n.modal-body {\n position: relative;\n -webkit-box-flex: 1;\n -ms-flex: 1 1 auto;\n flex: 1 1 auto;\n padding: 1rem;\n}\n\n.modal-footer {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: end;\n -ms-flex-pack: end;\n justify-content: flex-end;\n padding: 1rem;\n border-top: 1px solid #e9ecef;\n}\n\n.modal-footer > :not(:first-child) {\n margin-left: .25rem;\n}\n\n.modal-footer > :not(:last-child) {\n margin-right: .25rem;\n}\n\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n@media (min-width: 576px) {\n .modal-dialog {\n max-width: 500px;\n margin: 1.75rem auto;\n }\n .modal-dialog-centered {\n min-height: calc(100% - (1.75rem * 2));\n }\n .modal-sm {\n max-width: 300px;\n }\n}\n\n@media (min-width: 992px) {\n .modal-lg {\n max-width: 800px;\n }\n}\n\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n opacity: 0;\n}\n\n.tooltip.show {\n opacity: 0.9;\n}\n\n.tooltip .arrow {\n position: absolute;\n display: block;\n width: 0.8rem;\n height: 0.4rem;\n}\n\n.tooltip .arrow::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-tooltip-top, .bs-tooltip-auto[x-placement^=\"top\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^=\"top\"] .arrow {\n bottom: 0;\n}\n\n.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^=\"top\"] .arrow::before {\n top: 0;\n border-width: 0.4rem 0.4rem 0;\n border-top-color: #000;\n}\n\n.bs-tooltip-right, .bs-tooltip-auto[x-placement^=\"right\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^=\"right\"] .arrow {\n left: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^=\"right\"] .arrow::before {\n right: 0;\n border-width: 0.4rem 0.4rem 0.4rem 0;\n border-right-color: #000;\n}\n\n.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^=\"bottom\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow {\n top: 0;\n}\n\n.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow::before {\n bottom: 0;\n border-width: 0 0.4rem 0.4rem;\n border-bottom-color: #000;\n}\n\n.bs-tooltip-left, .bs-tooltip-auto[x-placement^=\"left\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^=\"left\"] .arrow {\n right: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^=\"left\"] .arrow::before {\n left: 0;\n border-width: 0.4rem 0 0.4rem 0.4rem;\n border-left-color: #000;\n}\n\n.tooltip-inner {\n max-width: 200px;\n padding: 0.25rem 0.5rem;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 0.25rem;\n}\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: block;\n max-width: 276px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n}\n\n.popover .arrow {\n position: absolute;\n display: block;\n width: 1rem;\n height: 0.5rem;\n margin: 0 0.3rem;\n}\n\n.popover .arrow::before, .popover .arrow::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-popover-top, .bs-popover-auto[x-placement^=\"top\"] {\n margin-bottom: 0.5rem;\n}\n\n.bs-popover-top .arrow, .bs-popover-auto[x-placement^=\"top\"] .arrow {\n bottom: calc((0.5rem + 1px) * -1);\n}\n\n.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^=\"top\"] .arrow::before,\n.bs-popover-top .arrow::after, .bs-popover-auto[x-placement^=\"top\"] .arrow::after {\n border-width: 0.5rem 0.5rem 0;\n}\n\n.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^=\"top\"] .arrow::before {\n bottom: 0;\n border-top-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-top .arrow::after, .bs-popover-auto[x-placement^=\"top\"] .arrow::after {\n bottom: 1px;\n border-top-color: #fff;\n}\n\n.bs-popover-right, .bs-popover-auto[x-placement^=\"right\"] {\n margin-left: 0.5rem;\n}\n\n.bs-popover-right .arrow, .bs-popover-auto[x-placement^=\"right\"] .arrow {\n left: calc((0.5rem + 1px) * -1);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^=\"right\"] .arrow::before,\n.bs-popover-right .arrow::after, .bs-popover-auto[x-placement^=\"right\"] .arrow::after {\n border-width: 0.5rem 0.5rem 0.5rem 0;\n}\n\n.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^=\"right\"] .arrow::before {\n left: 0;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-right .arrow::after, .bs-popover-auto[x-placement^=\"right\"] .arrow::after {\n left: 1px;\n border-right-color: #fff;\n}\n\n.bs-popover-bottom, .bs-popover-auto[x-placement^=\"bottom\"] {\n margin-top: 0.5rem;\n}\n\n.bs-popover-bottom .arrow, .bs-popover-auto[x-placement^=\"bottom\"] .arrow {\n top: calc((0.5rem + 1px) * -1);\n}\n\n.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::before,\n.bs-popover-bottom .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::after {\n border-width: 0 0.5rem 0.5rem 0.5rem;\n}\n\n.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::before {\n top: 0;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-bottom .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::after {\n top: 1px;\n border-bottom-color: #fff;\n}\n\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^=\"bottom\"] .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: 1rem;\n margin-left: -0.5rem;\n content: \"\";\n border-bottom: 1px solid #f7f7f7;\n}\n\n.bs-popover-left, .bs-popover-auto[x-placement^=\"left\"] {\n margin-right: 0.5rem;\n}\n\n.bs-popover-left .arrow, .bs-popover-auto[x-placement^=\"left\"] .arrow {\n right: calc((0.5rem + 1px) * -1);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^=\"left\"] .arrow::before,\n.bs-popover-left .arrow::after, .bs-popover-auto[x-placement^=\"left\"] .arrow::after {\n border-width: 0.5rem 0 0.5rem 0.5rem;\n}\n\n.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^=\"left\"] .arrow::before {\n right: 0;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-left .arrow::after, .bs-popover-auto[x-placement^=\"left\"] .arrow::after {\n right: 1px;\n border-left-color: #fff;\n}\n\n.popover-header {\n padding: 0.5rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n color: inherit;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.popover-header:empty {\n display: none;\n}\n\n.popover-body {\n padding: 0.5rem 0.75rem;\n color: #212529;\n}\n\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n\n.carousel-item {\n position: relative;\n display: none;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n width: 100%;\n transition: -webkit-transform 0.6s ease;\n transition: transform 0.6s ease;\n transition: transform 0.6s ease, -webkit-transform 0.6s ease;\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n perspective: 1000px;\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next,\n.carousel-item-prev {\n position: absolute;\n top: 0;\n}\n\n.carousel-item-next.carousel-item-left,\n.carousel-item-prev.carousel-item-right {\n -webkit-transform: translateX(0);\n transform: translateX(0);\n}\n\n@supports ((-webkit-transform-style: preserve-3d) or (transform-style: preserve-3d)) {\n .carousel-item-next.carousel-item-left,\n .carousel-item-prev.carousel-item-right {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n }\n}\n\n.carousel-item-next,\n.active.carousel-item-right {\n -webkit-transform: translateX(100%);\n transform: translateX(100%);\n}\n\n@supports ((-webkit-transform-style: preserve-3d) or (transform-style: preserve-3d)) {\n .carousel-item-next,\n .active.carousel-item-right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n }\n}\n\n.carousel-item-prev,\n.active.carousel-item-left {\n -webkit-transform: translateX(-100%);\n transform: translateX(-100%);\n}\n\n@supports ((-webkit-transform-style: preserve-3d) or (transform-style: preserve-3d)) {\n .carousel-item-prev,\n .active.carousel-item-left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n width: 15%;\n color: #fff;\n text-align: center;\n opacity: 0.5;\n}\n\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n opacity: .9;\n}\n\n.carousel-control-prev {\n left: 0;\n}\n\n.carousel-control-next {\n right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n background: transparent no-repeat center center;\n background-size: 100% 100%;\n}\n\n.carousel-control-prev-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E\");\n}\n\n.carousel-control-next-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E\");\n}\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 10px;\n left: 0;\n z-index: 15;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n padding-left: 0;\n margin-right: 15%;\n margin-left: 15%;\n list-style: none;\n}\n\n.carousel-indicators li {\n position: relative;\n -webkit-box-flex: 0;\n -ms-flex: 0 1 auto;\n flex: 0 1 auto;\n width: 30px;\n height: 3px;\n margin-right: 3px;\n margin-left: 3px;\n text-indent: -999px;\n background-color: rgba(255, 255, 255, 0.5);\n}\n\n.carousel-indicators li::before {\n position: absolute;\n top: -10px;\n left: 0;\n display: inline-block;\n width: 100%;\n height: 10px;\n content: \"\";\n}\n\n.carousel-indicators li::after {\n position: absolute;\n bottom: -10px;\n left: 0;\n display: inline-block;\n width: 100%;\n height: 10px;\n content: \"\";\n}\n\n.carousel-indicators .active {\n background-color: #fff;\n}\n\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n}\n\n.align-baseline {\n vertical-align: baseline !important;\n}\n\n.align-top {\n vertical-align: top !important;\n}\n\n.align-middle {\n vertical-align: middle !important;\n}\n\n.align-bottom {\n vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n vertical-align: text-top !important;\n}\n\n.bg-primary {\n background-color: #007bff !important;\n}\n\na.bg-primary:hover, a.bg-primary:focus,\nbutton.bg-primary:hover,\nbutton.bg-primary:focus {\n background-color: #0062cc !important;\n}\n\n.bg-secondary {\n background-color: #6c757d !important;\n}\n\na.bg-secondary:hover, a.bg-secondary:focus,\nbutton.bg-secondary:hover,\nbutton.bg-secondary:focus {\n background-color: #545b62 !important;\n}\n\n.bg-success {\n background-color: #28a745 !important;\n}\n\na.bg-success:hover, a.bg-success:focus,\nbutton.bg-success:hover,\nbutton.bg-success:focus {\n background-color: #1e7e34 !important;\n}\n\n.bg-info {\n background-color: #17a2b8 !important;\n}\n\na.bg-info:hover, a.bg-info:focus,\nbutton.bg-info:hover,\nbutton.bg-info:focus {\n background-color: #117a8b !important;\n}\n\n.bg-warning {\n background-color: #ffc107 !important;\n}\n\na.bg-warning:hover, a.bg-warning:focus,\nbutton.bg-warning:hover,\nbutton.bg-warning:focus {\n background-color: #d39e00 !important;\n}\n\n.bg-danger {\n background-color: #dc3545 !important;\n}\n\na.bg-danger:hover, a.bg-danger:focus,\nbutton.bg-danger:hover,\nbutton.bg-danger:focus {\n background-color: #bd2130 !important;\n}\n\n.bg-light {\n background-color: #f8f9fa !important;\n}\n\na.bg-light:hover, a.bg-light:focus,\nbutton.bg-light:hover,\nbutton.bg-light:focus {\n background-color: #dae0e5 !important;\n}\n\n.bg-dark {\n background-color: #343a40 !important;\n}\n\na.bg-dark:hover, a.bg-dark:focus,\nbutton.bg-dark:hover,\nbutton.bg-dark:focus {\n background-color: #1d2124 !important;\n}\n\n.bg-white {\n background-color: #fff !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n\n.border {\n border: 1px solid #dee2e6 !important;\n}\n\n.border-top {\n border-top: 1px solid #dee2e6 !important;\n}\n\n.border-right {\n border-right: 1px solid #dee2e6 !important;\n}\n\n.border-bottom {\n border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-left {\n border-left: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n border: 0 !important;\n}\n\n.border-top-0 {\n border-top: 0 !important;\n}\n\n.border-right-0 {\n border-right: 0 !important;\n}\n\n.border-bottom-0 {\n border-bottom: 0 !important;\n}\n\n.border-left-0 {\n border-left: 0 !important;\n}\n\n.border-primary {\n border-color: #007bff !important;\n}\n\n.border-secondary {\n border-color: #6c757d !important;\n}\n\n.border-success {\n border-color: #28a745 !important;\n}\n\n.border-info {\n border-color: #17a2b8 !important;\n}\n\n.border-warning {\n border-color: #ffc107 !important;\n}\n\n.border-danger {\n border-color: #dc3545 !important;\n}\n\n.border-light {\n border-color: #f8f9fa !important;\n}\n\n.border-dark {\n border-color: #343a40 !important;\n}\n\n.border-white {\n border-color: #fff !important;\n}\n\n.rounded {\n border-radius: 0.25rem !important;\n}\n\n.rounded-top {\n border-top-left-radius: 0.25rem !important;\n border-top-right-radius: 0.25rem !important;\n}\n\n.rounded-right {\n border-top-right-radius: 0.25rem !important;\n border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-left {\n border-top-left-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n\n.clearfix::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n}\n\n.d-inline-flex {\n display: -webkit-inline-box !important;\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: -webkit-inline-box !important;\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-md-inline-flex {\n display: -webkit-inline-box !important;\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: -webkit-inline-box !important;\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: -webkit-inline-box !important;\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: -webkit-box !important;\n display: -ms-flexbox !important;\n display: flex !important;\n }\n .d-print-inline-flex {\n display: -webkit-inline-box !important;\n display: -ms-inline-flexbox !important;\n display: inline-flex !important;\n }\n}\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n}\n\n.embed-responsive::before {\n display: block;\n content: \"\";\n}\n\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n\n.embed-responsive-21by9::before {\n padding-top: 42.857143%;\n}\n\n.embed-responsive-16by9::before {\n padding-top: 56.25%;\n}\n\n.embed-responsive-4by3::before {\n padding-top: 75%;\n}\n\n.embed-responsive-1by1::before {\n padding-top: 100%;\n}\n\n.flex-row {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n}\n\n.flex-column {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n}\n\n.justify-content-start {\n -webkit-box-pack: start !important;\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n -webkit-box-pack: end !important;\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n -webkit-box-pack: center !important;\n -ms-flex-pack: center !important;\n justify-content: center !important;\n}\n\n.justify-content-between {\n -webkit-box-pack: justify !important;\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n}\n\n.align-items-start {\n -webkit-box-align: start !important;\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n}\n\n.align-items-end {\n -webkit-box-align: end !important;\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n}\n\n.align-items-center {\n -webkit-box-align: center !important;\n -ms-flex-align: center !important;\n align-items: center !important;\n}\n\n.align-items-baseline {\n -webkit-box-align: baseline !important;\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n -webkit-box-align: stretch !important;\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n}\n\n.align-content-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n}\n\n.align-content-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n}\n\n.align-content-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n}\n\n.align-content-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n}\n\n.align-content-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n}\n\n.align-self-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n}\n\n.align-self-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n}\n\n.align-self-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n}\n\n.align-self-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n}\n\n.align-self-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-sm-column {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-sm-start {\n -webkit-box-pack: start !important;\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n -webkit-box-pack: end !important;\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n -webkit-box-pack: center !important;\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-sm-between {\n -webkit-box-pack: justify !important;\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n -webkit-box-align: start !important;\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n -webkit-box-align: end !important;\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n -webkit-box-align: center !important;\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-sm-baseline {\n -webkit-box-align: baseline !important;\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n -webkit-box-align: stretch !important;\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-sm-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-sm-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-sm-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-sm-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-sm-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-md-column {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-md-start {\n -webkit-box-pack: start !important;\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n -webkit-box-pack: end !important;\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n -webkit-box-pack: center !important;\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-md-between {\n -webkit-box-pack: justify !important;\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-md-start {\n -webkit-box-align: start !important;\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-md-end {\n -webkit-box-align: end !important;\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-md-center {\n -webkit-box-align: center !important;\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-md-baseline {\n -webkit-box-align: baseline !important;\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n -webkit-box-align: stretch !important;\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-md-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-md-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-md-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-md-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-md-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-md-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-md-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-md-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-md-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-md-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-lg-column {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-lg-start {\n -webkit-box-pack: start !important;\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n -webkit-box-pack: end !important;\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n -webkit-box-pack: center !important;\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-lg-between {\n -webkit-box-pack: justify !important;\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n -webkit-box-align: start !important;\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n -webkit-box-align: end !important;\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n -webkit-box-align: center !important;\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-lg-baseline {\n -webkit-box-align: baseline !important;\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n -webkit-box-align: stretch !important;\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-lg-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-lg-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-lg-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-lg-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-lg-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: row !important;\n flex-direction: row !important;\n }\n .flex-xl-column {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: normal !important;\n -ms-flex-direction: column !important;\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n -webkit-box-orient: horizontal !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: row-reverse !important;\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n -webkit-box-orient: vertical !important;\n -webkit-box-direction: reverse !important;\n -ms-flex-direction: column-reverse !important;\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n -ms-flex-wrap: wrap !important;\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n -ms-flex-wrap: nowrap !important;\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n -ms-flex-wrap: wrap-reverse !important;\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-xl-start {\n -webkit-box-pack: start !important;\n -ms-flex-pack: start !important;\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n -webkit-box-pack: end !important;\n -ms-flex-pack: end !important;\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n -webkit-box-pack: center !important;\n -ms-flex-pack: center !important;\n justify-content: center !important;\n }\n .justify-content-xl-between {\n -webkit-box-pack: justify !important;\n -ms-flex-pack: justify !important;\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n -ms-flex-pack: distribute !important;\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n -webkit-box-align: start !important;\n -ms-flex-align: start !important;\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n -webkit-box-align: end !important;\n -ms-flex-align: end !important;\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n -webkit-box-align: center !important;\n -ms-flex-align: center !important;\n align-items: center !important;\n }\n .align-items-xl-baseline {\n -webkit-box-align: baseline !important;\n -ms-flex-align: baseline !important;\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n -webkit-box-align: stretch !important;\n -ms-flex-align: stretch !important;\n align-items: stretch !important;\n }\n .align-content-xl-start {\n -ms-flex-line-pack: start !important;\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n -ms-flex-line-pack: end !important;\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n -ms-flex-line-pack: center !important;\n align-content: center !important;\n }\n .align-content-xl-between {\n -ms-flex-line-pack: justify !important;\n align-content: space-between !important;\n }\n .align-content-xl-around {\n -ms-flex-line-pack: distribute !important;\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n -ms-flex-line-pack: stretch !important;\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n -ms-flex-item-align: auto !important;\n align-self: auto !important;\n }\n .align-self-xl-start {\n -ms-flex-item-align: start !important;\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n -ms-flex-item-align: end !important;\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n -ms-flex-item-align: center !important;\n align-self: center !important;\n }\n .align-self-xl-baseline {\n -ms-flex-item-align: baseline !important;\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n -ms-flex-item-align: stretch !important;\n align-self: stretch !important;\n }\n}\n\n.float-left {\n float: left !important;\n}\n\n.float-right {\n float: right !important;\n}\n\n.float-none {\n float: none !important;\n}\n\n@media (min-width: 576px) {\n .float-sm-left {\n float: left !important;\n }\n .float-sm-right {\n float: right !important;\n }\n .float-sm-none {\n float: none !important;\n }\n}\n\n@media (min-width: 768px) {\n .float-md-left {\n float: left !important;\n }\n .float-md-right {\n float: right !important;\n }\n .float-md-none {\n float: none !important;\n }\n}\n\n@media (min-width: 992px) {\n .float-lg-left {\n float: left !important;\n }\n .float-lg-right {\n float: right !important;\n }\n .float-lg-none {\n float: none !important;\n }\n}\n\n@media (min-width: 1200px) {\n .float-xl-left {\n float: left !important;\n }\n .float-xl-right {\n float: right !important;\n }\n .float-xl-none {\n float: none !important;\n }\n}\n\n.position-static {\n position: static !important;\n}\n\n.position-relative {\n position: relative !important;\n}\n\n.position-absolute {\n position: absolute !important;\n}\n\n.position-fixed {\n position: fixed !important;\n}\n\n.position-sticky {\n position: -webkit-sticky !important;\n position: sticky !important;\n}\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1030;\n}\n\n@supports ((position: -webkit-sticky) or (position: sticky)) {\n .sticky-top {\n position: -webkit-sticky;\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n}\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n -webkit-clip-path: inset(50%);\n clip-path: inset(50%);\n border: 0;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n -webkit-clip-path: none;\n clip-path: none;\n}\n\n.w-25 {\n width: 25% !important;\n}\n\n.w-50 {\n width: 50% !important;\n}\n\n.w-75 {\n width: 75% !important;\n}\n\n.w-100 {\n width: 100% !important;\n}\n\n.h-25 {\n height: 25% !important;\n}\n\n.h-50 {\n height: 50% !important;\n}\n\n.h-75 {\n height: 75% !important;\n}\n\n.h-100 {\n height: 100% !important;\n}\n\n.mw-100 {\n max-width: 100% !important;\n}\n\n.mh-100 {\n max-height: 100% !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n\n.text-justify {\n text-align: justify !important;\n}\n\n.text-nowrap {\n white-space: nowrap !important;\n}\n\n.text-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.text-left {\n text-align: left !important;\n}\n\n.text-right {\n text-align: right !important;\n}\n\n.text-center {\n text-align: center !important;\n}\n\n@media (min-width: 576px) {\n .text-sm-left {\n text-align: left !important;\n }\n .text-sm-right {\n text-align: right !important;\n }\n .text-sm-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 768px) {\n .text-md-left {\n text-align: left !important;\n }\n .text-md-right {\n text-align: right !important;\n }\n .text-md-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 992px) {\n .text-lg-left {\n text-align: left !important;\n }\n .text-lg-right {\n text-align: right !important;\n }\n .text-lg-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 1200px) {\n .text-xl-left {\n text-align: left !important;\n }\n .text-xl-right {\n text-align: right !important;\n }\n .text-xl-center {\n text-align: center !important;\n }\n}\n\n.text-lowercase {\n text-transform: lowercase !important;\n}\n\n.text-uppercase {\n text-transform: uppercase !important;\n}\n\n.text-capitalize {\n text-transform: capitalize !important;\n}\n\n.font-weight-light {\n font-weight: 300 !important;\n}\n\n.font-weight-normal {\n font-weight: 400 !important;\n}\n\n.font-weight-bold {\n font-weight: 700 !important;\n}\n\n.font-italic {\n font-style: italic !important;\n}\n\n.text-white {\n color: #fff !important;\n}\n\n.text-primary {\n color: #007bff !important;\n}\n\na.text-primary:hover, a.text-primary:focus {\n color: #0062cc !important;\n}\n\n.text-secondary {\n color: #6c757d !important;\n}\n\na.text-secondary:hover, a.text-secondary:focus {\n color: #545b62 !important;\n}\n\n.text-success {\n color: #28a745 !important;\n}\n\na.text-success:hover, a.text-success:focus {\n color: #1e7e34 !important;\n}\n\n.text-info {\n color: #17a2b8 !important;\n}\n\na.text-info:hover, a.text-info:focus {\n color: #117a8b !important;\n}\n\n.text-warning {\n color: #ffc107 !important;\n}\n\na.text-warning:hover, a.text-warning:focus {\n color: #d39e00 !important;\n}\n\n.text-danger {\n color: #dc3545 !important;\n}\n\na.text-danger:hover, a.text-danger:focus {\n color: #bd2130 !important;\n}\n\n.text-light {\n color: #f8f9fa !important;\n}\n\na.text-light:hover, a.text-light:focus {\n color: #dae0e5 !important;\n}\n\n.text-dark {\n color: #343a40 !important;\n}\n\na.text-dark:hover, a.text-dark:focus {\n color: #1d2124 !important;\n}\n\n.text-muted {\n color: #6c757d !important;\n}\n\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n\n@media print {\n *,\n *::before,\n *::after {\n text-shadow: none !important;\n box-shadow: none !important;\n }\n a:not(.btn) {\n text-decoration: underline;\n }\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n @page {\n size: a3;\n }\n body {\n min-width: 992px !important;\n }\n .container {\n min-width: 992px !important;\n }\n .navbar {\n display: none;\n }\n .badge {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*!\n * Bootstrap v4.0.0 (https://getbootstrap.com)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n:root {\n --blue: #007bff;\n --indigo: #6610f2;\n --purple: #6f42c1;\n --pink: #e83e8c;\n --red: #dc3545;\n --orange: #fd7e14;\n --yellow: #ffc107;\n --green: #28a745;\n --teal: #20c997;\n --cyan: #17a2b8;\n --white: #fff;\n --gray: #6c757d;\n --gray-dark: #343a40;\n --primary: #007bff;\n --secondary: #6c757d;\n --success: #28a745;\n --info: #17a2b8;\n --warning: #ffc107;\n --danger: #dc3545;\n --light: #f8f9fa;\n --dark: #343a40;\n --breakpoint-xs: 0;\n --breakpoint-sm: 576px;\n --breakpoint-md: 768px;\n --breakpoint-lg: 992px;\n --breakpoint-xl: 1200px;\n --font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n -ms-overflow-style: scrollbar;\n -webkit-tap-highlight-color: transparent;\n}\n\n@-ms-viewport {\n width: device-width;\n}\n\narticle, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n -webkit-text-decoration-skip: objects;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus {\n outline: 0;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: .5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\nbutton,\nhtml [type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: 0.5rem;\n font-family: inherit;\n font-weight: 500;\n line-height: 1.2;\n color: inherit;\n}\n\nh1, .h1 {\n font-size: 2.5rem;\n}\n\nh2, .h2 {\n font-size: 2rem;\n}\n\nh3, .h3 {\n font-size: 1.75rem;\n}\n\nh4, .h4 {\n font-size: 1.5rem;\n}\n\nh5, .h5 {\n font-size: 1.25rem;\n}\n\nh6, .h6 {\n font-size: 1rem;\n}\n\n.lead {\n font-size: 1.25rem;\n font-weight: 300;\n}\n\n.display-1 {\n font-size: 6rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-2 {\n font-size: 5.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-3 {\n font-size: 4.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-4 {\n font-size: 3.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\nhr {\n margin-top: 1rem;\n margin-bottom: 1rem;\n border: 0;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\nsmall,\n.small {\n font-size: 80%;\n font-weight: 400;\n}\n\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline-item {\n display: inline-block;\n}\n\n.list-inline-item:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n.blockquote {\n margin-bottom: 1rem;\n font-size: 1.25rem;\n}\n\n.blockquote-footer {\n display: block;\n font-size: 80%;\n color: #6c757d;\n}\n\n.blockquote-footer::before {\n content: \"\\2014 \\00A0\";\n}\n\n.img-fluid {\n max-width: 100%;\n height: auto;\n}\n\n.img-thumbnail {\n padding: 0.25rem;\n background-color: #fff;\n border: 1px solid #dee2e6;\n border-radius: 0.25rem;\n max-width: 100%;\n height: auto;\n}\n\n.figure {\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: 0.5rem;\n line-height: 1;\n}\n\n.figure-caption {\n font-size: 90%;\n color: #6c757d;\n}\n\ncode,\nkbd,\npre,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\ncode {\n font-size: 87.5%;\n color: #e83e8c;\n word-break: break-word;\n}\n\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.2rem 0.4rem;\n font-size: 87.5%;\n color: #fff;\n background-color: #212529;\n border-radius: 0.2rem;\n}\n\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n}\n\npre {\n display: block;\n font-size: 87.5%;\n color: #212529;\n}\n\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n\n.container {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container {\n max-width: 1140px;\n }\n}\n\n.container-fluid {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n.row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n min-height: 1px;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n}\n\n.col-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n order: -1;\n}\n\n.order-last {\n order: 13;\n}\n\n.order-0 {\n order: 0;\n}\n\n.order-1 {\n order: 1;\n}\n\n.order-2 {\n order: 2;\n}\n\n.order-3 {\n order: 3;\n}\n\n.order-4 {\n order: 4;\n}\n\n.order-5 {\n order: 5;\n}\n\n.order-6 {\n order: 6;\n}\n\n.order-7 {\n order: 7;\n}\n\n.order-8 {\n order: 8;\n}\n\n.order-9 {\n order: 9;\n}\n\n.order-10 {\n order: 10;\n}\n\n.order-11 {\n order: 11;\n}\n\n.order-12 {\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-sm-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n order: -1;\n }\n .order-sm-last {\n order: 13;\n }\n .order-sm-0 {\n order: 0;\n }\n .order-sm-1 {\n order: 1;\n }\n .order-sm-2 {\n order: 2;\n }\n .order-sm-3 {\n order: 3;\n }\n .order-sm-4 {\n order: 4;\n }\n .order-sm-5 {\n order: 5;\n }\n .order-sm-6 {\n order: 6;\n }\n .order-sm-7 {\n order: 7;\n }\n .order-sm-8 {\n order: 8;\n }\n .order-sm-9 {\n order: 9;\n }\n .order-sm-10 {\n order: 10;\n }\n .order-sm-11 {\n order: 11;\n }\n .order-sm-12 {\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-md-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n order: -1;\n }\n .order-md-last {\n order: 13;\n }\n .order-md-0 {\n order: 0;\n }\n .order-md-1 {\n order: 1;\n }\n .order-md-2 {\n order: 2;\n }\n .order-md-3 {\n order: 3;\n }\n .order-md-4 {\n order: 4;\n }\n .order-md-5 {\n order: 5;\n }\n .order-md-6 {\n order: 6;\n }\n .order-md-7 {\n order: 7;\n }\n .order-md-8 {\n order: 8;\n }\n .order-md-9 {\n order: 9;\n }\n .order-md-10 {\n order: 10;\n }\n .order-md-11 {\n order: 11;\n }\n .order-md-12 {\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-lg-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n order: -1;\n }\n .order-lg-last {\n order: 13;\n }\n .order-lg-0 {\n order: 0;\n }\n .order-lg-1 {\n order: 1;\n }\n .order-lg-2 {\n order: 2;\n }\n .order-lg-3 {\n order: 3;\n }\n .order-lg-4 {\n order: 4;\n }\n .order-lg-5 {\n order: 5;\n }\n .order-lg-6 {\n order: 6;\n }\n .order-lg-7 {\n order: 7;\n }\n .order-lg-8 {\n order: 8;\n }\n .order-lg-9 {\n order: 9;\n }\n .order-lg-10 {\n order: 10;\n }\n .order-lg-11 {\n order: 11;\n }\n .order-lg-12 {\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none;\n }\n .col-xl-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n order: -1;\n }\n .order-xl-last {\n order: 13;\n }\n .order-xl-0 {\n order: 0;\n }\n .order-xl-1 {\n order: 1;\n }\n .order-xl-2 {\n order: 2;\n }\n .order-xl-3 {\n order: 3;\n }\n .order-xl-4 {\n order: 4;\n }\n .order-xl-5 {\n order: 5;\n }\n .order-xl-6 {\n order: 6;\n }\n .order-xl-7 {\n order: 7;\n }\n .order-xl-8 {\n order: 8;\n }\n .order-xl-9 {\n order: 9;\n }\n .order-xl-10 {\n order: 10;\n }\n .order-xl-11 {\n order: 11;\n }\n .order-xl-12 {\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 1rem;\n background-color: transparent;\n}\n\n.table th,\n.table td {\n padding: 0.75rem;\n vertical-align: top;\n border-top: 1px solid #dee2e6;\n}\n\n.table thead th {\n vertical-align: bottom;\n border-bottom: 2px solid #dee2e6;\n}\n\n.table tbody + tbody {\n border-top: 2px solid #dee2e6;\n}\n\n.table .table {\n background-color: #fff;\n}\n\n.table-sm th,\n.table-sm td {\n padding: 0.3rem;\n}\n\n.table-bordered {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered th,\n.table-bordered td {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered thead th,\n.table-bordered thead td {\n border-bottom-width: 2px;\n}\n\n.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.table-hover tbody tr:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-primary,\n.table-primary > th,\n.table-primary > td {\n background-color: #b8daff;\n}\n\n.table-hover .table-primary:hover {\n background-color: #9fcdff;\n}\n\n.table-hover .table-primary:hover > td,\n.table-hover .table-primary:hover > th {\n background-color: #9fcdff;\n}\n\n.table-secondary,\n.table-secondary > th,\n.table-secondary > td {\n background-color: #d6d8db;\n}\n\n.table-hover .table-secondary:hover {\n background-color: #c8cbcf;\n}\n\n.table-hover .table-secondary:hover > td,\n.table-hover .table-secondary:hover > th {\n background-color: #c8cbcf;\n}\n\n.table-success,\n.table-success > th,\n.table-success > td {\n background-color: #c3e6cb;\n}\n\n.table-hover .table-success:hover {\n background-color: #b1dfbb;\n}\n\n.table-hover .table-success:hover > td,\n.table-hover .table-success:hover > th {\n background-color: #b1dfbb;\n}\n\n.table-info,\n.table-info > th,\n.table-info > td {\n background-color: #bee5eb;\n}\n\n.table-hover .table-info:hover {\n background-color: #abdde5;\n}\n\n.table-hover .table-info:hover > td,\n.table-hover .table-info:hover > th {\n background-color: #abdde5;\n}\n\n.table-warning,\n.table-warning > th,\n.table-warning > td {\n background-color: #ffeeba;\n}\n\n.table-hover .table-warning:hover {\n background-color: #ffe8a1;\n}\n\n.table-hover .table-warning:hover > td,\n.table-hover .table-warning:hover > th {\n background-color: #ffe8a1;\n}\n\n.table-danger,\n.table-danger > th,\n.table-danger > td {\n background-color: #f5c6cb;\n}\n\n.table-hover .table-danger:hover {\n background-color: #f1b0b7;\n}\n\n.table-hover .table-danger:hover > td,\n.table-hover .table-danger:hover > th {\n background-color: #f1b0b7;\n}\n\n.table-light,\n.table-light > th,\n.table-light > td {\n background-color: #fdfdfe;\n}\n\n.table-hover .table-light:hover {\n background-color: #ececf6;\n}\n\n.table-hover .table-light:hover > td,\n.table-hover .table-light:hover > th {\n background-color: #ececf6;\n}\n\n.table-dark,\n.table-dark > th,\n.table-dark > td {\n background-color: #c6c8ca;\n}\n\n.table-hover .table-dark:hover {\n background-color: #b9bbbe;\n}\n\n.table-hover .table-dark:hover > td,\n.table-hover .table-dark:hover > th {\n background-color: #b9bbbe;\n}\n\n.table-active,\n.table-active > th,\n.table-active > td {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover > td,\n.table-hover .table-active:hover > th {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table .thead-dark th {\n color: #fff;\n background-color: #212529;\n border-color: #32383e;\n}\n\n.table .thead-light th {\n color: #495057;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.table-dark {\n color: #fff;\n background-color: #212529;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th {\n border-color: #32383e;\n}\n\n.table-dark.table-bordered {\n border: 0;\n}\n\n.table-dark.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(255, 255, 255, 0.05);\n}\n\n.table-dark.table-hover tbody tr:hover {\n background-color: rgba(255, 255, 255, 0.075);\n}\n\n@media (max-width: 575.98px) {\n .table-responsive-sm {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-sm > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 767.98px) {\n .table-responsive-md {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-md > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 991.98px) {\n .table-responsive-lg {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-lg > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 1199.98px) {\n .table-responsive-xl {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .table-responsive-xl > .table-bordered {\n border: 0;\n }\n}\n\n.table-responsive {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n}\n\n.table-responsive > .table-bordered {\n border: 0;\n}\n\n.form-control {\n display: block;\n width: 100%;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n\n.form-control:focus {\n color: #495057;\n background-color: #fff;\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.form-control::placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:disabled, .form-control[readonly] {\n background-color: #e9ecef;\n opacity: 1;\n}\n\nselect.form-control:not([size]):not([multiple]) {\n height: calc(2.25rem + 2px);\n}\n\nselect.form-control:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n.col-form-label {\n padding-top: calc(0.375rem + 1px);\n padding-bottom: calc(0.375rem + 1px);\n margin-bottom: 0;\n font-size: inherit;\n line-height: 1.5;\n}\n\n.col-form-label-lg {\n padding-top: calc(0.5rem + 1px);\n padding-bottom: calc(0.5rem + 1px);\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.col-form-label-sm {\n padding-top: calc(0.25rem + 1px);\n padding-bottom: calc(0.25rem + 1px);\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n margin-bottom: 0;\n line-height: 1.5;\n background-color: transparent;\n border: solid transparent;\n border-width: 1px 0;\n}\n\n.form-control-plaintext.form-control-sm, .input-group-sm > .form-control-plaintext.form-control,\n.input-group-sm > .input-group-prepend > .form-control-plaintext.input-group-text,\n.input-group-sm > .input-group-append > .form-control-plaintext.input-group-text,\n.input-group-sm > .input-group-prepend > .form-control-plaintext.btn,\n.input-group-sm > .input-group-append > .form-control-plaintext.btn, .form-control-plaintext.form-control-lg, .input-group-lg > .form-control-plaintext.form-control,\n.input-group-lg > .input-group-prepend > .form-control-plaintext.input-group-text,\n.input-group-lg > .input-group-append > .form-control-plaintext.input-group-text,\n.input-group-lg > .input-group-prepend > .form-control-plaintext.btn,\n.input-group-lg > .input-group-append > .form-control-plaintext.btn {\n padding-right: 0;\n padding-left: 0;\n}\n\n.form-control-sm, .input-group-sm > .form-control,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\nselect.form-control-sm:not([size]):not([multiple]), .input-group-sm > select.form-control:not([size]):not([multiple]),\n.input-group-sm > .input-group-prepend > select.input-group-text:not([size]):not([multiple]),\n.input-group-sm > .input-group-append > select.input-group-text:not([size]):not([multiple]),\n.input-group-sm > .input-group-prepend > select.btn:not([size]):not([multiple]),\n.input-group-sm > .input-group-append > select.btn:not([size]):not([multiple]) {\n height: calc(1.8125rem + 2px);\n}\n\n.form-control-lg, .input-group-lg > .form-control,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\nselect.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.form-control:not([size]):not([multiple]),\n.input-group-lg > .input-group-prepend > select.input-group-text:not([size]):not([multiple]),\n.input-group-lg > .input-group-append > select.input-group-text:not([size]):not([multiple]),\n.input-group-lg > .input-group-prepend > select.btn:not([size]):not([multiple]),\n.input-group-lg > .input-group-append > select.btn:not([size]):not([multiple]) {\n height: calc(2.875rem + 2px);\n}\n\n.form-group {\n margin-bottom: 1rem;\n}\n\n.form-text {\n display: block;\n margin-top: 0.25rem;\n}\n\n.form-row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -5px;\n margin-left: -5px;\n}\n\n.form-row > .col,\n.form-row > [class*=\"col-\"] {\n padding-right: 5px;\n padding-left: 5px;\n}\n\n.form-check {\n position: relative;\n display: block;\n padding-left: 1.25rem;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: 0.3rem;\n margin-left: -1.25rem;\n}\n\n.form-check-input:disabled ~ .form-check-label {\n color: #6c757d;\n}\n\n.form-check-label {\n margin-bottom: 0;\n}\n\n.form-check-inline {\n display: inline-flex;\n align-items: center;\n padding-left: 0;\n margin-right: 0.75rem;\n}\n\n.form-check-inline .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: 0.3125rem;\n margin-left: 0;\n}\n\n.valid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #28a745;\n}\n\n.valid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: .5rem;\n margin-top: .1rem;\n font-size: .875rem;\n line-height: 1;\n color: #fff;\n background-color: rgba(40, 167, 69, 0.8);\n border-radius: .2rem;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid, .was-validated\n.custom-select:valid,\n.custom-select.is-valid {\n border-color: #28a745;\n}\n\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus, .was-validated\n.custom-select:valid:focus,\n.custom-select.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .form-control:valid ~ .valid-feedback,\n.was-validated .form-control:valid ~ .valid-tooltip, .form-control.is-valid ~ .valid-feedback,\n.form-control.is-valid ~ .valid-tooltip, .was-validated\n.custom-select:valid ~ .valid-feedback,\n.was-validated\n.custom-select:valid ~ .valid-tooltip,\n.custom-select.is-valid ~ .valid-feedback,\n.custom-select.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n color: #28a745;\n}\n\n.was-validated .form-check-input:valid ~ .valid-feedback,\n.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback,\n.form-check-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label {\n color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before {\n background-color: #71dd8a;\n}\n\n.was-validated .custom-control-input:valid ~ .valid-feedback,\n.was-validated .custom-control-input:valid ~ .valid-tooltip, .custom-control-input.is-valid ~ .valid-feedback,\n.custom-control-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before {\n background-color: #34ce57;\n}\n\n.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label::before, .custom-file-input.is-valid ~ .custom-file-label::before {\n border-color: inherit;\n}\n\n.was-validated .custom-file-input:valid ~ .valid-feedback,\n.was-validated .custom-file-input:valid ~ .valid-tooltip, .custom-file-input.is-valid ~ .valid-feedback,\n.custom-file-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.invalid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #dc3545;\n}\n\n.invalid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: .5rem;\n margin-top: .1rem;\n font-size: .875rem;\n line-height: 1;\n color: #fff;\n background-color: rgba(220, 53, 69, 0.8);\n border-radius: .2rem;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid, .was-validated\n.custom-select:invalid,\n.custom-select.is-invalid {\n border-color: #dc3545;\n}\n\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus, .was-validated\n.custom-select:invalid:focus,\n.custom-select.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-control:invalid ~ .invalid-feedback,\n.was-validated .form-control:invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback,\n.form-control.is-invalid ~ .invalid-tooltip, .was-validated\n.custom-select:invalid ~ .invalid-feedback,\n.was-validated\n.custom-select:invalid ~ .invalid-tooltip,\n.custom-select.is-invalid ~ .invalid-feedback,\n.custom-select.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n color: #dc3545;\n}\n\n.was-validated .form-check-input:invalid ~ .invalid-feedback,\n.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback,\n.form-check-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label {\n color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before {\n background-color: #efa2a9;\n}\n\n.was-validated .custom-control-input:invalid ~ .invalid-feedback,\n.was-validated .custom-control-input:invalid ~ .invalid-tooltip, .custom-control-input.is-invalid ~ .invalid-feedback,\n.custom-control-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before {\n background-color: #e4606d;\n}\n\n.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label::before, .custom-file-input.is-invalid ~ .custom-file-label::before {\n border-color: inherit;\n}\n\n.was-validated .custom-file-input:invalid ~ .invalid-feedback,\n.was-validated .custom-file-input:invalid ~ .invalid-tooltip, .custom-file-input.is-invalid ~ .invalid-feedback,\n.custom-file-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center;\n}\n\n.form-inline .form-check {\n width: 100%;\n}\n\n@media (min-width: 576px) {\n .form-inline label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 0;\n }\n .form-inline .form-group {\n display: flex;\n flex: 0 0 auto;\n flex-flow: row wrap;\n align-items: center;\n margin-bottom: 0;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-plaintext {\n display: inline-block;\n }\n .form-inline .input-group {\n width: auto;\n }\n .form-inline .form-check {\n display: flex;\n align-items: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-inline .form-check-input {\n position: relative;\n margin-top: 0;\n margin-right: 0.25rem;\n margin-left: 0;\n }\n .form-inline .custom-control {\n align-items: center;\n justify-content: center;\n }\n .form-inline .custom-control-label {\n margin-bottom: 0;\n }\n}\n\n.btn {\n display: inline-block;\n font-weight: 400;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n user-select: none;\n border: 1px solid transparent;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n border-radius: 0.25rem;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.btn:hover, .btn:focus {\n text-decoration: none;\n}\n\n.btn:focus, .btn.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.btn.disabled, .btn:disabled {\n opacity: 0.65;\n}\n\n.btn:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.btn:not(:disabled):not(.disabled):active, .btn:not(:disabled):not(.disabled).active {\n background-image: none;\n}\n\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n.btn-primary {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:hover {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n}\n\n.btn-primary:focus, .btn-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-primary.disabled, .btn-primary:disabled {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active,\n.show > .btn-primary.dropdown-toggle {\n color: #fff;\n background-color: #0062cc;\n border-color: #005cbf;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-secondary {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:hover {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n}\n\n.btn-secondary:focus, .btn-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-secondary.disabled, .btn-secondary:disabled {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-secondary.dropdown-toggle {\n color: #fff;\n background-color: #545b62;\n border-color: #4e555b;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-success {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:hover {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n}\n\n.btn-success:focus, .btn-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-success.disabled, .btn-success:disabled {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active,\n.show > .btn-success.dropdown-toggle {\n color: #fff;\n background-color: #1e7e34;\n border-color: #1c7430;\n}\n\n.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-info {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:hover {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n}\n\n.btn-info:focus, .btn-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-info.disabled, .btn-info:disabled {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active,\n.show > .btn-info.dropdown-toggle {\n color: #fff;\n background-color: #117a8b;\n border-color: #10707f;\n}\n\n.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-warning {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:hover {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n}\n\n.btn-warning:focus, .btn-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-warning.disabled, .btn-warning:disabled {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active,\n.show > .btn-warning.dropdown-toggle {\n color: #212529;\n background-color: #d39e00;\n border-color: #c69500;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-danger {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:hover {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n}\n\n.btn-danger:focus, .btn-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-danger.disabled, .btn-danger:disabled {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active,\n.show > .btn-danger.dropdown-toggle {\n color: #fff;\n background-color: #bd2130;\n border-color: #b21f2d;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-light {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:hover {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n}\n\n.btn-light:focus, .btn-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-light.disabled, .btn-light:disabled {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active,\n.show > .btn-light.dropdown-toggle {\n color: #212529;\n background-color: #dae0e5;\n border-color: #d3d9df;\n}\n\n.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-dark {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:hover {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n}\n\n.btn-dark:focus, .btn-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-dark.disabled, .btn-dark:disabled {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active,\n.show > .btn-dark.dropdown-toggle {\n color: #fff;\n background-color: #1d2124;\n border-color: #171a1d;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-primary {\n color: #007bff;\n background-color: transparent;\n background-image: none;\n border-color: #007bff;\n}\n\n.btn-outline-primary:hover {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:focus, .btn-outline-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-primary.disabled, .btn-outline-primary:disabled {\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-primary.dropdown-toggle {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-secondary {\n color: #6c757d;\n background-color: transparent;\n background-image: none;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:hover {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:focus, .btn-outline-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-secondary.disabled, .btn-outline-secondary:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-secondary.dropdown-toggle {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-success {\n color: #28a745;\n background-color: transparent;\n background-image: none;\n border-color: #28a745;\n}\n\n.btn-outline-success:hover {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:focus, .btn-outline-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-success.disabled, .btn-outline-success:disabled {\n color: #28a745;\n background-color: transparent;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active,\n.show > .btn-outline-success.dropdown-toggle {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-info {\n color: #17a2b8;\n background-color: transparent;\n background-image: none;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:hover {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:focus, .btn-outline-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-info.disabled, .btn-outline-info:disabled {\n color: #17a2b8;\n background-color: transparent;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active,\n.show > .btn-outline-info.dropdown-toggle {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-warning {\n color: #ffc107;\n background-color: transparent;\n background-image: none;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:hover {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:focus, .btn-outline-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-warning.disabled, .btn-outline-warning:disabled {\n color: #ffc107;\n background-color: transparent;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active,\n.show > .btn-outline-warning.dropdown-toggle {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-danger {\n color: #dc3545;\n background-color: transparent;\n background-image: none;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:hover {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:focus, .btn-outline-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-danger.disabled, .btn-outline-danger:disabled {\n color: #dc3545;\n background-color: transparent;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active,\n.show > .btn-outline-danger.dropdown-toggle {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-light {\n color: #f8f9fa;\n background-color: transparent;\n background-image: none;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:hover {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:focus, .btn-outline-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-light.disabled, .btn-outline-light:disabled {\n color: #f8f9fa;\n background-color: transparent;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active,\n.show > .btn-outline-light.dropdown-toggle {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-dark {\n color: #343a40;\n background-color: transparent;\n background-image: none;\n border-color: #343a40;\n}\n\n.btn-outline-dark:hover {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:focus, .btn-outline-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-dark.disabled, .btn-outline-dark:disabled {\n color: #343a40;\n background-color: transparent;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active,\n.show > .btn-outline-dark.dropdown-toggle {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-link {\n font-weight: 400;\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-link:hover {\n color: #0056b3;\n text-decoration: underline;\n background-color: transparent;\n border-color: transparent;\n}\n\n.btn-link:focus, .btn-link.focus {\n text-decoration: underline;\n border-color: transparent;\n box-shadow: none;\n}\n\n.btn-link:disabled, .btn-link.disabled {\n color: #6c757d;\n}\n\n.btn-lg, .btn-group-lg > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n.btn-block + .btn-block {\n margin-top: 0.5rem;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n\n.fade {\n opacity: 0;\n transition: opacity 0.15s linear;\n}\n\n.fade.show {\n opacity: 1;\n}\n\n.collapse {\n display: none;\n}\n\n.collapse.show {\n display: block;\n}\n\ntr.collapse.show {\n display: table-row;\n}\n\ntbody.collapse.show {\n display: table-row-group;\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n transition: height 0.35s ease;\n}\n\n.dropup,\n.dropdown {\n position: relative;\n}\n\n.dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n}\n\n.dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 10rem;\n padding: 0.5rem 0;\n margin: 0.125rem 0 0;\n font-size: 1rem;\n color: #212529;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 0.25rem;\n}\n\n.dropup .dropdown-menu {\n margin-top: 0;\n margin-bottom: 0.125rem;\n}\n\n.dropup .dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0;\n border-right: 0.3em solid transparent;\n border-bottom: 0.3em solid;\n border-left: 0.3em solid transparent;\n}\n\n.dropup .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-menu {\n margin-top: 0;\n margin-left: 0.125rem;\n}\n\n.dropright .dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-bottom: 0.3em solid transparent;\n border-left: 0.3em solid;\n}\n\n.dropright .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-toggle::after {\n vertical-align: 0;\n}\n\n.dropleft .dropdown-menu {\n margin-top: 0;\n margin-right: 0.125rem;\n}\n\n.dropleft .dropdown-toggle::after {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n}\n\n.dropleft .dropdown-toggle::after {\n display: none;\n}\n\n.dropleft .dropdown-toggle::before {\n display: inline-block;\n width: 0;\n height: 0;\n margin-right: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0.3em solid;\n border-bottom: 0.3em solid transparent;\n}\n\n.dropleft .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle::before {\n vertical-align: 0;\n}\n\n.dropdown-divider {\n height: 0;\n margin: 0.5rem 0;\n overflow: hidden;\n border-top: 1px solid #e9ecef;\n}\n\n.dropdown-item {\n display: block;\n width: 100%;\n padding: 0.25rem 1.5rem;\n clear: both;\n font-weight: 400;\n color: #212529;\n text-align: inherit;\n white-space: nowrap;\n background-color: transparent;\n border: 0;\n}\n\n.dropdown-item:hover, .dropdown-item:focus {\n color: #16181b;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.dropdown-item.active, .dropdown-item:active {\n color: #fff;\n text-decoration: none;\n background-color: #007bff;\n}\n\n.dropdown-item.disabled, .dropdown-item:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n.dropdown-header {\n display: block;\n padding: 0.5rem 1.5rem;\n margin-bottom: 0;\n font-size: 0.875rem;\n color: #6c757d;\n white-space: nowrap;\n}\n\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle;\n}\n\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n flex: 0 1 auto;\n}\n\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover {\n z-index: 1;\n}\n\n.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n z-index: 1;\n}\n\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group,\n.btn-group-vertical .btn + .btn,\n.btn-group-vertical .btn + .btn-group,\n.btn-group-vertical .btn-group + .btn,\n.btn-group-vertical .btn-group + .btn-group {\n margin-left: -1px;\n}\n\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n}\n\n.btn-toolbar .input-group {\n width: auto;\n}\n\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n padding-right: 0.5625rem;\n padding-left: 0.5625rem;\n}\n\n.dropdown-toggle-split::after {\n margin-left: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n padding-right: 0.375rem;\n padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n padding-right: 0.75rem;\n padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n}\n\n.btn-group-vertical .btn,\n.btn-group-vertical .btn-group {\n width: 100%;\n}\n\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.btn-group-toggle > .btn,\n.btn-group-toggle > .btn-group > .btn {\n margin-bottom: 0;\n}\n\n.btn-group-toggle > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn input[type=\"checkbox\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: stretch;\n width: 100%;\n}\n\n.input-group > .form-control,\n.input-group > .custom-select,\n.input-group > .custom-file {\n position: relative;\n flex: 1 1 auto;\n width: 1%;\n margin-bottom: 0;\n}\n\n.input-group > .form-control:focus,\n.input-group > .custom-select:focus,\n.input-group > .custom-file:focus {\n z-index: 3;\n}\n\n.input-group > .form-control + .form-control,\n.input-group > .form-control + .custom-select,\n.input-group > .form-control + .custom-file,\n.input-group > .custom-select + .form-control,\n.input-group > .custom-select + .custom-select,\n.input-group > .custom-select + .custom-file,\n.input-group > .custom-file + .form-control,\n.input-group > .custom-file + .custom-select,\n.input-group > .custom-file + .custom-file {\n margin-left: -1px;\n}\n\n.input-group > .form-control:not(:last-child),\n.input-group > .custom-select:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .form-control:not(:first-child),\n.input-group > .custom-select:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group > .custom-file {\n display: flex;\n align-items: center;\n}\n\n.input-group > .custom-file:not(:last-child) .custom-file-label,\n.input-group > .custom-file:not(:last-child) .custom-file-label::before {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .custom-file:not(:first-child) .custom-file-label,\n.input-group > .custom-file:not(:first-child) .custom-file-label::before {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group-prepend,\n.input-group-append {\n display: flex;\n}\n\n.input-group-prepend .btn,\n.input-group-append .btn {\n position: relative;\n z-index: 2;\n}\n\n.input-group-prepend .btn + .btn,\n.input-group-prepend .btn + .input-group-text,\n.input-group-prepend .input-group-text + .input-group-text,\n.input-group-prepend .input-group-text + .btn,\n.input-group-append .btn + .btn,\n.input-group-append .btn + .input-group-text,\n.input-group-append .input-group-text + .input-group-text,\n.input-group-append .input-group-text + .btn {\n margin-left: -1px;\n}\n\n.input-group-prepend {\n margin-right: -1px;\n}\n\n.input-group-append {\n margin-left: -1px;\n}\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: 0.375rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n text-align: center;\n white-space: nowrap;\n background-color: #e9ecef;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.input-group-text input[type=\"radio\"],\n.input-group-text input[type=\"checkbox\"] {\n margin-top: 0;\n}\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group > .input-group-append:not(:last-child) > .btn,\n.input-group > .input-group-append:not(:last-child) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.custom-control {\n position: relative;\n display: block;\n min-height: 1.5rem;\n padding-left: 1.5rem;\n}\n\n.custom-control-inline {\n display: inline-flex;\n margin-right: 1rem;\n}\n\n.custom-control-input {\n position: absolute;\n z-index: -1;\n opacity: 0;\n}\n\n.custom-control-input:checked ~ .custom-control-label::before {\n color: #fff;\n background-color: #007bff;\n}\n\n.custom-control-input:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-control-input:active ~ .custom-control-label::before {\n color: #fff;\n background-color: #b3d7ff;\n}\n\n.custom-control-input:disabled ~ .custom-control-label {\n color: #6c757d;\n}\n\n.custom-control-input:disabled ~ .custom-control-label::before {\n background-color: #e9ecef;\n}\n\n.custom-control-label {\n margin-bottom: 0;\n}\n\n.custom-control-label::before {\n position: absolute;\n top: 0.25rem;\n left: 0;\n display: block;\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n content: \"\";\n user-select: none;\n background-color: #dee2e6;\n}\n\n.custom-control-label::after {\n position: absolute;\n top: 0.25rem;\n left: 0;\n display: block;\n width: 1rem;\n height: 1rem;\n content: \"\";\n background-repeat: no-repeat;\n background-position: center center;\n background-size: 50% 50%;\n}\n\n.custom-checkbox .custom-control-label::before {\n border-radius: 0.25rem;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before {\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E\");\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before {\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E\");\n}\n\n.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-radio .custom-control-label::before {\n border-radius: 50%;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::before {\n background-color: #007bff;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E\");\n}\n\n.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: calc(2.25rem + 2px);\n padding: 0.375rem 1.75rem 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n vertical-align: middle;\n background: #fff url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E\") no-repeat right 0.75rem center;\n background-size: 8px 10px;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n appearance: none;\n}\n\n.custom-select:focus {\n border-color: #80bdff;\n outline: 0;\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075), 0 0 5px rgba(128, 189, 255, 0.5);\n}\n\n.custom-select:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.custom-select[multiple], .custom-select[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: 0.75rem;\n background-image: none;\n}\n\n.custom-select:disabled {\n color: #6c757d;\n background-color: #e9ecef;\n}\n\n.custom-select::-ms-expand {\n opacity: 0;\n}\n\n.custom-select-sm {\n height: calc(1.8125rem + 2px);\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n font-size: 75%;\n}\n\n.custom-select-lg {\n height: calc(2.875rem + 2px);\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n font-size: 125%;\n}\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: calc(2.25rem + 2px);\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: calc(2.25rem + 2px);\n margin: 0;\n opacity: 0;\n}\n\n.custom-file-input:focus ~ .custom-file-control {\n border-color: #80bdff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-file-input:focus ~ .custom-file-control::before {\n border-color: #80bdff;\n}\n\n.custom-file-input:lang(en) ~ .custom-file-label::after {\n content: \"Browse\";\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: calc(2.25rem + 2px);\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.custom-file-label::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: calc(calc(2.25rem + 2px) - 1px * 2);\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n content: \"Browse\";\n background-color: #e9ecef;\n border-left: 1px solid #ced4da;\n border-radius: 0 0.25rem 0.25rem 0;\n}\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: 0.5rem 1rem;\n}\n\n.nav-link:hover, .nav-link:focus {\n text-decoration: none;\n}\n\n.nav-link.disabled {\n color: #6c757d;\n}\n\n.nav-tabs {\n border-bottom: 1px solid #dee2e6;\n}\n\n.nav-tabs .nav-item {\n margin-bottom: -1px;\n}\n\n.nav-tabs .nav-link {\n border: 1px solid transparent;\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n border-color: #e9ecef #e9ecef #dee2e6;\n}\n\n.nav-tabs .nav-link.disabled {\n color: #6c757d;\n background-color: transparent;\n border-color: transparent;\n}\n\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n color: #495057;\n background-color: #fff;\n border-color: #dee2e6 #dee2e6 #fff;\n}\n\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.nav-pills .nav-link {\n border-radius: 0.25rem;\n}\n\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n color: #fff;\n background-color: #007bff;\n}\n\n.nav-fill .nav-item {\n flex: 1 1 auto;\n text-align: center;\n}\n\n.nav-justified .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n}\n\n.tab-content > .tab-pane {\n display: none;\n}\n\n.tab-content > .active {\n display: block;\n}\n\n.navbar {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n}\n\n.navbar > .container,\n.navbar > .container-fluid {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n}\n\n.navbar-brand {\n display: inline-block;\n padding-top: 0.3125rem;\n padding-bottom: 0.3125rem;\n margin-right: 1rem;\n font-size: 1.25rem;\n line-height: inherit;\n white-space: nowrap;\n}\n\n.navbar-brand:hover, .navbar-brand:focus {\n text-decoration: none;\n}\n\n.navbar-nav {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.navbar-nav .nav-link {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-nav .dropdown-menu {\n position: static;\n float: none;\n}\n\n.navbar-text {\n display: inline-block;\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n align-items: center;\n}\n\n.navbar-toggler {\n padding: 0.25rem 0.75rem;\n font-size: 1.25rem;\n line-height: 1;\n background-color: transparent;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.navbar-toggler:hover, .navbar-toggler:focus {\n text-decoration: none;\n}\n\n.navbar-toggler:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: no-repeat center center;\n background-size: 100% 100%;\n}\n\n@media (max-width: 575.98px) {\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 576px) {\n .navbar-expand-sm {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-sm .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-sm .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-sm .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-sm .navbar-toggler {\n display: none;\n }\n .navbar-expand-sm .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n@media (max-width: 767.98px) {\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 768px) {\n .navbar-expand-md {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-md .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-md .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-md .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-md .navbar-toggler {\n display: none;\n }\n .navbar-expand-md .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n@media (max-width: 991.98px) {\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 992px) {\n .navbar-expand-lg {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-lg .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-lg .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-lg .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-lg .navbar-toggler {\n display: none;\n }\n .navbar-expand-lg .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n@media (max-width: 1199.98px) {\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .navbar-expand-xl {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-xl .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n }\n .navbar-expand-xl .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-xl .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-xl .navbar-toggler {\n display: none;\n }\n .navbar-expand-xl .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n }\n}\n\n.navbar-expand {\n flex-flow: row nowrap;\n justify-content: flex-start;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-expand .navbar-nav {\n flex-direction: row;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu {\n position: absolute;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu-right {\n right: 0;\n left: auto;\n}\n\n.navbar-expand .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid {\n flex-wrap: nowrap;\n}\n\n.navbar-expand .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n}\n\n.navbar-expand .navbar-toggler {\n display: none;\n}\n\n.navbar-expand .dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n}\n\n.navbar-light .navbar-brand {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-nav .nav-link {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus {\n color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar-light .navbar-nav .nav-link.disabled {\n color: rgba(0, 0, 0, 0.3);\n}\n\n.navbar-light .navbar-nav .show > .nav-link,\n.navbar-light .navbar-nav .active > .nav-link,\n.navbar-light .navbar-nav .nav-link.show,\n.navbar-light .navbar-nav .nav-link.active {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-toggler {\n color: rgba(0, 0, 0, 0.5);\n border-color: rgba(0, 0, 0, 0.1);\n}\n\n.navbar-light .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\");\n}\n\n.navbar-light .navbar-text {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-text a {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-dark .navbar-brand {\n color: #fff;\n}\n\n.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus {\n color: #fff;\n}\n\n.navbar-dark .navbar-nav .nav-link {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus {\n color: rgba(255, 255, 255, 0.75);\n}\n\n.navbar-dark .navbar-nav .nav-link.disabled {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.navbar-dark .navbar-nav .show > .nav-link,\n.navbar-dark .navbar-nav .active > .nav-link,\n.navbar-dark .navbar-nav .nav-link.show,\n.navbar-dark .navbar-nav .nav-link.active {\n color: #fff;\n}\n\n.navbar-dark .navbar-toggler {\n color: rgba(255, 255, 255, 0.5);\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.navbar-dark .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E\");\n}\n\n.navbar-dark .navbar-text {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-text a {\n color: #fff;\n}\n\n.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus {\n color: #fff;\n}\n\n.card {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: border-box;\n border: 1px solid rgba(0, 0, 0, 0.125);\n border-radius: 0.25rem;\n}\n\n.card > hr {\n margin-right: 0;\n margin-left: 0;\n}\n\n.card > .list-group:first-child .list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.card > .list-group:last-child .list-group-item:last-child {\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.card-body {\n flex: 1 1 auto;\n padding: 1.25rem;\n}\n\n.card-title {\n margin-bottom: 0.75rem;\n}\n\n.card-subtitle {\n margin-top: -0.375rem;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link:hover {\n text-decoration: none;\n}\n\n.card-link + .card-link {\n margin-left: 1.25rem;\n}\n\n.card-header {\n padding: 0.75rem 1.25rem;\n margin-bottom: 0;\n background-color: rgba(0, 0, 0, 0.03);\n border-bottom: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-header:first-child {\n border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;\n}\n\n.card-header + .list-group .list-group-item:first-child {\n border-top: 0;\n}\n\n.card-footer {\n padding: 0.75rem 1.25rem;\n background-color: rgba(0, 0, 0, 0.03);\n border-top: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-footer:last-child {\n border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);\n}\n\n.card-header-tabs {\n margin-right: -0.625rem;\n margin-bottom: -0.75rem;\n margin-left: -0.625rem;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -0.625rem;\n margin-left: -0.625rem;\n}\n\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: 1.25rem;\n}\n\n.card-img {\n width: 100%;\n border-radius: calc(0.25rem - 1px);\n}\n\n.card-img-top {\n width: 100%;\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card-img-bottom {\n width: 100%;\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card-deck {\n display: flex;\n flex-direction: column;\n}\n\n.card-deck .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-deck {\n flex-flow: row wrap;\n margin-right: -15px;\n margin-left: -15px;\n }\n .card-deck .card {\n display: flex;\n flex: 1 0 0%;\n flex-direction: column;\n margin-right: 15px;\n margin-bottom: 0;\n margin-left: 15px;\n }\n}\n\n.card-group {\n display: flex;\n flex-direction: column;\n}\n\n.card-group > .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-group {\n flex-flow: row wrap;\n }\n .card-group > .card {\n flex: 1 0 0%;\n margin-bottom: 0;\n }\n .card-group > .card + .card {\n margin-left: 0;\n border-left: 0;\n }\n .card-group > .card:first-child {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n .card-group > .card:first-child .card-img-top,\n .card-group > .card:first-child .card-header {\n border-top-right-radius: 0;\n }\n .card-group > .card:first-child .card-img-bottom,\n .card-group > .card:first-child .card-footer {\n border-bottom-right-radius: 0;\n }\n .card-group > .card:last-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .card-group > .card:last-child .card-img-top,\n .card-group > .card:last-child .card-header {\n border-top-left-radius: 0;\n }\n .card-group > .card:last-child .card-img-bottom,\n .card-group > .card:last-child .card-footer {\n border-bottom-left-radius: 0;\n }\n .card-group > .card:only-child {\n border-radius: 0.25rem;\n }\n .card-group > .card:only-child .card-img-top,\n .card-group > .card:only-child .card-header {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n }\n .card-group > .card:only-child .card-img-bottom,\n .card-group > .card:only-child .card-footer {\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) {\n border-radius: 0;\n }\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-top,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-header,\n .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-footer {\n border-radius: 0;\n }\n}\n\n.card-columns .card {\n margin-bottom: 0.75rem;\n}\n\n@media (min-width: 576px) {\n .card-columns {\n column-count: 3;\n column-gap: 1.25rem;\n }\n .card-columns .card {\n display: inline-block;\n width: 100%;\n }\n}\n\n.breadcrumb {\n display: flex;\n flex-wrap: wrap;\n padding: 0.75rem 1rem;\n margin-bottom: 1rem;\n list-style: none;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.breadcrumb-item + .breadcrumb-item::before {\n display: inline-block;\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n color: #6c757d;\n content: \"/\";\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: underline;\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: none;\n}\n\n.breadcrumb-item.active {\n color: #6c757d;\n}\n\n.pagination {\n display: flex;\n padding-left: 0;\n list-style: none;\n border-radius: 0.25rem;\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: 0.5rem 0.75rem;\n margin-left: -1px;\n line-height: 1.25;\n color: #007bff;\n background-color: #fff;\n border: 1px solid #dee2e6;\n}\n\n.page-link:hover {\n color: #0056b3;\n text-decoration: none;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.page-link:focus {\n z-index: 2;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.page-link:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\n.page-item:first-child .page-link {\n margin-left: 0;\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.page-item:last-child .page-link {\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n}\n\n.page-item.active .page-link {\n z-index: 1;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.page-item.disabled .page-link {\n color: #6c757d;\n pointer-events: none;\n cursor: auto;\n background-color: #fff;\n border-color: #dee2e6;\n}\n\n.pagination-lg .page-link {\n padding: 0.75rem 1.5rem;\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.pagination-lg .page-item:first-child .page-link {\n border-top-left-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.pagination-lg .page-item:last-child .page-link {\n border-top-right-radius: 0.3rem;\n border-bottom-right-radius: 0.3rem;\n}\n\n.pagination-sm .page-link {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.pagination-sm .page-item:first-child .page-link {\n border-top-left-radius: 0.2rem;\n border-bottom-left-radius: 0.2rem;\n}\n\n.pagination-sm .page-item:last-child .page-link {\n border-top-right-radius: 0.2rem;\n border-bottom-right-radius: 0.2rem;\n}\n\n.badge {\n display: inline-block;\n padding: 0.25em 0.4em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25rem;\n}\n\n.badge:empty {\n display: none;\n}\n\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n.badge-pill {\n padding-right: 0.6em;\n padding-left: 0.6em;\n border-radius: 10rem;\n}\n\n.badge-primary {\n color: #fff;\n background-color: #007bff;\n}\n\n.badge-primary[href]:hover, .badge-primary[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #0062cc;\n}\n\n.badge-secondary {\n color: #fff;\n background-color: #6c757d;\n}\n\n.badge-secondary[href]:hover, .badge-secondary[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #545b62;\n}\n\n.badge-success {\n color: #fff;\n background-color: #28a745;\n}\n\n.badge-success[href]:hover, .badge-success[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #1e7e34;\n}\n\n.badge-info {\n color: #fff;\n background-color: #17a2b8;\n}\n\n.badge-info[href]:hover, .badge-info[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #117a8b;\n}\n\n.badge-warning {\n color: #212529;\n background-color: #ffc107;\n}\n\n.badge-warning[href]:hover, .badge-warning[href]:focus {\n color: #212529;\n text-decoration: none;\n background-color: #d39e00;\n}\n\n.badge-danger {\n color: #fff;\n background-color: #dc3545;\n}\n\n.badge-danger[href]:hover, .badge-danger[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #bd2130;\n}\n\n.badge-light {\n color: #212529;\n background-color: #f8f9fa;\n}\n\n.badge-light[href]:hover, .badge-light[href]:focus {\n color: #212529;\n text-decoration: none;\n background-color: #dae0e5;\n}\n\n.badge-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.badge-dark[href]:hover, .badge-dark[href]:focus {\n color: #fff;\n text-decoration: none;\n background-color: #1d2124;\n}\n\n.jumbotron {\n padding: 2rem 1rem;\n margin-bottom: 2rem;\n background-color: #e9ecef;\n border-radius: 0.3rem;\n}\n\n@media (min-width: 576px) {\n .jumbotron {\n padding: 4rem 2rem;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n border-radius: 0;\n}\n\n.alert {\n position: relative;\n padding: 0.75rem 1.25rem;\n margin-bottom: 1rem;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.alert-heading {\n color: inherit;\n}\n\n.alert-link {\n font-weight: 700;\n}\n\n.alert-dismissible {\n padding-right: 4rem;\n}\n\n.alert-dismissible .close {\n position: absolute;\n top: 0;\n right: 0;\n padding: 0.75rem 1.25rem;\n color: inherit;\n}\n\n.alert-primary {\n color: #004085;\n background-color: #cce5ff;\n border-color: #b8daff;\n}\n\n.alert-primary hr {\n border-top-color: #9fcdff;\n}\n\n.alert-primary .alert-link {\n color: #002752;\n}\n\n.alert-secondary {\n color: #383d41;\n background-color: #e2e3e5;\n border-color: #d6d8db;\n}\n\n.alert-secondary hr {\n border-top-color: #c8cbcf;\n}\n\n.alert-secondary .alert-link {\n color: #202326;\n}\n\n.alert-success {\n color: #155724;\n background-color: #d4edda;\n border-color: #c3e6cb;\n}\n\n.alert-success hr {\n border-top-color: #b1dfbb;\n}\n\n.alert-success .alert-link {\n color: #0b2e13;\n}\n\n.alert-info {\n color: #0c5460;\n background-color: #d1ecf1;\n border-color: #bee5eb;\n}\n\n.alert-info hr {\n border-top-color: #abdde5;\n}\n\n.alert-info .alert-link {\n color: #062c33;\n}\n\n.alert-warning {\n color: #856404;\n background-color: #fff3cd;\n border-color: #ffeeba;\n}\n\n.alert-warning hr {\n border-top-color: #ffe8a1;\n}\n\n.alert-warning .alert-link {\n color: #533f03;\n}\n\n.alert-danger {\n color: #721c24;\n background-color: #f8d7da;\n border-color: #f5c6cb;\n}\n\n.alert-danger hr {\n border-top-color: #f1b0b7;\n}\n\n.alert-danger .alert-link {\n color: #491217;\n}\n\n.alert-light {\n color: #818182;\n background-color: #fefefe;\n border-color: #fdfdfe;\n}\n\n.alert-light hr {\n border-top-color: #ececf6;\n}\n\n.alert-light .alert-link {\n color: #686868;\n}\n\n.alert-dark {\n color: #1b1e21;\n background-color: #d6d8d9;\n border-color: #c6c8ca;\n}\n\n.alert-dark hr {\n border-top-color: #b9bbbe;\n}\n\n.alert-dark .alert-link {\n color: #040505;\n}\n\n@keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n.progress {\n display: flex;\n height: 1rem;\n overflow: hidden;\n font-size: 0.75rem;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n color: #fff;\n text-align: center;\n background-color: #007bff;\n transition: width 0.6s ease;\n}\n\n.progress-bar-striped {\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 1rem 1rem;\n}\n\n.progress-bar-animated {\n animation: progress-bar-stripes 1s linear infinite;\n}\n\n.media {\n display: flex;\n align-items: flex-start;\n}\n\n.media-body {\n flex: 1;\n}\n\n.list-group {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n}\n\n.list-group-item-action {\n width: 100%;\n color: #495057;\n text-align: inherit;\n}\n\n.list-group-item-action:hover, .list-group-item-action:focus {\n color: #495057;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.list-group-item-action:active {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 0.75rem 1.25rem;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.list-group-item:hover, .list-group-item:focus {\n z-index: 1;\n text-decoration: none;\n}\n\n.list-group-item.disabled, .list-group-item:disabled {\n color: #6c757d;\n background-color: #fff;\n}\n\n.list-group-item.active {\n z-index: 2;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.list-group-flush .list-group-item {\n border-right: 0;\n border-left: 0;\n border-radius: 0;\n}\n\n.list-group-flush:first-child .list-group-item:first-child {\n border-top: 0;\n}\n\n.list-group-flush:last-child .list-group-item:last-child {\n border-bottom: 0;\n}\n\n.list-group-item-primary {\n color: #004085;\n background-color: #b8daff;\n}\n\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n color: #004085;\n background-color: #9fcdff;\n}\n\n.list-group-item-primary.list-group-item-action.active {\n color: #fff;\n background-color: #004085;\n border-color: #004085;\n}\n\n.list-group-item-secondary {\n color: #383d41;\n background-color: #d6d8db;\n}\n\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n color: #383d41;\n background-color: #c8cbcf;\n}\n\n.list-group-item-secondary.list-group-item-action.active {\n color: #fff;\n background-color: #383d41;\n border-color: #383d41;\n}\n\n.list-group-item-success {\n color: #155724;\n background-color: #c3e6cb;\n}\n\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n color: #155724;\n background-color: #b1dfbb;\n}\n\n.list-group-item-success.list-group-item-action.active {\n color: #fff;\n background-color: #155724;\n border-color: #155724;\n}\n\n.list-group-item-info {\n color: #0c5460;\n background-color: #bee5eb;\n}\n\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n color: #0c5460;\n background-color: #abdde5;\n}\n\n.list-group-item-info.list-group-item-action.active {\n color: #fff;\n background-color: #0c5460;\n border-color: #0c5460;\n}\n\n.list-group-item-warning {\n color: #856404;\n background-color: #ffeeba;\n}\n\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n color: #856404;\n background-color: #ffe8a1;\n}\n\n.list-group-item-warning.list-group-item-action.active {\n color: #fff;\n background-color: #856404;\n border-color: #856404;\n}\n\n.list-group-item-danger {\n color: #721c24;\n background-color: #f5c6cb;\n}\n\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n color: #721c24;\n background-color: #f1b0b7;\n}\n\n.list-group-item-danger.list-group-item-action.active {\n color: #fff;\n background-color: #721c24;\n border-color: #721c24;\n}\n\n.list-group-item-light {\n color: #818182;\n background-color: #fdfdfe;\n}\n\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n color: #818182;\n background-color: #ececf6;\n}\n\n.list-group-item-light.list-group-item-action.active {\n color: #fff;\n background-color: #818182;\n border-color: #818182;\n}\n\n.list-group-item-dark {\n color: #1b1e21;\n background-color: #c6c8ca;\n}\n\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n color: #1b1e21;\n background-color: #b9bbbe;\n}\n\n.list-group-item-dark.list-group-item-action.active {\n color: #fff;\n background-color: #1b1e21;\n border-color: #1b1e21;\n}\n\n.close {\n float: right;\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: .5;\n}\n\n.close:hover, .close:focus {\n color: #000;\n text-decoration: none;\n opacity: .75;\n}\n\n.close:not(:disabled):not(.disabled) {\n cursor: pointer;\n}\n\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n\n.modal-open {\n overflow: hidden;\n}\n\n.modal {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n display: none;\n overflow: hidden;\n outline: 0;\n}\n\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 0.5rem;\n pointer-events: none;\n}\n\n.modal.fade .modal-dialog {\n transition: transform 0.3s ease-out;\n transform: translate(0, -25%);\n}\n\n.modal.show .modal-dialog {\n transform: translate(0, 0);\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: calc(100% - (0.5rem * 2));\n}\n\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n pointer-events: auto;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n outline: 0;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n\n.modal-backdrop.fade {\n opacity: 0;\n}\n\n.modal-backdrop.show {\n opacity: 0.5;\n}\n\n.modal-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 1rem;\n border-bottom: 1px solid #e9ecef;\n border-top-left-radius: 0.3rem;\n border-top-right-radius: 0.3rem;\n}\n\n.modal-header .close {\n padding: 1rem;\n margin: -1rem -1rem -1rem auto;\n}\n\n.modal-title {\n margin-bottom: 0;\n line-height: 1.5;\n}\n\n.modal-body {\n position: relative;\n flex: 1 1 auto;\n padding: 1rem;\n}\n\n.modal-footer {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n padding: 1rem;\n border-top: 1px solid #e9ecef;\n}\n\n.modal-footer > :not(:first-child) {\n margin-left: .25rem;\n}\n\n.modal-footer > :not(:last-child) {\n margin-right: .25rem;\n}\n\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n@media (min-width: 576px) {\n .modal-dialog {\n max-width: 500px;\n margin: 1.75rem auto;\n }\n .modal-dialog-centered {\n min-height: calc(100% - (1.75rem * 2));\n }\n .modal-sm {\n max-width: 300px;\n }\n}\n\n@media (min-width: 992px) {\n .modal-lg {\n max-width: 800px;\n }\n}\n\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n opacity: 0;\n}\n\n.tooltip.show {\n opacity: 0.9;\n}\n\n.tooltip .arrow {\n position: absolute;\n display: block;\n width: 0.8rem;\n height: 0.4rem;\n}\n\n.tooltip .arrow::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-tooltip-top, .bs-tooltip-auto[x-placement^=\"top\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^=\"top\"] .arrow {\n bottom: 0;\n}\n\n.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^=\"top\"] .arrow::before {\n top: 0;\n border-width: 0.4rem 0.4rem 0;\n border-top-color: #000;\n}\n\n.bs-tooltip-right, .bs-tooltip-auto[x-placement^=\"right\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^=\"right\"] .arrow {\n left: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^=\"right\"] .arrow::before {\n right: 0;\n border-width: 0.4rem 0.4rem 0.4rem 0;\n border-right-color: #000;\n}\n\n.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^=\"bottom\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow {\n top: 0;\n}\n\n.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow::before {\n bottom: 0;\n border-width: 0 0.4rem 0.4rem;\n border-bottom-color: #000;\n}\n\n.bs-tooltip-left, .bs-tooltip-auto[x-placement^=\"left\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^=\"left\"] .arrow {\n right: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^=\"left\"] .arrow::before {\n left: 0;\n border-width: 0.4rem 0 0.4rem 0.4rem;\n border-left-color: #000;\n}\n\n.tooltip-inner {\n max-width: 200px;\n padding: 0.25rem 0.5rem;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 0.25rem;\n}\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: block;\n max-width: 276px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n}\n\n.popover .arrow {\n position: absolute;\n display: block;\n width: 1rem;\n height: 0.5rem;\n margin: 0 0.3rem;\n}\n\n.popover .arrow::before, .popover .arrow::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-popover-top, .bs-popover-auto[x-placement^=\"top\"] {\n margin-bottom: 0.5rem;\n}\n\n.bs-popover-top .arrow, .bs-popover-auto[x-placement^=\"top\"] .arrow {\n bottom: calc((0.5rem + 1px) * -1);\n}\n\n.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^=\"top\"] .arrow::before,\n.bs-popover-top .arrow::after, .bs-popover-auto[x-placement^=\"top\"] .arrow::after {\n border-width: 0.5rem 0.5rem 0;\n}\n\n.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^=\"top\"] .arrow::before {\n bottom: 0;\n border-top-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-top .arrow::after, .bs-popover-auto[x-placement^=\"top\"] .arrow::after {\n bottom: 1px;\n border-top-color: #fff;\n}\n\n.bs-popover-right, .bs-popover-auto[x-placement^=\"right\"] {\n margin-left: 0.5rem;\n}\n\n.bs-popover-right .arrow, .bs-popover-auto[x-placement^=\"right\"] .arrow {\n left: calc((0.5rem + 1px) * -1);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^=\"right\"] .arrow::before,\n.bs-popover-right .arrow::after, .bs-popover-auto[x-placement^=\"right\"] .arrow::after {\n border-width: 0.5rem 0.5rem 0.5rem 0;\n}\n\n.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^=\"right\"] .arrow::before {\n left: 0;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-right .arrow::after, .bs-popover-auto[x-placement^=\"right\"] .arrow::after {\n left: 1px;\n border-right-color: #fff;\n}\n\n.bs-popover-bottom, .bs-popover-auto[x-placement^=\"bottom\"] {\n margin-top: 0.5rem;\n}\n\n.bs-popover-bottom .arrow, .bs-popover-auto[x-placement^=\"bottom\"] .arrow {\n top: calc((0.5rem + 1px) * -1);\n}\n\n.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::before,\n.bs-popover-bottom .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::after {\n border-width: 0 0.5rem 0.5rem 0.5rem;\n}\n\n.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::before {\n top: 0;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-bottom .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] .arrow::after {\n top: 1px;\n border-bottom-color: #fff;\n}\n\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^=\"bottom\"] .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: 1rem;\n margin-left: -0.5rem;\n content: \"\";\n border-bottom: 1px solid #f7f7f7;\n}\n\n.bs-popover-left, .bs-popover-auto[x-placement^=\"left\"] {\n margin-right: 0.5rem;\n}\n\n.bs-popover-left .arrow, .bs-popover-auto[x-placement^=\"left\"] .arrow {\n right: calc((0.5rem + 1px) * -1);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^=\"left\"] .arrow::before,\n.bs-popover-left .arrow::after, .bs-popover-auto[x-placement^=\"left\"] .arrow::after {\n border-width: 0.5rem 0 0.5rem 0.5rem;\n}\n\n.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^=\"left\"] .arrow::before {\n right: 0;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-left .arrow::after, .bs-popover-auto[x-placement^=\"left\"] .arrow::after {\n right: 1px;\n border-left-color: #fff;\n}\n\n.popover-header {\n padding: 0.5rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n color: inherit;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.popover-header:empty {\n display: none;\n}\n\n.popover-body {\n padding: 0.5rem 0.75rem;\n color: #212529;\n}\n\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n\n.carousel-item {\n position: relative;\n display: none;\n align-items: center;\n width: 100%;\n transition: transform 0.6s ease;\n backface-visibility: hidden;\n perspective: 1000px;\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next,\n.carousel-item-prev {\n position: absolute;\n top: 0;\n}\n\n.carousel-item-next.carousel-item-left,\n.carousel-item-prev.carousel-item-right {\n transform: translateX(0);\n}\n\n@supports (transform-style: preserve-3d) {\n .carousel-item-next.carousel-item-left,\n .carousel-item-prev.carousel-item-right {\n transform: translate3d(0, 0, 0);\n }\n}\n\n.carousel-item-next,\n.active.carousel-item-right {\n transform: translateX(100%);\n}\n\n@supports (transform-style: preserve-3d) {\n .carousel-item-next,\n .active.carousel-item-right {\n transform: translate3d(100%, 0, 0);\n }\n}\n\n.carousel-item-prev,\n.active.carousel-item-left {\n transform: translateX(-100%);\n}\n\n@supports (transform-style: preserve-3d) {\n .carousel-item-prev,\n .active.carousel-item-left {\n transform: translate3d(-100%, 0, 0);\n }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 15%;\n color: #fff;\n text-align: center;\n opacity: 0.5;\n}\n\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n opacity: .9;\n}\n\n.carousel-control-prev {\n left: 0;\n}\n\n.carousel-control-next {\n right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n background: transparent no-repeat center center;\n background-size: 100% 100%;\n}\n\n.carousel-control-prev-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E\");\n}\n\n.carousel-control-next-icon {\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E\");\n}\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 10px;\n left: 0;\n z-index: 15;\n display: flex;\n justify-content: center;\n padding-left: 0;\n margin-right: 15%;\n margin-left: 15%;\n list-style: none;\n}\n\n.carousel-indicators li {\n position: relative;\n flex: 0 1 auto;\n width: 30px;\n height: 3px;\n margin-right: 3px;\n margin-left: 3px;\n text-indent: -999px;\n background-color: rgba(255, 255, 255, 0.5);\n}\n\n.carousel-indicators li::before {\n position: absolute;\n top: -10px;\n left: 0;\n display: inline-block;\n width: 100%;\n height: 10px;\n content: \"\";\n}\n\n.carousel-indicators li::after {\n position: absolute;\n bottom: -10px;\n left: 0;\n display: inline-block;\n width: 100%;\n height: 10px;\n content: \"\";\n}\n\n.carousel-indicators .active {\n background-color: #fff;\n}\n\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n}\n\n.align-baseline {\n vertical-align: baseline !important;\n}\n\n.align-top {\n vertical-align: top !important;\n}\n\n.align-middle {\n vertical-align: middle !important;\n}\n\n.align-bottom {\n vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n vertical-align: text-top !important;\n}\n\n.bg-primary {\n background-color: #007bff !important;\n}\n\na.bg-primary:hover, a.bg-primary:focus,\nbutton.bg-primary:hover,\nbutton.bg-primary:focus {\n background-color: #0062cc !important;\n}\n\n.bg-secondary {\n background-color: #6c757d !important;\n}\n\na.bg-secondary:hover, a.bg-secondary:focus,\nbutton.bg-secondary:hover,\nbutton.bg-secondary:focus {\n background-color: #545b62 !important;\n}\n\n.bg-success {\n background-color: #28a745 !important;\n}\n\na.bg-success:hover, a.bg-success:focus,\nbutton.bg-success:hover,\nbutton.bg-success:focus {\n background-color: #1e7e34 !important;\n}\n\n.bg-info {\n background-color: #17a2b8 !important;\n}\n\na.bg-info:hover, a.bg-info:focus,\nbutton.bg-info:hover,\nbutton.bg-info:focus {\n background-color: #117a8b !important;\n}\n\n.bg-warning {\n background-color: #ffc107 !important;\n}\n\na.bg-warning:hover, a.bg-warning:focus,\nbutton.bg-warning:hover,\nbutton.bg-warning:focus {\n background-color: #d39e00 !important;\n}\n\n.bg-danger {\n background-color: #dc3545 !important;\n}\n\na.bg-danger:hover, a.bg-danger:focus,\nbutton.bg-danger:hover,\nbutton.bg-danger:focus {\n background-color: #bd2130 !important;\n}\n\n.bg-light {\n background-color: #f8f9fa !important;\n}\n\na.bg-light:hover, a.bg-light:focus,\nbutton.bg-light:hover,\nbutton.bg-light:focus {\n background-color: #dae0e5 !important;\n}\n\n.bg-dark {\n background-color: #343a40 !important;\n}\n\na.bg-dark:hover, a.bg-dark:focus,\nbutton.bg-dark:hover,\nbutton.bg-dark:focus {\n background-color: #1d2124 !important;\n}\n\n.bg-white {\n background-color: #fff !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n\n.border {\n border: 1px solid #dee2e6 !important;\n}\n\n.border-top {\n border-top: 1px solid #dee2e6 !important;\n}\n\n.border-right {\n border-right: 1px solid #dee2e6 !important;\n}\n\n.border-bottom {\n border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-left {\n border-left: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n border: 0 !important;\n}\n\n.border-top-0 {\n border-top: 0 !important;\n}\n\n.border-right-0 {\n border-right: 0 !important;\n}\n\n.border-bottom-0 {\n border-bottom: 0 !important;\n}\n\n.border-left-0 {\n border-left: 0 !important;\n}\n\n.border-primary {\n border-color: #007bff !important;\n}\n\n.border-secondary {\n border-color: #6c757d !important;\n}\n\n.border-success {\n border-color: #28a745 !important;\n}\n\n.border-info {\n border-color: #17a2b8 !important;\n}\n\n.border-warning {\n border-color: #ffc107 !important;\n}\n\n.border-danger {\n border-color: #dc3545 !important;\n}\n\n.border-light {\n border-color: #f8f9fa !important;\n}\n\n.border-dark {\n border-color: #343a40 !important;\n}\n\n.border-white {\n border-color: #fff !important;\n}\n\n.rounded {\n border-radius: 0.25rem !important;\n}\n\n.rounded-top {\n border-top-left-radius: 0.25rem !important;\n border-top-right-radius: 0.25rem !important;\n}\n\n.rounded-right {\n border-top-right-radius: 0.25rem !important;\n border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-left {\n border-top-left-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n\n.clearfix::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n}\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n}\n\n.embed-responsive::before {\n display: block;\n content: \"\";\n}\n\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n\n.embed-responsive-21by9::before {\n padding-top: 42.857143%;\n}\n\n.embed-responsive-16by9::before {\n padding-top: 56.25%;\n}\n\n.embed-responsive-4by3::before {\n padding-top: 75%;\n}\n\n.embed-responsive-1by1::before {\n padding-top: 100%;\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n}\n\n.float-left {\n float: left !important;\n}\n\n.float-right {\n float: right !important;\n}\n\n.float-none {\n float: none !important;\n}\n\n@media (min-width: 576px) {\n .float-sm-left {\n float: left !important;\n }\n .float-sm-right {\n float: right !important;\n }\n .float-sm-none {\n float: none !important;\n }\n}\n\n@media (min-width: 768px) {\n .float-md-left {\n float: left !important;\n }\n .float-md-right {\n float: right !important;\n }\n .float-md-none {\n float: none !important;\n }\n}\n\n@media (min-width: 992px) {\n .float-lg-left {\n float: left !important;\n }\n .float-lg-right {\n float: right !important;\n }\n .float-lg-none {\n float: none !important;\n }\n}\n\n@media (min-width: 1200px) {\n .float-xl-left {\n float: left !important;\n }\n .float-xl-right {\n float: right !important;\n }\n .float-xl-none {\n float: none !important;\n }\n}\n\n.position-static {\n position: static !important;\n}\n\n.position-relative {\n position: relative !important;\n}\n\n.position-absolute {\n position: absolute !important;\n}\n\n.position-fixed {\n position: fixed !important;\n}\n\n.position-sticky {\n position: sticky !important;\n}\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1030;\n}\n\n@supports (position: sticky) {\n .sticky-top {\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n}\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n clip-path: inset(50%);\n border: 0;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n clip-path: none;\n}\n\n.w-25 {\n width: 25% !important;\n}\n\n.w-50 {\n width: 50% !important;\n}\n\n.w-75 {\n width: 75% !important;\n}\n\n.w-100 {\n width: 100% !important;\n}\n\n.h-25 {\n height: 25% !important;\n}\n\n.h-50 {\n height: 50% !important;\n}\n\n.h-75 {\n height: 75% !important;\n}\n\n.h-100 {\n height: 100% !important;\n}\n\n.mw-100 {\n max-width: 100% !important;\n}\n\n.mh-100 {\n max-height: 100% !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n\n.text-justify {\n text-align: justify !important;\n}\n\n.text-nowrap {\n white-space: nowrap !important;\n}\n\n.text-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.text-left {\n text-align: left !important;\n}\n\n.text-right {\n text-align: right !important;\n}\n\n.text-center {\n text-align: center !important;\n}\n\n@media (min-width: 576px) {\n .text-sm-left {\n text-align: left !important;\n }\n .text-sm-right {\n text-align: right !important;\n }\n .text-sm-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 768px) {\n .text-md-left {\n text-align: left !important;\n }\n .text-md-right {\n text-align: right !important;\n }\n .text-md-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 992px) {\n .text-lg-left {\n text-align: left !important;\n }\n .text-lg-right {\n text-align: right !important;\n }\n .text-lg-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 1200px) {\n .text-xl-left {\n text-align: left !important;\n }\n .text-xl-right {\n text-align: right !important;\n }\n .text-xl-center {\n text-align: center !important;\n }\n}\n\n.text-lowercase {\n text-transform: lowercase !important;\n}\n\n.text-uppercase {\n text-transform: uppercase !important;\n}\n\n.text-capitalize {\n text-transform: capitalize !important;\n}\n\n.font-weight-light {\n font-weight: 300 !important;\n}\n\n.font-weight-normal {\n font-weight: 400 !important;\n}\n\n.font-weight-bold {\n font-weight: 700 !important;\n}\n\n.font-italic {\n font-style: italic !important;\n}\n\n.text-white {\n color: #fff !important;\n}\n\n.text-primary {\n color: #007bff !important;\n}\n\na.text-primary:hover, a.text-primary:focus {\n color: #0062cc !important;\n}\n\n.text-secondary {\n color: #6c757d !important;\n}\n\na.text-secondary:hover, a.text-secondary:focus {\n color: #545b62 !important;\n}\n\n.text-success {\n color: #28a745 !important;\n}\n\na.text-success:hover, a.text-success:focus {\n color: #1e7e34 !important;\n}\n\n.text-info {\n color: #17a2b8 !important;\n}\n\na.text-info:hover, a.text-info:focus {\n color: #117a8b !important;\n}\n\n.text-warning {\n color: #ffc107 !important;\n}\n\na.text-warning:hover, a.text-warning:focus {\n color: #d39e00 !important;\n}\n\n.text-danger {\n color: #dc3545 !important;\n}\n\na.text-danger:hover, a.text-danger:focus {\n color: #bd2130 !important;\n}\n\n.text-light {\n color: #f8f9fa !important;\n}\n\na.text-light:hover, a.text-light:focus {\n color: #dae0e5 !important;\n}\n\n.text-dark {\n color: #343a40 !important;\n}\n\na.text-dark:hover, a.text-dark:focus {\n color: #1d2124 !important;\n}\n\n.text-muted {\n color: #6c757d !important;\n}\n\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n\n@media print {\n *,\n *::before,\n *::after {\n text-shadow: none !important;\n box-shadow: none !important;\n }\n a:not(.btn) {\n text-decoration: underline;\n }\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n @page {\n size: a3;\n }\n body {\n min-width: 992px !important;\n }\n .container {\n min-width: 992px !important;\n }\n .navbar {\n display: none;\n }\n .badge {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n\n/*# sourceMappingURL=bootstrap.css.map */","// stylelint-disable indentation\n\n// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Origally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS—an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular psuedo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover {\n &:hover { @content; }\n}\n\n@mixin hover-focus {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n","// stylelint-disable declaration-no-important, selector-list-comma-newline-after\n\n//\n// Headings\n//\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: $headings-margin-bottom;\n font-family: $headings-font-family;\n font-weight: $headings-font-weight;\n line-height: $headings-line-height;\n color: $headings-color;\n}\n\nh1, .h1 { font-size: $h1-font-size; }\nh2, .h2 { font-size: $h2-font-size; }\nh3, .h3 { font-size: $h3-font-size; }\nh4, .h4 { font-size: $h4-font-size; }\nh5, .h5 { font-size: $h5-font-size; }\nh6, .h6 { font-size: $h6-font-size; }\n\n.lead {\n font-size: $lead-font-size;\n font-weight: $lead-font-weight;\n}\n\n// Type display classes\n.display-1 {\n font-size: $display1-size;\n font-weight: $display1-weight;\n line-height: $display-line-height;\n}\n.display-2 {\n font-size: $display2-size;\n font-weight: $display2-weight;\n line-height: $display-line-height;\n}\n.display-3 {\n font-size: $display3-size;\n font-weight: $display3-weight;\n line-height: $display-line-height;\n}\n.display-4 {\n font-size: $display4-size;\n font-weight: $display4-weight;\n line-height: $display-line-height;\n}\n\n\n//\n// Horizontal rules\n//\n\nhr {\n margin-top: $hr-margin-y;\n margin-bottom: $hr-margin-y;\n border: 0;\n border-top: $hr-border-width solid $hr-border-color;\n}\n\n\n//\n// Emphasis\n//\n\nsmall,\n.small {\n font-size: $small-font-size;\n font-weight: $font-weight-normal;\n}\n\nmark,\n.mark {\n padding: $mark-padding;\n background-color: $mark-bg;\n}\n\n\n//\n// Lists\n//\n\n.list-unstyled {\n @include list-unstyled;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n @include list-unstyled;\n}\n.list-inline-item {\n display: inline-block;\n\n &:not(:last-child) {\n margin-right: $list-inline-padding;\n }\n}\n\n\n//\n// Misc\n//\n\n// Builds on `abbr`\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n// Blockquotes\n.blockquote {\n margin-bottom: $spacer;\n font-size: $blockquote-font-size;\n}\n\n.blockquote-footer {\n display: block;\n font-size: 80%; // back to default font-size\n color: $blockquote-small-color;\n\n &::before {\n content: \"\\2014 \\00A0\"; // em dash, nbsp\n }\n}\n","// Lists\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n@mixin list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n","// Responsive images (ensure images don't scale beyond their parents)\n//\n// This is purposefully opt-in via an explicit class rather than being the default for all ``s.\n// We previously tried the \"images are responsive by default\" approach in Bootstrap v2,\n// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)\n// which weren't expecting the images within themselves to be involuntarily resized.\n// See also https://github.com/twbs/bootstrap/issues/18178\n.img-fluid {\n @include img-fluid;\n}\n\n\n// Image thumbnails\n.img-thumbnail {\n padding: $thumbnail-padding;\n background-color: $thumbnail-bg;\n border: $thumbnail-border-width solid $thumbnail-border-color;\n @include border-radius($thumbnail-border-radius);\n @include box-shadow($thumbnail-box-shadow);\n\n // Keep them at most 100% wide\n @include img-fluid;\n}\n\n//\n// Figures\n//\n\n.figure {\n // Ensures the caption's text aligns with the image.\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: ($spacer / 2);\n line-height: 1;\n}\n\n.figure-caption {\n font-size: $figure-caption-font-size;\n color: $figure-caption-color;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n@mixin img-fluid {\n // Part 1: Set a maximum relative to the parent\n max-width: 100%;\n // Part 2: Override the height to auto, otherwise images will be stretched\n // when setting a width and height attribute on the img element.\n height: auto;\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size.\n\n// stylelint-disable indentation, media-query-list-comma-newline-after\n@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {\n background-image: url($file-1x);\n\n // Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio,\n // but doesn't convert dppx=>dpi.\n // There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard.\n // Compatibility info: https://caniuse.com/#feat=css-media-resolution\n @media only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx\n only screen and (min-resolution: 2dppx) { // Standardized\n background-image: url($file-2x);\n background-size: $width-1x $height-1x;\n }\n}\n","// Single side border-radius\n\n@mixin border-radius($radius: $border-radius) {\n @if $enable-rounded {\n border-radius: $radius;\n }\n}\n\n@mixin border-top-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-top-right-radius: $radius;\n }\n}\n\n@mixin border-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: $radius;\n border-bottom-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n\n@mixin border-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n","// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: $font-family-monospace;\n}\n\n// Inline code\ncode {\n font-size: $code-font-size;\n color: $code-color;\n word-break: break-word;\n\n // Streamline the style when inside anchors to avoid broken underline and more\n a > & {\n color: inherit;\n }\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: $kbd-padding-y $kbd-padding-x;\n font-size: $kbd-font-size;\n color: $kbd-color;\n background-color: $kbd-bg;\n @include border-radius($border-radius-sm);\n @include box-shadow($kbd-box-shadow);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: $nested-kbd-font-weight;\n @include box-shadow(none);\n }\n}\n\n// Blocks of code\npre {\n display: block;\n font-size: $code-font-size;\n color: $pre-color;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: $pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n .container {\n @include make-container();\n @include make-container-max-widths();\n }\n}\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but with 100% width for\n// fluid, full width layouts.\n\n@if $enable-grid-classes {\n .container-fluid {\n @include make-container();\n }\n}\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n }\n\n // Remove the negative margin from default .row, then the horizontal padding\n // from all immediate children columns (to prevent runaway style inheritance).\n .no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n }\n}\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container() {\n width: 100%;\n padding-right: ($grid-gutter-width / 2);\n padding-left: ($grid-gutter-width / 2);\n margin-right: auto;\n margin-left: auto;\n}\n\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n}\n\n@mixin make-row() {\n display: flex;\n flex-wrap: wrap;\n margin-right: ($grid-gutter-width / -2);\n margin-left: ($grid-gutter-width / -2);\n}\n\n@mixin make-col-ready() {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n min-height: 1px; // Prevent collapsing\n padding-right: ($grid-gutter-width / 2);\n padding-left: ($grid-gutter-width / 2);\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02px, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash infront.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n // Common properties for all breakpoints\n %grid-column {\n position: relative;\n width: 100%;\n min-height: 1px; // Prevent columns from collapsing when empty\n padding-right: ($gutter / 2);\n padding-left: ($gutter / 2);\n }\n\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n // Allow columns to stretch full width below their breakpoints\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @extend %grid-column;\n }\n }\n .col#{$infix},\n .col#{$infix}-auto {\n @extend %grid-column;\n }\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col#{$infix}-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: none; // Reset earlier grid tiers\n }\n\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n\n .order#{$infix}-first { order: -1; }\n\n .order#{$infix}-last { order: $columns + 1; }\n\n @for $i from 0 through $columns {\n .order#{$infix}-#{$i} { order: $i; }\n }\n\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n }\n}\n","//\n// Basic Bootstrap table\n//\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: $spacer;\n background-color: $table-bg; // Reset for nesting within parents with `background-color`.\n\n th,\n td {\n padding: $table-cell-padding;\n vertical-align: top;\n border-top: $table-border-width solid $table-border-color;\n }\n\n thead th {\n vertical-align: bottom;\n border-bottom: (2 * $table-border-width) solid $table-border-color;\n }\n\n tbody + tbody {\n border-top: (2 * $table-border-width) solid $table-border-color;\n }\n\n .table {\n background-color: $body-bg;\n }\n}\n\n\n//\n// Condensed table w/ half padding\n//\n\n.table-sm {\n th,\n td {\n padding: $table-cell-padding-sm;\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: $table-border-width solid $table-border-color;\n\n th,\n td {\n border: $table-border-width solid $table-border-color;\n }\n\n thead {\n th,\n td {\n border-bottom-width: (2 * $table-border-width);\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n tbody tr:nth-of-type(odd) {\n background-color: $table-accent-bg;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n tbody tr {\n @include hover {\n background-color: $table-hover-bg;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n@each $color, $value in $theme-colors {\n @include table-row-variant($color, theme-color-level($color, -9));\n}\n\n@include table-row-variant(active, $table-active-bg);\n\n\n// Dark styles\n//\n// Same table markup, but inverted color scheme: dark background and light text.\n\n// stylelint-disable-next-line no-duplicate-selectors\n.table {\n .thead-dark {\n th {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n border-color: $table-dark-border-color;\n }\n }\n\n .thead-light {\n th {\n color: $table-head-color;\n background-color: $table-head-bg;\n border-color: $table-border-color;\n }\n }\n}\n\n.table-dark {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n\n th,\n td,\n thead th {\n border-color: $table-dark-border-color;\n }\n\n &.table-bordered {\n border: 0;\n }\n\n &.table-striped {\n tbody tr:nth-of-type(odd) {\n background-color: $table-dark-accent-bg;\n }\n }\n\n &.table-hover {\n tbody tr {\n @include hover {\n background-color: $table-dark-hover-bg;\n }\n }\n }\n}\n\n\n// Responsive tables\n//\n// Generate series of `.table-responsive-*` classes for configuring the screen\n// size of where your table will overflow.\n\n.table-responsive {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $next: breakpoint-next($breakpoint, $grid-breakpoints);\n $infix: breakpoint-infix($next, $grid-breakpoints);\n\n &#{$infix} {\n @include media-breakpoint-down($breakpoint) {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n -ms-overflow-style: -ms-autohiding-scrollbar; // See https://github.com/twbs/bootstrap/pull/10057\n\n // Prevent double border on horizontal scroll due to use of `display: block;`\n > .table-bordered {\n border: 0;\n }\n }\n }\n }\n}\n","// Tables\n\n@mixin table-row-variant($state, $background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table-#{$state} {\n &,\n > th,\n > td {\n background-color: $background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover {\n $hover-background: darken($background, 5%);\n\n .table-#{$state} {\n @include hover {\n background-color: $hover-background;\n\n > td,\n > th {\n background-color: $hover-background;\n }\n }\n }\n }\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Textual form controls\n//\n\n.form-control {\n display: block;\n width: 100%;\n padding: $input-padding-y $input-padding-x;\n font-size: $font-size-base;\n line-height: $input-line-height;\n color: $input-color;\n background-color: $input-bg;\n background-clip: padding-box;\n border: $input-border-width solid $input-border-color;\n\n // Note: This has no effect on `s in CSS.\n @if $enable-rounded {\n // Manually use the if/else instead of the mixin to account for iOS override\n border-radius: $input-border-radius;\n } @else {\n // Otherwise undo the iOS default\n border-radius: 0;\n }\n\n @include box-shadow($input-box-shadow);\n @include transition($input-transition);\n\n // Unstyle the caret on ` receives focus\n // in IE and (under certain conditions) Edge, as it looks bad and cannot be made to\n // match the appearance of the native widget.\n // See https://github.com/twbs/bootstrap/issues/19398.\n color: $input-color;\n background-color: $input-bg;\n }\n}\n\n// Make file inputs better match text inputs by forcing them to new lines.\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n\n//\n// Labels\n//\n\n// For use with horizontal and inline forms, when you need the label (or legend)\n// text to align with the form controls.\n.col-form-label {\n padding-top: calc(#{$input-padding-y} + #{$input-border-width});\n padding-bottom: calc(#{$input-padding-y} + #{$input-border-width});\n margin-bottom: 0; // Override the `
    +{{elif request.function=='select':}} +

    {{=XML(str(T("Database %s select"))%A(request.args[0],_href=URL('index'))) }} +

    + {{if tb:}} +

    {{=T('Traceback')}}

    +
    +    {{=tb}}
    +  
    + {{pass}} + {{if table:}} + {{=A(str(T('New Record')),_href=URL('insert',args=[request.args[0],table]),_class="btn btn-primary", _role="button")}}

    +
    +

    {{=T("Rows in Table")}}


    + {{else:}} +

    {{=T("Rows selected")}}


    + {{pass}} + {{=form}} +

    {{=T('The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.')}}
    + {{=T('Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.')}}
    + {{=T('"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN')}}

    +

    +

    {{=T("%s selected", nrows)}}

    + {{if start>0:}}{{=A(T('previous %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start-step)),_class="btn btn-primary")}}{{pass}} + {{if stop + {{linkto = lambda f, t, r: URL('update', args=[request.args[0], r, f]) if f else "#"}} + {{upload=URL('download',args=request.args[0])}} + {{=SQLTABLE(rows,linkto,upload,orderby=True,_class='table table-striped table-bordered sortable')}} + + {{pass}} +

    +
    +

    {{=T("Import/Export")}}


    +
    {{=T("export as csv file")}} + {{=formcsv or ''}} + +{{elif request.function=='insert':}} +

    {{=T("Database")}} {{=A(request.args[0],_href=URL('index'))}} + {{if hasattr(table,'_primarykey'):}} + {{fieldname=table._primarykey[0]}} + {{dbname=request.args[0]}} + {{tablename=request.args[1]}} + {{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}} + {{=T("Table")}} {{=A(tablename,_href=URL('select',args=dbname,vars=dict(query='%s.%s.%s%s'%(dbname,tablename,fieldname,cond))))}} + {{else:}} + {{=T("Table")}} {{=A(request.args[1],_href=URL('select',args=request.args[0],vars=dict(query='%s.%s.id>0'%tuple(request.args[:2]))))}} + {{pass}} +

    +

    {{=T("New Record")}}


    + {{=form}} +{{elif request.function=='update':}} +

    {{=T("Database")}} {{=A(request.args[0],_href=URL('index'))}} + {{if hasattr(table,'_primarykey'):}} + {{fieldname=request.vars.keys()[0]}} + {{dbname=request.args[0]}} + {{tablename=request.args[1]}} + {{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}} + {{=T("Table")}} {{=A(tablename,_href=URL('select',args=dbname,vars=dict(query='%s.%s.%s%s'%(dbname,tablename,fieldname,cond))))}} + {{=T("Record")}} {{=A('%s=%s'%request.vars.items()[0],_href=URL('update',args=request.args[:2],vars=request.vars))}} + {{else:}} + {{=T("Table")}} {{=A(request.args[1],_href=URL('select',args=request.args[0],vars=dict(query='%s.%s.id>0'%tuple(request.args[:2]))))}} + {{=T("Record id")}} {{=A(request.args[2],_href=URL('update',args=request.args[:3]))}} + {{pass}} +

    +

    {{=T("Edit current record")}}



    {{=form}} + +{{elif request.function=='state':}} +

    {{=T("Internal State")}}

    +

    {{=T("Current request")}}

    + {{=BEAUTIFY(request)}} +

    {{=T("Current response")}}

    + {{=BEAUTIFY(response)}} +

    {{=T("Current session")}}

    + {{=BEAUTIFY(session)}} + + +{{elif request.function == 'ccache':}} +

    {{T("Cache")}}

    +
    + +
    +

    {{T("Statistics")}}

    +
    + +
    +

    {{=T("Overview")}}

    +

    {{=T.M("Number of entries: **%s**", total['entries'])}}

    + {{if total['entries'] > 0:}} +

    {{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})", + dict( ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}} +

    +

    + {{=T("Size of cache:")}} + {{if object_stats:}} + {{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict(items=total['objects'], bytes=total['bytes']))}} + {{if total['bytes'] > 524287:}} + {{=T.M("(**%.0d MB**)", total['bytes'] / 1048576)}} + {{pass}} + {{else:}} + {{=T.M("**not available** (requires the Python [[Pympler https://pypi.python.org/pypi/Pympler popup]] library)")}} + {{pass}} +

    +

    + {{=T.M("Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.", + dict(hours=total['oldest'][0], min=total['oldest'][1], sec=total['oldest'][2]))}} +

    + {{=BUTTON(T('Cache Keys'), _onclick='jQuery("#all_keys").toggle().toggleClass( "w2p_hidden" );')}} +
    + {{=total['keys']}} +
    +
    + {{pass}} + +

    {{=T("RAM")}}

    +

    {{=T.M("Number of entries: **%s**", ram['entries'])}}

    + {{if ram['entries'] > 0:}} +

    {{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})", + dict( ratio=ram['ratio'], hits=ram['hits'], misses=ram['misses']))}} +

    +

    + {{=T("Size of cache:")}} + {{if object_stats:}} + {{=T.M("**%(items)s** items, **%(bytes)s** %%{byte(bytes)}", dict(items=ram['objects'], bytes=ram['bytes']))}} + {{if ram['bytes'] > 524287:}} + {{=T.M("(**%.0d MB**)", ram['bytes'] / 10485576)}} + {{pass}} + {{else:}} + {{=T.M("``**not available**``:red (requires the Python [[Pympler https://pypi.python.org/pypi/Pympler popup]] library)")}} + {{pass}} +

    +

    + {{=T.M("RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.", + dict(hours=ram['oldest'][0], min=ram['oldest'][1], sec=ram['oldest'][2]))}} +

    + {{=BUTTON(T('RAM Cache Keys'), _onclick='jQuery("#ram_keys").toggle().toggleClass( "w2p_hidden" );')}} +
    + {{=ram['keys']}} +
    +
    + {{pass}} + +

    {{=T("DISK")}}

    +

    {{=T.M("Number of entries: **%s**", disk['entries'])}}

    + {{if disk['entries'] > 0:}} +

    + {{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})", + dict(ratio=disk['ratio'], hits=disk['hits'], misses=disk['misses']))}} +

    +

    + {{=T("Size of cache:")}} + {{if object_stats:}} + {{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict( items=disk['objects'], bytes=disk['bytes']))}} + {{if disk['bytes'] > 524287:}} + {{=T.M("(**%.0d MB**)", disk['bytes'] / 1048576)}} + {{pass}} + {{else:}} + {{=T.M("``**not available**``:red (requires the Python [[Pympler https://pypi.python.org/pypi/Pympler popup]] library)")}} + {{pass}} +

    +

    + {{=T.M("DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.", + dict(hours=disk['oldest'][0], min=disk['oldest'][1], sec=disk['oldest'][2]))}} +

    + {{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle().toggleClass( "w2p_hidden" );')}} +
    + {{=disk['keys']}} +
    +
    + {{pass}} +
    + +
    +

    {{=T("Manage Cache")}}

    +
    + +
    +

    + {{=form}} +

    +
    +
    +
    +{{pass}} + +{{if request.function=='d3_graph_model':}} +

    {{=T("Graph Model")}}

    + {{if not databases:}} + {{=T("No databases in this application")}} + {{else:}} +
    + + + {{pass}} +{{pass}} + +{{if request.function == 'manage':}} +

    {{=heading}}

    + + +
    + {{for k, tablename in enumerate(tablenames):}} +
    + {{=LOAD(f='manage.load', args=[request.args(0), k], ajax=True)}} +
    + {{pass}} +
    +{{pass}} + + + diff --git a/web2py/applications/welcome/views/default/index.html b/web2py/applications/welcome/views/default/index.html new file mode 100644 index 0000000..9107d64 --- /dev/null +++ b/web2py/applications/welcome/views/default/index.html @@ -0,0 +1,51 @@ +{{extend 'layout.html'}} + +{{block header}} +
    +
    +

    /{{=request.application}}/{{=request.controller}}/{{=request.function}}

    +
    +
    +{{end}} + +
    +
    + {{if 'message' in globals():}} +

    {{=message}}

    +

    {{=T('How did you get here?')}}

    +
      +
    1. {{=T('You are successfully running web2py')}}
    2. +
    3. {{=XML(T('You visited the url %s', A(request.env.path_info,_href=request.env.path_info)))}}
    4. +
    5. {{=XML(T('Which called the function %s located in the file %s', + (A(request.function+'()',_href='#'), + A('web2py/applications/%(application)s/controllers/%(controller)s.py' % request, + _href=URL('admin','default','peek', args=(request.application,'controllers',request.controller+'.py'))))))}}
    6. +
    7. {{=XML(T('The output of the file is a dictionary that was rendered by the view %s', + A('web2py/applications/%(application)s/views/%(controller)s/index.html' % request, + _href=URL('admin','default','peek',args=(request.application,'views',request.controller,'index.html')))))}}
    8. +
    9. {{=T('You can modify this application and adapt it to your needs')}}
    10. +
    + + {{elif 'content' in globals():}} + {{=content}} + {{else:}} + {{=BEAUTIFY(response._vars)}} + {{pass}} +
    +
    + + + diff --git a/web2py/applications/welcome/views/default/user.html b/web2py/applications/welcome/views/default/user.html new file mode 100644 index 0000000..e6635ae --- /dev/null +++ b/web2py/applications/welcome/views/default/user.html @@ -0,0 +1,33 @@ +{{extend 'layout.html'}} + +
    +
    +

    + {{=T('Sign Up') if request.args(0) == 'register' else T('Log In') if request.args(0) == 'login' else T(request.args(0).replace('_',' ').title())}} +

    + {{=form}} + {{if request.args(0)=='login' and not 'register' in auth.settings.actions_disabled:}} + {{=T('Register')}} +
    + {{pass}} + {{if request.args(0)=='login' and not 'retrieve_password' in auth.settings.actions_disabled:}} + {{=T('Lost your password?')}} + {{pass}} + {{if request.args(0)=='register':}} + {{=T('Login')}} + {{pass}} +
    +
    + + + +{{block page_js}} + +{{end page_js}} diff --git a/web2py/applications/welcome/views/generic.html b/web2py/applications/welcome/views/generic.html new file mode 100644 index 0000000..56e0f78 --- /dev/null +++ b/web2py/applications/welcome/views/generic.html @@ -0,0 +1,13 @@ +{{extend 'layout.html'}} +{{""" + +You should not modify this file. +It is used as default when a view is not provided for your controllers + +"""}} +

    {{=' '.join(x.capitalize() for x in request.function.split('_'))}}

    +{{if len(response._vars)==1:}} +{{=BEAUTIFY(response._vars[next(iter(response._vars))])}} +{{elif len(response._vars)>1:}} +{{=BEAUTIFY(response._vars)}} +{{pass}} diff --git a/web2py/applications/welcome/views/generic.ics b/web2py/applications/welcome/views/generic.ics new file mode 100644 index 0000000..a812bfe --- /dev/null +++ b/web2py/applications/welcome/views/generic.ics @@ -0,0 +1,17 @@ +{{ +### +# response._vars contains the dictionary returned by the controller action +# Assuming something like: +# +# db.define_table('event', +# Field('title'), +# Field('start_datetime','datetime'), +# Field('stop_datetime','datetime')) +# events = db(db.event).select() +# +# Aor this to work the action must return something like +# +# dict(events=events, title='title',link=URL('action'),timeshift=0) +# +### +from gluon.serializers import ics}}{{=XML(ics(**response._vars))}} diff --git a/web2py/applications/welcome/views/generic.json b/web2py/applications/welcome/views/generic.json new file mode 100644 index 0000000..3bd0e1c --- /dev/null +++ b/web2py/applications/welcome/views/generic.json @@ -0,0 +1 @@ +{{from gluon.serializers import json}}{{=XML(json(response._vars))}} diff --git a/web2py/applications/welcome/views/generic.jsonp b/web2py/applications/welcome/views/generic.jsonp new file mode 100644 index 0000000..b46aaf0 --- /dev/null +++ b/web2py/applications/welcome/views/generic.jsonp @@ -0,0 +1,23 @@ +{{ +### +# response._vars contains the dictionary returned by the controller action +### + +# security check! This file is an example for a jsonp view. +# it is not safe to use as a generic.jsonp because of security implications. + +if response.view == 'generic.jsonp': + raise HTTP(501,'generic.jsonp disabled for security reasons') + +try: + from gluon.serializers import json + result = "%s(%s)" % (request.vars['callback'], json(response._vars)) + response.write(result, escape=False) + response.headers['Content-Type'] = 'application/jsonp' +except (TypeError, ValueError): + raise HTTP(405, 'JSON serialization error') +except ImportError: + raise HTTP(405, 'JSON not available') +except: + raise HTTP(405, 'JSON error') +}} diff --git a/web2py/applications/welcome/views/generic.load b/web2py/applications/welcome/views/generic.load new file mode 100644 index 0000000..03f0416 --- /dev/null +++ b/web2py/applications/welcome/views/generic.load @@ -0,0 +1,30 @@ +{{''' +# License: Public Domain +# Author: Iceberg at 21cn dot com + +With this generic.load file, you can use same function to serve two purposes. + += regular action +- ajax callback (when called with .load) + +Example modified from http://www.web2py.com/AlterEgo/default/show/252: + +def index(): + return dict( + part1='hello world', + part2=LOAD(url=URL(r=request,f='auxiliary.load'),ajax=True)) + +def auxiliary(): + form=SQLFORM.factory(Field('name')) + if form.accepts(request.vars): + response.flash = 'ok' + return dict(message="Hello %s" % form.vars.name) + return dict(form=form) + +Notice: + +- no need to set response.headers['web2py-response-flash'] +- no need to return a string +even if the function is called via ajax. + +'''}}{{if len(response._vars)==1:}}{{=response._vars[next(iter(response._vars))]}}{{else:}}{{=BEAUTIFY(response._vars)}}{{pass}} \ No newline at end of file diff --git a/web2py/applications/welcome/views/generic.map b/web2py/applications/welcome/views/generic.map new file mode 100644 index 0000000..773a8f7 --- /dev/null +++ b/web2py/applications/welcome/views/generic.map @@ -0,0 +1,69 @@ +{{""" +this is an example of usage of google map +the web2py action should be something like: + +def map(): + return dict( + googlemap_key='...', + center_latitude = 41.878, + center_longitude = -87.629, + scale = 7, + maker = lambda point: A(row.id,_href='...') + points = db(db.point).select() where a points have latitute and longitude + ) + +the corresponding views/defaut/map.html should be something like: + + \{\{extend 'layout.html'\}\} +
    \{\{include 'generic.map'\}\}
    + +"""}} + + +
    + diff --git a/web2py/applications/welcome/views/generic.pdf b/web2py/applications/welcome/views/generic.pdf new file mode 100644 index 0000000..bc257a3 --- /dev/null +++ b/web2py/applications/welcome/views/generic.pdf @@ -0,0 +1,11 @@ +{{ +import os +from gluon.contrib.generics import pdf_from_html +filename = '%s/%s.html' % (request.controller,request.function) +if os.path.exists(os.path.join(request.folder,'views',filename)): + html=response.render(filename) +else: + html=BODY(BEAUTIFY(response._vars)) +pass +=pdf_from_html(html) +}} diff --git a/web2py/applications/welcome/views/generic.rss b/web2py/applications/welcome/views/generic.rss new file mode 100644 index 0000000..82bb4c4 --- /dev/null +++ b/web2py/applications/welcome/views/generic.rss @@ -0,0 +1,10 @@ +{{ +### +# response._vars contains the dictionary returned by the controller action +# for this to work the action must return something like +# +# dict(title=...,link=...,description=...,created_on='...',items=...) +# +# items is a list of dictionaries each with title, link, description, pub_date. +### +from gluon.serializers import rss}}{{=XML(rss(response._vars))}} diff --git a/web2py/applications/welcome/views/generic.xml b/web2py/applications/welcome/views/generic.xml new file mode 100644 index 0000000..234b405 --- /dev/null +++ b/web2py/applications/welcome/views/generic.xml @@ -0,0 +1 @@ +{{from gluon.serializers import xml}}{{=XML(xml(response._vars,quote=False))}} diff --git a/web2py/applications/welcome/views/layout.html b/web2py/applications/welcome/views/layout.html new file mode 100644 index 0000000..5643dfd --- /dev/null +++ b/web2py/applications/welcome/views/layout.html @@ -0,0 +1,131 @@ + + + + + + + + + + {{=response.title or request.application}} + + + + + + + + + + + + + + {{include 'web2py_ajax.html'}} + {{block head}}{{end}} + + +
    {{=response.flash or ''}}
    + + + + + {{block header}} + {{end}} + + +
    + {{include}} + {{=response.toolbar() if response.show_toolbar else ''}} +
    + + {{block footer}} +
    +
    +
    + +
    + {{=T('Powered by')}} + web2py +
    +
    +
    +
    + {{end}} + + + + {{block page_js}}{{end page_js}} + {{if response.google_analytics_id:}} + + + + {{pass}} + + diff --git a/web2py/applications/welcome/views/web2py_ajax.html b/web2py/applications/welcome/views/web2py_ajax.html new file mode 100644 index 0000000..28ec0e0 --- /dev/null +++ b/web2py/applications/welcome/views/web2py_ajax.html @@ -0,0 +1,18 @@ + +{{ +response.files.insert(0,URL('static','js/jquery.js')) +response.files.insert(1,URL('static','css/calendar.css')) +response.files.insert(2,URL('static','js/calendar.js')) +response.files.insert(3,URL('static','js/web2py.js')) +response.include_meta() +response.include_files() +}} diff --git a/web2py/examples/README b/web2py/examples/README new file mode 100644 index 0000000..77d9bed --- /dev/null +++ b/web2py/examples/README @@ -0,0 +1,2 @@ +Here are various example files for configuration of routes and gae. +To use them, move them to main web2py folder and customize them. \ No newline at end of file diff --git a/web2py/examples/app.example.yaml b/web2py/examples/app.example.yaml new file mode 100644 index 0000000..b0fe287 --- /dev/null +++ b/web2py/examples/app.example.yaml @@ -0,0 +1,90 @@ +# For Google App Engine deployment, copy this file to app.yaml +# and edit as required +# See http://code.google.com/appengine/docs/python/config/appconfig.html +# and http://web2py.com/book/default/chapter/11?search=app.yaml + +application: yourappname +version: 1 +api_version: 1 + +# use these lines for Python 2.7 +# upload app with: appcfg.py update web2py (where 'web2py' is web2py's root directory) +# +runtime: python27 +threadsafe: true # true for WSGI & concurrent requests (Python 2.7 only) + +default_expiration: "24h" # for static files + +handlers: + +# Warning! Static mapping - below - isn't compatible with +# the parametric router's language logic. +# You cannot use them together. + +- url: /(.+?)/static/_(\d+\.\d+\.\d+)\/(.+) + static_files: applications/\1/static/\3 + upload: applications/(.+?)/static/(.+) + secure: optional + expiration: "365d" + +- url: /(.+?)/static/(.+) + static_files: applications/\1/static/\2 + upload: applications/(.+?)/static/(.+) + secure: optional + +- url: /favicon.ico + static_files: applications/welcome/static/favicon.ico + upload: applications/welcome/static/favicon.ico + +- url: /robots.txt + static_files: applications/welcome/static/robots.txt + upload: applications/welcome/static/robots.txt + +- url: .* + script: gaehandler.wsgiapp # WSGI (Python 2.7 only) + secure: optional + +admin_console: + pages: + - name: Appstats + url: /_ah/stats + +skip_files: | + ^(.*/)?( + (app\.yaml)| + (app\.yml)| + (index\.yaml)| + (index\.yml)| + (#.*#)| + (.*~)| + (.*\.py[co])| + (.*/RCS/.*)| + (\..*)| + (applications/examples/.*)| + ((examples|welcome)\.(w2p|tar))| + (applications/.*?/(cron|databases|errors|cache|sessions)/.*)| + ((logs|scripts)/.*)| + (anyserver\.py)| + (web2py\.py)| + ((cgi|fcgi|modpython|wsgi)handler\.py)| + (epydoc\.(conf|css))| + (httpserver\.log)| + (logging\.example\.conf)| + (route[rs]\.example\.py)| + (setup_(app|exe)\.py)| + (splashlogo\.gif)| + (parameters_\d+\.py)| + (options_std.py)| + (gluon/tests/.*)| + (gluon/rocket\.py)| + (contrib/(gateways|markdown|memcache|pymysql)/.*)| + (contrib/(populate|taskbar_widget)\.py)| + (google_appengine/.*)| + (.*\.(bak|orig))| + )$ + +builtins: +- remote_api: on +- appstats: on +- admin_redirect: on +- deferred: on diff --git a/web2py/examples/appengine_config.example.py b/web2py/examples/appengine_config.example.py new file mode 100644 index 0000000..a36d1db --- /dev/null +++ b/web2py/examples/appengine_config.example.py @@ -0,0 +1,4 @@ +def webapp_add_wsgi_middleware(app): + from google.appengine.ext.appstats import recording + app = recording.appstats_wsgi_middleware(app) + return app diff --git a/web2py/examples/logging.example.conf b/web2py/examples/logging.example.conf new file mode 100644 index 0000000..ee1f54d --- /dev/null +++ b/web2py/examples/logging.example.conf @@ -0,0 +1,145 @@ +# Configure the Python logging facility. +# To use this file, copy it to logging.conf and edit logging.conf as required. +# See http://docs.python.org/library/logging.html for details of the logging facility. +# Note that this is not the newer logging.config facility. +# +# The default configuration is console-based (stdout) for backward compatibility; +# edit the [handlers] section to choose a different logging destination. +# +# Note that file-based handlers are thread-safe but not mp-safe; +# for mp-safe logging, configure the appropriate syslog handler. +# +# To create a configurable logger for application 'myapp', add myapp to +# the [loggers] keys list and add a [logger_myapp] section, using +# [logger_welcome] as a starting point. +# +# In your application, create your logger in your model or in a controller: +# +# import logging +# logger = logging.getLogger("web2py.app.myapp") +# logger.setLevel(logging.DEBUG) +# +# To log a message: +# +# logger.debug("You ought to know that %s", details) +# +# Note that a logging call will be governed by the most restrictive level +# set by the setLevel call, the [logger_myapp] section, and the [handler_...] +# section. For example, you will not see DEBUG messages unless all three are +# set to DEBUG. +# +# Available levels: DEBUG INFO WARNING ERROR CRITICAL + +[loggers] +keys=root,rocket,markdown,web2py,rewrite,cron,app,welcome + +[handlers] +keys=consoleHandler,messageBoxHandler,rotatingFileHandler +#keys=consoleHandler,rotatingFileHandler +#keys=osxSysLogHandler +#keys=notifySendHandler + +[formatters] +keys=simpleFormatter + +[logger_root] +level=WARNING +handlers=consoleHandler,rotatingFileHandler + +[logger_web2py] +level=WARNING +handlers=consoleHandler,rotatingFileHandler +qualname=web2py +propagate=0 + +# URL rewrite logging (routes.py) +# See also the logging parameter in routes.py +# +[logger_rewrite] +level=WARNING +qualname=web2py.rewrite +handlers=consoleHandler,rotatingFileHandler +propagate=0 + +[logger_cron] +level=WARNING +qualname=web2py.cron +handlers=consoleHandler,rotatingFileHandler +propagate=0 + +# generic app handler +[logger_app] +level=WARNING +qualname=web2py.app +handlers=consoleHandler,rotatingFileHandler +propagate=0 + +# welcome app handler +[logger_welcome] +level=WARNING +qualname=web2py.app.welcome +handlers=consoleHandler,rotatingFileHandler +propagate=0 + +# loggers for legacy getLogger calls: Rocket and markdown +[logger_rocket] +level=WARNING +handlers=consoleHandler,messageBoxHandler,rotatingFileHandler +qualname=Rocket +propagate=0 + +[logger_markdown] +level=WARNING +handlers=consoleHandler,rotatingFileHandler +qualname=markdown +propagate=0 + +[handler_consoleHandler] +class=StreamHandler +level=WARNING +formatter=simpleFormatter +args=(sys.stdout,) + +[handler_messageBoxHandler] +class=gluon.messageboxhandler.MessageBoxHandler +level=ERROR +formatter=simpleFormatter +args=() + +[handler_notifySendHandler] +class=gluon.messageboxhandler.NotifySendHandler +level=ERROR +formatter=simpleFormatter +args=() + +# Rotating file handler +# mkdir logs in the web2py base directory if not already present +# args: (filename[, mode[, maxBytes[, backupCount[, encoding[, delay]]]]]) +# +[handler_rotatingFileHandler] +class=handlers.RotatingFileHandler +level=DEBUG +formatter=simpleFormatter +args=("web2py.log", "a", 1000000, 5) + +[handler_osxSysLogHandler] +class=handlers.SysLogHandler +level=WARNING +formatter=simpleFormatter +args=("/var/run/syslog", handlers.SysLogHandler.LOG_DAEMON) + +[handler_linuxSysLogHandler] +class=handlers.SysLogHandler +level=WARNING +formatter=simpleFormatter +args=("/dev/log", handlers.SysLogHandler.LOG_DAEMON) + +[handler_remoteSysLogHandler] +class=handlers.SysLogHandler +level=WARNING +formatter=simpleFormatter +args=(('sysloghost.domain.com', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_DAEMON) + +[formatter_simpleFormatter] +format=%(asctime)s - %(name)s - %(levelname)s - %(message)s +datefmt= diff --git a/web2py/examples/options_std.py b/web2py/examples/options_std.py new file mode 100644 index 0000000..6a7d822 --- /dev/null +++ b/web2py/examples/options_std.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +# when web2py is run as a windows service (web2py.py -W) +# it does not load the command line options but it +# expects to find configuration settings in a file called +# +# web2py/options.py +# +# this file is an example for options.py + +import socket +import os + +ip = '0.0.0.0' +port = 80 +interfaces = [('0.0.0.0', 80)] + #,('0.0.0.0',443,'ssl_private_key.pem','ssl_certificate.pem')] +password = '' # ## means use the previous password +pid_filename = 'httpserver.pid' +log_filename = 'httpserver.log' +profiler_filename = None +ssl_certificate = '' # 'ssl_certificate.pem' # ## path to certificate file +ssl_private_key = '' # 'ssl_private_key.pem' # ## path to private key file +#numthreads = 50 # ## deprecated; remove +minthreads = None +maxthreads = None +server_name = socket.gethostname() +request_queue_size = 5 +timeout = 30 +shutdown_timeout = 5 +folder = os.getcwd() +extcron = None +nocron = None diff --git a/web2py/examples/queue.example.yaml b/web2py/examples/queue.example.yaml new file mode 100644 index 0000000..0a2be0c --- /dev/null +++ b/web2py/examples/queue.example.yaml @@ -0,0 +1,8 @@ +# To configure Google App Engine task queues, copy this file to queue.yaml +# and edit as required +# See http://code.google.com/appengine/docs/python/config/queue.html + +queue: +- name: default + rate: 20/m + bucket_size: 1 diff --git a/web2py/examples/routes.parametric.example.py b/web2py/examples/routes.parametric.example.py new file mode 100644 index 0000000..9518ed4 --- /dev/null +++ b/web2py/examples/routes.parametric.example.py @@ -0,0 +1,213 @@ +# -*- coding: utf-8 -*- + +# routers are dictionaries of URL routing parameters. +# +# For each request, the effective router is: +# the built-in default base router (shown below), +# updated by the BASE router in routes.py routers, +# updated by the app-specific router in routes.py routers (if any), +# updated by the app-specific router from applications/app/routes.py routers (if any) +# +# +# Router members: +# +# default_application: default application name +# applications: list of all recognized applications, or 'ALL' to use all currently installed applications +# Names in applications are always treated as an application names when they appear first in an incoming URL. +# Set applications=None to disable the removal of application names from outgoing URLs. +# domains: optional dict mapping domain names to application names +# The domain name can include a port number: domain.com:8080 +# The application name can include a controller: appx/ctlrx +# or a controller and a function: appx/ctlrx/fcnx +# Example: +# domains = { "domain.com" : "app", +# "x.domain.com" : "appx", +# }, +# path_prefix: a path fragment that is prefixed to all outgoing URLs and stripped from all incoming URLs +# +# Note: default_application, applications, domains & path_prefix are permitted only in the BASE router, +# and domain makes sense only in an application-specific router. +# The remaining members can appear in the BASE router (as defaults for all applications) +# or in application-specific routers. +# +# default_controller: name of default controller +# default_function: name of default function (in all controllers) or dictionary of default functions +# by controller +# controllers: list of valid controllers in selected app +# or "DEFAULT" to use all controllers in the selected app plus 'static' +# or None to disable controller-name removal. +# Names in controllers are always treated as controller names when they appear in an incoming URL after +# the (optional) application and language names. +# functions: list of valid functions in the default controller (default None) or dictionary of valid +# functions by controller. +# If present, the default function name will be omitted when the controller is the default controller +# and the first arg does not create an ambiguity. +# languages: list of all supported languages +# Names in languages are always treated as language names when they appear in an incoming URL after +# the (optional) application name. +# default_language +# The language code (for example: en, it-it) optionally appears in the URL following +# the application (which may be omitted). For incoming URLs, the code is copied to +# request.uri_language; for outgoing URLs it is taken from request.uri_language. +# If languages=None, language support is disabled. +# The default_language, if any, is omitted from the URL. +# To use the incoming language in your application, add this line to one of your models files: +# if request.uri_language: T.force(request.uri_language) +# root_static: list of static files accessed from root (by default, favicon.ico & robots.txt) +# (mapped to the default application's static/ directory) +# Each default (including domain-mapped) application has its own root-static files. +# domain: the domain that maps to this application (alternative to using domains in the BASE router) +# exclusive_domain: If True (default is False), an exception is raised if an attempt is made to generate +# an outgoing URL with a different application without providing an explicit host. +# map_hyphen: If True (default is False), hyphens in incoming /a/c/f fields are converted +# to underscores, and back to hyphens in outgoing URLs. +# Language, args and the query string are not affected. +# map_static: By default (None), the default application is not stripped from static URLs. +# Set map_static=True to override this policy. +# Set map_static=False to map lang/static/file to static/lang/file +# acfe_match: regex for valid application, controller, function, extension /a/c/f.e +# file_match: regex for valid subpath (used for static file paths) +# if file_match does not contain '/', it is uses to validate each element of a static file subpath, +# rather than the entire subpath. +# args_match: regex for valid args +# This validation provides a measure of security. +# If it is changed, the application perform its own validation. +# +# +# The built-in default router supplies default values (undefined members are None): +# +# default_router = dict( +# default_application = 'init', +# applications = 'ALL', +# default_controller = 'default', +# controllers = 'DEFAULT', +# default_function = 'index', +# functions = None, +# default_language = None, +# languages = None, +# root_static = ['favicon.ico', 'robots.txt'], +# map_static = None, +# domains = None, +# map_hyphen = False, +# acfe_match = r'\w+$', # legal app/ctlr/fcn/ext +# file_match = r'([-+=@$%\w]|(?<=[-+=@$%\w])[./])*$', # legal static subpath +# args_match = r'([\w@ -]|(?<=[\w@ -])[.=])*$', # legal arg in args +# ) +# +# See rewrite.map_url_in() and rewrite.map_url_out() for implementation details. + + +# This simple router set overrides only the default application name, +# but provides full rewrite functionality. + +routers = dict( + + # base router + BASE=dict( + default_application='welcome', + ), +) + +# Specify log level for rewrite's debug logging +# Possible values: debug, info, warning, error, critical (loglevels), +# off, print (print uses print statement rather than logging) +# GAE users may want to use 'off' to suppress routine logging. +# +logging = 'debug' + +# Error-handling redirects all HTTP errors (status codes >= 400) to a specified +# path. If you wish to use error-handling redirects, uncomment the tuple +# below. You can customize responses by adding a tuple entry with the first +# value in 'appName/HTTPstatusCode' format. ( Only HTTP codes >= 400 are +# routed. ) and the value as a path to redirect the user to. You may also use +# '*' as a wildcard. +# +# The error handling page is also passed the error code and ticket as +# variables. Traceback information will be stored in the ticket. +# +# routes_onerror = [ +# (r'init/400', r'/init/default/login') +# ,(r'init/*', r'/init/static/fail.html') +# ,(r'*/404', r'/init/static/cantfind.html') +# ,(r'*/*', r'/init/error/index') +# ] + +# specify action in charge of error handling +# +# error_handler = dict(application='error', +# controller='default', +# function='index') + +# In the event that the error-handling page itself returns an error, web2py will +# fall back to its old static responses. You can customize them here. +# ErrorMessageTicket takes a string format dictionary containing (only) the +# "ticket" key. + +# error_message = '

    %s

    ' +# error_message_ticket = '

    Internal error

    Ticket issued: %(ticket)s' + + +def __routes_doctest(): + ''' + Dummy function for doctesting routes.py. + + Use filter_url() to test incoming or outgoing routes; + filter_err() for error redirection. + + filter_url() accepts overrides for method and remote host: + filter_url(url, method='get', remote='0.0.0.0', out=False) + + filter_err() accepts overrides for application and ticket: + filter_err(status, application='app', ticket='tkt') + + >>> import os + >>> import gluon.main + >>> from gluon.rewrite import load, filter_url, filter_err, get_effective_router + >>> load(routes=os.path.basename(__file__)) + + >>> filter_url('http://domain.com/abc', app=True) + 'welcome' + >>> filter_url('http://domain.com/welcome', app=True) + 'welcome' + >>> os.path.relpath(filter_url('http://domain.com/favicon.ico')) + 'applications/welcome/static/favicon.ico' + >>> filter_url('http://domain.com/abc') + '/welcome/default/abc' + >>> filter_url('http://domain.com/index/abc') + "/welcome/default/index ['abc']" + >>> filter_url('http://domain.com/default/abc.css') + '/welcome/default/abc.css' + >>> filter_url('http://domain.com/default/index/abc') + "/welcome/default/index ['abc']" + >>> filter_url('http://domain.com/default/index/a bc') + "/welcome/default/index ['a bc']" + + >>> filter_url('https://domain.com/app/ctr/fcn', out=True) + '/app/ctr/fcn' + >>> filter_url('https://domain.com/welcome/ctr/fcn', out=True) + '/ctr/fcn' + >>> filter_url('https://domain.com/welcome/default/fcn', out=True) + '/fcn' + >>> filter_url('https://domain.com/welcome/default/index', out=True) + '/' + >>> filter_url('https://domain.com/welcome/appadmin/index', out=True) + '/appadmin' + >>> filter_url('http://domain.com/welcome/default/fcn?query', out=True) + '/fcn?query' + >>> filter_url('http://domain.com/welcome/default/fcn#anchor', out=True) + '/fcn#anchor' + >>> filter_url('http://domain.com/welcome/default/fcn?query#anchor', out=True) + '/fcn?query#anchor' + + >>> filter_err(200) + 200 + >>> filter_err(399) + 399 + >>> filter_err(400) + 400 + ''' + pass + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/web2py/examples/routes.patterns.example.py b/web2py/examples/routes.patterns.example.py new file mode 100644 index 0000000..018f3c9 --- /dev/null +++ b/web2py/examples/routes.patterns.example.py @@ -0,0 +1,199 @@ +# -*- coding: utf-8 -*- + +# default_application, default_controller, default_function +# are used when the respective element is missing from the +# (possibly rewritten) incoming URL +# +default_application = 'init' # ordinarily set in base routes.py +default_controller = 'default' # ordinarily set in app-specific routes.py +default_function = 'index' # ordinarily set in app-specific routes.py + +# routes_app is a tuple of tuples. The first item in each is a regexp that will +# be used to match the incoming request URL. The second item in the tuple is +# an applicationname. This mechanism allows you to specify the use of an +# app-specific routes.py. This entry is meaningful only in the base routes.py. +# +# Example: support welcome, admin, app and myapp, with myapp the default: + + +routes_app = ((r'/(?Pwelcome|admin|app)\b.*', r'\g'), + (r'(.*)', r'myapp'), + (r'/?(.*)', r'myapp')) + +# routes_in is a tuple of tuples. The first item in each is a regexp that will +# be used to match the incoming request URL. The second item in the tuple is +# what it will be replaced with. This mechanism allows you to redirect incoming +# routes to different web2py locations +# +# Example: If you wish for your entire website to use init's static directory: +# +# routes_in=( (r'/static/(?P[\w./-]+)', r'/init/static/\g') ) +# + +BASE = '' # optonal prefix for incoming URLs + +routes_in = ( + # do not reroute admin unless you want to disable it + (BASE + '/admin', '/admin/default/index'), + (BASE + '/admin/$anything', '/admin/$anything'), + # do not reroute appadmin unless you want to disable it + (BASE + '/$app/appadmin', '/$app/appadmin/index'), + (BASE + '/$app/appadmin/$anything', '/$app/appadmin/$anything'), + # do not reroute static files + (BASE + '/$app/static/$anything', '/$app/static/$anything'), + # reroute favicon and robots, use exable for lack of better choice + ('/favicon.ico', '/examples/static/favicon.ico'), + ('/robots.txt', '/examples/static/robots.txt'), + # do other stuff + ((r'.*http://otherdomain\.com.* (?P.*)', r'/app/ctr\g')), + # remove the BASE prefix + (BASE + '/$anything', '/$anything'), +) + +# routes_out, like routes_in translates URL paths created with the web2py URL() +# function in the same manner that route_in translates inbound URL paths. +# + +routes_out = ( + # do not reroute admin unless you want to disable it + ('/admin/$anything', BASE + '/admin/$anything'), + # do not reroute appadmin unless you want to disable it + ('/$app/appadmin/$anything', BASE + '/$app/appadmin/$anything'), + # do not reroute static files + ('/$app/static/$anything', BASE + '/$app/static/$anything'), + # do other stuff + (r'.*http://otherdomain\.com.* /app/ctr(?P.*)', r'\g'), + (r'/app(?P.*)', r'\g'), + # restore the BASE prefix + ('/$anything', BASE + '/$anything'), +) + +# Specify log level for rewrite's debug logging +# Possible values: debug, info, warning, error, critical (loglevels), +# off, print (print uses print statement rather than logging) +# GAE users may want to use 'off' to suppress routine logging. +# +logging = 'debug' + +# Error-handling redirects all HTTP errors (status codes >= 400) to a specified +# path. If you wish to use error-handling redirects, uncomment the tuple +# below. You can customize responses by adding a tuple entry with the first +# value in 'appName/HTTPstatusCode' format. ( Only HTTP codes >= 400 are +# routed. ) and the value as a path to redirect the user to. You may also use +# '*' as a wildcard. +# +# The error handling page is also passed the error code and ticket as +# variables. Traceback information will be stored in the ticket. +# +# routes_onerror = [ +# (r'init/400', r'/init/default/login') +# ,(r'init/*', r'/init/static/fail.html') +# ,(r'*/404', r'/init/static/cantfind.html') +# ,(r'*/*', r'/init/error/index') +# ] + +# specify action in charge of error handling +# +# error_handler = dict(application='error', +# controller='default', +# function='index') + +# In the event that the error-handling page itself returns an error, web2py will +# fall back to its old static responses. You can customize them here. +# ErrorMessageTicket takes a string format dictionary containing (only) the +# "ticket" key. + +# error_message = '

    %s

    ' +# error_message_ticket = '

    Internal error

    Ticket issued: %(ticket)s' + +# specify a list of apps that bypass args-checking and use request.raw_args +# +#routes_apps_raw=['myapp'] +#routes_apps_raw=['myapp', 'myotherapp'] + + +def __routes_doctest(): + ''' + Dummy function for doctesting routes.py. + + Use filter_url() to test incoming or outgoing routes; + filter_err() for error redirection. + + filter_url() accepts overrides for method and remote host: + filter_url(url, method='get', remote='0.0.0.0', out=False) + + filter_err() accepts overrides for application and ticket: + filter_err(status, application='app', ticket='tkt') + + >>> import os + >>> import gluon.main + >>> from gluon.rewrite import regex_select, load, filter_url, regex_filter_out, filter_err, compile_regex + >>> regex_select() + >>> load(routes=os.path.basename(__file__)) + + >>> os.path.relpath(filter_url('http://domain.com/favicon.ico')) + 'applications/examples/static/favicon.ico' + >>> os.path.relpath(filter_url('http://domain.com/robots.txt')) + 'applications/examples/static/robots.txt' + >>> filter_url('http://domain.com') + '/init/default/index' + >>> filter_url('http://domain.com/') + '/init/default/index' + >>> filter_url('http://domain.com/init/default/fcn') + '/init/default/fcn' + >>> filter_url('http://domain.com/init/default/fcn/') + '/init/default/fcn' + >>> filter_url('http://domain.com/app/ctr/fcn') + '/app/ctr/fcn' + >>> filter_url('http://domain.com/app/ctr/fcn/arg1') + "/app/ctr/fcn ['arg1']" + >>> filter_url('http://domain.com/app/ctr/fcn/arg1/') + "/app/ctr/fcn ['arg1']" + >>> filter_url('http://domain.com/app/ctr/fcn/arg1//') + "/app/ctr/fcn ['arg1', '']" + >>> filter_url('http://domain.com/app/ctr/fcn//arg1') + "/app/ctr/fcn ['', 'arg1']" + >>> filter_url('HTTP://DOMAIN.COM/app/ctr/fcn') + '/app/ctr/fcn' + >>> filter_url('http://domain.com/app/ctr/fcn?query') + '/app/ctr/fcn ?query' + >>> filter_url('http://otherdomain.com/fcn') + '/app/ctr/fcn' + >>> regex_filter_out('/app/ctr/fcn') + '/ctr/fcn' + >>> filter_url('https://otherdomain.com/app/ctr/fcn', out=True) + '/ctr/fcn' + >>> filter_url('https://otherdomain.com/app/ctr/fcn/arg1//', out=True) + '/ctr/fcn/arg1//' + >>> filter_url('http://otherdomain.com/app/ctr/fcn', out=True) + '/fcn' + >>> filter_url('http://otherdomain.com/app/ctr/fcn?query', out=True) + '/fcn?query' + >>> filter_url('http://otherdomain.com/app/ctr/fcn#anchor', out=True) + '/fcn#anchor' + >>> filter_err(200) + 200 + >>> filter_err(399) + 399 + >>> filter_err(400) + 400 + >>> filter_url('http://domain.com/welcome', app=True) + 'welcome' + >>> filter_url('http://domain.com/', app=True) + 'myapp' + >>> filter_url('http://domain.com', app=True) + 'myapp' + >>> compile_regex('.*http://otherdomain.com.* (?P.*)', '/app/ctr\g')[0].pattern + '^.*http://otherdomain.com.* (?P.*)$' + >>> compile_regex('.*http://otherdomain.com.* (?P.*)', '/app/ctr\g')[1] + '/app/ctr\\\\g' + >>> compile_regex('/$c/$f', '/init/$c/$f')[0].pattern + '^.*?:https?://[^:/]+:[a-z]+ /(?P\\\\w+)/(?P\\\\w+)$' + >>> compile_regex('/$c/$f', '/init/$c/$f')[1] + '/init/\\\\g/\\\\g' + ''' + pass + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/web2py/examples/web.config b/web2py/examples/web.config new file mode 100644 index 0000000..f6c094a --- /dev/null +++ b/web2py/examples/web.config @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web2py/extras/build_web2py/README b/web2py/extras/build_web2py/README new file mode 100644 index 0000000..0fc35b1 --- /dev/null +++ b/web2py/extras/build_web2py/README @@ -0,0 +1,2 @@ +The files in this folder must be run from the main web2py folder. +They are for building windows and osx binary distribution and not meant for the end user. \ No newline at end of file diff --git a/web2py/extras/build_web2py/setup_app.py b/web2py/extras/build_web2py/setup_app.py new file mode 100644 index 0000000..9298541 --- /dev/null +++ b/web2py/extras/build_web2py/setup_app.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +This is a setup.py script generated by py2applet + +Usage: + python setup.py py2app +""" + +copy_apps = False +copy_scripts = True +copy_site_packages = True +remove_build_files = True +make_zip = True +zip_filename = "web2py_osx" + +from setuptools import setup +from gluon.import_all import base_modules, contributed_modules +from gluon.fileutils import readlines_file +import os +import fnmatch +import shutil +import sys +import re +import zipfile + +#read web2py version from VERSION file +web2py_version_line = readlines_file('VERSION')[0] +#use regular expression to get just the version number +v_re = re.compile('[0-9]+\.[0-9]+\.[0-9]+') +web2py_version = v_re.search(web2py_version_line).group(0) + +class reglob: + def __init__(self, directory, pattern="*"): + self.stack = [directory] + self.pattern = pattern + self.files = [] + self.index = 0 + + def __getitem__(self, index): + while 1: + try: + file = self.files[self.index] + self.index = self.index + 1 + except IndexError: + self.index = 0 + self.directory = self.stack.pop() + self.files = os.listdir(self.directory) + else: + fullname = os.path.join(self.directory, file) + if os.path.isdir(fullname) and not os.path.islink(fullname): + self.stack.append(fullname) + if not (file.startswith('.') or file.startswith('#') or file.endswith('~')) \ + and fnmatch.fnmatch(file, self.pattern): + return fullname + +setup(app=['web2py.py'], + version=web2py_version, + description="web2py web framework", + author="Massimo DiPierro", + license="LGPL v3", + data_files=[ + 'NEWINSTALL', + 'ABOUT', + 'LICENSE', + 'VERSION', + 'splashlogo.gif', + 'logging.example.conf', + 'options_std.py', + ], + options={'py2app': { + 'argv_emulation': True, + 'includes': base_modules, + }}, + setup_requires=['py2app']) + + +def copy_folders(source, destination): + """Copy files & folders from source to destination (within dist/)""" + print 'copying %s -> %s' % (source, destination) + base = 'dist/web2py.app/Contents/Resources/' + if os.path.exists(os.path.join(base, destination)): + shutil.rmtree(os.path.join(base, destination)) + shutil.copytree(os.path.join(source), os.path.join(base, destination)) + +#Should we include applications? +copy_folders('gluon','gluon') + +if copy_apps: + copy_folders('applications', 'applications') + print "Your application(s) have been added" +else: + #only copy web2py's default applications + copy_folders('applications/admin', 'applications/admin') + copy_folders('applications/welcome', 'applications/welcome') + copy_folders('applications/examples', 'applications/examples') + print "Only web2py's admin, examples & welcome applications have been added" + + +#should we copy project's site-packages into dist/site-packages +if copy_site_packages: + #copy site-packages + copy_folders('site-packages', 'site-packages') +else: + #no worries, web2py will create the (empty) folder first run + print "Skipping site-packages" + pass + +#should we copy project's scripts into dist/scripts +if copy_scripts: + #copy scripts + copy_folders('scripts', 'scripts') +else: + #no worries, web2py will create the (empty) folder first run + print "Skipping scripts" + pass + + +#borrowed from http://bytes.com/topic/python/answers/851018-how-zip-directory-python-using-zipfile +def recursive_zip(zipf, directory, folder=""): + for item in os.listdir(directory): + if os.path.isfile(os.path.join(directory, item)): + zipf.write(os.path.join(directory, item), folder + os.sep + item) + elif os.path.isdir(os.path.join(directory, item)): + recursive_zip( + zipf, os.path.join(directory, item), folder + os.sep + item) + +#should we create a zip file of the build? + +if make_zip: + #to keep consistent with how official web2py windows zip file is setup, + #create a web2py folder & copy dist's files into it + shutil.copytree('dist', 'zip_temp/web2py') + #create zip file + #use filename specified via command line + zipf = zipfile.ZipFile( + zip_filename + ".zip", "w", compression=zipfile.ZIP_DEFLATED) + path = 'zip_temp' # just temp so the web2py directory is included in our zip file + recursive_zip( + zipf, path) # leave the first folder as None, as path is root. + zipf.close() + shutil.rmtree('zip_temp') + print "Your Windows binary version of web2py can be found in " + \ + zip_filename + ".zip" + print "You may extract the archive anywhere and then run web2py/web2py.exe" + +#should py2exe build files be removed? +if remove_build_files: + shutil.rmtree('build') + shutil.rmtree('deposit') + shutil.rmtree('dist') + print "py2exe build files removed" + +#final info +if not make_zip and not remove_build_files: + print "Your Windows binary & associated files can also be found in /dist" + +print "Finished!" +print "Enjoy web2py " + web2py_version_line diff --git a/web2py/extras/build_web2py/setup_exe.conf b/web2py/extras/build_web2py/setup_exe.conf new file mode 100644 index 0000000..f4a9b42 --- /dev/null +++ b/web2py/extras/build_web2py/setup_exe.conf @@ -0,0 +1,27 @@ +[Setup] +#py2exe often includes DLLS from windows which aren't licensed for +#open source distribution. Should they be removed? +remove_microsoft_dlls: Yes + +#copy all web2py apps currently installed? +#If no, only the default admin, welcome & example apps will be included +copy_apps: No + +#include the web2py\site-packages directory? +copy_site_packages: Yes + +#include the web2py\scripts directory? +copy_scripts: Yes + +#create a zip file of the build for easy distribution? +make_zip: Yes + +#what should the zip file be named? (leave off the .zip extension) +zip_filename = web2py_win + +#should the build, deposit & dist directories used by py2exe be removed? +#if you created a zip file you likely don't need these directories anymore +remove_build_files = Yes + +#should the build include the gevented webserver (needs gevent) +include_gevent = Yes \ No newline at end of file diff --git a/web2py/extras/build_web2py/setup_exe.py b/web2py/extras/build_web2py/setup_exe.py new file mode 100644 index 0000000..ae0d00e --- /dev/null +++ b/web2py/extras/build_web2py/setup_exe.py @@ -0,0 +1,232 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +#Adapted from http://bazaar.launchpad.net/~flavour/sahana-eden/trunk/view/head:/static/scripts/tools/standalone_exe.py + +USAGE = """ +Usage: + Copy this and setup_exe.conf to web2py root folder + To build with py2exe: + Install py2exe: http://sourceforge.net/projects/py2exe/files/ + run python setup_exe.py py2exe + To build with bbfreeze: + Install bbfreeze: https://pypi.python.org/pypi/bbfreeze/ + run python setup_exe.py bbfreeze +""" + +from distutils.core import setup +from gluon.import_all import base_modules, contributed_modules +from gluon.fileutils import readlines_file +from glob import glob +import fnmatch +import os +import shutil +import sys +import re +import zipfile + +if len(sys.argv) != 2 or not os.path.isfile('web2py.py'): + print USAGE + sys.exit(1) +BUILD_MODE = sys.argv[1] +if not BUILD_MODE in ('py2exe', 'bbfreeze'): + print USAGE + sys.exit(1) + +def unzip(source_filename, dest_dir): + with zipfile.ZipFile(source_filename) as zf: + zf.extractall(dest_dir) + +#borrowed from http://bytes.com/topic/python/answers/851018-how-zip-directory-python-using-zipfile +def recursive_zip(zipf, directory, folder=""): + for item in os.listdir(directory): + if os.path.isfile(os.path.join(directory, item)): + zipf.write(os.path.join(directory, item), folder + os.sep + item) + elif os.path.isdir(os.path.join(directory, item)): + recursive_zip( + zipf, os.path.join(directory, item), folder + os.sep + item) + + +#read web2py version from VERSION file +web2py_version_line = readlines_file('VERSION')[0] +#use regular expression to get just the version number +v_re = re.compile('[0-9]+\.[0-9]+\.[0-9]+') +web2py_version = v_re.search(web2py_version_line).group(0) + +#pull in preferences from config file +import ConfigParser +Config = ConfigParser.ConfigParser() +Config.read('setup_exe.conf') +remove_msft_dlls = Config.getboolean("Setup", "remove_microsoft_dlls") +copy_apps = Config.getboolean("Setup", "copy_apps") +copy_site_packages = Config.getboolean("Setup", "copy_site_packages") +copy_scripts = Config.getboolean("Setup", "copy_scripts") +make_zip = Config.getboolean("Setup", "make_zip") +zip_filename = Config.get("Setup", "zip_filename") +remove_build_files = Config.getboolean("Setup", "remove_build_files") +include_gevent = Config.getboolean("Setup", "include_gevent") + +# Python base version +python_version = sys.version_info[:3] + + + +if BUILD_MODE == 'py2exe': + import py2exe + + setup( + console=[{'script':'web2py.py', + 'icon_resources': [(0, 'extras/icons/web2py.ico')] + }], + windows=[{'script':'web2py.py', + 'icon_resources': [(1, 'extras/icons/web2py.ico')], + 'dest_base':'web2py_no_console' # MUST NOT be just 'web2py' otherwise it overrides the standard web2py.exe + }], + name="web2py", + version=web2py_version, + description="web2py web framework", + author="Massimo DiPierro", + license="LGPL v3", + data_files=[ + 'ABOUT', + 'LICENSE', + 'VERSION' + ], + options={'py2exe': { + 'packages': contributed_modules, + 'includes': base_modules, + }}, + ) + #py2exe packages lots of duplicates in the library.zip, let's save some space + library_temp_dir = os.path.join('dist', 'library_temp') + library_zip_archive = os.path.join('dist', 'library.zip') + os.makedirs(library_temp_dir) + unzip(library_zip_archive, library_temp_dir) + os.unlink(library_zip_archive) + zipl = zipfile.ZipFile(library_zip_archive, "w", compression=zipfile.ZIP_DEFLATED) + recursive_zip(zipl, library_temp_dir) + zipl.close() + shutil.rmtree(library_temp_dir) + print "web2py binary successfully built" + +elif BUILD_MODE == 'bbfreeze': + modules = base_modules + contributed_modules + from bbfreeze import Freezer + f = Freezer(distdir="dist", includes=(modules)) + f.addScript("web2py.py") + #to make executable without GUI we need this trick + shutil.copy("web2py.py", "web2py_no_console.py") + f.addScript("web2py_no_console.py", gui_only=True) + if include_gevent: + #fetch the gevented webserver script and copy to root + gevented_webserver = os.path.join("handlers", "web2py_on_gevent.py") + shutil.copy(gevented_webserver, "web2py_on_gevent.py") + f.addScript("web2py_on_gevent.py") + f.setIcon('extras/icons/web2py.ico') + f() # starts the freezing process + os.unlink("web2py_no_console.py") + if include_gevent: + os.unlink("web2py_on_gevent.py") + #add data_files + for req in ['ABOUT', 'LICENSE', 'VERSION']: + shutil.copy(req, os.path.join('dist', req)) + print "web2py binary successfully built" + +try: + os.unlink('storage.sqlite') +except: + pass + +#This need to happen after bbfreeze is run because Freezer() deletes distdir before starting! +if python_version > (2,5): + # Python26 compatibility: http://www.py2exe.org/index.cgi/Tutorial#Step52 + try: + shutil.copytree('C:\Bin\Microsoft.VC90.CRT', 'dist/Microsoft.VC90.CRT/') + except: + print "You MUST copy Microsoft.VC90.CRT folder into the archive" + +def copy_folders(source, destination): + """Copy files & folders from source to destination (within dist/)""" + if os.path.exists(os.path.join('dist', destination)): + shutil.rmtree(os.path.join('dist', destination)) + shutil.copytree(os.path.join(source), os.path.join('dist', destination)) + +#should we remove Windows OS dlls user is unlikely to be able to distribute +if remove_msft_dlls: + print "Deleted Microsoft files not licensed for open source distribution" + print "You are still responsible for making sure you have the rights to distribute any other included files!" + #delete the API-MS-Win-Core DLLs + for f in glob('dist/API-MS-Win-*.dll'): + os.unlink(f) + #then delete some other files belonging to Microsoft + other_ms_files = ['KERNELBASE.dll', 'MPR.dll', 'MSWSOCK.dll', + 'POWRPROF.dll'] + for f in other_ms_files: + try: + os.unlink(os.path.join('dist', f)) + except: + print "unable to delete dist/" + f + +#Should we include applications? +if copy_apps: + copy_folders('applications', 'applications') + print "Your application(s) have been added" +else: + #only copy web2py's default applications + copy_folders('applications/admin', 'applications/admin') + copy_folders('applications/welcome', 'applications/welcome') + copy_folders('applications/examples', 'applications/examples') + print "Only web2py's admin, examples & welcome applications have been added" + +copy_folders('extras', 'extras') +copy_folders('examples', 'examples') +copy_folders('handlers', 'handlers') + + +#should we copy project's site-packages into dist/site-packages +if copy_site_packages: + #copy site-packages + copy_folders('site-packages', 'site-packages') +else: + #no worries, web2py will create the (empty) folder first run + print "Skipping site-packages" + +#should we copy project's scripts into dist/scripts +if copy_scripts: + #copy scripts + copy_folders('scripts', 'scripts') +else: + #no worries, web2py will create the (empty) folder first run + print "Skipping scripts" + +#should we create a zip file of the build? +if make_zip: + #create a web2py folder & copy dist's files into it + shutil.copytree('dist', 'zip_temp/web2py') + #create zip file + zipf = zipfile.ZipFile(zip_filename + ".zip", + "w", compression=zipfile.ZIP_DEFLATED) + # just temp so the web2py directory is included in our zip file + path = 'zip_temp' + # leave the first folder as None, as path is root. + recursive_zip(zipf, path) + zipf.close() + shutil.rmtree('zip_temp') + print "Your Windows binary version of web2py can be found in " + \ + zip_filename + ".zip" + print "You may extract the archive anywhere and then run web2py/web2py.exe" + +#should py2exe build files be removed? +if remove_build_files: + if BUILD_MODE == 'py2exe': + shutil.rmtree('build') + shutil.rmtree('deposit') + shutil.rmtree('dist') + print "build files removed" + +#final info +if not make_zip and not remove_build_files: + print "Your Windows binary & associated files can also be found in /dist" + +print "Finished!" +print "Enjoy web2py " + web2py_version_line diff --git a/web2py/extras/icons/splashlogo.gif b/web2py/extras/icons/splashlogo.gif new file mode 100644 index 0000000000000000000000000000000000000000..ebb32e9e9ffe44cb4091163bc73a14f4abb82e15 GIT binary patch literal 9093 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 literal 0 HcmV?d00001 diff --git a/web2py/extras/icons/web2py.icns b/web2py/extras/icons/web2py.icns new file mode 100644 index 0000000000000000000000000000000000000000..19e6e70e105fc44f8123bbf5fb4062e559bd6faf GIT binary patch literal 39379 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 literal 0 HcmV?d00001 diff --git a/web2py/extras/icons/web2py.ico b/web2py/extras/icons/web2py.ico new file mode 100644 index 0000000000000000000000000000000000000000..8291c260f53fec3f88f8e9200a12967b2bfa8f5b GIT binary patch literal 113846 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 K-XS@ZdiQ?~(e0lA literal 0 HcmV?d00001 diff --git a/web2py/fabfile.py b/web2py/fabfile.py new file mode 100644 index 0000000..2a1f601 --- /dev/null +++ b/web2py/fabfile.py @@ -0,0 +1,177 @@ +from fabric.api import * +from fabric.operations import put, get +from fabric.contrib.files import exists, append, uncomment +import os +import crypt +import datetime +import getpass + +if os.path.exists('hosts'): + env.hosts = [h.strip() for h in open('hosts').readlines() if h.strip()] + +env.hosts = env.hosts or raw_input('hostname (example.com):').split(',') +env.user = env.user or raw_input('username :') + +INSTALL_SCRIPT = "setup-web2py-nginx-uwsgi-ubuntu.sh" +now = datetime.datetime.now() +applications = '/home/www-data/web2py/applications' + +def create_user(username): + """fab -H root@host create_user:username""" + password = getpass.getpass('password for %s> ' % username) + run('useradd -m -G www-data -s /bin/bash -p %s %s' % (crypt.crypt(password, 'salt'), username)) + local('ssh-copy-id %s' % env.hosts[0]) + run('cp /etc/sudoers /tmp/sudoers.new') + append('/tmp/sudoers.new', '%s ALL=(ALL) NOPASSWD:ALL' % username, use_sudo=True) + run('visudo -c -f /tmp/sudoers.new') + run('EDITOR="cp /tmp/sudoers.new" visudo') + uncomment('~%s/.bashrc' % username, '#force_color_prompt=yes') + +def install_web2py(): + """fab -H username@host install_web2py""" + sudo('wget https://raw.githubusercontent.com/web2py/web2py/master/scripts/%s' % INSTALL_SCRIPT) + sudo('chmod +x %s' % INSTALL_SCRIPT) + sudo('./'+INSTALL_SCRIPT) + +def start_webserver(): + sudo('service nginx start') + sudo('start uwsgi-emperor') + sudo('start web2py-scheduler') + +def stop_webserver(): + sudo('stop uwsgi-emperor') + sudo('service nginx stop') + sudo('stop web2py-scheduler') + +def restart_webserver(): + stop_webserver() + start_webserver() + +def notify(appname=None): + """fab -H username@host notify:appname""" + appname = appname or os.path.split(os.getcwd())[-1] + appfolder = applications+'/'+appname + with cd(appfolder): + sudo('echo "response.flash = \'System Going Down For Maintenance\'" > models/flash_goingdown.py') + +def down(appname=None): + """fab -H username@host down:appname""" + appname = appname or os.path.split(os.getcwd())[-1] + appfolder = applications+'/'+appname + with cd(appfolder): + sudo('echo `date` > DISABLED') + sudo('rm -rf sessions/* || true') + +def up(appname=None): + """fab -H username@host up:appname""" + appname = appname or os.path.split(os.getcwd())[-1] + appfolder = applications+'/'+appname + with cd(appfolder): + if exists('modules/flash_goingdown.py'): + sudo('rm modules/flash_goingdown.py') + sudo('rm DISABLED') + +def mkdir_or_backup(appname): + appfolder = applications+'/'+appname + if not exists(appfolder): + sudo('mkdir %s' % appfolder) + sudo('chown -R www-data:www-data %s' % appfolder) + backup = None + else: + dt = now.strftime('%y-%m-%d-%h-%m') + backup = '%s.%s.zip' % (appname, dt) + with cd(applications): + sudo('zip -r %s %s' % (backup, appname)) + return backup + +def git_deploy(appname, repo): + """fab -H username@host git_deploy:appname,username/remoname""" + appfolder = applications+'/'+appname + backup = mkdir_or_backup(appname) + + if exists(appfolder): + with cd(appfolder): + sudo('git pull origin master') + sudo('chown -R www-data:www-data *') + else: + with cd(applications): + sudo('git clone git@github.com/%s %s' % (repo, name)) + sudo('chown -R www-data:www-data %s' % name) + +def retrieve(appname=None): + """fab -H username@host retrieve:appname""" + appname = appname or os.path.split(os.getcwd())[-1] + appfolder = applications+'/'+appname + filename = '%s.zip' % appname + with cd(appfolder): + sudo('zip -r /tmp/%s *' % filename) + get('/tmp/%s' % filename, filename) + sudo('rm /tmp/%s' % filename) + local('unzip %s' % filename) + local('rm %s' % filename) + +def deploy(appname=None, all=False): + """fab -H username@host deploy:appname,all""" + appname = appname or os.path.split(os.getcwd())[-1] + appfolder = applications+'/'+appname + zipfile = os.path.join(appfolder, '_update.zip') + if os.path.exists(zipfile): + os.unlink(zipfile) + + backup = mkdir_or_backup(appname) + + if all=='all' or not backup: + local('zip -r _update.zip * -x *~ -x .* -x \#* -x *.bak -x *.bak2') + else: + local('zip -r _update.zip */*.py */*/*.py views/*.html views/*/*.html static/*') + + put('_update.zip','/tmp/_update.zip') + try: + with cd(appfolder): + sudo('unzip -o /tmp/_update.zip') + sudo('chown -R www-data:www-data *') + sudo('echo "%s" > DATE_DEPLOYMENT' % now) + + finally: + sudo('rm /tmp/_update.zip') + + if backup: + print 'TO RESTORE: fab restore:%s' % backup + +def deploynobackup(appname=None): + """fab -H username@host deploy:appname,all""" + appname = appname or os.path.split(os.getcwd())[-1] + appfolder = applications+'/'+appname + zipfile = os.path.join(appfolder, '_update.zip') + if os.path.exists(zipfile): + os.unlink(zipfile) + + local('zip -r _update.zip */*.py */*/*.py views/*.html views/*/*.html static/*') + + put('_update.zip','/tmp/_update.zip') + try: + with cd(appfolder): + sudo('unzip -o /tmp/_update.zip') + sudo('chown -R www-data:www-data *') + sudo('echo "%s" > DATE_DEPLOYMENT' % now) + + finally: + sudo('rm /tmp/_update.zip') + +def restore(backup): + """fab -H username@host restore:backupfilename""" + appname = backup.split('/')[-1].split('.')[0] + appfolder = applications + '/' + appname + with cd(appfolder): + sudo('rm -r *') + with cd(applications): + sudo('unzip %s' % backup) + sudo('chown -R www-data:www-data %s' % appname) + +def cleanup(appname): + appname = appname or os.path.split(os.getcwd())[-1] + appfolder = applications + '/' + appname + with cd(appfolder): + sudo('rm -rf sessions/* || true') + sudo('rm -rf errors/* || true') + sudo('rm -rf cache/* || true') diff --git a/web2py/gluon/__init__.py b/web2py/gluon/__init__.py new file mode 100644 index 0000000..6a5e25f --- /dev/null +++ b/web2py/gluon/__init__.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +This file is part of the web2py Web Framework +Copyrighted by Massimo Di Pierro +License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + + +Web2Py framework modules +======================== +""" + +__all__ = ['A', 'B', 'BEAUTIFY', 'BODY', 'BR', 'CAT', 'CENTER', 'CLEANUP', 'CODE', 'CRYPT', 'DAL', 'DIV', 'EM', 'EMBED', 'FIELDSET', 'FORM', 'Field', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEAD', 'HR', 'HTML', 'HTTP', 'I', 'IFRAME', 'IMG', 'INPUT', 'IS_ALPHANUMERIC', 'IS_DATE', 'IS_DATETIME', 'IS_DATETIME_IN_RANGE', 'IS_DATE_IN_RANGE', 'IS_DECIMAL_IN_RANGE', 'IS_EMAIL', 'IS_LIST_OF_EMAILS', 'IS_EMPTY_OR', 'IS_EQUAL_TO', 'IS_EXPR', 'IS_FLOAT_IN_RANGE', 'IS_IMAGE', 'IS_JSON', 'IS_INT_IN_RANGE', 'IS_IN_DB', 'IS_IN_SET', 'IS_IPV4', 'IS_LENGTH', 'IS_LIST_OF', 'IS_LOWER', 'IS_MATCH', 'IS_NOT_EMPTY', 'IS_NOT_IN_DB', 'IS_NULL_OR', 'IS_SLUG', 'IS_STRONG', 'IS_TIME', 'IS_UPLOAD_FILENAME', 'IS_UPPER', 'IS_URL', 'LABEL', 'LEGEND', 'LI', 'LINK', 'LOAD', 'MARKMIN', 'MENU', 'META', 'OBJECT', 'OL', 'ON', 'OPTGROUP', 'OPTION', 'P', 'PRE', 'SCRIPT', 'SELECT', 'SPAN', 'SQLFORM', 'SQLTABLE', 'STRONG', 'STYLE', 'TABLE', 'TAG', 'TBODY', 'TD', 'TEXTAREA', 'TFOOT', 'TH', 'THEAD', 'TITLE', 'TR', 'TT', 'UL', 'URL', 'XHTML', 'XML', 'redirect', 'current', 'embed64'] + +#: add pydal to sys.modules +import os +import sys +try: + pydalpath = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "packages", "dal") + if pydalpath not in sys.path: + sys.path.append(pydalpath) + import pydal + sys.modules['pydal'] = pydal +except ImportError: + raise RuntimeError( + "web2py depends on pydal, which apparently you have not installed.\n" + + "Probably you cloned the repository using git without '--recursive'" + + "\nTo fix this, please run (from inside your web2py folder):\n\n" + + " git submodule update --init --recursive\n\n" + + "You can also download a complete copy from http://www.web2py.com." + ) + +from .globals import current +from .html import * +from .validators import * +from .http import redirect, HTTP +from .dal import DAL, Field +from .sqlhtml import SQLFORM, SQLTABLE +from .compileapp import LOAD + +# Dummy code to enable code completion in IDE's. +if 0: + from .globals import Request, Response, Session + from .cache import Cache + from .languages import translator + from .tools import Auth, Crud, Mail, Service, PluginManager + + # API objects + request = Request() + response = Response() + session = Session() + cache = Cache(request) + T = translator(request) + + # Objects commonly defined in application model files + # (names are conventions only -- not part of API) + db = DAL() + auth = Auth(db) + crud = Crud(db) + mail = Mail() + service = Service() + plugins = PluginManager() diff --git a/web2py/gluon/_compat.py b/web2py/gluon/_compat.py new file mode 100644 index 0000000..b3b82ad --- /dev/null +++ b/web2py/gluon/_compat.py @@ -0,0 +1,163 @@ +import sys +import hashlib +import os + +PY2 = sys.version_info[0] == 2 + +_identity = lambda x: x + +if PY2: + import cPickle as pickle + from cStringIO import StringIO + import copy_reg as copyreg + from HTMLParser import HTMLParser + import urlparse + from htmlentitydefs import entitydefs, name2codepoint + import __builtin__ as builtin + import thread + import Cookie + import urllib2 + import Queue + import ConfigParser as configparser + from email.MIMEBase import MIMEBase + from email.Header import Header + from email import Encoders, Charset + from email.MIMEMultipart import MIMEMultipart + from email.MIMEText import MIMEText + from email.Charset import add_charset, QP as charset_QP + from urllib import FancyURLopener, urlencode, urlopen + from urllib import quote as urllib_quote, unquote as urllib_unquote, quote_plus as urllib_quote_plus + from string import maketrans + from types import ClassType + import cgi + import cookielib + from xmlrpclib import ProtocolError + from gluon.contrib import ipaddress + BytesIO = StringIO + reduce = reduce + reload = reload + hashlib_md5 = hashlib.md5 + iterkeys = lambda d: d.iterkeys() + itervalues = lambda d: d.itervalues() + iteritems = lambda d: d.iteritems() + integer_types = (int, long) + string_types = (str, unicode) + text_type = unicode + basestring = basestring + xrange = xrange + long = long + unichr = unichr + unicodeT = unicode + + def implements_bool(cls): + cls.__nonzero__ = cls.__bool__ + del cls.__bool__ + return cls + + def implements_iterator(cls): + cls.next = cls.__next__ + del cls.__next__ + return cls + + def to_bytes(obj, charset='utf-8', errors='strict'): + if obj is None: + return None + if isinstance(obj, (bytes, bytearray, buffer)): + return bytes(obj) + if hasattr(obj, 'encode'): + return obj.encode(charset, errors) + raise TypeError('Expected bytes') + + def to_native(obj, charset='utf8', errors='strict'): + if obj is None or isinstance(obj, str): + return obj + return obj.encode(charset, errors) + + +else: + import pickle + from io import StringIO, BytesIO + import copyreg + from importlib import reload + from functools import reduce + from html.parser import HTMLParser + from http import cookies as Cookie + from urllib import parse as urlparse + from urllib import request as urllib2 + from html.entities import entitydefs, name2codepoint + import builtins as builtin + import _thread as thread + import configparser + import queue as Queue + from email.mime.base import MIMEBase + from email.mime.multipart import MIMEMultipart + from email.mime.text import MIMEText + from email import encoders as Encoders + from email.header import Header + from email.charset import Charset, add_charset, QP as charset_QP + from urllib.request import FancyURLopener, urlopen + from urllib.parse import quote as urllib_quote, unquote as urllib_unquote, urlencode, quote_plus as urllib_quote_plus + from http import cookiejar as cookielib + from xmlrpc.client import ProtocolError + import html # warning, this is the python3 module and not the web2py html module + import ipaddress + hashlib_md5 = lambda s: hashlib.md5(bytes(s, 'utf8')) + iterkeys = lambda d: iter(d.keys()) + itervalues = lambda d: iter(d.values()) + iteritems = lambda d: iter(d.items()) + integer_types = (int,) + string_types = (str,) + text_type = str + basestring = str + xrange = range + long = int + unichr = chr + unicodeT = str + maketrans = str.maketrans + ClassType = type + + implements_iterator = _identity + implements_bool = _identity + + def to_bytes(obj, charset='utf-8', errors='strict'): + if obj is None: + return None + if isinstance(obj, (bytes, bytearray, memoryview)): + return bytes(obj) + if hasattr(obj, 'encode'): + return obj.encode(charset, errors) + raise TypeError('Expected bytes') + + def to_native(obj, charset='utf8', errors='strict'): + if obj is None or isinstance(obj, str): + return obj + return obj.decode(charset, errors) + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(meta): + __call__ = type.__call__ + __init__ = type.__init__ + + def __new__(cls, name, this_bases, d): + if this_bases is None: + return type.__new__(cls, name, (), d) + return meta(name, bases, d) + return metaclass('temporary_class', None, {}) + + +def to_unicode(obj, charset='utf-8', errors='strict'): + if obj is None: + return None + if not hasattr(obj, 'decode'): + return text_type(obj) + return obj.decode(charset, errors) + + +# shortcuts +pjoin = os.path.join +exists = os.path.exists diff --git a/web2py/gluon/admin.py b/web2py/gluon/admin.py new file mode 100644 index 0000000..ad5e18d --- /dev/null +++ b/web2py/gluon/admin.py @@ -0,0 +1,478 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +Utility functions for the Admin application +------------------------------------------- +""" +from __future__ import print_function +import os +import sys +import traceback +import zipfile +from shutil import rmtree +from gluon.utils import web2py_uuid +from gluon.fileutils import w2p_pack, w2p_unpack, w2p_pack_plugin, w2p_unpack_plugin +from gluon.fileutils import up, fix_newlines, abspath, recursive_unlink +from gluon.fileutils import read_file, write_file, parse_version +from gluon.restricted import RestrictedError +from gluon.settings import global_settings +from gluon.cache import CacheOnDisk +from gluon._compat import urlopen, to_native + +if not global_settings.web2py_runtime_gae: + import site + + +def apath(path='', r=None): + """Builds a path inside an application folder + + Args: + path(str): path within the application folder + r: the global request object + + """ + + opath = up(r.folder) + while path[:3] == '../': + (opath, path) = (up(opath), path[3:]) + return os.path.join(opath, path).replace('\\', '/') + + +def app_pack(app, request, raise_ex=False, filenames=None): + """Builds a w2p package for the application + + Args: + app(str): application name + request: the global request object + Returns: + filename of the w2p file or None on error + + """ + try: + if filenames is None: + app_cleanup(app, request) + filename = apath('../deposit/web2py.app.%s.w2p' % app, request) + w2p_pack(filename, apath(app, request), filenames=filenames) + return filename + except Exception as e: + if raise_ex: + raise + return False + + +def app_pack_compiled(app, request, raise_ex=False): + """Builds a w2p bytecode-compiled package for the application + + Args: + app(str): application name + request: the global request object + + Returns: + filename of the w2p file or None on error + + """ + + try: + filename = apath('../deposit/%s.w2p' % app, request) + w2p_pack(filename, apath(app, request), compiled=True) + return filename + except Exception as e: + if raise_ex: + raise + return None + + +def app_cleanup(app, request): + """Removes session, cache and error files + + Args: + app(str): application name + request: the global request object + + Returns: + True if everything went ok, False otherwise + + """ + r = True + + # Remove error files + path = apath('%s/errors/' % app, request) + if os.path.exists(path): + for f in os.listdir(path): + try: + if f[:1] != '.': + os.unlink(os.path.join(path, f)) + except IOError: + r = False + + # Remove session files + path = apath('%s/sessions/' % app, request) + if os.path.exists(path): + for f in os.listdir(path): + try: + if f[:1] != '.': + recursive_unlink(os.path.join(path, f)) + except (OSError, IOError): + r = False + + # Remove cache files + path = apath('%s/cache/' % app, request) + if os.path.exists(path): + CacheOnDisk(folder=path).clear() + for f in os.listdir(path): + try: + if f[:1] != '.': + recursive_unlink(os.path.join(path, f)) + except (OSError, IOError): + r = False + return r + + +def app_compile(app, request, skip_failed_views=False): + """Compiles the application + + Args: + app(str): application name + request: the global request object + + Returns: + None if everything went ok, traceback text if errors are found + + """ + from gluon.compileapp import compile_application, remove_compiled_application + folder = apath(app, request) + try: + failed_views = compile_application(folder, skip_failed_views) + return failed_views + except (Exception, RestrictedError): + tb = traceback.format_exc() + remove_compiled_application(folder) + return tb + + +def app_create(app, request, force=False, key=None, info=False): + """Create a copy of welcome.w2p (scaffolding) app + + Args: + app(str): application name + request: the global request object + + """ + path = apath(app, request) + if not os.path.exists(path): + try: + os.mkdir(path) + except: + if info: + return False, traceback.format_exc() + else: + return False + elif not force: + if info: + return False, "Application exists" + else: + return False + try: + w2p_unpack('welcome.w2p', path) + for subfolder in ['models', 'views', 'controllers', 'databases', + 'modules', 'cron', 'errors', 'sessions', 'cache', + 'languages', 'static', 'private', 'uploads']: + subpath = os.path.join(path, subfolder) + if not os.path.exists(subpath): + os.mkdir(subpath) + db = os.path.join(path, 'models', 'db.py') + if os.path.exists(db): + data = read_file(db) + data = data.replace('', + 'sha512:' + (key or web2py_uuid())) + write_file(db, data) + if info: + return True, None + else: + return True + except: + rmtree(path) + if info: + return False, traceback.format_exc() + else: + return False + + +def app_install(app, fobj, request, filename, overwrite=None): + """Installs an application: + + - Identifies file type by filename + - Writes `fobj` contents to the `../deposit/` folder + - Calls `w2p_unpack()` to do the job. + + Args: + app(str): new application name + fobj(obj): file object containing the application to be installed + request: the global request object + filename(str): original filename of the `fobj`, + required to determine extension + overwrite(bool): force overwrite of existing application + + Returns: + name of the file where app is temporarily stored or `None` on failure + + """ + did_mkdir = False + if filename[-4:] == '.w2p': + extension = 'w2p' + elif filename[-7:] == '.tar.gz': + extension = 'tar.gz' + else: + extension = 'tar' + upname = apath('../deposit/%s.%s' % (app, extension), request) + + try: + write_file(upname, fobj.read(), 'wb') + path = apath(app, request) + if not overwrite: + os.mkdir(path) + did_mkdir = True + w2p_unpack(upname, path) + if extension != 'tar': + os.unlink(upname) + fix_newlines(path) + return upname + except Exception: + if did_mkdir: + rmtree(path) + return False + + +def app_uninstall(app, request): + """Uninstalls the application. + + Args: + app(str): application name + request: the global request object + + Returns: + `True` on success, `False` on failure + + """ + try: + # Hey App, this is your end... + path = apath(app, request) + rmtree(path) + return True + except Exception: + return False + + +def plugin_pack(app, plugin_name, request): + """Builds a w2p package for the plugin + + Args: + app(str): application name + plugin_name(str): the name of the plugin without `plugin_` prefix + request: the current request app + + Returns: + filename of the w2p file or False on error + + """ + try: + filename = apath( + '../deposit/web2py.plugin.%s.w2p' % plugin_name, request) + w2p_pack_plugin(filename, apath(app, request), plugin_name) + return filename + except Exception: + return False + + +def plugin_install(app, fobj, request, filename): + """Installs a plugin: + + - Identifies file type by filename + - Writes `fobj` contents to the `../deposit/` folder + - Calls `w2p_unpack_plugin()` to do the job. + + Args: + app(str): new application name + fobj: file object containing the application to be installed + request: the global request object + filename: original filename of the `fobj`, + required to determine extension + + Returns: + name of the file where plugin is temporarily stored + or `False` on failure + + """ + upname = apath('../deposit/%s' % filename, request) + + try: + write_file(upname, fobj.read(), 'wb') + path = apath(app, request) + w2p_unpack_plugin(upname, path) + fix_newlines(path) + return upname + except Exception: + os.unlink(upname) + return False + + +def check_new_version(myversion, version_url): + """Compares current web2py's version with the latest stable web2py version. + + Args: + myversion: the current version as stored in file `web2py/VERSION` + version_URL: the URL that contains the version + of the latest stable release + + Returns: + tuple: state, version + + - state : `True` if upgrade available, `False` if current + version is up-to-date, -1 on error + - version : the most up-to-version available + + """ + try: + version = to_native(urlopen(version_url).read()) + pversion = parse_version(version) + pmyversion = parse_version(myversion) + except IOError: + import traceback + print(traceback.format_exc()) + return -1, myversion + + if pversion[:3]+pversion[-6:] > pmyversion[:3]+pmyversion[-6:]: + return True, version + else: + return False, version + + +def unzip(filename, dir, subfolder=''): + """Unzips filename into dir (.zip only, no .gz etc) + + Args: + filename(str): archive + dir(str): destination + subfolder(str): if != '' unzips only files in subfolder + + """ + filename = abspath(filename) + if not zipfile.is_zipfile(filename): + raise RuntimeError('Not a valid zipfile') + zf = zipfile.ZipFile(filename) + if not subfolder.endswith('/'): + subfolder += '/' + n = len(subfolder) + for name in sorted(zf.namelist()): + if not name.startswith(subfolder): + continue + # print name[n:] + if name.endswith('/'): + folder = os.path.join(dir, name[n:]) + if not os.path.exists(folder): + os.mkdir(folder) + else: + write_file(os.path.join(dir, name[n:]), zf.read(name), 'wb') + + +def upgrade(request, url='http://web2py.com'): + """Upgrades web2py (src, osx, win) if a new version is posted. + It detects whether src, osx or win is running and downloads the right one + + Args: + request: the current request object + (required to determine version and path) + url: the incomplete url where to locate the latest web2py + (actual url is url+'/examples/static/web2py_(src|osx|win).zip') + + Returns + tuple: completed, traceback + + - completed: True on success, False on failure + (network problem or old version) + - traceback: None on success, raised exception details on failure + + """ + web2py_version = request.env.web2py_version + gluon_parent = request.env.gluon_parent + if not gluon_parent.endswith('/'): + gluon_parent += '/' + (check, version) = check_new_version(web2py_version, + url + '/examples/default/version') + if not check: + return False, 'Already latest version' + if os.path.exists(os.path.join(gluon_parent, 'web2py.exe')): + version_type = 'win' + destination = gluon_parent + subfolder = 'web2py/' + elif gluon_parent.endswith('/Contents/Resources/'): + version_type = 'osx' + destination = gluon_parent[:-len('/Contents/Resources/')] + subfolder = 'web2py/web2py.app/' + else: + version_type = 'src' + destination = gluon_parent + subfolder = 'web2py/' + + full_url = url + '/examples/static/web2py_%s.zip' % version_type + filename = abspath('web2py_%s_downloaded.zip' % version_type) + try: + write_file(filename, urlopen(full_url).read(), 'wb') + except Exception as e: + return False, e + try: + unzip(filename, destination, subfolder) + return True, None + except Exception as e: + return False, e + + +def add_path_first(path): + sys.path = [path] + [p for p in sys.path if ( + not p == path and not p == (path + '/'))] + if not global_settings.web2py_runtime_gae: + site.addsitedir(path) + + +def try_mkdir(path): + if not os.path.exists(path): + try: + if os.path.islink(path): + # path is a broken link, try to mkdir the target of the link instead of the link itself. + os.mkdir(os.path.realpath(path)) + else: + os.mkdir(path) + except OSError as e: + if e.strerror == 'File exists': # In case of race condition. + pass + else: + raise e + + +def create_missing_folders(): + if not global_settings.web2py_runtime_gae: + for path in ('applications', 'deposit', 'site-packages', 'logs'): + try_mkdir(abspath(path, gluon=True)) + """ + OLD sys.path dance + paths = (global_settings.gluon_parent, abspath( + 'site-packages', gluon=True), abspath('gluon', gluon=True), '') + """ + paths = (global_settings.gluon_parent, abspath( + 'site-packages', gluon=True), '') + [add_path_first(p) for p in paths] + + +def create_missing_app_folders(request): + if not global_settings.web2py_runtime_gae: + if request.folder not in global_settings.app_folders: + for subfolder in ('models', 'views', 'controllers', 'databases', + 'modules', 'cron', 'errors', 'sessions', + 'languages', 'static', 'private', 'uploads'): + try_mkdir(os.path.join(request.folder, subfolder)) + global_settings.app_folders.add(request.folder) diff --git a/web2py/gluon/authapi.py b/web2py/gluon/authapi.py new file mode 100644 index 0000000..887ae72 --- /dev/null +++ b/web2py/gluon/authapi.py @@ -0,0 +1,1057 @@ +# -*- coding: utf-8 -*- +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) +""" +from gluon._compat import long +from gluon import current +from gluon.storage import Messages, Settings, Storage +from gluon.utils import web2py_uuid +from gluon.validators import CRYPT, IS_EMAIL, IS_EQUAL_TO, IS_INT_IN_RANGE, IS_LOWER, IS_MATCH, IS_NOT_EMPTY, \ + IS_NOT_IN_DB +from pydal.objects import Table, Field, Row +import datetime +from gluon.settings import global_settings + +DEFAULT = lambda: None + + +class AuthAPI(object): + """ + AuthAPI is a barebones Auth implementation which does not have a concept of + HTML forms or redirects, emailing or even an URL, you are responsible for + all that if you use it. + The main Auth functions such as login, logout, register, profile are designed + in a Dict In -> Dict Out logic so, for instance, if you set + registration_requires_verification you are responsible for sending the key to + the user and even rolling back the transaction if you can't do it. + + NOTES: * It does not support all the callbacks Traditional Auth does yet. + Some of the callbacks will not be supported. + Check the method signatures to find out which ones are supported. + * register_fields and profile_fields settings are ignored for now. + + WARNING: No builtin CSRF protection whatsoever. + """ + + default_settings = { + 'create_user_groups': 'user_%(id)s', + 'email_case_sensitive': False, + 'everybody_group_id': None, + 'expiration': 3600, + 'keep_session_onlogin': True, + 'keep_session_onlogout': False, + 'logging_enabled': True, + 'login_after_registration': False, + 'login_email_validate': True, + 'login_userfield': None, + 'logout_onlogout': None, + 'long_expiration': 3600 * 24 * 30, + 'ondelete': 'CASCADE', + 'password_field': 'password', + 'password_min_length': 4, + 'registration_requires_approval': False, + 'registration_requires_verification': False, + 'renew_session_onlogin': True, + 'renew_session_onlogout': True, + 'table_event_name': 'auth_event', + 'table_group_name': 'auth_group', + 'table_membership_name': 'auth_membership', + 'table_permission_name': 'auth_permission', + 'table_user_name': 'auth_user', + 'use_username': False, + 'username_case_sensitive': True + } + + default_messages = { + 'add_group_log': 'Group %(group_id)s created', + 'add_membership_log': None, + 'add_permission_log': None, + 'change_password_log': 'User %(id)s Password changed', + 'del_group_log': 'Group %(group_id)s deleted', + 'del_membership_log': None, + 'del_permission_log': None, + 'email_taken': 'This email already has an account', + 'group_description': 'Group uniquely assigned to user %(id)s', + 'has_membership_log': None, + 'has_permission_log': None, + 'invalid_email': 'Invalid email', + 'key_verified': 'Key verified', + 'invalid_login': 'Invalid login', + 'invalid_password': 'Invalid password', + 'invalid_user': 'Invalid user', + 'invalid_key': 'Invalid key', + 'invalid_username': 'Invalid username', + 'logged_in': 'Logged in', + 'logged_out': 'Logged out', + 'login_failed_log': None, + 'login_log': 'User %(id)s Logged-in', + 'logout_log': 'User %(id)s Logged-out', + 'mismatched_password': "Password fields don't match", + 'password_changed': 'Password changed', + 'profile_log': 'User %(id)s Profile updated', + 'profile_updated': 'Profile updated', + 'register_log': 'User %(id)s Registered', + 'registration_pending': 'Registration is pending approval', + 'registration_successful': 'Registration successful', + 'registration_verifying': 'Registration needs verification', + 'username_taken': 'Username already taken', + 'verify_log': 'User %(id)s verified registration key' + } + + def __init__(self, db=None, hmac_key=None, signature=True): + self.db = db + session = current.session + auth = session.auth + self.user_groups = auth and auth.user_groups or {} + now = current.request.now + # if we have auth info + # if not expired it, used it + # if expired, clear the session + # else, only clear auth info in the session + if auth: + delta = datetime.timedelta(days=0, seconds=auth.expiration) + if auth.last_visit and auth.last_visit + delta > now: + self.user = auth.user + # this is a trick to speed up sessions to avoid many writes + if (now - auth.last_visit).seconds > (auth.expiration // 10): + auth.last_visit = now + else: + self.user = None + if session.auth: + del session.auth + session.renew(clear_session=True) + else: + self.user = None + if session.auth: + del session.auth + + settings = self.settings = Settings(self.__class__.default_settings) + settings.update( + extra_fields={}, + hmac_key=hmac_key, + ) + settings.lock_keys = True + messages = self.messages = Messages(current.T) + messages.update(self.default_messages) + messages.lock_keys = True + if signature is True: + self.define_signature() + else: + self.signature = signature or None + + def __validate(self, value, requires): + if not isinstance(requires, (list, tuple)): + requires = [requires] + for validator in requires: + (value, error) = validator(value) + if error: + return (value, error) + return (value, None) + + def _get_migrate(self, tablename, migrate=True): + + if type(migrate).__name__ == 'str': + return (migrate + tablename + '.table') + elif not migrate: + return False + else: + return True + + def _get_user_id(self): + """accessor for auth.user_id""" + return self.user and self.user.id or None + + user_id = property(_get_user_id, doc="user.id or None") + + def table_user(self): + return self.db[self.settings.table_user_name] + + def table_group(self): + return self.db[self.settings.table_group_name] + + def table_membership(self): + return self.db[self.settings.table_membership_name] + + def table_permission(self): + return self.db[self.settings.table_permission_name] + + def table_event(self): + return self.db[self.settings.table_event_name] + + def define_signature(self): + db = self.db + settings = self.settings + request = current.request + T = current.T + reference_user = 'reference %s' % settings.table_user_name + + def lazy_user(auth=self): + return auth.user_id + + def represent(id, record=None, s=settings): + try: + user = s.table_user(id) + return '%s %s' % (user.get("first_name", user.get("email")), + user.get("last_name", '')) + except: + return id + ondelete = self.settings.ondelete + self.signature = Table( + self.db, 'auth_signature', + Field('is_active', 'boolean', + default=True, + readable=False, writable=False, + label=T('Is Active')), + Field('created_on', 'datetime', + default=request.now, + writable=False, readable=False, + label=T('Created On')), + Field('created_by', + reference_user, + default=lazy_user, represent=represent, + writable=False, readable=False, + label=T('Created By'), ondelete=ondelete), + Field('modified_on', 'datetime', + update=request.now, default=request.now, + writable=False, readable=False, + label=T('Modified On')), + Field('modified_by', + reference_user, represent=represent, + default=lazy_user, update=lazy_user, + writable=False, readable=False, + label=T('Modified By'), ondelete=ondelete)) + + def define_tables(self, username=None, signature=None, migrate=None, + fake_migrate=None): + """ + To be called unless tables are defined manually + + Examples: + Use as:: + + # defines all needed tables and table files + # 'myprefix_auth_user.table', ... + auth.define_tables(migrate='myprefix_') + + # defines all needed tables without migration/table files + auth.define_tables(migrate=False) + + """ + + db = self.db + if migrate is None: + migrate = db._migrate + if fake_migrate is None: + fake_migrate = db._fake_migrate + + settings = self.settings + if username is None: + username = settings.use_username + else: + settings.use_username = username + + if not self.signature: + self.define_signature() + if signature is True: + signature_list = [self.signature] + elif not signature: + signature_list = [] + elif isinstance(signature, Table): + signature_list = [signature] + else: + signature_list = signature + self._table_signature_list = signature_list # Should it defined in __init__ first?? + + is_not_empty = IS_NOT_EMPTY(error_message=self.messages.is_empty) + is_crypted = CRYPT(key=settings.hmac_key, + min_length=settings.password_min_length) + is_unique_email = [ + IS_EMAIL(error_message=self.messages.invalid_email), + IS_NOT_IN_DB(db, '%s.email' % settings.table_user_name, + error_message=self.messages.email_taken)] + if not settings.email_case_sensitive: + is_unique_email.insert(1, IS_LOWER()) + if settings.table_user_name not in db.tables: + passfield = settings.password_field + extra_fields = settings.extra_fields.get( + settings.table_user_name, []) + signature_list + # cas_provider Will always be None here but we compare it anyway so subclasses can use our define_tables + if username or settings.cas_provider: + is_unique_username = \ + [IS_MATCH('[\w\.\-]+', strict=True, + error_message=self.messages.invalid_username), + IS_NOT_IN_DB(db, '%s.username' % settings.table_user_name, + error_message=self.messages.username_taken)] + if not settings.username_case_sensitive: + is_unique_username.insert(1, IS_LOWER()) + db.define_table( + settings.table_user_name, + Field('first_name', length=128, default='', + label=self.messages.label_first_name, + requires=is_not_empty), + Field('last_name', length=128, default='', + label=self.messages.label_last_name, + requires=is_not_empty), + Field('email', length=512, default='', + label=self.messages.label_email, + requires=is_unique_email), + Field('username', length=128, default='', + label=self.messages.label_username, + requires=is_unique_username), + Field(passfield, 'password', length=512, + readable=False, label=self.messages.label_password, + requires=[is_crypted]), + Field('registration_key', length=512, + writable=False, readable=False, default='', + label=self.messages.label_registration_key), + Field('reset_password_key', length=512, + writable=False, readable=False, default='', + label=self.messages.label_reset_password_key), + Field('registration_id', length=512, + writable=False, readable=False, default='', + label=self.messages.label_registration_id), + *extra_fields, + **dict( + migrate=self._get_migrate(settings.table_user_name, + migrate), + fake_migrate=fake_migrate, + format='%(username)s')) + else: + db.define_table( + settings.table_user_name, + Field('first_name', length=128, default='', + label=self.messages.label_first_name, + requires=is_not_empty), + Field('last_name', length=128, default='', + label=self.messages.label_last_name, + requires=is_not_empty), + Field('email', length=512, default='', + label=self.messages.label_email, + requires=is_unique_email), + Field(passfield, 'password', length=512, + readable=False, label=self.messages.label_password, + requires=[is_crypted]), + Field('registration_key', length=512, + writable=False, readable=False, default='', + label=self.messages.label_registration_key), + Field('reset_password_key', length=512, + writable=False, readable=False, default='', + label=self.messages.label_reset_password_key), + Field('registration_id', length=512, + writable=False, readable=False, default='', + label=self.messages.label_registration_id), + *extra_fields, + **dict( + migrate=self._get_migrate(settings.table_user_name, + migrate), + fake_migrate=fake_migrate, + format='%(first_name)s %(last_name)s (%(id)s)')) + reference_table_user = 'reference %s' % settings.table_user_name + if settings.table_group_name not in db.tables: + extra_fields = settings.extra_fields.get( + settings.table_group_name, []) + signature_list + db.define_table( + settings.table_group_name, + Field('role', length=512, default='', + label=self.messages.label_role, + requires=IS_NOT_IN_DB(db, '%s.role' % settings.table_group_name)), + Field('description', 'text', + label=self.messages.label_description), + *extra_fields, + **dict( + migrate=self._get_migrate( + settings.table_group_name, migrate), + fake_migrate=fake_migrate, + format='%(role)s (%(id)s)')) + reference_table_group = 'reference %s' % settings.table_group_name + if settings.table_membership_name not in db.tables: + extra_fields = settings.extra_fields.get( + settings.table_membership_name, []) + signature_list + db.define_table( + settings.table_membership_name, + Field('user_id', reference_table_user, + label=self.messages.label_user_id), + Field('group_id', reference_table_group, + label=self.messages.label_group_id), + *extra_fields, + **dict( + migrate=self._get_migrate( + settings.table_membership_name, migrate), + fake_migrate=fake_migrate)) + if settings.table_permission_name not in db.tables: + extra_fields = settings.extra_fields.get( + settings.table_permission_name, []) + signature_list + db.define_table( + settings.table_permission_name, + Field('group_id', reference_table_group, + label=self.messages.label_group_id), + Field('name', default='default', length=512, + label=self.messages.label_name, + requires=is_not_empty), + Field('table_name', length=512, + label=self.messages.label_table_name), + Field('record_id', 'integer', default=0, + label=self.messages.label_record_id, + requires=IS_INT_IN_RANGE(0, 10 ** 9)), + *extra_fields, + **dict( + migrate=self._get_migrate( + settings.table_permission_name, migrate), + fake_migrate=fake_migrate)) + if settings.table_event_name not in db.tables: + db.define_table( + settings.table_event_name, + Field('time_stamp', 'datetime', + default=current.request.now, + label=self.messages.label_time_stamp), + Field('client_ip', + default=current.request.client, + label=self.messages.label_client_ip), + Field('user_id', reference_table_user, default=None, + label=self.messages.label_user_id), + Field('origin', default='auth', length=512, + label=self.messages.label_origin, + requires=is_not_empty), + Field('description', 'text', default='', + label=self.messages.label_description, + requires=is_not_empty), + *settings.extra_fields.get(settings.table_event_name, []), + **dict( + migrate=self._get_migrate( + settings.table_event_name, migrate), + fake_migrate=fake_migrate)) + + return self + + def log_event(self, description, vars=None, origin='auth'): + """ + Examples: + Use as:: + + auth.log_event(description='this happened', origin='auth') + + """ + if not self.settings.logging_enabled or not description: + return + elif self.is_logged_in(): + user_id = self.user.id + else: + user_id = None # user unknown + vars = vars or {} + # log messages should not be translated + if type(description).__name__ == 'lazyT': + description = description.m + if not user_id or self.table_user()[user_id]: + self.table_event().insert( + description=str(description % vars), origin=origin, user_id=user_id) + + def id_group(self, role): + """ + Returns the group_id of the group specified by the role + """ + rows = self.db(self.table_group().role == role).select() + if not rows: + return None + return rows[0].id + + def user_group(self, user_id=None): + """ + Returns the group_id of the group uniquely associated to this user + i.e. `role=user:[user_id]` + """ + return self.id_group(self.user_group_role(user_id)) + + def user_group_role(self, user_id=None): + if not self.settings.create_user_groups: + return None + if user_id: + user = self.table_user()[user_id] + else: + user = self.user + return self.settings.create_user_groups % user + + def add_group(self, role, description=''): + """ + Creates a group associated to a role + """ + group_id = self.table_group().insert(role=role, description=description) + self.log_event(self.messages['add_group_log'], dict(group_id=group_id, role=role)) + return group_id + + def del_group(self, group_id): + """ + Deletes a group + """ + self.db(self.table_group().id == group_id).delete() + self.db(self.table_membership().group_id == group_id).delete() + self.db(self.table_permission().group_id == group_id).delete() + if group_id in self.user_groups: + del self.user_groups[group_id] + self.log_event(self.messages.del_group_log, dict(group_id=group_id)) + + def update_groups(self): + if not self.user: + return + user_groups = self.user_groups = {} + if current.session.auth: + current.session.auth.user_groups = self.user_groups + table_group = self.table_group() + table_membership = self.table_membership() + memberships = self.db( + table_membership.user_id == self.user.id).select() + for membership in memberships: + group = table_group(membership.group_id) + if group: + user_groups[membership.group_id] = group.role + + def add_membership(self, group_id=None, user_id=None, role=None): + """ + Gives user_id membership of group_id or role + if user is None than user_id is that of current logged in user + """ + + group_id = group_id or self.id_group(role) + try: + group_id = int(group_id) + except: + group_id = self.id_group(group_id) # interpret group_id as a role + if not user_id and self.user: + user_id = self.user.id + if not group_id: + raise ValueError('group_id not provided or invalid') + if not user_id: + raise ValueError('user_id not provided or invalid') + membership = self.table_membership() + db = membership._db + record = db((membership.user_id == user_id) & + (membership.group_id == group_id), + ignore_common_filters=True).select().first() + if record: + if hasattr(record, 'is_active') and not record.is_active: + record.update_record(is_active=True) + return record.id + else: + id = membership.insert(group_id=group_id, user_id=user_id) + if role and user_id == self.user_id: + self.user_groups[group_id] = role + else: + self.update_groups() + self.log_event(self.messages['add_membership_log'], + dict(user_id=user_id, group_id=group_id)) + return id + + def del_membership(self, group_id=None, user_id=None, role=None): + """ + Revokes membership from group_id to user_id + if user_id is None than user_id is that of current logged in user + """ + + group_id = group_id or self.id_group(role) + try: + group_id = int(group_id) + except: + group_id = self.id_group(group_id) # interpret group_id as a role + if not user_id and self.user: + user_id = self.user.id + membership = self.table_membership() + self.log_event(self.messages['del_membership_log'], + dict(user_id=user_id, group_id=group_id)) + ret = self.db(membership.user_id == user_id)(membership.group_id == group_id).delete() + if group_id in self.user_groups and user_id == self.user_id: + del self.user_groups[group_id] + return ret + + def has_membership(self, group_id=None, user_id=None, role=None, cached=False): + """ + Checks if user is member of group_id or role + + NOTE: To avoid database query at each page load that use auth.has_membership, someone can use cached=True. + If cached is set to True has_membership() check group_id or role only against auth.user_groups variable + which is populated properly only at login time. This means that if an user membership change during a + given session the user has to log off and log in again in order to auth.user_groups to be properly + recreated and reflecting the user membership modification. There is one exception to this log off and + log in process which is in case that the user change his own membership, in this case auth.user_groups + can be properly update for the actual connected user because web2py has access to the proper session + user_groups variable. To make use of this exception someone has to place an "auth.update_groups()" + instruction in his app code to force auth.user_groups to be updated. As mention this will only work if it + the user itself that change it membership not if another user, let say an administrator, change someone + else's membership. + """ + if not user_id and self.user: + user_id = self.user.id + if cached: + id_role = group_id or role + r = (user_id and id_role in self.user_groups.values()) or (user_id and id_role in self.user_groups) + else: + group_id = group_id or self.id_group(role) + try: + group_id = int(group_id) + except: + group_id = self.id_group(group_id) # interpret group_id as a role + membership = self.table_membership() + if group_id and user_id and self.db((membership.user_id == user_id) & + (membership.group_id == group_id)).select(): + r = True + else: + r = False + self.log_event(self.messages['has_membership_log'], + dict(user_id=user_id, group_id=group_id, check=r)) + return r + + def add_permission(self, + group_id, + name='any', + table_name='', + record_id=0, + ): + """ + Gives group_id 'name' access to 'table_name' and 'record_id' + """ + + permission = self.table_permission() + if group_id == 0: + group_id = self.user_group() + record = self.db((permission.group_id == group_id) & + (permission.name == name) & + (permission.table_name == str(table_name)) & + (permission.record_id == long(record_id)), + ignore_common_filters=True + ).select(limitby=(0, 1), orderby_on_limitby=False).first() + if record: + if hasattr(record, 'is_active') and not record.is_active: + record.update_record(is_active=True) + id = record.id + else: + id = permission.insert(group_id=group_id, name=name, + table_name=str(table_name), + record_id=long(record_id)) + self.log_event(self.messages['add_permission_log'], + dict(permission_id=id, group_id=group_id, + name=name, table_name=table_name, + record_id=record_id)) + return id + + def del_permission(self, + group_id, + name='any', + table_name='', + record_id=0, + ): + """ + Revokes group_id 'name' access to 'table_name' and 'record_id' + """ + + permission = self.table_permission() + self.log_event(self.messages['del_permission_log'], + dict(group_id=group_id, name=name, + table_name=table_name, record_id=record_id)) + return self.db(permission.group_id == + group_id)(permission.name == + name)(permission.table_name == + str(table_name))(permission.record_id == + long(record_id)).delete() + + def has_permission(self, + name='any', + table_name='', + record_id=0, + user_id=None, + group_id=None, + ): + """ + Checks if user_id or current logged in user is member of a group + that has 'name' permission on 'table_name' and 'record_id' + if group_id is passed, it checks whether the group has the permission + """ + + if not group_id and self.settings.everybody_group_id and \ + self.has_permission(name, table_name, record_id, user_id=None, + group_id=self.settings.everybody_group_id): + return True + + if not user_id and not group_id and self.user: + user_id = self.user.id + if user_id: + membership = self.table_membership() + rows = self.db(membership.user_id == user_id).select(membership.group_id) + groups = set([row.group_id for row in rows]) + if group_id and group_id not in groups: + return False + else: + groups = set([group_id]) + permission = self.table_permission() + rows = self.db(permission.name == + name)(permission.table_name == + str(table_name))(permission.record_id == + record_id).select(permission.group_id) + groups_required = set([row.group_id for row in rows]) + if record_id: + rows = self.db(permission.name == + name)(permission.table_name == + str(table_name))(permission.record_id == + 0).select(permission.group_id) + groups_required = groups_required.union(set([row.group_id for row in rows])) + if groups.intersection(groups_required): + r = True + else: + r = False + if user_id: + self.log_event(self.messages['has_permission_log'], + dict(user_id=user_id, name=name, + table_name=table_name, record_id=record_id)) + return r + + def is_logged_in(self): + """ + Checks if the user is logged in and returns True/False. + If so user is in auth.user as well as in session.auth.user + """ + if self.user: + return True + return False + + def _update_session_user(self, user): + if global_settings.web2py_runtime_gae: + user = Row(self.table_user()._filter_fields(user, id=True)) + delattr(user, self.settings.password_field) + else: + user = Row(user) + for key in list(user.keys()): + value = user[key] + if callable(value) or key == self.settings.password_field: + delattr(user, key) + current.session.auth = Storage(user=user, + last_visit=current.request.now, + expiration=self.settings.expiration, + hmac_key=web2py_uuid()) + return user + + def login_user(self, user): + """ + Logins the `user = db.auth_user(id)` + """ + user = self._update_session_user(user) + if self.settings.renew_session_onlogin: + current.session.renew(clear_session=not self.settings.keep_session_onlogin) + self.user = user + self.update_groups() + + def login(self, log=DEFAULT, **kwargs): + """ + Login a user + + Keyword Args: + username/email/name_of_your_username_field (string) - username + password/name_of_your_passfield (string) - user's password + remember_me (boolean) - extend the duration of the login to settings.long_expiration + """ + settings = self.settings + session = current.session + table_user = self.table_user() + + if 'username' in table_user.fields or \ + not settings.login_email_validate: + userfield_validator = IS_NOT_EMPTY(error_message=self.messages.is_empty) + if not settings.username_case_sensitive: + userfield_validator = [IS_LOWER(), userfield_validator] + else: + userfield_validator = IS_EMAIL(error_message=self.messages.invalid_email) + if not settings.email_case_sensitive: + userfield_validator = [IS_LOWER(), userfield_validator] + + passfield = settings.password_field + + if log is DEFAULT: + log = self.messages['login_log'] + + user = None + + # Setup the default field used for the userfield + if self.settings.login_userfield: + userfield = self.settings.login_userfield + else: + if 'username' in table_user.fields: + userfield = 'username' + else: + userfield = 'email' + + # Get the userfield from kwargs and validate it + userfield_value = kwargs.get(userfield) + if userfield_value is None: + raise KeyError('%s not found in kwargs' % userfield) + + validated, error = self.__validate(userfield_value, userfield_validator) + + if error: + return {'errors': {userfield: error}, 'message': self.messages.invalid_login, 'user': None} + + # Get the user for this userfield and check it + user = table_user(**{userfield: validated}) + + if user is None: + return {'errors': {userfield: self.messages.invalid_user}, + 'message': self.messages.invalid_login, 'user': None} + + if (user.registration_key or '').startswith('pending'): + return {'errors': None, 'message': self.messages.registration_pending, 'user': None} + elif user.registration_key in ('disabled', 'blocked'): + return {'errors': None, 'message': self.messages.login_disabled, 'user': None} + elif (user.registration_key is not None and user.registration_key.strip()): + return {'errors': None, 'message': self.messages.registration_verifying, 'user': None} + + # Finally verify the password + passfield = settings.password_field + password = table_user[passfield].validate(kwargs.get(passfield, ''))[0] + + if password == user[passfield]: + self.login_user(user) + session.auth.expiration = \ + kwargs.get('remember_me', False) and \ + settings.long_expiration or \ + settings.expiration + session.auth.remember_me = kwargs.get('remember_me', False) + self.log_event(log, user) + return {'errors': None, 'message': self.messages.logged_in, + 'user': {k: user[k] for k in table_user.fields if table_user[k].readable}} + else: + self.log_event(self.messages['login_failed_log'], kwargs) + return {'errors': {passfield: self.messages.invalid_password}, + 'message': self.messages.invalid_login, 'user': None} + + def logout(self, log=DEFAULT, onlogout=DEFAULT, **kwargs): + """ + Logs out user + """ + settings = self.settings + session = current.session + + if onlogout is DEFAULT: + onlogout = settings.logout_onlogout + if onlogout: + onlogout(self.user) + if log is DEFAULT: + log = self.messages['logout_log'] + if self.user: + self.log_event(log, self.user) + + session.auth = None + self.user = None + if settings.renew_session_onlogout: + session.renew(clear_session=not settings.keep_session_onlogout) + + return {'errors': None, 'message': self.messages.logged_out, 'user': None} + + def register(self, log=DEFAULT, **kwargs): + """ + Register a user. + """ + + table_user = self.table_user() + settings = self.settings + + if self.is_logged_in(): + raise AssertionError('User trying to register is logged in') + + if log is DEFAULT: + log = self.messages['register_log'] + + if self.settings.login_userfield: + userfield = self.settings.login_userfield + elif 'username' in table_user.fields: + userfield = 'username' + else: + userfield = 'email' + + # Ensure the username field is unique. + unique_validator = IS_NOT_IN_DB(self.db, table_user[userfield]) + userfield_validator = table_user[userfield].requires + if userfield_validator is None: + userfield_validator = unique_validator + elif isinstance(userfield_validator, (list, tuple)): + if not any([isinstance(validator, IS_NOT_IN_DB) for validator in + userfield_validator]): + if isinstance(userfield_validator, list): + userfield_validator.append(unique_validator) + else: + userfield_validator += (unique_validator, ) + elif not isinstance(userfield_validator, IS_NOT_IN_DB): + userfield_validator = [userfield_validator, unique_validator] + table_user[userfield].requires = userfield_validator + + passfield = settings.password_field + + try: # Make sure we have our original minimum length + table_user[passfield].requires[-1].min_length = settings.password_min_length + except: + pass + + key = web2py_uuid() + if settings.registration_requires_approval: + key = 'pending-' + key + + table_user.registration_key.default = key + + result = table_user.validate_and_insert(**kwargs) + if result.errors: + return {'errors': result.errors.as_dict(), 'message': None, 'user': None} + + user = table_user[result.id] + + message = self.messages.registration_successful + + if settings.create_user_groups: + d = user.as_dict() + description = self.messages.group_description % d + group_id = self.add_group(settings.create_user_groups % d, description) + self.add_membership(group_id, result.id) + + if self.settings.everybody_group_id: + self.add_membership(self.settings.everybody_group_id, result) + + if settings.registration_requires_verification: + d = {k: user[k] for k in table_user.fields if table_user[k].readable} + d['key'] = key + if settings.login_after_registration and not settings.registration_requires_approval: + self.login_user(user) + return {'errors': None, 'message': None, 'user': d} + + if settings.registration_requires_approval: + user.update_record(registration_key='pending') + message = self.messages.registration_pending + elif settings.login_after_registration: + user.update_record(registration_key='') + self.login_user(user) + message = self.messages.logged_in + + self.log_event(log, user) + + return {'errors': None, 'message': message, + 'user': {k: user[k] for k in table_user.fields if table_user[k].readable}} + + def profile(self, log=DEFAULT, **kwargs): + """ + Lets the user change his/her profile + """ + + table_user = self.table_user() + settings = self.settings + table_user[settings.password_field].writable = False + + if not self.is_logged_in(): + raise AssertionError('User is not logged in') + + if not kwargs: + user = table_user[self.user.id] + return {'errors': None, 'message': None, + 'user': {k: user[k] for k in table_user.fields if table_user[k].readable}} + + result = self.db(table_user.id == self.user.id).validate_and_update(**kwargs) + user = table_user[self.user.id] + + if result.errors: + return {'errors': result.errors, 'message': None, + 'user': {k: user[k] for k in table_user.fields if table_user[k].readable}} + + if log is DEFAULT: + log = self.messages['profile_log'] + + self.log_event(log, user) + self._update_session_user(user) + return {'errors': None, 'message': self.messages.profile_updated, + 'user': {k: user[k] for k in table_user.fields if table_user[k].readable}} + + def change_password(self, log=DEFAULT, **kwargs): + """ + Lets the user change password + + Keyword Args: + old_password (string) - User's current password + new_password (string) - User's new password + new_password2 (string) - Verify the new password + """ + settings = self.settings + messages = self.messages + + if not self.is_logged_in(): + raise AssertionError('User is not logged in') + + db = self.db + table_user = self.table_user() + s = db(table_user.id == self.user.id) + + request = current.request + session = current.session + passfield = settings.password_field + + requires = table_user[passfield].requires + if not isinstance(requires, (list, tuple)): + requires = [requires] + requires = list(filter(lambda t: isinstance(t, CRYPT), requires)) + if requires: + requires[0] = CRYPT(**requires[0].__dict__) # Copy the existing CRYPT attributes + requires[0].min_length = 0 # But do not enforce minimum length for the old password + + old_password = kwargs.get('old_password', '') + new_password = kwargs.get('new_password', '') + new_password2 = kwargs.get('new_password2', '') + + validator_old = requires + validator_pass2 = IS_EQUAL_TO(new_password, error_message=messages.mismatched_password) + + old_password, error_old = self.__validate(old_password, validator_old) + new_password2, error_new2 = self.__validate(new_password2, validator_pass2) + + errors = {} + if error_old: + errors['old_password'] = error_old + if error_new2: + errors['new_password2'] = error_new2 + if errors: + return {'errors': errors, 'message': None} + + current_user = s.select(limitby=(0, 1), orderby_on_limitby=False).first() + if not old_password == current_user[passfield]: + return {'errors': {'old_password': messages.invalid_password}, 'message': None} + else: + d = {passfield: new_password} + resp = s.validate_and_update(**d) + if resp.errors: + return {'errors': {'new_password': resp.errors[passfield]}, 'message': None} + if log is DEFAULT: + log = messages['change_password_log'] + self.log_event(log, self.user) + return {'errors': None, 'message': messages.password_changed} + + def verify_key(self, + key=None, + ignore_approval=False, + log=DEFAULT, + ): + """ + Verify a given registration_key actually exists in the user table. + Resets the key to empty string '' or 'pending' if + setttings.registration_requires_approval is true. + + Keyword Args: + key (string) - User's registration key + """ + table_user = self.table_user() + user = table_user(registration_key=key) + if (user is None) or (key is None): + return {'errors': {'key': self.messages.invalid_key}, 'message': self.messages.invalid_key} + + if self.settings.registration_requires_approval: + user.update_record(registration_key='pending') + result = {'errors': None, 'message': self.messages.registration_pending} + else: + user.update_record(registration_key='') + result = {'errors': None, 'message': self.messages.key_verified} + # make sure session has same user.registration_key as db record + if current.session.auth and current.session.auth.user: + current.session.auth.user.registration_key = user.registration_key + if log is DEFAULT: + log = self.messages['verify_log'] + self.log_event(log, user) + return result diff --git a/web2py/gluon/cache.py b/web2py/gluon/cache.py new file mode 100644 index 0000000..5050d21 --- /dev/null +++ b/web2py/gluon/cache.py @@ -0,0 +1,746 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +Basic caching classes and methods +--------------------------------- + +- Cache - The generic caching object interfacing with the others +- CacheInRam - providing caching in ram +- CacheOnDisk - provides caches on disk + +Memcache is also available via a different module (see gluon.contrib.memcache) + +When web2py is running on Google App Engine, +caching will be provided by the GAE memcache +(see gluon.contrib.gae_memcache) +""" +import time +import os +import gc +import sys +import logging +import re +import random +import hashlib +import datetime +import tempfile +from gluon import recfile +from collections import defaultdict +from collections import OrderedDict + +try: + from gluon import settings + have_settings = True +except ImportError: + have_settings = False + +from pydal.contrib import portalocker +from gluon._compat import pickle, thread, to_bytes, to_native, hashlib_md5 + +try: + import psutil + HAVE_PSUTIL = True +except ImportError: + HAVE_PSUTIL = False + + +def remove_oldest_entries(storage, percentage=90): + # compute current memory usage (%) + old_mem = psutil.virtual_memory().percent + # if we have data in storage and utilization exceeds 90% + while storage and old_mem > percentage: + # removed oldest entry + storage.popitem(last=False) + # garbage collect + gc.collect(1) + # comute used memory again + new_mem = psutil.virtual_memory().percent + # if the used memory did not decrease stop + if new_mem >= old_mem: + break + # net new measurement for memory usage and loop + old_mem = new_mem + + +logger = logging.getLogger("web2py.cache") + +__all__ = ['Cache', 'lazy_cache'] + + +DEFAULT_TIME_EXPIRE = 300 + + +class CacheAbstract(object): + """ + Abstract class for cache implementations. + Main function just provides referenced api documentation. + + Use CacheInRam or CacheOnDisk instead which are derived from this class. + + Note: + Michele says: there are signatures inside gdbm files that are used + directly by the python gdbm adapter that often are lagging behind in the + detection code in python part. + On every occasion that a gdbm store is probed by the python adapter, + the probe fails, because gdbm file version is newer. + Using gdbm directly from C would work, because there is backward + compatibility, but not from python! + The .shelve file is discarded and a new one created (with new + signature) and it works until it is probed again... + The possible consequences are memory leaks and broken sessions. + """ + + cache_stats_name = 'web2py_cache_statistics' + max_ram_utilization = None # percent + + def __init__(self, request=None): + """Initializes the object + + Args: + request: the global request object + """ + raise NotImplementedError + + def __call__(self, key, f, + time_expire=DEFAULT_TIME_EXPIRE): + """ + Tries to retrieve the value corresponding to `key` from the cache if the + object exists and if it did not expire, else it calls the function `f` + and stores the output in the cache corresponding to `key`. It always + returns the function that is returned. + + Args: + key(str): the key of the object to be stored or retrieved + f(function): the function whose output is to be cached. + + If `f` is `None` the cache is cleared. + time_expire(int): expiration of the cache in seconds. + + It's used to compare the current time with the time + when the requested object was last saved in cache. It does not + affect future requests. Setting `time_expire` to 0 or negative + value forces the cache to refresh. + """ + raise NotImplementedError + + def clear(self, regex=None): + """ + Clears the cache of all keys that match the provided regular expression. + If no regular expression is provided, it clears all entries in cache. + + Args: + regex: if provided, only keys matching the regex will be cleared, + otherwise all keys are cleared. + """ + + raise NotImplementedError + + def increment(self, key, value=1): + """ + Increments the cached value for the given key by the amount in value + + Args: + key(str): key for the cached object to be incremeneted + value(int): amount of the increment (defaults to 1, can be negative) + """ + raise NotImplementedError + + def _clear(self, storage, regex): + """ + Auxiliary function called by `clear` to search and clear cache entries + """ + r = re.compile(regex) + for key in list(storage.keys()): + if r.match(str(key)): + del storage[key] + return + + +class CacheInRam(CacheAbstract): + """ + Ram based caching + + This is implemented as global (per process, shared by all threads) + dictionary. + A mutex-lock mechanism avoid conflicts. + """ + + locker = thread.allocate_lock() + meta_storage = {} + stats = {} + + def __init__(self, request=None): + self.initialized = False + self.request = request + self.storage = OrderedDict() if HAVE_PSUTIL else {} + self.app = request.application if request else '' + + def initialize(self): + if self.initialized: + return + else: + self.initialized = True + self.locker.acquire() + if self.app not in self.meta_storage: + self.storage = self.meta_storage[self.app] = \ + OrderedDict() if HAVE_PSUTIL else {} + self.stats[self.app] = {'hit_total': 0, 'misses': 0} + else: + self.storage = self.meta_storage[self.app] + self.locker.release() + + def clear(self, regex=None): + self.initialize() + self.locker.acquire() + storage = self.storage + if regex is None: + storage.clear() + else: + self._clear(storage, regex) + + if self.app not in self.stats: + self.stats[self.app] = {'hit_total': 0, 'misses': 0} + + self.locker.release() + + def __call__(self, key, f, + time_expire=DEFAULT_TIME_EXPIRE, + destroyer=None): + """ + Attention! cache.ram does not copy the cached object. + It just stores a reference to it. Turns out the deepcopying the object + has some problems: + + - would break backward compatibility + - would be limiting because people may want to cache live objects + - would work unless we deepcopy no storage and retrival which would make + things slow. + + Anyway. You can deepcopy explicitly in the function generating the value + to be cached. + """ + self.initialize() + + dt = time_expire + now = time.time() + + self.locker.acquire() + item = self.storage.get(key, None) + if item and f is None: + del self.storage[key] + if destroyer: + destroyer(item[1]) + self.stats[self.app]['hit_total'] += 1 + self.locker.release() + + if f is None: + return None + if item and (dt is None or item[0] > now - dt): + return item[1] + elif item and (item[0] < now - dt) and destroyer: + destroyer(item[1]) + value = f() + + self.locker.acquire() + self.storage[key] = (now, value) + self.stats[self.app]['misses'] += 1 + if HAVE_PSUTIL and self.max_ram_utilization is not None and random.random() < 0.10: + remove_oldest_entries(self.storage, percentage=self.max_ram_utilization) + self.locker.release() + return value + + def increment(self, key, value=1): + self.initialize() + self.locker.acquire() + try: + if key in self.storage: + value = self.storage[key][1] + value + self.storage[key] = (time.time(), value) + except BaseException as e: + self.locker.release() + raise e + self.locker.release() + return value + + +class CacheOnDisk(CacheAbstract): + """ + Disk based cache + + This is implemented as a key value store where each key corresponds to a + single file in disk which is replaced when the value changes. + + Disk cache provides persistance when web2py is started/stopped but it is + slower than `CacheInRam` + + Values stored in disk cache must be pickable. + """ + + class PersistentStorage(object): + """ + Implements a key based thread/process-safe safe storage in disk. + """ + + def __init__(self, folder, file_lock_time_wait=0.1): + self.folder = folder + self.key_filter_in = lambda key: key + self.key_filter_out = lambda key: key + self.file_lock_time_wait = file_lock_time_wait + # How long we should wait before retrying to lock a file held by another process + # We still need a mutex for each file as portalocker only blocks other processes + self.file_locks = defaultdict(thread.allocate_lock) + + # Make sure we use valid filenames. + if sys.platform == "win32": + import base64 + + def key_filter_in_windows(key): + """ + Windows doesn't allow \ / : * ? "< > | in filenames. + To go around this encode the keys with base32. + """ + return to_native(base64.b32encode(to_bytes(key))) + + def key_filter_out_windows(key): + """ + We need to decode the keys so regex based removal works. + """ + return to_native(base64.b32decode(to_bytes(key))) + + self.key_filter_in = key_filter_in_windows + self.key_filter_out = key_filter_out_windows + + def wait_portalock(self, val_file): + """ + Wait for the process file lock. + """ + while True: + try: + portalocker.lock(val_file, portalocker.LOCK_EX) + break + except: + time.sleep(self.file_lock_time_wait) + + def acquire(self, key): + self.file_locks[key].acquire() + + def release(self, key): + self.file_locks[key].release() + + def __setitem__(self, key, value): + key = self.key_filter_in(key) + val_file = recfile.open(key, mode='wb', path=self.folder) + self.wait_portalock(val_file) + pickle.dump(value, val_file, pickle.HIGHEST_PROTOCOL) + val_file.close() + + def __getitem__(self, key): + key = self.key_filter_in(key) + try: + val_file = recfile.open(key, mode='rb', path=self.folder) + except IOError: + raise KeyError + + self.wait_portalock(val_file) + value = pickle.load(val_file) + val_file.close() + return value + + def __contains__(self, key): + key = self.key_filter_in(key) + return (key in self.file_locks) or recfile.exists(key, path=self.folder) + + def __delitem__(self, key): + key = self.key_filter_in(key) + try: + recfile.remove(key, path=self.folder) + except IOError: + raise KeyError + + def __iter__(self): + for dirpath, dirnames, filenames in os.walk(self.folder): + for filename in filenames: + yield self.key_filter_out(filename) + + def safe_apply(self, key, function, default_value=None): + """ + Safely apply a function to the value of a key in storage and set + the return value of the function to it. + + Return the result of applying the function. + """ + key = self.key_filter_in(key) + exists = True + try: + val_file = recfile.open(key, mode='r+b', path=self.folder) + except IOError: + exists = False + val_file = recfile.open(key, mode='wb', path=self.folder) + self.wait_portalock(val_file) + if exists: + timestamp, value = pickle.load(val_file) + else: + value = default_value + new_value = function(value) + val_file.seek(0) + pickle.dump((time.time(), new_value), val_file, pickle.HIGHEST_PROTOCOL) + val_file.truncate() + val_file.close() + return new_value + + def keys(self): + return list(self.__iter__()) + + def get(self, key, default=None): + try: + return self[key] + except KeyError: + return default + + def __init__(self, request=None, folder=None): + self.initialized = False + self.request = request + self.folder = folder + self.storage = None + + def initialize(self): + if self.initialized: + return + else: + self.initialized = True + + folder = self.folder + request = self.request + + # Lets test if the cache folder exists, if not + # we are going to create it + folder = os.path.join(folder or request.folder, 'cache') + + if not os.path.exists(folder): + os.mkdir(folder) + + self.storage = CacheOnDisk.PersistentStorage(folder) + + def __call__(self, key, f, + time_expire=DEFAULT_TIME_EXPIRE): + self.initialize() + + def inc_hit_total(v): + v['hit_total'] += 1 + return v + + def inc_misses(v): + v['misses'] += 1 + return v + + dt = time_expire + self.storage.acquire(key) + self.storage.acquire(CacheAbstract.cache_stats_name) + item = self.storage.get(key) + self.storage.safe_apply(CacheAbstract.cache_stats_name, inc_hit_total, + default_value={'hit_total': 0, 'misses': 0}) + + if item and f is None: + del self.storage[key] + + if f is None: + self.storage.release(CacheAbstract.cache_stats_name) + self.storage.release(key) + return None + + now = time.time() + + if item and ((dt is None) or (item[0] > now - dt)): + value = item[1] + else: + try: + value = f() + except: + self.storage.release(CacheAbstract.cache_stats_name) + self.storage.release(key) + raise + self.storage[key] = (now, value) + self.storage.safe_apply(CacheAbstract.cache_stats_name, inc_misses, + default_value={'hit_total': 0, 'misses': 0}) + + self.storage.release(CacheAbstract.cache_stats_name) + self.storage.release(key) + return value + + def clear(self, regex=None): + self.initialize() + storage = self.storage + if regex is None: + keys = storage + else: + r = re.compile(regex) + keys = (key for key in storage if r.match(key)) + for key in keys: + storage.acquire(key) + try: + del storage[key] + except KeyError: + pass + storage.release(key) + + def increment(self, key, value=1): + self.initialize() + self.storage.acquire(key) + value = self.storage.safe_apply(key, lambda x: x + value, default_value=0) + self.storage.release(key) + return value + + +class CacheAction(object): + def __init__(self, func, key, time_expire, cache, cache_model): + self.__name__ = func.__name__ + self.__doc__ = func.__doc__ + self.func = func + self.key = key + self.time_expire = time_expire + self.cache = cache + self.cache_model = cache_model + + def __call__(self, *a, **b): + if not self.key: + key2 = self.__name__ + ':' + repr(a) + ':' + repr(b) + else: + key2 = self.key.replace('%(name)s', self.__name__)\ + .replace('%(args)s', str(a)).replace('%(vars)s', str(b)) + cache_model = self.cache_model + if not cache_model or isinstance(cache_model, str): + cache_model = getattr(self.cache, cache_model or 'ram') + return cache_model(key2, + lambda a=a, b=b: self.func(*a, **b), + self.time_expire) + + +class Cache(object): + """ + Sets up generic caching, creating an instance of both CacheInRam and + CacheOnDisk. + In case of GAE will make use of gluon.contrib.gae_memcache. + + - self.ram is an instance of CacheInRam + - self.disk is an instance of CacheOnDisk + """ + + autokey = ':%(name)s:%(args)s:%(vars)s' + + def __init__(self, request): + """ + Args: + request: the global request object + """ + # GAE will have a special caching + if have_settings and settings.global_settings.web2py_runtime_gae: + from gluon.contrib.gae_memcache import MemcacheClient + self.ram = self.disk = MemcacheClient(request) + else: + # Otherwise use ram (and try also disk) + self.ram = CacheInRam(request) + try: + self.disk = CacheOnDisk(request) + except IOError: + logger.warning('no cache.disk (IOError)') + except AttributeError: + # normally not expected anymore, as GAE has already + # been accounted for + logger.warning('no cache.disk (AttributeError)') + + def action(self, time_expire=DEFAULT_TIME_EXPIRE, cache_model=None, + prefix=None, session=False, vars=True, lang=True, + user_agent=False, public=True, valid_statuses=None, + quick=None): + """Better fit for caching an action + + Warning: + Experimental! + + Currently only HTTP 1.1 compliant + reference : http://code.google.com/p/doctype-mirror/wiki/ArticleHttpCaching + + Args: + time_expire(int): same as @cache + cache_model(str): same as @cache + prefix(str): add a prefix to the calculated key + session(bool): adds response.session_id to the key + vars(bool): adds request.env.query_string + lang(bool): adds T.accepted_language + user_agent(bool or dict): if True, adds is_mobile and is_tablet to the key. + Pass a dict to use all the needed values (uses str(.items())) + (e.g. user_agent=request.user_agent()). Used only if session is + not True + public(bool): if False forces the Cache-Control to be 'private' + valid_statuses: by default only status codes starting with 1,2,3 will be cached. + pass an explicit list of statuses on which turn the cache on + quick: Session,Vars,Lang,User-agent,Public: + fast overrides with initials, e.g. 'SVLP' or 'VLP', or 'VLP' + """ + from gluon import current + from gluon.http import HTTP + + def wrap(func): + def wrapped_f(): + if current.request.env.request_method != 'GET': + return func() + + if quick: + session_ = True if 'S' in quick else False + vars_ = True if 'V' in quick else False + lang_ = True if 'L' in quick else False + user_agent_ = True if 'U' in quick else False + public_ = True if 'P' in quick else False + else: + (session_, vars_, lang_, user_agent_, public_) = \ + (session, vars, lang, user_agent, public) + + if time_expire: + cache_control = 'max-age=%(time_expire)s, s-maxage=%(time_expire)s' % dict(time_expire=time_expire) + if not session_ and public_: + cache_control += ', public' + expires = (current.request.utcnow + datetime.timedelta(seconds=time_expire) + ).strftime('%a, %d %b %Y %H:%M:%S GMT') + else: + cache_control += ', private' + expires = 'Fri, 01 Jan 1990 00:00:00 GMT' + + if cache_model: + # figure out the correct cache key + cache_key = [current.request.env.path_info, current.response.view] + if session_: + cache_key.append(current.response.session_id) + elif user_agent_: + if user_agent_ is True: + cache_key.append("%(is_mobile)s_%(is_tablet)s" % current.request.user_agent()) + else: + cache_key.append(str(user_agent_.items())) + if vars_: + cache_key.append(current.request.env.query_string) + if lang_: + cache_key.append(current.T.accepted_language) + cache_key = hashlib_md5('__'.join(cache_key)).hexdigest() + if prefix: + cache_key = prefix + cache_key + try: + # action returns something + rtn = cache_model(cache_key, lambda: func(), time_expire=time_expire) + http, status = None, current.response.status + except HTTP as e: + # action raises HTTP (can still be valid) + rtn = cache_model(cache_key, lambda: e.body, time_expire=time_expire) + http, status = HTTP(e.status, rtn, **e.headers), e.status + else: + # action raised a generic exception + http = None + else: + # no server-cache side involved + try: + # action returns something + rtn = func() + http, status = None, current.response.status + except HTTP as e: + # action raises HTTP (can still be valid) + status = e.status + http = HTTP(e.status, e.body, **e.headers) + else: + # action raised a generic exception + http = None + send_headers = False + if http and isinstance(valid_statuses, list): + if status in valid_statuses: + send_headers = True + elif valid_statuses is None: + if str(status)[0] in '123': + send_headers = True + if send_headers: + headers = {'Pragma': None, + 'Expires': expires, + 'Cache-Control': cache_control} + current.response.headers.update(headers) + if cache_model and not send_headers: + # we cached already the value, but the status is not valid + # so we need to delete the cached value + cache_model(cache_key, None) + if http: + if send_headers: + http.headers.update(current.response.headers) + raise http + return rtn + wrapped_f.__name__ = func.__name__ + wrapped_f.__doc__ = func.__doc__ + return wrapped_f + return wrap + + def __call__(self, + key=None, + time_expire=DEFAULT_TIME_EXPIRE, + cache_model=None): + """ + Decorator function that can be used to cache any function/method. + + Args: + key(str) : the key of the object to be store or retrieved + time_expire(int) : expiration of the cache in seconds + `time_expire` is used to compare the current time with the time + when the requested object was last saved in cache. + It does not affect future requests. + Setting `time_expire` to 0 or negative value forces the cache to + refresh. + cache_model(str): can be "ram", "disk" or other (like "memcache"). + Defaults to "ram" + + When the function `f` is called, web2py tries to retrieve + the value corresponding to `key` from the cache if the + object exists and if it did not expire, else it calles the function `f` + and stores the output in the cache corresponding to `key`. In the case + the output of the function is returned. + + Example: :: + + @cache('key', 5000, cache.ram) + def f(): + return time.ctime() + + Note: + If the function `f` is an action, we suggest using + @cache.action instead + """ + + def tmp(func, cache=self, cache_model=cache_model): + return CacheAction(func, key, time_expire, self, cache_model) + return tmp + + @staticmethod + def with_prefix(cache_model, prefix): + """ + allow replacing cache.ram with cache.with_prefix(cache.ram,'prefix') + it will add prefix to all the cache keys used. + """ + return lambda key, f, time_expire=DEFAULT_TIME_EXPIRE, prefix=prefix: cache_model(prefix + key, f, time_expire) + + +def lazy_cache(key=None, time_expire=None, cache_model='ram'): + """ + Can be used to cache any function including ones in modules, + as long as the cached function is only called within a web2py request + + If a key is not provided, one is generated from the function name + `time_expire` defaults to None (no cache expiration) + + If cache_model is "ram" then the model is current.cache.ram, etc. + """ + def decorator(f, key=key, time_expire=time_expire, cache_model=cache_model): + key = key or repr(f) + + def g(*c, **d): + from gluon import current + return current.cache(key, time_expire, cache_model)(f)(*c, **d) + g.__name__ = f.__name__ + return g + return decorator diff --git a/web2py/gluon/cfs.py b/web2py/gluon/cfs.py new file mode 100644 index 0000000..4925a3c --- /dev/null +++ b/web2py/gluon/cfs.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +Functions required to execute app components +-------------------------------------------- + +Note: + FOR INTERNAL USE ONLY +""" + +from os import stat +from gluon.fileutils import read_file +from gluon._compat import thread + +cfs = {} # for speed-up +cfs_lock = thread.allocate_lock() # and thread safety + + +def getcfs(key, filename, filter=None): + """ + Caches the *filtered* file `filename` with `key` until the file is + modified. + + Args: + key(str): the cache key + filename: the file to cache + filter: is the function used for filtering. Normally `filename` is a + .py file and `filter` is a function that bytecode compiles the file. + In this way the bytecode compiled file is cached. (Default = None) + + This is used on Google App Engine since pyc files cannot be saved. + """ + try: + t = stat(filename).st_mtime + except OSError: + return filter() if callable(filter) else '' + cfs_lock.acquire() + item = cfs.get(key, None) + cfs_lock.release() + if item and item[0] == t: + return item[1] + if not callable(filter): + data = read_file(filename) + else: + data = filter() + cfs_lock.acquire() + cfs[key] = (t, data) + cfs_lock.release() + return data diff --git a/web2py/gluon/compileapp.py b/web2py/gluon/compileapp.py new file mode 100644 index 0000000..0d61afb --- /dev/null +++ b/web2py/gluon/compileapp.py @@ -0,0 +1,755 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +Functions required to execute app components +--------------------------------------------- + +Note: + FOR INTERNAL USE ONLY +""" + +import re +import fnmatch +import os +import copy +import random +from gluon._compat import builtin, PY2, unicodeT, to_native, to_bytes, iteritems, basestring, reduce, xrange, long, reload +from gluon.storage import Storage, List +from gluon.template import parse_template +from gluon.restricted import restricted, compile2 +from gluon.fileutils import mktree, listdir, read_file, write_file +from gluon.myregex import regex_expose, regex_longcomments +from gluon.languages import translator +from gluon.dal import DAL, Field +from pydal.base import BaseAdapter +from gluon.sqlhtml import SQLFORM, SQLTABLE +from gluon.cache import Cache +from gluon.globals import current, Response +from gluon import settings +from gluon.cfs import getcfs +from gluon import html +from gluon import validators +from gluon.http import HTTP, redirect +import marshal +import shutil +import imp +import logging +import types +from functools import reduce +from gluon import rewrite +from gluon.custom_import import custom_import_install +import py_compile + +logger = logging.getLogger("web2py") + +is_pypy = settings.global_settings.is_pypy +is_gae = settings.global_settings.web2py_runtime_gae +is_jython = settings.global_settings.is_jython +pjoin = os.path.join + +marshal_header_size = 8 if PY2 else 12 + +TEST_CODE = \ + r""" +def _TEST(): + import doctest, sys, cStringIO, types, cgi, gluon.fileutils + if not gluon.fileutils.check_credentials(request): + raise HTTP(401, web2py_error='invalid credentials') + stdout = sys.stdout + html = '

    Testing controller "%s.py" ... done.


    \n' \ + % request.controller + for key in sorted([key for key in globals() if not key in __symbols__+['_TEST']]): + eval_key = eval(key) + if type(eval_key) == types.FunctionType: + number_doctests = sum([len(ds.examples) for ds in doctest.DocTestFinder().find(eval_key)]) + if number_doctests>0: + sys.stdout = cStringIO.StringIO() + name = '%s/controllers/%s.py in %s.__doc__' \ + % (request.folder, request.controller, key) + doctest.run_docstring_examples(eval_key, + globals(), False, name=name) + report = sys.stdout.getvalue().strip() + if report: + pf = 'failed' + else: + pf = 'passed' + html += '

    Function %s [%s]

    \n' \ + % (pf, key, pf) + if report: + html += CODE(report, language='web2py', \ + link='/examples/global/vars/').xml() + html += '
    \n' + else: + html += \ + '

    Function %s [no doctests]


    \n' \ + % (key) + response._vars = html + sys.stdout = stdout +_TEST() +""" + +CACHED_REGEXES = {} +CACHED_REGEXES_MAX_SIZE = 1000 + + +def re_compile(regex): + try: + return CACHED_REGEXES[regex] + except KeyError: + if len(CACHED_REGEXES) >= CACHED_REGEXES_MAX_SIZE: + CACHED_REGEXES.clear() + compiled_regex = CACHED_REGEXES[regex] = re.compile(regex) + return compiled_regex + + +class mybuiltin(object): + """ + NOTE could simple use a dict and populate it, + NOTE not sure if this changes things though if monkey patching import..... + """ + # __builtins__ + def __getitem__(self, key): + try: + return getattr(builtin, key) + except AttributeError: + raise KeyError(key) + + def __setitem__(self, key, value): + setattr(self, key, value) + + +def LOAD(c=None, f='index', args=None, vars=None, + extension=None, target=None, ajax=False, ajax_trap=False, + url=None, user_signature=False, timeout=None, times=1, + content='loading...', post_vars=Storage(), **attr): + """ LOADs a component into the action's document + + Args: + c(str): controller + f(str): function + args(tuple or list): arguments + vars(dict): vars + extension(str): extension + target(str): id of the target + ajax(bool): True to enable AJAX bahaviour + ajax_trap(bool): True if `ajax` is set to `True`, traps + both links and forms "inside" the target + url(str): overrides `c`,`f`,`args` and `vars` + user_signature(bool): adds hmac signature to all links + with a key that is different for every user + timeout(int): in milliseconds, specifies the time to wait before + starting the request or the frequency if times is greater than + 1 or "infinity" + times(integer or str): how many times the component will be requested + "infinity" or "continuous" are accepted to reload indefinitely the + component + """ + from gluon.html import TAG, DIV, URL, SCRIPT, XML + if args is None: + args = [] + vars = Storage(vars or {}) + target = target or 'c' + str(random.random())[2:] + attr['_id'] = target + request = current.request + if '.' in f: + f, extension = f.rsplit('.', 1) + if url or ajax: + url = url or URL(request.application, c, f, r=request, + args=args, vars=vars, extension=extension, + user_signature=user_signature) + # timing options + if isinstance(times, basestring): + if times.upper() in ("INFINITY", "CONTINUOUS"): + times = "Infinity" + else: + raise TypeError("Unsupported times argument %s" % times) + elif isinstance(times, int): + if times <= 0: + raise ValueError("Times argument must be greater than zero, 'Infinity' or None") + else: + raise TypeError("Unsupported times argument type %s" % type(times)) + if timeout is not None: + if not isinstance(timeout, (int, long)): + raise ValueError("Timeout argument must be an integer or None") + elif timeout <= 0: + raise ValueError( + "Timeout argument must be greater than zero or None") + statement = "$.web2py.component('%s','%s', %s, %s);" \ + % (url, target, timeout, times) + attr['_data-w2p_timeout'] = timeout + attr['_data-w2p_times'] = times + else: + statement = "$.web2py.component('%s','%s');" % (url, target) + attr['_data-w2p_remote'] = url + if target is not None: + return DIV(content, **attr) + + else: + if not isinstance(args, (list, tuple)): + args = [args] + c = c or request.controller + other_request = Storage(request) + other_request['env'] = Storage(request.env) + other_request.controller = c + other_request.function = f + other_request.extension = extension or request.extension + other_request.args = List(args) + other_request.vars = vars + other_request.get_vars = vars + other_request.post_vars = post_vars + other_response = Response() + other_request.env.path_info = '/' + \ + '/'.join([request.application, c, f] + + [str(a) for a in other_request.args]) + other_request.env.query_string = \ + vars and URL(vars=vars).split('?')[1] or '' + other_request.env.http_web2py_component_location = \ + request.env.path_info + other_request.cid = target + other_request.env.http_web2py_component_element = target + other_request.restful = types.MethodType(request.restful.__func__, other_request) + # A bit nasty but needed to use LOAD on action decorates with @request.restful() + other_response.view = '%s/%s.%s' % (c, f, other_request.extension) + + other_environment = copy.copy(current.globalenv) # NASTY + + other_response._view_environment = other_environment + other_response.generic_patterns = \ + copy.copy(current.response.generic_patterns) + other_environment['request'] = other_request + other_environment['response'] = other_response + + ## some magic here because current are thread-locals + + original_request, current.request = current.request, other_request + original_response, current.response = current.response, other_response + page = run_controller_in(c, f, other_environment) + if isinstance(page, dict): + other_response._vars = page + other_response._view_environment.update(page) + page = run_view_in(other_response._view_environment) + + current.request, current.response = original_request, original_response + js = None + if ajax_trap: + link = URL(request.application, c, f, r=request, + args=args, vars=vars, extension=extension, + user_signature=user_signature) + js = "$.web2py.trap_form('%s','%s');" % (link, target) + script = js and SCRIPT(js, _type="text/javascript") or '' + return TAG[''](DIV(XML(page), **attr), script) + + +class LoadFactory(object): + """ + Attention: this helper is new and experimental + """ + def __init__(self, environment): + self.environment = environment + + def __call__(self, c=None, f='index', args=None, vars=None, + extension=None, target=None, ajax=False, ajax_trap=False, + url=None, user_signature=False, content='loading...', **attr): + if args is None: + args = [] + vars = Storage(vars or {}) + import globals + target = target or 'c' + str(random.random())[2:] + attr['_id'] = target + request = current.request + if '.' in f: + f, extension = f.rsplit('.', 1) + if url or ajax: + url = url or html.URL(request.application, c, f, r=request, + args=args, vars=vars, extension=extension, + user_signature=user_signature) + script = html.SCRIPT('$.web2py.component("%s","%s")' % (url, target), + _type="text/javascript") + return html.TAG[''](script, html.DIV(content, **attr)) + else: + if not isinstance(args, (list, tuple)): + args = [args] + c = c or request.controller + + other_request = Storage(request) + other_request['env'] = Storage(request.env) + other_request.controller = c + other_request.function = f + other_request.extension = extension or request.extension + other_request.args = List(args) + other_request.vars = vars + other_request.get_vars = vars + other_request.post_vars = Storage() + other_response = globals.Response() + other_request.env.path_info = '/' + \ + '/'.join([request.application, c, f] + + [str(a) for a in other_request.args]) + other_request.env.query_string = \ + vars and html.URL(vars=vars).split('?')[1] or '' + other_request.env.http_web2py_component_location = \ + request.env.path_info + other_request.cid = target + other_request.env.http_web2py_component_element = target + other_response.view = '%s/%s.%s' % (c, f, other_request.extension) + other_environment = copy.copy(self.environment) + other_response._view_environment = other_environment + other_response.generic_patterns = \ + copy.copy(current.response.generic_patterns) + other_environment['request'] = other_request + other_environment['response'] = other_response + + ## some magic here because current are thread-locals + + original_request, current.request = current.request, other_request + original_response, current.response = current.response, other_response + page = run_controller_in(c, f, other_environment) + if isinstance(page, dict): + other_response._vars = page + other_response._view_environment.update(page) + page = run_view_in(other_response._view_environment) + + current.request, current.response = original_request, original_response + js = None + if ajax_trap: + link = html.URL(request.application, c, f, r=request, + args=args, vars=vars, extension=extension, + user_signature=user_signature) + js = "$.web2py.trap_form('%s','%s');" % (link, target) + script = js and html.SCRIPT(js, _type="text/javascript") or '' + return html.TAG[''](html.DIV(html.XML(page), **attr), script) + + +def local_import_aux(name, reload_force=False, app='welcome'): + """ + In apps, instead of importing a local module + (in applications/app/modules) with:: + + import a.b.c as d + + you should do:: + + d = local_import('a.b.c') + + or (to force a reload): + + d = local_import('a.b.c', reload=True) + + This prevents conflict between applications and un-necessary execs. + It can be used to import any module, including regular Python modules. + """ + items = name.replace('/', '.') + name = "applications.%s.modules.%s" % (app, items) + module = __import__(name) + for item in name.split(".")[1:]: + module = getattr(module, item) + if reload_force: + reload(module) + return module + + +""" +OLD IMPLEMENTATION: + items = name.replace('/','.').split('.') + filename, modulepath = items[-1], pjoin(apath,'modules',*items[:-1]) + imp.acquire_lock() + try: + file=None + (file,path,desc) = imp.find_module(filename,[modulepath]+sys.path) + if not path in sys.modules or reload: + if is_gae: + module={} + execfile(path,{},module) + module=Storage(module) + else: + module = imp.load_module(path,file,path,desc) + sys.modules[path] = module + else: + module = sys.modules[path] + except Exception, e: + module = None + if file: + file.close() + imp.release_lock() + if not module: + raise ImportError, "cannot find module %s in %s" % ( + filename, modulepath) + return module +""" + +_base_environment_ = dict((k, getattr(html, k)) for k in html.__all__) +_base_environment_.update( + (k, getattr(validators, k)) for k in validators.__all__) +_base_environment_['__builtins__'] = __builtins__ +_base_environment_['HTTP'] = HTTP +_base_environment_['redirect'] = redirect +_base_environment_['DAL'] = DAL +_base_environment_['Field'] = Field +_base_environment_['SQLDB'] = DAL # for backward compatibility +_base_environment_['SQLField'] = Field # for backward compatibility +_base_environment_['SQLFORM'] = SQLFORM +_base_environment_['SQLTABLE'] = SQLTABLE +_base_environment_['LOAD'] = LOAD +# For an easier PY3 migration +_base_environment_['PY2'] = PY2 +_base_environment_['to_native'] = to_native +_base_environment_['to_bytes'] = to_bytes +_base_environment_['iteritems'] = iteritems +_base_environment_['reduce'] = reduce +_base_environment_['xrange'] = xrange + + +def build_environment(request, response, session, store_current=True): + """ + Build the environment dictionary into which web2py files are executed. + """ + # h,v = html,validators + environment = dict(_base_environment_) + + if not request.env: + request.env = Storage() + # Enable standard conditional models (i.e., /*.py, /[controller]/*.py, and + # /[controller]/[function]/*.py) + response.models_to_run = [ + r'^\w+\.py$', + r'^%s/\w+\.py$' % request.controller, + r'^%s/%s/\w+\.py$' % (request.controller, request.function) + ] + + t = environment['T'] = translator(os.path.join(request.folder, 'languages'), + request.env.http_accept_language) + c = environment['cache'] = Cache(request) + + if store_current: + current.globalenv = environment + current.request = request + current.response = response + current.session = session + current.T = t + current.cache = c + + if is_jython: # jython hack + global __builtins__ + __builtins__ = mybuiltin() + + environment['request'] = request + environment['response'] = response + environment['session'] = session + environment['local_import'] = \ + lambda name, reload=False, app=request.application:\ + local_import_aux(name, reload, app) + BaseAdapter.set_folder(pjoin(request.folder, 'databases')) + custom_import_install() + return environment + + +def save_pyc(filename): + """ + Bytecode compiles the file `filename` + """ + cfile = "%sc" % filename + py_compile.compile(filename, cfile=cfile) + + +def read_pyc(filename): + """ + Read the code inside a bytecode compiled file if the MAGIC number is + compatible + + Returns: + a code object + """ + data = read_file(filename, 'rb') + if not is_gae and data[:4] != imp.get_magic(): + raise SystemError('compiled code is incompatible') + return marshal.loads(data[marshal_header_size:]) + + +def compile_views(folder, skip_failed_views=False): + """ + Compiles all the views in the application specified by `folder` + """ + + path = pjoin(folder, 'views') + failed_views = [] + for fname in listdir(path, '^[\w/\-]+(\.\w+)*$'): + try: + data = parse_template(fname, path) + except Exception as e: + if skip_failed_views: + failed_views.append(fname) + else: + raise Exception("%s in %s" % (e, fname)) + else: + filename = 'views.%s.py' % fname.replace(os.path.sep, '.') + filename = pjoin(folder, 'compiled', filename) + write_file(filename, data) + save_pyc(filename) + os.unlink(filename) + return failed_views if failed_views else None + + +def compile_models(folder): + """ + Compiles all the models in the application specified by `folder` + """ + + path = pjoin(folder, 'models') + for fname in listdir(path, '.+\.py$'): + data = read_file(pjoin(path, fname)) + modelfile = 'models.'+fname.replace(os.path.sep, '.') + filename = pjoin(folder, 'compiled', modelfile) + mktree(filename) + write_file(filename, data) + save_pyc(filename) + os.unlink(filename) + + +def find_exposed_functions(data): + data = regex_longcomments.sub('', data) + return regex_expose.findall(data) + + +def compile_controllers(folder): + """ + Compiles all the controllers in the application specified by `folder` + """ + + path = pjoin(folder, 'controllers') + for fname in listdir(path, '.+\.py$'): + ### why is this here? save_pyc(pjoin(path, file)) + data = read_file(pjoin(path, fname)) + exposed = find_exposed_functions(data) + for function in exposed: + command = data + "\nresponse._vars=response._caller(%s)\n" % \ + function + filename = pjoin(folder, 'compiled', + 'controllers.%s.%s.py' % (fname[:-3], function)) + write_file(filename, command) + save_pyc(filename) + os.unlink(filename) + + +def model_cmp(a, b, sep='.'): + return cmp(a.count(sep), b.count(sep)) or cmp(a, b) + + +def model_cmp_sep(a, b, sep=os.path.sep): + return model_cmp(a, b, sep) + + +def run_models_in(environment): + """ + Runs all models (in the app specified by the current folder) + It tries pre-compiled models first before compiling them. + """ + + request = current.request + folder = request.folder + c = request.controller + # f = environment['request'].function + response = current.response + + path = pjoin(folder, 'models') + cpath = pjoin(folder, 'compiled') + compiled = os.path.exists(cpath) + if PY2: + if compiled: + models = sorted(listdir(cpath, '^models[_.][\w.]+\.pyc$', 0), model_cmp) + else: + models = sorted(listdir(path, '^\w+\.py$', 0, sort=False), model_cmp_sep) + else: + if compiled: + models = sorted(listdir(cpath, '^models[_.][\w.]+\.pyc$', 0), + key=lambda f: '{0:03d}'.format(f.count('.')) + f) + else: + models = sorted(listdir(path, '^\w+\.py$', 0, sort=False), + key=lambda f: '{0:03d}'.format(f.count(os.path.sep)) + f) + + models_to_run = None + for model in models: + if response.models_to_run != models_to_run: + regex = models_to_run = response.models_to_run[:] + if isinstance(regex, list): + regex = re_compile('|'.join(regex)) + if models_to_run: + if compiled: + n = len(cpath)+8 + fname = model[n:-4].replace('.', '/')+'.py' + else: + n = len(path)+1 + fname = model[n:].replace(os.path.sep, '/') + if not regex.search(fname) and c != 'appadmin': + continue + elif compiled: + f = lambda: read_pyc(model) + else: + f = lambda: compile2(read_file(model), model) + ccode = getcfs(model, model, f) + restricted(ccode, environment, layer=model) + + +def run_controller_in(controller, function, environment): + """ + Runs the controller.function() (for the app specified by + the current folder). + It tries pre-compiled controller.function.pyc first before compiling it. + """ + + # if compiled should run compiled! + folder = current.request.folder + cpath = pjoin(folder, 'compiled') + badc = 'invalid controller (%s/%s)' % (controller, function) + badf = 'invalid function (%s/%s)' % (controller, function) + if os.path.exists(cpath): + filename = pjoin(cpath, 'controllers.%s.%s.pyc' % (controller, function)) + try: + ccode = getcfs(filename, filename, lambda: read_pyc(filename)) + except IOError: + raise HTTP(404, + rewrite.THREAD_LOCAL.routes.error_message % badf, + web2py_error=badf) + elif function == '_TEST': + # TESTING: adjust the path to include site packages + from gluon.settings import global_settings + from gluon.admin import abspath, add_path_first + paths = (global_settings.gluon_parent, abspath( + 'site-packages', gluon=True), abspath('gluon', gluon=True), '') + [add_path_first(path) for path in paths] + # TESTING END + + filename = pjoin(folder, 'controllers/%s.py' + % controller) + if not os.path.exists(filename): + raise HTTP(404, + rewrite.THREAD_LOCAL.routes.error_message % badc, + web2py_error=badc) + environment['__symbols__'] = environment.keys() + code = read_file(filename) + code += TEST_CODE + ccode = compile2(code, filename) + else: + filename = pjoin(folder, 'controllers/%s.py' % controller) + try: + code = getcfs(filename, filename, lambda: read_file(filename)) + except IOError: + raise HTTP(404, + rewrite.THREAD_LOCAL.routes.error_message % badc, + web2py_error=badc) + exposed = find_exposed_functions(code) + if function not in exposed: + raise HTTP(404, + rewrite.THREAD_LOCAL.routes.error_message % badf, + web2py_error=badf) + code = "%s\nresponse._vars=response._caller(%s)" % (code, function) + layer = "%s:%s" % (filename, function) + ccode = getcfs(layer, filename, lambda: compile2(code, filename)) + + restricted(ccode, environment, layer=filename) + response = environment["response"] + vars = response._vars + if response.postprocessing: + vars = reduce(lambda vars, p: p(vars), response.postprocessing, vars) + if isinstance(vars, unicodeT): + vars = to_native(vars) + elif hasattr(vars, 'xml') and callable(vars.xml): + vars = vars.xml() + return vars + + +def run_view_in(environment): + """ + Executes the view for the requested action. + The view is the one specified in `response.view` or determined by the url + or `view/generic.extension` + It tries the pre-compiled views.controller.function.pyc before compiling it. + """ + request = current.request + response = current.response + view = environment['response'].view + folder = request.folder + cpath = pjoin(folder, 'compiled') + badv = 'invalid view (%s)' % view + patterns = response.get('generic_patterns') + layer = None + scode = None + if patterns: + regex = re_compile('|'.join(fnmatch.translate(p) for p in patterns)) + short_action = '%(controller)s/%(function)s.%(extension)s' % request + allow_generic = regex.search(short_action) + else: + allow_generic = False + if not isinstance(view, str): + ccode = parse_template(view, pjoin(folder, 'views'), + context=environment) + layer = 'file stream' + else: + filename = pjoin(folder, 'views', view) + if os.path.exists(cpath): # compiled views + x = view.replace('/', '.') + files = ['views.%s.pyc' % x] + is_compiled = os.path.exists(pjoin(cpath, files[0])) + # Don't use a generic view if the non-compiled view exists. + if is_compiled or (not is_compiled and not os.path.exists(filename)): + if allow_generic: + files.append('views.generic.%s.pyc' % request.extension) + # for backward compatibility + if request.extension == 'html': + files.append('views.%s.pyc' % x[:-5]) + if allow_generic: + files.append('views.generic.pyc') + # end backward compatibility code + for f in files: + compiled = pjoin(cpath, f) + if os.path.exists(compiled): + ccode = getcfs(compiled, compiled, lambda: read_pyc(compiled)) + layer = compiled + break + # if the view is not compiled + if not layer: + if not os.path.exists(filename) and allow_generic: + view = 'generic.' + request.extension + filename = pjoin(folder, 'views', view) + if not os.path.exists(filename): + raise HTTP(404, + rewrite.THREAD_LOCAL.routes.error_message % badv, + web2py_error=badv) + # Parse template + scode = parse_template(view, + pjoin(folder, 'views'), + context=environment) + # Compile template + ccode = compile2(scode, filename) + layer = filename + restricted(ccode, environment, layer=layer, scode=scode) + # parse_template saves everything in response body + return environment['response'].body.getvalue() + + +def remove_compiled_application(folder): + """ + Deletes the folder `compiled` containing the compiled application. + """ + try: + shutil.rmtree(pjoin(folder, 'compiled')) + path = pjoin(folder, 'controllers') + for file in listdir(path, '.*\.pyc$', drop=False): + os.unlink(file) + except OSError: + pass + + +def compile_application(folder, skip_failed_views=False): + """ + Compiles all models, views, controller for the application in `folder`. + """ + remove_compiled_application(folder) + os.mkdir(pjoin(folder, 'compiled')) + compile_models(folder) + compile_controllers(folder) + failed_views = compile_views(folder, skip_failed_views) + return failed_views diff --git a/web2py/gluon/contenttype.py b/web2py/gluon/contenttype.py new file mode 100644 index 0000000..e5f6dd3 --- /dev/null +++ b/web2py/gluon/contenttype.py @@ -0,0 +1,855 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +CONTENT_TYPE dictionary created against freedesktop.org's shared mime info +database version 1.1. + +Deviations from official standards: + - .md: application/x-genesis-rom --> text/x-markdown + - .png: image/x-apple-ios-png --> image/png +Additions: + - .load: text/html + - .json: application/json + - .jsonp: application/jsonp + - .pickle: application/python-pickle + - .w2p': application/w2p +""" +from gluon._compat import to_native + +__all__ = ['contenttype'] + +CONTENT_TYPE = { + '.123': 'application/vnd.lotus-1-2-3', + '.3ds': 'image/x-3ds', + '.3g2': 'video/3gpp2', + '.3ga': 'video/3gpp', + '.3gp': 'video/3gpp', + '.3gp2': 'video/3gpp2', + '.3gpp': 'video/3gpp', + '.3gpp2': 'video/3gpp2', + '.602': 'application/x-t602', + '.669': 'audio/x-mod', + '.7z': 'application/x-7z-compressed', + '.a': 'application/x-archive', + '.aac': 'audio/aac', + '.abw': 'application/x-abiword', + '.abw.crashed': 'application/x-abiword', + '.abw.gz': 'application/x-abiword', + '.ac3': 'audio/ac3', + '.ace': 'application/x-ace', + '.adb': 'text/x-adasrc', + '.ads': 'text/x-adasrc', + '.afm': 'application/x-font-afm', + '.ag': 'image/x-applix-graphics', + '.ai': 'application/illustrator', + '.aif': 'audio/x-aiff', + '.aifc': 'audio/x-aifc', + '.aiff': 'audio/x-aiff', + '.aiffc': 'audio/x-aifc', + '.al': 'application/x-perl', + '.alz': 'application/x-alz', + '.amr': 'audio/amr', + '.amz': 'audio/x-amzxml', + '.ani': 'application/x-navi-animation', + '.anim[1-9j]': 'video/x-anim', + '.anx': 'application/annodex', + '.ape': 'audio/x-ape', + '.apk': 'application/vnd.android.package-archive', + '.ar': 'application/x-archive', + '.arj': 'application/x-arj', + '.arw': 'image/x-sony-arw', + '.as': 'application/x-applix-spreadsheet', + '.asc': 'text/plain', + '.asf': 'video/x-ms-asf', + '.asp': 'application/x-asp', + '.ass': 'text/x-ssa', + '.asx': 'audio/x-ms-asx', + '.atom': 'application/atom+xml', + '.au': 'audio/basic', + '.avf': 'video/x-msvideo', + '.avi': 'video/x-msvideo', + '.aw': 'application/x-applix-word', + '.awb': 'audio/amr-wb', + '.awk': 'application/x-awk', + '.axa': 'audio/annodex', + '.axv': 'video/annodex', + '.bak': 'application/x-trash', + '.bcpio': 'application/x-bcpio', + '.bdf': 'application/x-font-bdf', + '.bdm': 'video/mp2t', + '.bdmv': 'video/mp2t', + '.bib': 'text/x-bibtex', + '.bin': 'application/octet-stream', + '.blend': 'application/x-blender', + '.blender': 'application/x-blender', + '.bmp': 'image/bmp', + '.bz': 'application/x-bzip', + '.bz2': 'application/x-bzip', + '.c': 'text/x-csrc', + '.c++': 'text/x-c++src', + '.cab': 'application/vnd.ms-cab-compressed', + '.cap': 'application/vnd.tcpdump.pcap', + '.cb7': 'application/x-cb7', + '.cbl': 'text/x-cobol', + '.cbr': 'application/x-cbr', + '.cbt': 'application/x-cbt', + '.cbz': 'application/x-cbz', + '.cc': 'text/x-c++src', + '.ccmx': 'application/x-ccmx', + '.cdf': 'application/x-netcdf', + '.cdr': 'application/vnd.corel-draw', + '.cer': 'application/pkix-cert', + '.cert': 'application/x-x509-ca-cert', + '.cgm': 'image/cgm', + '.chm': 'application/vnd.ms-htmlhelp', + '.chrt': 'application/x-kchart', + '.class': 'application/x-java', + '.clpi': 'video/mp2t', + '.cls': 'text/x-tex', + '.cmake': 'text/x-cmake', + '.cob': 'text/x-cobol', + '.cpi': 'video/mp2t', + '.cpio': 'application/x-cpio', + '.cpio.gz': 'application/x-cpio-compressed', + '.cpp': 'text/x-c++src', + '.cr2': 'image/x-canon-cr2', + '.crl': 'application/pkix-crl', + '.crt': 'application/x-x509-ca-cert', + '.crw': 'image/x-canon-crw', + '.cs': 'text/x-csharp', + '.csh': 'application/x-csh', + '.css': 'text/css', + '.cssl': 'text/css', + '.csv': 'text/csv', + '.cue': 'application/x-cue', + '.cur': 'image/x-win-bitmap', + '.cxx': 'text/x-c++src', + '.d': 'text/x-dsrc', + '.dar': 'application/x-dar', + '.dbf': 'application/x-dbf', + '.dc': 'application/x-dc-rom', + '.dcl': 'text/x-dcl', + '.dcm': 'application/dicom', + '.dcr': 'image/x-kodak-dcr', + '.dds': 'image/x-dds', + '.deb': 'application/x-deb', + '.der': 'application/x-x509-ca-cert', + '.desktop': 'application/x-desktop', + '.di': 'text/x-dsrc', + '.dia': 'application/x-dia-diagram', + '.diff': 'text/x-patch', + '.divx': 'video/x-msvideo', + '.djv': 'image/vnd.djvu', + '.djvu': 'image/vnd.djvu', + '.dmg': 'application/x-apple-diskimage', + '.dmp': 'application/vnd.tcpdump.pcap', + '.dng': 'image/x-adobe-dng', + '.doc': 'application/msword', + '.docbook': 'application/x-docbook+xml', + '.docm': 'application/vnd.ms-word.document.macroenabled.12', + '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + '.dot': 'text/vnd.graphviz', + '.dotm': 'application/vnd.ms-word.template.macroenabled.12', + '.dotx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + '.dsl': 'text/x-dsl', + '.dtd': 'application/xml-dtd', + '.dts': 'audio/vnd.dts', + '.dtshd': 'audio/vnd.dts.hd', + '.dtx': 'text/x-tex', + '.dv': 'video/dv', + '.dvi': 'application/x-dvi', + '.dvi.bz2': 'application/x-bzdvi', + '.dvi.gz': 'application/x-gzdvi', + '.dwg': 'image/vnd.dwg', + '.dxf': 'image/vnd.dxf', + '.e': 'text/x-eiffel', + '.egon': 'application/x-egon', + '.eif': 'text/x-eiffel', + '.el': 'text/x-emacs-lisp', + '.emf': 'image/x-emf', + '.eml': 'message/rfc822', + '.emp': 'application/vnd.emusic-emusic_package', + '.ent': 'application/xml-external-parsed-entity', + '.eps': 'image/x-eps', + '.eps.bz2': 'image/x-bzeps', + '.eps.gz': 'image/x-gzeps', + '.epsf': 'image/x-eps', + '.epsf.bz2': 'image/x-bzeps', + '.epsf.gz': 'image/x-gzeps', + '.epsi': 'image/x-eps', + '.epsi.bz2': 'image/x-bzeps', + '.epsi.gz': 'image/x-gzeps', + '.epub': 'application/epub+zip', + '.erl': 'text/x-erlang', + '.es': 'application/ecmascript', + '.etheme': 'application/x-e-theme', + '.etx': 'text/x-setext', + '.exe': 'application/x-ms-dos-executable', + '.exr': 'image/x-exr', + '.ez': 'application/andrew-inset', + '.f': 'text/x-fortran', + '.f4a': 'audio/mp4', + '.f4b': 'audio/x-m4b', + '.f4v': 'video/mp4', + '.f90': 'text/x-fortran', + '.f95': 'text/x-fortran', + '.fb2': 'application/x-fictionbook+xml', + '.fig': 'image/x-xfig', + '.fits': 'image/fits', + '.fl': 'application/x-fluid', + '.flac': 'audio/flac', + '.flc': 'video/x-flic', + '.fli': 'video/x-flic', + '.flv': 'video/x-flv', + '.flw': 'application/x-kivio', + '.fo': 'text/x-xslfo', + '.fodg': 'application/vnd.oasis.opendocument.graphics-flat-xml', + '.fodp': 'application/vnd.oasis.opendocument.presentation-flat-xml', + '.fods': 'application/vnd.oasis.opendocument.spreadsheet-flat-xml', + '.fodt': 'application/vnd.oasis.opendocument.text-flat-xml', + '.for': 'text/x-fortran', + '.fxm': 'video/x-javafx', + '.g3': 'image/fax-g3', + '.gb': 'application/x-gameboy-rom', + '.gba': 'application/x-gba-rom', + '.gcrd': 'text/vcard', + '.ged': 'application/x-gedcom', + '.gedcom': 'application/x-gedcom', + '.gem': 'application/x-tar', + '.gen': 'application/x-genesis-rom', + '.gf': 'application/x-tex-gf', + '.gg': 'application/x-sms-rom', + '.gif': 'image/gif', + '.glade': 'application/x-glade', + '.gml': 'application/gml+xml', + '.gmo': 'application/x-gettext-translation', + '.gnc': 'application/x-gnucash', + '.gnd': 'application/gnunet-directory', + '.gnucash': 'application/x-gnucash', + '.gnumeric': 'application/x-gnumeric', + '.gnuplot': 'application/x-gnuplot', + '.go': 'text/x-go', + '.gp': 'application/x-gnuplot', + '.gpg': 'application/pgp-encrypted', + '.gplt': 'application/x-gnuplot', + '.gra': 'application/x-graphite', + '.gsf': 'application/x-font-type1', + '.gsm': 'audio/x-gsm', + '.gtar': 'application/x-tar', + '.gv': 'text/vnd.graphviz', + '.gvp': 'text/x-google-video-pointer', + '.gz': 'application/gzip', + '.h': 'text/x-chdr', + '.h++': 'text/x-c++hdr', + '.h4': 'application/x-hdf', + '.h5': 'application/x-hdf', + '.hdf': 'application/x-hdf', + '.hdf4': 'application/x-hdf', + '.hdf5': 'application/x-hdf', + '.hh': 'text/x-c++hdr', + '.hlp': 'application/winhlp', + '.hp': 'text/x-c++hdr', + '.hpgl': 'application/vnd.hp-hpgl', + '.hpp': 'text/x-c++hdr', + '.hs': 'text/x-haskell', + '.htm': 'text/html', + '.html': 'text/html', + '.hwp': 'application/x-hwp', + '.hwt': 'application/x-hwt', + '.hxx': 'text/x-c++hdr', + '.ica': 'application/x-ica', + '.icb': 'image/x-tga', + '.icc': 'application/vnd.iccprofile', + '.icm': 'application/vnd.iccprofile', + '.icns': 'image/x-icns', + '.ico': 'image/vnd.microsoft.icon', + '.ics': 'text/calendar', + '.idl': 'text/x-idl', + '.ief': 'image/ief', + '.iff': 'image/x-ilbm', + '.ilbm': 'image/x-ilbm', + '.ime': 'text/x-imelody', + '.imy': 'text/x-imelody', + '.ins': 'text/x-tex', + '.iptables': 'text/x-iptables', + '.iso': 'application/x-cd-image', + '.iso9660': 'application/x-cd-image', + '.it': 'audio/x-it', + '.it87': 'application/x-it87', + '.j2k': 'image/jp2', + '.jad': 'text/vnd.sun.j2me.app-descriptor', + '.jar': 'application/x-java-archive', + '.java': 'text/x-java', + '.jceks': 'application/x-java-jce-keystore', + '.jks': 'application/x-java-keystore', + '.jng': 'image/x-jng', + '.jnlp': 'application/x-java-jnlp-file', + '.jp2': 'image/jp2', + '.jpc': 'image/jp2', + '.jpe': 'image/jpeg', + '.jpeg': 'image/jpeg', + '.jpf': 'image/jp2', + '.jpg': 'image/jpeg', + '.jpr': 'application/x-jbuilder-project', + '.jpx': 'image/jp2', + '.js': 'application/javascript', + '.json': 'application/json', + '.jsonp': 'application/jsonp', + '.k25': 'image/x-kodak-k25', + '.kar': 'audio/midi', + '.karbon': 'application/x-karbon', + '.kdc': 'image/x-kodak-kdc', + '.kdelnk': 'application/x-desktop', + '.kexi': 'application/x-kexiproject-sqlite3', + '.kexic': 'application/x-kexi-connectiondata', + '.kexis': 'application/x-kexiproject-shortcut', + '.kfo': 'application/x-kformula', + '.kil': 'application/x-killustrator', + '.kino': 'application/smil', + '.kml': 'application/vnd.google-earth.kml+xml', + '.kmz': 'application/vnd.google-earth.kmz', + '.kon': 'application/x-kontour', + '.kpm': 'application/x-kpovmodeler', + '.kpr': 'application/x-kpresenter', + '.kpt': 'application/x-kpresenter', + '.kra': 'application/x-krita', + '.ks': 'application/x-java-keystore', + '.ksp': 'application/x-kspread', + '.kud': 'application/x-kugar', + '.kwd': 'application/x-kword', + '.kwt': 'application/x-kword', + '.la': 'application/x-shared-library-la', + '.latex': 'text/x-tex', + '.lbm': 'image/x-ilbm', + '.ldif': 'text/x-ldif', + '.lha': 'application/x-lha', + '.lhs': 'text/x-literate-haskell', + '.lhz': 'application/x-lhz', + '.load': 'text/html', + '.log': 'text/x-log', + '.lrz': 'application/x-lrzip', + '.ltx': 'text/x-tex', + '.lua': 'text/x-lua', + '.lwo': 'image/x-lwo', + '.lwob': 'image/x-lwo', + '.lwp': 'application/vnd.lotus-wordpro', + '.lws': 'image/x-lws', + '.ly': 'text/x-lilypond', + '.lyx': 'application/x-lyx', + '.lz': 'application/x-lzip', + '.lzh': 'application/x-lha', + '.lzma': 'application/x-lzma', + '.lzo': 'application/x-lzop', + '.m': 'text/x-matlab', + '.m15': 'audio/x-mod', + '.m1u': 'video/vnd.mpegurl', + '.m2t': 'video/mp2t', + '.m2ts': 'video/mp2t', + '.m3u': 'application/vnd.apple.mpegurl', + '.m3u8': 'application/vnd.apple.mpegurl', + '.m4': 'application/x-m4', + '.m4a': 'audio/mp4', + '.m4b': 'audio/x-m4b', + '.m4u': 'video/vnd.mpegurl', + '.m4v': 'video/mp4', + '.mab': 'application/x-markaby', + '.mak': 'text/x-makefile', + '.man': 'application/x-troff-man', + '.manifest': 'text/cache-manifest', + '.markdown': 'text/x-markdown', + '.mbox': 'application/mbox', + '.md': 'text/x-markdown', + '.mdb': 'application/vnd.ms-access', + '.mdi': 'image/vnd.ms-modi', + '.me': 'text/x-troff-me', + '.med': 'audio/x-mod', + '.meta4': 'application/metalink4+xml', + '.metalink': 'application/metalink+xml', + '.mgp': 'application/x-magicpoint', + '.mht': 'application/x-mimearchive', + '.mhtml': 'application/x-mimearchive', + '.mid': 'audio/midi', + '.midi': 'audio/midi', + '.mif': 'application/x-mif', + '.minipsf': 'audio/x-minipsf', + '.mk': 'text/x-makefile', + '.mka': 'audio/x-matroska', + '.mkd': 'text/x-markdown', + '.mkv': 'video/x-matroska', + '.ml': 'text/x-ocaml', + '.mli': 'text/x-ocaml', + '.mm': 'text/x-troff-mm', + '.mmf': 'application/x-smaf', + '.mml': 'application/mathml+xml', + '.mng': 'video/x-mng', + '.mo': 'text/x-modelica', + '.mo3': 'audio/x-mo3', + '.mobi': 'application/x-mobipocket-ebook', + '.moc': 'text/x-moc', + '.mod': 'audio/x-mod', + '.mof': 'text/x-mof', + '.moov': 'video/quicktime', + '.mov': 'video/quicktime', + '.movie': 'video/x-sgi-movie', + '.mp+': 'audio/x-musepack', + '.mp2': 'video/mpeg', + '.mp3': 'audio/mpeg', + '.mp4': 'video/mp4', + '.mpc': 'audio/x-musepack', + '.mpe': 'video/mpeg', + '.mpeg': 'video/mpeg', + '.mpg': 'video/mpeg', + '.mpga': 'audio/mpeg', + '.mpl': 'video/mp2t', + '.mpls': 'video/mp2t', + '.mpp': 'audio/x-musepack', + '.mrl': 'text/x-mrml', + '.mrml': 'text/x-mrml', + '.mrw': 'image/x-minolta-mrw', + '.ms': 'text/x-troff-ms', + '.msi': 'application/x-msi', + '.msod': 'image/x-msod', + '.msx': 'application/x-msx-rom', + '.mtm': 'audio/x-mod', + '.mts': 'video/mp2t', + '.mup': 'text/x-mup', + '.mxf': 'application/mxf', + '.mxu': 'video/vnd.mpegurl', + '.n64': 'application/x-n64-rom', + '.nb': 'application/mathematica', + '.nc': 'application/x-netcdf', + '.nds': 'application/x-nintendo-ds-rom', + '.nef': 'image/x-nikon-nef', + '.nes': 'application/x-nes-rom', + '.nfo': 'text/x-nfo', + '.not': 'text/x-mup', + '.nsc': 'application/x-netshow-channel', + '.nsv': 'video/x-nsv', + '.nzb': 'application/x-nzb', + '.o': 'application/x-object', + '.obj': 'application/x-tgif', + '.ocl': 'text/x-ocl', + '.oda': 'application/oda', + '.odb': 'application/vnd.oasis.opendocument.database', + '.odc': 'application/vnd.oasis.opendocument.chart', + '.odf': 'application/vnd.oasis.opendocument.formula', + '.odg': 'application/vnd.oasis.opendocument.graphics', + '.odi': 'application/vnd.oasis.opendocument.image', + '.odm': 'application/vnd.oasis.opendocument.text-master', + '.odp': 'application/vnd.oasis.opendocument.presentation', + '.ods': 'application/vnd.oasis.opendocument.spreadsheet', + '.odt': 'application/vnd.oasis.opendocument.text', + '.oga': 'audio/ogg', + '.ogg': 'application/ogg', + '.ogm': 'video/x-ogm+ogg', + '.ogv': 'video/ogg', + '.ogx': 'application/ogg', + '.old': 'application/x-trash', + '.oleo': 'application/x-oleo', + '.ooc': 'text/x-ooc', + '.opml': 'text/x-opml+xml', + '.oprc': 'application/vnd.palm', + '.ora': 'image/openraster', + '.orf': 'image/x-olympus-orf', + '.otc': 'application/vnd.oasis.opendocument.chart-template', + '.otf': 'application/x-font-otf', + '.otg': 'application/vnd.oasis.opendocument.graphics-template', + '.oth': 'application/vnd.oasis.opendocument.text-web', + '.otp': 'application/vnd.oasis.opendocument.presentation-template', + '.ots': 'application/vnd.oasis.opendocument.spreadsheet-template', + '.ott': 'application/vnd.oasis.opendocument.text-template', + '.owl': 'application/rdf+xml', + '.oxps': 'application/oxps', + '.oxt': 'application/vnd.openofficeorg.extension', + '.p': 'text/x-pascal', + '.p10': 'application/pkcs10', + '.p12': 'application/x-pkcs12', + '.p7b': 'application/x-pkcs7-certificates', + '.p7c': 'application/pkcs7-mime', + '.p7m': 'application/pkcs7-mime', + '.p7s': 'application/pkcs7-signature', + '.p8': 'application/pkcs8', + '.pack': 'application/x-java-pack200', + '.pak': 'application/x-pak', + '.par2': 'application/x-par2', + '.pas': 'text/x-pascal', + '.patch': 'text/x-patch', + '.pbm': 'image/x-portable-bitmap', + '.pcap': 'application/vnd.tcpdump.pcap', + '.pcd': 'image/x-photo-cd', + '.pcf': 'application/x-cisco-vpn-settings', + '.pcf.gz': 'application/x-font-pcf', + '.pcf.z': 'application/x-font-pcf', + '.pcl': 'application/vnd.hp-pcl', + '.pct': 'image/x-pict', + '.pcx': 'image/x-pcx', + '.pdb': 'chemical/x-pdb', + '.pdc': 'application/x-aportisdoc', + '.pdf': 'application/pdf', + '.pdf.bz2': 'application/x-bzpdf', + '.pdf.gz': 'application/x-gzpdf', + '.pdf.xz': 'application/x-xzpdf', + '.pef': 'image/x-pentax-pef', + '.pem': 'application/x-x509-ca-cert', + '.perl': 'application/x-perl', + '.pfa': 'application/x-font-type1', + '.pfb': 'application/x-font-type1', + '.pfx': 'application/x-pkcs12', + '.pgm': 'image/x-portable-graymap', + '.pgn': 'application/x-chess-pgn', + '.pgp': 'application/pgp-encrypted', + '.php': 'application/x-php', + '.php3': 'application/x-php', + '.php4': 'application/x-php', + '.php5': 'application/x-php', + '.phps': 'application/x-php', + '.pict': 'image/x-pict', + '.pict1': 'image/x-pict', + '.pict2': 'image/x-pict', + '.pk': 'application/x-tex-pk', + '.pkipath': 'application/pkix-pkipath', + '.pkr': 'application/pgp-keys', + '.pl': 'application/x-perl', + '.pla': 'audio/x-iriver-pla', + '.pln': 'application/x-planperfect', + '.pls': 'audio/x-scpls', + '.pm': 'application/x-perl', + '.png': 'image/png', + '.pnm': 'image/x-portable-anymap', + '.pntg': 'image/x-macpaint', + '.po': 'text/x-gettext-translation', + '.por': 'application/x-spss-por', + '.pot': 'text/x-gettext-translation-template', + '.potm': 'application/vnd.ms-powerpoint.template.macroenabled.12', + '.potx': 'application/vnd.openxmlformats-officedocument.presentationml.template', + '.ppam': 'application/vnd.ms-powerpoint.addin.macroenabled.12', + '.ppm': 'image/x-portable-pixmap', + '.pps': 'application/vnd.ms-powerpoint', + '.ppsm': 'application/vnd.ms-powerpoint.slideshow.macroenabled.12', + '.ppsx': 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + '.ppt': 'application/vnd.ms-powerpoint', + '.pptm': 'application/vnd.ms-powerpoint.presentation.macroenabled.12', + '.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + '.ppz': 'application/vnd.ms-powerpoint', + '.pqa': 'application/vnd.palm', + '.prc': 'application/vnd.palm', + '.ps': 'application/postscript', + '.ps.bz2': 'application/x-bzpostscript', + '.ps.gz': 'application/x-gzpostscript', + '.psd': 'image/vnd.adobe.photoshop', + '.psf': 'audio/x-psf', + '.psf.gz': 'application/x-gz-font-linux-psf', + '.psflib': 'audio/x-psflib', + '.psid': 'audio/prs.sid', + '.psw': 'application/x-pocket-word', + '.pw': 'application/x-pw', + '.py': 'text/x-python', + '.pyc': 'application/x-python-bytecode', + '.pickle': 'application/python-pickle', + '.pyo': 'application/x-python-bytecode', + '.qif': 'image/x-quicktime', + '.qml': 'text/x-qml', + '.qt': 'video/quicktime', + '.qti': 'application/x-qtiplot', + '.qti.gz': 'application/x-qtiplot', + '.qtif': 'image/x-quicktime', + '.qtl': 'application/x-quicktime-media-link', + '.qtvr': 'video/quicktime', + '.ra': 'audio/vnd.rn-realaudio', + '.raf': 'image/x-fuji-raf', + '.ram': 'application/ram', + '.rar': 'application/x-rar', + '.ras': 'image/x-cmu-raster', + '.raw': 'image/x-panasonic-raw', + '.rax': 'audio/vnd.rn-realaudio', + '.rb': 'application/x-ruby', + '.rdf': 'application/rdf+xml', + '.rdfs': 'application/rdf+xml', + '.reg': 'text/x-ms-regedit', + '.rej': 'text/x-reject', + '.rgb': 'image/x-rgb', + '.rle': 'image/rle', + '.rm': 'application/vnd.rn-realmedia', + '.rmj': 'application/vnd.rn-realmedia', + '.rmm': 'application/vnd.rn-realmedia', + '.rms': 'application/vnd.rn-realmedia', + '.rmvb': 'application/vnd.rn-realmedia', + '.rmx': 'application/vnd.rn-realmedia', + '.rnc': 'application/relax-ng-compact-syntax', + '.rng': 'application/xml', + '.roff': 'text/troff', + '.rp': 'image/vnd.rn-realpix', + '.rpm': 'application/x-rpm', + '.rss': 'application/rss+xml', + '.rt': 'text/vnd.rn-realtext', + '.rtf': 'application/rtf', + '.rtx': 'text/richtext', + '.rv': 'video/vnd.rn-realvideo', + '.rvx': 'video/vnd.rn-realvideo', + '.rw2': 'image/x-panasonic-raw2', + '.s3m': 'audio/x-s3m', + '.sam': 'application/x-amipro', + '.sami': 'application/x-sami', + '.sav': 'application/x-spss-sav', + '.scala': 'text/x-scala', + '.scm': 'text/x-scheme', + '.sda': 'application/vnd.stardivision.draw', + '.sdc': 'application/vnd.stardivision.calc', + '.sdd': 'application/vnd.stardivision.impress', + '.sdp': 'application/sdp', + '.sds': 'application/vnd.stardivision.chart', + '.sdw': 'application/vnd.stardivision.writer', + '.sgf': 'application/x-go-sgf', + '.sgi': 'image/x-sgi', + '.sgl': 'application/vnd.stardivision.writer', + '.sgm': 'text/sgml', + '.sgml': 'text/sgml', + '.sh': 'application/x-shellscript', + '.shape': 'application/x-dia-shape', + '.shar': 'application/x-shar', + '.shn': 'application/x-shorten', + '.siag': 'application/x-siag', + '.sid': 'audio/prs.sid', + '.sik': 'application/x-trash', + '.sis': 'application/vnd.symbian.install', + '.sisx': 'x-epoc/x-sisx-app', + '.sit': 'application/x-stuffit', + '.siv': 'application/sieve', + '.sk': 'image/x-skencil', + '.sk1': 'image/x-skencil', + '.skr': 'application/pgp-keys', + '.sldm': 'application/vnd.ms-powerpoint.slide.macroenabled.12', + '.sldx': 'application/vnd.openxmlformats-officedocument.presentationml.slide', + '.slk': 'text/spreadsheet', + '.smaf': 'application/x-smaf', + '.smc': 'application/x-snes-rom', + '.smd': 'application/vnd.stardivision.mail', + '.smf': 'application/vnd.stardivision.math', + '.smi': 'application/x-sami', + '.smil': 'application/smil', + '.sml': 'application/smil', + '.sms': 'application/x-sms-rom', + '.snd': 'audio/basic', + '.so': 'application/x-sharedlib', + '.spc': 'application/x-pkcs7-certificates', + '.spd': 'application/x-font-speedo', + '.spec': 'text/x-rpm-spec', + '.spl': 'application/x-shockwave-flash', + '.spm': 'application/x-source-rpm', + '.spx': 'audio/x-speex', + '.sql': 'text/x-sql', + '.sr2': 'image/x-sony-sr2', + '.src': 'application/x-wais-source', + '.src.rpm': 'application/x-source-rpm', + '.srf': 'image/x-sony-srf', + '.srt': 'application/x-subrip', + '.ss': 'text/x-scheme', + '.ssa': 'text/x-ssa', + '.stc': 'application/vnd.sun.xml.calc.template', + '.std': 'application/vnd.sun.xml.draw.template', + '.sti': 'application/vnd.sun.xml.impress.template', + '.stm': 'audio/x-stm', + '.stw': 'application/vnd.sun.xml.writer.template', + '.sty': 'text/x-tex', + '.sub': 'text/x-subviewer', + '.sun': 'image/x-sun-raster', + '.sv': 'text/x-svsrc', + '.sv4cpio': 'application/x-sv4cpio', + '.sv4crc': 'application/x-sv4crc', + '.svg': 'image/svg+xml', + '.svgz': 'image/svg+xml-compressed', + '.svh': 'text/x-svhdr', + '.swf': 'application/x-shockwave-flash', + '.swm': 'application/x-ms-wim', + '.sxc': 'application/vnd.sun.xml.calc', + '.sxd': 'application/vnd.sun.xml.draw', + '.sxg': 'application/vnd.sun.xml.writer.global', + '.sxi': 'application/vnd.sun.xml.impress', + '.sxm': 'application/vnd.sun.xml.math', + '.sxw': 'application/vnd.sun.xml.writer', + '.sylk': 'text/spreadsheet', + '.t': 'text/troff', + '.t2t': 'text/x-txt2tags', + '.tar': 'application/x-tar', + '.tar.bz': 'application/x-bzip-compressed-tar', + '.tar.bz2': 'application/x-bzip-compressed-tar', + '.tar.gz': 'application/x-compressed-tar', + '.tar.lrz': 'application/x-lrzip-compressed-tar', + '.tar.lzma': 'application/x-lzma-compressed-tar', + '.tar.lzo': 'application/x-tzo', + '.tar.xz': 'application/x-xz-compressed-tar', + '.tar.z': 'application/x-tarz', + '.taz': 'application/x-tarz', + '.tb2': 'application/x-bzip-compressed-tar', + '.tbz': 'application/x-bzip-compressed-tar', + '.tbz2': 'application/x-bzip-compressed-tar', + '.tcl': 'text/x-tcl', + '.tex': 'text/x-tex', + '.texi': 'text/x-texinfo', + '.texinfo': 'text/x-texinfo', + '.tga': 'image/x-tga', + '.tgz': 'application/x-compressed-tar', + '.theme': 'application/x-theme', + '.themepack': 'application/x-windows-themepack', + '.tif': 'image/tiff', + '.tiff': 'image/tiff', + '.tk': 'text/x-tcl', + '.tlrz': 'application/x-lrzip-compressed-tar', + '.tlz': 'application/x-lzma-compressed-tar', + '.tnef': 'application/vnd.ms-tnef', + '.tnf': 'application/vnd.ms-tnef', + '.toc': 'application/x-cdrdao-toc', + '.torrent': 'application/x-bittorrent', + '.tpic': 'image/x-tga', + '.tr': 'text/troff', + '.ts': 'video/mp2t', + '.tsv': 'text/tab-separated-values', + '.tta': 'audio/x-tta', + '.ttc': 'application/x-font-ttf', + '.ttf': 'application/x-font-ttf', + '.ttx': 'application/x-font-ttx', + '.txt': 'text/plain', + '.txz': 'application/x-xz-compressed-tar', + '.tzo': 'application/x-tzo', + '.ufraw': 'application/x-ufraw', + '.ui': 'application/x-gtk-builder', + '.uil': 'text/x-uil', + '.ult': 'audio/x-mod', + '.uni': 'audio/x-mod', + '.url': 'application/x-mswinurl', + '.ustar': 'application/x-ustar', + '.uue': 'text/x-uuencode', + '.v': 'text/x-verilog', + '.vala': 'text/x-vala', + '.vapi': 'text/x-vala', + '.vcard': 'text/vcard', + '.vcf': 'text/vcard', + '.vcs': 'text/calendar', + '.vct': 'text/vcard', + '.vda': 'image/x-tga', + '.vhd': 'text/x-vhdl', + '.vhdl': 'text/x-vhdl', + '.viv': 'video/vivo', + '.vivo': 'video/vivo', + '.vlc': 'audio/x-mpegurl', + '.vob': 'video/mpeg', + '.voc': 'audio/x-voc', + '.vor': 'application/vnd.stardivision.writer', + '.vrm': 'model/vrml', + '.vrml': 'model/vrml', + '.vsd': 'application/vnd.visio', + '.vss': 'application/vnd.visio', + '.vst': 'image/x-tga', + '.vsw': 'application/vnd.visio', + '.vtt': 'text/vtt', + '.w2p': 'application/w2p', + '.wav': 'audio/x-wav', + '.wax': 'audio/x-ms-asx', + '.wb1': 'application/x-quattropro', + '.wb2': 'application/x-quattropro', + '.wb3': 'application/x-quattropro', + '.wbmp': 'image/vnd.wap.wbmp', + '.wcm': 'application/vnd.ms-works', + '.wdb': 'application/vnd.ms-works', + '.webm': 'video/webm', + '.wim': 'application/x-ms-wim', + '.wk1': 'application/vnd.lotus-1-2-3', + '.wk3': 'application/vnd.lotus-1-2-3', + '.wk4': 'application/vnd.lotus-1-2-3', + '.wks': 'application/vnd.ms-works', + '.wma': 'audio/x-ms-wma', + '.wmf': 'image/x-wmf', + '.wml': 'text/vnd.wap.wml', + '.wmls': 'text/vnd.wap.wmlscript', + '.wmv': 'video/x-ms-wmv', + '.wmx': 'audio/x-ms-asx', + '.woff': 'application/font-woff', + '.wp': 'application/vnd.wordperfect', + '.wp4': 'application/vnd.wordperfect', + '.wp5': 'application/vnd.wordperfect', + '.wp6': 'application/vnd.wordperfect', + '.wpd': 'application/vnd.wordperfect', + '.wpg': 'application/x-wpg', + '.wpl': 'application/vnd.ms-wpl', + '.wpp': 'application/vnd.wordperfect', + '.wps': 'application/vnd.ms-works', + '.wri': 'application/x-mswrite', + '.wrl': 'model/vrml', + '.wsgi': 'text/x-python', + '.wv': 'audio/x-wavpack', + '.wvc': 'audio/x-wavpack-correction', + '.wvp': 'audio/x-wavpack', + '.wvx': 'audio/x-ms-asx', + '.wwf': 'application/x-wwf', + '.x3f': 'image/x-sigma-x3f', + '.xac': 'application/x-gnucash', + '.xbel': 'application/x-xbel', + '.xbl': 'application/xml', + '.xbm': 'image/x-xbitmap', + '.xcf': 'image/x-xcf', + '.xcf.bz2': 'image/x-compressed-xcf', + '.xcf.gz': 'image/x-compressed-xcf', + '.xhtml': 'application/xhtml+xml', + '.xi': 'audio/x-xi', + '.xla': 'application/vnd.ms-excel', + '.xlam': 'application/vnd.ms-excel.addin.macroenabled.12', + '.xlc': 'application/vnd.ms-excel', + '.xld': 'application/vnd.ms-excel', + '.xlf': 'application/x-xliff', + '.xliff': 'application/x-xliff', + '.xll': 'application/vnd.ms-excel', + '.xlm': 'application/vnd.ms-excel', + '.xlr': 'application/vnd.ms-works', + '.xls': 'application/vnd.ms-excel', + '.xlsb': 'application/vnd.ms-excel.sheet.binary.macroenabled.12', + '.xlsm': 'application/vnd.ms-excel.sheet.macroenabled.12', + '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + '.xlt': 'application/vnd.ms-excel', + '.xltm': 'application/vnd.ms-excel.template.macroenabled.12', + '.xltx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + '.xlw': 'application/vnd.ms-excel', + '.xm': 'audio/x-xm', + '.xmf': 'audio/x-xmf', + '.xmi': 'text/x-xmi', + '.xml': 'application/xml', + '.xpi': 'application/x-xpinstall', + '.xpm': 'image/x-xpixmap', + '.xps': 'application/oxps', + '.xsd': 'application/xml', + '.xsl': 'application/xslt+xml', + '.xslfo': 'text/x-xslfo', + '.xslm': 'application/vnd.ms-excel.sheet.macroEnabled.12', + '.xslt': 'application/xslt+xml', + '.xspf': 'application/xspf+xml', + '.xul': 'application/vnd.mozilla.xul+xml', + '.xwd': 'image/x-xwindowdump', + '.xyz': 'chemical/x-pdb', + '.xz': 'application/x-xz', + '.yaml': 'application/x-yaml', + '.yml': 'application/x-yaml', + '.z': 'application/x-compress', + '.zabw': 'application/x-abiword', + '.zip': 'application/zip', + '.zoo': 'application/x-zoo', +} + + +def contenttype(filename, default='text/plain'): + """ + Returns the Content-Type string matching extension of the given filename. + """ + filename = to_native(filename) + i = filename.rfind('.') + if i >= 0: + default = CONTENT_TYPE.get(filename[i:].lower(), default) + j = filename.rfind('.', 0, i) + if j >= 0: + default = CONTENT_TYPE.get(filename[j:].lower(), default) + if default.startswith('text/'): + default += '; charset=utf-8' + return default diff --git a/web2py/gluon/contrib/AuthorizeNet.py b/web2py/gluon/contrib/AuthorizeNet.py new file mode 100644 index 0000000..705db6f --- /dev/null +++ b/web2py/gluon/contrib/AuthorizeNet.py @@ -0,0 +1,271 @@ +""" +AIM class to credit card payment with authorize.net + +Fork of authnet code written by John Conde +http://www.johnconde.net/blog/integrate-the-authorizenet-aim-api-with-python-3-2/ +BSDv3 License + +Modifed by Massimo Di Pierro + +- ported from Python 3.x run on Python 2.4+ +- fixed a couple of bugs +- merged with test so single file +- namedtuple from http://code.activestate.com/recipes/500261/ + +""" +from __future__ import print_function + +__all__ = ['AIM'] + +from operator import itemgetter +from gluon._compat import urlopen, urlencode, FancyURLopener + +_known_tuple_types = {} + + +class NamedTupleBase(tuple): + """Base class for named tuples with the __new__ operator set, named tuples + yielded by the namedtuple() function will subclass this and add + properties.""" + def __new__(cls, *args, **kws): + """Create a new instance of this fielded tuple""" + # May need to unpack named field values here + if kws: + values = list(args) + [None] * (len(cls._fields) - len(args)) + fields = dict((val, idx) for idx, val in enumerate(cls._fields)) + for kw, val in kws.iteritems(): + assert kw in kws, "%r not in field list" % kw + values[fields[kw]] = val + args = tuple(values) + return tuple.__new__(cls, args) + + +def namedtuple(typename, fieldnames): + """ + >>> import namedtuples + >>> tpl = namedtuples.namedtuple(['a', 'b', 'c']) + >>> tpl(1, 2, 3) + (1, 2, 3) + >>> tpl(1, 2, 3).b + 2 + >>> tpl(c=1, a=2, b=3) + (2, 3, 1) + >>> tpl(c=1, a=2, b=3).b + 3 + >>> tpl(c='pads with nones') + (None, None, 'pads with nones') + >>> tpl(b='pads with nones') + (None, 'pads with nones', None) + >>> + """ + # Split up a string, some people do this + if isinstance(fieldnames, basestring): + fieldnames = fieldnames.replace(',', ' ').split() + # Convert anything iterable that enumerates fields to a tuple now + fieldname_tuple = tuple(str(field) for field in fieldnames) + # See if we've cached this + if fieldname_tuple in _known_tuple_types: + return _known_tuple_types[fieldname_tuple] + # Make the type + new_tuple_type = type(typename, (NamedTupleBase,), {}) + # Set the hidden field + new_tuple_type._fields = fieldname_tuple + # Add the getters + for i, field in enumerate(fieldname_tuple): + setattr(new_tuple_type, field, property(itemgetter(i))) + # Cache + _known_tuple_types[fieldname_tuple] = new_tuple_type + # Done + return new_tuple_type + + +class AIM: + + class AIMError(Exception): + def __init__(self, value): + self.parameter = value + + def __str__(self): + return str(self.parameter) + + def __init__(self, login, transkey, testmode=False): + if str(login).strip() == '' or login is None: + raise AIM.AIMError('No login name provided') + if str(transkey).strip() == '' or transkey is None: + raise AIM.AIMError('No transaction key provided') + if testmode != True and testmode != False: + raise AIM.AIMError('Invalid value for testmode. Must be True or False. "{0}" given.'.format(testmode)) + + self.testmode = testmode + self.proxy = None + self.delimiter = '|' + self.results = [] + self.error = True + self.success = False + self.declined = False + + self.parameters = {} + self.setParameter('x_delim_data', 'true') + self.setParameter('x_delim_char', self.delimiter) + self.setParameter('x_relay_response', 'FALSE') + self.setParameter('x_url', 'FALSE') + self.setParameter('x_version', '3.1') + self.setParameter('x_method', 'CC') + self.setParameter('x_type', 'AUTH_CAPTURE') + self.setParameter('x_login', login) + self.setParameter('x_tran_key', transkey) + + def process(self): + encoded_args = urlencode(self.parameters) + if self.testmode == True: + url = 'https://test.authorize.net/gateway/transact.dll' + else: + url = 'https://secure.authorize.net/gateway/transact.dll' + + if self.proxy is None: + self.results += str(urlopen( + url, encoded_args).read()).split(self.delimiter) + else: + opener = FancyURLopener(self.proxy) + opened = opener.open(url, encoded_args) + try: + self.results += str(opened.read()).split(self.delimiter) + finally: + opened.close() + Results = namedtuple('Results', 'ResultResponse ResponseSubcode ResponseCode ResponseText AuthCode \ + AVSResponse TransactionID InvoiceNumber Description Amount PaymentMethod \ + TransactionType CustomerID CHFirstName CHLastName Company BillingAddress \ + BillingCity BillingState BillingZip BillingCountry Phone Fax Email ShippingFirstName \ + ShippingLastName ShippingCompany ShippingAddress ShippingCity ShippingState \ + ShippingZip ShippingCountry TaxAmount DutyAmount FreightAmount TaxExemptFlag \ + PONumber MD5Hash CVVResponse CAVVResponse') + self.response = Results(*tuple(r for r in self.results)[0:40]) + + if self.getResultResponseFull() == 'Approved': + self.error = False + self.success = True + self.declined = False + elif self.getResultResponseFull() == 'Declined': + self.error = False + self.success = False + self.declined = True + else: + raise AIM.AIMError(self.response.ResponseText) + + def setTransaction(self, creditcard, expiration, total, cvv=None, tax=None, invoice=None): + if str(creditcard).strip() == '' or creditcard is None: + raise AIM.AIMError('No credit card number passed to setTransaction(): {0}'.format(creditcard)) + if str(expiration).strip() == '' or expiration is None: + raise AIM.AIMError('No expiration number to setTransaction(): {0}'.format(expiration)) + if str(total).strip() == '' or total is None: + raise AIM.AIMError('No total amount passed to setTransaction(): {0}'.format(total)) + + self.setParameter('x_card_num', creditcard) + self.setParameter('x_exp_date', expiration) + self.setParameter('x_amount', total) + if cvv is not None: + self.setParameter('x_card_code', cvv) + if tax is not None: + self.setParameter('x_tax', tax) + if invoice is not None: + self.setParameter('x_invoice_num', invoice) + + def setTransactionType(self, transtype=None): + types = ['AUTH_CAPTURE', 'AUTH_ONLY', 'PRIOR_AUTH_CAPTURE', + 'CREDIT', 'CAPTURE_ONLY', 'VOID'] + if transtype.upper() not in types: + raise AIM.AIMError('Incorrect Transaction Type passed to setTransactionType(): {0}'.format(transtype)) + self.setParameter('x_type', transtype.upper()) + + def setProxy(self, proxy=None): + if str(proxy).strip() == '' or proxy is None: + raise AIM.AIMError('No proxy passed to setProxy()') + self.proxy = {'http': str(proxy).strip()} + + def setParameter(self, key=None, value=None): + if key is not None and value is not None and str(key).strip() != '' and str(value).strip() != '': + self.parameters[key] = str(value).strip() + else: + raise AIM.AIMError('Incorrect parameters passed to setParameter(): {0}:{1}'.format(key, value)) + + def isApproved(self): + return self.success + + def isDeclined(self): + return self.declined + + def isError(self): + return self.error + + def getResultResponseFull(self): + responses = ['', 'Approved', 'Declined', 'Error'] + return responses[int(self.results[0])] + + +def process(creditcard, expiration, total, cvv=None, tax=None, invoice=None, + login='cnpdev4289', transkey='SR2P8g4jdEn7vFLQ', testmode=True): + payment = AIM(login, transkey, testmode) + expiration = expiration.replace('/', '') + payment.setTransaction(creditcard, expiration, total, cvv, tax, invoice) + try: + payment.process() + return payment.isApproved() + except AIM.AIMError: + return False + + +def test(): + import socket + import sys + from time import time + + creditcard = '4427802641004797' + expiration = '122012' + total = '1.00' + cvv = '123' + tax = '0.00' + invoice = str(time())[4:10] # get a random invoice number + + try: + payment = AIM('cnpdev4289', 'SR2P8g4jdEn7vFLQ', True) + payment.setTransaction( + creditcard, expiration, total, cvv, tax, invoice) + payment.setParameter( + 'x_duplicate_window', 180) # three minutes duplicate windows + payment.setParameter('x_cust_id', '1324') # customer ID + payment.setParameter('x_first_name', 'John') + payment.setParameter('x_last_name', 'Conde') + payment.setParameter('x_company', 'Test Company') + payment.setParameter('x_address', '1234 Main Street') + payment.setParameter('x_city', 'Townsville') + payment.setParameter('x_state', 'NJ') + payment.setParameter('x_zip', '12345') + payment.setParameter('x_country', 'US') + payment.setParameter('x_phone', '800-555-1234') + payment.setParameter('x_description', 'Test Transaction') + payment.setParameter( + 'x_customer_ip', socket.gethostbyname(socket.gethostname())) + payment.setParameter('x_email', 'john@example.com') + payment.setParameter('x_email_customer', False) + payment.process() + if payment.isApproved(): + print('Response Code: ', payment.response.ResponseCode) + print('Response Text: ', payment.response.ResponseText) + print('Response: ', payment.getResultResponseFull()) + print('Transaction ID: ', payment.response.TransactionID) + print('CVV Result: ', payment.response.CVVResponse) + print('Approval Code: ', payment.response.AuthCode) + print('AVS Result: ', payment.response.AVSResponse) + elif payment.isDeclined(): + print('Your credit card was declined by your bank') + elif payment.isError(): + raise AIM.AIMError('An uncaught error occurred') + except AIM.AIMError as e: + print("Exception thrown:", e) + print('An error occured') + print('approved', payment.isApproved()) + print('declined', payment.isDeclined()) + print('error', payment.isError()) + +if __name__ == '__main__': + test() diff --git a/web2py/gluon/contrib/DowCommerce.py b/web2py/gluon/contrib/DowCommerce.py new file mode 100644 index 0000000..f900c6b --- /dev/null +++ b/web2py/gluon/contrib/DowCommerce.py @@ -0,0 +1,245 @@ +""" +DowCommerce class to process credit card payments with DowCommerce.com + +Modifications to support Dow Commerce API from code originally written by John Conde +http://www.johnconde.net/blog/integrate-the-authorizenet-aim-api-with-python-3-2/ +BSDv3 License + +Modifed by Dave Stoll dave.stoll@gmail.com + +- modifed to support Dow Commerce API +""" +from __future__ import print_function + +__all__ = ['DowCommerce'] + +from operator import itemgetter +from gluon._compat import urlopen, urlencode, FancyURLopene + + +class DowCommerce: + + class DowCommerceError(Exception): + def __init__(self, value): + self.parameter = value + + def __str__(self): + return str(self.parameter) + + def __init__(self, username=None, password=None, demomode=False): + if not demomode: + if str(username).strip() == '' or username is None: + raise DowCommerce.DowCommerceError('No username provided') + if str(password).strip() == '' or password is None: + raise DowCommerce.DowCommerceError('No password provided') + else: + username = 'demo' + password = 'password' + + self.proxy = None + self.delimiter = '&' + self.results = {} + self.error = True + self.success = False + self.declined = False + self.url = 'https://secure.dowcommerce.net/api/transact.php' + + self.parameters = {} + self.setParameter('username', username) + self.setParameter('password', password) + + def process(self): + encoded_args = urlencode(self.parameters) + if self.proxy is None: + results = str(urlopen( + self.url, encoded_args).read()).split(self.delimiter) + else: + opener = FancyURLopener(self.proxy) + opened = opener.open(self.url, encoded_args) + try: + results = str(opened.read()).split(self.delimiter) + finally: + opened.close() + + for result in results: + (key, val) = result.split('=') + self.results[key] = val + + if self.results['response'] == '1': + self.error = False + self.success = True + self.declined = False + elif self.results['response'] == '2': + self.error = False + self.success = False + self.declined = True + elif self.results['response'] == '3': + self.error = True + self.success = False + self.declined = False + else: + self.error = True + self.success = False + self.declined = False + raise DowCommerce.DowCommerceError(self.results) + + def setTransaction( + self, creditcard, expiration, total, cvv=None, orderid=None, orderdescription=None, + ipaddress=None, tax=None, shipping=None, + firstname=None, lastname=None, company=None, address1=None, address2=None, city=None, state=None, zipcode=None, + country=None, phone=None, fax=None, emailaddress=None, website=None, + shipping_firstname=None, shipping_lastname=None, shipping_company=None, shipping_address1=None, shipping_address2=None, + shipping_city=None, shipping_state=None, shipping_zipcode=None, shipping_country=None, shipping_emailaddress=None): + if str(creditcard).strip() == '' or creditcard is None: + raise DowCommerce.DowCommerceError('No credit card number passed to setTransaction(): {0}'.format(creditcard)) + if str(expiration).strip() == '' or expiration is None: + raise DowCommerce.DowCommerceError('No expiration number passed to setTransaction(): {0}'.format(expiration)) + if str(total).strip() == '' or total is None: + raise DowCommerce.DowCommerceError('No total amount passed to setTransaction(): {0}'.format(total)) + + self.setParameter('ccnumber', creditcard) + self.setParameter('ccexp', expiration) + self.setParameter('amount', total) + + if cvv: + self.setParameter('cvv', cvv) + if orderid: + self.setParameter('orderid', orderid) + if orderdescription: + self.setParameter('orderdescription', orderdescription) + if ipaddress: + self.setParameter('ipaddress', ipaddress) + if tax: + self.setParameter('tax', tax) + if shipping: + self.setParameter('shipping', shipping) + + ## billing info + if firstname: + self.setParameter('firstname', firstname) + if lastname: + self.setParameter('lastname', lastname) + if company: + self.setParameter('company', company) + if address1: + self.setParameter('address1', address1) + if address2: + self.setParameter('address2', address2) + if city: + self.setParameter('city', city) + if state: + self.setParameter('state', state) + if zipcode: + self.setParameter('zip', zipcode) + if country: + self.setParameter('country', country) + if phone: + self.setParameter('phone', phone) + if fax: + self.setParameter('fax', fax) + if emailaddress: + self.setParameter('email', emailaddress) + if website: + self.setParameter('website', website) + + ## shipping info + if shipping_firstname: + self.setParameter('shipping_firstname', shipping_firstname) + if shipping_lastname: + self.setParameter('shipping_lastname', shipping_lastname) + if shipping_company: + self.setParameter('shipping_company', shipping_company) + if shipping_address1: + self.setParameter('shipping_address1', shipping_address1) + if shipping_address2: + self.setParameter('shipping_address2', shipping_address2) + if shipping_city: + self.setParameter('shipping_city', shipping_city) + if shipping_state: + self.setParameter('shipping_state', shipping_state) + if shipping_zipcode: + self.setParameter('shipping_zip', shipping_zipcode) + if shipping_country: + self.setParameter('shipping_country', shipping_country) + + def setTransactionType(self, transtype=None): + types = ['sale', 'auth', 'credit'] + if transtype.lower() not in types: + raise DowCommerce.DowCommerceError('Incorrect Transaction Type passed to setTransactionType(): {0}'.format(transtype)) + self.setParameter('type', transtype.lower()) + + def setProxy(self, proxy=None): + if str(proxy).strip() == '' or proxy is None: + raise DowCommerce.DowCommerceError('No proxy passed to setProxy()') + self.proxy = {'http': str(proxy).strip()} + + def setParameter(self, key=None, value=None): + if key is not None and value is not None and str(key).strip() != '' and str(value).strip() != '': + self.parameters[key] = str(value).strip() + else: + raise DowCommerce.DowCommerceError('Incorrect parameters passed to setParameter(): {0}:{1}'.format(key, value)) + + def isApproved(self): + return self.success + + def isDeclined(self): + return self.declined + + def isError(self): + return self.error + + def getResultResponseShort(self): + responses = ['', 'Approved', 'Declined', 'Error'] + return responses[int(self.results['response'])] + + def getFullResponse(self): + return self.results + + def getResponseText(self): + return self.results['responsetext'] + + +def test(): + import socket + import sys + from time import time + + ## TEST VALUES FROM API DOC: + # Visa: 4111111111111111 + # MasterCard 5431111111111111 + # DiscoverCard: 6011601160116611 + # American Express: 341111111111111 + # Expiration: 10/10 + # Amount: > 1.00 (( passing less than $1.00 will cause it to be declined )) + # CVV: 999 + creditcard = '4111111111111111' + expiration = '1010' + total = '1.00' + cvv = '999' + tax = '0.00' + orderid = str(time())[4:10] # get a random invoice number + + try: + payment = DowCommerce(demomode=True) + payment.setTransaction( + creditcard, expiration, total, cvv=cvv, tax=tax, orderid=orderid, orderdescription='Test Transaction', + firstname='John', lastname='Doe', company='Acme', address1='123 Min Street', city='Hometown', state='VA', + zipcode='12345', country='US', phone='888-555-1212', emailaddress='john@noemail.local', ipaddress='192.168.1.1') + + payment.process() + if payment.isApproved(): + print('Payment approved!') + print(payment.getFullResponse()) + elif payment.isDeclined(): + print('Your credit card was declined by your bank') + elif payment.isError(): + raise DowCommerce.DowCommerceError('An uncaught error occurred') + except DowCommerce.DowCommerceError as e: + print("Exception thrown:", e) + print('An error occured') + print('approved', payment.isApproved()) + print('declined', payment.isDeclined()) + print('error', payment.isError()) + +if __name__ == '__main__': + test() diff --git a/web2py/gluon/contrib/__init__.py b/web2py/gluon/contrib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web2py/gluon/contrib/appconfig.py b/web2py/gluon/contrib/appconfig.py new file mode 100644 index 0000000..1160e08 --- /dev/null +++ b/web2py/gluon/contrib/appconfig.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Read from configuration files easily without hurting performances + +USAGE: +During development you can load a config file either in .ini or .json +format (by default app/private/appconfig.ini or app/private/appconfig.json) +The result is a dict holding the configured values. Passing reload=True +is meant only for development: in production, leave reload to False and all +values will be cached + +from gluon.contrib.appconfig import AppConfig +myconfig = AppConfig(path_to_configfile, reload=False) + +print myconfig['db']['uri'] + +The returned dict can walk with "dot notation" an arbitrarely nested dict + +print myconfig.take('db.uri') + +You can even pass a cast function, i.e. + +print myconfig.take('auth.expiration', cast=int) + +Once the value has been fetched (and casted) it won't change until the process +is restarted (or reload=True is passed). + +""" +import os +import json +from gluon._compat import thread, configparser +from gluon.globals import current + +locker = thread.allocate_lock() + +def AppConfig(*args, **vars): + + locker.acquire() + reload_ = vars.pop('reload', False) + try: + instance_name = 'AppConfig_' + current.request.application + if reload_ or not hasattr(AppConfig, instance_name): + setattr(AppConfig, instance_name, AppConfigLoader(*args, **vars)) + return getattr(AppConfig, instance_name).settings + finally: + locker.release() + + +class AppConfigDict(dict): + """ + dict that has a .take() method to fetch nested values and puts + them into cache + """ + + def __init__(self, *args, **kwargs): + dict.__init__(self, *args, **kwargs) + self.int_cache = {} + + def get(self, path, default=None): + try: + value = self.take(path).strip() + if value.lower() in ('none','null',''): + return None + elif value.lower() == 'true': + return True + elif value.lower() == 'false': + return False + elif value.isdigit() or (value[0]=='-' and value[1:].isdigit()): + return int(value) + elif ',' in value: + return map(lambda x:x.strip(),value.split(',')) + else: + try: + return float(value) + except: + return value + except: + return default + + def take(self, path, cast=None): + parts = path.split('.') + if path in self.int_cache: + return self.int_cache[path] + value = self + walking = [] + for part in parts: + if part not in value: + raise BaseException("%s not in config [%s]" % + (part, '-->'.join(walking))) + value = value[part] + walking.append(part) + if cast is None: + self.int_cache[path] = value + else: + try: + value = cast(value) + self.int_cache[path] = value + except (ValueError, TypeError): + raise BaseException("%s can't be converted to %s" % + (value, cast)) + return value + + +class AppConfigLoader(object): + + def __init__(self, configfile=None): + if not configfile: + priv_folder = os.path.join(current.request.folder, 'private') + configfile = os.path.join(priv_folder, 'appconfig.ini') + if not os.path.isfile(configfile): + configfile = os.path.join(priv_folder, 'appconfig.json') + if not os.path.isfile(configfile): + configfile = None + if not configfile or not os.path.isfile(configfile): + raise BaseException("Config file not found") + self.file = configfile + self.ctype = os.path.splitext(configfile)[1][1:] + self.settings = None + self.read_config() + + def read_config_ini(self): + config = configparser.SafeConfigParser() + config.read(self.file) + settings = {} + for section in config.sections(): + settings[section] = {} + for option in config.options(section): + settings[section][option] = config.get(section, option) + self.settings = AppConfigDict(settings) + + def read_config_json(self): + with open(self.file, 'r') as c: + self.settings = AppConfigDict(json.load(c)) + + def read_config(self): + if self.settings is None: + try: + getattr(self, 'read_config_' + self.ctype)() + except AttributeError: + raise BaseException("Unsupported config file format") + return self.settings diff --git a/web2py/gluon/contrib/autolinks.py b/web2py/gluon/contrib/autolinks.py new file mode 100644 index 0000000..4670c30 --- /dev/null +++ b/web2py/gluon/contrib/autolinks.py @@ -0,0 +1,222 @@ +""" +Developed by Massimo Di Pierro +Released under the web2py license (LGPL) + +What does it do? + +if html is a variable containing HTML text and urls in the text, when you call + + html = expend_html(html) + +it automatically converts the url to links but when possible it embeds the object being linked. +In particular it can embed images, videos, audio files, documents (it uses the google code player), +as well as pages to a oembed service. + + +Google Doc Support +================== +Microsoft Word (.DOC, .DOCX) +Microsoft Excel (.XLS and .XLSX) +Microsoft PowerPoint 2007 / 2010 (.PPTX) +Apple Pages (.PAGES) +Adobe PDF (.PDF) +Adobe Illustrator (.AI) +Adobe Photoshop (.PSD) +Autodesk AutoCad (.DXF) +Scalable Vector Graphics (.SVG) +PostScript (.EPS, .PS) +TrueType (.TTF) +XML Paper Specification (.XPS) + +Oembed Support +============== +flickr.com +youtube.com +hulu.com +vimeo.com +slideshare.net +qik.com +polleverywhere.com +wordpress.com +revision3.com +viddler.com +""" +from __future__ import print_function +from gluon._compat import FancyURLopener, urllib_quote + +import re +import cgi +import sys +from json import loads +import urllib +import uuid +try: + from BeautifulSoup import BeautifulSoup, Comment + have_soup = True +except ImportError: + have_soup = False + +regex_link = re.compile('https?://\S+') + +EMBED_MAPS = [ + (re.compile('http://\S*?flickr.com/\S*'), + 'http://www.flickr.com/services/oembed/'), + (re.compile('http://\S*.youtu(\.be|be\.com)/watch\S*'), + 'http://www.youtube.com/oembed'), + (re.compile('http://www.hulu.com/watch/\S*'), + 'http://www.hulu.com/api/oembed.json'), + (re.compile('http://vimeo.com/\S*'), + 'http://vimeo.com/api/oembed.json'), + (re.compile('http://www.slideshare.net/[^\/]+/\S*'), + 'http://www.slideshare.net/api/oembed/2'), + (re.compile('http://qik.com/\S*'), + 'http://qik.com/api/oembed.json'), + (re.compile('http://www.polleverywhere.com/\w+/\S+'), + 'http://www.polleverywhere.com/services/oembed/'), + (re.compile('http://\S+.wordpress.com/\S+'), + 'http://public-api.wordpress.com/oembed/'), + (re.compile('http://*.revision3.com/\S+'), + 'http://revision3.com/api/oembed/'), + (re.compile('http://\S+.viddler.com/\S+'), + 'http://lab.viddler.com/services/oembed/'), +] + + +def image(url): + return '' % url + + +def audio(url): + return '' % url + + +def video(url): + return '' % url + + +def googledoc_viewer(url): + return '' % urllib_quote(url) + + +def web2py_component(url): + code = str(uuid.uuid4()) + return '
    ' % (code, url, code) + +EXTENSION_MAPS = { + 'png': image, + 'gif': image, + 'jpg': image, + 'jpeg': image, + 'wav': audio, + 'ogg': audio, + 'mp3': audio, + 'mov': video, + 'mpe': video, + 'mp4': video, + 'mpg': video, + 'mpg2': video, + 'mpeg': video, + 'mpeg4': video, + 'movie': video, + 'wmv': video, + 'load': web2py_component, + 'pdf': googledoc_viewer, + 'doc': googledoc_viewer, + 'docx': googledoc_viewer, + 'ppt': googledoc_viewer, + 'pptx': googledoc_viewer, + 'xls': googledoc_viewer, + 'xlsx': googledoc_viewer, + 'pages': googledoc_viewer, + 'ai': googledoc_viewer, + 'psd': googledoc_viewer, + 'xdf': googledoc_viewer, + 'svg': googledoc_viewer, + 'ttf': googledoc_viewer, + 'xps': googledoc_viewer, +} + + +class VimeoURLOpener(FancyURLopener): + "Vimeo blocks the urllib user agent for some reason" + version = "Mozilla/4.0" +urllib._urlopener = VimeoURLOpener() + + +def oembed(url): + for k, v in EMBED_MAPS: + if k.match(url): + oembed = v + '?format=json&url=' + cgi.escape(url) + try: + data = urllib.urlopen(oembed).read() + return loads(data) # json! + except: + pass + return {} + + +def extension(url): + return url.split('?')[0].split('.')[-1].lower() + + +def expand_one(url, cdict): + # try ombed but first check in cache + if '@' in url and not '://'in url: + return '%s' % (url, url) + if cdict and url in cdict: + r = cdict[url] + else: + r = oembed(url) + if isinstance(cdict, dict): + cdict[url] = r + # if oembed service + if 'html' in r: + html = r['html'].encode('utf8') + if html.startswith('%s' % html + else: + return html + elif 'url' in r: + url = r['url'].encode('utf8') + # embed images, video, audio files + ext = extension(url) + if ext in EXTENSION_MAPS: + return EXTENSION_MAPS[ext](url) + # else regular link + return '%(u)s' % dict(u=url) + + +def expand_html(html, cdict=None): + if not have_soup: + raise RuntimeError("Missing BeautifulSoup") + soup = BeautifulSoup(html) + comments = soup.findAll(text=lambda text: isinstance(text, Comment)) + [comment.extract() for comment in comments] + for txt in soup.findAll(text=True): + if not txt.parent.name in ('a', 'script', 'pre', 'code', 'embed', 'object', 'audio', 'video'): + ntxt = regex_link.sub( + lambda match: expand_one(match.group(0), cdict), txt) + txt.replaceWith(BeautifulSoup(ntxt)) + return str(soup) + + +def test(): + example = """ +

    Fringilla nisi parturient nullam

    +

    http://www.youtube.com/watch?v=IWBFiI5RrA0

    +

    http://www.web2py.com/examples/static/images/logo_bw.png

    +

    http://www.web2py.com/examples/default/index.load

    +

    http://www.web2py.com/examples/static/web2py_manual_cutl.pdf

    +

    Elementum sodales est varius magna leo sociis erat. Nascetur pretium non +ultricies gravida. Condimentum at nascetur tempus. Porttitor viverra ipsum +accumsan neque aliquet. Ultrices vestibulum tempor quisque eget sem eget. +Ornare malesuada tempus dolor dolor magna consectetur. Nisl dui non curabitur +laoreet tortor.

    +""" + return expand_html(example) + +if __name__ == "__main__": + if len(sys.argv) > 1: + print(expand_html(open(sys.argv[1]).read())) + else: + print(test()) diff --git a/web2py/gluon/contrib/dbg.py b/web2py/gluon/contrib/dbg.py new file mode 100644 index 0000000..0dcbcf1 --- /dev/null +++ b/web2py/gluon/contrib/dbg.py @@ -0,0 +1,1121 @@ +#!/usr/bin/env python3 +# coding:utf-8 + +"Queues(Pipe)-based independent remote client-server Python Debugger (new-py3)" + +from __future__ import print_function + +__author__ = "Mariano Reingart (reingart@gmail.com)" +__copyright__ = "Copyright (C) 2011 Mariano Reingart" +__license__ = "LGPL 3.0" +__version__ = "1.5.2" + +# remote debugger queue-based (jsonrpc-like interface): +# - bidirectional communication (request - response calls in both ways) +# - request with id == null is a notification (do not send a response) +# - request with a value for id is a normal call, wait response +# based on idle, inspired by pythonwin implementation, taken many code from pdb + +import bdb +import inspect +import linecache +import os +import sys +import traceback +import cmd +import pydoc +import threading +import collections + + +# Speed Ups: global variables +breaks = [] + + +class Qdb(bdb.Bdb): + "Qdb Debugger Backend" + + def __init__(self, pipe, redirect_stdio=True, allow_interruptions=False, + use_speedups=True, skip=[__name__]): + global breaks + kwargs = {} + if sys.version_info > (2, 7): + kwargs['skip'] = skip + bdb.Bdb.__init__(self, **kwargs) + self.frame = None + self.i = 1 # sequential RPC call id + self.waiting = False + self.pipe = pipe # for communication + self._wait_for_mainpyfile = False + self._wait_for_breakpoint = False + self.mainpyfile = "" + self._lineno = None # last listed line numbre + # ignore filenames (avoid spurious interaction specially on py2) + self.ignore_files = [self.canonic(f) for f in (__file__, bdb.__file__)] + # replace system standard input and output (send them thru the pipe) + self.old_stdio = sys.stdin, sys.stdout, sys.stderr + if redirect_stdio: + sys.stdin = self + sys.stdout = self + sys.stderr = self + if allow_interruptions: + # fake breakpoint to prevent removing trace_dispatch on set_continue + self.breaks[None] = [] + self.allow_interruptions = allow_interruptions + self.burst = 0 # do not send notifications ("burst" mode) + self.params = {} # optional parameters for interaction + + # flags to reduce overhead (only stop at breakpoint or interrupt) + self.use_speedups = use_speedups + self.fast_continue = False + + def pull_actions(self): + # receive a remote procedure call from the frontend: + # returns True if action processed + # None when 'run' notification is received (see 'startup') + request = self.pipe.recv() + if request.get("method") == 'run': + return None + response = {'version': '1.1', 'id': request.get('id'), + 'result': None, + 'error': None} + try: + # dispatch message (JSON RPC like) + method = getattr(self, request['method']) + response['result'] = method.__call__(*request['args'], + **request.get('kwargs', {})) + except Exception as e: + response['error'] = {'code': 0, 'message': str(e)} + # send the result for normal method calls, not for notifications + if request.get('id'): + self.pipe.send(response) + return True + + # Override Bdb methods + + def trace_dispatch(self, frame, event, arg): + # check for non-interaction rpc (set_breakpoint, interrupt) + while self.allow_interruptions and self.pipe.poll(): + self.pull_actions() + # check for non-interaction rpc (set_breakpoint, interrupt) + while self.pipe.poll(): + self.pull_actions() + if (frame.f_code.co_filename, frame.f_lineno) not in breaks and \ + self.fast_continue: + return self.trace_dispatch + # process the frame (see Bdb.trace_dispatch) + ##if self.fast_continue: + ## return self.trace_dispatch + if self.quitting: + return # None + if event == 'line': + return self.dispatch_line(frame) + if event == 'call': + return self.dispatch_call(frame, arg) + if event == 'return': + return self.dispatch_return(frame, arg) + if event == 'exception': + return self.dispatch_exception(frame, arg) + return self.trace_dispatch + + def user_call(self, frame, argument_list): + """This method is called when there is the remote possibility + that we ever need to stop in this function.""" + if self._wait_for_mainpyfile or self._wait_for_breakpoint: + return + if self.stop_here(frame): + self.interaction(frame) + + def user_line(self, frame): + """This function is called when we stop or break at this line.""" + if self._wait_for_mainpyfile: + if (not self.canonic(frame.f_code.co_filename).startswith(self.mainpyfile) + or frame.f_lineno<= 0): + return + self._wait_for_mainpyfile = 0 + if self._wait_for_breakpoint: + if not self.break_here(frame): + return + self._wait_for_breakpoint = 0 + self.interaction(frame) + + def user_exception(self, frame, info): + """This function is called if an exception occurs, + but only if we are to stop at or just below this level.""" + if self._wait_for_mainpyfile or self._wait_for_breakpoint: + return + extype, exvalue, trace = info + # pre-process stack trace as it isn't pickeable (cannot be sent pure) + msg = ''.join(traceback.format_exception(extype, exvalue, trace)) + # in python3.5, convert FrameSummary to tuples (py2.7+ compatibility) + tb = [tuple(fs) for fs in traceback.extract_tb(trace)] + title = traceback.format_exception_only(extype, exvalue)[0] + # send an Exception notification + msg = {'method': 'exception', + 'args': (title, extype.__name__, repr(exvalue), tb, msg), + 'id': None} + self.pipe.send(msg) + self.interaction(frame) + + def run(self, code, interp=None, *args, **kwargs): + try: + return bdb.Bdb.run(self, code, *args, **kwargs) + finally: + pass + + def runcall(self, function, interp=None, *args, **kwargs): + try: + self.interp = interp + return bdb.Bdb.runcall(self, function, *args, **kwargs) + finally: + pass + + def _runscript(self, filename): + # The script has to run in __main__ namespace (clear it) + import __main__ + import imp + filename = os.path.abspath(filename) + __main__.__dict__.clear() + __main__.__dict__.update({"__name__" : "__main__", + "__file__" : filename, + "__builtins__": __builtins__, + "imp" : imp, # need for run + }) + + # avoid stopping before we reach the main script + self._wait_for_mainpyfile = 1 + self.mainpyfile = self.canonic(filename) + self._user_requested_quit = 0 + if sys.version_info>(3,0): + statement = 'imp.load_source("__main__", "%s")' % filename + else: + statement = 'execfile(%r)' % filename + self.startup() + self.run(statement) + + def startup(self): + "Notify and wait frontend to set initial params and breakpoints" + # send some useful info to identify session + thread = threading.current_thread() + # get the caller module filename + frame = sys._getframe() + fn = self.canonic(frame.f_code.co_filename) + while frame.f_back and self.canonic(frame.f_code.co_filename) == fn: + frame = frame.f_back + args = [__version__, os.getpid(), thread.name, " ".join(sys.argv), + frame.f_code.co_filename] + self.pipe.send({'method': 'startup', 'args': args}) + while self.pull_actions() is not None: + pass + + # General interaction function + + def interaction(self, frame): + # chache frame locals to ensure that modifications are not overwritten + self.frame_locals = frame and frame.f_locals or {} + # extract current filename and line number + code, lineno = frame.f_code, frame.f_lineno + filename = self.canonic(code.co_filename) + basename = os.path.basename(filename) + # check if interaction should be ignored (i.e. debug modules internals) + if filename in self.ignore_files: + return + message = "%s:%s" % (basename, lineno) + if code.co_name != "?": + message = "%s: %s()" % (message, code.co_name) + + # wait user events + self.waiting = True + self.frame = frame + try: + while self.waiting: + # sync_source_line() + if frame and filename[:1] + filename[-1:] != "<>" and os.path.exists(filename): + line = linecache.getline(filename, self.frame.f_lineno, + self.frame.f_globals) + else: + line = "" + # send the notification (debug event) - DOESN'T WAIT RESPONSE + self.burst -= 1 + if self.burst < 0: + kwargs = {} + if self.params.get('call_stack'): + kwargs['call_stack'] = self.do_where() + if self.params.get('environment'): + kwargs['environment'] = self.do_environment() + self.pipe.send({'method': 'interaction', 'id': None, + 'args': (filename, self.frame.f_lineno, line), + 'kwargs': kwargs}) + + self.pull_actions() + finally: + self.waiting = False + self.frame = None + + def do_debug(self, mainpyfile=None, wait_breakpoint=1): + self.reset() + if not wait_breakpoint or mainpyfile: + self._wait_for_mainpyfile = 1 + if not mainpyfile: + frame = sys._getframe().f_back + mainpyfile = frame.f_code.co_filename + self.mainpyfile = self.canonic(mainpyfile) + self._wait_for_breakpoint = wait_breakpoint + sys.settrace(self.trace_dispatch) + + def set_trace(self, frame=None): + # start debugger interaction immediatelly + if frame is None: + frame = sys._getframe().f_back + self._wait_for_mainpyfile = frame.f_code.co_filename + self._wait_for_breakpoint = 0 + # reinitialize debugger internal settings + self.fast_continue = False + bdb.Bdb.set_trace(self, frame) + + # Command definitions, called by interaction() + + def do_continue(self): + self.set_continue() + self.waiting = False + self.fast_continue = self.use_speedups + + def do_step(self): + self.set_step() + self.waiting = False + self.fast_continue = False + + def do_return(self): + self.set_return(self.frame) + self.waiting = False + self.fast_continue = False + + def do_next(self): + self.set_next(self.frame) + self.waiting = False + self.fast_continue = False + + def interrupt(self): + self.set_trace() + self.fast_continue = False + + def do_quit(self): + self.set_quit() + self.waiting = False + self.fast_continue = False + + def do_jump(self, lineno): + arg = int(lineno) + try: + self.frame.f_lineno = arg + except ValueError as e: + return str(e) + + def do_list(self, arg): + last = None + if arg: + if isinstance(arg, tuple): + first, last = arg + else: + first = arg + elif not self._lineno: + first = max(1, self.frame.f_lineno - 5) + else: + first = self._lineno + 1 + if last is None: + last = first + 10 + filename = self.frame.f_code.co_filename + breaklist = self.get_file_breaks(filename) + lines = [] + for lineno in range(first, last+1): + line = linecache.getline(filename, lineno, + self.frame.f_globals) + if not line: + lines.append((filename, lineno, '', "", "\n")) + break + else: + breakpoint = "B" if lineno in breaklist else "" + current = "->" if self.frame.f_lineno == lineno else "" + lines.append((filename, lineno, breakpoint, current, line)) + self._lineno = lineno + return lines + + def do_read(self, filename): + return open(filename, "Ur").read() + + def do_set_breakpoint(self, filename, lineno, temporary=0, cond=None): + global breaks # list for speedups! + breaks.append((filename.replace("\\", "/"), int(lineno))) + return self.set_break(filename, int(lineno), temporary, cond) + + def do_list_breakpoint(self): + breaks = [] + if self.breaks: # There's at least one + for bp in bdb.Breakpoint.bpbynumber: + if bp: + breaks.append((bp.number, bp.file, bp.line, + bp.temporary, bp.enabled, bp.hits, bp.cond, )) + return breaks + + def do_clear_breakpoint(self, filename, lineno): + self.clear_break(filename, lineno) + + def do_clear_file_breakpoints(self, filename): + self.clear_all_file_breaks(filename) + + def do_clear(self, arg): + # required by BDB to remove temp breakpoints! + err = self.clear_bpbynumber(arg) + if err: + print('*** DO_CLEAR failed', err) + + def do_eval(self, arg, safe=True): + if self.frame: + ret = eval(arg, self.frame.f_globals, + self.frame_locals) + else: + ret = RPCError("No current frame available to eval") + if safe: + ret = pydoc.cram(repr(ret), 255) + return ret + + def do_exec(self, arg, safe=True): + if not self.frame: + ret = RPCError("No current frame available to exec") + else: + locals = self.frame_locals + globals = self.frame.f_globals + code = compile(arg + '\n', '', 'single') + save_displayhook = sys.displayhook + self.displayhook_value = None + try: + sys.displayhook = self.displayhook + exec(code, globals, locals) + ret = self.displayhook_value + finally: + sys.displayhook = save_displayhook + if safe: + ret = pydoc.cram(repr(ret), 255) + return ret + + def do_where(self): + "print_stack_trace" + stack, curindex = self.get_stack(self.frame, None) + lines = [] + for frame, lineno in stack: + filename = frame.f_code.co_filename + line = linecache.getline(filename, lineno) + lines.append((filename, lineno, "", "", line, )) + return lines + + def do_environment(self): + "return current frame local and global environment" + env = {'locals': {}, 'globals': {}} + # converts the frame global and locals to a short text representation: + if self.frame: + for scope, max_length, vars in ( + ("locals", 255, list(self.frame_locals.items())), + ("globals", 20, list(self.frame.f_globals.items())), ): + for (name, value) in vars: + try: + short_repr = pydoc.cram(repr(value), max_length) + except Exception as e: + # some objects cannot be represented... + short_repr = "**exception** %s" % repr(e) + env[scope][name] = (short_repr, repr(type(value))) + return env + + def get_autocomplete_list(self, expression): + "Return list of auto-completion options for expression" + try: + obj = self.do_eval(expression, safe=False) + except: + return [] + else: + return dir(obj) + + def get_call_tip(self, expression): + "Return list of auto-completion options for expression" + try: + obj = self.do_eval(expression) + except Exception as e: + return ('', '', str(e)) + else: + name = '' + try: + name = obj.__name__ + except AttributeError: + pass + argspec = '' + drop_self = 0 + f = None + try: + if inspect.isbuiltin(obj): + pass + elif inspect.ismethod(obj): + # Get the function from the object + f = obj.__func__ + drop_self = 1 + elif inspect.isclass(obj): + # Get the __init__ method function for the class. + if hasattr(obj, '__init__'): + f = obj.__init__.__func__ + else: + for base in object.__bases__: + if hasattr(base, '__init__'): + f = base.__init__.__func__ + break + if f is not None: + drop_self = 1 + elif isinstance(obj, collections.Callable): + # use the obj as a function by default + f = obj + # Get the __call__ method instead. + f = obj.__call__.__func__ + drop_self = 0 + except AttributeError: + pass + if f: + argspec = inspect.formatargspec(*inspect.getargspec(f)) + doc = '' + if isinstance(obj, collections.Callable): + try: + doc = inspect.getdoc(obj) + except: + pass + return (name, argspec[1:-1], doc.strip()) + + def set_burst(self, val): + "Set burst mode -multiple command count- (shut up notifications)" + self.burst = val + + def set_params(self, params): + "Set parameters for interaction" + self.params.update(params) + + def displayhook(self, obj): + """Custom displayhook for the do_exec which prevents + assignment of the _ variable in the builtins. + """ + self.displayhook_value = repr(obj) + + def reset(self): + bdb.Bdb.reset(self) + self.waiting = False + self.frame = None + + def post_mortem(self, info=None): + "Debug an un-handled python exception" + # check if post mortem mode is enabled: + if not self.params.get('postmortem', True): + return + # handling the default + if info is None: + # sys.exc_info() returns (type, value, traceback) if an exception is + # being handled, otherwise it returns None + info = sys.exc_info() + # extract the traceback object: + t = info[2] + if t is None: + raise ValueError("A valid traceback must be passed if no " + "exception is being handled") + self.reset() + # get last frame: + while t is not None: + frame = t.tb_frame + t = t.tb_next + code, lineno = frame.f_code, frame.f_lineno + filename = code.co_filename + line = linecache.getline(filename, lineno) + #(filename, lineno, "", current, line, )} + # SyntaxError doesn't execute even one line, so avoid mainpyfile check + self._wait_for_mainpyfile = False + # send exception information & request interaction + self.user_exception(frame, info) + + def ping(self): + "Minimal method to test that the pipe (connection) is alive" + try: + # get some non-trivial data to compare: + args = (id(object()), ) + msg = {'method': 'ping', 'args': args, 'id': None} + self.pipe.send(msg) + msg = self.pipe.recv() + # check if data received is ok (alive and synchonized!) + return msg['result'] == args + except (IOError, EOFError): + return None + + # console file-like object emulation + def readline(self): + "Replacement for stdin.readline()" + msg = {'method': 'readline', 'args': (), 'id': self.i} + self.pipe.send(msg) + msg = self.pipe.recv() + self.i += 1 + return msg['result'] + + def readlines(self): + "Replacement for stdin.readlines()" + lines = [] + while lines[-1:] != ['\n']: + lines.append(self.readline()) + return lines + + def write(self, text): + "Replacement for stdout.write()" + msg = {'method': 'write', 'args': (text, ), 'id': None} + self.pipe.send(msg) + + def writelines(self, l): + list(map(self.write, l)) + + def flush(self): + pass + + def isatty(self): + return 0 + + def encoding(self): + return None # use default, 'utf-8' should be better... + + def close(self): + # revert redirections and close connection + if sys: + sys.stdin, sys.stdout, sys.stderr = self.old_stdio + try: + self.pipe.close() + except: + pass + + def __del__(self): + self.close() + + +class QueuePipe(object): + "Simulated pipe for threads (using two queues)" + + def __init__(self, name, in_queue, out_queue): + self.__name = name + self.in_queue = in_queue + self.out_queue = out_queue + + def send(self, data): + self.out_queue.put(data, block=True) + + def recv(self, count=None, timeout=None): + data = self.in_queue.get(block=True, timeout=timeout) + return data + + def poll(self, timeout=None): + return not self.in_queue.empty() + + def close(self): + pass + + +class RPCError(RuntimeError): + "Remote Error (not user exception)" + pass + + +class Frontend(object): + "Qdb generic Frontend interface" + + def __init__(self, pipe): + self.i = 1 + self.info = () + self.pipe = pipe + self.notifies = [] + self.read_lock = threading.RLock() + self.write_lock = threading.RLock() + + def recv(self): + self.read_lock.acquire() + try: + return self.pipe.recv() + finally: + self.read_lock.release() + + def send(self, data): + self.write_lock.acquire() + try: + return self.pipe.send(data) + finally: + self.write_lock.release() + + def startup(self, version, pid, thread_name, argv, filename): + self.info = (version, pid, thread_name, argv, filename) + self.send({'method': 'run', 'args': (), 'id': None}) + + def interaction(self, filename, lineno, line, *kwargs): + raise NotImplementedError + + def exception(self, title, extype, exvalue, trace, request): + "Show a user_exception" + raise NotImplementedError + + def write(self, text): + "Console output (print)" + raise NotImplementedError + + def readline(self, text): + "Console input/rawinput" + raise NotImplementedError + + def run(self): + "Main method dispatcher (infinite loop)" + if self.pipe: + if not self.notifies: + # wait for a message... + request = self.recv() + else: + # process an asyncronus notification received earlier + request = self.notifies.pop(0) + return self.process_message(request) + + def process_message(self, request): + if request: + result = None + if request.get("error"): + # it is not supposed to get an error here + # it should be raised by the method call + raise RPCError(res['error']['message']) + elif request.get('method') == 'interaction': + self.interaction(*request.get("args"), **request.get("kwargs")) + elif request.get('method') == 'startup': + self.startup(*request['args']) + elif request.get('method') == 'exception': + self.exception(*request['args']) + elif request.get('method') == 'write': + self.write(*request.get("args")) + elif request.get('method') == 'readline': + result = self.readline() + elif request.get('method') == 'ping': + result = request['args'] + if result: + response = {'version': '1.1', 'id': request.get('id'), + 'result': result, + 'error': None} + self.send(response) + return True + + def call(self, method, *args): + "Actually call the remote method (inside the thread)" + req = {'method': method, 'args': args, 'id': self.i} + self.send(req) + self.i += 1 # increment the id + while 1: + # wait until command acknowledge (response id match the request) + res = self.recv() + if 'id' not in res or not res['id']: + # nested notification received (i.e. write)! process it later... + self.notifies.append(res) + elif 'result' not in res: + # nested request received (i.e. readline)! process it! + self.process_message(res) + elif int(req['id']) != int(res['id']): + print("DEBUGGER wrong packet received: expecting id", req['id'], res['id']) + # protocol state is unknown + elif 'error' in res and res['error']: + raise RPCError(res['error']['message']) + else: + return res['result'] + + def do_step(self, arg=None): + "Execute the current line, stop at the first possible occasion" + self.call('do_step') + + def do_next(self, arg=None): + "Execute the current line, do not stop at function calls" + self.call('do_next') + + def do_continue(self, arg=None): + "Continue execution, only stop when a breakpoint is encountered." + self.call('do_continue') + + def do_return(self, arg=None): + "Continue execution until the current function returns" + self.call('do_return') + + def do_jump(self, arg): + "Set the next line that will be executed (None if sucess or message)" + res = self.call('do_jump', arg) + return res + + def do_where(self, arg=None): + "Print a stack trace, with the most recent frame at the bottom." + return self.call('do_where') + + def do_quit(self, arg=None): + "Quit from the debugger. The program being executed is aborted." + self.call('do_quit') + + def do_eval(self, expr): + "Inspect the value of the expression" + return self.call('do_eval', expr) + + def do_environment(self): + "List all the locals and globals variables (string representation)" + return self.call('do_environment') + + def do_list(self, arg=None): + "List source code for the current file" + return self.call('do_list', arg) + + def do_read(self, filename): + "Read and send a local filename" + return self.call('do_read', filename) + + def do_set_breakpoint(self, filename, lineno, temporary=0, cond=None): + "Set a breakpoint at filename:breakpoint" + self.call('do_set_breakpoint', filename, lineno, temporary, cond) + + def do_clear_breakpoint(self, filename, lineno): + "Remove a breakpoint at filename:breakpoint" + self.call('do_clear_breakpoint', filename, lineno) + + def do_clear_file_breakpoints(self, filename): + "Remove all breakpoints at filename" + self.call('do_clear_breakpoints', filename, lineno) + + def do_list_breakpoint(self): + "List all breakpoints" + return self.call('do_list_breakpoint') + + def do_exec(self, statement): + return self.call('do_exec', statement) + + def get_autocomplete_list(self, expression): + return self.call('get_autocomplete_list', expression) + + def get_call_tip(self, expression): + return self.call('get_call_tip', expression) + + def interrupt(self): + "Immediately stop at the first possible occasion (outside interaction)" + # this is a notification!, do not expect a response + req = {'method': 'interrupt', 'args': ()} + self.send(req) + + def set_burst(self, value): + req = {'method': 'set_burst', 'args': (value, )} + self.send(req) + + def set_params(self, params): + req = {'method': 'set_params', 'args': (params, )} + self.send(req) + + +class Cli(Frontend, cmd.Cmd): + "Qdb Front-end command line interface" + + def __init__(self, pipe, completekey='tab', stdin=None, stdout=None, skip=None): + cmd.Cmd.__init__(self, completekey, stdin, stdout) + Frontend.__init__(self, pipe) + + # redefine Frontend methods: + + def run(self): + while 1: + try: + Frontend.run(self) + except KeyboardInterrupt: + print("Interupting...") + self.interrupt() + + def interaction(self, filename, lineno, line): + print("> %s(%d)\n-> %s" % (filename, lineno, line), end=' ') + self.filename = filename + self.cmdloop() + + def exception(self, title, extype, exvalue, trace, request): + print("=" * 80) + print("Exception", title) + print(request) + print("-" * 80) + + def write(self, text): + print(text, end=' ') + + def readline(self): + return input() + + def postcmd(self, stop, line): + return not line.startswith("h") # stop + + do_h = cmd.Cmd.do_help + + do_s = Frontend.do_step + do_n = Frontend.do_next + do_c = Frontend.do_continue + do_r = Frontend.do_return + do_q = Frontend.do_quit + + def do_eval(self, args): + "Inspect the value of the expression" + print(Frontend.do_eval(self, args)) + + def do_list(self, args): + "List source code for the current file" + lines = Frontend.do_list(self, eval(args, {}, {}) if args else None) + self.print_lines(lines) + + def do_where(self, args): + "Print a stack trace, with the most recent frame at the bottom." + lines = Frontend.do_where(self) + self.print_lines(lines) + + def do_environment(self, args=None): + env = Frontend.do_environment(self) + for key in env: + print("=" * 78) + print(key.capitalize()) + print("-" * 78) + for name, value in list(env[key].items()): + print("%-12s = %s" % (name, value)) + + def do_list_breakpoint(self, arg=None): + "List all breakpoints" + breaks = Frontend.do_list_breakpoint(self) + print("Num File Line Temp Enab Hits Cond") + for bp in breaks: + print('%-4d%-30s%4d %4s %4s %4d %s' % bp) + print() + + def do_set_breakpoint(self, arg): + "Set a breakpoint at filename:breakpoint" + if arg: + if ':' in arg: + args = arg.split(":") + else: + args = (self.filename, arg) + Frontend.do_set_breakpoint(self, *args) + else: + self.do_list_breakpoint() + + def do_jump(self, args): + "Jump to the selected line" + ret = Frontend.do_jump(self, args) + if ret: # show error message if failed + print("cannot jump:", ret) + + do_b = do_set_breakpoint + do_l = do_list + do_p = do_eval + do_w = do_where + do_e = do_environment + do_j = do_jump + + def default(self, line): + "Default command" + if line[:1] == '!': + print(self.do_exec(line[1:])) + else: + print("*** Unknown command: ", line) + + def print_lines(self, lines): + for filename, lineno, bp, current, source in lines: + print("%s:%4d%s%s\t%s" % (filename, lineno, bp, current, source), end=' ') + print() + + +# WORKAROUND for python3 server using pickle's HIGHEST_PROTOCOL (now 3) +# but python2 client using pickles's protocol version 2 +if sys.version_info[0] > 2: + + import multiprocessing.reduction # forking in py2 + + class ForkingPickler2(multiprocessing.reduction.ForkingPickler): + def __init__(self, file, protocol=None, fix_imports=True): + # downgrade to protocol ver 2 + protocol = 2 + super().__init__(file, protocol, fix_imports) + + multiprocessing.reduction.ForkingPickler = ForkingPickler2 + + +def f(pipe): + "test function to be debugged" + print("creating debugger") + qdb_test = Qdb(pipe=pipe, redirect_stdio=False, allow_interruptions=True) + print("set trace") + + my_var = "Mariano!" + qdb_test.set_trace() + print("hello world!") + for i in range(100000): + pass + print("good by!") + + +def test(): + "Create a backend/frontend and time it" + if '--process' in sys.argv: + from multiprocessing import Process, Pipe + front_conn, child_conn = Pipe() + p = Process(target=f, args=(child_conn,)) + else: + from threading import Thread + from queue import Queue + parent_queue, child_queue = Queue(), Queue() + front_conn = QueuePipe("parent", parent_queue, child_queue) + child_conn = QueuePipe("child", child_queue, parent_queue) + p = Thread(target=f, args=(child_conn,)) + + p.start() + import time + + class Test(Frontend): + def interaction(self, *args): + print("interaction!", args) + ##self.do_next() + def exception(self, *args): + print("exception", args) + + qdb_test = Test(front_conn) + time.sleep(1) + t0 = time.time() + + print("running...") + while front_conn.poll(): + Frontend.run(qdb_test) + qdb_test.do_continue() + p.join() + t1 = time.time() + print("took", t1 - t0, "seconds") + sys.exit(0) + + +def start(host="localhost", port=6000, authkey='secret password'): + "Start the CLI server and wait connection from a running debugger backend" + + address = (host, port) + from multiprocessing.connection import Listener + address = (host, port) # family is deduced to be 'AF_INET' + if isinstance(authkey, str): + authkey = authkey.encode("utf8") + listener = Listener(address, authkey=authkey) + print("qdb debugger backend: waiting for connection at", address) + conn = listener.accept() + print('qdb debugger backend: connected to', listener.last_accepted) + try: + Cli(conn).run() + except EOFError: + pass + finally: + conn.close() + + +def main(host='localhost', port=6000, authkey='secret password'): + "Debug a script (running under the backend) and connect to remote frontend" + + if not sys.argv[1:] or sys.argv[1] in ("--help", "-h"): + print("usage: pdb.py scriptfile [arg] ...") + sys.exit(2) + + mainpyfile = sys.argv[1] # Get script filename + if not os.path.exists(mainpyfile): + print('Error:', mainpyfile, 'does not exist') + sys.exit(1) + + del sys.argv[0] # Hide "pdb.py" from argument list + + # Replace pdb's dir with script's dir in front of module search path. + sys.path[0] = os.path.dirname(mainpyfile) + + # create the backend + init(host, port, authkey) + try: + print("running", mainpyfile) + qdb._runscript(mainpyfile) + print("The program finished") + except SystemExit: + # In most cases SystemExit does not warrant a post-mortem session. + print("The program exited via sys.exit(). Exit status: ", end=' ') + print(sys.exc_info()[1]) + raise + except Exception: + traceback.print_exc() + print("Uncaught exception. Entering post mortem debugging") + info = sys.exc_info() + qdb.post_mortem(info) + print("Program terminated!") + finally: + conn.close() + print("qdb debbuger backend: connection closed") + + +# "singleton" to store a unique backend per process +qdb = None + + +def init(host='localhost', port=6000, authkey='secret password', redirect=True): + "Simplified interface to debug running programs" + global qdb, listener, conn + + # destroy the debugger if the previous connection is lost (i.e. broken pipe) + if qdb and not qdb.ping(): + qdb.close() + qdb = None + + from multiprocessing.connection import Client + # only create it if not currently instantiated + if not qdb: + address = (host, port) # family is deduced to be 'AF_INET' + print("qdb debugger backend: waiting for connection to", address) + if isinstance(authkey, str): + authkey = authkey.encode("utf8") + conn = Client(address, authkey=authkey) + print('qdb debugger backend: connected to', address) + # create the backend + qdb = Qdb(conn, redirect_stdio=redirect, allow_interruptions=True) + # initial hanshake + qdb.startup() + + +def set_trace(host='localhost', port=6000, authkey='secret password'): + "Simplified interface to start debugging immediately" + init(host, port, authkey) + # start debugger backend: + qdb.set_trace() + +def debug(host='localhost', port=6000, authkey='secret password'): + "Simplified interface to start debugging immediately (no stop)" + init(host, port, authkey) + # start debugger backend: + qdb.do_debug() + + +def quit(): + "Remove trace and quit" + global qdb, listener, conn + if qdb: + sys.settrace(None) + qdb = None + if conn: + conn.close() + conn = None + if listener: + listener.close() + listener = None + +if __name__ == '__main__': + # When invoked as main program: + if '--test1' in sys.argv: + test() + # Check environment for configuration parameters: + kwargs = {} + for param in 'host', 'port', 'authkey': + if 'DBG_%s' % param.upper() in os.environ: + kwargs[param] = os.environ['DBG_%s' % param.upper()] + + if not sys.argv[1:]: + # connect to a remote debbuger + start(**kwargs) + else: + # start the debugger on a script + # reimport as global __main__ namespace is destroyed + import dbg + dbg.main(**kwargs) + diff --git a/web2py/gluon/contrib/feedparser.py b/web2py/gluon/contrib/feedparser.py new file mode 100644 index 0000000..999cb0d --- /dev/null +++ b/web2py/gluon/contrib/feedparser.py @@ -0,0 +1,4007 @@ +"""Universal feed parser + +Handles RSS 0.9x, RSS 1.0, RSS 2.0, CDF, Atom 0.3, and Atom 1.0 feeds + +Visit https://code.google.com/p/feedparser/ for the latest version +Visit http://packages.python.org/feedparser/ for the latest documentation + +Required: Python 2.4 or later +Recommended: iconv_codec +""" + +__version__ = "5.2.1" +__license__ = """ +Copyright 2010-2015 Kurt McKee +Copyright 2002-2008 Mark Pilgrim +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE.""" +__author__ = "Mark Pilgrim " +__contributors__ = ["Jason Diamond ", + "John Beimler ", + "Fazal Majid ", + "Aaron Swartz ", + "Kevin Marks ", + "Sam Ruby ", + "Ade Oshineye ", + "Martin Pool ", + "Kurt McKee ", + "Bernd Schlapsi ",] + +# HTTP "User-Agent" header to send to servers when downloading feeds. +# If you are embedding feedparser in a larger application, you should +# change this to your application name and URL. +USER_AGENT = "UniversalFeedParser/%s +https://code.google.com/p/feedparser/" % __version__ + +# HTTP "Accept" header to send to servers when downloading feeds. If you don't +# want to send an Accept header, set this to None. +ACCEPT_HEADER = "application/atom+xml,application/rdf+xml,application/rss+xml,application/x-netcdf,application/xml;q=0.9,text/xml;q=0.2,*/*;q=0.1" + +# List of preferred XML parsers, by SAX driver name. These will be tried first, +# but if they're not installed, Python will keep searching through its own list +# of pre-installed parsers until it finds one that supports everything we need. +PREFERRED_XML_PARSERS = ["drv_libxml2"] + +# If you want feedparser to automatically resolve all relative URIs, set this +# to 1. +RESOLVE_RELATIVE_URIS = 1 + +# If you want feedparser to automatically sanitize all potentially unsafe +# HTML content, set this to 1. +SANITIZE_HTML = 1 + +# ---------- Python 3 modules (make it work if possible) ---------- +try: + import rfc822 +except ImportError: + from email import _parseaddr as rfc822 + +try: + # Python 3.1 introduces bytes.maketrans and simultaneously + # deprecates string.maketrans; use bytes.maketrans if possible + _maketrans = bytes.maketrans +except (NameError, AttributeError): + import string + _maketrans = string.maketrans + +# base64 support for Atom feeds that contain embedded binary data +try: + import base64, binascii +except ImportError: + base64 = binascii = None +else: + # Python 3.1 deprecates decodestring in favor of decodebytes + _base64decode = getattr(base64, 'decodebytes', base64.decodestring) + +# _s2bytes: convert a UTF-8 str to bytes if the interpreter is Python 3 +# _l2bytes: convert a list of ints to bytes if the interpreter is Python 3 +try: + if bytes is str: + # In Python 2.5 and below, bytes doesn't exist (NameError) + # In Python 2.6 and above, bytes and str are the same type + raise NameError +except NameError: + # Python 2 + def _s2bytes(s): + return s + def _l2bytes(l): + return ''.join(map(chr, l)) +else: + # Python 3 + def _s2bytes(s): + return bytes(s, 'utf8') + def _l2bytes(l): + return bytes(l) + +# If you want feedparser to allow all URL schemes, set this to () +# List culled from Python's urlparse documentation at: +# http://docs.python.org/library/urlparse.html +# as well as from "URI scheme" at Wikipedia: +# https://secure.wikimedia.org/wikipedia/en/wiki/URI_scheme +# Many more will likely need to be added! +ACCEPTABLE_URI_SCHEMES = ( + 'file', 'ftp', 'gopher', 'h323', 'hdl', 'http', 'https', 'imap', 'magnet', + 'mailto', 'mms', 'news', 'nntp', 'prospero', 'rsync', 'rtsp', 'rtspu', + 'sftp', 'shttp', 'sip', 'sips', 'snews', 'svn', 'svn+ssh', 'telnet', + 'wais', + # Additional common-but-unofficial schemes + 'aim', 'callto', 'cvs', 'facetime', 'feed', 'git', 'gtalk', 'irc', 'ircs', + 'irc6', 'itms', 'mms', 'msnim', 'skype', 'ssh', 'smb', 'svn', 'ymsg', +) +#ACCEPTABLE_URI_SCHEMES = () + +# ---------- required modules (should come with any Python distribution) ---------- +import cgi +import codecs +import copy +import datetime +import itertools +import re +import struct +import time +import types +import urllib +import urllib2 +import urlparse +import warnings + +from htmlentitydefs import name2codepoint, codepoint2name, entitydefs + +try: + from io import BytesIO as _StringIO +except ImportError: + try: + from cStringIO import StringIO as _StringIO + except ImportError: + from StringIO import StringIO as _StringIO + +# ---------- optional modules (feedparser will work without these, but with reduced functionality) ---------- + +# gzip is included with most Python distributions, but may not be available if you compiled your own +try: + import gzip +except ImportError: + gzip = None +try: + import zlib +except ImportError: + zlib = None + +# If a real XML parser is available, feedparser will attempt to use it. feedparser has +# been tested with the built-in SAX parser and libxml2. On platforms where the +# Python distribution does not come with an XML parser (such as Mac OS X 10.2 and some +# versions of FreeBSD), feedparser will quietly fall back on regex-based parsing. +try: + import xml.sax + from xml.sax.saxutils import escape as _xmlescape +except ImportError: + _XML_AVAILABLE = 0 + def _xmlescape(data,entities={}): + data = data.replace('&', '&') + data = data.replace('>', '>') + data = data.replace('<', '<') + for char, entity in entities: + data = data.replace(char, entity) + return data +else: + try: + xml.sax.make_parser(PREFERRED_XML_PARSERS) # test for valid parsers + except xml.sax.SAXReaderNotAvailable: + _XML_AVAILABLE = 0 + else: + _XML_AVAILABLE = 1 + +# sgmllib is not available by default in Python 3; if the end user doesn't have +# it available then we'll lose illformed XML parsing and content santizing +try: + import sgmllib +except ImportError: + # This is probably Python 3, which doesn't include sgmllib anymore + _SGML_AVAILABLE = 0 + + # Mock sgmllib enough to allow subclassing later on + class sgmllib(object): + class SGMLParser(object): + def goahead(self, i): + pass + def parse_starttag(self, i): + pass +else: + _SGML_AVAILABLE = 1 + + # sgmllib defines a number of module-level regular expressions that are + # insufficient for the XML parsing feedparser needs. Rather than modify + # the variables directly in sgmllib, they're defined here using the same + # names, and the compiled code objects of several sgmllib.SGMLParser + # methods are copied into _BaseHTMLProcessor so that they execute in + # feedparser's scope instead of sgmllib's scope. + charref = re.compile('&#(\d+|[xX][0-9a-fA-F]+);') + tagfind = re.compile('[a-zA-Z][-_.:a-zA-Z0-9]*') + attrfind = re.compile( + r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)[$]?(\s*=\s*' + r'(\'[^\']*\'|"[^"]*"|[][\-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~\'"@]*))?' + ) + + # Unfortunately, these must be copied over to prevent NameError exceptions + entityref = sgmllib.entityref + incomplete = sgmllib.incomplete + interesting = sgmllib.interesting + shorttag = sgmllib.shorttag + shorttagopen = sgmllib.shorttagopen + starttagopen = sgmllib.starttagopen + + class _EndBracketRegEx: + def __init__(self): + # Overriding the built-in sgmllib.endbracket regex allows the + # parser to find angle brackets embedded in element attributes. + self.endbracket = re.compile('''([^'"<>]|"[^"]*"(?=>|/|\s|\w+=)|'[^']*'(?=>|/|\s|\w+=))*(?=[<>])|.*?(?=[<>])''') + def search(self, target, index=0): + match = self.endbracket.match(target, index) + if match is not None: + # Returning a new object in the calling thread's context + # resolves a thread-safety. + return EndBracketMatch(match) + return None + class EndBracketMatch: + def __init__(self, match): + self.match = match + def start(self, n): + return self.match.end(n) + endbracket = _EndBracketRegEx() + + +# iconv_codec provides support for more character encodings. +# It's available from http://cjkpython.i18n.org/ +try: + import iconv_codec +except ImportError: + pass + +# chardet library auto-detects character encodings +# Download from http://chardet.feedparser.org/ +try: + import chardet +except ImportError: + chardet = None + +# ---------- don't touch these ---------- +class ThingsNobodyCaresAboutButMe(Exception): pass +class CharacterEncodingOverride(ThingsNobodyCaresAboutButMe): pass +class CharacterEncodingUnknown(ThingsNobodyCaresAboutButMe): pass +class NonXMLContentType(ThingsNobodyCaresAboutButMe): pass +class UndeclaredNamespace(Exception): pass + +SUPPORTED_VERSIONS = {'': u'unknown', + 'rss090': u'RSS 0.90', + 'rss091n': u'RSS 0.91 (Netscape)', + 'rss091u': u'RSS 0.91 (Userland)', + 'rss092': u'RSS 0.92', + 'rss093': u'RSS 0.93', + 'rss094': u'RSS 0.94', + 'rss20': u'RSS 2.0', + 'rss10': u'RSS 1.0', + 'rss': u'RSS (unknown version)', + 'atom01': u'Atom 0.1', + 'atom02': u'Atom 0.2', + 'atom03': u'Atom 0.3', + 'atom10': u'Atom 1.0', + 'atom': u'Atom (unknown version)', + 'cdf': u'CDF', + } + +class FeedParserDict(dict): + keymap = {'channel': 'feed', + 'items': 'entries', + 'guid': 'id', + 'date': 'updated', + 'date_parsed': 'updated_parsed', + 'description': ['summary', 'subtitle'], + 'description_detail': ['summary_detail', 'subtitle_detail'], + 'url': ['href'], + 'modified': 'updated', + 'modified_parsed': 'updated_parsed', + 'issued': 'published', + 'issued_parsed': 'published_parsed', + 'copyright': 'rights', + 'copyright_detail': 'rights_detail', + 'tagline': 'subtitle', + 'tagline_detail': 'subtitle_detail'} + def __getitem__(self, key): + ''' + :return: A :class:`FeedParserDict`. + ''' + if key == 'category': + try: + return dict.__getitem__(self, 'tags')[0]['term'] + except IndexError: + raise KeyError, "object doesn't have key 'category'" + elif key == 'enclosures': + norel = lambda link: FeedParserDict([(name,value) for (name,value) in link.items() if name!='rel']) + return [norel(link) for link in dict.__getitem__(self, 'links') if link['rel']==u'enclosure'] + elif key == 'license': + for link in dict.__getitem__(self, 'links'): + if link['rel']==u'license' and 'href' in link: + return link['href'] + elif key == 'updated': + # Temporarily help developers out by keeping the old + # broken behavior that was reported in issue 310. + # This fix was proposed in issue 328. + if not dict.__contains__(self, 'updated') and \ + dict.__contains__(self, 'published'): + warnings.warn("To avoid breaking existing software while " + "fixing issue 310, a temporary mapping has been created " + "from `updated` to `published` if `updated` doesn't " + "exist. This fallback will be removed in a future version " + "of feedparser.", DeprecationWarning) + return dict.__getitem__(self, 'published') + return dict.__getitem__(self, 'updated') + elif key == 'updated_parsed': + if not dict.__contains__(self, 'updated_parsed') and \ + dict.__contains__(self, 'published_parsed'): + warnings.warn("To avoid breaking existing software while " + "fixing issue 310, a temporary mapping has been created " + "from `updated_parsed` to `published_parsed` if " + "`updated_parsed` doesn't exist. This fallback will be " + "removed in a future version of feedparser.", + DeprecationWarning) + return dict.__getitem__(self, 'published_parsed') + return dict.__getitem__(self, 'updated_parsed') + else: + realkey = self.keymap.get(key, key) + if isinstance(realkey, list): + for k in realkey: + if dict.__contains__(self, k): + return dict.__getitem__(self, k) + elif dict.__contains__(self, realkey): + return dict.__getitem__(self, realkey) + return dict.__getitem__(self, key) + + def __contains__(self, key): + if key in ('updated', 'updated_parsed'): + # Temporarily help developers out by keeping the old + # broken behavior that was reported in issue 310. + # This fix was proposed in issue 328. + return dict.__contains__(self, key) + try: + self.__getitem__(key) + except KeyError: + return False + else: + return True + + has_key = __contains__ + + def get(self, key, default=None): + ''' + :return: A :class:`FeedParserDict`. + ''' + try: + return self.__getitem__(key) + except KeyError: + return default + + def __setitem__(self, key, value): + key = self.keymap.get(key, key) + if isinstance(key, list): + key = key[0] + return dict.__setitem__(self, key, value) + + def setdefault(self, key, value): + if key not in self: + self[key] = value + return value + return self[key] + + def __getattr__(self, key): + # __getattribute__() is called first; this will be called + # only if an attribute was not already found + try: + return self.__getitem__(key) + except KeyError: + raise AttributeError, "object has no attribute '%s'" % key + + def __hash__(self): + return id(self) + +_cp1252 = { + 128: unichr(8364), # euro sign + 130: unichr(8218), # single low-9 quotation mark + 131: unichr( 402), # latin small letter f with hook + 132: unichr(8222), # double low-9 quotation mark + 133: unichr(8230), # horizontal ellipsis + 134: unichr(8224), # dagger + 135: unichr(8225), # double dagger + 136: unichr( 710), # modifier letter circumflex accent + 137: unichr(8240), # per mille sign + 138: unichr( 352), # latin capital letter s with caron + 139: unichr(8249), # single left-pointing angle quotation mark + 140: unichr( 338), # latin capital ligature oe + 142: unichr( 381), # latin capital letter z with caron + 145: unichr(8216), # left single quotation mark + 146: unichr(8217), # right single quotation mark + 147: unichr(8220), # left double quotation mark + 148: unichr(8221), # right double quotation mark + 149: unichr(8226), # bullet + 150: unichr(8211), # en dash + 151: unichr(8212), # em dash + 152: unichr( 732), # small tilde + 153: unichr(8482), # trade mark sign + 154: unichr( 353), # latin small letter s with caron + 155: unichr(8250), # single right-pointing angle quotation mark + 156: unichr( 339), # latin small ligature oe + 158: unichr( 382), # latin small letter z with caron + 159: unichr( 376), # latin capital letter y with diaeresis +} + +_urifixer = re.compile('^([A-Za-z][A-Za-z0-9+-.]*://)(/*)(.*?)') +def _urljoin(base, uri): + uri = _urifixer.sub(r'\1\3', uri) + if not isinstance(uri, unicode): + uri = uri.decode('utf-8', 'ignore') + try: + uri = urlparse.urljoin(base, uri) + except ValueError: + uri = u'' + if not isinstance(uri, unicode): + return uri.decode('utf-8', 'ignore') + return uri + +class _FeedParserMixin: + namespaces = { + '': '', + 'http://backend.userland.com/rss': '', + 'http://blogs.law.harvard.edu/tech/rss': '', + 'http://purl.org/rss/1.0/': '', + 'http://my.netscape.com/rdf/simple/0.9/': '', + 'http://example.com/newformat#': '', + 'http://example.com/necho': '', + 'http://purl.org/echo/': '', + 'uri/of/echo/namespace#': '', + 'http://purl.org/pie/': '', + 'http://purl.org/atom/ns#': '', + 'http://www.w3.org/2005/Atom': '', + 'http://purl.org/rss/1.0/modules/rss091#': '', + + 'http://webns.net/mvcb/': 'admin', + 'http://purl.org/rss/1.0/modules/aggregation/': 'ag', + 'http://purl.org/rss/1.0/modules/annotate/': 'annotate', + 'http://media.tangent.org/rss/1.0/': 'audio', + 'http://backend.userland.com/blogChannelModule': 'blogChannel', + 'http://web.resource.org/cc/': 'cc', + 'http://backend.userland.com/creativeCommonsRssModule': 'creativeCommons', + 'http://purl.org/rss/1.0/modules/company': 'co', + 'http://purl.org/rss/1.0/modules/content/': 'content', + 'http://my.theinfo.org/changed/1.0/rss/': 'cp', + 'http://purl.org/dc/elements/1.1/': 'dc', + 'http://purl.org/dc/terms/': 'dcterms', + 'http://purl.org/rss/1.0/modules/email/': 'email', + 'http://purl.org/rss/1.0/modules/event/': 'ev', + 'http://rssnamespace.org/feedburner/ext/1.0': 'feedburner', + 'http://freshmeat.net/rss/fm/': 'fm', + 'http://xmlns.com/foaf/0.1/': 'foaf', + 'http://www.w3.org/2003/01/geo/wgs84_pos#': 'geo', + 'http://www.georss.org/georss': 'georss', + 'http://www.opengis.net/gml': 'gml', + 'http://postneo.com/icbm/': 'icbm', + 'http://purl.org/rss/1.0/modules/image/': 'image', + 'http://www.itunes.com/DTDs/PodCast-1.0.dtd': 'itunes', + 'http://example.com/DTDs/PodCast-1.0.dtd': 'itunes', + 'http://purl.org/rss/1.0/modules/link/': 'l', + 'http://search.yahoo.com/mrss': 'media', + # Version 1.1.2 of the Media RSS spec added the trailing slash on the namespace + 'http://search.yahoo.com/mrss/': 'media', + 'http://madskills.com/public/xml/rss/module/pingback/': 'pingback', + 'http://prismstandard.org/namespaces/1.2/basic/': 'prism', + 'http://www.w3.org/1999/02/22-rdf-syntax-ns#': 'rdf', + 'http://www.w3.org/2000/01/rdf-schema#': 'rdfs', + 'http://purl.org/rss/1.0/modules/reference/': 'ref', + 'http://purl.org/rss/1.0/modules/richequiv/': 'reqv', + 'http://purl.org/rss/1.0/modules/search/': 'search', + 'http://purl.org/rss/1.0/modules/slash/': 'slash', + 'http://schemas.xmlsoap.org/soap/envelope/': 'soap', + 'http://purl.org/rss/1.0/modules/servicestatus/': 'ss', + 'http://hacks.benhammersley.com/rss/streaming/': 'str', + 'http://purl.org/rss/1.0/modules/subscription/': 'sub', + 'http://purl.org/rss/1.0/modules/syndication/': 'sy', + 'http://schemas.pocketsoap.com/rss/myDescModule/': 'szf', + 'http://purl.org/rss/1.0/modules/taxonomy/': 'taxo', + 'http://purl.org/rss/1.0/modules/threading/': 'thr', + 'http://purl.org/rss/1.0/modules/textinput/': 'ti', + 'http://madskills.com/public/xml/rss/module/trackback/': 'trackback', + 'http://wellformedweb.org/commentAPI/': 'wfw', + 'http://purl.org/rss/1.0/modules/wiki/': 'wiki', + 'http://www.w3.org/1999/xhtml': 'xhtml', + 'http://www.w3.org/1999/xlink': 'xlink', + 'http://www.w3.org/XML/1998/namespace': 'xml', + 'http://podlove.org/simple-chapters': 'psc', + } + _matchnamespaces = {} + + can_be_relative_uri = set(['link', 'id', 'wfw_comment', 'wfw_commentrss', 'docs', 'url', 'href', 'comments', 'icon', 'logo']) + can_contain_relative_uris = set(['content', 'title', 'summary', 'info', 'tagline', 'subtitle', 'copyright', 'rights', 'description']) + can_contain_dangerous_markup = set(['content', 'title', 'summary', 'info', 'tagline', 'subtitle', 'copyright', 'rights', 'description']) + html_types = [u'text/html', u'application/xhtml+xml'] + + def __init__(self, baseuri=None, baselang=None, encoding=u'utf-8'): + if not self._matchnamespaces: + for k, v in self.namespaces.items(): + self._matchnamespaces[k.lower()] = v + self.feeddata = FeedParserDict() # feed-level data + self.encoding = encoding # character encoding + self.entries = [] # list of entry-level data + self.version = u'' # feed type/version, see SUPPORTED_VERSIONS + self.namespacesInUse = {} # dictionary of namespaces defined by the feed + + # the following are used internally to track state; + # this is really out of control and should be refactored + self.infeed = 0 + self.inentry = 0 + self.incontent = 0 + self.intextinput = 0 + self.inimage = 0 + self.inauthor = 0 + self.incontributor = 0 + self.inpublisher = 0 + self.insource = 0 + + # georss + self.ingeometry = 0 + + self.sourcedata = FeedParserDict() + self.contentparams = FeedParserDict() + self._summaryKey = None + self.namespacemap = {} + self.elementstack = [] + self.basestack = [] + self.langstack = [] + self.baseuri = baseuri or u'' + self.lang = baselang or None + self.svgOK = 0 + self.title_depth = -1 + self.depth = 0 + # psc_chapters_flag prevents multiple psc_chapters from being + # captured in a single entry or item. The transition states are + # None -> True -> False. psc_chapter elements will only be + # captured while it is True. + self.psc_chapters_flag = None + if baselang: + self.feeddata['language'] = baselang.replace('_','-') + + # A map of the following form: + # { + # object_that_value_is_set_on: { + # property_name: depth_of_node_property_was_extracted_from, + # other_property: depth_of_node_property_was_extracted_from, + # }, + # } + self.property_depth_map = {} + + def _normalize_attributes(self, kv): + k = kv[0].lower() + v = k in ('rel', 'type') and kv[1].lower() or kv[1] + # the sgml parser doesn't handle entities in attributes, nor + # does it pass the attribute values through as unicode, while + # strict xml parsers do -- account for this difference + if isinstance(self, _LooseFeedParser): + v = v.replace('&', '&') + if not isinstance(v, unicode): + v = v.decode('utf-8') + return (k, v) + + def unknown_starttag(self, tag, attrs): + # increment depth counter + self.depth += 1 + + # normalize attrs + attrs = map(self._normalize_attributes, attrs) + + # track xml:base and xml:lang + attrsD = dict(attrs) + baseuri = attrsD.get('xml:base', attrsD.get('base')) or self.baseuri + if not isinstance(baseuri, unicode): + baseuri = baseuri.decode(self.encoding, 'ignore') + # ensure that self.baseuri is always an absolute URI that + # uses a whitelisted URI scheme (e.g. not `javscript:`) + if self.baseuri: + self.baseuri = _makeSafeAbsoluteURI(self.baseuri, baseuri) or self.baseuri + else: + self.baseuri = _urljoin(self.baseuri, baseuri) + lang = attrsD.get('xml:lang', attrsD.get('lang')) + if lang == '': + # xml:lang could be explicitly set to '', we need to capture that + lang = None + elif lang is None: + # if no xml:lang is specified, use parent lang + lang = self.lang + if lang: + if tag in ('feed', 'rss', 'rdf:RDF'): + self.feeddata['language'] = lang.replace('_','-') + self.lang = lang + self.basestack.append(self.baseuri) + self.langstack.append(lang) + + # track namespaces + for prefix, uri in attrs: + if prefix.startswith('xmlns:'): + self.trackNamespace(prefix[6:], uri) + elif prefix == 'xmlns': + self.trackNamespace(None, uri) + + # track inline content + if self.incontent and not self.contentparams.get('type', u'xml').endswith(u'xml'): + if tag in ('xhtml:div', 'div'): + return # typepad does this 10/2007 + # element declared itself as escaped markup, but it isn't really + self.contentparams['type'] = u'application/xhtml+xml' + if self.incontent and self.contentparams.get('type') == u'application/xhtml+xml': + if tag.find(':') <> -1: + prefix, tag = tag.split(':', 1) + namespace = self.namespacesInUse.get(prefix, '') + if tag=='math' and namespace=='http://www.w3.org/1998/Math/MathML': + attrs.append(('xmlns',namespace)) + if tag=='svg' and namespace=='http://www.w3.org/2000/svg': + attrs.append(('xmlns',namespace)) + if tag == 'svg': + self.svgOK += 1 + return self.handle_data('<%s%s>' % (tag, self.strattrs(attrs)), escape=0) + + # match namespaces + if tag.find(':') <> -1: + prefix, suffix = tag.split(':', 1) + else: + prefix, suffix = '', tag + prefix = self.namespacemap.get(prefix, prefix) + if prefix: + prefix = prefix + '_' + + # special hack for better tracking of empty textinput/image elements in illformed feeds + if (not prefix) and tag not in ('title', 'link', 'description', 'name'): + self.intextinput = 0 + if (not prefix) and tag not in ('title', 'link', 'description', 'url', 'href', 'width', 'height'): + self.inimage = 0 + + # call special handler (if defined) or default handler + methodname = '_start_' + prefix + suffix + try: + method = getattr(self, methodname) + return method(attrsD) + except AttributeError: + # Since there's no handler or something has gone wrong we explicitly add the element and its attributes + unknown_tag = prefix + suffix + if len(attrsD) == 0: + # No attributes so merge it into the encosing dictionary + return self.push(unknown_tag, 1) + else: + # Has attributes so create it in its own dictionary + context = self._getContext() + context[unknown_tag] = attrsD + + def unknown_endtag(self, tag): + # match namespaces + if tag.find(':') <> -1: + prefix, suffix = tag.split(':', 1) + else: + prefix, suffix = '', tag + prefix = self.namespacemap.get(prefix, prefix) + if prefix: + prefix = prefix + '_' + if suffix == 'svg' and self.svgOK: + self.svgOK -= 1 + + # call special handler (if defined) or default handler + methodname = '_end_' + prefix + suffix + try: + if self.svgOK: + raise AttributeError() + method = getattr(self, methodname) + method() + except AttributeError: + self.pop(prefix + suffix) + + # track inline content + if self.incontent and not self.contentparams.get('type', u'xml').endswith(u'xml'): + # element declared itself as escaped markup, but it isn't really + if tag in ('xhtml:div', 'div'): + return # typepad does this 10/2007 + self.contentparams['type'] = u'application/xhtml+xml' + if self.incontent and self.contentparams.get('type') == u'application/xhtml+xml': + tag = tag.split(':')[-1] + self.handle_data('' % tag, escape=0) + + # track xml:base and xml:lang going out of scope + if self.basestack: + self.basestack.pop() + if self.basestack and self.basestack[-1]: + self.baseuri = self.basestack[-1] + if self.langstack: + self.langstack.pop() + if self.langstack: # and (self.langstack[-1] is not None): + self.lang = self.langstack[-1] + + self.depth -= 1 + + def handle_charref(self, ref): + # called for each character reference, e.g. for ' ', ref will be '160' + if not self.elementstack: + return + ref = ref.lower() + if ref in ('34', '38', '39', '60', '62', 'x22', 'x26', 'x27', 'x3c', 'x3e'): + text = '&#%s;' % ref + else: + if ref[0] == 'x': + c = int(ref[1:], 16) + else: + c = int(ref) + text = unichr(c).encode('utf-8') + self.elementstack[-1][2].append(text) + + def handle_entityref(self, ref): + # called for each entity reference, e.g. for '©', ref will be 'copy' + if not self.elementstack: + return + if ref in ('lt', 'gt', 'quot', 'amp', 'apos'): + text = '&%s;' % ref + elif ref in self.entities: + text = self.entities[ref] + if text.startswith('&#') and text.endswith(';'): + return self.handle_entityref(text) + else: + try: + name2codepoint[ref] + except KeyError: + text = '&%s;' % ref + else: + text = unichr(name2codepoint[ref]).encode('utf-8') + self.elementstack[-1][2].append(text) + + def handle_data(self, text, escape=1): + # called for each block of plain text, i.e. outside of any tag and + # not containing any character or entity references + if not self.elementstack: + return + if escape and self.contentparams.get('type') == u'application/xhtml+xml': + text = _xmlescape(text) + self.elementstack[-1][2].append(text) + + def handle_comment(self, text): + # called for each comment, e.g. + pass + + def handle_pi(self, text): + # called for each processing instruction, e.g. + pass + + def handle_decl(self, text): + pass + + def parse_declaration(self, i): + # override internal declaration handler to handle CDATA blocks + if self.rawdata[i:i+9] == '', i) + if k == -1: + # CDATA block began but didn't finish + k = len(self.rawdata) + return k + self.handle_data(_xmlescape(self.rawdata[i+9:k]), 0) + return k+3 + else: + k = self.rawdata.find('>', i) + if k >= 0: + return k+1 + else: + # We have an incomplete CDATA block. + return k + + def mapContentType(self, contentType): + contentType = contentType.lower() + if contentType == 'text' or contentType == 'plain': + contentType = u'text/plain' + elif contentType == 'html': + contentType = u'text/html' + elif contentType == 'xhtml': + contentType = u'application/xhtml+xml' + return contentType + + def trackNamespace(self, prefix, uri): + loweruri = uri.lower() + if not self.version: + if (prefix, loweruri) == (None, 'http://my.netscape.com/rdf/simple/0.9/'): + self.version = u'rss090' + elif loweruri == 'http://purl.org/rss/1.0/': + self.version = u'rss10' + elif loweruri == 'http://www.w3.org/2005/atom': + self.version = u'atom10' + if loweruri.find(u'backend.userland.com/rss') <> -1: + # match any backend.userland.com namespace + uri = u'http://backend.userland.com/rss' + loweruri = uri + if loweruri in self._matchnamespaces: + self.namespacemap[prefix] = self._matchnamespaces[loweruri] + self.namespacesInUse[self._matchnamespaces[loweruri]] = uri + else: + self.namespacesInUse[prefix or ''] = uri + + def resolveURI(self, uri): + return _urljoin(self.baseuri or u'', uri) + + def decodeEntities(self, element, data): + return data + + def strattrs(self, attrs): + return ''.join([' %s="%s"' % (t[0],_xmlescape(t[1],{'"':'"'})) for t in attrs]) + + def push(self, element, expectingText): + self.elementstack.append([element, expectingText, []]) + + def pop(self, element, stripWhitespace=1): + if not self.elementstack: + return + if self.elementstack[-1][0] != element: + return + + element, expectingText, pieces = self.elementstack.pop() + + if self.version == u'atom10' and self.contentparams.get('type', u'text') == u'application/xhtml+xml': + # remove enclosing child element, but only if it is a
    and + # only if all the remaining content is nested underneath it. + # This means that the divs would be retained in the following: + #
    foo
    bar
    + while pieces and len(pieces)>1 and not pieces[-1].strip(): + del pieces[-1] + while pieces and len(pieces)>1 and not pieces[0].strip(): + del pieces[0] + if pieces and (pieces[0] == '
    ' or pieces[0].startswith('
    ': + depth = 0 + for piece in pieces[:-1]: + if piece.startswith(''): + depth += 1 + else: + pieces = pieces[1:-1] + + # Ensure each piece is a str for Python 3 + for (i, v) in enumerate(pieces): + if not isinstance(v, unicode): + pieces[i] = v.decode('utf-8') + + output = u''.join(pieces) + if stripWhitespace: + output = output.strip() + if not expectingText: + return output + + # decode base64 content + if base64 and self.contentparams.get('base64', 0): + try: + output = _base64decode(output) + except binascii.Error: + pass + except binascii.Incomplete: + pass + except TypeError: + # In Python 3, base64 takes and outputs bytes, not str + # This may not be the most correct way to accomplish this + output = _base64decode(output.encode('utf-8')).decode('utf-8') + + # resolve relative URIs + if (element in self.can_be_relative_uri) and output: + # do not resolve guid elements with isPermalink="false" + if not element == 'id' or self.guidislink: + output = self.resolveURI(output) + + # decode entities within embedded markup + if not self.contentparams.get('base64', 0): + output = self.decodeEntities(element, output) + + # some feed formats require consumers to guess + # whether the content is html or plain text + if not self.version.startswith(u'atom') and self.contentparams.get('type') == u'text/plain': + if self.lookslikehtml(output): + self.contentparams['type'] = u'text/html' + + # remove temporary cruft from contentparams + try: + del self.contentparams['mode'] + except KeyError: + pass + try: + del self.contentparams['base64'] + except KeyError: + pass + + is_htmlish = self.mapContentType(self.contentparams.get('type', u'text/html')) in self.html_types + # resolve relative URIs within embedded markup + if is_htmlish and RESOLVE_RELATIVE_URIS: + if element in self.can_contain_relative_uris: + output = _resolveRelativeURIs(output, self.baseuri, self.encoding, self.contentparams.get('type', u'text/html')) + + # sanitize embedded markup + if is_htmlish and SANITIZE_HTML: + if element in self.can_contain_dangerous_markup: + output = _sanitizeHTML(output, self.encoding, self.contentparams.get('type', u'text/html')) + + if self.encoding and not isinstance(output, unicode): + output = output.decode(self.encoding, 'ignore') + + # address common error where people take data that is already + # utf-8, presume that it is iso-8859-1, and re-encode it. + if self.encoding in (u'utf-8', u'utf-8_INVALID_PYTHON_3') and isinstance(output, unicode): + try: + output = output.encode('iso-8859-1').decode('utf-8') + except (UnicodeEncodeError, UnicodeDecodeError): + pass + + # map win-1252 extensions to the proper code points + if isinstance(output, unicode): + output = output.translate(_cp1252) + + # categories/tags/keywords/whatever are handled in _end_category or _end_tags or _end_itunes_keywords + if element in ('category', 'tags', 'itunes_keywords'): + return output + + if element == 'title' and -1 < self.title_depth <= self.depth: + return output + + # store output in appropriate place(s) + if self.inentry and not self.insource: + if element == 'content': + self.entries[-1].setdefault(element, []) + contentparams = copy.deepcopy(self.contentparams) + contentparams['value'] = output + self.entries[-1][element].append(contentparams) + elif element == 'link': + if not self.inimage: + # query variables in urls in link elements are improperly + # converted from `?a=1&b=2` to `?a=1&b;=2` as if they're + # unhandled character references. fix this special case. + output = output.replace('&', '&') + output = re.sub("&([A-Za-z0-9_]+);", "&\g<1>", output) + self.entries[-1][element] = output + if output: + self.entries[-1]['links'][-1]['href'] = output + else: + if element == 'description': + element = 'summary' + old_value_depth = self.property_depth_map.setdefault(self.entries[-1], {}).get(element) + if old_value_depth is None or self.depth <= old_value_depth: + self.property_depth_map[self.entries[-1]][element] = self.depth + self.entries[-1][element] = output + if self.incontent: + contentparams = copy.deepcopy(self.contentparams) + contentparams['value'] = output + self.entries[-1][element + '_detail'] = contentparams + elif (self.infeed or self.insource):# and (not self.intextinput) and (not self.inimage): + context = self._getContext() + if element == 'description': + element = 'subtitle' + context[element] = output + if element == 'link': + # fix query variables; see above for the explanation + output = re.sub("&([A-Za-z0-9_]+);", "&\g<1>", output) + context[element] = output + context['links'][-1]['href'] = output + elif self.incontent: + contentparams = copy.deepcopy(self.contentparams) + contentparams['value'] = output + context[element + '_detail'] = contentparams + return output + + def pushContent(self, tag, attrsD, defaultContentType, expectingText): + self.incontent += 1 + if self.lang: + self.lang=self.lang.replace('_','-') + self.contentparams = FeedParserDict({ + 'type': self.mapContentType(attrsD.get('type', defaultContentType)), + 'language': self.lang, + 'base': self.baseuri}) + self.contentparams['base64'] = self._isBase64(attrsD, self.contentparams) + self.push(tag, expectingText) + + def popContent(self, tag): + value = self.pop(tag) + self.incontent -= 1 + self.contentparams.clear() + return value + + # a number of elements in a number of RSS variants are nominally plain + # text, but this is routinely ignored. This is an attempt to detect + # the most common cases. As false positives often result in silent + # data loss, this function errs on the conservative side. + @staticmethod + def lookslikehtml(s): + # must have a close tag or an entity reference to qualify + if not (re.search(r'',s) or re.search("&#?\w+;",s)): + return + + # all tags must be in a restricted subset of valid HTML tags + if filter(lambda t: t.lower() not in _HTMLSanitizer.acceptable_elements, + re.findall(r' -1: + prefix = name[:colonpos] + suffix = name[colonpos+1:] + prefix = self.namespacemap.get(prefix, prefix) + name = prefix + ':' + suffix + return name + + def _getAttribute(self, attrsD, name): + return attrsD.get(self._mapToStandardPrefix(name)) + + def _isBase64(self, attrsD, contentparams): + if attrsD.get('mode', '') == 'base64': + return 1 + if self.contentparams['type'].startswith(u'text/'): + return 0 + if self.contentparams['type'].endswith(u'+xml'): + return 0 + if self.contentparams['type'].endswith(u'/xml'): + return 0 + return 1 + + def _itsAnHrefDamnIt(self, attrsD): + href = attrsD.get('url', attrsD.get('uri', attrsD.get('href', None))) + if href: + try: + del attrsD['url'] + except KeyError: + pass + try: + del attrsD['uri'] + except KeyError: + pass + attrsD['href'] = href + return attrsD + + def _save(self, key, value, overwrite=False): + context = self._getContext() + if overwrite: + context[key] = value + else: + context.setdefault(key, value) + + def _start_rss(self, attrsD): + versionmap = {'0.91': u'rss091u', + '0.92': u'rss092', + '0.93': u'rss093', + '0.94': u'rss094'} + #If we're here then this is an RSS feed. + #If we don't have a version or have a version that starts with something + #other than RSS then there's been a mistake. Correct it. + if not self.version or not self.version.startswith(u'rss'): + attr_version = attrsD.get('version', '') + version = versionmap.get(attr_version) + if version: + self.version = version + elif attr_version.startswith('2.'): + self.version = u'rss20' + else: + self.version = u'rss' + + def _start_channel(self, attrsD): + self.infeed = 1 + self._cdf_common(attrsD) + + def _cdf_common(self, attrsD): + if 'lastmod' in attrsD: + self._start_modified({}) + self.elementstack[-1][-1] = attrsD['lastmod'] + self._end_modified() + if 'href' in attrsD: + self._start_link({}) + self.elementstack[-1][-1] = attrsD['href'] + self._end_link() + + def _start_feed(self, attrsD): + self.infeed = 1 + versionmap = {'0.1': u'atom01', + '0.2': u'atom02', + '0.3': u'atom03'} + if not self.version: + attr_version = attrsD.get('version') + version = versionmap.get(attr_version) + if version: + self.version = version + else: + self.version = u'atom' + + def _end_channel(self): + self.infeed = 0 + _end_feed = _end_channel + + def _start_image(self, attrsD): + context = self._getContext() + if not self.inentry: + context.setdefault('image', FeedParserDict()) + self.inimage = 1 + self.title_depth = -1 + self.push('image', 0) + + def _end_image(self): + self.pop('image') + self.inimage = 0 + + def _start_textinput(self, attrsD): + context = self._getContext() + context.setdefault('textinput', FeedParserDict()) + self.intextinput = 1 + self.title_depth = -1 + self.push('textinput', 0) + _start_textInput = _start_textinput + + def _end_textinput(self): + self.pop('textinput') + self.intextinput = 0 + _end_textInput = _end_textinput + + def _start_author(self, attrsD): + self.inauthor = 1 + self.push('author', 1) + # Append a new FeedParserDict when expecting an author + context = self._getContext() + context.setdefault('authors', []) + context['authors'].append(FeedParserDict()) + _start_managingeditor = _start_author + _start_dc_author = _start_author + _start_dc_creator = _start_author + _start_itunes_author = _start_author + + def _end_author(self): + self.pop('author') + self.inauthor = 0 + self._sync_author_detail() + _end_managingeditor = _end_author + _end_dc_author = _end_author + _end_dc_creator = _end_author + _end_itunes_author = _end_author + + def _start_itunes_owner(self, attrsD): + self.inpublisher = 1 + self.push('publisher', 0) + + def _end_itunes_owner(self): + self.pop('publisher') + self.inpublisher = 0 + self._sync_author_detail('publisher') + + def _start_contributor(self, attrsD): + self.incontributor = 1 + context = self._getContext() + context.setdefault('contributors', []) + context['contributors'].append(FeedParserDict()) + self.push('contributor', 0) + + def _end_contributor(self): + self.pop('contributor') + self.incontributor = 0 + + def _start_dc_contributor(self, attrsD): + self.incontributor = 1 + context = self._getContext() + context.setdefault('contributors', []) + context['contributors'].append(FeedParserDict()) + self.push('name', 0) + + def _end_dc_contributor(self): + self._end_name() + self.incontributor = 0 + + def _start_name(self, attrsD): + self.push('name', 0) + _start_itunes_name = _start_name + + def _end_name(self): + value = self.pop('name') + if self.inpublisher: + self._save_author('name', value, 'publisher') + elif self.inauthor: + self._save_author('name', value) + elif self.incontributor: + self._save_contributor('name', value) + elif self.intextinput: + context = self._getContext() + context['name'] = value + _end_itunes_name = _end_name + + def _start_width(self, attrsD): + self.push('width', 0) + + def _end_width(self): + value = self.pop('width') + try: + value = int(value) + except ValueError: + value = 0 + if self.inimage: + context = self._getContext() + context['width'] = value + + def _start_height(self, attrsD): + self.push('height', 0) + + def _end_height(self): + value = self.pop('height') + try: + value = int(value) + except ValueError: + value = 0 + if self.inimage: + context = self._getContext() + context['height'] = value + + def _start_url(self, attrsD): + self.push('href', 1) + _start_homepage = _start_url + _start_uri = _start_url + + def _end_url(self): + value = self.pop('href') + if self.inauthor: + self._save_author('href', value) + elif self.incontributor: + self._save_contributor('href', value) + _end_homepage = _end_url + _end_uri = _end_url + + def _start_email(self, attrsD): + self.push('email', 0) + _start_itunes_email = _start_email + + def _end_email(self): + value = self.pop('email') + if self.inpublisher: + self._save_author('email', value, 'publisher') + elif self.inauthor: + self._save_author('email', value) + elif self.incontributor: + self._save_contributor('email', value) + _end_itunes_email = _end_email + + def _getContext(self): + if self.insource: + context = self.sourcedata + elif self.inimage and 'image' in self.feeddata: + context = self.feeddata['image'] + elif self.intextinput: + context = self.feeddata['textinput'] + elif self.inentry: + context = self.entries[-1] + else: + context = self.feeddata + return context + + def _save_author(self, key, value, prefix='author'): + context = self._getContext() + context.setdefault(prefix + '_detail', FeedParserDict()) + context[prefix + '_detail'][key] = value + self._sync_author_detail() + context.setdefault('authors', [FeedParserDict()]) + context['authors'][-1][key] = value + + def _save_contributor(self, key, value): + context = self._getContext() + context.setdefault('contributors', [FeedParserDict()]) + context['contributors'][-1][key] = value + + def _sync_author_detail(self, key='author'): + context = self._getContext() + detail = context.get('%ss' % key, [FeedParserDict()])[-1] + if detail: + name = detail.get('name') + email = detail.get('email') + if name and email: + context[key] = u'%s (%s)' % (name, email) + elif name: + context[key] = name + elif email: + context[key] = email + else: + author, email = context.get(key), None + if not author: + return + emailmatch = re.search(ur'''(([a-zA-Z0-9\_\-\.\+]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?))(\?subject=\S+)?''', author) + if emailmatch: + email = emailmatch.group(0) + # probably a better way to do the following, but it passes all the tests + author = author.replace(email, u'') + author = author.replace(u'()', u'') + author = author.replace(u'<>', u'') + author = author.replace(u'<>', u'') + author = author.strip() + if author and (author[0] == u'('): + author = author[1:] + if author and (author[-1] == u')'): + author = author[:-1] + author = author.strip() + if author or email: + context.setdefault('%s_detail' % key, detail) + if author: + detail['name'] = author + if email: + detail['email'] = email + + def _start_subtitle(self, attrsD): + self.pushContent('subtitle', attrsD, u'text/plain', 1) + _start_tagline = _start_subtitle + _start_itunes_subtitle = _start_subtitle + + def _end_subtitle(self): + self.popContent('subtitle') + _end_tagline = _end_subtitle + _end_itunes_subtitle = _end_subtitle + + def _start_rights(self, attrsD): + self.pushContent('rights', attrsD, u'text/plain', 1) + _start_dc_rights = _start_rights + _start_copyright = _start_rights + + def _end_rights(self): + self.popContent('rights') + _end_dc_rights = _end_rights + _end_copyright = _end_rights + + def _start_item(self, attrsD): + self.entries.append(FeedParserDict()) + self.push('item', 0) + self.inentry = 1 + self.guidislink = 0 + self.title_depth = -1 + self.psc_chapters_flag = None + id = self._getAttribute(attrsD, 'rdf:about') + if id: + context = self._getContext() + context['id'] = id + self._cdf_common(attrsD) + _start_entry = _start_item + + def _end_item(self): + self.pop('item') + self.inentry = 0 + _end_entry = _end_item + + def _start_dc_language(self, attrsD): + self.push('language', 1) + _start_language = _start_dc_language + + def _end_dc_language(self): + self.lang = self.pop('language') + _end_language = _end_dc_language + + def _start_dc_publisher(self, attrsD): + self.push('publisher', 1) + _start_webmaster = _start_dc_publisher + + def _end_dc_publisher(self): + self.pop('publisher') + self._sync_author_detail('publisher') + _end_webmaster = _end_dc_publisher + + def _start_dcterms_valid(self, attrsD): + self.push('validity', 1) + + def _end_dcterms_valid(self): + for validity_detail in self.pop('validity').split(';'): + if '=' in validity_detail: + key, value = validity_detail.split('=', 1) + if key == 'start': + self._save('validity_start', value, overwrite=True) + self._save('validity_start_parsed', _parse_date(value), overwrite=True) + elif key == 'end': + self._save('validity_end', value, overwrite=True) + self._save('validity_end_parsed', _parse_date(value), overwrite=True) + + def _start_published(self, attrsD): + self.push('published', 1) + _start_dcterms_issued = _start_published + _start_issued = _start_published + _start_pubdate = _start_published + + def _end_published(self): + value = self.pop('published') + self._save('published_parsed', _parse_date(value), overwrite=True) + _end_dcterms_issued = _end_published + _end_issued = _end_published + _end_pubdate = _end_published + + def _start_updated(self, attrsD): + self.push('updated', 1) + _start_modified = _start_updated + _start_dcterms_modified = _start_updated + _start_dc_date = _start_updated + _start_lastbuilddate = _start_updated + + def _end_updated(self): + value = self.pop('updated') + parsed_value = _parse_date(value) + self._save('updated_parsed', parsed_value, overwrite=True) + _end_modified = _end_updated + _end_dcterms_modified = _end_updated + _end_dc_date = _end_updated + _end_lastbuilddate = _end_updated + + def _start_created(self, attrsD): + self.push('created', 1) + _start_dcterms_created = _start_created + + def _end_created(self): + value = self.pop('created') + self._save('created_parsed', _parse_date(value), overwrite=True) + _end_dcterms_created = _end_created + + def _start_expirationdate(self, attrsD): + self.push('expired', 1) + + def _end_expirationdate(self): + self._save('expired_parsed', _parse_date(self.pop('expired')), overwrite=True) + + # geospatial location, or "where", from georss.org + + def _start_georssgeom(self, attrsD): + self.push('geometry', 0) + context = self._getContext() + context['where'] = FeedParserDict() + + _start_georss_point = _start_georssgeom + _start_georss_line = _start_georssgeom + _start_georss_polygon = _start_georssgeom + _start_georss_box = _start_georssgeom + + def _save_where(self, geometry): + context = self._getContext() + context['where'].update(geometry) + + def _end_georss_point(self): + geometry = _parse_georss_point(self.pop('geometry')) + if geometry: + self._save_where(geometry) + + def _end_georss_line(self): + geometry = _parse_georss_line(self.pop('geometry')) + if geometry: + self._save_where(geometry) + + def _end_georss_polygon(self): + this = self.pop('geometry') + geometry = _parse_georss_polygon(this) + if geometry: + self._save_where(geometry) + + def _end_georss_box(self): + geometry = _parse_georss_box(self.pop('geometry')) + if geometry: + self._save_where(geometry) + + def _start_where(self, attrsD): + self.push('where', 0) + context = self._getContext() + context['where'] = FeedParserDict() + _start_georss_where = _start_where + + def _parse_srs_attrs(self, attrsD): + srsName = attrsD.get('srsname') + try: + srsDimension = int(attrsD.get('srsdimension', '2')) + except ValueError: + srsDimension = 2 + context = self._getContext() + context['where']['srsName'] = srsName + context['where']['srsDimension'] = srsDimension + + def _start_gml_point(self, attrsD): + self._parse_srs_attrs(attrsD) + self.ingeometry = 1 + self.push('geometry', 0) + + def _start_gml_linestring(self, attrsD): + self._parse_srs_attrs(attrsD) + self.ingeometry = 'linestring' + self.push('geometry', 0) + + def _start_gml_polygon(self, attrsD): + self._parse_srs_attrs(attrsD) + self.push('geometry', 0) + + def _start_gml_exterior(self, attrsD): + self.push('geometry', 0) + + def _start_gml_linearring(self, attrsD): + self.ingeometry = 'polygon' + self.push('geometry', 0) + + def _start_gml_pos(self, attrsD): + self.push('pos', 0) + + def _end_gml_pos(self): + this = self.pop('pos') + context = self._getContext() + srsName = context['where'].get('srsName') + srsDimension = context['where'].get('srsDimension', 2) + swap = True + if srsName and "EPSG" in srsName: + epsg = int(srsName.split(":")[-1]) + swap = bool(epsg in _geogCS) + geometry = _parse_georss_point(this, swap=swap, dims=srsDimension) + if geometry: + self._save_where(geometry) + + def _start_gml_poslist(self, attrsD): + self.push('pos', 0) + + def _end_gml_poslist(self): + this = self.pop('pos') + context = self._getContext() + srsName = context['where'].get('srsName') + srsDimension = context['where'].get('srsDimension', 2) + swap = True + if srsName and "EPSG" in srsName: + epsg = int(srsName.split(":")[-1]) + swap = bool(epsg in _geogCS) + geometry = _parse_poslist( + this, self.ingeometry, swap=swap, dims=srsDimension) + if geometry: + self._save_where(geometry) + + def _end_geom(self): + self.ingeometry = 0 + self.pop('geometry') + _end_gml_point = _end_geom + _end_gml_linestring = _end_geom + _end_gml_linearring = _end_geom + _end_gml_exterior = _end_geom + _end_gml_polygon = _end_geom + + def _end_where(self): + self.pop('where') + _end_georss_where = _end_where + + # end geospatial + + def _start_cc_license(self, attrsD): + context = self._getContext() + value = self._getAttribute(attrsD, 'rdf:resource') + attrsD = FeedParserDict() + attrsD['rel'] = u'license' + if value: + attrsD['href']=value + context.setdefault('links', []).append(attrsD) + + def _start_creativecommons_license(self, attrsD): + self.push('license', 1) + _start_creativeCommons_license = _start_creativecommons_license + + def _end_creativecommons_license(self): + value = self.pop('license') + context = self._getContext() + attrsD = FeedParserDict() + attrsD['rel'] = u'license' + if value: + attrsD['href'] = value + context.setdefault('links', []).append(attrsD) + del context['license'] + _end_creativeCommons_license = _end_creativecommons_license + + def _addTag(self, term, scheme, label): + context = self._getContext() + tags = context.setdefault('tags', []) + if (not term) and (not scheme) and (not label): + return + value = FeedParserDict(term=term, scheme=scheme, label=label) + if value not in tags: + tags.append(value) + + def _start_tags(self, attrsD): + # This is a completely-made up element. Its semantics are determined + # only by a single feed that precipitated bug report 392 on Google Code. + # In short, this is junk code. + self.push('tags', 1) + + def _end_tags(self): + for term in self.pop('tags').split(','): + self._addTag(term.strip(), None, None) + + def _start_category(self, attrsD): + term = attrsD.get('term') + scheme = attrsD.get('scheme', attrsD.get('domain')) + label = attrsD.get('label') + self._addTag(term, scheme, label) + self.push('category', 1) + _start_dc_subject = _start_category + _start_keywords = _start_category + + def _start_media_category(self, attrsD): + attrsD.setdefault('scheme', u'http://search.yahoo.com/mrss/category_schema') + self._start_category(attrsD) + + def _end_itunes_keywords(self): + for term in self.pop('itunes_keywords').split(','): + if term.strip(): + self._addTag(term.strip(), u'http://www.itunes.com/', None) + + def _end_media_keywords(self): + for term in self.pop('media_keywords').split(','): + if term.strip(): + self._addTag(term.strip(), None, None) + + def _start_itunes_category(self, attrsD): + self._addTag(attrsD.get('text'), u'http://www.itunes.com/', None) + self.push('category', 1) + + def _end_category(self): + value = self.pop('category') + if not value: + return + context = self._getContext() + tags = context['tags'] + if value and len(tags) and not tags[-1]['term']: + tags[-1]['term'] = value + else: + self._addTag(value, None, None) + _end_dc_subject = _end_category + _end_keywords = _end_category + _end_itunes_category = _end_category + _end_media_category = _end_category + + def _start_cloud(self, attrsD): + self._getContext()['cloud'] = FeedParserDict(attrsD) + + def _start_link(self, attrsD): + attrsD.setdefault('rel', u'alternate') + if attrsD['rel'] == u'self': + attrsD.setdefault('type', u'application/atom+xml') + else: + attrsD.setdefault('type', u'text/html') + context = self._getContext() + attrsD = self._itsAnHrefDamnIt(attrsD) + if 'href' in attrsD: + attrsD['href'] = self.resolveURI(attrsD['href']) + expectingText = self.infeed or self.inentry or self.insource + context.setdefault('links', []) + if not (self.inentry and self.inimage): + context['links'].append(FeedParserDict(attrsD)) + if 'href' in attrsD: + expectingText = 0 + if (attrsD.get('rel') == u'alternate') and (self.mapContentType(attrsD.get('type')) in self.html_types): + context['link'] = attrsD['href'] + else: + self.push('link', expectingText) + + def _end_link(self): + value = self.pop('link') + + def _start_guid(self, attrsD): + self.guidislink = (attrsD.get('ispermalink', 'true') == 'true') + self.push('id', 1) + _start_id = _start_guid + + def _end_guid(self): + value = self.pop('id') + self._save('guidislink', self.guidislink and 'link' not in self._getContext()) + if self.guidislink: + # guid acts as link, but only if 'ispermalink' is not present or is 'true', + # and only if the item doesn't already have a link element + self._save('link', value) + _end_id = _end_guid + + def _start_title(self, attrsD): + if self.svgOK: + return self.unknown_starttag('title', attrsD.items()) + self.pushContent('title', attrsD, u'text/plain', self.infeed or self.inentry or self.insource) + _start_dc_title = _start_title + _start_media_title = _start_title + + def _end_title(self): + if self.svgOK: + return + value = self.popContent('title') + if not value: + return + self.title_depth = self.depth + _end_dc_title = _end_title + + def _end_media_title(self): + title_depth = self.title_depth + self._end_title() + self.title_depth = title_depth + + def _start_description(self, attrsD): + context = self._getContext() + if 'summary' in context: + self._summaryKey = 'content' + self._start_content(attrsD) + else: + self.pushContent('description', attrsD, u'text/html', self.infeed or self.inentry or self.insource) + _start_dc_description = _start_description + _start_media_description = _start_description + + def _start_abstract(self, attrsD): + self.pushContent('description', attrsD, u'text/plain', self.infeed or self.inentry or self.insource) + + def _end_description(self): + if self._summaryKey == 'content': + self._end_content() + else: + value = self.popContent('description') + self._summaryKey = None + _end_abstract = _end_description + _end_dc_description = _end_description + _end_media_description = _end_description + + def _start_info(self, attrsD): + self.pushContent('info', attrsD, u'text/plain', 1) + _start_feedburner_browserfriendly = _start_info + + def _end_info(self): + self.popContent('info') + _end_feedburner_browserfriendly = _end_info + + def _start_generator(self, attrsD): + if attrsD: + attrsD = self._itsAnHrefDamnIt(attrsD) + if 'href' in attrsD: + attrsD['href'] = self.resolveURI(attrsD['href']) + self._getContext()['generator_detail'] = FeedParserDict(attrsD) + self.push('generator', 1) + + def _end_generator(self): + value = self.pop('generator') + context = self._getContext() + if 'generator_detail' in context: + context['generator_detail']['name'] = value + + def _start_admin_generatoragent(self, attrsD): + self.push('generator', 1) + value = self._getAttribute(attrsD, 'rdf:resource') + if value: + self.elementstack[-1][2].append(value) + self.pop('generator') + self._getContext()['generator_detail'] = FeedParserDict({'href': value}) + + def _start_admin_errorreportsto(self, attrsD): + self.push('errorreportsto', 1) + value = self._getAttribute(attrsD, 'rdf:resource') + if value: + self.elementstack[-1][2].append(value) + self.pop('errorreportsto') + + def _start_summary(self, attrsD): + context = self._getContext() + if 'summary' in context: + self._summaryKey = 'content' + self._start_content(attrsD) + else: + self._summaryKey = 'summary' + self.pushContent(self._summaryKey, attrsD, u'text/plain', 1) + _start_itunes_summary = _start_summary + + def _end_summary(self): + if self._summaryKey == 'content': + self._end_content() + else: + self.popContent(self._summaryKey or 'summary') + self._summaryKey = None + _end_itunes_summary = _end_summary + + def _start_enclosure(self, attrsD): + attrsD = self._itsAnHrefDamnIt(attrsD) + context = self._getContext() + attrsD['rel'] = u'enclosure' + context.setdefault('links', []).append(FeedParserDict(attrsD)) + + def _start_source(self, attrsD): + if 'url' in attrsD: + # This means that we're processing a source element from an RSS 2.0 feed + self.sourcedata['href'] = attrsD[u'url'] + self.push('source', 1) + self.insource = 1 + self.title_depth = -1 + + def _end_source(self): + self.insource = 0 + value = self.pop('source') + if value: + self.sourcedata['title'] = value + self._getContext()['source'] = copy.deepcopy(self.sourcedata) + self.sourcedata.clear() + + def _start_content(self, attrsD): + self.pushContent('content', attrsD, u'text/plain', 1) + src = attrsD.get('src') + if src: + self.contentparams['src'] = src + self.push('content', 1) + + def _start_body(self, attrsD): + self.pushContent('content', attrsD, u'application/xhtml+xml', 1) + _start_xhtml_body = _start_body + + def _start_content_encoded(self, attrsD): + self.pushContent('content', attrsD, u'text/html', 1) + _start_fullitem = _start_content_encoded + + def _end_content(self): + copyToSummary = self.mapContentType(self.contentparams.get('type')) in ([u'text/plain'] + self.html_types) + value = self.popContent('content') + if copyToSummary: + self._save('summary', value) + + _end_body = _end_content + _end_xhtml_body = _end_content + _end_content_encoded = _end_content + _end_fullitem = _end_content + + def _start_itunes_image(self, attrsD): + self.push('itunes_image', 0) + if attrsD.get('href'): + self._getContext()['image'] = FeedParserDict({'href': attrsD.get('href')}) + elif attrsD.get('url'): + self._getContext()['image'] = FeedParserDict({'href': attrsD.get('url')}) + _start_itunes_link = _start_itunes_image + + def _end_itunes_block(self): + value = self.pop('itunes_block', 0) + self._getContext()['itunes_block'] = (value == 'yes') and 1 or 0 + + def _end_itunes_explicit(self): + value = self.pop('itunes_explicit', 0) + # Convert 'yes' -> True, 'clean' to False, and any other value to None + # False and None both evaluate as False, so the difference can be ignored + # by applications that only need to know if the content is explicit. + self._getContext()['itunes_explicit'] = (None, False, True)[(value == 'yes' and 2) or value == 'clean' or 0] + + def _start_media_group(self, attrsD): + # don't do anything, but don't break the enclosed tags either + pass + + def _start_media_rating(self, attrsD): + context = self._getContext() + context.setdefault('media_rating', attrsD) + self.push('rating', 1) + + def _end_media_rating(self): + rating = self.pop('rating') + if rating is not None and rating.strip(): + context = self._getContext() + context['media_rating']['content'] = rating + + def _start_media_credit(self, attrsD): + context = self._getContext() + context.setdefault('media_credit', []) + context['media_credit'].append(attrsD) + self.push('credit', 1) + + def _end_media_credit(self): + credit = self.pop('credit') + if credit != None and len(credit.strip()) != 0: + context = self._getContext() + context['media_credit'][-1]['content'] = credit + + def _start_media_restriction(self, attrsD): + context = self._getContext() + context.setdefault('media_restriction', attrsD) + self.push('restriction', 1) + + def _end_media_restriction(self): + restriction = self.pop('restriction') + if restriction != None and len(restriction.strip()) != 0: + context = self._getContext() + context['media_restriction']['content'] = [cc.strip().lower() for cc in restriction.split(' ')] + + def _start_media_license(self, attrsD): + context = self._getContext() + context.setdefault('media_license', attrsD) + self.push('license', 1) + + def _end_media_license(self): + license = self.pop('license') + if license != None and len(license.strip()) != 0: + context = self._getContext() + context['media_license']['content'] = license + + def _start_media_content(self, attrsD): + context = self._getContext() + context.setdefault('media_content', []) + context['media_content'].append(attrsD) + + def _start_media_thumbnail(self, attrsD): + context = self._getContext() + context.setdefault('media_thumbnail', []) + self.push('url', 1) # new + context['media_thumbnail'].append(attrsD) + + def _end_media_thumbnail(self): + url = self.pop('url') + context = self._getContext() + if url != None and len(url.strip()) != 0: + if 'url' not in context['media_thumbnail'][-1]: + context['media_thumbnail'][-1]['url'] = url + + def _start_media_player(self, attrsD): + self.push('media_player', 0) + self._getContext()['media_player'] = FeedParserDict(attrsD) + + def _end_media_player(self): + value = self.pop('media_player') + context = self._getContext() + context['media_player']['content'] = value + + def _start_newlocation(self, attrsD): + self.push('newlocation', 1) + + def _end_newlocation(self): + url = self.pop('newlocation') + context = self._getContext() + # don't set newlocation if the context isn't right + if context is not self.feeddata: + return + context['newlocation'] = _makeSafeAbsoluteURI(self.baseuri, url.strip()) + + def _start_psc_chapters(self, attrsD): + if self.psc_chapters_flag is None: + # Transition from None -> True + self.psc_chapters_flag = True + attrsD['chapters'] = [] + self._getContext()['psc_chapters'] = FeedParserDict(attrsD) + + def _end_psc_chapters(self): + # Transition from True -> False + self.psc_chapters_flag = False + + def _start_psc_chapter(self, attrsD): + if self.psc_chapters_flag: + start = self._getAttribute(attrsD, 'start') + attrsD['start_parsed'] = _parse_psc_chapter_start(start) + + context = self._getContext()['psc_chapters'] + context['chapters'].append(FeedParserDict(attrsD)) + + +if _XML_AVAILABLE: + class _StrictFeedParser(_FeedParserMixin, xml.sax.handler.ContentHandler): + def __init__(self, baseuri, baselang, encoding): + xml.sax.handler.ContentHandler.__init__(self) + _FeedParserMixin.__init__(self, baseuri, baselang, encoding) + self.bozo = 0 + self.exc = None + self.decls = {} + + def startPrefixMapping(self, prefix, uri): + if not uri: + return + # Jython uses '' instead of None; standardize on None + prefix = prefix or None + self.trackNamespace(prefix, uri) + if prefix and uri == 'http://www.w3.org/1999/xlink': + self.decls['xmlns:' + prefix] = uri + + def startElementNS(self, name, qname, attrs): + namespace, localname = name + lowernamespace = str(namespace or '').lower() + if lowernamespace.find(u'backend.userland.com/rss') <> -1: + # match any backend.userland.com namespace + namespace = u'http://backend.userland.com/rss' + lowernamespace = namespace + if qname and qname.find(':') > 0: + givenprefix = qname.split(':')[0] + else: + givenprefix = None + prefix = self._matchnamespaces.get(lowernamespace, givenprefix) + if givenprefix and (prefix == None or (prefix == '' and lowernamespace == '')) and givenprefix not in self.namespacesInUse: + raise UndeclaredNamespace, "'%s' is not associated with a namespace" % givenprefix + localname = str(localname).lower() + + # qname implementation is horribly broken in Python 2.1 (it + # doesn't report any), and slightly broken in Python 2.2 (it + # doesn't report the xml: namespace). So we match up namespaces + # with a known list first, and then possibly override them with + # the qnames the SAX parser gives us (if indeed it gives us any + # at all). Thanks to MatejC for helping me test this and + # tirelessly telling me that it didn't work yet. + attrsD, self.decls = self.decls, {} + if localname=='math' and namespace=='http://www.w3.org/1998/Math/MathML': + attrsD['xmlns']=namespace + if localname=='svg' and namespace=='http://www.w3.org/2000/svg': + attrsD['xmlns']=namespace + + if prefix: + localname = prefix.lower() + ':' + localname + elif namespace and not qname: #Expat + for name,value in self.namespacesInUse.items(): + if name and value == namespace: + localname = name + ':' + localname + break + + for (namespace, attrlocalname), attrvalue in attrs.items(): + lowernamespace = (namespace or '').lower() + prefix = self._matchnamespaces.get(lowernamespace, '') + if prefix: + attrlocalname = prefix + ':' + attrlocalname + attrsD[str(attrlocalname).lower()] = attrvalue + for qname in attrs.getQNames(): + attrsD[str(qname).lower()] = attrs.getValueByQName(qname) + localname = str(localname).lower() + self.unknown_starttag(localname, attrsD.items()) + + def characters(self, text): + self.handle_data(text) + + def endElementNS(self, name, qname): + namespace, localname = name + lowernamespace = str(namespace or '').lower() + if qname and qname.find(':') > 0: + givenprefix = qname.split(':')[0] + else: + givenprefix = '' + prefix = self._matchnamespaces.get(lowernamespace, givenprefix) + if prefix: + localname = prefix + ':' + localname + elif namespace and not qname: #Expat + for name,value in self.namespacesInUse.items(): + if name and value == namespace: + localname = name + ':' + localname + break + localname = str(localname).lower() + self.unknown_endtag(localname) + + def error(self, exc): + self.bozo = 1 + self.exc = exc + + # drv_libxml2 calls warning() in some cases + warning = error + + def fatalError(self, exc): + self.error(exc) + raise exc + +class _BaseHTMLProcessor(sgmllib.SGMLParser): + special = re.compile('''[<>'"]''') + bare_ampersand = re.compile("&(?!#\d+;|#x[0-9a-fA-F]+;|\w+;)") + elements_no_end_tag = set([ + 'area', 'base', 'basefont', 'br', 'col', 'command', 'embed', 'frame', + 'hr', 'img', 'input', 'isindex', 'keygen', 'link', 'meta', 'param', + 'source', 'track', 'wbr' + ]) + + def __init__(self, encoding, _type): + self.encoding = encoding + self._type = _type + sgmllib.SGMLParser.__init__(self) + + def reset(self): + self.pieces = [] + sgmllib.SGMLParser.reset(self) + + def _shorttag_replace(self, match): + tag = match.group(1) + if tag in self.elements_no_end_tag: + return '<' + tag + ' />' + else: + return '<' + tag + '>' + + # By declaring these methods and overriding their compiled code + # with the code from sgmllib, the original code will execute in + # feedparser's scope instead of sgmllib's. This means that the + # `tagfind` and `charref` regular expressions will be found as + # they're declared above, not as they're declared in sgmllib. + def goahead(self, i): + pass + goahead.func_code = sgmllib.SGMLParser.goahead.func_code + + def __parse_starttag(self, i): + pass + __parse_starttag.func_code = sgmllib.SGMLParser.parse_starttag.func_code + + def parse_starttag(self,i): + j = self.__parse_starttag(i) + if self._type == 'application/xhtml+xml': + if j>2 and self.rawdata[j-2:j]=='/>': + self.unknown_endtag(self.lasttag) + return j + + def feed(self, data): + data = re.compile(r'\s]+?)\s*/>', self._shorttag_replace, data) + data = data.replace(''', "'") + data = data.replace('"', '"') + try: + bytes + if bytes is str: + raise NameError + self.encoding = self.encoding + u'_INVALID_PYTHON_3' + except NameError: + if self.encoding and isinstance(data, unicode): + data = data.encode(self.encoding) + sgmllib.SGMLParser.feed(self, data) + sgmllib.SGMLParser.close(self) + + def normalize_attrs(self, attrs): + if not attrs: + return attrs + # utility method to be called by descendants + attrs = dict([(k.lower(), v) for k, v in attrs]).items() + attrs = [(k, k in ('rel', 'type') and v.lower() or v) for k, v in attrs] + attrs.sort() + return attrs + + def unknown_starttag(self, tag, attrs): + # called for each start tag + # attrs is a list of (attr, value) tuples + # e.g. for
    , tag='pre', attrs=[('class', 'screen')]
    +        uattrs = []
    +        strattrs=''
    +        if attrs:
    +            for key, value in attrs:
    +                value=value.replace('>','>').replace('<','<').replace('"','"')
    +                value = self.bare_ampersand.sub("&", value)
    +                # thanks to Kevin Marks for this breathtaking hack to deal with (valid) high-bit attribute values in UTF-8 feeds
    +                if not isinstance(value, unicode):
    +                    value = value.decode(self.encoding, 'ignore')
    +                try:
    +                    # Currently, in Python 3 the key is already a str, and cannot be decoded again
    +                    uattrs.append((unicode(key, self.encoding), value))
    +                except TypeError:
    +                    uattrs.append((key, value))
    +            strattrs = u''.join([u' %s="%s"' % (key, value) for key, value in uattrs])
    +            if self.encoding:
    +                try:
    +                    strattrs = strattrs.encode(self.encoding)
    +                except (UnicodeEncodeError, LookupError):
    +                    pass
    +        if tag in self.elements_no_end_tag:
    +            self.pieces.append('<%s%s />' % (tag, strattrs))
    +        else:
    +            self.pieces.append('<%s%s>' % (tag, strattrs))
    +
    +    def unknown_endtag(self, tag):
    +        # called for each end tag, e.g. for 
    , tag will be 'pre' + # Reconstruct the original end tag. + if tag not in self.elements_no_end_tag: + self.pieces.append("" % tag) + + def handle_charref(self, ref): + # called for each character reference, e.g. for ' ', ref will be '160' + # Reconstruct the original character reference. + ref = ref.lower() + if ref.startswith('x'): + value = int(ref[1:], 16) + else: + value = int(ref) + + if value in _cp1252: + self.pieces.append('&#%s;' % hex(ord(_cp1252[value]))[1:]) + else: + self.pieces.append('&#%s;' % ref) + + def handle_entityref(self, ref): + # called for each entity reference, e.g. for '©', ref will be 'copy' + # Reconstruct the original entity reference. + if ref in name2codepoint or ref == 'apos': + self.pieces.append('&%s;' % ref) + else: + self.pieces.append('&%s' % ref) + + def handle_data(self, text): + # called for each block of plain text, i.e. outside of any tag and + # not containing any character or entity references + # Store the original text verbatim. + self.pieces.append(text) + + def handle_comment(self, text): + # called for each HTML comment, e.g. + # Reconstruct the original comment. + self.pieces.append('' % text) + + def handle_pi(self, text): + # called for each processing instruction, e.g. + # Reconstruct original processing instruction. + self.pieces.append('' % text) + + def handle_decl(self, text): + # called for the DOCTYPE, if present, e.g. + # + # Reconstruct original DOCTYPE + self.pieces.append('' % text) + + _new_declname_match = re.compile(r'[a-zA-Z][-_.a-zA-Z0-9:]*\s*').match + def _scan_name(self, i, declstartpos): + rawdata = self.rawdata + n = len(rawdata) + if i == n: + return None, -1 + m = self._new_declname_match(rawdata, i) + if m: + s = m.group() + name = s.strip() + if (i + len(s)) == n: + return None, -1 # end of buffer + return name.lower(), m.end() + else: + self.handle_data(rawdata) +# self.updatepos(declstartpos, i) + return None, -1 + + def convert_charref(self, name): + return '&#%s;' % name + + def convert_entityref(self, name): + return '&%s;' % name + + def output(self): + '''Return processed HTML as a single string''' + return ''.join([str(p) for p in self.pieces]) + + def parse_declaration(self, i): + try: + return sgmllib.SGMLParser.parse_declaration(self, i) + except sgmllib.SGMLParseError: + # escape the doctype declaration and continue parsing + self.handle_data('<') + return i+1 + +class _LooseFeedParser(_FeedParserMixin, _BaseHTMLProcessor): + def __init__(self, baseuri, baselang, encoding, entities): + sgmllib.SGMLParser.__init__(self) + _FeedParserMixin.__init__(self, baseuri, baselang, encoding) + _BaseHTMLProcessor.__init__(self, encoding, 'application/xhtml+xml') + self.entities=entities + + def decodeEntities(self, element, data): + data = data.replace('<', '<') + data = data.replace('<', '<') + data = data.replace('<', '<') + data = data.replace('>', '>') + data = data.replace('>', '>') + data = data.replace('>', '>') + data = data.replace('&', '&') + data = data.replace('&', '&') + data = data.replace('"', '"') + data = data.replace('"', '"') + data = data.replace(''', ''') + data = data.replace(''', ''') + if not self.contentparams.get('type', u'xml').endswith(u'xml'): + data = data.replace('<', '<') + data = data.replace('>', '>') + data = data.replace('&', '&') + data = data.replace('"', '"') + data = data.replace(''', "'") + data = data.replace('/', '/') + data = data.replace('/', '/') + return data + + def strattrs(self, attrs): + return ''.join([' %s="%s"' % (n,v.replace('"','"')) for n,v in attrs]) + +class _RelativeURIResolver(_BaseHTMLProcessor): + relative_uris = set([('a', 'href'), + ('applet', 'codebase'), + ('area', 'href'), + ('audio', 'src'), + ('blockquote', 'cite'), + ('body', 'background'), + ('del', 'cite'), + ('form', 'action'), + ('frame', 'longdesc'), + ('frame', 'src'), + ('iframe', 'longdesc'), + ('iframe', 'src'), + ('head', 'profile'), + ('img', 'longdesc'), + ('img', 'src'), + ('img', 'usemap'), + ('input', 'src'), + ('input', 'usemap'), + ('ins', 'cite'), + ('link', 'href'), + ('object', 'classid'), + ('object', 'codebase'), + ('object', 'data'), + ('object', 'usemap'), + ('q', 'cite'), + ('script', 'src'), + ('source', 'src'), + ('video', 'poster'), + ('video', 'src')]) + + def __init__(self, baseuri, encoding, _type): + _BaseHTMLProcessor.__init__(self, encoding, _type) + self.baseuri = baseuri + + def resolveURI(self, uri): + return _makeSafeAbsoluteURI(self.baseuri, uri.strip()) + + def unknown_starttag(self, tag, attrs): + attrs = self.normalize_attrs(attrs) + attrs = [(key, ((tag, key) in self.relative_uris) and self.resolveURI(value) or value) for key, value in attrs] + _BaseHTMLProcessor.unknown_starttag(self, tag, attrs) + +def _resolveRelativeURIs(htmlSource, baseURI, encoding, _type): + if not _SGML_AVAILABLE: + return htmlSource + + p = _RelativeURIResolver(baseURI, encoding, _type) + p.feed(htmlSource) + return p.output() + +def _makeSafeAbsoluteURI(base, rel=None): + # bail if ACCEPTABLE_URI_SCHEMES is empty + if not ACCEPTABLE_URI_SCHEMES: + return _urljoin(base, rel or u'') + if not base: + return rel or u'' + if not rel: + try: + scheme = urlparse.urlparse(base)[0] + except ValueError: + return u'' + if not scheme or scheme in ACCEPTABLE_URI_SCHEMES: + return base + return u'' + uri = _urljoin(base, rel) + if uri.strip().split(':', 1)[0] not in ACCEPTABLE_URI_SCHEMES: + return u'' + return uri + +class _HTMLSanitizer(_BaseHTMLProcessor): + acceptable_elements = set(['a', 'abbr', 'acronym', 'address', 'area', + 'article', 'aside', 'audio', 'b', 'big', 'blockquote', 'br', 'button', + 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', + 'command', 'datagrid', 'datalist', 'dd', 'del', 'details', 'dfn', + 'dialog', 'dir', 'div', 'dl', 'dt', 'em', 'event-source', 'fieldset', + 'figcaption', 'figure', 'footer', 'font', 'form', 'header', 'h1', + 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'input', 'ins', + 'keygen', 'kbd', 'label', 'legend', 'li', 'm', 'map', 'menu', 'meter', + 'multicol', 'nav', 'nextid', 'ol', 'output', 'optgroup', 'option', + 'p', 'pre', 'progress', 'q', 's', 'samp', 'section', 'select', + 'small', 'sound', 'source', 'spacer', 'span', 'strike', 'strong', + 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'time', 'tfoot', + 'th', 'thead', 'tr', 'tt', 'u', 'ul', 'var', 'video', 'noscript']) + + acceptable_attributes = set(['abbr', 'accept', 'accept-charset', 'accesskey', + 'action', 'align', 'alt', 'autocomplete', 'autofocus', 'axis', + 'background', 'balance', 'bgcolor', 'bgproperties', 'border', + 'bordercolor', 'bordercolordark', 'bordercolorlight', 'bottompadding', + 'cellpadding', 'cellspacing', 'ch', 'challenge', 'char', 'charoff', + 'choff', 'charset', 'checked', 'cite', 'class', 'clear', 'color', 'cols', + 'colspan', 'compact', 'contenteditable', 'controls', 'coords', 'data', + 'datafld', 'datapagesize', 'datasrc', 'datetime', 'default', 'delay', + 'dir', 'disabled', 'draggable', 'dynsrc', 'enctype', 'end', 'face', 'for', + 'form', 'frame', 'galleryimg', 'gutter', 'headers', 'height', 'hidefocus', + 'hidden', 'high', 'href', 'hreflang', 'hspace', 'icon', 'id', 'inputmode', + 'ismap', 'keytype', 'label', 'leftspacing', 'lang', 'list', 'longdesc', + 'loop', 'loopcount', 'loopend', 'loopstart', 'low', 'lowsrc', 'max', + 'maxlength', 'media', 'method', 'min', 'multiple', 'name', 'nohref', + 'noshade', 'nowrap', 'open', 'optimum', 'pattern', 'ping', 'point-size', + 'poster', 'pqg', 'preload', 'prompt', 'radiogroup', 'readonly', 'rel', + 'repeat-max', 'repeat-min', 'replace', 'required', 'rev', 'rightspacing', + 'rows', 'rowspan', 'rules', 'scope', 'selected', 'shape', 'size', 'span', + 'src', 'start', 'step', 'summary', 'suppress', 'tabindex', 'target', + 'template', 'title', 'toppadding', 'type', 'unselectable', 'usemap', + 'urn', 'valign', 'value', 'variable', 'volume', 'vspace', 'vrml', + 'width', 'wrap', 'xml:lang']) + + unacceptable_elements_with_end_tag = set(['script', 'applet', 'style']) + + acceptable_css_properties = set(['azimuth', 'background-color', + 'border-bottom-color', 'border-collapse', 'border-color', + 'border-left-color', 'border-right-color', 'border-top-color', 'clear', + 'color', 'cursor', 'direction', 'display', 'elevation', 'float', 'font', + 'font-family', 'font-size', 'font-style', 'font-variant', 'font-weight', + 'height', 'letter-spacing', 'line-height', 'overflow', 'pause', + 'pause-after', 'pause-before', 'pitch', 'pitch-range', 'richness', + 'speak', 'speak-header', 'speak-numeral', 'speak-punctuation', + 'speech-rate', 'stress', 'text-align', 'text-decoration', 'text-indent', + 'unicode-bidi', 'vertical-align', 'voice-family', 'volume', + 'white-space', 'width']) + + # survey of common keywords found in feeds + acceptable_css_keywords = set(['auto', 'aqua', 'black', 'block', 'blue', + 'bold', 'both', 'bottom', 'brown', 'center', 'collapse', 'dashed', + 'dotted', 'fuchsia', 'gray', 'green', '!important', 'italic', 'left', + 'lime', 'maroon', 'medium', 'none', 'navy', 'normal', 'nowrap', 'olive', + 'pointer', 'purple', 'red', 'right', 'solid', 'silver', 'teal', 'top', + 'transparent', 'underline', 'white', 'yellow']) + + valid_css_values = re.compile('^(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|' + + '\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$') + + mathml_elements = set([ + 'annotation', + 'annotation-xml', + 'maction', + 'maligngroup', + 'malignmark', + 'math', + 'menclose', + 'merror', + 'mfenced', + 'mfrac', + 'mglyph', + 'mi', + 'mlabeledtr', + 'mlongdiv', + 'mmultiscripts', + 'mn', + 'mo', + 'mover', + 'mpadded', + 'mphantom', + 'mprescripts', + 'mroot', + 'mrow', + 'ms', + 'mscarries', + 'mscarry', + 'msgroup', + 'msline', + 'mspace', + 'msqrt', + 'msrow', + 'mstack', + 'mstyle', + 'msub', + 'msubsup', + 'msup', + 'mtable', + 'mtd', + 'mtext', + 'mtr', + 'munder', + 'munderover', + 'none', + 'semantics', + ]) + + mathml_attributes = set([ + 'accent', + 'accentunder', + 'actiontype', + 'align', + 'alignmentscope', + 'altimg', + 'altimg-height', + 'altimg-valign', + 'altimg-width', + 'alttext', + 'bevelled', + 'charalign', + 'close', + 'columnalign', + 'columnlines', + 'columnspacing', + 'columnspan', + 'columnwidth', + 'crossout', + 'decimalpoint', + 'denomalign', + 'depth', + 'dir', + 'display', + 'displaystyle', + 'edge', + 'encoding', + 'equalcolumns', + 'equalrows', + 'fence', + 'fontstyle', + 'fontweight', + 'form', + 'frame', + 'framespacing', + 'groupalign', + 'height', + 'href', + 'id', + 'indentalign', + 'indentalignfirst', + 'indentalignlast', + 'indentshift', + 'indentshiftfirst', + 'indentshiftlast', + 'indenttarget', + 'infixlinebreakstyle', + 'largeop', + 'length', + 'linebreak', + 'linebreakmultchar', + 'linebreakstyle', + 'lineleading', + 'linethickness', + 'location', + 'longdivstyle', + 'lquote', + 'lspace', + 'mathbackground', + 'mathcolor', + 'mathsize', + 'mathvariant', + 'maxsize', + 'minlabelspacing', + 'minsize', + 'movablelimits', + 'notation', + 'numalign', + 'open', + 'other', + 'overflow', + 'position', + 'rowalign', + 'rowlines', + 'rowspacing', + 'rowspan', + 'rquote', + 'rspace', + 'scriptlevel', + 'scriptminsize', + 'scriptsizemultiplier', + 'selection', + 'separator', + 'separators', + 'shift', + 'side', + 'src', + 'stackalign', + 'stretchy', + 'subscriptshift', + 'superscriptshift', + 'symmetric', + 'voffset', + 'width', + 'xlink:href', + 'xlink:show', + 'xlink:type', + 'xmlns', + 'xmlns:xlink', + ]) + + # svgtiny - foreignObject + linearGradient + radialGradient + stop + svg_elements = set(['a', 'animate', 'animateColor', 'animateMotion', + 'animateTransform', 'circle', 'defs', 'desc', 'ellipse', 'foreignObject', + 'font-face', 'font-face-name', 'font-face-src', 'g', 'glyph', 'hkern', + 'linearGradient', 'line', 'marker', 'metadata', 'missing-glyph', 'mpath', + 'path', 'polygon', 'polyline', 'radialGradient', 'rect', 'set', 'stop', + 'svg', 'switch', 'text', 'title', 'tspan', 'use']) + + # svgtiny + class + opacity + offset + xmlns + xmlns:xlink + svg_attributes = set(['accent-height', 'accumulate', 'additive', 'alphabetic', + 'arabic-form', 'ascent', 'attributeName', 'attributeType', + 'baseProfile', 'bbox', 'begin', 'by', 'calcMode', 'cap-height', + 'class', 'color', 'color-rendering', 'content', 'cx', 'cy', 'd', 'dx', + 'dy', 'descent', 'display', 'dur', 'end', 'fill', 'fill-opacity', + 'fill-rule', 'font-family', 'font-size', 'font-stretch', 'font-style', + 'font-variant', 'font-weight', 'from', 'fx', 'fy', 'g1', 'g2', + 'glyph-name', 'gradientUnits', 'hanging', 'height', 'horiz-adv-x', + 'horiz-origin-x', 'id', 'ideographic', 'k', 'keyPoints', 'keySplines', + 'keyTimes', 'lang', 'mathematical', 'marker-end', 'marker-mid', + 'marker-start', 'markerHeight', 'markerUnits', 'markerWidth', 'max', + 'min', 'name', 'offset', 'opacity', 'orient', 'origin', + 'overline-position', 'overline-thickness', 'panose-1', 'path', + 'pathLength', 'points', 'preserveAspectRatio', 'r', 'refX', 'refY', + 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', + 'restart', 'rotate', 'rx', 'ry', 'slope', 'stemh', 'stemv', + 'stop-color', 'stop-opacity', 'strikethrough-position', + 'strikethrough-thickness', 'stroke', 'stroke-dasharray', + 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', + 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'systemLanguage', + 'target', 'text-anchor', 'to', 'transform', 'type', 'u1', 'u2', + 'underline-position', 'underline-thickness', 'unicode', 'unicode-range', + 'units-per-em', 'values', 'version', 'viewBox', 'visibility', 'width', + 'widths', 'x', 'x-height', 'x1', 'x2', 'xlink:actuate', 'xlink:arcrole', + 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', + 'xml:base', 'xml:lang', 'xml:space', 'xmlns', 'xmlns:xlink', 'y', 'y1', + 'y2', 'zoomAndPan']) + + svg_attr_map = None + svg_elem_map = None + + acceptable_svg_properties = set([ 'fill', 'fill-opacity', 'fill-rule', + 'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin', + 'stroke-opacity']) + + def reset(self): + _BaseHTMLProcessor.reset(self) + self.unacceptablestack = 0 + self.mathmlOK = 0 + self.svgOK = 0 + + def unknown_starttag(self, tag, attrs): + acceptable_attributes = self.acceptable_attributes + keymap = {} + if not tag in self.acceptable_elements or self.svgOK: + if tag in self.unacceptable_elements_with_end_tag: + self.unacceptablestack += 1 + + # add implicit namespaces to html5 inline svg/mathml + if self._type.endswith('html'): + if not dict(attrs).get('xmlns'): + if tag=='svg': + attrs.append( ('xmlns','http://www.w3.org/2000/svg') ) + if tag=='math': + attrs.append( ('xmlns','http://www.w3.org/1998/Math/MathML') ) + + # not otherwise acceptable, perhaps it is MathML or SVG? + if tag=='math' and ('xmlns','http://www.w3.org/1998/Math/MathML') in attrs: + self.mathmlOK += 1 + if tag=='svg' and ('xmlns','http://www.w3.org/2000/svg') in attrs: + self.svgOK += 1 + + # chose acceptable attributes based on tag class, else bail + if self.mathmlOK and tag in self.mathml_elements: + acceptable_attributes = self.mathml_attributes + elif self.svgOK and tag in self.svg_elements: + # for most vocabularies, lowercasing is a good idea. Many + # svg elements, however, are camel case + if not self.svg_attr_map: + lower=[attr.lower() for attr in self.svg_attributes] + mix=[a for a in self.svg_attributes if a not in lower] + self.svg_attributes = lower + self.svg_attr_map = dict([(a.lower(),a) for a in mix]) + + lower=[attr.lower() for attr in self.svg_elements] + mix=[a for a in self.svg_elements if a not in lower] + self.svg_elements = lower + self.svg_elem_map = dict([(a.lower(),a) for a in mix]) + acceptable_attributes = self.svg_attributes + tag = self.svg_elem_map.get(tag,tag) + keymap = self.svg_attr_map + elif not tag in self.acceptable_elements: + return + + # declare xlink namespace, if needed + if self.mathmlOK or self.svgOK: + if filter(lambda (n,v): n.startswith('xlink:'),attrs): + if not ('xmlns:xlink','http://www.w3.org/1999/xlink') in attrs: + attrs.append(('xmlns:xlink','http://www.w3.org/1999/xlink')) + + clean_attrs = [] + for key, value in self.normalize_attrs(attrs): + if key in acceptable_attributes: + key=keymap.get(key,key) + # make sure the uri uses an acceptable uri scheme + if key == u'href': + value = _makeSafeAbsoluteURI(value) + clean_attrs.append((key,value)) + elif key=='style': + clean_value = self.sanitize_style(value) + if clean_value: + clean_attrs.append((key,clean_value)) + _BaseHTMLProcessor.unknown_starttag(self, tag, clean_attrs) + + def unknown_endtag(self, tag): + if not tag in self.acceptable_elements: + if tag in self.unacceptable_elements_with_end_tag: + self.unacceptablestack -= 1 + if self.mathmlOK and tag in self.mathml_elements: + if tag == 'math' and self.mathmlOK: + self.mathmlOK -= 1 + elif self.svgOK and tag in self.svg_elements: + tag = self.svg_elem_map.get(tag,tag) + if tag == 'svg' and self.svgOK: + self.svgOK -= 1 + else: + return + _BaseHTMLProcessor.unknown_endtag(self, tag) + + def handle_pi(self, text): + pass + + def handle_decl(self, text): + pass + + def handle_data(self, text): + if not self.unacceptablestack: + _BaseHTMLProcessor.handle_data(self, text) + + def sanitize_style(self, style): + # disallow urls + style=re.compile('url\s*\(\s*[^\s)]+?\s*\)\s*').sub(' ',style) + + # gauntlet + if not re.match("""^([:,;#%.\sa-zA-Z0-9!]|\w-\w|'[\s\w]+'|"[\s\w]+"|\([\d,\s]+\))*$""", style): + return '' + # This replaced a regexp that used re.match and was prone to pathological back-tracking. + if re.sub("\s*[-\w]+\s*:\s*[^:;]*;?", '', style).strip(): + return '' + + clean = [] + for prop,value in re.findall("([-\w]+)\s*:\s*([^:;]*)",style): + if not value: + continue + if prop.lower() in self.acceptable_css_properties: + clean.append(prop + ': ' + value + ';') + elif prop.split('-')[0].lower() in ['background','border','margin','padding']: + for keyword in value.split(): + if not keyword in self.acceptable_css_keywords and \ + not self.valid_css_values.match(keyword): + break + else: + clean.append(prop + ': ' + value + ';') + elif self.svgOK and prop.lower() in self.acceptable_svg_properties: + clean.append(prop + ': ' + value + ';') + + return ' '.join(clean) + + def parse_comment(self, i, report=1): + ret = _BaseHTMLProcessor.parse_comment(self, i, report) + if ret >= 0: + return ret + # if ret == -1, this may be a malicious attempt to circumvent + # sanitization, or a page-destroying unclosed comment + match = re.compile(r'--[^>]*>').search(self.rawdata, i+4) + if match: + return match.end() + # unclosed comment; deliberately fail to handle_data() + return len(self.rawdata) + + +def _sanitizeHTML(htmlSource, encoding, _type): + if not _SGML_AVAILABLE: + return htmlSource + p = _HTMLSanitizer(encoding, _type) + htmlSource = htmlSource.replace(' stream + + This function lets you define parsers that take any input source + (URL, pathname to local or network file, or actual data as a string) + and deal with it in a uniform manner. Returned object is guaranteed + to have all the basic stdio read methods (read, readline, readlines). + Just .close() the object when you're done with it. + + If the etag argument is supplied, it will be used as the value of an + If-None-Match request header. + + If the modified argument is supplied, it can be a tuple of 9 integers + (as returned by gmtime() in the standard Python time module) or a date + string in any format supported by feedparser. Regardless, it MUST + be in GMT (Greenwich Mean Time). It will be reformatted into an + RFC 1123-compliant date and used as the value of an If-Modified-Since + request header. + + If the agent argument is supplied, it will be used as the value of a + User-Agent request header. + + If the referrer argument is supplied, it will be used as the value of a + Referer[sic] request header. + + If handlers is supplied, it is a list of handlers used to build a + urllib2 opener. + + if request_headers is supplied it is a dictionary of HTTP request headers + that will override the values generated by FeedParser. + + :return: A :class:`StringIO.StringIO` or :class:`io.BytesIO`. + """ + + if hasattr(url_file_stream_or_string, 'read'): + return url_file_stream_or_string + + if isinstance(url_file_stream_or_string, basestring) \ + and urlparse.urlparse(url_file_stream_or_string)[0] in ('http', 'https', 'ftp', 'file', 'feed'): + # Deal with the feed URI scheme + if url_file_stream_or_string.startswith('feed:http'): + url_file_stream_or_string = url_file_stream_or_string[5:] + elif url_file_stream_or_string.startswith('feed:'): + url_file_stream_or_string = 'http:' + url_file_stream_or_string[5:] + if not agent: + agent = USER_AGENT + # Test for inline user:password credentials for HTTP basic auth + auth = None + if base64 and not url_file_stream_or_string.startswith('ftp:'): + urltype, rest = urllib.splittype(url_file_stream_or_string) + realhost, rest = urllib.splithost(rest) + if realhost: + user_passwd, realhost = urllib.splituser(realhost) + if user_passwd: + url_file_stream_or_string = '%s://%s%s' % (urltype, realhost, rest) + auth = base64.standard_b64encode(user_passwd).strip() + + # iri support + if isinstance(url_file_stream_or_string, unicode): + url_file_stream_or_string = _convert_to_idn(url_file_stream_or_string) + + # try to open with urllib2 (to use optional headers) + request = _build_urllib2_request(url_file_stream_or_string, agent, etag, modified, referrer, auth, request_headers) + opener = urllib2.build_opener(*tuple(handlers + [_FeedURLHandler()])) + opener.addheaders = [] # RMK - must clear so we only send our custom User-Agent + try: + return opener.open(request) + finally: + opener.close() # JohnD + + # try to open with native open function (if url_file_stream_or_string is a filename) + try: + return open(url_file_stream_or_string, 'rb') + except (IOError, UnicodeEncodeError, TypeError): + # if url_file_stream_or_string is a unicode object that + # cannot be converted to the encoding returned by + # sys.getfilesystemencoding(), a UnicodeEncodeError + # will be thrown + # If url_file_stream_or_string is a string that contains NULL + # (such as an XML document encoded in UTF-32), TypeError will + # be thrown. + pass + + # treat url_file_stream_or_string as string + if isinstance(url_file_stream_or_string, unicode): + return _StringIO(url_file_stream_or_string.encode('utf-8')) + return _StringIO(url_file_stream_or_string) + +def _convert_to_idn(url): + """Convert a URL to IDN notation""" + # this function should only be called with a unicode string + # strategy: if the host cannot be encoded in ascii, then + # it'll be necessary to encode it in idn form + parts = list(urlparse.urlsplit(url)) + try: + parts[1].encode('ascii') + except UnicodeEncodeError: + # the url needs to be converted to idn notation + host = parts[1].rsplit(':', 1) + newhost = [] + port = u'' + if len(host) == 2: + port = host.pop() + for h in host[0].split('.'): + newhost.append(h.encode('idna').decode('utf-8')) + parts[1] = '.'.join(newhost) + if port: + parts[1] += ':' + port + return urlparse.urlunsplit(parts) + else: + return url + +def _build_urllib2_request(url, agent, etag, modified, referrer, auth, request_headers): + request = urllib2.Request(url) + request.add_header('User-Agent', agent) + if etag: + request.add_header('If-None-Match', etag) + if isinstance(modified, basestring): + modified = _parse_date(modified) + elif isinstance(modified, datetime.datetime): + modified = modified.utctimetuple() + if modified: + # format into an RFC 1123-compliant timestamp. We can't use + # time.strftime() since the %a and %b directives can be affected + # by the current locale, but RFC 2616 states that dates must be + # in English. + short_weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + request.add_header('If-Modified-Since', '%s, %02d %s %04d %02d:%02d:%02d GMT' % (short_weekdays[modified[6]], modified[2], months[modified[1] - 1], modified[0], modified[3], modified[4], modified[5])) + if referrer: + request.add_header('Referer', referrer) + if gzip and zlib: + request.add_header('Accept-encoding', 'gzip, deflate') + elif gzip: + request.add_header('Accept-encoding', 'gzip') + elif zlib: + request.add_header('Accept-encoding', 'deflate') + else: + request.add_header('Accept-encoding', '') + if auth: + request.add_header('Authorization', 'Basic %s' % auth) + if ACCEPT_HEADER: + request.add_header('Accept', ACCEPT_HEADER) + # use this for whatever -- cookies, special headers, etc + # [('Cookie','Something'),('x-special-header','Another Value')] + for header_name, header_value in request_headers.items(): + request.add_header(header_name, header_value) + request.add_header('A-IM', 'feed') # RFC 3229 support + return request + +def _parse_psc_chapter_start(start): + FORMAT = r'^((\d{2}):)?(\d{2}):(\d{2})(\.(\d{3}))?$' + + m = re.compile(FORMAT).match(start) + if m is None: + return None + + _, h, m, s, _, ms = m.groups() + h, m, s, ms = (int(h or 0), int(m), int(s), int(ms or 0)) + return datetime.timedelta(0, h*60*60 + m*60 + s, ms*1000) + +_date_handlers = [] +def registerDateHandler(func): + '''Register a date handler function (takes string, returns 9-tuple date in GMT)''' + _date_handlers.insert(0, func) + +# ISO-8601 date parsing routines written by Fazal Majid. +# The ISO 8601 standard is very convoluted and irregular - a full ISO 8601 +# parser is beyond the scope of feedparser and would be a worthwhile addition +# to the Python library. +# A single regular expression cannot parse ISO 8601 date formats into groups +# as the standard is highly irregular (for instance is 030104 2003-01-04 or +# 0301-04-01), so we use templates instead. +# Please note the order in templates is significant because we need a +# greedy match. +_iso8601_tmpl = ['YYYY-?MM-?DD', 'YYYY-0MM?-?DD', 'YYYY-MM', 'YYYY-?OOO', + 'YY-?MM-?DD', 'YY-?OOO', 'YYYY', + '-YY-?MM', '-OOO', '-YY', + '--MM-?DD', '--MM', + '---DD', + 'CC', ''] +_iso8601_re = [ + tmpl.replace( + 'YYYY', r'(?P\d{4})').replace( + 'YY', r'(?P\d\d)').replace( + 'MM', r'(?P[01]\d)').replace( + 'DD', r'(?P[0123]\d)').replace( + 'OOO', r'(?P[0123]\d\d)').replace( + 'CC', r'(?P\d\d$)') + + r'(T?(?P\d{2}):(?P\d{2})' + + r'(:(?P\d{2}))?' + + r'(\.(?P\d+))?' + + r'(?P[+-](?P\d{2})(:(?P\d{2}))?|Z)?)?' + for tmpl in _iso8601_tmpl] +try: + del tmpl +except NameError: + pass +_iso8601_matches = [re.compile(regex).match for regex in _iso8601_re] +try: + del regex +except NameError: + pass + +def _parse_date_iso8601(dateString): + '''Parse a variety of ISO-8601-compatible formats like 20040105''' + m = None + for _iso8601_match in _iso8601_matches: + m = _iso8601_match(dateString) + if m: + break + if not m: + return + if m.span() == (0, 0): + return + params = m.groupdict() + ordinal = params.get('ordinal', 0) + if ordinal: + ordinal = int(ordinal) + else: + ordinal = 0 + year = params.get('year', '--') + if not year or year == '--': + year = time.gmtime()[0] + elif len(year) == 2: + # ISO 8601 assumes current century, i.e. 93 -> 2093, NOT 1993 + year = 100 * int(time.gmtime()[0] / 100) + int(year) + else: + year = int(year) + month = params.get('month', '-') + if not month or month == '-': + # ordinals are NOT normalized by mktime, we simulate them + # by setting month=1, day=ordinal + if ordinal: + month = 1 + else: + month = time.gmtime()[1] + month = int(month) + day = params.get('day', 0) + if not day: + # see above + if ordinal: + day = ordinal + elif params.get('century', 0) or \ + params.get('year', 0) or params.get('month', 0): + day = 1 + else: + day = time.gmtime()[2] + else: + day = int(day) + # special case of the century - is the first year of the 21st century + # 2000 or 2001 ? The debate goes on... + if 'century' in params: + year = (int(params['century']) - 1) * 100 + 1 + # in ISO 8601 most fields are optional + for field in ['hour', 'minute', 'second', 'tzhour', 'tzmin']: + if not params.get(field, None): + params[field] = 0 + hour = int(params.get('hour', 0)) + minute = int(params.get('minute', 0)) + second = int(float(params.get('second', 0))) + # weekday is normalized by mktime(), we can ignore it + weekday = 0 + daylight_savings_flag = -1 + tm = [year, month, day, hour, minute, second, weekday, + ordinal, daylight_savings_flag] + # ISO 8601 time zone adjustments + tz = params.get('tz') + if tz and tz != 'Z': + if tz[0] == '-': + tm[3] += int(params.get('tzhour', 0)) + tm[4] += int(params.get('tzmin', 0)) + elif tz[0] == '+': + tm[3] -= int(params.get('tzhour', 0)) + tm[4] -= int(params.get('tzmin', 0)) + else: + return None + # Python's time.mktime() is a wrapper around the ANSI C mktime(3c) + # which is guaranteed to normalize d/m/y/h/m/s. + # Many implementations have bugs, but we'll pretend they don't. + return time.localtime(time.mktime(tuple(tm))) +registerDateHandler(_parse_date_iso8601) + +# 8-bit date handling routines written by ytrewq1. +_korean_year = u'\ub144' # b3e2 in euc-kr +_korean_month = u'\uc6d4' # bff9 in euc-kr +_korean_day = u'\uc77c' # c0cf in euc-kr +_korean_am = u'\uc624\uc804' # bfc0 c0fc in euc-kr +_korean_pm = u'\uc624\ud6c4' # bfc0 c8c4 in euc-kr + +_korean_onblog_date_re = \ + re.compile('(\d{4})%s\s+(\d{2})%s\s+(\d{2})%s\s+(\d{2}):(\d{2}):(\d{2})' % \ + (_korean_year, _korean_month, _korean_day)) +_korean_nate_date_re = \ + re.compile(u'(\d{4})-(\d{2})-(\d{2})\s+(%s|%s)\s+(\d{,2}):(\d{,2}):(\d{,2})' % \ + (_korean_am, _korean_pm)) +def _parse_date_onblog(dateString): + '''Parse a string according to the OnBlog 8-bit date format''' + m = _korean_onblog_date_re.match(dateString) + if not m: + return + w3dtfdate = '%(year)s-%(month)s-%(day)sT%(hour)s:%(minute)s:%(second)s%(zonediff)s' % \ + {'year': m.group(1), 'month': m.group(2), 'day': m.group(3),\ + 'hour': m.group(4), 'minute': m.group(5), 'second': m.group(6),\ + 'zonediff': '+09:00'} + return _parse_date_w3dtf(w3dtfdate) +registerDateHandler(_parse_date_onblog) + +def _parse_date_nate(dateString): + '''Parse a string according to the Nate 8-bit date format''' + m = _korean_nate_date_re.match(dateString) + if not m: + return + hour = int(m.group(5)) + ampm = m.group(4) + if (ampm == _korean_pm): + hour += 12 + hour = str(hour) + if len(hour) == 1: + hour = '0' + hour + w3dtfdate = '%(year)s-%(month)s-%(day)sT%(hour)s:%(minute)s:%(second)s%(zonediff)s' % \ + {'year': m.group(1), 'month': m.group(2), 'day': m.group(3),\ + 'hour': hour, 'minute': m.group(6), 'second': m.group(7),\ + 'zonediff': '+09:00'} + return _parse_date_w3dtf(w3dtfdate) +registerDateHandler(_parse_date_nate) + +# Unicode strings for Greek date strings +_greek_months = \ + { \ + u'\u0399\u03b1\u03bd': u'Jan', # c9e1ed in iso-8859-7 + u'\u03a6\u03b5\u03b2': u'Feb', # d6e5e2 in iso-8859-7 + u'\u039c\u03ac\u03ce': u'Mar', # ccdcfe in iso-8859-7 + u'\u039c\u03b1\u03ce': u'Mar', # cce1fe in iso-8859-7 + u'\u0391\u03c0\u03c1': u'Apr', # c1f0f1 in iso-8859-7 + u'\u039c\u03ac\u03b9': u'May', # ccdce9 in iso-8859-7 + u'\u039c\u03b1\u03ca': u'May', # cce1fa in iso-8859-7 + u'\u039c\u03b1\u03b9': u'May', # cce1e9 in iso-8859-7 + u'\u0399\u03bf\u03cd\u03bd': u'Jun', # c9effded in iso-8859-7 + u'\u0399\u03bf\u03bd': u'Jun', # c9efed in iso-8859-7 + u'\u0399\u03bf\u03cd\u03bb': u'Jul', # c9effdeb in iso-8859-7 + u'\u0399\u03bf\u03bb': u'Jul', # c9f9eb in iso-8859-7 + u'\u0391\u03cd\u03b3': u'Aug', # c1fde3 in iso-8859-7 + u'\u0391\u03c5\u03b3': u'Aug', # c1f5e3 in iso-8859-7 + u'\u03a3\u03b5\u03c0': u'Sep', # d3e5f0 in iso-8859-7 + u'\u039f\u03ba\u03c4': u'Oct', # cfeaf4 in iso-8859-7 + u'\u039d\u03bf\u03ad': u'Nov', # cdefdd in iso-8859-7 + u'\u039d\u03bf\u03b5': u'Nov', # cdefe5 in iso-8859-7 + u'\u0394\u03b5\u03ba': u'Dec', # c4e5ea in iso-8859-7 + } + +_greek_wdays = \ + { \ + u'\u039a\u03c5\u03c1': u'Sun', # caf5f1 in iso-8859-7 + u'\u0394\u03b5\u03c5': u'Mon', # c4e5f5 in iso-8859-7 + u'\u03a4\u03c1\u03b9': u'Tue', # d4f1e9 in iso-8859-7 + u'\u03a4\u03b5\u03c4': u'Wed', # d4e5f4 in iso-8859-7 + u'\u03a0\u03b5\u03bc': u'Thu', # d0e5ec in iso-8859-7 + u'\u03a0\u03b1\u03c1': u'Fri', # d0e1f1 in iso-8859-7 + u'\u03a3\u03b1\u03b2': u'Sat', # d3e1e2 in iso-8859-7 + } + +_greek_date_format_re = \ + re.compile(u'([^,]+),\s+(\d{2})\s+([^\s]+)\s+(\d{4})\s+(\d{2}):(\d{2}):(\d{2})\s+([^\s]+)') + +def _parse_date_greek(dateString): + '''Parse a string according to a Greek 8-bit date format.''' + m = _greek_date_format_re.match(dateString) + if not m: + return + wday = _greek_wdays[m.group(1)] + month = _greek_months[m.group(3)] + rfc822date = '%(wday)s, %(day)s %(month)s %(year)s %(hour)s:%(minute)s:%(second)s %(zonediff)s' % \ + {'wday': wday, 'day': m.group(2), 'month': month, 'year': m.group(4),\ + 'hour': m.group(5), 'minute': m.group(6), 'second': m.group(7),\ + 'zonediff': m.group(8)} + return _parse_date_rfc822(rfc822date) +registerDateHandler(_parse_date_greek) + +# Unicode strings for Hungarian date strings +_hungarian_months = \ + { \ + u'janu\u00e1r': u'01', # e1 in iso-8859-2 + u'febru\u00e1ri': u'02', # e1 in iso-8859-2 + u'm\u00e1rcius': u'03', # e1 in iso-8859-2 + u'\u00e1prilis': u'04', # e1 in iso-8859-2 + u'm\u00e1ujus': u'05', # e1 in iso-8859-2 + u'j\u00fanius': u'06', # fa in iso-8859-2 + u'j\u00falius': u'07', # fa in iso-8859-2 + u'augusztus': u'08', + u'szeptember': u'09', + u'okt\u00f3ber': u'10', # f3 in iso-8859-2 + u'november': u'11', + u'december': u'12', + } + +_hungarian_date_format_re = \ + re.compile(u'(\d{4})-([^-]+)-(\d{,2})T(\d{,2}):(\d{2})((\+|-)(\d{,2}:\d{2}))') + +def _parse_date_hungarian(dateString): + '''Parse a string according to a Hungarian 8-bit date format.''' + m = _hungarian_date_format_re.match(dateString) + if not m or m.group(2) not in _hungarian_months: + return None + month = _hungarian_months[m.group(2)] + day = m.group(3) + if len(day) == 1: + day = '0' + day + hour = m.group(4) + if len(hour) == 1: + hour = '0' + hour + w3dtfdate = '%(year)s-%(month)s-%(day)sT%(hour)s:%(minute)s%(zonediff)s' % \ + {'year': m.group(1), 'month': month, 'day': day,\ + 'hour': hour, 'minute': m.group(5),\ + 'zonediff': m.group(6)} + return _parse_date_w3dtf(w3dtfdate) +registerDateHandler(_parse_date_hungarian) + +timezonenames = { + 'ut': 0, 'gmt': 0, 'z': 0, + 'adt': -3, 'ast': -4, 'at': -4, + 'edt': -4, 'est': -5, 'et': -5, + 'cdt': -5, 'cst': -6, 'ct': -6, + 'mdt': -6, 'mst': -7, 'mt': -7, + 'pdt': -7, 'pst': -8, 'pt': -8, + 'a': -1, 'n': 1, + 'm': -12, 'y': 12, +} +# W3 date and time format parser +# http://www.w3.org/TR/NOTE-datetime +# Also supports MSSQL-style datetimes as defined at: +# http://msdn.microsoft.com/en-us/library/ms186724.aspx +# (basically, allow a space as a date/time/timezone separator) +def _parse_date_w3dtf(datestr): + if not datestr.strip(): + return None + parts = datestr.lower().split('t') + if len(parts) == 1: + # This may be a date only, or may be an MSSQL-style date + parts = parts[0].split() + if len(parts) == 1: + # Treat this as a date only + parts.append('00:00:00z') + elif len(parts) > 2: + return None + date = parts[0].split('-', 2) + if not date or len(date[0]) != 4: + return None + # Ensure that `date` has 3 elements. Using '1' sets the default + # month to January and the default day to the 1st of the month. + date.extend(['1'] * (3 - len(date))) + try: + year, month, day = [int(i) for i in date] + except ValueError: + # `date` may have more than 3 elements or may contain + # non-integer strings. + return None + if parts[1].endswith('z'): + parts[1] = parts[1][:-1] + parts.append('z') + # Append the numeric timezone offset, if any, to parts. + # If this is an MSSQL-style date then parts[2] already contains + # the timezone information, so `append()` will not affect it. + # Add 1 to each value so that if `find()` returns -1 it will be + # treated as False. + loc = parts[1].find('-') + 1 or parts[1].find('+') + 1 or len(parts[1]) + 1 + loc = loc - 1 + parts.append(parts[1][loc:]) + parts[1] = parts[1][:loc] + time = parts[1].split(':', 2) + # Ensure that time has 3 elements. Using '0' means that the + # minutes and seconds, if missing, will default to 0. + time.extend(['0'] * (3 - len(time))) + tzhour = 0 + tzmin = 0 + if parts[2][:1] in ('-', '+'): + try: + tzhour = int(parts[2][1:3]) + tzmin = int(parts[2][4:]) + except ValueError: + return None + if parts[2].startswith('-'): + tzhour = tzhour * -1 + tzmin = tzmin * -1 + else: + tzhour = timezonenames.get(parts[2], 0) + try: + hour, minute, second = [int(float(i)) for i in time] + except ValueError: + return None + # Create the datetime object and timezone delta objects + try: + stamp = datetime.datetime(year, month, day, hour, minute, second) + except ValueError: + return None + delta = datetime.timedelta(0, 0, 0, 0, tzmin, tzhour) + # Return the date and timestamp in a UTC 9-tuple + try: + return (stamp - delta).utctimetuple() + except (OverflowError, ValueError): + # IronPython throws ValueErrors instead of OverflowErrors + return None + +registerDateHandler(_parse_date_w3dtf) + +def _parse_date_rfc822(date): + """Parse RFC 822 dates and times + http://tools.ietf.org/html/rfc822#section-5 + + There are some formatting differences that are accounted for: + 1. Years may be two or four digits. + 2. The month and day can be swapped. + 3. Additional timezone names are supported. + 4. A default time and timezone are assumed if only a date is present. + """ + daynames = set(['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']) + months = { + 'jan': 1, 'feb': 2, 'mar': 3, 'apr': 4, 'may': 5, 'jun': 6, + 'jul': 7, 'aug': 8, 'sep': 9, 'oct': 10, 'nov': 11, 'dec': 12, + } + + parts = date.lower().split() + if len(parts) < 5: + # Assume that the time and timezone are missing + parts.extend(('00:00:00', '0000')) + # Remove the day name + if parts[0][:3] in daynames: + parts = parts[1:] + if len(parts) < 5: + # If there are still fewer than five parts, there's not enough + # information to interpret this + return None + try: + day = int(parts[0]) + except ValueError: + # Check if the day and month are swapped + if months.get(parts[0][:3]): + try: + day = int(parts[1]) + except ValueError: + return None + else: + parts[1] = parts[0] + else: + return None + month = months.get(parts[1][:3]) + if not month: + return None + try: + year = int(parts[2]) + except ValueError: + return None + # Normalize two-digit years: + # Anything in the 90's is interpreted as 1990 and on + # Anything 89 or less is interpreted as 2089 or before + if len(parts[2]) <= 2: + year += (1900, 2000)[year < 90] + timeparts = parts[3].split(':') + timeparts = timeparts + ([0] * (3 - len(timeparts))) + try: + (hour, minute, second) = map(int, timeparts) + except ValueError: + return None + tzhour = 0 + tzmin = 0 + # Strip 'Etc/' from the timezone + if parts[4].startswith('etc/'): + parts[4] = parts[4][4:] + # Normalize timezones that start with 'gmt': + # GMT-05:00 => -0500 + # GMT => GMT + if parts[4].startswith('gmt'): + parts[4] = ''.join(parts[4][3:].split(':')) or 'gmt' + # Handle timezones like '-0500', '+0500', and 'EST' + if parts[4] and parts[4][0] in ('-', '+'): + try: + tzhour = int(parts[4][1:3]) + tzmin = int(parts[4][3:]) + except ValueError: + return None + if parts[4].startswith('-'): + tzhour = tzhour * -1 + tzmin = tzmin * -1 + else: + tzhour = timezonenames.get(parts[4], 0) + # Create the datetime object and timezone delta objects + try: + stamp = datetime.datetime(year, month, day, hour, minute, second) + except ValueError: + return None + delta = datetime.timedelta(0, 0, 0, 0, tzmin, tzhour) + # Return the date and timestamp in a UTC 9-tuple + try: + return (stamp - delta).utctimetuple() + except (OverflowError, ValueError): + # IronPython throws ValueErrors instead of OverflowErrors + return None +registerDateHandler(_parse_date_rfc822) + +_months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', + 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'] +def _parse_date_asctime(dt): + """Parse asctime-style dates. + + Converts asctime to RFC822-compatible dates and uses the RFC822 parser + to do the actual parsing. + + Supported formats (format is standardized to the first one listed): + + * {weekday name} {month name} dd hh:mm:ss {+-tz} yyyy + * {weekday name} {month name} dd hh:mm:ss yyyy + """ + + parts = dt.split() + + # Insert a GMT timezone, if needed. + if len(parts) == 5: + parts.insert(4, '+0000') + + # Exit if there are not six parts. + if len(parts) != 6: + return None + + # Reassemble the parts in an RFC822-compatible order and parse them. + return _parse_date_rfc822(' '.join([ + parts[0], parts[2], parts[1], parts[5], parts[3], parts[4], + ])) +registerDateHandler(_parse_date_asctime) + +def _parse_date_perforce(aDateString): + """parse a date in yyyy/mm/dd hh:mm:ss TTT format""" + # Fri, 2006/09/15 08:19:53 EDT + _my_date_pattern = re.compile( \ + r'(\w{,3}), (\d{,4})/(\d{,2})/(\d{2}) (\d{,2}):(\d{2}):(\d{2}) (\w{,3})') + + m = _my_date_pattern.search(aDateString) + if m is None: + return None + dow, year, month, day, hour, minute, second, tz = m.groups() + months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + dateString = "%s, %s %s %s %s:%s:%s %s" % (dow, day, months[int(month) - 1], year, hour, minute, second, tz) + tm = rfc822.parsedate_tz(dateString) + if tm: + return time.gmtime(rfc822.mktime_tz(tm)) +registerDateHandler(_parse_date_perforce) + +def _parse_date(dateString): + '''Parses a variety of date formats into a 9-tuple in GMT''' + if not dateString: + return None + for handler in _date_handlers: + try: + date9tuple = handler(dateString) + except (KeyError, OverflowError, ValueError): + continue + if not date9tuple: + continue + if len(date9tuple) != 9: + continue + return date9tuple + return None + +# Each marker represents some of the characters of the opening XML +# processing instruction (' +RE_XML_DECLARATION = re.compile('^<\?xml[^>]*?>') + +# Capture the value of the XML processing instruction's encoding attribute. +# Example: +RE_XML_PI_ENCODING = re.compile(_s2bytes('^<\?.*encoding=[\'"](.*?)[\'"].*\?>')) + +def convert_to_utf8(http_headers, data): + '''Detect and convert the character encoding to UTF-8. + + http_headers is a dictionary + data is a raw string (not Unicode)''' + + # This is so much trickier than it sounds, it's not even funny. + # According to RFC 3023 ('XML Media Types'), if the HTTP Content-Type + # is application/xml, application/*+xml, + # application/xml-external-parsed-entity, or application/xml-dtd, + # the encoding given in the charset parameter of the HTTP Content-Type + # takes precedence over the encoding given in the XML prefix within the + # document, and defaults to 'utf-8' if neither are specified. But, if + # the HTTP Content-Type is text/xml, text/*+xml, or + # text/xml-external-parsed-entity, the encoding given in the XML prefix + # within the document is ALWAYS IGNORED and only the encoding given in + # the charset parameter of the HTTP Content-Type header should be + # respected, and it defaults to 'us-ascii' if not specified. + + # Furthermore, discussion on the atom-syntax mailing list with the + # author of RFC 3023 leads me to the conclusion that any document + # served with a Content-Type of text/* and no charset parameter + # must be treated as us-ascii. (We now do this.) And also that it + # must always be flagged as non-well-formed. (We now do this too.) + + # If Content-Type is unspecified (input was local file or non-HTTP source) + # or unrecognized (server just got it totally wrong), then go by the + # encoding given in the XML prefix of the document and default to + # 'iso-8859-1' as per the HTTP specification (RFC 2616). + + # Then, assuming we didn't find a character encoding in the HTTP headers + # (and the HTTP Content-type allowed us to look in the body), we need + # to sniff the first few bytes of the XML data and try to determine + # whether the encoding is ASCII-compatible. Section F of the XML + # specification shows the way here: + # http://www.w3.org/TR/REC-xml/#sec-guessing-no-ext-info + + # If the sniffed encoding is not ASCII-compatible, we need to make it + # ASCII compatible so that we can sniff further into the XML declaration + # to find the encoding attribute, which will tell us the true encoding. + + # Of course, none of this guarantees that we will be able to parse the + # feed in the declared character encoding (assuming it was declared + # correctly, which many are not). iconv_codec can help a lot; + # you should definitely install it if you can. + # http://cjkpython.i18n.org/ + + bom_encoding = u'' + xml_encoding = u'' + rfc3023_encoding = u'' + + # Look at the first few bytes of the document to guess what + # its encoding may be. We only need to decode enough of the + # document that we can use an ASCII-compatible regular + # expression to search for an XML encoding declaration. + # The heuristic follows the XML specification, section F: + # http://www.w3.org/TR/REC-xml/#sec-guessing-no-ext-info + # Check for BOMs first. + if data[:4] == codecs.BOM_UTF32_BE: + bom_encoding = u'utf-32be' + data = data[4:] + elif data[:4] == codecs.BOM_UTF32_LE: + bom_encoding = u'utf-32le' + data = data[4:] + elif data[:2] == codecs.BOM_UTF16_BE and data[2:4] != ZERO_BYTES: + bom_encoding = u'utf-16be' + data = data[2:] + elif data[:2] == codecs.BOM_UTF16_LE and data[2:4] != ZERO_BYTES: + bom_encoding = u'utf-16le' + data = data[2:] + elif data[:3] == codecs.BOM_UTF8: + bom_encoding = u'utf-8' + data = data[3:] + # Check for the characters '''' + if RE_XML_DECLARATION.search(data): + data = RE_XML_DECLARATION.sub(new_declaration, data) + else: + data = new_declaration + u'\n' + data + data = data.encode('utf-8') + break + # if still no luck, give up + if not known_encoding: + error = CharacterEncodingUnknown( + 'document encoding unknown, I tried ' + + '%s, %s, utf-8, windows-1252, and iso-8859-2 but nothing worked' % + (rfc3023_encoding, xml_encoding)) + rfc3023_encoding = u'' + elif proposed_encoding != rfc3023_encoding: + error = CharacterEncodingOverride( + 'document declared as %s, but parsed as %s' % + (rfc3023_encoding, proposed_encoding)) + rfc3023_encoding = proposed_encoding + + return data, rfc3023_encoding, error + +# Match XML entity declarations. +# Example: +RE_ENTITY_PATTERN = re.compile(_s2bytes(r'^\s*]*?)>'), re.MULTILINE) + +# Match XML DOCTYPE declarations. +# Example: +RE_DOCTYPE_PATTERN = re.compile(_s2bytes(r'^\s*]*?)>'), re.MULTILINE) + +# Match safe entity declarations. +# This will allow hexadecimal character references through, +# as well as text, but not arbitrary nested entities. +# Example: cubed "³" +# Example: copyright "(C)" +# Forbidden: explode1 "&explode2;&explode2;" +RE_SAFE_ENTITY_PATTERN = re.compile(_s2bytes('\s+(\w+)\s+"(&#\w+;|[^&"]*)"')) + +def replace_doctype(data): + '''Strips and replaces the DOCTYPE, returns (rss_version, stripped_data) + + rss_version may be 'rss091n' or None + stripped_data is the same XML document with a replaced DOCTYPE + ''' + + # Divide the document into two groups by finding the location + # of the first element that doesn't begin with '\n\n]>') + data = RE_DOCTYPE_PATTERN.sub(replacement, head) + data + + # Precompute the safe entities for the loose parser. + safe_entities = dict((k.decode('utf-8'), v.decode('utf-8')) + for k, v in RE_SAFE_ENTITY_PATTERN.findall(replacement)) + return version, data, safe_entities + + +# GeoRSS geometry parsers. Each return a dict with 'type' and 'coordinates' +# items, or None in the case of a parsing error. + +def _parse_poslist(value, geom_type, swap=True, dims=2): + if geom_type == 'linestring': + return _parse_georss_line(value, swap, dims) + elif geom_type == 'polygon': + ring = _parse_georss_line(value, swap, dims) + return {'type': u'Polygon', 'coordinates': (ring['coordinates'],)} + else: + return None + +def _gen_georss_coords(value, swap=True, dims=2): + # A generator of (lon, lat) pairs from a string of encoded GeoRSS + # coordinates. Converts to floats and swaps order. + latlons = itertools.imap(float, value.strip().replace(',', ' ').split()) + nxt = latlons.next + while True: + t = [nxt(), nxt()][::swap and -1 or 1] + if dims == 3: + t.append(nxt()) + yield tuple(t) + +def _parse_georss_point(value, swap=True, dims=2): + # A point contains a single latitude-longitude pair, separated by + # whitespace. We'll also handle comma separators. + try: + coords = list(_gen_georss_coords(value, swap, dims)) + return {u'type': u'Point', u'coordinates': coords[0]} + except (IndexError, ValueError): + return None + +def _parse_georss_line(value, swap=True, dims=2): + # A line contains a space separated list of latitude-longitude pairs in + # WGS84 coordinate reference system, with each pair separated by + # whitespace. There must be at least two pairs. + try: + coords = list(_gen_georss_coords(value, swap, dims)) + return {u'type': u'LineString', u'coordinates': coords} + except (IndexError, ValueError): + return None + +def _parse_georss_polygon(value, swap=True, dims=2): + # A polygon contains a space separated list of latitude-longitude pairs, + # with each pair separated by whitespace. There must be at least four + # pairs, with the last being identical to the first (so a polygon has a + # minimum of three actual points). + try: + ring = list(_gen_georss_coords(value, swap, dims)) + except (IndexError, ValueError): + return None + if len(ring) < 4: + return None + return {u'type': u'Polygon', u'coordinates': (ring,)} + +def _parse_georss_box(value, swap=True, dims=2): + # A bounding box is a rectangular region, often used to define the extents + # of a map or a rough area of interest. A box contains two space seperate + # latitude-longitude pairs, with each pair separated by whitespace. The + # first pair is the lower corner, the second is the upper corner. + try: + coords = list(_gen_georss_coords(value, swap, dims)) + return {u'type': u'Box', u'coordinates': tuple(coords)} + except (IndexError, ValueError): + return None + +# end geospatial parsers + + +def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, referrer=None, handlers=None, request_headers=None, response_headers=None): + '''Parse a feed from a URL, file, stream, or string. + + request_headers, if given, is a dict from http header name to value to add + to the request; this overrides internally generated values. + + :return: A :class:`FeedParserDict`. + ''' + + if handlers is None: + handlers = [] + if request_headers is None: + request_headers = {} + if response_headers is None: + response_headers = {} + + result = FeedParserDict() + result['feed'] = FeedParserDict() + result['entries'] = [] + result['bozo'] = 0 + if not isinstance(handlers, list): + handlers = [handlers] + try: + f = _open_resource(url_file_stream_or_string, etag, modified, agent, referrer, handlers, request_headers) + data = f.read() + except Exception, e: + result['bozo'] = 1 + result['bozo_exception'] = e + data = None + f = None + + if hasattr(f, 'headers'): + result['headers'] = dict(f.headers) + # overwrite existing headers using response_headers + if 'headers' in result: + result['headers'].update(response_headers) + elif response_headers: + result['headers'] = copy.deepcopy(response_headers) + + # lowercase all of the HTTP headers for comparisons per RFC 2616 + if 'headers' in result: + http_headers = dict((k.lower(), v) for k, v in result['headers'].items()) + else: + http_headers = {} + + # if feed is gzip-compressed, decompress it + if f and data and http_headers: + if gzip and 'gzip' in http_headers.get('content-encoding', ''): + try: + data = gzip.GzipFile(fileobj=_StringIO(data)).read() + except (IOError, struct.error), e: + # IOError can occur if the gzip header is bad. + # struct.error can occur if the data is damaged. + result['bozo'] = 1 + result['bozo_exception'] = e + if isinstance(e, struct.error): + # A gzip header was found but the data is corrupt. + # Ideally, we should re-request the feed without the + # 'Accept-encoding: gzip' header, but we don't. + data = None + elif zlib and 'deflate' in http_headers.get('content-encoding', ''): + try: + data = zlib.decompress(data) + except zlib.error, e: + try: + # The data may have no headers and no checksum. + data = zlib.decompress(data, -15) + except zlib.error, e: + result['bozo'] = 1 + result['bozo_exception'] = e + + # save HTTP headers + if http_headers: + if 'etag' in http_headers: + etag = http_headers.get('etag', u'') + if not isinstance(etag, unicode): + etag = etag.decode('utf-8', 'ignore') + if etag: + result['etag'] = etag + if 'last-modified' in http_headers: + modified = http_headers.get('last-modified', u'') + if modified: + result['modified'] = modified + result['modified_parsed'] = _parse_date(modified) + if hasattr(f, 'url'): + if not isinstance(f.url, unicode): + result['href'] = f.url.decode('utf-8', 'ignore') + else: + result['href'] = f.url + result['status'] = 200 + if hasattr(f, 'status'): + result['status'] = f.status + if hasattr(f, 'close'): + f.close() + + if data is None: + return result + + # Stop processing if the server sent HTTP 304 Not Modified. + if getattr(f, 'code', 0) == 304: + result['version'] = u'' + result['debug_message'] = 'The feed has not changed since you last checked, ' + \ + 'so the server sent no data. This is a feature, not a bug!' + return result + + data, result['encoding'], error = convert_to_utf8(http_headers, data) + use_strict_parser = result['encoding'] and True or False + if error is not None: + result['bozo'] = 1 + result['bozo_exception'] = error + + result['version'], data, entities = replace_doctype(data) + + # Ensure that baseuri is an absolute URI using an acceptable URI scheme. + contentloc = http_headers.get('content-location', u'') + href = result.get('href', u'') + baseuri = _makeSafeAbsoluteURI(href, contentloc) or _makeSafeAbsoluteURI(contentloc) or href + + baselang = http_headers.get('content-language', None) + if not isinstance(baselang, unicode) and baselang is not None: + baselang = baselang.decode('utf-8', 'ignore') + + if not _XML_AVAILABLE: + use_strict_parser = 0 + if use_strict_parser: + # initialize the SAX parser + feedparser = _StrictFeedParser(baseuri, baselang, 'utf-8') + saxparser = xml.sax.make_parser(PREFERRED_XML_PARSERS) + saxparser.setFeature(xml.sax.handler.feature_namespaces, 1) + try: + # disable downloading external doctype references, if possible + saxparser.setFeature(xml.sax.handler.feature_external_ges, 0) + except xml.sax.SAXNotSupportedException: + pass + saxparser.setContentHandler(feedparser) + saxparser.setErrorHandler(feedparser) + source = xml.sax.xmlreader.InputSource() + source.setByteStream(_StringIO(data)) + try: + saxparser.parse(source) + except xml.sax.SAXException, e: + result['bozo'] = 1 + result['bozo_exception'] = feedparser.exc or e + use_strict_parser = 0 + if not use_strict_parser and _SGML_AVAILABLE: + feedparser = _LooseFeedParser(baseuri, baselang, 'utf-8', entities) + feedparser.feed(data.decode('utf-8', 'replace')) + result['feed'] = feedparser.feeddata + result['entries'] = feedparser.entries + result['version'] = result['version'] or feedparser.version + result['namespaces'] = feedparser.namespacesInUse + return result + +# The list of EPSG codes for geographic (latitude/longitude) coordinate +# systems to support decoding of GeoRSS GML profiles. +_geogCS = [ +3819, 3821, 3824, 3889, 3906, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, +4009, 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4018, 4019, 4020, 4021, 4022, +4023, 4024, 4025, 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, +4041, 4042, 4043, 4044, 4045, 4046, 4047, 4052, 4053, 4054, 4055, 4075, 4081, +4120, 4121, 4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, +4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4142, 4143, 4144, 4145, +4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, +4159, 4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, +4172, 4173, 4174, 4175, 4176, 4178, 4179, 4180, 4181, 4182, 4183, 4184, 4185, +4188, 4189, 4190, 4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, +4201, 4202, 4203, 4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, 4212, 4213, +4214, 4215, 4216, 4218, 4219, 4220, 4221, 4222, 4223, 4224, 4225, 4226, 4227, +4228, 4229, 4230, 4231, 4232, 4233, 4234, 4235, 4236, 4237, 4238, 4239, 4240, +4241, 4242, 4243, 4244, 4245, 4246, 4247, 4248, 4249, 4250, 4251, 4252, 4253, +4254, 4255, 4256, 4257, 4258, 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4266, +4267, 4268, 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, +4280, 4281, 4282, 4283, 4284, 4285, 4286, 4287, 4288, 4289, 4291, 4292, 4293, +4294, 4295, 4296, 4297, 4298, 4299, 4300, 4301, 4302, 4303, 4304, 4306, 4307, +4308, 4309, 4310, 4311, 4312, 4313, 4314, 4315, 4316, 4317, 4318, 4319, 4322, +4324, 4326, 4463, 4470, 4475, 4483, 4490, 4555, 4558, 4600, 4601, 4602, 4603, +4604, 4605, 4606, 4607, 4608, 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, +4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 4625, 4626, 4627, 4628, 4629, +4630, 4631, 4632, 4633, 4634, 4635, 4636, 4637, 4638, 4639, 4640, 4641, 4642, +4643, 4644, 4645, 4646, 4657, 4658, 4659, 4660, 4661, 4662, 4663, 4664, 4665, +4666, 4667, 4668, 4669, 4670, 4671, 4672, 4673, 4674, 4675, 4676, 4677, 4678, +4679, 4680, 4681, 4682, 4683, 4684, 4685, 4686, 4687, 4688, 4689, 4690, 4691, +4692, 4693, 4694, 4695, 4696, 4697, 4698, 4699, 4700, 4701, 4702, 4703, 4704, +4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714, 4715, 4716, 4717, +4718, 4719, 4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 4728, 4729, 4730, +4731, 4732, 4733, 4734, 4735, 4736, 4737, 4738, 4739, 4740, 4741, 4742, 4743, +4744, 4745, 4746, 4747, 4748, 4749, 4750, 4751, 4752, 4753, 4754, 4755, 4756, +4757, 4758, 4759, 4760, 4761, 4762, 4763, 4764, 4765, 4801, 4802, 4803, 4804, +4805, 4806, 4807, 4808, 4809, 4810, 4811, 4813, 4814, 4815, 4816, 4817, 4818, +4819, 4820, 4821, 4823, 4824, 4901, 4902, 4903, 4904, 4979 ] diff --git a/web2py/gluon/contrib/fpdf/__init__.py b/web2py/gluon/contrib/fpdf/__init__.py new file mode 100644 index 0000000..6c8a431 --- /dev/null +++ b/web2py/gluon/contrib/fpdf/__init__.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"FPDF for python" + +__license__ = "LGPL 3.0" +__version__ = "1.7.2" + +from .fpdf import FPDF, FPDF_FONT_DIR, FPDF_VERSION, SYSTEM_TTFONTS, set_global, FPDF_CACHE_MODE, FPDF_CACHE_DIR +try: + from .html import HTMLMixin +except ImportError: + import warnings + warnings.warn("web2py gluon package not installed, required for html2pdf") + +from .template import Template diff --git a/web2py/gluon/contrib/fpdf/fonts.py b/web2py/gluon/contrib/fpdf/fonts.py new file mode 100644 index 0000000..d66cf76 --- /dev/null +++ b/web2py/gluon/contrib/fpdf/fonts.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python +# -*- coding: latin-1 -*- + +# Fonts: + +fpdf_charwidths = {} + +fpdf_charwidths['courier']={} + +for i in range(0,256): + fpdf_charwidths['courier'][chr(i)]=600 + fpdf_charwidths['courierB']=fpdf_charwidths['courier'] + fpdf_charwidths['courierI']=fpdf_charwidths['courier'] + fpdf_charwidths['courierBI']=fpdf_charwidths['courier'] + +fpdf_charwidths['helvetica']={ + '\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278, + '\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':278,'"':355,'#':556,'$':556,'%':889,'&':667,'\'':191,'(':333,')':333,'*':389,'+':584, + ',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':278,';':278,'<':584,'=':584,'>':584,'?':556,'@':1015,'A':667, + 'B':667,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':500,'K':667,'L':556,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944, + 'X':667,'Y':667,'Z':611,'[':278,'\\':278,']':278,'^':469,'_':556,'`':333,'a':556,'b':556,'c':500,'d':556,'e':556,'f':278,'g':556,'h':556,'i':222,'j':222,'k':500,'l':222,'m':833, + 'n':556,'o':556,'p':556,'q':556,'r':333,'s':500,'t':278,'u':556,'v':500,'w':722,'x':500,'y':500,'z':500,'{':334,'|':260,'}':334,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':222,'\x83':556, + '\x84':333,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':222,'\x92':222,'\x93':333,'\x94':333,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000, + '\x9a':500,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':260,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333, + '\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':556,'\xb6':537,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':667,'\xc1':667,'\xc2':667,'\xc3':667,'\xc4':667,'\xc5':667, + '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':500,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':556,'\xf1':556, + '\xf2':556,'\xf3':556,'\xf4':556,'\xf5':556,'\xf6':556,'\xf7':584,'\xf8':611,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':500,'\xfe':556,'\xff':500} + +fpdf_charwidths['helveticaB']={ + '\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278, + '\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':333,'"':474,'#':556,'$':556,'%':889,'&':722,'\'':238,'(':333,')':333,'*':389,'+':584, + ',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':333,';':333,'<':584,'=':584,'>':584,'?':611,'@':975,'A':722, + 'B':722,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':556,'K':722,'L':611,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944, + 'X':667,'Y':667,'Z':611,'[':333,'\\':278,']':333,'^':584,'_':556,'`':333,'a':556,'b':611,'c':556,'d':611,'e':556,'f':333,'g':611,'h':611,'i':278,'j':278,'k':556,'l':278,'m':889, + 'n':611,'o':611,'p':611,'q':611,'r':389,'s':556,'t':333,'u':611,'v':556,'w':778,'x':556,'y':556,'z':500,'{':389,'|':280,'}':389,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':278,'\x83':556, + '\x84':500,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':278,'\x92':278,'\x93':500,'\x94':500,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000, + '\x9a':556,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':280,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333, + '\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':611,'\xb6':556,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722, + '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':556,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':611,'\xf1':611, + '\xf2':611,'\xf3':611,'\xf4':611,'\xf5':611,'\xf6':611,'\xf7':584,'\xf8':611,'\xf9':611,'\xfa':611,'\xfb':611,'\xfc':611,'\xfd':556,'\xfe':611,'\xff':556 +} + +fpdf_charwidths['helveticaBI']={ + '\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278, + '\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':333,'"':474,'#':556,'$':556,'%':889,'&':722,'\'':238,'(':333,')':333,'*':389,'+':584, + ',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':333,';':333,'<':584,'=':584,'>':584,'?':611,'@':975,'A':722, + 'B':722,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':556,'K':722,'L':611,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944, + 'X':667,'Y':667,'Z':611,'[':333,'\\':278,']':333,'^':584,'_':556,'`':333,'a':556,'b':611,'c':556,'d':611,'e':556,'f':333,'g':611,'h':611,'i':278,'j':278,'k':556,'l':278,'m':889, + 'n':611,'o':611,'p':611,'q':611,'r':389,'s':556,'t':333,'u':611,'v':556,'w':778,'x':556,'y':556,'z':500,'{':389,'|':280,'}':389,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':278,'\x83':556, + '\x84':500,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':278,'\x92':278,'\x93':500,'\x94':500,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000, + '\x9a':556,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':280,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333, + '\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':611,'\xb6':556,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722, + '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':556,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':611,'\xf1':611, + '\xf2':611,'\xf3':611,'\xf4':611,'\xf5':611,'\xf6':611,'\xf7':584,'\xf8':611,'\xf9':611,'\xfa':611,'\xfb':611,'\xfc':611,'\xfd':556,'\xfe':611,'\xff':556} + +fpdf_charwidths['helveticaI']={ + '\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278, + '\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':278,'"':355,'#':556,'$':556,'%':889,'&':667,'\'':191,'(':333,')':333,'*':389,'+':584, + ',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':278,';':278,'<':584,'=':584,'>':584,'?':556,'@':1015,'A':667, + 'B':667,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':500,'K':667,'L':556,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944, + 'X':667,'Y':667,'Z':611,'[':278,'\\':278,']':278,'^':469,'_':556,'`':333,'a':556,'b':556,'c':500,'d':556,'e':556,'f':278,'g':556,'h':556,'i':222,'j':222,'k':500,'l':222,'m':833, + 'n':556,'o':556,'p':556,'q':556,'r':333,'s':500,'t':278,'u':556,'v':500,'w':722,'x':500,'y':500,'z':500,'{':334,'|':260,'}':334,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':222,'\x83':556, + '\x84':333,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':222,'\x92':222,'\x93':333,'\x94':333,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000, + '\x9a':500,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':260,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333, + '\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':556,'\xb6':537,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':667,'\xc1':667,'\xc2':667,'\xc3':667,'\xc4':667,'\xc5':667, + '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':500,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':556,'\xf1':556, + '\xf2':556,'\xf3':556,'\xf4':556,'\xf5':556,'\xf6':556,'\xf7':584,'\xf8':611,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':500,'\xfe':556,'\xff':500} + +fpdf_charwidths['symbol']={ + '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, + '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':713,'#':500,'$':549,'%':833,'&':778,'\'':439,'(':333,')':333,'*':500,'+':549, + ',':250,'-':549,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':278,';':278,'<':549,'=':549,'>':549,'?':444,'@':549,'A':722, + 'B':667,'C':722,'D':612,'E':611,'F':763,'G':603,'H':722,'I':333,'J':631,'K':722,'L':686,'M':889,'N':722,'O':722,'P':768,'Q':741,'R':556,'S':592,'T':611,'U':690,'V':439,'W':768, + 'X':645,'Y':795,'Z':611,'[':333,'\\':863,']':333,'^':658,'_':500,'`':500,'a':631,'b':549,'c':549,'d':494,'e':439,'f':521,'g':411,'h':603,'i':329,'j':603,'k':549,'l':549,'m':576, + 'n':521,'o':549,'p':549,'q':521,'r':549,'s':603,'t':439,'u':576,'v':713,'w':686,'x':493,'y':686,'z':494,'{':480,'|':200,'}':480,'~':549,'\x7f':0,'\x80':0,'\x81':0,'\x82':0,'\x83':0, + '\x84':0,'\x85':0,'\x86':0,'\x87':0,'\x88':0,'\x89':0,'\x8a':0,'\x8b':0,'\x8c':0,'\x8d':0,'\x8e':0,'\x8f':0,'\x90':0,'\x91':0,'\x92':0,'\x93':0,'\x94':0,'\x95':0,'\x96':0,'\x97':0,'\x98':0,'\x99':0, + '\x9a':0,'\x9b':0,'\x9c':0,'\x9d':0,'\x9e':0,'\x9f':0,'\xa0':750,'\xa1':620,'\xa2':247,'\xa3':549,'\xa4':167,'\xa5':713,'\xa6':500,'\xa7':753,'\xa8':753,'\xa9':753,'\xaa':753,'\xab':1042,'\xac':987,'\xad':603,'\xae':987,'\xaf':603, + '\xb0':400,'\xb1':549,'\xb2':411,'\xb3':549,'\xb4':549,'\xb5':713,'\xb6':494,'\xb7':460,'\xb8':549,'\xb9':549,'\xba':549,'\xbb':549,'\xbc':1000,'\xbd':603,'\xbe':1000,'\xbf':658,'\xc0':823,'\xc1':686,'\xc2':795,'\xc3':987,'\xc4':768,'\xc5':768, + '\xc6':823,'\xc7':768,'\xc8':768,'\xc9':713,'\xca':713,'\xcb':713,'\xcc':713,'\xcd':713,'\xce':713,'\xcf':713,'\xd0':768,'\xd1':713,'\xd2':790,'\xd3':790,'\xd4':890,'\xd5':823,'\xd6':549,'\xd7':250,'\xd8':713,'\xd9':603,'\xda':603,'\xdb':1042, + '\xdc':987,'\xdd':603,'\xde':987,'\xdf':603,'\xe0':494,'\xe1':329,'\xe2':790,'\xe3':790,'\xe4':786,'\xe5':713,'\xe6':384,'\xe7':384,'\xe8':384,'\xe9':384,'\xea':384,'\xeb':384,'\xec':494,'\xed':494,'\xee':494,'\xef':494,'\xf0':0,'\xf1':329, + '\xf2':274,'\xf3':686,'\xf4':686,'\xf5':686,'\xf6':384,'\xf7':384,'\xf8':384,'\xf9':384,'\xfa':384,'\xfb':384,'\xfc':494,'\xfd':494,'\xfe':494,'\xff':0} + +fpdf_charwidths['times']={ + '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, + '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':408,'#':500,'$':500,'%':833,'&':778,'\'':180,'(':333,')':333,'*':500,'+':564, + ',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':278,';':278,'<':564,'=':564,'>':564,'?':444,'@':921,'A':722, + 'B':667,'C':667,'D':722,'E':611,'F':556,'G':722,'H':722,'I':333,'J':389,'K':722,'L':611,'M':889,'N':722,'O':722,'P':556,'Q':722,'R':667,'S':556,'T':611,'U':722,'V':722,'W':944, + 'X':722,'Y':722,'Z':611,'[':333,'\\':278,']':333,'^':469,'_':500,'`':333,'a':444,'b':500,'c':444,'d':500,'e':444,'f':333,'g':500,'h':500,'i':278,'j':278,'k':500,'l':278,'m':778, + 'n':500,'o':500,'p':500,'q':500,'r':333,'s':389,'t':278,'u':500,'v':500,'w':722,'x':500,'y':500,'z':444,'{':480,'|':200,'}':480,'~':541,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500, + '\x84':444,'\x85':1000,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':556,'\x8b':333,'\x8c':889,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':444,'\x94':444,'\x95':350,'\x96':500,'\x97':1000,'\x98':333,'\x99':980, + '\x9a':389,'\x9b':333,'\x9c':722,'\x9d':350,'\x9e':444,'\x9f':722,'\xa0':250,'\xa1':333,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':200,'\xa7':500,'\xa8':333,'\xa9':760,'\xaa':276,'\xab':500,'\xac':564,'\xad':333,'\xae':760,'\xaf':333, + '\xb0':400,'\xb1':564,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':500,'\xb6':453,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':310,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':444,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722, + '\xc6':889,'\xc7':667,'\xc8':611,'\xc9':611,'\xca':611,'\xcb':611,'\xcc':333,'\xcd':333,'\xce':333,'\xcf':333,'\xd0':722,'\xd1':722,'\xd2':722,'\xd3':722,'\xd4':722,'\xd5':722,'\xd6':722,'\xd7':564,'\xd8':722,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':722,'\xde':556,'\xdf':500,'\xe0':444,'\xe1':444,'\xe2':444,'\xe3':444,'\xe4':444,'\xe5':444,'\xe6':667,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':500, + '\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':564,'\xf8':500,'\xf9':500,'\xfa':500,'\xfb':500,'\xfc':500,'\xfd':500,'\xfe':500,'\xff':500} + +fpdf_charwidths['timesB']={ + '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, + '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':555,'#':500,'$':500,'%':1000,'&':833,'\'':278,'(':333,')':333,'*':500,'+':570, + ',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':333,';':333,'<':570,'=':570,'>':570,'?':500,'@':930,'A':722, + 'B':667,'C':722,'D':722,'E':667,'F':611,'G':778,'H':778,'I':389,'J':500,'K':778,'L':667,'M':944,'N':722,'O':778,'P':611,'Q':778,'R':722,'S':556,'T':667,'U':722,'V':722,'W':1000, + 'X':722,'Y':722,'Z':667,'[':333,'\\':278,']':333,'^':581,'_':500,'`':333,'a':500,'b':556,'c':444,'d':556,'e':444,'f':333,'g':500,'h':556,'i':278,'j':333,'k':556,'l':278,'m':833, + 'n':556,'o':500,'p':556,'q':556,'r':444,'s':389,'t':333,'u':556,'v':500,'w':722,'x':500,'y':500,'z':444,'{':394,'|':220,'}':394,'~':520,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500, + '\x84':500,'\x85':1000,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':556,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':667,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':500,'\x94':500,'\x95':350,'\x96':500,'\x97':1000,'\x98':333,'\x99':1000, + '\x9a':389,'\x9b':333,'\x9c':722,'\x9d':350,'\x9e':444,'\x9f':722,'\xa0':250,'\xa1':333,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':220,'\xa7':500,'\xa8':333,'\xa9':747,'\xaa':300,'\xab':500,'\xac':570,'\xad':333,'\xae':747,'\xaf':333, + '\xb0':400,'\xb1':570,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':556,'\xb6':540,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':330,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':500,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722, + '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':389,'\xcd':389,'\xce':389,'\xcf':389,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':570,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':722,'\xde':611,'\xdf':556,'\xe0':500,'\xe1':500,'\xe2':500,'\xe3':500,'\xe4':500,'\xe5':500,'\xe6':722,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':556, + '\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':570,'\xf8':500,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':500,'\xfe':556,'\xff':500} + +fpdf_charwidths['timesBI']={ + '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, + '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':389,'"':555,'#':500,'$':500,'%':833,'&':778,'\'':278,'(':333,')':333,'*':500,'+':570, + ',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':333,';':333,'<':570,'=':570,'>':570,'?':500,'@':832,'A':667, + 'B':667,'C':667,'D':722,'E':667,'F':667,'G':722,'H':778,'I':389,'J':500,'K':667,'L':611,'M':889,'N':722,'O':722,'P':611,'Q':722,'R':667,'S':556,'T':611,'U':722,'V':667,'W':889, + 'X':667,'Y':611,'Z':611,'[':333,'\\':278,']':333,'^':570,'_':500,'`':333,'a':500,'b':500,'c':444,'d':500,'e':444,'f':333,'g':500,'h':556,'i':278,'j':278,'k':500,'l':278,'m':778, + 'n':556,'o':500,'p':500,'q':500,'r':389,'s':389,'t':278,'u':556,'v':444,'w':667,'x':500,'y':444,'z':389,'{':348,'|':220,'}':348,'~':570,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500, + '\x84':500,'\x85':1000,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':556,'\x8b':333,'\x8c':944,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':500,'\x94':500,'\x95':350,'\x96':500,'\x97':1000,'\x98':333,'\x99':1000, + '\x9a':389,'\x9b':333,'\x9c':722,'\x9d':350,'\x9e':389,'\x9f':611,'\xa0':250,'\xa1':389,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':220,'\xa7':500,'\xa8':333,'\xa9':747,'\xaa':266,'\xab':500,'\xac':606,'\xad':333,'\xae':747,'\xaf':333, + '\xb0':400,'\xb1':570,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':576,'\xb6':500,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':300,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':500,'\xc0':667,'\xc1':667,'\xc2':667,'\xc3':667,'\xc4':667,'\xc5':667, + '\xc6':944,'\xc7':667,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':389,'\xcd':389,'\xce':389,'\xcf':389,'\xd0':722,'\xd1':722,'\xd2':722,'\xd3':722,'\xd4':722,'\xd5':722,'\xd6':722,'\xd7':570,'\xd8':722,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':611,'\xde':611,'\xdf':500,'\xe0':500,'\xe1':500,'\xe2':500,'\xe3':500,'\xe4':500,'\xe5':500,'\xe6':722,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':556, + '\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':570,'\xf8':500,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':444,'\xfe':500,'\xff':444} + +fpdf_charwidths['timesI']={ + '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, + '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':420,'#':500,'$':500,'%':833,'&':778,'\'':214,'(':333,')':333,'*':500,'+':675, + ',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':333,';':333,'<':675,'=':675,'>':675,'?':500,'@':920,'A':611, + 'B':611,'C':667,'D':722,'E':611,'F':611,'G':722,'H':722,'I':333,'J':444,'K':667,'L':556,'M':833,'N':667,'O':722,'P':611,'Q':722,'R':611,'S':500,'T':556,'U':722,'V':611,'W':833, + 'X':611,'Y':556,'Z':556,'[':389,'\\':278,']':389,'^':422,'_':500,'`':333,'a':500,'b':500,'c':444,'d':500,'e':444,'f':278,'g':500,'h':500,'i':278,'j':278,'k':444,'l':278,'m':722, + 'n':500,'o':500,'p':500,'q':500,'r':389,'s':389,'t':278,'u':500,'v':444,'w':667,'x':444,'y':444,'z':389,'{':400,'|':275,'}':400,'~':541,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500, + '\x84':556,'\x85':889,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':500,'\x8b':333,'\x8c':944,'\x8d':350,'\x8e':556,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':556,'\x94':556,'\x95':350,'\x96':500,'\x97':889,'\x98':333,'\x99':980, + '\x9a':389,'\x9b':333,'\x9c':667,'\x9d':350,'\x9e':389,'\x9f':556,'\xa0':250,'\xa1':389,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':275,'\xa7':500,'\xa8':333,'\xa9':760,'\xaa':276,'\xab':500,'\xac':675,'\xad':333,'\xae':760,'\xaf':333, + '\xb0':400,'\xb1':675,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':500,'\xb6':523,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':310,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':500,'\xc0':611,'\xc1':611,'\xc2':611,'\xc3':611,'\xc4':611,'\xc5':611, + '\xc6':889,'\xc7':667,'\xc8':611,'\xc9':611,'\xca':611,'\xcb':611,'\xcc':333,'\xcd':333,'\xce':333,'\xcf':333,'\xd0':722,'\xd1':667,'\xd2':722,'\xd3':722,'\xd4':722,'\xd5':722,'\xd6':722,'\xd7':675,'\xd8':722,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':556,'\xde':611,'\xdf':500,'\xe0':500,'\xe1':500,'\xe2':500,'\xe3':500,'\xe4':500,'\xe5':500,'\xe6':667,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':500, + '\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':675,'\xf8':500,'\xf9':500,'\xfa':500,'\xfb':500,'\xfc':500,'\xfd':444,'\xfe':500,'\xff':444} + +fpdf_charwidths['zapfdingbats']={ + '\x00':0,'\x01':0,'\x02':0,'\x03':0,'\x04':0,'\x05':0,'\x06':0,'\x07':0,'\x08':0,'\t':0,'\n':0,'\x0b':0,'\x0c':0,'\r':0,'\x0e':0,'\x0f':0,'\x10':0,'\x11':0,'\x12':0,'\x13':0,'\x14':0,'\x15':0, + '\x16':0,'\x17':0,'\x18':0,'\x19':0,'\x1a':0,'\x1b':0,'\x1c':0,'\x1d':0,'\x1e':0,'\x1f':0,' ':278,'!':974,'"':961,'#':974,'$':980,'%':719,'&':789,'\'':790,'(':791,')':690,'*':960,'+':939, + ',':549,'-':855,'.':911,'/':933,'0':911,'1':945,'2':974,'3':755,'4':846,'5':762,'6':761,'7':571,'8':677,'9':763,':':760,';':759,'<':754,'=':494,'>':552,'?':537,'@':577,'A':692, + 'B':786,'C':788,'D':788,'E':790,'F':793,'G':794,'H':816,'I':823,'J':789,'K':841,'L':823,'M':833,'N':816,'O':831,'P':923,'Q':744,'R':723,'S':749,'T':790,'U':792,'V':695,'W':776, + 'X':768,'Y':792,'Z':759,'[':707,'\\':708,']':682,'^':701,'_':826,'`':815,'a':789,'b':789,'c':707,'d':687,'e':696,'f':689,'g':786,'h':787,'i':713,'j':791,'k':785,'l':791,'m':873, + 'n':761,'o':762,'p':762,'q':759,'r':759,'s':892,'t':892,'u':788,'v':784,'w':438,'x':138,'y':277,'z':415,'{':392,'|':392,'}':668,'~':668,'\x7f':0,'\x80':390,'\x81':390,'\x82':317,'\x83':317, + '\x84':276,'\x85':276,'\x86':509,'\x87':509,'\x88':410,'\x89':410,'\x8a':234,'\x8b':234,'\x8c':334,'\x8d':334,'\x8e':0,'\x8f':0,'\x90':0,'\x91':0,'\x92':0,'\x93':0,'\x94':0,'\x95':0,'\x96':0,'\x97':0,'\x98':0,'\x99':0, + '\x9a':0,'\x9b':0,'\x9c':0,'\x9d':0,'\x9e':0,'\x9f':0,'\xa0':0,'\xa1':732,'\xa2':544,'\xa3':544,'\xa4':910,'\xa5':667,'\xa6':760,'\xa7':760,'\xa8':776,'\xa9':595,'\xaa':694,'\xab':626,'\xac':788,'\xad':788,'\xae':788,'\xaf':788, + '\xb0':788,'\xb1':788,'\xb2':788,'\xb3':788,'\xb4':788,'\xb5':788,'\xb6':788,'\xb7':788,'\xb8':788,'\xb9':788,'\xba':788,'\xbb':788,'\xbc':788,'\xbd':788,'\xbe':788,'\xbf':788,'\xc0':788,'\xc1':788,'\xc2':788,'\xc3':788,'\xc4':788,'\xc5':788, + '\xc6':788,'\xc7':788,'\xc8':788,'\xc9':788,'\xca':788,'\xcb':788,'\xcc':788,'\xcd':788,'\xce':788,'\xcf':788,'\xd0':788,'\xd1':788,'\xd2':788,'\xd3':788,'\xd4':894,'\xd5':838,'\xd6':1016,'\xd7':458,'\xd8':748,'\xd9':924,'\xda':748,'\xdb':918, + '\xdc':927,'\xdd':928,'\xde':928,'\xdf':834,'\xe0':873,'\xe1':828,'\xe2':924,'\xe3':924,'\xe4':917,'\xe5':930,'\xe6':931,'\xe7':463,'\xe8':883,'\xe9':836,'\xea':836,'\xeb':867,'\xec':867,'\xed':696,'\xee':696,'\xef':874,'\xf0':0,'\xf1':874, + '\xf2':760,'\xf3':946,'\xf4':771,'\xf5':865,'\xf6':771,'\xf7':888,'\xf8':967,'\xf9':888,'\xfa':831,'\xfb':873,'\xfc':927,'\xfd':970,'\xfe':918,'\xff':0} + diff --git a/web2py/gluon/contrib/fpdf/fpdf.py b/web2py/gluon/contrib/fpdf/fpdf.py new file mode 100644 index 0000000..4274701 --- /dev/null +++ b/web2py/gluon/contrib/fpdf/fpdf.py @@ -0,0 +1,2059 @@ +#!/usr/bin/env python +# -*- coding: latin-1 -*- +# **************************************************************************** +# * Software: FPDF for python * +# * Version: 1.7.1 * +# * Date: 2010-09-10 * +# * Last update: 2012-08-16 * +# * License: LGPL v3.0 * +# * * +# * Original Author (PHP): Olivier PLATHEY 2004-12-31 * +# * Ported to Python 2.4 by Max (maxpat78@yahoo.it) on 2006-05 * +# * Maintainer: Mariano Reingart (reingart@gmail.com) et al since 2008 est. * +# * NOTE: 'I' and 'D' destinations are disabled, and simply print to STDOUT * +# **************************************************************************** + +from __future__ import division, with_statement + +from datetime import datetime +from functools import wraps +import math +import errno +import os, sys, zlib, struct, re, tempfile, struct + +from .ttfonts import TTFontFile +from .fonts import fpdf_charwidths +from .php import substr, sprintf, print_r, UTF8ToUTF16BE, UTF8StringToArray +from .py3k import PY3K, pickle, urlopen, BytesIO, Image, basestring, unicode, exception, b, hashpath + +# Global variables +FPDF_VERSION = '1.7.2' +FPDF_FONT_DIR = os.path.join(os.path.dirname(__file__),'font') +FPDF_CACHE_MODE = 0 # 0 - in same folder, 1 - none, 2 - hash +FPDF_CACHE_DIR = None +SYSTEM_TTFONTS = None + +PAGE_FORMATS = { + "a3": (841.89, 1190.55), + "a4": (595.28, 841.89), + "a5": (420.94, 595.28), + "letter": (612, 792), + "legal": (612, 1008), +} + +def set_global(var, val): + globals()[var] = val + +def load_cache(filename): + """Return unpickled object, or None if cache unavailable""" + if not filename: + return None + try: + with open(filename, "rb") as fh: + return pickle.load(fh) + except (IOError, ValueError): # File missing, unsupported pickle, etc + return None + +class FPDF(object): + "PDF Generation class" + + def __init__(self, orientation = 'P', unit = 'mm', format = 'A4'): + # Some checks + self._dochecks() + # Initialization of properties + self.offsets = {} # array of object offsets + self.page = 0 # current page number + self.n = 2 # current object number + self.buffer = '' # buffer holding in-memory PDF + self.pages = {} # array containing pages and metadata + self.state = 0 # current document state + self.fonts = {} # array of used fonts + self.font_files = {} # array of font files + self.diffs = {} # array of encoding differences + self.images = {} # array of used images + self.page_links = {} # array of links in pages + self.links = {} # array of internal links + self.in_footer = 0 # flag set when processing footer + self.lastw = 0 + self.lasth = 0 # height of last cell printed + self.font_family = '' # current font family + self.font_style = '' # current font style + self.font_size_pt = 12 # current font size in points + self.font_stretching = 100 # current font stretching + self.underline = 0 # underlining flag + self.draw_color = '0 G' + self.fill_color = '0 g' + self.text_color = '0 g' + self.color_flag = 0 # indicates whether fill and text colors are different + self.ws = 0 # word spacing + self.angle = 0 + # Standard fonts + self.core_fonts={'courier': 'Courier', 'courierB': 'Courier-Bold', + 'courierI': 'Courier-Oblique', 'courierBI': 'Courier-BoldOblique', + 'helvetica': 'Helvetica', 'helveticaB': 'Helvetica-Bold', + 'helveticaI': 'Helvetica-Oblique', + 'helveticaBI': 'Helvetica-BoldOblique', + 'times': 'Times-Roman', 'timesB': 'Times-Bold', + 'timesI': 'Times-Italic', 'timesBI': 'Times-BoldItalic', + 'symbol': 'Symbol', 'zapfdingbats': 'ZapfDingbats'} + self.core_fonts_encoding = "latin-1" + # Scale factor + if unit == "pt": + self.k = 1 + elif unit == "mm": + self.k = 72 / 25.4 + elif unit == "cm": + self.k = 72 / 2.54 + elif unit == 'in': + self.k = 72. + else: + self.error("Incorrect unit: " + unit) + # Page format + self.fw_pt, self.fh_pt = self.get_page_format(format, self.k) + self.dw_pt = self.fw_pt + self.dh_pt = self.fh_pt + self.fw = self.fw_pt / self.k + self.fh = self.fh_pt / self.k + # Page orientation + orientation = orientation.lower() + if orientation in ('p', 'portrait'): + self.def_orientation = 'P' + self.w_pt = self.fw_pt + self.h_pt = self.fh_pt + elif orientation in ('l', 'landscape'): + self.def_orientation = 'L' + self.w_pt = self.fh_pt + self.h_pt = self.fw_pt + else: + self.error('Incorrect orientation: ' + orientation) + self.cur_orientation = self.def_orientation + self.w = self.w_pt / self.k + self.h = self.h_pt / self.k + # Page margins (1 cm) + margin = 28.35 / self.k + self.set_margins(margin, margin) + # Interior cell margin (1 mm) + self.c_margin = margin / 10.0 + # line width (0.2 mm) + self.line_width = .567 / self.k + # Automatic page break + self.set_auto_page_break(1, 2 * margin) + # Full width display mode + self.set_display_mode('fullwidth') + # Enable compression + self.set_compression(1) + # Set default PDF version number + self.pdf_version = '1.3' + + @staticmethod + def get_page_format(format, k): + "Return scale factor, page w and h size in points" + if isinstance(format, basestring): + format = format.lower() + if format in PAGE_FORMATS: + return PAGE_FORMATS[format] + else: + raise RuntimeError("Unknown page format: " + format) + else: + return (format[0] * k, format[1] * k) + + def check_page(fn): + "Decorator to protect drawing methods" + @wraps(fn) + def wrapper(self, *args, **kwargs): + if not self.page and not kwargs.get('split_only'): + self.error("No page open, you need to call add_page() first") + else: + return fn(self, *args, **kwargs) + return wrapper + + def set_margins(self, left,top,right=-1): + "Set left, top and right margins" + self.l_margin=left + self.t_margin=top + if(right==-1): + right=left + self.r_margin=right + + def set_left_margin(self, margin): + "Set left margin" + self.l_margin=margin + if(self.page>0 and self.x0): + #Page footer + self.in_footer=1 + self.footer() + self.in_footer=0 + #close page + self._endpage() + #Start new page + self._beginpage(orientation, format, same) + #Set line cap style to square + self._out('2 J') + #Set line width + self.line_width=lw + self._out(sprintf('%.2f w',lw*self.k)) + #Set font + if(family): + self.set_font(family,style,size) + #Set colors + self.draw_color=dc + if(dc!='0 G'): + self._out(dc) + self.fill_color=fc + if(fc!='0 g'): + self._out(fc) + self.text_color=tc + self.color_flag=cf + #Page header + self.header() + #Restore line width + if(self.line_width!=lw): + self.line_width=lw + self._out(sprintf('%.2f w',lw*self.k)) + #Restore font + if(family): + self.set_font(family,style,size) + #Restore colors + if(self.draw_color!=dc): + self.draw_color=dc + self._out(dc) + if(self.fill_color!=fc): + self.fill_color=fc + self._out(fc) + self.text_color=tc + self.color_flag=cf + #Restore stretching + if(stretching != 100): + self.set_stretching(stretching) + + def header(self): + "Header to be implemented in your own inherited class" + pass + + def footer(self): + "Footer to be implemented in your own inherited class" + pass + + def page_no(self): + "Get current page number" + return self.page + + def set_draw_color(self, r,g=-1,b=-1): + "Set color for all stroking operations" + if((r==0 and g==0 and b==0) or g==-1): + self.draw_color=sprintf('%.3f G',r/255.0) + else: + self.draw_color=sprintf('%.3f %.3f %.3f RG',r/255.0,g/255.0,b/255.0) + if(self.page>0): + self._out(self.draw_color) + + def set_fill_color(self,r,g=-1,b=-1): + "Set color for all filling operations" + if((r==0 and g==0 and b==0) or g==-1): + self.fill_color=sprintf('%.3f g',r/255.0) + else: + self.fill_color=sprintf('%.3f %.3f %.3f rg',r/255.0,g/255.0,b/255.0) + self.color_flag=(self.fill_color!=self.text_color) + if(self.page>0): + self._out(self.fill_color) + + def set_text_color(self, r,g=-1,b=-1): + "Set color for text" + if((r==0 and g==0 and b==0) or g==-1): + self.text_color=sprintf('%.3f g',r/255.0) + else: + self.text_color=sprintf('%.3f %.3f %.3f rg',r/255.0,g/255.0,b/255.0) + self.color_flag=(self.fill_color!=self.text_color) + + def get_string_width(self, s, normalized = False): + "Get width of a string in the current font" + # normalized is parameter for internal use + s = s if normalized else self.normalize_text(s) + cw=self.current_font['cw'] + w=0 + l=len(s) + if self.unifontsubset: + for char in s: + char = ord(char) + if len(cw) > char: + w += cw[char] # ord(cw[2*char])<<8 + ord(cw[2*char+1]) + #elif (char>0 and char<128 and isset($cw[chr($char)])) { $w += $cw[chr($char)]; } + elif (self.current_font['desc']['MissingWidth']) : + w += self.current_font['desc']['MissingWidth'] + #elif (isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; } + else: + w += 500 + else: + for i in range(0, l): + w += cw.get(s[i],0) + if self.font_stretching != 100: + w = w * self.font_stretching / 100.0 + return w * self.font_size / 1000.0 + + def set_line_width(self, width): + "Set line width" + self.line_width=width + if(self.page>0): + self._out(sprintf('%.2f w',width*self.k)) + + @check_page + def line(self, x1,y1,x2,y2): + "Draw a line" + self._out(sprintf('%.2f %.2f m %.2f %.2f l S',x1*self.k,(self.h-y1)*self.k,x2*self.k,(self.h-y2)*self.k)) + + def _set_dash(self, dash_length=False, space_length=False): + if(dash_length and space_length): + s = sprintf('[%.3f %.3f] 0 d', dash_length*self.k, space_length*self.k) + else: + s = '[] 0 d' + self._out(s) + + @check_page + def dashed_line(self, x1,y1,x2,y2, dash_length=1, space_length=1): + """Draw a dashed line. Same interface as line() except: + - dash_length: Length of the dash + - space_length: Length of the space between dashes""" + self._set_dash(dash_length, space_length) + self.line(x1, y1, x2, y2) + self._set_dash() + + @check_page + def rect(self, x,y,w,h,style=''): + "Draw a rectangle" + if(style=='F'): + op='f' + elif(style=='FD' or style=='DF'): + op='B' + else: + op='S' + self._out(sprintf('%.2f %.2f %.2f %.2f re %s',x*self.k,(self.h-y)*self.k,w*self.k,-h*self.k,op)) + + @check_page + def ellipse(self, x,y,w,h,style=''): + "Draw a ellipse" + if(style=='F'): + op='f' + elif(style=='FD' or style=='DF'): + op='B' + else: + op='S' + + cx = x + w/2.0 + cy = y + h/2.0 + rx = w/2.0 + ry = h/2.0 + + lx = 4.0/3.0*(math.sqrt(2)-1)*rx + ly = 4.0/3.0*(math.sqrt(2)-1)*ry + + self._out(sprintf('%.2f %.2f m %.2f %.2f %.2f %.2f %.2f %.2f c', + (cx+rx)*self.k, (self.h-cy)*self.k, + (cx+rx)*self.k, (self.h-(cy-ly))*self.k, + (cx+lx)*self.k, (self.h-(cy-ry))*self.k, + cx*self.k, (self.h-(cy-ry))*self.k)) + self._out(sprintf('%.2f %.2f %.2f %.2f %.2f %.2f c', + (cx-lx)*self.k, (self.h-(cy-ry))*self.k, + (cx-rx)*self.k, (self.h-(cy-ly))*self.k, + (cx-rx)*self.k, (self.h-cy)*self.k)) + self._out(sprintf('%.2f %.2f %.2f %.2f %.2f %.2f c', + (cx-rx)*self.k, (self.h-(cy+ly))*self.k, + (cx-lx)*self.k, (self.h-(cy+ry))*self.k, + cx*self.k, (self.h-(cy+ry))*self.k)) + self._out(sprintf('%.2f %.2f %.2f %.2f %.2f %.2f c %s', + (cx+lx)*self.k, (self.h-(cy+ry))*self.k, + (cx+rx)*self.k, (self.h-(cy+ly))*self.k, + (cx+rx)*self.k, (self.h-cy)*self.k, + op)) + + def add_font(self, family, style='', fname='', uni=False): + "Add a TrueType or Type1 font" + family = family.lower() + if (fname == ''): + fname = family.replace(' ','') + style.lower() + '.pkl' + if (family == 'arial'): + family = 'helvetica' + style = style.upper() + if (style == 'IB'): + style = 'BI' + fontkey = family+style + if fontkey in self.fonts: + # Font already added! + return + if (uni): + global SYSTEM_TTFONTS, FPDF_CACHE_MODE, FPDF_CACHE_DIR + if os.path.exists(fname): + ttffilename = fname + elif (FPDF_FONT_DIR and + os.path.exists(os.path.join(FPDF_FONT_DIR, fname))): + ttffilename = os.path.join(FPDF_FONT_DIR, fname) + elif (SYSTEM_TTFONTS and + os.path.exists(os.path.join(SYSTEM_TTFONTS, fname))): + ttffilename = os.path.join(SYSTEM_TTFONTS, fname) + else: + raise RuntimeError("TTF Font file not found: %s" % fname) + name = '' + if FPDF_CACHE_MODE == 0: + unifilename = os.path.splitext(ttffilename)[0] + '.pkl' + elif FPDF_CACHE_MODE == 2: + unifilename = os.path.join(FPDF_CACHE_DIR, \ + hashpath(ttffilename) + ".pkl") + else: + unifilename = None + font_dict = load_cache(unifilename) + if font_dict is None: + ttf = TTFontFile() + ttf.getMetrics(ttffilename) + desc = { + 'Ascent': int(round(ttf.ascent, 0)), + 'Descent': int(round(ttf.descent, 0)), + 'CapHeight': int(round(ttf.capHeight, 0)), + 'Flags': ttf.flags, + 'FontBBox': "[%s %s %s %s]" % ( + int(round(ttf.bbox[0], 0)), + int(round(ttf.bbox[1], 0)), + int(round(ttf.bbox[2], 0)), + int(round(ttf.bbox[3], 0))), + 'ItalicAngle': int(ttf.italicAngle), + 'StemV': int(round(ttf.stemV, 0)), + 'MissingWidth': int(round(ttf.defaultWidth, 0)), + } + # Generate metrics .pkl file + font_dict = { + 'name': re.sub('[ ()]', '', ttf.fullName), + 'type': 'TTF', + 'desc': desc, + 'up': round(ttf.underlinePosition), + 'ut': round(ttf.underlineThickness), + 'ttffile': ttffilename, + 'fontkey': fontkey, + 'originalsize': os.stat(ttffilename).st_size, + 'cw': ttf.charWidths, + } + if unifilename: + try: + with open(unifilename, "wb") as fh: + pickle.dump(font_dict, fh) + except IOError: + if not exception().errno == errno.EACCES: + raise # Not a permission error. + del ttf + if hasattr(self,'str_alias_nb_pages'): + sbarr = list(range(0,57)) # include numbers in the subset! + else: + sbarr = list(range(0,32)) + self.fonts[fontkey] = { + 'i': len(self.fonts)+1, 'type': font_dict['type'], + 'name': font_dict['name'], 'desc': font_dict['desc'], + 'up': font_dict['up'], 'ut': font_dict['ut'], + 'cw': font_dict['cw'], + 'ttffile': font_dict['ttffile'], 'fontkey': fontkey, + 'subset': sbarr, 'unifilename': unifilename, + } + self.font_files[fontkey] = {'length1': font_dict['originalsize'], + 'type': "TTF", 'ttffile': ttffilename} + self.font_files[fname] = {'type': "TTF"} + else: + with open(fname, 'rb') as fontfile: + font_dict = pickle.load(fontfile) + self.fonts[fontkey] = {'i': len(self.fonts)+1} + self.fonts[fontkey].update(font_dict) + diff = font_dict.get('diff') + if (diff): + #Search existing encodings + d = 0 + nb = len(self.diffs) + for i in range(1, nb+1): + if(self.diffs[i] == diff): + d = i + break + if (d == 0): + d = nb + 1 + self.diffs[d] = diff + self.fonts[fontkey]['diff'] = d + filename = font_dict.get('filename') + if (filename): + if (font_dict['type'] == 'TrueType'): + originalsize = font_dict['originalsize'] + self.font_files[filename]={'length1': originalsize} + else: + self.font_files[filename]={'length1': font_dict['size1'], + 'length2': font_dict['size2']} + + def set_font(self, family,style='',size=0): + "Select a font; size given in points" + family=family.lower() + if(family==''): + family=self.font_family + if(family=='arial'): + family='helvetica' + elif(family=='symbol' or family=='zapfdingbats'): + style='' + style=style.upper() + if('U' in style): + self.underline=1 + style=style.replace('U','') + else: + self.underline=0 + if(style=='IB'): + style='BI' + if(size==0): + size=self.font_size_pt + #Test if font is already selected + if(self.font_family==family and self.font_style==style and self.font_size_pt==size): + return + #Test if used for the first time + fontkey=family+style + if fontkey not in self.fonts: + #Check if one of the standard fonts + if fontkey in self.core_fonts: + if fontkey not in fpdf_charwidths: + #Load metric file + name=os.path.join(FPDF_FONT_DIR,family) + if(family=='times' or family=='helvetica'): + name+=style.lower() + with open(name+'.font') as file: + exec(compile(file.read(), name+'.font', 'exec')) + if fontkey not in fpdf_charwidths: + self.error('Could not include font metric file for'+fontkey) + i=len(self.fonts)+1 + self.fonts[fontkey]={'i':i,'type':'core','name':self.core_fonts[fontkey],'up':-100,'ut':50,'cw':fpdf_charwidths[fontkey]} + else: + self.error('Undefined font: '+family+' '+style) + #Select it + self.font_family=family + self.font_style=style + self.font_size_pt=size + self.font_size=size/self.k + self.current_font=self.fonts[fontkey] + self.unifontsubset = (self.fonts[fontkey]['type'] == 'TTF') + if(self.page>0): + self._out(sprintf('BT /F%d %.2f Tf ET',self.current_font['i'],self.font_size_pt)) + + def set_font_size(self, size): + "Set font size in points" + if(self.font_size_pt==size): + return + self.font_size_pt=size + self.font_size=size/self.k + if(self.page>0): + self._out(sprintf('BT /F%d %.2f Tf ET',self.current_font['i'],self.font_size_pt)) + + def set_stretching(self, factor): + "Set from stretch factor percents (default: 100.0)" + if(self.font_stretching == factor): + return + self.font_stretching = factor + if (self.page > 0): + self._out(sprintf('BT %.2f Tz ET', self.font_stretching)) + + def add_link(self): + "Create a new internal link" + n=len(self.links)+1 + self.links[n]=(0,0) + return n + + def set_link(self, link,y=0,page=-1): + "Set destination of internal link" + if(y==-1): + y=self.y + if(page==-1): + page=self.page + self.links[link]=[page,y] + + def link(self, x,y,w,h,link): + "Put a link on the page" + if not self.page in self.page_links: + self.page_links[self.page] = [] + self.page_links[self.page] += [(x*self.k,self.h_pt-y*self.k,w*self.k,h*self.k,link),] + + @check_page + def text(self, x, y, txt=''): + "Output a string" + txt = self.normalize_text(txt) + if (self.unifontsubset): + txt2 = self._escape(UTF8ToUTF16BE(txt, False)) + for uni in UTF8StringToArray(txt): + self.current_font['subset'].append(uni) + else: + txt2 = self._escape(txt) + s=sprintf('BT %.2f %.2f Td (%s) Tj ET',x*self.k,(self.h-y)*self.k, txt2) + if(self.underline and txt!=''): + s+=' '+self._dounderline(x,y,txt) + if(self.color_flag): + s='q '+self.text_color+' '+s+' Q' + self._out(s) + + @check_page + def rotate(self, angle, x=None, y=None): + if x is None: + x = self.x + if y is None: + y = self.y; + if self.angle!=0: + self._out('Q') + self.angle = angle + if angle!=0: + angle *= math.pi/180; + c = math.cos(angle); + s = math.sin(angle); + cx = x*self.k; + cy = (self.h-y)*self.k + s = sprintf('q %.5F %.5F %.5F %.5F %.2F %.2F cm 1 0 0 1 %.2F %.2F cm',c,s,-s,c,cx,cy,-cx,-cy) + self._out(s) + + def accept_page_break(self): + "Accept automatic page break or not" + return self.auto_page_break + + @check_page + def cell(self, w,h=0,txt='',border=0,ln=0,align='',fill=0,link=''): + "Output a cell" + txt = self.normalize_text(txt) + k=self.k + if(self.y+h>self.page_break_trigger and not self.in_footer and self.accept_page_break()): + #Automatic page break + x=self.x + ws=self.ws + if(ws>0): + self.ws=0 + self._out('0 Tw') + self.add_page(same = True) + self.x=x + if(ws>0): + self.ws=ws + self._out(sprintf('%.3f Tw',ws*k)) + if(w==0): + w=self.w-self.r_margin-self.x + s='' + if(fill==1 or border==1): + if(fill==1): + if border==1: + op='B' + else: + op='f' + else: + op='S' + s=sprintf('%.2f %.2f %.2f %.2f re %s ',self.x*k,(self.h-self.y)*k,w*k,-h*k,op) + if(isinstance(border,basestring)): + x=self.x + y=self.y + if('L' in border): + s+=sprintf('%.2f %.2f m %.2f %.2f l S ',x*k,(self.h-y)*k,x*k,(self.h-(y+h))*k) + if('T' in border): + s+=sprintf('%.2f %.2f m %.2f %.2f l S ',x*k,(self.h-y)*k,(x+w)*k,(self.h-y)*k) + if('R' in border): + s+=sprintf('%.2f %.2f m %.2f %.2f l S ',(x+w)*k,(self.h-y)*k,(x+w)*k,(self.h-(y+h))*k) + if('B' in border): + s+=sprintf('%.2f %.2f m %.2f %.2f l S ',x*k,(self.h-(y+h))*k,(x+w)*k,(self.h-(y+h))*k) + if(txt!=''): + if(align=='R'): + dx=w-self.c_margin-self.get_string_width(txt, True) + elif(align=='C'): + dx=(w-self.get_string_width(txt, True))/2.0 + else: + dx=self.c_margin + if(self.color_flag): + s+='q '+self.text_color+' ' + + # If multibyte, Tw has no effect - do word spacing using an adjustment before each space + if (self.ws and self.unifontsubset): + for uni in UTF8StringToArray(txt): + self.current_font['subset'].append(uni) + space = self._escape(UTF8ToUTF16BE(' ', False)) + s += sprintf('BT 0 Tw %.2F %.2F Td [',(self.x + dx) * k,(self.h - (self.y + 0.5*h+ 0.3 * self.font_size)) * k) + t = txt.split(' ') + numt = len(t) + for i in range(numt): + tx = t[i] + tx = '(' + self._escape(UTF8ToUTF16BE(tx, False)) + ')' + s += sprintf('%s ', tx); + if ((i+1)0): + #Go to next line + self.y+=h + if(ln==1): + self.x=self.l_margin + else: + self.x+=w + + @check_page + def multi_cell(self, w, h, txt='', border=0, align='J', fill=0, split_only=False): + "Output text with automatic or explicit line breaks" + txt = self.normalize_text(txt) + ret = [] # if split_only = True, returns splited text cells + cw=self.current_font['cw'] + if(w==0): + w=self.w-self.r_margin-self.x + wmax=(w-2*self.c_margin)*1000.0/self.font_size + s=txt.replace("\r",'') + nb=len(s) + if(nb>0 and s[nb-1]=="\n"): + nb-=1 + b=0 + if(border): + if(border==1): + border='LTRB' + b='LRT' + b2='LR' + else: + b2='' + if('L' in border): + b2+='L' + if('R' in border): + b2+='R' + if ('T' in border): + b=b2+'T' + else: + b=b2 + sep=-1 + i=0 + j=0 + l=0 + ns=0 + nl=1 + while(i0): + self.ws=0 + if not split_only: + self._out('0 Tw') + if not split_only: + self.cell(w,h,substr(s,j,i-j),b,2,align,fill) + else: + ret.append(substr(s,j,i-j)) + i+=1 + sep=-1 + j=i + l=0 + ns=0 + nl+=1 + if(border and nl==2): + b=b2 + continue + if(c==' '): + sep=i + ls=l + ns+=1 + if self.unifontsubset: + l += self.get_string_width(c, True) / self.font_size*1000.0 + else: + l += cw.get(c,0) + if(l>wmax): + #Automatic line break + if(sep==-1): + if(i==j): + i+=1 + if(self.ws>0): + self.ws=0 + if not split_only: + self._out('0 Tw') + if not split_only: + self.cell(w,h,substr(s,j,i-j),b,2,align,fill) + else: + ret.append(substr(s,j,i-j)) + else: + if(align=='J'): + if ns>1: + self.ws=(wmax-ls)/1000.0*self.font_size/(ns-1) + else: + self.ws=0 + if not split_only: + self._out(sprintf('%.3f Tw',self.ws*self.k)) + if not split_only: + self.cell(w,h,substr(s,j,sep-j),b,2,align,fill) + else: + ret.append(substr(s,j,sep-j)) + i=sep+1 + sep=-1 + j=i + l=0 + ns=0 + nl+=1 + if(border and nl==2): + b=b2 + else: + i+=1 + #Last chunk + if(self.ws>0): + self.ws=0 + if not split_only: + self._out('0 Tw') + if(border and 'B' in border): + b+='B' + if not split_only: + self.cell(w,h,substr(s,j,i-j),b,2,align,fill) + self.x=self.l_margin + else: + ret.append(substr(s,j,i-j)) + return ret + + @check_page + def write(self, h, txt='', link=''): + "Output text in flowing mode" + txt = self.normalize_text(txt) + cw=self.current_font['cw'] + w=self.w-self.r_margin-self.x + wmax=(w-2*self.c_margin)*1000.0/self.font_size + s=txt.replace("\r",'') + nb=len(s) + sep=-1 + i=0 + j=0 + l=0 + nl=1 + while(iwmax): + #Automatic line break + if(sep==-1): + if(self.x>self.l_margin): + #Move to next line + self.x=self.l_margin + self.y+=h + w=self.w-self.r_margin-self.x + wmax=(w-2*self.c_margin)*1000.0/self.font_size + i+=1 + nl+=1 + continue + if(i==j): + i+=1 + self.cell(w,h,substr(s,j,i-j),0,2,'',0,link) + else: + self.cell(w,h,substr(s,j,sep-j),0,2,'',0,link) + i=sep+1 + sep=-1 + j=i + l=0 + if(nl==1): + self.x=self.l_margin + w=self.w-self.r_margin-self.x + wmax=(w-2*self.c_margin)*1000.0/self.font_size + nl+=1 + else: + i+=1 + #Last chunk + if(i!=j): + self.cell(l/1000.0*self.font_size,h,substr(s,j),0,0,'',0,link) + + @check_page + def image(self, name, x=None, y=None, w=0,h=0,type='',link=''): + "Put an image on the page" + if not name in self.images: + #First use of image, get info + if(type==''): + pos=name.rfind('.') + if(not pos): + self.error('image file has no extension and no type was specified: '+name) + type=substr(name,pos+1) + type=type.lower() + if(type=='jpg' or type=='jpeg'): + info=self._parsejpg(name) + elif(type=='png'): + info=self._parsepng(name) + else: + #Allow for additional formats + #maybe the image is not showing the correct extension, + #but the header is OK, + succeed_parsing = False + #try all the parsing functions + parsing_functions = [self._parsejpg,self._parsepng,self._parsegif] + for pf in parsing_functions: + try: + info = pf(name) + succeed_parsing = True + break; + except: + pass + #last resource + if not succeed_parsing: + mtd='_parse'+type + if not hasattr(self,mtd): + self.error('Unsupported image type: '+type) + info=getattr(self, mtd)(name) + mtd='_parse'+type + if not hasattr(self,mtd): + self.error('Unsupported image type: '+type) + info=getattr(self, mtd)(name) + info['i']=len(self.images)+1 + self.images[name]=info + else: + info=self.images[name] + #Automatic width and height calculation if needed + if(w==0 and h==0): + #Put image at 72 dpi + w=info['w']/self.k + h=info['h']/self.k + elif(w==0): + w=h*info['w']/info['h'] + elif(h==0): + h=w*info['h']/info['w'] + # Flowing mode + if y is None: + if (self.y + h > self.page_break_trigger and not self.in_footer and self.accept_page_break()): + #Automatic page break + x = self.x + self.add_page(same = True) + self.x = x + y = self.y + self.y += h + if x is None: + x = self.x + self._out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q',w*self.k,h*self.k,x*self.k,(self.h-(y+h))*self.k,info['i'])) + if(link): + self.link(x,y,w,h,link) + + @check_page + def ln(self, h=''): + "Line Feed; default value is last cell height" + self.x=self.l_margin + if(isinstance(h, basestring)): + self.y+=self.lasth + else: + self.y+=h + + def get_x(self): + "Get x position" + return self.x + + def set_x(self, x): + "Set x position" + if(x>=0): + self.x=x + else: + self.x=self.w+x + + def get_y(self): + "Get y position" + return self.y + + def set_y(self, y): + "Set y position and reset x" + self.x=self.l_margin + if(y>=0): + self.y=y + else: + self.y=self.h+y + + def set_xy(self, x,y): + "Set x and y positions" + self.set_y(y) + self.set_x(x) + + def output(self, name='',dest=''): + """Output PDF to some destination + + By default the PDF is written to sys.stdout. If a name is given, the + PDF is written to a new file. If dest='S' is given, the PDF data is + returned as a byte string.""" + + #Finish document if necessary + if(self.state<3): + self.close() + dest=dest.upper() + if(dest==''): + if(name==''): + dest='I' + else: + dest='F' + if PY3K: + # manage binary data as latin1 until PEP461 or similar is implemented + buffer = self.buffer.encode("latin1") + else: + buffer = self.buffer + if dest in ('I', 'D'): + # Python < 3 writes byte data transparently without "buffer" + stdout = getattr(sys.stdout, 'buffer', sys.stdout) + stdout.write(buffer) + elif dest=='F': + #Save to local file + with open(name,'wb') as f: + f.write(buffer) + elif dest=='S': + #Return as a byte string + return buffer + else: + self.error('Incorrect output destination: '+dest) + + def normalize_text(self, txt): + "Check that text input is in the correct format/encoding" + # - for TTF unicode fonts: unicode object (utf8 encoding) + # - for built-in fonts: string instances (encoding: latin-1, cp1252) + if not PY3K: + if self.unifontsubset and isinstance(txt, str): + return txt.decode("utf-8") + elif not self.unifontsubset and isinstance(txt, unicode): + return txt.encode(self.core_fonts_encoding) + else: + if not self.unifontsubset and self.core_fonts_encoding: + return txt.encode(self.core_fonts_encoding).decode("latin-1") + return txt + + def _dochecks(self): + #Check for locale-related bug +# if(1.1==1): +# self.error("Don\'t alter the locale before including class file"); + #Check for decimal separator + if(sprintf('%.1f',1.0)!='1.0'): + import locale + locale.setlocale(locale.LC_NUMERIC,'C') + + def _getfontpath(self): + return FPDF_FONT_DIR+'/' + + def _putpages(self): + nb = self.page + if hasattr(self, 'str_alias_nb_pages'): + # Replace number of pages in fonts using subsets (unicode) + alias = UTF8ToUTF16BE(self.str_alias_nb_pages, False) + r = UTF8ToUTF16BE(str(nb), False) + for n in range(1, nb + 1): + self.pages[n]["content"] = \ + self.pages[n]["content"].replace(alias, r) + # Now repeat for no pages in non-subset fonts + for n in range(1,nb + 1): + self.pages[n]["content"] = \ + self.pages[n]["content"].replace(self.str_alias_nb_pages, + str(nb)) + if self.def_orientation == 'P': + dw_pt = self.dw_pt + dh_pt = self.dh_pt + else: + dw_pt = self.dh_pt + dh_pt = self.dw_pt + if self.compress: + filter = '/Filter /FlateDecode ' + else: + filter = '' + for n in range(1, nb + 1): + # Page + self._newobj() + self._out('<>>>' + else: + l = self.links[pl[4]] + if l[0] in self.orientation_changes: + h = w_pt + else: + h = h_pt + annots += sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>', + 1 + 2 * l[0], h - l[1] * self.k) + self._out(annots + ']') + if self.pdf_version > '1.3': + self._out('/Group <>') + self._out('/Contents ' + str(self.n + 1) + ' 0 R>>') + self._out('endobj') + # Page content + content = self.pages[n]["content"] + if self.compress: + # manage binary data as latin1 until PEP461 or similar is implemented + p = content.encode("latin1") if PY3K else content + p = zlib.compress(p) + else: + p = content + self._newobj() + self._out('<<' + filter + '/Length ' + str(len(p)) + '>>') + self._putstream(p) + self._out('endobj') + # Pages root + self.offsets[1] = len(self.buffer) + self._out('1 0 obj') + self._out('<>') + self._out('endobj') + + def _putfonts(self): + nf=self.n + for diff in self.diffs: + #Encodings + self._newobj() + self._out('<>') + self._out('endobj') + for name,info in self.font_files.items(): + if 'type' in info and info['type'] != 'TTF': + #Font file embedding + self._newobj() + self.font_files[name]['n']=self.n + with open(self._getfontpath()+name,'rb',1) as f: + font=f.read() + compressed=(substr(name,-2)=='.z') + if(not compressed and 'length2' in info): + header=(ord(font[0])==128) + if(header): + #Strip first binary header + font=substr(font,6) + if(header and ord(font[info['length1']])==128): + #Strip second binary header + font=substr(font,0,info['length1'])+substr(font,info['length1']+6) + self._out('<>') + self._putstream(font) + self._out('endobj') + flist = [(x[1]["i"],x[0],x[1]) for x in self.fonts.items()] + flist.sort() + for idx,k,font in flist: + #Font objects + self.fonts[k]['n']=self.n+1 + type=font['type'] + name=font['name'] + if(type=='core'): + #Standard font + self._newobj() + self._out('<>') + self._out('endobj') + elif(type=='Type1' or type=='TrueType'): + #Additional Type1 or TrueType font + self._newobj() + self._out('<>') + self._out('endobj') + #Widths + self._newobj() + cw=font['cw'] + s='[' + for i in range(32,256): + # Get doesn't raise exception; returns 0 instead of None if not set + s+=str(cw.get(chr(i)) or 0)+' ' + self._out(s+']') + self._out('endobj') + #Descriptor + self._newobj() + s='<>') + self._out('endobj') + elif (type == 'TTF'): + self.fonts[k]['n'] = self.n + 1 + ttf = TTFontFile() + fontname = 'MPDFAA' + '+' + font['name'] + subset = font['subset'] + del subset[0] + ttfontstream = ttf.makeSubset(font['ttffile'], subset) + ttfontsize = len(ttfontstream) + fontstream = zlib.compress(ttfontstream) + codeToGlyph = ttf.codeToGlyph + ##del codeToGlyph[0] + # Type0 Font + # A composite font - a font composed of other fonts, organized hierarchically + self._newobj() + self._out('<>') + self._out('endobj') + + # CIDFontType2 + # A CIDFont whose glyph descriptions are based on TrueType font technology + self._newobj() + self._out('<>') + self._out('endobj') + + # ToUnicode + self._newobj() + toUni = "/CIDInit /ProcSet findresource begin\n" \ + "12 dict begin\n" \ + "begincmap\n" \ + "/CIDSystemInfo\n" \ + "<> def\n" \ + "/CMapName /Adobe-Identity-UCS def\n" \ + "/CMapType 2 def\n" \ + "1 begincodespacerange\n" \ + "<0000> \n" \ + "endcodespacerange\n" \ + "1 beginbfrange\n" \ + "<0000> <0000>\n" \ + "endbfrange\n" \ + "endcmap\n" \ + "CMapName currentdict /CMap defineresource pop\n" \ + "end\n" \ + "end" + self._out('<>') + self._putstream(toUni) + self._out('endobj') + + # CIDSystemInfo dictionary + self._newobj() + self._out('<>') + self._out('endobj') + + # Font descriptor + self._newobj() + self._out('<>') + self._out('endobj') + + # Embed CIDToGIDMap + # A specification of the mapping from CIDs to glyph indices + cidtogidmap = ''; + cidtogidmap = ["\x00"] * 256*256*2 + for cc, glyph in codeToGlyph.items(): + cidtogidmap[cc*2] = chr(glyph >> 8) + cidtogidmap[cc*2 + 1] = chr(glyph & 0xFF) + cidtogidmap = ''.join(cidtogidmap) + if PY3K: + # manage binary data as latin1 until PEP461-like function is implemented + cidtogidmap = cidtogidmap.encode("latin1") + cidtogidmap = zlib.compress(cidtogidmap); + self._newobj() + self._out('<>') + self._putstream(cidtogidmap) + self._out('endobj') + + #Font file + self._newobj() + self._out('<>') + self._putstream(fontstream) + self._out('endobj') + del ttf + else: + #Allow for additional types + mtd='_put'+type.lower() + if(not method_exists(self,mtd)): + self.error('Unsupported font type: '+type) + self.mtd(font) + + def _putTTfontwidths(self, font, maxUni): + if font['unifilename']: + cw127fname = os.path.splitext(font['unifilename'])[0] + '.cw127.pkl' + else: + cw127fname = None + font_dict = load_cache(cw127fname) + if font_dict is None: + rangeid = 0 + range_ = {} + range_interval = {} + prevcid = -2 + prevwidth = -1 + interval = False + startcid = 1 + else: + rangeid = font_dict['rangeid'] + range_ = font_dict['range'] + prevcid = font_dict['prevcid'] + prevwidth = font_dict['prevwidth'] + interval = font_dict['interval'] + range_interval = font_dict['range_interval'] + startcid = 128 + cwlen = maxUni + 1 + + # for each character + subset = set(font['subset']) + for cid in range(startcid, cwlen): + if cid == 128 and cw127fname and not os.path.exists(cw127fname): + try: + with open(cw127fname, "wb") as fh: + font_dict = {} + font_dict['rangeid'] = rangeid + font_dict['prevcid'] = prevcid + font_dict['prevwidth'] = prevwidth + font_dict['interval'] = interval + font_dict['range_interval'] = range_interval + font_dict['range'] = range_ + pickle.dump(font_dict, fh) + except IOError: + if not exception().errno == errno.EACCES: + raise # Not a permission error. + if cid > 255 and (cid not in subset): # + continue + width = font['cw'][cid] + if (width == 0): + continue + if (width == 65535): width = 0 + if ('dw' not in font or (font['dw'] and width != font['dw'])): + if (cid == (prevcid + 1)): + if (width == prevwidth): + if (width == range_[rangeid][0]): + range_.setdefault(rangeid, []).append(width) + else: + range_[rangeid].pop() + # new range + rangeid = prevcid + range_[rangeid] = [prevwidth, width] + interval = True + range_interval[rangeid] = True + else: + if (interval): + # new range + rangeid = cid + range_[rangeid] = [width] + else: + range_[rangeid].append(width) + interval = False + else: + rangeid = cid + range_[rangeid] = [width] + interval = False + prevcid = cid + prevwidth = width + prevk = -1 + nextk = -1 + prevint = False + for k, ws in sorted(range_.items()): + cws = len(ws) + if (k == nextk and not prevint and (not k in range_interval or cws < 3)): + if (k in range_interval): + del range_interval[k] + range_[prevk] = range_[prevk] + range_[k] + del range_[k] + else: + prevk = k + nextk = k + cws + if (k in range_interval): + prevint = (cws > 3) + del range_interval[k] + nextk -= 1 + else: + prevint = False + w = [] + for k, ws in sorted(range_.items()): + if (len(set(ws)) == 1): + w.append(' %s %s %s' % (k, k + len(ws) - 1, ws[0])) + else: + w.append(' %s [ %s ]\n' % (k, ' '.join([str(int(h)) for h in ws]))) ## + self._out('/W [%s]' % ''.join(w)) + + def _putimages(self): + filter='' + if self.compress: + filter='/Filter /FlateDecode ' + i = [(x[1]["i"],x[1]) for x in self.images.items()] + i.sort() + for idx,info in i: + self._putimage(info) + del info['data'] + if 'smask' in info: + del info['smask'] + + def _putimage(self, info): + if 'data' in info: + self._newobj() + info['n']=self.n + self._out('<>') + if('trns' in info and isinstance(info['trns'], list)): + trns='' + for i in range(0,len(info['trns'])): + trns+=str(info['trns'][i])+' '+str(info['trns'][i])+' ' + self._out('/Mask ['+trns+']') + if('smask' in info): + self._out('/SMask ' + str(self.n+1) + ' 0 R'); + self._out('/Length '+str(len(info['data']))+'>>') + self._putstream(info['data']) + self._out('endobj') + # Soft mask + if('smask' in info): + dp = '/Predictor 15 /Colors 1 /BitsPerComponent 8 /Columns ' + str(info['w']) + smask = {'w': info['w'], 'h': info['h'], 'cs': 'DeviceGray', 'bpc': 8, 'f': info['f'], 'dp': dp, 'data': info['smask']} + self._putimage(smask) + #Palette + if(info['cs']=='Indexed'): + self._newobj() + filter = self.compress and '/Filter /FlateDecode ' or '' + if self.compress: + pal=zlib.compress(info['pal']) + else: + pal=info['pal'] + self._out('<<'+filter+'/Length '+str(len(pal))+'>>') + self._putstream(pal) + self._out('endobj') + + def _putxobjectdict(self): + i = [(x["i"],x["n"]) for x in self.images.values()] + i.sort() + for idx,n in i: + self._out('/I'+str(idx)+' '+str(n)+' 0 R') + + def _putresourcedict(self): + self._out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]') + self._out('/Font <<') + f = [(x["i"],x["n"]) for x in self.fonts.values()] + f.sort() + for idx,n in f: + self._out('/F'+str(idx)+' '+str(n)+' 0 R') + self._out('>>') + self._out('/XObject <<') + self._putxobjectdict() + self._out('>>') + + def _putresources(self): + self._putfonts() + self._putimages() + #Resource dictionary + self.offsets[2]=len(self.buffer) + self._out('2 0 obj') + self._out('<<') + self._putresourcedict() + self._out('>>') + self._out('endobj') + + def _putinfo(self): + self._out('/Producer '+self._textstring('PyFPDF '+FPDF_VERSION+' http://pyfpdf.googlecode.com/')) + if hasattr(self,'title'): + self._out('/Title '+self._textstring(self.title)) + if hasattr(self,'subject'): + self._out('/Subject '+self._textstring(self.subject)) + if hasattr(self,'author'): + self._out('/Author '+self._textstring(self.author)) + if hasattr (self,'keywords'): + self._out('/Keywords '+self._textstring(self.keywords)) + if hasattr(self,'creator'): + self._out('/Creator '+self._textstring(self.creator)) + self._out('/CreationDate '+self._textstring('D:'+datetime.now().strftime('%Y%m%d%H%M%S'))) + + def _putcatalog(self): + self._out('/Type /Catalog') + self._out('/Pages 1 0 R') + if(self.zoom_mode=='fullpage'): + self._out('/OpenAction [3 0 R /Fit]') + elif(self.zoom_mode=='fullwidth'): + self._out('/OpenAction [3 0 R /FitH null]') + elif(self.zoom_mode=='real'): + self._out('/OpenAction [3 0 R /XYZ null null 1]') + elif(not isinstance(self.zoom_mode,basestring)): + self._out(sprintf('/OpenAction [3 0 R /XYZ null null %s]',self.zoom_mode/100)) + if(self.layout_mode=='single'): + self._out('/PageLayout /SinglePage') + elif(self.layout_mode=='continuous'): + self._out('/PageLayout /OneColumn') + elif(self.layout_mode=='two'): + self._out('/PageLayout /TwoColumnLeft') + + def _putheader(self): + self._out('%PDF-'+self.pdf_version) + + def _puttrailer(self): + self._out('/Size '+str(self.n+1)) + self._out('/Root '+str(self.n)+' 0 R') + self._out('/Info '+str(self.n-1)+' 0 R') + + def _enddoc(self): + self._putheader() + self._putpages() + self._putresources() + #Info + self._newobj() + self._out('<<') + self._putinfo() + self._out('>>') + self._out('endobj') + #Catalog + self._newobj() + self._out('<<') + self._putcatalog() + self._out('>>') + self._out('endobj') + #Cross-ref + o=len(self.buffer) + self._out('xref') + self._out('0 '+(str(self.n+1))) + self._out('0000000000 65535 f ') + for i in range(1,self.n+1): + self._out(sprintf('%010d 00000 n ',self.offsets[i])) + #Trailer + self._out('trailer') + self._out('<<') + self._puttrailer() + self._out('>>') + self._out('startxref') + self._out(o) + self._out('%%EOF') + self.state=3 + + def _beginpage(self, orientation, format, same): + self.page += 1 + self.pages[self.page] = {"content": ""} + self.state = 2 + self.x = self.l_margin + self.y = self.t_margin + self.font_family = '' + self.font_stretching = 100 + if not same: + # Page format + if format: + # Change page format + self.fw_pt, self.fh_pt = self.get_page_format(format, self.k) + else: + # Set to default format + self.fw_pt = self.dw_pt + self.fh_pt = self.dh_pt + self.fw = self.fw_pt / self.k + self.fh = self.fh_pt / self.k + # Page orientation + if not orientation: + orientation = self.def_orientation + else: + orientation = orientation[0].upper() + if orientation == 'P': + self.w_pt = self.fw_pt + self.h_pt = self.fh_pt + else: + self.w_pt = self.fh_pt + self.h_pt = self.fw_pt + self.w = self.w_pt / self.k + self.h = self.h_pt / self.k + self.cur_orientation = orientation + self.page_break_trigger = self.h - self.b_margin + self.cur_orientation = orientation + self.pages[self.page]["w_pt"] = self.w_pt + self.pages[self.page]["h_pt"] = self.h_pt + + def _endpage(self): + #End of page contents + self.state=1 + + def _newobj(self): + #Begin a new object + self.n+=1 + self.offsets[self.n]=len(self.buffer) + self._out(str(self.n)+' 0 obj') + + def _dounderline(self, x, y, txt): + #Underline text + up=self.current_font['up'] + ut=self.current_font['ut'] + w=self.get_string_width(txt, True)+self.ws*txt.count(' ') + return sprintf('%.2f %.2f %.2f %.2f re f',x*self.k,(self.h-(y-up/1000.0*self.font_size))*self.k,w*self.k,-ut/1000.0*self.font_size_pt) + + def load_resource(self, reason, filename): + "Load external file" + # by default loading from network is allowed for all images + if reason == "image": + if filename.startswith("http://") or filename.startswith("https://"): + f = BytesIO(urlopen(filename).read()) + else: + f = open(filename, "rb") + return f + else: + self.error("Unknown resource loading reason \"%s\"" % reason) + + def _parsejpg(self, filename): + # Extract info from a JPEG file + f = None + try: + f = self.load_resource("image", filename) + while True: + markerHigh, markerLow = struct.unpack('BB', f.read(2)) + if markerHigh != 0xFF or markerLow < 0xC0: + raise SyntaxError('No JPEG marker found') + elif markerLow == 0xDA: # SOS + raise SyntaxError('No JPEG SOF marker found') + elif (markerLow == 0xC8 or # JPG + (markerLow >= 0xD0 and markerLow <= 0xD9) or # RSTx + (markerLow >= 0xF0 and markerLow <= 0xFD)): # JPGx + pass + else: + dataSize, = struct.unpack('>H', f.read(2)) + data = f.read(dataSize - 2) if dataSize > 2 else '' + if ((markerLow >= 0xC0 and markerLow <= 0xC3) or # SOF0 - SOF3 + (markerLow >= 0xC5 and markerLow <= 0xC7) or # SOF4 - SOF7 + (markerLow >= 0xC9 and markerLow <= 0xCB) or # SOF9 - SOF11 + (markerLow >= 0xCD and markerLow <= 0xCF)): # SOF13 - SOF15 + bpc, height, width, layers = struct.unpack_from('>BHHB', data) + colspace = 'DeviceRGB' if layers == 3 else ('DeviceCMYK' if layers == 4 else 'DeviceGray') + break + except Exception: + if f: + f.close() + self.error('Missing or incorrect image file: %s. error: %s' % (filename, str(exception()))) + + with f: + # Read whole file from the start + f.seek(0) + data = f.read() + return {'w':width,'h':height,'cs':colspace,'bpc':bpc,'f':'DCTDecode','data':data} + + def _parsegif(self, filename): + # Extract info from a GIF file (via PNG conversion) + if Image is None: + self.error('PIL is required for GIF support') + try: + im = Image.open(filename) + except Exception: + self.error('Missing or incorrect image file: %s. error: %s' % (filename, str(exception()))) + else: + # Use temporary file + with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as \ + f: + tmp = f.name + if "transparency" in im.info: + im.save(tmp, transparency = im.info['transparency']) + else: + im.save(tmp) + info = self._parsepng(tmp) + os.unlink(tmp) + return info + + def _parsepng(self, filename): + #Extract info from a PNG file + f = self.load_resource("image", filename) + #Check signature + magic = f.read(8).decode("latin1") + signature = '\x89'+'PNG'+'\r'+'\n'+'\x1a'+'\n' + if not PY3K: signature = signature.decode("latin1") + if(magic!=signature): + self.error('Not a PNG file: ' + filename) + #Read header chunk + f.read(4) + chunk = f.read(4).decode("latin1") + if(chunk!='IHDR'): + self.error('Incorrect PNG file: ' + filename) + w=self._freadint(f) + h=self._freadint(f) + bpc=ord(f.read(1)) + if(bpc>8): + self.error('16-bit depth not supported: ' + filename) + ct=ord(f.read(1)) + if(ct==0 or ct==4): + colspace='DeviceGray' + elif(ct==2 or ct==6): + colspace='DeviceRGB' + elif(ct==3): + colspace='Indexed' + else: + self.error('Unknown color type: ' + filename) + if(ord(f.read(1))!=0): + self.error('Unknown compression method: ' + filename) + if(ord(f.read(1))!=0): + self.error('Unknown filter method: ' + filename) + if(ord(f.read(1))!=0): + self.error('Interlacing not supported: ' + filename) + f.read(4) + dp='/Predictor 15 /Colors ' + if colspace == 'DeviceRGB': + dp+='3' + else: + dp+='1' + dp+=' /BitsPerComponent '+str(bpc)+' /Columns '+str(w)+'' + #Scan chunks looking for palette, transparency and image data + pal='' + trns='' + data=bytes() if PY3K else str() + n=1 + while n != None: + n=self._freadint(f) + type=f.read(4).decode("latin1") + if(type=='PLTE'): + #Read palette + pal=f.read(n) + f.read(4) + elif(type=='tRNS'): + #Read transparency info + t=f.read(n) + if(ct==0): + trns=[ord(substr(t,1,1)),] + elif(ct==2): + trns=[ord(substr(t,1,1)),ord(substr(t,3,1)),ord(substr(t,5,1))] + else: + pos=t.find('\x00'.encode("latin1")) + if(pos!=-1): + trns=[pos,] + f.read(4) + elif(type=='IDAT'): + #Read image data block + data+=f.read(n) + f.read(4) + elif(type=='IEND'): + break + else: + f.read(n+4) + if(colspace=='Indexed' and not pal): + self.error('Missing palette in ' + filename) + f.close() + info = {'w':w,'h':h,'cs':colspace,'bpc':bpc,'f':'FlateDecode','dp':dp,'pal':pal,'trns':trns,} + if(ct>=4): + # Extract alpha channel + data = zlib.decompress(data) + color = b('') + alpha = b('') + if(ct==4): + # Gray image + length = 2*w + for i in range(h): + pos = (1+length)*i + color += b(data[pos]) + alpha += b(data[pos]) + line = substr(data, pos+1, length) + re_c = re.compile('(.).'.encode("ascii"), flags=re.DOTALL) + re_a = re.compile('.(.)'.encode("ascii"), flags=re.DOTALL) + color += re_c.sub(lambda m: m.group(1), line) + alpha += re_a.sub(lambda m: m.group(1), line) + else: + # RGB image + length = 4*w + for i in range(h): + pos = (1+length)*i + color += b(data[pos]) + alpha += b(data[pos]) + line = substr(data, pos+1, length) + re_c = re.compile('(...).'.encode("ascii"), flags=re.DOTALL) + re_a = re.compile('...(.)'.encode("ascii"), flags=re.DOTALL) + color += re_c.sub(lambda m: m.group(1), line) + alpha += re_a.sub(lambda m: m.group(1), line) + del data + data = zlib.compress(color) + info['smask'] = zlib.compress(alpha) + if (self.pdf_version < '1.4'): + self.pdf_version = '1.4' + info['data'] = data + return info + + def _freadint(self, f): + #Read a 4-byte integer from file + try: + return struct.unpack('>I', f.read(4))[0] + except: + return None + + def _textstring(self, s): + #Format a text string + return '('+self._escape(s)+')' + + def _escape(self, s): + #Add \ before \, ( and ) + return s.replace('\\','\\\\').replace(')','\\)').replace('(','\\(').replace('\r','\\r') + + def _putstream(self, s): + self._out('stream') + self._out(s) + self._out('endstream') + + def _out(self, s): + #Add a line to the document + if PY3K and isinstance(s, bytes): + # manage binary data as latin1 until PEP461-like function is implemented + s = s.decode("latin1") + elif not PY3K and isinstance(s, unicode): + s = s.encode("latin1") # default encoding (font name and similar) + elif not isinstance(s, basestring): + s = str(s) + if(self.state == 2): + self.pages[self.page]["content"] += (s + "\n") + else: + self.buffer += (s + "\n") + + @check_page + def interleaved2of5(self, txt, x, y, w=1.0, h=10.0): + "Barcode I2of5 (numeric), adds a 0 if odd lenght" + narrow = w / 3.0 + wide = w + + # wide/narrow codes for the digits + bar_char={'0': 'nnwwn', '1': 'wnnnw', '2': 'nwnnw', '3': 'wwnnn', + '4': 'nnwnw', '5': 'wnwnn', '6': 'nwwnn', '7': 'nnnww', + '8': 'wnnwn', '9': 'nwnwn', 'A': 'nn', 'Z': 'wn'} + + self.set_fill_color(0) + code = txt + # add leading zero if code-length is odd + if len(code) % 2 != 0: + code = '0' + code + + # add start and stop codes + code = 'AA' + code.lower() + 'ZA' + + for i in range(0, len(code), 2): + # choose next pair of digits + char_bar = code[i] + char_space = code[i+1] + # check whether it is a valid digit + if not char_bar in bar_char.keys(): + raise RuntimeError ('Char "%s" invalid for I25: ' % char_bar) + if not char_space in bar_char.keys(): + raise RuntimeError ('Char "%s" invalid for I25: ' % char_space) + + # create a wide/narrow-seq (first digit=bars, second digit=spaces) + seq = '' + for s in range(0, len(bar_char[char_bar])): + seq += bar_char[char_bar][s] + bar_char[char_space][s] + + for bar in range(0, len(seq)): + # set line_width depending on value + if seq[bar] == 'n': + line_width = narrow + else: + line_width = wide + + # draw every second value, the other is represented by space + if bar % 2 == 0: + self.rect(x, y, line_width, h, 'F') + + x += line_width + + + @check_page + def code39(self, txt, x, y, w=1.5, h=5.0): + """Barcode 3of9""" + dim = {'w': w, 'n': w/3.} + chars = { + '0': 'nnnwwnwnn', '1': 'wnnwnnnnw', '2': 'nnwwnnnnw', + '3': 'wnwwnnnnn', '4': 'nnnwwnnnw', '5': 'wnnwwnnnn', + '6': 'nnwwwnnnn', '7': 'nnnwnnwnw', '8': 'wnnwnnwnn', + '9': 'nnwwnnwnn', 'A': 'wnnnnwnnw', 'B': 'nnwnnwnnw', + 'C': 'wnwnnwnnn', 'D': 'nnnnwwnnw', 'E': 'wnnnwwnnn', + 'F': 'nnwnwwnnn', 'G': 'nnnnnwwnw', 'H': 'wnnnnwwnn', + 'I': 'nnwnnwwnn', 'J': 'nnnnwwwnn', 'K': 'wnnnnnnww', + 'L': 'nnwnnnnww', 'M': 'wnwnnnnwn', 'N': 'nnnnwnnww', + 'O': 'wnnnwnnwn', 'P': 'nnwnwnnwn', 'Q': 'nnnnnnwww', + 'R': 'wnnnnnwwn', 'S': 'nnwnnnwwn', 'T': 'nnnnwnwwn', + 'U': 'wwnnnnnnw', 'V': 'nwwnnnnnw', 'W': 'wwwnnnnnn', + 'X': 'nwnnwnnnw', 'Y': 'wwnnwnnnn', 'Z': 'nwwnwnnnn', + '-': 'nwnnnnwnw', '.': 'wwnnnnwnn', ' ': 'nwwnnnwnn', + '*': 'nwnnwnwnn', '$': 'nwnwnwnnn', '/': 'nwnwnnnwn', + '+': 'nwnnnwnwn', '%': 'nnnwnwnwn', + } + self.set_fill_color(0) + for c in txt.upper(): + if c not in chars: + raise RuntimeError('Invalid char "%s" for Code39' % c) + for i, d in enumerate(chars[c]): + if i % 2 == 0: + self.rect(x, y, dim[d], h, 'F') + x += dim[d] + x += dim['n'] + + diff --git a/web2py/gluon/contrib/fpdf/html.py b/web2py/gluon/contrib/fpdf/html.py new file mode 100644 index 0000000..60eb6b2 --- /dev/null +++ b/web2py/gluon/contrib/fpdf/html.py @@ -0,0 +1,402 @@ +# -*- coding: latin-1 -*- + +"HTML Renderer for FPDF.py" + +__author__ = "Mariano Reingart " +__copyright__ = "Copyright (C) 2010 Mariano Reingart" +__license__ = "LGPL 3.0" + +# Inspired by tuto5.py and several examples from fpdf.org, html2fpdf, etc. + +from .fpdf import FPDF +from .py3k import PY3K, basestring, unicode, HTMLParser + +DEBUG = False + +def px2mm(px): + return int(px)*25.4/72.0 + +def hex2dec(color = "#000000"): + if color: + r = int(color[1:3], 16) + g = int(color[3:5], 16) + b = int(color[5:7], 16) + return r, g, b + +class HTML2FPDF(HTMLParser): + "Render basic HTML to FPDF" + + def __init__(self, pdf, image_map=None): + HTMLParser.__init__(self) + self.style = {} + self.pre = False + self.href = '' + self.align = '' + self.page_links = {} + self.font = None + self.font_stack = [] + self.pdf = pdf + self.image_map = image_map or (lambda src: src) + self.r = self.g = self.b = 0 + self.indent = 0 + self.bullet = [] + self.set_font("times", 12) + self.font_face = "times" # initialize font + self.color = 0 #initialize font color + self.table = None # table attributes + self.table_col_width = None # column (header) widths + self.table_col_index = None # current column index + self.td = None # cell attributes + self.th = False # header enabled + self.tr = None + self.theader = None # table header cells + self.tfooter = None # table footer cells + self.thead = None + self.tfoot = None + self.theader_out = self.tfooter_out = False + self.hsize = dict(h1=2, h2=1.5, h3=1.17, h4=1, h5=0.83, h6=0.67) + + def width2mm(self, length): + if length[-1]=='%': + total = self.pdf.w - self.pdf.r_margin - self.pdf.l_margin + if self.table['width'][-1]=='%': + total *= int(self.table['width'][:-1])/100.0 + return int(length[:-1]) * total / 101.0 + else: + return int(length) / 6.0 + + def handle_data(self, txt): + if self.td is not None: # drawing a table? + if 'width' not in self.td and 'colspan' not in self.td: + try: + l = [self.table_col_width[self.table_col_index]] + except IndexError: + raise RuntimeError("Table column/cell width not specified, unable to continue") + elif 'colspan' in self.td: + i = self.table_col_index + colspan = int(self.td['colspan']) + l = self.table_col_width[i:i+colspan] + else: + l = [self.td.get('width','240')] + w = sum([self.width2mm(length) for length in l]) + h = int(self.td.get('height', 0)) // 4 or self.h*1.30 + self.table_h = h + border = int(self.table.get('border', 0)) + if not self.th: + align = self.td.get('align', 'L')[0].upper() + border = border and 'LR' + else: + self.set_style('B',True) + border = border or 'B' + align = self.td.get('align', 'C')[0].upper() + bgcolor = hex2dec(self.td.get('bgcolor', self.tr.get('bgcolor', ''))) + # parsing table header/footer (drawn later): + if self.thead is not None: + self.theader.append(((w,h,txt,border,0,align), bgcolor)) + if self.tfoot is not None: + self.tfooter.append(((w,h,txt,border,0,align), bgcolor)) + # check if reached end of page, add table footer and header: + height = h + (self.tfooter and self.tfooter[0][0][1] or 0) + if self.pdf.y+height>self.pdf.page_break_trigger and not self.th: + self.output_table_footer() + self.pdf.add_page(same = True) + self.theader_out = self.tfooter_out = False + if self.tfoot is None and self.thead is None: + if not self.theader_out: + self.output_table_header() + self.box_shadow(w, h, bgcolor) + if DEBUG: print("td cell", self.pdf.x, w, txt, "*") + self.pdf.cell(w,h,txt,border,0,align) + elif self.table is not None: + # ignore anything else than td inside a table + pass + elif self.align: + if DEBUG: print("cell", txt, "*") + self.pdf.cell(0,self.h,txt,0,1,self.align[0].upper(), self.href) + else: + txt = txt.replace("\n"," ") + if self.href: + self.put_link(self.href,txt) + else: + if DEBUG: print("write", txt, "*") + self.pdf.write(self.h,txt) + + def box_shadow(self, w, h, bgcolor): + if DEBUG: print("box_shadow", w, h, bgcolor) + if bgcolor: + fill_color = self.pdf.fill_color + self.pdf.set_fill_color(*bgcolor) + self.pdf.rect(self.pdf.x, self.pdf.y, w, h, 'F') + self.pdf.fill_color = fill_color + + def output_table_header(self): + if self.theader: + b = self.b + x = self.pdf.x + self.pdf.set_x(self.table_offset) + self.set_style('B',True) + for cell, bgcolor in self.theader: + self.box_shadow(cell[0], cell[1], bgcolor) + self.pdf.cell(*cell) + self.set_style('B',b) + self.pdf.ln(self.theader[0][0][1]) + self.pdf.set_x(self.table_offset) + #self.pdf.set_x(x) + self.theader_out = True + + def output_table_footer(self): + if self.tfooter: + x = self.pdf.x + self.pdf.set_x(self.table_offset) + #TODO: self.output_table_sep() + for cell, bgcolor in self.tfooter: + self.box_shadow(cell[0], cell[1], bgcolor) + self.pdf.cell(*cell) + self.pdf.ln(self.tfooter[0][0][1]) + self.pdf.set_x(x) + if int(self.table.get('border', 0)): + self.output_table_sep() + self.tfooter_out = True + + def output_table_sep(self): + self.pdf.set_x(self.table_offset) + x1 = self.pdf.x + y1 = self.pdf.y + w = sum([self.width2mm(lenght) for lenght in self.table_col_width]) + self.pdf.line(x1,y1,x1+w,y1) + + + def handle_starttag(self, tag, attrs): + attrs = dict(attrs) + if DEBUG: print("STARTTAG", tag, attrs) + if tag=='b' or tag=='i' or tag=='u': + self.set_style(tag,1) + if tag=='a': + self.href=attrs['href'] + if tag=='br': + self.pdf.ln(5) + if tag=='p': + self.pdf.ln(5) + if attrs: + if attrs: self.align = attrs.get('align') + if tag in self.hsize: + k = self.hsize[tag] + self.pdf.ln(5*k) + self.pdf.set_text_color(150,0,0) + self.pdf.set_font_size(12 * k) + if attrs: self.align = attrs.get('align') + if tag=='hr': + self.put_line() + if tag=='pre': + self.pdf.set_font('Courier','',11) + self.pdf.set_font_size(11) + self.set_style('B',False) + self.set_style('I',False) + self.pre = True + if tag=='blockquote': + self.set_text_color(100,0,45) + self.pdf.ln(3) + if tag=='ul': + self.indent+=1 + self.bullet.append('\x95') + if tag=='ol': + self.indent+=1 + self.bullet.append(0) + if tag=='li': + self.pdf.ln(self.h+2) + self.pdf.set_text_color(190,0,0) + bullet = self.bullet[self.indent-1] + if not isinstance(bullet, basestring): + bullet += 1 + self.bullet[self.indent-1] = bullet + bullet = "%s. " % bullet + self.pdf.write(self.h,'%s%s ' % (' '*5*self.indent, bullet)) + self.set_text_color() + if tag=='font': + # save previous font state: + self.font_stack.append((self.font_face, self.font_size, self.color)) + if 'color' in attrs: + color = hex2dec(attrs['color']) + self.set_text_color(*color) + self.color = color + if 'face' in attrs: + face = attrs.get('face').lower() + try: + self.pdf.set_font(face) + self.font_face = face + except RuntimeError: + pass # font not found, ignore + if 'size' in attrs: + size = int(attrs.get('size')) + self.pdf.set_font(self.font_face, size=int(size)) + self.font_size = size + if tag=='table': + self.table = dict([(k.lower(), v) for k,v in attrs.items()]) + if not 'width' in self.table: + self.table['width'] = '100%' + if self.table['width'][-1]=='%': + w = self.pdf.w - self.pdf.r_margin - self.pdf.l_margin + w *= int(self.table['width'][:-1])/100.0 + self.table_offset = (self.pdf.w-w)/2.0 + self.table_col_width = [] + self.theader_out = self.tfooter_out = False + self.theader = [] + self.tfooter = [] + self.thead = None + self.tfoot = None + self.table_h = 0 + self.pdf.ln() + if tag=='tr': + self.tr = dict([(k.lower(), v) for k,v in attrs.items()]) + self.table_col_index = 0 + self.pdf.set_x(self.table_offset) + if tag=='td': + self.td = dict([(k.lower(), v) for k,v in attrs.items()]) + if tag=='th': + self.td = dict([(k.lower(), v) for k,v in attrs.items()]) + self.th = True + if 'width' in self.td: + self.table_col_width.append(self.td['width']) + if tag=='thead': + self.thead = {} + if tag=='tfoot': + self.tfoot = {} + if tag=='img': + if 'src' in attrs: + x = self.pdf.get_x() + y = self.pdf.get_y() + w = px2mm(attrs.get('width', 0)) + h = px2mm(attrs.get('height',0)) + if self.align and self.align[0].upper() == 'C': + x = (self.pdf.w-x)/2.0 - w/2.0 + self.pdf.image(self.image_map(attrs['src']), + x, y, w, h, link=self.href) + self.pdf.set_x(x+w) + self.pdf.set_y(y+h) + if tag=='b' or tag=='i' or tag=='u': + self.set_style(tag, True) + if tag=='center': + self.align = 'Center' + + def handle_endtag(self, tag): + #Closing tag + if DEBUG: print("ENDTAG", tag) + if tag=='h1' or tag=='h2' or tag=='h3' or tag=='h4': + self.pdf.ln(6) + self.set_font() + self.set_style() + self.align = None + if tag=='pre': + self.pdf.set_font(self.font or 'Times','',12) + self.pdf.set_font_size(12) + self.pre=False + if tag=='blockquote': + self.set_text_color(0,0,0) + self.pdf.ln(3) + if tag=='strong': + tag='b' + if tag=='em': + tag='i' + if tag=='b' or tag=='i' or tag=='u': + self.set_style(tag, False) + if tag=='a': + self.href='' + if tag=='p': + self.align='' + if tag in ('ul', 'ol'): + self.indent-=1 + self.bullet.pop() + if tag=='table': + if not self.tfooter_out: + self.output_table_footer() + self.table = None + self.th = False + self.theader = None + self.tfooter = None + self.pdf.ln() + if tag=='thead': + self.thead = None + if tag=='tfoot': + self.tfoot = None + if tag=='tbody': + # draw a line separator between table bodies + self.pdf.set_x(self.table_offset) + self.output_table_sep() + if tag=='tr': + h = self.table_h + if self.tfoot is None: + self.pdf.ln(h) + self.tr = None + if tag=='td' or tag=='th': + if self.th: + if DEBUG: print("revert style") + self.set_style('B', False) # revert style + self.table_col_index += int(self.td.get('colspan','1')) + self.td = None + self.th = False + if tag=='font': + # recover last font state + face, size, color = self.font_stack.pop() + if face: + self.pdf.set_text_color(0,0,0) + self.color = None + self.set_font(face, size) + self.font = None + if tag=='center': + self.align = None + + def set_font(self, face=None, size=None): + if face: + self.font_face = face + if size: + self.font_size = size + self.h = size / 72.0*25.4 + if DEBUG: print("H", self.h) + self.pdf.set_font(self.font_face or 'times','',12) + self.pdf.set_font_size(self.font_size or 12) + self.set_style('u', False) + self.set_style('b', False) + self.set_style('i', False) + self.set_text_color() + + def set_style(self, tag=None, enable=None): + #Modify style and select corresponding font + if tag: + t = self.style.get(tag.lower()) + self.style[tag.lower()] = enable + style='' + for s in ('b','i','u'): + if self.style.get(s): + style+=s + if DEBUG: print("SET_FONT_STYLE", style) + self.pdf.set_font('',style) + + def set_text_color(self, r=None, g=0, b=0): + if r is None: + self.pdf.set_text_color(self.r,self.g,self.b) + else: + self.pdf.set_text_color(r, g, b) + self.r = r + self.g = g + self.b = b + + def put_link(self, url, txt): + #Put a hyperlink + self.set_text_color(0,0,255) + self.set_style('u', True) + self.pdf.write(5,txt,url) + self.set_style('u', False) + self.set_text_color(0) + + def put_line(self): + self.pdf.ln(2) + self.pdf.line(self.pdf.get_x(),self.pdf.get_y(),self.pdf.get_x()+187,self.pdf.get_y()) + self.pdf.ln(3) + +class HTMLMixin(object): + def write_html(self, text, image_map=None): + "Parse HTML and convert it to PDF" + h2p = HTML2FPDF(self, image_map) + text = h2p.unescape(text) # To deal with HTML entities + h2p.feed(text) + diff --git a/web2py/gluon/contrib/fpdf/php.py b/web2py/gluon/contrib/fpdf/php.py new file mode 100644 index 0000000..b95bbf0 --- /dev/null +++ b/web2py/gluon/contrib/fpdf/php.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +# -*- coding: latin-1 -*- + +from .py3k import PY3K, basestring, unicode + +# fpdf php helpers: + +def substr(s, start, length=-1): + if length < 0: + length=len(s)-start + return s[start:start+length] + +def sprintf(fmt, *args): return fmt % args + +def print_r(array): + if not isinstance(array, dict): + array = dict([(k, k) for k in array]) + for k, v in array.items(): + print("[%s] => %s " % (k, v)) + +def UTF8ToUTF16BE(instr, setbom=True): + "Converts UTF-8 strings to UTF16-BE." + outstr = "".encode() + if (setbom): + outstr += "\xFE\xFF".encode("latin1") + if not isinstance(instr, unicode): + instr = instr.decode('UTF-8') + outstr += instr.encode('UTF-16BE') + # convert bytes back to fake unicode string until PEP461-like is implemented + if PY3K: + outstr = outstr.decode("latin1") + return outstr + +def UTF8StringToArray(instr): + "Converts UTF-8 strings to codepoints array" + return [ord(c) for c in instr] + +# ttfints php helpers: + +def die(msg): + raise RuntimeError(msg) + +def str_repeat(s, count): + return s * count + +def str_pad(s, pad_length=0, pad_char= " ", pad_type= +1 ): + if pad_type<0: # pad left + return s.rjust(pad_length, pad_char) + elif pad_type>0: # pad right + return s.ljust(pad_length, pad_char) + else: # pad both + return s.center(pad_length, pad_char) + +strlen = count = lambda s: len(s) diff --git a/web2py/gluon/contrib/fpdf/py3k.py b/web2py/gluon/contrib/fpdf/py3k.py new file mode 100644 index 0000000..86b16e3 --- /dev/null +++ b/web2py/gluon/contrib/fpdf/py3k.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"Special module to handle differences between Python 2 and 3 versions" + +import sys + +PY3K = sys.version_info >= (3, 0) + +try: + import cPickle as pickle +except ImportError: + import pickle + +try: + from urllib import urlopen +except ImportError: + from urllib.request import urlopen + +try: + from io import BytesIO +except ImportError: + try: + from cStringIO import StringIO as BytesIO + except ImportError: + from StringIO import StringIO as BytesIO + +try: + from hashlib import md5 +except ImportError: + try: + from md5 import md5 + except ImportError: + md5 = None +def hashpath(fn): + h = md5() + if PY3K: + h.update(fn.encode("UTF-8")) + else: + h.update(fn) + return h.hexdigest() + +# Check if PIL is available (tries importing both pypi version and corrected or manually installed versions). +# Necessary for JPEG and GIF support. +# TODO: Pillow support +try: + from PIL import Image +except ImportError: + try: + import Image + except ImportError: + Image = None + +try: + from HTMLParser import HTMLParser +except ImportError: + from html.parser import HTMLParser + +if PY3K: + basestring = str + unicode = str + ord = lambda x: x +else: + basestring = basestring + unicode = unicode + ord = ord + +# shortcut to bytes conversion (b prefix) +def b(s): + if isinstance(s, basestring): + return s.encode("latin1") + elif isinstance(s, int): + if PY3K: + return bytes([s]) # http://bugs.python.org/issue4588 + else: + return chr(s) + +def exception(): + "Return the current the exception instance currently being handled" + # this is needed to support Python 2.5 that lacks "as" syntax + return sys.exc_info()[1] + + diff --git a/web2py/gluon/contrib/fpdf/template.py b/web2py/gluon/contrib/fpdf/template.py new file mode 100644 index 0000000..a004538 --- /dev/null +++ b/web2py/gluon/contrib/fpdf/template.py @@ -0,0 +1,229 @@ +# -*- coding: iso-8859-1 -*- + +"PDF Template Helper for FPDF.py" + +from __future__ import with_statement + +__author__ = "Mariano Reingart " +__copyright__ = "Copyright (C) 2010 Mariano Reingart" +__license__ = "LGPL 3.0" + +import sys,os,csv +from .fpdf import FPDF +from .py3k import PY3K, basestring, unicode + +def rgb(col): + return (col // 65536), (col // 256 % 256), (col% 256) + +class Template: + def __init__(self, infile=None, elements=None, format='A4', orientation='portrait', + title='', author='', subject='', creator='', keywords=''): + if elements: + self.load_elements(elements) + self.handlers = {'T': self.text, 'L': self.line, 'I': self.image, + 'B': self.rect, 'BC': self.barcode, 'W': self.write, } + self.texts = {} + pdf = self.pdf = FPDF(format=format,orientation=orientation, unit="mm") + pdf.set_title(title) + pdf.set_author(author) + pdf.set_creator(creator) + pdf.set_subject(subject) + pdf.set_keywords(keywords) + + def load_elements(self, elements): + "Initialize the internal element structures" + self.pg_no = 0 + self.elements = elements + self.keys = [v['name'].lower() for v in self.elements] + + def parse_csv(self, infile, delimiter=",", decimal_sep="."): + "Parse template format csv file and create elements dict" + keys = ('name','type','x1','y1','x2','y2','font','size', + 'bold','italic','underline','foreground','background', + 'align','text','priority', 'multiline') + self.elements = [] + self.pg_no = 0 + if not PY3K: + f = open(infile, 'rb') + else: + f = open(infile) + with f: + for row in csv.reader(f, delimiter=delimiter): + kargs = {} + for i,v in enumerate(row): + if not v.startswith("'") and decimal_sep!=".": + v = v.replace(decimal_sep,".") + else: + v = v + if v=='': + v = None + else: + v = eval(v.strip()) + kargs[keys[i]] = v + self.elements.append(kargs) + self.keys = [v['name'].lower() for v in self.elements] + + def add_page(self): + self.pg_no += 1 + self.texts[self.pg_no] = {} + + def __setitem__(self, name, value): + if name.lower() in self.keys: + if not PY3K and isinstance(value, unicode): + value = value.encode("latin1","ignore") + elif value is None: + value = "" + else: + value = str(value) + self.texts[self.pg_no][name.lower()] = value + + # setitem shortcut (may be further extended) + set = __setitem__ + + def has_key(self, name): + return name.lower() in self.keys + + def __getitem__(self, name): + if name in self.keys: + key = name.lower() + if key in self.texts: + # text for this page: + return self.texts[self.pg_no][key] + else: + # find first element for default text: + elements = [element for element in self.elements + if element['name'].lower() == key] + if elements: + return elements[0]['text'] + + def split_multicell(self, text, element_name): + "Divide (\n) a string using a given element width" + pdf = self.pdf + element = [element for element in self.elements + if element['name'].lower() == element_name.lower()][0] + style = "" + if element['bold']: style += "B" + if element['italic']: style += "I" + if element['underline']: style += "U" + pdf.set_font(element['font'],style,element['size']) + align = {'L':'L','R':'R','I':'L','D':'R','C':'C','':''}.get(element['align']) # D/I in spanish + if isinstance(text, unicode) and not PY3K: + text = text.encode("latin1","ignore") + else: + text = str(text) + return pdf.multi_cell(w=element['x2']-element['x1'], + h=element['y2']-element['y1'], + txt=text,align=align,split_only=True) + + def render(self, outfile, dest="F"): + pdf = self.pdf + for pg in range(1, self.pg_no+1): + pdf.add_page() + pdf.set_font('Arial','B',16) + pdf.set_auto_page_break(False,margin=0) + + for element in sorted(self.elements,key=lambda x: x['priority']): + #print "dib",element['type'], element['name'], element['x1'], element['y1'], element['x2'], element['y2'] + element = element.copy() + element['text'] = self.texts[pg].get(element['name'].lower(), element['text']) + if 'rotate' in element: + pdf.rotate(element['rotate'], element['x1'], element['y1']) + self.handlers[element['type'].upper()](pdf, **element) + if 'rotate' in element: + pdf.rotate(0) + + if dest: + return pdf.output(outfile, dest) + + def text(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', font="arial", size=10, + bold=False, italic=False, underline=False, align="", + foreground=0, backgroud=65535, multiline=None, + *args, **kwargs): + if text: + if pdf.text_color!=rgb(foreground): + pdf.set_text_color(*rgb(foreground)) + if pdf.fill_color!=rgb(backgroud): + pdf.set_fill_color(*rgb(backgroud)) + + font = font.strip().lower() + if font == 'arial black': + font = 'arial' + style = "" + for tag in 'B', 'I', 'U': + if (text.startswith("<%s>" % tag) and text.endswith("" %tag)): + text = text[3:-4] + style += tag + if bold: style += "B" + if italic: style += "I" + if underline: style += "U" + align = {'L':'L','R':'R','I':'L','D':'R','C':'C','':''}.get(align) # D/I in spanish + pdf.set_font(font,style,size) + ##m_k = 72 / 2.54 + ##h = (size/m_k) + pdf.set_xy(x1,y1) + if multiline is None: + # multiline==None: write without wrapping/trimming (default) + pdf.cell(w=x2-x1,h=y2-y1,txt=text,border=0,ln=0,align=align) + elif multiline: + # multiline==True: automatic word - warp + pdf.multi_cell(w=x2-x1,h=y2-y1,txt=text,border=0,align=align) + else: + # multiline==False: trim to fit exactly the space defined + text = pdf.multi_cell(w=x2-x1, h=y2-y1, + txt=text, align=align, split_only=True)[0] + print("trimming: *%s*" % text) + pdf.cell(w=x2-x1,h=y2-y1,txt=text,border=0,ln=0,align=align) + + #pdf.Text(x=x1,y=y1,txt=text) + + def line(self, pdf, x1=0, y1=0, x2=0, y2=0, size=0, foreground=0, *args, **kwargs): + if pdf.draw_color!=rgb(foreground): + #print "SetDrawColor", hex(foreground) + pdf.set_draw_color(*rgb(foreground)) + #print "SetLineWidth", size + pdf.set_line_width(size) + pdf.line(x1, y1, x2, y2) + + def rect(self, pdf, x1=0, y1=0, x2=0, y2=0, size=0, foreground=0, backgroud=65535, *args, **kwargs): + if pdf.draw_color!=rgb(foreground): + pdf.set_draw_color(*rgb(foreground)) + if pdf.fill_color!=rgb(backgroud): + pdf.set_fill_color(*rgb(backgroud)) + pdf.set_line_width(size) + pdf.rect(x1, y1, x2-x1, y2-y1) + + def image(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', *args,**kwargs): + if text: + pdf.image(text,x1,y1,w=x2-x1,h=y2-y1,type='',link='') + + def barcode(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', font="arial", size=1, + foreground=0, *args, **kwargs): + if pdf.draw_color!=rgb(foreground): + pdf.set_draw_color(*rgb(foreground)) + font = font.lower().strip() + if font == 'interleaved 2of5 nt': + pdf.interleaved2of5(text,x1,y1,w=size,h=y2-y1) + + # Added by Derek Schwalenberg Schwalenberg1013@gmail.com to allow (url) links in templates (using write method) 2014-02-22 + def write(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', font="arial", size=1, + bold=False, italic=False, underline=False, align="", link='http://example.com', + foreground=0, *args, **kwargs): + if pdf.text_color!=rgb(foreground): + pdf.set_text_color(*rgb(foreground)) + font = font.strip().lower() + if font == 'arial black': + font = 'arial' + style = "" + for tag in 'B', 'I', 'U': + if (text.startswith("<%s>" % tag) and text.endswith("" %tag)): + text = text[3:-4] + style += tag + if bold: style += "B" + if italic: style += "I" + if underline: style += "U" + align = {'L':'L','R':'R','I':'L','D':'R','C':'C','':''}.get(align) # D/I in spanish + pdf.set_font(font,style,size) + ##m_k = 72 / 2.54 + ##h = (size/m_k) + pdf.set_xy(x1,y1) + pdf.write(5,text,link) diff --git a/web2py/gluon/contrib/fpdf/ttfonts.py b/web2py/gluon/contrib/fpdf/ttfonts.py new file mode 100644 index 0000000..46655c6 --- /dev/null +++ b/web2py/gluon/contrib/fpdf/ttfonts.py @@ -0,0 +1,1075 @@ +#****************************************************************************** +# TTFontFile class +# +# This class is based on The ReportLab Open Source PDF library +# written in Python - http://www.reportlab.com/software/opensource/ +# together with ideas from the OpenOffice source code and others. +# +# Version: 1.04 +# Date: 2011-09-18 +# Author: Ian Back +# License: LGPL +# Copyright (c) Ian Back, 2010 +# Ported to Python 2.7 by Mariano Reingart (reingart@gmail.com) on 2012 +# This header must be retained in any redistribution or +# modification of the file. +# +#****************************************************************************** + +from __future__ import with_statement + +from struct import pack, unpack, unpack_from +import re +import warnings +from .php import die, substr, str_repeat, str_pad, strlen, count +from .py3k import b, ord + + +# Define the value used in the "head" table of a created TTF file +# 0x74727565 "true" for Mac +# 0x00010000 for Windows +# Either seems to work for a font embedded in a PDF file +# when read by Adobe Reader on a Windows PC(!) +_TTF_MAC_HEADER = False + + +# TrueType Font Glyph operators +GF_WORDS = (1 << 0) +GF_SCALE = (1 << 3) +GF_MORE = (1 << 5) +GF_XYSCALE = (1 << 6) +GF_TWOBYTWO = (1 << 7) + + +def sub32(x, y): + xlo = x[1] + xhi = x[0] + ylo = y[1] + yhi = y[0] + if (ylo > xlo): + xlo += 1 << 16 + yhi += 1 + reslo = xlo-ylo + if (yhi > xhi): + xhi += 1 << 16 + reshi = xhi-yhi + reshi = reshi & 0xFFFF + return (reshi, reslo) + +def calcChecksum(data): + if (strlen(data) % 4): + data += str_repeat(b("\0"), (4-(len(data) % 4))) + hi=0x0000 + lo=0x0000 + for i in range(0, len(data), 4): + hi += (ord(data[i])<<8) + ord(data[i+1]) + lo += (ord(data[i+2])<<8) + ord(data[i+3]) + hi += lo >> 16 + lo = lo & 0xFFFF + hi = hi & 0xFFFF + return (hi, lo) + + +class TTFontFile: + + def __init__(self): + self.maxStrLenRead = 200000 # Maximum size of glyf table to read in as string (otherwise reads each glyph from file) + + def getMetrics(self, file): + self.filename = file + with open(file,'rb') as self.fh: + self._pos = 0 + self.charWidths = [] + self.glyphPos = {} + self.charToGlyph = {} + self.tables = {} + self.otables = {} + self.ascent = 0 + self.descent = 0 + self.TTCFonts = {} + self.version = version = self.read_ulong() + if (version==0x4F54544F): + die("Postscript outlines are not supported") + if (version==0x74746366): + die("ERROR - TrueType Fonts Collections not supported") + if (version not in (0x00010000,0x74727565)): + die("Not a TrueType font: version=" + str(version)) + self.readTableDirectory() + self.extractInfo() + + def readTableDirectory(self, ): + self.numTables = self.read_ushort() + self.searchRange = self.read_ushort() + self.entrySelector = self.read_ushort() + self.rangeShift = self.read_ushort() + self.tables = {} + for i in range(self.numTables): + record = {} + record['tag'] = self.read_tag() + record['checksum'] = (self.read_ushort(),self.read_ushort()) + record['offset'] = self.read_ulong() + record['length'] = self.read_ulong() + self.tables[record['tag']] = record + + def get_table_pos(self, tag): + offset = self.tables[tag]['offset'] + length = self.tables[tag]['length'] + return (offset, length) + + def seek(self, pos): + self._pos = pos + self.fh.seek(self._pos) + + def skip(self, delta): + self._pos = self._pos + delta + self.fh.seek(self._pos) + + def seek_table(self, tag, offset_in_table = 0): + tpos = self.get_table_pos(tag) + self._pos = tpos[0] + offset_in_table + self.fh.seek(self._pos) + return self._pos + + def read_tag(self): + self._pos += 4 + return self.fh.read(4).decode("latin1") + + def read_short(self): + self._pos += 2 + s = self.fh.read(2) + a = (ord(s[0])<<8) + ord(s[1]) + if (a & (1 << 15) ): + a = (a - (1 << 16)) + return a + + def unpack_short(self, s): + a = (ord(s[0])<<8) + ord(s[1]) + if (a & (1 << 15) ): + a = (a - (1 << 16)) + return a + + def read_ushort(self): + self._pos += 2 + s = self.fh.read(2) + return (ord(s[0])<<8) + ord(s[1]) + + def read_ulong(self): + self._pos += 4 + s = self.fh.read(4) + # if large uInt32 as an integer, PHP converts it to -ve + return (ord(s[0])*16777216) + (ord(s[1])<<16) + (ord(s[2])<<8) + ord(s[3]) # 16777216 = 1<<24 + + def get_ushort(self, pos): + self.fh.seek(pos) + s = self.fh.read(2) + return (ord(s[0])<<8) + ord(s[1]) + + def get_ulong(self, pos): + self.fh.seek(pos) + s = self.fh.read(4) + # iF large uInt32 as an integer, PHP converts it to -ve + return (ord(s[0])*16777216) + (ord(s[1])<<16) + (ord(s[2])<<8) + ord(s[3]) # 16777216 = 1<<24 + + def pack_short(self, val): + if (val<0): + val = abs(val) + val = ~val + val += 1 + return pack(">H",val) + + def splice(self, stream, offset, value): + return substr(stream,0,offset) + value + substr(stream,offset+strlen(value)) + + def _set_ushort(self, stream, offset, value): + up = pack(">H", value) + return self.splice(stream, offset, up) + + def _set_short(self, stream, offset, val): + if (val<0): + val = abs(val) + val = ~val + val += 1 + up = pack(">H",val) + return self.splice(stream, offset, up) + + def get_chunk(self, pos, length): + self.fh.seek(pos) + if (length <1): return '' + return (self.fh.read(length)) + + def get_table(self, tag): + (pos, length) = self.get_table_pos(tag) + if (length == 0): + die('Truetype font (' + self.filename + '): error reading table: ' + tag) + self.fh.seek(pos) + return (self.fh.read(length)) + + def add(self, tag, data): + if (tag == 'head') : + data = self.splice(data, 8, b("\0\0\0\0")) + self.otables[tag] = data + +############################################/ +############################################/ + +############################################/ + + def extractInfo(self): + #################/ + # name - Naming table + #################/ + self.sFamilyClass = 0 + self.sFamilySubClass = 0 + + name_offset = self.seek_table("name") + format = self.read_ushort() + if (format != 0): + die("Unknown name table format " + format) + numRecords = self.read_ushort() + string_data_offset = name_offset + self.read_ushort() + names = {1:'',2:'',3:'',4:'',6:''} + K = list(names.keys()) + nameCount = len(names) + for i in range(numRecords): + platformId = self.read_ushort() + encodingId = self.read_ushort() + languageId = self.read_ushort() + nameId = self.read_ushort() + length = self.read_ushort() + offset = self.read_ushort() + if (nameId not in K): continue + N = '' + if (platformId == 3 and encodingId == 1 and languageId == 0x409): # Microsoft, Unicode, US English, PS Name + opos = self._pos + self.seek(string_data_offset + offset) + if (length % 2 != 0): + die("PostScript name is UTF-16BE string of odd length") + length //= 2 + N = '' + while (length > 0): + char = self.read_ushort() + N += (chr(char)) + length -= 1 + self._pos = opos + self.seek(opos) + + elif (platformId == 1 and encodingId == 0 and languageId == 0): # Macintosh, Roman, English, PS Name + opos = self._pos + N = self.get_chunk(string_data_offset + offset, length).decode("latin1") + self._pos = opos + self.seek(opos) + + if (N and names[nameId]==''): + names[nameId] = N + nameCount -= 1 + if (nameCount==0): break + + + if (names[6]): + psName = names[6] + elif (names[4]): + psName = re.sub(' ','-',names[4]) + elif (names[1]): + psName = re.sub(' ','-',names[1]) + else: + psName = '' + if (not psName): + die("Could not find PostScript font name") + self.name = psName + if (names[1]): + self.familyName = names[1] + else: + self.familyName = psName + if (names[2]): + self.styleName = names[2] + else: + self.styleName = 'Regular' + if (names[4]): + self.fullName = names[4] + else: + self.fullName = psName + if (names[3]): + self.uniqueFontID = names[3] + else: + self.uniqueFontID = psName + if (names[6]): + self.fullName = names[6] + + #################/ + # head - Font header table + #################/ + self.seek_table("head") + self.skip(18) + self.unitsPerEm = unitsPerEm = self.read_ushort() + scale = 1000 / float(unitsPerEm) + self.skip(16) + xMin = self.read_short() + yMin = self.read_short() + xMax = self.read_short() + yMax = self.read_short() + self.bbox = [(xMin*scale), (yMin*scale), (xMax*scale), (yMax*scale)] + self.skip(3*2) + indexToLocFormat = self.read_ushort() + glyphDataFormat = self.read_ushort() + if (glyphDataFormat != 0): + die('Unknown glyph data format ' + glyphDataFormat) + + #################/ + # hhea metrics table + #################/ + # ttf2t1 seems to use this value rather than the one in OS/2 - so put in for compatibility + if ("hhea" in self.tables): + self.seek_table("hhea") + self.skip(4) + hheaAscender = self.read_short() + hheaDescender = self.read_short() + self.ascent = (hheaAscender *scale) + self.descent = (hheaDescender *scale) + + + #################/ + # OS/2 - OS/2 and Windows metrics table + #################/ + if ("OS/2" in self.tables): + self.seek_table("OS/2") + version = self.read_ushort() + self.skip(2) + usWeightClass = self.read_ushort() + self.skip(2) + fsType = self.read_ushort() + if (fsType == 0x0002 or (fsType & 0x0300) != 0): + die('ERROR - Font file ' + self.filename + ' cannot be embedded due to copyright restrictions.') + self.restrictedUse = True + + self.skip(20) + sF = self.read_short() + self.sFamilyClass = (sF >> 8) + self.sFamilySubClass = (sF & 0xFF) + self._pos += 10 #PANOSE = 10 byte length + panose = self.fh.read(10) + self.skip(26) + sTypoAscender = self.read_short() + sTypoDescender = self.read_short() + if (not self.ascent): + self.ascent = (sTypoAscender*scale) + if (not self.descent): + self.descent = (sTypoDescender*scale) + if (version > 1): + self.skip(16) + sCapHeight = self.read_short() + self.capHeight = (sCapHeight*scale) + else: + self.capHeight = self.ascent + + else: + usWeightClass = 500 + if (not self.ascent): self.ascent = (yMax*scale) + if (not self.descent): self.descent = (yMin*scale) + self.capHeight = self.ascent + + self.stemV = 50 + int(pow((usWeightClass / 65.0),2)) + + #################/ + # post - PostScript table + #################/ + self.seek_table("post") + self.skip(4) + self.italicAngle = self.read_short() + self.read_ushort() / 65536.0 + self.underlinePosition = self.read_short() * scale + self.underlineThickness = self.read_short() * scale + isFixedPitch = self.read_ulong() + + self.flags = 4 + + if (self.italicAngle!= 0): + self.flags = self.flags | 64 + if (usWeightClass >= 600): + self.flags = self.flags | 262144 + if (isFixedPitch): + self.flags = self.flags | 1 + + #################/ + # hhea - Horizontal header table + #################/ + self.seek_table("hhea") + self.skip(32) + metricDataFormat = self.read_ushort() + if (metricDataFormat != 0): + die('Unknown horizontal metric data format '.metricDataFormat) + numberOfHMetrics = self.read_ushort() + if (numberOfHMetrics == 0): + die('Number of horizontal metrics is 0') + + #################/ + # maxp - Maximum profile table + #################/ + self.seek_table("maxp") + self.skip(4) + numGlyphs = self.read_ushort() + + #################/ + # cmap - Character to glyph index mapping table + #################/ + cmap_offset = self.seek_table("cmap") + self.skip(2) + cmapTableCount = self.read_ushort() + unicode_cmap_offset = 0 + unicode_cmap_offset12 = 0 + + for i in range(cmapTableCount): + platformID = self.read_ushort() + encodingID = self.read_ushort() + offset = self.read_ulong() + save_pos = self._pos + if platformID == 3 and encodingID == 10: # Microsoft, UCS-4 + format = self.get_ushort(cmap_offset + offset) + if (format == 12): + if not unicode_cmap_offset12: + unicode_cmap_offset12 = cmap_offset + offset + break + if ((platformID == 3 and encodingID == 1) or platformID == 0): # Microsoft, Unicode + format = self.get_ushort(cmap_offset + offset) + if (format == 4): + if (not unicode_cmap_offset): + unicode_cmap_offset = cmap_offset + offset + break + + self.seek(save_pos) + + if not unicode_cmap_offset and not unicode_cmap_offset12: + die('Font (' + self.filename + ') does not have cmap for Unicode (platform 3, encoding 1, format 4, or platform 3, encoding 10, format 12, or platform 0, any encoding, format 4)') + + glyphToChar = {} + charToGlyph = {} + if unicode_cmap_offset12: + self.getCMAP12(unicode_cmap_offset12, glyphToChar, charToGlyph) + else: + self.getCMAP4(unicode_cmap_offset, glyphToChar, charToGlyph) + + #################/ + # hmtx - Horizontal metrics table + #################/ + self.getHMTX(numberOfHMetrics, numGlyphs, glyphToChar, scale) + + +############################################/ +############################################/ + + def makeSubset(self, file, subset): + self.filename = file + with open(file ,'rb') as self.fh: + self._pos = 0 + self.charWidths = [] + self.glyphPos = {} + self.charToGlyph = {} + self.tables = {} + self.otables = {} + self.ascent = 0 + self.descent = 0 + self.skip(4) + self.maxUni = 0 + self.readTableDirectory() + + #################/ + # head - Font header table + #################/ + self.seek_table("head") + self.skip(50) + indexToLocFormat = self.read_ushort() + glyphDataFormat = self.read_ushort() + + #################/ + # hhea - Horizontal header table + #################/ + self.seek_table("hhea") + self.skip(32) + metricDataFormat = self.read_ushort() + orignHmetrics = numberOfHMetrics = self.read_ushort() + + #################/ + # maxp - Maximum profile table + #################/ + self.seek_table("maxp") + self.skip(4) + numGlyphs = self.read_ushort() + + #################/ + # cmap - Character to glyph index mapping table + #################/ + cmap_offset = self.seek_table("cmap") + self.skip(2) + cmapTableCount = self.read_ushort() + unicode_cmap_offset = 0 + unicode_cmap_offset12 = 0 + for i in range(cmapTableCount): + platformID = self.read_ushort() + encodingID = self.read_ushort() + offset = self.read_ulong() + save_pos = self._pos + if platformID == 3 and encodingID == 10: # Microsoft, UCS-4 + format = self.get_ushort(cmap_offset + offset) + if (format == 12): + if not unicode_cmap_offset12: + unicode_cmap_offset12 = cmap_offset + offset + break + if ((platformID == 3 and encodingID == 1) or platformID == 0): # Microsoft, Unicode + format = self.get_ushort(cmap_offset + offset) + if (format == 4): + unicode_cmap_offset = cmap_offset + offset + break + + self.seek(save_pos ) + + if not unicode_cmap_offset and not unicode_cmap_offset12: + die('Font (' + self.filename + ') does not have cmap for Unicode (platform 3, encoding 1, format 4, or platform 3, encoding 10, format 12, or platform 0, any encoding, format 4)') + + glyphToChar = {} + charToGlyph = {} + if unicode_cmap_offset12: + self.getCMAP12(unicode_cmap_offset12, glyphToChar, charToGlyph) + else: + self.getCMAP4(unicode_cmap_offset, glyphToChar, charToGlyph) + + self.charToGlyph = charToGlyph + + #################/ + # hmtx - Horizontal metrics table + #################/ + scale = 1 # not used + self.getHMTX(numberOfHMetrics, numGlyphs, glyphToChar, scale) + + #################/ + # loca - Index to location + #################/ + self.getLOCA(indexToLocFormat, numGlyphs) + + subsetglyphs = [(0, 0)] # special "sorted dict"! + subsetCharToGlyph = {} + for code in subset: + if (code in self.charToGlyph): + if (self.charToGlyph[code], code) not in subsetglyphs: + subsetglyphs.append((self.charToGlyph[code], code)) # Old Glyph ID => Unicode + subsetCharToGlyph[code] = self.charToGlyph[code] # Unicode to old GlyphID + self.maxUni = max(self.maxUni, code) + (start,dummy) = self.get_table_pos('glyf') + + subsetglyphs.sort() + glyphSet = {} + n = 0 + fsLastCharIndex = 0 # maximum Unicode index (character code) in this font, according to the cmap subtable for platform ID 3 and platform- specific encoding ID 0 or 1. + for originalGlyphIdx, uni in subsetglyphs: + fsLastCharIndex = max(fsLastCharIndex , uni) + glyphSet[originalGlyphIdx] = n # old glyphID to new glyphID + n += 1 + + codeToGlyph = {} + for uni, originalGlyphIdx in sorted(subsetCharToGlyph.items()): + codeToGlyph[uni] = glyphSet[originalGlyphIdx] + + self.codeToGlyph = codeToGlyph + + for originalGlyphIdx, uni in subsetglyphs: + nonlocals = {'start': start, 'glyphSet': glyphSet, + 'subsetglyphs': subsetglyphs} + self.getGlyphs(originalGlyphIdx, nonlocals) + + numGlyphs = numberOfHMetrics = len(subsetglyphs) + + #tables copied from the original + tags = ['name'] + for tag in tags: + self.add(tag, self.get_table(tag)) + tags = ['cvt ', 'fpgm', 'prep', 'gasp'] + for tag in tags: + if (tag in self.tables): + self.add(tag, self.get_table(tag)) + + # post - PostScript + opost = self.get_table('post') + post = b("\x00\x03\x00\x00") + substr(opost,4,12) + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + self.add('post', post) + + # Sort CID2GID map into segments of contiguous codes + if 0 in codeToGlyph: + del codeToGlyph[0] + #unset(codeToGlyph[65535]) + rangeid = 0 + range_ = {} + prevcid = -2 + prevglidx = -1 + # for each character + for cid, glidx in sorted(codeToGlyph.items()): + if (cid == (prevcid + 1) and glidx == (prevglidx + 1)): + range_[rangeid].append(glidx) + else: + # new range + rangeid = cid + range_[rangeid] = [] + range_[rangeid].append(glidx) + prevcid = cid + prevglidx = glidx + + # cmap - Character to glyph mapping - Format 4 (MS / ) + segCount = len(range_) + 1 # + 1 Last segment has missing character 0xFFFF + searchRange = 1 + entrySelector = 0 + while (searchRange * 2 <= segCount ): + searchRange = searchRange * 2 + entrySelector = entrySelector + 1 + + searchRange = searchRange * 2 + rangeShift = segCount * 2 - searchRange + length = 16 + (8*segCount ) + (numGlyphs+1) + cmap = [0, 1, # Index : version, number of encoding subtables + 3, 1, # Encoding Subtable : platform (MS=3), encoding (Unicode) + 0, 12, # Encoding Subtable : offset (hi,lo) + 4, length, 0, # Format 4 Mapping subtable: format, length, language + segCount*2, + searchRange, + entrySelector, + rangeShift] + + range_ = sorted(range_.items()) + + # endCode(s) + for start, subrange in range_: + endCode = start + (len(subrange)-1) + cmap.append(endCode) # endCode(s) + + cmap.append(0xFFFF) # endCode of last Segment + cmap.append(0) # reservedPad + + # startCode(s) + for start, subrange in range_: + cmap.append(start) # startCode(s) + + cmap.append(0xFFFF) # startCode of last Segment + # idDelta(s) + for start, subrange in range_: + idDelta = -(start-subrange[0]) + n += count(subrange) + cmap.append(idDelta) # idDelta(s) + + cmap.append(1) # idDelta of last Segment + # idRangeOffset(s) + for subrange in range_: + cmap.append(0) # idRangeOffset[segCount] Offset in bytes to glyph indexArray, or 0 + + cmap.append(0) # idRangeOffset of last Segment + for subrange, glidx in range_: + cmap.extend(glidx) + + cmap.append(0) # Mapping for last character + cmapstr = b('') + for cm in cmap: + if cm >= 0: + cmapstr += pack(">H", cm) + else: + try: + cmapstr += pack(">h", cm) + except: + warnings.warn("cmap value too big/small: %s" % cm) + cmapstr += pack(">H", -cm) + self.add('cmap', cmapstr) + + # glyf - Glyph data + (glyfOffset,glyfLength) = self.get_table_pos('glyf') + if (glyfLength < self.maxStrLenRead): + glyphData = self.get_table('glyf') + + offsets = [] + glyf = b('') + pos = 0 + + hmtxstr = b('') + xMinT = 0 + yMinT = 0 + xMaxT = 0 + yMaxT = 0 + advanceWidthMax = 0 + minLeftSideBearing = 0 + minRightSideBearing = 0 + xMaxExtent = 0 + maxPoints = 0 # points in non-compound glyph + maxContours = 0 # contours in non-compound glyph + maxComponentPoints = 0 # points in compound glyph + maxComponentContours = 0 # contours in compound glyph + maxComponentElements = 0 # number of glyphs referenced at top level + maxComponentDepth = 0 # levels of recursion, set to 0 if font has only simple glyphs + self.glyphdata = {} + + for originalGlyphIdx, uni in subsetglyphs: + # hmtx - Horizontal Metrics + hm = self.getHMetric(orignHmetrics, originalGlyphIdx) + hmtxstr += hm + + offsets.append(pos) + try: + glyphPos = self.glyphPos[originalGlyphIdx] + glyphLen = self.glyphPos[originalGlyphIdx + 1] - glyphPos + except IndexError: + warnings.warn("missing glyph %s" % (originalGlyphIdx)) + glyphLen = 0 + + if (glyfLength < self.maxStrLenRead): + data = substr(glyphData,glyphPos,glyphLen) + else: + if (glyphLen > 0): + data = self.get_chunk(glyfOffset+glyphPos,glyphLen) + else: + data = b('') + + if (glyphLen > 0): + up = unpack(">H", substr(data,0,2))[0] + if (glyphLen > 2 and (up & (1 << 15)) ): # If number of contours <= -1 i.e. composite glyph + pos_in_glyph = 10 + flags = GF_MORE + nComponentElements = 0 + while (flags & GF_MORE): + nComponentElements += 1 # number of glyphs referenced at top level + up = unpack(">H", substr(data,pos_in_glyph,2)) + flags = up[0] + up = unpack(">H", substr(data,pos_in_glyph+2,2)) + glyphIdx = up[0] + self.glyphdata.setdefault(originalGlyphIdx, {}).setdefault('compGlyphs', []).append(glyphIdx) + try: + data = self._set_ushort(data, pos_in_glyph + 2, glyphSet[glyphIdx]) + except KeyError: + data = 0 + warnings.warn("missing glyph data %s" % glyphIdx) + pos_in_glyph += 4 + if (flags & GF_WORDS): + pos_in_glyph += 4 + else: + pos_in_glyph += 2 + if (flags & GF_SCALE): + pos_in_glyph += 2 + elif (flags & GF_XYSCALE): + pos_in_glyph += 4 + elif (flags & GF_TWOBYTWO): + pos_in_glyph += 8 + + maxComponentElements = max(maxComponentElements, nComponentElements) + + glyf += data + pos += glyphLen + if (pos % 4 != 0): + padding = 4 - (pos % 4) + glyf += str_repeat(b("\0"),padding) + pos += padding + + offsets.append(pos) + self.add('glyf', glyf) + + # hmtx - Horizontal Metrics + self.add('hmtx', hmtxstr) + + # loca - Index to location + locastr = b('') + if (((pos + 1) >> 1) > 0xFFFF): + indexToLocFormat = 1 # long format + for offset in offsets: + locastr += pack(">L",offset) + else: + indexToLocFormat = 0 # short format + for offset in offsets: + locastr += pack(">H",offset//2) + + self.add('loca', locastr) + + # head - Font header + head = self.get_table('head') + head = self._set_ushort(head, 50, indexToLocFormat) + self.add('head', head) + + # hhea - Horizontal Header + hhea = self.get_table('hhea') + hhea = self._set_ushort(hhea, 34, numberOfHMetrics) + self.add('hhea', hhea) + + # maxp - Maximum Profile + maxp = self.get_table('maxp') + maxp = self._set_ushort(maxp, 4, numGlyphs) + self.add('maxp', maxp) + + # OS/2 - OS/2 + os2 = self.get_table('OS/2') + self.add('OS/2', os2 ) + + # Put the TTF file together + stm = self.endTTFile('') + return stm + + + ######################################### + # Recursively get composite glyph data + def getGlyphData(self, originalGlyphIdx, nonlocals): + # &maxdepth, &depth, &points, &contours + nonlocals['depth'] += 1 + nonlocals['maxdepth'] = max(nonlocals['maxdepth'], nonlocals['depth']) + if (len(self.glyphdata[originalGlyphIdx]['compGlyphs'])): + for glyphIdx in self.glyphdata[originalGlyphIdx]['compGlyphs']: + self.getGlyphData(glyphIdx, nonlocals) + + elif ((self.glyphdata[originalGlyphIdx]['nContours'] > 0) and nonlocals['depth'] > 0): # simple + contours += self.glyphdata[originalGlyphIdx]['nContours'] + points += self.glyphdata[originalGlyphIdx]['nPoints'] + + nonlocals['depth'] -= 1 + + + ######################################### + # Recursively get composite glyphs + def getGlyphs(self, originalGlyphIdx, nonlocals): + # &start, &glyphSet, &subsetglyphs) + + try: + glyphPos = self.glyphPos[originalGlyphIdx] + glyphLen = self.glyphPos[originalGlyphIdx + 1] - glyphPos + except IndexError: + warnings.warn("missing glyph %s" % (originalGlyphIdx)) + return + + if (not glyphLen): + return + + self.seek(nonlocals['start'] + glyphPos) + numberOfContours = self.read_short() + if (numberOfContours < 0): + self.skip(8) + flags = GF_MORE + while (flags & GF_MORE): + flags = self.read_ushort() + glyphIdx = self.read_ushort() + if (glyphIdx not in nonlocals['glyphSet']): + nonlocals['glyphSet'][glyphIdx] = len(nonlocals['subsetglyphs']) # old glyphID to new glyphID + nonlocals['subsetglyphs'].append((glyphIdx, 1)) + + savepos = self.fh.tell() + self.getGlyphs(glyphIdx, nonlocals) + self.seek(savepos) + if (flags & GF_WORDS): + self.skip(4) + else: + self.skip(2) + if (flags & GF_SCALE): + self.skip(2) + elif (flags & GF_XYSCALE): + self.skip(4) + elif (flags & GF_TWOBYTWO): + self.skip(8) + + ######################################### + + def getHMTX(self, numberOfHMetrics, numGlyphs, glyphToChar, scale): + start = self.seek_table("hmtx") + aw = 0 + self.charWidths = [] + def resize_cw(size, default): + size = (((size + 1) // 1024) + 1) * 1024 + delta = size - len(self.charWidths) + if delta > 0: + self.charWidths += [default] * delta + nCharWidths = 0 + if ((numberOfHMetrics*4) < self.maxStrLenRead): + data = self.get_chunk(start,(numberOfHMetrics*4)) + arr = unpack(">%dH" % (len(data)//2), data) + else: + self.seek(start) + for glyph in range(numberOfHMetrics): + if ((numberOfHMetrics*4) < self.maxStrLenRead): + aw = arr[(glyph*2)] # PHP starts arrays from index 0!? +1 + else: + aw = self.read_ushort() + lsb = self.read_ushort() + + if (glyph in glyphToChar or glyph == 0): + if (aw >= (1 << 15) ): + aw = 0 # 1.03 Some (arabic) fonts have -ve values for width + # although should be unsigned value - comes out as e.g. 65108 (intended -50) + if (glyph == 0): + self.defaultWidth = scale*aw + continue + + for char in glyphToChar[glyph]: + if (char != 0 and char != 65535): + w = int(round(scale*aw+0.001)) # ROUND_HALF_UP in PY3K (like php) + if (w == 0): w = 65535 + if (char < 196608): + if char >= len(self.charWidths): + resize_cw(char, self.defaultWidth) + self.charWidths[char] = w + nCharWidths += 1 + + + data = self.get_chunk((start+numberOfHMetrics*4),(numGlyphs*2)) + arr = unpack(">%dH" % (len(data)//2), data) + diff = numGlyphs-numberOfHMetrics + for pos in range(diff): + glyph = pos + numberOfHMetrics + if (glyph in glyphToChar): + for char in glyphToChar[glyph]: + if (char != 0 and char != 65535): + w = int(round(scale*aw+0.001)) # ROUND_HALF_UP in PY3K (like php) + if (w == 0): w = 65535 + if (char < 196608): + if char >= len(self.charWidths): + resize_cw(char, self.defaultWidth) + self.charWidths[char] = w + nCharWidths += 1 + + + # NB 65535 is a set width of 0 + # First bytes define number of chars in font + self.charWidths[0] = nCharWidths + + + def getHMetric(self, numberOfHMetrics, gid): + start = self.seek_table("hmtx") + if (gid < numberOfHMetrics): + self.seek(start+(gid*4)) + hm = self.fh.read(4) + else: + self.seek(start+((numberOfHMetrics-1)*4)) + hm = self.fh.read(2) + self.seek(start+(numberOfHMetrics*2)+(gid*2)) + hm += self.fh.read(2) + return hm + + + def getLOCA(self, indexToLocFormat, numGlyphs): + start = self.seek_table('loca') + self.glyphPos = [] + if (indexToLocFormat == 0): + data = self.get_chunk(start,(numGlyphs*2)+2) + arr = unpack(">%dH" % (len(data)//2), data) + for n in range(numGlyphs): + self.glyphPos.append((arr[n] * 2)) # n+1 !? + elif (indexToLocFormat == 1): + data = self.get_chunk(start,(numGlyphs*4)+4) + arr = unpack(">%dL" % (len(data)//4), data) + for n in range(numGlyphs): + self.glyphPos.append((arr[n])) # n+1 !? + else: + die('Unknown location table format ' + indexToLocFormat) + + # CMAP Format 4 + def getCMAP4(self, unicode_cmap_offset, glyphToChar, charToGlyph): + self.maxUniChar = 0 + self.seek(unicode_cmap_offset + 2) + length = self.read_ushort() + limit = unicode_cmap_offset + length + self.skip(2) + + segCount = self.read_ushort() // 2 + self.skip(6) + endCount = [] + for i in range(segCount): + endCount.append(self.read_ushort()) + self.skip(2) + startCount = [] + for i in range(segCount): + startCount.append(self.read_ushort()) + idDelta = [] + for i in range(segCount): + idDelta.append(self.read_short()) # ???? was unsigned short + idRangeOffset_start = self._pos + idRangeOffset = [] + for i in range(segCount): + idRangeOffset.append(self.read_ushort()) + + for n in range(segCount): + endpoint = (endCount[n] + 1) + for unichar in range(startCount[n], endpoint, 1): + if (idRangeOffset[n] == 0): + glyph = (unichar + idDelta[n]) & 0xFFFF + else: + offset = (unichar - startCount[n]) * 2 + idRangeOffset[n] + offset = idRangeOffset_start + 2 * n + offset + if (offset >= limit): + glyph = 0 + else: + glyph = self.get_ushort(offset) + if (glyph != 0): + glyph = (glyph + idDelta[n]) & 0xFFFF + + charToGlyph[unichar] = glyph + if (unichar < 196608): + self.maxUniChar = max(unichar,self.maxUniChar) + glyphToChar.setdefault(glyph, []).append(unichar) + + # CMAP Format 12 + def getCMAP12(self, unicode_cmap_offset, glyphToChar, charToGlyph): + self.maxUniChar = 0 + # table (skip format version, should be 12) + self.seek(unicode_cmap_offset + 2) + # reserved + self.skip(2) + # table length + length = self.read_ulong() + # language (should be 0) + self.skip(4) + # groups count + grpCount = self.read_ulong() + + if 2 + 2 + 4 + 4 + 4 + grpCount * 3 * 4 > length: + die("TTF format 12 cmap table too small") + for n in range(grpCount): + startCharCode = self.read_ulong() + endCharCode = self.read_ulong() + glyph = self.read_ulong() + for unichar in range(startCharCode, endCharCode + 1): + charToGlyph[unichar] = glyph + if (unichar < 196608): + self.maxUniChar = max(unichar, self.maxUniChar) + glyphToChar.setdefault(glyph, []).append(unichar) + glyph += 1 + + + + # Put the TTF file together + def endTTFile(self, stm): + stm = b('') + numTables = count(self.otables) + searchRange = 1 + entrySelector = 0 + while (searchRange * 2 <= numTables): + searchRange = searchRange * 2 + entrySelector = entrySelector + 1 + + searchRange = searchRange * 16 + rangeShift = numTables * 16 - searchRange + + # Header + if (_TTF_MAC_HEADER): + stm += (pack(">LHHHH", 0x74727565, numTables, searchRange, entrySelector, rangeShift)) # Mac + else: + stm += (pack(">LHHHH", 0x00010000 , numTables, searchRange, entrySelector, rangeShift)) # Windows + + + # Table directory + tables = self.otables + + offset = 12 + numTables * 16 + sorted_tables = sorted(tables.items()) + for tag, data in sorted_tables: + if (tag == 'head'): + head_start = offset + stm += tag.encode("latin1") + checksum = calcChecksum(data) + stm += pack(">HH", checksum[0],checksum[1]) + stm += pack(">LL", offset, strlen(data)) + paddedLength = (strlen(data)+3)&~3 + offset = offset + paddedLength + + # Table data + for tag, data in sorted_tables: + data += b("\0\0\0") + stm += substr(data,0,(strlen(data)&~3)) + + checksum = calcChecksum(stm) + checksum = sub32((0xB1B0,0xAFBA), checksum) + chk = pack(">HH", checksum[0],checksum[1]) + stm = self.splice(stm,(head_start + 8),chk) + return stm + diff --git a/web2py/gluon/contrib/gae_memcache.py b/web2py/gluon/contrib/gae_memcache.py new file mode 100644 index 0000000..d20c9f9 --- /dev/null +++ b/web2py/gluon/contrib/gae_memcache.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Developed by Robin Bhattacharyya (memecache for GAE) +Released under the web2py license (LGPL) + +from gluon.contrib.gae_memcache import MemcacheClient +cache.ram=cache.disk=MemcacheClient(request) +""" + +import time +from google.appengine.api.memcache import Client + + +class MemcacheClient(object): + + client = Client() + + def __init__(self, request, default_time_expire = 300): + self.request = request + self.default_time_expire = default_time_expire + + def initialize(self): + pass + + def __call__( + self, + key, + f, + time_expire=None, + ): + if time_expire is None: + time_expire = self.default_time_expire + + key = '%s/%s' % (self.request.application, key) + value = None + obj = self.client.get(key) if time_expire != 0 else None + if obj: + value = obj[1] + elif f is not None: + value = f() + self.client.set(key, (time.time(), value), time=time_expire) + return value + + def increment(self, key, value=1): + key = '%s/%s' % (self.request.application, key) + obj = self.client.get(key) + if obj: + value = obj[1] + value + self.client.set(key, (time.time(), value)) + return value + + def incr(self, key, value=1): + return self.increment(key, value) + + def clear(self, key=None): + if key: + key = '%s/%s' % (self.request.application, key) + self.client.delete(key) + else: + self.client.flush_all() + + def delete(self, *a, **b): + return self.client.delete(*a, **b) + + def get(self, *a, **b): + return self.client.get(*a, **b) + + def set(self, *a, **b): + return self.client.set(*a, **b) + + def flush_all(self, *a, **b): + return self.client.delete(*a, **b) diff --git a/web2py/gluon/contrib/gae_retry.py b/web2py/gluon/contrib/gae_retry.py new file mode 100644 index 0000000..692279d --- /dev/null +++ b/web2py/gluon/contrib/gae_retry.py @@ -0,0 +1,89 @@ +def autoretry_datastore_timeouts(attempts=5.0, interval=0.1, exponent=2.0): + """ + Copyright (C) 2009 twitter.com/rcb + + 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. + + ====================================================================== + + This function wraps the AppEngine Datastore API to autoretry + datastore timeouts at the lowest accessible level. + + The benefits of this approach are: + + 1. Small Footprint: Does not monkey with Model internals + which may break in future releases. + 2. Max Performance: Retrying at this lowest level means + serialization and key formatting is not + needlessly repeated on each retry. + At initialization time, execute this: + + >>> autoretry_datastore_timeouts() + + Should only be called once, subsequent calls have no effect. + + >>> autoretry_datastore_timeouts() # no effect + + Default (5) attempts: .1, .2, .4, .8, 1.6 seconds + + Parameters can each be specified as floats. + + :param attempts: maximum number of times to retry. + :param interval: base seconds to sleep between retries. + :param exponent: rate of exponential back-off. + """ + + import time + import logging + from google.appengine.api import apiproxy_stub_map + from google.appengine.runtime import apiproxy_errors + from google.appengine.datastore import datastore_pb + + attempts = float(attempts) + interval = float(interval) + exponent = float(exponent) + wrapped = apiproxy_stub_map.MakeSyncCall + errors = {datastore_pb.Error.TIMEOUT: 'Timeout', + datastore_pb.Error.CONCURRENT_TRANSACTION: 'TransactionFailedError'} + + def wrapper(*args, **kwargs): + count = 0.0 + while True: + try: + return wrapped(*args, **kwargs) + except apiproxy_errors.ApplicationError as err: + errno = err.application_error + if errno not in errors: + raise + sleep = (exponent ** count) * interval + count += 1.0 + if count > attempts: + raise + msg = "Datastore %s: retry #%d in %s seconds.\n%s" + vals = '' + if count == 1.0: + vals = '\n'.join([str(a) for a in args]) + logging.warning(msg % (errors[errno], count, sleep, vals)) + time.sleep(sleep) + + setattr(wrapper, '_autoretry_datastore_timeouts', False) + if getattr(wrapped, '_autoretry_datastore_timeouts', True): + apiproxy_stub_map.MakeSyncCall = wrapper diff --git a/web2py/gluon/contrib/gateways/__init__.py b/web2py/gluon/contrib/gateways/__init__.py new file mode 100644 index 0000000..139597f --- /dev/null +++ b/web2py/gluon/contrib/gateways/__init__.py @@ -0,0 +1,2 @@ + + diff --git a/web2py/gluon/contrib/gateways/fcgi.py b/web2py/gluon/contrib/gateways/fcgi.py new file mode 100644 index 0000000..df61c79 --- /dev/null +++ b/web2py/gluon/contrib/gateways/fcgi.py @@ -0,0 +1,1331 @@ +# Copyright (c) 2002, 2003, 2005, 2006 Allan Saddi +# All rights reserved. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +# +# $Id$ + +""" +fcgi - a FastCGI/WSGI gateway. + +For more information about FastCGI, see . + +For more information about the Web Server Gateway Interface, see +. + +Example usage: + + #!/usr/bin/env python + from myapplication import app # Assume app is your WSGI application object + from fcgi import WSGIServer + WSGIServer(app).run() + +See the documentation for WSGIServer/Server for more information. + +On most platforms, fcgi will fallback to regular CGI behavior if run in a +non-FastCGI context. If you want to force CGI behavior, set the environment +variable FCGI_FORCE_CGI to "Y" or "y". +""" + +__author__ = 'Allan Saddi ' +__version__ = '$Revision$' + +import sys +import os +import signal +import struct +import cStringIO as StringIO +import select +import socket +import errno +import traceback + +try: + import thread + import threading + thread_available = True +except ImportError: + import dummy_thread as thread + import dummy_threading as threading + thread_available = False + +# Apparently 2.3 doesn't define SHUT_WR? Assume it is 1 in this case. +if not hasattr(socket, 'SHUT_WR'): + socket.SHUT_WR = 1 + +__all__ = ['WSGIServer'] + +# Constants from the spec. +FCGI_LISTENSOCK_FILENO = 0 + +FCGI_HEADER_LEN = 8 + +FCGI_VERSION_1 = 1 + +FCGI_BEGIN_REQUEST = 1 +FCGI_ABORT_REQUEST = 2 +FCGI_END_REQUEST = 3 +FCGI_PARAMS = 4 +FCGI_STDIN = 5 +FCGI_STDOUT = 6 +FCGI_STDERR = 7 +FCGI_DATA = 8 +FCGI_GET_VALUES = 9 +FCGI_GET_VALUES_RESULT = 10 +FCGI_UNKNOWN_TYPE = 11 +FCGI_MAXTYPE = FCGI_UNKNOWN_TYPE + +FCGI_NULL_REQUEST_ID = 0 + +FCGI_KEEP_CONN = 1 + +FCGI_RESPONDER = 1 +FCGI_AUTHORIZER = 2 +FCGI_FILTER = 3 + +FCGI_REQUEST_COMPLETE = 0 +FCGI_CANT_MPX_CONN = 1 +FCGI_OVERLOADED = 2 +FCGI_UNKNOWN_ROLE = 3 + +FCGI_MAX_CONNS = 'FCGI_MAX_CONNS' +FCGI_MAX_REQS = 'FCGI_MAX_REQS' +FCGI_MPXS_CONNS = 'FCGI_MPXS_CONNS' + +FCGI_Header = '!BBHHBx' +FCGI_BeginRequestBody = '!HB5x' +FCGI_EndRequestBody = '!LB3x' +FCGI_UnknownTypeBody = '!B7x' + +FCGI_EndRequestBody_LEN = struct.calcsize(FCGI_EndRequestBody) +FCGI_UnknownTypeBody_LEN = struct.calcsize(FCGI_UnknownTypeBody) + +if __debug__: + import time + + # Set non-zero to write debug output to a file. + DEBUG = 0 + DEBUGLOG = '/tmp/fcgi.log' + + def _debug(level, msg): + if DEBUG < level: + return + + try: + f = open(DEBUGLOG, 'a') + f.write('%sfcgi: %s\n' % (time.ctime()[4:-4], msg)) + f.close() + except: + pass + +class InputStream(object): + """ + File-like object representing FastCGI input streams (FCGI_STDIN and + FCGI_DATA). Supports the minimum methods required by WSGI spec. + """ + def __init__(self, conn): + self._conn = conn + + # See Server. + self._shrinkThreshold = conn.server.inputStreamShrinkThreshold + + self._buf = '' + self._bufList = [] + self._pos = 0 # Current read position. + self._avail = 0 # Number of bytes currently available. + + self._eof = False # True when server has sent EOF notification. + + def _shrinkBuffer(self): + """Gets rid of already read data (since we can't rewind).""" + if self._pos >= self._shrinkThreshold: + self._buf = self._buf[self._pos:] + self._avail -= self._pos + self._pos = 0 + + assert self._avail >= 0 + + def _waitForData(self): + """Waits for more data to become available.""" + self._conn.process_input() + + def read(self, n=-1): + if self._pos == self._avail and self._eof: + return '' + while True: + if n < 0 or (self._avail - self._pos) < n: + # Not enough data available. + if self._eof: + # And there's no more coming. + newPos = self._avail + break + else: + # Wait for more data. + self._waitForData() + continue + else: + newPos = self._pos + n + break + # Merge buffer list, if necessary. + if self._bufList: + self._buf += ''.join(self._bufList) + self._bufList = [] + r = self._buf[self._pos:newPos] + self._pos = newPos + self._shrinkBuffer() + return r + + def readline(self, length=None): + if self._pos == self._avail and self._eof: + return '' + while True: + # Unfortunately, we need to merge the buffer list early. + if self._bufList: + self._buf += ''.join(self._bufList) + self._bufList = [] + # Find newline. + i = self._buf.find('\n', self._pos) + if i < 0: + # Not found? + if self._eof: + # No more data coming. + newPos = self._avail + break + else: + # Wait for more to come. + self._waitForData() + continue + else: + newPos = i + 1 + break + if length is not None: + if self._pos + length < newPos: + newPos = self._pos + length + r = self._buf[self._pos:newPos] + self._pos = newPos + self._shrinkBuffer() + return r + + def readlines(self, sizehint=0): + total = 0 + lines = [] + line = self.readline() + while line: + lines.append(line) + total += len(line) + if 0 < sizehint <= total: + break + line = self.readline() + return lines + + def __iter__(self): + return self + + def next(self): + r = self.readline() + if not r: + raise StopIteration + return r + + def add_data(self, data): + if not data: + self._eof = True + else: + self._bufList.append(data) + self._avail += len(data) + +class MultiplexedInputStream(InputStream): + """ + A version of InputStream meant to be used with MultiplexedConnections. + Assumes the MultiplexedConnection (the producer) and the Request + (the consumer) are running in different threads. + """ + def __init__(self, conn): + super(MultiplexedInputStream, self).__init__(conn) + + # Arbitrates access to this InputStream (it's used simultaneously + # by a Request and its owning Connection object). + lock = threading.RLock() + + # Notifies Request thread that there is new data available. + self._lock = threading.Condition(lock) + + def _waitForData(self): + # Wait for notification from add_data(). + self._lock.wait() + + def read(self, n=-1): + self._lock.acquire() + try: + return super(MultiplexedInputStream, self).read(n) + finally: + self._lock.release() + + def readline(self, length=None): + self._lock.acquire() + try: + return super(MultiplexedInputStream, self).readline(length) + finally: + self._lock.release() + + def add_data(self, data): + self._lock.acquire() + try: + super(MultiplexedInputStream, self).add_data(data) + self._lock.notify() + finally: + self._lock.release() + +class OutputStream(object): + """ + FastCGI output stream (FCGI_STDOUT/FCGI_STDERR). By default, calls to + write() or writelines() immediately result in Records being sent back + to the server. Buffering should be done in a higher level! + """ + def __init__(self, conn, req, type, buffered=False): + self._conn = conn + self._req = req + self._type = type + self._buffered = buffered + self._bufList = [] # Used if buffered is True + self.dataWritten = False + self.closed = False + + def _write(self, data): + length = len(data) + while length: + toWrite = min(length, self._req.server.maxwrite - FCGI_HEADER_LEN) + + rec = Record(self._type, self._req.requestId) + rec.contentLength = toWrite + rec.contentData = data[:toWrite] + self._conn.writeRecord(rec) + + data = data[toWrite:] + length -= toWrite + + def write(self, data): + assert not self.closed + + if not data: + return + + self.dataWritten = True + + if self._buffered: + self._bufList.append(data) + else: + self._write(data) + + def writelines(self, lines): + assert not self.closed + + for line in lines: + self.write(line) + + def flush(self): + # Only need to flush if this OutputStream is actually buffered. + if self._buffered: + data = ''.join(self._bufList) + self._bufList = [] + self._write(data) + + # Though available, the following should NOT be called by WSGI apps. + def close(self): + """Sends end-of-stream notification, if necessary.""" + if not self.closed and self.dataWritten: + self.flush() + rec = Record(self._type, self._req.requestId) + self._conn.writeRecord(rec) + self.closed = True + +class TeeOutputStream(object): + """ + Simple wrapper around two or more output file-like objects that copies + written data to all streams. + """ + def __init__(self, streamList): + self._streamList = streamList + + def write(self, data): + for f in self._streamList: + f.write(data) + + def writelines(self, lines): + for line in lines: + self.write(line) + + def flush(self): + for f in self._streamList: + f.flush() + +class StdoutWrapper(object): + """ + Wrapper for sys.stdout so we know if data has actually been written. + """ + def __init__(self, stdout): + self._file = stdout + self.dataWritten = False + + def write(self, data): + if data: + self.dataWritten = True + self._file.write(data) + + def writelines(self, lines): + for line in lines: + self.write(line) + + def __getattr__(self, name): + return getattr(self._file, name) + +def decode_pair(s, pos=0): + """ + Decodes a name/value pair. + + The number of bytes decoded as well as the name/value pair + are returned. + """ + nameLength = ord(s[pos]) + if nameLength & 128: + nameLength = struct.unpack('!L', s[pos:pos+4])[0] & 0x7fffffff + pos += 4 + else: + pos += 1 + + valueLength = ord(s[pos]) + if valueLength & 128: + valueLength = struct.unpack('!L', s[pos:pos+4])[0] & 0x7fffffff + pos += 4 + else: + pos += 1 + + name = s[pos:pos+nameLength] + pos += nameLength + value = s[pos:pos+valueLength] + pos += valueLength + + return (pos, (name, value)) + +def encode_pair(name, value): + """ + Encodes a name/value pair. + + The encoded string is returned. + """ + nameLength = len(name) + if nameLength < 128: + s = chr(nameLength) + else: + s = struct.pack('!L', nameLength | 0x80000000L) + + valueLength = len(value) + if valueLength < 128: + s += chr(valueLength) + else: + s += struct.pack('!L', valueLength | 0x80000000L) + + return s + name + value + +class Record(object): + """ + A FastCGI Record. + + Used for encoding/decoding records. + """ + def __init__(self, type=FCGI_UNKNOWN_TYPE, requestId=FCGI_NULL_REQUEST_ID): + self.version = FCGI_VERSION_1 + self.type = type + self.requestId = requestId + self.contentLength = 0 + self.paddingLength = 0 + self.contentData = '' + + def _recvall(sock, length): + """ + Attempts to receive length bytes from a socket, blocking if necessary. + (Socket may be blocking or non-blocking.) + """ + dataList = [] + recvLen = 0 + while length: + try: + data = sock.recv(length) + except socket.error as e: + if e.errno == errno.EAGAIN: + select.select([sock], [], []) + continue + else: + raise + if not data: # EOF + break + dataList.append(data) + dataLen = len(data) + recvLen += dataLen + length -= dataLen + return ''.join(dataList), recvLen + _recvall = staticmethod(_recvall) + + def read(self, sock): + """Read and decode a Record from a socket.""" + try: + header, length = self._recvall(sock, FCGI_HEADER_LEN) + except: + raise EOFError + + if length < FCGI_HEADER_LEN: + raise EOFError + + self.version, self.type, self.requestId, self.contentLength, \ + self.paddingLength = struct.unpack(FCGI_Header, header) + + if __debug__: _debug(9, 'read: fd = %d, type = %d, requestId = %d, ' + 'contentLength = %d' % + (sock.fileno(), self.type, self.requestId, + self.contentLength)) + + if self.contentLength: + try: + self.contentData, length = self._recvall(sock, + self.contentLength) + except: + raise EOFError + + if length < self.contentLength: + raise EOFError + + if self.paddingLength: + try: + self._recvall(sock, self.paddingLength) + except: + raise EOFError + + def _sendall(sock, data): + """ + Writes data to a socket and does not return until all the data is sent. + """ + length = len(data) + while length: + try: + sent = sock.send(data) + except socket.error as e: + if e.errno == errno.EAGAIN: + select.select([], [sock], []) + continue + else: + raise + data = data[sent:] + length -= sent + _sendall = staticmethod(_sendall) + + def write(self, sock): + """Encode and write a Record to a socket.""" + self.paddingLength = -self.contentLength & 7 + + if __debug__: _debug(9, 'write: fd = %d, type = %d, requestId = %d, ' + 'contentLength = %d' % + (sock.fileno(), self.type, self.requestId, + self.contentLength)) + + header = struct.pack(FCGI_Header, self.version, self.type, + self.requestId, self.contentLength, + self.paddingLength) + self._sendall(sock, header) + if self.contentLength: + self._sendall(sock, self.contentData) + if self.paddingLength: + self._sendall(sock, '\x00'*self.paddingLength) + +class Request(object): + """ + Represents a single FastCGI request. + + These objects are passed to your handler and is the main interface + between your handler and the fcgi module. The methods should not + be called by your handler. However, server, params, stdin, stdout, + stderr, and data are free for your handler's use. + """ + def __init__(self, conn, inputStreamClass): + self._conn = conn + + self.server = conn.server + self.params = {} + self.stdin = inputStreamClass(conn) + self.stdout = OutputStream(conn, self, FCGI_STDOUT) + self.stderr = OutputStream(conn, self, FCGI_STDERR, buffered=True) + self.data = inputStreamClass(conn) + + def run(self): + """Runs the handler, flushes the streams, and ends the request.""" + try: + protocolStatus, appStatus = self.server.handler(self) + except: + traceback.print_exc(file=self.stderr) + self.stderr.flush() + if not self.stdout.dataWritten: + self.server.error(self) + + protocolStatus, appStatus = FCGI_REQUEST_COMPLETE, 0 + + if __debug__: _debug(1, 'protocolStatus = %d, appStatus = %d' % + (protocolStatus, appStatus)) + + self._flush() + self._end(appStatus, protocolStatus) + + def _end(self, appStatus=0L, protocolStatus=FCGI_REQUEST_COMPLETE): + self._conn.end_request(self, appStatus, protocolStatus) + + def _flush(self): + self.stdout.close() + self.stderr.close() + +class CGIRequest(Request): + """A normal CGI request disguised as a FastCGI request.""" + def __init__(self, server): + # These are normally filled in by Connection. + self.requestId = 1 + self.role = FCGI_RESPONDER + self.flags = 0 + self.aborted = False + + self.server = server + self.params = dict(os.environ) + self.stdin = sys.stdin + self.stdout = StdoutWrapper(sys.stdout) # Oh, the humanity! + self.stderr = sys.stderr + self.data = StringIO.StringIO() + + def _end(self, appStatus=0L, protocolStatus=FCGI_REQUEST_COMPLETE): + sys.exit(appStatus) + + def _flush(self): + # Not buffered, do nothing. + pass + +class Connection(object): + """ + A Connection with the web server. + + Each Connection is associated with a single socket (which is + connected to the web server) and is responsible for handling all + the FastCGI message processing for that socket. + """ + _multiplexed = False + _inputStreamClass = InputStream + + def __init__(self, sock, addr, server): + self._sock = sock + self._addr = addr + self.server = server + + # Active Requests for this Connection, mapped by request ID. + self._requests = {} + + def _cleanupSocket(self): + """Close the Connection's socket.""" + try: + self._sock.shutdown(socket.SHUT_WR) + except: + return + try: + while True: + r, w, e = select.select([self._sock], [], []) + if not r or not self._sock.recv(1024): + break + except: + pass + self._sock.close() + + def run(self): + """Begin processing data from the socket.""" + self._keepGoing = True + while self._keepGoing: + try: + self.process_input() + except EOFError: + break + except (select.error, socket.error), e: + if e.errno == errno.EBADF: # Socket was closed by Request. + break + raise + + self._cleanupSocket() + + def process_input(self): + """Attempt to read a single Record from the socket and process it.""" + # Currently, any children Request threads notify this Connection + # that it is no longer needed by closing the Connection's socket. + # We need to put a timeout on select, otherwise we might get + # stuck in it indefinitely... (I don't like this solution.) + while self._keepGoing: + try: + r, w, e = select.select([self._sock], [], [], 1.0) + except ValueError: + # Sigh. ValueError gets thrown sometimes when passing select + # a closed socket. + raise EOFError + if r: break + if not self._keepGoing: + return + rec = Record() + rec.read(self._sock) + + if rec.type == FCGI_GET_VALUES: + self._do_get_values(rec) + elif rec.type == FCGI_BEGIN_REQUEST: + self._do_begin_request(rec) + elif rec.type == FCGI_ABORT_REQUEST: + self._do_abort_request(rec) + elif rec.type == FCGI_PARAMS: + self._do_params(rec) + elif rec.type == FCGI_STDIN: + self._do_stdin(rec) + elif rec.type == FCGI_DATA: + self._do_data(rec) + elif rec.requestId == FCGI_NULL_REQUEST_ID: + self._do_unknown_type(rec) + else: + # Need to complain about this. + pass + + def writeRecord(self, rec): + """ + Write a Record to the socket. + """ + rec.write(self._sock) + + def end_request(self, req, appStatus=0L, + protocolStatus=FCGI_REQUEST_COMPLETE, remove=True): + """ + End a Request. + + Called by Request objects. An FCGI_END_REQUEST Record is + sent to the web server. If the web server no longer requires + the connection, the socket is closed, thereby ending this + Connection (run() returns). + """ + rec = Record(FCGI_END_REQUEST, req.requestId) + rec.contentData = struct.pack(FCGI_EndRequestBody, appStatus, + protocolStatus) + rec.contentLength = FCGI_EndRequestBody_LEN + self.writeRecord(rec) + + if remove: + del self._requests[req.requestId] + + if __debug__: _debug(2, 'end_request: flags = %d' % req.flags) + + if not (req.flags & FCGI_KEEP_CONN) and not self._requests: + self._cleanupSocket() + self._keepGoing = False + + def _do_get_values(self, inrec): + """Handle an FCGI_GET_VALUES request from the web server.""" + outrec = Record(FCGI_GET_VALUES_RESULT) + + pos = 0 + while pos < inrec.contentLength: + pos, (name, value) = decode_pair(inrec.contentData, pos) + cap = self.server.capability.get(name) + if cap is not None: + outrec.contentData += encode_pair(name, str(cap)) + + outrec.contentLength = len(outrec.contentData) + self.writeRecord(outrec) + + def _do_begin_request(self, inrec): + """Handle an FCGI_BEGIN_REQUEST from the web server.""" + role, flags = struct.unpack(FCGI_BeginRequestBody, inrec.contentData) + + req = self.server.request_class(self, self._inputStreamClass) + req.requestId, req.role, req.flags = inrec.requestId, role, flags + req.aborted = False + + if not self._multiplexed and self._requests: + # Can't multiplex requests. + self.end_request(req, 0L, FCGI_CANT_MPX_CONN, remove=False) + else: + self._requests[inrec.requestId] = req + + def _do_abort_request(self, inrec): + """ + Handle an FCGI_ABORT_REQUEST from the web server. + + We just mark a flag in the associated Request. + """ + req = self._requests.get(inrec.requestId) + if req is not None: + req.aborted = True + + def _start_request(self, req): + """Run the request.""" + # Not multiplexed, so run it inline. + req.run() + + def _do_params(self, inrec): + """ + Handle an FCGI_PARAMS Record. + + If the last FCGI_PARAMS Record is received, start the request. + """ + req = self._requests.get(inrec.requestId) + if req is not None: + if inrec.contentLength: + pos = 0 + while pos < inrec.contentLength: + pos, (name, value) = decode_pair(inrec.contentData, pos) + req.params[name] = value + else: + self._start_request(req) + + def _do_stdin(self, inrec): + """Handle the FCGI_STDIN stream.""" + req = self._requests.get(inrec.requestId) + if req is not None: + req.stdin.add_data(inrec.contentData) + + def _do_data(self, inrec): + """Handle the FCGI_DATA stream.""" + req = self._requests.get(inrec.requestId) + if req is not None: + req.data.add_data(inrec.contentData) + + def _do_unknown_type(self, inrec): + """Handle an unknown request type. Respond accordingly.""" + outrec = Record(FCGI_UNKNOWN_TYPE) + outrec.contentData = struct.pack(FCGI_UnknownTypeBody, inrec.type) + outrec.contentLength = FCGI_UnknownTypeBody_LEN + self.writeRecord(outrec) + +class MultiplexedConnection(Connection): + """ + A version of Connection capable of handling multiple requests + simultaneously. + """ + _multiplexed = True + _inputStreamClass = MultiplexedInputStream + + def __init__(self, sock, addr, server): + super(MultiplexedConnection, self).__init__(sock, addr, server) + + # Used to arbitrate access to self._requests. + lock = threading.RLock() + + # Notification is posted everytime a request completes, allowing us + # to quit cleanly. + self._lock = threading.Condition(lock) + + def _cleanupSocket(self): + # Wait for any outstanding requests before closing the socket. + self._lock.acquire() + while self._requests: + self._lock.wait() + self._lock.release() + + super(MultiplexedConnection, self)._cleanupSocket() + + def writeRecord(self, rec): + # Must use locking to prevent intermingling of Records from different + # threads. + self._lock.acquire() + try: + # Probably faster than calling super. ;) + rec.write(self._sock) + finally: + self._lock.release() + + def end_request(self, req, appStatus=0L, + protocolStatus=FCGI_REQUEST_COMPLETE, remove=True): + self._lock.acquire() + try: + super(MultiplexedConnection, self).end_request(req, appStatus, + protocolStatus, + remove) + self._lock.notify() + finally: + self._lock.release() + + def _do_begin_request(self, inrec): + self._lock.acquire() + try: + super(MultiplexedConnection, self)._do_begin_request(inrec) + finally: + self._lock.release() + + def _do_abort_request(self, inrec): + self._lock.acquire() + try: + super(MultiplexedConnection, self)._do_abort_request(inrec) + finally: + self._lock.release() + + def _start_request(self, req): + thread.start_new_thread(req.run, ()) + + def _do_params(self, inrec): + self._lock.acquire() + try: + super(MultiplexedConnection, self)._do_params(inrec) + finally: + self._lock.release() + + def _do_stdin(self, inrec): + self._lock.acquire() + try: + super(MultiplexedConnection, self)._do_stdin(inrec) + finally: + self._lock.release() + + def _do_data(self, inrec): + self._lock.acquire() + try: + super(MultiplexedConnection, self)._do_data(inrec) + finally: + self._lock.release() + +class Server(object): + """ + The FastCGI server. + + Waits for connections from the web server, processing each + request. + + If run in a normal CGI context, it will instead instantiate a + CGIRequest and run the handler through there. + """ + request_class = Request + cgirequest_class = CGIRequest + + # Limits the size of the InputStream's string buffer to this size + the + # server's maximum Record size. Since the InputStream is not seekable, + # we throw away already-read data once this certain amount has been read. + inputStreamShrinkThreshold = 102400 - 8192 + + def __init__(self, handler=None, maxwrite=8192, bindAddress=None, + umask=None, multiplexed=False): + """ + handler, if present, must reference a function or method that + takes one argument: a Request object. If handler is not + specified at creation time, Server *must* be subclassed. + (The handler method below is abstract.) + + maxwrite is the maximum number of bytes (per Record) to write + to the server. I've noticed mod_fastcgi has a relatively small + receive buffer (8K or so). + + bindAddress, if present, must either be a string or a 2-tuple. If + present, run() will open its own listening socket. You would use + this if you wanted to run your application as an 'external' FastCGI + app. (i.e. the webserver would no longer be responsible for starting + your app) If a string, it will be interpreted as a filename and a UNIX + socket will be opened. If a tuple, the first element, a string, + is the interface name/IP to bind to, and the second element (an int) + is the port number. + + Set multiplexed to True if you want to handle multiple requests + per connection. Some FastCGI backends (namely mod_fastcgi) don't + multiplex requests at all, so by default this is off (which saves + on thread creation/locking overhead). If threads aren't available, + this keyword is ignored; it's not possible to multiplex requests + at all. + """ + if handler is not None: + self.handler = handler + self.maxwrite = maxwrite + if thread_available: + try: + import resource + # Attempt to glean the maximum number of connections + # from the OS. + maxConns = resource.getrlimit(resource.RLIMIT_NOFILE)[0] + except ImportError: + maxConns = 100 # Just some made up number. + maxReqs = maxConns + if multiplexed: + self._connectionClass = MultiplexedConnection + maxReqs *= 5 # Another made up number. + else: + self._connectionClass = Connection + self.capability = { + FCGI_MAX_CONNS: maxConns, + FCGI_MAX_REQS: maxReqs, + FCGI_MPXS_CONNS: multiplexed and 1 or 0 + } + else: + self._connectionClass = Connection + self.capability = { + # If threads aren't available, these are pretty much correct. + FCGI_MAX_CONNS: 1, + FCGI_MAX_REQS: 1, + FCGI_MPXS_CONNS: 0 + } + self._bindAddress = bindAddress + self._umask = umask + + def _setupSocket(self): + if self._bindAddress is None: # Run as a normal FastCGI? + isFCGI = True + + sock = socket.fromfd(FCGI_LISTENSOCK_FILENO, socket.AF_INET, + socket.SOCK_STREAM) + try: + sock.getpeername() + except socket.error as e: + if e.errno == errno.ENOTSOCK: + # Not a socket, assume CGI context. + isFCGI = False + elif e.errno != errno.ENOTCONN: + raise + + # FastCGI/CGI discrimination is broken on Mac OS X. + # Set the environment variable FCGI_FORCE_CGI to "Y" or "y" + # if you want to run your app as a simple CGI. (You can do + # this with Apache's mod_env [not loaded by default in OS X + # client, ha ha] and the SetEnv directive.) + if not isFCGI or \ + os.environ.get('FCGI_FORCE_CGI', 'N').upper().startswith('Y'): + req = self.cgirequest_class(self) + req.run() + sys.exit(0) + else: + # Run as a server + oldUmask = None + if type(self._bindAddress) is str: + # Unix socket + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + try: + os.unlink(self._bindAddress) + except OSError: + pass + if self._umask is not None: + oldUmask = os.umask(self._umask) + else: + # INET socket + assert type(self._bindAddress) is tuple + assert len(self._bindAddress) == 2 + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + sock.bind(self._bindAddress) + sock.listen(socket.SOMAXCONN) + + if oldUmask is not None: + os.umask(oldUmask) + + return sock + + def _cleanupSocket(self, sock): + """Closes the main socket.""" + sock.close() + + def _installSignalHandlers(self): + self._oldSIGs = [(x,signal.getsignal(x)) for x in + (signal.SIGHUP, signal.SIGINT, signal.SIGTERM)] + signal.signal(signal.SIGHUP, self._hupHandler) + signal.signal(signal.SIGINT, self._intHandler) + signal.signal(signal.SIGTERM, self._intHandler) + + def _restoreSignalHandlers(self): + for signum,handler in self._oldSIGs: + signal.signal(signum, handler) + + def _hupHandler(self, signum, frame): + self._hupReceived = True + self._keepGoing = False + + def _intHandler(self, signum, frame): + self._keepGoing = False + + def run(self, timeout=1.0): + """ + The main loop. Exits on SIGHUP, SIGINT, SIGTERM. Returns True if + SIGHUP was received, False otherwise. + """ + web_server_addrs = os.environ.get('FCGI_WEB_SERVER_ADDRS') + if web_server_addrs is not None: + web_server_addrs = map(lambda x: x.strip(), + web_server_addrs.split(',')) + + sock = self._setupSocket() + + self._keepGoing = True + self._hupReceived = False + + # Install signal handlers. + self._installSignalHandlers() + + while self._keepGoing: + try: + r, w, e = select.select([sock], [], [], timeout) + except select.error, e: + if e.errno == errno.EINTR: + continue + raise + + if r: + try: + clientSock, addr = sock.accept() + except socket.error as e: + if e.errno in (errno.EINTR, errno.EAGAIN): + continue + raise + + if web_server_addrs and \ + (len(addr) != 2 or addr[0] not in web_server_addrs): + clientSock.close() + continue + + # Instantiate a new Connection and begin processing FastCGI + # messages (either in a new thread or this thread). + conn = self._connectionClass(clientSock, addr, self) + thread.start_new_thread(conn.run, ()) + + self._mainloopPeriodic() + + # Restore signal handlers. + self._restoreSignalHandlers() + + self._cleanupSocket(sock) + + return self._hupReceived + + def _mainloopPeriodic(self): + """ + Called with just about each iteration of the main loop. Meant to + be overridden. + """ + pass + + def _exit(self, reload=False): + """ + Protected convenience method for subclasses to force an exit. Not + really thread-safe, which is why it isn't public. + """ + if self._keepGoing: + self._keepGoing = False + self._hupReceived = reload + + def handler(self, req): + """ + Default handler, which just raises an exception. Unless a handler + is passed at initialization time, this must be implemented by + a subclass. + """ + raise NotImplementedError, self.__class__.__name__ + '.handler' + + def error(self, req): + """ + Called by Request if an exception occurs within the handler. May and + should be overridden. + """ + import cgitb + req.stdout.write('Content-Type: text/html\r\n\r\n' + + cgitb.html(sys.exc_info())) + +class WSGIServer(Server): + """ + FastCGI server that supports the Web Server Gateway Interface. See + . + """ + def __init__(self, application, environ=None, + multithreaded=True, **kw): + """ + environ, if present, must be a dictionary-like object. Its + contents will be copied into application's environ. Useful + for passing application-specific variables. + + Set multithreaded to False if your application is not MT-safe. + """ + if kw.has_key('handler'): + del kw['handler'] # Doesn't make sense to let this through + super(WSGIServer, self).__init__(**kw) + + if environ is None: + environ = {} + + self.application = application + self.environ = environ + self.multithreaded = multithreaded + + # Used to force single-threadedness + self._app_lock = thread.allocate_lock() + + def handler(self, req): + """Special handler for WSGI.""" + if req.role != FCGI_RESPONDER: + return FCGI_UNKNOWN_ROLE, 0 + + # Mostly taken from example CGI gateway. + environ = req.params + environ.update(self.environ) + + environ['wsgi.version'] = (1,0) + environ['wsgi.input'] = req.stdin + if self._bindAddress is None: + stderr = req.stderr + else: + stderr = TeeOutputStream((sys.stderr, req.stderr)) + environ['wsgi.errors'] = stderr + environ['wsgi.multithread'] = not isinstance(req, CGIRequest) and \ + thread_available and self.multithreaded + # Rationale for the following: If started by the web server + # (self._bindAddress is None) in either FastCGI or CGI mode, the + # possibility of being spawned multiple times simultaneously is quite + # real. And, if started as an external server, multiple copies may be + # spawned for load-balancing/redundancy. (Though I don't think + # mod_fastcgi supports this?) + environ['wsgi.multiprocess'] = True + environ['wsgi.run_once'] = isinstance(req, CGIRequest) + + if environ.get('HTTPS', 'off') in ('on', '1'): + environ['wsgi.url_scheme'] = 'https' + else: + environ['wsgi.url_scheme'] = 'http' + + self._sanitizeEnv(environ) + + headers_set = [] + headers_sent = [] + result = None + + def write(data): + assert type(data) is str, 'write() argument must be string' + assert headers_set, 'write() before start_response()' + + if not headers_sent: + status, responseHeaders = headers_sent[:] = headers_set + found = False + for header,value in responseHeaders: + if header.lower() == 'content-length': + found = True + break + if not found and result is not None: + try: + if len(result) == 1: + responseHeaders.append(('Content-Length', + str(len(data)))) + except: + pass + s = 'Status: %s\r\n' % status + for header in responseHeaders: + s += '%s: %s\r\n' % header + s += '\r\n' + req.stdout.write(s) + + req.stdout.write(data) + req.stdout.flush() + + def start_response(status, response_headers, exc_info=None): + if exc_info: + try: + if headers_sent: + # Re-raise if too late + raise exc_info[0], exc_info[1], exc_info[2] + finally: + exc_info = None # avoid dangling circular ref + else: + assert not headers_set, 'Headers already set!' + + assert type(status) is str, 'Status must be a string' + assert len(status) >= 4, 'Status must be at least 4 characters' + assert int(status[:3]), 'Status must begin with 3-digit code' + assert status[3] == ' ', 'Status must have a space after code' + assert type(response_headers) is list, 'Headers must be a list' + if __debug__: + for name,val in response_headers: + assert type(name) is str, 'Header names must be strings' + assert type(val) is str, 'Header values must be strings' + + headers_set[:] = [status, response_headers] + return write + + if not self.multithreaded: + self._app_lock.acquire() + try: + try: + result = self.application(environ, start_response) + try: + for data in result: + if data: + write(data) + if not headers_sent: + write('') # in case body was empty + finally: + if hasattr(result, 'close'): + result.close() + except socket.error as e: + if e.errno != errno.EPIPE: + raise # Don't let EPIPE propagate beyond server + finally: + if not self.multithreaded: + self._app_lock.release() + + return FCGI_REQUEST_COMPLETE, 0 + + def _sanitizeEnv(self, environ): + """Ensure certain values are present, if required by WSGI.""" + if not environ.has_key('SCRIPT_NAME'): + environ['SCRIPT_NAME'] = '' + if not environ.has_key('PATH_INFO'): + environ['PATH_INFO'] = '' + + # If any of these are missing, it probably signifies a broken + # server... + for name,default in [('REQUEST_METHOD', 'GET'), + ('SERVER_NAME', 'localhost'), + ('SERVER_PORT', '80'), + ('SERVER_PROTOCOL', 'HTTP/1.0')]: + if not environ.has_key(name): + environ['wsgi.errors'].write('%s: missing FastCGI param %s ' + 'required by WSGI!\n' % + (self.__class__.__name__, name)) + environ[name] = default + +if __name__ == '__main__': + def test_app(environ, start_response): + """Probably not the most efficient example.""" + import cgi + start_response('200 OK', [('Content-Type', 'text/html')]) + yield 'Hello World!\n' \ + '\n' \ + '

    Hello World!

    \n' \ + '' + names = environ.keys() + names.sort() + for name in names: + yield '\n' % ( + name, cgi.escape(`environ[name]`)) + + form = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ, + keep_blank_values=1) + if form.list: + yield '' + + for field in form.list: + yield '\n' % ( + field.name, field.value) + + yield '
    %s%s
    Form data
    %s%s
    \n' \ + '\n' + + WSGIServer(test_app).run() diff --git a/web2py/gluon/contrib/generics.py b/web2py/gluon/contrib/generics.py new file mode 100644 index 0000000..3beb6e5 --- /dev/null +++ b/web2py/gluon/contrib/generics.py @@ -0,0 +1,76 @@ +# fix response + +import os +from gluon import current, HTTP +from gluon.html import markmin_serializer, TAG, HTML, BODY, UL, XML, H1 +from gluon.contrib.fpdf import FPDF, HTMLMixin +from gluon.sanitizer import sanitize +from gluon.contrib.markmin.markmin2latex import markmin2latex +from gluon.contrib.markmin.markmin2pdf import markmin2pdf + + +def wrapper(f): + def g(data): + try: + output = f(data) + return XML(ouput) + except (TypeError, ValueError) as e: + raise HTTP(405, '%s serialization error' % e) + except ImportError as e: + raise HTTP(405, '%s not available' % e) + except Exception as e: + raise HTTP(405, '%s error' % e) + return g + + +def latex_from_html(html): + markmin = TAG(html).element('body').flatten(markmin_serializer) + return markmin2latex(markmin) + + +def pdflatex_from_html(html): + if os.system('which pdflatex > /dev/null') == 0: + markmin = TAG(html).element('body').flatten(markmin_serializer) + out, warnings, errors = markmin2pdf(markmin) + if errors: + current.response.headers['Content-Type'] = 'text/html' + raise HTTP(405, HTML(BODY(H1('errors'), + UL(*errors), + H1('warnings'), + UL(*warnings))).xml()) + else: + return out + + +def pyfpdf_from_html(html): + request = current.request + + def image_map(path): + if path.startswith('/%s/static/' % request.application): + return os.path.join(request.folder, path.split('/', 2)[2]) + return 'http%s://%s%s' % (request.is_https and 's' or '', request.env.http_host, path) + + class MyFPDF(FPDF, HTMLMixin): + pass + pdf = MyFPDF() + pdf.add_page() + # pyfpdf needs some attributes to render the table correctly: + html = sanitize( + html, allowed_attributes={ + 'a': ['href', 'title'], + 'img': ['src', 'alt'], + 'blockquote': ['type'], + 'td': ['align', 'bgcolor', 'colspan', 'height', 'width'], + 'tr': ['bgcolor', 'height', 'width'], + 'table': ['border', 'bgcolor', 'height', 'width'], + }, escape=False) + pdf.write_html(html, image_map=image_map) + return XML(pdf.output(dest='S')) + + +def pdf_from_html(html): + # try use latex and pdflatex + if os.system('which pdflatex > /dev/null') == 0: + return pdflatex_from_html(html) + else: + return pyfpdf_from_html(html) diff --git a/web2py/gluon/contrib/google_wallet.py b/web2py/gluon/contrib/google_wallet.py new file mode 100644 index 0000000..822baa2 --- /dev/null +++ b/web2py/gluon/contrib/google_wallet.py @@ -0,0 +1,15 @@ +from gluon.html import XML + +def button(merchant_id="123456789012345", + products=[dict(name="shoes", + quantity=1, + price=23.5, + currency='USD', + description="running shoes black")]): + t = '\n' + list_products = '' + for k, product in enumerate(products): + for key in ('name','description','quantity','price','currency'): + list_products += t % dict(k=k + 1, key=key, value=product[key]) + button = """
    \n%(list_products)s\n\n
    """ % dict(merchant_id=merchant_id, list_products=list_products) + return XML(button) diff --git a/web2py/gluon/contrib/heroku.py b/web2py/gluon/contrib/heroku.py new file mode 100644 index 0000000..a5b50b2 --- /dev/null +++ b/web2py/gluon/contrib/heroku.py @@ -0,0 +1,28 @@ +""" +Usage: in web2py models/db.py + +from gluon.contrib.heroku import get_db +db = get_db() + +""" +import os +from gluon import * +from pydal.adapters import adapters, PostgrePsyco +from pydal.helpers.classes import DatabaseStoredFile + +@adapters.register_for('postgres') +class HerokuPostgresAdapter(DatabaseStoredFile, PostgrePsyco): + uploads_in_blob = True + +def get_db(name = None, pool_size=10): + if not name: + names = [n for n in os.environ.keys() + if n[:18]+n[-4:]=='HEROKU_POSTGRESQL__URL'] + if names: + name = names[0] + if name: + db = DAL(os.environ[name], pool_size=pool_size) + current.session.connect(current.request, current.response, db=db) + else: + db = DAL('sqlite://heroku.test.sqlite') + return db diff --git a/web2py/gluon/contrib/hypermedia.py b/web2py/gluon/contrib/hypermedia.py new file mode 100644 index 0000000..03aec2f --- /dev/null +++ b/web2py/gluon/contrib/hypermedia.py @@ -0,0 +1,341 @@ +import json +from collections import OrderedDict +from gluon import URL, IS_SLUG +from functools import reduce + +# compliant with https://github.com/collection-json/spec +# also compliant with http://code.ge/media-types/collection-next-json/ + +""" + +Example controller: + +def api(): + from gluon.contrib.hypermedia import Collection + policies = { + 'thing': { + 'GET':{'query':None,'fields':['id', 'name']}, + 'POST':{'query':None,'fields':['name']}, + 'PUT':{'query':None,'fields':['name']}, + 'DELETE':{'query':None}, + }, + 'attr': { + 'GET':{'query':None,'fields':['id', 'name', 'thing']}, + 'POST':{'query':None,'fields':['name', 'thing']}, + 'PUT':{'query':None,'fields':['name', 'thing']}, + 'DELETE':{'query':None}, + }, + } + return Collection(db).process(request, response, policies) +""" + +__all__ = ['Collection'] + +class Collection(object): + + VERSION = '1.0' + MAXITEMS = 100 + + def __init__(self,db, extensions=True, compact=False): + self.db = db + self.extensions = extensions + self.compact = compact + + def row2data(self,table,row,text=False): + """ converts a DAL Row object into a collection.item """ + data = [] + if self.compact: + for fieldname in (self.table_policy.get('fields',table.fields)): + field = table[fieldname] + if not ((field.type=='text' and text==False) or + field.type=='blob' or + field.type.startswith('reference ') or + field.type.startswith('list:reference ')) and field.name in row: + data.append(row[field.name]) + else: + for fieldname in (self.table_policy.get('fields',table.fields)): + field = table[fieldname] + if not ((field.type=='text' and text==False) or + field.type=='blob' or + field.type.startswith('reference ') or + field.type.startswith('list:reference ')) and field.name in row: + data.append({'name':field.name,'value':row[field.name], + 'prompt':field.label, 'type':field.type}) + return data + + def row2links(self,table,row): + """ converts a DAL Row object into a set of links referencing the row """ + links = [] + for field in table._referenced_by: + if field._tablename in self.policies: + if row: + href = URL(args=field._tablename,vars={field.name:row.id},scheme=True) + else: + href = URL(args=field._tablename,scheme=True)+'?%s={id}' % field.name + links.append({'rel':'current','href':href,'prompt':str(field), + 'type':'children'}) + if row: + fields = self.table_policy.get('fields', table.fields) + for fieldname in fields: + field = table[fieldname] + if field.type.startswith('reference '): + href = URL(args=field.type[10:],vars={'id':row[fieldname]}, + scheme=True) + links.append({'rel':'current','href':href,'prompt':str(field), + 'type':'parent'}) + + for fieldname in fields: + field = table[fieldname] + if field.type=='upload' and row[fieldname]: + href = URL('download',args=row[fieldname],scheme=True) + links.append({'rel':'current','href':href,'prompt':str(field), + 'type':'attachment'}) + + # should this be supported? + for rel,build in (self.table_policy.get('links',{}).items()): + links.append({'rel':'current','href':build(row),'prompt':rel}) + # not sure + return links + + def table2template(self,table): + """ confeverts a table into its form template """ + data = [] + fields = self.table_policy.get('fields', table.fields) + for fieldname in fields: + field = table[fieldname] + info = {'name': field.name, 'value': '', 'prompt': field.label} + policies = self.policies[table._tablename] + # https://github.com/collection-json/extensions/blob/master/template-validation.md + info['type'] = str(field.type) # FIX THIS + if hasattr(field,'regexp_validator'): + info['regexp'] = field.regexp_validator + info['required'] = field.required + info['post_writable'] = field.name in policies['POST'].get('fields',fields) + info['put_writable'] = field.name in policies['PUT'].get('fields',fields) + info['options'] = {} # FIX THIS + data.append(info) + return {'data':data} + + def request2query(self,table,vars): + """ parses a request and converts it into a query """ + if len(self.request.args)>1: + vars.id = self.request.args[1] + + fieldnames = table.fields + queries = [table] + limitby = [0,self.MAXITEMS+1] + orderby = 'id' + for key,value in vars.items(): + if key=='_offset': + limitby[0] = int(value) # MAY FAIL + elif key == '_limit': + limitby[1] = int(value)+1 # MAY FAIL + elif key=='_orderby': + orderby = value + elif key in fieldnames: + queries.append(table[key] == value) + elif key.endswith('.eq') and key[:-3] in fieldnames: # for completeness (useless) + queries.append(table[key[:-3]] == value) + elif key.endswith('.lt') and key[:-3] in fieldnames: + queries.append(table[key[:-3]] < value) + elif key.endswith('.le') and key[:-3] in fieldnames: + queries.append(table[key[:-3]] <= value) + elif key.endswith('.gt') and key[:-3] in fieldnames: + queries.append(table[key[:-3]] > value) + elif key.endswith('.ge') and key[:-3] in fieldnames: + queries.append(table[key[:-3]] >= value) + elif key.endswith('.contains') and key[:-9] in fieldnames: + queries.append(table[key[:-9]].contains(value)) + elif key.endswith('.startswith') and key[:-11] in fieldnames: + queries.append(table[key[:-11]].startswith(value)) + elif key.endswith('.ne') and key[:-3] in fieldnames: + queries.append(table[key][:-3] != value) + else: + raise ValueError("Invalid Query") + filter_query = self.table_policy.get('query') + if filter_query: + queries.append(filter_query) + query = reduce(lambda a,b:a&b,queries[1:]) if len(queries)>1 else queries[0] + orderby = [table[f] if f[0]!='~' else ~table[f[1:]] for f in orderby.split(',')] + return (query, limitby, orderby) + + def table2queries(self,table, href): + """ generates a set of collection.queries examples for the table """ + data = [] + for fieldname in (self.table_policy.get('fields', table.fields)): + data.append({'name':fieldname,'value':''}) + if self.extensions: + data.append({'name':fieldname+'.ne','value':''}) # NEW !!! + data.append({'name':fieldname+'.lt','value':''}) + data.append({'name':fieldname+'.le','value':''}) + data.append({'name':fieldname+'.gt','value':''}) + data.append({'name':fieldname+'.ge','value':''}) + if table[fieldname].type in ['string','text']: + data.append({'name':fieldname+'.contains','value':''}) + data.append({'name':fieldname+'.startswith','value':''}) + data.append({'name':'_limitby','value':''}) + data.append({'name':'_offset','value':''}) + data.append({'name':'_orderby','value':''}) + return [{'rel' : 'search', 'href' : href, 'prompt' : 'Search', 'data' : data}] + + def process(self,request,response,policies=None): + """ the main method, processes a request, filters by policies and produces a JSON response """ + self.request = request + self.response = response + self.policies = policies + db = self.db + tablename = request.args(0) + r = OrderedDict() + r['version'] = self.VERSION + tablenames = policies.keys() if policies else db.tables + # if there is no tables + if not tablename: + r['href'] = URL(scheme=True), + # https://github.com/collection-json/extensions/blob/master/model.md + r['links'] = [{'rel' : t, 'href' : URL(args=t,scheme=True), 'model':t} + for t in tablenames] + response.headers['Content-Type'] = 'application/vnd.collection+json' + return response.json({'collection':r}) + # or if the tablenames is invalid + if not tablename in tablenames: + return self.error(400,'BAD REQUEST','Invalid table name') + # of if the method is invalid + if not request.env.request_method in policies[tablename]: + return self.error(400,'BAD REQUEST','Method not recognized') + # get the policies + self.table_policy = policies[tablename][request.env.request_method] + # process GET + if request.env.request_method=='GET': + table = db[tablename] + r['href'] = URL(args=tablename) + r['items'] = items = [] + try: + (query, limitby, orderby) = self.request2query(table,request.get_vars) + fields = [table[fn] for fn in (self.table_policy.get('fields', table.fields))] + fields = filter(lambda field: field.readable, fields) + rows = db(query).select(*fields,**dict(limitby=limitby, orderby=orderby)) + except: + db.rollback() + return self.error(400,'BAD REQUEST','Invalid Query') + r['items_found'] = db(query).count() + delta = limitby[1]-limitby[0]-1 + r['links'] = self.row2links(table,None) if self.compact else [] + text = r['items_found']<2 + for row in rows[:delta]: + id = row.id + for name in ('slug','fullname','title','name'): + if name in row: + href = URL(args=(tablename,id),scheme=True) + break + else: + href = URL(args=(tablename,id),scheme=True) + if self.compact: + items.append(self.row2data(table,row,text)) + else: + items.append({ + 'href':href, + 'data':self.row2data(table,row,text), + 'links':self.row2links(table,row) + }); + if self.extensions and len(rows)>delta: + vars = dict(request.get_vars) + vars['_offset'] = limitby[1]-1 + vars['_limit'] = limitby[1]-1+delta + r['next'] = {'rel':'next', + 'href':URL(args=request.args,vars=vars,scheme=True)} + if self.extensions and limitby[0]>0: + vars = dict(request.get_vars) + vars['_offset'] = max(0,limitby[0]-delta) + vars['_limit'] = limitby[0] + r['previous'] = {'rel':'previous', + 'href':URL(args=request.args,vars=vars,scheme=True)} + data = [] + if not self.compact: + r['queries'] = self.table2queries(table, r['href']) + r['template'] = self.table2template(table) + response.headers['Content-Type'] = 'application/vnd.collection+json' + return response.json({'collection':r}) + # process DELETE + elif request.env.request_method=='DELETE': + table = db[tablename] + if not request.get_vars: + return self.error(400, "BAD REQUEST", "Nothing to delete") + else: + try: + (query, limitby, orderby) = self.request2query(table, request.vars) + n = db(query).delete() # MAY FAIL + response.status = 204 + return '' + except: + db.rollback() + return self.error(400,'BAD REQUEST','Invalid Query') + return response.json(r) + # process POST and PUT (on equal footing!) + elif request.env.request_method in ('POST','PUT'): # we treat them the same! + table = db[tablename] + if 'json' in request.env.content_type: + data = request.post_vars.data + else: + data = request.post_vars + if request.get_vars or len(request.args)>1: # update + # ADD validate fields and return error + try: + (query, limitby, orderby) = self.request2query(table, request.get_vars) + fields = filter(lambda fn_value:table[fn_value[0]].writable,data.items()) + res = db(query).validate_and_update(**dict(fields)) # MAY FAIL + if res.errors: + return self.error(400,'BAD REQUEST','Validation Error',res.errors) + else: + response.status = 200 + return '' + except: + db.rollback() + return self.error(400,'BAD REQUEST','Invalid Query') + else: # create + # ADD validate fields and return error + try: + fields = filter(lambda fn_value1:table[fn_value1[0]].writable,data.items()) + res = table.validate_and_insert(**dict(fields)) # MAY FAIL + if res.errors: + return self.error(400,'BAD REQUEST','Validation Error',res.errors) + else: + response.status = 201 + response.headers['location'] = \ + URL(args=(tablename,res.id),scheme=True) + return '' + except SyntaxError as e: #Exception,e: + db.rollback() + return self.error(400,'BAD REQUEST','Invalid Query:'+e) + + def error(self,code="400", title="BAD REQUEST", message="UNKNOWN", form_errors={}): + request, response = self.request, self.response + r = OrderedDict({ + "version" : self.VERSION, + "href" : URL(args=request.args,vars=request.vars), + "error" : { + "title" : title, + "code" : code, + "message" : message}}) + if self.extensions and form_errors: + # https://github.com/collection-json/extensions/blob/master/errors.md + r['errors'] = errors = {} + for key, value in form_errors.items(): + errors[key] = {'title':'Validation Error','code':'','message':value} + response.headers['Content-Type'] = 'application/vnd.collection+json' + response.status = 400 + return response.json({'collection':r}) + +example_policies = { + 'thing': { + 'GET':{'query':None,'fields':['id', 'name']}, + 'POST':{'query':None,'fields':['name']}, + 'PUT':{'query':None,'fields':['name']}, + 'DELETE':{'query':None}, + }, + 'attr': { + 'GET':{'query':None,'fields':['id', 'name', 'thing']}, + 'POST':{'query':None,'fields':['name', 'thing']}, + 'PUT':{'query':None,'fields':['name', 'thing']}, + 'DELETE':{'query':None}, + }, + } diff --git a/web2py/gluon/contrib/imageutils.py b/web2py/gluon/contrib/imageutils.py new file mode 100644 index 0000000..a5c24b6 --- /dev/null +++ b/web2py/gluon/contrib/imageutils.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- + +####################################################################### +# +# Put this file in yourapp/modules/images.py +# +# Given the model +# +# db.define_table("table_name", Field("picture", "upload"), +# Field("thumbnail", "upload")) +# +# to resize the picture on upload +# +# from images import RESIZE +# +# db.table_name.picture.requires = RESIZE(200, 200) +# +# to store original image in picture and create a thumbnail +# in 'thumbnail' field +# +# from images import THUMB +# db.table_name.thumbnail.compute = lambda row: THUMB(row.picture, 200, 200) + +######################################################################### +from gluon import current + + +class RESIZE(object): + + def __init__(self, nx=160, ny=80, quality=100, padding = False, + error_message=' image resize'): + (self.nx, self.ny, self.quality, self.error_message, self.padding) = ( + nx, ny, quality, error_message, padding) + + def __call__(self, value): + if isinstance(value, str) and len(value) == 0: + return (value, None) + from PIL import Image + from io import BytesIO + try: + img = Image.open(value.file) + img.thumbnail((self.nx, self.ny), Image.ANTIALIAS) + s = BytesIO() + if self.padding: + background = Image.new('RGBA', (self.nx, self.ny), (255, 255, 255, 0)) + background.paste( + img, + ((self.nx - img.size[0]) // 2, (self.ny - img.size[1]) // 2)) + background.save(s, 'JPEG', quality=self.quality) + else: + img.save(s, 'JPEG', quality=self.quality) + s.seek(0) + value.file = s + except: + return (value, self.error_message) + else: + return (value, None) + + +def THUMB(image, nx=120, ny=120, gae=False, name='thumb'): + if image: + if not gae: + request = current.request + from PIL import Image + import os + img = Image.open(os.path.join(request.folder, 'uploads', image)) + img.thumbnail((nx, ny), Image.ANTIALIAS) + root, ext = os.path.splitext(image) + thumb = '%s_%s%s' % (root, name, ext) + img.save(request.folder + 'uploads/' + thumb) + return thumb + else: + return image diff --git a/web2py/gluon/contrib/ipaddress.py b/web2py/gluon/contrib/ipaddress.py new file mode 100644 index 0000000..9cf71a7 --- /dev/null +++ b/web2py/gluon/contrib/ipaddress.py @@ -0,0 +1,2425 @@ +# Copyright 2007 Google Inc. +# Licensed to PSF under a Contributor Agreement. + +"""A fast, lightweight IPv4/IPv6 manipulation library in Python. + +This library is used to create/poke/manipulate IPv4 and IPv6 addresses +and networks. + +""" + +from __future__ import unicode_literals + + +import itertools +import struct + +__version__ = '1.0.17' + +# Compatibility functions +_compat_int_types = (int,) +try: + _compat_int_types = (int, long) +except NameError: + pass +try: + _compat_str = unicode +except NameError: + _compat_str = str + assert bytes != str +if b'\0'[0] == 0: # Python 3 semantics + def _compat_bytes_to_byte_vals(byt): + return byt +else: + def _compat_bytes_to_byte_vals(byt): + return [struct.unpack(b'!B', b)[0] for b in byt] +try: + _compat_int_from_byte_vals = int.from_bytes +except AttributeError: + def _compat_int_from_byte_vals(bytvals, endianess): + assert endianess == 'big' + res = 0 + for bv in bytvals: + assert isinstance(bv, _compat_int_types) + res = (res << 8) + bv + return res + + +def _compat_to_bytes(intval, length, endianess): + assert isinstance(intval, _compat_int_types) + assert endianess == 'big' + if length == 4: + if intval < 0 or intval >= 2 ** 32: + raise struct.error("integer out of range for 'I' format code") + return struct.pack(b'!I', intval) + elif length == 16: + if intval < 0 or intval >= 2 ** 128: + raise struct.error("integer out of range for 'QQ' format code") + return struct.pack(b'!QQ', intval >> 64, intval & 0xffffffffffffffff) + else: + raise NotImplementedError() +if hasattr(int, 'bit_length'): + # Not int.bit_length , since that won't work in 2.7 where long exists + def _compat_bit_length(i): + return i.bit_length() +else: + def _compat_bit_length(i): + for res in itertools.count(): + if i >> res == 0: + return res + + +def _compat_range(start, end, step=1): + assert step > 0 + i = start + while i < end: + yield i + i += step + + +class _TotalOrderingMixin(object): + __slots__ = () + + # Helper that derives the other comparison operations from + # __lt__ and __eq__ + # We avoid functools.total_ordering because it doesn't handle + # NotImplemented correctly yet (http://bugs.python.org/issue10042) + def __eq__(self, other): + raise NotImplementedError + + def __ne__(self, other): + equal = self.__eq__(other) + if equal is NotImplemented: + return NotImplemented + return not equal + + def __lt__(self, other): + raise NotImplementedError + + def __le__(self, other): + less = self.__lt__(other) + if less is NotImplemented or not less: + return self.__eq__(other) + return less + + def __gt__(self, other): + less = self.__lt__(other) + if less is NotImplemented: + return NotImplemented + equal = self.__eq__(other) + if equal is NotImplemented: + return NotImplemented + return not (less or equal) + + def __ge__(self, other): + less = self.__lt__(other) + if less is NotImplemented: + return NotImplemented + return not less + + +IPV4LENGTH = 32 +IPV6LENGTH = 128 + + +class AddressValueError(ValueError): + """A Value Error related to the address.""" + + +class NetmaskValueError(ValueError): + """A Value Error related to the netmask.""" + + +def ip_address(address): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Address or IPv6Address object. + + Raises: + ValueError: if the *address* passed isn't either a v4 or a v6 + address + + """ + try: + return IPv4Address(address) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Address(address) + except (AddressValueError, NetmaskValueError): + pass + + if isinstance(address, bytes): + raise AddressValueError( + '%r does not appear to be an IPv4 or IPv6 address. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?' % address) + + raise ValueError('%r does not appear to be an IPv4 or IPv6 address' % + address) + + +def ip_network(address, strict=True): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP network. Either IPv4 or + IPv6 networks may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Network or IPv6Network object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. Or if the network has host bits set. + + """ + try: + return IPv4Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + if isinstance(address, bytes): + raise AddressValueError( + '%r does not appear to be an IPv4 or IPv6 network. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?' % address) + + raise ValueError('%r does not appear to be an IPv4 or IPv6 network' % + address) + + +def ip_interface(address): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Interface or IPv6Interface object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. + + Notes: + The IPv?Interface classes describe an Address on a particular + Network, so they're basically a combination of both the Address + and Network classes. + + """ + try: + return IPv4Interface(address) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Interface(address) + except (AddressValueError, NetmaskValueError): + pass + + raise ValueError('%r does not appear to be an IPv4 or IPv6 interface' % + address) + + +def v4_int_to_packed(address): + """Represent an address as 4 packed bytes in network (big-endian) order. + + Args: + address: An integer representation of an IPv4 IP address. + + Returns: + The integer address packed as 4 bytes in network (big-endian) order. + + Raises: + ValueError: If the integer is negative or too large to be an + IPv4 IP address. + + """ + try: + return _compat_to_bytes(address, 4, 'big') + except (struct.error, OverflowError): + raise ValueError("Address negative or too large for IPv4") + + +def v6_int_to_packed(address): + """Represent an address as 16 packed bytes in network (big-endian) order. + + Args: + address: An integer representation of an IPv6 IP address. + + Returns: + The integer address packed as 16 bytes in network (big-endian) order. + + """ + try: + return _compat_to_bytes(address, 16, 'big') + except (struct.error, OverflowError): + raise ValueError("Address negative or too large for IPv6") + + +def _split_optional_netmask(address): + """Helper to split the netmask and raise AddressValueError if needed""" + addr = _compat_str(address).split('/') + if len(addr) > 2: + raise AddressValueError("Only one '/' permitted in %r" % address) + return addr + + +def _find_address_range(addresses): + """Find a sequence of sorted deduplicated IPv#Address. + + Args: + addresses: a list of IPv#Address objects. + + Yields: + A tuple containing the first and last IP addresses in the sequence. + + """ + it = iter(addresses) + first = last = next(it) + for ip in it: + if ip._ip != last._ip + 1: + yield first, last + first = ip + last = ip + yield first, last + + +def _count_righthand_zero_bits(number, bits): + """Count the number of zero bits on the right hand side. + + Args: + number: an integer. + bits: maximum number of bits to count. + + Returns: + The number of zero bits on the right hand side of the number. + + """ + if number == 0: + return bits + return min(bits, _compat_bit_length(~number & (number - 1))) + + +def summarize_address_range(first, last): + """Summarize a network range given the first and last IP addresses. + + Example: + >>> list(summarize_address_range(IPv4Address('192.0.2.0'), + ... IPv4Address('192.0.2.130'))) + ... #doctest: +NORMALIZE_WHITESPACE + [IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/31'), + IPv4Network('192.0.2.130/32')] + + Args: + first: the first IPv4Address or IPv6Address in the range. + last: the last IPv4Address or IPv6Address in the range. + + Returns: + An iterator of the summarized IPv(4|6) network objects. + + Raise: + TypeError: + If the first and last objects are not IP addresses. + If the first and last objects are not the same version. + ValueError: + If the last object is not greater than the first. + If the version of the first address is not 4 or 6. + + """ + if (not (isinstance(first, _BaseAddress) and + isinstance(last, _BaseAddress))): + raise TypeError('first and last must be IP addresses, not networks') + if first.version != last.version: + raise TypeError("%s and %s are not of the same version" % ( + first, last)) + if first > last: + raise ValueError('last IP address must be greater than first') + + if first.version == 4: + ip = IPv4Network + elif first.version == 6: + ip = IPv6Network + else: + raise ValueError('unknown IP version') + + ip_bits = first._max_prefixlen + first_int = first._ip + last_int = last._ip + while first_int <= last_int: + nbits = min(_count_righthand_zero_bits(first_int, ip_bits), + _compat_bit_length(last_int - first_int + 1) - 1) + net = ip((first_int, ip_bits - nbits)) + yield net + first_int += 1 << nbits + if first_int - 1 == ip._ALL_ONES: + break + + +def _collapse_addresses_internal(addresses): + """Loops through the addresses, collapsing concurrent netblocks. + + Example: + + ip1 = IPv4Network('192.0.2.0/26') + ip2 = IPv4Network('192.0.2.64/26') + ip3 = IPv4Network('192.0.2.128/26') + ip4 = IPv4Network('192.0.2.192/26') + + _collapse_addresses_internal([ip1, ip2, ip3, ip4]) -> + [IPv4Network('192.0.2.0/24')] + + This shouldn't be called directly; it is called via + collapse_addresses([]). + + Args: + addresses: A list of IPv4Network's or IPv6Network's + + Returns: + A list of IPv4Network's or IPv6Network's depending on what we were + passed. + + """ + # First merge + to_merge = list(addresses) + subnets = {} + while to_merge: + net = to_merge.pop() + supernet = net.supernet() + existing = subnets.get(supernet) + if existing is None: + subnets[supernet] = net + elif existing != net: + # Merge consecutive subnets + del subnets[supernet] + to_merge.append(supernet) + # Then iterate over resulting networks, skipping subsumed subnets + last = None + for net in sorted(subnets.values()): + if last is not None: + # Since they are sorted, + # last.network_address <= net.network_address is a given. + if last.broadcast_address >= net.broadcast_address: + continue + yield net + last = net + + +def collapse_addresses(addresses): + """Collapse a list of IP objects. + + Example: + collapse_addresses([IPv4Network('192.0.2.0/25'), + IPv4Network('192.0.2.128/25')]) -> + [IPv4Network('192.0.2.0/24')] + + Args: + addresses: An iterator of IPv4Network or IPv6Network objects. + + Returns: + An iterator of the collapsed IPv(4|6)Network objects. + + Raises: + TypeError: If passed a list of mixed version objects. + + """ + addrs = [] + ips = [] + nets = [] + + # split IP addresses and networks + for ip in addresses: + if isinstance(ip, _BaseAddress): + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, ips[-1])) + ips.append(ip) + elif ip._prefixlen == ip._max_prefixlen: + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, ips[-1])) + try: + ips.append(ip.ip) + except AttributeError: + ips.append(ip.network_address) + else: + if nets and nets[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, nets[-1])) + nets.append(ip) + + # sort and dedup + ips = sorted(set(ips)) + + # find consecutive address ranges in the sorted sequence and summarize them + if ips: + for first, last in _find_address_range(ips): + addrs.extend(summarize_address_range(first, last)) + + return _collapse_addresses_internal(addrs + nets) + + +def get_mixed_type_key(obj): + """Return a key suitable for sorting between networks and addresses. + + Address and Network objects are not sortable by default; they're + fundamentally different so the expression + + IPv4Address('192.0.2.0') <= IPv4Network('192.0.2.0/24') + + doesn't make any sense. There are some times however, where you may wish + to have ipaddress sort these for you anyway. If you need to do this, you + can use this function as the key= argument to sorted(). + + Args: + obj: either a Network or Address object. + Returns: + appropriate key. + + """ + if isinstance(obj, _BaseNetwork): + return obj._get_networks_key() + elif isinstance(obj, _BaseAddress): + return obj._get_address_key() + return NotImplemented + + +class _IPAddressBase(_TotalOrderingMixin): + + """The mother class.""" + + __slots__ = () + + @property + def exploded(self): + """Return the longhand version of the IP address as a string.""" + return self._explode_shorthand_ip_string() + + @property + def compressed(self): + """Return the shorthand version of the IP address as a string.""" + return _compat_str(self) + + @property + def reverse_pointer(self): + """The name of the reverse DNS pointer for the IP address, e.g.: + >>> ipaddress.ip_address("127.0.0.1").reverse_pointer + '1.0.0.127.in-addr.arpa' + >>> ipaddress.ip_address("2001:db8::1").reverse_pointer + '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa' + + """ + return self._reverse_pointer() + + @property + def version(self): + msg = '%200s has no version specified' % (type(self),) + raise NotImplementedError(msg) + + def _check_int_address(self, address): + if address < 0: + msg = "%d (< 0) is not permitted as an IPv%d address" + raise AddressValueError(msg % (address, self._version)) + if address > self._ALL_ONES: + msg = "%d (>= 2**%d) is not permitted as an IPv%d address" + raise AddressValueError(msg % (address, self._max_prefixlen, + self._version)) + + def _check_packed_address(self, address, expected_len): + address_len = len(address) + if address_len != expected_len: + msg = ( + '%r (len %d != %d) is not permitted as an IPv%d address. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?' + ) + raise AddressValueError(msg % (address, address_len, + expected_len, self._version)) + + @classmethod + def _ip_int_from_prefix(cls, prefixlen): + """Turn the prefix length into a bitwise netmask + + Args: + prefixlen: An integer, the prefix length. + + Returns: + An integer. + + """ + return cls._ALL_ONES ^ (cls._ALL_ONES >> prefixlen) + + @classmethod + def _prefix_from_ip_int(cls, ip_int): + """Return prefix length from the bitwise netmask. + + Args: + ip_int: An integer, the netmask in expanded bitwise format + + Returns: + An integer, the prefix length. + + Raises: + ValueError: If the input intermingles zeroes & ones + """ + trailing_zeroes = _count_righthand_zero_bits(ip_int, + cls._max_prefixlen) + prefixlen = cls._max_prefixlen - trailing_zeroes + leading_ones = ip_int >> trailing_zeroes + all_ones = (1 << prefixlen) - 1 + if leading_ones != all_ones: + byteslen = cls._max_prefixlen // 8 + details = _compat_to_bytes(ip_int, byteslen, 'big') + msg = 'Netmask pattern %r mixes zeroes & ones' + raise ValueError(msg % details) + return prefixlen + + @classmethod + def _report_invalid_netmask(cls, netmask_str): + msg = '%r is not a valid netmask' % netmask_str + raise NetmaskValueError(msg) + + @classmethod + def _prefix_from_prefix_string(cls, prefixlen_str): + """Return prefix length from a numeric string + + Args: + prefixlen_str: The string to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask + """ + # int allows a leading +/- as well as surrounding whitespace, + # so we ensure that isn't the case + if not _BaseV4._DECIMAL_DIGITS.issuperset(prefixlen_str): + cls._report_invalid_netmask(prefixlen_str) + try: + prefixlen = int(prefixlen_str) + except ValueError: + cls._report_invalid_netmask(prefixlen_str) + if not (0 <= prefixlen <= cls._max_prefixlen): + cls._report_invalid_netmask(prefixlen_str) + return prefixlen + + @classmethod + def _prefix_from_ip_string(cls, ip_str): + """Turn a netmask/hostmask string into a prefix length + + Args: + ip_str: The netmask/hostmask to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask/hostmask + """ + # Parse the netmask/hostmask like an IP address. + try: + ip_int = cls._ip_int_from_string(ip_str) + except AddressValueError: + cls._report_invalid_netmask(ip_str) + + # Try matching a netmask (this would be /1*0*/ as a bitwise regexp). + # Note that the two ambiguous cases (all-ones and all-zeroes) are + # treated as netmasks. + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + pass + + # Invert the bits, and try matching a /0+1+/ hostmask instead. + ip_int ^= cls._ALL_ONES + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + cls._report_invalid_netmask(ip_str) + + def __reduce__(self): + return self.__class__, (_compat_str(self),) + + +class _BaseAddress(_IPAddressBase): + + """A generic IP object. + + This IP class contains the version independent methods which are + used by single IP addresses. + """ + + __slots__ = () + + def __int__(self): + return self._ip + + def __eq__(self, other): + try: + return (self._ip == other._ip and + self._version == other._version) + except AttributeError: + return NotImplemented + + def __lt__(self, other): + if not isinstance(other, _IPAddressBase): + return NotImplemented + if not isinstance(other, _BaseAddress): + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + self, other)) + if self._ip != other._ip: + return self._ip < other._ip + return False + + # Shorthand for Integer addition and subtraction. This is not + # meant to ever support addition/subtraction of addresses. + def __add__(self, other): + if not isinstance(other, _compat_int_types): + return NotImplemented + return self.__class__(int(self) + other) + + def __sub__(self, other): + if not isinstance(other, _compat_int_types): + return NotImplemented + return self.__class__(int(self) - other) + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) + + def __str__(self): + return _compat_str(self._string_from_ip_int(self._ip)) + + def __hash__(self): + return hash(hex(int(self._ip))) + + def _get_address_key(self): + return (self._version, self) + + def __reduce__(self): + return self.__class__, (self._ip,) + + +class _BaseNetwork(_IPAddressBase): + + """A generic IP network object. + + This IP class contains the version independent methods which are + used by networks. + + """ + def __init__(self, address): + self._cache = {} + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) + + def __str__(self): + return '%s/%d' % (self.network_address, self.prefixlen) + + def hosts(self): + """Generate Iterator over usable hosts in a network. + + This is like __iter__ except it doesn't return the network + or broadcast addresses. + + """ + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network + 1, broadcast): + yield self._address_class(x) + + def __iter__(self): + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network, broadcast + 1): + yield self._address_class(x) + + def __getitem__(self, n): + network = int(self.network_address) + broadcast = int(self.broadcast_address) + if n >= 0: + if network + n > broadcast: + raise IndexError('address out of range') + return self._address_class(network + n) + else: + n += 1 + if broadcast + n < network: + raise IndexError('address out of range') + return self._address_class(broadcast + n) + + def __lt__(self, other): + if not isinstance(other, _IPAddressBase): + return NotImplemented + if not isinstance(other, _BaseNetwork): + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + self, other)) + if self.network_address != other.network_address: + return self.network_address < other.network_address + if self.netmask != other.netmask: + return self.netmask < other.netmask + return False + + def __eq__(self, other): + try: + return (self._version == other._version and + self.network_address == other.network_address and + int(self.netmask) == int(other.netmask)) + except AttributeError: + return NotImplemented + + def __hash__(self): + return hash(int(self.network_address) ^ int(self.netmask)) + + def __contains__(self, other): + # always false if one is v4 and the other is v6. + if self._version != other._version: + return False + # dealing with another network. + if isinstance(other, _BaseNetwork): + return False + # dealing with another address + else: + # address + return (int(self.network_address) <= int(other._ip) <= + int(self.broadcast_address)) + + def overlaps(self, other): + """Tell if self is partly contained in other.""" + return self.network_address in other or ( + self.broadcast_address in other or ( + other.network_address in self or ( + other.broadcast_address in self))) + + @property + def broadcast_address(self): + x = self._cache.get('broadcast_address') + if x is None: + x = self._address_class(int(self.network_address) | + int(self.hostmask)) + self._cache['broadcast_address'] = x + return x + + @property + def hostmask(self): + x = self._cache.get('hostmask') + if x is None: + x = self._address_class(int(self.netmask) ^ self._ALL_ONES) + self._cache['hostmask'] = x + return x + + @property + def with_prefixlen(self): + return '%s/%d' % (self.network_address, self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self.network_address, self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self.network_address, self.hostmask) + + @property + def num_addresses(self): + """Number of hosts in the current subnet.""" + return int(self.broadcast_address) - int(self.network_address) + 1 + + @property + def _address_class(self): + # Returning bare address objects (rather than interfaces) allows for + # more consistent behaviour across the network address, broadcast + # address and individual host addresses. + msg = '%200s has no associated address class' % (type(self),) + raise NotImplementedError(msg) + + @property + def prefixlen(self): + return self._prefixlen + + def address_exclude(self, other): + """Remove an address from a larger block. + + For example: + + addr1 = ip_network('192.0.2.0/28') + addr2 = ip_network('192.0.2.1/32') + list(addr1.address_exclude(addr2)) = + [IPv4Network('192.0.2.0/32'), IPv4Network('192.0.2.2/31'), + IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')] + + or IPv6: + + addr1 = ip_network('2001:db8::1/32') + addr2 = ip_network('2001:db8::1/128') + list(addr1.address_exclude(addr2)) = + [ip_network('2001:db8::1/128'), + ip_network('2001:db8::2/127'), + ip_network('2001:db8::4/126'), + ip_network('2001:db8::8/125'), + ... + ip_network('2001:db8:8000::/33')] + + Args: + other: An IPv4Network or IPv6Network object of the same type. + + Returns: + An iterator of the IPv(4|6)Network objects which is self + minus other. + + Raises: + TypeError: If self and other are of differing address + versions, or if other is not a network object. + ValueError: If other is not completely contained by self. + + """ + if not self._version == other._version: + raise TypeError("%s and %s are not of the same version" % ( + self, other)) + + if not isinstance(other, _BaseNetwork): + raise TypeError("%s is not a network object" % other) + + if not other.subnet_of(self): + raise ValueError('%s not contained in %s' % (other, self)) + if other == self: + return + + # Make sure we're comparing the network of other. + other = other.__class__('%s/%s' % (other.network_address, + other.prefixlen)) + + s1, s2 = self.subnets() + while s1 != other and s2 != other: + if other.subnet_of(s1): + yield s2 + s1, s2 = s1.subnets() + elif other.subnet_of(s2): + yield s1 + s1, s2 = s2.subnets() + else: + # If we got here, there's a bug somewhere. + raise AssertionError('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (s1, s2, other)) + if s1 == other: + yield s2 + elif s2 == other: + yield s1 + else: + # If we got here, there's a bug somewhere. + raise AssertionError('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (s1, s2, other)) + + def compare_networks(self, other): + """Compare two IP objects. + + This is only concerned about the comparison of the integer + representation of the network addresses. This means that the + host bits aren't considered at all in this method. If you want + to compare host bits, you can easily enough do a + 'HostA._ip < HostB._ip' + + Args: + other: An IP object. + + Returns: + If the IP versions of self and other are the same, returns: + + -1 if self < other: + eg: IPv4Network('192.0.2.0/25') < IPv4Network('192.0.2.128/25') + IPv6Network('2001:db8::1000/124') < + IPv6Network('2001:db8::2000/124') + 0 if self == other + eg: IPv4Network('192.0.2.0/24') == IPv4Network('192.0.2.0/24') + IPv6Network('2001:db8::1000/124') == + IPv6Network('2001:db8::1000/124') + 1 if self > other + eg: IPv4Network('192.0.2.128/25') > IPv4Network('192.0.2.0/25') + IPv6Network('2001:db8::2000/124') > + IPv6Network('2001:db8::1000/124') + + Raises: + TypeError if the IP versions are different. + + """ + # does this need to raise a ValueError? + if self._version != other._version: + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + # self._version == other._version below here: + if self.network_address < other.network_address: + return -1 + if self.network_address > other.network_address: + return 1 + # self.network_address == other.network_address below here: + if self.netmask < other.netmask: + return -1 + if self.netmask > other.netmask: + return 1 + return 0 + + def _get_networks_key(self): + """Network-only key function. + + Returns an object that identifies this address' network and + netmask. This function is a suitable "key" argument for sorted() + and list.sort(). + + """ + return (self._version, self.network_address, self.netmask) + + def subnets(self, prefixlen_diff=1, new_prefix=None): + """The subnets which join to make the current subnet. + + In the case that self contains only one IP + (self._prefixlen == 32 for IPv4 or self._prefixlen == 128 + for IPv6), yield an iterator with just ourself. + + Args: + prefixlen_diff: An integer, the amount the prefix length + should be increased by. This should not be set if + new_prefix is also set. + new_prefix: The desired new prefix length. This must be a + larger number (smaller prefix) than the existing prefix. + This should not be set if prefixlen_diff is also set. + + Returns: + An iterator of IPv(4|6) objects. + + Raises: + ValueError: The prefixlen_diff is too small or too large. + OR + prefixlen_diff and new_prefix are both set or new_prefix + is a smaller number than the current prefix (smaller + number means a larger network) + + """ + if self._prefixlen == self._max_prefixlen: + yield self + return + + if new_prefix is not None: + if new_prefix < self._prefixlen: + raise ValueError('new prefix must be longer') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = new_prefix - self._prefixlen + + if prefixlen_diff < 0: + raise ValueError('prefix length diff must be > 0') + new_prefixlen = self._prefixlen + prefixlen_diff + + if new_prefixlen > self._max_prefixlen: + raise ValueError( + 'prefix length diff %d is invalid for netblock %s' % ( + new_prefixlen, self)) + + start = int(self.network_address) + end = int(self.broadcast_address) + 1 + step = (int(self.hostmask) + 1) >> prefixlen_diff + for new_addr in _compat_range(start, end, step): + current = self.__class__((new_addr, new_prefixlen)) + yield current + + def supernet(self, prefixlen_diff=1, new_prefix=None): + """The supernet containing the current network. + + Args: + prefixlen_diff: An integer, the amount the prefix length of + the network should be decreased by. For example, given a + /24 network and a prefixlen_diff of 3, a supernet with a + /21 netmask is returned. + + Returns: + An IPv4 network object. + + Raises: + ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have + a negative prefix length. + OR + If prefixlen_diff and new_prefix are both set or new_prefix is a + larger number than the current prefix (larger number means a + smaller network) + + """ + if self._prefixlen == 0: + return self + + if new_prefix is not None: + if new_prefix > self._prefixlen: + raise ValueError('new prefix must be shorter') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = self._prefixlen - new_prefix + + new_prefixlen = self.prefixlen - prefixlen_diff + if new_prefixlen < 0: + raise ValueError( + 'current prefixlen is %d, cannot have a prefixlen_diff of %d' % + (self.prefixlen, prefixlen_diff)) + return self.__class__(( + int(self.network_address) & (int(self.netmask) << prefixlen_diff), + new_prefixlen + )) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is a multicast address. + See RFC 2373 2.7 for details. + + """ + return (self.network_address.is_multicast and + self.broadcast_address.is_multicast) + + def subnet_of(self, other): + # always false if one is v4 and the other is v6. + if self._version != other._version: + return False + # dealing with another network. + if (hasattr(other, 'network_address') and + hasattr(other, 'broadcast_address')): + return (other.network_address <= self.network_address and + other.broadcast_address >= self.broadcast_address) + # dealing with another address + else: + raise TypeError('Unable to test subnet containment with element ' + 'of type %s' % type(other)) + + def supernet_of(self, other): + # always false if one is v4 and the other is v6. + if self._version != other._version: + return False + # dealing with another network. + if (hasattr(other, 'network_address') and + hasattr(other, 'broadcast_address')): + return (other.network_address >= self.network_address and + other.broadcast_address <= self.broadcast_address) + # dealing with another address + else: + raise TypeError('Unable to test subnet containment with element ' + 'of type %s' % type(other)) + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within one of the + reserved IPv6 Network ranges. + + """ + return (self.network_address.is_reserved and + self.broadcast_address.is_reserved) + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is reserved per RFC 4291. + + """ + return (self.network_address.is_link_local and + self.broadcast_address.is_link_local) + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv4-special-registry or iana-ipv6-special-registry. + + """ + return (self.network_address.is_private and + self.broadcast_address.is_private) + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, True if the address is not reserved per + iana-ipv4-special-registry or iana-ipv6-special-registry. + + """ + return not self.is_private + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 2373 2.5.2. + + """ + return (self.network_address.is_unspecified and + self.broadcast_address.is_unspecified) + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback address as defined in + RFC 2373 2.5.3. + + """ + return (self.network_address.is_loopback and + self.broadcast_address.is_loopback) + + +class _BaseV4(object): + + """Base IPv4 object. + + The following methods are used by IPv4 objects in both single IP + addresses and networks. + + """ + + __slots__ = () + _version = 4 + # Equivalent to 255.255.255.255 or 32 bits of 1's. + _ALL_ONES = (2 ** IPV4LENGTH) - 1 + _DECIMAL_DIGITS = frozenset('0123456789') + + # the valid octets for host and netmasks. only useful for IPv4. + _valid_mask_octets = frozenset([255, 254, 252, 248, 240, 224, 192, 128, 0]) + + _max_prefixlen = IPV4LENGTH + # There are only a handful of valid v4 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} + + def _explode_shorthand_ip_string(self): + return _compat_str(self) + + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, _compat_int_types): + prefixlen = arg + else: + try: + # Check for a netmask in prefix length form + prefixlen = cls._prefix_from_prefix_string(arg) + except NetmaskValueError: + # Check for a netmask or hostmask in dotted-quad form. + # This may raise NetmaskValueError. + prefixlen = cls._prefix_from_ip_string(arg) + netmask = IPv4Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): + """Turn the given IP string into an integer for comparison. + + Args: + ip_str: A string, the IP ip_str. + + Returns: + The IP ip_str as an integer. + + Raises: + AddressValueError: if ip_str isn't a valid IPv4 Address. + + """ + if not ip_str: + raise AddressValueError('Address cannot be empty') + + octets = ip_str.split('.') + if len(octets) != 4: + raise AddressValueError("Expected 4 octets in %r" % ip_str) + + try: + return _compat_int_from_byte_vals( + map(cls._parse_octet, octets), 'big') + except ValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + + @classmethod + def _parse_octet(cls, octet_str): + """Convert a decimal octet into an integer. + + Args: + octet_str: A string, the number to parse. + + Returns: + The octet as an integer. + + Raises: + ValueError: if the octet isn't strictly a decimal from [0..255]. + + """ + if not octet_str: + raise ValueError("Empty octet not permitted") + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not cls._DECIMAL_DIGITS.issuperset(octet_str): + msg = "Only decimal digits permitted in %r" + raise ValueError(msg % octet_str) + # We do the length check second, since the invalid character error + # is likely to be more informative for the user + if len(octet_str) > 3: + msg = "At most 3 characters permitted in %r" + raise ValueError(msg % octet_str) + # Convert to integer (we know digits are legal) + octet_int = int(octet_str, 10) + # Any octets that look like they *might* be written in octal, + # and which don't look exactly the same in both octal and + # decimal are rejected as ambiguous + if octet_int > 7 and octet_str[0] == '0': + msg = "Ambiguous (octal/decimal) value in %r not permitted" + raise ValueError(msg % octet_str) + if octet_int > 255: + raise ValueError("Octet %d (> 255) not permitted" % octet_int) + return octet_int + + @classmethod + def _string_from_ip_int(cls, ip_int): + """Turns a 32-bit integer into dotted decimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + The IP address as a string in dotted decimal notation. + + """ + return '.'.join(_compat_str(struct.unpack(b'!B', b)[0] + if isinstance(b, bytes) + else b) + for b in _compat_to_bytes(ip_int, 4, 'big')) + + def _is_hostmask(self, ip_str): + """Test if the IP string is a hostmask (rather than a netmask). + + Args: + ip_str: A string, the potential hostmask. + + Returns: + A boolean, True if the IP string is a hostmask. + + """ + bits = ip_str.split('.') + try: + parts = [x for x in map(int, bits) if x in self._valid_mask_octets] + except ValueError: + return False + if len(parts) != len(bits): + return False + if parts[0] < parts[-1]: + return True + return False + + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv4 address. + + This implements the method described in RFC1035 3.5. + + """ + reverse_octets = _compat_str(self).split('.')[::-1] + return '.'.join(reverse_octets) + '.in-addr.arpa' + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def version(self): + return self._version + + +class IPv4Address(_BaseV4, _BaseAddress): + + """Represent and manipulate single IPv4 Addresses.""" + + __slots__ = ('_ip', '__weakref__') + + def __init__(self, address): + + """ + Args: + address: A string or integer representing the IP + + Additionally, an integer can be passed, so + IPv4Address('192.0.2.1') == IPv4Address(3221225985). + or, more generally + IPv4Address(int(IPv4Address('192.0.2.1'))) == + IPv4Address('192.0.2.1') + + Raises: + AddressValueError: If ipaddress isn't a valid IPv4 address. + + """ + # Efficient constructor from integer. + if isinstance(address, _compat_int_types): + self._check_int_address(address) + self._ip = address + return + + # Constructing from a packed address + if isinstance(address, bytes): + self._check_packed_address(address, 4) + bvs = _compat_bytes_to_byte_vals(address) + self._ip = _compat_int_from_byte_vals(bvs, 'big') + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = _compat_str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) + self._ip = self._ip_int_from_string(addr_str) + + @property + def packed(self): + """The binary representation of this address.""" + return v4_int_to_packed(self._ip) + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within the + reserved IPv4 Network range. + + """ + return self in self._constants._reserved_network + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv4-special-registry. + + """ + return any(self in net for net in self._constants._private_networks) + + @property + def is_global(self): + return ( + self not in self._constants._public_network and + not self.is_private) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is multicast. + See RFC 3171 for details. + + """ + return self in self._constants._multicast_network + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 5735 3. + + """ + return self == self._constants._unspecified_address + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback per RFC 3330. + + """ + return self in self._constants._loopback_network + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is link-local per RFC 3927. + + """ + return self in self._constants._linklocal_network + + +class IPv4Interface(IPv4Address): + + def __init__(self, address): + if isinstance(address, (bytes, _compat_int_types)): + IPv4Address.__init__(self, address) + self.network = IPv4Network(self._ip) + self._prefixlen = self._max_prefixlen + return + + if isinstance(address, tuple): + IPv4Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + + self.network = IPv4Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + + addr = _split_optional_netmask(address) + IPv4Address.__init__(self, addr[0]) + + self.network = IPv4Network(address, strict=False) + self._prefixlen = self.network._prefixlen + + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + + def __str__(self): + return '%s/%d' % (self._string_from_ip_int(self._ip), + self.network.prefixlen) + + def __eq__(self, other): + address_equal = IPv4Address.__eq__(self, other) + if not address_equal or address_equal is NotImplemented: + return address_equal + try: + return self.network == other.network + except AttributeError: + # An interface with an associated network is NOT the + # same as an unassociated address. That's why the hash + # takes the extra info into account. + return False + + def __lt__(self, other): + address_less = IPv4Address.__lt__(self, other) + if address_less is NotImplemented: + return NotImplemented + try: + return self.network < other.network + except AttributeError: + # We *do* allow addresses and interfaces to be sorted. The + # unassociated address is considered less than all interfaces. + return False + + def __hash__(self): + return self._ip ^ self._prefixlen ^ int(self.network.network_address) + + __reduce__ = _IPAddressBase.__reduce__ + + @property + def ip(self): + return IPv4Address(self._ip) + + @property + def with_prefixlen(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.hostmask) + + +class IPv4Network(_BaseV4, _BaseNetwork): + + """This class represents and manipulates 32-bit IPv4 network + addresses.. + + Attributes: [examples for IPv4Network('192.0.2.0/27')] + .network_address: IPv4Address('192.0.2.0') + .hostmask: IPv4Address('0.0.0.31') + .broadcast_address: IPv4Address('192.0.2.32') + .netmask: IPv4Address('255.255.255.224') + .prefixlen: 27 + + """ + # Class to use when creating address objects + _address_class = IPv4Address + + def __init__(self, address, strict=True): + + """Instantiate a new IPv4 network object. + + Args: + address: A string or integer representing the IP [& network]. + '192.0.2.0/24' + '192.0.2.0/255.255.255.0' + '192.0.0.2/0.0.0.255' + are all functionally the same in IPv4. Similarly, + '192.0.2.1' + '192.0.2.1/255.255.255.255' + '192.0.2.1/32' + are also functionally equivalent. That is to say, failing to + provide a subnetmask will create an object with a mask of /32. + + If the mask (portion after the / in the argument) is given in + dotted quad form, it is treated as a netmask if it starts with a + non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it + starts with a zero field (e.g. 0.255.255.255 == /8), with the + single exception of an all-zero mask which is treated as a + netmask == /0. If no mask is given, a default of /32 is used. + + Additionally, an integer can be passed, so + IPv4Network('192.0.2.1') == IPv4Network(3221225985) + or, more generally + IPv4Interface(int(IPv4Interface('192.0.2.1'))) == + IPv4Interface('192.0.2.1') + + Raises: + AddressValueError: If ipaddress isn't a valid IPv4 address. + NetmaskValueError: If the netmask isn't valid for + an IPv4 address. + ValueError: If strict is True and a network address is not + supplied. + + """ + _BaseNetwork.__init__(self, address) + + # Constructing from a packed address or integer + if isinstance(address, (_compat_int_types, bytes)): + self.network_address = IPv4Address(address) + self.netmask, self._prefixlen = self._make_netmask( + self._max_prefixlen) + # fixme: address/network test here. + return + + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + # We weren't given an address[1] + arg = self._max_prefixlen + self.network_address = IPv4Address(address[0]) + self.netmask, self._prefixlen = self._make_netmask(arg) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv4Address(packed & + int(self.netmask)) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = _split_optional_netmask(address) + self.network_address = IPv4Address(self._ip_int_from_string(addr[0])) + + if len(addr) == 2: + arg = addr[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + + if strict: + if (IPv4Address(int(self.network_address) & int(self.netmask)) != + self.network_address): + raise ValueError('%s has host bits set' % self) + self.network_address = IPv4Address(int(self.network_address) & + int(self.netmask)) + + if self._prefixlen == (self._max_prefixlen - 1): + self.hosts = self.__iter__ + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, True if the address is not reserved per + iana-ipv4-special-registry. + + """ + return (not (self.network_address in IPv4Network('100.64.0.0/10') and + self.broadcast_address in IPv4Network('100.64.0.0/10')) and + not self.is_private) + + +class _IPv4Constants(object): + + _linklocal_network = IPv4Network('169.254.0.0/16') + + _loopback_network = IPv4Network('127.0.0.0/8') + + _multicast_network = IPv4Network('224.0.0.0/4') + + _public_network = IPv4Network('100.64.0.0/10') + + _private_networks = [ + IPv4Network('0.0.0.0/8'), + IPv4Network('10.0.0.0/8'), + IPv4Network('127.0.0.0/8'), + IPv4Network('169.254.0.0/16'), + IPv4Network('172.16.0.0/12'), + IPv4Network('192.0.0.0/29'), + IPv4Network('192.0.0.170/31'), + IPv4Network('192.0.2.0/24'), + IPv4Network('192.168.0.0/16'), + IPv4Network('198.18.0.0/15'), + IPv4Network('198.51.100.0/24'), + IPv4Network('203.0.113.0/24'), + IPv4Network('240.0.0.0/4'), + IPv4Network('255.255.255.255/32'), + ] + + _reserved_network = IPv4Network('240.0.0.0/4') + + _unspecified_address = IPv4Address('0.0.0.0') + + +IPv4Address._constants = _IPv4Constants + + +class _BaseV6(object): + + """Base IPv6 object. + + The following methods are used by IPv6 objects in both single IP + addresses and networks. + + """ + + __slots__ = () + _version = 6 + _ALL_ONES = (2 ** IPV6LENGTH) - 1 + _HEXTET_COUNT = 8 + _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef') + _max_prefixlen = IPV6LENGTH + + # There are only a bunch of valid v6 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} + + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, _compat_int_types): + prefixlen = arg + else: + prefixlen = cls._prefix_from_prefix_string(arg) + netmask = IPv6Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): + """Turn an IPv6 ip_str into an integer. + + Args: + ip_str: A string, the IPv6 ip_str. + + Returns: + An int, the IPv6 address + + Raises: + AddressValueError: if ip_str isn't a valid IPv6 Address. + + """ + if not ip_str: + raise AddressValueError('Address cannot be empty') + + parts = ip_str.split(':') + + # An IPv6 address needs at least 2 colons (3 parts). + _min_parts = 3 + if len(parts) < _min_parts: + msg = "At least %d parts expected in %r" % (_min_parts, ip_str) + raise AddressValueError(msg) + + # If the address has an IPv4-style suffix, convert it to hexadecimal. + if '.' in parts[-1]: + try: + ipv4_int = IPv4Address(parts.pop())._ip + except AddressValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF)) + parts.append('%x' % (ipv4_int & 0xFFFF)) + + # An IPv6 address can't have more than 8 colons (9 parts). + # The extra colon comes from using the "::" notation for a single + # leading or trailing zero part. + _max_parts = cls._HEXTET_COUNT + 1 + if len(parts) > _max_parts: + msg = "At most %d colons permitted in %r" % ( + _max_parts - 1, ip_str) + raise AddressValueError(msg) + + # Disregarding the endpoints, find '::' with nothing in between. + # This indicates that a run of zeroes has been skipped. + skip_index = None + for i in _compat_range(1, len(parts) - 1): + if not parts[i]: + if skip_index is not None: + # Can't have more than one '::' + msg = "At most one '::' permitted in %r" % ip_str + raise AddressValueError(msg) + skip_index = i + + # parts_hi is the number of parts to copy from above/before the '::' + # parts_lo is the number of parts to copy from below/after the '::' + if skip_index is not None: + # If we found a '::', then check if it also covers the endpoints. + parts_hi = skip_index + parts_lo = len(parts) - skip_index - 1 + if not parts[0]: + parts_hi -= 1 + if parts_hi: + msg = "Leading ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # ^: requires ^:: + if not parts[-1]: + parts_lo -= 1 + if parts_lo: + msg = "Trailing ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # :$ requires ::$ + parts_skipped = cls._HEXTET_COUNT - (parts_hi + parts_lo) + if parts_skipped < 1: + msg = "Expected at most %d other parts with '::' in %r" + raise AddressValueError(msg % (cls._HEXTET_COUNT - 1, ip_str)) + else: + # Otherwise, allocate the entire address to parts_hi. The + # endpoints could still be empty, but _parse_hextet() will check + # for that. + if len(parts) != cls._HEXTET_COUNT: + msg = "Exactly %d parts expected without '::' in %r" + raise AddressValueError(msg % (cls._HEXTET_COUNT, ip_str)) + if not parts[0]: + msg = "Leading ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # ^: requires ^:: + if not parts[-1]: + msg = "Trailing ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # :$ requires ::$ + parts_hi = len(parts) + parts_lo = 0 + parts_skipped = 0 + + try: + # Now, parse the hextets into a 128-bit integer. + ip_int = 0 + for i in range(parts_hi): + ip_int <<= 16 + ip_int |= cls._parse_hextet(parts[i]) + ip_int <<= 16 * parts_skipped + for i in range(-parts_lo, 0): + ip_int <<= 16 + ip_int |= cls._parse_hextet(parts[i]) + return ip_int + except ValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + + @classmethod + def _parse_hextet(cls, hextet_str): + """Convert an IPv6 hextet string into an integer. + + Args: + hextet_str: A string, the number to parse. + + Returns: + The hextet as an integer. + + Raises: + ValueError: if the input isn't strictly a hex number from + [0..FFFF]. + + """ + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not cls._HEX_DIGITS.issuperset(hextet_str): + raise ValueError("Only hex digits permitted in %r" % hextet_str) + # We do the length check second, since the invalid character error + # is likely to be more informative for the user + if len(hextet_str) > 4: + msg = "At most 4 characters permitted in %r" + raise ValueError(msg % hextet_str) + # Length check means we can skip checking the integer value + return int(hextet_str, 16) + + @classmethod + def _compress_hextets(cls, hextets): + """Compresses a list of hextets. + + Compresses a list of strings, replacing the longest continuous + sequence of "0" in the list with "" and adding empty strings at + the beginning or at the end of the string such that subsequently + calling ":".join(hextets) will produce the compressed version of + the IPv6 address. + + Args: + hextets: A list of strings, the hextets to compress. + + Returns: + A list of strings. + + """ + best_doublecolon_start = -1 + best_doublecolon_len = 0 + doublecolon_start = -1 + doublecolon_len = 0 + for index, hextet in enumerate(hextets): + if hextet == '0': + doublecolon_len += 1 + if doublecolon_start == -1: + # Start of a sequence of zeros. + doublecolon_start = index + if doublecolon_len > best_doublecolon_len: + # This is the longest sequence of zeros so far. + best_doublecolon_len = doublecolon_len + best_doublecolon_start = doublecolon_start + else: + doublecolon_len = 0 + doublecolon_start = -1 + + if best_doublecolon_len > 1: + best_doublecolon_end = (best_doublecolon_start + + best_doublecolon_len) + # For zeros at the end of the address. + if best_doublecolon_end == len(hextets): + hextets += [''] + hextets[best_doublecolon_start:best_doublecolon_end] = [''] + # For zeros at the beginning of the address. + if best_doublecolon_start == 0: + hextets = [''] + hextets + + return hextets + + @classmethod + def _string_from_ip_int(cls, ip_int=None): + """Turns a 128-bit integer into hexadecimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + A string, the hexadecimal representation of the address. + + Raises: + ValueError: The address is bigger than 128 bits of all ones. + + """ + if ip_int is None: + ip_int = int(cls._ip) + + if ip_int > cls._ALL_ONES: + raise ValueError('IPv6 address is too large') + + hex_str = '%032x' % ip_int + hextets = ['%x' % int(hex_str[x:x + 4], 16) for x in range(0, 32, 4)] + + hextets = cls._compress_hextets(hextets) + return ':'.join(hextets) + + def _explode_shorthand_ip_string(self): + """Expand a shortened IPv6 address. + + Args: + ip_str: A string, the IPv6 address. + + Returns: + A string, the expanded IPv6 address. + + """ + if isinstance(self, IPv6Network): + ip_str = _compat_str(self.network_address) + elif isinstance(self, IPv6Interface): + ip_str = _compat_str(self.ip) + else: + ip_str = _compat_str(self) + + ip_int = self._ip_int_from_string(ip_str) + hex_str = '%032x' % ip_int + parts = [hex_str[x:x + 4] for x in range(0, 32, 4)] + if isinstance(self, (_BaseNetwork, IPv6Interface)): + return '%s/%d' % (':'.join(parts), self._prefixlen) + return ':'.join(parts) + + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv6 address. + + This implements the method described in RFC3596 2.5. + + """ + reverse_chars = self.exploded[::-1].replace(':', '') + return '.'.join(reverse_chars) + '.ip6.arpa' + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def version(self): + return self._version + + +class IPv6Address(_BaseV6, _BaseAddress): + + """Represent and manipulate single IPv6 Addresses.""" + + __slots__ = ('_ip', '__weakref__') + + def __init__(self, address): + """Instantiate a new IPv6 address object. + + Args: + address: A string or integer representing the IP + + Additionally, an integer can be passed, so + IPv6Address('2001:db8::') == + IPv6Address(42540766411282592856903984951653826560) + or, more generally + IPv6Address(int(IPv6Address('2001:db8::'))) == + IPv6Address('2001:db8::') + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + + """ + # Efficient constructor from integer. + if isinstance(address, _compat_int_types): + self._check_int_address(address) + self._ip = address + return + + # Constructing from a packed address + if isinstance(address, bytes): + self._check_packed_address(address, 16) + bvs = _compat_bytes_to_byte_vals(address) + self._ip = _compat_int_from_byte_vals(bvs, 'big') + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = _compat_str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) + self._ip = self._ip_int_from_string(addr_str) + + @property + def packed(self): + """The binary representation of this address.""" + return v6_int_to_packed(self._ip) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is a multicast address. + See RFC 2373 2.7 for details. + + """ + return self in self._constants._multicast_network + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within one of the + reserved IPv6 Network ranges. + + """ + return any(self in x for x in self._constants._reserved_networks) + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is reserved per RFC 4291. + + """ + return self in self._constants._linklocal_network + + @property + def is_site_local(self): + """Test if the address is reserved for site-local. + + Note that the site-local address space has been deprecated by RFC 3879. + Use is_private to test if this address is in the space of unique local + addresses as defined by RFC 4193. + + Returns: + A boolean, True if the address is reserved per RFC 3513 2.5.6. + + """ + return self in self._constants._sitelocal_network + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv6-special-registry. + + """ + return any(self in net for net in self._constants._private_networks) + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, true if the address is not reserved per + iana-ipv6-special-registry. + + """ + return not self.is_private + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 2373 2.5.2. + + """ + return self._ip == 0 + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback address as defined in + RFC 2373 2.5.3. + + """ + return self._ip == 1 + + @property + def ipv4_mapped(self): + """Return the IPv4 mapped address. + + Returns: + If the IPv6 address is a v4 mapped address, return the + IPv4 mapped address. Return None otherwise. + + """ + if (self._ip >> 32) != 0xFFFF: + return None + return IPv4Address(self._ip & 0xFFFFFFFF) + + @property + def teredo(self): + """Tuple of embedded teredo IPs. + + Returns: + Tuple of the (server, client) IPs or None if the address + doesn't appear to be a teredo address (doesn't start with + 2001::/32) + + """ + if (self._ip >> 96) != 0x20010000: + return None + return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF), + IPv4Address(~self._ip & 0xFFFFFFFF)) + + @property + def sixtofour(self): + """Return the IPv4 6to4 embedded address. + + Returns: + The IPv4 6to4-embedded address if present or None if the + address doesn't appear to contain a 6to4 embedded address. + + """ + if (self._ip >> 112) != 0x2002: + return None + return IPv4Address((self._ip >> 80) & 0xFFFFFFFF) + + +class IPv6Interface(IPv6Address): + + def __init__(self, address): + if isinstance(address, (bytes, _compat_int_types)): + IPv6Address.__init__(self, address) + self.network = IPv6Network(self._ip) + self._prefixlen = self._max_prefixlen + return + if isinstance(address, tuple): + IPv6Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + + addr = _split_optional_netmask(address) + IPv6Address.__init__(self, addr[0]) + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self._prefixlen = self.network._prefixlen + self.hostmask = self.network.hostmask + + def __str__(self): + return '%s/%d' % (self._string_from_ip_int(self._ip), + self.network.prefixlen) + + def __eq__(self, other): + address_equal = IPv6Address.__eq__(self, other) + if not address_equal or address_equal is NotImplemented: + return address_equal + try: + return self.network == other.network + except AttributeError: + # An interface with an associated network is NOT the + # same as an unassociated address. That's why the hash + # takes the extra info into account. + return False + + def __lt__(self, other): + address_less = IPv6Address.__lt__(self, other) + if address_less is NotImplemented: + return NotImplemented + try: + return self.network < other.network + except AttributeError: + # We *do* allow addresses and interfaces to be sorted. The + # unassociated address is considered less than all interfaces. + return False + + def __hash__(self): + return self._ip ^ self._prefixlen ^ int(self.network.network_address) + + __reduce__ = _IPAddressBase.__reduce__ + + @property + def ip(self): + return IPv6Address(self._ip) + + @property + def with_prefixlen(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.hostmask) + + @property + def is_unspecified(self): + return self._ip == 0 and self.network.is_unspecified + + @property + def is_loopback(self): + return self._ip == 1 and self.network.is_loopback + + +class IPv6Network(_BaseV6, _BaseNetwork): + + """This class represents and manipulates 128-bit IPv6 networks. + + Attributes: [examples for IPv6('2001:db8::1000/124')] + .network_address: IPv6Address('2001:db8::1000') + .hostmask: IPv6Address('::f') + .broadcast_address: IPv6Address('2001:db8::100f') + .netmask: IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0') + .prefixlen: 124 + + """ + + # Class to use when creating address objects + _address_class = IPv6Address + + def __init__(self, address, strict=True): + """Instantiate a new IPv6 Network object. + + Args: + address: A string or integer representing the IPv6 network or the + IP and prefix/netmask. + '2001:db8::/128' + '2001:db8:0000:0000:0000:0000:0000:0000/128' + '2001:db8::' + are all functionally the same in IPv6. That is to say, + failing to provide a subnetmask will create an object with + a mask of /128. + + Additionally, an integer can be passed, so + IPv6Network('2001:db8::') == + IPv6Network(42540766411282592856903984951653826560) + or, more generally + IPv6Network(int(IPv6Network('2001:db8::'))) == + IPv6Network('2001:db8::') + + strict: A boolean. If true, ensure that we have been passed + A true network address, eg, 2001:db8::1000/124 and not an + IP address on a network, eg, 2001:db8::1/124. + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + NetmaskValueError: If the netmask isn't valid for + an IPv6 address. + ValueError: If strict was True and a network address was not + supplied. + + """ + _BaseNetwork.__init__(self, address) + + # Efficient constructor from integer or packed address + if isinstance(address, (bytes, _compat_int_types)): + self.network_address = IPv6Address(address) + self.netmask, self._prefixlen = self._make_netmask( + self._max_prefixlen) + return + + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + self.network_address = IPv6Address(address[0]) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv6Address(packed & + int(self.netmask)) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = _split_optional_netmask(address) + + self.network_address = IPv6Address(self._ip_int_from_string(addr[0])) + + if len(addr) == 2: + arg = addr[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + + if strict: + if (IPv6Address(int(self.network_address) & int(self.netmask)) != + self.network_address): + raise ValueError('%s has host bits set' % self) + self.network_address = IPv6Address(int(self.network_address) & + int(self.netmask)) + + if self._prefixlen == (self._max_prefixlen - 1): + self.hosts = self.__iter__ + + def hosts(self): + """Generate Iterator over usable hosts in a network. + + This is like __iter__ except it doesn't return the + Subnet-Router anycast address. + + """ + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network + 1, broadcast + 1): + yield self._address_class(x) + + @property + def is_site_local(self): + """Test if the address is reserved for site-local. + + Note that the site-local address space has been deprecated by RFC 3879. + Use is_private to test if this address is in the space of unique local + addresses as defined by RFC 4193. + + Returns: + A boolean, True if the address is reserved per RFC 3513 2.5.6. + + """ + return (self.network_address.is_site_local and + self.broadcast_address.is_site_local) + + +class _IPv6Constants(object): + + _linklocal_network = IPv6Network('fe80::/10') + + _multicast_network = IPv6Network('ff00::/8') + + _private_networks = [ + IPv6Network('::1/128'), + IPv6Network('::/128'), + IPv6Network('::ffff:0:0/96'), + IPv6Network('100::/64'), + IPv6Network('2001::/23'), + IPv6Network('2001:2::/48'), + IPv6Network('2001:db8::/32'), + IPv6Network('2001:10::/28'), + IPv6Network('fc00::/7'), + IPv6Network('fe80::/10'), + ] + + _reserved_networks = [ + IPv6Network('::/8'), IPv6Network('100::/8'), + IPv6Network('200::/7'), IPv6Network('400::/6'), + IPv6Network('800::/5'), IPv6Network('1000::/4'), + IPv6Network('4000::/3'), IPv6Network('6000::/3'), + IPv6Network('8000::/3'), IPv6Network('A000::/3'), + IPv6Network('C000::/3'), IPv6Network('E000::/4'), + IPv6Network('F000::/5'), IPv6Network('F800::/6'), + IPv6Network('FE00::/9'), + ] + + _sitelocal_network = IPv6Network('fec0::/10') + + +IPv6Address._constants = _IPv6Constants diff --git a/web2py/gluon/contrib/login_methods/__init__.py b/web2py/gluon/contrib/login_methods/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/web2py/gluon/contrib/login_methods/__init__.py @@ -0,0 +1 @@ + diff --git a/web2py/gluon/contrib/login_methods/basic_auth.py b/web2py/gluon/contrib/login_methods/basic_auth.py new file mode 100644 index 0000000..fb9ff71 --- /dev/null +++ b/web2py/gluon/contrib/login_methods/basic_auth.py @@ -0,0 +1,24 @@ +from gluon._compat import urlopen +from gluon._compat import urllib2 +import base64 + + +def basic_auth(server="http://127.0.0.1"): + """ + to use basic login with a different server + from gluon.contrib.login_methods.basic_auth import basic_auth + auth.settings.login_methods.append(basic_auth('http://server')) + """ + + def basic_login_aux(username, + password, + server=server): + key = base64.b64encode(username + ':' + password) + headers = {'Authorization': 'Basic ' + key} + request = urllib2.Request(server, None, headers) + try: + urlopen(request) + return True + except (urllib2.URLError, urllib2.HTTPError): + return False + return basic_login_aux diff --git a/web2py/gluon/contrib/login_methods/browserid_account.py b/web2py/gluon/contrib/login_methods/browserid_account.py new file mode 100644 index 0000000..f00ec46 --- /dev/null +++ b/web2py/gluon/contrib/login_methods/browserid_account.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" + BrowserID Authentication for web2py + developed by Madhukar R Pai (Copyright 2012) + Email + License : LGPL + + thanks and credits to the web2py community + + This custom authenticator allows web2py to authenticate using browserid (https://login.persona.org/) + BrowserID is a project by Mozilla Labs (http://mozillalabs.com/) + to Know how browserid works please visit http://identity.mozilla.com/post/7616727542/introducing-browserid-a-better-way-to-sign-in + + bottom line BrowserID provides a free, secure, de-centralized, easy to use(for users and developers) login solution. + You can use any email id as your login id. Browserid just verifys the email id and lets you login with that id. + + credits for the doPost jquery function - itsadok (http://stackoverflow.com/users/7581/itsadok) + +""" +import time +from gluon import * +from gluon.storage import Storage +from gluon.tools import fetch +import json + + +class BrowserID(object): + """ + from gluon.contrib.login_methods.browserid_account import BrowserID + auth.settings.login_form = BrowserID(request, + audience = "http://127.0.0.1:8000" + assertion_post_url = "http://127.0.0.1:8000/%s/default/user/login" % request.application) + """ + + def __init__(self, + request, + audience="", + assertion_post_url="", + prompt="BrowserID Login", + issuer="login.persona.org", + verify_url="https://login.persona.org/verify", + browserid_js="https://login.persona.org/include.js", + browserid_button="https://login.persona.org/i/sign_in_red.png", + crypto_js="https://crypto-js.googlecode.com/files/2.2.0-crypto-md5.js", + on_login_failure=None, + ): + + self.request = request + self.audience = audience + self.assertion_post_url = assertion_post_url + self.prompt = prompt + self.issuer = issuer + self.verify_url = verify_url + self.browserid_js = browserid_js + self.browserid_button = browserid_button + self.crypto_js = crypto_js + self.on_login_failure = on_login_failure + self.asertion_js = """ + (function($){$.extend({doPost:function(url,params){var $form=$("
    ").attr("action",url); + $.each(params,function(name,value){$("").attr("name",name).attr("value",value).appendTo($form)}); + $form.appendTo("body");$form.submit()}})})(jQuery); + function gotVerifiedEmail(assertion){if(assertion !== null){$.doPost('%s',{'assertion':assertion});}}""" % self.assertion_post_url + + def get_user(self): + request = self.request + if request.vars.assertion: + audience = self.audience + issuer = self.issuer + assertion = XML(request.vars.assertion, sanitize=True) + verify_data = {'assertion': assertion, 'audience': audience} + auth_info_json = fetch(self.verify_url, data=verify_data) + j = json.loads(auth_info_json) + epoch_time = int(time.time() * 1000) # we need 13 digit epoch time + if j["status"] == "okay" and j["audience"] == audience and j['issuer'].endswith(issuer) and j['expires'] >= epoch_time: + return dict(email=j['email']) + elif self.on_login_failure: + #print "status: ", j["status"]=="okay", j["status"] + #print "audience:", j["audience"]==audience, j["audience"], audience + #print "issuer: ", j["issuer"]==issuer, j["issuer"], issuer + #print "expires: ", j["expires"] >= epoch_time, j["expires"], epoch_time + redirect(self.on_login_failure) + else: + redirect('https://login.persona.org') + return None + + def login_form(self): + request = self.request + onclick = "javascript:navigator.id.getVerifiedEmail(gotVerifiedEmail) ; return false" + form = DIV(SCRIPT(_src=self.browserid_js, _type="text/javascript"), + SCRIPT(_src=self.crypto_js, _type="text/javascript"), + A(IMG(_src=self.browserid_button, _alt=self.prompt), _href="#", _onclick=onclick, _class="browserid", _title="Login With BrowserID"), + SCRIPT(self.asertion_js)) + return form diff --git a/web2py/gluon/contrib/login_methods/cas_auth.py b/web2py/gluon/contrib/login_methods/cas_auth.py new file mode 100644 index 0000000..73be8ae --- /dev/null +++ b/web2py/gluon/contrib/login_methods/cas_auth.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +This file is part of web2py Web Framework (Copyrighted, 2007-2009). +Developed by Massimo Di Pierro . +License: LGPL v3 + +Tinkered by Szabolcs Gyuris < szimszo n @ o regpreshaz dot eu> +""" +import xml.dom.minidom as dom +import xml.parsers.expat as expat + +from gluon import current, redirect, URL +from gluon._compat import urlopen, to_native + +class CasAuth(object): + """ + Login will be done via Web2py's CAS application, instead of web2py's + login form. + + Include in your model (eg db.py):: + + from gluon.contrib.login_methods.cas_auth import CasAuth + auth.define_tables(username=True) + auth.settings.login_form=CasAuth( + urlbase = "https://[your CAS provider]/app/default/user/cas", + actions=['login','validate','logout']) + + where urlbase is the actual CAS server url without the login,logout... + Enjoy. + + ###UPDATE### + if you want to connect to a CAS version 2 JASIG Server use this: + auth.settings.login_form=CasAuth( + urlbase = "https://[Your CAS server]/cas", + actions = ['login','serviceValidate','logout'], + casversion = 2, + casusername = "cas:user") + + where casusername is the xml node returned by CAS server which contains + user's username. + + """ + def __init__(self, g=None, # g for backward compatibility ### + urlbase="https://web2py.com/cas/cas", + actions=['login', 'validate', 'logout'], + maps=dict(username=lambda v: v.get('username', v['user']), + email=lambda v: v.get('email', None), + user_id=lambda v: v['user']), + casversion=1, + casusername='cas:user', + change_password_url=None + ): + self.urlbase = urlbase + self.cas_login_url = "%s/%s" % (self.urlbase, actions[0]) + self.cas_check_url = "%s/%s" % (self.urlbase, actions[1]) + self.cas_logout_url = "%s/%s" % (self.urlbase, actions[2]) + self.maps = maps + self.casversion = casversion + self.casusername = casusername + # vars commented because of + # https://code.google.com/p/web2py/issues/detail?id=1774 + self.cas_my_url = URL(args=current.request.args, + #vars=current.request.vars, + scheme=True) + + # URL to let users change their password in the IDP system + self.cas_change_password_url = change_password_url + + def login_url(self, next="/"): + current.session.token = self._CAS_login() + return next + + def logout_url(self, next="/"): + current.session.token = None + current.session.auth = None + self._CAS_logout() + return next + + def change_password_url(self, next="/"): + self._CAS_change_password() + return next + + def get_user(self): + user = current.session.token + if user: + d = {'source': 'web2py cas'} + for key in self.maps: + d[key] = self.maps[key](user) + return d + return None + + def _CAS_login(self): + """ + exposed as CAS.login(request) + returns a token on success, None on failed authentication + """ + self.ticket = current.request.vars.ticket + if not current.request.vars.ticket: + redirect("%s?service=%s" % (self.cas_login_url, + self.cas_my_url)) + else: + url = "%s?service=%s&ticket=%s" % (self.cas_check_url, + self.cas_my_url, + self.ticket) + data = to_native(urlopen(url).read()) + if data.startswith('yes') or data.startswith('no'): + data = data.split('\n') + if data[0] == 'yes': + if ':' in data[1]: # for Compatibility with Custom CAS + items = data[1].split(':') + a = items[0] + b = len(items) > 1 and items[1] or a + c = len(items) > 2 and items[2] or b + else: + a = b = c = data[1] + return dict(user=a, email=b, username=c) + return None + try: + dxml = dom.parseString(data) + envelop = dxml.getElementsByTagName("cas:authenticationSuccess") + if len(envelop) > 0: + res = dict() + for x in envelop[0].childNodes: + if x.nodeName.startswith('cas:') and len(x.childNodes): + key = to_native(x.nodeName[4:]) + value = to_native(x.childNodes[0].nodeValue) + if key not in res: + res[key] = value + else: + if not isinstance(res[key], list): + res[key] = [res[key]] + res[key].append(value) + return res + except expat.ExpatError: + pass + return None # fallback + + def _CAS_logout(self): + """ + exposed CAS.logout() + redirects to the CAS logout page + """ + redirect("%s?service=%s" % (self.cas_logout_url, self.cas_my_url)) + + def _CAS_change_password(self): + redirect(self.cas_change_password_url) diff --git a/web2py/gluon/contrib/login_methods/dropbox_account.py b/web2py/gluon/contrib/login_methods/dropbox_account.py new file mode 100644 index 0000000..e2948c4 --- /dev/null +++ b/web2py/gluon/contrib/login_methods/dropbox_account.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python +# coding: utf8 + +""" +Dropbox Authentication for web2py +Developed by Massimo Di Pierro (2012) +Same License as Web2py License +""" + +# mind here session is dropbox session, not current.session + +import os +import re +import urllib +from dropbox import client, rest, session +from gluon import * +from gluon.tools import fetch +from gluon.storage import Storage + + +class DropboxAccount(object): + + """ + from gluon.contrib.login_methods.dropbox_account import DropboxAccount + auth.settings.actions_disabled=['register','change_password', + 'request_reset_password'] + auth.settings.login_form = DropboxAccount(request, + key="...", + secret="...", + access_type="...", + login_url = "http://localhost:8000/%s/default/user/login" % request.application) + when logged in + client = auth.settings.login_form.client + """ + + def __init__(self, + request, + key="", + secret="", + access_type="app_folder", + login_url="", + on_login_failure=None, + ): + + self.request = request + self.key = key + self.secret = secret + self.access_type = access_type + self.login_url = login_url + self.on_login_failure = on_login_failure + self.sess = session.DropboxSession( + self.key, self.secret, self.access_type) + + def get_token(self): + if not current.session.dropbox_access_token: + request_token = current.session.dropbox_request_token + self.sess.set_request_token(request_token[0], request_token[1]) + access_token = self.sess.obtain_access_token(self.sess.token) + current.session.dropbox_access_token = \ + (access_token.key, access_token.secret) + else: + access_token = current.session.dropbox_access_token + self.sess.set_token(access_token[0], access_token[1]) + + def get_user(self): + if not current.session.dropbox_request_token: + return None + self.get_token() + user = Storage() + self.client = client.DropboxClient(self.sess) + data = self.client.account_info() + display_name = data.get('display_name', '').split(' ', 1) + user = dict(email=data.get('email', None), + first_name=display_name[0], + last_name=display_name[-1], + registration_id=data.get('uid', None)) + if not user['registration_id'] and self.on_login_failure: + redirect(self.on_login_failure) + return user + + def login_form(self): + + request_token = self.sess.obtain_request_token() + current.session.dropbox_request_token = \ + (request_token.key, request_token.secret) + dropbox_url = self.sess.build_authorize_url(request_token, + self.login_url) + redirect(dropbox_url) + form = IFRAME(_src=dropbox_url, + _scrolling="no", + _frameborder="no", + _style="width:400px;height:240px;") + return form + + def logout_url(self, next="/"): + self.sess.unlink() + current.session.auth = None + return next + + def get_client(self): + self.get_token() + self.client = client.DropboxClient(self.sess) + + def put(self, filename, file): + if not hasattr(self,'client'): self.get_client() + return self.client.put_file(filename, file)['bytes'] + + def get(self, filename): + if not hasattr(self,'client'): self.get_client() + return self.client.get_file(filename) + + def dir(self, path): + if not hasattr(self,'client'): self.get_client() + return self.client.metadata(path) + + +def use_dropbox(auth, filename='private/dropbox.key', **kwargs): + path = os.path.join(current.request.folder, filename) + if os.path.exists(path): + request = current.request + key, secret, access_type = open(path, 'r').read().strip().split(':') + host = current.request.env.http_host + login_url = "http://%s/%s/default/user/login" % \ + (host, request.application) + auth.settings.actions_disabled = \ + ['register', 'change_password', 'request_reset_password'] + auth.settings.login_form = DropboxAccount( + request, key=key, secret=secret, access_type=access_type, + login_url=login_url, **kwargs) diff --git a/web2py/gluon/contrib/login_methods/email_auth.py b/web2py/gluon/contrib/login_methods/email_auth.py new file mode 100644 index 0000000..840fc0c --- /dev/null +++ b/web2py/gluon/contrib/login_methods/email_auth.py @@ -0,0 +1,46 @@ +import smtplib +import logging + + +def email_auth(server="smtp.gmail.com:587", + domain="@gmail.com", + tls_mode=None): + """ + to use email_login: + from gluon.contrib.login_methods.email_auth import email_auth + auth.settings.login_methods.append(email_auth("smtp.gmail.com:587", + "@gmail.com")) + """ + + def email_auth_aux(email, + password, + server=server, + domain=domain, + tls_mode=tls_mode): + if domain: + if not isinstance(domain, (list, tuple)): + domain = [str(domain)] + if not [d for d in domain if email[-len(d):] == d]: + return False + (host, port) = server.split(':') + if tls_mode is None: # then auto detect + tls_mode = port == '587' + try: + server = None + server = smtplib.SMTP(host, port) + server.ehlo() + if tls_mode: + server.starttls() + server.ehlo() + server.login(email, password) + server.quit() + return True + except: + logging.exception('email_auth() failed') + if server: + try: + server.quit() + except: # server might already close connection after error + pass + return False + return email_auth_aux diff --git a/web2py/gluon/contrib/login_methods/extended_login_form.py b/web2py/gluon/contrib/login_methods/extended_login_form.py new file mode 100644 index 0000000..6946531 --- /dev/null +++ b/web2py/gluon/contrib/login_methods/extended_login_form.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python +# coding: utf8 + +""" +ExtendedLoginForm is used to extend normal login form in web2py with one more login method. +So user can choose the built-in login or extended login methods. +""" + +from gluon import current, DIV + + +class ExtendedLoginForm(object): + """ + Put extended_login_form under web2py/gluon/contrib/login_methods folder. + Then inside your model where defines the auth: + + auth = Auth(globals(),db) # authentication/authorization + ... + auth.define_tables() # You might like to put the code after auth.define_tables + ... # if the alt_login_form deals with tables of auth. + + alt_login_form = RPXAccount(request, + api_key="...", + domain="...", + url = "http://localhost:8000/%s/default/user/login" % request.application) + extended_login_form = ExtendedLoginForm( + auth, alt_login_form, signals=['token']) + + auth.settings.login_form = extended_login_form + + Note: + Since rpx_account doesn't create the password for the user, you + might need to provide a way for user to create password to do + normal login. + + """ + + def __init__(self, + auth, + alt_login_form, + signals=[], + login_arg='login' + ): + self.auth = auth + self.alt_login_form = alt_login_form + self.signals = signals + self.login_arg = login_arg + + def get_user(self): + """ + Delegate the get_user to alt_login_form.get_user. + """ + if hasattr(self.alt_login_form, 'get_user'): + return self.alt_login_form.get_user() + return None # let gluon.tools.Auth.get_or_create_user do the rest + + def login_url(self, next): + """ + Optional implement for alt_login_form. + + In normal case, this should be replaced by get_user, and never get called. + """ + if hasattr(self.alt_login_form, 'login_url'): + return self.alt_login_form.login_url(next) + return self.auth.settings.login_url + + def logout_url(self, next): + """ + Optional implement for alt_login_form. + + Called if bool(alt_login_form.get_user) is True. + + If alt_login_form implemented logout_url function, it will return that function call. + """ + if hasattr(self.alt_login_form, 'logout_url'): + return self.alt_login_form.logout_url(next) + return next + + def login_form(self): + """ + Combine the auth() form with alt_login_form. + + If signals are set and a parameter in request matches any signals, + it will return the call of alt_login_form.login_form instead. + So alt_login_form can handle some particular situations, for example, + multiple steps of OpenID login inside alt_login_form.login_form. + + Otherwise it will render the normal login form combined with + alt_login_form.login_form. + """ + + request = current.request + args = request.args + + if (self.signals and + any([True for signal in self.signals if signal in request.vars]) + ): + return self.alt_login_form.login_form() + + self.auth.settings.login_form = self.auth + form = DIV(self.auth()) + self.auth.settings.login_form = self + + form.components.append(self.alt_login_form.login_form()) + return form diff --git a/web2py/gluon/contrib/login_methods/gae_google_account.py b/web2py/gluon/contrib/login_methods/gae_google_account.py new file mode 100644 index 0000000..446b380 --- /dev/null +++ b/web2py/gluon/contrib/login_methods/gae_google_account.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +This file is part of web2py Web Framework (Copyrighted, 2007-2009). +Developed by Massimo Di Pierro . +License: LGPL v3 + +Thanks to Hans Donner for GaeGoogleAccount. +""" + +from google.appengine.api import users + + +class GaeGoogleAccount(object): + """ + Login will be done via Google's Appengine login object, instead of web2py's + login form. + + Include in your model (eg db.py):: + + from gluon.contrib.login_methods.gae_google_account import \ + GaeGoogleAccount + auth.settings.login_form=GaeGoogleAccount() + + """ + + def login_url(self, next="/"): + return users.create_login_url(next) + + def logout_url(self, next="/"): + return users.create_logout_url(next) + + def get_user(self): + user = users.get_current_user() + if user: + return dict(nickname = user.nickname(), + email = user.email(), + registration_id = user.user_id(), + user_id = user.user_id(), + source = "google account") diff --git a/web2py/gluon/contrib/login_methods/janrain_account.py b/web2py/gluon/contrib/login_methods/janrain_account.py new file mode 100644 index 0000000..1834b32 --- /dev/null +++ b/web2py/gluon/contrib/login_methods/janrain_account.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python +# coding: utf8 + +""" + RPX Authentication for web2py + Developed by Nathan Freeze (Copyright © 2009) + Email + Modified by Massimo Di Pierro + + This file contains code to allow using RPXNow.com (now Jainrain.com) + services with web2py +""" + +import os +import re +import urllib +from gluon import * +from gluon.tools import fetch +from gluon.storage import Storage +import json + + +class RPXAccount(object): + + """ + from gluon.contrib.login_methods.rpx_account import RPXAccount + auth.settings.actions_disabled=['register','change_password', + 'request_reset_password'] + auth.settings.login_form = RPXAccount(request, + api_key="...", + domain="...", + url = "http://localhost:8000/%s/default/user/login" % request.application) + """ + + def __init__(self, + request, + api_key="", + domain="", + url="", + embed=True, + auth_url="https://rpxnow.com/api/v2/auth_info", + language="en", + prompt='rpx', + on_login_failure=None, + ): + + self.request = request + self.api_key = api_key + self.embed = embed + self.auth_url = auth_url + self.domain = domain + self.token_url = url + self.language = language + self.profile = None + self.prompt = prompt + self.on_login_failure = on_login_failure + self.mappings = Storage() + + dn = {'givenName': '', 'familyName': ''} + self.mappings.Facebook = lambda profile, dn=dn:\ + dict(registration_id=profile.get("identifier", ""), + username=profile.get("preferredUsername", ""), + email=profile.get("email", ""), + first_name=profile.get("name", dn).get("givenName", ""), + last_name=profile.get("name", dn).get("familyName", "")) + self.mappings.Google = lambda profile, dn=dn:\ + dict(registration_id=profile.get("identifier", ""), + username=profile.get("preferredUsername", ""), + email=profile.get("email", ""), + first_name=profile.get("name", dn).get("givenName", ""), + last_name=profile.get("name", dn).get("familyName", "")) + self.mappings.default = lambda profile:\ + dict(registration_id=profile.get("identifier", ""), + username=profile.get("preferredUsername", ""), + email=profile.get("email", ""), + first_name=profile.get("preferredUsername", ""), + last_name='') + + def get_user(self): + request = self.request + # Janrain now sends the token via both a POST body and the query + # string, so we should keep only one of these. + token = request.post_vars.token or request.get_vars.token + if token: + user = Storage() + data = urllib.urlencode( + dict(apiKey=self.api_key, token=token)) + auth_info_json = fetch(self.auth_url + '?' + data) + auth_info = json.loads(auth_info_json) + + if auth_info['stat'] == 'ok': + self.profile = auth_info['profile'] + provider = re.sub('[^\w\-]', '', self.profile['providerName']) + user = self.mappings.get( + provider, self.mappings.default)(self.profile) + return user + elif self.on_login_failure: + redirect(self.on_login_failure) + return None + + def login_form(self): + request = self.request + args = request.args + rpxform = """ + +
    """ % (self.token_url, self.domain, self.domain) + return XML(rpxform) + +def use_janrain(auth, filename='private/janrain.key', **kwargs): + path = os.path.join(current.request.folder, filename) + if os.path.exists(path): + request = current.request + domain, key = open(path, 'r').read().strip().split(':') + host = current.request.env.http_host + url = URL('default', 'user', args='login', scheme=True) + auth.settings.actions_disabled = \ + ['register', 'change_password', 'request_reset_password'] + auth.settings.login_form = RPXAccount( + request, api_key=key, domain=domain, url=url, **kwargs) diff --git a/web2py/gluon/contrib/login_methods/ldap_auth.py b/web2py/gluon/contrib/login_methods/ldap_auth.py new file mode 100644 index 0000000..feb2939 --- /dev/null +++ b/web2py/gluon/contrib/login_methods/ldap_auth.py @@ -0,0 +1,716 @@ +# -*- coding: utf-8 -*- +# +# last tinkered with by korylprince at gmail.com on 2012-07-12 +# + +import sys +import logging +try: + import ldap + import ldap.filter + ldap.set_option(ldap.OPT_REFERRALS, 0) +except Exception as e: + logging.error('missing ldap, try "pip install python-ldap"') + raise e + + +def ldap_auth(server='ldap', + port=None, + base_dn='ou=users,dc=domain,dc=com', + mode='uid', + secure=False, + self_signed_certificate=None, # See NOTE below + cert_path=None, + cert_file=None, + cacert_path=None, + cacert_file=None, + key_file=None, + bind_dn=None, + bind_pw=None, + filterstr='objectClass=*', + username_attrib='uid', + custom_scope='subtree', + allowed_groups=None, + manage_user=False, + user_firstname_attrib='cn:1', + user_lastname_attrib='cn:2', + user_mail_attrib='mail', + manage_groups=False, + manage_groups_callback=[], + db=None, + group_dn=None, + group_name_attrib='cn', + group_member_attrib='memberUid', + group_filterstr='objectClass=*', + group_mapping={}, + tls=False, + logging_level='error'): + + """ + to use ldap login with MS Active Directory: + + from gluon.contrib.login_methods.ldap_auth import ldap_auth + auth.settings.login_methods.append(ldap_auth( + mode='ad', server='my.domain.controller', + base_dn='ou=Users,dc=domain,dc=com')) + + to use ldap login with Notes Domino: + + auth.settings.login_methods.append(ldap_auth( + mode='domino',server='my.domino.server')) + + to use ldap login with OpenLDAP: + + auth.settings.login_methods.append(ldap_auth( + server='my.ldap.server', base_dn='ou=Users,dc=domain,dc=com')) + + to use ldap login with OpenLDAP and subtree search and (optionally) + multiple DNs: + + auth.settings.login_methods.append(ldap_auth( + mode='uid_r', server='my.ldap.server', + base_dn=['ou=Users,dc=domain,dc=com','ou=Staff,dc=domain,dc=com'])) + + or (if using CN): + + auth.settings.login_methods.append(ldap_auth( + mode='cn', server='my.ldap.server', + base_dn='ou=Users,dc=domain,dc=com')) + + or you can full customize the search for user: + + auth.settings.login_methods.append(ldap_auth( + mode='custom', server='my.ldap.server', + base_dn='ou=Users,dc=domain,dc=com', + username_attrib='uid', + custom_scope='subtree')) + + the custom_scope can be: base, onelevel, subtree. + + If using secure ldaps:// pass secure=True and cert_path="..." + If ldap is using GnuTLS then you need cert_file="..." instead cert_path + because cert_path isn't implemented in GnuTLS :( + + To enable TLS, set tls=True: + + auth.settings.login_methods.append(ldap_auth( + server='my.ldap.server', + base_dn='ou=Users,dc=domain,dc=com', + tls=True)) + + If you need to bind to the directory with an admin account in order to + search it then specify bind_dn & bind_pw to use for this. + - currently only implemented for Active Directory + + If you need to restrict the set of allowed users (e.g. to members of a + department) then specify an rfc4515 search filter string. + - currently only implemented for mode in ['ad', 'company', 'uid_r'] + + You can manage user attributes first name, last name, email from ldap: + auth.settings.login_methods.append(ldap_auth(...as usual..., + manage_user=True, + user_firstname_attrib='cn:1', + user_lastname_attrib='cn:2', + user_mail_attrib='mail' + )) + + Where: + manage_user - let web2py handle user data from ldap + user_firstname_attrib - the attribute containing the user's first name + optionally you can specify parts. + Example: cn: "John Smith" - 'cn:1'='John' + user_lastname_attrib - the attribute containing the user's last name + optionally you can specify parts. + Example: cn: "John Smith" - 'cn:2'='Smith' + user_mail_attrib - the attribute containing the user's email address + + + If you need group control from ldap to web2py app's database feel free + to set: + + auth.settings.login_methods.append(ldap_auth(...as usual..., + manage_groups=True, + db=db, + group_dn='ou=Groups,dc=domain,dc=com', + group_name_attrib='cn', + group_member_attrib='memberUid', + group_filterstr='objectClass=*' + )) + + Where: + manage_group - let web2py handle the groups from ldap + db - is the database object (need to have auth_user, auth_group, + auth_membership) + group_dn - the ldap branch of the groups + group_name_attrib - the attribute where the group name is stored + group_member_attrib - the attribute containing the group members name + group_filterstr - as the filterstr but for group select + + You can restrict login access to specific groups if you specify: + + auth.settings.login_methods.append(ldap_auth(...as usual..., + allowed_groups=[...], + group_dn='ou=Groups,dc=domain,dc=com', + group_name_attrib='cn', + group_member_attrib='memberUid',#use 'member' for Active Directory + group_filterstr='objectClass=*' + )) + + Where: + allowed_groups - a list with allowed ldap group names + group_dn - the ldap branch of the groups + group_name_attrib - the attribute where the group name is stored + group_member_attrib - the attribute containing the group members name + group_filterstr - as the filterstr but for group select + + If using Active Directory you must specify bind_dn and bind_pw for + allowed_groups unless anonymous bind works. + + You can set the logging level with the "logging_level" parameter, default + is "error" and can be set to error, warning, info, debug. + """ + logger = logging.getLogger('web2py.auth.ldap_auth') + if isinstance(logging_level, int): + logger.setLevel(logging_level) + elif logging_level == 'error': + logger.setLevel(logging.ERROR) + elif logging_level == 'warning': + logger.setLevel(logging.WARNING) + elif logging_level == 'info': + logger.setLevel(logging.INFO) + elif logging_level == 'debug': + logger.setLevel(logging.DEBUG) + + def ldap_auth_aux(username, + password, + ldap_server=server, + ldap_port=port, + ldap_basedn=base_dn, + ldap_mode=mode, + ldap_binddn=bind_dn, + ldap_bindpw=bind_pw, + secure=secure, + cert_path=cert_path, + cert_file=cert_file, + cacert_file=cacert_file, + key_file=key_file, + filterstr=filterstr, + username_attrib=username_attrib, + custom_scope=custom_scope, + manage_user=manage_user, + user_firstname_attrib=user_firstname_attrib, + user_lastname_attrib=user_lastname_attrib, + user_mail_attrib=user_mail_attrib, + manage_groups=manage_groups, + allowed_groups=allowed_groups, + group_mapping=group_mapping, + db=db): + if password == '': # http://tools.ietf.org/html/rfc4513#section-5.1.2 + logger.warning('blank password not allowed') + return False + logger.debug('mode: [%s] manage_user: [%s] custom_scope: [%s]' + ' manage_groups: [%s]' % (str(mode), str(manage_user), str(custom_scope), str(manage_groups))) + if manage_user: + if user_firstname_attrib.count(':') > 0: + (user_firstname_attrib, + user_firstname_part) = user_firstname_attrib.split(':', 1) + user_firstname_part = (int(user_firstname_part) - 1) + else: + user_firstname_part = None + if user_lastname_attrib.count(':') > 0: + (user_lastname_attrib, + user_lastname_part) = user_lastname_attrib.split(':', 1) + user_lastname_part = (int(user_lastname_part) - 1) + else: + user_lastname_part = None + user_firstname_attrib = ldap.filter.escape_filter_chars( + user_firstname_attrib) + user_lastname_attrib = ldap.filter.escape_filter_chars( + user_lastname_attrib) + user_mail_attrib = ldap.filter.escape_filter_chars( + user_mail_attrib) + try: + if allowed_groups: + if not is_user_in_allowed_groups(username, password): + return False + con = init_ldap() + if ldap_mode == 'ad': + # Microsoft Active Directory + if '@' not in username: + domain = [] + for x in ldap_basedn.split(','): + if "DC=" in x.upper(): + domain.append(x.split('=')[-1]) + username = "%s@%s" % (username, '.'.join(domain)) + username_bare = username.split("@")[0] + con.set_option(ldap.OPT_PROTOCOL_VERSION, 3) + # In cases where ForestDnsZones and DomainDnsZones are found, + # result will look like the following: + # ['ldap://ForestDnsZones.domain.com/DC=ForestDnsZones, + # DC=domain,DC=com'] + if ldap_binddn: + # need to search directory with an admin account 1st + con.simple_bind_s(ldap_binddn, ldap_bindpw) + else: + # credentials should be in the form of username@domain.tld + con.simple_bind_s(username, password) + # this will throw an index error if the account is not found + # in the ldap_basedn + requested_attrs = ['sAMAccountName'] + if manage_user: + requested_attrs.extend([user_firstname_attrib, user_lastname_attrib, user_mail_attrib]) + + result = con.search_ext_s( + ldap_basedn, ldap.SCOPE_SUBTREE, + "(&(sAMAccountName=%s)(%s))" % (ldap.filter.escape_filter_chars(username_bare), filterstr), + requested_attrs)[0][1] + if not isinstance(result, dict): + # result should be a dict in the form + # {'sAMAccountName': [username_bare]} + logger.warning('User [%s] not found!' % username) + return False + if ldap_binddn: + # We know the user exists & is in the correct OU + # so now we just check the password + con.simple_bind_s(username, password) + username = username_bare + + if ldap_mode == 'domino': + # Notes Domino + if "@" in username: + username = username.split("@")[0] + con.simple_bind_s(username, password) + if manage_user: + # TODO: sorry I have no clue how to query attrs in domino + result = {user_firstname_attrib: username, + user_lastname_attrib: None, + user_mail_attrib: None} + + if ldap_mode == 'cn': + # OpenLDAP (CN) + if ldap_binddn and ldap_bindpw: + con.simple_bind_s(ldap_binddn, ldap_bindpw) + dn = "cn=" + username + "," + ldap_basedn + con.simple_bind_s(dn, password) + if manage_user: + result = con.search_s(dn, ldap.SCOPE_BASE, + "(objectClass=*)", + [user_firstname_attrib, user_lastname_attrib, user_mail_attrib])[0][1] + + if ldap_mode == 'uid': + # OpenLDAP (UID) + if ldap_binddn and ldap_bindpw: + con.simple_bind_s(ldap_binddn, ldap_bindpw) + dn = "uid=" + username + "," + ldap_basedn + dn = con.search_s(ldap_basedn, ldap.SCOPE_SUBTREE, "(uid=%s)" % username, [''])[0][0] + else: + dn = "uid=" + username + "," + ldap_basedn + con.simple_bind_s(dn, password) + if manage_user: + result = con.search_s(dn, ldap.SCOPE_BASE, + "(objectClass=*)", + [user_firstname_attrib, user_lastname_attrib, user_mail_attrib])[0][1] + + if ldap_mode == 'company': + # no DNs or password needed to search directory + dn = "" + pw = "" + # bind anonymously + con.simple_bind_s(dn, pw) + # search by e-mail address + filter = '(&(mail=%s)(%s))' % ( + ldap.filter.escape_filter_chars(username), + filterstr) + # find the uid + attrs = ['uid'] + if manage_user: + attrs.extend([user_firstname_attrib, user_lastname_attrib, user_mail_attrib]) + # perform the actual search + company_search_result = con.search_s(ldap_basedn, + ldap.SCOPE_SUBTREE, + filter, attrs) + dn = company_search_result[0][0] + result = company_search_result[0][1] + # perform the real authentication test + con.simple_bind_s(dn, password) + + if ldap_mode == 'uid_r': + # OpenLDAP (UID) with subtree search and multiple DNs + if isinstance(ldap_basedn, list): + basedns = ldap_basedn + else: + basedns = [ldap_basedn] + filter = '(&(uid=%s)(%s))' % (ldap.filter.escape_filter_chars(username), filterstr) + found = False + for basedn in basedns: + try: + result = con.search_s(basedn, ldap.SCOPE_SUBTREE, filter) + if result: + user_dn = result[0][0] + # Check the password + con.simple_bind_s(user_dn, password) + found = True + break + except ldap.LDAPError as detail: + (exc_type, exc_value) = sys.exc_info()[:2] + logger.warning("ldap_auth: searching %s for %s resulted in %s: %s\n" % (basedn, + filter, + exc_type, + exc_value) + ) + if not found: + logger.warning('User [%s] not found!' % username) + return False + result = result[0][1] + if ldap_mode == 'custom': + # OpenLDAP (username_attrs) with subtree search and + # multiple DNs + if isinstance(ldap_basedn, list): + basedns = ldap_basedn + else: + basedns = [ldap_basedn] + filter = '(&(%s=%s)(%s))' % (username_attrib, ldap.filter.escape_filter_chars(username), filterstr) + if custom_scope == 'subtree': + ldap_scope = ldap.SCOPE_SUBTREE + elif custom_scope == 'base': + ldap_scope = ldap.SCOPE_BASE + elif custom_scope == 'onelevel': + ldap_scope = ldap.SCOPE_ONELEVEL + found = False + for basedn in basedns: + try: + result = con.search_s(basedn, ldap_scope, filter) + if result: + user_dn = result[0][0] + # Check the password + con.simple_bind_s(user_dn, password) + found = True + break + except ldap.LDAPError as detail: + (exc_type, exc_value) = sys.exc_info()[:2] + logger.warning("ldap_auth: searching %s for %s resulted in %s: %s\n" % (basedn, + filter, + exc_type, + exc_value) + ) + if not found: + logger.warning('User [%s] not found!' % username) + return False + result = result[0][1] + if manage_user: + logger.info('[%s] Manage user data' % str(username)) + try: + user_firstname = result[user_firstname_attrib][0] + if user_firstname_part is not None: + store_user_firstname = user_firstname.split( + b' ' if isinstance(user_firstname, bytes) else ' ', + 1 + )[user_firstname_part] + else: + store_user_firstname = user_firstname + except KeyError as e: + store_user_firstname = None + try: + user_lastname = result[user_lastname_attrib][0] + if user_lastname_part is not None: + store_user_lastname = user_lastname.split( + b' ' if isinstance(user_lastname, bytes) else ' ', + 1 + )[user_lastname_part] + else: + store_user_lastname = user_lastname + except KeyError as e: + store_user_lastname = None + try: + store_user_mail = result[user_mail_attrib][0] + except KeyError as e: + store_user_mail = None + update_or_insert_values = {'first_name': store_user_firstname, + 'last_name': store_user_lastname, + 'email': store_user_mail, + 'username': username} + if '@' not in username: + # user as username + # ################ + fields = ['first_name', 'last_name', 'email'] + user_in_db = db(db.auth_user.username == username) + elif '@' in username: + # user as email + # ############# + fields = ['first_name', 'last_name'] + user_in_db = db(db.auth_user.email == username) + update_or_insert_values = dict(((f, update_or_insert_values[f]) for f in fields)) + + if user_in_db.count() > 0: + actual_values = user_in_db.select(*[db.auth_user[f] for f in fields]).first().as_dict() + if update_or_insert_values != actual_values: # We don't update record if values are the same + user_in_db.update(**update_or_insert_values) + else: + db.auth_user.insert(**update_or_insert_values) + con.unbind() + + if manage_groups: + if not do_manage_groups(username, password, group_mapping): + return False + return True + except ldap.INVALID_CREDENTIALS as e: + return False + except ldap.LDAPError as e: + import traceback + logger.warning('[%s] Error in ldap processing' % str(username)) + logger.debug(traceback.format_exc()) + return False + except IndexError as ex: # for AD membership test + import traceback + logger.warning('[%s] Ldap result indexing error' % str(username)) + logger.debug(traceback.format_exc()) + return False + + def is_user_in_allowed_groups(username, + password=None, + allowed_groups=allowed_groups): + """ + Figure out if the username is a member of an allowed group + in ldap or not + """ + # + # Get all group name where the user is in actually in ldap + # ######################################################### + ldap_groups_of_the_user = get_user_groups_from_ldap(username, password) + + # search for allowed group names + if not isinstance(allowed_groups, list): + allowed_groups = [allowed_groups] + for group in allowed_groups: + if ldap_groups_of_the_user.count(group) > 0: + # Match + return True + # No match + return False + + def do_manage_groups(username, password=None, group_mapping={}, db=db): + """ + Manage user groups + + Get all user's group from ldap and refresh the already stored + ones in web2py's application database or create new groups + according to ldap. + """ + logger.info('[%s] Manage user groups' % str(username)) + try: + # + # Get all group name where the user is in actually in ldap + # ######################################################### + ldap_groups_of_the_user = get_user_groups_from_ldap( + username, password) + + if group_mapping != {}: + l = [] + for group in ldap_groups_of_the_user: + if group in group_mapping: + l.append(group_mapping[group]) + ldap_groups_of_the_user = l + logger.info("User groups after remapping: %s" % str(l)) + + # + # Get all group name where the user is in actually in local db + # ############################################################# + try: + db_user_id = db(db.auth_user.username == username).select(db.auth_user.id).first().id + except: + try: + db_user_id = db(db.auth_user.email == username).select(db.auth_user.id).first().id + except AttributeError as e: + # + # There is no user in local db + # We create one + # ############################## + try: + db_user_id = db.auth_user.insert(username=username, first_name=username) + except AttributeError as e: + db_user_id = db.auth_user.insert(email=username, first_name=username) + if not db_user_id: + logger.error( + 'There is no username or email for %s!' % username) + raise + # if old pydal version, assume this is a relational database which can do joins + db_can_join = db.can_join() if hasattr(db._adapter, 'can_join') else True + if db_can_join: + db_group_search = \ + db((db.auth_membership.user_id == db_user_id) & + (db.auth_user.id == db.auth_membership.user_id) & + (db.auth_group.id == db.auth_membership.group_id)) + else: + # no joins on NoSQL databases, perform two queries + db_group_search = db(db.auth_membership.user_id == db_user_id) + group_ids = [x.group_id for x in db_group_search.select(db.auth_membership.group_id, distinct=True)] + db_group_search = db(db.auth_group.id.belongs(group_ids)) + db_groups_of_the_user = list() + db_group_id = dict() + + if db_group_search.count() > 0: + for group in db_group_search.select(db.auth_group.id, db.auth_group.role, distinct=True): + db_group_id[group.role] = group.id + db_groups_of_the_user.append(group.role) + logger.debug('db groups of user %s: %s' % (username, str(db_groups_of_the_user))) + + auth_membership_changed = False + # + # Delete user membership from groups where user is not anymore + # ############################################################# + for group_to_del in db_groups_of_the_user: + if ldap_groups_of_the_user.count(group_to_del) == 0: + db((db.auth_membership.user_id == db_user_id) & + (db.auth_membership.group_id == db_group_id[group_to_del])).delete() + auth_membership_changed = True + + # + # Create user membership in groups where user is not in already + # ############################################################## + for group_to_add in ldap_groups_of_the_user: + if db_groups_of_the_user.count(group_to_add) == 0: + if db(db.auth_group.role == group_to_add).count() == 0: + gid = db.auth_group.insert(role=group_to_add, description='Generated from LDAP') + else: + gid = db(db.auth_group.role == group_to_add).select(db.auth_group.id).first().id + db.auth_membership.insert(user_id=db_user_id, group_id=gid) + auth_membership_changed = True + + if auth_membership_changed: + for callback in manage_groups_callback: + callback() + + except: + logger.warning("[%s] Groups are not managed successfully!" % str(username)) + import traceback + logger.debug(traceback.format_exc()) + return False + return True + + def init_ldap(ldap_server=server, + ldap_port=port, + ldap_basedn=base_dn, + ldap_mode=mode, + secure=secure, + cert_path=cert_path, + cert_file=cert_file, + cacert_file=cacert_file, + key_file=key_file): + """ + Inicialize ldap connection + """ + logger.info('[%s] Initialize ldap connection' % str(ldap_server)) + if secure: + if not ldap_port: + ldap_port = 636 + + if self_signed_certificate: + # NOTE : If you have a self-signed SSL Certificate pointing over "port=686" and "secure=True" alone + # will not work, you need also to set "self_signed_certificate=True". + # Ref1: https://onemoretech.wordpress.com/2015/06/25/connecting-to-ldap-over-self-signed-tls-with-python/ + # Ref2: http://bneijt.nl/blog/post/connecting-to-ldaps-with-self-signed-cert-using-python/ + ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) + + if cacert_path: + ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, cacert_path) + + if cacert_file: + ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) + ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, cacert_file) + if cert_file: + ldap.set_option(ldap.OPT_X_TLS_CERTFILE, cert_file) + if key_file: + ldap.set_option(ldap.OPT_X_TLS_KEYFILE, key_file) + + con = ldap.initialize("ldaps://" + ldap_server + ":" + str(ldap_port)) + else: + if not ldap_port: + ldap_port = 389 + con = ldap.initialize( + "ldap://" + ldap_server + ":" + str(ldap_port)) + if tls: + con.start_tls_s() + return con + + def get_user_groups_from_ldap(username, + password=None, + base_dn=base_dn, + ldap_binddn=bind_dn, + ldap_bindpw=bind_pw, + group_dn=group_dn, + group_name_attrib=group_name_attrib, + group_member_attrib=group_member_attrib, + group_filterstr=group_filterstr, + ldap_mode=mode): + """ + Get all group names from ldap where the user is in + """ + logger.info('[%s] Get user groups from ldap' % str(username)) + # + # Get all group name where the user is in actually in ldap + # ######################################################### + # Initialize ldap + if not group_dn: + group_dn = base_dn + con = init_ldap() + logger.debug('Username init: [%s]' % username) + if ldap_mode == 'ad': + # + # Get the AD username + # #################### + if '@' not in username: + domain = [] + for x in base_dn.split(','): + if "DC=" in x.upper(): + domain.append(x.split('=')[-1]) + username = "%s@%s" % (username, '.'.join(domain)) + username_bare = username.split("@")[0] + con.set_option(ldap.OPT_PROTOCOL_VERSION, 3) + # In cases where ForestDnsZones and DomainDnsZones are found, + # result will look like the following: + # ['ldap://ForestDnsZones.domain.com/DC=ForestDnsZones, + # DC=domain,DC=com'] + if ldap_binddn: + # need to search directory with an admin account 1st + con.simple_bind_s(ldap_binddn, ldap_bindpw) + logger.debug('Ldap bind connect...') + else: + # credentials should be in the form of username@domain.tld + con.simple_bind_s(username, password) + logger.debug('Ldap username connect...') + # We have to use the full string + username = \ + con.search_ext_s(base_dn, + ldap.SCOPE_SUBTREE, + "(&(sAMAccountName=%s)(%s))" % (ldap.filter.escape_filter_chars(username_bare), + filterstr), + ["cn"])[0][0] + else: + if ldap_binddn: + # need to search directory with an bind_dn account 1st + con.simple_bind_s(ldap_binddn, ldap_bindpw) + else: + # bind as anonymous + con.simple_bind_s('', '') + + # if username is None, return empty list + if username is None: + return list() + # search for groups where user is in + filter = '(&(%s=%s)(%s))' % (ldap.filter.escape_filter_chars(group_member_attrib), + ldap.filter.escape_filter_chars(username), + group_filterstr) + group_search_result = con.search_s(group_dn, ldap.SCOPE_SUBTREE, filter, [group_name_attrib]) + ldap_groups_of_the_user = list() + for group_row in group_search_result: + group = group_row[1] + if isinstance(group, dict) and group_name_attrib in group: + ldap_groups_of_the_user.extend(group[group_name_attrib]) + + con.unbind() + logger.debug('User groups: %s' % ldap_groups_of_the_user) + return list(ldap_groups_of_the_user) + + if filterstr[0] == '(' and filterstr[-1] == ')': # rfc4515 syntax + filterstr = filterstr[1:-1] # parens added again where used + return ldap_auth_aux diff --git a/web2py/gluon/contrib/login_methods/linkedin_account.py b/web2py/gluon/contrib/login_methods/linkedin_account.py new file mode 100644 index 0000000..07cb9a0 --- /dev/null +++ b/web2py/gluon/contrib/login_methods/linkedin_account.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +This file is part of web2py Web Framework (Copyrighted, 2007-2009). +Developed by Massimo Di Pierro . +License: GPL v2 + +Thanks to Hans Donner for GaeGoogleAccount. +""" + +from gluon.http import HTTP +try: + import linkedin +except ImportError: + raise HTTP(400, "linkedin module not found") + + +class LinkedInAccount(object): + """ + Login will be done via Google's Appengine login object, instead of web2py's + login form. + + Include in your model (eg db.py):: + + from gluon.contrib.login_methods.linkedin_account import LinkedInAccount + auth.settings.login_form=LinkedInAccount(request,KEY,SECRET,RETURN_URL) + + """ + + def __init__(self, request, key, secret, return_url): + self.request = request + self.api = linkedin.LinkedIn(key, secret, return_url) + self.token = result = self.api.requestToken() + + def login_url(self, next="/"): + return self.api.getAuthorizeURL(self.token) + + def logout_url(self, next="/"): + return '' + + def get_user(self): + result = self.request.vars.verifier and self.api.accessToken( + verifier=self.request.vars.verifier) + if result: + profile = self.api.GetProfile() + profile = self.api.GetProfile( + profile).public_url = "http://www.linkedin.com/in/ozgurv" + return dict(first_name=profile.first_name, + last_name=profile.last_name, + username=profile.id) diff --git a/web2py/gluon/contrib/login_methods/loginradius_account.py b/web2py/gluon/contrib/login_methods/loginradius_account.py new file mode 100644 index 0000000..462410d --- /dev/null +++ b/web2py/gluon/contrib/login_methods/loginradius_account.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# coding: utf8 + +""" + LoginRadius Authentication for web2py + Developed by Nathan Freeze (Copyright © 2013) + Email + + This file contains code to allow using loginradius.com + authentication services with web2py +""" + +import os +from gluon import * +from gluon.storage import Storage +from gluon.tools import fetch +import json + + +class LoginRadiusAccount(object): + """ + from gluon.contrib.login_methods.loginradius_account import LoginRadiusAccount + auth.settings.actions_disabled=['register','change_password', + 'request_reset_password'] + auth.settings.login_form = LoginRadiusAccount(request, + api_key="...", + api_secret="...", + url = "http://localhost:8000/%s/default/user/login" % request.application) + """ + + def __init__(self, request, api_key="", api_secret="", + url="", on_login_failure=None): + + self.request = request + self.api_key = api_key + self.api_secret = api_secret + self.url = url + self.auth_base_url = "https://hub.loginradius.com/UserProfile.ashx/" + self.profile = None + self.on_login_failure = on_login_failure + self.mappings = Storage() + + def defaultmapping(profile): + first_name = profile.get('FirstName') + last_name = profile.get('LastName') + email = profile.get('Email', [{}])[0].get('Value') + reg_id = profile.get('ID', '') + username = profile.get('ProfileName', email) + + return dict(registration_id=reg_id, username=username, email=email, + first_name=first_name, last_name=last_name) + + self.mappings.default = defaultmapping + + def get_user(self): + request = self.request + user = None + if request.vars.token: + try: + auth_url = self.auth_base_url + self.api_secret + "/" + request.vars.token + json_data = fetch(auth_url, headers={'User-Agent': "LoginRadius - Python - SDK"}) + self.profile = json.loads(json_data) + provider = self.profile['Provider'] + mapping = self.mappings.get(provider, self.mappings['default']) + user = mapping(self.profile) + except (ValueError, KeyError): + pass + if user is None and self.on_login_failure: + redirect(self.on_login_failure) + return user + + def login_form(self): + loginradius_url = "https://hub.loginradius.com/include/js/LoginRadius.js" + loginradius_lib = SCRIPT(_src=loginradius_url, _type='text/javascript') + container = DIV(_id="interfacecontainerdiv", _class='interfacecontainerdiv') + widget = SCRIPT("""var options={}; options.login=true; + LoginRadius_SocialLogin.util.ready(function () { + $ui = LoginRadius_SocialLogin.lr_login_settings; + $ui.interfacesize = "";$ui.apikey = "%s"; + $ui.callback="%s"; $ui.lrinterfacecontainer ="interfacecontainerdiv"; + LoginRadius_SocialLogin.init(options); });""" % (self.api_key, self.url)) + form = DIV(container, loginradius_lib, widget) + return form + + +def use_loginradius(auth, filename='private/loginradius.key', **kwargs): + path = os.path.join(current.request.folder, filename) + if os.path.exists(path): + request = current.request + domain, public_key, private_key = open(path, 'r').read().strip().split(':') + url = URL('default', 'user', args='login', scheme=True) + auth.settings.actions_disabled = \ + ['register', 'change_password', 'request_reset_password'] + auth.settings.login_form = LoginRadiusAccount( + request, api_key=public_key, api_secret=private_key, + url=url, **kwargs) diff --git a/web2py/gluon/contrib/login_methods/loginza.py b/web2py/gluon/contrib/login_methods/loginza.py new file mode 100644 index 0000000..4674136 --- /dev/null +++ b/web2py/gluon/contrib/login_methods/loginza.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" + Loginza.ru authentication for web2py + Developed by Vladimir Dronnikov (Copyright © 2011) + Email +""" + +import urllib +from gluon.html import * +from gluon.tools import fetch +from gluon.storage import Storage +import json + + +class Loginza(object): + + """ + from gluon.contrib.login_methods.loginza import Loginza + auth.settings.login_form = Loginza(request, + url = "http://localhost:8000/%s/default/user/login" % request.application) + """ + + def __init__(self, + request, + url="", + embed=True, + auth_url="http://loginza.ru/api/authinfo", + language="en", + prompt="loginza", + on_login_failure=None, + ): + + self.request = request + self.token_url = url + self.embed = embed + self.auth_url = auth_url + self.language = language + self.prompt = prompt + self.profile = None + self.on_login_failure = on_login_failure + self.mappings = Storage() + + # TODO: profile.photo is the URL to the picture + # Howto download and store it locally? + # FIXME: what if email is unique=True + + self.mappings["http://twitter.com/"] = lambda profile:\ + dict(registration_id=profile.get("identity", ""), + username=profile.get("nickname", ""), + email=profile.get("email", ""), + last_name=profile.get("name", "").get("full_name", ""), + #avatar = profile.get("photo",""), + ) + self.mappings["https://www.google.com/accounts/o8/ud"] = lambda profile:\ + dict(registration_id=profile.get("identity", ""), + username=profile.get("name", "").get("full_name", ""), + email=profile.get("email", ""), + first_name=profile.get("name", "").get("first_name", ""), + last_name=profile.get("name", "").get("last_name", ""), + #avatar = profile.get("photo",""), + ) + self.mappings["http://vkontakte.ru/"] = lambda profile:\ + dict(registration_id=profile.get("identity", ""), + username=profile.get("name", "").get("full_name", ""), + email=profile.get("email", ""), + first_name=profile.get("name", "").get("first_name", ""), + last_name=profile.get("name", "").get("last_name", ""), + #avatar = profile.get("photo",""), + ) + self.mappings.default = lambda profile:\ + dict(registration_id=profile.get("identity", ""), + username=profile.get("name", "").get("full_name"), + email=profile.get("email", ""), + first_name=profile.get("name", "").get("first_name", ""), + last_name=profile.get("name", "").get("last_name", ""), + #avatar = profile.get("photo",""), + ) + + def get_user(self): + request = self.request + if request.vars.token: + user = Storage() + data = urllib.urlencode(dict(token=request.vars.token)) + auth_info_json = fetch(self.auth_url + '?' + data) + # print auth_info_json + auth_info = json.loads(auth_info_json) + if auth_info["identity"] is not None: + self.profile = auth_info + provider = self.profile["provider"] + user = self.mappings.get( + provider, self.mappings.default)(self.profile) + # user["password"] = ??? + # user["avatar"] = ??? + return user + elif self.on_login_failure: + redirect(self.on_login_failure) + return None + + def login_form(self): + request = self.request + args = request.args + LOGINZA_URL = "https://loginza.ru/api/widget?lang=%s&token_url=%s&overlay=loginza" + if self.embed: + form = IFRAME(_src=LOGINZA_URL % (self.language, self.token_url), + _scrolling="no", + _frameborder="no", + _style="width:359px;height:300px;") + else: + form = DIV( + A(self.prompt, _href=LOGINZA_URL % ( + self.language, self.token_url), _class="loginza"), + SCRIPT(_src="https://s3-eu-west-1.amazonaws.com/s1.loginza.ru/js/widget.js", _type="text/javascript")) + return form diff --git a/web2py/gluon/contrib/login_methods/motp_auth.py b/web2py/gluon/contrib/login_methods/motp_auth.py new file mode 100644 index 0000000..aad9d27 --- /dev/null +++ b/web2py/gluon/contrib/login_methods/motp_auth.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python + +import time +from hashlib import md5 +from gluon.dal import DAL + + +def motp_auth(db=DAL('sqlite://storage.sqlite'), + time_offset=60): + + """ + motp allows you to login with a one time password(OTP) generated on a motp client, + motp clients are available for practically all platforms. + to know more about OTP visit http://en.wikipedia.org/wiki/One-time_password + to know more visit http://motp.sourceforge.net + + + Written by Madhukar R Pai (madspai@gmail.com) + License : MIT or GPL v2 + + thanks and credits to the web2py community + + to use motp_auth: + motp_auth.py has to be located in gluon/contrib/login_methods/ folder + first auth_user has to have 2 extra fields - motp_secret and motp_pin + for that define auth like shown below: + + ## after auth = Auth(db) + db.define_table( + auth.settings.table_user_name, + Field('first_name', length=128, default=''), + Field('last_name', length=128, default=''), + Field('email', length=128, default='', unique=True), # required + Field('password', 'password', length=512, # required + readable=False, label='Password'), + Field('motp_secret',length=512,default='', + label='MOTP Seceret'), + Field('motp_pin',length=128,default='', + label='MOTP PIN'), + Field('registration_key', length=512, # required + writable=False, readable=False, default=''), + Field('reset_password_key', length=512, # required + writable=False, readable=False, default=''), + Field('registration_id', length=512, # required + writable=False, readable=False, default='')) + + ##validators + custom_auth_table = db[auth.settings.table_user_name] + # get the custom_auth_table + custom_auth_table.first_name.requires = \ + IS_NOT_EMPTY(error_message=auth.messages.is_empty) + custom_auth_table.last_name.requires = \ + IS_NOT_EMPTY(error_message=auth.messages.is_empty) + custom_auth_table.password.requires = CRYPT() + custom_auth_table.email.requires = [ + IS_EMAIL(error_message=auth.messages.invalid_email), + IS_NOT_IN_DB(db, custom_auth_table.email)] + + auth.settings.table_user = custom_auth_table # tell auth to use custom_auth_table + ## before auth.define_tables() + + ##after that: + + from gluon.contrib.login_methods.motp_auth import motp_auth + auth.settings.login_methods.append(motp_auth(db=db)) + + ##Instructions for using MOTP + - after configuring motp for web2py, Install a MOTP client on your phone (android,IOS, java, windows phone, etc) + - initialize the motp client (to reset a motp secret type in #**#), + During user creation enter the secret generated during initialization into the motp_secret field in auth_user and + similarly enter a pre-decided pin into the motp_pin + - done.. to login, just generate a fresh OTP by typing in the pin and use the OTP as password + + ###To Dos### + - both motp_secret and pin are stored in plain text! need to have some way of encrypting + - web2py stores the password in db on successful login (should not happen) + - maybe some utility or page to check the otp would be useful + - as of now user field is hardcoded to email. Some way of selecting user table and user field. + """ + + def verify_otp(otp, pin, secret, offset=60): + epoch_time = int(time.time()) + time_start = int(str(epoch_time - offset)[:-1]) + time_end = int(str(epoch_time + offset)[:-1]) + for t in range(time_start - 1, time_end + 1): + to_hash = str(t) + secret + pin + hash = md5(to_hash).hexdigest()[:6] + if otp == hash: + return True + return False + + def motp_auth_aux(email, + password, + db=db, + offset=time_offset): + if db: + user_data = db(db.auth_user.email == email).select().first() + if user_data: + if user_data['motp_secret'] and user_data['motp_pin']: + motp_secret = user_data['motp_secret'] + motp_pin = user_data['motp_pin'] + otp_check = verify_otp( + password, motp_pin, motp_secret, offset=offset) + if otp_check: + return True + else: + return False + else: + return False + return False + return motp_auth_aux diff --git a/web2py/gluon/contrib/login_methods/oauth10a_account.py b/web2py/gluon/contrib/login_methods/oauth10a_account.py new file mode 100644 index 0000000..d981da8 --- /dev/null +++ b/web2py/gluon/contrib/login_methods/oauth10a_account.py @@ -0,0 +1,184 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Written by Michele Comitini +License: LGPL v3 + +Adds support for OAuth1.0a authentication to web2py. + +Dependencies: + - python-oauth2 (http://github.com/simplegeo/python-oauth2) + +""" + +import oauth2 as oauth +import cgi + +from urllib import urlencode + +from gluon import current + +class OAuthAccount(object): + """ + Login will be done via OAuth Framework, instead of web2py's + login form. + + Include in your model (eg db.py):: + # define the auth_table before call to auth.define_tables() + auth_table = db.define_table( + auth.settings.table_user_name, + Field('first_name', length=128, default=""), + Field('last_name', length=128, default=""), + Field('username', length=128, default="", unique=True), + Field('password', 'password', length=256, + readable=False, label='Password'), + Field('registration_key', length=128, default= "", + writable=False, readable=False)) + + auth_table.username.requires = IS_NOT_IN_DB(db, auth_table.username) + . + . + . + auth.define_tables() + . + . + . + + CLIENT_ID=\"\" + CLIENT_SECRET=\"\" + AUTH_URL="..." + TOKEN_URL="..." + ACCESS_TOKEN_URL="..." + from gluon.contrib.login_methods.oauth10a_account import OAuthAccount + auth.settings.login_form=OAuthAccount(globals( + ),CLIENT_ID,CLIENT_SECRET, AUTH_URL, TOKEN_URL, ACCESS_TOKEN_URL) + + """ + + def __redirect_uri(self, next=None): + """Build the uri used by the authenticating server to redirect + the client back to the page originating the auth request. + Appends the _next action to the generated url so the flows continues. + """ + r = self.request + http_host = r.env.http_host + + url_scheme = r.env.wsgi_url_scheme + if next: + path_info = next + else: + path_info = r.env.path_info + uri = '%s://%s%s' % (url_scheme, http_host, path_info) + if r.get_vars and not next: + uri += '?' + urlencode(r.get_vars) + return uri + + def accessToken(self): + """Return the access token generated by the authenticating server. + + If token is already in the session that one will be used. + Otherwise the token is fetched from the auth server. + + """ + + if self.session.access_token: + # return the token (TODO: does it expire?) + + return self.session.access_token + if self.session.request_token: + # Exchange the request token with an authorization token. + token = self.session.request_token + self.session.request_token = None + + # Build an authorized client + # OAuth1.0a put the verifier! + token.set_verifier(self.request.vars.oauth_verifier) + client = oauth.Client(self.consumer, token) + + resp, content = client.request(self.access_token_url, "POST") + if str(resp['status']) != '200': + self.session.request_token = None + self.globals['redirect'](self.globals[ + 'URL'](f='user', args='logout')) + + self.session.access_token = oauth.Token.from_string(content) + + return self.session.access_token + + self.session.access_token = None + return None + + def __init__(self, g, client_id, client_secret, auth_url, token_url, access_token_url, socket_timeout=60): + self.globals = g + self.client_id = client_id + self.client_secret = client_secret + self.code = None + self.request = current.request + self.session = current.session + self.auth_url = auth_url + self.token_url = token_url + self.access_token_url = access_token_url + self.socket_timeout = socket_timeout + + # consumer init + self.consumer = oauth.Consumer(self.client_id, self.client_secret) + + def login_url(self, next="/"): + self.__oauth_login(next) + return next + + def logout_url(self, next="/"): + self.session.request_token = None + self.session.access_token = None + return next + + def get_user(self): + '''Get user data. + + Since OAuth does not specify what a user + is, this function must be implemented for the specific + provider. + ''' + raise NotImplementedError("Must override get_user()") + + def __oauth_login(self, next): + '''This method redirects the user to the authenticating form + on authentication server if the authentication code + and the authentication token are not available to the + application yet. + + Once the authentication code has been received this method is + called to set the access token into the session by calling + accessToken() + ''' + + if not self.accessToken(): + # setup the client + client = oauth.Client(self.consumer, None, timeout=self.socket_timeout) + # Get a request token. + # oauth_callback *is REQUIRED* for OAuth1.0a + # putting it in the body seems to work. + callback_url = self.__redirect_uri(next) + data = urlencode(dict(oauth_callback=callback_url)) + resp, content = client.request(self.token_url, "POST", body=data) + if resp['status'] != '200': + self.session.request_token = None + self.globals['redirect'](self.globals[ + 'URL'](f='user', args='logout')) + + # Store the request token in session. + request_token = self.session.request_token = oauth.Token.from_string(content) + + # Redirect the user to the authentication URL and pass the callback url. + data = urlencode(dict(oauth_token=request_token.key, + oauth_callback=callback_url)) + auth_request_url = self.auth_url + '?' + data + + HTTP = self.globals['HTTP'] + + raise HTTP(302, + "You are not authenticated: you are being redirected to the authentication server", + Location=auth_request_url) + + return None diff --git a/web2py/gluon/contrib/login_methods/oauth20_account.py b/web2py/gluon/contrib/login_methods/oauth20_account.py new file mode 100644 index 0000000..dca6173 --- /dev/null +++ b/web2py/gluon/contrib/login_methods/oauth20_account.py @@ -0,0 +1,303 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Written by Michele Comitini +License: LGPL v3 + +Adds support for OAuth 2.0 authentication to web2py. + +OAuth 2.0 spec: http://tools.ietf.org/html/rfc6749 + +""" + +import time +import cgi +import urllib2 + +from urllib import urlencode +from gluon import current, redirect, HTTP + +import json + +class OAuthAccount(object): + """ + Login will be done via OAuth Framework, instead of web2py's + login form. + + You need to override the get_user method to match your auth provider needs. + Example for facebook in your model (eg db.py):: + # define the auth_table before call to auth.define_tables() + auth_table = db.define_table( + auth.settings.table_user_name, + Field('first_name', length=128, default=""), + Field('last_name', length=128, default=""), + Field('username', length=128, default="", unique=True), + Field('password', 'password', length=256, + readable=False, label='Password'), + Field('registration_key', length=128, default= "", + writable=False, readable=False)) + + auth_table.username.requires = IS_NOT_IN_DB(db, auth_table.username) + auth.define_tables() + + CLIENT_ID=\"\" + CLIENT_SECRET=\"\" + AUTH_URL="http://..." + TOKEN_URL="http://..." + # remember to download and install facebook GraphAPI module in your app + from facebook import GraphAPI, GraphAPIError + from gluon.contrib.login_methods.oauth20_account import OAuthAccount + class FaceBookAccount(OAuthAccount): + '''OAuth impl for FaceBook''' + AUTH_URL="https://graph.facebook.com/oauth/authorize" + TOKEN_URL="https://graph.facebook.com/oauth/access_token" + + def __init__(self): + OAuthAccount.__init__(self, + client_id=CLIENT_ID, + client_secret=CLIENT_SECRET, + auth_url=self.AUTH_URL, + token_url=self.TOKEN_URL, + scope='user_photos,friends_photos') + self.graph = None + + def get_user(self): + ''' + Returns the user using the Graph API. + ''' + + if not self.accessToken(): + return None + + if not self.graph: + self.graph = GraphAPI((self.accessToken())) + + user = None + try: + user = self.graph.get_object("me") + except GraphAPIError, e: + self.session.token = None + self.graph = None + + + if user: + return dict(first_name = user['first_name'], + last_name = user['last_name'], + username = user['id']) + + + auth.settings.actions_disabled=['register', + 'change_password','request_reset_password','profile'] + auth.settings.login_form=FaceBookAccount() + +Any optional arg in the constructor will be passed asis to remote +server for requests. It can be used for the optional"scope" parameters for Facebook. + + """ + def __redirect_uri(self, next=None): + """ + Build the uri used by the authenticating server to redirect + the client back to the page originating the auth request. + Appends the _next action to the generated url so the flows continues. + """ + + r = current.request + http_host = r.env.http_host + + if r.env.https == 'on': + url_scheme = 'https' + else: + url_scheme = r.env.wsgi_url_scheme + if next: + path_info = next + else: + path_info = r.env.path_info + uri = '%s://%s%s' % (url_scheme, http_host, path_info) + if r.get_vars and not next: + uri += '?' + urlencode(r.get_vars) + return uri + + + def __build_url_opener(self, uri): + """ + Build the url opener for managing HTTP Basic Athentication + """ + # Create an OpenerDirector with support + # for Basic HTTP Authentication... + password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() + password_mgr.add_password(realm=None, + uri=uri, + user=self.client_id, + passwd=self.client_secret) + handler = urllib2.HTTPBasicAuthHandler(password_mgr) + opener = urllib2.build_opener(handler) + return opener + + def accessToken(self): + """ + Return the access token generated by the authenticating server. + + If token is already in the session that one will be used. + If token has expired refresh_token is used to get another token. + Otherwise the token is fetched from the auth server. + """ + refresh_token = None + if current.session.token and 'expires' in current.session.token: + expires = current.session.token['expires'] + # reuse token until expiration + if expires == 0 or expires > time.time(): + return current.session.token['access_token'] + if 'refresh_token' in current.session.token: + refresh_token = current.session.token['refresh_token'] + + code = current.request.vars.code + + if code or refresh_token: + data = dict( + client_id=self.client_id, + client_secret=self.client_secret, + ) + if code: + data.update( + redirect_uri=current.session.redirect_uri, + code=code, + grant_type='authorization_code' + ) + elif refresh_token: + data.update( + refresh_token=refresh_token, + grant_type='refresh_token' + ) + + open_url = None + opener = self.__build_url_opener(self.token_url) + try: + open_url = opener.open(self.token_url, urlencode(data), self.socket_timeout) + except urllib2.HTTPError as e: + tmp = e.read() + raise Exception(tmp) + finally: + if current.session.code: + del current.session.code # throw it away + + if open_url: + try: + data = open_url.read() + resp_type = open_url.info().gettype() + # try json style first + if not resp_type or resp_type[:16] == 'application/json': + try: + tokendata = json.loads(data) + current.session.token = tokendata + except Exception as e: + raise Exception("Cannot parse oauth server response %s %s" % (data, e)) + else: # try facebook style first with x-www-form-encoded + tokendata = cgi.parse_qs(data) + current.session.token = \ + dict([(k, v[-1]) for k, v in tokendata.items()]) + if not tokendata: # parsing failed? + raise Exception("Cannot parse oauth server response %s" % data) + # set expiration absolute time try to avoid broken + # implementations where "expires_in" becomes "expires" + if 'expires_in' in current.session.token: + exps = 'expires_in' + elif 'expires' in current.session.token: + exps = 'expires' + else: + exps = None + current.session.token['expires'] = exps and \ + int(current.session.token[exps]) + \ + time.time() + finally: + opener.close() + return current.session.token['access_token'] + + current.session.token = None + return None + + def __init__(self, g=None, + client_id=None, client_secret=None, + auth_url=None, token_url=None, socket_timeout=60, **args): + """ + first argument is unused. Here only for legacy reasons. + """ + if [client_id, client_secret, auth_url, token_url].count(None) > 0: + raise RuntimeError("""Following args are mandatory: + client_id, + client_secret, + auth_url, + token_url. + """) + self.client_id = client_id + self.client_secret = client_secret + self.auth_url = auth_url + self.token_url = token_url + self.args = args + self.socket_timeout = socket_timeout + + def login_url(self, next="/"): + self.__oauth_login(next) + return next + + def logout_url(self, next="/"): + del current.session.token + return next + + def get_user(self): + """ + Override this method by sublcassing the class. + + """ + if not current.session.token: + return None + return dict(first_name='Pinco', + last_name='Pallino', + username='pincopallino') + raise NotImplementedError("Must override get_user()") + + # Following code is never executed. It can be used as example + # for overriding in subclasses. + if not self.accessToken(): + return None + + if not self.graph: + self.graph = GraphAPI((self.accessToken())) + + user = None + try: + user = self.graph.get_object("me") + except GraphAPIError: + current.session.token = None + self.graph = None + + if user: + return dict(first_name=user['first_name'], + last_name=user['last_name'], + username=user['id']) + + def __oauth_login(self, next): + """ + This method redirects the user to the authenticating form + on authentication server if the authentication code + and the authentication token are not available to the + application yet. + + Once the authentication code has been received this method is + called to set the access token into the session by calling + accessToken() + """ + + token = self.accessToken() + if not token: + current.session.redirect_uri = self.__redirect_uri(next) + data = dict(redirect_uri=current.session.redirect_uri, + response_type='code', + client_id=self.client_id) + if self.args: + data.update(self.args) + auth_request_url = self.auth_url + "?" + urlencode(data) + raise HTTP(302, + "You are not authenticated: you are being redirected to the authentication server", + Location=auth_request_url) + return diff --git a/web2py/gluon/contrib/login_methods/oneall_account.py b/web2py/gluon/contrib/login_methods/oneall_account.py new file mode 100644 index 0000000..12311cd --- /dev/null +++ b/web2py/gluon/contrib/login_methods/oneall_account.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# coding: utf8 + +""" + Oneall Authentication for web2py + Developed by Nathan Freeze (Copyright © 2013) + Email + + This file contains code to allow using onall.com + authentication services with web2py +""" + +import os +import base64 +from gluon import * +from gluon.storage import Storage +from gluon.tools import fetch +import json + +class OneallAccount(object): + + """ + from gluon.contrib.login_methods.oneall_account import OneallAccount + auth.settings.actions_disabled=['register','change_password', + 'request_reset_password'] + auth.settings.login_form = OneallAccount(request, + public_key="...", + private_key="...", + domain="...", + url = "http://localhost:8000/%s/default/user/login" % request.application) + """ + + def __init__(self, request, public_key="", private_key="", domain="", + url=None, providers=None, on_login_failure=None): + + self.request = request + self.public_key = public_key + self.private_key = private_key + self.url = url + self.domain = domain + self.profile = None + self.on_login_failure = on_login_failure + self.providers = providers or ["facebook", "google", "yahoo", "openid"] + + self.mappings = Storage() + def defaultmapping(profile): + name = profile.get('name',{}) + dname = name.get('formatted',profile.get('displayName')) + email=profile.get('emails', [{}])[0].get('value') + reg_id=profile.get('identity_token','') + username=profile.get('preferredUsername',email) + first_name=name.get('givenName', dname.split(' ')[0]) + last_name=profile.get('familyName', dname.split(' ')[1] if(dname.count(' ') > 0) else None) + return dict(registration_id=reg_id,username=username,email=email, + first_name=first_name,last_name=last_name) + self.mappings.default = defaultmapping + + def get_user(self): + request = self.request + user = None + if request.vars.connection_token: + auth_url = "https://%s.api.oneall.com/connections/%s.json" % \ + (self.domain, request.vars.connection_token) + auth_pw = "%s:%s" % (self.public_key,self.private_key) + auth_pw = base64.b64encode(auth_pw) + headers = dict(Authorization="Basic %s" % auth_pw) + try: + auth_info_json = fetch(auth_url,headers=headers) + auth_info = json.loads(auth_info_json) + data = auth_info['response']['result']['data'] + if data['plugin']['key'] == 'social_login': + if data['plugin']['data']['status'] == 'success': + userdata = data['user'] + self.profile = userdata['identity'] + source = self.profile['source']['key'] + mapping = self.mappings.get(source,self.mappings['default']) + user = mapping(self.profile) + except (ValueError, KeyError): + pass + if user is None and self.on_login_failure: + redirect(self.on_login_failure) + return user + + def login_form(self): + scheme = self.request.env.wsgi_url_scheme + oneall_url = scheme + "://%s.api.oneall.com/socialize/library.js" % self.domain + oneall_lib = SCRIPT(_src=oneall_url,_type='text/javascript') + container = DIV(_id="oa_social_login_container") + widget = SCRIPT('oneall.api.plugins.social_login.build("oa_social_login_container",', + '{providers : %s,' % self.providers, + 'callback_uri: "%s"});' % self.url, + _type="text/javascript") + form = DIV(oneall_lib,container,widget) + return form + +def use_oneall(auth, filename='private/oneall.key', **kwargs): + path = os.path.join(current.request.folder, filename) + if os.path.exists(path): + request = current.request + domain, public_key, private_key = open(path, 'r').read().strip().split(':') + url = URL('default', 'user', args='login', scheme=True) + auth.settings.actions_disabled =\ + ['register', 'change_password', 'request_reset_password'] + auth.settings.login_form = OneallAccount( + request, public_key=public_key,private_key=private_key, + domain=domain, url=url, **kwargs) diff --git a/web2py/gluon/contrib/login_methods/openid_auth.py b/web2py/gluon/contrib/login_methods/openid_auth.py new file mode 100644 index 0000000..6fd3dbd --- /dev/null +++ b/web2py/gluon/contrib/login_methods/openid_auth.py @@ -0,0 +1,653 @@ +#!/usr/bin/env python +# coding: utf8 + +""" + OpenID authentication for web2py + + Allowed using OpenID login together with web2py built-in login. + + By default, to support OpenID login, put this in your db.py + + >>> from gluon.contrib.login_methods.openid_auth import OpenIDAuth + >>> auth.settings.login_form = OpenIDAuth(auth) + + To show OpenID list in user profile, you can add the following code + before the end of function user() of your_app/controllers/default.py + + + if (request.args and request.args(0) == "profile"): + + form = DIV(form, openid_login_form.list_user_openids()) + return dict(form=form, login_form=login_form, register_form=register_form, self_registration=self_registration) + + More detail in the description of the class OpenIDAuth. + + Requirements: + python-openid version 2.2.5 or later + + Reference: + * w2p openID + http://w2popenid.appspot.com/init/default/wiki/w2popenid + * RPX and web2py auth module + http://www.web2pyslices.com/main/slices/take_slice/28 + * built-in file: gluon/contrib/login_methods/rpx_account.py + * built-in file: gluon/tools.py (Auth class) +""" +import time +from datetime import datetime, timedelta + +from gluon import * +from gluon.storage import Storage, Messages + +try: + import openid.consumer.consumer + from openid.association import Association + from openid.store.interface import OpenIDStore + from openid.extensions.sreg import SRegRequest, SRegResponse + from openid.store import nonce + from openid.consumer.discover import DiscoveryFailure +except ImportError as err: + raise ImportError("OpenIDAuth requires python-openid package") + +DEFAULT = lambda: None + + +class OpenIDAuth(object): + """ + OpenIDAuth + + It supports the logout_url, implementing the get_user and login_form + for cas usage of gluon.tools.Auth. + + It also uses the ExtendedLoginForm to allow the OpenIDAuth login_methods + combined with the standard logon/register procedure. + + It uses OpenID Consumer when render the form and begins the OpenID + authentication. + + Example: (put these code after auth.define_tables() in your models.) + + auth = Auth(globals(), db) # authentication/authorization + ... + auth.define_tables() # creates all needed tables + ... + + #include in your model after auth has been defined + from gluon.contrib.login_methods.openid_auth import OpenIDAuth + openid_login_form = OpenIDAuth(request, auth, db) + + from gluon.contrib.login_methods.extended_login_form import ExtendedLoginForm + extended_login_form = ExtendedLoginForm(request, auth, openid_login_form, + signals=['oid','janrain_nonce']) + + auth.settings.login_form = extended_login_form + """ + + def __init__(self, auth): + self.auth = auth + self.db = auth.db + + request = current.request + self.nextvar = '_next' + self.realm = 'http://%s' % request.env.http_host + self.login_url = URL(r=request, f='user', args=['login']) + self.return_to_url = self.realm + self.login_url + + self.table_alt_logins_name = "alt_logins" + if not auth.settings.table_user: + raise + self.table_user = self.auth.settings.table_user + self.openid_expiration = 15 # minutes + + self.messages = self._define_messages() + + if not self.table_alt_logins_name in self.db.tables: + self._define_alt_login_table() + + def _define_messages(self): + messages = Messages(current.T) + messages.label_alt_login_username = 'Sign-in with OpenID: ' + messages.label_add_alt_login_username = 'Add a new OpenID: ' + messages.submit_button = 'Sign in' + messages.submit_button_add = 'Add' + messages.a_delete = 'Delete' + messages.comment_openid_signin = 'What is OpenID?' + messages.comment_openid_help_title = 'Start using your OpenID' + messages.comment_openid_help_url = 'http://openid.net/get-an-openid/start-using-your-openid/' + messages.openid_fail_discover = 'Failed to discover OpenID service. Check your OpenID or "More about OpenID"?' + messages.flash_openid_expired = 'OpenID expired. Please login or authenticate OpenID again. Sorry for the inconvenient.' + messages.flash_openid_associated = 'OpenID associated' + messages.flash_associate_openid = 'Please login or register an account for this OpenID.' + messages.p_openid_not_registered = "This Open ID haven't be registered. " \ + + "Please login to associate with it or register an account for it." + messages.flash_openid_authenticated = 'OpenID authenticated successfully.' + messages.flash_openid_fail_authentication = 'OpenID authentication failed. (Error message: %s)' + messages.flash_openid_canceled = 'OpenID authentication canceled by user.' + messages.flash_openid_need_setup = 'OpenID authentication needs to be setup by the user with the provider first.' + messages.h_openid_login = 'OpenID Login' + messages.h_openid_list = 'OpenID List' + return messages + + def _define_alt_login_table(self): + """ + Define the OpenID login table. + Note: oidtype is what I used for our project. + We're going to support 'fackbook' and + 'plurk' alternate login methods. + Otherwise it's always 'openid' and you + may not need it. This should be easy to changed. + (Just remove the field of "type" and remove the + "and db.alt_logins.oidtype == type_" + in _find_matched_openid function) + """ + db = self.db + table = db.define_table( + self.table_alt_logins_name, + Field('username', length=512, default=''), + Field('oidtype', length=128, default='openid', readable=False), + Field('oiduser', self.table_user, readable=False), + ) + table.username.requires = IS_NOT_IN_DB(db, table.username) + self.table_alt_logins = table + + def logout_url(self, next): + """ + Delete the w2popenid record in session as logout + """ + if current.session.w2popenid: + del(current.session.w2popenid) + return next + + def login_form(self): + """ + Start to process the OpenID response if 'janrain_nonce' in request parameters + and not processed yet. Else return the OpenID form for login. + """ + request = current.request + if 'janrain_nonce' in request.vars and not self._processed(): + self._process_response() + return self.auth() + return self._form() + + def get_user(self): + """ + It supports the logout_url, implementing the get_user and login_form + for cas usage of gluon.tools.Auth. + """ + request = current.request + args = request.args + + if args[0] == 'logout': + return True # Let logout_url got called + + if current.session.w2popenid: + w2popenid = current.session.w2popenid + db = self.db + if (w2popenid.ok is True and w2popenid.oid): # OpenID authenticated + if self._w2popenid_expired(w2popenid): + del(current.session.w2popenid) + flash = self.messages.flash_openid_expired + current.session.warning = flash + redirect(self.auth.settings.login_url) + oid = self._remove_protocol(w2popenid.oid) + alt_login = self._find_matched_openid(db, oid) + + nextvar = self.nextvar + # This OpenID not in the database. If user logged in then add it + # into database, else ask user to login or register. + if not alt_login: + if self.auth.is_logged_in(): + # TODO: ask first maybe + self._associate_user_openid(self.auth.user, oid) + if current.session.w2popenid: + del(current.session.w2popenid) + current.session.flash = self.messages.flash_openid_associated + if nextvar in request.vars: + redirect(request.vars[nextvar]) + redirect(self.auth.settings.login_next) + + if nextvar not in request.vars: + # no next var, add it and do login again + # so if user login or register can go back here to associate the OpenID + redirect(URL(r=request, + args=['login'], + vars={nextvar: self.login_url})) + self.login_form = self._form_with_notification() + current.session.flash = self.messages.flash_associate_openid + return None # need to login or register to associate this openid + + # Get existed OpenID user + user = db( + self.table_user.id == alt_login.oiduser).select().first() + if user: + if current.session.w2popenid: + del(current.session.w2popenid) + if 'username' in self.table_user.fields(): + username = 'username' + elif 'email' in self.table_user.fields(): + username = 'email' + return {username: user[username]} if user else None # login success (almost) + + return None # just start to login + + def _find_matched_openid(self, db, oid, type_='openid'): + """ + Get the matched OpenID for given + """ + query = ( + (db.alt_logins.username == oid) & (db.alt_logins.oidtype == type_)) + alt_login = db(query).select().first() # Get the OpenID record + return alt_login + + def _associate_user_openid(self, user, oid): + """ + Associate the user logged in with given OpenID + """ + # print "[DB] %s authenticated" % oid + self.db.alt_logins.insert(username=oid, oiduser=user.id) + + def _form_with_notification(self): + """ + Render the form for normal login with a notice of OpenID authenticated + """ + form = DIV() + # TODO: check when will happen + if self.auth.settings.login_form in (self.auth, self): + self.auth.settings.login_form = self.auth + form = DIV(self.auth()) + + register_note = DIV(P(self.messages.p_openid_not_registered)) + form.components.append(register_note) + return lambda: form + + def _remove_protocol(self, oid): + """ + Remove https:// or http:// from oid url + """ + protocol = 'https://' + if oid.startswith(protocol): + oid = oid[len(protocol):] + return oid + protocol = 'http://' + if oid.startswith(protocol): + oid = oid[len(protocol):] + return oid + return oid + + def _init_consumerhelper(self): + """ + Initialize the ConsumerHelper + """ + if not hasattr(self, "consumerhelper"): + self.consumerhelper = ConsumerHelper(current.session, + self.db) + return self.consumerhelper + + def _form(self, style=None): + form = DIV(H3(self.messages.h_openid_login), self._login_form(style)) + return form + + def _login_form(self, + openid_field_label=None, + submit_button=None, + _next=None, + style=None): + """ + Render the form for OpenID login + """ + def warning_openid_fail(session): + session.warning = messages.openid_fail_discover + + style = style or """ +background-attachment: scroll; +background-repeat: no-repeat; +background-image: url("http://wiki.openid.net/f/openid-16x16.gif"); +background-position: 0% 50%; +background-color: transparent; +padding-left: 18px; +width: 400px; +""" + style = style.replace("\n", "") + + request = current.request + session = current.session + messages = self.messages + hidden_next_input = "" + if _next == 'profile': + profile_url = URL(r=request, f='user', args=['profile']) + hidden_next_input = INPUT( + _type="hidden", _name="_next", _value=profile_url) + form = FORM( + openid_field_label or self.messages.label_alt_login_username, + INPUT(_type="input", _name="oid", + requires=IS_NOT_EMPTY( + error_message=messages.openid_fail_discover), + _style=style), + hidden_next_input, + INPUT(_type="submit", + _value=submit_button or messages.submit_button), + " ", + A(messages.comment_openid_signin, + _href=messages.comment_openid_help_url, + _title=messages.comment_openid_help_title, + _class='openid-identifier', + _target="_blank"), + _action=self.login_url + ) + if form.accepts(request.vars, session): + oid = request.vars.oid + consumerhelper = self._init_consumerhelper() + url = self.login_url + return_to_url = self.return_to_url + if not oid: + warning_openid_fail(session) + redirect(url) + try: + if '_next' in request.vars: + return_to_url = self.return_to_url + \ + '?_next=' + request.vars._next + url = consumerhelper.begin(oid, self.realm, return_to_url) + except DiscoveryFailure: + warning_openid_fail(session) + redirect(url) + return form + + def _processed(self): + """ + Check if w2popenid authentication is processed. + Return True if processed else False. + """ + processed = (hasattr(current.session, 'w2popenid') and + current.session.w2popenid.ok is True) + return processed + + def _set_w2popenid_expiration(self, w2popenid): + """ + Set expiration for OpenID authentication. + """ + w2popenid.expiration = datetime.now( + ) + timedelta(minutes=self.openid_expiration) + + def _w2popenid_expired(self, w2popenid): + """ + Check if w2popenid authentication is expired. + Return True if expired else False. + """ + return (not w2popenid.expiration) or (datetime.now() > w2popenid.expiration) + + def _process_response(self): + """ + Process the OpenID by ConsumerHelper. + """ + request = current.request + request_vars = request.vars + consumerhelper = self._init_consumerhelper() + process_status = consumerhelper.process_response( + request_vars, self.return_to_url) + if process_status == "success": + w2popenid = current.session.w2popenid + user_data = self.consumerhelper.sreg() + current.session.w2popenid.ok = True + self._set_w2popenid_expiration(w2popenid) + w2popenid.user_data = user_data + current.session.flash = self.messages.flash_openid_authenticated + elif process_status == "failure": + flash = self.messages.flash_openid_fail_authentication % consumerhelper.error_message + current.session.warning = flash + elif process_status == "cancel": + current.session.warning = self.messages.flash_openid_canceled + elif process_status == "setup_needed": + current.session.warning = self.messages.flash_openid_need_setup + + def list_user_openids(self): + messages = self.messages + request = current.request + if 'delete_openid' in request.vars: + self.remove_openid(request.vars.delete_openid) + + query = self.db.alt_logins.oiduser == self.auth.user.id + alt_logins = self.db(query).select() + l = [] + for alt_login in alt_logins: + username = alt_login.username + delete_href = URL(r=request, f='user', + args=['profile'], + vars={'delete_openid': username}) + delete_link = A(messages.a_delete, _href=delete_href) + l.append(LI(username, " ", delete_link)) + + profile_url = URL(r=request, f='user', args=['profile']) + #return_to_url = self.return_to_url + '?' + self.nextvar + '=' + profile_url + openid_list = DIV(H3(messages.h_openid_list), UL(l), + self._login_form( + _next='profile', + submit_button=messages.submit_button_add, + openid_field_label=messages.label_add_alt_login_username) + ) + return openid_list + + def remove_openid(self, openid): + query = self.db.alt_logins.username == openid + self.db(query).delete() + + +class ConsumerHelper(object): + """ + ConsumerHelper knows the python-openid and + """ + + def __init__(self, session, db): + self.session = session + store = self._init_store(db) + self.consumer = openid.consumer.consumer.Consumer(session, store) + + def _init_store(self, db): + """ + Initialize Web2pyStore + """ + if not hasattr(self, "store"): + store = Web2pyStore(db) + session = self.session + if 'w2popenid' not in session: + session.w2popenid = Storage() + self.store = store + return self.store + + def begin(self, oid, realm, return_to_url): + """ + Begin the OpenID authentication + """ + w2popenid = self.session.w2popenid + w2popenid.oid = oid + auth_req = self.consumer.begin(oid) + auth_req.addExtension(SRegRequest(required=['email', 'nickname'])) + url = auth_req.redirectURL(return_to=return_to_url, realm=realm) + return url + + def process_response(self, request_vars, return_to_url): + """ + Complete the process and + """ + resp = self.consumer.complete(request_vars, return_to_url) + if resp: + if resp.status == openid.consumer.consumer.SUCCESS: + self.resp = resp + if hasattr(resp, "identity_url"): + self.session.w2popenid.oid = resp.identity_url + return "success" + if resp.status == openid.consumer.consumer.FAILURE: + self.error_message = resp.message + return "failure" + if resp.status == openid.consumer.consumer.CANCEL: + return "cancel" + if resp.status == openid.consumer.consumer.SETUP_NEEDED: + return "setup_needed" + return "no resp" + + def sreg(self): + """ + Try to get OpenID Simple Registation + http://openid.net/specs/openid-simple-registration-extension-1_0.html + """ + if self.resp: + resp = self.resp + sreg_resp = SRegResponse.fromSuccessResponse(resp) + return sreg_resp.data if sreg_resp else None + else: + return None + + +class Web2pyStore(OpenIDStore): + """ + Web2pyStore + + This class implements the OpenIDStore interface. OpenID stores take care + of persisting nonces and associations. The Janrain Python OpenID library + comes with implementations for file and memory storage. Web2pyStore uses + the web2py db abstration layer. See the source code docs of OpenIDStore + for a comprehensive description of this interface. + """ + + def __init__(self, database): + self.database = database + self.table_oid_associations_name = 'oid_associations' + self.table_oid_nonces_name = 'oid_nonces' + self._initDB() + + def _initDB(self): + + if self.table_oid_associations_name not in self.database: + self.database.define_table(self.table_oid_associations_name, + Field('server_url', + 'string', length=2047, required=True), + Field('handle', + 'string', length=255, required=True), + Field('secret', 'blob', required=True), + Field('issued', + 'integer', required=True), + Field('lifetime', + 'integer', required=True), + Field('assoc_type', + 'string', length=64, required=True) + ) + if self.table_oid_nonces_name not in self.database: + self.database.define_table(self.table_oid_nonces_name, + Field('server_url', + 'string', length=2047, required=True), + Field('itimestamp', + 'integer', required=True), + Field('salt', 'string', + length=40, required=True) + ) + + def storeAssociation(self, server_url, association): + """ + Store associations. If there already is one with the same + server_url and handle in the table replace it. + """ + + db = self.database + query = (db.oid_associations.server_url == server_url) & ( + db.oid_associations.handle == association.handle) + db(query).delete() + db.oid_associations.insert(server_url=server_url, + handle=association.handle, + secret=association.secret, + issued=association.issued, + lifetime=association.lifetime, + assoc_type=association.assoc_type), 'insert ' * 10 + + def getAssociation(self, server_url, handle=None): + """ + Return the association for server_url and handle. If handle is + not None return the latests associations for that server_url. + Return None if no association can be found. + """ + + db = self.database + query = (db.oid_associations.server_url == server_url) + if handle: + query &= (db.oid_associations.handle == handle) + rows = db(query).select(orderby=db.oid_associations.issued) + keep_assoc, _ = self._removeExpiredAssocations(rows) + if len(keep_assoc) == 0: + return None + else: + assoc = keep_assoc.pop( + ) # pop the last one as it should be the latest one + return Association(assoc['handle'], + assoc['secret'], + assoc['issued'], + assoc['lifetime'], + assoc['assoc_type']) + + def removeAssociation(self, server_url, handle): + db = self.database + query = (db.oid_associations.server_url == server_url) & ( + db.oid_associations.handle == handle) + return db(query).delete() is not None + + def useNonce(self, server_url, timestamp, salt): + """ + This method returns Falase if a nonce has been used before or its + timestamp is not current. + """ + + db = self.database + if abs(timestamp - time.time()) > nonce.SKEW: + return False + query = (db.oid_nonces.server_url == server_url) & (db.oid_nonces.itimestamp == timestamp) & (db.oid_nonces.salt == salt) + if db(query).count() > 0: + return False + else: + db.oid_nonces.insert(server_url=server_url, + itimestamp=timestamp, + salt=salt) + return True + + def _removeExpiredAssocations(self, rows): + """ + This helper function is not part of the interface. Given a list of + association rows it checks which associations have expired and + deletes them from the db. It returns a tuple of the form + ([valid_assoc], no_of_expired_assoc_deleted). + """ + + db = self.database + keep_assoc = [] + remove_assoc = [] + t1970 = time.time() + for r in rows: + if r['issued'] + r['lifetime'] < t1970: + remove_assoc.append(r) + else: + keep_assoc.append(r) + for r in remove_assoc: + del db.oid_associations[r['id']] + return (keep_assoc, len(remove_assoc)) # return tuple (list of valid associations, number of deleted associations) + + def cleanupNonces(self): + """ + Remove expired nonce entries from DB and return the number + of entries deleted. + """ + + db = self.database + query = (db.oid_nonces.itimestamp < time.time() - nonce.SKEW) + return db(query).delete() + + def cleanupAssociations(self): + """ + Remove expired associations from db and return the number + of entries deleted. + """ + + db = self.database + query = (db.oid_associations.id > 0) + return self._removeExpiredAssocations(db(query).select())[1] # return number of assoc removed + + def cleanup(self): + """ + This method should be run periodically to free the db from + expired nonce and association entries. + """ + + return self.cleanupNonces(), self.cleanupAssociations() diff --git a/web2py/gluon/contrib/login_methods/pam_auth.py b/web2py/gluon/contrib/login_methods/pam_auth.py new file mode 100644 index 0000000..03564bf --- /dev/null +++ b/web2py/gluon/contrib/login_methods/pam_auth.py @@ -0,0 +1,22 @@ +from gluon.contrib.pam import authenticate + + +def pam_auth(): + """ + to use pam_login: + from gluon.contrib.login_methods.pam_auth import pam_auth + auth.settings.login_methods.append(pam_auth()) + + or + + auth.settings.actions_disabled=[ + 'register','change_password','request_reset_password'] + auth.settings.login_methods=[pam_auth()] + + The latter method will not store the user password in auth_user. + """ + + def pam_auth_aux(username, password): + return authenticate(username, password) + + return pam_auth_aux diff --git a/web2py/gluon/contrib/login_methods/rpx_account.py b/web2py/gluon/contrib/login_methods/rpx_account.py new file mode 100644 index 0000000..e79d17d --- /dev/null +++ b/web2py/gluon/contrib/login_methods/rpx_account.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python +# coding: utf8 + +""" + RPX Authentication for web2py + Developed by Nathan Freeze (Copyright © 2009) + Email + Modified by Massimo Di Pierro + + This file contains code to allow using RPXNow.com (now Jainrain.com) + services with web2py +""" + +import os +import re +from gluon import * +from gluon.tools import fetch +from gluon.storage import Storage +import json +from gluon._compat import urlencode + +class RPXAccount(object): + + """ + from gluon.contrib.login_methods.rpx_account import RPXAccount + auth.settings.actions_disabled=['register','change_password', + 'request_reset_password'] + auth.settings.login_form = RPXAccount(request, + api_key="...", + domain="...", + url = "http://localhost:8000/%s/default/user/login" % request.application) + """ + + def __init__(self, + request, + api_key="", + domain="", + url="", + embed=True, + auth_url="https://rpxnow.com/api/v2/auth_info", + language="en", + prompt='rpx', + on_login_failure=None, + ): + + self.request = request + self.api_key = api_key + self.embed = embed + self.auth_url = auth_url + self.domain = domain + self.token_url = url + self.language = language + self.profile = None + self.prompt = prompt + self.on_login_failure = on_login_failure + self.mappings = Storage() + + dn = {'givenName': '', 'familyName': ''} + self.mappings.Facebook = lambda profile, dn=dn:\ + dict(registration_id=profile.get("identifier", ""), + username=profile.get("preferredUsername", ""), + email=profile.get("email", ""), + first_name=profile.get("name", dn).get("givenName", ""), + last_name=profile.get("name", dn).get("familyName", "")) + self.mappings.Google = lambda profile, dn=dn:\ + dict(registration_id=profile.get("identifier", ""), + username=profile.get("preferredUsername", ""), + email=profile.get("email", ""), + first_name=profile.get("name", dn).get("givenName", ""), + last_name=profile.get("name", dn).get("familyName", "")) + self.mappings.default = lambda profile:\ + dict(registration_id=profile.get("identifier", ""), + username=profile.get("preferredUsername", ""), + email=profile.get("email", ""), + first_name=profile.get("preferredUsername", ""), + last_name='') + + def get_user(self): + request = self.request + # Janrain now sends the token via both a POST body and the query + # string, so we should keep only one of these. + token = request.post_vars.token or request.get_vars.token + if token: + user = Storage() + data = urlencode( + dict(apiKey=self.api_key, token=token)) + auth_info_json = fetch(self.auth_url + '?' + data) + auth_info = json.loads(auth_info_json) + + if auth_info['stat'] == 'ok': + self.profile = auth_info['profile'] + provider = re.sub('[^\w\-]', '', self.profile['providerName']) + user = self.mappings.get( + provider, self.mappings.default)(self.profile) + return user + elif self.on_login_failure: + redirect(self.on_login_failure) + return None + + def login_form(self): + request = self.request + args = request.args + if self.embed: + JANRAIN_URL = \ + "https://%s.rpxnow.com/openid/embed?token_url=%s&language_preference=%s" + rpxform = IFRAME( + _src=JANRAIN_URL % ( + self.domain, self.token_url, self.language), + _scrolling="no", + _frameborder="no", + _style="width:400px;height:240px;") + else: + JANRAIN_URL = \ + "https://%s.rpxnow.com/openid/v2/signin?token_url=%s" + rpxform = DIV(SCRIPT(_src="https://rpxnow.com/openid/v2/widget", + _type="text/javascript"), + SCRIPT("RPXNOW.overlay = true;", + "RPXNOW.language_preference = '%s';" % self.language, + "RPXNOW.realm = '%s';" % self.domain, + "RPXNOW.token_url = '%s';" % self.token_url, + "RPXNOW.show();", + _type="text/javascript")) + return rpxform + + +def use_janrain(auth, filename='private/janrain.key', **kwargs): + path = os.path.join(current.request.folder, filename) + if os.path.exists(path): + request = current.request + domain, key = open(path, 'r').read().strip().split(':') + host = current.request.env.http_host + url = URL('default', 'user', args='login', scheme=True) + auth.settings.actions_disabled = \ + ['register', 'change_password', 'request_reset_password'] + auth.settings.login_form = RPXAccount( + request, api_key=key, domain=domain, url=url, **kwargs) diff --git a/web2py/gluon/contrib/login_methods/saml2_auth.py b/web2py/gluon/contrib/login_methods/saml2_auth.py new file mode 100644 index 0000000..ea65046 --- /dev/null +++ b/web2py/gluon/contrib/login_methods/saml2_auth.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +This file is part of web2py Web Framework (Copyrighted, 2007-2014). +Developed by Massimo Di Pierro . +License: LGPL v3 + +Login will be done via Web2py's CAS application, instead of web2py's +login form. + +Include in your model (eg db.py):: + + auth.define_tables(username=True) + from gluon.contrib.login_methods.saml2_auth import Saml2Auth + import os + auth.settings.login_form=Saml2Auth( + config_file = os.path.join(request.folder,'private','sp_conf'), + maps=dict( + username=lambda v: v['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn'][0], + email=lambda v: v['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn'][0], + user_id=lambda v: v['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn'][0])) + +you must have private/sp_conf.py, the pysaml2 sp configuration file. For example: + + + #!/usr/bin/env python + # -*- coding: utf-8 -*- + + from saml2 import BINDING_HTTP_POST, BINDING_HTTP_REDIRECT + import os.path + import requests + import tempfile + + BASEDIR = os.path.abspath(os.path.dirname(__file__)) + + # Web2py SP url and application name + HOST = 'http://127.0.0.1:8000' + APP = 'sp' + + # To load the IDP metadata... + IDP_METADATA = 'http://127.0.0.1:8088/metadata' + + def full_path(local_file): + return os.path.join(BASEDIR, local_file) + + CONFIG = { + # your entity id, usually your subdomain plus the url to the metadata view. + 'entityid': '%s/%s/default/metadata' % (HOST, APP), + 'service': { + 'sp' : { + 'name': 'MYSP', + 'endpoints': { + 'assertion_consumer_service': [ + ('%s/%s/default/user/login' % (HOST, APP), BINDING_HTTP_REDIRECT), + ('%s/%s/default/user/login' % (HOST, APP), BINDING_HTTP_POST), + ], + }, + }, + }, + # Your private and public key. + 'key_file': full_path('pki/mykey.pem'), + 'cert_file': full_path('pki/mycert.pem'), + + # where the remote metadata is stored + 'metadata': { + "remote": [{ + "url": IDP_METADATA, + "cert":full_path('pki/mycert.pem') + }] + }, + } + +""" + +from saml2 import BINDING_HTTP_REDIRECT, BINDING_HTTP_POST +from saml2.client import Saml2Client +from gluon.utils import web2py_uuid +from gluon import current, redirect, URL +import os, types + +def obj2dict(obj, processed=None): + """ + converts any object into a dict, recursively + """ + processed = processed if not processed is None else set() + if obj is None: + return None + if isinstance(obj,(int,long,str,unicode,float,bool)): + return obj + if id(obj) in processed: + return '' + processed.add(id(obj)) + if isinstance(obj,(list,tuple)): + return [obj2dict(item,processed) for item in obj] + if not isinstance(obj, dict) and hasattr(obj,'__dict__'): + obj = obj.__dict__ + else: + return repr(obj) + return dict((key,obj2dict(value,processed)) for key,value in obj.items() + if not key.startswith('_') and + not type(value) in (types.FunctionType, + types.LambdaType, + types.BuiltinFunctionType, + types.BuiltinMethodType)) + +def saml2_handler(session, request, config_filename = None, entityid = None): + config_filename = config_filename or os.path.join(request.folder,'private','sp_conf') + client = Saml2Client(config_file = config_filename) + if not entityid: + idps = client.metadata.with_descriptor("idpsso") + entityid = idps.keys()[0] + bindings = [BINDING_HTTP_REDIRECT, BINDING_HTTP_POST] + binding, destination = client.pick_binding( + "single_sign_on_service", bindings, "idpsso", entity_id=entityid) + if request.env.request_method == 'GET': + binding = BINDING_HTTP_REDIRECT + elif request.env.request_method == 'POST': + binding = BINDING_HTTP_POST + if not request.vars.SAMLResponse: + req_id, req = client.create_authn_request(destination, binding=binding) + relay_state = web2py_uuid().replace('-','') + session.saml_outstanding_queries = {req_id: request.url} + session.saml_req_id = req_id + http_args = client.apply_binding(binding, str(req), destination, + relay_state=relay_state) + return {'url':dict(http_args["headers"])['Location']} + else: + relay_state = request.vars.RelayState + req_id = session.saml_req_id + unquoted_response = request.vars.SAMLResponse + res = {} + try: + data = client.parse_authn_request_response( + unquoted_response, binding, session.saml_outstanding_queries) + res['response'] = data if data else {} + except Exception as e: + import traceback + res['error'] = traceback.format_exc() + return res + + +class Saml2Auth(object): + + def __init__(self, config_file=None, maps=dict( + username=lambda v:v['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn'][0], + email=lambda v:v['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn'][0], + user_id=lambda v:v['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn'][0], + ), logout_url=None, change_password_url=None, entityid=None): + self.config_file = config_file + self.maps = maps + + # URL for redirecting users to when they sign out + self.saml_logout_url = logout_url + + # URL to let users change their password in the IDP system + self.saml_change_password_url = change_password_url + + # URL to specify an IDP if using federation metadata or an MDQ + self.entityid = entityid + + def login_url(self, next="/"): + d = saml2_handler(current.session, current.request, entityid=self.entityid) + if 'url' in d: + redirect(d['url']) + elif 'error' in d: + current.session.flash = d['error'] + redirect(URL('default','index')) + elif 'response' in d: + # a['assertions'][0]['attribute_statement'][0]['attribute'] + # is list of + # {'name': 'http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname', 'name_format': None, 'text': None, 'friendly_name': None, 'attribute_value': [{'text': 'CAA\\dev-mdp', 'extension_attributes': "{'{http://www.w3.org/2001/XMLSchema-instance}type': 'xs:string'}", 'extension_elements': []}], 'extension_elements': [], 'extension_attributes': '{}'} + try: + attributes = d['response'].assertions[0].attribute_statement[0].attribute + except: + attributes = d['response'].assertion.attribute_statement[0].attribute + current.session.saml2_info = dict( + (a.name, [i.text for i in a.attribute_value]) for a in attributes) + return next + + def logout_url(self, next="/"): + current.session.saml2_info = None + current.session.auth = None + self._SAML_logout() + return next + + def change_password_url(self, next="/"): + self._SAML_change_password() + return next + + def get_user(self): + user = current.session.saml2_info + if user: + d = {'source': 'web2py saml2'} + for key in self.maps: + d[key] = self.maps[key](user) + return d + return None + + def _SAML_logout(self): + """ + exposed SAML.logout() + redirects to the SAML logout page + """ + redirect(self.saml_logout_url) + + def _SAML_change_password(self): + redirect(self.saml_change_password_url) diff --git a/web2py/gluon/contrib/login_methods/x509_auth.py b/web2py/gluon/contrib/login_methods/x509_auth.py new file mode 100644 index 0000000..63e83d7 --- /dev/null +++ b/web2py/gluon/contrib/login_methods/x509_auth.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Written by Michele Comitini +License: LGPL v3 + +Adds support for x509 authentication. + +""" + +from gluon.globals import current +from gluon.storage import Storage +from gluon.http import HTTP, redirect + +#requires M2Crypto +from M2Crypto import X509 +from functools import reduce + + +class X509Auth(object): + """ + Login using x509 cert from client. + + from gluon.contrib.login_methods.x509_auth import X509Account + auth.settings.actions_disabled=['register','change_password', + 'request_reset_password','profile'] + auth.settings.login_form = X509Auth() + + """ + + def __init__(self): + self.request = current.request + self.ssl_client_raw_cert = self.request.env.ssl_client_raw_cert + + # rebuild the certificate passed by the env + # this is double work, but it is the only way + # since we cannot access the web server ssl engine directly + + if self.ssl_client_raw_cert: + + x509 = X509.load_cert_string( + self.ssl_client_raw_cert, X509.FORMAT_PEM) + # extract it from the cert + self.serial = self.request.env.ssl_client_serial or ( + '%x' % x509.get_serial_number()).upper() + + subject = x509.get_subject() + + # Reordering the subject map to a usable Storage map + # this allows us a cleaner syntax: + # cn = self.subject.cn + self.subject = Storage(filter(None, + map(lambda x: + (x, map(lambda y: + y.get_data( + ).as_text(), + subject.get_entries_by_nid(subject.nid[x]))), + subject.nid.keys()))) + + def login_form(self, **args): + raise HTTP(403, 'Login not allowed. No valid x509 crentials') + + def login_url(self, next="/"): + raise HTTP(403, 'Login not allowed. No valid x509 crentials') + + def logout_url(self, next="/"): + return next + + def get_user(self): + '''Returns the user info contained in the certificate. + ''' + + # We did not get the client cert? + if not self.ssl_client_raw_cert: + return None + + # Try to reconstruct some useful info for web2py auth machinery + + p = profile = dict() + + username = p['username'] = reduce(lambda a, b: '%s | %s' % ( + a, b), self.subject.CN or self.subject.commonName) + p['first_name'] = reduce(lambda a, b: '%s | %s' % (a, b), + self.subject.givenName or username) + p['last_name'] = reduce( + lambda a, b: '%s | %s' % (a, b), self.subject.surname) + p['email'] = reduce(lambda a, b: '%s | %s' % ( + a, b), self.subject.Email or self.subject.emailAddress) + + # IMPORTANT WE USE THE CERT SERIAL AS UNIQUE KEY FOR THE USER + p['registration_id'] = self.serial + + # If the auth table has a field certificate it will be used to + # save a PEM encoded copy of the user certificate. + + p['certificate'] = self.ssl_client_raw_cert + + return profile diff --git a/web2py/gluon/contrib/markdown/LICENSE b/web2py/gluon/contrib/markdown/LICENSE new file mode 100644 index 0000000..a66731f --- /dev/null +++ b/web2py/gluon/contrib/markdown/LICENSE @@ -0,0 +1 @@ +markdown2.py is released under MIT license. \ No newline at end of file diff --git a/web2py/gluon/contrib/markdown/__init__.py b/web2py/gluon/contrib/markdown/__init__.py new file mode 100644 index 0000000..4378de2 --- /dev/null +++ b/web2py/gluon/contrib/markdown/__init__.py @@ -0,0 +1,17 @@ +from .markdown2 import * +from gluon.html import XML + +def WIKI(text, encoding="utf8", safe_mode='escape', html4tags=False, **attributes): + if not text: + test = '' + if 'extras' in attributes: + extras = attributes['extras'] + del attributes['extras'] + else: + extras=None + text = text.decode(encoding,'replace') + + return XML(markdown(text,extras=extras, + safe_mode=safe_mode, html4tags=html4tags)\ + .encode(encoding,'xmlcharrefreplace'),**attributes) + diff --git a/web2py/gluon/contrib/markdown/markdown2.py b/web2py/gluon/contrib/markdown/markdown2.py new file mode 100644 index 0000000..07797b9 --- /dev/null +++ b/web2py/gluon/contrib/markdown/markdown2.py @@ -0,0 +1,2459 @@ +#!/usr/bin/env python +# Copyright (c) 2012 Trent Mick. +# Copyright (c) 2007-2008 ActiveState Corp. +# License: MIT (http://www.opensource.org/licenses/mit-license.php) + +from __future__ import generators +from __future__ import print_function + +r"""A fast and complete Python implementation of Markdown. + +[from http://daringfireball.net/projects/markdown/] +> Markdown is a text-to-HTML filter; it translates an easy-to-read / +> easy-to-write structured text format into HTML. Markdown's text +> format is most similar to that of plain text email, and supports +> features such as headers, *emphasis*, code blocks, blockquotes, and +> links. +> +> Markdown's syntax is designed not as a generic markup language, but +> specifically to serve as a front-end to (X)HTML. You can use span-level +> HTML tags anywhere in a Markdown document, and you can use block level +> HTML tags (like
    and as well). + +Module usage: + + >>> import markdown2 + >>> markdown2.markdown("*boo!*") # or use `html = markdown_path(PATH)` + u'

    boo!

    \n' + + >>> markdowner = Markdown() + >>> markdowner.convert("*boo!*") + u'

    boo!

    \n' + >>> markdowner.convert("**boom!**") + u'

    boom!

    \n' + +This implementation of Markdown implements the full "core" syntax plus a +number of extras (e.g., code syntax coloring, footnotes) as described on +. +""" + +cmdln_desc = """A fast and complete Python implementation of Markdown, a +text-to-HTML conversion tool for web writers. + +Supported extra syntax options (see -x|--extras option below and +see for details): + +* code-friendly: Disable _ and __ for em and strong. +* cuddled-lists: Allow lists to be cuddled to the preceding paragraph. +* fenced-code-blocks: Allows a code block to not have to be indented + by fencing it with '```' on a line before and after. Based on + with support for + syntax highlighting. +* footnotes: Support footnotes as in use on daringfireball.net and + implemented in other Markdown processors (tho not in Markdown.pl v1.0.1). +* header-ids: Adds "id" attributes to headers. The id value is a slug of + the header text. +* html-classes: Takes a dict mapping html tag names (lowercase) to a + string to use for a "class" tag attribute. Currently only supports "img", + "table", "pre" and "code" tags. Add an issue if you require this for other + tags. +* markdown-in-html: Allow the use of `markdown="1"` in a block HTML tag to + have markdown processing be done on its contents. Similar to + but with + some limitations. +* metadata: Extract metadata from a leading '---'-fenced block. + See for details. +* nofollow: Add `rel="nofollow"` to add `` tags with an href. See + . +* pyshell: Treats unindented Python interactive shell sessions as + blocks. +* link-patterns: Auto-link given regex patterns in text (e.g. bug number + references, revision number references). +* smarty-pants: Replaces ' and " with curly quotation marks or curly + apostrophes. Replaces --, ---, ..., and . . . with en dashes, em dashes, + and ellipses. +* spoiler: A special kind of blockquote commonly hidden behind a + click on SO. Syntax per . +* toc: The returned HTML string gets a new "toc_html" attribute which is + a Table of Contents for the document. (experimental) +* xml: Passes one-liner processing instructions and namespaced XML tags. +* tables: Tables using the same format as GFM + and + PHP-Markdown Extra . +* wiki-tables: Google Code Wiki-style tables. See + . +""" + +# Dev Notes: +# - Python's regex syntax doesn't have '\z', so I'm using '\Z'. I'm +# not yet sure if there implications with this. Compare 'pydoc sre' +# and 'perldoc perlre'. + +__version_info__ = (2, 3, 1) +__version__ = '.'.join(map(str, __version_info__)) +__author__ = "Trent Mick" + +import sys +import re +import logging +try: + from hashlib import md5 +except ImportError: + from md5 import md5 +import optparse +from random import random, randint +import codecs + + +#---- Python version compat + +if sys.version_info[:2] < (2,4): + def reversed(sequence): + for i in sequence[::-1]: + yield i + +# Use `bytes` for byte strings and `unicode` for unicode strings (str in Py3). +if sys.version_info[0] <= 2: + py3 = False + try: + bytes + except NameError: + bytes = str + base_string_type = basestring +elif sys.version_info[0] >= 3: + py3 = True + unicode = str + base_string_type = str + + + +#---- globals + +DEBUG = False +log = logging.getLogger("markdown") + +DEFAULT_TAB_WIDTH = 4 + + +SECRET_SALT = bytes(randint(0, 1000000)) +def _hash_text(s): + return 'md5-' + md5(SECRET_SALT + s.encode("utf-8")).hexdigest() + +# Table of hash values for escaped characters: +g_escape_table = dict([(ch, _hash_text(ch)) + for ch in '\\`*_{}[]()>#+-.!']) + + + +#---- exceptions + +class MarkdownError(Exception): + pass + + + +#---- public api + +def markdown_path(path, encoding="utf-8", + html4tags=False, tab_width=DEFAULT_TAB_WIDTH, + safe_mode=None, extras=None, link_patterns=None, + use_file_vars=False): + fp = codecs.open(path, 'r', encoding) + text = fp.read() + fp.close() + return Markdown(html4tags=html4tags, tab_width=tab_width, + safe_mode=safe_mode, extras=extras, + link_patterns=link_patterns, + use_file_vars=use_file_vars).convert(text) + +def markdown(text, html4tags=False, tab_width=DEFAULT_TAB_WIDTH, + safe_mode=None, extras=None, link_patterns=None, + use_file_vars=False): + return Markdown(html4tags=html4tags, tab_width=tab_width, + safe_mode=safe_mode, extras=extras, + link_patterns=link_patterns, + use_file_vars=use_file_vars).convert(text) + +class Markdown(object): + # The dict of "extras" to enable in processing -- a mapping of + # extra name to argument for the extra. Most extras do not have an + # argument, in which case the value is None. + # + # This can be set via (a) subclassing and (b) the constructor + # "extras" argument. + extras = None + + urls = None + titles = None + html_blocks = None + html_spans = None + html_removed_text = "[HTML_REMOVED]" # for compat with markdown.py + + # Used to track when we're inside an ordered or unordered list + # (see _ProcessListItems() for details): + list_level = 0 + + _ws_only_line_re = re.compile(r"^[ \t]+$", re.M) + + def __init__(self, html4tags=False, tab_width=4, safe_mode=None, + extras=None, link_patterns=None, use_file_vars=False): + if html4tags: + self.empty_element_suffix = ">" + else: + self.empty_element_suffix = " />" + self.tab_width = tab_width + + # For compatibility with earlier markdown2.py and with + # markdown.py's safe_mode being a boolean, + # safe_mode == True -> "replace" + if safe_mode is True: + self.safe_mode = "replace" + else: + self.safe_mode = safe_mode + + # Massaging and building the "extras" info. + if self.extras is None: + self.extras = {} + elif not isinstance(self.extras, dict): + self.extras = dict([(e, None) for e in self.extras]) + if extras: + if not isinstance(extras, dict): + extras = dict([(e, None) for e in extras]) + self.extras.update(extras) + assert isinstance(self.extras, dict) + if "toc" in self.extras and not "header-ids" in self.extras: + self.extras["header-ids"] = None # "toc" implies "header-ids" + self._instance_extras = self.extras.copy() + + self.link_patterns = link_patterns + self.use_file_vars = use_file_vars + self._outdent_re = re.compile(r'^(\t|[ ]{1,%d})' % tab_width, re.M) + + self._escape_table = g_escape_table.copy() + if "smarty-pants" in self.extras: + self._escape_table['"'] = _hash_text('"') + self._escape_table["'"] = _hash_text("'") + + def reset(self): + self.urls = {} + self.titles = {} + self.html_blocks = {} + self.html_spans = {} + self.list_level = 0 + self.extras = self._instance_extras.copy() + if "footnotes" in self.extras: + self.footnotes = {} + self.footnote_ids = [] + if "header-ids" in self.extras: + self._count_from_header_id = {} # no `defaultdict` in Python 2.4 + if "metadata" in self.extras: + self.metadata = {} + + # Per "rel" + # should only be used in tags with an "href" attribute. + _a_nofollow = re.compile(r"<(a)([^>]*href=)", re.IGNORECASE) + + def convert(self, text): + """Convert the given text.""" + # Main function. The order in which other subs are called here is + # essential. Link and image substitutions need to happen before + # _EscapeSpecialChars(), so that any *'s or _'s in the + # and tags get encoded. + + # Clear the global hashes. If we don't clear these, you get conflicts + # from other articles when generating a page which contains more than + # one article (e.g. an index page that shows the N most recent + # articles): + self.reset() + + if not isinstance(text, unicode): + #TODO: perhaps shouldn't presume UTF-8 for string input? + text = unicode(text, 'utf-8') + + if self.use_file_vars: + # Look for emacs-style file variable hints. + emacs_vars = self._get_emacs_vars(text) + if "markdown-extras" in emacs_vars: + splitter = re.compile("[ ,]+") + for e in splitter.split(emacs_vars["markdown-extras"]): + if '=' in e: + ename, earg = e.split('=', 1) + try: + earg = int(earg) + except ValueError: + pass + else: + ename, earg = e, None + self.extras[ename] = earg + + # Standardize line endings: + text = re.sub("\r\n|\r", "\n", text) + + # Make sure $text ends with a couple of newlines: + text += "\n\n" + + # Convert all tabs to spaces. + text = self._detab(text) + + # Strip any lines consisting only of spaces and tabs. + # This makes subsequent regexen easier to write, because we can + # match consecutive blank lines with /\n+/ instead of something + # contorted like /[ \t]*\n+/ . + text = self._ws_only_line_re.sub("", text) + + # strip metadata from head and extract + if "metadata" in self.extras: + text = self._extract_metadata(text) + + text = self.preprocess(text) + + if "fenced-code-blocks" in self.extras and not self.safe_mode: + text = self._do_fenced_code_blocks(text) + + if self.safe_mode: + text = self._hash_html_spans(text) + + # Turn block-level HTML blocks into hash entries + text = self._hash_html_blocks(text, raw=True) + + if "fenced-code-blocks" in self.extras and self.safe_mode: + text = self._do_fenced_code_blocks(text) + + # Strip link definitions, store in hashes. + if "footnotes" in self.extras: + # Must do footnotes first because an unlucky footnote defn + # looks like a link defn: + # [^4]: this "looks like a link defn" + text = self._strip_footnote_definitions(text) + text = self._strip_link_definitions(text) + + text = self._run_block_gamut(text) + + if "footnotes" in self.extras: + text = self._add_footnotes(text) + + text = self.postprocess(text) + + text = self._unescape_special_chars(text) + + if self.safe_mode: + text = self._unhash_html_spans(text) + + if "nofollow" in self.extras: + text = self._a_nofollow.sub(r'<\1 rel="nofollow"\2', text) + + text += "\n" + + rv = UnicodeWithAttrs(text) + if "toc" in self.extras: + rv._toc = self._toc + if "metadata" in self.extras: + rv.metadata = self.metadata + return rv + + def postprocess(self, text): + """A hook for subclasses to do some postprocessing of the html, if + desired. This is called before unescaping of special chars and + unhashing of raw HTML spans. + """ + return text + + def preprocess(self, text): + """A hook for subclasses to do some preprocessing of the Markdown, if + desired. This is called after basic formatting of the text, but prior + to any extras, safe mode, etc. processing. + """ + return text + + # Is metadata if the content starts with '---'-fenced `key: value` + # pairs. E.g. (indented for presentation): + # --- + # foo: bar + # another-var: blah blah + # --- + _metadata_pat = re.compile("""^---[ \t]*\n((?:[ \t]*[^ \t:]+[ \t]*:[^\n]*\n)+)---[ \t]*\n""") + + def _extract_metadata(self, text): + # fast test + if not text.startswith("---"): + return text + match = self._metadata_pat.match(text) + if not match: + return text + + tail = text[len(match.group(0)):] + metadata_str = match.group(1).strip() + for line in metadata_str.split('\n'): + key, value = line.split(':', 1) + self.metadata[key.strip()] = value.strip() + + return tail + + + _emacs_oneliner_vars_pat = re.compile(r"-\*-\s*([^\r\n]*?)\s*-\*-", re.UNICODE) + # This regular expression is intended to match blocks like this: + # PREFIX Local Variables: SUFFIX + # PREFIX mode: Tcl SUFFIX + # PREFIX End: SUFFIX + # Some notes: + # - "[ \t]" is used instead of "\s" to specifically exclude newlines + # - "(\r\n|\n|\r)" is used instead of "$" because the sre engine does + # not like anything other than Unix-style line terminators. + _emacs_local_vars_pat = re.compile(r"""^ + (?P(?:[^\r\n|\n|\r])*?) + [\ \t]*Local\ Variables:[\ \t]* + (?P.*?)(?:\r\n|\n|\r) + (?P.*?\1End:) + """, re.IGNORECASE | re.MULTILINE | re.DOTALL | re.VERBOSE) + + def _get_emacs_vars(self, text): + """Return a dictionary of emacs-style local variables. + + Parsing is done loosely according to this spec (and according to + some in-practice deviations from this): + http://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html#Specifying-File-Variables + """ + emacs_vars = {} + SIZE = pow(2, 13) # 8kB + + # Search near the start for a '-*-'-style one-liner of variables. + head = text[:SIZE] + if "-*-" in head: + match = self._emacs_oneliner_vars_pat.search(head) + if match: + emacs_vars_str = match.group(1) + assert '\n' not in emacs_vars_str + emacs_var_strs = [s.strip() for s in emacs_vars_str.split(';') + if s.strip()] + if len(emacs_var_strs) == 1 and ':' not in emacs_var_strs[0]: + # While not in the spec, this form is allowed by emacs: + # -*- Tcl -*- + # where the implied "variable" is "mode". This form + # is only allowed if there are no other variables. + emacs_vars["mode"] = emacs_var_strs[0].strip() + else: + for emacs_var_str in emacs_var_strs: + try: + variable, value = emacs_var_str.strip().split(':', 1) + except ValueError: + log.debug("emacs variables error: malformed -*- " + "line: %r", emacs_var_str) + continue + # Lowercase the variable name because Emacs allows "Mode" + # or "mode" or "MoDe", etc. + emacs_vars[variable.lower()] = value.strip() + + tail = text[-SIZE:] + if "Local Variables" in tail: + match = self._emacs_local_vars_pat.search(tail) + if match: + prefix = match.group("prefix") + suffix = match.group("suffix") + lines = match.group("content").splitlines(0) + #print "prefix=%r, suffix=%r, content=%r, lines: %s"\ + # % (prefix, suffix, match.group("content"), lines) + + # Validate the Local Variables block: proper prefix and suffix + # usage. + for i, line in enumerate(lines): + if not line.startswith(prefix): + log.debug("emacs variables error: line '%s' " + "does not use proper prefix '%s'" + % (line, prefix)) + return {} + # Don't validate suffix on last line. Emacs doesn't care, + # neither should we. + if i != len(lines)-1 and not line.endswith(suffix): + log.debug("emacs variables error: line '%s' " + "does not use proper suffix '%s'" + % (line, suffix)) + return {} + + # Parse out one emacs var per line. + continued_for = None + for line in lines[:-1]: # no var on the last line ("PREFIX End:") + if prefix: line = line[len(prefix):] # strip prefix + if suffix: line = line[:-len(suffix)] # strip suffix + line = line.strip() + if continued_for: + variable = continued_for + if line.endswith('\\'): + line = line[:-1].rstrip() + else: + continued_for = None + emacs_vars[variable] += ' ' + line + else: + try: + variable, value = line.split(':', 1) + except ValueError: + log.debug("local variables error: missing colon " + "in local variables entry: '%s'" % line) + continue + # Do NOT lowercase the variable name, because Emacs only + # allows "mode" (and not "Mode", "MoDe", etc.) in this block. + value = value.strip() + if value.endswith('\\'): + value = value[:-1].rstrip() + continued_for = variable + else: + continued_for = None + emacs_vars[variable] = value + + # Unquote values. + for var, val in list(emacs_vars.items()): + if len(val) > 1 and (val.startswith('"') and val.endswith('"') + or val.startswith('"') and val.endswith('"')): + emacs_vars[var] = val[1:-1] + + return emacs_vars + + # Cribbed from a post by Bart Lateur: + # + _detab_re = re.compile(r'(.*?)\t', re.M) + def _detab_sub(self, match): + g1 = match.group(1) + return g1 + (' ' * (self.tab_width - len(g1) % self.tab_width)) + def _detab(self, text): + r"""Remove (leading?) tabs from a file. + + >>> m = Markdown() + >>> m._detab("\tfoo") + ' foo' + >>> m._detab(" \tfoo") + ' foo' + >>> m._detab("\t foo") + ' foo' + >>> m._detab(" foo") + ' foo' + >>> m._detab(" foo\n\tbar\tblam") + ' foo\n bar blam' + """ + if '\t' not in text: + return text + return self._detab_re.subn(self._detab_sub, text)[0] + + # I broke out the html5 tags here and add them to _block_tags_a and + # _block_tags_b. This way html5 tags are easy to keep track of. + _html5tags = '|article|aside|header|hgroup|footer|nav|section|figure|figcaption' + + _block_tags_a = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del' + _block_tags_a += _html5tags + + _strict_tag_block_re = re.compile(r""" + ( # save in \1 + ^ # start of line (with re.M) + <(%s) # start tag = \2 + \b # word break + (.*\n)*? # any number of lines, minimally matching + # the matching end tag + [ \t]* # trailing spaces/tabs + (?=\n+|\Z) # followed by a newline or end of document + ) + """ % _block_tags_a, + re.X | re.M) + + _block_tags_b = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math' + _block_tags_b += _html5tags + + _liberal_tag_block_re = re.compile(r""" + ( # save in \1 + ^ # start of line (with re.M) + <(%s) # start tag = \2 + \b # word break + (.*\n)*? # any number of lines, minimally matching + .* # the matching end tag + [ \t]* # trailing spaces/tabs + (?=\n+|\Z) # followed by a newline or end of document + ) + """ % _block_tags_b, + re.X | re.M) + + _html_markdown_attr_re = re.compile( + r'''\s+markdown=("1"|'1')''') + def _hash_html_block_sub(self, match, raw=False): + html = match.group(1) + if raw and self.safe_mode: + html = self._sanitize_html(html) + elif 'markdown-in-html' in self.extras and 'markdown=' in html: + first_line = html.split('\n', 1)[0] + m = self._html_markdown_attr_re.search(first_line) + if m: + lines = html.split('\n') + middle = '\n'.join(lines[1:-1]) + last_line = lines[-1] + first_line = first_line[:m.start()] + first_line[m.end():] + f_key = _hash_text(first_line) + self.html_blocks[f_key] = first_line + l_key = _hash_text(last_line) + self.html_blocks[l_key] = last_line + return ''.join(["\n\n", f_key, + "\n\n", middle, "\n\n", + l_key, "\n\n"]) + key = _hash_text(html) + self.html_blocks[key] = html + return "\n\n" + key + "\n\n" + + def _hash_html_blocks(self, text, raw=False): + """Hashify HTML blocks + + We only want to do this for block-level HTML tags, such as headers, + lists, and tables. That's because we still want to wrap

    s around + "paragraphs" that are wrapped in non-block-level tags, such as anchors, + phrase emphasis, and spans. The list of tags we're looking for is + hard-coded. + + @param raw {boolean} indicates if these are raw HTML blocks in + the original source. It makes a difference in "safe" mode. + """ + if '<' not in text: + return text + + # Pass `raw` value into our calls to self._hash_html_block_sub. + hash_html_block_sub = _curry(self._hash_html_block_sub, raw=raw) + + # First, look for nested blocks, e.g.: + #

    + #
    + # tags for inner block must be indented. + #
    + #
    + # + # The outermost tags must start at the left margin for this to match, and + # the inner nested divs must be indented. + # We need to do this before the next, more liberal match, because the next + # match will start at the first `
    ` and stop at the first `
    `. + text = self._strict_tag_block_re.sub(hash_html_block_sub, text) + + # Now match more liberally, simply from `\n` to `\n` + text = self._liberal_tag_block_re.sub(hash_html_block_sub, text) + + # Special case just for
    . It was easier to make a special + # case than to make the other regex more complicated. + if "", start_idx) + 3 + except ValueError: + break + + # Start position for next comment block search. + start = end_idx + + # Validate whitespace before comment. + if start_idx: + # - Up to `tab_width - 1` spaces before start_idx. + for i in range(self.tab_width - 1): + if text[start_idx - 1] != ' ': + break + start_idx -= 1 + if start_idx == 0: + break + # - Must be preceded by 2 newlines or hit the start of + # the document. + if start_idx == 0: + pass + elif start_idx == 1 and text[0] == '\n': + start_idx = 0 # to match minute detail of Markdown.pl regex + elif text[start_idx-2:start_idx] == '\n\n': + pass + else: + break + + # Validate whitespace after comment. + # - Any number of spaces and tabs. + while end_idx < len(text): + if text[end_idx] not in ' \t': + break + end_idx += 1 + # - Must be following by 2 newlines or hit end of text. + if text[end_idx:end_idx+2] not in ('', '\n', '\n\n'): + continue + + # Escape and hash (must match `_hash_html_block_sub`). + html = text[start_idx:end_idx] + if raw and self.safe_mode: + html = self._sanitize_html(html) + key = _hash_text(html) + self.html_blocks[key] = html + text = text[:start_idx] + "\n\n" + key + "\n\n" + text[end_idx:] + + if "xml" in self.extras: + # Treat XML processing instructions and namespaced one-liner + # tags as if they were block HTML tags. E.g., if standalone + # (i.e. are their own paragraph), the following do not get + # wrapped in a

    tag: + # + # + # + _xml_oneliner_re = _xml_oneliner_re_from_tab_width(self.tab_width) + text = _xml_oneliner_re.sub(hash_html_block_sub, text) + + return text + + def _strip_link_definitions(self, text): + # Strips link definitions from text, stores the URLs and titles in + # hash references. + less_than_tab = self.tab_width - 1 + + # Link defs are in the form: + # [id]: url "optional title" + _link_def_re = re.compile(r""" + ^[ ]{0,%d}\[(.+)\]: # id = \1 + [ \t]* + \n? # maybe *one* newline + [ \t]* + ? # url = \2 + [ \t]* + (?: + \n? # maybe one newline + [ \t]* + (?<=\s) # lookbehind for whitespace + ['"(] + ([^\n]*) # title = \3 + ['")] + [ \t]* + )? # title is optional + (?:\n+|\Z) + """ % less_than_tab, re.X | re.M | re.U) + return _link_def_re.sub(self._extract_link_def_sub, text) + + def _extract_link_def_sub(self, match): + id, url, title = match.groups() + key = id.lower() # Link IDs are case-insensitive + self.urls[key] = self._encode_amps_and_angles(url) + if title: + self.titles[key] = title + return "" + + def _extract_footnote_def_sub(self, match): + id, text = match.groups() + text = _dedent(text, skip_first_line=not text.startswith('\n')).strip() + normed_id = re.sub(r'\W', '-', id) + # Ensure footnote text ends with a couple newlines (for some + # block gamut matches). + self.footnotes[normed_id] = text + "\n\n" + return "" + + def _strip_footnote_definitions(self, text): + """A footnote definition looks like this: + + [^note-id]: Text of the note. + + May include one or more indented paragraphs. + + Where, + - The 'note-id' can be pretty much anything, though typically it + is the number of the footnote. + - The first paragraph may start on the next line, like so: + + [^note-id]: + Text of the note. + """ + less_than_tab = self.tab_width - 1 + footnote_def_re = re.compile(r''' + ^[ ]{0,%d}\[\^(.+)\]: # id = \1 + [ \t]* + ( # footnote text = \2 + # First line need not start with the spaces. + (?:\s*.*\n+) + (?: + (?:[ ]{%d} | \t) # Subsequent lines must be indented. + .*\n+ + )* + ) + # Lookahead for non-space at line-start, or end of doc. + (?:(?=^[ ]{0,%d}\S)|\Z) + ''' % (less_than_tab, self.tab_width, self.tab_width), + re.X | re.M) + return footnote_def_re.sub(self._extract_footnote_def_sub, text) + + _hr_re = re.compile(r'^[ ]{0,3}([-_*][ ]{0,2}){3,}$', re.M) + + def _run_block_gamut(self, text): + # These are all the transformations that form block-level + # tags like paragraphs, headers, and list items. + + if "fenced-code-blocks" in self.extras: + text = self._do_fenced_code_blocks(text) + + text = self._do_headers(text) + + # Do Horizontal Rules: + # On the number of spaces in horizontal rules: The spec is fuzzy: "If + # you wish, you may use spaces between the hyphens or asterisks." + # Markdown.pl 1.0.1's hr regexes limit the number of spaces between the + # hr chars to one or two. We'll reproduce that limit here. + hr = "\n tags around block-level tags. + text = self._hash_html_blocks(text) + + text = self._form_paragraphs(text) + + return text + + def _pyshell_block_sub(self, match): + lines = match.group(0).splitlines(0) + _dedentlines(lines) + indent = ' ' * self.tab_width + s = ('\n' # separate from possible cuddled paragraph + + indent + ('\n'+indent).join(lines) + + '\n\n') + return s + + def _prepare_pyshell_blocks(self, text): + """Ensure that Python interactive shell sessions are put in + code blocks -- even if not properly indented. + """ + if ">>>" not in text: + return text + + less_than_tab = self.tab_width - 1 + _pyshell_block_re = re.compile(r""" + ^([ ]{0,%d})>>>[ ].*\n # first line + ^(\1.*\S+.*\n)* # any number of subsequent lines + ^\n # ends with a blank line + """ % less_than_tab, re.M | re.X) + + return _pyshell_block_re.sub(self._pyshell_block_sub, text) + + def _table_sub(self, match): + trim_space_re = '^[ \t\n]+|[ \t\n]+$' + trim_bar_re = '^\||\|$' + + head, underline, body = match.groups() + + # Determine aligns for columns. + cols = [cell.strip() for cell in re.sub(trim_bar_re, "", re.sub(trim_space_re, "", underline)).split('|')] + align_from_col_idx = {} + for col_idx, col in enumerate(cols): + if col[0] == ':' and col[-1] == ':': + align_from_col_idx[col_idx] = ' align="center"' + elif col[0] == ':': + align_from_col_idx[col_idx] = ' align="left"' + elif col[-1] == ':': + align_from_col_idx[col_idx] = ' align="right"' + + # thead + hlines = ['' % self._html_class_str_from_tag('table'), '

    ', ''] + cols = [cell.strip() for cell in re.sub(trim_bar_re, "", re.sub(trim_space_re, "", head)).split('|')] + for col_idx, col in enumerate(cols): + hlines.append(' %s' % ( + align_from_col_idx.get(col_idx, ''), + self._run_span_gamut(col) + )) + hlines.append('') + hlines.append('') + + # tbody + hlines.append('') + for line in body.strip('\n').split('\n'): + hlines.append('') + cols = [cell.strip() for cell in re.sub(trim_bar_re, "", re.sub(trim_space_re, "", line)).split('|')] + for col_idx, col in enumerate(cols): + hlines.append(' %s' % ( + align_from_col_idx.get(col_idx, ''), + self._run_span_gamut(col) + )) + hlines.append('') + hlines.append('') + hlines.append('
    ') + + return '\n'.join(hlines) + '\n' + + def _do_tables(self, text): + """Copying PHP-Markdown and GFM table syntax. Some regex borrowed from + https://github.com/michelf/php-markdown/blob/lib/Michelf/Markdown.php#L2538 + """ + less_than_tab = self.tab_width - 1 + table_re = re.compile(r''' + (?:(?<=\n\n)|\A\n?) # leading blank line + + ^[ ]{0,%d} # allowed whitespace + (.*[|].*) \n # $1: header row (at least one pipe) + + ^[ ]{0,%d} # allowed whitespace + ( # $2: underline row + # underline row with leading bar + (?: \|\ *:?-+:?\ * )+ \|? \n + | + # or, underline row without leading bar + (?: \ *:?-+:?\ *\| )+ (?: \ *:?-+:?\ * )? \n + ) + + ( # $3: data rows + (?: + ^[ ]{0,%d}(?!\ ) # ensure line begins with 0 to less_than_tab spaces + .*\|.* \n + )+ + ) + ''' % (less_than_tab, less_than_tab, less_than_tab), re.M | re.X) + return table_re.sub(self._table_sub, text) + + def _wiki_table_sub(self, match): + ttext = match.group(0).strip() + #print 'wiki table: %r' % match.group(0) + rows = [] + for line in ttext.splitlines(0): + line = line.strip()[2:-2].strip() + row = [c.strip() for c in re.split(r'(?' % self._html_class_str_from_tag('table'), '
    ') + hrow.append(self._run_span_gamut(cell)) + hrow.append('
    '] + return '\n'.join(hlines) + '\n' + + def _do_wiki_tables(self, text): + # Optimization. + if "||" not in text: + return text + + less_than_tab = self.tab_width - 1 + wiki_table_re = re.compile(r''' + (?:(?<=\n\n)|\A\n?) # leading blank line + ^([ ]{0,%d})\|\|.+?\|\|[ ]*\n # first line + (^\1\|\|.+?\|\|\n)* # any number of subsequent lines + ''' % less_than_tab, re.M | re.X) + return wiki_table_re.sub(self._wiki_table_sub, text) + + def _run_span_gamut(self, text): + # These are all the transformations that occur *within* block-level + # tags like paragraphs, headers, and list items. + + text = self._do_code_spans(text) + + text = self._escape_special_chars(text) + + # Process anchor and image tags. + text = self._do_links(text) + + # Make links out of things like `` + # Must come after _do_links(), because you can use < and > + # delimiters in inline links like [this](). + text = self._do_auto_links(text) + + if "link-patterns" in self.extras: + text = self._do_link_patterns(text) + + text = self._encode_amps_and_angles(text) + + if "strike" in self.extras: + text = self._do_strike(text) + + text = self._do_italics_and_bold(text) + + if "smarty-pants" in self.extras: + text = self._do_smart_punctuation(text) + + # Do hard breaks: + if "break-on-newline" in self.extras: + text = re.sub(r" *\n", " + | + # auto-link (e.g., ) + <\w+[^>]*> + | + # comment + | + <\?.*?\?> # processing instruction + ) + """, re.X) + + def _escape_special_chars(self, text): + # Python markdown note: the HTML tokenization here differs from + # that in Markdown.pl, hence the behaviour for subtle cases can + # differ (I believe the tokenizer here does a better job because + # it isn't susceptible to unmatched '<' and '>' in HTML tags). + # Note, however, that '>' is not allowed in an auto-link URL + # here. + escaped = [] + is_html_markup = False + for token in self._sorta_html_tokenize_re.split(text): + if is_html_markup: + # Within tags/HTML-comments/auto-links, encode * and _ + # so they don't conflict with their use in Markdown for + # italics and strong. We're replacing each such + # character with its corresponding MD5 checksum value; + # this is likely overkill, but it should prevent us from + # colliding with the escape values by accident. + escaped.append(token.replace('*', self._escape_table['*']) + .replace('_', self._escape_table['_'])) + else: + escaped.append(self._encode_backslash_escapes(token)) + is_html_markup = not is_html_markup + return ''.join(escaped) + + def _hash_html_spans(self, text): + # Used for safe_mode. + + def _is_auto_link(s): + if ':' in s and self._auto_link_re.match(s): + return True + elif '@' in s and self._auto_email_link_re.match(s): + return True + return False + + tokens = [] + is_html_markup = False + for token in self._sorta_html_tokenize_re.split(text): + if is_html_markup and not _is_auto_link(token): + sanitized = self._sanitize_html(token) + key = _hash_text(sanitized) + self.html_spans[key] = sanitized + tokens.append(key) + else: + tokens.append(token) + is_html_markup = not is_html_markup + return ''.join(tokens) + + def _unhash_html_spans(self, text): + for key, sanitized in list(self.html_spans.items()): + text = text.replace(key, sanitized) + return text + + def _sanitize_html(self, s): + if self.safe_mode == "replace": + return self.html_removed_text + elif self.safe_mode == "escape": + replacements = [ + ('&', '&'), + ('<', '<'), + ('>', '>'), + ] + for before, after in replacements: + s = s.replace(before, after) + return s + else: + raise MarkdownError("invalid value for 'safe_mode': %r (must be " + "'escape' or 'replace')" % self.safe_mode) + + _inline_link_title = re.compile(r''' + ( # \1 + [ \t]+ + (['"]) # quote char = \2 + (?P.*?) + \2 + )? # title is optional + \)$ + ''', re.X | re.S) + _tail_of_reference_link_re = re.compile(r''' + # Match tail of: [text][id] + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + \[ + (?P<id>.*?) + \] + ''', re.X | re.S) + + _whitespace = re.compile(r'\s*') + + _strip_anglebrackets = re.compile(r'<(.*)>.*') + + def _find_non_whitespace(self, text, start): + """Returns the index of the first non-whitespace character in text + after (and including) start + """ + match = self._whitespace.match(text, start) + return match.end() + + def _find_balanced(self, text, start, open_c, close_c): + """Returns the index where the open_c and close_c characters balance + out - the same number of open_c and close_c are encountered - or the + end of string if it's reached before the balance point is found. + """ + i = start + l = len(text) + count = 1 + while count > 0 and i < l: + if text[i] == open_c: + count += 1 + elif text[i] == close_c: + count -= 1 + i += 1 + return i + + def _extract_url_and_title(self, text, start): + """Extracts the url and (optional) title from the tail of a link""" + # text[start] equals the opening parenthesis + idx = self._find_non_whitespace(text, start+1) + if idx == len(text): + return None, None, None + end_idx = idx + has_anglebrackets = text[idx] == "<" + if has_anglebrackets: + end_idx = self._find_balanced(text, end_idx+1, "<", ">") + end_idx = self._find_balanced(text, end_idx, "(", ")") + match = self._inline_link_title.search(text, idx, end_idx) + if not match: + return None, None, None + url, title = text[idx:match.start()], match.group("title") + if has_anglebrackets: + url = self._strip_anglebrackets.sub(r'\1', url) + return url, title, end_idx + + def _do_links(self, text): + """Turn Markdown link shortcuts into XHTML <a> and <img> tags. + + This is a combination of Markdown.pl's _DoAnchors() and + _DoImages(). They are done together because that simplified the + approach. It was necessary to use a different approach than + Markdown.pl because of the lack of atomic matching support in + Python's regex engine used in $g_nested_brackets. + """ + MAX_LINK_TEXT_SENTINEL = 3000 # markdown2 issue 24 + + # `anchor_allowed_pos` is used to support img links inside + # anchors, but not anchors inside anchors. An anchor's start + # pos must be `>= anchor_allowed_pos`. + anchor_allowed_pos = 0 + + curr_pos = 0 + while True: # Handle the next link. + # The next '[' is the start of: + # - an inline anchor: [text](url "title") + # - a reference anchor: [text][id] + # - an inline img: ![text](url "title") + # - a reference img: ![text][id] + # - a footnote ref: [^id] + # (Only if 'footnotes' extra enabled) + # - a footnote defn: [^id]: ... + # (Only if 'footnotes' extra enabled) These have already + # been stripped in _strip_footnote_definitions() so no + # need to watch for them. + # - a link definition: [id]: url "title" + # These have already been stripped in + # _strip_link_definitions() so no need to watch for them. + # - not markup: [...anything else... + try: + start_idx = text.index('[', curr_pos) + except ValueError: + break + text_length = len(text) + + # Find the matching closing ']'. + # Markdown.pl allows *matching* brackets in link text so we + # will here too. Markdown.pl *doesn't* currently allow + # matching brackets in img alt text -- we'll differ in that + # regard. + bracket_depth = 0 + for p in range(start_idx+1, min(start_idx+MAX_LINK_TEXT_SENTINEL, + text_length)): + ch = text[p] + if ch == ']': + bracket_depth -= 1 + if bracket_depth < 0: + break + elif ch == '[': + bracket_depth += 1 + else: + # Closing bracket not found within sentinel length. + # This isn't markup. + curr_pos = start_idx + 1 + continue + link_text = text[start_idx+1:p] + + # Possibly a footnote ref? + if "footnotes" in self.extras and link_text.startswith("^"): + normed_id = re.sub(r'\W', '-', link_text[1:]) + if normed_id in self.footnotes: + self.footnote_ids.append(normed_id) + result = '<sup class="footnote-ref" id="fnref-%s">' \ + '<a href="#fn-%s">%s</a></sup>' \ + % (normed_id, normed_id, len(self.footnote_ids)) + text = text[:start_idx] + result + text[p+1:] + else: + # This id isn't defined, leave the markup alone. + curr_pos = p+1 + continue + + # Now determine what this is by the remainder. + p += 1 + if p == text_length: + return text + + # Inline anchor or img? + if text[p] == '(': # attempt at perf improvement + url, title, url_end_idx = self._extract_url_and_title(text, p) + if url is not None: + # Handle an inline anchor or img. + is_img = start_idx > 0 and text[start_idx-1] == "!" + if is_img: + start_idx -= 1 + + # We've got to encode these to avoid conflicting + # with italics/bold. + url = url.replace('*', self._escape_table['*']) \ + .replace('_', self._escape_table['_']) + if title: + title_str = ' title="%s"' % ( + _xml_escape_attr(title) + .replace('*', self._escape_table['*']) + .replace('_', self._escape_table['_'])) + else: + title_str = '' + if is_img: + img_class_str = self._html_class_str_from_tag("img") + result = '<img src="%s" alt="%s"%s%s%s' \ + % (url.replace('"', '"'), + _xml_escape_attr(link_text), + title_str, img_class_str, self.empty_element_suffix) + if "smarty-pants" in self.extras: + result = result.replace('"', self._escape_table['"']) + curr_pos = start_idx + len(result) + text = text[:start_idx] + result + text[url_end_idx:] + elif start_idx >= anchor_allowed_pos: + result_head = '<a href="%s"%s>' % (url, title_str) + result = '%s%s</a>' % (result_head, link_text) + if "smarty-pants" in self.extras: + result = result.replace('"', self._escape_table['"']) + # <img> allowed from curr_pos on, <a> from + # anchor_allowed_pos on. + curr_pos = start_idx + len(result_head) + anchor_allowed_pos = start_idx + len(result) + text = text[:start_idx] + result + text[url_end_idx:] + else: + # Anchor not allowed here. + curr_pos = start_idx + 1 + continue + + # Reference anchor or img? + else: + match = self._tail_of_reference_link_re.match(text, p) + if match: + # Handle a reference-style anchor or img. + is_img = start_idx > 0 and text[start_idx-1] == "!" + if is_img: + start_idx -= 1 + link_id = match.group("id").lower() + if not link_id: + link_id = link_text.lower() # for links like [this][] + if link_id in self.urls: + url = self.urls[link_id] + # We've got to encode these to avoid conflicting + # with italics/bold. + url = url.replace('*', self._escape_table['*']) \ + .replace('_', self._escape_table['_']) + title = self.titles.get(link_id) + if title: + title = _xml_escape_attr(title) \ + .replace('*', self._escape_table['*']) \ + .replace('_', self._escape_table['_']) + title_str = ' title="%s"' % title + else: + title_str = '' + if is_img: + img_class_str = self._html_class_str_from_tag("img") + result = '<img src="%s" alt="%s"%s%s%s' \ + % (url.replace('"', '"'), + link_text.replace('"', '"'), + title_str, img_class_str, self.empty_element_suffix) + if "smarty-pants" in self.extras: + result = result.replace('"', self._escape_table['"']) + curr_pos = start_idx + len(result) + text = text[:start_idx] + result + text[match.end():] + elif start_idx >= anchor_allowed_pos: + result = '<a href="%s"%s>%s</a>' \ + % (url, title_str, link_text) + result_head = '<a href="%s"%s>' % (url, title_str) + result = '%s%s</a>' % (result_head, link_text) + if "smarty-pants" in self.extras: + result = result.replace('"', self._escape_table['"']) + # <img> allowed from curr_pos on, <a> from + # anchor_allowed_pos on. + curr_pos = start_idx + len(result_head) + anchor_allowed_pos = start_idx + len(result) + text = text[:start_idx] + result + text[match.end():] + else: + # Anchor not allowed here. + curr_pos = start_idx + 1 + else: + # This id isn't defined, leave the markup alone. + curr_pos = match.end() + continue + + # Otherwise, it isn't markup. + curr_pos = start_idx + 1 + + return text + + def header_id_from_text(self, text, prefix, n): + """Generate a header id attribute value from the given header + HTML content. + + This is only called if the "header-ids" extra is enabled. + Subclasses may override this for different header ids. + + @param text {str} The text of the header tag + @param prefix {str} The requested prefix for header ids. This is the + value of the "header-ids" extra key, if any. Otherwise, None. + @param n {int} The <hN> tag number, i.e. `1` for an <h1> tag. + @returns {str} The value for the header tag's "id" attribute. Return + None to not have an id attribute and to exclude this header from + the TOC (if the "toc" extra is specified). + """ + header_id = _slugify(text) + if prefix and isinstance(prefix, base_string_type): + header_id = prefix + '-' + header_id + if header_id in self._count_from_header_id: + self._count_from_header_id[header_id] += 1 + header_id += '-%s' % self._count_from_header_id[header_id] + else: + self._count_from_header_id[header_id] = 1 + return header_id + + _toc = None + def _toc_add_entry(self, level, id, name): + if self._toc is None: + self._toc = [] + self._toc.append((level, id, self._unescape_special_chars(name))) + + _h_re_base = r''' + (^(.+)[ \t]*\n(=+|-+)[ \t]*\n+) + | + (^(\#{1,6}) # \1 = string of #'s + [ \t]%s + (.+?) # \2 = Header text + [ \t]* + (?<!\\) # ensure not an escaped trailing '#' + \#* # optional closing #'s (not counted) + \n+ + ) + ''' + + _h_re = re.compile(_h_re_base % '*', re.X | re.M) + _h_re_tag_friendly = re.compile(_h_re_base % '+', re.X | re.M) + + def _h_sub(self, match): + if match.group(1) is not None: + # Setext header + n = {"=": 1, "-": 2}[match.group(3)[0]] + header_group = match.group(2) + else: + # atx header + n = len(match.group(5)) + header_group = match.group(6) + + demote_headers = self.extras.get("demote-headers") + if demote_headers: + n = min(n + demote_headers, 6) + header_id_attr = "" + if "header-ids" in self.extras: + header_id = self.header_id_from_text(header_group, + self.extras["header-ids"], n) + if header_id: + header_id_attr = ' id="%s"' % header_id + html = self._run_span_gamut(header_group) + if "toc" in self.extras and header_id: + self._toc_add_entry(n, header_id, html) + return "<h%d%s>%s</h%d>\n\n" % (n, header_id_attr, html, n) + + def _do_headers(self, text): + # Setext-style headers: + # Header 1 + # ======== + # + # Header 2 + # -------- + + # atx-style headers: + # # Header 1 + # ## Header 2 + # ## Header 2 with closing hashes ## + # ... + # ###### Header 6 + + if 'tag-friendly' in self.extras: + return self._h_re_tag_friendly.sub(self._h_sub, text) + return self._h_re.sub(self._h_sub, text) + + _marker_ul_chars = '*+-' + _marker_any = r'(?:[%s]|\d+\.)' % _marker_ul_chars + _marker_ul = '(?:[%s])' % _marker_ul_chars + _marker_ol = r'(?:\d+\.)' + + def _list_sub(self, match): + lst = match.group(1) + lst_type = match.group(3) in self._marker_ul_chars and "ul" or "ol" + result = self._process_list_items(lst) + if self.list_level: + return "<%s>\n%s</%s>\n" % (lst_type, result, lst_type) + else: + return "<%s>\n%s</%s>\n\n" % (lst_type, result, lst_type) + + def _do_lists(self, text): + # Form HTML ordered (numbered) and unordered (bulleted) lists. + + # Iterate over each *non-overlapping* list match. + pos = 0 + while True: + # Find the *first* hit for either list style (ul or ol). We + # match ul and ol separately to avoid adjacent lists of different + # types running into each other (see issue #16). + hits = [] + for marker_pat in (self._marker_ul, self._marker_ol): + less_than_tab = self.tab_width - 1 + whole_list = r''' + ( # \1 = whole list + ( # \2 + [ ]{0,%d} + (%s) # \3 = first list item marker + [ \t]+ + (?!\ *\3\ ) # '- - - ...' isn't a list. See 'not_quite_a_list' test case. + ) + (?:.+?) + ( # \4 + \Z + | + \n{2,} + (?=\S) + (?! # Negative lookahead for another list item marker + [ \t]* + %s[ \t]+ + ) + ) + ) + ''' % (less_than_tab, marker_pat, marker_pat) + if self.list_level: # sub-list + list_re = re.compile("^"+whole_list, re.X | re.M | re.S) + else: + list_re = re.compile(r"(?:(?<=\n\n)|\A\n?)"+whole_list, + re.X | re.M | re.S) + match = list_re.search(text, pos) + if match: + hits.append((match.start(), match)) + if not hits: + break + hits.sort() + match = hits[0][1] + start, end = match.span() + middle = self._list_sub(match) + text = text[:start] + middle + text[end:] + pos = start + len(middle) # start pos for next attempted match + + return text + + _list_item_re = re.compile(r''' + (\n)? # leading line = \1 + (^[ \t]*) # leading whitespace = \2 + (?P<marker>%s) [ \t]+ # list marker = \3 + ((?:.+?) # list item text = \4 + (\n{1,2})) # eols = \5 + (?= \n* (\Z | \2 (?P<next_marker>%s) [ \t]+)) + ''' % (_marker_any, _marker_any), + re.M | re.X | re.S) + + _last_li_endswith_two_eols = False + def _list_item_sub(self, match): + item = match.group(4) + leading_line = match.group(1) + if leading_line or "\n\n" in item or self._last_li_endswith_two_eols: + item = self._run_block_gamut(self._outdent(item)) + else: + # Recursion for sub-lists: + item = self._do_lists(self._outdent(item)) + if item.endswith('\n'): + item = item[:-1] + item = self._run_span_gamut(item) + self._last_li_endswith_two_eols = (len(match.group(5)) == 2) + return "<li>%s</li>\n" % item + + def _process_list_items(self, list_str): + # Process the contents of a single ordered or unordered list, + # splitting it into individual list items. + + # The $g_list_level global keeps track of when we're inside a list. + # Each time we enter a list, we increment it; when we leave a list, + # we decrement. If it's zero, we're not in a list anymore. + # + # We do this because when we're not inside a list, we want to treat + # something like this: + # + # I recommend upgrading to version + # 8. Oops, now this line is treated + # as a sub-list. + # + # As a single paragraph, despite the fact that the second line starts + # with a digit-period-space sequence. + # + # Whereas when we're inside a list (or sub-list), that line will be + # treated as the start of a sub-list. What a kludge, huh? This is + # an aspect of Markdown's syntax that's hard to parse perfectly + # without resorting to mind-reading. Perhaps the solution is to + # change the syntax rules such that sub-lists must start with a + # starting cardinal number; e.g. "1." or "a.". + self.list_level += 1 + self._last_li_endswith_two_eols = False + list_str = list_str.rstrip('\n') + '\n' + list_str = self._list_item_re.sub(self._list_item_sub, list_str) + self.list_level -= 1 + return list_str + + def _get_pygments_lexer(self, lexer_name): + try: + from pygments import lexers, util + except ImportError: + return None + try: + return lexers.get_lexer_by_name(lexer_name) + except util.ClassNotFound: + return None + + def _color_with_pygments(self, codeblock, lexer, **formatter_opts): + import pygments + import pygments.formatters + + class HtmlCodeFormatter(pygments.formatters.HtmlFormatter): + def _wrap_code(self, inner): + """A function for use in a Pygments Formatter which + wraps in <code> tags. + """ + yield 0, "<code>" + for tup in inner: + yield tup + yield 0, "</code>" + + def wrap(self, source, outfile): + """Return the source with a code, pre, and div.""" + return self._wrap_div(self._wrap_pre(self._wrap_code(source))) + + formatter_opts.setdefault("cssclass", "codehilite") + formatter = HtmlCodeFormatter(**formatter_opts) + return pygments.highlight(codeblock, lexer, formatter) + + def _code_block_sub(self, match, is_fenced_code_block=False): + lexer_name = None + if is_fenced_code_block: + lexer_name = match.group(1) + if lexer_name: + formatter_opts = self.extras['fenced-code-blocks'] or {} + codeblock = match.group(2) + codeblock = codeblock[:-1] # drop one trailing newline + else: + codeblock = match.group(1) + codeblock = self._outdent(codeblock) + codeblock = self._detab(codeblock) + codeblock = codeblock.lstrip('\n') # trim leading newlines + codeblock = codeblock.rstrip() # trim trailing whitespace + + # Note: "code-color" extra is DEPRECATED. + if "code-color" in self.extras and codeblock.startswith(":::"): + lexer_name, rest = codeblock.split('\n', 1) + lexer_name = lexer_name[3:].strip() + codeblock = rest.lstrip("\n") # Remove lexer declaration line. + formatter_opts = self.extras['code-color'] or {} + + if lexer_name: + def unhash_code( codeblock ): + for key, sanitized in list(self.html_spans.items()): + codeblock = codeblock.replace(key, sanitized) + replacements = [ + ("&", "&"), + ("<", "<"), + (">", ">") + ] + for old, new in replacements: + codeblock = codeblock.replace(old, new) + return codeblock + lexer = self._get_pygments_lexer(lexer_name) + if lexer: + codeblock = unhash_code( codeblock ) + colored = self._color_with_pygments(codeblock, lexer, + **formatter_opts) + return "\n\n%s\n\n" % colored + + codeblock = self._encode_code(codeblock) + pre_class_str = self._html_class_str_from_tag("pre") + code_class_str = self._html_class_str_from_tag("code") + return "\n\n<pre%s><code%s>%s\n</code></pre>\n\n" % ( + pre_class_str, code_class_str, codeblock) + + def _html_class_str_from_tag(self, tag): + """Get the appropriate ' class="..."' string (note the leading + space), if any, for the given tag. + """ + if "html-classes" not in self.extras: + return "" + try: + html_classes_from_tag = self.extras["html-classes"] + except TypeError: + return "" + else: + if tag in html_classes_from_tag: + return ' class="%s"' % html_classes_from_tag[tag] + return "" + + def _do_code_blocks(self, text): + """Process Markdown `<pre><code>` blocks.""" + code_block_re = re.compile(r''' + (?:\n\n|\A\n?) + ( # $1 = the code block -- one or more lines, starting with a space/tab + (?: + (?:[ ]{%d} | \t) # Lines must start with a tab or a tab-width of spaces + .*\n+ + )+ + ) + ((?=^[ ]{0,%d}\S)|\Z) # Lookahead for non-space at line-start, or end of doc + # Lookahead to make sure this block isn't already in a code block. + # Needed when syntax highlighting is being used. + (?![^<]*\</code\>) + ''' % (self.tab_width, self.tab_width), + re.M | re.X) + return code_block_re.sub(self._code_block_sub, text) + + _fenced_code_block_re = re.compile(r''' + (?:\n\n|\A\n?) + ^```([\w+-]+)?[ \t]*\n # opening fence, $1 = optional lang + (.*?) # $2 = code block content + ^```[ \t]*\n # closing fence + ''', re.M | re.X | re.S) + + def _fenced_code_block_sub(self, match): + return self._code_block_sub(match, is_fenced_code_block=True); + + def _do_fenced_code_blocks(self, text): + """Process ```-fenced unindented code blocks ('fenced-code-blocks' extra).""" + return self._fenced_code_block_re.sub(self._fenced_code_block_sub, text) + + # Rules for a code span: + # - backslash escapes are not interpreted in a code span + # - to include one or or a run of more backticks the delimiters must + # be a longer run of backticks + # - cannot start or end a code span with a backtick; pad with a + # space and that space will be removed in the emitted HTML + # See `test/tm-cases/escapes.text` for a number of edge-case + # examples. + _code_span_re = re.compile(r''' + (?<!\\) + (`+) # \1 = Opening run of ` + (?!`) # See Note A test/tm-cases/escapes.text + (.+?) # \2 = The code block + (?<!`) + \1 # Matching closer + (?!`) + ''', re.X | re.S) + + def _code_span_sub(self, match): + c = match.group(2).strip(" \t") + c = self._encode_code(c) + return "<code>%s</code>" % c + + def _do_code_spans(self, text): + # * Backtick quotes are used for <code></code> spans. + # + # * You can use multiple backticks as the delimiters if you want to + # include literal backticks in the code span. So, this input: + # + # Just type ``foo `bar` baz`` at the prompt. + # + # Will translate to: + # + # <p>Just type <code>foo `bar` baz</code> at the prompt.</p> + # + # There's no arbitrary limit to the number of backticks you + # can use as delimters. If you need three consecutive backticks + # in your code, use four for delimiters, etc. + # + # * You can use spaces to get literal backticks at the edges: + # + # ... type `` `bar` `` ... + # + # Turns to: + # + # ... type <code>`bar`</code> ... + return self._code_span_re.sub(self._code_span_sub, text) + + def _encode_code(self, text): + """Encode/escape certain characters inside Markdown code runs. + The point is that in code, these characters are literals, + and lose their special Markdown meanings. + """ + replacements = [ + # Encode all ampersands; HTML entities are not + # entities within a Markdown code span. + ('&', '&'), + # Do the angle bracket song and dance: + ('<', '<'), + ('>', '>'), + ] + for before, after in replacements: + text = text.replace(before, after) + hashed = _hash_text(text) + self._escape_table[text] = hashed + return hashed + + _strike_re = re.compile(r"~~(?=\S)(.+?)(?<=\S)~~", re.S) + def _do_strike(self, text): + text = self._strike_re.sub(r"<strike>\1</strike>", text) + return text + + _strong_re = re.compile(r"(\*\*|__)(?=\S)(.+?[*_]*)(?<=\S)\1", re.S) + _em_re = re.compile(r"(\*|_)(?=\S)(.+?)(?<=\S)\1", re.S) + _code_friendly_strong_re = re.compile(r"\*\*(?=\S)(.+?[*_]*)(?<=\S)\*\*", re.S) + _code_friendly_em_re = re.compile(r"\*(?=\S)(.+?)(?<=\S)\*", re.S) + def _do_italics_and_bold(self, text): + # <strong> must go first: + if "code-friendly" in self.extras: + text = self._code_friendly_strong_re.sub(r"<strong>\1</strong>", text) + text = self._code_friendly_em_re.sub(r"<em>\1</em>", text) + else: + text = self._strong_re.sub(r"<strong>\2</strong>", text) + text = self._em_re.sub(r"<em>\2</em>", text) + return text + + # "smarty-pants" extra: Very liberal in interpreting a single prime as an + # apostrophe; e.g. ignores the fact that "round", "bout", "twer", and + # "twixt" can be written without an initial apostrophe. This is fine because + # using scare quotes (single quotation marks) is rare. + _apostrophe_year_re = re.compile(r"'(\d\d)(?=(\s|,|;|\.|\?|!|$))") + _contractions = ["tis", "twas", "twer", "neath", "o", "n", + "round", "bout", "twixt", "nuff", "fraid", "sup"] + def _do_smart_contractions(self, text): + text = self._apostrophe_year_re.sub(r"’\1", text) + for c in self._contractions: + text = text.replace("'%s" % c, "’%s" % c) + text = text.replace("'%s" % c.capitalize(), + "’%s" % c.capitalize()) + return text + + # Substitute double-quotes before single-quotes. + _opening_single_quote_re = re.compile(r"(?<!\S)'(?=\S)") + _opening_double_quote_re = re.compile(r'(?<!\S)"(?=\S)') + _closing_single_quote_re = re.compile(r"(?<=\S)'") + _closing_double_quote_re = re.compile(r'(?<=\S)"(?=(\s|,|;|\.|\?|!|$))') + def _do_smart_punctuation(self, text): + """Fancifies 'single quotes', "double quotes", and apostrophes. + Converts --, ---, and ... into en dashes, em dashes, and ellipses. + + Inspiration is: <http://daringfireball.net/projects/smartypants/> + See "test/tm-cases/smarty_pants.text" for a full discussion of the + support here and + <http://code.google.com/p/python-markdown2/issues/detail?id=42> for a + discussion of some diversion from the original SmartyPants. + """ + if "'" in text: # guard for perf + text = self._do_smart_contractions(text) + text = self._opening_single_quote_re.sub("‘", text) + text = self._closing_single_quote_re.sub("’", text) + + if '"' in text: # guard for perf + text = self._opening_double_quote_re.sub("“", text) + text = self._closing_double_quote_re.sub("”", text) + + text = text.replace("---", "—") + text = text.replace("--", "–") + text = text.replace("...", "…") + text = text.replace(" . . . ", "…") + text = text.replace(". . .", "…") + return text + + _block_quote_base = r''' + ( # Wrap whole match in \1 + ( + ^[ \t]*>%s[ \t]? # '>' at the start of a line + .+\n # rest of the first line + (.+\n)* # subsequent consecutive lines + \n* # blanks + )+ + ) + ''' + _block_quote_re = re.compile(_block_quote_base % '', re.M | re.X) + _block_quote_re_spoiler = re.compile(_block_quote_base % '[ \t]*?!?', re.M | re.X) + _bq_one_level_re = re.compile('^[ \t]*>[ \t]?', re.M); + _bq_one_level_re_spoiler = re.compile('^[ \t]*>[ \t]*?![ \t]?', re.M); + _bq_all_lines_spoilers = re.compile(r'\A(?:^[ \t]*>[ \t]*?!.*[\n\r]*)+\Z', re.M) + _html_pre_block_re = re.compile(r'(\s*<pre>.+?</pre>)', re.S) + def _dedent_two_spaces_sub(self, match): + return re.sub(r'(?m)^ ', '', match.group(1)) + + def _block_quote_sub(self, match): + bq = match.group(1) + is_spoiler = 'spoiler' in self.extras and self._bq_all_lines_spoilers.match(bq) + # trim one level of quoting + if is_spoiler: + bq = self._bq_one_level_re_spoiler.sub('', bq) + else: + bq = self._bq_one_level_re.sub('', bq) + # trim whitespace-only lines + bq = self._ws_only_line_re.sub('', bq) + bq = self._run_block_gamut(bq) # recurse + + bq = re.sub('(?m)^', ' ', bq) + # These leading spaces screw with <pre> content, so we need to fix that: + bq = self._html_pre_block_re.sub(self._dedent_two_spaces_sub, bq) + + if is_spoiler: + return '<blockquote class="spoiler">\n%s\n</blockquote>\n\n' % bq + else: + return '<blockquote>\n%s\n</blockquote>\n\n' % bq + + def _do_block_quotes(self, text): + if '>' not in text: + return text + if 'spoiler' in self.extras: + return self._block_quote_re_spoiler.sub(self._block_quote_sub, text) + else: + return self._block_quote_re.sub(self._block_quote_sub, text) + + def _form_paragraphs(self, text): + # Strip leading and trailing lines: + text = text.strip('\n') + + # Wrap <p> tags. + grafs = [] + for i, graf in enumerate(re.split(r"\n{2,}", text)): + if graf in self.html_blocks: + # Unhashify HTML blocks + grafs.append(self.html_blocks[graf]) + else: + cuddled_list = None + if "cuddled-lists" in self.extras: + # Need to put back trailing '\n' for `_list_item_re` + # match at the end of the paragraph. + li = self._list_item_re.search(graf + '\n') + # Two of the same list marker in this paragraph: a likely + # candidate for a list cuddled to preceding paragraph + # text (issue 33). Note the `[-1]` is a quick way to + # consider numeric bullets (e.g. "1." and "2.") to be + # equal. + if (li and len(li.group(2)) <= 3 and li.group("next_marker") + and li.group("marker")[-1] == li.group("next_marker")[-1]): + start = li.start() + cuddled_list = self._do_lists(graf[start:]).rstrip("\n") + assert cuddled_list.startswith("<ul>") or cuddled_list.startswith("<ol>") + graf = graf[:start] + + # Wrap <p> tags. + graf = self._run_span_gamut(graf) + grafs.append("<p>" + graf.lstrip(" \t") + "</p>") + + if cuddled_list: + grafs.append(cuddled_list) + + return "\n\n".join(grafs) + + def _add_footnotes(self, text): + if self.footnotes: + footer = [ + '<div class="footnotes">', + '<hr' + self.empty_element_suffix, + '<ol>', + ] + for i, id in enumerate(self.footnote_ids): + if i != 0: + footer.append('') + footer.append('<li id="fn-%s">' % id) + footer.append(self._run_block_gamut(self.footnotes[id])) + backlink = ('<a href="#fnref-%s" ' + 'class="footnoteBackLink" ' + 'title="Jump back to footnote %d in the text.">' + '↩</a>' % (id, i+1)) + if footer[-1].endswith("</p>"): + footer[-1] = footer[-1][:-len("</p>")] \ + + ' ' + backlink + "</p>" + else: + footer.append("\n<p>%s</p>" % backlink) + footer.append('</li>') + footer.append('</ol>') + footer.append('</div>') + return text + '\n\n' + '\n'.join(footer) + else: + return text + + # Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: + # http://bumppo.net/projects/amputator/ + _ampersand_re = re.compile(r'&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)') + _naked_lt_re = re.compile(r'<(?![a-z/?\$!])', re.I) + _naked_gt_re = re.compile(r'''(?<![a-z0-9?!/'"-])>''', re.I) + + def _encode_amps_and_angles(self, text): + # Smart processing for ampersands and angle brackets that need + # to be encoded. + text = self._ampersand_re.sub('&', text) + + # Encode naked <'s + text = self._naked_lt_re.sub('<', text) + + # Encode naked >'s + # Note: Other markdown implementations (e.g. Markdown.pl, PHP + # Markdown) don't do this. + text = self._naked_gt_re.sub('>', text) + return text + + def _encode_backslash_escapes(self, text): + for ch, escape in list(self._escape_table.items()): + text = text.replace("\\"+ch, escape) + return text + + _auto_link_re = re.compile(r'<((https?|ftp):[^\'">\s]+)>', re.I) + def _auto_link_sub(self, match): + g1 = match.group(1) + return '<a href="%s">%s</a>' % (g1, g1) + + _auto_email_link_re = re.compile(r""" + < + (?:mailto:)? + ( + [-.\w]+ + \@ + [-\w]+(\.[-\w]+)*\.[a-z]+ + ) + > + """, re.I | re.X | re.U) + def _auto_email_link_sub(self, match): + return self._encode_email_address( + self._unescape_special_chars(match.group(1))) + + def _do_auto_links(self, text): + text = self._auto_link_re.sub(self._auto_link_sub, text) + text = self._auto_email_link_re.sub(self._auto_email_link_sub, text) + return text + + def _encode_email_address(self, addr): + # Input: an email address, e.g. "foo@example.com" + # + # Output: the email address as a mailto link, with each character + # of the address encoded as either a decimal or hex entity, in + # the hopes of foiling most address harvesting spam bots. E.g.: + # + # <a href="mailto:foo@e + # xample.com">foo + # @example.com</a> + # + # Based on a filter by Matthew Wickline, posted to the BBEdit-Talk + # mailing list: <http://tinyurl.com/yu7ue> + chars = [_xml_encode_email_char_at_random(ch) + for ch in "mailto:" + addr] + # Strip the mailto: from the visible part. + addr = '<a href="%s">%s</a>' \ + % (''.join(chars), ''.join(chars[7:])) + return addr + + def _do_link_patterns(self, text): + """Caveat emptor: there isn't much guarding against link + patterns being formed inside other standard Markdown links, e.g. + inside a [link def][like this]. + + Dev Notes: *Could* consider prefixing regexes with a negative + lookbehind assertion to attempt to guard against this. + """ + link_from_hash = {} + for regex, repl in self.link_patterns: + replacements = [] + for match in regex.finditer(text): + if hasattr(repl, "__call__"): + href = repl(match) + else: + href = match.expand(repl) + replacements.append((match.span(), href)) + for (start, end), href in reversed(replacements): + escaped_href = ( + href.replace('"', '"') # b/c of attr quote + # To avoid markdown <em> and <strong>: + .replace('*', self._escape_table['*']) + .replace('_', self._escape_table['_'])) + link = '<a href="%s">%s</a>' % (escaped_href, text[start:end]) + hash = _hash_text(link) + link_from_hash[hash] = link + text = text[:start] + hash + text[end:] + for hash, link in list(link_from_hash.items()): + text = text.replace(hash, link) + return text + + def _unescape_special_chars(self, text): + # Swap back in all the special characters we've hidden. + for ch, hash in list(self._escape_table.items()): + text = text.replace(hash, ch) + return text + + def _outdent(self, text): + # Remove one level of line-leading tabs or spaces + return self._outdent_re.sub('', text) + + +class MarkdownWithExtras(Markdown): + """A markdowner class that enables most extras: + + - footnotes + - code-color (only has effect if 'pygments' Python module on path) + + These are not included: + - pyshell (specific to Python-related documenting) + - code-friendly (because it *disables* part of the syntax) + - link-patterns (because you need to specify some actual + link-patterns anyway) + """ + extras = ["footnotes", "code-color"] + + +#---- internal support functions + +class UnicodeWithAttrs(unicode): + """A subclass of unicode used for the return value of conversion to + possibly attach some attributes. E.g. the "toc_html" attribute when + the "toc" extra is used. + """ + metadata = None + _toc = None + def toc_html(self): + """Return the HTML for the current TOC. + + This expects the `_toc` attribute to have been set on this instance. + """ + if self._toc is None: + return None + + def indent(): + return ' ' * (len(h_stack) - 1) + lines = [] + h_stack = [0] # stack of header-level numbers + for level, id, name in self._toc: + if level > h_stack[-1]: + lines.append("%s<ul>" % indent()) + h_stack.append(level) + elif level == h_stack[-1]: + lines[-1] += "</li>" + else: + while level < h_stack[-1]: + h_stack.pop() + if not lines[-1].endswith("</li>"): + lines[-1] += "</li>" + lines.append("%s</ul></li>" % indent()) + lines.append('%s<li><a href="#%s">%s</a>' % ( + indent(), id, name)) + while len(h_stack) > 1: + h_stack.pop() + if not lines[-1].endswith("</li>"): + lines[-1] += "</li>" + lines.append("%s</ul>" % indent()) + return '\n'.join(lines) + '\n' + toc_html = property(toc_html) + +## {{{ http://code.activestate.com/recipes/577257/ (r1) +_slugify_strip_re = re.compile(r'[^\w\s-]') +_slugify_hyphenate_re = re.compile(r'[-\s]+') +def _slugify(value): + """ + Normalizes string, converts to lowercase, removes non-alpha characters, + and converts spaces to hyphens. + + From Django's "django/template/defaultfilters.py". + """ + import unicodedata + value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode() + value = _slugify_strip_re.sub('', value).strip().lower() + return _slugify_hyphenate_re.sub('-', value) +## end of http://code.activestate.com/recipes/577257/ }}} + + +# From http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549 +def _curry(*args, **kwargs): + function, args = args[0], args[1:] + def result(*rest, **kwrest): + combined = kwargs.copy() + combined.update(kwrest) + return function(*args + rest, **combined) + return result + +# Recipe: regex_from_encoded_pattern (1.0) +def _regex_from_encoded_pattern(s): + """'foo' -> re.compile(re.escape('foo')) + '/foo/' -> re.compile('foo') + '/foo/i' -> re.compile('foo', re.I) + """ + if s.startswith('/') and s.rfind('/') != 0: + # Parse it: /PATTERN/FLAGS + idx = s.rfind('/') + pattern, flags_str = s[1:idx], s[idx+1:] + flag_from_char = { + "i": re.IGNORECASE, + "l": re.LOCALE, + "s": re.DOTALL, + "m": re.MULTILINE, + "u": re.UNICODE, + } + flags = 0 + for char in flags_str: + try: + flags |= flag_from_char[char] + except KeyError: + raise ValueError("unsupported regex flag: '%s' in '%s' " + "(must be one of '%s')" + % (char, s, ''.join(list(flag_from_char.keys())))) + return re.compile(s[1:idx], flags) + else: # not an encoded regex + return re.compile(re.escape(s)) + +# Recipe: dedent (0.1.2) +def _dedentlines(lines, tabsize=8, skip_first_line=False): + """_dedentlines(lines, tabsize=8, skip_first_line=False) -> dedented lines + + "lines" is a list of lines to dedent. + "tabsize" is the tab width to use for indent width calculations. + "skip_first_line" is a boolean indicating if the first line should + be skipped for calculating the indent width and for dedenting. + This is sometimes useful for docstrings and similar. + + Same as dedent() except operates on a sequence of lines. Note: the + lines list is modified **in-place**. + """ + DEBUG = False + if DEBUG: + print("dedent: dedent(..., tabsize=%d, skip_first_line=%r)"\ + % (tabsize, skip_first_line)) + margin = None + for i, line in enumerate(lines): + if i == 0 and skip_first_line: continue + indent = 0 + for ch in line: + if ch == ' ': + indent += 1 + elif ch == '\t': + indent += tabsize - (indent % tabsize) + elif ch in '\r\n': + continue # skip all-whitespace lines + else: + break + else: + continue # skip all-whitespace lines + if DEBUG: print("dedent: indent=%d: %r" % (indent, line)) + if margin is None: + margin = indent + else: + margin = min(margin, indent) + if DEBUG: print("dedent: margin=%r" % margin) + + if margin is not None and margin > 0: + for i, line in enumerate(lines): + if i == 0 and skip_first_line: continue + removed = 0 + for j, ch in enumerate(line): + if ch == ' ': + removed += 1 + elif ch == '\t': + removed += tabsize - (removed % tabsize) + elif ch in '\r\n': + if DEBUG: print("dedent: %r: EOL -> strip up to EOL" % line) + lines[i] = lines[i][j:] + break + else: + raise ValueError("unexpected non-whitespace char %r in " + "line %r while removing %d-space margin" + % (ch, line, margin)) + if DEBUG: + print("dedent: %r: %r -> removed %d/%d"\ + % (line, ch, removed, margin)) + if removed == margin: + lines[i] = lines[i][j+1:] + break + elif removed > margin: + lines[i] = ' '*(removed-margin) + lines[i][j+1:] + break + else: + if removed: + lines[i] = lines[i][removed:] + return lines + +def _dedent(text, tabsize=8, skip_first_line=False): + """_dedent(text, tabsize=8, skip_first_line=False) -> dedented text + + "text" is the text to dedent. + "tabsize" is the tab width to use for indent width calculations. + "skip_first_line" is a boolean indicating if the first line should + be skipped for calculating the indent width and for dedenting. + This is sometimes useful for docstrings and similar. + + textwrap.dedent(s), but don't expand tabs to spaces + """ + lines = text.splitlines(1) + _dedentlines(lines, tabsize=tabsize, skip_first_line=skip_first_line) + return ''.join(lines) + + +class _memoized(object): + """Decorator that caches a function's return value each time it is called. + If called later with the same arguments, the cached value is returned, and + not re-evaluated. + + http://wiki.python.org/moin/PythonDecoratorLibrary + """ + def __init__(self, func): + self.func = func + self.cache = {} + def __call__(self, *args): + try: + return self.cache[args] + except KeyError: + self.cache[args] = value = self.func(*args) + return value + except TypeError: + # uncachable -- for instance, passing a list as an argument. + # Better to not cache than to blow up entirely. + return self.func(*args) + def __repr__(self): + """Return the function's docstring.""" + return self.func.__doc__ + + +def _xml_oneliner_re_from_tab_width(tab_width): + """Standalone XML processing instruction regex.""" + return re.compile(r""" + (?: + (?<=\n\n) # Starting after a blank line + | # or + \A\n? # the beginning of the doc + ) + ( # save in $1 + [ ]{0,%d} + (?: + <\?\w+\b\s+.*?\?> # XML processing instruction + | + <\w+:\w+\b\s+.*?/> # namespaced single tag + ) + [ \t]* + (?=\n{2,}|\Z) # followed by a blank line or end of document + ) + """ % (tab_width - 1), re.X) +_xml_oneliner_re_from_tab_width = _memoized(_xml_oneliner_re_from_tab_width) + +def _hr_tag_re_from_tab_width(tab_width): + return re.compile(r""" + (?: + (?<=\n\n) # Starting after a blank line + | # or + \A\n? # the beginning of the doc + ) + ( # save in \1 + [ ]{0,%d} + <(hr) # start tag = \2 + \b # word break + ([^<>])*? # + /?> # the matching end tag + [ \t]* + (?=\n{2,}|\Z) # followed by a blank line or end of document + ) + """ % (tab_width - 1), re.X) +_hr_tag_re_from_tab_width = _memoized(_hr_tag_re_from_tab_width) + + +def _xml_escape_attr(attr, skip_single_quote=True): + """Escape the given string for use in an HTML/XML tag attribute. + + By default this doesn't bother with escaping `'` to `'`, presuming that + the tag attribute is surrounded by double quotes. + """ + escaped = (attr + .replace('&', '&') + .replace('"', '"') + .replace('<', '<') + .replace('>', '>')) + if not skip_single_quote: + escaped = escaped.replace("'", "'") + return escaped + + +def _xml_encode_email_char_at_random(ch): + r = random() + # Roughly 10% raw, 45% hex, 45% dec. + # '@' *must* be encoded. I [John Gruber] insist. + # Issue 26: '_' must be encoded. + if r > 0.9 and ch not in "@_": + return ch + elif r < 0.45: + # The [1:] is to drop leading '0': 0x63 -> x63 + return '&#%s;' % hex(ord(ch))[1:] + else: + return '&#%s;' % ord(ch) + + + +#---- mainline + +class _NoReflowFormatter(optparse.IndentedHelpFormatter): + """An optparse formatter that does NOT reflow the description.""" + def format_description(self, description): + return description or "" + +def _test(): + import doctest + doctest.testmod() + +def main(argv=None): + if argv is None: + argv = sys.argv + if not logging.root.handlers: + logging.basicConfig() + + usage = "usage: %prog [PATHS...]" + version = "%prog "+__version__ + parser = optparse.OptionParser(prog="markdown2", usage=usage, + version=version, description=cmdln_desc, + formatter=_NoReflowFormatter()) + parser.add_option("-v", "--verbose", dest="log_level", + action="store_const", const=logging.DEBUG, + help="more verbose output") + parser.add_option("--encoding", + help="specify encoding of text content") + parser.add_option("--html4tags", action="store_true", default=False, + help="use HTML 4 style for empty element tags") + parser.add_option("-s", "--safe", metavar="MODE", dest="safe_mode", + help="sanitize literal HTML: 'escape' escapes " + "HTML meta chars, 'replace' replaces with an " + "[HTML_REMOVED] note") + parser.add_option("-x", "--extras", action="append", + help="Turn on specific extra features (not part of " + "the core Markdown spec). See above.") + parser.add_option("--use-file-vars", + help="Look for and use Emacs-style 'markdown-extras' " + "file var to turn on extras. See " + "<https://github.com/trentm/python-markdown2/wiki/Extras>") + parser.add_option("--link-patterns-file", + help="path to a link pattern file") + parser.add_option("--self-test", action="store_true", + help="run internal self-tests (some doctests)") + parser.add_option("--compare", action="store_true", + help="run against Markdown.pl as well (for testing)") + parser.set_defaults(log_level=logging.INFO, compare=False, + encoding="utf-8", safe_mode=None, use_file_vars=False) + opts, paths = parser.parse_args() + log.setLevel(opts.log_level) + + if opts.self_test: + return _test() + + if opts.extras: + extras = {} + for s in opts.extras: + splitter = re.compile("[,;: ]+") + for e in splitter.split(s): + if '=' in e: + ename, earg = e.split('=', 1) + try: + earg = int(earg) + except ValueError: + pass + else: + ename, earg = e, None + extras[ename] = earg + else: + extras = None + + if opts.link_patterns_file: + link_patterns = [] + f = open(opts.link_patterns_file) + try: + for i, line in enumerate(f.readlines()): + if not line.strip(): continue + if line.lstrip().startswith("#"): continue + try: + pat, href = line.rstrip().rsplit(None, 1) + except ValueError: + raise MarkdownError("%s:%d: invalid link pattern line: %r" + % (opts.link_patterns_file, i+1, line)) + link_patterns.append( + (_regex_from_encoded_pattern(pat), href)) + finally: + f.close() + else: + link_patterns = None + + from os.path import join, dirname, abspath, exists + markdown_pl = join(dirname(dirname(abspath(__file__))), "test", + "Markdown.pl") + if not paths: + paths = ['-'] + for path in paths: + if path == '-': + text = sys.stdin.read() + else: + fp = codecs.open(path, 'r', opts.encoding) + text = fp.read() + fp.close() + if opts.compare: + from subprocess import Popen, PIPE + print("==== Markdown.pl ====") + p = Popen('perl %s' % markdown_pl, shell=True, stdin=PIPE, stdout=PIPE, close_fds=True) + p.stdin.write(text.encode('utf-8')) + p.stdin.close() + perl_html = p.stdout.read().decode('utf-8') + if py3: + sys.stdout.write(perl_html) + else: + sys.stdout.write(perl_html.encode( + sys.stdout.encoding or "utf-8", 'xmlcharrefreplace')) + print("==== markdown2.py ====") + html = markdown(text, + html4tags=opts.html4tags, + safe_mode=opts.safe_mode, + extras=extras, link_patterns=link_patterns, + use_file_vars=opts.use_file_vars) + if py3: + sys.stdout.write(html) + else: + sys.stdout.write(html.encode( + sys.stdout.encoding or "utf-8", 'xmlcharrefreplace')) + if extras and "toc" in extras: + log.debug("toc_html: " + + html.toc_html.encode(sys.stdout.encoding or "utf-8", 'xmlcharrefreplace')) + if opts.compare: + test_dir = join(dirname(dirname(abspath(__file__))), "test") + if exists(join(test_dir, "test_markdown2.py")): + sys.path.insert(0, test_dir) + from test_markdown2 import norm_html_from_html + norm_html = norm_html_from_html(html) + norm_perl_html = norm_html_from_html(perl_html) + else: + norm_html = html + norm_perl_html = perl_html + print("==== match? %r ====" % (norm_perl_html == norm_html)) + + +if __name__ == "__main__": + sys.exit( main(sys.argv) ) \ No newline at end of file diff --git a/web2py/gluon/contrib/markmin/__init__.py b/web2py/gluon/contrib/markmin/__init__.py new file mode 100644 index 0000000..139597f --- /dev/null +++ b/web2py/gluon/contrib/markmin/__init__.py @@ -0,0 +1,2 @@ + + diff --git a/web2py/gluon/contrib/markmin/markmin.html b/web2py/gluon/contrib/markmin/markmin.html new file mode 100644 index 0000000..98aa58c --- /dev/null +++ b/web2py/gluon/contrib/markmin/markmin.html @@ -0,0 +1,92 @@ +<!doctype html> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<meta http-equiv="content-type" content="text/html; charset=utf-8" /> +<style> + blockquote { background-color: #FFFAAE; padding: 7px; } + table { border-collapse: collapse; } + thead td { border-bottom: 1px solid; } + tfoot td { border-top: 1px solid; } + .tableclass1 { background-color: lime; } + .tableclass1 thead { color: yellow; background-color: green; } + .tableclass1 tfoot { color: yellow; background-color: green; } + .tableclass1 .even td { background-color: #80FF7F; } + .tableclass1 .first td {border-top: 1px solid; } + + td.num { text-align: right; } + pre { background-color: #E0E0E0; padding: 5px; } +</style> +<title>Markmin markup language + + +

    Markmin markup language

    About

    This is a new markup language that we call markmin designed to produce high quality scientific papers and books and also put them online. We provide serializers for html, latex and pdf. It is implemented in the markmin2html function in the markmin2html.py.

    Example of usage:

    m = "Hello **world** [[link http://web2py.com]]"
    +from markmin2html import markmin2html
    +print markmin2html(m)
    +from markmin2latex import markmin2latex
    +print markmin2latex(m)
    +from markmin2pdf import markmin2pdf # requires pdflatex
    +print markmin2pdf(m)
    ====================

    This is a test block with new features:

    This is a blockquote with a list with tables in it:

    This is a paragraph before list. You can continue paragraph on the next lines.
    This is an ordered list with tables:
    1. Item 1
    2. Item 2
    3. aabbcc
      112233
    4. Item 4
      T1T2t3
      aaabbbccc
      dddfffggg
      12305.0

    This this a new paragraph with a table. Table has header, footer, sections, odd and even rows:

    Title 1Title 2Title 3
    data 1data 22.00
    data 3data4(long)23.00
    data 533.50
    New sectionNew data5.00
    data 1data2(long)100.45
    data 312.50
    data 4data 5.33
    data 6data7(long)8.01
    data 8514
    Total:9 items698,79

    Multilevel lists

    Now lists can be multilevel:

    1. Ordered item 1 on level 1. You can continue item text on next strings
      1. Ordered item 1 of sublevel 2 with a paragraph (paragraph can start with point after plus or minus characters, e.g. ++. or --.)

      2. This is another item. But with 3 paragraphs, blockquote and sublists:

        This is the second paragraph in the item. You can add paragraphs to an item, using point notation, where first characters in the string are sequence of points with space between them and another string. For example, this paragraph (in sublevel 2) starts with two points:

        .. This is the second paragraph...

        this is a blockquote in a list

        You can use blockquote with headers, paragraphs, tables and lists in it:
        Tables can have or have not header and footer. This table is defined without any header and footer in it:
        redfox0
        bluedolphin1000
        greenleaf10000

        This is yet another paragraph in the item.

        • This is an item of unordered list (sublevel 3)
        • This is the second item of the unordered list (sublevel 3)
              1. This is a single item of ordered list in sublevel 6

            and this is a paragraph in sublevel 4

        • This is a new item with paragraph in sublevel 3.

          1. Start ordered list in sublevel 4 with code block:
            line 1
            +  line 2
            +     line 3
          2. Yet another item with code block:

              line 1
            +line 2
            +  line 3
            This item finishes with this paragraph.

          Item in sublevel 3 can be continued with paragraphs.

            this is another
          +code block
          +    in the
          +  sublevel 3 item
        1. The last item in sublevel 3

        This is a continuous paragraph for item 2 in sublevel 2. You can use such structure to create difficult structured documents.

      3. item 3 in sublevel 2
      • item 1 in sublevel 2 (new unordered list)
      • item 2 in sublevel 2
      • item 3 in sublevel 2
      1. item 1 in sublevel 2 (new ordered list)
      2. item 2 in sublevel 2
      3. item 3 in sublevle 2
    2. item 2 in level 1
    3. item 3 in level 1
    • new unordered list (item 1 in level 1)
    • level 2 in level 1
    • level 3 in level 1
    • level 4 in level 1

    This is the last section of the test

    Single paragraph with '----' in it will be turned into separator:


    And this is the last paragraph in the test. Be happy!

    ====================

    Why?

    We wanted a markup language with the following requirements:

    • less than 300 lines of functional code
    • easy to read
    • secure
    • support table, ul, ol, code
    • support html5 video and audio elements (html serialization only)
    • can align images and resize them
    • can specify class for tables and code elements
    • can add anchors
    • does not use _ for markup (since it creates odd behavior)
    • automatically links urls
    • fast
    • easy to extend
    • supports latex and pdf including references
    • allows to describe the markup in the markup (this document is generated from markmin syntax)

    (results depend on text but in average for text ~100K markmin is 30% faster than markdown, for text ~10K it is 10x faster)

    The web2py book published by lulu, for example, was entirely generated with markmin2pdf from the online web2py wiki

    Download

    markmin2html.py and markmin2latex.py are single files and have no web2py dependence. Their license is BSD.

    Examples

    Bold, italic, code and links

    SOURCEOUTPUT
    # titletitle
    ## sectionsection
    ### subsectionsubsection
    **bold**bold
    ''italic''italic
    ~~strikeout~~strikeout
    ``verbatim``verbatim
    ``color with **bold**``:redcolor with bold
    ``many colors``:color[blue:#ffff00]many colors
    http://google.comhttp://google.com
    [[**click** me #myanchor]]click me
    [[click me [extra info] #myanchor popup]]click me

    More on links

    The format is always [[title link]] or [[title [extra] link]]. Notice you can nest bold, italic, strikeout and code inside the link title.

    Anchors

    You can place an anchor anywhere in the text using the syntax [[name]] where name is the name of the anchor. You can then link the anchor with link, i.e. [[link #myanchor]] or link with an extra info, i.e. [[link with an extra info [extra info] #myanchor]].

    Images

    alt-string for the image This paragraph has an image aligned to the right with a width of 200px. Its is placed using the code

    [[alt-string for the image [the image title] http://www.web2py.com/examples/static/web2py_logo.png right 200px]].

    Unordered Lists

    - Dog
    +- Cat
    +- Mouse

    is rendered as

    • Dog
    • Cat
    • Mouse

    Two new lines between items break the list in two lists.

    Ordered Lists

    + Dog
    ++ Cat
    ++ Mouse

    is rendered as

    1. Dog
    2. Cat
    3. Mouse

    Multilevel Lists

    + Dogs
    + -- red
    + -- brown
    + -- black
    ++ Cats
    + -- fluffy
    + -- smooth
    + -- bald
    ++ Mice
    + -- small
    + -- big
    + -- huge

    is rendered as

    1. Dogs
      • red
      • brown
      • black
    2. Cats
      • fluffy
      • smooth
      • bald
    3. Mice
      • small
      • big
      • huge

    Tables (with optional header and/or footer)

    Something like this

    -----------------
    +**A**|**B**|**C**
    +=================
    +  0  |  0  |  X
    +  0  |  X  |  0
    +  X  |  0  |  0
    +=================
    +**D**|**F**|**G**
    +-----------------:abc[id]
    is a table and is rendered as
    ABC
    00X
    0X0
    X00
    DFG
    Four or more dashes delimit the table and | separates the columns. The :abc, :id[abc_1] or :abc[abc_1] at the end sets the class and/or id for the table and it is optional.

    Blockquote

    A table with a single cell is rendered as a blockquote:

    Hello world

    Blockquote can contain headers, paragraphs, lists and tables:

    -----
    +  This is a paragraph in a blockquote
    +
    +  + item 1
    +  + item 2
    +  -- item 2.1
    +  -- item 2.2
    +  + item 3
    +
    +  ---------
    +  0 | 0 | X
    +  0 | X | 0
    +  X | 0 | 0
    +  ---------:tableclass1
    +-----

    is rendered as:

    This is a paragraph in a blockquote
    1. item 1
    2. item 2
      • item 2.1
      • item 2.2
    3. item 3
    00X
    0X0
    X00

    Code, <code>, escaping and extra stuff

    def test():
    +    return "this is Python code"

    Optionally a ` inside a ``...`` block can be inserted escaped with !`!.

    NOTE: You can escape markmin constructions ('',``,**,~~,[,{,]},$,@) with '\' character: so \`\` can replace !`!`! escape string

    The :python after the markup is also optional. If present, by default, it is used to set the class of the <code> block. The behavior can be overridden by passing an argument extra to the render function. For example:

    markmin2html("``aaa``:custom",
    +             extra=dict(custom=lambda text: 'x'+text+'x'))

    generates

    'xaaax'

    (the ``...``:custom block is rendered by the custom=lambda function passed to render).

    Html5 support

    Markmin also supports the <video> and <audio> html5 tags using the notation:

    [[message link video]]
    +[[message link audio]]
    +
    +[[message [title] link video]]
    +[[message [title] link audio]]
    where message will be shown in brousers without HTML5 video/audio tags support.

    Latex and other extensions

    Formulas can be embedded into HTML with $$formula$$. You can use Google charts to render the formula:

    LATEX = '<img src="http://chart.apis.google.com/chart?cht=tx&chl=%s" />'
    +markmin2html(text,{'latex':lambda code: LATEX % code.replace('"','\"')})

    Code with syntax highlighting

    This requires a syntax highlighting tool, such as the web2py CODE helper.

    extra={'code_cpp':lambda text: CODE(text,language='cpp').xml(),
    +       'code_java':lambda text: CODE(text,language='java').xml(),
    +       'code_python':lambda text: CODE(text,language='python').xml(),
    +       'code_html':lambda text: CODE(text,language='html').xml()}
    or simple:
    extra={'code':lambda text,lang='python': CODE(text,language=lang).xml()}
    markmin2html(text,extra=extra)

    Code can now be marked up as in this example:

    ``
    +<html><body>example</body></html>
    +``:code_html
    OR
    ``
    +<html><body>example</body></html>
    +``:code[html]

    Citations and References

    Citations are treated as internal links in html and proper citations in latex if there is a final section called "References". Items like

    - [[key]] value

    in the References will be translated into Latex

    \bibitem{key} value

    Here is an example of usage:

    As shown in Ref.``mdipierro``:cite
    +
    +## References
    +
    +- [[mdipierro]] web2py Manual, 3rd Edition, lulu.com

    Caveats

    <ul/>, <ol/>, <code/>, <table/>, <blockquote/>, <h1/>, ..., <h6/> do not have <p>...</p> around them.

    + + diff --git a/web2py/gluon/contrib/markmin/markmin.pdf b/web2py/gluon/contrib/markmin/markmin.pdf new file mode 100644 index 0000000000000000000000000000000000000000..36cf02073ed2e3a5e33566fa27dd9fc08e04c17b GIT binary patch literal 116299 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

    929j)LrD(+-?lz+8=S{rpw# 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 literal 0 HcmV?d00001 diff --git a/web2py/gluon/contrib/markmin/markmin2html.py b/web2py/gluon/contrib/markmin/markmin2html.py new file mode 100644 index 0000000..c58374f --- /dev/null +++ b/web2py/gluon/contrib/markmin/markmin2html.py @@ -0,0 +1,1564 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# created by Massimo Di Pierro +# recreated by Vladyslav Kozlovskyy +# license MIT/BSD/GPL +from __future__ import print_function +import re +import sys +import urllib +import ast + +PY2 = sys.version_info[0] == 2 + +if PY2: + from urllib import quote as urllib_quote + from string import maketrans +else: + from urllib.parse import quote as urllib_quote + maketrans = str.maketrans + + +""" +TODO: next version should use MathJax + + +""" + +__all__ = ['render', 'markmin2html', 'markmin_escape'] + +__doc__ = """ +# Markmin markup language + +## About + +This is a new markup language that we call markmin designed to produce high quality scientific papers and books and also put them online. We provide serializers for html, latex and pdf. It is implemented in the ``markmin2html`` function in the ``markmin2html.py``. + +Example of usage: + +`` +m = "Hello **world** [[link http://web2py.com]]" +from markmin2html import markmin2html +print(markmin2html(m)) +from markmin2latex import markmin2latex +print(markmin2latex(m)) +from markmin2pdf import markmin2pdf # requires pdflatex +print(markmin2pdf(m)) +`` +==================== +# This is a test block + with new features: +This is a blockquote with +a list with tables in it: +----------- + This is a paragraph before list. + You can continue paragraph on the + next lines. + + This is an ordered list with tables: + + Item 1 + + Item 2 + + -------- + aa|bb|cc + 11|22|33 + --------:tableclass1[tableid1] + + Item 4 + ----------- + T1| T2| t3 + =========== + aaa|bbb|ccc + ddd|fff|ggg + 123|0 |5.0 + -----------:tableclass1 +-----------:blockquoteclass[blockquoteid] + +This this a new paragraph +with a followed table. +Table has header, footer, sections, +odd and even rows: +------------------------------- +**Title 1**|**Title 2**|**Title 3** +============================== +data 1 | data 2 | 2.00 +data 3 |data4(long)| 23.00 + |data 5 | 33.50 +============================== +New section|New data | 5.00 +data 1 |data2(long)|100.45 + |data 3 | 12.50 +data 4 | data 5 | .33 +data 6 |data7(long)| 8.01 + |data 8 | 514 +============================== +Total: | 9 items |698,79 +------------------------------:tableclass1[tableid2] + +## Multilevel + lists + +Now lists can be multilevel: + ++ Ordered item 1 on level 1. + You can continue item text on + next strings + +. paragraph in an item + +++. Ordered item 1 of sublevel 2 with + a paragraph (paragraph can start + with point after plus or minus + characters, e.g. **++.** or **--.**) + +++. This is another item. But with 3 paragraphs, + blockquote and sublists: + +.. This is the second paragraph in the item. You + can add paragraphs to an item, using point + notation, where first characters in the string + are sequence of points with space between + them and another string. For example, this + paragraph (in sublevel 2) starts with two points: + ``.. This is the second paragraph...`` + +.. ---------- + ### this is a blockquote in a list + + You can use blockquote with headers, paragraphs, + tables and lists in it: + + Tables can have or have not header and footer. + This table is defined without any header + and footer in it: + --------------------- + red |fox | 0 + blue |dolphin | 1000 + green|leaf | 10000 + --------------------- + ---------- + +.. This is yet another paragraph in the item. + +--- This is an item of unordered list **(sublevel 3)** +--- This is the second item of the unordered list ''(sublevel 3)'' + +++++++ This is a single item of ordered list in sublevel 6 +.... and this is a paragraph in sublevel 4 +---. This is a new item with paragraph in sublevel 3. +++++ Start ordered list in sublevel 4 with code block: `` +line 1 + line 2 + line 3 +`` +++++. Yet another item with code block (we need to indent \`\` to add code block as part of item): + `` + line 1 +line 2 + line 3 +`` + This item finishes with this paragraph. + +... Item in sublevel 3 can be continued with paragraphs. + +... `` + this is another +code block + in the + sublevel 3 item +`` + ++++ The last item in sublevel 3 +.. This is a continuous paragraph for item 2 in sublevel 2. + You can use such structure to create difficult structured + documents. + +++ item 3 in sublevel 2 +-- item 1 in sublevel 2 (new unordered list) +-- item 2 in sublevel 2 +-- item 3 in sublevel 2 + +++ item 1 in sublevel 2 (new ordered list) +++ item 2 in sublevel 2 +++ item 3 in sublevle 2 + ++ item 2 in level 1 ++ item 3 in level 1 +- new unordered list (item 1 in level 1) +- level 2 in level 1 + +- level 3 in level 1 +- level 4 in level 1 +## This is the last section of the test + +Single paragraph with '----' in it will be turned into separator: + +----------- + +And this is the last paragraph in +the test. Be happy! + +==================== + +## Why? + +We wanted a markup language with the following requirements: +- less than 300 lines of functional code +- easy to read +- secure +- support table, ul, ol, code +- support html5 video and audio elements (html serialization only) +- can align images and resize them +- can specify class for tables, blockquotes and code elements +- can add anchors +- does not use _ for markup (since it creates odd behavior) +- automatically links urls +- fast +- easy to extend +- supports latex and pdf including references +- allows to describe the markup in the markup (this document is generated from markmin syntax) + +(results depend on text but in average for text ~100K markmin is 30% faster than markdown, for text ~10K it is 10x faster) + +The [[web2py book http://www.lulu.com/product/paperback/web2py-%283rd-edition%29/12822827]] published by lulu, for example, was entirely generated with markmin2pdf from the online [[web2py wiki http://www.web2py.com/book]] + +## Download + +- http://web2py.googlecode.com/hg/gluon/contrib/markmin/markmin2html.py +- http://web2py.googlecode.com/hg/gluon/contrib/markmin/markmin2latex.py +- http://web2py.googlecode.com/hg/gluon/contrib/markmin/markmin2pdf.py + +markmin2html.py and markmin2latex.py are single files and have no web2py dependence. Their license is BSD. + +## Examples + +### Bold, italic, code and links + +------------------------------------------------------------------------------ +**SOURCE** | **OUTPUT** +============================================================================== +``# title`` | **title** +``## section`` | **section** +``### subsection`` | **subsection** +``**bold**`` | **bold** +``''italic''`` | ''italic'' +``~~strikeout~~`` | ~~strikeout~~ +``!`!`verbatim`!`!`` | ``verbatim`` +``\`\`color with **bold**\`\`:red`` | ``color with **bold**``:red +``\`\`many colors\`\`:color[blue:#ffff00]`` | ``many colors``:color[blue:#ffff00] +``http://google.com`` | http://google.com +``[[**click** me #myanchor]]`` | [[**click** me #myanchor]] +``[[click me [extra info] #myanchor popup]]`` | [[click me [extra info] #myanchor popup]] +------------------------------------------------------------------------------- + +### More on links + +The format is always ``[[title link]]`` or ``[[title [extra] link]]``. Notice you can nest bold, italic, strikeout and code inside the link ``title``. + +### Anchors [[myanchor]] + +You can place an anchor anywhere in the text using the syntax ``[[name]]`` where ''name'' is the name of the anchor. +You can then link the anchor with [[link #myanchor]], i.e. ``[[link #myanchor]]`` or [[link with an extra info [extra info] #myanchor]], i.e. +``[[link with an extra info [extra info] #myanchor]]``. + +### Images + +[[alt-string for the image [the image title] http://www.web2py.com/examples/static/web2py_logo.png right 200px]] +This paragraph has an image aligned to the right with a width of 200px. Its is placed using the code + +``[[alt-string for the image [the image title] http://www.web2py.com/examples/static/web2py_logo.png right 200px]]``. + +### Unordered Lists + +`` +- Dog +- Cat +- Mouse +`` + +is rendered as +- Dog +- Cat +- Mouse + +Two new lines between items break the list in two lists. + +### Ordered Lists + +`` ++ Dog ++ Cat ++ Mouse +`` + +is rendered as ++ Dog ++ Cat ++ Mouse + + +### Multilevel Lists + +`` ++ Dogs + -- red + -- brown + -- black ++ Cats + -- fluffy + -- smooth + -- bald ++ Mice + -- small + -- big + -- huge +`` + +is rendered as ++ Dogs + -- red + -- brown + -- black ++ Cats + -- fluffy + -- smooth + -- bald ++ Mice + -- small + -- big + -- huge + + +### Tables (with optional header and/or footer) + +Something like this +`` +----------------- +**A**|**B**|**C** +================= + 0 | 0 | X + 0 | X | 0 + X | 0 | 0 +================= +**D**|**F**|**G** +-----------------:abc[id] +`` +is a table and is rendered as +----------------- +**A**|**B**|**C** +================= +0 | 0 | X +0 | X | 0 +X | 0 | 0 +================= +**D**|**F**|**G** +-----------------:abc[id] +Four or more dashes delimit the table and | separates the columns. +The ``:abc``, ``:id[abc_1]`` or ``:abc[abc_1]`` at the end sets the class and/or id for the table and it is optional. + +### Blockquote + +A table with a single cell is rendered as a blockquote: + +----- +Hello world +----- + +Blockquote can contain headers, paragraphs, lists and tables: + +`` +----- + This is a paragraph in a blockquote + + + item 1 + + item 2 + -- item 2.1 + -- item 2.2 + + item 3 + + --------- + 0 | 0 | X + 0 | X | 0 + X | 0 | 0 + ---------:tableclass1 +----- +`` + +is rendered as: +----- + This is a paragraph in a blockquote + + + item 1 + + item 2 + -- item 2.1 + -- item 2.2 + + item 3 + + --------- + 0 | 0 | X + 0 | X | 0 + X | 0 | 0 + ---------:tableclass1 +----- + + +### Code, ````, escaping and extra stuff + +`` +def test(): + return "this is Python code" +``:python + +Optionally a ` inside a ``!`!`...`!`!`` block can be inserted escaped with !`!. + +**NOTE:** You can escape markmin constructions (\\'\\',\`\`,\*\*,\~\~,\[,\{,\]\},\$,\@) with '\\\\' character: + so \\\\`\\\\` can replace !`!`! escape string + +The ``:python`` after the markup is also optional. If present, by default, it is used to set the class of the block. +The behavior can be overridden by passing an argument ``extra`` to the ``render`` function. For example: + +`` +markmin2html("!`!!`!aaa!`!!`!:custom", + extra=dict(custom=lambda text: 'x'+text+'x')) +``:python + +generates + +``'xaaax'``:python + +(the ``!`!`...`!`!:custom`` block is rendered by the ``custom=lambda`` function passed to ``render``). + +### Line breaks + +``[[NEWLINE]]`` tag is used to break lines: +`` +#### Multiline [[NEWLINE]] + title +paragraph [[NEWLINE]] +with breaks[[NEWLINE]]in it +`` +generates: + +#### Multiline [[NEWLINE]] + title +paragraph [[NEWLINE]] +with breaks[[NEWLINE]]in it + + +### Html5 support + +Markmin also supports the

    %s' % (t_cls, t_id, pp, s, pp) + mtag = 't' + else: + # parse blockquote: + bq_begin = lineno + t_mode = False # embedded table + t_cls = '' + t_id = '' + + # search blockquote closing line: + while lineno < strings_len: + s = strings[lineno].strip() + if not t_mode: + m = regex_tq.match(s) + if m: + if (lineno + 1 == strings_len or + '|' not in strings[lineno + 1]): + t_cls = m.group('c') or '' + t_id = m.group('p') or '' + break + + if regex_bq_headline.match(s): + if (lineno + 1 < strings_len and + strings[lineno + 1].strip()): + t_mode = True + lineno += 1 + continue + elif regex_tq.match(s): + t_mode = False + lineno += 1 + continue + + lineno += 1 + + t_cls = ' class="%s%s"' % (class_prefix, t_cls) \ + if t_cls and t_cls != 'id' else '' + t_id = ' id="%s%s"' % (id_prefix, t_id) \ + if t_id else '' + + s = '%s%s' \ + % (t_cls, + t_id, + render('\n'.join(strings[bq_begin:lineno])), pp) + mtag = 'q' + else: + s = '
    ' + lineno -= 1 + mtag = 'q' + return (s, 'q', lineno) + + if sep == 'p': + pbeg = "

    " + pend = "

    " + pp + br = '' + else: + pbeg = pend = '' + br = "
    " + pp if sep == 'br' else '' + + lev = 0 # nesting level of lists + c0 = '' # first character of current line + out = [] # list of processed lines + etags = [] # trailing tags + ltags = [] # level# correspondent to trailing tag + tlev = [] # list of tags for each level ('ul' or 'ol') + mtag = '' # marked tag (~last tag) ('l','.','h','p','t'). Used to set
    + # and to avoid

    around tables and blockquotes + lineno = 0 + strings_len = len(strings) + while lineno < strings_len: + s0 = strings[lineno][:1] + s = strings[lineno].strip() + """ # + - . --------------------- + ## ++ -- .. ------- field | field | field <-title + ### +++ --- ... quote ===================== + #### ++++ ---- .... ------- field | field | field <-body + ##### +++++ ----- ..... ---------------------:class[id] + """ + pc0 = c0 # first character of previous line + c0 = s[:1] + if c0: # for non empty strings + if c0 in "#+-.": # first character is one of: # + - . + (t1, t2, p, ss) = regex_list.findall(s)[0] + # t1 - tag ("###") + # t2 - tag ("+++", "---", "...") + # p - paragraph point ('.')->for "++." or "--." + # ss - other part of string + if t1 or t2: + # headers and lists: + if c0 == '#': # headers + (lev, mtag) = parse_title(t1, ss) + lineno += 1 + continue + elif c0 == '+': # ordered list + (lev, mtag, lineno) = parse_list(t2, p, ss, 'ol', lev, mtag, lineno) + lineno += 1 + continue + elif c0 == '-': # unordered list, table or blockquote + if p or ss: + (lev, mtag, lineno) = parse_list(t2, p, ss, 'ul', lev, mtag, lineno) + lineno += 1 + continue + else: + (s, mtag, lineno) = parse_table_or_blockquote(s, mtag, lineno) + elif lev > 0: # and c0 == '.' # paragraph in lists + (lev, mtag, lineno) = parse_point(t2, ss, lev, mtag, lineno) + lineno += 1 + continue + + if lev == 0 and (mtag == 'q' or s == META): + # new paragraph + pc0 = '' + + if pc0 == '' or (mtag != 'p' and s0 not in (' ', '\t')): + # paragraph + out.extend(etags[::-1]) + etags = [] + ltags = [] + tlev = [] + lev = 0 + if br and mtag == 'p': + out.append(br) + if mtag != 'q' and s != META: + if pend: + etags = [pend] + out.append(pbeg) + mtag = 'p' + else: + mtag = '' + out.append(s) + else: + if lev > 0 and mtag == '.' and s == META: + out.append(etags.pop()) + ltags.pop() + out.append(s) + mtag = '' + else: + out.append(' ' + s) + lineno += 1 + out.extend(etags[::-1]) + text = ''.join(out) + + ############################################################# + # do strong,em,del + ############################################################# + text = regex_strong.sub('\g', text) + text = regex_del.sub('\g', text) + text = regex_em.sub('\g', text) + + ############################################################# + # deal with images, videos, audios and links + ############################################################# + def sub_media(m): + t, a, k, p, w = m.group('t', 'a', 'k', 'p', 'w') + if not k: + return m.group(0) + k = local_html_escape(k) + t = t or '' + style = 'width:%s' % w if w else '' + title = ' title="%s"' % local_html_escape(a).replace(META, DISABLED_META) if a else '' + p_begin = p_end = '' + if p == 'center': + p_begin = '

    ' + p_end = '

    ' + pp + elif p == 'blockleft': + p_begin = '

    ' + p_end = '

    ' + pp + elif p == 'blockright': + p_begin = '

    ' + p_end = '

    ' + pp + elif p in ('left', 'right'): + style = ('float:%s' % p) + (';%s' % style if style else '') + if t and regex_auto.match(t): + p_begin = p_begin + '
    ' % t + p_end = '' + p_end + t = '' + if style: + style = ' style="%s"' % style + if p in ('video', 'audio'): + t = render(t, {}, {}, 'br', URL, environment, latex, + autolinks, protolinks, class_prefix, id_prefix, pretty_print) + return '<%(p)s controls="controls"%(title)s%(style)s>%(t)s' \ + % dict(p=p, title=title, style=style, k=k, t=t) + alt = ' alt="%s"' % local_html_escape(t).replace(META, DISABLED_META) if t else '' + return '%(begin)s%(end)s' \ + % dict(begin=p_begin, k=k, alt=alt, title=title, style=style, end=p_end) + + def sub_link(m): + t, a, k, p = m.group('t', 'a', 'k', 'p') + if not k and not t: + return m.group(0) + t = t or '' + a = local_html_escape(a) if a else '' + if k: + if '#' in k and ':' not in k.split('#')[0]: + # wikipage, not external url + k = k.replace('#', '#' + id_prefix) + k = local_html_escape(k) + title = ' title="%s"' % a.replace(META, DISABLED_META) if a else '' + target = ' target="_blank"' if p == 'popup' else '' + t = render(t, {}, {}, 'br', URL, environment, latex, None, + None, class_prefix, id_prefix, pretty_print) if t else k + return '%(t)s' \ + % dict(k=k, title=title, target=target, t=t) + if t == 'NEWLINE' and not a: + return '
    ' + pp + return '%s' % ( + local_html_escape(id_prefix + t), + render(a, {}, {}, 'br', URL, + environment, latex, autolinks, + protolinks, class_prefix, + id_prefix, pretty_print)) + + parts = text.split(LINK) + text = parts[0] + for i, s in enumerate(links): + if s is None: + html = LINK + else: + html = regex_media_level2.sub(sub_media, s) + if html == s: + html = regex_link_level2.sub(sub_link, html) + if html == s: + # return unprocessed string as a signal of an error + html = '[[%s]]' % s + text += html + parts[i + 1] + + ############################################################# + # process all code text + ############################################################# + def expand_meta(m): + code, b, p, s = segments.pop(0) + if code is None or m.group() == DISABLED_META: + return local_html_escape(s) + if b in extra: + if code[:1] == '\n': + code = code[1:] + if code[-1:] == '\n': + code = code[:-1] + if p: + return str(extra[b](code, p)) + else: + return str(extra[b](code)) + elif b == 'cite': + return '[' + ','.join('%s' % + (id_prefix + d, b, d) for d in local_html_escape(code).split(',')) + ']' + elif b == 'latex': + return LATEX % urllib_quote(code) + elif b in html_colors: + return '%s' \ + % (b, render(code, {}, {}, 'br', URL, environment, latex, + autolinks, protolinks, class_prefix, id_prefix, pretty_print)) + elif b in ('c', 'color') and p: + c = p.split(':') + fg = 'color: %s;' % c[0] if c[0] else '' + bg = 'background-color: %s;' % c[1] if len(c) > 1 and c[1] else '' + return '%s' \ + % (fg, bg, render(code, {}, {}, 'br', URL, environment, latex, + autolinks, protolinks, class_prefix, id_prefix, pretty_print)) + cls = ' class="%s%s"' % (class_prefix, b) if b and b != 'id' else '' + id = ' id="%s%s"' % (id_prefix, local_html_escape(p)) if p else '' + beg = (code[:1] == '\n') + end = [None, -1][code[-1:] == '\n'] + if beg and end: + return '
    %s
    %s' % (cls, id, local_html_escape(code[1:-1]), pp) + return '%s' % (cls, id, local_html_escape(code[beg:end])) + + text = regex_expand_meta.sub(expand_meta, text) + + if environment: + text = replace_components(text, environment) + + return text.translate(ttab_out) + + +def markmin2html(text, extra={}, allowed={}, sep='p', + autolinks='default', protolinks='default', + class_prefix='', id_prefix='markmin_', pretty_print=False): + return render(text, extra, allowed, sep, + autolinks=autolinks, protolinks=protolinks, + class_prefix=class_prefix, id_prefix=id_prefix, + pretty_print=pretty_print) + + +def run_doctests(): + import doctest + doctest.testmod() + + +if __name__ == '__main__': + import sys + import doctest + from textwrap import dedent + + html = dedent(""" + + + + + %(style)s + %(title)s + + + %(body)s + + """)[1:] + + if sys.argv[1:2] == ['-h']: + style = dedent(""" + """)[1:] + + print(html % dict(title="Markmin markup language", + style=style, + body=markmin2html(__doc__, pretty_print=True))) + elif sys.argv[1:2] == ['-t']: + from timeit import Timer + + loops = 1000 + ts = Timer("markmin2html(__doc__)", "from markmin2html import markmin2html") + print('timeit "markmin2html(__doc__)":') + t = min([ts.timeit(loops) for i in range(3)]) + print("%s loops, best of 3: %.3f ms per loop" % (loops, t / 1000 * loops)) + elif len(sys.argv) > 1: + fargv = open(sys.argv[1], 'r') + try: + markmin_text = fargv.read() + + # embed css file from second parameter into html file + if len(sys.argv) > 2: + if sys.argv[2].startswith('@'): + markmin_style = '' + else: + fargv2 = open(sys.argv[2], 'r') + try: + markmin_style = "" + finally: + fargv2.close() + else: + markmin_style = "" + + print(html % dict(title=sys.argv[1], style=markmin_style, + body=markmin2html(markmin_text, pretty_print=True))) + finally: + fargv.close() + + else: + print("Usage: " + sys.argv[0] + " -h | -t | file.markmin [file.css|@path_to/css]") + print("where: -h - print __doc__") + print(" -t - timeit __doc__ (for testing purpuse only)") + print(" file.markmin [file.css] - process file.markmin + built in file.css (optional)") + print(" file.markmin [@path_to/css] - process file.markmin + link path_to/css (optional)") + run_doctests() diff --git a/web2py/gluon/contrib/markmin/markmin2latex.py b/web2py/gluon/contrib/markmin/markmin2latex.py new file mode 100644 index 0000000..ce1fe1d --- /dev/null +++ b/web2py/gluon/contrib/markmin/markmin2latex.py @@ -0,0 +1,313 @@ +#!/usr/bin/env python +# created my Massimo Di Pierro +# license MIT/BSD/GPL +from __future__ import print_function +import re +import cgi +import sys +import doctest +from optparse import OptionParser + +__all__ = ['render', 'markmin2latex'] + +META = 'META' +regex_newlines = re.compile('(\n\r)|(\r\n)') +regex_dd = re.compile('\$\$(?P.*?)\$\$') +regex_code = re.compile('(' + META + ')|(``(?P.*?)``(:(?P\w+))?)', re.S) +regex_title = re.compile('^#{1} (?P[^\n]+)', re.M) +regex_maps = [ + (re.compile('[ \t\r]+\n'), '\n'), + (re.compile('\*\*(?P[^\s\*]+( +[^\s\*]+)*)\*\*'), '{\\\\bf \g}'), + (re.compile("''(?P[^\s']+( +[^\s']+)*)''"), '{\\it \g}'), + (re.compile('^#{5,6}\s*(?P[^\n]+)', re.M), '\n\n{\\\\bf \g}\n'), + (re.compile('^#{4}\s*(?P[^\n]+)', re.M), '\n\n\\\\goodbreak\\subsubsection{\g}\n'), + (re.compile('^#{3}\s*(?P[^\n]+)', re.M), '\n\n\\\\goodbreak\\subsection{\g}\n'), + (re.compile('^#{2}\s*(?P[^\n]+)', re.M), '\n\n\\\\goodbreak\\section{\g}\n'), + (re.compile('^#{1}\s*(?P[^\n]+)', re.M), ''), + (re.compile('^\- +(?P.*)', re.M), '\\\\begin{itemize}\n\\item \g\n\\end{itemize}'), + (re.compile('^\+ +(?P.*)', re.M), '\\\\begin{itemize}\n\\item \g\n\\end{itemize}'), + (re.compile('\\\\end\{itemize\}\s+\\\\begin\{itemize\}'), '\n'), + (re.compile('\n\s+\n'), '\n\n')] +regex_table = re.compile('^\-{4,}\n(?P.*?)\n\-{4,}(:(?P\w+))?\n', re.M | re.S) + +regex_anchor = re.compile('\[\[(?P\S+)\]\]') +regex_bibitem = re.compile('\-\s*\[\[(?P\S+)\]\]') +regex_image_width = re.compile('\[\[(?P[^\]]*?) +(?P\S+) +(?P

    left|right|center) +(?P\d+px)\]\]') +regex_image = re.compile('\[\[(?P[^\]]*?) +(?P\S+) +(?P

    left|right|center)\]\]') +# regex_video = re.compile('\[\[(?P[^\]]*?) +(?P\S+) +video\]\]') +# regex_audio = re.compile('\[\[(?P[^\]]*?) +(?P\S+) +audio\]\]') +regex_link = re.compile('\[\[(?P[^\]]*?) +(?P\S+)\]\]') +regex_auto = re.compile('(?\w+://[\w\.\-\?&%\:]+)', re.M) +regex_commas = re.compile('[ ]+(?P[,;\.])') +regex_noindent = re.compile('\n\n(?P[a-z])') + + +# regex_quote_left = re.compile('"(?=\w)') +# regex_quote_right = re.compile('(?=\w\.)"') + +def latex_escape(text, pound=True): + text = text.replace('\\', '{\\textbackslash}') + for c in '^_&$%{}': + text = text.replace(c, '\\' + c) + text = text.replace('\\{\\textbackslash\\}', '{\\textbackslash}') + if pound: text = text.replace('#', '\\#') + return text + + +def render(text, + extra={}, + allowed={}, + sep='p', + image_mapper=lambda x: x, + chapters=False): + ############################################################# + # replace all blocks marked with ``...``:class with META + # store them into segments they will be treated as code + ############################################################# + text = str(text or '') + segments, i = [], 0 + text = regex_dd.sub('``\g``:latex ', text) + text = regex_newlines.sub('\n', text) + while True: + item = regex_code.search(text, i) + if not item: + break + if item.group() == META: + segments.append((None, None)) + text = text[:item.start()] + META + text[item.end():] + else: + c = item.group('c') or '' + if 'code' in allowed and c not in allowed['code']: + c = '' + code = item.group('t').replace('!`!', '`') + segments.append((code, c)) + text = text[:item.start()] + META + text[item.end():] + i = item.start() + 3 + + ############################################################# + # do h1,h2,h3,h4,h5,h6,b,i,ol,ul and normalize spaces + ############################################################# + + title = regex_title.search(text) + if not title: + title = 'Title' + else: + title = title.group('t') + + text = latex_escape(text, pound=False) + + texts = text.split('## References', 1) + text = regex_anchor.sub('\\label{\g}', texts[0]) + if len(texts) == 2: + text += '\n\\begin{thebibliography}{999}\n' + text += regex_bibitem.sub('\n\\\\bibitem{\g}', texts[1]) + text += '\n\\end{thebibliography}\n' + + text = '\n'.join(t.strip() for t in text.split('\n')) + for regex, sub in regex_maps: + text = regex.sub(sub, text) + text = text.replace('#', '\\#') + text = text.replace('`', "'") + + ############################################################# + # process tables and blockquotes + ############################################################# + while True: + item = regex_table.search(text) + if not item: + break + c = item.group('c') or '' + if 'table' in allowed and c not in allowed['table']: + c = '' + content = item.group('t') + if ' | ' in content: + rows = content.replace('\n', '\\\\\n').replace(' | ', ' & ') + row0, row2 = rows.split('\\\\\n', 1) + cols = row0.count(' & ') + 1 + cal = '{' + ''.join('l' for j in range(cols)) + '}' + tabular = '\\begin{center}\n{\\begin{tabular}' + cal + '\\hline\n' + row0 + '\\\\ \\hline\n' + row2 + ' \\\\ \\hline\n\\end{tabular}}\n\\end{center}' + if row2.count('\n') > 20: + tabular = '\\newpage\n' + tabular + text = text[:item.start()] + tabular + text[item.end():] + else: + text = text[:item.start()] + '\\begin{quote}' + content + '\\end{quote}' + text[item.end():] + + ############################################################# + # deal with images, videos, audios and links + ############################################################# + + def sub(x): + f = image_mapper(x.group('k')) + if not f: + return None + return '\n\\begin{center}\\includegraphics[width=8cm]{%s}\\end{center}\n' % f + + text = regex_image_width.sub(sub, text) + text = regex_image.sub(sub, text) + + text = regex_link.sub('{\\\\footnotesize\\href{\g}{\g}}', text) + text = regex_commas.sub('\g', text) + text = regex_noindent.sub('\n\\\\noindent \g', text) + + # ## fix paths in images + regex = re.compile('\\\\_\w*\.(eps|png|jpg|gif)') + while True: + match = regex.search(text) + if not match: + break + text = text[:match.start()] + text[match.start() + 1:] + # text = regex_quote_left.sub('``',text) + # text = regex_quote_right.sub("''",text) + + if chapters: + text = text.replace(r'\section*{', r'\chapter*{') + text = text.replace(r'\section{', r'\chapter{') + text = text.replace(r'subsection{', r'section{') + + ############################################################# + # process all code text + ############################################################# + parts = text.split(META) + text = parts[0] + authors = [] + for i, (code, b) in enumerate(segments): + if code is None: + html = META + else: + if b == 'hidden': + html = '' + elif b == 'author': + author = latex_escape(code.strip()) + authors.append(author) + html = '' + elif b == 'inxx': + html = '\inxx{%s}' % latex_escape(code) + elif b == 'cite': + html = '~\cite{%s}' % latex_escape(code.strip()) + elif b == 'ref': + html = '~\ref{%s}' % latex_escape(code.strip()) + elif b == 'latex': + if '\n' in code: + html = '\n\\begin{equation}\n%s\n\\end{equation}\n' % code.strip() + else: + html = '$%s$' % code.strip() + elif b == 'latex_eqnarray': + code = code.strip() + code = '\\\\'.join(x.replace('=', '&=&', 1) for x in code.split('\\\\')) + html = '\n\\begin{eqnarray}\n%s\n\\end{eqnarray}\n' % code + elif b.startswith('latex_'): + key = b[6:] + html = '\\begin{%s}%s\\end{%s}' % (key, code, key) + elif b in extra: + if code[:1] == '\n': + code = code[1:] + if code[-1:] == '\n': + code = code[:-1] + html = extra[b](code) + elif code[:1] == '\n' or code[:-1] == '\n': + if code[:1] == '\n': + code = code[1:] + if code[-1:] == '\n': + code = code[:-1] + if code.startswith('<') or code.startswith('{{') or code.startswith('http'): + html = '\\begin{lstlisting}[keywords={}]\n%s\n\\end{lstlisting}' % code + else: + html = '\\begin{lstlisting}\n%s\n\\end{lstlisting}' % code + else: + if code[:1] == '\n': + code = code[1:] + if code[-1:] == '\n': + code = code[:-1] + html = '{\\ft %s}' % latex_escape(code) + try: + text = text + html + parts[i + 1] + except: + text = text + '... WIKI PROCESSING ERROR ...' + break + text = text.replace(' ~\\cite', '~\\cite') + return text, title, authors + + +WRAPPER = """ +\\documentclass[12pt]{article} +\\usepackage{hyperref} +\\usepackage{listings} +\\usepackage{upquote} +\\usepackage{color} +\\usepackage{graphicx} +\\usepackage{grffile} +\\usepackage[utf8x]{inputenc} +\\definecolor{lg}{rgb}{0.9,0.9,0.9} +\\definecolor{dg}{rgb}{0.3,0.3,0.3} +\\def\\ft{\\small\\tt} +\\lstset{ + basicstyle=\\footnotesize, + breaklines=true, basicstyle=\\ttfamily\\color{black}\\footnotesize, + keywordstyle=\\bf\\ttfamily, + commentstyle=\\it\\ttfamily, + stringstyle=\\color{dg}\\it\\ttfamily, + numbers=left, numberstyle=\\color{dg}\\tiny, stepnumber=1, numbersep=5pt, + backgroundcolor=\\color{lg}, tabsize=4, showspaces=false, + showstringspaces=false +} +\\title{%(title)s} +\\author{%(author)s} +\\begin{document} +\\maketitle +\\tableofcontents +\\newpage +%(body)s +\\end{document} +""" + + +def markmin2latex(data, image_mapper=lambda x: x, extra={}, + wrapper=WRAPPER): + body, title, authors = render(data, extra=extra, image_mapper=image_mapper) + author = '\n\\and\n'.join(a.replace('\n', '\\\\\n\\footnotesize ') for a in authors) + return wrapper % dict(title=title, author=author, body=body) + + +if __name__ == '__main__': + parser = OptionParser() + parser.add_option("-i", "--info", dest="info", + help="markmin help") + parser.add_option("-t", "--test", dest="test", action="store_true", + default=False) + parser.add_option("-n", "--no_wrapper", dest="no_wrapper", + action="store_true", default=False) + parser.add_option("-c", "--chapters", dest="chapters", action="store_true", + default=False, help="switch section for chapter") + parser.add_option("-w", "--wrapper", dest="wrapper", default=False, + help="latex file containing header and footer") + + (options, args) = parser.parse_args() + if options.info: + import markmin2html + + markmin2latex(markmin2html.__doc__) + elif options.test: + doctest.testmod() + else: + if options.wrapper: + fwrapper = open(options.wrapper, 'rb') + try: + wrapper = fwrapper.read() + finally: + fwrapper.close() + elif options.no_wrapper: + wrapper = '%(body)s' + else: + wrapper = WRAPPER + for f in args: + fargs = open(f, 'r') + content_data = [] + try: + content_data.append(fargs.read()) + finally: + fargs.close() + content = '\n'.join(content_data) + output = markmin2latex(content, + wrapper=wrapper, + chapters=options.chapters) + print(output) diff --git a/web2py/gluon/contrib/markmin/markmin2pdf.py b/web2py/gluon/contrib/markmin/markmin2pdf.py new file mode 100644 index 0000000..7e3c2ee --- /dev/null +++ b/web2py/gluon/contrib/markmin/markmin2pdf.py @@ -0,0 +1,132 @@ +""" +Created by Massimo Di Pierro +License BSD +""" +from __future__ import print_function + +import subprocess +import os +import os.path +import re +import sys +from tempfile import mkstemp, mkdtemp, NamedTemporaryFile +from gluon.contrib.markmin.markmin2latex import markmin2latex + +__all__ = ['markmin2pdf'] + + +def removeall(path): + ERROR_STR = """Error removing %(path)s, %(error)s """ + + def rmgeneric(path, __func__): + try: + __func__(path) + except OSError as xxx_todo_changeme: + (errno, strerror) = xxx_todo_changeme.args + print(ERROR_STR % {'path': path, 'error': strerror}) + + files = [path] + + while files: + file = files[0] + if os.path.isfile(file): + f = os.remove + rmgeneric(file, os.remove) + del files[0] + elif os.path.isdir(file): + nested = os.listdir(file) + if not nested: + rmgeneric(file, os.rmdir) + del files[0] + else: + files = [os.path.join(file, x) for x in nested] + files + + +def latex2pdf(latex, pdflatex='pdflatex', passes=3): + """ + calls pdflatex in a tempfolder + + Arguments: + + - pdflatex: path to the pdflatex command. Default is just 'pdflatex'. + - passes: defines how often pdflates should be run in the texfile. + """ + + pdflatex = pdflatex + passes = passes + warnings = [] + + # setup the envoriment + tmpdir = mkdtemp() + texfile = open(tmpdir + '/test.tex', 'wt',encoding="utf-8") + texfile.write(latex) + texfile.seek(0) + texfile.close() + texfile = os.path.abspath(texfile.name) + + # start doing some work + for i in range(0, passes): + logfd, logname = mkstemp() + outfile = os.fdopen(logfd) + try: + ret = subprocess.call([pdflatex, + '-interaction=nonstopmode', + '-output-format', 'pdf', + '-output-directory', tmpdir, + texfile], + cwd=os.path.dirname(texfile), stdout=outfile, + stderr=subprocess.PIPE) + finally: + outfile.close() + re_errors = re.compile('^\!(.*)$', re.M) + re_warnings = re.compile('^LaTeX Warning\:(.*)$', re.M) + flog = open(logname) + try: + loglines = flog.read() + finally: + flog.close() + errors = re_errors.findall(loglines) + warnings = re_warnings.findall(loglines) + os.unlink(logname) + + pdffile = texfile.rsplit('.', 1)[0] + '.pdf' + data = None + + if os.path.isfile(pdffile): + with open(pdffile,'rb') as fpdf : + data = fpdf.read() + + removeall(tmpdir) + + return data, warnings, errors + + +def markmin2pdf(text, image_mapper=lambda x: None, extra={}): + return latex2pdf(markmin2latex(text, image_mapper=image_mapper, extra=extra)) + + +if __name__ == '__main__': + import sys + import doctest + import markmin2html + + if sys.argv[1:2] == ['-h']: + data, warnings, errors = markmin2pdf(markmin2html.__doc__) + if errors: + print('ERRORS:' + '\n'.join(errors)) + print('WARNGINS:' + '\n'.join(warnings)) + else: + print(data) + elif len(sys.argv) > 1: + fargv = open(sys.argv[1], 'rb') + try: + data, warnings, errors = markmin2pdf(fargv.read()) + finally: + fargv.close() + if errors: + print('ERRORS:' + '\n'.join(errors)) + print('WARNGINS:' + '\n'.join(warnings)) + else: + print(data) + else: + doctest.testmod() diff --git a/web2py/gluon/contrib/memcache/ChangeLog b/web2py/gluon/contrib/memcache/ChangeLog new file mode 100644 index 0000000..5546440 --- /dev/null +++ b/web2py/gluon/contrib/memcache/ChangeLog @@ -0,0 +1,362 @@ +Sun, 27 Nov 2011 18:15:32 -0700 Sean Reifschneider + + * Bug #745633: Values of maximum size are not stored + API inconsistency, max value length was tested for <= while max KEY + length was <. So I picked that keys and values *LONGER* than the + specified max value are what is used, and added documentation and tests + to that effect. The test for max value tested that length plus 4, so + I've changed that to be that value plus 1. Issue found by matt-quru. + + * Bug #713488: Issues Invalid "delete" command. + Protocol has changed so that the "delete" operation no longer takes a + "time" argument. It seems that some servers will refuse a "delete key + 0" while others will accept it, but the official server will NOT accept + "delete key 1". So I've changed it so that if no "time" argument is + specified, no time argument is sent to the server. + + * Bug #713451: server.expect("END") needs to be in a finally block + Expect an "END" when the _recv_value() raises an exception. + Patch by Jay Farrimond. + + * Bug: #741090: cas cache can grow unbounded. Default now is that the + cache is not used, unless the "Client()" object is created with + "cache_cas=True". In that case, you need to have your own cas clearing + code, a simple one would be to use Client().reset_cas() to completely + clear the cas_ids cache. Problem pointed out by Shaun Cutts. + + * Bug #728359: Make python-memcache work on memcache restarts. + Patch by Tarek Ziade', reviewed and further patches submitted by Hugo + Beauze'e-Luysse and Neganov Alexandr. + + * Bug #798342: If memcached server sends unknown flag in response for + "get", results in: + "UnboundLocalError: local variable 'val' referenced before assignment" + Now returns "None" instead. Patch by Sharoon Thomas + +Mon, 20 Dec 2010 19:14:17 -0700 Sean Reifschneider + + * Bug #680359: useOldServerHashFunction() is broken. It now correctly + switches back to the old memcache hash function. + +Thu, 16 Dec 2010 02:07:40 -0700 Sean Reifschneider + + * Bug #471727: Changed the delete() code to explicitly check for both + NOT_FOUND and DELETED as the responses and return successful for both. + It also logs an error if one of these two responses is not found. + Also added a test to ensure that delete() works. + + * When using set_multi and one value is too big, traceback + TypeError: 'int' object is unsubscriptable + Patch by Orjan Persson + + * Fixing Bug #529855: Server host can now be bare host without ":". + Fix proposed by Roger Binns. + + * Fixing Bug #491164: Typo fix, "compession" -> "compRession". + + * Fixing Bug #509712: "TypeError: 'NoneType' object is unsubscriptable" + Also fixed some other similar code to not have issues with that. + + * Also related to 509712 and 628339: readline() now returns '' instead + of None when a server dies. This should be safer. Patch suggested by + Denis Otkidach. + + * Fixing Bug #628339: Read from server sometimes fails. Patch by Jeremy + Cowles. + + * Fixing Bug #633553: Add stat arguments support to get_stats(). Patch + by Ryan Lane. + + * Changing the license to the PSF License. + + * Removing Evan's e-mail address at his request, changing authorship to + Sean. + +Sat, 28 Nov 2009 01:07:42 -0700 Sean Reifschneider + + * Version 1.45 + + * Per-connection max server key length. Patch by Nicolas Delaby + + * Patches to make memcached more garbage-collectable. Removes + "debugfunc" argument from _Host objects and changed to "debug" + boolean. Patches by John McFarlane and Aryeh Katz. + + * Switching to a cmemcache compatible hash function. Implemented by + André Cru and Ludvig Ericson. To switch back to the old style, use: + + memcached.useOldServerHashFunction() + + * Rejecting keys that have spaces in them. Patch by Etienne Posthumus. + + * Fixing exception raising syntax. Patch by Samuel Stauffer. + + * Optimizations in read code. Patch by Samuel Stauffer. + + * Changing classes to be newstyle. Patch by Samuel Stauffer. + + * Changed "has_key" to "in". Patch by Samuel Stauffer. + + * incr/decr were raising ValueError if the key did not exist, the + docstring said it returned none. Patch by Chihiro Sakatoku. + + * Adding cas method, submitted by Ben Gutierrez. + + * Fix in the docstring for how to use the "set" method. Found and fixed + by William McVey + +Thu, 02 Apr 2009 13:37:49 -0600 Sean Reifschneider + + * Version 1.44 + + * Allowing spaces in the key. (Patch provided by xmm on Launchpad) + + * Detecting when the pickler needs a positional argument. (Patch + provided by Brad Clements on Launchpad) + + * Moving length check after the compression. (Patch provided by user + Tom on Launchpad) + + * Fixing arguments passed to the _Error if invalid read length. + + * Fixing the representation of domain sockets. (Patch provided by user + MTB on Launchpad) + + * Changing a typo of dead_until. (Patch provided by Shane R. Spencer) + + * Providing better error messages (patch provided by Johan Euphrosine). + + * Adding get_slabs() function to get stats. (Patch provided + by Nick Verbeck) + +Sun, 01 Jun 2008 15:05:11 -0600 Sean Reifschneider + + * Version 1.43 + + * eliott reported a bug in the 1.42 related to the socket timeout code + causing a traceback due to the timeout value not being set. + +Sat, 31 May 2008 02:09:17 -0600 Sean Reifschneider + + * Version 1.42 + + * Paul Hummer set up a Launchpad project which I'm going to start using + to track patches and allow users to set up their own bzr branches and + manage marging in the upstream patches with their own. + + https://launchpad.net/python-memcached + + * Patch from Jehiah Czebotar which does: Changing the calls to + mark_dead() to make them dereference tuples, reducing timeout on + sockets to 3 seconds, settable via setting Host._SOCKET_TIMEOUT. + + * Patches from Steve Schwarz for set_multi() to return the full set of + keys if all servers are down. Previously would not report any keys. + + * Fix from Steve Schwarz delete_multi() argument "seconds" not being + correctly handled. Changed it to "time" to match all other calls. + + * Patch from Peter Wilkinson to support using unix domain sockets. + He reports that tests succeed with with memcached daemons running, + the normal and a domain socket started via + "memcached -s memcached.socket". I massaged it quite a bit. + + To use domain sockets, use a connect string of "unix:/path/to/socket" + Note however that if you are using a host name of "unix", it will now + detect "unix:11211" as being a domain socket with the name "11211". + In this case, please use "inet:unix:11211". + + Because of this, it is now preferred to use a connect string prefix + of "inet:" or "unix:". + +Tue, 29 Apr 2008 21:03:53 -0600 Sean Reifschneider + + * Version 1.41 + + * Patch from Jehiah Czebotar to catch an additional server disconnect + situation. + + * Patch from Andrey Petrov to add the "append" and "replace" commands. + +Tue, 18 Sep 2007 20:52:09 -0600 Sean Reifschneider + + * Version 1.40 + + * Updated setup.py file that uses distutils provided by Kai Lautaportti. + + * Prevent keys from containing ASCII character 127 as well, patch provided + by Philip Neustrom. + + * Added ability to overload the persistent_load/id, patch provided by + Steve Schwarz. + + * Fixed ability to pass (server_hash,key) in place of key in Client.set() + Reported by Alexander Klyuev. + +Tue, 14 Aug 2007 14:43:27 -0600 Sean Reifschneider + + * Version 1.39 + + * Michael Krause reports the previous version doesn't work for + _val_to_store_info() calls because it's defined as a staticmethod. + Removing staticmethod decorator. Also confirmed by Kai Lautaportti, + with suggested fix of removing staticmethod. + +Fri, 10 Aug 2007 17:50:13 -0600 Sean Reifschneider + + * Version 1.38 + + * Matt McClanahan submitted a patch that allow add() to have a + min_compress_len argument. + + * Steve Schwarz submitted a patch allowing user-defined picklers. + + * Michael Krause suggested checking the return value to prevent an + exception from being raised in _set() when a value is too large to be + stored. + +Fri, 27 Jul 2007 01:55:48 -0600 Sean Reifschneider + + * Version 1.37 + + * Fixing call from add() to _set() with parameter for min_compress_len. + Reported by Jeff Fisher. + +Thu, 07 Jun 2007 04:10:31 -0600 Sean Reifschneider + + * Version 1.36 + + * Patch by Dave St.Germain to make the Client() class sub-class + threadlocal to help with multi-threading issues. Only available in + Python 2.4 and above. + + * Patch by James Robinson with: + 1) new set_multi method. + 2) factored out determining the flags, length, and value to store + from set() into method _val_to_store_info() for use by both set() + and set_multi(). + 3) send_cmds() method on host which doesn't apply the trailing '\r\n' + for use by set_multi. + 4) check_key() extended a bit to allow for testing the prefix passed + to set_multi just once, not once per each key. + 5) Patch also enables support for auto compression in set, set_multi, + and replace. + + * Suggestion by Helge Tesdal, fixes in check_key for non-string keys. + + * NOTE: On a farm of clients with multiple servers, all clients will + need to be upgraded to this version. The next patch changes the + server hash. + + * Philip Neustrom supplied a patch to change the server hash function to + binascii.crc32. The original "hash()" call is not cross-platform, so + big and little endian systems accessing the same memcache may end up + hitting different servers. Restore the old functionality by calling: + "memcached.serverHashFunction = hash" after importing memcache. + + * Philip Neustrom points out that passing Unicode keys or values causes + problems because len(key) or len(value) is not equal to the number of + bytes that are required to store the key/value. Philip provides a + patch which raises an exception in this case. Raises + memcache.Client.MemcachedStringEncodingError exception in this case. + + * NOTE: If you recompiled memcached to increase the default 1MB max + value size, you will need to call "memcached.MAX_SERVER_VALUE_LENGTH = N" + or memcached will not store values larger than the default 1MB. + + * Philip Neustrom includes another patch which checks that the key + doesn't exceed the memcache server's max size. If it does, the item + is silently not stored. + + * Philip Neustrom added a bunch of sanity checks. + + * Jehiah Czebotar provided a patch to make the add() and replace() + functions return 0 when the add or replace fails, similar to how set() + works. + +Sat, 16 Sep 2006 18:31:46 -0600 Sean Reifschneider + + * Version 1.34 + + * In get_multi, if the recv loop reads 0 bytes, raising an EOFError. + Identified by Jim Baker. + +Tue, 05 Sep 2006 14:06:50 -0600 Sean Reifschneider + + * Version 1.33 + + * Including patch from Yoshinori K. Okuji to read in larger chunks for + readline() calls. This should dramatically improve performance under + some circumstances. + +Sun, 03 Sep 2006 14:02:03 -0600 Sean Reifschneider + + * Version 1.32 + + * Including patch from Philip Neustrom which checks keys sent to the + server for length and bad characters. + +Sat, 20 May 2006 14:51:28 -0600 Sean Reifschneider + + * Version 1.31 + + * Rolled version 1.30 since the Danga folks are now listing this + version as the official version. Removing the "tummy" from the version + number, and incrementing so that it's clear it's more recent than "1.2". + + * Patch applied from Simon Forman for handling of weighted hosts. + + * Added a little more meat to the README. + +Sat, 28 Jan 2006 15:59:50 -0700 Sean Reifschneider + + * cludwin at socallocal suggested that the write-combining with + sendall() may not be beneficial. After testing on both SMP and non-SMP + machines, I can't see a significant benefit to not doing the + write-combining, even on large strings. The benefits of write-combining + on smaller strings seems to be significant on UP machines in tight loops. + Even on strings that are larger than 2MB, there seems to be no benefit to + splitting out the writes. + +Sun, 18 Sep 2005 18:56:31 -0600 Sean Reifschneider + + * Changing a printf to debuglog and catching a pickle exception, patch + submitted by Justin Azoff. + +Thu, 14 Jul 2005 11:17:30 -0700 Sean Reifschneider + + * Alex Stapleton found that the sendall call was slow for writing data + larger than several kilobytes. I had him test a change to his patch, + which worked as well, but was simpler. The code now does two sendall + calls, one for the data and one for the line termination, if the data is + larger than 100 bytes. + +Thu, 7 Apr 2005 14:45:44 -0700 Sean Reifschneider + + * Incorporating some fixes to get_multi() from Bo Yang + +Mon, 13 Dec 2004 02:35:17 -0700 Sean Reifschneider + + * Simplifying the readline() function and speeding it up ~25%. + * Fixing a bug in readline() if the server drops, mark_dead() was not + being properly called. + +Sun, 12 Dec 2004 18:56:33 -0700 Sean Reifschneider + + * Adding "stats()" and "flush_all()" methods. + +Thu, 10 Aug 2003 12:17:50 -0700 Evan Martin + + * Slightly more verbose self-test output. + * Fix mark_dead() to use proper classname. + * Make pooltest.py run from the test directory. + +Thu, 07 Aug 2003 16:32:32 -0700 Evan Martin + + * Add incr, decr, and delete. + * Better Python (based on comments from Uriah Welcome). + * Docs, using epydoc. + +Thu, 07 Aug 2003 14:20:27 -0700 Evan Martin + + * Initial prerelease. diff --git a/web2py/gluon/contrib/memcache/PKG-INFO b/web2py/gluon/contrib/memcache/PKG-INFO new file mode 100644 index 0000000..7b13d9d --- /dev/null +++ b/web2py/gluon/contrib/memcache/PKG-INFO @@ -0,0 +1,10 @@ +Metadata-Version: 1.0 +Name: python-memcached +Version: 1.48 +Summary: A Python memcached client library. +Home-page: http://www.tummy.com/Community/software/python-memcached/ +Author: Sean Reifschneider +Author-email: jafo-memcached@tummy.com +License: Python Software Foundation License +Description: A Python memcached client library. +Platform: UNKNOWN diff --git a/web2py/gluon/contrib/memcache/README b/web2py/gluon/contrib/memcache/README new file mode 100644 index 0000000..55e5af4 --- /dev/null +++ b/web2py/gluon/contrib/memcache/README @@ -0,0 +1,8 @@ +This software is a 100% Python interface to the memcached memory cache +daemon. It is the client side software which allows storing values in one +or more, possibly remote, memcached servers. Search google for memcached +for more information. + +This package was originally written by Evan Martin of Danga. +Please do not contact Evan about maintenance. +Sean Reifschneider of tummy.com, ltd. has taken over maintenance of it. diff --git a/web2py/gluon/contrib/memcache/__init__.py b/web2py/gluon/contrib/memcache/__init__.py new file mode 100644 index 0000000..137c729 --- /dev/null +++ b/web2py/gluon/contrib/memcache/__init__.py @@ -0,0 +1,114 @@ +from gluon.contrib.memcache.memcache import Client +from gluon.cache import CacheAbstract +import time + +""" +examle of usage: + +cache.memcache = MemcacheClient(request,[127.0.0.1:11211],debug=true) +""" + +import cPickle as pickle +import thread +from gluon import current + +DEFAULT_TIME_EXPIRE = 300 # seconds (must be the same as cache.ram) + +def MemcacheClient(*a, **b): + if not hasattr(current,'__memcache_client'): + current.__memcache_client = MemcacheClientObj(*a, **b) + return current.__memcache_client + +class MemcacheClientObj(Client): + + def initialize(self): + pass + + meta_storage = {} + max_time_expire = 24*3600 + + def __init__(self, request, servers, debug=0, pickleProtocol=0, + pickler=pickle.Pickler, unpickler=pickle.Unpickler, + pload=None, pid=None, + default_time_expire = DEFAULT_TIME_EXPIRE): + self.request=request + self.default_time_expire = default_time_expire + if request: + app = request.application + else: + app = '' + Client.__init__(self, servers, debug, pickleProtocol, + pickler, unpickler, pload, pid) + if not app in self.meta_storage: + self.storage = self.meta_storage[app] = { + CacheAbstract.cache_stats_name: { + 'hit_total': 0, + 'misses': 0, + }} + else: + self.storage = self.meta_storage[app] + + def __call__(self, key, f, time_expire = 'default'): + if time_expire == 'default': + time_expire = self.default_time_expire + if time_expire == None: + time_expire = self.max_time_expire + # this must be commented because get and set are redefined + # key = self.__keyFormat__(key) + now = time.time() + value = None + if f is None: # force deletion of value + self.delete(key) + return None + elif time_expire==0: # value forced expired + item = None # value to be computed + else: + item = self.get(key) + if item: + if not isinstance(item,(list,tuple)): + value = item + elif (item[0] < now - time_expire): # value expired + item = None # value to be computed + else: + value = item[1] + if not item: + value = f() + self.set(key, (now,value), self.max_time_expire) + return value + + def increment(self, key, value=1, time_expire='default'): + """ time_expire is ignored """ + if time_expire == 'default': + time_expire = self.default_time_expire + newKey = self.__keyFormat__(key) + obj = Client.get(self, newKey) + if obj: + if isinstance(obj,(int,float,long)): + return Client.incr(self, newKey, value) + else: + value += obj[1] + Client.set(self,newKey,(time.time(),value), + self.max_time_expire) + return value + else: + Client.set(self, newKey, value, self.max_time_expire) + return value + + def set(self, key, value, time_expire='default'): + if time_expire == 'default': + time_expire = self.default_time_expire + newKey = self.__keyFormat__(key) + return Client.set(self, newKey, value, time_expire) + + def get(self, key): + newKey = self.__keyFormat__(key) + return Client.get(self, newKey) + + def delete(self, key): + newKey = self.__keyFormat__(key) + return Client.delete(self, newKey) + + def __keyFormat__(self, key): + return '%s/%s' % (self.request.application, key.replace(' ', '_')) + + diff --git a/web2py/gluon/contrib/memcache/memcache.py b/web2py/gluon/contrib/memcache/memcache.py new file mode 100644 index 0000000..9bc6168 --- /dev/null +++ b/web2py/gluon/contrib/memcache/memcache.py @@ -0,0 +1,1578 @@ +#!/usr/bin/env python + +"""client module for memcached (memory cache daemon) + +Overview +======== + +See U{the MemCached homepage} for more +about memcached. + +Usage summary +============= + +This should give you a feel for how this module operates:: + + import memcache + mc = memcache.Client(['127.0.0.1:11211'], debug=0) + + mc.set("some_key", "Some value") + value = mc.get("some_key") + + mc.set("another_key", 3) + mc.delete("another_key") + + mc.set("key", "1") # note that the key used for incr/decr must be + # a string. + mc.incr("key") + mc.decr("key") + +The standard way to use memcache with a database is like this: + + key = derive_key(obj) + obj = mc.get(key) + if not obj: + obj = backend_api.get(...) + mc.set(key, obj) + + # we now have obj, and future passes through this code + # will use the object from the cache. + +Detailed Documentation +====================== + +More detailed documentation is available in the L{Client} class. + +""" + +from __future__ import print_function + +import binascii +import os +import pickle +import re +import socket +import sys +import threading +import time +import zlib + +import six + + +def cmemcache_hash(key): + return ( + (((binascii.crc32(key.encode('ascii')) & 0xffffffff) + >> 16) & 0x7fff) or 1) +serverHashFunction = cmemcache_hash + + +def useOldServerHashFunction(): + """Use the old python-memcache server hash function.""" + global serverHashFunction + serverHashFunction = binascii.crc32 + +try: + from zlib import compress, decompress + _supports_compress = True +except ImportError: + _supports_compress = False + # quickly define a decompress just in case we recv compressed data. + + def decompress(val): + raise _Error( + "Received compressed data but I don't support " + "compression (import error)") + +from io import BytesIO +try: + unicode +except NameError: + _has_unicode = False +else: + _has_unicode = True + +try: + _str_cls = basestring +except NameError: + _str_cls = str + +valid_key_chars_re = re.compile('[\x21-\x7e\x80-\xff]+$') + + +# Original author: Evan Martin of Danga Interactive +__author__ = "Sean Reifschneider " +__version__ = "1.53" +__copyright__ = "Copyright (C) 2003 Danga Interactive" +# http://en.wikipedia.org/wiki/Python_Software_Foundation_License +__license__ = "Python Software Foundation License" + +SERVER_MAX_KEY_LENGTH = 250 +# Storing values larger than 1MB requires recompiling memcached. If +# you do, this value can be changed by doing +# "memcache.SERVER_MAX_VALUE_LENGTH = N" after importing this module. +SERVER_MAX_VALUE_LENGTH = 1024 * 1024 + + +class _Error(Exception): + pass + + +class _ConnectionDeadError(Exception): + pass + + +_DEAD_RETRY = 30 # number of seconds before retrying a dead server. +_SOCKET_TIMEOUT = 3 # number of seconds before sockets timeout. + + +class Client(threading.local): + """Object representing a pool of memcache servers. + + See L{memcache} for an overview. + + In all cases where a key is used, the key can be either: + 1. A simple hashable type (string, integer, etc.). + 2. A tuple of C{(hashvalue, key)}. This is useful if you want + to avoid making this module calculate a hash value. You may + prefer, for example, to keep all of a given user's objects on + the same memcache server, so you could use the user's unique + id as the hash value. + + + @group Setup: __init__, set_servers, forget_dead_hosts, + disconnect_all, debuglog + @group Insertion: set, add, replace, set_multi + @group Retrieval: get, get_multi + @group Integers: incr, decr + @group Removal: delete, delete_multi + @sort: __init__, set_servers, forget_dead_hosts, disconnect_all, + debuglog,\ set, set_multi, add, replace, get, get_multi, + incr, decr, delete, delete_multi + """ + _FLAG_PICKLE = 1 << 0 + _FLAG_INTEGER = 1 << 1 + _FLAG_LONG = 1 << 2 + _FLAG_COMPRESSED = 1 << 3 + + _SERVER_RETRIES = 10 # how many times to try finding a free server. + + # exceptions for Client + class MemcachedKeyError(Exception): + pass + + class MemcachedKeyLengthError(MemcachedKeyError): + pass + + class MemcachedKeyCharacterError(MemcachedKeyError): + pass + + class MemcachedKeyNoneError(MemcachedKeyError): + pass + + class MemcachedKeyTypeError(MemcachedKeyError): + pass + + class MemcachedStringEncodingError(Exception): + pass + + def __init__(self, servers, debug=0, pickleProtocol=0, + pickler=pickle.Pickler, unpickler=pickle.Unpickler, + pload=None, pid=None, + server_max_key_length=None, server_max_value_length=None, + dead_retry=_DEAD_RETRY, socket_timeout=_SOCKET_TIMEOUT, + cache_cas=False, flush_on_reconnect=0, check_keys=True): + """Create a new Client object with the given list of servers. + + @param servers: C{servers} is passed to L{set_servers}. + @param debug: whether to display error messages when a server + can't be contacted. + @param pickleProtocol: number to mandate protocol used by + (c)Pickle. + @param pickler: optional override of default Pickler to allow + subclassing. + @param unpickler: optional override of default Unpickler to + allow subclassing. + @param pload: optional persistent_load function to call on + pickle loading. Useful for cPickle since subclassing isn't + allowed. + @param pid: optional persistent_id function to call on pickle + storing. Useful for cPickle since subclassing isn't allowed. + @param dead_retry: number of seconds before retrying a + blacklisted server. Default to 30 s. + @param socket_timeout: timeout in seconds for all calls to a + server. Defaults to 3 seconds. + @param cache_cas: (default False) If true, cas operations will + be cached. WARNING: This cache is not expired internally, if + you have a long-running process you will need to expire it + manually via client.reset_cas(), or the cache can grow + unlimited. + @param server_max_key_length: (default SERVER_MAX_KEY_LENGTH) + Data that is larger than this will not be sent to the server. + @param server_max_value_length: (default + SERVER_MAX_VALUE_LENGTH) Data that is larger than this will + not be sent to the server. + @param flush_on_reconnect: optional flag which prevents a + scenario that can cause stale data to be read: If there's more + than one memcached server and the connection to one is + interrupted, keys that mapped to that server will get + reassigned to another. If the first server comes back, those + keys will map to it again. If it still has its data, get()s + can read stale data that was overwritten on another + server. This flag is off by default for backwards + compatibility. + @param check_keys: (default True) If True, the key is checked + to ensure it is the correct length and composed of the right + characters. + """ + super(Client, self).__init__() + self.debug = debug + self.dead_retry = dead_retry + self.socket_timeout = socket_timeout + self.flush_on_reconnect = flush_on_reconnect + self.set_servers(servers) + self.stats = {} + self.cache_cas = cache_cas + self.reset_cas() + self.do_check_key = check_keys + + # Allow users to modify pickling/unpickling behavior + self.pickleProtocol = pickleProtocol + self.pickler = pickler + self.unpickler = unpickler + self.persistent_load = pload + self.persistent_id = pid + self.server_max_key_length = server_max_key_length + if self.server_max_key_length is None: + self.server_max_key_length = SERVER_MAX_KEY_LENGTH + self.server_max_value_length = server_max_value_length + if self.server_max_value_length is None: + self.server_max_value_length = SERVER_MAX_VALUE_LENGTH + + # figure out the pickler style + file = BytesIO() + try: + pickler = self.pickler(file, protocol=self.pickleProtocol) + self.picklerIsKeyword = True + except TypeError: + self.picklerIsKeyword = False + + def reset_cas(self): + """Reset the cas cache. + + This is only used if the Client() object was created with + "cache_cas=True". If used, this cache does not expire + internally, so it can grow unbounded if you do not clear it + yourself. + """ + self.cas_ids = {} + + def set_servers(self, servers): + """Set the pool of servers used by this client. + + @param servers: an array of servers. + Servers can be passed in two forms: + 1. Strings of the form C{"host:port"}, which implies a + default weight of 1. + 2. Tuples of the form C{("host:port", weight)}, where + C{weight} is an integer weight value. + + """ + self.servers = [_Host(s, self.debug, dead_retry=self.dead_retry, + socket_timeout=self.socket_timeout, + flush_on_reconnect=self.flush_on_reconnect) + for s in servers] + self._init_buckets() + + def get_stats(self, stat_args=None): + """Get statistics from each of the servers. + + @param stat_args: Additional arguments to pass to the memcache + "stats" command. + + @return: A list of tuples ( server_identifier, + stats_dictionary ). The dictionary contains a number of + name/value pairs specifying the name of the status field + and the string value associated with it. The values are + not converted from strings. + """ + data = [] + for s in self.servers: + if not s.connect(): + continue + if s.family == socket.AF_INET: + name = '%s:%s (%s)' % (s.ip, s.port, s.weight) + elif s.family == socket.AF_INET6: + name = '[%s]:%s (%s)' % (s.ip, s.port, s.weight) + else: + name = 'unix:%s (%s)' % (s.address, s.weight) + if not stat_args: + s.send_cmd('stats') + else: + s.send_cmd('stats ' + stat_args) + serverData = {} + data.append((name, serverData)) + readline = s.readline + while 1: + line = readline() + if not line or line.strip() == 'END': + break + stats = line.split(' ', 2) + serverData[stats[1]] = stats[2] + + return(data) + + def get_slabs(self): + data = [] + for s in self.servers: + if not s.connect(): + continue + if s.family == socket.AF_INET: + name = '%s:%s (%s)' % (s.ip, s.port, s.weight) + elif s.family == socket.AF_INET6: + name = '[%s]:%s (%s)' % (s.ip, s.port, s.weight) + else: + name = 'unix:%s (%s)' % (s.address, s.weight) + serverData = {} + data.append((name, serverData)) + s.send_cmd('stats items') + readline = s.readline + while 1: + line = readline() + if not line or line.strip() == 'END': + break + item = line.split(' ', 2) + # 0 = STAT, 1 = ITEM, 2 = Value + slab = item[1].split(':', 2) + # 0 = items, 1 = Slab #, 2 = Name + if slab[1] not in serverData: + serverData[slab[1]] = {} + serverData[slab[1]][slab[2]] = item[2] + return data + + def flush_all(self): + """Expire all data in memcache servers that are reachable.""" + for s in self.servers: + if not s.connect(): + continue + s.flush() + + def debuglog(self, str): + if self.debug: + sys.stderr.write("MemCached: %s\n" % str) + + def _statlog(self, func): + if func not in self.stats: + self.stats[func] = 1 + else: + self.stats[func] += 1 + + def forget_dead_hosts(self): + """Reset every host in the pool to an "alive" state.""" + for s in self.servers: + s.deaduntil = 0 + + def _init_buckets(self): + self.buckets = [] + for server in self.servers: + for i in range(server.weight): + self.buckets.append(server) + + def _get_server(self, key): + if isinstance(key, tuple): + serverhash, key = key + else: + serverhash = serverHashFunction(key) + + if not self.buckets: + return None, None + + for i in range(Client._SERVER_RETRIES): + server = self.buckets[serverhash % len(self.buckets)] + if server.connect(): + # print("(using server %s)" % server,) + return server, key + serverhash = serverHashFunction(str(serverhash) + str(i)) + return None, None + + def disconnect_all(self): + for s in self.servers: + s.close_socket() + + def delete_multi(self, keys, time=0, key_prefix=''): + """Delete multiple keys in the memcache doing just one query. + + >>> notset_keys = mc.set_multi({'a1' : 'val1', 'a2' : 'val2'}) + >>> mc.get_multi(['a1', 'a2']) == {'a1' : 'val1','a2' : 'val2'} + 1 + >>> mc.delete_multi(['key1', 'key2']) + 1 + >>> mc.get_multi(['key1', 'key2']) == {} + 1 + + This method is recommended over iterated regular L{delete}s as + it reduces total latency, since your app doesn't have to wait + for each round-trip of L{delete} before sending the next one. + + @param keys: An iterable of keys to clear + @param time: number of seconds any subsequent set / update + commands should fail. Defaults to 0 for no delay. + @param key_prefix: Optional string to prepend to each key when + sending to memcache. See docs for L{get_multi} and + L{set_multi}. + @return: 1 if no failure in communication with any memcacheds. + @rtype: int + """ + + self._statlog('delete_multi') + + server_keys, prefixed_to_orig_key = self._map_and_prefix_keys( + keys, key_prefix) + + # send out all requests on each server before reading anything + dead_servers = [] + + rc = 1 + for server in six.iterkeys(server_keys): + bigcmd = [] + write = bigcmd.append + if time is not None: + for key in server_keys[server]: # These are mangled keys + write("delete %s %d\r\n" % (key, time)) + else: + for key in server_keys[server]: # These are mangled keys + write("delete %s\r\n" % key) + try: + server.send_cmds(''.join(bigcmd)) + except socket.error as msg: + rc = 0 + if isinstance(msg, tuple): + msg = msg[1] + server.mark_dead(msg) + dead_servers.append(server) + + # if any servers died on the way, don't expect them to respond. + for server in dead_servers: + del server_keys[server] + + for server, keys in six.iteritems(server_keys): + try: + for key in keys: + server.expect("DELETED") + except socket.error as msg: + if isinstance(msg, tuple): + msg = msg[1] + server.mark_dead(msg) + rc = 0 + return rc + + def delete(self, key, time=0): + '''Deletes a key from the memcache. + + @return: Nonzero on success. + @param time: number of seconds any subsequent set / update commands + should fail. Defaults to None for no delay. + @rtype: int + ''' + return self._deletetouch(['DELETED', 'NOT_FOUND'], "delete", key, time) + + def touch(self, key, time=0): + '''Updates the expiration time of a key in memcache. + + @return: Nonzero on success. + @param time: Tells memcached the time which this value should + expire, either as a delta number of seconds, or an absolute + unix time-since-the-epoch value. See the memcached protocol + docs section "Storage Commands" for more info on . We + default to 0 == cache forever. + @rtype: int + ''' + return self._deletetouch(['TOUCHED'], "touch", key, time) + + def _deletetouch(self, expected, cmd, key, time=0): + if self.do_check_key: + self.check_key(key) + server, key = self._get_server(key) + if not server: + return 0 + self._statlog(cmd) + if time is not None and time != 0: + cmd = "%s %s %d" % (cmd, key, time) + else: + cmd = "%s %s" % (cmd, key) + + try: + server.send_cmd(cmd) + line = server.readline() + if line and line.strip() in expected: + return 1 + self.debuglog('%s expected %s, got: %r' + % (cmd, ' or '.join(expected), line)) + except socket.error as msg: + if isinstance(msg, tuple): + msg = msg[1] + server.mark_dead(msg) + return 0 + + def incr(self, key, delta=1): + """Increment value for C{key} by C{delta} + + Sends a command to the server to atomically increment the + value for C{key} by C{delta}, or by 1 if C{delta} is + unspecified. Returns None if C{key} doesn't exist on server, + otherwise it returns the new value after incrementing. + + Note that the value for C{key} must already exist in the + memcache, and it must be the string representation of an + integer. + + >>> mc.set("counter", "20") # returns 1, indicating success + 1 + >>> mc.incr("counter") + 21 + >>> mc.incr("counter") + 22 + + Overflow on server is not checked. Be aware of values + approaching 2**32. See L{decr}. + + @param delta: Integer amount to increment by (should be zero + or greater). + + @return: New value after incrementing. + @rtype: int + """ + return self._incrdecr("incr", key, delta) + + def decr(self, key, delta=1): + """Decrement value for C{key} by C{delta} + + Like L{incr}, but decrements. Unlike L{incr}, underflow is + checked and new values are capped at 0. If server value is 1, + a decrement of 2 returns 0, not -1. + + @param delta: Integer amount to decrement by (should be zero + or greater). + + @return: New value after decrementing or None on error. + @rtype: int + """ + return self._incrdecr("decr", key, delta) + + def _incrdecr(self, cmd, key, delta): + if self.do_check_key: + self.check_key(key) + server, key = self._get_server(key) + if not server: + return None + self._statlog(cmd) + cmd = "%s %s %d" % (cmd, key, delta) + try: + server.send_cmd(cmd) + line = server.readline() + if line is None or line.strip() == 'NOT_FOUND': + return None + return int(line) + except socket.error as msg: + if isinstance(msg, tuple): + msg = msg[1] + server.mark_dead(msg) + return None + + def add(self, key, val, time=0, min_compress_len=0): + '''Add new key with value. + + Like L{set}, but only stores in memcache if the key doesn't + already exist. + + @return: Nonzero on success. + @rtype: int + ''' + return self._set("add", key, val, time, min_compress_len) + + def append(self, key, val, time=0, min_compress_len=0): + '''Append the value to the end of the existing key's value. + + Only stores in memcache if key already exists. + Also see L{prepend}. + + @return: Nonzero on success. + @rtype: int + ''' + return self._set("append", key, val, time, min_compress_len) + + def prepend(self, key, val, time=0, min_compress_len=0): + '''Prepend the value to the beginning of the existing key's value. + + Only stores in memcache if key already exists. + Also see L{append}. + + @return: Nonzero on success. + @rtype: int + ''' + return self._set("prepend", key, val, time, min_compress_len) + + def replace(self, key, val, time=0, min_compress_len=0): + '''Replace existing key with value. + + Like L{set}, but only stores in memcache if the key already exists. + The opposite of L{add}. + + @return: Nonzero on success. + @rtype: int + ''' + return self._set("replace", key, val, time, min_compress_len) + + def set(self, key, val, time=0, min_compress_len=0): + '''Unconditionally sets a key to a given value in the memcache. + + The C{key} can optionally be an tuple, with the first element + being the server hash value and the second being the key. If + you want to avoid making this module calculate a hash value. + You may prefer, for example, to keep all of a given user's + objects on the same memcache server, so you could use the + user's unique id as the hash value. + + @return: Nonzero on success. + @rtype: int + + @param time: Tells memcached the time which this value should + expire, either as a delta number of seconds, or an absolute + unix time-since-the-epoch value. See the memcached protocol + docs section "Storage Commands" for more info on . We + default to 0 == cache forever. + + @param min_compress_len: The threshold length to kick in + auto-compression of the value using the zlib.compress() + routine. If the value being cached is a string, then the + length of the string is measured, else if the value is an + object, then the length of the pickle result is measured. If + the resulting attempt at compression yeilds a larger string + than the input, then it is discarded. For backwards + compatability, this parameter defaults to 0, indicating don't + ever try to compress. + + ''' + return self._set("set", key, val, time, min_compress_len) + + def cas(self, key, val, time=0, min_compress_len=0): + '''Check and set (CAS) + + Sets a key to a given value in the memcache if it hasn't been + altered since last fetched. (See L{gets}). + + The C{key} can optionally be an tuple, with the first element + being the server hash value and the second being the key. If + you want to avoid making this module calculate a hash value. + You may prefer, for example, to keep all of a given user's + objects on the same memcache server, so you could use the + user's unique id as the hash value. + + @return: Nonzero on success. + @rtype: int + + @param time: Tells memcached the time which this value should + expire, either as a delta number of seconds, or an absolute + unix time-since-the-epoch value. See the memcached protocol + docs section "Storage Commands" for more info on . We + default to 0 == cache forever. + + @param min_compress_len: The threshold length to kick in + auto-compression of the value using the zlib.compress() + routine. If the value being cached is a string, then the + length of the string is measured, else if the value is an + object, then the length of the pickle result is measured. If + the resulting attempt at compression yeilds a larger string + than the input, then it is discarded. For backwards + compatability, this parameter defaults to 0, indicating don't + ever try to compress. + ''' + return self._set("cas", key, val, time, min_compress_len) + + def _map_and_prefix_keys(self, key_iterable, key_prefix): + """Compute the mapping of server (_Host instance) -> list of keys to + stuff onto that server, as well as the mapping of prefixed key + -> original key. + """ + # Check it just once ... + key_extra_len = len(key_prefix) + if key_prefix and self.do_check_key: + self.check_key(key_prefix) + + # server (_Host) -> list of unprefixed server keys in mapping + server_keys = {} + + prefixed_to_orig_key = {} + # build up a list for each server of all the keys we want. + for orig_key in key_iterable: + if isinstance(orig_key, tuple): + # Tuple of hashvalue, key ala _get_server(). Caller is + # essentially telling us what server to stuff this on. + # Ensure call to _get_server gets a Tuple as well. + str_orig_key = str(orig_key[1]) + + # Gotta pre-mangle key before hashing to a + # server. Returns the mangled key. + server, key = self._get_server( + (orig_key[0], key_prefix + str_orig_key)) + else: + # set_multi supports int / long keys. + str_orig_key = str(orig_key) + server, key = self._get_server(key_prefix + str_orig_key) + + # Now check to make sure key length is proper ... + if self.do_check_key: + self.check_key(str_orig_key, key_extra_len=key_extra_len) + + if not server: + continue + + if server not in server_keys: + server_keys[server] = [] + server_keys[server].append(key) + prefixed_to_orig_key[key] = orig_key + + return (server_keys, prefixed_to_orig_key) + + def set_multi(self, mapping, time=0, key_prefix='', min_compress_len=0): + '''Sets multiple keys in the memcache doing just one query. + + >>> notset_keys = mc.set_multi({'key1' : 'val1', 'key2' : 'val2'}) + >>> mc.get_multi(['key1', 'key2']) == {'key1' : 'val1', + ... 'key2' : 'val2'} + 1 + + + This method is recommended over regular L{set} as it lowers + the number of total packets flying around your network, + reducing total latency, since your app doesn't have to wait + for each round-trip of L{set} before sending the next one. + + @param mapping: A dict of key/value pairs to set. + + @param time: Tells memcached the time which this value should + expire, either as a delta number of seconds, or an + absolute unix time-since-the-epoch value. See the + memcached protocol docs section "Storage Commands" for + more info on . We default to 0 == cache forever. + + @param key_prefix: Optional string to prepend to each key when + sending to memcache. Allows you to efficiently stuff these + keys into a pseudo-namespace in memcache: + + >>> notset_keys = mc.set_multi( + ... {'key1' : 'val1', 'key2' : 'val2'}, + ... key_prefix='subspace_') + >>> len(notset_keys) == 0 + True + >>> mc.get_multi(['subspace_key1', + ... 'subspace_key2']) == {'subspace_key1': 'val1', + ... 'subspace_key2' : 'val2'} + True + + Causes key 'subspace_key1' and 'subspace_key2' to be + set. Useful in conjunction with a higher-level layer which + applies namespaces to data in memcache. In this case, the + return result would be the list of notset original keys, + prefix not applied. + + @param min_compress_len: The threshold length to kick in + auto-compression of the value using the zlib.compress() + routine. If the value being cached is a string, then the + length of the string is measured, else if the value is an + object, then the length of the pickle result is + measured. If the resulting attempt at compression yeilds a + larger string than the input, then it is discarded. For + backwards compatability, this parameter defaults to 0, + indicating don't ever try to compress. + + @return: List of keys which failed to be stored [ memcache out + of memory, etc. ]. + + @rtype: list + ''' + self._statlog('set_multi') + + server_keys, prefixed_to_orig_key = self._map_and_prefix_keys( + six.iterkeys(mapping), key_prefix) + + # send out all requests on each server before reading anything + dead_servers = [] + notstored = [] # original keys. + + for server in six.iterkeys(server_keys): + bigcmd = [] + write = bigcmd.append + try: + for key in server_keys[server]: # These are mangled keys + store_info = self._val_to_store_info( + mapping[prefixed_to_orig_key[key]], + min_compress_len) + if store_info: + msg = "set %s %d %d %d\r\n%s\r\n" + write(msg % (key, + store_info[0], + time, + store_info[1], + store_info[2])) + else: + notstored.append(prefixed_to_orig_key[key]) + server.send_cmds(''.join(bigcmd)) + except socket.error as msg: + if isinstance(msg, tuple): + msg = msg[1] + server.mark_dead(msg) + dead_servers.append(server) + + # if any servers died on the way, don't expect them to respond. + for server in dead_servers: + del server_keys[server] + + # short-circuit if there are no servers, just return all keys + if not server_keys: + return(mapping.keys()) + + for server, keys in six.iteritems(server_keys): + try: + for key in keys: + if server.readline() == 'STORED': + continue + else: + # un-mangle. + notstored.append(prefixed_to_orig_key[key]) + except (_Error, socket.error) as msg: + if isinstance(msg, tuple): + msg = msg[1] + server.mark_dead(msg) + return notstored + + def _val_to_store_info(self, val, min_compress_len): + """Transform val to a storable representation. + + Returns a tuple of the flags, the length of the new value, and + the new value itself. + """ + flags = 0 + if isinstance(val, str): + pass + elif isinstance(val, int): + flags |= Client._FLAG_INTEGER + val = "%d" % val + # force no attempt to compress this silly string. + min_compress_len = 0 + elif isinstance(val, long): + flags |= Client._FLAG_LONG + val = "%d" % val + # force no attempt to compress this silly string. + min_compress_len = 0 + else: + flags |= Client._FLAG_PICKLE + file = BytesIO() + if self.picklerIsKeyword: + pickler = self.pickler(file, protocol=self.pickleProtocol) + else: + pickler = self.pickler(file, self.pickleProtocol) + if self.persistent_id: + pickler.persistent_id = self.persistent_id + pickler.dump(val) + val = file.getvalue() + + lv = len(val) + # We should try to compress if min_compress_len > 0 and we + # could import zlib and this string is longer than our min + # threshold. + if min_compress_len and lv > min_compress_len: + comp_val = zlib.compress(val) + # Only retain the result if the compression result is smaller + # than the original. + if len(comp_val) < lv: + flags |= Client._FLAG_COMPRESSED + val = comp_val + + # silently do not store if value length exceeds maximum + if (self.server_max_value_length != 0 and + len(val) > self.server_max_value_length): + return(0) + + return (flags, len(val), val) + + def _set(self, cmd, key, val, time, min_compress_len=0): + if self.do_check_key: + self.check_key(key) + server, key = self._get_server(key) + if not server: + return 0 + + def _unsafe_set(): + self._statlog(cmd) + + store_info = self._val_to_store_info(val, min_compress_len) + if not store_info: + return(0) + + if cmd == 'cas': + if key not in self.cas_ids: + return self._set('set', key, val, time, min_compress_len) + fullcmd = "%s %s %d %d %d %d\r\n%s" % ( + cmd, key, store_info[0], time, store_info[1], + self.cas_ids[key], store_info[2]) + else: + fullcmd = "%s %s %d %d %d\r\n%s" % ( + cmd, key, store_info[0], + time, store_info[1], store_info[2] + ) + + try: + server.send_cmd(fullcmd) + return(server.expect("STORED", raise_exception=True) + == "STORED") + except socket.error as msg: + if isinstance(msg, tuple): + msg = msg[1] + server.mark_dead(msg) + return 0 + + try: + return _unsafe_set() + except _ConnectionDeadError: + # retry once + try: + if server._get_socket(): + return _unsafe_set() + except (_ConnectionDeadError, socket.error) as msg: + server.mark_dead(msg) + return 0 + + def _get(self, cmd, key): + if self.do_check_key: + self.check_key(key) + server, key = self._get_server(key) + if not server: + return None + + def _unsafe_get(): + self._statlog(cmd) + + try: + server.send_cmd("%s %s" % (cmd, key)) + rkey = flags = rlen = cas_id = None + + if cmd == 'gets': + rkey, flags, rlen, cas_id, = self._expect_cas_value( + server, raise_exception=True + ) + if rkey and self.cache_cas: + self.cas_ids[rkey] = cas_id + else: + rkey, flags, rlen, = self._expectvalue( + server, raise_exception=True + ) + + if not rkey: + return None + try: + value = self._recv_value(server, flags, rlen) + finally: + server.expect("END", raise_exception=True) + except (_Error, socket.error) as msg: + if isinstance(msg, tuple): + msg = msg[1] + server.mark_dead(msg) + return None + + return value + + try: + return _unsafe_get() + except _ConnectionDeadError: + # retry once + try: + if server.connect(): + return _unsafe_get() + return None + except (_ConnectionDeadError, socket.error) as msg: + server.mark_dead(msg) + return None + + def get(self, key): + '''Retrieves a key from the memcache. + + @return: The value or None. + ''' + return self._get('get', key) + + def gets(self, key): + '''Retrieves a key from the memcache. Used in conjunction with 'cas'. + + @return: The value or None. + ''' + return self._get('gets', key) + + def get_multi(self, keys, key_prefix=''): + '''Retrieves multiple keys from the memcache doing just one query. + + >>> success = mc.set("foo", "bar") + >>> success = mc.set("baz", 42) + >>> mc.get_multi(["foo", "baz", "foobar"]) == { + ... "foo": "bar", "baz": 42 + ... } + 1 + >>> mc.set_multi({'k1' : 1, 'k2' : 2}, key_prefix='pfx_') == [] + 1 + + This looks up keys 'pfx_k1', 'pfx_k2', ... . Returned dict + will just have unprefixed keys 'k1', 'k2'. + + >>> mc.get_multi(['k1', 'k2', 'nonexist'], + ... key_prefix='pfx_') == {'k1' : 1, 'k2' : 2} + 1 + + get_mult [ and L{set_multi} ] can take str()-ables like ints / + longs as keys too. Such as your db pri key fields. They're + rotored through str() before being passed off to memcache, + with or without the use of a key_prefix. In this mode, the + key_prefix could be a table name, and the key itself a db + primary key number. + + >>> mc.set_multi({42: 'douglass adams', + ... 46: 'and 2 just ahead of me'}, + ... key_prefix='numkeys_') == [] + 1 + >>> mc.get_multi([46, 42], key_prefix='numkeys_') == { + ... 42: 'douglass adams', + ... 46: 'and 2 just ahead of me' + ... } + 1 + + This method is recommended over regular L{get} as it lowers + the number of total packets flying around your network, + reducing total latency, since your app doesn't have to wait + for each round-trip of L{get} before sending the next one. + + See also L{set_multi}. + + @param keys: An array of keys. + + @param key_prefix: A string to prefix each key when we + communicate with memcache. Facilitates pseudo-namespaces + within memcache. Returned dictionary keys will not have this + prefix. + + @return: A dictionary of key/value pairs that were + available. If key_prefix was provided, the keys in the retured + dictionary will not have it present. + ''' + + self._statlog('get_multi') + + server_keys, prefixed_to_orig_key = self._map_and_prefix_keys( + keys, key_prefix) + + # send out all requests on each server before reading anything + dead_servers = [] + for server in six.iterkeys(server_keys): + try: + server.send_cmd("get %s" % " ".join(server_keys[server])) + except socket.error as msg: + if isinstance(msg, tuple): + msg = msg[1] + server.mark_dead(msg) + dead_servers.append(server) + + # if any servers died on the way, don't expect them to respond. + for server in dead_servers: + del server_keys[server] + + retvals = {} + for server in six.iterkeys(server_keys): + try: + line = server.readline() + while line and line != 'END': + rkey, flags, rlen = self._expectvalue(server, line) + # Bo Yang reports that this can sometimes be None + if rkey is not None: + val = self._recv_value(server, flags, rlen) + # un-prefix returned key. + retvals[prefixed_to_orig_key[rkey]] = val + line = server.readline() + except (_Error, socket.error) as msg: + if isinstance(msg, tuple): + msg = msg[1] + server.mark_dead(msg) + return retvals + + def _expect_cas_value(self, server, line=None, raise_exception=False): + if not line: + line = server.readline(raise_exception) + + if line and line[:5] == 'VALUE': + resp, rkey, flags, len, cas_id = line.split() + return (rkey, int(flags), int(len), int(cas_id)) + else: + return (None, None, None, None) + + def _expectvalue(self, server, line=None, raise_exception=False): + if not line: + line = server.readline(raise_exception) + + if line and line[:5] == 'VALUE': + resp, rkey, flags, len = line.split() + flags = int(flags) + rlen = int(len) + return (rkey, flags, rlen) + else: + return (None, None, None) + + def _recv_value(self, server, flags, rlen): + rlen += 2 # include \r\n + buf = server.recv(rlen) + if len(buf) != rlen: + raise _Error("received %d bytes when expecting %d" + % (len(buf), rlen)) + + if len(buf) == rlen: + buf = buf[:-2] # strip \r\n + + if flags & Client._FLAG_COMPRESSED: + buf = zlib.decompress(buf) + + if flags == 0 or flags == Client._FLAG_COMPRESSED: + # Either a bare string or a compressed string now decompressed... + val = buf + elif flags & Client._FLAG_INTEGER: + val = int(buf) + elif flags & Client._FLAG_LONG: + val = long(buf) + elif flags & Client._FLAG_PICKLE: + try: + file = BytesIO(buf) + unpickler = self.unpickler(file) + if self.persistent_load: + unpickler.persistent_load = self.persistent_load + val = unpickler.load() + except Exception as e: + self.debuglog('Pickle error: %s\n' % e) + return None + else: + self.debuglog("unknown flags on get: %x\n" % flags) + raise ValueError('Unknown flags on get: %x' % flags) + + return val + + def check_key(self, key, key_extra_len=0): + """Checks sanity of key. + + Fails if: + + Key length is > SERVER_MAX_KEY_LENGTH (Raises MemcachedKeyLength). + Contains control characters (Raises MemcachedKeyCharacterError). + Is not a string (Raises MemcachedStringEncodingError) + Is an unicode string (Raises MemcachedStringEncodingError) + Is not a string (Raises MemcachedKeyError) + Is None (Raises MemcachedKeyError) + """ + if isinstance(key, tuple): + key = key[1] + if not key: + raise Client.MemcachedKeyNoneError("Key is None") + + # Make sure we're not a specific unicode type, if we're old enough that + # it's a separate type. + if _has_unicode is True and isinstance(key, unicode): + raise Client.MemcachedStringEncodingError( + "Keys must be str()'s, not unicode. Convert your unicode " + "strings using mystring.encode(charset)!") + if not isinstance(key, str): + raise Client.MemcachedKeyTypeError("Key must be str()'s") + + if isinstance(key, _str_cls): + if (self.server_max_key_length != 0 and + len(key) + key_extra_len > self.server_max_key_length): + raise Client.MemcachedKeyLengthError( + "Key length is > %s" % self.server_max_key_length + ) + if not valid_key_chars_re.match(key): + raise Client.MemcachedKeyCharacterError( + "Control characters not allowed") + + +class _Host(object): + + def __init__(self, host, debug=0, dead_retry=_DEAD_RETRY, + socket_timeout=_SOCKET_TIMEOUT, flush_on_reconnect=0): + self.dead_retry = dead_retry + self.socket_timeout = socket_timeout + self.debug = debug + self.flush_on_reconnect = flush_on_reconnect + if isinstance(host, tuple): + host, self.weight = host + else: + self.weight = 1 + + # parse the connection string + m = re.match(r'^(?Punix):(?P.*)$', host) + if not m: + m = re.match(r'^(?Pinet6):' + r'\[(?P[^\[\]]+)\](:(?P[0-9]+))?$', host) + if not m: + m = re.match(r'^(?Pinet):' + r'(?P[^:]+)(:(?P[0-9]+))?$', host) + if not m: + m = re.match(r'^(?P[^:]+)(:(?P[0-9]+))?$', host) + if not m: + raise ValueError('Unable to parse connection string: "%s"' % host) + + hostData = m.groupdict() + if hostData.get('proto') == 'unix': + self.family = socket.AF_UNIX + self.address = hostData['path'] + elif hostData.get('proto') == 'inet6': + self.family = socket.AF_INET6 + self.ip = hostData['host'] + self.port = int(hostData.get('port') or 11211) + self.address = (self.ip, self.port) + else: + self.family = socket.AF_INET + self.ip = hostData['host'] + self.port = int(hostData.get('port') or 11211) + self.address = (self.ip, self.port) + + self.deaduntil = 0 + self.socket = None + self.flush_on_next_connect = 0 + + self.buffer = '' + + def debuglog(self, str): + if self.debug: + sys.stderr.write("MemCached: %s\n" % str) + + def _check_dead(self): + if self.deaduntil and self.deaduntil > time.time(): + return 1 + self.deaduntil = 0 + return 0 + + def connect(self): + if self._get_socket(): + return 1 + return 0 + + def mark_dead(self, reason): + self.debuglog("MemCache: %s: %s. Marking dead." % (self, reason)) + self.deaduntil = time.time() + self.dead_retry + if self.flush_on_reconnect: + self.flush_on_next_connect = 1 + self.close_socket() + + def _get_socket(self): + if self._check_dead(): + return None + if self.socket: + return self.socket + s = socket.socket(self.family, socket.SOCK_STREAM) + if hasattr(s, 'settimeout'): + s.settimeout(self.socket_timeout) + try: + s.connect(self.address) + except socket.timeout as msg: + self.mark_dead("connect: %s" % msg) + return None + except socket.error as msg: + if isinstance(msg, tuple): + msg = msg[1] + self.mark_dead("connect: %s" % msg) + return None + self.socket = s + self.buffer = '' + if self.flush_on_next_connect: + self.flush() + self.flush_on_next_connect = 0 + return s + + def close_socket(self): + if self.socket: + self.socket.close() + self.socket = None + + def send_cmd(self, cmd): + self.socket.sendall(cmd + '\r\n') + + def send_cmds(self, cmds): + """cmds already has trailing \r\n's applied.""" + self.socket.sendall(cmds) + + def readline(self, raise_exception=False): + """Read a line and return it. + + If "raise_exception" is set, raise _ConnectionDeadError if the + read fails, otherwise return an empty string. + """ + buf = self.buffer + if self.socket: + recv = self.socket.recv + else: + recv = lambda bufsize: '' + + while True: + index = buf.find('\r\n') + if index >= 0: + break + data = recv(4096) + if not data: + # connection close, let's kill it and raise + self.mark_dead('connection closed in readline()') + if raise_exception: + raise _ConnectionDeadError() + else: + return '' + + buf += data + self.buffer = buf[index + 2:] + return buf[:index] + + def expect(self, text, raise_exception=False): + line = self.readline(raise_exception) + if line != text: + self.debuglog("while expecting '%s', got unexpected response '%s'" + % (text, line)) + return line + + def recv(self, rlen): + self_socket_recv = self.socket.recv + buf = self.buffer + while len(buf) < rlen: + foo = self_socket_recv(max(rlen - len(buf), 4096)) + buf += foo + if not foo: + raise _Error('Read %d bytes, expecting %d, ' + 'read returned 0 length bytes' % (len(buf), rlen)) + self.buffer = buf[rlen:] + return buf[:rlen] + + def flush(self): + self.send_cmd('flush_all') + self.expect('OK') + + def __str__(self): + d = '' + if self.deaduntil: + d = " (dead until %d)" % self.deaduntil + + if self.family == socket.AF_INET: + return "inet:%s:%d%s" % (self.address[0], self.address[1], d) + elif self.family == socket.AF_INET6: + return "inet6:[%s]:%d%s" % (self.address[0], self.address[1], d) + else: + return "unix:%s%s" % (self.address, d) + + +def _doctest(): + import doctest + import memcache + servers = ["127.0.0.1:11211"] + mc = Client(servers, debug=1) + globs = {"mc": mc} + return doctest.testmod(memcache, globs=globs) + +if __name__ == "__main__": + failures = 0 + print("Testing docstrings...") + _doctest() + print("Running tests:") + print() + serverList = [["127.0.0.1:11211"]] + if '--do-unix' in sys.argv: + serverList.append([os.path.join(os.getcwd(), 'memcached.socket')]) + + for servers in serverList: + mc = Client(servers, debug=1) + + def to_s(val): + if not isinstance(val, _str_cls): + return "%s (%s)" % (val, type(val)) + return "%s" % val + + def test_setget(key, val): + global failures + print("Testing set/get {'%s': %s} ..." + % (to_s(key), to_s(val)), end=" ") + mc.set(key, val) + newval = mc.get(key) + if newval == val: + print("OK") + return 1 + else: + print("FAIL") + failures += 1 + return 0 + + class FooStruct(object): + + def __init__(self): + self.bar = "baz" + + def __str__(self): + return "A FooStruct" + + def __eq__(self, other): + if isinstance(other, FooStruct): + return self.bar == other.bar + return 0 + + test_setget("a_string", "some random string") + test_setget("an_integer", 42) + if test_setget("long", long(1 << 30)): + print("Testing delete ...", end=" ") + if mc.delete("long"): + print("OK") + else: + print("FAIL") + failures += 1 + print("Checking results of delete ...", end=" ") + if mc.get("long") is None: + print("OK") + else: + print("FAIL") + failures += 1 + print("Testing get_multi ...",) + print(mc.get_multi(["a_string", "an_integer"])) + + # removed from the protocol + # if test_setget("timed_delete", 'foo'): + # print "Testing timed delete ...", + # if mc.delete("timed_delete", 1): + # print("OK") + # else: + # print("FAIL") + # failures += 1 + # print "Checking results of timed delete ..." + # if mc.get("timed_delete") is None: + # print("OK") + # else: + # print("FAIL") + # failures += 1 + + print("Testing get(unknown value) ...", end=" ") + print(to_s(mc.get("unknown_value"))) + + f = FooStruct() + test_setget("foostruct", f) + + print("Testing incr ...", end=" ") + x = mc.incr("an_integer", 1) + if x == 43: + print("OK") + else: + print("FAIL") + failures += 1 + + print("Testing decr ...", end=" ") + x = mc.decr("an_integer", 1) + if x == 42: + print("OK") + else: + print("FAIL") + failures += 1 + sys.stdout.flush() + + # sanity tests + print("Testing sending spaces...", end=" ") + sys.stdout.flush() + try: + x = mc.set("this has spaces", 1) + except Client.MemcachedKeyCharacterError as msg: + print("OK") + else: + print("FAIL") + failures += 1 + + print("Testing sending control characters...", end=" ") + try: + x = mc.set("this\x10has\x11control characters\x02", 1) + except Client.MemcachedKeyCharacterError as msg: + print("OK") + else: + print("FAIL") + failures += 1 + + print("Testing using insanely long key...", end=" ") + try: + x = mc.set('a'*SERVER_MAX_KEY_LENGTH, 1) + except Client.MemcachedKeyLengthError as msg: + print("FAIL") + failures += 1 + else: + print("OK") + try: + x = mc.set('a'*SERVER_MAX_KEY_LENGTH + 'a', 1) + except Client.MemcachedKeyLengthError as msg: + print("OK") + else: + print("FAIL") + failures += 1 + + print("Testing sending a unicode-string key...", end=" ") + try: + x = mc.set(unicode('keyhere'), 1) + except Client.MemcachedStringEncodingError as msg: + print("OK", end=" ") + else: + print("FAIL", end=" ") + failures += 1 + try: + x = mc.set((unicode('a')*SERVER_MAX_KEY_LENGTH).encode('utf-8'), 1) + except Client.MemcachedKeyError: + print("FAIL", end=" ") + failures += 1 + else: + print("OK", end=" ") + s = pickle.loads('V\\u4f1a\np0\n.') + try: + x = mc.set((s * SERVER_MAX_KEY_LENGTH).encode('utf-8'), 1) + except Client.MemcachedKeyLengthError: + print("OK") + else: + print("FAIL") + failures += 1 + + print("Testing using a value larger than the memcached value limit...") + print('NOTE: "MemCached: while expecting[...]" is normal...') + x = mc.set('keyhere', 'a'*SERVER_MAX_VALUE_LENGTH) + if mc.get('keyhere') is None: + print("OK", end=" ") + else: + print("FAIL", end=" ") + failures += 1 + x = mc.set('keyhere', 'a'*SERVER_MAX_VALUE_LENGTH + 'aaa') + if mc.get('keyhere') is None: + print("OK") + else: + print("FAIL") + failures += 1 + + print("Testing set_multi() with no memcacheds running", end=" ") + mc.disconnect_all() + errors = mc.set_multi({'keyhere': 'a', 'keythere': 'b'}) + if errors != []: + print("FAIL") + failures += 1 + else: + print("OK") + + print("Testing delete_multi() with no memcacheds running", end=" ") + mc.disconnect_all() + ret = mc.delete_multi({'keyhere': 'a', 'keythere': 'b'}) + if ret != 1: + print("FAIL") + failures += 1 + else: + print("OK") + + if failures > 0: + print('*** THERE WERE FAILED TESTS') + sys.exit(1) + sys.exit(0) + + +# vim: ts=4 sw=4 et : diff --git a/web2py/gluon/contrib/memdb.py b/web2py/gluon/contrib/memdb.py new file mode 100644 index 0000000..e4b56ef --- /dev/null +++ b/web2py/gluon/contrib/memdb.py @@ -0,0 +1,905 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +This file is part of web2py Web Framework (Copyrighted, 2007-2009). +Developed by Massimo Di Pierro and +Robin B . +License: LGPLv3 +""" + +__all__ = ['MEMDB', 'Field'] + +import re +import sys +import os +import types +import datetime +import thread +import cStringIO +import csv +import copy +import gluon.validators as validators +from gluon.utils import web2py_uuid +from gluon.storage import Storage +from gluon import SQLTABLE +import random + +SQL_DIALECTS = {'memcache': { + 'boolean': bool, + 'string': unicode, + 'text': unicode, + 'password': unicode, + 'blob': unicode, + 'upload': unicode, + 'integer': long, + 'double': float, + 'date': datetime.date, + 'time': datetime.time, + 'datetime': datetime.datetime, + 'id': int, + 'reference': int, + 'lower': None, + 'upper': None, + 'is null': 'IS NULL', + 'is not null': 'IS NOT NULL', + 'extract': None, + 'left join': None, +}} + + +def cleanup(text): + if re.compile('[^0-9a-zA-Z_]').findall(text): + raise SyntaxError('Can\'t cleanup \'%s\': only [0-9a-zA-Z_] allowed in table and field names' % text) + return text + + +def assert_filter_fields(*fields): + for field in fields: + if isinstance(field, (Field, Expression)) and field.type\ + in ['text', 'blob']: + raise SyntaxError('AppEngine does not index by: %s' + % field.type) + + +def dateobj_to_datetime(object): + + # convert dates,times to datetimes for AppEngine + + if isinstance(object, datetime.date): + object = datetime.datetime(object.year, object.month, + object.day) + if isinstance(object, datetime.time): + object = datetime.datetime( + 1970, + 1, + 1, + object.hour, + object.minute, + object.second, + object.microsecond, + ) + return object + + +def sqlhtml_validators(field_type, length): + v = { + 'boolean': [], + 'string': validators.IS_LENGTH(length), + 'text': [], + 'password': validators.IS_LENGTH(length), + 'blob': [], + 'upload': [], + 'double': validators.IS_FLOAT_IN_RANGE(-1e100, 1e100), + 'integer': validators.IS_INT_IN_RANGE(-1e100, 1e100), + 'date': validators.IS_DATE(), + 'time': validators.IS_TIME(), + 'datetime': validators.IS_DATETIME(), + 'reference': validators.IS_INT_IN_RANGE(0, 1e100), + } + try: + return v[field_type[:9]] + except KeyError: + return [] + + +class DALStorage(dict): + + """ + a dictionary that let you do d['a'] as well as d.a + """ + + def __getattr__(self, key): + return self[key] + + def __setattr__(self, key, value): + if key in self: + raise SyntaxError( + 'Object \'%s\'exists and cannot be redefined' % key) + self[key] = value + + def __repr__(self): + return '' + + +class SQLCallableList(list): + + def __call__(self): + return copy.copy(self) + + +class MEMDB(DALStorage): + + """ + an instance of this class represents a database connection + + Example:: + + db=MEMDB(Client()) + db.define_table('tablename',Field('fieldname1'), + Field('fieldname2')) + """ + + def __init__(self, client): + self._dbname = 'memdb' + self['_lastsql'] = '' + self.tables = SQLCallableList() + self._translator = SQL_DIALECTS['memcache'] + self.client = client + + def define_table( + self, + tablename, + *fields, + **args + ): + tablename = cleanup(tablename) + if tablename in dir(self) or tablename[0] == '_': + raise SyntaxError('invalid table name: %s' % tablename) + if not tablename in self.tables: + self.tables.append(tablename) + else: + raise SyntaxError('table already defined: %s' % tablename) + t = self[tablename] = Table(self, tablename, *fields) + t._create() + return t + + def __call__(self, where=''): + return Set(self, where) + + +class SQLALL(object): + + def __init__(self, table): + self.table = table + + +class Table(DALStorage): + + """ + an instance of this class represents a database table + + Example:: + + db=MEMDB(Client()) + db.define_table('users',Field('name')) + db.users.insert(name='me') + """ + + def __init__( + self, + db, + tablename, + *fields + ): + self._db = db + self._tablename = tablename + self.fields = SQLCallableList() + self._referenced_by = [] + fields = list(fields) + fields.insert(0, Field('id', 'id')) + for field in fields: + self.fields.append(field.name) + self[field.name] = field + field._tablename = self._tablename + field._table = self + field._db = self._db + self.ALL = SQLALL(self) + + def _create(self): + fields = [] + myfields = {} + for k in self.fields: + field = self[k] + attr = {} + if not field.type[:9] in ['id', 'reference']: + if field.notnull: + attr = dict(required=True) + if field.type[:2] == 'id': + continue + if field.type[:9] == 'reference': + referenced = field.type[10:].strip() + if not referenced: + raise SyntaxError('Table %s: reference \'%s\' to nothing!' % ( + self._tablename, k)) + if not referenced in self._db: + raise SyntaxError( + 'Table: table %s does not exist' % referenced) + referee = self._db[referenced] + ftype = \ + self._db._translator[field.type[:9]]( + self._db[referenced]._tableobj) + if self._tablename in referee.fields: # ## THIS IS OK + raise SyntaxError('Field: table \'%s\' has same name as a field ' + 'in referenced table \'%s\'' % ( + self._tablename, referenced)) + self._db[referenced]._referenced_by.append((self._tablename, + field.name)) + elif not field.type in self._db._translator\ + or not self._db._translator[field.type]: + raise SyntaxError('Field: unknown field type %s' % field.type) + self._tableobj = self._db.client + return None + + def create(self): + + # nothing to do, here for backward compatility + + pass + + def drop(self): + + # nothing to do, here for backward compatibility + + self._db(self.id > 0).delete() + + + def insert(self, **fields): + # Checks 3 times that the id is new. 3 times is enough! + for i in range(3): + id = self._create_id() + if self.get(id) is None and self.update(id, **fields): + return long(id) + else: + raise RuntimeError("Too many ID conflicts") + + def get(self, id): + val = self._tableobj.get(self._id_to_key(id)) + if val: + return Storage(val) + else: + return None + + def update(self, id, **fields): + for field in fields: + if not field in fields and self[field].default\ + is not None: + fields[field] = self[field].default + if field in fields: + fields[field] = obj_represent(fields[field], + self[field].type, self._db) + return self._tableobj.set(self._id_to_key(id), fields) + + def delete(self, id): + return self._tableobj.delete(self._id_to_key(id)) + + def _id_to_key(self, id): + return '__memdb__/t/%s/k/%s' % (self._tablename, str(id)) + + def _create_id(self): + return long(web2py_uuid().replace('-',''),16) + + def __str__(self): + return self._tablename + + def __call__(self, id, **kwargs): + record = self.get(id) + if record is None: + return None + if kwargs and any(record[key]!=kwargs[key] for key in kwargs): + return None + return record + +class Expression(object): + + def __init__( + self, + name, + type='string', + db=None, + ): + (self.name, self.type, self._db) = (name, type, db) + + def __str__(self): + return self.name + + def __or__(self, other): # for use in sortby + assert_filter_fields(self, other) + return Expression(self.name + '|' + other.name, None, None) + + def __invert__(self): + assert_filter_fields(self) + return Expression('-' + self.name, self.type, None) + + # for use in Query + + def __eq__(self, value): + return Query(self, '=', value) + + def __ne__(self, value): + return Query(self, '!=', value) + + def __lt__(self, value): + return Query(self, '<', value) + + def __le__(self, value): + return Query(self, '<=', value) + + def __gt__(self, value): + return Query(self, '>', value) + + def __ge__(self, value): + return Query(self, '>=', value) + + # def like(self,value): return Query(self,' LIKE ',value) + # def belongs(self,value): return Query(self,' IN ',value) + # for use in both Query and sortby + + def __add__(self, other): + return Expression('%s+%s' % (self, other), 'float', None) + + def __sub__(self, other): + return Expression('%s-%s' % (self, other), 'float', None) + + def __mul__(self, other): + return Expression('%s*%s' % (self, other), 'float', None) + + def __div__(self, other): + return Expression('%s/%s' % (self, other), 'float', None) + + +class Field(Expression): + + """ + an instance of this class represents a database field + + example:: + + a = Field(name, 'string', length=32, required=False, + default=None, requires=IS_NOT_EMPTY(), notnull=False, + unique=False, uploadfield=True) + + to be used as argument of GQLDB.define_table + + allowed field types: + string, boolean, integer, double, text, blob, + date, time, datetime, upload, password + + strings must have a length or 512 by default. + fields should have a default or they will be required in SQLFORMs + the requires argument are used to validate the field input in SQLFORMs + + """ + + def __init__( + self, + fieldname, + type='string', + length=None, + default=None, + required=False, + requires=sqlhtml_validators, + ondelete='CASCADE', + notnull=False, + unique=False, + uploadfield=True, + ): + + self.name = cleanup(fieldname) + if fieldname in dir(Table) or fieldname[0] == '_': + raise SyntaxError('Field: invalid field name: %s' % fieldname) + if isinstance(type, Table): + type = 'reference ' + type._tablename + if not length: + length = 512 + self.type = type # 'string', 'integer' + self.length = length # the length of the string + self.default = default # default value for field + self.required = required # is this field required + self.ondelete = ondelete.upper() # this is for reference fields only + self.notnull = notnull + self.unique = unique + self.uploadfield = uploadfield + if requires == sqlhtml_validators: + requires = sqlhtml_validators(type, length) + elif requires is None: + requires = [] + self.requires = requires # list of validators + + def formatter(self, value): + if value is None or not self.requires: + return value + if not isinstance(self.requires, (list, tuple)): + requires = [self.requires] + else: + requires = copy.copy(self.requires) + requires.reverse() + for item in requires: + if hasattr(item, 'formatter'): + value = item.formatter(value) + return value + + def __str__(self): + return '%s.%s' % (self._tablename, self.name) + + +MEMDB.Field = Field # ## required by gluon/globals.py session.connect + + +def obj_represent(object, fieldtype, db): + if object is not None: + if fieldtype == 'date' and not isinstance(object, + datetime.date): + (y, m, d) = [int(x) for x in str(object).strip().split('-')] + object = datetime.date(y, m, d) + elif fieldtype == 'time' and not isinstance(object, datetime.time): + time_items = [int(x) for x in str(object).strip().split(':')[:3]] + if len(time_items) == 3: + (h, mi, s) = time_items + else: + (h, mi, s) = time_items + [0] + object = datetime.time(h, mi, s) + elif fieldtype == 'datetime' and not isinstance(object, + datetime.datetime): + (y, m, d) = [int(x) for x in + str(object)[:10].strip().split('-')] + time_items = [int(x) for x in + str(object)[11:].strip().split(':')[:3]] + if len(time_items) == 3: + (h, mi, s) = time_items + else: + (h, mi, s) = time_items + [0] + object = datetime.datetime( + y, + m, + d, + h, + mi, + s, + ) + elif fieldtype == 'integer' and not isinstance(object, long): + object = long(object) + + return object + + +class QueryException: + + def __init__(self, **a): + self.__dict__ = a + + +class Query(object): + + """ + A query object necessary to define a set. + It can be stored or can be passed to GQLDB.__call__() to obtain a Set + + Example: + query=db.users.name=='Max' + set=db(query) + records=set.select() + """ + + def __init__( + self, + left, + op=None, + right=None, + ): + if isinstance(right, (Field, Expression)): + raise SyntaxError( + 'Query: right side of filter must be a value or entity') + if isinstance(left, Field) and left.name == 'id': + if op == '=': + self.get_one = QueryException( + tablename=left._tablename, id=long(right or 0)) + return + else: + raise SyntaxError('only equality by id is supported') + raise SyntaxError('not supported') + + def __str__(self): + return str(self.left) + + +class Set(object): + + """ + As Set represents a set of records in the database, + the records are identified by the where=Query(...) object. + normally the Set is generated by GQLDB.__call__(Query(...)) + + given a set, for example + set=db(db.users.name=='Max') + you can: + set.update(db.users.name='Massimo') + set.delete() # all elements in the set + set.select(orderby=db.users.id,groupby=db.users.name,limitby=(0,10)) + and take subsets: + subset=set(db.users.id<5) + """ + + def __init__(self, db, where=None): + self._db = db + self._tables = [] + self.filters = [] + if hasattr(where, 'get_all'): + self.where = where + self._tables.insert(0, where.get_all) + elif hasattr(where, 'get_one') and isinstance(where.get_one, + QueryException): + self.where = where.get_one + else: + + # find out which tables are involved + + if isinstance(where, Query): + self.filters = where.left + self.where = where + self._tables = [field._tablename for (field, op, val) in + self.filters] + + def __call__(self, where): + if isinstance(self.where, QueryException) or isinstance(where, + QueryException): + raise SyntaxError('neither self.where nor where can be a QueryException instance') + if self.where: + return Set(self._db, self.where & where) + else: + return Set(self._db, where) + + def _get_table_or_raise(self): + tablenames = list(set(self._tables)) # unique + if len(tablenames) < 1: + raise SyntaxError('Set: no tables selected') + if len(tablenames) > 1: + raise SyntaxError('Set: no join in appengine') + return self._db[tablenames[0]]._tableobj + + def _getitem_exception(self): + (tablename, id) = (self.where.tablename, self.where.id) + fields = self._db[tablename].fields + self.colnames = ['%s.%s' % (tablename, t) for t in fields] + item = self._db[tablename].get(id) + return (item, fields, tablename, id) + + def _select_except(self): + (item, fields, tablename, id) = self._getitem_exception() + if not item: + return [] + new_item = [] + for t in fields: + if t == 'id': + new_item.append(long(id)) + else: + new_item.append(getattr(item, t)) + r = [new_item] + return Rows(self._db, r, *self.colnames) + + def select(self, *fields, **attributes): + """ + Always returns a Rows object, even if it may be empty + """ + + if isinstance(self.where, QueryException): + return self._select_except() + else: + raise SyntaxError('select arguments not supported') + + def count(self): + return len(self.select()) + + def delete(self): + if isinstance(self.where, QueryException): + (item, fields, tablename, id) = self._getitem_exception() + if not item: + return + self._db[tablename].delete(id) + else: + raise Exception('deletion not implemented') + + def update(self, **update_fields): + if isinstance(self.where, QueryException): + (item, fields, tablename, id) = self._getitem_exception() + if not item: + return + for (key, value) in update_fields.items(): + setattr(item, key, value) + self._db[tablename].update(id, **item) + else: + raise Exception('update not implemented') + + +def update_record( + t, + s, + id, + a, +): + item = s.get(id) + for (key, value) in a.items(): + t[key] = value + setattr(item, key, value) + s.update(id, **item) + + +class Rows(object): + + """ + A wrapper for the return value of a select. It basically represents a table. + It has an iterator and each row is represented as a dictionary. + """ + + # ## this class still needs some work to care for ID/OID + + def __init__( + self, + db, + response, + *colnames + ): + self._db = db + self.colnames = colnames + self.response = response + + def __len__(self): + return len(self.response) + + def __getitem__(self, i): + if i >= len(self.response) or i < 0: + raise SyntaxError('Rows: no such row: %i' % i) + if len(self.response[0]) != len(self.colnames): + raise SyntaxError('Rows: internal error') + row = DALStorage() + for j in xrange(len(self.colnames)): + value = self.response[i][j] + if isinstance(value, unicode): + value = value.encode('utf-8') + packed = self.colnames[j].split('.') + try: + (tablename, fieldname) = packed + except: + if not '_extra' in row: + row['_extra'] = DALStorage() + row['_extra'][self.colnames[j]] = value + continue + table = self._db[tablename] + field = table[fieldname] + if not tablename in row: + row[tablename] = DALStorage() + if field.type[:9] == 'reference': + referee = field.type[10:].strip() + rid = value + row[tablename][fieldname] = rid + elif field.type == 'boolean' and value is not None: + + # row[tablename][fieldname]=Set(self._db[referee].id==rid) + + if value == True or value == 'T': + row[tablename][fieldname] = True + else: + row[tablename][fieldname] = False + elif field.type == 'date' and value is not None\ + and not isinstance(value, datetime.date): + (y, m, d) = [int(x) for x in + str(value).strip().split('-')] + row[tablename][fieldname] = datetime.date(y, m, d) + elif field.type == 'time' and value is not None\ + and not isinstance(value, datetime.time): + time_items = [int(x) for x in + str(value).strip().split(':')[:3]] + if len(time_items) == 3: + (h, mi, s) = time_items + else: + (h, mi, s) = time_items + [0] + row[tablename][fieldname] = datetime.time(h, mi, s) + elif field.type == 'datetime' and value is not None\ + and not isinstance(value, datetime.datetime): + (y, m, d) = [int(x) for x in + str(value)[:10].strip().split('-')] + time_items = [int(x) for x in + str(value)[11:].strip().split(':')[:3]] + if len(time_items) == 3: + (h, mi, s) = time_items + else: + (h, mi, s) = time_items + [0] + row[tablename][fieldname] = datetime.datetime( + y, + m, + d, + h, + mi, + s, + ) + else: + row[tablename][fieldname] = value + if fieldname == 'id': + id = row[tablename].id + row[tablename].update_record = lambda t = row[tablename], \ + s = self._db[tablename], id = id, **a: update_record(t, + s, id, a) + for (referee_table, referee_name) in \ + table._referenced_by: + s = self._db[referee_table][referee_name] + row[tablename][referee_table] = Set(self._db, s + == id) + if len(row.keys()) == 1: + return row[row.keys()[0]] + return row + + def __iter__(self): + """ + iterator over records + """ + + for i in xrange(len(self)): + yield self[i] + + def __str__(self): + """ + serializes the table into a csv file + """ + + s = cStringIO.StringIO() + writer = csv.writer(s) + writer.writerow(self.colnames) + c = len(self.colnames) + for i in xrange(len(self)): + row = [self.response[i][j] for j in xrange(c)] + for k in xrange(c): + if isinstance(row[k], unicode): + row[k] = row[k].encode('utf-8') + writer.writerow(row) + return s.getvalue() + + def xml(self): + """ + serializes the table using SQLTABLE (if present) + """ + + return SQLTABLE(self).xml() + + +def test_all(): + """ + How to run from web2py dir: + export PYTHONPATH=.:YOUR_PLATFORMS_APPENGINE_PATH + python gluon/contrib/memdb.py + + Setup the UTC timezone and database stubs + + >>> import os + >>> os.environ['TZ'] = 'UTC' + >>> import time + >>> if hasattr(time, 'tzset'): + ... time.tzset() + >>> + >>> from google.appengine.api import apiproxy_stub_map + >>> from google.appengine.api.memcache import memcache_stub + >>> apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap() + >>> apiproxy_stub_map.apiproxy.RegisterStub('memcache', memcache_stub.MemcacheServiceStub()) + + Create a table with all possible field types + >>> from google.appengine.api.memcache import Client + >>> db=MEMDB(Client()) + >>> tmp=db.define_table('users', Field('stringf','string',length=32,required=True), Field('booleanf','boolean',default=False), Field('passwordf','password',notnull=True), Field('blobf','blob'), Field('uploadf','upload'), Field('integerf','integer',unique=True), Field('doublef','double',unique=True,notnull=True), Field('datef','date',default=datetime.date.today()), Field('timef','time'), Field('datetimef','datetime'), migrate='test_user.table') + + Insert a field + + >>> user_id = db.users.insert(stringf='a',booleanf=True,passwordf='p',blobf='0A', uploadf=None, integerf=5,doublef=3.14, datef=datetime.date(2001,1,1), timef=datetime.time(12,30,15), datetimef=datetime.datetime(2002,2,2,12,30,15)) + >>> user_id != None + True + + Select all + + # >>> all = db().select(db.users.ALL) + + Drop the table + + # >>> db.users.drop() + + Select many entities + + >>> tmp = db.define_table(\"posts\", Field('body','text'), Field('total','integer'), Field('created_at','datetime')) + >>> many = 20 #2010 # more than 1000 single fetch limit (it can be slow) + >>> few = 5 + >>> most = many - few + >>> 0 < few < most < many + True + >>> for i in range(many): + ... f=db.posts.insert(body='', total=i,created_at=datetime.datetime(2008, 7, 6, 14, 15, 42, i)) + >>> + + # test timezones + >>> class TZOffset(datetime.tzinfo): + ... def __init__(self,offset=0): + ... self.offset = offset + ... def utcoffset(self, dt): return datetime.timedelta(hours=self.offset) + ... def dst(self, dt): return datetime.timedelta(0) + ... def tzname(self, dt): return 'UTC' + str(self.offset) + ... + >>> SERVER_OFFSET = -8 + >>> + >>> stamp = datetime.datetime(2008, 7, 6, 14, 15, 42, 828201) + >>> post_id = db.posts.insert(created_at=stamp,body='body1') + >>> naive_stamp = db(db.posts.id==post_id).select()[0].created_at + >>> utc_stamp=naive_stamp.replace(tzinfo=TZOffset()) + >>> server_stamp = utc_stamp.astimezone(TZOffset(SERVER_OFFSET)) + >>> stamp == naive_stamp + True + >>> utc_stamp == server_stamp + True + >>> rows = db(db.posts.id==post_id).select() + >>> len(rows) == 1 + True + >>> rows[0].body == 'body1' + True + >>> db(db.posts.id==post_id).delete() + >>> rows = db(db.posts.id==post_id).select() + >>> len(rows) == 0 + True + + >>> id = db.posts.insert(total='0') # coerce str to integer + >>> rows = db(db.posts.id==id).select() + >>> len(rows) == 1 + True + >>> rows[0].total == 0 + True + + Examples of insert, select, update, delete + + >>> tmp=db.define_table('person', Field('name'), Field('birth','date'), migrate='test_person.table') + >>> marco_id=db.person.insert(name=\"Marco\",birth='2005-06-22') + >>> person_id=db.person.insert(name=\"Massimo\",birth='1971-12-21') + >>> me=db(db.person.id==person_id).select()[0] # test select + >>> me.name + 'Massimo' + >>> db(db.person.id==person_id).update(name='massimo') # test update + >>> me = db(db.person.id==person_id).select()[0] + >>> me.name + 'massimo' + >>> str(me.birth) + '1971-12-21' + + # resave date to ensure it comes back the same + >>> me=db(db.person.id==person_id).update(birth=me.birth) # test update + >>> me = db(db.person.id==person_id).select()[0] + >>> me.birth + datetime.date(1971, 12, 21) + >>> db(db.person.id==marco_id).delete() # test delete + >>> len(db(db.person.id==marco_id).select()) + 0 + + Update a single record + + >>> me.update_record(name=\"Max\") + >>> me.name + 'Max' + >>> me = db(db.person.id == person_id).select()[0] + >>> me.name + 'Max' + + """ + +SQLField = Field +SQLTable = Table +SQLXorable = Expression +SQLQuery = Query +SQLSet = Set +SQLRows = Rows +SQLStorage = DALStorage + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/web2py/gluon/contrib/minify/__init__.py b/web2py/gluon/contrib/minify/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web2py/gluon/contrib/minify/cssmin.py b/web2py/gluon/contrib/minify/cssmin.py new file mode 100644 index 0000000..15d97a0 --- /dev/null +++ b/web2py/gluon/contrib/minify/cssmin.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""`cssmin` - A Python port of the YUI CSS compressor.""" + +""" +Home page: https://github.com/zacharyvoase/cssmin +License: BSD: https://github.com/zacharyvoase/cssmin/blob/master/LICENSE +Original author: Zachary Voase +Modified for inclusion into web2py by: Ross Peoples +""" + +try: + from StringIO import StringIO +except ImportError: + from io import StringIO + +import re + + +__version__ = '0.1.4' + + +def remove_comments(css): + """Remove all CSS comment blocks.""" + + iemac = False + preserve = False + comment_start = css.find("/*") + while comment_start >= 0: + # Preserve comments that look like `/*!...*/`. + # Slicing is used to make sure we don"t get an IndexError. + preserve = css[comment_start + 2:comment_start + 3] == "!" + + comment_end = css.find("*/", comment_start + 2) + if comment_end < 0: + if not preserve: + css = css[:comment_start] + break + elif comment_end >= (comment_start + 2): + if css[comment_end - 1] == "\\": + # This is an IE Mac-specific comment; leave this one and the + # following one alone. + comment_start = comment_end + 2 + iemac = True + elif iemac: + comment_start = comment_end + 2 + iemac = False + elif not preserve: + css = css[:comment_start] + css[comment_end + 2:] + else: + comment_start = comment_end + 2 + comment_start = css.find("/*", comment_start) + + return css + + +def remove_unnecessary_whitespace(css): + """Remove unnecessary whitespace characters.""" + + def pseudoclasscolon(css): + + """ + Prevents 'p :link' from becoming 'p:link'. + + Translates 'p :link' into 'p ___PSEUDOCLASSCOLON___link'; this is + translated back again later. + """ + + regex = re.compile(r"(^|\})(([^\{\:])+\:)+([^\{]*\{)") + match = regex.search(css) + while match: + css = ''.join([ + css[:match.start()], + match.group().replace(":", "___PSEUDOCLASSCOLON___"), + css[match.end():]]) + match = regex.search(css) + return css + + css = pseudoclasscolon(css) + # Remove spaces from before things. + css = re.sub(r"\s+([!{};:>+\(\)\],])", r"\1", css) + + # If there is a `@charset`, then only allow one, and move to the beginning. + css = re.sub(r"^(.*)(@charset \"[^\"]*\";)", r"\2\1", css) + css = re.sub(r"^(\s*@charset [^;]+;\s*)+", r"\1", css) + + # Put the space back in for a few cases, such as `@media screen` and + # `(-webkit-min-device-pixel-ratio:0)`. + css = re.sub(r"\band\(", "and (", css) + + # Put the colons back. + css = css.replace('___PSEUDOCLASSCOLON___', ':') + + # Remove spaces from after things. + css = re.sub(r"([!{}:;>+\(\[,])\s+", r"\1", css) + + return css + + +def remove_unnecessary_semicolons(css): + """Remove unnecessary semicolons.""" + + return re.sub(r";+\}", "}", css) + + +def remove_empty_rules(css): + """Remove empty rules.""" + + return re.sub(r"[^\}\{]+\{\}", "", css) + + +def normalize_rgb_colors_to_hex(css): + """Convert `rgb(51,102,153)` to `#336699`.""" + + regex = re.compile(r"rgb\s*\(\s*([0-9,\s]+)\s*\)") + match = regex.search(css) + while match: + colors = map(lambda s: s.strip(), match.group(1).split(",")) + hexcolor = '#%.2x%.2x%.2x' % tuple(map(int, colors)) + css = css.replace(match.group(), hexcolor) + match = regex.search(css) + return css + + +def condense_zero_units(css): + """Replace `0(px, em, %, etc)` with `0`.""" + + return re.sub(r"([\s:])(0)(px|em|%|in|cm|mm|pc|pt|ex)", r"\1\2", css) + + +def condense_multidimensional_zeros(css): + """Replace `:0 0 0 0;`, `:0 0 0;` etc. with `:0;`.""" + + css = css.replace(":0 0 0 0;", ":0;") + css = css.replace(":0 0 0;", ":0;") + css = css.replace(":0 0;", ":0;") + + # Revert `background-position:0;` to the valid `background-position:0 0;`. + css = css.replace("background-position:0;", "background-position:0 0;") + + return css + + +def condense_floating_points(css): + """Replace `0.6` with `.6` where possible.""" + + return re.sub(r"(:|\s)0+\.(\d+)", r"\1.\2", css) + + +def condense_hex_colors(css): + """Shorten colors from #AABBCC to #ABC where possible.""" + + regex = re.compile(r"([^\"'=\s])(\s*)#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])") + match = regex.search(css) + while match: + first = match.group(3) + match.group(5) + match.group(7) + second = match.group(4) + match.group(6) + match.group(8) + if first.lower() == second.lower(): + css = css.replace( + match.group(), match.group(1) + match.group(2) + '#' + first) + match = regex.search(css, match.end() - 3) + else: + match = regex.search(css, match.end()) + return css + + +def condense_whitespace(css): + """Condense multiple adjacent whitespace characters into one.""" + + return re.sub(r"\s+", " ", css) + + +def condense_semicolons(css): + """Condense multiple adjacent semicolon characters into one.""" + + return re.sub(r";;+", ";", css) + + +def wrap_css_lines(css, line_length): + """Wrap the lines of the given CSS to an approximate length.""" + + lines = [] + line_start = 0 + for i, char in enumerate(css): + # It's safe to break after `}` characters. + if char == '}' and (i - line_start >= line_length): + lines.append(css[line_start:i + 1]) + line_start = i + 1 + + if line_start < len(css): + lines.append(css[line_start:]) + return '\n'.join(lines) + + +def cssmin(css, wrap=None): + css = remove_comments(css) + css = condense_whitespace(css) + # A pseudo class for the Box Model Hack + # (see http://tantek.com/CSS/Examples/boxmodelhack.html) + css = css.replace('"\\"}\\""', "___PSEUDOCLASSBMH___") + css = remove_unnecessary_whitespace(css) + css = remove_unnecessary_semicolons(css) + css = condense_zero_units(css) + css = condense_multidimensional_zeros(css) + css = condense_floating_points(css) + css = normalize_rgb_colors_to_hex(css) + css = condense_hex_colors(css) + if wrap is not None: + css = wrap_css_lines(css, wrap) + css = css.replace("___PSEUDOCLASSBMH___", '"\\"}\\""') + css = condense_semicolons(css) + return css.strip() + + +def main(): + import optparse + import sys + + p = optparse.OptionParser( + prog="cssmin", version=__version__, + usage="%prog [--wrap N]", + description="""Reads raw CSS from stdin, and writes compressed CSS to stdout.""") + + p.add_option( + '-w', '--wrap', type='int', default=None, metavar='N', + help="Wrap output to approximately N chars per line.") + + options, args = p.parse_args() + sys.stdout.write(cssmin(sys.stdin.read(), wrap=options.wrap)) + + +if __name__ == '__main__': + main() diff --git a/web2py/gluon/contrib/minify/htmlmin.py b/web2py/gluon/contrib/minify/htmlmin.py new file mode 100644 index 0000000..ea4971e --- /dev/null +++ b/web2py/gluon/contrib/minify/htmlmin.py @@ -0,0 +1,15 @@ +# coding: utf-8 + +import re + + +def minify(response): + def _replace(match): + match = match.group() + # save whole

    , |')
    +            if self.documentOrder == _LesserElement: W('\n')
    +    handlers[Node.COMMENT_NODE] = _do_comment
    +
    +
    +    def _do_attr(self, n, value):
    +        ''''_do_attr(self, node) -> None
    +        Process an attribute.'''
    +
    +        W = self.write
    +        W(' ')
    +        W(n)
    +        W('="')
    +        s = string.replace(value, "&", "&")
    +        s = string.replace(s, "<", "<")
    +        s = string.replace(s, '"', '"')
    +        s = string.replace(s, '\011', '	')
    +        s = string.replace(s, '\012', '
    ')
    +        s = string.replace(s, '\015', '
')
    +        W(s)
    +        W('"')
    +
    +
    +    def _do_element(self, node, initial_other_attrs = [], unused = None):
    +        '''_do_element(self, node, initial_other_attrs = [], unused = {}) -> None
    +        Process an element (and its children).'''
    +
    +        # Get state (from the stack) make local copies.
    +        #   ns_parent -- NS declarations in parent
    +        #   ns_rendered -- NS nodes rendered by ancestors
    +        #        ns_local -- NS declarations relevant to this element
    +        #   xml_attrs -- Attributes in XML namespace from parent
    +        #       xml_attrs_local -- Local attributes in XML namespace.
    +        #   ns_unused_inherited -- not rendered namespaces, used for exclusive 
    +        ns_parent, ns_rendered, xml_attrs = \
    +                self.state[0], self.state[1].copy(), self.state[2].copy() #0422
    +                
    +        ns_unused_inherited = unused
    +        if unused is None:
    +            ns_unused_inherited = self.state[3].copy()
    +            
    +        ns_local = ns_parent.copy()
    +        inclusive = _inclusive(self)
    +        xml_attrs_local = {}
    +
    +        # Divide attributes into NS, XML, and others.
    +        other_attrs = []
    +        in_subset = _in_subset(self.subset, node)
    +        for a in initial_other_attrs + _attrs(node):
    +            if a.namespaceURI == XMLNS.BASE:
    +                n = a.nodeName
    +                if n == "xmlns:": n = "xmlns"        # DOM bug workaround
    +                ns_local[n] = a.nodeValue
    +            elif a.namespaceURI == XMLNS.XML:
    +                if inclusive or (in_subset and  _in_subset(self.subset, a)): #020925 Test to see if attribute node in subset
    +                    xml_attrs_local[a.nodeName] = a #0426
    +            else:
    +                if  _in_subset(self.subset, a):     #020925 Test to see if attribute node in subset
    +                    other_attrs.append(a)
    +                    
    +#                # TODO: exclusive, might need to define xmlns:prefix here
    +#                if not inclusive and a.prefix is not None and not ns_rendered.has_key('xmlns:%s' %a.prefix):
    +#                    ns_local['xmlns:%s' %a.prefix] = ??
    +
    +            #add local xml:foo attributes to ancestor's xml:foo attributes
    +            xml_attrs.update(xml_attrs_local)
    +
    +        # Render the node
    +        W, name = self.write, None
    +        if in_subset: 
    +            name = node.nodeName
    +            if not inclusive:
    +                if node.prefix is not None:
    +                    prefix = 'xmlns:%s' %node.prefix
    +                else:
    +                    prefix = 'xmlns'
    +                    
    +                if not ns_rendered.has_key(prefix) and not ns_local.has_key(prefix):
    +                    if not ns_unused_inherited.has_key(prefix):
    +                        raise RuntimeError(\
    +                            'For exclusive c14n, unable to map prefix "%s" in %s' %(
    +                            prefix, node))
    +                    
    +                    ns_local[prefix] = ns_unused_inherited[prefix]
    +                    del ns_unused_inherited[prefix]
    +                
    +            W('<')
    +            W(name)
    +
    +            # Create list of NS attributes to render.
    +            ns_to_render = []
    +            for n,v in ns_local.items():
    +
    +                # If default namespace is XMLNS.BASE or empty,
    +                # and if an ancestor was the same
    +                if n == "xmlns" and v in [ XMLNS.BASE, '' ] \
    +                and ns_rendered.get('xmlns') in [ XMLNS.BASE, '', None ]:
    +                    continue
    +
    +                # "omit namespace node with local name xml, which defines
    +                # the xml prefix, if its string value is
    +                # http://www.w3.org/XML/1998/namespace."
    +                if n in ["xmlns:xml", "xml"] \
    +                and v in [ 'http://www.w3.org/XML/1998/namespace' ]:
    +                    continue
    +
    +
    +                # If not previously rendered
    +                # and it's inclusive  or utilized
    +                if (n,v) not in ns_rendered.items():
    +                    if inclusive or _utilized(n, node, other_attrs, self.unsuppressedPrefixes):
    +                        ns_to_render.append((n, v))
    +                    elif not inclusive:
    +                        ns_unused_inherited[n] = v
    +
    +            # Sort and render the ns, marking what was rendered.
    +            ns_to_render.sort(_sorter_ns)
    +            for n,v in ns_to_render:
    +                self._do_attr(n, v)
    +                ns_rendered[n]=v    #0417
    +
    +            # If exclusive or the parent is in the subset, add the local xml attributes
    +            # Else, add all local and ancestor xml attributes
    +            # Sort and render the attributes.
    +            if not inclusive or _in_subset(self.subset,node.parentNode):  #0426
    +                other_attrs.extend(xml_attrs_local.values())
    +            else:
    +                other_attrs.extend(xml_attrs.values())
    +            other_attrs.sort(_sorter)
    +            for a in other_attrs:
    +                self._do_attr(a.nodeName, a.value)
    +            W('>')
    +
    +        # Push state, recurse, pop state.
    +        state, self.state = self.state, (ns_local, ns_rendered, xml_attrs, ns_unused_inherited)
    +        for c in _children(node):
    +            _implementation.handlers[c.nodeType](self, c)
    +        self.state = state
    +
    +        if name: W('' % name)
    +    handlers[Node.ELEMENT_NODE] = _do_element
    +
    +
    +def Canonicalize(node, output=None, **kw):
    +    '''Canonicalize(node, output=None, **kw) -> UTF-8
    +
    +    Canonicalize a DOM document/element node and all descendents.
    +    Return the text; if output is specified then output.write will
    +    be called to output the text and None will be returned
    +    Keyword parameters:
    +        nsdict: a dictionary of prefix:uri namespace entries
    +                assumed to exist in the surrounding context
    +        comments: keep comments if non-zero (default is 0)
    +        subset: Canonical XML subsetting resulting from XPath
    +                (default is [])
    +        unsuppressedPrefixes: do exclusive C14N, and this specifies the
    +                prefixes that should be inherited.
    +    '''
    +    if output:
    +        apply(_implementation, (node, output.write), kw)
    +    else:
    +        s = StringIO.StringIO()
    +        apply(_implementation, (node, s.write), kw)
    +        return s.getvalue()
    diff --git a/web2py/gluon/contrib/pysimplesoap/client.py b/web2py/gluon/contrib/pysimplesoap/client.py
    new file mode 100644
    index 0000000..48eefad
    --- /dev/null
    +++ b/web2py/gluon/contrib/pysimplesoap/client.py
    @@ -0,0 +1,962 @@
    +#!/usr/bin/python
    +# -*- coding: utf-8 -*-
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU Lesser General Public License as published by the
    +# Free Software Foundation; either version 3, or (at your option) any later
    +# version.
    +#
    +# This program is distributed in the hope that it will be useful, but
    +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    +# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    +# for more details.
    +
    +"""Pythonic simple SOAP Client implementation"""
    +
    +from __future__ import unicode_literals
    +import sys
    +if sys.version > '3':
    +    unicode = str
    +
    +try:
    +    import cPickle as pickle
    +except ImportError:
    +    import pickle
    +import copy
    +import hashlib
    +import logging
    +import os
    +import tempfile
    +import warnings
    +
    +from . import __author__, __copyright__, __license__, __version__, TIMEOUT
    +from .simplexml import SimpleXMLElement, TYPE_MAP, REVERSE_TYPE_MAP, Struct
    +from .transport import get_http_wrapper, set_http_wrapper, get_Http
    +# Utility functions used throughout wsdl_parse, moved aside for readability
    +from .helpers import Alias, fetch, sort_dict, make_key, process_element, \
    +                     postprocess_element, get_message, preprocess_schema, \
    +                     get_local_name, get_namespace_prefix, TYPE_MAP, urlsplit
    +from .wsse import UsernameToken
    +
    +log = logging.getLogger(__name__)
    +
    +class SoapFault(RuntimeError):
    +    def __init__(self, faultcode, faultstring, detail=None):
    +        self.faultcode = faultcode
    +        self.faultstring = faultstring
    +        self.detail = detail
    +        RuntimeError.__init__(self, faultcode, faultstring, detail)
    +
    +    def __unicode__(self):
    +        return '%s: %s' % (self.faultcode, self.faultstring)
    +
    +    if sys.version > '3':
    +        __str__ = __unicode__
    +    else:
    +        def __str__(self):
    +            return self.__unicode__().encode('ascii', 'ignore')
    +
    +    def __repr__(self):
    +        return "SoapFault(faultcode = %s, faultstring %s, detail = %s)" % (repr(self.faultcode),
    +                                                                           repr(self.faultstring),
    +                                                                           repr(self.detail))
    +
    +
    +# soap protocol specification & namespace
    +soap_namespaces = dict(
    +    soap11='http://schemas.xmlsoap.org/soap/envelope/',
    +    soap='http://schemas.xmlsoap.org/soap/envelope/',
    +    soapenv='http://schemas.xmlsoap.org/soap/envelope/',
    +    soap12='http://www.w3.org/2003/05/soap-env',
    +    soap12env="http://www.w3.org/2003/05/soap-envelope",
    +)
    +
    +
    +class SoapClient(object):
    +    """Simple SOAP Client (simil PHP)"""
    +    def __init__(self, location=None, action=None, namespace=None,
    +                 cert=None, exceptions=True, proxy=None, ns=None,
    +                 soap_ns=None, wsdl=None, wsdl_basedir='', cache=False, cacert=None,
    +                 sessions=False, soap_server=None, timeout=TIMEOUT,
    +                 http_headers=None, trace=False,
    +                 username=None, password=None,
    +                 key_file=None, plugins=None, strict=True,
    +                 ):
    +        """
    +        :param http_headers: Additional HTTP Headers; example: {'Host': 'ipsec.example.com'}
    +        """
    +        self.certssl = cert
    +        self.keyssl = key_file
    +        self.location = location        # server location (url)
    +        self.action = action            # SOAP base action
    +        self.namespace = namespace      # message
    +        self.exceptions = exceptions    # lanzar execpiones? (Soap Faults)
    +        self.xml_request = self.xml_response = ''
    +        self.http_headers = http_headers or {}
    +        self.plugins = plugins or []
    +        self.strict = strict
    +        # extract the base directory / url for wsdl relative imports:
    +        if wsdl and wsdl_basedir == '':
    +            # parse the wsdl url, strip the scheme and filename
    +            url_scheme, netloc, path, query, fragment = urlsplit(wsdl)
    +            wsdl_basedir = os.path.dirname(netloc + path)
    +
    +        self.wsdl_basedir = wsdl_basedir
    +
    +        # shortcut to print all debugging info and sent / received xml messages
    +        if trace:
    +            if trace is True:
    +                level = logging.DEBUG           # default logging level
    +            else:
    +                level = trace                   # use the provided level
    +            logging.basicConfig(level=level)
    +            log.setLevel(level)
    +
    +        if not soap_ns and not ns:
    +            self.__soap_ns = 'soap'  # 1.1
    +        elif not soap_ns and ns:
    +            self.__soap_ns = 'soapenv'  # 1.2
    +        else:
    +            self.__soap_ns = soap_ns
    +
    +        # SOAP Server (special cases like oracle, jbossas6 or jetty)
    +        self.__soap_server = soap_server
    +
    +        # SOAP Header support
    +        self.__headers = {}         # general headers
    +        self.__call_headers = None  # Struct to be marshalled for RPC Call
    +
    +        # check if the Certification Authority Cert is a string and store it
    +        if cacert and cacert.startswith('-----BEGIN CERTIFICATE-----'):
    +            fd, filename = tempfile.mkstemp()
    +            f = os.fdopen(fd, 'w+b', -1)
    +            log.debug("Saving CA certificate to %s" % filename)
    +            f.write(cacert)
    +            cacert = filename
    +            f.close()
    +        self.cacert = cacert
    +
    +        # Create HTTP wrapper
    +        Http = get_Http()
    +        self.http = Http(timeout=timeout, cacert=cacert, proxy=proxy, sessions=sessions)
    +        if username and password:
    +            if hasattr(self.http, 'add_credentials'):
    +                self.http.add_credentials(username, password)
    +        if cert and key_file:
    +            if hasattr(self.http, 'add_certificate'):
    +                self.http.add_certificate(key=key_file, cert=cert, domain='')
    +
    +
    +        # namespace prefix, None to use xmlns attribute or False to not use it:
    +        self.__ns = ns
    +        if not ns:
    +            self.__xml = """
    +<%(soap_ns)s:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    +    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    +    xmlns:%(soap_ns)s="%(soap_uri)s">
    +<%(soap_ns)s:Header/>
    +<%(soap_ns)s:Body>
    +    <%(method)s xmlns="%(namespace)s">
    +    
    +
    +"""
    +        else:
    +            self.__xml = """
    +<%(soap_ns)s:Envelope xmlns:%(soap_ns)s="%(soap_uri)s" xmlns:%(ns)s="%(namespace)s">
    +<%(soap_ns)s:Header/>
    +<%(soap_ns)s:Body><%(ns)s:%(method)s>"""
    +
    +        # parse wsdl url
    +        self.services = wsdl and self.wsdl_parse(wsdl, cache=cache)
    +        self.service_port = None                 # service port for late binding
    +
    +    def __getattr__(self, attr):
    +        """Return a pseudo-method that can be called"""
    +        if not self.services:  # not using WSDL?
    +            return lambda *args, **kwargs: self.call(attr, *args, **kwargs)
    +        else:  # using WSDL:
    +            return lambda *args, **kwargs: self.wsdl_call(attr, *args, **kwargs)
    +
    +    def call(self, method, *args, **kwargs):
    +        """Prepare xml request and make SOAP call, returning a SimpleXMLElement.
    +
    +        If a keyword argument called "headers" is passed with a value of a
    +        SimpleXMLElement object, then these headers will be inserted into the
    +        request.
    +        """
    +        #TODO: method != input_message
    +        # Basic SOAP request:
    +        soap_uri = soap_namespaces[self.__soap_ns]
    +        xml = self.__xml % dict(method=method,              # method tag name
    +                                namespace=self.namespace,   # method ns uri
    +                                ns=self.__ns,               # method ns prefix
    +                                soap_ns=self.__soap_ns,     # soap prefix & uri
    +                                soap_uri=soap_uri)
    +        request = SimpleXMLElement(xml, namespace=self.__ns and self.namespace,
    +                                        prefix=self.__ns)
    +
    +        request_headers = kwargs.pop('headers', None)
    +
    +        # serialize parameters
    +        if kwargs:
    +            parameters = list(kwargs.items())
    +        else:
    +            parameters = args
    +        if parameters and isinstance(parameters[0], SimpleXMLElement):
    +            body = request('Body', ns=list(soap_namespaces.values()),)
    +            # remove default body parameter (method name)
    +            delattr(body, method)
    +            # merge xmlelement parameter ("raw" - already marshalled)
    +            body.import_node(parameters[0])
    +        elif parameters:
    +            # marshall parameters:
    +            use_ns = None if (self.__soap_server == "jetty" or self.qualified is False) else True
    +            for k, v in parameters:  # dict: tag=valor
    +                if hasattr(v, "namespaces") and use_ns:
    +                    ns = v.namespaces.get(None, True)
    +                else:
    +                    ns = use_ns
    +                getattr(request, method).marshall(k, v, ns=ns)
    +        elif self.__soap_server in ('jbossas6',):
    +            # JBossAS-6 requires no empty method parameters!
    +            delattr(request("Body", ns=list(soap_namespaces.values()),), method)
    +
    +        # construct header and parameters (if not wsdl given) except wsse
    +        if self.__headers and not self.services:
    +            self.__call_headers = dict([(k, v) for k, v in self.__headers.items()
    +                                        if not k.startswith('wsse:')])
    +        # always extract WS Security header and send it (backward compatible)
    +        if 'wsse:Security' in self.__headers and not self.plugins:
    +            warnings.warn("Replace wsse:Security with UsernameToken plugin",
    +                          DeprecationWarning)
    +            self.plugins.append(UsernameToken())
    +
    +        if self.__call_headers:
    +            header = request('Header', ns=list(soap_namespaces.values()),)
    +            for k, v in self.__call_headers.items():
    +                ##if not self.__ns:
    +                ##    header['xmlns']
    +                if isinstance(v, SimpleXMLElement):
    +                    # allows a SimpleXMLElement to be constructed and inserted
    +                    # rather than a dictionary. marshall doesn't allow ns: prefixes
    +                    # in dict key names
    +                    header.import_node(v)
    +                else:
    +                    header.marshall(k, v, ns=self.__ns, add_children_ns=False)
    +        if request_headers:
    +            header = request('Header', ns=list(soap_namespaces.values()),)
    +            for subheader in request_headers.children():
    +                header.import_node(subheader)
    +
    +        # do pre-processing using plugins (i.e. WSSE signing)
    +        for plugin in self.plugins:
    +            plugin.preprocess(self, request, method, args, kwargs,
    +                                    self.__headers, soap_uri)
    +
    +        self.xml_request = request.as_xml()
    +        self.xml_response = self.send(method, self.xml_request)
    +        response = SimpleXMLElement(self.xml_response, namespace=self.namespace,
    +                                    jetty=self.__soap_server in ('jetty',))
    +        if self.exceptions and response("Fault", ns=list(soap_namespaces.values()), error=False):
    +            detailXml = response("detail", ns=list(soap_namespaces.values()), error=False)
    +            detail = None
    +
    +            if detailXml and detailXml.children():
    +                if self.services is not None:
    +                    operation = self.get_operation(method)
    +                    fault_name = detailXml.children()[0].get_name()
    +                    # if fault not defined in WSDL, it could be an axis or other 
    +                    # standard type (i.e. "hostname"), try to convert it to string 
    +                    fault = operation['faults'].get(fault_name) or unicode
    +                    detail = detailXml.children()[0].unmarshall(fault, strict=False)
    +                else:
    +                    detail = repr(detailXml.children())
    +
    +            raise SoapFault(unicode(response.faultcode),
    +                            unicode(response.faultstring),
    +                            detail)
    +
    +        # do post-processing using plugins (i.e. WSSE signature verification)
    +        for plugin in self.plugins:
    +            plugin.postprocess(self, response, method, args, kwargs,
    +                                     self.__headers, soap_uri)
    +
    +        return response
    +
    +    def send(self, method, xml):
    +        """Send SOAP request using HTTP"""
    +        if self.location == 'test': return
    +        # location = '%s' % self.location #?op=%s" % (self.location, method)
    +        http_method = str('POST')
    +        location = str(self.location)
    +
    +        if self.services:
    +            soap_action = str(self.action)
    +        else:
    +            soap_action = str(self.action) + method
    +
    +        headers = {
    +            'Content-type': 'text/xml; charset="UTF-8"',
    +            'Content-length': str(len(xml)),
    +        }
    +
    +        if self.action is not None:
    +            headers['SOAPAction'] = '"' + soap_action + '"'
    +
    +        headers.update(self.http_headers)
    +        log.info("POST %s" % location)
    +        log.debug('\n'.join(["%s: %s" % (k, v) for k, v in headers.items()]))
    +        log.debug(xml)
    +
    +        if sys.version < '3':
    +            # Ensure http_method, location and all headers are binary to prevent
    +            # UnicodeError inside httplib.HTTPConnection._send_output.
    +
    +            # httplib in python3 do the same inside itself, don't need to convert it here
    +            headers = dict((str(k), str(v)) for k, v in headers.items())
    +
    +        response, content = self.http.request(
    +            location, http_method, body=xml, headers=headers)
    +        self.response = response
    +        self.content = content
    +
    +        log.debug('\n'.join(["%s: %s" % (k, v) for k, v in response.items()]))
    +        log.debug(content)
    +        return content
    +
    +    def get_operation(self, method):
    +        # try to find operation in wsdl file
    +        soap_ver = self.__soap_ns.startswith('soap12') and 'soap12' or 'soap11'
    +        if not self.service_port:
    +            for service_name, service in self.services.items():
    +                for port_name, port in [port for port in service['ports'].items()]:
    +                    if port['soap_ver'] == soap_ver:
    +                        self.service_port = service_name, port_name
    +                        break
    +                else:
    +                    raise RuntimeError('Cannot determine service in WSDL: '
    +                                       'SOAP version: %s' % soap_ver)
    +        else:
    +            port = self.services[self.service_port[0]]['ports'][self.service_port[1]]
    +        if not self.location:
    +            self.location = port['location']
    +        operation = port['operations'].get(method)
    +        if not operation:
    +            raise RuntimeError('Operation %s not found in WSDL: '
    +                               'Service/Port Type: %s' %
    +                               (method, self.service_port))
    +        return operation
    +
    +    def wsdl_call(self, method, *args, **kwargs):
    +        """Pre and post process SOAP call, input and output parameters using WSDL"""
    +        return self.wsdl_call_with_args(method, args, kwargs)
    +
    +    def wsdl_call_with_args(self, method, args, kwargs):
    +        """Pre and post process SOAP call, input and output parameters using WSDL"""
    +        soap_uri = soap_namespaces[self.__soap_ns]
    +        operation = self.get_operation(method)
    +
    +        # get i/o type declarations:
    +        input = operation['input']
    +        output = operation['output']
    +        header = operation.get('header')
    +        if 'action' in operation:
    +            self.action = operation['action']
    +
    +        if 'namespace' in operation:
    +            self.namespace = operation['namespace'] or ''
    +            self.qualified = operation['qualified']
    +
    +        # construct header and parameters
    +        if header:
    +            self.__call_headers = sort_dict(header, self.__headers)
    +        method, params = self.wsdl_call_get_params(method, input, args, kwargs)
    +
    +        # call remote procedure
    +        response = self.call(method, *params)
    +        # parse results:
    +        resp = response('Body', ns=soap_uri).children().unmarshall(output, strict=self.strict)
    +        return resp and list(resp.values())[0]  # pass Response tag children
    +
    +    def wsdl_call_get_params(self, method, input, args, kwargs):
    +        """Build params from input and args/kwargs"""
    +        params = inputname = inputargs = None
    +        all_args = {}
    +        if input:
    +            inputname = list(input.keys())[0]
    +            inputargs = input[inputname]
    +
    +        if input and args:
    +            # convert positional parameters to named parameters:
    +            d = {}
    +            for idx, arg in enumerate(args):
    +                key = list(inputargs.keys())[idx]
    +                if isinstance(arg, dict):
    +                    if key not in arg:
    +                        raise KeyError('Unhandled key %s. use client.help(method)' % key)
    +                    d[key] = arg[key]
    +                else:
    +                    d[key] = arg
    +            all_args.update({inputname: d})
    +
    +        if input and (kwargs or all_args):
    +            if kwargs:
    +                all_args.update({inputname: kwargs})
    +            valid, errors, warnings = self.wsdl_validate_params(input, all_args)
    +            if not valid:
    +                raise ValueError('Invalid Args Structure. Errors: %s' % errors)
    +            # sort and filter parameters according to wsdl input structure
    +            tree = sort_dict(input, all_args)
    +            root = list(tree.values())[0]
    +            params = []
    +            # make a params tuple list suitable for self.call(method, *params)
    +            for k, v in root.items():
    +                # fix referenced namespaces as info is lost when calling call
    +                root_ns = root.namespaces[k]
    +                if not root.references[k] and isinstance(v, Struct):
    +                    v.namespaces[None] = root_ns
    +                params.append((k, v))
    +            # TODO: check style and document attributes
    +            if self.__soap_server in ('axis', ):
    +                # use the operation name
    +                method = method
    +            else:
    +                # use the message (element) name
    +                method = inputname
    +        #elif not input:
    +            #TODO: no message! (see wsmtxca.dummy)
    +        else:
    +            params = kwargs and kwargs.items()
    +
    +        return (method, params)
    +
    +    def wsdl_validate_params(self, struct, value):
    +        """Validate the arguments (actual values) for the parameters structure.
    +           Fail for any invalid arguments or type mismatches."""
    +        errors = []
    +        warnings = []
    +        valid = True
    +
    +        # Determine parameter type
    +        if type(struct) == type(value):
    +            typematch = True
    +        if not isinstance(struct, dict) and isinstance(value, dict):
    +            typematch = True    # struct can be a dict or derived (Struct)
    +        else:
    +            typematch = False
    +
    +        if struct == str:
    +            struct = unicode        # fix for py2 vs py3 string handling
    +
    +        if not isinstance(struct, (list, dict, tuple)) and struct in TYPE_MAP.keys():
    +            if not type(value) == struct  and value is not None:
    +                try:
    +                    struct(value)       # attempt to cast input to parameter type
    +                except:
    +                    valid = False
    +                    errors.append('Type mismatch for argument value. parameter(%s): %s, value(%s): %s' % (type(struct), struct, type(value), value))
    +
    +        elif isinstance(struct, list) and len(struct) == 1 and not isinstance(value, list):
    +            # parameter can have a dict in a list: [{}] indicating a list is allowed, but not needed if only one argument.
    +            next_valid, next_errors, next_warnings = self.wsdl_validate_params(struct[0], value)
    +            if not next_valid:
    +                valid = False
    +            errors.extend(next_errors)
    +            warnings.extend(next_warnings)
    +
    +        # traverse tree
    +        elif isinstance(struct, dict):
    +            if struct and value:
    +                for key in value:
    +                    if key not in struct:
    +                        valid = False
    +                        errors.append('Argument key %s not in parameter. parameter: %s, args: %s' % (key, struct, value))
    +                    else:
    +                        next_valid, next_errors, next_warnings = self.wsdl_validate_params(struct[key], value[key])
    +                        if not next_valid:
    +                            valid = False
    +                        errors.extend(next_errors)
    +                        warnings.extend(next_warnings)
    +                for key in struct:
    +                    if key not in value:
    +                        warnings.append('Parameter key %s not in args. parameter: %s, value: %s' % (key, struct, value))
    +            elif struct and not value:
    +                warnings.append('parameter keys not in args. parameter: %s, args: %s' % (struct, value))
    +            elif not struct and value:
    +                valid = False
    +                errors.append('Args keys not in parameter. parameter: %s, args: %s' % (struct, value))
    +            else:
    +                pass
    +        elif isinstance(struct, list):
    +            struct_list_value = struct[0]
    +            for item in value:
    +                next_valid, next_errors, next_warnings = self.wsdl_validate_params(struct_list_value, item)
    +                if not next_valid:
    +                    valid = False
    +                errors.extend(next_errors)
    +                warnings.extend(next_warnings)
    +        elif not typematch:
    +            valid = False
    +            errors.append('Type mismatch. parameter(%s): %s, value(%s): %s' % (type(struct), struct, type(value), value))
    +
    +        return (valid, errors, warnings)
    +
    +    def help(self, method):
    +        """Return operation documentation and invocation/returned value example"""
    +        operation = self.get_operation(method)
    +        input = operation.get('input')
    +        input = input and input.values() and list(input.values())[0]
    +        if isinstance(input, dict):
    +            input = ", ".join("%s=%s" % (k, repr(v)) for k, v in input.items())
    +        elif isinstance(input, list):
    +            input = repr(input)
    +        output = operation.get('output')
    +        if output:
    +            output = list(operation['output'].values())[0]
    +        headers = operation.get('headers') or None
    +        return "%s(%s)\n -> %s:\n\n%s\nHeaders: %s" % (
    +            method,
    +            input or '',
    +            output and output or '',
    +            operation.get('documentation', ''),
    +            headers,
    +        )
    +
    +    soap_ns_uris = {
    +        'http://schemas.xmlsoap.org/wsdl/soap/': 'soap11',
    +        'http://schemas.xmlsoap.org/wsdl/soap12/': 'soap12',
    +    }
    +    wsdl_uri = 'http://schemas.xmlsoap.org/wsdl/'
    +    xsd_uri = 'http://www.w3.org/2001/XMLSchema'
    +    xsi_uri = 'http://www.w3.org/2001/XMLSchema-instance'
    +
    +    def _url_to_xml_tree(self, url, cache, force_download):
    +        """Unmarshall the WSDL at the given url into a tree of SimpleXMLElement nodes"""
    +        # Open uri and read xml:
    +        xml = fetch(url, self.http, cache, force_download, self.wsdl_basedir, self.http_headers)
    +        # Parse WSDL XML:
    +        wsdl = SimpleXMLElement(xml, namespace=self.wsdl_uri)
    +
    +        # Extract useful data:
    +        self.namespace = ""
    +        self.documentation = unicode(wsdl('documentation', error=False)) or ''
    +
    +        # some wsdl are split down in several files, join them:
    +        imported_wsdls = {}
    +        for element in wsdl.children() or []:
    +            if element.get_local_name() in ('import'):
    +                wsdl_namespace = element['namespace']
    +                wsdl_location = element['location']
    +                if wsdl_location is None:
    +                    log.warning('WSDL location not provided for %s!' % wsdl_namespace)
    +                    continue
    +                if wsdl_location in imported_wsdls:
    +                    log.warning('WSDL %s already imported!' % wsdl_location)
    +                    continue
    +                imported_wsdls[wsdl_location] = wsdl_namespace
    +                log.debug('Importing wsdl %s from %s' % (wsdl_namespace, wsdl_location))
    +                # Open uri and read xml:
    +                xml = fetch(wsdl_location, self.http, cache, force_download, self.wsdl_basedir, self.http_headers)
    +                # Parse imported XML schema (recursively):
    +                imported_wsdl = SimpleXMLElement(xml, namespace=self.xsd_uri)
    +                # merge the imported wsdl into the main document:
    +                wsdl.import_node(imported_wsdl)
    +                # warning: do not process schemas to avoid infinite recursion!
    +
    +        return wsdl
    +
    +    def _xml_tree_to_services(self, wsdl, cache, force_download):
    +        """Convert SimpleXMLElement tree representation of the WSDL into pythonic objects"""
    +        # detect soap prefix and uri (xmlns attributes of )
    +        xsd_ns = None
    +        soap_uris = {}
    +        for k, v in wsdl[:]:
    +            if v in self.soap_ns_uris and k.startswith('xmlns:'):
    +                soap_uris[get_local_name(k)] = v
    +            if v == self.xsd_uri and k.startswith('xmlns:'):
    +                xsd_ns = get_local_name(k)
    +
    +        elements = {}            # element: type def
    +        messages = {}            # message: element
    +        port_types = {}          # port_type_name: port_type
    +        bindings = {}            # binding_name: binding
    +        services = {}            # service_name: service
    +
    +        # check axis2 namespace at schema types attributes (europa.eu checkVat)
    +        if "http://xml.apache.org/xml-soap" in dict(wsdl[:]).values():
    +            # get the sub-namespace in the first schema element (see issue 8)
    +            if wsdl('types', error=False):
    +                schema = wsdl.types('schema', ns=self.xsd_uri)
    +                attrs = dict(schema[:])
    +                self.namespace = attrs.get('targetNamespace', self.namespace)
    +            if not self.namespace or self.namespace == "urn:DefaultNamespace":
    +                self.namespace = wsdl['targetNamespace'] or self.namespace
    +
    +        imported_schemas = {}
    +        global_namespaces = {None: self.namespace}
    +
    +        # process current wsdl schema (if any, or many if imported):
    +        # 
    +        #     
    +        #         
    +        #             
    +        #                 ...
    +        #                 or
    +        #                 
    +        #             
    +        #         
    +        #     
    +        # 
    +
    +        for types in wsdl('types', error=False) or []:
    +            # avoid issue if schema is not given in the main WSDL file
    +            schemas = types('schema', ns=self.xsd_uri, error=False)
    +            for schema in schemas or []:
    +                preprocess_schema(schema, imported_schemas, elements, self.xsd_uri,
    +                                  self.__soap_server, self.http, cache,
    +                                  force_download, self.wsdl_basedir,
    +                                  global_namespaces=global_namespaces)
    +
    +        # 2nd phase: alias, postdefined elements, extend bases, convert lists
    +        postprocess_element(elements, [])
    +
    +        for message in wsdl.message:
    +            for part in message('part', error=False) or []:
    +                element = {}
    +                element_name = part['element']
    +                if not element_name:
    +                    # some implementations (axis) uses type instead
    +                    element_name = part['type']
    +                type_ns = get_namespace_prefix(element_name)
    +                type_uri = part.get_namespace_uri(type_ns)
    +                part_name = part['name'] or None
    +                if type_uri == self.xsd_uri:
    +                    element_name = get_local_name(element_name)
    +                    fn = REVERSE_TYPE_MAP.get(element_name, None)
    +                    element = {part_name: fn}
    +                    # emulate a true Element (complexType) for rpc style
    +                    if (message['name'], part_name) not in messages:
    +                        od = Struct()
    +                        od.namespaces[None] = type_uri
    +                        messages[(message['name'], part_name)] = {message['name']: od}
    +                    else:
    +                        od = messages[(message['name'], part_name)].values()[0]
    +                    od.namespaces[part_name] = type_uri
    +                    od.references[part_name] = False
    +                    od.update(element)
    +                else:
    +                    element_name = get_local_name(element_name)
    +                    fn = elements.get(make_key(element_name, 'element', type_uri))
    +                    if not fn:
    +                        # some axis servers uses complexType for part messages (rpc)
    +                        fn = elements.get(make_key(element_name, 'complexType', type_uri))
    +                        od = Struct()
    +                        od[part_name] = fn
    +                        od.namespaces[None] = type_uri
    +                        od.namespaces[part_name] = type_uri
    +                        od.references[part_name] = False
    +                        element = {message['name']: od}
    +                    else:
    +                        element = {element_name: fn}
    +                    messages[(message['name'], part_name)] = element
    +
    +        for port_type_node in wsdl.portType:
    +            port_type_name = port_type_node['name']
    +            port_type = port_types[port_type_name] = {}
    +            operations = port_type['operations'] = {}
    +
    +            for operation_node in port_type_node.operation:
    +                op_name = operation_node['name']
    +                op = operations[op_name] = {}
    +                op['style'] = operation_node['style']
    +                op['parameter_order'] = (operation_node['parameterOrder'] or "").split(" ")
    +                op['documentation'] = unicode(operation_node('documentation', error=False)) or ''
    +
    +                if operation_node('input', error=False):
    +                    op['input_msg'] = get_local_name(operation_node.input['message'])
    +                    ns = get_namespace_prefix(operation_node.input['message'])
    +                    op['namespace'] = operation_node.get_namespace_uri(ns)
    +
    +                if operation_node('output', error=False):
    +                    op['output_msg'] = get_local_name(operation_node.output['message'])
    +
    +                #Get all fault message types this operation may return
    +                fault_msgs = op['fault_msgs'] = {}
    +                faults = operation_node('fault', error=False)
    +                if faults is not None:
    +                    for fault in operation_node('fault', error=False):
    +                        fault_msgs[fault['name']] = get_local_name(fault['message'])
    +
    +        for binding_node in wsdl.binding:
    +            port_type_name = get_local_name(binding_node['type'])
    +            if port_type_name not in port_types:
    +                # Invalid port type
    +                continue
    +            port_type = port_types[port_type_name]
    +            binding_name = binding_node['name']
    +            soap_binding = binding_node('binding', ns=list(soap_uris.values()), error=False)
    +            transport = soap_binding and soap_binding['transport'] or None
    +            style = soap_binding and soap_binding['style'] or None  # rpc
    +
    +            binding = bindings[binding_name] = {
    +                'name': binding_name,
    +                'operations': copy.deepcopy(port_type['operations']),
    +                'port_type_name': port_type_name,
    +                'transport': transport,
    +                'style': style,
    +            }
    +
    +            for operation_node in binding_node.operation:
    +                op_name = operation_node['name']
    +                op_op = operation_node('operation', ns=list(soap_uris.values()), error=False)
    +                action = op_op and op_op['soapAction']
    +
    +                op = binding['operations'].setdefault(op_name, {})
    +                op['name'] = op_name
    +                op['style'] = op.get('style', style)
    +                if action is not None:
    +                    op['action'] = action
    +
    +                # input and/or output can be not present!
    +                input = operation_node('input', error=False)
    +                body = input and input('body', ns=list(soap_uris.values()), error=False)
    +                parts_input_body = body and body['parts'] or None
    +
    +                # parse optional header messages (some implementations use more than one!)
    +                parts_input_headers = []
    +                headers = input and input('header', ns=list(soap_uris.values()), error=False)
    +                for header in headers or []:
    +                    hdr = {'message': header['message'], 'part': header['part']}
    +                    parts_input_headers.append(hdr)
    +
    +                if 'input_msg' in op:
    +                    headers = {}    # base header message structure
    +                    for input_header in parts_input_headers:
    +                        header_msg = get_local_name(input_header.get('message'))
    +                        header_part = get_local_name(input_header.get('part'))
    +                        # warning: some implementations use a separate message!
    +                        hdr = get_message(messages, header_msg or op['input_msg'], header_part)
    +                        if hdr:
    +                            headers.update(hdr)
    +                        else:
    +                            pass # not enough info to search the header message:
    +                    op['input'] = get_message(messages, op['input_msg'], parts_input_body, op['parameter_order'])
    +                    op['header'] = headers
    +
    +                    try:
    +                        element = list(op['input'].values())[0]
    +                        ns_uri = element.namespaces[None]
    +                        qualified = element.qualified
    +                    except (AttributeError, KeyError) as e:
    +                        # TODO: fix if no parameters parsed or "variants"
    +                        ns_uri = op['namespace']
    +                        qualified = None
    +                    if ns_uri:
    +                        op['namespace'] = ns_uri
    +                        op['qualified'] = qualified
    +
    +                    # Remove temporary property
    +                    del op['input_msg']
    +
    +                else:
    +                    op['input'] = None
    +                    op['header'] = None
    +
    +                output = operation_node('output', error=False)
    +                body = output and output('body', ns=list(soap_uris.values()), error=False)
    +                parts_output_body = body and body['parts'] or None
    +                if 'output_msg' in op:
    +                    op['output'] = get_message(messages, op['output_msg'], parts_output_body)
    +                    # Remove temporary property
    +                    del op['output_msg']
    +                else:
    +                    op['output'] = None
    +
    +                if 'fault_msgs' in op:
    +                    faults = op['faults'] = {}
    +                    for msg in op['fault_msgs'].values():
    +                        msg_obj = get_message(messages, msg, parts_output_body)
    +                        tag_name = list(msg_obj)[0]
    +                        faults[tag_name] = msg_obj
    +
    +                # useless? never used
    +                parts_output_headers = []
    +                headers = output and output('header', ns=list(soap_uris.values()), error=False)
    +                for header in headers or []:
    +                    hdr = {'message': header['message'], 'part': header['part']}
    +                    parts_output_headers.append(hdr)
    +
    +
    +
    +
    +        for service in wsdl("service", error=False) or []:
    +            service_name = service['name']
    +            if not service_name:
    +                continue  # empty service?
    +
    +            serv = services.setdefault(service_name, {})
    +            ports = serv['ports'] = {}
    +            serv['documentation'] = service['documentation'] or ''
    +            for port in service.port:
    +                binding_name = get_local_name(port['binding'])
    +
    +                if not binding_name in bindings:
    +                    continue    # unknown binding
    +
    +                binding = ports[port['name']] = copy.deepcopy(bindings[binding_name])
    +                address = port('address', ns=list(soap_uris.values()), error=False)
    +                location = address and address['location'] or None
    +                soap_uri = address and soap_uris.get(address.get_prefix())
    +                soap_ver = soap_uri and self.soap_ns_uris.get(soap_uri)
    +
    +                binding.update({
    +                    'location': location,
    +                    'service_name': service_name,
    +                    'soap_uri': soap_uri,
    +                    'soap_ver': soap_ver,
    +                })
    +
    +        # create an default service if none is given in the wsdl:
    +        if not services:
    +            services[''] = {'ports': {'': None}}
    +   
    +        elements = list(e for e in elements.values() if type(e) is type) + sorted(e for e in elements.values() if not(type(e) is type))
    +        e = None
    +        self.elements = []
    +        for element in elements:
    +            if e!= element: self.elements.append(element)
    +            e = element
    +
    +        return services
    +
    +    def wsdl_parse(self, url, cache=False):
    +        """Parse Web Service Description v1.1"""
    +
    +        log.debug('Parsing wsdl url: %s' % url)
    +        # Try to load a previously parsed wsdl:
    +        force_download = False
    +        if cache:
    +            # make md5 hash of the url for caching...
    +            filename_pkl = '%s.pkl' % hashlib.md5(url).hexdigest()
    +            if isinstance(cache, basestring):
    +                filename_pkl = os.path.join(cache, filename_pkl)
    +            if os.path.exists(filename_pkl):
    +                log.debug('Unpickle file %s' % (filename_pkl, ))
    +                f = open(filename_pkl, 'r')
    +                pkl = pickle.load(f)
    +                f.close()
    +                # sanity check:
    +                if pkl['version'][:-1] != __version__.split(' ')[0][:-1] or pkl['url'] != url:
    +                    warnings.warn('version or url mismatch! discarding cached wsdl', RuntimeWarning)
    +                    log.debug('Version: %s %s' % (pkl['version'], __version__))
    +                    log.debug('URL: %s %s' % (pkl['url'], url))
    +                    force_download = True
    +                else:
    +                    self.namespace = pkl['namespace']
    +                    self.documentation = pkl['documentation']
    +                    return pkl['services']
    +
    +        # always return an unicode object:
    +        REVERSE_TYPE_MAP['string'] = str
    +
    +        wsdl = self._url_to_xml_tree(url, cache, force_download)
    +        services = self._xml_tree_to_services(wsdl, cache, force_download)
    +
    +        # dump the full service/port/operation map
    +        #log.debug(pprint.pformat(services))
    +
    +        # Save parsed wsdl (cache)
    +        if cache:
    +            f = open(filename_pkl, "wb")
    +            pkl = {
    +                'version': __version__.split(' ')[0],
    +                'url': url,
    +                'namespace': self.namespace,
    +                'documentation': self.documentation,
    +                'services': services,
    +            }
    +            pickle.dump(pkl, f)
    +            f.close()
    +
    +        return services
    +
    +    def __setitem__(self, item, value):
    +        """Set SOAP Header value - this header will be sent for every request."""
    +        self.__headers[item] = value
    +
    +    def close(self):
    +        """Finish the connection and remove temp files"""
    +        self.http.close()
    +        if self.cacert.startswith(tempfile.gettempdir()):
    +            log.debug('removing %s' % self.cacert)
    +            os.unlink(self.cacert)
    +
    +    def __repr__(self):
    +        s = 'SOAP CLIENT'
    +        s += '\n ELEMENTS'
    +        for e in self.elements:
    +            if isinstance(e, type):
    +                e = e.__name__
    +            elif isinstance(e, Alias):
    +                e = e.xml_type
    +            elif isinstance(e, Struct) and e.key[1]=='element':
    +                e = repr(e)
    +            else:
    +                continue
    +            s += '\n  %s' % e
    +        for service in self.services:
    +            s += '\n SERVICE (%s)' % service
    +            ports = self.services[service]['ports']
    +            for port in ports:
    +                port = ports[port]
    +                if port['soap_ver'] == None: continue
    +                s += '\n   PORT (%s)' % port['name']
    +                s += '\n    Location: %s' % port['location']
    +                s += '\n    Soap ver: %s' % port['soap_ver']
    +                s += '\n    Soap URI: %s' % port['soap_uri']
    +                s += '\n    OPERATIONS'
    +                operations = port['operations']
    +                for operation in sorted(operations):
    +                    operation = self.get_operation(operation)
    +                    input = operation.get('input')
    +                    input = input and input.values() and list(input.values())[0]
    +                    input_str = ''
    +                    if isinstance(input, dict):
    +                        if 'parameters' not in input or input['parameters']!=None:
    +                            for k, v in input.items():
    +                                if isinstance(v, type):
    +                                    v = v.__name__
    +                                elif isinstance(v, Alias):
    +                                    v = v.xml_type
    +                                elif isinstance(v, Struct):
    +                                    v = v.key[0]
    +                                input_str += '%s: %s, ' % (k, v)
    +                    output = operation.get('output')
    +                    if output:
    +                        output = list(operation['output'].values())[0]
    +                    s += '\n     %s(%s)' % (
    +                        operation['name'],
    +                        input_str[:-2]
    +                        )
    +                    s += '\n      > %s' % output
    +
    +        return s
    +
    +def parse_proxy(proxy_str):
    +    """Parses proxy address user:pass@host:port into a dict suitable for httplib2"""
    +    proxy_dict = {}
    +    if proxy_str is None:
    +        return
    +    if '@' in proxy_str:
    +        user_pass, host_port = proxy_str.split('@')
    +    else:
    +        user_pass, host_port = '', proxy_str
    +    if ':' in host_port:
    +        host, port = host_port.split(':')
    +        proxy_dict['proxy_host'], proxy_dict['proxy_port'] = host, int(port)
    +    if ':' in user_pass:
    +        proxy_dict['proxy_user'], proxy_dict['proxy_pass'] = user_pass.split(':')
    +    return proxy_dict
    +
    +
    +if __name__ == '__main__':
    +    pass
    diff --git a/web2py/gluon/contrib/pysimplesoap/helpers.py b/web2py/gluon/contrib/pysimplesoap/helpers.py
    new file mode 100644
    index 0000000..b6e6ce0
    --- /dev/null
    +++ b/web2py/gluon/contrib/pysimplesoap/helpers.py
    @@ -0,0 +1,706 @@
    +#!/usr/bin/python
    +# -*- coding: utf-8 -*-
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU Lesser General Public License as published by
    +# the Free Software Foundation; either version 3, or (at your option) any
    +# later version.
    +#
    +# This program is distributed in the hope that it will be useful, but
    +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    +# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    +# for more details.
    +
    +"""Pythonic simple SOAP Client helpers"""
    +
    +
    +from __future__ import unicode_literals
    +import sys
    +if sys.version > '3':
    +    basestring = unicode = str
    +
    +import datetime
    +from decimal import Decimal
    +import os
    +import logging
    +import hashlib
    +import warnings
    +
    +try:
    +    import urllib2
    +    from urlparse import urlsplit
    +except ImportError:
    +    from urllib import request as urllib2
    +    from urllib.parse import urlsplit
    +
    +from . import __author__, __copyright__, __license__, __version__
    +
    +
    +log = logging.getLogger(__name__)
    +
    +
    +def fetch(url, http, cache=False, force_download=False, wsdl_basedir='', headers={}):
    +    """Download a document from a URL, save it locally if cache enabled"""
    +
    +    # check / append a valid schema if not given:
    +    url_scheme, netloc, path, query, fragment = urlsplit(url)
    +    if not url_scheme in ('http', 'https', 'file'):
    +        for scheme in ('http', 'https', 'file'):
    +            try:
    +                path = os.path.normpath(os.path.join(wsdl_basedir, url))
    +                if not url.startswith("/") and scheme in ('http', 'https'):
    +                    tmp_url = "%s://%s" % (scheme, path)
    +                else:
    +                    tmp_url = "%s:%s" % (scheme, path)
    +                log.debug('Scheme not found, trying %s' % scheme)
    +                return fetch(tmp_url, http, cache, force_download, wsdl_basedir, headers)
    +            except Exception as e:
    +                log.error(e)
    +        raise RuntimeError('No scheme given for url: %s' % url)
    +
    +    # make md5 hash of the url for caching...
    +    filename = '%s.xml' % hashlib.md5(url.encode('utf8')).hexdigest()
    +    if isinstance(cache, basestring):
    +        filename = os.path.join(cache, filename)
    +    if cache and os.path.exists(filename) and not force_download:
    +        log.info('Reading file %s' % filename)
    +        f = open(filename, 'r')
    +        xml = f.read()
    +        f.close()
    +    else:
    +        if url_scheme == 'file':
    +            log.info('Fetching url %s using urllib2' % url)
    +            f = urllib2.urlopen(url)
    +            xml = f.read()
    +        else:
    +            log.info('GET %s using %s' % (url, http._wrapper_version))
    +            response, xml = http.request(url, 'GET', None, headers)
    +        if cache:
    +            log.info('Writing file %s' % filename)
    +            if not os.path.isdir(cache):
    +                os.makedirs(cache)
    +            f = open(filename, 'w')
    +            f.write(xml)
    +            f.close()
    +    return xml
    +
    +
    +def sort_dict(od, d):
    +    """Sort parameters (same order as xsd:sequence)"""
    +    if isinstance(od, dict):
    +        ret = Struct()
    +        for k in od.keys():
    +            v = d.get(k)
    +            # don't append null tags!
    +            if v is not None:
    +                if isinstance(v, dict):
    +                    v = sort_dict(od[k], v)
    +                elif isinstance(v, list):
    +                    v = [sort_dict(od[k][0], v1) for v1 in v]
    +                ret[k] = v
    +        if hasattr(od, 'namespaces'):
    +            ret.namespaces.update(od.namespaces)
    +            ret.references.update(od.references)
    +            ret.qualified = od.qualified
    +        return ret
    +    else:
    +        return d
    +
    +
    +def make_key(element_name, element_type, namespace):
    +    """Return a suitable key for elements"""
    +    # only distinguish 'element' vs other types
    +    if element_type in ('complexType', 'simpleType'):
    +        eltype = 'complexType'
    +    else:
    +        eltype = element_type
    +    if eltype not in ('element', 'complexType', 'simpleType'):
    +        raise RuntimeError("Unknown element type %s = %s" % (element_name, eltype))
    +    return (element_name, eltype, namespace)
    +
    +
    +def process_element(elements, element_name, node, element_type, xsd_uri,
    +                    dialect, namespace, qualified=None,
    +                    soapenc_uri='http://schemas.xmlsoap.org/soap/encoding/',
    +                    struct=None):
    +    """Parse and define simple element types as Struct objects"""
    +
    +    log.debug('Processing element %s %s' % (element_name, element_type))
    +
    +    # iterate over inner tags of the element definition:
    +    for tag in node:
    +
    +        # sanity checks (skip superfluous xml tags, resolve aliases, etc.):
    +        if tag.get_local_name() in ('annotation', 'documentation'):
    +            continue
    +        elif tag.get_local_name() in ('element', 'restriction', 'list'):
    +            log.debug('%s has no children! %s' % (element_name, tag))
    +            children = tag  # element "alias"?
    +            alias = True
    +        elif tag.children():
    +            children = tag.children()
    +            alias = False
    +        else:
    +            log.debug('%s has no children! %s' % (element_name, tag))
    +            continue  # TODO: abstract?
    +
    +        # check if extending a previous processed element ("extension"):
    +        new_struct = struct is None
    +        if new_struct:
    +            struct = Struct()
    +            struct.namespaces[None] = namespace   # set the default namespace
    +            struct.qualified = qualified
    +
    +        # iterate over the element's components (sub-elements):
    +        for e in children:
    +
    +            # extract type information from xml attributes / children:
    +            t = e['type']
    +            if not t:
    +                t = e['itemType']  # xs:list
    +            if not t:
    +                t = e['base']  # complexContent (extension)!
    +            if not t:
    +                t = e['ref']   # reference to another element
    +            if not t:
    +                # "anonymous" elements had no type attribute but children
    +                if e['name'] and e.children():
    +                    # create a type name to process the children
    +                    t = "%s_%s" % (element_name, e['name'])
    +                    c = e.children()
    +                    et = c.get_local_name()
    +                    c = c.children()
    +                    process_element(elements, t, c, et, xsd_uri, dialect,
    +                                    namespace, qualified)
    +                else:
    +                    t = 'anyType'  # no type given!
    +
    +            # extract namespace uri and type from xml attribute:
    +            t = t.split(":")
    +            if len(t) > 1:
    +                ns, type_name = t
    +            else:
    +                ns, type_name = None, t[0]
    +            uri = ns and e.get_namespace_uri(ns) or xsd_uri
    +
    +            # look for the conversion function (python type)
    +            if uri in (xsd_uri, soapenc_uri) and type_name != 'Array':
    +                # look for the type, None == any
    +                fn = REVERSE_TYPE_MAP.get(type_name, None)
    +                if tag.get_local_name() == 'list':
    +                    # simple list type (values separated by spaces)
    +                    fn = lambda s: [fn(v) for v in s.split(" ")]
    +            elif (uri == soapenc_uri and type_name == 'Array'):
    +                # arrays of simple types (look at the attribute tags):
    +                fn = []
    +                for a in e.children():
    +                    for k, v in a[:]:
    +                        if k.endswith(":arrayType"):
    +                            type_name = v
    +                            fn_namespace = None
    +                            if ":" in type_name:
    +                                fn_uri, type_name = type_name.split(":")
    +                                fn_namespace = e.get_namespace_uri(fn_uri)
    +                            if "[]" in type_name:
    +                                type_name = type_name[:type_name.index("[]")]
    +                            # get the scalar conversion function (if any)
    +                            fn_array = REVERSE_TYPE_MAP.get(type_name, None)
    +                            if fn_array is None and type_name != "anyType" and fn_namespace:
    +                                # get the complext element:
    +                                ref_type = "complexType"
    +                                key = make_key(type_name, ref_type, fn_namespace)
    +                                fn_complex = elements.setdefault(key, Struct(key))
    +                                # create an indirect struct {type_name: ...}:
    +                                fn_array = Struct(key)
    +                                fn_array[type_name] = fn_complex
    +                                fn_array.namespaces[None] = fn_namespace   # set the default namespace
    +                                fn_array.qualified = qualified
    +                            fn.append(fn_array)
    +            else:
    +                # not a simple python type / conversion function not available
    +                fn = None
    +
    +            if not fn:
    +                # simple / complex type, postprocess later
    +                if ns:
    +                    fn_namespace = uri       # use the specified namespace
    +                else:
    +                    fn_namespace = namespace # use parent namespace (default)
    +                for k, v in e[:]:
    +                    if k.startswith("xmlns:"):
    +                        # get the namespace uri from the element
    +                        fn_namespace = v
    +                # create and store an empty python element (dict) filled later
    +                if not e['ref']:
    +                    ref_type = "complexType"
    +                else:
    +                    ref_type = "element"
    +                key = make_key(type_name, ref_type, fn_namespace)
    +                fn = elements.setdefault(key, Struct(key))
    +
    +            if e['maxOccurs'] == 'unbounded' or (uri == soapenc_uri and type_name == 'Array'):
    +                # it's an array... TODO: compound arrays? and check ns uri!
    +                if isinstance(fn, Struct):
    +                    if len(children) > 1 or (dialect in ('jetty', )):
    +                        # Jetty style support
    +                        # {'ClassName': [{'attr1': val1, 'attr2': val2}]
    +                        fn.array = True
    +                    else:
    +                        # .NET style now matches Jetty style
    +                        # {'ClassName': [{'attr1': val1, 'attr2': val2}]
    +                        #fn.array = True
    +                        #struct.array = True
    +                        fn = [fn]
    +                else:
    +                    if len(children) > 1 or dialect in ('jetty',):
    +                        # Jetty style support
    +                        # scalar array support {'attr1': [val1]}
    +                        fn = [fn]
    +                    else:
    +                        # Jetty.NET style support (backward compatibility)
    +                        # scalar array support [{'attr1': val1}]
    +                        struct.array = True
    +
    +            # store the sub-element python type (function) in the element dict
    +            if (e['name'] is not None and not alias) or e['ref']:
    +                e_name = e['name'] or type_name  # for refs, use the type name
    +                struct[e_name] = fn
    +                struct.references[e_name] = e['ref']
    +                struct.namespaces[e_name] = namespace  # set the element namespace
    +            else:
    +                log.debug('complexContent/simpleType/element %s = %s' % (element_name, type_name))
    +                # use None to point this is a complex element reference
    +                struct.refers_to = fn
    +            if e is not None and e.get_local_name() == 'extension' and e.children():
    +                # extend base element (if ComplexContent only!):
    +                if isinstance(fn, Struct) and fn.refers_to:
    +                    base_struct = fn.refers_to
    +                else:
    +                    # TODO: check if this actually works for SimpleContent
    +                    base_struct = None
    +                # extend base element:
    +                process_element(elements, element_name, e.children(),
    +                                element_type, xsd_uri, dialect, namespace,
    +                                qualified, struct=base_struct)
    +
    +        # add the processed element to the main dictionary (if not extension):
    +        if new_struct:
    +            key = make_key(element_name, element_type, namespace)
    +            elements.setdefault(key, Struct(key)).update(struct)
    +
    +
    +def postprocess_element(elements, processed):
    +    """Fix unresolved references"""
    +    #elements variable contains all eelements and complexTypes defined in http://www.w3.org/2001/XMLSchema
    +
    +    # (elements referenced before its definition, thanks .net)
    +    # avoid already processed elements:
    +    if elements in processed:
    +        return
    +    processed.append(elements)
    +
    +    for k, v in elements.items():
    +        if isinstance(v, Struct):
    +            if v != elements:  # TODO: fix recursive elements
    +                try:
    +                    postprocess_element(v, processed)
    +                except RuntimeError as e:  # maximum recursion depth exceeded
    +                    warnings.warn(unicode(e), RuntimeWarning)
    +            if v.refers_to:  # extension base?
    +                if isinstance(v.refers_to, dict):
    +                    extend_element(v, v.refers_to)
    +                    # clean the reference:
    +                    v.refers_to = None
    +                else:  # "alias", just replace
    +                    ##log.debug('Replacing %s = %s' % (k, v.refers_to))
    +                    elements[k] = v.refers_to
    +            if v.array:
    +                elements[k] = [v]  # convert arrays to python lists
    +        if isinstance(v, list):
    +            for n in v:  # recurse list
    +                if isinstance(n, (Struct, list)):
    +                    #if n != elements:  # TODO: fix recursive elements
    +                    postprocess_element(n, processed)
    +
    +def extend_element(element, base):
    +    ''' Recursively extend the elemnet if it has an extension base.'''
    +    ''' Recursion is needed if the extension base itself extends another element.'''
    +    if isinstance(base, dict):
    +        for i, kk in enumerate(base):
    +            # extend base -keep orignal order-
    +            if isinstance(base, Struct):
    +                element.insert(kk, base[kk], i)
    +                # update namespace (avoid ArrayOfKeyValueOfanyTypeanyType)
    +                if isinstance(base, Struct) and base.namespaces and kk:
    +                    element.namespaces[kk] = base.namespaces[kk]
    +                    element.references[kk] = base.references[kk]
    +        if base.refers_to:
    +            extend_element(element, base.refers_to)
    +
    +def get_message(messages, message_name, part_name, parameter_order=None):
    +    if part_name:
    +        # get the specific part of the message:
    +        return messages.get((message_name, part_name))
    +    else:
    +        # get the first part for the specified message:
    +        parts = {}
    +        for (message_name_key, part_name_key), message in messages.items():
    +            if message_name_key == message_name:
    +                parts[part_name_key] = message
    +        if len(parts)>1:
    +            # merge (sorted by parameter_order for rpc style)
    +            new_msg = None
    +            for part_name_key in parameter_order:
    +                part = parts.get(part_name_key)
    +                if not part:
    +                    log.error('Part %s not found for %s' % (part_name_key, message_name))
    +                elif not new_msg:
    +                    new_msg = part.copy()
    +                else:
    +                    new_msg[message_name].update(part[message_name])
    +            return new_msg
    +        elif parts:
    +            return list(parts.values())[0]
    +            #return parts.values()[0]
    +
    +
    +
    +get_local_name = lambda s: s and str((':' in s) and s.split(':')[1] or s)
    +get_namespace_prefix = lambda s: s and str((':' in s) and s.split(':')[0] or None)
    +
    +
    +def preprocess_schema(schema, imported_schemas, elements, xsd_uri, dialect,
    +                      http, cache, force_download, wsdl_basedir,
    +                      global_namespaces=None, qualified=False):
    +    """Find schema elements and complex types"""
    +
    +    from .simplexml import SimpleXMLElement    # here to avoid recursive imports
    +
    +    # analyze the namespaces used in this schema
    +    local_namespaces = {}
    +    for k, v in schema[:]:
    +        if k.startswith("xmlns"):
    +            local_namespaces[get_local_name(k)] = v
    +        if k == 'targetNamespace':
    +            # URI namespace reference for this schema
    +            if v == "urn:DefaultNamespace":
    +                v = global_namespaces[None]
    +            local_namespaces[None] = v
    +        if k == 'elementFormDefault':
    +            qualified = (v == "qualified")
    +    # add schema namespaces to the global namespace dict = {URI: ns prefix}
    +    for ns in local_namespaces.values():
    +        if ns not in global_namespaces:
    +            global_namespaces[ns] = 'ns%s' % len(global_namespaces)
    +
    +    for element in schema.children() or []:
    +        if element.get_local_name() in ('import', 'include',):
    +            schema_namespace = element['namespace']
    +            schema_location = element['schemaLocation']
    +            if schema_location is None:
    +                log.debug('Schema location not provided for %s!' % schema_namespace)
    +                continue
    +            if schema_location in imported_schemas:
    +                log.debug('Schema %s already imported!' % schema_location)
    +                continue
    +            imported_schemas[schema_location] = schema_namespace
    +            log.debug('Importing schema %s from %s' % (schema_namespace, schema_location))
    +            # Open uri and read xml:
    +            xml = fetch(schema_location, http, cache, force_download, wsdl_basedir)
    +
    +            # recalculate base path for relative schema locations
    +            path = os.path.normpath(os.path.join(wsdl_basedir, schema_location))
    +            path = os.path.dirname(path)
    +
    +            # Parse imported XML schema (recursively):
    +            imported_schema = SimpleXMLElement(xml, namespace=xsd_uri)
    +            preprocess_schema(imported_schema, imported_schemas, elements,
    +                              xsd_uri, dialect, http, cache, force_download,
    +                              path, global_namespaces, qualified)
    +
    +        element_type = element.get_local_name()
    +        if element_type in ('element', 'complexType', "simpleType"):
    +            namespace = local_namespaces[None]          # get targetNamespace
    +            element_ns = global_namespaces[ns]          # get the prefix
    +            element_name = element['name']
    +            log.debug("Parsing Element %s: %s" % (element_type, element_name))
    +            if element.get_local_name() == 'complexType':
    +                children = element.children()
    +            elif element.get_local_name() == 'simpleType':
    +                children = element('restriction', ns=xsd_uri, error=False)
    +                if not children:
    +                    children = element.children()       # xs:list
    +            elif element.get_local_name() == 'element' and element['type']:
    +                children = element
    +            else:
    +                children = element.children()
    +                if children:
    +                    children = children.children()
    +                elif element.get_local_name() == 'element':
    +                    children = element
    +            if children:
    +                process_element(elements, element_name, children, element_type,
    +                                xsd_uri, dialect, namespace, qualified)
    +
    +
    +# simplexml utilities:
    +
    +try:
    +    _strptime = datetime.datetime.strptime
    +except AttributeError:  # python2.4
    +    _strptime = lambda s, fmt: datetime.datetime(*(time.strptime(s, fmt)[:6]))
    +
    +
    +# Functions to serialize/deserialize special immutable types:
    +def datetime_u(s):
    +    fmt = "%Y-%m-%dT%H:%M:%S"
    +    try:
    +        return _strptime(s, fmt)
    +    except ValueError:
    +        try:
    +            # strip zulu timezone suffix or utc offset
    +            if s[-1] == "Z" or (s[-3] == ":" and s[-6] in (' ', '-', '+')):
    +                try:
    +                    import iso8601
    +                    return iso8601.parse_date(s)
    +                except ImportError:
    +                    pass
    +
    +                try:
    +                    import isodate
    +                    return isodate.parse_datetime(s)
    +                except ImportError:
    +                    pass
    +
    +                try:
    +                    import dateutil.parser
    +                    return dateutil.parser.parse(s)
    +                except ImportError:
    +                    pass
    +
    +                warnings.warn('removing unsupported "Z" suffix or UTC offset. Install `iso8601`, `isodate` or `python-dateutil` package to support it', RuntimeWarning)
    +                s = s[:-1] if s[-1] == "Z" else s[:-6]
    +            # parse microseconds
    +            try:
    +                return _strptime(s, fmt + ".%f")
    +            except:
    +                return _strptime(s, fmt)
    +        except ValueError:
    +            # strip microseconds (not supported in this platform)
    +            if "." in s:
    +                warnings.warn('removing unsuppported microseconds', RuntimeWarning)
    +                s = s[:s.index(".")]
    +            return _strptime(s, fmt)
    +
    +
    +datetime_m = lambda dt: dt.isoformat()
    +date_u = lambda s: _strptime(s[0:10], "%Y-%m-%d").date()
    +date_m = lambda d: d.strftime("%Y-%m-%d")
    +time_u = lambda s: _strptime(s, "%H:%M:%S").time()
    +time_m = lambda d: d.strftime("%H%M%S")
    +bool_u = lambda s: {'0': False, 'false': False, '1': True, 'true': True}[s]
    +bool_m = lambda s: {False: 'false', True: 'true'}[s]
    +decimal_m = lambda d: '{0:f}'.format(d)
    +float_m = lambda f: '{0:.10f}'.format(f)
    +
    +# aliases:
    +class Alias(object):
    +    def __init__(self, py_type, xml_type):
    +        self.py_type, self.xml_type = py_type, xml_type
    +
    +    def __call__(self, value):
    +        return self.py_type(value)
    +
    +    def __repr__(self):
    +        return "" % (self.xml_type, self.py_type)
    +
    +    def __eq__(self, other):
    +        return isinstance(other, Alias) and self.xml_type == other.xml_type
    +        
    +    def __ne__(self, other):
    +        return not self.__eq__(other)
    +
    +    def __gt__(self, other):
    +        if isinstance(other, Alias): return self.xml_type > other.xml_type
    +        if isinstance(other, Struct): return False
    +        return True
    +
    +    def __lt__(self, other):
    +        if isinstance(other, Alias): return self.xml_type < other.xml_type
    +        if isinstance(other, Struct): return True
    +        return False
    +
    +    def __ge__(self, other):
    +        return self.__gt__(other) or self.__eq__(other)
    +
    +    def __le__(self, other):
    +        return self.__gt__(other) or self.__eq__(other)
    +
    +    def __hash__(self):
    +        return hash(self.xml_type)
    +
    +if sys.version > '3':
    +    long = Alias(int, 'long')
    +byte = Alias(str, 'byte')
    +short = Alias(int, 'short')
    +double = Alias(float, 'double')
    +integer = Alias(long, 'integer')
    +DateTime = datetime.datetime
    +Date = datetime.date
    +Time = datetime.time
    +duration = Alias(str, 'duration')
    +any_uri = Alias(str, 'anyURI')
    +
    +# Define conversion function (python type): xml schema type
    +TYPE_MAP = {
    +    unicode: 'string',
    +    bool: 'boolean',
    +    short: 'short',
    +    byte: 'byte',
    +    int: 'int',
    +    long: 'long',
    +    integer: 'integer',
    +    float: 'float',
    +    double: 'double',
    +    Decimal: 'decimal',
    +    datetime.datetime: 'dateTime',
    +    datetime.date: 'date',
    +    datetime.time: 'time',
    +    duration: 'duration',
    +    any_uri: 'anyURI',
    +}
    +TYPE_MARSHAL_FN = {
    +    datetime.datetime: datetime_m,
    +    datetime.date: date_m,
    +    datetime.time: time_m,
    +    float: float_m,
    +    Decimal: decimal_m,
    +    bool: bool_m,
    +}
    +TYPE_UNMARSHAL_FN = {
    +    datetime.datetime: datetime_u,
    +    datetime.date: date_u,
    +    datetime.time: time_u,
    +    bool: bool_u,
    +    str: unicode,
    +}
    +
    +REVERSE_TYPE_MAP = dict([(v, k) for k, v in TYPE_MAP.items()])
    +
    +REVERSE_TYPE_MAP.update({
    +    'base64Binary': str,
    +    'unsignedByte': byte,
    +    'unsignedInt': int,
    +    'unsignedLong': long,
    +    'unsignedShort': short
    +})
    +
    +# insert str here to avoid collision in REVERSE_TYPE_MAP (i.e. decoding errors)
    +if str not in TYPE_MAP:
    +    TYPE_MAP[str] = 'string'
    +
    +
    +class Struct(dict):
    +    """Minimal ordered dictionary to represent elements (i.e. xsd:sequences)"""
    +
    +    def __init__(self, key=None):
    +        self.key = key
    +        self.__keys = []
    +        self.array = False
    +        self.namespaces = {}     # key: element, value: namespace URI
    +        self.references = {}     # key: element, value: reference name
    +        self.refers_to = None    # "symbolic linked" struct
    +        self.qualified = None
    +
    +    def __setitem__(self, key, value):
    +        if key not in self.__keys:
    +            self.__keys.append(key)
    +        dict.__setitem__(self, key, value)
    +
    +    def insert(self, key, value, index=0):
    +        if key not in self.__keys:
    +            self.__keys.insert(index, key)
    +        dict.__setitem__(self, key, value)
    +
    +    def __delitem__(self, key):
    +        if key in self.__keys:
    +            self.__keys.remove(key)
    +        dict.__delitem__(self, key)
    +
    +    def __iter__(self):
    +        return iter(self.__keys)
    +
    +    def keys(self):
    +        return self.__keys
    +
    +    def items(self):
    +        return [(key, self[key]) for key in self.__keys]
    +
    +    def update(self, other):
    +        if isinstance(other, Struct) and other.key:
    +            self.key = other.key
    +        for k, v in other.items():
    +            self[k] = v
    +        # do not change if we are an array but the other is not:
    +        if isinstance(other, Struct) and not self.array:
    +            self.array = other.array
    +        if isinstance(other, Struct):
    +            # TODO: check replacing default ns is a regression
    +            self.namespaces.update(other.namespaces)
    +            self.references.update(other.references)
    +            self.qualified = other.qualified
    +            self.refers_to = other.refers_to
    +
    +    def copy(self):
    +        "Make a duplicate"
    +        new = Struct(self.key)
    +        new.update(self)
    +        return new
    +
    +    def __eq__(self, other):
    +        return isinstance(other, Struct) and self.key == other.key and self.key != None
    +
    +    def __ne__(self, other):
    +        return not self.__eq__(other)
    +
    +    def __gt__(self, other):
    +        if isinstance(other, Struct): return (self.key[2], self.key[0], self.key[1]) > (other.key[2], other.key[0], other.key[1])
    +        return True
    +
    +    def __lt__(self, other):
    +        if isinstance(other, Struct): return (self.key[2], self.key[0], self.key[1]) < (other.key[2], other.key[0], other.key[1])
    +        return False
    +
    +    def __ge__(self, other):
    +        return self.__gt__(other) or self.__eq__(other)
    +
    +    def __le__(self, other):
    +        return self.__gt__(other) or self.__eq__(other)
    +
    +    def __hash__(self):
    +        return hash(self.key)
    +
    +    def __str__(self):
    +        return "%s" % dict.__str__(self)
    +
    +    def __repr__(self):
    +        if not self.key: return str(self.keys())
    +        s = '%s' % self.key[0]
    +        if self.keys():
    +            s += ' {'
    +            for k, t in self.items():
    +                is_list = False
    +                if isinstance(t, list):
    +                    is_list = True
    +                    t = t[0]
    +                if isinstance(t, type):
    +                    t = t.__name__
    +                    pass
    +                elif isinstance(t, Alias):
    +                    t = t.xml_type
    +                elif isinstance(t, Struct):
    +                    t = t.key[0]
    +                if is_list:
    +                    t = [t]
    +                s += '%s: %s, ' % (k, t)
    +            s = s[:-2]+'}'
    +        return s
    diff --git a/web2py/gluon/contrib/pysimplesoap/plugins.py b/web2py/gluon/contrib/pysimplesoap/plugins.py
    new file mode 100644
    index 0000000..b08daaa
    --- /dev/null
    +++ b/web2py/gluon/contrib/pysimplesoap/plugins.py
    @@ -0,0 +1,39 @@
    +#!/usr/bin/python
    +# -*- coding: utf-8 -*-
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU Lesser General Public License as published by
    +# the Free Software Foundation; either version 3, or (at your option) any
    +# later version.
    +#
    +# This program is distributed in the hope that it will be useful, but
    +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
    +# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    +# for more details.
    +
    +"""Pythonic simple SOAP Client plugins"""
    +
    +
    +from __future__ import unicode_literals
    +import sys
    +if sys.version > '3':
    +    basestring = unicode = str
    +
    +import datetime
    +from decimal import Decimal
    +import os
    +import logging
    +import hashlib
    +import warnings
    +
    +
    +from . import __author__, __copyright__, __license__, __version__
    +
    +
    +class WSSE:
    +
    +    def preprocess(self, request):
    +        header = request('Header')
    +        
    +    
    +    def postprocess(response):
    +        return response
    diff --git a/web2py/gluon/contrib/pysimplesoap/server.py b/web2py/gluon/contrib/pysimplesoap/server.py
    new file mode 100644
    index 0000000..ede3908
    --- /dev/null
    +++ b/web2py/gluon/contrib/pysimplesoap/server.py
    @@ -0,0 +1,624 @@
    +#!/usr/bin/python
    +# -*- coding: utf-8 -*-
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU Lesser General Public License as published by the
    +# Free Software Foundation; either version 3, or (at your option) any later
    +# version.
    +#
    +# This program is distributed in the hope that it will be useful, but
    +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    +# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    +# for more details.
    +
    +"""Pythonic simple SOAP Server implementation"""
    +
    +
    +from __future__ import unicode_literals
    +import sys
    +if sys.version > '3':
    +    unicode = str
    +
    +
    +import datetime
    +import sys
    +import logging
    +import warnings
    +import re
    +import traceback
    +try:
    +    from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
    +except ImportError:
    +    from http.server import BaseHTTPRequestHandler, HTTPServer
    +
    +from . import __author__, __copyright__, __license__, __version__
    +from .simplexml import SimpleXMLElement, TYPE_MAP, Date, Decimal
    +
    +log = logging.getLogger(__name__)
    +
    +# Deprecated?
    +NS_RX = re.compile(r'xmlns:(\w+)="(.+?)"')
    +
    +
    +class SoapFault(Exception):
    +    def __init__(self, faultcode=None, faultstring=None, detail=None):
    +        self.faultcode = faultcode or self.__class__.__name__
    +        self.faultstring = faultstring or ''
    +        self.detail = detail
    +
    +
    +class SoapDispatcher(object):
    +    """Simple Dispatcher for SOAP Server"""
    +
    +    def __init__(self, name, documentation='', action='', location='',
    +                 namespace=None, prefix=False,
    +                 soap_uri="http://schemas.xmlsoap.org/soap/envelope/",
    +                 soap_ns='soap',
    +                 namespaces={},
    +                 pretty=False,
    +                 debug=False,
    +                 **kwargs):
    +        """
    +        :param namespace: Target namespace; xmlns=targetNamespace
    +        :param prefix: Prefix for target namespace; xmlns:prefix=targetNamespace
    +        :param namespaces: Specify additional namespaces; example: {'external': 'http://external.mt.moboperator'}
    +        :param pretty: Prettifies generated xmls
    +        :param debug: Use to add tracebacks in generated xmls.
    +
    +        Multiple namespaces
    +        ===================
    +
    +        It is possible to support multiple namespaces.
    +        You need to specify additional namespaces by passing `namespace` parameter.
    +
    +        >>> dispatcher = SoapDispatcher(
    +        ...    name = "MTClientWS",
    +        ...    location = "http://localhost:8008/ws/MTClientWS",
    +        ...    action = 'http://localhost:8008/ws/MTClientWS', # SOAPAction
    +        ...    namespace = "http://external.mt.moboperator", prefix="external",
    +        ...    documentation = 'moboperator MTClientWS',
    +        ...    namespaces = {
    +        ...        'external': 'http://external.mt.moboperator',
    +        ...        'model': 'http://model.common.mt.moboperator'
    +        ...    },
    +        ...    ns = True)
    +
    +        Now the registered method must return node names with namespaces' prefixes.
    +
    +        >>> def _multi_ns_func(self, serviceMsisdn):
    +        ...    ret = {
    +        ...        'external:activateSubscriptionsReturn': [
    +        ...            {'model:code': '0'},
    +        ...            {'model:description': 'desc'},
    +        ...        ]}
    +        ...    return ret
    +
    +        Our prefixes will be changed to those used by the client.
    +        """
    +        self.methods = {}
    +        self.name = name
    +        self.documentation = documentation
    +        self.action = action  # base SoapAction
    +        self.location = location
    +        self.namespace = namespace  # targetNamespace
    +        self.prefix = prefix
    +        self.soap_ns = soap_ns
    +        self.soap_uri = soap_uri
    +        self.namespaces = namespaces
    +        self.pretty = pretty
    +        self.debug = debug
    +
    +    @staticmethod
    +    def _extra_namespaces(xml, ns):
    +        """Extends xml with extra namespaces.
    +        :param ns: dict with namespaceUrl:prefix pairs
    +        :param xml: XML node to modify
    +        """
    +        if ns:
    +            _tpl = 'xmlns:%s="%s"'
    +            _ns_str = " ".join([_tpl % (prefix, uri) for uri, prefix in ns.items() if uri not in xml])
    +            xml = xml.replace('/>', ' ' + _ns_str + '/>')
    +        return xml
    +
    +    def register_function(self, name, fn, returns=None, args=None, doc=None, response_element_name=None):
    +        self.methods[name] = fn, returns, args, doc or getattr(fn, "__doc__", ""), response_element_name or '%sResponse' % name
    +
    +    def response_element_name(self, method):
    +        return self.methods[method][4]
    +
    +    def dispatch(self, xml, action=None, fault=None):
    +        """Receive and process SOAP call, returns the xml"""
    +        # a dict can be sent in fault to expose it to the caller
    +        # default values:
    +        prefix = self.prefix
    +        ret = None
    +        if fault is None:
    +            fault = {}
    +        soap_ns, soap_uri = self.soap_ns, self.soap_uri
    +        soap_fault_code = 'VersionMismatch'
    +        name = None
    +
    +        # namespaces = [('model', 'http://model.common.mt.moboperator'), ('external', 'http://external.mt.moboperator')]
    +        _ns_reversed = dict(((v, k) for k, v in self.namespaces.items()))  # Switch keys-values
    +        # _ns_reversed = {'http://external.mt.moboperator': 'external', 'http://model.common.mt.moboperator': 'model'}
    +
    +        try:
    +            request = SimpleXMLElement(xml, namespace=self.namespace)
    +
    +            # detect soap prefix and uri (xmlns attributes of Envelope)
    +            for k, v in request[:]:
    +                if v in ("http://schemas.xmlsoap.org/soap/envelope/",
    +                         "http://www.w3.org/2003/05/soap-env",
    +                         "http://www.w3.org/2003/05/soap-envelope",):
    +                    soap_ns = request.attributes()[k].localName
    +                    soap_uri = request.attributes()[k].value
    +
    +                # If the value from attributes on Envelope is in additional namespaces
    +                elif v in self.namespaces.values():
    +                    _ns = request.attributes()[k].localName
    +                    _uri = request.attributes()[k].value
    +                    _ns_reversed[_uri] = _ns  # update with received alias
    +                    # Now we change 'external' and 'model' to the received forms i.e. 'ext' and 'mod'
    +                # After that we know how the client has prefixed additional namespaces
    +
    +            ns = NS_RX.findall(xml)
    +            for k, v in ns:
    +                if v in self.namespaces.values():
    +                    _ns_reversed[v] = k
    +
    +            soap_fault_code = 'Client'
    +
    +            # parse request message and get local method
    +            method = request('Body', ns=soap_uri).children()(0)
    +            if action:
    +                # method name = action
    +                name = action[len(self.action)+1:-1]
    +                prefix = self.prefix
    +            if not action or not name:
    +                # method name = input message name
    +                name = method.get_local_name()
    +                prefix = method.get_prefix()
    +
    +            log.debug('dispatch method: %s', name)
    +            function, returns_types, args_types, doc, response_element_name = self.methods[name]
    +            log.debug('returns_types %s', returns_types)
    +
    +            # de-serialize parameters (if type definitions given)
    +            if args_types:
    +                args = method.children().unmarshall(args_types)
    +            elif args_types is None:
    +                args = {'request': method}  # send raw request
    +            else:
    +                args = {}  # no parameters
    +
    +            soap_fault_code = 'Server'
    +            # execute function
    +            ret = function(**args)
    +            log.debug('dispathed method returns: %s', ret)
    +
    +        except SoapFault as e:
    +            fault.update({
    +                'faultcode': "%s.%s" % (soap_fault_code, e.faultcode),
    +                'faultstring': e.faultstring,
    +                'detail': e.detail
    +            })
    +
    +        except Exception:  # This shouldn't be one huge try/except
    +            import sys
    +            etype, evalue, etb = sys.exc_info()
    +            log.error(traceback.format_exc())
    +            if self.debug:
    +                detail = u''.join(traceback.format_exception(etype, evalue, etb))
    +                detail += u'\n\nXML REQUEST\n\n' + xml.decode('UTF-8')
    +            else:
    +                detail = None
    +            fault.update({'faultcode': "%s.%s" % (soap_fault_code, etype.__name__),
    +                     'faultstring': evalue,
    +                     'detail': detail})
    +
    +        # build response message
    +        if not prefix:
    +            xml = """<%(soap_ns)s:Envelope xmlns:%(soap_ns)s="%(soap_uri)s"/>"""
    +        else:
    +            xml = """<%(soap_ns)s:Envelope xmlns:%(soap_ns)s="%(soap_uri)s"
    +                       xmlns:%(prefix)s="%(namespace)s"/>"""
    +
    +        xml %= {    # a %= {} is a shortcut for a = a % {}
    +            'namespace': self.namespace,
    +            'prefix': prefix,
    +            'soap_ns': soap_ns,
    +            'soap_uri': soap_uri
    +        }
    +
    +        # Now we add extra namespaces
    +        xml = SoapDispatcher._extra_namespaces(xml, _ns_reversed)
    +
    +        # Change our namespace alias to that given by the client.
    +        # We put [('model', 'http://model.common.mt.moboperator'), ('external', 'http://external.mt.moboperator')]
    +        # mix it with {'http://external.mt.moboperator': 'ext', 'http://model.common.mt.moboperator': 'mod'}
    +        mapping = dict(((k, _ns_reversed[v]) for k, v in self.namespaces.items()))  # Switch keys-values and change value
    +        # and get {'model': u'mod', 'external': u'ext'}
    +
    +        response = SimpleXMLElement(xml,
    +                                    namespace=self.namespace,
    +                                    namespaces_map=mapping,
    +                                    prefix=prefix)
    +
    +        response['xmlns:xsi'] = "http://www.w3.org/2001/XMLSchema-instance"
    +        response['xmlns:xsd'] = "http://www.w3.org/2001/XMLSchema"
    +
    +        body = response.add_child("%s:Body" % soap_ns, ns=False)
    +
    +        if fault:
    +            # generate a Soap Fault (with the python exception)
    +            body.marshall("%s:Fault" % soap_ns, fault, ns=False)
    +        else:
    +            # return normal value
    +            res = body.add_child(self.response_element_name(name), ns=self.namespace)
    +            if not prefix:
    +                res['xmlns'] = self.namespace  # add target namespace
    +
    +            # serialize returned values (response) if type definition available
    +            if returns_types:
    +                # TODO: full sanity check of type structure (recursive)
    +                complex_type = isinstance(ret, dict)
    +                if complex_type:
    +                    # check if type mapping correlates with return value
    +                    types_ok = all([k in returns_types for k in ret.keys()])
    +                    if not types_ok:
    +                        warnings.warn("Return value doesn't match type structure: "
    +                                     "%s vs %s" % (str(returns_types), str(ret)))
    +                if not complex_type or not types_ok:
    +                    # backward compatibility for scalar and simple types
    +                    res.marshall(list(returns_types.keys())[0], ret, )
    +                else:
    +                    # new style for complex classes
    +                    for k, v in ret.items():
    +                        res.marshall(k, v)
    +            elif returns_types is None:
    +                # merge xmlelement returned
    +                res.import_node(ret)
    +            elif returns_types == {}:
    +                log.warning('Given returns_types is an empty dict.')
    +
    +        return response.as_xml(pretty=self.pretty)
    +
    +    # Introspection functions:
    +
    +    def list_methods(self):
    +        """Return a list of aregistered operations"""
    +        return [(method, doc) for method, (function, returns, args, doc, response_element_name) in self.methods.items()]
    +
    +    def help(self, method=None):
    +        """Generate sample request and response messages"""
    +        (function, returns, args, doc, response_element_name) = self.methods[method]
    +        xml = """
    +
    +<%(method)s xmlns="%(namespace)s"/>
    +""" % {'method': method, 'namespace': self.namespace}
    +        request = SimpleXMLElement(xml, namespace=self.namespace, prefix=self.prefix)
    +        if args:
    +            items = args.items()
    +        elif args is None:
    +            items = [('value', None)]
    +        else:
    +            items = []
    +        for k, v in items:
    +            request(method).marshall(k, v, add_comments=True, ns=False)
    +
    +        xml = """
    +
    +<%(response_element_name)s xmlns="%(namespace)s"/>
    +""" % {'response_element_name': response_element_name, 'namespace': self.namespace}
    +        response = SimpleXMLElement(xml, namespace=self.namespace, prefix=self.prefix)
    +        if returns:
    +            items = returns.items()
    +        elif args is None:
    +            items = [('value', None)]
    +        else:
    +            items = []
    +        for k, v in items:
    +            response(response_element_name).marshall(k, v, add_comments=True, ns=False)
    +
    +        return request.as_xml(pretty=True), response.as_xml(pretty=True), doc
    +
    +    def wsdl(self):
    +        """Generate Web Service Description v1.1"""
    +        xml = """
    +
    +    %(documentation)s
    +
    +    
    +       
    +       
    +    
    +
    +
    +""" % {'namespace': self.namespace, 'name': self.name, 'documentation': self.documentation}
    +        wsdl = SimpleXMLElement(xml)
    +
    +        for method, (function, returns, args, doc, response_element_name) in self.methods.items():
    +            # create elements:
    +
    +            def parse_element(name, values, array=False, complex=False):
    +                if not complex:
    +                    element = wsdl('wsdl:types')('xsd:schema').add_child('xsd:element')
    +                    complex = element.add_child("xsd:complexType")
    +                else:
    +                    complex = wsdl('wsdl:types')('xsd:schema').add_child('xsd:complexType')
    +                    element = complex
    +                element['name'] = name
    +                if values:
    +                    items = values
    +                elif values is None:
    +                    items = [('value', None)]
    +                else:
    +                    items = []
    +                if not array and items:
    +                    all = complex.add_child("xsd:all")
    +                elif items:
    +                    all = complex.add_child("xsd:sequence")
    +                for k, v in items:
    +                    e = all.add_child("xsd:element")
    +                    e['name'] = k
    +                    if array:
    +                        e[:] = {'minOccurs': "0", 'maxOccurs': "unbounded"}
    +                    if v in TYPE_MAP.keys():
    +                        t = 'xsd:%s' % TYPE_MAP[v]
    +                    elif v is None:
    +                        t = 'xsd:anyType'
    +                    elif isinstance(v, list):
    +                        n = "ArrayOf%s%s" % (name, k)
    +                        l = []
    +                        for d in v:
    +                            l.extend(d.items())
    +                        parse_element(n, l, array=True, complex=True)
    +                        t = "tns:%s" % n
    +                    elif isinstance(v, dict):
    +                        n = "%s%s" % (name, k)
    +                        parse_element(n, v.items(), complex=True)
    +                        t = "tns:%s" % n
    +                    else:
    +                        raise TypeError("unknonw type %s for marshalling" % str(v))
    +                    e.add_attribute('type', t)
    +
    +            parse_element("%s" % method, args and args.items())
    +            parse_element(response_element_name, returns and returns.items())
    +
    +            # create messages:
    +            for m, e in ('Input', method), ('Output', response_element_name):
    +                message = wsdl.add_child('wsdl:message')
    +                message['name'] = "%s%s" % (method, m)
    +                part = message.add_child("wsdl:part")
    +                part[:] = {'name': 'parameters',
    +                           'element': 'tns:%s' % e}
    +
    +        # create ports
    +        portType = wsdl.add_child('wsdl:portType')
    +        portType['name'] = "%sPortType" % self.name
    +        for method, (function, returns, args, doc, response_element_name) in self.methods.items():
    +            op = portType.add_child('wsdl:operation')
    +            op['name'] = method
    +            if doc:
    +                op.add_child("wsdl:documentation", doc)
    +            input = op.add_child("wsdl:input")
    +            input['message'] = "tns:%sInput" % method
    +            output = op.add_child("wsdl:output")
    +            output['message'] = "tns:%sOutput" % method
    +
    +        # create bindings
    +        binding = wsdl.add_child('wsdl:binding')
    +        binding['name'] = "%sBinding" % self.name
    +        binding['type'] = "tns:%sPortType" % self.name
    +        soapbinding = binding.add_child('soap:binding')
    +        soapbinding['style'] = "document"
    +        soapbinding['transport'] = "http://schemas.xmlsoap.org/soap/http"
    +        for method in self.methods.keys():
    +            op = binding.add_child('wsdl:operation')
    +            op['name'] = method
    +            soapop = op.add_child('soap:operation')
    +            soapop['soapAction'] = self.action + method
    +            soapop['style'] = 'document'
    +            input = op.add_child("wsdl:input")
    +            ##input.add_attribute('name', "%sInput" % method)
    +            soapbody = input.add_child("soap:body")
    +            soapbody["use"] = "literal"
    +            output = op.add_child("wsdl:output")
    +            ##output.add_attribute('name', "%sOutput" % method)
    +            soapbody = output.add_child("soap:body")
    +            soapbody["use"] = "literal"
    +
    +        service = wsdl.add_child('wsdl:service')
    +        service["name"] = "%sService" % self.name
    +        service.add_child('wsdl:documentation', text=self.documentation)
    +        port = service.add_child('wsdl:port')
    +        port["name"] = "%s" % self.name
    +        port["binding"] = "tns:%sBinding" % self.name
    +        soapaddress = port.add_child('soap:address')
    +        soapaddress["location"] = self.location
    +        return wsdl.as_xml(pretty=True)
    +
    +
    +class SOAPHandler(BaseHTTPRequestHandler):
    +
    +    def do_GET(self):
    +        """User viewable help information and wsdl"""
    +        args = self.path[1:].split("?")
    +        if self.path != "/" and args[0] not in self.server.dispatcher.methods.keys():
    +            self.send_error(404, "Method not found: %s" % args[0])
    +        else:
    +            if self.path == "/":
    +                # return wsdl if no method supplied
    +                response = self.server.dispatcher.wsdl()
    +            else:
    +                # return supplied method help (?request or ?response messages)
    +                req, res, doc = self.server.dispatcher.help(args[0])
    +                if len(args) == 1 or args[1] == "request":
    +                    response = req
    +                else:
    +                    response = res
    +            self.send_response(200)
    +            self.send_header("Content-type", "text/xml")
    +            self.end_headers()
    +            self.wfile.write(response)
    +
    +    def do_POST(self):
    +        """SOAP POST gateway"""
    +        request = self.rfile.read(int(self.headers.get('content-length')))
    +        # convert xml request to unicode (according to request headers)
    +        if sys.version < '3':
    +            encoding = self.headers.getparam("charset")
    +        else:
    +            encoding = self.headers.get_param("charset")
    +        request = request.decode(encoding)
    +        fault = {}
    +        # execute the method
    +        response = self.server.dispatcher.dispatch(request, fault=fault)
    +        # check if fault dict was completed (faultcode, faultstring, detail)
    +        if fault:
    +            self.send_response(500)
    +        else:
    +            self.send_response(200)
    +        self.send_header("Content-type", "text/xml")
    +        self.end_headers()
    +        self.wfile.write(response)
    +
    +
    +class WSGISOAPHandler(object):
    +
    +    def __init__(self, dispatcher):
    +        self.dispatcher = dispatcher
    +
    +    def __call__(self, environ, start_response):
    +        return self.handler(environ, start_response)
    +
    +    def handler(self, environ, start_response):
    +        if environ['REQUEST_METHOD'] == 'GET':
    +            return self.do_get(environ, start_response)
    +        elif environ['REQUEST_METHOD'] == 'POST':
    +            return self.do_post(environ, start_response)
    +        else:
    +            start_response('405 Method not allowed', [('Content-Type', 'text/plain')])
    +            return ['Method not allowed']
    +
    +    def do_get(self, environ, start_response):
    +        path = environ.get('PATH_INFO').lstrip('/')
    +        query = environ.get('QUERY_STRING')
    +        if path != "" and path not in self.dispatcher.methods.keys():
    +            start_response('404 Not Found', [('Content-Type', 'text/plain')])
    +            return ["Method not found: %s" % path]
    +        elif path == "":
    +            # return wsdl if no method supplied
    +            response = self.dispatcher.wsdl()
    +        else:
    +            # return supplied method help (?request or ?response messages)
    +            req, res, doc = self.dispatcher.help(path)
    +            if len(query) == 0 or query == "request":
    +                response = req
    +            else:
    +                response = res
    +        start_response('200 OK', [('Content-Type', 'text/xml'), ('Content-Length', str(len(response)))])
    +        return [response]
    +
    +    def do_post(self, environ, start_response):
    +        length = int(environ['CONTENT_LENGTH'])
    +        request = environ['wsgi.input'].read(length)
    +        response = self.dispatcher.dispatch(request)
    +        start_response('200 OK', [('Content-Type', 'text/xml'), ('Content-Length', str(len(response)))])
    +        return [response]
    +
    +
    +if __name__ == "__main__":
    +
    +    dispatcher = SoapDispatcher(
    +        name="PySimpleSoapSample",
    +        location="http://localhost:8008/",
    +        action='http://localhost:8008/',  # SOAPAction
    +        namespace="http://example.com/pysimplesoapsamle/", prefix="ns0",
    +        documentation='Example soap service using PySimpleSoap',
    +        trace=True, debug=True,
    +        ns=True)
    +
    +    def adder(p, c, dt=None):
    +        """Add several values"""
    +        dt = dt + datetime.timedelta(365)
    +        return {'ab': p['a'] + p['b'], 'dd': c[0]['d'] + c[1]['d'], 'dt': dt}
    +
    +    def dummy(in0):
    +        """Just return input"""
    +        return in0
    +
    +    def echo(request):
    +        """Copy request->response (generic, any type)"""
    +        return request.value
    +
    +    dispatcher.register_function(
    +        'Adder', adder,
    +        returns={'AddResult': {'ab': int, 'dd': unicode, 'dt': datetime.date}},
    +        args={'p': {'a': int, 'b': int}, 'dt': Date, 'c': [{'d': Decimal}]}
    +    )
    +
    +    dispatcher.register_function(
    +        'Dummy', dummy,
    +        returns={'out0': str},
    +        args={'in0': str}
    +    )
    +
    +    dispatcher.register_function('Echo', echo)
    +
    +    if '--local' in sys.argv:
    +
    +        wsdl = dispatcher.wsdl()
    +
    +        for method, doc in dispatcher.list_methods():
    +            request, response, doc = dispatcher.help(method)
    +
    +    if '--serve' in sys.argv:
    +        log.info("Starting server...")
    +        httpd = HTTPServer(("", 8008), SOAPHandler)
    +        httpd.dispatcher = dispatcher
    +        httpd.serve_forever()
    +
    +    if '--wsgi-serve' in sys.argv:
    +        log.info("Starting wsgi server...")
    +        from wsgiref.simple_server import make_server
    +        application = WSGISOAPHandler(dispatcher)
    +        wsgid = make_server('', 8008, application)
    +        wsgid.serve_forever()
    +
    +    if '--consume' in sys.argv:
    +        from .client import SoapClient
    +        client = SoapClient(
    +            location="http://localhost:8008/",
    +            action='http://localhost:8008/',  # SOAPAction
    +            namespace="http://example.com/sample.wsdl",
    +            soap_ns='soap',
    +            trace=True,
    +            ns="ns0",
    +        )
    +        p = {'a': 1, 'b': 2}
    +        c = [{'d': '1.20'}, {'d': '2.01'}]
    +        response = client.Adder(p=p, dt='2010-07-24', c=c)
    +        result = response.AddResult
    +        log.info(int(result.ab))
    +        log.info(str(result.dd))
    +        
    +    if '--consume-wsdl' in sys.argv:
    +        from .client import SoapClient
    +        client = SoapClient(
    +            wsdl="http://localhost:8008/",
    +        )
    +        p = {'a': 1, 'b': 2}
    +        c = [{'d': '1.20'}, {'d': '2.01'}]
    +        dt = datetime.date.today()
    +        response = client.Adder(p=p, dt=dt, c=c)
    +        result = response['AddResult']
    +        log.info(int(result['ab']))
    +        log.info(str(result['dd']))
    +
    diff --git a/web2py/gluon/contrib/pysimplesoap/simplexml.py b/web2py/gluon/contrib/pysimplesoap/simplexml.py
    new file mode 100644
    index 0000000..e20ef6c
    --- /dev/null
    +++ b/web2py/gluon/contrib/pysimplesoap/simplexml.py
    @@ -0,0 +1,532 @@
    +#!/usr/bin/python
    +# -*- coding: utf-8 -*-
    +# This program is free software; you can redistribute it and/or modify
    +# it under the terms of the GNU Lesser General Public License as published by the
    +# Free Software Foundation; either version 3, or (at your option) any later
    +# version.
    +#
    +# This program is distributed in the hope that it will be useful, but
    +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    +# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    +# for more details.
    +
    +"""Simple XML manipulation"""
    +
    +
    +from __future__ import unicode_literals
    +import sys
    +if sys.version > '3':
    +    basestring = str
    +    unicode = str
    +
    +import logging
    +import re
    +import time
    +import xml.dom.minidom
    +
    +from . import __author__, __copyright__, __license__, __version__
    +
    +# Utility functions used for marshalling, moved aside for readability
    +from .helpers import TYPE_MAP, TYPE_MARSHAL_FN, TYPE_UNMARSHAL_FN, \
    +                     REVERSE_TYPE_MAP, Struct, Date, Decimal
    +
    +log = logging.getLogger(__name__)
    +
    +
    +class SimpleXMLElement(object):
    +    """Simple XML manipulation (simil PHP)"""
    +
    +    def __init__(self, text=None, elements=None, document=None,
    +                 namespace=None, prefix=None, namespaces_map={}, jetty=False):
    +        """
    +        :param namespaces_map: How to map our namespace prefix to that given by the client;
    +          {prefix: received_prefix}
    +        """
    +        self.__namespaces_map = namespaces_map
    +        _rx = "|".join(namespaces_map.keys())  # {'external': 'ext', 'model': 'mod'} -> 'external|model'
    +        self.__ns_rx = re.compile(r"^(%s):.*$" % _rx)  # And now we build an expression ^(external|model):.*$
    +                                                       # to find prefixes in all xml nodes i.e.: 1
    +                                                       # and later change that to 1
    +        self.__ns = namespace
    +        self.__prefix = prefix
    +        self.__jetty = jetty                           # special list support
    +
    +        if text is not None:
    +            try:
    +                self.__document = xml.dom.minidom.parseString(text)
    +            except:
    +                log.error(text)
    +                raise
    +            self.__elements = [self.__document.documentElement]
    +        else:
    +            self.__elements = elements
    +            self.__document = document
    +
    +    def add_child(self, name, text=None, ns=True):
    +        """Adding a child tag to a node"""
    +        if not ns or self.__ns is False:
    +            ##log.debug('adding %s without namespace', name)
    +            element = self.__document.createElement(name)
    +        else:
    +            ##log.debug('adding %s ns "%s" %s', name, self.__ns, ns)
    +            if isinstance(ns, basestring):
    +                element = self.__document.createElement(name)
    +                if ns:
    +                    element.setAttribute("xmlns", ns)
    +            elif self.__prefix:
    +                element = self.__document.createElementNS(self.__ns, "%s:%s" % (self.__prefix, name))
    +            else:
    +                element = self.__document.createElementNS(self.__ns, name)
    +        # don't append null tags!
    +        if text is not None:
    +            if isinstance(text, xml.dom.minidom.CDATASection):
    +                element.appendChild(self.__document.createCDATASection(text.data))
    +            else:
    +                element.appendChild(self.__document.createTextNode(text))
    +        self._element.appendChild(element)
    +        return SimpleXMLElement(
    +            elements=[element],
    +            document=self.__document,
    +            namespace=self.__ns,
    +            prefix=self.__prefix,
    +            jetty=self.__jetty,
    +            namespaces_map=self.__namespaces_map
    +        )
    +
    +    def __setattr__(self, tag, text):
    +        """Add text child tag node (short form)"""
    +        if tag.startswith("_"):
    +            object.__setattr__(self, tag, text)
    +        else:
    +            ##log.debug('__setattr__(%s, %s)', tag, text)
    +            self.add_child(tag, text)
    +
    +    def __delattr__(self, tag):
    +        """Remove a child tag (non recursive!)"""
    +        elements = [__element for __element in self._element.childNodes
    +                    if __element.nodeType == __element.ELEMENT_NODE]
    +        for element in elements:
    +            self._element.removeChild(element)
    +
    +    def add_comment(self, data):
    +        """Add an xml comment to this child"""
    +        comment = self.__document.createComment(data)
    +        self._element.appendChild(comment)
    +
    +    def as_xml(self, filename=None, pretty=False):
    +        """Return the XML representation of the document"""
    +        if not pretty:
    +            return self.__document.toxml('UTF-8')
    +        else:
    +            return self.__document.toprettyxml(encoding='UTF-8')
    +
    +    if sys.version > '3':
    +        def __repr__(self):
    +            """Return the XML representation of this tag"""
    +            return self._element.toxml()
    +    else:
    +        def __repr__(self):
    +            """Return the XML representation of this tag"""
    +            # NOTE: do not use self.as_xml('UTF-8') as it returns the whole xml doc
    +            return self._element.toxml('UTF-8')
    +
    +    def get_name(self):
    +        """Return the tag name of this node"""
    +        return self._element.tagName
    +
    +    def get_local_name(self):
    +        """Return the tag local name (prefix:name) of this node"""
    +        return self._element.localName
    +
    +    def get_prefix(self):
    +        """Return the namespace prefix of this node"""
    +        return self._element.prefix
    +
    +    def get_namespace_uri(self, ns):
    +        """Return the namespace uri for a prefix"""
    +        element = self._element
    +        while element is not None and element.attributes is not None:
    +            try:
    +                return element.attributes['xmlns:%s' % ns].value
    +            except KeyError:
    +                element = element.parentNode
    +
    +    def attributes(self):
    +        """Return a dict of attributes for this tag"""
    +        #TODO: use slice syntax [:]?
    +        return self._element.attributes
    +
    +    def __getitem__(self, item):
    +        """Return xml tag attribute value or a slice of attributes (iter)"""
    +        ##log.debug('__getitem__(%s)', item)
    +        if isinstance(item, basestring):
    +            if self._element.hasAttribute(item):
    +                return self._element.attributes[item].value
    +        elif isinstance(item, slice):
    +            # return a list with name:values
    +            return list(self._element.attributes.items())[item]
    +        else:
    +            # return element by index (position)
    +            element = self.__elements[item]
    +            return SimpleXMLElement(
    +                elements=[element],
    +                document=self.__document,
    +                namespace=self.__ns,
    +                prefix=self.__prefix,
    +                jetty=self.__jetty,
    +                namespaces_map=self.__namespaces_map
    +            )
    +
    +    def add_attribute(self, name, value):
    +        """Set an attribute value from a string"""
    +        self._element.setAttribute(name, value)
    +
    +    def __setitem__(self, item, value):
    +        """Set an attribute value"""
    +        if isinstance(item, basestring):
    +            self.add_attribute(item, value)
    +        elif isinstance(item, slice):
    +            # set multiple attributes at once
    +            for k, v in value.items():
    +                self.add_attribute(k, v)
    +
    +    def __delitem__(self, item):
    +        "Remove an attribute"
    +        self._element.removeAttribute(item)
    +
    +    def __call__(self, tag=None, ns=None, children=False, root=False,
    +                 error=True, ):
    +        """Search (even in child nodes) and return a child tag by name"""
    +        try:
    +            if root:
    +                # return entire document
    +                return SimpleXMLElement(
    +                    elements=[self.__document.documentElement],
    +                    document=self.__document,
    +                    namespace=self.__ns,
    +                    prefix=self.__prefix,
    +                    jetty=self.__jetty,
    +                    namespaces_map=self.__namespaces_map
    +                )
    +            if tag is None:
    +                # if no name given, iterate over siblings (same level)
    +                return self.__iter__()
    +            if children:
    +                # future: filter children? by ns?
    +                return self.children()
    +            elements = None
    +            if isinstance(tag, int):
    +                # return tag by index
    +                elements = [self.__elements[tag]]
    +            if ns and not elements:
    +                for ns_uri in isinstance(ns, (tuple, list)) and ns or (ns, ):
    +                    ##log.debug('searching %s by ns=%s', tag, ns_uri)
    +                    elements = self._element.getElementsByTagNameNS(ns_uri, tag)
    +                    if elements:
    +                        break
    +            if self.__ns and not elements:
    +                ##log.debug('searching %s by ns=%s', tag, self.__ns)
    +                elements = self._element.getElementsByTagNameNS(self.__ns, tag)
    +            if not elements:
    +                ##log.debug('searching %s', tag)
    +                elements = self._element.getElementsByTagName(tag)
    +            if not elements:
    +                ##log.debug(self._element.toxml())
    +                if error:
    +                    raise AttributeError("No elements found")
    +                else:
    +                    return
    +            return SimpleXMLElement(
    +                elements=elements,
    +                document=self.__document,
    +                namespace=self.__ns,
    +                prefix=self.__prefix,
    +                jetty=self.__jetty,
    +                namespaces_map=self.__namespaces_map)
    +        except AttributeError as e:
    +            raise AttributeError("Tag not found: %s (%s)" % (tag, e))
    +
    +    def __getattr__(self, tag):
    +        """Shortcut for __call__"""
    +        return self.__call__(tag)
    +
    +    def __iter__(self):
    +        """Iterate over xml tags at this level"""
    +        try:
    +            for __element in self.__elements:
    +                yield SimpleXMLElement(
    +                    elements=[__element],
    +                    document=self.__document,
    +                    namespace=self.__ns,
    +                    prefix=self.__prefix,
    +                    jetty=self.__jetty,
    +                    namespaces_map=self.__namespaces_map)
    +        except:
    +            raise
    +
    +    def __dir__(self):
    +        """List xml children tags names"""
    +        return [node.tagName for node
    +                in self._element.childNodes
    +                if node.nodeType != node.TEXT_NODE]
    +
    +    def children(self):
    +        """Return xml children tags element"""
    +        elements = [__element for __element in self._element.childNodes
    +                    if __element.nodeType == __element.ELEMENT_NODE]
    +        if not elements:
    +            return None
    +            #raise IndexError("Tag %s has no children" % self._element.tagName)
    +        return SimpleXMLElement(
    +            elements=elements,
    +            document=self.__document,
    +            namespace=self.__ns,
    +            prefix=self.__prefix,
    +            jetty=self.__jetty,
    +            namespaces_map=self.__namespaces_map
    +        )
    +
    +    def __len__(self):
    +        """Return element count"""
    +        return len(self.__elements)
    +
    +    def __contains__(self, item):
    +        """Search for a tag name in this element or child nodes"""
    +        return self._element.getElementsByTagName(item)
    +
    +    def __unicode__(self):
    +        """Returns the unicode text nodes of the current element"""
    +        rc = ''
    +        for node in self._element.childNodes:
    +            if node.nodeType == node.TEXT_NODE or node.nodeType == node.CDATA_SECTION_NODE:
    +                rc = rc + node.data
    +        return rc
    +
    +    if sys.version > '3':
    +        __str__ = __unicode__
    +    else:
    +        def __str__(self):
    +            return self.__unicode__().encode('utf-8')
    +
    +    def __int__(self):
    +        """Returns the integer value of the current element"""
    +        return int(self.__str__())
    +
    +    def __float__(self):
    +        """Returns the float value of the current element"""
    +        try:
    +            return float(self.__str__())
    +        except:
    +            raise IndexError(self._element.toxml())
    +
    +    _element = property(lambda self: self.__elements[0])
    +
    +    def unmarshall(self, types, strict=True):
    +        #import pdb; pdb.set_trace()
    +
    +        """Convert to python values the current serialized xml element"""
    +        # types is a dict of {tag name: conversion function}
    +        # strict=False to use default type conversion if not specified
    +        # example: types={'p': {'a': int,'b': int}, 'c': [{'d':str}]}
    +        #   expected xml: 

    12

    holachau + # returnde value: {'p': {'a':1,'b':2}, `'c':[{'d':'hola'},{'d':'chau'}]} + d = {} + for node in self(): + name = str(node.get_local_name()) + ref_name_type = None + # handle multirefs: href="#id0" + if 'href' in node.attributes().keys(): + href = node['href'][1:] + for ref_node in self(root=True)("multiRef"): + if ref_node['id'] == href: + node = ref_node + ref_name_type = ref_node['xsi:type'].split(":")[1] + break + + try: + if isinstance(types, dict): + fn = types[name] + # custom array only in the response (not defined in the WSDL): + # + fn = None + elif None in types: + # , return the SimpleXMLElement + # TODO: check position of None if inside + fn = None + elif strict: + raise TypeError("Tag: %s invalid (type not found)" % (name,)) + else: + # if not strict, use default type conversion + fn = str + + if isinstance(fn, list): + # append to existing list (if any) - unnested dict arrays - + value = d.setdefault(name, []) + # If the node has no children then the node itself might + # have multiple occurrences: + children = node.children() or node + # TODO: check if this was really needed (get first child only) + ##if len(fn[0]) == 1 and children: + ## children = children() + if fn and not isinstance(fn[0], dict): + # simple arrays [] + for child in (children or []): + tmp_dict = child.unmarshall(fn[0], strict) + value.extend(tmp_dict.values()) + #elif (self.__jetty and len(fn[0]) > 1): + elif (len(fn[0]) > 1): + # Jetty and now all dialects use array style support [{k, v}] + for parent in node: + tmp_dict = {} # unmarshall each value & mix + for child in (node.children() or []): + tmp_dict.update(child.unmarshall(fn[0], strict)) + value.append(tmp_dict) + else: # len(fn[0]) == 0 + for child in (children or []): + value.append(child.unmarshall(fn[0], strict)) + + elif isinstance(fn, tuple): + value = [] + _d = {} + children = node.children() + as_dict = len(fn) == 1 and isinstance(fn[0], dict) + + for child in (children and children() or []): # Readability counts + if as_dict: + _d.update(child.unmarshall(fn[0], strict)) # Merging pairs + else: + value.append(child.unmarshall(fn[0], strict)) + if as_dict: + value.append(_d) + + if name in d: + _tmp = list(d[name]) + _tmp.extend(value) + value = tuple(_tmp) + else: + value = tuple(value) + + elif isinstance(fn, dict): + ##if ref_name_type is not None: + ## fn = fn[ref_name_type] + children = node.children() + value = children and children.unmarshall(fn, strict) + else: + if fn is None: # xsd:anyType not unmarshalled + value = node + elif unicode(node) or (fn == str and unicode(node) != ''): + try: + # get special deserialization function (if any) + fn = TYPE_UNMARSHAL_FN.get(fn, fn) + if fn == str: + # always return an unicode object: + # (avoid encoding errors in py<3!) + value = unicode(node) + else: + value = fn(unicode(node)) + except (ValueError, TypeError) as e: + raise ValueError("Tag: %s: %s" % (name, e)) + else: + value = None + d[name] = value + return d + + def _update_ns(self, name): + """Replace the defined namespace alias with tohse used by the client.""" + pref = self.__ns_rx.search(name) + if pref: + pref = pref.groups()[0] + try: + name = name.replace(pref, self.__namespaces_map[pref]) + except KeyError: + log.warning('Unknown namespace alias %s' % name) + return name + + def marshall(self, name, value, add_child=True, add_comments=False, + ns=False, add_children_ns=True): + """Analyze python value and add the serialized XML element using tag name""" + # Change node name to that used by a client + name = self._update_ns(name) + + if isinstance(value, dict): # serialize dict (value) + # for the first parent node, use the document target namespace + # (ns==True) or use the namespace string uri if passed (elements) + child = add_child and self.add_child(name, ns=ns) or self + for k, v in value.items(): + if not add_children_ns: + ns = False + elif hasattr(value, 'namespaces'): + # for children, use the wsdl element target namespace: + ns = value.namespaces.get(k) + else: + # simple type + ns = None + child.marshall(k, v, add_comments=add_comments, ns=ns) + elif isinstance(value, tuple): # serialize tuple (value) + child = add_child and self.add_child(name, ns=ns) or self + if not add_children_ns: + ns = False + for k, v in value: + getattr(self, name).marshall(k, v, add_comments=add_comments, ns=ns) + elif isinstance(value, list): # serialize lists name: [value1, value2] + # list elements should be a dict with one element: + # 'vats': [{'vat': {'vat_amount': 50, 'vat_percent': 5}}, {...}] + # or an array of complex types directly (a.k.a. jetty dialect) + # 'vat': [{'vat_amount': 100, 'vat_percent': 21.0}, {...}] + child = self.add_child(name, ns=ns) + if not add_children_ns: + ns = False + if add_comments: + child.add_comment("Repetitive array of:") + for i, t in enumerate(value): + child.marshall(name, t, False, add_comments=add_comments, ns=ns) + # "jetty" arrays: add new base node (if not last) -see abobe- + # TODO: this could be an issue for some arrays of single values + if isinstance(t, dict) and len(t) > 1 and i < len(value) - 1: + child = self.add_child(name, ns=ns) + elif isinstance(value, (xml.dom.minidom.CDATASection, basestring)): # do not convert strings or unicodes + self.add_child(name, value, ns=ns) + elif value is None: # sent a empty tag? + self.add_child(name, ns=ns) + elif value in TYPE_MAP.keys(): + # add commented placeholders for simple tipes (for examples/help only) + child = self.add_child(name, ns=ns) + child.add_comment(TYPE_MAP[value]) + else: # the rest of object types are converted to string + # get special serialization function (if any) + fn = TYPE_MARSHAL_FN.get(type(value), str) + self.add_child(name, fn(value), ns=ns) + + def import_node(self, other): + x = self.__document.importNode(other._element, True) # deep copy + self._element.appendChild(x) + + def write_c14n(self, output=None, exclusive=True): + "Generate the canonical version of the XML node" + from . import c14n + xml = c14n.Canonicalize(self._element, output, + unsuppressedPrefixes=[] if exclusive else None) + return xml diff --git a/web2py/gluon/contrib/pysimplesoap/transport.py b/web2py/gluon/contrib/pysimplesoap/transport.py new file mode 100644 index 0000000..9c27fc5 --- /dev/null +++ b/web2py/gluon/contrib/pysimplesoap/transport.py @@ -0,0 +1,281 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. + +"""Pythonic simple SOAP Client transport""" + + +import logging +import ssl +import sys +try: + import urllib2 + from cookielib import CookieJar +except ImportError: + from urllib import request as urllib2 + from http.cookiejar import CookieJar + +from . import __author__, __copyright__, __license__, __version__, TIMEOUT +from .simplexml import SimpleXMLElement, TYPE_MAP, Struct + +log = logging.getLogger(__name__) + +# +# Socket wrapper to enable socket.TCP_NODELAY - this greatly speeds up transactions in Linux +# WARNING: this will modify the standard library socket module, use with care! +# TODO: implement this as a transport faciliy +# (to pass options directly to httplib2 or pycurl) +# be aware of metaclasses and socks.py (SocksiPy) used by httplib2 + +if False: + import socket + realsocket = socket.socket + def socketwrap(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0): + sockobj = realsocket(family, type, proto) + if type == socket.SOCK_STREAM: + sockobj.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + return sockobj + socket.socket = socketwrap + +# +# We store metadata about what available transport mechanisms we have available. +# +_http_connectors = {} # libname: classimpl mapping +_http_facilities = {} # functionalitylabel: [sequence of libname] mapping + + +class TransportBase: + @classmethod + def supports_feature(cls, feature_name): + return cls._wrapper_name in _http_facilities[feature_name] + +# +# httplib2 support. +# +try: + import httplib2 + if sys.version > '3' and httplib2.__version__ <= "0.7.7": + import http.client + # httplib2 workaround: check_hostname needs a SSL context with either + # CERT_OPTIONAL or CERT_REQUIRED + # see https://code.google.com/p/httplib2/issues/detail?id=173 + orig__init__ = http.client.HTTPSConnection.__init__ + def fixer(self, host, port, key_file, cert_file, timeout, context, + check_hostname, *args, **kwargs): + chk = kwargs.get('disable_ssl_certificate_validation', True) ^ True + orig__init__(self, host, port=port, key_file=key_file, + cert_file=cert_file, timeout=timeout, context=context, + check_hostname=chk) + http.client.HTTPSConnection.__init__ = fixer +except ImportError: + TIMEOUT = None # timeout not supported by urllib2 + pass +else: + class Httplib2Transport(httplib2.Http, TransportBase): + _wrapper_version = "httplib2 %s" % httplib2.__version__ + _wrapper_name = 'httplib2' + + def __init__(self, timeout, proxy=None, cacert=None, sessions=False): +# httplib2.debuglevel=4 + kwargs = {} + if proxy: + import socks + kwargs['proxy_info'] = httplib2.ProxyInfo(proxy_type=socks.PROXY_TYPE_HTTP, **proxy) + log.info("using proxy %s" % proxy) + + # set optional parameters according to supported httplib2 version + if httplib2.__version__ >= '0.3.0': + kwargs['timeout'] = timeout + if httplib2.__version__ >= '0.7.0': + kwargs['disable_ssl_certificate_validation'] = cacert is None + kwargs['ca_certs'] = cacert + httplib2.Http.__init__(self, **kwargs) + + _http_connectors['httplib2'] = Httplib2Transport + _http_facilities.setdefault('proxy', []).append('httplib2') + _http_facilities.setdefault('cacert', []).append('httplib2') + + import inspect + if 'timeout' in inspect.getargspec(httplib2.Http.__init__)[0]: + _http_facilities.setdefault('timeout', []).append('httplib2') + + +# +# urllib2 support. +# +class urllib2Transport(TransportBase): + _wrapper_version = "urllib2 %s" % urllib2.__version__ + _wrapper_name = 'urllib2' + + def __init__(self, timeout=None, proxy=None, cacert=None, sessions=False): + if (timeout is not None) and not self.supports_feature('timeout'): + raise RuntimeError('timeout is not supported with urllib2 transport') + if proxy: + raise RuntimeError('proxy is not supported with urllib2 transport') + if cacert: + raise RuntimeError('cacert is not support with urllib2 transport') + + handlers = [] + + if ((sys.version_info[0] == 2 and sys.version_info >= (2,7,9)) or + (sys.version_info[0] == 3 and sys.version_info >= (3,2,0))): + context = ssl.create_default_context() + context.check_hostname = False + context.verify_mode = ssl.CERT_NONE + handlers.append(urllib2.HTTPSHandler(context=context)) + + if sessions: + handlers.append(urllib2.HTTPCookieProcessor(CookieJar())) + + opener = urllib2.build_opener(*handlers) + self.request_opener = opener.open + self._timeout = timeout + + def request(self, url, method="GET", body=None, headers={}): + req = urllib2.Request(url, body, headers) + try: + f = self.request_opener(req, timeout=self._timeout) + return f.info(), f.read() + except urllib2.HTTPError as f: + if f.code != 500: + raise + return f.info(), f.read() + +_http_connectors['urllib2'] = urllib2Transport +_http_facilities.setdefault('sessions', []).append('urllib2') + +if sys.version_info >= (2, 6): + _http_facilities.setdefault('timeout', []).append('urllib2') + +# +# pycurl support. +# experimental: pycurl seems faster + better proxy support (NTLM) + ssl features +# +try: + import pycurl +except ImportError: + pass +else: + try: + from cStringIO import StringIO + except ImportError: + try: + from StringIO import StringIO + except ImportError: + from io import StringIO + + class pycurlTransport(TransportBase): + _wrapper_version = pycurl.version + _wrapper_name = 'pycurl' + + def __init__(self, timeout, proxy=None, cacert=None, sessions=False): + self.timeout = timeout + self.proxy = proxy or {} + self.cacert = cacert + + def request(self, url, method, body, headers): + c = pycurl.Curl() + c.setopt(pycurl.URL, url) + if 'proxy_host' in self.proxy: + c.setopt(pycurl.PROXY, self.proxy['proxy_host']) + if 'proxy_port' in self.proxy: + c.setopt(pycurl.PROXYPORT, self.proxy['proxy_port']) + if 'proxy_user' in self.proxy: + c.setopt(pycurl.PROXYUSERPWD, "%(proxy_user)s:%(proxy_pass)s" % self.proxy) + self.buf = StringIO() + c.setopt(pycurl.WRITEFUNCTION, self.buf.write) + #c.setopt(pycurl.READFUNCTION, self.read) + #self.body = StringIO(body) + #c.setopt(pycurl.HEADERFUNCTION, self.header) + if self.cacert: + c.setopt(c.CAINFO, self.cacert) + c.setopt(pycurl.SSL_VERIFYPEER, self.cacert and 1 or 0) + c.setopt(pycurl.SSL_VERIFYHOST, self.cacert and 2 or 0) + c.setopt(pycurl.CONNECTTIMEOUT, self.timeout) + c.setopt(pycurl.TIMEOUT, self.timeout) + if method == 'POST': + c.setopt(pycurl.POST, 1) + c.setopt(pycurl.POSTFIELDS, body) + if headers: + hdrs = ['%s: %s' % (k, v) for k, v in headers.items()] + log.debug(hdrs) + c.setopt(pycurl.HTTPHEADER, hdrs) + c.perform() + c.close() + return {}, self.buf.getvalue() + + _http_connectors['pycurl'] = pycurlTransport + _http_facilities.setdefault('proxy', []).append('pycurl') + _http_facilities.setdefault('cacert', []).append('pycurl') + _http_facilities.setdefault('timeout', []).append('pycurl') + + +class DummyTransport: + """Testing class to load a xml response""" + + def __init__(self, xml_response): + self.xml_response = xml_response + + def request(self, location, method, body, headers): + log.debug("%s %s", method, location) + log.debug(headers) + log.debug(body) + return {}, self.xml_response + + +def get_http_wrapper(library=None, features=[]): + # If we are asked for a specific library, return it. + if library is not None: + try: + return _http_connectors[library] + except KeyError: + raise RuntimeError('%s transport is not available' % (library,)) + + # If we haven't been asked for a specific feature either, then just return our favourite + # implementation. + if not features: + return _http_connectors.get('httplib2', _http_connectors['urllib2']) + + # If we are asked for a connector which supports the given features, then we will + # try that. + current_candidates = _http_connectors.keys() + new_candidates = [] + for feature in features: + for candidate in current_candidates: + if candidate in _http_facilities.get(feature, []): + new_candidates.append(candidate) + current_candidates = new_candidates + new_candidates = [] + + # Return the first candidate in the list. + try: + candidate_name = current_candidates[0] + except IndexError: + raise RuntimeError("no transport available which supports these features: %s" % (features,)) + else: + return _http_connectors[candidate_name] + + +def set_http_wrapper(library=None, features=[]): + """Set a suitable HTTP connection wrapper.""" + global Http + Http = get_http_wrapper(library, features) + return Http + + +def get_Http(): + """Return current transport class""" + global Http + return Http + + +# define the default HTTP connection class (it can be changed at runtime!): +set_http_wrapper() diff --git a/web2py/gluon/contrib/pysimplesoap/wsse.py b/web2py/gluon/contrib/pysimplesoap/wsse.py new file mode 100644 index 0000000..58044cf --- /dev/null +++ b/web2py/gluon/contrib/pysimplesoap/wsse.py @@ -0,0 +1,215 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) any +# later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. + +"""Pythonic simple SOAP Client plugins for WebService Security extensions""" + + +from __future__ import unicode_literals +import sys +if sys.version > '3': + basestring = unicode = str + +import datetime +from decimal import Decimal +import os +import logging +import hashlib +import warnings + +from . import __author__, __copyright__, __license__, __version__ +from .simplexml import SimpleXMLElement + +import random +import string +from hashlib import sha1 + +def randombytes(N): + return ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N)) + +# Namespaces: + +WSSE_URI = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' +WSU_URI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" +XMLDSIG_URI = "http://www.w3.org/2000/09/xmldsig#" +X509v3_URI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" +Base64Binary_URI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" +PasswordDigest_URI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest" + + +class UsernameToken: + "WebService Security extension to add a basic credentials to xml request" + + def __init__(self, username="", password=""): + self.token = { + 'wsse:UsernameToken': { + 'wsse:Username': username, + 'wsse:Password': password, + } + } + + def preprocess(self, client, request, method, args, kwargs, headers, soap_uri): + "Add basic credentials to outgoing message" + # always extract WS Security header and send it + header = request('Header', ns=soap_uri, ) + k = 'wsse:Security' + # for backward compatibility, use header if given: + if k in headers: + self.token = headers[k] + # convert the token to xml + header.marshall(k, self.token, ns=False, add_children_ns=False) + header(k)['xmlns:wsse'] = WSSE_URI + # + + def postprocess(self, client, response, method, args, kwargs, headers, soap_uri): + "Analyze incoming credentials" + # TODO: add some password validation callback? + pass + +class UsernameDigestToken(UsernameToken): + """ + WebService Security extension to add a http digest credentials to xml request + drift -> time difference from the server in seconds, needed for 'Created' header + """ + + def __init__(self, username="", password="", drift=0): + self.username = username + self.password = password + self.drift = datetime.timedelta(seconds=drift) + + def preprocess(self, client, request, method, args, kwargs, headers, soap_uri): + header = request('Header', ns=soap_uri, ) + wsse = header.add_child('wsse:Security', ns=False) + wsse['xmlns:wsse'] = WSSE_URI + wsse['xmlns:wsu'] = WSU_URI + + usertoken = wsse.add_child('wsse:UsernameToken', ns=False) + usertoken.add_child('wsse:Username', self.username, ns=False) + + created = (datetime.datetime.utcnow() + self.drift).isoformat() + 'Z' + usertoken.add_child('wsu:Created', created, ns=False) + + nonce = randombytes(16) + wssenonce = usertoken.add_child('wsse:Nonce', nonce.encode('base64')[:-1], ns=False) + wssenonce['EncodingType'] = Base64Binary_URI + + sha1obj = sha1() + sha1obj.update(nonce + created + self.password) + digest = sha1obj.digest() + password = usertoken.add_child('wsse:Password', digest.encode('base64')[:-1], ns=False) + password['Type'] = PasswordDigest_URI + + +BIN_TOKEN_TMPL = """ + + +%(certificate)s + + %(signed_info)s + %(signature_value)s + + + + + + + +""" + +class BinaryTokenSignature: + "WebService Security extension to add a basic signature to xml request" + + def __init__(self, certificate="", private_key="", password=None, cacert=None): + # read the X509v3 certificate (PEM) + self.certificate = ''.join([line for line in open(certificate) + if not line.startswith("---")]) + self.private_key = private_key + self.password = password + self.cacert = cacert + + def preprocess(self, client, request, method, args, kwargs, headers, soap_uri): + "Sign the outgoing SOAP request" + # get xml elements: + body = request('Body', ns=soap_uri, ) + header = request('Header', ns=soap_uri, ) + # prepare body xml attributes to be signed (reference) + body['wsu:Id'] = "id-14" + body['xmlns:wsu'] = WSU_URI + # workaround: copy namespaces so lxml can parse the xml to be signed + for attr, value in request[:]: + if attr.startswith("xmlns"): + body[attr] = value + # use the internal tag xml representation (not the full xml document) + ref_xml = repr(body) + # sign using RSA-SHA1 (XML Security) + from . import xmlsec + vars = xmlsec.rsa_sign(ref_xml, "#id-14", + self.private_key, self.password) + vars['certificate'] = self.certificate + # generate the xml (filling the placeholders) + wsse = SimpleXMLElement(BIN_TOKEN_TMPL % vars) + header.import_node(wsse) + + def postprocess(self, client, response, method, args, kwargs, headers, soap_uri): + "Verify the signature of the incoming response" + from . import xmlsec + # get xml elements: + body = response('Body', ns=soap_uri, ) + header = response('Header', ns=soap_uri, ) + wsse = header("Security", ns=WSSE_URI) + cert = wsse("BinarySecurityToken", ns=WSSE_URI) + # check that the cert (binary token) is coming in the correct format: + self.__check(cert["EncodingType"], Base64Binary_URI) + self.__check(cert["ValueType"], X509v3_URI) + # extract the certificate (in DER to avoid new line & padding issues!) + cert_der = str(cert).decode("base64") + public_key = xmlsec.x509_extract_rsa_public_key(cert_der, binary=True) + # validate the certificate using the certification authority: + if not self.cacert: + warnings.warn("No CA provided, WSSE not validating certificate") + elif not xmlsec.x509_verify(self.cacert, cert_der, binary=True): + raise RuntimeError("WSSE certificate validation failed") + # check body xml attributes was signed correctly (reference) + self.__check(body['xmlns:wsu'], WSU_URI) + ref_uri = body['wsu:Id'] + signature = wsse("Signature", ns=XMLDSIG_URI) + signed_info = signature("SignedInfo", ns=XMLDSIG_URI) + signature_value = signature("SignatureValue", ns=XMLDSIG_URI) + # TODO: these sanity checks should be moved to xmlsec? + self.__check(signed_info("Reference", ns=XMLDSIG_URI)['URI'], "#" + ref_uri) + self.__check(signed_info("SignatureMethod", ns=XMLDSIG_URI)['Algorithm'], + XMLDSIG_URI + "rsa-sha1") + self.__check(signed_info("Reference", ns=XMLDSIG_URI)("DigestMethod", ns=XMLDSIG_URI)['Algorithm'], + XMLDSIG_URI + "sha1") + # TODO: check KeyInfo uses the correct SecurityTokenReference + # workaround: copy namespaces so lxml can parse the xml to be signed + for attr, value in response[:]: + if attr.startswith("xmlns"): + body[attr] = value + # use the internal tag xml representation (not the full xml document) + ref_xml = xmlsec.canonicalize(repr(body)) + # verify the signed hash + computed_hash = xmlsec.sha1_hash_digest(ref_xml) + digest_value = str(signed_info("Reference", ns=XMLDSIG_URI)("DigestValue", ns=XMLDSIG_URI)) + if computed_hash != digest_value: + raise RuntimeError("WSSE SHA1 hash digests mismatch") + # workaround: prepare the signed info (assure the parent ns is present) + signed_info['xmlns'] = XMLDSIG_URI + xml = repr(signed_info) + # verify the signature using RSA-SHA1 (XML Security) + ok = xmlsec.rsa_verify(xml, str(signature_value), public_key) + if not ok: + raise RuntimeError("WSSE RSA-SHA1 signature verification failed") + # TODO: remove any unsigned part from the xml? + + def __check(self, value, expected, msg="WSSE sanity check failed"): + if value != expected: + raise RuntimeError(msg) diff --git a/web2py/gluon/contrib/pysimplesoap/xmlsec.py b/web2py/gluon/contrib/pysimplesoap/xmlsec.py new file mode 100644 index 0000000..2f96df7 --- /dev/null +++ b/web2py/gluon/contrib/pysimplesoap/xmlsec.py @@ -0,0 +1,220 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. + +"""Pythonic XML Security Library implementation""" +from __future__ import print_function +import base64 +import hashlib +import os +from cStringIO import StringIO +from M2Crypto import BIO, EVP, RSA, X509, m2 + +# if lxml is not installed, use c14n.py native implementation +try: + import lxml.etree +except ImportError: + lxml = None + +# Features: +# * Uses M2Crypto and lxml (libxml2) but it is independent from libxmlsec1 +# * Sign, Verify, Encrypt & Decrypt XML documents + +# Enveloping templates ("by reference": signature is parent): +SIGN_REF_TMPL = """ + + + + + + + + + %(digest_value)s + + +""" +SIGNED_TMPL = """ + + +%(signed_info)s +%(signature_value)s +%(key_info)s +%(ref_xml)s + +""" + +# Enveloped templates (signature is child, the reference is the root object): +SIGN_ENV_TMPL = """ + + + + + + + + + + %(digest_value)s + + +""" +SIGNATURE_TMPL = """ +%(signed_info)s +%(signature_value)s +%(key_info)s +""" + +KEY_INFO_RSA_TMPL = """ + + + + %(modulus)s + %(exponent)s + + + +""" + +KEY_INFO_X509_TMPL = """ + + + + %(issuer_name)s + %(serial_number)s + + + +""" + +def canonicalize(xml, c14n_exc=True): + "Return the canonical (c14n) form of the xml document for hashing" + # UTF8, normalization of line feeds/spaces, quoting, attribute ordering... + output = StringIO() + if lxml is not None: + # use faster libxml2 / lxml canonicalization function if available + et = lxml.etree.parse(StringIO(xml)) + et.write_c14n(output, exclusive=c14n_exc) + else: + # use pure-python implementation: c14n.py (avoid recursive import) + from .simplexml import SimpleXMLElement + SimpleXMLElement(xml).write_c14n(output, exclusive=c14n_exc) + return output.getvalue() + + +def sha1_hash_digest(payload): + "Create a SHA1 hash and return the base64 string" + return base64.b64encode(hashlib.sha1(payload).digest()) + + +def rsa_sign(xml, ref_uri, private_key, password=None, cert=None, c14n_exc=True, + sign_template=SIGN_REF_TMPL, key_info_template=KEY_INFO_RSA_TMPL): + "Sign an XML document usign RSA (templates: enveloped -ref- or enveloping)" + + # normalize the referenced xml (to compute the SHA1 hash) + ref_xml = canonicalize(xml, c14n_exc) + # create the signed xml normalized (with the referenced uri and hash value) + signed_info = sign_template % {'ref_uri': ref_uri, + 'digest_value': sha1_hash_digest(ref_xml)} + signed_info = canonicalize(signed_info, c14n_exc) + # Sign the SHA1 digest of the signed xml using RSA cipher + pkey = RSA.load_key(private_key, lambda *args, **kwargs: password) + signature = pkey.sign(hashlib.sha1(signed_info).digest()) + # build the mapping (placeholders) to create the final xml signed message + return { + 'ref_xml': ref_xml, 'ref_uri': ref_uri, + 'signed_info': signed_info, + 'signature_value': base64.b64encode(signature), + 'key_info': key_info(pkey, cert, key_info_template), + } + + +def rsa_verify(xml, signature, key, c14n_exc=True): + "Verify a XML document signature usign RSA-SHA1, return True if valid" + + # load the public key (from buffer or filename) + if key.startswith("-----BEGIN PUBLIC KEY-----"): + bio = BIO.MemoryBuffer(key) + rsa = RSA.load_pub_key_bio(bio) + else: + rsa = RSA.load_pub_key(certificate) + # create the digital envelope + pubkey = EVP.PKey() + pubkey.assign_rsa(rsa) + # do the cryptographic validation (using the default sha1 hash digest) + pubkey.reset_context(md='sha1') + pubkey.verify_init() + # normalize and feed the signed xml to be verified + pubkey.verify_update(canonicalize(xml, c14n_exc)) + ret = pubkey.verify_final(base64.b64decode(signature)) + return ret == 1 + + +def key_info(pkey, cert, key_info_template): + "Convert private key (PEM) to XML Signature format (RSAKeyValue/X509Data)" + exponent = base64.b64encode(pkey.e[4:]) + modulus = m2.bn_to_hex(m2.mpi_to_bn(pkey.n)).decode("hex").encode("base64") + x509 = x509_parse_cert(cert) if cert else None + return key_info_template % { + 'modulus': modulus, + 'exponent': exponent, + 'issuer_name': x509.get_issuer().as_text() if x509 else "", + 'serial_number': x509.get_serial_number() if x509 else "", + } + + +# Miscellaneous certificate utility functions: + + +def x509_parse_cert(cert, binary=False): + "Create a X509 certificate from binary DER, plain text PEM or filename" + if binary: + bio = BIO.MemoryBuffer(cert) + x509 = X509.load_cert_bio(bio, X509.FORMAT_DER) + elif cert.startswith("-----BEGIN CERTIFICATE-----"): + bio = BIO.MemoryBuffer(cert) + x509 = X509.load_cert_bio(bio, X509.FORMAT_PEM) + else: + x509 = X509.load_cert(cert, 1) + return x509 + + +def x509_extract_rsa_public_key(cert, binary=False): + "Return the public key (PEM format) from a X509 certificate" + x509 = x509_parse_cert(cert, binary) + return x509.get_pubkey().get_rsa().as_pem() + + +def x509_verify(cacert, cert, binary=False): + "Validate the certificate's authenticity using a certification authority" + ca = x509_parse_cert(cacert) + crt = x509_parse_cert(cert, binary) + return crt.verify(ca.get_pubkey()) + + +if __name__ == "__main__": + # basic test of enveloping signature (the reference is a part of the xml) + sample_xml = """data""" + output = canonicalize(sample_xml) + print (output) + vars = rsa_sign(sample_xml, '#object', "no_encriptada.key", "password") + print (SIGNED_TMPL % vars) + + # basic test of enveloped signature (the reference is the document itself) + sample_xml = """data%s""" + vars = rsa_sign(sample_xml % "", '', "no_encriptada.key", "password", + sign_template=SIGN_ENV_TMPL, c14n_exc=False) + print (sample_xml % (SIGNATURE_TMPL % vars)) + + # basic signature verification: + public_key = x509_extract_rsa_public_key(open("zunimercado.crt").read()) + assert rsa_verify(vars['signed_info'], vars['signature_value'], public_key, + c14n_exc=False) diff --git a/web2py/gluon/contrib/pyuca/LICENSE b/web2py/gluon/contrib/pyuca/LICENSE new file mode 100644 index 0000000..a52383b --- /dev/null +++ b/web2py/gluon/contrib/pyuca/LICENSE @@ -0,0 +1,19 @@ +# Copyright (c) 2006-2012 James Tauber and 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. \ No newline at end of file diff --git a/web2py/gluon/contrib/pyuca/README.markmin b/web2py/gluon/contrib/pyuca/README.markmin new file mode 100644 index 0000000..c146ccf --- /dev/null +++ b/web2py/gluon/contrib/pyuca/README.markmin @@ -0,0 +1,43 @@ +# pyuca: Python Unicode Collation Algorithm implementation +(http://jtauber.com/blog/2006/01/27/python_unicode_collation_algorithm/) + +This is my preliminary attempt at a Python implementation of the +[Unicode Collation Algorithm (UCA)](http://unicode.org/reports/tr10/). +I originally posted it to my blog in 2006 but it seems to get enough +usage it really belongs here (and in PyPI). + +What do you use it for? In short, sorting non-English strings properly. + +The core of the algorithm involves multi-level comparison. For example, +``café`` comes before ``caff`` because at the primary level, the accent +is ignored and the first word is treated as if it were ``cafe``. +The secondary level (which considers accents) only applies then to words +that are equivalent at the primary level. + +The Unicode Collation Algorithm and pyuca also support contraction and +expansion. **Contraction** is where multiple letters are treated as a +single unit. In Spanish, ``ch`` is treated as a letter coming between +``c`` and ``d`` so that, for example, words beginning ``ch`` should +sort after all other words beginnings with ``c``. **Expansion** is where +a single letter is treated as though it were multiple letters. In German, +``ä`` is sorted as if it were ``ae``, i.e. after ``ad`` but before ``af``. + +## Here is how to use the ``pyuca`` module: +`` +git clone https://github.com/jtauber/pyuca.git +cd pyuca +pip install pyuca +`` + +**Usage example:** +`` + from pyuca import Collator + c = Collator("allkeys.txt") + + sorted_words = sorted(words, key=c.sort_key) +`` + +``allkeys.txt`` (1 MB) is available at + +http://www.unicode.org/Public/UCA/latest/allkeys.txt + diff --git a/web2py/gluon/contrib/pyuca/__init__.py b/web2py/gluon/contrib/pyuca/__init__.py new file mode 100644 index 0000000..96d0619 --- /dev/null +++ b/web2py/gluon/contrib/pyuca/__init__.py @@ -0,0 +1,10 @@ +import os +import pyuca + +unicode_collator = None + +def set_unicode_collator(file): + global unicode_collator + unicode_collator = pyuca.Collator(file) + +set_unicode_collator(os.path.join(os.path.dirname(__file__), 'allkeys.txt')) diff --git a/web2py/gluon/contrib/pyuca/allkeys.txt b/web2py/gluon/contrib/pyuca/allkeys.txt new file mode 100644 index 0000000..a39ea3c --- /dev/null +++ b/web2py/gluon/contrib/pyuca/allkeys.txt @@ -0,0 +1,25141 @@ +# unidata-6.1.0.txt +# Date: 2011-12-06, 16:57:32 GMT [KW] +# +# This file defines the Default Unicode Collation Element Table +# (DUCET) for the Unicode Collation Algorithm +# +# Copyright (c) 2001-2011 Unicode, Inc. +# For terms of use, see http://www.unicode.org/terms_of_use.html +# +# See UTS #10, Unicode Collation Algorithm, for more information. +# +# Diagnostic weight ranges +# Primary weight range: 0200..430F (16656) +# Secondary weight range: 0020..0177 (344) +# Variant secondaries: 0139..013E (6) +# Digit secondaries: 013F..0177 (57) +# Tertiary weight range: 0002..001F (30) +# +@version 6.1.0 + +0000 ; [.0000.0000.0000.0000] # [0000] NULL (in 6429) +0001 ; [.0000.0000.0000.0000] # [0001] START OF HEADING (in 6429) +0002 ; [.0000.0000.0000.0000] # [0002] START OF TEXT (in 6429) +0003 ; [.0000.0000.0000.0000] # [0003] END OF TEXT (in 6429) +0004 ; [.0000.0000.0000.0000] # [0004] END OF TRANSMISSION (in 6429) +0005 ; [.0000.0000.0000.0000] # [0005] ENQUIRY (in 6429) +0006 ; [.0000.0000.0000.0000] # [0006] ACKNOWLEDGE (in 6429) +0007 ; [.0000.0000.0000.0000] # [0007] BELL (in 6429) +0008 ; [.0000.0000.0000.0000] # [0008] BACKSPACE (in 6429) +000E ; [.0000.0000.0000.0000] # [000E] SHIFT OUT (in 6429) +000F ; [.0000.0000.0000.0000] # [000F] SHIFT IN (in 6429) +0010 ; [.0000.0000.0000.0000] # [0010] DATA LINK ESCAPE (in 6429) +0011 ; [.0000.0000.0000.0000] # [0011] DEVICE CONTROL ONE (in 6429) +0012 ; [.0000.0000.0000.0000] # [0012] DEVICE CONTROL TWO (in 6429) +0013 ; [.0000.0000.0000.0000] # [0013] DEVICE CONTROL THREE (in 6429) +0014 ; [.0000.0000.0000.0000] # [0014] DEVICE CONTROL FOUR (in 6429) +0015 ; [.0000.0000.0000.0000] # [0015] NEGATIVE ACKNOWLEDGE (in 6429) +0016 ; [.0000.0000.0000.0000] # [0016] SYNCHRONOUS IDLE (in 6429) +0017 ; [.0000.0000.0000.0000] # [0017] END OF TRANSMISSION BLOCK (in 6429) +0018 ; [.0000.0000.0000.0000] # [0018] CANCEL (in 6429) +0019 ; [.0000.0000.0000.0000] # [0019] END OF MEDIUM (in 6429) +001A ; [.0000.0000.0000.0000] # [001A] SUBSTITUTE (in 6429) +001B ; [.0000.0000.0000.0000] # [001B] ESCAPE (in 6429) +001C ; [.0000.0000.0000.0000] # [001C] FILE SEPARATOR (in 6429) +001D ; [.0000.0000.0000.0000] # [001D] GROUP SEPARATOR (in 6429) +001E ; [.0000.0000.0000.0000] # [001E] RECORD SEPARATOR (in 6429) +001F ; [.0000.0000.0000.0000] # [001F] UNIT SEPARATOR (in 6429) +007F ; [.0000.0000.0000.0000] # [007F] DELETE (in 6429) +0080 ; [.0000.0000.0000.0000] # [0080] +0081 ; [.0000.0000.0000.0000] # [0081] +0082 ; [.0000.0000.0000.0000] # [0082] BREAK PERMITTED HERE (in 6429) +0083 ; [.0000.0000.0000.0000] # [0083] NO BREAK HERE (in 6429) +0084 ; [.0000.0000.0000.0000] # [0084] +0086 ; [.0000.0000.0000.0000] # [0086] START OF SELECTED AREA (in 6429) +0087 ; [.0000.0000.0000.0000] # [0087] END OF SELECTED AREA (in 6429) +0088 ; [.0000.0000.0000.0000] # [0088] CHARACTER TABULATION SET (in 6429) +0089 ; [.0000.0000.0000.0000] # [0089] CHARACTER TABULATION WITH JUSTIFICATION (in 6429) +008A ; [.0000.0000.0000.0000] # [008A] LINE TABULATION SET (in 6429) +008B ; [.0000.0000.0000.0000] # [008B] PARTIAL LINE FORWARD (in 6429) +008C ; [.0000.0000.0000.0000] # [008C] PARTIAL LINE BACKWARD (in 6429) +008D ; [.0000.0000.0000.0000] # [008D] PARTIAL LINE FEED (in 6429) +008E ; [.0000.0000.0000.0000] # [008E] SINGLE SHIFT TWO (in 6429) +008F ; [.0000.0000.0000.0000] # [008F] SINGLE SHIFT THREE (in 6429) +0090 ; [.0000.0000.0000.0000] # [0090] DEVICE CONTROL STRING (in 6429) +0091 ; [.0000.0000.0000.0000] # [0091] PRIVATE USE ONE (in 6429) +0092 ; [.0000.0000.0000.0000] # [0092] PRIVATE USE TWO (in 6429) +0093 ; [.0000.0000.0000.0000] # [0093] SET TRANSMIT STATE (in 6429) +0094 ; [.0000.0000.0000.0000] # [0094] CANCEL CHARACTER (in 6429) +0095 ; [.0000.0000.0000.0000] # [0095] MESSAGE WAITING (in 6429) +0096 ; [.0000.0000.0000.0000] # [0096] START OF GUARDED AREA (in 6429) +0097 ; [.0000.0000.0000.0000] # [0097] END OF GUARDED AREA (in 6429) +0098 ; [.0000.0000.0000.0000] # [0098] START OF STRING (in 6429) +0099 ; [.0000.0000.0000.0000] # [0099] +009A ; [.0000.0000.0000.0000] # [009A] SINGLE CHARACTER INTRODUCER (in 6429) +009B ; [.0000.0000.0000.0000] # [009B] CONTROL SEQUENCE INTRODUCER (in 6429) +009C ; [.0000.0000.0000.0000] # [009C] STRING TERMINATOR (in 6429) +009D ; [.0000.0000.0000.0000] # [009D] OPERATING SYSTEM COMMAND (in 6429) +009E ; [.0000.0000.0000.0000] # [009E] PRIVACY MESSAGE (in 6429) +009F ; [.0000.0000.0000.0000] # [009F] APPLICATION PROGRAM COMMAND (in 6429) +00AD ; [.0000.0000.0000.0000] # [00AD] SOFT HYPHEN +070F ; [.0000.0000.0000.0000] # [070F] SYRIAC ABBREVIATION MARK +180B ; [.0000.0000.0000.0000] # [180B] MONGOLIAN FREE VARIATION SELECTOR ONE +180C ; [.0000.0000.0000.0000] # [180C] MONGOLIAN FREE VARIATION SELECTOR TWO +180D ; [.0000.0000.0000.0000] # [180D] MONGOLIAN FREE VARIATION SELECTOR THREE +200B ; [.0000.0000.0000.0000] # [200B] ZERO WIDTH SPACE +200C ; [.0000.0000.0000.0000] # [200C] ZERO WIDTH NON-JOINER +200D ; [.0000.0000.0000.0000] # [200D] ZERO WIDTH JOINER +200E ; [.0000.0000.0000.0000] # [200E] LEFT-TO-RIGHT MARK +200F ; [.0000.0000.0000.0000] # [200F] RIGHT-TO-LEFT MARK +202A ; [.0000.0000.0000.0000] # [202A] LEFT-TO-RIGHT EMBEDDING +202B ; [.0000.0000.0000.0000] # [202B] RIGHT-TO-LEFT EMBEDDING +202C ; [.0000.0000.0000.0000] # [202C] POP DIRECTIONAL FORMATTING +202D ; [.0000.0000.0000.0000] # [202D] LEFT-TO-RIGHT OVERRIDE +202E ; [.0000.0000.0000.0000] # [202E] RIGHT-TO-LEFT OVERRIDE +2060 ; [.0000.0000.0000.0000] # [2060] WORD JOINER +206A ; [.0000.0000.0000.0000] # [206A] INHIBIT SYMMETRIC SWAPPING +206B ; [.0000.0000.0000.0000] # [206B] ACTIVATE SYMMETRIC SWAPPING +206C ; [.0000.0000.0000.0000] # [206C] INHIBIT ARABIC FORM SHAPING +206D ; [.0000.0000.0000.0000] # [206D] ACTIVATE ARABIC FORM SHAPING +206E ; [.0000.0000.0000.0000] # [206E] NATIONAL DIGIT SHAPES +206F ; [.0000.0000.0000.0000] # [206F] NOMINAL DIGIT SHAPES +FE00 ; [.0000.0000.0000.0000] # [FE00] VARIATION SELECTOR-1 +FE01 ; [.0000.0000.0000.0000] # [FE01] VARIATION SELECTOR-2 +FE02 ; [.0000.0000.0000.0000] # [FE02] VARIATION SELECTOR-3 +FE03 ; [.0000.0000.0000.0000] # [FE03] VARIATION SELECTOR-4 +FE04 ; [.0000.0000.0000.0000] # [FE04] VARIATION SELECTOR-5 +FE05 ; [.0000.0000.0000.0000] # [FE05] VARIATION SELECTOR-6 +FE06 ; [.0000.0000.0000.0000] # [FE06] VARIATION SELECTOR-7 +FE07 ; [.0000.0000.0000.0000] # [FE07] VARIATION SELECTOR-8 +FE08 ; [.0000.0000.0000.0000] # [FE08] VARIATION SELECTOR-9 +FE09 ; [.0000.0000.0000.0000] # [FE09] VARIATION SELECTOR-10 +FE0A ; [.0000.0000.0000.0000] # [FE0A] VARIATION SELECTOR-11 +FE0B ; [.0000.0000.0000.0000] # [FE0B] VARIATION SELECTOR-12 +FE0C ; [.0000.0000.0000.0000] # [FE0C] VARIATION SELECTOR-13 +FE0D ; [.0000.0000.0000.0000] # [FE0D] VARIATION SELECTOR-14 +FE0E ; [.0000.0000.0000.0000] # [FE0E] VARIATION SELECTOR-15 +FE0F ; [.0000.0000.0000.0000] # [FE0F] VARIATION SELECTOR-16 +FEFF ; [.0000.0000.0000.0000] # [FEFF] ZERO WIDTH NO-BREAK SPACE +FFF9 ; [.0000.0000.0000.0000] # [FFF9] INTERLINEAR ANNOTATION ANCHOR +FFFA ; [.0000.0000.0000.0000] # [FFFA] INTERLINEAR ANNOTATION SEPARATOR +FFFB ; [.0000.0000.0000.0000] # [FFFB] INTERLINEAR ANNOTATION TERMINATOR +1D173 ; [.0000.0000.0000.0000] # [1D173] MUSICAL SYMBOL BEGIN BEAM +1D174 ; [.0000.0000.0000.0000] # [1D174] MUSICAL SYMBOL END BEAM +1D175 ; [.0000.0000.0000.0000] # [1D175] MUSICAL SYMBOL BEGIN TIE +1D176 ; [.0000.0000.0000.0000] # [1D176] MUSICAL SYMBOL END TIE +1D177 ; [.0000.0000.0000.0000] # [1D177] MUSICAL SYMBOL BEGIN SLUR +1D178 ; [.0000.0000.0000.0000] # [1D178] MUSICAL SYMBOL END SLUR +1D179 ; [.0000.0000.0000.0000] # [1D179] MUSICAL SYMBOL BEGIN PHRASE +1D17A ; [.0000.0000.0000.0000] # [1D17A] MUSICAL SYMBOL END PHRASE +E0001 ; [.0000.0000.0000.0000] # [E0001] LANGUAGE TAG +E0020 ; [.0000.0000.0000.0000] # [E0020] TAG SPACE +E0021 ; [.0000.0000.0000.0000] # [E0021] TAG EXCLAMATION MARK +E0022 ; [.0000.0000.0000.0000] # [E0022] TAG QUOTATION MARK +E0023 ; [.0000.0000.0000.0000] # [E0023] TAG NUMBER SIGN +E0024 ; [.0000.0000.0000.0000] # [E0024] TAG DOLLAR SIGN +E0025 ; [.0000.0000.0000.0000] # [E0025] TAG PERCENT SIGN +E0026 ; [.0000.0000.0000.0000] # [E0026] TAG AMPERSAND +E0027 ; [.0000.0000.0000.0000] # [E0027] TAG APOSTROPHE +E0028 ; [.0000.0000.0000.0000] # [E0028] TAG LEFT PARENTHESIS +E0029 ; [.0000.0000.0000.0000] # [E0029] TAG RIGHT PARENTHESIS +E002A ; [.0000.0000.0000.0000] # [E002A] TAG ASTERISK +E002B ; [.0000.0000.0000.0000] # [E002B] TAG PLUS SIGN +E002C ; [.0000.0000.0000.0000] # [E002C] TAG COMMA +E002D ; [.0000.0000.0000.0000] # [E002D] TAG HYPHEN-MINUS +E002E ; [.0000.0000.0000.0000] # [E002E] TAG FULL STOP +E002F ; [.0000.0000.0000.0000] # [E002F] TAG SOLIDUS +E0030 ; [.0000.0000.0000.0000] # [E0030] TAG DIGIT ZERO +E0031 ; [.0000.0000.0000.0000] # [E0031] TAG DIGIT ONE +E0032 ; [.0000.0000.0000.0000] # [E0032] TAG DIGIT TWO +E0033 ; [.0000.0000.0000.0000] # [E0033] TAG DIGIT THREE +E0034 ; [.0000.0000.0000.0000] # [E0034] TAG DIGIT FOUR +E0035 ; [.0000.0000.0000.0000] # [E0035] TAG DIGIT FIVE +E0036 ; [.0000.0000.0000.0000] # [E0036] TAG DIGIT SIX +E0037 ; [.0000.0000.0000.0000] # [E0037] TAG DIGIT SEVEN +E0038 ; [.0000.0000.0000.0000] # [E0038] TAG DIGIT EIGHT +E0039 ; [.0000.0000.0000.0000] # [E0039] TAG DIGIT NINE +E003A ; [.0000.0000.0000.0000] # [E003A] TAG COLON +E003B ; [.0000.0000.0000.0000] # [E003B] TAG SEMICOLON +E003C ; [.0000.0000.0000.0000] # [E003C] TAG LESS-THAN SIGN +E003D ; [.0000.0000.0000.0000] # [E003D] TAG EQUALS SIGN +E003E ; [.0000.0000.0000.0000] # [E003E] TAG GREATER-THAN SIGN +E003F ; [.0000.0000.0000.0000] # [E003F] TAG QUESTION MARK +E0040 ; [.0000.0000.0000.0000] # [E0040] TAG COMMERCIAL AT +E0041 ; [.0000.0000.0000.0000] # [E0041] TAG LATIN CAPITAL LETTER A +E0042 ; [.0000.0000.0000.0000] # [E0042] TAG LATIN CAPITAL LETTER B +E0043 ; [.0000.0000.0000.0000] # [E0043] TAG LATIN CAPITAL LETTER C +E0044 ; [.0000.0000.0000.0000] # [E0044] TAG LATIN CAPITAL LETTER D +E0045 ; [.0000.0000.0000.0000] # [E0045] TAG LATIN CAPITAL LETTER E +E0046 ; [.0000.0000.0000.0000] # [E0046] TAG LATIN CAPITAL LETTER F +E0047 ; [.0000.0000.0000.0000] # [E0047] TAG LATIN CAPITAL LETTER G +E0048 ; [.0000.0000.0000.0000] # [E0048] TAG LATIN CAPITAL LETTER H +E0049 ; [.0000.0000.0000.0000] # [E0049] TAG LATIN CAPITAL LETTER I +E004A ; [.0000.0000.0000.0000] # [E004A] TAG LATIN CAPITAL LETTER J +E004B ; [.0000.0000.0000.0000] # [E004B] TAG LATIN CAPITAL LETTER K +E004C ; [.0000.0000.0000.0000] # [E004C] TAG LATIN CAPITAL LETTER L +E004D ; [.0000.0000.0000.0000] # [E004D] TAG LATIN CAPITAL LETTER M +E004E ; [.0000.0000.0000.0000] # [E004E] TAG LATIN CAPITAL LETTER N +E004F ; [.0000.0000.0000.0000] # [E004F] TAG LATIN CAPITAL LETTER O +E0050 ; [.0000.0000.0000.0000] # [E0050] TAG LATIN CAPITAL LETTER P +E0051 ; [.0000.0000.0000.0000] # [E0051] TAG LATIN CAPITAL LETTER Q +E0052 ; [.0000.0000.0000.0000] # [E0052] TAG LATIN CAPITAL LETTER R +E0053 ; [.0000.0000.0000.0000] # [E0053] TAG LATIN CAPITAL LETTER S +E0054 ; [.0000.0000.0000.0000] # [E0054] TAG LATIN CAPITAL LETTER T +E0055 ; [.0000.0000.0000.0000] # [E0055] TAG LATIN CAPITAL LETTER U +E0056 ; [.0000.0000.0000.0000] # [E0056] TAG LATIN CAPITAL LETTER V +E0057 ; [.0000.0000.0000.0000] # [E0057] TAG LATIN CAPITAL LETTER W +E0058 ; [.0000.0000.0000.0000] # [E0058] TAG LATIN CAPITAL LETTER X +E0059 ; [.0000.0000.0000.0000] # [E0059] TAG LATIN CAPITAL LETTER Y +E005A ; [.0000.0000.0000.0000] # [E005A] TAG LATIN CAPITAL LETTER Z +E005B ; [.0000.0000.0000.0000] # [E005B] TAG LEFT SQUARE BRACKET +E005C ; [.0000.0000.0000.0000] # [E005C] TAG REVERSE SOLIDUS +E005D ; [.0000.0000.0000.0000] # [E005D] TAG RIGHT SQUARE BRACKET +E005E ; [.0000.0000.0000.0000] # [E005E] TAG CIRCUMFLEX ACCENT +E005F ; [.0000.0000.0000.0000] # [E005F] TAG LOW LINE +E0060 ; [.0000.0000.0000.0000] # [E0060] TAG GRAVE ACCENT +E0061 ; [.0000.0000.0000.0000] # [E0061] TAG LATIN SMALL LETTER A +E0062 ; [.0000.0000.0000.0000] # [E0062] TAG LATIN SMALL LETTER B +E0063 ; [.0000.0000.0000.0000] # [E0063] TAG LATIN SMALL LETTER C +E0064 ; [.0000.0000.0000.0000] # [E0064] TAG LATIN SMALL LETTER D +E0065 ; [.0000.0000.0000.0000] # [E0065] TAG LATIN SMALL LETTER E +E0066 ; [.0000.0000.0000.0000] # [E0066] TAG LATIN SMALL LETTER F +E0067 ; [.0000.0000.0000.0000] # [E0067] TAG LATIN SMALL LETTER G +E0068 ; [.0000.0000.0000.0000] # [E0068] TAG LATIN SMALL LETTER H +E0069 ; [.0000.0000.0000.0000] # [E0069] TAG LATIN SMALL LETTER I +E006A ; [.0000.0000.0000.0000] # [E006A] TAG LATIN SMALL LETTER J +E006B ; [.0000.0000.0000.0000] # [E006B] TAG LATIN SMALL LETTER K +E006C ; [.0000.0000.0000.0000] # [E006C] TAG LATIN SMALL LETTER L +E006D ; [.0000.0000.0000.0000] # [E006D] TAG LATIN SMALL LETTER M +E006E ; [.0000.0000.0000.0000] # [E006E] TAG LATIN SMALL LETTER N +E006F ; [.0000.0000.0000.0000] # [E006F] TAG LATIN SMALL LETTER O +E0070 ; [.0000.0000.0000.0000] # [E0070] TAG LATIN SMALL LETTER P +E0071 ; [.0000.0000.0000.0000] # [E0071] TAG LATIN SMALL LETTER Q +E0072 ; [.0000.0000.0000.0000] # [E0072] TAG LATIN SMALL LETTER R +E0073 ; [.0000.0000.0000.0000] # [E0073] TAG LATIN SMALL LETTER S +E0074 ; [.0000.0000.0000.0000] # [E0074] TAG LATIN SMALL LETTER T +E0075 ; [.0000.0000.0000.0000] # [E0075] TAG LATIN SMALL LETTER U +E0076 ; [.0000.0000.0000.0000] # [E0076] TAG LATIN SMALL LETTER V +E0077 ; [.0000.0000.0000.0000] # [E0077] TAG LATIN SMALL LETTER W +E0078 ; [.0000.0000.0000.0000] # [E0078] TAG LATIN SMALL LETTER X +E0079 ; [.0000.0000.0000.0000] # [E0079] TAG LATIN SMALL LETTER Y +E007A ; [.0000.0000.0000.0000] # [E007A] TAG LATIN SMALL LETTER Z +E007B ; [.0000.0000.0000.0000] # [E007B] TAG LEFT CURLY BRACKET +E007C ; [.0000.0000.0000.0000] # [E007C] TAG VERTICAL LINE +E007D ; [.0000.0000.0000.0000] # [E007D] TAG RIGHT CURLY BRACKET +E007E ; [.0000.0000.0000.0000] # [E007E] TAG TILDE +E007F ; [.0000.0000.0000.0000] # [E007F] CANCEL TAG +E0100 ; [.0000.0000.0000.0000] # [E0100] VARIATION SELECTOR-17 +E0101 ; [.0000.0000.0000.0000] # [E0101] VARIATION SELECTOR-18 +E0102 ; [.0000.0000.0000.0000] # [E0102] VARIATION SELECTOR-19 +E0103 ; [.0000.0000.0000.0000] # [E0103] VARIATION SELECTOR-20 +E0104 ; [.0000.0000.0000.0000] # [E0104] VARIATION SELECTOR-21 +E0105 ; [.0000.0000.0000.0000] # [E0105] VARIATION SELECTOR-22 +E0106 ; [.0000.0000.0000.0000] # [E0106] VARIATION SELECTOR-23 +E0107 ; [.0000.0000.0000.0000] # [E0107] VARIATION SELECTOR-24 +E0108 ; [.0000.0000.0000.0000] # [E0108] VARIATION SELECTOR-25 +E0109 ; [.0000.0000.0000.0000] # [E0109] VARIATION SELECTOR-26 +E010A ; [.0000.0000.0000.0000] # [E010A] VARIATION SELECTOR-27 +E010B ; [.0000.0000.0000.0000] # [E010B] VARIATION SELECTOR-28 +E010C ; [.0000.0000.0000.0000] # [E010C] VARIATION SELECTOR-29 +E010D ; [.0000.0000.0000.0000] # [E010D] VARIATION SELECTOR-30 +E010E ; [.0000.0000.0000.0000] # [E010E] VARIATION SELECTOR-31 +E010F ; [.0000.0000.0000.0000] # [E010F] VARIATION SELECTOR-32 +E0110 ; [.0000.0000.0000.0000] # [E0110] VARIATION SELECTOR-33 +E0111 ; [.0000.0000.0000.0000] # [E0111] VARIATION SELECTOR-34 +E0112 ; [.0000.0000.0000.0000] # [E0112] VARIATION SELECTOR-35 +E0113 ; [.0000.0000.0000.0000] # [E0113] VARIATION SELECTOR-36 +E0114 ; [.0000.0000.0000.0000] # [E0114] VARIATION SELECTOR-37 +E0115 ; [.0000.0000.0000.0000] # [E0115] VARIATION SELECTOR-38 +E0116 ; [.0000.0000.0000.0000] # [E0116] VARIATION SELECTOR-39 +E0117 ; [.0000.0000.0000.0000] # [E0117] VARIATION SELECTOR-40 +E0118 ; [.0000.0000.0000.0000] # [E0118] VARIATION SELECTOR-41 +E0119 ; [.0000.0000.0000.0000] # [E0119] VARIATION SELECTOR-42 +E011A ; [.0000.0000.0000.0000] # [E011A] VARIATION SELECTOR-43 +E011B ; [.0000.0000.0000.0000] # [E011B] VARIATION SELECTOR-44 +E011C ; [.0000.0000.0000.0000] # [E011C] VARIATION SELECTOR-45 +E011D ; [.0000.0000.0000.0000] # [E011D] VARIATION SELECTOR-46 +E011E ; [.0000.0000.0000.0000] # [E011E] VARIATION SELECTOR-47 +E011F ; [.0000.0000.0000.0000] # [E011F] VARIATION SELECTOR-48 +E0120 ; [.0000.0000.0000.0000] # [E0120] VARIATION SELECTOR-49 +E0121 ; [.0000.0000.0000.0000] # [E0121] VARIATION SELECTOR-50 +E0122 ; [.0000.0000.0000.0000] # [E0122] VARIATION SELECTOR-51 +E0123 ; [.0000.0000.0000.0000] # [E0123] VARIATION SELECTOR-52 +E0124 ; [.0000.0000.0000.0000] # [E0124] VARIATION SELECTOR-53 +E0125 ; [.0000.0000.0000.0000] # [E0125] VARIATION SELECTOR-54 +E0126 ; [.0000.0000.0000.0000] # [E0126] VARIATION SELECTOR-55 +E0127 ; [.0000.0000.0000.0000] # [E0127] VARIATION SELECTOR-56 +E0128 ; [.0000.0000.0000.0000] # [E0128] VARIATION SELECTOR-57 +E0129 ; [.0000.0000.0000.0000] # [E0129] VARIATION SELECTOR-58 +E012A ; [.0000.0000.0000.0000] # [E012A] VARIATION SELECTOR-59 +E012B ; [.0000.0000.0000.0000] # [E012B] VARIATION SELECTOR-60 +E012C ; [.0000.0000.0000.0000] # [E012C] VARIATION SELECTOR-61 +E012D ; [.0000.0000.0000.0000] # [E012D] VARIATION SELECTOR-62 +E012E ; [.0000.0000.0000.0000] # [E012E] VARIATION SELECTOR-63 +E012F ; [.0000.0000.0000.0000] # [E012F] VARIATION SELECTOR-64 +E0130 ; [.0000.0000.0000.0000] # [E0130] VARIATION SELECTOR-65 +E0131 ; [.0000.0000.0000.0000] # [E0131] VARIATION SELECTOR-66 +E0132 ; [.0000.0000.0000.0000] # [E0132] VARIATION SELECTOR-67 +E0133 ; [.0000.0000.0000.0000] # [E0133] VARIATION SELECTOR-68 +E0134 ; [.0000.0000.0000.0000] # [E0134] VARIATION SELECTOR-69 +E0135 ; [.0000.0000.0000.0000] # [E0135] VARIATION SELECTOR-70 +E0136 ; [.0000.0000.0000.0000] # [E0136] VARIATION SELECTOR-71 +E0137 ; [.0000.0000.0000.0000] # [E0137] VARIATION SELECTOR-72 +E0138 ; [.0000.0000.0000.0000] # [E0138] VARIATION SELECTOR-73 +E0139 ; [.0000.0000.0000.0000] # [E0139] VARIATION SELECTOR-74 +E013A ; [.0000.0000.0000.0000] # [E013A] VARIATION SELECTOR-75 +E013B ; [.0000.0000.0000.0000] # [E013B] VARIATION SELECTOR-76 +E013C ; [.0000.0000.0000.0000] # [E013C] VARIATION SELECTOR-77 +E013D ; [.0000.0000.0000.0000] # [E013D] VARIATION SELECTOR-78 +E013E ; [.0000.0000.0000.0000] # [E013E] VARIATION SELECTOR-79 +E013F ; [.0000.0000.0000.0000] # [E013F] VARIATION SELECTOR-80 +E0140 ; [.0000.0000.0000.0000] # [E0140] VARIATION SELECTOR-81 +E0141 ; [.0000.0000.0000.0000] # [E0141] VARIATION SELECTOR-82 +E0142 ; [.0000.0000.0000.0000] # [E0142] VARIATION SELECTOR-83 +E0143 ; [.0000.0000.0000.0000] # [E0143] VARIATION SELECTOR-84 +E0144 ; [.0000.0000.0000.0000] # [E0144] VARIATION SELECTOR-85 +E0145 ; [.0000.0000.0000.0000] # [E0145] VARIATION SELECTOR-86 +E0146 ; [.0000.0000.0000.0000] # [E0146] VARIATION SELECTOR-87 +E0147 ; [.0000.0000.0000.0000] # [E0147] VARIATION SELECTOR-88 +E0148 ; [.0000.0000.0000.0000] # [E0148] VARIATION SELECTOR-89 +E0149 ; [.0000.0000.0000.0000] # [E0149] VARIATION SELECTOR-90 +E014A ; [.0000.0000.0000.0000] # [E014A] VARIATION SELECTOR-91 +E014B ; [.0000.0000.0000.0000] # [E014B] VARIATION SELECTOR-92 +E014C ; [.0000.0000.0000.0000] # [E014C] VARIATION SELECTOR-93 +E014D ; [.0000.0000.0000.0000] # [E014D] VARIATION SELECTOR-94 +E014E ; [.0000.0000.0000.0000] # [E014E] VARIATION SELECTOR-95 +E014F ; [.0000.0000.0000.0000] # [E014F] VARIATION SELECTOR-96 +E0150 ; [.0000.0000.0000.0000] # [E0150] VARIATION SELECTOR-97 +E0151 ; [.0000.0000.0000.0000] # [E0151] VARIATION SELECTOR-98 +E0152 ; [.0000.0000.0000.0000] # [E0152] VARIATION SELECTOR-99 +E0153 ; [.0000.0000.0000.0000] # [E0153] VARIATION SELECTOR-100 +E0154 ; [.0000.0000.0000.0000] # [E0154] VARIATION SELECTOR-101 +E0155 ; [.0000.0000.0000.0000] # [E0155] VARIATION SELECTOR-102 +E0156 ; [.0000.0000.0000.0000] # [E0156] VARIATION SELECTOR-103 +E0157 ; [.0000.0000.0000.0000] # [E0157] VARIATION SELECTOR-104 +E0158 ; [.0000.0000.0000.0000] # [E0158] VARIATION SELECTOR-105 +E0159 ; [.0000.0000.0000.0000] # [E0159] VARIATION SELECTOR-106 +E015A ; [.0000.0000.0000.0000] # [E015A] VARIATION SELECTOR-107 +E015B ; [.0000.0000.0000.0000] # [E015B] VARIATION SELECTOR-108 +E015C ; [.0000.0000.0000.0000] # [E015C] VARIATION SELECTOR-109 +E015D ; [.0000.0000.0000.0000] # [E015D] VARIATION SELECTOR-110 +E015E ; [.0000.0000.0000.0000] # [E015E] VARIATION SELECTOR-111 +E015F ; [.0000.0000.0000.0000] # [E015F] VARIATION SELECTOR-112 +E0160 ; [.0000.0000.0000.0000] # [E0160] VARIATION SELECTOR-113 +E0161 ; [.0000.0000.0000.0000] # [E0161] VARIATION SELECTOR-114 +E0162 ; [.0000.0000.0000.0000] # [E0162] VARIATION SELECTOR-115 +E0163 ; [.0000.0000.0000.0000] # [E0163] VARIATION SELECTOR-116 +E0164 ; [.0000.0000.0000.0000] # [E0164] VARIATION SELECTOR-117 +E0165 ; [.0000.0000.0000.0000] # [E0165] VARIATION SELECTOR-118 +E0166 ; [.0000.0000.0000.0000] # [E0166] VARIATION SELECTOR-119 +E0167 ; [.0000.0000.0000.0000] # [E0167] VARIATION SELECTOR-120 +E0168 ; [.0000.0000.0000.0000] # [E0168] VARIATION SELECTOR-121 +E0169 ; [.0000.0000.0000.0000] # [E0169] VARIATION SELECTOR-122 +E016A ; [.0000.0000.0000.0000] # [E016A] VARIATION SELECTOR-123 +E016B ; [.0000.0000.0000.0000] # [E016B] VARIATION SELECTOR-124 +E016C ; [.0000.0000.0000.0000] # [E016C] VARIATION SELECTOR-125 +E016D ; [.0000.0000.0000.0000] # [E016D] VARIATION SELECTOR-126 +E016E ; [.0000.0000.0000.0000] # [E016E] VARIATION SELECTOR-127 +E016F ; [.0000.0000.0000.0000] # [E016F] VARIATION SELECTOR-128 +E0170 ; [.0000.0000.0000.0000] # [E0170] VARIATION SELECTOR-129 +E0171 ; [.0000.0000.0000.0000] # [E0171] VARIATION SELECTOR-130 +E0172 ; [.0000.0000.0000.0000] # [E0172] VARIATION SELECTOR-131 +E0173 ; [.0000.0000.0000.0000] # [E0173] VARIATION SELECTOR-132 +E0174 ; [.0000.0000.0000.0000] # [E0174] VARIATION SELECTOR-133 +E0175 ; [.0000.0000.0000.0000] # [E0175] VARIATION SELECTOR-134 +E0176 ; [.0000.0000.0000.0000] # [E0176] VARIATION SELECTOR-135 +E0177 ; [.0000.0000.0000.0000] # [E0177] VARIATION SELECTOR-136 +E0178 ; [.0000.0000.0000.0000] # [E0178] VARIATION SELECTOR-137 +E0179 ; [.0000.0000.0000.0000] # [E0179] VARIATION SELECTOR-138 +E017A ; [.0000.0000.0000.0000] # [E017A] VARIATION SELECTOR-139 +E017B ; [.0000.0000.0000.0000] # [E017B] VARIATION SELECTOR-140 +E017C ; [.0000.0000.0000.0000] # [E017C] VARIATION SELECTOR-141 +E017D ; [.0000.0000.0000.0000] # [E017D] VARIATION SELECTOR-142 +E017E ; [.0000.0000.0000.0000] # [E017E] VARIATION SELECTOR-143 +E017F ; [.0000.0000.0000.0000] # [E017F] VARIATION SELECTOR-144 +E0180 ; [.0000.0000.0000.0000] # [E0180] VARIATION SELECTOR-145 +E0181 ; [.0000.0000.0000.0000] # [E0181] VARIATION SELECTOR-146 +E0182 ; [.0000.0000.0000.0000] # [E0182] VARIATION SELECTOR-147 +E0183 ; [.0000.0000.0000.0000] # [E0183] VARIATION SELECTOR-148 +E0184 ; [.0000.0000.0000.0000] # [E0184] VARIATION SELECTOR-149 +E0185 ; [.0000.0000.0000.0000] # [E0185] VARIATION SELECTOR-150 +E0186 ; [.0000.0000.0000.0000] # [E0186] VARIATION SELECTOR-151 +E0187 ; [.0000.0000.0000.0000] # [E0187] VARIATION SELECTOR-152 +E0188 ; [.0000.0000.0000.0000] # [E0188] VARIATION SELECTOR-153 +E0189 ; [.0000.0000.0000.0000] # [E0189] VARIATION SELECTOR-154 +E018A ; [.0000.0000.0000.0000] # [E018A] VARIATION SELECTOR-155 +E018B ; [.0000.0000.0000.0000] # [E018B] VARIATION SELECTOR-156 +E018C ; [.0000.0000.0000.0000] # [E018C] VARIATION SELECTOR-157 +E018D ; [.0000.0000.0000.0000] # [E018D] VARIATION SELECTOR-158 +E018E ; [.0000.0000.0000.0000] # [E018E] VARIATION SELECTOR-159 +E018F ; [.0000.0000.0000.0000] # [E018F] VARIATION SELECTOR-160 +E0190 ; [.0000.0000.0000.0000] # [E0190] VARIATION SELECTOR-161 +E0191 ; [.0000.0000.0000.0000] # [E0191] VARIATION SELECTOR-162 +E0192 ; [.0000.0000.0000.0000] # [E0192] VARIATION SELECTOR-163 +E0193 ; [.0000.0000.0000.0000] # [E0193] VARIATION SELECTOR-164 +E0194 ; [.0000.0000.0000.0000] # [E0194] VARIATION SELECTOR-165 +E0195 ; [.0000.0000.0000.0000] # [E0195] VARIATION SELECTOR-166 +E0196 ; [.0000.0000.0000.0000] # [E0196] VARIATION SELECTOR-167 +E0197 ; [.0000.0000.0000.0000] # [E0197] VARIATION SELECTOR-168 +E0198 ; [.0000.0000.0000.0000] # [E0198] VARIATION SELECTOR-169 +E0199 ; [.0000.0000.0000.0000] # [E0199] VARIATION SELECTOR-170 +E019A ; [.0000.0000.0000.0000] # [E019A] VARIATION SELECTOR-171 +E019B ; [.0000.0000.0000.0000] # [E019B] VARIATION SELECTOR-172 +E019C ; [.0000.0000.0000.0000] # [E019C] VARIATION SELECTOR-173 +E019D ; [.0000.0000.0000.0000] # [E019D] VARIATION SELECTOR-174 +E019E ; [.0000.0000.0000.0000] # [E019E] VARIATION SELECTOR-175 +E019F ; [.0000.0000.0000.0000] # [E019F] VARIATION SELECTOR-176 +E01A0 ; [.0000.0000.0000.0000] # [E01A0] VARIATION SELECTOR-177 +E01A1 ; [.0000.0000.0000.0000] # [E01A1] VARIATION SELECTOR-178 +E01A2 ; [.0000.0000.0000.0000] # [E01A2] VARIATION SELECTOR-179 +E01A3 ; [.0000.0000.0000.0000] # [E01A3] VARIATION SELECTOR-180 +E01A4 ; [.0000.0000.0000.0000] # [E01A4] VARIATION SELECTOR-181 +E01A5 ; [.0000.0000.0000.0000] # [E01A5] VARIATION SELECTOR-182 +E01A6 ; [.0000.0000.0000.0000] # [E01A6] VARIATION SELECTOR-183 +E01A7 ; [.0000.0000.0000.0000] # [E01A7] VARIATION SELECTOR-184 +E01A8 ; [.0000.0000.0000.0000] # [E01A8] VARIATION SELECTOR-185 +E01A9 ; [.0000.0000.0000.0000] # [E01A9] VARIATION SELECTOR-186 +E01AA ; [.0000.0000.0000.0000] # [E01AA] VARIATION SELECTOR-187 +E01AB ; [.0000.0000.0000.0000] # [E01AB] VARIATION SELECTOR-188 +E01AC ; [.0000.0000.0000.0000] # [E01AC] VARIATION SELECTOR-189 +E01AD ; [.0000.0000.0000.0000] # [E01AD] VARIATION SELECTOR-190 +E01AE ; [.0000.0000.0000.0000] # [E01AE] VARIATION SELECTOR-191 +E01AF ; [.0000.0000.0000.0000] # [E01AF] VARIATION SELECTOR-192 +E01B0 ; [.0000.0000.0000.0000] # [E01B0] VARIATION SELECTOR-193 +E01B1 ; [.0000.0000.0000.0000] # [E01B1] VARIATION SELECTOR-194 +E01B2 ; [.0000.0000.0000.0000] # [E01B2] VARIATION SELECTOR-195 +E01B3 ; [.0000.0000.0000.0000] # [E01B3] VARIATION SELECTOR-196 +E01B4 ; [.0000.0000.0000.0000] # [E01B4] VARIATION SELECTOR-197 +E01B5 ; [.0000.0000.0000.0000] # [E01B5] VARIATION SELECTOR-198 +E01B6 ; [.0000.0000.0000.0000] # [E01B6] VARIATION SELECTOR-199 +E01B7 ; [.0000.0000.0000.0000] # [E01B7] VARIATION SELECTOR-200 +E01B8 ; [.0000.0000.0000.0000] # [E01B8] VARIATION SELECTOR-201 +E01B9 ; [.0000.0000.0000.0000] # [E01B9] VARIATION SELECTOR-202 +E01BA ; [.0000.0000.0000.0000] # [E01BA] VARIATION SELECTOR-203 +E01BB ; [.0000.0000.0000.0000] # [E01BB] VARIATION SELECTOR-204 +E01BC ; [.0000.0000.0000.0000] # [E01BC] VARIATION SELECTOR-205 +E01BD ; [.0000.0000.0000.0000] # [E01BD] VARIATION SELECTOR-206 +E01BE ; [.0000.0000.0000.0000] # [E01BE] VARIATION SELECTOR-207 +E01BF ; [.0000.0000.0000.0000] # [E01BF] VARIATION SELECTOR-208 +E01C0 ; [.0000.0000.0000.0000] # [E01C0] VARIATION SELECTOR-209 +E01C1 ; [.0000.0000.0000.0000] # [E01C1] VARIATION SELECTOR-210 +E01C2 ; [.0000.0000.0000.0000] # [E01C2] VARIATION SELECTOR-211 +E01C3 ; [.0000.0000.0000.0000] # [E01C3] VARIATION SELECTOR-212 +E01C4 ; [.0000.0000.0000.0000] # [E01C4] VARIATION SELECTOR-213 +E01C5 ; [.0000.0000.0000.0000] # [E01C5] VARIATION SELECTOR-214 +E01C6 ; [.0000.0000.0000.0000] # [E01C6] VARIATION SELECTOR-215 +E01C7 ; [.0000.0000.0000.0000] # [E01C7] VARIATION SELECTOR-216 +E01C8 ; [.0000.0000.0000.0000] # [E01C8] VARIATION SELECTOR-217 +E01C9 ; [.0000.0000.0000.0000] # [E01C9] VARIATION SELECTOR-218 +E01CA ; [.0000.0000.0000.0000] # [E01CA] VARIATION SELECTOR-219 +E01CB ; [.0000.0000.0000.0000] # [E01CB] VARIATION SELECTOR-220 +E01CC ; [.0000.0000.0000.0000] # [E01CC] VARIATION SELECTOR-221 +E01CD ; [.0000.0000.0000.0000] # [E01CD] VARIATION SELECTOR-222 +E01CE ; [.0000.0000.0000.0000] # [E01CE] VARIATION SELECTOR-223 +E01CF ; [.0000.0000.0000.0000] # [E01CF] VARIATION SELECTOR-224 +E01D0 ; [.0000.0000.0000.0000] # [E01D0] VARIATION SELECTOR-225 +E01D1 ; [.0000.0000.0000.0000] # [E01D1] VARIATION SELECTOR-226 +E01D2 ; [.0000.0000.0000.0000] # [E01D2] VARIATION SELECTOR-227 +E01D3 ; [.0000.0000.0000.0000] # [E01D3] VARIATION SELECTOR-228 +E01D4 ; [.0000.0000.0000.0000] # [E01D4] VARIATION SELECTOR-229 +E01D5 ; [.0000.0000.0000.0000] # [E01D5] VARIATION SELECTOR-230 +E01D6 ; [.0000.0000.0000.0000] # [E01D6] VARIATION SELECTOR-231 +E01D7 ; [.0000.0000.0000.0000] # [E01D7] VARIATION SELECTOR-232 +E01D8 ; [.0000.0000.0000.0000] # [E01D8] VARIATION SELECTOR-233 +E01D9 ; [.0000.0000.0000.0000] # [E01D9] VARIATION SELECTOR-234 +E01DA ; [.0000.0000.0000.0000] # [E01DA] VARIATION SELECTOR-235 +E01DB ; [.0000.0000.0000.0000] # [E01DB] VARIATION SELECTOR-236 +E01DC ; [.0000.0000.0000.0000] # [E01DC] VARIATION SELECTOR-237 +E01DD ; [.0000.0000.0000.0000] # [E01DD] VARIATION SELECTOR-238 +E01DE ; [.0000.0000.0000.0000] # [E01DE] VARIATION SELECTOR-239 +E01DF ; [.0000.0000.0000.0000] # [E01DF] VARIATION SELECTOR-240 +E01E0 ; [.0000.0000.0000.0000] # [E01E0] VARIATION SELECTOR-241 +E01E1 ; [.0000.0000.0000.0000] # [E01E1] VARIATION SELECTOR-242 +E01E2 ; [.0000.0000.0000.0000] # [E01E2] VARIATION SELECTOR-243 +E01E3 ; [.0000.0000.0000.0000] # [E01E3] VARIATION SELECTOR-244 +E01E4 ; [.0000.0000.0000.0000] # [E01E4] VARIATION SELECTOR-245 +E01E5 ; [.0000.0000.0000.0000] # [E01E5] VARIATION SELECTOR-246 +E01E6 ; [.0000.0000.0000.0000] # [E01E6] VARIATION SELECTOR-247 +E01E7 ; [.0000.0000.0000.0000] # [E01E7] VARIATION SELECTOR-248 +E01E8 ; [.0000.0000.0000.0000] # [E01E8] VARIATION SELECTOR-249 +E01E9 ; [.0000.0000.0000.0000] # [E01E9] VARIATION SELECTOR-250 +E01EA ; [.0000.0000.0000.0000] # [E01EA] VARIATION SELECTOR-251 +E01EB ; [.0000.0000.0000.0000] # [E01EB] VARIATION SELECTOR-252 +E01EC ; [.0000.0000.0000.0000] # [E01EC] VARIATION SELECTOR-253 +E01ED ; [.0000.0000.0000.0000] # [E01ED] VARIATION SELECTOR-254 +E01EE ; [.0000.0000.0000.0000] # [E01EE] VARIATION SELECTOR-255 +E01EF ; [.0000.0000.0000.0000] # [E01EF] VARIATION SELECTOR-256 +0009 ; [*0201.0020.0002.0009] # HORIZONTAL TABULATION (in 6429) +000A ; [*0202.0020.0002.000A] # LINE FEED (in 6429) +000B ; [*0203.0020.0002.000B] # VERTICAL TABULATION (in 6429) +000C ; [*0204.0020.0002.000C] # FORM FEED (in 6429) +000D ; [*0205.0020.0002.000D] # CARRIAGE RETURN (in 6429) +0020 ; [*020A.0020.0002.0020] # SPACE +0021 ; [*025E.0020.0002.0021] # EXCLAMATION MARK +0022 ; [*02F1.0020.0002.0022] # QUOTATION MARK +0023 ; [*0376.0020.0002.0023] # NUMBER SIGN +0025 ; [*0377.0020.0002.0025] # PERCENT SIGN +0026 ; [*0374.0020.0002.0026] # AMPERSAND +0027 ; [*02EA.0020.0002.0027] # APOSTROPHE +0028 ; [*02FB.0020.0002.0028] # LEFT PARENTHESIS +0029 ; [*02FC.0020.0002.0029] # RIGHT PARENTHESIS +002A ; [*036D.0020.0002.002A] # ASTERISK +002B ; [*059C.0020.0002.002B] # PLUS SIGN +002C ; [*0221.0020.0002.002C] # COMMA +002D ; [*020E.0020.0002.002D] # HYPHEN-MINUS +002E ; [*0273.0020.0002.002E] # FULL STOP +002F ; [*0372.0020.0002.002F] # SOLIDUS +003A ; [*0237.0020.0002.003A] # COLON +003B ; [*0232.0020.0002.003B] # SEMICOLON +003C ; [*05A0.0020.0002.003C] # LESS-THAN SIGN +003D ; [*05A1.0020.0002.003D] # EQUALS SIGN +003E ; [*05A2.0020.0002.003E] # GREATER-THAN SIGN +003F ; [*0263.0020.0002.003F] # QUESTION MARK +0040 ; [*036C.0020.0002.0040] # COMMERCIAL AT +005B ; [*02FD.0020.0002.005B] # LEFT SQUARE BRACKET +005C ; [*0373.0020.0002.005C] # REVERSE SOLIDUS +005D ; [*02FE.0020.0002.005D] # RIGHT SQUARE BRACKET +005E ; [*0412.0020.0002.005E] # CIRCUMFLEX ACCENT +005F ; [*020C.0020.0002.005F] # LOW LINE +0060 ; [*040F.0020.0002.0060] # GRAVE ACCENT +007B ; [*02FF.0020.0002.007B] # LEFT CURLY BRACKET +007C ; [*05A4.0020.0002.007C] # VERTICAL LINE +007D ; [*0300.0020.0002.007D] # RIGHT CURLY BRACKET +007E ; [*05A6.0020.0002.007E] # TILDE +0085 ; [*0206.0020.0002.0085] # NEXT LINE (in 6429) +00A0 ; [*020A.0020.001B.00A0] # NO-BREAK SPACE +00A1 ; [*025F.0020.0002.00A1] # INVERTED EXCLAMATION MARK +00A6 ; [*05A5.0020.0002.00A6] # BROKEN BAR +00A7 ; [*0368.0020.0002.00A7] # SECTION SIGN +00A8 ; [*0416.0020.0002.00A8] # DIAERESIS +00A9 ; [*050C.0020.0002.00A9] # COPYRIGHT SIGN +00AB ; [*02F9.0020.0002.00AB] # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +00AC ; [*05A3.0020.0002.00AC] # NOT SIGN +00AE ; [*050D.0020.0002.00AE] # REGISTERED SIGN +00AF ; [*0413.0020.0002.00AF] # MACRON +00B0 ; [*0482.0020.0002.00B0] # DEGREE SIGN +00B1 ; [*059D.0020.0002.00B1] # PLUS-MINUS SIGN +00B4 ; [*0410.0020.0002.00B4] # ACUTE ACCENT +00B6 ; [*036A.0020.0002.00B6] # PILCROW SIGN +00B7 ; [*0284.0020.0002.00B7] # MIDDLE DOT +00B8 ; [*0419.0020.0002.00B8] # CEDILLA +00BB ; [*02FA.0020.0002.00BB] # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +00BF ; [*0264.0020.0002.00BF] # INVERTED QUESTION MARK +00D7 ; [*059F.0020.0002.00D7] # MULTIPLICATION SIGN +00F7 ; [*059E.0020.0002.00F7] # DIVISION SIGN +02B9 ; [*0420.0020.0002.02B9] # MODIFIER LETTER PRIME +02BA ; [*0422.0020.0002.02BA] # MODIFIER LETTER DOUBLE PRIME +02C2 ; [*0423.0020.0002.02C2] # MODIFIER LETTER LEFT ARROWHEAD +02C3 ; [*0424.0020.0002.02C3] # MODIFIER LETTER RIGHT ARROWHEAD +02C4 ; [*0425.0020.0002.02C4] # MODIFIER LETTER UP ARROWHEAD +02C5 ; [*0426.0020.0002.02C5] # MODIFIER LETTER DOWN ARROWHEAD +02C6 ; [*0427.0020.0002.02C6] # MODIFIER LETTER CIRCUMFLEX ACCENT +02C7 ; [*0428.0020.0002.02C7] # CARON +02C8 ; [*0429.0020.0002.02C8] # MODIFIER LETTER VERTICAL LINE +02C9 ; [*042A.0020.0002.02C9] # MODIFIER LETTER MACRON +02CA ; [*042B.0020.0002.02CA] # MODIFIER LETTER ACUTE ACCENT +02CB ; [*042C.0020.0002.02CB] # MODIFIER LETTER GRAVE ACCENT +02CC ; [*042D.0020.0002.02CC] # MODIFIER LETTER LOW VERTICAL LINE +02CD ; [*042E.0020.0002.02CD] # MODIFIER LETTER LOW MACRON +02CE ; [*042F.0020.0002.02CE] # MODIFIER LETTER LOW GRAVE ACCENT +02CF ; [*0430.0020.0002.02CF] # MODIFIER LETTER LOW ACUTE ACCENT +02D2 ; [*0431.0020.0002.02D2] # MODIFIER LETTER CENTRED RIGHT HALF RING +02D3 ; [*0432.0020.0002.02D3] # MODIFIER LETTER CENTRED LEFT HALF RING +02D4 ; [*0433.0020.0002.02D4] # MODIFIER LETTER UP TACK +02D5 ; [*0434.0020.0002.02D5] # MODIFIER LETTER DOWN TACK +02D6 ; [*0435.0020.0002.02D6] # MODIFIER LETTER PLUS SIGN +02D7 ; [*0436.0020.0002.02D7] # MODIFIER LETTER MINUS SIGN +02D8 ; [*0414.0020.0002.02D8] # BREVE +02D9 ; [*0415.0020.0002.02D9] # DOT ABOVE +02DA ; [*0417.0020.0002.02DA] # RING ABOVE +02DB ; [*041A.0020.0002.02DB] # OGONEK +02DC ; [*0411.0020.0002.02DC] # SMALL TILDE +02DD ; [*0418.0020.0002.02DD] # DOUBLE ACUTE ACCENT +02DE ; [*0437.0020.0002.02DE] # MODIFIER LETTER RHOTIC HOOK +02DF ; [*0438.0020.0002.02DF] # MODIFIER LETTER CROSS ACCENT +02E5 ; [*0439.0020.0002.02E5] # MODIFIER LETTER EXTRA-HIGH TONE BAR +02E6 ; [*043A.0020.0002.02E6] # MODIFIER LETTER HIGH TONE BAR +02E7 ; [*043B.0020.0002.02E7] # MODIFIER LETTER MID TONE BAR +02E8 ; [*043C.0020.0002.02E8] # MODIFIER LETTER LOW TONE BAR +02E9 ; [*043D.0020.0002.02E9] # MODIFIER LETTER EXTRA-LOW TONE BAR +02EA ; [*043E.0020.0002.02EA] # MODIFIER LETTER YIN DEPARTING TONE MARK +02EB ; [*043F.0020.0002.02EB] # MODIFIER LETTER YANG DEPARTING TONE MARK +02EC ; [*0440.0020.0002.02EC] # MODIFIER LETTER VOICING +02ED ; [*0441.0020.0002.02ED] # MODIFIER LETTER UNASPIRATED +02EF ; [*0442.0020.0002.02EF] # MODIFIER LETTER LOW DOWN ARROWHEAD +02F0 ; [*0443.0020.0002.02F0] # MODIFIER LETTER LOW UP ARROWHEAD +02F1 ; [*0444.0020.0002.02F1] # MODIFIER LETTER LOW LEFT ARROWHEAD +02F2 ; [*0445.0020.0002.02F2] # MODIFIER LETTER LOW RIGHT ARROWHEAD +02F3 ; [*0446.0020.0002.02F3] # MODIFIER LETTER LOW RING +02F4 ; [*0447.0020.0002.02F4] # MODIFIER LETTER MIDDLE GRAVE ACCENT +02F5 ; [*0448.0020.0002.02F5] # MODIFIER LETTER MIDDLE DOUBLE GRAVE ACCENT +02F6 ; [*0449.0020.0002.02F6] # MODIFIER LETTER MIDDLE DOUBLE ACUTE ACCENT +02F7 ; [*044A.0020.0002.02F7] # MODIFIER LETTER LOW TILDE +02F8 ; [*044B.0020.0002.02F8] # MODIFIER LETTER RAISED COLON +02F9 ; [*044C.0020.0002.02F9] # MODIFIER LETTER BEGIN HIGH TONE +02FA ; [*044D.0020.0002.02FA] # MODIFIER LETTER END HIGH TONE +02FB ; [*044E.0020.0002.02FB] # MODIFIER LETTER BEGIN LOW TONE +02FC ; [*044F.0020.0002.02FC] # MODIFIER LETTER END LOW TONE +02FD ; [*0450.0020.0002.02FD] # MODIFIER LETTER SHELF +02FE ; [*0451.0020.0002.02FE] # MODIFIER LETTER OPEN SHELF +02FF ; [*0452.0020.0002.02FF] # MODIFIER LETTER LOW LEFT ARROW +034F ; [.0000.0000.0000.034F] # COMBINING GRAPHEME JOINER +0374 ; [*0420.0020.0002.0374] # GREEK NUMERAL SIGN +0375 ; [*0421.0020.0002.0375] # GREEK LOWER NUMERAL SIGN +037E ; [*0232.0020.0002.037E] # GREEK QUESTION MARK +0384 ; [*0410.0020.0002.0384] # GREEK TONOS +0385 ; [*0416.0020.0002.00A8][.0000.0032.0002.0301] # GREEK DIALYTIKA TONOS +0387 ; [*0284.0020.0002.0387] # GREEK ANO TELEIA +03F6 ; [*0597.0020.0002.03F6] # GREEK REVERSED LUNATE EPSILON SYMBOL +0482 ; [*0483.0020.0002.0482] # CYRILLIC THOUSANDS SIGN +0488 ; [.0000.0000.0000.0488] # COMBINING CYRILLIC HUNDRED THOUSANDS SIGN +0489 ; [.0000.0000.0000.0489] # COMBINING CYRILLIC MILLIONS SIGN +055A ; [*03A8.0020.0002.055A] # ARMENIAN APOSTROPHE +055B ; [*03A9.0020.0002.055B] # ARMENIAN EMPHASIS MARK +055C ; [*0260.0020.0002.055C] # ARMENIAN EXCLAMATION MARK +055D ; [*0224.0020.0002.055D] # ARMENIAN COMMA +055E ; [*0266.0020.0002.055E] # ARMENIAN QUESTION MARK +055F ; [*03AA.0020.0002.055F] # ARMENIAN ABBREVIATION MARK +0589 ; [*0238.0020.0002.0589] # ARMENIAN FULL STOP +058A ; [*020F.0020.0002.058A] # ARMENIAN HYPHEN +0591 ; [.0000.0000.0000.0591] # HEBREW ACCENT ETNAHTA +0592 ; [.0000.0000.0000.0592] # HEBREW ACCENT SEGOL +0593 ; [.0000.0000.0000.0593] # HEBREW ACCENT SHALSHELET +0594 ; [.0000.0000.0000.0594] # HEBREW ACCENT ZAQEF QATAN +0595 ; [.0000.0000.0000.0595] # HEBREW ACCENT ZAQEF GADOL +0596 ; [.0000.0000.0000.0596] # HEBREW ACCENT TIPEHA +0597 ; [.0000.0000.0000.0597] # HEBREW ACCENT REVIA +0598 ; [.0000.0000.0000.0598] # HEBREW ACCENT ZARQA +0599 ; [.0000.0000.0000.0599] # HEBREW ACCENT PASHTA +059A ; [.0000.0000.0000.059A] # HEBREW ACCENT YETIV +059B ; [.0000.0000.0000.059B] # HEBREW ACCENT TEVIR +059C ; [.0000.0000.0000.059C] # HEBREW ACCENT GERESH +059D ; [.0000.0000.0000.059D] # HEBREW ACCENT GERESH MUQDAM +059E ; [.0000.0000.0000.059E] # HEBREW ACCENT GERSHAYIM +059F ; [.0000.0000.0000.059F] # HEBREW ACCENT QARNEY PARA +05A0 ; [.0000.0000.0000.05A0] # HEBREW ACCENT TELISHA GEDOLA +05A1 ; [.0000.0000.0000.05A1] # HEBREW ACCENT PAZER +05A2 ; [.0000.0000.0000.05A2] # HEBREW ACCENT ATNAH HAFUKH +05A3 ; [.0000.0000.0000.05A3] # HEBREW ACCENT MUNAH +05A4 ; [.0000.0000.0000.05A4] # HEBREW ACCENT MAHAPAKH +05A5 ; [.0000.0000.0000.05A5] # HEBREW ACCENT MERKHA +05A6 ; [.0000.0000.0000.05A6] # HEBREW ACCENT MERKHA KEFULA +05A7 ; [.0000.0000.0000.05A7] # HEBREW ACCENT DARGA +05A8 ; [.0000.0000.0000.05A8] # HEBREW ACCENT QADMA +05A9 ; [.0000.0000.0000.05A9] # HEBREW ACCENT TELISHA QETANA +05AA ; [.0000.0000.0000.05AA] # HEBREW ACCENT YERAH BEN YOMO +05AB ; [.0000.0000.0000.05AB] # HEBREW ACCENT OLE +05AC ; [.0000.0000.0000.05AC] # HEBREW ACCENT ILUY +05AD ; [.0000.0000.0000.05AD] # HEBREW ACCENT DEHI +05AE ; [.0000.0000.0000.05AE] # HEBREW ACCENT ZINOR +05AF ; [.0000.0000.0000.05AF] # HEBREW MARK MASORA CIRCLE +05BD ; [.0000.0000.0000.05BD] # HEBREW POINT METEG +05BE ; [*03AB.0020.0002.05BE] # HEBREW PUNCTUATION MAQAF +05C0 ; [*03AC.0020.0002.05C0] # HEBREW PUNCTUATION PASEQ +05C3 ; [*03AD.0020.0002.05C3] # HEBREW PUNCTUATION SOF PASUQ +05C4 ; [.0000.0000.0000.05C4] # HEBREW MARK UPPER DOT +05C5 ; [.0000.0000.0000.05C5] # HEBREW MARK LOWER DOT +05C6 ; [*03AE.0020.0002.05C6] # HEBREW PUNCTUATION NUN HAFUKHA +05F3 ; [*03AF.0020.0002.05F3] # HEBREW PUNCTUATION GERESH +05F4 ; [*03B0.0020.0002.05F4] # HEBREW PUNCTUATION GERSHAYIM +0600 ; [.0000.0000.0000.0600] # ARABIC NUMBER SIGN +0601 ; [.0000.0000.0000.0601] # ARABIC SIGN SANAH +0602 ; [.0000.0000.0000.0602] # ARABIC FOOTNOTE MARKER +0603 ; [.0000.0000.0000.0603] # ARABIC SIGN SAFHA +0604 ; [.0000.0000.0000.0604] # ARABIC SIGN SAMVAT +0606 ; [*05B3.0020.0002.0606] # ARABIC-INDIC CUBE ROOT +0607 ; [*05B5.0020.0002.0607] # ARABIC-INDIC FOURTH ROOT +0608 ; [*0484.0020.0002.0608] # ARABIC RAY +0609 ; [*037A.0020.0002.0609] # ARABIC-INDIC PER MILLE SIGN +060A ; [*037C.0020.0002.060A] # ARABIC-INDIC PER TEN THOUSAND SIGN +060C ; [*0225.0020.0002.060C] # ARABIC COMMA +060D ; [*0226.0020.0002.060D] # ARABIC DATE SEPARATOR +060E ; [*0487.0020.0002.060E] # ARABIC POETIC VERSE SIGN +060F ; [*0488.0020.0002.060F] # ARABIC SIGN MISRA +0610 ; [.0000.0000.0000.0610] # ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM +0611 ; [.0000.0000.0000.0611] # ARABIC SIGN ALAYHE ASSALLAM +0612 ; [.0000.0000.0000.0612] # ARABIC SIGN RAHMATULLAH ALAYHE +0613 ; [.0000.0000.0000.0613] # ARABIC SIGN RADI ALLAHOU ANHU +0614 ; [.0000.0000.0000.0614] # ARABIC SIGN TAKHALLUS +0615 ; [.0000.0000.0000.0615] # ARABIC SMALL HIGH TAH +0616 ; [.0000.0000.0000.0616] # ARABIC SMALL HIGH LIGATURE ALEF WITH LAM WITH YEH +0617 ; [.0000.0000.0000.0617] # ARABIC SMALL HIGH ZAIN +0618 ; [.0000.0000.0000.0618] # ARABIC SMALL FATHA +0619 ; [.0000.0000.0000.0619] # ARABIC SMALL DAMMA +061A ; [.0000.0000.0000.061A] # ARABIC SMALL KASRA +061B ; [*0233.0020.0002.061B] # ARABIC SEMICOLON +061E ; [*0239.0020.0002.061E] # ARABIC TRIPLE DOT PUNCTUATION MARK +061F ; [*0267.0020.0002.061F] # ARABIC QUESTION MARK +0640 ; [.0000.0000.0000.0640] # ARABIC TATWEEL +066A ; [*0378.0020.0002.066A] # ARABIC PERCENT SIGN +066B ; [*0227.0020.0002.066B] # ARABIC DECIMAL SEPARATOR +066C ; [*0228.0020.0002.066C] # ARABIC THOUSANDS SEPARATOR +066D ; [*0370.0020.0002.066D] # ARABIC FIVE POINTED STAR +06D4 ; [*0275.0020.0002.06D4] # ARABIC FULL STOP +06D6 ; [.0000.0000.0000.06D6] # ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA +06D7 ; [.0000.0000.0000.06D7] # ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA +06D8 ; [.0000.0000.0000.06D8] # ARABIC SMALL HIGH MEEM INITIAL FORM +06D9 ; [.0000.0000.0000.06D9] # ARABIC SMALL HIGH LAM ALEF +06DA ; [.0000.0000.0000.06DA] # ARABIC SMALL HIGH JEEM +06DB ; [.0000.0000.0000.06DB] # ARABIC SMALL HIGH THREE DOTS +06DC ; [.0000.0000.0000.06DC] # ARABIC SMALL HIGH SEEN +06DD ; [.0000.0000.0000.06DD] # ARABIC END OF AYAH +06DE ; [*0489.0020.0002.06DE] # ARABIC START OF RUB EL HIZB +06DF ; [.0000.0000.0000.06DF] # ARABIC SMALL HIGH ROUNDED ZERO +06E0 ; [.0000.0000.0000.06E0] # ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO +06E1 ; [.0000.0000.0000.06E1] # ARABIC SMALL HIGH DOTLESS HEAD OF KHAH +06E2 ; [.0000.0000.0000.06E2] # ARABIC SMALL HIGH MEEM ISOLATED FORM +06E3 ; [.0000.0000.0000.06E3] # ARABIC SMALL LOW SEEN +06E4 ; [.0000.0000.0000.06E4] # ARABIC SMALL HIGH MADDA +06E7 ; [.0000.0000.0000.06E7] # ARABIC SMALL HIGH YEH +06E8 ; [.0000.0000.0000.06E8] # ARABIC SMALL HIGH NOON +06E9 ; [*048A.0020.0002.06E9] # ARABIC PLACE OF SAJDAH +06EA ; [.0000.0000.0000.06EA] # ARABIC EMPTY CENTRE LOW STOP +06EB ; [.0000.0000.0000.06EB] # ARABIC EMPTY CENTRE HIGH STOP +06EC ; [.0000.0000.0000.06EC] # ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE +06ED ; [.0000.0000.0000.06ED] # ARABIC SMALL LOW MEEM +0700 ; [*02AF.0020.0002.0700] # SYRIAC END OF PARAGRAPH +0701 ; [*0276.0020.0002.0701] # SYRIAC SUPRALINEAR FULL STOP +0702 ; [*0277.0020.0002.0702] # SYRIAC SUBLINEAR FULL STOP +0703 ; [*023A.0020.0002.0703] # SYRIAC SUPRALINEAR COLON +0704 ; [*023B.0020.0002.0704] # SYRIAC SUBLINEAR COLON +0705 ; [*023C.0020.0002.0705] # SYRIAC HORIZONTAL COLON +0706 ; [*023D.0020.0002.0706] # SYRIAC COLON SKEWED LEFT +0707 ; [*023E.0020.0002.0707] # SYRIAC COLON SKEWED RIGHT +0708 ; [*023F.0020.0002.0708] # SYRIAC SUPRALINEAR COLON SKEWED LEFT +0709 ; [*0268.0020.0002.0709] # SYRIAC SUBLINEAR COLON SKEWED RIGHT +070A ; [*03B1.0020.0002.070A] # SYRIAC CONTRACTION +070B ; [*03B2.0020.0002.070B] # SYRIAC HARKLEAN OBELUS +070C ; [*03B3.0020.0002.070C] # SYRIAC HARKLEAN METOBELUS +070D ; [*03B4.0020.0002.070D] # SYRIAC HARKLEAN ASTERISCUS +0740 ; [.0000.0000.0000.0740] # SYRIAC FEMININE DOT +0743 ; [.0000.0000.0000.0743] # SYRIAC TWO VERTICAL DOTS ABOVE +0744 ; [.0000.0000.0000.0744] # SYRIAC TWO VERTICAL DOTS BELOW +0747 ; [.0000.0000.0000.0747] # SYRIAC OBLIQUE LINE ABOVE +0748 ; [.0000.0000.0000.0748] # SYRIAC OBLIQUE LINE BELOW +0749 ; [.0000.0000.0000.0749] # SYRIAC MUSIC +074A ; [.0000.0000.0000.074A] # SYRIAC BARREKH +07F6 ; [*049C.0020.0002.07F6] # NKO SYMBOL OO DENNEN +07F7 ; [*02B0.0020.0002.07F7] # NKO SYMBOL GBAKURUNEN +07F8 ; [*0229.0020.0002.07F8] # NKO COMMA +07F9 ; [*0261.0020.0002.07F9] # NKO EXCLAMATION MARK +07FA ; [.0000.0000.0000.07FA] # NKO LAJANYALAN +0830 ; [*0240.0020.0002.0830] # SAMARITAN PUNCTUATION NEQUDAA +0831 ; [*0241.0020.0002.0831] # SAMARITAN PUNCTUATION AFSAAQ +0832 ; [*0242.0020.0002.0832] # SAMARITAN PUNCTUATION ANGED +0833 ; [*0243.0020.0002.0833] # SAMARITAN PUNCTUATION BAU +0834 ; [*0244.0020.0002.0834] # SAMARITAN PUNCTUATION ATMAAU +0835 ; [*0245.0020.0002.0835] # SAMARITAN PUNCTUATION SHIYYAALAA +0836 ; [*0246.0020.0002.0836] # SAMARITAN ABBREVIATION MARK +0837 ; [*0247.0020.0002.0837] # SAMARITAN PUNCTUATION MELODIC QITSA +0838 ; [*0248.0020.0002.0838] # SAMARITAN PUNCTUATION ZIQAA +0839 ; [*0249.0020.0002.0839] # SAMARITAN PUNCTUATION QITSA +083A ; [*024A.0020.0002.083A] # SAMARITAN PUNCTUATION ZAEF +083B ; [*024B.0020.0002.083B] # SAMARITAN PUNCTUATION TURU +083C ; [*024C.0020.0002.083C] # SAMARITAN PUNCTUATION ARKAANU +083D ; [*024D.0020.0002.083D] # SAMARITAN PUNCTUATION SOF MASHFAAT +083E ; [*024E.0020.0002.083E] # SAMARITAN PUNCTUATION ANNAAU +085E ; [*03B5.0020.0002.085E] # MANDAIC PUNCTUATION +08EA ; [.0000.0000.0000.08EA] # ARABIC TONE ONE DOT ABOVE +08EB ; [.0000.0000.0000.08EB] # ARABIC TONE TWO DOTS ABOVE +08EC ; [.0000.0000.0000.08EC] # ARABIC TONE LOOP ABOVE +08ED ; [.0000.0000.0000.08ED] # ARABIC TONE ONE DOT BELOW +08EE ; [.0000.0000.0000.08EE] # ARABIC TONE TWO DOTS BELOW +08EF ; [.0000.0000.0000.08EF] # ARABIC TONE LOOP BELOW +08F3 ; [.0000.0000.0000.08F3] # ARABIC SMALL HIGH WAW +0951 ; [.0000.0000.0000.0951] # DEVANAGARI STRESS SIGN UDATTA +0952 ; [.0000.0000.0000.0952] # DEVANAGARI STRESS SIGN ANUDATTA +0964 ; [*0287.0020.0002.0964] # DEVANAGARI DANDA +0965 ; [*0288.0020.0002.0965] # DEVANAGARI DOUBLE DANDA +0970 ; [*03B7.0020.0002.0970] # DEVANAGARI ABBREVIATION SIGN +09F4 ; [*14BF.0020.0002.09F4] # BENGALI CURRENCY NUMERATOR ONE +09F5 ; [*14C0.0020.0002.09F5] # BENGALI CURRENCY NUMERATOR TWO +09F6 ; [*14C1.0020.0002.09F6] # BENGALI CURRENCY NUMERATOR THREE +09F7 ; [*14C2.0020.0002.09F7] # BENGALI CURRENCY NUMERATOR FOUR +09F8 ; [*14C3.0020.0002.09F8] # BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR +09F9 ; [*14C4.0020.0002.09F9] # BENGALI CURRENCY DENOMINATOR SIXTEEN +09FA ; [*049D.0020.0002.09FA] # BENGALI ISSHAR +0AF0 ; [*03BB.0020.0002.0AF0] # GUJARATI ABBREVIATION SIGN +0B70 ; [*049E.0020.0002.0B70] # ORIYA ISSHAR +0B72 ; [*14C5.0020.0002.0B72] # ORIYA FRACTION ONE QUARTER +0B73 ; [*14C6.0020.0002.0B73] # ORIYA FRACTION ONE HALF +0B74 ; [*14C7.0020.0002.0B74] # ORIYA FRACTION THREE QUARTERS +0B75 ; [*14C8.0020.0002.0B75] # ORIYA FRACTION ONE SIXTEENTH +0B76 ; [*14C9.0020.0002.0B76] # ORIYA FRACTION ONE EIGHTH +0B77 ; [*14CA.0020.0002.0B77] # ORIYA FRACTION THREE SIXTEENTHS +0BF0 ; [*14D1.0020.0002.0BF0] # TAMIL NUMBER TEN +0BF1 ; [*14D2.0020.0002.0BF1] # TAMIL NUMBER ONE HUNDRED +0BF2 ; [*14D3.0020.0002.0BF2] # TAMIL NUMBER ONE THOUSAND +0BF3 ; [*049F.0020.0002.0BF3] # TAMIL DAY SIGN +0BF4 ; [*04A0.0020.0002.0BF4] # TAMIL MONTH SIGN +0BF5 ; [*04A1.0020.0002.0BF5] # TAMIL YEAR SIGN +0BF6 ; [*04A2.0020.0002.0BF6] # TAMIL DEBIT SIGN +0BF7 ; [*04A3.0020.0002.0BF7] # TAMIL CREDIT SIGN +0BF8 ; [*04A4.0020.0002.0BF8] # TAMIL AS ABOVE SIGN +0BFA ; [*04A5.0020.0002.0BFA] # TAMIL NUMBER SIGN +0C7F ; [*04A6.0020.0002.0C7F] # TELUGU SIGN TUUMU +0D70 ; [*14D4.0020.0002.0D70] # MALAYALAM NUMBER TEN +0D71 ; [*14D5.0020.0002.0D71] # MALAYALAM NUMBER ONE HUNDRED +0D72 ; [*14D6.0020.0002.0D72] # MALAYALAM NUMBER ONE THOUSAND +0D73 ; [*14D7.0020.0002.0D73] # MALAYALAM FRACTION ONE QUARTER +0D74 ; [*14D8.0020.0002.0D74] # MALAYALAM FRACTION ONE HALF +0D75 ; [*14D9.0020.0002.0D75] # MALAYALAM FRACTION THREE QUARTERS +0D79 ; [*04A7.0020.0002.0D79] # MALAYALAM DATE MARK +0DF4 ; [*03BC.0020.0002.0DF4] # SINHALA PUNCTUATION KUNDDALIYA +0E4F ; [*03BD.0020.0002.0E4F] # THAI CHARACTER FONGMAN +0E5A ; [*03BE.0020.0002.0E5A] # THAI CHARACTER ANGKHANKHU +0E5B ; [*03BF.0020.0002.0E5B] # THAI CHARACTER KHOMUT +0F01 ; [*04AF.0020.0002.0F01] # TIBETAN MARK GTER YIG MGO TRUNCATED A +0F02 ; [*04B0.0020.0002.0F02] # TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA +0F03 ; [*04B1.0020.0002.0F03] # TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA +0F04 ; [*03C2.0020.0002.0F04] # TIBETAN MARK INITIAL YIG MGO MDUN MA +0F05 ; [*03C3.0020.0002.0F05] # TIBETAN MARK CLOSING YIG MGO SGAB MA +0F06 ; [*03C4.0020.0002.0F06] # TIBETAN MARK CARET YIG MGO PHUR SHAD MA +0F07 ; [*03C5.0020.0002.0F07] # TIBETAN MARK YIG MGO TSHEG SHAD MA +0F08 ; [*03C6.0020.0002.0F08] # TIBETAN MARK SBRUL SHAD +0F09 ; [*03C7.0020.0002.0F09] # TIBETAN MARK BSKUR YIG MGO +0F0A ; [*03C8.0020.0002.0F0A] # TIBETAN MARK BKA- SHOG YIG MGO +0F0B ; [*03CB.0020.0002.0F0B] # TIBETAN MARK INTERSYLLABIC TSHEG +0F0C ; [*03CB.0020.001B.0F0C] # TIBETAN MARK DELIMITER TSHEG BSTAR +0F0D ; [*03CC.0020.0002.0F0D] # TIBETAN MARK SHAD +0F0E ; [*03CD.0020.0002.0F0E] # TIBETAN MARK NYIS SHAD +0F0F ; [*03CE.0020.0002.0F0F] # TIBETAN MARK TSHEG SHAD +0F10 ; [*03CF.0020.0002.0F10] # TIBETAN MARK NYIS TSHEG SHAD +0F11 ; [*03D0.0020.0002.0F11] # TIBETAN MARK RIN CHEN SPUNGS SHAD +0F12 ; [*03D1.0020.0002.0F12] # TIBETAN MARK RGYA GRAM SHAD +0F13 ; [*04B2.0020.0002.0F13] # TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN +0F14 ; [*0256.0020.0002.0F14] # TIBETAN MARK GTER TSHEG +0F15 ; [*04B3.0020.0002.0F15] # TIBETAN LOGOTYPE SIGN CHAD RTAGS +0F16 ; [*04B4.0020.0002.0F16] # TIBETAN LOGOTYPE SIGN LHAG RTAGS +0F17 ; [*04B5.0020.0002.0F17] # TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS +0F18 ; [.0000.0000.0000.0F18] # TIBETAN ASTROLOGICAL SIGN -KHYUD PA +0F19 ; [.0000.0000.0000.0F19] # TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS +0F1A ; [*04B6.0020.0002.0F1A] # TIBETAN SIGN RDEL DKAR GCIG +0F1B ; [*04B7.0020.0002.0F1B] # TIBETAN SIGN RDEL DKAR GNYIS +0F1C ; [*04B8.0020.0002.0F1C] # TIBETAN SIGN RDEL DKAR GSUM +0F1D ; [*04B9.0020.0002.0F1D] # TIBETAN SIGN RDEL NAG GCIG +0F1E ; [*04BA.0020.0002.0F1E] # TIBETAN SIGN RDEL NAG GNYIS +0F1F ; [*04BB.0020.0002.0F1F] # TIBETAN SIGN RDEL DKAR RDEL NAG +0F34 ; [*04BC.0020.0002.0F34] # TIBETAN MARK BSDUS RTAGS +0F35 ; [.0000.0000.0000.0F35] # TIBETAN MARK NGAS BZUNG NYI ZLA +0F36 ; [*04BD.0020.0002.0F36] # TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN +0F37 ; [.0000.0000.0000.0F37] # TIBETAN MARK NGAS BZUNG SGOR RTAGS +0F38 ; [*04BE.0020.0002.0F38] # TIBETAN MARK CHE MGO +0F3A ; [*0301.0020.0002.0F3A] # TIBETAN MARK GUG RTAGS GYON +0F3B ; [*0302.0020.0002.0F3B] # TIBETAN MARK GUG RTAGS GYAS +0F3C ; [*0303.0020.0002.0F3C] # TIBETAN MARK ANG KHANG GYON +0F3D ; [*0304.0020.0002.0F3D] # TIBETAN MARK ANG KHANG GYAS +0F3E ; [.0000.0000.0000.0F3E] # TIBETAN SIGN YAR TSHES +0F3F ; [.0000.0000.0000.0F3F] # TIBETAN SIGN MAR TSHES +0F82 ; [.0000.0000.0000.0F82] # TIBETAN SIGN NYI ZLA NAA DA +0F83 ; [.0000.0000.0000.0F83] # TIBETAN SIGN SNA LDAN +0F85 ; [*03D2.0020.0002.0F85] # TIBETAN MARK PALUTA +0F86 ; [.0000.0000.0000.0F86] # TIBETAN SIGN LCI RTAGS +0F87 ; [.0000.0000.0000.0F87] # TIBETAN SIGN YANG RTAGS +0FBE ; [*04BF.0020.0002.0FBE] # TIBETAN KU RU KHA +0FBF ; [*04C0.0020.0002.0FBF] # TIBETAN KU RU KHA BZHI MIG CAN +0FC0 ; [*04C1.0020.0002.0FC0] # TIBETAN CANTILLATION SIGN HEAVY BEAT +0FC1 ; [*04C2.0020.0002.0FC1] # TIBETAN CANTILLATION SIGN LIGHT BEAT +0FC2 ; [*04C3.0020.0002.0FC2] # TIBETAN CANTILLATION SIGN CANG TE-U +0FC3 ; [*04C4.0020.0002.0FC3] # TIBETAN CANTILLATION SIGN SBUB -CHAL +0FC4 ; [*04C5.0020.0002.0FC4] # TIBETAN SYMBOL DRIL BU +0FC5 ; [*04C6.0020.0002.0FC5] # TIBETAN SYMBOL RDO RJE +0FC6 ; [.0000.0000.0000.0FC6] # TIBETAN SYMBOL PADMA GDAN +0FC7 ; [*04C7.0020.0002.0FC7] # TIBETAN SYMBOL RDO RJE RGYA GRAM +0FC8 ; [*04C8.0020.0002.0FC8] # TIBETAN SYMBOL PHUR PA +0FC9 ; [*04C9.0020.0002.0FC9] # TIBETAN SYMBOL NOR BU +0FCA ; [*04CA.0020.0002.0FCA] # TIBETAN SYMBOL NOR BU NYIS -KHYIL +0FCB ; [*04CB.0020.0002.0FCB] # TIBETAN SYMBOL NOR BU GSUM -KHYIL +0FCC ; [*04CC.0020.0002.0FCC] # TIBETAN SYMBOL NOR BU BZHI -KHYIL +0FCE ; [*04CD.0020.0002.0FCE] # TIBETAN SIGN RDEL NAG RDEL DKAR +0FCF ; [*04CE.0020.0002.0FCF] # TIBETAN SIGN RDEL NAG GSUM +0FD0 ; [*03C9.0020.0002.0FD0] # TIBETAN MARK BSKA- SHOG GI MGO RGYAN +0FD1 ; [*03CA.0020.0002.0FD1] # TIBETAN MARK MNYAM YIG GI MGO RGYAN +0FD2 ; [*03D3.0020.0002.0FD2] # TIBETAN MARK NYIS TSHEG +0FD3 ; [*03D4.0020.0002.0FD3] # TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA +0FD4 ; [*03D5.0020.0002.0FD4] # TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA +0FD5 ; [*04CF.0020.0002.0FD5] # RIGHT-FACING SVASTI SIGN +0FD6 ; [*04D0.0020.0002.0FD6] # LEFT-FACING SVASTI SIGN +0FD7 ; [*04D1.0020.0002.0FD7] # RIGHT-FACING SVASTI SIGN WITH DOTS +0FD8 ; [*04D2.0020.0002.0FD8] # LEFT-FACING SVASTI SIGN WITH DOTS +0FD9 ; [*03D6.0020.0002.0FD9] # TIBETAN MARK LEADING MCHAN RTAGS +0FDA ; [*03D7.0020.0002.0FDA] # TIBETAN MARK TRAILING MCHAN RTAGS +104A ; [*0292.0020.0002.104A] # MYANMAR SIGN LITTLE SECTION +104B ; [*0293.0020.0002.104B] # MYANMAR SIGN SECTION +104C ; [*03DB.0020.0002.104C] # MYANMAR SYMBOL LOCATIVE +104D ; [*03DC.0020.0002.104D] # MYANMAR SYMBOL COMPLETED +104E ; [*03DD.0020.0002.104E] # MYANMAR SYMBOL AFOREMENTIONED +104F ; [*03DE.0020.0002.104F] # MYANMAR SYMBOL GENITIVE +109E ; [*04D4.0020.0002.109E] # MYANMAR SYMBOL SHAN ONE +109F ; [*04D5.0020.0002.109F] # MYANMAR SYMBOL SHAN EXCLAMATION +10FB ; [*02B1.0020.0002.10FB] # GEORGIAN PARAGRAPH SEPARATOR +1360 ; [*02B2.0020.0002.1360] # ETHIOPIC SECTION MARK +1361 ; [*024F.0020.0002.1361] # ETHIOPIC WORDSPACE +1362 ; [*0278.0020.0002.1362] # ETHIOPIC FULL STOP +1363 ; [*0250.0020.0002.1363] # ETHIOPIC COMMA +1364 ; [*0251.0020.0002.1364] # ETHIOPIC SEMICOLON +1365 ; [*0252.0020.0002.1365] # ETHIOPIC COLON +1366 ; [*0253.0020.0002.1366] # ETHIOPIC PREFACE COLON +1367 ; [*0269.0020.0002.1367] # ETHIOPIC QUESTION MARK +1368 ; [*02B3.0020.0002.1368] # ETHIOPIC PARAGRAPH SEPARATOR +1372 ; [*14DA.0020.0002.1372] # ETHIOPIC NUMBER TEN +1373 ; [*14DB.0020.0002.1373] # ETHIOPIC NUMBER TWENTY +1374 ; [*14DC.0020.0002.1374] # ETHIOPIC NUMBER THIRTY +1375 ; [*14DD.0020.0002.1375] # ETHIOPIC NUMBER FORTY +1376 ; [*14DE.0020.0002.1376] # ETHIOPIC NUMBER FIFTY +1377 ; [*14DF.0020.0002.1377] # ETHIOPIC NUMBER SIXTY +1378 ; [*14E0.0020.0002.1378] # ETHIOPIC NUMBER SEVENTY +1379 ; [*14E1.0020.0002.1379] # ETHIOPIC NUMBER EIGHTY +137A ; [*14E2.0020.0002.137A] # ETHIOPIC NUMBER NINETY +137B ; [*14E3.0020.0002.137B] # ETHIOPIC NUMBER HUNDRED +137C ; [*14E4.0020.0002.137C] # ETHIOPIC NUMBER TEN THOUSAND +1390 ; [*0453.0020.0002.1390] # ETHIOPIC TONAL MARK YIZET +1391 ; [*0454.0020.0002.1391] # ETHIOPIC TONAL MARK DERET +1392 ; [*0455.0020.0002.1392] # ETHIOPIC TONAL MARK RIKRIK +1393 ; [*0456.0020.0002.1393] # ETHIOPIC TONAL MARK SHORT RIKRIK +1394 ; [*0457.0020.0002.1394] # ETHIOPIC TONAL MARK DIFAT +1395 ; [*0458.0020.0002.1395] # ETHIOPIC TONAL MARK KENAT +1396 ; [*0459.0020.0002.1396] # ETHIOPIC TONAL MARK CHIRET +1397 ; [*045A.0020.0002.1397] # ETHIOPIC TONAL MARK HIDET +1398 ; [*045B.0020.0002.1398] # ETHIOPIC TONAL MARK DERET-HIDET +1399 ; [*045C.0020.0002.1399] # ETHIOPIC TONAL MARK KURT +1400 ; [*0210.0020.0002.1400] # CANADIAN SYLLABICS HYPHEN +166D ; [*03EB.0020.0002.166D] # CANADIAN SYLLABICS CHI SIGN +166E ; [*027B.0020.0002.166E] # CANADIAN SYLLABICS FULL STOP +1680 ; [*020A.0020.0004.1680] # OGHAM SPACE MARK +169B ; [*0305.0020.0002.169B] # OGHAM FEATHER MARK +169C ; [*0306.0020.0002.169C] # OGHAM REVERSED FEATHER MARK +16EB ; [*025A.0020.0002.16EB] # RUNIC SINGLE PUNCTUATION +16EC ; [*025B.0020.0002.16EC] # RUNIC MULTIPLE PUNCTUATION +16ED ; [*025C.0020.0002.16ED] # RUNIC CROSS PUNCTUATION +1735 ; [*028F.0020.0002.1735] # PHILIPPINE SINGLE PUNCTUATION +1736 ; [*0290.0020.0002.1736] # PHILIPPINE DOUBLE PUNCTUATION +17B4 ; [.0000.0000.0000.17B4] # KHMER VOWEL INHERENT AQ +17B5 ; [.0000.0000.0000.17B5] # KHMER VOWEL INHERENT AA +17D3 ; [.0000.0000.0000.17D3] # KHMER SIGN BATHAMASAT +17D4 ; [*0294.0020.0002.17D4] # KHMER SIGN KHAN +17D5 ; [*0295.0020.0002.17D5] # KHMER SIGN BARIYOOSAN +17D6 ; [*0257.0020.0002.17D6] # KHMER SIGN CAMNUC PII KUUH +17D8 ; [*03DF.0020.0002.17D8] # KHMER SIGN BEYYAL +17D9 ; [*03E0.0020.0002.17D9] # KHMER SIGN PHNAEK MUAN +17DA ; [*03E1.0020.0002.17DA] # KHMER SIGN KOOMUUT +1800 ; [*03B6.0020.0002.1800] # MONGOLIAN BIRGA +1801 ; [*0274.0020.0002.1801] # MONGOLIAN ELLIPSIS +1802 ; [*022A.0020.0002.1802] # MONGOLIAN COMMA +1803 ; [*0279.0020.0002.1803] # MONGOLIAN FULL STOP +1804 ; [*0254.0020.0002.1804] # MONGOLIAN COLON +1805 ; [*0255.0020.0002.1805] # MONGOLIAN FOUR DOTS +1806 ; [*0212.0020.0002.1806] # MONGOLIAN TODO SOFT HYPHEN +1807 ; [*0213.0020.0002.1807] # MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER +1808 ; [*022B.0020.0002.1808] # MONGOLIAN MANCHU COMMA +1809 ; [*027A.0020.0002.1809] # MONGOLIAN MANCHU FULL STOP +180A ; [.0000.0000.0000.180A] # MONGOLIAN NIRUGU +180E ; [*0207.0020.0002.180E] # MONGOLIAN VOWEL SEPARATOR +1940 ; [*04D3.0020.0002.1940] # LIMBU SIGN LOO +1944 ; [*0262.0020.0002.1944] # LIMBU EXCLAMATION MARK +1945 ; [*026A.0020.0002.1945] # LIMBU QUESTION MARK +19E0 ; [*04D9.0020.0002.19E0] # KHMER SYMBOL PATHAMASAT +19E1 ; [*04DA.0020.0002.19E1] # KHMER SYMBOL MUOY KOET +19E2 ; [*04DB.0020.0002.19E2] # KHMER SYMBOL PII KOET +19E3 ; [*04DC.0020.0002.19E3] # KHMER SYMBOL BEI KOET +19E4 ; [*04DD.0020.0002.19E4] # KHMER SYMBOL BUON KOET +19E5 ; [*04DE.0020.0002.19E5] # KHMER SYMBOL PRAM KOET +19E6 ; [*04DF.0020.0002.19E6] # KHMER SYMBOL PRAM-MUOY KOET +19E7 ; [*04E0.0020.0002.19E7] # KHMER SYMBOL PRAM-PII KOET +19E8 ; [*04E1.0020.0002.19E8] # KHMER SYMBOL PRAM-BEI KOET +19E9 ; [*04E2.0020.0002.19E9] # KHMER SYMBOL PRAM-BUON KOET +19EA ; [*04E3.0020.0002.19EA] # KHMER SYMBOL DAP KOET +19EB ; [*04E4.0020.0002.19EB] # KHMER SYMBOL DAP-MUOY KOET +19EC ; [*04E5.0020.0002.19EC] # KHMER SYMBOL DAP-PII KOET +19ED ; [*04E6.0020.0002.19ED] # KHMER SYMBOL DAP-BEI KOET +19EE ; [*04E7.0020.0002.19EE] # KHMER SYMBOL DAP-BUON KOET +19EF ; [*04E8.0020.0002.19EF] # KHMER SYMBOL DAP-PRAM KOET +19F0 ; [*04E9.0020.0002.19F0] # KHMER SYMBOL TUTEYASAT +19F1 ; [*04EA.0020.0002.19F1] # KHMER SYMBOL MUOY ROC +19F2 ; [*04EB.0020.0002.19F2] # KHMER SYMBOL PII ROC +19F3 ; [*04EC.0020.0002.19F3] # KHMER SYMBOL BEI ROC +19F4 ; [*04ED.0020.0002.19F4] # KHMER SYMBOL BUON ROC +19F5 ; [*04EE.0020.0002.19F5] # KHMER SYMBOL PRAM ROC +19F6 ; [*04EF.0020.0002.19F6] # KHMER SYMBOL PRAM-MUOY ROC +19F7 ; [*04F0.0020.0002.19F7] # KHMER SYMBOL PRAM-PII ROC +19F8 ; [*04F1.0020.0002.19F8] # KHMER SYMBOL PRAM-BEI ROC +19F9 ; [*04F2.0020.0002.19F9] # KHMER SYMBOL PRAM-BUON ROC +19FA ; [*04F3.0020.0002.19FA] # KHMER SYMBOL DAP ROC +19FB ; [*04F4.0020.0002.19FB] # KHMER SYMBOL DAP-MUOY ROC +19FC ; [*04F5.0020.0002.19FC] # KHMER SYMBOL DAP-PII ROC +19FD ; [*04F6.0020.0002.19FD] # KHMER SYMBOL DAP-BEI ROC +19FE ; [*04F7.0020.0002.19FE] # KHMER SYMBOL DAP-BUON ROC +19FF ; [*04F8.0020.0002.19FF] # KHMER SYMBOL DAP-PRAM ROC +1A1E ; [*02B4.0020.0002.1A1E] # BUGINESE PALLAWA +1A1F ; [*02B5.0020.0002.1A1F] # BUGINESE END OF SECTION +1A7F ; [.0000.0000.0000.1A7F] # TAI THAM COMBINING CRYPTOGRAMMIC DOT +1AA0 ; [*03E2.0020.0002.1AA0] # TAI THAM SIGN WIANG +1AA1 ; [*03E3.0020.0002.1AA1] # TAI THAM SIGN WIANGWAAK +1AA2 ; [*03E4.0020.0002.1AA2] # TAI THAM SIGN SAWAN +1AA3 ; [*03E5.0020.0002.1AA3] # TAI THAM SIGN KEOW +1AA4 ; [*03E6.0020.0002.1AA4] # TAI THAM SIGN HOY +1AA5 ; [*03E7.0020.0002.1AA5] # TAI THAM SIGN DOKMAI +1AA6 ; [*03E8.0020.0002.1AA6] # TAI THAM SIGN REVERSED ROTATED RANA +1AA8 ; [*0296.0020.0002.1AA8] # TAI THAM SIGN KAAN +1AA9 ; [*0297.0020.0002.1AA9] # TAI THAM SIGN KAANKUU +1AAA ; [*0298.0020.0002.1AAA] # TAI THAM SIGN SATKAAN +1AAB ; [*0299.0020.0002.1AAB] # TAI THAM SIGN SATKAANKUU +1AAC ; [*03E9.0020.0002.1AAC] # TAI THAM SIGN HANG +1AAD ; [*03EA.0020.0002.1AAD] # TAI THAM SIGN CAANG +1B5A ; [*02B6.0020.0002.1B5A] # BALINESE PANTI +1B5B ; [*02B7.0020.0002.1B5B] # BALINESE PAMADA +1B5C ; [*027C.0020.0002.1B5C] # BALINESE WINDU +1B5D ; [*0258.0020.0002.1B5D] # BALINESE CARIK PAMUNGKAH +1B5E ; [*029A.0020.0002.1B5E] # BALINESE CARIK SIKI +1B5F ; [*029B.0020.0002.1B5F] # BALINESE CARIK PAREREN +1B60 ; [*0211.0020.0002.1B60] # BALINESE PAMENENG +1B61 ; [*04F9.0020.0002.1B61] # BALINESE MUSICAL SYMBOL DONG +1B62 ; [*04FA.0020.0002.1B62] # BALINESE MUSICAL SYMBOL DENG +1B63 ; [*04FB.0020.0002.1B63] # BALINESE MUSICAL SYMBOL DUNG +1B64 ; [*04FC.0020.0002.1B64] # BALINESE MUSICAL SYMBOL DANG +1B65 ; [*04FD.0020.0002.1B65] # BALINESE MUSICAL SYMBOL DANG SURANG +1B66 ; [*04FE.0020.0002.1B66] # BALINESE MUSICAL SYMBOL DING +1B67 ; [*04FF.0020.0002.1B67] # BALINESE MUSICAL SYMBOL DAENG +1B68 ; [*0500.0020.0002.1B68] # BALINESE MUSICAL SYMBOL DEUNG +1B69 ; [*0501.0020.0002.1B69] # BALINESE MUSICAL SYMBOL DAING +1B6A ; [*0502.0020.0002.1B6A] # BALINESE MUSICAL SYMBOL DANG GEDE +1B6B ; [.0000.0000.0000.1B6B] # BALINESE MUSICAL SYMBOL COMBINING TEGEH +1B6C ; [.0000.0000.0000.1B6C] # BALINESE MUSICAL SYMBOL COMBINING ENDEP +1B6D ; [.0000.0000.0000.1B6D] # BALINESE MUSICAL SYMBOL COMBINING KEMPUL +1B6E ; [.0000.0000.0000.1B6E] # BALINESE MUSICAL SYMBOL COMBINING KEMPLI +1B6F ; [.0000.0000.0000.1B6F] # BALINESE MUSICAL SYMBOL COMBINING JEGOGAN +1B70 ; [.0000.0000.0000.1B70] # BALINESE MUSICAL SYMBOL COMBINING KEMPUL WITH JEGOGAN +1B71 ; [.0000.0000.0000.1B71] # BALINESE MUSICAL SYMBOL COMBINING KEMPLI WITH JEGOGAN +1B72 ; [.0000.0000.0000.1B72] # BALINESE MUSICAL SYMBOL COMBINING BENDE +1B73 ; [.0000.0000.0000.1B73] # BALINESE MUSICAL SYMBOL COMBINING GONG +1B74 ; [*0503.0020.0002.1B74] # BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG +1B75 ; [*0504.0020.0002.1B75] # BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DAG +1B76 ; [*0505.0020.0002.1B76] # BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TUK +1B77 ; [*0506.0020.0002.1B77] # BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TAK +1B78 ; [*0507.0020.0002.1B78] # BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PANG +1B79 ; [*0508.0020.0002.1B79] # BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PUNG +1B7A ; [*0509.0020.0002.1B7A] # BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLAK +1B7B ; [*050A.0020.0002.1B7B] # BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLUK +1B7C ; [*050B.0020.0002.1B7C] # BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING +1BFC ; [*03F7.0020.0002.1BFC] # BATAK SYMBOL BINDU NA METEK +1BFD ; [*03F8.0020.0002.1BFD] # BATAK SYMBOL BINDU PINARBORAS +1BFE ; [*03F9.0020.0002.1BFE] # BATAK SYMBOL BINDU JUDUL +1BFF ; [*03FA.0020.0002.1BFF] # BATAK SYMBOL BINDU PANGOLAT +1C3B ; [*028B.0020.0002.1C3B] # LEPCHA PUNCTUATION TA-ROL +1C3C ; [*028C.0020.0002.1C3C] # LEPCHA PUNCTUATION NYET THYOOM TA-ROL +1C3D ; [*03D8.0020.0002.1C3D] # LEPCHA PUNCTUATION CER-WA +1C3E ; [*03D9.0020.0002.1C3E] # LEPCHA PUNCTUATION TSHOOK CER-WA +1C3F ; [*03DA.0020.0002.1C3F] # LEPCHA PUNCTUATION TSHOOK +1C7E ; [*02AD.0020.0002.1C7E] # OL CHIKI PUNCTUATION MUCAAD +1C7F ; [*02AE.0020.0002.1C7F] # OL CHIKI PUNCTUATION DOUBLE MUCAAD +1CC0 ; [*03EC.0020.0002.1CC0] # SUNDANESE PUNCTUATION BINDU SURYA +1CC1 ; [*03ED.0020.0002.1CC1] # SUNDANESE PUNCTUATION BINDU PANGLONG +1CC2 ; [*03EE.0020.0002.1CC2] # SUNDANESE PUNCTUATION BINDU PURNAMA +1CC3 ; [*03EF.0020.0002.1CC3] # SUNDANESE PUNCTUATION BINDU CAKRA +1CC4 ; [*03F0.0020.0002.1CC4] # SUNDANESE PUNCTUATION BINDU LEU SATANGA +1CC5 ; [*03F1.0020.0002.1CC5] # SUNDANESE PUNCTUATION BINDU KA SATANGA +1CC6 ; [*03F2.0020.0002.1CC6] # SUNDANESE PUNCTUATION BINDU DA SATANGA +1CC7 ; [*03F3.0020.0002.1CC7] # SUNDANESE PUNCTUATION BINDU BA SATANGA +1CD0 ; [.0000.0000.0000.1CD0] # VEDIC TONE KARSHANA +1CD1 ; [.0000.0000.0000.1CD1] # VEDIC TONE SHARA +1CD2 ; [.0000.0000.0000.1CD2] # VEDIC TONE PRENKHA +1CD3 ; [.0000.0000.0000.1CD3] # VEDIC SIGN NIHSHVASA +1CD4 ; [.0000.0000.0000.1CD4] # VEDIC SIGN YAJURVEDIC MIDLINE SVARITA +1CD5 ; [.0000.0000.0000.1CD5] # VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA +1CD6 ; [.0000.0000.0000.1CD6] # VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA +1CD7 ; [.0000.0000.0000.1CD7] # VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA +1CD8 ; [.0000.0000.0000.1CD8] # VEDIC TONE CANDRA BELOW +1CD9 ; [.0000.0000.0000.1CD9] # VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER +1CDA ; [.0000.0000.0000.1CDA] # VEDIC TONE DOUBLE SVARITA +1CDB ; [.0000.0000.0000.1CDB] # VEDIC TONE TRIPLE SVARITA +1CDC ; [.0000.0000.0000.1CDC] # VEDIC TONE KATHAKA ANUDATTA +1CDD ; [.0000.0000.0000.1CDD] # VEDIC TONE DOT BELOW +1CDE ; [.0000.0000.0000.1CDE] # VEDIC TONE TWO DOTS BELOW +1CDF ; [.0000.0000.0000.1CDF] # VEDIC TONE THREE DOTS BELOW +1CE0 ; [.0000.0000.0000.1CE0] # VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA +1CE1 ; [.0000.0000.0000.1CE1] # VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA +1CE2 ; [.0000.0000.0000.1CE2] # VEDIC SIGN VISARGA SVARITA +1CE3 ; [.0000.0000.0000.1CE3] # VEDIC SIGN VISARGA UDATTA +1CE4 ; [.0000.0000.0000.1CE4] # VEDIC SIGN REVERSED VISARGA UDATTA +1CE5 ; [.0000.0000.0000.1CE5] # VEDIC SIGN VISARGA ANUDATTA +1CE6 ; [.0000.0000.0000.1CE6] # VEDIC SIGN REVERSED VISARGA ANUDATTA +1CE7 ; [.0000.0000.0000.1CE7] # VEDIC SIGN VISARGA UDATTA WITH TAIL +1CE8 ; [.0000.0000.0000.1CE8] # VEDIC SIGN VISARGA ANUDATTA WITH TAIL +1CF4 ; [.0000.0000.0000.1CF4] # VEDIC TONE CANDRA ABOVE +1FBD ; [*041B.0020.0002.1FBD] # GREEK KORONIS +1FBF ; [*041B.0020.0002.1FBF] # GREEK PSILI +1FC0 ; [*041D.0020.0002.1FC0] # GREEK PERISPOMENI +1FC1 ; [*0416.0020.0002.00A8][.0000.0045.0002.0342] # GREEK DIALYTIKA AND PERISPOMENI +1FCD ; [*041B.0020.0002.1FBF][.0000.0035.0002.0300] # GREEK PSILI AND VARIA +1FCE ; [*041B.0020.0002.1FBF][.0000.0032.0002.0301] # GREEK PSILI AND OXIA +1FCF ; [*041B.0020.0002.1FBF][.0000.0045.0002.0342] # GREEK PSILI AND PERISPOMENI +1FDD ; [*041C.0020.0002.1FFE][.0000.0035.0002.0300] # GREEK DASIA AND VARIA +1FDE ; [*041C.0020.0002.1FFE][.0000.0032.0002.0301] # GREEK DASIA AND OXIA +1FDF ; [*041C.0020.0002.1FFE][.0000.0045.0002.0342] # GREEK DASIA AND PERISPOMENI +1FED ; [*0416.0020.0002.00A8][.0000.0035.0002.0300] # GREEK DIALYTIKA AND VARIA +1FEE ; [*0416.0020.0002.00A8][.0000.0032.0002.0301] # GREEK DIALYTIKA AND OXIA +1FEF ; [*040F.0020.0002.1FEF] # GREEK VARIA +1FFD ; [*0410.0020.0002.1FFD] # GREEK OXIA +1FFE ; [*041C.0020.0002.1FFE] # GREEK DASIA +2000 ; [*020A.0020.0004.2000] # EN QUAD +2001 ; [*020A.0020.0004.2001] # EM QUAD +2002 ; [*020A.0020.0004.2002] # EN SPACE +2003 ; [*020A.0020.0004.2003] # EM SPACE +2004 ; [*020A.0020.0004.2004] # THREE-PER-EM SPACE +2005 ; [*020A.0020.0004.2005] # FOUR-PER-EM SPACE +2006 ; [*020A.0020.0004.2006] # SIX-PER-EM SPACE +2007 ; [*020A.0020.001B.2007] # FIGURE SPACE +2008 ; [*020A.0020.0004.2008] # PUNCTUATION SPACE +2009 ; [*020A.0020.0004.2009] # THIN SPACE +200A ; [*020A.0020.0004.200A] # HAIR SPACE +2010 ; [*0214.0020.0002.2010] # HYPHEN +2011 ; [*0214.0020.001B.2011] # NON-BREAKING HYPHEN +2012 ; [*0215.0020.0002.2012] # FIGURE DASH +2013 ; [*0216.0020.0002.2013] # EN DASH +2014 ; [*0217.0020.0002.2014] # EM DASH +2015 ; [*0218.0020.0002.2015] # HORIZONTAL BAR +2016 ; [*0363.0020.0002.2016] # DOUBLE VERTICAL LINE +2017 ; [*020D.0020.0002.2017] # DOUBLE LOW LINE +2018 ; [*02EB.0020.0002.2018] # LEFT SINGLE QUOTATION MARK +2019 ; [*02EC.0020.0002.2019] # RIGHT SINGLE QUOTATION MARK +201A ; [*02ED.0020.0002.201A] # SINGLE LOW-9 QUOTATION MARK +201B ; [*02EE.0020.0002.201B] # SINGLE HIGH-REVERSED-9 QUOTATION MARK +201C ; [*02F2.0020.0002.201C] # LEFT DOUBLE QUOTATION MARK +201D ; [*02F3.0020.0002.201D] # RIGHT DOUBLE QUOTATION MARK +201E ; [*02F4.0020.0002.201E] # DOUBLE LOW-9 QUOTATION MARK +201F ; [*02F5.0020.0002.201F] # DOUBLE HIGH-REVERSED-9 QUOTATION MARK +2020 ; [*037D.0020.0002.2020] # DAGGER +2021 ; [*037E.0020.0002.2021] # DOUBLE DAGGER +2022 ; [*0382.0020.0002.2022] # BULLET +2023 ; [*0383.0020.0002.2023] # TRIANGULAR BULLET +2024 ; [*0273.0020.0004.2024] # ONE DOT LEADER +2025 ; [*0273.0020.0004.2025][*0273.0020.0004.2025] # TWO DOT LEADER +2026 ; [*0273.0020.0004.2026][*0273.0020.0004.2026][*0273.0020.001F.2026] # HORIZONTAL ELLIPSIS +2027 ; [*0384.0020.0002.2027] # HYPHENATION POINT +2028 ; [*0208.0020.0002.2028] # LINE SEPARATOR +2029 ; [*0209.0020.0002.2029] # PARAGRAPH SEPARATOR +202F ; [*020A.0020.001B.202F] # NARROW NO-BREAK SPACE +2030 ; [*0379.0020.0002.2030] # PER MILLE SIGN +2031 ; [*037B.0020.0002.2031] # PER TEN THOUSAND SIGN +2032 ; [*0388.0020.0002.2032] # PRIME +2033 ; [*0388.0020.0004.2033][*0388.0020.0004.2033] # DOUBLE PRIME +2034 ; [*0388.0020.0004.2034][*0388.0020.0004.2034][*0388.0020.001F.2034] # TRIPLE PRIME +2035 ; [*0389.0020.0002.2035] # REVERSED PRIME +2036 ; [*0389.0020.0004.2036][*0389.0020.0004.2036] # REVERSED DOUBLE PRIME +2037 ; [*0389.0020.0004.2037][*0389.0020.0004.2037][*0389.0020.001F.2037] # REVERSED TRIPLE PRIME +2038 ; [*038C.0020.0002.2038] # CARET +2039 ; [*02EF.0020.0002.2039] # SINGLE LEFT-POINTING ANGLE QUOTATION MARK +203A ; [*02F0.0020.0002.203A] # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +203B ; [*038D.0020.0002.203B] # REFERENCE MARK +203C ; [*025E.0020.0004.203C][*025E.0020.0004.203C] # DOUBLE EXCLAMATION MARK +203D ; [*0271.0020.0002.203D] # INTERROBANG +203E ; [*020B.0020.0002.203E] # OVERLINE +203F ; [*038E.0020.0002.203F] # UNDERTIE +2040 ; [*0390.0020.0002.2040] # CHARACTER TIE +2041 ; [*0392.0020.0002.2041] # CARET INSERTION POINT +2042 ; [*0393.0020.0002.2042] # ASTERISM +2043 ; [*0385.0020.0002.2043] # HYPHEN BULLET +2044 ; [*05AC.0020.0002.2044] # FRACTION SLASH +2045 ; [*0307.0020.0002.2045] # LEFT SQUARE BRACKET WITH QUILL +2046 ; [*0308.0020.0002.2046] # RIGHT SQUARE BRACKET WITH QUILL +2047 ; [*0263.0020.0004.2047][*0263.0020.0004.2047] # DOUBLE QUESTION MARK +2048 ; [*0263.0020.0004.2048][*025E.0020.0004.2048] # QUESTION EXCLAMATION MARK +2049 ; [*025E.0020.0004.2049][*0263.0020.0004.2049] # EXCLAMATION QUESTION MARK +204A ; [*0375.0020.0002.204A] # TIRONIAN SIGN ET +204B ; [*036B.0020.0002.204B] # REVERSED PILCROW SIGN +204C ; [*0386.0020.0002.204C] # BLACK LEFTWARDS BULLET +204D ; [*0387.0020.0002.204D] # BLACK RIGHTWARDS BULLET +204E ; [*036E.0020.0002.204E] # LOW ASTERISK +204F ; [*0234.0020.0002.204F] # REVERSED SEMICOLON +2050 ; [*0391.0020.0002.2050] # CLOSE UP +2051 ; [*036F.0020.0002.2051] # TWO ASTERISKS ALIGNED VERTICALLY +2052 ; [*05A8.0020.0002.2052] # COMMERCIAL MINUS SIGN +2053 ; [*021B.0020.0002.2053] # SWUNG DASH +2054 ; [*038F.0020.0002.2054] # INVERTED UNDERTIE +2055 ; [*02CF.0020.0002.2055] # FLOWER PUNCTUATION MARK +2056 ; [*02D0.0020.0002.2056] # THREE DOT PUNCTUATION +2057 ; [*0388.0020.0004.2057][*0388.0020.0004.2057][*0388.0020.001F.2057][*0388.0020.001F.2057] # QUADRUPLE PRIME +2058 ; [*02D1.0020.0002.2058] # FOUR DOT PUNCTUATION +2059 ; [*02D2.0020.0002.2059] # FIVE DOT PUNCTUATION +205A ; [*02D3.0020.0002.205A] # TWO DOT PUNCTUATION +205B ; [*02D4.0020.0002.205B] # FOUR DOT MARK +205C ; [*02D5.0020.0002.205C] # DOTTED CROSS +205D ; [*02D6.0020.0002.205D] # TRICOLON +205E ; [*02D7.0020.0002.205E] # VERTICAL FOUR DOTS +205F ; [*020A.0020.0004.205F] # MEDIUM MATHEMATICAL SPACE +2061 ; [.0000.0000.0000.2061] # FUNCTION APPLICATION +2062 ; [.0000.0000.0000.2062] # INVISIBLE TIMES +2063 ; [.0000.0000.0000.2063] # INVISIBLE SEPARATOR +2064 ; [.0000.0000.0000.2064] # INVISIBLE PLUS +207A ; [*059C.0020.0014.207A] # SUPERSCRIPT PLUS SIGN +207B ; [*05A7.0020.0014.207B] # SUPERSCRIPT MINUS +207C ; [*05A1.0020.0014.207C] # SUPERSCRIPT EQUALS SIGN +207D ; [*02FB.0020.0014.207D] # SUPERSCRIPT LEFT PARENTHESIS +207E ; [*02FC.0020.0014.207E] # SUPERSCRIPT RIGHT PARENTHESIS +208A ; [*059C.0020.0015.208A] # SUBSCRIPT PLUS SIGN +208B ; [*05A7.0020.0015.208B] # SUBSCRIPT MINUS +208C ; [*05A1.0020.0015.208C] # SUBSCRIPT EQUALS SIGN +208D ; [*02FB.0020.0015.208D] # SUBSCRIPT LEFT PARENTHESIS +208E ; [*02FC.0020.0015.208E] # SUBSCRIPT RIGHT PARENTHESIS +2104 ; [*050E.0020.0002.2104] # CENTRE LINE SYMBOL +2108 ; [*050F.0020.0002.2108] # SCRUPLE +2114 ; [*0510.0020.0002.2114] # L B BAR SYMBOL +2117 ; [*0511.0020.0002.2117] # SOUND RECORDING COPYRIGHT +2118 ; [*0512.0020.0002.2118] # SCRIPT CAPITAL P +211E ; [*0513.0020.0002.211E] # PRESCRIPTION TAKE +211F ; [*0514.0020.0002.211F] # RESPONSE +2123 ; [*0515.0020.0002.2123] # VERSICLE +2125 ; [*0516.0020.0002.2125] # OUNCE SIGN +2127 ; [*0517.0020.0002.2127] # INVERTED OHM SIGN +2129 ; [*0518.0020.0002.2129] # TURNED GREEK SMALL LETTER IOTA +212E ; [*0519.0020.0002.212E] # ESTIMATED SYMBOL +213A ; [*051A.0020.0002.213A] # ROTATED CAPITAL Q +2140 ; [*059B.0020.0005.2140] # DOUBLE-STRUCK N-ARY SUMMATION +2141 ; [*051B.0020.0002.2141] # TURNED SANS-SERIF CAPITAL G +2142 ; [*051C.0020.0002.2142] # TURNED SANS-SERIF CAPITAL L +2143 ; [*051D.0020.0002.2143] # REVERSED SANS-SERIF CAPITAL L +2144 ; [*051E.0020.0002.2144] # TURNED SANS-SERIF CAPITAL Y +214A ; [*051F.0020.0002.214A] # PROPERTY LINE +214B ; [*0637.0020.0002.214B] # TURNED AMPERSAND +214C ; [*0520.0020.0002.214C] # PER SIGN +214F ; [*0521.0020.0002.214F] # SYMBOL FOR SAMARITAN SOURCE +2180 ; [*14E5.0020.0002.2180] # ROMAN NUMERAL ONE THOUSAND C D +2181 ; [*14E6.0020.0002.2181] # ROMAN NUMERAL FIVE THOUSAND +2182 ; [*14E7.0020.0002.2182] # ROMAN NUMERAL TEN THOUSAND +2186 ; [*14E8.0020.0002.2186] # ROMAN NUMERAL FIFTY EARLY FORM +2187 ; [*14E9.0020.0002.2187] # ROMAN NUMERAL FIFTY THOUSAND +2188 ; [*14EA.0020.0002.2188] # ROMAN NUMERAL ONE HUNDRED THOUSAND +2190 ; [*0522.0020.0002.2190] # LEFTWARDS ARROW +2191 ; [*0524.0020.0002.2191] # UPWARDS ARROW +2192 ; [*0523.0020.0002.2192] # RIGHTWARDS ARROW +2193 ; [*0525.0020.0002.2193] # DOWNWARDS ARROW +2194 ; [*0526.0020.0002.2194] # LEFT RIGHT ARROW +2195 ; [*0527.0020.0002.2195] # UP DOWN ARROW +2196 ; [*0528.0020.0002.2196] # NORTH WEST ARROW +2197 ; [*0529.0020.0002.2197] # NORTH EAST ARROW +2198 ; [*052A.0020.0002.2198] # SOUTH EAST ARROW +2199 ; [*052B.0020.0002.2199] # SOUTH WEST ARROW +219A ; [*0522.0020.0002.2190][.0000.0054.0002.0338] # LEFTWARDS ARROW WITH STROKE +219B ; [*0523.0020.0002.2192][.0000.0054.0002.0338] # RIGHTWARDS ARROW WITH STROKE +219C ; [*052C.0020.0002.219C] # LEFTWARDS WAVE ARROW +219D ; [*052D.0020.0002.219D] # RIGHTWARDS WAVE ARROW +219E ; [*052E.0020.0002.219E] # LEFTWARDS TWO HEADED ARROW +219F ; [*052F.0020.0002.219F] # UPWARDS TWO HEADED ARROW +21A0 ; [*0530.0020.0002.21A0] # RIGHTWARDS TWO HEADED ARROW +21A1 ; [*0531.0020.0002.21A1] # DOWNWARDS TWO HEADED ARROW +21A2 ; [*0532.0020.0002.21A2] # LEFTWARDS ARROW WITH TAIL +21A3 ; [*0533.0020.0002.21A3] # RIGHTWARDS ARROW WITH TAIL +21A4 ; [*0534.0020.0002.21A4] # LEFTWARDS ARROW FROM BAR +21A5 ; [*0535.0020.0002.21A5] # UPWARDS ARROW FROM BAR +21A6 ; [*0536.0020.0002.21A6] # RIGHTWARDS ARROW FROM BAR +21A7 ; [*0537.0020.0002.21A7] # DOWNWARDS ARROW FROM BAR +21A8 ; [*0538.0020.0002.21A8] # UP DOWN ARROW WITH BASE +21A9 ; [*0539.0020.0002.21A9] # LEFTWARDS ARROW WITH HOOK +21AA ; [*053A.0020.0002.21AA] # RIGHTWARDS ARROW WITH HOOK +21AB ; [*053B.0020.0002.21AB] # LEFTWARDS ARROW WITH LOOP +21AC ; [*053C.0020.0002.21AC] # RIGHTWARDS ARROW WITH LOOP +21AD ; [*053D.0020.0002.21AD] # LEFT RIGHT WAVE ARROW +21AE ; [*0526.0020.0002.2194][.0000.0054.0002.0338] # LEFT RIGHT ARROW WITH STROKE +21AF ; [*053E.0020.0002.21AF] # DOWNWARDS ZIGZAG ARROW +21B0 ; [*053F.0020.0002.21B0] # UPWARDS ARROW WITH TIP LEFTWARDS +21B1 ; [*0540.0020.0002.21B1] # UPWARDS ARROW WITH TIP RIGHTWARDS +21B2 ; [*0541.0020.0002.21B2] # DOWNWARDS ARROW WITH TIP LEFTWARDS +21B3 ; [*0542.0020.0002.21B3] # DOWNWARDS ARROW WITH TIP RIGHTWARDS +21B4 ; [*0543.0020.0002.21B4] # RIGHTWARDS ARROW WITH CORNER DOWNWARDS +21B5 ; [*0544.0020.0002.21B5] # DOWNWARDS ARROW WITH CORNER LEFTWARDS +21B6 ; [*0545.0020.0002.21B6] # ANTICLOCKWISE TOP SEMICIRCLE ARROW +21B7 ; [*0546.0020.0002.21B7] # CLOCKWISE TOP SEMICIRCLE ARROW +21B8 ; [*0547.0020.0002.21B8] # NORTH WEST ARROW TO LONG BAR +21B9 ; [*0548.0020.0002.21B9] # LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR +21BA ; [*0549.0020.0002.21BA] # ANTICLOCKWISE OPEN CIRCLE ARROW +21BB ; [*054A.0020.0002.21BB] # CLOCKWISE OPEN CIRCLE ARROW +21BC ; [*054B.0020.0002.21BC] # LEFTWARDS HARPOON WITH BARB UPWARDS +21BD ; [*054C.0020.0002.21BD] # LEFTWARDS HARPOON WITH BARB DOWNWARDS +21BE ; [*054D.0020.0002.21BE] # UPWARDS HARPOON WITH BARB RIGHTWARDS +21BF ; [*054E.0020.0002.21BF] # UPWARDS HARPOON WITH BARB LEFTWARDS +21C0 ; [*054F.0020.0002.21C0] # RIGHTWARDS HARPOON WITH BARB UPWARDS +21C1 ; [*0550.0020.0002.21C1] # RIGHTWARDS HARPOON WITH BARB DOWNWARDS +21C2 ; [*0551.0020.0002.21C2] # DOWNWARDS HARPOON WITH BARB RIGHTWARDS +21C3 ; [*0552.0020.0002.21C3] # DOWNWARDS HARPOON WITH BARB LEFTWARDS +21C4 ; [*0553.0020.0002.21C4] # RIGHTWARDS ARROW OVER LEFTWARDS ARROW +21C5 ; [*0554.0020.0002.21C5] # UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW +21C6 ; [*0555.0020.0002.21C6] # LEFTWARDS ARROW OVER RIGHTWARDS ARROW +21C7 ; [*0556.0020.0002.21C7] # LEFTWARDS PAIRED ARROWS +21C8 ; [*0557.0020.0002.21C8] # UPWARDS PAIRED ARROWS +21C9 ; [*0558.0020.0002.21C9] # RIGHTWARDS PAIRED ARROWS +21CA ; [*0559.0020.0002.21CA] # DOWNWARDS PAIRED ARROWS +21CB ; [*055A.0020.0002.21CB] # LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON +21CC ; [*055B.0020.0002.21CC] # RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON +21CD ; [*055C.0020.0002.21D0][.0000.0054.0002.0338] # LEFTWARDS DOUBLE ARROW WITH STROKE +21CE ; [*0560.0020.0002.21D4][.0000.0054.0002.0338] # LEFT RIGHT DOUBLE ARROW WITH STROKE +21CF ; [*055E.0020.0002.21D2][.0000.0054.0002.0338] # RIGHTWARDS DOUBLE ARROW WITH STROKE +21D0 ; [*055C.0020.0002.21D0] # LEFTWARDS DOUBLE ARROW +21D1 ; [*055D.0020.0002.21D1] # UPWARDS DOUBLE ARROW +21D2 ; [*055E.0020.0002.21D2] # RIGHTWARDS DOUBLE ARROW +21D3 ; [*055F.0020.0002.21D3] # DOWNWARDS DOUBLE ARROW +21D4 ; [*0560.0020.0002.21D4] # LEFT RIGHT DOUBLE ARROW +21D5 ; [*0561.0020.0002.21D5] # UP DOWN DOUBLE ARROW +21D6 ; [*0562.0020.0002.21D6] # NORTH WEST DOUBLE ARROW +21D7 ; [*0563.0020.0002.21D7] # NORTH EAST DOUBLE ARROW +21D8 ; [*0564.0020.0002.21D8] # SOUTH EAST DOUBLE ARROW +21D9 ; [*0565.0020.0002.21D9] # SOUTH WEST DOUBLE ARROW +21DA ; [*0566.0020.0002.21DA] # LEFTWARDS TRIPLE ARROW +21DB ; [*0567.0020.0002.21DB] # RIGHTWARDS TRIPLE ARROW +21DC ; [*0568.0020.0002.21DC] # LEFTWARDS SQUIGGLE ARROW +21DD ; [*0569.0020.0002.21DD] # RIGHTWARDS SQUIGGLE ARROW +21DE ; [*056A.0020.0002.21DE] # UPWARDS ARROW WITH DOUBLE STROKE +21DF ; [*056B.0020.0002.21DF] # DOWNWARDS ARROW WITH DOUBLE STROKE +21E0 ; [*056C.0020.0002.21E0] # LEFTWARDS DASHED ARROW +21E1 ; [*056D.0020.0002.21E1] # UPWARDS DASHED ARROW +21E2 ; [*056E.0020.0002.21E2] # RIGHTWARDS DASHED ARROW +21E3 ; [*056F.0020.0002.21E3] # DOWNWARDS DASHED ARROW +21E4 ; [*0570.0020.0002.21E4] # LEFTWARDS ARROW TO BAR +21E5 ; [*0571.0020.0002.21E5] # RIGHTWARDS ARROW TO BAR +21E6 ; [*0572.0020.0002.21E6] # LEFTWARDS WHITE ARROW +21E7 ; [*0573.0020.0002.21E7] # UPWARDS WHITE ARROW +21E8 ; [*0574.0020.0002.21E8] # RIGHTWARDS WHITE ARROW +21E9 ; [*0575.0020.0002.21E9] # DOWNWARDS WHITE ARROW +21EA ; [*0576.0020.0002.21EA] # UPWARDS WHITE ARROW FROM BAR +21EB ; [*0577.0020.0002.21EB] # UPWARDS WHITE ARROW ON PEDESTAL +21EC ; [*0578.0020.0002.21EC] # UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR +21ED ; [*0579.0020.0002.21ED] # UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR +21EE ; [*057A.0020.0002.21EE] # UPWARDS WHITE DOUBLE ARROW +21EF ; [*057B.0020.0002.21EF] # UPWARDS WHITE DOUBLE ARROW ON PEDESTAL +21F0 ; [*057C.0020.0002.21F0] # RIGHTWARDS WHITE ARROW FROM WALL +21F1 ; [*057D.0020.0002.21F1] # NORTH WEST ARROW TO CORNER +21F2 ; [*057E.0020.0002.21F2] # SOUTH EAST ARROW TO CORNER +21F3 ; [*057F.0020.0002.21F3] # UP DOWN WHITE ARROW +21F4 ; [*0580.0020.0002.21F4] # RIGHT ARROW WITH SMALL CIRCLE +21F5 ; [*0581.0020.0002.21F5] # DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW +21F6 ; [*0582.0020.0002.21F6] # THREE RIGHTWARDS ARROWS +21F7 ; [*0583.0020.0002.21F7] # LEFTWARDS ARROW WITH VERTICAL STROKE +21F8 ; [*0584.0020.0002.21F8] # RIGHTWARDS ARROW WITH VERTICAL STROKE +21F9 ; [*0585.0020.0002.21F9] # LEFT RIGHT ARROW WITH VERTICAL STROKE +21FA ; [*0586.0020.0002.21FA] # LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE +21FB ; [*0587.0020.0002.21FB] # RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE +21FC ; [*0588.0020.0002.21FC] # LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE +21FD ; [*0589.0020.0002.21FD] # LEFTWARDS OPEN-HEADED ARROW +21FE ; [*058A.0020.0002.21FE] # RIGHTWARDS OPEN-HEADED ARROW +21FF ; [*058B.0020.0002.21FF] # LEFT RIGHT OPEN-HEADED ARROW +2200 ; [*058C.0020.0002.2200] # FOR ALL +2201 ; [*058D.0020.0002.2201] # COMPLEMENT +2202 ; [*058E.0020.0002.2202] # PARTIAL DIFFERENTIAL +2203 ; [*058F.0020.0002.2203] # THERE EXISTS +2204 ; [*058F.0020.0002.2203][.0000.0054.0002.0338] # THERE DOES NOT EXIST +2205 ; [*0590.0020.0002.2205] # EMPTY SET +2206 ; [*0591.0020.0002.2206] # INCREMENT +2207 ; [*0592.0020.0002.2207] # NABLA +2208 ; [*0593.0020.0002.2208] # ELEMENT OF +2209 ; [*0593.0020.0002.2208][.0000.0054.0002.0338] # NOT AN ELEMENT OF +220A ; [*0594.0020.0002.220A] # SMALL ELEMENT OF +220B ; [*0595.0020.0002.220B] # CONTAINS AS MEMBER +220C ; [*0595.0020.0002.220B][.0000.0054.0002.0338] # DOES NOT CONTAIN AS MEMBER +220D ; [*0596.0020.0002.220D] # SMALL CONTAINS AS MEMBER +220E ; [*0598.0020.0002.220E] # END OF PROOF +220F ; [*0599.0020.0002.220F] # N-ARY PRODUCT +2210 ; [*059A.0020.0002.2210] # N-ARY COPRODUCT +2211 ; [*059B.0020.0002.2211] # N-ARY SUMMATION +2212 ; [*05A7.0020.0002.2212] # MINUS SIGN +2213 ; [*05A9.0020.0002.2213] # MINUS-OR-PLUS SIGN +2214 ; [*05AA.0020.0002.2214] # DOT PLUS +2215 ; [*05AB.0020.0002.2215] # DIVISION SLASH +2216 ; [*05AD.0020.0002.2216] # SET MINUS +2217 ; [*05AE.0020.0002.2217] # ASTERISK OPERATOR +2218 ; [*05AF.0020.0002.2218] # RING OPERATOR +2219 ; [*05B0.0020.0002.2219] # BULLET OPERATOR +221A ; [*05B1.0020.0002.221A] # SQUARE ROOT +221B ; [*05B2.0020.0002.221B] # CUBE ROOT +221C ; [*05B4.0020.0002.221C] # FOURTH ROOT +221D ; [*05B6.0020.0002.221D] # PROPORTIONAL TO +221E ; [*05B7.0020.0002.221E] # INFINITY +221F ; [*05B8.0020.0002.221F] # RIGHT ANGLE +2220 ; [*05B9.0020.0002.2220] # ANGLE +2221 ; [*05BA.0020.0002.2221] # MEASURED ANGLE +2222 ; [*05BB.0020.0002.2222] # SPHERICAL ANGLE +2223 ; [*05BC.0020.0002.2223] # DIVIDES +2224 ; [*05BC.0020.0002.2223][.0000.0054.0002.0338] # DOES NOT DIVIDE +2225 ; [*05BD.0020.0002.2225] # PARALLEL TO +2226 ; [*05BD.0020.0002.2225][.0000.0054.0002.0338] # NOT PARALLEL TO +2227 ; [*05BE.0020.0002.2227] # LOGICAL AND +2228 ; [*05BF.0020.0002.2228] # LOGICAL OR +2229 ; [*05C0.0020.0002.2229] # INTERSECTION +222A ; [*05C1.0020.0002.222A] # UNION +222B ; [*05C2.0020.0002.222B] # INTEGRAL +222C ; [*05C2.0020.0004.222C][*05C2.0020.0004.222C] # DOUBLE INTEGRAL +222D ; [*05C2.0020.0004.222D][*05C2.0020.0004.222D][*05C2.0020.001F.222D] # TRIPLE INTEGRAL +222E ; [*05C3.0020.0002.222E] # CONTOUR INTEGRAL +222F ; [*05C3.0020.0004.222F][*05C3.0020.0004.222F] # SURFACE INTEGRAL +2230 ; [*05C3.0020.0004.2230][*05C3.0020.0004.2230][*05C3.0020.001F.2230] # VOLUME INTEGRAL +2231 ; [*05C4.0020.0002.2231] # CLOCKWISE INTEGRAL +2232 ; [*05C5.0020.0002.2232] # CLOCKWISE CONTOUR INTEGRAL +2233 ; [*05C6.0020.0002.2233] # ANTICLOCKWISE CONTOUR INTEGRAL +2234 ; [*05C7.0020.0002.2234] # THEREFORE +2235 ; [*05C8.0020.0002.2235] # BECAUSE +2236 ; [*05C9.0020.0002.2236] # RATIO +2237 ; [*05CA.0020.0002.2237] # PROPORTION +2238 ; [*05CB.0020.0002.2238] # DOT MINUS +2239 ; [*05CC.0020.0002.2239] # EXCESS +223A ; [*05CD.0020.0002.223A] # GEOMETRIC PROPORTION +223B ; [*05CE.0020.0002.223B] # HOMOTHETIC +223C ; [*05CF.0020.0002.223C] # TILDE OPERATOR +223D ; [*05D0.0020.0002.223D] # REVERSED TILDE +223E ; [*05D1.0020.0002.223E] # INVERTED LAZY S +223F ; [*05D2.0020.0002.223F] # SINE WAVE +2240 ; [*05D3.0020.0002.2240] # WREATH PRODUCT +2241 ; [*05CF.0020.0002.223C][.0000.0054.0002.0338] # NOT TILDE +2242 ; [*05D4.0020.0002.2242] # MINUS TILDE +2243 ; [*05D5.0020.0002.2243] # ASYMPTOTICALLY EQUAL TO +2244 ; [*05D5.0020.0002.2243][.0000.0054.0002.0338] # NOT ASYMPTOTICALLY EQUAL TO +2245 ; [*05D6.0020.0002.2245] # APPROXIMATELY EQUAL TO +2246 ; [*05D7.0020.0002.2246] # APPROXIMATELY BUT NOT ACTUALLY EQUAL TO +2247 ; [*05D6.0020.0002.2245][.0000.0054.0002.0338] # NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO +2248 ; [*05D8.0020.0002.2248] # ALMOST EQUAL TO +2249 ; [*05D8.0020.0002.2248][.0000.0054.0002.0338] # NOT ALMOST EQUAL TO +224A ; [*05D9.0020.0002.224A] # ALMOST EQUAL OR EQUAL TO +224B ; [*05DA.0020.0002.224B] # TRIPLE TILDE +224C ; [*05DB.0020.0002.224C] # ALL EQUAL TO +224D ; [*05DC.0020.0002.224D] # EQUIVALENT TO +224E ; [*05DD.0020.0002.224E] # GEOMETRICALLY EQUIVALENT TO +224F ; [*05DE.0020.0002.224F] # DIFFERENCE BETWEEN +2250 ; [*05DF.0020.0002.2250] # APPROACHES THE LIMIT +2251 ; [*05E0.0020.0002.2251] # GEOMETRICALLY EQUAL TO +2252 ; [*05E1.0020.0002.2252] # APPROXIMATELY EQUAL TO OR THE IMAGE OF +2253 ; [*05E2.0020.0002.2253] # IMAGE OF OR APPROXIMATELY EQUAL TO +2254 ; [*05E3.0020.0002.2254] # COLON EQUALS +2255 ; [*05E4.0020.0002.2255] # EQUALS COLON +2256 ; [*05E5.0020.0002.2256] # RING IN EQUAL TO +2257 ; [*05E6.0020.0002.2257] # RING EQUAL TO +2258 ; [*05E7.0020.0002.2258] # CORRESPONDS TO +2259 ; [*05E8.0020.0002.2259] # ESTIMATES +225A ; [*05E9.0020.0002.225A] # EQUIANGULAR TO +225B ; [*05EA.0020.0002.225B] # STAR EQUALS +225C ; [*05EB.0020.0002.225C] # DELTA EQUAL TO +225D ; [*05EC.0020.0002.225D] # EQUAL TO BY DEFINITION +225E ; [*05ED.0020.0002.225E] # MEASURED BY +225F ; [*05EE.0020.0002.225F] # QUESTIONED EQUAL TO +2260 ; [*05A1.0020.0002.003D][.0000.0054.0002.0338] # NOT EQUAL TO +2261 ; [*05EF.0020.0002.2261] # IDENTICAL TO +2262 ; [*05EF.0020.0002.2261][.0000.0054.0002.0338] # NOT IDENTICAL TO +2263 ; [*05F0.0020.0002.2263] # STRICTLY EQUIVALENT TO +2264 ; [*05F1.0020.0002.2264] # LESS-THAN OR EQUAL TO +2265 ; [*05F2.0020.0002.2265] # GREATER-THAN OR EQUAL TO +2266 ; [*05F3.0020.0002.2266] # LESS-THAN OVER EQUAL TO +2267 ; [*05F4.0020.0002.2267] # GREATER-THAN OVER EQUAL TO +2268 ; [*05F5.0020.0002.2268] # LESS-THAN BUT NOT EQUAL TO +2269 ; [*05F6.0020.0002.2269] # GREATER-THAN BUT NOT EQUAL TO +226A ; [*05F7.0020.0002.226A] # MUCH LESS-THAN +226B ; [*05F8.0020.0002.226B] # MUCH GREATER-THAN +226C ; [*05F9.0020.0002.226C] # BETWEEN +226D ; [*05DC.0020.0002.224D][.0000.0054.0002.0338] # NOT EQUIVALENT TO +226E ; [*05A0.0020.0002.003C][.0000.0054.0002.0338] # NOT LESS-THAN +226F ; [*05A2.0020.0002.003E][.0000.0054.0002.0338] # NOT GREATER-THAN +2270 ; [*05F1.0020.0002.2264][.0000.0054.0002.0338] # NEITHER LESS-THAN NOR EQUAL TO +2271 ; [*05F2.0020.0002.2265][.0000.0054.0002.0338] # NEITHER GREATER-THAN NOR EQUAL TO +2272 ; [*05FA.0020.0002.2272] # LESS-THAN OR EQUIVALENT TO +2273 ; [*05FB.0020.0002.2273] # GREATER-THAN OR EQUIVALENT TO +2274 ; [*05FA.0020.0002.2272][.0000.0054.0002.0338] # NEITHER LESS-THAN NOR EQUIVALENT TO +2275 ; [*05FB.0020.0002.2273][.0000.0054.0002.0338] # NEITHER GREATER-THAN NOR EQUIVALENT TO +2276 ; [*05FC.0020.0002.2276] # LESS-THAN OR GREATER-THAN +2277 ; [*05FD.0020.0002.2277] # GREATER-THAN OR LESS-THAN +2278 ; [*05FC.0020.0002.2276][.0000.0054.0002.0338] # NEITHER LESS-THAN NOR GREATER-THAN +2279 ; [*05FD.0020.0002.2277][.0000.0054.0002.0338] # NEITHER GREATER-THAN NOR LESS-THAN +227A ; [*05FE.0020.0002.227A] # PRECEDES +227B ; [*05FF.0020.0002.227B] # SUCCEEDS +227C ; [*0600.0020.0002.227C] # PRECEDES OR EQUAL TO +227D ; [*0601.0020.0002.227D] # SUCCEEDS OR EQUAL TO +227E ; [*0602.0020.0002.227E] # PRECEDES OR EQUIVALENT TO +227F ; [*0603.0020.0002.227F] # SUCCEEDS OR EQUIVALENT TO +2280 ; [*05FE.0020.0002.227A][.0000.0054.0002.0338] # DOES NOT PRECEDE +2281 ; [*05FF.0020.0002.227B][.0000.0054.0002.0338] # DOES NOT SUCCEED +2282 ; [*0604.0020.0002.2282] # SUBSET OF +2283 ; [*0605.0020.0002.2283] # SUPERSET OF +2284 ; [*0604.0020.0002.2282][.0000.0054.0002.0338] # NOT A SUBSET OF +2285 ; [*0605.0020.0002.2283][.0000.0054.0002.0338] # NOT A SUPERSET OF +2286 ; [*0606.0020.0002.2286] # SUBSET OF OR EQUAL TO +2287 ; [*0607.0020.0002.2287] # SUPERSET OF OR EQUAL TO +2288 ; [*0606.0020.0002.2286][.0000.0054.0002.0338] # NEITHER A SUBSET OF NOR EQUAL TO +2289 ; [*0607.0020.0002.2287][.0000.0054.0002.0338] # NEITHER A SUPERSET OF NOR EQUAL TO +228A ; [*0608.0020.0002.228A] # SUBSET OF WITH NOT EQUAL TO +228B ; [*0609.0020.0002.228B] # SUPERSET OF WITH NOT EQUAL TO +228C ; [*060A.0020.0002.228C] # MULTISET +228D ; [*060B.0020.0002.228D] # MULTISET MULTIPLICATION +228E ; [*060C.0020.0002.228E] # MULTISET UNION +228F ; [*060D.0020.0002.228F] # SQUARE IMAGE OF +2290 ; [*060E.0020.0002.2290] # SQUARE ORIGINAL OF +2291 ; [*060F.0020.0002.2291] # SQUARE IMAGE OF OR EQUAL TO +2292 ; [*0610.0020.0002.2292] # SQUARE ORIGINAL OF OR EQUAL TO +2293 ; [*0611.0020.0002.2293] # SQUARE CAP +2294 ; [*0612.0020.0002.2294] # SQUARE CUP +2295 ; [*0613.0020.0002.2295] # CIRCLED PLUS +2296 ; [*0614.0020.0002.2296] # CIRCLED MINUS +2297 ; [*0615.0020.0002.2297] # CIRCLED TIMES +2298 ; [*0616.0020.0002.2298] # CIRCLED DIVISION SLASH +2299 ; [*0617.0020.0002.2299] # CIRCLED DOT OPERATOR +229A ; [*0618.0020.0002.229A] # CIRCLED RING OPERATOR +229B ; [*0619.0020.0002.229B] # CIRCLED ASTERISK OPERATOR +229C ; [*061A.0020.0002.229C] # CIRCLED EQUALS +229D ; [*061B.0020.0002.229D] # CIRCLED DASH +229E ; [*061C.0020.0002.229E] # SQUARED PLUS +229F ; [*061D.0020.0002.229F] # SQUARED MINUS +22A0 ; [*061E.0020.0002.22A0] # SQUARED TIMES +22A1 ; [*061F.0020.0002.22A1] # SQUARED DOT OPERATOR +22A2 ; [*0620.0020.0002.22A2] # RIGHT TACK +22A3 ; [*0621.0020.0002.22A3] # LEFT TACK +22A4 ; [*0622.0020.0002.22A4] # DOWN TACK +22A5 ; [*0623.0020.0002.22A5] # UP TACK +22A6 ; [*0624.0020.0002.22A6] # ASSERTION +22A7 ; [*0625.0020.0002.22A7] # MODELS +22A8 ; [*0626.0020.0002.22A8] # TRUE +22A9 ; [*0627.0020.0002.22A9] # FORCES +22AA ; [*0628.0020.0002.22AA] # TRIPLE VERTICAL BAR RIGHT TURNSTILE +22AB ; [*0629.0020.0002.22AB] # DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE +22AC ; [*0620.0020.0002.22A2][.0000.0054.0002.0338] # DOES NOT PROVE +22AD ; [*0626.0020.0002.22A8][.0000.0054.0002.0338] # NOT TRUE +22AE ; [*0627.0020.0002.22A9][.0000.0054.0002.0338] # DOES NOT FORCE +22AF ; [*0629.0020.0002.22AB][.0000.0054.0002.0338] # NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE +22B0 ; [*062A.0020.0002.22B0] # PRECEDES UNDER RELATION +22B1 ; [*062B.0020.0002.22B1] # SUCCEEDS UNDER RELATION +22B2 ; [*062C.0020.0002.22B2] # NORMAL SUBGROUP OF +22B3 ; [*062D.0020.0002.22B3] # CONTAINS AS NORMAL SUBGROUP +22B4 ; [*062E.0020.0002.22B4] # NORMAL SUBGROUP OF OR EQUAL TO +22B5 ; [*062F.0020.0002.22B5] # CONTAINS AS NORMAL SUBGROUP OR EQUAL TO +22B6 ; [*0630.0020.0002.22B6] # ORIGINAL OF +22B7 ; [*0631.0020.0002.22B7] # IMAGE OF +22B8 ; [*0632.0020.0002.22B8] # MULTIMAP +22B9 ; [*0633.0020.0002.22B9] # HERMITIAN CONJUGATE MATRIX +22BA ; [*0634.0020.0002.22BA] # INTERCALATE +22BB ; [*0635.0020.0002.22BB] # XOR +22BC ; [*0636.0020.0002.22BC] # NAND +22BD ; [*0638.0020.0002.22BD] # NOR +22BE ; [*0639.0020.0002.22BE] # RIGHT ANGLE WITH ARC +22BF ; [*063A.0020.0002.22BF] # RIGHT TRIANGLE +22C0 ; [*063B.0020.0002.22C0] # N-ARY LOGICAL AND +22C1 ; [*063C.0020.0002.22C1] # N-ARY LOGICAL OR +22C2 ; [*063D.0020.0002.22C2] # N-ARY INTERSECTION +22C3 ; [*063E.0020.0002.22C3] # N-ARY UNION +22C4 ; [*063F.0020.0002.22C4] # DIAMOND OPERATOR +22C5 ; [*0640.0020.0002.22C5] # DOT OPERATOR +22C6 ; [*0641.0020.0002.22C6] # STAR OPERATOR +22C7 ; [*0642.0020.0002.22C7] # DIVISION TIMES +22C8 ; [*0643.0020.0002.22C8] # BOWTIE +22C9 ; [*0644.0020.0002.22C9] # LEFT NORMAL FACTOR SEMIDIRECT PRODUCT +22CA ; [*0645.0020.0002.22CA] # RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT +22CB ; [*0646.0020.0002.22CB] # LEFT SEMIDIRECT PRODUCT +22CC ; [*0647.0020.0002.22CC] # RIGHT SEMIDIRECT PRODUCT +22CD ; [*0648.0020.0002.22CD] # REVERSED TILDE EQUALS +22CE ; [*0649.0020.0002.22CE] # CURLY LOGICAL OR +22CF ; [*064A.0020.0002.22CF] # CURLY LOGICAL AND +22D0 ; [*064B.0020.0002.22D0] # DOUBLE SUBSET +22D1 ; [*064C.0020.0002.22D1] # DOUBLE SUPERSET +22D2 ; [*064D.0020.0002.22D2] # DOUBLE INTERSECTION +22D3 ; [*064E.0020.0002.22D3] # DOUBLE UNION +22D4 ; [*064F.0020.0002.22D4] # PITCHFORK +22D5 ; [*0650.0020.0002.22D5] # EQUAL AND PARALLEL TO +22D6 ; [*0651.0020.0002.22D6] # LESS-THAN WITH DOT +22D7 ; [*0652.0020.0002.22D7] # GREATER-THAN WITH DOT +22D8 ; [*0653.0020.0002.22D8] # VERY MUCH LESS-THAN +22D9 ; [*0654.0020.0002.22D9] # VERY MUCH GREATER-THAN +22DA ; [*0655.0020.0002.22DA] # LESS-THAN EQUAL TO OR GREATER-THAN +22DB ; [*0656.0020.0002.22DB] # GREATER-THAN EQUAL TO OR LESS-THAN +22DC ; [*0657.0020.0002.22DC] # EQUAL TO OR LESS-THAN +22DD ; [*0658.0020.0002.22DD] # EQUAL TO OR GREATER-THAN +22DE ; [*0659.0020.0002.22DE] # EQUAL TO OR PRECEDES +22DF ; [*065A.0020.0002.22DF] # EQUAL TO OR SUCCEEDS +22E0 ; [*0600.0020.0002.227C][.0000.0054.0002.0338] # DOES NOT PRECEDE OR EQUAL +22E1 ; [*0601.0020.0002.227D][.0000.0054.0002.0338] # DOES NOT SUCCEED OR EQUAL +22E2 ; [*060F.0020.0002.2291][.0000.0054.0002.0338] # NOT SQUARE IMAGE OF OR EQUAL TO +22E3 ; [*0610.0020.0002.2292][.0000.0054.0002.0338] # NOT SQUARE ORIGINAL OF OR EQUAL TO +22E4 ; [*065B.0020.0002.22E4] # SQUARE IMAGE OF OR NOT EQUAL TO +22E5 ; [*065C.0020.0002.22E5] # SQUARE ORIGINAL OF OR NOT EQUAL TO +22E6 ; [*065D.0020.0002.22E6] # LESS-THAN BUT NOT EQUIVALENT TO +22E7 ; [*065E.0020.0002.22E7] # GREATER-THAN BUT NOT EQUIVALENT TO +22E8 ; [*065F.0020.0002.22E8] # PRECEDES BUT NOT EQUIVALENT TO +22E9 ; [*0660.0020.0002.22E9] # SUCCEEDS BUT NOT EQUIVALENT TO +22EA ; [*062C.0020.0002.22B2][.0000.0054.0002.0338] # NOT NORMAL SUBGROUP OF +22EB ; [*062D.0020.0002.22B3][.0000.0054.0002.0338] # DOES NOT CONTAIN AS NORMAL SUBGROUP +22EC ; [*062E.0020.0002.22B4][.0000.0054.0002.0338] # NOT NORMAL SUBGROUP OF OR EQUAL TO +22ED ; [*062F.0020.0002.22B5][.0000.0054.0002.0338] # DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL +22EE ; [*0661.0020.0002.22EE] # VERTICAL ELLIPSIS +22EF ; [*0662.0020.0002.22EF] # MIDLINE HORIZONTAL ELLIPSIS +22F0 ; [*0663.0020.0002.22F0] # UP RIGHT DIAGONAL ELLIPSIS +22F1 ; [*0664.0020.0002.22F1] # DOWN RIGHT DIAGONAL ELLIPSIS +22F2 ; [*0665.0020.0002.22F2] # ELEMENT OF WITH LONG HORIZONTAL STROKE +22F3 ; [*0666.0020.0002.22F3] # ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE +22F4 ; [*0667.0020.0002.22F4] # SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE +22F5 ; [*0668.0020.0002.22F5] # ELEMENT OF WITH DOT ABOVE +22F6 ; [*0669.0020.0002.22F6] # ELEMENT OF WITH OVERBAR +22F7 ; [*066A.0020.0002.22F7] # SMALL ELEMENT OF WITH OVERBAR +22F8 ; [*066B.0020.0002.22F8] # ELEMENT OF WITH UNDERBAR +22F9 ; [*066C.0020.0002.22F9] # ELEMENT OF WITH TWO HORIZONTAL STROKES +22FA ; [*066D.0020.0002.22FA] # CONTAINS WITH LONG HORIZONTAL STROKE +22FB ; [*066E.0020.0002.22FB] # CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE +22FC ; [*066F.0020.0002.22FC] # SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE +22FD ; [*0670.0020.0002.22FD] # CONTAINS WITH OVERBAR +22FE ; [*0671.0020.0002.22FE] # SMALL CONTAINS WITH OVERBAR +22FF ; [*0672.0020.0002.22FF] # Z NOTATION BAG MEMBERSHIP +2300 ; [*0673.0020.0002.2300] # DIAMETER SIGN +2301 ; [*0674.0020.0002.2301] # ELECTRIC ARROW +2302 ; [*0675.0020.0002.2302] # HOUSE +2303 ; [*0676.0020.0002.2303] # UP ARROWHEAD +2304 ; [*0677.0020.0002.2304] # DOWN ARROWHEAD +2305 ; [*0678.0020.0002.2305] # PROJECTIVE +2306 ; [*0679.0020.0002.2306] # PERSPECTIVE +2307 ; [*067A.0020.0002.2307] # WAVY LINE +2308 ; [*067B.0020.0002.2308] # LEFT CEILING +2309 ; [*067C.0020.0002.2309] # RIGHT CEILING +230A ; [*067D.0020.0002.230A] # LEFT FLOOR +230B ; [*067E.0020.0002.230B] # RIGHT FLOOR +230C ; [*067F.0020.0002.230C] # BOTTOM RIGHT CROP +230D ; [*0680.0020.0002.230D] # BOTTOM LEFT CROP +230E ; [*0681.0020.0002.230E] # TOP RIGHT CROP +230F ; [*0682.0020.0002.230F] # TOP LEFT CROP +2310 ; [*0683.0020.0002.2310] # REVERSED NOT SIGN +2311 ; [*0684.0020.0002.2311] # SQUARE LOZENGE +2312 ; [*0685.0020.0002.2312] # ARC +2313 ; [*0686.0020.0002.2313] # SEGMENT +2314 ; [*0687.0020.0002.2314] # SECTOR +2315 ; [*0688.0020.0002.2315] # TELEPHONE RECORDER +2316 ; [*0689.0020.0002.2316] # POSITION INDICATOR +2317 ; [*068A.0020.0002.2317] # VIEWDATA SQUARE +2318 ; [*068B.0020.0002.2318] # PLACE OF INTEREST SIGN +2319 ; [*068C.0020.0002.2319] # TURNED NOT SIGN +231A ; [*068D.0020.0002.231A] # WATCH +231B ; [*068E.0020.0002.231B] # HOURGLASS +231C ; [*068F.0020.0002.231C] # TOP LEFT CORNER +231D ; [*0690.0020.0002.231D] # TOP RIGHT CORNER +231E ; [*0691.0020.0002.231E] # BOTTOM LEFT CORNER +231F ; [*0692.0020.0002.231F] # BOTTOM RIGHT CORNER +2320 ; [*0693.0020.0002.2320] # TOP HALF INTEGRAL +2321 ; [*0694.0020.0002.2321] # BOTTOM HALF INTEGRAL +2322 ; [*0695.0020.0002.2322] # FROWN +2323 ; [*0696.0020.0002.2323] # SMILE +2324 ; [*0697.0020.0002.2324] # UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS +2325 ; [*0698.0020.0002.2325] # OPTION KEY +2326 ; [*0699.0020.0002.2326] # ERASE TO THE RIGHT +2327 ; [*069A.0020.0002.2327] # X IN A RECTANGLE BOX +2328 ; [*069B.0020.0002.2328] # KEYBOARD +2329 ; [*034F.0020.0002.2329] # LEFT-POINTING ANGLE BRACKET +232A ; [*0350.0020.0002.232A] # RIGHT-POINTING ANGLE BRACKET +232B ; [*069C.0020.0002.232B] # ERASE TO THE LEFT +232C ; [*069D.0020.0002.232C] # BENZENE RING +232D ; [*069E.0020.0002.232D] # CYLINDRICITY +232E ; [*069F.0020.0002.232E] # ALL AROUND-PROFILE +232F ; [*06A0.0020.0002.232F] # SYMMETRY +2330 ; [*06A1.0020.0002.2330] # TOTAL RUNOUT +2331 ; [*06A2.0020.0002.2331] # DIMENSION ORIGIN +2332 ; [*06A3.0020.0002.2332] # CONICAL TAPER +2333 ; [*06A4.0020.0002.2333] # SLOPE +2334 ; [*06A5.0020.0002.2334] # COUNTERBORE +2335 ; [*06A6.0020.0002.2335] # COUNTERSINK +2336 ; [*06A7.0020.0002.2336] # APL FUNCTIONAL SYMBOL I-BEAM +2337 ; [*06A8.0020.0002.2337] # APL FUNCTIONAL SYMBOL SQUISH QUAD +2338 ; [*06A9.0020.0002.2338] # APL FUNCTIONAL SYMBOL QUAD EQUAL +2339 ; [*06AA.0020.0002.2339] # APL FUNCTIONAL SYMBOL QUAD DIVIDE +233A ; [*06AB.0020.0002.233A] # APL FUNCTIONAL SYMBOL QUAD DIAMOND +233B ; [*06AC.0020.0002.233B] # APL FUNCTIONAL SYMBOL QUAD JOT +233C ; [*06AD.0020.0002.233C] # APL FUNCTIONAL SYMBOL QUAD CIRCLE +233D ; [*06AE.0020.0002.233D] # APL FUNCTIONAL SYMBOL CIRCLE STILE +233E ; [*06AF.0020.0002.233E] # APL FUNCTIONAL SYMBOL CIRCLE JOT +233F ; [*06B0.0020.0002.233F] # APL FUNCTIONAL SYMBOL SLASH BAR +2340 ; [*06B1.0020.0002.2340] # APL FUNCTIONAL SYMBOL BACKSLASH BAR +2341 ; [*06B2.0020.0002.2341] # APL FUNCTIONAL SYMBOL QUAD SLASH +2342 ; [*06B3.0020.0002.2342] # APL FUNCTIONAL SYMBOL QUAD BACKSLASH +2343 ; [*06B4.0020.0002.2343] # APL FUNCTIONAL SYMBOL QUAD LESS-THAN +2344 ; [*06B5.0020.0002.2344] # APL FUNCTIONAL SYMBOL QUAD GREATER-THAN +2345 ; [*06B6.0020.0002.2345] # APL FUNCTIONAL SYMBOL LEFTWARDS VANE +2346 ; [*06B7.0020.0002.2346] # APL FUNCTIONAL SYMBOL RIGHTWARDS VANE +2347 ; [*06B8.0020.0002.2347] # APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW +2348 ; [*06B9.0020.0002.2348] # APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW +2349 ; [*06BA.0020.0002.2349] # APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH +234A ; [*06BB.0020.0002.234A] # APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR +234B ; [*06BC.0020.0002.234B] # APL FUNCTIONAL SYMBOL DELTA STILE +234C ; [*06BD.0020.0002.234C] # APL FUNCTIONAL SYMBOL QUAD DOWN CARET +234D ; [*06BE.0020.0002.234D] # APL FUNCTIONAL SYMBOL QUAD DELTA +234E ; [*06BF.0020.0002.234E] # APL FUNCTIONAL SYMBOL DOWN TACK JOT +234F ; [*06C0.0020.0002.234F] # APL FUNCTIONAL SYMBOL UPWARDS VANE +2350 ; [*06C1.0020.0002.2350] # APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW +2351 ; [*06C2.0020.0002.2351] # APL FUNCTIONAL SYMBOL UP TACK OVERBAR +2352 ; [*06C3.0020.0002.2352] # APL FUNCTIONAL SYMBOL DEL STILE +2353 ; [*06C4.0020.0002.2353] # APL FUNCTIONAL SYMBOL QUAD UP CARET +2354 ; [*06C5.0020.0002.2354] # APL FUNCTIONAL SYMBOL QUAD DEL +2355 ; [*06C6.0020.0002.2355] # APL FUNCTIONAL SYMBOL UP TACK JOT +2356 ; [*06C7.0020.0002.2356] # APL FUNCTIONAL SYMBOL DOWNWARDS VANE +2357 ; [*06C8.0020.0002.2357] # APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW +2358 ; [*06C9.0020.0002.2358] # APL FUNCTIONAL SYMBOL QUOTE UNDERBAR +2359 ; [*06CA.0020.0002.2359] # APL FUNCTIONAL SYMBOL DELTA UNDERBAR +235A ; [*06CB.0020.0002.235A] # APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR +235B ; [*06CC.0020.0002.235B] # APL FUNCTIONAL SYMBOL JOT UNDERBAR +235C ; [*06CD.0020.0002.235C] # APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR +235D ; [*06CE.0020.0002.235D] # APL FUNCTIONAL SYMBOL UP SHOE JOT +235E ; [*06CF.0020.0002.235E] # APL FUNCTIONAL SYMBOL QUOTE QUAD +235F ; [*06D0.0020.0002.235F] # APL FUNCTIONAL SYMBOL CIRCLE STAR +2360 ; [*06D1.0020.0002.2360] # APL FUNCTIONAL SYMBOL QUAD COLON +2361 ; [*06D2.0020.0002.2361] # APL FUNCTIONAL SYMBOL UP TACK DIAERESIS +2362 ; [*06D3.0020.0002.2362] # APL FUNCTIONAL SYMBOL DEL DIAERESIS +2363 ; [*06D4.0020.0002.2363] # APL FUNCTIONAL SYMBOL STAR DIAERESIS +2364 ; [*06D5.0020.0002.2364] # APL FUNCTIONAL SYMBOL JOT DIAERESIS +2365 ; [*06D6.0020.0002.2365] # APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS +2366 ; [*06D7.0020.0002.2366] # APL FUNCTIONAL SYMBOL DOWN SHOE STILE +2367 ; [*06D8.0020.0002.2367] # APL FUNCTIONAL SYMBOL LEFT SHOE STILE +2368 ; [*06D9.0020.0002.2368] # APL FUNCTIONAL SYMBOL TILDE DIAERESIS +2369 ; [*06DA.0020.0002.2369] # APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS +236A ; [*06DB.0020.0002.236A] # APL FUNCTIONAL SYMBOL COMMA BAR +236B ; [*06DC.0020.0002.236B] # APL FUNCTIONAL SYMBOL DEL TILDE +236C ; [*06DD.0020.0002.236C] # APL FUNCTIONAL SYMBOL ZILDE +236D ; [*06DE.0020.0002.236D] # APL FUNCTIONAL SYMBOL STILE TILDE +236E ; [*06DF.0020.0002.236E] # APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR +236F ; [*06E0.0020.0002.236F] # APL FUNCTIONAL SYMBOL QUAD NOT EQUAL +2370 ; [*06E1.0020.0002.2370] # APL FUNCTIONAL SYMBOL QUAD QUESTION +2371 ; [*06E2.0020.0002.2371] # APL FUNCTIONAL SYMBOL DOWN CARET TILDE +2372 ; [*06E3.0020.0002.2372] # APL FUNCTIONAL SYMBOL UP CARET TILDE +2373 ; [*06E4.0020.0002.2373] # APL FUNCTIONAL SYMBOL IOTA +2374 ; [*06E5.0020.0002.2374] # APL FUNCTIONAL SYMBOL RHO +2375 ; [*06E6.0020.0002.2375] # APL FUNCTIONAL SYMBOL OMEGA +2376 ; [*06E7.0020.0002.2376] # APL FUNCTIONAL SYMBOL ALPHA UNDERBAR +2377 ; [*06E8.0020.0002.2377] # APL FUNCTIONAL SYMBOL EPSILON UNDERBAR +2378 ; [*06E9.0020.0002.2378] # APL FUNCTIONAL SYMBOL IOTA UNDERBAR +2379 ; [*06EA.0020.0002.2379] # APL FUNCTIONAL SYMBOL OMEGA UNDERBAR +237A ; [*06EB.0020.0002.237A] # APL FUNCTIONAL SYMBOL ALPHA +237B ; [*06EC.0020.0002.237B] # NOT CHECK MARK +237C ; [*06ED.0020.0002.237C] # RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW +237D ; [*06EE.0020.0002.237D] # SHOULDERED OPEN BOX +237E ; [*06EF.0020.0002.237E] # BELL SYMBOL +237F ; [*06F0.0020.0002.237F] # VERTICAL LINE WITH MIDDLE DOT +2380 ; [*06F1.0020.0002.2380] # INSERTION SYMBOL +2381 ; [*06F2.0020.0002.2381] # CONTINUOUS UNDERLINE SYMBOL +2382 ; [*06F3.0020.0002.2382] # DISCONTINUOUS UNDERLINE SYMBOL +2383 ; [*06F4.0020.0002.2383] # EMPHASIS SYMBOL +2384 ; [*06F5.0020.0002.2384] # COMPOSITION SYMBOL +2385 ; [*06F6.0020.0002.2385] # WHITE SQUARE WITH CENTRE VERTICAL LINE +2386 ; [*06F7.0020.0002.2386] # ENTER SYMBOL +2387 ; [*06F8.0020.0002.2387] # ALTERNATIVE KEY SYMBOL +2388 ; [*06F9.0020.0002.2388] # HELM SYMBOL +2389 ; [*06FA.0020.0002.2389] # CIRCLED HORIZONTAL BAR WITH NOTCH +238A ; [*06FB.0020.0002.238A] # CIRCLED TRIANGLE DOWN +238B ; [*06FC.0020.0002.238B] # BROKEN CIRCLE WITH NORTHWEST ARROW +238C ; [*06FD.0020.0002.238C] # UNDO SYMBOL +238D ; [*06FE.0020.0002.238D] # MONOSTABLE SYMBOL +238E ; [*06FF.0020.0002.238E] # HYSTERESIS SYMBOL +238F ; [*0700.0020.0002.238F] # OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL +2390 ; [*0701.0020.0002.2390] # OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL +2391 ; [*0702.0020.0002.2391] # PASSIVE-PULL-DOWN-OUTPUT SYMBOL +2392 ; [*0703.0020.0002.2392] # PASSIVE-PULL-UP-OUTPUT SYMBOL +2393 ; [*0704.0020.0002.2393] # DIRECT CURRENT SYMBOL FORM TWO +2394 ; [*0705.0020.0002.2394] # SOFTWARE-FUNCTION SYMBOL +2395 ; [*0706.0020.0002.2395] # APL FUNCTIONAL SYMBOL QUAD +2396 ; [*0707.0020.0002.2396] # DECIMAL SEPARATOR KEY SYMBOL +2397 ; [*0708.0020.0002.2397] # PREVIOUS PAGE +2398 ; [*0709.0020.0002.2398] # NEXT PAGE +2399 ; [*070A.0020.0002.2399] # PRINT SCREEN SYMBOL +239A ; [*070B.0020.0002.239A] # CLEAR SCREEN SYMBOL +239B ; [*070C.0020.0002.239B] # LEFT PARENTHESIS UPPER HOOK +239C ; [*070D.0020.0002.239C] # LEFT PARENTHESIS EXTENSION +239D ; [*070E.0020.0002.239D] # LEFT PARENTHESIS LOWER HOOK +239E ; [*070F.0020.0002.239E] # RIGHT PARENTHESIS UPPER HOOK +239F ; [*0710.0020.0002.239F] # RIGHT PARENTHESIS EXTENSION +23A0 ; [*0711.0020.0002.23A0] # RIGHT PARENTHESIS LOWER HOOK +23A1 ; [*0712.0020.0002.23A1] # LEFT SQUARE BRACKET UPPER CORNER +23A2 ; [*0713.0020.0002.23A2] # LEFT SQUARE BRACKET EXTENSION +23A3 ; [*0714.0020.0002.23A3] # LEFT SQUARE BRACKET LOWER CORNER +23A4 ; [*0715.0020.0002.23A4] # RIGHT SQUARE BRACKET UPPER CORNER +23A5 ; [*0716.0020.0002.23A5] # RIGHT SQUARE BRACKET EXTENSION +23A6 ; [*0717.0020.0002.23A6] # RIGHT SQUARE BRACKET LOWER CORNER +23A7 ; [*0718.0020.0002.23A7] # LEFT CURLY BRACKET UPPER HOOK +23A8 ; [*0719.0020.0002.23A8] # LEFT CURLY BRACKET MIDDLE PIECE +23A9 ; [*071A.0020.0002.23A9] # LEFT CURLY BRACKET LOWER HOOK +23AA ; [*071B.0020.0002.23AA] # CURLY BRACKET EXTENSION +23AB ; [*071C.0020.0002.23AB] # RIGHT CURLY BRACKET UPPER HOOK +23AC ; [*071D.0020.0002.23AC] # RIGHT CURLY BRACKET MIDDLE PIECE +23AD ; [*071E.0020.0002.23AD] # RIGHT CURLY BRACKET LOWER HOOK +23AE ; [*071F.0020.0002.23AE] # INTEGRAL EXTENSION +23AF ; [*0720.0020.0002.23AF] # HORIZONTAL LINE EXTENSION +23B0 ; [*0721.0020.0002.23B0] # UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION +23B1 ; [*0722.0020.0002.23B1] # UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION +23B2 ; [*0723.0020.0002.23B2] # SUMMATION TOP +23B3 ; [*0724.0020.0002.23B3] # SUMMATION BOTTOM +23B4 ; [*0725.0020.0002.23B4] # TOP SQUARE BRACKET +23B5 ; [*0726.0020.0002.23B5] # BOTTOM SQUARE BRACKET +23B6 ; [*0727.0020.0002.23B6] # BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET +23B7 ; [*0728.0020.0002.23B7] # RADICAL SYMBOL BOTTOM +23B8 ; [*0729.0020.0002.23B8] # LEFT VERTICAL BOX LINE +23B9 ; [*072A.0020.0002.23B9] # RIGHT VERTICAL BOX LINE +23BA ; [*072B.0020.0002.23BA] # HORIZONTAL SCAN LINE-1 +23BB ; [*072C.0020.0002.23BB] # HORIZONTAL SCAN LINE-3 +23BC ; [*072D.0020.0002.23BC] # HORIZONTAL SCAN LINE-7 +23BD ; [*072E.0020.0002.23BD] # HORIZONTAL SCAN LINE-9 +23BE ; [*072F.0020.0002.23BE] # DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT +23BF ; [*0730.0020.0002.23BF] # DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT +23C0 ; [*0731.0020.0002.23C0] # DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE +23C1 ; [*0732.0020.0002.23C1] # DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE +23C2 ; [*0733.0020.0002.23C2] # DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE +23C3 ; [*0734.0020.0002.23C3] # DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE +23C4 ; [*0735.0020.0002.23C4] # DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE +23C5 ; [*0736.0020.0002.23C5] # DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE +23C6 ; [*0737.0020.0002.23C6] # DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE +23C7 ; [*0738.0020.0002.23C7] # DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE +23C8 ; [*0739.0020.0002.23C8] # DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE +23C9 ; [*073A.0020.0002.23C9] # DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL +23CA ; [*073B.0020.0002.23CA] # DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL +23CB ; [*073C.0020.0002.23CB] # DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT +23CC ; [*073D.0020.0002.23CC] # DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT +23CD ; [*073E.0020.0002.23CD] # SQUARE FOOT +23CE ; [*073F.0020.0002.23CE] # RETURN SYMBOL +23CF ; [*0740.0020.0002.23CF] # EJECT SYMBOL +23D0 ; [*0741.0020.0002.23D0] # VERTICAL LINE EXTENSION +23D1 ; [*0742.0020.0002.23D1] # METRICAL BREVE +23D2 ; [*0743.0020.0002.23D2] # METRICAL LONG OVER SHORT +23D3 ; [*0744.0020.0002.23D3] # METRICAL SHORT OVER LONG +23D4 ; [*0745.0020.0002.23D4] # METRICAL LONG OVER TWO SHORTS +23D5 ; [*0746.0020.0002.23D5] # METRICAL TWO SHORTS OVER LONG +23D6 ; [*0747.0020.0002.23D6] # METRICAL TWO SHORTS JOINED +23D7 ; [*0748.0020.0002.23D7] # METRICAL TRISEME +23D8 ; [*0749.0020.0002.23D8] # METRICAL TETRASEME +23D9 ; [*074A.0020.0002.23D9] # METRICAL PENTASEME +23DA ; [*074B.0020.0002.23DA] # EARTH GROUND +23DB ; [*074C.0020.0002.23DB] # FUSE +23DC ; [*074D.0020.0002.23DC] # TOP PARENTHESIS +23DD ; [*074E.0020.0002.23DD] # BOTTOM PARENTHESIS +23DE ; [*074F.0020.0002.23DE] # TOP CURLY BRACKET +23DF ; [*0750.0020.0002.23DF] # BOTTOM CURLY BRACKET +23E0 ; [*0751.0020.0002.23E0] # TOP TORTOISE SHELL BRACKET +23E1 ; [*0752.0020.0002.23E1] # BOTTOM TORTOISE SHELL BRACKET +23E2 ; [*0753.0020.0002.23E2] # WHITE TRAPEZIUM +23E3 ; [*0754.0020.0002.23E3] # BENZENE RING WITH CIRCLE +23E4 ; [*0755.0020.0002.23E4] # STRAIGHTNESS +23E5 ; [*0756.0020.0002.23E5] # FLATNESS +23E6 ; [*0757.0020.0002.23E6] # AC CURRENT +23E7 ; [*0758.0020.0002.23E7] # ELECTRICAL INTERSECTION +23E8 ; [*0759.0020.0002.23E8] # DECIMAL EXPONENT SYMBOL +23E9 ; [*075A.0020.0002.23E9] # BLACK RIGHT-POINTING DOUBLE TRIANGLE +23EA ; [*075B.0020.0002.23EA] # BLACK LEFT-POINTING DOUBLE TRIANGLE +23EB ; [*075C.0020.0002.23EB] # BLACK UP-POINTING DOUBLE TRIANGLE +23EC ; [*075D.0020.0002.23EC] # BLACK DOWN-POINTING DOUBLE TRIANGLE +23ED ; [*075E.0020.0002.23ED] # BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR +23EE ; [*075F.0020.0002.23EE] # BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR +23EF ; [*0760.0020.0002.23EF] # BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR +23F0 ; [*0761.0020.0002.23F0] # ALARM CLOCK +23F1 ; [*0762.0020.0002.23F1] # STOPWATCH +23F2 ; [*0763.0020.0002.23F2] # TIMER CLOCK +23F3 ; [*0764.0020.0002.23F3] # HOURGLASS WITH FLOWING SAND +2400 ; [*0765.0020.0002.2400] # SYMBOL FOR NULL +2401 ; [*0766.0020.0002.2401] # SYMBOL FOR START OF HEADING +2402 ; [*0767.0020.0002.2402] # SYMBOL FOR START OF TEXT +2403 ; [*0768.0020.0002.2403] # SYMBOL FOR END OF TEXT +2404 ; [*0769.0020.0002.2404] # SYMBOL FOR END OF TRANSMISSION +2405 ; [*076A.0020.0002.2405] # SYMBOL FOR ENQUIRY +2406 ; [*076B.0020.0002.2406] # SYMBOL FOR ACKNOWLEDGE +2407 ; [*076C.0020.0002.2407] # SYMBOL FOR BELL +2408 ; [*076D.0020.0002.2408] # SYMBOL FOR BACKSPACE +2409 ; [*076E.0020.0002.2409] # SYMBOL FOR HORIZONTAL TABULATION +240A ; [*076F.0020.0002.240A] # SYMBOL FOR LINE FEED +240B ; [*0770.0020.0002.240B] # SYMBOL FOR VERTICAL TABULATION +240C ; [*0771.0020.0002.240C] # SYMBOL FOR FORM FEED +240D ; [*0772.0020.0002.240D] # SYMBOL FOR CARRIAGE RETURN +240E ; [*0773.0020.0002.240E] # SYMBOL FOR SHIFT OUT +240F ; [*0774.0020.0002.240F] # SYMBOL FOR SHIFT IN +2410 ; [*0775.0020.0002.2410] # SYMBOL FOR DATA LINK ESCAPE +2411 ; [*0776.0020.0002.2411] # SYMBOL FOR DEVICE CONTROL ONE +2412 ; [*0777.0020.0002.2412] # SYMBOL FOR DEVICE CONTROL TWO +2413 ; [*0778.0020.0002.2413] # SYMBOL FOR DEVICE CONTROL THREE +2414 ; [*0779.0020.0002.2414] # SYMBOL FOR DEVICE CONTROL FOUR +2415 ; [*077A.0020.0002.2415] # SYMBOL FOR NEGATIVE ACKNOWLEDGE +2416 ; [*077B.0020.0002.2416] # SYMBOL FOR SYNCHRONOUS IDLE +2417 ; [*077C.0020.0002.2417] # SYMBOL FOR END OF TRANSMISSION BLOCK +2418 ; [*077D.0020.0002.2418] # SYMBOL FOR CANCEL +2419 ; [*077E.0020.0002.2419] # SYMBOL FOR END OF MEDIUM +241A ; [*077F.0020.0002.241A] # SYMBOL FOR SUBSTITUTE +241B ; [*0780.0020.0002.241B] # SYMBOL FOR ESCAPE +241C ; [*0781.0020.0002.241C] # SYMBOL FOR FILE SEPARATOR +241D ; [*0782.0020.0002.241D] # SYMBOL FOR GROUP SEPARATOR +241E ; [*0783.0020.0002.241E] # SYMBOL FOR RECORD SEPARATOR +241F ; [*0784.0020.0002.241F] # SYMBOL FOR UNIT SEPARATOR +2420 ; [*0785.0020.0002.2420] # SYMBOL FOR SPACE +2421 ; [*0786.0020.0002.2421] # SYMBOL FOR DELETE +2422 ; [*0787.0020.0002.2422] # BLANK SYMBOL +2423 ; [*0788.0020.0002.2423] # OPEN BOX +2424 ; [*0789.0020.0002.2424] # SYMBOL FOR NEWLINE +2425 ; [*078A.0020.0002.2425] # SYMBOL FOR DELETE FORM TWO +2426 ; [*078B.0020.0002.2426] # SYMBOL FOR SUBSTITUTE FORM TWO +2440 ; [*078C.0020.0002.2440] # OCR HOOK +2441 ; [*078D.0020.0002.2441] # OCR CHAIR +2442 ; [*078E.0020.0002.2442] # OCR FORK +2443 ; [*078F.0020.0002.2443] # OCR INVERTED FORK +2444 ; [*0790.0020.0002.2444] # OCR BELT BUCKLE +2445 ; [*0791.0020.0002.2445] # OCR BOW TIE +2446 ; [*0792.0020.0002.2446] # OCR BRANCH BANK IDENTIFICATION +2447 ; [*0793.0020.0002.2447] # OCR AMOUNT OF CHECK +2448 ; [*0794.0020.0002.2448] # OCR DASH +2449 ; [*0795.0020.0002.2449] # OCR CUSTOMER ACCOUNT NUMBER +244A ; [*0796.0020.0002.244A] # OCR DOUBLE BACKSLASH +2500 ; [*0797.0020.0002.2500] # BOX DRAWINGS LIGHT HORIZONTAL +2501 ; [*0798.0020.0002.2501] # BOX DRAWINGS HEAVY HORIZONTAL +2502 ; [*0799.0020.0002.2502] # BOX DRAWINGS LIGHT VERTICAL +2503 ; [*079A.0020.0002.2503] # BOX DRAWINGS HEAVY VERTICAL +2504 ; [*079B.0020.0002.2504] # BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL +2505 ; [*079C.0020.0002.2505] # BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL +2506 ; [*079D.0020.0002.2506] # BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL +2507 ; [*079E.0020.0002.2507] # BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL +2508 ; [*079F.0020.0002.2508] # BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL +2509 ; [*07A0.0020.0002.2509] # BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL +250A ; [*07A1.0020.0002.250A] # BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL +250B ; [*07A2.0020.0002.250B] # BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL +250C ; [*07A3.0020.0002.250C] # BOX DRAWINGS LIGHT DOWN AND RIGHT +250D ; [*07A4.0020.0002.250D] # BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY +250E ; [*07A5.0020.0002.250E] # BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT +250F ; [*07A6.0020.0002.250F] # BOX DRAWINGS HEAVY DOWN AND RIGHT +2510 ; [*07A7.0020.0002.2510] # BOX DRAWINGS LIGHT DOWN AND LEFT +2511 ; [*07A8.0020.0002.2511] # BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY +2512 ; [*07A9.0020.0002.2512] # BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT +2513 ; [*07AA.0020.0002.2513] # BOX DRAWINGS HEAVY DOWN AND LEFT +2514 ; [*07AB.0020.0002.2514] # BOX DRAWINGS LIGHT UP AND RIGHT +2515 ; [*07AC.0020.0002.2515] # BOX DRAWINGS UP LIGHT AND RIGHT HEAVY +2516 ; [*07AD.0020.0002.2516] # BOX DRAWINGS UP HEAVY AND RIGHT LIGHT +2517 ; [*07AE.0020.0002.2517] # BOX DRAWINGS HEAVY UP AND RIGHT +2518 ; [*07AF.0020.0002.2518] # BOX DRAWINGS LIGHT UP AND LEFT +2519 ; [*07B0.0020.0002.2519] # BOX DRAWINGS UP LIGHT AND LEFT HEAVY +251A ; [*07B1.0020.0002.251A] # BOX DRAWINGS UP HEAVY AND LEFT LIGHT +251B ; [*07B2.0020.0002.251B] # BOX DRAWINGS HEAVY UP AND LEFT +251C ; [*07B3.0020.0002.251C] # BOX DRAWINGS LIGHT VERTICAL AND RIGHT +251D ; [*07B4.0020.0002.251D] # BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY +251E ; [*07B5.0020.0002.251E] # BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT +251F ; [*07B6.0020.0002.251F] # BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT +2520 ; [*07B7.0020.0002.2520] # BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT +2521 ; [*07B8.0020.0002.2521] # BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY +2522 ; [*07B9.0020.0002.2522] # BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY +2523 ; [*07BA.0020.0002.2523] # BOX DRAWINGS HEAVY VERTICAL AND RIGHT +2524 ; [*07BB.0020.0002.2524] # BOX DRAWINGS LIGHT VERTICAL AND LEFT +2525 ; [*07BC.0020.0002.2525] # BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY +2526 ; [*07BD.0020.0002.2526] # BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT +2527 ; [*07BE.0020.0002.2527] # BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT +2528 ; [*07BF.0020.0002.2528] # BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT +2529 ; [*07C0.0020.0002.2529] # BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY +252A ; [*07C1.0020.0002.252A] # BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY +252B ; [*07C2.0020.0002.252B] # BOX DRAWINGS HEAVY VERTICAL AND LEFT +252C ; [*07C3.0020.0002.252C] # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +252D ; [*07C4.0020.0002.252D] # BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT +252E ; [*07C5.0020.0002.252E] # BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT +252F ; [*07C6.0020.0002.252F] # BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY +2530 ; [*07C7.0020.0002.2530] # BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT +2531 ; [*07C8.0020.0002.2531] # BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY +2532 ; [*07C9.0020.0002.2532] # BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY +2533 ; [*07CA.0020.0002.2533] # BOX DRAWINGS HEAVY DOWN AND HORIZONTAL +2534 ; [*07CB.0020.0002.2534] # BOX DRAWINGS LIGHT UP AND HORIZONTAL +2535 ; [*07CC.0020.0002.2535] # BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT +2536 ; [*07CD.0020.0002.2536] # BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT +2537 ; [*07CE.0020.0002.2537] # BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY +2538 ; [*07CF.0020.0002.2538] # BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT +2539 ; [*07D0.0020.0002.2539] # BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY +253A ; [*07D1.0020.0002.253A] # BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY +253B ; [*07D2.0020.0002.253B] # BOX DRAWINGS HEAVY UP AND HORIZONTAL +253C ; [*07D3.0020.0002.253C] # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +253D ; [*07D4.0020.0002.253D] # BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT +253E ; [*07D5.0020.0002.253E] # BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT +253F ; [*07D6.0020.0002.253F] # BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY +2540 ; [*07D7.0020.0002.2540] # BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT +2541 ; [*07D8.0020.0002.2541] # BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT +2542 ; [*07D9.0020.0002.2542] # BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT +2543 ; [*07DA.0020.0002.2543] # BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT +2544 ; [*07DB.0020.0002.2544] # BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT +2545 ; [*07DC.0020.0002.2545] # BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT +2546 ; [*07DD.0020.0002.2546] # BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT +2547 ; [*07DE.0020.0002.2547] # BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY +2548 ; [*07DF.0020.0002.2548] # BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY +2549 ; [*07E0.0020.0002.2549] # BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY +254A ; [*07E1.0020.0002.254A] # BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY +254B ; [*07E2.0020.0002.254B] # BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL +254C ; [*07E3.0020.0002.254C] # BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL +254D ; [*07E4.0020.0002.254D] # BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL +254E ; [*07E5.0020.0002.254E] # BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL +254F ; [*07E6.0020.0002.254F] # BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL +2550 ; [*07E7.0020.0002.2550] # BOX DRAWINGS DOUBLE HORIZONTAL +2551 ; [*07E8.0020.0002.2551] # BOX DRAWINGS DOUBLE VERTICAL +2552 ; [*07E9.0020.0002.2552] # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE +2553 ; [*07EA.0020.0002.2553] # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE +2554 ; [*07EB.0020.0002.2554] # BOX DRAWINGS DOUBLE DOWN AND RIGHT +2555 ; [*07EC.0020.0002.2555] # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE +2556 ; [*07ED.0020.0002.2556] # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE +2557 ; [*07EE.0020.0002.2557] # BOX DRAWINGS DOUBLE DOWN AND LEFT +2558 ; [*07EF.0020.0002.2558] # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE +2559 ; [*07F0.0020.0002.2559] # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE +255A ; [*07F1.0020.0002.255A] # BOX DRAWINGS DOUBLE UP AND RIGHT +255B ; [*07F2.0020.0002.255B] # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE +255C ; [*07F3.0020.0002.255C] # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE +255D ; [*07F4.0020.0002.255D] # BOX DRAWINGS DOUBLE UP AND LEFT +255E ; [*07F5.0020.0002.255E] # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE +255F ; [*07F6.0020.0002.255F] # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE +2560 ; [*07F7.0020.0002.2560] # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +2561 ; [*07F8.0020.0002.2561] # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE +2562 ; [*07F9.0020.0002.2562] # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE +2563 ; [*07FA.0020.0002.2563] # BOX DRAWINGS DOUBLE VERTICAL AND LEFT +2564 ; [*07FB.0020.0002.2564] # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE +2565 ; [*07FC.0020.0002.2565] # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE +2566 ; [*07FD.0020.0002.2566] # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +2567 ; [*07FE.0020.0002.2567] # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE +2568 ; [*07FF.0020.0002.2568] # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE +2569 ; [*0800.0020.0002.2569] # BOX DRAWINGS DOUBLE UP AND HORIZONTAL +256A ; [*0801.0020.0002.256A] # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE +256B ; [*0802.0020.0002.256B] # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE +256C ; [*0803.0020.0002.256C] # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +256D ; [*0804.0020.0002.256D] # BOX DRAWINGS LIGHT ARC DOWN AND RIGHT +256E ; [*0805.0020.0002.256E] # BOX DRAWINGS LIGHT ARC DOWN AND LEFT +256F ; [*0806.0020.0002.256F] # BOX DRAWINGS LIGHT ARC UP AND LEFT +2570 ; [*0807.0020.0002.2570] # BOX DRAWINGS LIGHT ARC UP AND RIGHT +2571 ; [*0808.0020.0002.2571] # BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT +2572 ; [*0809.0020.0002.2572] # BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT +2573 ; [*080A.0020.0002.2573] # BOX DRAWINGS LIGHT DIAGONAL CROSS +2574 ; [*080B.0020.0002.2574] # BOX DRAWINGS LIGHT LEFT +2575 ; [*080C.0020.0002.2575] # BOX DRAWINGS LIGHT UP +2576 ; [*080D.0020.0002.2576] # BOX DRAWINGS LIGHT RIGHT +2577 ; [*080E.0020.0002.2577] # BOX DRAWINGS LIGHT DOWN +2578 ; [*080F.0020.0002.2578] # BOX DRAWINGS HEAVY LEFT +2579 ; [*0810.0020.0002.2579] # BOX DRAWINGS HEAVY UP +257A ; [*0811.0020.0002.257A] # BOX DRAWINGS HEAVY RIGHT +257B ; [*0812.0020.0002.257B] # BOX DRAWINGS HEAVY DOWN +257C ; [*0813.0020.0002.257C] # BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT +257D ; [*0814.0020.0002.257D] # BOX DRAWINGS LIGHT UP AND HEAVY DOWN +257E ; [*0815.0020.0002.257E] # BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT +257F ; [*0816.0020.0002.257F] # BOX DRAWINGS HEAVY UP AND LIGHT DOWN +2580 ; [*0817.0020.0002.2580] # UPPER HALF BLOCK +2581 ; [*0818.0020.0002.2581] # LOWER ONE EIGHTH BLOCK +2582 ; [*0819.0020.0002.2582] # LOWER ONE QUARTER BLOCK +2583 ; [*081A.0020.0002.2583] # LOWER THREE EIGHTHS BLOCK +2584 ; [*081B.0020.0002.2584] # LOWER HALF BLOCK +2585 ; [*081C.0020.0002.2585] # LOWER FIVE EIGHTHS BLOCK +2586 ; [*081D.0020.0002.2586] # LOWER THREE QUARTERS BLOCK +2587 ; [*081E.0020.0002.2587] # LOWER SEVEN EIGHTHS BLOCK +2588 ; [*081F.0020.0002.2588] # FULL BLOCK +2589 ; [*0820.0020.0002.2589] # LEFT SEVEN EIGHTHS BLOCK +258A ; [*0821.0020.0002.258A] # LEFT THREE QUARTERS BLOCK +258B ; [*0822.0020.0002.258B] # LEFT FIVE EIGHTHS BLOCK +258C ; [*0823.0020.0002.258C] # LEFT HALF BLOCK +258D ; [*0824.0020.0002.258D] # LEFT THREE EIGHTHS BLOCK +258E ; [*0825.0020.0002.258E] # LEFT ONE QUARTER BLOCK +258F ; [*0826.0020.0002.258F] # LEFT ONE EIGHTH BLOCK +2590 ; [*0827.0020.0002.2590] # RIGHT HALF BLOCK +2591 ; [*0828.0020.0002.2591] # LIGHT SHADE +2592 ; [*0829.0020.0002.2592] # MEDIUM SHADE +2593 ; [*082A.0020.0002.2593] # DARK SHADE +2594 ; [*082B.0020.0002.2594] # UPPER ONE EIGHTH BLOCK +2595 ; [*082C.0020.0002.2595] # RIGHT ONE EIGHTH BLOCK +2596 ; [*082D.0020.0002.2596] # QUADRANT LOWER LEFT +2597 ; [*082E.0020.0002.2597] # QUADRANT LOWER RIGHT +2598 ; [*082F.0020.0002.2598] # QUADRANT UPPER LEFT +2599 ; [*0830.0020.0002.2599] # QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT +259A ; [*0831.0020.0002.259A] # QUADRANT UPPER LEFT AND LOWER RIGHT +259B ; [*0832.0020.0002.259B] # QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT +259C ; [*0833.0020.0002.259C] # QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT +259D ; [*0834.0020.0002.259D] # QUADRANT UPPER RIGHT +259E ; [*0835.0020.0002.259E] # QUADRANT UPPER RIGHT AND LOWER LEFT +259F ; [*0836.0020.0002.259F] # QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT +25A0 ; [*0837.0020.0002.25A0] # BLACK SQUARE +25A1 ; [*0838.0020.0002.25A1] # WHITE SQUARE +25A2 ; [*0839.0020.0002.25A2] # WHITE SQUARE WITH ROUNDED CORNERS +25A3 ; [*083A.0020.0002.25A3] # WHITE SQUARE CONTAINING BLACK SMALL SQUARE +25A4 ; [*083B.0020.0002.25A4] # SQUARE WITH HORIZONTAL FILL +25A5 ; [*083C.0020.0002.25A5] # SQUARE WITH VERTICAL FILL +25A6 ; [*083D.0020.0002.25A6] # SQUARE WITH ORTHOGONAL CROSSHATCH FILL +25A7 ; [*083E.0020.0002.25A7] # SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL +25A8 ; [*083F.0020.0002.25A8] # SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL +25A9 ; [*0840.0020.0002.25A9] # SQUARE WITH DIAGONAL CROSSHATCH FILL +25AA ; [*0841.0020.0002.25AA] # BLACK SMALL SQUARE +25AB ; [*0842.0020.0002.25AB] # WHITE SMALL SQUARE +25AC ; [*0843.0020.0002.25AC] # BLACK RECTANGLE +25AD ; [*0844.0020.0002.25AD] # WHITE RECTANGLE +25AE ; [*0845.0020.0002.25AE] # BLACK VERTICAL RECTANGLE +25AF ; [*0846.0020.0002.25AF] # WHITE VERTICAL RECTANGLE +25B0 ; [*0847.0020.0002.25B0] # BLACK PARALLELOGRAM +25B1 ; [*0848.0020.0002.25B1] # WHITE PARALLELOGRAM +25B2 ; [*0849.0020.0002.25B2] # BLACK UP-POINTING TRIANGLE +25B3 ; [*084A.0020.0002.25B3] # WHITE UP-POINTING TRIANGLE +25B4 ; [*084B.0020.0002.25B4] # BLACK UP-POINTING SMALL TRIANGLE +25B5 ; [*084C.0020.0002.25B5] # WHITE UP-POINTING SMALL TRIANGLE +25B6 ; [*084D.0020.0002.25B6] # BLACK RIGHT-POINTING TRIANGLE +25B7 ; [*084E.0020.0002.25B7] # WHITE RIGHT-POINTING TRIANGLE +25B8 ; [*084F.0020.0002.25B8] # BLACK RIGHT-POINTING SMALL TRIANGLE +25B9 ; [*0850.0020.0002.25B9] # WHITE RIGHT-POINTING SMALL TRIANGLE +25BA ; [*0851.0020.0002.25BA] # BLACK RIGHT-POINTING POINTER +25BB ; [*0852.0020.0002.25BB] # WHITE RIGHT-POINTING POINTER +25BC ; [*0853.0020.0002.25BC] # BLACK DOWN-POINTING TRIANGLE +25BD ; [*0854.0020.0002.25BD] # WHITE DOWN-POINTING TRIANGLE +25BE ; [*0855.0020.0002.25BE] # BLACK DOWN-POINTING SMALL TRIANGLE +25BF ; [*0856.0020.0002.25BF] # WHITE DOWN-POINTING SMALL TRIANGLE +25C0 ; [*0857.0020.0002.25C0] # BLACK LEFT-POINTING TRIANGLE +25C1 ; [*0858.0020.0002.25C1] # WHITE LEFT-POINTING TRIANGLE +25C2 ; [*0859.0020.0002.25C2] # BLACK LEFT-POINTING SMALL TRIANGLE +25C3 ; [*085A.0020.0002.25C3] # WHITE LEFT-POINTING SMALL TRIANGLE +25C4 ; [*085B.0020.0002.25C4] # BLACK LEFT-POINTING POINTER +25C5 ; [*085C.0020.0002.25C5] # WHITE LEFT-POINTING POINTER +25C6 ; [*085D.0020.0002.25C6] # BLACK DIAMOND +25C7 ; [*085E.0020.0002.25C7] # WHITE DIAMOND +25C8 ; [*085F.0020.0002.25C8] # WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND +25C9 ; [*0860.0020.0002.25C9] # FISHEYE +25CA ; [*0861.0020.0002.25CA] # LOZENGE +25CB ; [*0862.0020.0002.25CB] # WHITE CIRCLE +25CC ; [*0863.0020.0002.25CC] # DOTTED CIRCLE +25CD ; [*0864.0020.0002.25CD] # CIRCLE WITH VERTICAL FILL +25CE ; [*0865.0020.0002.25CE] # BULLSEYE +25CF ; [*0866.0020.0002.25CF] # BLACK CIRCLE +25D0 ; [*0867.0020.0002.25D0] # CIRCLE WITH LEFT HALF BLACK +25D1 ; [*0868.0020.0002.25D1] # CIRCLE WITH RIGHT HALF BLACK +25D2 ; [*0869.0020.0002.25D2] # CIRCLE WITH LOWER HALF BLACK +25D3 ; [*086A.0020.0002.25D3] # CIRCLE WITH UPPER HALF BLACK +25D4 ; [*086B.0020.0002.25D4] # CIRCLE WITH UPPER RIGHT QUADRANT BLACK +25D5 ; [*086C.0020.0002.25D5] # CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK +25D6 ; [*086D.0020.0002.25D6] # LEFT HALF BLACK CIRCLE +25D7 ; [*086E.0020.0002.25D7] # RIGHT HALF BLACK CIRCLE +25D8 ; [*086F.0020.0002.25D8] # INVERSE BULLET +25D9 ; [*0870.0020.0002.25D9] # INVERSE WHITE CIRCLE +25DA ; [*0871.0020.0002.25DA] # UPPER HALF INVERSE WHITE CIRCLE +25DB ; [*0872.0020.0002.25DB] # LOWER HALF INVERSE WHITE CIRCLE +25DC ; [*0873.0020.0002.25DC] # UPPER LEFT QUADRANT CIRCULAR ARC +25DD ; [*0874.0020.0002.25DD] # UPPER RIGHT QUADRANT CIRCULAR ARC +25DE ; [*0875.0020.0002.25DE] # LOWER RIGHT QUADRANT CIRCULAR ARC +25DF ; [*0876.0020.0002.25DF] # LOWER LEFT QUADRANT CIRCULAR ARC +25E0 ; [*0877.0020.0002.25E0] # UPPER HALF CIRCLE +25E1 ; [*0878.0020.0002.25E1] # LOWER HALF CIRCLE +25E2 ; [*0879.0020.0002.25E2] # BLACK LOWER RIGHT TRIANGLE +25E3 ; [*087A.0020.0002.25E3] # BLACK LOWER LEFT TRIANGLE +25E4 ; [*087B.0020.0002.25E4] # BLACK UPPER LEFT TRIANGLE +25E5 ; [*087C.0020.0002.25E5] # BLACK UPPER RIGHT TRIANGLE +25E6 ; [*087D.0020.0002.25E6] # WHITE BULLET +25E7 ; [*087E.0020.0002.25E7] # SQUARE WITH LEFT HALF BLACK +25E8 ; [*087F.0020.0002.25E8] # SQUARE WITH RIGHT HALF BLACK +25E9 ; [*0880.0020.0002.25E9] # SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK +25EA ; [*0881.0020.0002.25EA] # SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK +25EB ; [*0882.0020.0002.25EB] # WHITE SQUARE WITH VERTICAL BISECTING LINE +25EC ; [*0883.0020.0002.25EC] # WHITE UP-POINTING TRIANGLE WITH DOT +25ED ; [*0884.0020.0002.25ED] # UP-POINTING TRIANGLE WITH LEFT HALF BLACK +25EE ; [*0885.0020.0002.25EE] # UP-POINTING TRIANGLE WITH RIGHT HALF BLACK +25EF ; [*0886.0020.0002.25EF] # LARGE CIRCLE +25F0 ; [*0887.0020.0002.25F0] # WHITE SQUARE WITH UPPER LEFT QUADRANT +25F1 ; [*0888.0020.0002.25F1] # WHITE SQUARE WITH LOWER LEFT QUADRANT +25F2 ; [*0889.0020.0002.25F2] # WHITE SQUARE WITH LOWER RIGHT QUADRANT +25F3 ; [*088A.0020.0002.25F3] # WHITE SQUARE WITH UPPER RIGHT QUADRANT +25F4 ; [*088B.0020.0002.25F4] # WHITE CIRCLE WITH UPPER LEFT QUADRANT +25F5 ; [*088C.0020.0002.25F5] # WHITE CIRCLE WITH LOWER LEFT QUADRANT +25F6 ; [*088D.0020.0002.25F6] # WHITE CIRCLE WITH LOWER RIGHT QUADRANT +25F7 ; [*088E.0020.0002.25F7] # WHITE CIRCLE WITH UPPER RIGHT QUADRANT +25F8 ; [*088F.0020.0002.25F8] # UPPER LEFT TRIANGLE +25F9 ; [*0890.0020.0002.25F9] # UPPER RIGHT TRIANGLE +25FA ; [*0891.0020.0002.25FA] # LOWER LEFT TRIANGLE +25FB ; [*0892.0020.0002.25FB] # WHITE MEDIUM SQUARE +25FC ; [*0893.0020.0002.25FC] # BLACK MEDIUM SQUARE +25FD ; [*0894.0020.0002.25FD] # WHITE MEDIUM SMALL SQUARE +25FE ; [*0895.0020.0002.25FE] # BLACK MEDIUM SMALL SQUARE +25FF ; [*0896.0020.0002.25FF] # LOWER RIGHT TRIANGLE +2600 ; [*0897.0020.0002.2600] # BLACK SUN WITH RAYS +2601 ; [*0898.0020.0002.2601] # CLOUD +2602 ; [*0899.0020.0002.2602] # UMBRELLA +2603 ; [*089A.0020.0002.2603] # SNOWMAN +2604 ; [*089B.0020.0002.2604] # COMET +2605 ; [*089C.0020.0002.2605] # BLACK STAR +2606 ; [*089D.0020.0002.2606] # WHITE STAR +2607 ; [*089E.0020.0002.2607] # LIGHTNING +2608 ; [*089F.0020.0002.2608] # THUNDERSTORM +2609 ; [*08A0.0020.0002.2609] # SUN +260A ; [*08A1.0020.0002.260A] # ASCENDING NODE +260B ; [*08A2.0020.0002.260B] # DESCENDING NODE +260C ; [*08A3.0020.0002.260C] # CONJUNCTION +260D ; [*08A4.0020.0002.260D] # OPPOSITION +260E ; [*08A5.0020.0002.260E] # BLACK TELEPHONE +260F ; [*08A6.0020.0002.260F] # WHITE TELEPHONE +2610 ; [*08A7.0020.0002.2610] # BALLOT BOX +2611 ; [*08A8.0020.0002.2611] # BALLOT BOX WITH CHECK +2612 ; [*08A9.0020.0002.2612] # BALLOT BOX WITH X +2613 ; [*08AA.0020.0002.2613] # SALTIRE +2614 ; [*08AB.0020.0002.2614] # UMBRELLA WITH RAIN DROPS +2615 ; [*08AC.0020.0002.2615] # HOT BEVERAGE +2616 ; [*08AD.0020.0002.2616] # WHITE SHOGI PIECE +2617 ; [*08AE.0020.0002.2617] # BLACK SHOGI PIECE +2618 ; [*08AF.0020.0002.2618] # SHAMROCK +2619 ; [*08B0.0020.0002.2619] # REVERSED ROTATED FLORAL HEART BULLET +261A ; [*08B1.0020.0002.261A] # BLACK LEFT POINTING INDEX +261B ; [*08B2.0020.0002.261B] # BLACK RIGHT POINTING INDEX +261C ; [*08B3.0020.0002.261C] # WHITE LEFT POINTING INDEX +261D ; [*08B4.0020.0002.261D] # WHITE UP POINTING INDEX +261E ; [*08B5.0020.0002.261E] # WHITE RIGHT POINTING INDEX +261F ; [*08B6.0020.0002.261F] # WHITE DOWN POINTING INDEX +2620 ; [*08B7.0020.0002.2620] # SKULL AND CROSSBONES +2621 ; [*08B8.0020.0002.2621] # CAUTION SIGN +2622 ; [*08B9.0020.0002.2622] # RADIOACTIVE SIGN +2623 ; [*08BA.0020.0002.2623] # BIOHAZARD SIGN +2624 ; [*08BB.0020.0002.2624] # CADUCEUS +2625 ; [*08BC.0020.0002.2625] # ANKH +2626 ; [*08BD.0020.0002.2626] # ORTHODOX CROSS +2627 ; [*08BE.0020.0002.2627] # CHI RHO +2628 ; [*08BF.0020.0002.2628] # CROSS OF LORRAINE +2629 ; [*08C0.0020.0002.2629] # CROSS OF JERUSALEM +262A ; [*08C1.0020.0002.262A] # STAR AND CRESCENT +262B ; [*08C2.0020.0002.262B] # FARSI SYMBOL +262C ; [*08C3.0020.0002.262C] # ADI SHAKTI +262D ; [*08C4.0020.0002.262D] # HAMMER AND SICKLE +262E ; [*08C5.0020.0002.262E] # PEACE SYMBOL +262F ; [*08C6.0020.0002.262F] # YIN YANG +2630 ; [*0D8F.0020.0002.2630] # TRIGRAM FOR HEAVEN +2631 ; [*0D90.0020.0002.2631] # TRIGRAM FOR LAKE +2632 ; [*0D91.0020.0002.2632] # TRIGRAM FOR FIRE +2633 ; [*0D92.0020.0002.2633] # TRIGRAM FOR THUNDER +2634 ; [*0D93.0020.0002.2634] # TRIGRAM FOR WIND +2635 ; [*0D94.0020.0002.2635] # TRIGRAM FOR WATER +2636 ; [*0D95.0020.0002.2636] # TRIGRAM FOR MOUNTAIN +2637 ; [*0D96.0020.0002.2637] # TRIGRAM FOR EARTH +2638 ; [*08C7.0020.0002.2638] # WHEEL OF DHARMA +2639 ; [*08C8.0020.0002.2639] # WHITE FROWNING FACE +263A ; [*08C9.0020.0002.263A] # WHITE SMILING FACE +263B ; [*08CA.0020.0002.263B] # BLACK SMILING FACE +263C ; [*08CB.0020.0002.263C] # WHITE SUN WITH RAYS +263D ; [*08CC.0020.0002.263D] # FIRST QUARTER MOON +263E ; [*08CD.0020.0002.263E] # LAST QUARTER MOON +263F ; [*08CE.0020.0002.263F] # MERCURY +2640 ; [*08CF.0020.0002.2640] # FEMALE SIGN +2641 ; [*08D0.0020.0002.2641] # EARTH +2642 ; [*08D1.0020.0002.2642] # MALE SIGN +2643 ; [*08D2.0020.0002.2643] # JUPITER +2644 ; [*08D3.0020.0002.2644] # SATURN +2645 ; [*08D4.0020.0002.2645] # URANUS +2646 ; [*08D5.0020.0002.2646] # NEPTUNE +2647 ; [*08D6.0020.0002.2647] # PLUTO +2648 ; [*08D7.0020.0002.2648] # ARIES +2649 ; [*08D8.0020.0002.2649] # TAURUS +264A ; [*08D9.0020.0002.264A] # GEMINI +264B ; [*08DA.0020.0002.264B] # CANCER +264C ; [*08DB.0020.0002.264C] # LEO +264D ; [*08DC.0020.0002.264D] # VIRGO +264E ; [*08DD.0020.0002.264E] # LIBRA +264F ; [*08DE.0020.0002.264F] # SCORPIUS +2650 ; [*08DF.0020.0002.2650] # SAGITTARIUS +2651 ; [*08E0.0020.0002.2651] # CAPRICORN +2652 ; [*08E1.0020.0002.2652] # AQUARIUS +2653 ; [*08E2.0020.0002.2653] # PISCES +2654 ; [*08E3.0020.0002.2654] # WHITE CHESS KING +2655 ; [*08E4.0020.0002.2655] # WHITE CHESS QUEEN +2656 ; [*08E5.0020.0002.2656] # WHITE CHESS ROOK +2657 ; [*08E6.0020.0002.2657] # WHITE CHESS BISHOP +2658 ; [*08E7.0020.0002.2658] # WHITE CHESS KNIGHT +2659 ; [*08E8.0020.0002.2659] # WHITE CHESS PAWN +265A ; [*08E9.0020.0002.265A] # BLACK CHESS KING +265B ; [*08EA.0020.0002.265B] # BLACK CHESS QUEEN +265C ; [*08EB.0020.0002.265C] # BLACK CHESS ROOK +265D ; [*08EC.0020.0002.265D] # BLACK CHESS BISHOP +265E ; [*08ED.0020.0002.265E] # BLACK CHESS KNIGHT +265F ; [*08EE.0020.0002.265F] # BLACK CHESS PAWN +2660 ; [*08EF.0020.0002.2660] # BLACK SPADE SUIT +2661 ; [*08F0.0020.0002.2661] # WHITE HEART SUIT +2662 ; [*08F1.0020.0002.2662] # WHITE DIAMOND SUIT +2663 ; [*08F2.0020.0002.2663] # BLACK CLUB SUIT +2664 ; [*08F3.0020.0002.2664] # WHITE SPADE SUIT +2665 ; [*08F4.0020.0002.2665] # BLACK HEART SUIT +2666 ; [*08F5.0020.0002.2666] # BLACK DIAMOND SUIT +2667 ; [*08F6.0020.0002.2667] # WHITE CLUB SUIT +2668 ; [*08F7.0020.0002.2668] # HOT SPRINGS +2669 ; [*08F8.0020.0002.2669] # QUARTER NOTE +266A ; [*08F9.0020.0002.266A] # EIGHTH NOTE +266B ; [*08FA.0020.0002.266B] # BEAMED EIGHTH NOTES +266C ; [*08FB.0020.0002.266C] # BEAMED SIXTEENTH NOTES +266D ; [*0FD5.0020.0002.266D] # MUSIC FLAT SIGN +266E ; [*0FD6.0020.0002.266E] # MUSIC NATURAL SIGN +266F ; [*0FD7.0020.0002.266F] # MUSIC SHARP SIGN +2670 ; [*08FC.0020.0002.2670] # WEST SYRIAC CROSS +2671 ; [*08FD.0020.0002.2671] # EAST SYRIAC CROSS +2672 ; [*08FE.0020.0002.2672] # UNIVERSAL RECYCLING SYMBOL +2673 ; [*08FF.0020.0002.2673] # RECYCLING SYMBOL FOR TYPE-1 PLASTICS +2674 ; [*0900.0020.0002.2674] # RECYCLING SYMBOL FOR TYPE-2 PLASTICS +2675 ; [*0901.0020.0002.2675] # RECYCLING SYMBOL FOR TYPE-3 PLASTICS +2676 ; [*0902.0020.0002.2676] # RECYCLING SYMBOL FOR TYPE-4 PLASTICS +2677 ; [*0903.0020.0002.2677] # RECYCLING SYMBOL FOR TYPE-5 PLASTICS +2678 ; [*0904.0020.0002.2678] # RECYCLING SYMBOL FOR TYPE-6 PLASTICS +2679 ; [*0905.0020.0002.2679] # RECYCLING SYMBOL FOR TYPE-7 PLASTICS +267A ; [*0906.0020.0002.267A] # RECYCLING SYMBOL FOR GENERIC MATERIALS +267B ; [*0907.0020.0002.267B] # BLACK UNIVERSAL RECYCLING SYMBOL +267C ; [*0908.0020.0002.267C] # RECYCLED PAPER SYMBOL +267D ; [*0909.0020.0002.267D] # PARTIALLY-RECYCLED PAPER SYMBOL +267E ; [*090A.0020.0002.267E] # PERMANENT PAPER SIGN +267F ; [*090B.0020.0002.267F] # WHEELCHAIR SYMBOL +2680 ; [*090C.0020.0002.2680] # DIE FACE-1 +2681 ; [*090D.0020.0002.2681] # DIE FACE-2 +2682 ; [*090E.0020.0002.2682] # DIE FACE-3 +2683 ; [*090F.0020.0002.2683] # DIE FACE-4 +2684 ; [*0910.0020.0002.2684] # DIE FACE-5 +2685 ; [*0911.0020.0002.2685] # DIE FACE-6 +2686 ; [*0912.0020.0002.2686] # WHITE CIRCLE WITH DOT RIGHT +2687 ; [*0913.0020.0002.2687] # WHITE CIRCLE WITH TWO DOTS +2688 ; [*0914.0020.0002.2688] # BLACK CIRCLE WITH WHITE DOT RIGHT +2689 ; [*0915.0020.0002.2689] # BLACK CIRCLE WITH TWO WHITE DOTS +268A ; [*0D89.0020.0002.268A] # MONOGRAM FOR YANG +268B ; [*0D8A.0020.0002.268B] # MONOGRAM FOR YIN +268C ; [*0D8B.0020.0002.268C] # DIGRAM FOR GREATER YANG +268D ; [*0D8C.0020.0002.268D] # DIGRAM FOR LESSER YIN +268E ; [*0D8D.0020.0002.268E] # DIGRAM FOR LESSER YANG +268F ; [*0D8E.0020.0002.268F] # DIGRAM FOR GREATER YIN +2690 ; [*0916.0020.0002.2690] # WHITE FLAG +2691 ; [*0917.0020.0002.2691] # BLACK FLAG +2692 ; [*0918.0020.0002.2692] # HAMMER AND PICK +2693 ; [*0919.0020.0002.2693] # ANCHOR +2694 ; [*091A.0020.0002.2694] # CROSSED SWORDS +2695 ; [*091B.0020.0002.2695] # STAFF OF AESCULAPIUS +2696 ; [*091C.0020.0002.2696] # SCALES +2697 ; [*091D.0020.0002.2697] # ALEMBIC +2698 ; [*091E.0020.0002.2698] # FLOWER +2699 ; [*091F.0020.0002.2699] # GEAR +269A ; [*0920.0020.0002.269A] # STAFF OF HERMES +269B ; [*0921.0020.0002.269B] # ATOM SYMBOL +269C ; [*0922.0020.0002.269C] # FLEUR-DE-LIS +269D ; [*0923.0020.0002.269D] # OUTLINED WHITE STAR +269E ; [*0924.0020.0002.269E] # THREE LINES CONVERGING RIGHT +269F ; [*0925.0020.0002.269F] # THREE LINES CONVERGING LEFT +26A0 ; [*0926.0020.0002.26A0] # WARNING SIGN +26A1 ; [*0927.0020.0002.26A1] # HIGH VOLTAGE SIGN +26A2 ; [*0928.0020.0002.26A2] # DOUBLED FEMALE SIGN +26A3 ; [*0929.0020.0002.26A3] # DOUBLED MALE SIGN +26A4 ; [*092A.0020.0002.26A4] # INTERLOCKED FEMALE AND MALE SIGN +26A5 ; [*092B.0020.0002.26A5] # MALE AND FEMALE SIGN +26A6 ; [*092C.0020.0002.26A6] # MALE WITH STROKE SIGN +26A7 ; [*092D.0020.0002.26A7] # MALE WITH STROKE AND MALE AND FEMALE SIGN +26A8 ; [*092E.0020.0002.26A8] # VERTICAL MALE WITH STROKE SIGN +26A9 ; [*092F.0020.0002.26A9] # HORIZONTAL MALE WITH STROKE SIGN +26AA ; [*0930.0020.0002.26AA] # MEDIUM WHITE CIRCLE +26AB ; [*0931.0020.0002.26AB] # MEDIUM BLACK CIRCLE +26AC ; [*0932.0020.0002.26AC] # MEDIUM SMALL WHITE CIRCLE +26AD ; [*0933.0020.0002.26AD] # MARRIAGE SYMBOL +26AE ; [*0934.0020.0002.26AE] # DIVORCE SYMBOL +26AF ; [*0935.0020.0002.26AF] # UNMARRIED PARTNERSHIP SYMBOL +26B0 ; [*0936.0020.0002.26B0] # COFFIN +26B1 ; [*0937.0020.0002.26B1] # FUNERAL URN +26B2 ; [*0938.0020.0002.26B2] # NEUTER +26B3 ; [*0939.0020.0002.26B3] # CERES +26B4 ; [*093A.0020.0002.26B4] # PALLAS +26B5 ; [*093B.0020.0002.26B5] # JUNO +26B6 ; [*093C.0020.0002.26B6] # VESTA +26B7 ; [*093D.0020.0002.26B7] # CHIRON +26B8 ; [*093E.0020.0002.26B8] # BLACK MOON LILITH +26B9 ; [*093F.0020.0002.26B9] # SEXTILE +26BA ; [*0940.0020.0002.26BA] # SEMISEXTILE +26BB ; [*0941.0020.0002.26BB] # QUINCUNX +26BC ; [*0942.0020.0002.26BC] # SESQUIQUADRATE +26BD ; [*0943.0020.0002.26BD] # SOCCER BALL +26BE ; [*0944.0020.0002.26BE] # BASEBALL +26BF ; [*0945.0020.0002.26BF] # SQUARED KEY +26C0 ; [*0946.0020.0002.26C0] # WHITE DRAUGHTS MAN +26C1 ; [*0947.0020.0002.26C1] # WHITE DRAUGHTS KING +26C2 ; [*0948.0020.0002.26C2] # BLACK DRAUGHTS MAN +26C3 ; [*0949.0020.0002.26C3] # BLACK DRAUGHTS KING +26C4 ; [*094A.0020.0002.26C4] # SNOWMAN WITHOUT SNOW +26C5 ; [*094B.0020.0002.26C5] # SUN BEHIND CLOUD +26C6 ; [*094C.0020.0002.26C6] # RAIN +26C7 ; [*094D.0020.0002.26C7] # BLACK SNOWMAN +26C8 ; [*094E.0020.0002.26C8] # THUNDER CLOUD AND RAIN +26C9 ; [*094F.0020.0002.26C9] # TURNED WHITE SHOGI PIECE +26CA ; [*0950.0020.0002.26CA] # TURNED BLACK SHOGI PIECE +26CB ; [*0951.0020.0002.26CB] # WHITE DIAMOND IN SQUARE +26CC ; [*0952.0020.0002.26CC] # CROSSING LANES +26CD ; [*0953.0020.0002.26CD] # DISABLED CAR +26CE ; [*0954.0020.0002.26CE] # OPHIUCHUS +26CF ; [*0955.0020.0002.26CF] # PICK +26D0 ; [*0956.0020.0002.26D0] # CAR SLIDING +26D1 ; [*0957.0020.0002.26D1] # HELMET WITH WHITE CROSS +26D2 ; [*0958.0020.0002.26D2] # CIRCLED CROSSING LANES +26D3 ; [*0959.0020.0002.26D3] # CHAINS +26D4 ; [*095A.0020.0002.26D4] # NO ENTRY +26D5 ; [*095B.0020.0002.26D5] # ALTERNATE ONE-WAY LEFT WAY TRAFFIC +26D6 ; [*095C.0020.0002.26D6] # BLACK TWO-WAY LEFT WAY TRAFFIC +26D7 ; [*095D.0020.0002.26D7] # WHITE TWO-WAY LEFT WAY TRAFFIC +26D8 ; [*095E.0020.0002.26D8] # BLACK LEFT LANE MERGE +26D9 ; [*095F.0020.0002.26D9] # WHITE LEFT LANE MERGE +26DA ; [*0960.0020.0002.26DA] # DRIVE SLOW SIGN +26DB ; [*0961.0020.0002.26DB] # HEAVY WHITE DOWN-POINTING TRIANGLE +26DC ; [*0962.0020.0002.26DC] # LEFT CLOSED ENTRY +26DD ; [*0963.0020.0002.26DD] # SQUARED SALTIRE +26DE ; [*0964.0020.0002.26DE] # FALLING DIAGONAL IN WHITE CIRCLE IN BLACK SQUARE +26DF ; [*0965.0020.0002.26DF] # BLACK TRUCK +26E0 ; [*0966.0020.0002.26E0] # RESTRICTED LEFT ENTRY-1 +26E1 ; [*0967.0020.0002.26E1] # RESTRICTED LEFT ENTRY-2 +26E2 ; [*0968.0020.0002.26E2] # ASTRONOMICAL SYMBOL FOR URANUS +26E3 ; [*0969.0020.0002.26E3] # HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE +26E4 ; [*096A.0020.0002.26E4] # PENTAGRAM +26E5 ; [*096B.0020.0002.26E5] # RIGHT-HANDED INTERLACED PENTAGRAM +26E6 ; [*096C.0020.0002.26E6] # LEFT-HANDED INTERLACED PENTAGRAM +26E7 ; [*096D.0020.0002.26E7] # INVERTED PENTAGRAM +26E8 ; [*096E.0020.0002.26E8] # BLACK CROSS ON SHIELD +26E9 ; [*096F.0020.0002.26E9] # SHINTO SHRINE +26EA ; [*0970.0020.0002.26EA] # CHURCH +26EB ; [*0971.0020.0002.26EB] # CASTLE +26EC ; [*0972.0020.0002.26EC] # HISTORIC SITE +26ED ; [*0973.0020.0002.26ED] # GEAR WITHOUT HUB +26EE ; [*0974.0020.0002.26EE] # GEAR WITH HANDLES +26EF ; [*0975.0020.0002.26EF] # MAP SYMBOL FOR LIGHTHOUSE +26F0 ; [*0976.0020.0002.26F0] # MOUNTAIN +26F1 ; [*0977.0020.0002.26F1] # UMBRELLA ON GROUND +26F2 ; [*0978.0020.0002.26F2] # FOUNTAIN +26F3 ; [*0979.0020.0002.26F3] # FLAG IN HOLE +26F4 ; [*097A.0020.0002.26F4] # FERRY +26F5 ; [*097B.0020.0002.26F5] # SAILBOAT +26F6 ; [*097C.0020.0002.26F6] # SQUARE FOUR CORNERS +26F7 ; [*097D.0020.0002.26F7] # SKIER +26F8 ; [*097E.0020.0002.26F8] # ICE SKATE +26F9 ; [*097F.0020.0002.26F9] # PERSON WITH BALL +26FA ; [*0980.0020.0002.26FA] # TENT +26FB ; [*0981.0020.0002.26FB] # JAPANESE BANK SYMBOL +26FC ; [*0982.0020.0002.26FC] # HEADSTONE GRAVEYARD SYMBOL +26FD ; [*0983.0020.0002.26FD] # FUEL PUMP +26FE ; [*0984.0020.0002.26FE] # CUP ON BLACK SQUARE +26FF ; [*0985.0020.0002.26FF] # WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE +2701 ; [*0986.0020.0002.2701] # UPPER BLADE SCISSORS +2702 ; [*0987.0020.0002.2702] # BLACK SCISSORS +2703 ; [*0988.0020.0002.2703] # LOWER BLADE SCISSORS +2704 ; [*0989.0020.0002.2704] # WHITE SCISSORS +2705 ; [*098A.0020.0002.2705] # WHITE HEAVY CHECK MARK +2706 ; [*098B.0020.0002.2706] # TELEPHONE LOCATION SIGN +2707 ; [*098C.0020.0002.2707] # TAPE DRIVE +2708 ; [*098D.0020.0002.2708] # AIRPLANE +2709 ; [*098E.0020.0002.2709] # ENVELOPE +270A ; [*098F.0020.0002.270A] # RAISED FIST +270B ; [*0990.0020.0002.270B] # RAISED HAND +270C ; [*0991.0020.0002.270C] # VICTORY HAND +270D ; [*0992.0020.0002.270D] # WRITING HAND +270E ; [*0993.0020.0002.270E] # LOWER RIGHT PENCIL +270F ; [*0994.0020.0002.270F] # PENCIL +2710 ; [*0995.0020.0002.2710] # UPPER RIGHT PENCIL +2711 ; [*0996.0020.0002.2711] # WHITE NIB +2712 ; [*0997.0020.0002.2712] # BLACK NIB +2713 ; [*0998.0020.0002.2713] # CHECK MARK +2714 ; [*0999.0020.0002.2714] # HEAVY CHECK MARK +2715 ; [*099A.0020.0002.2715] # MULTIPLICATION X +2716 ; [*099B.0020.0002.2716] # HEAVY MULTIPLICATION X +2717 ; [*099C.0020.0002.2717] # BALLOT X +2718 ; [*099D.0020.0002.2718] # HEAVY BALLOT X +2719 ; [*099E.0020.0002.2719] # OUTLINED GREEK CROSS +271A ; [*099F.0020.0002.271A] # HEAVY GREEK CROSS +271B ; [*09A0.0020.0002.271B] # OPEN CENTRE CROSS +271C ; [*09A1.0020.0002.271C] # HEAVY OPEN CENTRE CROSS +271D ; [*09A2.0020.0002.271D] # LATIN CROSS +271E ; [*09A3.0020.0002.271E] # SHADOWED WHITE LATIN CROSS +271F ; [*09A4.0020.0002.271F] # OUTLINED LATIN CROSS +2720 ; [*09A5.0020.0002.2720] # MALTESE CROSS +2721 ; [*09A6.0020.0002.2721] # STAR OF DAVID +2722 ; [*09A7.0020.0002.2722] # FOUR TEARDROP-SPOKED ASTERISK +2723 ; [*09A8.0020.0002.2723] # FOUR BALLOON-SPOKED ASTERISK +2724 ; [*09A9.0020.0002.2724] # HEAVY FOUR BALLOON-SPOKED ASTERISK +2725 ; [*09AA.0020.0002.2725] # FOUR CLUB-SPOKED ASTERISK +2726 ; [*09AB.0020.0002.2726] # BLACK FOUR POINTED STAR +2727 ; [*09AC.0020.0002.2727] # WHITE FOUR POINTED STAR +2728 ; [*09AD.0020.0002.2728] # SPARKLES +2729 ; [*09AE.0020.0002.2729] # STRESS OUTLINED WHITE STAR +272A ; [*09AF.0020.0002.272A] # CIRCLED WHITE STAR +272B ; [*09B0.0020.0002.272B] # OPEN CENTRE BLACK STAR +272C ; [*09B1.0020.0002.272C] # BLACK CENTRE WHITE STAR +272D ; [*09B2.0020.0002.272D] # OUTLINED BLACK STAR +272E ; [*09B3.0020.0002.272E] # HEAVY OUTLINED BLACK STAR +272F ; [*09B4.0020.0002.272F] # PINWHEEL STAR +2730 ; [*09B5.0020.0002.2730] # SHADOWED WHITE STAR +2731 ; [*09B6.0020.0002.2731] # HEAVY ASTERISK +2732 ; [*09B7.0020.0002.2732] # OPEN CENTRE ASTERISK +2733 ; [*09B8.0020.0002.2733] # EIGHT SPOKED ASTERISK +2734 ; [*09B9.0020.0002.2734] # EIGHT POINTED BLACK STAR +2735 ; [*09BA.0020.0002.2735] # EIGHT POINTED PINWHEEL STAR +2736 ; [*09BB.0020.0002.2736] # SIX POINTED BLACK STAR +2737 ; [*09BC.0020.0002.2737] # EIGHT POINTED RECTILINEAR BLACK STAR +2738 ; [*09BD.0020.0002.2738] # HEAVY EIGHT POINTED RECTILINEAR BLACK STAR +2739 ; [*09BE.0020.0002.2739] # TWELVE POINTED BLACK STAR +273A ; [*09BF.0020.0002.273A] # SIXTEEN POINTED ASTERISK +273B ; [*09C0.0020.0002.273B] # TEARDROP-SPOKED ASTERISK +273C ; [*09C1.0020.0002.273C] # OPEN CENTRE TEARDROP-SPOKED ASTERISK +273D ; [*09C2.0020.0002.273D] # HEAVY TEARDROP-SPOKED ASTERISK +273E ; [*09C3.0020.0002.273E] # SIX PETALLED BLACK AND WHITE FLORETTE +273F ; [*09C4.0020.0002.273F] # BLACK FLORETTE +2740 ; [*09C5.0020.0002.2740] # WHITE FLORETTE +2741 ; [*09C6.0020.0002.2741] # EIGHT PETALLED OUTLINED BLACK FLORETTE +2742 ; [*09C7.0020.0002.2742] # CIRCLED OPEN CENTRE EIGHT POINTED STAR +2743 ; [*09C8.0020.0002.2743] # HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK +2744 ; [*09C9.0020.0002.2744] # SNOWFLAKE +2745 ; [*09CA.0020.0002.2745] # TIGHT TRIFOLIATE SNOWFLAKE +2746 ; [*09CB.0020.0002.2746] # HEAVY CHEVRON SNOWFLAKE +2747 ; [*09CC.0020.0002.2747] # SPARKLE +2748 ; [*09CD.0020.0002.2748] # HEAVY SPARKLE +2749 ; [*09CE.0020.0002.2749] # BALLOON-SPOKED ASTERISK +274A ; [*09CF.0020.0002.274A] # EIGHT TEARDROP-SPOKED PROPELLER ASTERISK +274B ; [*09D0.0020.0002.274B] # HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK +274C ; [*09D1.0020.0002.274C] # CROSS MARK +274D ; [*09D2.0020.0002.274D] # SHADOWED WHITE CIRCLE +274E ; [*09D3.0020.0002.274E] # NEGATIVE SQUARED CROSS MARK +274F ; [*09D4.0020.0002.274F] # LOWER RIGHT DROP-SHADOWED WHITE SQUARE +2750 ; [*09D5.0020.0002.2750] # UPPER RIGHT DROP-SHADOWED WHITE SQUARE +2751 ; [*09D6.0020.0002.2751] # LOWER RIGHT SHADOWED WHITE SQUARE +2752 ; [*09D7.0020.0002.2752] # UPPER RIGHT SHADOWED WHITE SQUARE +2753 ; [*09D8.0020.0002.2753] # BLACK QUESTION MARK ORNAMENT +2754 ; [*09D9.0020.0002.2754] # WHITE QUESTION MARK ORNAMENT +2755 ; [*09DA.0020.0002.2755] # WHITE EXCLAMATION MARK ORNAMENT +2756 ; [*09DB.0020.0002.2756] # BLACK DIAMOND MINUS WHITE X +2757 ; [*09DC.0020.0002.2757] # HEAVY EXCLAMATION MARK SYMBOL +2758 ; [*09DD.0020.0002.2758] # LIGHT VERTICAL BAR +2759 ; [*09DE.0020.0002.2759] # MEDIUM VERTICAL BAR +275A ; [*09DF.0020.0002.275A] # HEAVY VERTICAL BAR +275B ; [*09E0.0020.0002.275B] # HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT +275C ; [*09E1.0020.0002.275C] # HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT +275D ; [*09E2.0020.0002.275D] # HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT +275E ; [*09E3.0020.0002.275E] # HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT +275F ; [*09E4.0020.0002.275F] # HEAVY LOW SINGLE COMMA QUOTATION MARK ORNAMENT +2760 ; [*09E5.0020.0002.2760] # HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT +2761 ; [*09E6.0020.0002.2761] # CURVED STEM PARAGRAPH SIGN ORNAMENT +2762 ; [*09E7.0020.0002.2762] # HEAVY EXCLAMATION MARK ORNAMENT +2763 ; [*09E8.0020.0002.2763] # HEAVY HEART EXCLAMATION MARK ORNAMENT +2764 ; [*09E9.0020.0002.2764] # HEAVY BLACK HEART +2765 ; [*09EA.0020.0002.2765] # ROTATED HEAVY BLACK HEART BULLET +2766 ; [*09EB.0020.0002.2766] # FLORAL HEART +2767 ; [*09EC.0020.0002.2767] # ROTATED FLORAL HEART BULLET +2768 ; [*032D.0020.0002.2768] # MEDIUM LEFT PARENTHESIS ORNAMENT +2769 ; [*032E.0020.0002.2769] # MEDIUM RIGHT PARENTHESIS ORNAMENT +276A ; [*032F.0020.0002.276A] # MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT +276B ; [*0330.0020.0002.276B] # MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT +276C ; [*0331.0020.0002.276C] # MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT +276D ; [*0332.0020.0002.276D] # MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT +276E ; [*0333.0020.0002.276E] # HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT +276F ; [*0334.0020.0002.276F] # HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT +2770 ; [*0335.0020.0002.2770] # HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT +2771 ; [*0336.0020.0002.2771] # HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT +2772 ; [*0337.0020.0002.2772] # LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT +2773 ; [*0338.0020.0002.2773] # LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT +2774 ; [*0339.0020.0002.2774] # MEDIUM LEFT CURLY BRACKET ORNAMENT +2775 ; [*033A.0020.0002.2775] # MEDIUM RIGHT CURLY BRACKET ORNAMENT +2794 ; [*09ED.0020.0002.2794] # HEAVY WIDE-HEADED RIGHTWARDS ARROW +2795 ; [*09EE.0020.0002.2795] # HEAVY PLUS SIGN +2796 ; [*09EF.0020.0002.2796] # HEAVY MINUS SIGN +2797 ; [*09F0.0020.0002.2797] # HEAVY DIVISION SIGN +2798 ; [*09F1.0020.0002.2798] # HEAVY SOUTH EAST ARROW +2799 ; [*09F2.0020.0002.2799] # HEAVY RIGHTWARDS ARROW +279A ; [*09F3.0020.0002.279A] # HEAVY NORTH EAST ARROW +279B ; [*09F4.0020.0002.279B] # DRAFTING POINT RIGHTWARDS ARROW +279C ; [*09F5.0020.0002.279C] # HEAVY ROUND-TIPPED RIGHTWARDS ARROW +279D ; [*09F6.0020.0002.279D] # TRIANGLE-HEADED RIGHTWARDS ARROW +279E ; [*09F7.0020.0002.279E] # HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW +279F ; [*09F8.0020.0002.279F] # DASHED TRIANGLE-HEADED RIGHTWARDS ARROW +27A0 ; [*09F9.0020.0002.27A0] # HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW +27A1 ; [*09FA.0020.0002.27A1] # BLACK RIGHTWARDS ARROW +27A2 ; [*09FB.0020.0002.27A2] # THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD +27A3 ; [*09FC.0020.0002.27A3] # THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD +27A4 ; [*09FD.0020.0002.27A4] # BLACK RIGHTWARDS ARROWHEAD +27A5 ; [*09FE.0020.0002.27A5] # HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW +27A6 ; [*09FF.0020.0002.27A6] # HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW +27A7 ; [*0A00.0020.0002.27A7] # SQUAT BLACK RIGHTWARDS ARROW +27A8 ; [*0A01.0020.0002.27A8] # HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW +27A9 ; [*0A02.0020.0002.27A9] # RIGHT-SHADED WHITE RIGHTWARDS ARROW +27AA ; [*0A03.0020.0002.27AA] # LEFT-SHADED WHITE RIGHTWARDS ARROW +27AB ; [*0A04.0020.0002.27AB] # BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW +27AC ; [*0A05.0020.0002.27AC] # FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW +27AD ; [*0A06.0020.0002.27AD] # HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW +27AE ; [*0A07.0020.0002.27AE] # HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW +27AF ; [*0A08.0020.0002.27AF] # NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW +27B0 ; [*0A09.0020.0002.27B0] # CURLY LOOP +27B1 ; [*0A0A.0020.0002.27B1] # NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW +27B2 ; [*0A0B.0020.0002.27B2] # CIRCLED HEAVY WHITE RIGHTWARDS ARROW +27B3 ; [*0A0C.0020.0002.27B3] # WHITE-FEATHERED RIGHTWARDS ARROW +27B4 ; [*0A0D.0020.0002.27B4] # BLACK-FEATHERED SOUTH EAST ARROW +27B5 ; [*0A0E.0020.0002.27B5] # BLACK-FEATHERED RIGHTWARDS ARROW +27B6 ; [*0A0F.0020.0002.27B6] # BLACK-FEATHERED NORTH EAST ARROW +27B7 ; [*0A10.0020.0002.27B7] # HEAVY BLACK-FEATHERED SOUTH EAST ARROW +27B8 ; [*0A11.0020.0002.27B8] # HEAVY BLACK-FEATHERED RIGHTWARDS ARROW +27B9 ; [*0A12.0020.0002.27B9] # HEAVY BLACK-FEATHERED NORTH EAST ARROW +27BA ; [*0A13.0020.0002.27BA] # TEARDROP-BARBED RIGHTWARDS ARROW +27BB ; [*0A14.0020.0002.27BB] # HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW +27BC ; [*0A15.0020.0002.27BC] # WEDGE-TAILED RIGHTWARDS ARROW +27BD ; [*0A16.0020.0002.27BD] # HEAVY WEDGE-TAILED RIGHTWARDS ARROW +27BE ; [*0A17.0020.0002.27BE] # OPEN-OUTLINED RIGHTWARDS ARROW +27BF ; [*0A18.0020.0002.27BF] # DOUBLE CURLY LOOP +27C0 ; [*0A19.0020.0002.27C0] # THREE DIMENSIONAL ANGLE +27C1 ; [*0A1A.0020.0002.27C1] # WHITE TRIANGLE CONTAINING SMALL WHITE TRIANGLE +27C2 ; [*0A1B.0020.0002.27C2] # PERPENDICULAR +27C3 ; [*0A1C.0020.0002.27C3] # OPEN SUBSET +27C4 ; [*0A1D.0020.0002.27C4] # OPEN SUPERSET +27C5 ; [*0321.0020.0002.27C5] # LEFT S-SHAPED BAG DELIMITER +27C6 ; [*0322.0020.0002.27C6] # RIGHT S-SHAPED BAG DELIMITER +27C7 ; [*0A1E.0020.0002.27C7] # OR WITH DOT INSIDE +27C8 ; [*0A1F.0020.0002.27C8] # REVERSE SOLIDUS PRECEDING SUBSET +27C9 ; [*0A20.0020.0002.27C9] # SUPERSET PRECEDING SOLIDUS +27CA ; [*0A21.0020.0002.27CA] # VERTICAL BAR WITH HORIZONTAL STROKE +27CB ; [*0A22.0020.0002.27CB] # MATHEMATICAL RISING DIAGONAL +27CC ; [*0A23.0020.0002.27CC] # LONG DIVISION +27CD ; [*0A24.0020.0002.27CD] # MATHEMATICAL FALLING DIAGONAL +27CE ; [*0A25.0020.0002.27CE] # SQUARED LOGICAL AND +27CF ; [*0A26.0020.0002.27CF] # SQUARED LOGICAL OR +27D0 ; [*0A27.0020.0002.27D0] # WHITE DIAMOND WITH CENTRED DOT +27D1 ; [*0A28.0020.0002.27D1] # AND WITH DOT +27D2 ; [*0A29.0020.0002.27D2] # ELEMENT OF OPENING UPWARDS +27D3 ; [*0A2A.0020.0002.27D3] # LOWER RIGHT CORNER WITH DOT +27D4 ; [*0A2B.0020.0002.27D4] # UPPER LEFT CORNER WITH DOT +27D5 ; [*0A2C.0020.0002.27D5] # LEFT OUTER JOIN +27D6 ; [*0A2D.0020.0002.27D6] # RIGHT OUTER JOIN +27D7 ; [*0A2E.0020.0002.27D7] # FULL OUTER JOIN +27D8 ; [*0A2F.0020.0002.27D8] # LARGE UP TACK +27D9 ; [*0A30.0020.0002.27D9] # LARGE DOWN TACK +27DA ; [*0A31.0020.0002.27DA] # LEFT AND RIGHT DOUBLE TURNSTILE +27DB ; [*0A32.0020.0002.27DB] # LEFT AND RIGHT TACK +27DC ; [*0A33.0020.0002.27DC] # LEFT MULTIMAP +27DD ; [*0A34.0020.0002.27DD] # LONG RIGHT TACK +27DE ; [*0A35.0020.0002.27DE] # LONG LEFT TACK +27DF ; [*0A36.0020.0002.27DF] # UP TACK WITH CIRCLE ABOVE +27E0 ; [*0A37.0020.0002.27E0] # LOZENGE DIVIDED BY HORIZONTAL RULE +27E1 ; [*0A38.0020.0002.27E1] # WHITE CONCAVE-SIDED DIAMOND +27E2 ; [*0A39.0020.0002.27E2] # WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK +27E3 ; [*0A3A.0020.0002.27E3] # WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK +27E4 ; [*0A3B.0020.0002.27E4] # WHITE SQUARE WITH LEFTWARDS TICK +27E5 ; [*0A3C.0020.0002.27E5] # WHITE SQUARE WITH RIGHTWARDS TICK +27E6 ; [*0323.0020.0002.27E6] # MATHEMATICAL LEFT WHITE SQUARE BRACKET +27E7 ; [*0324.0020.0002.27E7] # MATHEMATICAL RIGHT WHITE SQUARE BRACKET +27E8 ; [*0325.0020.0002.27E8] # MATHEMATICAL LEFT ANGLE BRACKET +27E9 ; [*0326.0020.0002.27E9] # MATHEMATICAL RIGHT ANGLE BRACKET +27EA ; [*0327.0020.0002.27EA] # MATHEMATICAL LEFT DOUBLE ANGLE BRACKET +27EB ; [*0328.0020.0002.27EB] # MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET +27EC ; [*0329.0020.0002.27EC] # MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET +27ED ; [*032A.0020.0002.27ED] # MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET +27EE ; [*032B.0020.0002.27EE] # MATHEMATICAL LEFT FLATTENED PARENTHESIS +27EF ; [*032C.0020.0002.27EF] # MATHEMATICAL RIGHT FLATTENED PARENTHESIS +27F0 ; [*0A3D.0020.0002.27F0] # UPWARDS QUADRUPLE ARROW +27F1 ; [*0A3E.0020.0002.27F1] # DOWNWARDS QUADRUPLE ARROW +27F2 ; [*0A3F.0020.0002.27F2] # ANTICLOCKWISE GAPPED CIRCLE ARROW +27F3 ; [*0A40.0020.0002.27F3] # CLOCKWISE GAPPED CIRCLE ARROW +27F4 ; [*0A41.0020.0002.27F4] # RIGHT ARROW WITH CIRCLED PLUS +27F5 ; [*0A42.0020.0002.27F5] # LONG LEFTWARDS ARROW +27F6 ; [*0A43.0020.0002.27F6] # LONG RIGHTWARDS ARROW +27F7 ; [*0A44.0020.0002.27F7] # LONG LEFT RIGHT ARROW +27F8 ; [*0A45.0020.0002.27F8] # LONG LEFTWARDS DOUBLE ARROW +27F9 ; [*0A46.0020.0002.27F9] # LONG RIGHTWARDS DOUBLE ARROW +27FA ; [*0A47.0020.0002.27FA] # LONG LEFT RIGHT DOUBLE ARROW +27FB ; [*0A48.0020.0002.27FB] # LONG LEFTWARDS ARROW FROM BAR +27FC ; [*0A49.0020.0002.27FC] # LONG RIGHTWARDS ARROW FROM BAR +27FD ; [*0A4A.0020.0002.27FD] # LONG LEFTWARDS DOUBLE ARROW FROM BAR +27FE ; [*0A4B.0020.0002.27FE] # LONG RIGHTWARDS DOUBLE ARROW FROM BAR +27FF ; [*0A4C.0020.0002.27FF] # LONG RIGHTWARDS SQUIGGLE ARROW +2800 ; [*0C89.0020.0002.2800] # BRAILLE PATTERN BLANK +2801 ; [*0C8A.0020.0002.2801] # BRAILLE PATTERN DOTS-1 +2802 ; [*0C8B.0020.0002.2802] # BRAILLE PATTERN DOTS-2 +2803 ; [*0C8C.0020.0002.2803] # BRAILLE PATTERN DOTS-12 +2804 ; [*0C8D.0020.0002.2804] # BRAILLE PATTERN DOTS-3 +2805 ; [*0C8E.0020.0002.2805] # BRAILLE PATTERN DOTS-13 +2806 ; [*0C8F.0020.0002.2806] # BRAILLE PATTERN DOTS-23 +2807 ; [*0C90.0020.0002.2807] # BRAILLE PATTERN DOTS-123 +2808 ; [*0C91.0020.0002.2808] # BRAILLE PATTERN DOTS-4 +2809 ; [*0C92.0020.0002.2809] # BRAILLE PATTERN DOTS-14 +280A ; [*0C93.0020.0002.280A] # BRAILLE PATTERN DOTS-24 +280B ; [*0C94.0020.0002.280B] # BRAILLE PATTERN DOTS-124 +280C ; [*0C95.0020.0002.280C] # BRAILLE PATTERN DOTS-34 +280D ; [*0C96.0020.0002.280D] # BRAILLE PATTERN DOTS-134 +280E ; [*0C97.0020.0002.280E] # BRAILLE PATTERN DOTS-234 +280F ; [*0C98.0020.0002.280F] # BRAILLE PATTERN DOTS-1234 +2810 ; [*0C99.0020.0002.2810] # BRAILLE PATTERN DOTS-5 +2811 ; [*0C9A.0020.0002.2811] # BRAILLE PATTERN DOTS-15 +2812 ; [*0C9B.0020.0002.2812] # BRAILLE PATTERN DOTS-25 +2813 ; [*0C9C.0020.0002.2813] # BRAILLE PATTERN DOTS-125 +2814 ; [*0C9D.0020.0002.2814] # BRAILLE PATTERN DOTS-35 +2815 ; [*0C9E.0020.0002.2815] # BRAILLE PATTERN DOTS-135 +2816 ; [*0C9F.0020.0002.2816] # BRAILLE PATTERN DOTS-235 +2817 ; [*0CA0.0020.0002.2817] # BRAILLE PATTERN DOTS-1235 +2818 ; [*0CA1.0020.0002.2818] # BRAILLE PATTERN DOTS-45 +2819 ; [*0CA2.0020.0002.2819] # BRAILLE PATTERN DOTS-145 +281A ; [*0CA3.0020.0002.281A] # BRAILLE PATTERN DOTS-245 +281B ; [*0CA4.0020.0002.281B] # BRAILLE PATTERN DOTS-1245 +281C ; [*0CA5.0020.0002.281C] # BRAILLE PATTERN DOTS-345 +281D ; [*0CA6.0020.0002.281D] # BRAILLE PATTERN DOTS-1345 +281E ; [*0CA7.0020.0002.281E] # BRAILLE PATTERN DOTS-2345 +281F ; [*0CA8.0020.0002.281F] # BRAILLE PATTERN DOTS-12345 +2820 ; [*0CA9.0020.0002.2820] # BRAILLE PATTERN DOTS-6 +2821 ; [*0CAA.0020.0002.2821] # BRAILLE PATTERN DOTS-16 +2822 ; [*0CAB.0020.0002.2822] # BRAILLE PATTERN DOTS-26 +2823 ; [*0CAC.0020.0002.2823] # BRAILLE PATTERN DOTS-126 +2824 ; [*0CAD.0020.0002.2824] # BRAILLE PATTERN DOTS-36 +2825 ; [*0CAE.0020.0002.2825] # BRAILLE PATTERN DOTS-136 +2826 ; [*0CAF.0020.0002.2826] # BRAILLE PATTERN DOTS-236 +2827 ; [*0CB0.0020.0002.2827] # BRAILLE PATTERN DOTS-1236 +2828 ; [*0CB1.0020.0002.2828] # BRAILLE PATTERN DOTS-46 +2829 ; [*0CB2.0020.0002.2829] # BRAILLE PATTERN DOTS-146 +282A ; [*0CB3.0020.0002.282A] # BRAILLE PATTERN DOTS-246 +282B ; [*0CB4.0020.0002.282B] # BRAILLE PATTERN DOTS-1246 +282C ; [*0CB5.0020.0002.282C] # BRAILLE PATTERN DOTS-346 +282D ; [*0CB6.0020.0002.282D] # BRAILLE PATTERN DOTS-1346 +282E ; [*0CB7.0020.0002.282E] # BRAILLE PATTERN DOTS-2346 +282F ; [*0CB8.0020.0002.282F] # BRAILLE PATTERN DOTS-12346 +2830 ; [*0CB9.0020.0002.2830] # BRAILLE PATTERN DOTS-56 +2831 ; [*0CBA.0020.0002.2831] # BRAILLE PATTERN DOTS-156 +2832 ; [*0CBB.0020.0002.2832] # BRAILLE PATTERN DOTS-256 +2833 ; [*0CBC.0020.0002.2833] # BRAILLE PATTERN DOTS-1256 +2834 ; [*0CBD.0020.0002.2834] # BRAILLE PATTERN DOTS-356 +2835 ; [*0CBE.0020.0002.2835] # BRAILLE PATTERN DOTS-1356 +2836 ; [*0CBF.0020.0002.2836] # BRAILLE PATTERN DOTS-2356 +2837 ; [*0CC0.0020.0002.2837] # BRAILLE PATTERN DOTS-12356 +2838 ; [*0CC1.0020.0002.2838] # BRAILLE PATTERN DOTS-456 +2839 ; [*0CC2.0020.0002.2839] # BRAILLE PATTERN DOTS-1456 +283A ; [*0CC3.0020.0002.283A] # BRAILLE PATTERN DOTS-2456 +283B ; [*0CC4.0020.0002.283B] # BRAILLE PATTERN DOTS-12456 +283C ; [*0CC5.0020.0002.283C] # BRAILLE PATTERN DOTS-3456 +283D ; [*0CC6.0020.0002.283D] # BRAILLE PATTERN DOTS-13456 +283E ; [*0CC7.0020.0002.283E] # BRAILLE PATTERN DOTS-23456 +283F ; [*0CC8.0020.0002.283F] # BRAILLE PATTERN DOTS-123456 +2840 ; [*0CC9.0020.0002.2840] # BRAILLE PATTERN DOTS-7 +2841 ; [*0CCA.0020.0002.2841] # BRAILLE PATTERN DOTS-17 +2842 ; [*0CCB.0020.0002.2842] # BRAILLE PATTERN DOTS-27 +2843 ; [*0CCC.0020.0002.2843] # BRAILLE PATTERN DOTS-127 +2844 ; [*0CCD.0020.0002.2844] # BRAILLE PATTERN DOTS-37 +2845 ; [*0CCE.0020.0002.2845] # BRAILLE PATTERN DOTS-137 +2846 ; [*0CCF.0020.0002.2846] # BRAILLE PATTERN DOTS-237 +2847 ; [*0CD0.0020.0002.2847] # BRAILLE PATTERN DOTS-1237 +2848 ; [*0CD1.0020.0002.2848] # BRAILLE PATTERN DOTS-47 +2849 ; [*0CD2.0020.0002.2849] # BRAILLE PATTERN DOTS-147 +284A ; [*0CD3.0020.0002.284A] # BRAILLE PATTERN DOTS-247 +284B ; [*0CD4.0020.0002.284B] # BRAILLE PATTERN DOTS-1247 +284C ; [*0CD5.0020.0002.284C] # BRAILLE PATTERN DOTS-347 +284D ; [*0CD6.0020.0002.284D] # BRAILLE PATTERN DOTS-1347 +284E ; [*0CD7.0020.0002.284E] # BRAILLE PATTERN DOTS-2347 +284F ; [*0CD8.0020.0002.284F] # BRAILLE PATTERN DOTS-12347 +2850 ; [*0CD9.0020.0002.2850] # BRAILLE PATTERN DOTS-57 +2851 ; [*0CDA.0020.0002.2851] # BRAILLE PATTERN DOTS-157 +2852 ; [*0CDB.0020.0002.2852] # BRAILLE PATTERN DOTS-257 +2853 ; [*0CDC.0020.0002.2853] # BRAILLE PATTERN DOTS-1257 +2854 ; [*0CDD.0020.0002.2854] # BRAILLE PATTERN DOTS-357 +2855 ; [*0CDE.0020.0002.2855] # BRAILLE PATTERN DOTS-1357 +2856 ; [*0CDF.0020.0002.2856] # BRAILLE PATTERN DOTS-2357 +2857 ; [*0CE0.0020.0002.2857] # BRAILLE PATTERN DOTS-12357 +2858 ; [*0CE1.0020.0002.2858] # BRAILLE PATTERN DOTS-457 +2859 ; [*0CE2.0020.0002.2859] # BRAILLE PATTERN DOTS-1457 +285A ; [*0CE3.0020.0002.285A] # BRAILLE PATTERN DOTS-2457 +285B ; [*0CE4.0020.0002.285B] # BRAILLE PATTERN DOTS-12457 +285C ; [*0CE5.0020.0002.285C] # BRAILLE PATTERN DOTS-3457 +285D ; [*0CE6.0020.0002.285D] # BRAILLE PATTERN DOTS-13457 +285E ; [*0CE7.0020.0002.285E] # BRAILLE PATTERN DOTS-23457 +285F ; [*0CE8.0020.0002.285F] # BRAILLE PATTERN DOTS-123457 +2860 ; [*0CE9.0020.0002.2860] # BRAILLE PATTERN DOTS-67 +2861 ; [*0CEA.0020.0002.2861] # BRAILLE PATTERN DOTS-167 +2862 ; [*0CEB.0020.0002.2862] # BRAILLE PATTERN DOTS-267 +2863 ; [*0CEC.0020.0002.2863] # BRAILLE PATTERN DOTS-1267 +2864 ; [*0CED.0020.0002.2864] # BRAILLE PATTERN DOTS-367 +2865 ; [*0CEE.0020.0002.2865] # BRAILLE PATTERN DOTS-1367 +2866 ; [*0CEF.0020.0002.2866] # BRAILLE PATTERN DOTS-2367 +2867 ; [*0CF0.0020.0002.2867] # BRAILLE PATTERN DOTS-12367 +2868 ; [*0CF1.0020.0002.2868] # BRAILLE PATTERN DOTS-467 +2869 ; [*0CF2.0020.0002.2869] # BRAILLE PATTERN DOTS-1467 +286A ; [*0CF3.0020.0002.286A] # BRAILLE PATTERN DOTS-2467 +286B ; [*0CF4.0020.0002.286B] # BRAILLE PATTERN DOTS-12467 +286C ; [*0CF5.0020.0002.286C] # BRAILLE PATTERN DOTS-3467 +286D ; [*0CF6.0020.0002.286D] # BRAILLE PATTERN DOTS-13467 +286E ; [*0CF7.0020.0002.286E] # BRAILLE PATTERN DOTS-23467 +286F ; [*0CF8.0020.0002.286F] # BRAILLE PATTERN DOTS-123467 +2870 ; [*0CF9.0020.0002.2870] # BRAILLE PATTERN DOTS-567 +2871 ; [*0CFA.0020.0002.2871] # BRAILLE PATTERN DOTS-1567 +2872 ; [*0CFB.0020.0002.2872] # BRAILLE PATTERN DOTS-2567 +2873 ; [*0CFC.0020.0002.2873] # BRAILLE PATTERN DOTS-12567 +2874 ; [*0CFD.0020.0002.2874] # BRAILLE PATTERN DOTS-3567 +2875 ; [*0CFE.0020.0002.2875] # BRAILLE PATTERN DOTS-13567 +2876 ; [*0CFF.0020.0002.2876] # BRAILLE PATTERN DOTS-23567 +2877 ; [*0D00.0020.0002.2877] # BRAILLE PATTERN DOTS-123567 +2878 ; [*0D01.0020.0002.2878] # BRAILLE PATTERN DOTS-4567 +2879 ; [*0D02.0020.0002.2879] # BRAILLE PATTERN DOTS-14567 +287A ; [*0D03.0020.0002.287A] # BRAILLE PATTERN DOTS-24567 +287B ; [*0D04.0020.0002.287B] # BRAILLE PATTERN DOTS-124567 +287C ; [*0D05.0020.0002.287C] # BRAILLE PATTERN DOTS-34567 +287D ; [*0D06.0020.0002.287D] # BRAILLE PATTERN DOTS-134567 +287E ; [*0D07.0020.0002.287E] # BRAILLE PATTERN DOTS-234567 +287F ; [*0D08.0020.0002.287F] # BRAILLE PATTERN DOTS-1234567 +2880 ; [*0D09.0020.0002.2880] # BRAILLE PATTERN DOTS-8 +2881 ; [*0D0A.0020.0002.2881] # BRAILLE PATTERN DOTS-18 +2882 ; [*0D0B.0020.0002.2882] # BRAILLE PATTERN DOTS-28 +2883 ; [*0D0C.0020.0002.2883] # BRAILLE PATTERN DOTS-128 +2884 ; [*0D0D.0020.0002.2884] # BRAILLE PATTERN DOTS-38 +2885 ; [*0D0E.0020.0002.2885] # BRAILLE PATTERN DOTS-138 +2886 ; [*0D0F.0020.0002.2886] # BRAILLE PATTERN DOTS-238 +2887 ; [*0D10.0020.0002.2887] # BRAILLE PATTERN DOTS-1238 +2888 ; [*0D11.0020.0002.2888] # BRAILLE PATTERN DOTS-48 +2889 ; [*0D12.0020.0002.2889] # BRAILLE PATTERN DOTS-148 +288A ; [*0D13.0020.0002.288A] # BRAILLE PATTERN DOTS-248 +288B ; [*0D14.0020.0002.288B] # BRAILLE PATTERN DOTS-1248 +288C ; [*0D15.0020.0002.288C] # BRAILLE PATTERN DOTS-348 +288D ; [*0D16.0020.0002.288D] # BRAILLE PATTERN DOTS-1348 +288E ; [*0D17.0020.0002.288E] # BRAILLE PATTERN DOTS-2348 +288F ; [*0D18.0020.0002.288F] # BRAILLE PATTERN DOTS-12348 +2890 ; [*0D19.0020.0002.2890] # BRAILLE PATTERN DOTS-58 +2891 ; [*0D1A.0020.0002.2891] # BRAILLE PATTERN DOTS-158 +2892 ; [*0D1B.0020.0002.2892] # BRAILLE PATTERN DOTS-258 +2893 ; [*0D1C.0020.0002.2893] # BRAILLE PATTERN DOTS-1258 +2894 ; [*0D1D.0020.0002.2894] # BRAILLE PATTERN DOTS-358 +2895 ; [*0D1E.0020.0002.2895] # BRAILLE PATTERN DOTS-1358 +2896 ; [*0D1F.0020.0002.2896] # BRAILLE PATTERN DOTS-2358 +2897 ; [*0D20.0020.0002.2897] # BRAILLE PATTERN DOTS-12358 +2898 ; [*0D21.0020.0002.2898] # BRAILLE PATTERN DOTS-458 +2899 ; [*0D22.0020.0002.2899] # BRAILLE PATTERN DOTS-1458 +289A ; [*0D23.0020.0002.289A] # BRAILLE PATTERN DOTS-2458 +289B ; [*0D24.0020.0002.289B] # BRAILLE PATTERN DOTS-12458 +289C ; [*0D25.0020.0002.289C] # BRAILLE PATTERN DOTS-3458 +289D ; [*0D26.0020.0002.289D] # BRAILLE PATTERN DOTS-13458 +289E ; [*0D27.0020.0002.289E] # BRAILLE PATTERN DOTS-23458 +289F ; [*0D28.0020.0002.289F] # BRAILLE PATTERN DOTS-123458 +28A0 ; [*0D29.0020.0002.28A0] # BRAILLE PATTERN DOTS-68 +28A1 ; [*0D2A.0020.0002.28A1] # BRAILLE PATTERN DOTS-168 +28A2 ; [*0D2B.0020.0002.28A2] # BRAILLE PATTERN DOTS-268 +28A3 ; [*0D2C.0020.0002.28A3] # BRAILLE PATTERN DOTS-1268 +28A4 ; [*0D2D.0020.0002.28A4] # BRAILLE PATTERN DOTS-368 +28A5 ; [*0D2E.0020.0002.28A5] # BRAILLE PATTERN DOTS-1368 +28A6 ; [*0D2F.0020.0002.28A6] # BRAILLE PATTERN DOTS-2368 +28A7 ; [*0D30.0020.0002.28A7] # BRAILLE PATTERN DOTS-12368 +28A8 ; [*0D31.0020.0002.28A8] # BRAILLE PATTERN DOTS-468 +28A9 ; [*0D32.0020.0002.28A9] # BRAILLE PATTERN DOTS-1468 +28AA ; [*0D33.0020.0002.28AA] # BRAILLE PATTERN DOTS-2468 +28AB ; [*0D34.0020.0002.28AB] # BRAILLE PATTERN DOTS-12468 +28AC ; [*0D35.0020.0002.28AC] # BRAILLE PATTERN DOTS-3468 +28AD ; [*0D36.0020.0002.28AD] # BRAILLE PATTERN DOTS-13468 +28AE ; [*0D37.0020.0002.28AE] # BRAILLE PATTERN DOTS-23468 +28AF ; [*0D38.0020.0002.28AF] # BRAILLE PATTERN DOTS-123468 +28B0 ; [*0D39.0020.0002.28B0] # BRAILLE PATTERN DOTS-568 +28B1 ; [*0D3A.0020.0002.28B1] # BRAILLE PATTERN DOTS-1568 +28B2 ; [*0D3B.0020.0002.28B2] # BRAILLE PATTERN DOTS-2568 +28B3 ; [*0D3C.0020.0002.28B3] # BRAILLE PATTERN DOTS-12568 +28B4 ; [*0D3D.0020.0002.28B4] # BRAILLE PATTERN DOTS-3568 +28B5 ; [*0D3E.0020.0002.28B5] # BRAILLE PATTERN DOTS-13568 +28B6 ; [*0D3F.0020.0002.28B6] # BRAILLE PATTERN DOTS-23568 +28B7 ; [*0D40.0020.0002.28B7] # BRAILLE PATTERN DOTS-123568 +28B8 ; [*0D41.0020.0002.28B8] # BRAILLE PATTERN DOTS-4568 +28B9 ; [*0D42.0020.0002.28B9] # BRAILLE PATTERN DOTS-14568 +28BA ; [*0D43.0020.0002.28BA] # BRAILLE PATTERN DOTS-24568 +28BB ; [*0D44.0020.0002.28BB] # BRAILLE PATTERN DOTS-124568 +28BC ; [*0D45.0020.0002.28BC] # BRAILLE PATTERN DOTS-34568 +28BD ; [*0D46.0020.0002.28BD] # BRAILLE PATTERN DOTS-134568 +28BE ; [*0D47.0020.0002.28BE] # BRAILLE PATTERN DOTS-234568 +28BF ; [*0D48.0020.0002.28BF] # BRAILLE PATTERN DOTS-1234568 +28C0 ; [*0D49.0020.0002.28C0] # BRAILLE PATTERN DOTS-78 +28C1 ; [*0D4A.0020.0002.28C1] # BRAILLE PATTERN DOTS-178 +28C2 ; [*0D4B.0020.0002.28C2] # BRAILLE PATTERN DOTS-278 +28C3 ; [*0D4C.0020.0002.28C3] # BRAILLE PATTERN DOTS-1278 +28C4 ; [*0D4D.0020.0002.28C4] # BRAILLE PATTERN DOTS-378 +28C5 ; [*0D4E.0020.0002.28C5] # BRAILLE PATTERN DOTS-1378 +28C6 ; [*0D4F.0020.0002.28C6] # BRAILLE PATTERN DOTS-2378 +28C7 ; [*0D50.0020.0002.28C7] # BRAILLE PATTERN DOTS-12378 +28C8 ; [*0D51.0020.0002.28C8] # BRAILLE PATTERN DOTS-478 +28C9 ; [*0D52.0020.0002.28C9] # BRAILLE PATTERN DOTS-1478 +28CA ; [*0D53.0020.0002.28CA] # BRAILLE PATTERN DOTS-2478 +28CB ; [*0D54.0020.0002.28CB] # BRAILLE PATTERN DOTS-12478 +28CC ; [*0D55.0020.0002.28CC] # BRAILLE PATTERN DOTS-3478 +28CD ; [*0D56.0020.0002.28CD] # BRAILLE PATTERN DOTS-13478 +28CE ; [*0D57.0020.0002.28CE] # BRAILLE PATTERN DOTS-23478 +28CF ; [*0D58.0020.0002.28CF] # BRAILLE PATTERN DOTS-123478 +28D0 ; [*0D59.0020.0002.28D0] # BRAILLE PATTERN DOTS-578 +28D1 ; [*0D5A.0020.0002.28D1] # BRAILLE PATTERN DOTS-1578 +28D2 ; [*0D5B.0020.0002.28D2] # BRAILLE PATTERN DOTS-2578 +28D3 ; [*0D5C.0020.0002.28D3] # BRAILLE PATTERN DOTS-12578 +28D4 ; [*0D5D.0020.0002.28D4] # BRAILLE PATTERN DOTS-3578 +28D5 ; [*0D5E.0020.0002.28D5] # BRAILLE PATTERN DOTS-13578 +28D6 ; [*0D5F.0020.0002.28D6] # BRAILLE PATTERN DOTS-23578 +28D7 ; [*0D60.0020.0002.28D7] # BRAILLE PATTERN DOTS-123578 +28D8 ; [*0D61.0020.0002.28D8] # BRAILLE PATTERN DOTS-4578 +28D9 ; [*0D62.0020.0002.28D9] # BRAILLE PATTERN DOTS-14578 +28DA ; [*0D63.0020.0002.28DA] # BRAILLE PATTERN DOTS-24578 +28DB ; [*0D64.0020.0002.28DB] # BRAILLE PATTERN DOTS-124578 +28DC ; [*0D65.0020.0002.28DC] # BRAILLE PATTERN DOTS-34578 +28DD ; [*0D66.0020.0002.28DD] # BRAILLE PATTERN DOTS-134578 +28DE ; [*0D67.0020.0002.28DE] # BRAILLE PATTERN DOTS-234578 +28DF ; [*0D68.0020.0002.28DF] # BRAILLE PATTERN DOTS-1234578 +28E0 ; [*0D69.0020.0002.28E0] # BRAILLE PATTERN DOTS-678 +28E1 ; [*0D6A.0020.0002.28E1] # BRAILLE PATTERN DOTS-1678 +28E2 ; [*0D6B.0020.0002.28E2] # BRAILLE PATTERN DOTS-2678 +28E3 ; [*0D6C.0020.0002.28E3] # BRAILLE PATTERN DOTS-12678 +28E4 ; [*0D6D.0020.0002.28E4] # BRAILLE PATTERN DOTS-3678 +28E5 ; [*0D6E.0020.0002.28E5] # BRAILLE PATTERN DOTS-13678 +28E6 ; [*0D6F.0020.0002.28E6] # BRAILLE PATTERN DOTS-23678 +28E7 ; [*0D70.0020.0002.28E7] # BRAILLE PATTERN DOTS-123678 +28E8 ; [*0D71.0020.0002.28E8] # BRAILLE PATTERN DOTS-4678 +28E9 ; [*0D72.0020.0002.28E9] # BRAILLE PATTERN DOTS-14678 +28EA ; [*0D73.0020.0002.28EA] # BRAILLE PATTERN DOTS-24678 +28EB ; [*0D74.0020.0002.28EB] # BRAILLE PATTERN DOTS-124678 +28EC ; [*0D75.0020.0002.28EC] # BRAILLE PATTERN DOTS-34678 +28ED ; [*0D76.0020.0002.28ED] # BRAILLE PATTERN DOTS-134678 +28EE ; [*0D77.0020.0002.28EE] # BRAILLE PATTERN DOTS-234678 +28EF ; [*0D78.0020.0002.28EF] # BRAILLE PATTERN DOTS-1234678 +28F0 ; [*0D79.0020.0002.28F0] # BRAILLE PATTERN DOTS-5678 +28F1 ; [*0D7A.0020.0002.28F1] # BRAILLE PATTERN DOTS-15678 +28F2 ; [*0D7B.0020.0002.28F2] # BRAILLE PATTERN DOTS-25678 +28F3 ; [*0D7C.0020.0002.28F3] # BRAILLE PATTERN DOTS-125678 +28F4 ; [*0D7D.0020.0002.28F4] # BRAILLE PATTERN DOTS-35678 +28F5 ; [*0D7E.0020.0002.28F5] # BRAILLE PATTERN DOTS-135678 +28F6 ; [*0D7F.0020.0002.28F6] # BRAILLE PATTERN DOTS-235678 +28F7 ; [*0D80.0020.0002.28F7] # BRAILLE PATTERN DOTS-1235678 +28F8 ; [*0D81.0020.0002.28F8] # BRAILLE PATTERN DOTS-45678 +28F9 ; [*0D82.0020.0002.28F9] # BRAILLE PATTERN DOTS-145678 +28FA ; [*0D83.0020.0002.28FA] # BRAILLE PATTERN DOTS-245678 +28FB ; [*0D84.0020.0002.28FB] # BRAILLE PATTERN DOTS-1245678 +28FC ; [*0D85.0020.0002.28FC] # BRAILLE PATTERN DOTS-345678 +28FD ; [*0D86.0020.0002.28FD] # BRAILLE PATTERN DOTS-1345678 +28FE ; [*0D87.0020.0002.28FE] # BRAILLE PATTERN DOTS-2345678 +28FF ; [*0D88.0020.0002.28FF] # BRAILLE PATTERN DOTS-12345678 +2900 ; [*0A4D.0020.0002.2900] # RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE +2901 ; [*0A4E.0020.0002.2901] # RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE +2902 ; [*0A4F.0020.0002.2902] # LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE +2903 ; [*0A50.0020.0002.2903] # RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE +2904 ; [*0A51.0020.0002.2904] # LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE +2905 ; [*0A52.0020.0002.2905] # RIGHTWARDS TWO-HEADED ARROW FROM BAR +2906 ; [*0A53.0020.0002.2906] # LEFTWARDS DOUBLE ARROW FROM BAR +2907 ; [*0A54.0020.0002.2907] # RIGHTWARDS DOUBLE ARROW FROM BAR +2908 ; [*0A55.0020.0002.2908] # DOWNWARDS ARROW WITH HORIZONTAL STROKE +2909 ; [*0A56.0020.0002.2909] # UPWARDS ARROW WITH HORIZONTAL STROKE +290A ; [*0A57.0020.0002.290A] # UPWARDS TRIPLE ARROW +290B ; [*0A58.0020.0002.290B] # DOWNWARDS TRIPLE ARROW +290C ; [*0A59.0020.0002.290C] # LEFTWARDS DOUBLE DASH ARROW +290D ; [*0A5A.0020.0002.290D] # RIGHTWARDS DOUBLE DASH ARROW +290E ; [*0A5B.0020.0002.290E] # LEFTWARDS TRIPLE DASH ARROW +290F ; [*0A5C.0020.0002.290F] # RIGHTWARDS TRIPLE DASH ARROW +2910 ; [*0A5D.0020.0002.2910] # RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW +2911 ; [*0A5E.0020.0002.2911] # RIGHTWARDS ARROW WITH DOTTED STEM +2912 ; [*0A5F.0020.0002.2912] # UPWARDS ARROW TO BAR +2913 ; [*0A60.0020.0002.2913] # DOWNWARDS ARROW TO BAR +2914 ; [*0A61.0020.0002.2914] # RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE +2915 ; [*0A62.0020.0002.2915] # RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE +2916 ; [*0A63.0020.0002.2916] # RIGHTWARDS TWO-HEADED ARROW WITH TAIL +2917 ; [*0A64.0020.0002.2917] # RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE +2918 ; [*0A65.0020.0002.2918] # RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE +2919 ; [*0A66.0020.0002.2919] # LEFTWARDS ARROW-TAIL +291A ; [*0A67.0020.0002.291A] # RIGHTWARDS ARROW-TAIL +291B ; [*0A68.0020.0002.291B] # LEFTWARDS DOUBLE ARROW-TAIL +291C ; [*0A69.0020.0002.291C] # RIGHTWARDS DOUBLE ARROW-TAIL +291D ; [*0A6A.0020.0002.291D] # LEFTWARDS ARROW TO BLACK DIAMOND +291E ; [*0A6B.0020.0002.291E] # RIGHTWARDS ARROW TO BLACK DIAMOND +291F ; [*0A6C.0020.0002.291F] # LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND +2920 ; [*0A6D.0020.0002.2920] # RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND +2921 ; [*0A6E.0020.0002.2921] # NORTH WEST AND SOUTH EAST ARROW +2922 ; [*0A6F.0020.0002.2922] # NORTH EAST AND SOUTH WEST ARROW +2923 ; [*0A70.0020.0002.2923] # NORTH WEST ARROW WITH HOOK +2924 ; [*0A71.0020.0002.2924] # NORTH EAST ARROW WITH HOOK +2925 ; [*0A72.0020.0002.2925] # SOUTH EAST ARROW WITH HOOK +2926 ; [*0A73.0020.0002.2926] # SOUTH WEST ARROW WITH HOOK +2927 ; [*0A74.0020.0002.2927] # NORTH WEST ARROW AND NORTH EAST ARROW +2928 ; [*0A75.0020.0002.2928] # NORTH EAST ARROW AND SOUTH EAST ARROW +2929 ; [*0A76.0020.0002.2929] # SOUTH EAST ARROW AND SOUTH WEST ARROW +292A ; [*0A77.0020.0002.292A] # SOUTH WEST ARROW AND NORTH WEST ARROW +292B ; [*0A78.0020.0002.292B] # RISING DIAGONAL CROSSING FALLING DIAGONAL +292C ; [*0A79.0020.0002.292C] # FALLING DIAGONAL CROSSING RISING DIAGONAL +292D ; [*0A7A.0020.0002.292D] # SOUTH EAST ARROW CROSSING NORTH EAST ARROW +292E ; [*0A7B.0020.0002.292E] # NORTH EAST ARROW CROSSING SOUTH EAST ARROW +292F ; [*0A7C.0020.0002.292F] # FALLING DIAGONAL CROSSING NORTH EAST ARROW +2930 ; [*0A7D.0020.0002.2930] # RISING DIAGONAL CROSSING SOUTH EAST ARROW +2931 ; [*0A7E.0020.0002.2931] # NORTH EAST ARROW CROSSING NORTH WEST ARROW +2932 ; [*0A7F.0020.0002.2932] # NORTH WEST ARROW CROSSING NORTH EAST ARROW +2933 ; [*0A80.0020.0002.2933] # WAVE ARROW POINTING DIRECTLY RIGHT +2934 ; [*0A81.0020.0002.2934] # ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS +2935 ; [*0A82.0020.0002.2935] # ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS +2936 ; [*0A83.0020.0002.2936] # ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS +2937 ; [*0A84.0020.0002.2937] # ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS +2938 ; [*0A85.0020.0002.2938] # RIGHT-SIDE ARC CLOCKWISE ARROW +2939 ; [*0A86.0020.0002.2939] # LEFT-SIDE ARC ANTICLOCKWISE ARROW +293A ; [*0A87.0020.0002.293A] # TOP ARC ANTICLOCKWISE ARROW +293B ; [*0A88.0020.0002.293B] # BOTTOM ARC ANTICLOCKWISE ARROW +293C ; [*0A89.0020.0002.293C] # TOP ARC CLOCKWISE ARROW WITH MINUS +293D ; [*0A8A.0020.0002.293D] # TOP ARC ANTICLOCKWISE ARROW WITH PLUS +293E ; [*0A8B.0020.0002.293E] # LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW +293F ; [*0A8C.0020.0002.293F] # LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW +2940 ; [*0A8D.0020.0002.2940] # ANTICLOCKWISE CLOSED CIRCLE ARROW +2941 ; [*0A8E.0020.0002.2941] # CLOCKWISE CLOSED CIRCLE ARROW +2942 ; [*0A8F.0020.0002.2942] # RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW +2943 ; [*0A90.0020.0002.2943] # LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW +2944 ; [*0A91.0020.0002.2944] # SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW +2945 ; [*0A92.0020.0002.2945] # RIGHTWARDS ARROW WITH PLUS BELOW +2946 ; [*0A93.0020.0002.2946] # LEFTWARDS ARROW WITH PLUS BELOW +2947 ; [*0A94.0020.0002.2947] # RIGHTWARDS ARROW THROUGH X +2948 ; [*0A95.0020.0002.2948] # LEFT RIGHT ARROW THROUGH SMALL CIRCLE +2949 ; [*0A96.0020.0002.2949] # UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE +294A ; [*0A97.0020.0002.294A] # LEFT BARB UP RIGHT BARB DOWN HARPOON +294B ; [*0A98.0020.0002.294B] # LEFT BARB DOWN RIGHT BARB UP HARPOON +294C ; [*0A99.0020.0002.294C] # UP BARB RIGHT DOWN BARB LEFT HARPOON +294D ; [*0A9A.0020.0002.294D] # UP BARB LEFT DOWN BARB RIGHT HARPOON +294E ; [*0A9B.0020.0002.294E] # LEFT BARB UP RIGHT BARB UP HARPOON +294F ; [*0A9C.0020.0002.294F] # UP BARB RIGHT DOWN BARB RIGHT HARPOON +2950 ; [*0A9D.0020.0002.2950] # LEFT BARB DOWN RIGHT BARB DOWN HARPOON +2951 ; [*0A9E.0020.0002.2951] # UP BARB LEFT DOWN BARB LEFT HARPOON +2952 ; [*0A9F.0020.0002.2952] # LEFTWARDS HARPOON WITH BARB UP TO BAR +2953 ; [*0AA0.0020.0002.2953] # RIGHTWARDS HARPOON WITH BARB UP TO BAR +2954 ; [*0AA1.0020.0002.2954] # UPWARDS HARPOON WITH BARB RIGHT TO BAR +2955 ; [*0AA2.0020.0002.2955] # DOWNWARDS HARPOON WITH BARB RIGHT TO BAR +2956 ; [*0AA3.0020.0002.2956] # LEFTWARDS HARPOON WITH BARB DOWN TO BAR +2957 ; [*0AA4.0020.0002.2957] # RIGHTWARDS HARPOON WITH BARB DOWN TO BAR +2958 ; [*0AA5.0020.0002.2958] # UPWARDS HARPOON WITH BARB LEFT TO BAR +2959 ; [*0AA6.0020.0002.2959] # DOWNWARDS HARPOON WITH BARB LEFT TO BAR +295A ; [*0AA7.0020.0002.295A] # LEFTWARDS HARPOON WITH BARB UP FROM BAR +295B ; [*0AA8.0020.0002.295B] # RIGHTWARDS HARPOON WITH BARB UP FROM BAR +295C ; [*0AA9.0020.0002.295C] # UPWARDS HARPOON WITH BARB RIGHT FROM BAR +295D ; [*0AAA.0020.0002.295D] # DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR +295E ; [*0AAB.0020.0002.295E] # LEFTWARDS HARPOON WITH BARB DOWN FROM BAR +295F ; [*0AAC.0020.0002.295F] # RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR +2960 ; [*0AAD.0020.0002.2960] # UPWARDS HARPOON WITH BARB LEFT FROM BAR +2961 ; [*0AAE.0020.0002.2961] # DOWNWARDS HARPOON WITH BARB LEFT FROM BAR +2962 ; [*0AAF.0020.0002.2962] # LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN +2963 ; [*0AB0.0020.0002.2963] # UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT +2964 ; [*0AB1.0020.0002.2964] # RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN +2965 ; [*0AB2.0020.0002.2965] # DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT +2966 ; [*0AB3.0020.0002.2966] # LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP +2967 ; [*0AB4.0020.0002.2967] # LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN +2968 ; [*0AB5.0020.0002.2968] # RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP +2969 ; [*0AB6.0020.0002.2969] # RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN +296A ; [*0AB7.0020.0002.296A] # LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH +296B ; [*0AB8.0020.0002.296B] # LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH +296C ; [*0AB9.0020.0002.296C] # RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH +296D ; [*0ABA.0020.0002.296D] # RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH +296E ; [*0ABB.0020.0002.296E] # UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT +296F ; [*0ABC.0020.0002.296F] # DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT +2970 ; [*0ABD.0020.0002.2970] # RIGHT DOUBLE ARROW WITH ROUNDED HEAD +2971 ; [*0ABE.0020.0002.2971] # EQUALS SIGN ABOVE RIGHTWARDS ARROW +2972 ; [*0ABF.0020.0002.2972] # TILDE OPERATOR ABOVE RIGHTWARDS ARROW +2973 ; [*0AC0.0020.0002.2973] # LEFTWARDS ARROW ABOVE TILDE OPERATOR +2974 ; [*0AC1.0020.0002.2974] # RIGHTWARDS ARROW ABOVE TILDE OPERATOR +2975 ; [*0AC2.0020.0002.2975] # RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO +2976 ; [*0AC3.0020.0002.2976] # LESS-THAN ABOVE LEFTWARDS ARROW +2977 ; [*0AC4.0020.0002.2977] # LEFTWARDS ARROW THROUGH LESS-THAN +2978 ; [*0AC5.0020.0002.2978] # GREATER-THAN ABOVE RIGHTWARDS ARROW +2979 ; [*0AC6.0020.0002.2979] # SUBSET ABOVE RIGHTWARDS ARROW +297A ; [*0AC7.0020.0002.297A] # LEFTWARDS ARROW THROUGH SUBSET +297B ; [*0AC8.0020.0002.297B] # SUPERSET ABOVE LEFTWARDS ARROW +297C ; [*0AC9.0020.0002.297C] # LEFT FISH TAIL +297D ; [*0ACA.0020.0002.297D] # RIGHT FISH TAIL +297E ; [*0ACB.0020.0002.297E] # UP FISH TAIL +297F ; [*0ACC.0020.0002.297F] # DOWN FISH TAIL +2980 ; [*0ACD.0020.0002.2980] # TRIPLE VERTICAL BAR DELIMITER +2981 ; [*0ACE.0020.0002.2981] # Z NOTATION SPOT +2982 ; [*0ACF.0020.0002.2982] # Z NOTATION TYPE COLON +2983 ; [*030B.0020.0002.2983] # LEFT WHITE CURLY BRACKET +2984 ; [*030C.0020.0002.2984] # RIGHT WHITE CURLY BRACKET +2985 ; [*030D.0020.0002.2985] # LEFT WHITE PARENTHESIS +2986 ; [*030E.0020.0002.2986] # RIGHT WHITE PARENTHESIS +2987 ; [*030F.0020.0002.2987] # Z NOTATION LEFT IMAGE BRACKET +2988 ; [*0310.0020.0002.2988] # Z NOTATION RIGHT IMAGE BRACKET +2989 ; [*0311.0020.0002.2989] # Z NOTATION LEFT BINDING BRACKET +298A ; [*0312.0020.0002.298A] # Z NOTATION RIGHT BINDING BRACKET +298B ; [*0313.0020.0002.298B] # LEFT SQUARE BRACKET WITH UNDERBAR +298C ; [*0314.0020.0002.298C] # RIGHT SQUARE BRACKET WITH UNDERBAR +298D ; [*0315.0020.0002.298D] # LEFT SQUARE BRACKET WITH TICK IN TOP CORNER +298E ; [*0316.0020.0002.298E] # RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +298F ; [*0317.0020.0002.298F] # LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER +2990 ; [*0318.0020.0002.2990] # RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER +2991 ; [*0319.0020.0002.2991] # LEFT ANGLE BRACKET WITH DOT +2992 ; [*031A.0020.0002.2992] # RIGHT ANGLE BRACKET WITH DOT +2993 ; [*031B.0020.0002.2993] # LEFT ARC LESS-THAN BRACKET +2994 ; [*031C.0020.0002.2994] # RIGHT ARC GREATER-THAN BRACKET +2995 ; [*031D.0020.0002.2995] # DOUBLE LEFT ARC GREATER-THAN BRACKET +2996 ; [*031E.0020.0002.2996] # DOUBLE RIGHT ARC LESS-THAN BRACKET +2997 ; [*031F.0020.0002.2997] # LEFT BLACK TORTOISE SHELL BRACKET +2998 ; [*0320.0020.0002.2998] # RIGHT BLACK TORTOISE SHELL BRACKET +2999 ; [*0AD0.0020.0002.2999] # DOTTED FENCE +299A ; [*0AD1.0020.0002.299A] # VERTICAL ZIGZAG LINE +299B ; [*0AD2.0020.0002.299B] # MEASURED ANGLE OPENING LEFT +299C ; [*0AD3.0020.0002.299C] # RIGHT ANGLE VARIANT WITH SQUARE +299D ; [*0AD4.0020.0002.299D] # MEASURED RIGHT ANGLE WITH DOT +299E ; [*0AD5.0020.0002.299E] # ANGLE WITH S INSIDE +299F ; [*0AD6.0020.0002.299F] # ACUTE ANGLE +29A0 ; [*0AD7.0020.0002.29A0] # SPHERICAL ANGLE OPENING LEFT +29A1 ; [*0AD8.0020.0002.29A1] # SPHERICAL ANGLE OPENING UP +29A2 ; [*0AD9.0020.0002.29A2] # TURNED ANGLE +29A3 ; [*0ADA.0020.0002.29A3] # REVERSED ANGLE +29A4 ; [*0ADB.0020.0002.29A4] # ANGLE WITH UNDERBAR +29A5 ; [*0ADC.0020.0002.29A5] # REVERSED ANGLE WITH UNDERBAR +29A6 ; [*0ADD.0020.0002.29A6] # OBLIQUE ANGLE OPENING UP +29A7 ; [*0ADE.0020.0002.29A7] # OBLIQUE ANGLE OPENING DOWN +29A8 ; [*0ADF.0020.0002.29A8] # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT +29A9 ; [*0AE0.0020.0002.29A9] # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT +29AA ; [*0AE1.0020.0002.29AA] # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT +29AB ; [*0AE2.0020.0002.29AB] # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT +29AC ; [*0AE3.0020.0002.29AC] # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP +29AD ; [*0AE4.0020.0002.29AD] # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP +29AE ; [*0AE5.0020.0002.29AE] # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN +29AF ; [*0AE6.0020.0002.29AF] # MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN +29B0 ; [*0AE7.0020.0002.29B0] # REVERSED EMPTY SET +29B1 ; [*0AE8.0020.0002.29B1] # EMPTY SET WITH OVERBAR +29B2 ; [*0AE9.0020.0002.29B2] # EMPTY SET WITH SMALL CIRCLE ABOVE +29B3 ; [*0AEA.0020.0002.29B3] # EMPTY SET WITH RIGHT ARROW ABOVE +29B4 ; [*0AEB.0020.0002.29B4] # EMPTY SET WITH LEFT ARROW ABOVE +29B5 ; [*0AEC.0020.0002.29B5] # CIRCLE WITH HORIZONTAL BAR +29B6 ; [*0AED.0020.0002.29B6] # CIRCLED VERTICAL BAR +29B7 ; [*0AEE.0020.0002.29B7] # CIRCLED PARALLEL +29B8 ; [*0AEF.0020.0002.29B8] # CIRCLED REVERSE SOLIDUS +29B9 ; [*0AF0.0020.0002.29B9] # CIRCLED PERPENDICULAR +29BA ; [*0AF1.0020.0002.29BA] # CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR +29BB ; [*0AF2.0020.0002.29BB] # CIRCLE WITH SUPERIMPOSED X +29BC ; [*0AF3.0020.0002.29BC] # CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN +29BD ; [*0AF4.0020.0002.29BD] # UP ARROW THROUGH CIRCLE +29BE ; [*0AF5.0020.0002.29BE] # CIRCLED WHITE BULLET +29BF ; [*0AF6.0020.0002.29BF] # CIRCLED BULLET +29C0 ; [*0AF7.0020.0002.29C0] # CIRCLED LESS-THAN +29C1 ; [*0AF8.0020.0002.29C1] # CIRCLED GREATER-THAN +29C2 ; [*0AF9.0020.0002.29C2] # CIRCLE WITH SMALL CIRCLE TO THE RIGHT +29C3 ; [*0AFA.0020.0002.29C3] # CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT +29C4 ; [*0AFB.0020.0002.29C4] # SQUARED RISING DIAGONAL SLASH +29C5 ; [*0AFC.0020.0002.29C5] # SQUARED FALLING DIAGONAL SLASH +29C6 ; [*0AFD.0020.0002.29C6] # SQUARED ASTERISK +29C7 ; [*0AFE.0020.0002.29C7] # SQUARED SMALL CIRCLE +29C8 ; [*0AFF.0020.0002.29C8] # SQUARED SQUARE +29C9 ; [*0B00.0020.0002.29C9] # TWO JOINED SQUARES +29CA ; [*0B01.0020.0002.29CA] # TRIANGLE WITH DOT ABOVE +29CB ; [*0B02.0020.0002.29CB] # TRIANGLE WITH UNDERBAR +29CC ; [*0B03.0020.0002.29CC] # S IN TRIANGLE +29CD ; [*0B04.0020.0002.29CD] # TRIANGLE WITH SERIFS AT BOTTOM +29CE ; [*0B05.0020.0002.29CE] # RIGHT TRIANGLE ABOVE LEFT TRIANGLE +29CF ; [*0B06.0020.0002.29CF] # LEFT TRIANGLE BESIDE VERTICAL BAR +29D0 ; [*0B07.0020.0002.29D0] # VERTICAL BAR BESIDE RIGHT TRIANGLE +29D1 ; [*0B08.0020.0002.29D1] # BOWTIE WITH LEFT HALF BLACK +29D2 ; [*0B09.0020.0002.29D2] # BOWTIE WITH RIGHT HALF BLACK +29D3 ; [*0B0A.0020.0002.29D3] # BLACK BOWTIE +29D4 ; [*0B0B.0020.0002.29D4] # TIMES WITH LEFT HALF BLACK +29D5 ; [*0B0C.0020.0002.29D5] # TIMES WITH RIGHT HALF BLACK +29D6 ; [*0B0D.0020.0002.29D6] # WHITE HOURGLASS +29D7 ; [*0B0E.0020.0002.29D7] # BLACK HOURGLASS +29D8 ; [*0364.0020.0002.29D8] # LEFT WIGGLY FENCE +29D9 ; [*0365.0020.0002.29D9] # RIGHT WIGGLY FENCE +29DA ; [*0366.0020.0002.29DA] # LEFT DOUBLE WIGGLY FENCE +29DB ; [*0367.0020.0002.29DB] # RIGHT DOUBLE WIGGLY FENCE +29DC ; [*0B0F.0020.0002.29DC] # INCOMPLETE INFINITY +29DD ; [*0B10.0020.0002.29DD] # TIE OVER INFINITY +29DE ; [*0B11.0020.0002.29DE] # INFINITY NEGATED WITH VERTICAL BAR +29DF ; [*0B12.0020.0002.29DF] # DOUBLE-ENDED MULTIMAP +29E0 ; [*0B13.0020.0002.29E0] # SQUARE WITH CONTOURED OUTLINE +29E1 ; [*0B14.0020.0002.29E1] # INCREASES AS +29E2 ; [*0B15.0020.0002.29E2] # SHUFFLE PRODUCT +29E3 ; [*0B16.0020.0002.29E3] # EQUALS SIGN AND SLANTED PARALLEL +29E4 ; [*0B17.0020.0002.29E4] # EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE +29E5 ; [*0B18.0020.0002.29E5] # IDENTICAL TO AND SLANTED PARALLEL +29E6 ; [*0B19.0020.0002.29E6] # GLEICH STARK +29E7 ; [*0B1A.0020.0002.29E7] # THERMODYNAMIC +29E8 ; [*0B1B.0020.0002.29E8] # DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK +29E9 ; [*0B1C.0020.0002.29E9] # DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK +29EA ; [*0B1D.0020.0002.29EA] # BLACK DIAMOND WITH DOWN ARROW +29EB ; [*0B1E.0020.0002.29EB] # BLACK LOZENGE +29EC ; [*0B1F.0020.0002.29EC] # WHITE CIRCLE WITH DOWN ARROW +29ED ; [*0B20.0020.0002.29ED] # BLACK CIRCLE WITH DOWN ARROW +29EE ; [*0B21.0020.0002.29EE] # ERROR-BARRED WHITE SQUARE +29EF ; [*0B22.0020.0002.29EF] # ERROR-BARRED BLACK SQUARE +29F0 ; [*0B23.0020.0002.29F0] # ERROR-BARRED WHITE DIAMOND +29F1 ; [*0B24.0020.0002.29F1] # ERROR-BARRED BLACK DIAMOND +29F2 ; [*0B25.0020.0002.29F2] # ERROR-BARRED WHITE CIRCLE +29F3 ; [*0B26.0020.0002.29F3] # ERROR-BARRED BLACK CIRCLE +29F4 ; [*0B27.0020.0002.29F4] # RULE-DELAYED +29F5 ; [*0B28.0020.0002.29F5] # REVERSE SOLIDUS OPERATOR +29F6 ; [*0B29.0020.0002.29F6] # SOLIDUS WITH OVERBAR +29F7 ; [*0B2A.0020.0002.29F7] # REVERSE SOLIDUS WITH HORIZONTAL STROKE +29F8 ; [*0B2B.0020.0002.29F8] # BIG SOLIDUS +29F9 ; [*0B2C.0020.0002.29F9] # BIG REVERSE SOLIDUS +29FA ; [*0B2D.0020.0002.29FA] # DOUBLE PLUS +29FB ; [*0B2E.0020.0002.29FB] # TRIPLE PLUS +29FC ; [*0309.0020.0002.29FC] # LEFT-POINTING CURVED ANGLE BRACKET +29FD ; [*030A.0020.0002.29FD] # RIGHT-POINTING CURVED ANGLE BRACKET +29FE ; [*0B2F.0020.0002.29FE] # TINY +29FF ; [*0B30.0020.0002.29FF] # MINY +2A00 ; [*0B31.0020.0002.2A00] # N-ARY CIRCLED DOT OPERATOR +2A01 ; [*0B32.0020.0002.2A01] # N-ARY CIRCLED PLUS OPERATOR +2A02 ; [*0B33.0020.0002.2A02] # N-ARY CIRCLED TIMES OPERATOR +2A03 ; [*0B34.0020.0002.2A03] # N-ARY UNION OPERATOR WITH DOT +2A04 ; [*0B35.0020.0002.2A04] # N-ARY UNION OPERATOR WITH PLUS +2A05 ; [*0B36.0020.0002.2A05] # N-ARY SQUARE INTERSECTION OPERATOR +2A06 ; [*0B37.0020.0002.2A06] # N-ARY SQUARE UNION OPERATOR +2A07 ; [*0B38.0020.0002.2A07] # TWO LOGICAL AND OPERATOR +2A08 ; [*0B39.0020.0002.2A08] # TWO LOGICAL OR OPERATOR +2A09 ; [*0B3A.0020.0002.2A09] # N-ARY TIMES OPERATOR +2A0A ; [*0B3B.0020.0002.2A0A] # MODULO TWO SUM +2A0B ; [*0B3C.0020.0002.2A0B] # SUMMATION WITH INTEGRAL +2A0C ; [*05C2.0020.0004.2A0C][*05C2.0020.0004.2A0C][*05C2.0020.001F.2A0C][*05C2.0020.001F.2A0C] # QUADRUPLE INTEGRAL OPERATOR +2A0D ; [*0B3D.0020.0002.2A0D] # FINITE PART INTEGRAL +2A0E ; [*0B3E.0020.0002.2A0E] # INTEGRAL WITH DOUBLE STROKE +2A0F ; [*0B3F.0020.0002.2A0F] # INTEGRAL AVERAGE WITH SLASH +2A10 ; [*0B40.0020.0002.2A10] # CIRCULATION FUNCTION +2A11 ; [*0B41.0020.0002.2A11] # ANTICLOCKWISE INTEGRATION +2A12 ; [*0B42.0020.0002.2A12] # LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE +2A13 ; [*0B43.0020.0002.2A13] # LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE +2A14 ; [*0B44.0020.0002.2A14] # LINE INTEGRATION NOT INCLUDING THE POLE +2A15 ; [*0B45.0020.0002.2A15] # INTEGRAL AROUND A POINT OPERATOR +2A16 ; [*0B46.0020.0002.2A16] # QUATERNION INTEGRAL OPERATOR +2A17 ; [*0B47.0020.0002.2A17] # INTEGRAL WITH LEFTWARDS ARROW WITH HOOK +2A18 ; [*0B48.0020.0002.2A18] # INTEGRAL WITH TIMES SIGN +2A19 ; [*0B49.0020.0002.2A19] # INTEGRAL WITH INTERSECTION +2A1A ; [*0B4A.0020.0002.2A1A] # INTEGRAL WITH UNION +2A1B ; [*0B4B.0020.0002.2A1B] # INTEGRAL WITH OVERBAR +2A1C ; [*0B4C.0020.0002.2A1C] # INTEGRAL WITH UNDERBAR +2A1D ; [*0B4D.0020.0002.2A1D] # JOIN +2A1E ; [*0B4E.0020.0002.2A1E] # LARGE LEFT TRIANGLE OPERATOR +2A1F ; [*0B4F.0020.0002.2A1F] # Z NOTATION SCHEMA COMPOSITION +2A20 ; [*0B50.0020.0002.2A20] # Z NOTATION SCHEMA PIPING +2A21 ; [*0B51.0020.0002.2A21] # Z NOTATION SCHEMA PROJECTION +2A22 ; [*0B52.0020.0002.2A22] # PLUS SIGN WITH SMALL CIRCLE ABOVE +2A23 ; [*0B53.0020.0002.2A23] # PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE +2A24 ; [*0B54.0020.0002.2A24] # PLUS SIGN WITH TILDE ABOVE +2A25 ; [*0B55.0020.0002.2A25] # PLUS SIGN WITH DOT BELOW +2A26 ; [*0B56.0020.0002.2A26] # PLUS SIGN WITH TILDE BELOW +2A27 ; [*0B57.0020.0002.2A27] # PLUS SIGN WITH SUBSCRIPT TWO +2A28 ; [*0B58.0020.0002.2A28] # PLUS SIGN WITH BLACK TRIANGLE +2A29 ; [*0B59.0020.0002.2A29] # MINUS SIGN WITH COMMA ABOVE +2A2A ; [*0B5A.0020.0002.2A2A] # MINUS SIGN WITH DOT BELOW +2A2B ; [*0B5B.0020.0002.2A2B] # MINUS SIGN WITH FALLING DOTS +2A2C ; [*0B5C.0020.0002.2A2C] # MINUS SIGN WITH RISING DOTS +2A2D ; [*0B5D.0020.0002.2A2D] # PLUS SIGN IN LEFT HALF CIRCLE +2A2E ; [*0B5E.0020.0002.2A2E] # PLUS SIGN IN RIGHT HALF CIRCLE +2A2F ; [*0B5F.0020.0002.2A2F] # VECTOR OR CROSS PRODUCT +2A30 ; [*0B60.0020.0002.2A30] # MULTIPLICATION SIGN WITH DOT ABOVE +2A31 ; [*0B61.0020.0002.2A31] # MULTIPLICATION SIGN WITH UNDERBAR +2A32 ; [*0B62.0020.0002.2A32] # SEMIDIRECT PRODUCT WITH BOTTOM CLOSED +2A33 ; [*0B63.0020.0002.2A33] # SMASH PRODUCT +2A34 ; [*0B64.0020.0002.2A34] # MULTIPLICATION SIGN IN LEFT HALF CIRCLE +2A35 ; [*0B65.0020.0002.2A35] # MULTIPLICATION SIGN IN RIGHT HALF CIRCLE +2A36 ; [*0B66.0020.0002.2A36] # CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT +2A37 ; [*0B67.0020.0002.2A37] # MULTIPLICATION SIGN IN DOUBLE CIRCLE +2A38 ; [*0B68.0020.0002.2A38] # CIRCLED DIVISION SIGN +2A39 ; [*0B69.0020.0002.2A39] # PLUS SIGN IN TRIANGLE +2A3A ; [*0B6A.0020.0002.2A3A] # MINUS SIGN IN TRIANGLE +2A3B ; [*0B6B.0020.0002.2A3B] # MULTIPLICATION SIGN IN TRIANGLE +2A3C ; [*0B6C.0020.0002.2A3C] # INTERIOR PRODUCT +2A3D ; [*0B6D.0020.0002.2A3D] # RIGHTHAND INTERIOR PRODUCT +2A3E ; [*0B6E.0020.0002.2A3E] # Z NOTATION RELATIONAL COMPOSITION +2A3F ; [*0B6F.0020.0002.2A3F] # AMALGAMATION OR COPRODUCT +2A40 ; [*0B70.0020.0002.2A40] # INTERSECTION WITH DOT +2A41 ; [*0B71.0020.0002.2A41] # UNION WITH MINUS SIGN +2A42 ; [*0B72.0020.0002.2A42] # UNION WITH OVERBAR +2A43 ; [*0B73.0020.0002.2A43] # INTERSECTION WITH OVERBAR +2A44 ; [*0B74.0020.0002.2A44] # INTERSECTION WITH LOGICAL AND +2A45 ; [*0B75.0020.0002.2A45] # UNION WITH LOGICAL OR +2A46 ; [*0B76.0020.0002.2A46] # UNION ABOVE INTERSECTION +2A47 ; [*0B77.0020.0002.2A47] # INTERSECTION ABOVE UNION +2A48 ; [*0B78.0020.0002.2A48] # UNION ABOVE BAR ABOVE INTERSECTION +2A49 ; [*0B79.0020.0002.2A49] # INTERSECTION ABOVE BAR ABOVE UNION +2A4A ; [*0B7A.0020.0002.2A4A] # UNION BESIDE AND JOINED WITH UNION +2A4B ; [*0B7B.0020.0002.2A4B] # INTERSECTION BESIDE AND JOINED WITH INTERSECTION +2A4C ; [*0B7C.0020.0002.2A4C] # CLOSED UNION WITH SERIFS +2A4D ; [*0B7D.0020.0002.2A4D] # CLOSED INTERSECTION WITH SERIFS +2A4E ; [*0B7E.0020.0002.2A4E] # DOUBLE SQUARE INTERSECTION +2A4F ; [*0B7F.0020.0002.2A4F] # DOUBLE SQUARE UNION +2A50 ; [*0B80.0020.0002.2A50] # CLOSED UNION WITH SERIFS AND SMASH PRODUCT +2A51 ; [*0B81.0020.0002.2A51] # LOGICAL AND WITH DOT ABOVE +2A52 ; [*0B82.0020.0002.2A52] # LOGICAL OR WITH DOT ABOVE +2A53 ; [*0B83.0020.0002.2A53] # DOUBLE LOGICAL AND +2A54 ; [*0B84.0020.0002.2A54] # DOUBLE LOGICAL OR +2A55 ; [*0B85.0020.0002.2A55] # TWO INTERSECTING LOGICAL AND +2A56 ; [*0B86.0020.0002.2A56] # TWO INTERSECTING LOGICAL OR +2A57 ; [*0B87.0020.0002.2A57] # SLOPING LARGE OR +2A58 ; [*0B88.0020.0002.2A58] # SLOPING LARGE AND +2A59 ; [*0B89.0020.0002.2A59] # LOGICAL OR OVERLAPPING LOGICAL AND +2A5A ; [*0B8A.0020.0002.2A5A] # LOGICAL AND WITH MIDDLE STEM +2A5B ; [*0B8B.0020.0002.2A5B] # LOGICAL OR WITH MIDDLE STEM +2A5C ; [*0B8C.0020.0002.2A5C] # LOGICAL AND WITH HORIZONTAL DASH +2A5D ; [*0B8D.0020.0002.2A5D] # LOGICAL OR WITH HORIZONTAL DASH +2A5E ; [*0B8E.0020.0002.2A5E] # LOGICAL AND WITH DOUBLE OVERBAR +2A5F ; [*0B8F.0020.0002.2A5F] # LOGICAL AND WITH UNDERBAR +2A60 ; [*0B90.0020.0002.2A60] # LOGICAL AND WITH DOUBLE UNDERBAR +2A61 ; [*0B91.0020.0002.2A61] # SMALL VEE WITH UNDERBAR +2A62 ; [*0B92.0020.0002.2A62] # LOGICAL OR WITH DOUBLE OVERBAR +2A63 ; [*0B93.0020.0002.2A63] # LOGICAL OR WITH DOUBLE UNDERBAR +2A64 ; [*0B94.0020.0002.2A64] # Z NOTATION DOMAIN ANTIRESTRICTION +2A65 ; [*0B95.0020.0002.2A65] # Z NOTATION RANGE ANTIRESTRICTION +2A66 ; [*0B96.0020.0002.2A66] # EQUALS SIGN WITH DOT BELOW +2A67 ; [*0B97.0020.0002.2A67] # IDENTICAL WITH DOT ABOVE +2A68 ; [*0B98.0020.0002.2A68] # TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE +2A69 ; [*0B99.0020.0002.2A69] # TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE +2A6A ; [*0B9A.0020.0002.2A6A] # TILDE OPERATOR WITH DOT ABOVE +2A6B ; [*0B9B.0020.0002.2A6B] # TILDE OPERATOR WITH RISING DOTS +2A6C ; [*0B9C.0020.0002.2A6C] # SIMILAR MINUS SIMILAR +2A6D ; [*0B9D.0020.0002.2A6D] # CONGRUENT WITH DOT ABOVE +2A6E ; [*0B9E.0020.0002.2A6E] # EQUALS WITH ASTERISK +2A6F ; [*0B9F.0020.0002.2A6F] # ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT +2A70 ; [*0BA0.0020.0002.2A70] # APPROXIMATELY EQUAL OR EQUAL TO +2A71 ; [*0BA1.0020.0002.2A71] # EQUALS SIGN ABOVE PLUS SIGN +2A72 ; [*0BA2.0020.0002.2A72] # PLUS SIGN ABOVE EQUALS SIGN +2A73 ; [*0BA3.0020.0002.2A73] # EQUALS SIGN ABOVE TILDE OPERATOR +2A74 ; [*0237.0020.0004.2A74][*0237.0020.0004.2A74][*05A1.0020.001F.2A74] # DOUBLE COLON EQUAL +2A75 ; [*05A1.0020.0004.2A75][*05A1.0020.0004.2A75] # TWO CONSECUTIVE EQUALS SIGNS +2A76 ; [*05A1.0020.0004.2A76][*05A1.0020.0004.2A76][*05A1.0020.001F.2A76] # THREE CONSECUTIVE EQUALS SIGNS +2A77 ; [*0BA4.0020.0002.2A77] # EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW +2A78 ; [*0BA5.0020.0002.2A78] # EQUIVALENT WITH FOUR DOTS ABOVE +2A79 ; [*0BA6.0020.0002.2A79] # LESS-THAN WITH CIRCLE INSIDE +2A7A ; [*0BA7.0020.0002.2A7A] # GREATER-THAN WITH CIRCLE INSIDE +2A7B ; [*0BA8.0020.0002.2A7B] # LESS-THAN WITH QUESTION MARK ABOVE +2A7C ; [*0BA9.0020.0002.2A7C] # GREATER-THAN WITH QUESTION MARK ABOVE +2A7D ; [*0BAA.0020.0002.2A7D] # LESS-THAN OR SLANTED EQUAL TO +2A7E ; [*0BAB.0020.0002.2A7E] # GREATER-THAN OR SLANTED EQUAL TO +2A7F ; [*0BAC.0020.0002.2A7F] # LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE +2A80 ; [*0BAD.0020.0002.2A80] # GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE +2A81 ; [*0BAE.0020.0002.2A81] # LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE +2A82 ; [*0BAF.0020.0002.2A82] # GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE +2A83 ; [*0BB0.0020.0002.2A83] # LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT +2A84 ; [*0BB1.0020.0002.2A84] # GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT +2A85 ; [*0BB2.0020.0002.2A85] # LESS-THAN OR APPROXIMATE +2A86 ; [*0BB3.0020.0002.2A86] # GREATER-THAN OR APPROXIMATE +2A87 ; [*0BB4.0020.0002.2A87] # LESS-THAN AND SINGLE-LINE NOT EQUAL TO +2A88 ; [*0BB5.0020.0002.2A88] # GREATER-THAN AND SINGLE-LINE NOT EQUAL TO +2A89 ; [*0BB6.0020.0002.2A89] # LESS-THAN AND NOT APPROXIMATE +2A8A ; [*0BB7.0020.0002.2A8A] # GREATER-THAN AND NOT APPROXIMATE +2A8B ; [*0BB8.0020.0002.2A8B] # LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN +2A8C ; [*0BB9.0020.0002.2A8C] # GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN +2A8D ; [*0BBA.0020.0002.2A8D] # LESS-THAN ABOVE SIMILAR OR EQUAL +2A8E ; [*0BBB.0020.0002.2A8E] # GREATER-THAN ABOVE SIMILAR OR EQUAL +2A8F ; [*0BBC.0020.0002.2A8F] # LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN +2A90 ; [*0BBD.0020.0002.2A90] # GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN +2A91 ; [*0BBE.0020.0002.2A91] # LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL +2A92 ; [*0BBF.0020.0002.2A92] # GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL +2A93 ; [*0BC0.0020.0002.2A93] # LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL +2A94 ; [*0BC1.0020.0002.2A94] # GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL +2A95 ; [*0BC2.0020.0002.2A95] # SLANTED EQUAL TO OR LESS-THAN +2A96 ; [*0BC3.0020.0002.2A96] # SLANTED EQUAL TO OR GREATER-THAN +2A97 ; [*0BC4.0020.0002.2A97] # SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE +2A98 ; [*0BC5.0020.0002.2A98] # SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE +2A99 ; [*0BC6.0020.0002.2A99] # DOUBLE-LINE EQUAL TO OR LESS-THAN +2A9A ; [*0BC7.0020.0002.2A9A] # DOUBLE-LINE EQUAL TO OR GREATER-THAN +2A9B ; [*0BC8.0020.0002.2A9B] # DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN +2A9C ; [*0BC9.0020.0002.2A9C] # DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN +2A9D ; [*0BCA.0020.0002.2A9D] # SIMILAR OR LESS-THAN +2A9E ; [*0BCB.0020.0002.2A9E] # SIMILAR OR GREATER-THAN +2A9F ; [*0BCC.0020.0002.2A9F] # SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN +2AA0 ; [*0BCD.0020.0002.2AA0] # SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN +2AA1 ; [*0BCE.0020.0002.2AA1] # DOUBLE NESTED LESS-THAN +2AA2 ; [*0BCF.0020.0002.2AA2] # DOUBLE NESTED GREATER-THAN +2AA3 ; [*0BD0.0020.0002.2AA3] # DOUBLE NESTED LESS-THAN WITH UNDERBAR +2AA4 ; [*0BD1.0020.0002.2AA4] # GREATER-THAN OVERLAPPING LESS-THAN +2AA5 ; [*0BD2.0020.0002.2AA5] # GREATER-THAN BESIDE LESS-THAN +2AA6 ; [*0BD3.0020.0002.2AA6] # LESS-THAN CLOSED BY CURVE +2AA7 ; [*0BD4.0020.0002.2AA7] # GREATER-THAN CLOSED BY CURVE +2AA8 ; [*0BD5.0020.0002.2AA8] # LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL +2AA9 ; [*0BD6.0020.0002.2AA9] # GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL +2AAA ; [*0BD7.0020.0002.2AAA] # SMALLER THAN +2AAB ; [*0BD8.0020.0002.2AAB] # LARGER THAN +2AAC ; [*0BD9.0020.0002.2AAC] # SMALLER THAN OR EQUAL TO +2AAD ; [*0BDA.0020.0002.2AAD] # LARGER THAN OR EQUAL TO +2AAE ; [*0BDB.0020.0002.2AAE] # EQUALS SIGN WITH BUMPY ABOVE +2AAF ; [*0BDC.0020.0002.2AAF] # PRECEDES ABOVE SINGLE-LINE EQUALS SIGN +2AB0 ; [*0BDD.0020.0002.2AB0] # SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN +2AB1 ; [*0BDE.0020.0002.2AB1] # PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO +2AB2 ; [*0BDF.0020.0002.2AB2] # SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO +2AB3 ; [*0BE0.0020.0002.2AB3] # PRECEDES ABOVE EQUALS SIGN +2AB4 ; [*0BE1.0020.0002.2AB4] # SUCCEEDS ABOVE EQUALS SIGN +2AB5 ; [*0BE2.0020.0002.2AB5] # PRECEDES ABOVE NOT EQUAL TO +2AB6 ; [*0BE3.0020.0002.2AB6] # SUCCEEDS ABOVE NOT EQUAL TO +2AB7 ; [*0BE4.0020.0002.2AB7] # PRECEDES ABOVE ALMOST EQUAL TO +2AB8 ; [*0BE5.0020.0002.2AB8] # SUCCEEDS ABOVE ALMOST EQUAL TO +2AB9 ; [*0BE6.0020.0002.2AB9] # PRECEDES ABOVE NOT ALMOST EQUAL TO +2ABA ; [*0BE7.0020.0002.2ABA] # SUCCEEDS ABOVE NOT ALMOST EQUAL TO +2ABB ; [*0BE8.0020.0002.2ABB] # DOUBLE PRECEDES +2ABC ; [*0BE9.0020.0002.2ABC] # DOUBLE SUCCEEDS +2ABD ; [*0BEA.0020.0002.2ABD] # SUBSET WITH DOT +2ABE ; [*0BEB.0020.0002.2ABE] # SUPERSET WITH DOT +2ABF ; [*0BEC.0020.0002.2ABF] # SUBSET WITH PLUS SIGN BELOW +2AC0 ; [*0BED.0020.0002.2AC0] # SUPERSET WITH PLUS SIGN BELOW +2AC1 ; [*0BEE.0020.0002.2AC1] # SUBSET WITH MULTIPLICATION SIGN BELOW +2AC2 ; [*0BEF.0020.0002.2AC2] # SUPERSET WITH MULTIPLICATION SIGN BELOW +2AC3 ; [*0BF0.0020.0002.2AC3] # SUBSET OF OR EQUAL TO WITH DOT ABOVE +2AC4 ; [*0BF1.0020.0002.2AC4] # SUPERSET OF OR EQUAL TO WITH DOT ABOVE +2AC5 ; [*0BF2.0020.0002.2AC5] # SUBSET OF ABOVE EQUALS SIGN +2AC6 ; [*0BF3.0020.0002.2AC6] # SUPERSET OF ABOVE EQUALS SIGN +2AC7 ; [*0BF4.0020.0002.2AC7] # SUBSET OF ABOVE TILDE OPERATOR +2AC8 ; [*0BF5.0020.0002.2AC8] # SUPERSET OF ABOVE TILDE OPERATOR +2AC9 ; [*0BF6.0020.0002.2AC9] # SUBSET OF ABOVE ALMOST EQUAL TO +2ACA ; [*0BF7.0020.0002.2ACA] # SUPERSET OF ABOVE ALMOST EQUAL TO +2ACB ; [*0BF8.0020.0002.2ACB] # SUBSET OF ABOVE NOT EQUAL TO +2ACC ; [*0BF9.0020.0002.2ACC] # SUPERSET OF ABOVE NOT EQUAL TO +2ACD ; [*0BFA.0020.0002.2ACD] # SQUARE LEFT OPEN BOX OPERATOR +2ACE ; [*0BFB.0020.0002.2ACE] # SQUARE RIGHT OPEN BOX OPERATOR +2ACF ; [*0BFC.0020.0002.2ACF] # CLOSED SUBSET +2AD0 ; [*0BFD.0020.0002.2AD0] # CLOSED SUPERSET +2AD1 ; [*0BFE.0020.0002.2AD1] # CLOSED SUBSET OR EQUAL TO +2AD2 ; [*0BFF.0020.0002.2AD2] # CLOSED SUPERSET OR EQUAL TO +2AD3 ; [*0C00.0020.0002.2AD3] # SUBSET ABOVE SUPERSET +2AD4 ; [*0C01.0020.0002.2AD4] # SUPERSET ABOVE SUBSET +2AD5 ; [*0C02.0020.0002.2AD5] # SUBSET ABOVE SUBSET +2AD6 ; [*0C03.0020.0002.2AD6] # SUPERSET ABOVE SUPERSET +2AD7 ; [*0C04.0020.0002.2AD7] # SUPERSET BESIDE SUBSET +2AD8 ; [*0C05.0020.0002.2AD8] # SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET +2AD9 ; [*0C06.0020.0002.2AD9] # ELEMENT OF OPENING DOWNWARDS +2ADA ; [*0C07.0020.0002.2ADA] # PITCHFORK WITH TEE TOP +2ADB ; [*0C08.0020.0002.2ADB] # TRANSVERSAL INTERSECTION +2ADC ; [*0C09.0020.0002.2ADD][.0000.0054.0002.0338] # FORKING +2ADD ; [*0C09.0020.0002.2ADD] # NONFORKING +2ADE ; [*0C0A.0020.0002.2ADE] # SHORT LEFT TACK +2ADF ; [*0C0B.0020.0002.2ADF] # SHORT DOWN TACK +2AE0 ; [*0C0C.0020.0002.2AE0] # SHORT UP TACK +2AE1 ; [*0C0D.0020.0002.2AE1] # PERPENDICULAR WITH S +2AE2 ; [*0C0E.0020.0002.2AE2] # VERTICAL BAR TRIPLE RIGHT TURNSTILE +2AE3 ; [*0C0F.0020.0002.2AE3] # DOUBLE VERTICAL BAR LEFT TURNSTILE +2AE4 ; [*0C10.0020.0002.2AE4] # VERTICAL BAR DOUBLE LEFT TURNSTILE +2AE5 ; [*0C11.0020.0002.2AE5] # DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE +2AE6 ; [*0C12.0020.0002.2AE6] # LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL +2AE7 ; [*0C13.0020.0002.2AE7] # SHORT DOWN TACK WITH OVERBAR +2AE8 ; [*0C14.0020.0002.2AE8] # SHORT UP TACK WITH UNDERBAR +2AE9 ; [*0C15.0020.0002.2AE9] # SHORT UP TACK ABOVE SHORT DOWN TACK +2AEA ; [*0C16.0020.0002.2AEA] # DOUBLE DOWN TACK +2AEB ; [*0C17.0020.0002.2AEB] # DOUBLE UP TACK +2AEC ; [*0C18.0020.0002.2AEC] # DOUBLE STROKE NOT SIGN +2AED ; [*0C19.0020.0002.2AED] # REVERSED DOUBLE STROKE NOT SIGN +2AEE ; [*0C1A.0020.0002.2AEE] # DOES NOT DIVIDE WITH REVERSED NEGATION SLASH +2AEF ; [*0C1B.0020.0002.2AEF] # VERTICAL LINE WITH CIRCLE ABOVE +2AF0 ; [*0C1C.0020.0002.2AF0] # VERTICAL LINE WITH CIRCLE BELOW +2AF1 ; [*0C1D.0020.0002.2AF1] # DOWN TACK WITH CIRCLE BELOW +2AF2 ; [*0C1E.0020.0002.2AF2] # PARALLEL WITH HORIZONTAL STROKE +2AF3 ; [*0C1F.0020.0002.2AF3] # PARALLEL WITH TILDE OPERATOR +2AF4 ; [*0C20.0020.0002.2AF4] # TRIPLE VERTICAL BAR BINARY RELATION +2AF5 ; [*0C21.0020.0002.2AF5] # TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE +2AF6 ; [*0C22.0020.0002.2AF6] # TRIPLE COLON OPERATOR +2AF7 ; [*0C23.0020.0002.2AF7] # TRIPLE NESTED LESS-THAN +2AF8 ; [*0C24.0020.0002.2AF8] # TRIPLE NESTED GREATER-THAN +2AF9 ; [*0C25.0020.0002.2AF9] # DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO +2AFA ; [*0C26.0020.0002.2AFA] # DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO +2AFB ; [*0C27.0020.0002.2AFB] # TRIPLE SOLIDUS BINARY RELATION +2AFC ; [*0C28.0020.0002.2AFC] # LARGE TRIPLE VERTICAL BAR OPERATOR +2AFD ; [*0C29.0020.0002.2AFD] # DOUBLE SOLIDUS OPERATOR +2AFE ; [*0C2A.0020.0002.2AFE] # WHITE VERTICAL BAR +2AFF ; [*0C2B.0020.0002.2AFF] # N-ARY WHITE VERTICAL BAR +2B00 ; [*0C2C.0020.0002.2B00] # NORTH EAST WHITE ARROW +2B01 ; [*0C2D.0020.0002.2B01] # NORTH WEST WHITE ARROW +2B02 ; [*0C2E.0020.0002.2B02] # SOUTH EAST WHITE ARROW +2B03 ; [*0C2F.0020.0002.2B03] # SOUTH WEST WHITE ARROW +2B04 ; [*0C30.0020.0002.2B04] # LEFT RIGHT WHITE ARROW +2B05 ; [*0C31.0020.0002.2B05] # LEFTWARDS BLACK ARROW +2B06 ; [*0C32.0020.0002.2B06] # UPWARDS BLACK ARROW +2B07 ; [*0C33.0020.0002.2B07] # DOWNWARDS BLACK ARROW +2B08 ; [*0C34.0020.0002.2B08] # NORTH EAST BLACK ARROW +2B09 ; [*0C35.0020.0002.2B09] # NORTH WEST BLACK ARROW +2B0A ; [*0C36.0020.0002.2B0A] # SOUTH EAST BLACK ARROW +2B0B ; [*0C37.0020.0002.2B0B] # SOUTH WEST BLACK ARROW +2B0C ; [*0C38.0020.0002.2B0C] # LEFT RIGHT BLACK ARROW +2B0D ; [*0C39.0020.0002.2B0D] # UP DOWN BLACK ARROW +2B0E ; [*0C3A.0020.0002.2B0E] # RIGHTWARDS ARROW WITH TIP DOWNWARDS +2B0F ; [*0C3B.0020.0002.2B0F] # RIGHTWARDS ARROW WITH TIP UPWARDS +2B10 ; [*0C3C.0020.0002.2B10] # LEFTWARDS ARROW WITH TIP DOWNWARDS +2B11 ; [*0C3D.0020.0002.2B11] # LEFTWARDS ARROW WITH TIP UPWARDS +2B12 ; [*0C3E.0020.0002.2B12] # SQUARE WITH TOP HALF BLACK +2B13 ; [*0C3F.0020.0002.2B13] # SQUARE WITH BOTTOM HALF BLACK +2B14 ; [*0C40.0020.0002.2B14] # SQUARE WITH UPPER RIGHT DIAGONAL HALF BLACK +2B15 ; [*0C41.0020.0002.2B15] # SQUARE WITH LOWER LEFT DIAGONAL HALF BLACK +2B16 ; [*0C42.0020.0002.2B16] # DIAMOND WITH LEFT HALF BLACK +2B17 ; [*0C43.0020.0002.2B17] # DIAMOND WITH RIGHT HALF BLACK +2B18 ; [*0C44.0020.0002.2B18] # DIAMOND WITH TOP HALF BLACK +2B19 ; [*0C45.0020.0002.2B19] # DIAMOND WITH BOTTOM HALF BLACK +2B1A ; [*0C46.0020.0002.2B1A] # DOTTED SQUARE +2B1B ; [*0C47.0020.0002.2B1B] # BLACK LARGE SQUARE +2B1C ; [*0C48.0020.0002.2B1C] # WHITE LARGE SQUARE +2B1D ; [*0C49.0020.0002.2B1D] # BLACK VERY SMALL SQUARE +2B1E ; [*0C4A.0020.0002.2B1E] # WHITE VERY SMALL SQUARE +2B1F ; [*0C4B.0020.0002.2B1F] # BLACK PENTAGON +2B20 ; [*0C4C.0020.0002.2B20] # WHITE PENTAGON +2B21 ; [*0C4D.0020.0002.2B21] # WHITE HEXAGON +2B22 ; [*0C4E.0020.0002.2B22] # BLACK HEXAGON +2B23 ; [*0C4F.0020.0002.2B23] # HORIZONTAL BLACK HEXAGON +2B24 ; [*0C50.0020.0002.2B24] # BLACK LARGE CIRCLE +2B25 ; [*0C51.0020.0002.2B25] # BLACK MEDIUM DIAMOND +2B26 ; [*0C52.0020.0002.2B26] # WHITE MEDIUM DIAMOND +2B27 ; [*0C53.0020.0002.2B27] # BLACK MEDIUM LOZENGE +2B28 ; [*0C54.0020.0002.2B28] # WHITE MEDIUM LOZENGE +2B29 ; [*0C55.0020.0002.2B29] # BLACK SMALL DIAMOND +2B2A ; [*0C56.0020.0002.2B2A] # BLACK SMALL LOZENGE +2B2B ; [*0C57.0020.0002.2B2B] # WHITE SMALL LOZENGE +2B2C ; [*0C58.0020.0002.2B2C] # BLACK HORIZONTAL ELLIPSE +2B2D ; [*0C59.0020.0002.2B2D] # WHITE HORIZONTAL ELLIPSE +2B2E ; [*0C5A.0020.0002.2B2E] # BLACK VERTICAL ELLIPSE +2B2F ; [*0C5B.0020.0002.2B2F] # WHITE VERTICAL ELLIPSE +2B30 ; [*0C5C.0020.0002.2B30] # LEFT ARROW WITH SMALL CIRCLE +2B31 ; [*0C5D.0020.0002.2B31] # THREE LEFTWARDS ARROWS +2B32 ; [*0C5E.0020.0002.2B32] # LEFT ARROW WITH CIRCLED PLUS +2B33 ; [*0C5F.0020.0002.2B33] # LONG LEFTWARDS SQUIGGLE ARROW +2B34 ; [*0C60.0020.0002.2B34] # LEFTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE +2B35 ; [*0C61.0020.0002.2B35] # LEFTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE +2B36 ; [*0C62.0020.0002.2B36] # LEFTWARDS TWO-HEADED ARROW FROM BAR +2B37 ; [*0C63.0020.0002.2B37] # LEFTWARDS TWO-HEADED TRIPLE DASH ARROW +2B38 ; [*0C64.0020.0002.2B38] # LEFTWARDS ARROW WITH DOTTED STEM +2B39 ; [*0C65.0020.0002.2B39] # LEFTWARDS ARROW WITH TAIL WITH VERTICAL STROKE +2B3A ; [*0C66.0020.0002.2B3A] # LEFTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE +2B3B ; [*0C67.0020.0002.2B3B] # LEFTWARDS TWO-HEADED ARROW WITH TAIL +2B3C ; [*0C68.0020.0002.2B3C] # LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE +2B3D ; [*0C69.0020.0002.2B3D] # LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE +2B3E ; [*0C6A.0020.0002.2B3E] # LEFTWARDS ARROW THROUGH X +2B3F ; [*0C6B.0020.0002.2B3F] # WAVE ARROW POINTING DIRECTLY LEFT +2B40 ; [*0C6C.0020.0002.2B40] # EQUALS SIGN ABOVE LEFTWARDS ARROW +2B41 ; [*0C6D.0020.0002.2B41] # REVERSE TILDE OPERATOR ABOVE LEFTWARDS ARROW +2B42 ; [*0C6E.0020.0002.2B42] # LEFTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO +2B43 ; [*0C6F.0020.0002.2B43] # RIGHTWARDS ARROW THROUGH GREATER-THAN +2B44 ; [*0C70.0020.0002.2B44] # RIGHTWARDS ARROW THROUGH SUPERSET +2B45 ; [*0C71.0020.0002.2B45] # LEFTWARDS QUADRUPLE ARROW +2B46 ; [*0C72.0020.0002.2B46] # RIGHTWARDS QUADRUPLE ARROW +2B47 ; [*0C73.0020.0002.2B47] # REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW +2B48 ; [*0C74.0020.0002.2B48] # RIGHTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO +2B49 ; [*0C75.0020.0002.2B49] # TILDE OPERATOR ABOVE LEFTWARDS ARROW +2B4A ; [*0C76.0020.0002.2B4A] # LEFTWARDS ARROW ABOVE ALMOST EQUAL TO +2B4B ; [*0C77.0020.0002.2B4B] # LEFTWARDS ARROW ABOVE REVERSE TILDE OPERATOR +2B4C ; [*0C78.0020.0002.2B4C] # RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR +2B50 ; [*0C79.0020.0002.2B50] # WHITE MEDIUM STAR +2B51 ; [*0C7A.0020.0002.2B51] # BLACK SMALL STAR +2B52 ; [*0C7B.0020.0002.2B52] # WHITE SMALL STAR +2B53 ; [*0C7C.0020.0002.2B53] # BLACK RIGHT-POINTING PENTAGON +2B54 ; [*0C7D.0020.0002.2B54] # WHITE RIGHT-POINTING PENTAGON +2B55 ; [*0C7E.0020.0002.2B55] # HEAVY LARGE CIRCLE +2B56 ; [*0C7F.0020.0002.2B56] # HEAVY OVAL WITH OVAL INSIDE +2B57 ; [*0C80.0020.0002.2B57] # HEAVY CIRCLE WITH CIRCLE INSIDE +2B58 ; [*0C81.0020.0002.2B58] # HEAVY CIRCLE +2B59 ; [*0C82.0020.0002.2B59] # HEAVY CIRCLED SALTIRE +2CE5 ; [*0C83.0020.0002.2CE5] # COPTIC SYMBOL MI RO +2CE6 ; [*0C84.0020.0002.2CE6] # COPTIC SYMBOL PI RO +2CE7 ; [*0C85.0020.0002.2CE7] # COPTIC SYMBOL STAUROS +2CE8 ; [*0C86.0020.0002.2CE8] # COPTIC SYMBOL TAU RO +2CE9 ; [*0C87.0020.0002.2CE9] # COPTIC SYMBOL KHI RO +2CEA ; [*0C88.0020.0002.2CEA] # COPTIC SYMBOL SHIMA SIMA +2CF9 ; [*027D.0020.0002.2CF9] # COPTIC OLD NUBIAN FULL STOP +2CFA ; [*026B.0020.0002.2CFA] # COPTIC OLD NUBIAN DIRECT QUESTION MARK +2CFB ; [*026C.0020.0002.2CFB] # COPTIC OLD NUBIAN INDIRECT QUESTION MARK +2CFC ; [*02DC.0020.0002.2CFC] # COPTIC OLD NUBIAN VERSE DIVIDER +2CFD ; [*1501.0020.0002.2CFD] # COPTIC FRACTION ONE HALF +2CFE ; [*027E.0020.0002.2CFE] # COPTIC FULL STOP +2CFF ; [*02DD.0020.0002.2CFF] # COPTIC MORPHOLOGICAL DIVIDER +2D70 ; [*03F4.0020.0002.2D70] # TIFINAGH SEPARATOR MARK +2D7F ; [.0000.0000.0000.2D7F] # TIFINAGH CONSONANT JOINER +2E00 ; [*0394.0020.0002.2E00] # RIGHT ANGLE SUBSTITUTION MARKER +2E01 ; [*0395.0020.0002.2E01] # RIGHT ANGLE DOTTED SUBSTITUTION MARKER +2E02 ; [*033B.0020.0002.2E02] # LEFT SUBSTITUTION BRACKET +2E03 ; [*033C.0020.0002.2E03] # RIGHT SUBSTITUTION BRACKET +2E04 ; [*033D.0020.0002.2E04] # LEFT DOTTED SUBSTITUTION BRACKET +2E05 ; [*033E.0020.0002.2E05] # RIGHT DOTTED SUBSTITUTION BRACKET +2E06 ; [*0396.0020.0002.2E06] # RAISED INTERPOLATION MARKER +2E07 ; [*0397.0020.0002.2E07] # RAISED DOTTED INTERPOLATION MARKER +2E08 ; [*0398.0020.0002.2E08] # DOTTED TRANSPOSITION MARKER +2E09 ; [*033F.0020.0002.2E09] # LEFT TRANSPOSITION BRACKET +2E0A ; [*0340.0020.0002.2E0A] # RIGHT TRANSPOSITION BRACKET +2E0B ; [*0399.0020.0002.2E0B] # RAISED SQUARE +2E0C ; [*0341.0020.0002.2E0C] # LEFT RAISED OMISSION BRACKET +2E0D ; [*0342.0020.0002.2E0D] # RIGHT RAISED OMISSION BRACKET +2E0E ; [*039A.0020.0002.2E0E] # EDITORIAL CORONIS +2E0F ; [*039B.0020.0002.2E0F] # PARAGRAPHOS +2E10 ; [*039C.0020.0002.2E10] # FORKED PARAGRAPHOS +2E11 ; [*039D.0020.0002.2E11] # REVERSED FORKED PARAGRAPHOS +2E12 ; [*039E.0020.0002.2E12] # HYPODIASTOLE +2E13 ; [*039F.0020.0002.2E13] # DOTTED OBELOS +2E14 ; [*03A0.0020.0002.2E14] # DOWNWARDS ANCORA +2E15 ; [*03A1.0020.0002.2E15] # UPWARDS ANCORA +2E16 ; [*03A2.0020.0002.2E16] # DOTTED RIGHT-POINTING ANGLE +2E17 ; [*021C.0020.0002.2E17] # DOUBLE OBLIQUE HYPHEN +2E18 ; [*0272.0020.0002.2E18] # INVERTED INTERROBANG +2E19 ; [*02DE.0020.0002.2E19] # PALM BRANCH +2E1A ; [*03A3.0020.0002.2E1A] # HYPHEN WITH DIAERESIS +2E1B ; [*03A4.0020.0002.2E1B] # TILDE WITH RING ABOVE +2E1C ; [*0343.0020.0002.2E1C] # LEFT LOW PARAPHRASE BRACKET +2E1D ; [*0344.0020.0002.2E1D] # RIGHT LOW PARAPHRASE BRACKET +2E1E ; [*03A5.0020.0002.2E1E] # TILDE WITH DOT ABOVE +2E1F ; [*03A6.0020.0002.2E1F] # TILDE WITH DOT BELOW +2E20 ; [*0345.0020.0002.2E20] # LEFT VERTICAL BAR WITH QUILL +2E21 ; [*0346.0020.0002.2E21] # RIGHT VERTICAL BAR WITH QUILL +2E22 ; [*0347.0020.0002.2E22] # TOP LEFT HALF BRACKET +2E23 ; [*0348.0020.0002.2E23] # TOP RIGHT HALF BRACKET +2E24 ; [*0349.0020.0002.2E24] # BOTTOM LEFT HALF BRACKET +2E25 ; [*034A.0020.0002.2E25] # BOTTOM RIGHT HALF BRACKET +2E26 ; [*034B.0020.0002.2E26] # LEFT SIDEWAYS U BRACKET +2E27 ; [*034C.0020.0002.2E27] # RIGHT SIDEWAYS U BRACKET +2E28 ; [*034D.0020.0002.2E28] # LEFT DOUBLE PARENTHESIS +2E29 ; [*034E.0020.0002.2E29] # RIGHT DOUBLE PARENTHESIS +2E2A ; [*02D8.0020.0002.2E2A] # TWO DOTS OVER ONE DOT PUNCTUATION +2E2B ; [*02D9.0020.0002.2E2B] # ONE DOT OVER TWO DOTS PUNCTUATION +2E2C ; [*02DA.0020.0002.2E2C] # SQUARED FOUR DOT PUNCTUATION +2E2D ; [*02DB.0020.0002.2E2D] # FIVE DOT MARK +2E2E ; [*0265.0020.0002.2E2E] # REVERSED QUESTION MARK +2E30 ; [*027F.0020.0002.2E30] # RING POINT +2E31 ; [*0285.0020.0002.2E31] # WORD SEPARATOR MIDDLE DOT +2E32 ; [*0223.0020.0002.2E32] # TURNED COMMA +2E33 ; [*0286.0020.0002.2E33] # RAISED DOT +2E34 ; [*0222.0020.0002.2E34] # RAISED COMMA +2E35 ; [*0235.0020.0002.2E35] # TURNED SEMICOLON +2E36 ; [*037F.0020.0002.2E36] # DAGGER WITH LEFT GUARD +2E37 ; [*0380.0020.0002.2E37] # DAGGER WITH RIGHT GUARD +2E38 ; [*0381.0020.0002.2E38] # TURNED DAGGER +2E39 ; [*0369.0020.0002.2E39] # TOP HALF SECTION SIGN +2E3A ; [*0219.0020.0002.2E3A] # TWO-EM DASH +2E3B ; [*021A.0020.0002.2E3B] # THREE-EM DASH +2FF0 ; [*1483.0020.0002.2FF0] # IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT +2FF1 ; [*1484.0020.0002.2FF1] # IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW +2FF2 ; [*1485.0020.0002.2FF2] # IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT +2FF3 ; [*1486.0020.0002.2FF3] # IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW +2FF4 ; [*1487.0020.0002.2FF4] # IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND +2FF5 ; [*1488.0020.0002.2FF5] # IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE +2FF6 ; [*1489.0020.0002.2FF6] # IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW +2FF7 ; [*148A.0020.0002.2FF7] # IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT +2FF8 ; [*148B.0020.0002.2FF8] # IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT +2FF9 ; [*148C.0020.0002.2FF9] # IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT +2FFA ; [*148D.0020.0002.2FFA] # IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT +2FFB ; [*148E.0020.0002.2FFB] # IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID +3000 ; [*020A.0020.0003.3000] # IDEOGRAPHIC SPACE +3001 ; [*022F.0020.0002.3001] # IDEOGRAPHIC COMMA +3002 ; [*0283.0020.0002.3002] # IDEOGRAPHIC FULL STOP +3003 ; [*038A.0020.0002.3003] # DITTO MARK +3004 ; [*14B3.0020.0002.3004] # JAPANESE INDUSTRIAL STANDARD SYMBOL +3008 ; [*034F.0020.0002.3008] # LEFT ANGLE BRACKET +3009 ; [*0350.0020.0002.3009] # RIGHT ANGLE BRACKET +300A ; [*0351.0020.0002.300A] # LEFT DOUBLE ANGLE BRACKET +300B ; [*0352.0020.0002.300B] # RIGHT DOUBLE ANGLE BRACKET +300C ; [*0353.0020.0002.300C] # LEFT CORNER BRACKET +300D ; [*0354.0020.0002.300D] # RIGHT CORNER BRACKET +300E ; [*0355.0020.0002.300E] # LEFT WHITE CORNER BRACKET +300F ; [*0356.0020.0002.300F] # RIGHT WHITE CORNER BRACKET +3010 ; [*0357.0020.0002.3010] # LEFT BLACK LENTICULAR BRACKET +3011 ; [*0358.0020.0002.3011] # RIGHT BLACK LENTICULAR BRACKET +3012 ; [*14B4.0020.0002.3012] # POSTAL MARK +3013 ; [*14B5.0020.0002.3013] # GETA MARK +3014 ; [*0359.0020.0002.3014] # LEFT TORTOISE SHELL BRACKET +3015 ; [*035A.0020.0002.3015] # RIGHT TORTOISE SHELL BRACKET +3016 ; [*035B.0020.0002.3016] # LEFT WHITE LENTICULAR BRACKET +3017 ; [*035C.0020.0002.3017] # RIGHT WHITE LENTICULAR BRACKET +3018 ; [*035D.0020.0002.3018] # LEFT WHITE TORTOISE SHELL BRACKET +3019 ; [*035E.0020.0002.3019] # RIGHT WHITE TORTOISE SHELL BRACKET +301A ; [*035F.0020.0002.301A] # LEFT WHITE SQUARE BRACKET +301B ; [*0360.0020.0002.301B] # RIGHT WHITE SQUARE BRACKET +301C ; [*021D.0020.0002.301C] # WAVE DASH +301D ; [*02F6.0020.0002.301D] # REVERSED DOUBLE PRIME QUOTATION MARK +301E ; [*02F7.0020.0002.301E] # DOUBLE PRIME QUOTATION MARK +301F ; [*02F8.0020.0002.301F] # LOW DOUBLE PRIME QUOTATION MARK +3020 ; [*14B6.0020.0002.3020] # POSTAL MARK FACE +3030 ; [*021E.0020.0002.3030] # WAVY DASH +3036 ; [*14B4.0020.0004.3036] # CIRCLED POSTAL MARK +3037 ; [*14B7.0020.0002.3037] # IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL +303D ; [*038B.0020.0002.303D] # PART ALTERNATION MARK +303E ; [*14B8.0020.0002.303E] # IDEOGRAPHIC VARIATION INDICATOR +303F ; [*14B9.0020.0002.303F] # IDEOGRAPHIC HALF FILL SPACE +309B ; [*041E.0020.0002.309B] # KATAKANA-HIRAGANA VOICED SOUND MARK +309C ; [*041F.0020.0002.309C] # KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK +30A0 ; [*021F.0020.0002.30A0] # KATAKANA-HIRAGANA DOUBLE HYPHEN +30FB ; [*0220.0020.0002.30FB] # KATAKANA MIDDLE DOT +3190 ; [*14BA.0020.0002.3190] # IDEOGRAPHIC ANNOTATION LINKING MARK +3191 ; [*14BB.0020.0002.3191] # IDEOGRAPHIC ANNOTATION REVERSE MARK +31C0 ; [*148F.0020.0002.31C0] # CJK STROKE T +31C1 ; [*1490.0020.0002.31C1] # CJK STROKE WG +31C2 ; [*1491.0020.0002.31C2] # CJK STROKE XG +31C3 ; [*1492.0020.0002.31C3] # CJK STROKE BXG +31C4 ; [*1493.0020.0002.31C4] # CJK STROKE SW +31C5 ; [*1494.0020.0002.31C5] # CJK STROKE HZZ +31C6 ; [*1495.0020.0002.31C6] # CJK STROKE HZG +31C7 ; [*1496.0020.0002.31C7] # CJK STROKE HP +31C8 ; [*1497.0020.0002.31C8] # CJK STROKE HZWG +31C9 ; [*1498.0020.0002.31C9] # CJK STROKE SZWG +31CA ; [*1499.0020.0002.31CA] # CJK STROKE HZT +31CB ; [*149A.0020.0002.31CB] # CJK STROKE HZZP +31CC ; [*149B.0020.0002.31CC] # CJK STROKE HPWG +31CD ; [*149C.0020.0002.31CD] # CJK STROKE HZW +31CE ; [*149D.0020.0002.31CE] # CJK STROKE HZZZ +31CF ; [*149E.0020.0002.31CF] # CJK STROKE N +31D0 ; [*149F.0020.0002.31D0] # CJK STROKE H +31D1 ; [*14A0.0020.0002.31D1] # CJK STROKE S +31D2 ; [*14A1.0020.0002.31D2] # CJK STROKE P +31D3 ; [*14A2.0020.0002.31D3] # CJK STROKE SP +31D4 ; [*14A3.0020.0002.31D4] # CJK STROKE D +31D5 ; [*14A4.0020.0002.31D5] # CJK STROKE HZ +31D6 ; [*14A5.0020.0002.31D6] # CJK STROKE HG +31D7 ; [*14A6.0020.0002.31D7] # CJK STROKE SZ +31D8 ; [*14A7.0020.0002.31D8] # CJK STROKE SWZ +31D9 ; [*14A8.0020.0002.31D9] # CJK STROKE ST +31DA ; [*14A9.0020.0002.31DA] # CJK STROKE SG +31DB ; [*14AA.0020.0002.31DB] # CJK STROKE PD +31DC ; [*14AB.0020.0002.31DC] # CJK STROKE PZ +31DD ; [*14AC.0020.0002.31DD] # CJK STROKE TN +31DE ; [*14AD.0020.0002.31DE] # CJK STROKE SZZ +31DF ; [*14AE.0020.0002.31DF] # CJK STROKE SWG +31E0 ; [*14AF.0020.0002.31E0] # CJK STROKE HXWG +31E1 ; [*14B0.0020.0002.31E1] # CJK STROKE HZZZG +31E2 ; [*14B1.0020.0002.31E2] # CJK STROKE PG +31E3 ; [*14B2.0020.0002.31E3] # CJK STROKE Q +327F ; [*14BC.0020.0002.327F] # KOREAN STANDARD SYMBOL +4DC0 ; [*0D97.0020.0002.4DC0] # HEXAGRAM FOR THE CREATIVE HEAVEN +4DC1 ; [*0D98.0020.0002.4DC1] # HEXAGRAM FOR THE RECEPTIVE EARTH +4DC2 ; [*0D99.0020.0002.4DC2] # HEXAGRAM FOR DIFFICULTY AT THE BEGINNING +4DC3 ; [*0D9A.0020.0002.4DC3] # HEXAGRAM FOR YOUTHFUL FOLLY +4DC4 ; [*0D9B.0020.0002.4DC4] # HEXAGRAM FOR WAITING +4DC5 ; [*0D9C.0020.0002.4DC5] # HEXAGRAM FOR CONFLICT +4DC6 ; [*0D9D.0020.0002.4DC6] # HEXAGRAM FOR THE ARMY +4DC7 ; [*0D9E.0020.0002.4DC7] # HEXAGRAM FOR HOLDING TOGETHER +4DC8 ; [*0D9F.0020.0002.4DC8] # HEXAGRAM FOR SMALL TAMING +4DC9 ; [*0DA0.0020.0002.4DC9] # HEXAGRAM FOR TREADING +4DCA ; [*0DA1.0020.0002.4DCA] # HEXAGRAM FOR PEACE +4DCB ; [*0DA2.0020.0002.4DCB] # HEXAGRAM FOR STANDSTILL +4DCC ; [*0DA3.0020.0002.4DCC] # HEXAGRAM FOR FELLOWSHIP +4DCD ; [*0DA4.0020.0002.4DCD] # HEXAGRAM FOR GREAT POSSESSION +4DCE ; [*0DA5.0020.0002.4DCE] # HEXAGRAM FOR MODESTY +4DCF ; [*0DA6.0020.0002.4DCF] # HEXAGRAM FOR ENTHUSIASM +4DD0 ; [*0DA7.0020.0002.4DD0] # HEXAGRAM FOR FOLLOWING +4DD1 ; [*0DA8.0020.0002.4DD1] # HEXAGRAM FOR WORK ON THE DECAYED +4DD2 ; [*0DA9.0020.0002.4DD2] # HEXAGRAM FOR APPROACH +4DD3 ; [*0DAA.0020.0002.4DD3] # HEXAGRAM FOR CONTEMPLATION +4DD4 ; [*0DAB.0020.0002.4DD4] # HEXAGRAM FOR BITING THROUGH +4DD5 ; [*0DAC.0020.0002.4DD5] # HEXAGRAM FOR GRACE +4DD6 ; [*0DAD.0020.0002.4DD6] # HEXAGRAM FOR SPLITTING APART +4DD7 ; [*0DAE.0020.0002.4DD7] # HEXAGRAM FOR RETURN +4DD8 ; [*0DAF.0020.0002.4DD8] # HEXAGRAM FOR INNOCENCE +4DD9 ; [*0DB0.0020.0002.4DD9] # HEXAGRAM FOR GREAT TAMING +4DDA ; [*0DB1.0020.0002.4DDA] # HEXAGRAM FOR MOUTH CORNERS +4DDB ; [*0DB2.0020.0002.4DDB] # HEXAGRAM FOR GREAT PREPONDERANCE +4DDC ; [*0DB3.0020.0002.4DDC] # HEXAGRAM FOR THE ABYSMAL WATER +4DDD ; [*0DB4.0020.0002.4DDD] # HEXAGRAM FOR THE CLINGING FIRE +4DDE ; [*0DB5.0020.0002.4DDE] # HEXAGRAM FOR INFLUENCE +4DDF ; [*0DB6.0020.0002.4DDF] # HEXAGRAM FOR DURATION +4DE0 ; [*0DB7.0020.0002.4DE0] # HEXAGRAM FOR RETREAT +4DE1 ; [*0DB8.0020.0002.4DE1] # HEXAGRAM FOR GREAT POWER +4DE2 ; [*0DB9.0020.0002.4DE2] # HEXAGRAM FOR PROGRESS +4DE3 ; [*0DBA.0020.0002.4DE3] # HEXAGRAM FOR DARKENING OF THE LIGHT +4DE4 ; [*0DBB.0020.0002.4DE4] # HEXAGRAM FOR THE FAMILY +4DE5 ; [*0DBC.0020.0002.4DE5] # HEXAGRAM FOR OPPOSITION +4DE6 ; [*0DBD.0020.0002.4DE6] # HEXAGRAM FOR OBSTRUCTION +4DE7 ; [*0DBE.0020.0002.4DE7] # HEXAGRAM FOR DELIVERANCE +4DE8 ; [*0DBF.0020.0002.4DE8] # HEXAGRAM FOR DECREASE +4DE9 ; [*0DC0.0020.0002.4DE9] # HEXAGRAM FOR INCREASE +4DEA ; [*0DC1.0020.0002.4DEA] # HEXAGRAM FOR BREAKTHROUGH +4DEB ; [*0DC2.0020.0002.4DEB] # HEXAGRAM FOR COMING TO MEET +4DEC ; [*0DC3.0020.0002.4DEC] # HEXAGRAM FOR GATHERING TOGETHER +4DED ; [*0DC4.0020.0002.4DED] # HEXAGRAM FOR PUSHING UPWARD +4DEE ; [*0DC5.0020.0002.4DEE] # HEXAGRAM FOR OPPRESSION +4DEF ; [*0DC6.0020.0002.4DEF] # HEXAGRAM FOR THE WELL +4DF0 ; [*0DC7.0020.0002.4DF0] # HEXAGRAM FOR REVOLUTION +4DF1 ; [*0DC8.0020.0002.4DF1] # HEXAGRAM FOR THE CAULDRON +4DF2 ; [*0DC9.0020.0002.4DF2] # HEXAGRAM FOR THE AROUSING THUNDER +4DF3 ; [*0DCA.0020.0002.4DF3] # HEXAGRAM FOR THE KEEPING STILL MOUNTAIN +4DF4 ; [*0DCB.0020.0002.4DF4] # HEXAGRAM FOR DEVELOPMENT +4DF5 ; [*0DCC.0020.0002.4DF5] # HEXAGRAM FOR THE MARRYING MAIDEN +4DF6 ; [*0DCD.0020.0002.4DF6] # HEXAGRAM FOR ABUNDANCE +4DF7 ; [*0DCE.0020.0002.4DF7] # HEXAGRAM FOR THE WANDERER +4DF8 ; [*0DCF.0020.0002.4DF8] # HEXAGRAM FOR THE GENTLE WIND +4DF9 ; [*0DD0.0020.0002.4DF9] # HEXAGRAM FOR THE JOYOUS LAKE +4DFA ; [*0DD1.0020.0002.4DFA] # HEXAGRAM FOR DISPERSION +4DFB ; [*0DD2.0020.0002.4DFB] # HEXAGRAM FOR LIMITATION +4DFC ; [*0DD3.0020.0002.4DFC] # HEXAGRAM FOR INNER TRUTH +4DFD ; [*0DD4.0020.0002.4DFD] # HEXAGRAM FOR SMALL PREPONDERANCE +4DFE ; [*0DD5.0020.0002.4DFE] # HEXAGRAM FOR AFTER COMPLETION +4DFF ; [*0DD6.0020.0002.4DFF] # HEXAGRAM FOR BEFORE COMPLETION +A490 ; [*0E2E.0020.0002.A490] # YI RADICAL QOT +A491 ; [*0E2F.0020.0002.A491] # YI RADICAL LI +A492 ; [*0E30.0020.0002.A492] # YI RADICAL KIT +A493 ; [*0E31.0020.0002.A493] # YI RADICAL NYIP +A494 ; [*0E32.0020.0002.A494] # YI RADICAL CYP +A495 ; [*0E33.0020.0002.A495] # YI RADICAL SSI +A496 ; [*0E34.0020.0002.A496] # YI RADICAL GGOP +A497 ; [*0E35.0020.0002.A497] # YI RADICAL GEP +A498 ; [*0E36.0020.0002.A498] # YI RADICAL MI +A499 ; [*0E37.0020.0002.A499] # YI RADICAL HXIT +A49A ; [*0E38.0020.0002.A49A] # YI RADICAL LYR +A49B ; [*0E39.0020.0002.A49B] # YI RADICAL BBUT +A49C ; [*0E3A.0020.0002.A49C] # YI RADICAL MOP +A49D ; [*0E3B.0020.0002.A49D] # YI RADICAL YO +A49E ; [*0E3C.0020.0002.A49E] # YI RADICAL PUT +A49F ; [*0E3D.0020.0002.A49F] # YI RADICAL HXUO +A4A0 ; [*0E3E.0020.0002.A4A0] # YI RADICAL TAT +A4A1 ; [*0E3F.0020.0002.A4A1] # YI RADICAL GA +A4A2 ; [*0E40.0020.0002.A4A2] # YI RADICAL ZUP +A4A3 ; [*0E41.0020.0002.A4A3] # YI RADICAL CYT +A4A4 ; [*0E42.0020.0002.A4A4] # YI RADICAL DDUR +A4A5 ; [*0E43.0020.0002.A4A5] # YI RADICAL BUR +A4A6 ; [*0E44.0020.0002.A4A6] # YI RADICAL GGUO +A4A7 ; [*0E45.0020.0002.A4A7] # YI RADICAL NYOP +A4A8 ; [*0E46.0020.0002.A4A8] # YI RADICAL TU +A4A9 ; [*0E47.0020.0002.A4A9] # YI RADICAL OP +A4AA ; [*0E48.0020.0002.A4AA] # YI RADICAL JJUT +A4AB ; [*0E49.0020.0002.A4AB] # YI RADICAL ZOT +A4AC ; [*0E4A.0020.0002.A4AC] # YI RADICAL PYT +A4AD ; [*0E4B.0020.0002.A4AD] # YI RADICAL HMO +A4AE ; [*0E4C.0020.0002.A4AE] # YI RADICAL YIT +A4AF ; [*0E4D.0020.0002.A4AF] # YI RADICAL VUR +A4B0 ; [*0E4E.0020.0002.A4B0] # YI RADICAL SHY +A4B1 ; [*0E4F.0020.0002.A4B1] # YI RADICAL VEP +A4B2 ; [*0E50.0020.0002.A4B2] # YI RADICAL ZA +A4B3 ; [*0E51.0020.0002.A4B3] # YI RADICAL JO +A4B4 ; [*0E52.0020.0002.A4B4] # YI RADICAL NZUP +A4B5 ; [*0E53.0020.0002.A4B5] # YI RADICAL JJY +A4B6 ; [*0E54.0020.0002.A4B6] # YI RADICAL GOT +A4B7 ; [*0E55.0020.0002.A4B7] # YI RADICAL JJIE +A4B8 ; [*0E56.0020.0002.A4B8] # YI RADICAL WO +A4B9 ; [*0E57.0020.0002.A4B9] # YI RADICAL DU +A4BA ; [*0E58.0020.0002.A4BA] # YI RADICAL SHUR +A4BB ; [*0E59.0020.0002.A4BB] # YI RADICAL LIE +A4BC ; [*0E5A.0020.0002.A4BC] # YI RADICAL CY +A4BD ; [*0E5B.0020.0002.A4BD] # YI RADICAL CUOP +A4BE ; [*0E5C.0020.0002.A4BE] # YI RADICAL CIP +A4BF ; [*0E5D.0020.0002.A4BF] # YI RADICAL HXOP +A4C0 ; [*0E5E.0020.0002.A4C0] # YI RADICAL SHAT +A4C1 ; [*0E5F.0020.0002.A4C1] # YI RADICAL ZUR +A4C2 ; [*0E60.0020.0002.A4C2] # YI RADICAL SHOP +A4C3 ; [*0E61.0020.0002.A4C3] # YI RADICAL CHE +A4C4 ; [*0E62.0020.0002.A4C4] # YI RADICAL ZZIET +A4C5 ; [*0E63.0020.0002.A4C5] # YI RADICAL NBIE +A4C6 ; [*0E64.0020.0002.A4C6] # YI RADICAL KE +A4FE ; [*022C.0020.0002.A4FE] # LISU PUNCTUATION COMMA +A4FF ; [*0280.0020.0002.A4FF] # LISU PUNCTUATION FULL STOP +A60D ; [*022D.0020.0002.A60D] # VAI COMMA +A60E ; [*0281.0020.0002.A60E] # VAI FULL STOP +A60F ; [*026D.0020.0002.A60F] # VAI QUESTION MARK +A670 ; [.0000.0000.0000.A670] # COMBINING CYRILLIC TEN MILLIONS SIGN +A671 ; [.0000.0000.0000.A671] # COMBINING CYRILLIC HUNDRED MILLIONS SIGN +A672 ; [.0000.0000.0000.A672] # COMBINING CYRILLIC THOUSAND MILLIONS SIGN +A673 ; [*0371.0020.0002.A673] # SLAVONIC ASTERISK +A67E ; [*03A7.0020.0002.A67E] # CYRILLIC KAVYKA +A6F2 ; [*02C2.0020.0002.A6F2] # BAMUM NJAEMLI +A6F3 ; [*0282.0020.0002.A6F3] # BAMUM FULL STOP +A6F4 ; [*025D.0020.0002.A6F4] # BAMUM COLON +A6F5 ; [*022E.0020.0002.A6F5] # BAMUM COMMA +A6F6 ; [*0236.0020.0002.A6F6] # BAMUM SEMICOLON +A6F7 ; [*026E.0020.0002.A6F7] # BAMUM QUESTION MARK +A700 ; [*045D.0020.0002.A700] # MODIFIER LETTER CHINESE TONE YIN PING +A701 ; [*045E.0020.0002.A701] # MODIFIER LETTER CHINESE TONE YANG PING +A702 ; [*045F.0020.0002.A702] # MODIFIER LETTER CHINESE TONE YIN SHANG +A703 ; [*0460.0020.0002.A703] # MODIFIER LETTER CHINESE TONE YANG SHANG +A704 ; [*0461.0020.0002.A704] # MODIFIER LETTER CHINESE TONE YIN QU +A705 ; [*0462.0020.0002.A705] # MODIFIER LETTER CHINESE TONE YANG QU +A706 ; [*0463.0020.0002.A706] # MODIFIER LETTER CHINESE TONE YIN RU +A707 ; [*0464.0020.0002.A707] # MODIFIER LETTER CHINESE TONE YANG RU +A708 ; [*0465.0020.0002.A708] # MODIFIER LETTER EXTRA-HIGH DOTTED TONE BAR +A709 ; [*0466.0020.0002.A709] # MODIFIER LETTER HIGH DOTTED TONE BAR +A70A ; [*0467.0020.0002.A70A] # MODIFIER LETTER MID DOTTED TONE BAR +A70B ; [*0468.0020.0002.A70B] # MODIFIER LETTER LOW DOTTED TONE BAR +A70C ; [*0469.0020.0002.A70C] # MODIFIER LETTER EXTRA-LOW DOTTED TONE BAR +A70D ; [*046A.0020.0002.A70D] # MODIFIER LETTER EXTRA-HIGH DOTTED LEFT-STEM TONE BAR +A70E ; [*046B.0020.0002.A70E] # MODIFIER LETTER HIGH DOTTED LEFT-STEM TONE BAR +A70F ; [*046C.0020.0002.A70F] # MODIFIER LETTER MID DOTTED LEFT-STEM TONE BAR +A710 ; [*046D.0020.0002.A710] # MODIFIER LETTER LOW DOTTED LEFT-STEM TONE BAR +A711 ; [*046E.0020.0002.A711] # MODIFIER LETTER EXTRA-LOW DOTTED LEFT-STEM TONE BAR +A712 ; [*046F.0020.0002.A712] # MODIFIER LETTER EXTRA-HIGH LEFT-STEM TONE BAR +A713 ; [*0470.0020.0002.A713] # MODIFIER LETTER HIGH LEFT-STEM TONE BAR +A714 ; [*0471.0020.0002.A714] # MODIFIER LETTER MID LEFT-STEM TONE BAR +A715 ; [*0472.0020.0002.A715] # MODIFIER LETTER LOW LEFT-STEM TONE BAR +A716 ; [*0473.0020.0002.A716] # MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR +A717 ; [*0474.0020.0002.A717] # MODIFIER LETTER DOT VERTICAL BAR +A718 ; [*0475.0020.0002.A718] # MODIFIER LETTER DOT SLASH +A719 ; [*0476.0020.0002.A719] # MODIFIER LETTER DOT HORIZONTAL BAR +A71A ; [*0477.0020.0002.A71A] # MODIFIER LETTER LOWER RIGHT CORNER ANGLE +A71B ; [*0478.0020.0002.A71B] # MODIFIER LETTER RAISED UP ARROW +A71C ; [*0479.0020.0002.A71C] # MODIFIER LETTER RAISED DOWN ARROW +A71D ; [*047A.0020.0002.A71D] # MODIFIER LETTER RAISED EXCLAMATION MARK +A71E ; [*047B.0020.0002.A71E] # MODIFIER LETTER RAISED INVERTED EXCLAMATION MARK +A71F ; [*047C.0020.0002.A71F] # MODIFIER LETTER LOW INVERTED EXCLAMATION MARK +A720 ; [*047D.0020.0002.A720] # MODIFIER LETTER STRESS AND HIGH TONE +A721 ; [*047E.0020.0002.A721] # MODIFIER LETTER STRESS AND LOW TONE +A788 ; [*047F.0020.0002.A788] # MODIFIER LETTER LOW CIRCUMFLEX ACCENT +A789 ; [*0480.0020.0002.A789] # MODIFIER LETTER COLON +A78A ; [*0481.0020.0002.A78A] # MODIFIER LETTER SHORT EQUALS SIGN +A828 ; [*04A8.0020.0002.A828] # SYLOTI NAGRI POETRY MARK-1 +A829 ; [*04A9.0020.0002.A829] # SYLOTI NAGRI POETRY MARK-2 +A82A ; [*04AA.0020.0002.A82A] # SYLOTI NAGRI POETRY MARK-3 +A82B ; [*04AB.0020.0002.A82B] # SYLOTI NAGRI POETRY MARK-4 +A830 ; [*14CB.0020.0002.A830] # NORTH INDIC FRACTION ONE QUARTER +A831 ; [*14CC.0020.0002.A831] # NORTH INDIC FRACTION ONE HALF +A832 ; [*14CD.0020.0002.A832] # NORTH INDIC FRACTION THREE QUARTERS +A833 ; [*14CE.0020.0002.A833] # NORTH INDIC FRACTION ONE SIXTEENTH +A834 ; [*14CF.0020.0002.A834] # NORTH INDIC FRACTION ONE EIGHTH +A835 ; [*14D0.0020.0002.A835] # NORTH INDIC FRACTION THREE SIXTEENTHS +A836 ; [*04AC.0020.0002.A836] # NORTH INDIC QUARTER MARK +A837 ; [*04AD.0020.0002.A837] # NORTH INDIC PLACEHOLDER MARK +A839 ; [*04AE.0020.0002.A839] # NORTH INDIC QUANTITY MARK +A874 ; [*03F5.0020.0002.A874] # PHAGS-PA SINGLE HEAD MARK +A875 ; [*03F6.0020.0002.A875] # PHAGS-PA DOUBLE HEAD MARK +A876 ; [*028D.0020.0002.A876] # PHAGS-PA MARK SHAD +A877 ; [*028E.0020.0002.A877] # PHAGS-PA MARK DOUBLE SHAD +A8CE ; [*0289.0020.0002.A8CE] # SAURASHTRA DANDA +A8CF ; [*028A.0020.0002.A8CF] # SAURASHTRA DOUBLE DANDA +A8E0 ; [.0000.0000.0000.A8E0] # COMBINING DEVANAGARI DIGIT ZERO +A8E1 ; [.0000.0000.0000.A8E1] # COMBINING DEVANAGARI DIGIT ONE +A8E2 ; [.0000.0000.0000.A8E2] # COMBINING DEVANAGARI DIGIT TWO +A8E3 ; [.0000.0000.0000.A8E3] # COMBINING DEVANAGARI DIGIT THREE +A8E4 ; [.0000.0000.0000.A8E4] # COMBINING DEVANAGARI DIGIT FOUR +A8E5 ; [.0000.0000.0000.A8E5] # COMBINING DEVANAGARI DIGIT FIVE +A8E6 ; [.0000.0000.0000.A8E6] # COMBINING DEVANAGARI DIGIT SIX +A8E7 ; [.0000.0000.0000.A8E7] # COMBINING DEVANAGARI DIGIT SEVEN +A8E8 ; [.0000.0000.0000.A8E8] # COMBINING DEVANAGARI DIGIT EIGHT +A8E9 ; [.0000.0000.0000.A8E9] # COMBINING DEVANAGARI DIGIT NINE +A8EA ; [.0000.0000.0000.A8EA] # COMBINING DEVANAGARI LETTER A +A8EB ; [.0000.0000.0000.A8EB] # COMBINING DEVANAGARI LETTER U +A8EC ; [.0000.0000.0000.A8EC] # COMBINING DEVANAGARI LETTER KA +A8ED ; [.0000.0000.0000.A8ED] # COMBINING DEVANAGARI LETTER NA +A8EE ; [.0000.0000.0000.A8EE] # COMBINING DEVANAGARI LETTER PA +A8EF ; [.0000.0000.0000.A8EF] # COMBINING DEVANAGARI LETTER RA +A8F0 ; [.0000.0000.0000.A8F0] # COMBINING DEVANAGARI LETTER VI +A8F1 ; [.0000.0000.0000.A8F1] # COMBINING DEVANAGARI SIGN AVAGRAHA +A8F8 ; [*03B8.0020.0002.A8F8] # DEVANAGARI SIGN PUSHPIKA +A8F9 ; [*03B9.0020.0002.A8F9] # DEVANAGARI GAP FILLER +A8FA ; [*03BA.0020.0002.A8FA] # DEVANAGARI CARET +A92E ; [*03FB.0020.0002.A92E] # KAYAH LI SIGN CWI +A92F ; [*0291.0020.0002.A92F] # KAYAH LI SIGN SHYA +A95F ; [*02C3.0020.0002.A95F] # REJANG SECTION MARK +A9C1 ; [*02B8.0020.0002.A9C1] # JAVANESE LEFT RERENGGAN +A9C2 ; [*02B9.0020.0002.A9C2] # JAVANESE RIGHT RERENGGAN +A9C3 ; [*02BA.0020.0002.A9C3] # JAVANESE PADA ANDAP +A9C4 ; [*02BB.0020.0002.A9C4] # JAVANESE PADA MADYA +A9C5 ; [*02BC.0020.0002.A9C5] # JAVANESE PADA LUHUR +A9C6 ; [*02BD.0020.0002.A9C6] # JAVANESE PADA WINDU +A9C7 ; [*0259.0020.0002.A9C7] # JAVANESE PADA PANGKAT +A9C8 ; [*029C.0020.0002.A9C8] # JAVANESE PADA LINGSA +A9C9 ; [*029D.0020.0002.A9C9] # JAVANESE PADA LUNGSI +A9CA ; [*02BE.0020.0002.A9CA] # JAVANESE PADA ADEG +A9CB ; [*02BF.0020.0002.A9CB] # JAVANESE PADA ADEG ADEG +A9CC ; [*02C0.0020.0002.A9CC] # JAVANESE PADA PISELEH +A9CD ; [*02C1.0020.0002.A9CD] # JAVANESE TURNED PADA PISELEH +A9DE ; [*03FC.0020.0002.A9DE] # JAVANESE PADA TIRTA TUMETES +A9DF ; [*03FD.0020.0002.A9DF] # JAVANESE PADA ISEN-ISEN +AA5C ; [*03FE.0020.0002.AA5C] # CHAM PUNCTUATION SPIRAL +AA5D ; [*029E.0020.0002.AA5D] # CHAM PUNCTUATION DANDA +AA5E ; [*029F.0020.0002.AA5E] # CHAM PUNCTUATION DOUBLE DANDA +AA5F ; [*02A0.0020.0002.AA5F] # CHAM PUNCTUATION TRIPLE DANDA +AA77 ; [*04D6.0020.0002.AA77] # MYANMAR SYMBOL AITON EXCLAMATION +AA78 ; [*04D7.0020.0002.AA78] # MYANMAR SYMBOL AITON ONE +AA79 ; [*04D8.0020.0002.AA79] # MYANMAR SYMBOL AITON TWO +AADE ; [*03C0.0020.0002.AADE] # TAI VIET SYMBOL HO HOI +AADF ; [*03C1.0020.0002.AADF] # TAI VIET SYMBOL KOI KOI +AAF0 ; [*02A1.0020.0002.AAF0] # MEETEI MAYEK CHEIKHAN +AAF1 ; [*026F.0020.0002.AAF1] # MEETEI MAYEK AHANG KHUDAM +ABEB ; [*02A2.0020.0002.ABEB] # MEETEI MAYEK CHEIKHEI +FB29 ; [*059C.0020.0005.FB29] # HEBREW LETTER ALTERNATIVE PLUS SIGN +FBB2 ; [*048C.0020.0002.FBB2] # ARABIC SYMBOL DOT ABOVE +FBB3 ; [*048D.0020.0002.FBB3] # ARABIC SYMBOL DOT BELOW +FBB4 ; [*048E.0020.0002.FBB4] # ARABIC SYMBOL TWO DOTS ABOVE +FBB5 ; [*048F.0020.0002.FBB5] # ARABIC SYMBOL TWO DOTS BELOW +FBB6 ; [*0490.0020.0002.FBB6] # ARABIC SYMBOL THREE DOTS ABOVE +FBB7 ; [*0491.0020.0002.FBB7] # ARABIC SYMBOL THREE DOTS BELOW +FBB8 ; [*0492.0020.0002.FBB8] # ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS ABOVE +FBB9 ; [*0493.0020.0002.FBB9] # ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS BELOW +FBBA ; [*0494.0020.0002.FBBA] # ARABIC SYMBOL FOUR DOTS ABOVE +FBBB ; [*0495.0020.0002.FBBB] # ARABIC SYMBOL FOUR DOTS BELOW +FBBC ; [*0496.0020.0002.FBBC] # ARABIC SYMBOL DOUBLE VERTICAL BAR BELOW +FBBD ; [*0497.0020.0002.FBBD] # ARABIC SYMBOL TWO DOTS VERTICALLY ABOVE +FBBE ; [*0498.0020.0002.FBBE] # ARABIC SYMBOL TWO DOTS VERTICALLY BELOW +FBBF ; [*0499.0020.0002.FBBF] # ARABIC SYMBOL RING +FBC0 ; [*049A.0020.0002.FBC0] # ARABIC SYMBOL SMALL TAH ABOVE +FBC1 ; [*049B.0020.0002.FBC1] # ARABIC SYMBOL SMALL TAH BELOW +FD3E ; [*0361.0020.0002.FD3E] # ORNATE LEFT PARENTHESIS +FD3F ; [*0362.0020.0002.FD3F] # ORNATE RIGHT PARENTHESIS +FDFD ; [*048B.0020.0002.FDFD] # ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM +FE10 ; [*0221.0020.0016.FE10] # PRESENTATION FORM FOR VERTICAL COMMA +FE11 ; [*022F.0020.0016.FE11] # PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA +FE12 ; [*0283.0020.0016.FE12] # PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP +FE13 ; [*0237.0020.0016.FE13] # PRESENTATION FORM FOR VERTICAL COLON +FE14 ; [*0232.0020.0016.FE14] # PRESENTATION FORM FOR VERTICAL SEMICOLON +FE15 ; [*025E.0020.0016.FE15] # PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK +FE16 ; [*0263.0020.0016.FE16] # PRESENTATION FORM FOR VERTICAL QUESTION MARK +FE17 ; [*035B.0020.0016.FE17] # PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET +FE18 ; [*035C.0020.0016.FE18] # PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET +FE19 ; [*0273.0020.0016.FE19][*0273.0020.0016.FE19][*0273.0020.001F.FE19] # PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS +FE21 ; [.0000.0000.0000.FE21] # COMBINING LIGATURE RIGHT HALF +FE23 ; [.0000.0000.0000.FE23] # COMBINING DOUBLE TILDE RIGHT HALF +FE24 ; [.0000.0000.0000.FE24] # COMBINING MACRON LEFT HALF +FE25 ; [.0000.0000.0000.FE25] # COMBINING MACRON RIGHT HALF +FE26 ; [.0000.0000.0000.FE26] # COMBINING CONJOINING MACRON +FE30 ; [*0273.0020.0016.FE30][*0273.0020.0016.FE30] # PRESENTATION FORM FOR VERTICAL TWO DOT LEADER +FE31 ; [*0217.0020.0016.FE31] # PRESENTATION FORM FOR VERTICAL EM DASH +FE32 ; [*0216.0020.0016.FE32] # PRESENTATION FORM FOR VERTICAL EN DASH +FE33 ; [*020C.0020.0016.FE33] # PRESENTATION FORM FOR VERTICAL LOW LINE +FE34 ; [*020C.0020.0016.FE34] # PRESENTATION FORM FOR VERTICAL WAVY LOW LINE +FE35 ; [*02FB.0020.0016.FE35] # PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS +FE36 ; [*02FC.0020.0016.FE36] # PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS +FE37 ; [*02FF.0020.0016.FE37] # PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET +FE38 ; [*0300.0020.0016.FE38] # PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET +FE39 ; [*0359.0020.0016.FE39] # PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET +FE3A ; [*035A.0020.0016.FE3A] # PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET +FE3B ; [*0357.0020.0016.FE3B] # PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET +FE3C ; [*0358.0020.0016.FE3C] # PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET +FE3D ; [*0351.0020.0016.FE3D] # PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET +FE3E ; [*0352.0020.0016.FE3E] # PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET +FE3F ; [*034F.0020.0016.FE3F] # PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET +FE40 ; [*0350.0020.0016.FE40] # PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET +FE41 ; [*0353.0020.0016.FE41] # PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET +FE42 ; [*0354.0020.0016.FE42] # PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET +FE43 ; [*0355.0020.0016.FE43] # PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET +FE44 ; [*0356.0020.0016.FE44] # PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET +FE45 ; [*0230.0020.0002.FE45] # SESAME DOT +FE46 ; [*0231.0020.0002.FE46] # WHITE SESAME DOT +FE47 ; [*02FD.0020.0016.FE47] # PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET +FE48 ; [*02FE.0020.0016.FE48] # PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET +FE49 ; [*020B.0020.0004.FE49] # DASHED OVERLINE +FE4A ; [*020B.0020.0004.FE4A] # CENTRELINE OVERLINE +FE4B ; [*020B.0020.0004.FE4B] # WAVY OVERLINE +FE4C ; [*020B.0020.0004.FE4C] # DOUBLE WAVY OVERLINE +FE4D ; [*020C.0020.0004.FE4D] # DASHED LOW LINE +FE4E ; [*020C.0020.0004.FE4E] # CENTRELINE LOW LINE +FE4F ; [*020C.0020.0004.FE4F] # WAVY LOW LINE +FE50 ; [*0221.0020.000F.FE50] # SMALL COMMA +FE51 ; [*022F.0020.000F.FE51] # SMALL IDEOGRAPHIC COMMA +FE52 ; [*0273.0020.000F.FE52] # SMALL FULL STOP +FE54 ; [*0232.0020.000F.FE54] # SMALL SEMICOLON +FE55 ; [*0237.0020.000F.FE55] # SMALL COLON +FE56 ; [*0263.0020.000F.FE56] # SMALL QUESTION MARK +FE57 ; [*025E.0020.000F.FE57] # SMALL EXCLAMATION MARK +FE58 ; [*0217.0020.000F.FE58] # SMALL EM DASH +FE59 ; [*02FB.0020.000F.FE59] # SMALL LEFT PARENTHESIS +FE5A ; [*02FC.0020.000F.FE5A] # SMALL RIGHT PARENTHESIS +FE5B ; [*02FF.0020.000F.FE5B] # SMALL LEFT CURLY BRACKET +FE5C ; [*0300.0020.000F.FE5C] # SMALL RIGHT CURLY BRACKET +FE5D ; [*0359.0020.000F.FE5D] # SMALL LEFT TORTOISE SHELL BRACKET +FE5E ; [*035A.0020.000F.FE5E] # SMALL RIGHT TORTOISE SHELL BRACKET +FE5F ; [*0376.0020.000F.FE5F] # SMALL NUMBER SIGN +FE60 ; [*0374.0020.000F.FE60] # SMALL AMPERSAND +FE61 ; [*036D.0020.000F.FE61] # SMALL ASTERISK +FE62 ; [*059C.0020.000F.FE62] # SMALL PLUS SIGN +FE63 ; [*020E.0020.000F.FE63] # SMALL HYPHEN-MINUS +FE64 ; [*05A0.0020.000F.FE64] # SMALL LESS-THAN SIGN +FE65 ; [*05A2.0020.000F.FE65] # SMALL GREATER-THAN SIGN +FE66 ; [*05A1.0020.000F.FE66] # SMALL EQUALS SIGN +FE68 ; [*0373.0020.000F.FE68] # SMALL REVERSE SOLIDUS +FE6A ; [*0377.0020.000F.FE6A] # SMALL PERCENT SIGN +FE6B ; [*036C.0020.000F.FE6B] # SMALL COMMERCIAL AT +FE73 ; [.0000.0000.0000.FE73] # ARABIC TAIL FRAGMENT +FF01 ; [*025E.0020.0003.FF01] # FULLWIDTH EXCLAMATION MARK +FF02 ; [*02F1.0020.0003.FF02] # FULLWIDTH QUOTATION MARK +FF03 ; [*0376.0020.0003.FF03] # FULLWIDTH NUMBER SIGN +FF05 ; [*0377.0020.0003.FF05] # FULLWIDTH PERCENT SIGN +FF06 ; [*0374.0020.0003.FF06] # FULLWIDTH AMPERSAND +FF07 ; [*02EA.0020.0003.FF07] # FULLWIDTH APOSTROPHE +FF08 ; [*02FB.0020.0003.FF08] # FULLWIDTH LEFT PARENTHESIS +FF09 ; [*02FC.0020.0003.FF09] # FULLWIDTH RIGHT PARENTHESIS +FF0A ; [*036D.0020.0003.FF0A] # FULLWIDTH ASTERISK +FF0B ; [*059C.0020.0003.FF0B] # FULLWIDTH PLUS SIGN +FF0C ; [*0221.0020.0003.FF0C] # FULLWIDTH COMMA +FF0D ; [*020E.0020.0003.FF0D] # FULLWIDTH HYPHEN-MINUS +FF0E ; [*0273.0020.0003.FF0E] # FULLWIDTH FULL STOP +FF0F ; [*0372.0020.0003.FF0F] # FULLWIDTH SOLIDUS +FF1A ; [*0237.0020.0003.FF1A] # FULLWIDTH COLON +FF1B ; [*0232.0020.0003.FF1B] # FULLWIDTH SEMICOLON +FF1C ; [*05A0.0020.0003.FF1C] # FULLWIDTH LESS-THAN SIGN +FF1D ; [*05A1.0020.0003.FF1D] # FULLWIDTH EQUALS SIGN +FF1E ; [*05A2.0020.0003.FF1E] # FULLWIDTH GREATER-THAN SIGN +FF1F ; [*0263.0020.0003.FF1F] # FULLWIDTH QUESTION MARK +FF20 ; [*036C.0020.0003.FF20] # FULLWIDTH COMMERCIAL AT +FF3B ; [*02FD.0020.0003.FF3B] # FULLWIDTH LEFT SQUARE BRACKET +FF3C ; [*0373.0020.0003.FF3C] # FULLWIDTH REVERSE SOLIDUS +FF3D ; [*02FE.0020.0003.FF3D] # FULLWIDTH RIGHT SQUARE BRACKET +FF3E ; [*0412.0020.0003.FF3E] # FULLWIDTH CIRCUMFLEX ACCENT +FF3F ; [*020C.0020.0003.FF3F] # FULLWIDTH LOW LINE +FF40 ; [*040F.0020.0003.FF40] # FULLWIDTH GRAVE ACCENT +FF5B ; [*02FF.0020.0003.FF5B] # FULLWIDTH LEFT CURLY BRACKET +FF5C ; [*05A4.0020.0003.FF5C] # FULLWIDTH VERTICAL LINE +FF5D ; [*0300.0020.0003.FF5D] # FULLWIDTH RIGHT CURLY BRACKET +FF5E ; [*05A6.0020.0003.FF5E] # FULLWIDTH TILDE +FF5F ; [*030D.0020.0003.FF5F] # FULLWIDTH LEFT WHITE PARENTHESIS +FF60 ; [*030E.0020.0003.FF60] # FULLWIDTH RIGHT WHITE PARENTHESIS +FF61 ; [*0283.0020.0012.FF61] # HALFWIDTH IDEOGRAPHIC FULL STOP +FF62 ; [*0353.0020.0012.FF62] # HALFWIDTH LEFT CORNER BRACKET +FF63 ; [*0354.0020.0012.FF63] # HALFWIDTH RIGHT CORNER BRACKET +FF64 ; [*022F.0020.0012.FF64] # HALFWIDTH IDEOGRAPHIC COMMA +FF65 ; [*0220.0020.0012.FF65] # HALFWIDTH KATAKANA MIDDLE DOT +FFE2 ; [*05A3.0020.0003.FFE2] # FULLWIDTH NOT SIGN +FFE3 ; [*0413.0020.0003.FFE3] # FULLWIDTH MACRON +FFE4 ; [*05A5.0020.0003.FFE4] # FULLWIDTH BROKEN BAR +FFE8 ; [*0799.0020.0012.FFE8] # HALFWIDTH FORMS LIGHT VERTICAL +FFE9 ; [*0522.0020.0012.FFE9] # HALFWIDTH LEFTWARDS ARROW +FFEA ; [*0524.0020.0012.FFEA] # HALFWIDTH UPWARDS ARROW +FFEB ; [*0523.0020.0012.FFEB] # HALFWIDTH RIGHTWARDS ARROW +FFEC ; [*0525.0020.0012.FFEC] # HALFWIDTH DOWNWARDS ARROW +FFED ; [*0837.0020.0012.FFED] # HALFWIDTH BLACK SQUARE +FFEE ; [*0862.0020.0012.FFEE] # HALFWIDTH WHITE CIRCLE +FFFC ; [*14BD.0020.0002.FFFC] # OBJECT REPLACEMENT CHARACTER +FFFD ; [*14BE.0020.0002.FFFD] # REPLACEMENT CHARACTER +10100 ; [*02E0.0020.0002.10100] # AEGEAN WORD SEPARATOR LINE +10101 ; [*02E1.0020.0002.10101] # AEGEAN WORD SEPARATOR DOT +10102 ; [*02E2.0020.0002.10102] # AEGEAN CHECK MARK +10110 ; [*1504.0020.0002.10110] # AEGEAN NUMBER TEN +10111 ; [*1505.0020.0002.10111] # AEGEAN NUMBER TWENTY +10112 ; [*1506.0020.0002.10112] # AEGEAN NUMBER THIRTY +10113 ; [*1507.0020.0002.10113] # AEGEAN NUMBER FORTY +10114 ; [*1508.0020.0002.10114] # AEGEAN NUMBER FIFTY +10115 ; [*1509.0020.0002.10115] # AEGEAN NUMBER SIXTY +10116 ; [*150A.0020.0002.10116] # AEGEAN NUMBER SEVENTY +10117 ; [*150B.0020.0002.10117] # AEGEAN NUMBER EIGHTY +10118 ; [*150C.0020.0002.10118] # AEGEAN NUMBER NINETY +10119 ; [*150D.0020.0002.10119] # AEGEAN NUMBER ONE HUNDRED +1011A ; [*150E.0020.0002.1011A] # AEGEAN NUMBER TWO HUNDRED +1011B ; [*150F.0020.0002.1011B] # AEGEAN NUMBER THREE HUNDRED +1011C ; [*1510.0020.0002.1011C] # AEGEAN NUMBER FOUR HUNDRED +1011D ; [*1511.0020.0002.1011D] # AEGEAN NUMBER FIVE HUNDRED +1011E ; [*1512.0020.0002.1011E] # AEGEAN NUMBER SIX HUNDRED +1011F ; [*1513.0020.0002.1011F] # AEGEAN NUMBER SEVEN HUNDRED +10120 ; [*1514.0020.0002.10120] # AEGEAN NUMBER EIGHT HUNDRED +10121 ; [*1515.0020.0002.10121] # AEGEAN NUMBER NINE HUNDRED +10122 ; [*1516.0020.0002.10122] # AEGEAN NUMBER ONE THOUSAND +10123 ; [*1517.0020.0002.10123] # AEGEAN NUMBER TWO THOUSAND +10124 ; [*1518.0020.0002.10124] # AEGEAN NUMBER THREE THOUSAND +10125 ; [*1519.0020.0002.10125] # AEGEAN NUMBER FOUR THOUSAND +10126 ; [*151A.0020.0002.10126] # AEGEAN NUMBER FIVE THOUSAND +10127 ; [*151B.0020.0002.10127] # AEGEAN NUMBER SIX THOUSAND +10128 ; [*151C.0020.0002.10128] # AEGEAN NUMBER SEVEN THOUSAND +10129 ; [*151D.0020.0002.10129] # AEGEAN NUMBER EIGHT THOUSAND +1012A ; [*151E.0020.0002.1012A] # AEGEAN NUMBER NINE THOUSAND +1012B ; [*151F.0020.0002.1012B] # AEGEAN NUMBER TEN THOUSAND +1012C ; [*1520.0020.0002.1012C] # AEGEAN NUMBER TWENTY THOUSAND +1012D ; [*1521.0020.0002.1012D] # AEGEAN NUMBER THIRTY THOUSAND +1012E ; [*1522.0020.0002.1012E] # AEGEAN NUMBER FORTY THOUSAND +1012F ; [*1523.0020.0002.1012F] # AEGEAN NUMBER FIFTY THOUSAND +10130 ; [*1524.0020.0002.10130] # AEGEAN NUMBER SIXTY THOUSAND +10131 ; [*1525.0020.0002.10131] # AEGEAN NUMBER SEVENTY THOUSAND +10132 ; [*1526.0020.0002.10132] # AEGEAN NUMBER EIGHTY THOUSAND +10133 ; [*1527.0020.0002.10133] # AEGEAN NUMBER NINETY THOUSAND +10137 ; [*0E65.0020.0002.10137] # AEGEAN WEIGHT BASE UNIT +10138 ; [*0E66.0020.0002.10138] # AEGEAN WEIGHT FIRST SUBUNIT +10139 ; [*0E67.0020.0002.10139] # AEGEAN WEIGHT SECOND SUBUNIT +1013A ; [*0E68.0020.0002.1013A] # AEGEAN WEIGHT THIRD SUBUNIT +1013B ; [*0E69.0020.0002.1013B] # AEGEAN WEIGHT FOURTH SUBUNIT +1013C ; [*0E6A.0020.0002.1013C] # AEGEAN DRY MEASURE FIRST SUBUNIT +1013D ; [*0E6B.0020.0002.1013D] # AEGEAN LIQUID MEASURE FIRST SUBUNIT +1013E ; [*0E6C.0020.0002.1013E] # AEGEAN MEASURE SECOND SUBUNIT +1013F ; [*0E6D.0020.0002.1013F] # AEGEAN MEASURE THIRD SUBUNIT +10140 ; [*1528.0020.0002.10140] # GREEK ACROPHONIC ATTIC ONE QUARTER +10141 ; [*1529.0020.0002.10141] # GREEK ACROPHONIC ATTIC ONE HALF +10144 ; [*152A.0020.0002.10144] # GREEK ACROPHONIC ATTIC FIFTY +10145 ; [*152B.0020.0002.10145] # GREEK ACROPHONIC ATTIC FIVE HUNDRED +10146 ; [*152C.0020.0002.10146] # GREEK ACROPHONIC ATTIC FIVE THOUSAND +10147 ; [*152D.0020.0002.10147] # GREEK ACROPHONIC ATTIC FIFTY THOUSAND +10149 ; [*152E.0020.0002.10149] # GREEK ACROPHONIC ATTIC TEN TALENTS +1014A ; [*152F.0020.0002.1014A] # GREEK ACROPHONIC ATTIC FIFTY TALENTS +1014B ; [*1530.0020.0002.1014B] # GREEK ACROPHONIC ATTIC ONE HUNDRED TALENTS +1014C ; [*1531.0020.0002.1014C] # GREEK ACROPHONIC ATTIC FIVE HUNDRED TALENTS +1014D ; [*1532.0020.0002.1014D] # GREEK ACROPHONIC ATTIC ONE THOUSAND TALENTS +1014E ; [*1533.0020.0002.1014E] # GREEK ACROPHONIC ATTIC FIVE THOUSAND TALENTS +10150 ; [*1534.0020.0002.10150] # GREEK ACROPHONIC ATTIC TEN STATERS +10151 ; [*1535.0020.0002.10151] # GREEK ACROPHONIC ATTIC FIFTY STATERS +10152 ; [*1536.0020.0002.10152] # GREEK ACROPHONIC ATTIC ONE HUNDRED STATERS +10153 ; [*1537.0020.0002.10153] # GREEK ACROPHONIC ATTIC FIVE HUNDRED STATERS +10154 ; [*1538.0020.0002.10154] # GREEK ACROPHONIC ATTIC ONE THOUSAND STATERS +10155 ; [*1539.0020.0002.10155] # GREEK ACROPHONIC ATTIC TEN THOUSAND STATERS +10156 ; [*153A.0020.0002.10156] # GREEK ACROPHONIC ATTIC FIFTY THOUSAND STATERS +10157 ; [*153B.0020.0002.10157] # GREEK ACROPHONIC ATTIC TEN MNAS +10160 ; [*153C.0020.0002.10160] # GREEK ACROPHONIC TROEZENIAN TEN +10161 ; [*153D.0020.0002.10161] # GREEK ACROPHONIC TROEZENIAN TEN ALTERNATE FORM +10162 ; [*153E.0020.0002.10162] # GREEK ACROPHONIC HERMIONIAN TEN +10163 ; [*153F.0020.0002.10163] # GREEK ACROPHONIC MESSENIAN TEN +10164 ; [*1540.0020.0002.10164] # GREEK ACROPHONIC THESPIAN TEN +10165 ; [*1541.0020.0002.10165] # GREEK ACROPHONIC THESPIAN THIRTY +10166 ; [*1542.0020.0002.10166] # GREEK ACROPHONIC TROEZENIAN FIFTY +10167 ; [*1543.0020.0002.10167] # GREEK ACROPHONIC TROEZENIAN FIFTY ALTERNATE FORM +10168 ; [*1544.0020.0002.10168] # GREEK ACROPHONIC HERMIONIAN FIFTY +10169 ; [*1545.0020.0002.10169] # GREEK ACROPHONIC THESPIAN FIFTY +1016A ; [*1546.0020.0002.1016A] # GREEK ACROPHONIC THESPIAN ONE HUNDRED +1016B ; [*1547.0020.0002.1016B] # GREEK ACROPHONIC THESPIAN THREE HUNDRED +1016C ; [*1548.0020.0002.1016C] # GREEK ACROPHONIC EPIDAUREAN FIVE HUNDRED +1016D ; [*1549.0020.0002.1016D] # GREEK ACROPHONIC TROEZENIAN FIVE HUNDRED +1016E ; [*154A.0020.0002.1016E] # GREEK ACROPHONIC THESPIAN FIVE HUNDRED +1016F ; [*154B.0020.0002.1016F] # GREEK ACROPHONIC CARYSTIAN FIVE HUNDRED +10170 ; [*154C.0020.0002.10170] # GREEK ACROPHONIC NAXIAN FIVE HUNDRED +10171 ; [*154D.0020.0002.10171] # GREEK ACROPHONIC THESPIAN ONE THOUSAND +10172 ; [*154E.0020.0002.10172] # GREEK ACROPHONIC THESPIAN FIVE THOUSAND +10174 ; [*154F.0020.0002.10174] # GREEK ACROPHONIC STRATIAN FIFTY MNAS +10175 ; [*1550.0020.0002.10175] # GREEK ONE HALF SIGN +10176 ; [*1551.0020.0002.10176] # GREEK ONE HALF SIGN ALTERNATE FORM +10177 ; [*1552.0020.0002.10177] # GREEK TWO THIRDS SIGN +10178 ; [*1553.0020.0002.10178] # GREEK THREE QUARTERS SIGN +10179 ; [*0E6E.0020.0002.10179] # GREEK YEAR SIGN +1017A ; [*0E6F.0020.0002.1017A] # GREEK TALENT SIGN +1017B ; [*0E70.0020.0002.1017B] # GREEK DRACHMA SIGN +1017C ; [*0E71.0020.0002.1017C] # GREEK OBOL SIGN +1017D ; [*0E72.0020.0002.1017D] # GREEK TWO OBOLS SIGN +1017E ; [*0E73.0020.0002.1017E] # GREEK THREE OBOLS SIGN +1017F ; [*0E74.0020.0002.1017F] # GREEK FOUR OBOLS SIGN +10180 ; [*0E75.0020.0002.10180] # GREEK FIVE OBOLS SIGN +10181 ; [*0E76.0020.0002.10181] # GREEK METRETES SIGN +10182 ; [*0E77.0020.0002.10182] # GREEK KYATHOS BASE SIGN +10183 ; [*0E78.0020.0002.10183] # GREEK LITRA SIGN +10184 ; [*0E79.0020.0002.10184] # GREEK OUNKIA SIGN +10185 ; [*0E7A.0020.0002.10185] # GREEK XESTES SIGN +10186 ; [*0E7B.0020.0002.10186] # GREEK ARTABE SIGN +10187 ; [*0E7C.0020.0002.10187] # GREEK AROURA SIGN +10188 ; [*0E7D.0020.0002.10188] # GREEK GRAMMA SIGN +10189 ; [*0E7E.0020.0002.10189] # GREEK TRYBLION BASE SIGN +10190 ; [*0E7F.0020.0002.10190] # ROMAN SEXTANS SIGN +10191 ; [*0E80.0020.0002.10191] # ROMAN UNCIA SIGN +10192 ; [*0E81.0020.0002.10192] # ROMAN SEMUNCIA SIGN +10193 ; [*0E82.0020.0002.10193] # ROMAN SEXTULA SIGN +10194 ; [*0E83.0020.0002.10194] # ROMAN DIMIDIA SEXTULA SIGN +10195 ; [*0E84.0020.0002.10195] # ROMAN SILIQUA SIGN +10196 ; [*0E85.0020.0002.10196] # ROMAN DENARIUS SIGN +10197 ; [*0E86.0020.0002.10197] # ROMAN QUINARIUS SIGN +10198 ; [*0E87.0020.0002.10198] # ROMAN SESTERTIUS SIGN +10199 ; [*0E88.0020.0002.10199] # ROMAN DUPONDIUS SIGN +1019A ; [*0E89.0020.0002.1019A] # ROMAN AS SIGN +1019B ; [*0E8A.0020.0002.1019B] # ROMAN CENTURIAL SIGN +101D0 ; [*0E8B.0020.0002.101D0] # PHAISTOS DISC SIGN PEDESTRIAN +101D1 ; [*0E8C.0020.0002.101D1] # PHAISTOS DISC SIGN PLUMED HEAD +101D2 ; [*0E8D.0020.0002.101D2] # PHAISTOS DISC SIGN TATTOOED HEAD +101D3 ; [*0E8E.0020.0002.101D3] # PHAISTOS DISC SIGN CAPTIVE +101D4 ; [*0E8F.0020.0002.101D4] # PHAISTOS DISC SIGN CHILD +101D5 ; [*0E90.0020.0002.101D5] # PHAISTOS DISC SIGN WOMAN +101D6 ; [*0E91.0020.0002.101D6] # PHAISTOS DISC SIGN HELMET +101D7 ; [*0E92.0020.0002.101D7] # PHAISTOS DISC SIGN GAUNTLET +101D8 ; [*0E93.0020.0002.101D8] # PHAISTOS DISC SIGN TIARA +101D9 ; [*0E94.0020.0002.101D9] # PHAISTOS DISC SIGN ARROW +101DA ; [*0E95.0020.0002.101DA] # PHAISTOS DISC SIGN BOW +101DB ; [*0E96.0020.0002.101DB] # PHAISTOS DISC SIGN SHIELD +101DC ; [*0E97.0020.0002.101DC] # PHAISTOS DISC SIGN CLUB +101DD ; [*0E98.0020.0002.101DD] # PHAISTOS DISC SIGN MANACLES +101DE ; [*0E99.0020.0002.101DE] # PHAISTOS DISC SIGN MATTOCK +101DF ; [*0E9A.0020.0002.101DF] # PHAISTOS DISC SIGN SAW +101E0 ; [*0E9B.0020.0002.101E0] # PHAISTOS DISC SIGN LID +101E1 ; [*0E9C.0020.0002.101E1] # PHAISTOS DISC SIGN BOOMERANG +101E2 ; [*0E9D.0020.0002.101E2] # PHAISTOS DISC SIGN CARPENTRY PLANE +101E3 ; [*0E9E.0020.0002.101E3] # PHAISTOS DISC SIGN DOLIUM +101E4 ; [*0E9F.0020.0002.101E4] # PHAISTOS DISC SIGN COMB +101E5 ; [*0EA0.0020.0002.101E5] # PHAISTOS DISC SIGN SLING +101E6 ; [*0EA1.0020.0002.101E6] # PHAISTOS DISC SIGN COLUMN +101E7 ; [*0EA2.0020.0002.101E7] # PHAISTOS DISC SIGN BEEHIVE +101E8 ; [*0EA3.0020.0002.101E8] # PHAISTOS DISC SIGN SHIP +101E9 ; [*0EA4.0020.0002.101E9] # PHAISTOS DISC SIGN HORN +101EA ; [*0EA5.0020.0002.101EA] # PHAISTOS DISC SIGN HIDE +101EB ; [*0EA6.0020.0002.101EB] # PHAISTOS DISC SIGN BULLS LEG +101EC ; [*0EA7.0020.0002.101EC] # PHAISTOS DISC SIGN CAT +101ED ; [*0EA8.0020.0002.101ED] # PHAISTOS DISC SIGN RAM +101EE ; [*0EA9.0020.0002.101EE] # PHAISTOS DISC SIGN EAGLE +101EF ; [*0EAA.0020.0002.101EF] # PHAISTOS DISC SIGN DOVE +101F0 ; [*0EAB.0020.0002.101F0] # PHAISTOS DISC SIGN TUNNY +101F1 ; [*0EAC.0020.0002.101F1] # PHAISTOS DISC SIGN BEE +101F2 ; [*0EAD.0020.0002.101F2] # PHAISTOS DISC SIGN PLANE TREE +101F3 ; [*0EAE.0020.0002.101F3] # PHAISTOS DISC SIGN VINE +101F4 ; [*0EAF.0020.0002.101F4] # PHAISTOS DISC SIGN PAPYRUS +101F5 ; [*0EB0.0020.0002.101F5] # PHAISTOS DISC SIGN ROSETTE +101F6 ; [*0EB1.0020.0002.101F6] # PHAISTOS DISC SIGN LILY +101F7 ; [*0EB2.0020.0002.101F7] # PHAISTOS DISC SIGN OX BACK +101F8 ; [*0EB3.0020.0002.101F8] # PHAISTOS DISC SIGN FLUTE +101F9 ; [*0EB4.0020.0002.101F9] # PHAISTOS DISC SIGN GRATER +101FA ; [*0EB5.0020.0002.101FA] # PHAISTOS DISC SIGN STRAINER +101FB ; [*0EB6.0020.0002.101FB] # PHAISTOS DISC SIGN SMALL AXE +101FC ; [*0EB7.0020.0002.101FC] # PHAISTOS DISC SIGN WAVY BAND +10322 ; [*1502.0020.0002.10322] # OLD ITALIC NUMERAL TEN +10323 ; [*1503.0020.0002.10323] # OLD ITALIC NUMERAL FIFTY +1039F ; [*02E3.0020.0002.1039F] # UGARITIC WORD DIVIDER +103D0 ; [*02E4.0020.0002.103D0] # OLD PERSIAN WORD DIVIDER +103D3 ; [*1554.0020.0002.103D3] # OLD PERSIAN NUMBER TEN +103D4 ; [*1555.0020.0002.103D4] # OLD PERSIAN NUMBER TWENTY +103D5 ; [*1556.0020.0002.103D5] # OLD PERSIAN NUMBER HUNDRED +10857 ; [*02C4.0020.0002.10857] # IMPERIAL ARAMAIC SECTION SIGN +1085B ; [*155C.0020.0002.1085B] # IMPERIAL ARAMAIC NUMBER TEN +1085C ; [*155D.0020.0002.1085C] # IMPERIAL ARAMAIC NUMBER TWENTY +1085D ; [*155E.0020.0002.1085D] # IMPERIAL ARAMAIC NUMBER ONE HUNDRED +1085E ; [*155F.0020.0002.1085E] # IMPERIAL ARAMAIC NUMBER ONE THOUSAND +1085F ; [*1560.0020.0002.1085F] # IMPERIAL ARAMAIC NUMBER TEN THOUSAND +10917 ; [*1559.0020.0002.10917] # PHOENICIAN NUMBER TEN +10918 ; [*155A.0020.0002.10918] # PHOENICIAN NUMBER TWENTY +10919 ; [*155B.0020.0002.10919] # PHOENICIAN NUMBER ONE HUNDRED +1091F ; [*02E5.0020.0002.1091F] # PHOENICIAN WORD SEPARATOR +1093F ; [*02DF.0020.0002.1093F] # LYDIAN TRIANGULAR MARK +10A44 ; [*1574.0020.0002.10A44] # KHAROSHTHI NUMBER TEN +10A45 ; [*1575.0020.0002.10A45] # KHAROSHTHI NUMBER TWENTY +10A46 ; [*1576.0020.0002.10A46] # KHAROSHTHI NUMBER ONE HUNDRED +10A47 ; [*1577.0020.0002.10A47] # KHAROSHTHI NUMBER ONE THOUSAND +10A50 ; [*0404.0020.0002.10A50] # KHAROSHTHI PUNCTUATION DOT +10A51 ; [*0405.0020.0002.10A51] # KHAROSHTHI PUNCTUATION SMALL CIRCLE +10A52 ; [*0406.0020.0002.10A52] # KHAROSHTHI PUNCTUATION CIRCLE +10A53 ; [*0407.0020.0002.10A53] # KHAROSHTHI PUNCTUATION CRESCENT BAR +10A54 ; [*0408.0020.0002.10A54] # KHAROSHTHI PUNCTUATION MANGALAM +10A55 ; [*0409.0020.0002.10A55] # KHAROSHTHI PUNCTUATION LOTUS +10A56 ; [*02A3.0020.0002.10A56] # KHAROSHTHI PUNCTUATION DANDA +10A57 ; [*02A4.0020.0002.10A57] # KHAROSHTHI PUNCTUATION DOUBLE DANDA +10A58 ; [*040A.0020.0002.10A58] # KHAROSHTHI PUNCTUATION LINES +10A7E ; [*1557.0020.0002.10A7E] # OLD SOUTH ARABIAN NUMBER FIFTY +10A7F ; [*1558.0020.0002.10A7F] # OLD SOUTH ARABIAN NUMERIC INDICATOR +10B39 ; [*040B.0020.0002.10B39] # AVESTAN ABBREVIATION MARK +10B3A ; [*02C5.0020.0002.10B3A] # TINY TWO DOTS OVER ONE DOT PUNCTUATION +10B3B ; [*02C6.0020.0002.10B3B] # SMALL TWO DOTS OVER ONE DOT PUNCTUATION +10B3C ; [*02C7.0020.0002.10B3C] # LARGE TWO DOTS OVER ONE DOT PUNCTUATION +10B3D ; [*02C8.0020.0002.10B3D] # LARGE ONE DOT OVER TWO DOTS PUNCTUATION +10B3E ; [*02C9.0020.0002.10B3E] # LARGE TWO RINGS OVER ONE RING PUNCTUATION +10B3F ; [*02CA.0020.0002.10B3F] # LARGE ONE RING OVER TWO RINGS PUNCTUATION +10B5C ; [*1561.0020.0002.10B5C] # INSCRIPTIONAL PARTHIAN NUMBER TEN +10B5D ; [*1562.0020.0002.10B5D] # INSCRIPTIONAL PARTHIAN NUMBER TWENTY +10B5E ; [*1563.0020.0002.10B5E] # INSCRIPTIONAL PARTHIAN NUMBER ONE HUNDRED +10B5F ; [*1564.0020.0002.10B5F] # INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND +10B7C ; [*1565.0020.0002.10B7C] # INSCRIPTIONAL PAHLAVI NUMBER TEN +10B7D ; [*1566.0020.0002.10B7D] # INSCRIPTIONAL PAHLAVI NUMBER TWENTY +10B7E ; [*1567.0020.0002.10B7E] # INSCRIPTIONAL PAHLAVI NUMBER ONE HUNDRED +10B7F ; [*1568.0020.0002.10B7F] # INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND +10E69 ; [*14EB.0020.0002.10E69] # RUMI NUMBER TEN +10E6A ; [*14EC.0020.0002.10E6A] # RUMI NUMBER TWENTY +10E6B ; [*14ED.0020.0002.10E6B] # RUMI NUMBER THIRTY +10E6C ; [*14EE.0020.0002.10E6C] # RUMI NUMBER FORTY +10E6D ; [*14EF.0020.0002.10E6D] # RUMI NUMBER FIFTY +10E6E ; [*14F0.0020.0002.10E6E] # RUMI NUMBER SIXTY +10E6F ; [*14F1.0020.0002.10E6F] # RUMI NUMBER SEVENTY +10E70 ; [*14F2.0020.0002.10E70] # RUMI NUMBER EIGHTY +10E71 ; [*14F3.0020.0002.10E71] # RUMI NUMBER NINETY +10E72 ; [*14F4.0020.0002.10E72] # RUMI NUMBER ONE HUNDRED +10E73 ; [*14F5.0020.0002.10E73] # RUMI NUMBER TWO HUNDRED +10E74 ; [*14F6.0020.0002.10E74] # RUMI NUMBER THREE HUNDRED +10E75 ; [*14F7.0020.0002.10E75] # RUMI NUMBER FOUR HUNDRED +10E76 ; [*14F8.0020.0002.10E76] # RUMI NUMBER FIVE HUNDRED +10E77 ; [*14F9.0020.0002.10E77] # RUMI NUMBER SIX HUNDRED +10E78 ; [*14FA.0020.0002.10E78] # RUMI NUMBER SEVEN HUNDRED +10E79 ; [*14FB.0020.0002.10E79] # RUMI NUMBER EIGHT HUNDRED +10E7A ; [*14FC.0020.0002.10E7A] # RUMI NUMBER NINE HUNDRED +10E7B ; [*14FD.0020.0002.10E7B] # RUMI FRACTION ONE HALF +10E7C ; [*14FE.0020.0002.10E7C] # RUMI FRACTION ONE QUARTER +10E7D ; [*14FF.0020.0002.10E7D] # RUMI FRACTION ONE THIRD +10E7E ; [*1500.0020.0002.10E7E] # RUMI FRACTION TWO THIRDS +11047 ; [*02A5.0020.0002.11047] # BRAHMI DANDA +11048 ; [*02A6.0020.0002.11048] # BRAHMI DOUBLE DANDA +11049 ; [*03FF.0020.0002.11049] # BRAHMI PUNCTUATION DOT +1104A ; [*0400.0020.0002.1104A] # BRAHMI PUNCTUATION DOUBLE DOT +1104B ; [*0401.0020.0002.1104B] # BRAHMI PUNCTUATION LINE +1104C ; [*0402.0020.0002.1104C] # BRAHMI PUNCTUATION CRESCENT BAR +1104D ; [*0403.0020.0002.1104D] # BRAHMI PUNCTUATION LOTUS +1105B ; [*1569.0020.0002.1105B] # BRAHMI NUMBER TEN +1105C ; [*156A.0020.0002.1105C] # BRAHMI NUMBER TWENTY +1105D ; [*156B.0020.0002.1105D] # BRAHMI NUMBER THIRTY +1105E ; [*156C.0020.0002.1105E] # BRAHMI NUMBER FORTY +1105F ; [*156D.0020.0002.1105F] # BRAHMI NUMBER FIFTY +11060 ; [*156E.0020.0002.11060] # BRAHMI NUMBER SIXTY +11061 ; [*156F.0020.0002.11061] # BRAHMI NUMBER SEVENTY +11062 ; [*1570.0020.0002.11062] # BRAHMI NUMBER EIGHTY +11063 ; [*1571.0020.0002.11063] # BRAHMI NUMBER NINETY +11064 ; [*1572.0020.0002.11064] # BRAHMI NUMBER ONE HUNDRED +11065 ; [*1573.0020.0002.11065] # BRAHMI NUMBER ONE THOUSAND +110BB ; [*040C.0020.0002.110BB] # KAITHI ABBREVIATION SIGN +110BC ; [*040D.0020.0002.110BC] # KAITHI ENUMERATION SIGN +110BD ; [.0000.0000.0000.110BD] # KAITHI NUMBER SIGN +110BE ; [*02CB.0020.0002.110BE] # KAITHI SECTION MARK +110BF ; [*02CC.0020.0002.110BF] # KAITHI DOUBLE SECTION MARK +110C0 ; [*02A7.0020.0002.110C0] # KAITHI DANDA +110C1 ; [*02A8.0020.0002.110C1] # KAITHI DOUBLE DANDA +11140 ; [*02CD.0020.0002.11140] # CHAKMA SECTION MARK +11141 ; [*02A9.0020.0002.11141] # CHAKMA DANDA +11142 ; [*02AA.0020.0002.11142] # CHAKMA DOUBLE DANDA +11143 ; [*0270.0020.0002.11143] # CHAKMA QUESTION MARK +111C5 ; [*02AB.0020.0002.111C5] # SHARADA DANDA +111C6 ; [*02AC.0020.0002.111C6] # SHARADA DOUBLE DANDA +111C7 ; [*040E.0020.0002.111C7] # SHARADA ABBREVIATION SIGN +111C8 ; [*02CE.0020.0002.111C8] # SHARADA SEPARATOR +12432 ; [*1578.0020.0002.12432] # CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS DISH +12433 ; [*1579.0020.0002.12433] # CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS MIN +12456 ; [*157A.0020.0002.12456] # CUNEIFORM NUMERIC SIGN NIGIDAMIN +12457 ; [*157B.0020.0002.12457] # CUNEIFORM NUMERIC SIGN NIGIDAESH +1245A ; [*157C.0020.0002.1245A] # CUNEIFORM NUMERIC SIGN ONE THIRD DISH +1245B ; [*157D.0020.0002.1245B] # CUNEIFORM NUMERIC SIGN TWO THIRDS DISH +1245C ; [*157E.0020.0002.1245C] # CUNEIFORM NUMERIC SIGN FIVE SIXTHS DISH +1245D ; [*157F.0020.0002.1245D] # CUNEIFORM NUMERIC SIGN ONE THIRD VARIANT FORM A +1245E ; [*1580.0020.0002.1245E] # CUNEIFORM NUMERIC SIGN TWO THIRDS VARIANT FORM A +1245F ; [*1581.0020.0002.1245F] # CUNEIFORM NUMERIC SIGN ONE EIGHTH ASH +12460 ; [*1582.0020.0002.12460] # CUNEIFORM NUMERIC SIGN ONE QUARTER ASH +12461 ; [*1583.0020.0002.12461] # CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE SIXTH +12462 ; [*1584.0020.0002.12462] # CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER +12470 ; [*02E6.0020.0002.12470] # CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER +12471 ; [*02E7.0020.0002.12471] # CUNEIFORM PUNCTUATION SIGN VERTICAL COLON +12472 ; [*02E8.0020.0002.12472] # CUNEIFORM PUNCTUATION SIGN DIAGONAL COLON +12473 ; [*02E9.0020.0002.12473] # CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON +1D000 ; [*0EB8.0020.0002.1D000] # BYZANTINE MUSICAL SYMBOL PSILI +1D001 ; [*0EB9.0020.0002.1D001] # BYZANTINE MUSICAL SYMBOL DASEIA +1D002 ; [*0EBA.0020.0002.1D002] # BYZANTINE MUSICAL SYMBOL PERISPOMENI +1D003 ; [*0EBB.0020.0002.1D003] # BYZANTINE MUSICAL SYMBOL OXEIA EKFONITIKON +1D004 ; [*0EBC.0020.0002.1D004] # BYZANTINE MUSICAL SYMBOL OXEIA DIPLI +1D005 ; [*0EBD.0020.0002.1D005] # BYZANTINE MUSICAL SYMBOL VAREIA EKFONITIKON +1D006 ; [*0EBE.0020.0002.1D006] # BYZANTINE MUSICAL SYMBOL VAREIA DIPLI +1D007 ; [*0EBF.0020.0002.1D007] # BYZANTINE MUSICAL SYMBOL KATHISTI +1D008 ; [*0EC0.0020.0002.1D008] # BYZANTINE MUSICAL SYMBOL SYRMATIKI +1D009 ; [*0EC1.0020.0002.1D009] # BYZANTINE MUSICAL SYMBOL PARAKLITIKI +1D00A ; [*0EC2.0020.0002.1D00A] # BYZANTINE MUSICAL SYMBOL YPOKRISIS +1D00B ; [*0EC3.0020.0002.1D00B] # BYZANTINE MUSICAL SYMBOL YPOKRISIS DIPLI +1D00C ; [*0EC4.0020.0002.1D00C] # BYZANTINE MUSICAL SYMBOL KREMASTI +1D00D ; [*0EC5.0020.0002.1D00D] # BYZANTINE MUSICAL SYMBOL APESO EKFONITIKON +1D00E ; [*0EC6.0020.0002.1D00E] # BYZANTINE MUSICAL SYMBOL EXO EKFONITIKON +1D00F ; [*0EC7.0020.0002.1D00F] # BYZANTINE MUSICAL SYMBOL TELEIA +1D010 ; [*0EC8.0020.0002.1D010] # BYZANTINE MUSICAL SYMBOL KENTIMATA +1D011 ; [*0EC9.0020.0002.1D011] # BYZANTINE MUSICAL SYMBOL APOSTROFOS +1D012 ; [*0ECA.0020.0002.1D012] # BYZANTINE MUSICAL SYMBOL APOSTROFOS DIPLI +1D013 ; [*0ECB.0020.0002.1D013] # BYZANTINE MUSICAL SYMBOL SYNEVMA +1D014 ; [*0ECC.0020.0002.1D014] # BYZANTINE MUSICAL SYMBOL THITA +1D015 ; [*0ECD.0020.0002.1D015] # BYZANTINE MUSICAL SYMBOL OLIGON ARCHAION +1D016 ; [*0ECE.0020.0002.1D016] # BYZANTINE MUSICAL SYMBOL GORGON ARCHAION +1D017 ; [*0ECF.0020.0002.1D017] # BYZANTINE MUSICAL SYMBOL PSILON +1D018 ; [*0ED0.0020.0002.1D018] # BYZANTINE MUSICAL SYMBOL CHAMILON +1D019 ; [*0ED1.0020.0002.1D019] # BYZANTINE MUSICAL SYMBOL VATHY +1D01A ; [*0ED2.0020.0002.1D01A] # BYZANTINE MUSICAL SYMBOL ISON ARCHAION +1D01B ; [*0ED3.0020.0002.1D01B] # BYZANTINE MUSICAL SYMBOL KENTIMA ARCHAION +1D01C ; [*0ED4.0020.0002.1D01C] # BYZANTINE MUSICAL SYMBOL KENTIMATA ARCHAION +1D01D ; [*0ED5.0020.0002.1D01D] # BYZANTINE MUSICAL SYMBOL SAXIMATA +1D01E ; [*0ED6.0020.0002.1D01E] # BYZANTINE MUSICAL SYMBOL PARICHON +1D01F ; [*0ED7.0020.0002.1D01F] # BYZANTINE MUSICAL SYMBOL STAVROS APODEXIA +1D020 ; [*0ED8.0020.0002.1D020] # BYZANTINE MUSICAL SYMBOL OXEIAI ARCHAION +1D021 ; [*0ED9.0020.0002.1D021] # BYZANTINE MUSICAL SYMBOL VAREIAI ARCHAION +1D022 ; [*0EDA.0020.0002.1D022] # BYZANTINE MUSICAL SYMBOL APODERMA ARCHAION +1D023 ; [*0EDB.0020.0002.1D023] # BYZANTINE MUSICAL SYMBOL APOTHEMA +1D024 ; [*0EDC.0020.0002.1D024] # BYZANTINE MUSICAL SYMBOL KLASMA +1D025 ; [*0EDD.0020.0002.1D025] # BYZANTINE MUSICAL SYMBOL REVMA +1D026 ; [*0EDE.0020.0002.1D026] # BYZANTINE MUSICAL SYMBOL PIASMA ARCHAION +1D027 ; [*0EDF.0020.0002.1D027] # BYZANTINE MUSICAL SYMBOL TINAGMA +1D028 ; [*0EE0.0020.0002.1D028] # BYZANTINE MUSICAL SYMBOL ANATRICHISMA +1D029 ; [*0EE1.0020.0002.1D029] # BYZANTINE MUSICAL SYMBOL SEISMA +1D02A ; [*0EE2.0020.0002.1D02A] # BYZANTINE MUSICAL SYMBOL SYNAGMA ARCHAION +1D02B ; [*0EE3.0020.0002.1D02B] # BYZANTINE MUSICAL SYMBOL SYNAGMA META STAVROU +1D02C ; [*0EE4.0020.0002.1D02C] # BYZANTINE MUSICAL SYMBOL OYRANISMA ARCHAION +1D02D ; [*0EE5.0020.0002.1D02D] # BYZANTINE MUSICAL SYMBOL THEMA +1D02E ; [*0EE6.0020.0002.1D02E] # BYZANTINE MUSICAL SYMBOL LEMOI +1D02F ; [*0EE7.0020.0002.1D02F] # BYZANTINE MUSICAL SYMBOL DYO +1D030 ; [*0EE8.0020.0002.1D030] # BYZANTINE MUSICAL SYMBOL TRIA +1D031 ; [*0EE9.0020.0002.1D031] # BYZANTINE MUSICAL SYMBOL TESSERA +1D032 ; [*0EEA.0020.0002.1D032] # BYZANTINE MUSICAL SYMBOL KRATIMATA +1D033 ; [*0EEB.0020.0002.1D033] # BYZANTINE MUSICAL SYMBOL APESO EXO NEO +1D034 ; [*0EEC.0020.0002.1D034] # BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION +1D035 ; [*0EED.0020.0002.1D035] # BYZANTINE MUSICAL SYMBOL IMIFTHORA +1D036 ; [*0EEE.0020.0002.1D036] # BYZANTINE MUSICAL SYMBOL TROMIKON ARCHAION +1D037 ; [*0EEF.0020.0002.1D037] # BYZANTINE MUSICAL SYMBOL KATAVA TROMIKON +1D038 ; [*0EF0.0020.0002.1D038] # BYZANTINE MUSICAL SYMBOL PELASTON +1D039 ; [*0EF1.0020.0002.1D039] # BYZANTINE MUSICAL SYMBOL PSIFISTON +1D03A ; [*0EF2.0020.0002.1D03A] # BYZANTINE MUSICAL SYMBOL KONTEVMA +1D03B ; [*0EF3.0020.0002.1D03B] # BYZANTINE MUSICAL SYMBOL CHOREVMA ARCHAION +1D03C ; [*0EF4.0020.0002.1D03C] # BYZANTINE MUSICAL SYMBOL RAPISMA +1D03D ; [*0EF5.0020.0002.1D03D] # BYZANTINE MUSICAL SYMBOL PARAKALESMA ARCHAION +1D03E ; [*0EF6.0020.0002.1D03E] # BYZANTINE MUSICAL SYMBOL PARAKLITIKI ARCHAION +1D03F ; [*0EF7.0020.0002.1D03F] # BYZANTINE MUSICAL SYMBOL ICHADIN +1D040 ; [*0EF8.0020.0002.1D040] # BYZANTINE MUSICAL SYMBOL NANA +1D041 ; [*0EF9.0020.0002.1D041] # BYZANTINE MUSICAL SYMBOL PETASMA +1D042 ; [*0EFA.0020.0002.1D042] # BYZANTINE MUSICAL SYMBOL KONTEVMA ALLO +1D043 ; [*0EFB.0020.0002.1D043] # BYZANTINE MUSICAL SYMBOL TROMIKON ALLO +1D044 ; [*0EFC.0020.0002.1D044] # BYZANTINE MUSICAL SYMBOL STRAGGISMATA +1D045 ; [*0EFD.0020.0002.1D045] # BYZANTINE MUSICAL SYMBOL GRONTHISMATA +1D046 ; [*0EFE.0020.0002.1D046] # BYZANTINE MUSICAL SYMBOL ISON NEO +1D047 ; [*0EFF.0020.0002.1D047] # BYZANTINE MUSICAL SYMBOL OLIGON NEO +1D048 ; [*0F00.0020.0002.1D048] # BYZANTINE MUSICAL SYMBOL OXEIA NEO +1D049 ; [*0F01.0020.0002.1D049] # BYZANTINE MUSICAL SYMBOL PETASTI +1D04A ; [*0F02.0020.0002.1D04A] # BYZANTINE MUSICAL SYMBOL KOUFISMA +1D04B ; [*0F03.0020.0002.1D04B] # BYZANTINE MUSICAL SYMBOL PETASTOKOUFISMA +1D04C ; [*0F04.0020.0002.1D04C] # BYZANTINE MUSICAL SYMBOL KRATIMOKOUFISMA +1D04D ; [*0F05.0020.0002.1D04D] # BYZANTINE MUSICAL SYMBOL PELASTON NEO +1D04E ; [*0F06.0020.0002.1D04E] # BYZANTINE MUSICAL SYMBOL KENTIMATA NEO ANO +1D04F ; [*0F07.0020.0002.1D04F] # BYZANTINE MUSICAL SYMBOL KENTIMA NEO ANO +1D050 ; [*0F08.0020.0002.1D050] # BYZANTINE MUSICAL SYMBOL YPSILI +1D051 ; [*0F09.0020.0002.1D051] # BYZANTINE MUSICAL SYMBOL APOSTROFOS NEO +1D052 ; [*0F0A.0020.0002.1D052] # BYZANTINE MUSICAL SYMBOL APOSTROFOI SYNDESMOS NEO +1D053 ; [*0F0B.0020.0002.1D053] # BYZANTINE MUSICAL SYMBOL YPORROI +1D054 ; [*0F0C.0020.0002.1D054] # BYZANTINE MUSICAL SYMBOL KRATIMOYPORROON +1D055 ; [*0F0D.0020.0002.1D055] # BYZANTINE MUSICAL SYMBOL ELAFRON +1D056 ; [*0F0E.0020.0002.1D056] # BYZANTINE MUSICAL SYMBOL CHAMILI +1D057 ; [*0F0F.0020.0002.1D057] # BYZANTINE MUSICAL SYMBOL MIKRON ISON +1D058 ; [*0F10.0020.0002.1D058] # BYZANTINE MUSICAL SYMBOL VAREIA NEO +1D059 ; [*0F11.0020.0002.1D059] # BYZANTINE MUSICAL SYMBOL PIASMA NEO +1D05A ; [*0F12.0020.0002.1D05A] # BYZANTINE MUSICAL SYMBOL PSIFISTON NEO +1D05B ; [*0F13.0020.0002.1D05B] # BYZANTINE MUSICAL SYMBOL OMALON +1D05C ; [*0F14.0020.0002.1D05C] # BYZANTINE MUSICAL SYMBOL ANTIKENOMA +1D05D ; [*0F15.0020.0002.1D05D] # BYZANTINE MUSICAL SYMBOL LYGISMA +1D05E ; [*0F16.0020.0002.1D05E] # BYZANTINE MUSICAL SYMBOL PARAKLITIKI NEO +1D05F ; [*0F17.0020.0002.1D05F] # BYZANTINE MUSICAL SYMBOL PARAKALESMA NEO +1D060 ; [*0F18.0020.0002.1D060] # BYZANTINE MUSICAL SYMBOL ETERON PARAKALESMA +1D061 ; [*0F19.0020.0002.1D061] # BYZANTINE MUSICAL SYMBOL KYLISMA +1D062 ; [*0F1A.0020.0002.1D062] # BYZANTINE MUSICAL SYMBOL ANTIKENOKYLISMA +1D063 ; [*0F1B.0020.0002.1D063] # BYZANTINE MUSICAL SYMBOL TROMIKON NEO +1D064 ; [*0F1C.0020.0002.1D064] # BYZANTINE MUSICAL SYMBOL EKSTREPTON +1D065 ; [*0F1D.0020.0002.1D065] # BYZANTINE MUSICAL SYMBOL SYNAGMA NEO +1D066 ; [*0F1E.0020.0002.1D066] # BYZANTINE MUSICAL SYMBOL SYRMA +1D067 ; [*0F1F.0020.0002.1D067] # BYZANTINE MUSICAL SYMBOL CHOREVMA NEO +1D068 ; [*0F20.0020.0002.1D068] # BYZANTINE MUSICAL SYMBOL EPEGERMA +1D069 ; [*0F21.0020.0002.1D069] # BYZANTINE MUSICAL SYMBOL SEISMA NEO +1D06A ; [*0F22.0020.0002.1D06A] # BYZANTINE MUSICAL SYMBOL XIRON KLASMA +1D06B ; [*0F23.0020.0002.1D06B] # BYZANTINE MUSICAL SYMBOL TROMIKOPSIFISTON +1D06C ; [*0F24.0020.0002.1D06C] # BYZANTINE MUSICAL SYMBOL PSIFISTOLYGISMA +1D06D ; [*0F25.0020.0002.1D06D] # BYZANTINE MUSICAL SYMBOL TROMIKOLYGISMA +1D06E ; [*0F26.0020.0002.1D06E] # BYZANTINE MUSICAL SYMBOL TROMIKOPARAKALESMA +1D06F ; [*0F27.0020.0002.1D06F] # BYZANTINE MUSICAL SYMBOL PSIFISTOPARAKALESMA +1D070 ; [*0F28.0020.0002.1D070] # BYZANTINE MUSICAL SYMBOL TROMIKOSYNAGMA +1D071 ; [*0F29.0020.0002.1D071] # BYZANTINE MUSICAL SYMBOL PSIFISTOSYNAGMA +1D072 ; [*0F2A.0020.0002.1D072] # BYZANTINE MUSICAL SYMBOL GORGOSYNTHETON +1D073 ; [*0F2B.0020.0002.1D073] # BYZANTINE MUSICAL SYMBOL ARGOSYNTHETON +1D074 ; [*0F2C.0020.0002.1D074] # BYZANTINE MUSICAL SYMBOL ETERON ARGOSYNTHETON +1D075 ; [*0F2D.0020.0002.1D075] # BYZANTINE MUSICAL SYMBOL OYRANISMA NEO +1D076 ; [*0F2E.0020.0002.1D076] # BYZANTINE MUSICAL SYMBOL THEMATISMOS ESO +1D077 ; [*0F2F.0020.0002.1D077] # BYZANTINE MUSICAL SYMBOL THEMATISMOS EXO +1D078 ; [*0F30.0020.0002.1D078] # BYZANTINE MUSICAL SYMBOL THEMA APLOUN +1D079 ; [*0F31.0020.0002.1D079] # BYZANTINE MUSICAL SYMBOL THES KAI APOTHES +1D07A ; [*0F32.0020.0002.1D07A] # BYZANTINE MUSICAL SYMBOL KATAVASMA +1D07B ; [*0F33.0020.0002.1D07B] # BYZANTINE MUSICAL SYMBOL ENDOFONON +1D07C ; [*0F34.0020.0002.1D07C] # BYZANTINE MUSICAL SYMBOL YFEN KATO +1D07D ; [*0F35.0020.0002.1D07D] # BYZANTINE MUSICAL SYMBOL YFEN ANO +1D07E ; [*0F36.0020.0002.1D07E] # BYZANTINE MUSICAL SYMBOL STAVROS +1D07F ; [*0F37.0020.0002.1D07F] # BYZANTINE MUSICAL SYMBOL KLASMA ANO +1D080 ; [*0F38.0020.0002.1D080] # BYZANTINE MUSICAL SYMBOL DIPLI ARCHAION +1D081 ; [*0F39.0020.0002.1D081] # BYZANTINE MUSICAL SYMBOL KRATIMA ARCHAION +1D082 ; [*0F3A.0020.0002.1D082] # BYZANTINE MUSICAL SYMBOL KRATIMA ALLO +1D083 ; [*0F3B.0020.0002.1D083] # BYZANTINE MUSICAL SYMBOL KRATIMA NEO +1D084 ; [*0F3C.0020.0002.1D084] # BYZANTINE MUSICAL SYMBOL APODERMA NEO +1D085 ; [*0F3D.0020.0002.1D085] # BYZANTINE MUSICAL SYMBOL APLI +1D086 ; [*0F3E.0020.0002.1D086] # BYZANTINE MUSICAL SYMBOL DIPLI +1D087 ; [*0F3F.0020.0002.1D087] # BYZANTINE MUSICAL SYMBOL TRIPLI +1D088 ; [*0F40.0020.0002.1D088] # BYZANTINE MUSICAL SYMBOL TETRAPLI +1D089 ; [*0F41.0020.0002.1D089] # BYZANTINE MUSICAL SYMBOL KORONIS +1D08A ; [*0F42.0020.0002.1D08A] # BYZANTINE MUSICAL SYMBOL LEIMMA ENOS CHRONOU +1D08B ; [*0F43.0020.0002.1D08B] # BYZANTINE MUSICAL SYMBOL LEIMMA DYO CHRONON +1D08C ; [*0F44.0020.0002.1D08C] # BYZANTINE MUSICAL SYMBOL LEIMMA TRION CHRONON +1D08D ; [*0F45.0020.0002.1D08D] # BYZANTINE MUSICAL SYMBOL LEIMMA TESSARON CHRONON +1D08E ; [*0F46.0020.0002.1D08E] # BYZANTINE MUSICAL SYMBOL LEIMMA IMISEOS CHRONOU +1D08F ; [*0F47.0020.0002.1D08F] # BYZANTINE MUSICAL SYMBOL GORGON NEO ANO +1D090 ; [*0F48.0020.0002.1D090] # BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON ARISTERA +1D091 ; [*0F49.0020.0002.1D091] # BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON DEXIA +1D092 ; [*0F4A.0020.0002.1D092] # BYZANTINE MUSICAL SYMBOL DIGORGON +1D093 ; [*0F4B.0020.0002.1D093] # BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA KATO +1D094 ; [*0F4C.0020.0002.1D094] # BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA ANO +1D095 ; [*0F4D.0020.0002.1D095] # BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON DEXIA +1D096 ; [*0F4E.0020.0002.1D096] # BYZANTINE MUSICAL SYMBOL TRIGORGON +1D097 ; [*0F4F.0020.0002.1D097] # BYZANTINE MUSICAL SYMBOL ARGON +1D098 ; [*0F50.0020.0002.1D098] # BYZANTINE MUSICAL SYMBOL IMIDIARGON +1D099 ; [*0F51.0020.0002.1D099] # BYZANTINE MUSICAL SYMBOL DIARGON +1D09A ; [*0F52.0020.0002.1D09A] # BYZANTINE MUSICAL SYMBOL AGOGI POLI ARGI +1D09B ; [*0F53.0020.0002.1D09B] # BYZANTINE MUSICAL SYMBOL AGOGI ARGOTERI +1D09C ; [*0F54.0020.0002.1D09C] # BYZANTINE MUSICAL SYMBOL AGOGI ARGI +1D09D ; [*0F55.0020.0002.1D09D] # BYZANTINE MUSICAL SYMBOL AGOGI METRIA +1D09E ; [*0F56.0020.0002.1D09E] # BYZANTINE MUSICAL SYMBOL AGOGI MESI +1D09F ; [*0F57.0020.0002.1D09F] # BYZANTINE MUSICAL SYMBOL AGOGI GORGI +1D0A0 ; [*0F58.0020.0002.1D0A0] # BYZANTINE MUSICAL SYMBOL AGOGI GORGOTERI +1D0A1 ; [*0F59.0020.0002.1D0A1] # BYZANTINE MUSICAL SYMBOL AGOGI POLI GORGI +1D0A2 ; [*0F5A.0020.0002.1D0A2] # BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOS ICHOS +1D0A3 ; [*0F5B.0020.0002.1D0A3] # BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI PROTOS ICHOS +1D0A4 ; [*0F5C.0020.0002.1D0A4] # BYZANTINE MUSICAL SYMBOL MARTYRIA DEYTEROS ICHOS +1D0A5 ; [*0F5D.0020.0002.1D0A5] # BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI DEYTEROS ICHOS +1D0A6 ; [*0F5E.0020.0002.1D0A6] # BYZANTINE MUSICAL SYMBOL MARTYRIA TRITOS ICHOS +1D0A7 ; [*0F5F.0020.0002.1D0A7] # BYZANTINE MUSICAL SYMBOL MARTYRIA TRIFONIAS +1D0A8 ; [*0F60.0020.0002.1D0A8] # BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS ICHOS +1D0A9 ; [*0F61.0020.0002.1D0A9] # BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS LEGETOS ICHOS +1D0AA ; [*0F62.0020.0002.1D0AA] # BYZANTINE MUSICAL SYMBOL MARTYRIA LEGETOS ICHOS +1D0AB ; [*0F63.0020.0002.1D0AB] # BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS ICHOS +1D0AC ; [*0F64.0020.0002.1D0AC] # BYZANTINE MUSICAL SYMBOL ISAKIA TELOUS ICHIMATOS +1D0AD ; [*0F65.0020.0002.1D0AD] # BYZANTINE MUSICAL SYMBOL APOSTROFOI TELOUS ICHIMATOS +1D0AE ; [*0F66.0020.0002.1D0AE] # BYZANTINE MUSICAL SYMBOL FANEROSIS TETRAFONIAS +1D0AF ; [*0F67.0020.0002.1D0AF] # BYZANTINE MUSICAL SYMBOL FANEROSIS MONOFONIAS +1D0B0 ; [*0F68.0020.0002.1D0B0] # BYZANTINE MUSICAL SYMBOL FANEROSIS DIFONIAS +1D0B1 ; [*0F69.0020.0002.1D0B1] # BYZANTINE MUSICAL SYMBOL MARTYRIA VARYS ICHOS +1D0B2 ; [*0F6A.0020.0002.1D0B2] # BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOVARYS ICHOS +1D0B3 ; [*0F6B.0020.0002.1D0B3] # BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS TETARTOS ICHOS +1D0B4 ; [*0F6C.0020.0002.1D0B4] # BYZANTINE MUSICAL SYMBOL GORTHMIKON N APLOUN +1D0B5 ; [*0F6D.0020.0002.1D0B5] # BYZANTINE MUSICAL SYMBOL GORTHMIKON N DIPLOUN +1D0B6 ; [*0F6E.0020.0002.1D0B6] # BYZANTINE MUSICAL SYMBOL ENARXIS KAI FTHORA VOU +1D0B7 ; [*0F6F.0020.0002.1D0B7] # BYZANTINE MUSICAL SYMBOL IMIFONON +1D0B8 ; [*0F70.0020.0002.1D0B8] # BYZANTINE MUSICAL SYMBOL IMIFTHORON +1D0B9 ; [*0F71.0020.0002.1D0B9] # BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION DEYTEROU ICHOU +1D0BA ; [*0F72.0020.0002.1D0BA] # BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI PA +1D0BB ; [*0F73.0020.0002.1D0BB] # BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NANA +1D0BC ; [*0F74.0020.0002.1D0BC] # BYZANTINE MUSICAL SYMBOL FTHORA NAOS ICHOS +1D0BD ; [*0F75.0020.0002.1D0BD] # BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI DI +1D0BE ; [*0F76.0020.0002.1D0BE] # BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON DIATONON DI +1D0BF ; [*0F77.0020.0002.1D0BF] # BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI KE +1D0C0 ; [*0F78.0020.0002.1D0C0] # BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI ZO +1D0C1 ; [*0F79.0020.0002.1D0C1] # BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI KATO +1D0C2 ; [*0F7A.0020.0002.1D0C2] # BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI ANO +1D0C3 ; [*0F7B.0020.0002.1D0C3] # BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA DIFONIAS +1D0C4 ; [*0F7C.0020.0002.1D0C4] # BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA MONOFONIAS +1D0C5 ; [*0F7D.0020.0002.1D0C5] # BYZANTINE MUSICAL SYMBOL FHTORA SKLIRON CHROMA VASIS +1D0C6 ; [*0F7E.0020.0002.1D0C6] # BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON CHROMA SYNAFI +1D0C7 ; [*0F7F.0020.0002.1D0C7] # BYZANTINE MUSICAL SYMBOL FTHORA NENANO +1D0C8 ; [*0F80.0020.0002.1D0C8] # BYZANTINE MUSICAL SYMBOL CHROA ZYGOS +1D0C9 ; [*0F81.0020.0002.1D0C9] # BYZANTINE MUSICAL SYMBOL CHROA KLITON +1D0CA ; [*0F82.0020.0002.1D0CA] # BYZANTINE MUSICAL SYMBOL CHROA SPATHI +1D0CB ; [*0F83.0020.0002.1D0CB] # BYZANTINE MUSICAL SYMBOL FTHORA I YFESIS TETARTIMORION +1D0CC ; [*0F84.0020.0002.1D0CC] # BYZANTINE MUSICAL SYMBOL FTHORA ENARMONIOS ANTIFONIA +1D0CD ; [*0F85.0020.0002.1D0CD] # BYZANTINE MUSICAL SYMBOL YFESIS TRITIMORION +1D0CE ; [*0F86.0020.0002.1D0CE] # BYZANTINE MUSICAL SYMBOL DIESIS TRITIMORION +1D0CF ; [*0F87.0020.0002.1D0CF] # BYZANTINE MUSICAL SYMBOL DIESIS TETARTIMORION +1D0D0 ; [*0F88.0020.0002.1D0D0] # BYZANTINE MUSICAL SYMBOL DIESIS APLI DYO DODEKATA +1D0D1 ; [*0F89.0020.0002.1D0D1] # BYZANTINE MUSICAL SYMBOL DIESIS MONOGRAMMOS TESSERA DODEKATA +1D0D2 ; [*0F8A.0020.0002.1D0D2] # BYZANTINE MUSICAL SYMBOL DIESIS DIGRAMMOS EX DODEKATA +1D0D3 ; [*0F8B.0020.0002.1D0D3] # BYZANTINE MUSICAL SYMBOL DIESIS TRIGRAMMOS OKTO DODEKATA +1D0D4 ; [*0F8C.0020.0002.1D0D4] # BYZANTINE MUSICAL SYMBOL YFESIS APLI DYO DODEKATA +1D0D5 ; [*0F8D.0020.0002.1D0D5] # BYZANTINE MUSICAL SYMBOL YFESIS MONOGRAMMOS TESSERA DODEKATA +1D0D6 ; [*0F8E.0020.0002.1D0D6] # BYZANTINE MUSICAL SYMBOL YFESIS DIGRAMMOS EX DODEKATA +1D0D7 ; [*0F8F.0020.0002.1D0D7] # BYZANTINE MUSICAL SYMBOL YFESIS TRIGRAMMOS OKTO DODEKATA +1D0D8 ; [*0F90.0020.0002.1D0D8] # BYZANTINE MUSICAL SYMBOL GENIKI DIESIS +1D0D9 ; [*0F91.0020.0002.1D0D9] # BYZANTINE MUSICAL SYMBOL GENIKI YFESIS +1D0DA ; [*0F92.0020.0002.1D0DA] # BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MIKRI +1D0DB ; [*0F93.0020.0002.1D0DB] # BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MEGALI +1D0DC ; [*0F94.0020.0002.1D0DC] # BYZANTINE MUSICAL SYMBOL DIASTOLI DIPLI +1D0DD ; [*0F95.0020.0002.1D0DD] # BYZANTINE MUSICAL SYMBOL DIASTOLI THESEOS +1D0DE ; [*0F96.0020.0002.1D0DE] # BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS +1D0DF ; [*0F97.0020.0002.1D0DF] # BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS DISIMOU +1D0E0 ; [*0F98.0020.0002.1D0E0] # BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TRISIMOU +1D0E1 ; [*0F99.0020.0002.1D0E1] # BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TETRASIMOU +1D0E2 ; [*0F9A.0020.0002.1D0E2] # BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS +1D0E3 ; [*0F9B.0020.0002.1D0E3] # BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS DISIMOU +1D0E4 ; [*0F9C.0020.0002.1D0E4] # BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TRISIMOU +1D0E5 ; [*0F9D.0020.0002.1D0E5] # BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TETRASIMOU +1D0E6 ; [*0F9E.0020.0002.1D0E6] # BYZANTINE MUSICAL SYMBOL DIGRAMMA GG +1D0E7 ; [*0F9F.0020.0002.1D0E7] # BYZANTINE MUSICAL SYMBOL DIFTOGGOS OU +1D0E8 ; [*0FA0.0020.0002.1D0E8] # BYZANTINE MUSICAL SYMBOL STIGMA +1D0E9 ; [*0FA1.0020.0002.1D0E9] # BYZANTINE MUSICAL SYMBOL ARKTIKO PA +1D0EA ; [*0FA2.0020.0002.1D0EA] # BYZANTINE MUSICAL SYMBOL ARKTIKO VOU +1D0EB ; [*0FA3.0020.0002.1D0EB] # BYZANTINE MUSICAL SYMBOL ARKTIKO GA +1D0EC ; [*0FA4.0020.0002.1D0EC] # BYZANTINE MUSICAL SYMBOL ARKTIKO DI +1D0ED ; [*0FA5.0020.0002.1D0ED] # BYZANTINE MUSICAL SYMBOL ARKTIKO KE +1D0EE ; [*0FA6.0020.0002.1D0EE] # BYZANTINE MUSICAL SYMBOL ARKTIKO ZO +1D0EF ; [*0FA7.0020.0002.1D0EF] # BYZANTINE MUSICAL SYMBOL ARKTIKO NI +1D0F0 ; [*0FA8.0020.0002.1D0F0] # BYZANTINE MUSICAL SYMBOL KENTIMATA NEO MESO +1D0F1 ; [*0FA9.0020.0002.1D0F1] # BYZANTINE MUSICAL SYMBOL KENTIMA NEO MESO +1D0F2 ; [*0FAA.0020.0002.1D0F2] # BYZANTINE MUSICAL SYMBOL KENTIMATA NEO KATO +1D0F3 ; [*0FAB.0020.0002.1D0F3] # BYZANTINE MUSICAL SYMBOL KENTIMA NEO KATO +1D0F4 ; [*0FAC.0020.0002.1D0F4] # BYZANTINE MUSICAL SYMBOL KLASMA KATO +1D0F5 ; [*0FAD.0020.0002.1D0F5] # BYZANTINE MUSICAL SYMBOL GORGON NEO KATO +1D100 ; [*0FAE.0020.0002.1D100] # MUSICAL SYMBOL SINGLE BARLINE +1D101 ; [*0FAF.0020.0002.1D101] # MUSICAL SYMBOL DOUBLE BARLINE +1D102 ; [*0FB0.0020.0002.1D102] # MUSICAL SYMBOL FINAL BARLINE +1D103 ; [*0FB1.0020.0002.1D103] # MUSICAL SYMBOL REVERSE FINAL BARLINE +1D104 ; [*0FB2.0020.0002.1D104] # MUSICAL SYMBOL DASHED BARLINE +1D105 ; [*0FB3.0020.0002.1D105] # MUSICAL SYMBOL SHORT BARLINE +1D106 ; [*0FB4.0020.0002.1D106] # MUSICAL SYMBOL LEFT REPEAT SIGN +1D107 ; [*0FB5.0020.0002.1D107] # MUSICAL SYMBOL RIGHT REPEAT SIGN +1D108 ; [*0FB6.0020.0002.1D108] # MUSICAL SYMBOL REPEAT DOTS +1D109 ; [*0FB7.0020.0002.1D109] # MUSICAL SYMBOL DAL SEGNO +1D10A ; [*0FB8.0020.0002.1D10A] # MUSICAL SYMBOL DA CAPO +1D10B ; [*0FB9.0020.0002.1D10B] # MUSICAL SYMBOL SEGNO +1D10C ; [*0FBA.0020.0002.1D10C] # MUSICAL SYMBOL CODA +1D10D ; [*0FBB.0020.0002.1D10D] # MUSICAL SYMBOL REPEATED FIGURE-1 +1D10E ; [*0FBC.0020.0002.1D10E] # MUSICAL SYMBOL REPEATED FIGURE-2 +1D10F ; [*0FBD.0020.0002.1D10F] # MUSICAL SYMBOL REPEATED FIGURE-3 +1D110 ; [*0FBE.0020.0002.1D110] # MUSICAL SYMBOL FERMATA +1D111 ; [*0FBF.0020.0002.1D111] # MUSICAL SYMBOL FERMATA BELOW +1D112 ; [*0FC0.0020.0002.1D112] # MUSICAL SYMBOL BREATH MARK +1D113 ; [*0FC1.0020.0002.1D113] # MUSICAL SYMBOL CAESURA +1D114 ; [*0FC2.0020.0002.1D114] # MUSICAL SYMBOL BRACE +1D115 ; [*0FC3.0020.0002.1D115] # MUSICAL SYMBOL BRACKET +1D116 ; [*0FC4.0020.0002.1D116] # MUSICAL SYMBOL ONE-LINE STAFF +1D117 ; [*0FC5.0020.0002.1D117] # MUSICAL SYMBOL TWO-LINE STAFF +1D118 ; [*0FC6.0020.0002.1D118] # MUSICAL SYMBOL THREE-LINE STAFF +1D119 ; [*0FC7.0020.0002.1D119] # MUSICAL SYMBOL FOUR-LINE STAFF +1D11A ; [*0FC8.0020.0002.1D11A] # MUSICAL SYMBOL FIVE-LINE STAFF +1D11B ; [*0FC9.0020.0002.1D11B] # MUSICAL SYMBOL SIX-LINE STAFF +1D11C ; [*0FCA.0020.0002.1D11C] # MUSICAL SYMBOL SIX-STRING FRETBOARD +1D11D ; [*0FCB.0020.0002.1D11D] # MUSICAL SYMBOL FOUR-STRING FRETBOARD +1D11E ; [*0FCC.0020.0002.1D11E] # MUSICAL SYMBOL G CLEF +1D11F ; [*0FCD.0020.0002.1D11F] # MUSICAL SYMBOL G CLEF OTTAVA ALTA +1D120 ; [*0FCE.0020.0002.1D120] # MUSICAL SYMBOL G CLEF OTTAVA BASSA +1D121 ; [*0FCF.0020.0002.1D121] # MUSICAL SYMBOL C CLEF +1D122 ; [*0FD0.0020.0002.1D122] # MUSICAL SYMBOL F CLEF +1D123 ; [*0FD1.0020.0002.1D123] # MUSICAL SYMBOL F CLEF OTTAVA ALTA +1D124 ; [*0FD2.0020.0002.1D124] # MUSICAL SYMBOL F CLEF OTTAVA BASSA +1D125 ; [*0FD3.0020.0002.1D125] # MUSICAL SYMBOL DRUM CLEF-1 +1D126 ; [*0FD4.0020.0002.1D126] # MUSICAL SYMBOL DRUM CLEF-2 +1D129 ; [*0FE8.0020.0002.1D129] # MUSICAL SYMBOL MULTIPLE MEASURE REST +1D12A ; [*0FD8.0020.0002.1D12A] # MUSICAL SYMBOL DOUBLE SHARP +1D12B ; [*0FD9.0020.0002.1D12B] # MUSICAL SYMBOL DOUBLE FLAT +1D12C ; [*0FDA.0020.0002.1D12C] # MUSICAL SYMBOL FLAT UP +1D12D ; [*0FDB.0020.0002.1D12D] # MUSICAL SYMBOL FLAT DOWN +1D12E ; [*0FDC.0020.0002.1D12E] # MUSICAL SYMBOL NATURAL UP +1D12F ; [*0FDD.0020.0002.1D12F] # MUSICAL SYMBOL NATURAL DOWN +1D130 ; [*0FDE.0020.0002.1D130] # MUSICAL SYMBOL SHARP UP +1D131 ; [*0FDF.0020.0002.1D131] # MUSICAL SYMBOL SHARP DOWN +1D132 ; [*0FE0.0020.0002.1D132] # MUSICAL SYMBOL QUARTER TONE SHARP +1D133 ; [*0FE1.0020.0002.1D133] # MUSICAL SYMBOL QUARTER TONE FLAT +1D134 ; [*0FE2.0020.0002.1D134] # MUSICAL SYMBOL COMMON TIME +1D135 ; [*0FE3.0020.0002.1D135] # MUSICAL SYMBOL CUT TIME +1D136 ; [*0FE4.0020.0002.1D136] # MUSICAL SYMBOL OTTAVA ALTA +1D137 ; [*0FE5.0020.0002.1D137] # MUSICAL SYMBOL OTTAVA BASSA +1D138 ; [*0FE6.0020.0002.1D138] # MUSICAL SYMBOL QUINDICESIMA ALTA +1D139 ; [*0FE7.0020.0002.1D139] # MUSICAL SYMBOL QUINDICESIMA BASSA +1D13A ; [*0FE9.0020.0002.1D13A] # MUSICAL SYMBOL MULTI REST +1D13B ; [*0FEA.0020.0002.1D13B] # MUSICAL SYMBOL WHOLE REST +1D13C ; [*0FEB.0020.0002.1D13C] # MUSICAL SYMBOL HALF REST +1D13D ; [*0FEC.0020.0002.1D13D] # MUSICAL SYMBOL QUARTER REST +1D13E ; [*0FED.0020.0002.1D13E] # MUSICAL SYMBOL EIGHTH REST +1D13F ; [*0FEE.0020.0002.1D13F] # MUSICAL SYMBOL SIXTEENTH REST +1D140 ; [*0FEF.0020.0002.1D140] # MUSICAL SYMBOL THIRTY-SECOND REST +1D141 ; [*0FF0.0020.0002.1D141] # MUSICAL SYMBOL SIXTY-FOURTH REST +1D142 ; [*0FF1.0020.0002.1D142] # MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH REST +1D143 ; [*0FF2.0020.0002.1D143] # MUSICAL SYMBOL X NOTEHEAD +1D144 ; [*0FF3.0020.0002.1D144] # MUSICAL SYMBOL PLUS NOTEHEAD +1D145 ; [*0FF4.0020.0002.1D145] # MUSICAL SYMBOL CIRCLE X NOTEHEAD +1D146 ; [*0FF5.0020.0002.1D146] # MUSICAL SYMBOL SQUARE NOTEHEAD WHITE +1D147 ; [*0FF6.0020.0002.1D147] # MUSICAL SYMBOL SQUARE NOTEHEAD BLACK +1D148 ; [*0FF7.0020.0002.1D148] # MUSICAL SYMBOL TRIANGLE NOTEHEAD UP WHITE +1D149 ; [*0FF8.0020.0002.1D149] # MUSICAL SYMBOL TRIANGLE NOTEHEAD UP BLACK +1D14A ; [*0FF9.0020.0002.1D14A] # MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT WHITE +1D14B ; [*0FFA.0020.0002.1D14B] # MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT BLACK +1D14C ; [*0FFB.0020.0002.1D14C] # MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT WHITE +1D14D ; [*0FFC.0020.0002.1D14D] # MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT BLACK +1D14E ; [*0FFD.0020.0002.1D14E] # MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN WHITE +1D14F ; [*0FFE.0020.0002.1D14F] # MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN BLACK +1D150 ; [*0FFF.0020.0002.1D150] # MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT WHITE +1D151 ; [*1000.0020.0002.1D151] # MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT BLACK +1D152 ; [*1001.0020.0002.1D152] # MUSICAL SYMBOL MOON NOTEHEAD WHITE +1D153 ; [*1002.0020.0002.1D153] # MUSICAL SYMBOL MOON NOTEHEAD BLACK +1D154 ; [*1003.0020.0002.1D154] # MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN WHITE +1D155 ; [*1004.0020.0002.1D155] # MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN BLACK +1D156 ; [*1005.0020.0002.1D156] # MUSICAL SYMBOL PARENTHESIS NOTEHEAD +1D157 ; [*1006.0020.0002.1D157] # MUSICAL SYMBOL VOID NOTEHEAD +1D158 ; [*1007.0020.0002.1D158] # MUSICAL SYMBOL NOTEHEAD BLACK +1D159 ; [*1008.0020.0002.1D159] # MUSICAL SYMBOL NULL NOTEHEAD +1D15A ; [*1009.0020.0002.1D15A] # MUSICAL SYMBOL CLUSTER NOTEHEAD WHITE +1D15B ; [*100A.0020.0002.1D15B] # MUSICAL SYMBOL CLUSTER NOTEHEAD BLACK +1D15C ; [*100B.0020.0002.1D15C] # MUSICAL SYMBOL BREVE +1D15D ; [*100C.0020.0002.1D15D] # MUSICAL SYMBOL WHOLE NOTE +1D15E ; [*1006.0020.0002.1D157][.0000.0000.0000.1D165] # MUSICAL SYMBOL HALF NOTE +1D15F ; [*1007.0020.0002.1D158][.0000.0000.0000.1D165] # MUSICAL SYMBOL QUARTER NOTE +1D160 ; [*1007.0020.0002.1D158][.0000.0000.0000.1D165][.0000.0000.0000.1D16E] # MUSICAL SYMBOL EIGHTH NOTE +1D161 ; [*1007.0020.0002.1D158][.0000.0000.0000.1D165][.0000.0000.0000.1D16F] # MUSICAL SYMBOL SIXTEENTH NOTE +1D162 ; [*1007.0020.0002.1D158][.0000.0000.0000.1D165][.0000.0000.0000.1D170] # MUSICAL SYMBOL THIRTY-SECOND NOTE +1D163 ; [*1007.0020.0002.1D158][.0000.0000.0000.1D165][.0000.0000.0000.1D171] # MUSICAL SYMBOL SIXTY-FOURTH NOTE +1D164 ; [*1007.0020.0002.1D158][.0000.0000.0000.1D165][.0000.0000.0000.1D172] # MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE +1D165 ; [.0000.0000.0000.1D165] # MUSICAL SYMBOL COMBINING STEM +1D166 ; [.0000.0000.0000.1D166] # MUSICAL SYMBOL COMBINING SPRECHGESANG STEM +1D167 ; [.0000.0000.0000.1D167] # MUSICAL SYMBOL COMBINING TREMOLO-1 +1D168 ; [.0000.0000.0000.1D168] # MUSICAL SYMBOL COMBINING TREMOLO-2 +1D169 ; [.0000.0000.0000.1D169] # MUSICAL SYMBOL COMBINING TREMOLO-3 +1D16A ; [*100D.0020.0002.1D16A] # MUSICAL SYMBOL FINGERED TREMOLO-1 +1D16B ; [*100E.0020.0002.1D16B] # MUSICAL SYMBOL FINGERED TREMOLO-2 +1D16C ; [*100F.0020.0002.1D16C] # MUSICAL SYMBOL FINGERED TREMOLO-3 +1D16D ; [.0000.0000.0000.1D16D] # MUSICAL SYMBOL COMBINING AUGMENTATION DOT +1D16E ; [.0000.0000.0000.1D16E] # MUSICAL SYMBOL COMBINING FLAG-1 +1D16F ; [.0000.0000.0000.1D16F] # MUSICAL SYMBOL COMBINING FLAG-2 +1D170 ; [.0000.0000.0000.1D170] # MUSICAL SYMBOL COMBINING FLAG-3 +1D171 ; [.0000.0000.0000.1D171] # MUSICAL SYMBOL COMBINING FLAG-4 +1D172 ; [.0000.0000.0000.1D172] # MUSICAL SYMBOL COMBINING FLAG-5 +1D17B ; [.0000.0000.0000.1D17B] # MUSICAL SYMBOL COMBINING ACCENT +1D17C ; [.0000.0000.0000.1D17C] # MUSICAL SYMBOL COMBINING STACCATO +1D17D ; [.0000.0000.0000.1D17D] # MUSICAL SYMBOL COMBINING TENUTO +1D17E ; [.0000.0000.0000.1D17E] # MUSICAL SYMBOL COMBINING STACCATISSIMO +1D17F ; [.0000.0000.0000.1D17F] # MUSICAL SYMBOL COMBINING MARCATO +1D180 ; [.0000.0000.0000.1D180] # MUSICAL SYMBOL COMBINING MARCATO-STACCATO +1D181 ; [.0000.0000.0000.1D181] # MUSICAL SYMBOL COMBINING ACCENT-STACCATO +1D182 ; [.0000.0000.0000.1D182] # MUSICAL SYMBOL COMBINING LOURE +1D183 ; [*1010.0020.0002.1D183] # MUSICAL SYMBOL ARPEGGIATO UP +1D184 ; [*1011.0020.0002.1D184] # MUSICAL SYMBOL ARPEGGIATO DOWN +1D185 ; [.0000.0000.0000.1D185] # MUSICAL SYMBOL COMBINING DOIT +1D186 ; [.0000.0000.0000.1D186] # MUSICAL SYMBOL COMBINING RIP +1D187 ; [.0000.0000.0000.1D187] # MUSICAL SYMBOL COMBINING FLIP +1D188 ; [.0000.0000.0000.1D188] # MUSICAL SYMBOL COMBINING SMEAR +1D189 ; [.0000.0000.0000.1D189] # MUSICAL SYMBOL COMBINING BEND +1D18A ; [.0000.0000.0000.1D18A] # MUSICAL SYMBOL COMBINING DOUBLE TONGUE +1D18B ; [.0000.0000.0000.1D18B] # MUSICAL SYMBOL COMBINING TRIPLE TONGUE +1D18C ; [*1012.0020.0002.1D18C] # MUSICAL SYMBOL RINFORZANDO +1D18D ; [*1013.0020.0002.1D18D] # MUSICAL SYMBOL SUBITO +1D18E ; [*1014.0020.0002.1D18E] # MUSICAL SYMBOL Z +1D18F ; [*1015.0020.0002.1D18F] # MUSICAL SYMBOL PIANO +1D190 ; [*1016.0020.0002.1D190] # MUSICAL SYMBOL MEZZO +1D191 ; [*1017.0020.0002.1D191] # MUSICAL SYMBOL FORTE +1D192 ; [*1018.0020.0002.1D192] # MUSICAL SYMBOL CRESCENDO +1D193 ; [*1019.0020.0002.1D193] # MUSICAL SYMBOL DECRESCENDO +1D194 ; [*101A.0020.0002.1D194] # MUSICAL SYMBOL GRACE NOTE SLASH +1D195 ; [*101B.0020.0002.1D195] # MUSICAL SYMBOL GRACE NOTE NO SLASH +1D196 ; [*101C.0020.0002.1D196] # MUSICAL SYMBOL TR +1D197 ; [*101D.0020.0002.1D197] # MUSICAL SYMBOL TURN +1D198 ; [*101E.0020.0002.1D198] # MUSICAL SYMBOL INVERTED TURN +1D199 ; [*101F.0020.0002.1D199] # MUSICAL SYMBOL TURN SLASH +1D19A ; [*1020.0020.0002.1D19A] # MUSICAL SYMBOL TURN UP +1D19B ; [*1021.0020.0002.1D19B] # MUSICAL SYMBOL ORNAMENT STROKE-1 +1D19C ; [*1022.0020.0002.1D19C] # MUSICAL SYMBOL ORNAMENT STROKE-2 +1D19D ; [*1023.0020.0002.1D19D] # MUSICAL SYMBOL ORNAMENT STROKE-3 +1D19E ; [*1024.0020.0002.1D19E] # MUSICAL SYMBOL ORNAMENT STROKE-4 +1D19F ; [*1025.0020.0002.1D19F] # MUSICAL SYMBOL ORNAMENT STROKE-5 +1D1A0 ; [*1026.0020.0002.1D1A0] # MUSICAL SYMBOL ORNAMENT STROKE-6 +1D1A1 ; [*1027.0020.0002.1D1A1] # MUSICAL SYMBOL ORNAMENT STROKE-7 +1D1A2 ; [*1028.0020.0002.1D1A2] # MUSICAL SYMBOL ORNAMENT STROKE-8 +1D1A3 ; [*1029.0020.0002.1D1A3] # MUSICAL SYMBOL ORNAMENT STROKE-9 +1D1A4 ; [*102A.0020.0002.1D1A4] # MUSICAL SYMBOL ORNAMENT STROKE-10 +1D1A5 ; [*102B.0020.0002.1D1A5] # MUSICAL SYMBOL ORNAMENT STROKE-11 +1D1A6 ; [*102C.0020.0002.1D1A6] # MUSICAL SYMBOL HAUPTSTIMME +1D1A7 ; [*102D.0020.0002.1D1A7] # MUSICAL SYMBOL NEBENSTIMME +1D1A8 ; [*102E.0020.0002.1D1A8] # MUSICAL SYMBOL END OF STIMME +1D1A9 ; [*102F.0020.0002.1D1A9] # MUSICAL SYMBOL DEGREE SLASH +1D1AA ; [.0000.0000.0000.1D1AA] # MUSICAL SYMBOL COMBINING DOWN BOW +1D1AB ; [.0000.0000.0000.1D1AB] # MUSICAL SYMBOL COMBINING UP BOW +1D1AC ; [.0000.0000.0000.1D1AC] # MUSICAL SYMBOL COMBINING HARMONIC +1D1AD ; [.0000.0000.0000.1D1AD] # MUSICAL SYMBOL COMBINING SNAP PIZZICATO +1D1AE ; [*1030.0020.0002.1D1AE] # MUSICAL SYMBOL PEDAL MARK +1D1AF ; [*1031.0020.0002.1D1AF] # MUSICAL SYMBOL PEDAL UP MARK +1D1B0 ; [*1032.0020.0002.1D1B0] # MUSICAL SYMBOL HALF PEDAL MARK +1D1B1 ; [*1033.0020.0002.1D1B1] # MUSICAL SYMBOL GLISSANDO UP +1D1B2 ; [*1034.0020.0002.1D1B2] # MUSICAL SYMBOL GLISSANDO DOWN +1D1B3 ; [*1035.0020.0002.1D1B3] # MUSICAL SYMBOL WITH FINGERNAILS +1D1B4 ; [*1036.0020.0002.1D1B4] # MUSICAL SYMBOL DAMP +1D1B5 ; [*1037.0020.0002.1D1B5] # MUSICAL SYMBOL DAMP ALL +1D1B6 ; [*1038.0020.0002.1D1B6] # MUSICAL SYMBOL MAXIMA +1D1B7 ; [*1039.0020.0002.1D1B7] # MUSICAL SYMBOL LONGA +1D1B8 ; [*103A.0020.0002.1D1B8] # MUSICAL SYMBOL BREVIS +1D1B9 ; [*103B.0020.0002.1D1B9] # MUSICAL SYMBOL SEMIBREVIS WHITE +1D1BA ; [*103C.0020.0002.1D1BA] # MUSICAL SYMBOL SEMIBREVIS BLACK +1D1BB ; [*103B.0020.0002.1D1B9][.0000.0000.0000.1D165] # MUSICAL SYMBOL MINIMA +1D1BC ; [*103C.0020.0002.1D1BA][.0000.0000.0000.1D165] # MUSICAL SYMBOL MINIMA BLACK +1D1BD ; [*103B.0020.0002.1D1B9][.0000.0000.0000.1D165][.0000.0000.0000.1D16E] # MUSICAL SYMBOL SEMIMINIMA WHITE +1D1BE ; [*103C.0020.0002.1D1BA][.0000.0000.0000.1D165][.0000.0000.0000.1D16E] # MUSICAL SYMBOL SEMIMINIMA BLACK +1D1BF ; [*103B.0020.0002.1D1B9][.0000.0000.0000.1D165][.0000.0000.0000.1D16F] # MUSICAL SYMBOL FUSA WHITE +1D1C0 ; [*103C.0020.0002.1D1BA][.0000.0000.0000.1D165][.0000.0000.0000.1D16F] # MUSICAL SYMBOL FUSA BLACK +1D1C1 ; [*103D.0020.0002.1D1C1] # MUSICAL SYMBOL LONGA PERFECTA REST +1D1C2 ; [*103E.0020.0002.1D1C2] # MUSICAL SYMBOL LONGA IMPERFECTA REST +1D1C3 ; [*103F.0020.0002.1D1C3] # MUSICAL SYMBOL BREVIS REST +1D1C4 ; [*1040.0020.0002.1D1C4] # MUSICAL SYMBOL SEMIBREVIS REST +1D1C5 ; [*1041.0020.0002.1D1C5] # MUSICAL SYMBOL MINIMA REST +1D1C6 ; [*1042.0020.0002.1D1C6] # MUSICAL SYMBOL SEMIMINIMA REST +1D1C7 ; [*1043.0020.0002.1D1C7] # MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA +1D1C8 ; [*1044.0020.0002.1D1C8] # MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE IMPERFECTA +1D1C9 ; [*1045.0020.0002.1D1C9] # MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA DIMINUTION-1 +1D1CA ; [*1046.0020.0002.1D1CA] # MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE PERFECTA +1D1CB ; [*1047.0020.0002.1D1CB] # MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA +1D1CC ; [*1048.0020.0002.1D1CC] # MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-1 +1D1CD ; [*1049.0020.0002.1D1CD] # MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-2 +1D1CE ; [*104A.0020.0002.1D1CE] # MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-3 +1D1CF ; [*104B.0020.0002.1D1CF] # MUSICAL SYMBOL CROIX +1D1D0 ; [*104C.0020.0002.1D1D0] # MUSICAL SYMBOL GREGORIAN C CLEF +1D1D1 ; [*104D.0020.0002.1D1D1] # MUSICAL SYMBOL GREGORIAN F CLEF +1D1D2 ; [*104E.0020.0002.1D1D2] # MUSICAL SYMBOL SQUARE B +1D1D3 ; [*104F.0020.0002.1D1D3] # MUSICAL SYMBOL VIRGA +1D1D4 ; [*1050.0020.0002.1D1D4] # MUSICAL SYMBOL PODATUS +1D1D5 ; [*1051.0020.0002.1D1D5] # MUSICAL SYMBOL CLIVIS +1D1D6 ; [*1052.0020.0002.1D1D6] # MUSICAL SYMBOL SCANDICUS +1D1D7 ; [*1053.0020.0002.1D1D7] # MUSICAL SYMBOL CLIMACUS +1D1D8 ; [*1054.0020.0002.1D1D8] # MUSICAL SYMBOL TORCULUS +1D1D9 ; [*1055.0020.0002.1D1D9] # MUSICAL SYMBOL PORRECTUS +1D1DA ; [*1056.0020.0002.1D1DA] # MUSICAL SYMBOL PORRECTUS FLEXUS +1D1DB ; [*1057.0020.0002.1D1DB] # MUSICAL SYMBOL SCANDICUS FLEXUS +1D1DC ; [*1058.0020.0002.1D1DC] # MUSICAL SYMBOL TORCULUS RESUPINUS +1D1DD ; [*1059.0020.0002.1D1DD] # MUSICAL SYMBOL PES SUBPUNCTIS +1D200 ; [*105A.0020.0002.1D200] # GREEK VOCAL NOTATION SYMBOL-1 +1D201 ; [*105B.0020.0002.1D201] # GREEK VOCAL NOTATION SYMBOL-2 +1D202 ; [*105C.0020.0002.1D202] # GREEK VOCAL NOTATION SYMBOL-3 +1D203 ; [*105D.0020.0002.1D203] # GREEK VOCAL NOTATION SYMBOL-4 +1D204 ; [*105E.0020.0002.1D204] # GREEK VOCAL NOTATION SYMBOL-5 +1D205 ; [*105F.0020.0002.1D205] # GREEK VOCAL NOTATION SYMBOL-6 +1D206 ; [*1060.0020.0002.1D206] # GREEK VOCAL NOTATION SYMBOL-7 +1D207 ; [*1061.0020.0002.1D207] # GREEK VOCAL NOTATION SYMBOL-8 +1D208 ; [*1062.0020.0002.1D208] # GREEK VOCAL NOTATION SYMBOL-9 +1D209 ; [*1063.0020.0002.1D209] # GREEK VOCAL NOTATION SYMBOL-10 +1D20A ; [*1064.0020.0002.1D20A] # GREEK VOCAL NOTATION SYMBOL-11 +1D20B ; [*1065.0020.0002.1D20B] # GREEK VOCAL NOTATION SYMBOL-12 +1D20C ; [*1066.0020.0002.1D20C] # GREEK VOCAL NOTATION SYMBOL-13 +1D20D ; [*1067.0020.0002.1D20D] # GREEK VOCAL NOTATION SYMBOL-14 +1D20E ; [*1068.0020.0002.1D20E] # GREEK VOCAL NOTATION SYMBOL-15 +1D20F ; [*1069.0020.0002.1D20F] # GREEK VOCAL NOTATION SYMBOL-16 +1D210 ; [*106A.0020.0002.1D210] # GREEK VOCAL NOTATION SYMBOL-17 +1D211 ; [*106B.0020.0002.1D211] # GREEK VOCAL NOTATION SYMBOL-18 +1D212 ; [*106C.0020.0002.1D212] # GREEK VOCAL NOTATION SYMBOL-19 +1D213 ; [*106D.0020.0002.1D213] # GREEK VOCAL NOTATION SYMBOL-20 +1D214 ; [*106E.0020.0002.1D214] # GREEK VOCAL NOTATION SYMBOL-21 +1D215 ; [*106F.0020.0002.1D215] # GREEK VOCAL NOTATION SYMBOL-22 +1D216 ; [*1070.0020.0002.1D216] # GREEK VOCAL NOTATION SYMBOL-23 +1D217 ; [*1071.0020.0002.1D217] # GREEK VOCAL NOTATION SYMBOL-24 +1D218 ; [*1072.0020.0002.1D218] # GREEK VOCAL NOTATION SYMBOL-50 +1D219 ; [*1073.0020.0002.1D219] # GREEK VOCAL NOTATION SYMBOL-51 +1D21A ; [*1074.0020.0002.1D21A] # GREEK VOCAL NOTATION SYMBOL-52 +1D21B ; [*1075.0020.0002.1D21B] # GREEK VOCAL NOTATION SYMBOL-53 +1D21C ; [*1076.0020.0002.1D21C] # GREEK VOCAL NOTATION SYMBOL-54 +1D21D ; [*1077.0020.0002.1D21D] # GREEK INSTRUMENTAL NOTATION SYMBOL-1 +1D21E ; [*1078.0020.0002.1D21E] # GREEK INSTRUMENTAL NOTATION SYMBOL-2 +1D21F ; [*1079.0020.0002.1D21F] # GREEK INSTRUMENTAL NOTATION SYMBOL-4 +1D220 ; [*107A.0020.0002.1D220] # GREEK INSTRUMENTAL NOTATION SYMBOL-5 +1D221 ; [*107B.0020.0002.1D221] # GREEK INSTRUMENTAL NOTATION SYMBOL-7 +1D222 ; [*107C.0020.0002.1D222] # GREEK INSTRUMENTAL NOTATION SYMBOL-8 +1D223 ; [*107D.0020.0002.1D223] # GREEK INSTRUMENTAL NOTATION SYMBOL-11 +1D224 ; [*107E.0020.0002.1D224] # GREEK INSTRUMENTAL NOTATION SYMBOL-12 +1D225 ; [*107F.0020.0002.1D225] # GREEK INSTRUMENTAL NOTATION SYMBOL-13 +1D226 ; [*1080.0020.0002.1D226] # GREEK INSTRUMENTAL NOTATION SYMBOL-14 +1D227 ; [*1081.0020.0002.1D227] # GREEK INSTRUMENTAL NOTATION SYMBOL-17 +1D228 ; [*1082.0020.0002.1D228] # GREEK INSTRUMENTAL NOTATION SYMBOL-18 +1D229 ; [*1083.0020.0002.1D229] # GREEK INSTRUMENTAL NOTATION SYMBOL-19 +1D22A ; [*1084.0020.0002.1D22A] # GREEK INSTRUMENTAL NOTATION SYMBOL-23 +1D22B ; [*1085.0020.0002.1D22B] # GREEK INSTRUMENTAL NOTATION SYMBOL-24 +1D22C ; [*1086.0020.0002.1D22C] # GREEK INSTRUMENTAL NOTATION SYMBOL-25 +1D22D ; [*1087.0020.0002.1D22D] # GREEK INSTRUMENTAL NOTATION SYMBOL-26 +1D22E ; [*1088.0020.0002.1D22E] # GREEK INSTRUMENTAL NOTATION SYMBOL-27 +1D22F ; [*1089.0020.0002.1D22F] # GREEK INSTRUMENTAL NOTATION SYMBOL-29 +1D230 ; [*108A.0020.0002.1D230] # GREEK INSTRUMENTAL NOTATION SYMBOL-30 +1D231 ; [*108B.0020.0002.1D231] # GREEK INSTRUMENTAL NOTATION SYMBOL-32 +1D232 ; [*108C.0020.0002.1D232] # GREEK INSTRUMENTAL NOTATION SYMBOL-36 +1D233 ; [*108D.0020.0002.1D233] # GREEK INSTRUMENTAL NOTATION SYMBOL-37 +1D234 ; [*108E.0020.0002.1D234] # GREEK INSTRUMENTAL NOTATION SYMBOL-38 +1D235 ; [*108F.0020.0002.1D235] # GREEK INSTRUMENTAL NOTATION SYMBOL-39 +1D236 ; [*1090.0020.0002.1D236] # GREEK INSTRUMENTAL NOTATION SYMBOL-40 +1D237 ; [*1091.0020.0002.1D237] # GREEK INSTRUMENTAL NOTATION SYMBOL-42 +1D238 ; [*1092.0020.0002.1D238] # GREEK INSTRUMENTAL NOTATION SYMBOL-43 +1D239 ; [*1093.0020.0002.1D239] # GREEK INSTRUMENTAL NOTATION SYMBOL-45 +1D23A ; [*1094.0020.0002.1D23A] # GREEK INSTRUMENTAL NOTATION SYMBOL-47 +1D23B ; [*1095.0020.0002.1D23B] # GREEK INSTRUMENTAL NOTATION SYMBOL-48 +1D23C ; [*1096.0020.0002.1D23C] # GREEK INSTRUMENTAL NOTATION SYMBOL-49 +1D23D ; [*1097.0020.0002.1D23D] # GREEK INSTRUMENTAL NOTATION SYMBOL-50 +1D23E ; [*1098.0020.0002.1D23E] # GREEK INSTRUMENTAL NOTATION SYMBOL-51 +1D23F ; [*1099.0020.0002.1D23F] # GREEK INSTRUMENTAL NOTATION SYMBOL-52 +1D240 ; [*109A.0020.0002.1D240] # GREEK INSTRUMENTAL NOTATION SYMBOL-53 +1D241 ; [*109B.0020.0002.1D241] # GREEK INSTRUMENTAL NOTATION SYMBOL-54 +1D242 ; [.0000.0000.0000.1D242] # COMBINING GREEK MUSICAL TRISEME +1D243 ; [.0000.0000.0000.1D243] # COMBINING GREEK MUSICAL TETRASEME +1D244 ; [.0000.0000.0000.1D244] # COMBINING GREEK MUSICAL PENTASEME +1D245 ; [*109C.0020.0002.1D245] # GREEK MUSICAL LEIMMA +1D300 ; [*0DD7.0020.0002.1D300] # MONOGRAM FOR EARTH +1D301 ; [*0DD8.0020.0002.1D301] # DIGRAM FOR HEAVENLY EARTH +1D302 ; [*0DD9.0020.0002.1D302] # DIGRAM FOR HUMAN EARTH +1D303 ; [*0DDA.0020.0002.1D303] # DIGRAM FOR EARTHLY HEAVEN +1D304 ; [*0DDB.0020.0002.1D304] # DIGRAM FOR EARTHLY HUMAN +1D305 ; [*0DDC.0020.0002.1D305] # DIGRAM FOR EARTH +1D306 ; [*0DDD.0020.0002.1D306] # TETRAGRAM FOR CENTRE +1D307 ; [*0DDE.0020.0002.1D307] # TETRAGRAM FOR FULL CIRCLE +1D308 ; [*0DDF.0020.0002.1D308] # TETRAGRAM FOR MIRED +1D309 ; [*0DE0.0020.0002.1D309] # TETRAGRAM FOR BARRIER +1D30A ; [*0DE1.0020.0002.1D30A] # TETRAGRAM FOR KEEPING SMALL +1D30B ; [*0DE2.0020.0002.1D30B] # TETRAGRAM FOR CONTRARIETY +1D30C ; [*0DE3.0020.0002.1D30C] # TETRAGRAM FOR ASCENT +1D30D ; [*0DE4.0020.0002.1D30D] # TETRAGRAM FOR OPPOSITION +1D30E ; [*0DE5.0020.0002.1D30E] # TETRAGRAM FOR BRANCHING OUT +1D30F ; [*0DE6.0020.0002.1D30F] # TETRAGRAM FOR DEFECTIVENESS OR DISTORTION +1D310 ; [*0DE7.0020.0002.1D310] # TETRAGRAM FOR DIVERGENCE +1D311 ; [*0DE8.0020.0002.1D311] # TETRAGRAM FOR YOUTHFULNESS +1D312 ; [*0DE9.0020.0002.1D312] # TETRAGRAM FOR INCREASE +1D313 ; [*0DEA.0020.0002.1D313] # TETRAGRAM FOR PENETRATION +1D314 ; [*0DEB.0020.0002.1D314] # TETRAGRAM FOR REACH +1D315 ; [*0DEC.0020.0002.1D315] # TETRAGRAM FOR CONTACT +1D316 ; [*0DED.0020.0002.1D316] # TETRAGRAM FOR HOLDING BACK +1D317 ; [*0DEE.0020.0002.1D317] # TETRAGRAM FOR WAITING +1D318 ; [*0DEF.0020.0002.1D318] # TETRAGRAM FOR FOLLOWING +1D319 ; [*0DF0.0020.0002.1D319] # TETRAGRAM FOR ADVANCE +1D31A ; [*0DF1.0020.0002.1D31A] # TETRAGRAM FOR RELEASE +1D31B ; [*0DF2.0020.0002.1D31B] # TETRAGRAM FOR RESISTANCE +1D31C ; [*0DF3.0020.0002.1D31C] # TETRAGRAM FOR EASE +1D31D ; [*0DF4.0020.0002.1D31D] # TETRAGRAM FOR JOY +1D31E ; [*0DF5.0020.0002.1D31E] # TETRAGRAM FOR CONTENTION +1D31F ; [*0DF6.0020.0002.1D31F] # TETRAGRAM FOR ENDEAVOUR +1D320 ; [*0DF7.0020.0002.1D320] # TETRAGRAM FOR DUTIES +1D321 ; [*0DF8.0020.0002.1D321] # TETRAGRAM FOR CHANGE +1D322 ; [*0DF9.0020.0002.1D322] # TETRAGRAM FOR DECISIVENESS +1D323 ; [*0DFA.0020.0002.1D323] # TETRAGRAM FOR BOLD RESOLUTION +1D324 ; [*0DFB.0020.0002.1D324] # TETRAGRAM FOR PACKING +1D325 ; [*0DFC.0020.0002.1D325] # TETRAGRAM FOR LEGION +1D326 ; [*0DFD.0020.0002.1D326] # TETRAGRAM FOR CLOSENESS +1D327 ; [*0DFE.0020.0002.1D327] # TETRAGRAM FOR KINSHIP +1D328 ; [*0DFF.0020.0002.1D328] # TETRAGRAM FOR GATHERING +1D329 ; [*0E00.0020.0002.1D329] # TETRAGRAM FOR STRENGTH +1D32A ; [*0E01.0020.0002.1D32A] # TETRAGRAM FOR PURITY +1D32B ; [*0E02.0020.0002.1D32B] # TETRAGRAM FOR FULLNESS +1D32C ; [*0E03.0020.0002.1D32C] # TETRAGRAM FOR RESIDENCE +1D32D ; [*0E04.0020.0002.1D32D] # TETRAGRAM FOR LAW OR MODEL +1D32E ; [*0E05.0020.0002.1D32E] # TETRAGRAM FOR RESPONSE +1D32F ; [*0E06.0020.0002.1D32F] # TETRAGRAM FOR GOING TO MEET +1D330 ; [*0E07.0020.0002.1D330] # TETRAGRAM FOR ENCOUNTERS +1D331 ; [*0E08.0020.0002.1D331] # TETRAGRAM FOR STOVE +1D332 ; [*0E09.0020.0002.1D332] # TETRAGRAM FOR GREATNESS +1D333 ; [*0E0A.0020.0002.1D333] # TETRAGRAM FOR ENLARGEMENT +1D334 ; [*0E0B.0020.0002.1D334] # TETRAGRAM FOR PATTERN +1D335 ; [*0E0C.0020.0002.1D335] # TETRAGRAM FOR RITUAL +1D336 ; [*0E0D.0020.0002.1D336] # TETRAGRAM FOR FLIGHT +1D337 ; [*0E0E.0020.0002.1D337] # TETRAGRAM FOR VASTNESS OR WASTING +1D338 ; [*0E0F.0020.0002.1D338] # TETRAGRAM FOR CONSTANCY +1D339 ; [*0E10.0020.0002.1D339] # TETRAGRAM FOR MEASURE +1D33A ; [*0E11.0020.0002.1D33A] # TETRAGRAM FOR ETERNITY +1D33B ; [*0E12.0020.0002.1D33B] # TETRAGRAM FOR UNITY +1D33C ; [*0E13.0020.0002.1D33C] # TETRAGRAM FOR DIMINISHMENT +1D33D ; [*0E14.0020.0002.1D33D] # TETRAGRAM FOR CLOSED MOUTH +1D33E ; [*0E15.0020.0002.1D33E] # TETRAGRAM FOR GUARDEDNESS +1D33F ; [*0E16.0020.0002.1D33F] # TETRAGRAM FOR GATHERING IN +1D340 ; [*0E17.0020.0002.1D340] # TETRAGRAM FOR MASSING +1D341 ; [*0E18.0020.0002.1D341] # TETRAGRAM FOR ACCUMULATION +1D342 ; [*0E19.0020.0002.1D342] # TETRAGRAM FOR EMBELLISHMENT +1D343 ; [*0E1A.0020.0002.1D343] # TETRAGRAM FOR DOUBT +1D344 ; [*0E1B.0020.0002.1D344] # TETRAGRAM FOR WATCH +1D345 ; [*0E1C.0020.0002.1D345] # TETRAGRAM FOR SINKING +1D346 ; [*0E1D.0020.0002.1D346] # TETRAGRAM FOR INNER +1D347 ; [*0E1E.0020.0002.1D347] # TETRAGRAM FOR DEPARTURE +1D348 ; [*0E1F.0020.0002.1D348] # TETRAGRAM FOR DARKENING +1D349 ; [*0E20.0020.0002.1D349] # TETRAGRAM FOR DIMMING +1D34A ; [*0E21.0020.0002.1D34A] # TETRAGRAM FOR EXHAUSTION +1D34B ; [*0E22.0020.0002.1D34B] # TETRAGRAM FOR SEVERANCE +1D34C ; [*0E23.0020.0002.1D34C] # TETRAGRAM FOR STOPPAGE +1D34D ; [*0E24.0020.0002.1D34D] # TETRAGRAM FOR HARDNESS +1D34E ; [*0E25.0020.0002.1D34E] # TETRAGRAM FOR COMPLETION +1D34F ; [*0E26.0020.0002.1D34F] # TETRAGRAM FOR CLOSURE +1D350 ; [*0E27.0020.0002.1D350] # TETRAGRAM FOR FAILURE +1D351 ; [*0E28.0020.0002.1D351] # TETRAGRAM FOR AGGRAVATION +1D352 ; [*0E29.0020.0002.1D352] # TETRAGRAM FOR COMPLIANCE +1D353 ; [*0E2A.0020.0002.1D353] # TETRAGRAM FOR ON THE VERGE +1D354 ; [*0E2B.0020.0002.1D354] # TETRAGRAM FOR DIFFICULTIES +1D355 ; [*0E2C.0020.0002.1D355] # TETRAGRAM FOR LABOURING +1D356 ; [*0E2D.0020.0002.1D356] # TETRAGRAM FOR FOSTERING +1D369 ; [*1585.0020.0002.1D369] # COUNTING ROD TENS DIGIT ONE +1D36A ; [*1586.0020.0002.1D36A] # COUNTING ROD TENS DIGIT TWO +1D36B ; [*1587.0020.0002.1D36B] # COUNTING ROD TENS DIGIT THREE +1D36C ; [*1588.0020.0002.1D36C] # COUNTING ROD TENS DIGIT FOUR +1D36D ; [*1589.0020.0002.1D36D] # COUNTING ROD TENS DIGIT FIVE +1D36E ; [*158A.0020.0002.1D36E] # COUNTING ROD TENS DIGIT SIX +1D36F ; [*158B.0020.0002.1D36F] # COUNTING ROD TENS DIGIT SEVEN +1D370 ; [*158C.0020.0002.1D370] # COUNTING ROD TENS DIGIT EIGHT +1D371 ; [*158D.0020.0002.1D371] # COUNTING ROD TENS DIGIT NINE +1D6C1 ; [*0592.0020.0005.1D6C1] # MATHEMATICAL BOLD NABLA +1D6DB ; [*058E.0020.0005.1D6DB] # MATHEMATICAL BOLD PARTIAL DIFFERENTIAL +1D6FB ; [*0592.0020.0005.1D6FB] # MATHEMATICAL ITALIC NABLA +1D715 ; [*058E.0020.0005.1D715] # MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL +1D735 ; [*0592.0020.0005.1D735] # MATHEMATICAL BOLD ITALIC NABLA +1D74F ; [*058E.0020.0005.1D74F] # MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL +1D76F ; [*0592.0020.0005.1D76F] # MATHEMATICAL SANS-SERIF BOLD NABLA +1D789 ; [*058E.0020.0005.1D789] # MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL +1D7A9 ; [*0592.0020.0005.1D7A9] # MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA +1D7C3 ; [*058E.0020.0005.1D7C3] # MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL +1EEF0 ; [*0485.0020.0002.1EEF0] # ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL +1EEF1 ; [*0486.0020.0002.1EEF1] # ARABIC MATHEMATICAL OPERATOR HAH WITH DAL +1F000 ; [*109D.0020.0002.1F000] # MAHJONG TILE EAST WIND +1F001 ; [*109E.0020.0002.1F001] # MAHJONG TILE SOUTH WIND +1F002 ; [*109F.0020.0002.1F002] # MAHJONG TILE WEST WIND +1F003 ; [*10A0.0020.0002.1F003] # MAHJONG TILE NORTH WIND +1F004 ; [*10A1.0020.0002.1F004] # MAHJONG TILE RED DRAGON +1F005 ; [*10A2.0020.0002.1F005] # MAHJONG TILE GREEN DRAGON +1F006 ; [*10A3.0020.0002.1F006] # MAHJONG TILE WHITE DRAGON +1F007 ; [*10A4.0020.0002.1F007] # MAHJONG TILE ONE OF CHARACTERS +1F008 ; [*10A5.0020.0002.1F008] # MAHJONG TILE TWO OF CHARACTERS +1F009 ; [*10A6.0020.0002.1F009] # MAHJONG TILE THREE OF CHARACTERS +1F00A ; [*10A7.0020.0002.1F00A] # MAHJONG TILE FOUR OF CHARACTERS +1F00B ; [*10A8.0020.0002.1F00B] # MAHJONG TILE FIVE OF CHARACTERS +1F00C ; [*10A9.0020.0002.1F00C] # MAHJONG TILE SIX OF CHARACTERS +1F00D ; [*10AA.0020.0002.1F00D] # MAHJONG TILE SEVEN OF CHARACTERS +1F00E ; [*10AB.0020.0002.1F00E] # MAHJONG TILE EIGHT OF CHARACTERS +1F00F ; [*10AC.0020.0002.1F00F] # MAHJONG TILE NINE OF CHARACTERS +1F010 ; [*10AD.0020.0002.1F010] # MAHJONG TILE ONE OF BAMBOOS +1F011 ; [*10AE.0020.0002.1F011] # MAHJONG TILE TWO OF BAMBOOS +1F012 ; [*10AF.0020.0002.1F012] # MAHJONG TILE THREE OF BAMBOOS +1F013 ; [*10B0.0020.0002.1F013] # MAHJONG TILE FOUR OF BAMBOOS +1F014 ; [*10B1.0020.0002.1F014] # MAHJONG TILE FIVE OF BAMBOOS +1F015 ; [*10B2.0020.0002.1F015] # MAHJONG TILE SIX OF BAMBOOS +1F016 ; [*10B3.0020.0002.1F016] # MAHJONG TILE SEVEN OF BAMBOOS +1F017 ; [*10B4.0020.0002.1F017] # MAHJONG TILE EIGHT OF BAMBOOS +1F018 ; [*10B5.0020.0002.1F018] # MAHJONG TILE NINE OF BAMBOOS +1F019 ; [*10B6.0020.0002.1F019] # MAHJONG TILE ONE OF CIRCLES +1F01A ; [*10B7.0020.0002.1F01A] # MAHJONG TILE TWO OF CIRCLES +1F01B ; [*10B8.0020.0002.1F01B] # MAHJONG TILE THREE OF CIRCLES +1F01C ; [*10B9.0020.0002.1F01C] # MAHJONG TILE FOUR OF CIRCLES +1F01D ; [*10BA.0020.0002.1F01D] # MAHJONG TILE FIVE OF CIRCLES +1F01E ; [*10BB.0020.0002.1F01E] # MAHJONG TILE SIX OF CIRCLES +1F01F ; [*10BC.0020.0002.1F01F] # MAHJONG TILE SEVEN OF CIRCLES +1F020 ; [*10BD.0020.0002.1F020] # MAHJONG TILE EIGHT OF CIRCLES +1F021 ; [*10BE.0020.0002.1F021] # MAHJONG TILE NINE OF CIRCLES +1F022 ; [*10BF.0020.0002.1F022] # MAHJONG TILE PLUM +1F023 ; [*10C0.0020.0002.1F023] # MAHJONG TILE ORCHID +1F024 ; [*10C1.0020.0002.1F024] # MAHJONG TILE BAMBOO +1F025 ; [*10C2.0020.0002.1F025] # MAHJONG TILE CHRYSANTHEMUM +1F026 ; [*10C3.0020.0002.1F026] # MAHJONG TILE SPRING +1F027 ; [*10C4.0020.0002.1F027] # MAHJONG TILE SUMMER +1F028 ; [*10C5.0020.0002.1F028] # MAHJONG TILE AUTUMN +1F029 ; [*10C6.0020.0002.1F029] # MAHJONG TILE WINTER +1F02A ; [*10C7.0020.0002.1F02A] # MAHJONG TILE JOKER +1F02B ; [*10C8.0020.0002.1F02B] # MAHJONG TILE BACK +1F030 ; [*10C9.0020.0002.1F030] # DOMINO TILE HORIZONTAL BACK +1F031 ; [*10CA.0020.0002.1F031] # DOMINO TILE HORIZONTAL-00-00 +1F032 ; [*10CB.0020.0002.1F032] # DOMINO TILE HORIZONTAL-00-01 +1F033 ; [*10CC.0020.0002.1F033] # DOMINO TILE HORIZONTAL-00-02 +1F034 ; [*10CD.0020.0002.1F034] # DOMINO TILE HORIZONTAL-00-03 +1F035 ; [*10CE.0020.0002.1F035] # DOMINO TILE HORIZONTAL-00-04 +1F036 ; [*10CF.0020.0002.1F036] # DOMINO TILE HORIZONTAL-00-05 +1F037 ; [*10D0.0020.0002.1F037] # DOMINO TILE HORIZONTAL-00-06 +1F038 ; [*10D1.0020.0002.1F038] # DOMINO TILE HORIZONTAL-01-00 +1F039 ; [*10D2.0020.0002.1F039] # DOMINO TILE HORIZONTAL-01-01 +1F03A ; [*10D3.0020.0002.1F03A] # DOMINO TILE HORIZONTAL-01-02 +1F03B ; [*10D4.0020.0002.1F03B] # DOMINO TILE HORIZONTAL-01-03 +1F03C ; [*10D5.0020.0002.1F03C] # DOMINO TILE HORIZONTAL-01-04 +1F03D ; [*10D6.0020.0002.1F03D] # DOMINO TILE HORIZONTAL-01-05 +1F03E ; [*10D7.0020.0002.1F03E] # DOMINO TILE HORIZONTAL-01-06 +1F03F ; [*10D8.0020.0002.1F03F] # DOMINO TILE HORIZONTAL-02-00 +1F040 ; [*10D9.0020.0002.1F040] # DOMINO TILE HORIZONTAL-02-01 +1F041 ; [*10DA.0020.0002.1F041] # DOMINO TILE HORIZONTAL-02-02 +1F042 ; [*10DB.0020.0002.1F042] # DOMINO TILE HORIZONTAL-02-03 +1F043 ; [*10DC.0020.0002.1F043] # DOMINO TILE HORIZONTAL-02-04 +1F044 ; [*10DD.0020.0002.1F044] # DOMINO TILE HORIZONTAL-02-05 +1F045 ; [*10DE.0020.0002.1F045] # DOMINO TILE HORIZONTAL-02-06 +1F046 ; [*10DF.0020.0002.1F046] # DOMINO TILE HORIZONTAL-03-00 +1F047 ; [*10E0.0020.0002.1F047] # DOMINO TILE HORIZONTAL-03-01 +1F048 ; [*10E1.0020.0002.1F048] # DOMINO TILE HORIZONTAL-03-02 +1F049 ; [*10E2.0020.0002.1F049] # DOMINO TILE HORIZONTAL-03-03 +1F04A ; [*10E3.0020.0002.1F04A] # DOMINO TILE HORIZONTAL-03-04 +1F04B ; [*10E4.0020.0002.1F04B] # DOMINO TILE HORIZONTAL-03-05 +1F04C ; [*10E5.0020.0002.1F04C] # DOMINO TILE HORIZONTAL-03-06 +1F04D ; [*10E6.0020.0002.1F04D] # DOMINO TILE HORIZONTAL-04-00 +1F04E ; [*10E7.0020.0002.1F04E] # DOMINO TILE HORIZONTAL-04-01 +1F04F ; [*10E8.0020.0002.1F04F] # DOMINO TILE HORIZONTAL-04-02 +1F050 ; [*10E9.0020.0002.1F050] # DOMINO TILE HORIZONTAL-04-03 +1F051 ; [*10EA.0020.0002.1F051] # DOMINO TILE HORIZONTAL-04-04 +1F052 ; [*10EB.0020.0002.1F052] # DOMINO TILE HORIZONTAL-04-05 +1F053 ; [*10EC.0020.0002.1F053] # DOMINO TILE HORIZONTAL-04-06 +1F054 ; [*10ED.0020.0002.1F054] # DOMINO TILE HORIZONTAL-05-00 +1F055 ; [*10EE.0020.0002.1F055] # DOMINO TILE HORIZONTAL-05-01 +1F056 ; [*10EF.0020.0002.1F056] # DOMINO TILE HORIZONTAL-05-02 +1F057 ; [*10F0.0020.0002.1F057] # DOMINO TILE HORIZONTAL-05-03 +1F058 ; [*10F1.0020.0002.1F058] # DOMINO TILE HORIZONTAL-05-04 +1F059 ; [*10F2.0020.0002.1F059] # DOMINO TILE HORIZONTAL-05-05 +1F05A ; [*10F3.0020.0002.1F05A] # DOMINO TILE HORIZONTAL-05-06 +1F05B ; [*10F4.0020.0002.1F05B] # DOMINO TILE HORIZONTAL-06-00 +1F05C ; [*10F5.0020.0002.1F05C] # DOMINO TILE HORIZONTAL-06-01 +1F05D ; [*10F6.0020.0002.1F05D] # DOMINO TILE HORIZONTAL-06-02 +1F05E ; [*10F7.0020.0002.1F05E] # DOMINO TILE HORIZONTAL-06-03 +1F05F ; [*10F8.0020.0002.1F05F] # DOMINO TILE HORIZONTAL-06-04 +1F060 ; [*10F9.0020.0002.1F060] # DOMINO TILE HORIZONTAL-06-05 +1F061 ; [*10FA.0020.0002.1F061] # DOMINO TILE HORIZONTAL-06-06 +1F062 ; [*10FB.0020.0002.1F062] # DOMINO TILE VERTICAL BACK +1F063 ; [*10FC.0020.0002.1F063] # DOMINO TILE VERTICAL-00-00 +1F064 ; [*10FD.0020.0002.1F064] # DOMINO TILE VERTICAL-00-01 +1F065 ; [*10FE.0020.0002.1F065] # DOMINO TILE VERTICAL-00-02 +1F066 ; [*10FF.0020.0002.1F066] # DOMINO TILE VERTICAL-00-03 +1F067 ; [*1100.0020.0002.1F067] # DOMINO TILE VERTICAL-00-04 +1F068 ; [*1101.0020.0002.1F068] # DOMINO TILE VERTICAL-00-05 +1F069 ; [*1102.0020.0002.1F069] # DOMINO TILE VERTICAL-00-06 +1F06A ; [*1103.0020.0002.1F06A] # DOMINO TILE VERTICAL-01-00 +1F06B ; [*1104.0020.0002.1F06B] # DOMINO TILE VERTICAL-01-01 +1F06C ; [*1105.0020.0002.1F06C] # DOMINO TILE VERTICAL-01-02 +1F06D ; [*1106.0020.0002.1F06D] # DOMINO TILE VERTICAL-01-03 +1F06E ; [*1107.0020.0002.1F06E] # DOMINO TILE VERTICAL-01-04 +1F06F ; [*1108.0020.0002.1F06F] # DOMINO TILE VERTICAL-01-05 +1F070 ; [*1109.0020.0002.1F070] # DOMINO TILE VERTICAL-01-06 +1F071 ; [*110A.0020.0002.1F071] # DOMINO TILE VERTICAL-02-00 +1F072 ; [*110B.0020.0002.1F072] # DOMINO TILE VERTICAL-02-01 +1F073 ; [*110C.0020.0002.1F073] # DOMINO TILE VERTICAL-02-02 +1F074 ; [*110D.0020.0002.1F074] # DOMINO TILE VERTICAL-02-03 +1F075 ; [*110E.0020.0002.1F075] # DOMINO TILE VERTICAL-02-04 +1F076 ; [*110F.0020.0002.1F076] # DOMINO TILE VERTICAL-02-05 +1F077 ; [*1110.0020.0002.1F077] # DOMINO TILE VERTICAL-02-06 +1F078 ; [*1111.0020.0002.1F078] # DOMINO TILE VERTICAL-03-00 +1F079 ; [*1112.0020.0002.1F079] # DOMINO TILE VERTICAL-03-01 +1F07A ; [*1113.0020.0002.1F07A] # DOMINO TILE VERTICAL-03-02 +1F07B ; [*1114.0020.0002.1F07B] # DOMINO TILE VERTICAL-03-03 +1F07C ; [*1115.0020.0002.1F07C] # DOMINO TILE VERTICAL-03-04 +1F07D ; [*1116.0020.0002.1F07D] # DOMINO TILE VERTICAL-03-05 +1F07E ; [*1117.0020.0002.1F07E] # DOMINO TILE VERTICAL-03-06 +1F07F ; [*1118.0020.0002.1F07F] # DOMINO TILE VERTICAL-04-00 +1F080 ; [*1119.0020.0002.1F080] # DOMINO TILE VERTICAL-04-01 +1F081 ; [*111A.0020.0002.1F081] # DOMINO TILE VERTICAL-04-02 +1F082 ; [*111B.0020.0002.1F082] # DOMINO TILE VERTICAL-04-03 +1F083 ; [*111C.0020.0002.1F083] # DOMINO TILE VERTICAL-04-04 +1F084 ; [*111D.0020.0002.1F084] # DOMINO TILE VERTICAL-04-05 +1F085 ; [*111E.0020.0002.1F085] # DOMINO TILE VERTICAL-04-06 +1F086 ; [*111F.0020.0002.1F086] # DOMINO TILE VERTICAL-05-00 +1F087 ; [*1120.0020.0002.1F087] # DOMINO TILE VERTICAL-05-01 +1F088 ; [*1121.0020.0002.1F088] # DOMINO TILE VERTICAL-05-02 +1F089 ; [*1122.0020.0002.1F089] # DOMINO TILE VERTICAL-05-03 +1F08A ; [*1123.0020.0002.1F08A] # DOMINO TILE VERTICAL-05-04 +1F08B ; [*1124.0020.0002.1F08B] # DOMINO TILE VERTICAL-05-05 +1F08C ; [*1125.0020.0002.1F08C] # DOMINO TILE VERTICAL-05-06 +1F08D ; [*1126.0020.0002.1F08D] # DOMINO TILE VERTICAL-06-00 +1F08E ; [*1127.0020.0002.1F08E] # DOMINO TILE VERTICAL-06-01 +1F08F ; [*1128.0020.0002.1F08F] # DOMINO TILE VERTICAL-06-02 +1F090 ; [*1129.0020.0002.1F090] # DOMINO TILE VERTICAL-06-03 +1F091 ; [*112A.0020.0002.1F091] # DOMINO TILE VERTICAL-06-04 +1F092 ; [*112B.0020.0002.1F092] # DOMINO TILE VERTICAL-06-05 +1F093 ; [*112C.0020.0002.1F093] # DOMINO TILE VERTICAL-06-06 +1F0A0 ; [*112D.0020.0002.1F0A0] # PLAYING CARD BACK +1F0A1 ; [*112E.0020.0002.1F0A1] # PLAYING CARD ACE OF SPADES +1F0A2 ; [*112F.0020.0002.1F0A2] # PLAYING CARD TWO OF SPADES +1F0A3 ; [*1130.0020.0002.1F0A3] # PLAYING CARD THREE OF SPADES +1F0A4 ; [*1131.0020.0002.1F0A4] # PLAYING CARD FOUR OF SPADES +1F0A5 ; [*1132.0020.0002.1F0A5] # PLAYING CARD FIVE OF SPADES +1F0A6 ; [*1133.0020.0002.1F0A6] # PLAYING CARD SIX OF SPADES +1F0A7 ; [*1134.0020.0002.1F0A7] # PLAYING CARD SEVEN OF SPADES +1F0A8 ; [*1135.0020.0002.1F0A8] # PLAYING CARD EIGHT OF SPADES +1F0A9 ; [*1136.0020.0002.1F0A9] # PLAYING CARD NINE OF SPADES +1F0AA ; [*1137.0020.0002.1F0AA] # PLAYING CARD TEN OF SPADES +1F0AB ; [*1138.0020.0002.1F0AB] # PLAYING CARD JACK OF SPADES +1F0AC ; [*1139.0020.0002.1F0AC] # PLAYING CARD KNIGHT OF SPADES +1F0AD ; [*113A.0020.0002.1F0AD] # PLAYING CARD QUEEN OF SPADES +1F0AE ; [*113B.0020.0002.1F0AE] # PLAYING CARD KING OF SPADES +1F0B1 ; [*113C.0020.0002.1F0B1] # PLAYING CARD ACE OF HEARTS +1F0B2 ; [*113D.0020.0002.1F0B2] # PLAYING CARD TWO OF HEARTS +1F0B3 ; [*113E.0020.0002.1F0B3] # PLAYING CARD THREE OF HEARTS +1F0B4 ; [*113F.0020.0002.1F0B4] # PLAYING CARD FOUR OF HEARTS +1F0B5 ; [*1140.0020.0002.1F0B5] # PLAYING CARD FIVE OF HEARTS +1F0B6 ; [*1141.0020.0002.1F0B6] # PLAYING CARD SIX OF HEARTS +1F0B7 ; [*1142.0020.0002.1F0B7] # PLAYING CARD SEVEN OF HEARTS +1F0B8 ; [*1143.0020.0002.1F0B8] # PLAYING CARD EIGHT OF HEARTS +1F0B9 ; [*1144.0020.0002.1F0B9] # PLAYING CARD NINE OF HEARTS +1F0BA ; [*1145.0020.0002.1F0BA] # PLAYING CARD TEN OF HEARTS +1F0BB ; [*1146.0020.0002.1F0BB] # PLAYING CARD JACK OF HEARTS +1F0BC ; [*1147.0020.0002.1F0BC] # PLAYING CARD KNIGHT OF HEARTS +1F0BD ; [*1148.0020.0002.1F0BD] # PLAYING CARD QUEEN OF HEARTS +1F0BE ; [*1149.0020.0002.1F0BE] # PLAYING CARD KING OF HEARTS +1F0C1 ; [*114A.0020.0002.1F0C1] # PLAYING CARD ACE OF DIAMONDS +1F0C2 ; [*114B.0020.0002.1F0C2] # PLAYING CARD TWO OF DIAMONDS +1F0C3 ; [*114C.0020.0002.1F0C3] # PLAYING CARD THREE OF DIAMONDS +1F0C4 ; [*114D.0020.0002.1F0C4] # PLAYING CARD FOUR OF DIAMONDS +1F0C5 ; [*114E.0020.0002.1F0C5] # PLAYING CARD FIVE OF DIAMONDS +1F0C6 ; [*114F.0020.0002.1F0C6] # PLAYING CARD SIX OF DIAMONDS +1F0C7 ; [*1150.0020.0002.1F0C7] # PLAYING CARD SEVEN OF DIAMONDS +1F0C8 ; [*1151.0020.0002.1F0C8] # PLAYING CARD EIGHT OF DIAMONDS +1F0C9 ; [*1152.0020.0002.1F0C9] # PLAYING CARD NINE OF DIAMONDS +1F0CA ; [*1153.0020.0002.1F0CA] # PLAYING CARD TEN OF DIAMONDS +1F0CB ; [*1154.0020.0002.1F0CB] # PLAYING CARD JACK OF DIAMONDS +1F0CC ; [*1155.0020.0002.1F0CC] # PLAYING CARD KNIGHT OF DIAMONDS +1F0CD ; [*1156.0020.0002.1F0CD] # PLAYING CARD QUEEN OF DIAMONDS +1F0CE ; [*1157.0020.0002.1F0CE] # PLAYING CARD KING OF DIAMONDS +1F0CF ; [*1158.0020.0002.1F0CF] # PLAYING CARD BLACK JOKER +1F0D1 ; [*1159.0020.0002.1F0D1] # PLAYING CARD ACE OF CLUBS +1F0D2 ; [*115A.0020.0002.1F0D2] # PLAYING CARD TWO OF CLUBS +1F0D3 ; [*115B.0020.0002.1F0D3] # PLAYING CARD THREE OF CLUBS +1F0D4 ; [*115C.0020.0002.1F0D4] # PLAYING CARD FOUR OF CLUBS +1F0D5 ; [*115D.0020.0002.1F0D5] # PLAYING CARD FIVE OF CLUBS +1F0D6 ; [*115E.0020.0002.1F0D6] # PLAYING CARD SIX OF CLUBS +1F0D7 ; [*115F.0020.0002.1F0D7] # PLAYING CARD SEVEN OF CLUBS +1F0D8 ; [*1160.0020.0002.1F0D8] # PLAYING CARD EIGHT OF CLUBS +1F0D9 ; [*1161.0020.0002.1F0D9] # PLAYING CARD NINE OF CLUBS +1F0DA ; [*1162.0020.0002.1F0DA] # PLAYING CARD TEN OF CLUBS +1F0DB ; [*1163.0020.0002.1F0DB] # PLAYING CARD JACK OF CLUBS +1F0DC ; [*1164.0020.0002.1F0DC] # PLAYING CARD KNIGHT OF CLUBS +1F0DD ; [*1165.0020.0002.1F0DD] # PLAYING CARD QUEEN OF CLUBS +1F0DE ; [*1166.0020.0002.1F0DE] # PLAYING CARD KING OF CLUBS +1F0DF ; [*1167.0020.0002.1F0DF] # PLAYING CARD WHITE JOKER +1F300 ; [*1168.0020.0002.1F300] # CYCLONE +1F301 ; [*1169.0020.0002.1F301] # FOGGY +1F302 ; [*116A.0020.0002.1F302] # CLOSED UMBRELLA +1F303 ; [*116B.0020.0002.1F303] # NIGHT WITH STARS +1F304 ; [*116C.0020.0002.1F304] # SUNRISE OVER MOUNTAINS +1F305 ; [*116D.0020.0002.1F305] # SUNRISE +1F306 ; [*116E.0020.0002.1F306] # CITYSCAPE AT DUSK +1F307 ; [*116F.0020.0002.1F307] # SUNSET OVER BUILDINGS +1F308 ; [*1170.0020.0002.1F308] # RAINBOW +1F309 ; [*1171.0020.0002.1F309] # BRIDGE AT NIGHT +1F30A ; [*1172.0020.0002.1F30A] # WATER WAVE +1F30B ; [*1173.0020.0002.1F30B] # VOLCANO +1F30C ; [*1174.0020.0002.1F30C] # MILKY WAY +1F30D ; [*1175.0020.0002.1F30D] # EARTH GLOBE EUROPE-AFRICA +1F30E ; [*1176.0020.0002.1F30E] # EARTH GLOBE AMERICAS +1F30F ; [*1177.0020.0002.1F30F] # EARTH GLOBE ASIA-AUSTRALIA +1F310 ; [*1178.0020.0002.1F310] # GLOBE WITH MERIDIANS +1F311 ; [*1179.0020.0002.1F311] # NEW MOON SYMBOL +1F312 ; [*117A.0020.0002.1F312] # WAXING CRESCENT MOON SYMBOL +1F313 ; [*117B.0020.0002.1F313] # FIRST QUARTER MOON SYMBOL +1F314 ; [*117C.0020.0002.1F314] # WAXING GIBBOUS MOON SYMBOL +1F315 ; [*117D.0020.0002.1F315] # FULL MOON SYMBOL +1F316 ; [*117E.0020.0002.1F316] # WANING GIBBOUS MOON SYMBOL +1F317 ; [*117F.0020.0002.1F317] # LAST QUARTER MOON SYMBOL +1F318 ; [*1180.0020.0002.1F318] # WANING CRESCENT MOON SYMBOL +1F319 ; [*1181.0020.0002.1F319] # CRESCENT MOON +1F31A ; [*1182.0020.0002.1F31A] # NEW MOON WITH FACE +1F31B ; [*1183.0020.0002.1F31B] # FIRST QUARTER MOON WITH FACE +1F31C ; [*1184.0020.0002.1F31C] # LAST QUARTER MOON WITH FACE +1F31D ; [*1185.0020.0002.1F31D] # FULL MOON WITH FACE +1F31E ; [*1186.0020.0002.1F31E] # SUN WITH FACE +1F31F ; [*1187.0020.0002.1F31F] # GLOWING STAR +1F320 ; [*1188.0020.0002.1F320] # SHOOTING STAR +1F330 ; [*1189.0020.0002.1F330] # CHESTNUT +1F331 ; [*118A.0020.0002.1F331] # SEEDLING +1F332 ; [*118B.0020.0002.1F332] # EVERGREEN TREE +1F333 ; [*118C.0020.0002.1F333] # DECIDUOUS TREE +1F334 ; [*118D.0020.0002.1F334] # PALM TREE +1F335 ; [*118E.0020.0002.1F335] # CACTUS +1F337 ; [*118F.0020.0002.1F337] # TULIP +1F338 ; [*1190.0020.0002.1F338] # CHERRY BLOSSOM +1F339 ; [*1191.0020.0002.1F339] # ROSE +1F33A ; [*1192.0020.0002.1F33A] # HIBISCUS +1F33B ; [*1193.0020.0002.1F33B] # SUNFLOWER +1F33C ; [*1194.0020.0002.1F33C] # BLOSSOM +1F33D ; [*1195.0020.0002.1F33D] # EAR OF MAIZE +1F33E ; [*1196.0020.0002.1F33E] # EAR OF RICE +1F33F ; [*1197.0020.0002.1F33F] # HERB +1F340 ; [*1198.0020.0002.1F340] # FOUR LEAF CLOVER +1F341 ; [*1199.0020.0002.1F341] # MAPLE LEAF +1F342 ; [*119A.0020.0002.1F342] # FALLEN LEAF +1F343 ; [*119B.0020.0002.1F343] # LEAF FLUTTERING IN WIND +1F344 ; [*119C.0020.0002.1F344] # MUSHROOM +1F345 ; [*119D.0020.0002.1F345] # TOMATO +1F346 ; [*119E.0020.0002.1F346] # AUBERGINE +1F347 ; [*119F.0020.0002.1F347] # GRAPES +1F348 ; [*11A0.0020.0002.1F348] # MELON +1F349 ; [*11A1.0020.0002.1F349] # WATERMELON +1F34A ; [*11A2.0020.0002.1F34A] # TANGERINE +1F34B ; [*11A3.0020.0002.1F34B] # LEMON +1F34C ; [*11A4.0020.0002.1F34C] # BANANA +1F34D ; [*11A5.0020.0002.1F34D] # PINEAPPLE +1F34E ; [*11A6.0020.0002.1F34E] # RED APPLE +1F34F ; [*11A7.0020.0002.1F34F] # GREEN APPLE +1F350 ; [*11A8.0020.0002.1F350] # PEAR +1F351 ; [*11A9.0020.0002.1F351] # PEACH +1F352 ; [*11AA.0020.0002.1F352] # CHERRIES +1F353 ; [*11AB.0020.0002.1F353] # STRAWBERRY +1F354 ; [*11AC.0020.0002.1F354] # HAMBURGER +1F355 ; [*11AD.0020.0002.1F355] # SLICE OF PIZZA +1F356 ; [*11AE.0020.0002.1F356] # MEAT ON BONE +1F357 ; [*11AF.0020.0002.1F357] # POULTRY LEG +1F358 ; [*11B0.0020.0002.1F358] # RICE CRACKER +1F359 ; [*11B1.0020.0002.1F359] # RICE BALL +1F35A ; [*11B2.0020.0002.1F35A] # COOKED RICE +1F35B ; [*11B3.0020.0002.1F35B] # CURRY AND RICE +1F35C ; [*11B4.0020.0002.1F35C] # STEAMING BOWL +1F35D ; [*11B5.0020.0002.1F35D] # SPAGHETTI +1F35E ; [*11B6.0020.0002.1F35E] # BREAD +1F35F ; [*11B7.0020.0002.1F35F] # FRENCH FRIES +1F360 ; [*11B8.0020.0002.1F360] # ROASTED SWEET POTATO +1F361 ; [*11B9.0020.0002.1F361] # DANGO +1F362 ; [*11BA.0020.0002.1F362] # ODEN +1F363 ; [*11BB.0020.0002.1F363] # SUSHI +1F364 ; [*11BC.0020.0002.1F364] # FRIED SHRIMP +1F365 ; [*11BD.0020.0002.1F365] # FISH CAKE WITH SWIRL DESIGN +1F366 ; [*11BE.0020.0002.1F366] # SOFT ICE CREAM +1F367 ; [*11BF.0020.0002.1F367] # SHAVED ICE +1F368 ; [*11C0.0020.0002.1F368] # ICE CREAM +1F369 ; [*11C1.0020.0002.1F369] # DOUGHNUT +1F36A ; [*11C2.0020.0002.1F36A] # COOKIE +1F36B ; [*11C3.0020.0002.1F36B] # CHOCOLATE BAR +1F36C ; [*11C4.0020.0002.1F36C] # CANDY +1F36D ; [*11C5.0020.0002.1F36D] # LOLLIPOP +1F36E ; [*11C6.0020.0002.1F36E] # CUSTARD +1F36F ; [*11C7.0020.0002.1F36F] # HONEY POT +1F370 ; [*11C8.0020.0002.1F370] # SHORTCAKE +1F371 ; [*11C9.0020.0002.1F371] # BENTO BOX +1F372 ; [*11CA.0020.0002.1F372] # POT OF FOOD +1F373 ; [*11CB.0020.0002.1F373] # COOKING +1F374 ; [*11CC.0020.0002.1F374] # FORK AND KNIFE +1F375 ; [*11CD.0020.0002.1F375] # TEACUP WITHOUT HANDLE +1F376 ; [*11CE.0020.0002.1F376] # SAKE BOTTLE AND CUP +1F377 ; [*11CF.0020.0002.1F377] # WINE GLASS +1F378 ; [*11D0.0020.0002.1F378] # COCKTAIL GLASS +1F379 ; [*11D1.0020.0002.1F379] # TROPICAL DRINK +1F37A ; [*11D2.0020.0002.1F37A] # BEER MUG +1F37B ; [*11D3.0020.0002.1F37B] # CLINKING BEER MUGS +1F37C ; [*11D4.0020.0002.1F37C] # BABY BOTTLE +1F380 ; [*11D5.0020.0002.1F380] # RIBBON +1F381 ; [*11D6.0020.0002.1F381] # WRAPPED PRESENT +1F382 ; [*11D7.0020.0002.1F382] # BIRTHDAY CAKE +1F383 ; [*11D8.0020.0002.1F383] # JACK-O-LANTERN +1F384 ; [*11D9.0020.0002.1F384] # CHRISTMAS TREE +1F385 ; [*11DA.0020.0002.1F385] # FATHER CHRISTMAS +1F386 ; [*11DB.0020.0002.1F386] # FIREWORKS +1F387 ; [*11DC.0020.0002.1F387] # FIREWORK SPARKLER +1F388 ; [*11DD.0020.0002.1F388] # BALLOON +1F389 ; [*11DE.0020.0002.1F389] # PARTY POPPER +1F38A ; [*11DF.0020.0002.1F38A] # CONFETTI BALL +1F38B ; [*11E0.0020.0002.1F38B] # TANABATA TREE +1F38C ; [*11E1.0020.0002.1F38C] # CROSSED FLAGS +1F38D ; [*11E2.0020.0002.1F38D] # PINE DECORATION +1F38E ; [*11E3.0020.0002.1F38E] # JAPANESE DOLLS +1F38F ; [*11E4.0020.0002.1F38F] # CARP STREAMER +1F390 ; [*11E5.0020.0002.1F390] # WIND CHIME +1F391 ; [*11E6.0020.0002.1F391] # MOON VIEWING CEREMONY +1F392 ; [*11E7.0020.0002.1F392] # SCHOOL SATCHEL +1F393 ; [*11E8.0020.0002.1F393] # GRADUATION CAP +1F3A0 ; [*11E9.0020.0002.1F3A0] # CAROUSEL HORSE +1F3A1 ; [*11EA.0020.0002.1F3A1] # FERRIS WHEEL +1F3A2 ; [*11EB.0020.0002.1F3A2] # ROLLER COASTER +1F3A3 ; [*11EC.0020.0002.1F3A3] # FISHING POLE AND FISH +1F3A4 ; [*11ED.0020.0002.1F3A4] # MICROPHONE +1F3A5 ; [*11EE.0020.0002.1F3A5] # MOVIE CAMERA +1F3A6 ; [*11EF.0020.0002.1F3A6] # CINEMA +1F3A7 ; [*11F0.0020.0002.1F3A7] # HEADPHONE +1F3A8 ; [*11F1.0020.0002.1F3A8] # ARTIST PALETTE +1F3A9 ; [*11F2.0020.0002.1F3A9] # TOP HAT +1F3AA ; [*11F3.0020.0002.1F3AA] # CIRCUS TENT +1F3AB ; [*11F4.0020.0002.1F3AB] # TICKET +1F3AC ; [*11F5.0020.0002.1F3AC] # CLAPPER BOARD +1F3AD ; [*11F6.0020.0002.1F3AD] # PERFORMING ARTS +1F3AE ; [*11F7.0020.0002.1F3AE] # VIDEO GAME +1F3AF ; [*11F8.0020.0002.1F3AF] # DIRECT HIT +1F3B0 ; [*11F9.0020.0002.1F3B0] # SLOT MACHINE +1F3B1 ; [*11FA.0020.0002.1F3B1] # BILLIARDS +1F3B2 ; [*11FB.0020.0002.1F3B2] # GAME DIE +1F3B3 ; [*11FC.0020.0002.1F3B3] # BOWLING +1F3B4 ; [*11FD.0020.0002.1F3B4] # FLOWER PLAYING CARDS +1F3B5 ; [*11FE.0020.0002.1F3B5] # MUSICAL NOTE +1F3B6 ; [*11FF.0020.0002.1F3B6] # MULTIPLE MUSICAL NOTES +1F3B7 ; [*1200.0020.0002.1F3B7] # SAXOPHONE +1F3B8 ; [*1201.0020.0002.1F3B8] # GUITAR +1F3B9 ; [*1202.0020.0002.1F3B9] # MUSICAL KEYBOARD +1F3BA ; [*1203.0020.0002.1F3BA] # TRUMPET +1F3BB ; [*1204.0020.0002.1F3BB] # VIOLIN +1F3BC ; [*1205.0020.0002.1F3BC] # MUSICAL SCORE +1F3BD ; [*1206.0020.0002.1F3BD] # RUNNING SHIRT WITH SASH +1F3BE ; [*1207.0020.0002.1F3BE] # TENNIS RACQUET AND BALL +1F3BF ; [*1208.0020.0002.1F3BF] # SKI AND SKI BOOT +1F3C0 ; [*1209.0020.0002.1F3C0] # BASKETBALL AND HOOP +1F3C1 ; [*120A.0020.0002.1F3C1] # CHEQUERED FLAG +1F3C2 ; [*120B.0020.0002.1F3C2] # SNOWBOARDER +1F3C3 ; [*120C.0020.0002.1F3C3] # RUNNER +1F3C4 ; [*120D.0020.0002.1F3C4] # SURFER +1F3C6 ; [*120E.0020.0002.1F3C6] # TROPHY +1F3C7 ; [*120F.0020.0002.1F3C7] # HORSE RACING +1F3C8 ; [*1210.0020.0002.1F3C8] # AMERICAN FOOTBALL +1F3C9 ; [*1211.0020.0002.1F3C9] # RUGBY FOOTBALL +1F3CA ; [*1212.0020.0002.1F3CA] # SWIMMER +1F3E0 ; [*1213.0020.0002.1F3E0] # HOUSE BUILDING +1F3E1 ; [*1214.0020.0002.1F3E1] # HOUSE WITH GARDEN +1F3E2 ; [*1215.0020.0002.1F3E2] # OFFICE BUILDING +1F3E3 ; [*1216.0020.0002.1F3E3] # JAPANESE POST OFFICE +1F3E4 ; [*1217.0020.0002.1F3E4] # EUROPEAN POST OFFICE +1F3E5 ; [*1218.0020.0002.1F3E5] # HOSPITAL +1F3E6 ; [*1219.0020.0002.1F3E6] # BANK +1F3E7 ; [*121A.0020.0002.1F3E7] # AUTOMATED TELLER MACHINE +1F3E8 ; [*121B.0020.0002.1F3E8] # HOTEL +1F3E9 ; [*121C.0020.0002.1F3E9] # LOVE HOTEL +1F3EA ; [*121D.0020.0002.1F3EA] # CONVENIENCE STORE +1F3EB ; [*121E.0020.0002.1F3EB] # SCHOOL +1F3EC ; [*121F.0020.0002.1F3EC] # DEPARTMENT STORE +1F3ED ; [*1220.0020.0002.1F3ED] # FACTORY +1F3EE ; [*1221.0020.0002.1F3EE] # IZAKAYA LANTERN +1F3EF ; [*1222.0020.0002.1F3EF] # JAPANESE CASTLE +1F3F0 ; [*1223.0020.0002.1F3F0] # EUROPEAN CASTLE +1F400 ; [*1224.0020.0002.1F400] # RAT +1F401 ; [*1225.0020.0002.1F401] # MOUSE +1F402 ; [*1226.0020.0002.1F402] # OX +1F403 ; [*1227.0020.0002.1F403] # WATER BUFFALO +1F404 ; [*1228.0020.0002.1F404] # COW +1F405 ; [*1229.0020.0002.1F405] # TIGER +1F406 ; [*122A.0020.0002.1F406] # LEOPARD +1F407 ; [*122B.0020.0002.1F407] # RABBIT +1F408 ; [*122C.0020.0002.1F408] # CAT +1F409 ; [*122D.0020.0002.1F409] # DRAGON +1F40A ; [*122E.0020.0002.1F40A] # CROCODILE +1F40B ; [*122F.0020.0002.1F40B] # WHALE +1F40C ; [*1230.0020.0002.1F40C] # SNAIL +1F40D ; [*1231.0020.0002.1F40D] # SNAKE +1F40E ; [*1232.0020.0002.1F40E] # HORSE +1F40F ; [*1233.0020.0002.1F40F] # RAM +1F410 ; [*1234.0020.0002.1F410] # GOAT +1F411 ; [*1235.0020.0002.1F411] # SHEEP +1F412 ; [*1236.0020.0002.1F412] # MONKEY +1F413 ; [*1237.0020.0002.1F413] # ROOSTER +1F414 ; [*1238.0020.0002.1F414] # CHICKEN +1F415 ; [*1239.0020.0002.1F415] # DOG +1F416 ; [*123A.0020.0002.1F416] # PIG +1F417 ; [*123B.0020.0002.1F417] # BOAR +1F418 ; [*123C.0020.0002.1F418] # ELEPHANT +1F419 ; [*123D.0020.0002.1F419] # OCTOPUS +1F41A ; [*123E.0020.0002.1F41A] # SPIRAL SHELL +1F41B ; [*123F.0020.0002.1F41B] # BUG +1F41C ; [*1240.0020.0002.1F41C] # ANT +1F41D ; [*1241.0020.0002.1F41D] # HONEYBEE +1F41E ; [*1242.0020.0002.1F41E] # LADY BEETLE +1F41F ; [*1243.0020.0002.1F41F] # FISH +1F420 ; [*1244.0020.0002.1F420] # TROPICAL FISH +1F421 ; [*1245.0020.0002.1F421] # BLOWFISH +1F422 ; [*1246.0020.0002.1F422] # TURTLE +1F423 ; [*1247.0020.0002.1F423] # HATCHING CHICK +1F424 ; [*1248.0020.0002.1F424] # BABY CHICK +1F425 ; [*1249.0020.0002.1F425] # FRONT-FACING BABY CHICK +1F426 ; [*124A.0020.0002.1F426] # BIRD +1F427 ; [*124B.0020.0002.1F427] # PENGUIN +1F428 ; [*124C.0020.0002.1F428] # KOALA +1F429 ; [*124D.0020.0002.1F429] # POODLE +1F42A ; [*124E.0020.0002.1F42A] # DROMEDARY CAMEL +1F42B ; [*124F.0020.0002.1F42B] # BACTRIAN CAMEL +1F42C ; [*1250.0020.0002.1F42C] # DOLPHIN +1F42D ; [*1251.0020.0002.1F42D] # MOUSE FACE +1F42E ; [*1252.0020.0002.1F42E] # COW FACE +1F42F ; [*1253.0020.0002.1F42F] # TIGER FACE +1F430 ; [*1254.0020.0002.1F430] # RABBIT FACE +1F431 ; [*1255.0020.0002.1F431] # CAT FACE +1F432 ; [*1256.0020.0002.1F432] # DRAGON FACE +1F433 ; [*1257.0020.0002.1F433] # SPOUTING WHALE +1F434 ; [*1258.0020.0002.1F434] # HORSE FACE +1F435 ; [*1259.0020.0002.1F435] # MONKEY FACE +1F436 ; [*125A.0020.0002.1F436] # DOG FACE +1F437 ; [*125B.0020.0002.1F437] # PIG FACE +1F438 ; [*125C.0020.0002.1F438] # FROG FACE +1F439 ; [*125D.0020.0002.1F439] # HAMSTER FACE +1F43A ; [*125E.0020.0002.1F43A] # WOLF FACE +1F43B ; [*125F.0020.0002.1F43B] # BEAR FACE +1F43C ; [*1260.0020.0002.1F43C] # PANDA FACE +1F43D ; [*1261.0020.0002.1F43D] # PIG NOSE +1F43E ; [*1262.0020.0002.1F43E] # PAW PRINTS +1F440 ; [*1263.0020.0002.1F440] # EYES +1F442 ; [*1264.0020.0002.1F442] # EAR +1F443 ; [*1265.0020.0002.1F443] # NOSE +1F444 ; [*1266.0020.0002.1F444] # MOUTH +1F445 ; [*1267.0020.0002.1F445] # TONGUE +1F446 ; [*1268.0020.0002.1F446] # WHITE UP POINTING BACKHAND INDEX +1F447 ; [*1269.0020.0002.1F447] # WHITE DOWN POINTING BACKHAND INDEX +1F448 ; [*126A.0020.0002.1F448] # WHITE LEFT POINTING BACKHAND INDEX +1F449 ; [*126B.0020.0002.1F449] # WHITE RIGHT POINTING BACKHAND INDEX +1F44A ; [*126C.0020.0002.1F44A] # FISTED HAND SIGN +1F44B ; [*126D.0020.0002.1F44B] # WAVING HAND SIGN +1F44C ; [*126E.0020.0002.1F44C] # OK HAND SIGN +1F44D ; [*126F.0020.0002.1F44D] # THUMBS UP SIGN +1F44E ; [*1270.0020.0002.1F44E] # THUMBS DOWN SIGN +1F44F ; [*1271.0020.0002.1F44F] # CLAPPING HANDS SIGN +1F450 ; [*1272.0020.0002.1F450] # OPEN HANDS SIGN +1F451 ; [*1273.0020.0002.1F451] # CROWN +1F452 ; [*1274.0020.0002.1F452] # WOMANS HAT +1F453 ; [*1275.0020.0002.1F453] # EYEGLASSES +1F454 ; [*1276.0020.0002.1F454] # NECKTIE +1F455 ; [*1277.0020.0002.1F455] # T-SHIRT +1F456 ; [*1278.0020.0002.1F456] # JEANS +1F457 ; [*1279.0020.0002.1F457] # DRESS +1F458 ; [*127A.0020.0002.1F458] # KIMONO +1F459 ; [*127B.0020.0002.1F459] # BIKINI +1F45A ; [*127C.0020.0002.1F45A] # WOMANS CLOTHES +1F45B ; [*127D.0020.0002.1F45B] # PURSE +1F45C ; [*127E.0020.0002.1F45C] # HANDBAG +1F45D ; [*127F.0020.0002.1F45D] # POUCH +1F45E ; [*1280.0020.0002.1F45E] # MANS SHOE +1F45F ; [*1281.0020.0002.1F45F] # ATHLETIC SHOE +1F460 ; [*1282.0020.0002.1F460] # HIGH-HEELED SHOE +1F461 ; [*1283.0020.0002.1F461] # WOMANS SANDAL +1F462 ; [*1284.0020.0002.1F462] # WOMANS BOOTS +1F463 ; [*1285.0020.0002.1F463] # FOOTPRINTS +1F464 ; [*1286.0020.0002.1F464] # BUST IN SILHOUETTE +1F465 ; [*1287.0020.0002.1F465] # BUSTS IN SILHOUETTE +1F466 ; [*1288.0020.0002.1F466] # BOY +1F467 ; [*1289.0020.0002.1F467] # GIRL +1F468 ; [*128A.0020.0002.1F468] # MAN +1F469 ; [*128B.0020.0002.1F469] # WOMAN +1F46A ; [*128C.0020.0002.1F46A] # FAMILY +1F46B ; [*128D.0020.0002.1F46B] # MAN AND WOMAN HOLDING HANDS +1F46C ; [*128E.0020.0002.1F46C] # TWO MEN HOLDING HANDS +1F46D ; [*128F.0020.0002.1F46D] # TWO WOMEN HOLDING HANDS +1F46E ; [*1290.0020.0002.1F46E] # POLICE OFFICER +1F46F ; [*1291.0020.0002.1F46F] # WOMAN WITH BUNNY EARS +1F470 ; [*1292.0020.0002.1F470] # BRIDE WITH VEIL +1F471 ; [*1293.0020.0002.1F471] # PERSON WITH BLOND HAIR +1F472 ; [*1294.0020.0002.1F472] # MAN WITH GUA PI MAO +1F473 ; [*1295.0020.0002.1F473] # MAN WITH TURBAN +1F474 ; [*1296.0020.0002.1F474] # OLDER MAN +1F475 ; [*1297.0020.0002.1F475] # OLDER WOMAN +1F476 ; [*1298.0020.0002.1F476] # BABY +1F477 ; [*1299.0020.0002.1F477] # CONSTRUCTION WORKER +1F478 ; [*129A.0020.0002.1F478] # PRINCESS +1F479 ; [*129B.0020.0002.1F479] # JAPANESE OGRE +1F47A ; [*129C.0020.0002.1F47A] # JAPANESE GOBLIN +1F47B ; [*129D.0020.0002.1F47B] # GHOST +1F47C ; [*129E.0020.0002.1F47C] # BABY ANGEL +1F47D ; [*129F.0020.0002.1F47D] # EXTRATERRESTRIAL ALIEN +1F47E ; [*12A0.0020.0002.1F47E] # ALIEN MONSTER +1F47F ; [*12A1.0020.0002.1F47F] # IMP +1F480 ; [*12A2.0020.0002.1F480] # SKULL +1F481 ; [*12A3.0020.0002.1F481] # INFORMATION DESK PERSON +1F482 ; [*12A4.0020.0002.1F482] # GUARDSMAN +1F483 ; [*12A5.0020.0002.1F483] # DANCER +1F484 ; [*12A6.0020.0002.1F484] # LIPSTICK +1F485 ; [*12A7.0020.0002.1F485] # NAIL POLISH +1F486 ; [*12A8.0020.0002.1F486] # FACE MASSAGE +1F487 ; [*12A9.0020.0002.1F487] # HAIRCUT +1F488 ; [*12AA.0020.0002.1F488] # BARBER POLE +1F489 ; [*12AB.0020.0002.1F489] # SYRINGE +1F48A ; [*12AC.0020.0002.1F48A] # PILL +1F48B ; [*12AD.0020.0002.1F48B] # KISS MARK +1F48C ; [*12AE.0020.0002.1F48C] # LOVE LETTER +1F48D ; [*12AF.0020.0002.1F48D] # RING +1F48E ; [*12B0.0020.0002.1F48E] # GEM STONE +1F48F ; [*12B1.0020.0002.1F48F] # KISS +1F490 ; [*12B2.0020.0002.1F490] # BOUQUET +1F491 ; [*12B3.0020.0002.1F491] # COUPLE WITH HEART +1F492 ; [*12B4.0020.0002.1F492] # WEDDING +1F493 ; [*12B5.0020.0002.1F493] # BEATING HEART +1F494 ; [*12B6.0020.0002.1F494] # BROKEN HEART +1F495 ; [*12B7.0020.0002.1F495] # TWO HEARTS +1F496 ; [*12B8.0020.0002.1F496] # SPARKLING HEART +1F497 ; [*12B9.0020.0002.1F497] # GROWING HEART +1F498 ; [*12BA.0020.0002.1F498] # HEART WITH ARROW +1F499 ; [*12BB.0020.0002.1F499] # BLUE HEART +1F49A ; [*12BC.0020.0002.1F49A] # GREEN HEART +1F49B ; [*12BD.0020.0002.1F49B] # YELLOW HEART +1F49C ; [*12BE.0020.0002.1F49C] # PURPLE HEART +1F49D ; [*12BF.0020.0002.1F49D] # HEART WITH RIBBON +1F49E ; [*12C0.0020.0002.1F49E] # REVOLVING HEARTS +1F49F ; [*12C1.0020.0002.1F49F] # HEART DECORATION +1F4A0 ; [*12C2.0020.0002.1F4A0] # DIAMOND SHAPE WITH A DOT INSIDE +1F4A1 ; [*12C3.0020.0002.1F4A1] # ELECTRIC LIGHT BULB +1F4A2 ; [*12C4.0020.0002.1F4A2] # ANGER SYMBOL +1F4A3 ; [*12C5.0020.0002.1F4A3] # BOMB +1F4A4 ; [*12C6.0020.0002.1F4A4] # SLEEPING SYMBOL +1F4A5 ; [*12C7.0020.0002.1F4A5] # COLLISION SYMBOL +1F4A6 ; [*12C8.0020.0002.1F4A6] # SPLASHING SWEAT SYMBOL +1F4A7 ; [*12C9.0020.0002.1F4A7] # DROPLET +1F4A8 ; [*12CA.0020.0002.1F4A8] # DASH SYMBOL +1F4A9 ; [*12CB.0020.0002.1F4A9] # PILE OF POO +1F4AA ; [*12CC.0020.0002.1F4AA] # FLEXED BICEPS +1F4AB ; [*12CD.0020.0002.1F4AB] # DIZZY SYMBOL +1F4AC ; [*12CE.0020.0002.1F4AC] # SPEECH BALLOON +1F4AD ; [*12CF.0020.0002.1F4AD] # THOUGHT BALLOON +1F4AE ; [*12D0.0020.0002.1F4AE] # WHITE FLOWER +1F4AF ; [*12D1.0020.0002.1F4AF] # HUNDRED POINTS SYMBOL +1F4B0 ; [*12D2.0020.0002.1F4B0] # MONEY BAG +1F4B1 ; [*12D3.0020.0002.1F4B1] # CURRENCY EXCHANGE +1F4B2 ; [*12D4.0020.0002.1F4B2] # HEAVY DOLLAR SIGN +1F4B3 ; [*12D5.0020.0002.1F4B3] # CREDIT CARD +1F4B4 ; [*12D6.0020.0002.1F4B4] # BANKNOTE WITH YEN SIGN +1F4B5 ; [*12D7.0020.0002.1F4B5] # BANKNOTE WITH DOLLAR SIGN +1F4B6 ; [*12D8.0020.0002.1F4B6] # BANKNOTE WITH EURO SIGN +1F4B7 ; [*12D9.0020.0002.1F4B7] # BANKNOTE WITH POUND SIGN +1F4B8 ; [*12DA.0020.0002.1F4B8] # MONEY WITH WINGS +1F4B9 ; [*12DB.0020.0002.1F4B9] # CHART WITH UPWARDS TREND AND YEN SIGN +1F4BA ; [*12DC.0020.0002.1F4BA] # SEAT +1F4BB ; [*12DD.0020.0002.1F4BB] # PERSONAL COMPUTER +1F4BC ; [*12DE.0020.0002.1F4BC] # BRIEFCASE +1F4BD ; [*12DF.0020.0002.1F4BD] # MINIDISC +1F4BE ; [*12E0.0020.0002.1F4BE] # FLOPPY DISK +1F4BF ; [*12E1.0020.0002.1F4BF] # OPTICAL DISC +1F4C0 ; [*12E2.0020.0002.1F4C0] # DVD +1F4C1 ; [*12E3.0020.0002.1F4C1] # FILE FOLDER +1F4C2 ; [*12E4.0020.0002.1F4C2] # OPEN FILE FOLDER +1F4C3 ; [*12E5.0020.0002.1F4C3] # PAGE WITH CURL +1F4C4 ; [*12E6.0020.0002.1F4C4] # PAGE FACING UP +1F4C5 ; [*12E7.0020.0002.1F4C5] # CALENDAR +1F4C6 ; [*12E8.0020.0002.1F4C6] # TEAR-OFF CALENDAR +1F4C7 ; [*12E9.0020.0002.1F4C7] # CARD INDEX +1F4C8 ; [*12EA.0020.0002.1F4C8] # CHART WITH UPWARDS TREND +1F4C9 ; [*12EB.0020.0002.1F4C9] # CHART WITH DOWNWARDS TREND +1F4CA ; [*12EC.0020.0002.1F4CA] # BAR CHART +1F4CB ; [*12ED.0020.0002.1F4CB] # CLIPBOARD +1F4CC ; [*12EE.0020.0002.1F4CC] # PUSHPIN +1F4CD ; [*12EF.0020.0002.1F4CD] # ROUND PUSHPIN +1F4CE ; [*12F0.0020.0002.1F4CE] # PAPERCLIP +1F4CF ; [*12F1.0020.0002.1F4CF] # STRAIGHT RULER +1F4D0 ; [*12F2.0020.0002.1F4D0] # TRIANGULAR RULER +1F4D1 ; [*12F3.0020.0002.1F4D1] # BOOKMARK TABS +1F4D2 ; [*12F4.0020.0002.1F4D2] # LEDGER +1F4D3 ; [*12F5.0020.0002.1F4D3] # NOTEBOOK +1F4D4 ; [*12F6.0020.0002.1F4D4] # NOTEBOOK WITH DECORATIVE COVER +1F4D5 ; [*12F7.0020.0002.1F4D5] # CLOSED BOOK +1F4D6 ; [*12F8.0020.0002.1F4D6] # OPEN BOOK +1F4D7 ; [*12F9.0020.0002.1F4D7] # GREEN BOOK +1F4D8 ; [*12FA.0020.0002.1F4D8] # BLUE BOOK +1F4D9 ; [*12FB.0020.0002.1F4D9] # ORANGE BOOK +1F4DA ; [*12FC.0020.0002.1F4DA] # BOOKS +1F4DB ; [*12FD.0020.0002.1F4DB] # NAME BADGE +1F4DC ; [*12FE.0020.0002.1F4DC] # SCROLL +1F4DD ; [*12FF.0020.0002.1F4DD] # MEMO +1F4DE ; [*1300.0020.0002.1F4DE] # TELEPHONE RECEIVER +1F4DF ; [*1301.0020.0002.1F4DF] # PAGER +1F4E0 ; [*1302.0020.0002.1F4E0] # FAX MACHINE +1F4E1 ; [*1303.0020.0002.1F4E1] # SATELLITE ANTENNA +1F4E2 ; [*1304.0020.0002.1F4E2] # PUBLIC ADDRESS LOUDSPEAKER +1F4E3 ; [*1305.0020.0002.1F4E3] # CHEERING MEGAPHONE +1F4E4 ; [*1306.0020.0002.1F4E4] # OUTBOX TRAY +1F4E5 ; [*1307.0020.0002.1F4E5] # INBOX TRAY +1F4E6 ; [*1308.0020.0002.1F4E6] # PACKAGE +1F4E7 ; [*1309.0020.0002.1F4E7] # E-MAIL SYMBOL +1F4E8 ; [*130A.0020.0002.1F4E8] # INCOMING ENVELOPE +1F4E9 ; [*130B.0020.0002.1F4E9] # ENVELOPE WITH DOWNWARDS ARROW ABOVE +1F4EA ; [*130C.0020.0002.1F4EA] # CLOSED MAILBOX WITH LOWERED FLAG +1F4EB ; [*130D.0020.0002.1F4EB] # CLOSED MAILBOX WITH RAISED FLAG +1F4EC ; [*130E.0020.0002.1F4EC] # OPEN MAILBOX WITH RAISED FLAG +1F4ED ; [*130F.0020.0002.1F4ED] # OPEN MAILBOX WITH LOWERED FLAG +1F4EE ; [*1310.0020.0002.1F4EE] # POSTBOX +1F4EF ; [*1311.0020.0002.1F4EF] # POSTAL HORN +1F4F0 ; [*1312.0020.0002.1F4F0] # NEWSPAPER +1F4F1 ; [*1313.0020.0002.1F4F1] # MOBILE PHONE +1F4F2 ; [*1314.0020.0002.1F4F2] # MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT +1F4F3 ; [*1315.0020.0002.1F4F3] # VIBRATION MODE +1F4F4 ; [*1316.0020.0002.1F4F4] # MOBILE PHONE OFF +1F4F5 ; [*1317.0020.0002.1F4F5] # NO MOBILE PHONES +1F4F6 ; [*1318.0020.0002.1F4F6] # ANTENNA WITH BARS +1F4F7 ; [*1319.0020.0002.1F4F7] # CAMERA +1F4F9 ; [*131A.0020.0002.1F4F9] # VIDEO CAMERA +1F4FA ; [*131B.0020.0002.1F4FA] # TELEVISION +1F4FB ; [*131C.0020.0002.1F4FB] # RADIO +1F4FC ; [*131D.0020.0002.1F4FC] # VIDEOCASSETTE +1F500 ; [*131E.0020.0002.1F500] # TWISTED RIGHTWARDS ARROWS +1F501 ; [*131F.0020.0002.1F501] # CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS +1F502 ; [*1320.0020.0002.1F502] # CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS WITH CIRCLED ONE OVERLAY +1F503 ; [*1321.0020.0002.1F503] # CLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS +1F504 ; [*1322.0020.0002.1F504] # ANTICLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS +1F505 ; [*1323.0020.0002.1F505] # LOW BRIGHTNESS SYMBOL +1F506 ; [*1324.0020.0002.1F506] # HIGH BRIGHTNESS SYMBOL +1F507 ; [*1325.0020.0002.1F507] # SPEAKER WITH CANCELLATION STROKE +1F508 ; [*1326.0020.0002.1F508] # SPEAKER +1F509 ; [*1327.0020.0002.1F509] # SPEAKER WITH ONE SOUND WAVE +1F50A ; [*1328.0020.0002.1F50A] # SPEAKER WITH THREE SOUND WAVES +1F50B ; [*1329.0020.0002.1F50B] # BATTERY +1F50C ; [*132A.0020.0002.1F50C] # ELECTRIC PLUG +1F50D ; [*132B.0020.0002.1F50D] # LEFT-POINTING MAGNIFYING GLASS +1F50E ; [*132C.0020.0002.1F50E] # RIGHT-POINTING MAGNIFYING GLASS +1F50F ; [*132D.0020.0002.1F50F] # LOCK WITH INK PEN +1F510 ; [*132E.0020.0002.1F510] # CLOSED LOCK WITH KEY +1F511 ; [*132F.0020.0002.1F511] # KEY +1F512 ; [*1330.0020.0002.1F512] # LOCK +1F513 ; [*1331.0020.0002.1F513] # OPEN LOCK +1F514 ; [*1332.0020.0002.1F514] # BELL +1F515 ; [*1333.0020.0002.1F515] # BELL WITH CANCELLATION STROKE +1F516 ; [*1334.0020.0002.1F516] # BOOKMARK +1F517 ; [*1335.0020.0002.1F517] # LINK SYMBOL +1F518 ; [*1336.0020.0002.1F518] # RADIO BUTTON +1F519 ; [*1337.0020.0002.1F519] # BACK WITH LEFTWARDS ARROW ABOVE +1F51A ; [*1338.0020.0002.1F51A] # END WITH LEFTWARDS ARROW ABOVE +1F51B ; [*1339.0020.0002.1F51B] # ON WITH EXCLAMATION MARK WITH LEFT RIGHT ARROW ABOVE +1F51C ; [*133A.0020.0002.1F51C] # SOON WITH RIGHTWARDS ARROW ABOVE +1F51D ; [*133B.0020.0002.1F51D] # TOP WITH UPWARDS ARROW ABOVE +1F51E ; [*133C.0020.0002.1F51E] # NO ONE UNDER EIGHTEEN SYMBOL +1F51F ; [*133D.0020.0002.1F51F] # KEYCAP TEN +1F520 ; [*133E.0020.0002.1F520] # INPUT SYMBOL FOR LATIN CAPITAL LETTERS +1F521 ; [*133F.0020.0002.1F521] # INPUT SYMBOL FOR LATIN SMALL LETTERS +1F522 ; [*1340.0020.0002.1F522] # INPUT SYMBOL FOR NUMBERS +1F523 ; [*1341.0020.0002.1F523] # INPUT SYMBOL FOR SYMBOLS +1F524 ; [*1342.0020.0002.1F524] # INPUT SYMBOL FOR LATIN LETTERS +1F525 ; [*1343.0020.0002.1F525] # FIRE +1F526 ; [*1344.0020.0002.1F526] # ELECTRIC TORCH +1F527 ; [*1345.0020.0002.1F527] # WRENCH +1F528 ; [*1346.0020.0002.1F528] # HAMMER +1F529 ; [*1347.0020.0002.1F529] # NUT AND BOLT +1F52A ; [*1348.0020.0002.1F52A] # HOCHO +1F52B ; [*1349.0020.0002.1F52B] # PISTOL +1F52C ; [*134A.0020.0002.1F52C] # MICROSCOPE +1F52D ; [*134B.0020.0002.1F52D] # TELESCOPE +1F52E ; [*134C.0020.0002.1F52E] # CRYSTAL BALL +1F52F ; [*134D.0020.0002.1F52F] # SIX POINTED STAR WITH MIDDLE DOT +1F530 ; [*134E.0020.0002.1F530] # JAPANESE SYMBOL FOR BEGINNER +1F531 ; [*134F.0020.0002.1F531] # TRIDENT EMBLEM +1F532 ; [*1350.0020.0002.1F532] # BLACK SQUARE BUTTON +1F533 ; [*1351.0020.0002.1F533] # WHITE SQUARE BUTTON +1F534 ; [*1352.0020.0002.1F534] # LARGE RED CIRCLE +1F535 ; [*1353.0020.0002.1F535] # LARGE BLUE CIRCLE +1F536 ; [*1354.0020.0002.1F536] # LARGE ORANGE DIAMOND +1F537 ; [*1355.0020.0002.1F537] # LARGE BLUE DIAMOND +1F538 ; [*1356.0020.0002.1F538] # SMALL ORANGE DIAMOND +1F539 ; [*1357.0020.0002.1F539] # SMALL BLUE DIAMOND +1F53A ; [*1358.0020.0002.1F53A] # UP-POINTING RED TRIANGLE +1F53B ; [*1359.0020.0002.1F53B] # DOWN-POINTING RED TRIANGLE +1F53C ; [*135A.0020.0002.1F53C] # UP-POINTING SMALL RED TRIANGLE +1F53D ; [*135B.0020.0002.1F53D] # DOWN-POINTING SMALL RED TRIANGLE +1F540 ; [*135C.0020.0002.1F540] # CIRCLED CROSS POMMEE +1F541 ; [*135D.0020.0002.1F541] # CROSS POMMEE WITH HALF-CIRCLE BELOW +1F542 ; [*135E.0020.0002.1F542] # CROSS POMMEE +1F543 ; [*135F.0020.0002.1F543] # NOTCHED LEFT SEMICIRCLE WITH THREE DOTS +1F550 ; [*1360.0020.0002.1F550] # CLOCK FACE ONE OCLOCK +1F551 ; [*1361.0020.0002.1F551] # CLOCK FACE TWO OCLOCK +1F552 ; [*1362.0020.0002.1F552] # CLOCK FACE THREE OCLOCK +1F553 ; [*1363.0020.0002.1F553] # CLOCK FACE FOUR OCLOCK +1F554 ; [*1364.0020.0002.1F554] # CLOCK FACE FIVE OCLOCK +1F555 ; [*1365.0020.0002.1F555] # CLOCK FACE SIX OCLOCK +1F556 ; [*1366.0020.0002.1F556] # CLOCK FACE SEVEN OCLOCK +1F557 ; [*1367.0020.0002.1F557] # CLOCK FACE EIGHT OCLOCK +1F558 ; [*1368.0020.0002.1F558] # CLOCK FACE NINE OCLOCK +1F559 ; [*1369.0020.0002.1F559] # CLOCK FACE TEN OCLOCK +1F55A ; [*136A.0020.0002.1F55A] # CLOCK FACE ELEVEN OCLOCK +1F55B ; [*136B.0020.0002.1F55B] # CLOCK FACE TWELVE OCLOCK +1F55C ; [*136C.0020.0002.1F55C] # CLOCK FACE ONE-THIRTY +1F55D ; [*136D.0020.0002.1F55D] # CLOCK FACE TWO-THIRTY +1F55E ; [*136E.0020.0002.1F55E] # CLOCK FACE THREE-THIRTY +1F55F ; [*136F.0020.0002.1F55F] # CLOCK FACE FOUR-THIRTY +1F560 ; [*1370.0020.0002.1F560] # CLOCK FACE FIVE-THIRTY +1F561 ; [*1371.0020.0002.1F561] # CLOCK FACE SIX-THIRTY +1F562 ; [*1372.0020.0002.1F562] # CLOCK FACE SEVEN-THIRTY +1F563 ; [*1373.0020.0002.1F563] # CLOCK FACE EIGHT-THIRTY +1F564 ; [*1374.0020.0002.1F564] # CLOCK FACE NINE-THIRTY +1F565 ; [*1375.0020.0002.1F565] # CLOCK FACE TEN-THIRTY +1F566 ; [*1376.0020.0002.1F566] # CLOCK FACE ELEVEN-THIRTY +1F567 ; [*1377.0020.0002.1F567] # CLOCK FACE TWELVE-THIRTY +1F5FB ; [*1378.0020.0002.1F5FB] # MOUNT FUJI +1F5FC ; [*1379.0020.0002.1F5FC] # TOKYO TOWER +1F5FD ; [*137A.0020.0002.1F5FD] # STATUE OF LIBERTY +1F5FE ; [*137B.0020.0002.1F5FE] # SILHOUETTE OF JAPAN +1F5FF ; [*137C.0020.0002.1F5FF] # MOYAI +1F600 ; [*137D.0020.0002.1F600] # GRINNING FACE +1F601 ; [*137E.0020.0002.1F601] # GRINNING FACE WITH SMILING EYES +1F602 ; [*137F.0020.0002.1F602] # FACE WITH TEARS OF JOY +1F603 ; [*1380.0020.0002.1F603] # SMILING FACE WITH OPEN MOUTH +1F604 ; [*1381.0020.0002.1F604] # SMILING FACE WITH OPEN MOUTH AND SMILING EYES +1F605 ; [*1382.0020.0002.1F605] # SMILING FACE WITH OPEN MOUTH AND COLD SWEAT +1F606 ; [*1383.0020.0002.1F606] # SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES +1F607 ; [*1384.0020.0002.1F607] # SMILING FACE WITH HALO +1F608 ; [*1385.0020.0002.1F608] # SMILING FACE WITH HORNS +1F609 ; [*1386.0020.0002.1F609] # WINKING FACE +1F60A ; [*1387.0020.0002.1F60A] # SMILING FACE WITH SMILING EYES +1F60B ; [*1388.0020.0002.1F60B] # FACE SAVOURING DELICIOUS FOOD +1F60C ; [*1389.0020.0002.1F60C] # RELIEVED FACE +1F60D ; [*138A.0020.0002.1F60D] # SMILING FACE WITH HEART-SHAPED EYES +1F60E ; [*138B.0020.0002.1F60E] # SMILING FACE WITH SUNGLASSES +1F60F ; [*138C.0020.0002.1F60F] # SMIRKING FACE +1F610 ; [*138D.0020.0002.1F610] # NEUTRAL FACE +1F611 ; [*138E.0020.0002.1F611] # EXPRESSIONLESS FACE +1F612 ; [*138F.0020.0002.1F612] # UNAMUSED FACE +1F613 ; [*1390.0020.0002.1F613] # FACE WITH COLD SWEAT +1F614 ; [*1391.0020.0002.1F614] # PENSIVE FACE +1F615 ; [*1392.0020.0002.1F615] # CONFUSED FACE +1F616 ; [*1393.0020.0002.1F616] # CONFOUNDED FACE +1F617 ; [*1394.0020.0002.1F617] # KISSING FACE +1F618 ; [*1395.0020.0002.1F618] # FACE THROWING A KISS +1F619 ; [*1396.0020.0002.1F619] # KISSING FACE WITH SMILING EYES +1F61A ; [*1397.0020.0002.1F61A] # KISSING FACE WITH CLOSED EYES +1F61B ; [*1398.0020.0002.1F61B] # FACE WITH STUCK-OUT TONGUE +1F61C ; [*1399.0020.0002.1F61C] # FACE WITH STUCK-OUT TONGUE AND WINKING EYE +1F61D ; [*139A.0020.0002.1F61D] # FACE WITH STUCK-OUT TONGUE AND TIGHTLY-CLOSED EYES +1F61E ; [*139B.0020.0002.1F61E] # DISAPPOINTED FACE +1F61F ; [*139C.0020.0002.1F61F] # WORRIED FACE +1F620 ; [*139D.0020.0002.1F620] # ANGRY FACE +1F621 ; [*139E.0020.0002.1F621] # POUTING FACE +1F622 ; [*139F.0020.0002.1F622] # CRYING FACE +1F623 ; [*13A0.0020.0002.1F623] # PERSEVERING FACE +1F624 ; [*13A1.0020.0002.1F624] # FACE WITH LOOK OF TRIUMPH +1F625 ; [*13A2.0020.0002.1F625] # DISAPPOINTED BUT RELIEVED FACE +1F626 ; [*13A3.0020.0002.1F626] # FROWNING FACE WITH OPEN MOUTH +1F627 ; [*13A4.0020.0002.1F627] # ANGUISHED FACE +1F628 ; [*13A5.0020.0002.1F628] # FEARFUL FACE +1F629 ; [*13A6.0020.0002.1F629] # WEARY FACE +1F62A ; [*13A7.0020.0002.1F62A] # SLEEPY FACE +1F62B ; [*13A8.0020.0002.1F62B] # TIRED FACE +1F62C ; [*13A9.0020.0002.1F62C] # GRIMACING FACE +1F62D ; [*13AA.0020.0002.1F62D] # LOUDLY CRYING FACE +1F62E ; [*13AB.0020.0002.1F62E] # FACE WITH OPEN MOUTH +1F62F ; [*13AC.0020.0002.1F62F] # HUSHED FACE +1F630 ; [*13AD.0020.0002.1F630] # FACE WITH OPEN MOUTH AND COLD SWEAT +1F631 ; [*13AE.0020.0002.1F631] # FACE SCREAMING IN FEAR +1F632 ; [*13AF.0020.0002.1F632] # ASTONISHED FACE +1F633 ; [*13B0.0020.0002.1F633] # FLUSHED FACE +1F634 ; [*13B1.0020.0002.1F634] # SLEEPING FACE +1F635 ; [*13B2.0020.0002.1F635] # DIZZY FACE +1F636 ; [*13B3.0020.0002.1F636] # FACE WITHOUT MOUTH +1F637 ; [*13B4.0020.0002.1F637] # FACE WITH MEDICAL MASK +1F638 ; [*13B5.0020.0002.1F638] # GRINNING CAT FACE WITH SMILING EYES +1F639 ; [*13B6.0020.0002.1F639] # CAT FACE WITH TEARS OF JOY +1F63A ; [*13B7.0020.0002.1F63A] # SMILING CAT FACE WITH OPEN MOUTH +1F63B ; [*13B8.0020.0002.1F63B] # SMILING CAT FACE WITH HEART-SHAPED EYES +1F63C ; [*13B9.0020.0002.1F63C] # CAT FACE WITH WRY SMILE +1F63D ; [*13BA.0020.0002.1F63D] # KISSING CAT FACE WITH CLOSED EYES +1F63E ; [*13BB.0020.0002.1F63E] # POUTING CAT FACE +1F63F ; [*13BC.0020.0002.1F63F] # CRYING CAT FACE +1F640 ; [*13BD.0020.0002.1F640] # WEARY CAT FACE +1F645 ; [*13BE.0020.0002.1F645] # FACE WITH NO GOOD GESTURE +1F646 ; [*13BF.0020.0002.1F646] # FACE WITH OK GESTURE +1F647 ; [*13C0.0020.0002.1F647] # PERSON BOWING DEEPLY +1F648 ; [*13C1.0020.0002.1F648] # SEE-NO-EVIL MONKEY +1F649 ; [*13C2.0020.0002.1F649] # HEAR-NO-EVIL MONKEY +1F64A ; [*13C3.0020.0002.1F64A] # SPEAK-NO-EVIL MONKEY +1F64B ; [*13C4.0020.0002.1F64B] # HAPPY PERSON RAISING ONE HAND +1F64C ; [*13C5.0020.0002.1F64C] # PERSON RAISING BOTH HANDS IN CELEBRATION +1F64D ; [*13C6.0020.0002.1F64D] # PERSON FROWNING +1F64E ; [*13C7.0020.0002.1F64E] # PERSON WITH POUTING FACE +1F64F ; [*13C8.0020.0002.1F64F] # PERSON WITH FOLDED HANDS +1F680 ; [*13C9.0020.0002.1F680] # ROCKET +1F681 ; [*13CA.0020.0002.1F681] # HELICOPTER +1F682 ; [*13CB.0020.0002.1F682] # STEAM LOCOMOTIVE +1F683 ; [*13CC.0020.0002.1F683] # RAILWAY CAR +1F684 ; [*13CD.0020.0002.1F684] # HIGH-SPEED TRAIN +1F685 ; [*13CE.0020.0002.1F685] # HIGH-SPEED TRAIN WITH BULLET NOSE +1F686 ; [*13CF.0020.0002.1F686] # TRAIN +1F687 ; [*13D0.0020.0002.1F687] # METRO +1F688 ; [*13D1.0020.0002.1F688] # LIGHT RAIL +1F689 ; [*13D2.0020.0002.1F689] # STATION +1F68A ; [*13D3.0020.0002.1F68A] # TRAM +1F68B ; [*13D4.0020.0002.1F68B] # TRAM CAR +1F68C ; [*13D5.0020.0002.1F68C] # BUS +1F68D ; [*13D6.0020.0002.1F68D] # ONCOMING BUS +1F68E ; [*13D7.0020.0002.1F68E] # TROLLEYBUS +1F68F ; [*13D8.0020.0002.1F68F] # BUS STOP +1F690 ; [*13D9.0020.0002.1F690] # MINIBUS +1F691 ; [*13DA.0020.0002.1F691] # AMBULANCE +1F692 ; [*13DB.0020.0002.1F692] # FIRE ENGINE +1F693 ; [*13DC.0020.0002.1F693] # POLICE CAR +1F694 ; [*13DD.0020.0002.1F694] # ONCOMING POLICE CAR +1F695 ; [*13DE.0020.0002.1F695] # TAXI +1F696 ; [*13DF.0020.0002.1F696] # ONCOMING TAXI +1F697 ; [*13E0.0020.0002.1F697] # AUTOMOBILE +1F698 ; [*13E1.0020.0002.1F698] # ONCOMING AUTOMOBILE +1F699 ; [*13E2.0020.0002.1F699] # RECREATIONAL VEHICLE +1F69A ; [*13E3.0020.0002.1F69A] # DELIVERY TRUCK +1F69B ; [*13E4.0020.0002.1F69B] # ARTICULATED LORRY +1F69C ; [*13E5.0020.0002.1F69C] # TRACTOR +1F69D ; [*13E6.0020.0002.1F69D] # MONORAIL +1F69E ; [*13E7.0020.0002.1F69E] # MOUNTAIN RAILWAY +1F69F ; [*13E8.0020.0002.1F69F] # SUSPENSION RAILWAY +1F6A0 ; [*13E9.0020.0002.1F6A0] # MOUNTAIN CABLEWAY +1F6A1 ; [*13EA.0020.0002.1F6A1] # AERIAL TRAMWAY +1F6A2 ; [*13EB.0020.0002.1F6A2] # SHIP +1F6A3 ; [*13EC.0020.0002.1F6A3] # ROWBOAT +1F6A4 ; [*13ED.0020.0002.1F6A4] # SPEEDBOAT +1F6A5 ; [*13EE.0020.0002.1F6A5] # HORIZONTAL TRAFFIC LIGHT +1F6A6 ; [*13EF.0020.0002.1F6A6] # VERTICAL TRAFFIC LIGHT +1F6A7 ; [*13F0.0020.0002.1F6A7] # CONSTRUCTION SIGN +1F6A8 ; [*13F1.0020.0002.1F6A8] # POLICE CARS REVOLVING LIGHT +1F6A9 ; [*13F2.0020.0002.1F6A9] # TRIANGULAR FLAG ON POST +1F6AA ; [*13F3.0020.0002.1F6AA] # DOOR +1F6AB ; [*13F4.0020.0002.1F6AB] # NO ENTRY SIGN +1F6AC ; [*13F5.0020.0002.1F6AC] # SMOKING SYMBOL +1F6AD ; [*13F6.0020.0002.1F6AD] # NO SMOKING SYMBOL +1F6AE ; [*13F7.0020.0002.1F6AE] # PUT LITTER IN ITS PLACE SYMBOL +1F6AF ; [*13F8.0020.0002.1F6AF] # DO NOT LITTER SYMBOL +1F6B0 ; [*13F9.0020.0002.1F6B0] # POTABLE WATER SYMBOL +1F6B1 ; [*13FA.0020.0002.1F6B1] # NON-POTABLE WATER SYMBOL +1F6B2 ; [*13FB.0020.0002.1F6B2] # BICYCLE +1F6B3 ; [*13FC.0020.0002.1F6B3] # NO BICYCLES +1F6B4 ; [*13FD.0020.0002.1F6B4] # BICYCLIST +1F6B5 ; [*13FE.0020.0002.1F6B5] # MOUNTAIN BICYCLIST +1F6B6 ; [*13FF.0020.0002.1F6B6] # PEDESTRIAN +1F6B7 ; [*1400.0020.0002.1F6B7] # NO PEDESTRIANS +1F6B8 ; [*1401.0020.0002.1F6B8] # CHILDREN CROSSING +1F6B9 ; [*1402.0020.0002.1F6B9] # MENS SYMBOL +1F6BA ; [*1403.0020.0002.1F6BA] # WOMENS SYMBOL +1F6BB ; [*1404.0020.0002.1F6BB] # RESTROOM +1F6BC ; [*1405.0020.0002.1F6BC] # BABY SYMBOL +1F6BD ; [*1406.0020.0002.1F6BD] # TOILET +1F6BE ; [*1407.0020.0002.1F6BE] # WATER CLOSET +1F6BF ; [*1408.0020.0002.1F6BF] # SHOWER +1F6C0 ; [*1409.0020.0002.1F6C0] # BATH +1F6C1 ; [*140A.0020.0002.1F6C1] # BATHTUB +1F6C2 ; [*140B.0020.0002.1F6C2] # PASSPORT CONTROL +1F6C3 ; [*140C.0020.0002.1F6C3] # CUSTOMS +1F6C4 ; [*140D.0020.0002.1F6C4] # BAGGAGE CLAIM +1F6C5 ; [*140E.0020.0002.1F6C5] # LEFT LUGGAGE +1F700 ; [*140F.0020.0002.1F700] # ALCHEMICAL SYMBOL FOR QUINTESSENCE +1F701 ; [*1410.0020.0002.1F701] # ALCHEMICAL SYMBOL FOR AIR +1F702 ; [*1411.0020.0002.1F702] # ALCHEMICAL SYMBOL FOR FIRE +1F703 ; [*1412.0020.0002.1F703] # ALCHEMICAL SYMBOL FOR EARTH +1F704 ; [*1413.0020.0002.1F704] # ALCHEMICAL SYMBOL FOR WATER +1F705 ; [*1414.0020.0002.1F705] # ALCHEMICAL SYMBOL FOR AQUAFORTIS +1F706 ; [*1415.0020.0002.1F706] # ALCHEMICAL SYMBOL FOR AQUA REGIA +1F707 ; [*1416.0020.0002.1F707] # ALCHEMICAL SYMBOL FOR AQUA REGIA-2 +1F708 ; [*1417.0020.0002.1F708] # ALCHEMICAL SYMBOL FOR AQUA VITAE +1F709 ; [*1418.0020.0002.1F709] # ALCHEMICAL SYMBOL FOR AQUA VITAE-2 +1F70A ; [*1419.0020.0002.1F70A] # ALCHEMICAL SYMBOL FOR VINEGAR +1F70B ; [*141A.0020.0002.1F70B] # ALCHEMICAL SYMBOL FOR VINEGAR-2 +1F70C ; [*141B.0020.0002.1F70C] # ALCHEMICAL SYMBOL FOR VINEGAR-3 +1F70D ; [*141C.0020.0002.1F70D] # ALCHEMICAL SYMBOL FOR SULFUR +1F70E ; [*141D.0020.0002.1F70E] # ALCHEMICAL SYMBOL FOR PHILOSOPHERS SULFUR +1F70F ; [*141E.0020.0002.1F70F] # ALCHEMICAL SYMBOL FOR BLACK SULFUR +1F710 ; [*141F.0020.0002.1F710] # ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE +1F711 ; [*1420.0020.0002.1F711] # ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-2 +1F712 ; [*1421.0020.0002.1F712] # ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-3 +1F713 ; [*1422.0020.0002.1F713] # ALCHEMICAL SYMBOL FOR CINNABAR +1F714 ; [*1423.0020.0002.1F714] # ALCHEMICAL SYMBOL FOR SALT +1F715 ; [*1424.0020.0002.1F715] # ALCHEMICAL SYMBOL FOR NITRE +1F716 ; [*1425.0020.0002.1F716] # ALCHEMICAL SYMBOL FOR VITRIOL +1F717 ; [*1426.0020.0002.1F717] # ALCHEMICAL SYMBOL FOR VITRIOL-2 +1F718 ; [*1427.0020.0002.1F718] # ALCHEMICAL SYMBOL FOR ROCK SALT +1F719 ; [*1428.0020.0002.1F719] # ALCHEMICAL SYMBOL FOR ROCK SALT-2 +1F71A ; [*1429.0020.0002.1F71A] # ALCHEMICAL SYMBOL FOR GOLD +1F71B ; [*142A.0020.0002.1F71B] # ALCHEMICAL SYMBOL FOR SILVER +1F71C ; [*142B.0020.0002.1F71C] # ALCHEMICAL SYMBOL FOR IRON ORE +1F71D ; [*142C.0020.0002.1F71D] # ALCHEMICAL SYMBOL FOR IRON ORE-2 +1F71E ; [*142D.0020.0002.1F71E] # ALCHEMICAL SYMBOL FOR CROCUS OF IRON +1F71F ; [*142E.0020.0002.1F71F] # ALCHEMICAL SYMBOL FOR REGULUS OF IRON +1F720 ; [*142F.0020.0002.1F720] # ALCHEMICAL SYMBOL FOR COPPER ORE +1F721 ; [*1430.0020.0002.1F721] # ALCHEMICAL SYMBOL FOR IRON-COPPER ORE +1F722 ; [*1431.0020.0002.1F722] # ALCHEMICAL SYMBOL FOR SUBLIMATE OF COPPER +1F723 ; [*1432.0020.0002.1F723] # ALCHEMICAL SYMBOL FOR CROCUS OF COPPER +1F724 ; [*1433.0020.0002.1F724] # ALCHEMICAL SYMBOL FOR CROCUS OF COPPER-2 +1F725 ; [*1434.0020.0002.1F725] # ALCHEMICAL SYMBOL FOR COPPER ANTIMONIATE +1F726 ; [*1435.0020.0002.1F726] # ALCHEMICAL SYMBOL FOR SALT OF COPPER ANTIMONIATE +1F727 ; [*1436.0020.0002.1F727] # ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF COPPER +1F728 ; [*1437.0020.0002.1F728] # ALCHEMICAL SYMBOL FOR VERDIGRIS +1F729 ; [*1438.0020.0002.1F729] # ALCHEMICAL SYMBOL FOR TIN ORE +1F72A ; [*1439.0020.0002.1F72A] # ALCHEMICAL SYMBOL FOR LEAD ORE +1F72B ; [*143A.0020.0002.1F72B] # ALCHEMICAL SYMBOL FOR ANTIMONY ORE +1F72C ; [*143B.0020.0002.1F72C] # ALCHEMICAL SYMBOL FOR SUBLIMATE OF ANTIMONY +1F72D ; [*143C.0020.0002.1F72D] # ALCHEMICAL SYMBOL FOR SALT OF ANTIMONY +1F72E ; [*143D.0020.0002.1F72E] # ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF ANTIMONY +1F72F ; [*143E.0020.0002.1F72F] # ALCHEMICAL SYMBOL FOR VINEGAR OF ANTIMONY +1F730 ; [*143F.0020.0002.1F730] # ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY +1F731 ; [*1440.0020.0002.1F731] # ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY-2 +1F732 ; [*1441.0020.0002.1F732] # ALCHEMICAL SYMBOL FOR REGULUS +1F733 ; [*1442.0020.0002.1F733] # ALCHEMICAL SYMBOL FOR REGULUS-2 +1F734 ; [*1443.0020.0002.1F734] # ALCHEMICAL SYMBOL FOR REGULUS-3 +1F735 ; [*1444.0020.0002.1F735] # ALCHEMICAL SYMBOL FOR REGULUS-4 +1F736 ; [*1445.0020.0002.1F736] # ALCHEMICAL SYMBOL FOR ALKALI +1F737 ; [*1446.0020.0002.1F737] # ALCHEMICAL SYMBOL FOR ALKALI-2 +1F738 ; [*1447.0020.0002.1F738] # ALCHEMICAL SYMBOL FOR MARCASITE +1F739 ; [*1448.0020.0002.1F739] # ALCHEMICAL SYMBOL FOR SAL-AMMONIAC +1F73A ; [*1449.0020.0002.1F73A] # ALCHEMICAL SYMBOL FOR ARSENIC +1F73B ; [*144A.0020.0002.1F73B] # ALCHEMICAL SYMBOL FOR REALGAR +1F73C ; [*144B.0020.0002.1F73C] # ALCHEMICAL SYMBOL FOR REALGAR-2 +1F73D ; [*144C.0020.0002.1F73D] # ALCHEMICAL SYMBOL FOR AURIPIGMENT +1F73E ; [*144D.0020.0002.1F73E] # ALCHEMICAL SYMBOL FOR BISMUTH ORE +1F73F ; [*144E.0020.0002.1F73F] # ALCHEMICAL SYMBOL FOR TARTAR +1F740 ; [*144F.0020.0002.1F740] # ALCHEMICAL SYMBOL FOR TARTAR-2 +1F741 ; [*1450.0020.0002.1F741] # ALCHEMICAL SYMBOL FOR QUICK LIME +1F742 ; [*1451.0020.0002.1F742] # ALCHEMICAL SYMBOL FOR BORAX +1F743 ; [*1452.0020.0002.1F743] # ALCHEMICAL SYMBOL FOR BORAX-2 +1F744 ; [*1453.0020.0002.1F744] # ALCHEMICAL SYMBOL FOR BORAX-3 +1F745 ; [*1454.0020.0002.1F745] # ALCHEMICAL SYMBOL FOR ALUM +1F746 ; [*1455.0020.0002.1F746] # ALCHEMICAL SYMBOL FOR OIL +1F747 ; [*1456.0020.0002.1F747] # ALCHEMICAL SYMBOL FOR SPIRIT +1F748 ; [*1457.0020.0002.1F748] # ALCHEMICAL SYMBOL FOR TINCTURE +1F749 ; [*1458.0020.0002.1F749] # ALCHEMICAL SYMBOL FOR GUM +1F74A ; [*1459.0020.0002.1F74A] # ALCHEMICAL SYMBOL FOR WAX +1F74B ; [*145A.0020.0002.1F74B] # ALCHEMICAL SYMBOL FOR POWDER +1F74C ; [*145B.0020.0002.1F74C] # ALCHEMICAL SYMBOL FOR CALX +1F74D ; [*145C.0020.0002.1F74D] # ALCHEMICAL SYMBOL FOR TUTTY +1F74E ; [*145D.0020.0002.1F74E] # ALCHEMICAL SYMBOL FOR CAPUT MORTUUM +1F74F ; [*145E.0020.0002.1F74F] # ALCHEMICAL SYMBOL FOR SCEPTER OF JOVE +1F750 ; [*145F.0020.0002.1F750] # ALCHEMICAL SYMBOL FOR CADUCEUS +1F751 ; [*1460.0020.0002.1F751] # ALCHEMICAL SYMBOL FOR TRIDENT +1F752 ; [*1461.0020.0002.1F752] # ALCHEMICAL SYMBOL FOR STARRED TRIDENT +1F753 ; [*1462.0020.0002.1F753] # ALCHEMICAL SYMBOL FOR LODESTONE +1F754 ; [*1463.0020.0002.1F754] # ALCHEMICAL SYMBOL FOR SOAP +1F755 ; [*1464.0020.0002.1F755] # ALCHEMICAL SYMBOL FOR URINE +1F756 ; [*1465.0020.0002.1F756] # ALCHEMICAL SYMBOL FOR HORSE DUNG +1F757 ; [*1466.0020.0002.1F757] # ALCHEMICAL SYMBOL FOR ASHES +1F758 ; [*1467.0020.0002.1F758] # ALCHEMICAL SYMBOL FOR POT ASHES +1F759 ; [*1468.0020.0002.1F759] # ALCHEMICAL SYMBOL FOR BRICK +1F75A ; [*1469.0020.0002.1F75A] # ALCHEMICAL SYMBOL FOR POWDERED BRICK +1F75B ; [*146A.0020.0002.1F75B] # ALCHEMICAL SYMBOL FOR AMALGAM +1F75C ; [*146B.0020.0002.1F75C] # ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM +1F75D ; [*146C.0020.0002.1F75D] # ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM-2 +1F75E ; [*146D.0020.0002.1F75E] # ALCHEMICAL SYMBOL FOR SUBLIMATION +1F75F ; [*146E.0020.0002.1F75F] # ALCHEMICAL SYMBOL FOR PRECIPITATE +1F760 ; [*146F.0020.0002.1F760] # ALCHEMICAL SYMBOL FOR DISTILL +1F761 ; [*1470.0020.0002.1F761] # ALCHEMICAL SYMBOL FOR DISSOLVE +1F762 ; [*1471.0020.0002.1F762] # ALCHEMICAL SYMBOL FOR DISSOLVE-2 +1F763 ; [*1472.0020.0002.1F763] # ALCHEMICAL SYMBOL FOR PURIFY +1F764 ; [*1473.0020.0002.1F764] # ALCHEMICAL SYMBOL FOR PUTREFACTION +1F765 ; [*1474.0020.0002.1F765] # ALCHEMICAL SYMBOL FOR CRUCIBLE +1F766 ; [*1475.0020.0002.1F766] # ALCHEMICAL SYMBOL FOR CRUCIBLE-2 +1F767 ; [*1476.0020.0002.1F767] # ALCHEMICAL SYMBOL FOR CRUCIBLE-3 +1F768 ; [*1477.0020.0002.1F768] # ALCHEMICAL SYMBOL FOR CRUCIBLE-4 +1F769 ; [*1478.0020.0002.1F769] # ALCHEMICAL SYMBOL FOR CRUCIBLE-5 +1F76A ; [*1479.0020.0002.1F76A] # ALCHEMICAL SYMBOL FOR ALEMBIC +1F76B ; [*147A.0020.0002.1F76B] # ALCHEMICAL SYMBOL FOR BATH OF MARY +1F76C ; [*147B.0020.0002.1F76C] # ALCHEMICAL SYMBOL FOR BATH OF VAPOURS +1F76D ; [*147C.0020.0002.1F76D] # ALCHEMICAL SYMBOL FOR RETORT +1F76E ; [*147D.0020.0002.1F76E] # ALCHEMICAL SYMBOL FOR HOUR +1F76F ; [*147E.0020.0002.1F76F] # ALCHEMICAL SYMBOL FOR NIGHT +1F770 ; [*147F.0020.0002.1F770] # ALCHEMICAL SYMBOL FOR DAY-NIGHT +1F771 ; [*1480.0020.0002.1F771] # ALCHEMICAL SYMBOL FOR MONTH +1F772 ; [*1481.0020.0002.1F772] # ALCHEMICAL SYMBOL FOR HALF DRAM +1F773 ; [*1482.0020.0002.1F773] # ALCHEMICAL SYMBOL FOR HALF OUNCE +0332 ; [.0000.0021.0002.0332] # COMBINING LOW LINE +0313 ; [.0000.0022.0002.0313] # COMBINING COMMA ABOVE +0343 ; [.0000.0022.0002.0343] # COMBINING GREEK KORONIS +0486 ; [.0000.0022.0002.0486] # COMBINING CYRILLIC PSILI PNEUMATA +2CF1 ; [.0000.0022.0002.2CF1] # COPTIC COMBINING SPIRITUS LENIS +0314 ; [.0000.002A.0002.0314] # COMBINING REVERSED COMMA ABOVE +0485 ; [.0000.002A.0002.0485] # COMBINING CYRILLIC DASIA PNEUMATA +2CF0 ; [.0000.002A.0002.2CF0] # COPTIC COMBINING SPIRITUS ASPER +0301 ; [.0000.0032.0002.0301] # COMBINING ACUTE ACCENT +0341 ; [.0000.0032.0002.0341] # COMBINING ACUTE TONE MARK +0954 ; [.0000.0032.0002.0954] # DEVANAGARI ACUTE ACCENT +0300 ; [.0000.0035.0002.0300] # COMBINING GRAVE ACCENT +0340 ; [.0000.0035.0002.0340] # COMBINING GRAVE TONE MARK +0953 ; [.0000.0035.0002.0953] # DEVANAGARI GRAVE ACCENT +0306 ; [.0000.0037.0002.0306] # COMBINING BREVE +0302 ; [.0000.003C.0002.0302] # COMBINING CIRCUMFLEX ACCENT +030C ; [.0000.0041.0002.030C] # COMBINING CARON +030A ; [.0000.0043.0002.030A] # COMBINING RING ABOVE +0342 ; [.0000.0045.0002.0342] # COMBINING GREEK PERISPOMENI +0308 ; [.0000.0047.0002.0308] # COMBINING DIAERESIS +0344 ; [.0000.0047.0002.0308][.0000.0032.0002.0301] # COMBINING GREEK DIALYTIKA TONOS +030B ; [.0000.004D.0002.030B] # COMBINING DOUBLE ACUTE ACCENT +0303 ; [.0000.004E.0002.0303] # COMBINING TILDE +0307 ; [.0000.0052.0002.0307] # COMBINING DOT ABOVE +0338 ; [.0000.0054.0002.0338] # COMBINING LONG SOLIDUS OVERLAY +0327 ; [.0000.0056.0002.0327] # COMBINING CEDILLA +0328 ; [.0000.0059.0002.0328] # COMBINING OGONEK +0304 ; [.0000.005B.0002.0304] # COMBINING MACRON +030D ; [.0000.005F.0002.030D] # COMBINING VERTICAL LINE ABOVE +030E ; [.0000.005F.0002.030E] # COMBINING DOUBLE VERTICAL LINE ABOVE +0312 ; [.0000.005F.0002.0312] # COMBINING TURNED COMMA ABOVE +0315 ; [.0000.005F.0002.0315] # COMBINING COMMA ABOVE RIGHT +031A ; [.0000.005F.0002.031A] # COMBINING LEFT ANGLE ABOVE +033D ; [.0000.005F.0002.033D] # COMBINING X ABOVE +033E ; [.0000.005F.0002.033E] # COMBINING VERTICAL TILDE +033F ; [.0000.005F.0002.033F] # COMBINING DOUBLE OVERLINE +0346 ; [.0000.005F.0002.0346] # COMBINING BRIDGE ABOVE +034A ; [.0000.005F.0002.034A] # COMBINING NOT TILDE ABOVE +034B ; [.0000.005F.0002.034B] # COMBINING HOMOTHETIC ABOVE +034C ; [.0000.005F.0002.034C] # COMBINING ALMOST EQUAL TO ABOVE +0350 ; [.0000.005F.0002.0350] # COMBINING RIGHT ARROWHEAD ABOVE +0351 ; [.0000.005F.0002.0351] # COMBINING LEFT HALF RING ABOVE +0352 ; [.0000.005F.0002.0352] # COMBINING FERMATA +0357 ; [.0000.005F.0002.0357] # COMBINING RIGHT HALF RING ABOVE +035B ; [.0000.005F.0002.035B] # COMBINING ZIGZAG ABOVE +035D ; [.0000.005F.0002.035D] # COMBINING DOUBLE BREVE +035E ; [.0000.005F.0002.035E] # COMBINING DOUBLE MACRON +0484 ; [.0000.005F.0002.0484] # COMBINING CYRILLIC PALATALIZATION +0487 ; [.0000.005F.0002.0487] # COMBINING CYRILLIC POKRYTIE +0741 ; [.0000.005F.0002.0741] # SYRIAC QUSHSHAYA +0745 ; [.0000.005F.0002.0745] # SYRIAC THREE DOTS ABOVE +17CB ; [.0000.005F.0002.17CB] # KHMER SIGN BANTOC +17CC ; [.0000.005F.0002.17CC] # KHMER SIGN ROBAT +17CD ; [.0000.005F.0002.17CD] # KHMER SIGN TOANDAKHIAT +17CE ; [.0000.005F.0002.17CE] # KHMER SIGN KAKABAT +17CF ; [.0000.005F.0002.17CF] # KHMER SIGN AHSDA +17D0 ; [.0000.005F.0002.17D0] # KHMER SIGN SAMYOK SANNYA +17D1 ; [.0000.005F.0002.17D1] # KHMER SIGN VIRIAM +17DD ; [.0000.005F.0002.17DD] # KHMER SIGN ATTHACAN +1DC0 ; [.0000.005F.0002.1DC0] # COMBINING DOTTED GRAVE ACCENT +1DC1 ; [.0000.005F.0002.1DC1] # COMBINING DOTTED ACUTE ACCENT +1DC3 ; [.0000.005F.0002.1DC3] # COMBINING SUSPENSION MARK +1DC4 ; [.0000.005F.0002.1DC4] # COMBINING MACRON-ACUTE +1DC5 ; [.0000.005F.0002.1DC5] # COMBINING GRAVE-MACRON +1DC6 ; [.0000.005F.0002.1DC6] # COMBINING MACRON-GRAVE +1DC7 ; [.0000.005F.0002.1DC7] # COMBINING ACUTE-MACRON +1DC8 ; [.0000.005F.0002.1DC8] # COMBINING GRAVE-ACUTE-GRAVE +1DC9 ; [.0000.005F.0002.1DC9] # COMBINING ACUTE-GRAVE-ACUTE +1DCB ; [.0000.005F.0002.1DCB] # COMBINING BREVE-MACRON +1DCC ; [.0000.005F.0002.1DCC] # COMBINING MACRON-BREVE +1DCD ; [.0000.005F.0002.1DCD] # COMBINING DOUBLE CIRCUMFLEX ABOVE +1DCE ; [.0000.005F.0002.1DCE] # COMBINING OGONEK ABOVE +1DD1 ; [.0000.005F.0002.1DD1] # COMBINING UR ABOVE +1DFE ; [.0000.005F.0002.1DFE] # COMBINING LEFT ARROWHEAD ABOVE +20F0 ; [.0000.005F.0002.20F0] # COMBINING ASTERISK ABOVE +2CEF ; [.0000.005F.0002.2CEF] # COPTIC COMBINING NI ABOVE +A67C ; [.0000.005F.0002.A67C] # COMBINING CYRILLIC KAVYKA +A67D ; [.0000.005F.0002.A67D] # COMBINING CYRILLIC PAYEROK +0316 ; [.0000.0060.0002.0316] # COMBINING GRAVE ACCENT BELOW +0317 ; [.0000.0060.0002.0317] # COMBINING ACUTE ACCENT BELOW +0318 ; [.0000.0060.0002.0318] # COMBINING LEFT TACK BELOW +0319 ; [.0000.0060.0002.0319] # COMBINING RIGHT TACK BELOW +031C ; [.0000.0060.0002.031C] # COMBINING LEFT HALF RING BELOW +031D ; [.0000.0060.0002.031D] # COMBINING UP TACK BELOW +031E ; [.0000.0060.0002.031E] # COMBINING DOWN TACK BELOW +031F ; [.0000.0060.0002.031F] # COMBINING PLUS SIGN BELOW +0320 ; [.0000.0060.0002.0320] # COMBINING MINUS SIGN BELOW +0329 ; [.0000.0060.0002.0329] # COMBINING VERTICAL LINE BELOW +032A ; [.0000.0060.0002.032A] # COMBINING BRIDGE BELOW +032B ; [.0000.0060.0002.032B] # COMBINING INVERTED DOUBLE ARCH BELOW +032C ; [.0000.0060.0002.032C] # COMBINING CARON BELOW +032F ; [.0000.0060.0002.032F] # COMBINING INVERTED BREVE BELOW +0333 ; [.0000.0060.0002.0333] # COMBINING DOUBLE LOW LINE +033A ; [.0000.0060.0002.033A] # COMBINING INVERTED BRIDGE BELOW +033B ; [.0000.0060.0002.033B] # COMBINING SQUARE BELOW +033C ; [.0000.0060.0002.033C] # COMBINING SEAGULL BELOW +0347 ; [.0000.0060.0002.0347] # COMBINING EQUALS SIGN BELOW +0348 ; [.0000.0060.0002.0348] # COMBINING DOUBLE VERTICAL LINE BELOW +0349 ; [.0000.0060.0002.0349] # COMBINING LEFT ANGLE BELOW +034D ; [.0000.0060.0002.034D] # COMBINING LEFT RIGHT ARROW BELOW +034E ; [.0000.0060.0002.034E] # COMBINING UPWARDS ARROW BELOW +0353 ; [.0000.0060.0002.0353] # COMBINING X BELOW +0354 ; [.0000.0060.0002.0354] # COMBINING LEFT ARROWHEAD BELOW +0355 ; [.0000.0060.0002.0355] # COMBINING RIGHT ARROWHEAD BELOW +0356 ; [.0000.0060.0002.0356] # COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW +0359 ; [.0000.0060.0002.0359] # COMBINING ASTERISK BELOW +035A ; [.0000.0060.0002.035A] # COMBINING DOUBLE RING BELOW +035C ; [.0000.0060.0002.035C] # COMBINING DOUBLE BREVE BELOW +035F ; [.0000.0060.0002.035F] # COMBINING DOUBLE MACRON BELOW +0362 ; [.0000.0060.0002.0362] # COMBINING DOUBLE RIGHTWARDS ARROW BELOW +0742 ; [.0000.0060.0002.0742] # SYRIAC RUKKAKHA +0746 ; [.0000.0060.0002.0746] # SYRIAC THREE DOTS BELOW +0859 ; [.0000.0060.0002.0859] # MANDAIC AFFRICATION MARK +085A ; [.0000.0060.0002.085A] # MANDAIC VOCALIZATION MARK +085B ; [.0000.0060.0002.085B] # MANDAIC GEMINATION MARK +1DC2 ; [.0000.0060.0002.1DC2] # COMBINING SNAKE BELOW +1DCF ; [.0000.0060.0002.1DCF] # COMBINING ZIGZAG BELOW +1DD0 ; [.0000.0060.0002.1DD0] # COMBINING IS BELOW +1DFC ; [.0000.0060.0002.1DFC] # COMBINING DOUBLE INVERTED BREVE BELOW +1DFD ; [.0000.0060.0002.1DFD] # COMBINING ALMOST EQUAL TO BELOW +1DFF ; [.0000.0060.0002.1DFF] # COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW +20EC ; [.0000.0060.0002.20EC] # COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS +20ED ; [.0000.0060.0002.20ED] # COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS +20EE ; [.0000.0060.0002.20EE] # COMBINING LEFT ARROW BELOW +20EF ; [.0000.0060.0002.20EF] # COMBINING RIGHT ARROW BELOW +10A0D ; [.0000.0060.0002.10A0D] # KHAROSHTHI SIGN DOUBLE RING BELOW +0336 ; [.0000.0061.0002.0336] # COMBINING LONG STROKE OVERLAY +0337 ; [.0000.0061.0002.0337] # COMBINING SHORT SOLIDUS OVERLAY +20D8 ; [.0000.0061.0002.20D8] # COMBINING RING OVERLAY +20D9 ; [.0000.0061.0002.20D9] # COMBINING CLOCKWISE RING OVERLAY +20DA ; [.0000.0061.0002.20DA] # COMBINING ANTICLOCKWISE RING OVERLAY +20E5 ; [.0000.0061.0002.20E5] # COMBINING REVERSE SOLIDUS OVERLAY +20EA ; [.0000.0061.0002.20EA] # COMBINING LEFTWARDS ARROW OVERLAY +20EB ; [.0000.0061.0002.20EB] # COMBINING LONG DOUBLE SOLIDUS OVERLAY +20DD ; [.0000.0062.0002.20DD] # COMBINING ENCLOSING CIRCLE +20DE ; [.0000.0062.0002.20DE] # COMBINING ENCLOSING SQUARE +20DF ; [.0000.0062.0002.20DF] # COMBINING ENCLOSING DIAMOND +20E0 ; [.0000.0062.0002.20E0] # COMBINING ENCLOSING CIRCLE BACKSLASH +20E2 ; [.0000.0062.0002.20E2] # COMBINING ENCLOSING SCREEN +20E3 ; [.0000.0062.0002.20E3] # COMBINING ENCLOSING KEYCAP +20E4 ; [.0000.0062.0002.20E4] # COMBINING ENCLOSING UPWARD POINTING TRIANGLE +0305 ; [.0000.0063.0002.0305] # COMBINING OVERLINE +0309 ; [.0000.0064.0002.0309] # COMBINING HOOK ABOVE +030F ; [.0000.0065.0002.030F] # COMBINING DOUBLE GRAVE ACCENT +0310 ; [.0000.0066.0002.0310] # COMBINING CANDRABINDU +0311 ; [.0000.0067.0002.0311] # COMBINING INVERTED BREVE +031B ; [.0000.0068.0002.031B] # COMBINING HORN +0321 ; [.0000.006E.0002.0321] # COMBINING PALATALIZED HOOK BELOW +0322 ; [.0000.006F.0002.0322] # COMBINING RETROFLEX HOOK BELOW +0323 ; [.0000.0070.0002.0323] # COMBINING DOT BELOW +0324 ; [.0000.0075.0002.0324] # COMBINING DIAERESIS BELOW +0325 ; [.0000.0076.0002.0325] # COMBINING RING BELOW +0326 ; [.0000.0077.0002.0326] # COMBINING COMMA BELOW +032D ; [.0000.0078.0002.032D] # COMBINING CIRCUMFLEX ACCENT BELOW +032E ; [.0000.0079.0002.032E] # COMBINING BREVE BELOW +0330 ; [.0000.007A.0002.0330] # COMBINING TILDE BELOW +0331 ; [.0000.007B.0002.0331] # COMBINING MACRON BELOW +0334 ; [.0000.007C.0002.0334] # COMBINING TILDE OVERLAY +0335 ; [.0000.007D.0002.0335] # COMBINING SHORT STROKE OVERLAY +0339 ; [.0000.007E.0002.0339] # COMBINING RIGHT HALF RING BELOW +0345 ; [.0000.007F.0002.0345] # COMBINING GREEK YPOGEGRAMMENI +0358 ; [.0000.0080.0002.0358] # COMBINING DOT ABOVE RIGHT +0360 ; [.0000.0081.0002.0360] # COMBINING DOUBLE TILDE +FE22 ; [.0000.0081.0002.FE22] # COMBINING DOUBLE TILDE LEFT HALF +0361 ; [.0000.0082.0002.0361] # COMBINING DOUBLE INVERTED BREVE +FE20 ; [.0000.0082.0002.FE20] # COMBINING LIGATURE LEFT HALF +0483 ; [.0000.0083.0002.0483] # COMBINING CYRILLIC TITLO +A66F ; [.0000.0084.0002.A66F] # COMBINING CYRILLIC VZMET +05B0 ; [.0000.0085.0002.05B0] # HEBREW POINT SHEVA +05B1 ; [.0000.0086.0002.05B1] # HEBREW POINT HATAF SEGOL +05B2 ; [.0000.0087.0002.05B2] # HEBREW POINT HATAF PATAH +05B3 ; [.0000.0088.0002.05B3] # HEBREW POINT HATAF QAMATS +05B4 ; [.0000.0089.0002.05B4] # HEBREW POINT HIRIQ +05B5 ; [.0000.008A.0002.05B5] # HEBREW POINT TSERE +05B6 ; [.0000.008B.0002.05B6] # HEBREW POINT SEGOL +05B7 ; [.0000.008C.0002.05B7] # HEBREW POINT PATAH +05B8 ; [.0000.008D.0002.05B8] # HEBREW POINT QAMATS +05C7 ; [.0000.008D.0002.05C7] # HEBREW POINT QAMATS QATAN +05B9 ; [.0000.008E.0002.05B9] # HEBREW POINT HOLAM +05BA ; [.0000.008E.0002.05BA] # HEBREW POINT HOLAM HASER FOR VAV +05BB ; [.0000.008F.0002.05BB] # HEBREW POINT QUBUTS +05C2 ; [.0000.0090.0002.05C2] # HEBREW POINT SIN DOT +05C1 ; [.0000.0091.0002.05C1] # HEBREW POINT SHIN DOT +05BC ; [.0000.0092.0002.05BC] # HEBREW POINT DAGESH OR MAPIQ +05BF ; [.0000.0095.0002.05BF] # HEBREW POINT RAFE +FB1E ; [.0000.0096.0002.FB1E] # HEBREW POINT JUDEO-SPANISH VARIKA +081C ; [.0000.0097.0002.081C] # SAMARITAN VOWEL SIGN LONG E +081D ; [.0000.0097.0002.081D] # SAMARITAN VOWEL SIGN E +081E ; [.0000.0098.0002.081E] # SAMARITAN VOWEL SIGN OVERLONG AA +081F ; [.0000.0098.0002.081F] # SAMARITAN VOWEL SIGN LONG AA +0820 ; [.0000.0098.0002.0820] # SAMARITAN VOWEL SIGN AA +0821 ; [.0000.0099.0002.0821] # SAMARITAN VOWEL SIGN OVERLONG A +0822 ; [.0000.0099.0002.0822] # SAMARITAN VOWEL SIGN LONG A +0823 ; [.0000.0099.0002.0823] # SAMARITAN VOWEL SIGN A +0824 ; [.0000.009A.0002.0824] # SAMARITAN MODIFIER LETTER SHORT A +0825 ; [.0000.009A.0002.0825] # SAMARITAN VOWEL SIGN SHORT A +0826 ; [.0000.009B.0002.0826] # SAMARITAN VOWEL SIGN LONG U +0827 ; [.0000.009B.0002.0827] # SAMARITAN VOWEL SIGN U +0828 ; [.0000.009C.0002.0828] # SAMARITAN MODIFIER LETTER I +0829 ; [.0000.009C.0002.0829] # SAMARITAN VOWEL SIGN LONG I +082A ; [.0000.009C.0002.082A] # SAMARITAN VOWEL SIGN I +082B ; [.0000.009D.0002.082B] # SAMARITAN VOWEL SIGN O +082C ; [.0000.009E.0002.082C] # SAMARITAN VOWEL SIGN SUKUN +0818 ; [.0000.009F.0002.0818] # SAMARITAN MARK DAGESH +0819 ; [.0000.00A0.0002.0819] # SAMARITAN MARK OCCLUSION +082D ; [.0000.00A1.0002.082D] # SAMARITAN MARK NEQUDAA +064B ; [.0000.00A2.0002.064B] # ARABIC FATHATAN +FE71 ; [.0000.00A2.0018.FE71] # ARABIC TATWEEL WITH FATHATAN ABOVE +FE70 ; [.0000.00A2.001A.FE70] # ARABIC FATHATAN ISOLATED FORM +08F0 ; [.0000.00A3.0002.08F0] # ARABIC OPEN FATHATAN +08E7 ; [.0000.00A4.0002.08E7] # ARABIC CURLY FATHATAN +064C ; [.0000.00A5.0002.064C] # ARABIC DAMMATAN +FE72 ; [.0000.00A5.001A.FE72] # ARABIC DAMMATAN ISOLATED FORM +FC5E ; [.0000.00A5.001A.FC5E][.0000.00BA.001A.FC5E] # ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM +08F1 ; [.0000.00A7.0002.08F1] # ARABIC OPEN DAMMATAN +08E8 ; [.0000.00A8.0002.08E8] # ARABIC CURLY DAMMATAN +064D ; [.0000.00A9.0002.064D] # ARABIC KASRATAN +FE74 ; [.0000.00A9.001A.FE74] # ARABIC KASRATAN ISOLATED FORM +FC5F ; [.0000.00A9.001A.FC5F][.0000.00BA.001A.FC5F] # ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM +08F2 ; [.0000.00AB.0002.08F2] # ARABIC OPEN KASRATAN +08E9 ; [.0000.00AC.0002.08E9] # ARABIC CURLY KASRATAN +064E ; [.0000.00AD.0002.064E] # ARABIC FATHA +FE77 ; [.0000.00AD.0018.FE77] # ARABIC FATHA MEDIAL FORM +FE76 ; [.0000.00AD.001A.FE76] # ARABIC FATHA ISOLATED FORM +FCF2 ; [.0000.00AD.0018.FCF2][.0000.00BA.0018.FCF2] # ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM +FC60 ; [.0000.00AD.001A.FC60][.0000.00BA.001A.FC60] # ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM +08E4 ; [.0000.00AF.0002.08E4] # ARABIC CURLY FATHA +08F4 ; [.0000.00B0.0002.08F4] # ARABIC FATHA WITH RING +08F5 ; [.0000.00B1.0002.08F5] # ARABIC FATHA WITH DOT ABOVE +064F ; [.0000.00B2.0002.064F] # ARABIC DAMMA +FE79 ; [.0000.00B2.0018.FE79] # ARABIC DAMMA MEDIAL FORM +FE78 ; [.0000.00B2.001A.FE78] # ARABIC DAMMA ISOLATED FORM +FCF3 ; [.0000.00B2.0018.FCF3][.0000.00BA.0018.FCF3] # ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM +FC61 ; [.0000.00B2.001A.FC61][.0000.00BA.001A.FC61] # ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM +08E5 ; [.0000.00B4.0002.08E5] # ARABIC CURLY DAMMA +08FE ; [.0000.00B5.0002.08FE] # ARABIC DAMMA WITH DOT +0650 ; [.0000.00B6.0002.0650] # ARABIC KASRA +FE7B ; [.0000.00B6.0018.FE7B] # ARABIC KASRA MEDIAL FORM +FE7A ; [.0000.00B6.001A.FE7A] # ARABIC KASRA ISOLATED FORM +FCF4 ; [.0000.00B6.0018.FCF4][.0000.00BA.0018.FCF4] # ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM +FC62 ; [.0000.00B6.001A.FC62][.0000.00BA.001A.FC62] # ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM +08E6 ; [.0000.00B8.0002.08E6] # ARABIC CURLY KASRA +08F6 ; [.0000.00B9.0002.08F6] # ARABIC KASRA WITH DOT BELOW +0651 ; [.0000.00BA.0002.0651] # ARABIC SHADDA +FE7D ; [.0000.00BA.0018.FE7D] # ARABIC SHADDA MEDIAL FORM +FE7C ; [.0000.00BA.001A.FE7C] # ARABIC SHADDA ISOLATED FORM +FC63 ; [.0000.00BA.001A.FC63][.0000.00D1.001A.FC63] # ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM +0652 ; [.0000.00BC.0002.0652] # ARABIC SUKUN +FE7F ; [.0000.00BC.0018.FE7F] # ARABIC SUKUN MEDIAL FORM +FE7E ; [.0000.00BC.001A.FE7E] # ARABIC SUKUN ISOLATED FORM +0653 ; [.0000.00BD.0002.0653] # ARABIC MADDAH ABOVE +0654 ; [.0000.00BE.0002.0654] # ARABIC HAMZA ABOVE +0655 ; [.0000.00BF.0002.0655] # ARABIC HAMZA BELOW +065F ; [.0000.00C0.0002.065F] # ARABIC WAVY HAMZA BELOW +0656 ; [.0000.00C1.0002.0656] # ARABIC SUBSCRIPT ALEF +0657 ; [.0000.00C2.0002.0657] # ARABIC INVERTED DAMMA +0658 ; [.0000.00C3.0002.0658] # ARABIC MARK NOON GHUNNA +0659 ; [.0000.00C4.0002.0659] # ARABIC ZWARAKAY +065A ; [.0000.00C5.0002.065A] # ARABIC VOWEL SIGN SMALL V ABOVE +065B ; [.0000.00C6.0002.065B] # ARABIC VOWEL SIGN INVERTED SMALL V ABOVE +065C ; [.0000.00C7.0002.065C] # ARABIC VOWEL SIGN DOT BELOW +065D ; [.0000.00C8.0002.065D] # ARABIC REVERSED DAMMA +065E ; [.0000.00C9.0002.065E] # ARABIC FATHA WITH TWO DOTS +08F7 ; [.0000.00CA.0002.08F7] # ARABIC LEFT ARROWHEAD ABOVE +08F8 ; [.0000.00CB.0002.08F8] # ARABIC RIGHT ARROWHEAD ABOVE +08FD ; [.0000.00CC.0002.08FD] # ARABIC RIGHT ARROWHEAD ABOVE WITH DOT +08FB ; [.0000.00CD.0002.08FB] # ARABIC DOUBLE RIGHT ARROWHEAD ABOVE +08FC ; [.0000.00CE.0002.08FC] # ARABIC DOUBLE RIGHT ARROWHEAD ABOVE WITH DOT +08F9 ; [.0000.00CF.0002.08F9] # ARABIC LEFT ARROWHEAD BELOW +08FA ; [.0000.00D0.0002.08FA] # ARABIC RIGHT ARROWHEAD BELOW +0670 ; [.0000.00D1.0002.0670] # ARABIC LETTER SUPERSCRIPT ALEF +0711 ; [.0000.00D2.0002.0711] # SYRIAC LETTER SUPERSCRIPT ALAPH +0730 ; [.0000.00D3.0002.0730] # SYRIAC PTHAHA ABOVE +0731 ; [.0000.00D4.0002.0731] # SYRIAC PTHAHA BELOW +0732 ; [.0000.00D5.0002.0732] # SYRIAC PTHAHA DOTTED +0733 ; [.0000.00D6.0002.0733] # SYRIAC ZQAPHA ABOVE +0734 ; [.0000.00D7.0002.0734] # SYRIAC ZQAPHA BELOW +0735 ; [.0000.00D8.0002.0735] # SYRIAC ZQAPHA DOTTED +0736 ; [.0000.00D9.0002.0736] # SYRIAC RBASA ABOVE +0737 ; [.0000.00DA.0002.0737] # SYRIAC RBASA BELOW +0738 ; [.0000.00DB.0002.0738] # SYRIAC DOTTED ZLAMA HORIZONTAL +0739 ; [.0000.00DC.0002.0739] # SYRIAC DOTTED ZLAMA ANGULAR +073A ; [.0000.00DD.0002.073A] # SYRIAC HBASA ABOVE +073B ; [.0000.00DE.0002.073B] # SYRIAC HBASA BELOW +073C ; [.0000.00DF.0002.073C] # SYRIAC HBASA-ESASA DOTTED +073D ; [.0000.00E0.0002.073D] # SYRIAC ESASA ABOVE +073E ; [.0000.00E1.0002.073E] # SYRIAC ESASA BELOW +073F ; [.0000.00E2.0002.073F] # SYRIAC RWAHA +07EB ; [.0000.00E3.0002.07EB] # NKO COMBINING SHORT HIGH TONE +07EC ; [.0000.00E4.0002.07EC] # NKO COMBINING SHORT LOW TONE +07ED ; [.0000.00E5.0002.07ED] # NKO COMBINING SHORT RISING TONE +07EE ; [.0000.00E6.0002.07EE] # NKO COMBINING LONG DESCENDING TONE +07EF ; [.0000.00E7.0002.07EF] # NKO COMBINING LONG HIGH TONE +07F0 ; [.0000.00E8.0002.07F0] # NKO COMBINING LONG LOW TONE +07F1 ; [.0000.00E9.0002.07F1] # NKO COMBINING LONG RISING TONE +07F2 ; [.0000.00EA.0002.07F2] # NKO COMBINING NASALIZATION MARK +07F3 ; [.0000.00EB.0002.07F3] # NKO COMBINING DOUBLE DOT ABOVE +135F ; [.0000.00EC.0002.135F] # ETHIOPIC COMBINING GEMINATION MARK +135E ; [.0000.00ED.0002.135E] # ETHIOPIC COMBINING VOWEL LENGTH MARK +135D ; [.0000.00EE.0002.135D] # ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK +A6F0 ; [.0000.00EF.0002.A6F0] # BAMUM COMBINING MARK KOQNDON +A6F1 ; [.0000.00F0.0002.A6F1] # BAMUM COMBINING MARK TUKWENTIS +093C ; [.0000.00F1.0002.093C] # DEVANAGARI SIGN NUKTA +09BC ; [.0000.00F1.0002.09BC] # BENGALI SIGN NUKTA +0A3C ; [.0000.00F1.0002.0A3C] # GURMUKHI SIGN NUKTA +0ABC ; [.0000.00F1.0002.0ABC] # GUJARATI SIGN NUKTA +0B3C ; [.0000.00F1.0002.0B3C] # ORIYA SIGN NUKTA +0CBC ; [.0000.00F1.0002.0CBC] # KANNADA SIGN NUKTA +1B34 ; [.0000.00F1.0002.1B34] # BALINESE SIGN REREKAN +1BE6 ; [.0000.00F1.0002.1BE6] # BATAK SIGN TOMPI +1C37 ; [.0000.00F1.0002.1C37] # LEPCHA SIGN NUKTA +A9B3 ; [.0000.00F1.0002.A9B3] # JAVANESE SIGN CECAK TELU +110BA ; [.0000.00F1.0002.110BA] # KAITHI SIGN NUKTA +116B7 ; [.0000.00F1.0002.116B7] # TAKRI SIGN NUKTA +0900 ; [.0000.00F2.0002.0900] # DEVANAGARI SIGN INVERTED CANDRABINDU +0901 ; [.0000.00F2.0002.0901] # DEVANAGARI SIGN CANDRABINDU +0981 ; [.0000.00F2.0002.0981] # BENGALI SIGN CANDRABINDU +0A01 ; [.0000.00F2.0002.0A01] # GURMUKHI SIGN ADAK BINDI +0A81 ; [.0000.00F2.0002.0A81] # GUJARATI SIGN CANDRABINDU +0B01 ; [.0000.00F2.0002.0B01] # ORIYA SIGN CANDRABINDU +0C01 ; [.0000.00F2.0002.0C01] # TELUGU SIGN CANDRABINDU +1B00 ; [.0000.00F2.0002.1B00] # BALINESE SIGN ULU RICEM +1B01 ; [.0000.00F2.0002.1B01] # BALINESE SIGN ULU CANDRA +A980 ; [.0000.00F2.0002.A980] # JAVANESE SIGN PANYANGGA +11000 ; [.0000.00F2.0002.11000] # BRAHMI SIGN CANDRABINDU +11080 ; [.0000.00F2.0002.11080] # KAITHI SIGN CANDRABINDU +11100 ; [.0000.00F2.0002.11100] # CHAKMA SIGN CANDRABINDU +11180 ; [.0000.00F2.0002.11180] # SHARADA SIGN CANDRABINDU +0902 ; [.0000.00F3.0002.0902] # DEVANAGARI SIGN ANUSVARA +0982 ; [.0000.00F3.0002.0982] # BENGALI SIGN ANUSVARA +0A02 ; [.0000.00F3.0002.0A02] # GURMUKHI SIGN BINDI +0A82 ; [.0000.00F3.0002.0A82] # GUJARATI SIGN ANUSVARA +0B02 ; [.0000.00F3.0002.0B02] # ORIYA SIGN ANUSVARA +0B82 ; [.0000.00F3.0002.0B82] # TAMIL SIGN ANUSVARA +0C02 ; [.0000.00F3.0002.0C02] # TELUGU SIGN ANUSVARA +0C82 ; [.0000.00F3.0002.0C82] # KANNADA SIGN ANUSVARA +0D02 ; [.0000.00F3.0002.0D02] # MALAYALAM SIGN ANUSVARA +0D82 ; [.0000.00F3.0002.0D82] # SINHALA SIGN ANUSVARAYA +0F7E ; [.0000.00F3.0002.0F7E] # TIBETAN SIGN RJES SU NGA RO +1036 ; [.0000.00F3.0002.1036] # MYANMAR SIGN ANUSVARA +17C6 ; [.0000.00F3.0002.17C6] # KHMER SIGN NIKAHIT +1A74 ; [.0000.00F3.0002.1A74] # TAI THAM SIGN MAI KANG +1B02 ; [.0000.00F3.0002.1B02] # BALINESE SIGN CECEK +1B80 ; [.0000.00F3.0002.1B80] # SUNDANESE SIGN PANYECEK +1CED ; [.0000.00F3.0002.1CED] # VEDIC SIGN TIRYAK +A80B ; [.0000.00F3.0002.A80B] # SYLOTI NAGRI SIGN ANUSVARA +A880 ; [.0000.00F3.0002.A880] # SAURASHTRA SIGN ANUSVARA +A981 ; [.0000.00F3.0002.A981] # JAVANESE SIGN CECAK +10A0E ; [.0000.00F3.0002.10A0E] # KHAROSHTHI SIGN ANUSVARA +11001 ; [.0000.00F3.0002.11001] # BRAHMI SIGN ANUSVARA +11081 ; [.0000.00F3.0002.11081] # KAITHI SIGN ANUSVARA +11101 ; [.0000.00F3.0002.11101] # CHAKMA SIGN ANUSVARA +11181 ; [.0000.00F3.0002.11181] # SHARADA SIGN ANUSVARA +116AB ; [.0000.00F3.0002.116AB] # TAKRI SIGN ANUSVARA +0903 ; [.0000.00F4.0002.0903] # DEVANAGARI SIGN VISARGA +0983 ; [.0000.00F4.0002.0983] # BENGALI SIGN VISARGA +0A03 ; [.0000.00F4.0002.0A03] # GURMUKHI SIGN VISARGA +0A83 ; [.0000.00F4.0002.0A83] # GUJARATI SIGN VISARGA +0B03 ; [.0000.00F4.0002.0B03] # ORIYA SIGN VISARGA +0C03 ; [.0000.00F4.0002.0C03] # TELUGU SIGN VISARGA +0C83 ; [.0000.00F4.0002.0C83] # KANNADA SIGN VISARGA +0D03 ; [.0000.00F4.0002.0D03] # MALAYALAM SIGN VISARGA +0D83 ; [.0000.00F4.0002.0D83] # SINHALA SIGN VISARGAYA +0F7F ; [.0000.00F4.0002.0F7F] # TIBETAN SIGN RNAM BCAD +1038 ; [.0000.00F4.0002.1038] # MYANMAR SIGN VISARGA +17C7 ; [.0000.00F4.0002.17C7] # KHMER SIGN REAHMUK +1B04 ; [.0000.00F4.0002.1B04] # BALINESE SIGN BISAH +1B82 ; [.0000.00F4.0002.1B82] # SUNDANESE SIGN PANGWISAD +1CF2 ; [.0000.00F4.0002.1CF2] # VEDIC SIGN ARDHAVISARGA +1CF3 ; [.0000.00F4.0002.1CF3] # VEDIC SIGN ROTATED ARDHAVISARGA +A881 ; [.0000.00F4.0002.A881] # SAURASHTRA SIGN VISARGA +A983 ; [.0000.00F4.0002.A983] # JAVANESE SIGN WIGNYAN +10A0F ; [.0000.00F4.0002.10A0F] # KHAROSHTHI SIGN VISARGA +11002 ; [.0000.00F4.0002.11002] # BRAHMI SIGN VISARGA +11082 ; [.0000.00F4.0002.11082] # KAITHI SIGN VISARGA +11102 ; [.0000.00F4.0002.11102] # CHAKMA SIGN VISARGA +11182 ; [.0000.00F4.0002.11182] # SHARADA SIGN VISARGA +116AC ; [.0000.00F4.0002.116AC] # TAKRI SIGN VISARGA +0A70 ; [.0000.00F5.0002.0A70] # GURMUKHI TIPPI +0A71 ; [.0000.00F6.0002.0A71] # GURMUKHI ADDAK +1B03 ; [.0000.00F7.0002.1B03] # BALINESE SIGN SURANG +A982 ; [.0000.00F8.0002.A982] # JAVANESE SIGN LAYAR +1B81 ; [.0000.00F9.0002.1B81] # SUNDANESE SIGN PANGLAYAR +ABEC ; [.0000.00FA.0002.ABEC] # MEETEI MAYEK LUM IYEK +10A38 ; [.0000.00FB.0002.10A38] # KHAROSHTHI SIGN BAR ABOVE +10A39 ; [.0000.00FC.0002.10A39] # KHAROSHTHI SIGN CAUDA +10A3A ; [.0000.00FD.0002.10A3A] # KHAROSHTHI SIGN DOT BELOW +0E4E ; [.0000.00FE.0002.0E4E] # THAI CHARACTER YAMAKKAN +0E47 ; [.0000.00FF.0002.0E47] # THAI CHARACTER MAITAIKHU +0E48 ; [.0000.0100.0002.0E48] # THAI CHARACTER MAI EK +0E49 ; [.0000.0101.0002.0E49] # THAI CHARACTER MAI THO +0E4A ; [.0000.0102.0002.0E4A] # THAI CHARACTER MAI TRI +0E4B ; [.0000.0103.0002.0E4B] # THAI CHARACTER MAI CHATTAWA +0E4C ; [.0000.0104.0002.0E4C] # THAI CHARACTER THANTHAKHAT +0E4D ; [.0000.0105.0002.0E4D] # THAI CHARACTER NIKHAHIT +0EC8 ; [.0000.0106.0002.0EC8] # LAO TONE MAI EK +0EC9 ; [.0000.0107.0002.0EC9] # LAO TONE MAI THO +0ECA ; [.0000.0108.0002.0ECA] # LAO TONE MAI TI +0ECB ; [.0000.0109.0002.0ECB] # LAO TONE MAI CATAWA +0ECC ; [.0000.010A.0002.0ECC] # LAO CANCELLATION MARK +0ECD ; [.0000.010B.0002.0ECD] # LAO NIGGAHITA +AABF ; [.0000.010C.0002.AABF] # TAI VIET TONE MAI EK +AAC1 ; [.0000.010D.0002.AAC1] # TAI VIET TONE MAI THO +0F39 ; [.0000.010E.0002.0F39] # TIBETAN MARK TSA -PHRU +A92B ; [.0000.010F.0002.A92B] # KAYAH LI TONE PLOPHU +A92C ; [.0000.0110.0002.A92C] # KAYAH LI TONE CALYA +A92D ; [.0000.0111.0002.A92D] # KAYAH LI TONE CALYA PLOPHU +1037 ; [.0000.0112.0002.1037] # MYANMAR SIGN DOT BELOW +108D ; [.0000.0113.0002.108D] # MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE +17C8 ; [.0000.0114.0002.17C8] # KHMER SIGN YUUKALEAPINTU +17C9 ; [.0000.0115.0002.17C9] # KHMER SIGN MUUSIKATOAN +17CA ; [.0000.0116.0002.17CA] # KHMER SIGN TRIISAP +1A75 ; [.0000.0117.0002.1A75] # TAI THAM SIGN TONE-1 +1A76 ; [.0000.0118.0002.1A76] # TAI THAM SIGN TONE-2 +1A77 ; [.0000.0119.0002.1A77] # TAI THAM SIGN KHUEN TONE-3 +1A78 ; [.0000.011A.0002.1A78] # TAI THAM SIGN KHUEN TONE-4 +1A79 ; [.0000.011B.0002.1A79] # TAI THAM SIGN KHUEN TONE-5 +1A7A ; [.0000.011C.0002.1A7A] # TAI THAM SIGN RA HAAM +1A7B ; [.0000.011D.0002.1A7B] # TAI THAM SIGN MAI SAM +1A7C ; [.0000.011E.0002.1A7C] # TAI THAM SIGN KHUEN-LUE KARAN +1939 ; [.0000.011F.0002.1939] # LIMBU SIGN MUKPHRENG +193A ; [.0000.0120.0002.193A] # LIMBU SIGN KEMPHRENG +193B ; [.0000.0121.0002.193B] # LIMBU SIGN SA-I +302A ; [.0000.0122.0002.302A] # IDEOGRAPHIC LEVEL TONE MARK +302B ; [.0000.0123.0002.302B] # IDEOGRAPHIC RISING TONE MARK +302C ; [.0000.0124.0002.302C] # IDEOGRAPHIC DEPARTING TONE MARK +302D ; [.0000.0125.0002.302D] # IDEOGRAPHIC ENTERING TONE MARK +302E ; [.0000.0126.0002.302E] # HANGUL SINGLE DOT TONE MARK +302F ; [.0000.0127.0002.302F] # HANGUL DOUBLE DOT TONE MARK +3099 ; [.0000.0128.0002.3099] # COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK +FF9E ; [.0000.0128.0012.FF9E] # HALFWIDTH KATAKANA VOICED SOUND MARK +309A ; [.0000.0129.0002.309A] # COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK +FF9F ; [.0000.0129.0012.FF9F] # HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK +20D0 ; [.0000.012A.0002.20D0] # COMBINING LEFT HARPOON ABOVE +20D1 ; [.0000.012B.0002.20D1] # COMBINING RIGHT HARPOON ABOVE +20D2 ; [.0000.012C.0002.20D2] # COMBINING LONG VERTICAL LINE OVERLAY +20D3 ; [.0000.012C.0002.20D3] # COMBINING SHORT VERTICAL LINE OVERLAY +20D4 ; [.0000.012D.0002.20D4] # COMBINING ANTICLOCKWISE ARROW ABOVE +20D5 ; [.0000.012E.0002.20D5] # COMBINING CLOCKWISE ARROW ABOVE +20D6 ; [.0000.012F.0002.20D6] # COMBINING LEFT ARROW ABOVE +20D7 ; [.0000.0130.0002.20D7] # COMBINING RIGHT ARROW ABOVE +20DB ; [.0000.0131.0002.20DB] # COMBINING THREE DOTS ABOVE +20DC ; [.0000.0132.0002.20DC] # COMBINING FOUR DOTS ABOVE +20E1 ; [.0000.0133.0002.20E1] # COMBINING LEFT RIGHT ARROW ABOVE +20E6 ; [.0000.0134.0002.20E6] # COMBINING DOUBLE VERTICAL STROKE OVERLAY +20E7 ; [.0000.0135.0002.20E7] # COMBINING ANNUITY SYMBOL +20E8 ; [.0000.0136.0002.20E8] # COMBINING TRIPLE UNDERDOT +20E9 ; [.0000.0137.0002.20E9] # COMBINING WIDE BRIDGE ABOVE +101FD ; [.0000.0138.0002.101FD] # PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE +02D0 ; [.158E.0020.0002.02D0] # MODIFIER LETTER TRIANGULAR COLON +02D1 ; [.158F.0020.0002.02D1] # MODIFIER LETTER HALF TRIANGULAR COLON +0971 ; [.1590.0020.0002.0971] # DEVANAGARI SIGN HIGH SPACING DOT +0E46 ; [.1591.0020.0002.0E46] # THAI CHARACTER MAIYAMOK +0EC6 ; [.1592.0020.0002.0EC6] # LAO KO LA +17D7 ; [.1593.0020.0002.17D7] # KHMER SIGN LEK TOO +1AA7 ; [.1594.0020.0002.1AA7] # TAI THAM SIGN MAI YAMOK +A9CF ; [.1595.0020.0002.A9CF] # JAVANESE PANGRANGKEP +AA70 ; [.1596.0020.0002.AA70] # MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION +AADD ; [.1597.0020.0002.AADD] # TAI VIET SYMBOL SAM +AAF3 ; [.1598.0020.0002.AAF3] # MEETEI MAYEK SYLLABLE REPETITION MARK +AAF4 ; [.1599.0020.0002.AAF4] # MEETEI MAYEK WORD REPETITION MARK +3005 ; [.159A.0020.0002.3005] # IDEOGRAPHIC ITERATION MARK +303B ; [.159B.0020.0002.303B] # VERTICAL IDEOGRAPHIC ITERATION MARK +3031 ; [.159C.0020.0002.3031] # VERTICAL KANA REPEAT MARK +3032 ; [.159C.0020.0002.3031][.0000.0128.0002.3099] # VERTICAL KANA REPEAT WITH VOICED SOUND MARK +3033 ; [.159D.0020.0002.3033] # VERTICAL KANA REPEAT MARK UPPER HALF +3034 ; [.159D.0020.0002.3033][.0000.0128.0002.3099] # VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF +3035 ; [.159E.0020.0002.3035] # VERTICAL KANA REPEAT MARK LOWER HALF +309D ; [.159F.0020.0002.309D] # HIRAGANA ITERATION MARK +309E ; [.159F.0020.0002.309D][.0000.0128.0002.3099] # HIRAGANA VOICED ITERATION MARK +30FC ; [.15A0.0020.0002.30FC] # KATAKANA-HIRAGANA PROLONGED SOUND MARK +FF70 ; [.15A0.0020.0012.FF70] # HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK +30FD ; [.15A1.0020.0002.30FD] # KATAKANA ITERATION MARK +30FE ; [.15A1.0020.0002.30FD][.0000.0128.0002.3099] # KATAKANA VOICED ITERATION MARK +00A4 ; [.15A2.0020.0002.00A4] # CURRENCY SIGN +00A2 ; [.15A3.0020.0002.00A2] # CENT SIGN +FFE0 ; [.15A3.0020.0003.FFE0] # FULLWIDTH CENT SIGN +0024 ; [.15A4.0020.0002.0024] # DOLLAR SIGN +FF04 ; [.15A4.0020.0003.FF04] # FULLWIDTH DOLLAR SIGN +FE69 ; [.15A4.0020.000F.FE69] # SMALL DOLLAR SIGN +00A3 ; [.15A5.0020.0002.00A3] # POUND SIGN +FFE1 ; [.15A5.0020.0003.FFE1] # FULLWIDTH POUND SIGN +00A5 ; [.15A6.0020.0002.00A5] # YEN SIGN +FFE5 ; [.15A6.0020.0003.FFE5] # FULLWIDTH YEN SIGN +058F ; [.15A7.0020.0002.058F] # ARMENIAN DRAM SIGN +060B ; [.15A8.0020.0002.060B] # AFGHANI SIGN +09F2 ; [.15A9.0020.0002.09F2] # BENGALI RUPEE MARK +09F3 ; [.15AA.0020.0002.09F3] # BENGALI RUPEE SIGN +09FB ; [.15AB.0020.0002.09FB] # BENGALI GANDA MARK +0AF1 ; [.15AC.0020.0002.0AF1] # GUJARATI RUPEE SIGN +A838 ; [.15AD.0020.0002.A838] # NORTH INDIC RUPEE MARK +0BF9 ; [.15AE.0020.0002.0BF9] # TAMIL RUPEE SIGN +0E3F ; [.15AF.0020.0002.0E3F] # THAI CURRENCY SYMBOL BAHT +17DB ; [.15B0.0020.0002.17DB] # KHMER CURRENCY SYMBOL RIEL +20A0 ; [.15B1.0020.0002.20A0] # EURO-CURRENCY SIGN +20A1 ; [.15B2.0020.0002.20A1] # COLON SIGN +20A2 ; [.15B3.0020.0002.20A2] # CRUZEIRO SIGN +20A3 ; [.15B4.0020.0002.20A3] # FRENCH FRANC SIGN +20A4 ; [.15B5.0020.0002.20A4] # LIRA SIGN +20A5 ; [.15B6.0020.0002.20A5] # MILL SIGN +20A6 ; [.15B7.0020.0002.20A6] # NAIRA SIGN +20A7 ; [.15B8.0020.0002.20A7] # PESETA SIGN +20A9 ; [.15B9.0020.0002.20A9] # WON SIGN +FFE6 ; [.15B9.0020.0003.FFE6] # FULLWIDTH WON SIGN +20AA ; [.15BA.0020.0002.20AA] # NEW SHEQEL SIGN +20AB ; [.15BB.0020.0002.20AB] # DONG SIGN +20AC ; [.15BC.0020.0002.20AC] # EURO SIGN +20AD ; [.15BD.0020.0002.20AD] # KIP SIGN +20AE ; [.15BE.0020.0002.20AE] # TUGRIK SIGN +20AF ; [.15BF.0020.0002.20AF] # DRACHMA SIGN +20B0 ; [.15C0.0020.0002.20B0] # GERMAN PENNY SIGN +20B1 ; [.15C1.0020.0002.20B1] # PESO SIGN +20B2 ; [.15C2.0020.0002.20B2] # GUARANI SIGN +20B3 ; [.15C3.0020.0002.20B3] # AUSTRAL SIGN +20B4 ; [.15C4.0020.0002.20B4] # HRYVNIA SIGN +20B5 ; [.15C5.0020.0002.20B5] # CEDI SIGN +20B6 ; [.15C6.0020.0002.20B6] # LIVRE TOURNOIS SIGN +20B7 ; [.15C7.0020.0002.20B7] # SPESMILO SIGN +20B8 ; [.15C8.0020.0002.20B8] # TENGE SIGN +20B9 ; [.15C9.0020.0002.20B9] # INDIAN RUPEE SIGN +0030 ; [.15CA.0020.0002.0030] # DIGIT ZERO +FF10 ; [.15CA.0020.0003.FF10] # FULLWIDTH DIGIT ZERO +1F100 ; [.15CA.0020.0004.1F100][*0273.0020.0004.1F100] # DIGIT ZERO FULL STOP +1F101 ; [.15CA.0020.0004.1F101][*0221.0020.0004.1F101] # DIGIT ZERO COMMA +1D7CE ; [.15CA.0020.0005.1D7CE] # MATHEMATICAL BOLD DIGIT ZERO +1D7D8 ; [.15CA.0020.0005.1D7D8] # MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO +1D7E2 ; [.15CA.0020.0005.1D7E2] # MATHEMATICAL SANS-SERIF DIGIT ZERO +1D7EC ; [.15CA.0020.0005.1D7EC] # MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO +1D7F6 ; [.15CA.0020.0005.1D7F6] # MATHEMATICAL MONOSPACE DIGIT ZERO +24EA ; [.15CA.0020.0006.24EA] # CIRCLED DIGIT ZERO +24FF ; [.15CA.0020.0006.24FF] # NEGATIVE CIRCLED DIGIT ZERO +2070 ; [.15CA.0020.0014.2070] # SUPERSCRIPT ZERO +2080 ; [.15CA.0020.0015.2080] # SUBSCRIPT ZERO +0660 ; [.15CA.0020.0002.0660][.0000.013F.0002.0660] # ARABIC-INDIC DIGIT ZERO +06F0 ; [.15CA.0020.0002.06F0][.0000.0140.0002.06F0] # EXTENDED ARABIC-INDIC DIGIT ZERO +07C0 ; [.15CA.0020.0002.07C0][.0000.0142.0002.07C0] # NKO DIGIT ZERO +104A0 ; [.15CA.0020.0002.104A0][.0000.0144.0002.104A0] # OSMANYA DIGIT ZERO +0966 ; [.15CA.0020.0002.0966][.0000.0145.0002.0966] # DEVANAGARI DIGIT ZERO +09E6 ; [.15CA.0020.0002.09E6][.0000.0146.0002.09E6] # BENGALI DIGIT ZERO +0A66 ; [.15CA.0020.0002.0A66][.0000.0147.0002.0A66] # GURMUKHI DIGIT ZERO +0AE6 ; [.15CA.0020.0002.0AE6][.0000.0148.0002.0AE6] # GUJARATI DIGIT ZERO +0B66 ; [.15CA.0020.0002.0B66][.0000.0149.0002.0B66] # ORIYA DIGIT ZERO +0BE6 ; [.15CA.0020.0002.0BE6][.0000.014A.0002.0BE6] # TAMIL DIGIT ZERO +0C66 ; [.15CA.0020.0002.0C66][.0000.014B.0002.0C66] # TELUGU DIGIT ZERO +0C78 ; [.15CA.0020.0002.0C78][.0000.014B.0002.0C78] # TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR +0CE6 ; [.15CA.0020.0002.0CE6][.0000.014C.0002.0CE6] # KANNADA DIGIT ZERO +0D66 ; [.15CA.0020.0002.0D66][.0000.014D.0002.0D66] # MALAYALAM DIGIT ZERO +ABF0 ; [.15CA.0020.0002.ABF0][.0000.014E.0002.ABF0] # MEETEI MAYEK DIGIT ZERO +A8D0 ; [.15CA.0020.0002.A8D0][.0000.014F.0002.A8D0] # SAURASHTRA DIGIT ZERO +1946 ; [.15CA.0020.0002.1946][.0000.0150.0002.1946] # LIMBU DIGIT ZERO +19D0 ; [.15CA.0020.0002.19D0][.0000.0151.0002.19D0] # NEW TAI LUE DIGIT ZERO +1A80 ; [.15CA.0020.0002.1A80][.0000.0152.0002.1A80] # TAI THAM HORA DIGIT ZERO +1A90 ; [.15CA.0020.0002.1A90][.0000.0153.0002.1A90] # TAI THAM THAM DIGIT ZERO +0E50 ; [.15CA.0020.0002.0E50][.0000.0154.0002.0E50] # THAI DIGIT ZERO +0ED0 ; [.15CA.0020.0002.0ED0][.0000.0155.0002.0ED0] # LAO DIGIT ZERO +0F20 ; [.15CA.0020.0002.0F20][.0000.0156.0002.0F20] # TIBETAN DIGIT ZERO +0F33 ; [.15CA.0020.0004.0F33][.0000.0156.0004.0F33] # TIBETAN DIGIT HALF ZERO +1C40 ; [.15CA.0020.0002.1C40][.0000.0157.0002.1C40] # LEPCHA DIGIT ZERO +A900 ; [.15CA.0020.0002.A900][.0000.0158.0002.A900] # KAYAH LI DIGIT ZERO +1040 ; [.15CA.0020.0002.1040][.0000.0159.0002.1040] # MYANMAR DIGIT ZERO +1090 ; [.15CA.0020.0002.1090][.0000.015A.0002.1090] # MYANMAR SHAN DIGIT ZERO +11136 ; [.15CA.0020.0002.11136][.0000.015B.0002.11136] # CHAKMA DIGIT ZERO +17E0 ; [.15CA.0020.0002.17E0][.0000.015C.0002.17E0] # KHMER DIGIT ZERO +17F0 ; [.15CA.0020.0002.17F0][.0000.015D.0002.17F0] # KHMER SYMBOL LEK ATTAK SON +AA50 ; [.15CA.0020.0002.AA50][.0000.015E.0002.AA50] # CHAM DIGIT ZERO +1B50 ; [.15CA.0020.0002.1B50][.0000.015F.0002.1B50] # BALINESE DIGIT ZERO +A9D0 ; [.15CA.0020.0002.A9D0][.0000.0160.0002.A9D0] # JAVANESE DIGIT ZERO +1BB0 ; [.15CA.0020.0002.1BB0][.0000.0161.0002.1BB0] # SUNDANESE DIGIT ZERO +1810 ; [.15CA.0020.0002.1810][.0000.0162.0002.1810] # MONGOLIAN DIGIT ZERO +1C50 ; [.15CA.0020.0002.1C50][.0000.0163.0002.1C50] # OL CHIKI DIGIT ZERO +A620 ; [.15CA.0020.0002.A620][.0000.0164.0002.A620] # VAI DIGIT ZERO +110F0 ; [.15CA.0020.0002.110F0][.0000.0165.0002.110F0] # SORA SOMPENG DIGIT ZERO +3007 ; [.15CA.0020.0002.3007][.0000.0166.0002.3007] # IDEOGRAPHIC NUMBER ZERO +1018A ; [.15CA.0020.0002.1018A][.0000.0168.0002.1018A] # GREEK ZERO SIGN +111D0 ; [.15CA.0020.0002.111D0][.0000.0172.0002.111D0] # SHARADA DIGIT ZERO +116C0 ; [.15CA.0020.0002.116C0][.0000.0173.0002.116C0] # TAKRI DIGIT ZERO +11066 ; [.15CA.0020.0002.11066][.0000.0174.0002.11066] # BRAHMI DIGIT ZERO +2189 ; [.15CA.0020.001E.2189][*05AC.0020.001E.2189][.15CD.0020.001F.2189] # VULGAR FRACTION ZERO THIRDS +3358 ; [.15CA.0020.0004.3358][.FB40.0020.0004.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO +0031 ; [.15CB.0020.0002.0031] # DIGIT ONE +FF11 ; [.15CB.0020.0003.FF11] # FULLWIDTH DIGIT ONE +2474 ; [*02FB.0020.0004.2474][.15CB.0020.0004.2474][*02FC.0020.001F.2474] # PARENTHESIZED DIGIT ONE +2488 ; [.15CB.0020.0004.2488][*0273.0020.0004.2488] # DIGIT ONE FULL STOP +1F102 ; [.15CB.0020.0004.1F102][*0221.0020.0004.1F102] # DIGIT ONE COMMA +1D7CF ; [.15CB.0020.0005.1D7CF] # MATHEMATICAL BOLD DIGIT ONE +1D7D9 ; [.15CB.0020.0005.1D7D9] # MATHEMATICAL DOUBLE-STRUCK DIGIT ONE +1D7E3 ; [.15CB.0020.0005.1D7E3] # MATHEMATICAL SANS-SERIF DIGIT ONE +1D7ED ; [.15CB.0020.0005.1D7ED] # MATHEMATICAL SANS-SERIF BOLD DIGIT ONE +1D7F7 ; [.15CB.0020.0005.1D7F7] # MATHEMATICAL MONOSPACE DIGIT ONE +2460 ; [.15CB.0020.0006.2460] # CIRCLED DIGIT ONE +24F5 ; [.15CB.0020.0006.24F5] # DOUBLE CIRCLED DIGIT ONE +2776 ; [.15CB.0020.0006.2776] # DINGBAT NEGATIVE CIRCLED DIGIT ONE +2780 ; [.15CB.0020.0006.2780] # DINGBAT CIRCLED SANS-SERIF DIGIT ONE +278A ; [.15CB.0020.0006.278A] # DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE +00B9 ; [.15CB.0020.0014.00B9] # SUPERSCRIPT ONE +2081 ; [.15CB.0020.0015.2081] # SUBSCRIPT ONE +215F ; [.15CB.0020.001E.215F][*05AC.0020.001E.215F] # FRACTION NUMERATOR ONE +0661 ; [.15CB.0020.0002.0661][.0000.013F.0002.0661] # ARABIC-INDIC DIGIT ONE +06F1 ; [.15CB.0020.0002.06F1][.0000.0140.0002.06F1] # EXTENDED ARABIC-INDIC DIGIT ONE +10E60 ; [.15CB.0020.0002.10E60][.0000.0141.0002.10E60] # RUMI DIGIT ONE +07C1 ; [.15CB.0020.0002.07C1][.0000.0142.0002.07C1] # NKO DIGIT ONE +1369 ; [.15CB.0020.0002.1369][.0000.0143.0002.1369] # ETHIOPIC DIGIT ONE +104A1 ; [.15CB.0020.0002.104A1][.0000.0144.0002.104A1] # OSMANYA DIGIT ONE +0967 ; [.15CB.0020.0002.0967][.0000.0145.0002.0967] # DEVANAGARI DIGIT ONE +09E7 ; [.15CB.0020.0002.09E7][.0000.0146.0002.09E7] # BENGALI DIGIT ONE +0A67 ; [.15CB.0020.0002.0A67][.0000.0147.0002.0A67] # GURMUKHI DIGIT ONE +0AE7 ; [.15CB.0020.0002.0AE7][.0000.0148.0002.0AE7] # GUJARATI DIGIT ONE +0B67 ; [.15CB.0020.0002.0B67][.0000.0149.0002.0B67] # ORIYA DIGIT ONE +0BE7 ; [.15CB.0020.0002.0BE7][.0000.014A.0002.0BE7] # TAMIL DIGIT ONE +0C67 ; [.15CB.0020.0002.0C67][.0000.014B.0002.0C67] # TELUGU DIGIT ONE +0C79 ; [.15CB.0020.0002.0C79][.0000.014B.0002.0C79] # TELUGU FRACTION DIGIT ONE FOR ODD POWERS OF FOUR +0C7C ; [.15CB.0020.0002.0C7C][.0000.014B.0002.0C7C] # TELUGU FRACTION DIGIT ONE FOR EVEN POWERS OF FOUR +0CE7 ; [.15CB.0020.0002.0CE7][.0000.014C.0002.0CE7] # KANNADA DIGIT ONE +0D67 ; [.15CB.0020.0002.0D67][.0000.014D.0002.0D67] # MALAYALAM DIGIT ONE +ABF1 ; [.15CB.0020.0002.ABF1][.0000.014E.0002.ABF1] # MEETEI MAYEK DIGIT ONE +A8D1 ; [.15CB.0020.0002.A8D1][.0000.014F.0002.A8D1] # SAURASHTRA DIGIT ONE +1947 ; [.15CB.0020.0002.1947][.0000.0150.0002.1947] # LIMBU DIGIT ONE +19D1 ; [.15CB.0020.0002.19D1][.0000.0151.0002.19D1] # NEW TAI LUE DIGIT ONE +19DA ; [.15CB.0020.0002.19DA][.0000.0151.0002.19DA] # NEW TAI LUE THAM DIGIT ONE +1A81 ; [.15CB.0020.0002.1A81][.0000.0152.0002.1A81] # TAI THAM HORA DIGIT ONE +1A91 ; [.15CB.0020.0002.1A91][.0000.0153.0002.1A91] # TAI THAM THAM DIGIT ONE +0E51 ; [.15CB.0020.0002.0E51][.0000.0154.0002.0E51] # THAI DIGIT ONE +0ED1 ; [.15CB.0020.0002.0ED1][.0000.0155.0002.0ED1] # LAO DIGIT ONE +0F21 ; [.15CB.0020.0002.0F21][.0000.0156.0002.0F21] # TIBETAN DIGIT ONE +0F2A ; [.15CB.0020.0004.0F2A][.0000.0156.0004.0F2A] # TIBETAN DIGIT HALF ONE +1C41 ; [.15CB.0020.0002.1C41][.0000.0157.0002.1C41] # LEPCHA DIGIT ONE +A901 ; [.15CB.0020.0002.A901][.0000.0158.0002.A901] # KAYAH LI DIGIT ONE +1041 ; [.15CB.0020.0002.1041][.0000.0159.0002.1041] # MYANMAR DIGIT ONE +1091 ; [.15CB.0020.0002.1091][.0000.015A.0002.1091] # MYANMAR SHAN DIGIT ONE +11137 ; [.15CB.0020.0002.11137][.0000.015B.0002.11137] # CHAKMA DIGIT ONE +17E1 ; [.15CB.0020.0002.17E1][.0000.015C.0002.17E1] # KHMER DIGIT ONE +17F1 ; [.15CB.0020.0002.17F1][.0000.015D.0002.17F1] # KHMER SYMBOL LEK ATTAK MUOY +AA51 ; [.15CB.0020.0002.AA51][.0000.015E.0002.AA51] # CHAM DIGIT ONE +1B51 ; [.15CB.0020.0002.1B51][.0000.015F.0002.1B51] # BALINESE DIGIT ONE +A9D1 ; [.15CB.0020.0002.A9D1][.0000.0160.0002.A9D1] # JAVANESE DIGIT ONE +1BB1 ; [.15CB.0020.0002.1BB1][.0000.0161.0002.1BB1] # SUNDANESE DIGIT ONE +1811 ; [.15CB.0020.0002.1811][.0000.0162.0002.1811] # MONGOLIAN DIGIT ONE +1C51 ; [.15CB.0020.0002.1C51][.0000.0163.0002.1C51] # OL CHIKI DIGIT ONE +A621 ; [.15CB.0020.0002.A621][.0000.0164.0002.A621] # VAI DIGIT ONE +110F1 ; [.15CB.0020.0002.110F1][.0000.0165.0002.110F1] # SORA SOMPENG DIGIT ONE +3021 ; [.15CB.0020.0002.3021][.0000.0166.0002.3021] # HANGZHOU NUMERAL ONE +10107 ; [.15CB.0020.0002.10107][.0000.0167.0002.10107] # AEGEAN NUMBER ONE +10142 ; [.15CB.0020.0002.10142][.0000.0168.0002.10142] # GREEK ACROPHONIC ATTIC ONE DRACHMA +10158 ; [.15CB.0020.0002.10158][.0000.0168.0002.10158] # GREEK ACROPHONIC HERAEUM ONE PLETHRON +10159 ; [.15CB.0020.0002.10159][.0000.0168.0002.10159] # GREEK ACROPHONIC THESPIAN ONE +1015A ; [.15CB.0020.0002.1015A][.0000.0168.0002.1015A] # GREEK ACROPHONIC HERMIONIAN ONE +10320 ; [.15CB.0020.0002.10320][.0000.016A.0002.10320] # OLD ITALIC NUMERAL ONE +103D1 ; [.15CB.0020.0002.103D1][.0000.016B.0002.103D1] # OLD PERSIAN NUMBER ONE +12415 ; [.15CB.0020.0002.12415][.0000.016C.0002.12415] # CUNEIFORM NUMERIC SIGN ONE GESH2 +1241E ; [.15CB.0020.0002.1241E][.0000.016C.0002.1241E] # CUNEIFORM NUMERIC SIGN ONE GESHU +1242C ; [.15CB.0020.0002.1242C][.0000.016C.0002.1242C] # CUNEIFORM NUMERIC SIGN ONE SHARU +12434 ; [.15CB.0020.0002.12434][.0000.016C.0002.12434] # CUNEIFORM NUMERIC SIGN ONE BURU +1244F ; [.15CB.0020.0002.1244F][.0000.016C.0002.1244F] # CUNEIFORM NUMERIC SIGN ONE BAN2 +12458 ; [.15CB.0020.0002.12458][.0000.016C.0002.12458] # CUNEIFORM NUMERIC SIGN ONE ESHE3 +10A7D ; [.15CB.0020.0002.10A7D][.0000.016D.0002.10A7D] # OLD SOUTH ARABIAN NUMBER ONE +10916 ; [.15CB.0020.0002.10916][.0000.016E.0002.10916] # PHOENICIAN NUMBER ONE +10858 ; [.15CB.0020.0002.10858][.0000.016F.0002.10858] # IMPERIAL ARAMAIC NUMBER ONE +10B58 ; [.15CB.0020.0002.10B58][.0000.0170.0002.10B58] # INSCRIPTIONAL PARTHIAN NUMBER ONE +10B78 ; [.15CB.0020.0002.10B78][.0000.0171.0002.10B78] # INSCRIPTIONAL PAHLAVI NUMBER ONE +111D1 ; [.15CB.0020.0002.111D1][.0000.0172.0002.111D1] # SHARADA DIGIT ONE +116C1 ; [.15CB.0020.0002.116C1][.0000.0173.0002.116C1] # TAKRI DIGIT ONE +11067 ; [.15CB.0020.0002.11067][.0000.0174.0002.11067] # BRAHMI DIGIT ONE +11052 ; [.15CB.0020.0002.11052][.0000.0175.0002.11052] # BRAHMI NUMBER ONE +10A40 ; [.15CB.0020.0002.10A40][.0000.0176.0002.10A40] # KHAROSHTHI DIGIT ONE +1D360 ; [.15CB.0020.0002.1D360][.0000.0177.0002.1D360] # COUNTING ROD UNIT DIGIT ONE +2491 ; [.15CB.0020.0004.2491][.15CA.0020.0004.2491][*0273.0020.001F.2491] # NUMBER TEN FULL STOP +247D ; [*02FB.0020.0004.247D][.15CB.0020.0004.247D][.15CA.0020.001F.247D][*02FC.0020.001F.247D] # PARENTHESIZED NUMBER TEN +2469 ; [.15CB.0020.0006.2469][.15CA.0020.0006.2469] # CIRCLED NUMBER TEN +24FE ; [.15CB.0020.0006.24FE][.15CA.0020.0006.24FE] # DOUBLE CIRCLED NUMBER TEN +277F ; [.15CB.0020.0006.277F][.15CA.0020.0006.277F] # DINGBAT NEGATIVE CIRCLED NUMBER TEN +2789 ; [.15CB.0020.0006.2789][.15CA.0020.0006.2789] # DINGBAT CIRCLED SANS-SERIF NUMBER TEN +2793 ; [.15CB.0020.0006.2793][.15CA.0020.0006.2793] # DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN +3248 ; [.15CB.0020.0006.3248][.15CA.0020.0006.3248] # CIRCLED NUMBER TEN ON BLACK SQUARE +33E9 ; [.15CB.0020.0004.33E9][.15CA.0020.0004.33E9][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN +32C9 ; [.15CB.0020.0004.32C9][.15CA.0020.0004.32C9][.FB40.0020.001F.6708][.E708.0000.0000.6708] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER +3362 ; [.15CB.0020.0004.3362][.15CA.0020.0004.3362][.FB40.0020.001F.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN +2492 ; [.15CB.0020.0004.2492][.15CB.0020.0004.2492][*0273.0020.001F.2492] # NUMBER ELEVEN FULL STOP +247E ; [*02FB.0020.0004.247E][.15CB.0020.0004.247E][.15CB.0020.001F.247E][*02FC.0020.001F.247E] # PARENTHESIZED NUMBER ELEVEN +246A ; [.15CB.0020.0006.246A][.15CB.0020.0006.246A] # CIRCLED NUMBER ELEVEN +24EB ; [.15CB.0020.0006.24EB][.15CB.0020.0006.24EB] # NEGATIVE CIRCLED NUMBER ELEVEN +2152 ; [.15CB.0020.001E.2152][*05AC.0020.001E.2152][.15CB.0020.001F.2152][.15CA.0020.001F.2152] # VULGAR FRACTION ONE TENTH +33EA ; [.15CB.0020.0004.33EA][.15CB.0020.0004.33EA][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN +32CA ; [.15CB.0020.0004.32CA][.15CB.0020.0004.32CA][.FB40.0020.001F.6708][.E708.0000.0000.6708] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER +3363 ; [.15CB.0020.0004.3363][.15CB.0020.0004.3363][.FB40.0020.001F.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN +2493 ; [.15CB.0020.0004.2493][.15CC.0020.0004.2493][*0273.0020.001F.2493] # NUMBER TWELVE FULL STOP +247F ; [*02FB.0020.0004.247F][.15CB.0020.0004.247F][.15CC.0020.001F.247F][*02FC.0020.001F.247F] # PARENTHESIZED NUMBER TWELVE +246B ; [.15CB.0020.0006.246B][.15CC.0020.0006.246B] # CIRCLED NUMBER TWELVE +24EC ; [.15CB.0020.0006.24EC][.15CC.0020.0006.24EC] # NEGATIVE CIRCLED NUMBER TWELVE +00BD ; [.15CB.0020.001E.00BD][*05AC.0020.001E.00BD][.15CC.0020.001F.00BD] # VULGAR FRACTION ONE HALF +33EB ; [.15CB.0020.0004.33EB][.15CC.0020.0004.33EB][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE +32CB ; [.15CB.0020.0004.32CB][.15CC.0020.0004.32CB][.FB40.0020.001F.6708][.E708.0000.0000.6708] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER +3364 ; [.15CB.0020.0004.3364][.15CC.0020.0004.3364][.FB40.0020.001F.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE +2494 ; [.15CB.0020.0004.2494][.15CD.0020.0004.2494][*0273.0020.001F.2494] # NUMBER THIRTEEN FULL STOP +2480 ; [*02FB.0020.0004.2480][.15CB.0020.0004.2480][.15CD.0020.001F.2480][*02FC.0020.001F.2480] # PARENTHESIZED NUMBER THIRTEEN +246C ; [.15CB.0020.0006.246C][.15CD.0020.0006.246C] # CIRCLED NUMBER THIRTEEN +24ED ; [.15CB.0020.0006.24ED][.15CD.0020.0006.24ED] # NEGATIVE CIRCLED NUMBER THIRTEEN +2153 ; [.15CB.0020.001E.2153][*05AC.0020.001E.2153][.15CD.0020.001F.2153] # VULGAR FRACTION ONE THIRD +33EC ; [.15CB.0020.0004.33EC][.15CD.0020.0004.33EC][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN +3365 ; [.15CB.0020.0004.3365][.15CD.0020.0004.3365][.FB40.0020.001F.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN +2495 ; [.15CB.0020.0004.2495][.15CE.0020.0004.2495][*0273.0020.001F.2495] # NUMBER FOURTEEN FULL STOP +2481 ; [*02FB.0020.0004.2481][.15CB.0020.0004.2481][.15CE.0020.001F.2481][*02FC.0020.001F.2481] # PARENTHESIZED NUMBER FOURTEEN +246D ; [.15CB.0020.0006.246D][.15CE.0020.0006.246D] # CIRCLED NUMBER FOURTEEN +24EE ; [.15CB.0020.0006.24EE][.15CE.0020.0006.24EE] # NEGATIVE CIRCLED NUMBER FOURTEEN +00BC ; [.15CB.0020.001E.00BC][*05AC.0020.001E.00BC][.15CE.0020.001F.00BC] # VULGAR FRACTION ONE QUARTER +33ED ; [.15CB.0020.0004.33ED][.15CE.0020.0004.33ED][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN +3366 ; [.15CB.0020.0004.3366][.15CE.0020.0004.3366][.FB40.0020.001F.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN +2496 ; [.15CB.0020.0004.2496][.15CF.0020.0004.2496][*0273.0020.001F.2496] # NUMBER FIFTEEN FULL STOP +2482 ; [*02FB.0020.0004.2482][.15CB.0020.0004.2482][.15CF.0020.001F.2482][*02FC.0020.001F.2482] # PARENTHESIZED NUMBER FIFTEEN +246E ; [.15CB.0020.0006.246E][.15CF.0020.0006.246E] # CIRCLED NUMBER FIFTEEN +24EF ; [.15CB.0020.0006.24EF][.15CF.0020.0006.24EF] # NEGATIVE CIRCLED NUMBER FIFTEEN +2155 ; [.15CB.0020.001E.2155][*05AC.0020.001E.2155][.15CF.0020.001F.2155] # VULGAR FRACTION ONE FIFTH +33EE ; [.15CB.0020.0004.33EE][.15CF.0020.0004.33EE][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN +3367 ; [.15CB.0020.0004.3367][.15CF.0020.0004.3367][.FB40.0020.001F.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN +2497 ; [.15CB.0020.0004.2497][.15D0.0020.0004.2497][*0273.0020.001F.2497] # NUMBER SIXTEEN FULL STOP +2483 ; [*02FB.0020.0004.2483][.15CB.0020.0004.2483][.15D0.0020.001F.2483][*02FC.0020.001F.2483] # PARENTHESIZED NUMBER SIXTEEN +246F ; [.15CB.0020.0006.246F][.15D0.0020.0006.246F] # CIRCLED NUMBER SIXTEEN +24F0 ; [.15CB.0020.0006.24F0][.15D0.0020.0006.24F0] # NEGATIVE CIRCLED NUMBER SIXTEEN +2159 ; [.15CB.0020.001E.2159][*05AC.0020.001E.2159][.15D0.0020.001F.2159] # VULGAR FRACTION ONE SIXTH +33EF ; [.15CB.0020.0004.33EF][.15D0.0020.0004.33EF][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN +3368 ; [.15CB.0020.0004.3368][.15D0.0020.0004.3368][.FB40.0020.001F.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN +2498 ; [.15CB.0020.0004.2498][.15D1.0020.0004.2498][*0273.0020.001F.2498] # NUMBER SEVENTEEN FULL STOP +2484 ; [*02FB.0020.0004.2484][.15CB.0020.0004.2484][.15D1.0020.001F.2484][*02FC.0020.001F.2484] # PARENTHESIZED NUMBER SEVENTEEN +2470 ; [.15CB.0020.0006.2470][.15D1.0020.0006.2470] # CIRCLED NUMBER SEVENTEEN +24F1 ; [.15CB.0020.0006.24F1][.15D1.0020.0006.24F1] # NEGATIVE CIRCLED NUMBER SEVENTEEN +2150 ; [.15CB.0020.001E.2150][*05AC.0020.001E.2150][.15D1.0020.001F.2150] # VULGAR FRACTION ONE SEVENTH +33F0 ; [.15CB.0020.0004.33F0][.15D1.0020.0004.33F0][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN +3369 ; [.15CB.0020.0004.3369][.15D1.0020.0004.3369][.FB40.0020.001F.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN +2499 ; [.15CB.0020.0004.2499][.15D2.0020.0004.2499][*0273.0020.001F.2499] # NUMBER EIGHTEEN FULL STOP +2485 ; [*02FB.0020.0004.2485][.15CB.0020.0004.2485][.15D2.0020.001F.2485][*02FC.0020.001F.2485] # PARENTHESIZED NUMBER EIGHTEEN +2471 ; [.15CB.0020.0006.2471][.15D2.0020.0006.2471] # CIRCLED NUMBER EIGHTEEN +24F2 ; [.15CB.0020.0006.24F2][.15D2.0020.0006.24F2] # NEGATIVE CIRCLED NUMBER EIGHTEEN +215B ; [.15CB.0020.001E.215B][*05AC.0020.001E.215B][.15D2.0020.001F.215B] # VULGAR FRACTION ONE EIGHTH +33F1 ; [.15CB.0020.0004.33F1][.15D2.0020.0004.33F1][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN +336A ; [.15CB.0020.0004.336A][.15D2.0020.0004.336A][.FB40.0020.001F.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN +249A ; [.15CB.0020.0004.249A][.15D3.0020.0004.249A][*0273.0020.001F.249A] # NUMBER NINETEEN FULL STOP +2486 ; [*02FB.0020.0004.2486][.15CB.0020.0004.2486][.15D3.0020.001F.2486][*02FC.0020.001F.2486] # PARENTHESIZED NUMBER NINETEEN +2472 ; [.15CB.0020.0006.2472][.15D3.0020.0006.2472] # CIRCLED NUMBER NINETEEN +24F3 ; [.15CB.0020.0006.24F3][.15D3.0020.0006.24F3] # NEGATIVE CIRCLED NUMBER NINETEEN +2151 ; [.15CB.0020.001E.2151][*05AC.0020.001E.2151][.15D3.0020.001F.2151] # VULGAR FRACTION ONE NINTH +33F2 ; [.15CB.0020.0004.33F2][.15D3.0020.0004.33F2][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN +336B ; [.15CB.0020.0004.336B][.15D3.0020.0004.336B][.FB40.0020.001F.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN +33E0 ; [.15CB.0020.0004.33E0][.FB40.0020.0004.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE +32C0 ; [.15CB.0020.0004.32C0][.FB40.0020.0004.6708][.E708.0000.0000.6708] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY +3359 ; [.15CB.0020.0004.3359][.FB40.0020.0004.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE +0032 ; [.15CC.0020.0002.0032] # DIGIT TWO +FF12 ; [.15CC.0020.0003.FF12] # FULLWIDTH DIGIT TWO +2475 ; [*02FB.0020.0004.2475][.15CC.0020.0004.2475][*02FC.0020.001F.2475] # PARENTHESIZED DIGIT TWO +2489 ; [.15CC.0020.0004.2489][*0273.0020.0004.2489] # DIGIT TWO FULL STOP +1F103 ; [.15CC.0020.0004.1F103][*0221.0020.0004.1F103] # DIGIT TWO COMMA +1D7D0 ; [.15CC.0020.0005.1D7D0] # MATHEMATICAL BOLD DIGIT TWO +1D7DA ; [.15CC.0020.0005.1D7DA] # MATHEMATICAL DOUBLE-STRUCK DIGIT TWO +1D7E4 ; [.15CC.0020.0005.1D7E4] # MATHEMATICAL SANS-SERIF DIGIT TWO +1D7EE ; [.15CC.0020.0005.1D7EE] # MATHEMATICAL SANS-SERIF BOLD DIGIT TWO +1D7F8 ; [.15CC.0020.0005.1D7F8] # MATHEMATICAL MONOSPACE DIGIT TWO +2461 ; [.15CC.0020.0006.2461] # CIRCLED DIGIT TWO +24F6 ; [.15CC.0020.0006.24F6] # DOUBLE CIRCLED DIGIT TWO +2777 ; [.15CC.0020.0006.2777] # DINGBAT NEGATIVE CIRCLED DIGIT TWO +2781 ; [.15CC.0020.0006.2781] # DINGBAT CIRCLED SANS-SERIF DIGIT TWO +278B ; [.15CC.0020.0006.278B] # DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO +00B2 ; [.15CC.0020.0014.00B2] # SUPERSCRIPT TWO +2082 ; [.15CC.0020.0015.2082] # SUBSCRIPT TWO +0662 ; [.15CC.0020.0002.0662][.0000.013F.0002.0662] # ARABIC-INDIC DIGIT TWO +06F2 ; [.15CC.0020.0002.06F2][.0000.0140.0002.06F2] # EXTENDED ARABIC-INDIC DIGIT TWO +10E61 ; [.15CC.0020.0002.10E61][.0000.0141.0002.10E61] # RUMI DIGIT TWO +07C2 ; [.15CC.0020.0002.07C2][.0000.0142.0002.07C2] # NKO DIGIT TWO +136A ; [.15CC.0020.0002.136A][.0000.0143.0002.136A] # ETHIOPIC DIGIT TWO +104A2 ; [.15CC.0020.0002.104A2][.0000.0144.0002.104A2] # OSMANYA DIGIT TWO +0968 ; [.15CC.0020.0002.0968][.0000.0145.0002.0968] # DEVANAGARI DIGIT TWO +09E8 ; [.15CC.0020.0002.09E8][.0000.0146.0002.09E8] # BENGALI DIGIT TWO +0A68 ; [.15CC.0020.0002.0A68][.0000.0147.0002.0A68] # GURMUKHI DIGIT TWO +0AE8 ; [.15CC.0020.0002.0AE8][.0000.0148.0002.0AE8] # GUJARATI DIGIT TWO +0B68 ; [.15CC.0020.0002.0B68][.0000.0149.0002.0B68] # ORIYA DIGIT TWO +0BE8 ; [.15CC.0020.0002.0BE8][.0000.014A.0002.0BE8] # TAMIL DIGIT TWO +0C68 ; [.15CC.0020.0002.0C68][.0000.014B.0002.0C68] # TELUGU DIGIT TWO +0C7A ; [.15CC.0020.0002.0C7A][.0000.014B.0002.0C7A] # TELUGU FRACTION DIGIT TWO FOR ODD POWERS OF FOUR +0C7D ; [.15CC.0020.0002.0C7D][.0000.014B.0002.0C7D] # TELUGU FRACTION DIGIT TWO FOR EVEN POWERS OF FOUR +0CE8 ; [.15CC.0020.0002.0CE8][.0000.014C.0002.0CE8] # KANNADA DIGIT TWO +0D68 ; [.15CC.0020.0002.0D68][.0000.014D.0002.0D68] # MALAYALAM DIGIT TWO +ABF2 ; [.15CC.0020.0002.ABF2][.0000.014E.0002.ABF2] # MEETEI MAYEK DIGIT TWO +A8D2 ; [.15CC.0020.0002.A8D2][.0000.014F.0002.A8D2] # SAURASHTRA DIGIT TWO +1948 ; [.15CC.0020.0002.1948][.0000.0150.0002.1948] # LIMBU DIGIT TWO +19D2 ; [.15CC.0020.0002.19D2][.0000.0151.0002.19D2] # NEW TAI LUE DIGIT TWO +1A82 ; [.15CC.0020.0002.1A82][.0000.0152.0002.1A82] # TAI THAM HORA DIGIT TWO +1A92 ; [.15CC.0020.0002.1A92][.0000.0153.0002.1A92] # TAI THAM THAM DIGIT TWO +0E52 ; [.15CC.0020.0002.0E52][.0000.0154.0002.0E52] # THAI DIGIT TWO +0ED2 ; [.15CC.0020.0002.0ED2][.0000.0155.0002.0ED2] # LAO DIGIT TWO +0F22 ; [.15CC.0020.0002.0F22][.0000.0156.0002.0F22] # TIBETAN DIGIT TWO +0F2B ; [.15CC.0020.0004.0F2B][.0000.0156.0004.0F2B] # TIBETAN DIGIT HALF TWO +1C42 ; [.15CC.0020.0002.1C42][.0000.0157.0002.1C42] # LEPCHA DIGIT TWO +A902 ; [.15CC.0020.0002.A902][.0000.0158.0002.A902] # KAYAH LI DIGIT TWO +1042 ; [.15CC.0020.0002.1042][.0000.0159.0002.1042] # MYANMAR DIGIT TWO +1092 ; [.15CC.0020.0002.1092][.0000.015A.0002.1092] # MYANMAR SHAN DIGIT TWO +11138 ; [.15CC.0020.0002.11138][.0000.015B.0002.11138] # CHAKMA DIGIT TWO +17E2 ; [.15CC.0020.0002.17E2][.0000.015C.0002.17E2] # KHMER DIGIT TWO +17F2 ; [.15CC.0020.0002.17F2][.0000.015D.0002.17F2] # KHMER SYMBOL LEK ATTAK PII +AA52 ; [.15CC.0020.0002.AA52][.0000.015E.0002.AA52] # CHAM DIGIT TWO +1B52 ; [.15CC.0020.0002.1B52][.0000.015F.0002.1B52] # BALINESE DIGIT TWO +A9D2 ; [.15CC.0020.0002.A9D2][.0000.0160.0002.A9D2] # JAVANESE DIGIT TWO +1BB2 ; [.15CC.0020.0002.1BB2][.0000.0161.0002.1BB2] # SUNDANESE DIGIT TWO +1812 ; [.15CC.0020.0002.1812][.0000.0162.0002.1812] # MONGOLIAN DIGIT TWO +1C52 ; [.15CC.0020.0002.1C52][.0000.0163.0002.1C52] # OL CHIKI DIGIT TWO +A622 ; [.15CC.0020.0002.A622][.0000.0164.0002.A622] # VAI DIGIT TWO +110F2 ; [.15CC.0020.0002.110F2][.0000.0165.0002.110F2] # SORA SOMPENG DIGIT TWO +3022 ; [.15CC.0020.0002.3022][.0000.0166.0002.3022] # HANGZHOU NUMERAL TWO +10108 ; [.15CC.0020.0002.10108][.0000.0167.0002.10108] # AEGEAN NUMBER TWO +1015B ; [.15CC.0020.0002.1015B][.0000.0168.0002.1015B] # GREEK ACROPHONIC EPIDAUREAN TWO +1015C ; [.15CC.0020.0002.1015C][.0000.0168.0002.1015C] # GREEK ACROPHONIC THESPIAN TWO +1015D ; [.15CC.0020.0002.1015D][.0000.0168.0002.1015D] # GREEK ACROPHONIC CYRENAIC TWO DRACHMAS +1015E ; [.15CC.0020.0002.1015E][.0000.0168.0002.1015E] # GREEK ACROPHONIC EPIDAUREAN TWO DRACHMAS +103D2 ; [.15CC.0020.0002.103D2][.0000.016B.0002.103D2] # OLD PERSIAN NUMBER TWO +12400 ; [.15CC.0020.0002.12400][.0000.016C.0002.12400] # CUNEIFORM NUMERIC SIGN TWO ASH +12416 ; [.15CC.0020.0002.12416][.0000.016C.0002.12416] # CUNEIFORM NUMERIC SIGN TWO GESH2 +1241F ; [.15CC.0020.0002.1241F][.0000.016C.0002.1241F] # CUNEIFORM NUMERIC SIGN TWO GESHU +12423 ; [.15CC.0020.0002.12423][.0000.016C.0002.12423] # CUNEIFORM NUMERIC SIGN TWO SHAR2 +1242D ; [.15CC.0020.0002.1242D][.0000.016C.0002.1242D] # CUNEIFORM NUMERIC SIGN TWO SHARU +12435 ; [.15CC.0020.0002.12435][.0000.016C.0002.12435] # CUNEIFORM NUMERIC SIGN TWO BURU +1244A ; [.15CC.0020.0002.1244A][.0000.016C.0002.1244A] # CUNEIFORM NUMERIC SIGN TWO ASH TENU +12450 ; [.15CC.0020.0002.12450][.0000.016C.0002.12450] # CUNEIFORM NUMERIC SIGN TWO BAN2 +12459 ; [.15CC.0020.0002.12459][.0000.016C.0002.12459] # CUNEIFORM NUMERIC SIGN TWO ESHE3 +1091A ; [.15CC.0020.0002.1091A][.0000.016E.0002.1091A] # PHOENICIAN NUMBER TWO +10859 ; [.15CC.0020.0002.10859][.0000.016F.0002.10859] # IMPERIAL ARAMAIC NUMBER TWO +10B59 ; [.15CC.0020.0002.10B59][.0000.0170.0002.10B59] # INSCRIPTIONAL PARTHIAN NUMBER TWO +10B79 ; [.15CC.0020.0002.10B79][.0000.0171.0002.10B79] # INSCRIPTIONAL PAHLAVI NUMBER TWO +111D2 ; [.15CC.0020.0002.111D2][.0000.0172.0002.111D2] # SHARADA DIGIT TWO +116C2 ; [.15CC.0020.0002.116C2][.0000.0173.0002.116C2] # TAKRI DIGIT TWO +11068 ; [.15CC.0020.0002.11068][.0000.0174.0002.11068] # BRAHMI DIGIT TWO +11053 ; [.15CC.0020.0002.11053][.0000.0175.0002.11053] # BRAHMI NUMBER TWO +10A41 ; [.15CC.0020.0002.10A41][.0000.0176.0002.10A41] # KHAROSHTHI DIGIT TWO +1D361 ; [.15CC.0020.0002.1D361][.0000.0177.0002.1D361] # COUNTING ROD UNIT DIGIT TWO +249B ; [.15CC.0020.0004.249B][.15CA.0020.0004.249B][*0273.0020.001F.249B] # NUMBER TWENTY FULL STOP +2487 ; [*02FB.0020.0004.2487][.15CC.0020.0004.2487][.15CA.0020.001F.2487][*02FC.0020.001F.2487] # PARENTHESIZED NUMBER TWENTY +2473 ; [.15CC.0020.0006.2473][.15CA.0020.0006.2473] # CIRCLED NUMBER TWENTY +24F4 ; [.15CC.0020.0006.24F4][.15CA.0020.0006.24F4] # NEGATIVE CIRCLED NUMBER TWENTY +3249 ; [.15CC.0020.0006.3249][.15CA.0020.0006.3249] # CIRCLED NUMBER TWENTY ON BLACK SQUARE +33F3 ; [.15CC.0020.0004.33F3][.15CA.0020.0004.33F3][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY +336C ; [.15CC.0020.0004.336C][.15CA.0020.0004.336C][.FB40.0020.001F.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY +3251 ; [.15CC.0020.0006.3251][.15CB.0020.0006.3251] # CIRCLED NUMBER TWENTY ONE +33F4 ; [.15CC.0020.0004.33F4][.15CB.0020.0004.33F4][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE +336D ; [.15CC.0020.0004.336D][.15CB.0020.0004.336D][.FB40.0020.001F.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE +3252 ; [.15CC.0020.0006.3252][.15CC.0020.0006.3252] # CIRCLED NUMBER TWENTY TWO +33F5 ; [.15CC.0020.0004.33F5][.15CC.0020.0004.33F5][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO +336E ; [.15CC.0020.0004.336E][.15CC.0020.0004.336E][.FB40.0020.001F.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO +3253 ; [.15CC.0020.0006.3253][.15CD.0020.0006.3253] # CIRCLED NUMBER TWENTY THREE +2154 ; [.15CC.0020.001E.2154][*05AC.0020.001E.2154][.15CD.0020.001F.2154] # VULGAR FRACTION TWO THIRDS +33F6 ; [.15CC.0020.0004.33F6][.15CD.0020.0004.33F6][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE +336F ; [.15CC.0020.0004.336F][.15CD.0020.0004.336F][.FB40.0020.001F.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE +3254 ; [.15CC.0020.0006.3254][.15CE.0020.0006.3254] # CIRCLED NUMBER TWENTY FOUR +33F7 ; [.15CC.0020.0004.33F7][.15CE.0020.0004.33F7][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR +3370 ; [.15CC.0020.0004.3370][.15CE.0020.0004.3370][.FB40.0020.001F.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR +3255 ; [.15CC.0020.0006.3255][.15CF.0020.0006.3255] # CIRCLED NUMBER TWENTY FIVE +2156 ; [.15CC.0020.001E.2156][*05AC.0020.001E.2156][.15CF.0020.001F.2156] # VULGAR FRACTION TWO FIFTHS +33F8 ; [.15CC.0020.0004.33F8][.15CF.0020.0004.33F8][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE +3256 ; [.15CC.0020.0006.3256][.15D0.0020.0006.3256] # CIRCLED NUMBER TWENTY SIX +33F9 ; [.15CC.0020.0004.33F9][.15D0.0020.0004.33F9][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX +3257 ; [.15CC.0020.0006.3257][.15D1.0020.0006.3257] # CIRCLED NUMBER TWENTY SEVEN +33FA ; [.15CC.0020.0004.33FA][.15D1.0020.0004.33FA][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN +3258 ; [.15CC.0020.0006.3258][.15D2.0020.0006.3258] # CIRCLED NUMBER TWENTY EIGHT +33FB ; [.15CC.0020.0004.33FB][.15D2.0020.0004.33FB][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT +3259 ; [.15CC.0020.0006.3259][.15D3.0020.0006.3259] # CIRCLED NUMBER TWENTY NINE +33FC ; [.15CC.0020.0004.33FC][.15D3.0020.0004.33FC][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE +33E1 ; [.15CC.0020.0004.33E1][.FB40.0020.0004.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO +32C1 ; [.15CC.0020.0004.32C1][.FB40.0020.0004.6708][.E708.0000.0000.6708] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY +335A ; [.15CC.0020.0004.335A][.FB40.0020.0004.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO +0033 ; [.15CD.0020.0002.0033] # DIGIT THREE +FF13 ; [.15CD.0020.0003.FF13] # FULLWIDTH DIGIT THREE +2476 ; [*02FB.0020.0004.2476][.15CD.0020.0004.2476][*02FC.0020.001F.2476] # PARENTHESIZED DIGIT THREE +248A ; [.15CD.0020.0004.248A][*0273.0020.0004.248A] # DIGIT THREE FULL STOP +1F104 ; [.15CD.0020.0004.1F104][*0221.0020.0004.1F104] # DIGIT THREE COMMA +1D7D1 ; [.15CD.0020.0005.1D7D1] # MATHEMATICAL BOLD DIGIT THREE +1D7DB ; [.15CD.0020.0005.1D7DB] # MATHEMATICAL DOUBLE-STRUCK DIGIT THREE +1D7E5 ; [.15CD.0020.0005.1D7E5] # MATHEMATICAL SANS-SERIF DIGIT THREE +1D7EF ; [.15CD.0020.0005.1D7EF] # MATHEMATICAL SANS-SERIF BOLD DIGIT THREE +1D7F9 ; [.15CD.0020.0005.1D7F9] # MATHEMATICAL MONOSPACE DIGIT THREE +2462 ; [.15CD.0020.0006.2462] # CIRCLED DIGIT THREE +24F7 ; [.15CD.0020.0006.24F7] # DOUBLE CIRCLED DIGIT THREE +2778 ; [.15CD.0020.0006.2778] # DINGBAT NEGATIVE CIRCLED DIGIT THREE +2782 ; [.15CD.0020.0006.2782] # DINGBAT CIRCLED SANS-SERIF DIGIT THREE +278C ; [.15CD.0020.0006.278C] # DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE +00B3 ; [.15CD.0020.0014.00B3] # SUPERSCRIPT THREE +2083 ; [.15CD.0020.0015.2083] # SUBSCRIPT THREE +0663 ; [.15CD.0020.0002.0663][.0000.013F.0002.0663] # ARABIC-INDIC DIGIT THREE +06F3 ; [.15CD.0020.0002.06F3][.0000.0140.0002.06F3] # EXTENDED ARABIC-INDIC DIGIT THREE +10E62 ; [.15CD.0020.0002.10E62][.0000.0141.0002.10E62] # RUMI DIGIT THREE +07C3 ; [.15CD.0020.0002.07C3][.0000.0142.0002.07C3] # NKO DIGIT THREE +136B ; [.15CD.0020.0002.136B][.0000.0143.0002.136B] # ETHIOPIC DIGIT THREE +104A3 ; [.15CD.0020.0002.104A3][.0000.0144.0002.104A3] # OSMANYA DIGIT THREE +0969 ; [.15CD.0020.0002.0969][.0000.0145.0002.0969] # DEVANAGARI DIGIT THREE +09E9 ; [.15CD.0020.0002.09E9][.0000.0146.0002.09E9] # BENGALI DIGIT THREE +0A69 ; [.15CD.0020.0002.0A69][.0000.0147.0002.0A69] # GURMUKHI DIGIT THREE +0AE9 ; [.15CD.0020.0002.0AE9][.0000.0148.0002.0AE9] # GUJARATI DIGIT THREE +0B69 ; [.15CD.0020.0002.0B69][.0000.0149.0002.0B69] # ORIYA DIGIT THREE +0BE9 ; [.15CD.0020.0002.0BE9][.0000.014A.0002.0BE9] # TAMIL DIGIT THREE +0C69 ; [.15CD.0020.0002.0C69][.0000.014B.0002.0C69] # TELUGU DIGIT THREE +0C7B ; [.15CD.0020.0002.0C7B][.0000.014B.0002.0C7B] # TELUGU FRACTION DIGIT THREE FOR ODD POWERS OF FOUR +0C7E ; [.15CD.0020.0002.0C7E][.0000.014B.0002.0C7E] # TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR +0CE9 ; [.15CD.0020.0002.0CE9][.0000.014C.0002.0CE9] # KANNADA DIGIT THREE +0D69 ; [.15CD.0020.0002.0D69][.0000.014D.0002.0D69] # MALAYALAM DIGIT THREE +ABF3 ; [.15CD.0020.0002.ABF3][.0000.014E.0002.ABF3] # MEETEI MAYEK DIGIT THREE +A8D3 ; [.15CD.0020.0002.A8D3][.0000.014F.0002.A8D3] # SAURASHTRA DIGIT THREE +1949 ; [.15CD.0020.0002.1949][.0000.0150.0002.1949] # LIMBU DIGIT THREE +19D3 ; [.15CD.0020.0002.19D3][.0000.0151.0002.19D3] # NEW TAI LUE DIGIT THREE +1A83 ; [.15CD.0020.0002.1A83][.0000.0152.0002.1A83] # TAI THAM HORA DIGIT THREE +1A93 ; [.15CD.0020.0002.1A93][.0000.0153.0002.1A93] # TAI THAM THAM DIGIT THREE +0E53 ; [.15CD.0020.0002.0E53][.0000.0154.0002.0E53] # THAI DIGIT THREE +0ED3 ; [.15CD.0020.0002.0ED3][.0000.0155.0002.0ED3] # LAO DIGIT THREE +0F23 ; [.15CD.0020.0002.0F23][.0000.0156.0002.0F23] # TIBETAN DIGIT THREE +0F2C ; [.15CD.0020.0004.0F2C][.0000.0156.0004.0F2C] # TIBETAN DIGIT HALF THREE +1C43 ; [.15CD.0020.0002.1C43][.0000.0157.0002.1C43] # LEPCHA DIGIT THREE +A903 ; [.15CD.0020.0002.A903][.0000.0158.0002.A903] # KAYAH LI DIGIT THREE +1043 ; [.15CD.0020.0002.1043][.0000.0159.0002.1043] # MYANMAR DIGIT THREE +1093 ; [.15CD.0020.0002.1093][.0000.015A.0002.1093] # MYANMAR SHAN DIGIT THREE +11139 ; [.15CD.0020.0002.11139][.0000.015B.0002.11139] # CHAKMA DIGIT THREE +17E3 ; [.15CD.0020.0002.17E3][.0000.015C.0002.17E3] # KHMER DIGIT THREE +17F3 ; [.15CD.0020.0002.17F3][.0000.015D.0002.17F3] # KHMER SYMBOL LEK ATTAK BEI +AA53 ; [.15CD.0020.0002.AA53][.0000.015E.0002.AA53] # CHAM DIGIT THREE +1B53 ; [.15CD.0020.0002.1B53][.0000.015F.0002.1B53] # BALINESE DIGIT THREE +A9D3 ; [.15CD.0020.0002.A9D3][.0000.0160.0002.A9D3] # JAVANESE DIGIT THREE +1BB3 ; [.15CD.0020.0002.1BB3][.0000.0161.0002.1BB3] # SUNDANESE DIGIT THREE +1813 ; [.15CD.0020.0002.1813][.0000.0162.0002.1813] # MONGOLIAN DIGIT THREE +1C53 ; [.15CD.0020.0002.1C53][.0000.0163.0002.1C53] # OL CHIKI DIGIT THREE +A623 ; [.15CD.0020.0002.A623][.0000.0164.0002.A623] # VAI DIGIT THREE +110F3 ; [.15CD.0020.0002.110F3][.0000.0165.0002.110F3] # SORA SOMPENG DIGIT THREE +3023 ; [.15CD.0020.0002.3023][.0000.0166.0002.3023] # HANGZHOU NUMERAL THREE +10109 ; [.15CD.0020.0002.10109][.0000.0167.0002.10109] # AEGEAN NUMBER THREE +12401 ; [.15CD.0020.0002.12401][.0000.016C.0002.12401] # CUNEIFORM NUMERIC SIGN THREE ASH +12408 ; [.15CD.0020.0002.12408][.0000.016C.0002.12408] # CUNEIFORM NUMERIC SIGN THREE DISH +12417 ; [.15CD.0020.0002.12417][.0000.016C.0002.12417] # CUNEIFORM NUMERIC SIGN THREE GESH2 +12420 ; [.15CD.0020.0002.12420][.0000.016C.0002.12420] # CUNEIFORM NUMERIC SIGN THREE GESHU +12424 ; [.15CD.0020.0002.12424][.0000.016C.0002.12424] # CUNEIFORM NUMERIC SIGN THREE SHAR2 +12425 ; [.15CD.0020.0002.12425][.0000.016C.0002.12425] # CUNEIFORM NUMERIC SIGN THREE SHAR2 VARIANT FORM +1242E ; [.15CD.0020.0002.1242E][.0000.016C.0002.1242E] # CUNEIFORM NUMERIC SIGN THREE SHARU +1242F ; [.15CD.0020.0002.1242F][.0000.016C.0002.1242F] # CUNEIFORM NUMERIC SIGN THREE SHARU VARIANT FORM +12436 ; [.15CD.0020.0002.12436][.0000.016C.0002.12436] # CUNEIFORM NUMERIC SIGN THREE BURU +12437 ; [.15CD.0020.0002.12437][.0000.016C.0002.12437] # CUNEIFORM NUMERIC SIGN THREE BURU VARIANT FORM +1243A ; [.15CD.0020.0002.1243A][.0000.016C.0002.1243A] # CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH16 +1243B ; [.15CD.0020.0002.1243B][.0000.016C.0002.1243B] # CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH21 +1244B ; [.15CD.0020.0002.1244B][.0000.016C.0002.1244B] # CUNEIFORM NUMERIC SIGN THREE ASH TENU +12451 ; [.15CD.0020.0002.12451][.0000.016C.0002.12451] # CUNEIFORM NUMERIC SIGN THREE BAN2 +1091B ; [.15CD.0020.0002.1091B][.0000.016E.0002.1091B] # PHOENICIAN NUMBER THREE +1085A ; [.15CD.0020.0002.1085A][.0000.016F.0002.1085A] # IMPERIAL ARAMAIC NUMBER THREE +10B5A ; [.15CD.0020.0002.10B5A][.0000.0170.0002.10B5A] # INSCRIPTIONAL PARTHIAN NUMBER THREE +10B7A ; [.15CD.0020.0002.10B7A][.0000.0171.0002.10B7A] # INSCRIPTIONAL PAHLAVI NUMBER THREE +111D3 ; [.15CD.0020.0002.111D3][.0000.0172.0002.111D3] # SHARADA DIGIT THREE +116C3 ; [.15CD.0020.0002.116C3][.0000.0173.0002.116C3] # TAKRI DIGIT THREE +11069 ; [.15CD.0020.0002.11069][.0000.0174.0002.11069] # BRAHMI DIGIT THREE +11054 ; [.15CD.0020.0002.11054][.0000.0175.0002.11054] # BRAHMI NUMBER THREE +10A42 ; [.15CD.0020.0002.10A42][.0000.0176.0002.10A42] # KHAROSHTHI DIGIT THREE +1D362 ; [.15CD.0020.0002.1D362][.0000.0177.0002.1D362] # COUNTING ROD UNIT DIGIT THREE +324A ; [.15CD.0020.0006.324A][.15CA.0020.0006.324A] # CIRCLED NUMBER THIRTY ON BLACK SQUARE +325A ; [.15CD.0020.0006.325A][.15CA.0020.0006.325A] # CIRCLED NUMBER THIRTY +33FD ; [.15CD.0020.0004.33FD][.15CA.0020.0004.33FD][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY +325B ; [.15CD.0020.0006.325B][.15CB.0020.0006.325B] # CIRCLED NUMBER THIRTY ONE +33FE ; [.15CD.0020.0004.33FE][.15CB.0020.0004.33FE][.FB40.0020.001F.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE +325C ; [.15CD.0020.0006.325C][.15CC.0020.0006.325C] # CIRCLED NUMBER THIRTY TWO +325D ; [.15CD.0020.0006.325D][.15CD.0020.0006.325D] # CIRCLED NUMBER THIRTY THREE +325E ; [.15CD.0020.0006.325E][.15CE.0020.0006.325E] # CIRCLED NUMBER THIRTY FOUR +00BE ; [.15CD.0020.001E.00BE][*05AC.0020.001E.00BE][.15CE.0020.001F.00BE] # VULGAR FRACTION THREE QUARTERS +325F ; [.15CD.0020.0006.325F][.15CF.0020.0006.325F] # CIRCLED NUMBER THIRTY FIVE +2157 ; [.15CD.0020.001E.2157][*05AC.0020.001E.2157][.15CF.0020.001F.2157] # VULGAR FRACTION THREE FIFTHS +32B1 ; [.15CD.0020.0006.32B1][.15D0.0020.0006.32B1] # CIRCLED NUMBER THIRTY SIX +32B2 ; [.15CD.0020.0006.32B2][.15D1.0020.0006.32B2] # CIRCLED NUMBER THIRTY SEVEN +32B3 ; [.15CD.0020.0006.32B3][.15D2.0020.0006.32B3] # CIRCLED NUMBER THIRTY EIGHT +215C ; [.15CD.0020.001E.215C][*05AC.0020.001E.215C][.15D2.0020.001F.215C] # VULGAR FRACTION THREE EIGHTHS +32B4 ; [.15CD.0020.0006.32B4][.15D3.0020.0006.32B4] # CIRCLED NUMBER THIRTY NINE +33E2 ; [.15CD.0020.0004.33E2][.FB40.0020.0004.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE +32C2 ; [.15CD.0020.0004.32C2][.FB40.0020.0004.6708][.E708.0000.0000.6708] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH +335B ; [.15CD.0020.0004.335B][.FB40.0020.0004.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE +0034 ; [.15CE.0020.0002.0034] # DIGIT FOUR +FF14 ; [.15CE.0020.0003.FF14] # FULLWIDTH DIGIT FOUR +2477 ; [*02FB.0020.0004.2477][.15CE.0020.0004.2477][*02FC.0020.001F.2477] # PARENTHESIZED DIGIT FOUR +248B ; [.15CE.0020.0004.248B][*0273.0020.0004.248B] # DIGIT FOUR FULL STOP +1F105 ; [.15CE.0020.0004.1F105][*0221.0020.0004.1F105] # DIGIT FOUR COMMA +1D7D2 ; [.15CE.0020.0005.1D7D2] # MATHEMATICAL BOLD DIGIT FOUR +1D7DC ; [.15CE.0020.0005.1D7DC] # MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR +1D7E6 ; [.15CE.0020.0005.1D7E6] # MATHEMATICAL SANS-SERIF DIGIT FOUR +1D7F0 ; [.15CE.0020.0005.1D7F0] # MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR +1D7FA ; [.15CE.0020.0005.1D7FA] # MATHEMATICAL MONOSPACE DIGIT FOUR +2463 ; [.15CE.0020.0006.2463] # CIRCLED DIGIT FOUR +24F8 ; [.15CE.0020.0006.24F8] # DOUBLE CIRCLED DIGIT FOUR +2779 ; [.15CE.0020.0006.2779] # DINGBAT NEGATIVE CIRCLED DIGIT FOUR +2783 ; [.15CE.0020.0006.2783] # DINGBAT CIRCLED SANS-SERIF DIGIT FOUR +278D ; [.15CE.0020.0006.278D] # DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR +2074 ; [.15CE.0020.0014.2074] # SUPERSCRIPT FOUR +2084 ; [.15CE.0020.0015.2084] # SUBSCRIPT FOUR +0664 ; [.15CE.0020.0002.0664][.0000.013F.0002.0664] # ARABIC-INDIC DIGIT FOUR +06F4 ; [.15CE.0020.0002.06F4][.0000.0140.0002.06F4] # EXTENDED ARABIC-INDIC DIGIT FOUR +10E63 ; [.15CE.0020.0002.10E63][.0000.0141.0002.10E63] # RUMI DIGIT FOUR +07C4 ; [.15CE.0020.0002.07C4][.0000.0142.0002.07C4] # NKO DIGIT FOUR +136C ; [.15CE.0020.0002.136C][.0000.0143.0002.136C] # ETHIOPIC DIGIT FOUR +104A4 ; [.15CE.0020.0002.104A4][.0000.0144.0002.104A4] # OSMANYA DIGIT FOUR +096A ; [.15CE.0020.0002.096A][.0000.0145.0002.096A] # DEVANAGARI DIGIT FOUR +09EA ; [.15CE.0020.0002.09EA][.0000.0146.0002.09EA] # BENGALI DIGIT FOUR +0A6A ; [.15CE.0020.0002.0A6A][.0000.0147.0002.0A6A] # GURMUKHI DIGIT FOUR +0AEA ; [.15CE.0020.0002.0AEA][.0000.0148.0002.0AEA] # GUJARATI DIGIT FOUR +0B6A ; [.15CE.0020.0002.0B6A][.0000.0149.0002.0B6A] # ORIYA DIGIT FOUR +0BEA ; [.15CE.0020.0002.0BEA][.0000.014A.0002.0BEA] # TAMIL DIGIT FOUR +0C6A ; [.15CE.0020.0002.0C6A][.0000.014B.0002.0C6A] # TELUGU DIGIT FOUR +0CEA ; [.15CE.0020.0002.0CEA][.0000.014C.0002.0CEA] # KANNADA DIGIT FOUR +0D6A ; [.15CE.0020.0002.0D6A][.0000.014D.0002.0D6A] # MALAYALAM DIGIT FOUR +ABF4 ; [.15CE.0020.0002.ABF4][.0000.014E.0002.ABF4] # MEETEI MAYEK DIGIT FOUR +A8D4 ; [.15CE.0020.0002.A8D4][.0000.014F.0002.A8D4] # SAURASHTRA DIGIT FOUR +194A ; [.15CE.0020.0002.194A][.0000.0150.0002.194A] # LIMBU DIGIT FOUR +19D4 ; [.15CE.0020.0002.19D4][.0000.0151.0002.19D4] # NEW TAI LUE DIGIT FOUR +1A84 ; [.15CE.0020.0002.1A84][.0000.0152.0002.1A84] # TAI THAM HORA DIGIT FOUR +1A94 ; [.15CE.0020.0002.1A94][.0000.0153.0002.1A94] # TAI THAM THAM DIGIT FOUR +0E54 ; [.15CE.0020.0002.0E54][.0000.0154.0002.0E54] # THAI DIGIT FOUR +0ED4 ; [.15CE.0020.0002.0ED4][.0000.0155.0002.0ED4] # LAO DIGIT FOUR +0F24 ; [.15CE.0020.0002.0F24][.0000.0156.0002.0F24] # TIBETAN DIGIT FOUR +0F2D ; [.15CE.0020.0004.0F2D][.0000.0156.0004.0F2D] # TIBETAN DIGIT HALF FOUR +1C44 ; [.15CE.0020.0002.1C44][.0000.0157.0002.1C44] # LEPCHA DIGIT FOUR +A904 ; [.15CE.0020.0002.A904][.0000.0158.0002.A904] # KAYAH LI DIGIT FOUR +1044 ; [.15CE.0020.0002.1044][.0000.0159.0002.1044] # MYANMAR DIGIT FOUR +1094 ; [.15CE.0020.0002.1094][.0000.015A.0002.1094] # MYANMAR SHAN DIGIT FOUR +1113A ; [.15CE.0020.0002.1113A][.0000.015B.0002.1113A] # CHAKMA DIGIT FOUR +17E4 ; [.15CE.0020.0002.17E4][.0000.015C.0002.17E4] # KHMER DIGIT FOUR +17F4 ; [.15CE.0020.0002.17F4][.0000.015D.0002.17F4] # KHMER SYMBOL LEK ATTAK BUON +AA54 ; [.15CE.0020.0002.AA54][.0000.015E.0002.AA54] # CHAM DIGIT FOUR +1B54 ; [.15CE.0020.0002.1B54][.0000.015F.0002.1B54] # BALINESE DIGIT FOUR +A9D4 ; [.15CE.0020.0002.A9D4][.0000.0160.0002.A9D4] # JAVANESE DIGIT FOUR +1BB4 ; [.15CE.0020.0002.1BB4][.0000.0161.0002.1BB4] # SUNDANESE DIGIT FOUR +1814 ; [.15CE.0020.0002.1814][.0000.0162.0002.1814] # MONGOLIAN DIGIT FOUR +1C54 ; [.15CE.0020.0002.1C54][.0000.0163.0002.1C54] # OL CHIKI DIGIT FOUR +A624 ; [.15CE.0020.0002.A624][.0000.0164.0002.A624] # VAI DIGIT FOUR +110F4 ; [.15CE.0020.0002.110F4][.0000.0165.0002.110F4] # SORA SOMPENG DIGIT FOUR +3024 ; [.15CE.0020.0002.3024][.0000.0166.0002.3024] # HANGZHOU NUMERAL FOUR +1010A ; [.15CE.0020.0002.1010A][.0000.0167.0002.1010A] # AEGEAN NUMBER FOUR +12402 ; [.15CE.0020.0002.12402][.0000.016C.0002.12402] # CUNEIFORM NUMERIC SIGN FOUR ASH +12409 ; [.15CE.0020.0002.12409][.0000.016C.0002.12409] # CUNEIFORM NUMERIC SIGN FOUR DISH +1240F ; [.15CE.0020.0002.1240F][.0000.016C.0002.1240F] # CUNEIFORM NUMERIC SIGN FOUR U +12418 ; [.15CE.0020.0002.12418][.0000.016C.0002.12418] # CUNEIFORM NUMERIC SIGN FOUR GESH2 +12421 ; [.15CE.0020.0002.12421][.0000.016C.0002.12421] # CUNEIFORM NUMERIC SIGN FOUR GESHU +12426 ; [.15CE.0020.0002.12426][.0000.016C.0002.12426] # CUNEIFORM NUMERIC SIGN FOUR SHAR2 +12430 ; [.15CE.0020.0002.12430][.0000.016C.0002.12430] # CUNEIFORM NUMERIC SIGN FOUR SHARU +12438 ; [.15CE.0020.0002.12438][.0000.016C.0002.12438] # CUNEIFORM NUMERIC SIGN FOUR BURU +1243C ; [.15CE.0020.0002.1243C][.0000.016C.0002.1243C] # CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU +1243D ; [.15CE.0020.0002.1243D][.0000.016C.0002.1243D] # CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU4 +1243E ; [.15CE.0020.0002.1243E][.0000.016C.0002.1243E] # CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU A +1243F ; [.15CE.0020.0002.1243F][.0000.016C.0002.1243F] # CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU B +1244C ; [.15CE.0020.0002.1244C][.0000.016C.0002.1244C] # CUNEIFORM NUMERIC SIGN FOUR ASH TENU +12452 ; [.15CE.0020.0002.12452][.0000.016C.0002.12452] # CUNEIFORM NUMERIC SIGN FOUR BAN2 +12453 ; [.15CE.0020.0002.12453][.0000.016C.0002.12453] # CUNEIFORM NUMERIC SIGN FOUR BAN2 VARIANT FORM +10B5B ; [.15CE.0020.0002.10B5B][.0000.0170.0002.10B5B] # INSCRIPTIONAL PARTHIAN NUMBER FOUR +10B7B ; [.15CE.0020.0002.10B7B][.0000.0171.0002.10B7B] # INSCRIPTIONAL PAHLAVI NUMBER FOUR +111D4 ; [.15CE.0020.0002.111D4][.0000.0172.0002.111D4] # SHARADA DIGIT FOUR +116C4 ; [.15CE.0020.0002.116C4][.0000.0173.0002.116C4] # TAKRI DIGIT FOUR +1106A ; [.15CE.0020.0002.1106A][.0000.0174.0002.1106A] # BRAHMI DIGIT FOUR +11055 ; [.15CE.0020.0002.11055][.0000.0175.0002.11055] # BRAHMI NUMBER FOUR +10A43 ; [.15CE.0020.0002.10A43][.0000.0176.0002.10A43] # KHAROSHTHI DIGIT FOUR +1D363 ; [.15CE.0020.0002.1D363][.0000.0177.0002.1D363] # COUNTING ROD UNIT DIGIT FOUR +324B ; [.15CE.0020.0006.324B][.15CA.0020.0006.324B] # CIRCLED NUMBER FORTY ON BLACK SQUARE +32B5 ; [.15CE.0020.0006.32B5][.15CA.0020.0006.32B5] # CIRCLED NUMBER FORTY +32B6 ; [.15CE.0020.0006.32B6][.15CB.0020.0006.32B6] # CIRCLED NUMBER FORTY ONE +32B7 ; [.15CE.0020.0006.32B7][.15CC.0020.0006.32B7] # CIRCLED NUMBER FORTY TWO +32B8 ; [.15CE.0020.0006.32B8][.15CD.0020.0006.32B8] # CIRCLED NUMBER FORTY THREE +32B9 ; [.15CE.0020.0006.32B9][.15CE.0020.0006.32B9] # CIRCLED NUMBER FORTY FOUR +32BA ; [.15CE.0020.0006.32BA][.15CF.0020.0006.32BA] # CIRCLED NUMBER FORTY FIVE +2158 ; [.15CE.0020.001E.2158][*05AC.0020.001E.2158][.15CF.0020.001F.2158] # VULGAR FRACTION FOUR FIFTHS +32BB ; [.15CE.0020.0006.32BB][.15D0.0020.0006.32BB] # CIRCLED NUMBER FORTY SIX +32BC ; [.15CE.0020.0006.32BC][.15D1.0020.0006.32BC] # CIRCLED NUMBER FORTY SEVEN +32BD ; [.15CE.0020.0006.32BD][.15D2.0020.0006.32BD] # CIRCLED NUMBER FORTY EIGHT +32BE ; [.15CE.0020.0006.32BE][.15D3.0020.0006.32BE] # CIRCLED NUMBER FORTY NINE +33E3 ; [.15CE.0020.0004.33E3][.FB40.0020.0004.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR +32C3 ; [.15CE.0020.0004.32C3][.FB40.0020.0004.6708][.E708.0000.0000.6708] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL +335C ; [.15CE.0020.0004.335C][.FB40.0020.0004.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR +0035 ; [.15CF.0020.0002.0035] # DIGIT FIVE +FF15 ; [.15CF.0020.0003.FF15] # FULLWIDTH DIGIT FIVE +2478 ; [*02FB.0020.0004.2478][.15CF.0020.0004.2478][*02FC.0020.001F.2478] # PARENTHESIZED DIGIT FIVE +248C ; [.15CF.0020.0004.248C][*0273.0020.0004.248C] # DIGIT FIVE FULL STOP +1F106 ; [.15CF.0020.0004.1F106][*0221.0020.0004.1F106] # DIGIT FIVE COMMA +1D7D3 ; [.15CF.0020.0005.1D7D3] # MATHEMATICAL BOLD DIGIT FIVE +1D7DD ; [.15CF.0020.0005.1D7DD] # MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE +1D7E7 ; [.15CF.0020.0005.1D7E7] # MATHEMATICAL SANS-SERIF DIGIT FIVE +1D7F1 ; [.15CF.0020.0005.1D7F1] # MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE +1D7FB ; [.15CF.0020.0005.1D7FB] # MATHEMATICAL MONOSPACE DIGIT FIVE +2464 ; [.15CF.0020.0006.2464] # CIRCLED DIGIT FIVE +24F9 ; [.15CF.0020.0006.24F9] # DOUBLE CIRCLED DIGIT FIVE +277A ; [.15CF.0020.0006.277A] # DINGBAT NEGATIVE CIRCLED DIGIT FIVE +2784 ; [.15CF.0020.0006.2784] # DINGBAT CIRCLED SANS-SERIF DIGIT FIVE +278E ; [.15CF.0020.0006.278E] # DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE +2075 ; [.15CF.0020.0014.2075] # SUPERSCRIPT FIVE +2085 ; [.15CF.0020.0015.2085] # SUBSCRIPT FIVE +0665 ; [.15CF.0020.0002.0665][.0000.013F.0002.0665] # ARABIC-INDIC DIGIT FIVE +06F5 ; [.15CF.0020.0002.06F5][.0000.0140.0002.06F5] # EXTENDED ARABIC-INDIC DIGIT FIVE +10E64 ; [.15CF.0020.0002.10E64][.0000.0141.0002.10E64] # RUMI DIGIT FIVE +07C5 ; [.15CF.0020.0002.07C5][.0000.0142.0002.07C5] # NKO DIGIT FIVE +136D ; [.15CF.0020.0002.136D][.0000.0143.0002.136D] # ETHIOPIC DIGIT FIVE +104A5 ; [.15CF.0020.0002.104A5][.0000.0144.0002.104A5] # OSMANYA DIGIT FIVE +096B ; [.15CF.0020.0002.096B][.0000.0145.0002.096B] # DEVANAGARI DIGIT FIVE +09EB ; [.15CF.0020.0002.09EB][.0000.0146.0002.09EB] # BENGALI DIGIT FIVE +0A6B ; [.15CF.0020.0002.0A6B][.0000.0147.0002.0A6B] # GURMUKHI DIGIT FIVE +0AEB ; [.15CF.0020.0002.0AEB][.0000.0148.0002.0AEB] # GUJARATI DIGIT FIVE +0B6B ; [.15CF.0020.0002.0B6B][.0000.0149.0002.0B6B] # ORIYA DIGIT FIVE +0BEB ; [.15CF.0020.0002.0BEB][.0000.014A.0002.0BEB] # TAMIL DIGIT FIVE +0C6B ; [.15CF.0020.0002.0C6B][.0000.014B.0002.0C6B] # TELUGU DIGIT FIVE +0CEB ; [.15CF.0020.0002.0CEB][.0000.014C.0002.0CEB] # KANNADA DIGIT FIVE +0D6B ; [.15CF.0020.0002.0D6B][.0000.014D.0002.0D6B] # MALAYALAM DIGIT FIVE +ABF5 ; [.15CF.0020.0002.ABF5][.0000.014E.0002.ABF5] # MEETEI MAYEK DIGIT FIVE +A8D5 ; [.15CF.0020.0002.A8D5][.0000.014F.0002.A8D5] # SAURASHTRA DIGIT FIVE +194B ; [.15CF.0020.0002.194B][.0000.0150.0002.194B] # LIMBU DIGIT FIVE +19D5 ; [.15CF.0020.0002.19D5][.0000.0151.0002.19D5] # NEW TAI LUE DIGIT FIVE +1A85 ; [.15CF.0020.0002.1A85][.0000.0152.0002.1A85] # TAI THAM HORA DIGIT FIVE +1A95 ; [.15CF.0020.0002.1A95][.0000.0153.0002.1A95] # TAI THAM THAM DIGIT FIVE +0E55 ; [.15CF.0020.0002.0E55][.0000.0154.0002.0E55] # THAI DIGIT FIVE +0ED5 ; [.15CF.0020.0002.0ED5][.0000.0155.0002.0ED5] # LAO DIGIT FIVE +0F25 ; [.15CF.0020.0002.0F25][.0000.0156.0002.0F25] # TIBETAN DIGIT FIVE +0F2E ; [.15CF.0020.0004.0F2E][.0000.0156.0004.0F2E] # TIBETAN DIGIT HALF FIVE +1C45 ; [.15CF.0020.0002.1C45][.0000.0157.0002.1C45] # LEPCHA DIGIT FIVE +A905 ; [.15CF.0020.0002.A905][.0000.0158.0002.A905] # KAYAH LI DIGIT FIVE +1045 ; [.15CF.0020.0002.1045][.0000.0159.0002.1045] # MYANMAR DIGIT FIVE +1095 ; [.15CF.0020.0002.1095][.0000.015A.0002.1095] # MYANMAR SHAN DIGIT FIVE +1113B ; [.15CF.0020.0002.1113B][.0000.015B.0002.1113B] # CHAKMA DIGIT FIVE +17E5 ; [.15CF.0020.0002.17E5][.0000.015C.0002.17E5] # KHMER DIGIT FIVE +17F5 ; [.15CF.0020.0002.17F5][.0000.015D.0002.17F5] # KHMER SYMBOL LEK ATTAK PRAM +AA55 ; [.15CF.0020.0002.AA55][.0000.015E.0002.AA55] # CHAM DIGIT FIVE +1B55 ; [.15CF.0020.0002.1B55][.0000.015F.0002.1B55] # BALINESE DIGIT FIVE +A9D5 ; [.15CF.0020.0002.A9D5][.0000.0160.0002.A9D5] # JAVANESE DIGIT FIVE +1BB5 ; [.15CF.0020.0002.1BB5][.0000.0161.0002.1BB5] # SUNDANESE DIGIT FIVE +1815 ; [.15CF.0020.0002.1815][.0000.0162.0002.1815] # MONGOLIAN DIGIT FIVE +1C55 ; [.15CF.0020.0002.1C55][.0000.0163.0002.1C55] # OL CHIKI DIGIT FIVE +A625 ; [.15CF.0020.0002.A625][.0000.0164.0002.A625] # VAI DIGIT FIVE +110F5 ; [.15CF.0020.0002.110F5][.0000.0165.0002.110F5] # SORA SOMPENG DIGIT FIVE +3025 ; [.15CF.0020.0002.3025][.0000.0166.0002.3025] # HANGZHOU NUMERAL FIVE +1010B ; [.15CF.0020.0002.1010B][.0000.0167.0002.1010B] # AEGEAN NUMBER FIVE +10143 ; [.15CF.0020.0002.10143][.0000.0168.0002.10143] # GREEK ACROPHONIC ATTIC FIVE +10148 ; [.15CF.0020.0002.10148][.0000.0168.0002.10148] # GREEK ACROPHONIC ATTIC FIVE TALENTS +1014F ; [.15CF.0020.0002.1014F][.0000.0168.0002.1014F] # GREEK ACROPHONIC ATTIC FIVE STATERS +1015F ; [.15CF.0020.0002.1015F][.0000.0168.0002.1015F] # GREEK ACROPHONIC TROEZENIAN FIVE +10173 ; [.15CF.0020.0002.10173][.0000.0168.0002.10173] # GREEK ACROPHONIC DELPHIC FIVE MNAS +10321 ; [.15CF.0020.0002.10321][.0000.016A.0002.10321] # OLD ITALIC NUMERAL FIVE +12403 ; [.15CF.0020.0002.12403][.0000.016C.0002.12403] # CUNEIFORM NUMERIC SIGN FIVE ASH +1240A ; [.15CF.0020.0002.1240A][.0000.016C.0002.1240A] # CUNEIFORM NUMERIC SIGN FIVE DISH +12410 ; [.15CF.0020.0002.12410][.0000.016C.0002.12410] # CUNEIFORM NUMERIC SIGN FIVE U +12419 ; [.15CF.0020.0002.12419][.0000.016C.0002.12419] # CUNEIFORM NUMERIC SIGN FIVE GESH2 +12422 ; [.15CF.0020.0002.12422][.0000.016C.0002.12422] # CUNEIFORM NUMERIC SIGN FIVE GESHU +12427 ; [.15CF.0020.0002.12427][.0000.016C.0002.12427] # CUNEIFORM NUMERIC SIGN FIVE SHAR2 +12431 ; [.15CF.0020.0002.12431][.0000.016C.0002.12431] # CUNEIFORM NUMERIC SIGN FIVE SHARU +12439 ; [.15CF.0020.0002.12439][.0000.016C.0002.12439] # CUNEIFORM NUMERIC SIGN FIVE BURU +1244D ; [.15CF.0020.0002.1244D][.0000.016C.0002.1244D] # CUNEIFORM NUMERIC SIGN FIVE ASH TENU +12454 ; [.15CF.0020.0002.12454][.0000.016C.0002.12454] # CUNEIFORM NUMERIC SIGN FIVE BAN2 +12455 ; [.15CF.0020.0002.12455][.0000.016C.0002.12455] # CUNEIFORM NUMERIC SIGN FIVE BAN2 VARIANT FORM +111D5 ; [.15CF.0020.0002.111D5][.0000.0172.0002.111D5] # SHARADA DIGIT FIVE +116C5 ; [.15CF.0020.0002.116C5][.0000.0173.0002.116C5] # TAKRI DIGIT FIVE +1106B ; [.15CF.0020.0002.1106B][.0000.0174.0002.1106B] # BRAHMI DIGIT FIVE +11056 ; [.15CF.0020.0002.11056][.0000.0175.0002.11056] # BRAHMI NUMBER FIVE +1D364 ; [.15CF.0020.0002.1D364][.0000.0177.0002.1D364] # COUNTING ROD UNIT DIGIT FIVE +324C ; [.15CF.0020.0006.324C][.15CA.0020.0006.324C] # CIRCLED NUMBER FIFTY ON BLACK SQUARE +32BF ; [.15CF.0020.0006.32BF][.15CA.0020.0006.32BF] # CIRCLED NUMBER FIFTY +215A ; [.15CF.0020.001E.215A][*05AC.0020.001E.215A][.15D0.0020.001F.215A] # VULGAR FRACTION FIVE SIXTHS +215D ; [.15CF.0020.001E.215D][*05AC.0020.001E.215D][.15D2.0020.001F.215D] # VULGAR FRACTION FIVE EIGHTHS +33E4 ; [.15CF.0020.0004.33E4][.FB40.0020.0004.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE +32C4 ; [.15CF.0020.0004.32C4][.FB40.0020.0004.6708][.E708.0000.0000.6708] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY +335D ; [.15CF.0020.0004.335D][.FB40.0020.0004.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE +0036 ; [.15D0.0020.0002.0036] # DIGIT SIX +FF16 ; [.15D0.0020.0003.FF16] # FULLWIDTH DIGIT SIX +2479 ; [*02FB.0020.0004.2479][.15D0.0020.0004.2479][*02FC.0020.001F.2479] # PARENTHESIZED DIGIT SIX +248D ; [.15D0.0020.0004.248D][*0273.0020.0004.248D] # DIGIT SIX FULL STOP +1F107 ; [.15D0.0020.0004.1F107][*0221.0020.0004.1F107] # DIGIT SIX COMMA +1D7D4 ; [.15D0.0020.0005.1D7D4] # MATHEMATICAL BOLD DIGIT SIX +1D7DE ; [.15D0.0020.0005.1D7DE] # MATHEMATICAL DOUBLE-STRUCK DIGIT SIX +1D7E8 ; [.15D0.0020.0005.1D7E8] # MATHEMATICAL SANS-SERIF DIGIT SIX +1D7F2 ; [.15D0.0020.0005.1D7F2] # MATHEMATICAL SANS-SERIF BOLD DIGIT SIX +1D7FC ; [.15D0.0020.0005.1D7FC] # MATHEMATICAL MONOSPACE DIGIT SIX +2465 ; [.15D0.0020.0006.2465] # CIRCLED DIGIT SIX +24FA ; [.15D0.0020.0006.24FA] # DOUBLE CIRCLED DIGIT SIX +277B ; [.15D0.0020.0006.277B] # DINGBAT NEGATIVE CIRCLED DIGIT SIX +2785 ; [.15D0.0020.0006.2785] # DINGBAT CIRCLED SANS-SERIF DIGIT SIX +278F ; [.15D0.0020.0006.278F] # DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX +2076 ; [.15D0.0020.0014.2076] # SUPERSCRIPT SIX +2086 ; [.15D0.0020.0015.2086] # SUBSCRIPT SIX +0666 ; [.15D0.0020.0002.0666][.0000.013F.0002.0666] # ARABIC-INDIC DIGIT SIX +06F6 ; [.15D0.0020.0002.06F6][.0000.0140.0002.06F6] # EXTENDED ARABIC-INDIC DIGIT SIX +10E65 ; [.15D0.0020.0002.10E65][.0000.0141.0002.10E65] # RUMI DIGIT SIX +07C6 ; [.15D0.0020.0002.07C6][.0000.0142.0002.07C6] # NKO DIGIT SIX +136E ; [.15D0.0020.0002.136E][.0000.0143.0002.136E] # ETHIOPIC DIGIT SIX +104A6 ; [.15D0.0020.0002.104A6][.0000.0144.0002.104A6] # OSMANYA DIGIT SIX +096C ; [.15D0.0020.0002.096C][.0000.0145.0002.096C] # DEVANAGARI DIGIT SIX +09EC ; [.15D0.0020.0002.09EC][.0000.0146.0002.09EC] # BENGALI DIGIT SIX +0A6C ; [.15D0.0020.0002.0A6C][.0000.0147.0002.0A6C] # GURMUKHI DIGIT SIX +0AEC ; [.15D0.0020.0002.0AEC][.0000.0148.0002.0AEC] # GUJARATI DIGIT SIX +0B6C ; [.15D0.0020.0002.0B6C][.0000.0149.0002.0B6C] # ORIYA DIGIT SIX +0BEC ; [.15D0.0020.0002.0BEC][.0000.014A.0002.0BEC] # TAMIL DIGIT SIX +0C6C ; [.15D0.0020.0002.0C6C][.0000.014B.0002.0C6C] # TELUGU DIGIT SIX +0CEC ; [.15D0.0020.0002.0CEC][.0000.014C.0002.0CEC] # KANNADA DIGIT SIX +0D6C ; [.15D0.0020.0002.0D6C][.0000.014D.0002.0D6C] # MALAYALAM DIGIT SIX +ABF6 ; [.15D0.0020.0002.ABF6][.0000.014E.0002.ABF6] # MEETEI MAYEK DIGIT SIX +A8D6 ; [.15D0.0020.0002.A8D6][.0000.014F.0002.A8D6] # SAURASHTRA DIGIT SIX +194C ; [.15D0.0020.0002.194C][.0000.0150.0002.194C] # LIMBU DIGIT SIX +19D6 ; [.15D0.0020.0002.19D6][.0000.0151.0002.19D6] # NEW TAI LUE DIGIT SIX +1A86 ; [.15D0.0020.0002.1A86][.0000.0152.0002.1A86] # TAI THAM HORA DIGIT SIX +1A96 ; [.15D0.0020.0002.1A96][.0000.0153.0002.1A96] # TAI THAM THAM DIGIT SIX +0E56 ; [.15D0.0020.0002.0E56][.0000.0154.0002.0E56] # THAI DIGIT SIX +0ED6 ; [.15D0.0020.0002.0ED6][.0000.0155.0002.0ED6] # LAO DIGIT SIX +0F26 ; [.15D0.0020.0002.0F26][.0000.0156.0002.0F26] # TIBETAN DIGIT SIX +0F2F ; [.15D0.0020.0004.0F2F][.0000.0156.0004.0F2F] # TIBETAN DIGIT HALF SIX +1C46 ; [.15D0.0020.0002.1C46][.0000.0157.0002.1C46] # LEPCHA DIGIT SIX +A906 ; [.15D0.0020.0002.A906][.0000.0158.0002.A906] # KAYAH LI DIGIT SIX +1046 ; [.15D0.0020.0002.1046][.0000.0159.0002.1046] # MYANMAR DIGIT SIX +1096 ; [.15D0.0020.0002.1096][.0000.015A.0002.1096] # MYANMAR SHAN DIGIT SIX +1113C ; [.15D0.0020.0002.1113C][.0000.015B.0002.1113C] # CHAKMA DIGIT SIX +17E6 ; [.15D0.0020.0002.17E6][.0000.015C.0002.17E6] # KHMER DIGIT SIX +17F6 ; [.15D0.0020.0002.17F6][.0000.015D.0002.17F6] # KHMER SYMBOL LEK ATTAK PRAM-MUOY +AA56 ; [.15D0.0020.0002.AA56][.0000.015E.0002.AA56] # CHAM DIGIT SIX +1B56 ; [.15D0.0020.0002.1B56][.0000.015F.0002.1B56] # BALINESE DIGIT SIX +A9D6 ; [.15D0.0020.0002.A9D6][.0000.0160.0002.A9D6] # JAVANESE DIGIT SIX +1BB6 ; [.15D0.0020.0002.1BB6][.0000.0161.0002.1BB6] # SUNDANESE DIGIT SIX +1816 ; [.15D0.0020.0002.1816][.0000.0162.0002.1816] # MONGOLIAN DIGIT SIX +1C56 ; [.15D0.0020.0002.1C56][.0000.0163.0002.1C56] # OL CHIKI DIGIT SIX +A626 ; [.15D0.0020.0002.A626][.0000.0164.0002.A626] # VAI DIGIT SIX +110F6 ; [.15D0.0020.0002.110F6][.0000.0165.0002.110F6] # SORA SOMPENG DIGIT SIX +3026 ; [.15D0.0020.0002.3026][.0000.0166.0002.3026] # HANGZHOU NUMERAL SIX +1010C ; [.15D0.0020.0002.1010C][.0000.0167.0002.1010C] # AEGEAN NUMBER SIX +2185 ; [.15D0.0020.0002.2185][.0000.0169.0002.2185] # ROMAN NUMERAL SIX LATE FORM +12404 ; [.15D0.0020.0002.12404][.0000.016C.0002.12404] # CUNEIFORM NUMERIC SIGN SIX ASH +1240B ; [.15D0.0020.0002.1240B][.0000.016C.0002.1240B] # CUNEIFORM NUMERIC SIGN SIX DISH +12411 ; [.15D0.0020.0002.12411][.0000.016C.0002.12411] # CUNEIFORM NUMERIC SIGN SIX U +1241A ; [.15D0.0020.0002.1241A][.0000.016C.0002.1241A] # CUNEIFORM NUMERIC SIGN SIX GESH2 +12428 ; [.15D0.0020.0002.12428][.0000.016C.0002.12428] # CUNEIFORM NUMERIC SIGN SIX SHAR2 +12440 ; [.15D0.0020.0002.12440][.0000.016C.0002.12440] # CUNEIFORM NUMERIC SIGN SIX VARIANT FORM ASH9 +1244E ; [.15D0.0020.0002.1244E][.0000.016C.0002.1244E] # CUNEIFORM NUMERIC SIGN SIX ASH TENU +111D6 ; [.15D0.0020.0002.111D6][.0000.0172.0002.111D6] # SHARADA DIGIT SIX +116C6 ; [.15D0.0020.0002.116C6][.0000.0173.0002.116C6] # TAKRI DIGIT SIX +1106C ; [.15D0.0020.0002.1106C][.0000.0174.0002.1106C] # BRAHMI DIGIT SIX +11057 ; [.15D0.0020.0002.11057][.0000.0175.0002.11057] # BRAHMI NUMBER SIX +1D365 ; [.15D0.0020.0002.1D365][.0000.0177.0002.1D365] # COUNTING ROD UNIT DIGIT SIX +324D ; [.15D0.0020.0006.324D][.15CA.0020.0006.324D] # CIRCLED NUMBER SIXTY ON BLACK SQUARE +33E5 ; [.15D0.0020.0004.33E5][.FB40.0020.0004.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX +32C5 ; [.15D0.0020.0004.32C5][.FB40.0020.0004.6708][.E708.0000.0000.6708] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE +335E ; [.15D0.0020.0004.335E][.FB40.0020.0004.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX +0037 ; [.15D1.0020.0002.0037] # DIGIT SEVEN +FF17 ; [.15D1.0020.0003.FF17] # FULLWIDTH DIGIT SEVEN +247A ; [*02FB.0020.0004.247A][.15D1.0020.0004.247A][*02FC.0020.001F.247A] # PARENTHESIZED DIGIT SEVEN +248E ; [.15D1.0020.0004.248E][*0273.0020.0004.248E] # DIGIT SEVEN FULL STOP +1F108 ; [.15D1.0020.0004.1F108][*0221.0020.0004.1F108] # DIGIT SEVEN COMMA +1D7D5 ; [.15D1.0020.0005.1D7D5] # MATHEMATICAL BOLD DIGIT SEVEN +1D7DF ; [.15D1.0020.0005.1D7DF] # MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN +1D7E9 ; [.15D1.0020.0005.1D7E9] # MATHEMATICAL SANS-SERIF DIGIT SEVEN +1D7F3 ; [.15D1.0020.0005.1D7F3] # MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN +1D7FD ; [.15D1.0020.0005.1D7FD] # MATHEMATICAL MONOSPACE DIGIT SEVEN +2466 ; [.15D1.0020.0006.2466] # CIRCLED DIGIT SEVEN +24FB ; [.15D1.0020.0006.24FB] # DOUBLE CIRCLED DIGIT SEVEN +277C ; [.15D1.0020.0006.277C] # DINGBAT NEGATIVE CIRCLED DIGIT SEVEN +2786 ; [.15D1.0020.0006.2786] # DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN +2790 ; [.15D1.0020.0006.2790] # DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN +2077 ; [.15D1.0020.0014.2077] # SUPERSCRIPT SEVEN +2087 ; [.15D1.0020.0015.2087] # SUBSCRIPT SEVEN +0667 ; [.15D1.0020.0002.0667][.0000.013F.0002.0667] # ARABIC-INDIC DIGIT SEVEN +06F7 ; [.15D1.0020.0002.06F7][.0000.0140.0002.06F7] # EXTENDED ARABIC-INDIC DIGIT SEVEN +10E66 ; [.15D1.0020.0002.10E66][.0000.0141.0002.10E66] # RUMI DIGIT SEVEN +07C7 ; [.15D1.0020.0002.07C7][.0000.0142.0002.07C7] # NKO DIGIT SEVEN +136F ; [.15D1.0020.0002.136F][.0000.0143.0002.136F] # ETHIOPIC DIGIT SEVEN +104A7 ; [.15D1.0020.0002.104A7][.0000.0144.0002.104A7] # OSMANYA DIGIT SEVEN +096D ; [.15D1.0020.0002.096D][.0000.0145.0002.096D] # DEVANAGARI DIGIT SEVEN +09ED ; [.15D1.0020.0002.09ED][.0000.0146.0002.09ED] # BENGALI DIGIT SEVEN +0A6D ; [.15D1.0020.0002.0A6D][.0000.0147.0002.0A6D] # GURMUKHI DIGIT SEVEN +0AED ; [.15D1.0020.0002.0AED][.0000.0148.0002.0AED] # GUJARATI DIGIT SEVEN +0B6D ; [.15D1.0020.0002.0B6D][.0000.0149.0002.0B6D] # ORIYA DIGIT SEVEN +0BED ; [.15D1.0020.0002.0BED][.0000.014A.0002.0BED] # TAMIL DIGIT SEVEN +0C6D ; [.15D1.0020.0002.0C6D][.0000.014B.0002.0C6D] # TELUGU DIGIT SEVEN +0CED ; [.15D1.0020.0002.0CED][.0000.014C.0002.0CED] # KANNADA DIGIT SEVEN +0D6D ; [.15D1.0020.0002.0D6D][.0000.014D.0002.0D6D] # MALAYALAM DIGIT SEVEN +ABF7 ; [.15D1.0020.0002.ABF7][.0000.014E.0002.ABF7] # MEETEI MAYEK DIGIT SEVEN +A8D7 ; [.15D1.0020.0002.A8D7][.0000.014F.0002.A8D7] # SAURASHTRA DIGIT SEVEN +194D ; [.15D1.0020.0002.194D][.0000.0150.0002.194D] # LIMBU DIGIT SEVEN +19D7 ; [.15D1.0020.0002.19D7][.0000.0151.0002.19D7] # NEW TAI LUE DIGIT SEVEN +1A87 ; [.15D1.0020.0002.1A87][.0000.0152.0002.1A87] # TAI THAM HORA DIGIT SEVEN +1A97 ; [.15D1.0020.0002.1A97][.0000.0153.0002.1A97] # TAI THAM THAM DIGIT SEVEN +0E57 ; [.15D1.0020.0002.0E57][.0000.0154.0002.0E57] # THAI DIGIT SEVEN +0ED7 ; [.15D1.0020.0002.0ED7][.0000.0155.0002.0ED7] # LAO DIGIT SEVEN +0F27 ; [.15D1.0020.0002.0F27][.0000.0156.0002.0F27] # TIBETAN DIGIT SEVEN +0F30 ; [.15D1.0020.0004.0F30][.0000.0156.0004.0F30] # TIBETAN DIGIT HALF SEVEN +1C47 ; [.15D1.0020.0002.1C47][.0000.0157.0002.1C47] # LEPCHA DIGIT SEVEN +A907 ; [.15D1.0020.0002.A907][.0000.0158.0002.A907] # KAYAH LI DIGIT SEVEN +1047 ; [.15D1.0020.0002.1047][.0000.0159.0002.1047] # MYANMAR DIGIT SEVEN +1097 ; [.15D1.0020.0002.1097][.0000.015A.0002.1097] # MYANMAR SHAN DIGIT SEVEN +1113D ; [.15D1.0020.0002.1113D][.0000.015B.0002.1113D] # CHAKMA DIGIT SEVEN +17E7 ; [.15D1.0020.0002.17E7][.0000.015C.0002.17E7] # KHMER DIGIT SEVEN +17F7 ; [.15D1.0020.0002.17F7][.0000.015D.0002.17F7] # KHMER SYMBOL LEK ATTAK PRAM-PII +AA57 ; [.15D1.0020.0002.AA57][.0000.015E.0002.AA57] # CHAM DIGIT SEVEN +1B57 ; [.15D1.0020.0002.1B57][.0000.015F.0002.1B57] # BALINESE DIGIT SEVEN +A9D7 ; [.15D1.0020.0002.A9D7][.0000.0160.0002.A9D7] # JAVANESE DIGIT SEVEN +1BB7 ; [.15D1.0020.0002.1BB7][.0000.0161.0002.1BB7] # SUNDANESE DIGIT SEVEN +1817 ; [.15D1.0020.0002.1817][.0000.0162.0002.1817] # MONGOLIAN DIGIT SEVEN +1C57 ; [.15D1.0020.0002.1C57][.0000.0163.0002.1C57] # OL CHIKI DIGIT SEVEN +A627 ; [.15D1.0020.0002.A627][.0000.0164.0002.A627] # VAI DIGIT SEVEN +110F7 ; [.15D1.0020.0002.110F7][.0000.0165.0002.110F7] # SORA SOMPENG DIGIT SEVEN +3027 ; [.15D1.0020.0002.3027][.0000.0166.0002.3027] # HANGZHOU NUMERAL SEVEN +1010D ; [.15D1.0020.0002.1010D][.0000.0167.0002.1010D] # AEGEAN NUMBER SEVEN +12405 ; [.15D1.0020.0002.12405][.0000.016C.0002.12405] # CUNEIFORM NUMERIC SIGN SEVEN ASH +1240C ; [.15D1.0020.0002.1240C][.0000.016C.0002.1240C] # CUNEIFORM NUMERIC SIGN SEVEN DISH +12412 ; [.15D1.0020.0002.12412][.0000.016C.0002.12412] # CUNEIFORM NUMERIC SIGN SEVEN U +1241B ; [.15D1.0020.0002.1241B][.0000.016C.0002.1241B] # CUNEIFORM NUMERIC SIGN SEVEN GESH2 +12429 ; [.15D1.0020.0002.12429][.0000.016C.0002.12429] # CUNEIFORM NUMERIC SIGN SEVEN SHAR2 +12441 ; [.15D1.0020.0002.12441][.0000.016C.0002.12441] # CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN3 +12442 ; [.15D1.0020.0002.12442][.0000.016C.0002.12442] # CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN A +12443 ; [.15D1.0020.0002.12443][.0000.016C.0002.12443] # CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN B +111D7 ; [.15D1.0020.0002.111D7][.0000.0172.0002.111D7] # SHARADA DIGIT SEVEN +116C7 ; [.15D1.0020.0002.116C7][.0000.0173.0002.116C7] # TAKRI DIGIT SEVEN +1106D ; [.15D1.0020.0002.1106D][.0000.0174.0002.1106D] # BRAHMI DIGIT SEVEN +11058 ; [.15D1.0020.0002.11058][.0000.0175.0002.11058] # BRAHMI NUMBER SEVEN +1D366 ; [.15D1.0020.0002.1D366][.0000.0177.0002.1D366] # COUNTING ROD UNIT DIGIT SEVEN +324E ; [.15D1.0020.0006.324E][.15CA.0020.0006.324E] # CIRCLED NUMBER SEVENTY ON BLACK SQUARE +215E ; [.15D1.0020.001E.215E][*05AC.0020.001E.215E][.15D2.0020.001F.215E] # VULGAR FRACTION SEVEN EIGHTHS +33E6 ; [.15D1.0020.0004.33E6][.FB40.0020.0004.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN +32C6 ; [.15D1.0020.0004.32C6][.FB40.0020.0004.6708][.E708.0000.0000.6708] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY +335F ; [.15D1.0020.0004.335F][.FB40.0020.0004.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN +0038 ; [.15D2.0020.0002.0038] # DIGIT EIGHT +FF18 ; [.15D2.0020.0003.FF18] # FULLWIDTH DIGIT EIGHT +247B ; [*02FB.0020.0004.247B][.15D2.0020.0004.247B][*02FC.0020.001F.247B] # PARENTHESIZED DIGIT EIGHT +248F ; [.15D2.0020.0004.248F][*0273.0020.0004.248F] # DIGIT EIGHT FULL STOP +1F109 ; [.15D2.0020.0004.1F109][*0221.0020.0004.1F109] # DIGIT EIGHT COMMA +1D7D6 ; [.15D2.0020.0005.1D7D6] # MATHEMATICAL BOLD DIGIT EIGHT +1D7E0 ; [.15D2.0020.0005.1D7E0] # MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT +1D7EA ; [.15D2.0020.0005.1D7EA] # MATHEMATICAL SANS-SERIF DIGIT EIGHT +1D7F4 ; [.15D2.0020.0005.1D7F4] # MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT +1D7FE ; [.15D2.0020.0005.1D7FE] # MATHEMATICAL MONOSPACE DIGIT EIGHT +2467 ; [.15D2.0020.0006.2467] # CIRCLED DIGIT EIGHT +24FC ; [.15D2.0020.0006.24FC] # DOUBLE CIRCLED DIGIT EIGHT +277D ; [.15D2.0020.0006.277D] # DINGBAT NEGATIVE CIRCLED DIGIT EIGHT +2787 ; [.15D2.0020.0006.2787] # DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT +2791 ; [.15D2.0020.0006.2791] # DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT +2078 ; [.15D2.0020.0014.2078] # SUPERSCRIPT EIGHT +2088 ; [.15D2.0020.0015.2088] # SUBSCRIPT EIGHT +0668 ; [.15D2.0020.0002.0668][.0000.013F.0002.0668] # ARABIC-INDIC DIGIT EIGHT +06F8 ; [.15D2.0020.0002.06F8][.0000.0140.0002.06F8] # EXTENDED ARABIC-INDIC DIGIT EIGHT +10E67 ; [.15D2.0020.0002.10E67][.0000.0141.0002.10E67] # RUMI DIGIT EIGHT +07C8 ; [.15D2.0020.0002.07C8][.0000.0142.0002.07C8] # NKO DIGIT EIGHT +1370 ; [.15D2.0020.0002.1370][.0000.0143.0002.1370] # ETHIOPIC DIGIT EIGHT +104A8 ; [.15D2.0020.0002.104A8][.0000.0144.0002.104A8] # OSMANYA DIGIT EIGHT +096E ; [.15D2.0020.0002.096E][.0000.0145.0002.096E] # DEVANAGARI DIGIT EIGHT +09EE ; [.15D2.0020.0002.09EE][.0000.0146.0002.09EE] # BENGALI DIGIT EIGHT +0A6E ; [.15D2.0020.0002.0A6E][.0000.0147.0002.0A6E] # GURMUKHI DIGIT EIGHT +0AEE ; [.15D2.0020.0002.0AEE][.0000.0148.0002.0AEE] # GUJARATI DIGIT EIGHT +0B6E ; [.15D2.0020.0002.0B6E][.0000.0149.0002.0B6E] # ORIYA DIGIT EIGHT +0BEE ; [.15D2.0020.0002.0BEE][.0000.014A.0002.0BEE] # TAMIL DIGIT EIGHT +0C6E ; [.15D2.0020.0002.0C6E][.0000.014B.0002.0C6E] # TELUGU DIGIT EIGHT +0CEE ; [.15D2.0020.0002.0CEE][.0000.014C.0002.0CEE] # KANNADA DIGIT EIGHT +0D6E ; [.15D2.0020.0002.0D6E][.0000.014D.0002.0D6E] # MALAYALAM DIGIT EIGHT +ABF8 ; [.15D2.0020.0002.ABF8][.0000.014E.0002.ABF8] # MEETEI MAYEK DIGIT EIGHT +A8D8 ; [.15D2.0020.0002.A8D8][.0000.014F.0002.A8D8] # SAURASHTRA DIGIT EIGHT +194E ; [.15D2.0020.0002.194E][.0000.0150.0002.194E] # LIMBU DIGIT EIGHT +19D8 ; [.15D2.0020.0002.19D8][.0000.0151.0002.19D8] # NEW TAI LUE DIGIT EIGHT +1A88 ; [.15D2.0020.0002.1A88][.0000.0152.0002.1A88] # TAI THAM HORA DIGIT EIGHT +1A98 ; [.15D2.0020.0002.1A98][.0000.0153.0002.1A98] # TAI THAM THAM DIGIT EIGHT +0E58 ; [.15D2.0020.0002.0E58][.0000.0154.0002.0E58] # THAI DIGIT EIGHT +0ED8 ; [.15D2.0020.0002.0ED8][.0000.0155.0002.0ED8] # LAO DIGIT EIGHT +0F28 ; [.15D2.0020.0002.0F28][.0000.0156.0002.0F28] # TIBETAN DIGIT EIGHT +0F31 ; [.15D2.0020.0004.0F31][.0000.0156.0004.0F31] # TIBETAN DIGIT HALF EIGHT +1C48 ; [.15D2.0020.0002.1C48][.0000.0157.0002.1C48] # LEPCHA DIGIT EIGHT +A908 ; [.15D2.0020.0002.A908][.0000.0158.0002.A908] # KAYAH LI DIGIT EIGHT +1048 ; [.15D2.0020.0002.1048][.0000.0159.0002.1048] # MYANMAR DIGIT EIGHT +1098 ; [.15D2.0020.0002.1098][.0000.015A.0002.1098] # MYANMAR SHAN DIGIT EIGHT +1113E ; [.15D2.0020.0002.1113E][.0000.015B.0002.1113E] # CHAKMA DIGIT EIGHT +17E8 ; [.15D2.0020.0002.17E8][.0000.015C.0002.17E8] # KHMER DIGIT EIGHT +17F8 ; [.15D2.0020.0002.17F8][.0000.015D.0002.17F8] # KHMER SYMBOL LEK ATTAK PRAM-BEI +AA58 ; [.15D2.0020.0002.AA58][.0000.015E.0002.AA58] # CHAM DIGIT EIGHT +1B58 ; [.15D2.0020.0002.1B58][.0000.015F.0002.1B58] # BALINESE DIGIT EIGHT +A9D8 ; [.15D2.0020.0002.A9D8][.0000.0160.0002.A9D8] # JAVANESE DIGIT EIGHT +1BB8 ; [.15D2.0020.0002.1BB8][.0000.0161.0002.1BB8] # SUNDANESE DIGIT EIGHT +1818 ; [.15D2.0020.0002.1818][.0000.0162.0002.1818] # MONGOLIAN DIGIT EIGHT +1C58 ; [.15D2.0020.0002.1C58][.0000.0163.0002.1C58] # OL CHIKI DIGIT EIGHT +A628 ; [.15D2.0020.0002.A628][.0000.0164.0002.A628] # VAI DIGIT EIGHT +110F8 ; [.15D2.0020.0002.110F8][.0000.0165.0002.110F8] # SORA SOMPENG DIGIT EIGHT +3028 ; [.15D2.0020.0002.3028][.0000.0166.0002.3028] # HANGZHOU NUMERAL EIGHT +1010E ; [.15D2.0020.0002.1010E][.0000.0167.0002.1010E] # AEGEAN NUMBER EIGHT +12406 ; [.15D2.0020.0002.12406][.0000.016C.0002.12406] # CUNEIFORM NUMERIC SIGN EIGHT ASH +1240D ; [.15D2.0020.0002.1240D][.0000.016C.0002.1240D] # CUNEIFORM NUMERIC SIGN EIGHT DISH +12413 ; [.15D2.0020.0002.12413][.0000.016C.0002.12413] # CUNEIFORM NUMERIC SIGN EIGHT U +1241C ; [.15D2.0020.0002.1241C][.0000.016C.0002.1241C] # CUNEIFORM NUMERIC SIGN EIGHT GESH2 +1242A ; [.15D2.0020.0002.1242A][.0000.016C.0002.1242A] # CUNEIFORM NUMERIC SIGN EIGHT SHAR2 +12444 ; [.15D2.0020.0002.12444][.0000.016C.0002.12444] # CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU +12445 ; [.15D2.0020.0002.12445][.0000.016C.0002.12445] # CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU3 +111D8 ; [.15D2.0020.0002.111D8][.0000.0172.0002.111D8] # SHARADA DIGIT EIGHT +116C8 ; [.15D2.0020.0002.116C8][.0000.0173.0002.116C8] # TAKRI DIGIT EIGHT +1106E ; [.15D2.0020.0002.1106E][.0000.0174.0002.1106E] # BRAHMI DIGIT EIGHT +11059 ; [.15D2.0020.0002.11059][.0000.0175.0002.11059] # BRAHMI NUMBER EIGHT +1D367 ; [.15D2.0020.0002.1D367][.0000.0177.0002.1D367] # COUNTING ROD UNIT DIGIT EIGHT +324F ; [.15D2.0020.0006.324F][.15CA.0020.0006.324F] # CIRCLED NUMBER EIGHTY ON BLACK SQUARE +33E7 ; [.15D2.0020.0004.33E7][.FB40.0020.0004.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT +32C7 ; [.15D2.0020.0004.32C7][.FB40.0020.0004.6708][.E708.0000.0000.6708] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST +3360 ; [.15D2.0020.0004.3360][.FB40.0020.0004.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT +0039 ; [.15D3.0020.0002.0039] # DIGIT NINE +FF19 ; [.15D3.0020.0003.FF19] # FULLWIDTH DIGIT NINE +247C ; [*02FB.0020.0004.247C][.15D3.0020.0004.247C][*02FC.0020.001F.247C] # PARENTHESIZED DIGIT NINE +2490 ; [.15D3.0020.0004.2490][*0273.0020.0004.2490] # DIGIT NINE FULL STOP +1F10A ; [.15D3.0020.0004.1F10A][*0221.0020.0004.1F10A] # DIGIT NINE COMMA +1D7D7 ; [.15D3.0020.0005.1D7D7] # MATHEMATICAL BOLD DIGIT NINE +1D7E1 ; [.15D3.0020.0005.1D7E1] # MATHEMATICAL DOUBLE-STRUCK DIGIT NINE +1D7EB ; [.15D3.0020.0005.1D7EB] # MATHEMATICAL SANS-SERIF DIGIT NINE +1D7F5 ; [.15D3.0020.0005.1D7F5] # MATHEMATICAL SANS-SERIF BOLD DIGIT NINE +1D7FF ; [.15D3.0020.0005.1D7FF] # MATHEMATICAL MONOSPACE DIGIT NINE +2468 ; [.15D3.0020.0006.2468] # CIRCLED DIGIT NINE +24FD ; [.15D3.0020.0006.24FD] # DOUBLE CIRCLED DIGIT NINE +277E ; [.15D3.0020.0006.277E] # DINGBAT NEGATIVE CIRCLED DIGIT NINE +2788 ; [.15D3.0020.0006.2788] # DINGBAT CIRCLED SANS-SERIF DIGIT NINE +2792 ; [.15D3.0020.0006.2792] # DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE +2079 ; [.15D3.0020.0014.2079] # SUPERSCRIPT NINE +2089 ; [.15D3.0020.0015.2089] # SUBSCRIPT NINE +0669 ; [.15D3.0020.0002.0669][.0000.013F.0002.0669] # ARABIC-INDIC DIGIT NINE +06F9 ; [.15D3.0020.0002.06F9][.0000.0140.0002.06F9] # EXTENDED ARABIC-INDIC DIGIT NINE +10E68 ; [.15D3.0020.0002.10E68][.0000.0141.0002.10E68] # RUMI DIGIT NINE +07C9 ; [.15D3.0020.0002.07C9][.0000.0142.0002.07C9] # NKO DIGIT NINE +1371 ; [.15D3.0020.0002.1371][.0000.0143.0002.1371] # ETHIOPIC DIGIT NINE +104A9 ; [.15D3.0020.0002.104A9][.0000.0144.0002.104A9] # OSMANYA DIGIT NINE +096F ; [.15D3.0020.0002.096F][.0000.0145.0002.096F] # DEVANAGARI DIGIT NINE +09EF ; [.15D3.0020.0002.09EF][.0000.0146.0002.09EF] # BENGALI DIGIT NINE +0A6F ; [.15D3.0020.0002.0A6F][.0000.0147.0002.0A6F] # GURMUKHI DIGIT NINE +0AEF ; [.15D3.0020.0002.0AEF][.0000.0148.0002.0AEF] # GUJARATI DIGIT NINE +0B6F ; [.15D3.0020.0002.0B6F][.0000.0149.0002.0B6F] # ORIYA DIGIT NINE +0BEF ; [.15D3.0020.0002.0BEF][.0000.014A.0002.0BEF] # TAMIL DIGIT NINE +0C6F ; [.15D3.0020.0002.0C6F][.0000.014B.0002.0C6F] # TELUGU DIGIT NINE +0CEF ; [.15D3.0020.0002.0CEF][.0000.014C.0002.0CEF] # KANNADA DIGIT NINE +0D6F ; [.15D3.0020.0002.0D6F][.0000.014D.0002.0D6F] # MALAYALAM DIGIT NINE +ABF9 ; [.15D3.0020.0002.ABF9][.0000.014E.0002.ABF9] # MEETEI MAYEK DIGIT NINE +A8D9 ; [.15D3.0020.0002.A8D9][.0000.014F.0002.A8D9] # SAURASHTRA DIGIT NINE +194F ; [.15D3.0020.0002.194F][.0000.0150.0002.194F] # LIMBU DIGIT NINE +19D9 ; [.15D3.0020.0002.19D9][.0000.0151.0002.19D9] # NEW TAI LUE DIGIT NINE +1A89 ; [.15D3.0020.0002.1A89][.0000.0152.0002.1A89] # TAI THAM HORA DIGIT NINE +1A99 ; [.15D3.0020.0002.1A99][.0000.0153.0002.1A99] # TAI THAM THAM DIGIT NINE +0E59 ; [.15D3.0020.0002.0E59][.0000.0154.0002.0E59] # THAI DIGIT NINE +0ED9 ; [.15D3.0020.0002.0ED9][.0000.0155.0002.0ED9] # LAO DIGIT NINE +0F29 ; [.15D3.0020.0002.0F29][.0000.0156.0002.0F29] # TIBETAN DIGIT NINE +0F32 ; [.15D3.0020.0004.0F32][.0000.0156.0004.0F32] # TIBETAN DIGIT HALF NINE +1C49 ; [.15D3.0020.0002.1C49][.0000.0157.0002.1C49] # LEPCHA DIGIT NINE +A909 ; [.15D3.0020.0002.A909][.0000.0158.0002.A909] # KAYAH LI DIGIT NINE +1049 ; [.15D3.0020.0002.1049][.0000.0159.0002.1049] # MYANMAR DIGIT NINE +1099 ; [.15D3.0020.0002.1099][.0000.015A.0002.1099] # MYANMAR SHAN DIGIT NINE +1113F ; [.15D3.0020.0002.1113F][.0000.015B.0002.1113F] # CHAKMA DIGIT NINE +17E9 ; [.15D3.0020.0002.17E9][.0000.015C.0002.17E9] # KHMER DIGIT NINE +17F9 ; [.15D3.0020.0002.17F9][.0000.015D.0002.17F9] # KHMER SYMBOL LEK ATTAK PRAM-BUON +AA59 ; [.15D3.0020.0002.AA59][.0000.015E.0002.AA59] # CHAM DIGIT NINE +1B59 ; [.15D3.0020.0002.1B59][.0000.015F.0002.1B59] # BALINESE DIGIT NINE +A9D9 ; [.15D3.0020.0002.A9D9][.0000.0160.0002.A9D9] # JAVANESE DIGIT NINE +1BB9 ; [.15D3.0020.0002.1BB9][.0000.0161.0002.1BB9] # SUNDANESE DIGIT NINE +1819 ; [.15D3.0020.0002.1819][.0000.0162.0002.1819] # MONGOLIAN DIGIT NINE +1C59 ; [.15D3.0020.0002.1C59][.0000.0163.0002.1C59] # OL CHIKI DIGIT NINE +A629 ; [.15D3.0020.0002.A629][.0000.0164.0002.A629] # VAI DIGIT NINE +110F9 ; [.15D3.0020.0002.110F9][.0000.0165.0002.110F9] # SORA SOMPENG DIGIT NINE +3029 ; [.15D3.0020.0002.3029][.0000.0166.0002.3029] # HANGZHOU NUMERAL NINE +1010F ; [.15D3.0020.0002.1010F][.0000.0167.0002.1010F] # AEGEAN NUMBER NINE +12407 ; [.15D3.0020.0002.12407][.0000.016C.0002.12407] # CUNEIFORM NUMERIC SIGN NINE ASH +1240E ; [.15D3.0020.0002.1240E][.0000.016C.0002.1240E] # CUNEIFORM NUMERIC SIGN NINE DISH +12414 ; [.15D3.0020.0002.12414][.0000.016C.0002.12414] # CUNEIFORM NUMERIC SIGN NINE U +1241D ; [.15D3.0020.0002.1241D][.0000.016C.0002.1241D] # CUNEIFORM NUMERIC SIGN NINE GESH2 +1242B ; [.15D3.0020.0002.1242B][.0000.016C.0002.1242B] # CUNEIFORM NUMERIC SIGN NINE SHAR2 +12446 ; [.15D3.0020.0002.12446][.0000.016C.0002.12446] # CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU +12447 ; [.15D3.0020.0002.12447][.0000.016C.0002.12447] # CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU3 +12448 ; [.15D3.0020.0002.12448][.0000.016C.0002.12448] # CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU4 +12449 ; [.15D3.0020.0002.12449][.0000.016C.0002.12449] # CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU A +111D9 ; [.15D3.0020.0002.111D9][.0000.0172.0002.111D9] # SHARADA DIGIT NINE +116C9 ; [.15D3.0020.0002.116C9][.0000.0173.0002.116C9] # TAKRI DIGIT NINE +1106F ; [.15D3.0020.0002.1106F][.0000.0174.0002.1106F] # BRAHMI DIGIT NINE +1105A ; [.15D3.0020.0002.1105A][.0000.0175.0002.1105A] # BRAHMI NUMBER NINE +1D368 ; [.15D3.0020.0002.1D368][.0000.0177.0002.1D368] # COUNTING ROD UNIT DIGIT NINE +33E8 ; [.15D3.0020.0004.33E8][.FB40.0020.0004.65E5][.E5E5.0000.0000.65E5] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE +32C8 ; [.15D3.0020.0004.32C8][.FB40.0020.0004.6708][.E708.0000.0000.6708] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER +3361 ; [.15D3.0020.0004.3361][.FB40.0020.0004.70B9][.F0B9.0000.0000.70B9] # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE +0061 ; [.15D4.0020.0002.0061] # LATIN SMALL LETTER A +FF41 ; [.15D4.0020.0003.FF41] # FULLWIDTH LATIN SMALL LETTER A +0363 ; [.15D4.0020.0004.0363] # COMBINING LATIN SMALL LETTER A +249C ; [*02FB.0020.0004.249C][.15D4.0020.0004.249C][*02FC.0020.001F.249C] # PARENTHESIZED LATIN SMALL LETTER A +1D41A ; [.15D4.0020.0005.1D41A] # MATHEMATICAL BOLD SMALL A +1D44E ; [.15D4.0020.0005.1D44E] # MATHEMATICAL ITALIC SMALL A +1D482 ; [.15D4.0020.0005.1D482] # MATHEMATICAL BOLD ITALIC SMALL A +1D4B6 ; [.15D4.0020.0005.1D4B6] # MATHEMATICAL SCRIPT SMALL A +1D4EA ; [.15D4.0020.0005.1D4EA] # MATHEMATICAL BOLD SCRIPT SMALL A +1D51E ; [.15D4.0020.0005.1D51E] # MATHEMATICAL FRAKTUR SMALL A +1D552 ; [.15D4.0020.0005.1D552] # MATHEMATICAL DOUBLE-STRUCK SMALL A +1D586 ; [.15D4.0020.0005.1D586] # MATHEMATICAL BOLD FRAKTUR SMALL A +1D5BA ; [.15D4.0020.0005.1D5BA] # MATHEMATICAL SANS-SERIF SMALL A +1D5EE ; [.15D4.0020.0005.1D5EE] # MATHEMATICAL SANS-SERIF BOLD SMALL A +1D622 ; [.15D4.0020.0005.1D622] # MATHEMATICAL SANS-SERIF ITALIC SMALL A +1D656 ; [.15D4.0020.0005.1D656] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A +1D68A ; [.15D4.0020.0005.1D68A] # MATHEMATICAL MONOSPACE SMALL A +24D0 ; [.15D4.0020.0006.24D0] # CIRCLED LATIN SMALL LETTER A +0041 ; [.15D4.0020.0008.0041] # LATIN CAPITAL LETTER A +FF21 ; [.15D4.0020.0009.FF21] # FULLWIDTH LATIN CAPITAL LETTER A +1F110 ; [*02FB.0020.0004.1F110][.15D4.0020.000A.1F110][*02FC.0020.001F.1F110] # PARENTHESIZED LATIN CAPITAL LETTER A +1F1E6 ; [.15D4.0020.000A.1F1E6] # REGIONAL INDICATOR SYMBOL LETTER A +1D400 ; [.15D4.0020.000B.1D400] # MATHEMATICAL BOLD CAPITAL A +1D434 ; [.15D4.0020.000B.1D434] # MATHEMATICAL ITALIC CAPITAL A +1D468 ; [.15D4.0020.000B.1D468] # MATHEMATICAL BOLD ITALIC CAPITAL A +1D49C ; [.15D4.0020.000B.1D49C] # MATHEMATICAL SCRIPT CAPITAL A +1D4D0 ; [.15D4.0020.000B.1D4D0] # MATHEMATICAL BOLD SCRIPT CAPITAL A +1D504 ; [.15D4.0020.000B.1D504] # MATHEMATICAL FRAKTUR CAPITAL A +1D538 ; [.15D4.0020.000B.1D538] # MATHEMATICAL DOUBLE-STRUCK CAPITAL A +1D56C ; [.15D4.0020.000B.1D56C] # MATHEMATICAL BOLD FRAKTUR CAPITAL A +1D5A0 ; [.15D4.0020.000B.1D5A0] # MATHEMATICAL SANS-SERIF CAPITAL A +1D5D4 ; [.15D4.0020.000B.1D5D4] # MATHEMATICAL SANS-SERIF BOLD CAPITAL A +1D608 ; [.15D4.0020.000B.1D608] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL A +1D63C ; [.15D4.0020.000B.1D63C] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A +1D670 ; [.15D4.0020.000B.1D670] # MATHEMATICAL MONOSPACE CAPITAL A +24B6 ; [.15D4.0020.000C.24B6] # CIRCLED LATIN CAPITAL LETTER A +1F150 ; [.15D4.0020.000C.1F150] # NEGATIVE CIRCLED LATIN CAPITAL LETTER A +00AA ; [.15D4.0020.0014.00AA] # FEMININE ORDINAL INDICATOR +1D43 ; [.15D4.0020.0014.1D43] # MODIFIER LETTER SMALL A +2090 ; [.15D4.0020.0015.2090] # LATIN SUBSCRIPT SMALL LETTER A +1D2C ; [.15D4.0020.001D.1D2C] # MODIFIER LETTER CAPITAL A +1F130 ; [.15D4.0020.001D.1F130] # SQUARED LATIN CAPITAL LETTER A +1F170 ; [.15D4.0020.001D.1F170] # NEGATIVE SQUARED LATIN CAPITAL LETTER A +00E1 ; [.15D4.0020.0002.0061][.0000.0032.0002.0301] # LATIN SMALL LETTER A WITH ACUTE +00C1 ; [.15D4.0020.0008.0041][.0000.0032.0002.0301] # LATIN CAPITAL LETTER A WITH ACUTE +00E0 ; [.15D4.0020.0002.0061][.0000.0035.0002.0300] # LATIN SMALL LETTER A WITH GRAVE +00C0 ; [.15D4.0020.0008.0041][.0000.0035.0002.0300] # LATIN CAPITAL LETTER A WITH GRAVE +0103 ; [.15D4.0020.0002.0061][.0000.0037.0002.0306] # LATIN SMALL LETTER A WITH BREVE +0102 ; [.15D4.0020.0008.0041][.0000.0037.0002.0306] # LATIN CAPITAL LETTER A WITH BREVE +1EAF ; [.15D4.0020.0002.0061][.0000.0037.0002.0306][.0000.0032.0002.0301] # LATIN SMALL LETTER A WITH BREVE AND ACUTE +1EAE ; [.15D4.0020.0008.0041][.0000.0037.0002.0306][.0000.0032.0002.0301] # LATIN CAPITAL LETTER A WITH BREVE AND ACUTE +1EB1 ; [.15D4.0020.0002.0061][.0000.0037.0002.0306][.0000.0035.0002.0300] # LATIN SMALL LETTER A WITH BREVE AND GRAVE +1EB0 ; [.15D4.0020.0008.0041][.0000.0037.0002.0306][.0000.0035.0002.0300] # LATIN CAPITAL LETTER A WITH BREVE AND GRAVE +1EB5 ; [.15D4.0020.0002.0061][.0000.0037.0002.0306][.0000.004E.0002.0303] # LATIN SMALL LETTER A WITH BREVE AND TILDE +1EB4 ; [.15D4.0020.0008.0041][.0000.0037.0002.0306][.0000.004E.0002.0303] # LATIN CAPITAL LETTER A WITH BREVE AND TILDE +1EB3 ; [.15D4.0020.0002.0061][.0000.0037.0002.0306][.0000.0064.0002.0309] # LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE +1EB2 ; [.15D4.0020.0008.0041][.0000.0037.0002.0306][.0000.0064.0002.0309] # LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE +00E2 ; [.15D4.0020.0002.0061][.0000.003C.0002.0302] # LATIN SMALL LETTER A WITH CIRCUMFLEX +00C2 ; [.15D4.0020.0008.0041][.0000.003C.0002.0302] # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +1EA5 ; [.15D4.0020.0002.0061][.0000.003C.0002.0302][.0000.0032.0002.0301] # LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE +1EA4 ; [.15D4.0020.0008.0041][.0000.003C.0002.0302][.0000.0032.0002.0301] # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE +1EA7 ; [.15D4.0020.0002.0061][.0000.003C.0002.0302][.0000.0035.0002.0300] # LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE +1EA6 ; [.15D4.0020.0008.0041][.0000.003C.0002.0302][.0000.0035.0002.0300] # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE +1EAB ; [.15D4.0020.0002.0061][.0000.003C.0002.0302][.0000.004E.0002.0303] # LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE +1EAA ; [.15D4.0020.0008.0041][.0000.003C.0002.0302][.0000.004E.0002.0303] # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE +1EA9 ; [.15D4.0020.0002.0061][.0000.003C.0002.0302][.0000.0064.0002.0309] # LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +1EA8 ; [.15D4.0020.0008.0041][.0000.003C.0002.0302][.0000.0064.0002.0309] # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +01CE ; [.15D4.0020.0002.0061][.0000.0041.0002.030C] # LATIN SMALL LETTER A WITH CARON +01CD ; [.15D4.0020.0008.0041][.0000.0041.0002.030C] # LATIN CAPITAL LETTER A WITH CARON +00E5 ; [.15D4.0020.0002.0061][.0000.0043.0002.030A] # LATIN SMALL LETTER A WITH RING ABOVE +00C5 ; [.15D4.0020.0008.0041][.0000.0043.0002.030A] # LATIN CAPITAL LETTER A WITH RING ABOVE +212B ; [.15D4.0020.0008.0041][.0000.0043.0002.030A] # ANGSTROM SIGN +01FB ; [.15D4.0020.0002.0061][.0000.0043.0002.030A][.0000.0032.0002.0301] # LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE +01FA ; [.15D4.0020.0008.0041][.0000.0043.0002.030A][.0000.0032.0002.0301] # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE +00E4 ; [.15D4.0020.0002.0061][.0000.0047.0002.0308] # LATIN SMALL LETTER A WITH DIAERESIS +00C4 ; [.15D4.0020.0008.0041][.0000.0047.0002.0308] # LATIN CAPITAL LETTER A WITH DIAERESIS +01DF ; [.15D4.0020.0002.0061][.0000.0047.0002.0308][.0000.005B.0002.0304] # LATIN SMALL LETTER A WITH DIAERESIS AND MACRON +01DE ; [.15D4.0020.0008.0041][.0000.0047.0002.0308][.0000.005B.0002.0304] # LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON +00E3 ; [.15D4.0020.0002.0061][.0000.004E.0002.0303] # LATIN SMALL LETTER A WITH TILDE +00C3 ; [.15D4.0020.0008.0041][.0000.004E.0002.0303] # LATIN CAPITAL LETTER A WITH TILDE +0227 ; [.15D4.0020.0002.0061][.0000.0052.0002.0307] # LATIN SMALL LETTER A WITH DOT ABOVE +0226 ; [.15D4.0020.0008.0041][.0000.0052.0002.0307] # LATIN CAPITAL LETTER A WITH DOT ABOVE +01E1 ; [.15D4.0020.0002.0061][.0000.0052.0002.0307][.0000.005B.0002.0304] # LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON +01E0 ; [.15D4.0020.0008.0041][.0000.0052.0002.0307][.0000.005B.0002.0304] # LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON +0105 ; [.15D4.0020.0002.0061][.0000.0059.0002.0328] # LATIN SMALL LETTER A WITH OGONEK +0104 ; [.15D4.0020.0008.0041][.0000.0059.0002.0328] # LATIN CAPITAL LETTER A WITH OGONEK +0101 ; [.15D4.0020.0002.0061][.0000.005B.0002.0304] # LATIN SMALL LETTER A WITH MACRON +0100 ; [.15D4.0020.0008.0041][.0000.005B.0002.0304] # LATIN CAPITAL LETTER A WITH MACRON +1EA3 ; [.15D4.0020.0002.0061][.0000.0064.0002.0309] # LATIN SMALL LETTER A WITH HOOK ABOVE +1EA2 ; [.15D4.0020.0008.0041][.0000.0064.0002.0309] # LATIN CAPITAL LETTER A WITH HOOK ABOVE +0201 ; [.15D4.0020.0002.0061][.0000.0065.0002.030F] # LATIN SMALL LETTER A WITH DOUBLE GRAVE +0200 ; [.15D4.0020.0008.0041][.0000.0065.0002.030F] # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE +0203 ; [.15D4.0020.0002.0061][.0000.0067.0002.0311] # LATIN SMALL LETTER A WITH INVERTED BREVE +0202 ; [.15D4.0020.0008.0041][.0000.0067.0002.0311] # LATIN CAPITAL LETTER A WITH INVERTED BREVE +1EA1 ; [.15D4.0020.0002.0061][.0000.0070.0002.0323] # LATIN SMALL LETTER A WITH DOT BELOW +1EA0 ; [.15D4.0020.0008.0041][.0000.0070.0002.0323] # LATIN CAPITAL LETTER A WITH DOT BELOW +1EB7 ; [.15D4.0020.0002.0061][.0000.0070.0002.0323][.0000.0037.0002.0306] # LATIN SMALL LETTER A WITH BREVE AND DOT BELOW +1EB6 ; [.15D4.0020.0008.0041][.0000.0070.0002.0323][.0000.0037.0002.0306] # LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW +1EAD ; [.15D4.0020.0002.0061][.0000.0070.0002.0323][.0000.003C.0002.0302] # LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW +1EAC ; [.15D4.0020.0008.0041][.0000.0070.0002.0323][.0000.003C.0002.0302] # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW +1E01 ; [.15D4.0020.0002.0061][.0000.0076.0002.0325] # LATIN SMALL LETTER A WITH RING BELOW +1E00 ; [.15D4.0020.0008.0041][.0000.0076.0002.0325] # LATIN CAPITAL LETTER A WITH RING BELOW +1DD3 ; [.15D4.0020.0004.1DD3][.0000.0139.0004.1DD3] # COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE +A733 ; [.15D4.0020.0004.A733][.15D4.0020.0004.A733] # LATIN SMALL LETTER AA +A732 ; [.15D4.0020.000A.A732][.15D4.0020.000A.A732] # LATIN CAPITAL LETTER AA +1F18E ; [.15D4.0020.001D.1F18E][.15EA.0020.001D.1F18E] # NEGATIVE SQUARED AB +2100 ; [.15D4.0020.0004.2100][*0372.0020.0004.2100][.1602.0020.001F.2100] # ACCOUNT OF +00E6 ; [.15D4.0020.0004.00E6][.0000.0139.0004.00E6][.1631.0020.001F.00E6] # LATIN SMALL LETTER AE +1DD4 ; [.15D4.0020.0004.1DD4][.0000.0139.0004.1DD4][.1631.0020.001F.1DD4] # COMBINING LATIN SMALL LETTER AE +00C6 ; [.15D4.0020.000A.00C6][.0000.0139.0004.00C6][.1631.0020.001F.00C6] # LATIN CAPITAL LETTER AE +1D2D ; [.15D4.0020.0014.1D2D][.0000.0139.0014.1D2D][.1631.0020.001F.1D2D] # MODIFIER LETTER CAPITAL AE +01FD ; [.15D4.0020.0004.01FD][.0000.0139.0004.01FD][.1631.0020.001F.01FD][.0000.0032.0002.01FD] # LATIN SMALL LETTER AE WITH ACUTE +01FC ; [.15D4.0020.000A.01FC][.0000.0139.0004.01FC][.1631.0020.001F.01FC][.0000.0032.0002.01FC] # LATIN CAPITAL LETTER AE WITH ACUTE +01E3 ; [.15D4.0020.0004.01E3][.0000.0139.0004.01E3][.1631.0020.001F.01E3][.0000.005B.0002.01E3] # LATIN SMALL LETTER AE WITH MACRON +01E2 ; [.15D4.0020.000A.01E2][.0000.0139.0004.01E2][.1631.0020.001F.01E2][.0000.005B.0002.01E2] # LATIN CAPITAL LETTER AE WITH MACRON +33C2 ; [.15D4.0020.001C.33C2][*0273.0020.001C.33C2][.1726.0020.001F.33C2][*0273.0020.001F.33C2] # SQUARE AM +33DF ; [.15D4.0020.001D.33DF][*05AB.0020.001C.33DF][.1726.0020.001F.33DF] # SQUARE A OVER M +1DD5 ; [.15D4.0020.0004.1DD5][.1756.0020.0004.1DD5] # COMBINING LATIN SMALL LETTER AO +A735 ; [.15D4.0020.0004.A735][.1756.0020.0004.A735] # LATIN SMALL LETTER AO +A734 ; [.15D4.0020.000A.A734][.1756.0020.000A.A734] # LATIN CAPITAL LETTER AO +2101 ; [.15D4.0020.0004.2101][*0372.0020.0004.2101][.17D8.0020.001F.2101] # ADDRESSED TO THE SUBJECT +214D ; [.15D4.0020.000A.214D][*0372.0020.0004.214D][.17D8.0020.001F.214D] # AKTIESELSKAB +A737 ; [.15D4.0020.0004.A737][.181B.0020.0004.A737] # LATIN SMALL LETTER AU +A736 ; [.15D4.0020.000A.A736][.181B.0020.000A.A736] # LATIN CAPITAL LETTER AU +3373 ; [.15D4.0020.001D.3373][.181B.0020.001D.3373] # SQUARE AU +1DD6 ; [.15D4.0020.0004.1DD6][.1844.0020.0004.1DD6] # COMBINING LATIN SMALL LETTER AV +A739 ; [.15D4.0020.0004.A739][.1844.0020.0004.A739] # LATIN SMALL LETTER AV +A738 ; [.15D4.0020.000A.A738][.1844.0020.000A.A738] # LATIN CAPITAL LETTER AV +A73B ; [.15D4.0020.0004.A73B][.0000.0139.0004.A73B][.1844.0020.001F.A73B] # LATIN SMALL LETTER AV WITH HORIZONTAL BAR +A73A ; [.15D4.0020.000A.A73A][.0000.0139.0004.A73A][.1844.0020.001F.A73A] # LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR +A73D ; [.15D4.0020.0004.A73D][.1865.0020.0004.A73D] # LATIN SMALL LETTER AY +A73C ; [.15D4.0020.000A.A73C][.1865.0020.000A.A73C] # LATIN CAPITAL LETTER AY +1E9A ; [.15D4.0020.0004.1E9A][.18D6.0020.0004.1E9A] # LATIN SMALL LETTER A WITH RIGHT HALF RING +1D00 ; [.15D8.0020.0002.1D00] # LATIN LETTER SMALL CAPITAL A +2C65 ; [.15D9.0020.0002.2C65] # LATIN SMALL LETTER A WITH STROKE +023A ; [.15D9.0020.0008.023A] # LATIN CAPITAL LETTER A WITH STROKE +1D8F ; [.15DA.0020.0002.1D8F] # LATIN SMALL LETTER A WITH RETROFLEX HOOK +1D01 ; [.15DB.0020.0002.1D01] # LATIN LETTER SMALL CAPITAL AE +1D02 ; [.15DC.0020.0002.1D02] # LATIN SMALL LETTER TURNED AE +1D46 ; [.15DC.0020.0014.1D46] # MODIFIER LETTER SMALL TURNED AE +0250 ; [.15DD.0020.0002.0250] # LATIN SMALL LETTER TURNED A +2C6F ; [.15DD.0020.0008.2C6F] # LATIN CAPITAL LETTER TURNED A +1D44 ; [.15DD.0020.0014.1D44] # MODIFIER LETTER SMALL TURNED A +0251 ; [.15E1.0020.0002.0251] # LATIN SMALL LETTER ALPHA +2C6D ; [.15E1.0020.0008.2C6D] # LATIN CAPITAL LETTER ALPHA +1D45 ; [.15E1.0020.0014.1D45] # MODIFIER LETTER SMALL ALPHA +1D90 ; [.15E5.0020.0002.1D90] # LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK +0252 ; [.15E6.0020.0002.0252] # LATIN SMALL LETTER TURNED ALPHA +2C70 ; [.15E6.0020.0008.2C70] # LATIN CAPITAL LETTER TURNED ALPHA +1D9B ; [.15E6.0020.0014.1D9B] # MODIFIER LETTER SMALL TURNED ALPHA +0062 ; [.15EA.0020.0002.0062] # LATIN SMALL LETTER B +FF42 ; [.15EA.0020.0003.FF42] # FULLWIDTH LATIN SMALL LETTER B +249D ; [*02FB.0020.0004.249D][.15EA.0020.0004.249D][*02FC.0020.001F.249D] # PARENTHESIZED LATIN SMALL LETTER B +1D41B ; [.15EA.0020.0005.1D41B] # MATHEMATICAL BOLD SMALL B +1D44F ; [.15EA.0020.0005.1D44F] # MATHEMATICAL ITALIC SMALL B +1D483 ; [.15EA.0020.0005.1D483] # MATHEMATICAL BOLD ITALIC SMALL B +1D4B7 ; [.15EA.0020.0005.1D4B7] # MATHEMATICAL SCRIPT SMALL B +1D4EB ; [.15EA.0020.0005.1D4EB] # MATHEMATICAL BOLD SCRIPT SMALL B +1D51F ; [.15EA.0020.0005.1D51F] # MATHEMATICAL FRAKTUR SMALL B +1D553 ; [.15EA.0020.0005.1D553] # MATHEMATICAL DOUBLE-STRUCK SMALL B +1D587 ; [.15EA.0020.0005.1D587] # MATHEMATICAL BOLD FRAKTUR SMALL B +1D5BB ; [.15EA.0020.0005.1D5BB] # MATHEMATICAL SANS-SERIF SMALL B +1D5EF ; [.15EA.0020.0005.1D5EF] # MATHEMATICAL SANS-SERIF BOLD SMALL B +1D623 ; [.15EA.0020.0005.1D623] # MATHEMATICAL SANS-SERIF ITALIC SMALL B +1D657 ; [.15EA.0020.0005.1D657] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B +1D68B ; [.15EA.0020.0005.1D68B] # MATHEMATICAL MONOSPACE SMALL B +24D1 ; [.15EA.0020.0006.24D1] # CIRCLED LATIN SMALL LETTER B +0042 ; [.15EA.0020.0008.0042] # LATIN CAPITAL LETTER B +FF22 ; [.15EA.0020.0009.FF22] # FULLWIDTH LATIN CAPITAL LETTER B +1F111 ; [*02FB.0020.0004.1F111][.15EA.0020.000A.1F111][*02FC.0020.001F.1F111] # PARENTHESIZED LATIN CAPITAL LETTER B +1F1E7 ; [.15EA.0020.000A.1F1E7] # REGIONAL INDICATOR SYMBOL LETTER B +212C ; [.15EA.0020.000B.212C] # SCRIPT CAPITAL B +1D401 ; [.15EA.0020.000B.1D401] # MATHEMATICAL BOLD CAPITAL B +1D435 ; [.15EA.0020.000B.1D435] # MATHEMATICAL ITALIC CAPITAL B +1D469 ; [.15EA.0020.000B.1D469] # MATHEMATICAL BOLD ITALIC CAPITAL B +1D4D1 ; [.15EA.0020.000B.1D4D1] # MATHEMATICAL BOLD SCRIPT CAPITAL B +1D505 ; [.15EA.0020.000B.1D505] # MATHEMATICAL FRAKTUR CAPITAL B +1D539 ; [.15EA.0020.000B.1D539] # MATHEMATICAL DOUBLE-STRUCK CAPITAL B +1D56D ; [.15EA.0020.000B.1D56D] # MATHEMATICAL BOLD FRAKTUR CAPITAL B +1D5A1 ; [.15EA.0020.000B.1D5A1] # MATHEMATICAL SANS-SERIF CAPITAL B +1D5D5 ; [.15EA.0020.000B.1D5D5] # MATHEMATICAL SANS-SERIF BOLD CAPITAL B +1D609 ; [.15EA.0020.000B.1D609] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL B +1D63D ; [.15EA.0020.000B.1D63D] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B +1D671 ; [.15EA.0020.000B.1D671] # MATHEMATICAL MONOSPACE CAPITAL B +24B7 ; [.15EA.0020.000C.24B7] # CIRCLED LATIN CAPITAL LETTER B +1F151 ; [.15EA.0020.000C.1F151] # NEGATIVE CIRCLED LATIN CAPITAL LETTER B +1D47 ; [.15EA.0020.0014.1D47] # MODIFIER LETTER SMALL B +1D2E ; [.15EA.0020.001D.1D2E] # MODIFIER LETTER CAPITAL B +1F131 ; [.15EA.0020.001D.1F131] # SQUARED LATIN CAPITAL LETTER B +1F171 ; [.15EA.0020.001D.1F171] # NEGATIVE SQUARED LATIN CAPITAL LETTER B +1E03 ; [.15EA.0020.0002.0062][.0000.0052.0002.0307] # LATIN SMALL LETTER B WITH DOT ABOVE +1E02 ; [.15EA.0020.0008.0042][.0000.0052.0002.0307] # LATIN CAPITAL LETTER B WITH DOT ABOVE +1E05 ; [.15EA.0020.0002.0062][.0000.0070.0002.0323] # LATIN SMALL LETTER B WITH DOT BELOW +1E04 ; [.15EA.0020.0008.0042][.0000.0070.0002.0323] # LATIN CAPITAL LETTER B WITH DOT BELOW +1E07 ; [.15EA.0020.0002.0062][.0000.007B.0002.0331] # LATIN SMALL LETTER B WITH LINE BELOW +1E06 ; [.15EA.0020.0008.0042][.0000.007B.0002.0331] # LATIN CAPITAL LETTER B WITH LINE BELOW +3374 ; [.15EA.0020.001C.3374][.15D4.0020.001C.3374][.17A2.0020.001F.3374] # SQUARE BAR +33C3 ; [.15EA.0020.001D.33C3][.1790.0020.001C.33C3] # SQUARE BQ +0299 ; [.15EE.0020.0002.0299] # LATIN LETTER SMALL CAPITAL B +0180 ; [.15F2.0020.0002.0180] # LATIN SMALL LETTER B WITH STROKE +0243 ; [.15F2.0020.0008.0243] # LATIN CAPITAL LETTER B WITH STROKE +1D2F ; [.15F6.0020.0002.1D2F] # MODIFIER LETTER CAPITAL BARRED B +1D03 ; [.15F7.0020.0002.1D03] # LATIN LETTER SMALL CAPITAL BARRED B +1D6C ; [.15F8.0020.0002.1D6C] # LATIN SMALL LETTER B WITH MIDDLE TILDE +1D80 ; [.15F9.0020.0002.1D80] # LATIN SMALL LETTER B WITH PALATAL HOOK +0253 ; [.15FA.0020.0002.0253] # LATIN SMALL LETTER B WITH HOOK +0181 ; [.15FA.0020.0008.0181] # LATIN CAPITAL LETTER B WITH HOOK +0183 ; [.15FE.0020.0002.0183] # LATIN SMALL LETTER B WITH TOPBAR +0182 ; [.15FE.0020.0008.0182] # LATIN CAPITAL LETTER B WITH TOPBAR +0063 ; [.1602.0020.0002.0063] # LATIN SMALL LETTER C +FF43 ; [.1602.0020.0003.FF43] # FULLWIDTH LATIN SMALL LETTER C +0368 ; [.1602.0020.0004.0368] # COMBINING LATIN SMALL LETTER C +217D ; [.1602.0020.0004.217D] # SMALL ROMAN NUMERAL ONE HUNDRED +249E ; [*02FB.0020.0004.249E][.1602.0020.0004.249E][*02FC.0020.001F.249E] # PARENTHESIZED LATIN SMALL LETTER C +1D41C ; [.1602.0020.0005.1D41C] # MATHEMATICAL BOLD SMALL C +1D450 ; [.1602.0020.0005.1D450] # MATHEMATICAL ITALIC SMALL C +1D484 ; [.1602.0020.0005.1D484] # MATHEMATICAL BOLD ITALIC SMALL C +1D4B8 ; [.1602.0020.0005.1D4B8] # MATHEMATICAL SCRIPT SMALL C +1D4EC ; [.1602.0020.0005.1D4EC] # MATHEMATICAL BOLD SCRIPT SMALL C +1D520 ; [.1602.0020.0005.1D520] # MATHEMATICAL FRAKTUR SMALL C +1D554 ; [.1602.0020.0005.1D554] # MATHEMATICAL DOUBLE-STRUCK SMALL C +1D588 ; [.1602.0020.0005.1D588] # MATHEMATICAL BOLD FRAKTUR SMALL C +1D5BC ; [.1602.0020.0005.1D5BC] # MATHEMATICAL SANS-SERIF SMALL C +1D5F0 ; [.1602.0020.0005.1D5F0] # MATHEMATICAL SANS-SERIF BOLD SMALL C +1D624 ; [.1602.0020.0005.1D624] # MATHEMATICAL SANS-SERIF ITALIC SMALL C +1D658 ; [.1602.0020.0005.1D658] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C +1D68C ; [.1602.0020.0005.1D68C] # MATHEMATICAL MONOSPACE SMALL C +24D2 ; [.1602.0020.0006.24D2] # CIRCLED LATIN SMALL LETTER C +0043 ; [.1602.0020.0008.0043] # LATIN CAPITAL LETTER C +FF23 ; [.1602.0020.0009.FF23] # FULLWIDTH LATIN CAPITAL LETTER C +2103 ; [*0482.0020.0004.2103][.1602.0020.000A.2103] # DEGREE CELSIUS +216D ; [.1602.0020.000A.216D] # ROMAN NUMERAL ONE HUNDRED +1F112 ; [*02FB.0020.0004.1F112][.1602.0020.000A.1F112][*02FC.0020.001F.1F112] # PARENTHESIZED LATIN CAPITAL LETTER C +1F1E8 ; [.1602.0020.000A.1F1E8] # REGIONAL INDICATOR SYMBOL LETTER C +2102 ; [.1602.0020.000B.2102] # DOUBLE-STRUCK CAPITAL C +212D ; [.1602.0020.000B.212D] # BLACK-LETTER CAPITAL C +1D402 ; [.1602.0020.000B.1D402] # MATHEMATICAL BOLD CAPITAL C +1D436 ; [.1602.0020.000B.1D436] # MATHEMATICAL ITALIC CAPITAL C +1D46A ; [.1602.0020.000B.1D46A] # MATHEMATICAL BOLD ITALIC CAPITAL C +1D49E ; [.1602.0020.000B.1D49E] # MATHEMATICAL SCRIPT CAPITAL C +1D4D2 ; [.1602.0020.000B.1D4D2] # MATHEMATICAL BOLD SCRIPT CAPITAL C +1D56E ; [.1602.0020.000B.1D56E] # MATHEMATICAL BOLD FRAKTUR CAPITAL C +1D5A2 ; [.1602.0020.000B.1D5A2] # MATHEMATICAL SANS-SERIF CAPITAL C +1D5D6 ; [.1602.0020.000B.1D5D6] # MATHEMATICAL SANS-SERIF BOLD CAPITAL C +1D60A ; [.1602.0020.000B.1D60A] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL C +1D63E ; [.1602.0020.000B.1D63E] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C +1D672 ; [.1602.0020.000B.1D672] # MATHEMATICAL MONOSPACE CAPITAL C +24B8 ; [.1602.0020.000C.24B8] # CIRCLED LATIN CAPITAL LETTER C +1F12B ; [.1602.0020.000C.1F12B] # CIRCLED ITALIC LATIN CAPITAL LETTER C +1F152 ; [.1602.0020.000C.1F152] # NEGATIVE CIRCLED LATIN CAPITAL LETTER C +1D9C ; [.1602.0020.0014.1D9C] # MODIFIER LETTER SMALL C +1F132 ; [.1602.0020.001D.1F132] # SQUARED LATIN CAPITAL LETTER C +1F172 ; [.1602.0020.001D.1F172] # NEGATIVE SQUARED LATIN CAPITAL LETTER C +0107 ; [.1602.0020.0002.0063][.0000.0032.0002.0301] # LATIN SMALL LETTER C WITH ACUTE +0106 ; [.1602.0020.0008.0043][.0000.0032.0002.0301] # LATIN CAPITAL LETTER C WITH ACUTE +0109 ; [.1602.0020.0002.0063][.0000.003C.0002.0302] # LATIN SMALL LETTER C WITH CIRCUMFLEX +0108 ; [.1602.0020.0008.0043][.0000.003C.0002.0302] # LATIN CAPITAL LETTER C WITH CIRCUMFLEX +010D ; [.1602.0020.0002.0063][.0000.0041.0002.030C] # LATIN SMALL LETTER C WITH CARON +010C ; [.1602.0020.0008.0043][.0000.0041.0002.030C] # LATIN CAPITAL LETTER C WITH CARON +010B ; [.1602.0020.0002.0063][.0000.0052.0002.0307] # LATIN SMALL LETTER C WITH DOT ABOVE +010A ; [.1602.0020.0008.0043][.0000.0052.0002.0307] # LATIN CAPITAL LETTER C WITH DOT ABOVE +00E7 ; [.1602.0020.0002.0063][.0000.0056.0002.0327] # LATIN SMALL LETTER C WITH CEDILLA +1DD7 ; [.1602.0020.0004.1DD7][.0000.0056.0004.1DD7] # COMBINING LATIN SMALL LETTER C CEDILLA +00C7 ; [.1602.0020.0008.0043][.0000.0056.0002.0327] # LATIN CAPITAL LETTER C WITH CEDILLA +1E09 ; [.1602.0020.0002.0063][.0000.0056.0002.0327][.0000.0032.0002.0301] # LATIN SMALL LETTER C WITH CEDILLA AND ACUTE +1E08 ; [.1602.0020.0008.0043][.0000.0056.0002.0327][.0000.0032.0002.0301] # LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE +3388 ; [.1602.0020.001C.3388][.15D4.0020.001C.3388][.16F6.0020.001F.3388] # SQUARE CAL +33C4 ; [.1602.0020.001C.33C4][.1602.0020.001C.33C4] # SQUARE CC +1F12D ; [.1602.0020.000C.1F12D][.1616.0020.000C.1F12D] # CIRCLED CD +33C5 ; [.1602.0020.001C.33C5][.1616.0020.001C.33C5] # SQUARE CD +33C6 ; [.1602.0020.001D.33C6][*05AB.0020.001C.33C6][.16E4.0020.001F.33C6][.1676.0020.001F.33C6] # SQUARE C OVER KG +1F191 ; [.1602.0020.001D.1F191][.16F6.0020.001D.1F191] # SQUARED CL +339D ; [.1602.0020.001C.339D][.1726.0020.001C.339D] # SQUARE CM +33A0 ; [.1602.0020.001C.33A0][.1726.0020.001C.33A0][.15CC.0020.001F.33A0] # SQUARE CM SQUARED +33A4 ; [.1602.0020.001C.33A4][.1726.0020.001C.33A4][.15CD.0020.001F.33A4] # SQUARE CM CUBED +2105 ; [.1602.0020.0004.2105][*0372.0020.0004.2105][.1756.0020.001F.2105] # CARE OF +33C7 ; [.1602.0020.001D.33C7][.1756.0020.001C.33C7][*0273.0020.001F.33C7] # SQUARE CO +1F192 ; [.1602.0020.001D.1F192][.1756.0020.001D.1F192][.1756.0020.001F.1F192][.16F6.0020.001F.1F192] # SQUARED COOL +2106 ; [.1602.0020.0004.2106][*0372.0020.0004.2106][.181B.0020.001F.2106] # CADA UNA +1D04 ; [.1606.0020.0002.1D04] # LATIN LETTER SMALL CAPITAL C +023C ; [.1607.0020.0002.023C] # LATIN SMALL LETTER C WITH STROKE +023B ; [.1607.0020.0008.023B] # LATIN CAPITAL LETTER C WITH STROKE +A793 ; [.160B.0020.0002.A793] # LATIN SMALL LETTER C WITH BAR +A792 ; [.160B.0020.0008.A792] # LATIN CAPITAL LETTER C WITH BAR +0188 ; [.160C.0020.0002.0188] # LATIN SMALL LETTER C WITH HOOK +0187 ; [.160C.0020.0008.0187] # LATIN CAPITAL LETTER C WITH HOOK +0255 ; [.1610.0020.0002.0255] # LATIN SMALL LETTER C WITH CURL +1D9D ; [.1610.0020.0014.1D9D] # MODIFIER LETTER SMALL C WITH CURL +2184 ; [.1614.0020.0002.2184] # LATIN SMALL LETTER REVERSED C +2183 ; [.1614.0020.0008.2183] # ROMAN NUMERAL REVERSED ONE HUNDRED +A73F ; [.1615.0020.0002.A73F] # LATIN SMALL LETTER REVERSED C WITH DOT +A73E ; [.1615.0020.0008.A73E] # LATIN CAPITAL LETTER REVERSED C WITH DOT +0064 ; [.1616.0020.0002.0064] # LATIN SMALL LETTER D +FF44 ; [.1616.0020.0003.FF44] # FULLWIDTH LATIN SMALL LETTER D +0369 ; [.1616.0020.0004.0369] # COMBINING LATIN SMALL LETTER D +217E ; [.1616.0020.0004.217E] # SMALL ROMAN NUMERAL FIVE HUNDRED +249F ; [*02FB.0020.0004.249F][.1616.0020.0004.249F][*02FC.0020.001F.249F] # PARENTHESIZED LATIN SMALL LETTER D +2146 ; [.1616.0020.0005.2146] # DOUBLE-STRUCK ITALIC SMALL D +1D41D ; [.1616.0020.0005.1D41D] # MATHEMATICAL BOLD SMALL D +1D451 ; [.1616.0020.0005.1D451] # MATHEMATICAL ITALIC SMALL D +1D485 ; [.1616.0020.0005.1D485] # MATHEMATICAL BOLD ITALIC SMALL D +1D4B9 ; [.1616.0020.0005.1D4B9] # MATHEMATICAL SCRIPT SMALL D +1D4ED ; [.1616.0020.0005.1D4ED] # MATHEMATICAL BOLD SCRIPT SMALL D +1D521 ; [.1616.0020.0005.1D521] # MATHEMATICAL FRAKTUR SMALL D +1D555 ; [.1616.0020.0005.1D555] # MATHEMATICAL DOUBLE-STRUCK SMALL D +1D589 ; [.1616.0020.0005.1D589] # MATHEMATICAL BOLD FRAKTUR SMALL D +1D5BD ; [.1616.0020.0005.1D5BD] # MATHEMATICAL SANS-SERIF SMALL D +1D5F1 ; [.1616.0020.0005.1D5F1] # MATHEMATICAL SANS-SERIF BOLD SMALL D +1D625 ; [.1616.0020.0005.1D625] # MATHEMATICAL SANS-SERIF ITALIC SMALL D +1D659 ; [.1616.0020.0005.1D659] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D +1D68D ; [.1616.0020.0005.1D68D] # MATHEMATICAL MONOSPACE SMALL D +24D3 ; [.1616.0020.0006.24D3] # CIRCLED LATIN SMALL LETTER D +0044 ; [.1616.0020.0008.0044] # LATIN CAPITAL LETTER D +FF24 ; [.1616.0020.0009.FF24] # FULLWIDTH LATIN CAPITAL LETTER D +216E ; [.1616.0020.000A.216E] # ROMAN NUMERAL FIVE HUNDRED +1F113 ; [*02FB.0020.0004.1F113][.1616.0020.000A.1F113][*02FC.0020.001F.1F113] # PARENTHESIZED LATIN CAPITAL LETTER D +1F1E9 ; [.1616.0020.000A.1F1E9] # REGIONAL INDICATOR SYMBOL LETTER D +2145 ; [.1616.0020.000B.2145] # DOUBLE-STRUCK ITALIC CAPITAL D +1D403 ; [.1616.0020.000B.1D403] # MATHEMATICAL BOLD CAPITAL D +1D437 ; [.1616.0020.000B.1D437] # MATHEMATICAL ITALIC CAPITAL D +1D46B ; [.1616.0020.000B.1D46B] # MATHEMATICAL BOLD ITALIC CAPITAL D +1D49F ; [.1616.0020.000B.1D49F] # MATHEMATICAL SCRIPT CAPITAL D +1D4D3 ; [.1616.0020.000B.1D4D3] # MATHEMATICAL BOLD SCRIPT CAPITAL D +1D507 ; [.1616.0020.000B.1D507] # MATHEMATICAL FRAKTUR CAPITAL D +1D53B ; [.1616.0020.000B.1D53B] # MATHEMATICAL DOUBLE-STRUCK CAPITAL D +1D56F ; [.1616.0020.000B.1D56F] # MATHEMATICAL BOLD FRAKTUR CAPITAL D +1D5A3 ; [.1616.0020.000B.1D5A3] # MATHEMATICAL SANS-SERIF CAPITAL D +1D5D7 ; [.1616.0020.000B.1D5D7] # MATHEMATICAL SANS-SERIF BOLD CAPITAL D +1D60B ; [.1616.0020.000B.1D60B] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL D +1D63F ; [.1616.0020.000B.1D63F] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D +1D673 ; [.1616.0020.000B.1D673] # MATHEMATICAL MONOSPACE CAPITAL D +24B9 ; [.1616.0020.000C.24B9] # CIRCLED LATIN CAPITAL LETTER D +1F153 ; [.1616.0020.000C.1F153] # NEGATIVE CIRCLED LATIN CAPITAL LETTER D +1D48 ; [.1616.0020.0014.1D48] # MODIFIER LETTER SMALL D +1D30 ; [.1616.0020.001D.1D30] # MODIFIER LETTER CAPITAL D +1F133 ; [.1616.0020.001D.1F133] # SQUARED LATIN CAPITAL LETTER D +1F173 ; [.1616.0020.001D.1F173] # NEGATIVE SQUARED LATIN CAPITAL LETTER D +010F ; [.1616.0020.0002.0064][.0000.0041.0002.030C] # LATIN SMALL LETTER D WITH CARON +010E ; [.1616.0020.0008.0044][.0000.0041.0002.030C] # LATIN CAPITAL LETTER D WITH CARON +1E0B ; [.1616.0020.0002.0064][.0000.0052.0002.0307] # LATIN SMALL LETTER D WITH DOT ABOVE +1E0A ; [.1616.0020.0008.0044][.0000.0052.0002.0307] # LATIN CAPITAL LETTER D WITH DOT ABOVE +1E11 ; [.1616.0020.0002.0064][.0000.0056.0002.0327] # LATIN SMALL LETTER D WITH CEDILLA +1E10 ; [.1616.0020.0008.0044][.0000.0056.0002.0327] # LATIN CAPITAL LETTER D WITH CEDILLA +1E0D ; [.1616.0020.0002.0064][.0000.0070.0002.0323] # LATIN SMALL LETTER D WITH DOT BELOW +1E0C ; [.1616.0020.0008.0044][.0000.0070.0002.0323] # LATIN CAPITAL LETTER D WITH DOT BELOW +1E13 ; [.1616.0020.0002.0064][.0000.0078.0002.032D] # LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW +1E12 ; [.1616.0020.0008.0044][.0000.0078.0002.032D] # LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW +1E0F ; [.1616.0020.0002.0064][.0000.007B.0002.0331] # LATIN SMALL LETTER D WITH LINE BELOW +1E0E ; [.1616.0020.0008.0044][.0000.007B.0002.0331] # LATIN CAPITAL LETTER D WITH LINE BELOW +0111 ; [.1616.0020.0002.0064][.0000.007D.0002.0335] # LATIN SMALL LETTER D WITH STROKE +0110 ; [.1616.0020.0008.0044][.0000.007D.0002.0335] # LATIN CAPITAL LETTER D WITH STROKE +00F0 ; [.1616.0020.0004.00F0][.0000.0139.0004.00F0] # LATIN SMALL LETTER ETH +1DD9 ; [.1616.0020.0004.1DD9][.0000.0139.0004.1DD9] # COMBINING LATIN SMALL LETTER ETH +00D0 ; [.1616.0020.000A.00D0][.0000.0139.0004.00D0] # LATIN CAPITAL LETTER ETH +1D9E ; [.1616.0020.0014.1D9E][.0000.0139.0014.1D9E] # MODIFIER LETTER SMALL ETH +1DD8 ; [.1616.0020.0004.1DD8][.0000.013A.0004.1DD8] # COMBINING LATIN SMALL LETTER INSULAR D +A77A ; [.1616.0020.0004.A77A][.0000.013A.0004.A77A] # LATIN SMALL LETTER INSULAR D +A779 ; [.1616.0020.000A.A779][.0000.013A.0004.A779] # LATIN CAPITAL LETTER INSULAR D +3372 ; [.1616.0020.001C.3372][.15D4.0020.001C.3372] # SQUARE DA +0238 ; [.1616.0020.0004.0238][.15EA.0020.0004.0238] # LATIN SMALL LETTER DB DIGRAPH +33C8 ; [.1616.0020.001C.33C8][.15EA.0020.001D.33C8] # SQUARE DB +1F190 ; [.1616.0020.001D.1F190][.16CB.0020.001D.1F190] # SQUARE DJ +3397 ; [.1616.0020.001C.3397][.16F6.0020.001C.3397] # SQUARE DL +3377 ; [.1616.0020.001C.3377][.1726.0020.001C.3377] # SQUARE DM +3378 ; [.1616.0020.001C.3378][.1726.0020.001C.3378][.15CC.0020.001F.3378] # SQUARE DM SQUARED +3379 ; [.1616.0020.001C.3379][.1726.0020.001C.3379][.15CD.0020.001F.3379] # SQUARE DM CUBED +01F3 ; [.1616.0020.0004.01F3][.187A.0020.0004.01F3] # LATIN SMALL LETTER DZ +02A3 ; [.1616.0020.0004.02A3][.187A.0020.0004.02A3] # LATIN SMALL LETTER DZ DIGRAPH +01F2 ; [.1616.0020.000A.01F2][.187A.0020.0004.01F2] # LATIN CAPITAL LETTER D WITH SMALL LETTER Z +01F1 ; [.1616.0020.000A.01F1][.187A.0020.000A.01F1] # LATIN CAPITAL LETTER DZ +01C6 ; [.1616.0020.0004.01C6][.187A.0020.0004.01C6][.0000.0041.001F.01C6] # LATIN SMALL LETTER DZ WITH CARON +01C5 ; [.1616.0020.000A.01C5][.187A.0020.0004.01C5][.0000.0041.001F.01C5] # LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON +01C4 ; [.1616.0020.000A.01C4][.187A.0020.000A.01C4][.0000.0041.001F.01C4] # LATIN CAPITAL LETTER DZ WITH CARON +02A5 ; [.1616.0020.0004.02A5][.188D.0020.0004.02A5] # LATIN SMALL LETTER DZ DIGRAPH WITH CURL +02A4 ; [.1616.0020.0004.02A4][.1897.0020.0004.02A4] # LATIN SMALL LETTER DEZH DIGRAPH +1D05 ; [.161A.0020.0002.1D05] # LATIN LETTER SMALL CAPITAL D +1D06 ; [.161B.0020.0002.1D06] # LATIN LETTER SMALL CAPITAL ETH +1D6D ; [.161C.0020.0002.1D6D] # LATIN SMALL LETTER D WITH MIDDLE TILDE +1D81 ; [.161D.0020.0002.1D81] # LATIN SMALL LETTER D WITH PALATAL HOOK +0256 ; [.161E.0020.0002.0256] # LATIN SMALL LETTER D WITH TAIL +0189 ; [.161E.0020.0008.0189] # LATIN CAPITAL LETTER AFRICAN D +0257 ; [.1622.0020.0002.0257] # LATIN SMALL LETTER D WITH HOOK +018A ; [.1622.0020.0008.018A] # LATIN CAPITAL LETTER D WITH HOOK +1D91 ; [.1626.0020.0002.1D91] # LATIN SMALL LETTER D WITH HOOK AND TAIL +018C ; [.1627.0020.0002.018C] # LATIN SMALL LETTER D WITH TOPBAR +018B ; [.1627.0020.0008.018B] # LATIN CAPITAL LETTER D WITH TOPBAR +0221 ; [.162B.0020.0002.0221] # LATIN SMALL LETTER D WITH CURL +A771 ; [.162F.0020.0002.A771] # LATIN SMALL LETTER DUM +1E9F ; [.1630.0020.0002.1E9F] # LATIN SMALL LETTER DELTA +0065 ; [.1631.0020.0002.0065] # LATIN SMALL LETTER E +FF45 ; [.1631.0020.0003.FF45] # FULLWIDTH LATIN SMALL LETTER E +0364 ; [.1631.0020.0004.0364] # COMBINING LATIN SMALL LETTER E +24A0 ; [*02FB.0020.0004.24A0][.1631.0020.0004.24A0][*02FC.0020.001F.24A0] # PARENTHESIZED LATIN SMALL LETTER E +212F ; [.1631.0020.0005.212F] # SCRIPT SMALL E +2147 ; [.1631.0020.0005.2147] # DOUBLE-STRUCK ITALIC SMALL E +1D41E ; [.1631.0020.0005.1D41E] # MATHEMATICAL BOLD SMALL E +1D452 ; [.1631.0020.0005.1D452] # MATHEMATICAL ITALIC SMALL E +1D486 ; [.1631.0020.0005.1D486] # MATHEMATICAL BOLD ITALIC SMALL E +1D4EE ; [.1631.0020.0005.1D4EE] # MATHEMATICAL BOLD SCRIPT SMALL E +1D522 ; [.1631.0020.0005.1D522] # MATHEMATICAL FRAKTUR SMALL E +1D556 ; [.1631.0020.0005.1D556] # MATHEMATICAL DOUBLE-STRUCK SMALL E +1D58A ; [.1631.0020.0005.1D58A] # MATHEMATICAL BOLD FRAKTUR SMALL E +1D5BE ; [.1631.0020.0005.1D5BE] # MATHEMATICAL SANS-SERIF SMALL E +1D5F2 ; [.1631.0020.0005.1D5F2] # MATHEMATICAL SANS-SERIF BOLD SMALL E +1D626 ; [.1631.0020.0005.1D626] # MATHEMATICAL SANS-SERIF ITALIC SMALL E +1D65A ; [.1631.0020.0005.1D65A] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E +1D68E ; [.1631.0020.0005.1D68E] # MATHEMATICAL MONOSPACE SMALL E +24D4 ; [.1631.0020.0006.24D4] # CIRCLED LATIN SMALL LETTER E +0045 ; [.1631.0020.0008.0045] # LATIN CAPITAL LETTER E +FF25 ; [.1631.0020.0009.FF25] # FULLWIDTH LATIN CAPITAL LETTER E +1F114 ; [*02FB.0020.0004.1F114][.1631.0020.000A.1F114][*02FC.0020.001F.1F114] # PARENTHESIZED LATIN CAPITAL LETTER E +1F1EA ; [.1631.0020.000A.1F1EA] # REGIONAL INDICATOR SYMBOL LETTER E +2130 ; [.1631.0020.000B.2130] # SCRIPT CAPITAL E +1D404 ; [.1631.0020.000B.1D404] # MATHEMATICAL BOLD CAPITAL E +1D438 ; [.1631.0020.000B.1D438] # MATHEMATICAL ITALIC CAPITAL E +1D46C ; [.1631.0020.000B.1D46C] # MATHEMATICAL BOLD ITALIC CAPITAL E +1D4D4 ; [.1631.0020.000B.1D4D4] # MATHEMATICAL BOLD SCRIPT CAPITAL E +1D508 ; [.1631.0020.000B.1D508] # MATHEMATICAL FRAKTUR CAPITAL E +1D53C ; [.1631.0020.000B.1D53C] # MATHEMATICAL DOUBLE-STRUCK CAPITAL E +1D570 ; [.1631.0020.000B.1D570] # MATHEMATICAL BOLD FRAKTUR CAPITAL E +1D5A4 ; [.1631.0020.000B.1D5A4] # MATHEMATICAL SANS-SERIF CAPITAL E +1D5D8 ; [.1631.0020.000B.1D5D8] # MATHEMATICAL SANS-SERIF BOLD CAPITAL E +1D60C ; [.1631.0020.000B.1D60C] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL E +1D640 ; [.1631.0020.000B.1D640] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E +1D674 ; [.1631.0020.000B.1D674] # MATHEMATICAL MONOSPACE CAPITAL E +24BA ; [.1631.0020.000C.24BA] # CIRCLED LATIN CAPITAL LETTER E +1F154 ; [.1631.0020.000C.1F154] # NEGATIVE CIRCLED LATIN CAPITAL LETTER E +1D49 ; [.1631.0020.0014.1D49] # MODIFIER LETTER SMALL E +2091 ; [.1631.0020.0015.2091] # LATIN SUBSCRIPT SMALL LETTER E +1D31 ; [.1631.0020.001D.1D31] # MODIFIER LETTER CAPITAL E +1F134 ; [.1631.0020.001D.1F134] # SQUARED LATIN CAPITAL LETTER E +1F174 ; [.1631.0020.001D.1F174] # NEGATIVE SQUARED LATIN CAPITAL LETTER E +00E9 ; [.1631.0020.0002.0065][.0000.0032.0002.0301] # LATIN SMALL LETTER E WITH ACUTE +00C9 ; [.1631.0020.0008.0045][.0000.0032.0002.0301] # LATIN CAPITAL LETTER E WITH ACUTE +00E8 ; [.1631.0020.0002.0065][.0000.0035.0002.0300] # LATIN SMALL LETTER E WITH GRAVE +00C8 ; [.1631.0020.0008.0045][.0000.0035.0002.0300] # LATIN CAPITAL LETTER E WITH GRAVE +0115 ; [.1631.0020.0002.0065][.0000.0037.0002.0306] # LATIN SMALL LETTER E WITH BREVE +0114 ; [.1631.0020.0008.0045][.0000.0037.0002.0306] # LATIN CAPITAL LETTER E WITH BREVE +00EA ; [.1631.0020.0002.0065][.0000.003C.0002.0302] # LATIN SMALL LETTER E WITH CIRCUMFLEX +00CA ; [.1631.0020.0008.0045][.0000.003C.0002.0302] # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +1EBF ; [.1631.0020.0002.0065][.0000.003C.0002.0302][.0000.0032.0002.0301] # LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE +1EBE ; [.1631.0020.0008.0045][.0000.003C.0002.0302][.0000.0032.0002.0301] # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE +1EC1 ; [.1631.0020.0002.0065][.0000.003C.0002.0302][.0000.0035.0002.0300] # LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE +1EC0 ; [.1631.0020.0008.0045][.0000.003C.0002.0302][.0000.0035.0002.0300] # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE +1EC5 ; [.1631.0020.0002.0065][.0000.003C.0002.0302][.0000.004E.0002.0303] # LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE +1EC4 ; [.1631.0020.0008.0045][.0000.003C.0002.0302][.0000.004E.0002.0303] # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE +1EC3 ; [.1631.0020.0002.0065][.0000.003C.0002.0302][.0000.0064.0002.0309] # LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +1EC2 ; [.1631.0020.0008.0045][.0000.003C.0002.0302][.0000.0064.0002.0309] # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +011B ; [.1631.0020.0002.0065][.0000.0041.0002.030C] # LATIN SMALL LETTER E WITH CARON +011A ; [.1631.0020.0008.0045][.0000.0041.0002.030C] # LATIN CAPITAL LETTER E WITH CARON +00EB ; [.1631.0020.0002.0065][.0000.0047.0002.0308] # LATIN SMALL LETTER E WITH DIAERESIS +00CB ; [.1631.0020.0008.0045][.0000.0047.0002.0308] # LATIN CAPITAL LETTER E WITH DIAERESIS +1EBD ; [.1631.0020.0002.0065][.0000.004E.0002.0303] # LATIN SMALL LETTER E WITH TILDE +1EBC ; [.1631.0020.0008.0045][.0000.004E.0002.0303] # LATIN CAPITAL LETTER E WITH TILDE +0117 ; [.1631.0020.0002.0065][.0000.0052.0002.0307] # LATIN SMALL LETTER E WITH DOT ABOVE +0116 ; [.1631.0020.0008.0045][.0000.0052.0002.0307] # LATIN CAPITAL LETTER E WITH DOT ABOVE +0229 ; [.1631.0020.0002.0065][.0000.0056.0002.0327] # LATIN SMALL LETTER E WITH CEDILLA +0228 ; [.1631.0020.0008.0045][.0000.0056.0002.0327] # LATIN CAPITAL LETTER E WITH CEDILLA +1E1D ; [.1631.0020.0002.0065][.0000.0056.0002.0327][.0000.0037.0002.0306] # LATIN SMALL LETTER E WITH CEDILLA AND BREVE +1E1C ; [.1631.0020.0008.0045][.0000.0056.0002.0327][.0000.0037.0002.0306] # LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE +0119 ; [.1631.0020.0002.0065][.0000.0059.0002.0328] # LATIN SMALL LETTER E WITH OGONEK +0118 ; [.1631.0020.0008.0045][.0000.0059.0002.0328] # LATIN CAPITAL LETTER E WITH OGONEK +0113 ; [.1631.0020.0002.0065][.0000.005B.0002.0304] # LATIN SMALL LETTER E WITH MACRON +0112 ; [.1631.0020.0008.0045][.0000.005B.0002.0304] # LATIN CAPITAL LETTER E WITH MACRON +1E17 ; [.1631.0020.0002.0065][.0000.005B.0002.0304][.0000.0032.0002.0301] # LATIN SMALL LETTER E WITH MACRON AND ACUTE +1E16 ; [.1631.0020.0008.0045][.0000.005B.0002.0304][.0000.0032.0002.0301] # LATIN CAPITAL LETTER E WITH MACRON AND ACUTE +1E15 ; [.1631.0020.0002.0065][.0000.005B.0002.0304][.0000.0035.0002.0300] # LATIN SMALL LETTER E WITH MACRON AND GRAVE +1E14 ; [.1631.0020.0008.0045][.0000.005B.0002.0304][.0000.0035.0002.0300] # LATIN CAPITAL LETTER E WITH MACRON AND GRAVE +1EBB ; [.1631.0020.0002.0065][.0000.0064.0002.0309] # LATIN SMALL LETTER E WITH HOOK ABOVE +1EBA ; [.1631.0020.0008.0045][.0000.0064.0002.0309] # LATIN CAPITAL LETTER E WITH HOOK ABOVE +0205 ; [.1631.0020.0002.0065][.0000.0065.0002.030F] # LATIN SMALL LETTER E WITH DOUBLE GRAVE +0204 ; [.1631.0020.0008.0045][.0000.0065.0002.030F] # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE +0207 ; [.1631.0020.0002.0065][.0000.0067.0002.0311] # LATIN SMALL LETTER E WITH INVERTED BREVE +0206 ; [.1631.0020.0008.0045][.0000.0067.0002.0311] # LATIN CAPITAL LETTER E WITH INVERTED BREVE +1EB9 ; [.1631.0020.0002.0065][.0000.0070.0002.0323] # LATIN SMALL LETTER E WITH DOT BELOW +1EB8 ; [.1631.0020.0008.0045][.0000.0070.0002.0323] # LATIN CAPITAL LETTER E WITH DOT BELOW +1EC7 ; [.1631.0020.0002.0065][.0000.0070.0002.0323][.0000.003C.0002.0302] # LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW +1EC6 ; [.1631.0020.0008.0045][.0000.0070.0002.0323][.0000.003C.0002.0302] # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW +1E19 ; [.1631.0020.0002.0065][.0000.0078.0002.032D] # LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW +1E18 ; [.1631.0020.0008.0045][.0000.0078.0002.032D] # LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW +1E1B ; [.1631.0020.0002.0065][.0000.007A.0002.0330] # LATIN SMALL LETTER E WITH TILDE BELOW +1E1A ; [.1631.0020.0008.0045][.0000.007A.0002.0330] # LATIN CAPITAL LETTER E WITH TILDE BELOW +32CD ; [.1631.0020.001C.32CD][.17A2.0020.001C.32CD][.1676.0020.001F.32CD] # SQUARE ERG +32CE ; [.1631.0020.001C.32CE][.1844.0020.001D.32CE] # SQUARE EV +1D07 ; [.1635.0020.0002.1D07] # LATIN LETTER SMALL CAPITAL E +0247 ; [.1636.0020.0002.0247] # LATIN SMALL LETTER E WITH STROKE +0246 ; [.1636.0020.0008.0246] # LATIN CAPITAL LETTER E WITH STROKE +1D92 ; [.163A.0020.0002.1D92] # LATIN SMALL LETTER E WITH RETROFLEX HOOK +2C78 ; [.163B.0020.0002.2C78] # LATIN SMALL LETTER E WITH NOTCH +01DD ; [.163C.0020.0002.01DD] # LATIN SMALL LETTER TURNED E +018E ; [.163C.0020.0008.018E] # LATIN CAPITAL LETTER REVERSED E +1D32 ; [.163C.0020.001D.1D32] # MODIFIER LETTER CAPITAL REVERSED E +2C7B ; [.1640.0020.0002.2C7B] # LATIN LETTER SMALL CAPITAL TURNED E +0259 ; [.1641.0020.0002.0259] # LATIN SMALL LETTER SCHWA +018F ; [.1641.0020.0008.018F] # LATIN CAPITAL LETTER SCHWA +1D4A ; [.1641.0020.0014.1D4A] # MODIFIER LETTER SMALL SCHWA +2094 ; [.1641.0020.0015.2094] # LATIN SUBSCRIPT SMALL LETTER SCHWA +1D95 ; [.1645.0020.0002.1D95] # LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK +025B ; [.1646.0020.0002.025B] # LATIN SMALL LETTER OPEN E +0190 ; [.1646.0020.0008.0190] # LATIN CAPITAL LETTER OPEN E +2107 ; [.1646.0020.000A.2107] # EULER CONSTANT +1D4B ; [.1646.0020.0014.1D4B] # MODIFIER LETTER SMALL OPEN E +1D93 ; [.164A.0020.0002.1D93] # LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK +0258 ; [.164B.0020.0002.0258] # LATIN SMALL LETTER REVERSED E +025A ; [.164F.0020.0002.025A] # LATIN SMALL LETTER SCHWA WITH HOOK +025C ; [.1653.0020.0002.025C] # LATIN SMALL LETTER REVERSED OPEN E +1D9F ; [.1653.0020.0014.1D9F] # MODIFIER LETTER SMALL REVERSED OPEN E +1D94 ; [.1657.0020.0002.1D94] # LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK +1D08 ; [.1658.0020.0002.1D08] # LATIN SMALL LETTER TURNED OPEN E +1D4C ; [.1658.0020.0014.1D4C] # MODIFIER LETTER SMALL TURNED OPEN E +025D ; [.1659.0020.0002.025D] # LATIN SMALL LETTER REVERSED OPEN E WITH HOOK +025E ; [.165D.0020.0002.025E] # LATIN SMALL LETTER CLOSED REVERSED OPEN E +029A ; [.1661.0020.0002.029A] # LATIN SMALL LETTER CLOSED OPEN E +0264 ; [.1665.0020.0002.0264] # LATIN SMALL LETTER RAMS HORN +0066 ; [.1669.0020.0002.0066] # LATIN SMALL LETTER F +FF46 ; [.1669.0020.0003.FF46] # FULLWIDTH LATIN SMALL LETTER F +24A1 ; [*02FB.0020.0004.24A1][.1669.0020.0004.24A1][*02FC.0020.001F.24A1] # PARENTHESIZED LATIN SMALL LETTER F +1D41F ; [.1669.0020.0005.1D41F] # MATHEMATICAL BOLD SMALL F +1D453 ; [.1669.0020.0005.1D453] # MATHEMATICAL ITALIC SMALL F +1D487 ; [.1669.0020.0005.1D487] # MATHEMATICAL BOLD ITALIC SMALL F +1D4BB ; [.1669.0020.0005.1D4BB] # MATHEMATICAL SCRIPT SMALL F +1D4EF ; [.1669.0020.0005.1D4EF] # MATHEMATICAL BOLD SCRIPT SMALL F +1D523 ; [.1669.0020.0005.1D523] # MATHEMATICAL FRAKTUR SMALL F +1D557 ; [.1669.0020.0005.1D557] # MATHEMATICAL DOUBLE-STRUCK SMALL F +1D58B ; [.1669.0020.0005.1D58B] # MATHEMATICAL BOLD FRAKTUR SMALL F +1D5BF ; [.1669.0020.0005.1D5BF] # MATHEMATICAL SANS-SERIF SMALL F +1D5F3 ; [.1669.0020.0005.1D5F3] # MATHEMATICAL SANS-SERIF BOLD SMALL F +1D627 ; [.1669.0020.0005.1D627] # MATHEMATICAL SANS-SERIF ITALIC SMALL F +1D65B ; [.1669.0020.0005.1D65B] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F +1D68F ; [.1669.0020.0005.1D68F] # MATHEMATICAL MONOSPACE SMALL F +24D5 ; [.1669.0020.0006.24D5] # CIRCLED LATIN SMALL LETTER F +0046 ; [.1669.0020.0008.0046] # LATIN CAPITAL LETTER F +FF26 ; [.1669.0020.0009.FF26] # FULLWIDTH LATIN CAPITAL LETTER F +2109 ; [*0482.0020.0004.2109][.1669.0020.000A.2109] # DEGREE FAHRENHEIT +1F115 ; [*02FB.0020.0004.1F115][.1669.0020.000A.1F115][*02FC.0020.001F.1F115] # PARENTHESIZED LATIN CAPITAL LETTER F +1F1EB ; [.1669.0020.000A.1F1EB] # REGIONAL INDICATOR SYMBOL LETTER F +2131 ; [.1669.0020.000B.2131] # SCRIPT CAPITAL F +1D405 ; [.1669.0020.000B.1D405] # MATHEMATICAL BOLD CAPITAL F +1D439 ; [.1669.0020.000B.1D439] # MATHEMATICAL ITALIC CAPITAL F +1D46D ; [.1669.0020.000B.1D46D] # MATHEMATICAL BOLD ITALIC CAPITAL F +1D4D5 ; [.1669.0020.000B.1D4D5] # MATHEMATICAL BOLD SCRIPT CAPITAL F +1D509 ; [.1669.0020.000B.1D509] # MATHEMATICAL FRAKTUR CAPITAL F +1D53D ; [.1669.0020.000B.1D53D] # MATHEMATICAL DOUBLE-STRUCK CAPITAL F +1D571 ; [.1669.0020.000B.1D571] # MATHEMATICAL BOLD FRAKTUR CAPITAL F +1D5A5 ; [.1669.0020.000B.1D5A5] # MATHEMATICAL SANS-SERIF CAPITAL F +1D5D9 ; [.1669.0020.000B.1D5D9] # MATHEMATICAL SANS-SERIF BOLD CAPITAL F +1D60D ; [.1669.0020.000B.1D60D] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL F +1D641 ; [.1669.0020.000B.1D641] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F +1D675 ; [.1669.0020.000B.1D675] # MATHEMATICAL MONOSPACE CAPITAL F +24BB ; [.1669.0020.000C.24BB] # CIRCLED LATIN CAPITAL LETTER F +1F155 ; [.1669.0020.000C.1F155] # NEGATIVE CIRCLED LATIN CAPITAL LETTER F +1DA0 ; [.1669.0020.0014.1DA0] # MODIFIER LETTER SMALL F +1F135 ; [.1669.0020.001D.1F135] # SQUARED LATIN CAPITAL LETTER F +1F175 ; [.1669.0020.001D.1F175] # NEGATIVE SQUARED LATIN CAPITAL LETTER F +1E1F ; [.1669.0020.0002.0066][.0000.0052.0002.0307] # LATIN SMALL LETTER F WITH DOT ABOVE +1E1E ; [.1669.0020.0008.0046][.0000.0052.0002.0307] # LATIN CAPITAL LETTER F WITH DOT ABOVE +A77C ; [.1669.0020.0004.A77C][.0000.013A.0004.A77C] # LATIN SMALL LETTER INSULAR F +A77B ; [.1669.0020.000A.A77B][.0000.013A.0004.A77B] # LATIN CAPITAL LETTER INSULAR F +213B ; [.1669.0020.000A.213B][.15D4.0020.000A.213B][.1860.0020.001F.213B] # FACSIMILE SIGN +FB00 ; [.1669.0020.0004.FB00][.1669.0020.0004.FB00] # LATIN SMALL LIGATURE FF +FB03 ; [.1669.0020.0004.FB03][.1669.0020.0004.FB03][.16B2.0020.001F.FB03] # LATIN SMALL LIGATURE FFI +FB04 ; [.1669.0020.0004.FB04][.1669.0020.0004.FB04][.16F6.0020.001F.FB04] # LATIN SMALL LIGATURE FFL +FB01 ; [.1669.0020.0004.FB01][.16B2.0020.0004.FB01] # LATIN SMALL LIGATURE FI +FB02 ; [.1669.0020.0004.FB02][.16F6.0020.0004.FB02] # LATIN SMALL LIGATURE FL +3399 ; [.1669.0020.001C.3399][.1726.0020.001C.3399] # SQUARE FM +02A9 ; [.1669.0020.0004.02A9][.1752.0020.0004.02A9] # LATIN SMALL LETTER FENG DIGRAPH +1F193 ; [.1669.0020.001D.1F193][.17A2.0020.001D.1F193][.1631.0020.001F.1F193][.1631.0020.001F.1F193] # SQUARED FREE +A730 ; [.166D.0020.0002.A730] # LATIN LETTER SMALL CAPITAL F +1D6E ; [.166E.0020.0002.1D6E] # LATIN SMALL LETTER F WITH MIDDLE TILDE +1D82 ; [.166F.0020.0002.1D82] # LATIN SMALL LETTER F WITH PALATAL HOOK +0192 ; [.1670.0020.0002.0192] # LATIN SMALL LETTER F WITH HOOK +0191 ; [.1670.0020.0008.0191] # LATIN CAPITAL LETTER F WITH HOOK +214E ; [.1674.0020.0002.214E] # TURNED SMALL F +2132 ; [.1674.0020.0008.2132] # TURNED CAPITAL F +A7FB ; [.1675.0020.0002.A7FB] # LATIN EPIGRAPHIC LETTER REVERSED F +0067 ; [.1676.0020.0002.0067] # LATIN SMALL LETTER G +FF47 ; [.1676.0020.0003.FF47] # FULLWIDTH LATIN SMALL LETTER G +1DDA ; [.1676.0020.0004.1DDA] # COMBINING LATIN SMALL LETTER G +24A2 ; [*02FB.0020.0004.24A2][.1676.0020.0004.24A2][*02FC.0020.001F.24A2] # PARENTHESIZED LATIN SMALL LETTER G +210A ; [.1676.0020.0005.210A] # SCRIPT SMALL G +1D420 ; [.1676.0020.0005.1D420] # MATHEMATICAL BOLD SMALL G +1D454 ; [.1676.0020.0005.1D454] # MATHEMATICAL ITALIC SMALL G +1D488 ; [.1676.0020.0005.1D488] # MATHEMATICAL BOLD ITALIC SMALL G +1D4F0 ; [.1676.0020.0005.1D4F0] # MATHEMATICAL BOLD SCRIPT SMALL G +1D524 ; [.1676.0020.0005.1D524] # MATHEMATICAL FRAKTUR SMALL G +1D558 ; [.1676.0020.0005.1D558] # MATHEMATICAL DOUBLE-STRUCK SMALL G +1D58C ; [.1676.0020.0005.1D58C] # MATHEMATICAL BOLD FRAKTUR SMALL G +1D5C0 ; [.1676.0020.0005.1D5C0] # MATHEMATICAL SANS-SERIF SMALL G +1D5F4 ; [.1676.0020.0005.1D5F4] # MATHEMATICAL SANS-SERIF BOLD SMALL G +1D628 ; [.1676.0020.0005.1D628] # MATHEMATICAL SANS-SERIF ITALIC SMALL G +1D65C ; [.1676.0020.0005.1D65C] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G +1D690 ; [.1676.0020.0005.1D690] # MATHEMATICAL MONOSPACE SMALL G +24D6 ; [.1676.0020.0006.24D6] # CIRCLED LATIN SMALL LETTER G +0047 ; [.1676.0020.0008.0047] # LATIN CAPITAL LETTER G +FF27 ; [.1676.0020.0009.FF27] # FULLWIDTH LATIN CAPITAL LETTER G +1F116 ; [*02FB.0020.0004.1F116][.1676.0020.000A.1F116][*02FC.0020.001F.1F116] # PARENTHESIZED LATIN CAPITAL LETTER G +1F1EC ; [.1676.0020.000A.1F1EC] # REGIONAL INDICATOR SYMBOL LETTER G +1D406 ; [.1676.0020.000B.1D406] # MATHEMATICAL BOLD CAPITAL G +1D43A ; [.1676.0020.000B.1D43A] # MATHEMATICAL ITALIC CAPITAL G +1D46E ; [.1676.0020.000B.1D46E] # MATHEMATICAL BOLD ITALIC CAPITAL G +1D4A2 ; [.1676.0020.000B.1D4A2] # MATHEMATICAL SCRIPT CAPITAL G +1D4D6 ; [.1676.0020.000B.1D4D6] # MATHEMATICAL BOLD SCRIPT CAPITAL G +1D50A ; [.1676.0020.000B.1D50A] # MATHEMATICAL FRAKTUR CAPITAL G +1D53E ; [.1676.0020.000B.1D53E] # MATHEMATICAL DOUBLE-STRUCK CAPITAL G +1D572 ; [.1676.0020.000B.1D572] # MATHEMATICAL BOLD FRAKTUR CAPITAL G +1D5A6 ; [.1676.0020.000B.1D5A6] # MATHEMATICAL SANS-SERIF CAPITAL G +1D5DA ; [.1676.0020.000B.1D5DA] # MATHEMATICAL SANS-SERIF BOLD CAPITAL G +1D60E ; [.1676.0020.000B.1D60E] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL G +1D642 ; [.1676.0020.000B.1D642] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G +1D676 ; [.1676.0020.000B.1D676] # MATHEMATICAL MONOSPACE CAPITAL G +24BC ; [.1676.0020.000C.24BC] # CIRCLED LATIN CAPITAL LETTER G +1F156 ; [.1676.0020.000C.1F156] # NEGATIVE CIRCLED LATIN CAPITAL LETTER G +1D4D ; [.1676.0020.0014.1D4D] # MODIFIER LETTER SMALL G +1D33 ; [.1676.0020.001D.1D33] # MODIFIER LETTER CAPITAL G +1F136 ; [.1676.0020.001D.1F136] # SQUARED LATIN CAPITAL LETTER G +1F176 ; [.1676.0020.001D.1F176] # NEGATIVE SQUARED LATIN CAPITAL LETTER G +01F5 ; [.1676.0020.0002.0067][.0000.0032.0002.0301] # LATIN SMALL LETTER G WITH ACUTE +01F4 ; [.1676.0020.0008.0047][.0000.0032.0002.0301] # LATIN CAPITAL LETTER G WITH ACUTE +011F ; [.1676.0020.0002.0067][.0000.0037.0002.0306] # LATIN SMALL LETTER G WITH BREVE +011E ; [.1676.0020.0008.0047][.0000.0037.0002.0306] # LATIN CAPITAL LETTER G WITH BREVE +011D ; [.1676.0020.0002.0067][.0000.003C.0002.0302] # LATIN SMALL LETTER G WITH CIRCUMFLEX +011C ; [.1676.0020.0008.0047][.0000.003C.0002.0302] # LATIN CAPITAL LETTER G WITH CIRCUMFLEX +01E7 ; [.1676.0020.0002.0067][.0000.0041.0002.030C] # LATIN SMALL LETTER G WITH CARON +01E6 ; [.1676.0020.0008.0047][.0000.0041.0002.030C] # LATIN CAPITAL LETTER G WITH CARON +0121 ; [.1676.0020.0002.0067][.0000.0052.0002.0307] # LATIN SMALL LETTER G WITH DOT ABOVE +0120 ; [.1676.0020.0008.0047][.0000.0052.0002.0307] # LATIN CAPITAL LETTER G WITH DOT ABOVE +0123 ; [.1676.0020.0002.0067][.0000.0056.0002.0327] # LATIN SMALL LETTER G WITH CEDILLA +0122 ; [.1676.0020.0008.0047][.0000.0056.0002.0327] # LATIN CAPITAL LETTER G WITH CEDILLA +1E21 ; [.1676.0020.0002.0067][.0000.005B.0002.0304] # LATIN SMALL LETTER G WITH MACRON +1E20 ; [.1676.0020.0008.0047][.0000.005B.0002.0304] # LATIN CAPITAL LETTER G WITH MACRON +A7A1 ; [.1676.0020.0004.A7A1][.0000.0061.0004.A7A1] # LATIN SMALL LETTER G WITH OBLIQUE STROKE +A7A0 ; [.1676.0020.000A.A7A0][.0000.0061.0004.A7A0] # LATIN CAPITAL LETTER G WITH OBLIQUE STROKE +1D79 ; [.1676.0020.0004.1D79][.0000.013A.0004.1D79] # LATIN SMALL LETTER INSULAR G +A77D ; [.1676.0020.000A.A77D][.0000.013A.0004.A77D] # LATIN CAPITAL LETTER INSULAR G +33FF ; [.1676.0020.001C.33FF][.15D4.0020.001C.33FF][.16F6.0020.001F.33FF] # SQUARE GAL +3387 ; [.1676.0020.001D.3387][.15EA.0020.001D.3387] # SQUARE GB +3393 ; [.1676.0020.001D.3393][.1699.0020.001D.3393][.187A.0020.001F.3393] # SQUARE GHZ +33AC ; [.1676.0020.001D.33AC][.177B.0020.001D.33AC][.15D4.0020.001F.33AC] # SQUARE GPA +33C9 ; [.1676.0020.001D.33C9][.1865.0020.001C.33C9] # SQUARE GY +0261 ; [.167A.0020.0002.0261] # LATIN SMALL LETTER SCRIPT G +1DA2 ; [.167A.0020.0014.1DA2] # MODIFIER LETTER SMALL SCRIPT G +0262 ; [.167E.0020.0002.0262] # LATIN LETTER SMALL CAPITAL G +1DDB ; [.167E.0020.0004.1DDB] # COMBINING LATIN LETTER SMALL CAPITAL G +01E5 ; [.1682.0020.0002.01E5] # LATIN SMALL LETTER G WITH STROKE +01E4 ; [.1682.0020.0008.01E4] # LATIN CAPITAL LETTER G WITH STROKE +1D83 ; [.1686.0020.0002.1D83] # LATIN SMALL LETTER G WITH PALATAL HOOK +0260 ; [.1687.0020.0002.0260] # LATIN SMALL LETTER G WITH HOOK +0193 ; [.1687.0020.0008.0193] # LATIN CAPITAL LETTER G WITH HOOK +029B ; [.168B.0020.0002.029B] # LATIN LETTER SMALL CAPITAL G WITH HOOK +1D77 ; [.168F.0020.0002.1D77] # LATIN SMALL LETTER TURNED G +A77F ; [.1690.0020.0002.A77F] # LATIN SMALL LETTER TURNED INSULAR G +A77E ; [.1690.0020.0008.A77E] # LATIN CAPITAL LETTER TURNED INSULAR G +0263 ; [.1691.0020.0002.0263] # LATIN SMALL LETTER GAMMA +0194 ; [.1691.0020.0008.0194] # LATIN CAPITAL LETTER GAMMA +02E0 ; [.1691.0020.0014.02E0] # MODIFIER LETTER SMALL GAMMA +01A3 ; [.1695.0020.0002.01A3] # LATIN SMALL LETTER OI +01A2 ; [.1695.0020.0008.01A2] # LATIN CAPITAL LETTER OI +0068 ; [.1699.0020.0002.0068] # LATIN SMALL LETTER H +FF48 ; [.1699.0020.0003.FF48] # FULLWIDTH LATIN SMALL LETTER H +036A ; [.1699.0020.0004.036A] # COMBINING LATIN SMALL LETTER H +24A3 ; [*02FB.0020.0004.24A3][.1699.0020.0004.24A3][*02FC.0020.001F.24A3] # PARENTHESIZED LATIN SMALL LETTER H +210E ; [.1699.0020.0005.210E] # PLANCK CONSTANT +1D421 ; [.1699.0020.0005.1D421] # MATHEMATICAL BOLD SMALL H +1D489 ; [.1699.0020.0005.1D489] # MATHEMATICAL BOLD ITALIC SMALL H +1D4BD ; [.1699.0020.0005.1D4BD] # MATHEMATICAL SCRIPT SMALL H +1D4F1 ; [.1699.0020.0005.1D4F1] # MATHEMATICAL BOLD SCRIPT SMALL H +1D525 ; [.1699.0020.0005.1D525] # MATHEMATICAL FRAKTUR SMALL H +1D559 ; [.1699.0020.0005.1D559] # MATHEMATICAL DOUBLE-STRUCK SMALL H +1D58D ; [.1699.0020.0005.1D58D] # MATHEMATICAL BOLD FRAKTUR SMALL H +1D5C1 ; [.1699.0020.0005.1D5C1] # MATHEMATICAL SANS-SERIF SMALL H +1D5F5 ; [.1699.0020.0005.1D5F5] # MATHEMATICAL SANS-SERIF BOLD SMALL H +1D629 ; [.1699.0020.0005.1D629] # MATHEMATICAL SANS-SERIF ITALIC SMALL H +1D65D ; [.1699.0020.0005.1D65D] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H +1D691 ; [.1699.0020.0005.1D691] # MATHEMATICAL MONOSPACE SMALL H +24D7 ; [.1699.0020.0006.24D7] # CIRCLED LATIN SMALL LETTER H +0048 ; [.1699.0020.0008.0048] # LATIN CAPITAL LETTER H +FF28 ; [.1699.0020.0009.FF28] # FULLWIDTH LATIN CAPITAL LETTER H +1F117 ; [*02FB.0020.0004.1F117][.1699.0020.000A.1F117][*02FC.0020.001F.1F117] # PARENTHESIZED LATIN CAPITAL LETTER H +1F1ED ; [.1699.0020.000A.1F1ED] # REGIONAL INDICATOR SYMBOL LETTER H +210B ; [.1699.0020.000B.210B] # SCRIPT CAPITAL H +210C ; [.1699.0020.000B.210C] # BLACK-LETTER CAPITAL H +210D ; [.1699.0020.000B.210D] # DOUBLE-STRUCK CAPITAL H +1D407 ; [.1699.0020.000B.1D407] # MATHEMATICAL BOLD CAPITAL H +1D43B ; [.1699.0020.000B.1D43B] # MATHEMATICAL ITALIC CAPITAL H +1D46F ; [.1699.0020.000B.1D46F] # MATHEMATICAL BOLD ITALIC CAPITAL H +1D4D7 ; [.1699.0020.000B.1D4D7] # MATHEMATICAL BOLD SCRIPT CAPITAL H +1D573 ; [.1699.0020.000B.1D573] # MATHEMATICAL BOLD FRAKTUR CAPITAL H +1D5A7 ; [.1699.0020.000B.1D5A7] # MATHEMATICAL SANS-SERIF CAPITAL H +1D5DB ; [.1699.0020.000B.1D5DB] # MATHEMATICAL SANS-SERIF BOLD CAPITAL H +1D60F ; [.1699.0020.000B.1D60F] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL H +1D643 ; [.1699.0020.000B.1D643] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H +1D677 ; [.1699.0020.000B.1D677] # MATHEMATICAL MONOSPACE CAPITAL H +24BD ; [.1699.0020.000C.24BD] # CIRCLED LATIN CAPITAL LETTER H +1F157 ; [.1699.0020.000C.1F157] # NEGATIVE CIRCLED LATIN CAPITAL LETTER H +02B0 ; [.1699.0020.0014.02B0] # MODIFIER LETTER SMALL H +2095 ; [.1699.0020.0015.2095] # LATIN SUBSCRIPT SMALL LETTER H +1D34 ; [.1699.0020.001D.1D34] # MODIFIER LETTER CAPITAL H +1F137 ; [.1699.0020.001D.1F137] # SQUARED LATIN CAPITAL LETTER H +1F177 ; [.1699.0020.001D.1F177] # NEGATIVE SQUARED LATIN CAPITAL LETTER H +0125 ; [.1699.0020.0002.0068][.0000.003C.0002.0302] # LATIN SMALL LETTER H WITH CIRCUMFLEX +0124 ; [.1699.0020.0008.0048][.0000.003C.0002.0302] # LATIN CAPITAL LETTER H WITH CIRCUMFLEX +021F ; [.1699.0020.0002.0068][.0000.0041.0002.030C] # LATIN SMALL LETTER H WITH CARON +021E ; [.1699.0020.0008.0048][.0000.0041.0002.030C] # LATIN CAPITAL LETTER H WITH CARON +1E27 ; [.1699.0020.0002.0068][.0000.0047.0002.0308] # LATIN SMALL LETTER H WITH DIAERESIS +1E26 ; [.1699.0020.0008.0048][.0000.0047.0002.0308] # LATIN CAPITAL LETTER H WITH DIAERESIS +1E23 ; [.1699.0020.0002.0068][.0000.0052.0002.0307] # LATIN SMALL LETTER H WITH DOT ABOVE +1E22 ; [.1699.0020.0008.0048][.0000.0052.0002.0307] # LATIN CAPITAL LETTER H WITH DOT ABOVE +1E29 ; [.1699.0020.0002.0068][.0000.0056.0002.0327] # LATIN SMALL LETTER H WITH CEDILLA +1E28 ; [.1699.0020.0008.0048][.0000.0056.0002.0327] # LATIN CAPITAL LETTER H WITH CEDILLA +1E25 ; [.1699.0020.0002.0068][.0000.0070.0002.0323] # LATIN SMALL LETTER H WITH DOT BELOW +1E24 ; [.1699.0020.0008.0048][.0000.0070.0002.0323] # LATIN CAPITAL LETTER H WITH DOT BELOW +1E2B ; [.1699.0020.0002.0068][.0000.0079.0002.032E] # LATIN SMALL LETTER H WITH BREVE BELOW +1E2A ; [.1699.0020.0008.0048][.0000.0079.0002.032E] # LATIN CAPITAL LETTER H WITH BREVE BELOW +1E96 ; [.1699.0020.0002.0068][.0000.007B.0002.0331] # LATIN SMALL LETTER H WITH LINE BELOW +0127 ; [.1699.0020.0002.0068][.0000.007D.0002.0335] # LATIN SMALL LETTER H WITH STROKE +210F ; [.1699.0020.0002.210F][.0000.007D.0002.210F] # PLANCK CONSTANT OVER TWO PI +0126 ; [.1699.0020.0008.0048][.0000.007D.0002.0335] # LATIN CAPITAL LETTER H WITH STROKE +A7F8 ; [.1699.0020.0014.A7F8][.0000.007D.0014.A7F8] # MODIFIER LETTER CAPITAL H WITH STROKE +33CA ; [.1699.0020.001C.33CA][.15D4.0020.001C.33CA] # SQUARE HA +32CC ; [.1699.0020.001D.32CC][.1676.0020.001C.32CC] # SQUARE HG +33CB ; [.1699.0020.001D.33CB][.177B.0020.001D.33CB] # SQUARE HP +3371 ; [.1699.0020.001C.3371][.177B.0020.001D.3371][.15D4.0020.001F.3371] # SQUARE HPA +1F14A ; [.1699.0020.001D.1F14A][.1844.0020.001D.1F14A] # SQUARED HV +3390 ; [.1699.0020.001D.3390][.187A.0020.001C.3390] # SQUARE HZ +029C ; [.169D.0020.0002.029C] # LATIN LETTER SMALL CAPITAL H +0195 ; [.16A1.0020.0002.0195] # LATIN SMALL LETTER HV +01F6 ; [.16A1.0020.0008.01F6] # LATIN CAPITAL LETTER HWAIR +0266 ; [.16A5.0020.0002.0266] # LATIN SMALL LETTER H WITH HOOK +A7AA ; [.16A5.0020.0008.A7AA] # LATIN CAPITAL LETTER H WITH HOOK +02B1 ; [.16A5.0020.0014.02B1] # MODIFIER LETTER SMALL H WITH HOOK +2C68 ; [.16A9.0020.0002.2C68] # LATIN SMALL LETTER H WITH DESCENDER +2C67 ; [.16A9.0020.0008.2C67] # LATIN CAPITAL LETTER H WITH DESCENDER +2C76 ; [.16AA.0020.0002.2C76] # LATIN SMALL LETTER HALF H +2C75 ; [.16AA.0020.0008.2C75] # LATIN CAPITAL LETTER HALF H +A727 ; [.16AB.0020.0002.A727] # LATIN SMALL LETTER HENG +A726 ; [.16AB.0020.0008.A726] # LATIN CAPITAL LETTER HENG +0267 ; [.16AC.0020.0002.0267] # LATIN SMALL LETTER HENG WITH HOOK +02BB ; [.16B0.0020.0002.02BB] # MODIFIER LETTER TURNED COMMA +02BD ; [.16B1.0020.0002.02BD] # MODIFIER LETTER REVERSED COMMA +0069 ; [.16B2.0020.0002.0069] # LATIN SMALL LETTER I +FF49 ; [.16B2.0020.0003.FF49] # FULLWIDTH LATIN SMALL LETTER I +0365 ; [.16B2.0020.0004.0365] # COMBINING LATIN SMALL LETTER I +2170 ; [.16B2.0020.0004.2170] # SMALL ROMAN NUMERAL ONE +24A4 ; [*02FB.0020.0004.24A4][.16B2.0020.0004.24A4][*02FC.0020.001F.24A4] # PARENTHESIZED LATIN SMALL LETTER I +2139 ; [.16B2.0020.0005.2139] # INFORMATION SOURCE +2148 ; [.16B2.0020.0005.2148] # DOUBLE-STRUCK ITALIC SMALL I +1D422 ; [.16B2.0020.0005.1D422] # MATHEMATICAL BOLD SMALL I +1D456 ; [.16B2.0020.0005.1D456] # MATHEMATICAL ITALIC SMALL I +1D48A ; [.16B2.0020.0005.1D48A] # MATHEMATICAL BOLD ITALIC SMALL I +1D4BE ; [.16B2.0020.0005.1D4BE] # MATHEMATICAL SCRIPT SMALL I +1D4F2 ; [.16B2.0020.0005.1D4F2] # MATHEMATICAL BOLD SCRIPT SMALL I +1D526 ; [.16B2.0020.0005.1D526] # MATHEMATICAL FRAKTUR SMALL I +1D55A ; [.16B2.0020.0005.1D55A] # MATHEMATICAL DOUBLE-STRUCK SMALL I +1D58E ; [.16B2.0020.0005.1D58E] # MATHEMATICAL BOLD FRAKTUR SMALL I +1D5C2 ; [.16B2.0020.0005.1D5C2] # MATHEMATICAL SANS-SERIF SMALL I +1D5F6 ; [.16B2.0020.0005.1D5F6] # MATHEMATICAL SANS-SERIF BOLD SMALL I +1D62A ; [.16B2.0020.0005.1D62A] # MATHEMATICAL SANS-SERIF ITALIC SMALL I +1D65E ; [.16B2.0020.0005.1D65E] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I +1D692 ; [.16B2.0020.0005.1D692] # MATHEMATICAL MONOSPACE SMALL I +24D8 ; [.16B2.0020.0006.24D8] # CIRCLED LATIN SMALL LETTER I +0049 ; [.16B2.0020.0008.0049] # LATIN CAPITAL LETTER I +FF29 ; [.16B2.0020.0009.FF29] # FULLWIDTH LATIN CAPITAL LETTER I +2160 ; [.16B2.0020.000A.2160] # ROMAN NUMERAL ONE +1F118 ; [*02FB.0020.0004.1F118][.16B2.0020.000A.1F118][*02FC.0020.001F.1F118] # PARENTHESIZED LATIN CAPITAL LETTER I +1F1EE ; [.16B2.0020.000A.1F1EE] # REGIONAL INDICATOR SYMBOL LETTER I +2110 ; [.16B2.0020.000B.2110] # SCRIPT CAPITAL I +2111 ; [.16B2.0020.000B.2111] # BLACK-LETTER CAPITAL I +1D408 ; [.16B2.0020.000B.1D408] # MATHEMATICAL BOLD CAPITAL I +1D43C ; [.16B2.0020.000B.1D43C] # MATHEMATICAL ITALIC CAPITAL I +1D470 ; [.16B2.0020.000B.1D470] # MATHEMATICAL BOLD ITALIC CAPITAL I +1D4D8 ; [.16B2.0020.000B.1D4D8] # MATHEMATICAL BOLD SCRIPT CAPITAL I +1D540 ; [.16B2.0020.000B.1D540] # MATHEMATICAL DOUBLE-STRUCK CAPITAL I +1D574 ; [.16B2.0020.000B.1D574] # MATHEMATICAL BOLD FRAKTUR CAPITAL I +1D5A8 ; [.16B2.0020.000B.1D5A8] # MATHEMATICAL SANS-SERIF CAPITAL I +1D5DC ; [.16B2.0020.000B.1D5DC] # MATHEMATICAL SANS-SERIF BOLD CAPITAL I +1D610 ; [.16B2.0020.000B.1D610] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL I +1D644 ; [.16B2.0020.000B.1D644] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I +1D678 ; [.16B2.0020.000B.1D678] # MATHEMATICAL MONOSPACE CAPITAL I +24BE ; [.16B2.0020.000C.24BE] # CIRCLED LATIN CAPITAL LETTER I +1F158 ; [.16B2.0020.000C.1F158] # NEGATIVE CIRCLED LATIN CAPITAL LETTER I +2071 ; [.16B2.0020.0014.2071] # SUPERSCRIPT LATIN SMALL LETTER I +1D62 ; [.16B2.0020.0015.1D62] # LATIN SUBSCRIPT SMALL LETTER I +1D35 ; [.16B2.0020.001D.1D35] # MODIFIER LETTER CAPITAL I +1F138 ; [.16B2.0020.001D.1F138] # SQUARED LATIN CAPITAL LETTER I +1F178 ; [.16B2.0020.001D.1F178] # NEGATIVE SQUARED LATIN CAPITAL LETTER I +00ED ; [.16B2.0020.0002.0069][.0000.0032.0002.0301] # LATIN SMALL LETTER I WITH ACUTE +00CD ; [.16B2.0020.0008.0049][.0000.0032.0002.0301] # LATIN CAPITAL LETTER I WITH ACUTE +00EC ; [.16B2.0020.0002.0069][.0000.0035.0002.0300] # LATIN SMALL LETTER I WITH GRAVE +00CC ; [.16B2.0020.0008.0049][.0000.0035.0002.0300] # LATIN CAPITAL LETTER I WITH GRAVE +012D ; [.16B2.0020.0002.0069][.0000.0037.0002.0306] # LATIN SMALL LETTER I WITH BREVE +012C ; [.16B2.0020.0008.0049][.0000.0037.0002.0306] # LATIN CAPITAL LETTER I WITH BREVE +00EE ; [.16B2.0020.0002.0069][.0000.003C.0002.0302] # LATIN SMALL LETTER I WITH CIRCUMFLEX +00CE ; [.16B2.0020.0008.0049][.0000.003C.0002.0302] # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +01D0 ; [.16B2.0020.0002.0069][.0000.0041.0002.030C] # LATIN SMALL LETTER I WITH CARON +01CF ; [.16B2.0020.0008.0049][.0000.0041.0002.030C] # LATIN CAPITAL LETTER I WITH CARON +00EF ; [.16B2.0020.0002.0069][.0000.0047.0002.0308] # LATIN SMALL LETTER I WITH DIAERESIS +00CF ; [.16B2.0020.0008.0049][.0000.0047.0002.0308] # LATIN CAPITAL LETTER I WITH DIAERESIS +1E2F ; [.16B2.0020.0002.0069][.0000.0047.0002.0308][.0000.0032.0002.0301] # LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE +1E2E ; [.16B2.0020.0008.0049][.0000.0047.0002.0308][.0000.0032.0002.0301] # LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE +0129 ; [.16B2.0020.0002.0069][.0000.004E.0002.0303] # LATIN SMALL LETTER I WITH TILDE +0128 ; [.16B2.0020.0008.0049][.0000.004E.0002.0303] # LATIN CAPITAL LETTER I WITH TILDE +0130 ; [.16B2.0020.0008.0049][.0000.0052.0002.0307] # LATIN CAPITAL LETTER I WITH DOT ABOVE +012F ; [.16B2.0020.0002.0069][.0000.0059.0002.0328] # LATIN SMALL LETTER I WITH OGONEK +012E ; [.16B2.0020.0008.0049][.0000.0059.0002.0328] # LATIN CAPITAL LETTER I WITH OGONEK +012B ; [.16B2.0020.0002.0069][.0000.005B.0002.0304] # LATIN SMALL LETTER I WITH MACRON +012A ; [.16B2.0020.0008.0049][.0000.005B.0002.0304] # LATIN CAPITAL LETTER I WITH MACRON +1EC9 ; [.16B2.0020.0002.0069][.0000.0064.0002.0309] # LATIN SMALL LETTER I WITH HOOK ABOVE +1EC8 ; [.16B2.0020.0008.0049][.0000.0064.0002.0309] # LATIN CAPITAL LETTER I WITH HOOK ABOVE +0209 ; [.16B2.0020.0002.0069][.0000.0065.0002.030F] # LATIN SMALL LETTER I WITH DOUBLE GRAVE +0208 ; [.16B2.0020.0008.0049][.0000.0065.0002.030F] # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE +020B ; [.16B2.0020.0002.0069][.0000.0067.0002.0311] # LATIN SMALL LETTER I WITH INVERTED BREVE +020A ; [.16B2.0020.0008.0049][.0000.0067.0002.0311] # LATIN CAPITAL LETTER I WITH INVERTED BREVE +1ECB ; [.16B2.0020.0002.0069][.0000.0070.0002.0323] # LATIN SMALL LETTER I WITH DOT BELOW +1ECA ; [.16B2.0020.0008.0049][.0000.0070.0002.0323] # LATIN CAPITAL LETTER I WITH DOT BELOW +1E2D ; [.16B2.0020.0002.0069][.0000.007A.0002.0330] # LATIN SMALL LETTER I WITH TILDE BELOW +1E2C ; [.16B2.0020.0008.0049][.0000.007A.0002.0330] # LATIN CAPITAL LETTER I WITH TILDE BELOW +1F18B ; [.16B2.0020.001D.1F18B][.1602.0020.001D.1F18B] # NEGATIVE SQUARED IC +1F194 ; [.16B2.0020.001D.1F194][.1616.0020.001D.1F194] # SQUARED ID +2171 ; [.16B2.0020.0004.2171][.16B2.0020.0004.2171] # SMALL ROMAN NUMERAL TWO +2161 ; [.16B2.0020.000A.2161][.16B2.0020.000A.2161] # ROMAN NUMERAL TWO +2172 ; [.16B2.0020.0004.2172][.16B2.0020.0004.2172][.16B2.0020.001F.2172] # SMALL ROMAN NUMERAL THREE +2162 ; [.16B2.0020.000A.2162][.16B2.0020.000A.2162][.16B2.0020.001F.2162] # ROMAN NUMERAL THREE +0133 ; [.16B2.0020.0004.0133][.16CB.0020.0004.0133] # LATIN SMALL LIGATURE IJ +0132 ; [.16B2.0020.000A.0132][.16CB.0020.000A.0132] # LATIN CAPITAL LIGATURE IJ +33CC ; [.16B2.0020.001C.33CC][.1734.0020.001C.33CC] # SQUARE IN +337A ; [.16B2.0020.001D.337A][.181B.0020.001D.337A] # SQUARE IU +2173 ; [.16B2.0020.0004.2173][.1844.0020.0004.2173] # SMALL ROMAN NUMERAL FOUR +2163 ; [.16B2.0020.000A.2163][.1844.0020.000A.2163] # ROMAN NUMERAL FOUR +2178 ; [.16B2.0020.0004.2178][.1860.0020.0004.2178] # SMALL ROMAN NUMERAL NINE +2168 ; [.16B2.0020.000A.2168][.1860.0020.000A.2168] # ROMAN NUMERAL NINE +0131 ; [.16B6.0020.0002.0131] # LATIN SMALL LETTER DOTLESS I +1D6A4 ; [.16B6.0020.0005.1D6A4] # MATHEMATICAL ITALIC SMALL DOTLESS I +026A ; [.16BA.0020.0002.026A] # LATIN LETTER SMALL CAPITAL I +1DA6 ; [.16BA.0020.0014.1DA6] # MODIFIER LETTER SMALL CAPITAL I +A7FE ; [.16BE.0020.0002.A7FE] # LATIN EPIGRAPHIC LETTER I LONGA +1D09 ; [.16BF.0020.0002.1D09] # LATIN SMALL LETTER TURNED I +1D4E ; [.16BF.0020.0014.1D4E] # MODIFIER LETTER SMALL TURNED I +0268 ; [.16C0.0020.0002.0268] # LATIN SMALL LETTER I WITH STROKE +0197 ; [.16C0.0020.0008.0197] # LATIN CAPITAL LETTER I WITH STROKE +1DA4 ; [.16C0.0020.0014.1DA4] # MODIFIER LETTER SMALL I WITH STROKE +1D7B ; [.16C4.0020.0002.1D7B] # LATIN SMALL CAPITAL LETTER I WITH STROKE +1DA7 ; [.16C4.0020.0014.1DA7] # MODIFIER LETTER SMALL CAPITAL I WITH STROKE +1D96 ; [.16C5.0020.0002.1D96] # LATIN SMALL LETTER I WITH RETROFLEX HOOK +0269 ; [.16C6.0020.0002.0269] # LATIN SMALL LETTER IOTA +0196 ; [.16C6.0020.0008.0196] # LATIN CAPITAL LETTER IOTA +1DA5 ; [.16C6.0020.0014.1DA5] # MODIFIER LETTER SMALL IOTA +1D7C ; [.16CA.0020.0002.1D7C] # LATIN SMALL LETTER IOTA WITH STROKE +006A ; [.16CB.0020.0002.006A] # LATIN SMALL LETTER J +FF4A ; [.16CB.0020.0003.FF4A] # FULLWIDTH LATIN SMALL LETTER J +24A5 ; [*02FB.0020.0004.24A5][.16CB.0020.0004.24A5][*02FC.0020.001F.24A5] # PARENTHESIZED LATIN SMALL LETTER J +2149 ; [.16CB.0020.0005.2149] # DOUBLE-STRUCK ITALIC SMALL J +1D423 ; [.16CB.0020.0005.1D423] # MATHEMATICAL BOLD SMALL J +1D457 ; [.16CB.0020.0005.1D457] # MATHEMATICAL ITALIC SMALL J +1D48B ; [.16CB.0020.0005.1D48B] # MATHEMATICAL BOLD ITALIC SMALL J +1D4BF ; [.16CB.0020.0005.1D4BF] # MATHEMATICAL SCRIPT SMALL J +1D4F3 ; [.16CB.0020.0005.1D4F3] # MATHEMATICAL BOLD SCRIPT SMALL J +1D527 ; [.16CB.0020.0005.1D527] # MATHEMATICAL FRAKTUR SMALL J +1D55B ; [.16CB.0020.0005.1D55B] # MATHEMATICAL DOUBLE-STRUCK SMALL J +1D58F ; [.16CB.0020.0005.1D58F] # MATHEMATICAL BOLD FRAKTUR SMALL J +1D5C3 ; [.16CB.0020.0005.1D5C3] # MATHEMATICAL SANS-SERIF SMALL J +1D5F7 ; [.16CB.0020.0005.1D5F7] # MATHEMATICAL SANS-SERIF BOLD SMALL J +1D62B ; [.16CB.0020.0005.1D62B] # MATHEMATICAL SANS-SERIF ITALIC SMALL J +1D65F ; [.16CB.0020.0005.1D65F] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J +1D693 ; [.16CB.0020.0005.1D693] # MATHEMATICAL MONOSPACE SMALL J +24D9 ; [.16CB.0020.0006.24D9] # CIRCLED LATIN SMALL LETTER J +004A ; [.16CB.0020.0008.004A] # LATIN CAPITAL LETTER J +FF2A ; [.16CB.0020.0009.FF2A] # FULLWIDTH LATIN CAPITAL LETTER J +1F119 ; [*02FB.0020.0004.1F119][.16CB.0020.000A.1F119][*02FC.0020.001F.1F119] # PARENTHESIZED LATIN CAPITAL LETTER J +1F1EF ; [.16CB.0020.000A.1F1EF] # REGIONAL INDICATOR SYMBOL LETTER J +1D409 ; [.16CB.0020.000B.1D409] # MATHEMATICAL BOLD CAPITAL J +1D43D ; [.16CB.0020.000B.1D43D] # MATHEMATICAL ITALIC CAPITAL J +1D471 ; [.16CB.0020.000B.1D471] # MATHEMATICAL BOLD ITALIC CAPITAL J +1D4A5 ; [.16CB.0020.000B.1D4A5] # MATHEMATICAL SCRIPT CAPITAL J +1D4D9 ; [.16CB.0020.000B.1D4D9] # MATHEMATICAL BOLD SCRIPT CAPITAL J +1D50D ; [.16CB.0020.000B.1D50D] # MATHEMATICAL FRAKTUR CAPITAL J +1D541 ; [.16CB.0020.000B.1D541] # MATHEMATICAL DOUBLE-STRUCK CAPITAL J +1D575 ; [.16CB.0020.000B.1D575] # MATHEMATICAL BOLD FRAKTUR CAPITAL J +1D5A9 ; [.16CB.0020.000B.1D5A9] # MATHEMATICAL SANS-SERIF CAPITAL J +1D5DD ; [.16CB.0020.000B.1D5DD] # MATHEMATICAL SANS-SERIF BOLD CAPITAL J +1D611 ; [.16CB.0020.000B.1D611] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL J +1D645 ; [.16CB.0020.000B.1D645] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J +1D679 ; [.16CB.0020.000B.1D679] # MATHEMATICAL MONOSPACE CAPITAL J +24BF ; [.16CB.0020.000C.24BF] # CIRCLED LATIN CAPITAL LETTER J +1F159 ; [.16CB.0020.000C.1F159] # NEGATIVE CIRCLED LATIN CAPITAL LETTER J +02B2 ; [.16CB.0020.0014.02B2] # MODIFIER LETTER SMALL J +2C7C ; [.16CB.0020.0015.2C7C] # LATIN SUBSCRIPT SMALL LETTER J +1D36 ; [.16CB.0020.001D.1D36] # MODIFIER LETTER CAPITAL J +1F139 ; [.16CB.0020.001D.1F139] # SQUARED LATIN CAPITAL LETTER J +1F179 ; [.16CB.0020.001D.1F179] # NEGATIVE SQUARED LATIN CAPITAL LETTER J +0135 ; [.16CB.0020.0002.006A][.0000.003C.0002.0302] # LATIN SMALL LETTER J WITH CIRCUMFLEX +0134 ; [.16CB.0020.0008.004A][.0000.003C.0002.0302] # LATIN CAPITAL LETTER J WITH CIRCUMFLEX +01F0 ; [.16CB.0020.0002.006A][.0000.0041.0002.030C] # LATIN SMALL LETTER J WITH CARON +0237 ; [.16CF.0020.0002.0237] # LATIN SMALL LETTER DOTLESS J +1D6A5 ; [.16CF.0020.0005.1D6A5] # MATHEMATICAL ITALIC SMALL DOTLESS J +1D0A ; [.16D3.0020.0002.1D0A] # LATIN LETTER SMALL CAPITAL J +0249 ; [.16D4.0020.0002.0249] # LATIN SMALL LETTER J WITH STROKE +0248 ; [.16D4.0020.0008.0248] # LATIN CAPITAL LETTER J WITH STROKE +029D ; [.16D8.0020.0002.029D] # LATIN SMALL LETTER J WITH CROSSED-TAIL +1DA8 ; [.16D8.0020.0014.1DA8] # MODIFIER LETTER SMALL J WITH CROSSED-TAIL +025F ; [.16DC.0020.0002.025F] # LATIN SMALL LETTER DOTLESS J WITH STROKE +1DA1 ; [.16DC.0020.0014.1DA1] # MODIFIER LETTER SMALL DOTLESS J WITH STROKE +0284 ; [.16E0.0020.0002.0284] # LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK +006B ; [.16E4.0020.0002.006B] # LATIN SMALL LETTER K +FF4B ; [.16E4.0020.0003.FF4B] # FULLWIDTH LATIN SMALL LETTER K +1DDC ; [.16E4.0020.0004.1DDC] # COMBINING LATIN SMALL LETTER K +24A6 ; [*02FB.0020.0004.24A6][.16E4.0020.0004.24A6][*02FC.0020.001F.24A6] # PARENTHESIZED LATIN SMALL LETTER K +1D424 ; [.16E4.0020.0005.1D424] # MATHEMATICAL BOLD SMALL K +1D458 ; [.16E4.0020.0005.1D458] # MATHEMATICAL ITALIC SMALL K +1D48C ; [.16E4.0020.0005.1D48C] # MATHEMATICAL BOLD ITALIC SMALL K +1D4C0 ; [.16E4.0020.0005.1D4C0] # MATHEMATICAL SCRIPT SMALL K +1D4F4 ; [.16E4.0020.0005.1D4F4] # MATHEMATICAL BOLD SCRIPT SMALL K +1D528 ; [.16E4.0020.0005.1D528] # MATHEMATICAL FRAKTUR SMALL K +1D55C ; [.16E4.0020.0005.1D55C] # MATHEMATICAL DOUBLE-STRUCK SMALL K +1D590 ; [.16E4.0020.0005.1D590] # MATHEMATICAL BOLD FRAKTUR SMALL K +1D5C4 ; [.16E4.0020.0005.1D5C4] # MATHEMATICAL SANS-SERIF SMALL K +1D5F8 ; [.16E4.0020.0005.1D5F8] # MATHEMATICAL SANS-SERIF BOLD SMALL K +1D62C ; [.16E4.0020.0005.1D62C] # MATHEMATICAL SANS-SERIF ITALIC SMALL K +1D660 ; [.16E4.0020.0005.1D660] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K +1D694 ; [.16E4.0020.0005.1D694] # MATHEMATICAL MONOSPACE SMALL K +24DA ; [.16E4.0020.0006.24DA] # CIRCLED LATIN SMALL LETTER K +004B ; [.16E4.0020.0008.004B] # LATIN CAPITAL LETTER K +212A ; [.16E4.0020.0008.212A] # KELVIN SIGN +FF2B ; [.16E4.0020.0009.FF2B] # FULLWIDTH LATIN CAPITAL LETTER K +1F11A ; [*02FB.0020.0004.1F11A][.16E4.0020.000A.1F11A][*02FC.0020.001F.1F11A] # PARENTHESIZED LATIN CAPITAL LETTER K +1F1F0 ; [.16E4.0020.000A.1F1F0] # REGIONAL INDICATOR SYMBOL LETTER K +1D40A ; [.16E4.0020.000B.1D40A] # MATHEMATICAL BOLD CAPITAL K +1D43E ; [.16E4.0020.000B.1D43E] # MATHEMATICAL ITALIC CAPITAL K +1D472 ; [.16E4.0020.000B.1D472] # MATHEMATICAL BOLD ITALIC CAPITAL K +1D4A6 ; [.16E4.0020.000B.1D4A6] # MATHEMATICAL SCRIPT CAPITAL K +1D4DA ; [.16E4.0020.000B.1D4DA] # MATHEMATICAL BOLD SCRIPT CAPITAL K +1D50E ; [.16E4.0020.000B.1D50E] # MATHEMATICAL FRAKTUR CAPITAL K +1D542 ; [.16E4.0020.000B.1D542] # MATHEMATICAL DOUBLE-STRUCK CAPITAL K +1D576 ; [.16E4.0020.000B.1D576] # MATHEMATICAL BOLD FRAKTUR CAPITAL K +1D5AA ; [.16E4.0020.000B.1D5AA] # MATHEMATICAL SANS-SERIF CAPITAL K +1D5DE ; [.16E4.0020.000B.1D5DE] # MATHEMATICAL SANS-SERIF BOLD CAPITAL K +1D612 ; [.16E4.0020.000B.1D612] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL K +1D646 ; [.16E4.0020.000B.1D646] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K +1D67A ; [.16E4.0020.000B.1D67A] # MATHEMATICAL MONOSPACE CAPITAL K +24C0 ; [.16E4.0020.000C.24C0] # CIRCLED LATIN CAPITAL LETTER K +1F15A ; [.16E4.0020.000C.1F15A] # NEGATIVE CIRCLED LATIN CAPITAL LETTER K +1D4F ; [.16E4.0020.0014.1D4F] # MODIFIER LETTER SMALL K +2096 ; [.16E4.0020.0015.2096] # LATIN SUBSCRIPT SMALL LETTER K +1D37 ; [.16E4.0020.001D.1D37] # MODIFIER LETTER CAPITAL K +1F13A ; [.16E4.0020.001D.1F13A] # SQUARED LATIN CAPITAL LETTER K +1F17A ; [.16E4.0020.001D.1F17A] # NEGATIVE SQUARED LATIN CAPITAL LETTER K +1E31 ; [.16E4.0020.0002.006B][.0000.0032.0002.0301] # LATIN SMALL LETTER K WITH ACUTE +1E30 ; [.16E4.0020.0008.004B][.0000.0032.0002.0301] # LATIN CAPITAL LETTER K WITH ACUTE +01E9 ; [.16E4.0020.0002.006B][.0000.0041.0002.030C] # LATIN SMALL LETTER K WITH CARON +01E8 ; [.16E4.0020.0008.004B][.0000.0041.0002.030C] # LATIN CAPITAL LETTER K WITH CARON +0137 ; [.16E4.0020.0002.006B][.0000.0056.0002.0327] # LATIN SMALL LETTER K WITH CEDILLA +0136 ; [.16E4.0020.0008.004B][.0000.0056.0002.0327] # LATIN CAPITAL LETTER K WITH CEDILLA +A7A3 ; [.16E4.0020.0004.A7A3][.0000.0061.0004.A7A3] # LATIN SMALL LETTER K WITH OBLIQUE STROKE +A7A2 ; [.16E4.0020.000A.A7A2][.0000.0061.0004.A7A2] # LATIN CAPITAL LETTER K WITH OBLIQUE STROKE +1E33 ; [.16E4.0020.0002.006B][.0000.0070.0002.0323] # LATIN SMALL LETTER K WITH DOT BELOW +1E32 ; [.16E4.0020.0008.004B][.0000.0070.0002.0323] # LATIN CAPITAL LETTER K WITH DOT BELOW +1E35 ; [.16E4.0020.0002.006B][.0000.007B.0002.0331] # LATIN SMALL LETTER K WITH LINE BELOW +1E34 ; [.16E4.0020.0008.004B][.0000.007B.0002.0331] # LATIN CAPITAL LETTER K WITH LINE BELOW +3384 ; [.16E4.0020.001C.3384][.15D4.0020.001D.3384] # SQUARE KA +3385 ; [.16E4.0020.001D.3385][.15EA.0020.001D.3385] # SQUARE KB +3389 ; [.16E4.0020.001C.3389][.1602.0020.001C.3389][.15D4.0020.001F.3389][.16F6.0020.001F.3389] # SQUARE KCAL +338F ; [.16E4.0020.001C.338F][.1676.0020.001C.338F] # SQUARE KG +3391 ; [.16E4.0020.001C.3391][.1699.0020.001D.3391][.187A.0020.001F.3391] # SQUARE KHZ +33CD ; [.16E4.0020.001D.33CD][.16E4.0020.001D.33CD] # SQUARE KK +3398 ; [.16E4.0020.001C.3398][.16F6.0020.001C.3398] # SQUARE KL +339E ; [.16E4.0020.001C.339E][.1726.0020.001C.339E] # SQUARE KM +33CE ; [.16E4.0020.001D.33CE][.1726.0020.001D.33CE] # SQUARE KM CAPITAL +33A2 ; [.16E4.0020.001C.33A2][.1726.0020.001C.33A2][.15CC.0020.001F.33A2] # SQUARE KM SQUARED +33A6 ; [.16E4.0020.001C.33A6][.1726.0020.001C.33A6][.15CD.0020.001F.33A6] # SQUARE KM CUBED +33AA ; [.16E4.0020.001C.33AA][.177B.0020.001D.33AA][.15D4.0020.001F.33AA] # SQUARE KPA +33CF ; [.16E4.0020.001C.33CF][.17FB.0020.001C.33CF] # SQUARE KT +33B8 ; [.16E4.0020.001C.33B8][.1844.0020.001D.33B8] # SQUARE KV +33BE ; [.16E4.0020.001C.33BE][.1856.0020.001D.33BE] # SQUARE KW +33C0 ; [.16E4.0020.001C.33C0][.1936.0020.001D.33C0] # SQUARE K OHM +1D0B ; [.16E8.0020.0002.1D0B] # LATIN LETTER SMALL CAPITAL K +1D84 ; [.16E9.0020.0002.1D84] # LATIN SMALL LETTER K WITH PALATAL HOOK +0199 ; [.16EA.0020.0002.0199] # LATIN SMALL LETTER K WITH HOOK +0198 ; [.16EA.0020.0008.0198] # LATIN CAPITAL LETTER K WITH HOOK +2C6A ; [.16EE.0020.0002.2C6A] # LATIN SMALL LETTER K WITH DESCENDER +2C69 ; [.16EE.0020.0008.2C69] # LATIN CAPITAL LETTER K WITH DESCENDER +A741 ; [.16EF.0020.0002.A741] # LATIN SMALL LETTER K WITH STROKE +A740 ; [.16EF.0020.0008.A740] # LATIN CAPITAL LETTER K WITH STROKE +A743 ; [.16F0.0020.0002.A743] # LATIN SMALL LETTER K WITH DIAGONAL STROKE +A742 ; [.16F0.0020.0008.A742] # LATIN CAPITAL LETTER K WITH DIAGONAL STROKE +A745 ; [.16F1.0020.0002.A745] # LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE +A744 ; [.16F1.0020.0008.A744] # LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE +029E ; [.16F2.0020.0002.029E] # LATIN SMALL LETTER TURNED K +006C ; [.16F6.0020.0002.006C] # LATIN SMALL LETTER L +FF4C ; [.16F6.0020.0003.FF4C] # FULLWIDTH LATIN SMALL LETTER L +1DDD ; [.16F6.0020.0004.1DDD] # COMBINING LATIN SMALL LETTER L +217C ; [.16F6.0020.0004.217C] # SMALL ROMAN NUMERAL FIFTY +24A7 ; [*02FB.0020.0004.24A7][.16F6.0020.0004.24A7][*02FC.0020.001F.24A7] # PARENTHESIZED LATIN SMALL LETTER L +2113 ; [.16F6.0020.0005.2113] # SCRIPT SMALL L +1D425 ; [.16F6.0020.0005.1D425] # MATHEMATICAL BOLD SMALL L +1D459 ; [.16F6.0020.0005.1D459] # MATHEMATICAL ITALIC SMALL L +1D48D ; [.16F6.0020.0005.1D48D] # MATHEMATICAL BOLD ITALIC SMALL L +1D4C1 ; [.16F6.0020.0005.1D4C1] # MATHEMATICAL SCRIPT SMALL L +1D4F5 ; [.16F6.0020.0005.1D4F5] # MATHEMATICAL BOLD SCRIPT SMALL L +1D529 ; [.16F6.0020.0005.1D529] # MATHEMATICAL FRAKTUR SMALL L +1D55D ; [.16F6.0020.0005.1D55D] # MATHEMATICAL DOUBLE-STRUCK SMALL L +1D591 ; [.16F6.0020.0005.1D591] # MATHEMATICAL BOLD FRAKTUR SMALL L +1D5C5 ; [.16F6.0020.0005.1D5C5] # MATHEMATICAL SANS-SERIF SMALL L +1D5F9 ; [.16F6.0020.0005.1D5F9] # MATHEMATICAL SANS-SERIF BOLD SMALL L +1D62D ; [.16F6.0020.0005.1D62D] # MATHEMATICAL SANS-SERIF ITALIC SMALL L +1D661 ; [.16F6.0020.0005.1D661] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L +1D695 ; [.16F6.0020.0005.1D695] # MATHEMATICAL MONOSPACE SMALL L +24DB ; [.16F6.0020.0006.24DB] # CIRCLED LATIN SMALL LETTER L +004C ; [.16F6.0020.0008.004C] # LATIN CAPITAL LETTER L +FF2C ; [.16F6.0020.0009.FF2C] # FULLWIDTH LATIN CAPITAL LETTER L +216C ; [.16F6.0020.000A.216C] # ROMAN NUMERAL FIFTY +1F11B ; [*02FB.0020.0004.1F11B][.16F6.0020.000A.1F11B][*02FC.0020.001F.1F11B] # PARENTHESIZED LATIN CAPITAL LETTER L +1F1F1 ; [.16F6.0020.000A.1F1F1] # REGIONAL INDICATOR SYMBOL LETTER L +2112 ; [.16F6.0020.000B.2112] # SCRIPT CAPITAL L +1D40B ; [.16F6.0020.000B.1D40B] # MATHEMATICAL BOLD CAPITAL L +1D43F ; [.16F6.0020.000B.1D43F] # MATHEMATICAL ITALIC CAPITAL L +1D473 ; [.16F6.0020.000B.1D473] # MATHEMATICAL BOLD ITALIC CAPITAL L +1D4DB ; [.16F6.0020.000B.1D4DB] # MATHEMATICAL BOLD SCRIPT CAPITAL L +1D50F ; [.16F6.0020.000B.1D50F] # MATHEMATICAL FRAKTUR CAPITAL L +1D543 ; [.16F6.0020.000B.1D543] # MATHEMATICAL DOUBLE-STRUCK CAPITAL L +1D577 ; [.16F6.0020.000B.1D577] # MATHEMATICAL BOLD FRAKTUR CAPITAL L +1D5AB ; [.16F6.0020.000B.1D5AB] # MATHEMATICAL SANS-SERIF CAPITAL L +1D5DF ; [.16F6.0020.000B.1D5DF] # MATHEMATICAL SANS-SERIF BOLD CAPITAL L +1D613 ; [.16F6.0020.000B.1D613] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL L +1D647 ; [.16F6.0020.000B.1D647] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L +1D67B ; [.16F6.0020.000B.1D67B] # MATHEMATICAL MONOSPACE CAPITAL L +24C1 ; [.16F6.0020.000C.24C1] # CIRCLED LATIN CAPITAL LETTER L +1F15B ; [.16F6.0020.000C.1F15B] # NEGATIVE CIRCLED LATIN CAPITAL LETTER L +02E1 ; [.16F6.0020.0014.02E1] # MODIFIER LETTER SMALL L +2097 ; [.16F6.0020.0015.2097] # LATIN SUBSCRIPT SMALL LETTER L +1D38 ; [.16F6.0020.001D.1D38] # MODIFIER LETTER CAPITAL L +1F13B ; [.16F6.0020.001D.1F13B] # SQUARED LATIN CAPITAL LETTER L +1F17B ; [.16F6.0020.001D.1F17B] # NEGATIVE SQUARED LATIN CAPITAL LETTER L +013A ; [.16F6.0020.0002.006C][.0000.0032.0002.0301] # LATIN SMALL LETTER L WITH ACUTE +0139 ; [.16F6.0020.0008.004C][.0000.0032.0002.0301] # LATIN CAPITAL LETTER L WITH ACUTE +013E ; [.16F6.0020.0002.006C][.0000.0041.0002.030C] # LATIN SMALL LETTER L WITH CARON +013D ; [.16F6.0020.0008.004C][.0000.0041.0002.030C] # LATIN CAPITAL LETTER L WITH CARON +013C ; [.16F6.0020.0002.006C][.0000.0056.0002.0327] # LATIN SMALL LETTER L WITH CEDILLA +013B ; [.16F6.0020.0008.004C][.0000.0056.0002.0327] # LATIN CAPITAL LETTER L WITH CEDILLA +1E37 ; [.16F6.0020.0002.006C][.0000.0070.0002.0323] # LATIN SMALL LETTER L WITH DOT BELOW +1E36 ; [.16F6.0020.0008.004C][.0000.0070.0002.0323] # LATIN CAPITAL LETTER L WITH DOT BELOW +1E39 ; [.16F6.0020.0002.006C][.0000.0070.0002.0323][.0000.005B.0002.0304] # LATIN SMALL LETTER L WITH DOT BELOW AND MACRON +1E38 ; [.16F6.0020.0008.004C][.0000.0070.0002.0323][.0000.005B.0002.0304] # LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON +1E3D ; [.16F6.0020.0002.006C][.0000.0078.0002.032D] # LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW +1E3C ; [.16F6.0020.0008.004C][.0000.0078.0002.032D] # LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW +1E3B ; [.16F6.0020.0002.006C][.0000.007B.0002.0331] # LATIN SMALL LETTER L WITH LINE BELOW +1E3A ; [.16F6.0020.0008.004C][.0000.007B.0002.0331] # LATIN CAPITAL LETTER L WITH LINE BELOW +0142 ; [.16F6.0020.0002.006C][.0000.007D.0002.0335] # LATIN SMALL LETTER L WITH STROKE +0141 ; [.16F6.0020.0008.004C][.0000.007D.0002.0335] # LATIN CAPITAL LETTER L WITH STROKE +0140 ; [.16F6.0020.0002.0140][.0000.0139.0002.0140] # LATIN SMALL LETTER L WITH MIDDLE DOT +006C 00B7 ; [.16F6.0020.0002.0140][.0000.0139.0002.0140] # LATIN SMALL LETTER L WITH MIDDLE DOT +006C 0387 ; [.16F6.0020.0002.0140][.0000.0139.0002.0140] # LATIN SMALL LETTER L WITH MIDDLE DOT +013F ; [.16F6.0020.0008.013F][.0000.0139.0002.013F] # LATIN CAPITAL LETTER L WITH MIDDLE DOT +004C 00B7 ; [.16F6.0020.0008.013F][.0000.0139.0002.013F] # LATIN CAPITAL LETTER L WITH MIDDLE DOT +004C 0387 ; [.16F6.0020.0008.013F][.0000.0139.0002.013F] # LATIN CAPITAL LETTER L WITH MIDDLE DOT +01C9 ; [.16F6.0020.0004.01C9][.16CB.0020.0004.01C9] # LATIN SMALL LETTER LJ +01C8 ; [.16F6.0020.000A.01C8][.16CB.0020.0004.01C8] # LATIN CAPITAL LETTER L WITH SMALL LETTER J +01C7 ; [.16F6.0020.000A.01C7][.16CB.0020.000A.01C7] # LATIN CAPITAL LETTER LJ +1EFB ; [.16F6.0020.0004.1EFB][.16F6.0020.0004.1EFB] # LATIN SMALL LETTER MIDDLE-WELSH LL +1EFA ; [.16F6.0020.000A.1EFA][.16F6.0020.000A.1EFA] # LATIN CAPITAL LETTER MIDDLE-WELSH LL +33D0 ; [.16F6.0020.001C.33D0][.1726.0020.001C.33D0] # SQUARE LM +33D1 ; [.16F6.0020.001C.33D1][.1734.0020.001C.33D1] # SQUARE LN +33D2 ; [.16F6.0020.001C.33D2][.1756.0020.001C.33D2][.1676.0020.001F.33D2] # SQUARE LOG +02AA ; [.16F6.0020.0004.02AA][.17D8.0020.0004.02AA] # LATIN SMALL LETTER LS DIGRAPH +32CF ; [.16F6.0020.001D.32CF][.17FB.0020.001D.32CF][.1616.0020.001F.32CF] # LIMITED LIABILITY SIGN +33D3 ; [.16F6.0020.001C.33D3][.1860.0020.001C.33D3] # SQUARE LX +02AB ; [.16F6.0020.0004.02AB][.187A.0020.0004.02AB] # LATIN SMALL LETTER LZ DIGRAPH +029F ; [.16FA.0020.0002.029F] # LATIN LETTER SMALL CAPITAL L +1DDE ; [.16FA.0020.0004.1DDE] # COMBINING LATIN LETTER SMALL CAPITAL L +1DAB ; [.16FA.0020.0014.1DAB] # MODIFIER LETTER SMALL CAPITAL L +A747 ; [.16FE.0020.0002.A747] # LATIN SMALL LETTER BROKEN L +A746 ; [.16FE.0020.0008.A746] # LATIN CAPITAL LETTER BROKEN L +1D0C ; [.16FF.0020.0002.1D0C] # LATIN LETTER SMALL CAPITAL L WITH STROKE +A749 ; [.1700.0020.0002.A749] # LATIN SMALL LETTER L WITH HIGH STROKE +A748 ; [.1700.0020.0008.A748] # LATIN CAPITAL LETTER L WITH HIGH STROKE +019A ; [.1701.0020.0002.019A] # LATIN SMALL LETTER L WITH BAR +023D ; [.1701.0020.0008.023D] # LATIN CAPITAL LETTER L WITH BAR +2C61 ; [.1705.0020.0002.2C61] # LATIN SMALL LETTER L WITH DOUBLE BAR +2C60 ; [.1705.0020.0008.2C60] # LATIN CAPITAL LETTER L WITH DOUBLE BAR +026B ; [.1706.0020.0002.026B] # LATIN SMALL LETTER L WITH MIDDLE TILDE +2C62 ; [.1706.0020.0008.2C62] # LATIN CAPITAL LETTER L WITH MIDDLE TILDE +026C ; [.170A.0020.0002.026C] # LATIN SMALL LETTER L WITH BELT +1D85 ; [.170E.0020.0002.1D85] # LATIN SMALL LETTER L WITH PALATAL HOOK +1DAA ; [.170E.0020.0014.1DAA] # MODIFIER LETTER SMALL L WITH PALATAL HOOK +026D ; [.170F.0020.0002.026D] # LATIN SMALL LETTER L WITH RETROFLEX HOOK +1DA9 ; [.170F.0020.0014.1DA9] # MODIFIER LETTER SMALL L WITH RETROFLEX HOOK +A78E ; [.1713.0020.0002.A78E] # LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT +0234 ; [.1714.0020.0002.0234] # LATIN SMALL LETTER L WITH CURL +A772 ; [.1718.0020.0002.A772] # LATIN SMALL LETTER LUM +026E ; [.1719.0020.0002.026E] # LATIN SMALL LETTER LEZH +A781 ; [.171D.0020.0002.A781] # LATIN SMALL LETTER TURNED L +A780 ; [.171D.0020.0008.A780] # LATIN CAPITAL LETTER TURNED L +019B ; [.171E.0020.0002.019B] # LATIN SMALL LETTER LAMBDA WITH STROKE +028E ; [.1722.0020.0002.028E] # LATIN SMALL LETTER TURNED Y +006D ; [.1726.0020.0002.006D] # LATIN SMALL LETTER M +FF4D ; [.1726.0020.0003.FF4D] # FULLWIDTH LATIN SMALL LETTER M +036B ; [.1726.0020.0004.036B] # COMBINING LATIN SMALL LETTER M +217F ; [.1726.0020.0004.217F] # SMALL ROMAN NUMERAL ONE THOUSAND +24A8 ; [*02FB.0020.0004.24A8][.1726.0020.0004.24A8][*02FC.0020.001F.24A8] # PARENTHESIZED LATIN SMALL LETTER M +1D426 ; [.1726.0020.0005.1D426] # MATHEMATICAL BOLD SMALL M +1D45A ; [.1726.0020.0005.1D45A] # MATHEMATICAL ITALIC SMALL M +1D48E ; [.1726.0020.0005.1D48E] # MATHEMATICAL BOLD ITALIC SMALL M +1D4C2 ; [.1726.0020.0005.1D4C2] # MATHEMATICAL SCRIPT SMALL M +1D4F6 ; [.1726.0020.0005.1D4F6] # MATHEMATICAL BOLD SCRIPT SMALL M +1D52A ; [.1726.0020.0005.1D52A] # MATHEMATICAL FRAKTUR SMALL M +1D55E ; [.1726.0020.0005.1D55E] # MATHEMATICAL DOUBLE-STRUCK SMALL M +1D592 ; [.1726.0020.0005.1D592] # MATHEMATICAL BOLD FRAKTUR SMALL M +1D5C6 ; [.1726.0020.0005.1D5C6] # MATHEMATICAL SANS-SERIF SMALL M +1D5FA ; [.1726.0020.0005.1D5FA] # MATHEMATICAL SANS-SERIF BOLD SMALL M +1D62E ; [.1726.0020.0005.1D62E] # MATHEMATICAL SANS-SERIF ITALIC SMALL M +1D662 ; [.1726.0020.0005.1D662] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M +1D696 ; [.1726.0020.0005.1D696] # MATHEMATICAL MONOSPACE SMALL M +24DC ; [.1726.0020.0006.24DC] # CIRCLED LATIN SMALL LETTER M +004D ; [.1726.0020.0008.004D] # LATIN CAPITAL LETTER M +FF2D ; [.1726.0020.0009.FF2D] # FULLWIDTH LATIN CAPITAL LETTER M +216F ; [.1726.0020.000A.216F] # ROMAN NUMERAL ONE THOUSAND +1F11C ; [*02FB.0020.0004.1F11C][.1726.0020.000A.1F11C][*02FC.0020.001F.1F11C] # PARENTHESIZED LATIN CAPITAL LETTER M +1F1F2 ; [.1726.0020.000A.1F1F2] # REGIONAL INDICATOR SYMBOL LETTER M +2133 ; [.1726.0020.000B.2133] # SCRIPT CAPITAL M +1D40C ; [.1726.0020.000B.1D40C] # MATHEMATICAL BOLD CAPITAL M +1D440 ; [.1726.0020.000B.1D440] # MATHEMATICAL ITALIC CAPITAL M +1D474 ; [.1726.0020.000B.1D474] # MATHEMATICAL BOLD ITALIC CAPITAL M +1D4DC ; [.1726.0020.000B.1D4DC] # MATHEMATICAL BOLD SCRIPT CAPITAL M +1D510 ; [.1726.0020.000B.1D510] # MATHEMATICAL FRAKTUR CAPITAL M +1D544 ; [.1726.0020.000B.1D544] # MATHEMATICAL DOUBLE-STRUCK CAPITAL M +1D578 ; [.1726.0020.000B.1D578] # MATHEMATICAL BOLD FRAKTUR CAPITAL M +1D5AC ; [.1726.0020.000B.1D5AC] # MATHEMATICAL SANS-SERIF CAPITAL M +1D5E0 ; [.1726.0020.000B.1D5E0] # MATHEMATICAL SANS-SERIF BOLD CAPITAL M +1D614 ; [.1726.0020.000B.1D614] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL M +1D648 ; [.1726.0020.000B.1D648] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M +1D67C ; [.1726.0020.000B.1D67C] # MATHEMATICAL MONOSPACE CAPITAL M +24C2 ; [.1726.0020.000C.24C2] # CIRCLED LATIN CAPITAL LETTER M +1F15C ; [.1726.0020.000C.1F15C] # NEGATIVE CIRCLED LATIN CAPITAL LETTER M +1D50 ; [.1726.0020.0014.1D50] # MODIFIER LETTER SMALL M +2098 ; [.1726.0020.0015.2098] # LATIN SUBSCRIPT SMALL LETTER M +1D39 ; [.1726.0020.001D.1D39] # MODIFIER LETTER CAPITAL M +1F13C ; [.1726.0020.001D.1F13C] # SQUARED LATIN CAPITAL LETTER M +1F17C ; [.1726.0020.001D.1F17C] # NEGATIVE SQUARED LATIN CAPITAL LETTER M +1E3F ; [.1726.0020.0002.006D][.0000.0032.0002.0301] # LATIN SMALL LETTER M WITH ACUTE +1E3E ; [.1726.0020.0008.004D][.0000.0032.0002.0301] # LATIN CAPITAL LETTER M WITH ACUTE +1E41 ; [.1726.0020.0002.006D][.0000.0052.0002.0307] # LATIN SMALL LETTER M WITH DOT ABOVE +1E40 ; [.1726.0020.0008.004D][.0000.0052.0002.0307] # LATIN CAPITAL LETTER M WITH DOT ABOVE +1E43 ; [.1726.0020.0002.006D][.0000.0070.0002.0323] # LATIN SMALL LETTER M WITH DOT BELOW +1E42 ; [.1726.0020.0008.004D][.0000.0070.0002.0323] # LATIN CAPITAL LETTER M WITH DOT BELOW +33A1 ; [.1726.0020.001C.33A1][.15CC.0020.001C.33A1] # SQUARE M SQUARED +33A5 ; [.1726.0020.001C.33A5][.15CD.0020.001C.33A5] # SQUARE M CUBED +3383 ; [.1726.0020.001C.3383][.15D4.0020.001D.3383] # SQUARE MA +33D4 ; [.1726.0020.001C.33D4][.15EA.0020.001C.33D4] # SQUARE MB SMALL +3386 ; [.1726.0020.001D.3386][.15EA.0020.001D.3386] # SQUARE MB +1F16A ; [.1726.0020.0014.1F16A][.1602.0020.0014.1F16A] # RAISED MC SIGN +1F16B ; [.1726.0020.0014.1F16B][.1616.0020.0014.1F16B] # RAISED MD SIGN +338E ; [.1726.0020.001C.338E][.1676.0020.001C.338E] # SQUARE MG +3392 ; [.1726.0020.001D.3392][.1699.0020.001D.3392][.187A.0020.001F.3392] # SQUARE MHZ +33D5 ; [.1726.0020.001C.33D5][.16B2.0020.001C.33D5][.16F6.0020.001F.33D5] # SQUARE MIL +3396 ; [.1726.0020.001C.3396][.16F6.0020.001C.3396] # SQUARE ML +339C ; [.1726.0020.001C.339C][.1726.0020.001C.339C] # SQUARE MM +339F ; [.1726.0020.001C.339F][.1726.0020.001C.339F][.15CC.0020.001F.339F] # SQUARE MM SQUARED +33A3 ; [.1726.0020.001C.33A3][.1726.0020.001C.33A3][.15CD.0020.001F.33A3] # SQUARE MM CUBED +33D6 ; [.1726.0020.001C.33D6][.1756.0020.001C.33D6][.16F6.0020.001F.33D6] # SQUARE MOL +33AB ; [.1726.0020.001D.33AB][.177B.0020.001D.33AB][.15D4.0020.001F.33AB] # SQUARE MPA +33B3 ; [.1726.0020.001C.33B3][.17D8.0020.001C.33B3] # SQUARE MS +33A7 ; [.1726.0020.001C.33A7][*05AB.0020.001C.33A7][.17D8.0020.001F.33A7] # SQUARE M OVER S +33A8 ; [.1726.0020.001C.33A8][*05AB.0020.001C.33A8][.17D8.0020.001F.33A8][.15CC.0020.001F.33A8] # SQUARE M OVER S SQUARED +33B7 ; [.1726.0020.001C.33B7][.1844.0020.001D.33B7] # SQUARE MV +33B9 ; [.1726.0020.001D.33B9][.1844.0020.001D.33B9] # SQUARE MV MEGA +1F14B ; [.1726.0020.001D.1F14B][.1844.0020.001D.1F14B] # SQUARED MV +33BD ; [.1726.0020.001C.33BD][.1856.0020.001D.33BD] # SQUARE MW +33BF ; [.1726.0020.001D.33BF][.1856.0020.001D.33BF] # SQUARE MW MEGA +33C1 ; [.1726.0020.001D.33C1][.1936.0020.001D.33C1] # SQUARE M OHM +1D0D ; [.172A.0020.0002.1D0D] # LATIN LETTER SMALL CAPITAL M +1DDF ; [.172A.0020.0004.1DDF] # COMBINING LATIN LETTER SMALL CAPITAL M +1D6F ; [.172B.0020.0002.1D6F] # LATIN SMALL LETTER M WITH MIDDLE TILDE +1D86 ; [.172C.0020.0002.1D86] # LATIN SMALL LETTER M WITH PALATAL HOOK +0271 ; [.172D.0020.0002.0271] # LATIN SMALL LETTER M WITH HOOK +2C6E ; [.172D.0020.0008.2C6E] # LATIN CAPITAL LETTER M WITH HOOK +1DAC ; [.172D.0020.0014.1DAC] # MODIFIER LETTER SMALL M WITH HOOK +A7FD ; [.1731.0020.0002.A7FD] # LATIN EPIGRAPHIC LETTER INVERTED M +A7FF ; [.1732.0020.0002.A7FF] # LATIN EPIGRAPHIC LETTER ARCHAIC M +A773 ; [.1733.0020.0002.A773] # LATIN SMALL LETTER MUM +006E ; [.1734.0020.0002.006E] # LATIN SMALL LETTER N +FF4E ; [.1734.0020.0003.FF4E] # FULLWIDTH LATIN SMALL LETTER N +1DE0 ; [.1734.0020.0004.1DE0] # COMBINING LATIN SMALL LETTER N +24A9 ; [*02FB.0020.0004.24A9][.1734.0020.0004.24A9][*02FC.0020.001F.24A9] # PARENTHESIZED LATIN SMALL LETTER N +1D427 ; [.1734.0020.0005.1D427] # MATHEMATICAL BOLD SMALL N +1D45B ; [.1734.0020.0005.1D45B] # MATHEMATICAL ITALIC SMALL N +1D48F ; [.1734.0020.0005.1D48F] # MATHEMATICAL BOLD ITALIC SMALL N +1D4C3 ; [.1734.0020.0005.1D4C3] # MATHEMATICAL SCRIPT SMALL N +1D4F7 ; [.1734.0020.0005.1D4F7] # MATHEMATICAL BOLD SCRIPT SMALL N +1D52B ; [.1734.0020.0005.1D52B] # MATHEMATICAL FRAKTUR SMALL N +1D55F ; [.1734.0020.0005.1D55F] # MATHEMATICAL DOUBLE-STRUCK SMALL N +1D593 ; [.1734.0020.0005.1D593] # MATHEMATICAL BOLD FRAKTUR SMALL N +1D5C7 ; [.1734.0020.0005.1D5C7] # MATHEMATICAL SANS-SERIF SMALL N +1D5FB ; [.1734.0020.0005.1D5FB] # MATHEMATICAL SANS-SERIF BOLD SMALL N +1D62F ; [.1734.0020.0005.1D62F] # MATHEMATICAL SANS-SERIF ITALIC SMALL N +1D663 ; [.1734.0020.0005.1D663] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N +1D697 ; [.1734.0020.0005.1D697] # MATHEMATICAL MONOSPACE SMALL N +24DD ; [.1734.0020.0006.24DD] # CIRCLED LATIN SMALL LETTER N +004E ; [.1734.0020.0008.004E] # LATIN CAPITAL LETTER N +FF2E ; [.1734.0020.0009.FF2E] # FULLWIDTH LATIN CAPITAL LETTER N +1F11D ; [*02FB.0020.0004.1F11D][.1734.0020.000A.1F11D][*02FC.0020.001F.1F11D] # PARENTHESIZED LATIN CAPITAL LETTER N +1F1F3 ; [.1734.0020.000A.1F1F3] # REGIONAL INDICATOR SYMBOL LETTER N +2115 ; [.1734.0020.000B.2115] # DOUBLE-STRUCK CAPITAL N +1D40D ; [.1734.0020.000B.1D40D] # MATHEMATICAL BOLD CAPITAL N +1D441 ; [.1734.0020.000B.1D441] # MATHEMATICAL ITALIC CAPITAL N +1D475 ; [.1734.0020.000B.1D475] # MATHEMATICAL BOLD ITALIC CAPITAL N +1D4A9 ; [.1734.0020.000B.1D4A9] # MATHEMATICAL SCRIPT CAPITAL N +1D4DD ; [.1734.0020.000B.1D4DD] # MATHEMATICAL BOLD SCRIPT CAPITAL N +1D511 ; [.1734.0020.000B.1D511] # MATHEMATICAL FRAKTUR CAPITAL N +1D579 ; [.1734.0020.000B.1D579] # MATHEMATICAL BOLD FRAKTUR CAPITAL N +1D5AD ; [.1734.0020.000B.1D5AD] # MATHEMATICAL SANS-SERIF CAPITAL N +1D5E1 ; [.1734.0020.000B.1D5E1] # MATHEMATICAL SANS-SERIF BOLD CAPITAL N +1D615 ; [.1734.0020.000B.1D615] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL N +1D649 ; [.1734.0020.000B.1D649] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N +1D67D ; [.1734.0020.000B.1D67D] # MATHEMATICAL MONOSPACE CAPITAL N +24C3 ; [.1734.0020.000C.24C3] # CIRCLED LATIN CAPITAL LETTER N +1F15D ; [.1734.0020.000C.1F15D] # NEGATIVE CIRCLED LATIN CAPITAL LETTER N +207F ; [.1734.0020.0014.207F] # SUPERSCRIPT LATIN SMALL LETTER N +2099 ; [.1734.0020.0015.2099] # LATIN SUBSCRIPT SMALL LETTER N +1D3A ; [.1734.0020.001D.1D3A] # MODIFIER LETTER CAPITAL N +1F13D ; [.1734.0020.001D.1F13D] # SQUARED LATIN CAPITAL LETTER N +1F17D ; [.1734.0020.001D.1F17D] # NEGATIVE SQUARED LATIN CAPITAL LETTER N +0144 ; [.1734.0020.0002.006E][.0000.0032.0002.0301] # LATIN SMALL LETTER N WITH ACUTE +0143 ; [.1734.0020.0008.004E][.0000.0032.0002.0301] # LATIN CAPITAL LETTER N WITH ACUTE +01F9 ; [.1734.0020.0002.006E][.0000.0035.0002.0300] # LATIN SMALL LETTER N WITH GRAVE +01F8 ; [.1734.0020.0008.004E][.0000.0035.0002.0300] # LATIN CAPITAL LETTER N WITH GRAVE +0148 ; [.1734.0020.0002.006E][.0000.0041.0002.030C] # LATIN SMALL LETTER N WITH CARON +0147 ; [.1734.0020.0008.004E][.0000.0041.0002.030C] # LATIN CAPITAL LETTER N WITH CARON +00F1 ; [.1734.0020.0002.006E][.0000.004E.0002.0303] # LATIN SMALL LETTER N WITH TILDE +00D1 ; [.1734.0020.0008.004E][.0000.004E.0002.0303] # LATIN CAPITAL LETTER N WITH TILDE +1E45 ; [.1734.0020.0002.006E][.0000.0052.0002.0307] # LATIN SMALL LETTER N WITH DOT ABOVE +1E44 ; [.1734.0020.0008.004E][.0000.0052.0002.0307] # LATIN CAPITAL LETTER N WITH DOT ABOVE +0146 ; [.1734.0020.0002.006E][.0000.0056.0002.0327] # LATIN SMALL LETTER N WITH CEDILLA +0145 ; [.1734.0020.0008.004E][.0000.0056.0002.0327] # LATIN CAPITAL LETTER N WITH CEDILLA +A7A5 ; [.1734.0020.0004.A7A5][.0000.0061.0004.A7A5] # LATIN SMALL LETTER N WITH OBLIQUE STROKE +A7A4 ; [.1734.0020.000A.A7A4][.0000.0061.0004.A7A4] # LATIN CAPITAL LETTER N WITH OBLIQUE STROKE +1E47 ; [.1734.0020.0002.006E][.0000.0070.0002.0323] # LATIN SMALL LETTER N WITH DOT BELOW +1E46 ; [.1734.0020.0008.004E][.0000.0070.0002.0323] # LATIN CAPITAL LETTER N WITH DOT BELOW +1E4B ; [.1734.0020.0002.006E][.0000.0078.0002.032D] # LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW +1E4A ; [.1734.0020.0008.004E][.0000.0078.0002.032D] # LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW +1E49 ; [.1734.0020.0002.006E][.0000.007B.0002.0331] # LATIN SMALL LETTER N WITH LINE BELOW +1E48 ; [.1734.0020.0008.004E][.0000.007B.0002.0331] # LATIN CAPITAL LETTER N WITH LINE BELOW +3381 ; [.1734.0020.001C.3381][.15D4.0020.001D.3381] # SQUARE NA +1F195 ; [.1734.0020.001D.1F195][.1631.0020.001D.1F195][.1856.0020.001F.1F195] # SQUARED NEW +338B ; [.1734.0020.001C.338B][.1669.0020.001D.338B] # SQUARE NF +1F196 ; [.1734.0020.001D.1F196][.1676.0020.001D.1F196] # SQUARED NG +01CC ; [.1734.0020.0004.01CC][.16CB.0020.0004.01CC] # LATIN SMALL LETTER NJ +01CB ; [.1734.0020.000A.01CB][.16CB.0020.0004.01CB] # LATIN CAPITAL LETTER N WITH SMALL LETTER J +01CA ; [.1734.0020.000A.01CA][.16CB.0020.000A.01CA] # LATIN CAPITAL LETTER NJ +339A ; [.1734.0020.001C.339A][.1726.0020.001C.339A] # SQUARE NM +2116 ; [.1734.0020.000A.2116][.1756.0020.0004.2116] # NUMERO SIGN +33B1 ; [.1734.0020.001C.33B1][.17D8.0020.001C.33B1] # SQUARE NS +33B5 ; [.1734.0020.001C.33B5][.1844.0020.001D.33B5] # SQUARE NV +33BB ; [.1734.0020.001C.33BB][.1856.0020.001D.33BB] # SQUARE NW +0274 ; [.1738.0020.0002.0274] # LATIN LETTER SMALL CAPITAL N +1DE1 ; [.1738.0020.0004.1DE1] # COMBINING LATIN LETTER SMALL CAPITAL N +1DB0 ; [.1738.0020.0014.1DB0] # MODIFIER LETTER SMALL CAPITAL N +1D3B ; [.173C.0020.0002.1D3B] # MODIFIER LETTER CAPITAL REVERSED N +1D0E ; [.173D.0020.0002.1D0E] # LATIN LETTER SMALL CAPITAL REVERSED N +1D70 ; [.173E.0020.0002.1D70] # LATIN SMALL LETTER N WITH MIDDLE TILDE +0272 ; [.173F.0020.0002.0272] # LATIN SMALL LETTER N WITH LEFT HOOK +019D ; [.173F.0020.0008.019D] # LATIN CAPITAL LETTER N WITH LEFT HOOK +1DAE ; [.173F.0020.0014.1DAE] # MODIFIER LETTER SMALL N WITH LEFT HOOK +019E ; [.1743.0020.0002.019E] # LATIN SMALL LETTER N WITH LONG RIGHT LEG +0220 ; [.1743.0020.0008.0220] # LATIN CAPITAL LETTER N WITH LONG RIGHT LEG +A791 ; [.1747.0020.0002.A791] # LATIN SMALL LETTER N WITH DESCENDER +A790 ; [.1747.0020.0008.A790] # LATIN CAPITAL LETTER N WITH DESCENDER +1D87 ; [.1748.0020.0002.1D87] # LATIN SMALL LETTER N WITH PALATAL HOOK +0273 ; [.1749.0020.0002.0273] # LATIN SMALL LETTER N WITH RETROFLEX HOOK +1DAF ; [.1749.0020.0014.1DAF] # MODIFIER LETTER SMALL N WITH RETROFLEX HOOK +0235 ; [.174D.0020.0002.0235] # LATIN SMALL LETTER N WITH CURL +A774 ; [.1751.0020.0002.A774] # LATIN SMALL LETTER NUM +014B ; [.1752.0020.0002.014B] # LATIN SMALL LETTER ENG +014A ; [.1752.0020.0008.014A] # LATIN CAPITAL LETTER ENG +1D51 ; [.1752.0020.0014.1D51] # MODIFIER LETTER SMALL ENG +006F ; [.1756.0020.0002.006F] # LATIN SMALL LETTER O +FF4F ; [.1756.0020.0003.FF4F] # FULLWIDTH LATIN SMALL LETTER O +0366 ; [.1756.0020.0004.0366] # COMBINING LATIN SMALL LETTER O +24AA ; [*02FB.0020.0004.24AA][.1756.0020.0004.24AA][*02FC.0020.001F.24AA] # PARENTHESIZED LATIN SMALL LETTER O +2134 ; [.1756.0020.0005.2134] # SCRIPT SMALL O +1D428 ; [.1756.0020.0005.1D428] # MATHEMATICAL BOLD SMALL O +1D45C ; [.1756.0020.0005.1D45C] # MATHEMATICAL ITALIC SMALL O +1D490 ; [.1756.0020.0005.1D490] # MATHEMATICAL BOLD ITALIC SMALL O +1D4F8 ; [.1756.0020.0005.1D4F8] # MATHEMATICAL BOLD SCRIPT SMALL O +1D52C ; [.1756.0020.0005.1D52C] # MATHEMATICAL FRAKTUR SMALL O +1D560 ; [.1756.0020.0005.1D560] # MATHEMATICAL DOUBLE-STRUCK SMALL O +1D594 ; [.1756.0020.0005.1D594] # MATHEMATICAL BOLD FRAKTUR SMALL O +1D5C8 ; [.1756.0020.0005.1D5C8] # MATHEMATICAL SANS-SERIF SMALL O +1D5FC ; [.1756.0020.0005.1D5FC] # MATHEMATICAL SANS-SERIF BOLD SMALL O +1D630 ; [.1756.0020.0005.1D630] # MATHEMATICAL SANS-SERIF ITALIC SMALL O +1D664 ; [.1756.0020.0005.1D664] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O +1D698 ; [.1756.0020.0005.1D698] # MATHEMATICAL MONOSPACE SMALL O +24DE ; [.1756.0020.0006.24DE] # CIRCLED LATIN SMALL LETTER O +004F ; [.1756.0020.0008.004F] # LATIN CAPITAL LETTER O +FF2F ; [.1756.0020.0009.FF2F] # FULLWIDTH LATIN CAPITAL LETTER O +1F11E ; [*02FB.0020.0004.1F11E][.1756.0020.000A.1F11E][*02FC.0020.001F.1F11E] # PARENTHESIZED LATIN CAPITAL LETTER O +1F1F4 ; [.1756.0020.000A.1F1F4] # REGIONAL INDICATOR SYMBOL LETTER O +1D40E ; [.1756.0020.000B.1D40E] # MATHEMATICAL BOLD CAPITAL O +1D442 ; [.1756.0020.000B.1D442] # MATHEMATICAL ITALIC CAPITAL O +1D476 ; [.1756.0020.000B.1D476] # MATHEMATICAL BOLD ITALIC CAPITAL O +1D4AA ; [.1756.0020.000B.1D4AA] # MATHEMATICAL SCRIPT CAPITAL O +1D4DE ; [.1756.0020.000B.1D4DE] # MATHEMATICAL BOLD SCRIPT CAPITAL O +1D512 ; [.1756.0020.000B.1D512] # MATHEMATICAL FRAKTUR CAPITAL O +1D546 ; [.1756.0020.000B.1D546] # MATHEMATICAL DOUBLE-STRUCK CAPITAL O +1D57A ; [.1756.0020.000B.1D57A] # MATHEMATICAL BOLD FRAKTUR CAPITAL O +1D5AE ; [.1756.0020.000B.1D5AE] # MATHEMATICAL SANS-SERIF CAPITAL O +1D5E2 ; [.1756.0020.000B.1D5E2] # MATHEMATICAL SANS-SERIF BOLD CAPITAL O +1D616 ; [.1756.0020.000B.1D616] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL O +1D64A ; [.1756.0020.000B.1D64A] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O +1D67E ; [.1756.0020.000B.1D67E] # MATHEMATICAL MONOSPACE CAPITAL O +24C4 ; [.1756.0020.000C.24C4] # CIRCLED LATIN CAPITAL LETTER O +1F15E ; [.1756.0020.000C.1F15E] # NEGATIVE CIRCLED LATIN CAPITAL LETTER O +00BA ; [.1756.0020.0014.00BA] # MASCULINE ORDINAL INDICATOR +1D52 ; [.1756.0020.0014.1D52] # MODIFIER LETTER SMALL O +2092 ; [.1756.0020.0015.2092] # LATIN SUBSCRIPT SMALL LETTER O +1D3C ; [.1756.0020.001D.1D3C] # MODIFIER LETTER CAPITAL O +1F13E ; [.1756.0020.001D.1F13E] # SQUARED LATIN CAPITAL LETTER O +1F17E ; [.1756.0020.001D.1F17E] # NEGATIVE SQUARED LATIN CAPITAL LETTER O +00F3 ; [.1756.0020.0002.006F][.0000.0032.0002.0301] # LATIN SMALL LETTER O WITH ACUTE +00D3 ; [.1756.0020.0008.004F][.0000.0032.0002.0301] # LATIN CAPITAL LETTER O WITH ACUTE +00F2 ; [.1756.0020.0002.006F][.0000.0035.0002.0300] # LATIN SMALL LETTER O WITH GRAVE +00D2 ; [.1756.0020.0008.004F][.0000.0035.0002.0300] # LATIN CAPITAL LETTER O WITH GRAVE +014F ; [.1756.0020.0002.006F][.0000.0037.0002.0306] # LATIN SMALL LETTER O WITH BREVE +014E ; [.1756.0020.0008.004F][.0000.0037.0002.0306] # LATIN CAPITAL LETTER O WITH BREVE +00F4 ; [.1756.0020.0002.006F][.0000.003C.0002.0302] # LATIN SMALL LETTER O WITH CIRCUMFLEX +00D4 ; [.1756.0020.0008.004F][.0000.003C.0002.0302] # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +1ED1 ; [.1756.0020.0002.006F][.0000.003C.0002.0302][.0000.0032.0002.0301] # LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE +1ED0 ; [.1756.0020.0008.004F][.0000.003C.0002.0302][.0000.0032.0002.0301] # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE +1ED3 ; [.1756.0020.0002.006F][.0000.003C.0002.0302][.0000.0035.0002.0300] # LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE +1ED2 ; [.1756.0020.0008.004F][.0000.003C.0002.0302][.0000.0035.0002.0300] # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE +1ED7 ; [.1756.0020.0002.006F][.0000.003C.0002.0302][.0000.004E.0002.0303] # LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE +1ED6 ; [.1756.0020.0008.004F][.0000.003C.0002.0302][.0000.004E.0002.0303] # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE +1ED5 ; [.1756.0020.0002.006F][.0000.003C.0002.0302][.0000.0064.0002.0309] # LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +1ED4 ; [.1756.0020.0008.004F][.0000.003C.0002.0302][.0000.0064.0002.0309] # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +01D2 ; [.1756.0020.0002.006F][.0000.0041.0002.030C] # LATIN SMALL LETTER O WITH CARON +01D1 ; [.1756.0020.0008.004F][.0000.0041.0002.030C] # LATIN CAPITAL LETTER O WITH CARON +00F6 ; [.1756.0020.0002.006F][.0000.0047.0002.0308] # LATIN SMALL LETTER O WITH DIAERESIS +00D6 ; [.1756.0020.0008.004F][.0000.0047.0002.0308] # LATIN CAPITAL LETTER O WITH DIAERESIS +022B ; [.1756.0020.0002.006F][.0000.0047.0002.0308][.0000.005B.0002.0304] # LATIN SMALL LETTER O WITH DIAERESIS AND MACRON +022A ; [.1756.0020.0008.004F][.0000.0047.0002.0308][.0000.005B.0002.0304] # LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON +0151 ; [.1756.0020.0002.006F][.0000.004D.0002.030B] # LATIN SMALL LETTER O WITH DOUBLE ACUTE +0150 ; [.1756.0020.0008.004F][.0000.004D.0002.030B] # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +00F5 ; [.1756.0020.0002.006F][.0000.004E.0002.0303] # LATIN SMALL LETTER O WITH TILDE +00D5 ; [.1756.0020.0008.004F][.0000.004E.0002.0303] # LATIN CAPITAL LETTER O WITH TILDE +1E4D ; [.1756.0020.0002.006F][.0000.004E.0002.0303][.0000.0032.0002.0301] # LATIN SMALL LETTER O WITH TILDE AND ACUTE +1E4C ; [.1756.0020.0008.004F][.0000.004E.0002.0303][.0000.0032.0002.0301] # LATIN CAPITAL LETTER O WITH TILDE AND ACUTE +1E4F ; [.1756.0020.0002.006F][.0000.004E.0002.0303][.0000.0047.0002.0308] # LATIN SMALL LETTER O WITH TILDE AND DIAERESIS +1E4E ; [.1756.0020.0008.004F][.0000.004E.0002.0303][.0000.0047.0002.0308] # LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS +022D ; [.1756.0020.0002.006F][.0000.004E.0002.0303][.0000.005B.0002.0304] # LATIN SMALL LETTER O WITH TILDE AND MACRON +022C ; [.1756.0020.0008.004F][.0000.004E.0002.0303][.0000.005B.0002.0304] # LATIN CAPITAL LETTER O WITH TILDE AND MACRON +022F ; [.1756.0020.0002.006F][.0000.0052.0002.0307] # LATIN SMALL LETTER O WITH DOT ABOVE +022E ; [.1756.0020.0008.004F][.0000.0052.0002.0307] # LATIN CAPITAL LETTER O WITH DOT ABOVE +0231 ; [.1756.0020.0002.006F][.0000.0052.0002.0307][.0000.005B.0002.0304] # LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON +0230 ; [.1756.0020.0008.004F][.0000.0052.0002.0307][.0000.005B.0002.0304] # LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON +00F8 ; [.1756.0020.0002.006F][.0000.0054.0002.0338] # LATIN SMALL LETTER O WITH STROKE +00D8 ; [.1756.0020.0008.004F][.0000.0054.0002.0338] # LATIN CAPITAL LETTER O WITH STROKE +01FF ; [.1756.0020.0002.006F][.0000.0054.0002.0338][.0000.0032.0002.0301] # LATIN SMALL LETTER O WITH STROKE AND ACUTE +01FE ; [.1756.0020.0008.004F][.0000.0054.0002.0338][.0000.0032.0002.0301] # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE +01EB ; [.1756.0020.0002.006F][.0000.0059.0002.0328] # LATIN SMALL LETTER O WITH OGONEK +01EA ; [.1756.0020.0008.004F][.0000.0059.0002.0328] # LATIN CAPITAL LETTER O WITH OGONEK +01ED ; [.1756.0020.0002.006F][.0000.0059.0002.0328][.0000.005B.0002.0304] # LATIN SMALL LETTER O WITH OGONEK AND MACRON +01EC ; [.1756.0020.0008.004F][.0000.0059.0002.0328][.0000.005B.0002.0304] # LATIN CAPITAL LETTER O WITH OGONEK AND MACRON +014D ; [.1756.0020.0002.006F][.0000.005B.0002.0304] # LATIN SMALL LETTER O WITH MACRON +014C ; [.1756.0020.0008.004F][.0000.005B.0002.0304] # LATIN CAPITAL LETTER O WITH MACRON +1E53 ; [.1756.0020.0002.006F][.0000.005B.0002.0304][.0000.0032.0002.0301] # LATIN SMALL LETTER O WITH MACRON AND ACUTE +1E52 ; [.1756.0020.0008.004F][.0000.005B.0002.0304][.0000.0032.0002.0301] # LATIN CAPITAL LETTER O WITH MACRON AND ACUTE +1E51 ; [.1756.0020.0002.006F][.0000.005B.0002.0304][.0000.0035.0002.0300] # LATIN SMALL LETTER O WITH MACRON AND GRAVE +1E50 ; [.1756.0020.0008.004F][.0000.005B.0002.0304][.0000.0035.0002.0300] # LATIN CAPITAL LETTER O WITH MACRON AND GRAVE +1ECF ; [.1756.0020.0002.006F][.0000.0064.0002.0309] # LATIN SMALL LETTER O WITH HOOK ABOVE +1ECE ; [.1756.0020.0008.004F][.0000.0064.0002.0309] # LATIN CAPITAL LETTER O WITH HOOK ABOVE +020D ; [.1756.0020.0002.006F][.0000.0065.0002.030F] # LATIN SMALL LETTER O WITH DOUBLE GRAVE +020C ; [.1756.0020.0008.004F][.0000.0065.0002.030F] # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE +020F ; [.1756.0020.0002.006F][.0000.0067.0002.0311] # LATIN SMALL LETTER O WITH INVERTED BREVE +020E ; [.1756.0020.0008.004F][.0000.0067.0002.0311] # LATIN CAPITAL LETTER O WITH INVERTED BREVE +01A1 ; [.1756.0020.0002.006F][.0000.0068.0002.031B] # LATIN SMALL LETTER O WITH HORN +01A0 ; [.1756.0020.0008.004F][.0000.0068.0002.031B] # LATIN CAPITAL LETTER O WITH HORN +1EDB ; [.1756.0020.0002.006F][.0000.0068.0002.031B][.0000.0032.0002.0301] # LATIN SMALL LETTER O WITH HORN AND ACUTE +1EDA ; [.1756.0020.0008.004F][.0000.0068.0002.031B][.0000.0032.0002.0301] # LATIN CAPITAL LETTER O WITH HORN AND ACUTE +1EDD ; [.1756.0020.0002.006F][.0000.0068.0002.031B][.0000.0035.0002.0300] # LATIN SMALL LETTER O WITH HORN AND GRAVE +1EDC ; [.1756.0020.0008.004F][.0000.0068.0002.031B][.0000.0035.0002.0300] # LATIN CAPITAL LETTER O WITH HORN AND GRAVE +1EE1 ; [.1756.0020.0002.006F][.0000.0068.0002.031B][.0000.004E.0002.0303] # LATIN SMALL LETTER O WITH HORN AND TILDE +1EE0 ; [.1756.0020.0008.004F][.0000.0068.0002.031B][.0000.004E.0002.0303] # LATIN CAPITAL LETTER O WITH HORN AND TILDE +1EDF ; [.1756.0020.0002.006F][.0000.0068.0002.031B][.0000.0064.0002.0309] # LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE +1EDE ; [.1756.0020.0008.004F][.0000.0068.0002.031B][.0000.0064.0002.0309] # LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE +1EE3 ; [.1756.0020.0002.006F][.0000.0068.0002.031B][.0000.0070.0002.0323] # LATIN SMALL LETTER O WITH HORN AND DOT BELOW +1EE2 ; [.1756.0020.0008.004F][.0000.0068.0002.031B][.0000.0070.0002.0323] # LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW +1ECD ; [.1756.0020.0002.006F][.0000.0070.0002.0323] # LATIN SMALL LETTER O WITH DOT BELOW +1ECC ; [.1756.0020.0008.004F][.0000.0070.0002.0323] # LATIN CAPITAL LETTER O WITH DOT BELOW +1ED9 ; [.1756.0020.0002.006F][.0000.0070.0002.0323][.0000.003C.0002.0302] # LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW +1ED8 ; [.1756.0020.0008.004F][.0000.0070.0002.0323][.0000.003C.0002.0302] # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW +0153 ; [.1756.0020.0004.0153][.0000.0139.0004.0153][.1631.0020.001F.0153] # LATIN SMALL LIGATURE OE +0152 ; [.1756.0020.000A.0152][.0000.0139.0004.0152][.1631.0020.001F.0152] # LATIN CAPITAL LIGATURE OE +A7F9 ; [.1756.0020.0014.A7F9][.0000.0139.0014.A7F9][.1631.0020.001F.A7F9] # MODIFIER LETTER SMALL LIGATURE OE +1F197 ; [.1756.0020.001D.1F197][.16E4.0020.001D.1F197] # SQUARED OK +A74F ; [.1756.0020.0004.A74F][.1756.0020.0004.A74F] # LATIN SMALL LETTER OO +A74E ; [.1756.0020.000A.A74E][.1756.0020.000A.A74E] # LATIN CAPITAL LETTER OO +3375 ; [.1756.0020.001C.3375][.1844.0020.001D.3375] # SQUARE OV +1D0F ; [.175A.0020.0002.1D0F] # LATIN LETTER SMALL CAPITAL O +1D11 ; [.175B.0020.0002.1D11] # LATIN SMALL LETTER SIDEWAYS O +0276 ; [.175C.0020.0002.0276] # LATIN LETTER SMALL CAPITAL OE +1D14 ; [.1760.0020.0002.1D14] # LATIN SMALL LETTER TURNED OE +1D13 ; [.1761.0020.0002.1D13] # LATIN SMALL LETTER SIDEWAYS O WITH STROKE +0254 ; [.1762.0020.0002.0254] # LATIN SMALL LETTER OPEN O +0186 ; [.1762.0020.0008.0186] # LATIN CAPITAL LETTER OPEN O +1D53 ; [.1762.0020.0014.1D53] # MODIFIER LETTER SMALL OPEN O +1D10 ; [.1766.0020.0002.1D10] # LATIN LETTER SMALL CAPITAL OPEN O +1D12 ; [.1767.0020.0002.1D12] # LATIN SMALL LETTER SIDEWAYS OPEN O +1D97 ; [.1768.0020.0002.1D97] # LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK +A74D ; [.1769.0020.0002.A74D] # LATIN SMALL LETTER O WITH LOOP +A74C ; [.1769.0020.0008.A74C] # LATIN CAPITAL LETTER O WITH LOOP +1D16 ; [.176A.0020.0002.1D16] # LATIN SMALL LETTER TOP HALF O +1D54 ; [.176A.0020.0014.1D54] # MODIFIER LETTER SMALL TOP HALF O +1D17 ; [.176B.0020.0002.1D17] # LATIN SMALL LETTER BOTTOM HALF O +1D55 ; [.176B.0020.0014.1D55] # MODIFIER LETTER SMALL BOTTOM HALF O +2C7A ; [.176C.0020.0002.2C7A] # LATIN SMALL LETTER O WITH LOW RING INSIDE +0275 ; [.176D.0020.0002.0275] # LATIN SMALL LETTER BARRED O +019F ; [.176D.0020.0008.019F] # LATIN CAPITAL LETTER O WITH MIDDLE TILDE +1DB1 ; [.176D.0020.0014.1DB1] # MODIFIER LETTER SMALL BARRED O +A74B ; [.1771.0020.0002.A74B] # LATIN SMALL LETTER O WITH LONG STROKE OVERLAY +A74A ; [.1771.0020.0008.A74A] # LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY +0277 ; [.1772.0020.0002.0277] # LATIN SMALL LETTER CLOSED OMEGA +0223 ; [.1776.0020.0002.0223] # LATIN SMALL LETTER OU +0222 ; [.1776.0020.0008.0222] # LATIN CAPITAL LETTER OU +1D3D ; [.1776.0020.001D.1D3D] # MODIFIER LETTER CAPITAL OU +1D15 ; [.177A.0020.0002.1D15] # LATIN LETTER SMALL CAPITAL OU +0070 ; [.177B.0020.0002.0070] # LATIN SMALL LETTER P +FF50 ; [.177B.0020.0003.FF50] # FULLWIDTH LATIN SMALL LETTER P +24AB ; [*02FB.0020.0004.24AB][.177B.0020.0004.24AB][*02FC.0020.001F.24AB] # PARENTHESIZED LATIN SMALL LETTER P +1D429 ; [.177B.0020.0005.1D429] # MATHEMATICAL BOLD SMALL P +1D45D ; [.177B.0020.0005.1D45D] # MATHEMATICAL ITALIC SMALL P +1D491 ; [.177B.0020.0005.1D491] # MATHEMATICAL BOLD ITALIC SMALL P +1D4C5 ; [.177B.0020.0005.1D4C5] # MATHEMATICAL SCRIPT SMALL P +1D4F9 ; [.177B.0020.0005.1D4F9] # MATHEMATICAL BOLD SCRIPT SMALL P +1D52D ; [.177B.0020.0005.1D52D] # MATHEMATICAL FRAKTUR SMALL P +1D561 ; [.177B.0020.0005.1D561] # MATHEMATICAL DOUBLE-STRUCK SMALL P +1D595 ; [.177B.0020.0005.1D595] # MATHEMATICAL BOLD FRAKTUR SMALL P +1D5C9 ; [.177B.0020.0005.1D5C9] # MATHEMATICAL SANS-SERIF SMALL P +1D5FD ; [.177B.0020.0005.1D5FD] # MATHEMATICAL SANS-SERIF BOLD SMALL P +1D631 ; [.177B.0020.0005.1D631] # MATHEMATICAL SANS-SERIF ITALIC SMALL P +1D665 ; [.177B.0020.0005.1D665] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P +1D699 ; [.177B.0020.0005.1D699] # MATHEMATICAL MONOSPACE SMALL P +24DF ; [.177B.0020.0006.24DF] # CIRCLED LATIN SMALL LETTER P +0050 ; [.177B.0020.0008.0050] # LATIN CAPITAL LETTER P +FF30 ; [.177B.0020.0009.FF30] # FULLWIDTH LATIN CAPITAL LETTER P +1F11F ; [*02FB.0020.0004.1F11F][.177B.0020.000A.1F11F][*02FC.0020.001F.1F11F] # PARENTHESIZED LATIN CAPITAL LETTER P +1F1F5 ; [.177B.0020.000A.1F1F5] # REGIONAL INDICATOR SYMBOL LETTER P +2119 ; [.177B.0020.000B.2119] # DOUBLE-STRUCK CAPITAL P +1D40F ; [.177B.0020.000B.1D40F] # MATHEMATICAL BOLD CAPITAL P +1D443 ; [.177B.0020.000B.1D443] # MATHEMATICAL ITALIC CAPITAL P +1D477 ; [.177B.0020.000B.1D477] # MATHEMATICAL BOLD ITALIC CAPITAL P +1D4AB ; [.177B.0020.000B.1D4AB] # MATHEMATICAL SCRIPT CAPITAL P +1D4DF ; [.177B.0020.000B.1D4DF] # MATHEMATICAL BOLD SCRIPT CAPITAL P +1D513 ; [.177B.0020.000B.1D513] # MATHEMATICAL FRAKTUR CAPITAL P +1D57B ; [.177B.0020.000B.1D57B] # MATHEMATICAL BOLD FRAKTUR CAPITAL P +1D5AF ; [.177B.0020.000B.1D5AF] # MATHEMATICAL SANS-SERIF CAPITAL P +1D5E3 ; [.177B.0020.000B.1D5E3] # MATHEMATICAL SANS-SERIF BOLD CAPITAL P +1D617 ; [.177B.0020.000B.1D617] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL P +1D64B ; [.177B.0020.000B.1D64B] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P +1D67F ; [.177B.0020.000B.1D67F] # MATHEMATICAL MONOSPACE CAPITAL P +24C5 ; [.177B.0020.000C.24C5] # CIRCLED LATIN CAPITAL LETTER P +1F15F ; [.177B.0020.000C.1F15F] # NEGATIVE CIRCLED LATIN CAPITAL LETTER P +1D56 ; [.177B.0020.0014.1D56] # MODIFIER LETTER SMALL P +209A ; [.177B.0020.0015.209A] # LATIN SUBSCRIPT SMALL LETTER P +1D3E ; [.177B.0020.001D.1D3E] # MODIFIER LETTER CAPITAL P +1F13F ; [.177B.0020.001D.1F13F] # SQUARED LATIN CAPITAL LETTER P +1F17F ; [.177B.0020.001D.1F17F] # NEGATIVE SQUARED LATIN CAPITAL LETTER P +1F18A ; [.177B.0020.001D.1F18A] # CROSSED NEGATIVE SQUARED LATIN CAPITAL LETTER P +1E55 ; [.177B.0020.0002.0070][.0000.0032.0002.0301] # LATIN SMALL LETTER P WITH ACUTE +1E54 ; [.177B.0020.0008.0050][.0000.0032.0002.0301] # LATIN CAPITAL LETTER P WITH ACUTE +1E57 ; [.177B.0020.0002.0070][.0000.0052.0002.0307] # LATIN SMALL LETTER P WITH DOT ABOVE +1E56 ; [.177B.0020.0008.0050][.0000.0052.0002.0307] # LATIN CAPITAL LETTER P WITH DOT ABOVE +3380 ; [.177B.0020.001C.3380][.15D4.0020.001D.3380] # SQUARE PA AMPS +33A9 ; [.177B.0020.001D.33A9][.15D4.0020.001C.33A9] # SQUARE PA +1F18C ; [.177B.0020.001D.1F18C][.15D4.0020.001D.1F18C] # NEGATIVE SQUARED PA +3376 ; [.177B.0020.001C.3376][.1602.0020.001C.3376] # SQUARE PC +338A ; [.177B.0020.001C.338A][.1669.0020.001D.338A] # SQUARE PF +33D7 ; [.177B.0020.001D.33D7][.1699.0020.001D.33D7] # SQUARE PH +33D8 ; [.177B.0020.001C.33D8][*0273.0020.001C.33D8][.1726.0020.001F.33D8][*0273.0020.001F.33D8] # SQUARE PM +33D9 ; [.177B.0020.001D.33D9][.177B.0020.001D.33D9][.1726.0020.001F.33D9] # SQUARE PPM +1F14E ; [.177B.0020.001D.1F14E][.177B.0020.001D.1F14E][.1844.0020.001F.1F14E] # SQUARED PPV +33DA ; [.177B.0020.001D.33DA][.17A2.0020.001D.33DA] # SQUARE PR +33B0 ; [.177B.0020.001C.33B0][.17D8.0020.001C.33B0] # SQUARE PS +3250 ; [.177B.0020.001D.3250][.17FB.0020.001D.3250][.1631.0020.001F.3250] # PARTNERSHIP SIGN +33B4 ; [.177B.0020.001C.33B4][.1844.0020.001D.33B4] # SQUARE PV +33BA ; [.177B.0020.001C.33BA][.1856.0020.001D.33BA] # SQUARE PW +1D18 ; [.177F.0020.0002.1D18] # LATIN LETTER SMALL CAPITAL P +1D7D ; [.1780.0020.0002.1D7D] # LATIN SMALL LETTER P WITH STROKE +2C63 ; [.1780.0020.0008.2C63] # LATIN CAPITAL LETTER P WITH STROKE +A751 ; [.1781.0020.0002.A751] # LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER +A750 ; [.1781.0020.0008.A750] # LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER +1D71 ; [.1782.0020.0002.1D71] # LATIN SMALL LETTER P WITH MIDDLE TILDE +1D88 ; [.1783.0020.0002.1D88] # LATIN SMALL LETTER P WITH PALATAL HOOK +01A5 ; [.1784.0020.0002.01A5] # LATIN SMALL LETTER P WITH HOOK +01A4 ; [.1784.0020.0008.01A4] # LATIN CAPITAL LETTER P WITH HOOK +A753 ; [.1788.0020.0002.A753] # LATIN SMALL LETTER P WITH FLOURISH +A752 ; [.1788.0020.0008.A752] # LATIN CAPITAL LETTER P WITH FLOURISH +A755 ; [.1789.0020.0002.A755] # LATIN SMALL LETTER P WITH SQUIRREL TAIL +A754 ; [.1789.0020.0008.A754] # LATIN CAPITAL LETTER P WITH SQUIRREL TAIL +A7FC ; [.178A.0020.0002.A7FC] # LATIN EPIGRAPHIC LETTER REVERSED P +0278 ; [.178B.0020.0002.0278] # LATIN SMALL LETTER PHI +1DB2 ; [.178B.0020.0014.1DB2] # MODIFIER LETTER SMALL PHI +2C77 ; [.178F.0020.0002.2C77] # LATIN SMALL LETTER TAILLESS PHI +0071 ; [.1790.0020.0002.0071] # LATIN SMALL LETTER Q +FF51 ; [.1790.0020.0003.FF51] # FULLWIDTH LATIN SMALL LETTER Q +24AC ; [*02FB.0020.0004.24AC][.1790.0020.0004.24AC][*02FC.0020.001F.24AC] # PARENTHESIZED LATIN SMALL LETTER Q +1D42A ; [.1790.0020.0005.1D42A] # MATHEMATICAL BOLD SMALL Q +1D45E ; [.1790.0020.0005.1D45E] # MATHEMATICAL ITALIC SMALL Q +1D492 ; [.1790.0020.0005.1D492] # MATHEMATICAL BOLD ITALIC SMALL Q +1D4C6 ; [.1790.0020.0005.1D4C6] # MATHEMATICAL SCRIPT SMALL Q +1D4FA ; [.1790.0020.0005.1D4FA] # MATHEMATICAL BOLD SCRIPT SMALL Q +1D52E ; [.1790.0020.0005.1D52E] # MATHEMATICAL FRAKTUR SMALL Q +1D562 ; [.1790.0020.0005.1D562] # MATHEMATICAL DOUBLE-STRUCK SMALL Q +1D596 ; [.1790.0020.0005.1D596] # MATHEMATICAL BOLD FRAKTUR SMALL Q +1D5CA ; [.1790.0020.0005.1D5CA] # MATHEMATICAL SANS-SERIF SMALL Q +1D5FE ; [.1790.0020.0005.1D5FE] # MATHEMATICAL SANS-SERIF BOLD SMALL Q +1D632 ; [.1790.0020.0005.1D632] # MATHEMATICAL SANS-SERIF ITALIC SMALL Q +1D666 ; [.1790.0020.0005.1D666] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q +1D69A ; [.1790.0020.0005.1D69A] # MATHEMATICAL MONOSPACE SMALL Q +24E0 ; [.1790.0020.0006.24E0] # CIRCLED LATIN SMALL LETTER Q +0051 ; [.1790.0020.0008.0051] # LATIN CAPITAL LETTER Q +FF31 ; [.1790.0020.0009.FF31] # FULLWIDTH LATIN CAPITAL LETTER Q +1F120 ; [*02FB.0020.0004.1F120][.1790.0020.000A.1F120][*02FC.0020.001F.1F120] # PARENTHESIZED LATIN CAPITAL LETTER Q +1F1F6 ; [.1790.0020.000A.1F1F6] # REGIONAL INDICATOR SYMBOL LETTER Q +211A ; [.1790.0020.000B.211A] # DOUBLE-STRUCK CAPITAL Q +1D410 ; [.1790.0020.000B.1D410] # MATHEMATICAL BOLD CAPITAL Q +1D444 ; [.1790.0020.000B.1D444] # MATHEMATICAL ITALIC CAPITAL Q +1D478 ; [.1790.0020.000B.1D478] # MATHEMATICAL BOLD ITALIC CAPITAL Q +1D4AC ; [.1790.0020.000B.1D4AC] # MATHEMATICAL SCRIPT CAPITAL Q +1D4E0 ; [.1790.0020.000B.1D4E0] # MATHEMATICAL BOLD SCRIPT CAPITAL Q +1D514 ; [.1790.0020.000B.1D514] # MATHEMATICAL FRAKTUR CAPITAL Q +1D57C ; [.1790.0020.000B.1D57C] # MATHEMATICAL BOLD FRAKTUR CAPITAL Q +1D5B0 ; [.1790.0020.000B.1D5B0] # MATHEMATICAL SANS-SERIF CAPITAL Q +1D5E4 ; [.1790.0020.000B.1D5E4] # MATHEMATICAL SANS-SERIF BOLD CAPITAL Q +1D618 ; [.1790.0020.000B.1D618] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q +1D64C ; [.1790.0020.000B.1D64C] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q +1D680 ; [.1790.0020.000B.1D680] # MATHEMATICAL MONOSPACE CAPITAL Q +24C6 ; [.1790.0020.000C.24C6] # CIRCLED LATIN CAPITAL LETTER Q +1F160 ; [.1790.0020.000C.1F160] # NEGATIVE CIRCLED LATIN CAPITAL LETTER Q +1F140 ; [.1790.0020.001D.1F140] # SQUARED LATIN CAPITAL LETTER Q +1F180 ; [.1790.0020.001D.1F180] # NEGATIVE SQUARED LATIN CAPITAL LETTER Q +0239 ; [.1790.0020.0004.0239][.177B.0020.0004.0239] # LATIN SMALL LETTER QP DIGRAPH +A757 ; [.1794.0020.0002.A757] # LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER +A756 ; [.1794.0020.0008.A756] # LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER +A759 ; [.1795.0020.0002.A759] # LATIN SMALL LETTER Q WITH DIAGONAL STROKE +A758 ; [.1795.0020.0008.A758] # LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE +02A0 ; [.1796.0020.0002.02A0] # LATIN SMALL LETTER Q WITH HOOK +024B ; [.179A.0020.0002.024B] # LATIN SMALL LETTER Q WITH HOOK TAIL +024A ; [.179A.0020.0008.024A] # LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL +0138 ; [.179E.0020.0002.0138] # LATIN SMALL LETTER KRA +0072 ; [.17A2.0020.0002.0072] # LATIN SMALL LETTER R +FF52 ; [.17A2.0020.0003.FF52] # FULLWIDTH LATIN SMALL LETTER R +036C ; [.17A2.0020.0004.036C] # COMBINING LATIN SMALL LETTER R +1DCA ; [.17A2.0020.0004.1DCA] # COMBINING LATIN SMALL LETTER R BELOW +24AD ; [*02FB.0020.0004.24AD][.17A2.0020.0004.24AD][*02FC.0020.001F.24AD] # PARENTHESIZED LATIN SMALL LETTER R +1D42B ; [.17A2.0020.0005.1D42B] # MATHEMATICAL BOLD SMALL R +1D45F ; [.17A2.0020.0005.1D45F] # MATHEMATICAL ITALIC SMALL R +1D493 ; [.17A2.0020.0005.1D493] # MATHEMATICAL BOLD ITALIC SMALL R +1D4C7 ; [.17A2.0020.0005.1D4C7] # MATHEMATICAL SCRIPT SMALL R +1D4FB ; [.17A2.0020.0005.1D4FB] # MATHEMATICAL BOLD SCRIPT SMALL R +1D52F ; [.17A2.0020.0005.1D52F] # MATHEMATICAL FRAKTUR SMALL R +1D563 ; [.17A2.0020.0005.1D563] # MATHEMATICAL DOUBLE-STRUCK SMALL R +1D597 ; [.17A2.0020.0005.1D597] # MATHEMATICAL BOLD FRAKTUR SMALL R +1D5CB ; [.17A2.0020.0005.1D5CB] # MATHEMATICAL SANS-SERIF SMALL R +1D5FF ; [.17A2.0020.0005.1D5FF] # MATHEMATICAL SANS-SERIF BOLD SMALL R +1D633 ; [.17A2.0020.0005.1D633] # MATHEMATICAL SANS-SERIF ITALIC SMALL R +1D667 ; [.17A2.0020.0005.1D667] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R +1D69B ; [.17A2.0020.0005.1D69B] # MATHEMATICAL MONOSPACE SMALL R +24E1 ; [.17A2.0020.0006.24E1] # CIRCLED LATIN SMALL LETTER R +0052 ; [.17A2.0020.0008.0052] # LATIN CAPITAL LETTER R +FF32 ; [.17A2.0020.0009.FF32] # FULLWIDTH LATIN CAPITAL LETTER R +1F121 ; [*02FB.0020.0004.1F121][.17A2.0020.000A.1F121][*02FC.0020.001F.1F121] # PARENTHESIZED LATIN CAPITAL LETTER R +1F1F7 ; [.17A2.0020.000A.1F1F7] # REGIONAL INDICATOR SYMBOL LETTER R +211B ; [.17A2.0020.000B.211B] # SCRIPT CAPITAL R +211C ; [.17A2.0020.000B.211C] # BLACK-LETTER CAPITAL R +211D ; [.17A2.0020.000B.211D] # DOUBLE-STRUCK CAPITAL R +1D411 ; [.17A2.0020.000B.1D411] # MATHEMATICAL BOLD CAPITAL R +1D445 ; [.17A2.0020.000B.1D445] # MATHEMATICAL ITALIC CAPITAL R +1D479 ; [.17A2.0020.000B.1D479] # MATHEMATICAL BOLD ITALIC CAPITAL R +1D4E1 ; [.17A2.0020.000B.1D4E1] # MATHEMATICAL BOLD SCRIPT CAPITAL R +1D57D ; [.17A2.0020.000B.1D57D] # MATHEMATICAL BOLD FRAKTUR CAPITAL R +1D5B1 ; [.17A2.0020.000B.1D5B1] # MATHEMATICAL SANS-SERIF CAPITAL R +1D5E5 ; [.17A2.0020.000B.1D5E5] # MATHEMATICAL SANS-SERIF BOLD CAPITAL R +1D619 ; [.17A2.0020.000B.1D619] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL R +1D64D ; [.17A2.0020.000B.1D64D] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R +1D681 ; [.17A2.0020.000B.1D681] # MATHEMATICAL MONOSPACE CAPITAL R +24C7 ; [.17A2.0020.000C.24C7] # CIRCLED LATIN CAPITAL LETTER R +1F12C ; [.17A2.0020.000C.1F12C] # CIRCLED ITALIC LATIN CAPITAL LETTER R +1F161 ; [.17A2.0020.000C.1F161] # NEGATIVE CIRCLED LATIN CAPITAL LETTER R +02B3 ; [.17A2.0020.0014.02B3] # MODIFIER LETTER SMALL R +1D63 ; [.17A2.0020.0015.1D63] # LATIN SUBSCRIPT SMALL LETTER R +1D3F ; [.17A2.0020.001D.1D3F] # MODIFIER LETTER CAPITAL R +1F141 ; [.17A2.0020.001D.1F141] # SQUARED LATIN CAPITAL LETTER R +1F181 ; [.17A2.0020.001D.1F181] # NEGATIVE SQUARED LATIN CAPITAL LETTER R +0155 ; [.17A2.0020.0002.0072][.0000.0032.0002.0301] # LATIN SMALL LETTER R WITH ACUTE +0154 ; [.17A2.0020.0008.0052][.0000.0032.0002.0301] # LATIN CAPITAL LETTER R WITH ACUTE +0159 ; [.17A2.0020.0002.0072][.0000.0041.0002.030C] # LATIN SMALL LETTER R WITH CARON +0158 ; [.17A2.0020.0008.0052][.0000.0041.0002.030C] # LATIN CAPITAL LETTER R WITH CARON +1E59 ; [.17A2.0020.0002.0072][.0000.0052.0002.0307] # LATIN SMALL LETTER R WITH DOT ABOVE +1E58 ; [.17A2.0020.0008.0052][.0000.0052.0002.0307] # LATIN CAPITAL LETTER R WITH DOT ABOVE +0157 ; [.17A2.0020.0002.0072][.0000.0056.0002.0327] # LATIN SMALL LETTER R WITH CEDILLA +0156 ; [.17A2.0020.0008.0052][.0000.0056.0002.0327] # LATIN CAPITAL LETTER R WITH CEDILLA +A7A7 ; [.17A2.0020.0004.A7A7][.0000.0061.0004.A7A7] # LATIN SMALL LETTER R WITH OBLIQUE STROKE +A7A6 ; [.17A2.0020.000A.A7A6][.0000.0061.0004.A7A6] # LATIN CAPITAL LETTER R WITH OBLIQUE STROKE +0211 ; [.17A2.0020.0002.0072][.0000.0065.0002.030F] # LATIN SMALL LETTER R WITH DOUBLE GRAVE +0210 ; [.17A2.0020.0008.0052][.0000.0065.0002.030F] # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE +0213 ; [.17A2.0020.0002.0072][.0000.0067.0002.0311] # LATIN SMALL LETTER R WITH INVERTED BREVE +0212 ; [.17A2.0020.0008.0052][.0000.0067.0002.0311] # LATIN CAPITAL LETTER R WITH INVERTED BREVE +1E5B ; [.17A2.0020.0002.0072][.0000.0070.0002.0323] # LATIN SMALL LETTER R WITH DOT BELOW +1E5A ; [.17A2.0020.0008.0052][.0000.0070.0002.0323] # LATIN CAPITAL LETTER R WITH DOT BELOW +1E5D ; [.17A2.0020.0002.0072][.0000.0070.0002.0323][.0000.005B.0002.0304] # LATIN SMALL LETTER R WITH DOT BELOW AND MACRON +1E5C ; [.17A2.0020.0008.0052][.0000.0070.0002.0323][.0000.005B.0002.0304] # LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON +1E5F ; [.17A2.0020.0002.0072][.0000.007B.0002.0331] # LATIN SMALL LETTER R WITH LINE BELOW +1E5E ; [.17A2.0020.0008.0052][.0000.007B.0002.0331] # LATIN CAPITAL LETTER R WITH LINE BELOW +A783 ; [.17A2.0020.0004.A783][.0000.013A.0004.A783] # LATIN SMALL LETTER INSULAR R +A782 ; [.17A2.0020.000A.A782][.0000.013A.0004.A782] # LATIN CAPITAL LETTER INSULAR R +33AD ; [.17A2.0020.001C.33AD][.15D4.0020.001C.33AD][.1616.0020.001F.33AD] # SQUARE RAD +33AE ; [.17A2.0020.001C.33AE][.15D4.0020.001C.33AE][.1616.0020.001F.33AE][*05AB.0020.001F.33AE][.17D8.0020.001F.33AE] # SQUARE RAD OVER S +33AF ; [.17A2.0020.001C.33AF][.15D4.0020.001C.33AF][.1616.0020.001F.33AF][*05AB.0020.001F.33AF][.17D8.0020.001F.33AF][.15CC.0020.001F.33AF] # SQUARE RAD OVER S SQUARED +20A8 ; [.17A2.0020.000A.20A8][.17D8.0020.0004.20A8] # RUPEE SIGN +0280 ; [.17A6.0020.0002.0280] # LATIN LETTER SMALL CAPITAL R +1DE2 ; [.17A6.0020.0004.1DE2] # COMBINING LATIN LETTER SMALL CAPITAL R +01A6 ; [.17A6.0020.0008.01A6] # LATIN LETTER YR +A75B ; [.17AA.0020.0002.A75B] # LATIN SMALL LETTER R ROTUNDA +1DE3 ; [.17AA.0020.0004.1DE3] # COMBINING LATIN SMALL LETTER R ROTUNDA +A75A ; [.17AA.0020.0008.A75A] # LATIN CAPITAL LETTER R ROTUNDA +1D19 ; [.17AB.0020.0002.1D19] # LATIN LETTER SMALL CAPITAL REVERSED R +024D ; [.17AC.0020.0002.024D] # LATIN SMALL LETTER R WITH STROKE +024C ; [.17AC.0020.0008.024C] # LATIN CAPITAL LETTER R WITH STROKE +1D72 ; [.17B0.0020.0002.1D72] # LATIN SMALL LETTER R WITH MIDDLE TILDE +0279 ; [.17B1.0020.0002.0279] # LATIN SMALL LETTER TURNED R +02B4 ; [.17B1.0020.0014.02B4] # MODIFIER LETTER SMALL TURNED R +1D1A ; [.17B5.0020.0002.1D1A] # LATIN LETTER SMALL CAPITAL TURNED R +027A ; [.17B6.0020.0002.027A] # LATIN SMALL LETTER TURNED R WITH LONG LEG +1D89 ; [.17BA.0020.0002.1D89] # LATIN SMALL LETTER R WITH PALATAL HOOK +027B ; [.17BB.0020.0002.027B] # LATIN SMALL LETTER TURNED R WITH HOOK +02B5 ; [.17BB.0020.0014.02B5] # MODIFIER LETTER SMALL TURNED R WITH HOOK +2C79 ; [.17BF.0020.0002.2C79] # LATIN SMALL LETTER TURNED R WITH TAIL +027C ; [.17C0.0020.0002.027C] # LATIN SMALL LETTER R WITH LONG LEG +027D ; [.17C4.0020.0002.027D] # LATIN SMALL LETTER R WITH TAIL +2C64 ; [.17C4.0020.0008.2C64] # LATIN CAPITAL LETTER R WITH TAIL +027E ; [.17C8.0020.0002.027E] # LATIN SMALL LETTER R WITH FISHHOOK +1D73 ; [.17CC.0020.0002.1D73] # LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE +027F ; [.17CD.0020.0002.027F] # LATIN SMALL LETTER REVERSED R WITH FISHHOOK +0281 ; [.17D1.0020.0002.0281] # LATIN LETTER SMALL CAPITAL INVERTED R +02B6 ; [.17D1.0020.0014.02B6] # MODIFIER LETTER SMALL CAPITAL INVERTED R +A775 ; [.17D5.0020.0002.A775] # LATIN SMALL LETTER RUM +A776 ; [.17D6.0020.0002.A776] # LATIN LETTER SMALL CAPITAL RUM +A75D ; [.17D7.0020.0002.A75D] # LATIN SMALL LETTER RUM ROTUNDA +A75C ; [.17D7.0020.0008.A75C] # LATIN CAPITAL LETTER RUM ROTUNDA +0073 ; [.17D8.0020.0002.0073] # LATIN SMALL LETTER S +FF53 ; [.17D8.0020.0003.FF53] # FULLWIDTH LATIN SMALL LETTER S +1DE4 ; [.17D8.0020.0004.1DE4] # COMBINING LATIN SMALL LETTER S +24AE ; [*02FB.0020.0004.24AE][.17D8.0020.0004.24AE][*02FC.0020.001F.24AE] # PARENTHESIZED LATIN SMALL LETTER S +1D42C ; [.17D8.0020.0005.1D42C] # MATHEMATICAL BOLD SMALL S +1D460 ; [.17D8.0020.0005.1D460] # MATHEMATICAL ITALIC SMALL S +1D494 ; [.17D8.0020.0005.1D494] # MATHEMATICAL BOLD ITALIC SMALL S +1D4C8 ; [.17D8.0020.0005.1D4C8] # MATHEMATICAL SCRIPT SMALL S +1D4FC ; [.17D8.0020.0005.1D4FC] # MATHEMATICAL BOLD SCRIPT SMALL S +1D530 ; [.17D8.0020.0005.1D530] # MATHEMATICAL FRAKTUR SMALL S +1D564 ; [.17D8.0020.0005.1D564] # MATHEMATICAL DOUBLE-STRUCK SMALL S +1D598 ; [.17D8.0020.0005.1D598] # MATHEMATICAL BOLD FRAKTUR SMALL S +1D5CC ; [.17D8.0020.0005.1D5CC] # MATHEMATICAL SANS-SERIF SMALL S +1D600 ; [.17D8.0020.0005.1D600] # MATHEMATICAL SANS-SERIF BOLD SMALL S +1D634 ; [.17D8.0020.0005.1D634] # MATHEMATICAL SANS-SERIF ITALIC SMALL S +1D668 ; [.17D8.0020.0005.1D668] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S +1D69C ; [.17D8.0020.0005.1D69C] # MATHEMATICAL MONOSPACE SMALL S +24E2 ; [.17D8.0020.0006.24E2] # CIRCLED LATIN SMALL LETTER S +0053 ; [.17D8.0020.0008.0053] # LATIN CAPITAL LETTER S +FF33 ; [.17D8.0020.0009.FF33] # FULLWIDTH LATIN CAPITAL LETTER S +1F122 ; [*02FB.0020.0004.1F122][.17D8.0020.000A.1F122][*02FC.0020.001F.1F122] # PARENTHESIZED LATIN CAPITAL LETTER S +1F12A ; [*0359.0020.0004.1F12A][.17D8.0020.000A.1F12A][*035A.0020.001F.1F12A] # TORTOISE SHELL BRACKETED LATIN CAPITAL LETTER S +1F1F8 ; [.17D8.0020.000A.1F1F8] # REGIONAL INDICATOR SYMBOL LETTER S +1D412 ; [.17D8.0020.000B.1D412] # MATHEMATICAL BOLD CAPITAL S +1D446 ; [.17D8.0020.000B.1D446] # MATHEMATICAL ITALIC CAPITAL S +1D47A ; [.17D8.0020.000B.1D47A] # MATHEMATICAL BOLD ITALIC CAPITAL S +1D4AE ; [.17D8.0020.000B.1D4AE] # MATHEMATICAL SCRIPT CAPITAL S +1D4E2 ; [.17D8.0020.000B.1D4E2] # MATHEMATICAL BOLD SCRIPT CAPITAL S +1D516 ; [.17D8.0020.000B.1D516] # MATHEMATICAL FRAKTUR CAPITAL S +1D54A ; [.17D8.0020.000B.1D54A] # MATHEMATICAL DOUBLE-STRUCK CAPITAL S +1D57E ; [.17D8.0020.000B.1D57E] # MATHEMATICAL BOLD FRAKTUR CAPITAL S +1D5B2 ; [.17D8.0020.000B.1D5B2] # MATHEMATICAL SANS-SERIF CAPITAL S +1D5E6 ; [.17D8.0020.000B.1D5E6] # MATHEMATICAL SANS-SERIF BOLD CAPITAL S +1D61A ; [.17D8.0020.000B.1D61A] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL S +1D64E ; [.17D8.0020.000B.1D64E] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S +1D682 ; [.17D8.0020.000B.1D682] # MATHEMATICAL MONOSPACE CAPITAL S +24C8 ; [.17D8.0020.000C.24C8] # CIRCLED LATIN CAPITAL LETTER S +1F162 ; [.17D8.0020.000C.1F162] # NEGATIVE CIRCLED LATIN CAPITAL LETTER S +02E2 ; [.17D8.0020.0014.02E2] # MODIFIER LETTER SMALL S +209B ; [.17D8.0020.0015.209B] # LATIN SUBSCRIPT SMALL LETTER S +1F142 ; [.17D8.0020.001D.1F142] # SQUARED LATIN CAPITAL LETTER S +1F182 ; [.17D8.0020.001D.1F182] # NEGATIVE SQUARED LATIN CAPITAL LETTER S +015B ; [.17D8.0020.0002.0073][.0000.0032.0002.0301] # LATIN SMALL LETTER S WITH ACUTE +015A ; [.17D8.0020.0008.0053][.0000.0032.0002.0301] # LATIN CAPITAL LETTER S WITH ACUTE +1E65 ; [.17D8.0020.0002.0073][.0000.0032.0002.0301][.0000.0052.0002.0307] # LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE +1E64 ; [.17D8.0020.0008.0053][.0000.0032.0002.0301][.0000.0052.0002.0307] # LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE +015D ; [.17D8.0020.0002.0073][.0000.003C.0002.0302] # LATIN SMALL LETTER S WITH CIRCUMFLEX +015C ; [.17D8.0020.0008.0053][.0000.003C.0002.0302] # LATIN CAPITAL LETTER S WITH CIRCUMFLEX +0161 ; [.17D8.0020.0002.0073][.0000.0041.0002.030C] # LATIN SMALL LETTER S WITH CARON +0160 ; [.17D8.0020.0008.0053][.0000.0041.0002.030C] # LATIN CAPITAL LETTER S WITH CARON +1E67 ; [.17D8.0020.0002.0073][.0000.0041.0002.030C][.0000.0052.0002.0307] # LATIN SMALL LETTER S WITH CARON AND DOT ABOVE +1E66 ; [.17D8.0020.0008.0053][.0000.0041.0002.030C][.0000.0052.0002.0307] # LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE +1E61 ; [.17D8.0020.0002.0073][.0000.0052.0002.0307] # LATIN SMALL LETTER S WITH DOT ABOVE +1E60 ; [.17D8.0020.0008.0053][.0000.0052.0002.0307] # LATIN CAPITAL LETTER S WITH DOT ABOVE +015F ; [.17D8.0020.0002.0073][.0000.0056.0002.0327] # LATIN SMALL LETTER S WITH CEDILLA +015E ; [.17D8.0020.0008.0053][.0000.0056.0002.0327] # LATIN CAPITAL LETTER S WITH CEDILLA +A7A9 ; [.17D8.0020.0004.A7A9][.0000.0061.0004.A7A9] # LATIN SMALL LETTER S WITH OBLIQUE STROKE +A7A8 ; [.17D8.0020.000A.A7A8][.0000.0061.0004.A7A8] # LATIN CAPITAL LETTER S WITH OBLIQUE STROKE +1E63 ; [.17D8.0020.0002.0073][.0000.0070.0002.0323] # LATIN SMALL LETTER S WITH DOT BELOW +1E62 ; [.17D8.0020.0008.0053][.0000.0070.0002.0323] # LATIN CAPITAL LETTER S WITH DOT BELOW +1E69 ; [.17D8.0020.0002.0073][.0000.0070.0002.0323][.0000.0052.0002.0307] # LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE +1E68 ; [.17D8.0020.0008.0053][.0000.0070.0002.0323][.0000.0052.0002.0307] # LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE +0219 ; [.17D8.0020.0002.0073][.0000.0077.0002.0326] # LATIN SMALL LETTER S WITH COMMA BELOW +0218 ; [.17D8.0020.0008.0053][.0000.0077.0002.0326] # LATIN CAPITAL LETTER S WITH COMMA BELOW +017F ; [.17D8.0020.0004.017F][.0000.013A.0004.017F] # LATIN SMALL LETTER LONG S +1DE5 ; [.17D8.0020.0004.1DE5][.0000.013A.0004.1DE5] # COMBINING LATIN SMALL LETTER LONG S +A785 ; [.17D8.0020.0004.A785][.0000.013A.0004.A785] # LATIN SMALL LETTER INSULAR S +A784 ; [.17D8.0020.000A.A784][.0000.013A.0004.A784] # LATIN CAPITAL LETTER INSULAR S +1E9B ; [.17D8.0020.0004.1E9B][.0000.013A.0004.1E9B][.0000.0052.0002.1E9B] # LATIN SMALL LETTER LONG S WITH DOT ABOVE +1F18D ; [.17D8.0020.001D.1F18D][.15D4.0020.001D.1F18D] # NEGATIVE SQUARED SA +1F14C ; [.17D8.0020.001D.1F14C][.1616.0020.001D.1F14C] # SQUARED SD +2120 ; [.17D8.0020.0014.2120][.1726.0020.0014.2120] # SERVICE MARK +1F198 ; [.17D8.0020.001D.1F198][.1756.0020.001D.1F198][.17D8.0020.001F.1F198] # SQUARED SOS +33DB ; [.17D8.0020.001C.33DB][.17A2.0020.001C.33DB] # SQUARE SR +1F14D ; [.17D8.0020.001D.1F14D][.17D8.0020.001D.1F14D] # SQUARED SS +00DF ; [.17D8.0020.0004.00DF][.0000.0139.0004.00DF][.17D8.0020.001F.00DF] # LATIN SMALL LETTER SHARP S +1E9E ; [.17D8.0020.000A.1E9E][.0000.0139.0004.1E9E][.17D8.0020.001F.1E9E] # LATIN CAPITAL LETTER SHARP S +FB06 ; [.17D8.0020.0004.FB06][.17FB.0020.0004.FB06] # LATIN SMALL LIGATURE ST +FB05 ; [.17D8.0020.0004.FB05][.0000.013A.0004.FB05][.17FB.0020.001F.FB05] # LATIN SMALL LIGATURE LONG S T +33DC ; [.17D8.0020.001D.33DC][.1844.0020.001C.33DC] # SQUARE SV +A731 ; [.17DC.0020.0002.A731] # LATIN LETTER SMALL CAPITAL S +1D74 ; [.17DD.0020.0002.1D74] # LATIN SMALL LETTER S WITH MIDDLE TILDE +1D8A ; [.17DE.0020.0002.1D8A] # LATIN SMALL LETTER S WITH PALATAL HOOK +0282 ; [.17DF.0020.0002.0282] # LATIN SMALL LETTER S WITH HOOK +1DB3 ; [.17DF.0020.0014.1DB3] # MODIFIER LETTER SMALL S WITH HOOK +023F ; [.17E3.0020.0002.023F] # LATIN SMALL LETTER S WITH SWASH TAIL +2C7E ; [.17E3.0020.0008.2C7E] # LATIN CAPITAL LETTER S WITH SWASH TAIL +1E9C ; [.17E7.0020.0002.1E9C] # LATIN SMALL LETTER LONG S WITH DIAGONAL STROKE +1E9D ; [.17E8.0020.0002.1E9D] # LATIN SMALL LETTER LONG S WITH HIGH STROKE +0283 ; [.17E9.0020.0002.0283] # LATIN SMALL LETTER ESH +01A9 ; [.17E9.0020.0008.01A9] # LATIN CAPITAL LETTER ESH +1DB4 ; [.17E9.0020.0014.1DB4] # MODIFIER LETTER SMALL ESH +1D8B ; [.17ED.0020.0002.1D8B] # LATIN SMALL LETTER ESH WITH PALATAL HOOK +01AA ; [.17EE.0020.0002.01AA] # LATIN LETTER REVERSED ESH LOOP +0285 ; [.17F2.0020.0002.0285] # LATIN SMALL LETTER SQUAT REVERSED ESH +1D98 ; [.17F6.0020.0002.1D98] # LATIN SMALL LETTER ESH WITH RETROFLEX HOOK +0286 ; [.17F7.0020.0002.0286] # LATIN SMALL LETTER ESH WITH CURL +0074 ; [.17FB.0020.0002.0074] # LATIN SMALL LETTER T +FF54 ; [.17FB.0020.0003.FF54] # FULLWIDTH LATIN SMALL LETTER T +036D ; [.17FB.0020.0004.036D] # COMBINING LATIN SMALL LETTER T +24AF ; [*02FB.0020.0004.24AF][.17FB.0020.0004.24AF][*02FC.0020.001F.24AF] # PARENTHESIZED LATIN SMALL LETTER T +1D42D ; [.17FB.0020.0005.1D42D] # MATHEMATICAL BOLD SMALL T +1D461 ; [.17FB.0020.0005.1D461] # MATHEMATICAL ITALIC SMALL T +1D495 ; [.17FB.0020.0005.1D495] # MATHEMATICAL BOLD ITALIC SMALL T +1D4C9 ; [.17FB.0020.0005.1D4C9] # MATHEMATICAL SCRIPT SMALL T +1D4FD ; [.17FB.0020.0005.1D4FD] # MATHEMATICAL BOLD SCRIPT SMALL T +1D531 ; [.17FB.0020.0005.1D531] # MATHEMATICAL FRAKTUR SMALL T +1D565 ; [.17FB.0020.0005.1D565] # MATHEMATICAL DOUBLE-STRUCK SMALL T +1D599 ; [.17FB.0020.0005.1D599] # MATHEMATICAL BOLD FRAKTUR SMALL T +1D5CD ; [.17FB.0020.0005.1D5CD] # MATHEMATICAL SANS-SERIF SMALL T +1D601 ; [.17FB.0020.0005.1D601] # MATHEMATICAL SANS-SERIF BOLD SMALL T +1D635 ; [.17FB.0020.0005.1D635] # MATHEMATICAL SANS-SERIF ITALIC SMALL T +1D669 ; [.17FB.0020.0005.1D669] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T +1D69D ; [.17FB.0020.0005.1D69D] # MATHEMATICAL MONOSPACE SMALL T +24E3 ; [.17FB.0020.0006.24E3] # CIRCLED LATIN SMALL LETTER T +0054 ; [.17FB.0020.0008.0054] # LATIN CAPITAL LETTER T +FF34 ; [.17FB.0020.0009.FF34] # FULLWIDTH LATIN CAPITAL LETTER T +1F123 ; [*02FB.0020.0004.1F123][.17FB.0020.000A.1F123][*02FC.0020.001F.1F123] # PARENTHESIZED LATIN CAPITAL LETTER T +1F1F9 ; [.17FB.0020.000A.1F1F9] # REGIONAL INDICATOR SYMBOL LETTER T +1D413 ; [.17FB.0020.000B.1D413] # MATHEMATICAL BOLD CAPITAL T +1D447 ; [.17FB.0020.000B.1D447] # MATHEMATICAL ITALIC CAPITAL T +1D47B ; [.17FB.0020.000B.1D47B] # MATHEMATICAL BOLD ITALIC CAPITAL T +1D4AF ; [.17FB.0020.000B.1D4AF] # MATHEMATICAL SCRIPT CAPITAL T +1D4E3 ; [.17FB.0020.000B.1D4E3] # MATHEMATICAL BOLD SCRIPT CAPITAL T +1D517 ; [.17FB.0020.000B.1D517] # MATHEMATICAL FRAKTUR CAPITAL T +1D54B ; [.17FB.0020.000B.1D54B] # MATHEMATICAL DOUBLE-STRUCK CAPITAL T +1D57F ; [.17FB.0020.000B.1D57F] # MATHEMATICAL BOLD FRAKTUR CAPITAL T +1D5B3 ; [.17FB.0020.000B.1D5B3] # MATHEMATICAL SANS-SERIF CAPITAL T +1D5E7 ; [.17FB.0020.000B.1D5E7] # MATHEMATICAL SANS-SERIF BOLD CAPITAL T +1D61B ; [.17FB.0020.000B.1D61B] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL T +1D64F ; [.17FB.0020.000B.1D64F] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T +1D683 ; [.17FB.0020.000B.1D683] # MATHEMATICAL MONOSPACE CAPITAL T +24C9 ; [.17FB.0020.000C.24C9] # CIRCLED LATIN CAPITAL LETTER T +1F163 ; [.17FB.0020.000C.1F163] # NEGATIVE CIRCLED LATIN CAPITAL LETTER T +1D57 ; [.17FB.0020.0014.1D57] # MODIFIER LETTER SMALL T +209C ; [.17FB.0020.0015.209C] # LATIN SUBSCRIPT SMALL LETTER T +1D40 ; [.17FB.0020.001D.1D40] # MODIFIER LETTER CAPITAL T +1F143 ; [.17FB.0020.001D.1F143] # SQUARED LATIN CAPITAL LETTER T +1F183 ; [.17FB.0020.001D.1F183] # NEGATIVE SQUARED LATIN CAPITAL LETTER T +0165 ; [.17FB.0020.0002.0074][.0000.0041.0002.030C] # LATIN SMALL LETTER T WITH CARON +0164 ; [.17FB.0020.0008.0054][.0000.0041.0002.030C] # LATIN CAPITAL LETTER T WITH CARON +1E97 ; [.17FB.0020.0002.0074][.0000.0047.0002.0308] # LATIN SMALL LETTER T WITH DIAERESIS +1E6B ; [.17FB.0020.0002.0074][.0000.0052.0002.0307] # LATIN SMALL LETTER T WITH DOT ABOVE +1E6A ; [.17FB.0020.0008.0054][.0000.0052.0002.0307] # LATIN CAPITAL LETTER T WITH DOT ABOVE +0163 ; [.17FB.0020.0002.0074][.0000.0056.0002.0327] # LATIN SMALL LETTER T WITH CEDILLA +0162 ; [.17FB.0020.0008.0054][.0000.0056.0002.0327] # LATIN CAPITAL LETTER T WITH CEDILLA +1E6D ; [.17FB.0020.0002.0074][.0000.0070.0002.0323] # LATIN SMALL LETTER T WITH DOT BELOW +1E6C ; [.17FB.0020.0008.0054][.0000.0070.0002.0323] # LATIN CAPITAL LETTER T WITH DOT BELOW +021B ; [.17FB.0020.0002.0074][.0000.0077.0002.0326] # LATIN SMALL LETTER T WITH COMMA BELOW +021A ; [.17FB.0020.0008.0054][.0000.0077.0002.0326] # LATIN CAPITAL LETTER T WITH COMMA BELOW +1E71 ; [.17FB.0020.0002.0074][.0000.0078.0002.032D] # LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW +1E70 ; [.17FB.0020.0008.0054][.0000.0078.0002.032D] # LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW +1E6F ; [.17FB.0020.0002.0074][.0000.007B.0002.0331] # LATIN SMALL LETTER T WITH LINE BELOW +1E6E ; [.17FB.0020.0008.0054][.0000.007B.0002.0331] # LATIN CAPITAL LETTER T WITH LINE BELOW +A787 ; [.17FB.0020.0004.A787][.0000.013A.0004.A787] # LATIN SMALL LETTER INSULAR T +A786 ; [.17FB.0020.000A.A786][.0000.013A.0004.A786] # LATIN CAPITAL LETTER INSULAR T +02A8 ; [.17FB.0020.0004.02A8][.1610.0020.0004.02A8] # LATIN SMALL LETTER TC DIGRAPH WITH CURL +2121 ; [.17FB.0020.000A.2121][.1631.0020.000A.2121][.16F6.0020.001F.2121] # TELEPHONE SIGN +1D7A ; [.17FB.0020.0004.1D7A][.0000.0139.0004.1D7A][.1699.0020.001F.1D7A] # LATIN SMALL LETTER TH WITH STRIKETHROUGH +3394 ; [.17FB.0020.001D.3394][.1699.0020.001D.3394][.187A.0020.001F.3394] # SQUARE THZ +2122 ; [.17FB.0020.0014.2122][.1726.0020.0014.2122] # TRADE MARK SIGN +01BE ; [.17FB.0020.0004.01BE][.17D8.0020.0004.01BE] # LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE +02A6 ; [.17FB.0020.0004.02A6][.17D8.0020.0004.02A6] # LATIN SMALL LETTER TS DIGRAPH +02A7 ; [.17FB.0020.0004.02A7][.17E9.0020.0004.02A7] # LATIN SMALL LETTER TESH DIGRAPH +A729 ; [.17FB.0020.0004.A729][.187A.0020.0004.A729] # LATIN SMALL LETTER TZ +A728 ; [.17FB.0020.000A.A728][.187A.0020.0004.A728] # LATIN CAPITAL LETTER TZ +1D1B ; [.17FF.0020.0002.1D1B] # LATIN LETTER SMALL CAPITAL T +0167 ; [.1800.0020.0002.0167] # LATIN SMALL LETTER T WITH STROKE +0166 ; [.1800.0020.0008.0166] # LATIN CAPITAL LETTER T WITH STROKE +2C66 ; [.1804.0020.0002.2C66] # LATIN SMALL LETTER T WITH DIAGONAL STROKE +023E ; [.1804.0020.0008.023E] # LATIN CAPITAL LETTER T WITH DIAGONAL STROKE +1D75 ; [.1805.0020.0002.1D75] # LATIN SMALL LETTER T WITH MIDDLE TILDE +01AB ; [.1806.0020.0002.01AB] # LATIN SMALL LETTER T WITH PALATAL HOOK +1DB5 ; [.1806.0020.0014.1DB5] # MODIFIER LETTER SMALL T WITH PALATAL HOOK +01AD ; [.180A.0020.0002.01AD] # LATIN SMALL LETTER T WITH HOOK +01AC ; [.180A.0020.0008.01AC] # LATIN CAPITAL LETTER T WITH HOOK +0288 ; [.180E.0020.0002.0288] # LATIN SMALL LETTER T WITH RETROFLEX HOOK +01AE ; [.180E.0020.0008.01AE] # LATIN CAPITAL LETTER T WITH RETROFLEX HOOK +0236 ; [.1812.0020.0002.0236] # LATIN SMALL LETTER T WITH CURL +A777 ; [.1816.0020.0002.A777] # LATIN SMALL LETTER TUM +0287 ; [.1817.0020.0002.0287] # LATIN SMALL LETTER TURNED T +0075 ; [.181B.0020.0002.0075] # LATIN SMALL LETTER U +FF55 ; [.181B.0020.0003.FF55] # FULLWIDTH LATIN SMALL LETTER U +0367 ; [.181B.0020.0004.0367] # COMBINING LATIN SMALL LETTER U +24B0 ; [*02FB.0020.0004.24B0][.181B.0020.0004.24B0][*02FC.0020.001F.24B0] # PARENTHESIZED LATIN SMALL LETTER U +1D42E ; [.181B.0020.0005.1D42E] # MATHEMATICAL BOLD SMALL U +1D462 ; [.181B.0020.0005.1D462] # MATHEMATICAL ITALIC SMALL U +1D496 ; [.181B.0020.0005.1D496] # MATHEMATICAL BOLD ITALIC SMALL U +1D4CA ; [.181B.0020.0005.1D4CA] # MATHEMATICAL SCRIPT SMALL U +1D4FE ; [.181B.0020.0005.1D4FE] # MATHEMATICAL BOLD SCRIPT SMALL U +1D532 ; [.181B.0020.0005.1D532] # MATHEMATICAL FRAKTUR SMALL U +1D566 ; [.181B.0020.0005.1D566] # MATHEMATICAL DOUBLE-STRUCK SMALL U +1D59A ; [.181B.0020.0005.1D59A] # MATHEMATICAL BOLD FRAKTUR SMALL U +1D5CE ; [.181B.0020.0005.1D5CE] # MATHEMATICAL SANS-SERIF SMALL U +1D602 ; [.181B.0020.0005.1D602] # MATHEMATICAL SANS-SERIF BOLD SMALL U +1D636 ; [.181B.0020.0005.1D636] # MATHEMATICAL SANS-SERIF ITALIC SMALL U +1D66A ; [.181B.0020.0005.1D66A] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U +1D69E ; [.181B.0020.0005.1D69E] # MATHEMATICAL MONOSPACE SMALL U +24E4 ; [.181B.0020.0006.24E4] # CIRCLED LATIN SMALL LETTER U +0055 ; [.181B.0020.0008.0055] # LATIN CAPITAL LETTER U +FF35 ; [.181B.0020.0009.FF35] # FULLWIDTH LATIN CAPITAL LETTER U +1F124 ; [*02FB.0020.0004.1F124][.181B.0020.000A.1F124][*02FC.0020.001F.1F124] # PARENTHESIZED LATIN CAPITAL LETTER U +1F1FA ; [.181B.0020.000A.1F1FA] # REGIONAL INDICATOR SYMBOL LETTER U +1D414 ; [.181B.0020.000B.1D414] # MATHEMATICAL BOLD CAPITAL U +1D448 ; [.181B.0020.000B.1D448] # MATHEMATICAL ITALIC CAPITAL U +1D47C ; [.181B.0020.000B.1D47C] # MATHEMATICAL BOLD ITALIC CAPITAL U +1D4B0 ; [.181B.0020.000B.1D4B0] # MATHEMATICAL SCRIPT CAPITAL U +1D4E4 ; [.181B.0020.000B.1D4E4] # MATHEMATICAL BOLD SCRIPT CAPITAL U +1D518 ; [.181B.0020.000B.1D518] # MATHEMATICAL FRAKTUR CAPITAL U +1D54C ; [.181B.0020.000B.1D54C] # MATHEMATICAL DOUBLE-STRUCK CAPITAL U +1D580 ; [.181B.0020.000B.1D580] # MATHEMATICAL BOLD FRAKTUR CAPITAL U +1D5B4 ; [.181B.0020.000B.1D5B4] # MATHEMATICAL SANS-SERIF CAPITAL U +1D5E8 ; [.181B.0020.000B.1D5E8] # MATHEMATICAL SANS-SERIF BOLD CAPITAL U +1D61C ; [.181B.0020.000B.1D61C] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL U +1D650 ; [.181B.0020.000B.1D650] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U +1D684 ; [.181B.0020.000B.1D684] # MATHEMATICAL MONOSPACE CAPITAL U +24CA ; [.181B.0020.000C.24CA] # CIRCLED LATIN CAPITAL LETTER U +1F164 ; [.181B.0020.000C.1F164] # NEGATIVE CIRCLED LATIN CAPITAL LETTER U +1D58 ; [.181B.0020.0014.1D58] # MODIFIER LETTER SMALL U +1D64 ; [.181B.0020.0015.1D64] # LATIN SUBSCRIPT SMALL LETTER U +1D41 ; [.181B.0020.001D.1D41] # MODIFIER LETTER CAPITAL U +1F144 ; [.181B.0020.001D.1F144] # SQUARED LATIN CAPITAL LETTER U +1F184 ; [.181B.0020.001D.1F184] # NEGATIVE SQUARED LATIN CAPITAL LETTER U +00FA ; [.181B.0020.0002.0075][.0000.0032.0002.0301] # LATIN SMALL LETTER U WITH ACUTE +00DA ; [.181B.0020.0008.0055][.0000.0032.0002.0301] # LATIN CAPITAL LETTER U WITH ACUTE +00F9 ; [.181B.0020.0002.0075][.0000.0035.0002.0300] # LATIN SMALL LETTER U WITH GRAVE +00D9 ; [.181B.0020.0008.0055][.0000.0035.0002.0300] # LATIN CAPITAL LETTER U WITH GRAVE +016D ; [.181B.0020.0002.0075][.0000.0037.0002.0306] # LATIN SMALL LETTER U WITH BREVE +016C ; [.181B.0020.0008.0055][.0000.0037.0002.0306] # LATIN CAPITAL LETTER U WITH BREVE +00FB ; [.181B.0020.0002.0075][.0000.003C.0002.0302] # LATIN SMALL LETTER U WITH CIRCUMFLEX +00DB ; [.181B.0020.0008.0055][.0000.003C.0002.0302] # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +01D4 ; [.181B.0020.0002.0075][.0000.0041.0002.030C] # LATIN SMALL LETTER U WITH CARON +01D3 ; [.181B.0020.0008.0055][.0000.0041.0002.030C] # LATIN CAPITAL LETTER U WITH CARON +016F ; [.181B.0020.0002.0075][.0000.0043.0002.030A] # LATIN SMALL LETTER U WITH RING ABOVE +016E ; [.181B.0020.0008.0055][.0000.0043.0002.030A] # LATIN CAPITAL LETTER U WITH RING ABOVE +00FC ; [.181B.0020.0002.0075][.0000.0047.0002.0308] # LATIN SMALL LETTER U WITH DIAERESIS +00DC ; [.181B.0020.0008.0055][.0000.0047.0002.0308] # LATIN CAPITAL LETTER U WITH DIAERESIS +01D8 ; [.181B.0020.0002.0075][.0000.0047.0002.0308][.0000.0032.0002.0301] # LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE +01D7 ; [.181B.0020.0008.0055][.0000.0047.0002.0308][.0000.0032.0002.0301] # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE +01DC ; [.181B.0020.0002.0075][.0000.0047.0002.0308][.0000.0035.0002.0300] # LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE +01DB ; [.181B.0020.0008.0055][.0000.0047.0002.0308][.0000.0035.0002.0300] # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE +01DA ; [.181B.0020.0002.0075][.0000.0047.0002.0308][.0000.0041.0002.030C] # LATIN SMALL LETTER U WITH DIAERESIS AND CARON +01D9 ; [.181B.0020.0008.0055][.0000.0047.0002.0308][.0000.0041.0002.030C] # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON +01D6 ; [.181B.0020.0002.0075][.0000.0047.0002.0308][.0000.005B.0002.0304] # LATIN SMALL LETTER U WITH DIAERESIS AND MACRON +01D5 ; [.181B.0020.0008.0055][.0000.0047.0002.0308][.0000.005B.0002.0304] # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON +0171 ; [.181B.0020.0002.0075][.0000.004D.0002.030B] # LATIN SMALL LETTER U WITH DOUBLE ACUTE +0170 ; [.181B.0020.0008.0055][.0000.004D.0002.030B] # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0169 ; [.181B.0020.0002.0075][.0000.004E.0002.0303] # LATIN SMALL LETTER U WITH TILDE +0168 ; [.181B.0020.0008.0055][.0000.004E.0002.0303] # LATIN CAPITAL LETTER U WITH TILDE +1E79 ; [.181B.0020.0002.0075][.0000.004E.0002.0303][.0000.0032.0002.0301] # LATIN SMALL LETTER U WITH TILDE AND ACUTE +1E78 ; [.181B.0020.0008.0055][.0000.004E.0002.0303][.0000.0032.0002.0301] # LATIN CAPITAL LETTER U WITH TILDE AND ACUTE +0173 ; [.181B.0020.0002.0075][.0000.0059.0002.0328] # LATIN SMALL LETTER U WITH OGONEK +0172 ; [.181B.0020.0008.0055][.0000.0059.0002.0328] # LATIN CAPITAL LETTER U WITH OGONEK +016B ; [.181B.0020.0002.0075][.0000.005B.0002.0304] # LATIN SMALL LETTER U WITH MACRON +016A ; [.181B.0020.0008.0055][.0000.005B.0002.0304] # LATIN CAPITAL LETTER U WITH MACRON +1E7B ; [.181B.0020.0002.0075][.0000.005B.0002.0304][.0000.0047.0002.0308] # LATIN SMALL LETTER U WITH MACRON AND DIAERESIS +1E7A ; [.181B.0020.0008.0055][.0000.005B.0002.0304][.0000.0047.0002.0308] # LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS +1EE7 ; [.181B.0020.0002.0075][.0000.0064.0002.0309] # LATIN SMALL LETTER U WITH HOOK ABOVE +1EE6 ; [.181B.0020.0008.0055][.0000.0064.0002.0309] # LATIN CAPITAL LETTER U WITH HOOK ABOVE +0215 ; [.181B.0020.0002.0075][.0000.0065.0002.030F] # LATIN SMALL LETTER U WITH DOUBLE GRAVE +0214 ; [.181B.0020.0008.0055][.0000.0065.0002.030F] # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE +0217 ; [.181B.0020.0002.0075][.0000.0067.0002.0311] # LATIN SMALL LETTER U WITH INVERTED BREVE +0216 ; [.181B.0020.0008.0055][.0000.0067.0002.0311] # LATIN CAPITAL LETTER U WITH INVERTED BREVE +01B0 ; [.181B.0020.0002.0075][.0000.0068.0002.031B] # LATIN SMALL LETTER U WITH HORN +01AF ; [.181B.0020.0008.0055][.0000.0068.0002.031B] # LATIN CAPITAL LETTER U WITH HORN +1EE9 ; [.181B.0020.0002.0075][.0000.0068.0002.031B][.0000.0032.0002.0301] # LATIN SMALL LETTER U WITH HORN AND ACUTE +1EE8 ; [.181B.0020.0008.0055][.0000.0068.0002.031B][.0000.0032.0002.0301] # LATIN CAPITAL LETTER U WITH HORN AND ACUTE +1EEB ; [.181B.0020.0002.0075][.0000.0068.0002.031B][.0000.0035.0002.0300] # LATIN SMALL LETTER U WITH HORN AND GRAVE +1EEA ; [.181B.0020.0008.0055][.0000.0068.0002.031B][.0000.0035.0002.0300] # LATIN CAPITAL LETTER U WITH HORN AND GRAVE +1EEF ; [.181B.0020.0002.0075][.0000.0068.0002.031B][.0000.004E.0002.0303] # LATIN SMALL LETTER U WITH HORN AND TILDE +1EEE ; [.181B.0020.0008.0055][.0000.0068.0002.031B][.0000.004E.0002.0303] # LATIN CAPITAL LETTER U WITH HORN AND TILDE +1EED ; [.181B.0020.0002.0075][.0000.0068.0002.031B][.0000.0064.0002.0309] # LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE +1EEC ; [.181B.0020.0008.0055][.0000.0068.0002.031B][.0000.0064.0002.0309] # LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE +1EF1 ; [.181B.0020.0002.0075][.0000.0068.0002.031B][.0000.0070.0002.0323] # LATIN SMALL LETTER U WITH HORN AND DOT BELOW +1EF0 ; [.181B.0020.0008.0055][.0000.0068.0002.031B][.0000.0070.0002.0323] # LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW +1EE5 ; [.181B.0020.0002.0075][.0000.0070.0002.0323] # LATIN SMALL LETTER U WITH DOT BELOW +1EE4 ; [.181B.0020.0008.0055][.0000.0070.0002.0323] # LATIN CAPITAL LETTER U WITH DOT BELOW +1E73 ; [.181B.0020.0002.0075][.0000.0075.0002.0324] # LATIN SMALL LETTER U WITH DIAERESIS BELOW +1E72 ; [.181B.0020.0008.0055][.0000.0075.0002.0324] # LATIN CAPITAL LETTER U WITH DIAERESIS BELOW +1E77 ; [.181B.0020.0002.0075][.0000.0078.0002.032D] # LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW +1E76 ; [.181B.0020.0008.0055][.0000.0078.0002.032D] # LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW +1E75 ; [.181B.0020.0002.0075][.0000.007A.0002.0330] # LATIN SMALL LETTER U WITH TILDE BELOW +1E74 ; [.181B.0020.0008.0055][.0000.007A.0002.0330] # LATIN CAPITAL LETTER U WITH TILDE BELOW +1F199 ; [.181B.0020.001D.1F199][.177B.0020.001D.1F199][*025E.0020.001F.1F199] # SQUARED UP WITH EXCLAMATION MARK +1D1C ; [.181F.0020.0002.1D1C] # LATIN LETTER SMALL CAPITAL U +1DB8 ; [.181F.0020.0014.1DB8] # MODIFIER LETTER SMALL CAPITAL U +1D1D ; [.1820.0020.0002.1D1D] # LATIN SMALL LETTER SIDEWAYS U +1D59 ; [.1820.0020.0014.1D59] # MODIFIER LETTER SMALL SIDEWAYS U +1D1E ; [.1821.0020.0002.1D1E] # LATIN SMALL LETTER SIDEWAYS DIAERESIZED U +1D6B ; [.1822.0020.0002.1D6B] # LATIN SMALL LETTER UE +0289 ; [.1823.0020.0002.0289] # LATIN SMALL LETTER U BAR +0244 ; [.1823.0020.0008.0244] # LATIN CAPITAL LETTER U BAR +1DB6 ; [.1823.0020.0014.1DB6] # MODIFIER LETTER SMALL U BAR +1D7E ; [.1827.0020.0002.1D7E] # LATIN SMALL CAPITAL LETTER U WITH STROKE +1D99 ; [.1828.0020.0002.1D99] # LATIN SMALL LETTER U WITH RETROFLEX HOOK +0265 ; [.1829.0020.0002.0265] # LATIN SMALL LETTER TURNED H +A78D ; [.1829.0020.0008.A78D] # LATIN CAPITAL LETTER TURNED H +1DA3 ; [.1829.0020.0014.1DA3] # MODIFIER LETTER SMALL TURNED H +02AE ; [.182D.0020.0002.02AE] # LATIN SMALL LETTER TURNED H WITH FISHHOOK +02AF ; [.1831.0020.0002.02AF] # LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL +026F ; [.1835.0020.0002.026F] # LATIN SMALL LETTER TURNED M +019C ; [.1835.0020.0008.019C] # LATIN CAPITAL LETTER TURNED M +1D5A ; [.1835.0020.0014.1D5A] # MODIFIER LETTER SMALL TURNED M +A7FA ; [.1839.0020.0002.A7FA] # LATIN LETTER SMALL CAPITAL TURNED M +1D1F ; [.183A.0020.0002.1D1F] # LATIN SMALL LETTER SIDEWAYS TURNED M +0270 ; [.183B.0020.0002.0270] # LATIN SMALL LETTER TURNED M WITH LONG LEG +1DAD ; [.183B.0020.0014.1DAD] # MODIFIER LETTER SMALL TURNED M WITH LONG LEG +028A ; [.183F.0020.0002.028A] # LATIN SMALL LETTER UPSILON +01B1 ; [.183F.0020.0008.01B1] # LATIN CAPITAL LETTER UPSILON +1DB7 ; [.183F.0020.0014.1DB7] # MODIFIER LETTER SMALL UPSILON +1D7F ; [.1843.0020.0002.1D7F] # LATIN SMALL LETTER UPSILON WITH STROKE +0076 ; [.1844.0020.0002.0076] # LATIN SMALL LETTER V +FF56 ; [.1844.0020.0003.FF56] # FULLWIDTH LATIN SMALL LETTER V +036E ; [.1844.0020.0004.036E] # COMBINING LATIN SMALL LETTER V +2174 ; [.1844.0020.0004.2174] # SMALL ROMAN NUMERAL FIVE +24B1 ; [*02FB.0020.0004.24B1][.1844.0020.0004.24B1][*02FC.0020.001F.24B1] # PARENTHESIZED LATIN SMALL LETTER V +1D42F ; [.1844.0020.0005.1D42F] # MATHEMATICAL BOLD SMALL V +1D463 ; [.1844.0020.0005.1D463] # MATHEMATICAL ITALIC SMALL V +1D497 ; [.1844.0020.0005.1D497] # MATHEMATICAL BOLD ITALIC SMALL V +1D4CB ; [.1844.0020.0005.1D4CB] # MATHEMATICAL SCRIPT SMALL V +1D4FF ; [.1844.0020.0005.1D4FF] # MATHEMATICAL BOLD SCRIPT SMALL V +1D533 ; [.1844.0020.0005.1D533] # MATHEMATICAL FRAKTUR SMALL V +1D567 ; [.1844.0020.0005.1D567] # MATHEMATICAL DOUBLE-STRUCK SMALL V +1D59B ; [.1844.0020.0005.1D59B] # MATHEMATICAL BOLD FRAKTUR SMALL V +1D5CF ; [.1844.0020.0005.1D5CF] # MATHEMATICAL SANS-SERIF SMALL V +1D603 ; [.1844.0020.0005.1D603] # MATHEMATICAL SANS-SERIF BOLD SMALL V +1D637 ; [.1844.0020.0005.1D637] # MATHEMATICAL SANS-SERIF ITALIC SMALL V +1D66B ; [.1844.0020.0005.1D66B] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V +1D69F ; [.1844.0020.0005.1D69F] # MATHEMATICAL MONOSPACE SMALL V +24E5 ; [.1844.0020.0006.24E5] # CIRCLED LATIN SMALL LETTER V +0056 ; [.1844.0020.0008.0056] # LATIN CAPITAL LETTER V +FF36 ; [.1844.0020.0009.FF36] # FULLWIDTH LATIN CAPITAL LETTER V +2164 ; [.1844.0020.000A.2164] # ROMAN NUMERAL FIVE +1F125 ; [*02FB.0020.0004.1F125][.1844.0020.000A.1F125][*02FC.0020.001F.1F125] # PARENTHESIZED LATIN CAPITAL LETTER V +1F1FB ; [.1844.0020.000A.1F1FB] # REGIONAL INDICATOR SYMBOL LETTER V +1D415 ; [.1844.0020.000B.1D415] # MATHEMATICAL BOLD CAPITAL V +1D449 ; [.1844.0020.000B.1D449] # MATHEMATICAL ITALIC CAPITAL V +1D47D ; [.1844.0020.000B.1D47D] # MATHEMATICAL BOLD ITALIC CAPITAL V +1D4B1 ; [.1844.0020.000B.1D4B1] # MATHEMATICAL SCRIPT CAPITAL V +1D4E5 ; [.1844.0020.000B.1D4E5] # MATHEMATICAL BOLD SCRIPT CAPITAL V +1D519 ; [.1844.0020.000B.1D519] # MATHEMATICAL FRAKTUR CAPITAL V +1D54D ; [.1844.0020.000B.1D54D] # MATHEMATICAL DOUBLE-STRUCK CAPITAL V +1D581 ; [.1844.0020.000B.1D581] # MATHEMATICAL BOLD FRAKTUR CAPITAL V +1D5B5 ; [.1844.0020.000B.1D5B5] # MATHEMATICAL SANS-SERIF CAPITAL V +1D5E9 ; [.1844.0020.000B.1D5E9] # MATHEMATICAL SANS-SERIF BOLD CAPITAL V +1D61D ; [.1844.0020.000B.1D61D] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL V +1D651 ; [.1844.0020.000B.1D651] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V +1D685 ; [.1844.0020.000B.1D685] # MATHEMATICAL MONOSPACE CAPITAL V +24CB ; [.1844.0020.000C.24CB] # CIRCLED LATIN CAPITAL LETTER V +1F165 ; [.1844.0020.000C.1F165] # NEGATIVE CIRCLED LATIN CAPITAL LETTER V +1D5B ; [.1844.0020.0014.1D5B] # MODIFIER LETTER SMALL V +1D65 ; [.1844.0020.0015.1D65] # LATIN SUBSCRIPT SMALL LETTER V +2C7D ; [.1844.0020.001D.2C7D] # MODIFIER LETTER CAPITAL V +1F145 ; [.1844.0020.001D.1F145] # SQUARED LATIN CAPITAL LETTER V +1F185 ; [.1844.0020.001D.1F185] # NEGATIVE SQUARED LATIN CAPITAL LETTER V +1E7D ; [.1844.0020.0002.0076][.0000.004E.0002.0303] # LATIN SMALL LETTER V WITH TILDE +1E7C ; [.1844.0020.0008.0056][.0000.004E.0002.0303] # LATIN CAPITAL LETTER V WITH TILDE +1E7F ; [.1844.0020.0002.0076][.0000.0070.0002.0323] # LATIN SMALL LETTER V WITH DOT BELOW +1E7E ; [.1844.0020.0008.0056][.0000.0070.0002.0323] # LATIN CAPITAL LETTER V WITH DOT BELOW +2175 ; [.1844.0020.0004.2175][.16B2.0020.0004.2175] # SMALL ROMAN NUMERAL SIX +2165 ; [.1844.0020.000A.2165][.16B2.0020.000A.2165] # ROMAN NUMERAL SIX +2176 ; [.1844.0020.0004.2176][.16B2.0020.0004.2176][.16B2.0020.001F.2176] # SMALL ROMAN NUMERAL SEVEN +2166 ; [.1844.0020.000A.2166][.16B2.0020.000A.2166][.16B2.0020.001F.2166] # ROMAN NUMERAL SEVEN +2177 ; [.1844.0020.0004.2177][.16B2.0020.0004.2177][.16B2.0020.001F.2177][.16B2.0020.001F.2177] # SMALL ROMAN NUMERAL EIGHT +2167 ; [.1844.0020.000A.2167][.16B2.0020.000A.2167][.16B2.0020.001F.2167][.16B2.0020.001F.2167] # ROMAN NUMERAL EIGHT +33DE ; [.1844.0020.001D.33DE][*05AB.0020.001C.33DE][.1726.0020.001F.33DE] # SQUARE V OVER M +1F19A ; [.1844.0020.001D.1F19A][.17D8.0020.001D.1F19A] # SQUARED VS +A761 ; [.1844.0020.0004.A761][.1865.0020.0004.A761] # LATIN SMALL LETTER VY +A760 ; [.1844.0020.000A.A760][.1865.0020.000A.A760] # LATIN CAPITAL LETTER VY +1D20 ; [.1848.0020.0002.1D20] # LATIN LETTER SMALL CAPITAL V +A75F ; [.1849.0020.0002.A75F] # LATIN SMALL LETTER V WITH DIAGONAL STROKE +A75E ; [.1849.0020.0008.A75E] # LATIN CAPITAL LETTER V WITH DIAGONAL STROKE +1D8C ; [.184A.0020.0002.1D8C] # LATIN SMALL LETTER V WITH PALATAL HOOK +028B ; [.184B.0020.0002.028B] # LATIN SMALL LETTER V WITH HOOK +01B2 ; [.184B.0020.0008.01B2] # LATIN CAPITAL LETTER V WITH HOOK +1DB9 ; [.184B.0020.0014.1DB9] # MODIFIER LETTER SMALL V WITH HOOK +2C71 ; [.184F.0020.0002.2C71] # LATIN SMALL LETTER V WITH RIGHT HOOK +2C74 ; [.1850.0020.0002.2C74] # LATIN SMALL LETTER V WITH CURL +1EFD ; [.1851.0020.0002.1EFD] # LATIN SMALL LETTER MIDDLE-WELSH V +1EFC ; [.1851.0020.0008.1EFC] # LATIN CAPITAL LETTER MIDDLE-WELSH V +028C ; [.1852.0020.0002.028C] # LATIN SMALL LETTER TURNED V +0245 ; [.1852.0020.0008.0245] # LATIN CAPITAL LETTER TURNED V +1DBA ; [.1852.0020.0014.1DBA] # MODIFIER LETTER SMALL TURNED V +0077 ; [.1856.0020.0002.0077] # LATIN SMALL LETTER W +FF57 ; [.1856.0020.0003.FF57] # FULLWIDTH LATIN SMALL LETTER W +24B2 ; [*02FB.0020.0004.24B2][.1856.0020.0004.24B2][*02FC.0020.001F.24B2] # PARENTHESIZED LATIN SMALL LETTER W +1D430 ; [.1856.0020.0005.1D430] # MATHEMATICAL BOLD SMALL W +1D464 ; [.1856.0020.0005.1D464] # MATHEMATICAL ITALIC SMALL W +1D498 ; [.1856.0020.0005.1D498] # MATHEMATICAL BOLD ITALIC SMALL W +1D4CC ; [.1856.0020.0005.1D4CC] # MATHEMATICAL SCRIPT SMALL W +1D500 ; [.1856.0020.0005.1D500] # MATHEMATICAL BOLD SCRIPT SMALL W +1D534 ; [.1856.0020.0005.1D534] # MATHEMATICAL FRAKTUR SMALL W +1D568 ; [.1856.0020.0005.1D568] # MATHEMATICAL DOUBLE-STRUCK SMALL W +1D59C ; [.1856.0020.0005.1D59C] # MATHEMATICAL BOLD FRAKTUR SMALL W +1D5D0 ; [.1856.0020.0005.1D5D0] # MATHEMATICAL SANS-SERIF SMALL W +1D604 ; [.1856.0020.0005.1D604] # MATHEMATICAL SANS-SERIF BOLD SMALL W +1D638 ; [.1856.0020.0005.1D638] # MATHEMATICAL SANS-SERIF ITALIC SMALL W +1D66C ; [.1856.0020.0005.1D66C] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W +1D6A0 ; [.1856.0020.0005.1D6A0] # MATHEMATICAL MONOSPACE SMALL W +24E6 ; [.1856.0020.0006.24E6] # CIRCLED LATIN SMALL LETTER W +0057 ; [.1856.0020.0008.0057] # LATIN CAPITAL LETTER W +FF37 ; [.1856.0020.0009.FF37] # FULLWIDTH LATIN CAPITAL LETTER W +1F126 ; [*02FB.0020.0004.1F126][.1856.0020.000A.1F126][*02FC.0020.001F.1F126] # PARENTHESIZED LATIN CAPITAL LETTER W +1F1FC ; [.1856.0020.000A.1F1FC] # REGIONAL INDICATOR SYMBOL LETTER W +1D416 ; [.1856.0020.000B.1D416] # MATHEMATICAL BOLD CAPITAL W +1D44A ; [.1856.0020.000B.1D44A] # MATHEMATICAL ITALIC CAPITAL W +1D47E ; [.1856.0020.000B.1D47E] # MATHEMATICAL BOLD ITALIC CAPITAL W +1D4B2 ; [.1856.0020.000B.1D4B2] # MATHEMATICAL SCRIPT CAPITAL W +1D4E6 ; [.1856.0020.000B.1D4E6] # MATHEMATICAL BOLD SCRIPT CAPITAL W +1D51A ; [.1856.0020.000B.1D51A] # MATHEMATICAL FRAKTUR CAPITAL W +1D54E ; [.1856.0020.000B.1D54E] # MATHEMATICAL DOUBLE-STRUCK CAPITAL W +1D582 ; [.1856.0020.000B.1D582] # MATHEMATICAL BOLD FRAKTUR CAPITAL W +1D5B6 ; [.1856.0020.000B.1D5B6] # MATHEMATICAL SANS-SERIF CAPITAL W +1D5EA ; [.1856.0020.000B.1D5EA] # MATHEMATICAL SANS-SERIF BOLD CAPITAL W +1D61E ; [.1856.0020.000B.1D61E] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL W +1D652 ; [.1856.0020.000B.1D652] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W +1D686 ; [.1856.0020.000B.1D686] # MATHEMATICAL MONOSPACE CAPITAL W +24CC ; [.1856.0020.000C.24CC] # CIRCLED LATIN CAPITAL LETTER W +1F166 ; [.1856.0020.000C.1F166] # NEGATIVE CIRCLED LATIN CAPITAL LETTER W +02B7 ; [.1856.0020.0014.02B7] # MODIFIER LETTER SMALL W +1D42 ; [.1856.0020.001D.1D42] # MODIFIER LETTER CAPITAL W +1F146 ; [.1856.0020.001D.1F146] # SQUARED LATIN CAPITAL LETTER W +1F186 ; [.1856.0020.001D.1F186] # NEGATIVE SQUARED LATIN CAPITAL LETTER W +1E83 ; [.1856.0020.0002.0077][.0000.0032.0002.0301] # LATIN SMALL LETTER W WITH ACUTE +1E82 ; [.1856.0020.0008.0057][.0000.0032.0002.0301] # LATIN CAPITAL LETTER W WITH ACUTE +1E81 ; [.1856.0020.0002.0077][.0000.0035.0002.0300] # LATIN SMALL LETTER W WITH GRAVE +1E80 ; [.1856.0020.0008.0057][.0000.0035.0002.0300] # LATIN CAPITAL LETTER W WITH GRAVE +0175 ; [.1856.0020.0002.0077][.0000.003C.0002.0302] # LATIN SMALL LETTER W WITH CIRCUMFLEX +0174 ; [.1856.0020.0008.0057][.0000.003C.0002.0302] # LATIN CAPITAL LETTER W WITH CIRCUMFLEX +1E98 ; [.1856.0020.0002.0077][.0000.0043.0002.030A] # LATIN SMALL LETTER W WITH RING ABOVE +1E85 ; [.1856.0020.0002.0077][.0000.0047.0002.0308] # LATIN SMALL LETTER W WITH DIAERESIS +1E84 ; [.1856.0020.0008.0057][.0000.0047.0002.0308] # LATIN CAPITAL LETTER W WITH DIAERESIS +1E87 ; [.1856.0020.0002.0077][.0000.0052.0002.0307] # LATIN SMALL LETTER W WITH DOT ABOVE +1E86 ; [.1856.0020.0008.0057][.0000.0052.0002.0307] # LATIN CAPITAL LETTER W WITH DOT ABOVE +1E89 ; [.1856.0020.0002.0077][.0000.0070.0002.0323] # LATIN SMALL LETTER W WITH DOT BELOW +1E88 ; [.1856.0020.0008.0057][.0000.0070.0002.0323] # LATIN CAPITAL LETTER W WITH DOT BELOW +33DD ; [.1856.0020.001D.33DD][.15EA.0020.001C.33DD] # SQUARE WB +1F14F ; [.1856.0020.001D.1F14F][.1602.0020.001D.1F14F] # SQUARED WC +1F18F ; [.1856.0020.001D.1F18F][.1602.0020.001D.1F18F] # NEGATIVE SQUARED WC +1F12E ; [.1856.0020.000C.1F12E][.187A.0020.000C.1F12E] # CIRCLED WZ +1D21 ; [.185A.0020.0002.1D21] # LATIN LETTER SMALL CAPITAL W +2C73 ; [.185B.0020.0002.2C73] # LATIN SMALL LETTER W WITH HOOK +2C72 ; [.185B.0020.0008.2C72] # LATIN CAPITAL LETTER W WITH HOOK +028D ; [.185C.0020.0002.028D] # LATIN SMALL LETTER TURNED W +0078 ; [.1860.0020.0002.0078] # LATIN SMALL LETTER X +FF58 ; [.1860.0020.0003.FF58] # FULLWIDTH LATIN SMALL LETTER X +036F ; [.1860.0020.0004.036F] # COMBINING LATIN SMALL LETTER X +2179 ; [.1860.0020.0004.2179] # SMALL ROMAN NUMERAL TEN +24B3 ; [*02FB.0020.0004.24B3][.1860.0020.0004.24B3][*02FC.0020.001F.24B3] # PARENTHESIZED LATIN SMALL LETTER X +1D431 ; [.1860.0020.0005.1D431] # MATHEMATICAL BOLD SMALL X +1D465 ; [.1860.0020.0005.1D465] # MATHEMATICAL ITALIC SMALL X +1D499 ; [.1860.0020.0005.1D499] # MATHEMATICAL BOLD ITALIC SMALL X +1D4CD ; [.1860.0020.0005.1D4CD] # MATHEMATICAL SCRIPT SMALL X +1D501 ; [.1860.0020.0005.1D501] # MATHEMATICAL BOLD SCRIPT SMALL X +1D535 ; [.1860.0020.0005.1D535] # MATHEMATICAL FRAKTUR SMALL X +1D569 ; [.1860.0020.0005.1D569] # MATHEMATICAL DOUBLE-STRUCK SMALL X +1D59D ; [.1860.0020.0005.1D59D] # MATHEMATICAL BOLD FRAKTUR SMALL X +1D5D1 ; [.1860.0020.0005.1D5D1] # MATHEMATICAL SANS-SERIF SMALL X +1D605 ; [.1860.0020.0005.1D605] # MATHEMATICAL SANS-SERIF BOLD SMALL X +1D639 ; [.1860.0020.0005.1D639] # MATHEMATICAL SANS-SERIF ITALIC SMALL X +1D66D ; [.1860.0020.0005.1D66D] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X +1D6A1 ; [.1860.0020.0005.1D6A1] # MATHEMATICAL MONOSPACE SMALL X +24E7 ; [.1860.0020.0006.24E7] # CIRCLED LATIN SMALL LETTER X +0058 ; [.1860.0020.0008.0058] # LATIN CAPITAL LETTER X +FF38 ; [.1860.0020.0009.FF38] # FULLWIDTH LATIN CAPITAL LETTER X +2169 ; [.1860.0020.000A.2169] # ROMAN NUMERAL TEN +1F127 ; [*02FB.0020.0004.1F127][.1860.0020.000A.1F127][*02FC.0020.001F.1F127] # PARENTHESIZED LATIN CAPITAL LETTER X +1F1FD ; [.1860.0020.000A.1F1FD] # REGIONAL INDICATOR SYMBOL LETTER X +1D417 ; [.1860.0020.000B.1D417] # MATHEMATICAL BOLD CAPITAL X +1D44B ; [.1860.0020.000B.1D44B] # MATHEMATICAL ITALIC CAPITAL X +1D47F ; [.1860.0020.000B.1D47F] # MATHEMATICAL BOLD ITALIC CAPITAL X +1D4B3 ; [.1860.0020.000B.1D4B3] # MATHEMATICAL SCRIPT CAPITAL X +1D4E7 ; [.1860.0020.000B.1D4E7] # MATHEMATICAL BOLD SCRIPT CAPITAL X +1D51B ; [.1860.0020.000B.1D51B] # MATHEMATICAL FRAKTUR CAPITAL X +1D54F ; [.1860.0020.000B.1D54F] # MATHEMATICAL DOUBLE-STRUCK CAPITAL X +1D583 ; [.1860.0020.000B.1D583] # MATHEMATICAL BOLD FRAKTUR CAPITAL X +1D5B7 ; [.1860.0020.000B.1D5B7] # MATHEMATICAL SANS-SERIF CAPITAL X +1D5EB ; [.1860.0020.000B.1D5EB] # MATHEMATICAL SANS-SERIF BOLD CAPITAL X +1D61F ; [.1860.0020.000B.1D61F] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL X +1D653 ; [.1860.0020.000B.1D653] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X +1D687 ; [.1860.0020.000B.1D687] # MATHEMATICAL MONOSPACE CAPITAL X +24CD ; [.1860.0020.000C.24CD] # CIRCLED LATIN CAPITAL LETTER X +1F167 ; [.1860.0020.000C.1F167] # NEGATIVE CIRCLED LATIN CAPITAL LETTER X +02E3 ; [.1860.0020.0014.02E3] # MODIFIER LETTER SMALL X +2093 ; [.1860.0020.0015.2093] # LATIN SUBSCRIPT SMALL LETTER X +1F147 ; [.1860.0020.001D.1F147] # SQUARED LATIN CAPITAL LETTER X +1F187 ; [.1860.0020.001D.1F187] # NEGATIVE SQUARED LATIN CAPITAL LETTER X +1E8D ; [.1860.0020.0002.0078][.0000.0047.0002.0308] # LATIN SMALL LETTER X WITH DIAERESIS +1E8C ; [.1860.0020.0008.0058][.0000.0047.0002.0308] # LATIN CAPITAL LETTER X WITH DIAERESIS +1E8B ; [.1860.0020.0002.0078][.0000.0052.0002.0307] # LATIN SMALL LETTER X WITH DOT ABOVE +1E8A ; [.1860.0020.0008.0058][.0000.0052.0002.0307] # LATIN CAPITAL LETTER X WITH DOT ABOVE +217A ; [.1860.0020.0004.217A][.16B2.0020.0004.217A] # SMALL ROMAN NUMERAL ELEVEN +216A ; [.1860.0020.000A.216A][.16B2.0020.000A.216A] # ROMAN NUMERAL ELEVEN +217B ; [.1860.0020.0004.217B][.16B2.0020.0004.217B][.16B2.0020.001F.217B] # SMALL ROMAN NUMERAL TWELVE +216B ; [.1860.0020.000A.216B][.16B2.0020.000A.216B][.16B2.0020.001F.216B] # ROMAN NUMERAL TWELVE +1D8D ; [.1864.0020.0002.1D8D] # LATIN SMALL LETTER X WITH PALATAL HOOK +0079 ; [.1865.0020.0002.0079] # LATIN SMALL LETTER Y +FF59 ; [.1865.0020.0003.FF59] # FULLWIDTH LATIN SMALL LETTER Y +24B4 ; [*02FB.0020.0004.24B4][.1865.0020.0004.24B4][*02FC.0020.001F.24B4] # PARENTHESIZED LATIN SMALL LETTER Y +1D432 ; [.1865.0020.0005.1D432] # MATHEMATICAL BOLD SMALL Y +1D466 ; [.1865.0020.0005.1D466] # MATHEMATICAL ITALIC SMALL Y +1D49A ; [.1865.0020.0005.1D49A] # MATHEMATICAL BOLD ITALIC SMALL Y +1D4CE ; [.1865.0020.0005.1D4CE] # MATHEMATICAL SCRIPT SMALL Y +1D502 ; [.1865.0020.0005.1D502] # MATHEMATICAL BOLD SCRIPT SMALL Y +1D536 ; [.1865.0020.0005.1D536] # MATHEMATICAL FRAKTUR SMALL Y +1D56A ; [.1865.0020.0005.1D56A] # MATHEMATICAL DOUBLE-STRUCK SMALL Y +1D59E ; [.1865.0020.0005.1D59E] # MATHEMATICAL BOLD FRAKTUR SMALL Y +1D5D2 ; [.1865.0020.0005.1D5D2] # MATHEMATICAL SANS-SERIF SMALL Y +1D606 ; [.1865.0020.0005.1D606] # MATHEMATICAL SANS-SERIF BOLD SMALL Y +1D63A ; [.1865.0020.0005.1D63A] # MATHEMATICAL SANS-SERIF ITALIC SMALL Y +1D66E ; [.1865.0020.0005.1D66E] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y +1D6A2 ; [.1865.0020.0005.1D6A2] # MATHEMATICAL MONOSPACE SMALL Y +24E8 ; [.1865.0020.0006.24E8] # CIRCLED LATIN SMALL LETTER Y +0059 ; [.1865.0020.0008.0059] # LATIN CAPITAL LETTER Y +FF39 ; [.1865.0020.0009.FF39] # FULLWIDTH LATIN CAPITAL LETTER Y +1F128 ; [*02FB.0020.0004.1F128][.1865.0020.000A.1F128][*02FC.0020.001F.1F128] # PARENTHESIZED LATIN CAPITAL LETTER Y +1F1FE ; [.1865.0020.000A.1F1FE] # REGIONAL INDICATOR SYMBOL LETTER Y +1D418 ; [.1865.0020.000B.1D418] # MATHEMATICAL BOLD CAPITAL Y +1D44C ; [.1865.0020.000B.1D44C] # MATHEMATICAL ITALIC CAPITAL Y +1D480 ; [.1865.0020.000B.1D480] # MATHEMATICAL BOLD ITALIC CAPITAL Y +1D4B4 ; [.1865.0020.000B.1D4B4] # MATHEMATICAL SCRIPT CAPITAL Y +1D4E8 ; [.1865.0020.000B.1D4E8] # MATHEMATICAL BOLD SCRIPT CAPITAL Y +1D51C ; [.1865.0020.000B.1D51C] # MATHEMATICAL FRAKTUR CAPITAL Y +1D550 ; [.1865.0020.000B.1D550] # MATHEMATICAL DOUBLE-STRUCK CAPITAL Y +1D584 ; [.1865.0020.000B.1D584] # MATHEMATICAL BOLD FRAKTUR CAPITAL Y +1D5B8 ; [.1865.0020.000B.1D5B8] # MATHEMATICAL SANS-SERIF CAPITAL Y +1D5EC ; [.1865.0020.000B.1D5EC] # MATHEMATICAL SANS-SERIF BOLD CAPITAL Y +1D620 ; [.1865.0020.000B.1D620] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y +1D654 ; [.1865.0020.000B.1D654] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y +1D688 ; [.1865.0020.000B.1D688] # MATHEMATICAL MONOSPACE CAPITAL Y +24CE ; [.1865.0020.000C.24CE] # CIRCLED LATIN CAPITAL LETTER Y +1F168 ; [.1865.0020.000C.1F168] # NEGATIVE CIRCLED LATIN CAPITAL LETTER Y +02B8 ; [.1865.0020.0014.02B8] # MODIFIER LETTER SMALL Y +1F148 ; [.1865.0020.001D.1F148] # SQUARED LATIN CAPITAL LETTER Y +1F188 ; [.1865.0020.001D.1F188] # NEGATIVE SQUARED LATIN CAPITAL LETTER Y +00FD ; [.1865.0020.0002.0079][.0000.0032.0002.0301] # LATIN SMALL LETTER Y WITH ACUTE +00DD ; [.1865.0020.0008.0059][.0000.0032.0002.0301] # LATIN CAPITAL LETTER Y WITH ACUTE +1EF3 ; [.1865.0020.0002.0079][.0000.0035.0002.0300] # LATIN SMALL LETTER Y WITH GRAVE +1EF2 ; [.1865.0020.0008.0059][.0000.0035.0002.0300] # LATIN CAPITAL LETTER Y WITH GRAVE +0177 ; [.1865.0020.0002.0079][.0000.003C.0002.0302] # LATIN SMALL LETTER Y WITH CIRCUMFLEX +0176 ; [.1865.0020.0008.0059][.0000.003C.0002.0302] # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +1E99 ; [.1865.0020.0002.0079][.0000.0043.0002.030A] # LATIN SMALL LETTER Y WITH RING ABOVE +00FF ; [.1865.0020.0002.0079][.0000.0047.0002.0308] # LATIN SMALL LETTER Y WITH DIAERESIS +0178 ; [.1865.0020.0008.0059][.0000.0047.0002.0308] # LATIN CAPITAL LETTER Y WITH DIAERESIS +1EF9 ; [.1865.0020.0002.0079][.0000.004E.0002.0303] # LATIN SMALL LETTER Y WITH TILDE +1EF8 ; [.1865.0020.0008.0059][.0000.004E.0002.0303] # LATIN CAPITAL LETTER Y WITH TILDE +1E8F ; [.1865.0020.0002.0079][.0000.0052.0002.0307] # LATIN SMALL LETTER Y WITH DOT ABOVE +1E8E ; [.1865.0020.0008.0059][.0000.0052.0002.0307] # LATIN CAPITAL LETTER Y WITH DOT ABOVE +0233 ; [.1865.0020.0002.0079][.0000.005B.0002.0304] # LATIN SMALL LETTER Y WITH MACRON +0232 ; [.1865.0020.0008.0059][.0000.005B.0002.0304] # LATIN CAPITAL LETTER Y WITH MACRON +1EF7 ; [.1865.0020.0002.0079][.0000.0064.0002.0309] # LATIN SMALL LETTER Y WITH HOOK ABOVE +1EF6 ; [.1865.0020.0008.0059][.0000.0064.0002.0309] # LATIN CAPITAL LETTER Y WITH HOOK ABOVE +1EF5 ; [.1865.0020.0002.0079][.0000.0070.0002.0323] # LATIN SMALL LETTER Y WITH DOT BELOW +1EF4 ; [.1865.0020.0008.0059][.0000.0070.0002.0323] # LATIN CAPITAL LETTER Y WITH DOT BELOW +028F ; [.1869.0020.0002.028F] # LATIN LETTER SMALL CAPITAL Y +024F ; [.186D.0020.0002.024F] # LATIN SMALL LETTER Y WITH STROKE +024E ; [.186D.0020.0008.024E] # LATIN CAPITAL LETTER Y WITH STROKE +01B4 ; [.1871.0020.0002.01B4] # LATIN SMALL LETTER Y WITH HOOK +01B3 ; [.1871.0020.0008.01B3] # LATIN CAPITAL LETTER Y WITH HOOK +1EFF ; [.1875.0020.0002.1EFF] # LATIN SMALL LETTER Y WITH LOOP +1EFE ; [.1875.0020.0008.1EFE] # LATIN CAPITAL LETTER Y WITH LOOP +021D ; [.1876.0020.0002.021D] # LATIN SMALL LETTER YOGH +021C ; [.1876.0020.0008.021C] # LATIN CAPITAL LETTER YOGH +007A ; [.187A.0020.0002.007A] # LATIN SMALL LETTER Z +FF5A ; [.187A.0020.0003.FF5A] # FULLWIDTH LATIN SMALL LETTER Z +1DE6 ; [.187A.0020.0004.1DE6] # COMBINING LATIN SMALL LETTER Z +24B5 ; [*02FB.0020.0004.24B5][.187A.0020.0004.24B5][*02FC.0020.001F.24B5] # PARENTHESIZED LATIN SMALL LETTER Z +1D433 ; [.187A.0020.0005.1D433] # MATHEMATICAL BOLD SMALL Z +1D467 ; [.187A.0020.0005.1D467] # MATHEMATICAL ITALIC SMALL Z +1D49B ; [.187A.0020.0005.1D49B] # MATHEMATICAL BOLD ITALIC SMALL Z +1D4CF ; [.187A.0020.0005.1D4CF] # MATHEMATICAL SCRIPT SMALL Z +1D503 ; [.187A.0020.0005.1D503] # MATHEMATICAL BOLD SCRIPT SMALL Z +1D537 ; [.187A.0020.0005.1D537] # MATHEMATICAL FRAKTUR SMALL Z +1D56B ; [.187A.0020.0005.1D56B] # MATHEMATICAL DOUBLE-STRUCK SMALL Z +1D59F ; [.187A.0020.0005.1D59F] # MATHEMATICAL BOLD FRAKTUR SMALL Z +1D5D3 ; [.187A.0020.0005.1D5D3] # MATHEMATICAL SANS-SERIF SMALL Z +1D607 ; [.187A.0020.0005.1D607] # MATHEMATICAL SANS-SERIF BOLD SMALL Z +1D63B ; [.187A.0020.0005.1D63B] # MATHEMATICAL SANS-SERIF ITALIC SMALL Z +1D66F ; [.187A.0020.0005.1D66F] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z +1D6A3 ; [.187A.0020.0005.1D6A3] # MATHEMATICAL MONOSPACE SMALL Z +24E9 ; [.187A.0020.0006.24E9] # CIRCLED LATIN SMALL LETTER Z +005A ; [.187A.0020.0008.005A] # LATIN CAPITAL LETTER Z +FF3A ; [.187A.0020.0009.FF3A] # FULLWIDTH LATIN CAPITAL LETTER Z +1F129 ; [*02FB.0020.0004.1F129][.187A.0020.000A.1F129][*02FC.0020.001F.1F129] # PARENTHESIZED LATIN CAPITAL LETTER Z +1F1FF ; [.187A.0020.000A.1F1FF] # REGIONAL INDICATOR SYMBOL LETTER Z +2124 ; [.187A.0020.000B.2124] # DOUBLE-STRUCK CAPITAL Z +2128 ; [.187A.0020.000B.2128] # BLACK-LETTER CAPITAL Z +1D419 ; [.187A.0020.000B.1D419] # MATHEMATICAL BOLD CAPITAL Z +1D44D ; [.187A.0020.000B.1D44D] # MATHEMATICAL ITALIC CAPITAL Z +1D481 ; [.187A.0020.000B.1D481] # MATHEMATICAL BOLD ITALIC CAPITAL Z +1D4B5 ; [.187A.0020.000B.1D4B5] # MATHEMATICAL SCRIPT CAPITAL Z +1D4E9 ; [.187A.0020.000B.1D4E9] # MATHEMATICAL BOLD SCRIPT CAPITAL Z +1D585 ; [.187A.0020.000B.1D585] # MATHEMATICAL BOLD FRAKTUR CAPITAL Z +1D5B9 ; [.187A.0020.000B.1D5B9] # MATHEMATICAL SANS-SERIF CAPITAL Z +1D5ED ; [.187A.0020.000B.1D5ED] # MATHEMATICAL SANS-SERIF BOLD CAPITAL Z +1D621 ; [.187A.0020.000B.1D621] # MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z +1D655 ; [.187A.0020.000B.1D655] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z +1D689 ; [.187A.0020.000B.1D689] # MATHEMATICAL MONOSPACE CAPITAL Z +24CF ; [.187A.0020.000C.24CF] # CIRCLED LATIN CAPITAL LETTER Z +1F169 ; [.187A.0020.000C.1F169] # NEGATIVE CIRCLED LATIN CAPITAL LETTER Z +1DBB ; [.187A.0020.0014.1DBB] # MODIFIER LETTER SMALL Z +1F149 ; [.187A.0020.001D.1F149] # SQUARED LATIN CAPITAL LETTER Z +1F189 ; [.187A.0020.001D.1F189] # NEGATIVE SQUARED LATIN CAPITAL LETTER Z +017A ; [.187A.0020.0002.007A][.0000.0032.0002.0301] # LATIN SMALL LETTER Z WITH ACUTE +0179 ; [.187A.0020.0008.005A][.0000.0032.0002.0301] # LATIN CAPITAL LETTER Z WITH ACUTE +1E91 ; [.187A.0020.0002.007A][.0000.003C.0002.0302] # LATIN SMALL LETTER Z WITH CIRCUMFLEX +1E90 ; [.187A.0020.0008.005A][.0000.003C.0002.0302] # LATIN CAPITAL LETTER Z WITH CIRCUMFLEX +017E ; [.187A.0020.0002.007A][.0000.0041.0002.030C] # LATIN SMALL LETTER Z WITH CARON +017D ; [.187A.0020.0008.005A][.0000.0041.0002.030C] # LATIN CAPITAL LETTER Z WITH CARON +017C ; [.187A.0020.0002.007A][.0000.0052.0002.0307] # LATIN SMALL LETTER Z WITH DOT ABOVE +017B ; [.187A.0020.0008.005A][.0000.0052.0002.0307] # LATIN CAPITAL LETTER Z WITH DOT ABOVE +1E93 ; [.187A.0020.0002.007A][.0000.0070.0002.0323] # LATIN SMALL LETTER Z WITH DOT BELOW +1E92 ; [.187A.0020.0008.005A][.0000.0070.0002.0323] # LATIN CAPITAL LETTER Z WITH DOT BELOW +1E95 ; [.187A.0020.0002.007A][.0000.007B.0002.0331] # LATIN SMALL LETTER Z WITH LINE BELOW +1E94 ; [.187A.0020.0008.005A][.0000.007B.0002.0331] # LATIN CAPITAL LETTER Z WITH LINE BELOW +018D ; [.187A.0020.0004.018D][.1856.0020.0004.018D] # LATIN SMALL LETTER TURNED DELTA +1D22 ; [.187E.0020.0002.1D22] # LATIN LETTER SMALL CAPITAL Z +01B6 ; [.187F.0020.0002.01B6] # LATIN SMALL LETTER Z WITH STROKE +01B5 ; [.187F.0020.0008.01B5] # LATIN CAPITAL LETTER Z WITH STROKE +1D76 ; [.1883.0020.0002.1D76] # LATIN SMALL LETTER Z WITH MIDDLE TILDE +1D8E ; [.1884.0020.0002.1D8E] # LATIN SMALL LETTER Z WITH PALATAL HOOK +0225 ; [.1885.0020.0002.0225] # LATIN SMALL LETTER Z WITH HOOK +0224 ; [.1885.0020.0008.0224] # LATIN CAPITAL LETTER Z WITH HOOK +0290 ; [.1889.0020.0002.0290] # LATIN SMALL LETTER Z WITH RETROFLEX HOOK +1DBC ; [.1889.0020.0014.1DBC] # MODIFIER LETTER SMALL Z WITH RETROFLEX HOOK +0291 ; [.188D.0020.0002.0291] # LATIN SMALL LETTER Z WITH CURL +1DBD ; [.188D.0020.0014.1DBD] # MODIFIER LETTER SMALL Z WITH CURL +0240 ; [.1891.0020.0002.0240] # LATIN SMALL LETTER Z WITH SWASH TAIL +2C7F ; [.1891.0020.0008.2C7F] # LATIN CAPITAL LETTER Z WITH SWASH TAIL +2C6C ; [.1895.0020.0002.2C6C] # LATIN SMALL LETTER Z WITH DESCENDER +2C6B ; [.1895.0020.0008.2C6B] # LATIN CAPITAL LETTER Z WITH DESCENDER +A763 ; [.1896.0020.0002.A763] # LATIN SMALL LETTER VISIGOTHIC Z +A762 ; [.1896.0020.0008.A762] # LATIN CAPITAL LETTER VISIGOTHIC Z +0292 ; [.1897.0020.0002.0292] # LATIN SMALL LETTER EZH +01B7 ; [.1897.0020.0008.01B7] # LATIN CAPITAL LETTER EZH +1DBE ; [.1897.0020.0014.1DBE] # MODIFIER LETTER SMALL EZH +01EF ; [.1897.0020.0002.0292][.0000.0041.0002.030C] # LATIN SMALL LETTER EZH WITH CARON +01EE ; [.1897.0020.0008.01B7][.0000.0041.0002.030C] # LATIN CAPITAL LETTER EZH WITH CARON +1D23 ; [.189B.0020.0002.1D23] # LATIN LETTER SMALL CAPITAL EZH +01B9 ; [.189C.0020.0002.01B9] # LATIN SMALL LETTER EZH REVERSED +01B8 ; [.189C.0020.0008.01B8] # LATIN CAPITAL LETTER EZH REVERSED +1D9A ; [.18A0.0020.0002.1D9A] # LATIN SMALL LETTER EZH WITH RETROFLEX HOOK +01BA ; [.18A1.0020.0002.01BA] # LATIN SMALL LETTER EZH WITH TAIL +0293 ; [.18A5.0020.0002.0293] # LATIN SMALL LETTER EZH WITH CURL +00FE ; [.18A9.0020.0002.00FE] # LATIN SMALL LETTER THORN +00DE ; [.18A9.0020.0008.00DE] # LATIN CAPITAL LETTER THORN +A765 ; [.18AD.0020.0002.A765] # LATIN SMALL LETTER THORN WITH STROKE +A764 ; [.18AD.0020.0008.A764] # LATIN CAPITAL LETTER THORN WITH STROKE +A767 ; [.18AE.0020.0002.A767] # LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER +A766 ; [.18AE.0020.0008.A766] # LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER +01BF ; [.18AF.0020.0002.01BF] # LATIN LETTER WYNN +01F7 ; [.18AF.0020.0008.01F7] # LATIN CAPITAL LETTER WYNN +A769 ; [.18B3.0020.0002.A769] # LATIN SMALL LETTER VEND +A768 ; [.18B3.0020.0008.A768] # LATIN CAPITAL LETTER VEND +A76B ; [.18B4.0020.0002.A76B] # LATIN SMALL LETTER ET +A76A ; [.18B4.0020.0008.A76A] # LATIN CAPITAL LETTER ET +A76D ; [.18B5.0020.0002.A76D] # LATIN SMALL LETTER IS +A76C ; [.18B5.0020.0008.A76C] # LATIN CAPITAL LETTER IS +A76F ; [.18B6.0020.0002.A76F] # LATIN SMALL LETTER CON +1DD2 ; [.18B6.0020.0004.1DD2] # COMBINING US ABOVE +A76E ; [.18B6.0020.0008.A76E] # LATIN CAPITAL LETTER CON +A770 ; [.18B6.0020.0014.A770] # MODIFIER LETTER US +A778 ; [.18B7.0020.0002.A778] # LATIN SMALL LETTER UM +01BB ; [.18B8.0020.0002.01BB] # LATIN LETTER TWO WITH STROKE +A72B ; [.18BC.0020.0002.A72B] # LATIN SMALL LETTER TRESILLO +A72A ; [.18BC.0020.0008.A72A] # LATIN CAPITAL LETTER TRESILLO +A72D ; [.18BD.0020.0002.A72D] # LATIN SMALL LETTER CUATRILLO +A72C ; [.18BD.0020.0008.A72C] # LATIN CAPITAL LETTER CUATRILLO +A72F ; [.18BE.0020.0002.A72F] # LATIN SMALL LETTER CUATRILLO WITH COMMA +A72E ; [.18BE.0020.0008.A72E] # LATIN CAPITAL LETTER CUATRILLO WITH COMMA +01A8 ; [.18BF.0020.0002.01A8] # LATIN SMALL LETTER TONE TWO +01A7 ; [.18BF.0020.0008.01A7] # LATIN CAPITAL LETTER TONE TWO +01BD ; [.18C3.0020.0002.01BD] # LATIN SMALL LETTER TONE FIVE +01BC ; [.18C3.0020.0008.01BC] # LATIN CAPITAL LETTER TONE FIVE +0185 ; [.18C7.0020.0002.0185] # LATIN SMALL LETTER TONE SIX +0184 ; [.18C7.0020.0008.0184] # LATIN CAPITAL LETTER TONE SIX +0294 ; [.18CB.0020.0002.0294] # LATIN LETTER GLOTTAL STOP +0242 ; [.18CF.0020.0002.0242] # LATIN SMALL LETTER GLOTTAL STOP +0241 ; [.18CF.0020.0008.0241] # LATIN CAPITAL LETTER GLOTTAL STOP +02C0 ; [.18D3.0020.0002.02C0] # MODIFIER LETTER GLOTTAL STOP +02BC ; [.18D4.0020.0002.02BC] # MODIFIER LETTER APOSTROPHE +0149 ; [.18D4.0020.0004.0149][.1734.0020.0004.0149] # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE +02EE ; [.18D5.0020.0002.02EE] # MODIFIER LETTER DOUBLE APOSTROPHE +02BE ; [.18D6.0020.0002.02BE] # MODIFIER LETTER RIGHT HALF RING +A723 ; [.18D7.0020.0002.A723] # LATIN SMALL LETTER EGYPTOLOGICAL ALEF +A722 ; [.18D7.0020.0008.A722] # LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF +A78C ; [.18D8.0020.0002.A78C] # LATIN SMALL LETTER SALTILLO +A78B ; [.18D8.0020.0008.A78B] # LATIN CAPITAL LETTER SALTILLO +0295 ; [.18D9.0020.0002.0295] # LATIN LETTER PHARYNGEAL VOICED FRICATIVE +02E4 ; [.18D9.0020.0014.02E4] # MODIFIER LETTER SMALL REVERSED GLOTTAL STOP +02BF ; [.18DD.0020.0002.02BF] # MODIFIER LETTER LEFT HALF RING +02C1 ; [.18DE.0020.0002.02C1] # MODIFIER LETTER REVERSED GLOTTAL STOP +1D24 ; [.18DF.0020.0002.1D24] # LATIN LETTER VOICED LARYNGEAL SPIRANT +1D25 ; [.18E0.0020.0002.1D25] # LATIN LETTER AIN +1D5C ; [.18E0.0020.0014.1D5C] # MODIFIER LETTER SMALL AIN +A725 ; [.18E1.0020.0002.A725] # LATIN SMALL LETTER EGYPTOLOGICAL AIN +A724 ; [.18E1.0020.0008.A724] # LATIN CAPITAL LETTER EGYPTOLOGICAL AIN +02A1 ; [.18E2.0020.0002.02A1] # LATIN LETTER GLOTTAL STOP WITH STROKE +02A2 ; [.18E6.0020.0002.02A2] # LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE +0296 ; [.18EA.0020.0002.0296] # LATIN LETTER INVERTED GLOTTAL STOP +01C0 ; [.18EE.0020.0002.01C0] # LATIN LETTER DENTAL CLICK +01C1 ; [.18F2.0020.0002.01C1] # LATIN LETTER LATERAL CLICK +01C2 ; [.18F6.0020.0002.01C2] # LATIN LETTER ALVEOLAR CLICK +01C3 ; [.18FA.0020.0002.01C3] # LATIN LETTER RETROFLEX CLICK +0297 ; [.18FE.0020.0002.0297] # LATIN LETTER STRETCHED C +0298 ; [.1902.0020.0002.0298] # LATIN LETTER BILABIAL CLICK +02AC ; [.1906.0020.0002.02AC] # LATIN LETTER BILABIAL PERCUSSIVE +02AD ; [.190A.0020.0002.02AD] # LATIN LETTER BIDENTAL PERCUSSIVE +03B1 ; [.190E.0020.0002.03B1] # GREEK SMALL LETTER ALPHA +1D6C2 ; [.190E.0020.0005.1D6C2] # MATHEMATICAL BOLD SMALL ALPHA +1D6FC ; [.190E.0020.0005.1D6FC] # MATHEMATICAL ITALIC SMALL ALPHA +1D736 ; [.190E.0020.0005.1D736] # MATHEMATICAL BOLD ITALIC SMALL ALPHA +1D770 ; [.190E.0020.0005.1D770] # MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA +1D7AA ; [.190E.0020.0005.1D7AA] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA +0391 ; [.190E.0020.0008.0391] # GREEK CAPITAL LETTER ALPHA +1D6A8 ; [.190E.0020.000B.1D6A8] # MATHEMATICAL BOLD CAPITAL ALPHA +1D6E2 ; [.190E.0020.000B.1D6E2] # MATHEMATICAL ITALIC CAPITAL ALPHA +1D71C ; [.190E.0020.000B.1D71C] # MATHEMATICAL BOLD ITALIC CAPITAL ALPHA +1D756 ; [.190E.0020.000B.1D756] # MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA +1D790 ; [.190E.0020.000B.1D790] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA +1F00 ; [.190E.0020.0002.03B1][.0000.0022.0002.0313] # GREEK SMALL LETTER ALPHA WITH PSILI +1F08 ; [.190E.0020.0008.0391][.0000.0022.0002.0313] # GREEK CAPITAL LETTER ALPHA WITH PSILI +1F04 ; [.190E.0020.0002.03B1][.0000.0022.0002.0313][.0000.0032.0002.0301] # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA +1F0C ; [.190E.0020.0008.0391][.0000.0022.0002.0313][.0000.0032.0002.0301] # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA +1F84 ; [.190E.0020.0002.03B1][.0000.0022.0002.0313][.0000.0032.0002.0301][.0000.007F.0002.0345] # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI +1F8C ; [.190E.0020.0008.0391][.0000.0022.0002.0313][.0000.0032.0002.0301][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F02 ; [.190E.0020.0002.03B1][.0000.0022.0002.0313][.0000.0035.0002.0300] # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA +1F0A ; [.190E.0020.0008.0391][.0000.0022.0002.0313][.0000.0035.0002.0300] # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA +1F82 ; [.190E.0020.0002.03B1][.0000.0022.0002.0313][.0000.0035.0002.0300][.0000.007F.0002.0345] # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI +1F8A ; [.190E.0020.0008.0391][.0000.0022.0002.0313][.0000.0035.0002.0300][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F06 ; [.190E.0020.0002.03B1][.0000.0022.0002.0313][.0000.0045.0002.0342] # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI +1F0E ; [.190E.0020.0008.0391][.0000.0022.0002.0313][.0000.0045.0002.0342] # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI +1F86 ; [.190E.0020.0002.03B1][.0000.0022.0002.0313][.0000.0045.0002.0342][.0000.007F.0002.0345] # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +1F8E ; [.190E.0020.0008.0391][.0000.0022.0002.0313][.0000.0045.0002.0342][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F80 ; [.190E.0020.0002.03B1][.0000.0022.0002.0313][.0000.007F.0002.0345] # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI +1F88 ; [.190E.0020.0008.0391][.0000.0022.0002.0313][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI +1F01 ; [.190E.0020.0002.03B1][.0000.002A.0002.0314] # GREEK SMALL LETTER ALPHA WITH DASIA +1F09 ; [.190E.0020.0008.0391][.0000.002A.0002.0314] # GREEK CAPITAL LETTER ALPHA WITH DASIA +1F05 ; [.190E.0020.0002.03B1][.0000.002A.0002.0314][.0000.0032.0002.0301] # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA +1F0D ; [.190E.0020.0008.0391][.0000.002A.0002.0314][.0000.0032.0002.0301] # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA +1F85 ; [.190E.0020.0002.03B1][.0000.002A.0002.0314][.0000.0032.0002.0301][.0000.007F.0002.0345] # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI +1F8D ; [.190E.0020.0008.0391][.0000.002A.0002.0314][.0000.0032.0002.0301][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F03 ; [.190E.0020.0002.03B1][.0000.002A.0002.0314][.0000.0035.0002.0300] # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA +1F0B ; [.190E.0020.0008.0391][.0000.002A.0002.0314][.0000.0035.0002.0300] # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA +1F83 ; [.190E.0020.0002.03B1][.0000.002A.0002.0314][.0000.0035.0002.0300][.0000.007F.0002.0345] # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI +1F8B ; [.190E.0020.0008.0391][.0000.002A.0002.0314][.0000.0035.0002.0300][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F07 ; [.190E.0020.0002.03B1][.0000.002A.0002.0314][.0000.0045.0002.0342] # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI +1F0F ; [.190E.0020.0008.0391][.0000.002A.0002.0314][.0000.0045.0002.0342] # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI +1F87 ; [.190E.0020.0002.03B1][.0000.002A.0002.0314][.0000.0045.0002.0342][.0000.007F.0002.0345] # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1F8F ; [.190E.0020.0008.0391][.0000.002A.0002.0314][.0000.0045.0002.0342][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1F81 ; [.190E.0020.0002.03B1][.0000.002A.0002.0314][.0000.007F.0002.0345] # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI +1F89 ; [.190E.0020.0008.0391][.0000.002A.0002.0314][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI +03AC ; [.190E.0020.0002.03B1][.0000.0032.0002.0301] # GREEK SMALL LETTER ALPHA WITH TONOS +1F71 ; [.190E.0020.0002.03B1][.0000.0032.0002.0301] # GREEK SMALL LETTER ALPHA WITH OXIA +0386 ; [.190E.0020.0008.0391][.0000.0032.0002.0301] # GREEK CAPITAL LETTER ALPHA WITH TONOS +1FBB ; [.190E.0020.0008.0391][.0000.0032.0002.0301] # GREEK CAPITAL LETTER ALPHA WITH OXIA +1FB4 ; [.190E.0020.0002.03B1][.0000.0032.0002.0301][.0000.007F.0002.0345] # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI +1F70 ; [.190E.0020.0002.03B1][.0000.0035.0002.0300] # GREEK SMALL LETTER ALPHA WITH VARIA +1FBA ; [.190E.0020.0008.0391][.0000.0035.0002.0300] # GREEK CAPITAL LETTER ALPHA WITH VARIA +1FB2 ; [.190E.0020.0002.03B1][.0000.0035.0002.0300][.0000.007F.0002.0345] # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI +1FB0 ; [.190E.0020.0002.03B1][.0000.0037.0002.0306] # GREEK SMALL LETTER ALPHA WITH VRACHY +1FB8 ; [.190E.0020.0008.0391][.0000.0037.0002.0306] # GREEK CAPITAL LETTER ALPHA WITH VRACHY +1FB6 ; [.190E.0020.0002.03B1][.0000.0045.0002.0342] # GREEK SMALL LETTER ALPHA WITH PERISPOMENI +1FB7 ; [.190E.0020.0002.03B1][.0000.0045.0002.0342][.0000.007F.0002.0345] # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI +1FB1 ; [.190E.0020.0002.03B1][.0000.005B.0002.0304] # GREEK SMALL LETTER ALPHA WITH MACRON +1FB9 ; [.190E.0020.0008.0391][.0000.005B.0002.0304] # GREEK CAPITAL LETTER ALPHA WITH MACRON +1FB3 ; [.190E.0020.0002.03B1][.0000.007F.0002.0345] # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI +1FBC ; [.190E.0020.0008.0391][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI +03B2 ; [.190F.0020.0002.03B2] # GREEK SMALL LETTER BETA +03D0 ; [.190F.0020.0004.03D0] # GREEK BETA SYMBOL +1D6C3 ; [.190F.0020.0005.1D6C3] # MATHEMATICAL BOLD SMALL BETA +1D6FD ; [.190F.0020.0005.1D6FD] # MATHEMATICAL ITALIC SMALL BETA +1D737 ; [.190F.0020.0005.1D737] # MATHEMATICAL BOLD ITALIC SMALL BETA +1D771 ; [.190F.0020.0005.1D771] # MATHEMATICAL SANS-SERIF BOLD SMALL BETA +1D7AB ; [.190F.0020.0005.1D7AB] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA +0392 ; [.190F.0020.0008.0392] # GREEK CAPITAL LETTER BETA +1D6A9 ; [.190F.0020.000B.1D6A9] # MATHEMATICAL BOLD CAPITAL BETA +1D6E3 ; [.190F.0020.000B.1D6E3] # MATHEMATICAL ITALIC CAPITAL BETA +1D71D ; [.190F.0020.000B.1D71D] # MATHEMATICAL BOLD ITALIC CAPITAL BETA +1D757 ; [.190F.0020.000B.1D757] # MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA +1D791 ; [.190F.0020.000B.1D791] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA +1D5D ; [.190F.0020.0014.1D5D] # MODIFIER LETTER SMALL BETA +1D66 ; [.190F.0020.0015.1D66] # GREEK SUBSCRIPT SMALL LETTER BETA +03B3 ; [.1910.0020.0002.03B3] # GREEK SMALL LETTER GAMMA +213D ; [.1910.0020.0005.213D] # DOUBLE-STRUCK SMALL GAMMA +1D6C4 ; [.1910.0020.0005.1D6C4] # MATHEMATICAL BOLD SMALL GAMMA +1D6FE ; [.1910.0020.0005.1D6FE] # MATHEMATICAL ITALIC SMALL GAMMA +1D738 ; [.1910.0020.0005.1D738] # MATHEMATICAL BOLD ITALIC SMALL GAMMA +1D772 ; [.1910.0020.0005.1D772] # MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA +1D7AC ; [.1910.0020.0005.1D7AC] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA +0393 ; [.1910.0020.0008.0393] # GREEK CAPITAL LETTER GAMMA +213E ; [.1910.0020.000B.213E] # DOUBLE-STRUCK CAPITAL GAMMA +1D6AA ; [.1910.0020.000B.1D6AA] # MATHEMATICAL BOLD CAPITAL GAMMA +1D6E4 ; [.1910.0020.000B.1D6E4] # MATHEMATICAL ITALIC CAPITAL GAMMA +1D71E ; [.1910.0020.000B.1D71E] # MATHEMATICAL BOLD ITALIC CAPITAL GAMMA +1D758 ; [.1910.0020.000B.1D758] # MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA +1D792 ; [.1910.0020.000B.1D792] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA +1D5E ; [.1910.0020.0014.1D5E] # MODIFIER LETTER SMALL GREEK GAMMA +1D67 ; [.1910.0020.0015.1D67] # GREEK SUBSCRIPT SMALL LETTER GAMMA +1D26 ; [.1911.0020.0002.1D26] # GREEK LETTER SMALL CAPITAL GAMMA +03B4 ; [.1912.0020.0002.03B4] # GREEK SMALL LETTER DELTA +1D6C5 ; [.1912.0020.0005.1D6C5] # MATHEMATICAL BOLD SMALL DELTA +1D6FF ; [.1912.0020.0005.1D6FF] # MATHEMATICAL ITALIC SMALL DELTA +1D739 ; [.1912.0020.0005.1D739] # MATHEMATICAL BOLD ITALIC SMALL DELTA +1D773 ; [.1912.0020.0005.1D773] # MATHEMATICAL SANS-SERIF BOLD SMALL DELTA +1D7AD ; [.1912.0020.0005.1D7AD] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA +0394 ; [.1912.0020.0008.0394] # GREEK CAPITAL LETTER DELTA +1D6AB ; [.1912.0020.000B.1D6AB] # MATHEMATICAL BOLD CAPITAL DELTA +1D6E5 ; [.1912.0020.000B.1D6E5] # MATHEMATICAL ITALIC CAPITAL DELTA +1D71F ; [.1912.0020.000B.1D71F] # MATHEMATICAL BOLD ITALIC CAPITAL DELTA +1D759 ; [.1912.0020.000B.1D759] # MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA +1D793 ; [.1912.0020.000B.1D793] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA +1D5F ; [.1912.0020.0014.1D5F] # MODIFIER LETTER SMALL DELTA +03B5 ; [.1913.0020.0002.03B5] # GREEK SMALL LETTER EPSILON +03F5 ; [.1913.0020.0004.03F5] # GREEK LUNATE EPSILON SYMBOL +1D6C6 ; [.1913.0020.0005.1D6C6] # MATHEMATICAL BOLD SMALL EPSILON +1D6DC ; [.1913.0020.0005.1D6DC] # MATHEMATICAL BOLD EPSILON SYMBOL +1D700 ; [.1913.0020.0005.1D700] # MATHEMATICAL ITALIC SMALL EPSILON +1D716 ; [.1913.0020.0005.1D716] # MATHEMATICAL ITALIC EPSILON SYMBOL +1D73A ; [.1913.0020.0005.1D73A] # MATHEMATICAL BOLD ITALIC SMALL EPSILON +1D750 ; [.1913.0020.0005.1D750] # MATHEMATICAL BOLD ITALIC EPSILON SYMBOL +1D774 ; [.1913.0020.0005.1D774] # MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON +1D78A ; [.1913.0020.0005.1D78A] # MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL +1D7AE ; [.1913.0020.0005.1D7AE] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON +1D7C4 ; [.1913.0020.0005.1D7C4] # MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL +0395 ; [.1913.0020.0008.0395] # GREEK CAPITAL LETTER EPSILON +1D6AC ; [.1913.0020.000B.1D6AC] # MATHEMATICAL BOLD CAPITAL EPSILON +1D6E6 ; [.1913.0020.000B.1D6E6] # MATHEMATICAL ITALIC CAPITAL EPSILON +1D720 ; [.1913.0020.000B.1D720] # MATHEMATICAL BOLD ITALIC CAPITAL EPSILON +1D75A ; [.1913.0020.000B.1D75A] # MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON +1D794 ; [.1913.0020.000B.1D794] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON +1F10 ; [.1913.0020.0002.03B5][.0000.0022.0002.0313] # GREEK SMALL LETTER EPSILON WITH PSILI +1F18 ; [.1913.0020.0008.0395][.0000.0022.0002.0313] # GREEK CAPITAL LETTER EPSILON WITH PSILI +1F14 ; [.1913.0020.0002.03B5][.0000.0022.0002.0313][.0000.0032.0002.0301] # GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA +1F1C ; [.1913.0020.0008.0395][.0000.0022.0002.0313][.0000.0032.0002.0301] # GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA +1F12 ; [.1913.0020.0002.03B5][.0000.0022.0002.0313][.0000.0035.0002.0300] # GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA +1F1A ; [.1913.0020.0008.0395][.0000.0022.0002.0313][.0000.0035.0002.0300] # GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA +1F11 ; [.1913.0020.0002.03B5][.0000.002A.0002.0314] # GREEK SMALL LETTER EPSILON WITH DASIA +1F19 ; [.1913.0020.0008.0395][.0000.002A.0002.0314] # GREEK CAPITAL LETTER EPSILON WITH DASIA +1F15 ; [.1913.0020.0002.03B5][.0000.002A.0002.0314][.0000.0032.0002.0301] # GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA +1F1D ; [.1913.0020.0008.0395][.0000.002A.0002.0314][.0000.0032.0002.0301] # GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA +1F13 ; [.1913.0020.0002.03B5][.0000.002A.0002.0314][.0000.0035.0002.0300] # GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA +1F1B ; [.1913.0020.0008.0395][.0000.002A.0002.0314][.0000.0035.0002.0300] # GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA +03AD ; [.1913.0020.0002.03B5][.0000.0032.0002.0301] # GREEK SMALL LETTER EPSILON WITH TONOS +1F73 ; [.1913.0020.0002.03B5][.0000.0032.0002.0301] # GREEK SMALL LETTER EPSILON WITH OXIA +0388 ; [.1913.0020.0008.0395][.0000.0032.0002.0301] # GREEK CAPITAL LETTER EPSILON WITH TONOS +1FC9 ; [.1913.0020.0008.0395][.0000.0032.0002.0301] # GREEK CAPITAL LETTER EPSILON WITH OXIA +1F72 ; [.1913.0020.0002.03B5][.0000.0035.0002.0300] # GREEK SMALL LETTER EPSILON WITH VARIA +1FC8 ; [.1913.0020.0008.0395][.0000.0035.0002.0300] # GREEK CAPITAL LETTER EPSILON WITH VARIA +03DD ; [.1914.0020.0002.03DD] # GREEK SMALL LETTER DIGAMMA +1D7CB ; [.1914.0020.0005.1D7CB] # MATHEMATICAL BOLD SMALL DIGAMMA +03DC ; [.1914.0020.0008.03DC] # GREEK LETTER DIGAMMA +1D7CA ; [.1914.0020.000B.1D7CA] # MATHEMATICAL BOLD CAPITAL DIGAMMA +0377 ; [.1915.0020.0002.0377] # GREEK SMALL LETTER PAMPHYLIAN DIGAMMA +0376 ; [.1915.0020.0008.0376] # GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA +03DB ; [.1916.0020.0002.03DB] # GREEK SMALL LETTER STIGMA +03DA ; [.1916.0020.0008.03DA] # GREEK LETTER STIGMA +03B6 ; [.1917.0020.0002.03B6] # GREEK SMALL LETTER ZETA +1D6C7 ; [.1917.0020.0005.1D6C7] # MATHEMATICAL BOLD SMALL ZETA +1D701 ; [.1917.0020.0005.1D701] # MATHEMATICAL ITALIC SMALL ZETA +1D73B ; [.1917.0020.0005.1D73B] # MATHEMATICAL BOLD ITALIC SMALL ZETA +1D775 ; [.1917.0020.0005.1D775] # MATHEMATICAL SANS-SERIF BOLD SMALL ZETA +1D7AF ; [.1917.0020.0005.1D7AF] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA +0396 ; [.1917.0020.0008.0396] # GREEK CAPITAL LETTER ZETA +1D6AD ; [.1917.0020.000B.1D6AD] # MATHEMATICAL BOLD CAPITAL ZETA +1D6E7 ; [.1917.0020.000B.1D6E7] # MATHEMATICAL ITALIC CAPITAL ZETA +1D721 ; [.1917.0020.000B.1D721] # MATHEMATICAL BOLD ITALIC CAPITAL ZETA +1D75B ; [.1917.0020.000B.1D75B] # MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA +1D795 ; [.1917.0020.000B.1D795] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA +0371 ; [.1918.0020.0002.0371] # GREEK SMALL LETTER HETA +0370 ; [.1918.0020.0008.0370] # GREEK CAPITAL LETTER HETA +03B7 ; [.1919.0020.0002.03B7] # GREEK SMALL LETTER ETA +1D6C8 ; [.1919.0020.0005.1D6C8] # MATHEMATICAL BOLD SMALL ETA +1D702 ; [.1919.0020.0005.1D702] # MATHEMATICAL ITALIC SMALL ETA +1D73C ; [.1919.0020.0005.1D73C] # MATHEMATICAL BOLD ITALIC SMALL ETA +1D776 ; [.1919.0020.0005.1D776] # MATHEMATICAL SANS-SERIF BOLD SMALL ETA +1D7B0 ; [.1919.0020.0005.1D7B0] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA +0397 ; [.1919.0020.0008.0397] # GREEK CAPITAL LETTER ETA +1D6AE ; [.1919.0020.000B.1D6AE] # MATHEMATICAL BOLD CAPITAL ETA +1D6E8 ; [.1919.0020.000B.1D6E8] # MATHEMATICAL ITALIC CAPITAL ETA +1D722 ; [.1919.0020.000B.1D722] # MATHEMATICAL BOLD ITALIC CAPITAL ETA +1D75C ; [.1919.0020.000B.1D75C] # MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA +1D796 ; [.1919.0020.000B.1D796] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA +1F20 ; [.1919.0020.0002.03B7][.0000.0022.0002.0313] # GREEK SMALL LETTER ETA WITH PSILI +1F28 ; [.1919.0020.0008.0397][.0000.0022.0002.0313] # GREEK CAPITAL LETTER ETA WITH PSILI +1F24 ; [.1919.0020.0002.03B7][.0000.0022.0002.0313][.0000.0032.0002.0301] # GREEK SMALL LETTER ETA WITH PSILI AND OXIA +1F2C ; [.1919.0020.0008.0397][.0000.0022.0002.0313][.0000.0032.0002.0301] # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA +1F94 ; [.1919.0020.0002.03B7][.0000.0022.0002.0313][.0000.0032.0002.0301][.0000.007F.0002.0345] # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI +1F9C ; [.1919.0020.0008.0397][.0000.0022.0002.0313][.0000.0032.0002.0301][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F22 ; [.1919.0020.0002.03B7][.0000.0022.0002.0313][.0000.0035.0002.0300] # GREEK SMALL LETTER ETA WITH PSILI AND VARIA +1F2A ; [.1919.0020.0008.0397][.0000.0022.0002.0313][.0000.0035.0002.0300] # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA +1F92 ; [.1919.0020.0002.03B7][.0000.0022.0002.0313][.0000.0035.0002.0300][.0000.007F.0002.0345] # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI +1F9A ; [.1919.0020.0008.0397][.0000.0022.0002.0313][.0000.0035.0002.0300][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F26 ; [.1919.0020.0002.03B7][.0000.0022.0002.0313][.0000.0045.0002.0342] # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI +1F2E ; [.1919.0020.0008.0397][.0000.0022.0002.0313][.0000.0045.0002.0342] # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI +1F96 ; [.1919.0020.0002.03B7][.0000.0022.0002.0313][.0000.0045.0002.0342][.0000.007F.0002.0345] # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +1F9E ; [.1919.0020.0008.0397][.0000.0022.0002.0313][.0000.0045.0002.0342][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1F90 ; [.1919.0020.0002.03B7][.0000.0022.0002.0313][.0000.007F.0002.0345] # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI +1F98 ; [.1919.0020.0008.0397][.0000.0022.0002.0313][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI +1F21 ; [.1919.0020.0002.03B7][.0000.002A.0002.0314] # GREEK SMALL LETTER ETA WITH DASIA +1F29 ; [.1919.0020.0008.0397][.0000.002A.0002.0314] # GREEK CAPITAL LETTER ETA WITH DASIA +1F25 ; [.1919.0020.0002.03B7][.0000.002A.0002.0314][.0000.0032.0002.0301] # GREEK SMALL LETTER ETA WITH DASIA AND OXIA +1F2D ; [.1919.0020.0008.0397][.0000.002A.0002.0314][.0000.0032.0002.0301] # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA +1F95 ; [.1919.0020.0002.03B7][.0000.002A.0002.0314][.0000.0032.0002.0301][.0000.007F.0002.0345] # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI +1F9D ; [.1919.0020.0008.0397][.0000.002A.0002.0314][.0000.0032.0002.0301][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F23 ; [.1919.0020.0002.03B7][.0000.002A.0002.0314][.0000.0035.0002.0300] # GREEK SMALL LETTER ETA WITH DASIA AND VARIA +1F2B ; [.1919.0020.0008.0397][.0000.002A.0002.0314][.0000.0035.0002.0300] # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA +1F93 ; [.1919.0020.0002.03B7][.0000.002A.0002.0314][.0000.0035.0002.0300][.0000.007F.0002.0345] # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI +1F9B ; [.1919.0020.0008.0397][.0000.002A.0002.0314][.0000.0035.0002.0300][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F27 ; [.1919.0020.0002.03B7][.0000.002A.0002.0314][.0000.0045.0002.0342] # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI +1F2F ; [.1919.0020.0008.0397][.0000.002A.0002.0314][.0000.0045.0002.0342] # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI +1F97 ; [.1919.0020.0002.03B7][.0000.002A.0002.0314][.0000.0045.0002.0342][.0000.007F.0002.0345] # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1F9F ; [.1919.0020.0008.0397][.0000.002A.0002.0314][.0000.0045.0002.0342][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1F91 ; [.1919.0020.0002.03B7][.0000.002A.0002.0314][.0000.007F.0002.0345] # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI +1F99 ; [.1919.0020.0008.0397][.0000.002A.0002.0314][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI +03AE ; [.1919.0020.0002.03B7][.0000.0032.0002.0301] # GREEK SMALL LETTER ETA WITH TONOS +1F75 ; [.1919.0020.0002.03B7][.0000.0032.0002.0301] # GREEK SMALL LETTER ETA WITH OXIA +0389 ; [.1919.0020.0008.0397][.0000.0032.0002.0301] # GREEK CAPITAL LETTER ETA WITH TONOS +1FCB ; [.1919.0020.0008.0397][.0000.0032.0002.0301] # GREEK CAPITAL LETTER ETA WITH OXIA +1FC4 ; [.1919.0020.0002.03B7][.0000.0032.0002.0301][.0000.007F.0002.0345] # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI +1F74 ; [.1919.0020.0002.03B7][.0000.0035.0002.0300] # GREEK SMALL LETTER ETA WITH VARIA +1FCA ; [.1919.0020.0008.0397][.0000.0035.0002.0300] # GREEK CAPITAL LETTER ETA WITH VARIA +1FC2 ; [.1919.0020.0002.03B7][.0000.0035.0002.0300][.0000.007F.0002.0345] # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI +1FC6 ; [.1919.0020.0002.03B7][.0000.0045.0002.0342] # GREEK SMALL LETTER ETA WITH PERISPOMENI +1FC7 ; [.1919.0020.0002.03B7][.0000.0045.0002.0342][.0000.007F.0002.0345] # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI +1FC3 ; [.1919.0020.0002.03B7][.0000.007F.0002.0345] # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI +1FCC ; [.1919.0020.0008.0397][.0000.007F.0002.0345] # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI +03B8 ; [.191A.0020.0002.03B8] # GREEK SMALL LETTER THETA +03D1 ; [.191A.0020.0004.03D1] # GREEK THETA SYMBOL +1D6C9 ; [.191A.0020.0005.1D6C9] # MATHEMATICAL BOLD SMALL THETA +1D6DD ; [.191A.0020.0005.1D6DD] # MATHEMATICAL BOLD THETA SYMBOL +1D703 ; [.191A.0020.0005.1D703] # MATHEMATICAL ITALIC SMALL THETA +1D717 ; [.191A.0020.0005.1D717] # MATHEMATICAL ITALIC THETA SYMBOL +1D73D ; [.191A.0020.0005.1D73D] # MATHEMATICAL BOLD ITALIC SMALL THETA +1D751 ; [.191A.0020.0005.1D751] # MATHEMATICAL BOLD ITALIC THETA SYMBOL +1D777 ; [.191A.0020.0005.1D777] # MATHEMATICAL SANS-SERIF BOLD SMALL THETA +1D78B ; [.191A.0020.0005.1D78B] # MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL +1D7B1 ; [.191A.0020.0005.1D7B1] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA +1D7C5 ; [.191A.0020.0005.1D7C5] # MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL +0398 ; [.191A.0020.0008.0398] # GREEK CAPITAL LETTER THETA +03F4 ; [.191A.0020.000A.03F4] # GREEK CAPITAL THETA SYMBOL +1D6AF ; [.191A.0020.000B.1D6AF] # MATHEMATICAL BOLD CAPITAL THETA +1D6B9 ; [.191A.0020.000B.1D6B9] # MATHEMATICAL BOLD CAPITAL THETA SYMBOL +1D6E9 ; [.191A.0020.000B.1D6E9] # MATHEMATICAL ITALIC CAPITAL THETA +1D6F3 ; [.191A.0020.000B.1D6F3] # MATHEMATICAL ITALIC CAPITAL THETA SYMBOL +1D723 ; [.191A.0020.000B.1D723] # MATHEMATICAL BOLD ITALIC CAPITAL THETA +1D72D ; [.191A.0020.000B.1D72D] # MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL +1D75D ; [.191A.0020.000B.1D75D] # MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA +1D767 ; [.191A.0020.000B.1D767] # MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL +1D797 ; [.191A.0020.000B.1D797] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA +1D7A1 ; [.191A.0020.000B.1D7A1] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL +1DBF ; [.191A.0020.0014.1DBF] # MODIFIER LETTER SMALL THETA +03B9 ; [.191B.0020.0002.03B9] # GREEK SMALL LETTER IOTA +1FBE ; [.191B.0020.0002.1FBE] # GREEK PROSGEGRAMMENI +037A ; [.191B.0020.0004.037A] # GREEK YPOGEGRAMMENI +1D6CA ; [.191B.0020.0005.1D6CA] # MATHEMATICAL BOLD SMALL IOTA +1D704 ; [.191B.0020.0005.1D704] # MATHEMATICAL ITALIC SMALL IOTA +1D73E ; [.191B.0020.0005.1D73E] # MATHEMATICAL BOLD ITALIC SMALL IOTA +1D778 ; [.191B.0020.0005.1D778] # MATHEMATICAL SANS-SERIF BOLD SMALL IOTA +1D7B2 ; [.191B.0020.0005.1D7B2] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA +0399 ; [.191B.0020.0008.0399] # GREEK CAPITAL LETTER IOTA +1D6B0 ; [.191B.0020.000B.1D6B0] # MATHEMATICAL BOLD CAPITAL IOTA +1D6EA ; [.191B.0020.000B.1D6EA] # MATHEMATICAL ITALIC CAPITAL IOTA +1D724 ; [.191B.0020.000B.1D724] # MATHEMATICAL BOLD ITALIC CAPITAL IOTA +1D75E ; [.191B.0020.000B.1D75E] # MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA +1D798 ; [.191B.0020.000B.1D798] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA +1F30 ; [.191B.0020.0002.03B9][.0000.0022.0002.0313] # GREEK SMALL LETTER IOTA WITH PSILI +1F38 ; [.191B.0020.0008.0399][.0000.0022.0002.0313] # GREEK CAPITAL LETTER IOTA WITH PSILI +1F34 ; [.191B.0020.0002.03B9][.0000.0022.0002.0313][.0000.0032.0002.0301] # GREEK SMALL LETTER IOTA WITH PSILI AND OXIA +1F3C ; [.191B.0020.0008.0399][.0000.0022.0002.0313][.0000.0032.0002.0301] # GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA +1F32 ; [.191B.0020.0002.03B9][.0000.0022.0002.0313][.0000.0035.0002.0300] # GREEK SMALL LETTER IOTA WITH PSILI AND VARIA +1F3A ; [.191B.0020.0008.0399][.0000.0022.0002.0313][.0000.0035.0002.0300] # GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA +1F36 ; [.191B.0020.0002.03B9][.0000.0022.0002.0313][.0000.0045.0002.0342] # GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI +1F3E ; [.191B.0020.0008.0399][.0000.0022.0002.0313][.0000.0045.0002.0342] # GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI +1F31 ; [.191B.0020.0002.03B9][.0000.002A.0002.0314] # GREEK SMALL LETTER IOTA WITH DASIA +1F39 ; [.191B.0020.0008.0399][.0000.002A.0002.0314] # GREEK CAPITAL LETTER IOTA WITH DASIA +1F35 ; [.191B.0020.0002.03B9][.0000.002A.0002.0314][.0000.0032.0002.0301] # GREEK SMALL LETTER IOTA WITH DASIA AND OXIA +1F3D ; [.191B.0020.0008.0399][.0000.002A.0002.0314][.0000.0032.0002.0301] # GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA +1F33 ; [.191B.0020.0002.03B9][.0000.002A.0002.0314][.0000.0035.0002.0300] # GREEK SMALL LETTER IOTA WITH DASIA AND VARIA +1F3B ; [.191B.0020.0008.0399][.0000.002A.0002.0314][.0000.0035.0002.0300] # GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA +1F37 ; [.191B.0020.0002.03B9][.0000.002A.0002.0314][.0000.0045.0002.0342] # GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI +1F3F ; [.191B.0020.0008.0399][.0000.002A.0002.0314][.0000.0045.0002.0342] # GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI +03AF ; [.191B.0020.0002.03B9][.0000.0032.0002.0301] # GREEK SMALL LETTER IOTA WITH TONOS +1F77 ; [.191B.0020.0002.03B9][.0000.0032.0002.0301] # GREEK SMALL LETTER IOTA WITH OXIA +038A ; [.191B.0020.0008.0399][.0000.0032.0002.0301] # GREEK CAPITAL LETTER IOTA WITH TONOS +1FDB ; [.191B.0020.0008.0399][.0000.0032.0002.0301] # GREEK CAPITAL LETTER IOTA WITH OXIA +1F76 ; [.191B.0020.0002.03B9][.0000.0035.0002.0300] # GREEK SMALL LETTER IOTA WITH VARIA +1FDA ; [.191B.0020.0008.0399][.0000.0035.0002.0300] # GREEK CAPITAL LETTER IOTA WITH VARIA +1FD0 ; [.191B.0020.0002.03B9][.0000.0037.0002.0306] # GREEK SMALL LETTER IOTA WITH VRACHY +1FD8 ; [.191B.0020.0008.0399][.0000.0037.0002.0306] # GREEK CAPITAL LETTER IOTA WITH VRACHY +1FD6 ; [.191B.0020.0002.03B9][.0000.0045.0002.0342] # GREEK SMALL LETTER IOTA WITH PERISPOMENI +03CA ; [.191B.0020.0002.03B9][.0000.0047.0002.0308] # GREEK SMALL LETTER IOTA WITH DIALYTIKA +03AA ; [.191B.0020.0008.0399][.0000.0047.0002.0308] # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +0390 ; [.191B.0020.0002.03B9][.0000.0047.0002.0308][.0000.0032.0002.0301] # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +1FD3 ; [.191B.0020.0002.03B9][.0000.0047.0002.0308][.0000.0032.0002.0301] # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA +1FD2 ; [.191B.0020.0002.03B9][.0000.0047.0002.0308][.0000.0035.0002.0300] # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA +1FD7 ; [.191B.0020.0002.03B9][.0000.0047.0002.0308][.0000.0045.0002.0342] # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI +1FD1 ; [.191B.0020.0002.03B9][.0000.005B.0002.0304] # GREEK SMALL LETTER IOTA WITH MACRON +1FD9 ; [.191B.0020.0008.0399][.0000.005B.0002.0304] # GREEK CAPITAL LETTER IOTA WITH MACRON +03F3 ; [.191C.0020.0002.03F3] # GREEK LETTER YOT +03BA ; [.191D.0020.0002.03BA] # GREEK SMALL LETTER KAPPA +03F0 ; [.191D.0020.0004.03F0] # GREEK KAPPA SYMBOL +1D6CB ; [.191D.0020.0005.1D6CB] # MATHEMATICAL BOLD SMALL KAPPA +1D6DE ; [.191D.0020.0005.1D6DE] # MATHEMATICAL BOLD KAPPA SYMBOL +1D705 ; [.191D.0020.0005.1D705] # MATHEMATICAL ITALIC SMALL KAPPA +1D718 ; [.191D.0020.0005.1D718] # MATHEMATICAL ITALIC KAPPA SYMBOL +1D73F ; [.191D.0020.0005.1D73F] # MATHEMATICAL BOLD ITALIC SMALL KAPPA +1D752 ; [.191D.0020.0005.1D752] # MATHEMATICAL BOLD ITALIC KAPPA SYMBOL +1D779 ; [.191D.0020.0005.1D779] # MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA +1D78C ; [.191D.0020.0005.1D78C] # MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL +1D7B3 ; [.191D.0020.0005.1D7B3] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA +1D7C6 ; [.191D.0020.0005.1D7C6] # MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL +039A ; [.191D.0020.0008.039A] # GREEK CAPITAL LETTER KAPPA +1D6B1 ; [.191D.0020.000B.1D6B1] # MATHEMATICAL BOLD CAPITAL KAPPA +1D6EB ; [.191D.0020.000B.1D6EB] # MATHEMATICAL ITALIC CAPITAL KAPPA +1D725 ; [.191D.0020.000B.1D725] # MATHEMATICAL BOLD ITALIC CAPITAL KAPPA +1D75F ; [.191D.0020.000B.1D75F] # MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA +1D799 ; [.191D.0020.000B.1D799] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA +03D7 ; [.191D.0020.0004.03D7][.190E.0020.0004.03D7][.191B.0020.001F.03D7] # GREEK KAI SYMBOL +03CF ; [.191D.0020.000A.03CF][.190E.0020.0004.03CF][.191B.0020.001F.03CF] # GREEK CAPITAL KAI SYMBOL +03BB ; [.191E.0020.0002.03BB] # GREEK SMALL LETTER LAMDA +1D6CC ; [.191E.0020.0005.1D6CC] # MATHEMATICAL BOLD SMALL LAMDA +1D706 ; [.191E.0020.0005.1D706] # MATHEMATICAL ITALIC SMALL LAMDA +1D740 ; [.191E.0020.0005.1D740] # MATHEMATICAL BOLD ITALIC SMALL LAMDA +1D77A ; [.191E.0020.0005.1D77A] # MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA +1D7B4 ; [.191E.0020.0005.1D7B4] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA +039B ; [.191E.0020.0008.039B] # GREEK CAPITAL LETTER LAMDA +1D6B2 ; [.191E.0020.000B.1D6B2] # MATHEMATICAL BOLD CAPITAL LAMDA +1D6EC ; [.191E.0020.000B.1D6EC] # MATHEMATICAL ITALIC CAPITAL LAMDA +1D726 ; [.191E.0020.000B.1D726] # MATHEMATICAL BOLD ITALIC CAPITAL LAMDA +1D760 ; [.191E.0020.000B.1D760] # MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA +1D79A ; [.191E.0020.000B.1D79A] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA +1D27 ; [.191F.0020.0002.1D27] # GREEK LETTER SMALL CAPITAL LAMDA +03BC ; [.1920.0020.0002.03BC] # GREEK SMALL LETTER MU +00B5 ; [.1920.0020.0004.00B5] # MICRO SIGN +1D6CD ; [.1920.0020.0005.1D6CD] # MATHEMATICAL BOLD SMALL MU +1D707 ; [.1920.0020.0005.1D707] # MATHEMATICAL ITALIC SMALL MU +1D741 ; [.1920.0020.0005.1D741] # MATHEMATICAL BOLD ITALIC SMALL MU +1D77B ; [.1920.0020.0005.1D77B] # MATHEMATICAL SANS-SERIF BOLD SMALL MU +1D7B5 ; [.1920.0020.0005.1D7B5] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU +039C ; [.1920.0020.0008.039C] # GREEK CAPITAL LETTER MU +1D6B3 ; [.1920.0020.000B.1D6B3] # MATHEMATICAL BOLD CAPITAL MU +1D6ED ; [.1920.0020.000B.1D6ED] # MATHEMATICAL ITALIC CAPITAL MU +1D727 ; [.1920.0020.000B.1D727] # MATHEMATICAL BOLD ITALIC CAPITAL MU +1D761 ; [.1920.0020.000B.1D761] # MATHEMATICAL SANS-SERIF BOLD CAPITAL MU +1D79B ; [.1920.0020.000B.1D79B] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU +3382 ; [.1920.0020.001C.3382][.15D4.0020.001D.3382] # SQUARE MU A +338C ; [.1920.0020.001C.338C][.1669.0020.001D.338C] # SQUARE MU F +338D ; [.1920.0020.001C.338D][.1676.0020.001C.338D] # SQUARE MU G +3395 ; [.1920.0020.001C.3395][.16F6.0020.001C.3395] # SQUARE MU L +339B ; [.1920.0020.001C.339B][.1726.0020.001C.339B] # SQUARE MU M +33B2 ; [.1920.0020.001C.33B2][.17D8.0020.001C.33B2] # SQUARE MU S +33B6 ; [.1920.0020.001C.33B6][.1844.0020.001D.33B6] # SQUARE MU V +33BC ; [.1920.0020.001C.33BC][.1856.0020.001D.33BC] # SQUARE MU W +03BD ; [.1921.0020.0002.03BD] # GREEK SMALL LETTER NU +1D6CE ; [.1921.0020.0005.1D6CE] # MATHEMATICAL BOLD SMALL NU +1D708 ; [.1921.0020.0005.1D708] # MATHEMATICAL ITALIC SMALL NU +1D742 ; [.1921.0020.0005.1D742] # MATHEMATICAL BOLD ITALIC SMALL NU +1D77C ; [.1921.0020.0005.1D77C] # MATHEMATICAL SANS-SERIF BOLD SMALL NU +1D7B6 ; [.1921.0020.0005.1D7B6] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU +039D ; [.1921.0020.0008.039D] # GREEK CAPITAL LETTER NU +1D6B4 ; [.1921.0020.000B.1D6B4] # MATHEMATICAL BOLD CAPITAL NU +1D6EE ; [.1921.0020.000B.1D6EE] # MATHEMATICAL ITALIC CAPITAL NU +1D728 ; [.1921.0020.000B.1D728] # MATHEMATICAL BOLD ITALIC CAPITAL NU +1D762 ; [.1921.0020.000B.1D762] # MATHEMATICAL SANS-SERIF BOLD CAPITAL NU +1D79C ; [.1921.0020.000B.1D79C] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU +03BE ; [.1922.0020.0002.03BE] # GREEK SMALL LETTER XI +1D6CF ; [.1922.0020.0005.1D6CF] # MATHEMATICAL BOLD SMALL XI +1D709 ; [.1922.0020.0005.1D709] # MATHEMATICAL ITALIC SMALL XI +1D743 ; [.1922.0020.0005.1D743] # MATHEMATICAL BOLD ITALIC SMALL XI +1D77D ; [.1922.0020.0005.1D77D] # MATHEMATICAL SANS-SERIF BOLD SMALL XI +1D7B7 ; [.1922.0020.0005.1D7B7] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI +039E ; [.1922.0020.0008.039E] # GREEK CAPITAL LETTER XI +1D6B5 ; [.1922.0020.000B.1D6B5] # MATHEMATICAL BOLD CAPITAL XI +1D6EF ; [.1922.0020.000B.1D6EF] # MATHEMATICAL ITALIC CAPITAL XI +1D729 ; [.1922.0020.000B.1D729] # MATHEMATICAL BOLD ITALIC CAPITAL XI +1D763 ; [.1922.0020.000B.1D763] # MATHEMATICAL SANS-SERIF BOLD CAPITAL XI +1D79D ; [.1922.0020.000B.1D79D] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI +03BF ; [.1923.0020.0002.03BF] # GREEK SMALL LETTER OMICRON +1D6D0 ; [.1923.0020.0005.1D6D0] # MATHEMATICAL BOLD SMALL OMICRON +1D70A ; [.1923.0020.0005.1D70A] # MATHEMATICAL ITALIC SMALL OMICRON +1D744 ; [.1923.0020.0005.1D744] # MATHEMATICAL BOLD ITALIC SMALL OMICRON +1D77E ; [.1923.0020.0005.1D77E] # MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON +1D7B8 ; [.1923.0020.0005.1D7B8] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON +039F ; [.1923.0020.0008.039F] # GREEK CAPITAL LETTER OMICRON +1D6B6 ; [.1923.0020.000B.1D6B6] # MATHEMATICAL BOLD CAPITAL OMICRON +1D6F0 ; [.1923.0020.000B.1D6F0] # MATHEMATICAL ITALIC CAPITAL OMICRON +1D72A ; [.1923.0020.000B.1D72A] # MATHEMATICAL BOLD ITALIC CAPITAL OMICRON +1D764 ; [.1923.0020.000B.1D764] # MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON +1D79E ; [.1923.0020.000B.1D79E] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON +1F40 ; [.1923.0020.0002.03BF][.0000.0022.0002.0313] # GREEK SMALL LETTER OMICRON WITH PSILI +1F48 ; [.1923.0020.0008.039F][.0000.0022.0002.0313] # GREEK CAPITAL LETTER OMICRON WITH PSILI +1F44 ; [.1923.0020.0002.03BF][.0000.0022.0002.0313][.0000.0032.0002.0301] # GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA +1F4C ; [.1923.0020.0008.039F][.0000.0022.0002.0313][.0000.0032.0002.0301] # GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA +1F42 ; [.1923.0020.0002.03BF][.0000.0022.0002.0313][.0000.0035.0002.0300] # GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA +1F4A ; [.1923.0020.0008.039F][.0000.0022.0002.0313][.0000.0035.0002.0300] # GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA +1F41 ; [.1923.0020.0002.03BF][.0000.002A.0002.0314] # GREEK SMALL LETTER OMICRON WITH DASIA +1F49 ; [.1923.0020.0008.039F][.0000.002A.0002.0314] # GREEK CAPITAL LETTER OMICRON WITH DASIA +1F45 ; [.1923.0020.0002.03BF][.0000.002A.0002.0314][.0000.0032.0002.0301] # GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA +1F4D ; [.1923.0020.0008.039F][.0000.002A.0002.0314][.0000.0032.0002.0301] # GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA +1F43 ; [.1923.0020.0002.03BF][.0000.002A.0002.0314][.0000.0035.0002.0300] # GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA +1F4B ; [.1923.0020.0008.039F][.0000.002A.0002.0314][.0000.0035.0002.0300] # GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA +03CC ; [.1923.0020.0002.03BF][.0000.0032.0002.0301] # GREEK SMALL LETTER OMICRON WITH TONOS +1F79 ; [.1923.0020.0002.03BF][.0000.0032.0002.0301] # GREEK SMALL LETTER OMICRON WITH OXIA +038C ; [.1923.0020.0008.039F][.0000.0032.0002.0301] # GREEK CAPITAL LETTER OMICRON WITH TONOS +1FF9 ; [.1923.0020.0008.039F][.0000.0032.0002.0301] # GREEK CAPITAL LETTER OMICRON WITH OXIA +1F78 ; [.1923.0020.0002.03BF][.0000.0035.0002.0300] # GREEK SMALL LETTER OMICRON WITH VARIA +1FF8 ; [.1923.0020.0008.039F][.0000.0035.0002.0300] # GREEK CAPITAL LETTER OMICRON WITH VARIA +03C0 ; [.1924.0020.0002.03C0] # GREEK SMALL LETTER PI +03D6 ; [.1924.0020.0004.03D6] # GREEK PI SYMBOL +213C ; [.1924.0020.0005.213C] # DOUBLE-STRUCK SMALL PI +1D6D1 ; [.1924.0020.0005.1D6D1] # MATHEMATICAL BOLD SMALL PI +1D6E1 ; [.1924.0020.0005.1D6E1] # MATHEMATICAL BOLD PI SYMBOL +1D70B ; [.1924.0020.0005.1D70B] # MATHEMATICAL ITALIC SMALL PI +1D71B ; [.1924.0020.0005.1D71B] # MATHEMATICAL ITALIC PI SYMBOL +1D745 ; [.1924.0020.0005.1D745] # MATHEMATICAL BOLD ITALIC SMALL PI +1D755 ; [.1924.0020.0005.1D755] # MATHEMATICAL BOLD ITALIC PI SYMBOL +1D77F ; [.1924.0020.0005.1D77F] # MATHEMATICAL SANS-SERIF BOLD SMALL PI +1D78F ; [.1924.0020.0005.1D78F] # MATHEMATICAL SANS-SERIF BOLD PI SYMBOL +1D7B9 ; [.1924.0020.0005.1D7B9] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI +1D7C9 ; [.1924.0020.0005.1D7C9] # MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL +03A0 ; [.1924.0020.0008.03A0] # GREEK CAPITAL LETTER PI +213F ; [.1924.0020.000B.213F] # DOUBLE-STRUCK CAPITAL PI +1D6B7 ; [.1924.0020.000B.1D6B7] # MATHEMATICAL BOLD CAPITAL PI +1D6F1 ; [.1924.0020.000B.1D6F1] # MATHEMATICAL ITALIC CAPITAL PI +1D72B ; [.1924.0020.000B.1D72B] # MATHEMATICAL BOLD ITALIC CAPITAL PI +1D765 ; [.1924.0020.000B.1D765] # MATHEMATICAL SANS-SERIF BOLD CAPITAL PI +1D79F ; [.1924.0020.000B.1D79F] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI +1D28 ; [.1925.0020.0002.1D28] # GREEK LETTER SMALL CAPITAL PI +03FB ; [.1926.0020.0002.03FB] # GREEK SMALL LETTER SAN +03FA ; [.1926.0020.0008.03FA] # GREEK CAPITAL LETTER SAN +03DF ; [.1927.0020.0002.03DF] # GREEK SMALL LETTER KOPPA +03DE ; [.1927.0020.0008.03DE] # GREEK LETTER KOPPA +03D9 ; [.1928.0020.0002.03D9] # GREEK SMALL LETTER ARCHAIC KOPPA +03D8 ; [.1928.0020.0008.03D8] # GREEK LETTER ARCHAIC KOPPA +03C1 ; [.1929.0020.0002.03C1] # GREEK SMALL LETTER RHO +03F1 ; [.1929.0020.0004.03F1] # GREEK RHO SYMBOL +1D6D2 ; [.1929.0020.0005.1D6D2] # MATHEMATICAL BOLD SMALL RHO +1D6E0 ; [.1929.0020.0005.1D6E0] # MATHEMATICAL BOLD RHO SYMBOL +1D70C ; [.1929.0020.0005.1D70C] # MATHEMATICAL ITALIC SMALL RHO +1D71A ; [.1929.0020.0005.1D71A] # MATHEMATICAL ITALIC RHO SYMBOL +1D746 ; [.1929.0020.0005.1D746] # MATHEMATICAL BOLD ITALIC SMALL RHO +1D754 ; [.1929.0020.0005.1D754] # MATHEMATICAL BOLD ITALIC RHO SYMBOL +1D780 ; [.1929.0020.0005.1D780] # MATHEMATICAL SANS-SERIF BOLD SMALL RHO +1D78E ; [.1929.0020.0005.1D78E] # MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL +1D7BA ; [.1929.0020.0005.1D7BA] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO +1D7C8 ; [.1929.0020.0005.1D7C8] # MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL +03A1 ; [.1929.0020.0008.03A1] # GREEK CAPITAL LETTER RHO +1D6B8 ; [.1929.0020.000B.1D6B8] # MATHEMATICAL BOLD CAPITAL RHO +1D6F2 ; [.1929.0020.000B.1D6F2] # MATHEMATICAL ITALIC CAPITAL RHO +1D72C ; [.1929.0020.000B.1D72C] # MATHEMATICAL BOLD ITALIC CAPITAL RHO +1D766 ; [.1929.0020.000B.1D766] # MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO +1D7A0 ; [.1929.0020.000B.1D7A0] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO +1D68 ; [.1929.0020.0015.1D68] # GREEK SUBSCRIPT SMALL LETTER RHO +1FE4 ; [.1929.0020.0002.03C1][.0000.0022.0002.0313] # GREEK SMALL LETTER RHO WITH PSILI +1FE5 ; [.1929.0020.0002.03C1][.0000.002A.0002.0314] # GREEK SMALL LETTER RHO WITH DASIA +1FEC ; [.1929.0020.0008.03A1][.0000.002A.0002.0314] # GREEK CAPITAL LETTER RHO WITH DASIA +1D29 ; [.192A.0020.0002.1D29] # GREEK LETTER SMALL CAPITAL RHO +03FC ; [.192B.0020.0002.03FC] # GREEK RHO WITH STROKE SYMBOL +03C3 ; [.192C.0020.0002.03C3] # GREEK SMALL LETTER SIGMA +03F2 ; [.192C.0020.0004.03F2] # GREEK LUNATE SIGMA SYMBOL +1D6D3 ; [.192C.0020.0005.1D6D3] # MATHEMATICAL BOLD SMALL FINAL SIGMA +1D6D4 ; [.192C.0020.0005.1D6D4] # MATHEMATICAL BOLD SMALL SIGMA +1D70D ; [.192C.0020.0005.1D70D] # MATHEMATICAL ITALIC SMALL FINAL SIGMA +1D70E ; [.192C.0020.0005.1D70E] # MATHEMATICAL ITALIC SMALL SIGMA +1D747 ; [.192C.0020.0005.1D747] # MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA +1D748 ; [.192C.0020.0005.1D748] # MATHEMATICAL BOLD ITALIC SMALL SIGMA +1D781 ; [.192C.0020.0005.1D781] # MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA +1D782 ; [.192C.0020.0005.1D782] # MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA +1D7BB ; [.192C.0020.0005.1D7BB] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA +1D7BC ; [.192C.0020.0005.1D7BC] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA +03A3 ; [.192C.0020.0008.03A3] # GREEK CAPITAL LETTER SIGMA +03F9 ; [.192C.0020.000A.03F9] # GREEK CAPITAL LUNATE SIGMA SYMBOL +1D6BA ; [.192C.0020.000B.1D6BA] # MATHEMATICAL BOLD CAPITAL SIGMA +1D6F4 ; [.192C.0020.000B.1D6F4] # MATHEMATICAL ITALIC CAPITAL SIGMA +1D72E ; [.192C.0020.000B.1D72E] # MATHEMATICAL BOLD ITALIC CAPITAL SIGMA +1D768 ; [.192C.0020.000B.1D768] # MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA +1D7A2 ; [.192C.0020.000B.1D7A2] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA +03C2 ; [.192C.0020.0019.03C2] # GREEK SMALL LETTER FINAL SIGMA +037C ; [.192D.0020.0002.037C] # GREEK SMALL DOTTED LUNATE SIGMA SYMBOL +03FE ; [.192D.0020.0008.03FE] # GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL +037B ; [.192E.0020.0002.037B] # GREEK SMALL REVERSED LUNATE SIGMA SYMBOL +03FD ; [.192E.0020.0008.03FD] # GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL +037D ; [.192F.0020.0002.037D] # GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL +03FF ; [.192F.0020.0008.03FF] # GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL +03C4 ; [.1930.0020.0002.03C4] # GREEK SMALL LETTER TAU +1D6D5 ; [.1930.0020.0005.1D6D5] # MATHEMATICAL BOLD SMALL TAU +1D70F ; [.1930.0020.0005.1D70F] # MATHEMATICAL ITALIC SMALL TAU +1D749 ; [.1930.0020.0005.1D749] # MATHEMATICAL BOLD ITALIC SMALL TAU +1D783 ; [.1930.0020.0005.1D783] # MATHEMATICAL SANS-SERIF BOLD SMALL TAU +1D7BD ; [.1930.0020.0005.1D7BD] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU +03A4 ; [.1930.0020.0008.03A4] # GREEK CAPITAL LETTER TAU +1D6BB ; [.1930.0020.000B.1D6BB] # MATHEMATICAL BOLD CAPITAL TAU +1D6F5 ; [.1930.0020.000B.1D6F5] # MATHEMATICAL ITALIC CAPITAL TAU +1D72F ; [.1930.0020.000B.1D72F] # MATHEMATICAL BOLD ITALIC CAPITAL TAU +1D769 ; [.1930.0020.000B.1D769] # MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU +1D7A3 ; [.1930.0020.000B.1D7A3] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU +03C5 ; [.1931.0020.0002.03C5] # GREEK SMALL LETTER UPSILON +1D6D6 ; [.1931.0020.0005.1D6D6] # MATHEMATICAL BOLD SMALL UPSILON +1D710 ; [.1931.0020.0005.1D710] # MATHEMATICAL ITALIC SMALL UPSILON +1D74A ; [.1931.0020.0005.1D74A] # MATHEMATICAL BOLD ITALIC SMALL UPSILON +1D784 ; [.1931.0020.0005.1D784] # MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON +1D7BE ; [.1931.0020.0005.1D7BE] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON +03A5 ; [.1931.0020.0008.03A5] # GREEK CAPITAL LETTER UPSILON +03D2 ; [.1931.0020.000A.03D2] # GREEK UPSILON WITH HOOK SYMBOL +1D6BC ; [.1931.0020.000B.1D6BC] # MATHEMATICAL BOLD CAPITAL UPSILON +1D6F6 ; [.1931.0020.000B.1D6F6] # MATHEMATICAL ITALIC CAPITAL UPSILON +1D730 ; [.1931.0020.000B.1D730] # MATHEMATICAL BOLD ITALIC CAPITAL UPSILON +1D76A ; [.1931.0020.000B.1D76A] # MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON +1D7A4 ; [.1931.0020.000B.1D7A4] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON +1F50 ; [.1931.0020.0002.03C5][.0000.0022.0002.0313] # GREEK SMALL LETTER UPSILON WITH PSILI +1F54 ; [.1931.0020.0002.03C5][.0000.0022.0002.0313][.0000.0032.0002.0301] # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA +1F52 ; [.1931.0020.0002.03C5][.0000.0022.0002.0313][.0000.0035.0002.0300] # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA +1F56 ; [.1931.0020.0002.03C5][.0000.0022.0002.0313][.0000.0045.0002.0342] # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI +1F51 ; [.1931.0020.0002.03C5][.0000.002A.0002.0314] # GREEK SMALL LETTER UPSILON WITH DASIA +1F59 ; [.1931.0020.0008.03A5][.0000.002A.0002.0314] # GREEK CAPITAL LETTER UPSILON WITH DASIA +1F55 ; [.1931.0020.0002.03C5][.0000.002A.0002.0314][.0000.0032.0002.0301] # GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA +1F5D ; [.1931.0020.0008.03A5][.0000.002A.0002.0314][.0000.0032.0002.0301] # GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA +1F53 ; [.1931.0020.0002.03C5][.0000.002A.0002.0314][.0000.0035.0002.0300] # GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA +1F5B ; [.1931.0020.0008.03A5][.0000.002A.0002.0314][.0000.0035.0002.0300] # GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA +1F57 ; [.1931.0020.0002.03C5][.0000.002A.0002.0314][.0000.0045.0002.0342] # GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI +1F5F ; [.1931.0020.0008.03A5][.0000.002A.0002.0314][.0000.0045.0002.0342] # GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI +03CD ; [.1931.0020.0002.03C5][.0000.0032.0002.0301] # GREEK SMALL LETTER UPSILON WITH TONOS +1F7B ; [.1931.0020.0002.03C5][.0000.0032.0002.0301] # GREEK SMALL LETTER UPSILON WITH OXIA +038E ; [.1931.0020.0008.03A5][.0000.0032.0002.0301] # GREEK CAPITAL LETTER UPSILON WITH TONOS +1FEB ; [.1931.0020.0008.03A5][.0000.0032.0002.0301] # GREEK CAPITAL LETTER UPSILON WITH OXIA +03D3 ; [.1931.0020.000A.03D3][.0000.0032.0002.03D3] # GREEK UPSILON WITH ACUTE AND HOOK SYMBOL +1F7A ; [.1931.0020.0002.03C5][.0000.0035.0002.0300] # GREEK SMALL LETTER UPSILON WITH VARIA +1FEA ; [.1931.0020.0008.03A5][.0000.0035.0002.0300] # GREEK CAPITAL LETTER UPSILON WITH VARIA +1FE0 ; [.1931.0020.0002.03C5][.0000.0037.0002.0306] # GREEK SMALL LETTER UPSILON WITH VRACHY +1FE8 ; [.1931.0020.0008.03A5][.0000.0037.0002.0306] # GREEK CAPITAL LETTER UPSILON WITH VRACHY +1FE6 ; [.1931.0020.0002.03C5][.0000.0045.0002.0342] # GREEK SMALL LETTER UPSILON WITH PERISPOMENI +03CB ; [.1931.0020.0002.03C5][.0000.0047.0002.0308] # GREEK SMALL LETTER UPSILON WITH DIALYTIKA +03AB ; [.1931.0020.0008.03A5][.0000.0047.0002.0308] # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +03D4 ; [.1931.0020.000A.03D4][.0000.0047.0002.03D4] # GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL +03B0 ; [.1931.0020.0002.03C5][.0000.0047.0002.0308][.0000.0032.0002.0301] # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +1FE3 ; [.1931.0020.0002.03C5][.0000.0047.0002.0308][.0000.0032.0002.0301] # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA +1FE2 ; [.1931.0020.0002.03C5][.0000.0047.0002.0308][.0000.0035.0002.0300] # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA +1FE7 ; [.1931.0020.0002.03C5][.0000.0047.0002.0308][.0000.0045.0002.0342] # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI +1FE1 ; [.1931.0020.0002.03C5][.0000.005B.0002.0304] # GREEK SMALL LETTER UPSILON WITH MACRON +1FE9 ; [.1931.0020.0008.03A5][.0000.005B.0002.0304] # GREEK CAPITAL LETTER UPSILON WITH MACRON +03C6 ; [.1932.0020.0002.03C6] # GREEK SMALL LETTER PHI +03D5 ; [.1932.0020.0004.03D5] # GREEK PHI SYMBOL +1D6D7 ; [.1932.0020.0005.1D6D7] # MATHEMATICAL BOLD SMALL PHI +1D6DF ; [.1932.0020.0005.1D6DF] # MATHEMATICAL BOLD PHI SYMBOL +1D711 ; [.1932.0020.0005.1D711] # MATHEMATICAL ITALIC SMALL PHI +1D719 ; [.1932.0020.0005.1D719] # MATHEMATICAL ITALIC PHI SYMBOL +1D74B ; [.1932.0020.0005.1D74B] # MATHEMATICAL BOLD ITALIC SMALL PHI +1D753 ; [.1932.0020.0005.1D753] # MATHEMATICAL BOLD ITALIC PHI SYMBOL +1D785 ; [.1932.0020.0005.1D785] # MATHEMATICAL SANS-SERIF BOLD SMALL PHI +1D78D ; [.1932.0020.0005.1D78D] # MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL +1D7BF ; [.1932.0020.0005.1D7BF] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI +1D7C7 ; [.1932.0020.0005.1D7C7] # MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL +03A6 ; [.1932.0020.0008.03A6] # GREEK CAPITAL LETTER PHI +1D6BD ; [.1932.0020.000B.1D6BD] # MATHEMATICAL BOLD CAPITAL PHI +1D6F7 ; [.1932.0020.000B.1D6F7] # MATHEMATICAL ITALIC CAPITAL PHI +1D731 ; [.1932.0020.000B.1D731] # MATHEMATICAL BOLD ITALIC CAPITAL PHI +1D76B ; [.1932.0020.000B.1D76B] # MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI +1D7A5 ; [.1932.0020.000B.1D7A5] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI +1D60 ; [.1932.0020.0014.1D60] # MODIFIER LETTER SMALL GREEK PHI +1D69 ; [.1932.0020.0015.1D69] # GREEK SUBSCRIPT SMALL LETTER PHI +03C7 ; [.1933.0020.0002.03C7] # GREEK SMALL LETTER CHI +1D6D8 ; [.1933.0020.0005.1D6D8] # MATHEMATICAL BOLD SMALL CHI +1D712 ; [.1933.0020.0005.1D712] # MATHEMATICAL ITALIC SMALL CHI +1D74C ; [.1933.0020.0005.1D74C] # MATHEMATICAL BOLD ITALIC SMALL CHI +1D786 ; [.1933.0020.0005.1D786] # MATHEMATICAL SANS-SERIF BOLD SMALL CHI +1D7C0 ; [.1933.0020.0005.1D7C0] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI +03A7 ; [.1933.0020.0008.03A7] # GREEK CAPITAL LETTER CHI +1D6BE ; [.1933.0020.000B.1D6BE] # MATHEMATICAL BOLD CAPITAL CHI +1D6F8 ; [.1933.0020.000B.1D6F8] # MATHEMATICAL ITALIC CAPITAL CHI +1D732 ; [.1933.0020.000B.1D732] # MATHEMATICAL BOLD ITALIC CAPITAL CHI +1D76C ; [.1933.0020.000B.1D76C] # MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI +1D7A6 ; [.1933.0020.000B.1D7A6] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI +1D61 ; [.1933.0020.0014.1D61] # MODIFIER LETTER SMALL CHI +1D6A ; [.1933.0020.0015.1D6A] # GREEK SUBSCRIPT SMALL LETTER CHI +03C8 ; [.1934.0020.0002.03C8] # GREEK SMALL LETTER PSI +1D6D9 ; [.1934.0020.0005.1D6D9] # MATHEMATICAL BOLD SMALL PSI +1D713 ; [.1934.0020.0005.1D713] # MATHEMATICAL ITALIC SMALL PSI +1D74D ; [.1934.0020.0005.1D74D] # MATHEMATICAL BOLD ITALIC SMALL PSI +1D787 ; [.1934.0020.0005.1D787] # MATHEMATICAL SANS-SERIF BOLD SMALL PSI +1D7C1 ; [.1934.0020.0005.1D7C1] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI +03A8 ; [.1934.0020.0008.03A8] # GREEK CAPITAL LETTER PSI +1D6BF ; [.1934.0020.000B.1D6BF] # MATHEMATICAL BOLD CAPITAL PSI +1D6F9 ; [.1934.0020.000B.1D6F9] # MATHEMATICAL ITALIC CAPITAL PSI +1D733 ; [.1934.0020.000B.1D733] # MATHEMATICAL BOLD ITALIC CAPITAL PSI +1D76D ; [.1934.0020.000B.1D76D] # MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI +1D7A7 ; [.1934.0020.000B.1D7A7] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI +1D2A ; [.1935.0020.0002.1D2A] # GREEK LETTER SMALL CAPITAL PSI +03C9 ; [.1936.0020.0002.03C9] # GREEK SMALL LETTER OMEGA +1D6DA ; [.1936.0020.0005.1D6DA] # MATHEMATICAL BOLD SMALL OMEGA +1D714 ; [.1936.0020.0005.1D714] # MATHEMATICAL ITALIC SMALL OMEGA +1D74E ; [.1936.0020.0005.1D74E] # MATHEMATICAL BOLD ITALIC SMALL OMEGA +1D788 ; [.1936.0020.0005.1D788] # MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA +1D7C2 ; [.1936.0020.0005.1D7C2] # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA +03A9 ; [.1936.0020.0008.03A9] # GREEK CAPITAL LETTER OMEGA +2126 ; [.1936.0020.0008.2126] # OHM SIGN +1D6C0 ; [.1936.0020.000B.1D6C0] # MATHEMATICAL BOLD CAPITAL OMEGA +1D6FA ; [.1936.0020.000B.1D6FA] # MATHEMATICAL ITALIC CAPITAL OMEGA +1D734 ; [.1936.0020.000B.1D734] # MATHEMATICAL BOLD ITALIC CAPITAL OMEGA +1D76E ; [.1936.0020.000B.1D76E] # MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA +1D7A8 ; [.1936.0020.000B.1D7A8] # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA +1F60 ; [.1936.0020.0002.03C9][.0000.0022.0002.0313] # GREEK SMALL LETTER OMEGA WITH PSILI +1F68 ; [.1936.0020.0008.03A9][.0000.0022.0002.0313] # GREEK CAPITAL LETTER OMEGA WITH PSILI +1F64 ; [.1936.0020.0002.03C9][.0000.0022.0002.0313][.0000.0032.0002.0301] # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA +1F6C ; [.1936.0020.0008.03A9][.0000.0022.0002.0313][.0000.0032.0002.0301] # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA +1FA4 ; [.1936.0020.0002.03C9][.0000.0022.0002.0313][.0000.0032.0002.0301][.0000.007F.0002.0345] # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI +1FAC ; [.1936.0020.0008.03A9][.0000.0022.0002.0313][.0000.0032.0002.0301][.0000.007F.0002.0345] # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI +1F62 ; [.1936.0020.0002.03C9][.0000.0022.0002.0313][.0000.0035.0002.0300] # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA +1F6A ; [.1936.0020.0008.03A9][.0000.0022.0002.0313][.0000.0035.0002.0300] # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA +1FA2 ; [.1936.0020.0002.03C9][.0000.0022.0002.0313][.0000.0035.0002.0300][.0000.007F.0002.0345] # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI +1FAA ; [.1936.0020.0008.03A9][.0000.0022.0002.0313][.0000.0035.0002.0300][.0000.007F.0002.0345] # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI +1F66 ; [.1936.0020.0002.03C9][.0000.0022.0002.0313][.0000.0045.0002.0342] # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI +1F6E ; [.1936.0020.0008.03A9][.0000.0022.0002.0313][.0000.0045.0002.0342] # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI +1FA6 ; [.1936.0020.0002.03C9][.0000.0022.0002.0313][.0000.0045.0002.0342][.0000.007F.0002.0345] # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +1FAE ; [.1936.0020.0008.03A9][.0000.0022.0002.0313][.0000.0045.0002.0342][.0000.007F.0002.0345] # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +1FA0 ; [.1936.0020.0002.03C9][.0000.0022.0002.0313][.0000.007F.0002.0345] # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI +1FA8 ; [.1936.0020.0008.03A9][.0000.0022.0002.0313][.0000.007F.0002.0345] # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI +1F61 ; [.1936.0020.0002.03C9][.0000.002A.0002.0314] # GREEK SMALL LETTER OMEGA WITH DASIA +1F69 ; [.1936.0020.0008.03A9][.0000.002A.0002.0314] # GREEK CAPITAL LETTER OMEGA WITH DASIA +1F65 ; [.1936.0020.0002.03C9][.0000.002A.0002.0314][.0000.0032.0002.0301] # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA +1F6D ; [.1936.0020.0008.03A9][.0000.002A.0002.0314][.0000.0032.0002.0301] # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA +1FA5 ; [.1936.0020.0002.03C9][.0000.002A.0002.0314][.0000.0032.0002.0301][.0000.007F.0002.0345] # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI +1FAD ; [.1936.0020.0008.03A9][.0000.002A.0002.0314][.0000.0032.0002.0301][.0000.007F.0002.0345] # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI +1F63 ; [.1936.0020.0002.03C9][.0000.002A.0002.0314][.0000.0035.0002.0300] # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA +1F6B ; [.1936.0020.0008.03A9][.0000.002A.0002.0314][.0000.0035.0002.0300] # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA +1FA3 ; [.1936.0020.0002.03C9][.0000.002A.0002.0314][.0000.0035.0002.0300][.0000.007F.0002.0345] # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI +1FAB ; [.1936.0020.0008.03A9][.0000.002A.0002.0314][.0000.0035.0002.0300][.0000.007F.0002.0345] # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI +1F67 ; [.1936.0020.0002.03C9][.0000.002A.0002.0314][.0000.0045.0002.0342] # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI +1F6F ; [.1936.0020.0008.03A9][.0000.002A.0002.0314][.0000.0045.0002.0342] # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI +1FA7 ; [.1936.0020.0002.03C9][.0000.002A.0002.0314][.0000.0045.0002.0342][.0000.007F.0002.0345] # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +1FAF ; [.1936.0020.0008.03A9][.0000.002A.0002.0314][.0000.0045.0002.0342][.0000.007F.0002.0345] # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +1FA1 ; [.1936.0020.0002.03C9][.0000.002A.0002.0314][.0000.007F.0002.0345] # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI +1FA9 ; [.1936.0020.0008.03A9][.0000.002A.0002.0314][.0000.007F.0002.0345] # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI +03CE ; [.1936.0020.0002.03C9][.0000.0032.0002.0301] # GREEK SMALL LETTER OMEGA WITH TONOS +1F7D ; [.1936.0020.0002.03C9][.0000.0032.0002.0301] # GREEK SMALL LETTER OMEGA WITH OXIA +038F ; [.1936.0020.0008.03A9][.0000.0032.0002.0301] # GREEK CAPITAL LETTER OMEGA WITH TONOS +1FFB ; [.1936.0020.0008.03A9][.0000.0032.0002.0301] # GREEK CAPITAL LETTER OMEGA WITH OXIA +1FF4 ; [.1936.0020.0002.03C9][.0000.0032.0002.0301][.0000.007F.0002.0345] # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI +1F7C ; [.1936.0020.0002.03C9][.0000.0035.0002.0300] # GREEK SMALL LETTER OMEGA WITH VARIA +1FFA ; [.1936.0020.0008.03A9][.0000.0035.0002.0300] # GREEK CAPITAL LETTER OMEGA WITH VARIA +1FF2 ; [.1936.0020.0002.03C9][.0000.0035.0002.0300][.0000.007F.0002.0345] # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI +1FF6 ; [.1936.0020.0002.03C9][.0000.0045.0002.0342] # GREEK SMALL LETTER OMEGA WITH PERISPOMENI +1FF7 ; [.1936.0020.0002.03C9][.0000.0045.0002.0342][.0000.007F.0002.0345] # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI +1FF3 ; [.1936.0020.0002.03C9][.0000.007F.0002.0345] # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI +1FFC ; [.1936.0020.0008.03A9][.0000.007F.0002.0345] # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI +03E1 ; [.1937.0020.0002.03E1] # GREEK SMALL LETTER SAMPI +03E0 ; [.1937.0020.0008.03E0] # GREEK LETTER SAMPI +0373 ; [.1938.0020.0002.0373] # GREEK SMALL LETTER ARCHAIC SAMPI +0372 ; [.1938.0020.0008.0372] # GREEK CAPITAL LETTER ARCHAIC SAMPI +03F8 ; [.1939.0020.0002.03F8] # GREEK SMALL LETTER SHO +03F7 ; [.1939.0020.0008.03F7] # GREEK CAPITAL LETTER SHO +2C81 ; [.193A.0020.0002.2C81] # COPTIC SMALL LETTER ALFA +2C80 ; [.193A.0020.0008.2C80] # COPTIC CAPITAL LETTER ALFA +2C83 ; [.193B.0020.0002.2C83] # COPTIC SMALL LETTER VIDA +2C82 ; [.193B.0020.0008.2C82] # COPTIC CAPITAL LETTER VIDA +2C85 ; [.193C.0020.0002.2C85] # COPTIC SMALL LETTER GAMMA +2C84 ; [.193C.0020.0008.2C84] # COPTIC CAPITAL LETTER GAMMA +2C87 ; [.193D.0020.0002.2C87] # COPTIC SMALL LETTER DALDA +2C86 ; [.193D.0020.0008.2C86] # COPTIC CAPITAL LETTER DALDA +2C89 ; [.193E.0020.0002.2C89] # COPTIC SMALL LETTER EIE +2C88 ; [.193E.0020.0008.2C88] # COPTIC CAPITAL LETTER EIE +2CB7 ; [.193F.0020.0002.2CB7] # COPTIC SMALL LETTER CRYPTOGRAMMIC EIE +2CB6 ; [.193F.0020.0008.2CB6] # COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE +2C8B ; [.1940.0020.0002.2C8B] # COPTIC SMALL LETTER SOU +2C8A ; [.1940.0020.0008.2C8A] # COPTIC CAPITAL LETTER SOU +2C8D ; [.1941.0020.0002.2C8D] # COPTIC SMALL LETTER ZATA +2C8C ; [.1941.0020.0008.2C8C] # COPTIC CAPITAL LETTER ZATA +2C8F ; [.1942.0020.0002.2C8F] # COPTIC SMALL LETTER HATE +2C8E ; [.1942.0020.0008.2C8E] # COPTIC CAPITAL LETTER HATE +2C91 ; [.1943.0020.0002.2C91] # COPTIC SMALL LETTER THETHE +2C90 ; [.1943.0020.0008.2C90] # COPTIC CAPITAL LETTER THETHE +2C93 ; [.1944.0020.0002.2C93] # COPTIC SMALL LETTER IAUDA +2C92 ; [.1944.0020.0008.2C92] # COPTIC CAPITAL LETTER IAUDA +2C95 ; [.1945.0020.0002.2C95] # COPTIC SMALL LETTER KAPA +2C94 ; [.1945.0020.0008.2C94] # COPTIC CAPITAL LETTER KAPA +2CE4 ; [.1945.0020.0004.2CE4][.193A.0020.0004.2CE4][.1944.0020.001F.2CE4] # COPTIC SYMBOL KAI +2CB9 ; [.1946.0020.0002.2CB9] # COPTIC SMALL LETTER DIALECT-P KAPA +2CB8 ; [.1946.0020.0008.2CB8] # COPTIC CAPITAL LETTER DIALECT-P KAPA +2C97 ; [.1947.0020.0002.2C97] # COPTIC SMALL LETTER LAULA +2C96 ; [.1947.0020.0008.2C96] # COPTIC CAPITAL LETTER LAULA +2C99 ; [.1948.0020.0002.2C99] # COPTIC SMALL LETTER MI +2C98 ; [.1948.0020.0008.2C98] # COPTIC CAPITAL LETTER MI +2C9B ; [.1949.0020.0002.2C9B] # COPTIC SMALL LETTER NI +2C9A ; [.1949.0020.0008.2C9A] # COPTIC CAPITAL LETTER NI +2CBB ; [.194A.0020.0002.2CBB] # COPTIC SMALL LETTER DIALECT-P NI +2CBA ; [.194A.0020.0008.2CBA] # COPTIC CAPITAL LETTER DIALECT-P NI +2CBD ; [.194B.0020.0002.2CBD] # COPTIC SMALL LETTER CRYPTOGRAMMIC NI +2CBC ; [.194B.0020.0008.2CBC] # COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI +2C9D ; [.194C.0020.0002.2C9D] # COPTIC SMALL LETTER KSI +2C9C ; [.194C.0020.0008.2C9C] # COPTIC CAPITAL LETTER KSI +2C9F ; [.194D.0020.0002.2C9F] # COPTIC SMALL LETTER O +2C9E ; [.194D.0020.0008.2C9E] # COPTIC CAPITAL LETTER O +2CA1 ; [.194E.0020.0002.2CA1] # COPTIC SMALL LETTER PI +2CA0 ; [.194E.0020.0008.2CA0] # COPTIC CAPITAL LETTER PI +2CA3 ; [.194F.0020.0002.2CA3] # COPTIC SMALL LETTER RO +2CA2 ; [.194F.0020.0008.2CA2] # COPTIC CAPITAL LETTER RO +2CA5 ; [.1950.0020.0002.2CA5] # COPTIC SMALL LETTER SIMA +2CA4 ; [.1950.0020.0008.2CA4] # COPTIC CAPITAL LETTER SIMA +2CA7 ; [.1951.0020.0002.2CA7] # COPTIC SMALL LETTER TAU +2CA6 ; [.1951.0020.0008.2CA6] # COPTIC CAPITAL LETTER TAU +2CA9 ; [.1952.0020.0002.2CA9] # COPTIC SMALL LETTER UA +2CA8 ; [.1952.0020.0008.2CA8] # COPTIC CAPITAL LETTER UA +2CAB ; [.1953.0020.0002.2CAB] # COPTIC SMALL LETTER FI +2CAA ; [.1953.0020.0008.2CAA] # COPTIC CAPITAL LETTER FI +2CAD ; [.1954.0020.0002.2CAD] # COPTIC SMALL LETTER KHI +2CAC ; [.1954.0020.0008.2CAC] # COPTIC CAPITAL LETTER KHI +2CAF ; [.1955.0020.0002.2CAF] # COPTIC SMALL LETTER PSI +2CAE ; [.1955.0020.0008.2CAE] # COPTIC CAPITAL LETTER PSI +2CB1 ; [.1956.0020.0002.2CB1] # COPTIC SMALL LETTER OOU +2CB0 ; [.1956.0020.0008.2CB0] # COPTIC CAPITAL LETTER OOU +2CBF ; [.1957.0020.0002.2CBF] # COPTIC SMALL LETTER OLD COPTIC OOU +2CBE ; [.1957.0020.0008.2CBE] # COPTIC CAPITAL LETTER OLD COPTIC OOU +2CC1 ; [.1958.0020.0002.2CC1] # COPTIC SMALL LETTER SAMPI +2CC0 ; [.1958.0020.0008.2CC0] # COPTIC CAPITAL LETTER SAMPI +03E3 ; [.1959.0020.0002.03E3] # COPTIC SMALL LETTER SHEI +03E2 ; [.1959.0020.0008.03E2] # COPTIC CAPITAL LETTER SHEI +2CEC ; [.195A.0020.0002.2CEC] # COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI +2CEB ; [.195A.0020.0008.2CEB] # COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI +2CC3 ; [.195B.0020.0002.2CC3] # COPTIC SMALL LETTER CROSSED SHEI +2CC2 ; [.195B.0020.0008.2CC2] # COPTIC CAPITAL LETTER CROSSED SHEI +2CC5 ; [.195C.0020.0002.2CC5] # COPTIC SMALL LETTER OLD COPTIC SHEI +2CC4 ; [.195C.0020.0008.2CC4] # COPTIC CAPITAL LETTER OLD COPTIC SHEI +2CC7 ; [.195D.0020.0002.2CC7] # COPTIC SMALL LETTER OLD COPTIC ESH +2CC6 ; [.195D.0020.0008.2CC6] # COPTIC CAPITAL LETTER OLD COPTIC ESH +03E5 ; [.195E.0020.0002.03E5] # COPTIC SMALL LETTER FEI +03E4 ; [.195E.0020.0008.03E4] # COPTIC CAPITAL LETTER FEI +03E7 ; [.195F.0020.0002.03E7] # COPTIC SMALL LETTER KHEI +03E6 ; [.195F.0020.0008.03E6] # COPTIC CAPITAL LETTER KHEI +2CF3 ; [.1960.0020.0002.2CF3] # COPTIC SMALL LETTER BOHAIRIC KHEI +2CF2 ; [.1960.0020.0008.2CF2] # COPTIC CAPITAL LETTER BOHAIRIC KHEI +2CC9 ; [.1961.0020.0002.2CC9] # COPTIC SMALL LETTER AKHMIMIC KHEI +2CC8 ; [.1961.0020.0008.2CC8] # COPTIC CAPITAL LETTER AKHMIMIC KHEI +03E9 ; [.1962.0020.0002.03E9] # COPTIC SMALL LETTER HORI +03E8 ; [.1962.0020.0008.03E8] # COPTIC CAPITAL LETTER HORI +2CCB ; [.1963.0020.0002.2CCB] # COPTIC SMALL LETTER DIALECT-P HORI +2CCA ; [.1963.0020.0008.2CCA] # COPTIC CAPITAL LETTER DIALECT-P HORI +2CCD ; [.1964.0020.0002.2CCD] # COPTIC SMALL LETTER OLD COPTIC HORI +2CCC ; [.1964.0020.0008.2CCC] # COPTIC CAPITAL LETTER OLD COPTIC HORI +2CCF ; [.1965.0020.0002.2CCF] # COPTIC SMALL LETTER OLD COPTIC HA +2CCE ; [.1965.0020.0008.2CCE] # COPTIC CAPITAL LETTER OLD COPTIC HA +2CD1 ; [.1966.0020.0002.2CD1] # COPTIC SMALL LETTER L-SHAPED HA +2CD0 ; [.1966.0020.0008.2CD0] # COPTIC CAPITAL LETTER L-SHAPED HA +2CD3 ; [.1967.0020.0002.2CD3] # COPTIC SMALL LETTER OLD COPTIC HEI +2CD2 ; [.1967.0020.0008.2CD2] # COPTIC CAPITAL LETTER OLD COPTIC HEI +2CD5 ; [.1968.0020.0002.2CD5] # COPTIC SMALL LETTER OLD COPTIC HAT +2CD4 ; [.1968.0020.0008.2CD4] # COPTIC CAPITAL LETTER OLD COPTIC HAT +03EB ; [.1969.0020.0002.03EB] # COPTIC SMALL LETTER GANGIA +03EA ; [.1969.0020.0008.03EA] # COPTIC CAPITAL LETTER GANGIA +2CEE ; [.196A.0020.0002.2CEE] # COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA +2CED ; [.196A.0020.0008.2CED] # COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA +2CD7 ; [.196B.0020.0002.2CD7] # COPTIC SMALL LETTER OLD COPTIC GANGIA +2CD6 ; [.196B.0020.0008.2CD6] # COPTIC CAPITAL LETTER OLD COPTIC GANGIA +03ED ; [.196C.0020.0002.03ED] # COPTIC SMALL LETTER SHIMA +03EC ; [.196C.0020.0008.03EC] # COPTIC CAPITAL LETTER SHIMA +2CD9 ; [.196D.0020.0002.2CD9] # COPTIC SMALL LETTER OLD COPTIC DJA +2CD8 ; [.196D.0020.0008.2CD8] # COPTIC CAPITAL LETTER OLD COPTIC DJA +2CDB ; [.196E.0020.0002.2CDB] # COPTIC SMALL LETTER OLD COPTIC SHIMA +2CDA ; [.196E.0020.0008.2CDA] # COPTIC CAPITAL LETTER OLD COPTIC SHIMA +2CDD ; [.196F.0020.0002.2CDD] # COPTIC SMALL LETTER OLD NUBIAN SHIMA +2CDC ; [.196F.0020.0008.2CDC] # COPTIC CAPITAL LETTER OLD NUBIAN SHIMA +03EF ; [.1970.0020.0002.03EF] # COPTIC SMALL LETTER DEI +03EE ; [.1970.0020.0008.03EE] # COPTIC CAPITAL LETTER DEI +2CB3 ; [.1971.0020.0002.2CB3] # COPTIC SMALL LETTER DIALECT-P ALEF +2CB2 ; [.1971.0020.0008.2CB2] # COPTIC CAPITAL LETTER DIALECT-P ALEF +2CB5 ; [.1972.0020.0002.2CB5] # COPTIC SMALL LETTER OLD COPTIC AIN +2CB4 ; [.1972.0020.0008.2CB4] # COPTIC CAPITAL LETTER OLD COPTIC AIN +2CDF ; [.1973.0020.0002.2CDF] # COPTIC SMALL LETTER OLD NUBIAN NGI +2CDE ; [.1973.0020.0008.2CDE] # COPTIC CAPITAL LETTER OLD NUBIAN NGI +2CE1 ; [.1974.0020.0002.2CE1] # COPTIC SMALL LETTER OLD NUBIAN NYI +2CE0 ; [.1974.0020.0008.2CE0] # COPTIC CAPITAL LETTER OLD NUBIAN NYI +2CE3 ; [.1975.0020.0002.2CE3] # COPTIC SMALL LETTER OLD NUBIAN WAU +2CE2 ; [.1975.0020.0008.2CE2] # COPTIC CAPITAL LETTER OLD NUBIAN WAU +0430 ; [.1976.0020.0002.0430] # CYRILLIC SMALL LETTER A +2DF6 ; [.1976.0020.0004.2DF6] # COMBINING CYRILLIC LETTER A +0410 ; [.1976.0020.0008.0410] # CYRILLIC CAPITAL LETTER A +04D1 ; [.197A.0020.0002.04D1] # CYRILLIC SMALL LETTER A WITH BREVE +0430 0306 ; [.197A.0020.0002.04D1] # CYRILLIC SMALL LETTER A WITH BREVE +04D0 ; [.197A.0020.0008.04D0] # CYRILLIC CAPITAL LETTER A WITH BREVE +0410 0306 ; [.197A.0020.0008.04D0] # CYRILLIC CAPITAL LETTER A WITH BREVE +04D3 ; [.197E.0020.0002.04D3] # CYRILLIC SMALL LETTER A WITH DIAERESIS +0430 0308 ; [.197E.0020.0002.04D3] # CYRILLIC SMALL LETTER A WITH DIAERESIS +04D2 ; [.197E.0020.0008.04D2] # CYRILLIC CAPITAL LETTER A WITH DIAERESIS +0410 0308 ; [.197E.0020.0008.04D2] # CYRILLIC CAPITAL LETTER A WITH DIAERESIS +04D9 ; [.1982.0020.0002.04D9] # CYRILLIC SMALL LETTER SCHWA +04D8 ; [.1982.0020.0008.04D8] # CYRILLIC CAPITAL LETTER SCHWA +04DB ; [.1986.0020.0002.04DB] # CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS +04D9 0308 ; [.1986.0020.0002.04DB] # CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS +04DA ; [.1986.0020.0008.04DA] # CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS +04D8 0308 ; [.1986.0020.0008.04DA] # CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS +04D5 ; [.198A.0020.0002.04D5] # CYRILLIC SMALL LIGATURE A IE +04D4 ; [.198A.0020.0008.04D4] # CYRILLIC CAPITAL LIGATURE A IE +0431 ; [.198E.0020.0002.0431] # CYRILLIC SMALL LETTER BE +2DE0 ; [.198E.0020.0004.2DE0] # COMBINING CYRILLIC LETTER BE +0411 ; [.198E.0020.0008.0411] # CYRILLIC CAPITAL LETTER BE +0432 ; [.1992.0020.0002.0432] # CYRILLIC SMALL LETTER VE +2DE1 ; [.1992.0020.0004.2DE1] # COMBINING CYRILLIC LETTER VE +0412 ; [.1992.0020.0008.0412] # CYRILLIC CAPITAL LETTER VE +0433 ; [.1996.0020.0002.0433] # CYRILLIC SMALL LETTER GHE +2DE2 ; [.1996.0020.0004.2DE2] # COMBINING CYRILLIC LETTER GHE +0413 ; [.1996.0020.0008.0413] # CYRILLIC CAPITAL LETTER GHE +0491 ; [.1996.0020.0004.0491][.0000.013A.0004.0491] # CYRILLIC SMALL LETTER GHE WITH UPTURN +0490 ; [.1996.0020.000A.0490][.0000.013A.0004.0490] # CYRILLIC CAPITAL LETTER GHE WITH UPTURN +0493 ; [.199A.0020.0002.0493] # CYRILLIC SMALL LETTER GHE WITH STROKE +0492 ; [.199A.0020.0008.0492] # CYRILLIC CAPITAL LETTER GHE WITH STROKE +04FB ; [.199E.0020.0002.04FB] # CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK +04FA ; [.199E.0020.0008.04FA] # CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK +0495 ; [.19A2.0020.0002.0495] # CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK +0494 ; [.19A2.0020.0008.0494] # CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK +04F7 ; [.19A6.0020.0002.04F7] # CYRILLIC SMALL LETTER GHE WITH DESCENDER +04F6 ; [.19A6.0020.0008.04F6] # CYRILLIC CAPITAL LETTER GHE WITH DESCENDER +0434 ; [.19AA.0020.0002.0434] # CYRILLIC SMALL LETTER DE +2DE3 ; [.19AA.0020.0004.2DE3] # COMBINING CYRILLIC LETTER DE +0414 ; [.19AA.0020.0008.0414] # CYRILLIC CAPITAL LETTER DE +0501 ; [.19AE.0020.0002.0501] # CYRILLIC SMALL LETTER KOMI DE +0500 ; [.19AE.0020.0008.0500] # CYRILLIC CAPITAL LETTER KOMI DE +A681 ; [.19AF.0020.0002.A681] # CYRILLIC SMALL LETTER DWE +A680 ; [.19AF.0020.0008.A680] # CYRILLIC CAPITAL LETTER DWE +0452 ; [.19B0.0020.0002.0452] # CYRILLIC SMALL LETTER DJE +0402 ; [.19B0.0020.0008.0402] # CYRILLIC CAPITAL LETTER DJE +A663 ; [.19B4.0020.0002.A663] # CYRILLIC SMALL LETTER SOFT DE +A662 ; [.19B4.0020.0008.A662] # CYRILLIC CAPITAL LETTER SOFT DE +0503 ; [.19B5.0020.0002.0503] # CYRILLIC SMALL LETTER KOMI DJE +0502 ; [.19B5.0020.0008.0502] # CYRILLIC CAPITAL LETTER KOMI DJE +0453 ; [.19B6.0020.0002.0453] # CYRILLIC SMALL LETTER GJE +0433 0301 ; [.19B6.0020.0002.0453] # CYRILLIC SMALL LETTER GJE +0433 0341 ; [.19B6.0020.0002.0453] # CYRILLIC SMALL LETTER GJE +0403 ; [.19B6.0020.0008.0403] # CYRILLIC CAPITAL LETTER GJE +0413 0301 ; [.19B6.0020.0008.0403] # CYRILLIC CAPITAL LETTER GJE +0413 0341 ; [.19B6.0020.0008.0403] # CYRILLIC CAPITAL LETTER GJE +0499 ; [.19BA.0020.0002.0499] # CYRILLIC SMALL LETTER ZE WITH DESCENDER +0498 ; [.19BA.0020.0008.0498] # CYRILLIC CAPITAL LETTER ZE WITH DESCENDER +0435 ; [.19BE.0020.0002.0435] # CYRILLIC SMALL LETTER IE +2DF7 ; [.19BE.0020.0004.2DF7] # COMBINING CYRILLIC LETTER IE +0415 ; [.19BE.0020.0008.0415] # CYRILLIC CAPITAL LETTER IE +0450 ; [.19BE.0020.0002.0435][.0000.0035.0002.0300] # CYRILLIC SMALL LETTER IE WITH GRAVE +0400 ; [.19BE.0020.0008.0415][.0000.0035.0002.0300] # CYRILLIC CAPITAL LETTER IE WITH GRAVE +0451 ; [.19BE.0020.0002.0435][.0000.0047.0002.0308] # CYRILLIC SMALL LETTER IO +0401 ; [.19BE.0020.0008.0415][.0000.0047.0002.0308] # CYRILLIC CAPITAL LETTER IO +04D7 ; [.19C2.0020.0002.04D7] # CYRILLIC SMALL LETTER IE WITH BREVE +0435 0306 ; [.19C2.0020.0002.04D7] # CYRILLIC SMALL LETTER IE WITH BREVE +04D6 ; [.19C2.0020.0008.04D6] # CYRILLIC CAPITAL LETTER IE WITH BREVE +0415 0306 ; [.19C2.0020.0008.04D6] # CYRILLIC CAPITAL LETTER IE WITH BREVE +0454 ; [.19C6.0020.0002.0454] # CYRILLIC SMALL LETTER UKRAINIAN IE +A674 ; [.19C6.0020.0004.A674] # COMBINING CYRILLIC LETTER UKRAINIAN IE +0404 ; [.19C6.0020.0008.0404] # CYRILLIC CAPITAL LETTER UKRAINIAN IE +0436 ; [.19CA.0020.0002.0436] # CYRILLIC SMALL LETTER ZHE +2DE4 ; [.19CA.0020.0004.2DE4] # COMBINING CYRILLIC LETTER ZHE +0416 ; [.19CA.0020.0008.0416] # CYRILLIC CAPITAL LETTER ZHE +04C2 ; [.19CA.0020.0002.0436][.0000.0037.0002.0306] # CYRILLIC SMALL LETTER ZHE WITH BREVE +04C1 ; [.19CA.0020.0008.0416][.0000.0037.0002.0306] # CYRILLIC CAPITAL LETTER ZHE WITH BREVE +A685 ; [.19CE.0020.0002.A685] # CYRILLIC SMALL LETTER ZHWE +A684 ; [.19CE.0020.0008.A684] # CYRILLIC CAPITAL LETTER ZHWE +04DD ; [.19CF.0020.0002.04DD] # CYRILLIC SMALL LETTER ZHE WITH DIAERESIS +0436 0308 ; [.19CF.0020.0002.04DD] # CYRILLIC SMALL LETTER ZHE WITH DIAERESIS +04DC ; [.19CF.0020.0008.04DC] # CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS +0416 0308 ; [.19CF.0020.0008.04DC] # CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS +0497 ; [.19D3.0020.0002.0497] # CYRILLIC SMALL LETTER ZHE WITH DESCENDER +0496 ; [.19D3.0020.0008.0496] # CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER +0437 ; [.19D7.0020.0002.0437] # CYRILLIC SMALL LETTER ZE +2DE5 ; [.19D7.0020.0004.2DE5] # COMBINING CYRILLIC LETTER ZE +0417 ; [.19D7.0020.0008.0417] # CYRILLIC CAPITAL LETTER ZE +A641 ; [.19DB.0020.0002.A641] # CYRILLIC SMALL LETTER ZEMLYA +A640 ; [.19DB.0020.0008.A640] # CYRILLIC CAPITAL LETTER ZEMLYA +0505 ; [.19DC.0020.0002.0505] # CYRILLIC SMALL LETTER KOMI ZJE +0504 ; [.19DC.0020.0008.0504] # CYRILLIC CAPITAL LETTER KOMI ZJE +0511 ; [.19DD.0020.0002.0511] # CYRILLIC SMALL LETTER REVERSED ZE +0510 ; [.19DD.0020.0008.0510] # CYRILLIC CAPITAL LETTER REVERSED ZE +04DF ; [.19DE.0020.0002.04DF] # CYRILLIC SMALL LETTER ZE WITH DIAERESIS +0437 0308 ; [.19DE.0020.0002.04DF] # CYRILLIC SMALL LETTER ZE WITH DIAERESIS +04DE ; [.19DE.0020.0008.04DE] # CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS +0417 0308 ; [.19DE.0020.0008.04DE] # CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS +A643 ; [.19E2.0020.0002.A643] # CYRILLIC SMALL LETTER DZELO +A642 ; [.19E2.0020.0008.A642] # CYRILLIC CAPITAL LETTER DZELO +0455 ; [.19E3.0020.0002.0455] # CYRILLIC SMALL LETTER DZE +0405 ; [.19E3.0020.0008.0405] # CYRILLIC CAPITAL LETTER DZE +A645 ; [.19E7.0020.0002.A645] # CYRILLIC SMALL LETTER REVERSED DZE +A644 ; [.19E7.0020.0008.A644] # CYRILLIC CAPITAL LETTER REVERSED DZE +04E1 ; [.19E8.0020.0002.04E1] # CYRILLIC SMALL LETTER ABKHASIAN DZE +04E0 ; [.19E8.0020.0008.04E0] # CYRILLIC CAPITAL LETTER ABKHASIAN DZE +A689 ; [.19EC.0020.0002.A689] # CYRILLIC SMALL LETTER DZZE +A688 ; [.19EC.0020.0008.A688] # CYRILLIC CAPITAL LETTER DZZE +0507 ; [.19ED.0020.0002.0507] # CYRILLIC SMALL LETTER KOMI DZJE +0506 ; [.19ED.0020.0008.0506] # CYRILLIC CAPITAL LETTER KOMI DZJE +A683 ; [.19EE.0020.0002.A683] # CYRILLIC SMALL LETTER DZWE +A682 ; [.19EE.0020.0008.A682] # CYRILLIC CAPITAL LETTER DZWE +0438 ; [.19EF.0020.0002.0438] # CYRILLIC SMALL LETTER I +A675 ; [.19EF.0020.0004.A675] # COMBINING CYRILLIC LETTER I +0418 ; [.19EF.0020.0008.0418] # CYRILLIC CAPITAL LETTER I +045D ; [.19EF.0020.0002.0438][.0000.0035.0002.0300] # CYRILLIC SMALL LETTER I WITH GRAVE +040D ; [.19EF.0020.0008.0418][.0000.0035.0002.0300] # CYRILLIC CAPITAL LETTER I WITH GRAVE +04E3 ; [.19EF.0020.0002.0438][.0000.005B.0002.0304] # CYRILLIC SMALL LETTER I WITH MACRON +04E2 ; [.19EF.0020.0008.0418][.0000.005B.0002.0304] # CYRILLIC CAPITAL LETTER I WITH MACRON +048B ; [.19F3.0020.0002.048B] # CYRILLIC SMALL LETTER SHORT I WITH TAIL +048A ; [.19F3.0020.0008.048A] # CYRILLIC CAPITAL LETTER SHORT I WITH TAIL +04E5 ; [.19F7.0020.0002.04E5] # CYRILLIC SMALL LETTER I WITH DIAERESIS +0438 0308 ; [.19F7.0020.0002.04E5] # CYRILLIC SMALL LETTER I WITH DIAERESIS +04E4 ; [.19F7.0020.0008.04E4] # CYRILLIC CAPITAL LETTER I WITH DIAERESIS +0418 0308 ; [.19F7.0020.0008.04E4] # CYRILLIC CAPITAL LETTER I WITH DIAERESIS +0456 ; [.19FB.0020.0002.0456] # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I +0406 ; [.19FB.0020.0008.0406] # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +A647 ; [.19FF.0020.0002.A647] # CYRILLIC SMALL LETTER IOTA +A646 ; [.19FF.0020.0008.A646] # CYRILLIC CAPITAL LETTER IOTA +0457 ; [.1A00.0020.0002.0457] # CYRILLIC SMALL LETTER YI +0456 0308 ; [.1A00.0020.0002.0457] # CYRILLIC SMALL LETTER YI +A676 ; [.1A00.0020.0004.A676] # COMBINING CYRILLIC LETTER YI +0407 ; [.1A00.0020.0008.0407] # CYRILLIC CAPITAL LETTER YI +0406 0308 ; [.1A00.0020.0008.0407] # CYRILLIC CAPITAL LETTER YI +0439 ; [.1A04.0020.0002.0439] # CYRILLIC SMALL LETTER SHORT I +0438 0306 ; [.1A04.0020.0002.0439] # CYRILLIC SMALL LETTER SHORT I +0419 ; [.1A04.0020.0008.0419] # CYRILLIC CAPITAL LETTER SHORT I +0418 0306 ; [.1A04.0020.0008.0419] # CYRILLIC CAPITAL LETTER SHORT I +0458 ; [.1A08.0020.0002.0458] # CYRILLIC SMALL LETTER JE +0408 ; [.1A08.0020.0008.0408] # CYRILLIC CAPITAL LETTER JE +A649 ; [.1A0C.0020.0002.A649] # CYRILLIC SMALL LETTER DJERV +2DF8 ; [.1A0C.0020.0004.2DF8] # COMBINING CYRILLIC LETTER DJERV +A648 ; [.1A0C.0020.0008.A648] # CYRILLIC CAPITAL LETTER DJERV +043A ; [.1A0D.0020.0002.043A] # CYRILLIC SMALL LETTER KA +2DE6 ; [.1A0D.0020.0004.2DE6] # COMBINING CYRILLIC LETTER KA +041A ; [.1A0D.0020.0008.041A] # CYRILLIC CAPITAL LETTER KA +049B ; [.1A11.0020.0002.049B] # CYRILLIC SMALL LETTER KA WITH DESCENDER +049A ; [.1A11.0020.0008.049A] # CYRILLIC CAPITAL LETTER KA WITH DESCENDER +04C4 ; [.1A15.0020.0002.04C4] # CYRILLIC SMALL LETTER KA WITH HOOK +04C3 ; [.1A15.0020.0008.04C3] # CYRILLIC CAPITAL LETTER KA WITH HOOK +04A1 ; [.1A19.0020.0002.04A1] # CYRILLIC SMALL LETTER BASHKIR KA +04A0 ; [.1A19.0020.0008.04A0] # CYRILLIC CAPITAL LETTER BASHKIR KA +049F ; [.1A1D.0020.0002.049F] # CYRILLIC SMALL LETTER KA WITH STROKE +049E ; [.1A1D.0020.0008.049E] # CYRILLIC CAPITAL LETTER KA WITH STROKE +049D ; [.1A21.0020.0002.049D] # CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE +049C ; [.1A21.0020.0008.049C] # CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE +051F ; [.1A25.0020.0002.051F] # CYRILLIC SMALL LETTER ALEUT KA +051E ; [.1A25.0020.0008.051E] # CYRILLIC CAPITAL LETTER ALEUT KA +051B ; [.1A26.0020.0002.051B] # CYRILLIC SMALL LETTER QA +051A ; [.1A26.0020.0008.051A] # CYRILLIC CAPITAL LETTER QA +043B ; [.1A27.0020.0002.043B] # CYRILLIC SMALL LETTER EL +2DE7 ; [.1A27.0020.0004.2DE7] # COMBINING CYRILLIC LETTER EL +041B ; [.1A27.0020.0008.041B] # CYRILLIC CAPITAL LETTER EL +1D2B ; [.1A2B.0020.0002.1D2B] # CYRILLIC LETTER SMALL CAPITAL EL +04C6 ; [.1A2C.0020.0002.04C6] # CYRILLIC SMALL LETTER EL WITH TAIL +04C5 ; [.1A2C.0020.0008.04C5] # CYRILLIC CAPITAL LETTER EL WITH TAIL +0513 ; [.1A30.0020.0002.0513] # CYRILLIC SMALL LETTER EL WITH HOOK +0512 ; [.1A30.0020.0008.0512] # CYRILLIC CAPITAL LETTER EL WITH HOOK +0521 ; [.1A31.0020.0002.0521] # CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK +0520 ; [.1A31.0020.0008.0520] # CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK +0459 ; [.1A32.0020.0002.0459] # CYRILLIC SMALL LETTER LJE +0409 ; [.1A32.0020.0008.0409] # CYRILLIC CAPITAL LETTER LJE +A665 ; [.1A36.0020.0002.A665] # CYRILLIC SMALL LETTER SOFT EL +A664 ; [.1A36.0020.0008.A664] # CYRILLIC CAPITAL LETTER SOFT EL +0509 ; [.1A37.0020.0002.0509] # CYRILLIC SMALL LETTER KOMI LJE +0508 ; [.1A37.0020.0008.0508] # CYRILLIC CAPITAL LETTER KOMI LJE +0515 ; [.1A38.0020.0002.0515] # CYRILLIC SMALL LETTER LHA +0514 ; [.1A38.0020.0008.0514] # CYRILLIC CAPITAL LETTER LHA +043C ; [.1A39.0020.0002.043C] # CYRILLIC SMALL LETTER EM +2DE8 ; [.1A39.0020.0004.2DE8] # COMBINING CYRILLIC LETTER EM +041C ; [.1A39.0020.0008.041C] # CYRILLIC CAPITAL LETTER EM +04CE ; [.1A3D.0020.0002.04CE] # CYRILLIC SMALL LETTER EM WITH TAIL +04CD ; [.1A3D.0020.0008.04CD] # CYRILLIC CAPITAL LETTER EM WITH TAIL +A667 ; [.1A41.0020.0002.A667] # CYRILLIC SMALL LETTER SOFT EM +A666 ; [.1A41.0020.0008.A666] # CYRILLIC CAPITAL LETTER SOFT EM +043D ; [.1A42.0020.0002.043D] # CYRILLIC SMALL LETTER EN +2DE9 ; [.1A42.0020.0004.2DE9] # COMBINING CYRILLIC LETTER EN +041D ; [.1A42.0020.0008.041D] # CYRILLIC CAPITAL LETTER EN +1D78 ; [.1A42.0020.0014.1D78] # MODIFIER LETTER CYRILLIC EN +04CA ; [.1A46.0020.0002.04CA] # CYRILLIC SMALL LETTER EN WITH TAIL +04C9 ; [.1A46.0020.0008.04C9] # CYRILLIC CAPITAL LETTER EN WITH TAIL +04A3 ; [.1A4A.0020.0002.04A3] # CYRILLIC SMALL LETTER EN WITH DESCENDER +04A2 ; [.1A4A.0020.0008.04A2] # CYRILLIC CAPITAL LETTER EN WITH DESCENDER +04C8 ; [.1A4E.0020.0002.04C8] # CYRILLIC SMALL LETTER EN WITH HOOK +04C7 ; [.1A4E.0020.0008.04C7] # CYRILLIC CAPITAL LETTER EN WITH HOOK +0523 ; [.1A52.0020.0002.0523] # CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK +0522 ; [.1A52.0020.0008.0522] # CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK +04A5 ; [.1A53.0020.0002.04A5] # CYRILLIC SMALL LIGATURE EN GHE +04A4 ; [.1A53.0020.0008.04A4] # CYRILLIC CAPITAL LIGATURE EN GHE +045A ; [.1A57.0020.0002.045A] # CYRILLIC SMALL LETTER NJE +040A ; [.1A57.0020.0008.040A] # CYRILLIC CAPITAL LETTER NJE +050B ; [.1A5B.0020.0002.050B] # CYRILLIC SMALL LETTER KOMI NJE +050A ; [.1A5B.0020.0008.050A] # CYRILLIC CAPITAL LETTER KOMI NJE +043E ; [.1A5C.0020.0002.043E] # CYRILLIC SMALL LETTER O +2DEA ; [.1A5C.0020.0004.2DEA] # COMBINING CYRILLIC LETTER O +A669 ; [.1A5C.0020.0004.A669] # CYRILLIC SMALL LETTER MONOCULAR O +A66B ; [.1A5C.0020.0004.A66B] # CYRILLIC SMALL LETTER BINOCULAR O +A66D ; [.1A5C.0020.0004.A66D] # CYRILLIC SMALL LETTER DOUBLE MONOCULAR O +A66E ; [.1A5C.0020.0004.A66E] # CYRILLIC LETTER MULTIOCULAR O +041E ; [.1A5C.0020.0008.041E] # CYRILLIC CAPITAL LETTER O +A668 ; [.1A5C.0020.000A.A668] # CYRILLIC CAPITAL LETTER MONOCULAR O +A66A ; [.1A5C.0020.000A.A66A] # CYRILLIC CAPITAL LETTER BINOCULAR O +A66C ; [.1A5C.0020.000A.A66C] # CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O +04E7 ; [.1A60.0020.0002.04E7] # CYRILLIC SMALL LETTER O WITH DIAERESIS +043E 0308 ; [.1A60.0020.0002.04E7] # CYRILLIC SMALL LETTER O WITH DIAERESIS +04E6 ; [.1A60.0020.0008.04E6] # CYRILLIC CAPITAL LETTER O WITH DIAERESIS +041E 0308 ; [.1A60.0020.0008.04E6] # CYRILLIC CAPITAL LETTER O WITH DIAERESIS +04E9 ; [.1A64.0020.0002.04E9] # CYRILLIC SMALL LETTER BARRED O +04E8 ; [.1A64.0020.0008.04E8] # CYRILLIC CAPITAL LETTER BARRED O +04EB ; [.1A68.0020.0002.04EB] # CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS +04E9 0308 ; [.1A68.0020.0002.04EB] # CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS +04EA ; [.1A68.0020.0008.04EA] # CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS +04E8 0308 ; [.1A68.0020.0008.04EA] # CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS +043F ; [.1A6C.0020.0002.043F] # CYRILLIC SMALL LETTER PE +2DEB ; [.1A6C.0020.0004.2DEB] # COMBINING CYRILLIC LETTER PE +041F ; [.1A6C.0020.0008.041F] # CYRILLIC CAPITAL LETTER PE +0525 ; [.1A70.0020.0002.0525] # CYRILLIC SMALL LETTER PE WITH DESCENDER +0524 ; [.1A70.0020.0008.0524] # CYRILLIC CAPITAL LETTER PE WITH DESCENDER +04A7 ; [.1A71.0020.0002.04A7] # CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK +04A6 ; [.1A71.0020.0008.04A6] # CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK +0481 ; [.1A75.0020.0002.0481] # CYRILLIC SMALL LETTER KOPPA +0480 ; [.1A75.0020.0008.0480] # CYRILLIC CAPITAL LETTER KOPPA +0440 ; [.1A79.0020.0002.0440] # CYRILLIC SMALL LETTER ER +2DEC ; [.1A79.0020.0004.2DEC] # COMBINING CYRILLIC LETTER ER +0420 ; [.1A79.0020.0008.0420] # CYRILLIC CAPITAL LETTER ER +048F ; [.1A7D.0020.0002.048F] # CYRILLIC SMALL LETTER ER WITH TICK +048E ; [.1A7D.0020.0008.048E] # CYRILLIC CAPITAL LETTER ER WITH TICK +0517 ; [.1A81.0020.0002.0517] # CYRILLIC SMALL LETTER RHA +0516 ; [.1A81.0020.0008.0516] # CYRILLIC CAPITAL LETTER RHA +0441 ; [.1A82.0020.0002.0441] # CYRILLIC SMALL LETTER ES +2DED ; [.1A82.0020.0004.2DED] # COMBINING CYRILLIC LETTER ES +0421 ; [.1A82.0020.0008.0421] # CYRILLIC CAPITAL LETTER ES +2DF5 ; [.1A82.0020.0004.2DF5][.1A8B.0020.0004.2DF5] # COMBINING CYRILLIC LETTER ES-TE +050D ; [.1A86.0020.0002.050D] # CYRILLIC SMALL LETTER KOMI SJE +050C ; [.1A86.0020.0008.050C] # CYRILLIC CAPITAL LETTER KOMI SJE +04AB ; [.1A87.0020.0002.04AB] # CYRILLIC SMALL LETTER ES WITH DESCENDER +04AA ; [.1A87.0020.0008.04AA] # CYRILLIC CAPITAL LETTER ES WITH DESCENDER +0442 ; [.1A8B.0020.0002.0442] # CYRILLIC SMALL LETTER TE +2DEE ; [.1A8B.0020.0004.2DEE] # COMBINING CYRILLIC LETTER TE +0422 ; [.1A8B.0020.0008.0422] # CYRILLIC CAPITAL LETTER TE +A68D ; [.1A8F.0020.0002.A68D] # CYRILLIC SMALL LETTER TWE +A68C ; [.1A8F.0020.0008.A68C] # CYRILLIC CAPITAL LETTER TWE +050F ; [.1A90.0020.0002.050F] # CYRILLIC SMALL LETTER KOMI TJE +050E ; [.1A90.0020.0008.050E] # CYRILLIC CAPITAL LETTER KOMI TJE +04AD ; [.1A91.0020.0002.04AD] # CYRILLIC SMALL LETTER TE WITH DESCENDER +04AC ; [.1A91.0020.0008.04AC] # CYRILLIC CAPITAL LETTER TE WITH DESCENDER +A68B ; [.1A95.0020.0002.A68B] # CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK +A68A ; [.1A95.0020.0008.A68A] # CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK +045B ; [.1A96.0020.0002.045B] # CYRILLIC SMALL LETTER TSHE +040B ; [.1A96.0020.0008.040B] # CYRILLIC CAPITAL LETTER TSHE +045C ; [.1A9A.0020.0002.045C] # CYRILLIC SMALL LETTER KJE +043A 0301 ; [.1A9A.0020.0002.045C] # CYRILLIC SMALL LETTER KJE +043A 0341 ; [.1A9A.0020.0002.045C] # CYRILLIC SMALL LETTER KJE +040C ; [.1A9A.0020.0008.040C] # CYRILLIC CAPITAL LETTER KJE +041A 0301 ; [.1A9A.0020.0008.040C] # CYRILLIC CAPITAL LETTER KJE +041A 0341 ; [.1A9A.0020.0008.040C] # CYRILLIC CAPITAL LETTER KJE +0443 ; [.1A9E.0020.0002.0443] # CYRILLIC SMALL LETTER U +A677 ; [.1A9E.0020.0004.A677] # COMBINING CYRILLIC LETTER U +0423 ; [.1A9E.0020.0008.0423] # CYRILLIC CAPITAL LETTER U +04EF ; [.1A9E.0020.0002.0443][.0000.005B.0002.0304] # CYRILLIC SMALL LETTER U WITH MACRON +04EE ; [.1A9E.0020.0008.0423][.0000.005B.0002.0304] # CYRILLIC CAPITAL LETTER U WITH MACRON +045E ; [.1AA2.0020.0002.045E] # CYRILLIC SMALL LETTER SHORT U +0443 0306 ; [.1AA2.0020.0002.045E] # CYRILLIC SMALL LETTER SHORT U +040E ; [.1AA2.0020.0008.040E] # CYRILLIC CAPITAL LETTER SHORT U +0423 0306 ; [.1AA2.0020.0008.040E] # CYRILLIC CAPITAL LETTER SHORT U +04F1 ; [.1AA6.0020.0002.04F1] # CYRILLIC SMALL LETTER U WITH DIAERESIS +0443 0308 ; [.1AA6.0020.0002.04F1] # CYRILLIC SMALL LETTER U WITH DIAERESIS +04F0 ; [.1AA6.0020.0008.04F0] # CYRILLIC CAPITAL LETTER U WITH DIAERESIS +0423 0308 ; [.1AA6.0020.0008.04F0] # CYRILLIC CAPITAL LETTER U WITH DIAERESIS +04F3 ; [.1AAA.0020.0002.04F3] # CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE +0443 030B ; [.1AAA.0020.0002.04F3] # CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE +04F2 ; [.1AAA.0020.0008.04F2] # CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE +0423 030B ; [.1AAA.0020.0008.04F2] # CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE +04AF ; [.1AAE.0020.0002.04AF] # CYRILLIC SMALL LETTER STRAIGHT U +04AE ; [.1AAE.0020.0008.04AE] # CYRILLIC CAPITAL LETTER STRAIGHT U +04B1 ; [.1AB2.0020.0002.04B1] # CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE +04B0 ; [.1AB2.0020.0008.04B0] # CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE +A64B ; [.1AB6.0020.0002.A64B] # CYRILLIC SMALL LETTER MONOGRAPH UK +2DF9 ; [.1AB6.0020.0004.2DF9] # COMBINING CYRILLIC LETTER MONOGRAPH UK +A64A ; [.1AB6.0020.0008.A64A] # CYRILLIC CAPITAL LETTER MONOGRAPH UK +0479 ; [.1AB7.0020.0002.0479] # CYRILLIC SMALL LETTER UK +0478 ; [.1AB7.0020.0008.0478] # CYRILLIC CAPITAL LETTER UK +0444 ; [.1ABB.0020.0002.0444] # CYRILLIC SMALL LETTER EF +0424 ; [.1ABB.0020.0008.0424] # CYRILLIC CAPITAL LETTER EF +0445 ; [.1ABF.0020.0002.0445] # CYRILLIC SMALL LETTER HA +2DEF ; [.1ABF.0020.0004.2DEF] # COMBINING CYRILLIC LETTER HA +0425 ; [.1ABF.0020.0008.0425] # CYRILLIC CAPITAL LETTER HA +04FD ; [.1AC3.0020.0002.04FD] # CYRILLIC SMALL LETTER HA WITH HOOK +04FC ; [.1AC3.0020.0008.04FC] # CYRILLIC CAPITAL LETTER HA WITH HOOK +04FF ; [.1AC7.0020.0002.04FF] # CYRILLIC SMALL LETTER HA WITH STROKE +04FE ; [.1AC7.0020.0008.04FE] # CYRILLIC CAPITAL LETTER HA WITH STROKE +04B3 ; [.1ACB.0020.0002.04B3] # CYRILLIC SMALL LETTER HA WITH DESCENDER +04B2 ; [.1ACB.0020.0008.04B2] # CYRILLIC CAPITAL LETTER HA WITH DESCENDER +04BB ; [.1ACF.0020.0002.04BB] # CYRILLIC SMALL LETTER SHHA +04BA ; [.1ACF.0020.0008.04BA] # CYRILLIC CAPITAL LETTER SHHA +0527 ; [.1AD3.0020.0002.0527] # CYRILLIC SMALL LETTER SHHA WITH DESCENDER +0526 ; [.1AD3.0020.0008.0526] # CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER +A695 ; [.1AD4.0020.0002.A695] # CYRILLIC SMALL LETTER HWE +A694 ; [.1AD4.0020.0008.A694] # CYRILLIC CAPITAL LETTER HWE +0461 ; [.1AD5.0020.0002.0461] # CYRILLIC SMALL LETTER OMEGA +A67B ; [.1AD5.0020.0004.A67B] # COMBINING CYRILLIC LETTER OMEGA +0460 ; [.1AD5.0020.0008.0460] # CYRILLIC CAPITAL LETTER OMEGA +047F ; [.1AD9.0020.0002.047F] # CYRILLIC SMALL LETTER OT +047E ; [.1AD9.0020.0008.047E] # CYRILLIC CAPITAL LETTER OT +A64D ; [.1ADD.0020.0002.A64D] # CYRILLIC SMALL LETTER BROAD OMEGA +A64C ; [.1ADD.0020.0008.A64C] # CYRILLIC CAPITAL LETTER BROAD OMEGA +047D ; [.1ADE.0020.0002.047D] # CYRILLIC SMALL LETTER OMEGA WITH TITLO +047C ; [.1ADE.0020.0008.047C] # CYRILLIC CAPITAL LETTER OMEGA WITH TITLO +047B ; [.1AE2.0020.0002.047B] # CYRILLIC SMALL LETTER ROUND OMEGA +047A ; [.1AE2.0020.0008.047A] # CYRILLIC CAPITAL LETTER ROUND OMEGA +0446 ; [.1AE6.0020.0002.0446] # CYRILLIC SMALL LETTER TSE +2DF0 ; [.1AE6.0020.0004.2DF0] # COMBINING CYRILLIC LETTER TSE +0426 ; [.1AE6.0020.0008.0426] # CYRILLIC CAPITAL LETTER TSE +A661 ; [.1AEA.0020.0002.A661] # CYRILLIC SMALL LETTER REVERSED TSE +A660 ; [.1AEA.0020.0008.A660] # CYRILLIC CAPITAL LETTER REVERSED TSE +A68F ; [.1AEB.0020.0002.A68F] # CYRILLIC SMALL LETTER TSWE +A68E ; [.1AEB.0020.0008.A68E] # CYRILLIC CAPITAL LETTER TSWE +04B5 ; [.1AEC.0020.0002.04B5] # CYRILLIC SMALL LIGATURE TE TSE +04B4 ; [.1AEC.0020.0008.04B4] # CYRILLIC CAPITAL LIGATURE TE TSE +A691 ; [.1AF0.0020.0002.A691] # CYRILLIC SMALL LETTER TSSE +A690 ; [.1AF0.0020.0008.A690] # CYRILLIC CAPITAL LETTER TSSE +0447 ; [.1AF1.0020.0002.0447] # CYRILLIC SMALL LETTER CHE +2DF1 ; [.1AF1.0020.0004.2DF1] # COMBINING CYRILLIC LETTER CHE +0427 ; [.1AF1.0020.0008.0427] # CYRILLIC CAPITAL LETTER CHE +A693 ; [.1AF5.0020.0002.A693] # CYRILLIC SMALL LETTER TCHE +A692 ; [.1AF5.0020.0008.A692] # CYRILLIC CAPITAL LETTER TCHE +04F5 ; [.1AF6.0020.0002.04F5] # CYRILLIC SMALL LETTER CHE WITH DIAERESIS +0447 0308 ; [.1AF6.0020.0002.04F5] # CYRILLIC SMALL LETTER CHE WITH DIAERESIS +04F4 ; [.1AF6.0020.0008.04F4] # CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS +0427 0308 ; [.1AF6.0020.0008.04F4] # CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS +04B7 ; [.1AFA.0020.0002.04B7] # CYRILLIC SMALL LETTER CHE WITH DESCENDER +04B6 ; [.1AFA.0020.0008.04B6] # CYRILLIC CAPITAL LETTER CHE WITH DESCENDER +04CC ; [.1AFE.0020.0002.04CC] # CYRILLIC SMALL LETTER KHAKASSIAN CHE +04CB ; [.1AFE.0020.0008.04CB] # CYRILLIC CAPITAL LETTER KHAKASSIAN CHE +04B9 ; [.1B02.0020.0002.04B9] # CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE +04B8 ; [.1B02.0020.0008.04B8] # CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE +A687 ; [.1B06.0020.0002.A687] # CYRILLIC SMALL LETTER CCHE +A686 ; [.1B06.0020.0008.A686] # CYRILLIC CAPITAL LETTER CCHE +04BD ; [.1B07.0020.0002.04BD] # CYRILLIC SMALL LETTER ABKHASIAN CHE +04BC ; [.1B07.0020.0008.04BC] # CYRILLIC CAPITAL LETTER ABKHASIAN CHE +04BF ; [.1B0B.0020.0002.04BF] # CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER +04BE ; [.1B0B.0020.0008.04BE] # CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER +045F ; [.1B0F.0020.0002.045F] # CYRILLIC SMALL LETTER DZHE +040F ; [.1B0F.0020.0008.040F] # CYRILLIC CAPITAL LETTER DZHE +0448 ; [.1B13.0020.0002.0448] # CYRILLIC SMALL LETTER SHA +2DF2 ; [.1B13.0020.0004.2DF2] # COMBINING CYRILLIC LETTER SHA +0428 ; [.1B13.0020.0008.0428] # CYRILLIC CAPITAL LETTER SHA +A697 ; [.1B17.0020.0002.A697] # CYRILLIC SMALL LETTER SHWE +A696 ; [.1B17.0020.0008.A696] # CYRILLIC CAPITAL LETTER SHWE +0449 ; [.1B18.0020.0002.0449] # CYRILLIC SMALL LETTER SHCHA +2DF3 ; [.1B18.0020.0004.2DF3] # COMBINING CYRILLIC LETTER SHCHA +0429 ; [.1B18.0020.0008.0429] # CYRILLIC CAPITAL LETTER SHCHA +A64F ; [.1B1C.0020.0002.A64F] # CYRILLIC SMALL LETTER NEUTRAL YER +A64E ; [.1B1C.0020.0008.A64E] # CYRILLIC CAPITAL LETTER NEUTRAL YER +2E2F ; [.1B1D.0020.0002.2E2F] # VERTICAL TILDE +A67F ; [.1B1E.0020.0002.A67F] # CYRILLIC PAYEROK +044A ; [.1B1F.0020.0002.044A] # CYRILLIC SMALL LETTER HARD SIGN +A678 ; [.1B1F.0020.0004.A678] # COMBINING CYRILLIC LETTER HARD SIGN +042A ; [.1B1F.0020.0008.042A] # CYRILLIC CAPITAL LETTER HARD SIGN +A651 ; [.1B23.0020.0002.A651] # CYRILLIC SMALL LETTER YERU WITH BACK YER +A650 ; [.1B23.0020.0008.A650] # CYRILLIC CAPITAL LETTER YERU WITH BACK YER +044B ; [.1B24.0020.0002.044B] # CYRILLIC SMALL LETTER YERU +A679 ; [.1B24.0020.0004.A679] # COMBINING CYRILLIC LETTER YERU +042B ; [.1B24.0020.0008.042B] # CYRILLIC CAPITAL LETTER YERU +04F9 ; [.1B28.0020.0002.04F9] # CYRILLIC SMALL LETTER YERU WITH DIAERESIS +044B 0308 ; [.1B28.0020.0002.04F9] # CYRILLIC SMALL LETTER YERU WITH DIAERESIS +04F8 ; [.1B28.0020.0008.04F8] # CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS +042B 0308 ; [.1B28.0020.0008.04F8] # CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS +044C ; [.1B2C.0020.0002.044C] # CYRILLIC SMALL LETTER SOFT SIGN +A67A ; [.1B2C.0020.0004.A67A] # COMBINING CYRILLIC LETTER SOFT SIGN +042C ; [.1B2C.0020.0008.042C] # CYRILLIC CAPITAL LETTER SOFT SIGN +048D ; [.1B30.0020.0002.048D] # CYRILLIC SMALL LETTER SEMISOFT SIGN +048C ; [.1B30.0020.0008.048C] # CYRILLIC CAPITAL LETTER SEMISOFT SIGN +0463 ; [.1B34.0020.0002.0463] # CYRILLIC SMALL LETTER YAT +2DFA ; [.1B34.0020.0004.2DFA] # COMBINING CYRILLIC LETTER YAT +0462 ; [.1B34.0020.0008.0462] # CYRILLIC CAPITAL LETTER YAT +A653 ; [.1B38.0020.0002.A653] # CYRILLIC SMALL LETTER IOTIFIED YAT +A652 ; [.1B38.0020.0008.A652] # CYRILLIC CAPITAL LETTER IOTIFIED YAT +044D ; [.1B39.0020.0002.044D] # CYRILLIC SMALL LETTER E +042D ; [.1B39.0020.0008.042D] # CYRILLIC CAPITAL LETTER E +04ED ; [.1B3D.0020.0002.04ED] # CYRILLIC SMALL LETTER E WITH DIAERESIS +044D 0308 ; [.1B3D.0020.0002.04ED] # CYRILLIC SMALL LETTER E WITH DIAERESIS +04EC ; [.1B3D.0020.0008.04EC] # CYRILLIC CAPITAL LETTER E WITH DIAERESIS +042D 0308 ; [.1B3D.0020.0008.04EC] # CYRILLIC CAPITAL LETTER E WITH DIAERESIS +044E ; [.1B41.0020.0002.044E] # CYRILLIC SMALL LETTER YU +2DFB ; [.1B41.0020.0004.2DFB] # COMBINING CYRILLIC LETTER YU +042E ; [.1B41.0020.0008.042E] # CYRILLIC CAPITAL LETTER YU +A655 ; [.1B45.0020.0002.A655] # CYRILLIC SMALL LETTER REVERSED YU +A654 ; [.1B45.0020.0008.A654] # CYRILLIC CAPITAL LETTER REVERSED YU +A657 ; [.1B46.0020.0002.A657] # CYRILLIC SMALL LETTER IOTIFIED A +2DFC ; [.1B46.0020.0004.2DFC] # COMBINING CYRILLIC LETTER IOTIFIED A +A656 ; [.1B46.0020.0008.A656] # CYRILLIC CAPITAL LETTER IOTIFIED A +044F ; [.1B47.0020.0002.044F] # CYRILLIC SMALL LETTER YA +042F ; [.1B47.0020.0008.042F] # CYRILLIC CAPITAL LETTER YA +0519 ; [.1B4B.0020.0002.0519] # CYRILLIC SMALL LETTER YAE +0518 ; [.1B4B.0020.0008.0518] # CYRILLIC CAPITAL LETTER YAE +0465 ; [.1B4C.0020.0002.0465] # CYRILLIC SMALL LETTER IOTIFIED E +A69F ; [.1B4C.0020.0004.A69F] # COMBINING CYRILLIC LETTER IOTIFIED E +0464 ; [.1B4C.0020.0008.0464] # CYRILLIC CAPITAL LETTER IOTIFIED E +0467 ; [.1B50.0020.0002.0467] # CYRILLIC SMALL LETTER LITTLE YUS +2DFD ; [.1B50.0020.0004.2DFD] # COMBINING CYRILLIC LETTER LITTLE YUS +0466 ; [.1B50.0020.0008.0466] # CYRILLIC CAPITAL LETTER LITTLE YUS +A659 ; [.1B54.0020.0002.A659] # CYRILLIC SMALL LETTER CLOSED LITTLE YUS +A658 ; [.1B54.0020.0008.A658] # CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS +046B ; [.1B55.0020.0002.046B] # CYRILLIC SMALL LETTER BIG YUS +2DFE ; [.1B55.0020.0004.2DFE] # COMBINING CYRILLIC LETTER BIG YUS +046A ; [.1B55.0020.0008.046A] # CYRILLIC CAPITAL LETTER BIG YUS +A65B ; [.1B59.0020.0002.A65B] # CYRILLIC SMALL LETTER BLENDED YUS +A65A ; [.1B59.0020.0008.A65A] # CYRILLIC CAPITAL LETTER BLENDED YUS +0469 ; [.1B5A.0020.0002.0469] # CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS +0468 ; [.1B5A.0020.0008.0468] # CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS +A65D ; [.1B5E.0020.0002.A65D] # CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS +A65C ; [.1B5E.0020.0008.A65C] # CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS +046D ; [.1B5F.0020.0002.046D] # CYRILLIC SMALL LETTER IOTIFIED BIG YUS +2DFF ; [.1B5F.0020.0004.2DFF] # COMBINING CYRILLIC LETTER IOTIFIED BIG YUS +046C ; [.1B5F.0020.0008.046C] # CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS +046F ; [.1B63.0020.0002.046F] # CYRILLIC SMALL LETTER KSI +046E ; [.1B63.0020.0008.046E] # CYRILLIC CAPITAL LETTER KSI +0471 ; [.1B67.0020.0002.0471] # CYRILLIC SMALL LETTER PSI +0470 ; [.1B67.0020.0008.0470] # CYRILLIC CAPITAL LETTER PSI +0473 ; [.1B6B.0020.0002.0473] # CYRILLIC SMALL LETTER FITA +2DF4 ; [.1B6B.0020.0004.2DF4] # COMBINING CYRILLIC LETTER FITA +0472 ; [.1B6B.0020.0008.0472] # CYRILLIC CAPITAL LETTER FITA +0475 ; [.1B6F.0020.0002.0475] # CYRILLIC SMALL LETTER IZHITSA +0474 ; [.1B6F.0020.0008.0474] # CYRILLIC CAPITAL LETTER IZHITSA +0477 ; [.1B73.0020.0002.0477] # CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT +0475 030F ; [.1B73.0020.0002.0477] # CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT +0476 ; [.1B73.0020.0008.0476] # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT +0474 030F ; [.1B73.0020.0008.0476] # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT +A65F ; [.1B77.0020.0002.A65F] # CYRILLIC SMALL LETTER YN +A65E ; [.1B77.0020.0008.A65E] # CYRILLIC CAPITAL LETTER YN +04A9 ; [.1B78.0020.0002.04A9] # CYRILLIC SMALL LETTER ABKHASIAN HA +04A8 ; [.1B78.0020.0008.04A8] # CYRILLIC CAPITAL LETTER ABKHASIAN HA +051D ; [.1B7C.0020.0002.051D] # CYRILLIC SMALL LETTER WE +051C ; [.1B7C.0020.0008.051C] # CYRILLIC CAPITAL LETTER WE +04CF ; [.1B7D.0020.0002.04CF] # CYRILLIC SMALL LETTER PALOCHKA +04C0 ; [.1B7D.0020.0008.04C0] # CYRILLIC LETTER PALOCHKA +2C30 ; [.1B81.0020.0002.2C30] # GLAGOLITIC SMALL LETTER AZU +2C00 ; [.1B81.0020.0008.2C00] # GLAGOLITIC CAPITAL LETTER AZU +2C31 ; [.1B82.0020.0002.2C31] # GLAGOLITIC SMALL LETTER BUKY +2C01 ; [.1B82.0020.0008.2C01] # GLAGOLITIC CAPITAL LETTER BUKY +2C32 ; [.1B83.0020.0002.2C32] # GLAGOLITIC SMALL LETTER VEDE +2C02 ; [.1B83.0020.0008.2C02] # GLAGOLITIC CAPITAL LETTER VEDE +2C33 ; [.1B84.0020.0002.2C33] # GLAGOLITIC SMALL LETTER GLAGOLI +2C03 ; [.1B84.0020.0008.2C03] # GLAGOLITIC CAPITAL LETTER GLAGOLI +2C34 ; [.1B85.0020.0002.2C34] # GLAGOLITIC SMALL LETTER DOBRO +2C04 ; [.1B85.0020.0008.2C04] # GLAGOLITIC CAPITAL LETTER DOBRO +2C35 ; [.1B86.0020.0002.2C35] # GLAGOLITIC SMALL LETTER YESTU +2C05 ; [.1B86.0020.0008.2C05] # GLAGOLITIC CAPITAL LETTER YESTU +2C36 ; [.1B87.0020.0002.2C36] # GLAGOLITIC SMALL LETTER ZHIVETE +2C06 ; [.1B87.0020.0008.2C06] # GLAGOLITIC CAPITAL LETTER ZHIVETE +2C37 ; [.1B88.0020.0002.2C37] # GLAGOLITIC SMALL LETTER DZELO +2C07 ; [.1B88.0020.0008.2C07] # GLAGOLITIC CAPITAL LETTER DZELO +2C38 ; [.1B89.0020.0002.2C38] # GLAGOLITIC SMALL LETTER ZEMLJA +2C08 ; [.1B89.0020.0008.2C08] # GLAGOLITIC CAPITAL LETTER ZEMLJA +2C39 ; [.1B8A.0020.0002.2C39] # GLAGOLITIC SMALL LETTER IZHE +2C09 ; [.1B8A.0020.0008.2C09] # GLAGOLITIC CAPITAL LETTER IZHE +2C3A ; [.1B8B.0020.0002.2C3A] # GLAGOLITIC SMALL LETTER INITIAL IZHE +2C0A ; [.1B8B.0020.0008.2C0A] # GLAGOLITIC CAPITAL LETTER INITIAL IZHE +2C3B ; [.1B8C.0020.0002.2C3B] # GLAGOLITIC SMALL LETTER I +2C0B ; [.1B8C.0020.0008.2C0B] # GLAGOLITIC CAPITAL LETTER I +2C3C ; [.1B8D.0020.0002.2C3C] # GLAGOLITIC SMALL LETTER DJERVI +2C0C ; [.1B8D.0020.0008.2C0C] # GLAGOLITIC CAPITAL LETTER DJERVI +2C3D ; [.1B8E.0020.0002.2C3D] # GLAGOLITIC SMALL LETTER KAKO +2C0D ; [.1B8E.0020.0008.2C0D] # GLAGOLITIC CAPITAL LETTER KAKO +2C3E ; [.1B8F.0020.0002.2C3E] # GLAGOLITIC SMALL LETTER LJUDIJE +2C0E ; [.1B8F.0020.0008.2C0E] # GLAGOLITIC CAPITAL LETTER LJUDIJE +2C3F ; [.1B90.0020.0002.2C3F] # GLAGOLITIC SMALL LETTER MYSLITE +2C0F ; [.1B90.0020.0008.2C0F] # GLAGOLITIC CAPITAL LETTER MYSLITE +2C40 ; [.1B91.0020.0002.2C40] # GLAGOLITIC SMALL LETTER NASHI +2C10 ; [.1B91.0020.0008.2C10] # GLAGOLITIC CAPITAL LETTER NASHI +2C41 ; [.1B92.0020.0002.2C41] # GLAGOLITIC SMALL LETTER ONU +2C11 ; [.1B92.0020.0008.2C11] # GLAGOLITIC CAPITAL LETTER ONU +2C42 ; [.1B93.0020.0002.2C42] # GLAGOLITIC SMALL LETTER POKOJI +2C12 ; [.1B93.0020.0008.2C12] # GLAGOLITIC CAPITAL LETTER POKOJI +2C43 ; [.1B94.0020.0002.2C43] # GLAGOLITIC SMALL LETTER RITSI +2C13 ; [.1B94.0020.0008.2C13] # GLAGOLITIC CAPITAL LETTER RITSI +2C44 ; [.1B95.0020.0002.2C44] # GLAGOLITIC SMALL LETTER SLOVO +2C14 ; [.1B95.0020.0008.2C14] # GLAGOLITIC CAPITAL LETTER SLOVO +2C45 ; [.1B96.0020.0002.2C45] # GLAGOLITIC SMALL LETTER TVRIDO +2C15 ; [.1B96.0020.0008.2C15] # GLAGOLITIC CAPITAL LETTER TVRIDO +2C46 ; [.1B97.0020.0002.2C46] # GLAGOLITIC SMALL LETTER UKU +2C16 ; [.1B97.0020.0008.2C16] # GLAGOLITIC CAPITAL LETTER UKU +2C47 ; [.1B98.0020.0002.2C47] # GLAGOLITIC SMALL LETTER FRITU +2C17 ; [.1B98.0020.0008.2C17] # GLAGOLITIC CAPITAL LETTER FRITU +2C48 ; [.1B99.0020.0002.2C48] # GLAGOLITIC SMALL LETTER HERU +2C18 ; [.1B99.0020.0008.2C18] # GLAGOLITIC CAPITAL LETTER HERU +2C49 ; [.1B9A.0020.0002.2C49] # GLAGOLITIC SMALL LETTER OTU +2C19 ; [.1B9A.0020.0008.2C19] # GLAGOLITIC CAPITAL LETTER OTU +2C4A ; [.1B9B.0020.0002.2C4A] # GLAGOLITIC SMALL LETTER PE +2C1A ; [.1B9B.0020.0008.2C1A] # GLAGOLITIC CAPITAL LETTER PE +2C4B ; [.1B9C.0020.0002.2C4B] # GLAGOLITIC SMALL LETTER SHTA +2C1B ; [.1B9C.0020.0008.2C1B] # GLAGOLITIC CAPITAL LETTER SHTA +2C4C ; [.1B9D.0020.0002.2C4C] # GLAGOLITIC SMALL LETTER TSI +2C1C ; [.1B9D.0020.0008.2C1C] # GLAGOLITIC CAPITAL LETTER TSI +2C4D ; [.1B9E.0020.0002.2C4D] # GLAGOLITIC SMALL LETTER CHRIVI +2C1D ; [.1B9E.0020.0008.2C1D] # GLAGOLITIC CAPITAL LETTER CHRIVI +2C4E ; [.1B9F.0020.0002.2C4E] # GLAGOLITIC SMALL LETTER SHA +2C1E ; [.1B9F.0020.0008.2C1E] # GLAGOLITIC CAPITAL LETTER SHA +2C4F ; [.1BA0.0020.0002.2C4F] # GLAGOLITIC SMALL LETTER YERU +2C1F ; [.1BA0.0020.0008.2C1F] # GLAGOLITIC CAPITAL LETTER YERU +2C50 ; [.1BA1.0020.0002.2C50] # GLAGOLITIC SMALL LETTER YERI +2C20 ; [.1BA1.0020.0008.2C20] # GLAGOLITIC CAPITAL LETTER YERI +2C51 ; [.1BA2.0020.0002.2C51] # GLAGOLITIC SMALL LETTER YATI +2C21 ; [.1BA2.0020.0008.2C21] # GLAGOLITIC CAPITAL LETTER YATI +2C52 ; [.1BA3.0020.0002.2C52] # GLAGOLITIC SMALL LETTER SPIDERY HA +2C22 ; [.1BA3.0020.0008.2C22] # GLAGOLITIC CAPITAL LETTER SPIDERY HA +2C53 ; [.1BA4.0020.0002.2C53] # GLAGOLITIC SMALL LETTER YU +2C23 ; [.1BA4.0020.0008.2C23] # GLAGOLITIC CAPITAL LETTER YU +2C54 ; [.1BA5.0020.0002.2C54] # GLAGOLITIC SMALL LETTER SMALL YUS +2C24 ; [.1BA5.0020.0008.2C24] # GLAGOLITIC CAPITAL LETTER SMALL YUS +2C55 ; [.1BA6.0020.0002.2C55] # GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL +2C25 ; [.1BA6.0020.0008.2C25] # GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL +2C56 ; [.1BA7.0020.0002.2C56] # GLAGOLITIC SMALL LETTER YO +2C26 ; [.1BA7.0020.0008.2C26] # GLAGOLITIC CAPITAL LETTER YO +2C57 ; [.1BA8.0020.0002.2C57] # GLAGOLITIC SMALL LETTER IOTATED SMALL YUS +2C27 ; [.1BA8.0020.0008.2C27] # GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS +2C58 ; [.1BA9.0020.0002.2C58] # GLAGOLITIC SMALL LETTER BIG YUS +2C28 ; [.1BA9.0020.0008.2C28] # GLAGOLITIC CAPITAL LETTER BIG YUS +2C59 ; [.1BAA.0020.0002.2C59] # GLAGOLITIC SMALL LETTER IOTATED BIG YUS +2C29 ; [.1BAA.0020.0008.2C29] # GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS +2C5A ; [.1BAB.0020.0002.2C5A] # GLAGOLITIC SMALL LETTER FITA +2C2A ; [.1BAB.0020.0008.2C2A] # GLAGOLITIC CAPITAL LETTER FITA +2C5B ; [.1BAC.0020.0002.2C5B] # GLAGOLITIC SMALL LETTER IZHITSA +2C2B ; [.1BAC.0020.0008.2C2B] # GLAGOLITIC CAPITAL LETTER IZHITSA +2C5C ; [.1BAD.0020.0002.2C5C] # GLAGOLITIC SMALL LETTER SHTAPIC +2C2C ; [.1BAD.0020.0008.2C2C] # GLAGOLITIC CAPITAL LETTER SHTAPIC +2C5D ; [.1BAE.0020.0002.2C5D] # GLAGOLITIC SMALL LETTER TROKUTASTI A +2C2D ; [.1BAE.0020.0008.2C2D] # GLAGOLITIC CAPITAL LETTER TROKUTASTI A +2C5E ; [.1BAF.0020.0002.2C5E] # GLAGOLITIC SMALL LETTER LATINATE MYSLITE +2C2E ; [.1BAF.0020.0008.2C2E] # GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE +10D0 ; [.1BB0.0020.0002.10D0] # GEORGIAN LETTER AN +2D00 ; [.1BB1.0020.0002.2D00] # GEORGIAN SMALL LETTER AN +10A0 ; [.1BB1.0020.0008.10A0] # GEORGIAN CAPITAL LETTER AN +10D1 ; [.1BB2.0020.0002.10D1] # GEORGIAN LETTER BAN +2D01 ; [.1BB3.0020.0002.2D01] # GEORGIAN SMALL LETTER BAN +10A1 ; [.1BB3.0020.0008.10A1] # GEORGIAN CAPITAL LETTER BAN +10D2 ; [.1BB4.0020.0002.10D2] # GEORGIAN LETTER GAN +2D02 ; [.1BB5.0020.0002.2D02] # GEORGIAN SMALL LETTER GAN +10A2 ; [.1BB5.0020.0008.10A2] # GEORGIAN CAPITAL LETTER GAN +10D3 ; [.1BB6.0020.0002.10D3] # GEORGIAN LETTER DON +2D03 ; [.1BB7.0020.0002.2D03] # GEORGIAN SMALL LETTER DON +10A3 ; [.1BB7.0020.0008.10A3] # GEORGIAN CAPITAL LETTER DON +10D4 ; [.1BB8.0020.0002.10D4] # GEORGIAN LETTER EN +2D04 ; [.1BB9.0020.0002.2D04] # GEORGIAN SMALL LETTER EN +10A4 ; [.1BB9.0020.0008.10A4] # GEORGIAN CAPITAL LETTER EN +10D5 ; [.1BBA.0020.0002.10D5] # GEORGIAN LETTER VIN +2D05 ; [.1BBB.0020.0002.2D05] # GEORGIAN SMALL LETTER VIN +10A5 ; [.1BBB.0020.0008.10A5] # GEORGIAN CAPITAL LETTER VIN +10D6 ; [.1BBC.0020.0002.10D6] # GEORGIAN LETTER ZEN +2D06 ; [.1BBD.0020.0002.2D06] # GEORGIAN SMALL LETTER ZEN +10A6 ; [.1BBD.0020.0008.10A6] # GEORGIAN CAPITAL LETTER ZEN +10F1 ; [.1BBE.0020.0002.10F1] # GEORGIAN LETTER HE +2D21 ; [.1BBF.0020.0002.2D21] # GEORGIAN SMALL LETTER HE +10C1 ; [.1BBF.0020.0008.10C1] # GEORGIAN CAPITAL LETTER HE +10D7 ; [.1BC0.0020.0002.10D7] # GEORGIAN LETTER TAN +2D07 ; [.1BC1.0020.0002.2D07] # GEORGIAN SMALL LETTER TAN +10A7 ; [.1BC1.0020.0008.10A7] # GEORGIAN CAPITAL LETTER TAN +10D8 ; [.1BC2.0020.0002.10D8] # GEORGIAN LETTER IN +2D08 ; [.1BC3.0020.0002.2D08] # GEORGIAN SMALL LETTER IN +10A8 ; [.1BC3.0020.0008.10A8] # GEORGIAN CAPITAL LETTER IN +10D9 ; [.1BC4.0020.0002.10D9] # GEORGIAN LETTER KAN +2D09 ; [.1BC5.0020.0002.2D09] # GEORGIAN SMALL LETTER KAN +10A9 ; [.1BC5.0020.0008.10A9] # GEORGIAN CAPITAL LETTER KAN +10DA ; [.1BC6.0020.0002.10DA] # GEORGIAN LETTER LAS +2D0A ; [.1BC7.0020.0002.2D0A] # GEORGIAN SMALL LETTER LAS +10AA ; [.1BC7.0020.0008.10AA] # GEORGIAN CAPITAL LETTER LAS +10DB ; [.1BC8.0020.0002.10DB] # GEORGIAN LETTER MAN +2D0B ; [.1BC9.0020.0002.2D0B] # GEORGIAN SMALL LETTER MAN +10AB ; [.1BC9.0020.0008.10AB] # GEORGIAN CAPITAL LETTER MAN +10DC ; [.1BCA.0020.0002.10DC] # GEORGIAN LETTER NAR +10FC ; [.1BCA.0020.0014.10FC] # MODIFIER LETTER GEORGIAN NAR +2D0C ; [.1BCB.0020.0002.2D0C] # GEORGIAN SMALL LETTER NAR +10AC ; [.1BCB.0020.0008.10AC] # GEORGIAN CAPITAL LETTER NAR +10F2 ; [.1BCC.0020.0002.10F2] # GEORGIAN LETTER HIE +2D22 ; [.1BCD.0020.0002.2D22] # GEORGIAN SMALL LETTER HIE +10C2 ; [.1BCD.0020.0008.10C2] # GEORGIAN CAPITAL LETTER HIE +10DD ; [.1BCE.0020.0002.10DD] # GEORGIAN LETTER ON +2D0D ; [.1BCF.0020.0002.2D0D] # GEORGIAN SMALL LETTER ON +10AD ; [.1BCF.0020.0008.10AD] # GEORGIAN CAPITAL LETTER ON +10DE ; [.1BD0.0020.0002.10DE] # GEORGIAN LETTER PAR +2D0E ; [.1BD1.0020.0002.2D0E] # GEORGIAN SMALL LETTER PAR +10AE ; [.1BD1.0020.0008.10AE] # GEORGIAN CAPITAL LETTER PAR +10DF ; [.1BD2.0020.0002.10DF] # GEORGIAN LETTER ZHAR +2D0F ; [.1BD3.0020.0002.2D0F] # GEORGIAN SMALL LETTER ZHAR +10AF ; [.1BD3.0020.0008.10AF] # GEORGIAN CAPITAL LETTER ZHAR +10E0 ; [.1BD4.0020.0002.10E0] # GEORGIAN LETTER RAE +2D10 ; [.1BD5.0020.0002.2D10] # GEORGIAN SMALL LETTER RAE +10B0 ; [.1BD5.0020.0008.10B0] # GEORGIAN CAPITAL LETTER RAE +10E1 ; [.1BD6.0020.0002.10E1] # GEORGIAN LETTER SAN +2D11 ; [.1BD7.0020.0002.2D11] # GEORGIAN SMALL LETTER SAN +10B1 ; [.1BD7.0020.0008.10B1] # GEORGIAN CAPITAL LETTER SAN +10E2 ; [.1BD8.0020.0002.10E2] # GEORGIAN LETTER TAR +2D12 ; [.1BD9.0020.0002.2D12] # GEORGIAN SMALL LETTER TAR +10B2 ; [.1BD9.0020.0008.10B2] # GEORGIAN CAPITAL LETTER TAR +10F3 ; [.1BDA.0020.0002.10F3] # GEORGIAN LETTER WE +2D23 ; [.1BDB.0020.0002.2D23] # GEORGIAN SMALL LETTER WE +10C3 ; [.1BDB.0020.0008.10C3] # GEORGIAN CAPITAL LETTER WE +10E3 ; [.1BDC.0020.0002.10E3] # GEORGIAN LETTER UN +2D13 ; [.1BDD.0020.0002.2D13] # GEORGIAN SMALL LETTER UN +10B3 ; [.1BDD.0020.0008.10B3] # GEORGIAN CAPITAL LETTER UN +10E4 ; [.1BDE.0020.0002.10E4] # GEORGIAN LETTER PHAR +2D14 ; [.1BDF.0020.0002.2D14] # GEORGIAN SMALL LETTER PHAR +10B4 ; [.1BDF.0020.0008.10B4] # GEORGIAN CAPITAL LETTER PHAR +10E5 ; [.1BE0.0020.0002.10E5] # GEORGIAN LETTER KHAR +2D15 ; [.1BE1.0020.0002.2D15] # GEORGIAN SMALL LETTER KHAR +10B5 ; [.1BE1.0020.0008.10B5] # GEORGIAN CAPITAL LETTER KHAR +10E6 ; [.1BE2.0020.0002.10E6] # GEORGIAN LETTER GHAN +2D16 ; [.1BE3.0020.0002.2D16] # GEORGIAN SMALL LETTER GHAN +10B6 ; [.1BE3.0020.0008.10B6] # GEORGIAN CAPITAL LETTER GHAN +10E7 ; [.1BE4.0020.0002.10E7] # GEORGIAN LETTER QAR +2D17 ; [.1BE5.0020.0002.2D17] # GEORGIAN SMALL LETTER QAR +10B7 ; [.1BE5.0020.0008.10B7] # GEORGIAN CAPITAL LETTER QAR +10E8 ; [.1BE6.0020.0002.10E8] # GEORGIAN LETTER SHIN +2D18 ; [.1BE7.0020.0002.2D18] # GEORGIAN SMALL LETTER SHIN +10B8 ; [.1BE7.0020.0008.10B8] # GEORGIAN CAPITAL LETTER SHIN +10E9 ; [.1BE8.0020.0002.10E9] # GEORGIAN LETTER CHIN +2D19 ; [.1BE9.0020.0002.2D19] # GEORGIAN SMALL LETTER CHIN +10B9 ; [.1BE9.0020.0008.10B9] # GEORGIAN CAPITAL LETTER CHIN +10EA ; [.1BEA.0020.0002.10EA] # GEORGIAN LETTER CAN +2D1A ; [.1BEB.0020.0002.2D1A] # GEORGIAN SMALL LETTER CAN +10BA ; [.1BEB.0020.0008.10BA] # GEORGIAN CAPITAL LETTER CAN +10EB ; [.1BEC.0020.0002.10EB] # GEORGIAN LETTER JIL +2D1B ; [.1BED.0020.0002.2D1B] # GEORGIAN SMALL LETTER JIL +10BB ; [.1BED.0020.0008.10BB] # GEORGIAN CAPITAL LETTER JIL +10EC ; [.1BEE.0020.0002.10EC] # GEORGIAN LETTER CIL +2D1C ; [.1BEF.0020.0002.2D1C] # GEORGIAN SMALL LETTER CIL +10BC ; [.1BEF.0020.0008.10BC] # GEORGIAN CAPITAL LETTER CIL +10ED ; [.1BF0.0020.0002.10ED] # GEORGIAN LETTER CHAR +2D1D ; [.1BF1.0020.0002.2D1D] # GEORGIAN SMALL LETTER CHAR +10BD ; [.1BF1.0020.0008.10BD] # GEORGIAN CAPITAL LETTER CHAR +10EE ; [.1BF2.0020.0002.10EE] # GEORGIAN LETTER XAN +2D1E ; [.1BF3.0020.0002.2D1E] # GEORGIAN SMALL LETTER XAN +10BE ; [.1BF3.0020.0008.10BE] # GEORGIAN CAPITAL LETTER XAN +10F4 ; [.1BF4.0020.0002.10F4] # GEORGIAN LETTER HAR +2D24 ; [.1BF5.0020.0002.2D24] # GEORGIAN SMALL LETTER HAR +10C4 ; [.1BF5.0020.0008.10C4] # GEORGIAN CAPITAL LETTER HAR +10EF ; [.1BF6.0020.0002.10EF] # GEORGIAN LETTER JHAN +2D1F ; [.1BF7.0020.0002.2D1F] # GEORGIAN SMALL LETTER JHAN +10BF ; [.1BF7.0020.0008.10BF] # GEORGIAN CAPITAL LETTER JHAN +10F0 ; [.1BF8.0020.0002.10F0] # GEORGIAN LETTER HAE +2D20 ; [.1BF9.0020.0002.2D20] # GEORGIAN SMALL LETTER HAE +10C0 ; [.1BF9.0020.0008.10C0] # GEORGIAN CAPITAL LETTER HAE +10F5 ; [.1BFA.0020.0002.10F5] # GEORGIAN LETTER HOE +2D25 ; [.1BFB.0020.0002.2D25] # GEORGIAN SMALL LETTER HOE +10C5 ; [.1BFB.0020.0008.10C5] # GEORGIAN CAPITAL LETTER HOE +10F6 ; [.1BFC.0020.0002.10F6] # GEORGIAN LETTER FI +10F7 ; [.1BFD.0020.0002.10F7] # GEORGIAN LETTER YN +2D27 ; [.1BFE.0020.0002.2D27] # GEORGIAN SMALL LETTER YN +10C7 ; [.1BFE.0020.0008.10C7] # GEORGIAN CAPITAL LETTER YN +10F8 ; [.1BFF.0020.0002.10F8] # GEORGIAN LETTER ELIFI +10F9 ; [.1C00.0020.0002.10F9] # GEORGIAN LETTER TURNED GAN +10FA ; [.1C01.0020.0002.10FA] # GEORGIAN LETTER AIN +10FD ; [.1C02.0020.0002.10FD] # GEORGIAN LETTER AEN +2D2D ; [.1C03.0020.0002.2D2D] # GEORGIAN SMALL LETTER AEN +10CD ; [.1C03.0020.0008.10CD] # GEORGIAN CAPITAL LETTER AEN +10FE ; [.1C04.0020.0002.10FE] # GEORGIAN LETTER HARD SIGN +10FF ; [.1C05.0020.0002.10FF] # GEORGIAN LETTER LABIAL SIGN +0561 ; [.1C06.0020.0002.0561] # ARMENIAN SMALL LETTER AYB +0531 ; [.1C06.0020.0008.0531] # ARMENIAN CAPITAL LETTER AYB +0562 ; [.1C07.0020.0002.0562] # ARMENIAN SMALL LETTER BEN +0532 ; [.1C07.0020.0008.0532] # ARMENIAN CAPITAL LETTER BEN +0563 ; [.1C08.0020.0002.0563] # ARMENIAN SMALL LETTER GIM +0533 ; [.1C08.0020.0008.0533] # ARMENIAN CAPITAL LETTER GIM +0564 ; [.1C09.0020.0002.0564] # ARMENIAN SMALL LETTER DA +0534 ; [.1C09.0020.0008.0534] # ARMENIAN CAPITAL LETTER DA +0565 ; [.1C0A.0020.0002.0565] # ARMENIAN SMALL LETTER ECH +0535 ; [.1C0A.0020.0008.0535] # ARMENIAN CAPITAL LETTER ECH +0587 ; [.1C0A.0020.0004.0587][.1C27.0020.0004.0587] # ARMENIAN SMALL LIGATURE ECH YIWN +0566 ; [.1C0B.0020.0002.0566] # ARMENIAN SMALL LETTER ZA +0536 ; [.1C0B.0020.0008.0536] # ARMENIAN CAPITAL LETTER ZA +0567 ; [.1C0C.0020.0002.0567] # ARMENIAN SMALL LETTER EH +0537 ; [.1C0C.0020.0008.0537] # ARMENIAN CAPITAL LETTER EH +0568 ; [.1C0D.0020.0002.0568] # ARMENIAN SMALL LETTER ET +0538 ; [.1C0D.0020.0008.0538] # ARMENIAN CAPITAL LETTER ET +0569 ; [.1C0E.0020.0002.0569] # ARMENIAN SMALL LETTER TO +0539 ; [.1C0E.0020.0008.0539] # ARMENIAN CAPITAL LETTER TO +056A ; [.1C0F.0020.0002.056A] # ARMENIAN SMALL LETTER ZHE +053A ; [.1C0F.0020.0008.053A] # ARMENIAN CAPITAL LETTER ZHE +056B ; [.1C10.0020.0002.056B] # ARMENIAN SMALL LETTER INI +053B ; [.1C10.0020.0008.053B] # ARMENIAN CAPITAL LETTER INI +056C ; [.1C11.0020.0002.056C] # ARMENIAN SMALL LETTER LIWN +053C ; [.1C11.0020.0008.053C] # ARMENIAN CAPITAL LETTER LIWN +056D ; [.1C12.0020.0002.056D] # ARMENIAN SMALL LETTER XEH +053D ; [.1C12.0020.0008.053D] # ARMENIAN CAPITAL LETTER XEH +056E ; [.1C13.0020.0002.056E] # ARMENIAN SMALL LETTER CA +053E ; [.1C13.0020.0008.053E] # ARMENIAN CAPITAL LETTER CA +056F ; [.1C14.0020.0002.056F] # ARMENIAN SMALL LETTER KEN +053F ; [.1C14.0020.0008.053F] # ARMENIAN CAPITAL LETTER KEN +0570 ; [.1C15.0020.0002.0570] # ARMENIAN SMALL LETTER HO +0540 ; [.1C15.0020.0008.0540] # ARMENIAN CAPITAL LETTER HO +0571 ; [.1C16.0020.0002.0571] # ARMENIAN SMALL LETTER JA +0541 ; [.1C16.0020.0008.0541] # ARMENIAN CAPITAL LETTER JA +0572 ; [.1C17.0020.0002.0572] # ARMENIAN SMALL LETTER GHAD +0542 ; [.1C17.0020.0008.0542] # ARMENIAN CAPITAL LETTER GHAD +0573 ; [.1C18.0020.0002.0573] # ARMENIAN SMALL LETTER CHEH +0543 ; [.1C18.0020.0008.0543] # ARMENIAN CAPITAL LETTER CHEH +0574 ; [.1C19.0020.0002.0574] # ARMENIAN SMALL LETTER MEN +0544 ; [.1C19.0020.0008.0544] # ARMENIAN CAPITAL LETTER MEN +FB14 ; [.1C19.0020.0004.FB14][.1C0A.0020.0004.FB14] # ARMENIAN SMALL LIGATURE MEN ECH +FB15 ; [.1C19.0020.0004.FB15][.1C10.0020.0004.FB15] # ARMENIAN SMALL LIGATURE MEN INI +FB17 ; [.1C19.0020.0004.FB17][.1C12.0020.0004.FB17] # ARMENIAN SMALL LIGATURE MEN XEH +FB13 ; [.1C19.0020.0004.FB13][.1C1B.0020.0004.FB13] # ARMENIAN SMALL LIGATURE MEN NOW +0575 ; [.1C1A.0020.0002.0575] # ARMENIAN SMALL LETTER YI +0545 ; [.1C1A.0020.0008.0545] # ARMENIAN CAPITAL LETTER YI +0576 ; [.1C1B.0020.0002.0576] # ARMENIAN SMALL LETTER NOW +0546 ; [.1C1B.0020.0008.0546] # ARMENIAN CAPITAL LETTER NOW +0577 ; [.1C1C.0020.0002.0577] # ARMENIAN SMALL LETTER SHA +0547 ; [.1C1C.0020.0008.0547] # ARMENIAN CAPITAL LETTER SHA +0578 ; [.1C1D.0020.0002.0578] # ARMENIAN SMALL LETTER VO +0548 ; [.1C1D.0020.0008.0548] # ARMENIAN CAPITAL LETTER VO +0579 ; [.1C1E.0020.0002.0579] # ARMENIAN SMALL LETTER CHA +0549 ; [.1C1E.0020.0008.0549] # ARMENIAN CAPITAL LETTER CHA +057A ; [.1C1F.0020.0002.057A] # ARMENIAN SMALL LETTER PEH +054A ; [.1C1F.0020.0008.054A] # ARMENIAN CAPITAL LETTER PEH +057B ; [.1C20.0020.0002.057B] # ARMENIAN SMALL LETTER JHEH +054B ; [.1C20.0020.0008.054B] # ARMENIAN CAPITAL LETTER JHEH +057C ; [.1C21.0020.0002.057C] # ARMENIAN SMALL LETTER RA +054C ; [.1C21.0020.0008.054C] # ARMENIAN CAPITAL LETTER RA +057D ; [.1C22.0020.0002.057D] # ARMENIAN SMALL LETTER SEH +054D ; [.1C22.0020.0008.054D] # ARMENIAN CAPITAL LETTER SEH +057E ; [.1C23.0020.0002.057E] # ARMENIAN SMALL LETTER VEW +054E ; [.1C23.0020.0008.054E] # ARMENIAN CAPITAL LETTER VEW +FB16 ; [.1C23.0020.0004.FB16][.1C1B.0020.0004.FB16] # ARMENIAN SMALL LIGATURE VEW NOW +057F ; [.1C24.0020.0002.057F] # ARMENIAN SMALL LETTER TIWN +054F ; [.1C24.0020.0008.054F] # ARMENIAN CAPITAL LETTER TIWN +0580 ; [.1C25.0020.0002.0580] # ARMENIAN SMALL LETTER REH +0550 ; [.1C25.0020.0008.0550] # ARMENIAN CAPITAL LETTER REH +0581 ; [.1C26.0020.0002.0581] # ARMENIAN SMALL LETTER CO +0551 ; [.1C26.0020.0008.0551] # ARMENIAN CAPITAL LETTER CO +0582 ; [.1C27.0020.0002.0582] # ARMENIAN SMALL LETTER YIWN +0552 ; [.1C27.0020.0008.0552] # ARMENIAN CAPITAL LETTER YIWN +0583 ; [.1C28.0020.0002.0583] # ARMENIAN SMALL LETTER PIWR +0553 ; [.1C28.0020.0008.0553] # ARMENIAN CAPITAL LETTER PIWR +0584 ; [.1C29.0020.0002.0584] # ARMENIAN SMALL LETTER KEH +0554 ; [.1C29.0020.0008.0554] # ARMENIAN CAPITAL LETTER KEH +0585 ; [.1C2A.0020.0002.0585] # ARMENIAN SMALL LETTER OH +0555 ; [.1C2A.0020.0008.0555] # ARMENIAN CAPITAL LETTER OH +0586 ; [.1C2B.0020.0002.0586] # ARMENIAN SMALL LETTER FEH +0556 ; [.1C2B.0020.0008.0556] # ARMENIAN CAPITAL LETTER FEH +0559 ; [.1C2C.0020.0002.0559] # ARMENIAN MODIFIER LETTER LEFT HALF RING +05D0 ; [.1C2D.0020.0002.05D0] # HEBREW LETTER ALEF +2135 ; [.1C2D.0020.0004.2135] # ALEF SYMBOL +FB21 ; [.1C2D.0020.0005.FB21] # HEBREW LETTER WIDE ALEF +FB2E ; [.1C2D.0020.0002.05D0][.0000.008C.0002.05B7] # HEBREW LETTER ALEF WITH PATAH +FB2F ; [.1C2D.0020.0002.05D0][.0000.008D.0002.05B8] # HEBREW LETTER ALEF WITH QAMATS +FB30 ; [.1C2D.0020.0002.05D0][.0000.0092.0002.05BC] # HEBREW LETTER ALEF WITH MAPIQ +FB4F ; [.1C2D.0020.0004.FB4F][.1C38.0020.0004.FB4F] # HEBREW LIGATURE ALEF LAMED +05D1 ; [.1C2E.0020.0002.05D1] # HEBREW LETTER BET +2136 ; [.1C2E.0020.0004.2136] # BET SYMBOL +FB31 ; [.1C2E.0020.0002.05D1][.0000.0092.0002.05BC] # HEBREW LETTER BET WITH DAGESH +FB4C ; [.1C2E.0020.0002.05D1][.0000.0095.0002.05BF] # HEBREW LETTER BET WITH RAFE +05D2 ; [.1C2F.0020.0002.05D2] # HEBREW LETTER GIMEL +2137 ; [.1C2F.0020.0004.2137] # GIMEL SYMBOL +FB32 ; [.1C2F.0020.0002.05D2][.0000.0092.0002.05BC] # HEBREW LETTER GIMEL WITH DAGESH +05D3 ; [.1C30.0020.0002.05D3] # HEBREW LETTER DALET +2138 ; [.1C30.0020.0004.2138] # DALET SYMBOL +FB22 ; [.1C30.0020.0005.FB22] # HEBREW LETTER WIDE DALET +FB33 ; [.1C30.0020.0002.05D3][.0000.0092.0002.05BC] # HEBREW LETTER DALET WITH DAGESH +05D4 ; [.1C31.0020.0002.05D4] # HEBREW LETTER HE +FB23 ; [.1C31.0020.0005.FB23] # HEBREW LETTER WIDE HE +FB34 ; [.1C31.0020.0002.05D4][.0000.0092.0002.05BC] # HEBREW LETTER HE WITH MAPIQ +05D5 ; [.1C32.0020.0002.05D5] # HEBREW LETTER VAV +FB4B ; [.1C32.0020.0002.05D5][.0000.008E.0002.05B9] # HEBREW LETTER VAV WITH HOLAM +FB35 ; [.1C32.0020.0002.05D5][.0000.0092.0002.05BC] # HEBREW LETTER VAV WITH DAGESH +05F0 ; [.1C32.0020.0004.05F0][.1C32.0020.0004.05F0] # HEBREW LIGATURE YIDDISH DOUBLE VAV +05F1 ; [.1C32.0020.0004.05F1][.1C36.0020.0004.05F1] # HEBREW LIGATURE YIDDISH VAV YOD +05D6 ; [.1C33.0020.0002.05D6] # HEBREW LETTER ZAYIN +FB36 ; [.1C33.0020.0002.05D6][.0000.0092.0002.05BC] # HEBREW LETTER ZAYIN WITH DAGESH +05D7 ; [.1C34.0020.0002.05D7] # HEBREW LETTER HET +05D8 ; [.1C35.0020.0002.05D8] # HEBREW LETTER TET +FB38 ; [.1C35.0020.0002.05D8][.0000.0092.0002.05BC] # HEBREW LETTER TET WITH DAGESH +05D9 ; [.1C36.0020.0002.05D9] # HEBREW LETTER YOD +FB1D ; [.1C36.0020.0002.05D9][.0000.0089.0002.05B4] # HEBREW LETTER YOD WITH HIRIQ +FB39 ; [.1C36.0020.0002.05D9][.0000.0092.0002.05BC] # HEBREW LETTER YOD WITH DAGESH +05F2 ; [.1C36.0020.0004.05F2][.1C36.0020.0004.05F2] # HEBREW LIGATURE YIDDISH DOUBLE YOD +FB1F ; [.1C36.0020.0004.FB1F][.1C36.0020.0004.FB1F][.0000.008C.0002.FB1F] # HEBREW LIGATURE YIDDISH YOD YOD PATAH +05DB ; [.1C37.0020.0002.05DB] # HEBREW LETTER KAF +FB24 ; [.1C37.0020.0005.FB24] # HEBREW LETTER WIDE KAF +05DA ; [.1C37.0020.0019.05DA] # HEBREW LETTER FINAL KAF +FB3B ; [.1C37.0020.0002.05DB][.0000.0092.0002.05BC] # HEBREW LETTER KAF WITH DAGESH +FB3A ; [.1C37.0020.0019.FB3A][.0000.0092.0002.FB3A] # HEBREW LETTER FINAL KAF WITH DAGESH +FB4D ; [.1C37.0020.0002.05DB][.0000.0095.0002.05BF] # HEBREW LETTER KAF WITH RAFE +05DC ; [.1C38.0020.0002.05DC] # HEBREW LETTER LAMED +FB25 ; [.1C38.0020.0005.FB25] # HEBREW LETTER WIDE LAMED +FB3C ; [.1C38.0020.0002.05DC][.0000.0092.0002.05BC] # HEBREW LETTER LAMED WITH DAGESH +05DE ; [.1C39.0020.0002.05DE] # HEBREW LETTER MEM +FB26 ; [.1C39.0020.0005.FB26] # HEBREW LETTER WIDE FINAL MEM +05DD ; [.1C39.0020.0019.05DD] # HEBREW LETTER FINAL MEM +FB3E ; [.1C39.0020.0002.05DE][.0000.0092.0002.05BC] # HEBREW LETTER MEM WITH DAGESH +05E0 ; [.1C3A.0020.0002.05E0] # HEBREW LETTER NUN +05DF ; [.1C3A.0020.0019.05DF] # HEBREW LETTER FINAL NUN +FB40 ; [.1C3A.0020.0002.05E0][.0000.0092.0002.05BC] # HEBREW LETTER NUN WITH DAGESH +05E1 ; [.1C3B.0020.0002.05E1] # HEBREW LETTER SAMEKH +FB41 ; [.1C3B.0020.0002.05E1][.0000.0092.0002.05BC] # HEBREW LETTER SAMEKH WITH DAGESH +05E2 ; [.1C3C.0020.0002.05E2] # HEBREW LETTER AYIN +FB20 ; [.1C3C.0020.0005.FB20] # HEBREW LETTER ALTERNATIVE AYIN +05E4 ; [.1C3D.0020.0002.05E4] # HEBREW LETTER PE +05E3 ; [.1C3D.0020.0019.05E3] # HEBREW LETTER FINAL PE +FB44 ; [.1C3D.0020.0002.05E4][.0000.0092.0002.05BC] # HEBREW LETTER PE WITH DAGESH +FB43 ; [.1C3D.0020.0019.FB43][.0000.0092.0002.FB43] # HEBREW LETTER FINAL PE WITH DAGESH +FB4E ; [.1C3D.0020.0002.05E4][.0000.0095.0002.05BF] # HEBREW LETTER PE WITH RAFE +05E6 ; [.1C3E.0020.0002.05E6] # HEBREW LETTER TSADI +05E5 ; [.1C3E.0020.0019.05E5] # HEBREW LETTER FINAL TSADI +FB46 ; [.1C3E.0020.0002.05E6][.0000.0092.0002.05BC] # HEBREW LETTER TSADI WITH DAGESH +05E7 ; [.1C3F.0020.0002.05E7] # HEBREW LETTER QOF +FB47 ; [.1C3F.0020.0002.05E7][.0000.0092.0002.05BC] # HEBREW LETTER QOF WITH DAGESH +05E8 ; [.1C40.0020.0002.05E8] # HEBREW LETTER RESH +FB27 ; [.1C40.0020.0005.FB27] # HEBREW LETTER WIDE RESH +FB48 ; [.1C40.0020.0002.05E8][.0000.0092.0002.05BC] # HEBREW LETTER RESH WITH DAGESH +05E9 ; [.1C41.0020.0002.05E9] # HEBREW LETTER SHIN +FB2B ; [.1C41.0020.0002.05E9][.0000.0090.0002.05C2] # HEBREW LETTER SHIN WITH SIN DOT +FB2A ; [.1C41.0020.0002.05E9][.0000.0091.0002.05C1] # HEBREW LETTER SHIN WITH SHIN DOT +FB49 ; [.1C41.0020.0002.05E9][.0000.0092.0002.05BC] # HEBREW LETTER SHIN WITH DAGESH +FB2D ; [.1C41.0020.0002.05E9][.0000.0092.0002.05BC][.0000.0090.0002.05C2] # HEBREW LETTER SHIN WITH DAGESH AND SIN DOT +FB2C ; [.1C41.0020.0002.05E9][.0000.0092.0002.05BC][.0000.0091.0002.05C1] # HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT +05EA ; [.1C42.0020.0002.05EA] # HEBREW LETTER TAV +FB28 ; [.1C42.0020.0005.FB28] # HEBREW LETTER WIDE TAV +FB4A ; [.1C42.0020.0002.05EA][.0000.0092.0002.05BC] # HEBREW LETTER TAV WITH DAGESH +10900 ; [.1C43.0020.0002.10900] # PHOENICIAN LETTER ALF +10901 ; [.1C44.0020.0002.10901] # PHOENICIAN LETTER BET +10902 ; [.1C45.0020.0002.10902] # PHOENICIAN LETTER GAML +10903 ; [.1C46.0020.0002.10903] # PHOENICIAN LETTER DELT +10904 ; [.1C47.0020.0002.10904] # PHOENICIAN LETTER HE +10905 ; [.1C48.0020.0002.10905] # PHOENICIAN LETTER WAU +10906 ; [.1C49.0020.0002.10906] # PHOENICIAN LETTER ZAI +10907 ; [.1C4A.0020.0002.10907] # PHOENICIAN LETTER HET +10908 ; [.1C4B.0020.0002.10908] # PHOENICIAN LETTER TET +10909 ; [.1C4C.0020.0002.10909] # PHOENICIAN LETTER YOD +1090A ; [.1C4D.0020.0002.1090A] # PHOENICIAN LETTER KAF +1090B ; [.1C4E.0020.0002.1090B] # PHOENICIAN LETTER LAMD +1090C ; [.1C4F.0020.0002.1090C] # PHOENICIAN LETTER MEM +1090D ; [.1C50.0020.0002.1090D] # PHOENICIAN LETTER NUN +1090E ; [.1C51.0020.0002.1090E] # PHOENICIAN LETTER SEMK +1090F ; [.1C52.0020.0002.1090F] # PHOENICIAN LETTER AIN +10910 ; [.1C53.0020.0002.10910] # PHOENICIAN LETTER PE +10911 ; [.1C54.0020.0002.10911] # PHOENICIAN LETTER SADE +10912 ; [.1C55.0020.0002.10912] # PHOENICIAN LETTER QOF +10913 ; [.1C56.0020.0002.10913] # PHOENICIAN LETTER ROSH +10914 ; [.1C57.0020.0002.10914] # PHOENICIAN LETTER SHIN +10915 ; [.1C58.0020.0002.10915] # PHOENICIAN LETTER TAU +0800 ; [.1C59.0020.0002.0800] # SAMARITAN LETTER ALAF +0801 ; [.1C5A.0020.0002.0801] # SAMARITAN LETTER BIT +0802 ; [.1C5B.0020.0002.0802] # SAMARITAN LETTER GAMAN +0803 ; [.1C5C.0020.0002.0803] # SAMARITAN LETTER DALAT +0804 ; [.1C5D.0020.0002.0804] # SAMARITAN LETTER IY +0805 ; [.1C5E.0020.0002.0805] # SAMARITAN LETTER BAA +0806 ; [.1C5F.0020.0002.0806] # SAMARITAN LETTER ZEN +0807 ; [.1C60.0020.0002.0807] # SAMARITAN LETTER IT +0808 ; [.1C61.0020.0002.0808] # SAMARITAN LETTER TIT +0809 ; [.1C62.0020.0002.0809] # SAMARITAN LETTER YUT +080A ; [.1C63.0020.0002.080A] # SAMARITAN LETTER KAAF +080B ; [.1C64.0020.0002.080B] # SAMARITAN LETTER LABAT +080C ; [.1C65.0020.0002.080C] # SAMARITAN LETTER MIM +080D ; [.1C66.0020.0002.080D] # SAMARITAN LETTER NUN +080E ; [.1C67.0020.0002.080E] # SAMARITAN LETTER SINGAAT +080F ; [.1C68.0020.0002.080F] # SAMARITAN LETTER IN +0810 ; [.1C69.0020.0002.0810] # SAMARITAN LETTER FI +0811 ; [.1C6A.0020.0002.0811] # SAMARITAN LETTER TSAADIY +0812 ; [.1C6B.0020.0002.0812] # SAMARITAN LETTER QUF +0813 ; [.1C6C.0020.0002.0813] # SAMARITAN LETTER RISH +0814 ; [.1C6D.0020.0002.0814] # SAMARITAN LETTER SHAN +0815 ; [.1C6E.0020.0002.0815] # SAMARITAN LETTER TAAF +0816 ; [.1C6F.0020.0002.0816] # SAMARITAN MARK IN +0817 ; [.1C70.0020.0002.0817] # SAMARITAN MARK IN-ALAF +081A ; [.1C71.0020.0002.081A] # SAMARITAN MODIFIER LETTER EPENTHETIC YUT +081B ; [.1C72.0020.0002.081B] # SAMARITAN MARK EPENTHETIC YUT +0621 ; [.1C73.0020.0002.0621] # ARABIC LETTER HAMZA +0674 ; [.1C73.0020.0004.0674] # ARABIC LETTER HIGH HAMZA +FE80 ; [.1C73.0020.001A.FE80] # ARABIC LETTER HAMZA ISOLATED FORM +06FD ; [.1C73.0020.0004.06FD][.0000.013A.0004.06FD] # ARABIC SIGN SINDHI AMPERSAND +0622 ; [.1C74.0020.0002.0622] # ARABIC LETTER ALEF WITH MADDA ABOVE +0627 0653 ; [.1C74.0020.0002.0622] # ARABIC LETTER ALEF WITH MADDA ABOVE +FE82 ; [.1C74.0020.0019.FE82] # ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM +FE81 ; [.1C74.0020.001A.FE81] # ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM +0623 ; [.1C75.0020.0002.0623] # ARABIC LETTER ALEF WITH HAMZA ABOVE +0627 0654 ; [.1C75.0020.0002.0623] # ARABIC LETTER ALEF WITH HAMZA ABOVE +FE84 ; [.1C75.0020.0019.FE84] # ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM +FE83 ; [.1C75.0020.001A.FE83] # ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM +0672 ; [.1C76.0020.0002.0672] # ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE +0671 ; [.1C77.0020.0002.0671] # ARABIC LETTER ALEF WASLA +FB51 ; [.1C77.0020.0019.FB51] # ARABIC LETTER ALEF WASLA FINAL FORM +FB50 ; [.1C77.0020.001A.FB50] # ARABIC LETTER ALEF WASLA ISOLATED FORM +0624 ; [.1C78.0020.0002.0624] # ARABIC LETTER WAW WITH HAMZA ABOVE +0648 0654 ; [.1C78.0020.0002.0624] # ARABIC LETTER WAW WITH HAMZA ABOVE +FE86 ; [.1C78.0020.0019.FE86] # ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM +FE85 ; [.1C78.0020.001A.FE85] # ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM +0625 ; [.1C79.0020.0002.0625] # ARABIC LETTER ALEF WITH HAMZA BELOW +0627 0655 ; [.1C79.0020.0002.0625] # ARABIC LETTER ALEF WITH HAMZA BELOW +FE88 ; [.1C79.0020.0019.FE88] # ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM +FE87 ; [.1C79.0020.001A.FE87] # ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM +0673 ; [.1C7A.0020.0002.0673] # ARABIC LETTER ALEF WITH WAVY HAMZA BELOW +0773 ; [.1C7B.0020.0002.0773] # ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE +0774 ; [.1C7C.0020.0002.0774] # ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE +0626 ; [.1C7D.0020.0002.0626] # ARABIC LETTER YEH WITH HAMZA ABOVE +064A 0654 ; [.1C7D.0020.0002.0626] # ARABIC LETTER YEH WITH HAMZA ABOVE +FE8B ; [.1C7D.0020.0017.FE8B] # ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM +FE8C ; [.1C7D.0020.0018.FE8C] # ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM +FE8A ; [.1C7D.0020.0019.FE8A] # ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM +FE89 ; [.1C7D.0020.001A.FE89] # ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM +FBEB ; [.1C7D.0020.0019.FBEB][.1C81.0020.0019.FBEB] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM +FBEA ; [.1C7D.0020.001A.FBEA][.1C81.0020.001A.FBEA] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM +FC97 ; [.1C7D.0020.0017.FC97][.1C97.0020.0017.FC97] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM +FC00 ; [.1C7D.0020.001A.FC00][.1C97.0020.001A.FC00] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM +FC98 ; [.1C7D.0020.0017.FC98][.1C9E.0020.0017.FC98] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM +FC01 ; [.1C7D.0020.001A.FC01][.1C9E.0020.001A.FC01] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM +FC99 ; [.1C7D.0020.0017.FC99][.1C9F.0020.0017.FC99] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM +FC64 ; [.1C7D.0020.0019.FC64][.1CB7.0020.0019.FC64] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM +FC65 ; [.1C7D.0020.0019.FC65][.1CB8.0020.0019.FC65] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM +FC9A ; [.1C7D.0020.0017.FC9A][.1D0C.0020.0017.FC9A] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM +FCDF ; [.1C7D.0020.0018.FCDF][.1D0C.0020.0018.FCDF] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM +FC66 ; [.1C7D.0020.0019.FC66][.1D0C.0020.0019.FC66] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM +FC02 ; [.1C7D.0020.001A.FC02][.1D0C.0020.001A.FC02] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM +FC67 ; [.1C7D.0020.0019.FC67][.1D10.0020.0019.FC67] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM +FC9B ; [.1C7D.0020.0017.FC9B][.1D19.0020.0017.FC9B] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM +FCE0 ; [.1C7D.0020.0018.FCE0][.1D19.0020.0018.FCE0] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM +FBED ; [.1C7D.0020.0019.FBED][.1D1E.0020.0019.FBED] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM +FBEC ; [.1C7D.0020.001A.FBEC][.1D1E.0020.001A.FBEC] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM +FBEF ; [.1C7D.0020.0019.FBEF][.1D1F.0020.0019.FBEF] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM +FBEE ; [.1C7D.0020.001A.FBEE][.1D1F.0020.001A.FBEE] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM +FBF3 ; [.1C7D.0020.0019.FBF3][.1D22.0020.0019.FBF3] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM +FBF2 ; [.1C7D.0020.001A.FBF2][.1D22.0020.001A.FBF2] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM +FBF1 ; [.1C7D.0020.0019.FBF1][.1D23.0020.0019.FBF1] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM +FBF0 ; [.1C7D.0020.001A.FBF0][.1D23.0020.001A.FBF0] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM +FBF5 ; [.1C7D.0020.0019.FBF5][.1D24.0020.0019.FBF5] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM +FBF4 ; [.1C7D.0020.001A.FBF4][.1D24.0020.001A.FBF4] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM +FBFB ; [.1C7D.0020.0017.FBFB][.1D2C.0020.0017.FBFB] # ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM +FBFA ; [.1C7D.0020.0019.FBFA][.1D2C.0020.0019.FBFA] # ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM +FC68 ; [.1C7D.0020.0019.FC68][.1D2C.0020.0019.FC68] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM +FBF9 ; [.1C7D.0020.001A.FBF9][.1D2C.0020.001A.FBF9] # ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM +FC03 ; [.1C7D.0020.001A.FC03][.1D2C.0020.001A.FC03] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM +FC69 ; [.1C7D.0020.0019.FC69][.1D2D.0020.0019.FC69] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM +FC04 ; [.1C7D.0020.001A.FC04][.1D2D.0020.001A.FC04] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM +FBF8 ; [.1C7D.0020.0017.FBF8][.1D31.0020.0017.FBF8] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM +FBF7 ; [.1C7D.0020.0019.FBF7][.1D31.0020.0019.FBF7] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM +FBF6 ; [.1C7D.0020.001A.FBF6][.1D31.0020.001A.FBF6] # ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM +08A8 ; [.1C7E.0020.0002.08A8] # ARABIC LETTER YEH WITH TWO DOTS BELOW AND HAMZA ABOVE +08A9 ; [.1C7F.0020.0002.08A9] # ARABIC LETTER YEH WITH TWO DOTS BELOW AND DOT ABOVE +08AC ; [.1C80.0020.0002.08AC] # ARABIC LETTER ROHINGYA YEH +0627 ; [.1C81.0020.0002.0627] # ARABIC LETTER ALEF +1EE00 ; [.1C81.0020.0005.1EE00] # ARABIC MATHEMATICAL ALEF +1EE80 ; [.1C81.0020.0005.1EE80] # ARABIC MATHEMATICAL LOOPED ALEF +FE8E ; [.1C81.0020.0019.FE8E] # ARABIC LETTER ALEF FINAL FORM +FE8D ; [.1C81.0020.001A.FE8D] # ARABIC LETTER ALEF ISOLATED FORM +FD3C ; [.1C81.0020.0019.FD3C][.0000.00A2.0019.FD3C] # ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM +FD3D ; [.1C81.0020.001A.FD3D][.0000.00A2.001A.FD3D] # ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM +0675 ; [.1C81.0020.0004.0675][.1C73.0020.0004.0675] # ARABIC LETTER HIGH HAMZA ALEF +FDF3 ; [.1C81.0020.001A.FDF3][.1CF2.0020.001A.FDF3][.1C83.0020.001F.FDF3][.1CB7.0020.001F.FDF3] # ARABIC LIGATURE AKBAR ISOLATED FORM +FDF2 ; [.1C81.0020.001A.FDF2][.1D05.0020.001A.FDF2][.1D05.0020.001F.FDF2][.1D19.0020.001F.FDF2] # ARABIC LIGATURE ALLAH ISOLATED FORM +066E ; [.1C82.0020.0002.066E] # ARABIC LETTER DOTLESS BEH +1EE1C ; [.1C82.0020.0005.1EE1C] # ARABIC MATHEMATICAL DOTLESS BEH +1EE7C ; [.1C82.0020.0005.1EE7C] # ARABIC MATHEMATICAL STRETCHED DOTLESS BEH +0628 ; [.1C83.0020.0002.0628] # ARABIC LETTER BEH +1EE01 ; [.1C83.0020.0005.1EE01] # ARABIC MATHEMATICAL BEH +1EE21 ; [.1C83.0020.0005.1EE21] # ARABIC MATHEMATICAL INITIAL BEH +1EE61 ; [.1C83.0020.0005.1EE61] # ARABIC MATHEMATICAL STRETCHED BEH +1EE81 ; [.1C83.0020.0005.1EE81] # ARABIC MATHEMATICAL LOOPED BEH +1EEA1 ; [.1C83.0020.0005.1EEA1] # ARABIC MATHEMATICAL DOUBLE-STRUCK BEH +FE91 ; [.1C83.0020.0017.FE91] # ARABIC LETTER BEH INITIAL FORM +FE92 ; [.1C83.0020.0018.FE92] # ARABIC LETTER BEH MEDIAL FORM +FE90 ; [.1C83.0020.0019.FE90] # ARABIC LETTER BEH FINAL FORM +FE8F ; [.1C83.0020.001A.FE8F] # ARABIC LETTER BEH ISOLATED FORM +FC9C ; [.1C83.0020.0017.FC9C][.1C97.0020.0017.FC9C] # ARABIC LIGATURE BEH WITH JEEM INITIAL FORM +FC05 ; [.1C83.0020.001A.FC05][.1C97.0020.001A.FC05] # ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM +FC9D ; [.1C83.0020.0017.FC9D][.1C9E.0020.0017.FC9D] # ARABIC LIGATURE BEH WITH HAH INITIAL FORM +FC06 ; [.1C83.0020.001A.FC06][.1C9E.0020.001A.FC06] # ARABIC LIGATURE BEH WITH HAH ISOLATED FORM +FDC2 ; [.1C83.0020.0019.FDC2][.1C9E.0020.0019.FDC2][.1D2D.0020.001F.FDC2] # ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM +FC9E ; [.1C83.0020.0017.FC9E][.1C9F.0020.0017.FC9E] # ARABIC LIGATURE BEH WITH KHAH INITIAL FORM +FC07 ; [.1C83.0020.001A.FC07][.1C9F.0020.001A.FC07] # ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM +FD9E ; [.1C83.0020.0019.FD9E][.1C9F.0020.0019.FD9E][.1D2D.0020.001F.FD9E] # ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM +FC6A ; [.1C83.0020.0019.FC6A][.1CB7.0020.0019.FC6A] # ARABIC LIGATURE BEH WITH REH FINAL FORM +FC6B ; [.1C83.0020.0019.FC6B][.1CB8.0020.0019.FC6B] # ARABIC LIGATURE BEH WITH ZAIN FINAL FORM +FC9F ; [.1C83.0020.0017.FC9F][.1D0C.0020.0017.FC9F] # ARABIC LIGATURE BEH WITH MEEM INITIAL FORM +FCE1 ; [.1C83.0020.0018.FCE1][.1D0C.0020.0018.FCE1] # ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM +FC6C ; [.1C83.0020.0019.FC6C][.1D0C.0020.0019.FC6C] # ARABIC LIGATURE BEH WITH MEEM FINAL FORM +FC08 ; [.1C83.0020.001A.FC08][.1D0C.0020.001A.FC08] # ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM +FC6D ; [.1C83.0020.0019.FC6D][.1D10.0020.0019.FC6D] # ARABIC LIGATURE BEH WITH NOON FINAL FORM +FCA0 ; [.1C83.0020.0017.FCA0][.1D19.0020.0017.FCA0] # ARABIC LIGATURE BEH WITH HEH INITIAL FORM +FCE2 ; [.1C83.0020.0018.FCE2][.1D19.0020.0018.FCE2] # ARABIC LIGATURE BEH WITH HEH MEDIAL FORM +FC6E ; [.1C83.0020.0019.FC6E][.1D2C.0020.0019.FC6E] # ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM +FC09 ; [.1C83.0020.001A.FC09][.1D2C.0020.001A.FC09] # ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM +FC6F ; [.1C83.0020.0019.FC6F][.1D2D.0020.0019.FC6F] # ARABIC LIGATURE BEH WITH YEH FINAL FORM +FC0A ; [.1C83.0020.001A.FC0A][.1D2D.0020.001A.FC0A] # ARABIC LIGATURE BEH WITH YEH ISOLATED FORM +067B ; [.1C84.0020.0002.067B] # ARABIC LETTER BEEH +FB54 ; [.1C84.0020.0017.FB54] # ARABIC LETTER BEEH INITIAL FORM +FB55 ; [.1C84.0020.0018.FB55] # ARABIC LETTER BEEH MEDIAL FORM +FB53 ; [.1C84.0020.0019.FB53] # ARABIC LETTER BEEH FINAL FORM +FB52 ; [.1C84.0020.001A.FB52] # ARABIC LETTER BEEH ISOLATED FORM +067E ; [.1C85.0020.0002.067E] # ARABIC LETTER PEH +FB58 ; [.1C85.0020.0017.FB58] # ARABIC LETTER PEH INITIAL FORM +FB59 ; [.1C85.0020.0018.FB59] # ARABIC LETTER PEH MEDIAL FORM +FB57 ; [.1C85.0020.0019.FB57] # ARABIC LETTER PEH FINAL FORM +FB56 ; [.1C85.0020.001A.FB56] # ARABIC LETTER PEH ISOLATED FORM +0680 ; [.1C86.0020.0002.0680] # ARABIC LETTER BEHEH +FB5C ; [.1C86.0020.0017.FB5C] # ARABIC LETTER BEHEH INITIAL FORM +FB5D ; [.1C86.0020.0018.FB5D] # ARABIC LETTER BEHEH MEDIAL FORM +FB5B ; [.1C86.0020.0019.FB5B] # ARABIC LETTER BEHEH FINAL FORM +FB5A ; [.1C86.0020.001A.FB5A] # ARABIC LETTER BEHEH ISOLATED FORM +0750 ; [.1C87.0020.0002.0750] # ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW +0751 ; [.1C88.0020.0002.0751] # ARABIC LETTER BEH WITH DOT BELOW AND THREE DOTS ABOVE +0752 ; [.1C89.0020.0002.0752] # ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW +0753 ; [.1C8A.0020.0002.0753] # ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW AND TWO DOTS ABOVE +0754 ; [.1C8B.0020.0002.0754] # ARABIC LETTER BEH WITH TWO DOTS BELOW AND DOT ABOVE +0755 ; [.1C8C.0020.0002.0755] # ARABIC LETTER BEH WITH INVERTED SMALL V BELOW +08A0 ; [.1C8D.0020.0002.08A0] # ARABIC LETTER BEH WITH SMALL V BELOW +0756 ; [.1C8E.0020.0002.0756] # ARABIC LETTER BEH WITH SMALL V +0629 ; [.1C8F.0020.0002.0629] # ARABIC LETTER TEH MARBUTA +FE94 ; [.1C8F.0020.0019.FE94] # ARABIC LETTER TEH MARBUTA FINAL FORM +FE93 ; [.1C8F.0020.001A.FE93] # ARABIC LETTER TEH MARBUTA ISOLATED FORM +062A ; [.1C90.0020.0002.062A] # ARABIC LETTER TEH +1EE15 ; [.1C90.0020.0005.1EE15] # ARABIC MATHEMATICAL TEH +1EE35 ; [.1C90.0020.0005.1EE35] # ARABIC MATHEMATICAL INITIAL TEH +1EE75 ; [.1C90.0020.0005.1EE75] # ARABIC MATHEMATICAL STRETCHED TEH +1EE95 ; [.1C90.0020.0005.1EE95] # ARABIC MATHEMATICAL LOOPED TEH +1EEB5 ; [.1C90.0020.0005.1EEB5] # ARABIC MATHEMATICAL DOUBLE-STRUCK TEH +FE97 ; [.1C90.0020.0017.FE97] # ARABIC LETTER TEH INITIAL FORM +FE98 ; [.1C90.0020.0018.FE98] # ARABIC LETTER TEH MEDIAL FORM +FE96 ; [.1C90.0020.0019.FE96] # ARABIC LETTER TEH FINAL FORM +FE95 ; [.1C90.0020.001A.FE95] # ARABIC LETTER TEH ISOLATED FORM +FCA1 ; [.1C90.0020.0017.FCA1][.1C97.0020.0017.FCA1] # ARABIC LIGATURE TEH WITH JEEM INITIAL FORM +FC0B ; [.1C90.0020.001A.FC0B][.1C97.0020.001A.FC0B] # ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM +FD50 ; [.1C90.0020.0017.FD50][.1C97.0020.0017.FD50][.1D0C.0020.001F.FD50] # ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM +FDA0 ; [.1C90.0020.0019.FDA0][.1C97.0020.0019.FDA0][.1D2C.0020.001F.FDA0] # ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM +FD9F ; [.1C90.0020.0019.FD9F][.1C97.0020.0019.FD9F][.1D2D.0020.001F.FD9F] # ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM +FCA2 ; [.1C90.0020.0017.FCA2][.1C9E.0020.0017.FCA2] # ARABIC LIGATURE TEH WITH HAH INITIAL FORM +FC0C ; [.1C90.0020.001A.FC0C][.1C9E.0020.001A.FC0C] # ARABIC LIGATURE TEH WITH HAH ISOLATED FORM +FD52 ; [.1C90.0020.0017.FD52][.1C9E.0020.0017.FD52][.1C97.0020.001F.FD52] # ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM +FD51 ; [.1C90.0020.0019.FD51][.1C9E.0020.0019.FD51][.1C97.0020.001F.FD51] # ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM +FD53 ; [.1C90.0020.0017.FD53][.1C9E.0020.0017.FD53][.1D0C.0020.001F.FD53] # ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM +FCA3 ; [.1C90.0020.0017.FCA3][.1C9F.0020.0017.FCA3] # ARABIC LIGATURE TEH WITH KHAH INITIAL FORM +FC0D ; [.1C90.0020.001A.FC0D][.1C9F.0020.001A.FC0D] # ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM +FD54 ; [.1C90.0020.0017.FD54][.1C9F.0020.0017.FD54][.1D0C.0020.001F.FD54] # ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM +FDA2 ; [.1C90.0020.0019.FDA2][.1C9F.0020.0019.FDA2][.1D2C.0020.001F.FDA2] # ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM +FDA1 ; [.1C90.0020.0019.FDA1][.1C9F.0020.0019.FDA1][.1D2D.0020.001F.FDA1] # ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM +FC70 ; [.1C90.0020.0019.FC70][.1CB7.0020.0019.FC70] # ARABIC LIGATURE TEH WITH REH FINAL FORM +FC71 ; [.1C90.0020.0019.FC71][.1CB8.0020.0019.FC71] # ARABIC LIGATURE TEH WITH ZAIN FINAL FORM +FCA4 ; [.1C90.0020.0017.FCA4][.1D0C.0020.0017.FCA4] # ARABIC LIGATURE TEH WITH MEEM INITIAL FORM +FCE3 ; [.1C90.0020.0018.FCE3][.1D0C.0020.0018.FCE3] # ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM +FC72 ; [.1C90.0020.0019.FC72][.1D0C.0020.0019.FC72] # ARABIC LIGATURE TEH WITH MEEM FINAL FORM +FC0E ; [.1C90.0020.001A.FC0E][.1D0C.0020.001A.FC0E] # ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM +FD55 ; [.1C90.0020.0017.FD55][.1D0C.0020.0017.FD55][.1C97.0020.001F.FD55] # ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM +FD56 ; [.1C90.0020.0017.FD56][.1D0C.0020.0017.FD56][.1C9E.0020.001F.FD56] # ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM +FD57 ; [.1C90.0020.0017.FD57][.1D0C.0020.0017.FD57][.1C9F.0020.001F.FD57] # ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM +FDA4 ; [.1C90.0020.0019.FDA4][.1D0C.0020.0019.FDA4][.1D2C.0020.001F.FDA4] # ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM +FDA3 ; [.1C90.0020.0019.FDA3][.1D0C.0020.0019.FDA3][.1D2D.0020.001F.FDA3] # ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM +FC73 ; [.1C90.0020.0019.FC73][.1D10.0020.0019.FC73] # ARABIC LIGATURE TEH WITH NOON FINAL FORM +FCA5 ; [.1C90.0020.0017.FCA5][.1D19.0020.0017.FCA5] # ARABIC LIGATURE TEH WITH HEH INITIAL FORM +FCE4 ; [.1C90.0020.0018.FCE4][.1D19.0020.0018.FCE4] # ARABIC LIGATURE TEH WITH HEH MEDIAL FORM +FC74 ; [.1C90.0020.0019.FC74][.1D2C.0020.0019.FC74] # ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM +FC0F ; [.1C90.0020.001A.FC0F][.1D2C.0020.001A.FC0F] # ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM +FC75 ; [.1C90.0020.0019.FC75][.1D2D.0020.0019.FC75] # ARABIC LIGATURE TEH WITH YEH FINAL FORM +FC10 ; [.1C90.0020.001A.FC10][.1D2D.0020.001A.FC10] # ARABIC LIGATURE TEH WITH YEH ISOLATED FORM +062B ; [.1C91.0020.0002.062B] # ARABIC LETTER THEH +1EE16 ; [.1C91.0020.0005.1EE16] # ARABIC MATHEMATICAL THEH +1EE36 ; [.1C91.0020.0005.1EE36] # ARABIC MATHEMATICAL INITIAL THEH +1EE76 ; [.1C91.0020.0005.1EE76] # ARABIC MATHEMATICAL STRETCHED THEH +1EE96 ; [.1C91.0020.0005.1EE96] # ARABIC MATHEMATICAL LOOPED THEH +1EEB6 ; [.1C91.0020.0005.1EEB6] # ARABIC MATHEMATICAL DOUBLE-STRUCK THEH +FE9B ; [.1C91.0020.0017.FE9B] # ARABIC LETTER THEH INITIAL FORM +FE9C ; [.1C91.0020.0018.FE9C] # ARABIC LETTER THEH MEDIAL FORM +FE9A ; [.1C91.0020.0019.FE9A] # ARABIC LETTER THEH FINAL FORM +FE99 ; [.1C91.0020.001A.FE99] # ARABIC LETTER THEH ISOLATED FORM +FC11 ; [.1C91.0020.001A.FC11][.1C97.0020.001A.FC11] # ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM +FC76 ; [.1C91.0020.0019.FC76][.1CB7.0020.0019.FC76] # ARABIC LIGATURE THEH WITH REH FINAL FORM +FC77 ; [.1C91.0020.0019.FC77][.1CB8.0020.0019.FC77] # ARABIC LIGATURE THEH WITH ZAIN FINAL FORM +FCA6 ; [.1C91.0020.0017.FCA6][.1D0C.0020.0017.FCA6] # ARABIC LIGATURE THEH WITH MEEM INITIAL FORM +FCE5 ; [.1C91.0020.0018.FCE5][.1D0C.0020.0018.FCE5] # ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM +FC78 ; [.1C91.0020.0019.FC78][.1D0C.0020.0019.FC78] # ARABIC LIGATURE THEH WITH MEEM FINAL FORM +FC12 ; [.1C91.0020.001A.FC12][.1D0C.0020.001A.FC12] # ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM +FC79 ; [.1C91.0020.0019.FC79][.1D10.0020.0019.FC79] # ARABIC LIGATURE THEH WITH NOON FINAL FORM +FCE6 ; [.1C91.0020.0018.FCE6][.1D19.0020.0018.FCE6] # ARABIC LIGATURE THEH WITH HEH MEDIAL FORM +FC7A ; [.1C91.0020.0019.FC7A][.1D2C.0020.0019.FC7A] # ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM +FC13 ; [.1C91.0020.001A.FC13][.1D2C.0020.001A.FC13] # ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM +FC7B ; [.1C91.0020.0019.FC7B][.1D2D.0020.0019.FC7B] # ARABIC LIGATURE THEH WITH YEH FINAL FORM +FC14 ; [.1C91.0020.001A.FC14][.1D2D.0020.001A.FC14] # ARABIC LIGATURE THEH WITH YEH ISOLATED FORM +0679 ; [.1C92.0020.0002.0679] # ARABIC LETTER TTEH +FB68 ; [.1C92.0020.0017.FB68] # ARABIC LETTER TTEH INITIAL FORM +FB69 ; [.1C92.0020.0018.FB69] # ARABIC LETTER TTEH MEDIAL FORM +FB67 ; [.1C92.0020.0019.FB67] # ARABIC LETTER TTEH FINAL FORM +FB66 ; [.1C92.0020.001A.FB66] # ARABIC LETTER TTEH ISOLATED FORM +067A ; [.1C93.0020.0002.067A] # ARABIC LETTER TTEHEH +FB60 ; [.1C93.0020.0017.FB60] # ARABIC LETTER TTEHEH INITIAL FORM +FB61 ; [.1C93.0020.0018.FB61] # ARABIC LETTER TTEHEH MEDIAL FORM +FB5F ; [.1C93.0020.0019.FB5F] # ARABIC LETTER TTEHEH FINAL FORM +FB5E ; [.1C93.0020.001A.FB5E] # ARABIC LETTER TTEHEH ISOLATED FORM +067C ; [.1C94.0020.0002.067C] # ARABIC LETTER TEH WITH RING +067D ; [.1C95.0020.0002.067D] # ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS +067F ; [.1C96.0020.0002.067F] # ARABIC LETTER TEHEH +FB64 ; [.1C96.0020.0017.FB64] # ARABIC LETTER TEHEH INITIAL FORM +FB65 ; [.1C96.0020.0018.FB65] # ARABIC LETTER TEHEH MEDIAL FORM +FB63 ; [.1C96.0020.0019.FB63] # ARABIC LETTER TEHEH FINAL FORM +FB62 ; [.1C96.0020.001A.FB62] # ARABIC LETTER TEHEH ISOLATED FORM +062C ; [.1C97.0020.0002.062C] # ARABIC LETTER JEEM +1EE02 ; [.1C97.0020.0005.1EE02] # ARABIC MATHEMATICAL JEEM +1EE22 ; [.1C97.0020.0005.1EE22] # ARABIC MATHEMATICAL INITIAL JEEM +1EE42 ; [.1C97.0020.0005.1EE42] # ARABIC MATHEMATICAL TAILED JEEM +1EE62 ; [.1C97.0020.0005.1EE62] # ARABIC MATHEMATICAL STRETCHED JEEM +1EE82 ; [.1C97.0020.0005.1EE82] # ARABIC MATHEMATICAL LOOPED JEEM +1EEA2 ; [.1C97.0020.0005.1EEA2] # ARABIC MATHEMATICAL DOUBLE-STRUCK JEEM +FE9F ; [.1C97.0020.0017.FE9F] # ARABIC LETTER JEEM INITIAL FORM +FEA0 ; [.1C97.0020.0018.FEA0] # ARABIC LETTER JEEM MEDIAL FORM +FE9E ; [.1C97.0020.0019.FE9E] # ARABIC LETTER JEEM FINAL FORM +FE9D ; [.1C97.0020.001A.FE9D] # ARABIC LETTER JEEM ISOLATED FORM +FCA7 ; [.1C97.0020.0017.FCA7][.1C9E.0020.0017.FCA7] # ARABIC LIGATURE JEEM WITH HAH INITIAL FORM +FC15 ; [.1C97.0020.001A.FC15][.1C9E.0020.001A.FC15] # ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM +FDA6 ; [.1C97.0020.0019.FDA6][.1C9E.0020.0019.FDA6][.1D2C.0020.001F.FDA6] # ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM +FDBE ; [.1C97.0020.0019.FDBE][.1C9E.0020.0019.FDBE][.1D2D.0020.001F.FDBE] # ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM +FDFB ; [.1C97.0020.001A.FDFB][.1D05.0020.001A.FDFB][*020A.0020.001F.FDFB][.1C97.0020.001F.FDFB][.1D05.0020.001F.FDFB][.1C81.0020.001F.FDFB][.1D05.0020.001F.FDFB][.1D19.0020.001F.FDFB] # ARABIC LIGATURE JALLAJALALOUHOU +FCA8 ; [.1C97.0020.0017.FCA8][.1D0C.0020.0017.FCA8] # ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM +FC16 ; [.1C97.0020.001A.FC16][.1D0C.0020.001A.FC16] # ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM +FD59 ; [.1C97.0020.0017.FD59][.1D0C.0020.0017.FD59][.1C9E.0020.001F.FD59] # ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM +FD58 ; [.1C97.0020.0019.FD58][.1D0C.0020.0019.FD58][.1C9E.0020.001F.FD58] # ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM +FDA7 ; [.1C97.0020.0019.FDA7][.1D0C.0020.0019.FDA7][.1D2C.0020.001F.FDA7] # ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM +FDA5 ; [.1C97.0020.0019.FDA5][.1D0C.0020.0019.FDA5][.1D2D.0020.001F.FDA5] # ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM +FD1D ; [.1C97.0020.0019.FD1D][.1D2C.0020.0019.FD1D] # ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM +FD01 ; [.1C97.0020.001A.FD01][.1D2C.0020.001A.FD01] # ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM +FD1E ; [.1C97.0020.0019.FD1E][.1D2D.0020.0019.FD1E] # ARABIC LIGATURE JEEM WITH YEH FINAL FORM +FD02 ; [.1C97.0020.001A.FD02][.1D2D.0020.001A.FD02] # ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM +0683 ; [.1C98.0020.0002.0683] # ARABIC LETTER NYEH +FB78 ; [.1C98.0020.0017.FB78] # ARABIC LETTER NYEH INITIAL FORM +FB79 ; [.1C98.0020.0018.FB79] # ARABIC LETTER NYEH MEDIAL FORM +FB77 ; [.1C98.0020.0019.FB77] # ARABIC LETTER NYEH FINAL FORM +FB76 ; [.1C98.0020.001A.FB76] # ARABIC LETTER NYEH ISOLATED FORM +0684 ; [.1C99.0020.0002.0684] # ARABIC LETTER DYEH +FB74 ; [.1C99.0020.0017.FB74] # ARABIC LETTER DYEH INITIAL FORM +FB75 ; [.1C99.0020.0018.FB75] # ARABIC LETTER DYEH MEDIAL FORM +FB73 ; [.1C99.0020.0019.FB73] # ARABIC LETTER DYEH FINAL FORM +FB72 ; [.1C99.0020.001A.FB72] # ARABIC LETTER DYEH ISOLATED FORM +0686 ; [.1C9A.0020.0002.0686] # ARABIC LETTER TCHEH +FB7C ; [.1C9A.0020.0017.FB7C] # ARABIC LETTER TCHEH INITIAL FORM +FB7D ; [.1C9A.0020.0018.FB7D] # ARABIC LETTER TCHEH MEDIAL FORM +FB7B ; [.1C9A.0020.0019.FB7B] # ARABIC LETTER TCHEH FINAL FORM +FB7A ; [.1C9A.0020.001A.FB7A] # ARABIC LETTER TCHEH ISOLATED FORM +06BF ; [.1C9B.0020.0002.06BF] # ARABIC LETTER TCHEH WITH DOT ABOVE +0687 ; [.1C9C.0020.0002.0687] # ARABIC LETTER TCHEHEH +FB80 ; [.1C9C.0020.0017.FB80] # ARABIC LETTER TCHEHEH INITIAL FORM +FB81 ; [.1C9C.0020.0018.FB81] # ARABIC LETTER TCHEHEH MEDIAL FORM +FB7F ; [.1C9C.0020.0019.FB7F] # ARABIC LETTER TCHEHEH FINAL FORM +FB7E ; [.1C9C.0020.001A.FB7E] # ARABIC LETTER TCHEHEH ISOLATED FORM +08A2 ; [.1C9D.0020.0002.08A2] # ARABIC LETTER JEEM WITH TWO DOTS ABOVE +062D ; [.1C9E.0020.0002.062D] # ARABIC LETTER HAH +1EE07 ; [.1C9E.0020.0005.1EE07] # ARABIC MATHEMATICAL HAH +1EE27 ; [.1C9E.0020.0005.1EE27] # ARABIC MATHEMATICAL INITIAL HAH +1EE47 ; [.1C9E.0020.0005.1EE47] # ARABIC MATHEMATICAL TAILED HAH +1EE67 ; [.1C9E.0020.0005.1EE67] # ARABIC MATHEMATICAL STRETCHED HAH +1EE87 ; [.1C9E.0020.0005.1EE87] # ARABIC MATHEMATICAL LOOPED HAH +1EEA7 ; [.1C9E.0020.0005.1EEA7] # ARABIC MATHEMATICAL DOUBLE-STRUCK HAH +FEA3 ; [.1C9E.0020.0017.FEA3] # ARABIC LETTER HAH INITIAL FORM +FEA4 ; [.1C9E.0020.0018.FEA4] # ARABIC LETTER HAH MEDIAL FORM +FEA2 ; [.1C9E.0020.0019.FEA2] # ARABIC LETTER HAH FINAL FORM +FEA1 ; [.1C9E.0020.001A.FEA1] # ARABIC LETTER HAH ISOLATED FORM +FCA9 ; [.1C9E.0020.0017.FCA9][.1C97.0020.0017.FCA9] # ARABIC LIGATURE HAH WITH JEEM INITIAL FORM +FC17 ; [.1C9E.0020.001A.FC17][.1C97.0020.001A.FC17] # ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM +FDBF ; [.1C9E.0020.0019.FDBF][.1C97.0020.0019.FDBF][.1D2D.0020.001F.FDBF] # ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM +FCAA ; [.1C9E.0020.0017.FCAA][.1D0C.0020.0017.FCAA] # ARABIC LIGATURE HAH WITH MEEM INITIAL FORM +FC18 ; [.1C9E.0020.001A.FC18][.1D0C.0020.001A.FC18] # ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM +FD5B ; [.1C9E.0020.0019.FD5B][.1D0C.0020.0019.FD5B][.1D2C.0020.001F.FD5B] # ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM +FD5A ; [.1C9E.0020.0019.FD5A][.1D0C.0020.0019.FD5A][.1D2D.0020.001F.FD5A] # ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM +FD1B ; [.1C9E.0020.0019.FD1B][.1D2C.0020.0019.FD1B] # ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM +FCFF ; [.1C9E.0020.001A.FCFF][.1D2C.0020.001A.FCFF] # ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM +FD1C ; [.1C9E.0020.0019.FD1C][.1D2D.0020.0019.FD1C] # ARABIC LIGATURE HAH WITH YEH FINAL FORM +FD00 ; [.1C9E.0020.001A.FD00][.1D2D.0020.001A.FD00] # ARABIC LIGATURE HAH WITH YEH ISOLATED FORM +062E ; [.1C9F.0020.0002.062E] # ARABIC LETTER KHAH +1EE17 ; [.1C9F.0020.0005.1EE17] # ARABIC MATHEMATICAL KHAH +1EE37 ; [.1C9F.0020.0005.1EE37] # ARABIC MATHEMATICAL INITIAL KHAH +1EE57 ; [.1C9F.0020.0005.1EE57] # ARABIC MATHEMATICAL TAILED KHAH +1EE77 ; [.1C9F.0020.0005.1EE77] # ARABIC MATHEMATICAL STRETCHED KHAH +1EE97 ; [.1C9F.0020.0005.1EE97] # ARABIC MATHEMATICAL LOOPED KHAH +1EEB7 ; [.1C9F.0020.0005.1EEB7] # ARABIC MATHEMATICAL DOUBLE-STRUCK KHAH +FEA7 ; [.1C9F.0020.0017.FEA7] # ARABIC LETTER KHAH INITIAL FORM +FEA8 ; [.1C9F.0020.0018.FEA8] # ARABIC LETTER KHAH MEDIAL FORM +FEA6 ; [.1C9F.0020.0019.FEA6] # ARABIC LETTER KHAH FINAL FORM +FEA5 ; [.1C9F.0020.001A.FEA5] # ARABIC LETTER KHAH ISOLATED FORM +FCAB ; [.1C9F.0020.0017.FCAB][.1C97.0020.0017.FCAB] # ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM +FC19 ; [.1C9F.0020.001A.FC19][.1C97.0020.001A.FC19] # ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM +FC1A ; [.1C9F.0020.001A.FC1A][.1C9E.0020.001A.FC1A] # ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM +FCAC ; [.1C9F.0020.0017.FCAC][.1D0C.0020.0017.FCAC] # ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM +FC1B ; [.1C9F.0020.001A.FC1B][.1D0C.0020.001A.FC1B] # ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM +FD1F ; [.1C9F.0020.0019.FD1F][.1D2C.0020.0019.FD1F] # ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM +FD03 ; [.1C9F.0020.001A.FD03][.1D2C.0020.001A.FD03] # ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM +FD20 ; [.1C9F.0020.0019.FD20][.1D2D.0020.0019.FD20] # ARABIC LIGATURE KHAH WITH YEH FINAL FORM +FD04 ; [.1C9F.0020.001A.FD04][.1D2D.0020.001A.FD04] # ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM +0681 ; [.1CA0.0020.0002.0681] # ARABIC LETTER HAH WITH HAMZA ABOVE +0682 ; [.1CA1.0020.0002.0682] # ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE +0685 ; [.1CA2.0020.0002.0685] # ARABIC LETTER HAH WITH THREE DOTS ABOVE +0757 ; [.1CA3.0020.0002.0757] # ARABIC LETTER HAH WITH TWO DOTS ABOVE +0758 ; [.1CA4.0020.0002.0758] # ARABIC LETTER HAH WITH THREE DOTS POINTING UPWARDS BELOW +076E ; [.1CA5.0020.0002.076E] # ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH BELOW +076F ; [.1CA6.0020.0002.076F] # ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH AND TWO DOTS +0772 ; [.1CA7.0020.0002.0772] # ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH ABOVE +077C ; [.1CA8.0020.0002.077C] # ARABIC LETTER HAH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW +062F ; [.1CA9.0020.0002.062F] # ARABIC LETTER DAL +1EE03 ; [.1CA9.0020.0005.1EE03] # ARABIC MATHEMATICAL DAL +1EE83 ; [.1CA9.0020.0005.1EE83] # ARABIC MATHEMATICAL LOOPED DAL +1EEA3 ; [.1CA9.0020.0005.1EEA3] # ARABIC MATHEMATICAL DOUBLE-STRUCK DAL +FEAA ; [.1CA9.0020.0019.FEAA] # ARABIC LETTER DAL FINAL FORM +FEA9 ; [.1CA9.0020.001A.FEA9] # ARABIC LETTER DAL ISOLATED FORM +0630 ; [.1CAA.0020.0002.0630] # ARABIC LETTER THAL +1EE18 ; [.1CAA.0020.0005.1EE18] # ARABIC MATHEMATICAL THAL +1EE98 ; [.1CAA.0020.0005.1EE98] # ARABIC MATHEMATICAL LOOPED THAL +1EEB8 ; [.1CAA.0020.0005.1EEB8] # ARABIC MATHEMATICAL DOUBLE-STRUCK THAL +FEAC ; [.1CAA.0020.0019.FEAC] # ARABIC LETTER THAL FINAL FORM +FEAB ; [.1CAA.0020.001A.FEAB] # ARABIC LETTER THAL ISOLATED FORM +FC5B ; [.1CAA.0020.001A.FC5B][.0000.00D1.001A.FC5B] # ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM +0688 ; [.1CAB.0020.0002.0688] # ARABIC LETTER DDAL +FB89 ; [.1CAB.0020.0019.FB89] # ARABIC LETTER DDAL FINAL FORM +FB88 ; [.1CAB.0020.001A.FB88] # ARABIC LETTER DDAL ISOLATED FORM +0689 ; [.1CAC.0020.0002.0689] # ARABIC LETTER DAL WITH RING +068A ; [.1CAD.0020.0002.068A] # ARABIC LETTER DAL WITH DOT BELOW +068B ; [.1CAE.0020.0002.068B] # ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH +068C ; [.1CAF.0020.0002.068C] # ARABIC LETTER DAHAL +FB85 ; [.1CAF.0020.0019.FB85] # ARABIC LETTER DAHAL FINAL FORM +FB84 ; [.1CAF.0020.001A.FB84] # ARABIC LETTER DAHAL ISOLATED FORM +068D ; [.1CB0.0020.0002.068D] # ARABIC LETTER DDAHAL +FB83 ; [.1CB0.0020.0019.FB83] # ARABIC LETTER DDAHAL FINAL FORM +FB82 ; [.1CB0.0020.001A.FB82] # ARABIC LETTER DDAHAL ISOLATED FORM +068E ; [.1CB1.0020.0002.068E] # ARABIC LETTER DUL +FB87 ; [.1CB1.0020.0019.FB87] # ARABIC LETTER DUL FINAL FORM +FB86 ; [.1CB1.0020.001A.FB86] # ARABIC LETTER DUL ISOLATED FORM +068F ; [.1CB2.0020.0002.068F] # ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS +0690 ; [.1CB3.0020.0002.0690] # ARABIC LETTER DAL WITH FOUR DOTS ABOVE +06EE ; [.1CB4.0020.0002.06EE] # ARABIC LETTER DAL WITH INVERTED V +0759 ; [.1CB5.0020.0002.0759] # ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW AND SMALL TAH +075A ; [.1CB6.0020.0002.075A] # ARABIC LETTER DAL WITH INVERTED SMALL V BELOW +0631 ; [.1CB7.0020.0002.0631] # ARABIC LETTER REH +1EE13 ; [.1CB7.0020.0005.1EE13] # ARABIC MATHEMATICAL REH +1EE93 ; [.1CB7.0020.0005.1EE93] # ARABIC MATHEMATICAL LOOPED REH +1EEB3 ; [.1CB7.0020.0005.1EEB3] # ARABIC MATHEMATICAL DOUBLE-STRUCK REH +FEAE ; [.1CB7.0020.0019.FEAE] # ARABIC LETTER REH FINAL FORM +FEAD ; [.1CB7.0020.001A.FEAD] # ARABIC LETTER REH ISOLATED FORM +FC5C ; [.1CB7.0020.001A.FC5C][.0000.00D1.001A.FC5C] # ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM +FDF6 ; [.1CB7.0020.001A.FDF6][.1CC8.0020.001A.FDF6][.1D1F.0020.001F.FDF6][.1D05.0020.001F.FDF6] # ARABIC LIGATURE RASOUL ISOLATED FORM +FDFC ; [.1CB7.0020.001A.FDFC][.1D2E.0020.001A.FDFC][.1C81.0020.001F.FDFC][.1D05.0020.001F.FDFC] # RIAL SIGN +0632 ; [.1CB8.0020.0002.0632] # ARABIC LETTER ZAIN +1EE06 ; [.1CB8.0020.0005.1EE06] # ARABIC MATHEMATICAL ZAIN +1EE86 ; [.1CB8.0020.0005.1EE86] # ARABIC MATHEMATICAL LOOPED ZAIN +1EEA6 ; [.1CB8.0020.0005.1EEA6] # ARABIC MATHEMATICAL DOUBLE-STRUCK ZAIN +FEB0 ; [.1CB8.0020.0019.FEB0] # ARABIC LETTER ZAIN FINAL FORM +FEAF ; [.1CB8.0020.001A.FEAF] # ARABIC LETTER ZAIN ISOLATED FORM +0691 ; [.1CB9.0020.0002.0691] # ARABIC LETTER RREH +FB8D ; [.1CB9.0020.0019.FB8D] # ARABIC LETTER RREH FINAL FORM +FB8C ; [.1CB9.0020.001A.FB8C] # ARABIC LETTER RREH ISOLATED FORM +0692 ; [.1CBA.0020.0002.0692] # ARABIC LETTER REH WITH SMALL V +0693 ; [.1CBB.0020.0002.0693] # ARABIC LETTER REH WITH RING +0694 ; [.1CBC.0020.0002.0694] # ARABIC LETTER REH WITH DOT BELOW +0695 ; [.1CBD.0020.0002.0695] # ARABIC LETTER REH WITH SMALL V BELOW +0696 ; [.1CBE.0020.0002.0696] # ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE +0697 ; [.1CBF.0020.0002.0697] # ARABIC LETTER REH WITH TWO DOTS ABOVE +0698 ; [.1CC0.0020.0002.0698] # ARABIC LETTER JEH +FB8B ; [.1CC0.0020.0019.FB8B] # ARABIC LETTER JEH FINAL FORM +FB8A ; [.1CC0.0020.001A.FB8A] # ARABIC LETTER JEH ISOLATED FORM +0699 ; [.1CC1.0020.0002.0699] # ARABIC LETTER REH WITH FOUR DOTS ABOVE +06EF ; [.1CC2.0020.0002.06EF] # ARABIC LETTER REH WITH INVERTED V +075B ; [.1CC3.0020.0002.075B] # ARABIC LETTER REH WITH STROKE +076B ; [.1CC4.0020.0002.076B] # ARABIC LETTER REH WITH TWO DOTS VERTICALLY ABOVE +076C ; [.1CC5.0020.0002.076C] # ARABIC LETTER REH WITH HAMZA ABOVE +0771 ; [.1CC6.0020.0002.0771] # ARABIC LETTER REH WITH SMALL ARABIC LETTER TAH AND TWO DOTS +08AA ; [.1CC7.0020.0002.08AA] # ARABIC LETTER REH WITH LOOP +0633 ; [.1CC8.0020.0002.0633] # ARABIC LETTER SEEN +1EE0E ; [.1CC8.0020.0005.1EE0E] # ARABIC MATHEMATICAL SEEN +1EE2E ; [.1CC8.0020.0005.1EE2E] # ARABIC MATHEMATICAL INITIAL SEEN +1EE4E ; [.1CC8.0020.0005.1EE4E] # ARABIC MATHEMATICAL TAILED SEEN +1EE6E ; [.1CC8.0020.0005.1EE6E] # ARABIC MATHEMATICAL STRETCHED SEEN +1EE8E ; [.1CC8.0020.0005.1EE8E] # ARABIC MATHEMATICAL LOOPED SEEN +1EEAE ; [.1CC8.0020.0005.1EEAE] # ARABIC MATHEMATICAL DOUBLE-STRUCK SEEN +FEB3 ; [.1CC8.0020.0017.FEB3] # ARABIC LETTER SEEN INITIAL FORM +FEB4 ; [.1CC8.0020.0018.FEB4] # ARABIC LETTER SEEN MEDIAL FORM +FEB2 ; [.1CC8.0020.0019.FEB2] # ARABIC LETTER SEEN FINAL FORM +FEB1 ; [.1CC8.0020.001A.FEB1] # ARABIC LETTER SEEN ISOLATED FORM +FCAD ; [.1CC8.0020.0017.FCAD][.1C97.0020.0017.FCAD] # ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM +FD34 ; [.1CC8.0020.0018.FD34][.1C97.0020.0018.FD34] # ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM +FC1C ; [.1CC8.0020.001A.FC1C][.1C97.0020.001A.FC1C] # ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM +FD5D ; [.1CC8.0020.0017.FD5D][.1C97.0020.0017.FD5D][.1C9E.0020.001F.FD5D] # ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM +FD5E ; [.1CC8.0020.0019.FD5E][.1C97.0020.0019.FD5E][.1D2C.0020.001F.FD5E] # ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM +FCAE ; [.1CC8.0020.0017.FCAE][.1C9E.0020.0017.FCAE] # ARABIC LIGATURE SEEN WITH HAH INITIAL FORM +FD35 ; [.1CC8.0020.0018.FD35][.1C9E.0020.0018.FD35] # ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM +FC1D ; [.1CC8.0020.001A.FC1D][.1C9E.0020.001A.FC1D] # ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM +FD5C ; [.1CC8.0020.0017.FD5C][.1C9E.0020.0017.FD5C][.1C97.0020.001F.FD5C] # ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM +FCAF ; [.1CC8.0020.0017.FCAF][.1C9F.0020.0017.FCAF] # ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM +FD36 ; [.1CC8.0020.0018.FD36][.1C9F.0020.0018.FD36] # ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM +FC1E ; [.1CC8.0020.001A.FC1E][.1C9F.0020.001A.FC1E] # ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM +FDA8 ; [.1CC8.0020.0019.FDA8][.1C9F.0020.0019.FDA8][.1D2C.0020.001F.FDA8] # ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM +FDC6 ; [.1CC8.0020.0019.FDC6][.1C9F.0020.0019.FDC6][.1D2D.0020.001F.FDC6] # ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM +FD2A ; [.1CC8.0020.0019.FD2A][.1CB7.0020.0019.FD2A] # ARABIC LIGATURE SEEN WITH REH FINAL FORM +FD0E ; [.1CC8.0020.001A.FD0E][.1CB7.0020.001A.FD0E] # ARABIC LIGATURE SEEN WITH REH ISOLATED FORM +FCB0 ; [.1CC8.0020.0017.FCB0][.1D0C.0020.0017.FCB0] # ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM +FCE7 ; [.1CC8.0020.0018.FCE7][.1D0C.0020.0018.FCE7] # ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM +FC1F ; [.1CC8.0020.001A.FC1F][.1D0C.0020.001A.FC1F] # ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM +FD61 ; [.1CC8.0020.0017.FD61][.1D0C.0020.0017.FD61][.1C97.0020.001F.FD61] # ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM +FD60 ; [.1CC8.0020.0017.FD60][.1D0C.0020.0017.FD60][.1C9E.0020.001F.FD60] # ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM +FD5F ; [.1CC8.0020.0019.FD5F][.1D0C.0020.0019.FD5F][.1C9E.0020.001F.FD5F] # ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM +FD63 ; [.1CC8.0020.0017.FD63][.1D0C.0020.0017.FD63][.1D0C.0020.001F.FD63] # ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM +FD62 ; [.1CC8.0020.0019.FD62][.1D0C.0020.0019.FD62][.1D0C.0020.001F.FD62] # ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM +FD31 ; [.1CC8.0020.0017.FD31][.1D19.0020.0017.FD31] # ARABIC LIGATURE SEEN WITH HEH INITIAL FORM +FCE8 ; [.1CC8.0020.0018.FCE8][.1D19.0020.0018.FCE8] # ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM +FD17 ; [.1CC8.0020.0019.FD17][.1D2C.0020.0019.FD17] # ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM +FCFB ; [.1CC8.0020.001A.FCFB][.1D2C.0020.001A.FCFB] # ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM +FD18 ; [.1CC8.0020.0019.FD18][.1D2D.0020.0019.FD18] # ARABIC LIGATURE SEEN WITH YEH FINAL FORM +FCFC ; [.1CC8.0020.001A.FCFC][.1D2D.0020.001A.FCFC] # ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM +0634 ; [.1CC9.0020.0002.0634] # ARABIC LETTER SHEEN +1EE14 ; [.1CC9.0020.0005.1EE14] # ARABIC MATHEMATICAL SHEEN +1EE34 ; [.1CC9.0020.0005.1EE34] # ARABIC MATHEMATICAL INITIAL SHEEN +1EE54 ; [.1CC9.0020.0005.1EE54] # ARABIC MATHEMATICAL TAILED SHEEN +1EE74 ; [.1CC9.0020.0005.1EE74] # ARABIC MATHEMATICAL STRETCHED SHEEN +1EE94 ; [.1CC9.0020.0005.1EE94] # ARABIC MATHEMATICAL LOOPED SHEEN +1EEB4 ; [.1CC9.0020.0005.1EEB4] # ARABIC MATHEMATICAL DOUBLE-STRUCK SHEEN +FEB7 ; [.1CC9.0020.0017.FEB7] # ARABIC LETTER SHEEN INITIAL FORM +FEB8 ; [.1CC9.0020.0018.FEB8] # ARABIC LETTER SHEEN MEDIAL FORM +FEB6 ; [.1CC9.0020.0019.FEB6] # ARABIC LETTER SHEEN FINAL FORM +FEB5 ; [.1CC9.0020.001A.FEB5] # ARABIC LETTER SHEEN ISOLATED FORM +FD2D ; [.1CC9.0020.0017.FD2D][.1C97.0020.0017.FD2D] # ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM +FD37 ; [.1CC9.0020.0018.FD37][.1C97.0020.0018.FD37] # ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM +FD25 ; [.1CC9.0020.0019.FD25][.1C97.0020.0019.FD25] # ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM +FD09 ; [.1CC9.0020.001A.FD09][.1C97.0020.001A.FD09] # ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM +FD69 ; [.1CC9.0020.0019.FD69][.1C97.0020.0019.FD69][.1D2D.0020.001F.FD69] # ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM +FD2E ; [.1CC9.0020.0017.FD2E][.1C9E.0020.0017.FD2E] # ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM +FD38 ; [.1CC9.0020.0018.FD38][.1C9E.0020.0018.FD38] # ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM +FD26 ; [.1CC9.0020.0019.FD26][.1C9E.0020.0019.FD26] # ARABIC LIGATURE SHEEN WITH HAH FINAL FORM +FD0A ; [.1CC9.0020.001A.FD0A][.1C9E.0020.001A.FD0A] # ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM +FD68 ; [.1CC9.0020.0017.FD68][.1C9E.0020.0017.FD68][.1D0C.0020.001F.FD68] # ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM +FD67 ; [.1CC9.0020.0019.FD67][.1C9E.0020.0019.FD67][.1D0C.0020.001F.FD67] # ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM +FDAA ; [.1CC9.0020.0019.FDAA][.1C9E.0020.0019.FDAA][.1D2D.0020.001F.FDAA] # ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM +FD2F ; [.1CC9.0020.0017.FD2F][.1C9F.0020.0017.FD2F] # ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM +FD39 ; [.1CC9.0020.0018.FD39][.1C9F.0020.0018.FD39] # ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM +FD27 ; [.1CC9.0020.0019.FD27][.1C9F.0020.0019.FD27] # ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM +FD0B ; [.1CC9.0020.001A.FD0B][.1C9F.0020.001A.FD0B] # ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM +FD29 ; [.1CC9.0020.0019.FD29][.1CB7.0020.0019.FD29] # ARABIC LIGATURE SHEEN WITH REH FINAL FORM +FD0D ; [.1CC9.0020.001A.FD0D][.1CB7.0020.001A.FD0D] # ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM +FD30 ; [.1CC9.0020.0017.FD30][.1D0C.0020.0017.FD30] # ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM +FCE9 ; [.1CC9.0020.0018.FCE9][.1D0C.0020.0018.FCE9] # ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM +FD28 ; [.1CC9.0020.0019.FD28][.1D0C.0020.0019.FD28] # ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM +FD0C ; [.1CC9.0020.001A.FD0C][.1D0C.0020.001A.FD0C] # ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM +FD6B ; [.1CC9.0020.0017.FD6B][.1D0C.0020.0017.FD6B][.1C9F.0020.001F.FD6B] # ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM +FD6A ; [.1CC9.0020.0019.FD6A][.1D0C.0020.0019.FD6A][.1C9F.0020.001F.FD6A] # ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM +FD6D ; [.1CC9.0020.0017.FD6D][.1D0C.0020.0017.FD6D][.1D0C.0020.001F.FD6D] # ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM +FD6C ; [.1CC9.0020.0019.FD6C][.1D0C.0020.0019.FD6C][.1D0C.0020.001F.FD6C] # ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM +FD32 ; [.1CC9.0020.0017.FD32][.1D19.0020.0017.FD32] # ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM +FCEA ; [.1CC9.0020.0018.FCEA][.1D19.0020.0018.FCEA] # ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM +FD19 ; [.1CC9.0020.0019.FD19][.1D2C.0020.0019.FD19] # ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM +FCFD ; [.1CC9.0020.001A.FCFD][.1D2C.0020.001A.FCFD] # ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM +FD1A ; [.1CC9.0020.0019.FD1A][.1D2D.0020.0019.FD1A] # ARABIC LIGATURE SHEEN WITH YEH FINAL FORM +FCFE ; [.1CC9.0020.001A.FCFE][.1D2D.0020.001A.FCFE] # ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM +069A ; [.1CCA.0020.0002.069A] # ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE +069B ; [.1CCB.0020.0002.069B] # ARABIC LETTER SEEN WITH THREE DOTS BELOW +069C ; [.1CCC.0020.0002.069C] # ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE +06FA ; [.1CCD.0020.0002.06FA] # ARABIC LETTER SHEEN WITH DOT BELOW +075C ; [.1CCE.0020.0002.075C] # ARABIC LETTER SEEN WITH FOUR DOTS ABOVE +076D ; [.1CCF.0020.0002.076D] # ARABIC LETTER SEEN WITH TWO DOTS VERTICALLY ABOVE +0770 ; [.1CD0.0020.0002.0770] # ARABIC LETTER SEEN WITH SMALL ARABIC LETTER TAH AND TWO DOTS +077D ; [.1CD1.0020.0002.077D] # ARABIC LETTER SEEN WITH EXTENDED ARABIC-INDIC DIGIT FOUR ABOVE +077E ; [.1CD2.0020.0002.077E] # ARABIC LETTER SEEN WITH INVERTED V +0635 ; [.1CD3.0020.0002.0635] # ARABIC LETTER SAD +1EE11 ; [.1CD3.0020.0005.1EE11] # ARABIC MATHEMATICAL SAD +1EE31 ; [.1CD3.0020.0005.1EE31] # ARABIC MATHEMATICAL INITIAL SAD +1EE51 ; [.1CD3.0020.0005.1EE51] # ARABIC MATHEMATICAL TAILED SAD +1EE71 ; [.1CD3.0020.0005.1EE71] # ARABIC MATHEMATICAL STRETCHED SAD +1EE91 ; [.1CD3.0020.0005.1EE91] # ARABIC MATHEMATICAL LOOPED SAD +1EEB1 ; [.1CD3.0020.0005.1EEB1] # ARABIC MATHEMATICAL DOUBLE-STRUCK SAD +FEBB ; [.1CD3.0020.0017.FEBB] # ARABIC LETTER SAD INITIAL FORM +FEBC ; [.1CD3.0020.0018.FEBC] # ARABIC LETTER SAD MEDIAL FORM +FEBA ; [.1CD3.0020.0019.FEBA] # ARABIC LETTER SAD FINAL FORM +FEB9 ; [.1CD3.0020.001A.FEB9] # ARABIC LETTER SAD ISOLATED FORM +FCB1 ; [.1CD3.0020.0017.FCB1][.1C9E.0020.0017.FCB1] # ARABIC LIGATURE SAD WITH HAH INITIAL FORM +FC20 ; [.1CD3.0020.001A.FC20][.1C9E.0020.001A.FC20] # ARABIC LIGATURE SAD WITH HAH ISOLATED FORM +FD65 ; [.1CD3.0020.0017.FD65][.1C9E.0020.0017.FD65][.1C9E.0020.001F.FD65] # ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM +FD64 ; [.1CD3.0020.0019.FD64][.1C9E.0020.0019.FD64][.1C9E.0020.001F.FD64] # ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM +FDA9 ; [.1CD3.0020.0019.FDA9][.1C9E.0020.0019.FDA9][.1D2D.0020.001F.FDA9] # ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM +FCB2 ; [.1CD3.0020.0017.FCB2][.1C9F.0020.0017.FCB2] # ARABIC LIGATURE SAD WITH KHAH INITIAL FORM +FD2B ; [.1CD3.0020.0019.FD2B][.1CB7.0020.0019.FD2B] # ARABIC LIGATURE SAD WITH REH FINAL FORM +FD0F ; [.1CD3.0020.001A.FD0F][.1CB7.0020.001A.FD0F] # ARABIC LIGATURE SAD WITH REH ISOLATED FORM +FDF5 ; [.1CD3.0020.001A.FDF5][.1D05.0020.001A.FDF5][.1CDC.0020.001F.FDF5][.1D0C.0020.001F.FDF5] # ARABIC LIGATURE SALAM ISOLATED FORM +FDF9 ; [.1CD3.0020.001A.FDF9][.1D05.0020.001A.FDF9][.1D2C.0020.001F.FDF9] # ARABIC LIGATURE SALLA ISOLATED FORM +FDFA ; [.1CD3.0020.001A.FDFA][.1D05.0020.001A.FDFA][.1D2C.0020.001F.FDFA][*020A.0020.001F.FDFA][.1C81.0020.001F.FDFA][.1D05.0020.001F.FDFA][.1D05.0020.001F.FDFA][.1D19.0020.001F.FDFA][*020A.0020.001F.FDFA][.1CDC.0020.001F.FDFA][.1D05.0020.001F.FDFA][.1D2D.0020.001F.FDFA][.1D19.0020.001F.FDFA][*020A.0020.001F.FDFA][.1D1F.0020.001F.FDFA][.1CC8.0020.001F.FDFA][.1D05.0020.001F.FDFA][.1D0C.0020.001F.FDFA] # ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM +FDF0 ; [.1CD3.0020.001A.FDF0][.1D05.0020.001A.FDF0][.1D3A.0020.001F.FDF0] # ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM +FCB3 ; [.1CD3.0020.0017.FCB3][.1D0C.0020.0017.FCB3] # ARABIC LIGATURE SAD WITH MEEM INITIAL FORM +FC21 ; [.1CD3.0020.001A.FC21][.1D0C.0020.001A.FC21] # ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM +FDC5 ; [.1CD3.0020.0017.FDC5][.1D0C.0020.0017.FDC5][.1D0C.0020.001F.FDC5] # ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM +FD66 ; [.1CD3.0020.0019.FD66][.1D0C.0020.0019.FD66][.1D0C.0020.001F.FD66] # ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM +FD21 ; [.1CD3.0020.0019.FD21][.1D2C.0020.0019.FD21] # ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM +FD05 ; [.1CD3.0020.001A.FD05][.1D2C.0020.001A.FD05] # ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM +FD22 ; [.1CD3.0020.0019.FD22][.1D2D.0020.0019.FD22] # ARABIC LIGATURE SAD WITH YEH FINAL FORM +FD06 ; [.1CD3.0020.001A.FD06][.1D2D.0020.001A.FD06] # ARABIC LIGATURE SAD WITH YEH ISOLATED FORM +0636 ; [.1CD4.0020.0002.0636] # ARABIC LETTER DAD +1EE19 ; [.1CD4.0020.0005.1EE19] # ARABIC MATHEMATICAL DAD +1EE39 ; [.1CD4.0020.0005.1EE39] # ARABIC MATHEMATICAL INITIAL DAD +1EE59 ; [.1CD4.0020.0005.1EE59] # ARABIC MATHEMATICAL TAILED DAD +1EE79 ; [.1CD4.0020.0005.1EE79] # ARABIC MATHEMATICAL STRETCHED DAD +1EE99 ; [.1CD4.0020.0005.1EE99] # ARABIC MATHEMATICAL LOOPED DAD +1EEB9 ; [.1CD4.0020.0005.1EEB9] # ARABIC MATHEMATICAL DOUBLE-STRUCK DAD +FEBF ; [.1CD4.0020.0017.FEBF] # ARABIC LETTER DAD INITIAL FORM +FEC0 ; [.1CD4.0020.0018.FEC0] # ARABIC LETTER DAD MEDIAL FORM +FEBE ; [.1CD4.0020.0019.FEBE] # ARABIC LETTER DAD FINAL FORM +FEBD ; [.1CD4.0020.001A.FEBD] # ARABIC LETTER DAD ISOLATED FORM +FCB4 ; [.1CD4.0020.0017.FCB4][.1C97.0020.0017.FCB4] # ARABIC LIGATURE DAD WITH JEEM INITIAL FORM +FC22 ; [.1CD4.0020.001A.FC22][.1C97.0020.001A.FC22] # ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM +FCB5 ; [.1CD4.0020.0017.FCB5][.1C9E.0020.0017.FCB5] # ARABIC LIGATURE DAD WITH HAH INITIAL FORM +FC23 ; [.1CD4.0020.001A.FC23][.1C9E.0020.001A.FC23] # ARABIC LIGATURE DAD WITH HAH ISOLATED FORM +FD6E ; [.1CD4.0020.0019.FD6E][.1C9E.0020.0019.FD6E][.1D2C.0020.001F.FD6E] # ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM +FDAB ; [.1CD4.0020.0019.FDAB][.1C9E.0020.0019.FDAB][.1D2D.0020.001F.FDAB] # ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM +FCB6 ; [.1CD4.0020.0017.FCB6][.1C9F.0020.0017.FCB6] # ARABIC LIGATURE DAD WITH KHAH INITIAL FORM +FC24 ; [.1CD4.0020.001A.FC24][.1C9F.0020.001A.FC24] # ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM +FD70 ; [.1CD4.0020.0017.FD70][.1C9F.0020.0017.FD70][.1D0C.0020.001F.FD70] # ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM +FD6F ; [.1CD4.0020.0019.FD6F][.1C9F.0020.0019.FD6F][.1D0C.0020.001F.FD6F] # ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM +FD2C ; [.1CD4.0020.0019.FD2C][.1CB7.0020.0019.FD2C] # ARABIC LIGATURE DAD WITH REH FINAL FORM +FD10 ; [.1CD4.0020.001A.FD10][.1CB7.0020.001A.FD10] # ARABIC LIGATURE DAD WITH REH ISOLATED FORM +FCB7 ; [.1CD4.0020.0017.FCB7][.1D0C.0020.0017.FCB7] # ARABIC LIGATURE DAD WITH MEEM INITIAL FORM +FC25 ; [.1CD4.0020.001A.FC25][.1D0C.0020.001A.FC25] # ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM +FD23 ; [.1CD4.0020.0019.FD23][.1D2C.0020.0019.FD23] # ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM +FD07 ; [.1CD4.0020.001A.FD07][.1D2C.0020.001A.FD07] # ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM +FD24 ; [.1CD4.0020.0019.FD24][.1D2D.0020.0019.FD24] # ARABIC LIGATURE DAD WITH YEH FINAL FORM +FD08 ; [.1CD4.0020.001A.FD08][.1D2D.0020.001A.FD08] # ARABIC LIGATURE DAD WITH YEH ISOLATED FORM +069D ; [.1CD5.0020.0002.069D] # ARABIC LETTER SAD WITH TWO DOTS BELOW +069E ; [.1CD6.0020.0002.069E] # ARABIC LETTER SAD WITH THREE DOTS ABOVE +06FB ; [.1CD7.0020.0002.06FB] # ARABIC LETTER DAD WITH DOT BELOW +0637 ; [.1CD8.0020.0002.0637] # ARABIC LETTER TAH +1EE08 ; [.1CD8.0020.0005.1EE08] # ARABIC MATHEMATICAL TAH +1EE68 ; [.1CD8.0020.0005.1EE68] # ARABIC MATHEMATICAL STRETCHED TAH +1EE88 ; [.1CD8.0020.0005.1EE88] # ARABIC MATHEMATICAL LOOPED TAH +1EEA8 ; [.1CD8.0020.0005.1EEA8] # ARABIC MATHEMATICAL DOUBLE-STRUCK TAH +FEC3 ; [.1CD8.0020.0017.FEC3] # ARABIC LETTER TAH INITIAL FORM +FEC4 ; [.1CD8.0020.0018.FEC4] # ARABIC LETTER TAH MEDIAL FORM +FEC2 ; [.1CD8.0020.0019.FEC2] # ARABIC LETTER TAH FINAL FORM +FEC1 ; [.1CD8.0020.001A.FEC1] # ARABIC LETTER TAH ISOLATED FORM +FCB8 ; [.1CD8.0020.0017.FCB8][.1C9E.0020.0017.FCB8] # ARABIC LIGATURE TAH WITH HAH INITIAL FORM +FC26 ; [.1CD8.0020.001A.FC26][.1C9E.0020.001A.FC26] # ARABIC LIGATURE TAH WITH HAH ISOLATED FORM +FD33 ; [.1CD8.0020.0017.FD33][.1D0C.0020.0017.FD33] # ARABIC LIGATURE TAH WITH MEEM INITIAL FORM +FD3A ; [.1CD8.0020.0018.FD3A][.1D0C.0020.0018.FD3A] # ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM +FC27 ; [.1CD8.0020.001A.FC27][.1D0C.0020.001A.FC27] # ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM +FD72 ; [.1CD8.0020.0017.FD72][.1D0C.0020.0017.FD72][.1C9E.0020.001F.FD72] # ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM +FD71 ; [.1CD8.0020.0019.FD71][.1D0C.0020.0019.FD71][.1C9E.0020.001F.FD71] # ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM +FD73 ; [.1CD8.0020.0017.FD73][.1D0C.0020.0017.FD73][.1D0C.0020.001F.FD73] # ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM +FD74 ; [.1CD8.0020.0019.FD74][.1D0C.0020.0019.FD74][.1D2D.0020.001F.FD74] # ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM +FD11 ; [.1CD8.0020.0019.FD11][.1D2C.0020.0019.FD11] # ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM +FCF5 ; [.1CD8.0020.001A.FCF5][.1D2C.0020.001A.FCF5] # ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM +FD12 ; [.1CD8.0020.0019.FD12][.1D2D.0020.0019.FD12] # ARABIC LIGATURE TAH WITH YEH FINAL FORM +FCF6 ; [.1CD8.0020.001A.FCF6][.1D2D.0020.001A.FCF6] # ARABIC LIGATURE TAH WITH YEH ISOLATED FORM +0638 ; [.1CD9.0020.0002.0638] # ARABIC LETTER ZAH +1EE1A ; [.1CD9.0020.0005.1EE1A] # ARABIC MATHEMATICAL ZAH +1EE7A ; [.1CD9.0020.0005.1EE7A] # ARABIC MATHEMATICAL STRETCHED ZAH +1EE9A ; [.1CD9.0020.0005.1EE9A] # ARABIC MATHEMATICAL LOOPED ZAH +1EEBA ; [.1CD9.0020.0005.1EEBA] # ARABIC MATHEMATICAL DOUBLE-STRUCK ZAH +FEC7 ; [.1CD9.0020.0017.FEC7] # ARABIC LETTER ZAH INITIAL FORM +FEC8 ; [.1CD9.0020.0018.FEC8] # ARABIC LETTER ZAH MEDIAL FORM +FEC6 ; [.1CD9.0020.0019.FEC6] # ARABIC LETTER ZAH FINAL FORM +FEC5 ; [.1CD9.0020.001A.FEC5] # ARABIC LETTER ZAH ISOLATED FORM +FCB9 ; [.1CD9.0020.0017.FCB9][.1D0C.0020.0017.FCB9] # ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM +FD3B ; [.1CD9.0020.0018.FD3B][.1D0C.0020.0018.FD3B] # ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM +FC28 ; [.1CD9.0020.001A.FC28][.1D0C.0020.001A.FC28] # ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM +069F ; [.1CDA.0020.0002.069F] # ARABIC LETTER TAH WITH THREE DOTS ABOVE +08A3 ; [.1CDB.0020.0002.08A3] # ARABIC LETTER TAH WITH TWO DOTS ABOVE +0639 ; [.1CDC.0020.0002.0639] # ARABIC LETTER AIN +1EE0F ; [.1CDC.0020.0005.1EE0F] # ARABIC MATHEMATICAL AIN +1EE2F ; [.1CDC.0020.0005.1EE2F] # ARABIC MATHEMATICAL INITIAL AIN +1EE4F ; [.1CDC.0020.0005.1EE4F] # ARABIC MATHEMATICAL TAILED AIN +1EE6F ; [.1CDC.0020.0005.1EE6F] # ARABIC MATHEMATICAL STRETCHED AIN +1EE8F ; [.1CDC.0020.0005.1EE8F] # ARABIC MATHEMATICAL LOOPED AIN +1EEAF ; [.1CDC.0020.0005.1EEAF] # ARABIC MATHEMATICAL DOUBLE-STRUCK AIN +FECB ; [.1CDC.0020.0017.FECB] # ARABIC LETTER AIN INITIAL FORM +FECC ; [.1CDC.0020.0018.FECC] # ARABIC LETTER AIN MEDIAL FORM +FECA ; [.1CDC.0020.0019.FECA] # ARABIC LETTER AIN FINAL FORM +FEC9 ; [.1CDC.0020.001A.FEC9] # ARABIC LETTER AIN ISOLATED FORM +FCBA ; [.1CDC.0020.0017.FCBA][.1C97.0020.0017.FCBA] # ARABIC LIGATURE AIN WITH JEEM INITIAL FORM +FC29 ; [.1CDC.0020.001A.FC29][.1C97.0020.001A.FC29] # ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM +FDC4 ; [.1CDC.0020.0017.FDC4][.1C97.0020.0017.FDC4][.1D0C.0020.001F.FDC4] # ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM +FD75 ; [.1CDC.0020.0019.FD75][.1C97.0020.0019.FD75][.1D0C.0020.001F.FD75] # ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM +FDF7 ; [.1CDC.0020.001A.FDF7][.1D05.0020.001A.FDF7][.1D2D.0020.001F.FDF7][.1D19.0020.001F.FDF7] # ARABIC LIGATURE ALAYHE ISOLATED FORM +FCBB ; [.1CDC.0020.0017.FCBB][.1D0C.0020.0017.FCBB] # ARABIC LIGATURE AIN WITH MEEM INITIAL FORM +FC2A ; [.1CDC.0020.001A.FC2A][.1D0C.0020.001A.FC2A] # ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM +FD77 ; [.1CDC.0020.0017.FD77][.1D0C.0020.0017.FD77][.1D0C.0020.001F.FD77] # ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM +FD76 ; [.1CDC.0020.0019.FD76][.1D0C.0020.0019.FD76][.1D0C.0020.001F.FD76] # ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM +FD78 ; [.1CDC.0020.0019.FD78][.1D0C.0020.0019.FD78][.1D2C.0020.001F.FD78] # ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM +FDB6 ; [.1CDC.0020.0019.FDB6][.1D0C.0020.0019.FDB6][.1D2D.0020.001F.FDB6] # ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM +FD13 ; [.1CDC.0020.0019.FD13][.1D2C.0020.0019.FD13] # ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM +FCF7 ; [.1CDC.0020.001A.FCF7][.1D2C.0020.001A.FCF7] # ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM +FD14 ; [.1CDC.0020.0019.FD14][.1D2D.0020.0019.FD14] # ARABIC LIGATURE AIN WITH YEH FINAL FORM +FCF8 ; [.1CDC.0020.001A.FCF8][.1D2D.0020.001A.FCF8] # ARABIC LIGATURE AIN WITH YEH ISOLATED FORM +063A ; [.1CDD.0020.0002.063A] # ARABIC LETTER GHAIN +1EE1B ; [.1CDD.0020.0005.1EE1B] # ARABIC MATHEMATICAL GHAIN +1EE3B ; [.1CDD.0020.0005.1EE3B] # ARABIC MATHEMATICAL INITIAL GHAIN +1EE5B ; [.1CDD.0020.0005.1EE5B] # ARABIC MATHEMATICAL TAILED GHAIN +1EE7B ; [.1CDD.0020.0005.1EE7B] # ARABIC MATHEMATICAL STRETCHED GHAIN +1EE9B ; [.1CDD.0020.0005.1EE9B] # ARABIC MATHEMATICAL LOOPED GHAIN +1EEBB ; [.1CDD.0020.0005.1EEBB] # ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN +FECF ; [.1CDD.0020.0017.FECF] # ARABIC LETTER GHAIN INITIAL FORM +FED0 ; [.1CDD.0020.0018.FED0] # ARABIC LETTER GHAIN MEDIAL FORM +FECE ; [.1CDD.0020.0019.FECE] # ARABIC LETTER GHAIN FINAL FORM +FECD ; [.1CDD.0020.001A.FECD] # ARABIC LETTER GHAIN ISOLATED FORM +FCBC ; [.1CDD.0020.0017.FCBC][.1C97.0020.0017.FCBC] # ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM +FC2B ; [.1CDD.0020.001A.FC2B][.1C97.0020.001A.FC2B] # ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM +FCBD ; [.1CDD.0020.0017.FCBD][.1D0C.0020.0017.FCBD] # ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM +FC2C ; [.1CDD.0020.001A.FC2C][.1D0C.0020.001A.FC2C] # ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM +FD79 ; [.1CDD.0020.0019.FD79][.1D0C.0020.0019.FD79][.1D0C.0020.001F.FD79] # ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM +FD7B ; [.1CDD.0020.0019.FD7B][.1D0C.0020.0019.FD7B][.1D2C.0020.001F.FD7B] # ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM +FD7A ; [.1CDD.0020.0019.FD7A][.1D0C.0020.0019.FD7A][.1D2D.0020.001F.FD7A] # ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM +FD15 ; [.1CDD.0020.0019.FD15][.1D2C.0020.0019.FD15] # ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM +FCF9 ; [.1CDD.0020.001A.FCF9][.1D2C.0020.001A.FCF9] # ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM +FD16 ; [.1CDD.0020.0019.FD16][.1D2D.0020.0019.FD16] # ARABIC LIGATURE GHAIN WITH YEH FINAL FORM +FCFA ; [.1CDD.0020.001A.FCFA][.1D2D.0020.001A.FCFA] # ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM +06A0 ; [.1CDE.0020.0002.06A0] # ARABIC LETTER AIN WITH THREE DOTS ABOVE +06FC ; [.1CDF.0020.0002.06FC] # ARABIC LETTER GHAIN WITH DOT BELOW +075D ; [.1CE0.0020.0002.075D] # ARABIC LETTER AIN WITH TWO DOTS ABOVE +075E ; [.1CE1.0020.0002.075E] # ARABIC LETTER AIN WITH THREE DOTS POINTING DOWNWARDS ABOVE +075F ; [.1CE2.0020.0002.075F] # ARABIC LETTER AIN WITH TWO DOTS VERTICALLY ABOVE +0641 ; [.1CE3.0020.0002.0641] # ARABIC LETTER FEH +1EE10 ; [.1CE3.0020.0005.1EE10] # ARABIC MATHEMATICAL FEH +1EE30 ; [.1CE3.0020.0005.1EE30] # ARABIC MATHEMATICAL INITIAL FEH +1EE70 ; [.1CE3.0020.0005.1EE70] # ARABIC MATHEMATICAL STRETCHED FEH +1EE90 ; [.1CE3.0020.0005.1EE90] # ARABIC MATHEMATICAL LOOPED FEH +1EEB0 ; [.1CE3.0020.0005.1EEB0] # ARABIC MATHEMATICAL DOUBLE-STRUCK FEH +FED3 ; [.1CE3.0020.0017.FED3] # ARABIC LETTER FEH INITIAL FORM +FED4 ; [.1CE3.0020.0018.FED4] # ARABIC LETTER FEH MEDIAL FORM +FED2 ; [.1CE3.0020.0019.FED2] # ARABIC LETTER FEH FINAL FORM +FED1 ; [.1CE3.0020.001A.FED1] # ARABIC LETTER FEH ISOLATED FORM +FCBE ; [.1CE3.0020.0017.FCBE][.1C97.0020.0017.FCBE] # ARABIC LIGATURE FEH WITH JEEM INITIAL FORM +FC2D ; [.1CE3.0020.001A.FC2D][.1C97.0020.001A.FC2D] # ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM +FCBF ; [.1CE3.0020.0017.FCBF][.1C9E.0020.0017.FCBF] # ARABIC LIGATURE FEH WITH HAH INITIAL FORM +FC2E ; [.1CE3.0020.001A.FC2E][.1C9E.0020.001A.FC2E] # ARABIC LIGATURE FEH WITH HAH ISOLATED FORM +FCC0 ; [.1CE3.0020.0017.FCC0][.1C9F.0020.0017.FCC0] # ARABIC LIGATURE FEH WITH KHAH INITIAL FORM +FC2F ; [.1CE3.0020.001A.FC2F][.1C9F.0020.001A.FC2F] # ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM +FD7D ; [.1CE3.0020.0017.FD7D][.1C9F.0020.0017.FD7D][.1D0C.0020.001F.FD7D] # ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM +FD7C ; [.1CE3.0020.0019.FD7C][.1C9F.0020.0019.FD7C][.1D0C.0020.001F.FD7C] # ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM +FCC1 ; [.1CE3.0020.0017.FCC1][.1D0C.0020.0017.FCC1] # ARABIC LIGATURE FEH WITH MEEM INITIAL FORM +FC30 ; [.1CE3.0020.001A.FC30][.1D0C.0020.001A.FC30] # ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM +FDC1 ; [.1CE3.0020.0019.FDC1][.1D0C.0020.0019.FDC1][.1D2D.0020.001F.FDC1] # ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM +FC7C ; [.1CE3.0020.0019.FC7C][.1D2C.0020.0019.FC7C] # ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM +FC31 ; [.1CE3.0020.001A.FC31][.1D2C.0020.001A.FC31] # ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM +FC7D ; [.1CE3.0020.0019.FC7D][.1D2D.0020.0019.FC7D] # ARABIC LIGATURE FEH WITH YEH FINAL FORM +FC32 ; [.1CE3.0020.001A.FC32][.1D2D.0020.001A.FC32] # ARABIC LIGATURE FEH WITH YEH ISOLATED FORM +06A1 ; [.1CE4.0020.0002.06A1] # ARABIC LETTER DOTLESS FEH +1EE1E ; [.1CE4.0020.0005.1EE1E] # ARABIC MATHEMATICAL DOTLESS FEH +1EE7E ; [.1CE4.0020.0005.1EE7E] # ARABIC MATHEMATICAL STRETCHED DOTLESS FEH +06A2 ; [.1CE5.0020.0002.06A2] # ARABIC LETTER FEH WITH DOT MOVED BELOW +06A3 ; [.1CE6.0020.0002.06A3] # ARABIC LETTER FEH WITH DOT BELOW +06A4 ; [.1CE7.0020.0002.06A4] # ARABIC LETTER VEH +FB6C ; [.1CE7.0020.0017.FB6C] # ARABIC LETTER VEH INITIAL FORM +FB6D ; [.1CE7.0020.0018.FB6D] # ARABIC LETTER VEH MEDIAL FORM +FB6B ; [.1CE7.0020.0019.FB6B] # ARABIC LETTER VEH FINAL FORM +FB6A ; [.1CE7.0020.001A.FB6A] # ARABIC LETTER VEH ISOLATED FORM +08A4 ; [.1CE8.0020.0002.08A4] # ARABIC LETTER FEH WITH DOT BELOW AND THREE DOTS ABOVE +06A5 ; [.1CE9.0020.0002.06A5] # ARABIC LETTER FEH WITH THREE DOTS BELOW +06A6 ; [.1CEA.0020.0002.06A6] # ARABIC LETTER PEHEH +FB70 ; [.1CEA.0020.0017.FB70] # ARABIC LETTER PEHEH INITIAL FORM +FB71 ; [.1CEA.0020.0018.FB71] # ARABIC LETTER PEHEH MEDIAL FORM +FB6F ; [.1CEA.0020.0019.FB6F] # ARABIC LETTER PEHEH FINAL FORM +FB6E ; [.1CEA.0020.001A.FB6E] # ARABIC LETTER PEHEH ISOLATED FORM +0760 ; [.1CEB.0020.0002.0760] # ARABIC LETTER FEH WITH TWO DOTS BELOW +0761 ; [.1CEC.0020.0002.0761] # ARABIC LETTER FEH WITH THREE DOTS POINTING UPWARDS BELOW +066F ; [.1CED.0020.0002.066F] # ARABIC LETTER DOTLESS QAF +1EE1F ; [.1CED.0020.0005.1EE1F] # ARABIC MATHEMATICAL DOTLESS QAF +1EE5F ; [.1CED.0020.0005.1EE5F] # ARABIC MATHEMATICAL TAILED DOTLESS QAF +0642 ; [.1CEE.0020.0002.0642] # ARABIC LETTER QAF +1EE12 ; [.1CEE.0020.0005.1EE12] # ARABIC MATHEMATICAL QAF +1EE32 ; [.1CEE.0020.0005.1EE32] # ARABIC MATHEMATICAL INITIAL QAF +1EE52 ; [.1CEE.0020.0005.1EE52] # ARABIC MATHEMATICAL TAILED QAF +1EE72 ; [.1CEE.0020.0005.1EE72] # ARABIC MATHEMATICAL STRETCHED QAF +1EE92 ; [.1CEE.0020.0005.1EE92] # ARABIC MATHEMATICAL LOOPED QAF +1EEB2 ; [.1CEE.0020.0005.1EEB2] # ARABIC MATHEMATICAL DOUBLE-STRUCK QAF +FED7 ; [.1CEE.0020.0017.FED7] # ARABIC LETTER QAF INITIAL FORM +FED8 ; [.1CEE.0020.0018.FED8] # ARABIC LETTER QAF MEDIAL FORM +FED6 ; [.1CEE.0020.0019.FED6] # ARABIC LETTER QAF FINAL FORM +FED5 ; [.1CEE.0020.001A.FED5] # ARABIC LETTER QAF ISOLATED FORM +FCC2 ; [.1CEE.0020.0017.FCC2][.1C9E.0020.0017.FCC2] # ARABIC LIGATURE QAF WITH HAH INITIAL FORM +FC33 ; [.1CEE.0020.001A.FC33][.1C9E.0020.001A.FC33] # ARABIC LIGATURE QAF WITH HAH ISOLATED FORM +FDF1 ; [.1CEE.0020.001A.FDF1][.1D05.0020.001A.FDF1][.1D3A.0020.001F.FDF1] # ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM +FCC3 ; [.1CEE.0020.0017.FCC3][.1D0C.0020.0017.FCC3] # ARABIC LIGATURE QAF WITH MEEM INITIAL FORM +FC34 ; [.1CEE.0020.001A.FC34][.1D0C.0020.001A.FC34] # ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM +FDB4 ; [.1CEE.0020.0017.FDB4][.1D0C.0020.0017.FDB4][.1C9E.0020.001F.FDB4] # ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM +FD7E ; [.1CEE.0020.0019.FD7E][.1D0C.0020.0019.FD7E][.1C9E.0020.001F.FD7E] # ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM +FD7F ; [.1CEE.0020.0019.FD7F][.1D0C.0020.0019.FD7F][.1D0C.0020.001F.FD7F] # ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM +FDB2 ; [.1CEE.0020.0019.FDB2][.1D0C.0020.0019.FDB2][.1D2D.0020.001F.FDB2] # ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM +FC7E ; [.1CEE.0020.0019.FC7E][.1D2C.0020.0019.FC7E] # ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM +FC35 ; [.1CEE.0020.001A.FC35][.1D2C.0020.001A.FC35] # ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM +FC7F ; [.1CEE.0020.0019.FC7F][.1D2D.0020.0019.FC7F] # ARABIC LIGATURE QAF WITH YEH FINAL FORM +FC36 ; [.1CEE.0020.001A.FC36][.1D2D.0020.001A.FC36] # ARABIC LIGATURE QAF WITH YEH ISOLATED FORM +06A7 ; [.1CEF.0020.0002.06A7] # ARABIC LETTER QAF WITH DOT ABOVE +06A8 ; [.1CF0.0020.0002.06A8] # ARABIC LETTER QAF WITH THREE DOTS ABOVE +08A5 ; [.1CF1.0020.0002.08A5] # ARABIC LETTER QAF WITH DOT BELOW +0643 ; [.1CF2.0020.0002.0643] # ARABIC LETTER KAF +1EE0A ; [.1CF2.0020.0005.1EE0A] # ARABIC MATHEMATICAL KAF +1EE2A ; [.1CF2.0020.0005.1EE2A] # ARABIC MATHEMATICAL INITIAL KAF +1EE6A ; [.1CF2.0020.0005.1EE6A] # ARABIC MATHEMATICAL STRETCHED KAF +FEDB ; [.1CF2.0020.0017.FEDB] # ARABIC LETTER KAF INITIAL FORM +FEDC ; [.1CF2.0020.0018.FEDC] # ARABIC LETTER KAF MEDIAL FORM +FEDA ; [.1CF2.0020.0019.FEDA] # ARABIC LETTER KAF FINAL FORM +FED9 ; [.1CF2.0020.001A.FED9] # ARABIC LETTER KAF ISOLATED FORM +FC80 ; [.1CF2.0020.0019.FC80][.1C81.0020.0019.FC80] # ARABIC LIGATURE KAF WITH ALEF FINAL FORM +FC37 ; [.1CF2.0020.001A.FC37][.1C81.0020.001A.FC37] # ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM +FCC4 ; [.1CF2.0020.0017.FCC4][.1C97.0020.0017.FCC4] # ARABIC LIGATURE KAF WITH JEEM INITIAL FORM +FC38 ; [.1CF2.0020.001A.FC38][.1C97.0020.001A.FC38] # ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM +FCC5 ; [.1CF2.0020.0017.FCC5][.1C9E.0020.0017.FCC5] # ARABIC LIGATURE KAF WITH HAH INITIAL FORM +FC39 ; [.1CF2.0020.001A.FC39][.1C9E.0020.001A.FC39] # ARABIC LIGATURE KAF WITH HAH ISOLATED FORM +FCC6 ; [.1CF2.0020.0017.FCC6][.1C9F.0020.0017.FCC6] # ARABIC LIGATURE KAF WITH KHAH INITIAL FORM +FC3A ; [.1CF2.0020.001A.FC3A][.1C9F.0020.001A.FC3A] # ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM +FCC7 ; [.1CF2.0020.0017.FCC7][.1D05.0020.0017.FCC7] # ARABIC LIGATURE KAF WITH LAM INITIAL FORM +FCEB ; [.1CF2.0020.0018.FCEB][.1D05.0020.0018.FCEB] # ARABIC LIGATURE KAF WITH LAM MEDIAL FORM +FC81 ; [.1CF2.0020.0019.FC81][.1D05.0020.0019.FC81] # ARABIC LIGATURE KAF WITH LAM FINAL FORM +FC3B ; [.1CF2.0020.001A.FC3B][.1D05.0020.001A.FC3B] # ARABIC LIGATURE KAF WITH LAM ISOLATED FORM +FCC8 ; [.1CF2.0020.0017.FCC8][.1D0C.0020.0017.FCC8] # ARABIC LIGATURE KAF WITH MEEM INITIAL FORM +FCEC ; [.1CF2.0020.0018.FCEC][.1D0C.0020.0018.FCEC] # ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM +FC82 ; [.1CF2.0020.0019.FC82][.1D0C.0020.0019.FC82] # ARABIC LIGATURE KAF WITH MEEM FINAL FORM +FC3C ; [.1CF2.0020.001A.FC3C][.1D0C.0020.001A.FC3C] # ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM +FDC3 ; [.1CF2.0020.0017.FDC3][.1D0C.0020.0017.FDC3][.1D0C.0020.001F.FDC3] # ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM +FDBB ; [.1CF2.0020.0019.FDBB][.1D0C.0020.0019.FDBB][.1D0C.0020.001F.FDBB] # ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM +FDB7 ; [.1CF2.0020.0019.FDB7][.1D0C.0020.0019.FDB7][.1D2D.0020.001F.FDB7] # ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM +FC83 ; [.1CF2.0020.0019.FC83][.1D2C.0020.0019.FC83] # ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM +FC3D ; [.1CF2.0020.001A.FC3D][.1D2C.0020.001A.FC3D] # ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM +FC84 ; [.1CF2.0020.0019.FC84][.1D2D.0020.0019.FC84] # ARABIC LIGATURE KAF WITH YEH FINAL FORM +FC3E ; [.1CF2.0020.001A.FC3E][.1D2D.0020.001A.FC3E] # ARABIC LIGATURE KAF WITH YEH ISOLATED FORM +06A9 ; [.1CF3.0020.0002.06A9] # ARABIC LETTER KEHEH +FB90 ; [.1CF3.0020.0017.FB90] # ARABIC LETTER KEHEH INITIAL FORM +FB91 ; [.1CF3.0020.0018.FB91] # ARABIC LETTER KEHEH MEDIAL FORM +FB8F ; [.1CF3.0020.0019.FB8F] # ARABIC LETTER KEHEH FINAL FORM +FB8E ; [.1CF3.0020.001A.FB8E] # ARABIC LETTER KEHEH ISOLATED FORM +06AA ; [.1CF4.0020.0002.06AA] # ARABIC LETTER SWASH KAF +06AB ; [.1CF5.0020.0002.06AB] # ARABIC LETTER KAF WITH RING +06AC ; [.1CF6.0020.0002.06AC] # ARABIC LETTER KAF WITH DOT ABOVE +077F ; [.1CF7.0020.0002.077F] # ARABIC LETTER KAF WITH TWO DOTS ABOVE +06AD ; [.1CF8.0020.0002.06AD] # ARABIC LETTER NG +FBD5 ; [.1CF8.0020.0017.FBD5] # ARABIC LETTER NG INITIAL FORM +FBD6 ; [.1CF8.0020.0018.FBD6] # ARABIC LETTER NG MEDIAL FORM +FBD4 ; [.1CF8.0020.0019.FBD4] # ARABIC LETTER NG FINAL FORM +FBD3 ; [.1CF8.0020.001A.FBD3] # ARABIC LETTER NG ISOLATED FORM +06AE ; [.1CF9.0020.0002.06AE] # ARABIC LETTER KAF WITH THREE DOTS BELOW +06AF ; [.1CFA.0020.0002.06AF] # ARABIC LETTER GAF +FB94 ; [.1CFA.0020.0017.FB94] # ARABIC LETTER GAF INITIAL FORM +FB95 ; [.1CFA.0020.0018.FB95] # ARABIC LETTER GAF MEDIAL FORM +FB93 ; [.1CFA.0020.0019.FB93] # ARABIC LETTER GAF FINAL FORM +FB92 ; [.1CFA.0020.001A.FB92] # ARABIC LETTER GAF ISOLATED FORM +06B0 ; [.1CFB.0020.0002.06B0] # ARABIC LETTER GAF WITH RING +06B1 ; [.1CFC.0020.0002.06B1] # ARABIC LETTER NGOEH +FB9C ; [.1CFC.0020.0017.FB9C] # ARABIC LETTER NGOEH INITIAL FORM +FB9D ; [.1CFC.0020.0018.FB9D] # ARABIC LETTER NGOEH MEDIAL FORM +FB9B ; [.1CFC.0020.0019.FB9B] # ARABIC LETTER NGOEH FINAL FORM +FB9A ; [.1CFC.0020.001A.FB9A] # ARABIC LETTER NGOEH ISOLATED FORM +06B2 ; [.1CFD.0020.0002.06B2] # ARABIC LETTER GAF WITH TWO DOTS BELOW +06B3 ; [.1CFE.0020.0002.06B3] # ARABIC LETTER GUEH +FB98 ; [.1CFE.0020.0017.FB98] # ARABIC LETTER GUEH INITIAL FORM +FB99 ; [.1CFE.0020.0018.FB99] # ARABIC LETTER GUEH MEDIAL FORM +FB97 ; [.1CFE.0020.0019.FB97] # ARABIC LETTER GUEH FINAL FORM +FB96 ; [.1CFE.0020.001A.FB96] # ARABIC LETTER GUEH ISOLATED FORM +06B4 ; [.1CFF.0020.0002.06B4] # ARABIC LETTER GAF WITH THREE DOTS ABOVE +0762 ; [.1D00.0020.0002.0762] # ARABIC LETTER KEHEH WITH DOT ABOVE +063B ; [.1D01.0020.0002.063B] # ARABIC LETTER KEHEH WITH TWO DOTS ABOVE +063C ; [.1D02.0020.0002.063C] # ARABIC LETTER KEHEH WITH THREE DOTS BELOW +0763 ; [.1D03.0020.0002.0763] # ARABIC LETTER KEHEH WITH THREE DOTS ABOVE +0764 ; [.1D04.0020.0002.0764] # ARABIC LETTER KEHEH WITH THREE DOTS POINTING UPWARDS BELOW +0644 ; [.1D05.0020.0002.0644] # ARABIC LETTER LAM +1EE0B ; [.1D05.0020.0005.1EE0B] # ARABIC MATHEMATICAL LAM +1EE2B ; [.1D05.0020.0005.1EE2B] # ARABIC MATHEMATICAL INITIAL LAM +1EE4B ; [.1D05.0020.0005.1EE4B] # ARABIC MATHEMATICAL TAILED LAM +1EE8B ; [.1D05.0020.0005.1EE8B] # ARABIC MATHEMATICAL LOOPED LAM +1EEAB ; [.1D05.0020.0005.1EEAB] # ARABIC MATHEMATICAL DOUBLE-STRUCK LAM +FEDF ; [.1D05.0020.0017.FEDF] # ARABIC LETTER LAM INITIAL FORM +FEE0 ; [.1D05.0020.0018.FEE0] # ARABIC LETTER LAM MEDIAL FORM +FEDE ; [.1D05.0020.0019.FEDE] # ARABIC LETTER LAM FINAL FORM +FEDD ; [.1D05.0020.001A.FEDD] # ARABIC LETTER LAM ISOLATED FORM +FEF6 ; [.1D05.0020.0019.FEF6][.1C74.0020.0019.FEF6] # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM +FEF5 ; [.1D05.0020.001A.FEF5][.1C74.0020.001A.FEF5] # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM +FEF8 ; [.1D05.0020.0019.FEF8][.1C75.0020.0019.FEF8] # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM +FEF7 ; [.1D05.0020.001A.FEF7][.1C75.0020.001A.FEF7] # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM +FEFA ; [.1D05.0020.0019.FEFA][.1C79.0020.0019.FEFA] # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM +FEF9 ; [.1D05.0020.001A.FEF9][.1C79.0020.001A.FEF9] # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM +FEFC ; [.1D05.0020.0019.FEFC][.1C81.0020.0019.FEFC] # ARABIC LIGATURE LAM WITH ALEF FINAL FORM +FEFB ; [.1D05.0020.001A.FEFB][.1C81.0020.001A.FEFB] # ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM +FCC9 ; [.1D05.0020.0017.FCC9][.1C97.0020.0017.FCC9] # ARABIC LIGATURE LAM WITH JEEM INITIAL FORM +FC3F ; [.1D05.0020.001A.FC3F][.1C97.0020.001A.FC3F] # ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM +FD83 ; [.1D05.0020.0017.FD83][.1C97.0020.0017.FD83][.1C97.0020.001F.FD83] # ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM +FD84 ; [.1D05.0020.0019.FD84][.1C97.0020.0019.FD84][.1C97.0020.001F.FD84] # ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM +FDBA ; [.1D05.0020.0017.FDBA][.1C97.0020.0017.FDBA][.1D0C.0020.001F.FDBA] # ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM +FDBC ; [.1D05.0020.0019.FDBC][.1C97.0020.0019.FDBC][.1D0C.0020.001F.FDBC] # ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM +FDAC ; [.1D05.0020.0019.FDAC][.1C97.0020.0019.FDAC][.1D2D.0020.001F.FDAC] # ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM +FCCA ; [.1D05.0020.0017.FCCA][.1C9E.0020.0017.FCCA] # ARABIC LIGATURE LAM WITH HAH INITIAL FORM +FC40 ; [.1D05.0020.001A.FC40][.1C9E.0020.001A.FC40] # ARABIC LIGATURE LAM WITH HAH ISOLATED FORM +FDB5 ; [.1D05.0020.0017.FDB5][.1C9E.0020.0017.FDB5][.1D0C.0020.001F.FDB5] # ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM +FD80 ; [.1D05.0020.0019.FD80][.1C9E.0020.0019.FD80][.1D0C.0020.001F.FD80] # ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM +FD82 ; [.1D05.0020.0019.FD82][.1C9E.0020.0019.FD82][.1D2C.0020.001F.FD82] # ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM +FD81 ; [.1D05.0020.0019.FD81][.1C9E.0020.0019.FD81][.1D2D.0020.001F.FD81] # ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM +FCCB ; [.1D05.0020.0017.FCCB][.1C9F.0020.0017.FCCB] # ARABIC LIGATURE LAM WITH KHAH INITIAL FORM +FC41 ; [.1D05.0020.001A.FC41][.1C9F.0020.001A.FC41] # ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM +FD86 ; [.1D05.0020.0017.FD86][.1C9F.0020.0017.FD86][.1D0C.0020.001F.FD86] # ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM +FD85 ; [.1D05.0020.0019.FD85][.1C9F.0020.0019.FD85][.1D0C.0020.001F.FD85] # ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM +FCCC ; [.1D05.0020.0017.FCCC][.1D0C.0020.0017.FCCC] # ARABIC LIGATURE LAM WITH MEEM INITIAL FORM +FCED ; [.1D05.0020.0018.FCED][.1D0C.0020.0018.FCED] # ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM +FC85 ; [.1D05.0020.0019.FC85][.1D0C.0020.0019.FC85] # ARABIC LIGATURE LAM WITH MEEM FINAL FORM +FC42 ; [.1D05.0020.001A.FC42][.1D0C.0020.001A.FC42] # ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM +FD88 ; [.1D05.0020.0017.FD88][.1D0C.0020.0017.FD88][.1C9E.0020.001F.FD88] # ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM +FD87 ; [.1D05.0020.0019.FD87][.1D0C.0020.0019.FD87][.1C9E.0020.001F.FD87] # ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM +FDAD ; [.1D05.0020.0019.FDAD][.1D0C.0020.0019.FDAD][.1D2D.0020.001F.FDAD] # ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM +FCCD ; [.1D05.0020.0017.FCCD][.1D19.0020.0017.FCCD] # ARABIC LIGATURE LAM WITH HEH INITIAL FORM +FC86 ; [.1D05.0020.0019.FC86][.1D2C.0020.0019.FC86] # ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM +FC43 ; [.1D05.0020.001A.FC43][.1D2C.0020.001A.FC43] # ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM +FC87 ; [.1D05.0020.0019.FC87][.1D2D.0020.0019.FC87] # ARABIC LIGATURE LAM WITH YEH FINAL FORM +FC44 ; [.1D05.0020.001A.FC44][.1D2D.0020.001A.FC44] # ARABIC LIGATURE LAM WITH YEH ISOLATED FORM +06B5 ; [.1D06.0020.0002.06B5] # ARABIC LETTER LAM WITH SMALL V +06B6 ; [.1D07.0020.0002.06B6] # ARABIC LETTER LAM WITH DOT ABOVE +06B7 ; [.1D08.0020.0002.06B7] # ARABIC LETTER LAM WITH THREE DOTS ABOVE +06B8 ; [.1D09.0020.0002.06B8] # ARABIC LETTER LAM WITH THREE DOTS BELOW +076A ; [.1D0A.0020.0002.076A] # ARABIC LETTER LAM WITH BAR +08A6 ; [.1D0B.0020.0002.08A6] # ARABIC LETTER LAM WITH DOUBLE BAR +0645 ; [.1D0C.0020.0002.0645] # ARABIC LETTER MEEM +1EE0C ; [.1D0C.0020.0005.1EE0C] # ARABIC MATHEMATICAL MEEM +1EE2C ; [.1D0C.0020.0005.1EE2C] # ARABIC MATHEMATICAL INITIAL MEEM +1EE6C ; [.1D0C.0020.0005.1EE6C] # ARABIC MATHEMATICAL STRETCHED MEEM +1EE8C ; [.1D0C.0020.0005.1EE8C] # ARABIC MATHEMATICAL LOOPED MEEM +1EEAC ; [.1D0C.0020.0005.1EEAC] # ARABIC MATHEMATICAL DOUBLE-STRUCK MEEM +FEE3 ; [.1D0C.0020.0017.FEE3] # ARABIC LETTER MEEM INITIAL FORM +FEE4 ; [.1D0C.0020.0018.FEE4] # ARABIC LETTER MEEM MEDIAL FORM +FEE2 ; [.1D0C.0020.0019.FEE2] # ARABIC LETTER MEEM FINAL FORM +FEE1 ; [.1D0C.0020.001A.FEE1] # ARABIC LETTER MEEM ISOLATED FORM +06FE ; [.1D0C.0020.0004.06FE][.0000.013A.0004.06FE] # ARABIC SIGN SINDHI POSTPOSITION MEN +FC88 ; [.1D0C.0020.0019.FC88][.1C81.0020.0019.FC88] # ARABIC LIGATURE MEEM WITH ALEF FINAL FORM +FCCE ; [.1D0C.0020.0017.FCCE][.1C97.0020.0017.FCCE] # ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM +FC45 ; [.1D0C.0020.001A.FC45][.1C97.0020.001A.FC45] # ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM +FD8C ; [.1D0C.0020.0017.FD8C][.1C97.0020.0017.FD8C][.1C9E.0020.001F.FD8C] # ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM +FD92 ; [.1D0C.0020.0017.FD92][.1C97.0020.0017.FD92][.1C9F.0020.001F.FD92] # ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM +FD8D ; [.1D0C.0020.0017.FD8D][.1C97.0020.0017.FD8D][.1D0C.0020.001F.FD8D] # ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM +FDC0 ; [.1D0C.0020.0019.FDC0][.1C97.0020.0019.FDC0][.1D2D.0020.001F.FDC0] # ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM +FCCF ; [.1D0C.0020.0017.FCCF][.1C9E.0020.0017.FCCF] # ARABIC LIGATURE MEEM WITH HAH INITIAL FORM +FC46 ; [.1D0C.0020.001A.FC46][.1C9E.0020.001A.FC46] # ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM +FD89 ; [.1D0C.0020.0017.FD89][.1C9E.0020.0017.FD89][.1C97.0020.001F.FD89] # ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM +FD8A ; [.1D0C.0020.0017.FD8A][.1C9E.0020.0017.FD8A][.1D0C.0020.001F.FD8A] # ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM +FDF4 ; [.1D0C.0020.001A.FDF4][.1C9E.0020.001A.FDF4][.1D0C.0020.001F.FDF4][.1CA9.0020.001F.FDF4] # ARABIC LIGATURE MOHAMMAD ISOLATED FORM +FD8B ; [.1D0C.0020.0019.FD8B][.1C9E.0020.0019.FD8B][.1D2D.0020.001F.FD8B] # ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM +FCD0 ; [.1D0C.0020.0017.FCD0][.1C9F.0020.0017.FCD0] # ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM +FC47 ; [.1D0C.0020.001A.FC47][.1C9F.0020.001A.FC47] # ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM +FD8E ; [.1D0C.0020.0017.FD8E][.1C9F.0020.0017.FD8E][.1C97.0020.001F.FD8E] # ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM +FD8F ; [.1D0C.0020.0017.FD8F][.1C9F.0020.0017.FD8F][.1D0C.0020.001F.FD8F] # ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM +FDB9 ; [.1D0C.0020.0019.FDB9][.1C9F.0020.0019.FDB9][.1D2D.0020.001F.FDB9] # ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM +FCD1 ; [.1D0C.0020.0017.FCD1][.1D0C.0020.0017.FCD1] # ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM +FC89 ; [.1D0C.0020.0019.FC89][.1D0C.0020.0019.FC89] # ARABIC LIGATURE MEEM WITH MEEM FINAL FORM +FC48 ; [.1D0C.0020.001A.FC48][.1D0C.0020.001A.FC48] # ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM +FDB1 ; [.1D0C.0020.0019.FDB1][.1D0C.0020.0019.FDB1][.1D2D.0020.001F.FDB1] # ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM +FC49 ; [.1D0C.0020.001A.FC49][.1D2C.0020.001A.FC49] # ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM +FC4A ; [.1D0C.0020.001A.FC4A][.1D2D.0020.001A.FC4A] # ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM +0765 ; [.1D0D.0020.0002.0765] # ARABIC LETTER MEEM WITH DOT ABOVE +0766 ; [.1D0E.0020.0002.0766] # ARABIC LETTER MEEM WITH DOT BELOW +08A7 ; [.1D0F.0020.0002.08A7] # ARABIC LETTER MEEM WITH THREE DOTS ABOVE +0646 ; [.1D10.0020.0002.0646] # ARABIC LETTER NOON +1EE0D ; [.1D10.0020.0005.1EE0D] # ARABIC MATHEMATICAL NOON +1EE2D ; [.1D10.0020.0005.1EE2D] # ARABIC MATHEMATICAL INITIAL NOON +1EE4D ; [.1D10.0020.0005.1EE4D] # ARABIC MATHEMATICAL TAILED NOON +1EE6D ; [.1D10.0020.0005.1EE6D] # ARABIC MATHEMATICAL STRETCHED NOON +1EE8D ; [.1D10.0020.0005.1EE8D] # ARABIC MATHEMATICAL LOOPED NOON +1EEAD ; [.1D10.0020.0005.1EEAD] # ARABIC MATHEMATICAL DOUBLE-STRUCK NOON +FEE7 ; [.1D10.0020.0017.FEE7] # ARABIC LETTER NOON INITIAL FORM +FEE8 ; [.1D10.0020.0018.FEE8] # ARABIC LETTER NOON MEDIAL FORM +FEE6 ; [.1D10.0020.0019.FEE6] # ARABIC LETTER NOON FINAL FORM +FEE5 ; [.1D10.0020.001A.FEE5] # ARABIC LETTER NOON ISOLATED FORM +FCD2 ; [.1D10.0020.0017.FCD2][.1C97.0020.0017.FCD2] # ARABIC LIGATURE NOON WITH JEEM INITIAL FORM +FC4B ; [.1D10.0020.001A.FC4B][.1C97.0020.001A.FC4B] # ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM +FDB8 ; [.1D10.0020.0017.FDB8][.1C97.0020.0017.FDB8][.1C9E.0020.001F.FDB8] # ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM +FDBD ; [.1D10.0020.0019.FDBD][.1C97.0020.0019.FDBD][.1C9E.0020.001F.FDBD] # ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM +FD98 ; [.1D10.0020.0017.FD98][.1C97.0020.0017.FD98][.1D0C.0020.001F.FD98] # ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM +FD97 ; [.1D10.0020.0019.FD97][.1C97.0020.0019.FD97][.1D0C.0020.001F.FD97] # ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM +FD99 ; [.1D10.0020.0019.FD99][.1C97.0020.0019.FD99][.1D2C.0020.001F.FD99] # ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM +FDC7 ; [.1D10.0020.0019.FDC7][.1C97.0020.0019.FDC7][.1D2D.0020.001F.FDC7] # ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM +FCD3 ; [.1D10.0020.0017.FCD3][.1C9E.0020.0017.FCD3] # ARABIC LIGATURE NOON WITH HAH INITIAL FORM +FC4C ; [.1D10.0020.001A.FC4C][.1C9E.0020.001A.FC4C] # ARABIC LIGATURE NOON WITH HAH ISOLATED FORM +FD95 ; [.1D10.0020.0017.FD95][.1C9E.0020.0017.FD95][.1D0C.0020.001F.FD95] # ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM +FD96 ; [.1D10.0020.0019.FD96][.1C9E.0020.0019.FD96][.1D2C.0020.001F.FD96] # ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM +FDB3 ; [.1D10.0020.0019.FDB3][.1C9E.0020.0019.FDB3][.1D2D.0020.001F.FDB3] # ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM +FCD4 ; [.1D10.0020.0017.FCD4][.1C9F.0020.0017.FCD4] # ARABIC LIGATURE NOON WITH KHAH INITIAL FORM +FC4D ; [.1D10.0020.001A.FC4D][.1C9F.0020.001A.FC4D] # ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM +FC8A ; [.1D10.0020.0019.FC8A][.1CB7.0020.0019.FC8A] # ARABIC LIGATURE NOON WITH REH FINAL FORM +FC8B ; [.1D10.0020.0019.FC8B][.1CB8.0020.0019.FC8B] # ARABIC LIGATURE NOON WITH ZAIN FINAL FORM +FCD5 ; [.1D10.0020.0017.FCD5][.1D0C.0020.0017.FCD5] # ARABIC LIGATURE NOON WITH MEEM INITIAL FORM +FCEE ; [.1D10.0020.0018.FCEE][.1D0C.0020.0018.FCEE] # ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM +FC8C ; [.1D10.0020.0019.FC8C][.1D0C.0020.0019.FC8C] # ARABIC LIGATURE NOON WITH MEEM FINAL FORM +FC4E ; [.1D10.0020.001A.FC4E][.1D0C.0020.001A.FC4E] # ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM +FD9B ; [.1D10.0020.0019.FD9B][.1D0C.0020.0019.FD9B][.1D2C.0020.001F.FD9B] # ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM +FD9A ; [.1D10.0020.0019.FD9A][.1D0C.0020.0019.FD9A][.1D2D.0020.001F.FD9A] # ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM +FC8D ; [.1D10.0020.0019.FC8D][.1D10.0020.0019.FC8D] # ARABIC LIGATURE NOON WITH NOON FINAL FORM +FCD6 ; [.1D10.0020.0017.FCD6][.1D19.0020.0017.FCD6] # ARABIC LIGATURE NOON WITH HEH INITIAL FORM +FCEF ; [.1D10.0020.0018.FCEF][.1D19.0020.0018.FCEF] # ARABIC LIGATURE NOON WITH HEH MEDIAL FORM +FC8E ; [.1D10.0020.0019.FC8E][.1D2C.0020.0019.FC8E] # ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM +FC4F ; [.1D10.0020.001A.FC4F][.1D2C.0020.001A.FC4F] # ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM +FC8F ; [.1D10.0020.0019.FC8F][.1D2D.0020.0019.FC8F] # ARABIC LIGATURE NOON WITH YEH FINAL FORM +FC50 ; [.1D10.0020.001A.FC50][.1D2D.0020.001A.FC50] # ARABIC LIGATURE NOON WITH YEH ISOLATED FORM +06BA ; [.1D11.0020.0002.06BA] # ARABIC LETTER NOON GHUNNA +1EE1D ; [.1D11.0020.0005.1EE1D] # ARABIC MATHEMATICAL DOTLESS NOON +1EE5D ; [.1D11.0020.0005.1EE5D] # ARABIC MATHEMATICAL TAILED DOTLESS NOON +FB9F ; [.1D11.0020.0019.FB9F] # ARABIC LETTER NOON GHUNNA FINAL FORM +FB9E ; [.1D11.0020.001A.FB9E] # ARABIC LETTER NOON GHUNNA ISOLATED FORM +06BB ; [.1D12.0020.0002.06BB] # ARABIC LETTER RNOON +FBA2 ; [.1D12.0020.0017.FBA2] # ARABIC LETTER RNOON INITIAL FORM +FBA3 ; [.1D12.0020.0018.FBA3] # ARABIC LETTER RNOON MEDIAL FORM +FBA1 ; [.1D12.0020.0019.FBA1] # ARABIC LETTER RNOON FINAL FORM +FBA0 ; [.1D12.0020.001A.FBA0] # ARABIC LETTER RNOON ISOLATED FORM +06BC ; [.1D13.0020.0002.06BC] # ARABIC LETTER NOON WITH RING +06BD ; [.1D14.0020.0002.06BD] # ARABIC LETTER NOON WITH THREE DOTS ABOVE +06B9 ; [.1D15.0020.0002.06B9] # ARABIC LETTER NOON WITH DOT BELOW +0767 ; [.1D16.0020.0002.0767] # ARABIC LETTER NOON WITH TWO DOTS BELOW +0768 ; [.1D17.0020.0002.0768] # ARABIC LETTER NOON WITH SMALL TAH +0769 ; [.1D18.0020.0002.0769] # ARABIC LETTER NOON WITH SMALL V +0647 ; [.1D19.0020.0002.0647] # ARABIC LETTER HEH +1EE24 ; [.1D19.0020.0005.1EE24] # ARABIC MATHEMATICAL INITIAL HEH +1EE64 ; [.1D19.0020.0005.1EE64] # ARABIC MATHEMATICAL STRETCHED HEH +1EE84 ; [.1D19.0020.0005.1EE84] # ARABIC MATHEMATICAL LOOPED HEH +FEEB ; [.1D19.0020.0017.FEEB] # ARABIC LETTER HEH INITIAL FORM +FEEC ; [.1D19.0020.0018.FEEC] # ARABIC LETTER HEH MEDIAL FORM +FEEA ; [.1D19.0020.0019.FEEA] # ARABIC LETTER HEH FINAL FORM +FEE9 ; [.1D19.0020.001A.FEE9] # ARABIC LETTER HEH ISOLATED FORM +FCD9 ; [.1D19.0020.0017.FCD9][.0000.00D1.0017.FCD9] # ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM +FCD7 ; [.1D19.0020.0017.FCD7][.1C97.0020.0017.FCD7] # ARABIC LIGATURE HEH WITH JEEM INITIAL FORM +FC51 ; [.1D19.0020.001A.FC51][.1C97.0020.001A.FC51] # ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM +FCD8 ; [.1D19.0020.0017.FCD8][.1D0C.0020.0017.FCD8] # ARABIC LIGATURE HEH WITH MEEM INITIAL FORM +FC52 ; [.1D19.0020.001A.FC52][.1D0C.0020.001A.FC52] # ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM +FD93 ; [.1D19.0020.0017.FD93][.1D0C.0020.0017.FD93][.1C97.0020.001F.FD93] # ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM +FD94 ; [.1D19.0020.0017.FD94][.1D0C.0020.0017.FD94][.1D0C.0020.001F.FD94] # ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM +FC53 ; [.1D19.0020.001A.FC53][.1D2C.0020.001A.FC53] # ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM +FC54 ; [.1D19.0020.001A.FC54][.1D2D.0020.001A.FC54] # ARABIC LIGATURE HEH WITH YEH ISOLATED FORM +06BE ; [.1D1A.0020.0002.06BE] # ARABIC LETTER HEH DOACHASHMEE +FBAC ; [.1D1A.0020.0017.FBAC] # ARABIC LETTER HEH DOACHASHMEE INITIAL FORM +FBAD ; [.1D1A.0020.0018.FBAD] # ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM +FBAB ; [.1D1A.0020.0019.FBAB] # ARABIC LETTER HEH DOACHASHMEE FINAL FORM +FBAA ; [.1D1A.0020.001A.FBAA] # ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM +06C1 ; [.1D1B.0020.0002.06C1] # ARABIC LETTER HEH GOAL +FBA8 ; [.1D1B.0020.0017.FBA8] # ARABIC LETTER HEH GOAL INITIAL FORM +FBA9 ; [.1D1B.0020.0018.FBA9] # ARABIC LETTER HEH GOAL MEDIAL FORM +FBA7 ; [.1D1B.0020.0019.FBA7] # ARABIC LETTER HEH GOAL FINAL FORM +FBA6 ; [.1D1B.0020.001A.FBA6] # ARABIC LETTER HEH GOAL ISOLATED FORM +06C2 ; [.1D1B.0020.0002.06C1][.0000.00BE.0002.0654] # ARABIC LETTER HEH GOAL WITH HAMZA ABOVE +06C3 ; [.1D1C.0020.0002.06C3] # ARABIC LETTER TEH MARBUTA GOAL +06FF ; [.1D1D.0020.0002.06FF] # ARABIC LETTER HEH WITH INVERTED V +06D5 ; [.1D1E.0020.0002.06D5] # ARABIC LETTER AE +06C0 ; [.1D1E.0020.0002.06D5][.0000.00BE.0002.0654] # ARABIC LETTER HEH WITH YEH ABOVE +FBA5 ; [.1D1E.0020.0019.FBA5][.0000.00BE.0019.FBA5] # ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM +FBA4 ; [.1D1E.0020.001A.FBA4][.0000.00BE.001A.FBA4] # ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM +0648 ; [.1D1F.0020.0002.0648] # ARABIC LETTER WAW +06E5 ; [.1D1F.0020.0004.06E5] # ARABIC SMALL WAW +1EE05 ; [.1D1F.0020.0005.1EE05] # ARABIC MATHEMATICAL WAW +1EE85 ; [.1D1F.0020.0005.1EE85] # ARABIC MATHEMATICAL LOOPED WAW +1EEA5 ; [.1D1F.0020.0005.1EEA5] # ARABIC MATHEMATICAL DOUBLE-STRUCK WAW +FEEE ; [.1D1F.0020.0019.FEEE] # ARABIC LETTER WAW FINAL FORM +FEED ; [.1D1F.0020.001A.FEED] # ARABIC LETTER WAW ISOLATED FORM +0676 ; [.1D1F.0020.0004.0676][.1C73.0020.0004.0676] # ARABIC LETTER HIGH HAMZA WAW +FDF8 ; [.1D1F.0020.001A.FDF8][.1CC8.0020.001A.FDF8][.1D05.0020.001F.FDF8][.1D0C.0020.001F.FDF8] # ARABIC LIGATURE WASALLAM ISOLATED FORM +06C4 ; [.1D20.0020.0002.06C4] # ARABIC LETTER WAW WITH RING +06C5 ; [.1D21.0020.0002.06C5] # ARABIC LETTER KIRGHIZ OE +FBE1 ; [.1D21.0020.0019.FBE1] # ARABIC LETTER KIRGHIZ OE FINAL FORM +FBE0 ; [.1D21.0020.001A.FBE0] # ARABIC LETTER KIRGHIZ OE ISOLATED FORM +06C6 ; [.1D22.0020.0002.06C6] # ARABIC LETTER OE +FBDA ; [.1D22.0020.0019.FBDA] # ARABIC LETTER OE FINAL FORM +FBD9 ; [.1D22.0020.001A.FBD9] # ARABIC LETTER OE ISOLATED FORM +06C7 ; [.1D23.0020.0002.06C7] # ARABIC LETTER U +FBD8 ; [.1D23.0020.0019.FBD8] # ARABIC LETTER U FINAL FORM +FBD7 ; [.1D23.0020.001A.FBD7] # ARABIC LETTER U ISOLATED FORM +0677 ; [.1D23.0020.0004.0677][.1C73.0020.0004.0677] # ARABIC LETTER U WITH HAMZA ABOVE +FBDD ; [.1D23.0020.001A.FBDD][.1C73.0020.001A.FBDD] # ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM +06C8 ; [.1D24.0020.0002.06C8] # ARABIC LETTER YU +FBDC ; [.1D24.0020.0019.FBDC] # ARABIC LETTER YU FINAL FORM +FBDB ; [.1D24.0020.001A.FBDB] # ARABIC LETTER YU ISOLATED FORM +06C9 ; [.1D25.0020.0002.06C9] # ARABIC LETTER KIRGHIZ YU +FBE3 ; [.1D25.0020.0019.FBE3] # ARABIC LETTER KIRGHIZ YU FINAL FORM +FBE2 ; [.1D25.0020.001A.FBE2] # ARABIC LETTER KIRGHIZ YU ISOLATED FORM +06CA ; [.1D26.0020.0002.06CA] # ARABIC LETTER WAW WITH TWO DOTS ABOVE +06CB ; [.1D27.0020.0002.06CB] # ARABIC LETTER VE +FBDF ; [.1D27.0020.0019.FBDF] # ARABIC LETTER VE FINAL FORM +FBDE ; [.1D27.0020.001A.FBDE] # ARABIC LETTER VE ISOLATED FORM +06CF ; [.1D28.0020.0002.06CF] # ARABIC LETTER WAW WITH DOT ABOVE +0778 ; [.1D29.0020.0002.0778] # ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE +0779 ; [.1D2A.0020.0002.0779] # ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE +08AB ; [.1D2B.0020.0002.08AB] # ARABIC LETTER WAW WITH DOT WITHIN +0649 ; [.1D2C.0020.0002.0649] # ARABIC LETTER ALEF MAKSURA +FBE8 ; [.1D2C.0020.0017.FBE8] # ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM +FBE9 ; [.1D2C.0020.0018.FBE9] # ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM +FEF0 ; [.1D2C.0020.0019.FEF0] # ARABIC LETTER ALEF MAKSURA FINAL FORM +FEEF ; [.1D2C.0020.001A.FEEF] # ARABIC LETTER ALEF MAKSURA ISOLATED FORM +FC90 ; [.1D2C.0020.0019.FC90][.0000.00D1.0019.FC90] # ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM +FC5D ; [.1D2C.0020.001A.FC5D][.0000.00D1.001A.FC5D] # ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM +064A ; [.1D2D.0020.0002.064A] # ARABIC LETTER YEH +06E6 ; [.1D2D.0020.0004.06E6] # ARABIC SMALL YEH +1EE09 ; [.1D2D.0020.0005.1EE09] # ARABIC MATHEMATICAL YEH +1EE29 ; [.1D2D.0020.0005.1EE29] # ARABIC MATHEMATICAL INITIAL YEH +1EE49 ; [.1D2D.0020.0005.1EE49] # ARABIC MATHEMATICAL TAILED YEH +1EE69 ; [.1D2D.0020.0005.1EE69] # ARABIC MATHEMATICAL STRETCHED YEH +1EE89 ; [.1D2D.0020.0005.1EE89] # ARABIC MATHEMATICAL LOOPED YEH +1EEA9 ; [.1D2D.0020.0005.1EEA9] # ARABIC MATHEMATICAL DOUBLE-STRUCK YEH +FEF3 ; [.1D2D.0020.0017.FEF3] # ARABIC LETTER YEH INITIAL FORM +FEF4 ; [.1D2D.0020.0018.FEF4] # ARABIC LETTER YEH MEDIAL FORM +FEF2 ; [.1D2D.0020.0019.FEF2] # ARABIC LETTER YEH FINAL FORM +FEF1 ; [.1D2D.0020.001A.FEF1] # ARABIC LETTER YEH ISOLATED FORM +0678 ; [.1D2D.0020.0004.0678][.1C73.0020.0004.0678] # ARABIC LETTER HIGH HAMZA YEH +FCDA ; [.1D2D.0020.0017.FCDA][.1C97.0020.0017.FCDA] # ARABIC LIGATURE YEH WITH JEEM INITIAL FORM +FC55 ; [.1D2D.0020.001A.FC55][.1C97.0020.001A.FC55] # ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM +FDAF ; [.1D2D.0020.0019.FDAF][.1C97.0020.0019.FDAF][.1D2D.0020.001F.FDAF] # ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM +FCDB ; [.1D2D.0020.0017.FCDB][.1C9E.0020.0017.FCDB] # ARABIC LIGATURE YEH WITH HAH INITIAL FORM +FC56 ; [.1D2D.0020.001A.FC56][.1C9E.0020.001A.FC56] # ARABIC LIGATURE YEH WITH HAH ISOLATED FORM +FDAE ; [.1D2D.0020.0019.FDAE][.1C9E.0020.0019.FDAE][.1D2D.0020.001F.FDAE] # ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM +FCDC ; [.1D2D.0020.0017.FCDC][.1C9F.0020.0017.FCDC] # ARABIC LIGATURE YEH WITH KHAH INITIAL FORM +FC57 ; [.1D2D.0020.001A.FC57][.1C9F.0020.001A.FC57] # ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM +FC91 ; [.1D2D.0020.0019.FC91][.1CB7.0020.0019.FC91] # ARABIC LIGATURE YEH WITH REH FINAL FORM +FC92 ; [.1D2D.0020.0019.FC92][.1CB8.0020.0019.FC92] # ARABIC LIGATURE YEH WITH ZAIN FINAL FORM +FCDD ; [.1D2D.0020.0017.FCDD][.1D0C.0020.0017.FCDD] # ARABIC LIGATURE YEH WITH MEEM INITIAL FORM +FCF0 ; [.1D2D.0020.0018.FCF0][.1D0C.0020.0018.FCF0] # ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM +FC93 ; [.1D2D.0020.0019.FC93][.1D0C.0020.0019.FC93] # ARABIC LIGATURE YEH WITH MEEM FINAL FORM +FC58 ; [.1D2D.0020.001A.FC58][.1D0C.0020.001A.FC58] # ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM +FD9D ; [.1D2D.0020.0017.FD9D][.1D0C.0020.0017.FD9D][.1D0C.0020.001F.FD9D] # ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM +FD9C ; [.1D2D.0020.0019.FD9C][.1D0C.0020.0019.FD9C][.1D0C.0020.001F.FD9C] # ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM +FDB0 ; [.1D2D.0020.0019.FDB0][.1D0C.0020.0019.FDB0][.1D2D.0020.001F.FDB0] # ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM +FC94 ; [.1D2D.0020.0019.FC94][.1D10.0020.0019.FC94] # ARABIC LIGATURE YEH WITH NOON FINAL FORM +FCDE ; [.1D2D.0020.0017.FCDE][.1D19.0020.0017.FCDE] # ARABIC LIGATURE YEH WITH HEH INITIAL FORM +FCF1 ; [.1D2D.0020.0018.FCF1][.1D19.0020.0018.FCF1] # ARABIC LIGATURE YEH WITH HEH MEDIAL FORM +FC95 ; [.1D2D.0020.0019.FC95][.1D2C.0020.0019.FC95] # ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM +FC59 ; [.1D2D.0020.001A.FC59][.1D2C.0020.001A.FC59] # ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM +FC96 ; [.1D2D.0020.0019.FC96][.1D2D.0020.0019.FC96] # ARABIC LIGATURE YEH WITH YEH FINAL FORM +FC5A ; [.1D2D.0020.001A.FC5A][.1D2D.0020.001A.FC5A] # ARABIC LIGATURE YEH WITH YEH ISOLATED FORM +06CC ; [.1D2E.0020.0002.06CC] # ARABIC LETTER FARSI YEH +FBFE ; [.1D2E.0020.0017.FBFE] # ARABIC LETTER FARSI YEH INITIAL FORM +FBFF ; [.1D2E.0020.0018.FBFF] # ARABIC LETTER FARSI YEH MEDIAL FORM +FBFD ; [.1D2E.0020.0019.FBFD] # ARABIC LETTER FARSI YEH FINAL FORM +FBFC ; [.1D2E.0020.001A.FBFC] # ARABIC LETTER FARSI YEH ISOLATED FORM +06CD ; [.1D2F.0020.0002.06CD] # ARABIC LETTER YEH WITH TAIL +06CE ; [.1D30.0020.0002.06CE] # ARABIC LETTER YEH WITH SMALL V +06D0 ; [.1D31.0020.0002.06D0] # ARABIC LETTER E +FBE6 ; [.1D31.0020.0017.FBE6] # ARABIC LETTER E INITIAL FORM +FBE7 ; [.1D31.0020.0018.FBE7] # ARABIC LETTER E MEDIAL FORM +FBE5 ; [.1D31.0020.0019.FBE5] # ARABIC LETTER E FINAL FORM +FBE4 ; [.1D31.0020.001A.FBE4] # ARABIC LETTER E ISOLATED FORM +06D1 ; [.1D32.0020.0002.06D1] # ARABIC LETTER YEH WITH THREE DOTS BELOW +063D ; [.1D33.0020.0002.063D] # ARABIC LETTER FARSI YEH WITH INVERTED V +063E ; [.1D34.0020.0002.063E] # ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE +063F ; [.1D35.0020.0002.063F] # ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE +0620 ; [.1D36.0020.0002.0620] # ARABIC LETTER KASHMIRI YEH +0775 ; [.1D37.0020.0002.0775] # ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE +0776 ; [.1D38.0020.0002.0776] # ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE +0777 ; [.1D39.0020.0002.0777] # ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW +06D2 ; [.1D3A.0020.0002.06D2] # ARABIC LETTER YEH BARREE +FBAF ; [.1D3A.0020.0019.FBAF] # ARABIC LETTER YEH BARREE FINAL FORM +FBAE ; [.1D3A.0020.001A.FBAE] # ARABIC LETTER YEH BARREE ISOLATED FORM +06D3 ; [.1D3A.0020.0002.06D2][.0000.00BE.0002.0654] # ARABIC LETTER YEH BARREE WITH HAMZA ABOVE +FBB1 ; [.1D3A.0020.0019.FBB1][.0000.00BE.0019.FBB1] # ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM +FBB0 ; [.1D3A.0020.001A.FBB0][.0000.00BE.001A.FBB0] # ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM +077A ; [.1D3B.0020.0002.077A] # ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE +077B ; [.1D3C.0020.0002.077B] # ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE +0710 ; [.1D3D.0020.0002.0710] # SYRIAC LETTER ALAPH +0712 ; [.1D3E.0020.0002.0712] # SYRIAC LETTER BETH +072D ; [.1D3E.0020.0004.072D][.0000.013C.0004.072D] # SYRIAC LETTER PERSIAN BHETH +0713 ; [.1D3F.0020.0002.0713] # SYRIAC LETTER GAMAL +0714 ; [.1D3F.0020.0004.0714][.0000.013A.0004.0714] # SYRIAC LETTER GAMAL GARSHUNI +072E ; [.1D3F.0020.0004.072E][.0000.013C.0004.072E] # SYRIAC LETTER PERSIAN GHAMAL +0716 ; [.1D40.0020.0002.0716] # SYRIAC LETTER DOTLESS DALATH RISH +0715 ; [.1D41.0020.0002.0715] # SYRIAC LETTER DALATH +072F ; [.1D41.0020.0004.072F][.0000.013C.0004.072F] # SYRIAC LETTER PERSIAN DHALATH +0717 ; [.1D42.0020.0002.0717] # SYRIAC LETTER HE +0718 ; [.1D43.0020.0002.0718] # SYRIAC LETTER WAW +0719 ; [.1D44.0020.0002.0719] # SYRIAC LETTER ZAIN +074D ; [.1D45.0020.0002.074D] # SYRIAC LETTER SOGDIAN ZHAIN +071A ; [.1D46.0020.0002.071A] # SYRIAC LETTER HETH +071B ; [.1D47.0020.0002.071B] # SYRIAC LETTER TETH +071C ; [.1D47.0020.0004.071C][.0000.013A.0004.071C] # SYRIAC LETTER TETH GARSHUNI +071D ; [.1D48.0020.0002.071D] # SYRIAC LETTER YUDH +071E ; [.1D49.0020.0002.071E] # SYRIAC LETTER YUDH HE +071F ; [.1D4A.0020.0002.071F] # SYRIAC LETTER KAPH +074E ; [.1D4B.0020.0002.074E] # SYRIAC LETTER SOGDIAN KHAPH +0720 ; [.1D4C.0020.0002.0720] # SYRIAC LETTER LAMADH +0721 ; [.1D4D.0020.0002.0721] # SYRIAC LETTER MIM +0722 ; [.1D4E.0020.0002.0722] # SYRIAC LETTER NUN +0723 ; [.1D4F.0020.0002.0723] # SYRIAC LETTER SEMKATH +0724 ; [.1D4F.0020.0019.0724] # SYRIAC LETTER FINAL SEMKATH +0725 ; [.1D50.0020.0002.0725] # SYRIAC LETTER E +0726 ; [.1D51.0020.0002.0726] # SYRIAC LETTER PE +0727 ; [.1D51.0020.0004.0727][.0000.013A.0004.0727] # SYRIAC LETTER REVERSED PE +074F ; [.1D52.0020.0002.074F] # SYRIAC LETTER SOGDIAN FE +0728 ; [.1D53.0020.0002.0728] # SYRIAC LETTER SADHE +0729 ; [.1D54.0020.0002.0729] # SYRIAC LETTER QAPH +072A ; [.1D55.0020.0002.072A] # SYRIAC LETTER RISH +072B ; [.1D56.0020.0002.072B] # SYRIAC LETTER SHIN +072C ; [.1D57.0020.0002.072C] # SYRIAC LETTER TAW +0840 ; [.1D58.0020.0002.0840] # MANDAIC LETTER HALQA +0841 ; [.1D59.0020.0002.0841] # MANDAIC LETTER AB +0842 ; [.1D5A.0020.0002.0842] # MANDAIC LETTER AG +0843 ; [.1D5B.0020.0002.0843] # MANDAIC LETTER AD +0844 ; [.1D5C.0020.0002.0844] # MANDAIC LETTER AH +0845 ; [.1D5D.0020.0002.0845] # MANDAIC LETTER USHENNA +0846 ; [.1D5E.0020.0002.0846] # MANDAIC LETTER AZ +0847 ; [.1D5F.0020.0002.0847] # MANDAIC LETTER IT +0848 ; [.1D60.0020.0002.0848] # MANDAIC LETTER ATT +0849 ; [.1D61.0020.0002.0849] # MANDAIC LETTER AKSA +084A ; [.1D62.0020.0002.084A] # MANDAIC LETTER AK +084B ; [.1D63.0020.0002.084B] # MANDAIC LETTER AL +084C ; [.1D64.0020.0002.084C] # MANDAIC LETTER AM +084D ; [.1D65.0020.0002.084D] # MANDAIC LETTER AN +084E ; [.1D66.0020.0002.084E] # MANDAIC LETTER AS +084F ; [.1D67.0020.0002.084F] # MANDAIC LETTER IN +0850 ; [.1D68.0020.0002.0850] # MANDAIC LETTER AP +0851 ; [.1D69.0020.0002.0851] # MANDAIC LETTER ASZ +0852 ; [.1D6A.0020.0002.0852] # MANDAIC LETTER AQ +0853 ; [.1D6B.0020.0002.0853] # MANDAIC LETTER AR +0854 ; [.1D6C.0020.0002.0854] # MANDAIC LETTER ASH +0855 ; [.1D6D.0020.0002.0855] # MANDAIC LETTER AT +0856 ; [.1D6E.0020.0002.0856] # MANDAIC LETTER DUSHENNA +0857 ; [.1D6F.0020.0002.0857] # MANDAIC LETTER KAD +0858 ; [.1D70.0020.0002.0858] # MANDAIC LETTER AIN +0780 ; [.1D71.0020.0002.0780] # THAANA LETTER HAA +0799 ; [.1D72.0020.0002.0799] # THAANA LETTER HHAA +079A ; [.1D73.0020.0002.079A] # THAANA LETTER KHAA +0781 ; [.1D74.0020.0002.0781] # THAANA LETTER SHAVIYANI +0782 ; [.1D75.0020.0002.0782] # THAANA LETTER NOONU +0783 ; [.1D76.0020.0002.0783] # THAANA LETTER RAA +079C ; [.1D77.0020.0002.079C] # THAANA LETTER ZAA +0784 ; [.1D78.0020.0002.0784] # THAANA LETTER BAA +0785 ; [.1D79.0020.0002.0785] # THAANA LETTER LHAVIYANI +0786 ; [.1D7A.0020.0002.0786] # THAANA LETTER KAAFU +0787 ; [.1D7B.0020.0002.0787] # THAANA LETTER ALIFU +07A2 ; [.1D7C.0020.0002.07A2] # THAANA LETTER AINU +07A3 ; [.1D7D.0020.0002.07A3] # THAANA LETTER GHAINU +0788 ; [.1D7E.0020.0002.0788] # THAANA LETTER VAAVU +07A5 ; [.1D7F.0020.0002.07A5] # THAANA LETTER WAAVU +0789 ; [.1D80.0020.0002.0789] # THAANA LETTER MEEMU +078A ; [.1D81.0020.0002.078A] # THAANA LETTER FAAFU +078B ; [.1D82.0020.0002.078B] # THAANA LETTER DHAALU +079B ; [.1D83.0020.0002.079B] # THAANA LETTER THAALU +078C ; [.1D84.0020.0002.078C] # THAANA LETTER THAA +0798 ; [.1D85.0020.0002.0798] # THAANA LETTER TTAA +07A0 ; [.1D86.0020.0002.07A0] # THAANA LETTER TO +07A1 ; [.1D87.0020.0002.07A1] # THAANA LETTER ZO +078D ; [.1D88.0020.0002.078D] # THAANA LETTER LAAMU +078E ; [.1D89.0020.0002.078E] # THAANA LETTER GAAFU +07A4 ; [.1D8A.0020.0002.07A4] # THAANA LETTER QAAFU +078F ; [.1D8B.0020.0002.078F] # THAANA LETTER GNAVIYANI +0790 ; [.1D8C.0020.0002.0790] # THAANA LETTER SEENU +079D ; [.1D8D.0020.0002.079D] # THAANA LETTER SHEENU +079E ; [.1D8E.0020.0002.079E] # THAANA LETTER SAADHU +079F ; [.1D8F.0020.0002.079F] # THAANA LETTER DAADHU +0791 ; [.1D90.0020.0002.0791] # THAANA LETTER DAVIYANI +0792 ; [.1D91.0020.0002.0792] # THAANA LETTER ZAVIYANI +0793 ; [.1D92.0020.0002.0793] # THAANA LETTER TAVIYANI +0794 ; [.1D93.0020.0002.0794] # THAANA LETTER YAA +0795 ; [.1D94.0020.0002.0795] # THAANA LETTER PAVIYANI +0796 ; [.1D95.0020.0002.0796] # THAANA LETTER JAVIYANI +0797 ; [.1D96.0020.0002.0797] # THAANA LETTER CHAVIYANI +07B1 ; [.1D97.0020.0002.07B1] # THAANA LETTER NAA +07A6 ; [.1D98.0020.0002.07A6] # THAANA ABAFILI +07A7 ; [.1D99.0020.0002.07A7] # THAANA AABAAFILI +07A8 ; [.1D9A.0020.0002.07A8] # THAANA IBIFILI +07A9 ; [.1D9B.0020.0002.07A9] # THAANA EEBEEFILI +07AA ; [.1D9C.0020.0002.07AA] # THAANA UBUFILI +07AB ; [.1D9D.0020.0002.07AB] # THAANA OOBOOFILI +07AC ; [.1D9E.0020.0002.07AC] # THAANA EBEFILI +07AD ; [.1D9F.0020.0002.07AD] # THAANA EYBEYFILI +07AE ; [.1DA0.0020.0002.07AE] # THAANA OBOFILI +07AF ; [.1DA1.0020.0002.07AF] # THAANA OABOAFILI +07B0 ; [.1DA2.0020.0002.07B0] # THAANA SUKUN +07CA ; [.1DA3.0020.0002.07CA] # NKO LETTER A +07CB ; [.1DA4.0020.0002.07CB] # NKO LETTER EE +07CC ; [.1DA5.0020.0002.07CC] # NKO LETTER I +07CD ; [.1DA6.0020.0002.07CD] # NKO LETTER E +07CE ; [.1DA7.0020.0002.07CE] # NKO LETTER U +07CF ; [.1DA8.0020.0002.07CF] # NKO LETTER OO +07D0 ; [.1DA9.0020.0002.07D0] # NKO LETTER O +07D1 ; [.1DAA.0020.0002.07D1] # NKO LETTER DAGBASINNA +07D2 ; [.1DAB.0020.0002.07D2] # NKO LETTER N +07D3 ; [.1DAC.0020.0002.07D3] # NKO LETTER BA +07D4 ; [.1DAD.0020.0002.07D4] # NKO LETTER PA +07D5 ; [.1DAE.0020.0002.07D5] # NKO LETTER TA +07D6 ; [.1DAF.0020.0002.07D6] # NKO LETTER JA +07E8 ; [.1DAF.0020.0004.07E8][.0000.0139.0004.07E8] # NKO LETTER JONA JA +07D7 ; [.1DB0.0020.0002.07D7] # NKO LETTER CHA +07E9 ; [.1DB0.0020.0004.07E9][.0000.0139.0004.07E9] # NKO LETTER JONA CHA +07D8 ; [.1DB1.0020.0002.07D8] # NKO LETTER DA +07D9 ; [.1DB2.0020.0002.07D9] # NKO LETTER RA +07EA ; [.1DB2.0020.0004.07EA][.0000.0139.0004.07EA] # NKO LETTER JONA RA +07DA ; [.1DB3.0020.0002.07DA] # NKO LETTER RRA +07DB ; [.1DB4.0020.0002.07DB] # NKO LETTER SA +07DC ; [.1DB5.0020.0002.07DC] # NKO LETTER GBA +07DD ; [.1DB6.0020.0002.07DD] # NKO LETTER FA +07DE ; [.1DB7.0020.0002.07DE] # NKO LETTER KA +07DF ; [.1DB8.0020.0002.07DF] # NKO LETTER LA +07E0 ; [.1DB9.0020.0002.07E0] # NKO LETTER NA WOLOSO +07E1 ; [.1DBA.0020.0002.07E1] # NKO LETTER MA +07E2 ; [.1DBB.0020.0002.07E2] # NKO LETTER NYA +07E3 ; [.1DBC.0020.0002.07E3] # NKO LETTER NA +07E4 ; [.1DBD.0020.0002.07E4] # NKO LETTER HA +07E5 ; [.1DBE.0020.0002.07E5] # NKO LETTER WA +07E6 ; [.1DBF.0020.0002.07E6] # NKO LETTER YA +07E7 ; [.1DC0.0020.0002.07E7] # NKO LETTER NYA WOLOSO +07F4 ; [.1DC1.0020.0002.07F4] # NKO HIGH TONE APOSTROPHE +07F5 ; [.1DC2.0020.0002.07F5] # NKO LOW TONE APOSTROPHE +2D30 ; [.1DC3.0020.0002.2D30] # TIFINAGH LETTER YA +2D31 ; [.1DC4.0020.0002.2D31] # TIFINAGH LETTER YAB +2D32 ; [.1DC5.0020.0002.2D32] # TIFINAGH LETTER YABH +2D33 ; [.1DC6.0020.0002.2D33] # TIFINAGH LETTER YAG +2D34 ; [.1DC7.0020.0002.2D34] # TIFINAGH LETTER YAGHH +2D35 ; [.1DC8.0020.0002.2D35] # TIFINAGH LETTER BERBER ACADEMY YAJ +2D36 ; [.1DC9.0020.0002.2D36] # TIFINAGH LETTER YAJ +2D37 ; [.1DCA.0020.0002.2D37] # TIFINAGH LETTER YAD +2D38 ; [.1DCB.0020.0002.2D38] # TIFINAGH LETTER YADH +2D39 ; [.1DCC.0020.0002.2D39] # TIFINAGH LETTER YADD +2D3A ; [.1DCD.0020.0002.2D3A] # TIFINAGH LETTER YADDH +2D3B ; [.1DCE.0020.0002.2D3B] # TIFINAGH LETTER YEY +2D66 ; [.1DCF.0020.0002.2D66] # TIFINAGH LETTER YE +2D3C ; [.1DD0.0020.0002.2D3C] # TIFINAGH LETTER YAF +2D3D ; [.1DD1.0020.0002.2D3D] # TIFINAGH LETTER YAK +2D3E ; [.1DD2.0020.0002.2D3E] # TIFINAGH LETTER TUAREG YAK +2D3F ; [.1DD3.0020.0002.2D3F] # TIFINAGH LETTER YAKHH +2D40 ; [.1DD4.0020.0002.2D40] # TIFINAGH LETTER YAH +2D41 ; [.1DD5.0020.0002.2D41] # TIFINAGH LETTER BERBER ACADEMY YAH +2D42 ; [.1DD6.0020.0002.2D42] # TIFINAGH LETTER TUAREG YAH +2D43 ; [.1DD7.0020.0002.2D43] # TIFINAGH LETTER YAHH +2D44 ; [.1DD8.0020.0002.2D44] # TIFINAGH LETTER YAA +2D45 ; [.1DD9.0020.0002.2D45] # TIFINAGH LETTER YAKH +2D46 ; [.1DDA.0020.0002.2D46] # TIFINAGH LETTER TUAREG YAKH +2D47 ; [.1DDB.0020.0002.2D47] # TIFINAGH LETTER YAQ +2D48 ; [.1DDC.0020.0002.2D48] # TIFINAGH LETTER TUAREG YAQ +2D49 ; [.1DDD.0020.0002.2D49] # TIFINAGH LETTER YI +2D4A ; [.1DDE.0020.0002.2D4A] # TIFINAGH LETTER YAZH +2D4B ; [.1DDF.0020.0002.2D4B] # TIFINAGH LETTER AHAGGAR YAZH +2D4C ; [.1DE0.0020.0002.2D4C] # TIFINAGH LETTER TUAREG YAZH +2D4D ; [.1DE1.0020.0002.2D4D] # TIFINAGH LETTER YAL +2D4E ; [.1DE2.0020.0002.2D4E] # TIFINAGH LETTER YAM +2D4F ; [.1DE3.0020.0002.2D4F] # TIFINAGH LETTER YAN +2D50 ; [.1DE4.0020.0002.2D50] # TIFINAGH LETTER TUAREG YAGN +2D51 ; [.1DE5.0020.0002.2D51] # TIFINAGH LETTER TUAREG YANG +2D52 ; [.1DE6.0020.0002.2D52] # TIFINAGH LETTER YAP +2D53 ; [.1DE7.0020.0002.2D53] # TIFINAGH LETTER YU +2D67 ; [.1DE8.0020.0002.2D67] # TIFINAGH LETTER YO +2D54 ; [.1DE9.0020.0002.2D54] # TIFINAGH LETTER YAR +2D55 ; [.1DEA.0020.0002.2D55] # TIFINAGH LETTER YARR +2D56 ; [.1DEB.0020.0002.2D56] # TIFINAGH LETTER YAGH +2D57 ; [.1DEC.0020.0002.2D57] # TIFINAGH LETTER TUAREG YAGH +2D58 ; [.1DED.0020.0002.2D58] # TIFINAGH LETTER AYER YAGH +2D59 ; [.1DEE.0020.0002.2D59] # TIFINAGH LETTER YAS +2D5A ; [.1DEF.0020.0002.2D5A] # TIFINAGH LETTER YASS +2D5B ; [.1DF0.0020.0002.2D5B] # TIFINAGH LETTER YASH +2D5C ; [.1DF1.0020.0002.2D5C] # TIFINAGH LETTER YAT +2D5D ; [.1DF2.0020.0002.2D5D] # TIFINAGH LETTER YATH +2D5E ; [.1DF3.0020.0002.2D5E] # TIFINAGH LETTER YACH +2D5F ; [.1DF4.0020.0002.2D5F] # TIFINAGH LETTER YATT +2D60 ; [.1DF5.0020.0002.2D60] # TIFINAGH LETTER YAV +2D61 ; [.1DF6.0020.0002.2D61] # TIFINAGH LETTER YAW +2D62 ; [.1DF7.0020.0002.2D62] # TIFINAGH LETTER YAY +2D63 ; [.1DF8.0020.0002.2D63] # TIFINAGH LETTER YAZ +2D64 ; [.1DF9.0020.0002.2D64] # TIFINAGH LETTER TAWELLEMET YAZ +2D65 ; [.1DFA.0020.0002.2D65] # TIFINAGH LETTER YAZZ +2D6F ; [.1DFB.0020.0002.2D6F] # TIFINAGH MODIFIER LETTER LABIALIZATION MARK +1200 ; [.1DFC.0020.0002.1200] # ETHIOPIC SYLLABLE HA +1201 ; [.1DFD.0020.0002.1201] # ETHIOPIC SYLLABLE HU +1202 ; [.1DFE.0020.0002.1202] # ETHIOPIC SYLLABLE HI +1203 ; [.1DFF.0020.0002.1203] # ETHIOPIC SYLLABLE HAA +1204 ; [.1E00.0020.0002.1204] # ETHIOPIC SYLLABLE HEE +1205 ; [.1E01.0020.0002.1205] # ETHIOPIC SYLLABLE HE +1206 ; [.1E02.0020.0002.1206] # ETHIOPIC SYLLABLE HO +1207 ; [.1E03.0020.0002.1207] # ETHIOPIC SYLLABLE HOA +1208 ; [.1E04.0020.0002.1208] # ETHIOPIC SYLLABLE LA +1209 ; [.1E05.0020.0002.1209] # ETHIOPIC SYLLABLE LU +120A ; [.1E06.0020.0002.120A] # ETHIOPIC SYLLABLE LI +120B ; [.1E07.0020.0002.120B] # ETHIOPIC SYLLABLE LAA +120C ; [.1E08.0020.0002.120C] # ETHIOPIC SYLLABLE LEE +120D ; [.1E09.0020.0002.120D] # ETHIOPIC SYLLABLE LE +120E ; [.1E0A.0020.0002.120E] # ETHIOPIC SYLLABLE LO +120F ; [.1E0B.0020.0002.120F] # ETHIOPIC SYLLABLE LWA +2D80 ; [.1E0C.0020.0002.2D80] # ETHIOPIC SYLLABLE LOA +1210 ; [.1E0D.0020.0002.1210] # ETHIOPIC SYLLABLE HHA +1211 ; [.1E0E.0020.0002.1211] # ETHIOPIC SYLLABLE HHU +1212 ; [.1E0F.0020.0002.1212] # ETHIOPIC SYLLABLE HHI +1213 ; [.1E10.0020.0002.1213] # ETHIOPIC SYLLABLE HHAA +1214 ; [.1E11.0020.0002.1214] # ETHIOPIC SYLLABLE HHEE +1215 ; [.1E12.0020.0002.1215] # ETHIOPIC SYLLABLE HHE +1216 ; [.1E13.0020.0002.1216] # ETHIOPIC SYLLABLE HHO +1217 ; [.1E14.0020.0002.1217] # ETHIOPIC SYLLABLE HHWA +1218 ; [.1E15.0020.0002.1218] # ETHIOPIC SYLLABLE MA +1219 ; [.1E16.0020.0002.1219] # ETHIOPIC SYLLABLE MU +121A ; [.1E17.0020.0002.121A] # ETHIOPIC SYLLABLE MI +121B ; [.1E18.0020.0002.121B] # ETHIOPIC SYLLABLE MAA +121C ; [.1E19.0020.0002.121C] # ETHIOPIC SYLLABLE MEE +121D ; [.1E1A.0020.0002.121D] # ETHIOPIC SYLLABLE ME +121E ; [.1E1B.0020.0002.121E] # ETHIOPIC SYLLABLE MO +121F ; [.1E1C.0020.0002.121F] # ETHIOPIC SYLLABLE MWA +1380 ; [.1E1D.0020.0002.1380] # ETHIOPIC SYLLABLE SEBATBEIT MWA +1381 ; [.1E1E.0020.0002.1381] # ETHIOPIC SYLLABLE MWI +1382 ; [.1E1F.0020.0002.1382] # ETHIOPIC SYLLABLE MWEE +1383 ; [.1E20.0020.0002.1383] # ETHIOPIC SYLLABLE MWE +2D81 ; [.1E21.0020.0002.2D81] # ETHIOPIC SYLLABLE MOA +1220 ; [.1E22.0020.0002.1220] # ETHIOPIC SYLLABLE SZA +1221 ; [.1E23.0020.0002.1221] # ETHIOPIC SYLLABLE SZU +1222 ; [.1E24.0020.0002.1222] # ETHIOPIC SYLLABLE SZI +1223 ; [.1E25.0020.0002.1223] # ETHIOPIC SYLLABLE SZAA +1224 ; [.1E26.0020.0002.1224] # ETHIOPIC SYLLABLE SZEE +1225 ; [.1E27.0020.0002.1225] # ETHIOPIC SYLLABLE SZE +1226 ; [.1E28.0020.0002.1226] # ETHIOPIC SYLLABLE SZO +1227 ; [.1E29.0020.0002.1227] # ETHIOPIC SYLLABLE SZWA +1228 ; [.1E2A.0020.0002.1228] # ETHIOPIC SYLLABLE RA +1229 ; [.1E2B.0020.0002.1229] # ETHIOPIC SYLLABLE RU +122A ; [.1E2C.0020.0002.122A] # ETHIOPIC SYLLABLE RI +122B ; [.1E2D.0020.0002.122B] # ETHIOPIC SYLLABLE RAA +122C ; [.1E2E.0020.0002.122C] # ETHIOPIC SYLLABLE REE +122D ; [.1E2F.0020.0002.122D] # ETHIOPIC SYLLABLE RE +122E ; [.1E30.0020.0002.122E] # ETHIOPIC SYLLABLE RO +122F ; [.1E31.0020.0002.122F] # ETHIOPIC SYLLABLE RWA +2D82 ; [.1E32.0020.0002.2D82] # ETHIOPIC SYLLABLE ROA +1230 ; [.1E33.0020.0002.1230] # ETHIOPIC SYLLABLE SA +1231 ; [.1E34.0020.0002.1231] # ETHIOPIC SYLLABLE SU +1232 ; [.1E35.0020.0002.1232] # ETHIOPIC SYLLABLE SI +1233 ; [.1E36.0020.0002.1233] # ETHIOPIC SYLLABLE SAA +1234 ; [.1E37.0020.0002.1234] # ETHIOPIC SYLLABLE SEE +1235 ; [.1E38.0020.0002.1235] # ETHIOPIC SYLLABLE SE +1236 ; [.1E39.0020.0002.1236] # ETHIOPIC SYLLABLE SO +1237 ; [.1E3A.0020.0002.1237] # ETHIOPIC SYLLABLE SWA +2D83 ; [.1E3B.0020.0002.2D83] # ETHIOPIC SYLLABLE SOA +AB01 ; [.1E3C.0020.0002.AB01] # ETHIOPIC SYLLABLE TTHU +AB02 ; [.1E3D.0020.0002.AB02] # ETHIOPIC SYLLABLE TTHI +AB03 ; [.1E3E.0020.0002.AB03] # ETHIOPIC SYLLABLE TTHAA +AB04 ; [.1E3F.0020.0002.AB04] # ETHIOPIC SYLLABLE TTHEE +AB05 ; [.1E40.0020.0002.AB05] # ETHIOPIC SYLLABLE TTHE +AB06 ; [.1E41.0020.0002.AB06] # ETHIOPIC SYLLABLE TTHO +1238 ; [.1E42.0020.0002.1238] # ETHIOPIC SYLLABLE SHA +1239 ; [.1E43.0020.0002.1239] # ETHIOPIC SYLLABLE SHU +123A ; [.1E44.0020.0002.123A] # ETHIOPIC SYLLABLE SHI +123B ; [.1E45.0020.0002.123B] # ETHIOPIC SYLLABLE SHAA +123C ; [.1E46.0020.0002.123C] # ETHIOPIC SYLLABLE SHEE +123D ; [.1E47.0020.0002.123D] # ETHIOPIC SYLLABLE SHE +123E ; [.1E48.0020.0002.123E] # ETHIOPIC SYLLABLE SHO +123F ; [.1E49.0020.0002.123F] # ETHIOPIC SYLLABLE SHWA +2D84 ; [.1E4A.0020.0002.2D84] # ETHIOPIC SYLLABLE SHOA +1240 ; [.1E4B.0020.0002.1240] # ETHIOPIC SYLLABLE QA +1241 ; [.1E4C.0020.0002.1241] # ETHIOPIC SYLLABLE QU +1242 ; [.1E4D.0020.0002.1242] # ETHIOPIC SYLLABLE QI +1243 ; [.1E4E.0020.0002.1243] # ETHIOPIC SYLLABLE QAA +1244 ; [.1E4F.0020.0002.1244] # ETHIOPIC SYLLABLE QEE +1245 ; [.1E50.0020.0002.1245] # ETHIOPIC SYLLABLE QE +1246 ; [.1E51.0020.0002.1246] # ETHIOPIC SYLLABLE QO +1247 ; [.1E52.0020.0002.1247] # ETHIOPIC SYLLABLE QOA +1248 ; [.1E53.0020.0002.1248] # ETHIOPIC SYLLABLE QWA +124A ; [.1E54.0020.0002.124A] # ETHIOPIC SYLLABLE QWI +124B ; [.1E55.0020.0002.124B] # ETHIOPIC SYLLABLE QWAA +124C ; [.1E56.0020.0002.124C] # ETHIOPIC SYLLABLE QWEE +124D ; [.1E57.0020.0002.124D] # ETHIOPIC SYLLABLE QWE +1250 ; [.1E58.0020.0002.1250] # ETHIOPIC SYLLABLE QHA +1251 ; [.1E59.0020.0002.1251] # ETHIOPIC SYLLABLE QHU +1252 ; [.1E5A.0020.0002.1252] # ETHIOPIC SYLLABLE QHI +1253 ; [.1E5B.0020.0002.1253] # ETHIOPIC SYLLABLE QHAA +1254 ; [.1E5C.0020.0002.1254] # ETHIOPIC SYLLABLE QHEE +1255 ; [.1E5D.0020.0002.1255] # ETHIOPIC SYLLABLE QHE +1256 ; [.1E5E.0020.0002.1256] # ETHIOPIC SYLLABLE QHO +1258 ; [.1E5F.0020.0002.1258] # ETHIOPIC SYLLABLE QHWA +125A ; [.1E60.0020.0002.125A] # ETHIOPIC SYLLABLE QHWI +125B ; [.1E61.0020.0002.125B] # ETHIOPIC SYLLABLE QHWAA +125C ; [.1E62.0020.0002.125C] # ETHIOPIC SYLLABLE QHWEE +125D ; [.1E63.0020.0002.125D] # ETHIOPIC SYLLABLE QHWE +1260 ; [.1E64.0020.0002.1260] # ETHIOPIC SYLLABLE BA +1261 ; [.1E65.0020.0002.1261] # ETHIOPIC SYLLABLE BU +1262 ; [.1E66.0020.0002.1262] # ETHIOPIC SYLLABLE BI +1263 ; [.1E67.0020.0002.1263] # ETHIOPIC SYLLABLE BAA +1264 ; [.1E68.0020.0002.1264] # ETHIOPIC SYLLABLE BEE +1265 ; [.1E69.0020.0002.1265] # ETHIOPIC SYLLABLE BE +1266 ; [.1E6A.0020.0002.1266] # ETHIOPIC SYLLABLE BO +1267 ; [.1E6B.0020.0002.1267] # ETHIOPIC SYLLABLE BWA +1384 ; [.1E6C.0020.0002.1384] # ETHIOPIC SYLLABLE SEBATBEIT BWA +1385 ; [.1E6D.0020.0002.1385] # ETHIOPIC SYLLABLE BWI +1386 ; [.1E6E.0020.0002.1386] # ETHIOPIC SYLLABLE BWEE +1387 ; [.1E6F.0020.0002.1387] # ETHIOPIC SYLLABLE BWE +2D85 ; [.1E70.0020.0002.2D85] # ETHIOPIC SYLLABLE BOA +1268 ; [.1E71.0020.0002.1268] # ETHIOPIC SYLLABLE VA +1269 ; [.1E72.0020.0002.1269] # ETHIOPIC SYLLABLE VU +126A ; [.1E73.0020.0002.126A] # ETHIOPIC SYLLABLE VI +126B ; [.1E74.0020.0002.126B] # ETHIOPIC SYLLABLE VAA +126C ; [.1E75.0020.0002.126C] # ETHIOPIC SYLLABLE VEE +126D ; [.1E76.0020.0002.126D] # ETHIOPIC SYLLABLE VE +126E ; [.1E77.0020.0002.126E] # ETHIOPIC SYLLABLE VO +126F ; [.1E78.0020.0002.126F] # ETHIOPIC SYLLABLE VWA +1270 ; [.1E79.0020.0002.1270] # ETHIOPIC SYLLABLE TA +1271 ; [.1E7A.0020.0002.1271] # ETHIOPIC SYLLABLE TU +1272 ; [.1E7B.0020.0002.1272] # ETHIOPIC SYLLABLE TI +1273 ; [.1E7C.0020.0002.1273] # ETHIOPIC SYLLABLE TAA +1274 ; [.1E7D.0020.0002.1274] # ETHIOPIC SYLLABLE TEE +1275 ; [.1E7E.0020.0002.1275] # ETHIOPIC SYLLABLE TE +1276 ; [.1E7F.0020.0002.1276] # ETHIOPIC SYLLABLE TO +1277 ; [.1E80.0020.0002.1277] # ETHIOPIC SYLLABLE TWA +2D86 ; [.1E81.0020.0002.2D86] # ETHIOPIC SYLLABLE TOA +1278 ; [.1E82.0020.0002.1278] # ETHIOPIC SYLLABLE CA +1279 ; [.1E83.0020.0002.1279] # ETHIOPIC SYLLABLE CU +127A ; [.1E84.0020.0002.127A] # ETHIOPIC SYLLABLE CI +127B ; [.1E85.0020.0002.127B] # ETHIOPIC SYLLABLE CAA +127C ; [.1E86.0020.0002.127C] # ETHIOPIC SYLLABLE CEE +127D ; [.1E87.0020.0002.127D] # ETHIOPIC SYLLABLE CE +127E ; [.1E88.0020.0002.127E] # ETHIOPIC SYLLABLE CO +127F ; [.1E89.0020.0002.127F] # ETHIOPIC SYLLABLE CWA +2D87 ; [.1E8A.0020.0002.2D87] # ETHIOPIC SYLLABLE COA +1280 ; [.1E8B.0020.0002.1280] # ETHIOPIC SYLLABLE XA +1281 ; [.1E8C.0020.0002.1281] # ETHIOPIC SYLLABLE XU +1282 ; [.1E8D.0020.0002.1282] # ETHIOPIC SYLLABLE XI +1283 ; [.1E8E.0020.0002.1283] # ETHIOPIC SYLLABLE XAA +1284 ; [.1E8F.0020.0002.1284] # ETHIOPIC SYLLABLE XEE +1285 ; [.1E90.0020.0002.1285] # ETHIOPIC SYLLABLE XE +1286 ; [.1E91.0020.0002.1286] # ETHIOPIC SYLLABLE XO +1287 ; [.1E92.0020.0002.1287] # ETHIOPIC SYLLABLE XOA +1288 ; [.1E93.0020.0002.1288] # ETHIOPIC SYLLABLE XWA +128A ; [.1E94.0020.0002.128A] # ETHIOPIC SYLLABLE XWI +128B ; [.1E95.0020.0002.128B] # ETHIOPIC SYLLABLE XWAA +128C ; [.1E96.0020.0002.128C] # ETHIOPIC SYLLABLE XWEE +128D ; [.1E97.0020.0002.128D] # ETHIOPIC SYLLABLE XWE +1290 ; [.1E98.0020.0002.1290] # ETHIOPIC SYLLABLE NA +1291 ; [.1E99.0020.0002.1291] # ETHIOPIC SYLLABLE NU +1292 ; [.1E9A.0020.0002.1292] # ETHIOPIC SYLLABLE NI +1293 ; [.1E9B.0020.0002.1293] # ETHIOPIC SYLLABLE NAA +1294 ; [.1E9C.0020.0002.1294] # ETHIOPIC SYLLABLE NEE +1295 ; [.1E9D.0020.0002.1295] # ETHIOPIC SYLLABLE NE +1296 ; [.1E9E.0020.0002.1296] # ETHIOPIC SYLLABLE NO +1297 ; [.1E9F.0020.0002.1297] # ETHIOPIC SYLLABLE NWA +2D88 ; [.1EA0.0020.0002.2D88] # ETHIOPIC SYLLABLE NOA +1298 ; [.1EA1.0020.0002.1298] # ETHIOPIC SYLLABLE NYA +1299 ; [.1EA2.0020.0002.1299] # ETHIOPIC SYLLABLE NYU +129A ; [.1EA3.0020.0002.129A] # ETHIOPIC SYLLABLE NYI +129B ; [.1EA4.0020.0002.129B] # ETHIOPIC SYLLABLE NYAA +129C ; [.1EA5.0020.0002.129C] # ETHIOPIC SYLLABLE NYEE +129D ; [.1EA6.0020.0002.129D] # ETHIOPIC SYLLABLE NYE +129E ; [.1EA7.0020.0002.129E] # ETHIOPIC SYLLABLE NYO +129F ; [.1EA8.0020.0002.129F] # ETHIOPIC SYLLABLE NYWA +2D89 ; [.1EA9.0020.0002.2D89] # ETHIOPIC SYLLABLE NYOA +12A0 ; [.1EAA.0020.0002.12A0] # ETHIOPIC SYLLABLE GLOTTAL A +12A1 ; [.1EAB.0020.0002.12A1] # ETHIOPIC SYLLABLE GLOTTAL U +12A2 ; [.1EAC.0020.0002.12A2] # ETHIOPIC SYLLABLE GLOTTAL I +12A3 ; [.1EAD.0020.0002.12A3] # ETHIOPIC SYLLABLE GLOTTAL AA +12A4 ; [.1EAE.0020.0002.12A4] # ETHIOPIC SYLLABLE GLOTTAL EE +12A5 ; [.1EAF.0020.0002.12A5] # ETHIOPIC SYLLABLE GLOTTAL E +12A6 ; [.1EB0.0020.0002.12A6] # ETHIOPIC SYLLABLE GLOTTAL O +12A7 ; [.1EB1.0020.0002.12A7] # ETHIOPIC SYLLABLE GLOTTAL WA +2D8A ; [.1EB2.0020.0002.2D8A] # ETHIOPIC SYLLABLE GLOTTAL OA +12A8 ; [.1EB3.0020.0002.12A8] # ETHIOPIC SYLLABLE KA +12A9 ; [.1EB4.0020.0002.12A9] # ETHIOPIC SYLLABLE KU +12AA ; [.1EB5.0020.0002.12AA] # ETHIOPIC SYLLABLE KI +12AB ; [.1EB6.0020.0002.12AB] # ETHIOPIC SYLLABLE KAA +12AC ; [.1EB7.0020.0002.12AC] # ETHIOPIC SYLLABLE KEE +12AD ; [.1EB8.0020.0002.12AD] # ETHIOPIC SYLLABLE KE +12AE ; [.1EB9.0020.0002.12AE] # ETHIOPIC SYLLABLE KO +12AF ; [.1EBA.0020.0002.12AF] # ETHIOPIC SYLLABLE KOA +12B0 ; [.1EBB.0020.0002.12B0] # ETHIOPIC SYLLABLE KWA +12B2 ; [.1EBC.0020.0002.12B2] # ETHIOPIC SYLLABLE KWI +12B3 ; [.1EBD.0020.0002.12B3] # ETHIOPIC SYLLABLE KWAA +12B4 ; [.1EBE.0020.0002.12B4] # ETHIOPIC SYLLABLE KWEE +12B5 ; [.1EBF.0020.0002.12B5] # ETHIOPIC SYLLABLE KWE +12B8 ; [.1EC0.0020.0002.12B8] # ETHIOPIC SYLLABLE KXA +12B9 ; [.1EC1.0020.0002.12B9] # ETHIOPIC SYLLABLE KXU +12BA ; [.1EC2.0020.0002.12BA] # ETHIOPIC SYLLABLE KXI +12BB ; [.1EC3.0020.0002.12BB] # ETHIOPIC SYLLABLE KXAA +12BC ; [.1EC4.0020.0002.12BC] # ETHIOPIC SYLLABLE KXEE +12BD ; [.1EC5.0020.0002.12BD] # ETHIOPIC SYLLABLE KXE +12BE ; [.1EC6.0020.0002.12BE] # ETHIOPIC SYLLABLE KXO +12C0 ; [.1EC7.0020.0002.12C0] # ETHIOPIC SYLLABLE KXWA +12C2 ; [.1EC8.0020.0002.12C2] # ETHIOPIC SYLLABLE KXWI +12C3 ; [.1EC9.0020.0002.12C3] # ETHIOPIC SYLLABLE KXWAA +12C4 ; [.1ECA.0020.0002.12C4] # ETHIOPIC SYLLABLE KXWEE +12C5 ; [.1ECB.0020.0002.12C5] # ETHIOPIC SYLLABLE KXWE +12C8 ; [.1ECC.0020.0002.12C8] # ETHIOPIC SYLLABLE WA +12C9 ; [.1ECD.0020.0002.12C9] # ETHIOPIC SYLLABLE WU +12CA ; [.1ECE.0020.0002.12CA] # ETHIOPIC SYLLABLE WI +12CB ; [.1ECF.0020.0002.12CB] # ETHIOPIC SYLLABLE WAA +12CC ; [.1ED0.0020.0002.12CC] # ETHIOPIC SYLLABLE WEE +12CD ; [.1ED1.0020.0002.12CD] # ETHIOPIC SYLLABLE WE +12CE ; [.1ED2.0020.0002.12CE] # ETHIOPIC SYLLABLE WO +12CF ; [.1ED3.0020.0002.12CF] # ETHIOPIC SYLLABLE WOA +12D0 ; [.1ED4.0020.0002.12D0] # ETHIOPIC SYLLABLE PHARYNGEAL A +12D1 ; [.1ED5.0020.0002.12D1] # ETHIOPIC SYLLABLE PHARYNGEAL U +12D2 ; [.1ED6.0020.0002.12D2] # ETHIOPIC SYLLABLE PHARYNGEAL I +12D3 ; [.1ED7.0020.0002.12D3] # ETHIOPIC SYLLABLE PHARYNGEAL AA +12D4 ; [.1ED8.0020.0002.12D4] # ETHIOPIC SYLLABLE PHARYNGEAL EE +12D5 ; [.1ED9.0020.0002.12D5] # ETHIOPIC SYLLABLE PHARYNGEAL E +12D6 ; [.1EDA.0020.0002.12D6] # ETHIOPIC SYLLABLE PHARYNGEAL O +12D8 ; [.1EDB.0020.0002.12D8] # ETHIOPIC SYLLABLE ZA +12D9 ; [.1EDC.0020.0002.12D9] # ETHIOPIC SYLLABLE ZU +12DA ; [.1EDD.0020.0002.12DA] # ETHIOPIC SYLLABLE ZI +12DB ; [.1EDE.0020.0002.12DB] # ETHIOPIC SYLLABLE ZAA +12DC ; [.1EDF.0020.0002.12DC] # ETHIOPIC SYLLABLE ZEE +12DD ; [.1EE0.0020.0002.12DD] # ETHIOPIC SYLLABLE ZE +12DE ; [.1EE1.0020.0002.12DE] # ETHIOPIC SYLLABLE ZO +12DF ; [.1EE2.0020.0002.12DF] # ETHIOPIC SYLLABLE ZWA +2D8B ; [.1EE3.0020.0002.2D8B] # ETHIOPIC SYLLABLE ZOA +AB11 ; [.1EE4.0020.0002.AB11] # ETHIOPIC SYLLABLE DZU +AB12 ; [.1EE5.0020.0002.AB12] # ETHIOPIC SYLLABLE DZI +AB13 ; [.1EE6.0020.0002.AB13] # ETHIOPIC SYLLABLE DZAA +AB14 ; [.1EE7.0020.0002.AB14] # ETHIOPIC SYLLABLE DZEE +AB15 ; [.1EE8.0020.0002.AB15] # ETHIOPIC SYLLABLE DZE +AB16 ; [.1EE9.0020.0002.AB16] # ETHIOPIC SYLLABLE DZO +12E0 ; [.1EEA.0020.0002.12E0] # ETHIOPIC SYLLABLE ZHA +12E1 ; [.1EEB.0020.0002.12E1] # ETHIOPIC SYLLABLE ZHU +12E2 ; [.1EEC.0020.0002.12E2] # ETHIOPIC SYLLABLE ZHI +12E3 ; [.1EED.0020.0002.12E3] # ETHIOPIC SYLLABLE ZHAA +12E4 ; [.1EEE.0020.0002.12E4] # ETHIOPIC SYLLABLE ZHEE +12E5 ; [.1EEF.0020.0002.12E5] # ETHIOPIC SYLLABLE ZHE +12E6 ; [.1EF0.0020.0002.12E6] # ETHIOPIC SYLLABLE ZHO +12E7 ; [.1EF1.0020.0002.12E7] # ETHIOPIC SYLLABLE ZHWA +12E8 ; [.1EF2.0020.0002.12E8] # ETHIOPIC SYLLABLE YA +12E9 ; [.1EF3.0020.0002.12E9] # ETHIOPIC SYLLABLE YU +12EA ; [.1EF4.0020.0002.12EA] # ETHIOPIC SYLLABLE YI +12EB ; [.1EF5.0020.0002.12EB] # ETHIOPIC SYLLABLE YAA +12EC ; [.1EF6.0020.0002.12EC] # ETHIOPIC SYLLABLE YEE +12ED ; [.1EF7.0020.0002.12ED] # ETHIOPIC SYLLABLE YE +12EE ; [.1EF8.0020.0002.12EE] # ETHIOPIC SYLLABLE YO +12EF ; [.1EF9.0020.0002.12EF] # ETHIOPIC SYLLABLE YOA +12F0 ; [.1EFA.0020.0002.12F0] # ETHIOPIC SYLLABLE DA +12F1 ; [.1EFB.0020.0002.12F1] # ETHIOPIC SYLLABLE DU +12F2 ; [.1EFC.0020.0002.12F2] # ETHIOPIC SYLLABLE DI +12F3 ; [.1EFD.0020.0002.12F3] # ETHIOPIC SYLLABLE DAA +12F4 ; [.1EFE.0020.0002.12F4] # ETHIOPIC SYLLABLE DEE +12F5 ; [.1EFF.0020.0002.12F5] # ETHIOPIC SYLLABLE DE +12F6 ; [.1F00.0020.0002.12F6] # ETHIOPIC SYLLABLE DO +12F7 ; [.1F01.0020.0002.12F7] # ETHIOPIC SYLLABLE DWA +2D8C ; [.1F02.0020.0002.2D8C] # ETHIOPIC SYLLABLE DOA +AB09 ; [.1F03.0020.0002.AB09] # ETHIOPIC SYLLABLE DDHU +AB0A ; [.1F04.0020.0002.AB0A] # ETHIOPIC SYLLABLE DDHI +AB0B ; [.1F05.0020.0002.AB0B] # ETHIOPIC SYLLABLE DDHAA +AB0C ; [.1F06.0020.0002.AB0C] # ETHIOPIC SYLLABLE DDHEE +AB0D ; [.1F07.0020.0002.AB0D] # ETHIOPIC SYLLABLE DDHE +AB0E ; [.1F08.0020.0002.AB0E] # ETHIOPIC SYLLABLE DDHO +12F8 ; [.1F09.0020.0002.12F8] # ETHIOPIC SYLLABLE DDA +12F9 ; [.1F0A.0020.0002.12F9] # ETHIOPIC SYLLABLE DDU +12FA ; [.1F0B.0020.0002.12FA] # ETHIOPIC SYLLABLE DDI +12FB ; [.1F0C.0020.0002.12FB] # ETHIOPIC SYLLABLE DDAA +12FC ; [.1F0D.0020.0002.12FC] # ETHIOPIC SYLLABLE DDEE +12FD ; [.1F0E.0020.0002.12FD] # ETHIOPIC SYLLABLE DDE +12FE ; [.1F0F.0020.0002.12FE] # ETHIOPIC SYLLABLE DDO +12FF ; [.1F10.0020.0002.12FF] # ETHIOPIC SYLLABLE DDWA +2D8D ; [.1F11.0020.0002.2D8D] # ETHIOPIC SYLLABLE DDOA +1300 ; [.1F12.0020.0002.1300] # ETHIOPIC SYLLABLE JA +1301 ; [.1F13.0020.0002.1301] # ETHIOPIC SYLLABLE JU +1302 ; [.1F14.0020.0002.1302] # ETHIOPIC SYLLABLE JI +1303 ; [.1F15.0020.0002.1303] # ETHIOPIC SYLLABLE JAA +1304 ; [.1F16.0020.0002.1304] # ETHIOPIC SYLLABLE JEE +1305 ; [.1F17.0020.0002.1305] # ETHIOPIC SYLLABLE JE +1306 ; [.1F18.0020.0002.1306] # ETHIOPIC SYLLABLE JO +1307 ; [.1F19.0020.0002.1307] # ETHIOPIC SYLLABLE JWA +2D8E ; [.1F1A.0020.0002.2D8E] # ETHIOPIC SYLLABLE JOA +1308 ; [.1F1B.0020.0002.1308] # ETHIOPIC SYLLABLE GA +1309 ; [.1F1C.0020.0002.1309] # ETHIOPIC SYLLABLE GU +130A ; [.1F1D.0020.0002.130A] # ETHIOPIC SYLLABLE GI +130B ; [.1F1E.0020.0002.130B] # ETHIOPIC SYLLABLE GAA +130C ; [.1F1F.0020.0002.130C] # ETHIOPIC SYLLABLE GEE +130D ; [.1F20.0020.0002.130D] # ETHIOPIC SYLLABLE GE +130E ; [.1F21.0020.0002.130E] # ETHIOPIC SYLLABLE GO +130F ; [.1F22.0020.0002.130F] # ETHIOPIC SYLLABLE GOA +1310 ; [.1F23.0020.0002.1310] # ETHIOPIC SYLLABLE GWA +1312 ; [.1F24.0020.0002.1312] # ETHIOPIC SYLLABLE GWI +1313 ; [.1F25.0020.0002.1313] # ETHIOPIC SYLLABLE GWAA +1314 ; [.1F26.0020.0002.1314] # ETHIOPIC SYLLABLE GWEE +1315 ; [.1F27.0020.0002.1315] # ETHIOPIC SYLLABLE GWE +1318 ; [.1F28.0020.0002.1318] # ETHIOPIC SYLLABLE GGA +1319 ; [.1F29.0020.0002.1319] # ETHIOPIC SYLLABLE GGU +131A ; [.1F2A.0020.0002.131A] # ETHIOPIC SYLLABLE GGI +131B ; [.1F2B.0020.0002.131B] # ETHIOPIC SYLLABLE GGAA +131C ; [.1F2C.0020.0002.131C] # ETHIOPIC SYLLABLE GGEE +131D ; [.1F2D.0020.0002.131D] # ETHIOPIC SYLLABLE GGE +131E ; [.1F2E.0020.0002.131E] # ETHIOPIC SYLLABLE GGO +131F ; [.1F2F.0020.0002.131F] # ETHIOPIC SYLLABLE GGWAA +2D93 ; [.1F30.0020.0002.2D93] # ETHIOPIC SYLLABLE GGWA +2D94 ; [.1F31.0020.0002.2D94] # ETHIOPIC SYLLABLE GGWI +2D95 ; [.1F32.0020.0002.2D95] # ETHIOPIC SYLLABLE GGWEE +2D96 ; [.1F33.0020.0002.2D96] # ETHIOPIC SYLLABLE GGWE +1320 ; [.1F34.0020.0002.1320] # ETHIOPIC SYLLABLE THA +1321 ; [.1F35.0020.0002.1321] # ETHIOPIC SYLLABLE THU +1322 ; [.1F36.0020.0002.1322] # ETHIOPIC SYLLABLE THI +1323 ; [.1F37.0020.0002.1323] # ETHIOPIC SYLLABLE THAA +1324 ; [.1F38.0020.0002.1324] # ETHIOPIC SYLLABLE THEE +1325 ; [.1F39.0020.0002.1325] # ETHIOPIC SYLLABLE THE +1326 ; [.1F3A.0020.0002.1326] # ETHIOPIC SYLLABLE THO +1327 ; [.1F3B.0020.0002.1327] # ETHIOPIC SYLLABLE THWA +2D8F ; [.1F3C.0020.0002.2D8F] # ETHIOPIC SYLLABLE THOA +1328 ; [.1F3D.0020.0002.1328] # ETHIOPIC SYLLABLE CHA +1329 ; [.1F3E.0020.0002.1329] # ETHIOPIC SYLLABLE CHU +132A ; [.1F3F.0020.0002.132A] # ETHIOPIC SYLLABLE CHI +132B ; [.1F40.0020.0002.132B] # ETHIOPIC SYLLABLE CHAA +132C ; [.1F41.0020.0002.132C] # ETHIOPIC SYLLABLE CHEE +132D ; [.1F42.0020.0002.132D] # ETHIOPIC SYLLABLE CHE +132E ; [.1F43.0020.0002.132E] # ETHIOPIC SYLLABLE CHO +132F ; [.1F44.0020.0002.132F] # ETHIOPIC SYLLABLE CHWA +2D90 ; [.1F45.0020.0002.2D90] # ETHIOPIC SYLLABLE CHOA +AB20 ; [.1F46.0020.0002.AB20] # ETHIOPIC SYLLABLE CCHHA +AB21 ; [.1F47.0020.0002.AB21] # ETHIOPIC SYLLABLE CCHHU +AB22 ; [.1F48.0020.0002.AB22] # ETHIOPIC SYLLABLE CCHHI +AB23 ; [.1F49.0020.0002.AB23] # ETHIOPIC SYLLABLE CCHHAA +AB24 ; [.1F4A.0020.0002.AB24] # ETHIOPIC SYLLABLE CCHHEE +AB25 ; [.1F4B.0020.0002.AB25] # ETHIOPIC SYLLABLE CCHHE +AB26 ; [.1F4C.0020.0002.AB26] # ETHIOPIC SYLLABLE CCHHO +1330 ; [.1F4D.0020.0002.1330] # ETHIOPIC SYLLABLE PHA +1331 ; [.1F4E.0020.0002.1331] # ETHIOPIC SYLLABLE PHU +1332 ; [.1F4F.0020.0002.1332] # ETHIOPIC SYLLABLE PHI +1333 ; [.1F50.0020.0002.1333] # ETHIOPIC SYLLABLE PHAA +1334 ; [.1F51.0020.0002.1334] # ETHIOPIC SYLLABLE PHEE +1335 ; [.1F52.0020.0002.1335] # ETHIOPIC SYLLABLE PHE +1336 ; [.1F53.0020.0002.1336] # ETHIOPIC SYLLABLE PHO +1337 ; [.1F54.0020.0002.1337] # ETHIOPIC SYLLABLE PHWA +2D91 ; [.1F55.0020.0002.2D91] # ETHIOPIC SYLLABLE PHOA +1338 ; [.1F56.0020.0002.1338] # ETHIOPIC SYLLABLE TSA +1339 ; [.1F57.0020.0002.1339] # ETHIOPIC SYLLABLE TSU +133A ; [.1F58.0020.0002.133A] # ETHIOPIC SYLLABLE TSI +133B ; [.1F59.0020.0002.133B] # ETHIOPIC SYLLABLE TSAA +133C ; [.1F5A.0020.0002.133C] # ETHIOPIC SYLLABLE TSEE +133D ; [.1F5B.0020.0002.133D] # ETHIOPIC SYLLABLE TSE +133E ; [.1F5C.0020.0002.133E] # ETHIOPIC SYLLABLE TSO +133F ; [.1F5D.0020.0002.133F] # ETHIOPIC SYLLABLE TSWA +AB28 ; [.1F5E.0020.0002.AB28] # ETHIOPIC SYLLABLE BBA +AB29 ; [.1F5F.0020.0002.AB29] # ETHIOPIC SYLLABLE BBU +AB2A ; [.1F60.0020.0002.AB2A] # ETHIOPIC SYLLABLE BBI +AB2B ; [.1F61.0020.0002.AB2B] # ETHIOPIC SYLLABLE BBAA +AB2C ; [.1F62.0020.0002.AB2C] # ETHIOPIC SYLLABLE BBEE +AB2D ; [.1F63.0020.0002.AB2D] # ETHIOPIC SYLLABLE BBE +AB2E ; [.1F64.0020.0002.AB2E] # ETHIOPIC SYLLABLE BBO +1340 ; [.1F65.0020.0002.1340] # ETHIOPIC SYLLABLE TZA +1341 ; [.1F66.0020.0002.1341] # ETHIOPIC SYLLABLE TZU +1342 ; [.1F67.0020.0002.1342] # ETHIOPIC SYLLABLE TZI +1343 ; [.1F68.0020.0002.1343] # ETHIOPIC SYLLABLE TZAA +1344 ; [.1F69.0020.0002.1344] # ETHIOPIC SYLLABLE TZEE +1345 ; [.1F6A.0020.0002.1345] # ETHIOPIC SYLLABLE TZE +1346 ; [.1F6B.0020.0002.1346] # ETHIOPIC SYLLABLE TZO +1347 ; [.1F6C.0020.0002.1347] # ETHIOPIC SYLLABLE TZOA +1348 ; [.1F6D.0020.0002.1348] # ETHIOPIC SYLLABLE FA +1349 ; [.1F6E.0020.0002.1349] # ETHIOPIC SYLLABLE FU +134A ; [.1F6F.0020.0002.134A] # ETHIOPIC SYLLABLE FI +134B ; [.1F70.0020.0002.134B] # ETHIOPIC SYLLABLE FAA +134C ; [.1F71.0020.0002.134C] # ETHIOPIC SYLLABLE FEE +134D ; [.1F72.0020.0002.134D] # ETHIOPIC SYLLABLE FE +134E ; [.1F73.0020.0002.134E] # ETHIOPIC SYLLABLE FO +134F ; [.1F74.0020.0002.134F] # ETHIOPIC SYLLABLE FWA +1388 ; [.1F75.0020.0002.1388] # ETHIOPIC SYLLABLE SEBATBEIT FWA +1389 ; [.1F76.0020.0002.1389] # ETHIOPIC SYLLABLE FWI +138A ; [.1F77.0020.0002.138A] # ETHIOPIC SYLLABLE FWEE +138B ; [.1F78.0020.0002.138B] # ETHIOPIC SYLLABLE FWE +1350 ; [.1F79.0020.0002.1350] # ETHIOPIC SYLLABLE PA +1351 ; [.1F7A.0020.0002.1351] # ETHIOPIC SYLLABLE PU +1352 ; [.1F7B.0020.0002.1352] # ETHIOPIC SYLLABLE PI +1353 ; [.1F7C.0020.0002.1353] # ETHIOPIC SYLLABLE PAA +1354 ; [.1F7D.0020.0002.1354] # ETHIOPIC SYLLABLE PEE +1355 ; [.1F7E.0020.0002.1355] # ETHIOPIC SYLLABLE PE +1356 ; [.1F7F.0020.0002.1356] # ETHIOPIC SYLLABLE PO +1357 ; [.1F80.0020.0002.1357] # ETHIOPIC SYLLABLE PWA +138C ; [.1F81.0020.0002.138C] # ETHIOPIC SYLLABLE SEBATBEIT PWA +138D ; [.1F82.0020.0002.138D] # ETHIOPIC SYLLABLE PWI +138E ; [.1F83.0020.0002.138E] # ETHIOPIC SYLLABLE PWEE +138F ; [.1F84.0020.0002.138F] # ETHIOPIC SYLLABLE PWE +2D92 ; [.1F85.0020.0002.2D92] # ETHIOPIC SYLLABLE POA +1358 ; [.1F86.0020.0002.1358] # ETHIOPIC SYLLABLE RYA +1359 ; [.1F87.0020.0002.1359] # ETHIOPIC SYLLABLE MYA +135A ; [.1F88.0020.0002.135A] # ETHIOPIC SYLLABLE FYA +2DA0 ; [.1F89.0020.0002.2DA0] # ETHIOPIC SYLLABLE SSA +2DA1 ; [.1F8A.0020.0002.2DA1] # ETHIOPIC SYLLABLE SSU +2DA2 ; [.1F8B.0020.0002.2DA2] # ETHIOPIC SYLLABLE SSI +2DA3 ; [.1F8C.0020.0002.2DA3] # ETHIOPIC SYLLABLE SSAA +2DA4 ; [.1F8D.0020.0002.2DA4] # ETHIOPIC SYLLABLE SSEE +2DA5 ; [.1F8E.0020.0002.2DA5] # ETHIOPIC SYLLABLE SSE +2DA6 ; [.1F8F.0020.0002.2DA6] # ETHIOPIC SYLLABLE SSO +2DA8 ; [.1F90.0020.0002.2DA8] # ETHIOPIC SYLLABLE CCA +2DA9 ; [.1F91.0020.0002.2DA9] # ETHIOPIC SYLLABLE CCU +2DAA ; [.1F92.0020.0002.2DAA] # ETHIOPIC SYLLABLE CCI +2DAB ; [.1F93.0020.0002.2DAB] # ETHIOPIC SYLLABLE CCAA +2DAC ; [.1F94.0020.0002.2DAC] # ETHIOPIC SYLLABLE CCEE +2DAD ; [.1F95.0020.0002.2DAD] # ETHIOPIC SYLLABLE CCE +2DAE ; [.1F96.0020.0002.2DAE] # ETHIOPIC SYLLABLE CCO +2DB0 ; [.1F97.0020.0002.2DB0] # ETHIOPIC SYLLABLE ZZA +2DB1 ; [.1F98.0020.0002.2DB1] # ETHIOPIC SYLLABLE ZZU +2DB2 ; [.1F99.0020.0002.2DB2] # ETHIOPIC SYLLABLE ZZI +2DB3 ; [.1F9A.0020.0002.2DB3] # ETHIOPIC SYLLABLE ZZAA +2DB4 ; [.1F9B.0020.0002.2DB4] # ETHIOPIC SYLLABLE ZZEE +2DB5 ; [.1F9C.0020.0002.2DB5] # ETHIOPIC SYLLABLE ZZE +2DB6 ; [.1F9D.0020.0002.2DB6] # ETHIOPIC SYLLABLE ZZO +2DB8 ; [.1F9E.0020.0002.2DB8] # ETHIOPIC SYLLABLE CCHA +2DB9 ; [.1F9F.0020.0002.2DB9] # ETHIOPIC SYLLABLE CCHU +2DBA ; [.1FA0.0020.0002.2DBA] # ETHIOPIC SYLLABLE CCHI +2DBB ; [.1FA1.0020.0002.2DBB] # ETHIOPIC SYLLABLE CCHAA +2DBC ; [.1FA2.0020.0002.2DBC] # ETHIOPIC SYLLABLE CCHEE +2DBD ; [.1FA3.0020.0002.2DBD] # ETHIOPIC SYLLABLE CCHE +2DBE ; [.1FA4.0020.0002.2DBE] # ETHIOPIC SYLLABLE CCHO +2DC0 ; [.1FA5.0020.0002.2DC0] # ETHIOPIC SYLLABLE QYA +2DC1 ; [.1FA6.0020.0002.2DC1] # ETHIOPIC SYLLABLE QYU +2DC2 ; [.1FA7.0020.0002.2DC2] # ETHIOPIC SYLLABLE QYI +2DC3 ; [.1FA8.0020.0002.2DC3] # ETHIOPIC SYLLABLE QYAA +2DC4 ; [.1FA9.0020.0002.2DC4] # ETHIOPIC SYLLABLE QYEE +2DC5 ; [.1FAA.0020.0002.2DC5] # ETHIOPIC SYLLABLE QYE +2DC6 ; [.1FAB.0020.0002.2DC6] # ETHIOPIC SYLLABLE QYO +2DC8 ; [.1FAC.0020.0002.2DC8] # ETHIOPIC SYLLABLE KYA +2DC9 ; [.1FAD.0020.0002.2DC9] # ETHIOPIC SYLLABLE KYU +2DCA ; [.1FAE.0020.0002.2DCA] # ETHIOPIC SYLLABLE KYI +2DCB ; [.1FAF.0020.0002.2DCB] # ETHIOPIC SYLLABLE KYAA +2DCC ; [.1FB0.0020.0002.2DCC] # ETHIOPIC SYLLABLE KYEE +2DCD ; [.1FB1.0020.0002.2DCD] # ETHIOPIC SYLLABLE KYE +2DCE ; [.1FB2.0020.0002.2DCE] # ETHIOPIC SYLLABLE KYO +2DD0 ; [.1FB3.0020.0002.2DD0] # ETHIOPIC SYLLABLE XYA +2DD1 ; [.1FB4.0020.0002.2DD1] # ETHIOPIC SYLLABLE XYU +2DD2 ; [.1FB5.0020.0002.2DD2] # ETHIOPIC SYLLABLE XYI +2DD3 ; [.1FB6.0020.0002.2DD3] # ETHIOPIC SYLLABLE XYAA +2DD4 ; [.1FB7.0020.0002.2DD4] # ETHIOPIC SYLLABLE XYEE +2DD5 ; [.1FB8.0020.0002.2DD5] # ETHIOPIC SYLLABLE XYE +2DD6 ; [.1FB9.0020.0002.2DD6] # ETHIOPIC SYLLABLE XYO +2DD8 ; [.1FBA.0020.0002.2DD8] # ETHIOPIC SYLLABLE GYA +2DD9 ; [.1FBB.0020.0002.2DD9] # ETHIOPIC SYLLABLE GYU +2DDA ; [.1FBC.0020.0002.2DDA] # ETHIOPIC SYLLABLE GYI +2DDB ; [.1FBD.0020.0002.2DDB] # ETHIOPIC SYLLABLE GYAA +2DDC ; [.1FBE.0020.0002.2DDC] # ETHIOPIC SYLLABLE GYEE +2DDD ; [.1FBF.0020.0002.2DDD] # ETHIOPIC SYLLABLE GYE +2DDE ; [.1FC0.0020.0002.2DDE] # ETHIOPIC SYLLABLE GYO +0950 ; [.1FC1.0020.0002.0950] # DEVANAGARI OM +0972 ; [.1FC2.0020.0002.0972] # DEVANAGARI LETTER CANDRA A +0904 ; [.1FC3.0020.0002.0904] # DEVANAGARI LETTER SHORT A +0905 ; [.1FC4.0020.0002.0905] # DEVANAGARI LETTER A +0906 ; [.1FC5.0020.0002.0906] # DEVANAGARI LETTER AA +0973 ; [.1FC6.0020.0002.0973] # DEVANAGARI LETTER OE +0974 ; [.1FC7.0020.0002.0974] # DEVANAGARI LETTER OOE +0975 ; [.1FC8.0020.0002.0975] # DEVANAGARI LETTER AW +0976 ; [.1FC9.0020.0002.0976] # DEVANAGARI LETTER UE +0977 ; [.1FCA.0020.0002.0977] # DEVANAGARI LETTER UUE +0907 ; [.1FCB.0020.0002.0907] # DEVANAGARI LETTER I +0908 ; [.1FCC.0020.0002.0908] # DEVANAGARI LETTER II +0909 ; [.1FCD.0020.0002.0909] # DEVANAGARI LETTER U +090A ; [.1FCE.0020.0002.090A] # DEVANAGARI LETTER UU +090B ; [.1FCF.0020.0002.090B] # DEVANAGARI LETTER VOCALIC R +0960 ; [.1FD0.0020.0002.0960] # DEVANAGARI LETTER VOCALIC RR +090C ; [.1FD1.0020.0002.090C] # DEVANAGARI LETTER VOCALIC L +0961 ; [.1FD2.0020.0002.0961] # DEVANAGARI LETTER VOCALIC LL +090D ; [.1FD3.0020.0002.090D] # DEVANAGARI LETTER CANDRA E +090E ; [.1FD4.0020.0002.090E] # DEVANAGARI LETTER SHORT E +090F ; [.1FD5.0020.0002.090F] # DEVANAGARI LETTER E +0910 ; [.1FD6.0020.0002.0910] # DEVANAGARI LETTER AI +0911 ; [.1FD7.0020.0002.0911] # DEVANAGARI LETTER CANDRA O +0912 ; [.1FD8.0020.0002.0912] # DEVANAGARI LETTER SHORT O +0913 ; [.1FD9.0020.0002.0913] # DEVANAGARI LETTER O +0914 ; [.1FDA.0020.0002.0914] # DEVANAGARI LETTER AU +0915 ; [.1FDB.0020.0002.0915] # DEVANAGARI LETTER KA +0958 ; [.1FDB.0020.0002.0915][.0000.00F1.0002.093C] # DEVANAGARI LETTER QA +0916 ; [.1FDC.0020.0002.0916] # DEVANAGARI LETTER KHA +0959 ; [.1FDC.0020.0002.0916][.0000.00F1.0002.093C] # DEVANAGARI LETTER KHHA +0917 ; [.1FDD.0020.0002.0917] # DEVANAGARI LETTER GA +095A ; [.1FDD.0020.0002.0917][.0000.00F1.0002.093C] # DEVANAGARI LETTER GHHA +097B ; [.1FDE.0020.0002.097B] # DEVANAGARI LETTER GGA +0918 ; [.1FDF.0020.0002.0918] # DEVANAGARI LETTER GHA +0919 ; [.1FE0.0020.0002.0919] # DEVANAGARI LETTER NGA +091A ; [.1FE1.0020.0002.091A] # DEVANAGARI LETTER CA +091B ; [.1FE2.0020.0002.091B] # DEVANAGARI LETTER CHA +091C ; [.1FE3.0020.0002.091C] # DEVANAGARI LETTER JA +095B ; [.1FE3.0020.0002.091C][.0000.00F1.0002.093C] # DEVANAGARI LETTER ZA +0979 ; [.1FE4.0020.0002.0979] # DEVANAGARI LETTER ZHA +097C ; [.1FE5.0020.0002.097C] # DEVANAGARI LETTER JJA +091D ; [.1FE6.0020.0002.091D] # DEVANAGARI LETTER JHA +091E ; [.1FE7.0020.0002.091E] # DEVANAGARI LETTER NYA +091F ; [.1FE8.0020.0002.091F] # DEVANAGARI LETTER TTA +0920 ; [.1FE9.0020.0002.0920] # DEVANAGARI LETTER TTHA +0921 ; [.1FEA.0020.0002.0921] # DEVANAGARI LETTER DDA +095C ; [.1FEA.0020.0002.0921][.0000.00F1.0002.093C] # DEVANAGARI LETTER DDDHA +097E ; [.1FEB.0020.0002.097E] # DEVANAGARI LETTER DDDA +0922 ; [.1FEC.0020.0002.0922] # DEVANAGARI LETTER DDHA +095D ; [.1FEC.0020.0002.0922][.0000.00F1.0002.093C] # DEVANAGARI LETTER RHA +0923 ; [.1FED.0020.0002.0923] # DEVANAGARI LETTER NNA +0924 ; [.1FEE.0020.0002.0924] # DEVANAGARI LETTER TA +0925 ; [.1FEF.0020.0002.0925] # DEVANAGARI LETTER THA +0926 ; [.1FF0.0020.0002.0926] # DEVANAGARI LETTER DA +0927 ; [.1FF1.0020.0002.0927] # DEVANAGARI LETTER DHA +0928 ; [.1FF2.0020.0002.0928] # DEVANAGARI LETTER NA +0929 ; [.1FF2.0020.0002.0928][.0000.00F1.0002.093C] # DEVANAGARI LETTER NNNA +092A ; [.1FF3.0020.0002.092A] # DEVANAGARI LETTER PA +092B ; [.1FF4.0020.0002.092B] # DEVANAGARI LETTER PHA +095E ; [.1FF4.0020.0002.092B][.0000.00F1.0002.093C] # DEVANAGARI LETTER FA +092C ; [.1FF5.0020.0002.092C] # DEVANAGARI LETTER BA +097F ; [.1FF6.0020.0002.097F] # DEVANAGARI LETTER BBA +092D ; [.1FF7.0020.0002.092D] # DEVANAGARI LETTER BHA +092E ; [.1FF8.0020.0002.092E] # DEVANAGARI LETTER MA +092F ; [.1FF9.0020.0002.092F] # DEVANAGARI LETTER YA +095F ; [.1FF9.0020.0002.092F][.0000.00F1.0002.093C] # DEVANAGARI LETTER YYA +097A ; [.1FFA.0020.0002.097A] # DEVANAGARI LETTER HEAVY YA +0930 ; [.1FFB.0020.0002.0930] # DEVANAGARI LETTER RA +0931 ; [.1FFB.0020.0002.0930][.0000.00F1.0002.093C] # DEVANAGARI LETTER RRA +0932 ; [.1FFC.0020.0002.0932] # DEVANAGARI LETTER LA +0933 ; [.1FFD.0020.0002.0933] # DEVANAGARI LETTER LLA +0934 ; [.1FFD.0020.0002.0933][.0000.00F1.0002.093C] # DEVANAGARI LETTER LLLA +0935 ; [.1FFE.0020.0002.0935] # DEVANAGARI LETTER VA +0936 ; [.1FFF.0020.0002.0936] # DEVANAGARI LETTER SHA +0937 ; [.2000.0020.0002.0937] # DEVANAGARI LETTER SSA +0938 ; [.2001.0020.0002.0938] # DEVANAGARI LETTER SA +0939 ; [.2002.0020.0002.0939] # DEVANAGARI LETTER HA +093D ; [.2003.0020.0002.093D] # DEVANAGARI SIGN AVAGRAHA +097D ; [.2004.0020.0002.097D] # DEVANAGARI LETTER GLOTTAL STOP +1CE9 ; [.2005.0020.0002.1CE9] # VEDIC SIGN ANUSVARA ANTARGOMUKHA +1CEA ; [.2005.0020.0004.1CEA] # VEDIC SIGN ANUSVARA BAHIRGOMUKHA +1CEB ; [.2005.0020.0004.1CEB] # VEDIC SIGN ANUSVARA VAMAGOMUKHA +1CEC ; [.2005.0020.0004.1CEC] # VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL +1CEE ; [.2005.0020.0004.1CEE] # VEDIC SIGN HEXIFORM LONG ANUSVARA +1CEF ; [.2005.0020.0004.1CEF] # VEDIC SIGN LONG ANUSVARA +1CF0 ; [.2005.0020.0004.1CF0] # VEDIC SIGN RTHANG LONG ANUSVARA +1CF1 ; [.2005.0020.0004.1CF1] # VEDIC SIGN ANUSVARA UBHAYATO MUKHA +1CF5 ; [.2006.0020.0002.1CF5] # VEDIC SIGN JIHVAMULIYA +1CF6 ; [.2007.0020.0002.1CF6] # VEDIC SIGN UPADHMANIYA +A8F2 ; [.2008.0020.0002.A8F2] # DEVANAGARI SIGN SPACING CANDRABINDU +A8F3 ; [.2008.0020.0004.A8F3] # DEVANAGARI SIGN CANDRABINDU VIRAMA +A8F4 ; [.2008.0020.0004.A8F4] # DEVANAGARI SIGN DOUBLE CANDRABINDU VIRAMA +A8F5 ; [.2008.0020.0004.A8F5] # DEVANAGARI SIGN CANDRABINDU TWO +A8F6 ; [.2008.0020.0004.A8F6] # DEVANAGARI SIGN CANDRABINDU THREE +A8F7 ; [.2008.0020.0004.A8F7] # DEVANAGARI SIGN CANDRABINDU AVAGRAHA +A8FB ; [.2009.0020.0002.A8FB] # DEVANAGARI HEADSTROKE +093E ; [.200A.0020.0002.093E] # DEVANAGARI VOWEL SIGN AA +093A ; [.200B.0020.0002.093A] # DEVANAGARI VOWEL SIGN OE +093B ; [.200C.0020.0002.093B] # DEVANAGARI VOWEL SIGN OOE +094F ; [.200D.0020.0002.094F] # DEVANAGARI VOWEL SIGN AW +0956 ; [.200E.0020.0002.0956] # DEVANAGARI VOWEL SIGN UE +0957 ; [.200F.0020.0002.0957] # DEVANAGARI VOWEL SIGN UUE +093F ; [.2010.0020.0002.093F] # DEVANAGARI VOWEL SIGN I +0940 ; [.2011.0020.0002.0940] # DEVANAGARI VOWEL SIGN II +0941 ; [.2012.0020.0002.0941] # DEVANAGARI VOWEL SIGN U +0942 ; [.2013.0020.0002.0942] # DEVANAGARI VOWEL SIGN UU +0943 ; [.2014.0020.0002.0943] # DEVANAGARI VOWEL SIGN VOCALIC R +0944 ; [.2015.0020.0002.0944] # DEVANAGARI VOWEL SIGN VOCALIC RR +0962 ; [.2016.0020.0002.0962] # DEVANAGARI VOWEL SIGN VOCALIC L +0963 ; [.2017.0020.0002.0963] # DEVANAGARI VOWEL SIGN VOCALIC LL +0945 ; [.2018.0020.0002.0945] # DEVANAGARI VOWEL SIGN CANDRA E +0955 ; [.2019.0020.0002.0955] # DEVANAGARI VOWEL SIGN CANDRA LONG E +0946 ; [.201A.0020.0002.0946] # DEVANAGARI VOWEL SIGN SHORT E +0947 ; [.201B.0020.0002.0947] # DEVANAGARI VOWEL SIGN E +094E ; [.201C.0020.0002.094E] # DEVANAGARI VOWEL SIGN PRISHTHAMATRA E +0948 ; [.201D.0020.0002.0948] # DEVANAGARI VOWEL SIGN AI +0949 ; [.201E.0020.0002.0949] # DEVANAGARI VOWEL SIGN CANDRA O +094A ; [.201F.0020.0002.094A] # DEVANAGARI VOWEL SIGN SHORT O +094B ; [.2020.0020.0002.094B] # DEVANAGARI VOWEL SIGN O +094C ; [.2021.0020.0002.094C] # DEVANAGARI VOWEL SIGN AU +094D ; [.2022.0020.0002.094D] # DEVANAGARI SIGN VIRAMA +0985 ; [.2023.0020.0002.0985] # BENGALI LETTER A +0986 ; [.2024.0020.0002.0986] # BENGALI LETTER AA +0987 ; [.2025.0020.0002.0987] # BENGALI LETTER I +0988 ; [.2026.0020.0002.0988] # BENGALI LETTER II +0989 ; [.2027.0020.0002.0989] # BENGALI LETTER U +098A ; [.2028.0020.0002.098A] # BENGALI LETTER UU +098B ; [.2029.0020.0002.098B] # BENGALI LETTER VOCALIC R +09E0 ; [.202A.0020.0002.09E0] # BENGALI LETTER VOCALIC RR +098C ; [.202B.0020.0002.098C] # BENGALI LETTER VOCALIC L +09E1 ; [.202C.0020.0002.09E1] # BENGALI LETTER VOCALIC LL +098F ; [.202D.0020.0002.098F] # BENGALI LETTER E +0990 ; [.202E.0020.0002.0990] # BENGALI LETTER AI +0993 ; [.202F.0020.0002.0993] # BENGALI LETTER O +0994 ; [.2030.0020.0002.0994] # BENGALI LETTER AU +0995 ; [.2031.0020.0002.0995] # BENGALI LETTER KA +0996 ; [.2032.0020.0002.0996] # BENGALI LETTER KHA +0997 ; [.2033.0020.0002.0997] # BENGALI LETTER GA +0998 ; [.2034.0020.0002.0998] # BENGALI LETTER GHA +0999 ; [.2035.0020.0002.0999] # BENGALI LETTER NGA +099A ; [.2036.0020.0002.099A] # BENGALI LETTER CA +099B ; [.2037.0020.0002.099B] # BENGALI LETTER CHA +099C ; [.2038.0020.0002.099C] # BENGALI LETTER JA +099D ; [.2039.0020.0002.099D] # BENGALI LETTER JHA +099E ; [.203A.0020.0002.099E] # BENGALI LETTER NYA +099F ; [.203B.0020.0002.099F] # BENGALI LETTER TTA +09A0 ; [.203C.0020.0002.09A0] # BENGALI LETTER TTHA +09A1 ; [.203D.0020.0002.09A1] # BENGALI LETTER DDA +09DC ; [.203D.0020.0002.09A1][.0000.00F1.0002.093C] # BENGALI LETTER RRA +09A2 ; [.203E.0020.0002.09A2] # BENGALI LETTER DDHA +09DD ; [.203E.0020.0002.09A2][.0000.00F1.0002.093C] # BENGALI LETTER RHA +09A3 ; [.203F.0020.0002.09A3] # BENGALI LETTER NNA +09A4 ; [.2040.0020.0002.09A4] # BENGALI LETTER TA +09CE ; [.2040.0020.0004.09CE][.2061.0020.0004.09CE] # BENGALI LETTER KHANDA TA +09A5 ; [.2041.0020.0002.09A5] # BENGALI LETTER THA +09A6 ; [.2042.0020.0002.09A6] # BENGALI LETTER DA +09A7 ; [.2043.0020.0002.09A7] # BENGALI LETTER DHA +09A8 ; [.2044.0020.0002.09A8] # BENGALI LETTER NA +09AA ; [.2045.0020.0002.09AA] # BENGALI LETTER PA +09AB ; [.2046.0020.0002.09AB] # BENGALI LETTER PHA +09AC ; [.2047.0020.0002.09AC] # BENGALI LETTER BA +09AD ; [.2048.0020.0002.09AD] # BENGALI LETTER BHA +09AE ; [.2049.0020.0002.09AE] # BENGALI LETTER MA +09AF ; [.204A.0020.0002.09AF] # BENGALI LETTER YA +09DF ; [.204A.0020.0002.09AF][.0000.00F1.0002.093C] # BENGALI LETTER YYA +09B0 ; [.204B.0020.0002.09B0] # BENGALI LETTER RA +09F0 ; [.204C.0020.0002.09F0] # BENGALI LETTER RA WITH MIDDLE DIAGONAL +09B2 ; [.204D.0020.0002.09B2] # BENGALI LETTER LA +09F1 ; [.204E.0020.0002.09F1] # BENGALI LETTER RA WITH LOWER DIAGONAL +09B6 ; [.204F.0020.0002.09B6] # BENGALI LETTER SHA +09B7 ; [.2050.0020.0002.09B7] # BENGALI LETTER SSA +09B8 ; [.2051.0020.0002.09B8] # BENGALI LETTER SA +09B9 ; [.2052.0020.0002.09B9] # BENGALI LETTER HA +09BD ; [.2053.0020.0002.09BD] # BENGALI SIGN AVAGRAHA +09BE ; [.2054.0020.0002.09BE] # BENGALI VOWEL SIGN AA +09BF ; [.2055.0020.0002.09BF] # BENGALI VOWEL SIGN I +09C0 ; [.2056.0020.0002.09C0] # BENGALI VOWEL SIGN II +09C1 ; [.2057.0020.0002.09C1] # BENGALI VOWEL SIGN U +09C2 ; [.2058.0020.0002.09C2] # BENGALI VOWEL SIGN UU +09C3 ; [.2059.0020.0002.09C3] # BENGALI VOWEL SIGN VOCALIC R +09C4 ; [.205A.0020.0002.09C4] # BENGALI VOWEL SIGN VOCALIC RR +09E2 ; [.205B.0020.0002.09E2] # BENGALI VOWEL SIGN VOCALIC L +09E3 ; [.205C.0020.0002.09E3] # BENGALI VOWEL SIGN VOCALIC LL +09C7 ; [.205D.0020.0002.09C7] # BENGALI VOWEL SIGN E +09C8 ; [.205E.0020.0002.09C8] # BENGALI VOWEL SIGN AI +09CB ; [.205F.0020.0002.09CB] # BENGALI VOWEL SIGN O +09C7 09BE ; [.205F.0020.0002.09CB] # BENGALI VOWEL SIGN O +09CC ; [.2060.0020.0002.09CC] # BENGALI VOWEL SIGN AU +09C7 09D7 ; [.2060.0020.0002.09CC] # BENGALI VOWEL SIGN AU +09CD ; [.2061.0020.0002.09CD] # BENGALI SIGN VIRAMA +09D7 ; [.2062.0020.0002.09D7] # BENGALI AU LENGTH MARK +0A74 ; [.2063.0020.0002.0A74] # GURMUKHI EK ONKAR +0A73 ; [.2064.0020.0002.0A73] # GURMUKHI URA +0A09 ; [.2065.0020.0002.0A09] # GURMUKHI LETTER U +0A0A ; [.2066.0020.0002.0A0A] # GURMUKHI LETTER UU +0A13 ; [.2067.0020.0002.0A13] # GURMUKHI LETTER OO +0A05 ; [.2068.0020.0002.0A05] # GURMUKHI LETTER A +0A06 ; [.2069.0020.0002.0A06] # GURMUKHI LETTER AA +0A10 ; [.206A.0020.0002.0A10] # GURMUKHI LETTER AI +0A14 ; [.206B.0020.0002.0A14] # GURMUKHI LETTER AU +0A72 ; [.206C.0020.0002.0A72] # GURMUKHI IRI +0A07 ; [.206D.0020.0002.0A07] # GURMUKHI LETTER I +0A08 ; [.206E.0020.0002.0A08] # GURMUKHI LETTER II +0A0F ; [.206F.0020.0002.0A0F] # GURMUKHI LETTER EE +0A38 ; [.2070.0020.0002.0A38] # GURMUKHI LETTER SA +0A36 ; [.2070.0020.0002.0A38][.0000.00F1.0002.093C] # GURMUKHI LETTER SHA +0A39 ; [.2071.0020.0002.0A39] # GURMUKHI LETTER HA +0A51 ; [.2072.0020.0002.0A51] # GURMUKHI SIGN UDAAT +0A15 ; [.2073.0020.0002.0A15] # GURMUKHI LETTER KA +0A16 ; [.2074.0020.0002.0A16] # GURMUKHI LETTER KHA +0A59 ; [.2074.0020.0002.0A16][.0000.00F1.0002.093C] # GURMUKHI LETTER KHHA +0A17 ; [.2075.0020.0002.0A17] # GURMUKHI LETTER GA +0A5A ; [.2075.0020.0002.0A17][.0000.00F1.0002.093C] # GURMUKHI LETTER GHHA +0A18 ; [.2076.0020.0002.0A18] # GURMUKHI LETTER GHA +0A19 ; [.2077.0020.0002.0A19] # GURMUKHI LETTER NGA +0A1A ; [.2078.0020.0002.0A1A] # GURMUKHI LETTER CA +0A1B ; [.2079.0020.0002.0A1B] # GURMUKHI LETTER CHA +0A1C ; [.207A.0020.0002.0A1C] # GURMUKHI LETTER JA +0A5B ; [.207A.0020.0002.0A1C][.0000.00F1.0002.093C] # GURMUKHI LETTER ZA +0A1D ; [.207B.0020.0002.0A1D] # GURMUKHI LETTER JHA +0A1E ; [.207C.0020.0002.0A1E] # GURMUKHI LETTER NYA +0A1F ; [.207D.0020.0002.0A1F] # GURMUKHI LETTER TTA +0A20 ; [.207E.0020.0002.0A20] # GURMUKHI LETTER TTHA +0A21 ; [.207F.0020.0002.0A21] # GURMUKHI LETTER DDA +0A22 ; [.2080.0020.0002.0A22] # GURMUKHI LETTER DDHA +0A23 ; [.2081.0020.0002.0A23] # GURMUKHI LETTER NNA +0A24 ; [.2082.0020.0002.0A24] # GURMUKHI LETTER TA +0A25 ; [.2083.0020.0002.0A25] # GURMUKHI LETTER THA +0A26 ; [.2084.0020.0002.0A26] # GURMUKHI LETTER DA +0A27 ; [.2085.0020.0002.0A27] # GURMUKHI LETTER DHA +0A28 ; [.2086.0020.0002.0A28] # GURMUKHI LETTER NA +0A2A ; [.2087.0020.0002.0A2A] # GURMUKHI LETTER PA +0A2B ; [.2088.0020.0002.0A2B] # GURMUKHI LETTER PHA +0A5E ; [.2088.0020.0002.0A2B][.0000.00F1.0002.093C] # GURMUKHI LETTER FA +0A2C ; [.2089.0020.0002.0A2C] # GURMUKHI LETTER BA +0A2D ; [.208A.0020.0002.0A2D] # GURMUKHI LETTER BHA +0A2E ; [.208B.0020.0002.0A2E] # GURMUKHI LETTER MA +0A2F ; [.208C.0020.0002.0A2F] # GURMUKHI LETTER YA +0A75 ; [.208D.0020.0002.0A75] # GURMUKHI SIGN YAKASH +0A30 ; [.208E.0020.0002.0A30] # GURMUKHI LETTER RA +0A32 ; [.208F.0020.0002.0A32] # GURMUKHI LETTER LA +0A33 ; [.208F.0020.0002.0A32][.0000.00F1.0002.093C] # GURMUKHI LETTER LLA +0A35 ; [.2090.0020.0002.0A35] # GURMUKHI LETTER VA +0A5C ; [.2091.0020.0002.0A5C] # GURMUKHI LETTER RRA +0A3E ; [.2092.0020.0002.0A3E] # GURMUKHI VOWEL SIGN AA +0A3F ; [.2093.0020.0002.0A3F] # GURMUKHI VOWEL SIGN I +0A40 ; [.2094.0020.0002.0A40] # GURMUKHI VOWEL SIGN II +0A41 ; [.2095.0020.0002.0A41] # GURMUKHI VOWEL SIGN U +0A42 ; [.2096.0020.0002.0A42] # GURMUKHI VOWEL SIGN UU +0A47 ; [.2097.0020.0002.0A47] # GURMUKHI VOWEL SIGN EE +0A48 ; [.2098.0020.0002.0A48] # GURMUKHI VOWEL SIGN AI +0A4B ; [.2099.0020.0002.0A4B] # GURMUKHI VOWEL SIGN OO +0A4C ; [.209A.0020.0002.0A4C] # GURMUKHI VOWEL SIGN AU +0A4D ; [.209B.0020.0002.0A4D] # GURMUKHI SIGN VIRAMA +0AD0 ; [.209C.0020.0002.0AD0] # GUJARATI OM +0A85 ; [.209D.0020.0002.0A85] # GUJARATI LETTER A +0A86 ; [.209E.0020.0002.0A86] # GUJARATI LETTER AA +0A87 ; [.209F.0020.0002.0A87] # GUJARATI LETTER I +0A88 ; [.20A0.0020.0002.0A88] # GUJARATI LETTER II +0A89 ; [.20A1.0020.0002.0A89] # GUJARATI LETTER U +0A8A ; [.20A2.0020.0002.0A8A] # GUJARATI LETTER UU +0A8B ; [.20A3.0020.0002.0A8B] # GUJARATI LETTER VOCALIC R +0AE0 ; [.20A4.0020.0002.0AE0] # GUJARATI LETTER VOCALIC RR +0A8C ; [.20A5.0020.0002.0A8C] # GUJARATI LETTER VOCALIC L +0AE1 ; [.20A6.0020.0002.0AE1] # GUJARATI LETTER VOCALIC LL +0A8D ; [.20A7.0020.0002.0A8D] # GUJARATI VOWEL CANDRA E +0A8F ; [.20A8.0020.0002.0A8F] # GUJARATI LETTER E +0A90 ; [.20A9.0020.0002.0A90] # GUJARATI LETTER AI +0A91 ; [.20AA.0020.0002.0A91] # GUJARATI VOWEL CANDRA O +0A93 ; [.20AB.0020.0002.0A93] # GUJARATI LETTER O +0A94 ; [.20AC.0020.0002.0A94] # GUJARATI LETTER AU +0A95 ; [.20AD.0020.0002.0A95] # GUJARATI LETTER KA +0A96 ; [.20AE.0020.0002.0A96] # GUJARATI LETTER KHA +0A97 ; [.20AF.0020.0002.0A97] # GUJARATI LETTER GA +0A98 ; [.20B0.0020.0002.0A98] # GUJARATI LETTER GHA +0A99 ; [.20B1.0020.0002.0A99] # GUJARATI LETTER NGA +0A9A ; [.20B2.0020.0002.0A9A] # GUJARATI LETTER CA +0A9B ; [.20B3.0020.0002.0A9B] # GUJARATI LETTER CHA +0A9C ; [.20B4.0020.0002.0A9C] # GUJARATI LETTER JA +0A9D ; [.20B5.0020.0002.0A9D] # GUJARATI LETTER JHA +0A9E ; [.20B6.0020.0002.0A9E] # GUJARATI LETTER NYA +0A9F ; [.20B7.0020.0002.0A9F] # GUJARATI LETTER TTA +0AA0 ; [.20B8.0020.0002.0AA0] # GUJARATI LETTER TTHA +0AA1 ; [.20B9.0020.0002.0AA1] # GUJARATI LETTER DDA +0AA2 ; [.20BA.0020.0002.0AA2] # GUJARATI LETTER DDHA +0AA3 ; [.20BB.0020.0002.0AA3] # GUJARATI LETTER NNA +0AA4 ; [.20BC.0020.0002.0AA4] # GUJARATI LETTER TA +0AA5 ; [.20BD.0020.0002.0AA5] # GUJARATI LETTER THA +0AA6 ; [.20BE.0020.0002.0AA6] # GUJARATI LETTER DA +0AA7 ; [.20BF.0020.0002.0AA7] # GUJARATI LETTER DHA +0AA8 ; [.20C0.0020.0002.0AA8] # GUJARATI LETTER NA +0AAA ; [.20C1.0020.0002.0AAA] # GUJARATI LETTER PA +0AAB ; [.20C2.0020.0002.0AAB] # GUJARATI LETTER PHA +0AAC ; [.20C3.0020.0002.0AAC] # GUJARATI LETTER BA +0AAD ; [.20C4.0020.0002.0AAD] # GUJARATI LETTER BHA +0AAE ; [.20C5.0020.0002.0AAE] # GUJARATI LETTER MA +0AAF ; [.20C6.0020.0002.0AAF] # GUJARATI LETTER YA +0AB0 ; [.20C7.0020.0002.0AB0] # GUJARATI LETTER RA +0AB2 ; [.20C8.0020.0002.0AB2] # GUJARATI LETTER LA +0AB5 ; [.20C9.0020.0002.0AB5] # GUJARATI LETTER VA +0AB6 ; [.20CA.0020.0002.0AB6] # GUJARATI LETTER SHA +0AB7 ; [.20CB.0020.0002.0AB7] # GUJARATI LETTER SSA +0AB8 ; [.20CC.0020.0002.0AB8] # GUJARATI LETTER SA +0AB9 ; [.20CD.0020.0002.0AB9] # GUJARATI LETTER HA +0AB3 ; [.20CE.0020.0002.0AB3] # GUJARATI LETTER LLA +0ABD ; [.20CF.0020.0002.0ABD] # GUJARATI SIGN AVAGRAHA +0ABE ; [.20D0.0020.0002.0ABE] # GUJARATI VOWEL SIGN AA +0ABF ; [.20D1.0020.0002.0ABF] # GUJARATI VOWEL SIGN I +0AC0 ; [.20D2.0020.0002.0AC0] # GUJARATI VOWEL SIGN II +0AC1 ; [.20D3.0020.0002.0AC1] # GUJARATI VOWEL SIGN U +0AC2 ; [.20D4.0020.0002.0AC2] # GUJARATI VOWEL SIGN UU +0AC3 ; [.20D5.0020.0002.0AC3] # GUJARATI VOWEL SIGN VOCALIC R +0AC4 ; [.20D6.0020.0002.0AC4] # GUJARATI VOWEL SIGN VOCALIC RR +0AE2 ; [.20D7.0020.0002.0AE2] # GUJARATI VOWEL SIGN VOCALIC L +0AE3 ; [.20D8.0020.0002.0AE3] # GUJARATI VOWEL SIGN VOCALIC LL +0AC5 ; [.20D9.0020.0002.0AC5] # GUJARATI VOWEL SIGN CANDRA E +0AC7 ; [.20DA.0020.0002.0AC7] # GUJARATI VOWEL SIGN E +0AC8 ; [.20DB.0020.0002.0AC8] # GUJARATI VOWEL SIGN AI +0AC9 ; [.20DC.0020.0002.0AC9] # GUJARATI VOWEL SIGN CANDRA O +0ACB ; [.20DD.0020.0002.0ACB] # GUJARATI VOWEL SIGN O +0ACC ; [.20DE.0020.0002.0ACC] # GUJARATI VOWEL SIGN AU +0ACD ; [.20DF.0020.0002.0ACD] # GUJARATI SIGN VIRAMA +0B05 ; [.20E0.0020.0002.0B05] # ORIYA LETTER A +0B06 ; [.20E1.0020.0002.0B06] # ORIYA LETTER AA +0B07 ; [.20E2.0020.0002.0B07] # ORIYA LETTER I +0B08 ; [.20E3.0020.0002.0B08] # ORIYA LETTER II +0B09 ; [.20E4.0020.0002.0B09] # ORIYA LETTER U +0B0A ; [.20E5.0020.0002.0B0A] # ORIYA LETTER UU +0B0B ; [.20E6.0020.0002.0B0B] # ORIYA LETTER VOCALIC R +0B60 ; [.20E7.0020.0002.0B60] # ORIYA LETTER VOCALIC RR +0B0C ; [.20E8.0020.0002.0B0C] # ORIYA LETTER VOCALIC L +0B61 ; [.20E9.0020.0002.0B61] # ORIYA LETTER VOCALIC LL +0B0F ; [.20EA.0020.0002.0B0F] # ORIYA LETTER E +0B10 ; [.20EB.0020.0002.0B10] # ORIYA LETTER AI +0B13 ; [.20EC.0020.0002.0B13] # ORIYA LETTER O +0B14 ; [.20ED.0020.0002.0B14] # ORIYA LETTER AU +0B15 ; [.20EE.0020.0002.0B15] # ORIYA LETTER KA +0B16 ; [.20EF.0020.0002.0B16] # ORIYA LETTER KHA +0B17 ; [.20F0.0020.0002.0B17] # ORIYA LETTER GA +0B18 ; [.20F1.0020.0002.0B18] # ORIYA LETTER GHA +0B19 ; [.20F2.0020.0002.0B19] # ORIYA LETTER NGA +0B1A ; [.20F3.0020.0002.0B1A] # ORIYA LETTER CA +0B1B ; [.20F4.0020.0002.0B1B] # ORIYA LETTER CHA +0B1C ; [.20F5.0020.0002.0B1C] # ORIYA LETTER JA +0B1D ; [.20F6.0020.0002.0B1D] # ORIYA LETTER JHA +0B1E ; [.20F7.0020.0002.0B1E] # ORIYA LETTER NYA +0B1F ; [.20F8.0020.0002.0B1F] # ORIYA LETTER TTA +0B20 ; [.20F9.0020.0002.0B20] # ORIYA LETTER TTHA +0B21 ; [.20FA.0020.0002.0B21] # ORIYA LETTER DDA +0B5C ; [.20FA.0020.0002.0B21][.0000.00F1.0002.093C] # ORIYA LETTER RRA +0B22 ; [.20FB.0020.0002.0B22] # ORIYA LETTER DDHA +0B5D ; [.20FB.0020.0002.0B22][.0000.00F1.0002.093C] # ORIYA LETTER RHA +0B23 ; [.20FC.0020.0002.0B23] # ORIYA LETTER NNA +0B24 ; [.20FD.0020.0002.0B24] # ORIYA LETTER TA +0B25 ; [.20FE.0020.0002.0B25] # ORIYA LETTER THA +0B26 ; [.20FF.0020.0002.0B26] # ORIYA LETTER DA +0B27 ; [.2100.0020.0002.0B27] # ORIYA LETTER DHA +0B28 ; [.2101.0020.0002.0B28] # ORIYA LETTER NA +0B2A ; [.2102.0020.0002.0B2A] # ORIYA LETTER PA +0B2B ; [.2103.0020.0002.0B2B] # ORIYA LETTER PHA +0B2C ; [.2104.0020.0002.0B2C] # ORIYA LETTER BA +0B2D ; [.2105.0020.0002.0B2D] # ORIYA LETTER BHA +0B2E ; [.2106.0020.0002.0B2E] # ORIYA LETTER MA +0B2F ; [.2107.0020.0002.0B2F] # ORIYA LETTER YA +0B5F ; [.2108.0020.0002.0B5F] # ORIYA LETTER YYA +0B30 ; [.2109.0020.0002.0B30] # ORIYA LETTER RA +0B32 ; [.210A.0020.0002.0B32] # ORIYA LETTER LA +0B33 ; [.210B.0020.0002.0B33] # ORIYA LETTER LLA +0B35 ; [.210C.0020.0002.0B35] # ORIYA LETTER VA +0B71 ; [.210D.0020.0002.0B71] # ORIYA LETTER WA +0B36 ; [.210E.0020.0002.0B36] # ORIYA LETTER SHA +0B37 ; [.210F.0020.0002.0B37] # ORIYA LETTER SSA +0B38 ; [.2110.0020.0002.0B38] # ORIYA LETTER SA +0B39 ; [.2111.0020.0002.0B39] # ORIYA LETTER HA +0B3D ; [.2112.0020.0002.0B3D] # ORIYA SIGN AVAGRAHA +0B3E ; [.2113.0020.0002.0B3E] # ORIYA VOWEL SIGN AA +0B3F ; [.2114.0020.0002.0B3F] # ORIYA VOWEL SIGN I +0B40 ; [.2115.0020.0002.0B40] # ORIYA VOWEL SIGN II +0B41 ; [.2116.0020.0002.0B41] # ORIYA VOWEL SIGN U +0B42 ; [.2117.0020.0002.0B42] # ORIYA VOWEL SIGN UU +0B43 ; [.2118.0020.0002.0B43] # ORIYA VOWEL SIGN VOCALIC R +0B44 ; [.2119.0020.0002.0B44] # ORIYA VOWEL SIGN VOCALIC RR +0B62 ; [.211A.0020.0002.0B62] # ORIYA VOWEL SIGN VOCALIC L +0B63 ; [.211B.0020.0002.0B63] # ORIYA VOWEL SIGN VOCALIC LL +0B47 ; [.211C.0020.0002.0B47] # ORIYA VOWEL SIGN E +0B48 ; [.211D.0020.0002.0B48] # ORIYA VOWEL SIGN AI +0B47 0B56 ; [.211D.0020.0002.0B48] # ORIYA VOWEL SIGN AI +0B4B ; [.211E.0020.0002.0B4B] # ORIYA VOWEL SIGN O +0B47 0B3E ; [.211E.0020.0002.0B4B] # ORIYA VOWEL SIGN O +0B4C ; [.211F.0020.0002.0B4C] # ORIYA VOWEL SIGN AU +0B47 0B57 ; [.211F.0020.0002.0B4C] # ORIYA VOWEL SIGN AU +0B4D ; [.2120.0020.0002.0B4D] # ORIYA SIGN VIRAMA +0B56 ; [.2121.0020.0002.0B56] # ORIYA AI LENGTH MARK +0B57 ; [.2122.0020.0002.0B57] # ORIYA AU LENGTH MARK +0BD0 ; [.2123.0020.0002.0BD0] # TAMIL OM +0B85 ; [.2124.0020.0002.0B85] # TAMIL LETTER A +0B86 ; [.2125.0020.0002.0B86] # TAMIL LETTER AA +0B87 ; [.2126.0020.0002.0B87] # TAMIL LETTER I +0B88 ; [.2127.0020.0002.0B88] # TAMIL LETTER II +0B89 ; [.2128.0020.0002.0B89] # TAMIL LETTER U +0B8A ; [.2129.0020.0002.0B8A] # TAMIL LETTER UU +0B8E ; [.212A.0020.0002.0B8E] # TAMIL LETTER E +0B8F ; [.212B.0020.0002.0B8F] # TAMIL LETTER EE +0B90 ; [.212C.0020.0002.0B90] # TAMIL LETTER AI +0B92 ; [.212D.0020.0002.0B92] # TAMIL LETTER O +0B93 ; [.212E.0020.0002.0B93] # TAMIL LETTER OO +0B94 ; [.212F.0020.0002.0B94] # TAMIL LETTER AU +0B92 0BD7 ; [.212F.0020.0002.0B94] # TAMIL LETTER AU +0B83 ; [.2130.0020.0002.0B83] # TAMIL SIGN VISARGA +0B95 ; [.2131.0020.0002.0B95] # TAMIL LETTER KA +0B99 ; [.2132.0020.0002.0B99] # TAMIL LETTER NGA +0B9A ; [.2133.0020.0002.0B9A] # TAMIL LETTER CA +0B9E ; [.2134.0020.0002.0B9E] # TAMIL LETTER NYA +0B9F ; [.2135.0020.0002.0B9F] # TAMIL LETTER TTA +0BA3 ; [.2136.0020.0002.0BA3] # TAMIL LETTER NNA +0BA4 ; [.2137.0020.0002.0BA4] # TAMIL LETTER TA +0BA8 ; [.2138.0020.0002.0BA8] # TAMIL LETTER NA +0BAA ; [.2139.0020.0002.0BAA] # TAMIL LETTER PA +0BAE ; [.213A.0020.0002.0BAE] # TAMIL LETTER MA +0BAF ; [.213B.0020.0002.0BAF] # TAMIL LETTER YA +0BB0 ; [.213C.0020.0002.0BB0] # TAMIL LETTER RA +0BB2 ; [.213D.0020.0002.0BB2] # TAMIL LETTER LA +0BB5 ; [.213E.0020.0002.0BB5] # TAMIL LETTER VA +0BB4 ; [.213F.0020.0002.0BB4] # TAMIL LETTER LLLA +0BB3 ; [.2140.0020.0002.0BB3] # TAMIL LETTER LLA +0BB1 ; [.2141.0020.0002.0BB1] # TAMIL LETTER RRA +0BA9 ; [.2142.0020.0002.0BA9] # TAMIL LETTER NNNA +0B9C ; [.2143.0020.0002.0B9C] # TAMIL LETTER JA +0BB6 ; [.2144.0020.0002.0BB6] # TAMIL LETTER SHA +0BB7 ; [.2145.0020.0002.0BB7] # TAMIL LETTER SSA +0BB8 ; [.2146.0020.0002.0BB8] # TAMIL LETTER SA +0BB9 ; [.2147.0020.0002.0BB9] # TAMIL LETTER HA +0BBE ; [.2148.0020.0002.0BBE] # TAMIL VOWEL SIGN AA +0BBF ; [.2149.0020.0002.0BBF] # TAMIL VOWEL SIGN I +0BC0 ; [.214A.0020.0002.0BC0] # TAMIL VOWEL SIGN II +0BC1 ; [.214B.0020.0002.0BC1] # TAMIL VOWEL SIGN U +0BC2 ; [.214C.0020.0002.0BC2] # TAMIL VOWEL SIGN UU +0BC6 ; [.214D.0020.0002.0BC6] # TAMIL VOWEL SIGN E +0BC7 ; [.214E.0020.0002.0BC7] # TAMIL VOWEL SIGN EE +0BC8 ; [.214F.0020.0002.0BC8] # TAMIL VOWEL SIGN AI +0BCA ; [.2150.0020.0002.0BCA] # TAMIL VOWEL SIGN O +0BC6 0BBE ; [.2150.0020.0002.0BCA] # TAMIL VOWEL SIGN O +0BCB ; [.2151.0020.0002.0BCB] # TAMIL VOWEL SIGN OO +0BC7 0BBE ; [.2151.0020.0002.0BCB] # TAMIL VOWEL SIGN OO +0BCC ; [.2152.0020.0002.0BCC] # TAMIL VOWEL SIGN AU +0BC6 0BD7 ; [.2152.0020.0002.0BCC] # TAMIL VOWEL SIGN AU +0BCD ; [.2153.0020.0002.0BCD] # TAMIL SIGN VIRAMA +0BD7 ; [.2154.0020.0002.0BD7] # TAMIL AU LENGTH MARK +0C05 ; [.2155.0020.0002.0C05] # TELUGU LETTER A +0C06 ; [.2156.0020.0002.0C06] # TELUGU LETTER AA +0C07 ; [.2157.0020.0002.0C07] # TELUGU LETTER I +0C08 ; [.2158.0020.0002.0C08] # TELUGU LETTER II +0C09 ; [.2159.0020.0002.0C09] # TELUGU LETTER U +0C0A ; [.215A.0020.0002.0C0A] # TELUGU LETTER UU +0C0B ; [.215B.0020.0002.0C0B] # TELUGU LETTER VOCALIC R +0C60 ; [.215C.0020.0002.0C60] # TELUGU LETTER VOCALIC RR +0C0C ; [.215D.0020.0002.0C0C] # TELUGU LETTER VOCALIC L +0C61 ; [.215E.0020.0002.0C61] # TELUGU LETTER VOCALIC LL +0C0E ; [.215F.0020.0002.0C0E] # TELUGU LETTER E +0C0F ; [.2160.0020.0002.0C0F] # TELUGU LETTER EE +0C10 ; [.2161.0020.0002.0C10] # TELUGU LETTER AI +0C12 ; [.2162.0020.0002.0C12] # TELUGU LETTER O +0C13 ; [.2163.0020.0002.0C13] # TELUGU LETTER OO +0C14 ; [.2164.0020.0002.0C14] # TELUGU LETTER AU +0C15 ; [.2165.0020.0002.0C15] # TELUGU LETTER KA +0C16 ; [.2166.0020.0002.0C16] # TELUGU LETTER KHA +0C17 ; [.2167.0020.0002.0C17] # TELUGU LETTER GA +0C18 ; [.2168.0020.0002.0C18] # TELUGU LETTER GHA +0C19 ; [.2169.0020.0002.0C19] # TELUGU LETTER NGA +0C1A ; [.216A.0020.0002.0C1A] # TELUGU LETTER CA +0C58 ; [.216B.0020.0002.0C58] # TELUGU LETTER TSA +0C1B ; [.216C.0020.0002.0C1B] # TELUGU LETTER CHA +0C1C ; [.216D.0020.0002.0C1C] # TELUGU LETTER JA +0C59 ; [.216E.0020.0002.0C59] # TELUGU LETTER DZA +0C1D ; [.216F.0020.0002.0C1D] # TELUGU LETTER JHA +0C1E ; [.2170.0020.0002.0C1E] # TELUGU LETTER NYA +0C1F ; [.2171.0020.0002.0C1F] # TELUGU LETTER TTA +0C20 ; [.2172.0020.0002.0C20] # TELUGU LETTER TTHA +0C21 ; [.2173.0020.0002.0C21] # TELUGU LETTER DDA +0C22 ; [.2174.0020.0002.0C22] # TELUGU LETTER DDHA +0C23 ; [.2175.0020.0002.0C23] # TELUGU LETTER NNA +0C24 ; [.2176.0020.0002.0C24] # TELUGU LETTER TA +0C25 ; [.2177.0020.0002.0C25] # TELUGU LETTER THA +0C26 ; [.2178.0020.0002.0C26] # TELUGU LETTER DA +0C27 ; [.2179.0020.0002.0C27] # TELUGU LETTER DHA +0C28 ; [.217A.0020.0002.0C28] # TELUGU LETTER NA +0C2A ; [.217B.0020.0002.0C2A] # TELUGU LETTER PA +0C2B ; [.217C.0020.0002.0C2B] # TELUGU LETTER PHA +0C2C ; [.217D.0020.0002.0C2C] # TELUGU LETTER BA +0C2D ; [.217E.0020.0002.0C2D] # TELUGU LETTER BHA +0C2E ; [.217F.0020.0002.0C2E] # TELUGU LETTER MA +0C2F ; [.2180.0020.0002.0C2F] # TELUGU LETTER YA +0C30 ; [.2181.0020.0002.0C30] # TELUGU LETTER RA +0C31 ; [.2182.0020.0002.0C31] # TELUGU LETTER RRA +0C32 ; [.2183.0020.0002.0C32] # TELUGU LETTER LA +0C35 ; [.2184.0020.0002.0C35] # TELUGU LETTER VA +0C36 ; [.2185.0020.0002.0C36] # TELUGU LETTER SHA +0C37 ; [.2186.0020.0002.0C37] # TELUGU LETTER SSA +0C38 ; [.2187.0020.0002.0C38] # TELUGU LETTER SA +0C39 ; [.2188.0020.0002.0C39] # TELUGU LETTER HA +0C33 ; [.2189.0020.0002.0C33] # TELUGU LETTER LLA +0C3D ; [.218A.0020.0002.0C3D] # TELUGU SIGN AVAGRAHA +0C3E ; [.218B.0020.0002.0C3E] # TELUGU VOWEL SIGN AA +0C3F ; [.218C.0020.0002.0C3F] # TELUGU VOWEL SIGN I +0C40 ; [.218D.0020.0002.0C40] # TELUGU VOWEL SIGN II +0C41 ; [.218E.0020.0002.0C41] # TELUGU VOWEL SIGN U +0C42 ; [.218F.0020.0002.0C42] # TELUGU VOWEL SIGN UU +0C43 ; [.2190.0020.0002.0C43] # TELUGU VOWEL SIGN VOCALIC R +0C44 ; [.2191.0020.0002.0C44] # TELUGU VOWEL SIGN VOCALIC RR +0C62 ; [.2192.0020.0002.0C62] # TELUGU VOWEL SIGN VOCALIC L +0C63 ; [.2193.0020.0002.0C63] # TELUGU VOWEL SIGN VOCALIC LL +0C46 ; [.2194.0020.0002.0C46] # TELUGU VOWEL SIGN E +0C47 ; [.2195.0020.0002.0C47] # TELUGU VOWEL SIGN EE +0C48 ; [.2196.0020.0002.0C48] # TELUGU VOWEL SIGN AI +0C46 0C56 ; [.2196.0020.0002.0C48] # TELUGU VOWEL SIGN AI +0C4A ; [.2197.0020.0002.0C4A] # TELUGU VOWEL SIGN O +0C4B ; [.2198.0020.0002.0C4B] # TELUGU VOWEL SIGN OO +0C4C ; [.2199.0020.0002.0C4C] # TELUGU VOWEL SIGN AU +0C4D ; [.219A.0020.0002.0C4D] # TELUGU SIGN VIRAMA +0C55 ; [.219B.0020.0002.0C55] # TELUGU LENGTH MARK +0C56 ; [.219C.0020.0002.0C56] # TELUGU AI LENGTH MARK +0C85 ; [.219D.0020.0002.0C85] # KANNADA LETTER A +0C86 ; [.219E.0020.0002.0C86] # KANNADA LETTER AA +0C87 ; [.219F.0020.0002.0C87] # KANNADA LETTER I +0C88 ; [.21A0.0020.0002.0C88] # KANNADA LETTER II +0C89 ; [.21A1.0020.0002.0C89] # KANNADA LETTER U +0C8A ; [.21A2.0020.0002.0C8A] # KANNADA LETTER UU +0C8B ; [.21A3.0020.0002.0C8B] # KANNADA LETTER VOCALIC R +0CE0 ; [.21A4.0020.0002.0CE0] # KANNADA LETTER VOCALIC RR +0C8C ; [.21A5.0020.0002.0C8C] # KANNADA LETTER VOCALIC L +0CE1 ; [.21A6.0020.0002.0CE1] # KANNADA LETTER VOCALIC LL +0C8E ; [.21A7.0020.0002.0C8E] # KANNADA LETTER E +0C8F ; [.21A8.0020.0002.0C8F] # KANNADA LETTER EE +0C90 ; [.21A9.0020.0002.0C90] # KANNADA LETTER AI +0C92 ; [.21AA.0020.0002.0C92] # KANNADA LETTER O +0C93 ; [.21AB.0020.0002.0C93] # KANNADA LETTER OO +0C94 ; [.21AC.0020.0002.0C94] # KANNADA LETTER AU +0C95 ; [.21AD.0020.0002.0C95] # KANNADA LETTER KA +0C96 ; [.21AE.0020.0002.0C96] # KANNADA LETTER KHA +0C97 ; [.21AF.0020.0002.0C97] # KANNADA LETTER GA +0C98 ; [.21B0.0020.0002.0C98] # KANNADA LETTER GHA +0C99 ; [.21B1.0020.0002.0C99] # KANNADA LETTER NGA +0C9A ; [.21B2.0020.0002.0C9A] # KANNADA LETTER CA +0C9B ; [.21B3.0020.0002.0C9B] # KANNADA LETTER CHA +0C9C ; [.21B4.0020.0002.0C9C] # KANNADA LETTER JA +0C9D ; [.21B5.0020.0002.0C9D] # KANNADA LETTER JHA +0C9E ; [.21B6.0020.0002.0C9E] # KANNADA LETTER NYA +0C9F ; [.21B7.0020.0002.0C9F] # KANNADA LETTER TTA +0CA0 ; [.21B8.0020.0002.0CA0] # KANNADA LETTER TTHA +0CA1 ; [.21B9.0020.0002.0CA1] # KANNADA LETTER DDA +0CA2 ; [.21BA.0020.0002.0CA2] # KANNADA LETTER DDHA +0CA3 ; [.21BB.0020.0002.0CA3] # KANNADA LETTER NNA +0CA4 ; [.21BC.0020.0002.0CA4] # KANNADA LETTER TA +0CA5 ; [.21BD.0020.0002.0CA5] # KANNADA LETTER THA +0CA6 ; [.21BE.0020.0002.0CA6] # KANNADA LETTER DA +0CA7 ; [.21BF.0020.0002.0CA7] # KANNADA LETTER DHA +0CA8 ; [.21C0.0020.0002.0CA8] # KANNADA LETTER NA +0CAA ; [.21C1.0020.0002.0CAA] # KANNADA LETTER PA +0CAB ; [.21C2.0020.0002.0CAB] # KANNADA LETTER PHA +0CAC ; [.21C3.0020.0002.0CAC] # KANNADA LETTER BA +0CAD ; [.21C4.0020.0002.0CAD] # KANNADA LETTER BHA +0CAE ; [.21C5.0020.0002.0CAE] # KANNADA LETTER MA +0CAF ; [.21C6.0020.0002.0CAF] # KANNADA LETTER YA +0CB0 ; [.21C7.0020.0002.0CB0] # KANNADA LETTER RA +0CB1 ; [.21C8.0020.0002.0CB1] # KANNADA LETTER RRA +0CB2 ; [.21C9.0020.0002.0CB2] # KANNADA LETTER LA +0CB5 ; [.21CA.0020.0002.0CB5] # KANNADA LETTER VA +0CB6 ; [.21CB.0020.0002.0CB6] # KANNADA LETTER SHA +0CB7 ; [.21CC.0020.0002.0CB7] # KANNADA LETTER SSA +0CB8 ; [.21CD.0020.0002.0CB8] # KANNADA LETTER SA +0CB9 ; [.21CE.0020.0002.0CB9] # KANNADA LETTER HA +0CB3 ; [.21CF.0020.0002.0CB3] # KANNADA LETTER LLA +0CDE ; [.21D0.0020.0002.0CDE] # KANNADA LETTER FA +0CBD ; [.21D1.0020.0002.0CBD] # KANNADA SIGN AVAGRAHA +0CF1 ; [.21D2.0020.0002.0CF1] # KANNADA SIGN JIHVAMULIYA +0CF2 ; [.21D3.0020.0002.0CF2] # KANNADA SIGN UPADHMANIYA +0CBE ; [.21D4.0020.0002.0CBE] # KANNADA VOWEL SIGN AA +0CBF ; [.21D5.0020.0002.0CBF] # KANNADA VOWEL SIGN I +0CC0 ; [.21D6.0020.0002.0CC0] # KANNADA VOWEL SIGN II +0CBF 0CD5 ; [.21D6.0020.0002.0CC0] # KANNADA VOWEL SIGN II +0CC1 ; [.21D7.0020.0002.0CC1] # KANNADA VOWEL SIGN U +0CC2 ; [.21D8.0020.0002.0CC2] # KANNADA VOWEL SIGN UU +0CC3 ; [.21D9.0020.0002.0CC3] # KANNADA VOWEL SIGN VOCALIC R +0CC4 ; [.21DA.0020.0002.0CC4] # KANNADA VOWEL SIGN VOCALIC RR +0CE2 ; [.21DB.0020.0002.0CE2] # KANNADA VOWEL SIGN VOCALIC L +0CE3 ; [.21DC.0020.0002.0CE3] # KANNADA VOWEL SIGN VOCALIC LL +0CC6 ; [.21DD.0020.0002.0CC6] # KANNADA VOWEL SIGN E +0CC7 ; [.21DE.0020.0002.0CC7] # KANNADA VOWEL SIGN EE +0CC6 0CD5 ; [.21DE.0020.0002.0CC7] # KANNADA VOWEL SIGN EE +0CC8 ; [.21DF.0020.0002.0CC8] # KANNADA VOWEL SIGN AI +0CC6 0CD6 ; [.21DF.0020.0002.0CC8] # KANNADA VOWEL SIGN AI +0CCA ; [.21E0.0020.0002.0CCA] # KANNADA VOWEL SIGN O +0CC6 0CC2 ; [.21E0.0020.0002.0CCA] # KANNADA VOWEL SIGN O +0CCB ; [.21E1.0020.0002.0CCB] # KANNADA VOWEL SIGN OO +0CC6 0CC2 0CD5 ; [.21E1.0020.0002.0CCB] # KANNADA VOWEL SIGN OO +0CCA 0CD5 ; [.21E1.0020.0002.0CCB] # KANNADA VOWEL SIGN OO +0CCC ; [.21E2.0020.0002.0CCC] # KANNADA VOWEL SIGN AU +0CCD ; [.21E3.0020.0002.0CCD] # KANNADA SIGN VIRAMA +0CD5 ; [.21E4.0020.0002.0CD5] # KANNADA LENGTH MARK +0CD6 ; [.21E5.0020.0002.0CD6] # KANNADA AI LENGTH MARK +0D05 ; [.21E6.0020.0002.0D05] # MALAYALAM LETTER A +0D06 ; [.21E7.0020.0002.0D06] # MALAYALAM LETTER AA +0D07 ; [.21E8.0020.0002.0D07] # MALAYALAM LETTER I +0D08 ; [.21E9.0020.0002.0D08] # MALAYALAM LETTER II +0D09 ; [.21EA.0020.0002.0D09] # MALAYALAM LETTER U +0D0A ; [.21EB.0020.0002.0D0A] # MALAYALAM LETTER UU +0D0B ; [.21EC.0020.0002.0D0B] # MALAYALAM LETTER VOCALIC R +0D60 ; [.21ED.0020.0002.0D60] # MALAYALAM LETTER VOCALIC RR +0D0C ; [.21EE.0020.0002.0D0C] # MALAYALAM LETTER VOCALIC L +0D61 ; [.21EF.0020.0002.0D61] # MALAYALAM LETTER VOCALIC LL +0D0E ; [.21F0.0020.0002.0D0E] # MALAYALAM LETTER E +0D0F ; [.21F1.0020.0002.0D0F] # MALAYALAM LETTER EE +0D10 ; [.21F2.0020.0002.0D10] # MALAYALAM LETTER AI +0D12 ; [.21F3.0020.0002.0D12] # MALAYALAM LETTER O +0D13 ; [.21F4.0020.0002.0D13] # MALAYALAM LETTER OO +0D14 ; [.21F5.0020.0002.0D14] # MALAYALAM LETTER AU +0D15 ; [.21F6.0020.0002.0D15] # MALAYALAM LETTER KA +0D7F ; [.21F6.0020.0004.0D7F][.222D.0020.0004.0D7F] # MALAYALAM LETTER CHILLU K +0D16 ; [.21F7.0020.0002.0D16] # MALAYALAM LETTER KHA +0D17 ; [.21F8.0020.0002.0D17] # MALAYALAM LETTER GA +0D18 ; [.21F9.0020.0002.0D18] # MALAYALAM LETTER GHA +0D19 ; [.21FA.0020.0002.0D19] # MALAYALAM LETTER NGA +0D1A ; [.21FB.0020.0002.0D1A] # MALAYALAM LETTER CA +0D1B ; [.21FC.0020.0002.0D1B] # MALAYALAM LETTER CHA +0D1C ; [.21FD.0020.0002.0D1C] # MALAYALAM LETTER JA +0D1D ; [.21FE.0020.0002.0D1D] # MALAYALAM LETTER JHA +0D1E ; [.21FF.0020.0002.0D1E] # MALAYALAM LETTER NYA +0D1F ; [.2200.0020.0002.0D1F] # MALAYALAM LETTER TTA +0D20 ; [.2201.0020.0002.0D20] # MALAYALAM LETTER TTHA +0D21 ; [.2202.0020.0002.0D21] # MALAYALAM LETTER DDA +0D22 ; [.2203.0020.0002.0D22] # MALAYALAM LETTER DDHA +0D23 ; [.2204.0020.0002.0D23] # MALAYALAM LETTER NNA +0D7A ; [.2204.0020.0004.0D7A][.222D.0020.0004.0D7A] # MALAYALAM LETTER CHILLU NN +0D24 ; [.2205.0020.0002.0D24] # MALAYALAM LETTER TA +0D25 ; [.2206.0020.0002.0D25] # MALAYALAM LETTER THA +0D26 ; [.2207.0020.0002.0D26] # MALAYALAM LETTER DA +0D27 ; [.2208.0020.0002.0D27] # MALAYALAM LETTER DHA +0D28 ; [.2209.0020.0002.0D28] # MALAYALAM LETTER NA +0D7B ; [.2209.0020.0004.0D7B][.222D.0020.0004.0D7B] # MALAYALAM LETTER CHILLU N +0D29 ; [.220A.0020.0002.0D29] # MALAYALAM LETTER NNNA +0D2A ; [.220B.0020.0002.0D2A] # MALAYALAM LETTER PA +0D2B ; [.220C.0020.0002.0D2B] # MALAYALAM LETTER PHA +0D2C ; [.220D.0020.0002.0D2C] # MALAYALAM LETTER BA +0D2D ; [.220E.0020.0002.0D2D] # MALAYALAM LETTER BHA +0D2E ; [.220F.0020.0002.0D2E] # MALAYALAM LETTER MA +0D2F ; [.2210.0020.0002.0D2F] # MALAYALAM LETTER YA +0D30 ; [.2211.0020.0002.0D30] # MALAYALAM LETTER RA +0D4E ; [.2211.0020.0004.0D4E][.222D.0020.0004.0D4E] # MALAYALAM LETTER DOT REPH +0D7C ; [.2211.0020.0004.0D7C][.222D.0020.0004.0D7C] # MALAYALAM LETTER CHILLU RR +0D32 ; [.2212.0020.0002.0D32] # MALAYALAM LETTER LA +0D7D ; [.2212.0020.0004.0D7D][.222D.0020.0004.0D7D] # MALAYALAM LETTER CHILLU L +0D35 ; [.2213.0020.0002.0D35] # MALAYALAM LETTER VA +0D36 ; [.2214.0020.0002.0D36] # MALAYALAM LETTER SHA +0D37 ; [.2215.0020.0002.0D37] # MALAYALAM LETTER SSA +0D38 ; [.2216.0020.0002.0D38] # MALAYALAM LETTER SA +0D39 ; [.2217.0020.0002.0D39] # MALAYALAM LETTER HA +0D33 ; [.2218.0020.0002.0D33] # MALAYALAM LETTER LLA +0D7E ; [.2218.0020.0004.0D7E][.222D.0020.0004.0D7E] # MALAYALAM LETTER CHILLU LL +0D34 ; [.2219.0020.0002.0D34] # MALAYALAM LETTER LLLA +0D31 ; [.221A.0020.0002.0D31] # MALAYALAM LETTER RRA +0D3A ; [.221B.0020.0002.0D3A] # MALAYALAM LETTER TTTA +0D3D ; [.221C.0020.0002.0D3D] # MALAYALAM SIGN AVAGRAHA +0D3E ; [.221D.0020.0002.0D3E] # MALAYALAM VOWEL SIGN AA +0D3F ; [.221E.0020.0002.0D3F] # MALAYALAM VOWEL SIGN I +0D40 ; [.221F.0020.0002.0D40] # MALAYALAM VOWEL SIGN II +0D41 ; [.2220.0020.0002.0D41] # MALAYALAM VOWEL SIGN U +0D42 ; [.2221.0020.0002.0D42] # MALAYALAM VOWEL SIGN UU +0D43 ; [.2222.0020.0002.0D43] # MALAYALAM VOWEL SIGN VOCALIC R +0D44 ; [.2223.0020.0002.0D44] # MALAYALAM VOWEL SIGN VOCALIC RR +0D62 ; [.2224.0020.0002.0D62] # MALAYALAM VOWEL SIGN VOCALIC L +0D63 ; [.2225.0020.0002.0D63] # MALAYALAM VOWEL SIGN VOCALIC LL +0D46 ; [.2226.0020.0002.0D46] # MALAYALAM VOWEL SIGN E +0D47 ; [.2227.0020.0002.0D47] # MALAYALAM VOWEL SIGN EE +0D48 ; [.2228.0020.0002.0D48] # MALAYALAM VOWEL SIGN AI +0D4A ; [.2229.0020.0002.0D4A] # MALAYALAM VOWEL SIGN O +0D46 0D3E ; [.2229.0020.0002.0D4A] # MALAYALAM VOWEL SIGN O +0D4B ; [.222A.0020.0002.0D4B] # MALAYALAM VOWEL SIGN OO +0D47 0D3E ; [.222A.0020.0002.0D4B] # MALAYALAM VOWEL SIGN OO +0D4C ; [.222B.0020.0002.0D4C] # MALAYALAM VOWEL SIGN AU +0D46 0D57 ; [.222B.0020.0002.0D4C] # MALAYALAM VOWEL SIGN AU +0D57 ; [.222C.0020.0002.0D57] # MALAYALAM AU LENGTH MARK +0D4D ; [.222D.0020.0002.0D4D] # MALAYALAM SIGN VIRAMA +0D85 ; [.222E.0020.0002.0D85] # SINHALA LETTER AYANNA +0D86 ; [.222F.0020.0002.0D86] # SINHALA LETTER AAYANNA +0D87 ; [.2230.0020.0002.0D87] # SINHALA LETTER AEYANNA +0D88 ; [.2231.0020.0002.0D88] # SINHALA LETTER AEEYANNA +0D89 ; [.2232.0020.0002.0D89] # SINHALA LETTER IYANNA +0D8A ; [.2233.0020.0002.0D8A] # SINHALA LETTER IIYANNA +0D8B ; [.2234.0020.0002.0D8B] # SINHALA LETTER UYANNA +0D8C ; [.2235.0020.0002.0D8C] # SINHALA LETTER UUYANNA +0D8D ; [.2236.0020.0002.0D8D] # SINHALA LETTER IRUYANNA +0D8E ; [.2237.0020.0002.0D8E] # SINHALA LETTER IRUUYANNA +0D8F ; [.2238.0020.0002.0D8F] # SINHALA LETTER ILUYANNA +0D90 ; [.2239.0020.0002.0D90] # SINHALA LETTER ILUUYANNA +0D91 ; [.223A.0020.0002.0D91] # SINHALA LETTER EYANNA +0D92 ; [.223B.0020.0002.0D92] # SINHALA LETTER EEYANNA +0D93 ; [.223C.0020.0002.0D93] # SINHALA LETTER AIYANNA +0D94 ; [.223D.0020.0002.0D94] # SINHALA LETTER OYANNA +0D95 ; [.223E.0020.0002.0D95] # SINHALA LETTER OOYANNA +0D96 ; [.223F.0020.0002.0D96] # SINHALA LETTER AUYANNA +0D9A ; [.2240.0020.0002.0D9A] # SINHALA LETTER ALPAPRAANA KAYANNA +0D9B ; [.2241.0020.0002.0D9B] # SINHALA LETTER MAHAAPRAANA KAYANNA +0D9C ; [.2242.0020.0002.0D9C] # SINHALA LETTER ALPAPRAANA GAYANNA +0D9D ; [.2243.0020.0002.0D9D] # SINHALA LETTER MAHAAPRAANA GAYANNA +0D9E ; [.2244.0020.0002.0D9E] # SINHALA LETTER KANTAJA NAASIKYAYA +0D9F ; [.2245.0020.0002.0D9F] # SINHALA LETTER SANYAKA GAYANNA +0DA0 ; [.2246.0020.0002.0DA0] # SINHALA LETTER ALPAPRAANA CAYANNA +0DA1 ; [.2247.0020.0002.0DA1] # SINHALA LETTER MAHAAPRAANA CAYANNA +0DA2 ; [.2248.0020.0002.0DA2] # SINHALA LETTER ALPAPRAANA JAYANNA +0DA3 ; [.2249.0020.0002.0DA3] # SINHALA LETTER MAHAAPRAANA JAYANNA +0DA4 ; [.224A.0020.0002.0DA4] # SINHALA LETTER TAALUJA NAASIKYAYA +0DA5 ; [.224B.0020.0002.0DA5] # SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA +0DA6 ; [.224C.0020.0002.0DA6] # SINHALA LETTER SANYAKA JAYANNA +0DA7 ; [.224D.0020.0002.0DA7] # SINHALA LETTER ALPAPRAANA TTAYANNA +0DA8 ; [.224E.0020.0002.0DA8] # SINHALA LETTER MAHAAPRAANA TTAYANNA +0DA9 ; [.224F.0020.0002.0DA9] # SINHALA LETTER ALPAPRAANA DDAYANNA +0DAA ; [.2250.0020.0002.0DAA] # SINHALA LETTER MAHAAPRAANA DDAYANNA +0DAB ; [.2251.0020.0002.0DAB] # SINHALA LETTER MUURDHAJA NAYANNA +0DAC ; [.2252.0020.0002.0DAC] # SINHALA LETTER SANYAKA DDAYANNA +0DAD ; [.2253.0020.0002.0DAD] # SINHALA LETTER ALPAPRAANA TAYANNA +0DAE ; [.2254.0020.0002.0DAE] # SINHALA LETTER MAHAAPRAANA TAYANNA +0DAF ; [.2255.0020.0002.0DAF] # SINHALA LETTER ALPAPRAANA DAYANNA +0DB0 ; [.2256.0020.0002.0DB0] # SINHALA LETTER MAHAAPRAANA DAYANNA +0DB1 ; [.2257.0020.0002.0DB1] # SINHALA LETTER DANTAJA NAYANNA +0DB3 ; [.2258.0020.0002.0DB3] # SINHALA LETTER SANYAKA DAYANNA +0DB4 ; [.2259.0020.0002.0DB4] # SINHALA LETTER ALPAPRAANA PAYANNA +0DB5 ; [.225A.0020.0002.0DB5] # SINHALA LETTER MAHAAPRAANA PAYANNA +0DB6 ; [.225B.0020.0002.0DB6] # SINHALA LETTER ALPAPRAANA BAYANNA +0DB7 ; [.225C.0020.0002.0DB7] # SINHALA LETTER MAHAAPRAANA BAYANNA +0DB8 ; [.225D.0020.0002.0DB8] # SINHALA LETTER MAYANNA +0DB9 ; [.225E.0020.0002.0DB9] # SINHALA LETTER AMBA BAYANNA +0DBA ; [.225F.0020.0002.0DBA] # SINHALA LETTER YAYANNA +0DBB ; [.2260.0020.0002.0DBB] # SINHALA LETTER RAYANNA +0DBD ; [.2261.0020.0002.0DBD] # SINHALA LETTER DANTAJA LAYANNA +0DC0 ; [.2262.0020.0002.0DC0] # SINHALA LETTER VAYANNA +0DC1 ; [.2263.0020.0002.0DC1] # SINHALA LETTER TAALUJA SAYANNA +0DC2 ; [.2264.0020.0002.0DC2] # SINHALA LETTER MUURDHAJA SAYANNA +0DC3 ; [.2265.0020.0002.0DC3] # SINHALA LETTER DANTAJA SAYANNA +0DC4 ; [.2266.0020.0002.0DC4] # SINHALA LETTER HAYANNA +0DC5 ; [.2267.0020.0002.0DC5] # SINHALA LETTER MUURDHAJA LAYANNA +0DC6 ; [.2268.0020.0002.0DC6] # SINHALA LETTER FAYANNA +0DCF ; [.2269.0020.0002.0DCF] # SINHALA VOWEL SIGN AELA-PILLA +0DD0 ; [.226A.0020.0002.0DD0] # SINHALA VOWEL SIGN KETTI AEDA-PILLA +0DD1 ; [.226B.0020.0002.0DD1] # SINHALA VOWEL SIGN DIGA AEDA-PILLA +0DD2 ; [.226C.0020.0002.0DD2] # SINHALA VOWEL SIGN KETTI IS-PILLA +0DD3 ; [.226D.0020.0002.0DD3] # SINHALA VOWEL SIGN DIGA IS-PILLA +0DD4 ; [.226E.0020.0002.0DD4] # SINHALA VOWEL SIGN KETTI PAA-PILLA +0DD6 ; [.226F.0020.0002.0DD6] # SINHALA VOWEL SIGN DIGA PAA-PILLA +0DD8 ; [.2270.0020.0002.0DD8] # SINHALA VOWEL SIGN GAETTA-PILLA +0DF2 ; [.2271.0020.0002.0DF2] # SINHALA VOWEL SIGN DIGA GAETTA-PILLA +0DDF ; [.2272.0020.0002.0DDF] # SINHALA VOWEL SIGN GAYANUKITTA +0DF3 ; [.2273.0020.0002.0DF3] # SINHALA VOWEL SIGN DIGA GAYANUKITTA +0DD9 ; [.2274.0020.0002.0DD9] # SINHALA VOWEL SIGN KOMBUVA +0DDA ; [.2275.0020.0002.0DDA] # SINHALA VOWEL SIGN DIGA KOMBUVA +0DD9 0DCA ; [.2275.0020.0002.0DDA] # SINHALA VOWEL SIGN DIGA KOMBUVA +0DDB ; [.2276.0020.0002.0DDB] # SINHALA VOWEL SIGN KOMBU DEKA +0DDC ; [.2277.0020.0002.0DDC] # SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA +0DD9 0DCF ; [.2277.0020.0002.0DDC] # SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA +0DDD ; [.2278.0020.0002.0DDD] # SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA +0DD9 0DCF 0DCA ; [.2278.0020.0002.0DDD] # SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA +0DDC 0DCA ; [.2278.0020.0002.0DDD] # SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA +0DDE ; [.2279.0020.0002.0DDE] # SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA +0DD9 0DDF ; [.2279.0020.0002.0DDE] # SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA +0DCA ; [.227A.0020.0002.0DCA] # SINHALA SIGN AL-LAKUNA +AAF2 ; [.227B.0020.0002.AAF2] # MEETEI MAYEK ANJI +ABC0 ; [.227C.0020.0002.ABC0] # MEETEI MAYEK LETTER KOK +ABC1 ; [.227D.0020.0002.ABC1] # MEETEI MAYEK LETTER SAM +ABC2 ; [.227E.0020.0002.ABC2] # MEETEI MAYEK LETTER LAI +ABC3 ; [.227F.0020.0002.ABC3] # MEETEI MAYEK LETTER MIT +ABC4 ; [.2280.0020.0002.ABC4] # MEETEI MAYEK LETTER PA +ABC5 ; [.2281.0020.0002.ABC5] # MEETEI MAYEK LETTER NA +ABC6 ; [.2282.0020.0002.ABC6] # MEETEI MAYEK LETTER CHIL +ABC7 ; [.2283.0020.0002.ABC7] # MEETEI MAYEK LETTER TIL +ABC8 ; [.2284.0020.0002.ABC8] # MEETEI MAYEK LETTER KHOU +ABC9 ; [.2285.0020.0002.ABC9] # MEETEI MAYEK LETTER NGOU +ABCA ; [.2286.0020.0002.ABCA] # MEETEI MAYEK LETTER THOU +ABCB ; [.2287.0020.0002.ABCB] # MEETEI MAYEK LETTER WAI +ABCC ; [.2288.0020.0002.ABCC] # MEETEI MAYEK LETTER YANG +ABCD ; [.2289.0020.0002.ABCD] # MEETEI MAYEK LETTER HUK +ABCE ; [.228A.0020.0002.ABCE] # MEETEI MAYEK LETTER UN +ABCF ; [.228B.0020.0002.ABCF] # MEETEI MAYEK LETTER I +ABD0 ; [.228C.0020.0002.ABD0] # MEETEI MAYEK LETTER PHAM +ABD1 ; [.228D.0020.0002.ABD1] # MEETEI MAYEK LETTER ATIYA +ABD2 ; [.228E.0020.0002.ABD2] # MEETEI MAYEK LETTER GOK +ABD3 ; [.228F.0020.0002.ABD3] # MEETEI MAYEK LETTER JHAM +ABD4 ; [.2290.0020.0002.ABD4] # MEETEI MAYEK LETTER RAI +ABD5 ; [.2291.0020.0002.ABD5] # MEETEI MAYEK LETTER BA +ABD6 ; [.2292.0020.0002.ABD6] # MEETEI MAYEK LETTER JIL +ABD7 ; [.2293.0020.0002.ABD7] # MEETEI MAYEK LETTER DIL +ABD8 ; [.2294.0020.0002.ABD8] # MEETEI MAYEK LETTER GHOU +ABD9 ; [.2295.0020.0002.ABD9] # MEETEI MAYEK LETTER DHOU +ABDA ; [.2296.0020.0002.ABDA] # MEETEI MAYEK LETTER BHAM +AAE0 ; [.2297.0020.0002.AAE0] # MEETEI MAYEK LETTER E +AAE1 ; [.2298.0020.0002.AAE1] # MEETEI MAYEK LETTER O +AAE2 ; [.2299.0020.0002.AAE2] # MEETEI MAYEK LETTER CHA +AAE3 ; [.229A.0020.0002.AAE3] # MEETEI MAYEK LETTER NYA +AAE4 ; [.229B.0020.0002.AAE4] # MEETEI MAYEK LETTER TTA +AAE5 ; [.229C.0020.0002.AAE5] # MEETEI MAYEK LETTER TTHA +AAE6 ; [.229D.0020.0002.AAE6] # MEETEI MAYEK LETTER DDA +AAE7 ; [.229E.0020.0002.AAE7] # MEETEI MAYEK LETTER DDHA +AAE8 ; [.229F.0020.0002.AAE8] # MEETEI MAYEK LETTER NNA +AAE9 ; [.22A0.0020.0002.AAE9] # MEETEI MAYEK LETTER SHA +AAEA ; [.22A1.0020.0002.AAEA] # MEETEI MAYEK LETTER SSA +ABE3 ; [.22A2.0020.0002.ABE3] # MEETEI MAYEK VOWEL SIGN ONAP +ABE4 ; [.22A3.0020.0002.ABE4] # MEETEI MAYEK VOWEL SIGN INAP +ABE5 ; [.22A4.0020.0002.ABE5] # MEETEI MAYEK VOWEL SIGN ANAP +ABE6 ; [.22A5.0020.0002.ABE6] # MEETEI MAYEK VOWEL SIGN YENAP +ABE7 ; [.22A6.0020.0002.ABE7] # MEETEI MAYEK VOWEL SIGN SOUNAP +ABE8 ; [.22A7.0020.0002.ABE8] # MEETEI MAYEK VOWEL SIGN UNAP +ABE9 ; [.22A8.0020.0002.ABE9] # MEETEI MAYEK VOWEL SIGN CHEINAP +ABEA ; [.22A9.0020.0002.ABEA] # MEETEI MAYEK VOWEL SIGN NUNG +AAEB ; [.22AA.0020.0002.AAEB] # MEETEI MAYEK VOWEL SIGN II +AAEC ; [.22AB.0020.0002.AAEC] # MEETEI MAYEK VOWEL SIGN UU +AAED ; [.22AC.0020.0002.AAED] # MEETEI MAYEK VOWEL SIGN AAI +AAEE ; [.22AD.0020.0002.AAEE] # MEETEI MAYEK VOWEL SIGN AU +AAEF ; [.22AE.0020.0002.AAEF] # MEETEI MAYEK VOWEL SIGN AAU +AAF5 ; [.22AF.0020.0002.AAF5] # MEETEI MAYEK VOWEL SIGN VISARGA +ABDB ; [.22B0.0020.0002.ABDB] # MEETEI MAYEK LETTER KOK LONSUM +ABDC ; [.22B1.0020.0002.ABDC] # MEETEI MAYEK LETTER LAI LONSUM +ABDD ; [.22B2.0020.0002.ABDD] # MEETEI MAYEK LETTER MIT LONSUM +ABDE ; [.22B3.0020.0002.ABDE] # MEETEI MAYEK LETTER PA LONSUM +ABDF ; [.22B4.0020.0002.ABDF] # MEETEI MAYEK LETTER NA LONSUM +ABE0 ; [.22B5.0020.0002.ABE0] # MEETEI MAYEK LETTER TIL LONSUM +ABE1 ; [.22B6.0020.0002.ABE1] # MEETEI MAYEK LETTER NGOU LONSUM +ABE2 ; [.22B7.0020.0002.ABE2] # MEETEI MAYEK LETTER I LONSUM +ABED ; [.22B8.0020.0002.ABED] # MEETEI MAYEK APUN IYEK +AAF6 ; [.22B9.0020.0002.AAF6] # MEETEI MAYEK VIRAMA +A800 ; [.22BA.0020.0002.A800] # SYLOTI NAGRI LETTER A +A801 ; [.22BB.0020.0002.A801] # SYLOTI NAGRI LETTER I +A802 ; [.22BC.0020.0002.A802] # SYLOTI NAGRI SIGN DVISVARA +A803 ; [.22BD.0020.0002.A803] # SYLOTI NAGRI LETTER U +A804 ; [.22BE.0020.0002.A804] # SYLOTI NAGRI LETTER E +A805 ; [.22BF.0020.0002.A805] # SYLOTI NAGRI LETTER O +A806 ; [.22C0.0020.0002.A806] # SYLOTI NAGRI SIGN HASANTA +A807 ; [.22C1.0020.0002.A807] # SYLOTI NAGRI LETTER KO +A808 ; [.22C2.0020.0002.A808] # SYLOTI NAGRI LETTER KHO +A809 ; [.22C3.0020.0002.A809] # SYLOTI NAGRI LETTER GO +A80A ; [.22C4.0020.0002.A80A] # SYLOTI NAGRI LETTER GHO +A80C ; [.22C5.0020.0002.A80C] # SYLOTI NAGRI LETTER CO +A80D ; [.22C6.0020.0002.A80D] # SYLOTI NAGRI LETTER CHO +A80E ; [.22C7.0020.0002.A80E] # SYLOTI NAGRI LETTER JO +A80F ; [.22C8.0020.0002.A80F] # SYLOTI NAGRI LETTER JHO +A810 ; [.22C9.0020.0002.A810] # SYLOTI NAGRI LETTER TTO +A811 ; [.22CA.0020.0002.A811] # SYLOTI NAGRI LETTER TTHO +A812 ; [.22CB.0020.0002.A812] # SYLOTI NAGRI LETTER DDO +A813 ; [.22CC.0020.0002.A813] # SYLOTI NAGRI LETTER DDHO +A814 ; [.22CD.0020.0002.A814] # SYLOTI NAGRI LETTER TO +A815 ; [.22CE.0020.0002.A815] # SYLOTI NAGRI LETTER THO +A816 ; [.22CF.0020.0002.A816] # SYLOTI NAGRI LETTER DO +A817 ; [.22D0.0020.0002.A817] # SYLOTI NAGRI LETTER DHO +A818 ; [.22D1.0020.0002.A818] # SYLOTI NAGRI LETTER NO +A819 ; [.22D2.0020.0002.A819] # SYLOTI NAGRI LETTER PO +A81A ; [.22D3.0020.0002.A81A] # SYLOTI NAGRI LETTER PHO +A81B ; [.22D4.0020.0002.A81B] # SYLOTI NAGRI LETTER BO +A81C ; [.22D5.0020.0002.A81C] # SYLOTI NAGRI LETTER BHO +A81D ; [.22D6.0020.0002.A81D] # SYLOTI NAGRI LETTER MO +A81E ; [.22D7.0020.0002.A81E] # SYLOTI NAGRI LETTER RO +A81F ; [.22D8.0020.0002.A81F] # SYLOTI NAGRI LETTER LO +A820 ; [.22D9.0020.0002.A820] # SYLOTI NAGRI LETTER RRO +A821 ; [.22DA.0020.0002.A821] # SYLOTI NAGRI LETTER SO +A822 ; [.22DB.0020.0002.A822] # SYLOTI NAGRI LETTER HO +A823 ; [.22DC.0020.0002.A823] # SYLOTI NAGRI VOWEL SIGN A +A824 ; [.22DD.0020.0002.A824] # SYLOTI NAGRI VOWEL SIGN I +A825 ; [.22DE.0020.0002.A825] # SYLOTI NAGRI VOWEL SIGN U +A826 ; [.22DF.0020.0002.A826] # SYLOTI NAGRI VOWEL SIGN E +A827 ; [.22E0.0020.0002.A827] # SYLOTI NAGRI VOWEL SIGN OO +A882 ; [.22E1.0020.0002.A882] # SAURASHTRA LETTER A +A883 ; [.22E2.0020.0002.A883] # SAURASHTRA LETTER AA +A884 ; [.22E3.0020.0002.A884] # SAURASHTRA LETTER I +A885 ; [.22E4.0020.0002.A885] # SAURASHTRA LETTER II +A886 ; [.22E5.0020.0002.A886] # SAURASHTRA LETTER U +A887 ; [.22E6.0020.0002.A887] # SAURASHTRA LETTER UU +A888 ; [.22E7.0020.0002.A888] # SAURASHTRA LETTER VOCALIC R +A889 ; [.22E8.0020.0002.A889] # SAURASHTRA LETTER VOCALIC RR +A88A ; [.22E9.0020.0002.A88A] # SAURASHTRA LETTER VOCALIC L +A88B ; [.22EA.0020.0002.A88B] # SAURASHTRA LETTER VOCALIC LL +A88C ; [.22EB.0020.0002.A88C] # SAURASHTRA LETTER E +A88D ; [.22EC.0020.0002.A88D] # SAURASHTRA LETTER EE +A88E ; [.22ED.0020.0002.A88E] # SAURASHTRA LETTER AI +A88F ; [.22EE.0020.0002.A88F] # SAURASHTRA LETTER O +A890 ; [.22EF.0020.0002.A890] # SAURASHTRA LETTER OO +A891 ; [.22F0.0020.0002.A891] # SAURASHTRA LETTER AU +A892 ; [.22F1.0020.0002.A892] # SAURASHTRA LETTER KA +A893 ; [.22F2.0020.0002.A893] # SAURASHTRA LETTER KHA +A894 ; [.22F3.0020.0002.A894] # SAURASHTRA LETTER GA +A895 ; [.22F4.0020.0002.A895] # SAURASHTRA LETTER GHA +A896 ; [.22F5.0020.0002.A896] # SAURASHTRA LETTER NGA +A897 ; [.22F6.0020.0002.A897] # SAURASHTRA LETTER CA +A898 ; [.22F7.0020.0002.A898] # SAURASHTRA LETTER CHA +A899 ; [.22F8.0020.0002.A899] # SAURASHTRA LETTER JA +A89A ; [.22F9.0020.0002.A89A] # SAURASHTRA LETTER JHA +A89B ; [.22FA.0020.0002.A89B] # SAURASHTRA LETTER NYA +A89C ; [.22FB.0020.0002.A89C] # SAURASHTRA LETTER TTA +A89D ; [.22FC.0020.0002.A89D] # SAURASHTRA LETTER TTHA +A89E ; [.22FD.0020.0002.A89E] # SAURASHTRA LETTER DDA +A89F ; [.22FE.0020.0002.A89F] # SAURASHTRA LETTER DDHA +A8A0 ; [.22FF.0020.0002.A8A0] # SAURASHTRA LETTER NNA +A8A1 ; [.2300.0020.0002.A8A1] # SAURASHTRA LETTER TA +A8A2 ; [.2301.0020.0002.A8A2] # SAURASHTRA LETTER THA +A8A3 ; [.2302.0020.0002.A8A3] # SAURASHTRA LETTER DA +A8A4 ; [.2303.0020.0002.A8A4] # SAURASHTRA LETTER DHA +A8A5 ; [.2304.0020.0002.A8A5] # SAURASHTRA LETTER NA +A8A6 ; [.2305.0020.0002.A8A6] # SAURASHTRA LETTER PA +A8A7 ; [.2306.0020.0002.A8A7] # SAURASHTRA LETTER PHA +A8A8 ; [.2307.0020.0002.A8A8] # SAURASHTRA LETTER BA +A8A9 ; [.2308.0020.0002.A8A9] # SAURASHTRA LETTER BHA +A8AA ; [.2309.0020.0002.A8AA] # SAURASHTRA LETTER MA +A8AB ; [.230A.0020.0002.A8AB] # SAURASHTRA LETTER YA +A8AC ; [.230B.0020.0002.A8AC] # SAURASHTRA LETTER RA +A8AD ; [.230C.0020.0002.A8AD] # SAURASHTRA LETTER LA +A8AE ; [.230D.0020.0002.A8AE] # SAURASHTRA LETTER VA +A8AF ; [.230E.0020.0002.A8AF] # SAURASHTRA LETTER SHA +A8B0 ; [.230F.0020.0002.A8B0] # SAURASHTRA LETTER SSA +A8B1 ; [.2310.0020.0002.A8B1] # SAURASHTRA LETTER SA +A8B2 ; [.2311.0020.0002.A8B2] # SAURASHTRA LETTER HA +A8B3 ; [.2312.0020.0002.A8B3] # SAURASHTRA LETTER LLA +A8B4 ; [.2313.0020.0002.A8B4] # SAURASHTRA CONSONANT SIGN HAARU +A8B5 ; [.2314.0020.0002.A8B5] # SAURASHTRA VOWEL SIGN AA +A8B6 ; [.2315.0020.0002.A8B6] # SAURASHTRA VOWEL SIGN I +A8B7 ; [.2316.0020.0002.A8B7] # SAURASHTRA VOWEL SIGN II +A8B8 ; [.2317.0020.0002.A8B8] # SAURASHTRA VOWEL SIGN U +A8B9 ; [.2318.0020.0002.A8B9] # SAURASHTRA VOWEL SIGN UU +A8BA ; [.2319.0020.0002.A8BA] # SAURASHTRA VOWEL SIGN VOCALIC R +A8BB ; [.231A.0020.0002.A8BB] # SAURASHTRA VOWEL SIGN VOCALIC RR +A8BC ; [.231B.0020.0002.A8BC] # SAURASHTRA VOWEL SIGN VOCALIC L +A8BD ; [.231C.0020.0002.A8BD] # SAURASHTRA VOWEL SIGN VOCALIC LL +A8BE ; [.231D.0020.0002.A8BE] # SAURASHTRA VOWEL SIGN E +A8BF ; [.231E.0020.0002.A8BF] # SAURASHTRA VOWEL SIGN EE +A8C0 ; [.231F.0020.0002.A8C0] # SAURASHTRA VOWEL SIGN AI +A8C1 ; [.2320.0020.0002.A8C1] # SAURASHTRA VOWEL SIGN O +A8C2 ; [.2321.0020.0002.A8C2] # SAURASHTRA VOWEL SIGN OO +A8C3 ; [.2322.0020.0002.A8C3] # SAURASHTRA VOWEL SIGN AU +A8C4 ; [.2323.0020.0002.A8C4] # SAURASHTRA SIGN VIRAMA +11083 ; [.2324.0020.0002.11083] # KAITHI LETTER A +11084 ; [.2325.0020.0002.11084] # KAITHI LETTER AA +11085 ; [.2326.0020.0002.11085] # KAITHI LETTER I +11086 ; [.2327.0020.0002.11086] # KAITHI LETTER II +11087 ; [.2328.0020.0002.11087] # KAITHI LETTER U +11088 ; [.2329.0020.0002.11088] # KAITHI LETTER UU +11089 ; [.232A.0020.0002.11089] # KAITHI LETTER E +1108A ; [.232B.0020.0002.1108A] # KAITHI LETTER AI +1108B ; [.232C.0020.0002.1108B] # KAITHI LETTER O +1108C ; [.232D.0020.0002.1108C] # KAITHI LETTER AU +1108D ; [.232E.0020.0002.1108D] # KAITHI LETTER KA +1108E ; [.232F.0020.0002.1108E] # KAITHI LETTER KHA +1108F ; [.2330.0020.0002.1108F] # KAITHI LETTER GA +11090 ; [.2331.0020.0002.11090] # KAITHI LETTER GHA +11091 ; [.2332.0020.0002.11091] # KAITHI LETTER NGA +11092 ; [.2333.0020.0002.11092] # KAITHI LETTER CA +11093 ; [.2334.0020.0002.11093] # KAITHI LETTER CHA +11094 ; [.2335.0020.0002.11094] # KAITHI LETTER JA +11095 ; [.2336.0020.0002.11095] # KAITHI LETTER JHA +11096 ; [.2337.0020.0002.11096] # KAITHI LETTER NYA +11097 ; [.2338.0020.0002.11097] # KAITHI LETTER TTA +11098 ; [.2339.0020.0002.11098] # KAITHI LETTER TTHA +11099 ; [.233A.0020.0002.11099] # KAITHI LETTER DDA +1109A ; [.233A.0020.0002.11099][.0000.00F1.0002.093C] # KAITHI LETTER DDDHA +1109B ; [.233B.0020.0002.1109B] # KAITHI LETTER DDHA +1109C ; [.233B.0020.0002.1109B][.0000.00F1.0002.093C] # KAITHI LETTER RHA +1109D ; [.233C.0020.0002.1109D] # KAITHI LETTER NNA +1109E ; [.233D.0020.0002.1109E] # KAITHI LETTER TA +1109F ; [.233E.0020.0002.1109F] # KAITHI LETTER THA +110A0 ; [.233F.0020.0002.110A0] # KAITHI LETTER DA +110A1 ; [.2340.0020.0002.110A1] # KAITHI LETTER DHA +110A2 ; [.2341.0020.0002.110A2] # KAITHI LETTER NA +110A3 ; [.2342.0020.0002.110A3] # KAITHI LETTER PA +110A4 ; [.2343.0020.0002.110A4] # KAITHI LETTER PHA +110A5 ; [.2344.0020.0002.110A5] # KAITHI LETTER BA +110AB ; [.2344.0020.0002.110A5][.0000.00F1.0002.093C] # KAITHI LETTER VA +110A6 ; [.2345.0020.0002.110A6] # KAITHI LETTER BHA +110A7 ; [.2346.0020.0002.110A7] # KAITHI LETTER MA +110A8 ; [.2347.0020.0002.110A8] # KAITHI LETTER YA +110A9 ; [.2348.0020.0002.110A9] # KAITHI LETTER RA +110AA ; [.2349.0020.0002.110AA] # KAITHI LETTER LA +110AC ; [.234A.0020.0002.110AC] # KAITHI LETTER SHA +110AD ; [.234B.0020.0002.110AD] # KAITHI LETTER SSA +110AE ; [.234C.0020.0002.110AE] # KAITHI LETTER SA +110AF ; [.234D.0020.0002.110AF] # KAITHI LETTER HA +110B0 ; [.234E.0020.0002.110B0] # KAITHI VOWEL SIGN AA +110B1 ; [.234F.0020.0002.110B1] # KAITHI VOWEL SIGN I +110B2 ; [.2350.0020.0002.110B2] # KAITHI VOWEL SIGN II +110B3 ; [.2351.0020.0002.110B3] # KAITHI VOWEL SIGN U +110B4 ; [.2352.0020.0002.110B4] # KAITHI VOWEL SIGN UU +110B5 ; [.2353.0020.0002.110B5] # KAITHI VOWEL SIGN E +110B6 ; [.2354.0020.0002.110B6] # KAITHI VOWEL SIGN AI +110B7 ; [.2355.0020.0002.110B7] # KAITHI VOWEL SIGN O +110B8 ; [.2356.0020.0002.110B8] # KAITHI VOWEL SIGN AU +110B9 ; [.2357.0020.0002.110B9] # KAITHI SIGN VIRAMA +111C4 ; [.2358.0020.0002.111C4] # SHARADA OM +11183 ; [.2359.0020.0002.11183] # SHARADA LETTER A +11184 ; [.235A.0020.0002.11184] # SHARADA LETTER AA +11185 ; [.235B.0020.0002.11185] # SHARADA LETTER I +11186 ; [.235C.0020.0002.11186] # SHARADA LETTER II +11187 ; [.235D.0020.0002.11187] # SHARADA LETTER U +11188 ; [.235E.0020.0002.11188] # SHARADA LETTER UU +11189 ; [.235F.0020.0002.11189] # SHARADA LETTER VOCALIC R +1118A ; [.2360.0020.0002.1118A] # SHARADA LETTER VOCALIC RR +1118B ; [.2361.0020.0002.1118B] # SHARADA LETTER VOCALIC L +1118C ; [.2362.0020.0002.1118C] # SHARADA LETTER VOCALIC LL +1118D ; [.2363.0020.0002.1118D] # SHARADA LETTER E +1118E ; [.2364.0020.0002.1118E] # SHARADA LETTER AI +1118F ; [.2365.0020.0002.1118F] # SHARADA LETTER O +11190 ; [.2366.0020.0002.11190] # SHARADA LETTER AU +11191 ; [.2367.0020.0002.11191] # SHARADA LETTER KA +11192 ; [.2368.0020.0002.11192] # SHARADA LETTER KHA +11193 ; [.2369.0020.0002.11193] # SHARADA LETTER GA +11194 ; [.236A.0020.0002.11194] # SHARADA LETTER GHA +11195 ; [.236B.0020.0002.11195] # SHARADA LETTER NGA +11196 ; [.236C.0020.0002.11196] # SHARADA LETTER CA +11197 ; [.236D.0020.0002.11197] # SHARADA LETTER CHA +11198 ; [.236E.0020.0002.11198] # SHARADA LETTER JA +11199 ; [.236F.0020.0002.11199] # SHARADA LETTER JHA +1119A ; [.2370.0020.0002.1119A] # SHARADA LETTER NYA +1119B ; [.2371.0020.0002.1119B] # SHARADA LETTER TTA +1119C ; [.2372.0020.0002.1119C] # SHARADA LETTER TTHA +1119D ; [.2373.0020.0002.1119D] # SHARADA LETTER DDA +1119E ; [.2374.0020.0002.1119E] # SHARADA LETTER DDHA +1119F ; [.2375.0020.0002.1119F] # SHARADA LETTER NNA +111A0 ; [.2376.0020.0002.111A0] # SHARADA LETTER TA +111A1 ; [.2377.0020.0002.111A1] # SHARADA LETTER THA +111A2 ; [.2378.0020.0002.111A2] # SHARADA LETTER DA +111A3 ; [.2379.0020.0002.111A3] # SHARADA LETTER DHA +111A4 ; [.237A.0020.0002.111A4] # SHARADA LETTER NA +111A5 ; [.237B.0020.0002.111A5] # SHARADA LETTER PA +111A6 ; [.237C.0020.0002.111A6] # SHARADA LETTER PHA +111A7 ; [.237D.0020.0002.111A7] # SHARADA LETTER BA +111A8 ; [.237E.0020.0002.111A8] # SHARADA LETTER BHA +111A9 ; [.237F.0020.0002.111A9] # SHARADA LETTER MA +111AA ; [.2380.0020.0002.111AA] # SHARADA LETTER YA +111AB ; [.2381.0020.0002.111AB] # SHARADA LETTER RA +111AC ; [.2382.0020.0002.111AC] # SHARADA LETTER LA +111AD ; [.2383.0020.0002.111AD] # SHARADA LETTER LLA +111AE ; [.2384.0020.0002.111AE] # SHARADA LETTER VA +111AF ; [.2385.0020.0002.111AF] # SHARADA LETTER SHA +111B0 ; [.2386.0020.0002.111B0] # SHARADA LETTER SSA +111B1 ; [.2387.0020.0002.111B1] # SHARADA LETTER SA +111B2 ; [.2388.0020.0002.111B2] # SHARADA LETTER HA +111B3 ; [.2389.0020.0002.111B3] # SHARADA VOWEL SIGN AA +111B4 ; [.238A.0020.0002.111B4] # SHARADA VOWEL SIGN I +111B5 ; [.238B.0020.0002.111B5] # SHARADA VOWEL SIGN II +111B6 ; [.238C.0020.0002.111B6] # SHARADA VOWEL SIGN U +111B7 ; [.238D.0020.0002.111B7] # SHARADA VOWEL SIGN UU +111B8 ; [.238E.0020.0002.111B8] # SHARADA VOWEL SIGN VOCALIC R +111B9 ; [.238F.0020.0002.111B9] # SHARADA VOWEL SIGN VOCALIC RR +111BA ; [.2390.0020.0002.111BA] # SHARADA VOWEL SIGN VOCALIC L +111BB ; [.2391.0020.0002.111BB] # SHARADA VOWEL SIGN VOCALIC LL +111BC ; [.2392.0020.0002.111BC] # SHARADA VOWEL SIGN E +111BD ; [.2393.0020.0002.111BD] # SHARADA VOWEL SIGN AI +111BE ; [.2394.0020.0002.111BE] # SHARADA VOWEL SIGN O +111BF ; [.2395.0020.0002.111BF] # SHARADA VOWEL SIGN AU +111C0 ; [.2396.0020.0002.111C0] # SHARADA SIGN VIRAMA +111C1 ; [.2397.0020.0002.111C1] # SHARADA SIGN AVAGRAHA +111C2 ; [.2398.0020.0002.111C2] # SHARADA SIGN JIHVAMULIYA +111C3 ; [.2399.0020.0002.111C3] # SHARADA SIGN UPADHMANIYA +11680 ; [.239A.0020.0002.11680] # TAKRI LETTER A +11681 ; [.239B.0020.0002.11681] # TAKRI LETTER AA +11682 ; [.239C.0020.0002.11682] # TAKRI LETTER I +11683 ; [.239D.0020.0002.11683] # TAKRI LETTER II +11684 ; [.239E.0020.0002.11684] # TAKRI LETTER U +11685 ; [.239F.0020.0002.11685] # TAKRI LETTER UU +11686 ; [.23A0.0020.0002.11686] # TAKRI LETTER E +11687 ; [.23A1.0020.0002.11687] # TAKRI LETTER AI +11688 ; [.23A2.0020.0002.11688] # TAKRI LETTER O +11689 ; [.23A3.0020.0002.11689] # TAKRI LETTER AU +116A8 ; [.23A4.0020.0002.116A8] # TAKRI LETTER SA +116A7 ; [.23A5.0020.0002.116A7] # TAKRI LETTER SHA +116A9 ; [.23A6.0020.0002.116A9] # TAKRI LETTER HA +1168A ; [.23A7.0020.0002.1168A] # TAKRI LETTER KA +1168B ; [.23A8.0020.0002.1168B] # TAKRI LETTER KHA +1168C ; [.23A9.0020.0002.1168C] # TAKRI LETTER GA +1168D ; [.23AA.0020.0002.1168D] # TAKRI LETTER GHA +1168E ; [.23AB.0020.0002.1168E] # TAKRI LETTER NGA +1168F ; [.23AC.0020.0002.1168F] # TAKRI LETTER CA +11690 ; [.23AD.0020.0002.11690] # TAKRI LETTER CHA +11691 ; [.23AE.0020.0002.11691] # TAKRI LETTER JA +11692 ; [.23AF.0020.0002.11692] # TAKRI LETTER JHA +11693 ; [.23B0.0020.0002.11693] # TAKRI LETTER NYA +11694 ; [.23B1.0020.0002.11694] # TAKRI LETTER TTA +11695 ; [.23B2.0020.0002.11695] # TAKRI LETTER TTHA +11696 ; [.23B3.0020.0002.11696] # TAKRI LETTER DDA +11697 ; [.23B4.0020.0002.11697] # TAKRI LETTER DDHA +11698 ; [.23B5.0020.0002.11698] # TAKRI LETTER NNA +11699 ; [.23B6.0020.0002.11699] # TAKRI LETTER TA +1169A ; [.23B7.0020.0002.1169A] # TAKRI LETTER THA +1169B ; [.23B8.0020.0002.1169B] # TAKRI LETTER DA +1169C ; [.23B9.0020.0002.1169C] # TAKRI LETTER DHA +1169D ; [.23BA.0020.0002.1169D] # TAKRI LETTER NA +1169E ; [.23BB.0020.0002.1169E] # TAKRI LETTER PA +1169F ; [.23BC.0020.0002.1169F] # TAKRI LETTER PHA +116A0 ; [.23BD.0020.0002.116A0] # TAKRI LETTER BA +116A1 ; [.23BE.0020.0002.116A1] # TAKRI LETTER BHA +116A2 ; [.23BF.0020.0002.116A2] # TAKRI LETTER MA +116A3 ; [.23C0.0020.0002.116A3] # TAKRI LETTER YA +116A4 ; [.23C1.0020.0002.116A4] # TAKRI LETTER RA +116A5 ; [.23C2.0020.0002.116A5] # TAKRI LETTER LA +116A6 ; [.23C3.0020.0002.116A6] # TAKRI LETTER VA +116AA ; [.23C4.0020.0002.116AA] # TAKRI LETTER RRA +116AD ; [.23C5.0020.0002.116AD] # TAKRI VOWEL SIGN AA +116AE ; [.23C6.0020.0002.116AE] # TAKRI VOWEL SIGN I +116AF ; [.23C7.0020.0002.116AF] # TAKRI VOWEL SIGN II +116B0 ; [.23C8.0020.0002.116B0] # TAKRI VOWEL SIGN U +116B1 ; [.23C9.0020.0002.116B1] # TAKRI VOWEL SIGN UU +116B2 ; [.23CA.0020.0002.116B2] # TAKRI VOWEL SIGN E +116B3 ; [.23CB.0020.0002.116B3] # TAKRI VOWEL SIGN AI +116B4 ; [.23CC.0020.0002.116B4] # TAKRI VOWEL SIGN O +116B5 ; [.23CD.0020.0002.116B5] # TAKRI VOWEL SIGN AU +116B6 ; [.23CE.0020.0002.116B6] # TAKRI SIGN VIRAMA +1B83 ; [.23CF.0020.0002.1B83] # SUNDANESE LETTER A +1BBA ; [.23CF.0020.0004.1BBA] # SUNDANESE AVAGRAHA +1B84 ; [.23D0.0020.0002.1B84] # SUNDANESE LETTER I +1B85 ; [.23D1.0020.0002.1B85] # SUNDANESE LETTER U +1B86 ; [.23D2.0020.0002.1B86] # SUNDANESE LETTER AE +1B87 ; [.23D3.0020.0002.1B87] # SUNDANESE LETTER O +1B88 ; [.23D4.0020.0002.1B88] # SUNDANESE LETTER E +1B89 ; [.23D5.0020.0002.1B89] # SUNDANESE LETTER EU +1B8A ; [.23D6.0020.0002.1B8A] # SUNDANESE LETTER KA +1BBE ; [.23D6.0020.0019.1BBE] # SUNDANESE LETTER FINAL K +1BAE ; [.23D7.0020.0002.1BAE] # SUNDANESE LETTER KHA +1B8B ; [.23D8.0020.0002.1B8B] # SUNDANESE LETTER QA +1B8C ; [.23D9.0020.0002.1B8C] # SUNDANESE LETTER GA +1B8D ; [.23DA.0020.0002.1B8D] # SUNDANESE LETTER NGA +1B8E ; [.23DB.0020.0002.1B8E] # SUNDANESE LETTER CA +1B8F ; [.23DC.0020.0002.1B8F] # SUNDANESE LETTER JA +1B90 ; [.23DD.0020.0002.1B90] # SUNDANESE LETTER ZA +1B91 ; [.23DE.0020.0002.1B91] # SUNDANESE LETTER NYA +1B92 ; [.23DF.0020.0002.1B92] # SUNDANESE LETTER TA +1B93 ; [.23E0.0020.0002.1B93] # SUNDANESE LETTER DA +1B94 ; [.23E1.0020.0002.1B94] # SUNDANESE LETTER NA +1B95 ; [.23E2.0020.0002.1B95] # SUNDANESE LETTER PA +1B96 ; [.23E3.0020.0002.1B96] # SUNDANESE LETTER FA +1B97 ; [.23E4.0020.0002.1B97] # SUNDANESE LETTER VA +1B98 ; [.23E5.0020.0002.1B98] # SUNDANESE LETTER BA +1BBD ; [.23E6.0020.0002.1BBD] # SUNDANESE LETTER BHA +1B99 ; [.23E7.0020.0002.1B99] # SUNDANESE LETTER MA +1BBF ; [.23E7.0020.0019.1BBF] # SUNDANESE LETTER FINAL M +1BAC ; [.23E8.0020.0002.1BAC] # SUNDANESE CONSONANT SIGN PASANGAN MA +1B9A ; [.23E9.0020.0002.1B9A] # SUNDANESE LETTER YA +1BA1 ; [.23EA.0020.0002.1BA1] # SUNDANESE CONSONANT SIGN PAMINGKAL +1B9B ; [.23EB.0020.0002.1B9B] # SUNDANESE LETTER RA +1BA2 ; [.23EC.0020.0002.1BA2] # SUNDANESE CONSONANT SIGN PANYAKRA +1BBB ; [.23ED.0020.0002.1BBB] # SUNDANESE LETTER REU +1B9C ; [.23EE.0020.0002.1B9C] # SUNDANESE LETTER LA +1BA3 ; [.23EF.0020.0002.1BA3] # SUNDANESE CONSONANT SIGN PANYIKU +1BBC ; [.23F0.0020.0002.1BBC] # SUNDANESE LETTER LEU +1B9D ; [.23F1.0020.0002.1B9D] # SUNDANESE LETTER WA +1BAD ; [.23F2.0020.0002.1BAD] # SUNDANESE CONSONANT SIGN PASANGAN WA +1B9E ; [.23F3.0020.0002.1B9E] # SUNDANESE LETTER SA +1B9F ; [.23F4.0020.0002.1B9F] # SUNDANESE LETTER XA +1BAF ; [.23F5.0020.0002.1BAF] # SUNDANESE LETTER SYA +1BA0 ; [.23F6.0020.0002.1BA0] # SUNDANESE LETTER HA +1BA4 ; [.23F7.0020.0002.1BA4] # SUNDANESE VOWEL SIGN PANGHULU +1BA5 ; [.23F8.0020.0002.1BA5] # SUNDANESE VOWEL SIGN PANYUKU +1BA6 ; [.23F9.0020.0002.1BA6] # SUNDANESE VOWEL SIGN PANAELAENG +1BA7 ; [.23FA.0020.0002.1BA7] # SUNDANESE VOWEL SIGN PANOLONG +1BA8 ; [.23FB.0020.0002.1BA8] # SUNDANESE VOWEL SIGN PAMEPET +1BA9 ; [.23FC.0020.0002.1BA9] # SUNDANESE VOWEL SIGN PANEULEUNG +1BAA ; [.23FD.0020.0002.1BAA] # SUNDANESE SIGN PAMAAEH +1BAB ; [.23FE.0020.0002.1BAB] # SUNDANESE SIGN VIRAMA +11005 ; [.23FF.0020.0002.11005] # BRAHMI LETTER A +11006 ; [.2400.0020.0002.11006] # BRAHMI LETTER AA +11007 ; [.2401.0020.0002.11007] # BRAHMI LETTER I +11008 ; [.2402.0020.0002.11008] # BRAHMI LETTER II +11009 ; [.2403.0020.0002.11009] # BRAHMI LETTER U +1100A ; [.2404.0020.0002.1100A] # BRAHMI LETTER UU +1100B ; [.2405.0020.0002.1100B] # BRAHMI LETTER VOCALIC R +1100C ; [.2406.0020.0002.1100C] # BRAHMI LETTER VOCALIC RR +1100D ; [.2407.0020.0002.1100D] # BRAHMI LETTER VOCALIC L +1100E ; [.2408.0020.0002.1100E] # BRAHMI LETTER VOCALIC LL +1100F ; [.2409.0020.0002.1100F] # BRAHMI LETTER E +11010 ; [.240A.0020.0002.11010] # BRAHMI LETTER AI +11011 ; [.240B.0020.0002.11011] # BRAHMI LETTER O +11012 ; [.240C.0020.0002.11012] # BRAHMI LETTER AU +11013 ; [.240D.0020.0002.11013] # BRAHMI LETTER KA +11014 ; [.240E.0020.0002.11014] # BRAHMI LETTER KHA +11015 ; [.240F.0020.0002.11015] # BRAHMI LETTER GA +11016 ; [.2410.0020.0002.11016] # BRAHMI LETTER GHA +11017 ; [.2411.0020.0002.11017] # BRAHMI LETTER NGA +11018 ; [.2412.0020.0002.11018] # BRAHMI LETTER CA +11019 ; [.2413.0020.0002.11019] # BRAHMI LETTER CHA +1101A ; [.2414.0020.0002.1101A] # BRAHMI LETTER JA +1101B ; [.2415.0020.0002.1101B] # BRAHMI LETTER JHA +1101C ; [.2416.0020.0002.1101C] # BRAHMI LETTER NYA +1101D ; [.2417.0020.0002.1101D] # BRAHMI LETTER TTA +1101E ; [.2418.0020.0002.1101E] # BRAHMI LETTER TTHA +1101F ; [.2419.0020.0002.1101F] # BRAHMI LETTER DDA +11020 ; [.241A.0020.0002.11020] # BRAHMI LETTER DDHA +11021 ; [.241B.0020.0002.11021] # BRAHMI LETTER NNA +11022 ; [.241C.0020.0002.11022] # BRAHMI LETTER TA +11023 ; [.241D.0020.0002.11023] # BRAHMI LETTER THA +11024 ; [.241E.0020.0002.11024] # BRAHMI LETTER DA +11025 ; [.241F.0020.0002.11025] # BRAHMI LETTER DHA +11026 ; [.2420.0020.0002.11026] # BRAHMI LETTER NA +11027 ; [.2421.0020.0002.11027] # BRAHMI LETTER PA +11028 ; [.2422.0020.0002.11028] # BRAHMI LETTER PHA +11029 ; [.2423.0020.0002.11029] # BRAHMI LETTER BA +1102A ; [.2424.0020.0002.1102A] # BRAHMI LETTER BHA +1102B ; [.2425.0020.0002.1102B] # BRAHMI LETTER MA +1102C ; [.2426.0020.0002.1102C] # BRAHMI LETTER YA +1102D ; [.2427.0020.0002.1102D] # BRAHMI LETTER RA +1102E ; [.2428.0020.0002.1102E] # BRAHMI LETTER LA +1102F ; [.2429.0020.0002.1102F] # BRAHMI LETTER VA +11030 ; [.242A.0020.0002.11030] # BRAHMI LETTER SHA +11031 ; [.242B.0020.0002.11031] # BRAHMI LETTER SSA +11032 ; [.242C.0020.0002.11032] # BRAHMI LETTER SA +11033 ; [.242D.0020.0002.11033] # BRAHMI LETTER HA +11003 ; [.242E.0020.0002.11003] # BRAHMI SIGN JIHVAMULIYA +11004 ; [.242F.0020.0002.11004] # BRAHMI SIGN UPADHMANIYA +11034 ; [.2430.0020.0002.11034] # BRAHMI LETTER LLA +11035 ; [.2431.0020.0002.11035] # BRAHMI LETTER OLD TAMIL LLLA +11036 ; [.2432.0020.0002.11036] # BRAHMI LETTER OLD TAMIL RRA +11037 ; [.2433.0020.0002.11037] # BRAHMI LETTER OLD TAMIL NNNA +11038 ; [.2434.0020.0002.11038] # BRAHMI VOWEL SIGN AA +11039 ; [.2435.0020.0002.11039] # BRAHMI VOWEL SIGN BHATTIPROLU AA +1103A ; [.2436.0020.0002.1103A] # BRAHMI VOWEL SIGN I +1103B ; [.2437.0020.0002.1103B] # BRAHMI VOWEL SIGN II +1103C ; [.2438.0020.0002.1103C] # BRAHMI VOWEL SIGN U +1103D ; [.2439.0020.0002.1103D] # BRAHMI VOWEL SIGN UU +1103E ; [.243A.0020.0002.1103E] # BRAHMI VOWEL SIGN VOCALIC R +1103F ; [.243B.0020.0002.1103F] # BRAHMI VOWEL SIGN VOCALIC RR +11040 ; [.243C.0020.0002.11040] # BRAHMI VOWEL SIGN VOCALIC L +11041 ; [.243D.0020.0002.11041] # BRAHMI VOWEL SIGN VOCALIC LL +11042 ; [.243E.0020.0002.11042] # BRAHMI VOWEL SIGN E +11043 ; [.243F.0020.0002.11043] # BRAHMI VOWEL SIGN AI +11044 ; [.2440.0020.0002.11044] # BRAHMI VOWEL SIGN O +11045 ; [.2441.0020.0002.11045] # BRAHMI VOWEL SIGN AU +11046 ; [.2442.0020.0002.11046] # BRAHMI VIRAMA +10A00 ; [.2443.0020.0002.10A00] # KHAROSHTHI LETTER A +10A01 ; [.2444.0020.0002.10A01] # KHAROSHTHI VOWEL SIGN I +10A02 ; [.2445.0020.0002.10A02] # KHAROSHTHI VOWEL SIGN U +10A03 ; [.2446.0020.0002.10A03] # KHAROSHTHI VOWEL SIGN VOCALIC R +10A05 ; [.2447.0020.0002.10A05] # KHAROSHTHI VOWEL SIGN E +10A06 ; [.2448.0020.0002.10A06] # KHAROSHTHI VOWEL SIGN O +10A0C ; [.2449.0020.0002.10A0C] # KHAROSHTHI VOWEL LENGTH MARK +10A10 ; [.244A.0020.0002.10A10] # KHAROSHTHI LETTER KA +10A11 ; [.244B.0020.0002.10A11] # KHAROSHTHI LETTER KHA +10A12 ; [.244C.0020.0002.10A12] # KHAROSHTHI LETTER GA +10A13 ; [.244D.0020.0002.10A13] # KHAROSHTHI LETTER GHA +10A15 ; [.244E.0020.0002.10A15] # KHAROSHTHI LETTER CA +10A16 ; [.244F.0020.0002.10A16] # KHAROSHTHI LETTER CHA +10A17 ; [.2450.0020.0002.10A17] # KHAROSHTHI LETTER JA +10A19 ; [.2451.0020.0002.10A19] # KHAROSHTHI LETTER NYA +10A1A ; [.2452.0020.0002.10A1A] # KHAROSHTHI LETTER TTA +10A1B ; [.2453.0020.0002.10A1B] # KHAROSHTHI LETTER TTHA +10A1C ; [.2454.0020.0002.10A1C] # KHAROSHTHI LETTER DDA +10A1D ; [.2455.0020.0002.10A1D] # KHAROSHTHI LETTER DDHA +10A1E ; [.2456.0020.0002.10A1E] # KHAROSHTHI LETTER NNA +10A1F ; [.2457.0020.0002.10A1F] # KHAROSHTHI LETTER TA +10A20 ; [.2458.0020.0002.10A20] # KHAROSHTHI LETTER THA +10A21 ; [.2459.0020.0002.10A21] # KHAROSHTHI LETTER DA +10A22 ; [.245A.0020.0002.10A22] # KHAROSHTHI LETTER DHA +10A23 ; [.245B.0020.0002.10A23] # KHAROSHTHI LETTER NA +10A24 ; [.245C.0020.0002.10A24] # KHAROSHTHI LETTER PA +10A25 ; [.245D.0020.0002.10A25] # KHAROSHTHI LETTER PHA +10A26 ; [.245E.0020.0002.10A26] # KHAROSHTHI LETTER BA +10A27 ; [.245F.0020.0002.10A27] # KHAROSHTHI LETTER BHA +10A28 ; [.2460.0020.0002.10A28] # KHAROSHTHI LETTER MA +10A29 ; [.2461.0020.0002.10A29] # KHAROSHTHI LETTER YA +10A2A ; [.2462.0020.0002.10A2A] # KHAROSHTHI LETTER RA +10A2B ; [.2463.0020.0002.10A2B] # KHAROSHTHI LETTER LA +10A2C ; [.2464.0020.0002.10A2C] # KHAROSHTHI LETTER VA +10A2D ; [.2465.0020.0002.10A2D] # KHAROSHTHI LETTER SHA +10A2E ; [.2466.0020.0002.10A2E] # KHAROSHTHI LETTER SSA +10A2F ; [.2467.0020.0002.10A2F] # KHAROSHTHI LETTER SA +10A30 ; [.2468.0020.0002.10A30] # KHAROSHTHI LETTER ZA +10A31 ; [.2469.0020.0002.10A31] # KHAROSHTHI LETTER HA +10A32 ; [.246A.0020.0002.10A32] # KHAROSHTHI LETTER KKA +10A33 ; [.246B.0020.0002.10A33] # KHAROSHTHI LETTER TTTHA +10A3F ; [.246C.0020.0002.10A3F] # KHAROSHTHI VIRAMA +0E01 ; [.246D.0020.0002.0E01] # THAI CHARACTER KO KAI +0E40 0E01 ; [.246D.0020.0002.0E01][.24A7.0020.001F.0E40] # +0E41 0E01 ; [.246D.0020.0002.0E01][.24A8.0020.001F.0E41] # +0E42 0E01 ; [.246D.0020.0002.0E01][.24A9.0020.001F.0E42] # +0E43 0E01 ; [.246D.0020.0002.0E01][.24AA.0020.001F.0E43] # +0E44 0E01 ; [.246D.0020.0002.0E01][.24AB.0020.001F.0E44] # +0E02 ; [.246E.0020.0002.0E02] # THAI CHARACTER KHO KHAI +0E40 0E02 ; [.246E.0020.0002.0E02][.24A7.0020.001F.0E40] # +0E41 0E02 ; [.246E.0020.0002.0E02][.24A8.0020.001F.0E41] # +0E42 0E02 ; [.246E.0020.0002.0E02][.24A9.0020.001F.0E42] # +0E43 0E02 ; [.246E.0020.0002.0E02][.24AA.0020.001F.0E43] # +0E44 0E02 ; [.246E.0020.0002.0E02][.24AB.0020.001F.0E44] # +0E03 ; [.246F.0020.0002.0E03] # THAI CHARACTER KHO KHUAT +0E40 0E03 ; [.246F.0020.0002.0E03][.24A7.0020.001F.0E40] # +0E41 0E03 ; [.246F.0020.0002.0E03][.24A8.0020.001F.0E41] # +0E42 0E03 ; [.246F.0020.0002.0E03][.24A9.0020.001F.0E42] # +0E43 0E03 ; [.246F.0020.0002.0E03][.24AA.0020.001F.0E43] # +0E44 0E03 ; [.246F.0020.0002.0E03][.24AB.0020.001F.0E44] # +0E04 ; [.2470.0020.0002.0E04] # THAI CHARACTER KHO KHWAI +0E40 0E04 ; [.2470.0020.0002.0E04][.24A7.0020.001F.0E40] # +0E41 0E04 ; [.2470.0020.0002.0E04][.24A8.0020.001F.0E41] # +0E42 0E04 ; [.2470.0020.0002.0E04][.24A9.0020.001F.0E42] # +0E43 0E04 ; [.2470.0020.0002.0E04][.24AA.0020.001F.0E43] # +0E44 0E04 ; [.2470.0020.0002.0E04][.24AB.0020.001F.0E44] # +0E05 ; [.2471.0020.0002.0E05] # THAI CHARACTER KHO KHON +0E40 0E05 ; [.2471.0020.0002.0E05][.24A7.0020.001F.0E40] # +0E41 0E05 ; [.2471.0020.0002.0E05][.24A8.0020.001F.0E41] # +0E42 0E05 ; [.2471.0020.0002.0E05][.24A9.0020.001F.0E42] # +0E43 0E05 ; [.2471.0020.0002.0E05][.24AA.0020.001F.0E43] # +0E44 0E05 ; [.2471.0020.0002.0E05][.24AB.0020.001F.0E44] # +0E06 ; [.2472.0020.0002.0E06] # THAI CHARACTER KHO RAKHANG +0E40 0E06 ; [.2472.0020.0002.0E06][.24A7.0020.001F.0E40] # +0E41 0E06 ; [.2472.0020.0002.0E06][.24A8.0020.001F.0E41] # +0E42 0E06 ; [.2472.0020.0002.0E06][.24A9.0020.001F.0E42] # +0E43 0E06 ; [.2472.0020.0002.0E06][.24AA.0020.001F.0E43] # +0E44 0E06 ; [.2472.0020.0002.0E06][.24AB.0020.001F.0E44] # +0E07 ; [.2473.0020.0002.0E07] # THAI CHARACTER NGO NGU +0E40 0E07 ; [.2473.0020.0002.0E07][.24A7.0020.001F.0E40] # +0E41 0E07 ; [.2473.0020.0002.0E07][.24A8.0020.001F.0E41] # +0E42 0E07 ; [.2473.0020.0002.0E07][.24A9.0020.001F.0E42] # +0E43 0E07 ; [.2473.0020.0002.0E07][.24AA.0020.001F.0E43] # +0E44 0E07 ; [.2473.0020.0002.0E07][.24AB.0020.001F.0E44] # +0E08 ; [.2474.0020.0002.0E08] # THAI CHARACTER CHO CHAN +0E40 0E08 ; [.2474.0020.0002.0E08][.24A7.0020.001F.0E40] # +0E41 0E08 ; [.2474.0020.0002.0E08][.24A8.0020.001F.0E41] # +0E42 0E08 ; [.2474.0020.0002.0E08][.24A9.0020.001F.0E42] # +0E43 0E08 ; [.2474.0020.0002.0E08][.24AA.0020.001F.0E43] # +0E44 0E08 ; [.2474.0020.0002.0E08][.24AB.0020.001F.0E44] # +0E09 ; [.2475.0020.0002.0E09] # THAI CHARACTER CHO CHING +0E40 0E09 ; [.2475.0020.0002.0E09][.24A7.0020.001F.0E40] # +0E41 0E09 ; [.2475.0020.0002.0E09][.24A8.0020.001F.0E41] # +0E42 0E09 ; [.2475.0020.0002.0E09][.24A9.0020.001F.0E42] # +0E43 0E09 ; [.2475.0020.0002.0E09][.24AA.0020.001F.0E43] # +0E44 0E09 ; [.2475.0020.0002.0E09][.24AB.0020.001F.0E44] # +0E0A ; [.2476.0020.0002.0E0A] # THAI CHARACTER CHO CHANG +0E40 0E0A ; [.2476.0020.0002.0E0A][.24A7.0020.001F.0E40] # +0E41 0E0A ; [.2476.0020.0002.0E0A][.24A8.0020.001F.0E41] # +0E42 0E0A ; [.2476.0020.0002.0E0A][.24A9.0020.001F.0E42] # +0E43 0E0A ; [.2476.0020.0002.0E0A][.24AA.0020.001F.0E43] # +0E44 0E0A ; [.2476.0020.0002.0E0A][.24AB.0020.001F.0E44] # +0E0B ; [.2477.0020.0002.0E0B] # THAI CHARACTER SO SO +0E40 0E0B ; [.2477.0020.0002.0E0B][.24A7.0020.001F.0E40] # +0E41 0E0B ; [.2477.0020.0002.0E0B][.24A8.0020.001F.0E41] # +0E42 0E0B ; [.2477.0020.0002.0E0B][.24A9.0020.001F.0E42] # +0E43 0E0B ; [.2477.0020.0002.0E0B][.24AA.0020.001F.0E43] # +0E44 0E0B ; [.2477.0020.0002.0E0B][.24AB.0020.001F.0E44] # +0E0C ; [.2478.0020.0002.0E0C] # THAI CHARACTER CHO CHOE +0E40 0E0C ; [.2478.0020.0002.0E0C][.24A7.0020.001F.0E40] # +0E41 0E0C ; [.2478.0020.0002.0E0C][.24A8.0020.001F.0E41] # +0E42 0E0C ; [.2478.0020.0002.0E0C][.24A9.0020.001F.0E42] # +0E43 0E0C ; [.2478.0020.0002.0E0C][.24AA.0020.001F.0E43] # +0E44 0E0C ; [.2478.0020.0002.0E0C][.24AB.0020.001F.0E44] # +0E0D ; [.2479.0020.0002.0E0D] # THAI CHARACTER YO YING +0E40 0E0D ; [.2479.0020.0002.0E0D][.24A7.0020.001F.0E40] # +0E41 0E0D ; [.2479.0020.0002.0E0D][.24A8.0020.001F.0E41] # +0E42 0E0D ; [.2479.0020.0002.0E0D][.24A9.0020.001F.0E42] # +0E43 0E0D ; [.2479.0020.0002.0E0D][.24AA.0020.001F.0E43] # +0E44 0E0D ; [.2479.0020.0002.0E0D][.24AB.0020.001F.0E44] # +0E0E ; [.247A.0020.0002.0E0E] # THAI CHARACTER DO CHADA +0E40 0E0E ; [.247A.0020.0002.0E0E][.24A7.0020.001F.0E40] # +0E41 0E0E ; [.247A.0020.0002.0E0E][.24A8.0020.001F.0E41] # +0E42 0E0E ; [.247A.0020.0002.0E0E][.24A9.0020.001F.0E42] # +0E43 0E0E ; [.247A.0020.0002.0E0E][.24AA.0020.001F.0E43] # +0E44 0E0E ; [.247A.0020.0002.0E0E][.24AB.0020.001F.0E44] # +0E0F ; [.247B.0020.0002.0E0F] # THAI CHARACTER TO PATAK +0E40 0E0F ; [.247B.0020.0002.0E0F][.24A7.0020.001F.0E40] # +0E41 0E0F ; [.247B.0020.0002.0E0F][.24A8.0020.001F.0E41] # +0E42 0E0F ; [.247B.0020.0002.0E0F][.24A9.0020.001F.0E42] # +0E43 0E0F ; [.247B.0020.0002.0E0F][.24AA.0020.001F.0E43] # +0E44 0E0F ; [.247B.0020.0002.0E0F][.24AB.0020.001F.0E44] # +0E10 ; [.247C.0020.0002.0E10] # THAI CHARACTER THO THAN +0E40 0E10 ; [.247C.0020.0002.0E10][.24A7.0020.001F.0E40] # +0E41 0E10 ; [.247C.0020.0002.0E10][.24A8.0020.001F.0E41] # +0E42 0E10 ; [.247C.0020.0002.0E10][.24A9.0020.001F.0E42] # +0E43 0E10 ; [.247C.0020.0002.0E10][.24AA.0020.001F.0E43] # +0E44 0E10 ; [.247C.0020.0002.0E10][.24AB.0020.001F.0E44] # +0E11 ; [.247D.0020.0002.0E11] # THAI CHARACTER THO NANGMONTHO +0E40 0E11 ; [.247D.0020.0002.0E11][.24A7.0020.001F.0E40] # +0E41 0E11 ; [.247D.0020.0002.0E11][.24A8.0020.001F.0E41] # +0E42 0E11 ; [.247D.0020.0002.0E11][.24A9.0020.001F.0E42] # +0E43 0E11 ; [.247D.0020.0002.0E11][.24AA.0020.001F.0E43] # +0E44 0E11 ; [.247D.0020.0002.0E11][.24AB.0020.001F.0E44] # +0E12 ; [.247E.0020.0002.0E12] # THAI CHARACTER THO PHUTHAO +0E40 0E12 ; [.247E.0020.0002.0E12][.24A7.0020.001F.0E40] # +0E41 0E12 ; [.247E.0020.0002.0E12][.24A8.0020.001F.0E41] # +0E42 0E12 ; [.247E.0020.0002.0E12][.24A9.0020.001F.0E42] # +0E43 0E12 ; [.247E.0020.0002.0E12][.24AA.0020.001F.0E43] # +0E44 0E12 ; [.247E.0020.0002.0E12][.24AB.0020.001F.0E44] # +0E13 ; [.247F.0020.0002.0E13] # THAI CHARACTER NO NEN +0E40 0E13 ; [.247F.0020.0002.0E13][.24A7.0020.001F.0E40] # +0E41 0E13 ; [.247F.0020.0002.0E13][.24A8.0020.001F.0E41] # +0E42 0E13 ; [.247F.0020.0002.0E13][.24A9.0020.001F.0E42] # +0E43 0E13 ; [.247F.0020.0002.0E13][.24AA.0020.001F.0E43] # +0E44 0E13 ; [.247F.0020.0002.0E13][.24AB.0020.001F.0E44] # +0E14 ; [.2480.0020.0002.0E14] # THAI CHARACTER DO DEK +0E40 0E14 ; [.2480.0020.0002.0E14][.24A7.0020.001F.0E40] # +0E41 0E14 ; [.2480.0020.0002.0E14][.24A8.0020.001F.0E41] # +0E42 0E14 ; [.2480.0020.0002.0E14][.24A9.0020.001F.0E42] # +0E43 0E14 ; [.2480.0020.0002.0E14][.24AA.0020.001F.0E43] # +0E44 0E14 ; [.2480.0020.0002.0E14][.24AB.0020.001F.0E44] # +0E15 ; [.2481.0020.0002.0E15] # THAI CHARACTER TO TAO +0E40 0E15 ; [.2481.0020.0002.0E15][.24A7.0020.001F.0E40] # +0E41 0E15 ; [.2481.0020.0002.0E15][.24A8.0020.001F.0E41] # +0E42 0E15 ; [.2481.0020.0002.0E15][.24A9.0020.001F.0E42] # +0E43 0E15 ; [.2481.0020.0002.0E15][.24AA.0020.001F.0E43] # +0E44 0E15 ; [.2481.0020.0002.0E15][.24AB.0020.001F.0E44] # +0E16 ; [.2482.0020.0002.0E16] # THAI CHARACTER THO THUNG +0E40 0E16 ; [.2482.0020.0002.0E16][.24A7.0020.001F.0E40] # +0E41 0E16 ; [.2482.0020.0002.0E16][.24A8.0020.001F.0E41] # +0E42 0E16 ; [.2482.0020.0002.0E16][.24A9.0020.001F.0E42] # +0E43 0E16 ; [.2482.0020.0002.0E16][.24AA.0020.001F.0E43] # +0E44 0E16 ; [.2482.0020.0002.0E16][.24AB.0020.001F.0E44] # +0E17 ; [.2483.0020.0002.0E17] # THAI CHARACTER THO THAHAN +0E40 0E17 ; [.2483.0020.0002.0E17][.24A7.0020.001F.0E40] # +0E41 0E17 ; [.2483.0020.0002.0E17][.24A8.0020.001F.0E41] # +0E42 0E17 ; [.2483.0020.0002.0E17][.24A9.0020.001F.0E42] # +0E43 0E17 ; [.2483.0020.0002.0E17][.24AA.0020.001F.0E43] # +0E44 0E17 ; [.2483.0020.0002.0E17][.24AB.0020.001F.0E44] # +0E18 ; [.2484.0020.0002.0E18] # THAI CHARACTER THO THONG +0E40 0E18 ; [.2484.0020.0002.0E18][.24A7.0020.001F.0E40] # +0E41 0E18 ; [.2484.0020.0002.0E18][.24A8.0020.001F.0E41] # +0E42 0E18 ; [.2484.0020.0002.0E18][.24A9.0020.001F.0E42] # +0E43 0E18 ; [.2484.0020.0002.0E18][.24AA.0020.001F.0E43] # +0E44 0E18 ; [.2484.0020.0002.0E18][.24AB.0020.001F.0E44] # +0E19 ; [.2485.0020.0002.0E19] # THAI CHARACTER NO NU +0E40 0E19 ; [.2485.0020.0002.0E19][.24A7.0020.001F.0E40] # +0E41 0E19 ; [.2485.0020.0002.0E19][.24A8.0020.001F.0E41] # +0E42 0E19 ; [.2485.0020.0002.0E19][.24A9.0020.001F.0E42] # +0E43 0E19 ; [.2485.0020.0002.0E19][.24AA.0020.001F.0E43] # +0E44 0E19 ; [.2485.0020.0002.0E19][.24AB.0020.001F.0E44] # +0E1A ; [.2486.0020.0002.0E1A] # THAI CHARACTER BO BAIMAI +0E40 0E1A ; [.2486.0020.0002.0E1A][.24A7.0020.001F.0E40] # +0E41 0E1A ; [.2486.0020.0002.0E1A][.24A8.0020.001F.0E41] # +0E42 0E1A ; [.2486.0020.0002.0E1A][.24A9.0020.001F.0E42] # +0E43 0E1A ; [.2486.0020.0002.0E1A][.24AA.0020.001F.0E43] # +0E44 0E1A ; [.2486.0020.0002.0E1A][.24AB.0020.001F.0E44] # +0E1B ; [.2487.0020.0002.0E1B] # THAI CHARACTER PO PLA +0E40 0E1B ; [.2487.0020.0002.0E1B][.24A7.0020.001F.0E40] # +0E41 0E1B ; [.2487.0020.0002.0E1B][.24A8.0020.001F.0E41] # +0E42 0E1B ; [.2487.0020.0002.0E1B][.24A9.0020.001F.0E42] # +0E43 0E1B ; [.2487.0020.0002.0E1B][.24AA.0020.001F.0E43] # +0E44 0E1B ; [.2487.0020.0002.0E1B][.24AB.0020.001F.0E44] # +0E1C ; [.2488.0020.0002.0E1C] # THAI CHARACTER PHO PHUNG +0E40 0E1C ; [.2488.0020.0002.0E1C][.24A7.0020.001F.0E40] # +0E41 0E1C ; [.2488.0020.0002.0E1C][.24A8.0020.001F.0E41] # +0E42 0E1C ; [.2488.0020.0002.0E1C][.24A9.0020.001F.0E42] # +0E43 0E1C ; [.2488.0020.0002.0E1C][.24AA.0020.001F.0E43] # +0E44 0E1C ; [.2488.0020.0002.0E1C][.24AB.0020.001F.0E44] # +0E1D ; [.2489.0020.0002.0E1D] # THAI CHARACTER FO FA +0E40 0E1D ; [.2489.0020.0002.0E1D][.24A7.0020.001F.0E40] # +0E41 0E1D ; [.2489.0020.0002.0E1D][.24A8.0020.001F.0E41] # +0E42 0E1D ; [.2489.0020.0002.0E1D][.24A9.0020.001F.0E42] # +0E43 0E1D ; [.2489.0020.0002.0E1D][.24AA.0020.001F.0E43] # +0E44 0E1D ; [.2489.0020.0002.0E1D][.24AB.0020.001F.0E44] # +0E1E ; [.248A.0020.0002.0E1E] # THAI CHARACTER PHO PHAN +0E40 0E1E ; [.248A.0020.0002.0E1E][.24A7.0020.001F.0E40] # +0E41 0E1E ; [.248A.0020.0002.0E1E][.24A8.0020.001F.0E41] # +0E42 0E1E ; [.248A.0020.0002.0E1E][.24A9.0020.001F.0E42] # +0E43 0E1E ; [.248A.0020.0002.0E1E][.24AA.0020.001F.0E43] # +0E44 0E1E ; [.248A.0020.0002.0E1E][.24AB.0020.001F.0E44] # +0E1F ; [.248B.0020.0002.0E1F] # THAI CHARACTER FO FAN +0E40 0E1F ; [.248B.0020.0002.0E1F][.24A7.0020.001F.0E40] # +0E41 0E1F ; [.248B.0020.0002.0E1F][.24A8.0020.001F.0E41] # +0E42 0E1F ; [.248B.0020.0002.0E1F][.24A9.0020.001F.0E42] # +0E43 0E1F ; [.248B.0020.0002.0E1F][.24AA.0020.001F.0E43] # +0E44 0E1F ; [.248B.0020.0002.0E1F][.24AB.0020.001F.0E44] # +0E20 ; [.248C.0020.0002.0E20] # THAI CHARACTER PHO SAMPHAO +0E40 0E20 ; [.248C.0020.0002.0E20][.24A7.0020.001F.0E40] # +0E41 0E20 ; [.248C.0020.0002.0E20][.24A8.0020.001F.0E41] # +0E42 0E20 ; [.248C.0020.0002.0E20][.24A9.0020.001F.0E42] # +0E43 0E20 ; [.248C.0020.0002.0E20][.24AA.0020.001F.0E43] # +0E44 0E20 ; [.248C.0020.0002.0E20][.24AB.0020.001F.0E44] # +0E21 ; [.248D.0020.0002.0E21] # THAI CHARACTER MO MA +0E40 0E21 ; [.248D.0020.0002.0E21][.24A7.0020.001F.0E40] # +0E41 0E21 ; [.248D.0020.0002.0E21][.24A8.0020.001F.0E41] # +0E42 0E21 ; [.248D.0020.0002.0E21][.24A9.0020.001F.0E42] # +0E43 0E21 ; [.248D.0020.0002.0E21][.24AA.0020.001F.0E43] # +0E44 0E21 ; [.248D.0020.0002.0E21][.24AB.0020.001F.0E44] # +0E22 ; [.248E.0020.0002.0E22] # THAI CHARACTER YO YAK +0E40 0E22 ; [.248E.0020.0002.0E22][.24A7.0020.001F.0E40] # +0E41 0E22 ; [.248E.0020.0002.0E22][.24A8.0020.001F.0E41] # +0E42 0E22 ; [.248E.0020.0002.0E22][.24A9.0020.001F.0E42] # +0E43 0E22 ; [.248E.0020.0002.0E22][.24AA.0020.001F.0E43] # +0E44 0E22 ; [.248E.0020.0002.0E22][.24AB.0020.001F.0E44] # +0E23 ; [.248F.0020.0002.0E23] # THAI CHARACTER RO RUA +0E40 0E23 ; [.248F.0020.0002.0E23][.24A7.0020.001F.0E40] # +0E41 0E23 ; [.248F.0020.0002.0E23][.24A8.0020.001F.0E41] # +0E42 0E23 ; [.248F.0020.0002.0E23][.24A9.0020.001F.0E42] # +0E43 0E23 ; [.248F.0020.0002.0E23][.24AA.0020.001F.0E43] # +0E44 0E23 ; [.248F.0020.0002.0E23][.24AB.0020.001F.0E44] # +0E24 ; [.2490.0020.0002.0E24] # THAI CHARACTER RU +0E40 0E24 ; [.2490.0020.0002.0E24][.24A7.0020.001F.0E40] # +0E41 0E24 ; [.2490.0020.0002.0E24][.24A8.0020.001F.0E41] # +0E42 0E24 ; [.2490.0020.0002.0E24][.24A9.0020.001F.0E42] # +0E43 0E24 ; [.2490.0020.0002.0E24][.24AA.0020.001F.0E43] # +0E44 0E24 ; [.2490.0020.0002.0E24][.24AB.0020.001F.0E44] # +0E25 ; [.2491.0020.0002.0E25] # THAI CHARACTER LO LING +0E40 0E25 ; [.2491.0020.0002.0E25][.24A7.0020.001F.0E40] # +0E41 0E25 ; [.2491.0020.0002.0E25][.24A8.0020.001F.0E41] # +0E42 0E25 ; [.2491.0020.0002.0E25][.24A9.0020.001F.0E42] # +0E43 0E25 ; [.2491.0020.0002.0E25][.24AA.0020.001F.0E43] # +0E44 0E25 ; [.2491.0020.0002.0E25][.24AB.0020.001F.0E44] # +0E26 ; [.2492.0020.0002.0E26] # THAI CHARACTER LU +0E40 0E26 ; [.2492.0020.0002.0E26][.24A7.0020.001F.0E40] # +0E41 0E26 ; [.2492.0020.0002.0E26][.24A8.0020.001F.0E41] # +0E42 0E26 ; [.2492.0020.0002.0E26][.24A9.0020.001F.0E42] # +0E43 0E26 ; [.2492.0020.0002.0E26][.24AA.0020.001F.0E43] # +0E44 0E26 ; [.2492.0020.0002.0E26][.24AB.0020.001F.0E44] # +0E27 ; [.2493.0020.0002.0E27] # THAI CHARACTER WO WAEN +0E40 0E27 ; [.2493.0020.0002.0E27][.24A7.0020.001F.0E40] # +0E41 0E27 ; [.2493.0020.0002.0E27][.24A8.0020.001F.0E41] # +0E42 0E27 ; [.2493.0020.0002.0E27][.24A9.0020.001F.0E42] # +0E43 0E27 ; [.2493.0020.0002.0E27][.24AA.0020.001F.0E43] # +0E44 0E27 ; [.2493.0020.0002.0E27][.24AB.0020.001F.0E44] # +0E28 ; [.2494.0020.0002.0E28] # THAI CHARACTER SO SALA +0E40 0E28 ; [.2494.0020.0002.0E28][.24A7.0020.001F.0E40] # +0E41 0E28 ; [.2494.0020.0002.0E28][.24A8.0020.001F.0E41] # +0E42 0E28 ; [.2494.0020.0002.0E28][.24A9.0020.001F.0E42] # +0E43 0E28 ; [.2494.0020.0002.0E28][.24AA.0020.001F.0E43] # +0E44 0E28 ; [.2494.0020.0002.0E28][.24AB.0020.001F.0E44] # +0E29 ; [.2495.0020.0002.0E29] # THAI CHARACTER SO RUSI +0E40 0E29 ; [.2495.0020.0002.0E29][.24A7.0020.001F.0E40] # +0E41 0E29 ; [.2495.0020.0002.0E29][.24A8.0020.001F.0E41] # +0E42 0E29 ; [.2495.0020.0002.0E29][.24A9.0020.001F.0E42] # +0E43 0E29 ; [.2495.0020.0002.0E29][.24AA.0020.001F.0E43] # +0E44 0E29 ; [.2495.0020.0002.0E29][.24AB.0020.001F.0E44] # +0E2A ; [.2496.0020.0002.0E2A] # THAI CHARACTER SO SUA +0E40 0E2A ; [.2496.0020.0002.0E2A][.24A7.0020.001F.0E40] # +0E41 0E2A ; [.2496.0020.0002.0E2A][.24A8.0020.001F.0E41] # +0E42 0E2A ; [.2496.0020.0002.0E2A][.24A9.0020.001F.0E42] # +0E43 0E2A ; [.2496.0020.0002.0E2A][.24AA.0020.001F.0E43] # +0E44 0E2A ; [.2496.0020.0002.0E2A][.24AB.0020.001F.0E44] # +0E2B ; [.2497.0020.0002.0E2B] # THAI CHARACTER HO HIP +0E40 0E2B ; [.2497.0020.0002.0E2B][.24A7.0020.001F.0E40] # +0E41 0E2B ; [.2497.0020.0002.0E2B][.24A8.0020.001F.0E41] # +0E42 0E2B ; [.2497.0020.0002.0E2B][.24A9.0020.001F.0E42] # +0E43 0E2B ; [.2497.0020.0002.0E2B][.24AA.0020.001F.0E43] # +0E44 0E2B ; [.2497.0020.0002.0E2B][.24AB.0020.001F.0E44] # +0E2C ; [.2498.0020.0002.0E2C] # THAI CHARACTER LO CHULA +0E40 0E2C ; [.2498.0020.0002.0E2C][.24A7.0020.001F.0E40] # +0E41 0E2C ; [.2498.0020.0002.0E2C][.24A8.0020.001F.0E41] # +0E42 0E2C ; [.2498.0020.0002.0E2C][.24A9.0020.001F.0E42] # +0E43 0E2C ; [.2498.0020.0002.0E2C][.24AA.0020.001F.0E43] # +0E44 0E2C ; [.2498.0020.0002.0E2C][.24AB.0020.001F.0E44] # +0E2D ; [.2499.0020.0002.0E2D] # THAI CHARACTER O ANG +0E40 0E2D ; [.2499.0020.0002.0E2D][.24A7.0020.001F.0E40] # +0E41 0E2D ; [.2499.0020.0002.0E2D][.24A8.0020.001F.0E41] # +0E42 0E2D ; [.2499.0020.0002.0E2D][.24A9.0020.001F.0E42] # +0E43 0E2D ; [.2499.0020.0002.0E2D][.24AA.0020.001F.0E43] # +0E44 0E2D ; [.2499.0020.0002.0E2D][.24AB.0020.001F.0E44] # +0E2E ; [.249A.0020.0002.0E2E] # THAI CHARACTER HO NOKHUK +0E40 0E2E ; [.249A.0020.0002.0E2E][.24A7.0020.001F.0E40] # +0E41 0E2E ; [.249A.0020.0002.0E2E][.24A8.0020.001F.0E41] # +0E42 0E2E ; [.249A.0020.0002.0E2E][.24A9.0020.001F.0E42] # +0E43 0E2E ; [.249A.0020.0002.0E2E][.24AA.0020.001F.0E43] # +0E44 0E2E ; [.249A.0020.0002.0E2E][.24AB.0020.001F.0E44] # +0E2F ; [.249B.0020.0002.0E2F] # THAI CHARACTER PAIYANNOI +0E30 ; [.249C.0020.0002.0E30] # THAI CHARACTER SARA A +0E31 ; [.249D.0020.0002.0E31] # THAI CHARACTER MAI HAN-AKAT +0E32 ; [.249E.0020.0002.0E32] # THAI CHARACTER SARA AA +0E33 ; [.249F.0020.0002.0E33] # THAI CHARACTER SARA AM +0E4D 0E32 ; [.249F.0020.0002.0E33] # THAI CHARACTER SARA AM +0E34 ; [.24A0.0020.0002.0E34] # THAI CHARACTER SARA I +0E35 ; [.24A1.0020.0002.0E35] # THAI CHARACTER SARA II +0E36 ; [.24A2.0020.0002.0E36] # THAI CHARACTER SARA UE +0E37 ; [.24A3.0020.0002.0E37] # THAI CHARACTER SARA UEE +0E38 ; [.24A4.0020.0002.0E38] # THAI CHARACTER SARA U +0E39 ; [.24A5.0020.0002.0E39] # THAI CHARACTER SARA UU +0E3A ; [.24A6.0020.0002.0E3A] # THAI CHARACTER PHINTHU +0E40 ; [.24A7.0020.0002.0E40] # THAI CHARACTER SARA E +0E41 ; [.24A8.0020.0002.0E41] # THAI CHARACTER SARA AE +0E42 ; [.24A9.0020.0002.0E42] # THAI CHARACTER SARA O +0E43 ; [.24AA.0020.0002.0E43] # THAI CHARACTER SARA AI MAIMUAN +0E44 ; [.24AB.0020.0002.0E44] # THAI CHARACTER SARA AI MAIMALAI +0E45 ; [.24AC.0020.0002.0E45] # THAI CHARACTER LAKKHANGYAO +0EDE ; [.24AD.0020.0002.0EDE] # LAO LETTER KHMU GO +0E81 ; [.24AE.0020.0002.0E81] # LAO LETTER KO +0EC0 0E81 ; [.24AE.0020.0002.0E81][.24D8.0020.001F.0EC0] # +0EC1 0E81 ; [.24AE.0020.0002.0E81][.24D9.0020.001F.0EC1] # +0EC2 0E81 ; [.24AE.0020.0002.0E81][.24DA.0020.001F.0EC2] # +0EC3 0E81 ; [.24AE.0020.0002.0E81][.24DB.0020.001F.0EC3] # +0EC4 0E81 ; [.24AE.0020.0002.0E81][.24DC.0020.001F.0EC4] # +0E82 ; [.24AF.0020.0002.0E82] # LAO LETTER KHO SUNG +0EC0 0E82 ; [.24AF.0020.0002.0E82][.24D8.0020.001F.0EC0] # +0EC1 0E82 ; [.24AF.0020.0002.0E82][.24D9.0020.001F.0EC1] # +0EC2 0E82 ; [.24AF.0020.0002.0E82][.24DA.0020.001F.0EC2] # +0EC3 0E82 ; [.24AF.0020.0002.0E82][.24DB.0020.001F.0EC3] # +0EC4 0E82 ; [.24AF.0020.0002.0E82][.24DC.0020.001F.0EC4] # +0E84 ; [.24B0.0020.0002.0E84] # LAO LETTER KHO TAM +0EC0 0E84 ; [.24B0.0020.0002.0E84][.24D8.0020.001F.0EC0] # +0EC1 0E84 ; [.24B0.0020.0002.0E84][.24D9.0020.001F.0EC1] # +0EC2 0E84 ; [.24B0.0020.0002.0E84][.24DA.0020.001F.0EC2] # +0EC3 0E84 ; [.24B0.0020.0002.0E84][.24DB.0020.001F.0EC3] # +0EC4 0E84 ; [.24B0.0020.0002.0E84][.24DC.0020.001F.0EC4] # +0E87 ; [.24B1.0020.0002.0E87] # LAO LETTER NGO +0EC0 0E87 ; [.24B1.0020.0002.0E87][.24D8.0020.001F.0EC0] # +0EC1 0E87 ; [.24B1.0020.0002.0E87][.24D9.0020.001F.0EC1] # +0EC2 0E87 ; [.24B1.0020.0002.0E87][.24DA.0020.001F.0EC2] # +0EC3 0E87 ; [.24B1.0020.0002.0E87][.24DB.0020.001F.0EC3] # +0EC4 0E87 ; [.24B1.0020.0002.0E87][.24DC.0020.001F.0EC4] # +0E88 ; [.24B2.0020.0002.0E88] # LAO LETTER CO +0EC0 0E88 ; [.24B2.0020.0002.0E88][.24D8.0020.001F.0EC0] # +0EC1 0E88 ; [.24B2.0020.0002.0E88][.24D9.0020.001F.0EC1] # +0EC2 0E88 ; [.24B2.0020.0002.0E88][.24DA.0020.001F.0EC2] # +0EC3 0E88 ; [.24B2.0020.0002.0E88][.24DB.0020.001F.0EC3] # +0EC4 0E88 ; [.24B2.0020.0002.0E88][.24DC.0020.001F.0EC4] # +0EAA ; [.24B3.0020.0002.0EAA] # LAO LETTER SO SUNG +0EC0 0EAA ; [.24B3.0020.0002.0EAA][.24D8.0020.001F.0EC0] # +0EC1 0EAA ; [.24B3.0020.0002.0EAA][.24D9.0020.001F.0EC1] # +0EC2 0EAA ; [.24B3.0020.0002.0EAA][.24DA.0020.001F.0EC2] # +0EC3 0EAA ; [.24B3.0020.0002.0EAA][.24DB.0020.001F.0EC3] # +0EC4 0EAA ; [.24B3.0020.0002.0EAA][.24DC.0020.001F.0EC4] # +0E8A ; [.24B4.0020.0002.0E8A] # LAO LETTER SO TAM +0EC0 0E8A ; [.24B4.0020.0002.0E8A][.24D8.0020.001F.0EC0] # +0EC1 0E8A ; [.24B4.0020.0002.0E8A][.24D9.0020.001F.0EC1] # +0EC2 0E8A ; [.24B4.0020.0002.0E8A][.24DA.0020.001F.0EC2] # +0EC3 0E8A ; [.24B4.0020.0002.0E8A][.24DB.0020.001F.0EC3] # +0EC4 0E8A ; [.24B4.0020.0002.0E8A][.24DC.0020.001F.0EC4] # +0EDF ; [.24B5.0020.0002.0EDF] # LAO LETTER KHMU NYO +0E8D ; [.24B6.0020.0002.0E8D] # LAO LETTER NYO +0EC0 0E8D ; [.24B6.0020.0002.0E8D][.24D8.0020.001F.0EC0] # +0EC1 0E8D ; [.24B6.0020.0002.0E8D][.24D9.0020.001F.0EC1] # +0EC2 0E8D ; [.24B6.0020.0002.0E8D][.24DA.0020.001F.0EC2] # +0EC3 0E8D ; [.24B6.0020.0002.0E8D][.24DB.0020.001F.0EC3] # +0EC4 0E8D ; [.24B6.0020.0002.0E8D][.24DC.0020.001F.0EC4] # +0E94 ; [.24B7.0020.0002.0E94] # LAO LETTER DO +0EC0 0E94 ; [.24B7.0020.0002.0E94][.24D8.0020.001F.0EC0] # +0EC1 0E94 ; [.24B7.0020.0002.0E94][.24D9.0020.001F.0EC1] # +0EC2 0E94 ; [.24B7.0020.0002.0E94][.24DA.0020.001F.0EC2] # +0EC3 0E94 ; [.24B7.0020.0002.0E94][.24DB.0020.001F.0EC3] # +0EC4 0E94 ; [.24B7.0020.0002.0E94][.24DC.0020.001F.0EC4] # +0E95 ; [.24B8.0020.0002.0E95] # LAO LETTER TO +0EC0 0E95 ; [.24B8.0020.0002.0E95][.24D8.0020.001F.0EC0] # +0EC1 0E95 ; [.24B8.0020.0002.0E95][.24D9.0020.001F.0EC1] # +0EC2 0E95 ; [.24B8.0020.0002.0E95][.24DA.0020.001F.0EC2] # +0EC3 0E95 ; [.24B8.0020.0002.0E95][.24DB.0020.001F.0EC3] # +0EC4 0E95 ; [.24B8.0020.0002.0E95][.24DC.0020.001F.0EC4] # +0E96 ; [.24B9.0020.0002.0E96] # LAO LETTER THO SUNG +0EC0 0E96 ; [.24B9.0020.0002.0E96][.24D8.0020.001F.0EC0] # +0EC1 0E96 ; [.24B9.0020.0002.0E96][.24D9.0020.001F.0EC1] # +0EC2 0E96 ; [.24B9.0020.0002.0E96][.24DA.0020.001F.0EC2] # +0EC3 0E96 ; [.24B9.0020.0002.0E96][.24DB.0020.001F.0EC3] # +0EC4 0E96 ; [.24B9.0020.0002.0E96][.24DC.0020.001F.0EC4] # +0E97 ; [.24BA.0020.0002.0E97] # LAO LETTER THO TAM +0EC0 0E97 ; [.24BA.0020.0002.0E97][.24D8.0020.001F.0EC0] # +0EC1 0E97 ; [.24BA.0020.0002.0E97][.24D9.0020.001F.0EC1] # +0EC2 0E97 ; [.24BA.0020.0002.0E97][.24DA.0020.001F.0EC2] # +0EC3 0E97 ; [.24BA.0020.0002.0E97][.24DB.0020.001F.0EC3] # +0EC4 0E97 ; [.24BA.0020.0002.0E97][.24DC.0020.001F.0EC4] # +0E99 ; [.24BB.0020.0002.0E99] # LAO LETTER NO +0EC0 0E99 ; [.24BB.0020.0002.0E99][.24D8.0020.001F.0EC0] # +0EC1 0E99 ; [.24BB.0020.0002.0E99][.24D9.0020.001F.0EC1] # +0EC2 0E99 ; [.24BB.0020.0002.0E99][.24DA.0020.001F.0EC2] # +0EC3 0E99 ; [.24BB.0020.0002.0E99][.24DB.0020.001F.0EC3] # +0EC4 0E99 ; [.24BB.0020.0002.0E99][.24DC.0020.001F.0EC4] # +0E9A ; [.24BC.0020.0002.0E9A] # LAO LETTER BO +0EC0 0E9A ; [.24BC.0020.0002.0E9A][.24D8.0020.001F.0EC0] # +0EC1 0E9A ; [.24BC.0020.0002.0E9A][.24D9.0020.001F.0EC1] # +0EC2 0E9A ; [.24BC.0020.0002.0E9A][.24DA.0020.001F.0EC2] # +0EC3 0E9A ; [.24BC.0020.0002.0E9A][.24DB.0020.001F.0EC3] # +0EC4 0E9A ; [.24BC.0020.0002.0E9A][.24DC.0020.001F.0EC4] # +0E9B ; [.24BD.0020.0002.0E9B] # LAO LETTER PO +0EC0 0E9B ; [.24BD.0020.0002.0E9B][.24D8.0020.001F.0EC0] # +0EC1 0E9B ; [.24BD.0020.0002.0E9B][.24D9.0020.001F.0EC1] # +0EC2 0E9B ; [.24BD.0020.0002.0E9B][.24DA.0020.001F.0EC2] # +0EC3 0E9B ; [.24BD.0020.0002.0E9B][.24DB.0020.001F.0EC3] # +0EC4 0E9B ; [.24BD.0020.0002.0E9B][.24DC.0020.001F.0EC4] # +0E9C ; [.24BE.0020.0002.0E9C] # LAO LETTER PHO SUNG +0EC0 0E9C ; [.24BE.0020.0002.0E9C][.24D8.0020.001F.0EC0] # +0EC1 0E9C ; [.24BE.0020.0002.0E9C][.24D9.0020.001F.0EC1] # +0EC2 0E9C ; [.24BE.0020.0002.0E9C][.24DA.0020.001F.0EC2] # +0EC3 0E9C ; [.24BE.0020.0002.0E9C][.24DB.0020.001F.0EC3] # +0EC4 0E9C ; [.24BE.0020.0002.0E9C][.24DC.0020.001F.0EC4] # +0E9D ; [.24BF.0020.0002.0E9D] # LAO LETTER FO TAM +0EC0 0E9D ; [.24BF.0020.0002.0E9D][.24D8.0020.001F.0EC0] # +0EC1 0E9D ; [.24BF.0020.0002.0E9D][.24D9.0020.001F.0EC1] # +0EC2 0E9D ; [.24BF.0020.0002.0E9D][.24DA.0020.001F.0EC2] # +0EC3 0E9D ; [.24BF.0020.0002.0E9D][.24DB.0020.001F.0EC3] # +0EC4 0E9D ; [.24BF.0020.0002.0E9D][.24DC.0020.001F.0EC4] # +0E9E ; [.24C0.0020.0002.0E9E] # LAO LETTER PHO TAM +0EC0 0E9E ; [.24C0.0020.0002.0E9E][.24D8.0020.001F.0EC0] # +0EC1 0E9E ; [.24C0.0020.0002.0E9E][.24D9.0020.001F.0EC1] # +0EC2 0E9E ; [.24C0.0020.0002.0E9E][.24DA.0020.001F.0EC2] # +0EC3 0E9E ; [.24C0.0020.0002.0E9E][.24DB.0020.001F.0EC3] # +0EC4 0E9E ; [.24C0.0020.0002.0E9E][.24DC.0020.001F.0EC4] # +0E9F ; [.24C1.0020.0002.0E9F] # LAO LETTER FO SUNG +0EC0 0E9F ; [.24C1.0020.0002.0E9F][.24D8.0020.001F.0EC0] # +0EC1 0E9F ; [.24C1.0020.0002.0E9F][.24D9.0020.001F.0EC1] # +0EC2 0E9F ; [.24C1.0020.0002.0E9F][.24DA.0020.001F.0EC2] # +0EC3 0E9F ; [.24C1.0020.0002.0E9F][.24DB.0020.001F.0EC3] # +0EC4 0E9F ; [.24C1.0020.0002.0E9F][.24DC.0020.001F.0EC4] # +0EA1 ; [.24C2.0020.0002.0EA1] # LAO LETTER MO +0EC0 0EA1 ; [.24C2.0020.0002.0EA1][.24D8.0020.001F.0EC0] # +0EC1 0EA1 ; [.24C2.0020.0002.0EA1][.24D9.0020.001F.0EC1] # +0EC2 0EA1 ; [.24C2.0020.0002.0EA1][.24DA.0020.001F.0EC2] # +0EC3 0EA1 ; [.24C2.0020.0002.0EA1][.24DB.0020.001F.0EC3] # +0EC4 0EA1 ; [.24C2.0020.0002.0EA1][.24DC.0020.001F.0EC4] # +0EA2 ; [.24C3.0020.0002.0EA2] # LAO LETTER YO +0EC0 0EA2 ; [.24C3.0020.0002.0EA2][.24D8.0020.001F.0EC0] # +0EC1 0EA2 ; [.24C3.0020.0002.0EA2][.24D9.0020.001F.0EC1] # +0EC2 0EA2 ; [.24C3.0020.0002.0EA2][.24DA.0020.001F.0EC2] # +0EC3 0EA2 ; [.24C3.0020.0002.0EA2][.24DB.0020.001F.0EC3] # +0EC4 0EA2 ; [.24C3.0020.0002.0EA2][.24DC.0020.001F.0EC4] # +0EA3 ; [.24C4.0020.0002.0EA3] # LAO LETTER LO LING +0EC0 0EA3 ; [.24C4.0020.0002.0EA3][.24D8.0020.001F.0EC0] # +0EC1 0EA3 ; [.24C4.0020.0002.0EA3][.24D9.0020.001F.0EC1] # +0EC2 0EA3 ; [.24C4.0020.0002.0EA3][.24DA.0020.001F.0EC2] # +0EC3 0EA3 ; [.24C4.0020.0002.0EA3][.24DB.0020.001F.0EC3] # +0EC4 0EA3 ; [.24C4.0020.0002.0EA3][.24DC.0020.001F.0EC4] # +0EA5 ; [.24C5.0020.0002.0EA5] # LAO LETTER LO LOOT +0EC0 0EA5 ; [.24C5.0020.0002.0EA5][.24D8.0020.001F.0EC0] # +0EC1 0EA5 ; [.24C5.0020.0002.0EA5][.24D9.0020.001F.0EC1] # +0EC2 0EA5 ; [.24C5.0020.0002.0EA5][.24DA.0020.001F.0EC2] # +0EC3 0EA5 ; [.24C5.0020.0002.0EA5][.24DB.0020.001F.0EC3] # +0EC4 0EA5 ; [.24C5.0020.0002.0EA5][.24DC.0020.001F.0EC4] # +0EA7 ; [.24C6.0020.0002.0EA7] # LAO LETTER WO +0EC0 0EA7 ; [.24C6.0020.0002.0EA7][.24D8.0020.001F.0EC0] # +0EC1 0EA7 ; [.24C6.0020.0002.0EA7][.24D9.0020.001F.0EC1] # +0EC2 0EA7 ; [.24C6.0020.0002.0EA7][.24DA.0020.001F.0EC2] # +0EC3 0EA7 ; [.24C6.0020.0002.0EA7][.24DB.0020.001F.0EC3] # +0EC4 0EA7 ; [.24C6.0020.0002.0EA7][.24DC.0020.001F.0EC4] # +0EAB ; [.24C7.0020.0002.0EAB] # LAO LETTER HO SUNG +0EDC ; [.24C7.0020.0004.0EDC][.24BB.0020.0004.0EDC] # LAO HO NO +0EC0 0EDC ; [.24C7.0020.0004.0EDC][.24BB.0020.0004.0EDC][.24D8.0020.001F.0EC0] # +0EC1 0EDC ; [.24C7.0020.0004.0EDC][.24BB.0020.0004.0EDC][.24D9.0020.001F.0EC1] # +0EC2 0EDC ; [.24C7.0020.0004.0EDC][.24BB.0020.0004.0EDC][.24DA.0020.001F.0EC2] # +0EC3 0EDC ; [.24C7.0020.0004.0EDC][.24BB.0020.0004.0EDC][.24DB.0020.001F.0EC3] # +0EC4 0EDC ; [.24C7.0020.0004.0EDC][.24BB.0020.0004.0EDC][.24DC.0020.001F.0EC4] # +0EDD ; [.24C7.0020.0004.0EDD][.24C2.0020.0004.0EDD] # LAO HO MO +0EC0 0EDD ; [.24C7.0020.0004.0EDD][.24C2.0020.0004.0EDD][.24D8.0020.001F.0EC0] # +0EC1 0EDD ; [.24C7.0020.0004.0EDD][.24C2.0020.0004.0EDD][.24D9.0020.001F.0EC1] # +0EC2 0EDD ; [.24C7.0020.0004.0EDD][.24C2.0020.0004.0EDD][.24DA.0020.001F.0EC2] # +0EC3 0EDD ; [.24C7.0020.0004.0EDD][.24C2.0020.0004.0EDD][.24DB.0020.001F.0EC3] # +0EC4 0EDD ; [.24C7.0020.0004.0EDD][.24C2.0020.0004.0EDD][.24DC.0020.001F.0EC4] # +0EC0 0EAB ; [.24C7.0020.0002.0EAB][.24D8.0020.001F.0EC0] # +0EC1 0EAB ; [.24C7.0020.0002.0EAB][.24D9.0020.001F.0EC1] # +0EC2 0EAB ; [.24C7.0020.0002.0EAB][.24DA.0020.001F.0EC2] # +0EC3 0EAB ; [.24C7.0020.0002.0EAB][.24DB.0020.001F.0EC3] # +0EC4 0EAB ; [.24C7.0020.0002.0EAB][.24DC.0020.001F.0EC4] # +0EAD ; [.24C8.0020.0002.0EAD] # LAO LETTER O +0EC0 0EAD ; [.24C8.0020.0002.0EAD][.24D8.0020.001F.0EC0] # +0EC1 0EAD ; [.24C8.0020.0002.0EAD][.24D9.0020.001F.0EC1] # +0EC2 0EAD ; [.24C8.0020.0002.0EAD][.24DA.0020.001F.0EC2] # +0EC3 0EAD ; [.24C8.0020.0002.0EAD][.24DB.0020.001F.0EC3] # +0EC4 0EAD ; [.24C8.0020.0002.0EAD][.24DC.0020.001F.0EC4] # +0EAE ; [.24C9.0020.0002.0EAE] # LAO LETTER HO TAM +0EC0 0EAE ; [.24C9.0020.0002.0EAE][.24D8.0020.001F.0EC0] # +0EC1 0EAE ; [.24C9.0020.0002.0EAE][.24D9.0020.001F.0EC1] # +0EC2 0EAE ; [.24C9.0020.0002.0EAE][.24DA.0020.001F.0EC2] # +0EC3 0EAE ; [.24C9.0020.0002.0EAE][.24DB.0020.001F.0EC3] # +0EC4 0EAE ; [.24C9.0020.0002.0EAE][.24DC.0020.001F.0EC4] # +0EAF ; [.24CA.0020.0002.0EAF] # LAO ELLIPSIS +0EB0 ; [.24CB.0020.0002.0EB0] # LAO VOWEL SIGN A +0EB1 ; [.24CC.0020.0002.0EB1] # LAO VOWEL SIGN MAI KAN +0EB2 ; [.24CD.0020.0002.0EB2] # LAO VOWEL SIGN AA +0EB3 ; [.24CE.0020.0002.0EB3] # LAO VOWEL SIGN AM +0ECD 0EB2 ; [.24CE.0020.0002.0EB3] # LAO VOWEL SIGN AM +0EB4 ; [.24CF.0020.0002.0EB4] # LAO VOWEL SIGN I +0EB5 ; [.24D0.0020.0002.0EB5] # LAO VOWEL SIGN II +0EB6 ; [.24D1.0020.0002.0EB6] # LAO VOWEL SIGN Y +0EB7 ; [.24D2.0020.0002.0EB7] # LAO VOWEL SIGN YY +0EB8 ; [.24D3.0020.0002.0EB8] # LAO VOWEL SIGN U +0EB9 ; [.24D4.0020.0002.0EB9] # LAO VOWEL SIGN UU +0EBB ; [.24D5.0020.0002.0EBB] # LAO VOWEL SIGN MAI KON +0EBC ; [.24D6.0020.0002.0EBC] # LAO SEMIVOWEL SIGN LO +0EBD ; [.24D7.0020.0002.0EBD] # LAO SEMIVOWEL SIGN NYO +0EC0 ; [.24D8.0020.0002.0EC0] # LAO VOWEL SIGN E +0EC1 ; [.24D9.0020.0002.0EC1] # LAO VOWEL SIGN EI +0EC2 ; [.24DA.0020.0002.0EC2] # LAO VOWEL SIGN O +0EC3 ; [.24DB.0020.0002.0EC3] # LAO VOWEL SIGN AY +0EC4 ; [.24DC.0020.0002.0EC4] # LAO VOWEL SIGN AI +AA80 ; [.24DD.0020.0002.AA80] # TAI VIET LETTER LOW KO +AAB5 AA80 ; [.24DD.0020.0002.AA80][.2512.0020.001F.AAB5] # +AAB6 AA80 ; [.24DD.0020.0002.AA80][.2513.0020.001F.AAB6] # +AAB9 AA80 ; [.24DD.0020.0002.AA80][.2516.0020.001F.AAB9] # +AABB AA80 ; [.24DD.0020.0002.AA80][.2518.0020.001F.AABB] # +AABC AA80 ; [.24DD.0020.0002.AA80][.2519.0020.001F.AABC] # +AA81 ; [.24DE.0020.0002.AA81] # TAI VIET LETTER HIGH KO +AAB5 AA81 ; [.24DE.0020.0002.AA81][.2512.0020.001F.AAB5] # +AAB6 AA81 ; [.24DE.0020.0002.AA81][.2513.0020.001F.AAB6] # +AAB9 AA81 ; [.24DE.0020.0002.AA81][.2516.0020.001F.AAB9] # +AABB AA81 ; [.24DE.0020.0002.AA81][.2518.0020.001F.AABB] # +AABC AA81 ; [.24DE.0020.0002.AA81][.2519.0020.001F.AABC] # +AA82 ; [.24DF.0020.0002.AA82] # TAI VIET LETTER LOW KHO +AAB5 AA82 ; [.24DF.0020.0002.AA82][.2512.0020.001F.AAB5] # +AAB6 AA82 ; [.24DF.0020.0002.AA82][.2513.0020.001F.AAB6] # +AAB9 AA82 ; [.24DF.0020.0002.AA82][.2516.0020.001F.AAB9] # +AABB AA82 ; [.24DF.0020.0002.AA82][.2518.0020.001F.AABB] # +AABC AA82 ; [.24DF.0020.0002.AA82][.2519.0020.001F.AABC] # +AA83 ; [.24E0.0020.0002.AA83] # TAI VIET LETTER HIGH KHO +AAB5 AA83 ; [.24E0.0020.0002.AA83][.2512.0020.001F.AAB5] # +AAB6 AA83 ; [.24E0.0020.0002.AA83][.2513.0020.001F.AAB6] # +AAB9 AA83 ; [.24E0.0020.0002.AA83][.2516.0020.001F.AAB9] # +AABB AA83 ; [.24E0.0020.0002.AA83][.2518.0020.001F.AABB] # +AABC AA83 ; [.24E0.0020.0002.AA83][.2519.0020.001F.AABC] # +AA84 ; [.24E1.0020.0002.AA84] # TAI VIET LETTER LOW KHHO +AAB5 AA84 ; [.24E1.0020.0002.AA84][.2512.0020.001F.AAB5] # +AAB6 AA84 ; [.24E1.0020.0002.AA84][.2513.0020.001F.AAB6] # +AAB9 AA84 ; [.24E1.0020.0002.AA84][.2516.0020.001F.AAB9] # +AABB AA84 ; [.24E1.0020.0002.AA84][.2518.0020.001F.AABB] # +AABC AA84 ; [.24E1.0020.0002.AA84][.2519.0020.001F.AABC] # +AA85 ; [.24E2.0020.0002.AA85] # TAI VIET LETTER HIGH KHHO +AAB5 AA85 ; [.24E2.0020.0002.AA85][.2512.0020.001F.AAB5] # +AAB6 AA85 ; [.24E2.0020.0002.AA85][.2513.0020.001F.AAB6] # +AAB9 AA85 ; [.24E2.0020.0002.AA85][.2516.0020.001F.AAB9] # +AABB AA85 ; [.24E2.0020.0002.AA85][.2518.0020.001F.AABB] # +AABC AA85 ; [.24E2.0020.0002.AA85][.2519.0020.001F.AABC] # +AA86 ; [.24E3.0020.0002.AA86] # TAI VIET LETTER LOW GO +AAB5 AA86 ; [.24E3.0020.0002.AA86][.2512.0020.001F.AAB5] # +AAB6 AA86 ; [.24E3.0020.0002.AA86][.2513.0020.001F.AAB6] # +AAB9 AA86 ; [.24E3.0020.0002.AA86][.2516.0020.001F.AAB9] # +AABB AA86 ; [.24E3.0020.0002.AA86][.2518.0020.001F.AABB] # +AABC AA86 ; [.24E3.0020.0002.AA86][.2519.0020.001F.AABC] # +AA87 ; [.24E4.0020.0002.AA87] # TAI VIET LETTER HIGH GO +AAB5 AA87 ; [.24E4.0020.0002.AA87][.2512.0020.001F.AAB5] # +AAB6 AA87 ; [.24E4.0020.0002.AA87][.2513.0020.001F.AAB6] # +AAB9 AA87 ; [.24E4.0020.0002.AA87][.2516.0020.001F.AAB9] # +AABB AA87 ; [.24E4.0020.0002.AA87][.2518.0020.001F.AABB] # +AABC AA87 ; [.24E4.0020.0002.AA87][.2519.0020.001F.AABC] # +AA88 ; [.24E5.0020.0002.AA88] # TAI VIET LETTER LOW NGO +AAB5 AA88 ; [.24E5.0020.0002.AA88][.2512.0020.001F.AAB5] # +AAB6 AA88 ; [.24E5.0020.0002.AA88][.2513.0020.001F.AAB6] # +AAB9 AA88 ; [.24E5.0020.0002.AA88][.2516.0020.001F.AAB9] # +AABB AA88 ; [.24E5.0020.0002.AA88][.2518.0020.001F.AABB] # +AABC AA88 ; [.24E5.0020.0002.AA88][.2519.0020.001F.AABC] # +AA89 ; [.24E6.0020.0002.AA89] # TAI VIET LETTER HIGH NGO +AAB5 AA89 ; [.24E6.0020.0002.AA89][.2512.0020.001F.AAB5] # +AAB6 AA89 ; [.24E6.0020.0002.AA89][.2513.0020.001F.AAB6] # +AAB9 AA89 ; [.24E6.0020.0002.AA89][.2516.0020.001F.AAB9] # +AABB AA89 ; [.24E6.0020.0002.AA89][.2518.0020.001F.AABB] # +AABC AA89 ; [.24E6.0020.0002.AA89][.2519.0020.001F.AABC] # +AA8A ; [.24E7.0020.0002.AA8A] # TAI VIET LETTER LOW CO +AAB5 AA8A ; [.24E7.0020.0002.AA8A][.2512.0020.001F.AAB5] # +AAB6 AA8A ; [.24E7.0020.0002.AA8A][.2513.0020.001F.AAB6] # +AAB9 AA8A ; [.24E7.0020.0002.AA8A][.2516.0020.001F.AAB9] # +AABB AA8A ; [.24E7.0020.0002.AA8A][.2518.0020.001F.AABB] # +AABC AA8A ; [.24E7.0020.0002.AA8A][.2519.0020.001F.AABC] # +AA8B ; [.24E8.0020.0002.AA8B] # TAI VIET LETTER HIGH CO +AAB5 AA8B ; [.24E8.0020.0002.AA8B][.2512.0020.001F.AAB5] # +AAB6 AA8B ; [.24E8.0020.0002.AA8B][.2513.0020.001F.AAB6] # +AAB9 AA8B ; [.24E8.0020.0002.AA8B][.2516.0020.001F.AAB9] # +AABB AA8B ; [.24E8.0020.0002.AA8B][.2518.0020.001F.AABB] # +AABC AA8B ; [.24E8.0020.0002.AA8B][.2519.0020.001F.AABC] # +AA8C ; [.24E9.0020.0002.AA8C] # TAI VIET LETTER LOW CHO +AAB5 AA8C ; [.24E9.0020.0002.AA8C][.2512.0020.001F.AAB5] # +AAB6 AA8C ; [.24E9.0020.0002.AA8C][.2513.0020.001F.AAB6] # +AAB9 AA8C ; [.24E9.0020.0002.AA8C][.2516.0020.001F.AAB9] # +AABB AA8C ; [.24E9.0020.0002.AA8C][.2518.0020.001F.AABB] # +AABC AA8C ; [.24E9.0020.0002.AA8C][.2519.0020.001F.AABC] # +AA8D ; [.24EA.0020.0002.AA8D] # TAI VIET LETTER HIGH CHO +AAB5 AA8D ; [.24EA.0020.0002.AA8D][.2512.0020.001F.AAB5] # +AAB6 AA8D ; [.24EA.0020.0002.AA8D][.2513.0020.001F.AAB6] # +AAB9 AA8D ; [.24EA.0020.0002.AA8D][.2516.0020.001F.AAB9] # +AABB AA8D ; [.24EA.0020.0002.AA8D][.2518.0020.001F.AABB] # +AABC AA8D ; [.24EA.0020.0002.AA8D][.2519.0020.001F.AABC] # +AA8E ; [.24EB.0020.0002.AA8E] # TAI VIET LETTER LOW SO +AAB5 AA8E ; [.24EB.0020.0002.AA8E][.2512.0020.001F.AAB5] # +AAB6 AA8E ; [.24EB.0020.0002.AA8E][.2513.0020.001F.AAB6] # +AAB9 AA8E ; [.24EB.0020.0002.AA8E][.2516.0020.001F.AAB9] # +AABB AA8E ; [.24EB.0020.0002.AA8E][.2518.0020.001F.AABB] # +AABC AA8E ; [.24EB.0020.0002.AA8E][.2519.0020.001F.AABC] # +AA8F ; [.24EC.0020.0002.AA8F] # TAI VIET LETTER HIGH SO +AAB5 AA8F ; [.24EC.0020.0002.AA8F][.2512.0020.001F.AAB5] # +AAB6 AA8F ; [.24EC.0020.0002.AA8F][.2513.0020.001F.AAB6] # +AAB9 AA8F ; [.24EC.0020.0002.AA8F][.2516.0020.001F.AAB9] # +AABB AA8F ; [.24EC.0020.0002.AA8F][.2518.0020.001F.AABB] # +AABC AA8F ; [.24EC.0020.0002.AA8F][.2519.0020.001F.AABC] # +AA90 ; [.24ED.0020.0002.AA90] # TAI VIET LETTER LOW NYO +AAB5 AA90 ; [.24ED.0020.0002.AA90][.2512.0020.001F.AAB5] # +AAB6 AA90 ; [.24ED.0020.0002.AA90][.2513.0020.001F.AAB6] # +AAB9 AA90 ; [.24ED.0020.0002.AA90][.2516.0020.001F.AAB9] # +AABB AA90 ; [.24ED.0020.0002.AA90][.2518.0020.001F.AABB] # +AABC AA90 ; [.24ED.0020.0002.AA90][.2519.0020.001F.AABC] # +AA91 ; [.24EE.0020.0002.AA91] # TAI VIET LETTER HIGH NYO +AAB5 AA91 ; [.24EE.0020.0002.AA91][.2512.0020.001F.AAB5] # +AAB6 AA91 ; [.24EE.0020.0002.AA91][.2513.0020.001F.AAB6] # +AAB9 AA91 ; [.24EE.0020.0002.AA91][.2516.0020.001F.AAB9] # +AABB AA91 ; [.24EE.0020.0002.AA91][.2518.0020.001F.AABB] # +AABC AA91 ; [.24EE.0020.0002.AA91][.2519.0020.001F.AABC] # +AA92 ; [.24EF.0020.0002.AA92] # TAI VIET LETTER LOW DO +AAB5 AA92 ; [.24EF.0020.0002.AA92][.2512.0020.001F.AAB5] # +AAB6 AA92 ; [.24EF.0020.0002.AA92][.2513.0020.001F.AAB6] # +AAB9 AA92 ; [.24EF.0020.0002.AA92][.2516.0020.001F.AAB9] # +AABB AA92 ; [.24EF.0020.0002.AA92][.2518.0020.001F.AABB] # +AABC AA92 ; [.24EF.0020.0002.AA92][.2519.0020.001F.AABC] # +AA93 ; [.24F0.0020.0002.AA93] # TAI VIET LETTER HIGH DO +AAB5 AA93 ; [.24F0.0020.0002.AA93][.2512.0020.001F.AAB5] # +AAB6 AA93 ; [.24F0.0020.0002.AA93][.2513.0020.001F.AAB6] # +AAB9 AA93 ; [.24F0.0020.0002.AA93][.2516.0020.001F.AAB9] # +AABB AA93 ; [.24F0.0020.0002.AA93][.2518.0020.001F.AABB] # +AABC AA93 ; [.24F0.0020.0002.AA93][.2519.0020.001F.AABC] # +AA94 ; [.24F1.0020.0002.AA94] # TAI VIET LETTER LOW TO +AAB5 AA94 ; [.24F1.0020.0002.AA94][.2512.0020.001F.AAB5] # +AAB6 AA94 ; [.24F1.0020.0002.AA94][.2513.0020.001F.AAB6] # +AAB9 AA94 ; [.24F1.0020.0002.AA94][.2516.0020.001F.AAB9] # +AABB AA94 ; [.24F1.0020.0002.AA94][.2518.0020.001F.AABB] # +AABC AA94 ; [.24F1.0020.0002.AA94][.2519.0020.001F.AABC] # +AA95 ; [.24F2.0020.0002.AA95] # TAI VIET LETTER HIGH TO +AAB5 AA95 ; [.24F2.0020.0002.AA95][.2512.0020.001F.AAB5] # +AAB6 AA95 ; [.24F2.0020.0002.AA95][.2513.0020.001F.AAB6] # +AAB9 AA95 ; [.24F2.0020.0002.AA95][.2516.0020.001F.AAB9] # +AABB AA95 ; [.24F2.0020.0002.AA95][.2518.0020.001F.AABB] # +AABC AA95 ; [.24F2.0020.0002.AA95][.2519.0020.001F.AABC] # +AA96 ; [.24F3.0020.0002.AA96] # TAI VIET LETTER LOW THO +AAB5 AA96 ; [.24F3.0020.0002.AA96][.2512.0020.001F.AAB5] # +AAB6 AA96 ; [.24F3.0020.0002.AA96][.2513.0020.001F.AAB6] # +AAB9 AA96 ; [.24F3.0020.0002.AA96][.2516.0020.001F.AAB9] # +AABB AA96 ; [.24F3.0020.0002.AA96][.2518.0020.001F.AABB] # +AABC AA96 ; [.24F3.0020.0002.AA96][.2519.0020.001F.AABC] # +AA97 ; [.24F4.0020.0002.AA97] # TAI VIET LETTER HIGH THO +AAB5 AA97 ; [.24F4.0020.0002.AA97][.2512.0020.001F.AAB5] # +AAB6 AA97 ; [.24F4.0020.0002.AA97][.2513.0020.001F.AAB6] # +AAB9 AA97 ; [.24F4.0020.0002.AA97][.2516.0020.001F.AAB9] # +AABB AA97 ; [.24F4.0020.0002.AA97][.2518.0020.001F.AABB] # +AABC AA97 ; [.24F4.0020.0002.AA97][.2519.0020.001F.AABC] # +AA98 ; [.24F5.0020.0002.AA98] # TAI VIET LETTER LOW NO +AAB5 AA98 ; [.24F5.0020.0002.AA98][.2512.0020.001F.AAB5] # +AAB6 AA98 ; [.24F5.0020.0002.AA98][.2513.0020.001F.AAB6] # +AAB9 AA98 ; [.24F5.0020.0002.AA98][.2516.0020.001F.AAB9] # +AABB AA98 ; [.24F5.0020.0002.AA98][.2518.0020.001F.AABB] # +AABC AA98 ; [.24F5.0020.0002.AA98][.2519.0020.001F.AABC] # +AA99 ; [.24F6.0020.0002.AA99] # TAI VIET LETTER HIGH NO +AAB5 AA99 ; [.24F6.0020.0002.AA99][.2512.0020.001F.AAB5] # +AAB6 AA99 ; [.24F6.0020.0002.AA99][.2513.0020.001F.AAB6] # +AAB9 AA99 ; [.24F6.0020.0002.AA99][.2516.0020.001F.AAB9] # +AABB AA99 ; [.24F6.0020.0002.AA99][.2518.0020.001F.AABB] # +AABC AA99 ; [.24F6.0020.0002.AA99][.2519.0020.001F.AABC] # +AA9A ; [.24F7.0020.0002.AA9A] # TAI VIET LETTER LOW BO +AAB5 AA9A ; [.24F7.0020.0002.AA9A][.2512.0020.001F.AAB5] # +AAB6 AA9A ; [.24F7.0020.0002.AA9A][.2513.0020.001F.AAB6] # +AAB9 AA9A ; [.24F7.0020.0002.AA9A][.2516.0020.001F.AAB9] # +AABB AA9A ; [.24F7.0020.0002.AA9A][.2518.0020.001F.AABB] # +AABC AA9A ; [.24F7.0020.0002.AA9A][.2519.0020.001F.AABC] # +AA9B ; [.24F8.0020.0002.AA9B] # TAI VIET LETTER HIGH BO +AAB5 AA9B ; [.24F8.0020.0002.AA9B][.2512.0020.001F.AAB5] # +AAB6 AA9B ; [.24F8.0020.0002.AA9B][.2513.0020.001F.AAB6] # +AAB9 AA9B ; [.24F8.0020.0002.AA9B][.2516.0020.001F.AAB9] # +AABB AA9B ; [.24F8.0020.0002.AA9B][.2518.0020.001F.AABB] # +AABC AA9B ; [.24F8.0020.0002.AA9B][.2519.0020.001F.AABC] # +AA9C ; [.24F9.0020.0002.AA9C] # TAI VIET LETTER LOW PO +AAB5 AA9C ; [.24F9.0020.0002.AA9C][.2512.0020.001F.AAB5] # +AAB6 AA9C ; [.24F9.0020.0002.AA9C][.2513.0020.001F.AAB6] # +AAB9 AA9C ; [.24F9.0020.0002.AA9C][.2516.0020.001F.AAB9] # +AABB AA9C ; [.24F9.0020.0002.AA9C][.2518.0020.001F.AABB] # +AABC AA9C ; [.24F9.0020.0002.AA9C][.2519.0020.001F.AABC] # +AA9D ; [.24FA.0020.0002.AA9D] # TAI VIET LETTER HIGH PO +AAB5 AA9D ; [.24FA.0020.0002.AA9D][.2512.0020.001F.AAB5] # +AAB6 AA9D ; [.24FA.0020.0002.AA9D][.2513.0020.001F.AAB6] # +AAB9 AA9D ; [.24FA.0020.0002.AA9D][.2516.0020.001F.AAB9] # +AABB AA9D ; [.24FA.0020.0002.AA9D][.2518.0020.001F.AABB] # +AABC AA9D ; [.24FA.0020.0002.AA9D][.2519.0020.001F.AABC] # +AA9E ; [.24FB.0020.0002.AA9E] # TAI VIET LETTER LOW PHO +AAB5 AA9E ; [.24FB.0020.0002.AA9E][.2512.0020.001F.AAB5] # +AAB6 AA9E ; [.24FB.0020.0002.AA9E][.2513.0020.001F.AAB6] # +AAB9 AA9E ; [.24FB.0020.0002.AA9E][.2516.0020.001F.AAB9] # +AABB AA9E ; [.24FB.0020.0002.AA9E][.2518.0020.001F.AABB] # +AABC AA9E ; [.24FB.0020.0002.AA9E][.2519.0020.001F.AABC] # +AA9F ; [.24FC.0020.0002.AA9F] # TAI VIET LETTER HIGH PHO +AAB5 AA9F ; [.24FC.0020.0002.AA9F][.2512.0020.001F.AAB5] # +AAB6 AA9F ; [.24FC.0020.0002.AA9F][.2513.0020.001F.AAB6] # +AAB9 AA9F ; [.24FC.0020.0002.AA9F][.2516.0020.001F.AAB9] # +AABB AA9F ; [.24FC.0020.0002.AA9F][.2518.0020.001F.AABB] # +AABC AA9F ; [.24FC.0020.0002.AA9F][.2519.0020.001F.AABC] # +AAA0 ; [.24FD.0020.0002.AAA0] # TAI VIET LETTER LOW FO +AAB5 AAA0 ; [.24FD.0020.0002.AAA0][.2512.0020.001F.AAB5] # +AAB6 AAA0 ; [.24FD.0020.0002.AAA0][.2513.0020.001F.AAB6] # +AAB9 AAA0 ; [.24FD.0020.0002.AAA0][.2516.0020.001F.AAB9] # +AABB AAA0 ; [.24FD.0020.0002.AAA0][.2518.0020.001F.AABB] # +AABC AAA0 ; [.24FD.0020.0002.AAA0][.2519.0020.001F.AABC] # +AAA1 ; [.24FE.0020.0002.AAA1] # TAI VIET LETTER HIGH FO +AAB5 AAA1 ; [.24FE.0020.0002.AAA1][.2512.0020.001F.AAB5] # +AAB6 AAA1 ; [.24FE.0020.0002.AAA1][.2513.0020.001F.AAB6] # +AAB9 AAA1 ; [.24FE.0020.0002.AAA1][.2516.0020.001F.AAB9] # +AABB AAA1 ; [.24FE.0020.0002.AAA1][.2518.0020.001F.AABB] # +AABC AAA1 ; [.24FE.0020.0002.AAA1][.2519.0020.001F.AABC] # +AAA2 ; [.24FF.0020.0002.AAA2] # TAI VIET LETTER LOW MO +AAB5 AAA2 ; [.24FF.0020.0002.AAA2][.2512.0020.001F.AAB5] # +AAB6 AAA2 ; [.24FF.0020.0002.AAA2][.2513.0020.001F.AAB6] # +AAB9 AAA2 ; [.24FF.0020.0002.AAA2][.2516.0020.001F.AAB9] # +AABB AAA2 ; [.24FF.0020.0002.AAA2][.2518.0020.001F.AABB] # +AABC AAA2 ; [.24FF.0020.0002.AAA2][.2519.0020.001F.AABC] # +AAA3 ; [.2500.0020.0002.AAA3] # TAI VIET LETTER HIGH MO +AAB5 AAA3 ; [.2500.0020.0002.AAA3][.2512.0020.001F.AAB5] # +AAB6 AAA3 ; [.2500.0020.0002.AAA3][.2513.0020.001F.AAB6] # +AAB9 AAA3 ; [.2500.0020.0002.AAA3][.2516.0020.001F.AAB9] # +AABB AAA3 ; [.2500.0020.0002.AAA3][.2518.0020.001F.AABB] # +AABC AAA3 ; [.2500.0020.0002.AAA3][.2519.0020.001F.AABC] # +AAA4 ; [.2501.0020.0002.AAA4] # TAI VIET LETTER LOW YO +AAB5 AAA4 ; [.2501.0020.0002.AAA4][.2512.0020.001F.AAB5] # +AAB6 AAA4 ; [.2501.0020.0002.AAA4][.2513.0020.001F.AAB6] # +AAB9 AAA4 ; [.2501.0020.0002.AAA4][.2516.0020.001F.AAB9] # +AABB AAA4 ; [.2501.0020.0002.AAA4][.2518.0020.001F.AABB] # +AABC AAA4 ; [.2501.0020.0002.AAA4][.2519.0020.001F.AABC] # +AAA5 ; [.2502.0020.0002.AAA5] # TAI VIET LETTER HIGH YO +AAB5 AAA5 ; [.2502.0020.0002.AAA5][.2512.0020.001F.AAB5] # +AAB6 AAA5 ; [.2502.0020.0002.AAA5][.2513.0020.001F.AAB6] # +AAB9 AAA5 ; [.2502.0020.0002.AAA5][.2516.0020.001F.AAB9] # +AABB AAA5 ; [.2502.0020.0002.AAA5][.2518.0020.001F.AABB] # +AABC AAA5 ; [.2502.0020.0002.AAA5][.2519.0020.001F.AABC] # +AAA6 ; [.2503.0020.0002.AAA6] # TAI VIET LETTER LOW RO +AAB5 AAA6 ; [.2503.0020.0002.AAA6][.2512.0020.001F.AAB5] # +AAB6 AAA6 ; [.2503.0020.0002.AAA6][.2513.0020.001F.AAB6] # +AAB9 AAA6 ; [.2503.0020.0002.AAA6][.2516.0020.001F.AAB9] # +AABB AAA6 ; [.2503.0020.0002.AAA6][.2518.0020.001F.AABB] # +AABC AAA6 ; [.2503.0020.0002.AAA6][.2519.0020.001F.AABC] # +AAA7 ; [.2504.0020.0002.AAA7] # TAI VIET LETTER HIGH RO +AAB5 AAA7 ; [.2504.0020.0002.AAA7][.2512.0020.001F.AAB5] # +AAB6 AAA7 ; [.2504.0020.0002.AAA7][.2513.0020.001F.AAB6] # +AAB9 AAA7 ; [.2504.0020.0002.AAA7][.2516.0020.001F.AAB9] # +AABB AAA7 ; [.2504.0020.0002.AAA7][.2518.0020.001F.AABB] # +AABC AAA7 ; [.2504.0020.0002.AAA7][.2519.0020.001F.AABC] # +AAA8 ; [.2505.0020.0002.AAA8] # TAI VIET LETTER LOW LO +AAB5 AAA8 ; [.2505.0020.0002.AAA8][.2512.0020.001F.AAB5] # +AAB6 AAA8 ; [.2505.0020.0002.AAA8][.2513.0020.001F.AAB6] # +AAB9 AAA8 ; [.2505.0020.0002.AAA8][.2516.0020.001F.AAB9] # +AABB AAA8 ; [.2505.0020.0002.AAA8][.2518.0020.001F.AABB] # +AABC AAA8 ; [.2505.0020.0002.AAA8][.2519.0020.001F.AABC] # +AAA9 ; [.2506.0020.0002.AAA9] # TAI VIET LETTER HIGH LO +AAB5 AAA9 ; [.2506.0020.0002.AAA9][.2512.0020.001F.AAB5] # +AAB6 AAA9 ; [.2506.0020.0002.AAA9][.2513.0020.001F.AAB6] # +AAB9 AAA9 ; [.2506.0020.0002.AAA9][.2516.0020.001F.AAB9] # +AABB AAA9 ; [.2506.0020.0002.AAA9][.2518.0020.001F.AABB] # +AABC AAA9 ; [.2506.0020.0002.AAA9][.2519.0020.001F.AABC] # +AAAA ; [.2507.0020.0002.AAAA] # TAI VIET LETTER LOW VO +AAB5 AAAA ; [.2507.0020.0002.AAAA][.2512.0020.001F.AAB5] # +AAB6 AAAA ; [.2507.0020.0002.AAAA][.2513.0020.001F.AAB6] # +AAB9 AAAA ; [.2507.0020.0002.AAAA][.2516.0020.001F.AAB9] # +AABB AAAA ; [.2507.0020.0002.AAAA][.2518.0020.001F.AABB] # +AABC AAAA ; [.2507.0020.0002.AAAA][.2519.0020.001F.AABC] # +AAAB ; [.2508.0020.0002.AAAB] # TAI VIET LETTER HIGH VO +AAB5 AAAB ; [.2508.0020.0002.AAAB][.2512.0020.001F.AAB5] # +AAB6 AAAB ; [.2508.0020.0002.AAAB][.2513.0020.001F.AAB6] # +AAB9 AAAB ; [.2508.0020.0002.AAAB][.2516.0020.001F.AAB9] # +AABB AAAB ; [.2508.0020.0002.AAAB][.2518.0020.001F.AABB] # +AABC AAAB ; [.2508.0020.0002.AAAB][.2519.0020.001F.AABC] # +AAAC ; [.2509.0020.0002.AAAC] # TAI VIET LETTER LOW HO +AAB5 AAAC ; [.2509.0020.0002.AAAC][.2512.0020.001F.AAB5] # +AAB6 AAAC ; [.2509.0020.0002.AAAC][.2513.0020.001F.AAB6] # +AAB9 AAAC ; [.2509.0020.0002.AAAC][.2516.0020.001F.AAB9] # +AABB AAAC ; [.2509.0020.0002.AAAC][.2518.0020.001F.AABB] # +AABC AAAC ; [.2509.0020.0002.AAAC][.2519.0020.001F.AABC] # +AAAD ; [.250A.0020.0002.AAAD] # TAI VIET LETTER HIGH HO +AAB5 AAAD ; [.250A.0020.0002.AAAD][.2512.0020.001F.AAB5] # +AAB6 AAAD ; [.250A.0020.0002.AAAD][.2513.0020.001F.AAB6] # +AAB9 AAAD ; [.250A.0020.0002.AAAD][.2516.0020.001F.AAB9] # +AABB AAAD ; [.250A.0020.0002.AAAD][.2518.0020.001F.AABB] # +AABC AAAD ; [.250A.0020.0002.AAAD][.2519.0020.001F.AABC] # +AAAE ; [.250B.0020.0002.AAAE] # TAI VIET LETTER LOW O +AAB5 AAAE ; [.250B.0020.0002.AAAE][.2512.0020.001F.AAB5] # +AAB6 AAAE ; [.250B.0020.0002.AAAE][.2513.0020.001F.AAB6] # +AAB9 AAAE ; [.250B.0020.0002.AAAE][.2516.0020.001F.AAB9] # +AABB AAAE ; [.250B.0020.0002.AAAE][.2518.0020.001F.AABB] # +AABC AAAE ; [.250B.0020.0002.AAAE][.2519.0020.001F.AABC] # +AAAF ; [.250C.0020.0002.AAAF] # TAI VIET LETTER HIGH O +AAB5 AAAF ; [.250C.0020.0002.AAAF][.2512.0020.001F.AAB5] # +AAB6 AAAF ; [.250C.0020.0002.AAAF][.2513.0020.001F.AAB6] # +AAB9 AAAF ; [.250C.0020.0002.AAAF][.2516.0020.001F.AAB9] # +AABB AAAF ; [.250C.0020.0002.AAAF][.2518.0020.001F.AABB] # +AABC AAAF ; [.250C.0020.0002.AAAF][.2519.0020.001F.AABC] # +AAB0 ; [.250D.0020.0002.AAB0] # TAI VIET MAI KANG +AAB1 ; [.250E.0020.0002.AAB1] # TAI VIET VOWEL AA +AAB2 ; [.250F.0020.0002.AAB2] # TAI VIET VOWEL I +AAB3 ; [.2510.0020.0002.AAB3] # TAI VIET VOWEL UE +AAB4 ; [.2511.0020.0002.AAB4] # TAI VIET VOWEL U +AAB5 ; [.2512.0020.0002.AAB5] # TAI VIET VOWEL E +AAB6 ; [.2513.0020.0002.AAB6] # TAI VIET VOWEL O +AAB7 ; [.2514.0020.0002.AAB7] # TAI VIET MAY KHIT +AAB8 ; [.2515.0020.0002.AAB8] # TAI VIET VOWEL IA +AAB9 ; [.2516.0020.0002.AAB9] # TAI VIET VOWEL UEA +AABA ; [.2517.0020.0002.AABA] # TAI VIET VOWEL UA +AABB ; [.2518.0020.0002.AABB] # TAI VIET VOWEL AUE +AABC ; [.2519.0020.0002.AABC] # TAI VIET VOWEL AY +AABD ; [.251A.0020.0002.AABD] # TAI VIET VOWEL AN +AABE ; [.251B.0020.0002.AABE] # TAI VIET VOWEL AM +AAC0 ; [.251C.0020.0002.AAC0] # TAI VIET TONE MAI NUENG +AAC2 ; [.251D.0020.0002.AAC2] # TAI VIET TONE MAI SONG +AADB ; [.251E.0020.0002.AADB] # TAI VIET SYMBOL KON +AADC ; [.251F.0020.0002.AADC] # TAI VIET SYMBOL NUENG +0F40 ; [.2520.0020.0002.0F40] # TIBETAN LETTER KA +0F69 ; [.2520.0020.0002.0F40][.2561.0020.0002.0FB5] # TIBETAN LETTER KSSA +0F90 ; [.2521.0020.0002.0F90] # TIBETAN SUBJOINED LETTER KA +0FB9 ; [.2521.0020.0002.0F90][.2561.0020.0002.0FB5] # TIBETAN SUBJOINED LETTER KSSA +0F6B ; [.2522.0020.0002.0F6B] # TIBETAN LETTER KKA +0F41 ; [.2523.0020.0002.0F41] # TIBETAN LETTER KHA +0F91 ; [.2524.0020.0002.0F91] # TIBETAN SUBJOINED LETTER KHA +0F42 ; [.2525.0020.0002.0F42] # TIBETAN LETTER GA +0F43 ; [.2525.0020.0002.0F42][.2565.0020.0002.0FB7] # TIBETAN LETTER GHA +0F92 ; [.2526.0020.0002.0F92] # TIBETAN SUBJOINED LETTER GA +0F93 ; [.2526.0020.0002.0F92][.2565.0020.0002.0FB7] # TIBETAN SUBJOINED LETTER GHA +0F44 ; [.2527.0020.0002.0F44] # TIBETAN LETTER NGA +0F94 ; [.2528.0020.0002.0F94] # TIBETAN SUBJOINED LETTER NGA +0F45 ; [.2529.0020.0002.0F45] # TIBETAN LETTER CA +0F95 ; [.252A.0020.0002.0F95] # TIBETAN SUBJOINED LETTER CA +0F46 ; [.252B.0020.0002.0F46] # TIBETAN LETTER CHA +0F96 ; [.252C.0020.0002.0F96] # TIBETAN SUBJOINED LETTER CHA +0F47 ; [.252D.0020.0002.0F47] # TIBETAN LETTER JA +0F97 ; [.252E.0020.0002.0F97] # TIBETAN SUBJOINED LETTER JA +0F49 ; [.252F.0020.0002.0F49] # TIBETAN LETTER NYA +0F99 ; [.2530.0020.0002.0F99] # TIBETAN SUBJOINED LETTER NYA +0F4A ; [.2531.0020.0002.0F4A] # TIBETAN LETTER TTA +0F9A ; [.2532.0020.0002.0F9A] # TIBETAN SUBJOINED LETTER TTA +0F4B ; [.2533.0020.0002.0F4B] # TIBETAN LETTER TTHA +0F9B ; [.2534.0020.0002.0F9B] # TIBETAN SUBJOINED LETTER TTHA +0F4C ; [.2535.0020.0002.0F4C] # TIBETAN LETTER DDA +0F4D ; [.2535.0020.0002.0F4C][.2565.0020.0002.0FB7] # TIBETAN LETTER DDHA +0F9C ; [.2536.0020.0002.0F9C] # TIBETAN SUBJOINED LETTER DDA +0F9D ; [.2536.0020.0002.0F9C][.2565.0020.0002.0FB7] # TIBETAN SUBJOINED LETTER DDHA +0F4E ; [.2537.0020.0002.0F4E] # TIBETAN LETTER NNA +0F9E ; [.2538.0020.0002.0F9E] # TIBETAN SUBJOINED LETTER NNA +0F4F ; [.2539.0020.0002.0F4F] # TIBETAN LETTER TA +0F9F ; [.253A.0020.0002.0F9F] # TIBETAN SUBJOINED LETTER TA +0F50 ; [.253B.0020.0002.0F50] # TIBETAN LETTER THA +0FA0 ; [.253C.0020.0002.0FA0] # TIBETAN SUBJOINED LETTER THA +0F51 ; [.253D.0020.0002.0F51] # TIBETAN LETTER DA +0F52 ; [.253D.0020.0002.0F51][.2565.0020.0002.0FB7] # TIBETAN LETTER DHA +0FA1 ; [.253E.0020.0002.0FA1] # TIBETAN SUBJOINED LETTER DA +0FA2 ; [.253E.0020.0002.0FA1][.2565.0020.0002.0FB7] # TIBETAN SUBJOINED LETTER DHA +0F53 ; [.253F.0020.0002.0F53] # TIBETAN LETTER NA +0FA3 ; [.2540.0020.0002.0FA3] # TIBETAN SUBJOINED LETTER NA +0F54 ; [.2541.0020.0002.0F54] # TIBETAN LETTER PA +0FA4 ; [.2542.0020.0002.0FA4] # TIBETAN SUBJOINED LETTER PA +0F55 ; [.2543.0020.0002.0F55] # TIBETAN LETTER PHA +0FA5 ; [.2544.0020.0002.0FA5] # TIBETAN SUBJOINED LETTER PHA +0F56 ; [.2545.0020.0002.0F56] # TIBETAN LETTER BA +0F57 ; [.2545.0020.0002.0F56][.2565.0020.0002.0FB7] # TIBETAN LETTER BHA +0FA6 ; [.2546.0020.0002.0FA6] # TIBETAN SUBJOINED LETTER BA +0FA7 ; [.2546.0020.0002.0FA6][.2565.0020.0002.0FB7] # TIBETAN SUBJOINED LETTER BHA +0F58 ; [.2547.0020.0002.0F58] # TIBETAN LETTER MA +0FA8 ; [.2548.0020.0002.0FA8] # TIBETAN SUBJOINED LETTER MA +0F59 ; [.2549.0020.0002.0F59] # TIBETAN LETTER TSA +0FA9 ; [.254A.0020.0002.0FA9] # TIBETAN SUBJOINED LETTER TSA +0F5A ; [.254B.0020.0002.0F5A] # TIBETAN LETTER TSHA +0FAA ; [.254C.0020.0002.0FAA] # TIBETAN SUBJOINED LETTER TSHA +0F5B ; [.254D.0020.0002.0F5B] # TIBETAN LETTER DZA +0F5C ; [.254D.0020.0002.0F5B][.2565.0020.0002.0FB7] # TIBETAN LETTER DZHA +0FAB ; [.254E.0020.0002.0FAB] # TIBETAN SUBJOINED LETTER DZA +0FAC ; [.254E.0020.0002.0FAB][.2565.0020.0002.0FB7] # TIBETAN SUBJOINED LETTER DZHA +0F5D ; [.254F.0020.0002.0F5D] # TIBETAN LETTER WA +0FAD ; [.2550.0020.0002.0FAD] # TIBETAN SUBJOINED LETTER WA +0FBA ; [.2550.0020.0004.0FBA][.0000.013A.0004.0FBA] # TIBETAN SUBJOINED LETTER FIXED-FORM WA +0F5E ; [.2551.0020.0002.0F5E] # TIBETAN LETTER ZHA +0FAE ; [.2552.0020.0002.0FAE] # TIBETAN SUBJOINED LETTER ZHA +0F5F ; [.2553.0020.0002.0F5F] # TIBETAN LETTER ZA +0FAF ; [.2554.0020.0002.0FAF] # TIBETAN SUBJOINED LETTER ZA +0F60 ; [.2555.0020.0002.0F60] # TIBETAN LETTER -A +0FB0 ; [.2556.0020.0002.0FB0] # TIBETAN SUBJOINED LETTER -A +0F61 ; [.2557.0020.0002.0F61] # TIBETAN LETTER YA +0FB1 ; [.2558.0020.0002.0FB1] # TIBETAN SUBJOINED LETTER YA +0FBB ; [.2558.0020.0004.0FBB][.0000.013A.0004.0FBB] # TIBETAN SUBJOINED LETTER FIXED-FORM YA +0F62 ; [.2559.0020.0002.0F62] # TIBETAN LETTER RA +0F6A ; [.2559.0020.0004.0F6A][.0000.013A.0004.0F6A] # TIBETAN LETTER FIXED-FORM RA +0FB2 ; [.255A.0020.0002.0FB2] # TIBETAN SUBJOINED LETTER RA +0FBC ; [.255A.0020.0004.0FBC][.0000.013A.0004.0FBC] # TIBETAN SUBJOINED LETTER FIXED-FORM RA +0F6C ; [.255B.0020.0002.0F6C] # TIBETAN LETTER RRA +0F63 ; [.255C.0020.0002.0F63] # TIBETAN LETTER LA +0FB3 ; [.255D.0020.0002.0FB3] # TIBETAN SUBJOINED LETTER LA +0F64 ; [.255E.0020.0002.0F64] # TIBETAN LETTER SHA +0FB4 ; [.255F.0020.0002.0FB4] # TIBETAN SUBJOINED LETTER SHA +0F65 ; [.2560.0020.0002.0F65] # TIBETAN LETTER SSA +0FB5 ; [.2561.0020.0002.0FB5] # TIBETAN SUBJOINED LETTER SSA +0F66 ; [.2562.0020.0002.0F66] # TIBETAN LETTER SA +0FB6 ; [.2563.0020.0002.0FB6] # TIBETAN SUBJOINED LETTER SA +0F67 ; [.2564.0020.0002.0F67] # TIBETAN LETTER HA +0FB7 ; [.2565.0020.0002.0FB7] # TIBETAN SUBJOINED LETTER HA +0F68 ; [.2566.0020.0002.0F68] # TIBETAN LETTER A +0F00 ; [.2566.0020.0004.0F00][.257D.0020.0004.0F00][.0000.00F3.001F.0F00] # TIBETAN SYLLABLE OM +0FB8 ; [.2567.0020.0002.0FB8] # TIBETAN SUBJOINED LETTER A +0F88 ; [.2568.0020.0002.0F88] # TIBETAN SIGN LCE TSA CAN +0F8D ; [.2569.0020.0002.0F8D] # TIBETAN SUBJOINED SIGN LCE TSA CAN +0F89 ; [.256A.0020.0002.0F89] # TIBETAN SIGN MCHU CAN +0F8E ; [.256B.0020.0002.0F8E] # TIBETAN SUBJOINED SIGN MCHU CAN +0F8C ; [.256C.0020.0002.0F8C] # TIBETAN SIGN INVERTED MCHU CAN +0F8F ; [.256D.0020.0002.0F8F] # TIBETAN SUBJOINED SIGN INVERTED MCHU CAN +0F8A ; [.256E.0020.0002.0F8A] # TIBETAN SIGN GRU CAN RGYINGS +0F8B ; [.256F.0020.0002.0F8B] # TIBETAN SIGN GRU MED RGYINGS +0F71 ; [.2570.0020.0002.0F71] # TIBETAN VOWEL SIGN AA +0F72 ; [.2571.0020.0002.0F72] # TIBETAN VOWEL SIGN I +0F73 ; [.2572.0020.0002.0F73] # TIBETAN VOWEL SIGN II +0F71 0F72 ; [.2572.0020.0002.0F73] # TIBETAN VOWEL SIGN II +0F80 ; [.2573.0020.0002.0F80] # TIBETAN VOWEL SIGN REVERSED I +0F81 ; [.2574.0020.0002.0F81] # TIBETAN VOWEL SIGN REVERSED II +0F71 0F80 ; [.2574.0020.0002.0F81] # TIBETAN VOWEL SIGN REVERSED II +0F74 ; [.2575.0020.0002.0F74] # TIBETAN VOWEL SIGN U +0F75 ; [.2576.0020.0002.0F75] # TIBETAN VOWEL SIGN UU +0F71 0F74 ; [.2576.0020.0002.0F75] # TIBETAN VOWEL SIGN UU +0F76 ; [.2577.0020.0002.0F76] # TIBETAN VOWEL SIGN VOCALIC R +0FB2 0F80 ; [.2577.0020.0002.0F76] # TIBETAN VOWEL SIGN VOCALIC R +0F77 ; [.2578.0020.0002.0F77] # TIBETAN VOWEL SIGN VOCALIC RR +0FB2 0F71 0F80 ; [.2578.0020.0002.0F77] # TIBETAN VOWEL SIGN VOCALIC RR +0FB2 0F81 ; [.2578.0020.0002.0F77] # TIBETAN VOWEL SIGN VOCALIC RR +0F78 ; [.2579.0020.0002.0F78] # TIBETAN VOWEL SIGN VOCALIC L +0FB3 0F80 ; [.2579.0020.0002.0F78] # TIBETAN VOWEL SIGN VOCALIC L +0F79 ; [.257A.0020.0002.0F79] # TIBETAN VOWEL SIGN VOCALIC LL +0FB3 0F71 0F80 ; [.257A.0020.0002.0F79] # TIBETAN VOWEL SIGN VOCALIC LL +0FB3 0F81 ; [.257A.0020.0002.0F79] # TIBETAN VOWEL SIGN VOCALIC LL +0F7A ; [.257B.0020.0002.0F7A] # TIBETAN VOWEL SIGN E +0F7B ; [.257C.0020.0002.0F7B] # TIBETAN VOWEL SIGN EE +0F7C ; [.257D.0020.0002.0F7C] # TIBETAN VOWEL SIGN O +0F7D ; [.257E.0020.0002.0F7D] # TIBETAN VOWEL SIGN OO +0F84 ; [.257F.0020.0002.0F84] # TIBETAN MARK HALANTA +1C00 ; [.2580.0020.0002.1C00] # LEPCHA LETTER KA +1C01 ; [.2581.0020.0002.1C01] # LEPCHA LETTER KLA +1C02 ; [.2582.0020.0002.1C02] # LEPCHA LETTER KHA +1C03 ; [.2583.0020.0002.1C03] # LEPCHA LETTER GA +1C04 ; [.2584.0020.0002.1C04] # LEPCHA LETTER GLA +1C05 ; [.2585.0020.0002.1C05] # LEPCHA LETTER NGA +1C06 ; [.2586.0020.0002.1C06] # LEPCHA LETTER CA +1C07 ; [.2587.0020.0002.1C07] # LEPCHA LETTER CHA +1C08 ; [.2588.0020.0002.1C08] # LEPCHA LETTER JA +1C09 ; [.2589.0020.0002.1C09] # LEPCHA LETTER NYA +1C4D ; [.258A.0020.0002.1C4D] # LEPCHA LETTER TTA +1C4E ; [.258B.0020.0002.1C4E] # LEPCHA LETTER TTHA +1C4F ; [.258C.0020.0002.1C4F] # LEPCHA LETTER DDA +1C0A ; [.258D.0020.0002.1C0A] # LEPCHA LETTER TA +1C0B ; [.258E.0020.0002.1C0B] # LEPCHA LETTER THA +1C0C ; [.258F.0020.0002.1C0C] # LEPCHA LETTER DA +1C0D ; [.2590.0020.0002.1C0D] # LEPCHA LETTER NA +1C0E ; [.2591.0020.0002.1C0E] # LEPCHA LETTER PA +1C0F ; [.2592.0020.0002.1C0F] # LEPCHA LETTER PLA +1C10 ; [.2593.0020.0002.1C10] # LEPCHA LETTER PHA +1C11 ; [.2594.0020.0002.1C11] # LEPCHA LETTER FA +1C12 ; [.2595.0020.0002.1C12] # LEPCHA LETTER FLA +1C13 ; [.2596.0020.0002.1C13] # LEPCHA LETTER BA +1C14 ; [.2597.0020.0002.1C14] # LEPCHA LETTER BLA +1C15 ; [.2598.0020.0002.1C15] # LEPCHA LETTER MA +1C16 ; [.2599.0020.0002.1C16] # LEPCHA LETTER MLA +1C17 ; [.259A.0020.0002.1C17] # LEPCHA LETTER TSA +1C18 ; [.259B.0020.0002.1C18] # LEPCHA LETTER TSHA +1C19 ; [.259C.0020.0002.1C19] # LEPCHA LETTER DZA +1C1A ; [.259D.0020.0002.1C1A] # LEPCHA LETTER YA +1C24 ; [.259E.0020.0002.1C24] # LEPCHA SUBJOINED LETTER YA +1C1B ; [.259F.0020.0002.1C1B] # LEPCHA LETTER RA +1C25 ; [.25A0.0020.0002.1C25] # LEPCHA SUBJOINED LETTER RA +1C1C ; [.25A1.0020.0002.1C1C] # LEPCHA LETTER LA +1C1D ; [.25A2.0020.0002.1C1D] # LEPCHA LETTER HA +1C1E ; [.25A3.0020.0002.1C1E] # LEPCHA LETTER HLA +1C1F ; [.25A4.0020.0002.1C1F] # LEPCHA LETTER VA +1C20 ; [.25A5.0020.0002.1C20] # LEPCHA LETTER SA +1C21 ; [.25A6.0020.0002.1C21] # LEPCHA LETTER SHA +1C22 ; [.25A7.0020.0002.1C22] # LEPCHA LETTER WA +1C23 ; [.25A8.0020.0002.1C23] # LEPCHA LETTER A +1C36 ; [.25A9.0020.0002.1C36] # LEPCHA SIGN RAN +1C26 ; [.25AA.0020.0002.1C26] # LEPCHA VOWEL SIGN AA +1C27 ; [.25AB.0020.0002.1C27] # LEPCHA VOWEL SIGN I +1C28 ; [.25AC.0020.0002.1C28] # LEPCHA VOWEL SIGN O +1C29 ; [.25AD.0020.0002.1C29] # LEPCHA VOWEL SIGN OO +1C2A ; [.25AE.0020.0002.1C2A] # LEPCHA VOWEL SIGN U +1C2B ; [.25AF.0020.0002.1C2B] # LEPCHA VOWEL SIGN UU +1C2C ; [.25B0.0020.0002.1C2C] # LEPCHA VOWEL SIGN E +1C2D ; [.25B1.0020.0002.1C2D] # LEPCHA CONSONANT SIGN K +1C2E ; [.25B2.0020.0002.1C2E] # LEPCHA CONSONANT SIGN M +1C2F ; [.25B3.0020.0002.1C2F] # LEPCHA CONSONANT SIGN L +1C30 ; [.25B4.0020.0002.1C30] # LEPCHA CONSONANT SIGN N +1C31 ; [.25B5.0020.0002.1C31] # LEPCHA CONSONANT SIGN P +1C32 ; [.25B6.0020.0002.1C32] # LEPCHA CONSONANT SIGN R +1C33 ; [.25B7.0020.0002.1C33] # LEPCHA CONSONANT SIGN T +1C34 ; [.25B8.0020.0002.1C34] # LEPCHA CONSONANT SIGN NYIN-DO +1C35 ; [.25B9.0020.0002.1C35] # LEPCHA CONSONANT SIGN KANG +A840 ; [.25BA.0020.0002.A840] # PHAGS-PA LETTER KA +A841 ; [.25BB.0020.0002.A841] # PHAGS-PA LETTER KHA +A842 ; [.25BC.0020.0002.A842] # PHAGS-PA LETTER GA +A843 ; [.25BD.0020.0002.A843] # PHAGS-PA LETTER NGA +A844 ; [.25BE.0020.0002.A844] # PHAGS-PA LETTER CA +A845 ; [.25BF.0020.0002.A845] # PHAGS-PA LETTER CHA +A846 ; [.25C0.0020.0002.A846] # PHAGS-PA LETTER JA +A847 ; [.25C1.0020.0002.A847] # PHAGS-PA LETTER NYA +A869 ; [.25C2.0020.0002.A869] # PHAGS-PA LETTER TTA +A86A ; [.25C3.0020.0002.A86A] # PHAGS-PA LETTER TTHA +A86B ; [.25C4.0020.0002.A86B] # PHAGS-PA LETTER DDA +A86C ; [.25C5.0020.0002.A86C] # PHAGS-PA LETTER NNA +A848 ; [.25C6.0020.0002.A848] # PHAGS-PA LETTER TA +A849 ; [.25C7.0020.0002.A849] # PHAGS-PA LETTER THA +A84A ; [.25C8.0020.0002.A84A] # PHAGS-PA LETTER DA +A84B ; [.25C9.0020.0002.A84B] # PHAGS-PA LETTER NA +A84C ; [.25CA.0020.0002.A84C] # PHAGS-PA LETTER PA +A84D ; [.25CB.0020.0002.A84D] # PHAGS-PA LETTER PHA +A84E ; [.25CC.0020.0002.A84E] # PHAGS-PA LETTER BA +A84F ; [.25CD.0020.0002.A84F] # PHAGS-PA LETTER MA +A850 ; [.25CE.0020.0002.A850] # PHAGS-PA LETTER TSA +A851 ; [.25CF.0020.0002.A851] # PHAGS-PA LETTER TSHA +A852 ; [.25D0.0020.0002.A852] # PHAGS-PA LETTER DZA +A853 ; [.25D1.0020.0002.A853] # PHAGS-PA LETTER WA +A867 ; [.25D2.0020.0002.A867] # PHAGS-PA SUBJOINED LETTER WA +A854 ; [.25D3.0020.0002.A854] # PHAGS-PA LETTER ZHA +A855 ; [.25D4.0020.0002.A855] # PHAGS-PA LETTER ZA +A856 ; [.25D5.0020.0002.A856] # PHAGS-PA LETTER SMALL A +A857 ; [.25D6.0020.0002.A857] # PHAGS-PA LETTER YA +A868 ; [.25D7.0020.0002.A868] # PHAGS-PA SUBJOINED LETTER YA +A86D ; [.25D8.0020.0002.A86D] # PHAGS-PA LETTER ALTERNATE YA +A858 ; [.25D9.0020.0002.A858] # PHAGS-PA LETTER RA +A871 ; [.25DA.0020.0002.A871] # PHAGS-PA SUBJOINED LETTER RA +A872 ; [.25DB.0020.0002.A872] # PHAGS-PA SUPERFIXED LETTER RA +A859 ; [.25DC.0020.0002.A859] # PHAGS-PA LETTER LA +A85A ; [.25DD.0020.0002.A85A] # PHAGS-PA LETTER SHA +A86E ; [.25DE.0020.0002.A86E] # PHAGS-PA LETTER VOICELESS SHA +A85B ; [.25DF.0020.0002.A85B] # PHAGS-PA LETTER SA +A85C ; [.25E0.0020.0002.A85C] # PHAGS-PA LETTER HA +A86F ; [.25E1.0020.0002.A86F] # PHAGS-PA LETTER VOICED HA +A870 ; [.25E2.0020.0002.A870] # PHAGS-PA LETTER ASPIRATED FA +A85D ; [.25E3.0020.0002.A85D] # PHAGS-PA LETTER A +A862 ; [.25E4.0020.0002.A862] # PHAGS-PA LETTER QA +A863 ; [.25E5.0020.0002.A863] # PHAGS-PA LETTER XA +A864 ; [.25E6.0020.0002.A864] # PHAGS-PA LETTER FA +A865 ; [.25E7.0020.0002.A865] # PHAGS-PA LETTER GGA +A85E ; [.25E8.0020.0002.A85E] # PHAGS-PA LETTER I +A85F ; [.25E9.0020.0002.A85F] # PHAGS-PA LETTER U +A860 ; [.25EA.0020.0002.A860] # PHAGS-PA LETTER E +A861 ; [.25EB.0020.0002.A861] # PHAGS-PA LETTER O +A866 ; [.25EC.0020.0002.A866] # PHAGS-PA LETTER EE +A873 ; [.25ED.0020.0002.A873] # PHAGS-PA LETTER CANDRABINDU +1900 ; [.25EE.0020.0002.1900] # LIMBU VOWEL-CARRIER LETTER +1901 ; [.25EF.0020.0002.1901] # LIMBU LETTER KA +1902 ; [.25F0.0020.0002.1902] # LIMBU LETTER KHA +1903 ; [.25F1.0020.0002.1903] # LIMBU LETTER GA +1904 ; [.25F2.0020.0002.1904] # LIMBU LETTER GHA +1905 ; [.25F3.0020.0002.1905] # LIMBU LETTER NGA +1906 ; [.25F4.0020.0002.1906] # LIMBU LETTER CA +1907 ; [.25F5.0020.0002.1907] # LIMBU LETTER CHA +1908 ; [.25F6.0020.0002.1908] # LIMBU LETTER JA +1909 ; [.25F7.0020.0002.1909] # LIMBU LETTER JHA +190A ; [.25F8.0020.0002.190A] # LIMBU LETTER YAN +190B ; [.25F9.0020.0002.190B] # LIMBU LETTER TA +190C ; [.25FA.0020.0002.190C] # LIMBU LETTER THA +190D ; [.25FB.0020.0002.190D] # LIMBU LETTER DA +190E ; [.25FC.0020.0002.190E] # LIMBU LETTER DHA +190F ; [.25FD.0020.0002.190F] # LIMBU LETTER NA +1910 ; [.25FE.0020.0002.1910] # LIMBU LETTER PA +1911 ; [.25FF.0020.0002.1911] # LIMBU LETTER PHA +1912 ; [.2600.0020.0002.1912] # LIMBU LETTER BA +1913 ; [.2601.0020.0002.1913] # LIMBU LETTER BHA +1914 ; [.2602.0020.0002.1914] # LIMBU LETTER MA +1915 ; [.2603.0020.0002.1915] # LIMBU LETTER YA +1916 ; [.2604.0020.0002.1916] # LIMBU LETTER RA +1917 ; [.2605.0020.0002.1917] # LIMBU LETTER LA +1918 ; [.2606.0020.0002.1918] # LIMBU LETTER WA +1919 ; [.2607.0020.0002.1919] # LIMBU LETTER SHA +191A ; [.2608.0020.0002.191A] # LIMBU LETTER SSA +191B ; [.2609.0020.0002.191B] # LIMBU LETTER SA +191C ; [.260A.0020.0002.191C] # LIMBU LETTER HA +1920 ; [.260B.0020.0002.1920] # LIMBU VOWEL SIGN A +1921 ; [.260C.0020.0002.1921] # LIMBU VOWEL SIGN I +1922 ; [.260D.0020.0002.1922] # LIMBU VOWEL SIGN U +1923 ; [.260E.0020.0002.1923] # LIMBU VOWEL SIGN EE +1924 ; [.260F.0020.0002.1924] # LIMBU VOWEL SIGN AI +1925 ; [.2610.0020.0002.1925] # LIMBU VOWEL SIGN OO +1926 ; [.2611.0020.0002.1926] # LIMBU VOWEL SIGN AU +1927 ; [.2612.0020.0002.1927] # LIMBU VOWEL SIGN E +1928 ; [.2613.0020.0002.1928] # LIMBU VOWEL SIGN O +1929 ; [.2614.0020.0002.1929] # LIMBU SUBJOINED LETTER YA +192A ; [.2615.0020.0002.192A] # LIMBU SUBJOINED LETTER RA +192B ; [.2616.0020.0002.192B] # LIMBU SUBJOINED LETTER WA +1930 ; [.2617.0020.0002.1930] # LIMBU SMALL LETTER KA +1931 ; [.2618.0020.0002.1931] # LIMBU SMALL LETTER NGA +1932 ; [.2619.0020.0002.1932] # LIMBU SMALL LETTER ANUSVARA +1933 ; [.261A.0020.0002.1933] # LIMBU SMALL LETTER TA +1934 ; [.261B.0020.0002.1934] # LIMBU SMALL LETTER NA +1935 ; [.261C.0020.0002.1935] # LIMBU SMALL LETTER PA +1936 ; [.261D.0020.0002.1936] # LIMBU SMALL LETTER MA +1937 ; [.261E.0020.0002.1937] # LIMBU SMALL LETTER RA +1938 ; [.261F.0020.0002.1938] # LIMBU SMALL LETTER LA +1700 ; [.2620.0020.0002.1700] # TAGALOG LETTER A +1701 ; [.2621.0020.0002.1701] # TAGALOG LETTER I +1702 ; [.2622.0020.0002.1702] # TAGALOG LETTER U +1703 ; [.2623.0020.0002.1703] # TAGALOG LETTER KA +1704 ; [.2624.0020.0002.1704] # TAGALOG LETTER GA +1705 ; [.2625.0020.0002.1705] # TAGALOG LETTER NGA +1706 ; [.2626.0020.0002.1706] # TAGALOG LETTER TA +1707 ; [.2627.0020.0002.1707] # TAGALOG LETTER DA +1708 ; [.2628.0020.0002.1708] # TAGALOG LETTER NA +1709 ; [.2629.0020.0002.1709] # TAGALOG LETTER PA +170A ; [.262A.0020.0002.170A] # TAGALOG LETTER BA +170B ; [.262B.0020.0002.170B] # TAGALOG LETTER MA +170C ; [.262C.0020.0002.170C] # TAGALOG LETTER YA +170E ; [.262D.0020.0002.170E] # TAGALOG LETTER LA +170F ; [.262E.0020.0002.170F] # TAGALOG LETTER WA +1710 ; [.262F.0020.0002.1710] # TAGALOG LETTER SA +1711 ; [.2630.0020.0002.1711] # TAGALOG LETTER HA +1712 ; [.2631.0020.0002.1712] # TAGALOG VOWEL SIGN I +1713 ; [.2632.0020.0002.1713] # TAGALOG VOWEL SIGN U +1714 ; [.2633.0020.0002.1714] # TAGALOG SIGN VIRAMA +1720 ; [.2634.0020.0002.1720] # HANUNOO LETTER A +1721 ; [.2635.0020.0002.1721] # HANUNOO LETTER I +1722 ; [.2636.0020.0002.1722] # HANUNOO LETTER U +1723 ; [.2637.0020.0002.1723] # HANUNOO LETTER KA +1724 ; [.2638.0020.0002.1724] # HANUNOO LETTER GA +1725 ; [.2639.0020.0002.1725] # HANUNOO LETTER NGA +1726 ; [.263A.0020.0002.1726] # HANUNOO LETTER TA +1727 ; [.263B.0020.0002.1727] # HANUNOO LETTER DA +1728 ; [.263C.0020.0002.1728] # HANUNOO LETTER NA +1729 ; [.263D.0020.0002.1729] # HANUNOO LETTER PA +172A ; [.263E.0020.0002.172A] # HANUNOO LETTER BA +172B ; [.263F.0020.0002.172B] # HANUNOO LETTER MA +172C ; [.2640.0020.0002.172C] # HANUNOO LETTER YA +172D ; [.2641.0020.0002.172D] # HANUNOO LETTER RA +172E ; [.2642.0020.0002.172E] # HANUNOO LETTER LA +172F ; [.2643.0020.0002.172F] # HANUNOO LETTER WA +1730 ; [.2644.0020.0002.1730] # HANUNOO LETTER SA +1731 ; [.2645.0020.0002.1731] # HANUNOO LETTER HA +1732 ; [.2646.0020.0002.1732] # HANUNOO VOWEL SIGN I +1733 ; [.2647.0020.0002.1733] # HANUNOO VOWEL SIGN U +1734 ; [.2648.0020.0002.1734] # HANUNOO SIGN PAMUDPOD +1740 ; [.2649.0020.0002.1740] # BUHID LETTER A +1741 ; [.264A.0020.0002.1741] # BUHID LETTER I +1742 ; [.264B.0020.0002.1742] # BUHID LETTER U +1743 ; [.264C.0020.0002.1743] # BUHID LETTER KA +1744 ; [.264D.0020.0002.1744] # BUHID LETTER GA +1745 ; [.264E.0020.0002.1745] # BUHID LETTER NGA +1746 ; [.264F.0020.0002.1746] # BUHID LETTER TA +1747 ; [.2650.0020.0002.1747] # BUHID LETTER DA +1748 ; [.2651.0020.0002.1748] # BUHID LETTER NA +1749 ; [.2652.0020.0002.1749] # BUHID LETTER PA +174A ; [.2653.0020.0002.174A] # BUHID LETTER BA +174B ; [.2654.0020.0002.174B] # BUHID LETTER MA +174C ; [.2655.0020.0002.174C] # BUHID LETTER YA +174D ; [.2656.0020.0002.174D] # BUHID LETTER RA +174E ; [.2657.0020.0002.174E] # BUHID LETTER LA +174F ; [.2658.0020.0002.174F] # BUHID LETTER WA +1750 ; [.2659.0020.0002.1750] # BUHID LETTER SA +1751 ; [.265A.0020.0002.1751] # BUHID LETTER HA +1752 ; [.265B.0020.0002.1752] # BUHID VOWEL SIGN I +1753 ; [.265C.0020.0002.1753] # BUHID VOWEL SIGN U +1760 ; [.265D.0020.0002.1760] # TAGBANWA LETTER A +1761 ; [.265E.0020.0002.1761] # TAGBANWA LETTER I +1762 ; [.265F.0020.0002.1762] # TAGBANWA LETTER U +1763 ; [.2660.0020.0002.1763] # TAGBANWA LETTER KA +1764 ; [.2661.0020.0002.1764] # TAGBANWA LETTER GA +1765 ; [.2662.0020.0002.1765] # TAGBANWA LETTER NGA +1766 ; [.2663.0020.0002.1766] # TAGBANWA LETTER TA +1767 ; [.2664.0020.0002.1767] # TAGBANWA LETTER DA +1768 ; [.2665.0020.0002.1768] # TAGBANWA LETTER NA +1769 ; [.2666.0020.0002.1769] # TAGBANWA LETTER PA +176A ; [.2667.0020.0002.176A] # TAGBANWA LETTER BA +176B ; [.2668.0020.0002.176B] # TAGBANWA LETTER MA +176C ; [.2669.0020.0002.176C] # TAGBANWA LETTER YA +176E ; [.266A.0020.0002.176E] # TAGBANWA LETTER LA +176F ; [.266B.0020.0002.176F] # TAGBANWA LETTER WA +1770 ; [.266C.0020.0002.1770] # TAGBANWA LETTER SA +1772 ; [.266D.0020.0002.1772] # TAGBANWA VOWEL SIGN I +1773 ; [.266E.0020.0002.1773] # TAGBANWA VOWEL SIGN U +1A00 ; [.266F.0020.0002.1A00] # BUGINESE LETTER KA +1A01 ; [.2670.0020.0002.1A01] # BUGINESE LETTER GA +1A02 ; [.2671.0020.0002.1A02] # BUGINESE LETTER NGA +1A03 ; [.2672.0020.0002.1A03] # BUGINESE LETTER NGKA +1A04 ; [.2673.0020.0002.1A04] # BUGINESE LETTER PA +1A05 ; [.2674.0020.0002.1A05] # BUGINESE LETTER BA +1A06 ; [.2675.0020.0002.1A06] # BUGINESE LETTER MA +1A07 ; [.2676.0020.0002.1A07] # BUGINESE LETTER MPA +1A08 ; [.2677.0020.0002.1A08] # BUGINESE LETTER TA +1A09 ; [.2678.0020.0002.1A09] # BUGINESE LETTER DA +1A0A ; [.2679.0020.0002.1A0A] # BUGINESE LETTER NA +1A0B ; [.267A.0020.0002.1A0B] # BUGINESE LETTER NRA +1A0C ; [.267B.0020.0002.1A0C] # BUGINESE LETTER CA +1A0D ; [.267C.0020.0002.1A0D] # BUGINESE LETTER JA +1A0E ; [.267D.0020.0002.1A0E] # BUGINESE LETTER NYA +1A0F ; [.267E.0020.0002.1A0F] # BUGINESE LETTER NYCA +1A10 ; [.267F.0020.0002.1A10] # BUGINESE LETTER YA +1A11 ; [.2680.0020.0002.1A11] # BUGINESE LETTER RA +1A12 ; [.2681.0020.0002.1A12] # BUGINESE LETTER LA +1A13 ; [.2682.0020.0002.1A13] # BUGINESE LETTER VA +1A14 ; [.2683.0020.0002.1A14] # BUGINESE LETTER SA +1A15 ; [.2684.0020.0002.1A15] # BUGINESE LETTER A +1A16 ; [.2685.0020.0002.1A16] # BUGINESE LETTER HA +1A17 ; [.2686.0020.0002.1A17] # BUGINESE VOWEL SIGN I +1A18 ; [.2687.0020.0002.1A18] # BUGINESE VOWEL SIGN U +1A19 ; [.2688.0020.0002.1A19] # BUGINESE VOWEL SIGN E +1A1A ; [.2689.0020.0002.1A1A] # BUGINESE VOWEL SIGN O +1A1B ; [.268A.0020.0002.1A1B] # BUGINESE VOWEL SIGN AE +1BC0 ; [.268B.0020.0002.1BC0] # BATAK LETTER A +1BC1 ; [.268B.0020.0004.1BC1] # BATAK LETTER SIMALUNGUN A +1BC2 ; [.268C.0020.0002.1BC2] # BATAK LETTER HA +1BC3 ; [.268C.0020.0004.1BC3] # BATAK LETTER SIMALUNGUN HA +1BC4 ; [.268C.0020.0004.1BC4] # BATAK LETTER MANDAILING HA +1BC5 ; [.268D.0020.0002.1BC5] # BATAK LETTER BA +1BC6 ; [.268D.0020.0004.1BC6] # BATAK LETTER KARO BA +1BC7 ; [.268E.0020.0002.1BC7] # BATAK LETTER PA +1BC8 ; [.268E.0020.0004.1BC8] # BATAK LETTER SIMALUNGUN PA +1BC9 ; [.268F.0020.0002.1BC9] # BATAK LETTER NA +1BCA ; [.268F.0020.0004.1BCA] # BATAK LETTER MANDAILING NA +1BCB ; [.2690.0020.0002.1BCB] # BATAK LETTER WA +1BCC ; [.2690.0020.0004.1BCC] # BATAK LETTER SIMALUNGUN WA +1BCD ; [.2690.0020.0004.1BCD] # BATAK LETTER PAKPAK WA +1BCE ; [.2691.0020.0002.1BCE] # BATAK LETTER GA +1BCF ; [.2691.0020.0004.1BCF] # BATAK LETTER SIMALUNGUN GA +1BD0 ; [.2692.0020.0002.1BD0] # BATAK LETTER JA +1BD1 ; [.2693.0020.0002.1BD1] # BATAK LETTER DA +1BD2 ; [.2694.0020.0002.1BD2] # BATAK LETTER RA +1BD3 ; [.2694.0020.0004.1BD3] # BATAK LETTER SIMALUNGUN RA +1BD4 ; [.2695.0020.0002.1BD4] # BATAK LETTER MA +1BD5 ; [.2695.0020.0004.1BD5] # BATAK LETTER SIMALUNGUN MA +1BD6 ; [.2696.0020.0002.1BD6] # BATAK LETTER SOUTHERN TA +1BD7 ; [.2696.0020.0004.1BD7] # BATAK LETTER NORTHERN TA +1BD8 ; [.2697.0020.0002.1BD8] # BATAK LETTER SA +1BD9 ; [.2697.0020.0004.1BD9] # BATAK LETTER SIMALUNGUN SA +1BDA ; [.2697.0020.0004.1BDA] # BATAK LETTER MANDAILING SA +1BDB ; [.2698.0020.0002.1BDB] # BATAK LETTER YA +1BDC ; [.2698.0020.0004.1BDC] # BATAK LETTER SIMALUNGUN YA +1BDD ; [.2699.0020.0002.1BDD] # BATAK LETTER NGA +1BDE ; [.269A.0020.0002.1BDE] # BATAK LETTER LA +1BDF ; [.269A.0020.0004.1BDF] # BATAK LETTER SIMALUNGUN LA +1BE0 ; [.269B.0020.0002.1BE0] # BATAK LETTER NYA +1BE1 ; [.269C.0020.0002.1BE1] # BATAK LETTER CA +1BE2 ; [.269D.0020.0002.1BE2] # BATAK LETTER NDA +1BE3 ; [.269E.0020.0002.1BE3] # BATAK LETTER MBA +1BE4 ; [.269F.0020.0002.1BE4] # BATAK LETTER I +1BE5 ; [.26A0.0020.0002.1BE5] # BATAK LETTER U +1BE7 ; [.26A1.0020.0002.1BE7] # BATAK VOWEL SIGN E +1BE8 ; [.26A1.0020.0004.1BE8] # BATAK VOWEL SIGN PAKPAK E +1BE9 ; [.26A2.0020.0002.1BE9] # BATAK VOWEL SIGN EE +1BEA ; [.26A3.0020.0002.1BEA] # BATAK VOWEL SIGN I +1BEB ; [.26A3.0020.0004.1BEB] # BATAK VOWEL SIGN KARO I +1BEC ; [.26A4.0020.0002.1BEC] # BATAK VOWEL SIGN O +1BED ; [.26A4.0020.0004.1BED] # BATAK VOWEL SIGN KARO O +1BEE ; [.26A5.0020.0002.1BEE] # BATAK VOWEL SIGN U +1BEF ; [.26A5.0020.0004.1BEF] # BATAK VOWEL SIGN U FOR SIMALUNGUN SA +1BF0 ; [.26A6.0020.0002.1BF0] # BATAK CONSONANT SIGN NG +1BF1 ; [.26A7.0020.0002.1BF1] # BATAK CONSONANT SIGN H +1BF2 ; [.26A8.0020.0002.1BF2] # BATAK PANGOLAT +1BF3 ; [.26A9.0020.0002.1BF3] # BATAK PANONGONAN +A930 ; [.26AA.0020.0002.A930] # REJANG LETTER KA +A931 ; [.26AB.0020.0002.A931] # REJANG LETTER GA +A932 ; [.26AC.0020.0002.A932] # REJANG LETTER NGA +A933 ; [.26AD.0020.0002.A933] # REJANG LETTER TA +A934 ; [.26AE.0020.0002.A934] # REJANG LETTER DA +A935 ; [.26AF.0020.0002.A935] # REJANG LETTER NA +A936 ; [.26B0.0020.0002.A936] # REJANG LETTER PA +A937 ; [.26B1.0020.0002.A937] # REJANG LETTER BA +A938 ; [.26B2.0020.0002.A938] # REJANG LETTER MA +A939 ; [.26B3.0020.0002.A939] # REJANG LETTER CA +A93A ; [.26B4.0020.0002.A93A] # REJANG LETTER JA +A93B ; [.26B5.0020.0002.A93B] # REJANG LETTER NYA +A93C ; [.26B6.0020.0002.A93C] # REJANG LETTER SA +A93D ; [.26B7.0020.0002.A93D] # REJANG LETTER RA +A93E ; [.26B8.0020.0002.A93E] # REJANG LETTER LA +A93F ; [.26B9.0020.0002.A93F] # REJANG LETTER YA +A940 ; [.26BA.0020.0002.A940] # REJANG LETTER WA +A941 ; [.26BB.0020.0002.A941] # REJANG LETTER HA +A942 ; [.26BC.0020.0002.A942] # REJANG LETTER MBA +A943 ; [.26BD.0020.0002.A943] # REJANG LETTER NGGA +A944 ; [.26BE.0020.0002.A944] # REJANG LETTER NDA +A945 ; [.26BF.0020.0002.A945] # REJANG LETTER NYJA +A946 ; [.26C0.0020.0002.A946] # REJANG LETTER A +A947 ; [.26C1.0020.0002.A947] # REJANG VOWEL SIGN I +A948 ; [.26C2.0020.0002.A948] # REJANG VOWEL SIGN U +A949 ; [.26C3.0020.0002.A949] # REJANG VOWEL SIGN E +A94A ; [.26C4.0020.0002.A94A] # REJANG VOWEL SIGN AI +A94B ; [.26C5.0020.0002.A94B] # REJANG VOWEL SIGN O +A94C ; [.26C6.0020.0002.A94C] # REJANG VOWEL SIGN AU +A94D ; [.26C7.0020.0002.A94D] # REJANG VOWEL SIGN EU +A94E ; [.26C8.0020.0002.A94E] # REJANG VOWEL SIGN EA +A94F ; [.26C9.0020.0002.A94F] # REJANG CONSONANT SIGN NG +A950 ; [.26CA.0020.0002.A950] # REJANG CONSONANT SIGN N +A951 ; [.26CB.0020.0002.A951] # REJANG CONSONANT SIGN R +A952 ; [.26CC.0020.0002.A952] # REJANG CONSONANT SIGN H +A953 ; [.26CD.0020.0002.A953] # REJANG VIRAMA +A90A ; [.26CE.0020.0002.A90A] # KAYAH LI LETTER KA +A90B ; [.26CF.0020.0002.A90B] # KAYAH LI LETTER KHA +A90C ; [.26D0.0020.0002.A90C] # KAYAH LI LETTER GA +A90D ; [.26D1.0020.0002.A90D] # KAYAH LI LETTER NGA +A90E ; [.26D2.0020.0002.A90E] # KAYAH LI LETTER SA +A90F ; [.26D3.0020.0002.A90F] # KAYAH LI LETTER SHA +A910 ; [.26D4.0020.0002.A910] # KAYAH LI LETTER ZA +A911 ; [.26D5.0020.0002.A911] # KAYAH LI LETTER NYA +A912 ; [.26D6.0020.0002.A912] # KAYAH LI LETTER TA +A913 ; [.26D7.0020.0002.A913] # KAYAH LI LETTER HTA +A914 ; [.26D8.0020.0002.A914] # KAYAH LI LETTER NA +A915 ; [.26D9.0020.0002.A915] # KAYAH LI LETTER PA +A916 ; [.26DA.0020.0002.A916] # KAYAH LI LETTER PHA +A917 ; [.26DB.0020.0002.A917] # KAYAH LI LETTER MA +A918 ; [.26DC.0020.0002.A918] # KAYAH LI LETTER DA +A919 ; [.26DD.0020.0002.A919] # KAYAH LI LETTER BA +A91A ; [.26DE.0020.0002.A91A] # KAYAH LI LETTER RA +A91B ; [.26DF.0020.0002.A91B] # KAYAH LI LETTER YA +A91C ; [.26E0.0020.0002.A91C] # KAYAH LI LETTER LA +A91D ; [.26E1.0020.0002.A91D] # KAYAH LI LETTER WA +A91E ; [.26E2.0020.0002.A91E] # KAYAH LI LETTER THA +A91F ; [.26E3.0020.0002.A91F] # KAYAH LI LETTER HA +A920 ; [.26E4.0020.0002.A920] # KAYAH LI LETTER VA +A921 ; [.26E5.0020.0002.A921] # KAYAH LI LETTER CA +A922 ; [.26E6.0020.0002.A922] # KAYAH LI LETTER A +A923 ; [.26E7.0020.0002.A923] # KAYAH LI LETTER OE +A924 ; [.26E8.0020.0002.A924] # KAYAH LI LETTER I +A925 ; [.26E9.0020.0002.A925] # KAYAH LI LETTER OO +A926 ; [.26EA.0020.0002.A926] # KAYAH LI VOWEL UE +A927 ; [.26EB.0020.0002.A927] # KAYAH LI VOWEL E +A928 ; [.26EC.0020.0002.A928] # KAYAH LI VOWEL U +A929 ; [.26ED.0020.0002.A929] # KAYAH LI VOWEL EE +A92A ; [.26EE.0020.0002.A92A] # KAYAH LI VOWEL O +1000 ; [.26EF.0020.0002.1000] # MYANMAR LETTER KA +1075 ; [.26F0.0020.0002.1075] # MYANMAR LETTER SHAN KA +1001 ; [.26F1.0020.0002.1001] # MYANMAR LETTER KHA +1076 ; [.26F2.0020.0002.1076] # MYANMAR LETTER SHAN KHA +1002 ; [.26F3.0020.0002.1002] # MYANMAR LETTER GA +1077 ; [.26F4.0020.0002.1077] # MYANMAR LETTER SHAN GA +AA60 ; [.26F5.0020.0002.AA60] # MYANMAR LETTER KHAMTI GA +1003 ; [.26F6.0020.0002.1003] # MYANMAR LETTER GHA +1004 ; [.26F7.0020.0002.1004] # MYANMAR LETTER NGA +105A ; [.26F8.0020.0002.105A] # MYANMAR LETTER MON NGA +1005 ; [.26F9.0020.0002.1005] # MYANMAR LETTER CA +1078 ; [.26FA.0020.0002.1078] # MYANMAR LETTER SHAN CA +AA61 ; [.26FB.0020.0002.AA61] # MYANMAR LETTER KHAMTI CA +1006 ; [.26FC.0020.0002.1006] # MYANMAR LETTER CHA +AA62 ; [.26FD.0020.0002.AA62] # MYANMAR LETTER KHAMTI CHA +1007 ; [.26FE.0020.0002.1007] # MYANMAR LETTER JA +AA63 ; [.26FF.0020.0002.AA63] # MYANMAR LETTER KHAMTI JA +1079 ; [.2700.0020.0002.1079] # MYANMAR LETTER SHAN ZA +AA72 ; [.2701.0020.0002.AA72] # MYANMAR LETTER KHAMTI ZA +1008 ; [.2702.0020.0002.1008] # MYANMAR LETTER JHA +105B ; [.2703.0020.0002.105B] # MYANMAR LETTER MON JHA +AA64 ; [.2704.0020.0002.AA64] # MYANMAR LETTER KHAMTI JHA +1061 ; [.2705.0020.0002.1061] # MYANMAR LETTER SGAW KAREN SHA +1009 ; [.2706.0020.0002.1009] # MYANMAR LETTER NYA +107A ; [.2707.0020.0002.107A] # MYANMAR LETTER SHAN NYA +AA65 ; [.2708.0020.0002.AA65] # MYANMAR LETTER KHAMTI NYA +100A ; [.2709.0020.0002.100A] # MYANMAR LETTER NNYA +100B ; [.270A.0020.0002.100B] # MYANMAR LETTER TTA +AA66 ; [.270B.0020.0002.AA66] # MYANMAR LETTER KHAMTI TTA +100C ; [.270C.0020.0002.100C] # MYANMAR LETTER TTHA +AA67 ; [.270D.0020.0002.AA67] # MYANMAR LETTER KHAMTI TTHA +100D ; [.270E.0020.0002.100D] # MYANMAR LETTER DDA +AA68 ; [.270F.0020.0002.AA68] # MYANMAR LETTER KHAMTI DDA +100E ; [.2710.0020.0002.100E] # MYANMAR LETTER DDHA +AA69 ; [.2711.0020.0002.AA69] # MYANMAR LETTER KHAMTI DDHA +100F ; [.2712.0020.0002.100F] # MYANMAR LETTER NNA +106E ; [.2713.0020.0002.106E] # MYANMAR LETTER EASTERN PWO KAREN NNA +1010 ; [.2714.0020.0002.1010] # MYANMAR LETTER TA +1011 ; [.2715.0020.0002.1011] # MYANMAR LETTER THA +1012 ; [.2716.0020.0002.1012] # MYANMAR LETTER DA +107B ; [.2717.0020.0002.107B] # MYANMAR LETTER SHAN DA +1013 ; [.2718.0020.0002.1013] # MYANMAR LETTER DHA +AA6A ; [.2719.0020.0002.AA6A] # MYANMAR LETTER KHAMTI DHA +1014 ; [.271A.0020.0002.1014] # MYANMAR LETTER NA +107C ; [.271B.0020.0002.107C] # MYANMAR LETTER SHAN NA +AA6B ; [.271C.0020.0002.AA6B] # MYANMAR LETTER KHAMTI NA +105E ; [.271D.0020.0002.105E] # MYANMAR CONSONANT SIGN MON MEDIAL NA +1015 ; [.271E.0020.0002.1015] # MYANMAR LETTER PA +1016 ; [.271F.0020.0002.1016] # MYANMAR LETTER PHA +107D ; [.2720.0020.0002.107D] # MYANMAR LETTER SHAN PHA +107E ; [.2721.0020.0002.107E] # MYANMAR LETTER SHAN FA +AA6F ; [.2722.0020.0002.AA6F] # MYANMAR LETTER KHAMTI FA +108E ; [.2723.0020.0002.108E] # MYANMAR LETTER RUMAI PALAUNG FA +1017 ; [.2724.0020.0002.1017] # MYANMAR LETTER BA +107F ; [.2725.0020.0002.107F] # MYANMAR LETTER SHAN BA +1018 ; [.2726.0020.0002.1018] # MYANMAR LETTER BHA +1019 ; [.2727.0020.0002.1019] # MYANMAR LETTER MA +105F ; [.2728.0020.0002.105F] # MYANMAR CONSONANT SIGN MON MEDIAL MA +101A ; [.2729.0020.0002.101A] # MYANMAR LETTER YA +103B ; [.272A.0020.0002.103B] # MYANMAR CONSONANT SIGN MEDIAL YA +101B ; [.272B.0020.0002.101B] # MYANMAR LETTER RA +AA73 ; [.272C.0020.0002.AA73] # MYANMAR LETTER KHAMTI RA +AA7A ; [.272D.0020.0002.AA7A] # MYANMAR LETTER AITON RA +103C ; [.272E.0020.0002.103C] # MYANMAR CONSONANT SIGN MEDIAL RA +101C ; [.272F.0020.0002.101C] # MYANMAR LETTER LA +1060 ; [.2730.0020.0002.1060] # MYANMAR CONSONANT SIGN MON MEDIAL LA +101D ; [.2731.0020.0002.101D] # MYANMAR LETTER WA +103D ; [.2732.0020.0002.103D] # MYANMAR CONSONANT SIGN MEDIAL WA +1082 ; [.2733.0020.0002.1082] # MYANMAR CONSONANT SIGN SHAN MEDIAL WA +1080 ; [.2734.0020.0002.1080] # MYANMAR LETTER SHAN THA +1050 ; [.2735.0020.0002.1050] # MYANMAR LETTER SHA +1051 ; [.2736.0020.0002.1051] # MYANMAR LETTER SSA +1065 ; [.2737.0020.0002.1065] # MYANMAR LETTER WESTERN PWO KAREN THA +101E ; [.2738.0020.0002.101E] # MYANMAR LETTER SA +103F ; [.2738.0020.0004.103F][.276F.0020.0004.103F][.2738.0020.001F.103F] # MYANMAR LETTER GREAT SA +AA6C ; [.2739.0020.0002.AA6C] # MYANMAR LETTER KHAMTI SA +101F ; [.273A.0020.0002.101F] # MYANMAR LETTER HA +1081 ; [.273B.0020.0002.1081] # MYANMAR LETTER SHAN HA +AA6D ; [.273C.0020.0002.AA6D] # MYANMAR LETTER KHAMTI HA +103E ; [.273D.0020.0002.103E] # MYANMAR CONSONANT SIGN MEDIAL HA +AA6E ; [.273E.0020.0002.AA6E] # MYANMAR LETTER KHAMTI HHA +AA71 ; [.273F.0020.0002.AA71] # MYANMAR LETTER KHAMTI XA +1020 ; [.2740.0020.0002.1020] # MYANMAR LETTER LLA +105C ; [.2741.0020.0002.105C] # MYANMAR LETTER MON BBA +105D ; [.2742.0020.0002.105D] # MYANMAR LETTER MON BBE +106F ; [.2743.0020.0002.106F] # MYANMAR LETTER EASTERN PWO KAREN YWA +1070 ; [.2744.0020.0002.1070] # MYANMAR LETTER EASTERN PWO KAREN GHWA +1066 ; [.2745.0020.0002.1066] # MYANMAR LETTER WESTERN PWO KAREN PWA +1021 ; [.2746.0020.0002.1021] # MYANMAR LETTER A +1022 ; [.2747.0020.0002.1022] # MYANMAR LETTER SHAN A +1023 ; [.2748.0020.0002.1023] # MYANMAR LETTER I +1024 ; [.2749.0020.0002.1024] # MYANMAR LETTER II +1025 ; [.274A.0020.0002.1025] # MYANMAR LETTER U +1026 ; [.274B.0020.0002.1026] # MYANMAR LETTER UU +1025 102E ; [.274B.0020.0002.1026] # MYANMAR LETTER UU +1052 ; [.274C.0020.0002.1052] # MYANMAR LETTER VOCALIC R +1053 ; [.274D.0020.0002.1053] # MYANMAR LETTER VOCALIC RR +1054 ; [.274E.0020.0002.1054] # MYANMAR LETTER VOCALIC L +1055 ; [.274F.0020.0002.1055] # MYANMAR LETTER VOCALIC LL +1027 ; [.2750.0020.0002.1027] # MYANMAR LETTER E +1028 ; [.2751.0020.0002.1028] # MYANMAR LETTER MON E +1029 ; [.2752.0020.0002.1029] # MYANMAR LETTER O +102A ; [.2753.0020.0002.102A] # MYANMAR LETTER AU +102C ; [.2754.0020.0002.102C] # MYANMAR VOWEL SIGN AA +102B ; [.2754.0020.0004.102B] # MYANMAR VOWEL SIGN TALL AA +1083 ; [.2755.0020.0002.1083] # MYANMAR VOWEL SIGN SHAN AA +1072 ; [.2756.0020.0002.1072] # MYANMAR VOWEL SIGN KAYAH OE +109C ; [.2757.0020.0002.109C] # MYANMAR VOWEL SIGN AITON A +102D ; [.2758.0020.0002.102D] # MYANMAR VOWEL SIGN I +1071 ; [.2759.0020.0002.1071] # MYANMAR VOWEL SIGN GEBA KAREN I +102E ; [.275A.0020.0002.102E] # MYANMAR VOWEL SIGN II +1033 ; [.275B.0020.0002.1033] # MYANMAR VOWEL SIGN MON II +102F ; [.275C.0020.0002.102F] # MYANMAR VOWEL SIGN U +1073 ; [.275D.0020.0002.1073] # MYANMAR VOWEL SIGN KAYAH U +1074 ; [.275E.0020.0002.1074] # MYANMAR VOWEL SIGN KAYAH EE +1030 ; [.275F.0020.0002.1030] # MYANMAR VOWEL SIGN UU +1056 ; [.2760.0020.0002.1056] # MYANMAR VOWEL SIGN VOCALIC R +1057 ; [.2761.0020.0002.1057] # MYANMAR VOWEL SIGN VOCALIC RR +1058 ; [.2762.0020.0002.1058] # MYANMAR VOWEL SIGN VOCALIC L +1059 ; [.2763.0020.0002.1059] # MYANMAR VOWEL SIGN VOCALIC LL +1031 ; [.2764.0020.0002.1031] # MYANMAR VOWEL SIGN E +1084 ; [.2765.0020.0002.1084] # MYANMAR VOWEL SIGN SHAN E +1035 ; [.2766.0020.0002.1035] # MYANMAR VOWEL SIGN E ABOVE +1085 ; [.2767.0020.0002.1085] # MYANMAR VOWEL SIGN SHAN E ABOVE +1032 ; [.2768.0020.0002.1032] # MYANMAR VOWEL SIGN AI +109D ; [.2769.0020.0002.109D] # MYANMAR VOWEL SIGN AITON AI +1034 ; [.276A.0020.0002.1034] # MYANMAR VOWEL SIGN MON O +1062 ; [.276B.0020.0002.1062] # MYANMAR VOWEL SIGN SGAW KAREN EU +1067 ; [.276C.0020.0002.1067] # MYANMAR VOWEL SIGN WESTERN PWO KAREN EU +1068 ; [.276D.0020.0002.1068] # MYANMAR VOWEL SIGN WESTERN PWO KAREN UE +1086 ; [.276E.0020.0002.1086] # MYANMAR VOWEL SIGN SHAN FINAL Y +1039 ; [.276F.0020.0002.1039] # MYANMAR SIGN VIRAMA +103A ; [.2770.0020.0002.103A] # MYANMAR SIGN ASAT +1063 ; [.2771.0020.0002.1063] # MYANMAR TONE MARK SGAW KAREN HATHI +1064 ; [.2772.0020.0002.1064] # MYANMAR TONE MARK SGAW KAREN KE PHO +1069 ; [.2773.0020.0002.1069] # MYANMAR SIGN WESTERN PWO KAREN TONE-1 +106A ; [.2774.0020.0002.106A] # MYANMAR SIGN WESTERN PWO KAREN TONE-2 +106B ; [.2775.0020.0002.106B] # MYANMAR SIGN WESTERN PWO KAREN TONE-3 +106C ; [.2776.0020.0002.106C] # MYANMAR SIGN WESTERN PWO KAREN TONE-4 +106D ; [.2777.0020.0002.106D] # MYANMAR SIGN WESTERN PWO KAREN TONE-5 +1087 ; [.2778.0020.0002.1087] # MYANMAR SIGN SHAN TONE-2 +108B ; [.2779.0020.0002.108B] # MYANMAR SIGN SHAN COUNCIL TONE-2 +1088 ; [.277A.0020.0002.1088] # MYANMAR SIGN SHAN TONE-3 +108C ; [.277B.0020.0002.108C] # MYANMAR SIGN SHAN COUNCIL TONE-3 +1089 ; [.277C.0020.0002.1089] # MYANMAR SIGN SHAN TONE-5 +108A ; [.277D.0020.0002.108A] # MYANMAR SIGN SHAN TONE-6 +108F ; [.277E.0020.0002.108F] # MYANMAR SIGN RUMAI PALAUNG TONE-5 +109A ; [.277F.0020.0002.109A] # MYANMAR SIGN KHAMTI TONE-1 +109B ; [.2780.0020.0002.109B] # MYANMAR SIGN KHAMTI TONE-3 +AA7B ; [.2781.0020.0002.AA7B] # MYANMAR SIGN PAO KAREN TONE +AA74 ; [.2782.0020.0002.AA74] # MYANMAR LOGOGRAM KHAMTI OAY +AA75 ; [.2783.0020.0002.AA75] # MYANMAR LOGOGRAM KHAMTI QN +AA76 ; [.2784.0020.0002.AA76] # MYANMAR LOGOGRAM KHAMTI HM +11103 ; [.2785.0020.0002.11103] # CHAKMA LETTER AA +11104 ; [.2786.0020.0002.11104] # CHAKMA LETTER I +11105 ; [.2787.0020.0002.11105] # CHAKMA LETTER U +11106 ; [.2788.0020.0002.11106] # CHAKMA LETTER E +11107 ; [.2789.0020.0002.11107] # CHAKMA LETTER KAA +11108 ; [.278A.0020.0002.11108] # CHAKMA LETTER KHAA +11109 ; [.278B.0020.0002.11109] # CHAKMA LETTER GAA +1110A ; [.278C.0020.0002.1110A] # CHAKMA LETTER GHAA +1110B ; [.278D.0020.0002.1110B] # CHAKMA LETTER NGAA +1110C ; [.278E.0020.0002.1110C] # CHAKMA LETTER CAA +1110D ; [.278F.0020.0002.1110D] # CHAKMA LETTER CHAA +1110E ; [.2790.0020.0002.1110E] # CHAKMA LETTER JAA +1110F ; [.2791.0020.0002.1110F] # CHAKMA LETTER JHAA +11110 ; [.2792.0020.0002.11110] # CHAKMA LETTER NYAA +11111 ; [.2793.0020.0002.11111] # CHAKMA LETTER TTAA +11112 ; [.2794.0020.0002.11112] # CHAKMA LETTER TTHAA +11113 ; [.2795.0020.0002.11113] # CHAKMA LETTER DDAA +11114 ; [.2796.0020.0002.11114] # CHAKMA LETTER DDHAA +11115 ; [.2797.0020.0002.11115] # CHAKMA LETTER NNAA +11116 ; [.2798.0020.0002.11116] # CHAKMA LETTER TAA +11117 ; [.2799.0020.0002.11117] # CHAKMA LETTER THAA +11118 ; [.279A.0020.0002.11118] # CHAKMA LETTER DAA +11119 ; [.279B.0020.0002.11119] # CHAKMA LETTER DHAA +1111A ; [.279C.0020.0002.1111A] # CHAKMA LETTER NAA +1111B ; [.279D.0020.0002.1111B] # CHAKMA LETTER PAA +1111C ; [.279E.0020.0002.1111C] # CHAKMA LETTER PHAA +1111D ; [.279F.0020.0002.1111D] # CHAKMA LETTER BAA +1111E ; [.27A0.0020.0002.1111E] # CHAKMA LETTER BHAA +1111F ; [.27A1.0020.0002.1111F] # CHAKMA LETTER MAA +11120 ; [.27A2.0020.0002.11120] # CHAKMA LETTER YYAA +11121 ; [.27A3.0020.0002.11121] # CHAKMA LETTER YAA +11122 ; [.27A4.0020.0002.11122] # CHAKMA LETTER RAA +11123 ; [.27A5.0020.0002.11123] # CHAKMA LETTER LAA +11124 ; [.27A6.0020.0002.11124] # CHAKMA LETTER WAA +11125 ; [.27A7.0020.0002.11125] # CHAKMA LETTER SAA +11126 ; [.27A8.0020.0002.11126] # CHAKMA LETTER HAA +11127 ; [.27A9.0020.0002.11127] # CHAKMA VOWEL SIGN A +11128 ; [.27AA.0020.0002.11128] # CHAKMA VOWEL SIGN I +11129 ; [.27AB.0020.0002.11129] # CHAKMA VOWEL SIGN II +1112A ; [.27AC.0020.0002.1112A] # CHAKMA VOWEL SIGN U +1112B ; [.27AD.0020.0002.1112B] # CHAKMA VOWEL SIGN UU +1112C ; [.27AE.0020.0002.1112C] # CHAKMA VOWEL SIGN E +1112D ; [.27AF.0020.0002.1112D] # CHAKMA VOWEL SIGN AI +1112E ; [.27B0.0020.0002.1112E] # CHAKMA VOWEL SIGN O +11131 11127 ; [.27B0.0020.0002.1112E] # CHAKMA VOWEL SIGN O +1112F ; [.27B1.0020.0002.1112F] # CHAKMA VOWEL SIGN AU +11132 11127 ; [.27B1.0020.0002.1112F] # CHAKMA VOWEL SIGN AU +11130 ; [.27B2.0020.0002.11130] # CHAKMA VOWEL SIGN OI +11131 ; [.27B3.0020.0002.11131] # CHAKMA O MARK +11132 ; [.27B4.0020.0002.11132] # CHAKMA AU MARK +11133 ; [.27B5.0020.0002.11133] # CHAKMA VIRAMA +11134 ; [.27B6.0020.0002.11134] # CHAKMA MAAYYAA +1780 ; [.27B7.0020.0002.1780] # KHMER LETTER KA +1781 ; [.27B8.0020.0002.1781] # KHMER LETTER KHA +1782 ; [.27B9.0020.0002.1782] # KHMER LETTER KO +1783 ; [.27BA.0020.0002.1783] # KHMER LETTER KHO +1784 ; [.27BB.0020.0002.1784] # KHMER LETTER NGO +1785 ; [.27BC.0020.0002.1785] # KHMER LETTER CA +1786 ; [.27BD.0020.0002.1786] # KHMER LETTER CHA +1787 ; [.27BE.0020.0002.1787] # KHMER LETTER CO +1788 ; [.27BF.0020.0002.1788] # KHMER LETTER CHO +1789 ; [.27C0.0020.0002.1789] # KHMER LETTER NYO +178A ; [.27C1.0020.0002.178A] # KHMER LETTER DA +178B ; [.27C2.0020.0002.178B] # KHMER LETTER TTHA +178C ; [.27C3.0020.0002.178C] # KHMER LETTER DO +178D ; [.27C4.0020.0002.178D] # KHMER LETTER TTHO +178E ; [.27C5.0020.0002.178E] # KHMER LETTER NNO +178F ; [.27C6.0020.0002.178F] # KHMER LETTER TA +1790 ; [.27C7.0020.0002.1790] # KHMER LETTER THA +1791 ; [.27C8.0020.0002.1791] # KHMER LETTER TO +1792 ; [.27C9.0020.0002.1792] # KHMER LETTER THO +1793 ; [.27CA.0020.0002.1793] # KHMER LETTER NO +1794 ; [.27CB.0020.0002.1794] # KHMER LETTER BA +1795 ; [.27CC.0020.0002.1795] # KHMER LETTER PHA +1796 ; [.27CD.0020.0002.1796] # KHMER LETTER PO +1797 ; [.27CE.0020.0002.1797] # KHMER LETTER PHO +1798 ; [.27CF.0020.0002.1798] # KHMER LETTER MO +1799 ; [.27D0.0020.0002.1799] # KHMER LETTER YO +179A ; [.27D1.0020.0002.179A] # KHMER LETTER RO +179B ; [.27D2.0020.0002.179B] # KHMER LETTER LO +179C ; [.27D3.0020.0002.179C] # KHMER LETTER VO +179D ; [.27D4.0020.0002.179D] # KHMER LETTER SHA +179E ; [.27D5.0020.0002.179E] # KHMER LETTER SSO +179F ; [.27D6.0020.0002.179F] # KHMER LETTER SA +17A0 ; [.27D7.0020.0002.17A0] # KHMER LETTER HA +17A1 ; [.27D8.0020.0002.17A1] # KHMER LETTER LA +17A2 ; [.27D9.0020.0002.17A2] # KHMER LETTER QA +17DC ; [.27DA.0020.0002.17DC] # KHMER SIGN AVAKRAHASANYA +17A3 ; [.27DB.0020.0002.17A3] # KHMER INDEPENDENT VOWEL QAQ +17A4 ; [.27DC.0020.0002.17A4] # KHMER INDEPENDENT VOWEL QAA +17A5 ; [.27DD.0020.0002.17A5] # KHMER INDEPENDENT VOWEL QI +17A6 ; [.27DE.0020.0002.17A6] # KHMER INDEPENDENT VOWEL QII +17A7 ; [.27DF.0020.0002.17A7] # KHMER INDEPENDENT VOWEL QU +17A8 ; [.27E0.0020.0002.17A8] # KHMER INDEPENDENT VOWEL QUK +17A9 ; [.27E1.0020.0002.17A9] # KHMER INDEPENDENT VOWEL QUU +17AA ; [.27E2.0020.0002.17AA] # KHMER INDEPENDENT VOWEL QUUV +17AB ; [.27E3.0020.0002.17AB] # KHMER INDEPENDENT VOWEL RY +17AC ; [.27E4.0020.0002.17AC] # KHMER INDEPENDENT VOWEL RYY +17AD ; [.27E5.0020.0002.17AD] # KHMER INDEPENDENT VOWEL LY +17AE ; [.27E6.0020.0002.17AE] # KHMER INDEPENDENT VOWEL LYY +17AF ; [.27E7.0020.0002.17AF] # KHMER INDEPENDENT VOWEL QE +17B0 ; [.27E8.0020.0002.17B0] # KHMER INDEPENDENT VOWEL QAI +17B1 ; [.27E9.0020.0002.17B1] # KHMER INDEPENDENT VOWEL QOO TYPE ONE +17B2 ; [.27EA.0020.0002.17B2] # KHMER INDEPENDENT VOWEL QOO TYPE TWO +17B3 ; [.27EB.0020.0002.17B3] # KHMER INDEPENDENT VOWEL QAU +17B6 ; [.27EC.0020.0002.17B6] # KHMER VOWEL SIGN AA +17B7 ; [.27ED.0020.0002.17B7] # KHMER VOWEL SIGN I +17B8 ; [.27EE.0020.0002.17B8] # KHMER VOWEL SIGN II +17B9 ; [.27EF.0020.0002.17B9] # KHMER VOWEL SIGN Y +17BA ; [.27F0.0020.0002.17BA] # KHMER VOWEL SIGN YY +17BB ; [.27F1.0020.0002.17BB] # KHMER VOWEL SIGN U +17BC ; [.27F2.0020.0002.17BC] # KHMER VOWEL SIGN UU +17BD ; [.27F3.0020.0002.17BD] # KHMER VOWEL SIGN UA +17BE ; [.27F4.0020.0002.17BE] # KHMER VOWEL SIGN OE +17BF ; [.27F5.0020.0002.17BF] # KHMER VOWEL SIGN YA +17C0 ; [.27F6.0020.0002.17C0] # KHMER VOWEL SIGN IE +17C1 ; [.27F7.0020.0002.17C1] # KHMER VOWEL SIGN E +17C2 ; [.27F8.0020.0002.17C2] # KHMER VOWEL SIGN AE +17C3 ; [.27F9.0020.0002.17C3] # KHMER VOWEL SIGN AI +17C4 ; [.27FA.0020.0002.17C4] # KHMER VOWEL SIGN OO +17C5 ; [.27FB.0020.0002.17C5] # KHMER VOWEL SIGN AU +17D2 ; [.27FC.0020.0002.17D2] # KHMER SIGN COENG +1950 ; [.27FD.0020.0002.1950] # TAI LE LETTER KA +1951 ; [.27FE.0020.0002.1951] # TAI LE LETTER XA +1952 ; [.27FF.0020.0002.1952] # TAI LE LETTER NGA +1953 ; [.2800.0020.0002.1953] # TAI LE LETTER TSA +1954 ; [.2801.0020.0002.1954] # TAI LE LETTER SA +1955 ; [.2802.0020.0002.1955] # TAI LE LETTER YA +1956 ; [.2803.0020.0002.1956] # TAI LE LETTER TA +1957 ; [.2804.0020.0002.1957] # TAI LE LETTER THA +1958 ; [.2805.0020.0002.1958] # TAI LE LETTER LA +1959 ; [.2806.0020.0002.1959] # TAI LE LETTER PA +195A ; [.2807.0020.0002.195A] # TAI LE LETTER PHA +195B ; [.2808.0020.0002.195B] # TAI LE LETTER MA +195C ; [.2809.0020.0002.195C] # TAI LE LETTER FA +195D ; [.280A.0020.0002.195D] # TAI LE LETTER VA +195E ; [.280B.0020.0002.195E] # TAI LE LETTER HA +195F ; [.280C.0020.0002.195F] # TAI LE LETTER QA +1960 ; [.280D.0020.0002.1960] # TAI LE LETTER KHA +1961 ; [.280E.0020.0002.1961] # TAI LE LETTER TSHA +1962 ; [.280F.0020.0002.1962] # TAI LE LETTER NA +1963 ; [.2810.0020.0002.1963] # TAI LE LETTER A +1964 ; [.2811.0020.0002.1964] # TAI LE LETTER I +1965 ; [.2812.0020.0002.1965] # TAI LE LETTER EE +1966 ; [.2813.0020.0002.1966] # TAI LE LETTER EH +1967 ; [.2814.0020.0002.1967] # TAI LE LETTER U +1968 ; [.2815.0020.0002.1968] # TAI LE LETTER OO +1969 ; [.2816.0020.0002.1969] # TAI LE LETTER O +196A ; [.2817.0020.0002.196A] # TAI LE LETTER UE +196B ; [.2818.0020.0002.196B] # TAI LE LETTER E +196C ; [.2819.0020.0002.196C] # TAI LE LETTER AUE +196D ; [.281A.0020.0002.196D] # TAI LE LETTER AI +1970 ; [.281B.0020.0002.1970] # TAI LE LETTER TONE-2 +1971 ; [.281C.0020.0002.1971] # TAI LE LETTER TONE-3 +1972 ; [.281D.0020.0002.1972] # TAI LE LETTER TONE-4 +1973 ; [.281E.0020.0002.1973] # TAI LE LETTER TONE-5 +1974 ; [.281F.0020.0002.1974] # TAI LE LETTER TONE-6 +1980 ; [.2820.0020.0002.1980] # NEW TAI LUE LETTER HIGH QA +1981 ; [.2821.0020.0002.1981] # NEW TAI LUE LETTER LOW QA +1982 ; [.2822.0020.0002.1982] # NEW TAI LUE LETTER HIGH KA +1983 ; [.2823.0020.0002.1983] # NEW TAI LUE LETTER HIGH XA +1984 ; [.2824.0020.0002.1984] # NEW TAI LUE LETTER HIGH NGA +1985 ; [.2825.0020.0002.1985] # NEW TAI LUE LETTER LOW KA +1986 ; [.2826.0020.0002.1986] # NEW TAI LUE LETTER LOW XA +1987 ; [.2827.0020.0002.1987] # NEW TAI LUE LETTER LOW NGA +1988 ; [.2828.0020.0002.1988] # NEW TAI LUE LETTER HIGH TSA +1989 ; [.2829.0020.0002.1989] # NEW TAI LUE LETTER HIGH SA +198A ; [.282A.0020.0002.198A] # NEW TAI LUE LETTER HIGH YA +198B ; [.282B.0020.0002.198B] # NEW TAI LUE LETTER LOW TSA +198C ; [.282C.0020.0002.198C] # NEW TAI LUE LETTER LOW SA +198D ; [.282D.0020.0002.198D] # NEW TAI LUE LETTER LOW YA +198E ; [.282E.0020.0002.198E] # NEW TAI LUE LETTER HIGH TA +198F ; [.282F.0020.0002.198F] # NEW TAI LUE LETTER HIGH THA +1990 ; [.2830.0020.0002.1990] # NEW TAI LUE LETTER HIGH NA +1991 ; [.2831.0020.0002.1991] # NEW TAI LUE LETTER LOW TA +1992 ; [.2832.0020.0002.1992] # NEW TAI LUE LETTER LOW THA +1993 ; [.2833.0020.0002.1993] # NEW TAI LUE LETTER LOW NA +1994 ; [.2834.0020.0002.1994] # NEW TAI LUE LETTER HIGH PA +1995 ; [.2835.0020.0002.1995] # NEW TAI LUE LETTER HIGH PHA +1996 ; [.2836.0020.0002.1996] # NEW TAI LUE LETTER HIGH MA +1997 ; [.2837.0020.0002.1997] # NEW TAI LUE LETTER LOW PA +1998 ; [.2838.0020.0002.1998] # NEW TAI LUE LETTER LOW PHA +1999 ; [.2839.0020.0002.1999] # NEW TAI LUE LETTER LOW MA +199A ; [.283A.0020.0002.199A] # NEW TAI LUE LETTER HIGH FA +199B ; [.283B.0020.0002.199B] # NEW TAI LUE LETTER HIGH VA +199C ; [.283C.0020.0002.199C] # NEW TAI LUE LETTER HIGH LA +19DE ; [.283C.0020.0004.19DE][.2852.0020.0004.19DE] # NEW TAI LUE SIGN LAE +19DF ; [.283C.0020.0004.19DF][.2852.0020.0004.19DF][.285D.0020.001F.19DF] # NEW TAI LUE SIGN LAEV +199D ; [.283D.0020.0002.199D] # NEW TAI LUE LETTER LOW FA +199E ; [.283E.0020.0002.199E] # NEW TAI LUE LETTER LOW VA +199F ; [.283F.0020.0002.199F] # NEW TAI LUE LETTER LOW LA +19A0 ; [.2840.0020.0002.19A0] # NEW TAI LUE LETTER HIGH HA +19A1 ; [.2841.0020.0002.19A1] # NEW TAI LUE LETTER HIGH DA +19A2 ; [.2842.0020.0002.19A2] # NEW TAI LUE LETTER HIGH BA +19A3 ; [.2843.0020.0002.19A3] # NEW TAI LUE LETTER LOW HA +19A4 ; [.2844.0020.0002.19A4] # NEW TAI LUE LETTER LOW DA +19A5 ; [.2845.0020.0002.19A5] # NEW TAI LUE LETTER LOW BA +19A6 ; [.2846.0020.0002.19A6] # NEW TAI LUE LETTER HIGH KVA +19A7 ; [.2847.0020.0002.19A7] # NEW TAI LUE LETTER HIGH XVA +19A8 ; [.2848.0020.0002.19A8] # NEW TAI LUE LETTER LOW KVA +19A9 ; [.2849.0020.0002.19A9] # NEW TAI LUE LETTER LOW XVA +19AA ; [.284A.0020.0002.19AA] # NEW TAI LUE LETTER HIGH SUA +19AB ; [.284B.0020.0002.19AB] # NEW TAI LUE LETTER LOW SUA +19B0 ; [.284C.0020.0002.19B0] # NEW TAI LUE VOWEL SIGN VOWEL SHORTENER +19B1 ; [.284D.0020.0002.19B1] # NEW TAI LUE VOWEL SIGN AA +19B2 ; [.284E.0020.0002.19B2] # NEW TAI LUE VOWEL SIGN II +19B3 ; [.284F.0020.0002.19B3] # NEW TAI LUE VOWEL SIGN U +19B4 ; [.2850.0020.0002.19B4] # NEW TAI LUE VOWEL SIGN UU +19B5 ; [.2851.0020.0002.19B5] # NEW TAI LUE VOWEL SIGN E +19B6 ; [.2852.0020.0002.19B6] # NEW TAI LUE VOWEL SIGN AE +19B7 ; [.2853.0020.0002.19B7] # NEW TAI LUE VOWEL SIGN O +19B8 ; [.2854.0020.0002.19B8] # NEW TAI LUE VOWEL SIGN OA +19B9 ; [.2855.0020.0002.19B9] # NEW TAI LUE VOWEL SIGN UE +19BA ; [.2856.0020.0002.19BA] # NEW TAI LUE VOWEL SIGN AY +19BB ; [.2857.0020.0002.19BB] # NEW TAI LUE VOWEL SIGN AAY +19BC ; [.2858.0020.0002.19BC] # NEW TAI LUE VOWEL SIGN UY +19BD ; [.2859.0020.0002.19BD] # NEW TAI LUE VOWEL SIGN OY +19BE ; [.285A.0020.0002.19BE] # NEW TAI LUE VOWEL SIGN OAY +19BF ; [.285B.0020.0002.19BF] # NEW TAI LUE VOWEL SIGN UEY +19C0 ; [.285C.0020.0002.19C0] # NEW TAI LUE VOWEL SIGN IY +19C1 ; [.285D.0020.0002.19C1] # NEW TAI LUE LETTER FINAL V +19C2 ; [.285E.0020.0002.19C2] # NEW TAI LUE LETTER FINAL NG +19C3 ; [.285F.0020.0002.19C3] # NEW TAI LUE LETTER FINAL N +19C4 ; [.2860.0020.0002.19C4] # NEW TAI LUE LETTER FINAL M +19C5 ; [.2861.0020.0002.19C5] # NEW TAI LUE LETTER FINAL K +19C6 ; [.2862.0020.0002.19C6] # NEW TAI LUE LETTER FINAL D +19C7 ; [.2863.0020.0002.19C7] # NEW TAI LUE LETTER FINAL B +19C8 ; [.2864.0020.0002.19C8] # NEW TAI LUE TONE MARK-1 +19C9 ; [.2865.0020.0002.19C9] # NEW TAI LUE TONE MARK-2 +1A20 ; [.2866.0020.0002.1A20] # TAI THAM LETTER HIGH KA +1A21 ; [.2867.0020.0002.1A21] # TAI THAM LETTER HIGH KHA +1A22 ; [.2868.0020.0002.1A22] # TAI THAM LETTER HIGH KXA +1A23 ; [.2869.0020.0002.1A23] # TAI THAM LETTER LOW KA +1A24 ; [.286A.0020.0002.1A24] # TAI THAM LETTER LOW KXA +1A25 ; [.286B.0020.0002.1A25] # TAI THAM LETTER LOW KHA +1A26 ; [.286C.0020.0002.1A26] # TAI THAM LETTER NGA +1A58 ; [.286C.0020.0004.1A58] # TAI THAM SIGN MAI KANG LAI +1A59 ; [.286C.0020.0004.1A59] # TAI THAM CONSONANT SIGN FINAL NGA +1A27 ; [.286D.0020.0002.1A27] # TAI THAM LETTER HIGH CA +1A28 ; [.286E.0020.0002.1A28] # TAI THAM LETTER HIGH CHA +1A29 ; [.286F.0020.0002.1A29] # TAI THAM LETTER LOW CA +1A2A ; [.2870.0020.0002.1A2A] # TAI THAM LETTER LOW SA +1A2B ; [.2871.0020.0002.1A2B] # TAI THAM LETTER LOW CHA +1A2C ; [.2872.0020.0002.1A2C] # TAI THAM LETTER NYA +1A2D ; [.2873.0020.0002.1A2D] # TAI THAM LETTER RATA +1A2E ; [.2874.0020.0002.1A2E] # TAI THAM LETTER HIGH RATHA +1A2F ; [.2875.0020.0002.1A2F] # TAI THAM LETTER DA +1A30 ; [.2876.0020.0002.1A30] # TAI THAM LETTER LOW RATHA +1A31 ; [.2877.0020.0002.1A31] # TAI THAM LETTER RANA +1A32 ; [.2878.0020.0002.1A32] # TAI THAM LETTER HIGH TA +1A33 ; [.2879.0020.0002.1A33] # TAI THAM LETTER HIGH THA +1A34 ; [.287A.0020.0002.1A34] # TAI THAM LETTER LOW TA +1A35 ; [.287B.0020.0002.1A35] # TAI THAM LETTER LOW THA +1A36 ; [.287C.0020.0002.1A36] # TAI THAM LETTER NA +1A37 ; [.287D.0020.0002.1A37] # TAI THAM LETTER BA +1A38 ; [.287E.0020.0002.1A38] # TAI THAM LETTER HIGH PA +1A39 ; [.287F.0020.0002.1A39] # TAI THAM LETTER HIGH PHA +1A3A ; [.2880.0020.0002.1A3A] # TAI THAM LETTER HIGH FA +1A3B ; [.2881.0020.0002.1A3B] # TAI THAM LETTER LOW PA +1A5A ; [.2881.0020.0004.1A5A] # TAI THAM CONSONANT SIGN LOW PA +1A5B ; [.2881.0020.0004.1A5B] # TAI THAM CONSONANT SIGN HIGH RATHA OR LOW PA +1A3C ; [.2882.0020.0002.1A3C] # TAI THAM LETTER LOW FA +1A3D ; [.2883.0020.0002.1A3D] # TAI THAM LETTER LOW PHA +1A3E ; [.2884.0020.0002.1A3E] # TAI THAM LETTER MA +1A3F ; [.2885.0020.0002.1A3F] # TAI THAM LETTER LOW YA +1A40 ; [.2886.0020.0002.1A40] # TAI THAM LETTER HIGH YA +1A41 ; [.2887.0020.0002.1A41] # TAI THAM LETTER RA +1A42 ; [.2888.0020.0002.1A42] # TAI THAM LETTER RUE +1A43 ; [.2889.0020.0002.1A43] # TAI THAM LETTER LA +1A44 ; [.288A.0020.0002.1A44] # TAI THAM LETTER LUE +1A45 ; [.288B.0020.0002.1A45] # TAI THAM LETTER WA +1A46 ; [.288C.0020.0002.1A46] # TAI THAM LETTER HIGH SHA +1A54 ; [.288C.0020.0004.1A54][.28B2.0020.0004.1A54][.288C.0020.001F.1A54] # TAI THAM LETTER GREAT SA +1A47 ; [.288D.0020.0002.1A47] # TAI THAM LETTER HIGH SSA +1A48 ; [.288E.0020.0002.1A48] # TAI THAM LETTER HIGH SA +1A49 ; [.288F.0020.0002.1A49] # TAI THAM LETTER HIGH HA +1A4A ; [.2890.0020.0002.1A4A] # TAI THAM LETTER LLA +1A4B ; [.2891.0020.0002.1A4B] # TAI THAM LETTER A +1A4C ; [.2892.0020.0002.1A4C] # TAI THAM LETTER LOW HA +1A53 ; [.2893.0020.0002.1A53] # TAI THAM LETTER LAE +1A6B ; [.2894.0020.0002.1A6B] # TAI THAM VOWEL SIGN O +1A55 ; [.2895.0020.0002.1A55] # TAI THAM CONSONANT SIGN MEDIAL RA +1A56 ; [.2896.0020.0002.1A56] # TAI THAM CONSONANT SIGN MEDIAL LA +1A57 ; [.2897.0020.0002.1A57] # TAI THAM CONSONANT SIGN LA TANG LAI +1A5C ; [.2898.0020.0002.1A5C] # TAI THAM CONSONANT SIGN MA +1A5D ; [.2899.0020.0002.1A5D] # TAI THAM CONSONANT SIGN BA +1A5E ; [.289A.0020.0002.1A5E] # TAI THAM CONSONANT SIGN SA +1A4D ; [.289B.0020.0002.1A4D] # TAI THAM LETTER I +1A4E ; [.289C.0020.0002.1A4E] # TAI THAM LETTER II +1A4F ; [.289D.0020.0002.1A4F] # TAI THAM LETTER U +1A50 ; [.289E.0020.0002.1A50] # TAI THAM LETTER UU +1A51 ; [.289F.0020.0002.1A51] # TAI THAM LETTER EE +1A52 ; [.28A0.0020.0002.1A52] # TAI THAM LETTER OO +1A61 ; [.28A1.0020.0002.1A61] # TAI THAM VOWEL SIGN A +1A6C ; [.28A2.0020.0002.1A6C] # TAI THAM VOWEL SIGN OA BELOW +1A62 ; [.28A3.0020.0002.1A62] # TAI THAM VOWEL SIGN MAI SAT +1A63 ; [.28A4.0020.0002.1A63] # TAI THAM VOWEL SIGN AA +1A64 ; [.28A4.0020.0004.1A64] # TAI THAM VOWEL SIGN TALL AA +1A65 ; [.28A5.0020.0002.1A65] # TAI THAM VOWEL SIGN I +1A66 ; [.28A6.0020.0002.1A66] # TAI THAM VOWEL SIGN II +1A67 ; [.28A7.0020.0002.1A67] # TAI THAM VOWEL SIGN UE +1A68 ; [.28A8.0020.0002.1A68] # TAI THAM VOWEL SIGN UUE +1A69 ; [.28A9.0020.0002.1A69] # TAI THAM VOWEL SIGN U +1A6A ; [.28AA.0020.0002.1A6A] # TAI THAM VOWEL SIGN UU +1A6E ; [.28AB.0020.0002.1A6E] # TAI THAM VOWEL SIGN E +1A6F ; [.28AC.0020.0002.1A6F] # TAI THAM VOWEL SIGN AE +1A73 ; [.28AD.0020.0002.1A73] # TAI THAM VOWEL SIGN OA ABOVE +1A70 ; [.28AE.0020.0002.1A70] # TAI THAM VOWEL SIGN OO +1A71 ; [.28AF.0020.0002.1A71] # TAI THAM VOWEL SIGN AI +1A72 ; [.28B0.0020.0002.1A72] # TAI THAM VOWEL SIGN THAM AI +1A6D ; [.28B1.0020.0002.1A6D] # TAI THAM VOWEL SIGN OY +1A60 ; [.28B2.0020.0002.1A60] # TAI THAM SIGN SAKOT +AA00 ; [.28B3.0020.0002.AA00] # CHAM LETTER A +AA01 ; [.28B4.0020.0002.AA01] # CHAM LETTER I +AA02 ; [.28B5.0020.0002.AA02] # CHAM LETTER U +AA03 ; [.28B6.0020.0002.AA03] # CHAM LETTER E +AA04 ; [.28B7.0020.0002.AA04] # CHAM LETTER AI +AA05 ; [.28B8.0020.0002.AA05] # CHAM LETTER O +AA06 ; [.28B9.0020.0002.AA06] # CHAM LETTER KA +AA07 ; [.28BA.0020.0002.AA07] # CHAM LETTER KHA +AA08 ; [.28BB.0020.0002.AA08] # CHAM LETTER GA +AA09 ; [.28BC.0020.0002.AA09] # CHAM LETTER GHA +AA0A ; [.28BD.0020.0002.AA0A] # CHAM LETTER NGUE +AA0B ; [.28BE.0020.0002.AA0B] # CHAM LETTER NGA +AA0C ; [.28BF.0020.0002.AA0C] # CHAM LETTER CHA +AA0D ; [.28C0.0020.0002.AA0D] # CHAM LETTER CHHA +AA0E ; [.28C1.0020.0002.AA0E] # CHAM LETTER JA +AA0F ; [.28C2.0020.0002.AA0F] # CHAM LETTER JHA +AA10 ; [.28C3.0020.0002.AA10] # CHAM LETTER NHUE +AA11 ; [.28C4.0020.0002.AA11] # CHAM LETTER NHA +AA12 ; [.28C5.0020.0002.AA12] # CHAM LETTER NHJA +AA13 ; [.28C6.0020.0002.AA13] # CHAM LETTER TA +AA14 ; [.28C7.0020.0002.AA14] # CHAM LETTER THA +AA15 ; [.28C8.0020.0002.AA15] # CHAM LETTER DA +AA16 ; [.28C9.0020.0002.AA16] # CHAM LETTER DHA +AA17 ; [.28CA.0020.0002.AA17] # CHAM LETTER NUE +AA18 ; [.28CB.0020.0002.AA18] # CHAM LETTER NA +AA19 ; [.28CC.0020.0002.AA19] # CHAM LETTER DDA +AA1A ; [.28CD.0020.0002.AA1A] # CHAM LETTER PA +AA1B ; [.28CE.0020.0002.AA1B] # CHAM LETTER PPA +AA1C ; [.28CF.0020.0002.AA1C] # CHAM LETTER PHA +AA1D ; [.28D0.0020.0002.AA1D] # CHAM LETTER BA +AA1E ; [.28D1.0020.0002.AA1E] # CHAM LETTER BHA +AA1F ; [.28D2.0020.0002.AA1F] # CHAM LETTER MUE +AA20 ; [.28D3.0020.0002.AA20] # CHAM LETTER MA +AA21 ; [.28D4.0020.0002.AA21] # CHAM LETTER BBA +AA22 ; [.28D5.0020.0002.AA22] # CHAM LETTER YA +AA23 ; [.28D6.0020.0002.AA23] # CHAM LETTER RA +AA24 ; [.28D7.0020.0002.AA24] # CHAM LETTER LA +AA25 ; [.28D8.0020.0002.AA25] # CHAM LETTER VA +AA26 ; [.28D9.0020.0002.AA26] # CHAM LETTER SSA +AA27 ; [.28DA.0020.0002.AA27] # CHAM LETTER SA +AA28 ; [.28DB.0020.0002.AA28] # CHAM LETTER HA +AA33 ; [.28DC.0020.0002.AA33] # CHAM CONSONANT SIGN YA +AA34 ; [.28DD.0020.0002.AA34] # CHAM CONSONANT SIGN RA +AA35 ; [.28DE.0020.0002.AA35] # CHAM CONSONANT SIGN LA +AA36 ; [.28DF.0020.0002.AA36] # CHAM CONSONANT SIGN WA +AA29 ; [.28E0.0020.0002.AA29] # CHAM VOWEL SIGN AA +AA2A ; [.28E1.0020.0002.AA2A] # CHAM VOWEL SIGN I +AA2B ; [.28E2.0020.0002.AA2B] # CHAM VOWEL SIGN II +AA2C ; [.28E3.0020.0002.AA2C] # CHAM VOWEL SIGN EI +AA2D ; [.28E4.0020.0002.AA2D] # CHAM VOWEL SIGN U +AA2E ; [.28E5.0020.0002.AA2E] # CHAM VOWEL SIGN OE +AA2F ; [.28E6.0020.0002.AA2F] # CHAM VOWEL SIGN O +AA30 ; [.28E7.0020.0002.AA30] # CHAM VOWEL SIGN AI +AA31 ; [.28E8.0020.0002.AA31] # CHAM VOWEL SIGN AU +AA32 ; [.28E9.0020.0002.AA32] # CHAM VOWEL SIGN UE +AA40 ; [.28EA.0020.0002.AA40] # CHAM LETTER FINAL K +AA41 ; [.28EB.0020.0002.AA41] # CHAM LETTER FINAL G +AA42 ; [.28EC.0020.0002.AA42] # CHAM LETTER FINAL NG +AA43 ; [.28ED.0020.0002.AA43] # CHAM CONSONANT SIGN FINAL NG +AA44 ; [.28EE.0020.0002.AA44] # CHAM LETTER FINAL CH +AA45 ; [.28EF.0020.0002.AA45] # CHAM LETTER FINAL T +AA46 ; [.28F0.0020.0002.AA46] # CHAM LETTER FINAL N +AA47 ; [.28F1.0020.0002.AA47] # CHAM LETTER FINAL P +AA48 ; [.28F2.0020.0002.AA48] # CHAM LETTER FINAL Y +AA49 ; [.28F3.0020.0002.AA49] # CHAM LETTER FINAL R +AA4A ; [.28F4.0020.0002.AA4A] # CHAM LETTER FINAL L +AA4B ; [.28F5.0020.0002.AA4B] # CHAM LETTER FINAL SS +AA4C ; [.28F6.0020.0002.AA4C] # CHAM CONSONANT SIGN FINAL M +AA4D ; [.28F7.0020.0002.AA4D] # CHAM CONSONANT SIGN FINAL H +1B05 ; [.28F8.0020.0002.1B05] # BALINESE LETTER AKARA +1B06 ; [.28F9.0020.0002.1B06] # BALINESE LETTER AKARA TEDUNG +1B05 1B35 ; [.28F9.0020.0002.1B06] # BALINESE LETTER AKARA TEDUNG +1B07 ; [.28FA.0020.0002.1B07] # BALINESE LETTER IKARA +1B08 ; [.28FB.0020.0002.1B08] # BALINESE LETTER IKARA TEDUNG +1B07 1B35 ; [.28FB.0020.0002.1B08] # BALINESE LETTER IKARA TEDUNG +1B09 ; [.28FC.0020.0002.1B09] # BALINESE LETTER UKARA +1B0A ; [.28FD.0020.0002.1B0A] # BALINESE LETTER UKARA TEDUNG +1B09 1B35 ; [.28FD.0020.0002.1B0A] # BALINESE LETTER UKARA TEDUNG +1B0B ; [.28FE.0020.0002.1B0B] # BALINESE LETTER RA REPA +1B0C ; [.28FF.0020.0002.1B0C] # BALINESE LETTER RA REPA TEDUNG +1B0B 1B35 ; [.28FF.0020.0002.1B0C] # BALINESE LETTER RA REPA TEDUNG +1B0D ; [.2900.0020.0002.1B0D] # BALINESE LETTER LA LENGA +1B0E ; [.2901.0020.0002.1B0E] # BALINESE LETTER LA LENGA TEDUNG +1B0D 1B35 ; [.2901.0020.0002.1B0E] # BALINESE LETTER LA LENGA TEDUNG +1B0F ; [.2902.0020.0002.1B0F] # BALINESE LETTER EKARA +1B10 ; [.2903.0020.0002.1B10] # BALINESE LETTER AIKARA +1B11 ; [.2904.0020.0002.1B11] # BALINESE LETTER OKARA +1B12 ; [.2905.0020.0002.1B12] # BALINESE LETTER OKARA TEDUNG +1B11 1B35 ; [.2905.0020.0002.1B12] # BALINESE LETTER OKARA TEDUNG +1B13 ; [.2906.0020.0002.1B13] # BALINESE LETTER KA +1B45 ; [.2907.0020.0002.1B45] # BALINESE LETTER KAF SASAK +1B46 ; [.2908.0020.0002.1B46] # BALINESE LETTER KHOT SASAK +1B14 ; [.2909.0020.0002.1B14] # BALINESE LETTER KA MAHAPRANA +1B15 ; [.290A.0020.0002.1B15] # BALINESE LETTER GA +1B16 ; [.290B.0020.0002.1B16] # BALINESE LETTER GA GORA +1B17 ; [.290C.0020.0002.1B17] # BALINESE LETTER NGA +1B18 ; [.290D.0020.0002.1B18] # BALINESE LETTER CA +1B19 ; [.290E.0020.0002.1B19] # BALINESE LETTER CA LACA +1B1A ; [.290F.0020.0002.1B1A] # BALINESE LETTER JA +1B1B ; [.2910.0020.0002.1B1B] # BALINESE LETTER JA JERA +1B1C ; [.2911.0020.0002.1B1C] # BALINESE LETTER NYA +1B1D ; [.2912.0020.0002.1B1D] # BALINESE LETTER TA LATIK +1B1E ; [.2913.0020.0002.1B1E] # BALINESE LETTER TA MURDA MAHAPRANA +1B1F ; [.2914.0020.0002.1B1F] # BALINESE LETTER DA MURDA ALPAPRANA +1B20 ; [.2915.0020.0002.1B20] # BALINESE LETTER DA MURDA MAHAPRANA +1B21 ; [.2916.0020.0002.1B21] # BALINESE LETTER NA RAMBAT +1B22 ; [.2917.0020.0002.1B22] # BALINESE LETTER TA +1B47 ; [.2918.0020.0002.1B47] # BALINESE LETTER TZIR SASAK +1B23 ; [.2919.0020.0002.1B23] # BALINESE LETTER TA TAWA +1B24 ; [.291A.0020.0002.1B24] # BALINESE LETTER DA +1B25 ; [.291B.0020.0002.1B25] # BALINESE LETTER DA MADU +1B26 ; [.291C.0020.0002.1B26] # BALINESE LETTER NA +1B27 ; [.291D.0020.0002.1B27] # BALINESE LETTER PA +1B48 ; [.291E.0020.0002.1B48] # BALINESE LETTER EF SASAK +1B28 ; [.291F.0020.0002.1B28] # BALINESE LETTER PA KAPAL +1B29 ; [.2920.0020.0002.1B29] # BALINESE LETTER BA +1B2A ; [.2921.0020.0002.1B2A] # BALINESE LETTER BA KEMBANG +1B2B ; [.2922.0020.0002.1B2B] # BALINESE LETTER MA +1B2C ; [.2923.0020.0002.1B2C] # BALINESE LETTER YA +1B2D ; [.2924.0020.0002.1B2D] # BALINESE LETTER RA +1B2E ; [.2925.0020.0002.1B2E] # BALINESE LETTER LA +1B2F ; [.2926.0020.0002.1B2F] # BALINESE LETTER WA +1B49 ; [.2927.0020.0002.1B49] # BALINESE LETTER VE SASAK +1B30 ; [.2928.0020.0002.1B30] # BALINESE LETTER SA SAGA +1B31 ; [.2929.0020.0002.1B31] # BALINESE LETTER SA SAPA +1B32 ; [.292A.0020.0002.1B32] # BALINESE LETTER SA +1B4A ; [.292B.0020.0002.1B4A] # BALINESE LETTER ZAL SASAK +1B4B ; [.292C.0020.0002.1B4B] # BALINESE LETTER ASYURA SASAK +1B33 ; [.292D.0020.0002.1B33] # BALINESE LETTER HA +1B35 ; [.292E.0020.0002.1B35] # BALINESE VOWEL SIGN TEDUNG +1B36 ; [.292F.0020.0002.1B36] # BALINESE VOWEL SIGN ULU +1B37 ; [.2930.0020.0002.1B37] # BALINESE VOWEL SIGN ULU SARI +1B38 ; [.2931.0020.0002.1B38] # BALINESE VOWEL SIGN SUKU +1B39 ; [.2932.0020.0002.1B39] # BALINESE VOWEL SIGN SUKU ILUT +1B3A ; [.2933.0020.0002.1B3A] # BALINESE VOWEL SIGN RA REPA +1B3B ; [.2934.0020.0002.1B3B] # BALINESE VOWEL SIGN RA REPA TEDUNG +1B3A 1B35 ; [.2934.0020.0002.1B3B] # BALINESE VOWEL SIGN RA REPA TEDUNG +1B3C ; [.2935.0020.0002.1B3C] # BALINESE VOWEL SIGN LA LENGA +1B3D ; [.2936.0020.0002.1B3D] # BALINESE VOWEL SIGN LA LENGA TEDUNG +1B3C 1B35 ; [.2936.0020.0002.1B3D] # BALINESE VOWEL SIGN LA LENGA TEDUNG +1B3E ; [.2937.0020.0002.1B3E] # BALINESE VOWEL SIGN TALING +1B3F ; [.2938.0020.0002.1B3F] # BALINESE VOWEL SIGN TALING REPA +1B40 ; [.2939.0020.0002.1B40] # BALINESE VOWEL SIGN TALING TEDUNG +1B3E 1B35 ; [.2939.0020.0002.1B40] # BALINESE VOWEL SIGN TALING TEDUNG +1B41 ; [.293A.0020.0002.1B41] # BALINESE VOWEL SIGN TALING REPA TEDUNG +1B3F 1B35 ; [.293A.0020.0002.1B41] # BALINESE VOWEL SIGN TALING REPA TEDUNG +1B42 ; [.293B.0020.0002.1B42] # BALINESE VOWEL SIGN PEPET +1B43 ; [.293C.0020.0002.1B43] # BALINESE VOWEL SIGN PEPET TEDUNG +1B42 1B35 ; [.293C.0020.0002.1B43] # BALINESE VOWEL SIGN PEPET TEDUNG +1B44 ; [.293D.0020.0002.1B44] # BALINESE ADEG ADEG +A984 ; [.293E.0020.0002.A984] # JAVANESE LETTER A +A985 ; [.293F.0020.0002.A985] # JAVANESE LETTER I KAWI +A986 ; [.2940.0020.0002.A986] # JAVANESE LETTER I +A987 ; [.2941.0020.0002.A987] # JAVANESE LETTER II +A988 ; [.2942.0020.0002.A988] # JAVANESE LETTER U +A989 ; [.2943.0020.0002.A989] # JAVANESE LETTER PA CEREK +A98A ; [.2944.0020.0002.A98A] # JAVANESE LETTER NGA LELET +A98B ; [.2945.0020.0002.A98B] # JAVANESE LETTER NGA LELET RASWADI +A98C ; [.2946.0020.0002.A98C] # JAVANESE LETTER E +A98D ; [.2947.0020.0002.A98D] # JAVANESE LETTER AI +A98E ; [.2948.0020.0002.A98E] # JAVANESE LETTER O +A98F ; [.2949.0020.0002.A98F] # JAVANESE LETTER KA +A990 ; [.294A.0020.0002.A990] # JAVANESE LETTER KA SASAK +A991 ; [.294B.0020.0002.A991] # JAVANESE LETTER KA MURDA +A992 ; [.294C.0020.0002.A992] # JAVANESE LETTER GA +A993 ; [.294D.0020.0002.A993] # JAVANESE LETTER GA MURDA +A994 ; [.294E.0020.0002.A994] # JAVANESE LETTER NGA +A995 ; [.294F.0020.0002.A995] # JAVANESE LETTER CA +A996 ; [.2950.0020.0002.A996] # JAVANESE LETTER CA MURDA +A997 ; [.2951.0020.0002.A997] # JAVANESE LETTER JA +A998 ; [.2952.0020.0002.A998] # JAVANESE LETTER NYA MURDA +A999 ; [.2953.0020.0002.A999] # JAVANESE LETTER JA MAHAPRANA +A99A ; [.2954.0020.0002.A99A] # JAVANESE LETTER NYA +A99B ; [.2955.0020.0002.A99B] # JAVANESE LETTER TTA +A99C ; [.2956.0020.0002.A99C] # JAVANESE LETTER TTA MAHAPRANA +A99D ; [.2957.0020.0002.A99D] # JAVANESE LETTER DDA +A99E ; [.2958.0020.0002.A99E] # JAVANESE LETTER DDA MAHAPRANA +A99F ; [.2959.0020.0002.A99F] # JAVANESE LETTER NA MURDA +A9A0 ; [.295A.0020.0002.A9A0] # JAVANESE LETTER TA +A9A1 ; [.295B.0020.0002.A9A1] # JAVANESE LETTER TA MURDA +A9A2 ; [.295C.0020.0002.A9A2] # JAVANESE LETTER DA +A9A3 ; [.295D.0020.0002.A9A3] # JAVANESE LETTER DA MAHAPRANA +A9A4 ; [.295E.0020.0002.A9A4] # JAVANESE LETTER NA +A9A5 ; [.295F.0020.0002.A9A5] # JAVANESE LETTER PA +A9A6 ; [.2960.0020.0002.A9A6] # JAVANESE LETTER PA MURDA +A9A7 ; [.2961.0020.0002.A9A7] # JAVANESE LETTER BA +A9A8 ; [.2962.0020.0002.A9A8] # JAVANESE LETTER BA MURDA +A9A9 ; [.2963.0020.0002.A9A9] # JAVANESE LETTER MA +A9AA ; [.2964.0020.0002.A9AA] # JAVANESE LETTER YA +A9BE ; [.2965.0020.0002.A9BE] # JAVANESE CONSONANT SIGN PENGKAL +A9AB ; [.2966.0020.0002.A9AB] # JAVANESE LETTER RA +A9AC ; [.2966.0020.0004.A9AC] # JAVANESE LETTER RA AGUNG +A9BF ; [.2967.0020.0002.A9BF] # JAVANESE CONSONANT SIGN CAKRA +A9AD ; [.2968.0020.0002.A9AD] # JAVANESE LETTER LA +A9AE ; [.2969.0020.0002.A9AE] # JAVANESE LETTER WA +A9AF ; [.296A.0020.0002.A9AF] # JAVANESE LETTER SA MURDA +A9B0 ; [.296B.0020.0002.A9B0] # JAVANESE LETTER SA MAHAPRANA +A9B1 ; [.296C.0020.0002.A9B1] # JAVANESE LETTER SA +A9B2 ; [.296D.0020.0002.A9B2] # JAVANESE LETTER HA +A9B4 ; [.296E.0020.0002.A9B4] # JAVANESE VOWEL SIGN TARUNG +A9BC ; [.296F.0020.0002.A9BC] # JAVANESE VOWEL SIGN PEPET +A9B6 ; [.2970.0020.0002.A9B6] # JAVANESE VOWEL SIGN WULU +A9B7 ; [.2971.0020.0002.A9B7] # JAVANESE VOWEL SIGN WULU MELIK +A9B8 ; [.2972.0020.0002.A9B8] # JAVANESE VOWEL SIGN SUKU +A9B9 ; [.2973.0020.0002.A9B9] # JAVANESE VOWEL SIGN SUKU MENDUT +A9BD ; [.2974.0020.0002.A9BD] # JAVANESE CONSONANT SIGN KERET +A9BA ; [.2975.0020.0002.A9BA] # JAVANESE VOWEL SIGN TALING +A9BB ; [.2976.0020.0002.A9BB] # JAVANESE VOWEL SIGN DIRGA MURE +A9B5 ; [.2977.0020.0002.A9B5] # JAVANESE VOWEL SIGN TOLONG +A9C0 ; [.2978.0020.0002.A9C0] # JAVANESE PANGKON +1880 ; [.2979.0020.0002.1880] # MONGOLIAN LETTER ALI GALI ANUSVARA ONE +1881 ; [.297A.0020.0002.1881] # MONGOLIAN LETTER ALI GALI VISARGA ONE +1882 ; [.297B.0020.0002.1882] # MONGOLIAN LETTER ALI GALI DAMARU +1883 ; [.297C.0020.0002.1883] # MONGOLIAN LETTER ALI GALI UBADAMA +1884 ; [.297D.0020.0002.1884] # MONGOLIAN LETTER ALI GALI INVERTED UBADAMA +1885 ; [.297E.0020.0002.1885] # MONGOLIAN LETTER ALI GALI BALUDA +1886 ; [.297F.0020.0002.1886] # MONGOLIAN LETTER ALI GALI THREE BALUDA +1843 ; [.2980.0020.0002.1843] # MONGOLIAN LETTER TODO LONG VOWEL SIGN +1820 ; [.2981.0020.0002.1820] # MONGOLIAN LETTER A +1887 ; [.2982.0020.0002.1887] # MONGOLIAN LETTER ALI GALI A +1821 ; [.2983.0020.0002.1821] # MONGOLIAN LETTER E +1844 ; [.2984.0020.0002.1844] # MONGOLIAN LETTER TODO E +185D ; [.2985.0020.0002.185D] # MONGOLIAN LETTER SIBE E +1822 ; [.2986.0020.0002.1822] # MONGOLIAN LETTER I +1845 ; [.2987.0020.0002.1845] # MONGOLIAN LETTER TODO I +185E ; [.2988.0020.0002.185E] # MONGOLIAN LETTER SIBE I +1873 ; [.2989.0020.0002.1873] # MONGOLIAN LETTER MANCHU I +1888 ; [.298A.0020.0002.1888] # MONGOLIAN LETTER ALI GALI I +185F ; [.298B.0020.0002.185F] # MONGOLIAN LETTER SIBE IY +1823 ; [.298C.0020.0002.1823] # MONGOLIAN LETTER O +1846 ; [.298D.0020.0002.1846] # MONGOLIAN LETTER TODO O +1824 ; [.298E.0020.0002.1824] # MONGOLIAN LETTER U +1847 ; [.298F.0020.0002.1847] # MONGOLIAN LETTER TODO U +1861 ; [.2990.0020.0002.1861] # MONGOLIAN LETTER SIBE U +1825 ; [.2991.0020.0002.1825] # MONGOLIAN LETTER OE +1848 ; [.2992.0020.0002.1848] # MONGOLIAN LETTER TODO OE +1826 ; [.2993.0020.0002.1826] # MONGOLIAN LETTER UE +1849 ; [.2994.0020.0002.1849] # MONGOLIAN LETTER TODO UE +1860 ; [.2995.0020.0002.1860] # MONGOLIAN LETTER SIBE UE +1827 ; [.2996.0020.0002.1827] # MONGOLIAN LETTER EE +1828 ; [.2997.0020.0002.1828] # MONGOLIAN LETTER NA +1829 ; [.2998.0020.0002.1829] # MONGOLIAN LETTER ANG +184A ; [.2999.0020.0002.184A] # MONGOLIAN LETTER TODO ANG +1862 ; [.299A.0020.0002.1862] # MONGOLIAN LETTER SIBE ANG +188A ; [.299B.0020.0002.188A] # MONGOLIAN LETTER ALI GALI NGA +189B ; [.299C.0020.0002.189B] # MONGOLIAN LETTER MANCHU ALI GALI NGA +182A ; [.299D.0020.0002.182A] # MONGOLIAN LETTER BA +184B ; [.299E.0020.0002.184B] # MONGOLIAN LETTER TODO BA +182B ; [.299F.0020.0002.182B] # MONGOLIAN LETTER PA +184C ; [.29A0.0020.0002.184C] # MONGOLIAN LETTER TODO PA +1866 ; [.29A1.0020.0002.1866] # MONGOLIAN LETTER SIBE PA +182C ; [.29A2.0020.0002.182C] # MONGOLIAN LETTER QA +184D ; [.29A3.0020.0002.184D] # MONGOLIAN LETTER TODO QA +182D ; [.29A4.0020.0002.182D] # MONGOLIAN LETTER GA +184E ; [.29A5.0020.0002.184E] # MONGOLIAN LETTER TODO GA +1864 ; [.29A6.0020.0002.1864] # MONGOLIAN LETTER SIBE GA +189A ; [.29A7.0020.0002.189A] # MONGOLIAN LETTER MANCHU ALI GALI GHA +1865 ; [.29A8.0020.0002.1865] # MONGOLIAN LETTER SIBE HA +182E ; [.29A9.0020.0002.182E] # MONGOLIAN LETTER MA +184F ; [.29AA.0020.0002.184F] # MONGOLIAN LETTER TODO MA +182F ; [.29AB.0020.0002.182F] # MONGOLIAN LETTER LA +1830 ; [.29AC.0020.0002.1830] # MONGOLIAN LETTER SA +1831 ; [.29AD.0020.0002.1831] # MONGOLIAN LETTER SHA +1867 ; [.29AE.0020.0002.1867] # MONGOLIAN LETTER SIBE SHA +189C ; [.29AF.0020.0002.189C] # MONGOLIAN LETTER MANCHU ALI GALI CA +189D ; [.29B0.0020.0002.189D] # MONGOLIAN LETTER MANCHU ALI GALI JHA +18A2 ; [.29B1.0020.0002.18A2] # MONGOLIAN LETTER MANCHU ALI GALI SSA +18A4 ; [.29B2.0020.0002.18A4] # MONGOLIAN LETTER MANCHU ALI GALI ZHA +18A5 ; [.29B3.0020.0002.18A5] # MONGOLIAN LETTER MANCHU ALI GALI ZA +1832 ; [.29B4.0020.0002.1832] # MONGOLIAN LETTER TA +1850 ; [.29B5.0020.0002.1850] # MONGOLIAN LETTER TODO TA +1868 ; [.29B6.0020.0002.1868] # MONGOLIAN LETTER SIBE TA +1833 ; [.29B7.0020.0002.1833] # MONGOLIAN LETTER DA +1851 ; [.29B8.0020.0002.1851] # MONGOLIAN LETTER TODO DA +1869 ; [.29B9.0020.0002.1869] # MONGOLIAN LETTER SIBE DA +1834 ; [.29BA.0020.0002.1834] # MONGOLIAN LETTER CHA +1852 ; [.29BB.0020.0002.1852] # MONGOLIAN LETTER TODO CHA +1871 ; [.29BC.0020.0002.1871] # MONGOLIAN LETTER SIBE CHA +185C ; [.29BD.0020.0002.185C] # MONGOLIAN LETTER TODO DZA +188B ; [.29BE.0020.0002.188B] # MONGOLIAN LETTER ALI GALI CA +1835 ; [.29BF.0020.0002.1835] # MONGOLIAN LETTER JA +1853 ; [.29C0.0020.0002.1853] # MONGOLIAN LETTER TODO JA +186A ; [.29C1.0020.0002.186A] # MONGOLIAN LETTER SIBE JA +1877 ; [.29C2.0020.0002.1877] # MONGOLIAN LETTER MANCHU ZHA +1836 ; [.29C3.0020.0002.1836] # MONGOLIAN LETTER YA +1855 ; [.29C4.0020.0002.1855] # MONGOLIAN LETTER TODO YA +1872 ; [.29C5.0020.0002.1872] # MONGOLIAN LETTER SIBE ZHA +1837 ; [.29C6.0020.0002.1837] # MONGOLIAN LETTER RA +1875 ; [.29C7.0020.0002.1875] # MONGOLIAN LETTER MANCHU RA +1838 ; [.29C8.0020.0002.1838] # MONGOLIAN LETTER WA +1856 ; [.29C9.0020.0002.1856] # MONGOLIAN LETTER TODO WA +1839 ; [.29CA.0020.0002.1839] # MONGOLIAN LETTER FA +186B ; [.29CB.0020.0002.186B] # MONGOLIAN LETTER SIBE FA +1876 ; [.29CC.0020.0002.1876] # MONGOLIAN LETTER MANCHU FA +183A ; [.29CD.0020.0002.183A] # MONGOLIAN LETTER KA +1857 ; [.29CE.0020.0002.1857] # MONGOLIAN LETTER TODO KA +1863 ; [.29CF.0020.0002.1863] # MONGOLIAN LETTER SIBE KA +1874 ; [.29D0.0020.0002.1874] # MONGOLIAN LETTER MANCHU KA +1889 ; [.29D1.0020.0002.1889] # MONGOLIAN LETTER ALI GALI KA +183B ; [.29D2.0020.0002.183B] # MONGOLIAN LETTER KHA +183C ; [.29D3.0020.0002.183C] # MONGOLIAN LETTER TSA +1854 ; [.29D4.0020.0002.1854] # MONGOLIAN LETTER TODO TSA +186E ; [.29D5.0020.0002.186E] # MONGOLIAN LETTER SIBE TSA +183D ; [.29D6.0020.0002.183D] # MONGOLIAN LETTER ZA +186F ; [.29D7.0020.0002.186F] # MONGOLIAN LETTER SIBE ZA +1858 ; [.29D8.0020.0002.1858] # MONGOLIAN LETTER TODO GAA +186C ; [.29D9.0020.0002.186C] # MONGOLIAN LETTER SIBE GAA +183E ; [.29DA.0020.0002.183E] # MONGOLIAN LETTER HAA +1859 ; [.29DB.0020.0002.1859] # MONGOLIAN LETTER TODO HAA +186D ; [.29DC.0020.0002.186D] # MONGOLIAN LETTER SIBE HAA +183F ; [.29DD.0020.0002.183F] # MONGOLIAN LETTER ZRA +1840 ; [.29DE.0020.0002.1840] # MONGOLIAN LETTER LHA +1841 ; [.29DF.0020.0002.1841] # MONGOLIAN LETTER ZHI +1842 ; [.29E0.0020.0002.1842] # MONGOLIAN LETTER CHI +185A ; [.29E1.0020.0002.185A] # MONGOLIAN LETTER TODO JIA +185B ; [.29E2.0020.0002.185B] # MONGOLIAN LETTER TODO NIA +1870 ; [.29E3.0020.0002.1870] # MONGOLIAN LETTER SIBE RAA +188C ; [.29E4.0020.0002.188C] # MONGOLIAN LETTER ALI GALI TTA +189E ; [.29E5.0020.0002.189E] # MONGOLIAN LETTER MANCHU ALI GALI TTA +188D ; [.29E6.0020.0002.188D] # MONGOLIAN LETTER ALI GALI TTHA +188E ; [.29E7.0020.0002.188E] # MONGOLIAN LETTER ALI GALI DDA +189F ; [.29E8.0020.0002.189F] # MONGOLIAN LETTER MANCHU ALI GALI DDHA +188F ; [.29E9.0020.0002.188F] # MONGOLIAN LETTER ALI GALI NNA +1890 ; [.29EA.0020.0002.1890] # MONGOLIAN LETTER ALI GALI TA +1898 ; [.29EB.0020.0002.1898] # MONGOLIAN LETTER TODO ALI GALI TA +18A0 ; [.29EC.0020.0002.18A0] # MONGOLIAN LETTER MANCHU ALI GALI TA +1891 ; [.29ED.0020.0002.1891] # MONGOLIAN LETTER ALI GALI DA +18A1 ; [.29EE.0020.0002.18A1] # MONGOLIAN LETTER MANCHU ALI GALI DHA +1892 ; [.29EF.0020.0002.1892] # MONGOLIAN LETTER ALI GALI PA +1893 ; [.29F0.0020.0002.1893] # MONGOLIAN LETTER ALI GALI PHA +18A8 ; [.29F1.0020.0002.18A8] # MONGOLIAN LETTER MANCHU ALI GALI BHA +1894 ; [.29F2.0020.0002.1894] # MONGOLIAN LETTER ALI GALI SSA +18A3 ; [.29F3.0020.0002.18A3] # MONGOLIAN LETTER MANCHU ALI GALI CYA +1895 ; [.29F4.0020.0002.1895] # MONGOLIAN LETTER ALI GALI ZHA +1899 ; [.29F5.0020.0002.1899] # MONGOLIAN LETTER TODO ALI GALI ZHA +1896 ; [.29F6.0020.0002.1896] # MONGOLIAN LETTER ALI GALI ZA +1897 ; [.29F7.0020.0002.1897] # MONGOLIAN LETTER ALI GALI AH +18A6 ; [.29F8.0020.0002.18A6] # MONGOLIAN LETTER ALI GALI HALF U +18A7 ; [.29F9.0020.0002.18A7] # MONGOLIAN LETTER ALI GALI HALF YA +18AA ; [.29FA.0020.0002.18AA] # MONGOLIAN LETTER MANCHU ALI GALI LHA +18A9 ; [.29FB.0020.0002.18A9] # MONGOLIAN LETTER ALI GALI DAGALGA +1C5A ; [.29FC.0020.0002.1C5A] # OL CHIKI LETTER LA +1C5B ; [.29FD.0020.0002.1C5B] # OL CHIKI LETTER AT +1C5C ; [.29FE.0020.0002.1C5C] # OL CHIKI LETTER AG +1C5D ; [.29FF.0020.0002.1C5D] # OL CHIKI LETTER ANG +1C5E ; [.2A00.0020.0002.1C5E] # OL CHIKI LETTER AL +1C5F ; [.2A01.0020.0002.1C5F] # OL CHIKI LETTER LAA +1C60 ; [.2A02.0020.0002.1C60] # OL CHIKI LETTER AAK +1C61 ; [.2A03.0020.0002.1C61] # OL CHIKI LETTER AAJ +1C62 ; [.2A04.0020.0002.1C62] # OL CHIKI LETTER AAM +1C63 ; [.2A05.0020.0002.1C63] # OL CHIKI LETTER AAW +1C64 ; [.2A06.0020.0002.1C64] # OL CHIKI LETTER LI +1C65 ; [.2A07.0020.0002.1C65] # OL CHIKI LETTER IS +1C66 ; [.2A08.0020.0002.1C66] # OL CHIKI LETTER IH +1C67 ; [.2A09.0020.0002.1C67] # OL CHIKI LETTER INY +1C68 ; [.2A0A.0020.0002.1C68] # OL CHIKI LETTER IR +1C69 ; [.2A0B.0020.0002.1C69] # OL CHIKI LETTER LU +1C6A ; [.2A0C.0020.0002.1C6A] # OL CHIKI LETTER UC +1C6B ; [.2A0D.0020.0002.1C6B] # OL CHIKI LETTER UD +1C6C ; [.2A0E.0020.0002.1C6C] # OL CHIKI LETTER UNN +1C6D ; [.2A0F.0020.0002.1C6D] # OL CHIKI LETTER UY +1C6E ; [.2A10.0020.0002.1C6E] # OL CHIKI LETTER LE +1C6F ; [.2A11.0020.0002.1C6F] # OL CHIKI LETTER EP +1C70 ; [.2A12.0020.0002.1C70] # OL CHIKI LETTER EDD +1C71 ; [.2A13.0020.0002.1C71] # OL CHIKI LETTER EN +1C72 ; [.2A14.0020.0002.1C72] # OL CHIKI LETTER ERR +1C73 ; [.2A15.0020.0002.1C73] # OL CHIKI LETTER LO +1C74 ; [.2A16.0020.0002.1C74] # OL CHIKI LETTER OTT +1C75 ; [.2A17.0020.0002.1C75] # OL CHIKI LETTER OB +1C76 ; [.2A18.0020.0002.1C76] # OL CHIKI LETTER OV +1C77 ; [.2A19.0020.0002.1C77] # OL CHIKI LETTER OH +1C78 ; [.2A1A.0020.0002.1C78] # OL CHIKI MU TTUDDAG +1C79 ; [.2A1B.0020.0002.1C79] # OL CHIKI GAAHLAA TTUDDAAG +1C7A ; [.2A1C.0020.0002.1C7A] # OL CHIKI MU-GAAHLAA TTUDDAAG +1C7B ; [.2A1D.0020.0002.1C7B] # OL CHIKI RELAA +1C7C ; [.2A1E.0020.0002.1C7C] # OL CHIKI PHAARKAA +1C7D ; [.2A1F.0020.0002.1C7D] # OL CHIKI AHAD +13A0 ; [.2A20.0020.0002.13A0] # CHEROKEE LETTER A +13A1 ; [.2A21.0020.0002.13A1] # CHEROKEE LETTER E +13A2 ; [.2A22.0020.0002.13A2] # CHEROKEE LETTER I +13A3 ; [.2A23.0020.0002.13A3] # CHEROKEE LETTER O +13A4 ; [.2A24.0020.0002.13A4] # CHEROKEE LETTER U +13A5 ; [.2A25.0020.0002.13A5] # CHEROKEE LETTER V +13A6 ; [.2A26.0020.0002.13A6] # CHEROKEE LETTER GA +13A7 ; [.2A27.0020.0002.13A7] # CHEROKEE LETTER KA +13A8 ; [.2A28.0020.0002.13A8] # CHEROKEE LETTER GE +13A9 ; [.2A29.0020.0002.13A9] # CHEROKEE LETTER GI +13AA ; [.2A2A.0020.0002.13AA] # CHEROKEE LETTER GO +13AB ; [.2A2B.0020.0002.13AB] # CHEROKEE LETTER GU +13AC ; [.2A2C.0020.0002.13AC] # CHEROKEE LETTER GV +13AD ; [.2A2D.0020.0002.13AD] # CHEROKEE LETTER HA +13AE ; [.2A2E.0020.0002.13AE] # CHEROKEE LETTER HE +13AF ; [.2A2F.0020.0002.13AF] # CHEROKEE LETTER HI +13B0 ; [.2A30.0020.0002.13B0] # CHEROKEE LETTER HO +13B1 ; [.2A31.0020.0002.13B1] # CHEROKEE LETTER HU +13B2 ; [.2A32.0020.0002.13B2] # CHEROKEE LETTER HV +13B3 ; [.2A33.0020.0002.13B3] # CHEROKEE LETTER LA +13B4 ; [.2A34.0020.0002.13B4] # CHEROKEE LETTER LE +13B5 ; [.2A35.0020.0002.13B5] # CHEROKEE LETTER LI +13B6 ; [.2A36.0020.0002.13B6] # CHEROKEE LETTER LO +13B7 ; [.2A37.0020.0002.13B7] # CHEROKEE LETTER LU +13B8 ; [.2A38.0020.0002.13B8] # CHEROKEE LETTER LV +13B9 ; [.2A39.0020.0002.13B9] # CHEROKEE LETTER MA +13BA ; [.2A3A.0020.0002.13BA] # CHEROKEE LETTER ME +13BB ; [.2A3B.0020.0002.13BB] # CHEROKEE LETTER MI +13BC ; [.2A3C.0020.0002.13BC] # CHEROKEE LETTER MO +13BD ; [.2A3D.0020.0002.13BD] # CHEROKEE LETTER MU +13BE ; [.2A3E.0020.0002.13BE] # CHEROKEE LETTER NA +13BF ; [.2A3F.0020.0002.13BF] # CHEROKEE LETTER HNA +13C0 ; [.2A40.0020.0002.13C0] # CHEROKEE LETTER NAH +13C1 ; [.2A41.0020.0002.13C1] # CHEROKEE LETTER NE +13C2 ; [.2A42.0020.0002.13C2] # CHEROKEE LETTER NI +13C3 ; [.2A43.0020.0002.13C3] # CHEROKEE LETTER NO +13C4 ; [.2A44.0020.0002.13C4] # CHEROKEE LETTER NU +13C5 ; [.2A45.0020.0002.13C5] # CHEROKEE LETTER NV +13C6 ; [.2A46.0020.0002.13C6] # CHEROKEE LETTER QUA +13C7 ; [.2A47.0020.0002.13C7] # CHEROKEE LETTER QUE +13C8 ; [.2A48.0020.0002.13C8] # CHEROKEE LETTER QUI +13C9 ; [.2A49.0020.0002.13C9] # CHEROKEE LETTER QUO +13CA ; [.2A4A.0020.0002.13CA] # CHEROKEE LETTER QUU +13CB ; [.2A4B.0020.0002.13CB] # CHEROKEE LETTER QUV +13CC ; [.2A4C.0020.0002.13CC] # CHEROKEE LETTER SA +13CD ; [.2A4D.0020.0002.13CD] # CHEROKEE LETTER S +13CE ; [.2A4E.0020.0002.13CE] # CHEROKEE LETTER SE +13CF ; [.2A4F.0020.0002.13CF] # CHEROKEE LETTER SI +13D0 ; [.2A50.0020.0002.13D0] # CHEROKEE LETTER SO +13D1 ; [.2A51.0020.0002.13D1] # CHEROKEE LETTER SU +13D2 ; [.2A52.0020.0002.13D2] # CHEROKEE LETTER SV +13D3 ; [.2A53.0020.0002.13D3] # CHEROKEE LETTER DA +13D4 ; [.2A54.0020.0002.13D4] # CHEROKEE LETTER TA +13D5 ; [.2A55.0020.0002.13D5] # CHEROKEE LETTER DE +13D6 ; [.2A56.0020.0002.13D6] # CHEROKEE LETTER TE +13D7 ; [.2A57.0020.0002.13D7] # CHEROKEE LETTER DI +13D8 ; [.2A58.0020.0002.13D8] # CHEROKEE LETTER TI +13D9 ; [.2A59.0020.0002.13D9] # CHEROKEE LETTER DO +13DA ; [.2A5A.0020.0002.13DA] # CHEROKEE LETTER DU +13DB ; [.2A5B.0020.0002.13DB] # CHEROKEE LETTER DV +13DC ; [.2A5C.0020.0002.13DC] # CHEROKEE LETTER DLA +13DD ; [.2A5D.0020.0002.13DD] # CHEROKEE LETTER TLA +13DE ; [.2A5E.0020.0002.13DE] # CHEROKEE LETTER TLE +13DF ; [.2A5F.0020.0002.13DF] # CHEROKEE LETTER TLI +13E0 ; [.2A60.0020.0002.13E0] # CHEROKEE LETTER TLO +13E1 ; [.2A61.0020.0002.13E1] # CHEROKEE LETTER TLU +13E2 ; [.2A62.0020.0002.13E2] # CHEROKEE LETTER TLV +13E3 ; [.2A63.0020.0002.13E3] # CHEROKEE LETTER TSA +13E4 ; [.2A64.0020.0002.13E4] # CHEROKEE LETTER TSE +13E5 ; [.2A65.0020.0002.13E5] # CHEROKEE LETTER TSI +13E6 ; [.2A66.0020.0002.13E6] # CHEROKEE LETTER TSO +13E7 ; [.2A67.0020.0002.13E7] # CHEROKEE LETTER TSU +13E8 ; [.2A68.0020.0002.13E8] # CHEROKEE LETTER TSV +13E9 ; [.2A69.0020.0002.13E9] # CHEROKEE LETTER WA +13EA ; [.2A6A.0020.0002.13EA] # CHEROKEE LETTER WE +13EB ; [.2A6B.0020.0002.13EB] # CHEROKEE LETTER WI +13EC ; [.2A6C.0020.0002.13EC] # CHEROKEE LETTER WO +13ED ; [.2A6D.0020.0002.13ED] # CHEROKEE LETTER WU +13EE ; [.2A6E.0020.0002.13EE] # CHEROKEE LETTER WV +13EF ; [.2A6F.0020.0002.13EF] # CHEROKEE LETTER YA +13F0 ; [.2A70.0020.0002.13F0] # CHEROKEE LETTER YE +13F1 ; [.2A71.0020.0002.13F1] # CHEROKEE LETTER YI +13F2 ; [.2A72.0020.0002.13F2] # CHEROKEE LETTER YO +13F3 ; [.2A73.0020.0002.13F3] # CHEROKEE LETTER YU +13F4 ; [.2A74.0020.0002.13F4] # CHEROKEE LETTER YV +1401 ; [.2A75.0020.0002.1401] # CANADIAN SYLLABICS E +1402 ; [.2A76.0020.0002.1402] # CANADIAN SYLLABICS AAI +1403 ; [.2A77.0020.0002.1403] # CANADIAN SYLLABICS I +1404 ; [.2A78.0020.0002.1404] # CANADIAN SYLLABICS II +1405 ; [.2A79.0020.0002.1405] # CANADIAN SYLLABICS O +1406 ; [.2A7A.0020.0002.1406] # CANADIAN SYLLABICS OO +1407 ; [.2A7B.0020.0002.1407] # CANADIAN SYLLABICS Y-CREE OO +1408 ; [.2A7C.0020.0002.1408] # CANADIAN SYLLABICS CARRIER EE +1409 ; [.2A7D.0020.0002.1409] # CANADIAN SYLLABICS CARRIER I +140A ; [.2A7E.0020.0002.140A] # CANADIAN SYLLABICS A +140B ; [.2A7F.0020.0002.140B] # CANADIAN SYLLABICS AA +140C ; [.2A80.0020.0002.140C] # CANADIAN SYLLABICS WE +140D ; [.2A81.0020.0002.140D] # CANADIAN SYLLABICS WEST-CREE WE +140E ; [.2A82.0020.0002.140E] # CANADIAN SYLLABICS WI +140F ; [.2A83.0020.0002.140F] # CANADIAN SYLLABICS WEST-CREE WI +1410 ; [.2A84.0020.0002.1410] # CANADIAN SYLLABICS WII +1411 ; [.2A85.0020.0002.1411] # CANADIAN SYLLABICS WEST-CREE WII +1412 ; [.2A86.0020.0002.1412] # CANADIAN SYLLABICS WO +1413 ; [.2A87.0020.0002.1413] # CANADIAN SYLLABICS WEST-CREE WO +1414 ; [.2A88.0020.0002.1414] # CANADIAN SYLLABICS WOO +1415 ; [.2A89.0020.0002.1415] # CANADIAN SYLLABICS WEST-CREE WOO +1416 ; [.2A8A.0020.0002.1416] # CANADIAN SYLLABICS NASKAPI WOO +1417 ; [.2A8B.0020.0002.1417] # CANADIAN SYLLABICS WA +1418 ; [.2A8C.0020.0002.1418] # CANADIAN SYLLABICS WEST-CREE WA +1419 ; [.2A8D.0020.0002.1419] # CANADIAN SYLLABICS WAA +141A ; [.2A8E.0020.0002.141A] # CANADIAN SYLLABICS WEST-CREE WAA +141B ; [.2A8F.0020.0002.141B] # CANADIAN SYLLABICS NASKAPI WAA +141C ; [.2A90.0020.0002.141C] # CANADIAN SYLLABICS AI +141D ; [.2A91.0020.0002.141D] # CANADIAN SYLLABICS Y-CREE W +141E ; [.2A92.0020.0002.141E] # CANADIAN SYLLABICS GLOTTAL STOP +141F ; [.2A93.0020.0002.141F] # CANADIAN SYLLABICS FINAL ACUTE +1420 ; [.2A94.0020.0002.1420] # CANADIAN SYLLABICS FINAL GRAVE +1421 ; [.2A95.0020.0002.1421] # CANADIAN SYLLABICS FINAL BOTTOM HALF RING +1422 ; [.2A96.0020.0002.1422] # CANADIAN SYLLABICS FINAL TOP HALF RING +1423 ; [.2A97.0020.0002.1423] # CANADIAN SYLLABICS FINAL RIGHT HALF RING +1424 ; [.2A98.0020.0002.1424] # CANADIAN SYLLABICS FINAL RING +1425 ; [.2A99.0020.0002.1425] # CANADIAN SYLLABICS FINAL DOUBLE ACUTE +1426 ; [.2A9A.0020.0002.1426] # CANADIAN SYLLABICS FINAL DOUBLE SHORT VERTICAL STROKES +1427 ; [.2A9B.0020.0002.1427] # CANADIAN SYLLABICS FINAL MIDDLE DOT +1428 ; [.2A9C.0020.0002.1428] # CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE +1429 ; [.2A9D.0020.0002.1429] # CANADIAN SYLLABICS FINAL PLUS +142A ; [.2A9E.0020.0002.142A] # CANADIAN SYLLABICS FINAL DOWN TACK +142B ; [.2A9F.0020.0002.142B] # CANADIAN SYLLABICS EN +142C ; [.2AA0.0020.0002.142C] # CANADIAN SYLLABICS IN +142D ; [.2AA1.0020.0002.142D] # CANADIAN SYLLABICS ON +142E ; [.2AA2.0020.0002.142E] # CANADIAN SYLLABICS AN +142F ; [.2AA3.0020.0002.142F] # CANADIAN SYLLABICS PE +1430 ; [.2AA4.0020.0002.1430] # CANADIAN SYLLABICS PAAI +1431 ; [.2AA5.0020.0002.1431] # CANADIAN SYLLABICS PI +1432 ; [.2AA6.0020.0002.1432] # CANADIAN SYLLABICS PII +1433 ; [.2AA7.0020.0002.1433] # CANADIAN SYLLABICS PO +1434 ; [.2AA8.0020.0002.1434] # CANADIAN SYLLABICS POO +1435 ; [.2AA9.0020.0002.1435] # CANADIAN SYLLABICS Y-CREE POO +1436 ; [.2AAA.0020.0002.1436] # CANADIAN SYLLABICS CARRIER HEE +1437 ; [.2AAB.0020.0002.1437] # CANADIAN SYLLABICS CARRIER HI +1438 ; [.2AAC.0020.0002.1438] # CANADIAN SYLLABICS PA +1439 ; [.2AAD.0020.0002.1439] # CANADIAN SYLLABICS PAA +143A ; [.2AAE.0020.0002.143A] # CANADIAN SYLLABICS PWE +143B ; [.2AAF.0020.0002.143B] # CANADIAN SYLLABICS WEST-CREE PWE +143C ; [.2AB0.0020.0002.143C] # CANADIAN SYLLABICS PWI +143D ; [.2AB1.0020.0002.143D] # CANADIAN SYLLABICS WEST-CREE PWI +143E ; [.2AB2.0020.0002.143E] # CANADIAN SYLLABICS PWII +143F ; [.2AB3.0020.0002.143F] # CANADIAN SYLLABICS WEST-CREE PWII +1440 ; [.2AB4.0020.0002.1440] # CANADIAN SYLLABICS PWO +1441 ; [.2AB5.0020.0002.1441] # CANADIAN SYLLABICS WEST-CREE PWO +1442 ; [.2AB6.0020.0002.1442] # CANADIAN SYLLABICS PWOO +1443 ; [.2AB7.0020.0002.1443] # CANADIAN SYLLABICS WEST-CREE PWOO +1444 ; [.2AB8.0020.0002.1444] # CANADIAN SYLLABICS PWA +1445 ; [.2AB9.0020.0002.1445] # CANADIAN SYLLABICS WEST-CREE PWA +1446 ; [.2ABA.0020.0002.1446] # CANADIAN SYLLABICS PWAA +1447 ; [.2ABB.0020.0002.1447] # CANADIAN SYLLABICS WEST-CREE PWAA +1448 ; [.2ABC.0020.0002.1448] # CANADIAN SYLLABICS Y-CREE PWAA +1449 ; [.2ABD.0020.0002.1449] # CANADIAN SYLLABICS P +144A ; [.2ABE.0020.0002.144A] # CANADIAN SYLLABICS WEST-CREE P +144B ; [.2ABF.0020.0002.144B] # CANADIAN SYLLABICS CARRIER H +144C ; [.2AC0.0020.0002.144C] # CANADIAN SYLLABICS TE +144D ; [.2AC1.0020.0002.144D] # CANADIAN SYLLABICS TAAI +144E ; [.2AC2.0020.0002.144E] # CANADIAN SYLLABICS TI +144F ; [.2AC3.0020.0002.144F] # CANADIAN SYLLABICS TII +1450 ; [.2AC4.0020.0002.1450] # CANADIAN SYLLABICS TO +1451 ; [.2AC5.0020.0002.1451] # CANADIAN SYLLABICS TOO +1452 ; [.2AC6.0020.0002.1452] # CANADIAN SYLLABICS Y-CREE TOO +1453 ; [.2AC7.0020.0002.1453] # CANADIAN SYLLABICS CARRIER DEE +1454 ; [.2AC8.0020.0002.1454] # CANADIAN SYLLABICS CARRIER DI +1455 ; [.2AC9.0020.0002.1455] # CANADIAN SYLLABICS TA +1456 ; [.2ACA.0020.0002.1456] # CANADIAN SYLLABICS TAA +1457 ; [.2ACB.0020.0002.1457] # CANADIAN SYLLABICS TWE +1458 ; [.2ACC.0020.0002.1458] # CANADIAN SYLLABICS WEST-CREE TWE +1459 ; [.2ACD.0020.0002.1459] # CANADIAN SYLLABICS TWI +145A ; [.2ACE.0020.0002.145A] # CANADIAN SYLLABICS WEST-CREE TWI +145B ; [.2ACF.0020.0002.145B] # CANADIAN SYLLABICS TWII +145C ; [.2AD0.0020.0002.145C] # CANADIAN SYLLABICS WEST-CREE TWII +145D ; [.2AD1.0020.0002.145D] # CANADIAN SYLLABICS TWO +145E ; [.2AD2.0020.0002.145E] # CANADIAN SYLLABICS WEST-CREE TWO +145F ; [.2AD3.0020.0002.145F] # CANADIAN SYLLABICS TWOO +1460 ; [.2AD4.0020.0002.1460] # CANADIAN SYLLABICS WEST-CREE TWOO +1461 ; [.2AD5.0020.0002.1461] # CANADIAN SYLLABICS TWA +1462 ; [.2AD6.0020.0002.1462] # CANADIAN SYLLABICS WEST-CREE TWA +1463 ; [.2AD7.0020.0002.1463] # CANADIAN SYLLABICS TWAA +1464 ; [.2AD8.0020.0002.1464] # CANADIAN SYLLABICS WEST-CREE TWAA +1465 ; [.2AD9.0020.0002.1465] # CANADIAN SYLLABICS NASKAPI TWAA +1466 ; [.2ADA.0020.0002.1466] # CANADIAN SYLLABICS T +1467 ; [.2ADB.0020.0002.1467] # CANADIAN SYLLABICS TTE +1468 ; [.2ADC.0020.0002.1468] # CANADIAN SYLLABICS TTI +1469 ; [.2ADD.0020.0002.1469] # CANADIAN SYLLABICS TTO +146A ; [.2ADE.0020.0002.146A] # CANADIAN SYLLABICS TTA +146B ; [.2ADF.0020.0002.146B] # CANADIAN SYLLABICS KE +146C ; [.2AE0.0020.0002.146C] # CANADIAN SYLLABICS KAAI +146D ; [.2AE1.0020.0002.146D] # CANADIAN SYLLABICS KI +146E ; [.2AE2.0020.0002.146E] # CANADIAN SYLLABICS KII +146F ; [.2AE3.0020.0002.146F] # CANADIAN SYLLABICS KO +1470 ; [.2AE4.0020.0002.1470] # CANADIAN SYLLABICS KOO +1471 ; [.2AE5.0020.0002.1471] # CANADIAN SYLLABICS Y-CREE KOO +1472 ; [.2AE6.0020.0002.1472] # CANADIAN SYLLABICS KA +1473 ; [.2AE7.0020.0002.1473] # CANADIAN SYLLABICS KAA +1474 ; [.2AE8.0020.0002.1474] # CANADIAN SYLLABICS KWE +1475 ; [.2AE9.0020.0002.1475] # CANADIAN SYLLABICS WEST-CREE KWE +1476 ; [.2AEA.0020.0002.1476] # CANADIAN SYLLABICS KWI +1477 ; [.2AEB.0020.0002.1477] # CANADIAN SYLLABICS WEST-CREE KWI +1478 ; [.2AEC.0020.0002.1478] # CANADIAN SYLLABICS KWII +1479 ; [.2AED.0020.0002.1479] # CANADIAN SYLLABICS WEST-CREE KWII +147A ; [.2AEE.0020.0002.147A] # CANADIAN SYLLABICS KWO +147B ; [.2AEF.0020.0002.147B] # CANADIAN SYLLABICS WEST-CREE KWO +147C ; [.2AF0.0020.0002.147C] # CANADIAN SYLLABICS KWOO +147D ; [.2AF1.0020.0002.147D] # CANADIAN SYLLABICS WEST-CREE KWOO +147E ; [.2AF2.0020.0002.147E] # CANADIAN SYLLABICS KWA +147F ; [.2AF3.0020.0002.147F] # CANADIAN SYLLABICS WEST-CREE KWA +1480 ; [.2AF4.0020.0002.1480] # CANADIAN SYLLABICS KWAA +1481 ; [.2AF5.0020.0002.1481] # CANADIAN SYLLABICS WEST-CREE KWAA +1482 ; [.2AF6.0020.0002.1482] # CANADIAN SYLLABICS NASKAPI KWAA +1483 ; [.2AF7.0020.0002.1483] # CANADIAN SYLLABICS K +1484 ; [.2AF8.0020.0002.1484] # CANADIAN SYLLABICS KW +1485 ; [.2AF9.0020.0002.1485] # CANADIAN SYLLABICS SOUTH-SLAVEY KEH +1486 ; [.2AFA.0020.0002.1486] # CANADIAN SYLLABICS SOUTH-SLAVEY KIH +1487 ; [.2AFB.0020.0002.1487] # CANADIAN SYLLABICS SOUTH-SLAVEY KOH +1488 ; [.2AFC.0020.0002.1488] # CANADIAN SYLLABICS SOUTH-SLAVEY KAH +1489 ; [.2AFD.0020.0002.1489] # CANADIAN SYLLABICS CE +148A ; [.2AFE.0020.0002.148A] # CANADIAN SYLLABICS CAAI +148B ; [.2AFF.0020.0002.148B] # CANADIAN SYLLABICS CI +148C ; [.2B00.0020.0002.148C] # CANADIAN SYLLABICS CII +148D ; [.2B01.0020.0002.148D] # CANADIAN SYLLABICS CO +148E ; [.2B02.0020.0002.148E] # CANADIAN SYLLABICS COO +148F ; [.2B03.0020.0002.148F] # CANADIAN SYLLABICS Y-CREE COO +1490 ; [.2B04.0020.0002.1490] # CANADIAN SYLLABICS CA +1491 ; [.2B05.0020.0002.1491] # CANADIAN SYLLABICS CAA +1492 ; [.2B06.0020.0002.1492] # CANADIAN SYLLABICS CWE +1493 ; [.2B07.0020.0002.1493] # CANADIAN SYLLABICS WEST-CREE CWE +1494 ; [.2B08.0020.0002.1494] # CANADIAN SYLLABICS CWI +1495 ; [.2B09.0020.0002.1495] # CANADIAN SYLLABICS WEST-CREE CWI +1496 ; [.2B0A.0020.0002.1496] # CANADIAN SYLLABICS CWII +1497 ; [.2B0B.0020.0002.1497] # CANADIAN SYLLABICS WEST-CREE CWII +1498 ; [.2B0C.0020.0002.1498] # CANADIAN SYLLABICS CWO +1499 ; [.2B0D.0020.0002.1499] # CANADIAN SYLLABICS WEST-CREE CWO +149A ; [.2B0E.0020.0002.149A] # CANADIAN SYLLABICS CWOO +149B ; [.2B0F.0020.0002.149B] # CANADIAN SYLLABICS WEST-CREE CWOO +149C ; [.2B10.0020.0002.149C] # CANADIAN SYLLABICS CWA +149D ; [.2B11.0020.0002.149D] # CANADIAN SYLLABICS WEST-CREE CWA +149E ; [.2B12.0020.0002.149E] # CANADIAN SYLLABICS CWAA +149F ; [.2B13.0020.0002.149F] # CANADIAN SYLLABICS WEST-CREE CWAA +14A0 ; [.2B14.0020.0002.14A0] # CANADIAN SYLLABICS NASKAPI CWAA +14A1 ; [.2B15.0020.0002.14A1] # CANADIAN SYLLABICS C +14A2 ; [.2B16.0020.0002.14A2] # CANADIAN SYLLABICS SAYISI TH +14A3 ; [.2B17.0020.0002.14A3] # CANADIAN SYLLABICS ME +14A4 ; [.2B18.0020.0002.14A4] # CANADIAN SYLLABICS MAAI +14A5 ; [.2B19.0020.0002.14A5] # CANADIAN SYLLABICS MI +14A6 ; [.2B1A.0020.0002.14A6] # CANADIAN SYLLABICS MII +14A7 ; [.2B1B.0020.0002.14A7] # CANADIAN SYLLABICS MO +14A8 ; [.2B1C.0020.0002.14A8] # CANADIAN SYLLABICS MOO +14A9 ; [.2B1D.0020.0002.14A9] # CANADIAN SYLLABICS Y-CREE MOO +14AA ; [.2B1E.0020.0002.14AA] # CANADIAN SYLLABICS MA +14AB ; [.2B1F.0020.0002.14AB] # CANADIAN SYLLABICS MAA +14AC ; [.2B20.0020.0002.14AC] # CANADIAN SYLLABICS MWE +14AD ; [.2B21.0020.0002.14AD] # CANADIAN SYLLABICS WEST-CREE MWE +14AE ; [.2B22.0020.0002.14AE] # CANADIAN SYLLABICS MWI +14AF ; [.2B23.0020.0002.14AF] # CANADIAN SYLLABICS WEST-CREE MWI +14B0 ; [.2B24.0020.0002.14B0] # CANADIAN SYLLABICS MWII +14B1 ; [.2B25.0020.0002.14B1] # CANADIAN SYLLABICS WEST-CREE MWII +14B2 ; [.2B26.0020.0002.14B2] # CANADIAN SYLLABICS MWO +14B3 ; [.2B27.0020.0002.14B3] # CANADIAN SYLLABICS WEST-CREE MWO +14B4 ; [.2B28.0020.0002.14B4] # CANADIAN SYLLABICS MWOO +14B5 ; [.2B29.0020.0002.14B5] # CANADIAN SYLLABICS WEST-CREE MWOO +14B6 ; [.2B2A.0020.0002.14B6] # CANADIAN SYLLABICS MWA +14B7 ; [.2B2B.0020.0002.14B7] # CANADIAN SYLLABICS WEST-CREE MWA +14B8 ; [.2B2C.0020.0002.14B8] # CANADIAN SYLLABICS MWAA +14B9 ; [.2B2D.0020.0002.14B9] # CANADIAN SYLLABICS WEST-CREE MWAA +14BA ; [.2B2E.0020.0002.14BA] # CANADIAN SYLLABICS NASKAPI MWAA +14BB ; [.2B2F.0020.0002.14BB] # CANADIAN SYLLABICS M +14BC ; [.2B30.0020.0002.14BC] # CANADIAN SYLLABICS WEST-CREE M +14BD ; [.2B31.0020.0002.14BD] # CANADIAN SYLLABICS MH +14BE ; [.2B32.0020.0002.14BE] # CANADIAN SYLLABICS ATHAPASCAN M +14BF ; [.2B33.0020.0002.14BF] # CANADIAN SYLLABICS SAYISI M +14C0 ; [.2B34.0020.0002.14C0] # CANADIAN SYLLABICS NE +14C1 ; [.2B35.0020.0002.14C1] # CANADIAN SYLLABICS NAAI +14C2 ; [.2B36.0020.0002.14C2] # CANADIAN SYLLABICS NI +14C3 ; [.2B37.0020.0002.14C3] # CANADIAN SYLLABICS NII +14C4 ; [.2B38.0020.0002.14C4] # CANADIAN SYLLABICS NO +14C5 ; [.2B39.0020.0002.14C5] # CANADIAN SYLLABICS NOO +14C6 ; [.2B3A.0020.0002.14C6] # CANADIAN SYLLABICS Y-CREE NOO +14C7 ; [.2B3B.0020.0002.14C7] # CANADIAN SYLLABICS NA +14C8 ; [.2B3C.0020.0002.14C8] # CANADIAN SYLLABICS NAA +14C9 ; [.2B3D.0020.0002.14C9] # CANADIAN SYLLABICS NWE +14CA ; [.2B3E.0020.0002.14CA] # CANADIAN SYLLABICS WEST-CREE NWE +14CB ; [.2B3F.0020.0002.14CB] # CANADIAN SYLLABICS NWA +14CC ; [.2B40.0020.0002.14CC] # CANADIAN SYLLABICS WEST-CREE NWA +14CD ; [.2B41.0020.0002.14CD] # CANADIAN SYLLABICS NWAA +14CE ; [.2B42.0020.0002.14CE] # CANADIAN SYLLABICS WEST-CREE NWAA +14CF ; [.2B43.0020.0002.14CF] # CANADIAN SYLLABICS NASKAPI NWAA +14D0 ; [.2B44.0020.0002.14D0] # CANADIAN SYLLABICS N +14D1 ; [.2B45.0020.0002.14D1] # CANADIAN SYLLABICS CARRIER NG +14D2 ; [.2B46.0020.0002.14D2] # CANADIAN SYLLABICS NH +14D3 ; [.2B47.0020.0002.14D3] # CANADIAN SYLLABICS LE +14D4 ; [.2B48.0020.0002.14D4] # CANADIAN SYLLABICS LAAI +14D5 ; [.2B49.0020.0002.14D5] # CANADIAN SYLLABICS LI +14D6 ; [.2B4A.0020.0002.14D6] # CANADIAN SYLLABICS LII +14D7 ; [.2B4B.0020.0002.14D7] # CANADIAN SYLLABICS LO +14D8 ; [.2B4C.0020.0002.14D8] # CANADIAN SYLLABICS LOO +14D9 ; [.2B4D.0020.0002.14D9] # CANADIAN SYLLABICS Y-CREE LOO +14DA ; [.2B4E.0020.0002.14DA] # CANADIAN SYLLABICS LA +14DB ; [.2B4F.0020.0002.14DB] # CANADIAN SYLLABICS LAA +14DC ; [.2B50.0020.0002.14DC] # CANADIAN SYLLABICS LWE +14DD ; [.2B51.0020.0002.14DD] # CANADIAN SYLLABICS WEST-CREE LWE +14DE ; [.2B52.0020.0002.14DE] # CANADIAN SYLLABICS LWI +14DF ; [.2B53.0020.0002.14DF] # CANADIAN SYLLABICS WEST-CREE LWI +14E0 ; [.2B54.0020.0002.14E0] # CANADIAN SYLLABICS LWII +14E1 ; [.2B55.0020.0002.14E1] # CANADIAN SYLLABICS WEST-CREE LWII +14E2 ; [.2B56.0020.0002.14E2] # CANADIAN SYLLABICS LWO +14E3 ; [.2B57.0020.0002.14E3] # CANADIAN SYLLABICS WEST-CREE LWO +14E4 ; [.2B58.0020.0002.14E4] # CANADIAN SYLLABICS LWOO +14E5 ; [.2B59.0020.0002.14E5] # CANADIAN SYLLABICS WEST-CREE LWOO +14E6 ; [.2B5A.0020.0002.14E6] # CANADIAN SYLLABICS LWA +14E7 ; [.2B5B.0020.0002.14E7] # CANADIAN SYLLABICS WEST-CREE LWA +14E8 ; [.2B5C.0020.0002.14E8] # CANADIAN SYLLABICS LWAA +14E9 ; [.2B5D.0020.0002.14E9] # CANADIAN SYLLABICS WEST-CREE LWAA +14EA ; [.2B5E.0020.0002.14EA] # CANADIAN SYLLABICS L +14EB ; [.2B5F.0020.0002.14EB] # CANADIAN SYLLABICS WEST-CREE L +14EC ; [.2B60.0020.0002.14EC] # CANADIAN SYLLABICS MEDIAL L +14ED ; [.2B61.0020.0002.14ED] # CANADIAN SYLLABICS SE +14EE ; [.2B62.0020.0002.14EE] # CANADIAN SYLLABICS SAAI +14EF ; [.2B63.0020.0002.14EF] # CANADIAN SYLLABICS SI +14F0 ; [.2B64.0020.0002.14F0] # CANADIAN SYLLABICS SII +14F1 ; [.2B65.0020.0002.14F1] # CANADIAN SYLLABICS SO +14F2 ; [.2B66.0020.0002.14F2] # CANADIAN SYLLABICS SOO +14F3 ; [.2B67.0020.0002.14F3] # CANADIAN SYLLABICS Y-CREE SOO +14F4 ; [.2B68.0020.0002.14F4] # CANADIAN SYLLABICS SA +14F5 ; [.2B69.0020.0002.14F5] # CANADIAN SYLLABICS SAA +14F6 ; [.2B6A.0020.0002.14F6] # CANADIAN SYLLABICS SWE +14F7 ; [.2B6B.0020.0002.14F7] # CANADIAN SYLLABICS WEST-CREE SWE +14F8 ; [.2B6C.0020.0002.14F8] # CANADIAN SYLLABICS SWI +14F9 ; [.2B6D.0020.0002.14F9] # CANADIAN SYLLABICS WEST-CREE SWI +14FA ; [.2B6E.0020.0002.14FA] # CANADIAN SYLLABICS SWII +14FB ; [.2B6F.0020.0002.14FB] # CANADIAN SYLLABICS WEST-CREE SWII +14FC ; [.2B70.0020.0002.14FC] # CANADIAN SYLLABICS SWO +14FD ; [.2B71.0020.0002.14FD] # CANADIAN SYLLABICS WEST-CREE SWO +14FE ; [.2B72.0020.0002.14FE] # CANADIAN SYLLABICS SWOO +14FF ; [.2B73.0020.0002.14FF] # CANADIAN SYLLABICS WEST-CREE SWOO +1500 ; [.2B74.0020.0002.1500] # CANADIAN SYLLABICS SWA +1501 ; [.2B75.0020.0002.1501] # CANADIAN SYLLABICS WEST-CREE SWA +1502 ; [.2B76.0020.0002.1502] # CANADIAN SYLLABICS SWAA +1503 ; [.2B77.0020.0002.1503] # CANADIAN SYLLABICS WEST-CREE SWAA +1504 ; [.2B78.0020.0002.1504] # CANADIAN SYLLABICS NASKAPI SWAA +1505 ; [.2B79.0020.0002.1505] # CANADIAN SYLLABICS S +1506 ; [.2B7A.0020.0002.1506] # CANADIAN SYLLABICS ATHAPASCAN S +1507 ; [.2B7B.0020.0002.1507] # CANADIAN SYLLABICS SW +1508 ; [.2B7C.0020.0002.1508] # CANADIAN SYLLABICS BLACKFOOT S +1509 ; [.2B7D.0020.0002.1509] # CANADIAN SYLLABICS MOOSE-CREE SK +150A ; [.2B7E.0020.0002.150A] # CANADIAN SYLLABICS NASKAPI SKW +150B ; [.2B7F.0020.0002.150B] # CANADIAN SYLLABICS NASKAPI S-W +150C ; [.2B80.0020.0002.150C] # CANADIAN SYLLABICS NASKAPI SPWA +150D ; [.2B81.0020.0002.150D] # CANADIAN SYLLABICS NASKAPI STWA +150E ; [.2B82.0020.0002.150E] # CANADIAN SYLLABICS NASKAPI SKWA +150F ; [.2B83.0020.0002.150F] # CANADIAN SYLLABICS NASKAPI SCWA +1510 ; [.2B84.0020.0002.1510] # CANADIAN SYLLABICS SHE +1511 ; [.2B85.0020.0002.1511] # CANADIAN SYLLABICS SHI +1512 ; [.2B86.0020.0002.1512] # CANADIAN SYLLABICS SHII +1513 ; [.2B87.0020.0002.1513] # CANADIAN SYLLABICS SHO +1514 ; [.2B88.0020.0002.1514] # CANADIAN SYLLABICS SHOO +1515 ; [.2B89.0020.0002.1515] # CANADIAN SYLLABICS SHA +1516 ; [.2B8A.0020.0002.1516] # CANADIAN SYLLABICS SHAA +1517 ; [.2B8B.0020.0002.1517] # CANADIAN SYLLABICS SHWE +1518 ; [.2B8C.0020.0002.1518] # CANADIAN SYLLABICS WEST-CREE SHWE +1519 ; [.2B8D.0020.0002.1519] # CANADIAN SYLLABICS SHWI +151A ; [.2B8E.0020.0002.151A] # CANADIAN SYLLABICS WEST-CREE SHWI +151B ; [.2B8F.0020.0002.151B] # CANADIAN SYLLABICS SHWII +151C ; [.2B90.0020.0002.151C] # CANADIAN SYLLABICS WEST-CREE SHWII +151D ; [.2B91.0020.0002.151D] # CANADIAN SYLLABICS SHWO +151E ; [.2B92.0020.0002.151E] # CANADIAN SYLLABICS WEST-CREE SHWO +151F ; [.2B93.0020.0002.151F] # CANADIAN SYLLABICS SHWOO +1520 ; [.2B94.0020.0002.1520] # CANADIAN SYLLABICS WEST-CREE SHWOO +1521 ; [.2B95.0020.0002.1521] # CANADIAN SYLLABICS SHWA +1522 ; [.2B96.0020.0002.1522] # CANADIAN SYLLABICS WEST-CREE SHWA +1523 ; [.2B97.0020.0002.1523] # CANADIAN SYLLABICS SHWAA +1524 ; [.2B98.0020.0002.1524] # CANADIAN SYLLABICS WEST-CREE SHWAA +1525 ; [.2B99.0020.0002.1525] # CANADIAN SYLLABICS SH +1526 ; [.2B9A.0020.0002.1526] # CANADIAN SYLLABICS YE +1527 ; [.2B9B.0020.0002.1527] # CANADIAN SYLLABICS YAAI +1528 ; [.2B9C.0020.0002.1528] # CANADIAN SYLLABICS YI +1529 ; [.2B9D.0020.0002.1529] # CANADIAN SYLLABICS YII +152A ; [.2B9E.0020.0002.152A] # CANADIAN SYLLABICS YO +152B ; [.2B9F.0020.0002.152B] # CANADIAN SYLLABICS YOO +152C ; [.2BA0.0020.0002.152C] # CANADIAN SYLLABICS Y-CREE YOO +152D ; [.2BA1.0020.0002.152D] # CANADIAN SYLLABICS YA +152E ; [.2BA2.0020.0002.152E] # CANADIAN SYLLABICS YAA +152F ; [.2BA3.0020.0002.152F] # CANADIAN SYLLABICS YWE +1530 ; [.2BA4.0020.0002.1530] # CANADIAN SYLLABICS WEST-CREE YWE +1531 ; [.2BA5.0020.0002.1531] # CANADIAN SYLLABICS YWI +1532 ; [.2BA6.0020.0002.1532] # CANADIAN SYLLABICS WEST-CREE YWI +1533 ; [.2BA7.0020.0002.1533] # CANADIAN SYLLABICS YWII +1534 ; [.2BA8.0020.0002.1534] # CANADIAN SYLLABICS WEST-CREE YWII +1535 ; [.2BA9.0020.0002.1535] # CANADIAN SYLLABICS YWO +1536 ; [.2BAA.0020.0002.1536] # CANADIAN SYLLABICS WEST-CREE YWO +1537 ; [.2BAB.0020.0002.1537] # CANADIAN SYLLABICS YWOO +1538 ; [.2BAC.0020.0002.1538] # CANADIAN SYLLABICS WEST-CREE YWOO +1539 ; [.2BAD.0020.0002.1539] # CANADIAN SYLLABICS YWA +153A ; [.2BAE.0020.0002.153A] # CANADIAN SYLLABICS WEST-CREE YWA +153B ; [.2BAF.0020.0002.153B] # CANADIAN SYLLABICS YWAA +153C ; [.2BB0.0020.0002.153C] # CANADIAN SYLLABICS WEST-CREE YWAA +153D ; [.2BB1.0020.0002.153D] # CANADIAN SYLLABICS NASKAPI YWAA +153E ; [.2BB2.0020.0002.153E] # CANADIAN SYLLABICS Y +153F ; [.2BB3.0020.0002.153F] # CANADIAN SYLLABICS BIBLE-CREE Y +1540 ; [.2BB4.0020.0002.1540] # CANADIAN SYLLABICS WEST-CREE Y +1541 ; [.2BB5.0020.0002.1541] # CANADIAN SYLLABICS SAYISI YI +1542 ; [.2BB6.0020.0002.1542] # CANADIAN SYLLABICS RE +1543 ; [.2BB7.0020.0002.1543] # CANADIAN SYLLABICS R-CREE RE +1544 ; [.2BB8.0020.0002.1544] # CANADIAN SYLLABICS WEST-CREE LE +1545 ; [.2BB9.0020.0002.1545] # CANADIAN SYLLABICS RAAI +1546 ; [.2BBA.0020.0002.1546] # CANADIAN SYLLABICS RI +1547 ; [.2BBB.0020.0002.1547] # CANADIAN SYLLABICS RII +1548 ; [.2BBC.0020.0002.1548] # CANADIAN SYLLABICS RO +1549 ; [.2BBD.0020.0002.1549] # CANADIAN SYLLABICS ROO +154A ; [.2BBE.0020.0002.154A] # CANADIAN SYLLABICS WEST-CREE LO +154B ; [.2BBF.0020.0002.154B] # CANADIAN SYLLABICS RA +154C ; [.2BC0.0020.0002.154C] # CANADIAN SYLLABICS RAA +154D ; [.2BC1.0020.0002.154D] # CANADIAN SYLLABICS WEST-CREE LA +154E ; [.2BC2.0020.0002.154E] # CANADIAN SYLLABICS RWAA +154F ; [.2BC3.0020.0002.154F] # CANADIAN SYLLABICS WEST-CREE RWAA +1550 ; [.2BC4.0020.0002.1550] # CANADIAN SYLLABICS R +1551 ; [.2BC5.0020.0002.1551] # CANADIAN SYLLABICS WEST-CREE R +1552 ; [.2BC6.0020.0002.1552] # CANADIAN SYLLABICS MEDIAL R +1553 ; [.2BC7.0020.0002.1553] # CANADIAN SYLLABICS FE +1554 ; [.2BC8.0020.0002.1554] # CANADIAN SYLLABICS FAAI +1555 ; [.2BC9.0020.0002.1555] # CANADIAN SYLLABICS FI +1556 ; [.2BCA.0020.0002.1556] # CANADIAN SYLLABICS FII +1557 ; [.2BCB.0020.0002.1557] # CANADIAN SYLLABICS FO +1558 ; [.2BCC.0020.0002.1558] # CANADIAN SYLLABICS FOO +1559 ; [.2BCD.0020.0002.1559] # CANADIAN SYLLABICS FA +155A ; [.2BCE.0020.0002.155A] # CANADIAN SYLLABICS FAA +155B ; [.2BCF.0020.0002.155B] # CANADIAN SYLLABICS FWAA +155C ; [.2BD0.0020.0002.155C] # CANADIAN SYLLABICS WEST-CREE FWAA +155D ; [.2BD1.0020.0002.155D] # CANADIAN SYLLABICS F +155E ; [.2BD2.0020.0002.155E] # CANADIAN SYLLABICS THE +155F ; [.2BD3.0020.0002.155F] # CANADIAN SYLLABICS N-CREE THE +1560 ; [.2BD4.0020.0002.1560] # CANADIAN SYLLABICS THI +1561 ; [.2BD5.0020.0002.1561] # CANADIAN SYLLABICS N-CREE THI +1562 ; [.2BD6.0020.0002.1562] # CANADIAN SYLLABICS THII +1563 ; [.2BD7.0020.0002.1563] # CANADIAN SYLLABICS N-CREE THII +1564 ; [.2BD8.0020.0002.1564] # CANADIAN SYLLABICS THO +1565 ; [.2BD9.0020.0002.1565] # CANADIAN SYLLABICS THOO +1566 ; [.2BDA.0020.0002.1566] # CANADIAN SYLLABICS THA +1567 ; [.2BDB.0020.0002.1567] # CANADIAN SYLLABICS THAA +1568 ; [.2BDC.0020.0002.1568] # CANADIAN SYLLABICS THWAA +1569 ; [.2BDD.0020.0002.1569] # CANADIAN SYLLABICS WEST-CREE THWAA +156A ; [.2BDE.0020.0002.156A] # CANADIAN SYLLABICS TH +156B ; [.2BDF.0020.0002.156B] # CANADIAN SYLLABICS TTHE +156C ; [.2BE0.0020.0002.156C] # CANADIAN SYLLABICS TTHI +156D ; [.2BE1.0020.0002.156D] # CANADIAN SYLLABICS TTHO +156E ; [.2BE2.0020.0002.156E] # CANADIAN SYLLABICS TTHA +156F ; [.2BE3.0020.0002.156F] # CANADIAN SYLLABICS TTH +1570 ; [.2BE4.0020.0002.1570] # CANADIAN SYLLABICS TYE +1571 ; [.2BE5.0020.0002.1571] # CANADIAN SYLLABICS TYI +1572 ; [.2BE6.0020.0002.1572] # CANADIAN SYLLABICS TYO +1573 ; [.2BE7.0020.0002.1573] # CANADIAN SYLLABICS TYA +1574 ; [.2BE8.0020.0002.1574] # CANADIAN SYLLABICS NUNAVIK HE +1575 ; [.2BE9.0020.0002.1575] # CANADIAN SYLLABICS NUNAVIK HI +1576 ; [.2BEA.0020.0002.1576] # CANADIAN SYLLABICS NUNAVIK HII +1577 ; [.2BEB.0020.0002.1577] # CANADIAN SYLLABICS NUNAVIK HO +1578 ; [.2BEC.0020.0002.1578] # CANADIAN SYLLABICS NUNAVIK HOO +1579 ; [.2BED.0020.0002.1579] # CANADIAN SYLLABICS NUNAVIK HA +157A ; [.2BEE.0020.0002.157A] # CANADIAN SYLLABICS NUNAVIK HAA +157B ; [.2BEF.0020.0002.157B] # CANADIAN SYLLABICS NUNAVIK H +157D ; [.2BF0.0020.0002.157D] # CANADIAN SYLLABICS HK +166F ; [.2BF1.0020.0002.166F] # CANADIAN SYLLABICS QAI +157E ; [.2BF2.0020.0002.157E] # CANADIAN SYLLABICS QAAI +157F ; [.2BF3.0020.0002.157F] # CANADIAN SYLLABICS QI +1580 ; [.2BF4.0020.0002.1580] # CANADIAN SYLLABICS QII +1581 ; [.2BF5.0020.0002.1581] # CANADIAN SYLLABICS QO +1582 ; [.2BF6.0020.0002.1582] # CANADIAN SYLLABICS QOO +1583 ; [.2BF7.0020.0002.1583] # CANADIAN SYLLABICS QA +1584 ; [.2BF8.0020.0002.1584] # CANADIAN SYLLABICS QAA +1585 ; [.2BF9.0020.0002.1585] # CANADIAN SYLLABICS Q +1586 ; [.2BFA.0020.0002.1586] # CANADIAN SYLLABICS TLHE +1587 ; [.2BFB.0020.0002.1587] # CANADIAN SYLLABICS TLHI +1588 ; [.2BFC.0020.0002.1588] # CANADIAN SYLLABICS TLHO +1589 ; [.2BFD.0020.0002.1589] # CANADIAN SYLLABICS TLHA +158A ; [.2BFE.0020.0002.158A] # CANADIAN SYLLABICS WEST-CREE RE +158B ; [.2BFF.0020.0002.158B] # CANADIAN SYLLABICS WEST-CREE RI +158C ; [.2C00.0020.0002.158C] # CANADIAN SYLLABICS WEST-CREE RO +158D ; [.2C01.0020.0002.158D] # CANADIAN SYLLABICS WEST-CREE RA +1670 ; [.2C02.0020.0002.1670] # CANADIAN SYLLABICS NGAI +158E ; [.2C03.0020.0002.158E] # CANADIAN SYLLABICS NGAAI +158F ; [.2C04.0020.0002.158F] # CANADIAN SYLLABICS NGI +1590 ; [.2C05.0020.0002.1590] # CANADIAN SYLLABICS NGII +1591 ; [.2C06.0020.0002.1591] # CANADIAN SYLLABICS NGO +1592 ; [.2C07.0020.0002.1592] # CANADIAN SYLLABICS NGOO +1593 ; [.2C08.0020.0002.1593] # CANADIAN SYLLABICS NGA +1594 ; [.2C09.0020.0002.1594] # CANADIAN SYLLABICS NGAA +1595 ; [.2C0A.0020.0002.1595] # CANADIAN SYLLABICS NG +1671 ; [.2C0B.0020.0002.1671] # CANADIAN SYLLABICS NNGI +1672 ; [.2C0C.0020.0002.1672] # CANADIAN SYLLABICS NNGII +1673 ; [.2C0D.0020.0002.1673] # CANADIAN SYLLABICS NNGO +1674 ; [.2C0E.0020.0002.1674] # CANADIAN SYLLABICS NNGOO +1675 ; [.2C0F.0020.0002.1675] # CANADIAN SYLLABICS NNGA +1676 ; [.2C10.0020.0002.1676] # CANADIAN SYLLABICS NNGAA +1596 ; [.2C11.0020.0002.1596] # CANADIAN SYLLABICS NNG +1597 ; [.2C12.0020.0002.1597] # CANADIAN SYLLABICS SAYISI SHE +1598 ; [.2C13.0020.0002.1598] # CANADIAN SYLLABICS SAYISI SHI +1599 ; [.2C14.0020.0002.1599] # CANADIAN SYLLABICS SAYISI SHO +159A ; [.2C15.0020.0002.159A] # CANADIAN SYLLABICS SAYISI SHA +159B ; [.2C16.0020.0002.159B] # CANADIAN SYLLABICS WOODS-CREE THE +159C ; [.2C17.0020.0002.159C] # CANADIAN SYLLABICS WOODS-CREE THI +159D ; [.2C18.0020.0002.159D] # CANADIAN SYLLABICS WOODS-CREE THO +159E ; [.2C19.0020.0002.159E] # CANADIAN SYLLABICS WOODS-CREE THA +159F ; [.2C1A.0020.0002.159F] # CANADIAN SYLLABICS WOODS-CREE TH +15A0 ; [.2C1B.0020.0002.15A0] # CANADIAN SYLLABICS LHI +15A1 ; [.2C1C.0020.0002.15A1] # CANADIAN SYLLABICS LHII +15A2 ; [.2C1D.0020.0002.15A2] # CANADIAN SYLLABICS LHO +15A3 ; [.2C1E.0020.0002.15A3] # CANADIAN SYLLABICS LHOO +15A4 ; [.2C1F.0020.0002.15A4] # CANADIAN SYLLABICS LHA +15A5 ; [.2C20.0020.0002.15A5] # CANADIAN SYLLABICS LHAA +15A6 ; [.2C21.0020.0002.15A6] # CANADIAN SYLLABICS LH +157C ; [.2C22.0020.0002.157C] # CANADIAN SYLLABICS NUNAVUT H +15A7 ; [.2C23.0020.0002.15A7] # CANADIAN SYLLABICS TH-CREE THE +15A8 ; [.2C24.0020.0002.15A8] # CANADIAN SYLLABICS TH-CREE THI +15A9 ; [.2C25.0020.0002.15A9] # CANADIAN SYLLABICS TH-CREE THII +15AA ; [.2C26.0020.0002.15AA] # CANADIAN SYLLABICS TH-CREE THO +15AB ; [.2C27.0020.0002.15AB] # CANADIAN SYLLABICS TH-CREE THOO +15AC ; [.2C28.0020.0002.15AC] # CANADIAN SYLLABICS TH-CREE THA +15AD ; [.2C29.0020.0002.15AD] # CANADIAN SYLLABICS TH-CREE THAA +15AE ; [.2C2A.0020.0002.15AE] # CANADIAN SYLLABICS TH-CREE TH +15AF ; [.2C2B.0020.0002.15AF] # CANADIAN SYLLABICS AIVILIK B +15B0 ; [.2C2C.0020.0002.15B0] # CANADIAN SYLLABICS BLACKFOOT E +15B1 ; [.2C2D.0020.0002.15B1] # CANADIAN SYLLABICS BLACKFOOT I +15B2 ; [.2C2E.0020.0002.15B2] # CANADIAN SYLLABICS BLACKFOOT O +15B3 ; [.2C2F.0020.0002.15B3] # CANADIAN SYLLABICS BLACKFOOT A +15B4 ; [.2C30.0020.0002.15B4] # CANADIAN SYLLABICS BLACKFOOT WE +15B5 ; [.2C31.0020.0002.15B5] # CANADIAN SYLLABICS BLACKFOOT WI +15B6 ; [.2C32.0020.0002.15B6] # CANADIAN SYLLABICS BLACKFOOT WO +15B7 ; [.2C33.0020.0002.15B7] # CANADIAN SYLLABICS BLACKFOOT WA +15B8 ; [.2C34.0020.0002.15B8] # CANADIAN SYLLABICS BLACKFOOT NE +15B9 ; [.2C35.0020.0002.15B9] # CANADIAN SYLLABICS BLACKFOOT NI +15BA ; [.2C36.0020.0002.15BA] # CANADIAN SYLLABICS BLACKFOOT NO +15BB ; [.2C37.0020.0002.15BB] # CANADIAN SYLLABICS BLACKFOOT NA +15BC ; [.2C38.0020.0002.15BC] # CANADIAN SYLLABICS BLACKFOOT KE +15BD ; [.2C39.0020.0002.15BD] # CANADIAN SYLLABICS BLACKFOOT KI +15BE ; [.2C3A.0020.0002.15BE] # CANADIAN SYLLABICS BLACKFOOT KO +15BF ; [.2C3B.0020.0002.15BF] # CANADIAN SYLLABICS BLACKFOOT KA +15C0 ; [.2C3C.0020.0002.15C0] # CANADIAN SYLLABICS SAYISI HE +15C1 ; [.2C3D.0020.0002.15C1] # CANADIAN SYLLABICS SAYISI HI +15C2 ; [.2C3E.0020.0002.15C2] # CANADIAN SYLLABICS SAYISI HO +15C3 ; [.2C3F.0020.0002.15C3] # CANADIAN SYLLABICS SAYISI HA +15C4 ; [.2C40.0020.0002.15C4] # CANADIAN SYLLABICS CARRIER GHU +15C5 ; [.2C41.0020.0002.15C5] # CANADIAN SYLLABICS CARRIER GHO +15C6 ; [.2C42.0020.0002.15C6] # CANADIAN SYLLABICS CARRIER GHE +15C7 ; [.2C43.0020.0002.15C7] # CANADIAN SYLLABICS CARRIER GHEE +15C8 ; [.2C44.0020.0002.15C8] # CANADIAN SYLLABICS CARRIER GHI +15C9 ; [.2C45.0020.0002.15C9] # CANADIAN SYLLABICS CARRIER GHA +15CA ; [.2C46.0020.0002.15CA] # CANADIAN SYLLABICS CARRIER RU +15CB ; [.2C47.0020.0002.15CB] # CANADIAN SYLLABICS CARRIER RO +15CC ; [.2C48.0020.0002.15CC] # CANADIAN SYLLABICS CARRIER RE +15CD ; [.2C49.0020.0002.15CD] # CANADIAN SYLLABICS CARRIER REE +15CE ; [.2C4A.0020.0002.15CE] # CANADIAN SYLLABICS CARRIER RI +15CF ; [.2C4B.0020.0002.15CF] # CANADIAN SYLLABICS CARRIER RA +15D0 ; [.2C4C.0020.0002.15D0] # CANADIAN SYLLABICS CARRIER WU +15D1 ; [.2C4D.0020.0002.15D1] # CANADIAN SYLLABICS CARRIER WO +15D2 ; [.2C4E.0020.0002.15D2] # CANADIAN SYLLABICS CARRIER WE +15D3 ; [.2C4F.0020.0002.15D3] # CANADIAN SYLLABICS CARRIER WEE +15D4 ; [.2C50.0020.0002.15D4] # CANADIAN SYLLABICS CARRIER WI +15D5 ; [.2C51.0020.0002.15D5] # CANADIAN SYLLABICS CARRIER WA +15D6 ; [.2C52.0020.0002.15D6] # CANADIAN SYLLABICS CARRIER HWU +15D7 ; [.2C53.0020.0002.15D7] # CANADIAN SYLLABICS CARRIER HWO +15D8 ; [.2C54.0020.0002.15D8] # CANADIAN SYLLABICS CARRIER HWE +15D9 ; [.2C55.0020.0002.15D9] # CANADIAN SYLLABICS CARRIER HWEE +15DA ; [.2C56.0020.0002.15DA] # CANADIAN SYLLABICS CARRIER HWI +15DB ; [.2C57.0020.0002.15DB] # CANADIAN SYLLABICS CARRIER HWA +15DC ; [.2C58.0020.0002.15DC] # CANADIAN SYLLABICS CARRIER THU +15DD ; [.2C59.0020.0002.15DD] # CANADIAN SYLLABICS CARRIER THO +15DE ; [.2C5A.0020.0002.15DE] # CANADIAN SYLLABICS CARRIER THE +15DF ; [.2C5B.0020.0002.15DF] # CANADIAN SYLLABICS CARRIER THEE +15E0 ; [.2C5C.0020.0002.15E0] # CANADIAN SYLLABICS CARRIER THI +15E1 ; [.2C5D.0020.0002.15E1] # CANADIAN SYLLABICS CARRIER THA +15E2 ; [.2C5E.0020.0002.15E2] # CANADIAN SYLLABICS CARRIER TTU +15E3 ; [.2C5F.0020.0002.15E3] # CANADIAN SYLLABICS CARRIER TTO +15E4 ; [.2C60.0020.0002.15E4] # CANADIAN SYLLABICS CARRIER TTE +15E5 ; [.2C61.0020.0002.15E5] # CANADIAN SYLLABICS CARRIER TTEE +15E6 ; [.2C62.0020.0002.15E6] # CANADIAN SYLLABICS CARRIER TTI +15E7 ; [.2C63.0020.0002.15E7] # CANADIAN SYLLABICS CARRIER TTA +15E8 ; [.2C64.0020.0002.15E8] # CANADIAN SYLLABICS CARRIER PU +15E9 ; [.2C65.0020.0002.15E9] # CANADIAN SYLLABICS CARRIER PO +15EA ; [.2C66.0020.0002.15EA] # CANADIAN SYLLABICS CARRIER PE +15EB ; [.2C67.0020.0002.15EB] # CANADIAN SYLLABICS CARRIER PEE +15EC ; [.2C68.0020.0002.15EC] # CANADIAN SYLLABICS CARRIER PI +15ED ; [.2C69.0020.0002.15ED] # CANADIAN SYLLABICS CARRIER PA +15EE ; [.2C6A.0020.0002.15EE] # CANADIAN SYLLABICS CARRIER P +15EF ; [.2C6B.0020.0002.15EF] # CANADIAN SYLLABICS CARRIER GU +15F0 ; [.2C6C.0020.0002.15F0] # CANADIAN SYLLABICS CARRIER GO +15F1 ; [.2C6D.0020.0002.15F1] # CANADIAN SYLLABICS CARRIER GE +15F2 ; [.2C6E.0020.0002.15F2] # CANADIAN SYLLABICS CARRIER GEE +15F3 ; [.2C6F.0020.0002.15F3] # CANADIAN SYLLABICS CARRIER GI +15F4 ; [.2C70.0020.0002.15F4] # CANADIAN SYLLABICS CARRIER GA +15F5 ; [.2C71.0020.0002.15F5] # CANADIAN SYLLABICS CARRIER KHU +15F6 ; [.2C72.0020.0002.15F6] # CANADIAN SYLLABICS CARRIER KHO +15F7 ; [.2C73.0020.0002.15F7] # CANADIAN SYLLABICS CARRIER KHE +15F8 ; [.2C74.0020.0002.15F8] # CANADIAN SYLLABICS CARRIER KHEE +15F9 ; [.2C75.0020.0002.15F9] # CANADIAN SYLLABICS CARRIER KHI +15FA ; [.2C76.0020.0002.15FA] # CANADIAN SYLLABICS CARRIER KHA +15FB ; [.2C77.0020.0002.15FB] # CANADIAN SYLLABICS CARRIER KKU +15FC ; [.2C78.0020.0002.15FC] # CANADIAN SYLLABICS CARRIER KKO +15FD ; [.2C79.0020.0002.15FD] # CANADIAN SYLLABICS CARRIER KKE +15FE ; [.2C7A.0020.0002.15FE] # CANADIAN SYLLABICS CARRIER KKEE +15FF ; [.2C7B.0020.0002.15FF] # CANADIAN SYLLABICS CARRIER KKI +1600 ; [.2C7C.0020.0002.1600] # CANADIAN SYLLABICS CARRIER KKA +1601 ; [.2C7D.0020.0002.1601] # CANADIAN SYLLABICS CARRIER KK +1602 ; [.2C7E.0020.0002.1602] # CANADIAN SYLLABICS CARRIER NU +1603 ; [.2C7F.0020.0002.1603] # CANADIAN SYLLABICS CARRIER NO +1604 ; [.2C80.0020.0002.1604] # CANADIAN SYLLABICS CARRIER NE +1605 ; [.2C81.0020.0002.1605] # CANADIAN SYLLABICS CARRIER NEE +1606 ; [.2C82.0020.0002.1606] # CANADIAN SYLLABICS CARRIER NI +1607 ; [.2C83.0020.0002.1607] # CANADIAN SYLLABICS CARRIER NA +1608 ; [.2C84.0020.0002.1608] # CANADIAN SYLLABICS CARRIER MU +1609 ; [.2C85.0020.0002.1609] # CANADIAN SYLLABICS CARRIER MO +160A ; [.2C86.0020.0002.160A] # CANADIAN SYLLABICS CARRIER ME +160B ; [.2C87.0020.0002.160B] # CANADIAN SYLLABICS CARRIER MEE +160C ; [.2C88.0020.0002.160C] # CANADIAN SYLLABICS CARRIER MI +160D ; [.2C89.0020.0002.160D] # CANADIAN SYLLABICS CARRIER MA +160E ; [.2C8A.0020.0002.160E] # CANADIAN SYLLABICS CARRIER YU +160F ; [.2C8B.0020.0002.160F] # CANADIAN SYLLABICS CARRIER YO +1610 ; [.2C8C.0020.0002.1610] # CANADIAN SYLLABICS CARRIER YE +1611 ; [.2C8D.0020.0002.1611] # CANADIAN SYLLABICS CARRIER YEE +1612 ; [.2C8E.0020.0002.1612] # CANADIAN SYLLABICS CARRIER YI +1613 ; [.2C8F.0020.0002.1613] # CANADIAN SYLLABICS CARRIER YA +1614 ; [.2C90.0020.0002.1614] # CANADIAN SYLLABICS CARRIER JU +1615 ; [.2C91.0020.0002.1615] # CANADIAN SYLLABICS SAYISI JU +1616 ; [.2C92.0020.0002.1616] # CANADIAN SYLLABICS CARRIER JO +1617 ; [.2C93.0020.0002.1617] # CANADIAN SYLLABICS CARRIER JE +1618 ; [.2C94.0020.0002.1618] # CANADIAN SYLLABICS CARRIER JEE +1619 ; [.2C95.0020.0002.1619] # CANADIAN SYLLABICS CARRIER JI +161A ; [.2C96.0020.0002.161A] # CANADIAN SYLLABICS SAYISI JI +161B ; [.2C97.0020.0002.161B] # CANADIAN SYLLABICS CARRIER JA +161C ; [.2C98.0020.0002.161C] # CANADIAN SYLLABICS CARRIER JJU +161D ; [.2C99.0020.0002.161D] # CANADIAN SYLLABICS CARRIER JJO +161E ; [.2C9A.0020.0002.161E] # CANADIAN SYLLABICS CARRIER JJE +161F ; [.2C9B.0020.0002.161F] # CANADIAN SYLLABICS CARRIER JJEE +1620 ; [.2C9C.0020.0002.1620] # CANADIAN SYLLABICS CARRIER JJI +1621 ; [.2C9D.0020.0002.1621] # CANADIAN SYLLABICS CARRIER JJA +1622 ; [.2C9E.0020.0002.1622] # CANADIAN SYLLABICS CARRIER LU +1623 ; [.2C9F.0020.0002.1623] # CANADIAN SYLLABICS CARRIER LO +1624 ; [.2CA0.0020.0002.1624] # CANADIAN SYLLABICS CARRIER LE +1625 ; [.2CA1.0020.0002.1625] # CANADIAN SYLLABICS CARRIER LEE +1626 ; [.2CA2.0020.0002.1626] # CANADIAN SYLLABICS CARRIER LI +1627 ; [.2CA3.0020.0002.1627] # CANADIAN SYLLABICS CARRIER LA +1628 ; [.2CA4.0020.0002.1628] # CANADIAN SYLLABICS CARRIER DLU +1629 ; [.2CA5.0020.0002.1629] # CANADIAN SYLLABICS CARRIER DLO +162A ; [.2CA6.0020.0002.162A] # CANADIAN SYLLABICS CARRIER DLE +162B ; [.2CA7.0020.0002.162B] # CANADIAN SYLLABICS CARRIER DLEE +162C ; [.2CA8.0020.0002.162C] # CANADIAN SYLLABICS CARRIER DLI +162D ; [.2CA9.0020.0002.162D] # CANADIAN SYLLABICS CARRIER DLA +162E ; [.2CAA.0020.0002.162E] # CANADIAN SYLLABICS CARRIER LHU +162F ; [.2CAB.0020.0002.162F] # CANADIAN SYLLABICS CARRIER LHO +1630 ; [.2CAC.0020.0002.1630] # CANADIAN SYLLABICS CARRIER LHE +1631 ; [.2CAD.0020.0002.1631] # CANADIAN SYLLABICS CARRIER LHEE +1632 ; [.2CAE.0020.0002.1632] # CANADIAN SYLLABICS CARRIER LHI +1633 ; [.2CAF.0020.0002.1633] # CANADIAN SYLLABICS CARRIER LHA +1634 ; [.2CB0.0020.0002.1634] # CANADIAN SYLLABICS CARRIER TLHU +1635 ; [.2CB1.0020.0002.1635] # CANADIAN SYLLABICS CARRIER TLHO +1636 ; [.2CB2.0020.0002.1636] # CANADIAN SYLLABICS CARRIER TLHE +1637 ; [.2CB3.0020.0002.1637] # CANADIAN SYLLABICS CARRIER TLHEE +1638 ; [.2CB4.0020.0002.1638] # CANADIAN SYLLABICS CARRIER TLHI +1639 ; [.2CB5.0020.0002.1639] # CANADIAN SYLLABICS CARRIER TLHA +163A ; [.2CB6.0020.0002.163A] # CANADIAN SYLLABICS CARRIER TLU +163B ; [.2CB7.0020.0002.163B] # CANADIAN SYLLABICS CARRIER TLO +163C ; [.2CB8.0020.0002.163C] # CANADIAN SYLLABICS CARRIER TLE +163D ; [.2CB9.0020.0002.163D] # CANADIAN SYLLABICS CARRIER TLEE +163E ; [.2CBA.0020.0002.163E] # CANADIAN SYLLABICS CARRIER TLI +163F ; [.2CBB.0020.0002.163F] # CANADIAN SYLLABICS CARRIER TLA +1640 ; [.2CBC.0020.0002.1640] # CANADIAN SYLLABICS CARRIER ZU +1641 ; [.2CBD.0020.0002.1641] # CANADIAN SYLLABICS CARRIER ZO +1642 ; [.2CBE.0020.0002.1642] # CANADIAN SYLLABICS CARRIER ZE +1643 ; [.2CBF.0020.0002.1643] # CANADIAN SYLLABICS CARRIER ZEE +1644 ; [.2CC0.0020.0002.1644] # CANADIAN SYLLABICS CARRIER ZI +1645 ; [.2CC1.0020.0002.1645] # CANADIAN SYLLABICS CARRIER ZA +1646 ; [.2CC2.0020.0002.1646] # CANADIAN SYLLABICS CARRIER Z +1647 ; [.2CC3.0020.0002.1647] # CANADIAN SYLLABICS CARRIER INITIAL Z +1648 ; [.2CC4.0020.0002.1648] # CANADIAN SYLLABICS CARRIER DZU +1649 ; [.2CC5.0020.0002.1649] # CANADIAN SYLLABICS CARRIER DZO +164A ; [.2CC6.0020.0002.164A] # CANADIAN SYLLABICS CARRIER DZE +164B ; [.2CC7.0020.0002.164B] # CANADIAN SYLLABICS CARRIER DZEE +164C ; [.2CC8.0020.0002.164C] # CANADIAN SYLLABICS CARRIER DZI +164D ; [.2CC9.0020.0002.164D] # CANADIAN SYLLABICS CARRIER DZA +164E ; [.2CCA.0020.0002.164E] # CANADIAN SYLLABICS CARRIER SU +164F ; [.2CCB.0020.0002.164F] # CANADIAN SYLLABICS CARRIER SO +1650 ; [.2CCC.0020.0002.1650] # CANADIAN SYLLABICS CARRIER SE +1651 ; [.2CCD.0020.0002.1651] # CANADIAN SYLLABICS CARRIER SEE +1652 ; [.2CCE.0020.0002.1652] # CANADIAN SYLLABICS CARRIER SI +1653 ; [.2CCF.0020.0002.1653] # CANADIAN SYLLABICS CARRIER SA +1654 ; [.2CD0.0020.0002.1654] # CANADIAN SYLLABICS CARRIER SHU +1655 ; [.2CD1.0020.0002.1655] # CANADIAN SYLLABICS CARRIER SHO +1656 ; [.2CD2.0020.0002.1656] # CANADIAN SYLLABICS CARRIER SHE +1657 ; [.2CD3.0020.0002.1657] # CANADIAN SYLLABICS CARRIER SHEE +1658 ; [.2CD4.0020.0002.1658] # CANADIAN SYLLABICS CARRIER SHI +1659 ; [.2CD5.0020.0002.1659] # CANADIAN SYLLABICS CARRIER SHA +165A ; [.2CD6.0020.0002.165A] # CANADIAN SYLLABICS CARRIER SH +165B ; [.2CD7.0020.0002.165B] # CANADIAN SYLLABICS CARRIER TSU +165C ; [.2CD8.0020.0002.165C] # CANADIAN SYLLABICS CARRIER TSO +165D ; [.2CD9.0020.0002.165D] # CANADIAN SYLLABICS CARRIER TSE +165E ; [.2CDA.0020.0002.165E] # CANADIAN SYLLABICS CARRIER TSEE +165F ; [.2CDB.0020.0002.165F] # CANADIAN SYLLABICS CARRIER TSI +1660 ; [.2CDC.0020.0002.1660] # CANADIAN SYLLABICS CARRIER TSA +1661 ; [.2CDD.0020.0002.1661] # CANADIAN SYLLABICS CARRIER CHU +1662 ; [.2CDE.0020.0002.1662] # CANADIAN SYLLABICS CARRIER CHO +1663 ; [.2CDF.0020.0002.1663] # CANADIAN SYLLABICS CARRIER CHE +1664 ; [.2CE0.0020.0002.1664] # CANADIAN SYLLABICS CARRIER CHEE +1665 ; [.2CE1.0020.0002.1665] # CANADIAN SYLLABICS CARRIER CHI +1666 ; [.2CE2.0020.0002.1666] # CANADIAN SYLLABICS CARRIER CHA +1667 ; [.2CE3.0020.0002.1667] # CANADIAN SYLLABICS CARRIER TTSU +1668 ; [.2CE4.0020.0002.1668] # CANADIAN SYLLABICS CARRIER TTSO +1669 ; [.2CE5.0020.0002.1669] # CANADIAN SYLLABICS CARRIER TTSE +166A ; [.2CE6.0020.0002.166A] # CANADIAN SYLLABICS CARRIER TTSEE +166B ; [.2CE7.0020.0002.166B] # CANADIAN SYLLABICS CARRIER TTSI +166C ; [.2CE8.0020.0002.166C] # CANADIAN SYLLABICS CARRIER TTSA +1677 ; [.2CE9.0020.0002.1677] # CANADIAN SYLLABICS WOODS-CREE THWEE +1678 ; [.2CEA.0020.0002.1678] # CANADIAN SYLLABICS WOODS-CREE THWI +1679 ; [.2CEB.0020.0002.1679] # CANADIAN SYLLABICS WOODS-CREE THWII +167A ; [.2CEC.0020.0002.167A] # CANADIAN SYLLABICS WOODS-CREE THWO +167B ; [.2CED.0020.0002.167B] # CANADIAN SYLLABICS WOODS-CREE THWOO +167C ; [.2CEE.0020.0002.167C] # CANADIAN SYLLABICS WOODS-CREE THWA +167D ; [.2CEF.0020.0002.167D] # CANADIAN SYLLABICS WOODS-CREE THWAA +167E ; [.2CF0.0020.0002.167E] # CANADIAN SYLLABICS WOODS-CREE FINAL TH +167F ; [.2CF1.0020.0002.167F] # CANADIAN SYLLABICS BLACKFOOT W +18B0 ; [.2CF2.0020.0002.18B0] # CANADIAN SYLLABICS OY +18B1 ; [.2CF3.0020.0002.18B1] # CANADIAN SYLLABICS AY +18B2 ; [.2CF4.0020.0002.18B2] # CANADIAN SYLLABICS AAY +18B3 ; [.2CF5.0020.0002.18B3] # CANADIAN SYLLABICS WAY +18B4 ; [.2CF6.0020.0002.18B4] # CANADIAN SYLLABICS POY +18B5 ; [.2CF7.0020.0002.18B5] # CANADIAN SYLLABICS PAY +18B6 ; [.2CF8.0020.0002.18B6] # CANADIAN SYLLABICS PWOY +18B7 ; [.2CF9.0020.0002.18B7] # CANADIAN SYLLABICS TAY +18B8 ; [.2CFA.0020.0002.18B8] # CANADIAN SYLLABICS KAY +18B9 ; [.2CFB.0020.0002.18B9] # CANADIAN SYLLABICS KWAY +18BA ; [.2CFC.0020.0002.18BA] # CANADIAN SYLLABICS MAY +18BB ; [.2CFD.0020.0002.18BB] # CANADIAN SYLLABICS NOY +18BC ; [.2CFE.0020.0002.18BC] # CANADIAN SYLLABICS NAY +18BD ; [.2CFF.0020.0002.18BD] # CANADIAN SYLLABICS LAY +18BE ; [.2D00.0020.0002.18BE] # CANADIAN SYLLABICS SOY +18BF ; [.2D01.0020.0002.18BF] # CANADIAN SYLLABICS SAY +18C0 ; [.2D02.0020.0002.18C0] # CANADIAN SYLLABICS SHOY +18C1 ; [.2D03.0020.0002.18C1] # CANADIAN SYLLABICS SHAY +18C2 ; [.2D04.0020.0002.18C2] # CANADIAN SYLLABICS SHWOY +18C3 ; [.2D05.0020.0002.18C3] # CANADIAN SYLLABICS YOY +18C4 ; [.2D06.0020.0002.18C4] # CANADIAN SYLLABICS YAY +18C5 ; [.2D07.0020.0002.18C5] # CANADIAN SYLLABICS RAY +18C6 ; [.2D08.0020.0002.18C6] # CANADIAN SYLLABICS NWI +18C7 ; [.2D09.0020.0002.18C7] # CANADIAN SYLLABICS OJIBWAY NWI +18C8 ; [.2D0A.0020.0002.18C8] # CANADIAN SYLLABICS NWII +18C9 ; [.2D0B.0020.0002.18C9] # CANADIAN SYLLABICS OJIBWAY NWII +18CA ; [.2D0C.0020.0002.18CA] # CANADIAN SYLLABICS NWO +18CB ; [.2D0D.0020.0002.18CB] # CANADIAN SYLLABICS OJIBWAY NWO +18CC ; [.2D0E.0020.0002.18CC] # CANADIAN SYLLABICS NWOO +18CD ; [.2D0F.0020.0002.18CD] # CANADIAN SYLLABICS OJIBWAY NWOO +18CE ; [.2D10.0020.0002.18CE] # CANADIAN SYLLABICS RWEE +18CF ; [.2D11.0020.0002.18CF] # CANADIAN SYLLABICS RWI +18D0 ; [.2D12.0020.0002.18D0] # CANADIAN SYLLABICS RWII +18D1 ; [.2D13.0020.0002.18D1] # CANADIAN SYLLABICS RWO +18D2 ; [.2D14.0020.0002.18D2] # CANADIAN SYLLABICS RWOO +18D3 ; [.2D15.0020.0002.18D3] # CANADIAN SYLLABICS RWA +18D4 ; [.2D16.0020.0002.18D4] # CANADIAN SYLLABICS OJIBWAY P +18D5 ; [.2D17.0020.0002.18D5] # CANADIAN SYLLABICS OJIBWAY T +18D6 ; [.2D18.0020.0002.18D6] # CANADIAN SYLLABICS OJIBWAY K +18D7 ; [.2D19.0020.0002.18D7] # CANADIAN SYLLABICS OJIBWAY C +18D8 ; [.2D1A.0020.0002.18D8] # CANADIAN SYLLABICS OJIBWAY M +18D9 ; [.2D1B.0020.0002.18D9] # CANADIAN SYLLABICS OJIBWAY N +18DA ; [.2D1C.0020.0002.18DA] # CANADIAN SYLLABICS OJIBWAY S +18DB ; [.2D1D.0020.0002.18DB] # CANADIAN SYLLABICS OJIBWAY SH +18DC ; [.2D1E.0020.0002.18DC] # CANADIAN SYLLABICS EASTERN W +18DD ; [.2D1F.0020.0002.18DD] # CANADIAN SYLLABICS WESTERN W +18DE ; [.2D20.0020.0002.18DE] # CANADIAN SYLLABICS FINAL SMALL RING +18DF ; [.2D21.0020.0002.18DF] # CANADIAN SYLLABICS FINAL RAISED DOT +18E0 ; [.2D22.0020.0002.18E0] # CANADIAN SYLLABICS R-CREE RWE +18E1 ; [.2D23.0020.0002.18E1] # CANADIAN SYLLABICS WEST-CREE LOO +18E2 ; [.2D24.0020.0002.18E2] # CANADIAN SYLLABICS WEST-CREE LAA +18E3 ; [.2D25.0020.0002.18E3] # CANADIAN SYLLABICS THWE +18E4 ; [.2D26.0020.0002.18E4] # CANADIAN SYLLABICS THWA +18E5 ; [.2D27.0020.0002.18E5] # CANADIAN SYLLABICS TTHWE +18E6 ; [.2D28.0020.0002.18E6] # CANADIAN SYLLABICS TTHOO +18E7 ; [.2D29.0020.0002.18E7] # CANADIAN SYLLABICS TTHAA +18E8 ; [.2D2A.0020.0002.18E8] # CANADIAN SYLLABICS TLHWE +18E9 ; [.2D2B.0020.0002.18E9] # CANADIAN SYLLABICS TLHOO +18EA ; [.2D2C.0020.0002.18EA] # CANADIAN SYLLABICS SAYISI SHWE +18EB ; [.2D2D.0020.0002.18EB] # CANADIAN SYLLABICS SAYISI SHOO +18EC ; [.2D2E.0020.0002.18EC] # CANADIAN SYLLABICS SAYISI HOO +18ED ; [.2D2F.0020.0002.18ED] # CANADIAN SYLLABICS CARRIER GWU +18EE ; [.2D30.0020.0002.18EE] # CANADIAN SYLLABICS CARRIER DENE GEE +18EF ; [.2D31.0020.0002.18EF] # CANADIAN SYLLABICS CARRIER GAA +18F0 ; [.2D32.0020.0002.18F0] # CANADIAN SYLLABICS CARRIER GWA +18F1 ; [.2D33.0020.0002.18F1] # CANADIAN SYLLABICS SAYISI JUU +18F2 ; [.2D34.0020.0002.18F2] # CANADIAN SYLLABICS CARRIER JWA +18F3 ; [.2D35.0020.0002.18F3] # CANADIAN SYLLABICS BEAVER DENE L +18F4 ; [.2D36.0020.0002.18F4] # CANADIAN SYLLABICS BEAVER DENE R +18F5 ; [.2D37.0020.0002.18F5] # CANADIAN SYLLABICS CARRIER DENTAL S +1681 ; [.2D38.0020.0002.1681] # OGHAM LETTER BEITH +1682 ; [.2D39.0020.0002.1682] # OGHAM LETTER LUIS +1683 ; [.2D3A.0020.0002.1683] # OGHAM LETTER FEARN +1684 ; [.2D3B.0020.0002.1684] # OGHAM LETTER SAIL +1685 ; [.2D3C.0020.0002.1685] # OGHAM LETTER NION +1686 ; [.2D3D.0020.0002.1686] # OGHAM LETTER UATH +1687 ; [.2D3E.0020.0002.1687] # OGHAM LETTER DAIR +1688 ; [.2D3F.0020.0002.1688] # OGHAM LETTER TINNE +1689 ; [.2D40.0020.0002.1689] # OGHAM LETTER COLL +168A ; [.2D41.0020.0002.168A] # OGHAM LETTER CEIRT +168B ; [.2D42.0020.0002.168B] # OGHAM LETTER MUIN +168C ; [.2D43.0020.0002.168C] # OGHAM LETTER GORT +168D ; [.2D44.0020.0002.168D] # OGHAM LETTER NGEADAL +168E ; [.2D45.0020.0002.168E] # OGHAM LETTER STRAIF +168F ; [.2D46.0020.0002.168F] # OGHAM LETTER RUIS +1690 ; [.2D47.0020.0002.1690] # OGHAM LETTER AILM +1691 ; [.2D48.0020.0002.1691] # OGHAM LETTER ONN +1692 ; [.2D49.0020.0002.1692] # OGHAM LETTER UR +1693 ; [.2D4A.0020.0002.1693] # OGHAM LETTER EADHADH +1694 ; [.2D4B.0020.0002.1694] # OGHAM LETTER IODHADH +1695 ; [.2D4C.0020.0002.1695] # OGHAM LETTER EABHADH +1696 ; [.2D4D.0020.0002.1696] # OGHAM LETTER OR +1697 ; [.2D4E.0020.0002.1697] # OGHAM LETTER UILLEANN +1698 ; [.2D4F.0020.0002.1698] # OGHAM LETTER IFIN +1699 ; [.2D50.0020.0002.1699] # OGHAM LETTER EAMHANCHOLL +169A ; [.2D51.0020.0002.169A] # OGHAM LETTER PEITH +16A0 ; [.2D52.0020.0002.16A0] # RUNIC LETTER FEHU FEOH FE F +16A1 ; [.2D52.0020.0004.16A1][.0000.0139.0004.16A1] # RUNIC LETTER V +16A2 ; [.2D53.0020.0002.16A2] # RUNIC LETTER URUZ UR U +16A4 ; [.2D53.0020.0004.16A4][.0000.0139.0004.16A4] # RUNIC LETTER Y +16A5 ; [.2D53.0020.0004.16A5][.0000.013A.0004.16A5] # RUNIC LETTER W +16A6 ; [.2D54.0020.0002.16A6] # RUNIC LETTER THURISAZ THURS THORN +16A7 ; [.2D54.0020.0004.16A7][.0000.0139.0004.16A7] # RUNIC LETTER ETH +16F0 ; [.2D54.0020.0004.16F0][.2D54.0020.0004.16F0] # RUNIC BELGTHOR SYMBOL +16A8 ; [.2D55.0020.0002.16A8] # RUNIC LETTER ANSUZ A +16A9 ; [.2D55.0020.0004.16A9][.0000.0139.0004.16A9] # RUNIC LETTER OS O +16AC ; [.2D55.0020.0004.16AC][.0000.013A.0004.16AC] # RUNIC LETTER LONG-BRANCH-OSS O +16AD ; [.2D55.0020.0004.16AD][.0000.013C.0004.16AD] # RUNIC LETTER SHORT-TWIG-OSS O +16AE ; [.2D55.0020.0004.16AE][.0000.013D.0004.16AE] # RUNIC LETTER O +16AF ; [.2D56.0020.0002.16AF] # RUNIC LETTER OE +16B0 ; [.2D57.0020.0002.16B0] # RUNIC LETTER ON +16B1 ; [.2D58.0020.0002.16B1] # RUNIC LETTER RAIDO RAD REID R +16B2 ; [.2D59.0020.0002.16B2] # RUNIC LETTER KAUNA +16B3 ; [.2D59.0020.0004.16B3][.0000.0139.0004.16B3] # RUNIC LETTER CEN +16B4 ; [.2D59.0020.0004.16B4][.0000.013A.0004.16B4] # RUNIC LETTER KAUN K +16B5 ; [.2D59.0020.0004.16B5][.0000.013C.0004.16B5] # RUNIC LETTER G +16B6 ; [.2D59.0020.0004.16B6][.0000.013D.0004.16B6] # RUNIC LETTER ENG +16B7 ; [.2D5A.0020.0002.16B7] # RUNIC LETTER GEBO GYFU G +16B9 ; [.2D5B.0020.0002.16B9] # RUNIC LETTER WUNJO WYNN W +16E9 ; [.2D5B.0020.0004.16E9][.0000.0139.0004.16E9] # RUNIC LETTER Q +16BA ; [.2D5C.0020.0002.16BA] # RUNIC LETTER HAGLAZ H +16BB ; [.2D5C.0020.0004.16BB][.0000.0139.0004.16BB] # RUNIC LETTER HAEGL H +16BC ; [.2D5C.0020.0004.16BC][.0000.013A.0004.16BC] # RUNIC LETTER LONG-BRANCH-HAGALL H +16BD ; [.2D5C.0020.0004.16BD][.0000.013C.0004.16BD] # RUNIC LETTER SHORT-TWIG-HAGALL H +16BE ; [.2D5D.0020.0002.16BE] # RUNIC LETTER NAUDIZ NYD NAUD N +16BF ; [.2D5D.0020.0004.16BF][.0000.0139.0004.16BF] # RUNIC LETTER SHORT-TWIG-NAUD N +16C0 ; [.2D5D.0020.0004.16C0][.0000.013A.0004.16C0] # RUNIC LETTER DOTTED-N +16C1 ; [.2D5E.0020.0002.16C1] # RUNIC LETTER ISAZ IS ISS I +16C2 ; [.2D5E.0020.0004.16C2][.0000.0139.0004.16C2] # RUNIC LETTER E +16C3 ; [.2D5F.0020.0002.16C3] # RUNIC LETTER JERAN J +16C4 ; [.2D5F.0020.0004.16C4][.0000.0139.0004.16C4] # RUNIC LETTER GER +16C5 ; [.2D60.0020.0002.16C5] # RUNIC LETTER LONG-BRANCH-AR AE +16C6 ; [.2D60.0020.0004.16C6][.0000.0139.0004.16C6] # RUNIC LETTER SHORT-TWIG-AR A +16EE ; [.2D60.0020.0004.16EE][.2D69.0020.0004.16EE] # RUNIC ARLAUG SYMBOL +16C7 ; [.2D61.0020.0002.16C7] # RUNIC LETTER IWAZ EOH +16C8 ; [.2D62.0020.0002.16C8] # RUNIC LETTER PERTHO PEORTH P +16D5 ; [.2D62.0020.0004.16D5][.0000.0139.0004.16D5] # RUNIC LETTER OPEN-P +16C9 ; [.2D63.0020.0002.16C9] # RUNIC LETTER ALGIZ EOLHX +16CA ; [.2D64.0020.0002.16CA] # RUNIC LETTER SOWILO S +16CB ; [.2D64.0020.0004.16CB][.0000.0139.0004.16CB] # RUNIC LETTER SIGEL LONG-BRANCH-SOL S +16EA ; [.2D64.0020.0004.16EA][.0000.013A.0004.16EA] # RUNIC LETTER X +16CC ; [.2D64.0020.0004.16CC][.0000.013C.0004.16CC] # RUNIC LETTER SHORT-TWIG-SOL S +16CD ; [.2D64.0020.0004.16CD][.0000.013D.0004.16CD] # RUNIC LETTER C +16CE ; [.2D64.0020.0004.16CE][.0000.013E.0004.16CE] # RUNIC LETTER Z +16CF ; [.2D65.0020.0002.16CF] # RUNIC LETTER TIWAZ TIR TYR T +16D0 ; [.2D65.0020.0004.16D0][.0000.0139.0004.16D0] # RUNIC LETTER SHORT-TWIG-TYR T +16D1 ; [.2D65.0020.0004.16D1][.0000.013A.0004.16D1] # RUNIC LETTER D +16D2 ; [.2D66.0020.0002.16D2] # RUNIC LETTER BERKANAN BEORC BJARKAN B +16D3 ; [.2D66.0020.0004.16D3][.0000.0139.0004.16D3] # RUNIC LETTER SHORT-TWIG-BJARKAN B +16D4 ; [.2D66.0020.0004.16D4][.0000.013A.0004.16D4] # RUNIC LETTER DOTTED-P +16D6 ; [.2D67.0020.0002.16D6] # RUNIC LETTER EHWAZ EH E +16D7 ; [.2D68.0020.0002.16D7] # RUNIC LETTER MANNAZ MAN M +16D8 ; [.2D68.0020.0004.16D8][.0000.0139.0004.16D8] # RUNIC LETTER LONG-BRANCH-MADR M +16D9 ; [.2D68.0020.0004.16D9][.0000.013A.0004.16D9] # RUNIC LETTER SHORT-TWIG-MADR M +16EF ; [.2D68.0020.0004.16EF][.0000.0139.0004.16EF][.2D68.0020.001F.16EF][.0000.0139.001F.16EF] # RUNIC TVIMADUR SYMBOL +16DA ; [.2D69.0020.0002.16DA] # RUNIC LETTER LAUKAZ LAGU LOGR L +16DB ; [.2D69.0020.0004.16DB][.0000.0139.0004.16DB] # RUNIC LETTER DOTTED-L +16DC ; [.2D6A.0020.0002.16DC] # RUNIC LETTER INGWAZ +16DD ; [.2D6A.0020.0004.16DD][.0000.0139.0004.16DD] # RUNIC LETTER ING +16DE ; [.2D6B.0020.0002.16DE] # RUNIC LETTER DAGAZ DAEG D +16DF ; [.2D6C.0020.0002.16DF] # RUNIC LETTER OTHALAN ETHEL O +16AA ; [.2D6D.0020.0002.16AA] # RUNIC LETTER AC A +16AB ; [.2D6E.0020.0002.16AB] # RUNIC LETTER AESC +16A3 ; [.2D6F.0020.0002.16A3] # RUNIC LETTER YR +16E0 ; [.2D70.0020.0002.16E0] # RUNIC LETTER EAR +16E3 ; [.2D71.0020.0002.16E3] # RUNIC LETTER CALC +16B8 ; [.2D72.0020.0002.16B8] # RUNIC LETTER GAR +16E4 ; [.2D73.0020.0002.16E4] # RUNIC LETTER CEALC +16E1 ; [.2D74.0020.0002.16E1] # RUNIC LETTER IOR +16E2 ; [.2D75.0020.0002.16E2] # RUNIC LETTER CWEORTH +16E5 ; [.2D76.0020.0002.16E5] # RUNIC LETTER STAN +16E6 ; [.2D77.0020.0002.16E6] # RUNIC LETTER LONG-BRANCH-YR +16E7 ; [.2D77.0020.0004.16E7][.0000.0139.0004.16E7] # RUNIC LETTER SHORT-TWIG-YR +16E8 ; [.2D77.0020.0004.16E8][.0000.013A.0004.16E8] # RUNIC LETTER ICELANDIC-YR +10C00 ; [.2D78.0020.0002.10C00] # OLD TURKIC LETTER ORKHON A +10C01 ; [.2D78.0020.0004.10C01][.0000.0139.0004.10C01] # OLD TURKIC LETTER YENISEI A +10C02 ; [.2D79.0020.0002.10C02] # OLD TURKIC LETTER YENISEI AE +10C03 ; [.2D7A.0020.0002.10C03] # OLD TURKIC LETTER ORKHON I +10C04 ; [.2D7A.0020.0004.10C04][.0000.0139.0004.10C04] # OLD TURKIC LETTER YENISEI I +10C05 ; [.2D7B.0020.0002.10C05] # OLD TURKIC LETTER YENISEI E +10C06 ; [.2D7C.0020.0002.10C06] # OLD TURKIC LETTER ORKHON O +10C07 ; [.2D7D.0020.0002.10C07] # OLD TURKIC LETTER ORKHON OE +10C08 ; [.2D7D.0020.0004.10C08][.0000.0139.0004.10C08] # OLD TURKIC LETTER YENISEI OE +10C09 ; [.2D7E.0020.0002.10C09] # OLD TURKIC LETTER ORKHON AB +10C0A ; [.2D7E.0020.0004.10C0A][.0000.0139.0004.10C0A] # OLD TURKIC LETTER YENISEI AB +10C0B ; [.2D7F.0020.0002.10C0B] # OLD TURKIC LETTER ORKHON AEB +10C0C ; [.2D7F.0020.0004.10C0C][.0000.0139.0004.10C0C] # OLD TURKIC LETTER YENISEI AEB +10C0D ; [.2D80.0020.0002.10C0D] # OLD TURKIC LETTER ORKHON AG +10C0E ; [.2D80.0020.0004.10C0E][.0000.0139.0004.10C0E] # OLD TURKIC LETTER YENISEI AG +10C0F ; [.2D81.0020.0002.10C0F] # OLD TURKIC LETTER ORKHON AEG +10C10 ; [.2D81.0020.0004.10C10][.0000.0139.0004.10C10] # OLD TURKIC LETTER YENISEI AEG +10C11 ; [.2D82.0020.0002.10C11] # OLD TURKIC LETTER ORKHON AD +10C12 ; [.2D82.0020.0004.10C12][.0000.0139.0004.10C12] # OLD TURKIC LETTER YENISEI AD +10C13 ; [.2D83.0020.0002.10C13] # OLD TURKIC LETTER ORKHON AED +10C14 ; [.2D84.0020.0002.10C14] # OLD TURKIC LETTER ORKHON EZ +10C15 ; [.2D84.0020.0004.10C15][.0000.0139.0004.10C15] # OLD TURKIC LETTER YENISEI EZ +10C16 ; [.2D85.0020.0002.10C16] # OLD TURKIC LETTER ORKHON AY +10C17 ; [.2D85.0020.0004.10C17][.0000.0139.0004.10C17] # OLD TURKIC LETTER YENISEI AY +10C18 ; [.2D86.0020.0002.10C18] # OLD TURKIC LETTER ORKHON AEY +10C19 ; [.2D86.0020.0004.10C19][.0000.0139.0004.10C19] # OLD TURKIC LETTER YENISEI AEY +10C1A ; [.2D87.0020.0002.10C1A] # OLD TURKIC LETTER ORKHON AEK +10C1B ; [.2D87.0020.0004.10C1B][.0000.0139.0004.10C1B] # OLD TURKIC LETTER YENISEI AEK +10C1C ; [.2D88.0020.0002.10C1C] # OLD TURKIC LETTER ORKHON OEK +10C1D ; [.2D88.0020.0004.10C1D][.0000.0139.0004.10C1D] # OLD TURKIC LETTER YENISEI OEK +10C1E ; [.2D89.0020.0002.10C1E] # OLD TURKIC LETTER ORKHON AL +10C1F ; [.2D89.0020.0004.10C1F][.0000.0139.0004.10C1F] # OLD TURKIC LETTER YENISEI AL +10C20 ; [.2D8A.0020.0002.10C20] # OLD TURKIC LETTER ORKHON AEL +10C21 ; [.2D8B.0020.0002.10C21] # OLD TURKIC LETTER ORKHON ELT +10C22 ; [.2D8C.0020.0002.10C22] # OLD TURKIC LETTER ORKHON EM +10C23 ; [.2D8D.0020.0002.10C23] # OLD TURKIC LETTER ORKHON AN +10C24 ; [.2D8E.0020.0002.10C24] # OLD TURKIC LETTER ORKHON AEN +10C25 ; [.2D8E.0020.0004.10C25][.0000.0139.0004.10C25] # OLD TURKIC LETTER YENISEI AEN +10C26 ; [.2D8F.0020.0002.10C26] # OLD TURKIC LETTER ORKHON ENT +10C27 ; [.2D8F.0020.0004.10C27][.0000.0139.0004.10C27] # OLD TURKIC LETTER YENISEI ENT +10C28 ; [.2D90.0020.0002.10C28] # OLD TURKIC LETTER ORKHON ENC +10C29 ; [.2D90.0020.0004.10C29][.0000.0139.0004.10C29] # OLD TURKIC LETTER YENISEI ENC +10C2A ; [.2D91.0020.0002.10C2A] # OLD TURKIC LETTER ORKHON ENY +10C2B ; [.2D91.0020.0004.10C2B][.0000.0139.0004.10C2B] # OLD TURKIC LETTER YENISEI ENY +10C2C ; [.2D92.0020.0002.10C2C] # OLD TURKIC LETTER YENISEI ANG +10C2D ; [.2D93.0020.0002.10C2D] # OLD TURKIC LETTER ORKHON ENG +10C2E ; [.2D93.0020.0004.10C2E][.0000.0139.0004.10C2E] # OLD TURKIC LETTER YENISEI AENG +10C2F ; [.2D94.0020.0002.10C2F] # OLD TURKIC LETTER ORKHON EP +10C30 ; [.2D95.0020.0002.10C30] # OLD TURKIC LETTER ORKHON OP +10C31 ; [.2D96.0020.0002.10C31] # OLD TURKIC LETTER ORKHON IC +10C32 ; [.2D97.0020.0002.10C32] # OLD TURKIC LETTER ORKHON EC +10C33 ; [.2D97.0020.0004.10C33][.0000.0139.0004.10C33] # OLD TURKIC LETTER YENISEI EC +10C34 ; [.2D98.0020.0002.10C34] # OLD TURKIC LETTER ORKHON AQ +10C35 ; [.2D98.0020.0004.10C35][.0000.0139.0004.10C35] # OLD TURKIC LETTER YENISEI AQ +10C36 ; [.2D99.0020.0002.10C36] # OLD TURKIC LETTER ORKHON IQ +10C37 ; [.2D99.0020.0004.10C37][.0000.0139.0004.10C37] # OLD TURKIC LETTER YENISEI IQ +10C38 ; [.2D9A.0020.0002.10C38] # OLD TURKIC LETTER ORKHON OQ +10C39 ; [.2D9A.0020.0004.10C39][.0000.0139.0004.10C39] # OLD TURKIC LETTER YENISEI OQ +10C3A ; [.2D9B.0020.0002.10C3A] # OLD TURKIC LETTER ORKHON AR +10C3B ; [.2D9B.0020.0004.10C3B][.0000.0139.0004.10C3B] # OLD TURKIC LETTER YENISEI AR +10C3C ; [.2D9C.0020.0002.10C3C] # OLD TURKIC LETTER ORKHON AER +10C3D ; [.2D9D.0020.0002.10C3D] # OLD TURKIC LETTER ORKHON AS +10C3E ; [.2D9E.0020.0002.10C3E] # OLD TURKIC LETTER ORKHON AES +10C3F ; [.2D9F.0020.0002.10C3F] # OLD TURKIC LETTER ORKHON ASH +10C40 ; [.2D9F.0020.0004.10C40][.0000.0139.0004.10C40] # OLD TURKIC LETTER YENISEI ASH +10C41 ; [.2DA0.0020.0002.10C41] # OLD TURKIC LETTER ORKHON ESH +10C42 ; [.2DA0.0020.0004.10C42][.0000.0139.0004.10C42] # OLD TURKIC LETTER YENISEI ESH +10C43 ; [.2DA1.0020.0002.10C43] # OLD TURKIC LETTER ORKHON AT +10C44 ; [.2DA1.0020.0004.10C44][.0000.0139.0004.10C44] # OLD TURKIC LETTER YENISEI AT +10C45 ; [.2DA2.0020.0002.10C45] # OLD TURKIC LETTER ORKHON AET +10C46 ; [.2DA2.0020.0004.10C46][.0000.0139.0004.10C46] # OLD TURKIC LETTER YENISEI AET +10C47 ; [.2DA3.0020.0002.10C47] # OLD TURKIC LETTER ORKHON OT +10C48 ; [.2DA4.0020.0002.10C48] # OLD TURKIC LETTER ORKHON BASH +A500 ; [.2DA5.0020.0002.A500] # VAI SYLLABLE EE +A501 ; [.2DA6.0020.0002.A501] # VAI SYLLABLE EEN +A502 ; [.2DA7.0020.0002.A502] # VAI SYLLABLE HEE +A503 ; [.2DA8.0020.0002.A503] # VAI SYLLABLE WEE +A504 ; [.2DA9.0020.0002.A504] # VAI SYLLABLE WEEN +A505 ; [.2DAA.0020.0002.A505] # VAI SYLLABLE PEE +A506 ; [.2DAB.0020.0002.A506] # VAI SYLLABLE BHEE +A507 ; [.2DAC.0020.0002.A507] # VAI SYLLABLE BEE +A508 ; [.2DAD.0020.0002.A508] # VAI SYLLABLE MBEE +A509 ; [.2DAE.0020.0002.A509] # VAI SYLLABLE KPEE +A50A ; [.2DAF.0020.0002.A50A] # VAI SYLLABLE MGBEE +A50B ; [.2DB0.0020.0002.A50B] # VAI SYLLABLE GBEE +A50C ; [.2DB1.0020.0002.A50C] # VAI SYLLABLE FEE +A613 ; [.2DB1.0020.0004.A613][.2EB0.0020.0004.A613] # VAI SYMBOL FEENG +A50D ; [.2DB2.0020.0002.A50D] # VAI SYLLABLE VEE +A50E ; [.2DB3.0020.0002.A50E] # VAI SYLLABLE TEE +A50F ; [.2DB4.0020.0002.A50F] # VAI SYLLABLE THEE +A510 ; [.2DB5.0020.0002.A510] # VAI SYLLABLE DHEE +A511 ; [.2DB6.0020.0002.A511] # VAI SYLLABLE DHHEE +A512 ; [.2DB7.0020.0002.A512] # VAI SYLLABLE LEE +A513 ; [.2DB8.0020.0002.A513] # VAI SYLLABLE REE +A514 ; [.2DB9.0020.0002.A514] # VAI SYLLABLE DEE +A515 ; [.2DBA.0020.0002.A515] # VAI SYLLABLE NDEE +A516 ; [.2DBB.0020.0002.A516] # VAI SYLLABLE SEE +A517 ; [.2DBC.0020.0002.A517] # VAI SYLLABLE SHEE +A518 ; [.2DBD.0020.0002.A518] # VAI SYLLABLE ZEE +A519 ; [.2DBE.0020.0002.A519] # VAI SYLLABLE ZHEE +A51A ; [.2DBF.0020.0002.A51A] # VAI SYLLABLE CEE +A51B ; [.2DC0.0020.0002.A51B] # VAI SYLLABLE JEE +A51C ; [.2DC1.0020.0002.A51C] # VAI SYLLABLE NJEE +A51D ; [.2DC2.0020.0002.A51D] # VAI SYLLABLE YEE +A51E ; [.2DC3.0020.0002.A51E] # VAI SYLLABLE KEE +A614 ; [.2DC3.0020.0004.A614][.2EB0.0020.0004.A614] # VAI SYMBOL KEENG +A51F ; [.2DC4.0020.0002.A51F] # VAI SYLLABLE NGGEE +A520 ; [.2DC5.0020.0002.A520] # VAI SYLLABLE GEE +A521 ; [.2DC6.0020.0002.A521] # VAI SYLLABLE MEE +A522 ; [.2DC7.0020.0002.A522] # VAI SYLLABLE NEE +A523 ; [.2DC8.0020.0002.A523] # VAI SYLLABLE NYEE +A524 ; [.2DC9.0020.0002.A524] # VAI SYLLABLE I +A525 ; [.2DCA.0020.0002.A525] # VAI SYLLABLE IN +A526 ; [.2DCB.0020.0002.A526] # VAI SYLLABLE HI +A527 ; [.2DCC.0020.0002.A527] # VAI SYLLABLE HIN +A528 ; [.2DCD.0020.0002.A528] # VAI SYLLABLE WI +A529 ; [.2DCE.0020.0002.A529] # VAI SYLLABLE WIN +A52A ; [.2DCF.0020.0002.A52A] # VAI SYLLABLE PI +A52B ; [.2DD0.0020.0002.A52B] # VAI SYLLABLE BHI +A52C ; [.2DD1.0020.0002.A52C] # VAI SYLLABLE BI +A52D ; [.2DD2.0020.0002.A52D] # VAI SYLLABLE MBI +A52E ; [.2DD3.0020.0002.A52E] # VAI SYLLABLE KPI +A52F ; [.2DD4.0020.0002.A52F] # VAI SYLLABLE MGBI +A530 ; [.2DD5.0020.0002.A530] # VAI SYLLABLE GBI +A531 ; [.2DD6.0020.0002.A531] # VAI SYLLABLE FI +A532 ; [.2DD7.0020.0002.A532] # VAI SYLLABLE VI +A533 ; [.2DD8.0020.0002.A533] # VAI SYLLABLE TI +A615 ; [.2DD8.0020.0004.A615][.2EB0.0020.0004.A615] # VAI SYMBOL TING +A534 ; [.2DD9.0020.0002.A534] # VAI SYLLABLE THI +A535 ; [.2DDA.0020.0002.A535] # VAI SYLLABLE DHI +A536 ; [.2DDB.0020.0002.A536] # VAI SYLLABLE DHHI +A537 ; [.2DDC.0020.0002.A537] # VAI SYLLABLE LI +A538 ; [.2DDD.0020.0002.A538] # VAI SYLLABLE RI +A539 ; [.2DDE.0020.0002.A539] # VAI SYLLABLE DI +A53A ; [.2DDF.0020.0002.A53A] # VAI SYLLABLE NDI +A53B ; [.2DE0.0020.0002.A53B] # VAI SYLLABLE SI +A53C ; [.2DE1.0020.0002.A53C] # VAI SYLLABLE SHI +A53D ; [.2DE2.0020.0002.A53D] # VAI SYLLABLE ZI +A53E ; [.2DE3.0020.0002.A53E] # VAI SYLLABLE ZHI +A53F ; [.2DE4.0020.0002.A53F] # VAI SYLLABLE CI +A540 ; [.2DE5.0020.0002.A540] # VAI SYLLABLE JI +A541 ; [.2DE6.0020.0002.A541] # VAI SYLLABLE NJI +A542 ; [.2DE7.0020.0002.A542] # VAI SYLLABLE YI +A543 ; [.2DE8.0020.0002.A543] # VAI SYLLABLE KI +A544 ; [.2DE9.0020.0002.A544] # VAI SYLLABLE NGGI +A545 ; [.2DEA.0020.0002.A545] # VAI SYLLABLE GI +A546 ; [.2DEB.0020.0002.A546] # VAI SYLLABLE MI +A547 ; [.2DEC.0020.0002.A547] # VAI SYLLABLE NI +A616 ; [.2DEC.0020.0004.A616][.2EB1.0020.0004.A616] # VAI SYMBOL NII +A548 ; [.2DED.0020.0002.A548] # VAI SYLLABLE NYI +A549 ; [.2DEE.0020.0002.A549] # VAI SYLLABLE A +A54A ; [.2DEF.0020.0002.A54A] # VAI SYLLABLE AN +A54B ; [.2DF0.0020.0002.A54B] # VAI SYLLABLE NGAN +A54C ; [.2DF1.0020.0002.A54C] # VAI SYLLABLE HA +A54D ; [.2DF2.0020.0002.A54D] # VAI SYLLABLE HAN +A54E ; [.2DF3.0020.0002.A54E] # VAI SYLLABLE WA +A54F ; [.2DF4.0020.0002.A54F] # VAI SYLLABLE WAN +A550 ; [.2DF5.0020.0002.A550] # VAI SYLLABLE PA +A551 ; [.2DF6.0020.0002.A551] # VAI SYLLABLE BHA +A552 ; [.2DF7.0020.0002.A552] # VAI SYLLABLE BA +A617 ; [.2DF7.0020.0004.A617][.2EB0.0020.0004.A617] # VAI SYMBOL BANG +A553 ; [.2DF8.0020.0002.A553] # VAI SYLLABLE MBA +A554 ; [.2DF9.0020.0002.A554] # VAI SYLLABLE KPA +A555 ; [.2DFA.0020.0002.A555] # VAI SYLLABLE KPAN +A556 ; [.2DFB.0020.0002.A556] # VAI SYLLABLE MGBA +A557 ; [.2DFC.0020.0002.A557] # VAI SYLLABLE GBA +A558 ; [.2DFD.0020.0002.A558] # VAI SYLLABLE FA +A610 ; [.2DFD.0020.0004.A610] # VAI SYLLABLE NDOLE FA +A618 ; [.2DFD.0020.0004.A618][.2EB1.0020.0004.A618] # VAI SYMBOL FAA +A559 ; [.2DFE.0020.0002.A559] # VAI SYLLABLE VA +A55A ; [.2DFF.0020.0002.A55A] # VAI SYLLABLE TA +A619 ; [.2DFF.0020.0004.A619][.2EB1.0020.0004.A619] # VAI SYMBOL TAA +A55B ; [.2E00.0020.0002.A55B] # VAI SYLLABLE THA +A55C ; [.2E01.0020.0002.A55C] # VAI SYLLABLE DHA +A55D ; [.2E02.0020.0002.A55D] # VAI SYLLABLE DHHA +A55E ; [.2E03.0020.0002.A55E] # VAI SYLLABLE LA +A55F ; [.2E04.0020.0002.A55F] # VAI SYLLABLE RA +A560 ; [.2E05.0020.0002.A560] # VAI SYLLABLE DA +A61A ; [.2E05.0020.0004.A61A][.2EB0.0020.0004.A61A] # VAI SYMBOL DANG +A561 ; [.2E06.0020.0002.A561] # VAI SYLLABLE NDA +A562 ; [.2E07.0020.0002.A562] # VAI SYLLABLE SA +A563 ; [.2E08.0020.0002.A563] # VAI SYLLABLE SHA +A564 ; [.2E09.0020.0002.A564] # VAI SYLLABLE ZA +A565 ; [.2E0A.0020.0002.A565] # VAI SYLLABLE ZHA +A566 ; [.2E0B.0020.0002.A566] # VAI SYLLABLE CA +A567 ; [.2E0C.0020.0002.A567] # VAI SYLLABLE JA +A568 ; [.2E0D.0020.0002.A568] # VAI SYLLABLE NJA +A569 ; [.2E0E.0020.0002.A569] # VAI SYLLABLE YA +A56A ; [.2E0F.0020.0002.A56A] # VAI SYLLABLE KA +A611 ; [.2E0F.0020.0004.A611] # VAI SYLLABLE NDOLE KA +A56B ; [.2E10.0020.0002.A56B] # VAI SYLLABLE KAN +A56C ; [.2E11.0020.0002.A56C] # VAI SYLLABLE NGGA +A56D ; [.2E12.0020.0002.A56D] # VAI SYLLABLE GA +A56E ; [.2E13.0020.0002.A56E] # VAI SYLLABLE MA +A62A ; [.2E13.0020.0004.A62A] # VAI SYLLABLE NDOLE MA +A56F ; [.2E14.0020.0002.A56F] # VAI SYLLABLE NA +A570 ; [.2E15.0020.0002.A570] # VAI SYLLABLE NYA +A571 ; [.2E16.0020.0002.A571] # VAI SYLLABLE OO +A572 ; [.2E17.0020.0002.A572] # VAI SYLLABLE OON +A573 ; [.2E18.0020.0002.A573] # VAI SYLLABLE HOO +A574 ; [.2E19.0020.0002.A574] # VAI SYLLABLE WOO +A575 ; [.2E1A.0020.0002.A575] # VAI SYLLABLE WOON +A576 ; [.2E1B.0020.0002.A576] # VAI SYLLABLE POO +A577 ; [.2E1C.0020.0002.A577] # VAI SYLLABLE BHOO +A578 ; [.2E1D.0020.0002.A578] # VAI SYLLABLE BOO +A579 ; [.2E1E.0020.0002.A579] # VAI SYLLABLE MBOO +A57A ; [.2E1F.0020.0002.A57A] # VAI SYLLABLE KPOO +A57B ; [.2E20.0020.0002.A57B] # VAI SYLLABLE MGBOO +A57C ; [.2E21.0020.0002.A57C] # VAI SYLLABLE GBOO +A57D ; [.2E22.0020.0002.A57D] # VAI SYLLABLE FOO +A57E ; [.2E23.0020.0002.A57E] # VAI SYLLABLE VOO +A57F ; [.2E24.0020.0002.A57F] # VAI SYLLABLE TOO +A580 ; [.2E25.0020.0002.A580] # VAI SYLLABLE THOO +A581 ; [.2E26.0020.0002.A581] # VAI SYLLABLE DHOO +A582 ; [.2E27.0020.0002.A582] # VAI SYLLABLE DHHOO +A583 ; [.2E28.0020.0002.A583] # VAI SYLLABLE LOO +A584 ; [.2E29.0020.0002.A584] # VAI SYLLABLE ROO +A585 ; [.2E2A.0020.0002.A585] # VAI SYLLABLE DOO +A61B ; [.2E2A.0020.0004.A61B][.2EB0.0020.0004.A61B] # VAI SYMBOL DOONG +A586 ; [.2E2B.0020.0002.A586] # VAI SYLLABLE NDOO +A587 ; [.2E2C.0020.0002.A587] # VAI SYLLABLE SOO +A612 ; [.2E2C.0020.0004.A612] # VAI SYLLABLE NDOLE SOO +A588 ; [.2E2D.0020.0002.A588] # VAI SYLLABLE SHOO +A589 ; [.2E2E.0020.0002.A589] # VAI SYLLABLE ZOO +A58A ; [.2E2F.0020.0002.A58A] # VAI SYLLABLE ZHOO +A58B ; [.2E30.0020.0002.A58B] # VAI SYLLABLE COO +A58C ; [.2E31.0020.0002.A58C] # VAI SYLLABLE JOO +A58D ; [.2E32.0020.0002.A58D] # VAI SYLLABLE NJOO +A58E ; [.2E33.0020.0002.A58E] # VAI SYLLABLE YOO +A58F ; [.2E34.0020.0002.A58F] # VAI SYLLABLE KOO +A590 ; [.2E35.0020.0002.A590] # VAI SYLLABLE NGGOO +A591 ; [.2E36.0020.0002.A591] # VAI SYLLABLE GOO +A592 ; [.2E37.0020.0002.A592] # VAI SYLLABLE MOO +A593 ; [.2E38.0020.0002.A593] # VAI SYLLABLE NOO +A594 ; [.2E39.0020.0002.A594] # VAI SYLLABLE NYOO +A595 ; [.2E3A.0020.0002.A595] # VAI SYLLABLE U +A596 ; [.2E3B.0020.0002.A596] # VAI SYLLABLE UN +A597 ; [.2E3C.0020.0002.A597] # VAI SYLLABLE HU +A598 ; [.2E3D.0020.0002.A598] # VAI SYLLABLE HUN +A599 ; [.2E3E.0020.0002.A599] # VAI SYLLABLE WU +A59A ; [.2E3F.0020.0002.A59A] # VAI SYLLABLE WUN +A59B ; [.2E40.0020.0002.A59B] # VAI SYLLABLE PU +A59C ; [.2E41.0020.0002.A59C] # VAI SYLLABLE BHU +A59D ; [.2E42.0020.0002.A59D] # VAI SYLLABLE BU +A59E ; [.2E43.0020.0002.A59E] # VAI SYLLABLE MBU +A59F ; [.2E44.0020.0002.A59F] # VAI SYLLABLE KPU +A5A0 ; [.2E45.0020.0002.A5A0] # VAI SYLLABLE MGBU +A5A1 ; [.2E46.0020.0002.A5A1] # VAI SYLLABLE GBU +A5A2 ; [.2E47.0020.0002.A5A2] # VAI SYLLABLE FU +A5A3 ; [.2E48.0020.0002.A5A3] # VAI SYLLABLE VU +A5A4 ; [.2E49.0020.0002.A5A4] # VAI SYLLABLE TU +A5A5 ; [.2E4A.0020.0002.A5A5] # VAI SYLLABLE THU +A5A6 ; [.2E4B.0020.0002.A5A6] # VAI SYLLABLE DHU +A5A7 ; [.2E4C.0020.0002.A5A7] # VAI SYLLABLE DHHU +A5A8 ; [.2E4D.0020.0002.A5A8] # VAI SYLLABLE LU +A5A9 ; [.2E4E.0020.0002.A5A9] # VAI SYLLABLE RU +A5AA ; [.2E4F.0020.0002.A5AA] # VAI SYLLABLE DU +A5AB ; [.2E50.0020.0002.A5AB] # VAI SYLLABLE NDU +A5AC ; [.2E51.0020.0002.A5AC] # VAI SYLLABLE SU +A5AD ; [.2E52.0020.0002.A5AD] # VAI SYLLABLE SHU +A5AE ; [.2E53.0020.0002.A5AE] # VAI SYLLABLE ZU +A5AF ; [.2E54.0020.0002.A5AF] # VAI SYLLABLE ZHU +A5B0 ; [.2E55.0020.0002.A5B0] # VAI SYLLABLE CU +A5B1 ; [.2E56.0020.0002.A5B1] # VAI SYLLABLE JU +A5B2 ; [.2E57.0020.0002.A5B2] # VAI SYLLABLE NJU +A5B3 ; [.2E58.0020.0002.A5B3] # VAI SYLLABLE YU +A5B4 ; [.2E59.0020.0002.A5B4] # VAI SYLLABLE KU +A61C ; [.2E59.0020.0004.A61C][.2EB0.0020.0004.A61C] # VAI SYMBOL KUNG +A5B5 ; [.2E5A.0020.0002.A5B5] # VAI SYLLABLE NGGU +A5B6 ; [.2E5B.0020.0002.A5B6] # VAI SYLLABLE GU +A5B7 ; [.2E5C.0020.0002.A5B7] # VAI SYLLABLE MU +A5B8 ; [.2E5D.0020.0002.A5B8] # VAI SYLLABLE NU +A5B9 ; [.2E5E.0020.0002.A5B9] # VAI SYLLABLE NYU +A5BA ; [.2E5F.0020.0002.A5BA] # VAI SYLLABLE O +A5BB ; [.2E60.0020.0002.A5BB] # VAI SYLLABLE ON +A5BC ; [.2E61.0020.0002.A5BC] # VAI SYLLABLE NGON +A5BD ; [.2E62.0020.0002.A5BD] # VAI SYLLABLE HO +A5BE ; [.2E63.0020.0002.A5BE] # VAI SYLLABLE HON +A5BF ; [.2E64.0020.0002.A5BF] # VAI SYLLABLE WO +A5C0 ; [.2E65.0020.0002.A5C0] # VAI SYLLABLE WON +A5C1 ; [.2E66.0020.0002.A5C1] # VAI SYLLABLE PO +A5C2 ; [.2E67.0020.0002.A5C2] # VAI SYLLABLE BHO +A5C3 ; [.2E68.0020.0002.A5C3] # VAI SYLLABLE BO +A5C4 ; [.2E69.0020.0002.A5C4] # VAI SYLLABLE MBO +A5C5 ; [.2E6A.0020.0002.A5C5] # VAI SYLLABLE KPO +A5C6 ; [.2E6B.0020.0002.A5C6] # VAI SYLLABLE MGBO +A5C7 ; [.2E6C.0020.0002.A5C7] # VAI SYLLABLE GBO +A5C8 ; [.2E6D.0020.0002.A5C8] # VAI SYLLABLE GBON +A5C9 ; [.2E6E.0020.0002.A5C9] # VAI SYLLABLE FO +A5CA ; [.2E6F.0020.0002.A5CA] # VAI SYLLABLE VO +A5CB ; [.2E70.0020.0002.A5CB] # VAI SYLLABLE TO +A61D ; [.2E70.0020.0004.A61D][.2EB0.0020.0004.A61D] # VAI SYMBOL TONG +A5CC ; [.2E71.0020.0002.A5CC] # VAI SYLLABLE THO +A5CD ; [.2E72.0020.0002.A5CD] # VAI SYLLABLE DHO +A5CE ; [.2E73.0020.0002.A5CE] # VAI SYLLABLE DHHO +A5CF ; [.2E74.0020.0002.A5CF] # VAI SYLLABLE LO +A5D0 ; [.2E75.0020.0002.A5D0] # VAI SYLLABLE RO +A5D1 ; [.2E76.0020.0002.A5D1] # VAI SYLLABLE DO +A62B ; [.2E76.0020.0004.A62B] # VAI SYLLABLE NDOLE DO +A61E ; [.2E76.0020.0004.A61E][.2EB1.0020.0004.A61E] # VAI SYMBOL DO-O +A5D2 ; [.2E77.0020.0002.A5D2] # VAI SYLLABLE NDO +A5D3 ; [.2E78.0020.0002.A5D3] # VAI SYLLABLE SO +A5D4 ; [.2E79.0020.0002.A5D4] # VAI SYLLABLE SHO +A5D5 ; [.2E7A.0020.0002.A5D5] # VAI SYLLABLE ZO +A5D6 ; [.2E7B.0020.0002.A5D6] # VAI SYLLABLE ZHO +A5D7 ; [.2E7C.0020.0002.A5D7] # VAI SYLLABLE CO +A5D8 ; [.2E7D.0020.0002.A5D8] # VAI SYLLABLE JO +A61F ; [.2E7D.0020.0004.A61F][.2EB0.0020.0004.A61F] # VAI SYMBOL JONG +A5D9 ; [.2E7E.0020.0002.A5D9] # VAI SYLLABLE NJO +A5DA ; [.2E7F.0020.0002.A5DA] # VAI SYLLABLE YO +A5DB ; [.2E80.0020.0002.A5DB] # VAI SYLLABLE KO +A5DC ; [.2E81.0020.0002.A5DC] # VAI SYLLABLE NGGO +A5DD ; [.2E82.0020.0002.A5DD] # VAI SYLLABLE GO +A5DE ; [.2E83.0020.0002.A5DE] # VAI SYLLABLE MO +A5DF ; [.2E84.0020.0002.A5DF] # VAI SYLLABLE NO +A5E0 ; [.2E85.0020.0002.A5E0] # VAI SYLLABLE NYO +A5E1 ; [.2E86.0020.0002.A5E1] # VAI SYLLABLE E +A5E2 ; [.2E87.0020.0002.A5E2] # VAI SYLLABLE EN +A5E3 ; [.2E88.0020.0002.A5E3] # VAI SYLLABLE NGEN +A5E4 ; [.2E89.0020.0002.A5E4] # VAI SYLLABLE HE +A5E5 ; [.2E8A.0020.0002.A5E5] # VAI SYLLABLE HEN +A5E6 ; [.2E8B.0020.0002.A5E6] # VAI SYLLABLE WE +A5E7 ; [.2E8C.0020.0002.A5E7] # VAI SYLLABLE WEN +A5E8 ; [.2E8D.0020.0002.A5E8] # VAI SYLLABLE PE +A5E9 ; [.2E8E.0020.0002.A5E9] # VAI SYLLABLE BHE +A5EA ; [.2E8F.0020.0002.A5EA] # VAI SYLLABLE BE +A5EB ; [.2E90.0020.0002.A5EB] # VAI SYLLABLE MBE +A5EC ; [.2E91.0020.0002.A5EC] # VAI SYLLABLE KPE +A5ED ; [.2E92.0020.0002.A5ED] # VAI SYLLABLE KPEN +A5EE ; [.2E93.0020.0002.A5EE] # VAI SYLLABLE MGBE +A5EF ; [.2E94.0020.0002.A5EF] # VAI SYLLABLE GBE +A5F0 ; [.2E95.0020.0002.A5F0] # VAI SYLLABLE GBEN +A5F1 ; [.2E96.0020.0002.A5F1] # VAI SYLLABLE FE +A5F2 ; [.2E97.0020.0002.A5F2] # VAI SYLLABLE VE +A5F3 ; [.2E98.0020.0002.A5F3] # VAI SYLLABLE TE +A5F4 ; [.2E99.0020.0002.A5F4] # VAI SYLLABLE THE +A5F5 ; [.2E9A.0020.0002.A5F5] # VAI SYLLABLE DHE +A5F6 ; [.2E9B.0020.0002.A5F6] # VAI SYLLABLE DHHE +A5F7 ; [.2E9C.0020.0002.A5F7] # VAI SYLLABLE LE +A5F8 ; [.2E9D.0020.0002.A5F8] # VAI SYLLABLE RE +A5F9 ; [.2E9E.0020.0002.A5F9] # VAI SYLLABLE DE +A5FA ; [.2E9F.0020.0002.A5FA] # VAI SYLLABLE NDE +A5FB ; [.2EA0.0020.0002.A5FB] # VAI SYLLABLE SE +A5FC ; [.2EA1.0020.0002.A5FC] # VAI SYLLABLE SHE +A5FD ; [.2EA2.0020.0002.A5FD] # VAI SYLLABLE ZE +A5FE ; [.2EA3.0020.0002.A5FE] # VAI SYLLABLE ZHE +A5FF ; [.2EA4.0020.0002.A5FF] # VAI SYLLABLE CE +A600 ; [.2EA5.0020.0002.A600] # VAI SYLLABLE JE +A601 ; [.2EA6.0020.0002.A601] # VAI SYLLABLE NJE +A602 ; [.2EA7.0020.0002.A602] # VAI SYLLABLE YE +A603 ; [.2EA8.0020.0002.A603] # VAI SYLLABLE KE +A604 ; [.2EA9.0020.0002.A604] # VAI SYLLABLE NGGE +A605 ; [.2EAA.0020.0002.A605] # VAI SYLLABLE NGGEN +A606 ; [.2EAB.0020.0002.A606] # VAI SYLLABLE GE +A607 ; [.2EAC.0020.0002.A607] # VAI SYLLABLE GEN +A608 ; [.2EAD.0020.0002.A608] # VAI SYLLABLE ME +A609 ; [.2EAE.0020.0002.A609] # VAI SYLLABLE NE +A60A ; [.2EAF.0020.0002.A60A] # VAI SYLLABLE NYE +A60B ; [.2EB0.0020.0002.A60B] # VAI SYLLABLE NG +A60C ; [.2EB1.0020.0002.A60C] # VAI SYLLABLE LENGTHENER +A6A0 ; [.2EB2.0020.0002.A6A0] # BAMUM LETTER A +A6A1 ; [.2EB3.0020.0002.A6A1] # BAMUM LETTER KA +A6A2 ; [.2EB4.0020.0002.A6A2] # BAMUM LETTER U +A6A3 ; [.2EB5.0020.0002.A6A3] # BAMUM LETTER KU +A6A4 ; [.2EB6.0020.0002.A6A4] # BAMUM LETTER EE +A6A5 ; [.2EB7.0020.0002.A6A5] # BAMUM LETTER REE +A6A6 ; [.2EB8.0020.0002.A6A6] # BAMUM LETTER TAE +A6A7 ; [.2EB9.0020.0002.A6A7] # BAMUM LETTER O +A6A8 ; [.2EBA.0020.0002.A6A8] # BAMUM LETTER NYI +A6A9 ; [.2EBB.0020.0002.A6A9] # BAMUM LETTER I +A6AA ; [.2EBC.0020.0002.A6AA] # BAMUM LETTER LA +A6AB ; [.2EBD.0020.0002.A6AB] # BAMUM LETTER PA +A6AC ; [.2EBE.0020.0002.A6AC] # BAMUM LETTER RII +A6AD ; [.2EBF.0020.0002.A6AD] # BAMUM LETTER RIEE +A6AE ; [.2EC0.0020.0002.A6AE] # BAMUM LETTER LEEEE +A6AF ; [.2EC1.0020.0002.A6AF] # BAMUM LETTER MEEEE +A6B0 ; [.2EC2.0020.0002.A6B0] # BAMUM LETTER TAA +A6B1 ; [.2EC3.0020.0002.A6B1] # BAMUM LETTER NDAA +A6B2 ; [.2EC4.0020.0002.A6B2] # BAMUM LETTER NJAEM +A6B3 ; [.2EC5.0020.0002.A6B3] # BAMUM LETTER M +A6B4 ; [.2EC6.0020.0002.A6B4] # BAMUM LETTER SUU +A6B5 ; [.2EC7.0020.0002.A6B5] # BAMUM LETTER MU +A6B6 ; [.2EC8.0020.0002.A6B6] # BAMUM LETTER SHII +A6B7 ; [.2EC9.0020.0002.A6B7] # BAMUM LETTER SI +A6B8 ; [.2ECA.0020.0002.A6B8] # BAMUM LETTER SHEUX +A6B9 ; [.2ECB.0020.0002.A6B9] # BAMUM LETTER SEUX +A6BA ; [.2ECC.0020.0002.A6BA] # BAMUM LETTER KYEE +A6BB ; [.2ECD.0020.0002.A6BB] # BAMUM LETTER KET +A6BC ; [.2ECE.0020.0002.A6BC] # BAMUM LETTER NUAE +A6BD ; [.2ECF.0020.0002.A6BD] # BAMUM LETTER NU +A6BE ; [.2ED0.0020.0002.A6BE] # BAMUM LETTER NJUAE +A6BF ; [.2ED1.0020.0002.A6BF] # BAMUM LETTER YOQ +A6C0 ; [.2ED2.0020.0002.A6C0] # BAMUM LETTER SHU +A6C1 ; [.2ED3.0020.0002.A6C1] # BAMUM LETTER YUQ +A6C2 ; [.2ED4.0020.0002.A6C2] # BAMUM LETTER YA +A6C3 ; [.2ED5.0020.0002.A6C3] # BAMUM LETTER NSHA +A6C4 ; [.2ED6.0020.0002.A6C4] # BAMUM LETTER KEUX +A6C5 ; [.2ED7.0020.0002.A6C5] # BAMUM LETTER PEUX +A6C6 ; [.2ED8.0020.0002.A6C6] # BAMUM LETTER NJEE +A6C7 ; [.2ED9.0020.0002.A6C7] # BAMUM LETTER NTEE +A6C8 ; [.2EDA.0020.0002.A6C8] # BAMUM LETTER PUE +A6C9 ; [.2EDB.0020.0002.A6C9] # BAMUM LETTER WUE +A6CA ; [.2EDC.0020.0002.A6CA] # BAMUM LETTER PEE +A6CB ; [.2EDD.0020.0002.A6CB] # BAMUM LETTER FEE +A6CC ; [.2EDE.0020.0002.A6CC] # BAMUM LETTER RU +A6CD ; [.2EDF.0020.0002.A6CD] # BAMUM LETTER LU +A6CE ; [.2EE0.0020.0002.A6CE] # BAMUM LETTER MI +A6CF ; [.2EE1.0020.0002.A6CF] # BAMUM LETTER NI +A6D0 ; [.2EE2.0020.0002.A6D0] # BAMUM LETTER REUX +A6D1 ; [.2EE3.0020.0002.A6D1] # BAMUM LETTER RAE +A6D2 ; [.2EE4.0020.0002.A6D2] # BAMUM LETTER KEN +A6D3 ; [.2EE5.0020.0002.A6D3] # BAMUM LETTER NGKWAEN +A6D4 ; [.2EE6.0020.0002.A6D4] # BAMUM LETTER NGGA +A6D5 ; [.2EE7.0020.0002.A6D5] # BAMUM LETTER NGA +A6D6 ; [.2EE8.0020.0002.A6D6] # BAMUM LETTER SHO +A6D7 ; [.2EE9.0020.0002.A6D7] # BAMUM LETTER PUAE +A6D8 ; [.2EEA.0020.0002.A6D8] # BAMUM LETTER FU +A6D9 ; [.2EEB.0020.0002.A6D9] # BAMUM LETTER FOM +A6DA ; [.2EEC.0020.0002.A6DA] # BAMUM LETTER WA +A6DB ; [.2EED.0020.0002.A6DB] # BAMUM LETTER NA +A6DC ; [.2EEE.0020.0002.A6DC] # BAMUM LETTER LI +A6DD ; [.2EEF.0020.0002.A6DD] # BAMUM LETTER PI +A6DE ; [.2EF0.0020.0002.A6DE] # BAMUM LETTER LOQ +A6DF ; [.2EF1.0020.0002.A6DF] # BAMUM LETTER KO +A6E0 ; [.2EF2.0020.0002.A6E0] # BAMUM LETTER MBEN +A6E1 ; [.2EF3.0020.0002.A6E1] # BAMUM LETTER REN +A6E2 ; [.2EF4.0020.0002.A6E2] # BAMUM LETTER MEN +A6E3 ; [.2EF5.0020.0002.A6E3] # BAMUM LETTER MA +A6E4 ; [.2EF6.0020.0002.A6E4] # BAMUM LETTER TI +A6E5 ; [.2EF7.0020.0002.A6E5] # BAMUM LETTER KI +A6E6 ; [.2EF8.0020.0002.A6E6] # BAMUM LETTER MO +A6E7 ; [.2EF9.0020.0002.A6E7] # BAMUM LETTER MBAA +A6E8 ; [.2EFA.0020.0002.A6E8] # BAMUM LETTER TET +A6E9 ; [.2EFB.0020.0002.A6E9] # BAMUM LETTER KPA +A6EA ; [.2EFC.0020.0002.A6EA] # BAMUM LETTER TEN +A6EB ; [.2EFD.0020.0002.A6EB] # BAMUM LETTER NTUU +A6EC ; [.2EFE.0020.0002.A6EC] # BAMUM LETTER SAMBA +A6ED ; [.2EFF.0020.0002.A6ED] # BAMUM LETTER FAAMAE +A6EE ; [.2F00.0020.0002.A6EE] # BAMUM LETTER KOVUU +A6EF ; [.2F01.0020.0002.A6EF] # BAMUM LETTER KOGHOM +16800 ; [.2F02.0020.0002.16800] # BAMUM LETTER PHASE-A NGKUE MFON +16801 ; [.2F03.0020.0002.16801] # BAMUM LETTER PHASE-A GBIEE FON +16802 ; [.2F04.0020.0002.16802] # BAMUM LETTER PHASE-A PON MFON PIPAEMGBIEE +16803 ; [.2F05.0020.0002.16803] # BAMUM LETTER PHASE-A PON MFON PIPAEMBA +16804 ; [.2F06.0020.0002.16804] # BAMUM LETTER PHASE-A NAA MFON +16805 ; [.2F07.0020.0002.16805] # BAMUM LETTER PHASE-A SHUENSHUET +16806 ; [.2F08.0020.0002.16806] # BAMUM LETTER PHASE-A TITA MFON +16807 ; [.2F09.0020.0002.16807] # BAMUM LETTER PHASE-A NZA MFON +16808 ; [.2F0A.0020.0002.16808] # BAMUM LETTER PHASE-A SHINDA PA NJI +16809 ; [.2F0B.0020.0002.16809] # BAMUM LETTER PHASE-A PON PA NJI PIPAEMGBIEE +1680A ; [.2F0C.0020.0002.1680A] # BAMUM LETTER PHASE-A PON PA NJI PIPAEMBA +1680B ; [.2F0D.0020.0002.1680B] # BAMUM LETTER PHASE-A MAEMBGBIEE +1680C ; [.2F0E.0020.0002.1680C] # BAMUM LETTER PHASE-A TU MAEMBA +1680D ; [.2F0F.0020.0002.1680D] # BAMUM LETTER PHASE-A NGANGU +1680E ; [.2F10.0020.0002.1680E] # BAMUM LETTER PHASE-A MAEMVEUX +1680F ; [.2F11.0020.0002.1680F] # BAMUM LETTER PHASE-A MANSUAE +16810 ; [.2F12.0020.0002.16810] # BAMUM LETTER PHASE-A MVEUAENGAM +16811 ; [.2F13.0020.0002.16811] # BAMUM LETTER PHASE-A SEUNYAM +16812 ; [.2F14.0020.0002.16812] # BAMUM LETTER PHASE-A NTOQPEN +16813 ; [.2F15.0020.0002.16813] # BAMUM LETTER PHASE-A KEUKEUTNDA +16814 ; [.2F16.0020.0002.16814] # BAMUM LETTER PHASE-A NKINDI +16815 ; [.2F17.0020.0002.16815] # BAMUM LETTER PHASE-A SUU +16816 ; [.2F18.0020.0002.16816] # BAMUM LETTER PHASE-A NGKUENZEUM +16817 ; [.2F19.0020.0002.16817] # BAMUM LETTER PHASE-A LAPAQ +16818 ; [.2F1A.0020.0002.16818] # BAMUM LETTER PHASE-A LET KUT +16819 ; [.2F1B.0020.0002.16819] # BAMUM LETTER PHASE-A NTAP MFAA +1681A ; [.2F1C.0020.0002.1681A] # BAMUM LETTER PHASE-A MAEKEUP +1681B ; [.2F1D.0020.0002.1681B] # BAMUM LETTER PHASE-A PASHAE +1681C ; [.2F1E.0020.0002.1681C] # BAMUM LETTER PHASE-A GHEUAERAE +1681D ; [.2F1F.0020.0002.1681D] # BAMUM LETTER PHASE-A PAMSHAE +1681E ; [.2F20.0020.0002.1681E] # BAMUM LETTER PHASE-A MON NGGEUAET +1681F ; [.2F21.0020.0002.1681F] # BAMUM LETTER PHASE-A NZUN MEUT +16820 ; [.2F22.0020.0002.16820] # BAMUM LETTER PHASE-A U YUQ NAE +16821 ; [.2F23.0020.0002.16821] # BAMUM LETTER PHASE-A GHEUAEGHEUAE +16822 ; [.2F24.0020.0002.16822] # BAMUM LETTER PHASE-A NTAP NTAA +16823 ; [.2F25.0020.0002.16823] # BAMUM LETTER PHASE-A SISA +16824 ; [.2F26.0020.0002.16824] # BAMUM LETTER PHASE-A MGBASA +16825 ; [.2F27.0020.0002.16825] # BAMUM LETTER PHASE-A MEUNJOMNDEUQ +16826 ; [.2F28.0020.0002.16826] # BAMUM LETTER PHASE-A MOOMPUQ +16827 ; [.2F29.0020.0002.16827] # BAMUM LETTER PHASE-A KAFA +16828 ; [.2F2A.0020.0002.16828] # BAMUM LETTER PHASE-A PA LEERAEWA +16829 ; [.2F2B.0020.0002.16829] # BAMUM LETTER PHASE-A NDA LEERAEWA +1682A ; [.2F2C.0020.0002.1682A] # BAMUM LETTER PHASE-A PET +1682B ; [.2F2D.0020.0002.1682B] # BAMUM LETTER PHASE-A MAEMKPEN +1682C ; [.2F2E.0020.0002.1682C] # BAMUM LETTER PHASE-A NIKA +1682D ; [.2F2F.0020.0002.1682D] # BAMUM LETTER PHASE-A PUP +1682E ; [.2F30.0020.0002.1682E] # BAMUM LETTER PHASE-A TUAEP +1682F ; [.2F31.0020.0002.1682F] # BAMUM LETTER PHASE-A LUAEP +16830 ; [.2F32.0020.0002.16830] # BAMUM LETTER PHASE-A SONJAM +16831 ; [.2F33.0020.0002.16831] # BAMUM LETTER PHASE-A TEUTEUWEN +16832 ; [.2F34.0020.0002.16832] # BAMUM LETTER PHASE-A MAENYI +16833 ; [.2F35.0020.0002.16833] # BAMUM LETTER PHASE-A KET +16834 ; [.2F36.0020.0002.16834] # BAMUM LETTER PHASE-A NDAANGGEUAET +16835 ; [.2F37.0020.0002.16835] # BAMUM LETTER PHASE-A KUOQ +16836 ; [.2F38.0020.0002.16836] # BAMUM LETTER PHASE-A MOOMEUT +16837 ; [.2F39.0020.0002.16837] # BAMUM LETTER PHASE-A SHUM +16838 ; [.2F3A.0020.0002.16838] # BAMUM LETTER PHASE-A LOMMAE +16839 ; [.2F3B.0020.0002.16839] # BAMUM LETTER PHASE-A FIRI +1683A ; [.2F3C.0020.0002.1683A] # BAMUM LETTER PHASE-A ROM +1683B ; [.2F3D.0020.0002.1683B] # BAMUM LETTER PHASE-A KPOQ +1683C ; [.2F3E.0020.0002.1683C] # BAMUM LETTER PHASE-A SOQ +1683D ; [.2F3F.0020.0002.1683D] # BAMUM LETTER PHASE-A MAP PIEET +1683E ; [.2F40.0020.0002.1683E] # BAMUM LETTER PHASE-A SHIRAE +1683F ; [.2F41.0020.0002.1683F] # BAMUM LETTER PHASE-A NTAP +16840 ; [.2F42.0020.0002.16840] # BAMUM LETTER PHASE-A SHOQ NSHUT YUM +16841 ; [.2F43.0020.0002.16841] # BAMUM LETTER PHASE-A NYIT MONGKEUAEQ +16842 ; [.2F44.0020.0002.16842] # BAMUM LETTER PHASE-A PAARAE +16843 ; [.2F45.0020.0002.16843] # BAMUM LETTER PHASE-A NKAARAE +16844 ; [.2F46.0020.0002.16844] # BAMUM LETTER PHASE-A UNKNOWN +16845 ; [.2F47.0020.0002.16845] # BAMUM LETTER PHASE-A NGGEN +16846 ; [.2F48.0020.0002.16846] # BAMUM LETTER PHASE-A MAESI +16847 ; [.2F49.0020.0002.16847] # BAMUM LETTER PHASE-A NJAM +16848 ; [.2F4A.0020.0002.16848] # BAMUM LETTER PHASE-A MBANYI +16849 ; [.2F4B.0020.0002.16849] # BAMUM LETTER PHASE-A NYET +1684A ; [.2F4C.0020.0002.1684A] # BAMUM LETTER PHASE-A TEUAEN +1684B ; [.2F4D.0020.0002.1684B] # BAMUM LETTER PHASE-A SOT +1684C ; [.2F4E.0020.0002.1684C] # BAMUM LETTER PHASE-A PAAM +1684D ; [.2F4F.0020.0002.1684D] # BAMUM LETTER PHASE-A NSHIEE +1684E ; [.2F50.0020.0002.1684E] # BAMUM LETTER PHASE-A MAEM +1684F ; [.2F51.0020.0002.1684F] # BAMUM LETTER PHASE-A NYI +16850 ; [.2F52.0020.0002.16850] # BAMUM LETTER PHASE-A KAQ +16851 ; [.2F53.0020.0002.16851] # BAMUM LETTER PHASE-A NSHA +16852 ; [.2F54.0020.0002.16852] # BAMUM LETTER PHASE-A VEE +16853 ; [.2F55.0020.0002.16853] # BAMUM LETTER PHASE-A LU +16854 ; [.2F56.0020.0002.16854] # BAMUM LETTER PHASE-A NEN +16855 ; [.2F57.0020.0002.16855] # BAMUM LETTER PHASE-A NAQ +16856 ; [.2F58.0020.0002.16856] # BAMUM LETTER PHASE-A MBAQ +16857 ; [.2F59.0020.0002.16857] # BAMUM LETTER PHASE-B NSHUET +16858 ; [.2F5A.0020.0002.16858] # BAMUM LETTER PHASE-B TU MAEMGBIEE +16859 ; [.2F5B.0020.0002.16859] # BAMUM LETTER PHASE-B SIEE +1685A ; [.2F5C.0020.0002.1685A] # BAMUM LETTER PHASE-B SET TU +1685B ; [.2F5D.0020.0002.1685B] # BAMUM LETTER PHASE-B LOM NTEUM +1685C ; [.2F5E.0020.0002.1685C] # BAMUM LETTER PHASE-B MBA MAELEE +1685D ; [.2F5F.0020.0002.1685D] # BAMUM LETTER PHASE-B KIEEM +1685E ; [.2F60.0020.0002.1685E] # BAMUM LETTER PHASE-B YEURAE +1685F ; [.2F61.0020.0002.1685F] # BAMUM LETTER PHASE-B MBAARAE +16860 ; [.2F62.0020.0002.16860] # BAMUM LETTER PHASE-B KAM +16861 ; [.2F63.0020.0002.16861] # BAMUM LETTER PHASE-B PEESHI +16862 ; [.2F64.0020.0002.16862] # BAMUM LETTER PHASE-B YAFU LEERAEWA +16863 ; [.2F65.0020.0002.16863] # BAMUM LETTER PHASE-B LAM NSHUT NYAM +16864 ; [.2F66.0020.0002.16864] # BAMUM LETTER PHASE-B NTIEE SHEUOQ +16865 ; [.2F67.0020.0002.16865] # BAMUM LETTER PHASE-B NDU NJAA +16866 ; [.2F68.0020.0002.16866] # BAMUM LETTER PHASE-B GHEUGHEUAEM +16867 ; [.2F69.0020.0002.16867] # BAMUM LETTER PHASE-B PIT +16868 ; [.2F6A.0020.0002.16868] # BAMUM LETTER PHASE-B TU NSIEE +16869 ; [.2F6B.0020.0002.16869] # BAMUM LETTER PHASE-B SHET NJAQ +1686A ; [.2F6C.0020.0002.1686A] # BAMUM LETTER PHASE-B SHEUAEQTU +1686B ; [.2F6D.0020.0002.1686B] # BAMUM LETTER PHASE-B MFON TEUAEQ +1686C ; [.2F6E.0020.0002.1686C] # BAMUM LETTER PHASE-B MBIT MBAAKET +1686D ; [.2F6F.0020.0002.1686D] # BAMUM LETTER PHASE-B NYI NTEUM +1686E ; [.2F70.0020.0002.1686E] # BAMUM LETTER PHASE-B KEUPUQ +1686F ; [.2F71.0020.0002.1686F] # BAMUM LETTER PHASE-B GHEUGHEN +16870 ; [.2F72.0020.0002.16870] # BAMUM LETTER PHASE-B KEUYEUX +16871 ; [.2F73.0020.0002.16871] # BAMUM LETTER PHASE-B LAANAE +16872 ; [.2F74.0020.0002.16872] # BAMUM LETTER PHASE-B PARUM +16873 ; [.2F75.0020.0002.16873] # BAMUM LETTER PHASE-B VEUM +16874 ; [.2F76.0020.0002.16874] # BAMUM LETTER PHASE-B NGKINDI MVOP +16875 ; [.2F77.0020.0002.16875] # BAMUM LETTER PHASE-B NGGEU MBU +16876 ; [.2F78.0020.0002.16876] # BAMUM LETTER PHASE-B WUAET +16877 ; [.2F79.0020.0002.16877] # BAMUM LETTER PHASE-B SAKEUAE +16878 ; [.2F7A.0020.0002.16878] # BAMUM LETTER PHASE-B TAAM +16879 ; [.2F7B.0020.0002.16879] # BAMUM LETTER PHASE-B MEUQ +1687A ; [.2F7C.0020.0002.1687A] # BAMUM LETTER PHASE-B NGGUOQ +1687B ; [.2F7D.0020.0002.1687B] # BAMUM LETTER PHASE-B NGGUOQ LARGE +1687C ; [.2F7E.0020.0002.1687C] # BAMUM LETTER PHASE-B MFIYAQ +1687D ; [.2F7F.0020.0002.1687D] # BAMUM LETTER PHASE-B SUE +1687E ; [.2F80.0020.0002.1687E] # BAMUM LETTER PHASE-B MBEURI +1687F ; [.2F81.0020.0002.1687F] # BAMUM LETTER PHASE-B MONTIEEN +16880 ; [.2F82.0020.0002.16880] # BAMUM LETTER PHASE-B NYAEMAE +16881 ; [.2F83.0020.0002.16881] # BAMUM LETTER PHASE-B PUNGAAM +16882 ; [.2F84.0020.0002.16882] # BAMUM LETTER PHASE-B MEUT NGGEET +16883 ; [.2F85.0020.0002.16883] # BAMUM LETTER PHASE-B FEUX +16884 ; [.2F86.0020.0002.16884] # BAMUM LETTER PHASE-B MBUOQ +16885 ; [.2F87.0020.0002.16885] # BAMUM LETTER PHASE-B FEE +16886 ; [.2F88.0020.0002.16886] # BAMUM LETTER PHASE-B KEUAEM +16887 ; [.2F89.0020.0002.16887] # BAMUM LETTER PHASE-B MA NJEUAENA +16888 ; [.2F8A.0020.0002.16888] # BAMUM LETTER PHASE-B MA NJUQA +16889 ; [.2F8B.0020.0002.16889] # BAMUM LETTER PHASE-B LET +1688A ; [.2F8C.0020.0002.1688A] # BAMUM LETTER PHASE-B NGGAAM +1688B ; [.2F8D.0020.0002.1688B] # BAMUM LETTER PHASE-B NSEN +1688C ; [.2F8E.0020.0002.1688C] # BAMUM LETTER PHASE-B MA +1688D ; [.2F8F.0020.0002.1688D] # BAMUM LETTER PHASE-B KIQ +1688E ; [.2F90.0020.0002.1688E] # BAMUM LETTER PHASE-B NGOM +1688F ; [.2F91.0020.0002.1688F] # BAMUM LETTER PHASE-C NGKUE MAEMBA +16890 ; [.2F92.0020.0002.16890] # BAMUM LETTER PHASE-C NZA +16891 ; [.2F93.0020.0002.16891] # BAMUM LETTER PHASE-C YUM +16892 ; [.2F94.0020.0002.16892] # BAMUM LETTER PHASE-C WANGKUOQ +16893 ; [.2F95.0020.0002.16893] # BAMUM LETTER PHASE-C NGGEN +16894 ; [.2F96.0020.0002.16894] # BAMUM LETTER PHASE-C NDEUAEREE +16895 ; [.2F97.0020.0002.16895] # BAMUM LETTER PHASE-C NGKAQ +16896 ; [.2F98.0020.0002.16896] # BAMUM LETTER PHASE-C GHARAE +16897 ; [.2F99.0020.0002.16897] # BAMUM LETTER PHASE-C MBEEKEET +16898 ; [.2F9A.0020.0002.16898] # BAMUM LETTER PHASE-C GBAYI +16899 ; [.2F9B.0020.0002.16899] # BAMUM LETTER PHASE-C NYIR MKPARAQ MEUN +1689A ; [.2F9C.0020.0002.1689A] # BAMUM LETTER PHASE-C NTU MBIT +1689B ; [.2F9D.0020.0002.1689B] # BAMUM LETTER PHASE-C MBEUM +1689C ; [.2F9E.0020.0002.1689C] # BAMUM LETTER PHASE-C PIRIEEN +1689D ; [.2F9F.0020.0002.1689D] # BAMUM LETTER PHASE-C NDOMBU +1689E ; [.2FA0.0020.0002.1689E] # BAMUM LETTER PHASE-C MBAA CABBAGE-TREE +1689F ; [.2FA1.0020.0002.1689F] # BAMUM LETTER PHASE-C KEUSHEUAEP +168A0 ; [.2FA2.0020.0002.168A0] # BAMUM LETTER PHASE-C GHAP +168A1 ; [.2FA3.0020.0002.168A1] # BAMUM LETTER PHASE-C KEUKAQ +168A2 ; [.2FA4.0020.0002.168A2] # BAMUM LETTER PHASE-C YU MUOMAE +168A3 ; [.2FA5.0020.0002.168A3] # BAMUM LETTER PHASE-C NZEUM +168A4 ; [.2FA6.0020.0002.168A4] # BAMUM LETTER PHASE-C MBUE +168A5 ; [.2FA7.0020.0002.168A5] # BAMUM LETTER PHASE-C NSEUAEN +168A6 ; [.2FA8.0020.0002.168A6] # BAMUM LETTER PHASE-C MBIT +168A7 ; [.2FA9.0020.0002.168A7] # BAMUM LETTER PHASE-C YEUQ +168A8 ; [.2FAA.0020.0002.168A8] # BAMUM LETTER PHASE-C KPARAQ +168A9 ; [.2FAB.0020.0002.168A9] # BAMUM LETTER PHASE-C KAA +168AA ; [.2FAC.0020.0002.168AA] # BAMUM LETTER PHASE-C SEUX +168AB ; [.2FAD.0020.0002.168AB] # BAMUM LETTER PHASE-C NDIDA +168AC ; [.2FAE.0020.0002.168AC] # BAMUM LETTER PHASE-C TAASHAE +168AD ; [.2FAF.0020.0002.168AD] # BAMUM LETTER PHASE-C NJUEQ +168AE ; [.2FB0.0020.0002.168AE] # BAMUM LETTER PHASE-C TITA YUE +168AF ; [.2FB1.0020.0002.168AF] # BAMUM LETTER PHASE-C SUAET +168B0 ; [.2FB2.0020.0002.168B0] # BAMUM LETTER PHASE-C NGGUAEN NYAM +168B1 ; [.2FB3.0020.0002.168B1] # BAMUM LETTER PHASE-C VEUX +168B2 ; [.2FB4.0020.0002.168B2] # BAMUM LETTER PHASE-C NANSANAQ +168B3 ; [.2FB5.0020.0002.168B3] # BAMUM LETTER PHASE-C MA KEUAERI +168B4 ; [.2FB6.0020.0002.168B4] # BAMUM LETTER PHASE-C NTAA +168B5 ; [.2FB7.0020.0002.168B5] # BAMUM LETTER PHASE-C NGGUON +168B6 ; [.2FB8.0020.0002.168B6] # BAMUM LETTER PHASE-C LAP +168B7 ; [.2FB9.0020.0002.168B7] # BAMUM LETTER PHASE-C MBIRIEEN +168B8 ; [.2FBA.0020.0002.168B8] # BAMUM LETTER PHASE-C MGBASAQ +168B9 ; [.2FBB.0020.0002.168B9] # BAMUM LETTER PHASE-C NTEUNGBA +168BA ; [.2FBC.0020.0002.168BA] # BAMUM LETTER PHASE-C TEUTEUX +168BB ; [.2FBD.0020.0002.168BB] # BAMUM LETTER PHASE-C NGGUM +168BC ; [.2FBE.0020.0002.168BC] # BAMUM LETTER PHASE-C FUE +168BD ; [.2FBF.0020.0002.168BD] # BAMUM LETTER PHASE-C NDEUT +168BE ; [.2FC0.0020.0002.168BE] # BAMUM LETTER PHASE-C NSA +168BF ; [.2FC1.0020.0002.168BF] # BAMUM LETTER PHASE-C NSHAQ +168C0 ; [.2FC2.0020.0002.168C0] # BAMUM LETTER PHASE-C BUNG +168C1 ; [.2FC3.0020.0002.168C1] # BAMUM LETTER PHASE-C VEUAEPEN +168C2 ; [.2FC4.0020.0002.168C2] # BAMUM LETTER PHASE-C MBERAE +168C3 ; [.2FC5.0020.0002.168C3] # BAMUM LETTER PHASE-C RU +168C4 ; [.2FC6.0020.0002.168C4] # BAMUM LETTER PHASE-C NJAEM +168C5 ; [.2FC7.0020.0002.168C5] # BAMUM LETTER PHASE-C LAM +168C6 ; [.2FC8.0020.0002.168C6] # BAMUM LETTER PHASE-C TITUAEP +168C7 ; [.2FC9.0020.0002.168C7] # BAMUM LETTER PHASE-C NSUOT NGOM +168C8 ; [.2FCA.0020.0002.168C8] # BAMUM LETTER PHASE-C NJEEEE +168C9 ; [.2FCB.0020.0002.168C9] # BAMUM LETTER PHASE-C KET +168CA ; [.2FCC.0020.0002.168CA] # BAMUM LETTER PHASE-C NGGU +168CB ; [.2FCD.0020.0002.168CB] # BAMUM LETTER PHASE-C MAESI +168CC ; [.2FCE.0020.0002.168CC] # BAMUM LETTER PHASE-C MBUAEM +168CD ; [.2FCF.0020.0002.168CD] # BAMUM LETTER PHASE-C LU +168CE ; [.2FD0.0020.0002.168CE] # BAMUM LETTER PHASE-C KUT +168CF ; [.2FD1.0020.0002.168CF] # BAMUM LETTER PHASE-C NJAM +168D0 ; [.2FD2.0020.0002.168D0] # BAMUM LETTER PHASE-C NGOM +168D1 ; [.2FD3.0020.0002.168D1] # BAMUM LETTER PHASE-C WUP +168D2 ; [.2FD4.0020.0002.168D2] # BAMUM LETTER PHASE-C NGGUEET +168D3 ; [.2FD5.0020.0002.168D3] # BAMUM LETTER PHASE-C NSOM +168D4 ; [.2FD6.0020.0002.168D4] # BAMUM LETTER PHASE-C NTEN +168D5 ; [.2FD7.0020.0002.168D5] # BAMUM LETTER PHASE-C KUOP NKAARAE +168D6 ; [.2FD8.0020.0002.168D6] # BAMUM LETTER PHASE-C NSUN +168D7 ; [.2FD9.0020.0002.168D7] # BAMUM LETTER PHASE-C NDAM +168D8 ; [.2FDA.0020.0002.168D8] # BAMUM LETTER PHASE-C MA NSIEE +168D9 ; [.2FDB.0020.0002.168D9] # BAMUM LETTER PHASE-C YAA +168DA ; [.2FDC.0020.0002.168DA] # BAMUM LETTER PHASE-C NDAP +168DB ; [.2FDD.0020.0002.168DB] # BAMUM LETTER PHASE-C SHUEQ +168DC ; [.2FDE.0020.0002.168DC] # BAMUM LETTER PHASE-C SETFON +168DD ; [.2FDF.0020.0002.168DD] # BAMUM LETTER PHASE-C MBI +168DE ; [.2FE0.0020.0002.168DE] # BAMUM LETTER PHASE-C MAEMBA +168DF ; [.2FE1.0020.0002.168DF] # BAMUM LETTER PHASE-C MBANYI +168E0 ; [.2FE2.0020.0002.168E0] # BAMUM LETTER PHASE-C KEUSEUX +168E1 ; [.2FE3.0020.0002.168E1] # BAMUM LETTER PHASE-C MBEUX +168E2 ; [.2FE4.0020.0002.168E2] # BAMUM LETTER PHASE-C KEUM +168E3 ; [.2FE5.0020.0002.168E3] # BAMUM LETTER PHASE-C MBAA PICKET +168E4 ; [.2FE6.0020.0002.168E4] # BAMUM LETTER PHASE-C YUWOQ +168E5 ; [.2FE7.0020.0002.168E5] # BAMUM LETTER PHASE-C NJEUX +168E6 ; [.2FE8.0020.0002.168E6] # BAMUM LETTER PHASE-C MIEE +168E7 ; [.2FE9.0020.0002.168E7] # BAMUM LETTER PHASE-C MUAE +168E8 ; [.2FEA.0020.0002.168E8] # BAMUM LETTER PHASE-C SHIQ +168E9 ; [.2FEB.0020.0002.168E9] # BAMUM LETTER PHASE-C KEN LAW +168EA ; [.2FEC.0020.0002.168EA] # BAMUM LETTER PHASE-C KEN FATIGUE +168EB ; [.2FED.0020.0002.168EB] # BAMUM LETTER PHASE-C NGAQ +168EC ; [.2FEE.0020.0002.168EC] # BAMUM LETTER PHASE-C NAQ +168ED ; [.2FEF.0020.0002.168ED] # BAMUM LETTER PHASE-C LIQ +168EE ; [.2FF0.0020.0002.168EE] # BAMUM LETTER PHASE-C PIN +168EF ; [.2FF1.0020.0002.168EF] # BAMUM LETTER PHASE-C PEN +168F0 ; [.2FF2.0020.0002.168F0] # BAMUM LETTER PHASE-C TET +168F1 ; [.2FF3.0020.0002.168F1] # BAMUM LETTER PHASE-D MBUO +168F2 ; [.2FF4.0020.0002.168F2] # BAMUM LETTER PHASE-D WAP +168F3 ; [.2FF5.0020.0002.168F3] # BAMUM LETTER PHASE-D NJI +168F4 ; [.2FF6.0020.0002.168F4] # BAMUM LETTER PHASE-D MFON +168F5 ; [.2FF7.0020.0002.168F5] # BAMUM LETTER PHASE-D NJIEE +168F6 ; [.2FF8.0020.0002.168F6] # BAMUM LETTER PHASE-D LIEE +168F7 ; [.2FF9.0020.0002.168F7] # BAMUM LETTER PHASE-D NJEUT +168F8 ; [.2FFA.0020.0002.168F8] # BAMUM LETTER PHASE-D NSHEE +168F9 ; [.2FFB.0020.0002.168F9] # BAMUM LETTER PHASE-D NGGAAMAE +168FA ; [.2FFC.0020.0002.168FA] # BAMUM LETTER PHASE-D NYAM +168FB ; [.2FFD.0020.0002.168FB] # BAMUM LETTER PHASE-D WUAEN +168FC ; [.2FFE.0020.0002.168FC] # BAMUM LETTER PHASE-D NGKUN +168FD ; [.2FFF.0020.0002.168FD] # BAMUM LETTER PHASE-D SHEE +168FE ; [.3000.0020.0002.168FE] # BAMUM LETTER PHASE-D NGKAP +168FF ; [.3001.0020.0002.168FF] # BAMUM LETTER PHASE-D KEUAETMEUN +16900 ; [.3002.0020.0002.16900] # BAMUM LETTER PHASE-D TEUT +16901 ; [.3003.0020.0002.16901] # BAMUM LETTER PHASE-D SHEUAE +16902 ; [.3004.0020.0002.16902] # BAMUM LETTER PHASE-D NJAP +16903 ; [.3005.0020.0002.16903] # BAMUM LETTER PHASE-D SUE +16904 ; [.3006.0020.0002.16904] # BAMUM LETTER PHASE-D KET +16905 ; [.3007.0020.0002.16905] # BAMUM LETTER PHASE-D YAEMMAE +16906 ; [.3008.0020.0002.16906] # BAMUM LETTER PHASE-D KUOM +16907 ; [.3009.0020.0002.16907] # BAMUM LETTER PHASE-D SAP +16908 ; [.300A.0020.0002.16908] # BAMUM LETTER PHASE-D MFEUT +16909 ; [.300B.0020.0002.16909] # BAMUM LETTER PHASE-D NDEUX +1690A ; [.300C.0020.0002.1690A] # BAMUM LETTER PHASE-D MALEERI +1690B ; [.300D.0020.0002.1690B] # BAMUM LETTER PHASE-D MEUT +1690C ; [.300E.0020.0002.1690C] # BAMUM LETTER PHASE-D SEUAEQ +1690D ; [.300F.0020.0002.1690D] # BAMUM LETTER PHASE-D YEN +1690E ; [.3010.0020.0002.1690E] # BAMUM LETTER PHASE-D NJEUAEM +1690F ; [.3011.0020.0002.1690F] # BAMUM LETTER PHASE-D KEUOT MBUAE +16910 ; [.3012.0020.0002.16910] # BAMUM LETTER PHASE-D NGKEURI +16911 ; [.3013.0020.0002.16911] # BAMUM LETTER PHASE-D TU +16912 ; [.3014.0020.0002.16912] # BAMUM LETTER PHASE-D GHAA +16913 ; [.3015.0020.0002.16913] # BAMUM LETTER PHASE-D NGKYEE +16914 ; [.3016.0020.0002.16914] # BAMUM LETTER PHASE-D FEUFEUAET +16915 ; [.3017.0020.0002.16915] # BAMUM LETTER PHASE-D NDEE +16916 ; [.3018.0020.0002.16916] # BAMUM LETTER PHASE-D MGBOFUM +16917 ; [.3019.0020.0002.16917] # BAMUM LETTER PHASE-D LEUAEP +16918 ; [.301A.0020.0002.16918] # BAMUM LETTER PHASE-D NDON +16919 ; [.301B.0020.0002.16919] # BAMUM LETTER PHASE-D MONI +1691A ; [.301C.0020.0002.1691A] # BAMUM LETTER PHASE-D MGBEUN +1691B ; [.301D.0020.0002.1691B] # BAMUM LETTER PHASE-D PUUT +1691C ; [.301E.0020.0002.1691C] # BAMUM LETTER PHASE-D MGBIEE +1691D ; [.301F.0020.0002.1691D] # BAMUM LETTER PHASE-D MFO +1691E ; [.3020.0020.0002.1691E] # BAMUM LETTER PHASE-D LUM +1691F ; [.3021.0020.0002.1691F] # BAMUM LETTER PHASE-D NSIEEP +16920 ; [.3022.0020.0002.16920] # BAMUM LETTER PHASE-D MBAA +16921 ; [.3023.0020.0002.16921] # BAMUM LETTER PHASE-D KWAET +16922 ; [.3024.0020.0002.16922] # BAMUM LETTER PHASE-D NYET +16923 ; [.3025.0020.0002.16923] # BAMUM LETTER PHASE-D TEUAEN +16924 ; [.3026.0020.0002.16924] # BAMUM LETTER PHASE-D SOT +16925 ; [.3027.0020.0002.16925] # BAMUM LETTER PHASE-D YUWOQ +16926 ; [.3028.0020.0002.16926] # BAMUM LETTER PHASE-D KEUM +16927 ; [.3029.0020.0002.16927] # BAMUM LETTER PHASE-D RAEM +16928 ; [.302A.0020.0002.16928] # BAMUM LETTER PHASE-D TEEEE +16929 ; [.302B.0020.0002.16929] # BAMUM LETTER PHASE-D NGKEUAEQ +1692A ; [.302C.0020.0002.1692A] # BAMUM LETTER PHASE-D MFEUAE +1692B ; [.302D.0020.0002.1692B] # BAMUM LETTER PHASE-D NSIEET +1692C ; [.302E.0020.0002.1692C] # BAMUM LETTER PHASE-D KEUP +1692D ; [.302F.0020.0002.1692D] # BAMUM LETTER PHASE-D PIP +1692E ; [.3030.0020.0002.1692E] # BAMUM LETTER PHASE-D PEUTAE +1692F ; [.3031.0020.0002.1692F] # BAMUM LETTER PHASE-D NYUE +16930 ; [.3032.0020.0002.16930] # BAMUM LETTER PHASE-D LET +16931 ; [.3033.0020.0002.16931] # BAMUM LETTER PHASE-D NGGAAM +16932 ; [.3034.0020.0002.16932] # BAMUM LETTER PHASE-D MFIEE +16933 ; [.3035.0020.0002.16933] # BAMUM LETTER PHASE-D NGGWAEN +16934 ; [.3036.0020.0002.16934] # BAMUM LETTER PHASE-D YUOM +16935 ; [.3037.0020.0002.16935] # BAMUM LETTER PHASE-D PAP +16936 ; [.3038.0020.0002.16936] # BAMUM LETTER PHASE-D YUOP +16937 ; [.3039.0020.0002.16937] # BAMUM LETTER PHASE-D NDAM +16938 ; [.303A.0020.0002.16938] # BAMUM LETTER PHASE-D NTEUM +16939 ; [.303B.0020.0002.16939] # BAMUM LETTER PHASE-D SUAE +1693A ; [.303C.0020.0002.1693A] # BAMUM LETTER PHASE-D KUN +1693B ; [.303D.0020.0002.1693B] # BAMUM LETTER PHASE-D NGGEUX +1693C ; [.303E.0020.0002.1693C] # BAMUM LETTER PHASE-D NGKIEE +1693D ; [.303F.0020.0002.1693D] # BAMUM LETTER PHASE-D TUOT +1693E ; [.3040.0020.0002.1693E] # BAMUM LETTER PHASE-D MEUN +1693F ; [.3041.0020.0002.1693F] # BAMUM LETTER PHASE-D KUQ +16940 ; [.3042.0020.0002.16940] # BAMUM LETTER PHASE-D NSUM +16941 ; [.3043.0020.0002.16941] # BAMUM LETTER PHASE-D TEUN +16942 ; [.3044.0020.0002.16942] # BAMUM LETTER PHASE-D MAENJET +16943 ; [.3045.0020.0002.16943] # BAMUM LETTER PHASE-D NGGAP +16944 ; [.3046.0020.0002.16944] # BAMUM LETTER PHASE-D LEUM +16945 ; [.3047.0020.0002.16945] # BAMUM LETTER PHASE-D NGGUOM +16946 ; [.3048.0020.0002.16946] # BAMUM LETTER PHASE-D NSHUT +16947 ; [.3049.0020.0002.16947] # BAMUM LETTER PHASE-D NJUEQ +16948 ; [.304A.0020.0002.16948] # BAMUM LETTER PHASE-D GHEUAE +16949 ; [.304B.0020.0002.16949] # BAMUM LETTER PHASE-D KU +1694A ; [.304C.0020.0002.1694A] # BAMUM LETTER PHASE-D REN OLD +1694B ; [.304D.0020.0002.1694B] # BAMUM LETTER PHASE-D TAE +1694C ; [.304E.0020.0002.1694C] # BAMUM LETTER PHASE-D TOQ +1694D ; [.304F.0020.0002.1694D] # BAMUM LETTER PHASE-D NYI +1694E ; [.3050.0020.0002.1694E] # BAMUM LETTER PHASE-D RII +1694F ; [.3051.0020.0002.1694F] # BAMUM LETTER PHASE-D LEEEE +16950 ; [.3052.0020.0002.16950] # BAMUM LETTER PHASE-D MEEEE +16951 ; [.3053.0020.0002.16951] # BAMUM LETTER PHASE-D M +16952 ; [.3054.0020.0002.16952] # BAMUM LETTER PHASE-D SUU +16953 ; [.3055.0020.0002.16953] # BAMUM LETTER PHASE-D MU +16954 ; [.3056.0020.0002.16954] # BAMUM LETTER PHASE-D SHII +16955 ; [.3057.0020.0002.16955] # BAMUM LETTER PHASE-D SHEUX +16956 ; [.3058.0020.0002.16956] # BAMUM LETTER PHASE-D KYEE +16957 ; [.3059.0020.0002.16957] # BAMUM LETTER PHASE-D NU +16958 ; [.305A.0020.0002.16958] # BAMUM LETTER PHASE-D SHU +16959 ; [.305B.0020.0002.16959] # BAMUM LETTER PHASE-D NTEE +1695A ; [.305C.0020.0002.1695A] # BAMUM LETTER PHASE-D PEE +1695B ; [.305D.0020.0002.1695B] # BAMUM LETTER PHASE-D NI +1695C ; [.305E.0020.0002.1695C] # BAMUM LETTER PHASE-D SHOQ +1695D ; [.305F.0020.0002.1695D] # BAMUM LETTER PHASE-D PUQ +1695E ; [.3060.0020.0002.1695E] # BAMUM LETTER PHASE-D MVOP +1695F ; [.3061.0020.0002.1695F] # BAMUM LETTER PHASE-D LOQ +16960 ; [.3062.0020.0002.16960] # BAMUM LETTER PHASE-D REN MUCH +16961 ; [.3063.0020.0002.16961] # BAMUM LETTER PHASE-D TI +16962 ; [.3064.0020.0002.16962] # BAMUM LETTER PHASE-D NTUU +16963 ; [.3065.0020.0002.16963] # BAMUM LETTER PHASE-D MBAA SEVEN +16964 ; [.3066.0020.0002.16964] # BAMUM LETTER PHASE-D SAQ +16965 ; [.3067.0020.0002.16965] # BAMUM LETTER PHASE-D FAA +16966 ; [.3068.0020.0002.16966] # BAMUM LETTER PHASE-E NDAP +16967 ; [.3069.0020.0002.16967] # BAMUM LETTER PHASE-E TOON +16968 ; [.306A.0020.0002.16968] # BAMUM LETTER PHASE-E MBEUM +16969 ; [.306B.0020.0002.16969] # BAMUM LETTER PHASE-E LAP +1696A ; [.306C.0020.0002.1696A] # BAMUM LETTER PHASE-E VOM +1696B ; [.306D.0020.0002.1696B] # BAMUM LETTER PHASE-E LOON +1696C ; [.306E.0020.0002.1696C] # BAMUM LETTER PHASE-E PAA +1696D ; [.306F.0020.0002.1696D] # BAMUM LETTER PHASE-E SOM +1696E ; [.3070.0020.0002.1696E] # BAMUM LETTER PHASE-E RAQ +1696F ; [.3071.0020.0002.1696F] # BAMUM LETTER PHASE-E NSHUOP +16970 ; [.3072.0020.0002.16970] # BAMUM LETTER PHASE-E NDUN +16971 ; [.3073.0020.0002.16971] # BAMUM LETTER PHASE-E PUAE +16972 ; [.3074.0020.0002.16972] # BAMUM LETTER PHASE-E TAM +16973 ; [.3075.0020.0002.16973] # BAMUM LETTER PHASE-E NGKA +16974 ; [.3076.0020.0002.16974] # BAMUM LETTER PHASE-E KPEUX +16975 ; [.3077.0020.0002.16975] # BAMUM LETTER PHASE-E WUO +16976 ; [.3078.0020.0002.16976] # BAMUM LETTER PHASE-E SEE +16977 ; [.3079.0020.0002.16977] # BAMUM LETTER PHASE-E NGGEUAET +16978 ; [.307A.0020.0002.16978] # BAMUM LETTER PHASE-E PAAM +16979 ; [.307B.0020.0002.16979] # BAMUM LETTER PHASE-E TOO +1697A ; [.307C.0020.0002.1697A] # BAMUM LETTER PHASE-E KUOP +1697B ; [.307D.0020.0002.1697B] # BAMUM LETTER PHASE-E LOM +1697C ; [.307E.0020.0002.1697C] # BAMUM LETTER PHASE-E NSHIEE +1697D ; [.307F.0020.0002.1697D] # BAMUM LETTER PHASE-E NGOP +1697E ; [.3080.0020.0002.1697E] # BAMUM LETTER PHASE-E MAEM +1697F ; [.3081.0020.0002.1697F] # BAMUM LETTER PHASE-E NGKEUX +16980 ; [.3082.0020.0002.16980] # BAMUM LETTER PHASE-E NGOQ +16981 ; [.3083.0020.0002.16981] # BAMUM LETTER PHASE-E NSHUE +16982 ; [.3084.0020.0002.16982] # BAMUM LETTER PHASE-E RIMGBA +16983 ; [.3085.0020.0002.16983] # BAMUM LETTER PHASE-E NJEUX +16984 ; [.3086.0020.0002.16984] # BAMUM LETTER PHASE-E PEEM +16985 ; [.3087.0020.0002.16985] # BAMUM LETTER PHASE-E SAA +16986 ; [.3088.0020.0002.16986] # BAMUM LETTER PHASE-E NGGURAE +16987 ; [.3089.0020.0002.16987] # BAMUM LETTER PHASE-E MGBA +16988 ; [.308A.0020.0002.16988] # BAMUM LETTER PHASE-E GHEUX +16989 ; [.308B.0020.0002.16989] # BAMUM LETTER PHASE-E NGKEUAEM +1698A ; [.308C.0020.0002.1698A] # BAMUM LETTER PHASE-E NJAEMLI +1698B ; [.308D.0020.0002.1698B] # BAMUM LETTER PHASE-E MAP +1698C ; [.308E.0020.0002.1698C] # BAMUM LETTER PHASE-E LOOT +1698D ; [.308F.0020.0002.1698D] # BAMUM LETTER PHASE-E NGGEEEE +1698E ; [.3090.0020.0002.1698E] # BAMUM LETTER PHASE-E NDIQ +1698F ; [.3091.0020.0002.1698F] # BAMUM LETTER PHASE-E TAEN NTEUM +16990 ; [.3092.0020.0002.16990] # BAMUM LETTER PHASE-E SET +16991 ; [.3093.0020.0002.16991] # BAMUM LETTER PHASE-E PUM +16992 ; [.3094.0020.0002.16992] # BAMUM LETTER PHASE-E NDAA SOFTNESS +16993 ; [.3095.0020.0002.16993] # BAMUM LETTER PHASE-E NGGUAESHAE NYAM +16994 ; [.3096.0020.0002.16994] # BAMUM LETTER PHASE-E YIEE +16995 ; [.3097.0020.0002.16995] # BAMUM LETTER PHASE-E GHEUN +16996 ; [.3098.0020.0002.16996] # BAMUM LETTER PHASE-E TUAE +16997 ; [.3099.0020.0002.16997] # BAMUM LETTER PHASE-E YEUAE +16998 ; [.309A.0020.0002.16998] # BAMUM LETTER PHASE-E PO +16999 ; [.309B.0020.0002.16999] # BAMUM LETTER PHASE-E TUMAE +1699A ; [.309C.0020.0002.1699A] # BAMUM LETTER PHASE-E KEUAE +1699B ; [.309D.0020.0002.1699B] # BAMUM LETTER PHASE-E SUAEN +1699C ; [.309E.0020.0002.1699C] # BAMUM LETTER PHASE-E TEUAEQ +1699D ; [.309F.0020.0002.1699D] # BAMUM LETTER PHASE-E VEUAE +1699E ; [.30A0.0020.0002.1699E] # BAMUM LETTER PHASE-E WEUX +1699F ; [.30A1.0020.0002.1699F] # BAMUM LETTER PHASE-E LAAM +169A0 ; [.30A2.0020.0002.169A0] # BAMUM LETTER PHASE-E PU +169A1 ; [.30A3.0020.0002.169A1] # BAMUM LETTER PHASE-E TAAQ +169A2 ; [.30A4.0020.0002.169A2] # BAMUM LETTER PHASE-E GHAAMAE +169A3 ; [.30A5.0020.0002.169A3] # BAMUM LETTER PHASE-E NGEUREUT +169A4 ; [.30A6.0020.0002.169A4] # BAMUM LETTER PHASE-E SHEUAEQ +169A5 ; [.30A7.0020.0002.169A5] # BAMUM LETTER PHASE-E MGBEN +169A6 ; [.30A8.0020.0002.169A6] # BAMUM LETTER PHASE-E MBEE +169A7 ; [.30A9.0020.0002.169A7] # BAMUM LETTER PHASE-E NZAQ +169A8 ; [.30AA.0020.0002.169A8] # BAMUM LETTER PHASE-E NKOM +169A9 ; [.30AB.0020.0002.169A9] # BAMUM LETTER PHASE-E GBET +169AA ; [.30AC.0020.0002.169AA] # BAMUM LETTER PHASE-E TUM +169AB ; [.30AD.0020.0002.169AB] # BAMUM LETTER PHASE-E KUET +169AC ; [.30AE.0020.0002.169AC] # BAMUM LETTER PHASE-E YAP +169AD ; [.30AF.0020.0002.169AD] # BAMUM LETTER PHASE-E NYI CLEAVER +169AE ; [.30B0.0020.0002.169AE] # BAMUM LETTER PHASE-E YIT +169AF ; [.30B1.0020.0002.169AF] # BAMUM LETTER PHASE-E MFEUQ +169B0 ; [.30B2.0020.0002.169B0] # BAMUM LETTER PHASE-E NDIAQ +169B1 ; [.30B3.0020.0002.169B1] # BAMUM LETTER PHASE-E PIEEQ +169B2 ; [.30B4.0020.0002.169B2] # BAMUM LETTER PHASE-E YUEQ +169B3 ; [.30B5.0020.0002.169B3] # BAMUM LETTER PHASE-E LEUAEM +169B4 ; [.30B6.0020.0002.169B4] # BAMUM LETTER PHASE-E FUE +169B5 ; [.30B7.0020.0002.169B5] # BAMUM LETTER PHASE-E GBEUX +169B6 ; [.30B8.0020.0002.169B6] # BAMUM LETTER PHASE-E NGKUP +169B7 ; [.30B9.0020.0002.169B7] # BAMUM LETTER PHASE-E KET +169B8 ; [.30BA.0020.0002.169B8] # BAMUM LETTER PHASE-E MAE +169B9 ; [.30BB.0020.0002.169B9] # BAMUM LETTER PHASE-E NGKAAMI +169BA ; [.30BC.0020.0002.169BA] # BAMUM LETTER PHASE-E GHET +169BB ; [.30BD.0020.0002.169BB] # BAMUM LETTER PHASE-E FA +169BC ; [.30BE.0020.0002.169BC] # BAMUM LETTER PHASE-E NTUM +169BD ; [.30BF.0020.0002.169BD] # BAMUM LETTER PHASE-E PEUT +169BE ; [.30C0.0020.0002.169BE] # BAMUM LETTER PHASE-E YEUM +169BF ; [.30C1.0020.0002.169BF] # BAMUM LETTER PHASE-E NGGEUAE +169C0 ; [.30C2.0020.0002.169C0] # BAMUM LETTER PHASE-E NYI BETWEEN +169C1 ; [.30C3.0020.0002.169C1] # BAMUM LETTER PHASE-E NZUQ +169C2 ; [.30C4.0020.0002.169C2] # BAMUM LETTER PHASE-E POON +169C3 ; [.30C5.0020.0002.169C3] # BAMUM LETTER PHASE-E MIEE +169C4 ; [.30C6.0020.0002.169C4] # BAMUM LETTER PHASE-E FUET +169C5 ; [.30C7.0020.0002.169C5] # BAMUM LETTER PHASE-E NAE +169C6 ; [.30C8.0020.0002.169C6] # BAMUM LETTER PHASE-E MUAE +169C7 ; [.30C9.0020.0002.169C7] # BAMUM LETTER PHASE-E GHEUAE +169C8 ; [.30CA.0020.0002.169C8] # BAMUM LETTER PHASE-E FU I +169C9 ; [.30CB.0020.0002.169C9] # BAMUM LETTER PHASE-E MVI +169CA ; [.30CC.0020.0002.169CA] # BAMUM LETTER PHASE-E PUAQ +169CB ; [.30CD.0020.0002.169CB] # BAMUM LETTER PHASE-E NGKUM +169CC ; [.30CE.0020.0002.169CC] # BAMUM LETTER PHASE-E KUT +169CD ; [.30CF.0020.0002.169CD] # BAMUM LETTER PHASE-E PIET +169CE ; [.30D0.0020.0002.169CE] # BAMUM LETTER PHASE-E NTAP +169CF ; [.30D1.0020.0002.169CF] # BAMUM LETTER PHASE-E YEUAET +169D0 ; [.30D2.0020.0002.169D0] # BAMUM LETTER PHASE-E NGGUP +169D1 ; [.30D3.0020.0002.169D1] # BAMUM LETTER PHASE-E PA PEOPLE +169D2 ; [.30D4.0020.0002.169D2] # BAMUM LETTER PHASE-E FU CALL +169D3 ; [.30D5.0020.0002.169D3] # BAMUM LETTER PHASE-E FOM +169D4 ; [.30D6.0020.0002.169D4] # BAMUM LETTER PHASE-E NJEE +169D5 ; [.30D7.0020.0002.169D5] # BAMUM LETTER PHASE-E A +169D6 ; [.30D8.0020.0002.169D6] # BAMUM LETTER PHASE-E TOQ +169D7 ; [.30D9.0020.0002.169D7] # BAMUM LETTER PHASE-E O +169D8 ; [.30DA.0020.0002.169D8] # BAMUM LETTER PHASE-E I +169D9 ; [.30DB.0020.0002.169D9] # BAMUM LETTER PHASE-E LAQ +169DA ; [.30DC.0020.0002.169DA] # BAMUM LETTER PHASE-E PA PLURAL +169DB ; [.30DD.0020.0002.169DB] # BAMUM LETTER PHASE-E TAA +169DC ; [.30DE.0020.0002.169DC] # BAMUM LETTER PHASE-E TAQ +169DD ; [.30DF.0020.0002.169DD] # BAMUM LETTER PHASE-E NDAA MY HOUSE +169DE ; [.30E0.0020.0002.169DE] # BAMUM LETTER PHASE-E SHIQ +169DF ; [.30E1.0020.0002.169DF] # BAMUM LETTER PHASE-E YEUX +169E0 ; [.30E2.0020.0002.169E0] # BAMUM LETTER PHASE-E NGUAE +169E1 ; [.30E3.0020.0002.169E1] # BAMUM LETTER PHASE-E YUAEN +169E2 ; [.30E4.0020.0002.169E2] # BAMUM LETTER PHASE-E YOQ SWIMMING +169E3 ; [.30E5.0020.0002.169E3] # BAMUM LETTER PHASE-E YOQ COVER +169E4 ; [.30E6.0020.0002.169E4] # BAMUM LETTER PHASE-E YUQ +169E5 ; [.30E7.0020.0002.169E5] # BAMUM LETTER PHASE-E YUN +169E6 ; [.30E8.0020.0002.169E6] # BAMUM LETTER PHASE-E KEUX +169E7 ; [.30E9.0020.0002.169E7] # BAMUM LETTER PHASE-E PEUX +169E8 ; [.30EA.0020.0002.169E8] # BAMUM LETTER PHASE-E NJEE EPOCH +169E9 ; [.30EB.0020.0002.169E9] # BAMUM LETTER PHASE-E PUE +169EA ; [.30EC.0020.0002.169EA] # BAMUM LETTER PHASE-E WUE +169EB ; [.30ED.0020.0002.169EB] # BAMUM LETTER PHASE-E FEE +169EC ; [.30EE.0020.0002.169EC] # BAMUM LETTER PHASE-E VEE +169ED ; [.30EF.0020.0002.169ED] # BAMUM LETTER PHASE-E LU +169EE ; [.30F0.0020.0002.169EE] # BAMUM LETTER PHASE-E MI +169EF ; [.30F1.0020.0002.169EF] # BAMUM LETTER PHASE-E REUX +169F0 ; [.30F2.0020.0002.169F0] # BAMUM LETTER PHASE-E RAE +169F1 ; [.30F3.0020.0002.169F1] # BAMUM LETTER PHASE-E NGUAET +169F2 ; [.30F4.0020.0002.169F2] # BAMUM LETTER PHASE-E NGA +169F3 ; [.30F5.0020.0002.169F3] # BAMUM LETTER PHASE-E SHO +169F4 ; [.30F6.0020.0002.169F4] # BAMUM LETTER PHASE-E SHOQ +169F5 ; [.30F7.0020.0002.169F5] # BAMUM LETTER PHASE-E FU REMEDY +169F6 ; [.30F8.0020.0002.169F6] # BAMUM LETTER PHASE-E NA +169F7 ; [.30F9.0020.0002.169F7] # BAMUM LETTER PHASE-E PI +169F8 ; [.30FA.0020.0002.169F8] # BAMUM LETTER PHASE-E LOQ +169F9 ; [.30FB.0020.0002.169F9] # BAMUM LETTER PHASE-E KO +169FA ; [.30FC.0020.0002.169FA] # BAMUM LETTER PHASE-E MEN +169FB ; [.30FD.0020.0002.169FB] # BAMUM LETTER PHASE-E MA +169FC ; [.30FE.0020.0002.169FC] # BAMUM LETTER PHASE-E MAQ +169FD ; [.30FF.0020.0002.169FD] # BAMUM LETTER PHASE-E TEU +169FE ; [.3100.0020.0002.169FE] # BAMUM LETTER PHASE-E KI +169FF ; [.3101.0020.0002.169FF] # BAMUM LETTER PHASE-E MON +16A00 ; [.3102.0020.0002.16A00] # BAMUM LETTER PHASE-E TEN +16A01 ; [.3103.0020.0002.16A01] # BAMUM LETTER PHASE-E FAQ +16A02 ; [.3104.0020.0002.16A02] # BAMUM LETTER PHASE-E GHOM +16A03 ; [.3105.0020.0002.16A03] # BAMUM LETTER PHASE-F KA +16A04 ; [.3106.0020.0002.16A04] # BAMUM LETTER PHASE-F U +16A05 ; [.3107.0020.0002.16A05] # BAMUM LETTER PHASE-F KU +16A06 ; [.3108.0020.0002.16A06] # BAMUM LETTER PHASE-F EE +16A07 ; [.3109.0020.0002.16A07] # BAMUM LETTER PHASE-F REE +16A08 ; [.310A.0020.0002.16A08] # BAMUM LETTER PHASE-F TAE +16A09 ; [.310B.0020.0002.16A09] # BAMUM LETTER PHASE-F NYI +16A0A ; [.310C.0020.0002.16A0A] # BAMUM LETTER PHASE-F LA +16A0B ; [.310D.0020.0002.16A0B] # BAMUM LETTER PHASE-F RII +16A0C ; [.310E.0020.0002.16A0C] # BAMUM LETTER PHASE-F RIEE +16A0D ; [.310F.0020.0002.16A0D] # BAMUM LETTER PHASE-F MEEEE +16A0E ; [.3110.0020.0002.16A0E] # BAMUM LETTER PHASE-F TAA +16A0F ; [.3111.0020.0002.16A0F] # BAMUM LETTER PHASE-F NDAA +16A10 ; [.3112.0020.0002.16A10] # BAMUM LETTER PHASE-F NJAEM +16A11 ; [.3113.0020.0002.16A11] # BAMUM LETTER PHASE-F M +16A12 ; [.3114.0020.0002.16A12] # BAMUM LETTER PHASE-F SUU +16A13 ; [.3115.0020.0002.16A13] # BAMUM LETTER PHASE-F SHII +16A14 ; [.3116.0020.0002.16A14] # BAMUM LETTER PHASE-F SI +16A15 ; [.3117.0020.0002.16A15] # BAMUM LETTER PHASE-F SEUX +16A16 ; [.3118.0020.0002.16A16] # BAMUM LETTER PHASE-F KYEE +16A17 ; [.3119.0020.0002.16A17] # BAMUM LETTER PHASE-F KET +16A18 ; [.311A.0020.0002.16A18] # BAMUM LETTER PHASE-F NUAE +16A19 ; [.311B.0020.0002.16A19] # BAMUM LETTER PHASE-F NU +16A1A ; [.311C.0020.0002.16A1A] # BAMUM LETTER PHASE-F NJUAE +16A1B ; [.311D.0020.0002.16A1B] # BAMUM LETTER PHASE-F YOQ +16A1C ; [.311E.0020.0002.16A1C] # BAMUM LETTER PHASE-F SHU +16A1D ; [.311F.0020.0002.16A1D] # BAMUM LETTER PHASE-F YA +16A1E ; [.3120.0020.0002.16A1E] # BAMUM LETTER PHASE-F NSHA +16A1F ; [.3121.0020.0002.16A1F] # BAMUM LETTER PHASE-F PEUX +16A20 ; [.3122.0020.0002.16A20] # BAMUM LETTER PHASE-F NTEE +16A21 ; [.3123.0020.0002.16A21] # BAMUM LETTER PHASE-F WUE +16A22 ; [.3124.0020.0002.16A22] # BAMUM LETTER PHASE-F PEE +16A23 ; [.3125.0020.0002.16A23] # BAMUM LETTER PHASE-F RU +16A24 ; [.3126.0020.0002.16A24] # BAMUM LETTER PHASE-F NI +16A25 ; [.3127.0020.0002.16A25] # BAMUM LETTER PHASE-F REUX +16A26 ; [.3128.0020.0002.16A26] # BAMUM LETTER PHASE-F KEN +16A27 ; [.3129.0020.0002.16A27] # BAMUM LETTER PHASE-F NGKWAEN +16A28 ; [.312A.0020.0002.16A28] # BAMUM LETTER PHASE-F NGGA +16A29 ; [.312B.0020.0002.16A29] # BAMUM LETTER PHASE-F SHO +16A2A ; [.312C.0020.0002.16A2A] # BAMUM LETTER PHASE-F PUAE +16A2B ; [.312D.0020.0002.16A2B] # BAMUM LETTER PHASE-F FOM +16A2C ; [.312E.0020.0002.16A2C] # BAMUM LETTER PHASE-F WA +16A2D ; [.312F.0020.0002.16A2D] # BAMUM LETTER PHASE-F LI +16A2E ; [.3130.0020.0002.16A2E] # BAMUM LETTER PHASE-F LOQ +16A2F ; [.3131.0020.0002.16A2F] # BAMUM LETTER PHASE-F KO +16A30 ; [.3132.0020.0002.16A30] # BAMUM LETTER PHASE-F MBEN +16A31 ; [.3133.0020.0002.16A31] # BAMUM LETTER PHASE-F REN +16A32 ; [.3134.0020.0002.16A32] # BAMUM LETTER PHASE-F MA +16A33 ; [.3135.0020.0002.16A33] # BAMUM LETTER PHASE-F MO +16A34 ; [.3136.0020.0002.16A34] # BAMUM LETTER PHASE-F MBAA +16A35 ; [.3137.0020.0002.16A35] # BAMUM LETTER PHASE-F TET +16A36 ; [.3138.0020.0002.16A36] # BAMUM LETTER PHASE-F KPA +16A37 ; [.3139.0020.0002.16A37] # BAMUM LETTER PHASE-F SAMBA +16A38 ; [.313A.0020.0002.16A38] # BAMUM LETTER PHASE-F VUEQ +1100 ; [.313B.0020.0002.1100] # HANGUL CHOSEONG KIYEOK +3131 ; [.313B.0020.0004.3131] # HANGUL LETTER KIYEOK +3200 ; [*02FB.0020.0004.3200][.313B.0020.0004.3200][*02FC.0020.001F.3200] # PARENTHESIZED HANGUL KIYEOK +3260 ; [.313B.0020.0006.3260] # CIRCLED HANGUL KIYEOK +FFA1 ; [.313B.0020.0012.FFA1] # HALFWIDTH HANGUL LETTER KIYEOK +320E ; [*02FB.0020.0004.320E][.313B.0020.0004.320E][.31B9.0020.001F.320E][*02FC.0020.001F.320E] # PARENTHESIZED HANGUL KIYEOK A +326E ; [.313B.0020.0006.326E][.31B9.0020.0006.326E] # CIRCLED HANGUL KIYEOK A +1101 ; [.313C.0020.0002.1101] # HANGUL CHOSEONG SSANGKIYEOK +3132 ; [.313C.0020.0004.3132] # HANGUL LETTER SSANGKIYEOK +FFA2 ; [.313C.0020.0012.FFA2] # HALFWIDTH HANGUL LETTER SSANGKIYEOK +1102 ; [.313D.0020.0002.1102] # HANGUL CHOSEONG NIEUN +3134 ; [.313D.0020.0004.3134] # HANGUL LETTER NIEUN +3201 ; [*02FB.0020.0004.3201][.313D.0020.0004.3201][*02FC.0020.001F.3201] # PARENTHESIZED HANGUL NIEUN +3261 ; [.313D.0020.0006.3261] # CIRCLED HANGUL NIEUN +FFA4 ; [.313D.0020.0012.FFA4] # HALFWIDTH HANGUL LETTER NIEUN +320F ; [*02FB.0020.0004.320F][.313D.0020.0004.320F][.31B9.0020.001F.320F][*02FC.0020.001F.320F] # PARENTHESIZED HANGUL NIEUN A +326F ; [.313D.0020.0006.326F][.31B9.0020.0006.326F] # CIRCLED HANGUL NIEUN A +1103 ; [.313E.0020.0002.1103] # HANGUL CHOSEONG TIKEUT +3137 ; [.313E.0020.0004.3137] # HANGUL LETTER TIKEUT +3202 ; [*02FB.0020.0004.3202][.313E.0020.0004.3202][*02FC.0020.001F.3202] # PARENTHESIZED HANGUL TIKEUT +3262 ; [.313E.0020.0006.3262] # CIRCLED HANGUL TIKEUT +FFA7 ; [.313E.0020.0012.FFA7] # HALFWIDTH HANGUL LETTER TIKEUT +3210 ; [*02FB.0020.0004.3210][.313E.0020.0004.3210][.31B9.0020.001F.3210][*02FC.0020.001F.3210] # PARENTHESIZED HANGUL TIKEUT A +3270 ; [.313E.0020.0006.3270][.31B9.0020.0006.3270] # CIRCLED HANGUL TIKEUT A +1104 ; [.313F.0020.0002.1104] # HANGUL CHOSEONG SSANGTIKEUT +3138 ; [.313F.0020.0004.3138] # HANGUL LETTER SSANGTIKEUT +FFA8 ; [.313F.0020.0012.FFA8] # HALFWIDTH HANGUL LETTER SSANGTIKEUT +1105 ; [.3140.0020.0002.1105] # HANGUL CHOSEONG RIEUL +3139 ; [.3140.0020.0004.3139] # HANGUL LETTER RIEUL +3203 ; [*02FB.0020.0004.3203][.3140.0020.0004.3203][*02FC.0020.001F.3203] # PARENTHESIZED HANGUL RIEUL +3263 ; [.3140.0020.0006.3263] # CIRCLED HANGUL RIEUL +FFA9 ; [.3140.0020.0012.FFA9] # HALFWIDTH HANGUL LETTER RIEUL +3211 ; [*02FB.0020.0004.3211][.3140.0020.0004.3211][.31B9.0020.001F.3211][*02FC.0020.001F.3211] # PARENTHESIZED HANGUL RIEUL A +3271 ; [.3140.0020.0006.3271][.31B9.0020.0006.3271] # CIRCLED HANGUL RIEUL A +1106 ; [.3141.0020.0002.1106] # HANGUL CHOSEONG MIEUM +3141 ; [.3141.0020.0004.3141] # HANGUL LETTER MIEUM +3204 ; [*02FB.0020.0004.3204][.3141.0020.0004.3204][*02FC.0020.001F.3204] # PARENTHESIZED HANGUL MIEUM +3264 ; [.3141.0020.0006.3264] # CIRCLED HANGUL MIEUM +FFB1 ; [.3141.0020.0012.FFB1] # HALFWIDTH HANGUL LETTER MIEUM +3212 ; [*02FB.0020.0004.3212][.3141.0020.0004.3212][.31B9.0020.001F.3212][*02FC.0020.001F.3212] # PARENTHESIZED HANGUL MIEUM A +3272 ; [.3141.0020.0006.3272][.31B9.0020.0006.3272] # CIRCLED HANGUL MIEUM A +1107 ; [.3142.0020.0002.1107] # HANGUL CHOSEONG PIEUP +3142 ; [.3142.0020.0004.3142] # HANGUL LETTER PIEUP +3205 ; [*02FB.0020.0004.3205][.3142.0020.0004.3205][*02FC.0020.001F.3205] # PARENTHESIZED HANGUL PIEUP +3265 ; [.3142.0020.0006.3265] # CIRCLED HANGUL PIEUP +FFB2 ; [.3142.0020.0012.FFB2] # HALFWIDTH HANGUL LETTER PIEUP +3213 ; [*02FB.0020.0004.3213][.3142.0020.0004.3213][.31B9.0020.001F.3213][*02FC.0020.001F.3213] # PARENTHESIZED HANGUL PIEUP A +3273 ; [.3142.0020.0006.3273][.31B9.0020.0006.3273] # CIRCLED HANGUL PIEUP A +1108 ; [.3143.0020.0002.1108] # HANGUL CHOSEONG SSANGPIEUP +3143 ; [.3143.0020.0004.3143] # HANGUL LETTER SSANGPIEUP +FFB3 ; [.3143.0020.0012.FFB3] # HALFWIDTH HANGUL LETTER SSANGPIEUP +1109 ; [.3144.0020.0002.1109] # HANGUL CHOSEONG SIOS +3145 ; [.3144.0020.0004.3145] # HANGUL LETTER SIOS +3206 ; [*02FB.0020.0004.3206][.3144.0020.0004.3206][*02FC.0020.001F.3206] # PARENTHESIZED HANGUL SIOS +3266 ; [.3144.0020.0006.3266] # CIRCLED HANGUL SIOS +FFB5 ; [.3144.0020.0012.FFB5] # HALFWIDTH HANGUL LETTER SIOS +3214 ; [*02FB.0020.0004.3214][.3144.0020.0004.3214][.31B9.0020.001F.3214][*02FC.0020.001F.3214] # PARENTHESIZED HANGUL SIOS A +3274 ; [.3144.0020.0006.3274][.31B9.0020.0006.3274] # CIRCLED HANGUL SIOS A +110A ; [.3145.0020.0002.110A] # HANGUL CHOSEONG SSANGSIOS +3146 ; [.3145.0020.0004.3146] # HANGUL LETTER SSANGSIOS +FFB6 ; [.3145.0020.0012.FFB6] # HALFWIDTH HANGUL LETTER SSANGSIOS +110B ; [.3146.0020.0002.110B] # HANGUL CHOSEONG IEUNG +3147 ; [.3146.0020.0004.3147] # HANGUL LETTER IEUNG +3207 ; [*02FB.0020.0004.3207][.3146.0020.0004.3207][*02FC.0020.001F.3207] # PARENTHESIZED HANGUL IEUNG +3267 ; [.3146.0020.0006.3267] # CIRCLED HANGUL IEUNG +FFB7 ; [.3146.0020.0012.FFB7] # HALFWIDTH HANGUL LETTER IEUNG +3215 ; [*02FB.0020.0004.3215][.3146.0020.0004.3215][.31B9.0020.001F.3215][*02FC.0020.001F.3215] # PARENTHESIZED HANGUL IEUNG A +3275 ; [.3146.0020.0006.3275][.31B9.0020.0006.3275] # CIRCLED HANGUL IEUNG A +321D ; [*02FB.0020.0004.321D][.3146.0020.0004.321D][.31C1.0020.001F.321D][.3147.0020.001F.321D][.31BD.0020.001F.321D][.321A.0020.001F.321D][*02FC.0020.001F.321D] # PARENTHESIZED KOREAN CHARACTER OJEON +321E ; [*02FB.0020.0004.321E][.3146.0020.0004.321E][.31C1.0020.001F.321E][.314D.0020.001F.321E][.31C6.0020.001F.321E][*02FC.0020.001F.321E] # PARENTHESIZED KOREAN CHARACTER O HU +327E ; [.3146.0020.0006.327E][.31C6.0020.0006.327E] # CIRCLED HANGUL IEUNG U +110C ; [.3147.0020.0002.110C] # HANGUL CHOSEONG CIEUC +3148 ; [.3147.0020.0004.3148] # HANGUL LETTER CIEUC +3208 ; [*02FB.0020.0004.3208][.3147.0020.0004.3208][*02FC.0020.001F.3208] # PARENTHESIZED HANGUL CIEUC +3268 ; [.3147.0020.0006.3268] # CIRCLED HANGUL CIEUC +FFB8 ; [.3147.0020.0012.FFB8] # HALFWIDTH HANGUL LETTER CIEUC +3216 ; [*02FB.0020.0004.3216][.3147.0020.0004.3216][.31B9.0020.001F.3216][*02FC.0020.001F.3216] # PARENTHESIZED HANGUL CIEUC A +3276 ; [.3147.0020.0006.3276][.31B9.0020.0006.3276] # CIRCLED HANGUL CIEUC A +321C ; [*02FB.0020.0004.321C][.3147.0020.0004.321C][.31C6.0020.001F.321C][*02FC.0020.001F.321C] # PARENTHESIZED HANGUL CIEUC U +327D ; [.3147.0020.0006.327D][.31C6.0020.0006.327D][.3146.0020.001F.327D][.31CC.0020.001F.327D] # CIRCLED KOREAN CHARACTER JUEUI +110D ; [.3148.0020.0002.110D] # HANGUL CHOSEONG SSANGCIEUC +3149 ; [.3148.0020.0004.3149] # HANGUL LETTER SSANGCIEUC +FFB9 ; [.3148.0020.0012.FFB9] # HALFWIDTH HANGUL LETTER SSANGCIEUC +110E ; [.3149.0020.0002.110E] # HANGUL CHOSEONG CHIEUCH +314A ; [.3149.0020.0004.314A] # HANGUL LETTER CHIEUCH +3209 ; [*02FB.0020.0004.3209][.3149.0020.0004.3209][*02FC.0020.001F.3209] # PARENTHESIZED HANGUL CHIEUCH +3269 ; [.3149.0020.0006.3269] # CIRCLED HANGUL CHIEUCH +FFBA ; [.3149.0020.0012.FFBA] # HALFWIDTH HANGUL LETTER CHIEUCH +3217 ; [*02FB.0020.0004.3217][.3149.0020.0004.3217][.31B9.0020.001F.3217][*02FC.0020.001F.3217] # PARENTHESIZED HANGUL CHIEUCH A +3277 ; [.3149.0020.0006.3277][.31B9.0020.0006.3277] # CIRCLED HANGUL CHIEUCH A +327C ; [.3149.0020.0006.327C][.31B9.0020.0006.327C][.3226.0020.001F.327C][.313B.0020.001F.327C][.31C1.0020.001F.327C] # CIRCLED KOREAN CHARACTER CHAMKO +110F ; [.314A.0020.0002.110F] # HANGUL CHOSEONG KHIEUKH +314B ; [.314A.0020.0004.314B] # HANGUL LETTER KHIEUKH +320A ; [*02FB.0020.0004.320A][.314A.0020.0004.320A][*02FC.0020.001F.320A] # PARENTHESIZED HANGUL KHIEUKH +326A ; [.314A.0020.0006.326A] # CIRCLED HANGUL KHIEUKH +FFBB ; [.314A.0020.0012.FFBB] # HALFWIDTH HANGUL LETTER KHIEUKH +3218 ; [*02FB.0020.0004.3218][.314A.0020.0004.3218][.31B9.0020.001F.3218][*02FC.0020.001F.3218] # PARENTHESIZED HANGUL KHIEUKH A +3278 ; [.314A.0020.0006.3278][.31B9.0020.0006.3278] # CIRCLED HANGUL KHIEUKH A +1110 ; [.314B.0020.0002.1110] # HANGUL CHOSEONG THIEUTH +314C ; [.314B.0020.0004.314C] # HANGUL LETTER THIEUTH +320B ; [*02FB.0020.0004.320B][.314B.0020.0004.320B][*02FC.0020.001F.320B] # PARENTHESIZED HANGUL THIEUTH +326B ; [.314B.0020.0006.326B] # CIRCLED HANGUL THIEUTH +FFBC ; [.314B.0020.0012.FFBC] # HALFWIDTH HANGUL LETTER THIEUTH +3219 ; [*02FB.0020.0004.3219][.314B.0020.0004.3219][.31B9.0020.001F.3219][*02FC.0020.001F.3219] # PARENTHESIZED HANGUL THIEUTH A +3279 ; [.314B.0020.0006.3279][.31B9.0020.0006.3279] # CIRCLED HANGUL THIEUTH A +1111 ; [.314C.0020.0002.1111] # HANGUL CHOSEONG PHIEUPH +314D ; [.314C.0020.0004.314D] # HANGUL LETTER PHIEUPH +320C ; [*02FB.0020.0004.320C][.314C.0020.0004.320C][*02FC.0020.001F.320C] # PARENTHESIZED HANGUL PHIEUPH +326C ; [.314C.0020.0006.326C] # CIRCLED HANGUL PHIEUPH +FFBD ; [.314C.0020.0012.FFBD] # HALFWIDTH HANGUL LETTER PHIEUPH +321A ; [*02FB.0020.0004.321A][.314C.0020.0004.321A][.31B9.0020.001F.321A][*02FC.0020.001F.321A] # PARENTHESIZED HANGUL PHIEUPH A +327A ; [.314C.0020.0006.327A][.31B9.0020.0006.327A] # CIRCLED HANGUL PHIEUPH A +1112 ; [.314D.0020.0002.1112] # HANGUL CHOSEONG HIEUH +314E ; [.314D.0020.0004.314E] # HANGUL LETTER HIEUH +320D ; [*02FB.0020.0004.320D][.314D.0020.0004.320D][*02FC.0020.001F.320D] # PARENTHESIZED HANGUL HIEUH +326D ; [.314D.0020.0006.326D] # CIRCLED HANGUL HIEUH +FFBE ; [.314D.0020.0012.FFBE] # HALFWIDTH HANGUL LETTER HIEUH +321B ; [*02FB.0020.0004.321B][.314D.0020.0004.321B][.31B9.0020.001F.321B][*02FC.0020.001F.321B] # PARENTHESIZED HANGUL HIEUH A +327B ; [.314D.0020.0006.327B][.31B9.0020.0006.327B] # CIRCLED HANGUL HIEUH A +1113 ; [.314E.0020.0002.1113] # HANGUL CHOSEONG NIEUN-KIYEOK +1114 ; [.314F.0020.0002.1114] # HANGUL CHOSEONG SSANGNIEUN +3165 ; [.314F.0020.0004.3165] # HANGUL LETTER SSANGNIEUN +1115 ; [.3150.0020.0002.1115] # HANGUL CHOSEONG NIEUN-TIKEUT +3166 ; [.3150.0020.0004.3166] # HANGUL LETTER NIEUN-TIKEUT +1116 ; [.3151.0020.0002.1116] # HANGUL CHOSEONG NIEUN-PIEUP +1117 ; [.3152.0020.0002.1117] # HANGUL CHOSEONG TIKEUT-KIYEOK +1118 ; [.3153.0020.0002.1118] # HANGUL CHOSEONG RIEUL-NIEUN +1119 ; [.3154.0020.0002.1119] # HANGUL CHOSEONG SSANGRIEUL +111A ; [.3155.0020.0002.111A] # HANGUL CHOSEONG RIEUL-HIEUH +3140 ; [.3155.0020.0004.3140] # HANGUL LETTER RIEUL-HIEUH +FFB0 ; [.3155.0020.0012.FFB0] # HALFWIDTH HANGUL LETTER RIEUL-HIEUH +111B ; [.3156.0020.0002.111B] # HANGUL CHOSEONG KAPYEOUNRIEUL +111C ; [.3157.0020.0002.111C] # HANGUL CHOSEONG MIEUM-PIEUP +316E ; [.3157.0020.0004.316E] # HANGUL LETTER MIEUM-PIEUP +111D ; [.3158.0020.0002.111D] # HANGUL CHOSEONG KAPYEOUNMIEUM +3171 ; [.3158.0020.0004.3171] # HANGUL LETTER KAPYEOUNMIEUM +111E ; [.3159.0020.0002.111E] # HANGUL CHOSEONG PIEUP-KIYEOK +3172 ; [.3159.0020.0004.3172] # HANGUL LETTER PIEUP-KIYEOK +111F ; [.315A.0020.0002.111F] # HANGUL CHOSEONG PIEUP-NIEUN +1120 ; [.315B.0020.0002.1120] # HANGUL CHOSEONG PIEUP-TIKEUT +3173 ; [.315B.0020.0004.3173] # HANGUL LETTER PIEUP-TIKEUT +1121 ; [.315C.0020.0002.1121] # HANGUL CHOSEONG PIEUP-SIOS +3144 ; [.315C.0020.0004.3144] # HANGUL LETTER PIEUP-SIOS +FFB4 ; [.315C.0020.0012.FFB4] # HALFWIDTH HANGUL LETTER PIEUP-SIOS +1122 ; [.315D.0020.0002.1122] # HANGUL CHOSEONG PIEUP-SIOS-KIYEOK +3174 ; [.315D.0020.0004.3174] # HANGUL LETTER PIEUP-SIOS-KIYEOK +1123 ; [.315E.0020.0002.1123] # HANGUL CHOSEONG PIEUP-SIOS-TIKEUT +3175 ; [.315E.0020.0004.3175] # HANGUL LETTER PIEUP-SIOS-TIKEUT +1124 ; [.315F.0020.0002.1124] # HANGUL CHOSEONG PIEUP-SIOS-PIEUP +1125 ; [.3160.0020.0002.1125] # HANGUL CHOSEONG PIEUP-SSANGSIOS +1126 ; [.3161.0020.0002.1126] # HANGUL CHOSEONG PIEUP-SIOS-CIEUC +1127 ; [.3162.0020.0002.1127] # HANGUL CHOSEONG PIEUP-CIEUC +3176 ; [.3162.0020.0004.3176] # HANGUL LETTER PIEUP-CIEUC +1128 ; [.3163.0020.0002.1128] # HANGUL CHOSEONG PIEUP-CHIEUCH +1129 ; [.3164.0020.0002.1129] # HANGUL CHOSEONG PIEUP-THIEUTH +3177 ; [.3164.0020.0004.3177] # HANGUL LETTER PIEUP-THIEUTH +112A ; [.3165.0020.0002.112A] # HANGUL CHOSEONG PIEUP-PHIEUPH +112B ; [.3166.0020.0002.112B] # HANGUL CHOSEONG KAPYEOUNPIEUP +3178 ; [.3166.0020.0004.3178] # HANGUL LETTER KAPYEOUNPIEUP +112C ; [.3167.0020.0002.112C] # HANGUL CHOSEONG KAPYEOUNSSANGPIEUP +3179 ; [.3167.0020.0004.3179] # HANGUL LETTER KAPYEOUNSSANGPIEUP +112D ; [.3168.0020.0002.112D] # HANGUL CHOSEONG SIOS-KIYEOK +317A ; [.3168.0020.0004.317A] # HANGUL LETTER SIOS-KIYEOK +112E ; [.3169.0020.0002.112E] # HANGUL CHOSEONG SIOS-NIEUN +317B ; [.3169.0020.0004.317B] # HANGUL LETTER SIOS-NIEUN +112F ; [.316A.0020.0002.112F] # HANGUL CHOSEONG SIOS-TIKEUT +317C ; [.316A.0020.0004.317C] # HANGUL LETTER SIOS-TIKEUT +1130 ; [.316B.0020.0002.1130] # HANGUL CHOSEONG SIOS-RIEUL +1131 ; [.316C.0020.0002.1131] # HANGUL CHOSEONG SIOS-MIEUM +1132 ; [.316D.0020.0002.1132] # HANGUL CHOSEONG SIOS-PIEUP +317D ; [.316D.0020.0004.317D] # HANGUL LETTER SIOS-PIEUP +1133 ; [.316E.0020.0002.1133] # HANGUL CHOSEONG SIOS-PIEUP-KIYEOK +1134 ; [.316F.0020.0002.1134] # HANGUL CHOSEONG SIOS-SSANGSIOS +1135 ; [.3170.0020.0002.1135] # HANGUL CHOSEONG SIOS-IEUNG +1136 ; [.3171.0020.0002.1136] # HANGUL CHOSEONG SIOS-CIEUC +317E ; [.3171.0020.0004.317E] # HANGUL LETTER SIOS-CIEUC +1137 ; [.3172.0020.0002.1137] # HANGUL CHOSEONG SIOS-CHIEUCH +1138 ; [.3173.0020.0002.1138] # HANGUL CHOSEONG SIOS-KHIEUKH +1139 ; [.3174.0020.0002.1139] # HANGUL CHOSEONG SIOS-THIEUTH +113A ; [.3175.0020.0002.113A] # HANGUL CHOSEONG SIOS-PHIEUPH +113B ; [.3176.0020.0002.113B] # HANGUL CHOSEONG SIOS-HIEUH +113C ; [.3177.0020.0002.113C] # HANGUL CHOSEONG CHITUEUMSIOS +113D ; [.3178.0020.0002.113D] # HANGUL CHOSEONG CHITUEUMSSANGSIOS +113E ; [.3179.0020.0002.113E] # HANGUL CHOSEONG CEONGCHIEUMSIOS +113F ; [.317A.0020.0002.113F] # HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS +1140 ; [.317B.0020.0002.1140] # HANGUL CHOSEONG PANSIOS +317F ; [.317B.0020.0004.317F] # HANGUL LETTER PANSIOS +1141 ; [.317C.0020.0002.1141] # HANGUL CHOSEONG IEUNG-KIYEOK +1142 ; [.317D.0020.0002.1142] # HANGUL CHOSEONG IEUNG-TIKEUT +1143 ; [.317E.0020.0002.1143] # HANGUL CHOSEONG IEUNG-MIEUM +1144 ; [.317F.0020.0002.1144] # HANGUL CHOSEONG IEUNG-PIEUP +1145 ; [.3180.0020.0002.1145] # HANGUL CHOSEONG IEUNG-SIOS +1146 ; [.3181.0020.0002.1146] # HANGUL CHOSEONG IEUNG-PANSIOS +1147 ; [.3182.0020.0002.1147] # HANGUL CHOSEONG SSANGIEUNG +3180 ; [.3182.0020.0004.3180] # HANGUL LETTER SSANGIEUNG +1148 ; [.3183.0020.0002.1148] # HANGUL CHOSEONG IEUNG-CIEUC +1149 ; [.3184.0020.0002.1149] # HANGUL CHOSEONG IEUNG-CHIEUCH +114A ; [.3185.0020.0002.114A] # HANGUL CHOSEONG IEUNG-THIEUTH +114B ; [.3186.0020.0002.114B] # HANGUL CHOSEONG IEUNG-PHIEUPH +114C ; [.3187.0020.0002.114C] # HANGUL CHOSEONG YESIEUNG +3181 ; [.3187.0020.0004.3181] # HANGUL LETTER YESIEUNG +114D ; [.3188.0020.0002.114D] # HANGUL CHOSEONG CIEUC-IEUNG +114E ; [.3189.0020.0002.114E] # HANGUL CHOSEONG CHITUEUMCIEUC +114F ; [.318A.0020.0002.114F] # HANGUL CHOSEONG CHITUEUMSSANGCIEUC +1150 ; [.318B.0020.0002.1150] # HANGUL CHOSEONG CEONGCHIEUMCIEUC +1151 ; [.318C.0020.0002.1151] # HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC +1152 ; [.318D.0020.0002.1152] # HANGUL CHOSEONG CHIEUCH-KHIEUKH +1153 ; [.318E.0020.0002.1153] # HANGUL CHOSEONG CHIEUCH-HIEUH +1154 ; [.318F.0020.0002.1154] # HANGUL CHOSEONG CHITUEUMCHIEUCH +1155 ; [.3190.0020.0002.1155] # HANGUL CHOSEONG CEONGCHIEUMCHIEUCH +1156 ; [.3191.0020.0002.1156] # HANGUL CHOSEONG PHIEUPH-PIEUP +1157 ; [.3192.0020.0002.1157] # HANGUL CHOSEONG KAPYEOUNPHIEUPH +3184 ; [.3192.0020.0004.3184] # HANGUL LETTER KAPYEOUNPHIEUPH +1158 ; [.3193.0020.0002.1158] # HANGUL CHOSEONG SSANGHIEUH +3185 ; [.3193.0020.0004.3185] # HANGUL LETTER SSANGHIEUH +1159 ; [.3194.0020.0002.1159] # HANGUL CHOSEONG YEORINHIEUH +3186 ; [.3194.0020.0004.3186] # HANGUL LETTER YEORINHIEUH +115A ; [.3195.0020.0002.115A] # HANGUL CHOSEONG KIYEOK-TIKEUT +115B ; [.3196.0020.0002.115B] # HANGUL CHOSEONG NIEUN-SIOS +115C ; [.3197.0020.0002.115C] # HANGUL CHOSEONG NIEUN-CIEUC +115D ; [.3198.0020.0002.115D] # HANGUL CHOSEONG NIEUN-HIEUH +115E ; [.3199.0020.0002.115E] # HANGUL CHOSEONG TIKEUT-RIEUL +A960 ; [.319A.0020.0002.A960] # HANGUL CHOSEONG TIKEUT-MIEUM +A961 ; [.319B.0020.0002.A961] # HANGUL CHOSEONG TIKEUT-PIEUP +A962 ; [.319C.0020.0002.A962] # HANGUL CHOSEONG TIKEUT-SIOS +A963 ; [.319D.0020.0002.A963] # HANGUL CHOSEONG TIKEUT-CIEUC +A964 ; [.319E.0020.0002.A964] # HANGUL CHOSEONG RIEUL-KIYEOK +A965 ; [.319F.0020.0002.A965] # HANGUL CHOSEONG RIEUL-SSANGKIYEOK +A966 ; [.31A0.0020.0002.A966] # HANGUL CHOSEONG RIEUL-TIKEUT +A967 ; [.31A1.0020.0002.A967] # HANGUL CHOSEONG RIEUL-SSANGTIKEUT +A968 ; [.31A2.0020.0002.A968] # HANGUL CHOSEONG RIEUL-MIEUM +A969 ; [.31A3.0020.0002.A969] # HANGUL CHOSEONG RIEUL-PIEUP +A96A ; [.31A4.0020.0002.A96A] # HANGUL CHOSEONG RIEUL-SSANGPIEUP +A96B ; [.31A5.0020.0002.A96B] # HANGUL CHOSEONG RIEUL-KAPYEOUNPIEUP +A96C ; [.31A6.0020.0002.A96C] # HANGUL CHOSEONG RIEUL-SIOS +A96D ; [.31A7.0020.0002.A96D] # HANGUL CHOSEONG RIEUL-CIEUC +A96E ; [.31A8.0020.0002.A96E] # HANGUL CHOSEONG RIEUL-KHIEUKH +A96F ; [.31A9.0020.0002.A96F] # HANGUL CHOSEONG MIEUM-KIYEOK +A970 ; [.31AA.0020.0002.A970] # HANGUL CHOSEONG MIEUM-TIKEUT +A971 ; [.31AB.0020.0002.A971] # HANGUL CHOSEONG MIEUM-SIOS +A972 ; [.31AC.0020.0002.A972] # HANGUL CHOSEONG PIEUP-SIOS-THIEUTH +A973 ; [.31AD.0020.0002.A973] # HANGUL CHOSEONG PIEUP-KHIEUKH +A974 ; [.31AE.0020.0002.A974] # HANGUL CHOSEONG PIEUP-HIEUH +A975 ; [.31AF.0020.0002.A975] # HANGUL CHOSEONG SSANGSIOS-PIEUP +A976 ; [.31B0.0020.0002.A976] # HANGUL CHOSEONG IEUNG-RIEUL +A977 ; [.31B1.0020.0002.A977] # HANGUL CHOSEONG IEUNG-HIEUH +A978 ; [.31B2.0020.0002.A978] # HANGUL CHOSEONG SSANGCIEUC-HIEUH +A979 ; [.31B3.0020.0002.A979] # HANGUL CHOSEONG SSANGTHIEUTH +A97A ; [.31B4.0020.0002.A97A] # HANGUL CHOSEONG PHIEUPH-HIEUH +A97B ; [.31B5.0020.0002.A97B] # HANGUL CHOSEONG HIEUH-SIOS +A97C ; [.31B6.0020.0002.A97C] # HANGUL CHOSEONG SSANGYEORINHIEUH +115F ; [.31B7.0020.0002.115F] # HANGUL CHOSEONG FILLER +1160 ; [.31B8.0020.0002.1160] # HANGUL JUNGSEONG FILLER +3164 ; [.31B8.0020.0004.3164] # HANGUL FILLER +FFA0 ; [.31B8.0020.0012.FFA0] # HALFWIDTH HANGUL FILLER +1161 ; [.31B9.0020.0002.1161] # HANGUL JUNGSEONG A +314F ; [.31B9.0020.0004.314F] # HANGUL LETTER A +FFC2 ; [.31B9.0020.0012.FFC2] # HALFWIDTH HANGUL LETTER A +1162 ; [.31BA.0020.0002.1162] # HANGUL JUNGSEONG AE +3150 ; [.31BA.0020.0004.3150] # HANGUL LETTER AE +FFC3 ; [.31BA.0020.0012.FFC3] # HALFWIDTH HANGUL LETTER AE +1163 ; [.31BB.0020.0002.1163] # HANGUL JUNGSEONG YA +3151 ; [.31BB.0020.0004.3151] # HANGUL LETTER YA +FFC4 ; [.31BB.0020.0012.FFC4] # HALFWIDTH HANGUL LETTER YA +1164 ; [.31BC.0020.0002.1164] # HANGUL JUNGSEONG YAE +3152 ; [.31BC.0020.0004.3152] # HANGUL LETTER YAE +FFC5 ; [.31BC.0020.0012.FFC5] # HALFWIDTH HANGUL LETTER YAE +1165 ; [.31BD.0020.0002.1165] # HANGUL JUNGSEONG EO +3153 ; [.31BD.0020.0004.3153] # HANGUL LETTER EO +FFC6 ; [.31BD.0020.0012.FFC6] # HALFWIDTH HANGUL LETTER EO +1166 ; [.31BE.0020.0002.1166] # HANGUL JUNGSEONG E +3154 ; [.31BE.0020.0004.3154] # HANGUL LETTER E +FFC7 ; [.31BE.0020.0012.FFC7] # HALFWIDTH HANGUL LETTER E +1167 ; [.31BF.0020.0002.1167] # HANGUL JUNGSEONG YEO +3155 ; [.31BF.0020.0004.3155] # HANGUL LETTER YEO +FFCA ; [.31BF.0020.0012.FFCA] # HALFWIDTH HANGUL LETTER YEO +1168 ; [.31C0.0020.0002.1168] # HANGUL JUNGSEONG YE +3156 ; [.31C0.0020.0004.3156] # HANGUL LETTER YE +FFCB ; [.31C0.0020.0012.FFCB] # HALFWIDTH HANGUL LETTER YE +1169 ; [.31C1.0020.0002.1169] # HANGUL JUNGSEONG O +3157 ; [.31C1.0020.0004.3157] # HANGUL LETTER O +FFCC ; [.31C1.0020.0012.FFCC] # HALFWIDTH HANGUL LETTER O +116A ; [.31C2.0020.0002.116A] # HANGUL JUNGSEONG WA +3158 ; [.31C2.0020.0004.3158] # HANGUL LETTER WA +FFCD ; [.31C2.0020.0012.FFCD] # HALFWIDTH HANGUL LETTER WA +116B ; [.31C3.0020.0002.116B] # HANGUL JUNGSEONG WAE +3159 ; [.31C3.0020.0004.3159] # HANGUL LETTER WAE +FFCE ; [.31C3.0020.0012.FFCE] # HALFWIDTH HANGUL LETTER WAE +116C ; [.31C4.0020.0002.116C] # HANGUL JUNGSEONG OE +315A ; [.31C4.0020.0004.315A] # HANGUL LETTER OE +FFCF ; [.31C4.0020.0012.FFCF] # HALFWIDTH HANGUL LETTER OE +116D ; [.31C5.0020.0002.116D] # HANGUL JUNGSEONG YO +315B ; [.31C5.0020.0004.315B] # HANGUL LETTER YO +FFD2 ; [.31C5.0020.0012.FFD2] # HALFWIDTH HANGUL LETTER YO +116E ; [.31C6.0020.0002.116E] # HANGUL JUNGSEONG U +315C ; [.31C6.0020.0004.315C] # HANGUL LETTER U +FFD3 ; [.31C6.0020.0012.FFD3] # HALFWIDTH HANGUL LETTER U +116F ; [.31C7.0020.0002.116F] # HANGUL JUNGSEONG WEO +315D ; [.31C7.0020.0004.315D] # HANGUL LETTER WEO +FFD4 ; [.31C7.0020.0012.FFD4] # HALFWIDTH HANGUL LETTER WEO +1170 ; [.31C8.0020.0002.1170] # HANGUL JUNGSEONG WE +315E ; [.31C8.0020.0004.315E] # HANGUL LETTER WE +FFD5 ; [.31C8.0020.0012.FFD5] # HALFWIDTH HANGUL LETTER WE +1171 ; [.31C9.0020.0002.1171] # HANGUL JUNGSEONG WI +315F ; [.31C9.0020.0004.315F] # HANGUL LETTER WI +FFD6 ; [.31C9.0020.0012.FFD6] # HALFWIDTH HANGUL LETTER WI +1172 ; [.31CA.0020.0002.1172] # HANGUL JUNGSEONG YU +3160 ; [.31CA.0020.0004.3160] # HANGUL LETTER YU +FFD7 ; [.31CA.0020.0012.FFD7] # HALFWIDTH HANGUL LETTER YU +1173 ; [.31CB.0020.0002.1173] # HANGUL JUNGSEONG EU +3161 ; [.31CB.0020.0004.3161] # HANGUL LETTER EU +FFDA ; [.31CB.0020.0012.FFDA] # HALFWIDTH HANGUL LETTER EU +1174 ; [.31CC.0020.0002.1174] # HANGUL JUNGSEONG YI +3162 ; [.31CC.0020.0004.3162] # HANGUL LETTER YI +FFDB ; [.31CC.0020.0012.FFDB] # HALFWIDTH HANGUL LETTER YI +1175 ; [.31CD.0020.0002.1175] # HANGUL JUNGSEONG I +3163 ; [.31CD.0020.0004.3163] # HANGUL LETTER I +FFDC ; [.31CD.0020.0012.FFDC] # HALFWIDTH HANGUL LETTER I +1176 ; [.31CE.0020.0002.1176] # HANGUL JUNGSEONG A-O +1177 ; [.31CF.0020.0002.1177] # HANGUL JUNGSEONG A-U +1178 ; [.31D0.0020.0002.1178] # HANGUL JUNGSEONG YA-O +1179 ; [.31D1.0020.0002.1179] # HANGUL JUNGSEONG YA-YO +117A ; [.31D2.0020.0002.117A] # HANGUL JUNGSEONG EO-O +117B ; [.31D3.0020.0002.117B] # HANGUL JUNGSEONG EO-U +117C ; [.31D4.0020.0002.117C] # HANGUL JUNGSEONG EO-EU +117D ; [.31D5.0020.0002.117D] # HANGUL JUNGSEONG YEO-O +117E ; [.31D6.0020.0002.117E] # HANGUL JUNGSEONG YEO-U +117F ; [.31D7.0020.0002.117F] # HANGUL JUNGSEONG O-EO +1180 ; [.31D8.0020.0002.1180] # HANGUL JUNGSEONG O-E +1181 ; [.31D9.0020.0002.1181] # HANGUL JUNGSEONG O-YE +1182 ; [.31DA.0020.0002.1182] # HANGUL JUNGSEONG O-O +1183 ; [.31DB.0020.0002.1183] # HANGUL JUNGSEONG O-U +1184 ; [.31DC.0020.0002.1184] # HANGUL JUNGSEONG YO-YA +3187 ; [.31DC.0020.0004.3187] # HANGUL LETTER YO-YA +1185 ; [.31DD.0020.0002.1185] # HANGUL JUNGSEONG YO-YAE +3188 ; [.31DD.0020.0004.3188] # HANGUL LETTER YO-YAE +1186 ; [.31DE.0020.0002.1186] # HANGUL JUNGSEONG YO-YEO +1187 ; [.31DF.0020.0002.1187] # HANGUL JUNGSEONG YO-O +1188 ; [.31E0.0020.0002.1188] # HANGUL JUNGSEONG YO-I +3189 ; [.31E0.0020.0004.3189] # HANGUL LETTER YO-I +1189 ; [.31E1.0020.0002.1189] # HANGUL JUNGSEONG U-A +118A ; [.31E2.0020.0002.118A] # HANGUL JUNGSEONG U-AE +118B ; [.31E3.0020.0002.118B] # HANGUL JUNGSEONG U-EO-EU +118C ; [.31E4.0020.0002.118C] # HANGUL JUNGSEONG U-YE +118D ; [.31E5.0020.0002.118D] # HANGUL JUNGSEONG U-U +118E ; [.31E6.0020.0002.118E] # HANGUL JUNGSEONG YU-A +118F ; [.31E7.0020.0002.118F] # HANGUL JUNGSEONG YU-EO +1190 ; [.31E8.0020.0002.1190] # HANGUL JUNGSEONG YU-E +1191 ; [.31E9.0020.0002.1191] # HANGUL JUNGSEONG YU-YEO +318A ; [.31E9.0020.0004.318A] # HANGUL LETTER YU-YEO +1192 ; [.31EA.0020.0002.1192] # HANGUL JUNGSEONG YU-YE +318B ; [.31EA.0020.0004.318B] # HANGUL LETTER YU-YE +1193 ; [.31EB.0020.0002.1193] # HANGUL JUNGSEONG YU-U +1194 ; [.31EC.0020.0002.1194] # HANGUL JUNGSEONG YU-I +318C ; [.31EC.0020.0004.318C] # HANGUL LETTER YU-I +1195 ; [.31ED.0020.0002.1195] # HANGUL JUNGSEONG EU-U +1196 ; [.31EE.0020.0002.1196] # HANGUL JUNGSEONG EU-EU +1197 ; [.31EF.0020.0002.1197] # HANGUL JUNGSEONG YI-U +1198 ; [.31F0.0020.0002.1198] # HANGUL JUNGSEONG I-A +1199 ; [.31F1.0020.0002.1199] # HANGUL JUNGSEONG I-YA +119A ; [.31F2.0020.0002.119A] # HANGUL JUNGSEONG I-O +119B ; [.31F3.0020.0002.119B] # HANGUL JUNGSEONG I-U +119C ; [.31F4.0020.0002.119C] # HANGUL JUNGSEONG I-EU +119D ; [.31F5.0020.0002.119D] # HANGUL JUNGSEONG I-ARAEA +119E ; [.31F6.0020.0002.119E] # HANGUL JUNGSEONG ARAEA +318D ; [.31F6.0020.0004.318D] # HANGUL LETTER ARAEA +119F ; [.31F7.0020.0002.119F] # HANGUL JUNGSEONG ARAEA-EO +11A0 ; [.31F8.0020.0002.11A0] # HANGUL JUNGSEONG ARAEA-U +11A1 ; [.31F9.0020.0002.11A1] # HANGUL JUNGSEONG ARAEA-I +318E ; [.31F9.0020.0004.318E] # HANGUL LETTER ARAEAE +11A2 ; [.31FA.0020.0002.11A2] # HANGUL JUNGSEONG SSANGARAEA +11A3 ; [.31FB.0020.0002.11A3] # HANGUL JUNGSEONG A-EU +11A4 ; [.31FC.0020.0002.11A4] # HANGUL JUNGSEONG YA-U +11A5 ; [.31FD.0020.0002.11A5] # HANGUL JUNGSEONG YEO-YA +11A6 ; [.31FE.0020.0002.11A6] # HANGUL JUNGSEONG O-YA +11A7 ; [.31FF.0020.0002.11A7] # HANGUL JUNGSEONG O-YAE +D7B0 ; [.3200.0020.0002.D7B0] # HANGUL JUNGSEONG O-YEO +D7B1 ; [.3201.0020.0002.D7B1] # HANGUL JUNGSEONG O-O-I +D7B2 ; [.3202.0020.0002.D7B2] # HANGUL JUNGSEONG YO-A +D7B3 ; [.3203.0020.0002.D7B3] # HANGUL JUNGSEONG YO-AE +D7B4 ; [.3204.0020.0002.D7B4] # HANGUL JUNGSEONG YO-EO +D7B5 ; [.3205.0020.0002.D7B5] # HANGUL JUNGSEONG U-YEO +D7B6 ; [.3206.0020.0002.D7B6] # HANGUL JUNGSEONG U-I-I +D7B7 ; [.3207.0020.0002.D7B7] # HANGUL JUNGSEONG YU-AE +D7B8 ; [.3208.0020.0002.D7B8] # HANGUL JUNGSEONG YU-O +D7B9 ; [.3209.0020.0002.D7B9] # HANGUL JUNGSEONG EU-A +D7BA ; [.320A.0020.0002.D7BA] # HANGUL JUNGSEONG EU-EO +D7BB ; [.320B.0020.0002.D7BB] # HANGUL JUNGSEONG EU-E +D7BC ; [.320C.0020.0002.D7BC] # HANGUL JUNGSEONG EU-O +D7BD ; [.320D.0020.0002.D7BD] # HANGUL JUNGSEONG I-YA-O +D7BE ; [.320E.0020.0002.D7BE] # HANGUL JUNGSEONG I-YAE +D7BF ; [.320F.0020.0002.D7BF] # HANGUL JUNGSEONG I-YEO +D7C0 ; [.3210.0020.0002.D7C0] # HANGUL JUNGSEONG I-YE +D7C1 ; [.3211.0020.0002.D7C1] # HANGUL JUNGSEONG I-O-I +D7C2 ; [.3212.0020.0002.D7C2] # HANGUL JUNGSEONG I-YO +D7C3 ; [.3213.0020.0002.D7C3] # HANGUL JUNGSEONG I-YU +D7C4 ; [.3214.0020.0002.D7C4] # HANGUL JUNGSEONG I-I +D7C5 ; [.3215.0020.0002.D7C5] # HANGUL JUNGSEONG ARAEA-A +D7C6 ; [.3216.0020.0002.D7C6] # HANGUL JUNGSEONG ARAEA-E +11A8 ; [.3217.0020.0002.11A8] # HANGUL JONGSEONG KIYEOK +11A9 ; [.3218.0020.0002.11A9] # HANGUL JONGSEONG SSANGKIYEOK +11AA ; [.3219.0020.0002.11AA] # HANGUL JONGSEONG KIYEOK-SIOS +3133 ; [.3219.0020.0004.3133] # HANGUL LETTER KIYEOK-SIOS +FFA3 ; [.3219.0020.0012.FFA3] # HALFWIDTH HANGUL LETTER KIYEOK-SIOS +11AB ; [.321A.0020.0002.11AB] # HANGUL JONGSEONG NIEUN +11AC ; [.321B.0020.0002.11AC] # HANGUL JONGSEONG NIEUN-CIEUC +3135 ; [.321B.0020.0004.3135] # HANGUL LETTER NIEUN-CIEUC +FFA5 ; [.321B.0020.0012.FFA5] # HALFWIDTH HANGUL LETTER NIEUN-CIEUC +11AD ; [.321C.0020.0002.11AD] # HANGUL JONGSEONG NIEUN-HIEUH +3136 ; [.321C.0020.0004.3136] # HANGUL LETTER NIEUN-HIEUH +FFA6 ; [.321C.0020.0012.FFA6] # HALFWIDTH HANGUL LETTER NIEUN-HIEUH +11AE ; [.321D.0020.0002.11AE] # HANGUL JONGSEONG TIKEUT +11AF ; [.321E.0020.0002.11AF] # HANGUL JONGSEONG RIEUL +11B0 ; [.321F.0020.0002.11B0] # HANGUL JONGSEONG RIEUL-KIYEOK +313A ; [.321F.0020.0004.313A] # HANGUL LETTER RIEUL-KIYEOK +FFAA ; [.321F.0020.0012.FFAA] # HALFWIDTH HANGUL LETTER RIEUL-KIYEOK +11B1 ; [.3220.0020.0002.11B1] # HANGUL JONGSEONG RIEUL-MIEUM +313B ; [.3220.0020.0004.313B] # HANGUL LETTER RIEUL-MIEUM +FFAB ; [.3220.0020.0012.FFAB] # HALFWIDTH HANGUL LETTER RIEUL-MIEUM +11B2 ; [.3221.0020.0002.11B2] # HANGUL JONGSEONG RIEUL-PIEUP +313C ; [.3221.0020.0004.313C] # HANGUL LETTER RIEUL-PIEUP +FFAC ; [.3221.0020.0012.FFAC] # HALFWIDTH HANGUL LETTER RIEUL-PIEUP +11B3 ; [.3222.0020.0002.11B3] # HANGUL JONGSEONG RIEUL-SIOS +313D ; [.3222.0020.0004.313D] # HANGUL LETTER RIEUL-SIOS +FFAD ; [.3222.0020.0012.FFAD] # HALFWIDTH HANGUL LETTER RIEUL-SIOS +11B4 ; [.3223.0020.0002.11B4] # HANGUL JONGSEONG RIEUL-THIEUTH +313E ; [.3223.0020.0004.313E] # HANGUL LETTER RIEUL-THIEUTH +FFAE ; [.3223.0020.0012.FFAE] # HALFWIDTH HANGUL LETTER RIEUL-THIEUTH +11B5 ; [.3224.0020.0002.11B5] # HANGUL JONGSEONG RIEUL-PHIEUPH +313F ; [.3224.0020.0004.313F] # HANGUL LETTER RIEUL-PHIEUPH +FFAF ; [.3224.0020.0012.FFAF] # HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH +11B6 ; [.3225.0020.0002.11B6] # HANGUL JONGSEONG RIEUL-HIEUH +11B7 ; [.3226.0020.0002.11B7] # HANGUL JONGSEONG MIEUM +11B8 ; [.3227.0020.0002.11B8] # HANGUL JONGSEONG PIEUP +11B9 ; [.3228.0020.0002.11B9] # HANGUL JONGSEONG PIEUP-SIOS +11BA ; [.3229.0020.0002.11BA] # HANGUL JONGSEONG SIOS +11BB ; [.322A.0020.0002.11BB] # HANGUL JONGSEONG SSANGSIOS +11BC ; [.322B.0020.0002.11BC] # HANGUL JONGSEONG IEUNG +11BD ; [.322C.0020.0002.11BD] # HANGUL JONGSEONG CIEUC +11BE ; [.322D.0020.0002.11BE] # HANGUL JONGSEONG CHIEUCH +11BF ; [.322E.0020.0002.11BF] # HANGUL JONGSEONG KHIEUKH +11C0 ; [.322F.0020.0002.11C0] # HANGUL JONGSEONG THIEUTH +11C1 ; [.3230.0020.0002.11C1] # HANGUL JONGSEONG PHIEUPH +11C2 ; [.3231.0020.0002.11C2] # HANGUL JONGSEONG HIEUH +11C3 ; [.3232.0020.0002.11C3] # HANGUL JONGSEONG KIYEOK-RIEUL +11C4 ; [.3233.0020.0002.11C4] # HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK +11C5 ; [.3234.0020.0002.11C5] # HANGUL JONGSEONG NIEUN-KIYEOK +11C6 ; [.3235.0020.0002.11C6] # HANGUL JONGSEONG NIEUN-TIKEUT +11C7 ; [.3236.0020.0002.11C7] # HANGUL JONGSEONG NIEUN-SIOS +3167 ; [.3236.0020.0004.3167] # HANGUL LETTER NIEUN-SIOS +11C8 ; [.3237.0020.0002.11C8] # HANGUL JONGSEONG NIEUN-PANSIOS +3168 ; [.3237.0020.0004.3168] # HANGUL LETTER NIEUN-PANSIOS +11C9 ; [.3238.0020.0002.11C9] # HANGUL JONGSEONG NIEUN-THIEUTH +11CA ; [.3239.0020.0002.11CA] # HANGUL JONGSEONG TIKEUT-KIYEOK +11CB ; [.323A.0020.0002.11CB] # HANGUL JONGSEONG TIKEUT-RIEUL +11CC ; [.323B.0020.0002.11CC] # HANGUL JONGSEONG RIEUL-KIYEOK-SIOS +3169 ; [.323B.0020.0004.3169] # HANGUL LETTER RIEUL-KIYEOK-SIOS +11CD ; [.323C.0020.0002.11CD] # HANGUL JONGSEONG RIEUL-NIEUN +11CE ; [.323D.0020.0002.11CE] # HANGUL JONGSEONG RIEUL-TIKEUT +316A ; [.323D.0020.0004.316A] # HANGUL LETTER RIEUL-TIKEUT +11CF ; [.323E.0020.0002.11CF] # HANGUL JONGSEONG RIEUL-TIKEUT-HIEUH +11D0 ; [.323F.0020.0002.11D0] # HANGUL JONGSEONG SSANGRIEUL +11D1 ; [.3240.0020.0002.11D1] # HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK +11D2 ; [.3241.0020.0002.11D2] # HANGUL JONGSEONG RIEUL-MIEUM-SIOS +11D3 ; [.3242.0020.0002.11D3] # HANGUL JONGSEONG RIEUL-PIEUP-SIOS +316B ; [.3242.0020.0004.316B] # HANGUL LETTER RIEUL-PIEUP-SIOS +11D4 ; [.3243.0020.0002.11D4] # HANGUL JONGSEONG RIEUL-PIEUP-HIEUH +11D5 ; [.3244.0020.0002.11D5] # HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP +11D6 ; [.3245.0020.0002.11D6] # HANGUL JONGSEONG RIEUL-SSANGSIOS +11D7 ; [.3246.0020.0002.11D7] # HANGUL JONGSEONG RIEUL-PANSIOS +316C ; [.3246.0020.0004.316C] # HANGUL LETTER RIEUL-PANSIOS +11D8 ; [.3247.0020.0002.11D8] # HANGUL JONGSEONG RIEUL-KHIEUKH +11D9 ; [.3248.0020.0002.11D9] # HANGUL JONGSEONG RIEUL-YEORINHIEUH +316D ; [.3248.0020.0004.316D] # HANGUL LETTER RIEUL-YEORINHIEUH +11DA ; [.3249.0020.0002.11DA] # HANGUL JONGSEONG MIEUM-KIYEOK +11DB ; [.324A.0020.0002.11DB] # HANGUL JONGSEONG MIEUM-RIEUL +11DC ; [.324B.0020.0002.11DC] # HANGUL JONGSEONG MIEUM-PIEUP +11DD ; [.324C.0020.0002.11DD] # HANGUL JONGSEONG MIEUM-SIOS +316F ; [.324C.0020.0004.316F] # HANGUL LETTER MIEUM-SIOS +11DE ; [.324D.0020.0002.11DE] # HANGUL JONGSEONG MIEUM-SSANGSIOS +11DF ; [.324E.0020.0002.11DF] # HANGUL JONGSEONG MIEUM-PANSIOS +3170 ; [.324E.0020.0004.3170] # HANGUL LETTER MIEUM-PANSIOS +11E0 ; [.324F.0020.0002.11E0] # HANGUL JONGSEONG MIEUM-CHIEUCH +11E1 ; [.3250.0020.0002.11E1] # HANGUL JONGSEONG MIEUM-HIEUH +11E2 ; [.3251.0020.0002.11E2] # HANGUL JONGSEONG KAPYEOUNMIEUM +11E3 ; [.3252.0020.0002.11E3] # HANGUL JONGSEONG PIEUP-RIEUL +11E4 ; [.3253.0020.0002.11E4] # HANGUL JONGSEONG PIEUP-PHIEUPH +11E5 ; [.3254.0020.0002.11E5] # HANGUL JONGSEONG PIEUP-HIEUH +11E6 ; [.3255.0020.0002.11E6] # HANGUL JONGSEONG KAPYEOUNPIEUP +11E7 ; [.3256.0020.0002.11E7] # HANGUL JONGSEONG SIOS-KIYEOK +11E8 ; [.3257.0020.0002.11E8] # HANGUL JONGSEONG SIOS-TIKEUT +11E9 ; [.3258.0020.0002.11E9] # HANGUL JONGSEONG SIOS-RIEUL +11EA ; [.3259.0020.0002.11EA] # HANGUL JONGSEONG SIOS-PIEUP +11EB ; [.325A.0020.0002.11EB] # HANGUL JONGSEONG PANSIOS +11EC ; [.325B.0020.0002.11EC] # HANGUL JONGSEONG IEUNG-KIYEOK +11ED ; [.325C.0020.0002.11ED] # HANGUL JONGSEONG IEUNG-SSANGKIYEOK +11EE ; [.325D.0020.0002.11EE] # HANGUL JONGSEONG SSANGIEUNG +11EF ; [.325E.0020.0002.11EF] # HANGUL JONGSEONG IEUNG-KHIEUKH +11F0 ; [.325F.0020.0002.11F0] # HANGUL JONGSEONG YESIEUNG +11F1 ; [.3260.0020.0002.11F1] # HANGUL JONGSEONG YESIEUNG-SIOS +3182 ; [.3260.0020.0004.3182] # HANGUL LETTER YESIEUNG-SIOS +11F2 ; [.3261.0020.0002.11F2] # HANGUL JONGSEONG YESIEUNG-PANSIOS +3183 ; [.3261.0020.0004.3183] # HANGUL LETTER YESIEUNG-PANSIOS +11F3 ; [.3262.0020.0002.11F3] # HANGUL JONGSEONG PHIEUPH-PIEUP +11F4 ; [.3263.0020.0002.11F4] # HANGUL JONGSEONG KAPYEOUNPHIEUPH +11F5 ; [.3264.0020.0002.11F5] # HANGUL JONGSEONG HIEUH-NIEUN +11F6 ; [.3265.0020.0002.11F6] # HANGUL JONGSEONG HIEUH-RIEUL +11F7 ; [.3266.0020.0002.11F7] # HANGUL JONGSEONG HIEUH-MIEUM +11F8 ; [.3267.0020.0002.11F8] # HANGUL JONGSEONG HIEUH-PIEUP +11F9 ; [.3268.0020.0002.11F9] # HANGUL JONGSEONG YEORINHIEUH +11FA ; [.3269.0020.0002.11FA] # HANGUL JONGSEONG KIYEOK-NIEUN +11FB ; [.326A.0020.0002.11FB] # HANGUL JONGSEONG KIYEOK-PIEUP +11FC ; [.326B.0020.0002.11FC] # HANGUL JONGSEONG KIYEOK-CHIEUCH +11FD ; [.326C.0020.0002.11FD] # HANGUL JONGSEONG KIYEOK-KHIEUKH +11FE ; [.326D.0020.0002.11FE] # HANGUL JONGSEONG KIYEOK-HIEUH +11FF ; [.326E.0020.0002.11FF] # HANGUL JONGSEONG SSANGNIEUN +D7CB ; [.326F.0020.0002.D7CB] # HANGUL JONGSEONG NIEUN-RIEUL +D7CC ; [.3270.0020.0002.D7CC] # HANGUL JONGSEONG NIEUN-CHIEUCH +D7CD ; [.3271.0020.0002.D7CD] # HANGUL JONGSEONG SSANGTIKEUT +D7CE ; [.3272.0020.0002.D7CE] # HANGUL JONGSEONG SSANGTIKEUT-PIEUP +D7CF ; [.3273.0020.0002.D7CF] # HANGUL JONGSEONG TIKEUT-PIEUP +D7D0 ; [.3274.0020.0002.D7D0] # HANGUL JONGSEONG TIKEUT-SIOS +D7D1 ; [.3275.0020.0002.D7D1] # HANGUL JONGSEONG TIKEUT-SIOS-KIYEOK +D7D2 ; [.3276.0020.0002.D7D2] # HANGUL JONGSEONG TIKEUT-CIEUC +D7D3 ; [.3277.0020.0002.D7D3] # HANGUL JONGSEONG TIKEUT-CHIEUCH +D7D4 ; [.3278.0020.0002.D7D4] # HANGUL JONGSEONG TIKEUT-THIEUTH +D7D5 ; [.3279.0020.0002.D7D5] # HANGUL JONGSEONG RIEUL-SSANGKIYEOK +D7D6 ; [.327A.0020.0002.D7D6] # HANGUL JONGSEONG RIEUL-KIYEOK-HIEUH +D7D7 ; [.327B.0020.0002.D7D7] # HANGUL JONGSEONG SSANGRIEUL-KHIEUKH +D7D8 ; [.327C.0020.0002.D7D8] # HANGUL JONGSEONG RIEUL-MIEUM-HIEUH +D7D9 ; [.327D.0020.0002.D7D9] # HANGUL JONGSEONG RIEUL-PIEUP-TIKEUT +D7DA ; [.327E.0020.0002.D7DA] # HANGUL JONGSEONG RIEUL-PIEUP-PHIEUPH +D7DB ; [.327F.0020.0002.D7DB] # HANGUL JONGSEONG RIEUL-YESIEUNG +D7DC ; [.3280.0020.0002.D7DC] # HANGUL JONGSEONG RIEUL-YEORINHIEUH-HIEUH +D7DD ; [.3281.0020.0002.D7DD] # HANGUL JONGSEONG KAPYEOUNRIEUL +D7DE ; [.3282.0020.0002.D7DE] # HANGUL JONGSEONG MIEUM-NIEUN +D7DF ; [.3283.0020.0002.D7DF] # HANGUL JONGSEONG MIEUM-SSANGNIEUN +D7E0 ; [.3284.0020.0002.D7E0] # HANGUL JONGSEONG SSANGMIEUM +D7E1 ; [.3285.0020.0002.D7E1] # HANGUL JONGSEONG MIEUM-PIEUP-SIOS +D7E2 ; [.3286.0020.0002.D7E2] # HANGUL JONGSEONG MIEUM-CIEUC +D7E3 ; [.3287.0020.0002.D7E3] # HANGUL JONGSEONG PIEUP-TIKEUT +D7E4 ; [.3288.0020.0002.D7E4] # HANGUL JONGSEONG PIEUP-RIEUL-PHIEUPH +D7E5 ; [.3289.0020.0002.D7E5] # HANGUL JONGSEONG PIEUP-MIEUM +D7E6 ; [.328A.0020.0002.D7E6] # HANGUL JONGSEONG SSANGPIEUP +D7E7 ; [.328B.0020.0002.D7E7] # HANGUL JONGSEONG PIEUP-SIOS-TIKEUT +D7E8 ; [.328C.0020.0002.D7E8] # HANGUL JONGSEONG PIEUP-CIEUC +D7E9 ; [.328D.0020.0002.D7E9] # HANGUL JONGSEONG PIEUP-CHIEUCH +D7EA ; [.328E.0020.0002.D7EA] # HANGUL JONGSEONG SIOS-MIEUM +D7EB ; [.328F.0020.0002.D7EB] # HANGUL JONGSEONG SIOS-KAPYEOUNPIEUP +D7EC ; [.3290.0020.0002.D7EC] # HANGUL JONGSEONG SSANGSIOS-KIYEOK +D7ED ; [.3291.0020.0002.D7ED] # HANGUL JONGSEONG SSANGSIOS-TIKEUT +D7EE ; [.3292.0020.0002.D7EE] # HANGUL JONGSEONG SIOS-PANSIOS +D7EF ; [.3293.0020.0002.D7EF] # HANGUL JONGSEONG SIOS-CIEUC +D7F0 ; [.3294.0020.0002.D7F0] # HANGUL JONGSEONG SIOS-CHIEUCH +D7F1 ; [.3295.0020.0002.D7F1] # HANGUL JONGSEONG SIOS-THIEUTH +D7F2 ; [.3296.0020.0002.D7F2] # HANGUL JONGSEONG SIOS-HIEUH +D7F3 ; [.3297.0020.0002.D7F3] # HANGUL JONGSEONG PANSIOS-PIEUP +D7F4 ; [.3298.0020.0002.D7F4] # HANGUL JONGSEONG PANSIOS-KAPYEOUNPIEUP +D7F5 ; [.3299.0020.0002.D7F5] # HANGUL JONGSEONG YESIEUNG-MIEUM +D7F6 ; [.329A.0020.0002.D7F6] # HANGUL JONGSEONG YESIEUNG-HIEUH +D7F7 ; [.329B.0020.0002.D7F7] # HANGUL JONGSEONG CIEUC-PIEUP +D7F8 ; [.329C.0020.0002.D7F8] # HANGUL JONGSEONG CIEUC-SSANGPIEUP +D7F9 ; [.329D.0020.0002.D7F9] # HANGUL JONGSEONG SSANGCIEUC +D7FA ; [.329E.0020.0002.D7FA] # HANGUL JONGSEONG PHIEUPH-SIOS +D7FB ; [.329F.0020.0002.D7FB] # HANGUL JONGSEONG PHIEUPH-THIEUTH +3041 ; [.32A0.0020.000D.3041] # HIRAGANA LETTER SMALL A +3042 ; [.32A0.0020.000E.3042] # HIRAGANA LETTER A +30A1 ; [.32A0.0020.000F.30A1] # KATAKANA LETTER SMALL A +FF67 ; [.32A0.0020.0010.FF67] # HALFWIDTH KATAKANA LETTER SMALL A +30A2 ; [.32A0.0020.0011.30A2] # KATAKANA LETTER A +FF71 ; [.32A0.0020.0012.FF71] # HALFWIDTH KATAKANA LETTER A +32D0 ; [.32A0.0020.0013.32D0] # CIRCLED KATAKANA A +3303 ; [.32A0.0020.001C.3303][.15A0.0020.001C.3303][.32CA.0020.001F.3303] # SQUARE AARU +3300 ; [.32A0.0020.001C.3300][.32BA.0020.001C.3300][.0000.0129.001F.3300][.15A0.0020.001F.3300][.32B4.0020.001F.3300] # SQUARE APAATO +3301 ; [.32A0.0020.001C.3301][.32CA.0020.001C.3301][.32BC.0020.001F.3301][.32A0.0020.001F.3301] # SQUARE ARUHUA +3302 ; [.32A0.0020.001C.3302][.32D1.0020.001C.3302][.32BD.0020.001F.3302][.0000.0129.001F.3302][.32A0.0020.001F.3302] # SQUARE ANPEA +3043 ; [.32A1.0020.000D.3043] # HIRAGANA LETTER SMALL I +3044 ; [.32A1.0020.000E.3044] # HIRAGANA LETTER I +30A3 ; [.32A1.0020.000F.30A3] # KATAKANA LETTER SMALL I +FF68 ; [.32A1.0020.0010.FF68] # HALFWIDTH KATAKANA LETTER SMALL I +30A4 ; [.32A1.0020.0011.30A4] # KATAKANA LETTER I +FF72 ; [.32A1.0020.0012.FF72] # HALFWIDTH KATAKANA LETTER I +32D1 ; [.32A1.0020.0013.32D1] # CIRCLED KATAKANA I +3304 ; [.32A1.0020.001C.3304][.32B6.0020.001C.3304][.32D1.0020.001F.3304][.32A8.0020.001F.3304][.0000.0128.001F.3304] # SQUARE ININGU +3305 ; [.32A1.0020.001C.3305][.32D1.0020.001C.3305][.32B1.0020.001F.3305] # SQUARE INTI +3045 ; [.32A2.0020.000D.3045] # HIRAGANA LETTER SMALL U +3046 ; [.32A2.0020.000E.3046] # HIRAGANA LETTER U +30A5 ; [.32A2.0020.000F.30A5] # KATAKANA LETTER SMALL U +FF69 ; [.32A2.0020.0010.FF69] # HALFWIDTH KATAKANA LETTER SMALL U +30A6 ; [.32A2.0020.0011.30A6] # KATAKANA LETTER U +FF73 ; [.32A2.0020.0012.FF73] # HALFWIDTH KATAKANA LETTER U +32D2 ; [.32A2.0020.0013.32D2] # CIRCLED KATAKANA U +3094 ; [.32A2.0020.000E.3046][.0000.0128.0002.3099] # HIRAGANA LETTER VU +30F4 ; [.32A2.0020.0011.30A6][.0000.0128.0002.3099] # KATAKANA LETTER VU +3306 ; [.32A2.0020.001C.3306][.32A5.0020.001C.3306][.32D1.0020.001F.3306] # SQUARE UON +1B000 ; [.32A3.0020.0002.1B000] # KATAKANA LETTER ARCHAIC E +3047 ; [.32A4.0020.000D.3047] # HIRAGANA LETTER SMALL E +3048 ; [.32A4.0020.000E.3048] # HIRAGANA LETTER E +30A7 ; [.32A4.0020.000F.30A7] # KATAKANA LETTER SMALL E +FF6A ; [.32A4.0020.0010.FF6A] # HALFWIDTH KATAKANA LETTER SMALL E +30A8 ; [.32A4.0020.0011.30A8] # KATAKANA LETTER E +FF74 ; [.32A4.0020.0012.FF74] # HALFWIDTH KATAKANA LETTER E +32D3 ; [.32A4.0020.0013.32D3] # CIRCLED KATAKANA E +3308 ; [.32A4.0020.001C.3308][.15A0.0020.001C.3308][.32A6.0020.001F.3308][.15A0.0020.001F.3308] # SQUARE EEKAA +3307 ; [.32A4.0020.001C.3307][.32AD.0020.001C.3307][.32A8.0020.001F.3307][.15A0.0020.001F.3307][.32B4.0020.001F.3307][.0000.0128.001F.3307] # SQUARE ESUKUUDO +3049 ; [.32A5.0020.000D.3049] # HIRAGANA LETTER SMALL O +304A ; [.32A5.0020.000E.304A] # HIRAGANA LETTER O +30A9 ; [.32A5.0020.000F.30A9] # KATAKANA LETTER SMALL O +FF6B ; [.32A5.0020.0010.FF6B] # HALFWIDTH KATAKANA LETTER SMALL O +30AA ; [.32A5.0020.0011.30AA] # KATAKANA LETTER O +FF75 ; [.32A5.0020.0012.FF75] # HALFWIDTH KATAKANA LETTER O +32D4 ; [.32A5.0020.0013.32D4] # CIRCLED KATAKANA O +330A ; [.32A5.0020.001C.330A][.15A0.0020.001C.330A][.32C1.0020.001F.330A] # SQUARE OOMU +3309 ; [.32A5.0020.001C.3309][.32D1.0020.001C.3309][.32AD.0020.001F.3309] # SQUARE ONSU +3095 ; [.32A6.0020.000D.3095] # HIRAGANA LETTER SMALL KA +304B ; [.32A6.0020.000E.304B] # HIRAGANA LETTER KA +30F5 ; [.32A6.0020.000F.30F5] # KATAKANA LETTER SMALL KA +30AB ; [.32A6.0020.0011.30AB] # KATAKANA LETTER KA +FF76 ; [.32A6.0020.0012.FF76] # HALFWIDTH KATAKANA LETTER KA +32D5 ; [.32A6.0020.0013.32D5] # CIRCLED KATAKANA KA +304C ; [.32A6.0020.000E.304B][.0000.0128.0002.3099] # HIRAGANA LETTER GA +30AC ; [.32A6.0020.0011.30AB][.0000.0128.0002.3099] # KATAKANA LETTER GA +330B ; [.32A6.0020.001C.330B][.32A1.0020.001C.330B][.32C9.0020.001F.330B] # SQUARE KAIRI +330C ; [.32A6.0020.001C.330C][.32C8.0020.001C.330C][.32B2.0020.001F.330C][.32B4.0020.001F.330C] # SQUARE KARATTO +330D ; [.32A6.0020.001C.330D][.32CC.0020.001C.330D][.32C9.0020.001F.330D][.15A0.0020.001F.330D] # SQUARE KARORII +330E ; [.32A6.0020.001C.330E][.0000.0128.001C.330E][.32CC.0020.001F.330E][.32D1.0020.001F.330E] # SQUARE GARON +330F ; [.32A6.0020.001C.330F][.0000.0128.001C.330F][.32D1.0020.001F.330F][.32BF.0020.001F.330F] # SQUARE GANMA +304D ; [.32A7.0020.000E.304D] # HIRAGANA LETTER KI +30AD ; [.32A7.0020.0011.30AD] # KATAKANA LETTER KI +FF77 ; [.32A7.0020.0012.FF77] # HALFWIDTH KATAKANA LETTER KI +32D6 ; [.32A7.0020.0013.32D6] # CIRCLED KATAKANA KI +304E ; [.32A7.0020.000E.304D][.0000.0128.0002.3099] # HIRAGANA LETTER GI +30AE ; [.32A7.0020.0011.30AD][.0000.0128.0002.3099] # KATAKANA LETTER GI +3310 ; [.32A7.0020.001C.3310][.0000.0128.001C.3310][.32A6.0020.001F.3310][.0000.0128.001F.3310] # SQUARE GIGA +3311 ; [.32A7.0020.001C.3311][.0000.0128.001C.3311][.32B6.0020.001F.3311][.15A0.0020.001F.3311] # SQUARE GINII +3312 ; [.32A7.0020.001C.3312][.32C5.0020.001C.3312][.32C9.0020.001F.3312][.15A0.0020.001F.3312] # SQUARE KYURII +3313 ; [.32A7.0020.001C.3313][.0000.0128.001C.3313][.32CA.0020.001F.3313][.32B0.0020.001F.3313][.0000.0128.001F.3313][.15A0.0020.001F.3313] # SQUARE GIRUDAA +3314 ; [.32A7.0020.001C.3314][.32CC.0020.001C.3314] # SQUARE KIRO +3315 ; [.32A7.0020.001C.3315][.32CC.0020.001C.3315][.32A8.0020.001F.3315][.0000.0128.001F.3315][.32C8.0020.001F.3315][.32C1.0020.001F.3315] # SQUARE KIROGURAMU +3316 ; [.32A7.0020.001C.3316][.32CC.0020.001C.3316][.32C2.0020.001F.3316][.15A0.0020.001F.3316][.32B4.0020.001F.3316][.32CA.0020.001F.3316] # SQUARE KIROMEETORU +3317 ; [.32A7.0020.001C.3317][.32CC.0020.001C.3317][.32CD.0020.001F.3317][.32B2.0020.001F.3317][.32B4.0020.001F.3317] # SQUARE KIROWATTO +304F ; [.32A8.0020.000E.304F] # HIRAGANA LETTER KU +31F0 ; [.32A8.0020.000F.31F0] # KATAKANA LETTER SMALL KU +30AF ; [.32A8.0020.0011.30AF] # KATAKANA LETTER KU +FF78 ; [.32A8.0020.0012.FF78] # HALFWIDTH KATAKANA LETTER KU +32D7 ; [.32A8.0020.0013.32D7] # CIRCLED KATAKANA KU +3050 ; [.32A8.0020.000E.304F][.0000.0128.0002.3099] # HIRAGANA LETTER GU +30B0 ; [.32A8.0020.0011.30AF][.0000.0128.0002.3099] # KATAKANA LETTER GU +3318 ; [.32A8.0020.001C.3318][.0000.0128.001C.3318][.32C8.0020.001F.3318][.32C1.0020.001F.3318] # SQUARE GURAMU +3319 ; [.32A8.0020.001C.3319][.0000.0128.001C.3319][.32C8.0020.001F.3319][.32C1.0020.001F.3319][.32B4.0020.001F.3319][.32D1.0020.001F.3319] # SQUARE GURAMUTON +331A ; [.32A8.0020.001C.331A][.32CA.0020.001C.331A][.32AE.0020.001F.331A][.0000.0128.001F.331A][.32A1.0020.001F.331A][.32CC.0020.001F.331A] # SQUARE KURUZEIRO +331B ; [.32A8.0020.001C.331B][.32CC.0020.001C.331B][.15A0.0020.001F.331B][.32B8.0020.001F.331B] # SQUARE KUROONE +3096 ; [.32A9.0020.000D.3096] # HIRAGANA LETTER SMALL KE +3051 ; [.32A9.0020.000E.3051] # HIRAGANA LETTER KE +30F6 ; [.32A9.0020.000F.30F6] # KATAKANA LETTER SMALL KE +30B1 ; [.32A9.0020.0011.30B1] # KATAKANA LETTER KE +FF79 ; [.32A9.0020.0012.FF79] # HALFWIDTH KATAKANA LETTER KE +32D8 ; [.32A9.0020.0013.32D8] # CIRCLED KATAKANA KE +3052 ; [.32A9.0020.000E.3051][.0000.0128.0002.3099] # HIRAGANA LETTER GE +30B2 ; [.32A9.0020.0011.30B1][.0000.0128.0002.3099] # KATAKANA LETTER GE +331C ; [.32A9.0020.001C.331C][.15A0.0020.001C.331C][.32AD.0020.001F.331C] # SQUARE KEESU +3053 ; [.32AA.0020.000E.3053] # HIRAGANA LETTER KO +30B3 ; [.32AA.0020.0011.30B3] # KATAKANA LETTER KO +FF7A ; [.32AA.0020.0012.FF7A] # HALFWIDTH KATAKANA LETTER KO +32D9 ; [.32AA.0020.0013.32D9] # CIRCLED KATAKANA KO +3054 ; [.32AA.0020.000E.3053][.0000.0128.0002.3099] # HIRAGANA LETTER GO +30B4 ; [.32AA.0020.0011.30B3][.0000.0128.0002.3099] # KATAKANA LETTER GO +331E ; [.32AA.0020.001C.331E][.15A0.0020.001C.331E][.32BE.0020.001F.331E][.0000.0129.001F.331E] # SQUARE KOOPO +1F201 ; [.32AA.0020.001C.1F201][.32AA.0020.001C.1F201] # SQUARED KATAKANA KOKO +30FF ; [.32AA.0020.0016.30FF][.32B4.0020.0016.30FF] # KATAKANA DIGRAPH KOTO +331D ; [.32AA.0020.001C.331D][.32CA.0020.001C.331D][.32B5.0020.001F.331D] # SQUARE KORUNA +3055 ; [.32AB.0020.000E.3055] # HIRAGANA LETTER SA +30B5 ; [.32AB.0020.0011.30B5] # KATAKANA LETTER SA +FF7B ; [.32AB.0020.0012.FF7B] # HALFWIDTH KATAKANA LETTER SA +32DA ; [.32AB.0020.0013.32DA] # CIRCLED KATAKANA SA +1F202 ; [.32AB.0020.001C.1F202] # SQUARED KATAKANA SA +3056 ; [.32AB.0020.000E.3055][.0000.0128.0002.3099] # HIRAGANA LETTER ZA +30B6 ; [.32AB.0020.0011.30B5][.0000.0128.0002.3099] # KATAKANA LETTER ZA +331F ; [.32AB.0020.001C.331F][.32A1.0020.001C.331F][.32A8.0020.001F.331F][.32CA.0020.001F.331F] # SQUARE SAIKURU +3320 ; [.32AB.0020.001C.3320][.32D1.0020.001C.3320][.32B1.0020.001F.3320][.15A0.0020.001F.3320][.32C1.0020.001F.3320] # SQUARE SANTIIMU +3057 ; [.32AC.0020.000E.3057] # HIRAGANA LETTER SI +31F1 ; [.32AC.0020.000F.31F1] # KATAKANA LETTER SMALL SI +30B7 ; [.32AC.0020.0011.30B7] # KATAKANA LETTER SI +FF7C ; [.32AC.0020.0012.FF7C] # HALFWIDTH KATAKANA LETTER SI +32DB ; [.32AC.0020.0013.32DB] # CIRCLED KATAKANA SI +3058 ; [.32AC.0020.000E.3057][.0000.0128.0002.3099] # HIRAGANA LETTER ZI +30B8 ; [.32AC.0020.0011.30B7][.0000.0128.0002.3099] # KATAKANA LETTER ZI +3006 ; [.32AC.0020.0004.3006][.32C2.0020.0004.3006] # IDEOGRAPHIC CLOSING MARK +3321 ; [.32AC.0020.001C.3321][.32C9.0020.001C.3321][.32D1.0020.001F.3321][.32A8.0020.001F.3321][.0000.0128.001F.3321] # SQUARE SIRINGU +3059 ; [.32AD.0020.000E.3059] # HIRAGANA LETTER SU +31F2 ; [.32AD.0020.000F.31F2] # KATAKANA LETTER SMALL SU +30B9 ; [.32AD.0020.0011.30B9] # KATAKANA LETTER SU +FF7D ; [.32AD.0020.0012.FF7D] # HALFWIDTH KATAKANA LETTER SU +32DC ; [.32AD.0020.0013.32DC] # CIRCLED KATAKANA SU +305A ; [.32AD.0020.000E.3059][.0000.0128.0002.3099] # HIRAGANA LETTER ZU +30BA ; [.32AD.0020.0011.30B9][.0000.0128.0002.3099] # KATAKANA LETTER ZU +305B ; [.32AE.0020.000E.305B] # HIRAGANA LETTER SE +30BB ; [.32AE.0020.0011.30BB] # KATAKANA LETTER SE +FF7E ; [.32AE.0020.0012.FF7E] # HALFWIDTH KATAKANA LETTER SE +32DD ; [.32AE.0020.0013.32DD] # CIRCLED KATAKANA SE +305C ; [.32AE.0020.000E.305B][.0000.0128.0002.3099] # HIRAGANA LETTER ZE +30BC ; [.32AE.0020.0011.30BB][.0000.0128.0002.3099] # KATAKANA LETTER ZE +3322 ; [.32AE.0020.001C.3322][.32D1.0020.001C.3322][.32B1.0020.001F.3322] # SQUARE SENTI +3323 ; [.32AE.0020.001C.3323][.32D1.0020.001C.3323][.32B4.0020.001F.3323] # SQUARE SENTO +305D ; [.32AF.0020.000E.305D] # HIRAGANA LETTER SO +30BD ; [.32AF.0020.0011.30BD] # KATAKANA LETTER SO +FF7F ; [.32AF.0020.0012.FF7F] # HALFWIDTH KATAKANA LETTER SO +32DE ; [.32AF.0020.0013.32DE] # CIRCLED KATAKANA SO +305E ; [.32AF.0020.000E.305D][.0000.0128.0002.3099] # HIRAGANA LETTER ZO +30BE ; [.32AF.0020.0011.30BD][.0000.0128.0002.3099] # KATAKANA LETTER ZO +305F ; [.32B0.0020.000E.305F] # HIRAGANA LETTER TA +30BF ; [.32B0.0020.0011.30BF] # KATAKANA LETTER TA +FF80 ; [.32B0.0020.0012.FF80] # HALFWIDTH KATAKANA LETTER TA +32DF ; [.32B0.0020.0013.32DF] # CIRCLED KATAKANA TA +3060 ; [.32B0.0020.000E.305F][.0000.0128.0002.3099] # HIRAGANA LETTER DA +30C0 ; [.32B0.0020.0011.30BF][.0000.0128.0002.3099] # KATAKANA LETTER DA +3324 ; [.32B0.0020.001C.3324][.0000.0128.001C.3324][.15A0.0020.001F.3324][.32AD.0020.001F.3324] # SQUARE DAASU +3061 ; [.32B1.0020.000E.3061] # HIRAGANA LETTER TI +30C1 ; [.32B1.0020.0011.30C1] # KATAKANA LETTER TI +FF81 ; [.32B1.0020.0012.FF81] # HALFWIDTH KATAKANA LETTER TI +32E0 ; [.32B1.0020.0013.32E0] # CIRCLED KATAKANA TI +3062 ; [.32B1.0020.000E.3061][.0000.0128.0002.3099] # HIRAGANA LETTER DI +30C2 ; [.32B1.0020.0011.30C1][.0000.0128.0002.3099] # KATAKANA LETTER DI +3063 ; [.32B2.0020.000D.3063] # HIRAGANA LETTER SMALL TU +3064 ; [.32B2.0020.000E.3064] # HIRAGANA LETTER TU +30C3 ; [.32B2.0020.000F.30C3] # KATAKANA LETTER SMALL TU +FF6F ; [.32B2.0020.0010.FF6F] # HALFWIDTH KATAKANA LETTER SMALL TU +30C4 ; [.32B2.0020.0011.30C4] # KATAKANA LETTER TU +FF82 ; [.32B2.0020.0012.FF82] # HALFWIDTH KATAKANA LETTER TU +32E1 ; [.32B2.0020.0013.32E1] # CIRCLED KATAKANA TU +3065 ; [.32B2.0020.000E.3064][.0000.0128.0002.3099] # HIRAGANA LETTER DU +30C5 ; [.32B2.0020.0011.30C4][.0000.0128.0002.3099] # KATAKANA LETTER DU +3066 ; [.32B3.0020.000E.3066] # HIRAGANA LETTER TE +30C6 ; [.32B3.0020.0011.30C6] # KATAKANA LETTER TE +FF83 ; [.32B3.0020.0012.FF83] # HALFWIDTH KATAKANA LETTER TE +32E2 ; [.32B3.0020.0013.32E2] # CIRCLED KATAKANA TE +3067 ; [.32B3.0020.000E.3066][.0000.0128.0002.3099] # HIRAGANA LETTER DE +30C7 ; [.32B3.0020.0011.30C6][.0000.0128.0002.3099] # KATAKANA LETTER DE +1F213 ; [.32B3.0020.001C.1F213][.0000.0128.001C.1F213] # SQUARED KATAKANA DE +3325 ; [.32B3.0020.001C.3325][.0000.0128.001C.3325][.32AC.0020.001F.3325] # SQUARE DESI +3068 ; [.32B4.0020.000E.3068] # HIRAGANA LETTER TO +31F3 ; [.32B4.0020.000F.31F3] # KATAKANA LETTER SMALL TO +30C8 ; [.32B4.0020.0011.30C8] # KATAKANA LETTER TO +FF84 ; [.32B4.0020.0012.FF84] # HALFWIDTH KATAKANA LETTER TO +32E3 ; [.32B4.0020.0013.32E3] # CIRCLED KATAKANA TO +3069 ; [.32B4.0020.000E.3068][.0000.0128.0002.3099] # HIRAGANA LETTER DO +30C9 ; [.32B4.0020.0011.30C8][.0000.0128.0002.3099] # KATAKANA LETTER DO +3326 ; [.32B4.0020.001C.3326][.0000.0128.001C.3326][.32CA.0020.001F.3326] # SQUARE DORU +3327 ; [.32B4.0020.001C.3327][.32D1.0020.001C.3327] # SQUARE TON +306A ; [.32B5.0020.000E.306A] # HIRAGANA LETTER NA +30CA ; [.32B5.0020.0011.30CA] # KATAKANA LETTER NA +FF85 ; [.32B5.0020.0012.FF85] # HALFWIDTH KATAKANA LETTER NA +32E4 ; [.32B5.0020.0013.32E4] # CIRCLED KATAKANA NA +3328 ; [.32B5.0020.001C.3328][.32B9.0020.001C.3328] # SQUARE NANO +306B ; [.32B6.0020.000E.306B] # HIRAGANA LETTER NI +30CB ; [.32B6.0020.0011.30CB] # KATAKANA LETTER NI +FF86 ; [.32B6.0020.0012.FF86] # HALFWIDTH KATAKANA LETTER NI +32E5 ; [.32B6.0020.0013.32E5] # CIRCLED KATAKANA NI +306C ; [.32B7.0020.000E.306C] # HIRAGANA LETTER NU +31F4 ; [.32B7.0020.000F.31F4] # KATAKANA LETTER SMALL NU +30CC ; [.32B7.0020.0011.30CC] # KATAKANA LETTER NU +FF87 ; [.32B7.0020.0012.FF87] # HALFWIDTH KATAKANA LETTER NU +32E6 ; [.32B7.0020.0013.32E6] # CIRCLED KATAKANA NU +306D ; [.32B8.0020.000E.306D] # HIRAGANA LETTER NE +30CD ; [.32B8.0020.0011.30CD] # KATAKANA LETTER NE +FF88 ; [.32B8.0020.0012.FF88] # HALFWIDTH KATAKANA LETTER NE +32E7 ; [.32B8.0020.0013.32E7] # CIRCLED KATAKANA NE +306E ; [.32B9.0020.000E.306E] # HIRAGANA LETTER NO +30CE ; [.32B9.0020.0011.30CE] # KATAKANA LETTER NO +FF89 ; [.32B9.0020.0012.FF89] # HALFWIDTH KATAKANA LETTER NO +32E8 ; [.32B9.0020.0013.32E8] # CIRCLED KATAKANA NO +3329 ; [.32B9.0020.001C.3329][.32B2.0020.001C.3329][.32B4.0020.001F.3329] # SQUARE NOTTO +306F ; [.32BA.0020.000E.306F] # HIRAGANA LETTER HA +31F5 ; [.32BA.0020.000F.31F5] # KATAKANA LETTER SMALL HA +30CF ; [.32BA.0020.0011.30CF] # KATAKANA LETTER HA +FF8A ; [.32BA.0020.0012.FF8A] # HALFWIDTH KATAKANA LETTER HA +32E9 ; [.32BA.0020.0013.32E9] # CIRCLED KATAKANA HA +3070 ; [.32BA.0020.000E.306F][.0000.0128.0002.3099] # HIRAGANA LETTER BA +30D0 ; [.32BA.0020.0011.30CF][.0000.0128.0002.3099] # KATAKANA LETTER BA +3071 ; [.32BA.0020.000E.306F][.0000.0129.0002.309A] # HIRAGANA LETTER PA +30D1 ; [.32BA.0020.0011.30CF][.0000.0129.0002.309A] # KATAKANA LETTER PA +332B ; [.32BA.0020.001C.332B][.0000.0129.001C.332B][.15A0.0020.001F.332B][.32AE.0020.001F.332B][.32D1.0020.001F.332B][.32B4.0020.001F.332B] # SQUARE PAASENTO +332C ; [.32BA.0020.001C.332C][.0000.0129.001C.332C][.15A0.0020.001F.332C][.32B2.0020.001F.332C] # SQUARE PAATU +332D ; [.32BA.0020.001C.332D][.0000.0128.001C.332D][.15A0.0020.001F.332D][.32CB.0020.001F.332D][.32CA.0020.001F.332D] # SQUARE BAARERU +332A ; [.32BA.0020.001C.332A][.32A1.0020.001C.332A][.32B2.0020.001F.332A] # SQUARE HAITU +3072 ; [.32BB.0020.000E.3072] # HIRAGANA LETTER HI +31F6 ; [.32BB.0020.000F.31F6] # KATAKANA LETTER SMALL HI +30D2 ; [.32BB.0020.0011.30D2] # KATAKANA LETTER HI +FF8B ; [.32BB.0020.0012.FF8B] # HALFWIDTH KATAKANA LETTER HI +32EA ; [.32BB.0020.0013.32EA] # CIRCLED KATAKANA HI +3073 ; [.32BB.0020.000E.3072][.0000.0128.0002.3099] # HIRAGANA LETTER BI +30D3 ; [.32BB.0020.0011.30D2][.0000.0128.0002.3099] # KATAKANA LETTER BI +3074 ; [.32BB.0020.000E.3072][.0000.0129.0002.309A] # HIRAGANA LETTER PI +30D4 ; [.32BB.0020.0011.30D2][.0000.0129.0002.309A] # KATAKANA LETTER PI +332E ; [.32BB.0020.001C.332E][.0000.0129.001C.332E][.32A0.0020.001F.332E][.32AD.0020.001F.332E][.32B4.0020.001F.332E][.32CA.0020.001F.332E] # SQUARE PIASUTORU +332F ; [.32BB.0020.001C.332F][.0000.0129.001C.332F][.32A8.0020.001F.332F][.32CA.0020.001F.332F] # SQUARE PIKURU +3330 ; [.32BB.0020.001C.3330][.0000.0129.001C.3330][.32AA.0020.001F.3330] # SQUARE PIKO +3331 ; [.32BB.0020.001C.3331][.0000.0128.001C.3331][.32CA.0020.001F.3331] # SQUARE BIRU +3075 ; [.32BC.0020.000E.3075] # HIRAGANA LETTER HU +31F7 ; [.32BC.0020.000F.31F7] # KATAKANA LETTER SMALL HU +30D5 ; [.32BC.0020.0011.30D5] # KATAKANA LETTER HU +FF8C ; [.32BC.0020.0012.FF8C] # HALFWIDTH KATAKANA LETTER HU +32EB ; [.32BC.0020.0013.32EB] # CIRCLED KATAKANA HU +3076 ; [.32BC.0020.000E.3075][.0000.0128.0002.3099] # HIRAGANA LETTER BU +30D6 ; [.32BC.0020.0011.30D5][.0000.0128.0002.3099] # KATAKANA LETTER BU +3077 ; [.32BC.0020.000E.3075][.0000.0129.0002.309A] # HIRAGANA LETTER PU +30D7 ; [.32BC.0020.0011.30D5][.0000.0129.0002.309A] # KATAKANA LETTER PU +3332 ; [.32BC.0020.001C.3332][.32A0.0020.001C.3332][.32C8.0020.001F.3332][.32B2.0020.001F.3332][.32B4.0020.001F.3332][.0000.0128.001F.3332] # SQUARE HUARADDO +3333 ; [.32BC.0020.001C.3333][.32A1.0020.001C.3333][.15A0.0020.001F.3333][.32B4.0020.001F.3333] # SQUARE HUIITO +3334 ; [.32BC.0020.001C.3334][.0000.0128.001C.3334][.32B2.0020.001F.3334][.32AC.0020.001F.3334][.32A4.0020.001F.3334][.32CA.0020.001F.3334] # SQUARE BUSSYERU +3335 ; [.32BC.0020.001C.3335][.32C8.0020.001C.3335][.32D1.0020.001F.3335] # SQUARE HURAN +3078 ; [.32BD.0020.000E.3078] # HIRAGANA LETTER HE +31F8 ; [.32BD.0020.000F.31F8] # KATAKANA LETTER SMALL HE +30D8 ; [.32BD.0020.0011.30D8] # KATAKANA LETTER HE +FF8D ; [.32BD.0020.0012.FF8D] # HALFWIDTH KATAKANA LETTER HE +32EC ; [.32BD.0020.0013.32EC] # CIRCLED KATAKANA HE +3079 ; [.32BD.0020.000E.3078][.0000.0128.0002.3099] # HIRAGANA LETTER BE +30D9 ; [.32BD.0020.0011.30D8][.0000.0128.0002.3099] # KATAKANA LETTER BE +307A ; [.32BD.0020.000E.3078][.0000.0129.0002.309A] # HIRAGANA LETTER PE +30DA ; [.32BD.0020.0011.30D8][.0000.0129.0002.309A] # KATAKANA LETTER PE +333B ; [.32BD.0020.001C.333B][.0000.0129.001C.333B][.15A0.0020.001F.333B][.32AC.0020.001F.333B][.0000.0128.001F.333B] # SQUARE PEEZI +333C ; [.32BD.0020.001C.333C][.0000.0128.001C.333C][.15A0.0020.001F.333C][.32B0.0020.001F.333C] # SQUARE BEETA +3336 ; [.32BD.0020.001C.3336][.32A8.0020.001C.3336][.32B0.0020.001F.3336][.15A0.0020.001F.3336][.32CA.0020.001F.3336] # SQUARE HEKUTAARU +3337 ; [.32BD.0020.001C.3337][.0000.0129.001C.3337][.32AF.0020.001F.3337] # SQUARE PESO +3338 ; [.32BD.0020.001C.3338][.0000.0129.001C.3338][.32B6.0020.001F.3338][.32BB.0020.001F.3338] # SQUARE PENIHI +3339 ; [.32BD.0020.001C.3339][.32CA.0020.001C.3339][.32B2.0020.001F.3339] # SQUARE HERUTU +333A ; [.32BD.0020.001C.333A][.0000.0129.001C.333A][.32D1.0020.001F.333A][.32AD.0020.001F.333A] # SQUARE PENSU +307B ; [.32BE.0020.000E.307B] # HIRAGANA LETTER HO +31F9 ; [.32BE.0020.000F.31F9] # KATAKANA LETTER SMALL HO +30DB ; [.32BE.0020.0011.30DB] # KATAKANA LETTER HO +FF8E ; [.32BE.0020.0012.FF8E] # HALFWIDTH KATAKANA LETTER HO +32ED ; [.32BE.0020.0013.32ED] # CIRCLED KATAKANA HO +307C ; [.32BE.0020.000E.307B][.0000.0128.0002.3099] # HIRAGANA LETTER BO +30DC ; [.32BE.0020.0011.30DB][.0000.0128.0002.3099] # KATAKANA LETTER BO +307D ; [.32BE.0020.000E.307B][.0000.0129.0002.309A] # HIRAGANA LETTER PO +30DD ; [.32BE.0020.0011.30DB][.0000.0129.0002.309A] # KATAKANA LETTER PO +3341 ; [.32BE.0020.001C.3341][.15A0.0020.001C.3341][.32CA.0020.001F.3341] # SQUARE HOORU +3342 ; [.32BE.0020.001C.3342][.15A0.0020.001C.3342][.32D1.0020.001F.3342] # SQUARE HOON +333D ; [.32BE.0020.001C.333D][.0000.0129.001C.333D][.32A1.0020.001F.333D][.32D1.0020.001F.333D][.32B4.0020.001F.333D] # SQUARE POINTO +1F200 ; [.32BE.0020.001C.1F200][.32A6.0020.001C.1F200] # SQUARE HIRAGANA HOKA +333E ; [.32BE.0020.001C.333E][.0000.0128.001C.333E][.32CA.0020.001F.333E][.32B4.0020.001F.333E] # SQUARE BORUTO +333F ; [.32BE.0020.001C.333F][.32D1.0020.001C.333F] # SQUARE HON +3340 ; [.32BE.0020.001C.3340][.0000.0129.001C.3340][.32D1.0020.001F.3340][.32B4.0020.001F.3340][.0000.0128.001F.3340] # SQUARE PONDO +307E ; [.32BF.0020.000E.307E] # HIRAGANA LETTER MA +30DE ; [.32BF.0020.0011.30DE] # KATAKANA LETTER MA +FF8F ; [.32BF.0020.0012.FF8F] # HALFWIDTH KATAKANA LETTER MA +32EE ; [.32BF.0020.0013.32EE] # CIRCLED KATAKANA MA +3343 ; [.32BF.0020.001C.3343][.32A1.0020.001C.3343][.32A8.0020.001F.3343][.32CC.0020.001F.3343] # SQUARE MAIKURO +3344 ; [.32BF.0020.001C.3344][.32A1.0020.001C.3344][.32CA.0020.001F.3344] # SQUARE MAIRU +303C ; [.32BF.0020.0004.303C][.32AD.0020.0004.303C] # MASU MARK +3345 ; [.32BF.0020.001C.3345][.32B2.0020.001C.3345][.32BA.0020.001F.3345] # SQUARE MAHHA +3346 ; [.32BF.0020.001C.3346][.32CA.0020.001C.3346][.32A8.0020.001F.3346] # SQUARE MARUKU +3347 ; [.32BF.0020.001C.3347][.32D1.0020.001C.3347][.32AC.0020.001F.3347][.32C7.0020.001F.3347][.32D1.0020.001F.3347] # SQUARE MANSYON +307F ; [.32C0.0020.000E.307F] # HIRAGANA LETTER MI +30DF ; [.32C0.0020.0011.30DF] # KATAKANA LETTER MI +FF90 ; [.32C0.0020.0012.FF90] # HALFWIDTH KATAKANA LETTER MI +32EF ; [.32C0.0020.0013.32EF] # CIRCLED KATAKANA MI +3348 ; [.32C0.0020.001C.3348][.32A8.0020.001C.3348][.32CC.0020.001F.3348][.32D1.0020.001F.3348] # SQUARE MIKURON +3349 ; [.32C0.0020.001C.3349][.32C9.0020.001C.3349] # SQUARE MIRI +334A ; [.32C0.0020.001C.334A][.32C9.0020.001C.334A][.32BA.0020.001F.334A][.0000.0128.001F.334A][.15A0.0020.001F.334A][.32CA.0020.001F.334A] # SQUARE MIRIBAARU +3080 ; [.32C1.0020.000E.3080] # HIRAGANA LETTER MU +31FA ; [.32C1.0020.000F.31FA] # KATAKANA LETTER SMALL MU +30E0 ; [.32C1.0020.0011.30E0] # KATAKANA LETTER MU +FF91 ; [.32C1.0020.0012.FF91] # HALFWIDTH KATAKANA LETTER MU +32F0 ; [.32C1.0020.0013.32F0] # CIRCLED KATAKANA MU +3081 ; [.32C2.0020.000E.3081] # HIRAGANA LETTER ME +30E1 ; [.32C2.0020.0011.30E1] # KATAKANA LETTER ME +FF92 ; [.32C2.0020.0012.FF92] # HALFWIDTH KATAKANA LETTER ME +32F1 ; [.32C2.0020.0013.32F1] # CIRCLED KATAKANA ME +334D ; [.32C2.0020.001C.334D][.15A0.0020.001C.334D][.32B4.0020.001F.334D][.32CA.0020.001F.334D] # SQUARE MEETORU +334B ; [.32C2.0020.001C.334B][.32A6.0020.001C.334B][.0000.0128.001F.334B] # SQUARE MEGA +334C ; [.32C2.0020.001C.334C][.32A6.0020.001C.334C][.0000.0128.001F.334C][.32B4.0020.001F.334C][.32D1.0020.001F.334C] # SQUARE MEGATON +3082 ; [.32C3.0020.000E.3082] # HIRAGANA LETTER MO +30E2 ; [.32C3.0020.0011.30E2] # KATAKANA LETTER MO +FF93 ; [.32C3.0020.0012.FF93] # HALFWIDTH KATAKANA LETTER MO +32F2 ; [.32C3.0020.0013.32F2] # CIRCLED KATAKANA MO +3083 ; [.32C4.0020.000D.3083] # HIRAGANA LETTER SMALL YA +3084 ; [.32C4.0020.000E.3084] # HIRAGANA LETTER YA +30E3 ; [.32C4.0020.000F.30E3] # KATAKANA LETTER SMALL YA +FF6C ; [.32C4.0020.0010.FF6C] # HALFWIDTH KATAKANA LETTER SMALL YA +30E4 ; [.32C4.0020.0011.30E4] # KATAKANA LETTER YA +FF94 ; [.32C4.0020.0012.FF94] # HALFWIDTH KATAKANA LETTER YA +32F3 ; [.32C4.0020.0013.32F3] # CIRCLED KATAKANA YA +334E ; [.32C4.0020.001C.334E][.15A0.0020.001C.334E][.32B4.0020.001F.334E][.0000.0128.001F.334E] # SQUARE YAADO +334F ; [.32C4.0020.001C.334F][.15A0.0020.001C.334F][.32CA.0020.001F.334F] # SQUARE YAARU +3085 ; [.32C5.0020.000D.3085] # HIRAGANA LETTER SMALL YU +3086 ; [.32C5.0020.000E.3086] # HIRAGANA LETTER YU +30E5 ; [.32C5.0020.000F.30E5] # KATAKANA LETTER SMALL YU +FF6D ; [.32C5.0020.0010.FF6D] # HALFWIDTH KATAKANA LETTER SMALL YU +30E6 ; [.32C5.0020.0011.30E6] # KATAKANA LETTER YU +FF95 ; [.32C5.0020.0012.FF95] # HALFWIDTH KATAKANA LETTER YU +32F4 ; [.32C5.0020.0013.32F4] # CIRCLED KATAKANA YU +3350 ; [.32C5.0020.001C.3350][.32A0.0020.001C.3350][.32D1.0020.001F.3350] # SQUARE YUAN +1B001 ; [.32C6.0020.0002.1B001] # HIRAGANA LETTER ARCHAIC YE +3087 ; [.32C7.0020.000D.3087] # HIRAGANA LETTER SMALL YO +3088 ; [.32C7.0020.000E.3088] # HIRAGANA LETTER YO +30E7 ; [.32C7.0020.000F.30E7] # KATAKANA LETTER SMALL YO +FF6E ; [.32C7.0020.0010.FF6E] # HALFWIDTH KATAKANA LETTER SMALL YO +30E8 ; [.32C7.0020.0011.30E8] # KATAKANA LETTER YO +FF96 ; [.32C7.0020.0012.FF96] # HALFWIDTH KATAKANA LETTER YO +32F5 ; [.32C7.0020.0013.32F5] # CIRCLED KATAKANA YO +309F ; [.32C7.0020.0016.309F][.32C9.0020.0016.309F] # HIRAGANA DIGRAPH YORI +3089 ; [.32C8.0020.000E.3089] # HIRAGANA LETTER RA +31FB ; [.32C8.0020.000F.31FB] # KATAKANA LETTER SMALL RA +30E9 ; [.32C8.0020.0011.30E9] # KATAKANA LETTER RA +FF97 ; [.32C8.0020.0012.FF97] # HALFWIDTH KATAKANA LETTER RA +32F6 ; [.32C8.0020.0013.32F6] # CIRCLED KATAKANA RA +308A ; [.32C9.0020.000E.308A] # HIRAGANA LETTER RI +31FC ; [.32C9.0020.000F.31FC] # KATAKANA LETTER SMALL RI +30EA ; [.32C9.0020.0011.30EA] # KATAKANA LETTER RI +FF98 ; [.32C9.0020.0012.FF98] # HALFWIDTH KATAKANA LETTER RI +32F7 ; [.32C9.0020.0013.32F7] # CIRCLED KATAKANA RI +3351 ; [.32C9.0020.001C.3351][.32B2.0020.001C.3351][.32B4.0020.001F.3351][.32CA.0020.001F.3351] # SQUARE RITTORU +3352 ; [.32C9.0020.001C.3352][.32C8.0020.001C.3352] # SQUARE RIRA +308B ; [.32CA.0020.000E.308B] # HIRAGANA LETTER RU +31FD ; [.32CA.0020.000F.31FD] # KATAKANA LETTER SMALL RU +30EB ; [.32CA.0020.0011.30EB] # KATAKANA LETTER RU +FF99 ; [.32CA.0020.0012.FF99] # HALFWIDTH KATAKANA LETTER RU +32F8 ; [.32CA.0020.0013.32F8] # CIRCLED KATAKANA RU +3354 ; [.32CA.0020.001C.3354][.15A0.0020.001C.3354][.32BC.0020.001F.3354][.0000.0128.001F.3354][.32CA.0020.001F.3354] # SQUARE RUUBURU +3353 ; [.32CA.0020.001C.3353][.32BB.0020.001C.3353][.0000.0129.001F.3353][.15A0.0020.001F.3353] # SQUARE RUPII +308C ; [.32CB.0020.000E.308C] # HIRAGANA LETTER RE +31FE ; [.32CB.0020.000F.31FE] # KATAKANA LETTER SMALL RE +30EC ; [.32CB.0020.0011.30EC] # KATAKANA LETTER RE +FF9A ; [.32CB.0020.0012.FF9A] # HALFWIDTH KATAKANA LETTER RE +32F9 ; [.32CB.0020.0013.32F9] # CIRCLED KATAKANA RE +3355 ; [.32CB.0020.001C.3355][.32C1.0020.001C.3355] # SQUARE REMU +3356 ; [.32CB.0020.001C.3356][.32D1.0020.001C.3356][.32B4.0020.001F.3356][.32A9.0020.001F.3356][.0000.0128.001F.3356][.32D1.0020.001F.3356] # SQUARE RENTOGEN +308D ; [.32CC.0020.000E.308D] # HIRAGANA LETTER RO +31FF ; [.32CC.0020.000F.31FF] # KATAKANA LETTER SMALL RO +30ED ; [.32CC.0020.0011.30ED] # KATAKANA LETTER RO +FF9B ; [.32CC.0020.0012.FF9B] # HALFWIDTH KATAKANA LETTER RO +32FA ; [.32CC.0020.0013.32FA] # CIRCLED KATAKANA RO +308E ; [.32CD.0020.000D.308E] # HIRAGANA LETTER SMALL WA +308F ; [.32CD.0020.000E.308F] # HIRAGANA LETTER WA +30EE ; [.32CD.0020.000F.30EE] # KATAKANA LETTER SMALL WA +30EF ; [.32CD.0020.0011.30EF] # KATAKANA LETTER WA +FF9C ; [.32CD.0020.0012.FF9C] # HALFWIDTH KATAKANA LETTER WA +32FB ; [.32CD.0020.0013.32FB] # CIRCLED KATAKANA WA +30F7 ; [.32CD.0020.0011.30EF][.0000.0128.0002.3099] # KATAKANA LETTER VA +3357 ; [.32CD.0020.001C.3357][.32B2.0020.001C.3357][.32B4.0020.001F.3357] # SQUARE WATTO +3090 ; [.32CE.0020.000E.3090] # HIRAGANA LETTER WI +30F0 ; [.32CE.0020.0011.30F0] # KATAKANA LETTER WI +32FC ; [.32CE.0020.0013.32FC] # CIRCLED KATAKANA WI +30F8 ; [.32CE.0020.0011.30F0][.0000.0128.0002.3099] # KATAKANA LETTER VI +3091 ; [.32CF.0020.000E.3091] # HIRAGANA LETTER WE +30F1 ; [.32CF.0020.0011.30F1] # KATAKANA LETTER WE +32FD ; [.32CF.0020.0013.32FD] # CIRCLED KATAKANA WE +30F9 ; [.32CF.0020.0011.30F1][.0000.0128.0002.3099] # KATAKANA LETTER VE +3092 ; [.32D0.0020.000E.3092] # HIRAGANA LETTER WO +30F2 ; [.32D0.0020.0011.30F2] # KATAKANA LETTER WO +FF66 ; [.32D0.0020.0012.FF66] # HALFWIDTH KATAKANA LETTER WO +32FE ; [.32D0.0020.0013.32FE] # CIRCLED KATAKANA WO +30FA ; [.32D0.0020.0011.30F2][.0000.0128.0002.3099] # KATAKANA LETTER VO +3093 ; [.32D1.0020.000E.3093] # HIRAGANA LETTER N +30F3 ; [.32D1.0020.0011.30F3] # KATAKANA LETTER N +FF9D ; [.32D1.0020.0012.FF9D] # HALFWIDTH KATAKANA LETTER N +3105 ; [.32D2.0020.0002.3105] # BOPOMOFO LETTER B +31A0 ; [.32D2.0020.0004.31A0][.0000.013A.0004.31A0] # BOPOMOFO LETTER BU +3106 ; [.32D3.0020.0002.3106] # BOPOMOFO LETTER P +31B4 ; [.32D3.0020.0019.31B4] # BOPOMOFO FINAL LETTER P +3107 ; [.32D4.0020.0002.3107] # BOPOMOFO LETTER M +3108 ; [.32D5.0020.0002.3108] # BOPOMOFO LETTER F +312A ; [.32D6.0020.0002.312A] # BOPOMOFO LETTER V +3109 ; [.32D7.0020.0002.3109] # BOPOMOFO LETTER D +310A ; [.32D8.0020.0002.310A] # BOPOMOFO LETTER T +31B5 ; [.32D8.0020.0019.31B5] # BOPOMOFO FINAL LETTER T +310B ; [.32D9.0020.0002.310B] # BOPOMOFO LETTER N +310C ; [.32DA.0020.0002.310C] # BOPOMOFO LETTER L +310D ; [.32DB.0020.0002.310D] # BOPOMOFO LETTER G +31A3 ; [.32DB.0020.0004.31A3][.0000.013A.0004.31A3] # BOPOMOFO LETTER GU +310E ; [.32DC.0020.0002.310E] # BOPOMOFO LETTER K +31B6 ; [.32DC.0020.0019.31B6] # BOPOMOFO FINAL LETTER K +312B ; [.32DD.0020.0002.312B] # BOPOMOFO LETTER NG +31AD ; [.32DE.0020.0002.31AD] # BOPOMOFO LETTER NGG +310F ; [.32DF.0020.0002.310F] # BOPOMOFO LETTER H +31B7 ; [.32DF.0020.0019.31B7] # BOPOMOFO FINAL LETTER H +3110 ; [.32E0.0020.0002.3110] # BOPOMOFO LETTER J +31A2 ; [.32E0.0020.0004.31A2][.0000.013A.0004.31A2] # BOPOMOFO LETTER JI +3111 ; [.32E1.0020.0002.3111] # BOPOMOFO LETTER Q +3112 ; [.32E2.0020.0002.3112] # BOPOMOFO LETTER X +312C ; [.32E3.0020.0002.312C] # BOPOMOFO LETTER GN +3113 ; [.32E4.0020.0002.3113] # BOPOMOFO LETTER ZH +3114 ; [.32E5.0020.0002.3114] # BOPOMOFO LETTER CH +3115 ; [.32E6.0020.0002.3115] # BOPOMOFO LETTER SH +3116 ; [.32E7.0020.0002.3116] # BOPOMOFO LETTER R +3117 ; [.32E8.0020.0002.3117] # BOPOMOFO LETTER Z +31A1 ; [.32E8.0020.0004.31A1][.0000.013A.0004.31A1] # BOPOMOFO LETTER ZI +3118 ; [.32E9.0020.0002.3118] # BOPOMOFO LETTER C +3119 ; [.32EA.0020.0002.3119] # BOPOMOFO LETTER S +31B8 ; [.32EB.0020.0002.31B8] # BOPOMOFO LETTER GH +31B9 ; [.32EC.0020.0002.31B9] # BOPOMOFO LETTER LH +31BA ; [.32ED.0020.0002.31BA] # BOPOMOFO LETTER ZY +311A ; [.32EE.0020.0002.311A] # BOPOMOFO LETTER A +31A9 ; [.32EE.0020.0004.31A9][.0000.013A.0004.31A9] # BOPOMOFO LETTER ANN +311B ; [.32EF.0020.0002.311B] # BOPOMOFO LETTER O +31A7 ; [.32EF.0020.0004.31A7][.0000.013A.0004.31A7] # BOPOMOFO LETTER ONN +31A6 ; [.32F0.0020.0002.31A6] # BOPOMOFO LETTER OO +311C ; [.32F1.0020.0002.311C] # BOPOMOFO LETTER E +311D ; [.32F2.0020.0002.311D] # BOPOMOFO LETTER EH +31A4 ; [.32F3.0020.0002.31A4] # BOPOMOFO LETTER EE +31A5 ; [.32F3.0020.0004.31A5][.0000.013A.0004.31A5] # BOPOMOFO LETTER ENN +311E ; [.32F4.0020.0002.311E] # BOPOMOFO LETTER AI +31AE ; [.32F4.0020.0004.31AE][.0000.013A.0004.31AE] # BOPOMOFO LETTER AINN +311F ; [.32F5.0020.0002.311F] # BOPOMOFO LETTER EI +3120 ; [.32F6.0020.0002.3120] # BOPOMOFO LETTER AU +31AF ; [.32F6.0020.0004.31AF][.0000.013A.0004.31AF] # BOPOMOFO LETTER AUNN +3121 ; [.32F7.0020.0002.3121] # BOPOMOFO LETTER OU +3122 ; [.32F8.0020.0002.3122] # BOPOMOFO LETTER AN +3123 ; [.32F9.0020.0002.3123] # BOPOMOFO LETTER EN +3124 ; [.32FA.0020.0002.3124] # BOPOMOFO LETTER ANG +31B2 ; [.32FB.0020.0002.31B2] # BOPOMOFO LETTER ONG +3125 ; [.32FC.0020.0002.3125] # BOPOMOFO LETTER ENG +31B0 ; [.32FD.0020.0002.31B0] # BOPOMOFO LETTER AM +31B1 ; [.32FE.0020.0002.31B1] # BOPOMOFO LETTER OM +31AC ; [.32FF.0020.0002.31AC] # BOPOMOFO LETTER IM +3126 ; [.3300.0020.0002.3126] # BOPOMOFO LETTER ER +3127 ; [.3301.0020.0002.3127] # BOPOMOFO LETTER I +31AA ; [.3301.0020.0004.31AA][.0000.013A.0004.31AA] # BOPOMOFO LETTER INN +31B3 ; [.3301.0020.0016.31B3][.0000.013A.0016.31B3] # BOPOMOFO LETTER INNN +3128 ; [.3302.0020.0002.3128] # BOPOMOFO LETTER U +31AB ; [.3302.0020.0004.31AB][.0000.013A.0004.31AB] # BOPOMOFO LETTER UNN +31A8 ; [.3302.0020.0004.31A8][.0000.013C.0004.31A8] # BOPOMOFO LETTER IR +3129 ; [.3303.0020.0002.3129] # BOPOMOFO LETTER IU +312D ; [.3304.0020.0002.312D] # BOPOMOFO LETTER IH +A000 ; [.3305.0020.0002.A000] # YI SYLLABLE IT +A001 ; [.3306.0020.0002.A001] # YI SYLLABLE IX +A002 ; [.3307.0020.0002.A002] # YI SYLLABLE I +A003 ; [.3308.0020.0002.A003] # YI SYLLABLE IP +A004 ; [.3309.0020.0002.A004] # YI SYLLABLE IET +A005 ; [.330A.0020.0002.A005] # YI SYLLABLE IEX +A006 ; [.330B.0020.0002.A006] # YI SYLLABLE IE +A007 ; [.330C.0020.0002.A007] # YI SYLLABLE IEP +A008 ; [.330D.0020.0002.A008] # YI SYLLABLE AT +A009 ; [.330E.0020.0002.A009] # YI SYLLABLE AX +A00A ; [.330F.0020.0002.A00A] # YI SYLLABLE A +A00B ; [.3310.0020.0002.A00B] # YI SYLLABLE AP +A00C ; [.3311.0020.0002.A00C] # YI SYLLABLE UOX +A00D ; [.3312.0020.0002.A00D] # YI SYLLABLE UO +A00E ; [.3313.0020.0002.A00E] # YI SYLLABLE UOP +A00F ; [.3314.0020.0002.A00F] # YI SYLLABLE OT +A010 ; [.3315.0020.0002.A010] # YI SYLLABLE OX +A011 ; [.3316.0020.0002.A011] # YI SYLLABLE O +A012 ; [.3317.0020.0002.A012] # YI SYLLABLE OP +A013 ; [.3318.0020.0002.A013] # YI SYLLABLE EX +A014 ; [.3319.0020.0002.A014] # YI SYLLABLE E +A015 ; [.331A.0020.0002.A015] # YI SYLLABLE WU +A016 ; [.331B.0020.0002.A016] # YI SYLLABLE BIT +A017 ; [.331C.0020.0002.A017] # YI SYLLABLE BIX +A018 ; [.331D.0020.0002.A018] # YI SYLLABLE BI +A019 ; [.331E.0020.0002.A019] # YI SYLLABLE BIP +A01A ; [.331F.0020.0002.A01A] # YI SYLLABLE BIET +A01B ; [.3320.0020.0002.A01B] # YI SYLLABLE BIEX +A01C ; [.3321.0020.0002.A01C] # YI SYLLABLE BIE +A01D ; [.3322.0020.0002.A01D] # YI SYLLABLE BIEP +A01E ; [.3323.0020.0002.A01E] # YI SYLLABLE BAT +A01F ; [.3324.0020.0002.A01F] # YI SYLLABLE BAX +A020 ; [.3325.0020.0002.A020] # YI SYLLABLE BA +A021 ; [.3326.0020.0002.A021] # YI SYLLABLE BAP +A022 ; [.3327.0020.0002.A022] # YI SYLLABLE BUOX +A023 ; [.3328.0020.0002.A023] # YI SYLLABLE BUO +A024 ; [.3329.0020.0002.A024] # YI SYLLABLE BUOP +A025 ; [.332A.0020.0002.A025] # YI SYLLABLE BOT +A026 ; [.332B.0020.0002.A026] # YI SYLLABLE BOX +A027 ; [.332C.0020.0002.A027] # YI SYLLABLE BO +A028 ; [.332D.0020.0002.A028] # YI SYLLABLE BOP +A029 ; [.332E.0020.0002.A029] # YI SYLLABLE BEX +A02A ; [.332F.0020.0002.A02A] # YI SYLLABLE BE +A02B ; [.3330.0020.0002.A02B] # YI SYLLABLE BEP +A02C ; [.3331.0020.0002.A02C] # YI SYLLABLE BUT +A02D ; [.3332.0020.0002.A02D] # YI SYLLABLE BUX +A02E ; [.3333.0020.0002.A02E] # YI SYLLABLE BU +A02F ; [.3334.0020.0002.A02F] # YI SYLLABLE BUP +A030 ; [.3335.0020.0002.A030] # YI SYLLABLE BURX +A031 ; [.3336.0020.0002.A031] # YI SYLLABLE BUR +A032 ; [.3337.0020.0002.A032] # YI SYLLABLE BYT +A033 ; [.3338.0020.0002.A033] # YI SYLLABLE BYX +A034 ; [.3339.0020.0002.A034] # YI SYLLABLE BY +A035 ; [.333A.0020.0002.A035] # YI SYLLABLE BYP +A036 ; [.333B.0020.0002.A036] # YI SYLLABLE BYRX +A037 ; [.333C.0020.0002.A037] # YI SYLLABLE BYR +A038 ; [.333D.0020.0002.A038] # YI SYLLABLE PIT +A039 ; [.333E.0020.0002.A039] # YI SYLLABLE PIX +A03A ; [.333F.0020.0002.A03A] # YI SYLLABLE PI +A03B ; [.3340.0020.0002.A03B] # YI SYLLABLE PIP +A03C ; [.3341.0020.0002.A03C] # YI SYLLABLE PIEX +A03D ; [.3342.0020.0002.A03D] # YI SYLLABLE PIE +A03E ; [.3343.0020.0002.A03E] # YI SYLLABLE PIEP +A03F ; [.3344.0020.0002.A03F] # YI SYLLABLE PAT +A040 ; [.3345.0020.0002.A040] # YI SYLLABLE PAX +A041 ; [.3346.0020.0002.A041] # YI SYLLABLE PA +A042 ; [.3347.0020.0002.A042] # YI SYLLABLE PAP +A043 ; [.3348.0020.0002.A043] # YI SYLLABLE PUOX +A044 ; [.3349.0020.0002.A044] # YI SYLLABLE PUO +A045 ; [.334A.0020.0002.A045] # YI SYLLABLE PUOP +A046 ; [.334B.0020.0002.A046] # YI SYLLABLE POT +A047 ; [.334C.0020.0002.A047] # YI SYLLABLE POX +A048 ; [.334D.0020.0002.A048] # YI SYLLABLE PO +A049 ; [.334E.0020.0002.A049] # YI SYLLABLE POP +A04A ; [.334F.0020.0002.A04A] # YI SYLLABLE PUT +A04B ; [.3350.0020.0002.A04B] # YI SYLLABLE PUX +A04C ; [.3351.0020.0002.A04C] # YI SYLLABLE PU +A04D ; [.3352.0020.0002.A04D] # YI SYLLABLE PUP +A04E ; [.3353.0020.0002.A04E] # YI SYLLABLE PURX +A04F ; [.3354.0020.0002.A04F] # YI SYLLABLE PUR +A050 ; [.3355.0020.0002.A050] # YI SYLLABLE PYT +A051 ; [.3356.0020.0002.A051] # YI SYLLABLE PYX +A052 ; [.3357.0020.0002.A052] # YI SYLLABLE PY +A053 ; [.3358.0020.0002.A053] # YI SYLLABLE PYP +A054 ; [.3359.0020.0002.A054] # YI SYLLABLE PYRX +A055 ; [.335A.0020.0002.A055] # YI SYLLABLE PYR +A056 ; [.335B.0020.0002.A056] # YI SYLLABLE BBIT +A057 ; [.335C.0020.0002.A057] # YI SYLLABLE BBIX +A058 ; [.335D.0020.0002.A058] # YI SYLLABLE BBI +A059 ; [.335E.0020.0002.A059] # YI SYLLABLE BBIP +A05A ; [.335F.0020.0002.A05A] # YI SYLLABLE BBIET +A05B ; [.3360.0020.0002.A05B] # YI SYLLABLE BBIEX +A05C ; [.3361.0020.0002.A05C] # YI SYLLABLE BBIE +A05D ; [.3362.0020.0002.A05D] # YI SYLLABLE BBIEP +A05E ; [.3363.0020.0002.A05E] # YI SYLLABLE BBAT +A05F ; [.3364.0020.0002.A05F] # YI SYLLABLE BBAX +A060 ; [.3365.0020.0002.A060] # YI SYLLABLE BBA +A061 ; [.3366.0020.0002.A061] # YI SYLLABLE BBAP +A062 ; [.3367.0020.0002.A062] # YI SYLLABLE BBUOX +A063 ; [.3368.0020.0002.A063] # YI SYLLABLE BBUO +A064 ; [.3369.0020.0002.A064] # YI SYLLABLE BBUOP +A065 ; [.336A.0020.0002.A065] # YI SYLLABLE BBOT +A066 ; [.336B.0020.0002.A066] # YI SYLLABLE BBOX +A067 ; [.336C.0020.0002.A067] # YI SYLLABLE BBO +A068 ; [.336D.0020.0002.A068] # YI SYLLABLE BBOP +A069 ; [.336E.0020.0002.A069] # YI SYLLABLE BBEX +A06A ; [.336F.0020.0002.A06A] # YI SYLLABLE BBE +A06B ; [.3370.0020.0002.A06B] # YI SYLLABLE BBEP +A06C ; [.3371.0020.0002.A06C] # YI SYLLABLE BBUT +A06D ; [.3372.0020.0002.A06D] # YI SYLLABLE BBUX +A06E ; [.3373.0020.0002.A06E] # YI SYLLABLE BBU +A06F ; [.3374.0020.0002.A06F] # YI SYLLABLE BBUP +A070 ; [.3375.0020.0002.A070] # YI SYLLABLE BBURX +A071 ; [.3376.0020.0002.A071] # YI SYLLABLE BBUR +A072 ; [.3377.0020.0002.A072] # YI SYLLABLE BBYT +A073 ; [.3378.0020.0002.A073] # YI SYLLABLE BBYX +A074 ; [.3379.0020.0002.A074] # YI SYLLABLE BBY +A075 ; [.337A.0020.0002.A075] # YI SYLLABLE BBYP +A076 ; [.337B.0020.0002.A076] # YI SYLLABLE NBIT +A077 ; [.337C.0020.0002.A077] # YI SYLLABLE NBIX +A078 ; [.337D.0020.0002.A078] # YI SYLLABLE NBI +A079 ; [.337E.0020.0002.A079] # YI SYLLABLE NBIP +A07A ; [.337F.0020.0002.A07A] # YI SYLLABLE NBIEX +A07B ; [.3380.0020.0002.A07B] # YI SYLLABLE NBIE +A07C ; [.3381.0020.0002.A07C] # YI SYLLABLE NBIEP +A07D ; [.3382.0020.0002.A07D] # YI SYLLABLE NBAT +A07E ; [.3383.0020.0002.A07E] # YI SYLLABLE NBAX +A07F ; [.3384.0020.0002.A07F] # YI SYLLABLE NBA +A080 ; [.3385.0020.0002.A080] # YI SYLLABLE NBAP +A081 ; [.3386.0020.0002.A081] # YI SYLLABLE NBOT +A082 ; [.3387.0020.0002.A082] # YI SYLLABLE NBOX +A083 ; [.3388.0020.0002.A083] # YI SYLLABLE NBO +A084 ; [.3389.0020.0002.A084] # YI SYLLABLE NBOP +A085 ; [.338A.0020.0002.A085] # YI SYLLABLE NBUT +A086 ; [.338B.0020.0002.A086] # YI SYLLABLE NBUX +A087 ; [.338C.0020.0002.A087] # YI SYLLABLE NBU +A088 ; [.338D.0020.0002.A088] # YI SYLLABLE NBUP +A089 ; [.338E.0020.0002.A089] # YI SYLLABLE NBURX +A08A ; [.338F.0020.0002.A08A] # YI SYLLABLE NBUR +A08B ; [.3390.0020.0002.A08B] # YI SYLLABLE NBYT +A08C ; [.3391.0020.0002.A08C] # YI SYLLABLE NBYX +A08D ; [.3392.0020.0002.A08D] # YI SYLLABLE NBY +A08E ; [.3393.0020.0002.A08E] # YI SYLLABLE NBYP +A08F ; [.3394.0020.0002.A08F] # YI SYLLABLE NBYRX +A090 ; [.3395.0020.0002.A090] # YI SYLLABLE NBYR +A091 ; [.3396.0020.0002.A091] # YI SYLLABLE HMIT +A092 ; [.3397.0020.0002.A092] # YI SYLLABLE HMIX +A093 ; [.3398.0020.0002.A093] # YI SYLLABLE HMI +A094 ; [.3399.0020.0002.A094] # YI SYLLABLE HMIP +A095 ; [.339A.0020.0002.A095] # YI SYLLABLE HMIEX +A096 ; [.339B.0020.0002.A096] # YI SYLLABLE HMIE +A097 ; [.339C.0020.0002.A097] # YI SYLLABLE HMIEP +A098 ; [.339D.0020.0002.A098] # YI SYLLABLE HMAT +A099 ; [.339E.0020.0002.A099] # YI SYLLABLE HMAX +A09A ; [.339F.0020.0002.A09A] # YI SYLLABLE HMA +A09B ; [.33A0.0020.0002.A09B] # YI SYLLABLE HMAP +A09C ; [.33A1.0020.0002.A09C] # YI SYLLABLE HMUOX +A09D ; [.33A2.0020.0002.A09D] # YI SYLLABLE HMUO +A09E ; [.33A3.0020.0002.A09E] # YI SYLLABLE HMUOP +A09F ; [.33A4.0020.0002.A09F] # YI SYLLABLE HMOT +A0A0 ; [.33A5.0020.0002.A0A0] # YI SYLLABLE HMOX +A0A1 ; [.33A6.0020.0002.A0A1] # YI SYLLABLE HMO +A0A2 ; [.33A7.0020.0002.A0A2] # YI SYLLABLE HMOP +A0A3 ; [.33A8.0020.0002.A0A3] # YI SYLLABLE HMUT +A0A4 ; [.33A9.0020.0002.A0A4] # YI SYLLABLE HMUX +A0A5 ; [.33AA.0020.0002.A0A5] # YI SYLLABLE HMU +A0A6 ; [.33AB.0020.0002.A0A6] # YI SYLLABLE HMUP +A0A7 ; [.33AC.0020.0002.A0A7] # YI SYLLABLE HMURX +A0A8 ; [.33AD.0020.0002.A0A8] # YI SYLLABLE HMUR +A0A9 ; [.33AE.0020.0002.A0A9] # YI SYLLABLE HMYX +A0AA ; [.33AF.0020.0002.A0AA] # YI SYLLABLE HMY +A0AB ; [.33B0.0020.0002.A0AB] # YI SYLLABLE HMYP +A0AC ; [.33B1.0020.0002.A0AC] # YI SYLLABLE HMYRX +A0AD ; [.33B2.0020.0002.A0AD] # YI SYLLABLE HMYR +A0AE ; [.33B3.0020.0002.A0AE] # YI SYLLABLE MIT +A0AF ; [.33B4.0020.0002.A0AF] # YI SYLLABLE MIX +A0B0 ; [.33B5.0020.0002.A0B0] # YI SYLLABLE MI +A0B1 ; [.33B6.0020.0002.A0B1] # YI SYLLABLE MIP +A0B2 ; [.33B7.0020.0002.A0B2] # YI SYLLABLE MIEX +A0B3 ; [.33B8.0020.0002.A0B3] # YI SYLLABLE MIE +A0B4 ; [.33B9.0020.0002.A0B4] # YI SYLLABLE MIEP +A0B5 ; [.33BA.0020.0002.A0B5] # YI SYLLABLE MAT +A0B6 ; [.33BB.0020.0002.A0B6] # YI SYLLABLE MAX +A0B7 ; [.33BC.0020.0002.A0B7] # YI SYLLABLE MA +A0B8 ; [.33BD.0020.0002.A0B8] # YI SYLLABLE MAP +A0B9 ; [.33BE.0020.0002.A0B9] # YI SYLLABLE MUOT +A0BA ; [.33BF.0020.0002.A0BA] # YI SYLLABLE MUOX +A0BB ; [.33C0.0020.0002.A0BB] # YI SYLLABLE MUO +A0BC ; [.33C1.0020.0002.A0BC] # YI SYLLABLE MUOP +A0BD ; [.33C2.0020.0002.A0BD] # YI SYLLABLE MOT +A0BE ; [.33C3.0020.0002.A0BE] # YI SYLLABLE MOX +A0BF ; [.33C4.0020.0002.A0BF] # YI SYLLABLE MO +A0C0 ; [.33C5.0020.0002.A0C0] # YI SYLLABLE MOP +A0C1 ; [.33C6.0020.0002.A0C1] # YI SYLLABLE MEX +A0C2 ; [.33C7.0020.0002.A0C2] # YI SYLLABLE ME +A0C3 ; [.33C8.0020.0002.A0C3] # YI SYLLABLE MUT +A0C4 ; [.33C9.0020.0002.A0C4] # YI SYLLABLE MUX +A0C5 ; [.33CA.0020.0002.A0C5] # YI SYLLABLE MU +A0C6 ; [.33CB.0020.0002.A0C6] # YI SYLLABLE MUP +A0C7 ; [.33CC.0020.0002.A0C7] # YI SYLLABLE MURX +A0C8 ; [.33CD.0020.0002.A0C8] # YI SYLLABLE MUR +A0C9 ; [.33CE.0020.0002.A0C9] # YI SYLLABLE MYT +A0CA ; [.33CF.0020.0002.A0CA] # YI SYLLABLE MYX +A0CB ; [.33D0.0020.0002.A0CB] # YI SYLLABLE MY +A0CC ; [.33D1.0020.0002.A0CC] # YI SYLLABLE MYP +A0CD ; [.33D2.0020.0002.A0CD] # YI SYLLABLE FIT +A0CE ; [.33D3.0020.0002.A0CE] # YI SYLLABLE FIX +A0CF ; [.33D4.0020.0002.A0CF] # YI SYLLABLE FI +A0D0 ; [.33D5.0020.0002.A0D0] # YI SYLLABLE FIP +A0D1 ; [.33D6.0020.0002.A0D1] # YI SYLLABLE FAT +A0D2 ; [.33D7.0020.0002.A0D2] # YI SYLLABLE FAX +A0D3 ; [.33D8.0020.0002.A0D3] # YI SYLLABLE FA +A0D4 ; [.33D9.0020.0002.A0D4] # YI SYLLABLE FAP +A0D5 ; [.33DA.0020.0002.A0D5] # YI SYLLABLE FOX +A0D6 ; [.33DB.0020.0002.A0D6] # YI SYLLABLE FO +A0D7 ; [.33DC.0020.0002.A0D7] # YI SYLLABLE FOP +A0D8 ; [.33DD.0020.0002.A0D8] # YI SYLLABLE FUT +A0D9 ; [.33DE.0020.0002.A0D9] # YI SYLLABLE FUX +A0DA ; [.33DF.0020.0002.A0DA] # YI SYLLABLE FU +A0DB ; [.33E0.0020.0002.A0DB] # YI SYLLABLE FUP +A0DC ; [.33E1.0020.0002.A0DC] # YI SYLLABLE FURX +A0DD ; [.33E2.0020.0002.A0DD] # YI SYLLABLE FUR +A0DE ; [.33E3.0020.0002.A0DE] # YI SYLLABLE FYT +A0DF ; [.33E4.0020.0002.A0DF] # YI SYLLABLE FYX +A0E0 ; [.33E5.0020.0002.A0E0] # YI SYLLABLE FY +A0E1 ; [.33E6.0020.0002.A0E1] # YI SYLLABLE FYP +A0E2 ; [.33E7.0020.0002.A0E2] # YI SYLLABLE VIT +A0E3 ; [.33E8.0020.0002.A0E3] # YI SYLLABLE VIX +A0E4 ; [.33E9.0020.0002.A0E4] # YI SYLLABLE VI +A0E5 ; [.33EA.0020.0002.A0E5] # YI SYLLABLE VIP +A0E6 ; [.33EB.0020.0002.A0E6] # YI SYLLABLE VIET +A0E7 ; [.33EC.0020.0002.A0E7] # YI SYLLABLE VIEX +A0E8 ; [.33ED.0020.0002.A0E8] # YI SYLLABLE VIE +A0E9 ; [.33EE.0020.0002.A0E9] # YI SYLLABLE VIEP +A0EA ; [.33EF.0020.0002.A0EA] # YI SYLLABLE VAT +A0EB ; [.33F0.0020.0002.A0EB] # YI SYLLABLE VAX +A0EC ; [.33F1.0020.0002.A0EC] # YI SYLLABLE VA +A0ED ; [.33F2.0020.0002.A0ED] # YI SYLLABLE VAP +A0EE ; [.33F3.0020.0002.A0EE] # YI SYLLABLE VOT +A0EF ; [.33F4.0020.0002.A0EF] # YI SYLLABLE VOX +A0F0 ; [.33F5.0020.0002.A0F0] # YI SYLLABLE VO +A0F1 ; [.33F6.0020.0002.A0F1] # YI SYLLABLE VOP +A0F2 ; [.33F7.0020.0002.A0F2] # YI SYLLABLE VEX +A0F3 ; [.33F8.0020.0002.A0F3] # YI SYLLABLE VEP +A0F4 ; [.33F9.0020.0002.A0F4] # YI SYLLABLE VUT +A0F5 ; [.33FA.0020.0002.A0F5] # YI SYLLABLE VUX +A0F6 ; [.33FB.0020.0002.A0F6] # YI SYLLABLE VU +A0F7 ; [.33FC.0020.0002.A0F7] # YI SYLLABLE VUP +A0F8 ; [.33FD.0020.0002.A0F8] # YI SYLLABLE VURX +A0F9 ; [.33FE.0020.0002.A0F9] # YI SYLLABLE VUR +A0FA ; [.33FF.0020.0002.A0FA] # YI SYLLABLE VYT +A0FB ; [.3400.0020.0002.A0FB] # YI SYLLABLE VYX +A0FC ; [.3401.0020.0002.A0FC] # YI SYLLABLE VY +A0FD ; [.3402.0020.0002.A0FD] # YI SYLLABLE VYP +A0FE ; [.3403.0020.0002.A0FE] # YI SYLLABLE VYRX +A0FF ; [.3404.0020.0002.A0FF] # YI SYLLABLE VYR +A100 ; [.3405.0020.0002.A100] # YI SYLLABLE DIT +A101 ; [.3406.0020.0002.A101] # YI SYLLABLE DIX +A102 ; [.3407.0020.0002.A102] # YI SYLLABLE DI +A103 ; [.3408.0020.0002.A103] # YI SYLLABLE DIP +A104 ; [.3409.0020.0002.A104] # YI SYLLABLE DIEX +A105 ; [.340A.0020.0002.A105] # YI SYLLABLE DIE +A106 ; [.340B.0020.0002.A106] # YI SYLLABLE DIEP +A107 ; [.340C.0020.0002.A107] # YI SYLLABLE DAT +A108 ; [.340D.0020.0002.A108] # YI SYLLABLE DAX +A109 ; [.340E.0020.0002.A109] # YI SYLLABLE DA +A10A ; [.340F.0020.0002.A10A] # YI SYLLABLE DAP +A10B ; [.3410.0020.0002.A10B] # YI SYLLABLE DUOX +A10C ; [.3411.0020.0002.A10C] # YI SYLLABLE DUO +A10D ; [.3412.0020.0002.A10D] # YI SYLLABLE DOT +A10E ; [.3413.0020.0002.A10E] # YI SYLLABLE DOX +A10F ; [.3414.0020.0002.A10F] # YI SYLLABLE DO +A110 ; [.3415.0020.0002.A110] # YI SYLLABLE DOP +A111 ; [.3416.0020.0002.A111] # YI SYLLABLE DEX +A112 ; [.3417.0020.0002.A112] # YI SYLLABLE DE +A113 ; [.3418.0020.0002.A113] # YI SYLLABLE DEP +A114 ; [.3419.0020.0002.A114] # YI SYLLABLE DUT +A115 ; [.341A.0020.0002.A115] # YI SYLLABLE DUX +A116 ; [.341B.0020.0002.A116] # YI SYLLABLE DU +A117 ; [.341C.0020.0002.A117] # YI SYLLABLE DUP +A118 ; [.341D.0020.0002.A118] # YI SYLLABLE DURX +A119 ; [.341E.0020.0002.A119] # YI SYLLABLE DUR +A11A ; [.341F.0020.0002.A11A] # YI SYLLABLE TIT +A11B ; [.3420.0020.0002.A11B] # YI SYLLABLE TIX +A11C ; [.3421.0020.0002.A11C] # YI SYLLABLE TI +A11D ; [.3422.0020.0002.A11D] # YI SYLLABLE TIP +A11E ; [.3423.0020.0002.A11E] # YI SYLLABLE TIEX +A11F ; [.3424.0020.0002.A11F] # YI SYLLABLE TIE +A120 ; [.3425.0020.0002.A120] # YI SYLLABLE TIEP +A121 ; [.3426.0020.0002.A121] # YI SYLLABLE TAT +A122 ; [.3427.0020.0002.A122] # YI SYLLABLE TAX +A123 ; [.3428.0020.0002.A123] # YI SYLLABLE TA +A124 ; [.3429.0020.0002.A124] # YI SYLLABLE TAP +A125 ; [.342A.0020.0002.A125] # YI SYLLABLE TUOT +A126 ; [.342B.0020.0002.A126] # YI SYLLABLE TUOX +A127 ; [.342C.0020.0002.A127] # YI SYLLABLE TUO +A128 ; [.342D.0020.0002.A128] # YI SYLLABLE TUOP +A129 ; [.342E.0020.0002.A129] # YI SYLLABLE TOT +A12A ; [.342F.0020.0002.A12A] # YI SYLLABLE TOX +A12B ; [.3430.0020.0002.A12B] # YI SYLLABLE TO +A12C ; [.3431.0020.0002.A12C] # YI SYLLABLE TOP +A12D ; [.3432.0020.0002.A12D] # YI SYLLABLE TEX +A12E ; [.3433.0020.0002.A12E] # YI SYLLABLE TE +A12F ; [.3434.0020.0002.A12F] # YI SYLLABLE TEP +A130 ; [.3435.0020.0002.A130] # YI SYLLABLE TUT +A131 ; [.3436.0020.0002.A131] # YI SYLLABLE TUX +A132 ; [.3437.0020.0002.A132] # YI SYLLABLE TU +A133 ; [.3438.0020.0002.A133] # YI SYLLABLE TUP +A134 ; [.3439.0020.0002.A134] # YI SYLLABLE TURX +A135 ; [.343A.0020.0002.A135] # YI SYLLABLE TUR +A136 ; [.343B.0020.0002.A136] # YI SYLLABLE DDIT +A137 ; [.343C.0020.0002.A137] # YI SYLLABLE DDIX +A138 ; [.343D.0020.0002.A138] # YI SYLLABLE DDI +A139 ; [.343E.0020.0002.A139] # YI SYLLABLE DDIP +A13A ; [.343F.0020.0002.A13A] # YI SYLLABLE DDIEX +A13B ; [.3440.0020.0002.A13B] # YI SYLLABLE DDIE +A13C ; [.3441.0020.0002.A13C] # YI SYLLABLE DDIEP +A13D ; [.3442.0020.0002.A13D] # YI SYLLABLE DDAT +A13E ; [.3443.0020.0002.A13E] # YI SYLLABLE DDAX +A13F ; [.3444.0020.0002.A13F] # YI SYLLABLE DDA +A140 ; [.3445.0020.0002.A140] # YI SYLLABLE DDAP +A141 ; [.3446.0020.0002.A141] # YI SYLLABLE DDUOX +A142 ; [.3447.0020.0002.A142] # YI SYLLABLE DDUO +A143 ; [.3448.0020.0002.A143] # YI SYLLABLE DDUOP +A144 ; [.3449.0020.0002.A144] # YI SYLLABLE DDOT +A145 ; [.344A.0020.0002.A145] # YI SYLLABLE DDOX +A146 ; [.344B.0020.0002.A146] # YI SYLLABLE DDO +A147 ; [.344C.0020.0002.A147] # YI SYLLABLE DDOP +A148 ; [.344D.0020.0002.A148] # YI SYLLABLE DDEX +A149 ; [.344E.0020.0002.A149] # YI SYLLABLE DDE +A14A ; [.344F.0020.0002.A14A] # YI SYLLABLE DDEP +A14B ; [.3450.0020.0002.A14B] # YI SYLLABLE DDUT +A14C ; [.3451.0020.0002.A14C] # YI SYLLABLE DDUX +A14D ; [.3452.0020.0002.A14D] # YI SYLLABLE DDU +A14E ; [.3453.0020.0002.A14E] # YI SYLLABLE DDUP +A14F ; [.3454.0020.0002.A14F] # YI SYLLABLE DDURX +A150 ; [.3455.0020.0002.A150] # YI SYLLABLE DDUR +A151 ; [.3456.0020.0002.A151] # YI SYLLABLE NDIT +A152 ; [.3457.0020.0002.A152] # YI SYLLABLE NDIX +A153 ; [.3458.0020.0002.A153] # YI SYLLABLE NDI +A154 ; [.3459.0020.0002.A154] # YI SYLLABLE NDIP +A155 ; [.345A.0020.0002.A155] # YI SYLLABLE NDIEX +A156 ; [.345B.0020.0002.A156] # YI SYLLABLE NDIE +A157 ; [.345C.0020.0002.A157] # YI SYLLABLE NDAT +A158 ; [.345D.0020.0002.A158] # YI SYLLABLE NDAX +A159 ; [.345E.0020.0002.A159] # YI SYLLABLE NDA +A15A ; [.345F.0020.0002.A15A] # YI SYLLABLE NDAP +A15B ; [.3460.0020.0002.A15B] # YI SYLLABLE NDOT +A15C ; [.3461.0020.0002.A15C] # YI SYLLABLE NDOX +A15D ; [.3462.0020.0002.A15D] # YI SYLLABLE NDO +A15E ; [.3463.0020.0002.A15E] # YI SYLLABLE NDOP +A15F ; [.3464.0020.0002.A15F] # YI SYLLABLE NDEX +A160 ; [.3465.0020.0002.A160] # YI SYLLABLE NDE +A161 ; [.3466.0020.0002.A161] # YI SYLLABLE NDEP +A162 ; [.3467.0020.0002.A162] # YI SYLLABLE NDUT +A163 ; [.3468.0020.0002.A163] # YI SYLLABLE NDUX +A164 ; [.3469.0020.0002.A164] # YI SYLLABLE NDU +A165 ; [.346A.0020.0002.A165] # YI SYLLABLE NDUP +A166 ; [.346B.0020.0002.A166] # YI SYLLABLE NDURX +A167 ; [.346C.0020.0002.A167] # YI SYLLABLE NDUR +A168 ; [.346D.0020.0002.A168] # YI SYLLABLE HNIT +A169 ; [.346E.0020.0002.A169] # YI SYLLABLE HNIX +A16A ; [.346F.0020.0002.A16A] # YI SYLLABLE HNI +A16B ; [.3470.0020.0002.A16B] # YI SYLLABLE HNIP +A16C ; [.3471.0020.0002.A16C] # YI SYLLABLE HNIET +A16D ; [.3472.0020.0002.A16D] # YI SYLLABLE HNIEX +A16E ; [.3473.0020.0002.A16E] # YI SYLLABLE HNIE +A16F ; [.3474.0020.0002.A16F] # YI SYLLABLE HNIEP +A170 ; [.3475.0020.0002.A170] # YI SYLLABLE HNAT +A171 ; [.3476.0020.0002.A171] # YI SYLLABLE HNAX +A172 ; [.3477.0020.0002.A172] # YI SYLLABLE HNA +A173 ; [.3478.0020.0002.A173] # YI SYLLABLE HNAP +A174 ; [.3479.0020.0002.A174] # YI SYLLABLE HNUOX +A175 ; [.347A.0020.0002.A175] # YI SYLLABLE HNUO +A176 ; [.347B.0020.0002.A176] # YI SYLLABLE HNOT +A177 ; [.347C.0020.0002.A177] # YI SYLLABLE HNOX +A178 ; [.347D.0020.0002.A178] # YI SYLLABLE HNOP +A179 ; [.347E.0020.0002.A179] # YI SYLLABLE HNEX +A17A ; [.347F.0020.0002.A17A] # YI SYLLABLE HNE +A17B ; [.3480.0020.0002.A17B] # YI SYLLABLE HNEP +A17C ; [.3481.0020.0002.A17C] # YI SYLLABLE HNUT +A17D ; [.3482.0020.0002.A17D] # YI SYLLABLE NIT +A17E ; [.3483.0020.0002.A17E] # YI SYLLABLE NIX +A17F ; [.3484.0020.0002.A17F] # YI SYLLABLE NI +A180 ; [.3485.0020.0002.A180] # YI SYLLABLE NIP +A181 ; [.3486.0020.0002.A181] # YI SYLLABLE NIEX +A182 ; [.3487.0020.0002.A182] # YI SYLLABLE NIE +A183 ; [.3488.0020.0002.A183] # YI SYLLABLE NIEP +A184 ; [.3489.0020.0002.A184] # YI SYLLABLE NAX +A185 ; [.348A.0020.0002.A185] # YI SYLLABLE NA +A186 ; [.348B.0020.0002.A186] # YI SYLLABLE NAP +A187 ; [.348C.0020.0002.A187] # YI SYLLABLE NUOX +A188 ; [.348D.0020.0002.A188] # YI SYLLABLE NUO +A189 ; [.348E.0020.0002.A189] # YI SYLLABLE NUOP +A18A ; [.348F.0020.0002.A18A] # YI SYLLABLE NOT +A18B ; [.3490.0020.0002.A18B] # YI SYLLABLE NOX +A18C ; [.3491.0020.0002.A18C] # YI SYLLABLE NO +A18D ; [.3492.0020.0002.A18D] # YI SYLLABLE NOP +A18E ; [.3493.0020.0002.A18E] # YI SYLLABLE NEX +A18F ; [.3494.0020.0002.A18F] # YI SYLLABLE NE +A190 ; [.3495.0020.0002.A190] # YI SYLLABLE NEP +A191 ; [.3496.0020.0002.A191] # YI SYLLABLE NUT +A192 ; [.3497.0020.0002.A192] # YI SYLLABLE NUX +A193 ; [.3498.0020.0002.A193] # YI SYLLABLE NU +A194 ; [.3499.0020.0002.A194] # YI SYLLABLE NUP +A195 ; [.349A.0020.0002.A195] # YI SYLLABLE NURX +A196 ; [.349B.0020.0002.A196] # YI SYLLABLE NUR +A197 ; [.349C.0020.0002.A197] # YI SYLLABLE HLIT +A198 ; [.349D.0020.0002.A198] # YI SYLLABLE HLIX +A199 ; [.349E.0020.0002.A199] # YI SYLLABLE HLI +A19A ; [.349F.0020.0002.A19A] # YI SYLLABLE HLIP +A19B ; [.34A0.0020.0002.A19B] # YI SYLLABLE HLIEX +A19C ; [.34A1.0020.0002.A19C] # YI SYLLABLE HLIE +A19D ; [.34A2.0020.0002.A19D] # YI SYLLABLE HLIEP +A19E ; [.34A3.0020.0002.A19E] # YI SYLLABLE HLAT +A19F ; [.34A4.0020.0002.A19F] # YI SYLLABLE HLAX +A1A0 ; [.34A5.0020.0002.A1A0] # YI SYLLABLE HLA +A1A1 ; [.34A6.0020.0002.A1A1] # YI SYLLABLE HLAP +A1A2 ; [.34A7.0020.0002.A1A2] # YI SYLLABLE HLUOX +A1A3 ; [.34A8.0020.0002.A1A3] # YI SYLLABLE HLUO +A1A4 ; [.34A9.0020.0002.A1A4] # YI SYLLABLE HLUOP +A1A5 ; [.34AA.0020.0002.A1A5] # YI SYLLABLE HLOX +A1A6 ; [.34AB.0020.0002.A1A6] # YI SYLLABLE HLO +A1A7 ; [.34AC.0020.0002.A1A7] # YI SYLLABLE HLOP +A1A8 ; [.34AD.0020.0002.A1A8] # YI SYLLABLE HLEX +A1A9 ; [.34AE.0020.0002.A1A9] # YI SYLLABLE HLE +A1AA ; [.34AF.0020.0002.A1AA] # YI SYLLABLE HLEP +A1AB ; [.34B0.0020.0002.A1AB] # YI SYLLABLE HLUT +A1AC ; [.34B1.0020.0002.A1AC] # YI SYLLABLE HLUX +A1AD ; [.34B2.0020.0002.A1AD] # YI SYLLABLE HLU +A1AE ; [.34B3.0020.0002.A1AE] # YI SYLLABLE HLUP +A1AF ; [.34B4.0020.0002.A1AF] # YI SYLLABLE HLURX +A1B0 ; [.34B5.0020.0002.A1B0] # YI SYLLABLE HLUR +A1B1 ; [.34B6.0020.0002.A1B1] # YI SYLLABLE HLYT +A1B2 ; [.34B7.0020.0002.A1B2] # YI SYLLABLE HLYX +A1B3 ; [.34B8.0020.0002.A1B3] # YI SYLLABLE HLY +A1B4 ; [.34B9.0020.0002.A1B4] # YI SYLLABLE HLYP +A1B5 ; [.34BA.0020.0002.A1B5] # YI SYLLABLE HLYRX +A1B6 ; [.34BB.0020.0002.A1B6] # YI SYLLABLE HLYR +A1B7 ; [.34BC.0020.0002.A1B7] # YI SYLLABLE LIT +A1B8 ; [.34BD.0020.0002.A1B8] # YI SYLLABLE LIX +A1B9 ; [.34BE.0020.0002.A1B9] # YI SYLLABLE LI +A1BA ; [.34BF.0020.0002.A1BA] # YI SYLLABLE LIP +A1BB ; [.34C0.0020.0002.A1BB] # YI SYLLABLE LIET +A1BC ; [.34C1.0020.0002.A1BC] # YI SYLLABLE LIEX +A1BD ; [.34C2.0020.0002.A1BD] # YI SYLLABLE LIE +A1BE ; [.34C3.0020.0002.A1BE] # YI SYLLABLE LIEP +A1BF ; [.34C4.0020.0002.A1BF] # YI SYLLABLE LAT +A1C0 ; [.34C5.0020.0002.A1C0] # YI SYLLABLE LAX +A1C1 ; [.34C6.0020.0002.A1C1] # YI SYLLABLE LA +A1C2 ; [.34C7.0020.0002.A1C2] # YI SYLLABLE LAP +A1C3 ; [.34C8.0020.0002.A1C3] # YI SYLLABLE LUOT +A1C4 ; [.34C9.0020.0002.A1C4] # YI SYLLABLE LUOX +A1C5 ; [.34CA.0020.0002.A1C5] # YI SYLLABLE LUO +A1C6 ; [.34CB.0020.0002.A1C6] # YI SYLLABLE LUOP +A1C7 ; [.34CC.0020.0002.A1C7] # YI SYLLABLE LOT +A1C8 ; [.34CD.0020.0002.A1C8] # YI SYLLABLE LOX +A1C9 ; [.34CE.0020.0002.A1C9] # YI SYLLABLE LO +A1CA ; [.34CF.0020.0002.A1CA] # YI SYLLABLE LOP +A1CB ; [.34D0.0020.0002.A1CB] # YI SYLLABLE LEX +A1CC ; [.34D1.0020.0002.A1CC] # YI SYLLABLE LE +A1CD ; [.34D2.0020.0002.A1CD] # YI SYLLABLE LEP +A1CE ; [.34D3.0020.0002.A1CE] # YI SYLLABLE LUT +A1CF ; [.34D4.0020.0002.A1CF] # YI SYLLABLE LUX +A1D0 ; [.34D5.0020.0002.A1D0] # YI SYLLABLE LU +A1D1 ; [.34D6.0020.0002.A1D1] # YI SYLLABLE LUP +A1D2 ; [.34D7.0020.0002.A1D2] # YI SYLLABLE LURX +A1D3 ; [.34D8.0020.0002.A1D3] # YI SYLLABLE LUR +A1D4 ; [.34D9.0020.0002.A1D4] # YI SYLLABLE LYT +A1D5 ; [.34DA.0020.0002.A1D5] # YI SYLLABLE LYX +A1D6 ; [.34DB.0020.0002.A1D6] # YI SYLLABLE LY +A1D7 ; [.34DC.0020.0002.A1D7] # YI SYLLABLE LYP +A1D8 ; [.34DD.0020.0002.A1D8] # YI SYLLABLE LYRX +A1D9 ; [.34DE.0020.0002.A1D9] # YI SYLLABLE LYR +A1DA ; [.34DF.0020.0002.A1DA] # YI SYLLABLE GIT +A1DB ; [.34E0.0020.0002.A1DB] # YI SYLLABLE GIX +A1DC ; [.34E1.0020.0002.A1DC] # YI SYLLABLE GI +A1DD ; [.34E2.0020.0002.A1DD] # YI SYLLABLE GIP +A1DE ; [.34E3.0020.0002.A1DE] # YI SYLLABLE GIET +A1DF ; [.34E4.0020.0002.A1DF] # YI SYLLABLE GIEX +A1E0 ; [.34E5.0020.0002.A1E0] # YI SYLLABLE GIE +A1E1 ; [.34E6.0020.0002.A1E1] # YI SYLLABLE GIEP +A1E2 ; [.34E7.0020.0002.A1E2] # YI SYLLABLE GAT +A1E3 ; [.34E8.0020.0002.A1E3] # YI SYLLABLE GAX +A1E4 ; [.34E9.0020.0002.A1E4] # YI SYLLABLE GA +A1E5 ; [.34EA.0020.0002.A1E5] # YI SYLLABLE GAP +A1E6 ; [.34EB.0020.0002.A1E6] # YI SYLLABLE GUOT +A1E7 ; [.34EC.0020.0002.A1E7] # YI SYLLABLE GUOX +A1E8 ; [.34ED.0020.0002.A1E8] # YI SYLLABLE GUO +A1E9 ; [.34EE.0020.0002.A1E9] # YI SYLLABLE GUOP +A1EA ; [.34EF.0020.0002.A1EA] # YI SYLLABLE GOT +A1EB ; [.34F0.0020.0002.A1EB] # YI SYLLABLE GOX +A1EC ; [.34F1.0020.0002.A1EC] # YI SYLLABLE GO +A1ED ; [.34F2.0020.0002.A1ED] # YI SYLLABLE GOP +A1EE ; [.34F3.0020.0002.A1EE] # YI SYLLABLE GET +A1EF ; [.34F4.0020.0002.A1EF] # YI SYLLABLE GEX +A1F0 ; [.34F5.0020.0002.A1F0] # YI SYLLABLE GE +A1F1 ; [.34F6.0020.0002.A1F1] # YI SYLLABLE GEP +A1F2 ; [.34F7.0020.0002.A1F2] # YI SYLLABLE GUT +A1F3 ; [.34F8.0020.0002.A1F3] # YI SYLLABLE GUX +A1F4 ; [.34F9.0020.0002.A1F4] # YI SYLLABLE GU +A1F5 ; [.34FA.0020.0002.A1F5] # YI SYLLABLE GUP +A1F6 ; [.34FB.0020.0002.A1F6] # YI SYLLABLE GURX +A1F7 ; [.34FC.0020.0002.A1F7] # YI SYLLABLE GUR +A1F8 ; [.34FD.0020.0002.A1F8] # YI SYLLABLE KIT +A1F9 ; [.34FE.0020.0002.A1F9] # YI SYLLABLE KIX +A1FA ; [.34FF.0020.0002.A1FA] # YI SYLLABLE KI +A1FB ; [.3500.0020.0002.A1FB] # YI SYLLABLE KIP +A1FC ; [.3501.0020.0002.A1FC] # YI SYLLABLE KIEX +A1FD ; [.3502.0020.0002.A1FD] # YI SYLLABLE KIE +A1FE ; [.3503.0020.0002.A1FE] # YI SYLLABLE KIEP +A1FF ; [.3504.0020.0002.A1FF] # YI SYLLABLE KAT +A200 ; [.3505.0020.0002.A200] # YI SYLLABLE KAX +A201 ; [.3506.0020.0002.A201] # YI SYLLABLE KA +A202 ; [.3507.0020.0002.A202] # YI SYLLABLE KAP +A203 ; [.3508.0020.0002.A203] # YI SYLLABLE KUOX +A204 ; [.3509.0020.0002.A204] # YI SYLLABLE KUO +A205 ; [.350A.0020.0002.A205] # YI SYLLABLE KUOP +A206 ; [.350B.0020.0002.A206] # YI SYLLABLE KOT +A207 ; [.350C.0020.0002.A207] # YI SYLLABLE KOX +A208 ; [.350D.0020.0002.A208] # YI SYLLABLE KO +A209 ; [.350E.0020.0002.A209] # YI SYLLABLE KOP +A20A ; [.350F.0020.0002.A20A] # YI SYLLABLE KET +A20B ; [.3510.0020.0002.A20B] # YI SYLLABLE KEX +A20C ; [.3511.0020.0002.A20C] # YI SYLLABLE KE +A20D ; [.3512.0020.0002.A20D] # YI SYLLABLE KEP +A20E ; [.3513.0020.0002.A20E] # YI SYLLABLE KUT +A20F ; [.3514.0020.0002.A20F] # YI SYLLABLE KUX +A210 ; [.3515.0020.0002.A210] # YI SYLLABLE KU +A211 ; [.3516.0020.0002.A211] # YI SYLLABLE KUP +A212 ; [.3517.0020.0002.A212] # YI SYLLABLE KURX +A213 ; [.3518.0020.0002.A213] # YI SYLLABLE KUR +A214 ; [.3519.0020.0002.A214] # YI SYLLABLE GGIT +A215 ; [.351A.0020.0002.A215] # YI SYLLABLE GGIX +A216 ; [.351B.0020.0002.A216] # YI SYLLABLE GGI +A217 ; [.351C.0020.0002.A217] # YI SYLLABLE GGIEX +A218 ; [.351D.0020.0002.A218] # YI SYLLABLE GGIE +A219 ; [.351E.0020.0002.A219] # YI SYLLABLE GGIEP +A21A ; [.351F.0020.0002.A21A] # YI SYLLABLE GGAT +A21B ; [.3520.0020.0002.A21B] # YI SYLLABLE GGAX +A21C ; [.3521.0020.0002.A21C] # YI SYLLABLE GGA +A21D ; [.3522.0020.0002.A21D] # YI SYLLABLE GGAP +A21E ; [.3523.0020.0002.A21E] # YI SYLLABLE GGUOT +A21F ; [.3524.0020.0002.A21F] # YI SYLLABLE GGUOX +A220 ; [.3525.0020.0002.A220] # YI SYLLABLE GGUO +A221 ; [.3526.0020.0002.A221] # YI SYLLABLE GGUOP +A222 ; [.3527.0020.0002.A222] # YI SYLLABLE GGOT +A223 ; [.3528.0020.0002.A223] # YI SYLLABLE GGOX +A224 ; [.3529.0020.0002.A224] # YI SYLLABLE GGO +A225 ; [.352A.0020.0002.A225] # YI SYLLABLE GGOP +A226 ; [.352B.0020.0002.A226] # YI SYLLABLE GGET +A227 ; [.352C.0020.0002.A227] # YI SYLLABLE GGEX +A228 ; [.352D.0020.0002.A228] # YI SYLLABLE GGE +A229 ; [.352E.0020.0002.A229] # YI SYLLABLE GGEP +A22A ; [.352F.0020.0002.A22A] # YI SYLLABLE GGUT +A22B ; [.3530.0020.0002.A22B] # YI SYLLABLE GGUX +A22C ; [.3531.0020.0002.A22C] # YI SYLLABLE GGU +A22D ; [.3532.0020.0002.A22D] # YI SYLLABLE GGUP +A22E ; [.3533.0020.0002.A22E] # YI SYLLABLE GGURX +A22F ; [.3534.0020.0002.A22F] # YI SYLLABLE GGUR +A230 ; [.3535.0020.0002.A230] # YI SYLLABLE MGIEX +A231 ; [.3536.0020.0002.A231] # YI SYLLABLE MGIE +A232 ; [.3537.0020.0002.A232] # YI SYLLABLE MGAT +A233 ; [.3538.0020.0002.A233] # YI SYLLABLE MGAX +A234 ; [.3539.0020.0002.A234] # YI SYLLABLE MGA +A235 ; [.353A.0020.0002.A235] # YI SYLLABLE MGAP +A236 ; [.353B.0020.0002.A236] # YI SYLLABLE MGUOX +A237 ; [.353C.0020.0002.A237] # YI SYLLABLE MGUO +A238 ; [.353D.0020.0002.A238] # YI SYLLABLE MGUOP +A239 ; [.353E.0020.0002.A239] # YI SYLLABLE MGOT +A23A ; [.353F.0020.0002.A23A] # YI SYLLABLE MGOX +A23B ; [.3540.0020.0002.A23B] # YI SYLLABLE MGO +A23C ; [.3541.0020.0002.A23C] # YI SYLLABLE MGOP +A23D ; [.3542.0020.0002.A23D] # YI SYLLABLE MGEX +A23E ; [.3543.0020.0002.A23E] # YI SYLLABLE MGE +A23F ; [.3544.0020.0002.A23F] # YI SYLLABLE MGEP +A240 ; [.3545.0020.0002.A240] # YI SYLLABLE MGUT +A241 ; [.3546.0020.0002.A241] # YI SYLLABLE MGUX +A242 ; [.3547.0020.0002.A242] # YI SYLLABLE MGU +A243 ; [.3548.0020.0002.A243] # YI SYLLABLE MGUP +A244 ; [.3549.0020.0002.A244] # YI SYLLABLE MGURX +A245 ; [.354A.0020.0002.A245] # YI SYLLABLE MGUR +A246 ; [.354B.0020.0002.A246] # YI SYLLABLE HXIT +A247 ; [.354C.0020.0002.A247] # YI SYLLABLE HXIX +A248 ; [.354D.0020.0002.A248] # YI SYLLABLE HXI +A249 ; [.354E.0020.0002.A249] # YI SYLLABLE HXIP +A24A ; [.354F.0020.0002.A24A] # YI SYLLABLE HXIET +A24B ; [.3550.0020.0002.A24B] # YI SYLLABLE HXIEX +A24C ; [.3551.0020.0002.A24C] # YI SYLLABLE HXIE +A24D ; [.3552.0020.0002.A24D] # YI SYLLABLE HXIEP +A24E ; [.3553.0020.0002.A24E] # YI SYLLABLE HXAT +A24F ; [.3554.0020.0002.A24F] # YI SYLLABLE HXAX +A250 ; [.3555.0020.0002.A250] # YI SYLLABLE HXA +A251 ; [.3556.0020.0002.A251] # YI SYLLABLE HXAP +A252 ; [.3557.0020.0002.A252] # YI SYLLABLE HXUOT +A253 ; [.3558.0020.0002.A253] # YI SYLLABLE HXUOX +A254 ; [.3559.0020.0002.A254] # YI SYLLABLE HXUO +A255 ; [.355A.0020.0002.A255] # YI SYLLABLE HXUOP +A256 ; [.355B.0020.0002.A256] # YI SYLLABLE HXOT +A257 ; [.355C.0020.0002.A257] # YI SYLLABLE HXOX +A258 ; [.355D.0020.0002.A258] # YI SYLLABLE HXO +A259 ; [.355E.0020.0002.A259] # YI SYLLABLE HXOP +A25A ; [.355F.0020.0002.A25A] # YI SYLLABLE HXEX +A25B ; [.3560.0020.0002.A25B] # YI SYLLABLE HXE +A25C ; [.3561.0020.0002.A25C] # YI SYLLABLE HXEP +A25D ; [.3562.0020.0002.A25D] # YI SYLLABLE NGIEX +A25E ; [.3563.0020.0002.A25E] # YI SYLLABLE NGIE +A25F ; [.3564.0020.0002.A25F] # YI SYLLABLE NGIEP +A260 ; [.3565.0020.0002.A260] # YI SYLLABLE NGAT +A261 ; [.3566.0020.0002.A261] # YI SYLLABLE NGAX +A262 ; [.3567.0020.0002.A262] # YI SYLLABLE NGA +A263 ; [.3568.0020.0002.A263] # YI SYLLABLE NGAP +A264 ; [.3569.0020.0002.A264] # YI SYLLABLE NGUOT +A265 ; [.356A.0020.0002.A265] # YI SYLLABLE NGUOX +A266 ; [.356B.0020.0002.A266] # YI SYLLABLE NGUO +A267 ; [.356C.0020.0002.A267] # YI SYLLABLE NGOT +A268 ; [.356D.0020.0002.A268] # YI SYLLABLE NGOX +A269 ; [.356E.0020.0002.A269] # YI SYLLABLE NGO +A26A ; [.356F.0020.0002.A26A] # YI SYLLABLE NGOP +A26B ; [.3570.0020.0002.A26B] # YI SYLLABLE NGEX +A26C ; [.3571.0020.0002.A26C] # YI SYLLABLE NGE +A26D ; [.3572.0020.0002.A26D] # YI SYLLABLE NGEP +A26E ; [.3573.0020.0002.A26E] # YI SYLLABLE HIT +A26F ; [.3574.0020.0002.A26F] # YI SYLLABLE HIEX +A270 ; [.3575.0020.0002.A270] # YI SYLLABLE HIE +A271 ; [.3576.0020.0002.A271] # YI SYLLABLE HAT +A272 ; [.3577.0020.0002.A272] # YI SYLLABLE HAX +A273 ; [.3578.0020.0002.A273] # YI SYLLABLE HA +A274 ; [.3579.0020.0002.A274] # YI SYLLABLE HAP +A275 ; [.357A.0020.0002.A275] # YI SYLLABLE HUOT +A276 ; [.357B.0020.0002.A276] # YI SYLLABLE HUOX +A277 ; [.357C.0020.0002.A277] # YI SYLLABLE HUO +A278 ; [.357D.0020.0002.A278] # YI SYLLABLE HUOP +A279 ; [.357E.0020.0002.A279] # YI SYLLABLE HOT +A27A ; [.357F.0020.0002.A27A] # YI SYLLABLE HOX +A27B ; [.3580.0020.0002.A27B] # YI SYLLABLE HO +A27C ; [.3581.0020.0002.A27C] # YI SYLLABLE HOP +A27D ; [.3582.0020.0002.A27D] # YI SYLLABLE HEX +A27E ; [.3583.0020.0002.A27E] # YI SYLLABLE HE +A27F ; [.3584.0020.0002.A27F] # YI SYLLABLE HEP +A280 ; [.3585.0020.0002.A280] # YI SYLLABLE WAT +A281 ; [.3586.0020.0002.A281] # YI SYLLABLE WAX +A282 ; [.3587.0020.0002.A282] # YI SYLLABLE WA +A283 ; [.3588.0020.0002.A283] # YI SYLLABLE WAP +A284 ; [.3589.0020.0002.A284] # YI SYLLABLE WUOX +A285 ; [.358A.0020.0002.A285] # YI SYLLABLE WUO +A286 ; [.358B.0020.0002.A286] # YI SYLLABLE WUOP +A287 ; [.358C.0020.0002.A287] # YI SYLLABLE WOX +A288 ; [.358D.0020.0002.A288] # YI SYLLABLE WO +A289 ; [.358E.0020.0002.A289] # YI SYLLABLE WOP +A28A ; [.358F.0020.0002.A28A] # YI SYLLABLE WEX +A28B ; [.3590.0020.0002.A28B] # YI SYLLABLE WE +A28C ; [.3591.0020.0002.A28C] # YI SYLLABLE WEP +A28D ; [.3592.0020.0002.A28D] # YI SYLLABLE ZIT +A28E ; [.3593.0020.0002.A28E] # YI SYLLABLE ZIX +A28F ; [.3594.0020.0002.A28F] # YI SYLLABLE ZI +A290 ; [.3595.0020.0002.A290] # YI SYLLABLE ZIP +A291 ; [.3596.0020.0002.A291] # YI SYLLABLE ZIEX +A292 ; [.3597.0020.0002.A292] # YI SYLLABLE ZIE +A293 ; [.3598.0020.0002.A293] # YI SYLLABLE ZIEP +A294 ; [.3599.0020.0002.A294] # YI SYLLABLE ZAT +A295 ; [.359A.0020.0002.A295] # YI SYLLABLE ZAX +A296 ; [.359B.0020.0002.A296] # YI SYLLABLE ZA +A297 ; [.359C.0020.0002.A297] # YI SYLLABLE ZAP +A298 ; [.359D.0020.0002.A298] # YI SYLLABLE ZUOX +A299 ; [.359E.0020.0002.A299] # YI SYLLABLE ZUO +A29A ; [.359F.0020.0002.A29A] # YI SYLLABLE ZUOP +A29B ; [.35A0.0020.0002.A29B] # YI SYLLABLE ZOT +A29C ; [.35A1.0020.0002.A29C] # YI SYLLABLE ZOX +A29D ; [.35A2.0020.0002.A29D] # YI SYLLABLE ZO +A29E ; [.35A3.0020.0002.A29E] # YI SYLLABLE ZOP +A29F ; [.35A4.0020.0002.A29F] # YI SYLLABLE ZEX +A2A0 ; [.35A5.0020.0002.A2A0] # YI SYLLABLE ZE +A2A1 ; [.35A6.0020.0002.A2A1] # YI SYLLABLE ZEP +A2A2 ; [.35A7.0020.0002.A2A2] # YI SYLLABLE ZUT +A2A3 ; [.35A8.0020.0002.A2A3] # YI SYLLABLE ZUX +A2A4 ; [.35A9.0020.0002.A2A4] # YI SYLLABLE ZU +A2A5 ; [.35AA.0020.0002.A2A5] # YI SYLLABLE ZUP +A2A6 ; [.35AB.0020.0002.A2A6] # YI SYLLABLE ZURX +A2A7 ; [.35AC.0020.0002.A2A7] # YI SYLLABLE ZUR +A2A8 ; [.35AD.0020.0002.A2A8] # YI SYLLABLE ZYT +A2A9 ; [.35AE.0020.0002.A2A9] # YI SYLLABLE ZYX +A2AA ; [.35AF.0020.0002.A2AA] # YI SYLLABLE ZY +A2AB ; [.35B0.0020.0002.A2AB] # YI SYLLABLE ZYP +A2AC ; [.35B1.0020.0002.A2AC] # YI SYLLABLE ZYRX +A2AD ; [.35B2.0020.0002.A2AD] # YI SYLLABLE ZYR +A2AE ; [.35B3.0020.0002.A2AE] # YI SYLLABLE CIT +A2AF ; [.35B4.0020.0002.A2AF] # YI SYLLABLE CIX +A2B0 ; [.35B5.0020.0002.A2B0] # YI SYLLABLE CI +A2B1 ; [.35B6.0020.0002.A2B1] # YI SYLLABLE CIP +A2B2 ; [.35B7.0020.0002.A2B2] # YI SYLLABLE CIET +A2B3 ; [.35B8.0020.0002.A2B3] # YI SYLLABLE CIEX +A2B4 ; [.35B9.0020.0002.A2B4] # YI SYLLABLE CIE +A2B5 ; [.35BA.0020.0002.A2B5] # YI SYLLABLE CIEP +A2B6 ; [.35BB.0020.0002.A2B6] # YI SYLLABLE CAT +A2B7 ; [.35BC.0020.0002.A2B7] # YI SYLLABLE CAX +A2B8 ; [.35BD.0020.0002.A2B8] # YI SYLLABLE CA +A2B9 ; [.35BE.0020.0002.A2B9] # YI SYLLABLE CAP +A2BA ; [.35BF.0020.0002.A2BA] # YI SYLLABLE CUOX +A2BB ; [.35C0.0020.0002.A2BB] # YI SYLLABLE CUO +A2BC ; [.35C1.0020.0002.A2BC] # YI SYLLABLE CUOP +A2BD ; [.35C2.0020.0002.A2BD] # YI SYLLABLE COT +A2BE ; [.35C3.0020.0002.A2BE] # YI SYLLABLE COX +A2BF ; [.35C4.0020.0002.A2BF] # YI SYLLABLE CO +A2C0 ; [.35C5.0020.0002.A2C0] # YI SYLLABLE COP +A2C1 ; [.35C6.0020.0002.A2C1] # YI SYLLABLE CEX +A2C2 ; [.35C7.0020.0002.A2C2] # YI SYLLABLE CE +A2C3 ; [.35C8.0020.0002.A2C3] # YI SYLLABLE CEP +A2C4 ; [.35C9.0020.0002.A2C4] # YI SYLLABLE CUT +A2C5 ; [.35CA.0020.0002.A2C5] # YI SYLLABLE CUX +A2C6 ; [.35CB.0020.0002.A2C6] # YI SYLLABLE CU +A2C7 ; [.35CC.0020.0002.A2C7] # YI SYLLABLE CUP +A2C8 ; [.35CD.0020.0002.A2C8] # YI SYLLABLE CURX +A2C9 ; [.35CE.0020.0002.A2C9] # YI SYLLABLE CUR +A2CA ; [.35CF.0020.0002.A2CA] # YI SYLLABLE CYT +A2CB ; [.35D0.0020.0002.A2CB] # YI SYLLABLE CYX +A2CC ; [.35D1.0020.0002.A2CC] # YI SYLLABLE CY +A2CD ; [.35D2.0020.0002.A2CD] # YI SYLLABLE CYP +A2CE ; [.35D3.0020.0002.A2CE] # YI SYLLABLE CYRX +A2CF ; [.35D4.0020.0002.A2CF] # YI SYLLABLE CYR +A2D0 ; [.35D5.0020.0002.A2D0] # YI SYLLABLE ZZIT +A2D1 ; [.35D6.0020.0002.A2D1] # YI SYLLABLE ZZIX +A2D2 ; [.35D7.0020.0002.A2D2] # YI SYLLABLE ZZI +A2D3 ; [.35D8.0020.0002.A2D3] # YI SYLLABLE ZZIP +A2D4 ; [.35D9.0020.0002.A2D4] # YI SYLLABLE ZZIET +A2D5 ; [.35DA.0020.0002.A2D5] # YI SYLLABLE ZZIEX +A2D6 ; [.35DB.0020.0002.A2D6] # YI SYLLABLE ZZIE +A2D7 ; [.35DC.0020.0002.A2D7] # YI SYLLABLE ZZIEP +A2D8 ; [.35DD.0020.0002.A2D8] # YI SYLLABLE ZZAT +A2D9 ; [.35DE.0020.0002.A2D9] # YI SYLLABLE ZZAX +A2DA ; [.35DF.0020.0002.A2DA] # YI SYLLABLE ZZA +A2DB ; [.35E0.0020.0002.A2DB] # YI SYLLABLE ZZAP +A2DC ; [.35E1.0020.0002.A2DC] # YI SYLLABLE ZZOX +A2DD ; [.35E2.0020.0002.A2DD] # YI SYLLABLE ZZO +A2DE ; [.35E3.0020.0002.A2DE] # YI SYLLABLE ZZOP +A2DF ; [.35E4.0020.0002.A2DF] # YI SYLLABLE ZZEX +A2E0 ; [.35E5.0020.0002.A2E0] # YI SYLLABLE ZZE +A2E1 ; [.35E6.0020.0002.A2E1] # YI SYLLABLE ZZEP +A2E2 ; [.35E7.0020.0002.A2E2] # YI SYLLABLE ZZUX +A2E3 ; [.35E8.0020.0002.A2E3] # YI SYLLABLE ZZU +A2E4 ; [.35E9.0020.0002.A2E4] # YI SYLLABLE ZZUP +A2E5 ; [.35EA.0020.0002.A2E5] # YI SYLLABLE ZZURX +A2E6 ; [.35EB.0020.0002.A2E6] # YI SYLLABLE ZZUR +A2E7 ; [.35EC.0020.0002.A2E7] # YI SYLLABLE ZZYT +A2E8 ; [.35ED.0020.0002.A2E8] # YI SYLLABLE ZZYX +A2E9 ; [.35EE.0020.0002.A2E9] # YI SYLLABLE ZZY +A2EA ; [.35EF.0020.0002.A2EA] # YI SYLLABLE ZZYP +A2EB ; [.35F0.0020.0002.A2EB] # YI SYLLABLE ZZYRX +A2EC ; [.35F1.0020.0002.A2EC] # YI SYLLABLE ZZYR +A2ED ; [.35F2.0020.0002.A2ED] # YI SYLLABLE NZIT +A2EE ; [.35F3.0020.0002.A2EE] # YI SYLLABLE NZIX +A2EF ; [.35F4.0020.0002.A2EF] # YI SYLLABLE NZI +A2F0 ; [.35F5.0020.0002.A2F0] # YI SYLLABLE NZIP +A2F1 ; [.35F6.0020.0002.A2F1] # YI SYLLABLE NZIEX +A2F2 ; [.35F7.0020.0002.A2F2] # YI SYLLABLE NZIE +A2F3 ; [.35F8.0020.0002.A2F3] # YI SYLLABLE NZIEP +A2F4 ; [.35F9.0020.0002.A2F4] # YI SYLLABLE NZAT +A2F5 ; [.35FA.0020.0002.A2F5] # YI SYLLABLE NZAX +A2F6 ; [.35FB.0020.0002.A2F6] # YI SYLLABLE NZA +A2F7 ; [.35FC.0020.0002.A2F7] # YI SYLLABLE NZAP +A2F8 ; [.35FD.0020.0002.A2F8] # YI SYLLABLE NZUOX +A2F9 ; [.35FE.0020.0002.A2F9] # YI SYLLABLE NZUO +A2FA ; [.35FF.0020.0002.A2FA] # YI SYLLABLE NZOX +A2FB ; [.3600.0020.0002.A2FB] # YI SYLLABLE NZOP +A2FC ; [.3601.0020.0002.A2FC] # YI SYLLABLE NZEX +A2FD ; [.3602.0020.0002.A2FD] # YI SYLLABLE NZE +A2FE ; [.3603.0020.0002.A2FE] # YI SYLLABLE NZUX +A2FF ; [.3604.0020.0002.A2FF] # YI SYLLABLE NZU +A300 ; [.3605.0020.0002.A300] # YI SYLLABLE NZUP +A301 ; [.3606.0020.0002.A301] # YI SYLLABLE NZURX +A302 ; [.3607.0020.0002.A302] # YI SYLLABLE NZUR +A303 ; [.3608.0020.0002.A303] # YI SYLLABLE NZYT +A304 ; [.3609.0020.0002.A304] # YI SYLLABLE NZYX +A305 ; [.360A.0020.0002.A305] # YI SYLLABLE NZY +A306 ; [.360B.0020.0002.A306] # YI SYLLABLE NZYP +A307 ; [.360C.0020.0002.A307] # YI SYLLABLE NZYRX +A308 ; [.360D.0020.0002.A308] # YI SYLLABLE NZYR +A309 ; [.360E.0020.0002.A309] # YI SYLLABLE SIT +A30A ; [.360F.0020.0002.A30A] # YI SYLLABLE SIX +A30B ; [.3610.0020.0002.A30B] # YI SYLLABLE SI +A30C ; [.3611.0020.0002.A30C] # YI SYLLABLE SIP +A30D ; [.3612.0020.0002.A30D] # YI SYLLABLE SIEX +A30E ; [.3613.0020.0002.A30E] # YI SYLLABLE SIE +A30F ; [.3614.0020.0002.A30F] # YI SYLLABLE SIEP +A310 ; [.3615.0020.0002.A310] # YI SYLLABLE SAT +A311 ; [.3616.0020.0002.A311] # YI SYLLABLE SAX +A312 ; [.3617.0020.0002.A312] # YI SYLLABLE SA +A313 ; [.3618.0020.0002.A313] # YI SYLLABLE SAP +A314 ; [.3619.0020.0002.A314] # YI SYLLABLE SUOX +A315 ; [.361A.0020.0002.A315] # YI SYLLABLE SUO +A316 ; [.361B.0020.0002.A316] # YI SYLLABLE SUOP +A317 ; [.361C.0020.0002.A317] # YI SYLLABLE SOT +A318 ; [.361D.0020.0002.A318] # YI SYLLABLE SOX +A319 ; [.361E.0020.0002.A319] # YI SYLLABLE SO +A31A ; [.361F.0020.0002.A31A] # YI SYLLABLE SOP +A31B ; [.3620.0020.0002.A31B] # YI SYLLABLE SEX +A31C ; [.3621.0020.0002.A31C] # YI SYLLABLE SE +A31D ; [.3622.0020.0002.A31D] # YI SYLLABLE SEP +A31E ; [.3623.0020.0002.A31E] # YI SYLLABLE SUT +A31F ; [.3624.0020.0002.A31F] # YI SYLLABLE SUX +A320 ; [.3625.0020.0002.A320] # YI SYLLABLE SU +A321 ; [.3626.0020.0002.A321] # YI SYLLABLE SUP +A322 ; [.3627.0020.0002.A322] # YI SYLLABLE SURX +A323 ; [.3628.0020.0002.A323] # YI SYLLABLE SUR +A324 ; [.3629.0020.0002.A324] # YI SYLLABLE SYT +A325 ; [.362A.0020.0002.A325] # YI SYLLABLE SYX +A326 ; [.362B.0020.0002.A326] # YI SYLLABLE SY +A327 ; [.362C.0020.0002.A327] # YI SYLLABLE SYP +A328 ; [.362D.0020.0002.A328] # YI SYLLABLE SYRX +A329 ; [.362E.0020.0002.A329] # YI SYLLABLE SYR +A32A ; [.362F.0020.0002.A32A] # YI SYLLABLE SSIT +A32B ; [.3630.0020.0002.A32B] # YI SYLLABLE SSIX +A32C ; [.3631.0020.0002.A32C] # YI SYLLABLE SSI +A32D ; [.3632.0020.0002.A32D] # YI SYLLABLE SSIP +A32E ; [.3633.0020.0002.A32E] # YI SYLLABLE SSIEX +A32F ; [.3634.0020.0002.A32F] # YI SYLLABLE SSIE +A330 ; [.3635.0020.0002.A330] # YI SYLLABLE SSIEP +A331 ; [.3636.0020.0002.A331] # YI SYLLABLE SSAT +A332 ; [.3637.0020.0002.A332] # YI SYLLABLE SSAX +A333 ; [.3638.0020.0002.A333] # YI SYLLABLE SSA +A334 ; [.3639.0020.0002.A334] # YI SYLLABLE SSAP +A335 ; [.363A.0020.0002.A335] # YI SYLLABLE SSOT +A336 ; [.363B.0020.0002.A336] # YI SYLLABLE SSOX +A337 ; [.363C.0020.0002.A337] # YI SYLLABLE SSO +A338 ; [.363D.0020.0002.A338] # YI SYLLABLE SSOP +A339 ; [.363E.0020.0002.A339] # YI SYLLABLE SSEX +A33A ; [.363F.0020.0002.A33A] # YI SYLLABLE SSE +A33B ; [.3640.0020.0002.A33B] # YI SYLLABLE SSEP +A33C ; [.3641.0020.0002.A33C] # YI SYLLABLE SSUT +A33D ; [.3642.0020.0002.A33D] # YI SYLLABLE SSUX +A33E ; [.3643.0020.0002.A33E] # YI SYLLABLE SSU +A33F ; [.3644.0020.0002.A33F] # YI SYLLABLE SSUP +A340 ; [.3645.0020.0002.A340] # YI SYLLABLE SSYT +A341 ; [.3646.0020.0002.A341] # YI SYLLABLE SSYX +A342 ; [.3647.0020.0002.A342] # YI SYLLABLE SSY +A343 ; [.3648.0020.0002.A343] # YI SYLLABLE SSYP +A344 ; [.3649.0020.0002.A344] # YI SYLLABLE SSYRX +A345 ; [.364A.0020.0002.A345] # YI SYLLABLE SSYR +A346 ; [.364B.0020.0002.A346] # YI SYLLABLE ZHAT +A347 ; [.364C.0020.0002.A347] # YI SYLLABLE ZHAX +A348 ; [.364D.0020.0002.A348] # YI SYLLABLE ZHA +A349 ; [.364E.0020.0002.A349] # YI SYLLABLE ZHAP +A34A ; [.364F.0020.0002.A34A] # YI SYLLABLE ZHUOX +A34B ; [.3650.0020.0002.A34B] # YI SYLLABLE ZHUO +A34C ; [.3651.0020.0002.A34C] # YI SYLLABLE ZHUOP +A34D ; [.3652.0020.0002.A34D] # YI SYLLABLE ZHOT +A34E ; [.3653.0020.0002.A34E] # YI SYLLABLE ZHOX +A34F ; [.3654.0020.0002.A34F] # YI SYLLABLE ZHO +A350 ; [.3655.0020.0002.A350] # YI SYLLABLE ZHOP +A351 ; [.3656.0020.0002.A351] # YI SYLLABLE ZHET +A352 ; [.3657.0020.0002.A352] # YI SYLLABLE ZHEX +A353 ; [.3658.0020.0002.A353] # YI SYLLABLE ZHE +A354 ; [.3659.0020.0002.A354] # YI SYLLABLE ZHEP +A355 ; [.365A.0020.0002.A355] # YI SYLLABLE ZHUT +A356 ; [.365B.0020.0002.A356] # YI SYLLABLE ZHUX +A357 ; [.365C.0020.0002.A357] # YI SYLLABLE ZHU +A358 ; [.365D.0020.0002.A358] # YI SYLLABLE ZHUP +A359 ; [.365E.0020.0002.A359] # YI SYLLABLE ZHURX +A35A ; [.365F.0020.0002.A35A] # YI SYLLABLE ZHUR +A35B ; [.3660.0020.0002.A35B] # YI SYLLABLE ZHYT +A35C ; [.3661.0020.0002.A35C] # YI SYLLABLE ZHYX +A35D ; [.3662.0020.0002.A35D] # YI SYLLABLE ZHY +A35E ; [.3663.0020.0002.A35E] # YI SYLLABLE ZHYP +A35F ; [.3664.0020.0002.A35F] # YI SYLLABLE ZHYRX +A360 ; [.3665.0020.0002.A360] # YI SYLLABLE ZHYR +A361 ; [.3666.0020.0002.A361] # YI SYLLABLE CHAT +A362 ; [.3667.0020.0002.A362] # YI SYLLABLE CHAX +A363 ; [.3668.0020.0002.A363] # YI SYLLABLE CHA +A364 ; [.3669.0020.0002.A364] # YI SYLLABLE CHAP +A365 ; [.366A.0020.0002.A365] # YI SYLLABLE CHUOT +A366 ; [.366B.0020.0002.A366] # YI SYLLABLE CHUOX +A367 ; [.366C.0020.0002.A367] # YI SYLLABLE CHUO +A368 ; [.366D.0020.0002.A368] # YI SYLLABLE CHUOP +A369 ; [.366E.0020.0002.A369] # YI SYLLABLE CHOT +A36A ; [.366F.0020.0002.A36A] # YI SYLLABLE CHOX +A36B ; [.3670.0020.0002.A36B] # YI SYLLABLE CHO +A36C ; [.3671.0020.0002.A36C] # YI SYLLABLE CHOP +A36D ; [.3672.0020.0002.A36D] # YI SYLLABLE CHET +A36E ; [.3673.0020.0002.A36E] # YI SYLLABLE CHEX +A36F ; [.3674.0020.0002.A36F] # YI SYLLABLE CHE +A370 ; [.3675.0020.0002.A370] # YI SYLLABLE CHEP +A371 ; [.3676.0020.0002.A371] # YI SYLLABLE CHUX +A372 ; [.3677.0020.0002.A372] # YI SYLLABLE CHU +A373 ; [.3678.0020.0002.A373] # YI SYLLABLE CHUP +A374 ; [.3679.0020.0002.A374] # YI SYLLABLE CHURX +A375 ; [.367A.0020.0002.A375] # YI SYLLABLE CHUR +A376 ; [.367B.0020.0002.A376] # YI SYLLABLE CHYT +A377 ; [.367C.0020.0002.A377] # YI SYLLABLE CHYX +A378 ; [.367D.0020.0002.A378] # YI SYLLABLE CHY +A379 ; [.367E.0020.0002.A379] # YI SYLLABLE CHYP +A37A ; [.367F.0020.0002.A37A] # YI SYLLABLE CHYRX +A37B ; [.3680.0020.0002.A37B] # YI SYLLABLE CHYR +A37C ; [.3681.0020.0002.A37C] # YI SYLLABLE RRAX +A37D ; [.3682.0020.0002.A37D] # YI SYLLABLE RRA +A37E ; [.3683.0020.0002.A37E] # YI SYLLABLE RRUOX +A37F ; [.3684.0020.0002.A37F] # YI SYLLABLE RRUO +A380 ; [.3685.0020.0002.A380] # YI SYLLABLE RROT +A381 ; [.3686.0020.0002.A381] # YI SYLLABLE RROX +A382 ; [.3687.0020.0002.A382] # YI SYLLABLE RRO +A383 ; [.3688.0020.0002.A383] # YI SYLLABLE RROP +A384 ; [.3689.0020.0002.A384] # YI SYLLABLE RRET +A385 ; [.368A.0020.0002.A385] # YI SYLLABLE RREX +A386 ; [.368B.0020.0002.A386] # YI SYLLABLE RRE +A387 ; [.368C.0020.0002.A387] # YI SYLLABLE RREP +A388 ; [.368D.0020.0002.A388] # YI SYLLABLE RRUT +A389 ; [.368E.0020.0002.A389] # YI SYLLABLE RRUX +A38A ; [.368F.0020.0002.A38A] # YI SYLLABLE RRU +A38B ; [.3690.0020.0002.A38B] # YI SYLLABLE RRUP +A38C ; [.3691.0020.0002.A38C] # YI SYLLABLE RRURX +A38D ; [.3692.0020.0002.A38D] # YI SYLLABLE RRUR +A38E ; [.3693.0020.0002.A38E] # YI SYLLABLE RRYT +A38F ; [.3694.0020.0002.A38F] # YI SYLLABLE RRYX +A390 ; [.3695.0020.0002.A390] # YI SYLLABLE RRY +A391 ; [.3696.0020.0002.A391] # YI SYLLABLE RRYP +A392 ; [.3697.0020.0002.A392] # YI SYLLABLE RRYRX +A393 ; [.3698.0020.0002.A393] # YI SYLLABLE RRYR +A394 ; [.3699.0020.0002.A394] # YI SYLLABLE NRAT +A395 ; [.369A.0020.0002.A395] # YI SYLLABLE NRAX +A396 ; [.369B.0020.0002.A396] # YI SYLLABLE NRA +A397 ; [.369C.0020.0002.A397] # YI SYLLABLE NRAP +A398 ; [.369D.0020.0002.A398] # YI SYLLABLE NROX +A399 ; [.369E.0020.0002.A399] # YI SYLLABLE NRO +A39A ; [.369F.0020.0002.A39A] # YI SYLLABLE NROP +A39B ; [.36A0.0020.0002.A39B] # YI SYLLABLE NRET +A39C ; [.36A1.0020.0002.A39C] # YI SYLLABLE NREX +A39D ; [.36A2.0020.0002.A39D] # YI SYLLABLE NRE +A39E ; [.36A3.0020.0002.A39E] # YI SYLLABLE NREP +A39F ; [.36A4.0020.0002.A39F] # YI SYLLABLE NRUT +A3A0 ; [.36A5.0020.0002.A3A0] # YI SYLLABLE NRUX +A3A1 ; [.36A6.0020.0002.A3A1] # YI SYLLABLE NRU +A3A2 ; [.36A7.0020.0002.A3A2] # YI SYLLABLE NRUP +A3A3 ; [.36A8.0020.0002.A3A3] # YI SYLLABLE NRURX +A3A4 ; [.36A9.0020.0002.A3A4] # YI SYLLABLE NRUR +A3A5 ; [.36AA.0020.0002.A3A5] # YI SYLLABLE NRYT +A3A6 ; [.36AB.0020.0002.A3A6] # YI SYLLABLE NRYX +A3A7 ; [.36AC.0020.0002.A3A7] # YI SYLLABLE NRY +A3A8 ; [.36AD.0020.0002.A3A8] # YI SYLLABLE NRYP +A3A9 ; [.36AE.0020.0002.A3A9] # YI SYLLABLE NRYRX +A3AA ; [.36AF.0020.0002.A3AA] # YI SYLLABLE NRYR +A3AB ; [.36B0.0020.0002.A3AB] # YI SYLLABLE SHAT +A3AC ; [.36B1.0020.0002.A3AC] # YI SYLLABLE SHAX +A3AD ; [.36B2.0020.0002.A3AD] # YI SYLLABLE SHA +A3AE ; [.36B3.0020.0002.A3AE] # YI SYLLABLE SHAP +A3AF ; [.36B4.0020.0002.A3AF] # YI SYLLABLE SHUOX +A3B0 ; [.36B5.0020.0002.A3B0] # YI SYLLABLE SHUO +A3B1 ; [.36B6.0020.0002.A3B1] # YI SYLLABLE SHUOP +A3B2 ; [.36B7.0020.0002.A3B2] # YI SYLLABLE SHOT +A3B3 ; [.36B8.0020.0002.A3B3] # YI SYLLABLE SHOX +A3B4 ; [.36B9.0020.0002.A3B4] # YI SYLLABLE SHO +A3B5 ; [.36BA.0020.0002.A3B5] # YI SYLLABLE SHOP +A3B6 ; [.36BB.0020.0002.A3B6] # YI SYLLABLE SHET +A3B7 ; [.36BC.0020.0002.A3B7] # YI SYLLABLE SHEX +A3B8 ; [.36BD.0020.0002.A3B8] # YI SYLLABLE SHE +A3B9 ; [.36BE.0020.0002.A3B9] # YI SYLLABLE SHEP +A3BA ; [.36BF.0020.0002.A3BA] # YI SYLLABLE SHUT +A3BB ; [.36C0.0020.0002.A3BB] # YI SYLLABLE SHUX +A3BC ; [.36C1.0020.0002.A3BC] # YI SYLLABLE SHU +A3BD ; [.36C2.0020.0002.A3BD] # YI SYLLABLE SHUP +A3BE ; [.36C3.0020.0002.A3BE] # YI SYLLABLE SHURX +A3BF ; [.36C4.0020.0002.A3BF] # YI SYLLABLE SHUR +A3C0 ; [.36C5.0020.0002.A3C0] # YI SYLLABLE SHYT +A3C1 ; [.36C6.0020.0002.A3C1] # YI SYLLABLE SHYX +A3C2 ; [.36C7.0020.0002.A3C2] # YI SYLLABLE SHY +A3C3 ; [.36C8.0020.0002.A3C3] # YI SYLLABLE SHYP +A3C4 ; [.36C9.0020.0002.A3C4] # YI SYLLABLE SHYRX +A3C5 ; [.36CA.0020.0002.A3C5] # YI SYLLABLE SHYR +A3C6 ; [.36CB.0020.0002.A3C6] # YI SYLLABLE RAT +A3C7 ; [.36CC.0020.0002.A3C7] # YI SYLLABLE RAX +A3C8 ; [.36CD.0020.0002.A3C8] # YI SYLLABLE RA +A3C9 ; [.36CE.0020.0002.A3C9] # YI SYLLABLE RAP +A3CA ; [.36CF.0020.0002.A3CA] # YI SYLLABLE RUOX +A3CB ; [.36D0.0020.0002.A3CB] # YI SYLLABLE RUO +A3CC ; [.36D1.0020.0002.A3CC] # YI SYLLABLE RUOP +A3CD ; [.36D2.0020.0002.A3CD] # YI SYLLABLE ROT +A3CE ; [.36D3.0020.0002.A3CE] # YI SYLLABLE ROX +A3CF ; [.36D4.0020.0002.A3CF] # YI SYLLABLE RO +A3D0 ; [.36D5.0020.0002.A3D0] # YI SYLLABLE ROP +A3D1 ; [.36D6.0020.0002.A3D1] # YI SYLLABLE REX +A3D2 ; [.36D7.0020.0002.A3D2] # YI SYLLABLE RE +A3D3 ; [.36D8.0020.0002.A3D3] # YI SYLLABLE REP +A3D4 ; [.36D9.0020.0002.A3D4] # YI SYLLABLE RUT +A3D5 ; [.36DA.0020.0002.A3D5] # YI SYLLABLE RUX +A3D6 ; [.36DB.0020.0002.A3D6] # YI SYLLABLE RU +A3D7 ; [.36DC.0020.0002.A3D7] # YI SYLLABLE RUP +A3D8 ; [.36DD.0020.0002.A3D8] # YI SYLLABLE RURX +A3D9 ; [.36DE.0020.0002.A3D9] # YI SYLLABLE RUR +A3DA ; [.36DF.0020.0002.A3DA] # YI SYLLABLE RYT +A3DB ; [.36E0.0020.0002.A3DB] # YI SYLLABLE RYX +A3DC ; [.36E1.0020.0002.A3DC] # YI SYLLABLE RY +A3DD ; [.36E2.0020.0002.A3DD] # YI SYLLABLE RYP +A3DE ; [.36E3.0020.0002.A3DE] # YI SYLLABLE RYRX +A3DF ; [.36E4.0020.0002.A3DF] # YI SYLLABLE RYR +A3E0 ; [.36E5.0020.0002.A3E0] # YI SYLLABLE JIT +A3E1 ; [.36E6.0020.0002.A3E1] # YI SYLLABLE JIX +A3E2 ; [.36E7.0020.0002.A3E2] # YI SYLLABLE JI +A3E3 ; [.36E8.0020.0002.A3E3] # YI SYLLABLE JIP +A3E4 ; [.36E9.0020.0002.A3E4] # YI SYLLABLE JIET +A3E5 ; [.36EA.0020.0002.A3E5] # YI SYLLABLE JIEX +A3E6 ; [.36EB.0020.0002.A3E6] # YI SYLLABLE JIE +A3E7 ; [.36EC.0020.0002.A3E7] # YI SYLLABLE JIEP +A3E8 ; [.36ED.0020.0002.A3E8] # YI SYLLABLE JUOT +A3E9 ; [.36EE.0020.0002.A3E9] # YI SYLLABLE JUOX +A3EA ; [.36EF.0020.0002.A3EA] # YI SYLLABLE JUO +A3EB ; [.36F0.0020.0002.A3EB] # YI SYLLABLE JUOP +A3EC ; [.36F1.0020.0002.A3EC] # YI SYLLABLE JOT +A3ED ; [.36F2.0020.0002.A3ED] # YI SYLLABLE JOX +A3EE ; [.36F3.0020.0002.A3EE] # YI SYLLABLE JO +A3EF ; [.36F4.0020.0002.A3EF] # YI SYLLABLE JOP +A3F0 ; [.36F5.0020.0002.A3F0] # YI SYLLABLE JUT +A3F1 ; [.36F6.0020.0002.A3F1] # YI SYLLABLE JUX +A3F2 ; [.36F7.0020.0002.A3F2] # YI SYLLABLE JU +A3F3 ; [.36F8.0020.0002.A3F3] # YI SYLLABLE JUP +A3F4 ; [.36F9.0020.0002.A3F4] # YI SYLLABLE JURX +A3F5 ; [.36FA.0020.0002.A3F5] # YI SYLLABLE JUR +A3F6 ; [.36FB.0020.0002.A3F6] # YI SYLLABLE JYT +A3F7 ; [.36FC.0020.0002.A3F7] # YI SYLLABLE JYX +A3F8 ; [.36FD.0020.0002.A3F8] # YI SYLLABLE JY +A3F9 ; [.36FE.0020.0002.A3F9] # YI SYLLABLE JYP +A3FA ; [.36FF.0020.0002.A3FA] # YI SYLLABLE JYRX +A3FB ; [.3700.0020.0002.A3FB] # YI SYLLABLE JYR +A3FC ; [.3701.0020.0002.A3FC] # YI SYLLABLE QIT +A3FD ; [.3702.0020.0002.A3FD] # YI SYLLABLE QIX +A3FE ; [.3703.0020.0002.A3FE] # YI SYLLABLE QI +A3FF ; [.3704.0020.0002.A3FF] # YI SYLLABLE QIP +A400 ; [.3705.0020.0002.A400] # YI SYLLABLE QIET +A401 ; [.3706.0020.0002.A401] # YI SYLLABLE QIEX +A402 ; [.3707.0020.0002.A402] # YI SYLLABLE QIE +A403 ; [.3708.0020.0002.A403] # YI SYLLABLE QIEP +A404 ; [.3709.0020.0002.A404] # YI SYLLABLE QUOT +A405 ; [.370A.0020.0002.A405] # YI SYLLABLE QUOX +A406 ; [.370B.0020.0002.A406] # YI SYLLABLE QUO +A407 ; [.370C.0020.0002.A407] # YI SYLLABLE QUOP +A408 ; [.370D.0020.0002.A408] # YI SYLLABLE QOT +A409 ; [.370E.0020.0002.A409] # YI SYLLABLE QOX +A40A ; [.370F.0020.0002.A40A] # YI SYLLABLE QO +A40B ; [.3710.0020.0002.A40B] # YI SYLLABLE QOP +A40C ; [.3711.0020.0002.A40C] # YI SYLLABLE QUT +A40D ; [.3712.0020.0002.A40D] # YI SYLLABLE QUX +A40E ; [.3713.0020.0002.A40E] # YI SYLLABLE QU +A40F ; [.3714.0020.0002.A40F] # YI SYLLABLE QUP +A410 ; [.3715.0020.0002.A410] # YI SYLLABLE QURX +A411 ; [.3716.0020.0002.A411] # YI SYLLABLE QUR +A412 ; [.3717.0020.0002.A412] # YI SYLLABLE QYT +A413 ; [.3718.0020.0002.A413] # YI SYLLABLE QYX +A414 ; [.3719.0020.0002.A414] # YI SYLLABLE QY +A415 ; [.371A.0020.0002.A415] # YI SYLLABLE QYP +A416 ; [.371B.0020.0002.A416] # YI SYLLABLE QYRX +A417 ; [.371C.0020.0002.A417] # YI SYLLABLE QYR +A418 ; [.371D.0020.0002.A418] # YI SYLLABLE JJIT +A419 ; [.371E.0020.0002.A419] # YI SYLLABLE JJIX +A41A ; [.371F.0020.0002.A41A] # YI SYLLABLE JJI +A41B ; [.3720.0020.0002.A41B] # YI SYLLABLE JJIP +A41C ; [.3721.0020.0002.A41C] # YI SYLLABLE JJIET +A41D ; [.3722.0020.0002.A41D] # YI SYLLABLE JJIEX +A41E ; [.3723.0020.0002.A41E] # YI SYLLABLE JJIE +A41F ; [.3724.0020.0002.A41F] # YI SYLLABLE JJIEP +A420 ; [.3725.0020.0002.A420] # YI SYLLABLE JJUOX +A421 ; [.3726.0020.0002.A421] # YI SYLLABLE JJUO +A422 ; [.3727.0020.0002.A422] # YI SYLLABLE JJUOP +A423 ; [.3728.0020.0002.A423] # YI SYLLABLE JJOT +A424 ; [.3729.0020.0002.A424] # YI SYLLABLE JJOX +A425 ; [.372A.0020.0002.A425] # YI SYLLABLE JJO +A426 ; [.372B.0020.0002.A426] # YI SYLLABLE JJOP +A427 ; [.372C.0020.0002.A427] # YI SYLLABLE JJUT +A428 ; [.372D.0020.0002.A428] # YI SYLLABLE JJUX +A429 ; [.372E.0020.0002.A429] # YI SYLLABLE JJU +A42A ; [.372F.0020.0002.A42A] # YI SYLLABLE JJUP +A42B ; [.3730.0020.0002.A42B] # YI SYLLABLE JJURX +A42C ; [.3731.0020.0002.A42C] # YI SYLLABLE JJUR +A42D ; [.3732.0020.0002.A42D] # YI SYLLABLE JJYT +A42E ; [.3733.0020.0002.A42E] # YI SYLLABLE JJYX +A42F ; [.3734.0020.0002.A42F] # YI SYLLABLE JJY +A430 ; [.3735.0020.0002.A430] # YI SYLLABLE JJYP +A431 ; [.3736.0020.0002.A431] # YI SYLLABLE NJIT +A432 ; [.3737.0020.0002.A432] # YI SYLLABLE NJIX +A433 ; [.3738.0020.0002.A433] # YI SYLLABLE NJI +A434 ; [.3739.0020.0002.A434] # YI SYLLABLE NJIP +A435 ; [.373A.0020.0002.A435] # YI SYLLABLE NJIET +A436 ; [.373B.0020.0002.A436] # YI SYLLABLE NJIEX +A437 ; [.373C.0020.0002.A437] # YI SYLLABLE NJIE +A438 ; [.373D.0020.0002.A438] # YI SYLLABLE NJIEP +A439 ; [.373E.0020.0002.A439] # YI SYLLABLE NJUOX +A43A ; [.373F.0020.0002.A43A] # YI SYLLABLE NJUO +A43B ; [.3740.0020.0002.A43B] # YI SYLLABLE NJOT +A43C ; [.3741.0020.0002.A43C] # YI SYLLABLE NJOX +A43D ; [.3742.0020.0002.A43D] # YI SYLLABLE NJO +A43E ; [.3743.0020.0002.A43E] # YI SYLLABLE NJOP +A43F ; [.3744.0020.0002.A43F] # YI SYLLABLE NJUX +A440 ; [.3745.0020.0002.A440] # YI SYLLABLE NJU +A441 ; [.3746.0020.0002.A441] # YI SYLLABLE NJUP +A442 ; [.3747.0020.0002.A442] # YI SYLLABLE NJURX +A443 ; [.3748.0020.0002.A443] # YI SYLLABLE NJUR +A444 ; [.3749.0020.0002.A444] # YI SYLLABLE NJYT +A445 ; [.374A.0020.0002.A445] # YI SYLLABLE NJYX +A446 ; [.374B.0020.0002.A446] # YI SYLLABLE NJY +A447 ; [.374C.0020.0002.A447] # YI SYLLABLE NJYP +A448 ; [.374D.0020.0002.A448] # YI SYLLABLE NJYRX +A449 ; [.374E.0020.0002.A449] # YI SYLLABLE NJYR +A44A ; [.374F.0020.0002.A44A] # YI SYLLABLE NYIT +A44B ; [.3750.0020.0002.A44B] # YI SYLLABLE NYIX +A44C ; [.3751.0020.0002.A44C] # YI SYLLABLE NYI +A44D ; [.3752.0020.0002.A44D] # YI SYLLABLE NYIP +A44E ; [.3753.0020.0002.A44E] # YI SYLLABLE NYIET +A44F ; [.3754.0020.0002.A44F] # YI SYLLABLE NYIEX +A450 ; [.3755.0020.0002.A450] # YI SYLLABLE NYIE +A451 ; [.3756.0020.0002.A451] # YI SYLLABLE NYIEP +A452 ; [.3757.0020.0002.A452] # YI SYLLABLE NYUOX +A453 ; [.3758.0020.0002.A453] # YI SYLLABLE NYUO +A454 ; [.3759.0020.0002.A454] # YI SYLLABLE NYUOP +A455 ; [.375A.0020.0002.A455] # YI SYLLABLE NYOT +A456 ; [.375B.0020.0002.A456] # YI SYLLABLE NYOX +A457 ; [.375C.0020.0002.A457] # YI SYLLABLE NYO +A458 ; [.375D.0020.0002.A458] # YI SYLLABLE NYOP +A459 ; [.375E.0020.0002.A459] # YI SYLLABLE NYUT +A45A ; [.375F.0020.0002.A45A] # YI SYLLABLE NYUX +A45B ; [.3760.0020.0002.A45B] # YI SYLLABLE NYU +A45C ; [.3761.0020.0002.A45C] # YI SYLLABLE NYUP +A45D ; [.3762.0020.0002.A45D] # YI SYLLABLE XIT +A45E ; [.3763.0020.0002.A45E] # YI SYLLABLE XIX +A45F ; [.3764.0020.0002.A45F] # YI SYLLABLE XI +A460 ; [.3765.0020.0002.A460] # YI SYLLABLE XIP +A461 ; [.3766.0020.0002.A461] # YI SYLLABLE XIET +A462 ; [.3767.0020.0002.A462] # YI SYLLABLE XIEX +A463 ; [.3768.0020.0002.A463] # YI SYLLABLE XIE +A464 ; [.3769.0020.0002.A464] # YI SYLLABLE XIEP +A465 ; [.376A.0020.0002.A465] # YI SYLLABLE XUOX +A466 ; [.376B.0020.0002.A466] # YI SYLLABLE XUO +A467 ; [.376C.0020.0002.A467] # YI SYLLABLE XOT +A468 ; [.376D.0020.0002.A468] # YI SYLLABLE XOX +A469 ; [.376E.0020.0002.A469] # YI SYLLABLE XO +A46A ; [.376F.0020.0002.A46A] # YI SYLLABLE XOP +A46B ; [.3770.0020.0002.A46B] # YI SYLLABLE XYT +A46C ; [.3771.0020.0002.A46C] # YI SYLLABLE XYX +A46D ; [.3772.0020.0002.A46D] # YI SYLLABLE XY +A46E ; [.3773.0020.0002.A46E] # YI SYLLABLE XYP +A46F ; [.3774.0020.0002.A46F] # YI SYLLABLE XYRX +A470 ; [.3775.0020.0002.A470] # YI SYLLABLE XYR +A471 ; [.3776.0020.0002.A471] # YI SYLLABLE YIT +A472 ; [.3777.0020.0002.A472] # YI SYLLABLE YIX +A473 ; [.3778.0020.0002.A473] # YI SYLLABLE YI +A474 ; [.3779.0020.0002.A474] # YI SYLLABLE YIP +A475 ; [.377A.0020.0002.A475] # YI SYLLABLE YIET +A476 ; [.377B.0020.0002.A476] # YI SYLLABLE YIEX +A477 ; [.377C.0020.0002.A477] # YI SYLLABLE YIE +A478 ; [.377D.0020.0002.A478] # YI SYLLABLE YIEP +A479 ; [.377E.0020.0002.A479] # YI SYLLABLE YUOT +A47A ; [.377F.0020.0002.A47A] # YI SYLLABLE YUOX +A47B ; [.3780.0020.0002.A47B] # YI SYLLABLE YUO +A47C ; [.3781.0020.0002.A47C] # YI SYLLABLE YUOP +A47D ; [.3782.0020.0002.A47D] # YI SYLLABLE YOT +A47E ; [.3783.0020.0002.A47E] # YI SYLLABLE YOX +A47F ; [.3784.0020.0002.A47F] # YI SYLLABLE YO +A480 ; [.3785.0020.0002.A480] # YI SYLLABLE YOP +A481 ; [.3786.0020.0002.A481] # YI SYLLABLE YUT +A482 ; [.3787.0020.0002.A482] # YI SYLLABLE YUX +A483 ; [.3788.0020.0002.A483] # YI SYLLABLE YU +A484 ; [.3789.0020.0002.A484] # YI SYLLABLE YUP +A485 ; [.378A.0020.0002.A485] # YI SYLLABLE YURX +A486 ; [.378B.0020.0002.A486] # YI SYLLABLE YUR +A487 ; [.378C.0020.0002.A487] # YI SYLLABLE YYT +A488 ; [.378D.0020.0002.A488] # YI SYLLABLE YYX +A489 ; [.378E.0020.0002.A489] # YI SYLLABLE YY +A48A ; [.378F.0020.0002.A48A] # YI SYLLABLE YYP +A48B ; [.3790.0020.0002.A48B] # YI SYLLABLE YYRX +A48C ; [.3791.0020.0002.A48C] # YI SYLLABLE YYR +A4F8 ; [.3792.0020.0002.A4F8] # LISU LETTER TONE MYA TI +A4F9 ; [.3793.0020.0002.A4F9] # LISU LETTER TONE NA PO +A4FA ; [.3794.0020.0002.A4FA] # LISU LETTER TONE MYA CYA +A4FB ; [.3795.0020.0002.A4FB] # LISU LETTER TONE MYA BO +A4FD ; [.3796.0020.0002.A4FD] # LISU LETTER TONE MYA JEU +A4FC ; [.3797.0020.0002.A4FC] # LISU LETTER TONE MYA NA +A4D0 ; [.3798.0020.0002.A4D0] # LISU LETTER BA +A4D1 ; [.3799.0020.0002.A4D1] # LISU LETTER PA +A4D2 ; [.379A.0020.0002.A4D2] # LISU LETTER PHA +A4D3 ; [.379B.0020.0002.A4D3] # LISU LETTER DA +A4D4 ; [.379C.0020.0002.A4D4] # LISU LETTER TA +A4D5 ; [.379D.0020.0002.A4D5] # LISU LETTER THA +A4D6 ; [.379E.0020.0002.A4D6] # LISU LETTER GA +A4D7 ; [.379F.0020.0002.A4D7] # LISU LETTER KA +A4D8 ; [.37A0.0020.0002.A4D8] # LISU LETTER KHA +A4D9 ; [.37A1.0020.0002.A4D9] # LISU LETTER JA +A4DA ; [.37A2.0020.0002.A4DA] # LISU LETTER CA +A4DB ; [.37A3.0020.0002.A4DB] # LISU LETTER CHA +A4DC ; [.37A4.0020.0002.A4DC] # LISU LETTER DZA +A4DD ; [.37A5.0020.0002.A4DD] # LISU LETTER TSA +A4DE ; [.37A6.0020.0002.A4DE] # LISU LETTER TSHA +A4DF ; [.37A7.0020.0002.A4DF] # LISU LETTER MA +A4E0 ; [.37A8.0020.0002.A4E0] # LISU LETTER NA +A4E1 ; [.37A9.0020.0002.A4E1] # LISU LETTER LA +A4E2 ; [.37AA.0020.0002.A4E2] # LISU LETTER SA +A4E3 ; [.37AB.0020.0002.A4E3] # LISU LETTER ZHA +A4E4 ; [.37AC.0020.0002.A4E4] # LISU LETTER ZA +A4E5 ; [.37AD.0020.0002.A4E5] # LISU LETTER NGA +A4E6 ; [.37AE.0020.0002.A4E6] # LISU LETTER HA +A4E7 ; [.37AF.0020.0002.A4E7] # LISU LETTER XA +A4E8 ; [.37B0.0020.0002.A4E8] # LISU LETTER HHA +A4E9 ; [.37B1.0020.0002.A4E9] # LISU LETTER FA +A4EB ; [.37B2.0020.0002.A4EB] # LISU LETTER SHA +A4ED ; [.37B3.0020.0002.A4ED] # LISU LETTER GHA +A4EA ; [.37B4.0020.0002.A4EA] # LISU LETTER WA +A4EC ; [.37B5.0020.0002.A4EC] # LISU LETTER YA +A4EE ; [.37B6.0020.0002.A4EE] # LISU LETTER A +A4EF ; [.37B7.0020.0002.A4EF] # LISU LETTER AE +A4F0 ; [.37B8.0020.0002.A4F0] # LISU LETTER E +A4F1 ; [.37B9.0020.0002.A4F1] # LISU LETTER EU +A4F2 ; [.37BA.0020.0002.A4F2] # LISU LETTER I +A4F3 ; [.37BB.0020.0002.A4F3] # LISU LETTER O +A4F4 ; [.37BC.0020.0002.A4F4] # LISU LETTER U +A4F5 ; [.37BD.0020.0002.A4F5] # LISU LETTER UE +A4F6 ; [.37BE.0020.0002.A4F6] # LISU LETTER UH +A4F7 ; [.37BF.0020.0002.A4F7] # LISU LETTER OE +16F00 ; [.37C0.0020.0002.16F00] # MIAO LETTER PA +16F01 ; [.37C1.0020.0002.16F01] # MIAO LETTER BA +16F02 ; [.37C2.0020.0002.16F02] # MIAO LETTER YI PA +16F03 ; [.37C3.0020.0002.16F03] # MIAO LETTER PLA +16F04 ; [.37C4.0020.0002.16F04] # MIAO LETTER MA +16F06 ; [.37C4.0020.0004.16F06] # MIAO LETTER ARCHAIC MA +16F05 ; [.37C5.0020.0002.16F05] # MIAO LETTER MHA +16F07 ; [.37C6.0020.0002.16F07] # MIAO LETTER FA +16F08 ; [.37C7.0020.0002.16F08] # MIAO LETTER VA +16F09 ; [.37C8.0020.0002.16F09] # MIAO LETTER VFA +16F0A ; [.37C9.0020.0002.16F0A] # MIAO LETTER TA +16F0B ; [.37CA.0020.0002.16F0B] # MIAO LETTER DA +16F0C ; [.37CB.0020.0002.16F0C] # MIAO LETTER YI TTA +16F0D ; [.37CC.0020.0002.16F0D] # MIAO LETTER YI TA +16F0E ; [.37CD.0020.0002.16F0E] # MIAO LETTER TTA +16F0F ; [.37CE.0020.0002.16F0F] # MIAO LETTER DDA +16F10 ; [.37CF.0020.0002.16F10] # MIAO LETTER NA +16F13 ; [.37CF.0020.0004.16F13] # MIAO LETTER ARCHAIC NA +16F11 ; [.37D0.0020.0002.16F11] # MIAO LETTER NHA +16F12 ; [.37D1.0020.0002.16F12] # MIAO LETTER YI NNA +16F14 ; [.37D2.0020.0002.16F14] # MIAO LETTER NNA +16F15 ; [.37D3.0020.0002.16F15] # MIAO LETTER NNHA +16F16 ; [.37D4.0020.0002.16F16] # MIAO LETTER LA +16F17 ; [.37D5.0020.0002.16F17] # MIAO LETTER LYA +16F18 ; [.37D6.0020.0002.16F18] # MIAO LETTER LHA +16F19 ; [.37D7.0020.0002.16F19] # MIAO LETTER LHYA +16F1A ; [.37D8.0020.0002.16F1A] # MIAO LETTER TLHA +16F1B ; [.37D9.0020.0002.16F1B] # MIAO LETTER DLHA +16F1C ; [.37DA.0020.0002.16F1C] # MIAO LETTER TLHYA +16F1D ; [.37DB.0020.0002.16F1D] # MIAO LETTER DLHYA +16F1E ; [.37DC.0020.0002.16F1E] # MIAO LETTER KA +16F1F ; [.37DD.0020.0002.16F1F] # MIAO LETTER GA +16F20 ; [.37DE.0020.0002.16F20] # MIAO LETTER YI KA +16F21 ; [.37DF.0020.0002.16F21] # MIAO LETTER QA +16F22 ; [.37E0.0020.0002.16F22] # MIAO LETTER QGA +16F23 ; [.37E1.0020.0002.16F23] # MIAO LETTER NGA +16F25 ; [.37E1.0020.0004.16F25] # MIAO LETTER ARCHAIC NGA +16F24 ; [.37E2.0020.0002.16F24] # MIAO LETTER NGHA +16F26 ; [.37E3.0020.0002.16F26] # MIAO LETTER HA +16F27 ; [.37E4.0020.0002.16F27] # MIAO LETTER XA +16F28 ; [.37E5.0020.0002.16F28] # MIAO LETTER GHA +16F29 ; [.37E6.0020.0002.16F29] # MIAO LETTER GHHA +16F2A ; [.37E7.0020.0002.16F2A] # MIAO LETTER TSSA +16F2B ; [.37E8.0020.0002.16F2B] # MIAO LETTER DZZA +16F2C ; [.37E9.0020.0002.16F2C] # MIAO LETTER NYA +16F2D ; [.37EA.0020.0002.16F2D] # MIAO LETTER NYHA +16F2E ; [.37EB.0020.0002.16F2E] # MIAO LETTER TSHA +16F2F ; [.37EC.0020.0002.16F2F] # MIAO LETTER DZHA +16F30 ; [.37ED.0020.0002.16F30] # MIAO LETTER YI TSHA +16F31 ; [.37EE.0020.0002.16F31] # MIAO LETTER YI DZHA +16F32 ; [.37EF.0020.0002.16F32] # MIAO LETTER REFORMED TSHA +16F33 ; [.37F0.0020.0002.16F33] # MIAO LETTER SHA +16F34 ; [.37F1.0020.0002.16F34] # MIAO LETTER SSA +16F35 ; [.37F2.0020.0002.16F35] # MIAO LETTER ZHA +16F36 ; [.37F3.0020.0002.16F36] # MIAO LETTER ZSHA +16F37 ; [.37F4.0020.0002.16F37] # MIAO LETTER TSA +16F38 ; [.37F5.0020.0002.16F38] # MIAO LETTER DZA +16F39 ; [.37F6.0020.0002.16F39] # MIAO LETTER YI TSA +16F3A ; [.37F7.0020.0002.16F3A] # MIAO LETTER SA +16F3B ; [.37F8.0020.0002.16F3B] # MIAO LETTER ZA +16F3C ; [.37F9.0020.0002.16F3C] # MIAO LETTER ZSA +16F3D ; [.37FA.0020.0002.16F3D] # MIAO LETTER ZZA +16F3F ; [.37FA.0020.0004.16F3F] # MIAO LETTER ARCHAIC ZZA +16F3E ; [.37FB.0020.0002.16F3E] # MIAO LETTER ZZSA +16F40 ; [.37FC.0020.0002.16F40] # MIAO LETTER ZZYA +16F41 ; [.37FD.0020.0002.16F41] # MIAO LETTER ZZSYA +16F42 ; [.37FE.0020.0002.16F42] # MIAO LETTER WA +16F43 ; [.37FF.0020.0002.16F43] # MIAO LETTER AH +16F44 ; [.3800.0020.0002.16F44] # MIAO LETTER HHA +16F50 ; [.3801.0020.0002.16F50] # MIAO LETTER NASALIZATION +16F51 ; [.3802.0020.0002.16F51] # MIAO SIGN ASPIRATION +16F52 ; [.3803.0020.0002.16F52] # MIAO SIGN REFORMED VOICING +16F53 ; [.3804.0020.0002.16F53] # MIAO SIGN REFORMED ASPIRATION +16F54 ; [.3805.0020.0002.16F54] # MIAO VOWEL SIGN A +16F55 ; [.3806.0020.0002.16F55] # MIAO VOWEL SIGN AA +16F56 ; [.3807.0020.0002.16F56] # MIAO VOWEL SIGN AHH +16F57 ; [.3808.0020.0002.16F57] # MIAO VOWEL SIGN AN +16F58 ; [.3809.0020.0002.16F58] # MIAO VOWEL SIGN ANG +16F59 ; [.380A.0020.0002.16F59] # MIAO VOWEL SIGN O +16F5A ; [.380B.0020.0002.16F5A] # MIAO VOWEL SIGN OO +16F5B ; [.380C.0020.0002.16F5B] # MIAO VOWEL SIGN WO +16F5C ; [.380D.0020.0002.16F5C] # MIAO VOWEL SIGN W +16F5D ; [.380E.0020.0002.16F5D] # MIAO VOWEL SIGN E +16F5E ; [.380F.0020.0002.16F5E] # MIAO VOWEL SIGN EN +16F5F ; [.3810.0020.0002.16F5F] # MIAO VOWEL SIGN ENG +16F60 ; [.3811.0020.0002.16F60] # MIAO VOWEL SIGN OEY +16F61 ; [.3812.0020.0002.16F61] # MIAO VOWEL SIGN I +16F62 ; [.3813.0020.0002.16F62] # MIAO VOWEL SIGN IA +16F63 ; [.3814.0020.0002.16F63] # MIAO VOWEL SIGN IAN +16F64 ; [.3815.0020.0002.16F64] # MIAO VOWEL SIGN IANG +16F65 ; [.3816.0020.0002.16F65] # MIAO VOWEL SIGN IO +16F66 ; [.3817.0020.0002.16F66] # MIAO VOWEL SIGN IE +16F67 ; [.3818.0020.0002.16F67] # MIAO VOWEL SIGN II +16F68 ; [.3819.0020.0002.16F68] # MIAO VOWEL SIGN IU +16F69 ; [.381A.0020.0002.16F69] # MIAO VOWEL SIGN ING +16F6A ; [.381B.0020.0002.16F6A] # MIAO VOWEL SIGN U +16F6B ; [.381C.0020.0002.16F6B] # MIAO VOWEL SIGN UA +16F6C ; [.381D.0020.0002.16F6C] # MIAO VOWEL SIGN UAN +16F6D ; [.381E.0020.0002.16F6D] # MIAO VOWEL SIGN UANG +16F6E ; [.381F.0020.0002.16F6E] # MIAO VOWEL SIGN UU +16F6F ; [.3820.0020.0002.16F6F] # MIAO VOWEL SIGN UEI +16F70 ; [.3821.0020.0002.16F70] # MIAO VOWEL SIGN UNG +16F71 ; [.3822.0020.0002.16F71] # MIAO VOWEL SIGN Y +16F72 ; [.3823.0020.0002.16F72] # MIAO VOWEL SIGN YI +16F73 ; [.3824.0020.0002.16F73] # MIAO VOWEL SIGN AE +16F74 ; [.3825.0020.0002.16F74] # MIAO VOWEL SIGN AEE +16F75 ; [.3826.0020.0002.16F75] # MIAO VOWEL SIGN ERR +16F76 ; [.3827.0020.0002.16F76] # MIAO VOWEL SIGN ROUNDED ERR +16F77 ; [.3828.0020.0002.16F77] # MIAO VOWEL SIGN ER +16F78 ; [.3829.0020.0002.16F78] # MIAO VOWEL SIGN ROUNDED ER +16F79 ; [.382A.0020.0002.16F79] # MIAO VOWEL SIGN AI +16F7A ; [.382B.0020.0002.16F7A] # MIAO VOWEL SIGN EI +16F7B ; [.382C.0020.0002.16F7B] # MIAO VOWEL SIGN AU +16F7C ; [.382D.0020.0002.16F7C] # MIAO VOWEL SIGN OU +16F7D ; [.382E.0020.0002.16F7D] # MIAO VOWEL SIGN N +16F7E ; [.382F.0020.0002.16F7E] # MIAO VOWEL SIGN NG +16F8F ; [.3830.0020.0002.16F8F] # MIAO TONE RIGHT +16F90 ; [.3831.0020.0002.16F90] # MIAO TONE TOP RIGHT +16F91 ; [.3832.0020.0002.16F91] # MIAO TONE ABOVE +16F92 ; [.3833.0020.0002.16F92] # MIAO TONE BELOW +16F93 ; [.3834.0020.0002.16F93] # MIAO LETTER TONE-2 +16F94 ; [.3835.0020.0002.16F94] # MIAO LETTER TONE-3 +16F95 ; [.3836.0020.0002.16F95] # MIAO LETTER TONE-4 +16F96 ; [.3837.0020.0002.16F96] # MIAO LETTER TONE-5 +16F97 ; [.3838.0020.0002.16F97] # MIAO LETTER TONE-6 +16F98 ; [.3839.0020.0002.16F98] # MIAO LETTER TONE-7 +16F99 ; [.383A.0020.0002.16F99] # MIAO LETTER TONE-8 +16F9A ; [.383B.0020.0002.16F9A] # MIAO LETTER REFORMED TONE-1 +16F9B ; [.383C.0020.0002.16F9B] # MIAO LETTER REFORMED TONE-2 +16F9C ; [.383D.0020.0002.16F9C] # MIAO LETTER REFORMED TONE-4 +16F9D ; [.383E.0020.0002.16F9D] # MIAO LETTER REFORMED TONE-5 +16F9E ; [.383F.0020.0002.16F9E] # MIAO LETTER REFORMED TONE-6 +16F9F ; [.3840.0020.0002.16F9F] # MIAO LETTER REFORMED TONE-8 +10280 ; [.3841.0020.0002.10280] # LYCIAN LETTER A +10281 ; [.3842.0020.0002.10281] # LYCIAN LETTER E +10282 ; [.3843.0020.0002.10282] # LYCIAN LETTER B +10283 ; [.3844.0020.0002.10283] # LYCIAN LETTER BH +10284 ; [.3845.0020.0002.10284] # LYCIAN LETTER G +10285 ; [.3846.0020.0002.10285] # LYCIAN LETTER D +10286 ; [.3847.0020.0002.10286] # LYCIAN LETTER I +10287 ; [.3848.0020.0002.10287] # LYCIAN LETTER W +10288 ; [.3849.0020.0002.10288] # LYCIAN LETTER Z +10289 ; [.384A.0020.0002.10289] # LYCIAN LETTER TH +1028A ; [.384B.0020.0002.1028A] # LYCIAN LETTER J +1028B ; [.384C.0020.0002.1028B] # LYCIAN LETTER K +1028C ; [.384D.0020.0002.1028C] # LYCIAN LETTER Q +1028D ; [.384E.0020.0002.1028D] # LYCIAN LETTER L +1028E ; [.384F.0020.0002.1028E] # LYCIAN LETTER M +1028F ; [.3850.0020.0002.1028F] # LYCIAN LETTER N +10290 ; [.3851.0020.0002.10290] # LYCIAN LETTER MM +10291 ; [.3852.0020.0002.10291] # LYCIAN LETTER NN +10292 ; [.3853.0020.0002.10292] # LYCIAN LETTER U +10293 ; [.3854.0020.0002.10293] # LYCIAN LETTER P +10294 ; [.3855.0020.0002.10294] # LYCIAN LETTER KK +10295 ; [.3856.0020.0002.10295] # LYCIAN LETTER R +10296 ; [.3857.0020.0002.10296] # LYCIAN LETTER S +10297 ; [.3858.0020.0002.10297] # LYCIAN LETTER T +10298 ; [.3859.0020.0002.10298] # LYCIAN LETTER TT +10299 ; [.385A.0020.0002.10299] # LYCIAN LETTER AN +1029A ; [.385B.0020.0002.1029A] # LYCIAN LETTER EN +1029B ; [.385C.0020.0002.1029B] # LYCIAN LETTER H +1029C ; [.385D.0020.0002.1029C] # LYCIAN LETTER X +102A0 ; [.385E.0020.0002.102A0] # CARIAN LETTER A +102A1 ; [.385F.0020.0002.102A1] # CARIAN LETTER P2 +102A2 ; [.3860.0020.0002.102A2] # CARIAN LETTER D +102A3 ; [.3861.0020.0002.102A3] # CARIAN LETTER L +102A4 ; [.3862.0020.0002.102A4] # CARIAN LETTER UUU +102A5 ; [.3863.0020.0002.102A5] # CARIAN LETTER R +102A6 ; [.3864.0020.0002.102A6] # CARIAN LETTER LD +102A7 ; [.3865.0020.0002.102A7] # CARIAN LETTER A2 +102A8 ; [.3866.0020.0002.102A8] # CARIAN LETTER Q +102A9 ; [.3867.0020.0002.102A9] # CARIAN LETTER B +102AA ; [.3868.0020.0002.102AA] # CARIAN LETTER M +102AB ; [.3869.0020.0002.102AB] # CARIAN LETTER O +102AC ; [.386A.0020.0002.102AC] # CARIAN LETTER D2 +102AD ; [.386B.0020.0002.102AD] # CARIAN LETTER T +102AE ; [.386C.0020.0002.102AE] # CARIAN LETTER SH +102AF ; [.386D.0020.0002.102AF] # CARIAN LETTER SH2 +102B0 ; [.386E.0020.0002.102B0] # CARIAN LETTER S +102B1 ; [.386F.0020.0002.102B1] # CARIAN LETTER C-18 +102B2 ; [.3870.0020.0002.102B2] # CARIAN LETTER U +102B3 ; [.3871.0020.0002.102B3] # CARIAN LETTER NN +102B4 ; [.3872.0020.0002.102B4] # CARIAN LETTER X +102B5 ; [.3873.0020.0002.102B5] # CARIAN LETTER N +102B6 ; [.3874.0020.0002.102B6] # CARIAN LETTER TT2 +102B7 ; [.3875.0020.0002.102B7] # CARIAN LETTER P +102B8 ; [.3876.0020.0002.102B8] # CARIAN LETTER SS +102B9 ; [.3877.0020.0002.102B9] # CARIAN LETTER I +102BA ; [.3878.0020.0002.102BA] # CARIAN LETTER E +102BB ; [.3879.0020.0002.102BB] # CARIAN LETTER UUUU +102BC ; [.387A.0020.0002.102BC] # CARIAN LETTER K +102BD ; [.387B.0020.0002.102BD] # CARIAN LETTER K2 +102BE ; [.387C.0020.0002.102BE] # CARIAN LETTER ND +102BF ; [.387D.0020.0002.102BF] # CARIAN LETTER UU +102C0 ; [.387E.0020.0002.102C0] # CARIAN LETTER G +102C1 ; [.387F.0020.0002.102C1] # CARIAN LETTER G2 +102C2 ; [.3880.0020.0002.102C2] # CARIAN LETTER ST +102C3 ; [.3881.0020.0002.102C3] # CARIAN LETTER ST2 +102C4 ; [.3882.0020.0002.102C4] # CARIAN LETTER NG +102C5 ; [.3883.0020.0002.102C5] # CARIAN LETTER II +102C6 ; [.3884.0020.0002.102C6] # CARIAN LETTER C-39 +102C7 ; [.3885.0020.0002.102C7] # CARIAN LETTER TT +102C8 ; [.3886.0020.0002.102C8] # CARIAN LETTER UUU2 +102C9 ; [.3887.0020.0002.102C9] # CARIAN LETTER RR +102CA ; [.3888.0020.0002.102CA] # CARIAN LETTER MB +102CB ; [.3889.0020.0002.102CB] # CARIAN LETTER MB2 +102CC ; [.388A.0020.0002.102CC] # CARIAN LETTER MB3 +102CD ; [.388B.0020.0002.102CD] # CARIAN LETTER MB4 +102CE ; [.388C.0020.0002.102CE] # CARIAN LETTER LD2 +102CF ; [.388D.0020.0002.102CF] # CARIAN LETTER E2 +102D0 ; [.388E.0020.0002.102D0] # CARIAN LETTER UUU3 +10920 ; [.388F.0020.0002.10920] # LYDIAN LETTER A +10921 ; [.3890.0020.0002.10921] # LYDIAN LETTER B +10922 ; [.3891.0020.0002.10922] # LYDIAN LETTER G +10923 ; [.3892.0020.0002.10923] # LYDIAN LETTER D +10924 ; [.3893.0020.0002.10924] # LYDIAN LETTER E +10925 ; [.3894.0020.0002.10925] # LYDIAN LETTER V +10926 ; [.3895.0020.0002.10926] # LYDIAN LETTER I +10927 ; [.3896.0020.0002.10927] # LYDIAN LETTER Y +10928 ; [.3897.0020.0002.10928] # LYDIAN LETTER K +10929 ; [.3898.0020.0002.10929] # LYDIAN LETTER L +1092A ; [.3899.0020.0002.1092A] # LYDIAN LETTER M +1092B ; [.389A.0020.0002.1092B] # LYDIAN LETTER N +1092C ; [.389B.0020.0002.1092C] # LYDIAN LETTER O +1092D ; [.389C.0020.0002.1092D] # LYDIAN LETTER R +1092E ; [.389D.0020.0002.1092E] # LYDIAN LETTER SS +1092F ; [.389E.0020.0002.1092F] # LYDIAN LETTER T +10930 ; [.389F.0020.0002.10930] # LYDIAN LETTER U +10931 ; [.38A0.0020.0002.10931] # LYDIAN LETTER F +10932 ; [.38A1.0020.0002.10932] # LYDIAN LETTER Q +10933 ; [.38A2.0020.0002.10933] # LYDIAN LETTER S +10934 ; [.38A3.0020.0002.10934] # LYDIAN LETTER TT +10935 ; [.38A4.0020.0002.10935] # LYDIAN LETTER AN +10936 ; [.38A5.0020.0002.10936] # LYDIAN LETTER EN +10937 ; [.38A6.0020.0002.10937] # LYDIAN LETTER LY +10938 ; [.38A7.0020.0002.10938] # LYDIAN LETTER NN +10939 ; [.38A8.0020.0002.10939] # LYDIAN LETTER C +10300 ; [.38A9.0020.0002.10300] # OLD ITALIC LETTER A +10301 ; [.38AA.0020.0002.10301] # OLD ITALIC LETTER BE +10302 ; [.38AB.0020.0002.10302] # OLD ITALIC LETTER KE +10303 ; [.38AC.0020.0002.10303] # OLD ITALIC LETTER DE +10304 ; [.38AD.0020.0002.10304] # OLD ITALIC LETTER E +10305 ; [.38AE.0020.0002.10305] # OLD ITALIC LETTER VE +10306 ; [.38AF.0020.0002.10306] # OLD ITALIC LETTER ZE +10307 ; [.38B0.0020.0002.10307] # OLD ITALIC LETTER HE +10308 ; [.38B1.0020.0002.10308] # OLD ITALIC LETTER THE +10309 ; [.38B2.0020.0002.10309] # OLD ITALIC LETTER I +1030A ; [.38B3.0020.0002.1030A] # OLD ITALIC LETTER KA +1030B ; [.38B4.0020.0002.1030B] # OLD ITALIC LETTER EL +1030C ; [.38B5.0020.0002.1030C] # OLD ITALIC LETTER EM +1030D ; [.38B6.0020.0002.1030D] # OLD ITALIC LETTER EN +1030E ; [.38B7.0020.0002.1030E] # OLD ITALIC LETTER ESH +1030F ; [.38B8.0020.0002.1030F] # OLD ITALIC LETTER O +10310 ; [.38B9.0020.0002.10310] # OLD ITALIC LETTER PE +10311 ; [.38BA.0020.0002.10311] # OLD ITALIC LETTER SHE +10312 ; [.38BB.0020.0002.10312] # OLD ITALIC LETTER KU +10313 ; [.38BC.0020.0002.10313] # OLD ITALIC LETTER ER +10314 ; [.38BD.0020.0002.10314] # OLD ITALIC LETTER ES +10315 ; [.38BE.0020.0002.10315] # OLD ITALIC LETTER TE +10316 ; [.38BF.0020.0002.10316] # OLD ITALIC LETTER U +10317 ; [.38C0.0020.0002.10317] # OLD ITALIC LETTER EKS +10318 ; [.38C1.0020.0002.10318] # OLD ITALIC LETTER PHE +10319 ; [.38C2.0020.0002.10319] # OLD ITALIC LETTER KHE +1031A ; [.38C3.0020.0002.1031A] # OLD ITALIC LETTER EF +1031B ; [.38C4.0020.0002.1031B] # OLD ITALIC LETTER ERS +1031C ; [.38C5.0020.0002.1031C] # OLD ITALIC LETTER CHE +1031D ; [.38C6.0020.0002.1031D] # OLD ITALIC LETTER II +1031E ; [.38C7.0020.0002.1031E] # OLD ITALIC LETTER UU +10330 ; [.38C8.0020.0002.10330] # GOTHIC LETTER AHSA +10331 ; [.38C9.0020.0002.10331] # GOTHIC LETTER BAIRKAN +10332 ; [.38CA.0020.0002.10332] # GOTHIC LETTER GIBA +10333 ; [.38CB.0020.0002.10333] # GOTHIC LETTER DAGS +10334 ; [.38CC.0020.0002.10334] # GOTHIC LETTER AIHVUS +10335 ; [.38CD.0020.0002.10335] # GOTHIC LETTER QAIRTHRA +10336 ; [.38CE.0020.0002.10336] # GOTHIC LETTER IUJA +10337 ; [.38CF.0020.0002.10337] # GOTHIC LETTER HAGL +10338 ; [.38D0.0020.0002.10338] # GOTHIC LETTER THIUTH +10339 ; [.38D1.0020.0002.10339] # GOTHIC LETTER EIS +1033A ; [.38D2.0020.0002.1033A] # GOTHIC LETTER KUSMA +1033B ; [.38D3.0020.0002.1033B] # GOTHIC LETTER LAGUS +1033C ; [.38D4.0020.0002.1033C] # GOTHIC LETTER MANNA +1033D ; [.38D5.0020.0002.1033D] # GOTHIC LETTER NAUTHS +1033E ; [.38D6.0020.0002.1033E] # GOTHIC LETTER JER +1033F ; [.38D7.0020.0002.1033F] # GOTHIC LETTER URUS +10340 ; [.38D8.0020.0002.10340] # GOTHIC LETTER PAIRTHRA +10341 ; [.38D9.0020.0002.10341] # GOTHIC LETTER NINETY +10342 ; [.38DA.0020.0002.10342] # GOTHIC LETTER RAIDA +10343 ; [.38DB.0020.0002.10343] # GOTHIC LETTER SAUIL +10344 ; [.38DC.0020.0002.10344] # GOTHIC LETTER TEIWS +10345 ; [.38DD.0020.0002.10345] # GOTHIC LETTER WINJA +10346 ; [.38DE.0020.0002.10346] # GOTHIC LETTER FAIHU +10347 ; [.38DF.0020.0002.10347] # GOTHIC LETTER IGGWS +10348 ; [.38E0.0020.0002.10348] # GOTHIC LETTER HWAIR +10349 ; [.38E1.0020.0002.10349] # GOTHIC LETTER OTHAL +1034A ; [.38E2.0020.0002.1034A] # GOTHIC LETTER NINE HUNDRED +10428 ; [.38E3.0020.0002.10428] # DESERET SMALL LETTER LONG I +10400 ; [.38E3.0020.0008.10400] # DESERET CAPITAL LETTER LONG I +10429 ; [.38E4.0020.0002.10429] # DESERET SMALL LETTER LONG E +10401 ; [.38E4.0020.0008.10401] # DESERET CAPITAL LETTER LONG E +1042A ; [.38E5.0020.0002.1042A] # DESERET SMALL LETTER LONG A +10402 ; [.38E5.0020.0008.10402] # DESERET CAPITAL LETTER LONG A +1042B ; [.38E6.0020.0002.1042B] # DESERET SMALL LETTER LONG AH +10403 ; [.38E6.0020.0008.10403] # DESERET CAPITAL LETTER LONG AH +1042C ; [.38E7.0020.0002.1042C] # DESERET SMALL LETTER LONG O +10404 ; [.38E7.0020.0008.10404] # DESERET CAPITAL LETTER LONG O +1042D ; [.38E8.0020.0002.1042D] # DESERET SMALL LETTER LONG OO +10405 ; [.38E8.0020.0008.10405] # DESERET CAPITAL LETTER LONG OO +1042E ; [.38E9.0020.0002.1042E] # DESERET SMALL LETTER SHORT I +10406 ; [.38E9.0020.0008.10406] # DESERET CAPITAL LETTER SHORT I +1042F ; [.38EA.0020.0002.1042F] # DESERET SMALL LETTER SHORT E +10407 ; [.38EA.0020.0008.10407] # DESERET CAPITAL LETTER SHORT E +10430 ; [.38EB.0020.0002.10430] # DESERET SMALL LETTER SHORT A +10408 ; [.38EB.0020.0008.10408] # DESERET CAPITAL LETTER SHORT A +10431 ; [.38EC.0020.0002.10431] # DESERET SMALL LETTER SHORT AH +10409 ; [.38EC.0020.0008.10409] # DESERET CAPITAL LETTER SHORT AH +10432 ; [.38ED.0020.0002.10432] # DESERET SMALL LETTER SHORT O +1040A ; [.38ED.0020.0008.1040A] # DESERET CAPITAL LETTER SHORT O +10433 ; [.38EE.0020.0002.10433] # DESERET SMALL LETTER SHORT OO +1040B ; [.38EE.0020.0008.1040B] # DESERET CAPITAL LETTER SHORT OO +10434 ; [.38EF.0020.0002.10434] # DESERET SMALL LETTER AY +1040C ; [.38EF.0020.0008.1040C] # DESERET CAPITAL LETTER AY +10435 ; [.38F0.0020.0002.10435] # DESERET SMALL LETTER OW +1040D ; [.38F0.0020.0008.1040D] # DESERET CAPITAL LETTER OW +10436 ; [.38F1.0020.0002.10436] # DESERET SMALL LETTER WU +1040E ; [.38F1.0020.0008.1040E] # DESERET CAPITAL LETTER WU +10437 ; [.38F2.0020.0002.10437] # DESERET SMALL LETTER YEE +1040F ; [.38F2.0020.0008.1040F] # DESERET CAPITAL LETTER YEE +10438 ; [.38F3.0020.0002.10438] # DESERET SMALL LETTER H +10410 ; [.38F3.0020.0008.10410] # DESERET CAPITAL LETTER H +10439 ; [.38F4.0020.0002.10439] # DESERET SMALL LETTER PEE +10411 ; [.38F4.0020.0008.10411] # DESERET CAPITAL LETTER PEE +1043A ; [.38F5.0020.0002.1043A] # DESERET SMALL LETTER BEE +10412 ; [.38F5.0020.0008.10412] # DESERET CAPITAL LETTER BEE +1043B ; [.38F6.0020.0002.1043B] # DESERET SMALL LETTER TEE +10413 ; [.38F6.0020.0008.10413] # DESERET CAPITAL LETTER TEE +1043C ; [.38F7.0020.0002.1043C] # DESERET SMALL LETTER DEE +10414 ; [.38F7.0020.0008.10414] # DESERET CAPITAL LETTER DEE +1043D ; [.38F8.0020.0002.1043D] # DESERET SMALL LETTER CHEE +10415 ; [.38F8.0020.0008.10415] # DESERET CAPITAL LETTER CHEE +1043E ; [.38F9.0020.0002.1043E] # DESERET SMALL LETTER JEE +10416 ; [.38F9.0020.0008.10416] # DESERET CAPITAL LETTER JEE +1043F ; [.38FA.0020.0002.1043F] # DESERET SMALL LETTER KAY +10417 ; [.38FA.0020.0008.10417] # DESERET CAPITAL LETTER KAY +10440 ; [.38FB.0020.0002.10440] # DESERET SMALL LETTER GAY +10418 ; [.38FB.0020.0008.10418] # DESERET CAPITAL LETTER GAY +10441 ; [.38FC.0020.0002.10441] # DESERET SMALL LETTER EF +10419 ; [.38FC.0020.0008.10419] # DESERET CAPITAL LETTER EF +10442 ; [.38FD.0020.0002.10442] # DESERET SMALL LETTER VEE +1041A ; [.38FD.0020.0008.1041A] # DESERET CAPITAL LETTER VEE +10443 ; [.38FE.0020.0002.10443] # DESERET SMALL LETTER ETH +1041B ; [.38FE.0020.0008.1041B] # DESERET CAPITAL LETTER ETH +10444 ; [.38FF.0020.0002.10444] # DESERET SMALL LETTER THEE +1041C ; [.38FF.0020.0008.1041C] # DESERET CAPITAL LETTER THEE +10445 ; [.3900.0020.0002.10445] # DESERET SMALL LETTER ES +1041D ; [.3900.0020.0008.1041D] # DESERET CAPITAL LETTER ES +10446 ; [.3901.0020.0002.10446] # DESERET SMALL LETTER ZEE +1041E ; [.3901.0020.0008.1041E] # DESERET CAPITAL LETTER ZEE +10447 ; [.3902.0020.0002.10447] # DESERET SMALL LETTER ESH +1041F ; [.3902.0020.0008.1041F] # DESERET CAPITAL LETTER ESH +10448 ; [.3903.0020.0002.10448] # DESERET SMALL LETTER ZHEE +10420 ; [.3903.0020.0008.10420] # DESERET CAPITAL LETTER ZHEE +10449 ; [.3904.0020.0002.10449] # DESERET SMALL LETTER ER +10421 ; [.3904.0020.0008.10421] # DESERET CAPITAL LETTER ER +1044A ; [.3905.0020.0002.1044A] # DESERET SMALL LETTER EL +10422 ; [.3905.0020.0008.10422] # DESERET CAPITAL LETTER EL +1044B ; [.3906.0020.0002.1044B] # DESERET SMALL LETTER EM +10423 ; [.3906.0020.0008.10423] # DESERET CAPITAL LETTER EM +1044C ; [.3907.0020.0002.1044C] # DESERET SMALL LETTER EN +10424 ; [.3907.0020.0008.10424] # DESERET CAPITAL LETTER EN +1044D ; [.3908.0020.0002.1044D] # DESERET SMALL LETTER ENG +10425 ; [.3908.0020.0008.10425] # DESERET CAPITAL LETTER ENG +1044E ; [.3909.0020.0002.1044E] # DESERET SMALL LETTER OI +10426 ; [.3909.0020.0008.10426] # DESERET CAPITAL LETTER OI +1044F ; [.390A.0020.0002.1044F] # DESERET SMALL LETTER EW +10427 ; [.390A.0020.0008.10427] # DESERET CAPITAL LETTER EW +10450 ; [.390B.0020.0002.10450] # SHAVIAN LETTER PEEP +10451 ; [.390C.0020.0002.10451] # SHAVIAN LETTER TOT +10452 ; [.390D.0020.0002.10452] # SHAVIAN LETTER KICK +10453 ; [.390E.0020.0002.10453] # SHAVIAN LETTER FEE +10454 ; [.390F.0020.0002.10454] # SHAVIAN LETTER THIGH +10455 ; [.3910.0020.0002.10455] # SHAVIAN LETTER SO +10456 ; [.3911.0020.0002.10456] # SHAVIAN LETTER SURE +10457 ; [.3912.0020.0002.10457] # SHAVIAN LETTER CHURCH +10458 ; [.3913.0020.0002.10458] # SHAVIAN LETTER YEA +10459 ; [.3914.0020.0002.10459] # SHAVIAN LETTER HUNG +1045A ; [.3915.0020.0002.1045A] # SHAVIAN LETTER BIB +1045B ; [.3916.0020.0002.1045B] # SHAVIAN LETTER DEAD +1045C ; [.3917.0020.0002.1045C] # SHAVIAN LETTER GAG +1045D ; [.3918.0020.0002.1045D] # SHAVIAN LETTER VOW +1045E ; [.3919.0020.0002.1045E] # SHAVIAN LETTER THEY +1045F ; [.391A.0020.0002.1045F] # SHAVIAN LETTER ZOO +10460 ; [.391B.0020.0002.10460] # SHAVIAN LETTER MEASURE +10461 ; [.391C.0020.0002.10461] # SHAVIAN LETTER JUDGE +10462 ; [.391D.0020.0002.10462] # SHAVIAN LETTER WOE +10463 ; [.391E.0020.0002.10463] # SHAVIAN LETTER HA-HA +10464 ; [.391F.0020.0002.10464] # SHAVIAN LETTER LOLL +10465 ; [.3920.0020.0002.10465] # SHAVIAN LETTER MIME +10466 ; [.3921.0020.0002.10466] # SHAVIAN LETTER IF +10467 ; [.3922.0020.0002.10467] # SHAVIAN LETTER EGG +10468 ; [.3923.0020.0002.10468] # SHAVIAN LETTER ASH +10469 ; [.3924.0020.0002.10469] # SHAVIAN LETTER ADO +1046A ; [.3925.0020.0002.1046A] # SHAVIAN LETTER ON +1046B ; [.3926.0020.0002.1046B] # SHAVIAN LETTER WOOL +1046C ; [.3927.0020.0002.1046C] # SHAVIAN LETTER OUT +1046D ; [.3928.0020.0002.1046D] # SHAVIAN LETTER AH +1046E ; [.3929.0020.0002.1046E] # SHAVIAN LETTER ROAR +1046F ; [.392A.0020.0002.1046F] # SHAVIAN LETTER NUN +10470 ; [.392B.0020.0002.10470] # SHAVIAN LETTER EAT +10471 ; [.392C.0020.0002.10471] # SHAVIAN LETTER AGE +10472 ; [.392D.0020.0002.10472] # SHAVIAN LETTER ICE +10473 ; [.392E.0020.0002.10473] # SHAVIAN LETTER UP +10474 ; [.392F.0020.0002.10474] # SHAVIAN LETTER OAK +10475 ; [.3930.0020.0002.10475] # SHAVIAN LETTER OOZE +10476 ; [.3931.0020.0002.10476] # SHAVIAN LETTER OIL +10477 ; [.3932.0020.0002.10477] # SHAVIAN LETTER AWE +10478 ; [.3933.0020.0002.10478] # SHAVIAN LETTER ARE +10479 ; [.3934.0020.0002.10479] # SHAVIAN LETTER OR +1047A ; [.3935.0020.0002.1047A] # SHAVIAN LETTER AIR +1047B ; [.3936.0020.0002.1047B] # SHAVIAN LETTER ERR +1047C ; [.3937.0020.0002.1047C] # SHAVIAN LETTER ARRAY +1047D ; [.3938.0020.0002.1047D] # SHAVIAN LETTER EAR +1047E ; [.3939.0020.0002.1047E] # SHAVIAN LETTER IAN +1047F ; [.393A.0020.0002.1047F] # SHAVIAN LETTER YEW +10480 ; [.393B.0020.0002.10480] # OSMANYA LETTER ALEF +10481 ; [.393C.0020.0002.10481] # OSMANYA LETTER BA +10482 ; [.393D.0020.0002.10482] # OSMANYA LETTER TA +10483 ; [.393E.0020.0002.10483] # OSMANYA LETTER JA +10484 ; [.393F.0020.0002.10484] # OSMANYA LETTER XA +10485 ; [.3940.0020.0002.10485] # OSMANYA LETTER KHA +10486 ; [.3941.0020.0002.10486] # OSMANYA LETTER DEEL +10487 ; [.3942.0020.0002.10487] # OSMANYA LETTER RA +10488 ; [.3943.0020.0002.10488] # OSMANYA LETTER SA +10489 ; [.3944.0020.0002.10489] # OSMANYA LETTER SHIIN +1048A ; [.3945.0020.0002.1048A] # OSMANYA LETTER DHA +1048B ; [.3946.0020.0002.1048B] # OSMANYA LETTER CAYN +1048C ; [.3947.0020.0002.1048C] # OSMANYA LETTER GA +1048D ; [.3948.0020.0002.1048D] # OSMANYA LETTER FA +1048E ; [.3949.0020.0002.1048E] # OSMANYA LETTER QAAF +1048F ; [.394A.0020.0002.1048F] # OSMANYA LETTER KAAF +10490 ; [.394B.0020.0002.10490] # OSMANYA LETTER LAAN +10491 ; [.394C.0020.0002.10491] # OSMANYA LETTER MIIN +10492 ; [.394D.0020.0002.10492] # OSMANYA LETTER NUUN +10493 ; [.394E.0020.0002.10493] # OSMANYA LETTER WAW +10494 ; [.394F.0020.0002.10494] # OSMANYA LETTER HA +10495 ; [.3950.0020.0002.10495] # OSMANYA LETTER YA +10496 ; [.3951.0020.0002.10496] # OSMANYA LETTER A +10497 ; [.3952.0020.0002.10497] # OSMANYA LETTER E +10498 ; [.3953.0020.0002.10498] # OSMANYA LETTER I +10499 ; [.3954.0020.0002.10499] # OSMANYA LETTER O +1049A ; [.3955.0020.0002.1049A] # OSMANYA LETTER U +1049B ; [.3956.0020.0002.1049B] # OSMANYA LETTER AA +1049C ; [.3957.0020.0002.1049C] # OSMANYA LETTER EE +1049D ; [.3958.0020.0002.1049D] # OSMANYA LETTER OO +110D0 ; [.3959.0020.0002.110D0] # SORA SOMPENG LETTER SAH +110D1 ; [.395A.0020.0002.110D1] # SORA SOMPENG LETTER TAH +110D2 ; [.395B.0020.0002.110D2] # SORA SOMPENG LETTER BAH +110D3 ; [.395C.0020.0002.110D3] # SORA SOMPENG LETTER CAH +110D4 ; [.395D.0020.0002.110D4] # SORA SOMPENG LETTER DAH +110D5 ; [.395E.0020.0002.110D5] # SORA SOMPENG LETTER GAH +110D6 ; [.395F.0020.0002.110D6] # SORA SOMPENG LETTER MAH +110D7 ; [.3960.0020.0002.110D7] # SORA SOMPENG LETTER NGAH +110D8 ; [.3961.0020.0002.110D8] # SORA SOMPENG LETTER LAH +110D9 ; [.3962.0020.0002.110D9] # SORA SOMPENG LETTER NAH +110DA ; [.3963.0020.0002.110DA] # SORA SOMPENG LETTER VAH +110DB ; [.3964.0020.0002.110DB] # SORA SOMPENG LETTER PAH +110DC ; [.3965.0020.0002.110DC] # SORA SOMPENG LETTER YAH +110DD ; [.3966.0020.0002.110DD] # SORA SOMPENG LETTER RAH +110DE ; [.3967.0020.0002.110DE] # SORA SOMPENG LETTER HAH +110DF ; [.3968.0020.0002.110DF] # SORA SOMPENG LETTER KAH +110E0 ; [.3969.0020.0002.110E0] # SORA SOMPENG LETTER JAH +110E1 ; [.396A.0020.0002.110E1] # SORA SOMPENG LETTER NYAH +110E2 ; [.396B.0020.0002.110E2] # SORA SOMPENG LETTER AH +110E3 ; [.396C.0020.0002.110E3] # SORA SOMPENG LETTER EEH +110E4 ; [.396D.0020.0002.110E4] # SORA SOMPENG LETTER IH +110E5 ; [.396E.0020.0002.110E5] # SORA SOMPENG LETTER UH +110E6 ; [.396F.0020.0002.110E6] # SORA SOMPENG LETTER OH +110E7 ; [.3970.0020.0002.110E7] # SORA SOMPENG LETTER EH +110E8 ; [.3971.0020.0002.110E8] # SORA SOMPENG LETTER MAE +10000 ; [.3972.0020.0002.10000] # LINEAR B SYLLABLE B008 A +10001 ; [.3973.0020.0002.10001] # LINEAR B SYLLABLE B038 E +10002 ; [.3974.0020.0002.10002] # LINEAR B SYLLABLE B028 I +10003 ; [.3975.0020.0002.10003] # LINEAR B SYLLABLE B061 O +10004 ; [.3976.0020.0002.10004] # LINEAR B SYLLABLE B010 U +10005 ; [.3977.0020.0002.10005] # LINEAR B SYLLABLE B001 DA +10006 ; [.3978.0020.0002.10006] # LINEAR B SYLLABLE B045 DE +10007 ; [.3979.0020.0002.10007] # LINEAR B SYLLABLE B007 DI +10008 ; [.397A.0020.0002.10008] # LINEAR B SYLLABLE B014 DO +10009 ; [.397B.0020.0002.10009] # LINEAR B SYLLABLE B051 DU +1000A ; [.397C.0020.0002.1000A] # LINEAR B SYLLABLE B057 JA +1000B ; [.397D.0020.0002.1000B] # LINEAR B SYLLABLE B046 JE +1000D ; [.397E.0020.0002.1000D] # LINEAR B SYLLABLE B036 JO +1000E ; [.397F.0020.0002.1000E] # LINEAR B SYLLABLE B065 JU +1000F ; [.3980.0020.0002.1000F] # LINEAR B SYLLABLE B077 KA +10010 ; [.3981.0020.0002.10010] # LINEAR B SYLLABLE B044 KE +10011 ; [.3982.0020.0002.10011] # LINEAR B SYLLABLE B067 KI +10012 ; [.3983.0020.0002.10012] # LINEAR B SYLLABLE B070 KO +10013 ; [.3984.0020.0002.10013] # LINEAR B SYLLABLE B081 KU +10014 ; [.3985.0020.0002.10014] # LINEAR B SYLLABLE B080 MA +10015 ; [.3986.0020.0002.10015] # LINEAR B SYLLABLE B013 ME +10016 ; [.3987.0020.0002.10016] # LINEAR B SYLLABLE B073 MI +10017 ; [.3988.0020.0002.10017] # LINEAR B SYLLABLE B015 MO +10018 ; [.3989.0020.0002.10018] # LINEAR B SYLLABLE B023 MU +10019 ; [.398A.0020.0002.10019] # LINEAR B SYLLABLE B006 NA +1001A ; [.398B.0020.0002.1001A] # LINEAR B SYLLABLE B024 NE +1001B ; [.398C.0020.0002.1001B] # LINEAR B SYLLABLE B030 NI +1001C ; [.398D.0020.0002.1001C] # LINEAR B SYLLABLE B052 NO +1001D ; [.398E.0020.0002.1001D] # LINEAR B SYLLABLE B055 NU +1001E ; [.398F.0020.0002.1001E] # LINEAR B SYLLABLE B003 PA +1001F ; [.3990.0020.0002.1001F] # LINEAR B SYLLABLE B072 PE +10020 ; [.3991.0020.0002.10020] # LINEAR B SYLLABLE B039 PI +10021 ; [.3992.0020.0002.10021] # LINEAR B SYLLABLE B011 PO +10022 ; [.3993.0020.0002.10022] # LINEAR B SYLLABLE B050 PU +10023 ; [.3994.0020.0002.10023] # LINEAR B SYLLABLE B016 QA +10024 ; [.3995.0020.0002.10024] # LINEAR B SYLLABLE B078 QE +10025 ; [.3996.0020.0002.10025] # LINEAR B SYLLABLE B021 QI +10026 ; [.3997.0020.0002.10026] # LINEAR B SYLLABLE B032 QO +10028 ; [.3998.0020.0002.10028] # LINEAR B SYLLABLE B060 RA +10029 ; [.3999.0020.0002.10029] # LINEAR B SYLLABLE B027 RE +1002A ; [.399A.0020.0002.1002A] # LINEAR B SYLLABLE B053 RI +1002B ; [.399B.0020.0002.1002B] # LINEAR B SYLLABLE B002 RO +1002C ; [.399C.0020.0002.1002C] # LINEAR B SYLLABLE B026 RU +1002D ; [.399D.0020.0002.1002D] # LINEAR B SYLLABLE B031 SA +1002E ; [.399E.0020.0002.1002E] # LINEAR B SYLLABLE B009 SE +1002F ; [.399F.0020.0002.1002F] # LINEAR B SYLLABLE B041 SI +10030 ; [.39A0.0020.0002.10030] # LINEAR B SYLLABLE B012 SO +10031 ; [.39A1.0020.0002.10031] # LINEAR B SYLLABLE B058 SU +10032 ; [.39A2.0020.0002.10032] # LINEAR B SYLLABLE B059 TA +10033 ; [.39A3.0020.0002.10033] # LINEAR B SYLLABLE B004 TE +10034 ; [.39A4.0020.0002.10034] # LINEAR B SYLLABLE B037 TI +10035 ; [.39A5.0020.0002.10035] # LINEAR B SYLLABLE B005 TO +10036 ; [.39A6.0020.0002.10036] # LINEAR B SYLLABLE B069 TU +10037 ; [.39A7.0020.0002.10037] # LINEAR B SYLLABLE B054 WA +10038 ; [.39A8.0020.0002.10038] # LINEAR B SYLLABLE B075 WE +10039 ; [.39A9.0020.0002.10039] # LINEAR B SYLLABLE B040 WI +1003A ; [.39AA.0020.0002.1003A] # LINEAR B SYLLABLE B042 WO +1003C ; [.39AB.0020.0002.1003C] # LINEAR B SYLLABLE B017 ZA +1003D ; [.39AC.0020.0002.1003D] # LINEAR B SYLLABLE B074 ZE +1003F ; [.39AD.0020.0002.1003F] # LINEAR B SYLLABLE B020 ZO +10040 ; [.39AE.0020.0002.10040] # LINEAR B SYLLABLE B025 A2 +10041 ; [.39AF.0020.0002.10041] # LINEAR B SYLLABLE B043 A3 +10042 ; [.39B0.0020.0002.10042] # LINEAR B SYLLABLE B085 AU +10043 ; [.39B1.0020.0002.10043] # LINEAR B SYLLABLE B071 DWE +10044 ; [.39B2.0020.0002.10044] # LINEAR B SYLLABLE B090 DWO +10045 ; [.39B3.0020.0002.10045] # LINEAR B SYLLABLE B048 NWA +10046 ; [.39B4.0020.0002.10046] # LINEAR B SYLLABLE B029 PU2 +10047 ; [.39B5.0020.0002.10047] # LINEAR B SYLLABLE B062 PTE +10048 ; [.39B6.0020.0002.10048] # LINEAR B SYLLABLE B076 RA2 +10049 ; [.39B7.0020.0002.10049] # LINEAR B SYLLABLE B033 RA3 +1004A ; [.39B8.0020.0002.1004A] # LINEAR B SYLLABLE B068 RO2 +1004B ; [.39B9.0020.0002.1004B] # LINEAR B SYLLABLE B066 TA2 +1004C ; [.39BA.0020.0002.1004C] # LINEAR B SYLLABLE B087 TWE +1004D ; [.39BB.0020.0002.1004D] # LINEAR B SYLLABLE B091 TWO +10050 ; [.39BC.0020.0002.10050] # LINEAR B SYMBOL B018 +10051 ; [.39BD.0020.0002.10051] # LINEAR B SYMBOL B019 +10052 ; [.39BE.0020.0002.10052] # LINEAR B SYMBOL B022 +10053 ; [.39BF.0020.0002.10053] # LINEAR B SYMBOL B034 +10054 ; [.39C0.0020.0002.10054] # LINEAR B SYMBOL B047 +10055 ; [.39C1.0020.0002.10055] # LINEAR B SYMBOL B049 +10056 ; [.39C2.0020.0002.10056] # LINEAR B SYMBOL B056 +10057 ; [.39C3.0020.0002.10057] # LINEAR B SYMBOL B063 +10058 ; [.39C4.0020.0002.10058] # LINEAR B SYMBOL B064 +10059 ; [.39C5.0020.0002.10059] # LINEAR B SYMBOL B079 +1005A ; [.39C6.0020.0002.1005A] # LINEAR B SYMBOL B082 +1005B ; [.39C7.0020.0002.1005B] # LINEAR B SYMBOL B083 +1005C ; [.39C8.0020.0002.1005C] # LINEAR B SYMBOL B086 +1005D ; [.39C9.0020.0002.1005D] # LINEAR B SYMBOL B089 +10080 ; [.39CA.0020.0002.10080] # LINEAR B IDEOGRAM B100 MAN +10081 ; [.39CB.0020.0002.10081] # LINEAR B IDEOGRAM B102 WOMAN +10082 ; [.39CC.0020.0002.10082] # LINEAR B IDEOGRAM B104 DEER +10083 ; [.39CD.0020.0002.10083] # LINEAR B IDEOGRAM B105 EQUID +10084 ; [.39CE.0020.0002.10084] # LINEAR B IDEOGRAM B105F MARE +10085 ; [.39CF.0020.0002.10085] # LINEAR B IDEOGRAM B105M STALLION +10086 ; [.39D0.0020.0002.10086] # LINEAR B IDEOGRAM B106F EWE +10087 ; [.39D1.0020.0002.10087] # LINEAR B IDEOGRAM B106M RAM +10088 ; [.39D2.0020.0002.10088] # LINEAR B IDEOGRAM B107F SHE-GOAT +10089 ; [.39D3.0020.0002.10089] # LINEAR B IDEOGRAM B107M HE-GOAT +1008A ; [.39D4.0020.0002.1008A] # LINEAR B IDEOGRAM B108F SOW +1008B ; [.39D5.0020.0002.1008B] # LINEAR B IDEOGRAM B108M BOAR +1008C ; [.39D6.0020.0002.1008C] # LINEAR B IDEOGRAM B109F COW +1008D ; [.39D7.0020.0002.1008D] # LINEAR B IDEOGRAM B109M BULL +1008E ; [.39D8.0020.0002.1008E] # LINEAR B IDEOGRAM B120 WHEAT +1008F ; [.39D9.0020.0002.1008F] # LINEAR B IDEOGRAM B121 BARLEY +10090 ; [.39DA.0020.0002.10090] # LINEAR B IDEOGRAM B122 OLIVE +10091 ; [.39DB.0020.0002.10091] # LINEAR B IDEOGRAM B123 SPICE +10092 ; [.39DC.0020.0002.10092] # LINEAR B IDEOGRAM B125 CYPERUS +10093 ; [.39DD.0020.0002.10093] # LINEAR B MONOGRAM B127 KAPO +10094 ; [.39DE.0020.0002.10094] # LINEAR B MONOGRAM B128 KANAKO +10095 ; [.39DF.0020.0002.10095] # LINEAR B IDEOGRAM B130 OIL +10096 ; [.39E0.0020.0002.10096] # LINEAR B IDEOGRAM B131 WINE +10097 ; [.39E1.0020.0002.10097] # LINEAR B IDEOGRAM B132 +10098 ; [.39E2.0020.0002.10098] # LINEAR B MONOGRAM B133 AREPA +10099 ; [.39E3.0020.0002.10099] # LINEAR B MONOGRAM B135 MERI +1009A ; [.39E4.0020.0002.1009A] # LINEAR B IDEOGRAM B140 BRONZE +1009B ; [.39E5.0020.0002.1009B] # LINEAR B IDEOGRAM B141 GOLD +1009C ; [.39E6.0020.0002.1009C] # LINEAR B IDEOGRAM B142 +1009D ; [.39E7.0020.0002.1009D] # LINEAR B IDEOGRAM B145 WOOL +1009E ; [.39E8.0020.0002.1009E] # LINEAR B IDEOGRAM B146 +1009F ; [.39E9.0020.0002.1009F] # LINEAR B IDEOGRAM B150 +100A0 ; [.39EA.0020.0002.100A0] # LINEAR B IDEOGRAM B151 HORN +100A1 ; [.39EB.0020.0002.100A1] # LINEAR B IDEOGRAM B152 +100A2 ; [.39EC.0020.0002.100A2] # LINEAR B IDEOGRAM B153 +100A3 ; [.39ED.0020.0002.100A3] # LINEAR B IDEOGRAM B154 +100A4 ; [.39EE.0020.0002.100A4] # LINEAR B MONOGRAM B156 TURO2 +100A5 ; [.39EF.0020.0002.100A5] # LINEAR B IDEOGRAM B157 +100A6 ; [.39F0.0020.0002.100A6] # LINEAR B IDEOGRAM B158 +100A7 ; [.39F1.0020.0002.100A7] # LINEAR B IDEOGRAM B159 CLOTH +100A8 ; [.39F2.0020.0002.100A8] # LINEAR B IDEOGRAM B160 +100A9 ; [.39F3.0020.0002.100A9] # LINEAR B IDEOGRAM B161 +100AA ; [.39F4.0020.0002.100AA] # LINEAR B IDEOGRAM B162 GARMENT +100AB ; [.39F5.0020.0002.100AB] # LINEAR B IDEOGRAM B163 ARMOUR +100AC ; [.39F6.0020.0002.100AC] # LINEAR B IDEOGRAM B164 +100AD ; [.39F7.0020.0002.100AD] # LINEAR B IDEOGRAM B165 +100AE ; [.39F8.0020.0002.100AE] # LINEAR B IDEOGRAM B166 +100AF ; [.39F9.0020.0002.100AF] # LINEAR B IDEOGRAM B167 +100B0 ; [.39FA.0020.0002.100B0] # LINEAR B IDEOGRAM B168 +100B1 ; [.39FB.0020.0002.100B1] # LINEAR B IDEOGRAM B169 +100B2 ; [.39FC.0020.0002.100B2] # LINEAR B IDEOGRAM B170 +100B3 ; [.39FD.0020.0002.100B3] # LINEAR B IDEOGRAM B171 +100B4 ; [.39FE.0020.0002.100B4] # LINEAR B IDEOGRAM B172 +100B5 ; [.39FF.0020.0002.100B5] # LINEAR B IDEOGRAM B173 MONTH +100B6 ; [.3A00.0020.0002.100B6] # LINEAR B IDEOGRAM B174 +100B7 ; [.3A01.0020.0002.100B7] # LINEAR B IDEOGRAM B176 TREE +100B8 ; [.3A02.0020.0002.100B8] # LINEAR B IDEOGRAM B177 +100B9 ; [.3A03.0020.0002.100B9] # LINEAR B IDEOGRAM B178 +100BA ; [.3A04.0020.0002.100BA] # LINEAR B IDEOGRAM B179 +100BB ; [.3A05.0020.0002.100BB] # LINEAR B IDEOGRAM B180 +100BC ; [.3A06.0020.0002.100BC] # LINEAR B IDEOGRAM B181 +100BD ; [.3A07.0020.0002.100BD] # LINEAR B IDEOGRAM B182 +100BE ; [.3A08.0020.0002.100BE] # LINEAR B IDEOGRAM B183 +100BF ; [.3A09.0020.0002.100BF] # LINEAR B IDEOGRAM B184 +100C0 ; [.3A0A.0020.0002.100C0] # LINEAR B IDEOGRAM B185 +100C1 ; [.3A0B.0020.0002.100C1] # LINEAR B IDEOGRAM B189 +100C2 ; [.3A0C.0020.0002.100C2] # LINEAR B IDEOGRAM B190 +100C3 ; [.3A0D.0020.0002.100C3] # LINEAR B IDEOGRAM B191 HELMET +100C4 ; [.3A0E.0020.0002.100C4] # LINEAR B IDEOGRAM B220 FOOTSTOOL +100C5 ; [.3A0F.0020.0002.100C5] # LINEAR B IDEOGRAM B225 BATHTUB +100C6 ; [.3A10.0020.0002.100C6] # LINEAR B IDEOGRAM B230 SPEAR +100C7 ; [.3A11.0020.0002.100C7] # LINEAR B IDEOGRAM B231 ARROW +100C8 ; [.3A12.0020.0002.100C8] # LINEAR B IDEOGRAM B232 +100C9 ; [.3A13.0020.0002.100C9] # LINEAR B IDEOGRAM B233 SWORD +100CA ; [.3A14.0020.0002.100CA] # LINEAR B IDEOGRAM B234 +100CB ; [.3A15.0020.0002.100CB] # LINEAR B IDEOGRAM B236 +100CC ; [.3A16.0020.0002.100CC] # LINEAR B IDEOGRAM B240 WHEELED CHARIOT +100CD ; [.3A17.0020.0002.100CD] # LINEAR B IDEOGRAM B241 CHARIOT +100CE ; [.3A18.0020.0002.100CE] # LINEAR B IDEOGRAM B242 CHARIOT FRAME +100CF ; [.3A19.0020.0002.100CF] # LINEAR B IDEOGRAM B243 WHEEL +100D0 ; [.3A1A.0020.0002.100D0] # LINEAR B IDEOGRAM B245 +100D1 ; [.3A1B.0020.0002.100D1] # LINEAR B IDEOGRAM B246 +100D2 ; [.3A1C.0020.0002.100D2] # LINEAR B MONOGRAM B247 DIPTE +100D3 ; [.3A1D.0020.0002.100D3] # LINEAR B IDEOGRAM B248 +100D4 ; [.3A1E.0020.0002.100D4] # LINEAR B IDEOGRAM B249 +100D5 ; [.3A1F.0020.0002.100D5] # LINEAR B IDEOGRAM B251 +100D6 ; [.3A20.0020.0002.100D6] # LINEAR B IDEOGRAM B252 +100D7 ; [.3A21.0020.0002.100D7] # LINEAR B IDEOGRAM B253 +100D8 ; [.3A22.0020.0002.100D8] # LINEAR B IDEOGRAM B254 DART +100D9 ; [.3A23.0020.0002.100D9] # LINEAR B IDEOGRAM B255 +100DA ; [.3A24.0020.0002.100DA] # LINEAR B IDEOGRAM B256 +100DB ; [.3A25.0020.0002.100DB] # LINEAR B IDEOGRAM B257 +100DC ; [.3A26.0020.0002.100DC] # LINEAR B IDEOGRAM B258 +100DD ; [.3A27.0020.0002.100DD] # LINEAR B IDEOGRAM B259 +100DE ; [.3A28.0020.0002.100DE] # LINEAR B IDEOGRAM VESSEL B155 +100DF ; [.3A29.0020.0002.100DF] # LINEAR B IDEOGRAM VESSEL B200 +100E0 ; [.3A2A.0020.0002.100E0] # LINEAR B IDEOGRAM VESSEL B201 +100E1 ; [.3A2B.0020.0002.100E1] # LINEAR B IDEOGRAM VESSEL B202 +100E2 ; [.3A2C.0020.0002.100E2] # LINEAR B IDEOGRAM VESSEL B203 +100E3 ; [.3A2D.0020.0002.100E3] # LINEAR B IDEOGRAM VESSEL B204 +100E4 ; [.3A2E.0020.0002.100E4] # LINEAR B IDEOGRAM VESSEL B205 +100E5 ; [.3A2F.0020.0002.100E5] # LINEAR B IDEOGRAM VESSEL B206 +100E6 ; [.3A30.0020.0002.100E6] # LINEAR B IDEOGRAM VESSEL B207 +100E7 ; [.3A31.0020.0002.100E7] # LINEAR B IDEOGRAM VESSEL B208 +100E8 ; [.3A32.0020.0002.100E8] # LINEAR B IDEOGRAM VESSEL B209 +100E9 ; [.3A33.0020.0002.100E9] # LINEAR B IDEOGRAM VESSEL B210 +100EA ; [.3A34.0020.0002.100EA] # LINEAR B IDEOGRAM VESSEL B211 +100EB ; [.3A35.0020.0002.100EB] # LINEAR B IDEOGRAM VESSEL B212 +100EC ; [.3A36.0020.0002.100EC] # LINEAR B IDEOGRAM VESSEL B213 +100ED ; [.3A37.0020.0002.100ED] # LINEAR B IDEOGRAM VESSEL B214 +100EE ; [.3A38.0020.0002.100EE] # LINEAR B IDEOGRAM VESSEL B215 +100EF ; [.3A39.0020.0002.100EF] # LINEAR B IDEOGRAM VESSEL B216 +100F0 ; [.3A3A.0020.0002.100F0] # LINEAR B IDEOGRAM VESSEL B217 +100F1 ; [.3A3B.0020.0002.100F1] # LINEAR B IDEOGRAM VESSEL B218 +100F2 ; [.3A3C.0020.0002.100F2] # LINEAR B IDEOGRAM VESSEL B219 +100F3 ; [.3A3D.0020.0002.100F3] # LINEAR B IDEOGRAM VESSEL B221 +100F4 ; [.3A3E.0020.0002.100F4] # LINEAR B IDEOGRAM VESSEL B222 +100F5 ; [.3A3F.0020.0002.100F5] # LINEAR B IDEOGRAM VESSEL B226 +100F6 ; [.3A40.0020.0002.100F6] # LINEAR B IDEOGRAM VESSEL B227 +100F7 ; [.3A41.0020.0002.100F7] # LINEAR B IDEOGRAM VESSEL B228 +100F8 ; [.3A42.0020.0002.100F8] # LINEAR B IDEOGRAM VESSEL B229 +100F9 ; [.3A43.0020.0002.100F9] # LINEAR B IDEOGRAM VESSEL B250 +100FA ; [.3A44.0020.0002.100FA] # LINEAR B IDEOGRAM VESSEL B305 +10800 ; [.3A45.0020.0002.10800] # CYPRIOT SYLLABLE A +10801 ; [.3A46.0020.0002.10801] # CYPRIOT SYLLABLE E +10802 ; [.3A47.0020.0002.10802] # CYPRIOT SYLLABLE I +10803 ; [.3A48.0020.0002.10803] # CYPRIOT SYLLABLE O +10804 ; [.3A49.0020.0002.10804] # CYPRIOT SYLLABLE U +10805 ; [.3A4A.0020.0002.10805] # CYPRIOT SYLLABLE JA +10808 ; [.3A4B.0020.0002.10808] # CYPRIOT SYLLABLE JO +1080A ; [.3A4C.0020.0002.1080A] # CYPRIOT SYLLABLE KA +1080B ; [.3A4D.0020.0002.1080B] # CYPRIOT SYLLABLE KE +1080C ; [.3A4E.0020.0002.1080C] # CYPRIOT SYLLABLE KI +1080D ; [.3A4F.0020.0002.1080D] # CYPRIOT SYLLABLE KO +1080E ; [.3A50.0020.0002.1080E] # CYPRIOT SYLLABLE KU +1080F ; [.3A51.0020.0002.1080F] # CYPRIOT SYLLABLE LA +10810 ; [.3A52.0020.0002.10810] # CYPRIOT SYLLABLE LE +10811 ; [.3A53.0020.0002.10811] # CYPRIOT SYLLABLE LI +10812 ; [.3A54.0020.0002.10812] # CYPRIOT SYLLABLE LO +10813 ; [.3A55.0020.0002.10813] # CYPRIOT SYLLABLE LU +10814 ; [.3A56.0020.0002.10814] # CYPRIOT SYLLABLE MA +10815 ; [.3A57.0020.0002.10815] # CYPRIOT SYLLABLE ME +10816 ; [.3A58.0020.0002.10816] # CYPRIOT SYLLABLE MI +10817 ; [.3A59.0020.0002.10817] # CYPRIOT SYLLABLE MO +10818 ; [.3A5A.0020.0002.10818] # CYPRIOT SYLLABLE MU +10819 ; [.3A5B.0020.0002.10819] # CYPRIOT SYLLABLE NA +1081A ; [.3A5C.0020.0002.1081A] # CYPRIOT SYLLABLE NE +1081B ; [.3A5D.0020.0002.1081B] # CYPRIOT SYLLABLE NI +1081C ; [.3A5E.0020.0002.1081C] # CYPRIOT SYLLABLE NO +1081D ; [.3A5F.0020.0002.1081D] # CYPRIOT SYLLABLE NU +1081E ; [.3A60.0020.0002.1081E] # CYPRIOT SYLLABLE PA +1081F ; [.3A61.0020.0002.1081F] # CYPRIOT SYLLABLE PE +10820 ; [.3A62.0020.0002.10820] # CYPRIOT SYLLABLE PI +10821 ; [.3A63.0020.0002.10821] # CYPRIOT SYLLABLE PO +10822 ; [.3A64.0020.0002.10822] # CYPRIOT SYLLABLE PU +10823 ; [.3A65.0020.0002.10823] # CYPRIOT SYLLABLE RA +10824 ; [.3A66.0020.0002.10824] # CYPRIOT SYLLABLE RE +10825 ; [.3A67.0020.0002.10825] # CYPRIOT SYLLABLE RI +10826 ; [.3A68.0020.0002.10826] # CYPRIOT SYLLABLE RO +10827 ; [.3A69.0020.0002.10827] # CYPRIOT SYLLABLE RU +10828 ; [.3A6A.0020.0002.10828] # CYPRIOT SYLLABLE SA +10829 ; [.3A6B.0020.0002.10829] # CYPRIOT SYLLABLE SE +1082A ; [.3A6C.0020.0002.1082A] # CYPRIOT SYLLABLE SI +1082B ; [.3A6D.0020.0002.1082B] # CYPRIOT SYLLABLE SO +1082C ; [.3A6E.0020.0002.1082C] # CYPRIOT SYLLABLE SU +1082D ; [.3A6F.0020.0002.1082D] # CYPRIOT SYLLABLE TA +1082E ; [.3A70.0020.0002.1082E] # CYPRIOT SYLLABLE TE +1082F ; [.3A71.0020.0002.1082F] # CYPRIOT SYLLABLE TI +10830 ; [.3A72.0020.0002.10830] # CYPRIOT SYLLABLE TO +10831 ; [.3A73.0020.0002.10831] # CYPRIOT SYLLABLE TU +10832 ; [.3A74.0020.0002.10832] # CYPRIOT SYLLABLE WA +10833 ; [.3A75.0020.0002.10833] # CYPRIOT SYLLABLE WE +10834 ; [.3A76.0020.0002.10834] # CYPRIOT SYLLABLE WI +10835 ; [.3A77.0020.0002.10835] # CYPRIOT SYLLABLE WO +10837 ; [.3A78.0020.0002.10837] # CYPRIOT SYLLABLE XA +10838 ; [.3A79.0020.0002.10838] # CYPRIOT SYLLABLE XE +1083C ; [.3A7A.0020.0002.1083C] # CYPRIOT SYLLABLE ZA +1083F ; [.3A7B.0020.0002.1083F] # CYPRIOT SYLLABLE ZO +10A60 ; [.3A7C.0020.0002.10A60] # OLD SOUTH ARABIAN LETTER HE +10A61 ; [.3A7D.0020.0002.10A61] # OLD SOUTH ARABIAN LETTER LAMEDH +10A62 ; [.3A7E.0020.0002.10A62] # OLD SOUTH ARABIAN LETTER HETH +10A63 ; [.3A7F.0020.0002.10A63] # OLD SOUTH ARABIAN LETTER MEM +10A64 ; [.3A80.0020.0002.10A64] # OLD SOUTH ARABIAN LETTER QOPH +10A65 ; [.3A81.0020.0002.10A65] # OLD SOUTH ARABIAN LETTER WAW +10A66 ; [.3A82.0020.0002.10A66] # OLD SOUTH ARABIAN LETTER SHIN +10A67 ; [.3A83.0020.0002.10A67] # OLD SOUTH ARABIAN LETTER RESH +10A68 ; [.3A84.0020.0002.10A68] # OLD SOUTH ARABIAN LETTER BETH +10A69 ; [.3A85.0020.0002.10A69] # OLD SOUTH ARABIAN LETTER TAW +10A6A ; [.3A86.0020.0002.10A6A] # OLD SOUTH ARABIAN LETTER SAT +10A6B ; [.3A87.0020.0002.10A6B] # OLD SOUTH ARABIAN LETTER KAPH +10A6C ; [.3A88.0020.0002.10A6C] # OLD SOUTH ARABIAN LETTER NUN +10A6D ; [.3A89.0020.0002.10A6D] # OLD SOUTH ARABIAN LETTER KHETH +10A6E ; [.3A8A.0020.0002.10A6E] # OLD SOUTH ARABIAN LETTER SADHE +10A6F ; [.3A8B.0020.0002.10A6F] # OLD SOUTH ARABIAN LETTER SAMEKH +10A70 ; [.3A8C.0020.0002.10A70] # OLD SOUTH ARABIAN LETTER FE +10A71 ; [.3A8D.0020.0002.10A71] # OLD SOUTH ARABIAN LETTER ALEF +10A72 ; [.3A8E.0020.0002.10A72] # OLD SOUTH ARABIAN LETTER AYN +10A73 ; [.3A8F.0020.0002.10A73] # OLD SOUTH ARABIAN LETTER DHADHE +10A74 ; [.3A90.0020.0002.10A74] # OLD SOUTH ARABIAN LETTER GIMEL +10A75 ; [.3A91.0020.0002.10A75] # OLD SOUTH ARABIAN LETTER DALETH +10A76 ; [.3A92.0020.0002.10A76] # OLD SOUTH ARABIAN LETTER GHAYN +10A77 ; [.3A93.0020.0002.10A77] # OLD SOUTH ARABIAN LETTER TETH +10A78 ; [.3A94.0020.0002.10A78] # OLD SOUTH ARABIAN LETTER ZAYN +10A79 ; [.3A95.0020.0002.10A79] # OLD SOUTH ARABIAN LETTER DHALETH +10A7A ; [.3A96.0020.0002.10A7A] # OLD SOUTH ARABIAN LETTER YODH +10A7B ; [.3A97.0020.0002.10A7B] # OLD SOUTH ARABIAN LETTER THAW +10A7C ; [.3A98.0020.0002.10A7C] # OLD SOUTH ARABIAN LETTER THETH +10B00 ; [.3A99.0020.0002.10B00] # AVESTAN LETTER A +10B01 ; [.3A9A.0020.0002.10B01] # AVESTAN LETTER AA +10B02 ; [.3A9B.0020.0002.10B02] # AVESTAN LETTER AO +10B03 ; [.3A9C.0020.0002.10B03] # AVESTAN LETTER AAO +10B04 ; [.3A9D.0020.0002.10B04] # AVESTAN LETTER AN +10B05 ; [.3A9E.0020.0002.10B05] # AVESTAN LETTER AAN +10B06 ; [.3A9F.0020.0002.10B06] # AVESTAN LETTER AE +10B07 ; [.3AA0.0020.0002.10B07] # AVESTAN LETTER AEE +10B08 ; [.3AA1.0020.0002.10B08] # AVESTAN LETTER E +10B09 ; [.3AA2.0020.0002.10B09] # AVESTAN LETTER EE +10B0A ; [.3AA3.0020.0002.10B0A] # AVESTAN LETTER O +10B0B ; [.3AA4.0020.0002.10B0B] # AVESTAN LETTER OO +10B0C ; [.3AA5.0020.0002.10B0C] # AVESTAN LETTER I +10B0D ; [.3AA6.0020.0002.10B0D] # AVESTAN LETTER II +10B0E ; [.3AA7.0020.0002.10B0E] # AVESTAN LETTER U +10B0F ; [.3AA8.0020.0002.10B0F] # AVESTAN LETTER UU +10B10 ; [.3AA9.0020.0002.10B10] # AVESTAN LETTER KE +10B11 ; [.3AAA.0020.0002.10B11] # AVESTAN LETTER XE +10B12 ; [.3AAB.0020.0002.10B12] # AVESTAN LETTER XYE +10B13 ; [.3AAC.0020.0002.10B13] # AVESTAN LETTER XVE +10B14 ; [.3AAD.0020.0002.10B14] # AVESTAN LETTER GE +10B15 ; [.3AAE.0020.0002.10B15] # AVESTAN LETTER GGE +10B16 ; [.3AAF.0020.0002.10B16] # AVESTAN LETTER GHE +10B17 ; [.3AB0.0020.0002.10B17] # AVESTAN LETTER CE +10B18 ; [.3AB1.0020.0002.10B18] # AVESTAN LETTER JE +10B19 ; [.3AB2.0020.0002.10B19] # AVESTAN LETTER TE +10B1A ; [.3AB3.0020.0002.10B1A] # AVESTAN LETTER THE +10B1B ; [.3AB4.0020.0002.10B1B] # AVESTAN LETTER DE +10B1C ; [.3AB5.0020.0002.10B1C] # AVESTAN LETTER DHE +10B1D ; [.3AB6.0020.0002.10B1D] # AVESTAN LETTER TTE +10B1E ; [.3AB7.0020.0002.10B1E] # AVESTAN LETTER PE +10B1F ; [.3AB8.0020.0002.10B1F] # AVESTAN LETTER FE +10B20 ; [.3AB9.0020.0002.10B20] # AVESTAN LETTER BE +10B21 ; [.3ABA.0020.0002.10B21] # AVESTAN LETTER BHE +10B22 ; [.3ABB.0020.0002.10B22] # AVESTAN LETTER NGE +10B23 ; [.3ABC.0020.0002.10B23] # AVESTAN LETTER NGYE +10B24 ; [.3ABD.0020.0002.10B24] # AVESTAN LETTER NGVE +10B25 ; [.3ABE.0020.0002.10B25] # AVESTAN LETTER NE +10B26 ; [.3ABF.0020.0002.10B26] # AVESTAN LETTER NYE +10B27 ; [.3AC0.0020.0002.10B27] # AVESTAN LETTER NNE +10B28 ; [.3AC1.0020.0002.10B28] # AVESTAN LETTER ME +10B29 ; [.3AC2.0020.0002.10B29] # AVESTAN LETTER HME +10B2A ; [.3AC3.0020.0002.10B2A] # AVESTAN LETTER YYE +10B2B ; [.3AC4.0020.0002.10B2B] # AVESTAN LETTER YE +10B2C ; [.3AC5.0020.0002.10B2C] # AVESTAN LETTER VE +10B2D ; [.3AC6.0020.0002.10B2D] # AVESTAN LETTER RE +10B2E ; [.3AC6.0020.0004.10B2E][.0000.0139.0004.10B2E] # AVESTAN LETTER LE +10B2F ; [.3AC7.0020.0002.10B2F] # AVESTAN LETTER SE +10B30 ; [.3AC8.0020.0002.10B30] # AVESTAN LETTER ZE +10B31 ; [.3AC9.0020.0002.10B31] # AVESTAN LETTER SHE +10B32 ; [.3ACA.0020.0002.10B32] # AVESTAN LETTER ZHE +10B33 ; [.3ACB.0020.0002.10B33] # AVESTAN LETTER SHYE +10B34 ; [.3ACC.0020.0002.10B34] # AVESTAN LETTER SSHE +10B35 ; [.3ACD.0020.0002.10B35] # AVESTAN LETTER HE +10840 ; [.3ACE.0020.0002.10840] # IMPERIAL ARAMAIC LETTER ALEPH +10841 ; [.3ACF.0020.0002.10841] # IMPERIAL ARAMAIC LETTER BETH +10842 ; [.3AD0.0020.0002.10842] # IMPERIAL ARAMAIC LETTER GIMEL +10843 ; [.3AD1.0020.0002.10843] # IMPERIAL ARAMAIC LETTER DALETH +10844 ; [.3AD2.0020.0002.10844] # IMPERIAL ARAMAIC LETTER HE +10845 ; [.3AD3.0020.0002.10845] # IMPERIAL ARAMAIC LETTER WAW +10846 ; [.3AD4.0020.0002.10846] # IMPERIAL ARAMAIC LETTER ZAYIN +10847 ; [.3AD5.0020.0002.10847] # IMPERIAL ARAMAIC LETTER HETH +10848 ; [.3AD6.0020.0002.10848] # IMPERIAL ARAMAIC LETTER TETH +10849 ; [.3AD7.0020.0002.10849] # IMPERIAL ARAMAIC LETTER YODH +1084A ; [.3AD8.0020.0002.1084A] # IMPERIAL ARAMAIC LETTER KAPH +1084B ; [.3AD9.0020.0002.1084B] # IMPERIAL ARAMAIC LETTER LAMEDH +1084C ; [.3ADA.0020.0002.1084C] # IMPERIAL ARAMAIC LETTER MEM +1084D ; [.3ADB.0020.0002.1084D] # IMPERIAL ARAMAIC LETTER NUN +1084E ; [.3ADC.0020.0002.1084E] # IMPERIAL ARAMAIC LETTER SAMEKH +1084F ; [.3ADD.0020.0002.1084F] # IMPERIAL ARAMAIC LETTER AYIN +10850 ; [.3ADE.0020.0002.10850] # IMPERIAL ARAMAIC LETTER PE +10851 ; [.3ADF.0020.0002.10851] # IMPERIAL ARAMAIC LETTER SADHE +10852 ; [.3AE0.0020.0002.10852] # IMPERIAL ARAMAIC LETTER QOPH +10853 ; [.3AE1.0020.0002.10853] # IMPERIAL ARAMAIC LETTER RESH +10854 ; [.3AE2.0020.0002.10854] # IMPERIAL ARAMAIC LETTER SHIN +10855 ; [.3AE3.0020.0002.10855] # IMPERIAL ARAMAIC LETTER TAW +10B40 ; [.3AE4.0020.0002.10B40] # INSCRIPTIONAL PARTHIAN LETTER ALEPH +10B41 ; [.3AE5.0020.0002.10B41] # INSCRIPTIONAL PARTHIAN LETTER BETH +10B42 ; [.3AE6.0020.0002.10B42] # INSCRIPTIONAL PARTHIAN LETTER GIMEL +10B43 ; [.3AE7.0020.0002.10B43] # INSCRIPTIONAL PARTHIAN LETTER DALETH +10B44 ; [.3AE8.0020.0002.10B44] # INSCRIPTIONAL PARTHIAN LETTER HE +10B45 ; [.3AE9.0020.0002.10B45] # INSCRIPTIONAL PARTHIAN LETTER WAW +10B46 ; [.3AEA.0020.0002.10B46] # INSCRIPTIONAL PARTHIAN LETTER ZAYIN +10B47 ; [.3AEB.0020.0002.10B47] # INSCRIPTIONAL PARTHIAN LETTER HETH +10B48 ; [.3AEC.0020.0002.10B48] # INSCRIPTIONAL PARTHIAN LETTER TETH +10B49 ; [.3AED.0020.0002.10B49] # INSCRIPTIONAL PARTHIAN LETTER YODH +10B4A ; [.3AEE.0020.0002.10B4A] # INSCRIPTIONAL PARTHIAN LETTER KAPH +10B4B ; [.3AEF.0020.0002.10B4B] # INSCRIPTIONAL PARTHIAN LETTER LAMEDH +10B4C ; [.3AF0.0020.0002.10B4C] # INSCRIPTIONAL PARTHIAN LETTER MEM +10B4D ; [.3AF1.0020.0002.10B4D] # INSCRIPTIONAL PARTHIAN LETTER NUN +10B4E ; [.3AF2.0020.0002.10B4E] # INSCRIPTIONAL PARTHIAN LETTER SAMEKH +10B4F ; [.3AF3.0020.0002.10B4F] # INSCRIPTIONAL PARTHIAN LETTER AYIN +10B50 ; [.3AF4.0020.0002.10B50] # INSCRIPTIONAL PARTHIAN LETTER PE +10B51 ; [.3AF5.0020.0002.10B51] # INSCRIPTIONAL PARTHIAN LETTER SADHE +10B52 ; [.3AF6.0020.0002.10B52] # INSCRIPTIONAL PARTHIAN LETTER QOPH +10B53 ; [.3AF7.0020.0002.10B53] # INSCRIPTIONAL PARTHIAN LETTER RESH +10B54 ; [.3AF8.0020.0002.10B54] # INSCRIPTIONAL PARTHIAN LETTER SHIN +10B55 ; [.3AF9.0020.0002.10B55] # INSCRIPTIONAL PARTHIAN LETTER TAW +10B60 ; [.3AFA.0020.0002.10B60] # INSCRIPTIONAL PAHLAVI LETTER ALEPH +10B61 ; [.3AFB.0020.0002.10B61] # INSCRIPTIONAL PAHLAVI LETTER BETH +10B62 ; [.3AFC.0020.0002.10B62] # INSCRIPTIONAL PAHLAVI LETTER GIMEL +10B63 ; [.3AFD.0020.0002.10B63] # INSCRIPTIONAL PAHLAVI LETTER DALETH +10B64 ; [.3AFE.0020.0002.10B64] # INSCRIPTIONAL PAHLAVI LETTER HE +10B65 ; [.3AFF.0020.0002.10B65] # INSCRIPTIONAL PAHLAVI LETTER WAW-AYIN-RESH +10B66 ; [.3B00.0020.0002.10B66] # INSCRIPTIONAL PAHLAVI LETTER ZAYIN +10B67 ; [.3B01.0020.0002.10B67] # INSCRIPTIONAL PAHLAVI LETTER HETH +10B68 ; [.3B02.0020.0002.10B68] # INSCRIPTIONAL PAHLAVI LETTER TETH +10B69 ; [.3B03.0020.0002.10B69] # INSCRIPTIONAL PAHLAVI LETTER YODH +10B6A ; [.3B04.0020.0002.10B6A] # INSCRIPTIONAL PAHLAVI LETTER KAPH +10B6B ; [.3B05.0020.0002.10B6B] # INSCRIPTIONAL PAHLAVI LETTER LAMEDH +10B6C ; [.3B06.0020.0002.10B6C] # INSCRIPTIONAL PAHLAVI LETTER MEM-QOPH +10B6D ; [.3B07.0020.0002.10B6D] # INSCRIPTIONAL PAHLAVI LETTER NUN +10B6E ; [.3B08.0020.0002.10B6E] # INSCRIPTIONAL PAHLAVI LETTER SAMEKH +10B6F ; [.3B09.0020.0002.10B6F] # INSCRIPTIONAL PAHLAVI LETTER PE +10B70 ; [.3B0A.0020.0002.10B70] # INSCRIPTIONAL PAHLAVI LETTER SADHE +10B71 ; [.3B0B.0020.0002.10B71] # INSCRIPTIONAL PAHLAVI LETTER SHIN +10B72 ; [.3B0C.0020.0002.10B72] # INSCRIPTIONAL PAHLAVI LETTER TAW +10380 ; [.3B0D.0020.0002.10380] # UGARITIC LETTER ALPA +10381 ; [.3B0E.0020.0002.10381] # UGARITIC LETTER BETA +10382 ; [.3B0F.0020.0002.10382] # UGARITIC LETTER GAMLA +10383 ; [.3B10.0020.0002.10383] # UGARITIC LETTER KHA +10384 ; [.3B11.0020.0002.10384] # UGARITIC LETTER DELTA +10385 ; [.3B12.0020.0002.10385] # UGARITIC LETTER HO +10386 ; [.3B13.0020.0002.10386] # UGARITIC LETTER WO +10387 ; [.3B14.0020.0002.10387] # UGARITIC LETTER ZETA +10388 ; [.3B15.0020.0002.10388] # UGARITIC LETTER HOTA +10389 ; [.3B16.0020.0002.10389] # UGARITIC LETTER TET +1038A ; [.3B17.0020.0002.1038A] # UGARITIC LETTER YOD +1038B ; [.3B18.0020.0002.1038B] # UGARITIC LETTER KAF +1038C ; [.3B19.0020.0002.1038C] # UGARITIC LETTER SHIN +1038D ; [.3B1A.0020.0002.1038D] # UGARITIC LETTER LAMDA +1038E ; [.3B1B.0020.0002.1038E] # UGARITIC LETTER MEM +1038F ; [.3B1C.0020.0002.1038F] # UGARITIC LETTER DHAL +10390 ; [.3B1D.0020.0002.10390] # UGARITIC LETTER NUN +10391 ; [.3B1E.0020.0002.10391] # UGARITIC LETTER ZU +10392 ; [.3B1F.0020.0002.10392] # UGARITIC LETTER SAMKA +10393 ; [.3B20.0020.0002.10393] # UGARITIC LETTER AIN +10394 ; [.3B21.0020.0002.10394] # UGARITIC LETTER PU +10395 ; [.3B22.0020.0002.10395] # UGARITIC LETTER SADE +10396 ; [.3B23.0020.0002.10396] # UGARITIC LETTER QOPA +10397 ; [.3B24.0020.0002.10397] # UGARITIC LETTER RASHA +10398 ; [.3B25.0020.0002.10398] # UGARITIC LETTER THANNA +10399 ; [.3B26.0020.0002.10399] # UGARITIC LETTER GHAIN +1039A ; [.3B27.0020.0002.1039A] # UGARITIC LETTER TO +1039B ; [.3B28.0020.0002.1039B] # UGARITIC LETTER I +1039C ; [.3B29.0020.0002.1039C] # UGARITIC LETTER U +1039D ; [.3B2A.0020.0002.1039D] # UGARITIC LETTER SSU +103A0 ; [.3B2B.0020.0002.103A0] # OLD PERSIAN SIGN A +103A1 ; [.3B2C.0020.0002.103A1] # OLD PERSIAN SIGN I +103A2 ; [.3B2D.0020.0002.103A2] # OLD PERSIAN SIGN U +103A3 ; [.3B2E.0020.0002.103A3] # OLD PERSIAN SIGN KA +103A4 ; [.3B2F.0020.0002.103A4] # OLD PERSIAN SIGN KU +103A5 ; [.3B30.0020.0002.103A5] # OLD PERSIAN SIGN GA +103A6 ; [.3B31.0020.0002.103A6] # OLD PERSIAN SIGN GU +103A7 ; [.3B32.0020.0002.103A7] # OLD PERSIAN SIGN XA +103A8 ; [.3B33.0020.0002.103A8] # OLD PERSIAN SIGN CA +103A9 ; [.3B34.0020.0002.103A9] # OLD PERSIAN SIGN JA +103AA ; [.3B35.0020.0002.103AA] # OLD PERSIAN SIGN JI +103AB ; [.3B36.0020.0002.103AB] # OLD PERSIAN SIGN TA +103AC ; [.3B37.0020.0002.103AC] # OLD PERSIAN SIGN TU +103AD ; [.3B38.0020.0002.103AD] # OLD PERSIAN SIGN DA +103AE ; [.3B39.0020.0002.103AE] # OLD PERSIAN SIGN DI +103AF ; [.3B3A.0020.0002.103AF] # OLD PERSIAN SIGN DU +103B0 ; [.3B3B.0020.0002.103B0] # OLD PERSIAN SIGN THA +103B1 ; [.3B3C.0020.0002.103B1] # OLD PERSIAN SIGN PA +103B2 ; [.3B3D.0020.0002.103B2] # OLD PERSIAN SIGN BA +103B3 ; [.3B3E.0020.0002.103B3] # OLD PERSIAN SIGN FA +103B4 ; [.3B3F.0020.0002.103B4] # OLD PERSIAN SIGN NA +103B5 ; [.3B40.0020.0002.103B5] # OLD PERSIAN SIGN NU +103B6 ; [.3B41.0020.0002.103B6] # OLD PERSIAN SIGN MA +103B7 ; [.3B42.0020.0002.103B7] # OLD PERSIAN SIGN MI +103B8 ; [.3B43.0020.0002.103B8] # OLD PERSIAN SIGN MU +103B9 ; [.3B44.0020.0002.103B9] # OLD PERSIAN SIGN YA +103BA ; [.3B45.0020.0002.103BA] # OLD PERSIAN SIGN VA +103BB ; [.3B46.0020.0002.103BB] # OLD PERSIAN SIGN VI +103BC ; [.3B47.0020.0002.103BC] # OLD PERSIAN SIGN RA +103BD ; [.3B48.0020.0002.103BD] # OLD PERSIAN SIGN RU +103BE ; [.3B49.0020.0002.103BE] # OLD PERSIAN SIGN LA +103BF ; [.3B4A.0020.0002.103BF] # OLD PERSIAN SIGN SA +103C0 ; [.3B4B.0020.0002.103C0] # OLD PERSIAN SIGN ZA +103C1 ; [.3B4C.0020.0002.103C1] # OLD PERSIAN SIGN SHA +103C2 ; [.3B4D.0020.0002.103C2] # OLD PERSIAN SIGN SSA +103C3 ; [.3B4E.0020.0002.103C3] # OLD PERSIAN SIGN HA +103C8 ; [.3B4F.0020.0002.103C8] # OLD PERSIAN SIGN AURAMAZDAA +103C9 ; [.3B50.0020.0002.103C9] # OLD PERSIAN SIGN AURAMAZDAA-2 +103CA ; [.3B51.0020.0002.103CA] # OLD PERSIAN SIGN AURAMAZDAAHA +103CB ; [.3B52.0020.0002.103CB] # OLD PERSIAN SIGN XSHAAYATHIYA +103CC ; [.3B53.0020.0002.103CC] # OLD PERSIAN SIGN DAHYAAUSH +103CD ; [.3B54.0020.0002.103CD] # OLD PERSIAN SIGN DAHYAAUSH-2 +103CE ; [.3B55.0020.0002.103CE] # OLD PERSIAN SIGN BAGA +103CF ; [.3B56.0020.0002.103CF] # OLD PERSIAN SIGN BUUMISH +12000 ; [.3B57.0020.0002.12000] # CUNEIFORM SIGN A +12001 ; [.3B58.0020.0002.12001] # CUNEIFORM SIGN A TIMES A +12002 ; [.3B59.0020.0002.12002] # CUNEIFORM SIGN A TIMES BAD +12003 ; [.3B5A.0020.0002.12003] # CUNEIFORM SIGN A TIMES GAN2 TENU +12004 ; [.3B5B.0020.0002.12004] # CUNEIFORM SIGN A TIMES HA +12005 ; [.3B5C.0020.0002.12005] # CUNEIFORM SIGN A TIMES IGI +12006 ; [.3B5D.0020.0002.12006] # CUNEIFORM SIGN A TIMES LAGAR GUNU +12007 ; [.3B5E.0020.0002.12007] # CUNEIFORM SIGN A TIMES MUSH +12008 ; [.3B5F.0020.0002.12008] # CUNEIFORM SIGN A TIMES SAG +12009 ; [.3B60.0020.0002.12009] # CUNEIFORM SIGN A2 +1200A ; [.3B61.0020.0002.1200A] # CUNEIFORM SIGN AB +1200B ; [.3B62.0020.0002.1200B] # CUNEIFORM SIGN AB TIMES ASH2 +1200C ; [.3B63.0020.0002.1200C] # CUNEIFORM SIGN AB TIMES DUN3 GUNU +1200D ; [.3B64.0020.0002.1200D] # CUNEIFORM SIGN AB TIMES GAL +1200E ; [.3B65.0020.0002.1200E] # CUNEIFORM SIGN AB TIMES GAN2 TENU +1200F ; [.3B66.0020.0002.1200F] # CUNEIFORM SIGN AB TIMES HA +12010 ; [.3B67.0020.0002.12010] # CUNEIFORM SIGN AB TIMES IGI GUNU +12011 ; [.3B68.0020.0002.12011] # CUNEIFORM SIGN AB TIMES IMIN +12012 ; [.3B69.0020.0002.12012] # CUNEIFORM SIGN AB TIMES LAGAB +12013 ; [.3B6A.0020.0002.12013] # CUNEIFORM SIGN AB TIMES SHESH +12014 ; [.3B6B.0020.0002.12014] # CUNEIFORM SIGN AB TIMES U PLUS U PLUS U +12015 ; [.3B6C.0020.0002.12015] # CUNEIFORM SIGN AB GUNU +12016 ; [.3B6D.0020.0002.12016] # CUNEIFORM SIGN AB2 +12017 ; [.3B6E.0020.0002.12017] # CUNEIFORM SIGN AB2 TIMES BALAG +12018 ; [.3B6F.0020.0002.12018] # CUNEIFORM SIGN AB2 TIMES GAN2 TENU +12019 ; [.3B70.0020.0002.12019] # CUNEIFORM SIGN AB2 TIMES ME PLUS EN +1201A ; [.3B71.0020.0002.1201A] # CUNEIFORM SIGN AB2 TIMES SHA3 +1201B ; [.3B72.0020.0002.1201B] # CUNEIFORM SIGN AB2 TIMES TAK4 +1201C ; [.3B73.0020.0002.1201C] # CUNEIFORM SIGN AD +1201D ; [.3B74.0020.0002.1201D] # CUNEIFORM SIGN AK +1201E ; [.3B75.0020.0002.1201E] # CUNEIFORM SIGN AK TIMES ERIN2 +1201F ; [.3B76.0020.0002.1201F] # CUNEIFORM SIGN AK TIMES SHITA PLUS GISH +12020 ; [.3B77.0020.0002.12020] # CUNEIFORM SIGN AL +12021 ; [.3B78.0020.0002.12021] # CUNEIFORM SIGN AL TIMES AL +12022 ; [.3B79.0020.0002.12022] # CUNEIFORM SIGN AL TIMES DIM2 +12023 ; [.3B7A.0020.0002.12023] # CUNEIFORM SIGN AL TIMES GISH +12024 ; [.3B7B.0020.0002.12024] # CUNEIFORM SIGN AL TIMES HA +12025 ; [.3B7C.0020.0002.12025] # CUNEIFORM SIGN AL TIMES KAD3 +12026 ; [.3B7D.0020.0002.12026] # CUNEIFORM SIGN AL TIMES KI +12027 ; [.3B7E.0020.0002.12027] # CUNEIFORM SIGN AL TIMES SHE +12028 ; [.3B7F.0020.0002.12028] # CUNEIFORM SIGN AL TIMES USH +12029 ; [.3B80.0020.0002.12029] # CUNEIFORM SIGN ALAN +1202A ; [.3B81.0020.0002.1202A] # CUNEIFORM SIGN ALEPH +1202B ; [.3B82.0020.0002.1202B] # CUNEIFORM SIGN AMAR +1202C ; [.3B83.0020.0002.1202C] # CUNEIFORM SIGN AMAR TIMES SHE +1202D ; [.3B84.0020.0002.1202D] # CUNEIFORM SIGN AN +1202E ; [.3B85.0020.0002.1202E] # CUNEIFORM SIGN AN OVER AN +1202F ; [.3B86.0020.0002.1202F] # CUNEIFORM SIGN AN THREE TIMES +12030 ; [.3B87.0020.0002.12030] # CUNEIFORM SIGN AN PLUS NAGA OPPOSING AN PLUS NAGA +12031 ; [.3B88.0020.0002.12031] # CUNEIFORM SIGN AN PLUS NAGA SQUARED +12032 ; [.3B89.0020.0002.12032] # CUNEIFORM SIGN ANSHE +12033 ; [.3B8A.0020.0002.12033] # CUNEIFORM SIGN APIN +12034 ; [.3B8B.0020.0002.12034] # CUNEIFORM SIGN ARAD +12035 ; [.3B8C.0020.0002.12035] # CUNEIFORM SIGN ARAD TIMES KUR +12036 ; [.3B8D.0020.0002.12036] # CUNEIFORM SIGN ARKAB +12037 ; [.3B8E.0020.0002.12037] # CUNEIFORM SIGN ASAL2 +12038 ; [.3B8F.0020.0002.12038] # CUNEIFORM SIGN ASH +12039 ; [.3B90.0020.0002.12039] # CUNEIFORM SIGN ASH ZIDA TENU +1203A ; [.3B91.0020.0002.1203A] # CUNEIFORM SIGN ASH KABA TENU +1203B ; [.3B92.0020.0002.1203B] # CUNEIFORM SIGN ASH OVER ASH TUG2 OVER TUG2 TUG2 OVER TUG2 PAP +1203C ; [.3B93.0020.0002.1203C] # CUNEIFORM SIGN ASH OVER ASH OVER ASH +1203D ; [.3B94.0020.0002.1203D] # CUNEIFORM SIGN ASH OVER ASH OVER ASH CROSSING ASH OVER ASH OVER ASH +1203E ; [.3B95.0020.0002.1203E] # CUNEIFORM SIGN ASH2 +1203F ; [.3B96.0020.0002.1203F] # CUNEIFORM SIGN ASHGAB +12040 ; [.3B97.0020.0002.12040] # CUNEIFORM SIGN BA +12041 ; [.3B98.0020.0002.12041] # CUNEIFORM SIGN BAD +12042 ; [.3B99.0020.0002.12042] # CUNEIFORM SIGN BAG3 +12043 ; [.3B9A.0020.0002.12043] # CUNEIFORM SIGN BAHAR2 +12044 ; [.3B9B.0020.0002.12044] # CUNEIFORM SIGN BAL +12045 ; [.3B9C.0020.0002.12045] # CUNEIFORM SIGN BAL OVER BAL +12046 ; [.3B9D.0020.0002.12046] # CUNEIFORM SIGN BALAG +12047 ; [.3B9E.0020.0002.12047] # CUNEIFORM SIGN BAR +12048 ; [.3B9F.0020.0002.12048] # CUNEIFORM SIGN BARA2 +12049 ; [.3BA0.0020.0002.12049] # CUNEIFORM SIGN BI +1204A ; [.3BA1.0020.0002.1204A] # CUNEIFORM SIGN BI TIMES A +1204B ; [.3BA2.0020.0002.1204B] # CUNEIFORM SIGN BI TIMES GAR +1204C ; [.3BA3.0020.0002.1204C] # CUNEIFORM SIGN BI TIMES IGI GUNU +1204D ; [.3BA4.0020.0002.1204D] # CUNEIFORM SIGN BU +1204E ; [.3BA5.0020.0002.1204E] # CUNEIFORM SIGN BU OVER BU AB +1204F ; [.3BA6.0020.0002.1204F] # CUNEIFORM SIGN BU OVER BU UN +12050 ; [.3BA7.0020.0002.12050] # CUNEIFORM SIGN BU CROSSING BU +12051 ; [.3BA8.0020.0002.12051] # CUNEIFORM SIGN BULUG +12052 ; [.3BA9.0020.0002.12052] # CUNEIFORM SIGN BULUG OVER BULUG +12053 ; [.3BAA.0020.0002.12053] # CUNEIFORM SIGN BUR +12054 ; [.3BAB.0020.0002.12054] # CUNEIFORM SIGN BUR2 +12055 ; [.3BAC.0020.0002.12055] # CUNEIFORM SIGN DA +12056 ; [.3BAD.0020.0002.12056] # CUNEIFORM SIGN DAG +12057 ; [.3BAE.0020.0002.12057] # CUNEIFORM SIGN DAG KISIM5 TIMES A PLUS MASH +12058 ; [.3BAF.0020.0002.12058] # CUNEIFORM SIGN DAG KISIM5 TIMES AMAR +12059 ; [.3BB0.0020.0002.12059] # CUNEIFORM SIGN DAG KISIM5 TIMES BALAG +1205A ; [.3BB1.0020.0002.1205A] # CUNEIFORM SIGN DAG KISIM5 TIMES BI +1205B ; [.3BB2.0020.0002.1205B] # CUNEIFORM SIGN DAG KISIM5 TIMES GA +1205C ; [.3BB3.0020.0002.1205C] # CUNEIFORM SIGN DAG KISIM5 TIMES GA PLUS MASH +1205D ; [.3BB4.0020.0002.1205D] # CUNEIFORM SIGN DAG KISIM5 TIMES GI +1205E ; [.3BB5.0020.0002.1205E] # CUNEIFORM SIGN DAG KISIM5 TIMES GIR2 +1205F ; [.3BB6.0020.0002.1205F] # CUNEIFORM SIGN DAG KISIM5 TIMES GUD +12060 ; [.3BB7.0020.0002.12060] # CUNEIFORM SIGN DAG KISIM5 TIMES HA +12061 ; [.3BB8.0020.0002.12061] # CUNEIFORM SIGN DAG KISIM5 TIMES IR +12062 ; [.3BB9.0020.0002.12062] # CUNEIFORM SIGN DAG KISIM5 TIMES IR PLUS LU +12063 ; [.3BBA.0020.0002.12063] # CUNEIFORM SIGN DAG KISIM5 TIMES KAK +12064 ; [.3BBB.0020.0002.12064] # CUNEIFORM SIGN DAG KISIM5 TIMES LA +12065 ; [.3BBC.0020.0002.12065] # CUNEIFORM SIGN DAG KISIM5 TIMES LU +12066 ; [.3BBD.0020.0002.12066] # CUNEIFORM SIGN DAG KISIM5 TIMES LU PLUS MASH2 +12067 ; [.3BBE.0020.0002.12067] # CUNEIFORM SIGN DAG KISIM5 TIMES LUM +12068 ; [.3BBF.0020.0002.12068] # CUNEIFORM SIGN DAG KISIM5 TIMES NE +12069 ; [.3BC0.0020.0002.12069] # CUNEIFORM SIGN DAG KISIM5 TIMES PAP PLUS PAP +1206A ; [.3BC1.0020.0002.1206A] # CUNEIFORM SIGN DAG KISIM5 TIMES SI +1206B ; [.3BC2.0020.0002.1206B] # CUNEIFORM SIGN DAG KISIM5 TIMES TAK4 +1206C ; [.3BC3.0020.0002.1206C] # CUNEIFORM SIGN DAG KISIM5 TIMES U2 PLUS GIR2 +1206D ; [.3BC4.0020.0002.1206D] # CUNEIFORM SIGN DAG KISIM5 TIMES USH +1206E ; [.3BC5.0020.0002.1206E] # CUNEIFORM SIGN DAM +1206F ; [.3BC6.0020.0002.1206F] # CUNEIFORM SIGN DAR +12070 ; [.3BC7.0020.0002.12070] # CUNEIFORM SIGN DARA3 +12071 ; [.3BC8.0020.0002.12071] # CUNEIFORM SIGN DARA4 +12072 ; [.3BC9.0020.0002.12072] # CUNEIFORM SIGN DI +12073 ; [.3BCA.0020.0002.12073] # CUNEIFORM SIGN DIB +12074 ; [.3BCB.0020.0002.12074] # CUNEIFORM SIGN DIM +12075 ; [.3BCC.0020.0002.12075] # CUNEIFORM SIGN DIM TIMES SHE +12076 ; [.3BCD.0020.0002.12076] # CUNEIFORM SIGN DIM2 +12077 ; [.3BCE.0020.0002.12077] # CUNEIFORM SIGN DIN +12078 ; [.3BCF.0020.0002.12078] # CUNEIFORM SIGN DIN KASKAL U GUNU DISH +12079 ; [.3BD0.0020.0002.12079] # CUNEIFORM SIGN DISH +1207A ; [.3BD1.0020.0002.1207A] # CUNEIFORM SIGN DU +1207B ; [.3BD2.0020.0002.1207B] # CUNEIFORM SIGN DU OVER DU +1207C ; [.3BD3.0020.0002.1207C] # CUNEIFORM SIGN DU GUNU +1207D ; [.3BD4.0020.0002.1207D] # CUNEIFORM SIGN DU SHESHIG +1207E ; [.3BD5.0020.0002.1207E] # CUNEIFORM SIGN DUB +1207F ; [.3BD6.0020.0002.1207F] # CUNEIFORM SIGN DUB TIMES ESH2 +12080 ; [.3BD7.0020.0002.12080] # CUNEIFORM SIGN DUB2 +12081 ; [.3BD8.0020.0002.12081] # CUNEIFORM SIGN DUG +12082 ; [.3BD9.0020.0002.12082] # CUNEIFORM SIGN DUGUD +12083 ; [.3BDA.0020.0002.12083] # CUNEIFORM SIGN DUH +12084 ; [.3BDB.0020.0002.12084] # CUNEIFORM SIGN DUN +12085 ; [.3BDC.0020.0002.12085] # CUNEIFORM SIGN DUN3 +12086 ; [.3BDD.0020.0002.12086] # CUNEIFORM SIGN DUN3 GUNU +12087 ; [.3BDE.0020.0002.12087] # CUNEIFORM SIGN DUN3 GUNU GUNU +12088 ; [.3BDF.0020.0002.12088] # CUNEIFORM SIGN DUN4 +12089 ; [.3BE0.0020.0002.12089] # CUNEIFORM SIGN DUR2 +1208A ; [.3BE1.0020.0002.1208A] # CUNEIFORM SIGN E +1208B ; [.3BE2.0020.0002.1208B] # CUNEIFORM SIGN E TIMES PAP +1208C ; [.3BE3.0020.0002.1208C] # CUNEIFORM SIGN E OVER E NUN OVER NUN +1208D ; [.3BE4.0020.0002.1208D] # CUNEIFORM SIGN E2 +1208E ; [.3BE5.0020.0002.1208E] # CUNEIFORM SIGN E2 TIMES A PLUS HA PLUS DA +1208F ; [.3BE6.0020.0002.1208F] # CUNEIFORM SIGN E2 TIMES GAR +12090 ; [.3BE7.0020.0002.12090] # CUNEIFORM SIGN E2 TIMES MI +12091 ; [.3BE8.0020.0002.12091] # CUNEIFORM SIGN E2 TIMES SAL +12092 ; [.3BE9.0020.0002.12092] # CUNEIFORM SIGN E2 TIMES SHE +12093 ; [.3BEA.0020.0002.12093] # CUNEIFORM SIGN E2 TIMES U +12094 ; [.3BEB.0020.0002.12094] # CUNEIFORM SIGN EDIN +12095 ; [.3BEC.0020.0002.12095] # CUNEIFORM SIGN EGIR +12096 ; [.3BED.0020.0002.12096] # CUNEIFORM SIGN EL +12097 ; [.3BEE.0020.0002.12097] # CUNEIFORM SIGN EN +12098 ; [.3BEF.0020.0002.12098] # CUNEIFORM SIGN EN TIMES GAN2 +12099 ; [.3BF0.0020.0002.12099] # CUNEIFORM SIGN EN TIMES GAN2 TENU +1209A ; [.3BF1.0020.0002.1209A] # CUNEIFORM SIGN EN TIMES ME +1209B ; [.3BF2.0020.0002.1209B] # CUNEIFORM SIGN EN CROSSING EN +1209C ; [.3BF3.0020.0002.1209C] # CUNEIFORM SIGN EN OPPOSING EN +1209D ; [.3BF4.0020.0002.1209D] # CUNEIFORM SIGN EN SQUARED +1209E ; [.3BF5.0020.0002.1209E] # CUNEIFORM SIGN EREN +1209F ; [.3BF6.0020.0002.1209F] # CUNEIFORM SIGN ERIN2 +120A0 ; [.3BF7.0020.0002.120A0] # CUNEIFORM SIGN ESH2 +120A1 ; [.3BF8.0020.0002.120A1] # CUNEIFORM SIGN EZEN +120A2 ; [.3BF9.0020.0002.120A2] # CUNEIFORM SIGN EZEN TIMES A +120A3 ; [.3BFA.0020.0002.120A3] # CUNEIFORM SIGN EZEN TIMES A PLUS LAL +120A4 ; [.3BFB.0020.0002.120A4] # CUNEIFORM SIGN EZEN TIMES A PLUS LAL TIMES LAL +120A5 ; [.3BFC.0020.0002.120A5] # CUNEIFORM SIGN EZEN TIMES AN +120A6 ; [.3BFD.0020.0002.120A6] # CUNEIFORM SIGN EZEN TIMES BAD +120A7 ; [.3BFE.0020.0002.120A7] # CUNEIFORM SIGN EZEN TIMES DUN3 GUNU +120A8 ; [.3BFF.0020.0002.120A8] # CUNEIFORM SIGN EZEN TIMES DUN3 GUNU GUNU +120A9 ; [.3C00.0020.0002.120A9] # CUNEIFORM SIGN EZEN TIMES HA +120AA ; [.3C01.0020.0002.120AA] # CUNEIFORM SIGN EZEN TIMES HA GUNU +120AB ; [.3C02.0020.0002.120AB] # CUNEIFORM SIGN EZEN TIMES IGI GUNU +120AC ; [.3C03.0020.0002.120AC] # CUNEIFORM SIGN EZEN TIMES KASKAL +120AD ; [.3C04.0020.0002.120AD] # CUNEIFORM SIGN EZEN TIMES KASKAL SQUARED +120AE ; [.3C05.0020.0002.120AE] # CUNEIFORM SIGN EZEN TIMES KU3 +120AF ; [.3C06.0020.0002.120AF] # CUNEIFORM SIGN EZEN TIMES LA +120B0 ; [.3C07.0020.0002.120B0] # CUNEIFORM SIGN EZEN TIMES LAL TIMES LAL +120B1 ; [.3C08.0020.0002.120B1] # CUNEIFORM SIGN EZEN TIMES LI +120B2 ; [.3C09.0020.0002.120B2] # CUNEIFORM SIGN EZEN TIMES LU +120B3 ; [.3C0A.0020.0002.120B3] # CUNEIFORM SIGN EZEN TIMES U2 +120B4 ; [.3C0B.0020.0002.120B4] # CUNEIFORM SIGN EZEN TIMES UD +120B5 ; [.3C0C.0020.0002.120B5] # CUNEIFORM SIGN GA +120B6 ; [.3C0D.0020.0002.120B6] # CUNEIFORM SIGN GA GUNU +120B7 ; [.3C0E.0020.0002.120B7] # CUNEIFORM SIGN GA2 +120B8 ; [.3C0F.0020.0002.120B8] # CUNEIFORM SIGN GA2 TIMES A PLUS DA PLUS HA +120B9 ; [.3C10.0020.0002.120B9] # CUNEIFORM SIGN GA2 TIMES A PLUS HA +120BA ; [.3C11.0020.0002.120BA] # CUNEIFORM SIGN GA2 TIMES A PLUS IGI +120BB ; [.3C12.0020.0002.120BB] # CUNEIFORM SIGN GA2 TIMES AB2 TENU PLUS TAB +120BC ; [.3C13.0020.0002.120BC] # CUNEIFORM SIGN GA2 TIMES AN +120BD ; [.3C14.0020.0002.120BD] # CUNEIFORM SIGN GA2 TIMES ASH +120BE ; [.3C15.0020.0002.120BE] # CUNEIFORM SIGN GA2 TIMES ASH2 PLUS GAL +120BF ; [.3C16.0020.0002.120BF] # CUNEIFORM SIGN GA2 TIMES BAD +120C0 ; [.3C17.0020.0002.120C0] # CUNEIFORM SIGN GA2 TIMES BAR PLUS RA +120C1 ; [.3C18.0020.0002.120C1] # CUNEIFORM SIGN GA2 TIMES BUR +120C2 ; [.3C19.0020.0002.120C2] # CUNEIFORM SIGN GA2 TIMES BUR PLUS RA +120C3 ; [.3C1A.0020.0002.120C3] # CUNEIFORM SIGN GA2 TIMES DA +120C4 ; [.3C1B.0020.0002.120C4] # CUNEIFORM SIGN GA2 TIMES DI +120C5 ; [.3C1C.0020.0002.120C5] # CUNEIFORM SIGN GA2 TIMES DIM TIMES SHE +120C6 ; [.3C1D.0020.0002.120C6] # CUNEIFORM SIGN GA2 TIMES DUB +120C7 ; [.3C1E.0020.0002.120C7] # CUNEIFORM SIGN GA2 TIMES EL +120C8 ; [.3C1F.0020.0002.120C8] # CUNEIFORM SIGN GA2 TIMES EL PLUS LA +120C9 ; [.3C20.0020.0002.120C9] # CUNEIFORM SIGN GA2 TIMES EN +120CA ; [.3C21.0020.0002.120CA] # CUNEIFORM SIGN GA2 TIMES EN TIMES GAN2 TENU +120CB ; [.3C22.0020.0002.120CB] # CUNEIFORM SIGN GA2 TIMES GAN2 TENU +120CC ; [.3C23.0020.0002.120CC] # CUNEIFORM SIGN GA2 TIMES GAR +120CD ; [.3C24.0020.0002.120CD] # CUNEIFORM SIGN GA2 TIMES GI +120CE ; [.3C25.0020.0002.120CE] # CUNEIFORM SIGN GA2 TIMES GI4 +120CF ; [.3C26.0020.0002.120CF] # CUNEIFORM SIGN GA2 TIMES GI4 PLUS A +120D0 ; [.3C27.0020.0002.120D0] # CUNEIFORM SIGN GA2 TIMES GIR2 PLUS SU +120D1 ; [.3C28.0020.0002.120D1] # CUNEIFORM SIGN GA2 TIMES HA PLUS LU PLUS ESH2 +120D2 ; [.3C29.0020.0002.120D2] # CUNEIFORM SIGN GA2 TIMES HAL +120D3 ; [.3C2A.0020.0002.120D3] # CUNEIFORM SIGN GA2 TIMES HAL PLUS LA +120D4 ; [.3C2B.0020.0002.120D4] # CUNEIFORM SIGN GA2 TIMES HI PLUS LI +120D5 ; [.3C2C.0020.0002.120D5] # CUNEIFORM SIGN GA2 TIMES HUB2 +120D6 ; [.3C2D.0020.0002.120D6] # CUNEIFORM SIGN GA2 TIMES IGI GUNU +120D7 ; [.3C2E.0020.0002.120D7] # CUNEIFORM SIGN GA2 TIMES ISH PLUS HU PLUS ASH +120D8 ; [.3C2F.0020.0002.120D8] # CUNEIFORM SIGN GA2 TIMES KAK +120D9 ; [.3C30.0020.0002.120D9] # CUNEIFORM SIGN GA2 TIMES KASKAL +120DA ; [.3C31.0020.0002.120DA] # CUNEIFORM SIGN GA2 TIMES KID +120DB ; [.3C32.0020.0002.120DB] # CUNEIFORM SIGN GA2 TIMES KID PLUS LAL +120DC ; [.3C33.0020.0002.120DC] # CUNEIFORM SIGN GA2 TIMES KU3 PLUS AN +120DD ; [.3C34.0020.0002.120DD] # CUNEIFORM SIGN GA2 TIMES LA +120DE ; [.3C35.0020.0002.120DE] # CUNEIFORM SIGN GA2 TIMES ME PLUS EN +120DF ; [.3C36.0020.0002.120DF] # CUNEIFORM SIGN GA2 TIMES MI +120E0 ; [.3C37.0020.0002.120E0] # CUNEIFORM SIGN GA2 TIMES NUN +120E1 ; [.3C38.0020.0002.120E1] # CUNEIFORM SIGN GA2 TIMES NUN OVER NUN +120E2 ; [.3C39.0020.0002.120E2] # CUNEIFORM SIGN GA2 TIMES PA +120E3 ; [.3C3A.0020.0002.120E3] # CUNEIFORM SIGN GA2 TIMES SAL +120E4 ; [.3C3B.0020.0002.120E4] # CUNEIFORM SIGN GA2 TIMES SAR +120E5 ; [.3C3C.0020.0002.120E5] # CUNEIFORM SIGN GA2 TIMES SHE +120E6 ; [.3C3D.0020.0002.120E6] # CUNEIFORM SIGN GA2 TIMES SHE PLUS TUR +120E7 ; [.3C3E.0020.0002.120E7] # CUNEIFORM SIGN GA2 TIMES SHID +120E8 ; [.3C3F.0020.0002.120E8] # CUNEIFORM SIGN GA2 TIMES SUM +120E9 ; [.3C40.0020.0002.120E9] # CUNEIFORM SIGN GA2 TIMES TAK4 +120EA ; [.3C41.0020.0002.120EA] # CUNEIFORM SIGN GA2 TIMES U +120EB ; [.3C42.0020.0002.120EB] # CUNEIFORM SIGN GA2 TIMES UD +120EC ; [.3C43.0020.0002.120EC] # CUNEIFORM SIGN GA2 TIMES UD PLUS DU +120ED ; [.3C44.0020.0002.120ED] # CUNEIFORM SIGN GA2 OVER GA2 +120EE ; [.3C45.0020.0002.120EE] # CUNEIFORM SIGN GABA +120EF ; [.3C46.0020.0002.120EF] # CUNEIFORM SIGN GABA CROSSING GABA +120F0 ; [.3C47.0020.0002.120F0] # CUNEIFORM SIGN GAD +120F1 ; [.3C48.0020.0002.120F1] # CUNEIFORM SIGN GAD OVER GAD GAR OVER GAR +120F2 ; [.3C49.0020.0002.120F2] # CUNEIFORM SIGN GAL +120F3 ; [.3C4A.0020.0002.120F3] # CUNEIFORM SIGN GAL GAD OVER GAD GAR OVER GAR +120F4 ; [.3C4B.0020.0002.120F4] # CUNEIFORM SIGN GALAM +120F5 ; [.3C4C.0020.0002.120F5] # CUNEIFORM SIGN GAM +120F6 ; [.3C4D.0020.0002.120F6] # CUNEIFORM SIGN GAN +120F7 ; [.3C4E.0020.0002.120F7] # CUNEIFORM SIGN GAN2 +120F8 ; [.3C4F.0020.0002.120F8] # CUNEIFORM SIGN GAN2 TENU +120F9 ; [.3C50.0020.0002.120F9] # CUNEIFORM SIGN GAN2 OVER GAN2 +120FA ; [.3C51.0020.0002.120FA] # CUNEIFORM SIGN GAN2 CROSSING GAN2 +120FB ; [.3C52.0020.0002.120FB] # CUNEIFORM SIGN GAR +120FC ; [.3C53.0020.0002.120FC] # CUNEIFORM SIGN GAR3 +120FD ; [.3C54.0020.0002.120FD] # CUNEIFORM SIGN GASHAN +120FE ; [.3C55.0020.0002.120FE] # CUNEIFORM SIGN GESHTIN +120FF ; [.3C56.0020.0002.120FF] # CUNEIFORM SIGN GESHTIN TIMES KUR +12100 ; [.3C57.0020.0002.12100] # CUNEIFORM SIGN GI +12101 ; [.3C58.0020.0002.12101] # CUNEIFORM SIGN GI TIMES E +12102 ; [.3C59.0020.0002.12102] # CUNEIFORM SIGN GI TIMES U +12103 ; [.3C5A.0020.0002.12103] # CUNEIFORM SIGN GI CROSSING GI +12104 ; [.3C5B.0020.0002.12104] # CUNEIFORM SIGN GI4 +12105 ; [.3C5C.0020.0002.12105] # CUNEIFORM SIGN GI4 OVER GI4 +12106 ; [.3C5D.0020.0002.12106] # CUNEIFORM SIGN GI4 CROSSING GI4 +12107 ; [.3C5E.0020.0002.12107] # CUNEIFORM SIGN GIDIM +12108 ; [.3C5F.0020.0002.12108] # CUNEIFORM SIGN GIR2 +12109 ; [.3C60.0020.0002.12109] # CUNEIFORM SIGN GIR2 GUNU +1210A ; [.3C61.0020.0002.1210A] # CUNEIFORM SIGN GIR3 +1210B ; [.3C62.0020.0002.1210B] # CUNEIFORM SIGN GIR3 TIMES A PLUS IGI +1210C ; [.3C63.0020.0002.1210C] # CUNEIFORM SIGN GIR3 TIMES GAN2 TENU +1210D ; [.3C64.0020.0002.1210D] # CUNEIFORM SIGN GIR3 TIMES IGI +1210E ; [.3C65.0020.0002.1210E] # CUNEIFORM SIGN GIR3 TIMES LU PLUS IGI +1210F ; [.3C66.0020.0002.1210F] # CUNEIFORM SIGN GIR3 TIMES PA +12110 ; [.3C67.0020.0002.12110] # CUNEIFORM SIGN GISAL +12111 ; [.3C68.0020.0002.12111] # CUNEIFORM SIGN GISH +12112 ; [.3C69.0020.0002.12112] # CUNEIFORM SIGN GISH CROSSING GISH +12113 ; [.3C6A.0020.0002.12113] # CUNEIFORM SIGN GISH TIMES BAD +12114 ; [.3C6B.0020.0002.12114] # CUNEIFORM SIGN GISH TIMES TAK4 +12115 ; [.3C6C.0020.0002.12115] # CUNEIFORM SIGN GISH TENU +12116 ; [.3C6D.0020.0002.12116] # CUNEIFORM SIGN GU +12117 ; [.3C6E.0020.0002.12117] # CUNEIFORM SIGN GU CROSSING GU +12118 ; [.3C6F.0020.0002.12118] # CUNEIFORM SIGN GU2 +12119 ; [.3C70.0020.0002.12119] # CUNEIFORM SIGN GU2 TIMES KAK +1211A ; [.3C71.0020.0002.1211A] # CUNEIFORM SIGN GU2 TIMES KAK TIMES IGI GUNU +1211B ; [.3C72.0020.0002.1211B] # CUNEIFORM SIGN GU2 TIMES NUN +1211C ; [.3C73.0020.0002.1211C] # CUNEIFORM SIGN GU2 TIMES SAL PLUS TUG2 +1211D ; [.3C74.0020.0002.1211D] # CUNEIFORM SIGN GU2 GUNU +1211E ; [.3C75.0020.0002.1211E] # CUNEIFORM SIGN GUD +1211F ; [.3C76.0020.0002.1211F] # CUNEIFORM SIGN GUD TIMES A PLUS KUR +12120 ; [.3C77.0020.0002.12120] # CUNEIFORM SIGN GUD TIMES KUR +12121 ; [.3C78.0020.0002.12121] # CUNEIFORM SIGN GUD OVER GUD LUGAL +12122 ; [.3C79.0020.0002.12122] # CUNEIFORM SIGN GUL +12123 ; [.3C7A.0020.0002.12123] # CUNEIFORM SIGN GUM +12124 ; [.3C7B.0020.0002.12124] # CUNEIFORM SIGN GUM TIMES SHE +12125 ; [.3C7C.0020.0002.12125] # CUNEIFORM SIGN GUR +12126 ; [.3C7D.0020.0002.12126] # CUNEIFORM SIGN GUR7 +12127 ; [.3C7E.0020.0002.12127] # CUNEIFORM SIGN GURUN +12128 ; [.3C7F.0020.0002.12128] # CUNEIFORM SIGN GURUSH +12129 ; [.3C80.0020.0002.12129] # CUNEIFORM SIGN HA +1212A ; [.3C81.0020.0002.1212A] # CUNEIFORM SIGN HA TENU +1212B ; [.3C82.0020.0002.1212B] # CUNEIFORM SIGN HA GUNU +1212C ; [.3C83.0020.0002.1212C] # CUNEIFORM SIGN HAL +1212D ; [.3C84.0020.0002.1212D] # CUNEIFORM SIGN HI +1212E ; [.3C85.0020.0002.1212E] # CUNEIFORM SIGN HI TIMES ASH +1212F ; [.3C86.0020.0002.1212F] # CUNEIFORM SIGN HI TIMES ASH2 +12130 ; [.3C87.0020.0002.12130] # CUNEIFORM SIGN HI TIMES BAD +12131 ; [.3C88.0020.0002.12131] # CUNEIFORM SIGN HI TIMES DISH +12132 ; [.3C89.0020.0002.12132] # CUNEIFORM SIGN HI TIMES GAD +12133 ; [.3C8A.0020.0002.12133] # CUNEIFORM SIGN HI TIMES KIN +12134 ; [.3C8B.0020.0002.12134] # CUNEIFORM SIGN HI TIMES NUN +12135 ; [.3C8C.0020.0002.12135] # CUNEIFORM SIGN HI TIMES SHE +12136 ; [.3C8D.0020.0002.12136] # CUNEIFORM SIGN HI TIMES U +12137 ; [.3C8E.0020.0002.12137] # CUNEIFORM SIGN HU +12138 ; [.3C8F.0020.0002.12138] # CUNEIFORM SIGN HUB2 +12139 ; [.3C90.0020.0002.12139] # CUNEIFORM SIGN HUB2 TIMES AN +1213A ; [.3C91.0020.0002.1213A] # CUNEIFORM SIGN HUB2 TIMES HAL +1213B ; [.3C92.0020.0002.1213B] # CUNEIFORM SIGN HUB2 TIMES KASKAL +1213C ; [.3C93.0020.0002.1213C] # CUNEIFORM SIGN HUB2 TIMES LISH +1213D ; [.3C94.0020.0002.1213D] # CUNEIFORM SIGN HUB2 TIMES UD +1213E ; [.3C95.0020.0002.1213E] # CUNEIFORM SIGN HUL2 +1213F ; [.3C96.0020.0002.1213F] # CUNEIFORM SIGN I +12140 ; [.3C97.0020.0002.12140] # CUNEIFORM SIGN I A +12141 ; [.3C98.0020.0002.12141] # CUNEIFORM SIGN IB +12142 ; [.3C99.0020.0002.12142] # CUNEIFORM SIGN IDIM +12143 ; [.3C9A.0020.0002.12143] # CUNEIFORM SIGN IDIM OVER IDIM BUR +12144 ; [.3C9B.0020.0002.12144] # CUNEIFORM SIGN IDIM OVER IDIM SQUARED +12145 ; [.3C9C.0020.0002.12145] # CUNEIFORM SIGN IG +12146 ; [.3C9D.0020.0002.12146] # CUNEIFORM SIGN IGI +12147 ; [.3C9E.0020.0002.12147] # CUNEIFORM SIGN IGI DIB +12148 ; [.3C9F.0020.0002.12148] # CUNEIFORM SIGN IGI RI +12149 ; [.3CA0.0020.0002.12149] # CUNEIFORM SIGN IGI OVER IGI SHIR OVER SHIR UD OVER UD +1214A ; [.3CA1.0020.0002.1214A] # CUNEIFORM SIGN IGI GUNU +1214B ; [.3CA2.0020.0002.1214B] # CUNEIFORM SIGN IL +1214C ; [.3CA3.0020.0002.1214C] # CUNEIFORM SIGN IL TIMES GAN2 TENU +1214D ; [.3CA4.0020.0002.1214D] # CUNEIFORM SIGN IL2 +1214E ; [.3CA5.0020.0002.1214E] # CUNEIFORM SIGN IM +1214F ; [.3CA6.0020.0002.1214F] # CUNEIFORM SIGN IM TIMES TAK4 +12150 ; [.3CA7.0020.0002.12150] # CUNEIFORM SIGN IM CROSSING IM +12151 ; [.3CA8.0020.0002.12151] # CUNEIFORM SIGN IM OPPOSING IM +12152 ; [.3CA9.0020.0002.12152] # CUNEIFORM SIGN IM SQUARED +12153 ; [.3CAA.0020.0002.12153] # CUNEIFORM SIGN IMIN +12154 ; [.3CAB.0020.0002.12154] # CUNEIFORM SIGN IN +12155 ; [.3CAC.0020.0002.12155] # CUNEIFORM SIGN IR +12156 ; [.3CAD.0020.0002.12156] # CUNEIFORM SIGN ISH +12157 ; [.3CAE.0020.0002.12157] # CUNEIFORM SIGN KA +12158 ; [.3CAF.0020.0002.12158] # CUNEIFORM SIGN KA TIMES A +12159 ; [.3CB0.0020.0002.12159] # CUNEIFORM SIGN KA TIMES AD +1215A ; [.3CB1.0020.0002.1215A] # CUNEIFORM SIGN KA TIMES AD PLUS KU3 +1215B ; [.3CB2.0020.0002.1215B] # CUNEIFORM SIGN KA TIMES ASH2 +1215C ; [.3CB3.0020.0002.1215C] # CUNEIFORM SIGN KA TIMES BAD +1215D ; [.3CB4.0020.0002.1215D] # CUNEIFORM SIGN KA TIMES BALAG +1215E ; [.3CB5.0020.0002.1215E] # CUNEIFORM SIGN KA TIMES BAR +1215F ; [.3CB6.0020.0002.1215F] # CUNEIFORM SIGN KA TIMES BI +12160 ; [.3CB7.0020.0002.12160] # CUNEIFORM SIGN KA TIMES ERIN2 +12161 ; [.3CB8.0020.0002.12161] # CUNEIFORM SIGN KA TIMES ESH2 +12162 ; [.3CB9.0020.0002.12162] # CUNEIFORM SIGN KA TIMES GA +12163 ; [.3CBA.0020.0002.12163] # CUNEIFORM SIGN KA TIMES GAL +12164 ; [.3CBB.0020.0002.12164] # CUNEIFORM SIGN KA TIMES GAN2 TENU +12165 ; [.3CBC.0020.0002.12165] # CUNEIFORM SIGN KA TIMES GAR +12166 ; [.3CBD.0020.0002.12166] # CUNEIFORM SIGN KA TIMES GAR PLUS SHA3 PLUS A +12167 ; [.3CBE.0020.0002.12167] # CUNEIFORM SIGN KA TIMES GI +12168 ; [.3CBF.0020.0002.12168] # CUNEIFORM SIGN KA TIMES GIR2 +12169 ; [.3CC0.0020.0002.12169] # CUNEIFORM SIGN KA TIMES GISH PLUS SAR +1216A ; [.3CC1.0020.0002.1216A] # CUNEIFORM SIGN KA TIMES GISH CROSSING GISH +1216B ; [.3CC2.0020.0002.1216B] # CUNEIFORM SIGN KA TIMES GU +1216C ; [.3CC3.0020.0002.1216C] # CUNEIFORM SIGN KA TIMES GUR7 +1216D ; [.3CC4.0020.0002.1216D] # CUNEIFORM SIGN KA TIMES IGI +1216E ; [.3CC5.0020.0002.1216E] # CUNEIFORM SIGN KA TIMES IM +1216F ; [.3CC6.0020.0002.1216F] # CUNEIFORM SIGN KA TIMES KAK +12170 ; [.3CC7.0020.0002.12170] # CUNEIFORM SIGN KA TIMES KI +12171 ; [.3CC8.0020.0002.12171] # CUNEIFORM SIGN KA TIMES KID +12172 ; [.3CC9.0020.0002.12172] # CUNEIFORM SIGN KA TIMES LI +12173 ; [.3CCA.0020.0002.12173] # CUNEIFORM SIGN KA TIMES LU +12174 ; [.3CCB.0020.0002.12174] # CUNEIFORM SIGN KA TIMES ME +12175 ; [.3CCC.0020.0002.12175] # CUNEIFORM SIGN KA TIMES ME PLUS DU +12176 ; [.3CCD.0020.0002.12176] # CUNEIFORM SIGN KA TIMES ME PLUS GI +12177 ; [.3CCE.0020.0002.12177] # CUNEIFORM SIGN KA TIMES ME PLUS TE +12178 ; [.3CCF.0020.0002.12178] # CUNEIFORM SIGN KA TIMES MI +12179 ; [.3CD0.0020.0002.12179] # CUNEIFORM SIGN KA TIMES MI PLUS NUNUZ +1217A ; [.3CD1.0020.0002.1217A] # CUNEIFORM SIGN KA TIMES NE +1217B ; [.3CD2.0020.0002.1217B] # CUNEIFORM SIGN KA TIMES NUN +1217C ; [.3CD3.0020.0002.1217C] # CUNEIFORM SIGN KA TIMES PI +1217D ; [.3CD4.0020.0002.1217D] # CUNEIFORM SIGN KA TIMES RU +1217E ; [.3CD5.0020.0002.1217E] # CUNEIFORM SIGN KA TIMES SA +1217F ; [.3CD6.0020.0002.1217F] # CUNEIFORM SIGN KA TIMES SAR +12180 ; [.3CD7.0020.0002.12180] # CUNEIFORM SIGN KA TIMES SHA +12181 ; [.3CD8.0020.0002.12181] # CUNEIFORM SIGN KA TIMES SHE +12182 ; [.3CD9.0020.0002.12182] # CUNEIFORM SIGN KA TIMES SHID +12183 ; [.3CDA.0020.0002.12183] # CUNEIFORM SIGN KA TIMES SHU +12184 ; [.3CDB.0020.0002.12184] # CUNEIFORM SIGN KA TIMES SIG +12185 ; [.3CDC.0020.0002.12185] # CUNEIFORM SIGN KA TIMES SUHUR +12186 ; [.3CDD.0020.0002.12186] # CUNEIFORM SIGN KA TIMES TAR +12187 ; [.3CDE.0020.0002.12187] # CUNEIFORM SIGN KA TIMES U +12188 ; [.3CDF.0020.0002.12188] # CUNEIFORM SIGN KA TIMES U2 +12189 ; [.3CE0.0020.0002.12189] # CUNEIFORM SIGN KA TIMES UD +1218A ; [.3CE1.0020.0002.1218A] # CUNEIFORM SIGN KA TIMES UMUM TIMES PA +1218B ; [.3CE2.0020.0002.1218B] # CUNEIFORM SIGN KA TIMES USH +1218C ; [.3CE3.0020.0002.1218C] # CUNEIFORM SIGN KA TIMES ZI +1218D ; [.3CE4.0020.0002.1218D] # CUNEIFORM SIGN KA2 +1218E ; [.3CE5.0020.0002.1218E] # CUNEIFORM SIGN KA2 CROSSING KA2 +1218F ; [.3CE6.0020.0002.1218F] # CUNEIFORM SIGN KAB +12190 ; [.3CE7.0020.0002.12190] # CUNEIFORM SIGN KAD2 +12191 ; [.3CE8.0020.0002.12191] # CUNEIFORM SIGN KAD3 +12192 ; [.3CE9.0020.0002.12192] # CUNEIFORM SIGN KAD4 +12193 ; [.3CEA.0020.0002.12193] # CUNEIFORM SIGN KAD5 +12194 ; [.3CEB.0020.0002.12194] # CUNEIFORM SIGN KAD5 OVER KAD5 +12195 ; [.3CEC.0020.0002.12195] # CUNEIFORM SIGN KAK +12196 ; [.3CED.0020.0002.12196] # CUNEIFORM SIGN KAK TIMES IGI GUNU +12197 ; [.3CEE.0020.0002.12197] # CUNEIFORM SIGN KAL +12198 ; [.3CEF.0020.0002.12198] # CUNEIFORM SIGN KAL TIMES BAD +12199 ; [.3CF0.0020.0002.12199] # CUNEIFORM SIGN KAL CROSSING KAL +1219A ; [.3CF1.0020.0002.1219A] # CUNEIFORM SIGN KAM2 +1219B ; [.3CF2.0020.0002.1219B] # CUNEIFORM SIGN KAM4 +1219C ; [.3CF3.0020.0002.1219C] # CUNEIFORM SIGN KASKAL +1219D ; [.3CF4.0020.0002.1219D] # CUNEIFORM SIGN KASKAL LAGAB TIMES U OVER LAGAB TIMES U +1219E ; [.3CF5.0020.0002.1219E] # CUNEIFORM SIGN KASKAL OVER KASKAL LAGAB TIMES U OVER LAGAB TIMES U +1219F ; [.3CF6.0020.0002.1219F] # CUNEIFORM SIGN KESH2 +121A0 ; [.3CF7.0020.0002.121A0] # CUNEIFORM SIGN KI +121A1 ; [.3CF8.0020.0002.121A1] # CUNEIFORM SIGN KI TIMES BAD +121A2 ; [.3CF9.0020.0002.121A2] # CUNEIFORM SIGN KI TIMES U +121A3 ; [.3CFA.0020.0002.121A3] # CUNEIFORM SIGN KI TIMES UD +121A4 ; [.3CFB.0020.0002.121A4] # CUNEIFORM SIGN KID +121A5 ; [.3CFC.0020.0002.121A5] # CUNEIFORM SIGN KIN +121A6 ; [.3CFD.0020.0002.121A6] # CUNEIFORM SIGN KISAL +121A7 ; [.3CFE.0020.0002.121A7] # CUNEIFORM SIGN KISH +121A8 ; [.3CFF.0020.0002.121A8] # CUNEIFORM SIGN KISIM5 +121A9 ; [.3D00.0020.0002.121A9] # CUNEIFORM SIGN KISIM5 OVER KISIM5 +121AA ; [.3D01.0020.0002.121AA] # CUNEIFORM SIGN KU +121AB ; [.3D02.0020.0002.121AB] # CUNEIFORM SIGN KU OVER HI TIMES ASH2 KU OVER HI TIMES ASH2 +121AC ; [.3D03.0020.0002.121AC] # CUNEIFORM SIGN KU3 +121AD ; [.3D04.0020.0002.121AD] # CUNEIFORM SIGN KU4 +121AE ; [.3D05.0020.0002.121AE] # CUNEIFORM SIGN KU4 VARIANT FORM +121AF ; [.3D06.0020.0002.121AF] # CUNEIFORM SIGN KU7 +121B0 ; [.3D07.0020.0002.121B0] # CUNEIFORM SIGN KUL +121B1 ; [.3D08.0020.0002.121B1] # CUNEIFORM SIGN KUL GUNU +121B2 ; [.3D09.0020.0002.121B2] # CUNEIFORM SIGN KUN +121B3 ; [.3D0A.0020.0002.121B3] # CUNEIFORM SIGN KUR +121B4 ; [.3D0B.0020.0002.121B4] # CUNEIFORM SIGN KUR OPPOSING KUR +121B5 ; [.3D0C.0020.0002.121B5] # CUNEIFORM SIGN KUSHU2 +121B6 ; [.3D0D.0020.0002.121B6] # CUNEIFORM SIGN KWU318 +121B7 ; [.3D0E.0020.0002.121B7] # CUNEIFORM SIGN LA +121B8 ; [.3D0F.0020.0002.121B8] # CUNEIFORM SIGN LAGAB +121B9 ; [.3D10.0020.0002.121B9] # CUNEIFORM SIGN LAGAB TIMES A +121BA ; [.3D11.0020.0002.121BA] # CUNEIFORM SIGN LAGAB TIMES A PLUS DA PLUS HA +121BB ; [.3D12.0020.0002.121BB] # CUNEIFORM SIGN LAGAB TIMES A PLUS GAR +121BC ; [.3D13.0020.0002.121BC] # CUNEIFORM SIGN LAGAB TIMES A PLUS LAL +121BD ; [.3D14.0020.0002.121BD] # CUNEIFORM SIGN LAGAB TIMES AL +121BE ; [.3D15.0020.0002.121BE] # CUNEIFORM SIGN LAGAB TIMES AN +121BF ; [.3D16.0020.0002.121BF] # CUNEIFORM SIGN LAGAB TIMES ASH ZIDA TENU +121C0 ; [.3D17.0020.0002.121C0] # CUNEIFORM SIGN LAGAB TIMES BAD +121C1 ; [.3D18.0020.0002.121C1] # CUNEIFORM SIGN LAGAB TIMES BI +121C2 ; [.3D19.0020.0002.121C2] # CUNEIFORM SIGN LAGAB TIMES DAR +121C3 ; [.3D1A.0020.0002.121C3] # CUNEIFORM SIGN LAGAB TIMES EN +121C4 ; [.3D1B.0020.0002.121C4] # CUNEIFORM SIGN LAGAB TIMES GA +121C5 ; [.3D1C.0020.0002.121C5] # CUNEIFORM SIGN LAGAB TIMES GAR +121C6 ; [.3D1D.0020.0002.121C6] # CUNEIFORM SIGN LAGAB TIMES GUD +121C7 ; [.3D1E.0020.0002.121C7] # CUNEIFORM SIGN LAGAB TIMES GUD PLUS GUD +121C8 ; [.3D1F.0020.0002.121C8] # CUNEIFORM SIGN LAGAB TIMES HA +121C9 ; [.3D20.0020.0002.121C9] # CUNEIFORM SIGN LAGAB TIMES HAL +121CA ; [.3D21.0020.0002.121CA] # CUNEIFORM SIGN LAGAB TIMES HI TIMES NUN +121CB ; [.3D22.0020.0002.121CB] # CUNEIFORM SIGN LAGAB TIMES IGI GUNU +121CC ; [.3D23.0020.0002.121CC] # CUNEIFORM SIGN LAGAB TIMES IM +121CD ; [.3D24.0020.0002.121CD] # CUNEIFORM SIGN LAGAB TIMES IM PLUS HA +121CE ; [.3D25.0020.0002.121CE] # CUNEIFORM SIGN LAGAB TIMES IM PLUS LU +121CF ; [.3D26.0020.0002.121CF] # CUNEIFORM SIGN LAGAB TIMES KI +121D0 ; [.3D27.0020.0002.121D0] # CUNEIFORM SIGN LAGAB TIMES KIN +121D1 ; [.3D28.0020.0002.121D1] # CUNEIFORM SIGN LAGAB TIMES KU3 +121D2 ; [.3D29.0020.0002.121D2] # CUNEIFORM SIGN LAGAB TIMES KUL +121D3 ; [.3D2A.0020.0002.121D3] # CUNEIFORM SIGN LAGAB TIMES KUL PLUS HI PLUS A +121D4 ; [.3D2B.0020.0002.121D4] # CUNEIFORM SIGN LAGAB TIMES LAGAB +121D5 ; [.3D2C.0020.0002.121D5] # CUNEIFORM SIGN LAGAB TIMES LISH +121D6 ; [.3D2D.0020.0002.121D6] # CUNEIFORM SIGN LAGAB TIMES LU +121D7 ; [.3D2E.0020.0002.121D7] # CUNEIFORM SIGN LAGAB TIMES LUL +121D8 ; [.3D2F.0020.0002.121D8] # CUNEIFORM SIGN LAGAB TIMES ME +121D9 ; [.3D30.0020.0002.121D9] # CUNEIFORM SIGN LAGAB TIMES ME PLUS EN +121DA ; [.3D31.0020.0002.121DA] # CUNEIFORM SIGN LAGAB TIMES MUSH +121DB ; [.3D32.0020.0002.121DB] # CUNEIFORM SIGN LAGAB TIMES NE +121DC ; [.3D33.0020.0002.121DC] # CUNEIFORM SIGN LAGAB TIMES SHE PLUS SUM +121DD ; [.3D34.0020.0002.121DD] # CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH PLUS ERIN2 +121DE ; [.3D35.0020.0002.121DE] # CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH TENU +121DF ; [.3D36.0020.0002.121DF] # CUNEIFORM SIGN LAGAB TIMES SHU2 +121E0 ; [.3D37.0020.0002.121E0] # CUNEIFORM SIGN LAGAB TIMES SHU2 PLUS SHU2 +121E1 ; [.3D38.0020.0002.121E1] # CUNEIFORM SIGN LAGAB TIMES SUM +121E2 ; [.3D39.0020.0002.121E2] # CUNEIFORM SIGN LAGAB TIMES TAG +121E3 ; [.3D3A.0020.0002.121E3] # CUNEIFORM SIGN LAGAB TIMES TAK4 +121E4 ; [.3D3B.0020.0002.121E4] # CUNEIFORM SIGN LAGAB TIMES TE PLUS A PLUS SU PLUS NA +121E5 ; [.3D3C.0020.0002.121E5] # CUNEIFORM SIGN LAGAB TIMES U +121E6 ; [.3D3D.0020.0002.121E6] # CUNEIFORM SIGN LAGAB TIMES U PLUS A +121E7 ; [.3D3E.0020.0002.121E7] # CUNEIFORM SIGN LAGAB TIMES U PLUS U PLUS U +121E8 ; [.3D3F.0020.0002.121E8] # CUNEIFORM SIGN LAGAB TIMES U2 PLUS ASH +121E9 ; [.3D40.0020.0002.121E9] # CUNEIFORM SIGN LAGAB TIMES UD +121EA ; [.3D41.0020.0002.121EA] # CUNEIFORM SIGN LAGAB TIMES USH +121EB ; [.3D42.0020.0002.121EB] # CUNEIFORM SIGN LAGAB SQUARED +121EC ; [.3D43.0020.0002.121EC] # CUNEIFORM SIGN LAGAR +121ED ; [.3D44.0020.0002.121ED] # CUNEIFORM SIGN LAGAR TIMES SHE +121EE ; [.3D45.0020.0002.121EE] # CUNEIFORM SIGN LAGAR TIMES SHE PLUS SUM +121EF ; [.3D46.0020.0002.121EF] # CUNEIFORM SIGN LAGAR GUNU +121F0 ; [.3D47.0020.0002.121F0] # CUNEIFORM SIGN LAGAR GUNU OVER LAGAR GUNU SHE +121F1 ; [.3D48.0020.0002.121F1] # CUNEIFORM SIGN LAHSHU +121F2 ; [.3D49.0020.0002.121F2] # CUNEIFORM SIGN LAL +121F3 ; [.3D4A.0020.0002.121F3] # CUNEIFORM SIGN LAL TIMES LAL +121F4 ; [.3D4B.0020.0002.121F4] # CUNEIFORM SIGN LAM +121F5 ; [.3D4C.0020.0002.121F5] # CUNEIFORM SIGN LAM TIMES KUR +121F6 ; [.3D4D.0020.0002.121F6] # CUNEIFORM SIGN LAM TIMES KUR PLUS RU +121F7 ; [.3D4E.0020.0002.121F7] # CUNEIFORM SIGN LI +121F8 ; [.3D4F.0020.0002.121F8] # CUNEIFORM SIGN LIL +121F9 ; [.3D50.0020.0002.121F9] # CUNEIFORM SIGN LIMMU2 +121FA ; [.3D51.0020.0002.121FA] # CUNEIFORM SIGN LISH +121FB ; [.3D52.0020.0002.121FB] # CUNEIFORM SIGN LU +121FC ; [.3D53.0020.0002.121FC] # CUNEIFORM SIGN LU TIMES BAD +121FD ; [.3D54.0020.0002.121FD] # CUNEIFORM SIGN LU2 +121FE ; [.3D55.0020.0002.121FE] # CUNEIFORM SIGN LU2 TIMES AL +121FF ; [.3D56.0020.0002.121FF] # CUNEIFORM SIGN LU2 TIMES BAD +12200 ; [.3D57.0020.0002.12200] # CUNEIFORM SIGN LU2 TIMES ESH2 +12201 ; [.3D58.0020.0002.12201] # CUNEIFORM SIGN LU2 TIMES ESH2 TENU +12202 ; [.3D59.0020.0002.12202] # CUNEIFORM SIGN LU2 TIMES GAN2 TENU +12203 ; [.3D5A.0020.0002.12203] # CUNEIFORM SIGN LU2 TIMES HI TIMES BAD +12204 ; [.3D5B.0020.0002.12204] # CUNEIFORM SIGN LU2 TIMES IM +12205 ; [.3D5C.0020.0002.12205] # CUNEIFORM SIGN LU2 TIMES KAD2 +12206 ; [.3D5D.0020.0002.12206] # CUNEIFORM SIGN LU2 TIMES KAD3 +12207 ; [.3D5E.0020.0002.12207] # CUNEIFORM SIGN LU2 TIMES KAD3 PLUS ASH +12208 ; [.3D5F.0020.0002.12208] # CUNEIFORM SIGN LU2 TIMES KI +12209 ; [.3D60.0020.0002.12209] # CUNEIFORM SIGN LU2 TIMES LA PLUS ASH +1220A ; [.3D61.0020.0002.1220A] # CUNEIFORM SIGN LU2 TIMES LAGAB +1220B ; [.3D62.0020.0002.1220B] # CUNEIFORM SIGN LU2 TIMES ME PLUS EN +1220C ; [.3D63.0020.0002.1220C] # CUNEIFORM SIGN LU2 TIMES NE +1220D ; [.3D64.0020.0002.1220D] # CUNEIFORM SIGN LU2 TIMES NU +1220E ; [.3D65.0020.0002.1220E] # CUNEIFORM SIGN LU2 TIMES SI PLUS ASH +1220F ; [.3D66.0020.0002.1220F] # CUNEIFORM SIGN LU2 TIMES SIK2 PLUS BU +12210 ; [.3D67.0020.0002.12210] # CUNEIFORM SIGN LU2 TIMES TUG2 +12211 ; [.3D68.0020.0002.12211] # CUNEIFORM SIGN LU2 TENU +12212 ; [.3D69.0020.0002.12212] # CUNEIFORM SIGN LU2 CROSSING LU2 +12213 ; [.3D6A.0020.0002.12213] # CUNEIFORM SIGN LU2 OPPOSING LU2 +12214 ; [.3D6B.0020.0002.12214] # CUNEIFORM SIGN LU2 SQUARED +12215 ; [.3D6C.0020.0002.12215] # CUNEIFORM SIGN LU2 SHESHIG +12216 ; [.3D6D.0020.0002.12216] # CUNEIFORM SIGN LU3 +12217 ; [.3D6E.0020.0002.12217] # CUNEIFORM SIGN LUGAL +12218 ; [.3D6F.0020.0002.12218] # CUNEIFORM SIGN LUGAL OVER LUGAL +12219 ; [.3D70.0020.0002.12219] # CUNEIFORM SIGN LUGAL OPPOSING LUGAL +1221A ; [.3D71.0020.0002.1221A] # CUNEIFORM SIGN LUGAL SHESHIG +1221B ; [.3D72.0020.0002.1221B] # CUNEIFORM SIGN LUH +1221C ; [.3D73.0020.0002.1221C] # CUNEIFORM SIGN LUL +1221D ; [.3D74.0020.0002.1221D] # CUNEIFORM SIGN LUM +1221E ; [.3D75.0020.0002.1221E] # CUNEIFORM SIGN LUM OVER LUM +1221F ; [.3D76.0020.0002.1221F] # CUNEIFORM SIGN LUM OVER LUM GAR OVER GAR +12220 ; [.3D77.0020.0002.12220] # CUNEIFORM SIGN MA +12221 ; [.3D78.0020.0002.12221] # CUNEIFORM SIGN MA TIMES TAK4 +12222 ; [.3D79.0020.0002.12222] # CUNEIFORM SIGN MA GUNU +12223 ; [.3D7A.0020.0002.12223] # CUNEIFORM SIGN MA2 +12224 ; [.3D7B.0020.0002.12224] # CUNEIFORM SIGN MAH +12225 ; [.3D7C.0020.0002.12225] # CUNEIFORM SIGN MAR +12226 ; [.3D7D.0020.0002.12226] # CUNEIFORM SIGN MASH +12227 ; [.3D7E.0020.0002.12227] # CUNEIFORM SIGN MASH2 +12228 ; [.3D7F.0020.0002.12228] # CUNEIFORM SIGN ME +12229 ; [.3D80.0020.0002.12229] # CUNEIFORM SIGN MES +1222A ; [.3D81.0020.0002.1222A] # CUNEIFORM SIGN MI +1222B ; [.3D82.0020.0002.1222B] # CUNEIFORM SIGN MIN +1222C ; [.3D83.0020.0002.1222C] # CUNEIFORM SIGN MU +1222D ; [.3D84.0020.0002.1222D] # CUNEIFORM SIGN MU OVER MU +1222E ; [.3D85.0020.0002.1222E] # CUNEIFORM SIGN MUG +1222F ; [.3D86.0020.0002.1222F] # CUNEIFORM SIGN MUG GUNU +12230 ; [.3D87.0020.0002.12230] # CUNEIFORM SIGN MUNSUB +12231 ; [.3D88.0020.0002.12231] # CUNEIFORM SIGN MURGU2 +12232 ; [.3D89.0020.0002.12232] # CUNEIFORM SIGN MUSH +12233 ; [.3D8A.0020.0002.12233] # CUNEIFORM SIGN MUSH TIMES A +12234 ; [.3D8B.0020.0002.12234] # CUNEIFORM SIGN MUSH TIMES KUR +12235 ; [.3D8C.0020.0002.12235] # CUNEIFORM SIGN MUSH TIMES ZA +12236 ; [.3D8D.0020.0002.12236] # CUNEIFORM SIGN MUSH OVER MUSH +12237 ; [.3D8E.0020.0002.12237] # CUNEIFORM SIGN MUSH OVER MUSH TIMES A PLUS NA +12238 ; [.3D8F.0020.0002.12238] # CUNEIFORM SIGN MUSH CROSSING MUSH +12239 ; [.3D90.0020.0002.12239] # CUNEIFORM SIGN MUSH3 +1223A ; [.3D91.0020.0002.1223A] # CUNEIFORM SIGN MUSH3 TIMES A +1223B ; [.3D92.0020.0002.1223B] # CUNEIFORM SIGN MUSH3 TIMES A PLUS DI +1223C ; [.3D93.0020.0002.1223C] # CUNEIFORM SIGN MUSH3 TIMES DI +1223D ; [.3D94.0020.0002.1223D] # CUNEIFORM SIGN MUSH3 GUNU +1223E ; [.3D95.0020.0002.1223E] # CUNEIFORM SIGN NA +1223F ; [.3D96.0020.0002.1223F] # CUNEIFORM SIGN NA2 +12240 ; [.3D97.0020.0002.12240] # CUNEIFORM SIGN NAGA +12241 ; [.3D98.0020.0002.12241] # CUNEIFORM SIGN NAGA INVERTED +12242 ; [.3D99.0020.0002.12242] # CUNEIFORM SIGN NAGA TIMES SHU TENU +12243 ; [.3D9A.0020.0002.12243] # CUNEIFORM SIGN NAGA OPPOSING NAGA +12244 ; [.3D9B.0020.0002.12244] # CUNEIFORM SIGN NAGAR +12245 ; [.3D9C.0020.0002.12245] # CUNEIFORM SIGN NAM NUTILLU +12246 ; [.3D9D.0020.0002.12246] # CUNEIFORM SIGN NAM +12247 ; [.3D9E.0020.0002.12247] # CUNEIFORM SIGN NAM2 +12248 ; [.3D9F.0020.0002.12248] # CUNEIFORM SIGN NE +12249 ; [.3DA0.0020.0002.12249] # CUNEIFORM SIGN NE TIMES A +1224A ; [.3DA1.0020.0002.1224A] # CUNEIFORM SIGN NE TIMES UD +1224B ; [.3DA2.0020.0002.1224B] # CUNEIFORM SIGN NE SHESHIG +1224C ; [.3DA3.0020.0002.1224C] # CUNEIFORM SIGN NI +1224D ; [.3DA4.0020.0002.1224D] # CUNEIFORM SIGN NI TIMES E +1224E ; [.3DA5.0020.0002.1224E] # CUNEIFORM SIGN NI2 +1224F ; [.3DA6.0020.0002.1224F] # CUNEIFORM SIGN NIM +12250 ; [.3DA7.0020.0002.12250] # CUNEIFORM SIGN NIM TIMES GAN2 TENU +12251 ; [.3DA8.0020.0002.12251] # CUNEIFORM SIGN NIM TIMES GAR PLUS GAN2 TENU +12252 ; [.3DA9.0020.0002.12252] # CUNEIFORM SIGN NINDA2 +12253 ; [.3DAA.0020.0002.12253] # CUNEIFORM SIGN NINDA2 TIMES AN +12254 ; [.3DAB.0020.0002.12254] # CUNEIFORM SIGN NINDA2 TIMES ASH +12255 ; [.3DAC.0020.0002.12255] # CUNEIFORM SIGN NINDA2 TIMES ASH PLUS ASH +12256 ; [.3DAD.0020.0002.12256] # CUNEIFORM SIGN NINDA2 TIMES GUD +12257 ; [.3DAE.0020.0002.12257] # CUNEIFORM SIGN NINDA2 TIMES ME PLUS GAN2 TENU +12258 ; [.3DAF.0020.0002.12258] # CUNEIFORM SIGN NINDA2 TIMES NE +12259 ; [.3DB0.0020.0002.12259] # CUNEIFORM SIGN NINDA2 TIMES NUN +1225A ; [.3DB1.0020.0002.1225A] # CUNEIFORM SIGN NINDA2 TIMES SHE +1225B ; [.3DB2.0020.0002.1225B] # CUNEIFORM SIGN NINDA2 TIMES SHE PLUS A AN +1225C ; [.3DB3.0020.0002.1225C] # CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH +1225D ; [.3DB4.0020.0002.1225D] # CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH PLUS ASH +1225E ; [.3DB5.0020.0002.1225E] # CUNEIFORM SIGN NINDA2 TIMES U2 PLUS ASH +1225F ; [.3DB6.0020.0002.1225F] # CUNEIFORM SIGN NINDA2 TIMES USH +12260 ; [.3DB7.0020.0002.12260] # CUNEIFORM SIGN NISAG +12261 ; [.3DB8.0020.0002.12261] # CUNEIFORM SIGN NU +12262 ; [.3DB9.0020.0002.12262] # CUNEIFORM SIGN NU11 +12263 ; [.3DBA.0020.0002.12263] # CUNEIFORM SIGN NUN +12264 ; [.3DBB.0020.0002.12264] # CUNEIFORM SIGN NUN LAGAR TIMES GAR +12265 ; [.3DBC.0020.0002.12265] # CUNEIFORM SIGN NUN LAGAR TIMES MASH +12266 ; [.3DBD.0020.0002.12266] # CUNEIFORM SIGN NUN LAGAR TIMES SAL +12267 ; [.3DBE.0020.0002.12267] # CUNEIFORM SIGN NUN LAGAR TIMES SAL OVER NUN LAGAR TIMES SAL +12268 ; [.3DBF.0020.0002.12268] # CUNEIFORM SIGN NUN LAGAR TIMES USH +12269 ; [.3DC0.0020.0002.12269] # CUNEIFORM SIGN NUN TENU +1226A ; [.3DC1.0020.0002.1226A] # CUNEIFORM SIGN NUN OVER NUN +1226B ; [.3DC2.0020.0002.1226B] # CUNEIFORM SIGN NUN CROSSING NUN +1226C ; [.3DC3.0020.0002.1226C] # CUNEIFORM SIGN NUN CROSSING NUN LAGAR OVER LAGAR +1226D ; [.3DC4.0020.0002.1226D] # CUNEIFORM SIGN NUNUZ +1226E ; [.3DC5.0020.0002.1226E] # CUNEIFORM SIGN NUNUZ AB2 TIMES ASHGAB +1226F ; [.3DC6.0020.0002.1226F] # CUNEIFORM SIGN NUNUZ AB2 TIMES BI +12270 ; [.3DC7.0020.0002.12270] # CUNEIFORM SIGN NUNUZ AB2 TIMES DUG +12271 ; [.3DC8.0020.0002.12271] # CUNEIFORM SIGN NUNUZ AB2 TIMES GUD +12272 ; [.3DC9.0020.0002.12272] # CUNEIFORM SIGN NUNUZ AB2 TIMES IGI GUNU +12273 ; [.3DCA.0020.0002.12273] # CUNEIFORM SIGN NUNUZ AB2 TIMES KAD3 +12274 ; [.3DCB.0020.0002.12274] # CUNEIFORM SIGN NUNUZ AB2 TIMES LA +12275 ; [.3DCC.0020.0002.12275] # CUNEIFORM SIGN NUNUZ AB2 TIMES NE +12276 ; [.3DCD.0020.0002.12276] # CUNEIFORM SIGN NUNUZ AB2 TIMES SILA3 +12277 ; [.3DCE.0020.0002.12277] # CUNEIFORM SIGN NUNUZ AB2 TIMES U2 +12278 ; [.3DCF.0020.0002.12278] # CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI +12279 ; [.3DD0.0020.0002.12279] # CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI U +1227A ; [.3DD1.0020.0002.1227A] # CUNEIFORM SIGN PA +1227B ; [.3DD2.0020.0002.1227B] # CUNEIFORM SIGN PAD +1227C ; [.3DD3.0020.0002.1227C] # CUNEIFORM SIGN PAN +1227D ; [.3DD4.0020.0002.1227D] # CUNEIFORM SIGN PAP +1227E ; [.3DD5.0020.0002.1227E] # CUNEIFORM SIGN PESH2 +1227F ; [.3DD6.0020.0002.1227F] # CUNEIFORM SIGN PI +12280 ; [.3DD7.0020.0002.12280] # CUNEIFORM SIGN PI TIMES A +12281 ; [.3DD8.0020.0002.12281] # CUNEIFORM SIGN PI TIMES AB +12282 ; [.3DD9.0020.0002.12282] # CUNEIFORM SIGN PI TIMES BI +12283 ; [.3DDA.0020.0002.12283] # CUNEIFORM SIGN PI TIMES BU +12284 ; [.3DDB.0020.0002.12284] # CUNEIFORM SIGN PI TIMES E +12285 ; [.3DDC.0020.0002.12285] # CUNEIFORM SIGN PI TIMES I +12286 ; [.3DDD.0020.0002.12286] # CUNEIFORM SIGN PI TIMES IB +12287 ; [.3DDE.0020.0002.12287] # CUNEIFORM SIGN PI TIMES U +12288 ; [.3DDF.0020.0002.12288] # CUNEIFORM SIGN PI TIMES U2 +12289 ; [.3DE0.0020.0002.12289] # CUNEIFORM SIGN PI CROSSING PI +1228A ; [.3DE1.0020.0002.1228A] # CUNEIFORM SIGN PIRIG +1228B ; [.3DE2.0020.0002.1228B] # CUNEIFORM SIGN PIRIG TIMES KAL +1228C ; [.3DE3.0020.0002.1228C] # CUNEIFORM SIGN PIRIG TIMES UD +1228D ; [.3DE4.0020.0002.1228D] # CUNEIFORM SIGN PIRIG TIMES ZA +1228E ; [.3DE5.0020.0002.1228E] # CUNEIFORM SIGN PIRIG OPPOSING PIRIG +1228F ; [.3DE6.0020.0002.1228F] # CUNEIFORM SIGN RA +12290 ; [.3DE7.0020.0002.12290] # CUNEIFORM SIGN RAB +12291 ; [.3DE8.0020.0002.12291] # CUNEIFORM SIGN RI +12292 ; [.3DE9.0020.0002.12292] # CUNEIFORM SIGN RU +12293 ; [.3DEA.0020.0002.12293] # CUNEIFORM SIGN SA +12294 ; [.3DEB.0020.0002.12294] # CUNEIFORM SIGN SAG NUTILLU +12295 ; [.3DEC.0020.0002.12295] # CUNEIFORM SIGN SAG +12296 ; [.3DED.0020.0002.12296] # CUNEIFORM SIGN SAG TIMES A +12297 ; [.3DEE.0020.0002.12297] # CUNEIFORM SIGN SAG TIMES DU +12298 ; [.3DEF.0020.0002.12298] # CUNEIFORM SIGN SAG TIMES DUB +12299 ; [.3DF0.0020.0002.12299] # CUNEIFORM SIGN SAG TIMES HA +1229A ; [.3DF1.0020.0002.1229A] # CUNEIFORM SIGN SAG TIMES KAK +1229B ; [.3DF2.0020.0002.1229B] # CUNEIFORM SIGN SAG TIMES KUR +1229C ; [.3DF3.0020.0002.1229C] # CUNEIFORM SIGN SAG TIMES LUM +1229D ; [.3DF4.0020.0002.1229D] # CUNEIFORM SIGN SAG TIMES MI +1229E ; [.3DF5.0020.0002.1229E] # CUNEIFORM SIGN SAG TIMES NUN +1229F ; [.3DF6.0020.0002.1229F] # CUNEIFORM SIGN SAG TIMES SAL +122A0 ; [.3DF7.0020.0002.122A0] # CUNEIFORM SIGN SAG TIMES SHID +122A1 ; [.3DF8.0020.0002.122A1] # CUNEIFORM SIGN SAG TIMES TAB +122A2 ; [.3DF9.0020.0002.122A2] # CUNEIFORM SIGN SAG TIMES U2 +122A3 ; [.3DFA.0020.0002.122A3] # CUNEIFORM SIGN SAG TIMES UB +122A4 ; [.3DFB.0020.0002.122A4] # CUNEIFORM SIGN SAG TIMES UM +122A5 ; [.3DFC.0020.0002.122A5] # CUNEIFORM SIGN SAG TIMES UR +122A6 ; [.3DFD.0020.0002.122A6] # CUNEIFORM SIGN SAG TIMES USH +122A7 ; [.3DFE.0020.0002.122A7] # CUNEIFORM SIGN SAG OVER SAG +122A8 ; [.3DFF.0020.0002.122A8] # CUNEIFORM SIGN SAG GUNU +122A9 ; [.3E00.0020.0002.122A9] # CUNEIFORM SIGN SAL +122AA ; [.3E01.0020.0002.122AA] # CUNEIFORM SIGN SAL LAGAB TIMES ASH2 +122AB ; [.3E02.0020.0002.122AB] # CUNEIFORM SIGN SANGA2 +122AC ; [.3E03.0020.0002.122AC] # CUNEIFORM SIGN SAR +122AD ; [.3E04.0020.0002.122AD] # CUNEIFORM SIGN SHA +122AE ; [.3E05.0020.0002.122AE] # CUNEIFORM SIGN SHA3 +122AF ; [.3E06.0020.0002.122AF] # CUNEIFORM SIGN SHA3 TIMES A +122B0 ; [.3E07.0020.0002.122B0] # CUNEIFORM SIGN SHA3 TIMES BAD +122B1 ; [.3E08.0020.0002.122B1] # CUNEIFORM SIGN SHA3 TIMES GISH +122B2 ; [.3E09.0020.0002.122B2] # CUNEIFORM SIGN SHA3 TIMES NE +122B3 ; [.3E0A.0020.0002.122B3] # CUNEIFORM SIGN SHA3 TIMES SHU2 +122B4 ; [.3E0B.0020.0002.122B4] # CUNEIFORM SIGN SHA3 TIMES TUR +122B5 ; [.3E0C.0020.0002.122B5] # CUNEIFORM SIGN SHA3 TIMES U +122B6 ; [.3E0D.0020.0002.122B6] # CUNEIFORM SIGN SHA3 TIMES U PLUS A +122B7 ; [.3E0E.0020.0002.122B7] # CUNEIFORM SIGN SHA6 +122B8 ; [.3E0F.0020.0002.122B8] # CUNEIFORM SIGN SHAB6 +122B9 ; [.3E10.0020.0002.122B9] # CUNEIFORM SIGN SHAR2 +122BA ; [.3E11.0020.0002.122BA] # CUNEIFORM SIGN SHE +122BB ; [.3E12.0020.0002.122BB] # CUNEIFORM SIGN SHE HU +122BC ; [.3E13.0020.0002.122BC] # CUNEIFORM SIGN SHE OVER SHE GAD OVER GAD GAR OVER GAR +122BD ; [.3E14.0020.0002.122BD] # CUNEIFORM SIGN SHE OVER SHE TAB OVER TAB GAR OVER GAR +122BE ; [.3E15.0020.0002.122BE] # CUNEIFORM SIGN SHEG9 +122BF ; [.3E16.0020.0002.122BF] # CUNEIFORM SIGN SHEN +122C0 ; [.3E17.0020.0002.122C0] # CUNEIFORM SIGN SHESH +122C1 ; [.3E18.0020.0002.122C1] # CUNEIFORM SIGN SHESH2 +122C2 ; [.3E19.0020.0002.122C2] # CUNEIFORM SIGN SHESHLAM +122C3 ; [.3E1A.0020.0002.122C3] # CUNEIFORM SIGN SHID +122C4 ; [.3E1B.0020.0002.122C4] # CUNEIFORM SIGN SHID TIMES A +122C5 ; [.3E1C.0020.0002.122C5] # CUNEIFORM SIGN SHID TIMES IM +122C6 ; [.3E1D.0020.0002.122C6] # CUNEIFORM SIGN SHIM +122C7 ; [.3E1E.0020.0002.122C7] # CUNEIFORM SIGN SHIM TIMES A +122C8 ; [.3E1F.0020.0002.122C8] # CUNEIFORM SIGN SHIM TIMES BAL +122C9 ; [.3E20.0020.0002.122C9] # CUNEIFORM SIGN SHIM TIMES BULUG +122CA ; [.3E21.0020.0002.122CA] # CUNEIFORM SIGN SHIM TIMES DIN +122CB ; [.3E22.0020.0002.122CB] # CUNEIFORM SIGN SHIM TIMES GAR +122CC ; [.3E23.0020.0002.122CC] # CUNEIFORM SIGN SHIM TIMES IGI +122CD ; [.3E24.0020.0002.122CD] # CUNEIFORM SIGN SHIM TIMES IGI GUNU +122CE ; [.3E25.0020.0002.122CE] # CUNEIFORM SIGN SHIM TIMES KUSHU2 +122CF ; [.3E26.0020.0002.122CF] # CUNEIFORM SIGN SHIM TIMES LUL +122D0 ; [.3E27.0020.0002.122D0] # CUNEIFORM SIGN SHIM TIMES MUG +122D1 ; [.3E28.0020.0002.122D1] # CUNEIFORM SIGN SHIM TIMES SAL +122D2 ; [.3E29.0020.0002.122D2] # CUNEIFORM SIGN SHINIG +122D3 ; [.3E2A.0020.0002.122D3] # CUNEIFORM SIGN SHIR +122D4 ; [.3E2B.0020.0002.122D4] # CUNEIFORM SIGN SHIR TENU +122D5 ; [.3E2C.0020.0002.122D5] # CUNEIFORM SIGN SHIR OVER SHIR BUR OVER BUR +122D6 ; [.3E2D.0020.0002.122D6] # CUNEIFORM SIGN SHITA +122D7 ; [.3E2E.0020.0002.122D7] # CUNEIFORM SIGN SHU +122D8 ; [.3E2F.0020.0002.122D8] # CUNEIFORM SIGN SHU OVER INVERTED SHU +122D9 ; [.3E30.0020.0002.122D9] # CUNEIFORM SIGN SHU2 +122DA ; [.3E31.0020.0002.122DA] # CUNEIFORM SIGN SHUBUR +122DB ; [.3E32.0020.0002.122DB] # CUNEIFORM SIGN SI +122DC ; [.3E33.0020.0002.122DC] # CUNEIFORM SIGN SI GUNU +122DD ; [.3E34.0020.0002.122DD] # CUNEIFORM SIGN SIG +122DE ; [.3E35.0020.0002.122DE] # CUNEIFORM SIGN SIG4 +122DF ; [.3E36.0020.0002.122DF] # CUNEIFORM SIGN SIG4 OVER SIG4 SHU2 +122E0 ; [.3E37.0020.0002.122E0] # CUNEIFORM SIGN SIK2 +122E1 ; [.3E38.0020.0002.122E1] # CUNEIFORM SIGN SILA3 +122E2 ; [.3E39.0020.0002.122E2] # CUNEIFORM SIGN SU +122E3 ; [.3E3A.0020.0002.122E3] # CUNEIFORM SIGN SU OVER SU +122E4 ; [.3E3B.0020.0002.122E4] # CUNEIFORM SIGN SUD +122E5 ; [.3E3C.0020.0002.122E5] # CUNEIFORM SIGN SUD2 +122E6 ; [.3E3D.0020.0002.122E6] # CUNEIFORM SIGN SUHUR +122E7 ; [.3E3E.0020.0002.122E7] # CUNEIFORM SIGN SUM +122E8 ; [.3E3F.0020.0002.122E8] # CUNEIFORM SIGN SUMASH +122E9 ; [.3E40.0020.0002.122E9] # CUNEIFORM SIGN SUR +122EA ; [.3E41.0020.0002.122EA] # CUNEIFORM SIGN SUR9 +122EB ; [.3E42.0020.0002.122EB] # CUNEIFORM SIGN TA +122EC ; [.3E43.0020.0002.122EC] # CUNEIFORM SIGN TA ASTERISK +122ED ; [.3E44.0020.0002.122ED] # CUNEIFORM SIGN TA TIMES HI +122EE ; [.3E45.0020.0002.122EE] # CUNEIFORM SIGN TA TIMES MI +122EF ; [.3E46.0020.0002.122EF] # CUNEIFORM SIGN TA GUNU +122F0 ; [.3E47.0020.0002.122F0] # CUNEIFORM SIGN TAB +122F1 ; [.3E48.0020.0002.122F1] # CUNEIFORM SIGN TAB OVER TAB NI OVER NI DISH OVER DISH +122F2 ; [.3E49.0020.0002.122F2] # CUNEIFORM SIGN TAB SQUARED +122F3 ; [.3E4A.0020.0002.122F3] # CUNEIFORM SIGN TAG +122F4 ; [.3E4B.0020.0002.122F4] # CUNEIFORM SIGN TAG TIMES BI +122F5 ; [.3E4C.0020.0002.122F5] # CUNEIFORM SIGN TAG TIMES GUD +122F6 ; [.3E4D.0020.0002.122F6] # CUNEIFORM SIGN TAG TIMES SHE +122F7 ; [.3E4E.0020.0002.122F7] # CUNEIFORM SIGN TAG TIMES SHU +122F8 ; [.3E4F.0020.0002.122F8] # CUNEIFORM SIGN TAG TIMES TUG2 +122F9 ; [.3E50.0020.0002.122F9] # CUNEIFORM SIGN TAG TIMES UD +122FA ; [.3E51.0020.0002.122FA] # CUNEIFORM SIGN TAK4 +122FB ; [.3E52.0020.0002.122FB] # CUNEIFORM SIGN TAR +122FC ; [.3E53.0020.0002.122FC] # CUNEIFORM SIGN TE +122FD ; [.3E54.0020.0002.122FD] # CUNEIFORM SIGN TE GUNU +122FE ; [.3E55.0020.0002.122FE] # CUNEIFORM SIGN TI +122FF ; [.3E56.0020.0002.122FF] # CUNEIFORM SIGN TI TENU +12300 ; [.3E57.0020.0002.12300] # CUNEIFORM SIGN TIL +12301 ; [.3E58.0020.0002.12301] # CUNEIFORM SIGN TIR +12302 ; [.3E59.0020.0002.12302] # CUNEIFORM SIGN TIR TIMES TAK4 +12303 ; [.3E5A.0020.0002.12303] # CUNEIFORM SIGN TIR OVER TIR +12304 ; [.3E5B.0020.0002.12304] # CUNEIFORM SIGN TIR OVER TIR GAD OVER GAD GAR OVER GAR +12305 ; [.3E5C.0020.0002.12305] # CUNEIFORM SIGN TU +12306 ; [.3E5D.0020.0002.12306] # CUNEIFORM SIGN TUG2 +12307 ; [.3E5E.0020.0002.12307] # CUNEIFORM SIGN TUK +12308 ; [.3E5F.0020.0002.12308] # CUNEIFORM SIGN TUM +12309 ; [.3E60.0020.0002.12309] # CUNEIFORM SIGN TUR +1230A ; [.3E61.0020.0002.1230A] # CUNEIFORM SIGN TUR OVER TUR ZA OVER ZA +1230B ; [.3E62.0020.0002.1230B] # CUNEIFORM SIGN U +1230C ; [.3E63.0020.0002.1230C] # CUNEIFORM SIGN U GUD +1230D ; [.3E64.0020.0002.1230D] # CUNEIFORM SIGN U U U +1230E ; [.3E65.0020.0002.1230E] # CUNEIFORM SIGN U OVER U PA OVER PA GAR OVER GAR +1230F ; [.3E66.0020.0002.1230F] # CUNEIFORM SIGN U OVER U SUR OVER SUR +12310 ; [.3E67.0020.0002.12310] # CUNEIFORM SIGN U OVER U U REVERSED OVER U REVERSED +12311 ; [.3E68.0020.0002.12311] # CUNEIFORM SIGN U2 +12312 ; [.3E69.0020.0002.12312] # CUNEIFORM SIGN UB +12313 ; [.3E6A.0020.0002.12313] # CUNEIFORM SIGN UD +12314 ; [.3E6B.0020.0002.12314] # CUNEIFORM SIGN UD KUSHU2 +12315 ; [.3E6C.0020.0002.12315] # CUNEIFORM SIGN UD TIMES BAD +12316 ; [.3E6D.0020.0002.12316] # CUNEIFORM SIGN UD TIMES MI +12317 ; [.3E6E.0020.0002.12317] # CUNEIFORM SIGN UD TIMES U PLUS U PLUS U +12318 ; [.3E6F.0020.0002.12318] # CUNEIFORM SIGN UD TIMES U PLUS U PLUS U GUNU +12319 ; [.3E70.0020.0002.12319] # CUNEIFORM SIGN UD GUNU +1231A ; [.3E71.0020.0002.1231A] # CUNEIFORM SIGN UD SHESHIG +1231B ; [.3E72.0020.0002.1231B] # CUNEIFORM SIGN UD SHESHIG TIMES BAD +1231C ; [.3E73.0020.0002.1231C] # CUNEIFORM SIGN UDUG +1231D ; [.3E74.0020.0002.1231D] # CUNEIFORM SIGN UM +1231E ; [.3E75.0020.0002.1231E] # CUNEIFORM SIGN UM TIMES LAGAB +1231F ; [.3E76.0020.0002.1231F] # CUNEIFORM SIGN UM TIMES ME PLUS DA +12320 ; [.3E77.0020.0002.12320] # CUNEIFORM SIGN UM TIMES SHA3 +12321 ; [.3E78.0020.0002.12321] # CUNEIFORM SIGN UM TIMES U +12322 ; [.3E79.0020.0002.12322] # CUNEIFORM SIGN UMBIN +12323 ; [.3E7A.0020.0002.12323] # CUNEIFORM SIGN UMUM +12324 ; [.3E7B.0020.0002.12324] # CUNEIFORM SIGN UMUM TIMES KASKAL +12325 ; [.3E7C.0020.0002.12325] # CUNEIFORM SIGN UMUM TIMES PA +12326 ; [.3E7D.0020.0002.12326] # CUNEIFORM SIGN UN +12327 ; [.3E7E.0020.0002.12327] # CUNEIFORM SIGN UN GUNU +12328 ; [.3E7F.0020.0002.12328] # CUNEIFORM SIGN UR +12329 ; [.3E80.0020.0002.12329] # CUNEIFORM SIGN UR CROSSING UR +1232A ; [.3E81.0020.0002.1232A] # CUNEIFORM SIGN UR SHESHIG +1232B ; [.3E82.0020.0002.1232B] # CUNEIFORM SIGN UR2 +1232C ; [.3E83.0020.0002.1232C] # CUNEIFORM SIGN UR2 TIMES A PLUS HA +1232D ; [.3E84.0020.0002.1232D] # CUNEIFORM SIGN UR2 TIMES A PLUS NA +1232E ; [.3E85.0020.0002.1232E] # CUNEIFORM SIGN UR2 TIMES AL +1232F ; [.3E86.0020.0002.1232F] # CUNEIFORM SIGN UR2 TIMES HA +12330 ; [.3E87.0020.0002.12330] # CUNEIFORM SIGN UR2 TIMES NUN +12331 ; [.3E88.0020.0002.12331] # CUNEIFORM SIGN UR2 TIMES U2 +12332 ; [.3E89.0020.0002.12332] # CUNEIFORM SIGN UR2 TIMES U2 PLUS ASH +12333 ; [.3E8A.0020.0002.12333] # CUNEIFORM SIGN UR2 TIMES U2 PLUS BI +12334 ; [.3E8B.0020.0002.12334] # CUNEIFORM SIGN UR4 +12335 ; [.3E8C.0020.0002.12335] # CUNEIFORM SIGN URI +12336 ; [.3E8D.0020.0002.12336] # CUNEIFORM SIGN URI3 +12337 ; [.3E8E.0020.0002.12337] # CUNEIFORM SIGN URU +12338 ; [.3E8F.0020.0002.12338] # CUNEIFORM SIGN URU TIMES A +12339 ; [.3E90.0020.0002.12339] # CUNEIFORM SIGN URU TIMES ASHGAB +1233A ; [.3E91.0020.0002.1233A] # CUNEIFORM SIGN URU TIMES BAR +1233B ; [.3E92.0020.0002.1233B] # CUNEIFORM SIGN URU TIMES DUN +1233C ; [.3E93.0020.0002.1233C] # CUNEIFORM SIGN URU TIMES GA +1233D ; [.3E94.0020.0002.1233D] # CUNEIFORM SIGN URU TIMES GAL +1233E ; [.3E95.0020.0002.1233E] # CUNEIFORM SIGN URU TIMES GAN2 TENU +1233F ; [.3E96.0020.0002.1233F] # CUNEIFORM SIGN URU TIMES GAR +12340 ; [.3E97.0020.0002.12340] # CUNEIFORM SIGN URU TIMES GU +12341 ; [.3E98.0020.0002.12341] # CUNEIFORM SIGN URU TIMES HA +12342 ; [.3E99.0020.0002.12342] # CUNEIFORM SIGN URU TIMES IGI +12343 ; [.3E9A.0020.0002.12343] # CUNEIFORM SIGN URU TIMES IM +12344 ; [.3E9B.0020.0002.12344] # CUNEIFORM SIGN URU TIMES ISH +12345 ; [.3E9C.0020.0002.12345] # CUNEIFORM SIGN URU TIMES KI +12346 ; [.3E9D.0020.0002.12346] # CUNEIFORM SIGN URU TIMES LUM +12347 ; [.3E9E.0020.0002.12347] # CUNEIFORM SIGN URU TIMES MIN +12348 ; [.3E9F.0020.0002.12348] # CUNEIFORM SIGN URU TIMES PA +12349 ; [.3EA0.0020.0002.12349] # CUNEIFORM SIGN URU TIMES SHE +1234A ; [.3EA1.0020.0002.1234A] # CUNEIFORM SIGN URU TIMES SIG4 +1234B ; [.3EA2.0020.0002.1234B] # CUNEIFORM SIGN URU TIMES TU +1234C ; [.3EA3.0020.0002.1234C] # CUNEIFORM SIGN URU TIMES U PLUS GUD +1234D ; [.3EA4.0020.0002.1234D] # CUNEIFORM SIGN URU TIMES UD +1234E ; [.3EA5.0020.0002.1234E] # CUNEIFORM SIGN URU TIMES URUDA +1234F ; [.3EA6.0020.0002.1234F] # CUNEIFORM SIGN URUDA +12350 ; [.3EA7.0020.0002.12350] # CUNEIFORM SIGN URUDA TIMES U +12351 ; [.3EA8.0020.0002.12351] # CUNEIFORM SIGN USH +12352 ; [.3EA9.0020.0002.12352] # CUNEIFORM SIGN USH TIMES A +12353 ; [.3EAA.0020.0002.12353] # CUNEIFORM SIGN USH TIMES KU +12354 ; [.3EAB.0020.0002.12354] # CUNEIFORM SIGN USH TIMES KUR +12355 ; [.3EAC.0020.0002.12355] # CUNEIFORM SIGN USH TIMES TAK4 +12356 ; [.3EAD.0020.0002.12356] # CUNEIFORM SIGN USHX +12357 ; [.3EAE.0020.0002.12357] # CUNEIFORM SIGN USH2 +12358 ; [.3EAF.0020.0002.12358] # CUNEIFORM SIGN USHUMX +12359 ; [.3EB0.0020.0002.12359] # CUNEIFORM SIGN UTUKI +1235A ; [.3EB1.0020.0002.1235A] # CUNEIFORM SIGN UZ3 +1235B ; [.3EB2.0020.0002.1235B] # CUNEIFORM SIGN UZ3 TIMES KASKAL +1235C ; [.3EB3.0020.0002.1235C] # CUNEIFORM SIGN UZU +1235D ; [.3EB4.0020.0002.1235D] # CUNEIFORM SIGN ZA +1235E ; [.3EB5.0020.0002.1235E] # CUNEIFORM SIGN ZA TENU +1235F ; [.3EB6.0020.0002.1235F] # CUNEIFORM SIGN ZA SQUARED TIMES KUR +12360 ; [.3EB7.0020.0002.12360] # CUNEIFORM SIGN ZAG +12361 ; [.3EB8.0020.0002.12361] # CUNEIFORM SIGN ZAMX +12362 ; [.3EB9.0020.0002.12362] # CUNEIFORM SIGN ZE2 +12363 ; [.3EBA.0020.0002.12363] # CUNEIFORM SIGN ZI +12364 ; [.3EBB.0020.0002.12364] # CUNEIFORM SIGN ZI OVER ZI +12365 ; [.3EBC.0020.0002.12365] # CUNEIFORM SIGN ZI3 +12366 ; [.3EBD.0020.0002.12366] # CUNEIFORM SIGN ZIB +12367 ; [.3EBE.0020.0002.12367] # CUNEIFORM SIGN ZIB KABA TENU +12368 ; [.3EBF.0020.0002.12368] # CUNEIFORM SIGN ZIG +12369 ; [.3EC0.0020.0002.12369] # CUNEIFORM SIGN ZIZ2 +1236A ; [.3EC1.0020.0002.1236A] # CUNEIFORM SIGN ZU +1236B ; [.3EC2.0020.0002.1236B] # CUNEIFORM SIGN ZU5 +1236C ; [.3EC3.0020.0002.1236C] # CUNEIFORM SIGN ZU5 TIMES A +1236D ; [.3EC4.0020.0002.1236D] # CUNEIFORM SIGN ZUBUR +1236E ; [.3EC5.0020.0002.1236E] # CUNEIFORM SIGN ZUM +13000 ; [.3EC6.0020.0002.13000] # EGYPTIAN HIEROGLYPH A001 +13001 ; [.3EC7.0020.0002.13001] # EGYPTIAN HIEROGLYPH A002 +13002 ; [.3EC8.0020.0002.13002] # EGYPTIAN HIEROGLYPH A003 +13003 ; [.3EC9.0020.0002.13003] # EGYPTIAN HIEROGLYPH A004 +13004 ; [.3ECA.0020.0002.13004] # EGYPTIAN HIEROGLYPH A005 +13005 ; [.3ECB.0020.0002.13005] # EGYPTIAN HIEROGLYPH A005A +13006 ; [.3ECC.0020.0002.13006] # EGYPTIAN HIEROGLYPH A006 +13007 ; [.3ECD.0020.0002.13007] # EGYPTIAN HIEROGLYPH A006A +13008 ; [.3ECE.0020.0002.13008] # EGYPTIAN HIEROGLYPH A006B +13009 ; [.3ECF.0020.0002.13009] # EGYPTIAN HIEROGLYPH A007 +1300A ; [.3ED0.0020.0002.1300A] # EGYPTIAN HIEROGLYPH A008 +1300B ; [.3ED1.0020.0002.1300B] # EGYPTIAN HIEROGLYPH A009 +1300C ; [.3ED2.0020.0002.1300C] # EGYPTIAN HIEROGLYPH A010 +1300D ; [.3ED3.0020.0002.1300D] # EGYPTIAN HIEROGLYPH A011 +1300E ; [.3ED4.0020.0002.1300E] # EGYPTIAN HIEROGLYPH A012 +1300F ; [.3ED5.0020.0002.1300F] # EGYPTIAN HIEROGLYPH A013 +13010 ; [.3ED6.0020.0002.13010] # EGYPTIAN HIEROGLYPH A014 +13011 ; [.3ED7.0020.0002.13011] # EGYPTIAN HIEROGLYPH A014A +13012 ; [.3ED8.0020.0002.13012] # EGYPTIAN HIEROGLYPH A015 +13013 ; [.3ED9.0020.0002.13013] # EGYPTIAN HIEROGLYPH A016 +13014 ; [.3EDA.0020.0002.13014] # EGYPTIAN HIEROGLYPH A017 +13015 ; [.3EDB.0020.0002.13015] # EGYPTIAN HIEROGLYPH A017A +13016 ; [.3EDC.0020.0002.13016] # EGYPTIAN HIEROGLYPH A018 +13017 ; [.3EDD.0020.0002.13017] # EGYPTIAN HIEROGLYPH A019 +13018 ; [.3EDE.0020.0002.13018] # EGYPTIAN HIEROGLYPH A020 +13019 ; [.3EDF.0020.0002.13019] # EGYPTIAN HIEROGLYPH A021 +1301A ; [.3EE0.0020.0002.1301A] # EGYPTIAN HIEROGLYPH A022 +1301B ; [.3EE1.0020.0002.1301B] # EGYPTIAN HIEROGLYPH A023 +1301C ; [.3EE2.0020.0002.1301C] # EGYPTIAN HIEROGLYPH A024 +1301D ; [.3EE3.0020.0002.1301D] # EGYPTIAN HIEROGLYPH A025 +1301E ; [.3EE4.0020.0002.1301E] # EGYPTIAN HIEROGLYPH A026 +1301F ; [.3EE5.0020.0002.1301F] # EGYPTIAN HIEROGLYPH A027 +13020 ; [.3EE6.0020.0002.13020] # EGYPTIAN HIEROGLYPH A028 +13021 ; [.3EE7.0020.0002.13021] # EGYPTIAN HIEROGLYPH A029 +13022 ; [.3EE8.0020.0002.13022] # EGYPTIAN HIEROGLYPH A030 +13023 ; [.3EE9.0020.0002.13023] # EGYPTIAN HIEROGLYPH A031 +13024 ; [.3EEA.0020.0002.13024] # EGYPTIAN HIEROGLYPH A032 +13025 ; [.3EEB.0020.0002.13025] # EGYPTIAN HIEROGLYPH A032A +13026 ; [.3EEC.0020.0002.13026] # EGYPTIAN HIEROGLYPH A033 +13027 ; [.3EED.0020.0002.13027] # EGYPTIAN HIEROGLYPH A034 +13028 ; [.3EEE.0020.0002.13028] # EGYPTIAN HIEROGLYPH A035 +13029 ; [.3EEF.0020.0002.13029] # EGYPTIAN HIEROGLYPH A036 +1302A ; [.3EF0.0020.0002.1302A] # EGYPTIAN HIEROGLYPH A037 +1302B ; [.3EF1.0020.0002.1302B] # EGYPTIAN HIEROGLYPH A038 +1302C ; [.3EF2.0020.0002.1302C] # EGYPTIAN HIEROGLYPH A039 +1302D ; [.3EF3.0020.0002.1302D] # EGYPTIAN HIEROGLYPH A040 +1302E ; [.3EF4.0020.0002.1302E] # EGYPTIAN HIEROGLYPH A040A +1302F ; [.3EF5.0020.0002.1302F] # EGYPTIAN HIEROGLYPH A041 +13030 ; [.3EF6.0020.0002.13030] # EGYPTIAN HIEROGLYPH A042 +13031 ; [.3EF7.0020.0002.13031] # EGYPTIAN HIEROGLYPH A042A +13032 ; [.3EF8.0020.0002.13032] # EGYPTIAN HIEROGLYPH A043 +13033 ; [.3EF9.0020.0002.13033] # EGYPTIAN HIEROGLYPH A043A +13034 ; [.3EFA.0020.0002.13034] # EGYPTIAN HIEROGLYPH A044 +13035 ; [.3EFB.0020.0002.13035] # EGYPTIAN HIEROGLYPH A045 +13036 ; [.3EFC.0020.0002.13036] # EGYPTIAN HIEROGLYPH A045A +13037 ; [.3EFD.0020.0002.13037] # EGYPTIAN HIEROGLYPH A046 +13038 ; [.3EFE.0020.0002.13038] # EGYPTIAN HIEROGLYPH A047 +13039 ; [.3EFF.0020.0002.13039] # EGYPTIAN HIEROGLYPH A048 +1303A ; [.3F00.0020.0002.1303A] # EGYPTIAN HIEROGLYPH A049 +1303B ; [.3F01.0020.0002.1303B] # EGYPTIAN HIEROGLYPH A050 +1303C ; [.3F02.0020.0002.1303C] # EGYPTIAN HIEROGLYPH A051 +1303D ; [.3F03.0020.0002.1303D] # EGYPTIAN HIEROGLYPH A052 +1303E ; [.3F04.0020.0002.1303E] # EGYPTIAN HIEROGLYPH A053 +1303F ; [.3F05.0020.0002.1303F] # EGYPTIAN HIEROGLYPH A054 +13040 ; [.3F06.0020.0002.13040] # EGYPTIAN HIEROGLYPH A055 +13041 ; [.3F07.0020.0002.13041] # EGYPTIAN HIEROGLYPH A056 +13042 ; [.3F08.0020.0002.13042] # EGYPTIAN HIEROGLYPH A057 +13043 ; [.3F09.0020.0002.13043] # EGYPTIAN HIEROGLYPH A058 +13044 ; [.3F0A.0020.0002.13044] # EGYPTIAN HIEROGLYPH A059 +13045 ; [.3F0B.0020.0002.13045] # EGYPTIAN HIEROGLYPH A060 +13046 ; [.3F0C.0020.0002.13046] # EGYPTIAN HIEROGLYPH A061 +13047 ; [.3F0D.0020.0002.13047] # EGYPTIAN HIEROGLYPH A062 +13048 ; [.3F0E.0020.0002.13048] # EGYPTIAN HIEROGLYPH A063 +13049 ; [.3F0F.0020.0002.13049] # EGYPTIAN HIEROGLYPH A064 +1304A ; [.3F10.0020.0002.1304A] # EGYPTIAN HIEROGLYPH A065 +1304B ; [.3F11.0020.0002.1304B] # EGYPTIAN HIEROGLYPH A066 +1304C ; [.3F12.0020.0002.1304C] # EGYPTIAN HIEROGLYPH A067 +1304D ; [.3F13.0020.0002.1304D] # EGYPTIAN HIEROGLYPH A068 +1304E ; [.3F14.0020.0002.1304E] # EGYPTIAN HIEROGLYPH A069 +1304F ; [.3F15.0020.0002.1304F] # EGYPTIAN HIEROGLYPH A070 +13050 ; [.3F16.0020.0002.13050] # EGYPTIAN HIEROGLYPH B001 +13051 ; [.3F17.0020.0002.13051] # EGYPTIAN HIEROGLYPH B002 +13052 ; [.3F18.0020.0002.13052] # EGYPTIAN HIEROGLYPH B003 +13053 ; [.3F19.0020.0002.13053] # EGYPTIAN HIEROGLYPH B004 +13054 ; [.3F1A.0020.0002.13054] # EGYPTIAN HIEROGLYPH B005 +13055 ; [.3F1B.0020.0002.13055] # EGYPTIAN HIEROGLYPH B005A +13056 ; [.3F1C.0020.0002.13056] # EGYPTIAN HIEROGLYPH B006 +13057 ; [.3F1D.0020.0002.13057] # EGYPTIAN HIEROGLYPH B007 +13058 ; [.3F1E.0020.0002.13058] # EGYPTIAN HIEROGLYPH B008 +13059 ; [.3F1F.0020.0002.13059] # EGYPTIAN HIEROGLYPH B009 +1305A ; [.3F20.0020.0002.1305A] # EGYPTIAN HIEROGLYPH C001 +1305B ; [.3F21.0020.0002.1305B] # EGYPTIAN HIEROGLYPH C002 +1305C ; [.3F22.0020.0002.1305C] # EGYPTIAN HIEROGLYPH C002A +1305D ; [.3F23.0020.0002.1305D] # EGYPTIAN HIEROGLYPH C002B +1305E ; [.3F24.0020.0002.1305E] # EGYPTIAN HIEROGLYPH C002C +1305F ; [.3F25.0020.0002.1305F] # EGYPTIAN HIEROGLYPH C003 +13060 ; [.3F26.0020.0002.13060] # EGYPTIAN HIEROGLYPH C004 +13061 ; [.3F27.0020.0002.13061] # EGYPTIAN HIEROGLYPH C005 +13062 ; [.3F28.0020.0002.13062] # EGYPTIAN HIEROGLYPH C006 +13063 ; [.3F29.0020.0002.13063] # EGYPTIAN HIEROGLYPH C007 +13064 ; [.3F2A.0020.0002.13064] # EGYPTIAN HIEROGLYPH C008 +13065 ; [.3F2B.0020.0002.13065] # EGYPTIAN HIEROGLYPH C009 +13066 ; [.3F2C.0020.0002.13066] # EGYPTIAN HIEROGLYPH C010 +13067 ; [.3F2D.0020.0002.13067] # EGYPTIAN HIEROGLYPH C010A +13068 ; [.3F2E.0020.0002.13068] # EGYPTIAN HIEROGLYPH C011 +13069 ; [.3F2F.0020.0002.13069] # EGYPTIAN HIEROGLYPH C012 +1306A ; [.3F30.0020.0002.1306A] # EGYPTIAN HIEROGLYPH C013 +1306B ; [.3F31.0020.0002.1306B] # EGYPTIAN HIEROGLYPH C014 +1306C ; [.3F32.0020.0002.1306C] # EGYPTIAN HIEROGLYPH C015 +1306D ; [.3F33.0020.0002.1306D] # EGYPTIAN HIEROGLYPH C016 +1306E ; [.3F34.0020.0002.1306E] # EGYPTIAN HIEROGLYPH C017 +1306F ; [.3F35.0020.0002.1306F] # EGYPTIAN HIEROGLYPH C018 +13070 ; [.3F36.0020.0002.13070] # EGYPTIAN HIEROGLYPH C019 +13071 ; [.3F37.0020.0002.13071] # EGYPTIAN HIEROGLYPH C020 +13072 ; [.3F38.0020.0002.13072] # EGYPTIAN HIEROGLYPH C021 +13073 ; [.3F39.0020.0002.13073] # EGYPTIAN HIEROGLYPH C022 +13074 ; [.3F3A.0020.0002.13074] # EGYPTIAN HIEROGLYPH C023 +13075 ; [.3F3B.0020.0002.13075] # EGYPTIAN HIEROGLYPH C024 +13076 ; [.3F3C.0020.0002.13076] # EGYPTIAN HIEROGLYPH D001 +13077 ; [.3F3D.0020.0002.13077] # EGYPTIAN HIEROGLYPH D002 +13078 ; [.3F3E.0020.0002.13078] # EGYPTIAN HIEROGLYPH D003 +13079 ; [.3F3F.0020.0002.13079] # EGYPTIAN HIEROGLYPH D004 +1307A ; [.3F40.0020.0002.1307A] # EGYPTIAN HIEROGLYPH D005 +1307B ; [.3F41.0020.0002.1307B] # EGYPTIAN HIEROGLYPH D006 +1307C ; [.3F42.0020.0002.1307C] # EGYPTIAN HIEROGLYPH D007 +1307D ; [.3F43.0020.0002.1307D] # EGYPTIAN HIEROGLYPH D008 +1307E ; [.3F44.0020.0002.1307E] # EGYPTIAN HIEROGLYPH D008A +1307F ; [.3F45.0020.0002.1307F] # EGYPTIAN HIEROGLYPH D009 +13080 ; [.3F46.0020.0002.13080] # EGYPTIAN HIEROGLYPH D010 +13081 ; [.3F47.0020.0002.13081] # EGYPTIAN HIEROGLYPH D011 +13082 ; [.3F48.0020.0002.13082] # EGYPTIAN HIEROGLYPH D012 +13083 ; [.3F49.0020.0002.13083] # EGYPTIAN HIEROGLYPH D013 +13084 ; [.3F4A.0020.0002.13084] # EGYPTIAN HIEROGLYPH D014 +13085 ; [.3F4B.0020.0002.13085] # EGYPTIAN HIEROGLYPH D015 +13086 ; [.3F4C.0020.0002.13086] # EGYPTIAN HIEROGLYPH D016 +13087 ; [.3F4D.0020.0002.13087] # EGYPTIAN HIEROGLYPH D017 +13088 ; [.3F4E.0020.0002.13088] # EGYPTIAN HIEROGLYPH D018 +13089 ; [.3F4F.0020.0002.13089] # EGYPTIAN HIEROGLYPH D019 +1308A ; [.3F50.0020.0002.1308A] # EGYPTIAN HIEROGLYPH D020 +1308B ; [.3F51.0020.0002.1308B] # EGYPTIAN HIEROGLYPH D021 +1308C ; [.3F52.0020.0002.1308C] # EGYPTIAN HIEROGLYPH D022 +1308D ; [.3F53.0020.0002.1308D] # EGYPTIAN HIEROGLYPH D023 +1308E ; [.3F54.0020.0002.1308E] # EGYPTIAN HIEROGLYPH D024 +1308F ; [.3F55.0020.0002.1308F] # EGYPTIAN HIEROGLYPH D025 +13090 ; [.3F56.0020.0002.13090] # EGYPTIAN HIEROGLYPH D026 +13091 ; [.3F57.0020.0002.13091] # EGYPTIAN HIEROGLYPH D027 +13092 ; [.3F58.0020.0002.13092] # EGYPTIAN HIEROGLYPH D027A +13093 ; [.3F59.0020.0002.13093] # EGYPTIAN HIEROGLYPH D028 +13094 ; [.3F5A.0020.0002.13094] # EGYPTIAN HIEROGLYPH D029 +13095 ; [.3F5B.0020.0002.13095] # EGYPTIAN HIEROGLYPH D030 +13096 ; [.3F5C.0020.0002.13096] # EGYPTIAN HIEROGLYPH D031 +13097 ; [.3F5D.0020.0002.13097] # EGYPTIAN HIEROGLYPH D031A +13098 ; [.3F5E.0020.0002.13098] # EGYPTIAN HIEROGLYPH D032 +13099 ; [.3F5F.0020.0002.13099] # EGYPTIAN HIEROGLYPH D033 +1309A ; [.3F60.0020.0002.1309A] # EGYPTIAN HIEROGLYPH D034 +1309B ; [.3F61.0020.0002.1309B] # EGYPTIAN HIEROGLYPH D034A +1309C ; [.3F62.0020.0002.1309C] # EGYPTIAN HIEROGLYPH D035 +1309D ; [.3F63.0020.0002.1309D] # EGYPTIAN HIEROGLYPH D036 +1309E ; [.3F64.0020.0002.1309E] # EGYPTIAN HIEROGLYPH D037 +1309F ; [.3F65.0020.0002.1309F] # EGYPTIAN HIEROGLYPH D038 +130A0 ; [.3F66.0020.0002.130A0] # EGYPTIAN HIEROGLYPH D039 +130A1 ; [.3F67.0020.0002.130A1] # EGYPTIAN HIEROGLYPH D040 +130A2 ; [.3F68.0020.0002.130A2] # EGYPTIAN HIEROGLYPH D041 +130A3 ; [.3F69.0020.0002.130A3] # EGYPTIAN HIEROGLYPH D042 +130A4 ; [.3F6A.0020.0002.130A4] # EGYPTIAN HIEROGLYPH D043 +130A5 ; [.3F6B.0020.0002.130A5] # EGYPTIAN HIEROGLYPH D044 +130A6 ; [.3F6C.0020.0002.130A6] # EGYPTIAN HIEROGLYPH D045 +130A7 ; [.3F6D.0020.0002.130A7] # EGYPTIAN HIEROGLYPH D046 +130A8 ; [.3F6E.0020.0002.130A8] # EGYPTIAN HIEROGLYPH D046A +130A9 ; [.3F6F.0020.0002.130A9] # EGYPTIAN HIEROGLYPH D047 +130AA ; [.3F70.0020.0002.130AA] # EGYPTIAN HIEROGLYPH D048 +130AB ; [.3F71.0020.0002.130AB] # EGYPTIAN HIEROGLYPH D048A +130AC ; [.3F72.0020.0002.130AC] # EGYPTIAN HIEROGLYPH D049 +130AD ; [.3F73.0020.0002.130AD] # EGYPTIAN HIEROGLYPH D050 +130AE ; [.3F74.0020.0002.130AE] # EGYPTIAN HIEROGLYPH D050A +130AF ; [.3F75.0020.0002.130AF] # EGYPTIAN HIEROGLYPH D050B +130B0 ; [.3F76.0020.0002.130B0] # EGYPTIAN HIEROGLYPH D050C +130B1 ; [.3F77.0020.0002.130B1] # EGYPTIAN HIEROGLYPH D050D +130B2 ; [.3F78.0020.0002.130B2] # EGYPTIAN HIEROGLYPH D050E +130B3 ; [.3F79.0020.0002.130B3] # EGYPTIAN HIEROGLYPH D050F +130B4 ; [.3F7A.0020.0002.130B4] # EGYPTIAN HIEROGLYPH D050G +130B5 ; [.3F7B.0020.0002.130B5] # EGYPTIAN HIEROGLYPH D050H +130B6 ; [.3F7C.0020.0002.130B6] # EGYPTIAN HIEROGLYPH D050I +130B7 ; [.3F7D.0020.0002.130B7] # EGYPTIAN HIEROGLYPH D051 +130B8 ; [.3F7E.0020.0002.130B8] # EGYPTIAN HIEROGLYPH D052 +130B9 ; [.3F7F.0020.0002.130B9] # EGYPTIAN HIEROGLYPH D052A +130BA ; [.3F80.0020.0002.130BA] # EGYPTIAN HIEROGLYPH D053 +130BB ; [.3F81.0020.0002.130BB] # EGYPTIAN HIEROGLYPH D054 +130BC ; [.3F82.0020.0002.130BC] # EGYPTIAN HIEROGLYPH D054A +130BD ; [.3F83.0020.0002.130BD] # EGYPTIAN HIEROGLYPH D055 +130BE ; [.3F84.0020.0002.130BE] # EGYPTIAN HIEROGLYPH D056 +130BF ; [.3F85.0020.0002.130BF] # EGYPTIAN HIEROGLYPH D057 +130C0 ; [.3F86.0020.0002.130C0] # EGYPTIAN HIEROGLYPH D058 +130C1 ; [.3F87.0020.0002.130C1] # EGYPTIAN HIEROGLYPH D059 +130C2 ; [.3F88.0020.0002.130C2] # EGYPTIAN HIEROGLYPH D060 +130C3 ; [.3F89.0020.0002.130C3] # EGYPTIAN HIEROGLYPH D061 +130C4 ; [.3F8A.0020.0002.130C4] # EGYPTIAN HIEROGLYPH D062 +130C5 ; [.3F8B.0020.0002.130C5] # EGYPTIAN HIEROGLYPH D063 +130C6 ; [.3F8C.0020.0002.130C6] # EGYPTIAN HIEROGLYPH D064 +130C7 ; [.3F8D.0020.0002.130C7] # EGYPTIAN HIEROGLYPH D065 +130C8 ; [.3F8E.0020.0002.130C8] # EGYPTIAN HIEROGLYPH D066 +130C9 ; [.3F8F.0020.0002.130C9] # EGYPTIAN HIEROGLYPH D067 +130CA ; [.3F90.0020.0002.130CA] # EGYPTIAN HIEROGLYPH D067A +130CB ; [.3F91.0020.0002.130CB] # EGYPTIAN HIEROGLYPH D067B +130CC ; [.3F92.0020.0002.130CC] # EGYPTIAN HIEROGLYPH D067C +130CD ; [.3F93.0020.0002.130CD] # EGYPTIAN HIEROGLYPH D067D +130CE ; [.3F94.0020.0002.130CE] # EGYPTIAN HIEROGLYPH D067E +130CF ; [.3F95.0020.0002.130CF] # EGYPTIAN HIEROGLYPH D067F +130D0 ; [.3F96.0020.0002.130D0] # EGYPTIAN HIEROGLYPH D067G +130D1 ; [.3F97.0020.0002.130D1] # EGYPTIAN HIEROGLYPH D067H +130D2 ; [.3F98.0020.0002.130D2] # EGYPTIAN HIEROGLYPH E001 +130D3 ; [.3F99.0020.0002.130D3] # EGYPTIAN HIEROGLYPH E002 +130D4 ; [.3F9A.0020.0002.130D4] # EGYPTIAN HIEROGLYPH E003 +130D5 ; [.3F9B.0020.0002.130D5] # EGYPTIAN HIEROGLYPH E004 +130D6 ; [.3F9C.0020.0002.130D6] # EGYPTIAN HIEROGLYPH E005 +130D7 ; [.3F9D.0020.0002.130D7] # EGYPTIAN HIEROGLYPH E006 +130D8 ; [.3F9E.0020.0002.130D8] # EGYPTIAN HIEROGLYPH E007 +130D9 ; [.3F9F.0020.0002.130D9] # EGYPTIAN HIEROGLYPH E008 +130DA ; [.3FA0.0020.0002.130DA] # EGYPTIAN HIEROGLYPH E008A +130DB ; [.3FA1.0020.0002.130DB] # EGYPTIAN HIEROGLYPH E009 +130DC ; [.3FA2.0020.0002.130DC] # EGYPTIAN HIEROGLYPH E009A +130DD ; [.3FA3.0020.0002.130DD] # EGYPTIAN HIEROGLYPH E010 +130DE ; [.3FA4.0020.0002.130DE] # EGYPTIAN HIEROGLYPH E011 +130DF ; [.3FA5.0020.0002.130DF] # EGYPTIAN HIEROGLYPH E012 +130E0 ; [.3FA6.0020.0002.130E0] # EGYPTIAN HIEROGLYPH E013 +130E1 ; [.3FA7.0020.0002.130E1] # EGYPTIAN HIEROGLYPH E014 +130E2 ; [.3FA8.0020.0002.130E2] # EGYPTIAN HIEROGLYPH E015 +130E3 ; [.3FA9.0020.0002.130E3] # EGYPTIAN HIEROGLYPH E016 +130E4 ; [.3FAA.0020.0002.130E4] # EGYPTIAN HIEROGLYPH E016A +130E5 ; [.3FAB.0020.0002.130E5] # EGYPTIAN HIEROGLYPH E017 +130E6 ; [.3FAC.0020.0002.130E6] # EGYPTIAN HIEROGLYPH E017A +130E7 ; [.3FAD.0020.0002.130E7] # EGYPTIAN HIEROGLYPH E018 +130E8 ; [.3FAE.0020.0002.130E8] # EGYPTIAN HIEROGLYPH E019 +130E9 ; [.3FAF.0020.0002.130E9] # EGYPTIAN HIEROGLYPH E020 +130EA ; [.3FB0.0020.0002.130EA] # EGYPTIAN HIEROGLYPH E020A +130EB ; [.3FB1.0020.0002.130EB] # EGYPTIAN HIEROGLYPH E021 +130EC ; [.3FB2.0020.0002.130EC] # EGYPTIAN HIEROGLYPH E022 +130ED ; [.3FB3.0020.0002.130ED] # EGYPTIAN HIEROGLYPH E023 +130EE ; [.3FB4.0020.0002.130EE] # EGYPTIAN HIEROGLYPH E024 +130EF ; [.3FB5.0020.0002.130EF] # EGYPTIAN HIEROGLYPH E025 +130F0 ; [.3FB6.0020.0002.130F0] # EGYPTIAN HIEROGLYPH E026 +130F1 ; [.3FB7.0020.0002.130F1] # EGYPTIAN HIEROGLYPH E027 +130F2 ; [.3FB8.0020.0002.130F2] # EGYPTIAN HIEROGLYPH E028 +130F3 ; [.3FB9.0020.0002.130F3] # EGYPTIAN HIEROGLYPH E028A +130F4 ; [.3FBA.0020.0002.130F4] # EGYPTIAN HIEROGLYPH E029 +130F5 ; [.3FBB.0020.0002.130F5] # EGYPTIAN HIEROGLYPH E030 +130F6 ; [.3FBC.0020.0002.130F6] # EGYPTIAN HIEROGLYPH E031 +130F7 ; [.3FBD.0020.0002.130F7] # EGYPTIAN HIEROGLYPH E032 +130F8 ; [.3FBE.0020.0002.130F8] # EGYPTIAN HIEROGLYPH E033 +130F9 ; [.3FBF.0020.0002.130F9] # EGYPTIAN HIEROGLYPH E034 +130FA ; [.3FC0.0020.0002.130FA] # EGYPTIAN HIEROGLYPH E034A +130FB ; [.3FC1.0020.0002.130FB] # EGYPTIAN HIEROGLYPH E036 +130FC ; [.3FC2.0020.0002.130FC] # EGYPTIAN HIEROGLYPH E037 +130FD ; [.3FC3.0020.0002.130FD] # EGYPTIAN HIEROGLYPH E038 +130FE ; [.3FC4.0020.0002.130FE] # EGYPTIAN HIEROGLYPH F001 +130FF ; [.3FC5.0020.0002.130FF] # EGYPTIAN HIEROGLYPH F001A +13100 ; [.3FC6.0020.0002.13100] # EGYPTIAN HIEROGLYPH F002 +13101 ; [.3FC7.0020.0002.13101] # EGYPTIAN HIEROGLYPH F003 +13102 ; [.3FC8.0020.0002.13102] # EGYPTIAN HIEROGLYPH F004 +13103 ; [.3FC9.0020.0002.13103] # EGYPTIAN HIEROGLYPH F005 +13104 ; [.3FCA.0020.0002.13104] # EGYPTIAN HIEROGLYPH F006 +13105 ; [.3FCB.0020.0002.13105] # EGYPTIAN HIEROGLYPH F007 +13106 ; [.3FCC.0020.0002.13106] # EGYPTIAN HIEROGLYPH F008 +13107 ; [.3FCD.0020.0002.13107] # EGYPTIAN HIEROGLYPH F009 +13108 ; [.3FCE.0020.0002.13108] # EGYPTIAN HIEROGLYPH F010 +13109 ; [.3FCF.0020.0002.13109] # EGYPTIAN HIEROGLYPH F011 +1310A ; [.3FD0.0020.0002.1310A] # EGYPTIAN HIEROGLYPH F012 +1310B ; [.3FD1.0020.0002.1310B] # EGYPTIAN HIEROGLYPH F013 +1310C ; [.3FD2.0020.0002.1310C] # EGYPTIAN HIEROGLYPH F013A +1310D ; [.3FD3.0020.0002.1310D] # EGYPTIAN HIEROGLYPH F014 +1310E ; [.3FD4.0020.0002.1310E] # EGYPTIAN HIEROGLYPH F015 +1310F ; [.3FD5.0020.0002.1310F] # EGYPTIAN HIEROGLYPH F016 +13110 ; [.3FD6.0020.0002.13110] # EGYPTIAN HIEROGLYPH F017 +13111 ; [.3FD7.0020.0002.13111] # EGYPTIAN HIEROGLYPH F018 +13112 ; [.3FD8.0020.0002.13112] # EGYPTIAN HIEROGLYPH F019 +13113 ; [.3FD9.0020.0002.13113] # EGYPTIAN HIEROGLYPH F020 +13114 ; [.3FDA.0020.0002.13114] # EGYPTIAN HIEROGLYPH F021 +13115 ; [.3FDB.0020.0002.13115] # EGYPTIAN HIEROGLYPH F021A +13116 ; [.3FDC.0020.0002.13116] # EGYPTIAN HIEROGLYPH F022 +13117 ; [.3FDD.0020.0002.13117] # EGYPTIAN HIEROGLYPH F023 +13118 ; [.3FDE.0020.0002.13118] # EGYPTIAN HIEROGLYPH F024 +13119 ; [.3FDF.0020.0002.13119] # EGYPTIAN HIEROGLYPH F025 +1311A ; [.3FE0.0020.0002.1311A] # EGYPTIAN HIEROGLYPH F026 +1311B ; [.3FE1.0020.0002.1311B] # EGYPTIAN HIEROGLYPH F027 +1311C ; [.3FE2.0020.0002.1311C] # EGYPTIAN HIEROGLYPH F028 +1311D ; [.3FE3.0020.0002.1311D] # EGYPTIAN HIEROGLYPH F029 +1311E ; [.3FE4.0020.0002.1311E] # EGYPTIAN HIEROGLYPH F030 +1311F ; [.3FE5.0020.0002.1311F] # EGYPTIAN HIEROGLYPH F031 +13120 ; [.3FE6.0020.0002.13120] # EGYPTIAN HIEROGLYPH F031A +13121 ; [.3FE7.0020.0002.13121] # EGYPTIAN HIEROGLYPH F032 +13122 ; [.3FE8.0020.0002.13122] # EGYPTIAN HIEROGLYPH F033 +13123 ; [.3FE9.0020.0002.13123] # EGYPTIAN HIEROGLYPH F034 +13124 ; [.3FEA.0020.0002.13124] # EGYPTIAN HIEROGLYPH F035 +13125 ; [.3FEB.0020.0002.13125] # EGYPTIAN HIEROGLYPH F036 +13126 ; [.3FEC.0020.0002.13126] # EGYPTIAN HIEROGLYPH F037 +13127 ; [.3FED.0020.0002.13127] # EGYPTIAN HIEROGLYPH F037A +13128 ; [.3FEE.0020.0002.13128] # EGYPTIAN HIEROGLYPH F038 +13129 ; [.3FEF.0020.0002.13129] # EGYPTIAN HIEROGLYPH F038A +1312A ; [.3FF0.0020.0002.1312A] # EGYPTIAN HIEROGLYPH F039 +1312B ; [.3FF1.0020.0002.1312B] # EGYPTIAN HIEROGLYPH F040 +1312C ; [.3FF2.0020.0002.1312C] # EGYPTIAN HIEROGLYPH F041 +1312D ; [.3FF3.0020.0002.1312D] # EGYPTIAN HIEROGLYPH F042 +1312E ; [.3FF4.0020.0002.1312E] # EGYPTIAN HIEROGLYPH F043 +1312F ; [.3FF5.0020.0002.1312F] # EGYPTIAN HIEROGLYPH F044 +13130 ; [.3FF6.0020.0002.13130] # EGYPTIAN HIEROGLYPH F045 +13131 ; [.3FF7.0020.0002.13131] # EGYPTIAN HIEROGLYPH F045A +13132 ; [.3FF8.0020.0002.13132] # EGYPTIAN HIEROGLYPH F046 +13133 ; [.3FF9.0020.0002.13133] # EGYPTIAN HIEROGLYPH F046A +13134 ; [.3FFA.0020.0002.13134] # EGYPTIAN HIEROGLYPH F047 +13135 ; [.3FFB.0020.0002.13135] # EGYPTIAN HIEROGLYPH F047A +13136 ; [.3FFC.0020.0002.13136] # EGYPTIAN HIEROGLYPH F048 +13137 ; [.3FFD.0020.0002.13137] # EGYPTIAN HIEROGLYPH F049 +13138 ; [.3FFE.0020.0002.13138] # EGYPTIAN HIEROGLYPH F050 +13139 ; [.3FFF.0020.0002.13139] # EGYPTIAN HIEROGLYPH F051 +1313A ; [.4000.0020.0002.1313A] # EGYPTIAN HIEROGLYPH F051A +1313B ; [.4001.0020.0002.1313B] # EGYPTIAN HIEROGLYPH F051B +1313C ; [.4002.0020.0002.1313C] # EGYPTIAN HIEROGLYPH F051C +1313D ; [.4003.0020.0002.1313D] # EGYPTIAN HIEROGLYPH F052 +1313E ; [.4004.0020.0002.1313E] # EGYPTIAN HIEROGLYPH F053 +1313F ; [.4005.0020.0002.1313F] # EGYPTIAN HIEROGLYPH G001 +13140 ; [.4006.0020.0002.13140] # EGYPTIAN HIEROGLYPH G002 +13141 ; [.4007.0020.0002.13141] # EGYPTIAN HIEROGLYPH G003 +13142 ; [.4008.0020.0002.13142] # EGYPTIAN HIEROGLYPH G004 +13143 ; [.4009.0020.0002.13143] # EGYPTIAN HIEROGLYPH G005 +13144 ; [.400A.0020.0002.13144] # EGYPTIAN HIEROGLYPH G006 +13145 ; [.400B.0020.0002.13145] # EGYPTIAN HIEROGLYPH G006A +13146 ; [.400C.0020.0002.13146] # EGYPTIAN HIEROGLYPH G007 +13147 ; [.400D.0020.0002.13147] # EGYPTIAN HIEROGLYPH G007A +13148 ; [.400E.0020.0002.13148] # EGYPTIAN HIEROGLYPH G007B +13149 ; [.400F.0020.0002.13149] # EGYPTIAN HIEROGLYPH G008 +1314A ; [.4010.0020.0002.1314A] # EGYPTIAN HIEROGLYPH G009 +1314B ; [.4011.0020.0002.1314B] # EGYPTIAN HIEROGLYPH G010 +1314C ; [.4012.0020.0002.1314C] # EGYPTIAN HIEROGLYPH G011 +1314D ; [.4013.0020.0002.1314D] # EGYPTIAN HIEROGLYPH G011A +1314E ; [.4014.0020.0002.1314E] # EGYPTIAN HIEROGLYPH G012 +1314F ; [.4015.0020.0002.1314F] # EGYPTIAN HIEROGLYPH G013 +13150 ; [.4016.0020.0002.13150] # EGYPTIAN HIEROGLYPH G014 +13151 ; [.4017.0020.0002.13151] # EGYPTIAN HIEROGLYPH G015 +13152 ; [.4018.0020.0002.13152] # EGYPTIAN HIEROGLYPH G016 +13153 ; [.4019.0020.0002.13153] # EGYPTIAN HIEROGLYPH G017 +13154 ; [.401A.0020.0002.13154] # EGYPTIAN HIEROGLYPH G018 +13155 ; [.401B.0020.0002.13155] # EGYPTIAN HIEROGLYPH G019 +13156 ; [.401C.0020.0002.13156] # EGYPTIAN HIEROGLYPH G020 +13157 ; [.401D.0020.0002.13157] # EGYPTIAN HIEROGLYPH G020A +13158 ; [.401E.0020.0002.13158] # EGYPTIAN HIEROGLYPH G021 +13159 ; [.401F.0020.0002.13159] # EGYPTIAN HIEROGLYPH G022 +1315A ; [.4020.0020.0002.1315A] # EGYPTIAN HIEROGLYPH G023 +1315B ; [.4021.0020.0002.1315B] # EGYPTIAN HIEROGLYPH G024 +1315C ; [.4022.0020.0002.1315C] # EGYPTIAN HIEROGLYPH G025 +1315D ; [.4023.0020.0002.1315D] # EGYPTIAN HIEROGLYPH G026 +1315E ; [.4024.0020.0002.1315E] # EGYPTIAN HIEROGLYPH G026A +1315F ; [.4025.0020.0002.1315F] # EGYPTIAN HIEROGLYPH G027 +13160 ; [.4026.0020.0002.13160] # EGYPTIAN HIEROGLYPH G028 +13161 ; [.4027.0020.0002.13161] # EGYPTIAN HIEROGLYPH G029 +13162 ; [.4028.0020.0002.13162] # EGYPTIAN HIEROGLYPH G030 +13163 ; [.4029.0020.0002.13163] # EGYPTIAN HIEROGLYPH G031 +13164 ; [.402A.0020.0002.13164] # EGYPTIAN HIEROGLYPH G032 +13165 ; [.402B.0020.0002.13165] # EGYPTIAN HIEROGLYPH G033 +13166 ; [.402C.0020.0002.13166] # EGYPTIAN HIEROGLYPH G034 +13167 ; [.402D.0020.0002.13167] # EGYPTIAN HIEROGLYPH G035 +13168 ; [.402E.0020.0002.13168] # EGYPTIAN HIEROGLYPH G036 +13169 ; [.402F.0020.0002.13169] # EGYPTIAN HIEROGLYPH G036A +1316A ; [.4030.0020.0002.1316A] # EGYPTIAN HIEROGLYPH G037 +1316B ; [.4031.0020.0002.1316B] # EGYPTIAN HIEROGLYPH G037A +1316C ; [.4032.0020.0002.1316C] # EGYPTIAN HIEROGLYPH G038 +1316D ; [.4033.0020.0002.1316D] # EGYPTIAN HIEROGLYPH G039 +1316E ; [.4034.0020.0002.1316E] # EGYPTIAN HIEROGLYPH G040 +1316F ; [.4035.0020.0002.1316F] # EGYPTIAN HIEROGLYPH G041 +13170 ; [.4036.0020.0002.13170] # EGYPTIAN HIEROGLYPH G042 +13171 ; [.4037.0020.0002.13171] # EGYPTIAN HIEROGLYPH G043 +13172 ; [.4038.0020.0002.13172] # EGYPTIAN HIEROGLYPH G043A +13173 ; [.4039.0020.0002.13173] # EGYPTIAN HIEROGLYPH G044 +13174 ; [.403A.0020.0002.13174] # EGYPTIAN HIEROGLYPH G045 +13175 ; [.403B.0020.0002.13175] # EGYPTIAN HIEROGLYPH G045A +13176 ; [.403C.0020.0002.13176] # EGYPTIAN HIEROGLYPH G046 +13177 ; [.403D.0020.0002.13177] # EGYPTIAN HIEROGLYPH G047 +13178 ; [.403E.0020.0002.13178] # EGYPTIAN HIEROGLYPH G048 +13179 ; [.403F.0020.0002.13179] # EGYPTIAN HIEROGLYPH G049 +1317A ; [.4040.0020.0002.1317A] # EGYPTIAN HIEROGLYPH G050 +1317B ; [.4041.0020.0002.1317B] # EGYPTIAN HIEROGLYPH G051 +1317C ; [.4042.0020.0002.1317C] # EGYPTIAN HIEROGLYPH G052 +1317D ; [.4043.0020.0002.1317D] # EGYPTIAN HIEROGLYPH G053 +1317E ; [.4044.0020.0002.1317E] # EGYPTIAN HIEROGLYPH G054 +1317F ; [.4045.0020.0002.1317F] # EGYPTIAN HIEROGLYPH H001 +13180 ; [.4046.0020.0002.13180] # EGYPTIAN HIEROGLYPH H002 +13181 ; [.4047.0020.0002.13181] # EGYPTIAN HIEROGLYPH H003 +13182 ; [.4048.0020.0002.13182] # EGYPTIAN HIEROGLYPH H004 +13183 ; [.4049.0020.0002.13183] # EGYPTIAN HIEROGLYPH H005 +13184 ; [.404A.0020.0002.13184] # EGYPTIAN HIEROGLYPH H006 +13185 ; [.404B.0020.0002.13185] # EGYPTIAN HIEROGLYPH H006A +13186 ; [.404C.0020.0002.13186] # EGYPTIAN HIEROGLYPH H007 +13187 ; [.404D.0020.0002.13187] # EGYPTIAN HIEROGLYPH H008 +13188 ; [.404E.0020.0002.13188] # EGYPTIAN HIEROGLYPH I001 +13189 ; [.404F.0020.0002.13189] # EGYPTIAN HIEROGLYPH I002 +1318A ; [.4050.0020.0002.1318A] # EGYPTIAN HIEROGLYPH I003 +1318B ; [.4051.0020.0002.1318B] # EGYPTIAN HIEROGLYPH I004 +1318C ; [.4052.0020.0002.1318C] # EGYPTIAN HIEROGLYPH I005 +1318D ; [.4053.0020.0002.1318D] # EGYPTIAN HIEROGLYPH I005A +1318E ; [.4054.0020.0002.1318E] # EGYPTIAN HIEROGLYPH I006 +1318F ; [.4055.0020.0002.1318F] # EGYPTIAN HIEROGLYPH I007 +13190 ; [.4056.0020.0002.13190] # EGYPTIAN HIEROGLYPH I008 +13191 ; [.4057.0020.0002.13191] # EGYPTIAN HIEROGLYPH I009 +13192 ; [.4058.0020.0002.13192] # EGYPTIAN HIEROGLYPH I009A +13193 ; [.4059.0020.0002.13193] # EGYPTIAN HIEROGLYPH I010 +13194 ; [.405A.0020.0002.13194] # EGYPTIAN HIEROGLYPH I010A +13195 ; [.405B.0020.0002.13195] # EGYPTIAN HIEROGLYPH I011 +13196 ; [.405C.0020.0002.13196] # EGYPTIAN HIEROGLYPH I011A +13197 ; [.405D.0020.0002.13197] # EGYPTIAN HIEROGLYPH I012 +13198 ; [.405E.0020.0002.13198] # EGYPTIAN HIEROGLYPH I013 +13199 ; [.405F.0020.0002.13199] # EGYPTIAN HIEROGLYPH I014 +1319A ; [.4060.0020.0002.1319A] # EGYPTIAN HIEROGLYPH I015 +1319B ; [.4061.0020.0002.1319B] # EGYPTIAN HIEROGLYPH K001 +1319C ; [.4062.0020.0002.1319C] # EGYPTIAN HIEROGLYPH K002 +1319D ; [.4063.0020.0002.1319D] # EGYPTIAN HIEROGLYPH K003 +1319E ; [.4064.0020.0002.1319E] # EGYPTIAN HIEROGLYPH K004 +1319F ; [.4065.0020.0002.1319F] # EGYPTIAN HIEROGLYPH K005 +131A0 ; [.4066.0020.0002.131A0] # EGYPTIAN HIEROGLYPH K006 +131A1 ; [.4067.0020.0002.131A1] # EGYPTIAN HIEROGLYPH K007 +131A2 ; [.4068.0020.0002.131A2] # EGYPTIAN HIEROGLYPH K008 +131A3 ; [.4069.0020.0002.131A3] # EGYPTIAN HIEROGLYPH L001 +131A4 ; [.406A.0020.0002.131A4] # EGYPTIAN HIEROGLYPH L002 +131A5 ; [.406B.0020.0002.131A5] # EGYPTIAN HIEROGLYPH L002A +131A6 ; [.406C.0020.0002.131A6] # EGYPTIAN HIEROGLYPH L003 +131A7 ; [.406D.0020.0002.131A7] # EGYPTIAN HIEROGLYPH L004 +131A8 ; [.406E.0020.0002.131A8] # EGYPTIAN HIEROGLYPH L005 +131A9 ; [.406F.0020.0002.131A9] # EGYPTIAN HIEROGLYPH L006 +131AA ; [.4070.0020.0002.131AA] # EGYPTIAN HIEROGLYPH L006A +131AB ; [.4071.0020.0002.131AB] # EGYPTIAN HIEROGLYPH L007 +131AC ; [.4072.0020.0002.131AC] # EGYPTIAN HIEROGLYPH L008 +131AD ; [.4073.0020.0002.131AD] # EGYPTIAN HIEROGLYPH M001 +131AE ; [.4074.0020.0002.131AE] # EGYPTIAN HIEROGLYPH M001A +131AF ; [.4075.0020.0002.131AF] # EGYPTIAN HIEROGLYPH M001B +131B0 ; [.4076.0020.0002.131B0] # EGYPTIAN HIEROGLYPH M002 +131B1 ; [.4077.0020.0002.131B1] # EGYPTIAN HIEROGLYPH M003 +131B2 ; [.4078.0020.0002.131B2] # EGYPTIAN HIEROGLYPH M003A +131B3 ; [.4079.0020.0002.131B3] # EGYPTIAN HIEROGLYPH M004 +131B4 ; [.407A.0020.0002.131B4] # EGYPTIAN HIEROGLYPH M005 +131B5 ; [.407B.0020.0002.131B5] # EGYPTIAN HIEROGLYPH M006 +131B6 ; [.407C.0020.0002.131B6] # EGYPTIAN HIEROGLYPH M007 +131B7 ; [.407D.0020.0002.131B7] # EGYPTIAN HIEROGLYPH M008 +131B8 ; [.407E.0020.0002.131B8] # EGYPTIAN HIEROGLYPH M009 +131B9 ; [.407F.0020.0002.131B9] # EGYPTIAN HIEROGLYPH M010 +131BA ; [.4080.0020.0002.131BA] # EGYPTIAN HIEROGLYPH M010A +131BB ; [.4081.0020.0002.131BB] # EGYPTIAN HIEROGLYPH M011 +131BC ; [.4082.0020.0002.131BC] # EGYPTIAN HIEROGLYPH M012 +131BD ; [.4083.0020.0002.131BD] # EGYPTIAN HIEROGLYPH M012A +131BE ; [.4084.0020.0002.131BE] # EGYPTIAN HIEROGLYPH M012B +131BF ; [.4085.0020.0002.131BF] # EGYPTIAN HIEROGLYPH M012C +131C0 ; [.4086.0020.0002.131C0] # EGYPTIAN HIEROGLYPH M012D +131C1 ; [.4087.0020.0002.131C1] # EGYPTIAN HIEROGLYPH M012E +131C2 ; [.4088.0020.0002.131C2] # EGYPTIAN HIEROGLYPH M012F +131C3 ; [.4089.0020.0002.131C3] # EGYPTIAN HIEROGLYPH M012G +131C4 ; [.408A.0020.0002.131C4] # EGYPTIAN HIEROGLYPH M012H +131C5 ; [.408B.0020.0002.131C5] # EGYPTIAN HIEROGLYPH M013 +131C6 ; [.408C.0020.0002.131C6] # EGYPTIAN HIEROGLYPH M014 +131C7 ; [.408D.0020.0002.131C7] # EGYPTIAN HIEROGLYPH M015 +131C8 ; [.408E.0020.0002.131C8] # EGYPTIAN HIEROGLYPH M015A +131C9 ; [.408F.0020.0002.131C9] # EGYPTIAN HIEROGLYPH M016 +131CA ; [.4090.0020.0002.131CA] # EGYPTIAN HIEROGLYPH M016A +131CB ; [.4091.0020.0002.131CB] # EGYPTIAN HIEROGLYPH M017 +131CC ; [.4092.0020.0002.131CC] # EGYPTIAN HIEROGLYPH M017A +131CD ; [.4093.0020.0002.131CD] # EGYPTIAN HIEROGLYPH M018 +131CE ; [.4094.0020.0002.131CE] # EGYPTIAN HIEROGLYPH M019 +131CF ; [.4095.0020.0002.131CF] # EGYPTIAN HIEROGLYPH M020 +131D0 ; [.4096.0020.0002.131D0] # EGYPTIAN HIEROGLYPH M021 +131D1 ; [.4097.0020.0002.131D1] # EGYPTIAN HIEROGLYPH M022 +131D2 ; [.4098.0020.0002.131D2] # EGYPTIAN HIEROGLYPH M022A +131D3 ; [.4099.0020.0002.131D3] # EGYPTIAN HIEROGLYPH M023 +131D4 ; [.409A.0020.0002.131D4] # EGYPTIAN HIEROGLYPH M024 +131D5 ; [.409B.0020.0002.131D5] # EGYPTIAN HIEROGLYPH M024A +131D6 ; [.409C.0020.0002.131D6] # EGYPTIAN HIEROGLYPH M025 +131D7 ; [.409D.0020.0002.131D7] # EGYPTIAN HIEROGLYPH M026 +131D8 ; [.409E.0020.0002.131D8] # EGYPTIAN HIEROGLYPH M027 +131D9 ; [.409F.0020.0002.131D9] # EGYPTIAN HIEROGLYPH M028 +131DA ; [.40A0.0020.0002.131DA] # EGYPTIAN HIEROGLYPH M028A +131DB ; [.40A1.0020.0002.131DB] # EGYPTIAN HIEROGLYPH M029 +131DC ; [.40A2.0020.0002.131DC] # EGYPTIAN HIEROGLYPH M030 +131DD ; [.40A3.0020.0002.131DD] # EGYPTIAN HIEROGLYPH M031 +131DE ; [.40A4.0020.0002.131DE] # EGYPTIAN HIEROGLYPH M031A +131DF ; [.40A5.0020.0002.131DF] # EGYPTIAN HIEROGLYPH M032 +131E0 ; [.40A6.0020.0002.131E0] # EGYPTIAN HIEROGLYPH M033 +131E1 ; [.40A7.0020.0002.131E1] # EGYPTIAN HIEROGLYPH M033A +131E2 ; [.40A8.0020.0002.131E2] # EGYPTIAN HIEROGLYPH M033B +131E3 ; [.40A9.0020.0002.131E3] # EGYPTIAN HIEROGLYPH M034 +131E4 ; [.40AA.0020.0002.131E4] # EGYPTIAN HIEROGLYPH M035 +131E5 ; [.40AB.0020.0002.131E5] # EGYPTIAN HIEROGLYPH M036 +131E6 ; [.40AC.0020.0002.131E6] # EGYPTIAN HIEROGLYPH M037 +131E7 ; [.40AD.0020.0002.131E7] # EGYPTIAN HIEROGLYPH M038 +131E8 ; [.40AE.0020.0002.131E8] # EGYPTIAN HIEROGLYPH M039 +131E9 ; [.40AF.0020.0002.131E9] # EGYPTIAN HIEROGLYPH M040 +131EA ; [.40B0.0020.0002.131EA] # EGYPTIAN HIEROGLYPH M040A +131EB ; [.40B1.0020.0002.131EB] # EGYPTIAN HIEROGLYPH M041 +131EC ; [.40B2.0020.0002.131EC] # EGYPTIAN HIEROGLYPH M042 +131ED ; [.40B3.0020.0002.131ED] # EGYPTIAN HIEROGLYPH M043 +131EE ; [.40B4.0020.0002.131EE] # EGYPTIAN HIEROGLYPH M044 +131EF ; [.40B5.0020.0002.131EF] # EGYPTIAN HIEROGLYPH N001 +131F0 ; [.40B6.0020.0002.131F0] # EGYPTIAN HIEROGLYPH N002 +131F1 ; [.40B7.0020.0002.131F1] # EGYPTIAN HIEROGLYPH N003 +131F2 ; [.40B8.0020.0002.131F2] # EGYPTIAN HIEROGLYPH N004 +131F3 ; [.40B9.0020.0002.131F3] # EGYPTIAN HIEROGLYPH N005 +131F4 ; [.40BA.0020.0002.131F4] # EGYPTIAN HIEROGLYPH N006 +131F5 ; [.40BB.0020.0002.131F5] # EGYPTIAN HIEROGLYPH N007 +131F6 ; [.40BC.0020.0002.131F6] # EGYPTIAN HIEROGLYPH N008 +131F7 ; [.40BD.0020.0002.131F7] # EGYPTIAN HIEROGLYPH N009 +131F8 ; [.40BE.0020.0002.131F8] # EGYPTIAN HIEROGLYPH N010 +131F9 ; [.40BF.0020.0002.131F9] # EGYPTIAN HIEROGLYPH N011 +131FA ; [.40C0.0020.0002.131FA] # EGYPTIAN HIEROGLYPH N012 +131FB ; [.40C1.0020.0002.131FB] # EGYPTIAN HIEROGLYPH N013 +131FC ; [.40C2.0020.0002.131FC] # EGYPTIAN HIEROGLYPH N014 +131FD ; [.40C3.0020.0002.131FD] # EGYPTIAN HIEROGLYPH N015 +131FE ; [.40C4.0020.0002.131FE] # EGYPTIAN HIEROGLYPH N016 +131FF ; [.40C5.0020.0002.131FF] # EGYPTIAN HIEROGLYPH N017 +13200 ; [.40C6.0020.0002.13200] # EGYPTIAN HIEROGLYPH N018 +13201 ; [.40C7.0020.0002.13201] # EGYPTIAN HIEROGLYPH N018A +13202 ; [.40C8.0020.0002.13202] # EGYPTIAN HIEROGLYPH N018B +13203 ; [.40C9.0020.0002.13203] # EGYPTIAN HIEROGLYPH N019 +13204 ; [.40CA.0020.0002.13204] # EGYPTIAN HIEROGLYPH N020 +13205 ; [.40CB.0020.0002.13205] # EGYPTIAN HIEROGLYPH N021 +13206 ; [.40CC.0020.0002.13206] # EGYPTIAN HIEROGLYPH N022 +13207 ; [.40CD.0020.0002.13207] # EGYPTIAN HIEROGLYPH N023 +13208 ; [.40CE.0020.0002.13208] # EGYPTIAN HIEROGLYPH N024 +13209 ; [.40CF.0020.0002.13209] # EGYPTIAN HIEROGLYPH N025 +1320A ; [.40D0.0020.0002.1320A] # EGYPTIAN HIEROGLYPH N025A +1320B ; [.40D1.0020.0002.1320B] # EGYPTIAN HIEROGLYPH N026 +1320C ; [.40D2.0020.0002.1320C] # EGYPTIAN HIEROGLYPH N027 +1320D ; [.40D3.0020.0002.1320D] # EGYPTIAN HIEROGLYPH N028 +1320E ; [.40D4.0020.0002.1320E] # EGYPTIAN HIEROGLYPH N029 +1320F ; [.40D5.0020.0002.1320F] # EGYPTIAN HIEROGLYPH N030 +13210 ; [.40D6.0020.0002.13210] # EGYPTIAN HIEROGLYPH N031 +13211 ; [.40D7.0020.0002.13211] # EGYPTIAN HIEROGLYPH N032 +13212 ; [.40D8.0020.0002.13212] # EGYPTIAN HIEROGLYPH N033 +13213 ; [.40D9.0020.0002.13213] # EGYPTIAN HIEROGLYPH N033A +13214 ; [.40DA.0020.0002.13214] # EGYPTIAN HIEROGLYPH N034 +13215 ; [.40DB.0020.0002.13215] # EGYPTIAN HIEROGLYPH N034A +13216 ; [.40DC.0020.0002.13216] # EGYPTIAN HIEROGLYPH N035 +13217 ; [.40DD.0020.0002.13217] # EGYPTIAN HIEROGLYPH N035A +13218 ; [.40DE.0020.0002.13218] # EGYPTIAN HIEROGLYPH N036 +13219 ; [.40DF.0020.0002.13219] # EGYPTIAN HIEROGLYPH N037 +1321A ; [.40E0.0020.0002.1321A] # EGYPTIAN HIEROGLYPH N037A +1321B ; [.40E1.0020.0002.1321B] # EGYPTIAN HIEROGLYPH N038 +1321C ; [.40E2.0020.0002.1321C] # EGYPTIAN HIEROGLYPH N039 +1321D ; [.40E3.0020.0002.1321D] # EGYPTIAN HIEROGLYPH N040 +1321E ; [.40E4.0020.0002.1321E] # EGYPTIAN HIEROGLYPH N041 +1321F ; [.40E5.0020.0002.1321F] # EGYPTIAN HIEROGLYPH N042 +13220 ; [.40E6.0020.0002.13220] # EGYPTIAN HIEROGLYPH NL001 +13221 ; [.40E7.0020.0002.13221] # EGYPTIAN HIEROGLYPH NL002 +13222 ; [.40E8.0020.0002.13222] # EGYPTIAN HIEROGLYPH NL003 +13223 ; [.40E9.0020.0002.13223] # EGYPTIAN HIEROGLYPH NL004 +13224 ; [.40EA.0020.0002.13224] # EGYPTIAN HIEROGLYPH NL005 +13225 ; [.40EB.0020.0002.13225] # EGYPTIAN HIEROGLYPH NL005A +13226 ; [.40EC.0020.0002.13226] # EGYPTIAN HIEROGLYPH NL006 +13227 ; [.40ED.0020.0002.13227] # EGYPTIAN HIEROGLYPH NL007 +13228 ; [.40EE.0020.0002.13228] # EGYPTIAN HIEROGLYPH NL008 +13229 ; [.40EF.0020.0002.13229] # EGYPTIAN HIEROGLYPH NL009 +1322A ; [.40F0.0020.0002.1322A] # EGYPTIAN HIEROGLYPH NL010 +1322B ; [.40F1.0020.0002.1322B] # EGYPTIAN HIEROGLYPH NL011 +1322C ; [.40F2.0020.0002.1322C] # EGYPTIAN HIEROGLYPH NL012 +1322D ; [.40F3.0020.0002.1322D] # EGYPTIAN HIEROGLYPH NL013 +1322E ; [.40F4.0020.0002.1322E] # EGYPTIAN HIEROGLYPH NL014 +1322F ; [.40F5.0020.0002.1322F] # EGYPTIAN HIEROGLYPH NL015 +13230 ; [.40F6.0020.0002.13230] # EGYPTIAN HIEROGLYPH NL016 +13231 ; [.40F7.0020.0002.13231] # EGYPTIAN HIEROGLYPH NL017 +13232 ; [.40F8.0020.0002.13232] # EGYPTIAN HIEROGLYPH NL017A +13233 ; [.40F9.0020.0002.13233] # EGYPTIAN HIEROGLYPH NL018 +13234 ; [.40FA.0020.0002.13234] # EGYPTIAN HIEROGLYPH NL019 +13235 ; [.40FB.0020.0002.13235] # EGYPTIAN HIEROGLYPH NL020 +13236 ; [.40FC.0020.0002.13236] # EGYPTIAN HIEROGLYPH NU001 +13237 ; [.40FD.0020.0002.13237] # EGYPTIAN HIEROGLYPH NU002 +13238 ; [.40FE.0020.0002.13238] # EGYPTIAN HIEROGLYPH NU003 +13239 ; [.40FF.0020.0002.13239] # EGYPTIAN HIEROGLYPH NU004 +1323A ; [.4100.0020.0002.1323A] # EGYPTIAN HIEROGLYPH NU005 +1323B ; [.4101.0020.0002.1323B] # EGYPTIAN HIEROGLYPH NU006 +1323C ; [.4102.0020.0002.1323C] # EGYPTIAN HIEROGLYPH NU007 +1323D ; [.4103.0020.0002.1323D] # EGYPTIAN HIEROGLYPH NU008 +1323E ; [.4104.0020.0002.1323E] # EGYPTIAN HIEROGLYPH NU009 +1323F ; [.4105.0020.0002.1323F] # EGYPTIAN HIEROGLYPH NU010 +13240 ; [.4106.0020.0002.13240] # EGYPTIAN HIEROGLYPH NU010A +13241 ; [.4107.0020.0002.13241] # EGYPTIAN HIEROGLYPH NU011 +13242 ; [.4108.0020.0002.13242] # EGYPTIAN HIEROGLYPH NU011A +13243 ; [.4109.0020.0002.13243] # EGYPTIAN HIEROGLYPH NU012 +13244 ; [.410A.0020.0002.13244] # EGYPTIAN HIEROGLYPH NU013 +13245 ; [.410B.0020.0002.13245] # EGYPTIAN HIEROGLYPH NU014 +13246 ; [.410C.0020.0002.13246] # EGYPTIAN HIEROGLYPH NU015 +13247 ; [.410D.0020.0002.13247] # EGYPTIAN HIEROGLYPH NU016 +13248 ; [.410E.0020.0002.13248] # EGYPTIAN HIEROGLYPH NU017 +13249 ; [.410F.0020.0002.13249] # EGYPTIAN HIEROGLYPH NU018 +1324A ; [.4110.0020.0002.1324A] # EGYPTIAN HIEROGLYPH NU018A +1324B ; [.4111.0020.0002.1324B] # EGYPTIAN HIEROGLYPH NU019 +1324C ; [.4112.0020.0002.1324C] # EGYPTIAN HIEROGLYPH NU020 +1324D ; [.4113.0020.0002.1324D] # EGYPTIAN HIEROGLYPH NU021 +1324E ; [.4114.0020.0002.1324E] # EGYPTIAN HIEROGLYPH NU022 +1324F ; [.4115.0020.0002.1324F] # EGYPTIAN HIEROGLYPH NU022A +13250 ; [.4116.0020.0002.13250] # EGYPTIAN HIEROGLYPH O001 +13251 ; [.4117.0020.0002.13251] # EGYPTIAN HIEROGLYPH O001A +13252 ; [.4118.0020.0002.13252] # EGYPTIAN HIEROGLYPH O002 +13253 ; [.4119.0020.0002.13253] # EGYPTIAN HIEROGLYPH O003 +13254 ; [.411A.0020.0002.13254] # EGYPTIAN HIEROGLYPH O004 +13255 ; [.411B.0020.0002.13255] # EGYPTIAN HIEROGLYPH O005 +13256 ; [.411C.0020.0002.13256] # EGYPTIAN HIEROGLYPH O005A +13257 ; [.411D.0020.0002.13257] # EGYPTIAN HIEROGLYPH O006 +13258 ; [.411E.0020.0002.13258] # EGYPTIAN HIEROGLYPH O006A +13259 ; [.411F.0020.0002.13259] # EGYPTIAN HIEROGLYPH O006B +1325A ; [.4120.0020.0002.1325A] # EGYPTIAN HIEROGLYPH O006C +1325B ; [.4121.0020.0002.1325B] # EGYPTIAN HIEROGLYPH O006D +1325C ; [.4122.0020.0002.1325C] # EGYPTIAN HIEROGLYPH O006E +1325D ; [.4123.0020.0002.1325D] # EGYPTIAN HIEROGLYPH O006F +1325E ; [.4124.0020.0002.1325E] # EGYPTIAN HIEROGLYPH O007 +1325F ; [.4125.0020.0002.1325F] # EGYPTIAN HIEROGLYPH O008 +13260 ; [.4126.0020.0002.13260] # EGYPTIAN HIEROGLYPH O009 +13261 ; [.4127.0020.0002.13261] # EGYPTIAN HIEROGLYPH O010 +13262 ; [.4128.0020.0002.13262] # EGYPTIAN HIEROGLYPH O010A +13263 ; [.4129.0020.0002.13263] # EGYPTIAN HIEROGLYPH O010B +13264 ; [.412A.0020.0002.13264] # EGYPTIAN HIEROGLYPH O010C +13265 ; [.412B.0020.0002.13265] # EGYPTIAN HIEROGLYPH O011 +13266 ; [.412C.0020.0002.13266] # EGYPTIAN HIEROGLYPH O012 +13267 ; [.412D.0020.0002.13267] # EGYPTIAN HIEROGLYPH O013 +13268 ; [.412E.0020.0002.13268] # EGYPTIAN HIEROGLYPH O014 +13269 ; [.412F.0020.0002.13269] # EGYPTIAN HIEROGLYPH O015 +1326A ; [.4130.0020.0002.1326A] # EGYPTIAN HIEROGLYPH O016 +1326B ; [.4131.0020.0002.1326B] # EGYPTIAN HIEROGLYPH O017 +1326C ; [.4132.0020.0002.1326C] # EGYPTIAN HIEROGLYPH O018 +1326D ; [.4133.0020.0002.1326D] # EGYPTIAN HIEROGLYPH O019 +1326E ; [.4134.0020.0002.1326E] # EGYPTIAN HIEROGLYPH O019A +1326F ; [.4135.0020.0002.1326F] # EGYPTIAN HIEROGLYPH O020 +13270 ; [.4136.0020.0002.13270] # EGYPTIAN HIEROGLYPH O020A +13271 ; [.4137.0020.0002.13271] # EGYPTIAN HIEROGLYPH O021 +13272 ; [.4138.0020.0002.13272] # EGYPTIAN HIEROGLYPH O022 +13273 ; [.4139.0020.0002.13273] # EGYPTIAN HIEROGLYPH O023 +13274 ; [.413A.0020.0002.13274] # EGYPTIAN HIEROGLYPH O024 +13275 ; [.413B.0020.0002.13275] # EGYPTIAN HIEROGLYPH O024A +13276 ; [.413C.0020.0002.13276] # EGYPTIAN HIEROGLYPH O025 +13277 ; [.413D.0020.0002.13277] # EGYPTIAN HIEROGLYPH O025A +13278 ; [.413E.0020.0002.13278] # EGYPTIAN HIEROGLYPH O026 +13279 ; [.413F.0020.0002.13279] # EGYPTIAN HIEROGLYPH O027 +1327A ; [.4140.0020.0002.1327A] # EGYPTIAN HIEROGLYPH O028 +1327B ; [.4141.0020.0002.1327B] # EGYPTIAN HIEROGLYPH O029 +1327C ; [.4142.0020.0002.1327C] # EGYPTIAN HIEROGLYPH O029A +1327D ; [.4143.0020.0002.1327D] # EGYPTIAN HIEROGLYPH O030 +1327E ; [.4144.0020.0002.1327E] # EGYPTIAN HIEROGLYPH O030A +1327F ; [.4145.0020.0002.1327F] # EGYPTIAN HIEROGLYPH O031 +13280 ; [.4146.0020.0002.13280] # EGYPTIAN HIEROGLYPH O032 +13281 ; [.4147.0020.0002.13281] # EGYPTIAN HIEROGLYPH O033 +13282 ; [.4148.0020.0002.13282] # EGYPTIAN HIEROGLYPH O033A +13283 ; [.4149.0020.0002.13283] # EGYPTIAN HIEROGLYPH O034 +13284 ; [.414A.0020.0002.13284] # EGYPTIAN HIEROGLYPH O035 +13285 ; [.414B.0020.0002.13285] # EGYPTIAN HIEROGLYPH O036 +13286 ; [.414C.0020.0002.13286] # EGYPTIAN HIEROGLYPH O036A +13287 ; [.414D.0020.0002.13287] # EGYPTIAN HIEROGLYPH O036B +13288 ; [.414E.0020.0002.13288] # EGYPTIAN HIEROGLYPH O036C +13289 ; [.414F.0020.0002.13289] # EGYPTIAN HIEROGLYPH O036D +1328A ; [.4150.0020.0002.1328A] # EGYPTIAN HIEROGLYPH O037 +1328B ; [.4151.0020.0002.1328B] # EGYPTIAN HIEROGLYPH O038 +1328C ; [.4152.0020.0002.1328C] # EGYPTIAN HIEROGLYPH O039 +1328D ; [.4153.0020.0002.1328D] # EGYPTIAN HIEROGLYPH O040 +1328E ; [.4154.0020.0002.1328E] # EGYPTIAN HIEROGLYPH O041 +1328F ; [.4155.0020.0002.1328F] # EGYPTIAN HIEROGLYPH O042 +13290 ; [.4156.0020.0002.13290] # EGYPTIAN HIEROGLYPH O043 +13291 ; [.4157.0020.0002.13291] # EGYPTIAN HIEROGLYPH O044 +13292 ; [.4158.0020.0002.13292] # EGYPTIAN HIEROGLYPH O045 +13293 ; [.4159.0020.0002.13293] # EGYPTIAN HIEROGLYPH O046 +13294 ; [.415A.0020.0002.13294] # EGYPTIAN HIEROGLYPH O047 +13295 ; [.415B.0020.0002.13295] # EGYPTIAN HIEROGLYPH O048 +13296 ; [.415C.0020.0002.13296] # EGYPTIAN HIEROGLYPH O049 +13297 ; [.415D.0020.0002.13297] # EGYPTIAN HIEROGLYPH O050 +13298 ; [.415E.0020.0002.13298] # EGYPTIAN HIEROGLYPH O050A +13299 ; [.415F.0020.0002.13299] # EGYPTIAN HIEROGLYPH O050B +1329A ; [.4160.0020.0002.1329A] # EGYPTIAN HIEROGLYPH O051 +1329B ; [.4161.0020.0002.1329B] # EGYPTIAN HIEROGLYPH P001 +1329C ; [.4162.0020.0002.1329C] # EGYPTIAN HIEROGLYPH P001A +1329D ; [.4163.0020.0002.1329D] # EGYPTIAN HIEROGLYPH P002 +1329E ; [.4164.0020.0002.1329E] # EGYPTIAN HIEROGLYPH P003 +1329F ; [.4165.0020.0002.1329F] # EGYPTIAN HIEROGLYPH P003A +132A0 ; [.4166.0020.0002.132A0] # EGYPTIAN HIEROGLYPH P004 +132A1 ; [.4167.0020.0002.132A1] # EGYPTIAN HIEROGLYPH P005 +132A2 ; [.4168.0020.0002.132A2] # EGYPTIAN HIEROGLYPH P006 +132A3 ; [.4169.0020.0002.132A3] # EGYPTIAN HIEROGLYPH P007 +132A4 ; [.416A.0020.0002.132A4] # EGYPTIAN HIEROGLYPH P008 +132A5 ; [.416B.0020.0002.132A5] # EGYPTIAN HIEROGLYPH P009 +132A6 ; [.416C.0020.0002.132A6] # EGYPTIAN HIEROGLYPH P010 +132A7 ; [.416D.0020.0002.132A7] # EGYPTIAN HIEROGLYPH P011 +132A8 ; [.416E.0020.0002.132A8] # EGYPTIAN HIEROGLYPH Q001 +132A9 ; [.416F.0020.0002.132A9] # EGYPTIAN HIEROGLYPH Q002 +132AA ; [.4170.0020.0002.132AA] # EGYPTIAN HIEROGLYPH Q003 +132AB ; [.4171.0020.0002.132AB] # EGYPTIAN HIEROGLYPH Q004 +132AC ; [.4172.0020.0002.132AC] # EGYPTIAN HIEROGLYPH Q005 +132AD ; [.4173.0020.0002.132AD] # EGYPTIAN HIEROGLYPH Q006 +132AE ; [.4174.0020.0002.132AE] # EGYPTIAN HIEROGLYPH Q007 +132AF ; [.4175.0020.0002.132AF] # EGYPTIAN HIEROGLYPH R001 +132B0 ; [.4176.0020.0002.132B0] # EGYPTIAN HIEROGLYPH R002 +132B1 ; [.4177.0020.0002.132B1] # EGYPTIAN HIEROGLYPH R002A +132B2 ; [.4178.0020.0002.132B2] # EGYPTIAN HIEROGLYPH R003 +132B3 ; [.4179.0020.0002.132B3] # EGYPTIAN HIEROGLYPH R003A +132B4 ; [.417A.0020.0002.132B4] # EGYPTIAN HIEROGLYPH R003B +132B5 ; [.417B.0020.0002.132B5] # EGYPTIAN HIEROGLYPH R004 +132B6 ; [.417C.0020.0002.132B6] # EGYPTIAN HIEROGLYPH R005 +132B7 ; [.417D.0020.0002.132B7] # EGYPTIAN HIEROGLYPH R006 +132B8 ; [.417E.0020.0002.132B8] # EGYPTIAN HIEROGLYPH R007 +132B9 ; [.417F.0020.0002.132B9] # EGYPTIAN HIEROGLYPH R008 +132BA ; [.4180.0020.0002.132BA] # EGYPTIAN HIEROGLYPH R009 +132BB ; [.4181.0020.0002.132BB] # EGYPTIAN HIEROGLYPH R010 +132BC ; [.4182.0020.0002.132BC] # EGYPTIAN HIEROGLYPH R010A +132BD ; [.4183.0020.0002.132BD] # EGYPTIAN HIEROGLYPH R011 +132BE ; [.4184.0020.0002.132BE] # EGYPTIAN HIEROGLYPH R012 +132BF ; [.4185.0020.0002.132BF] # EGYPTIAN HIEROGLYPH R013 +132C0 ; [.4186.0020.0002.132C0] # EGYPTIAN HIEROGLYPH R014 +132C1 ; [.4187.0020.0002.132C1] # EGYPTIAN HIEROGLYPH R015 +132C2 ; [.4188.0020.0002.132C2] # EGYPTIAN HIEROGLYPH R016 +132C3 ; [.4189.0020.0002.132C3] # EGYPTIAN HIEROGLYPH R016A +132C4 ; [.418A.0020.0002.132C4] # EGYPTIAN HIEROGLYPH R017 +132C5 ; [.418B.0020.0002.132C5] # EGYPTIAN HIEROGLYPH R018 +132C6 ; [.418C.0020.0002.132C6] # EGYPTIAN HIEROGLYPH R019 +132C7 ; [.418D.0020.0002.132C7] # EGYPTIAN HIEROGLYPH R020 +132C8 ; [.418E.0020.0002.132C8] # EGYPTIAN HIEROGLYPH R021 +132C9 ; [.418F.0020.0002.132C9] # EGYPTIAN HIEROGLYPH R022 +132CA ; [.4190.0020.0002.132CA] # EGYPTIAN HIEROGLYPH R023 +132CB ; [.4191.0020.0002.132CB] # EGYPTIAN HIEROGLYPH R024 +132CC ; [.4192.0020.0002.132CC] # EGYPTIAN HIEROGLYPH R025 +132CD ; [.4193.0020.0002.132CD] # EGYPTIAN HIEROGLYPH R026 +132CE ; [.4194.0020.0002.132CE] # EGYPTIAN HIEROGLYPH R027 +132CF ; [.4195.0020.0002.132CF] # EGYPTIAN HIEROGLYPH R028 +132D0 ; [.4196.0020.0002.132D0] # EGYPTIAN HIEROGLYPH R029 +132D1 ; [.4197.0020.0002.132D1] # EGYPTIAN HIEROGLYPH S001 +132D2 ; [.4198.0020.0002.132D2] # EGYPTIAN HIEROGLYPH S002 +132D3 ; [.4199.0020.0002.132D3] # EGYPTIAN HIEROGLYPH S002A +132D4 ; [.419A.0020.0002.132D4] # EGYPTIAN HIEROGLYPH S003 +132D5 ; [.419B.0020.0002.132D5] # EGYPTIAN HIEROGLYPH S004 +132D6 ; [.419C.0020.0002.132D6] # EGYPTIAN HIEROGLYPH S005 +132D7 ; [.419D.0020.0002.132D7] # EGYPTIAN HIEROGLYPH S006 +132D8 ; [.419E.0020.0002.132D8] # EGYPTIAN HIEROGLYPH S006A +132D9 ; [.419F.0020.0002.132D9] # EGYPTIAN HIEROGLYPH S007 +132DA ; [.41A0.0020.0002.132DA] # EGYPTIAN HIEROGLYPH S008 +132DB ; [.41A1.0020.0002.132DB] # EGYPTIAN HIEROGLYPH S009 +132DC ; [.41A2.0020.0002.132DC] # EGYPTIAN HIEROGLYPH S010 +132DD ; [.41A3.0020.0002.132DD] # EGYPTIAN HIEROGLYPH S011 +132DE ; [.41A4.0020.0002.132DE] # EGYPTIAN HIEROGLYPH S012 +132DF ; [.41A5.0020.0002.132DF] # EGYPTIAN HIEROGLYPH S013 +132E0 ; [.41A6.0020.0002.132E0] # EGYPTIAN HIEROGLYPH S014 +132E1 ; [.41A7.0020.0002.132E1] # EGYPTIAN HIEROGLYPH S014A +132E2 ; [.41A8.0020.0002.132E2] # EGYPTIAN HIEROGLYPH S014B +132E3 ; [.41A9.0020.0002.132E3] # EGYPTIAN HIEROGLYPH S015 +132E4 ; [.41AA.0020.0002.132E4] # EGYPTIAN HIEROGLYPH S016 +132E5 ; [.41AB.0020.0002.132E5] # EGYPTIAN HIEROGLYPH S017 +132E6 ; [.41AC.0020.0002.132E6] # EGYPTIAN HIEROGLYPH S017A +132E7 ; [.41AD.0020.0002.132E7] # EGYPTIAN HIEROGLYPH S018 +132E8 ; [.41AE.0020.0002.132E8] # EGYPTIAN HIEROGLYPH S019 +132E9 ; [.41AF.0020.0002.132E9] # EGYPTIAN HIEROGLYPH S020 +132EA ; [.41B0.0020.0002.132EA] # EGYPTIAN HIEROGLYPH S021 +132EB ; [.41B1.0020.0002.132EB] # EGYPTIAN HIEROGLYPH S022 +132EC ; [.41B2.0020.0002.132EC] # EGYPTIAN HIEROGLYPH S023 +132ED ; [.41B3.0020.0002.132ED] # EGYPTIAN HIEROGLYPH S024 +132EE ; [.41B4.0020.0002.132EE] # EGYPTIAN HIEROGLYPH S025 +132EF ; [.41B5.0020.0002.132EF] # EGYPTIAN HIEROGLYPH S026 +132F0 ; [.41B6.0020.0002.132F0] # EGYPTIAN HIEROGLYPH S026A +132F1 ; [.41B7.0020.0002.132F1] # EGYPTIAN HIEROGLYPH S026B +132F2 ; [.41B8.0020.0002.132F2] # EGYPTIAN HIEROGLYPH S027 +132F3 ; [.41B9.0020.0002.132F3] # EGYPTIAN HIEROGLYPH S028 +132F4 ; [.41BA.0020.0002.132F4] # EGYPTIAN HIEROGLYPH S029 +132F5 ; [.41BB.0020.0002.132F5] # EGYPTIAN HIEROGLYPH S030 +132F6 ; [.41BC.0020.0002.132F6] # EGYPTIAN HIEROGLYPH S031 +132F7 ; [.41BD.0020.0002.132F7] # EGYPTIAN HIEROGLYPH S032 +132F8 ; [.41BE.0020.0002.132F8] # EGYPTIAN HIEROGLYPH S033 +132F9 ; [.41BF.0020.0002.132F9] # EGYPTIAN HIEROGLYPH S034 +132FA ; [.41C0.0020.0002.132FA] # EGYPTIAN HIEROGLYPH S035 +132FB ; [.41C1.0020.0002.132FB] # EGYPTIAN HIEROGLYPH S035A +132FC ; [.41C2.0020.0002.132FC] # EGYPTIAN HIEROGLYPH S036 +132FD ; [.41C3.0020.0002.132FD] # EGYPTIAN HIEROGLYPH S037 +132FE ; [.41C4.0020.0002.132FE] # EGYPTIAN HIEROGLYPH S038 +132FF ; [.41C5.0020.0002.132FF] # EGYPTIAN HIEROGLYPH S039 +13300 ; [.41C6.0020.0002.13300] # EGYPTIAN HIEROGLYPH S040 +13301 ; [.41C7.0020.0002.13301] # EGYPTIAN HIEROGLYPH S041 +13302 ; [.41C8.0020.0002.13302] # EGYPTIAN HIEROGLYPH S042 +13303 ; [.41C9.0020.0002.13303] # EGYPTIAN HIEROGLYPH S043 +13304 ; [.41CA.0020.0002.13304] # EGYPTIAN HIEROGLYPH S044 +13305 ; [.41CB.0020.0002.13305] # EGYPTIAN HIEROGLYPH S045 +13306 ; [.41CC.0020.0002.13306] # EGYPTIAN HIEROGLYPH S046 +13307 ; [.41CD.0020.0002.13307] # EGYPTIAN HIEROGLYPH T001 +13308 ; [.41CE.0020.0002.13308] # EGYPTIAN HIEROGLYPH T002 +13309 ; [.41CF.0020.0002.13309] # EGYPTIAN HIEROGLYPH T003 +1330A ; [.41D0.0020.0002.1330A] # EGYPTIAN HIEROGLYPH T003A +1330B ; [.41D1.0020.0002.1330B] # EGYPTIAN HIEROGLYPH T004 +1330C ; [.41D2.0020.0002.1330C] # EGYPTIAN HIEROGLYPH T005 +1330D ; [.41D3.0020.0002.1330D] # EGYPTIAN HIEROGLYPH T006 +1330E ; [.41D4.0020.0002.1330E] # EGYPTIAN HIEROGLYPH T007 +1330F ; [.41D5.0020.0002.1330F] # EGYPTIAN HIEROGLYPH T007A +13310 ; [.41D6.0020.0002.13310] # EGYPTIAN HIEROGLYPH T008 +13311 ; [.41D7.0020.0002.13311] # EGYPTIAN HIEROGLYPH T008A +13312 ; [.41D8.0020.0002.13312] # EGYPTIAN HIEROGLYPH T009 +13313 ; [.41D9.0020.0002.13313] # EGYPTIAN HIEROGLYPH T009A +13314 ; [.41DA.0020.0002.13314] # EGYPTIAN HIEROGLYPH T010 +13315 ; [.41DB.0020.0002.13315] # EGYPTIAN HIEROGLYPH T011 +13316 ; [.41DC.0020.0002.13316] # EGYPTIAN HIEROGLYPH T011A +13317 ; [.41DD.0020.0002.13317] # EGYPTIAN HIEROGLYPH T012 +13318 ; [.41DE.0020.0002.13318] # EGYPTIAN HIEROGLYPH T013 +13319 ; [.41DF.0020.0002.13319] # EGYPTIAN HIEROGLYPH T014 +1331A ; [.41E0.0020.0002.1331A] # EGYPTIAN HIEROGLYPH T015 +1331B ; [.41E1.0020.0002.1331B] # EGYPTIAN HIEROGLYPH T016 +1331C ; [.41E2.0020.0002.1331C] # EGYPTIAN HIEROGLYPH T016A +1331D ; [.41E3.0020.0002.1331D] # EGYPTIAN HIEROGLYPH T017 +1331E ; [.41E4.0020.0002.1331E] # EGYPTIAN HIEROGLYPH T018 +1331F ; [.41E5.0020.0002.1331F] # EGYPTIAN HIEROGLYPH T019 +13320 ; [.41E6.0020.0002.13320] # EGYPTIAN HIEROGLYPH T020 +13321 ; [.41E7.0020.0002.13321] # EGYPTIAN HIEROGLYPH T021 +13322 ; [.41E8.0020.0002.13322] # EGYPTIAN HIEROGLYPH T022 +13323 ; [.41E9.0020.0002.13323] # EGYPTIAN HIEROGLYPH T023 +13324 ; [.41EA.0020.0002.13324] # EGYPTIAN HIEROGLYPH T024 +13325 ; [.41EB.0020.0002.13325] # EGYPTIAN HIEROGLYPH T025 +13326 ; [.41EC.0020.0002.13326] # EGYPTIAN HIEROGLYPH T026 +13327 ; [.41ED.0020.0002.13327] # EGYPTIAN HIEROGLYPH T027 +13328 ; [.41EE.0020.0002.13328] # EGYPTIAN HIEROGLYPH T028 +13329 ; [.41EF.0020.0002.13329] # EGYPTIAN HIEROGLYPH T029 +1332A ; [.41F0.0020.0002.1332A] # EGYPTIAN HIEROGLYPH T030 +1332B ; [.41F1.0020.0002.1332B] # EGYPTIAN HIEROGLYPH T031 +1332C ; [.41F2.0020.0002.1332C] # EGYPTIAN HIEROGLYPH T032 +1332D ; [.41F3.0020.0002.1332D] # EGYPTIAN HIEROGLYPH T032A +1332E ; [.41F4.0020.0002.1332E] # EGYPTIAN HIEROGLYPH T033 +1332F ; [.41F5.0020.0002.1332F] # EGYPTIAN HIEROGLYPH T033A +13330 ; [.41F6.0020.0002.13330] # EGYPTIAN HIEROGLYPH T034 +13331 ; [.41F7.0020.0002.13331] # EGYPTIAN HIEROGLYPH T035 +13332 ; [.41F8.0020.0002.13332] # EGYPTIAN HIEROGLYPH T036 +13333 ; [.41F9.0020.0002.13333] # EGYPTIAN HIEROGLYPH U001 +13334 ; [.41FA.0020.0002.13334] # EGYPTIAN HIEROGLYPH U002 +13335 ; [.41FB.0020.0002.13335] # EGYPTIAN HIEROGLYPH U003 +13336 ; [.41FC.0020.0002.13336] # EGYPTIAN HIEROGLYPH U004 +13337 ; [.41FD.0020.0002.13337] # EGYPTIAN HIEROGLYPH U005 +13338 ; [.41FE.0020.0002.13338] # EGYPTIAN HIEROGLYPH U006 +13339 ; [.41FF.0020.0002.13339] # EGYPTIAN HIEROGLYPH U006A +1333A ; [.4200.0020.0002.1333A] # EGYPTIAN HIEROGLYPH U006B +1333B ; [.4201.0020.0002.1333B] # EGYPTIAN HIEROGLYPH U007 +1333C ; [.4202.0020.0002.1333C] # EGYPTIAN HIEROGLYPH U008 +1333D ; [.4203.0020.0002.1333D] # EGYPTIAN HIEROGLYPH U009 +1333E ; [.4204.0020.0002.1333E] # EGYPTIAN HIEROGLYPH U010 +1333F ; [.4205.0020.0002.1333F] # EGYPTIAN HIEROGLYPH U011 +13340 ; [.4206.0020.0002.13340] # EGYPTIAN HIEROGLYPH U012 +13341 ; [.4207.0020.0002.13341] # EGYPTIAN HIEROGLYPH U013 +13342 ; [.4208.0020.0002.13342] # EGYPTIAN HIEROGLYPH U014 +13343 ; [.4209.0020.0002.13343] # EGYPTIAN HIEROGLYPH U015 +13344 ; [.420A.0020.0002.13344] # EGYPTIAN HIEROGLYPH U016 +13345 ; [.420B.0020.0002.13345] # EGYPTIAN HIEROGLYPH U017 +13346 ; [.420C.0020.0002.13346] # EGYPTIAN HIEROGLYPH U018 +13347 ; [.420D.0020.0002.13347] # EGYPTIAN HIEROGLYPH U019 +13348 ; [.420E.0020.0002.13348] # EGYPTIAN HIEROGLYPH U020 +13349 ; [.420F.0020.0002.13349] # EGYPTIAN HIEROGLYPH U021 +1334A ; [.4210.0020.0002.1334A] # EGYPTIAN HIEROGLYPH U022 +1334B ; [.4211.0020.0002.1334B] # EGYPTIAN HIEROGLYPH U023 +1334C ; [.4212.0020.0002.1334C] # EGYPTIAN HIEROGLYPH U023A +1334D ; [.4213.0020.0002.1334D] # EGYPTIAN HIEROGLYPH U024 +1334E ; [.4214.0020.0002.1334E] # EGYPTIAN HIEROGLYPH U025 +1334F ; [.4215.0020.0002.1334F] # EGYPTIAN HIEROGLYPH U026 +13350 ; [.4216.0020.0002.13350] # EGYPTIAN HIEROGLYPH U027 +13351 ; [.4217.0020.0002.13351] # EGYPTIAN HIEROGLYPH U028 +13352 ; [.4218.0020.0002.13352] # EGYPTIAN HIEROGLYPH U029 +13353 ; [.4219.0020.0002.13353] # EGYPTIAN HIEROGLYPH U029A +13354 ; [.421A.0020.0002.13354] # EGYPTIAN HIEROGLYPH U030 +13355 ; [.421B.0020.0002.13355] # EGYPTIAN HIEROGLYPH U031 +13356 ; [.421C.0020.0002.13356] # EGYPTIAN HIEROGLYPH U032 +13357 ; [.421D.0020.0002.13357] # EGYPTIAN HIEROGLYPH U032A +13358 ; [.421E.0020.0002.13358] # EGYPTIAN HIEROGLYPH U033 +13359 ; [.421F.0020.0002.13359] # EGYPTIAN HIEROGLYPH U034 +1335A ; [.4220.0020.0002.1335A] # EGYPTIAN HIEROGLYPH U035 +1335B ; [.4221.0020.0002.1335B] # EGYPTIAN HIEROGLYPH U036 +1335C ; [.4222.0020.0002.1335C] # EGYPTIAN HIEROGLYPH U037 +1335D ; [.4223.0020.0002.1335D] # EGYPTIAN HIEROGLYPH U038 +1335E ; [.4224.0020.0002.1335E] # EGYPTIAN HIEROGLYPH U039 +1335F ; [.4225.0020.0002.1335F] # EGYPTIAN HIEROGLYPH U040 +13360 ; [.4226.0020.0002.13360] # EGYPTIAN HIEROGLYPH U041 +13361 ; [.4227.0020.0002.13361] # EGYPTIAN HIEROGLYPH U042 +13362 ; [.4228.0020.0002.13362] # EGYPTIAN HIEROGLYPH V001 +13363 ; [.4229.0020.0002.13363] # EGYPTIAN HIEROGLYPH V001A +13364 ; [.422A.0020.0002.13364] # EGYPTIAN HIEROGLYPH V001B +13365 ; [.422B.0020.0002.13365] # EGYPTIAN HIEROGLYPH V001C +13366 ; [.422C.0020.0002.13366] # EGYPTIAN HIEROGLYPH V001D +13367 ; [.422D.0020.0002.13367] # EGYPTIAN HIEROGLYPH V001E +13368 ; [.422E.0020.0002.13368] # EGYPTIAN HIEROGLYPH V001F +13369 ; [.422F.0020.0002.13369] # EGYPTIAN HIEROGLYPH V001G +1336A ; [.4230.0020.0002.1336A] # EGYPTIAN HIEROGLYPH V001H +1336B ; [.4231.0020.0002.1336B] # EGYPTIAN HIEROGLYPH V001I +1336C ; [.4232.0020.0002.1336C] # EGYPTIAN HIEROGLYPH V002 +1336D ; [.4233.0020.0002.1336D] # EGYPTIAN HIEROGLYPH V002A +1336E ; [.4234.0020.0002.1336E] # EGYPTIAN HIEROGLYPH V003 +1336F ; [.4235.0020.0002.1336F] # EGYPTIAN HIEROGLYPH V004 +13370 ; [.4236.0020.0002.13370] # EGYPTIAN HIEROGLYPH V005 +13371 ; [.4237.0020.0002.13371] # EGYPTIAN HIEROGLYPH V006 +13372 ; [.4238.0020.0002.13372] # EGYPTIAN HIEROGLYPH V007 +13373 ; [.4239.0020.0002.13373] # EGYPTIAN HIEROGLYPH V007A +13374 ; [.423A.0020.0002.13374] # EGYPTIAN HIEROGLYPH V007B +13375 ; [.423B.0020.0002.13375] # EGYPTIAN HIEROGLYPH V008 +13376 ; [.423C.0020.0002.13376] # EGYPTIAN HIEROGLYPH V009 +13377 ; [.423D.0020.0002.13377] # EGYPTIAN HIEROGLYPH V010 +13378 ; [.423E.0020.0002.13378] # EGYPTIAN HIEROGLYPH V011 +13379 ; [.423F.0020.0002.13379] # EGYPTIAN HIEROGLYPH V011A +1337A ; [.4240.0020.0002.1337A] # EGYPTIAN HIEROGLYPH V011B +1337B ; [.4241.0020.0002.1337B] # EGYPTIAN HIEROGLYPH V011C +1337C ; [.4242.0020.0002.1337C] # EGYPTIAN HIEROGLYPH V012 +1337D ; [.4243.0020.0002.1337D] # EGYPTIAN HIEROGLYPH V012A +1337E ; [.4244.0020.0002.1337E] # EGYPTIAN HIEROGLYPH V012B +1337F ; [.4245.0020.0002.1337F] # EGYPTIAN HIEROGLYPH V013 +13380 ; [.4246.0020.0002.13380] # EGYPTIAN HIEROGLYPH V014 +13381 ; [.4247.0020.0002.13381] # EGYPTIAN HIEROGLYPH V015 +13382 ; [.4248.0020.0002.13382] # EGYPTIAN HIEROGLYPH V016 +13383 ; [.4249.0020.0002.13383] # EGYPTIAN HIEROGLYPH V017 +13384 ; [.424A.0020.0002.13384] # EGYPTIAN HIEROGLYPH V018 +13385 ; [.424B.0020.0002.13385] # EGYPTIAN HIEROGLYPH V019 +13386 ; [.424C.0020.0002.13386] # EGYPTIAN HIEROGLYPH V020 +13387 ; [.424D.0020.0002.13387] # EGYPTIAN HIEROGLYPH V020A +13388 ; [.424E.0020.0002.13388] # EGYPTIAN HIEROGLYPH V020B +13389 ; [.424F.0020.0002.13389] # EGYPTIAN HIEROGLYPH V020C +1338A ; [.4250.0020.0002.1338A] # EGYPTIAN HIEROGLYPH V020D +1338B ; [.4251.0020.0002.1338B] # EGYPTIAN HIEROGLYPH V020E +1338C ; [.4252.0020.0002.1338C] # EGYPTIAN HIEROGLYPH V020F +1338D ; [.4253.0020.0002.1338D] # EGYPTIAN HIEROGLYPH V020G +1338E ; [.4254.0020.0002.1338E] # EGYPTIAN HIEROGLYPH V020H +1338F ; [.4255.0020.0002.1338F] # EGYPTIAN HIEROGLYPH V020I +13390 ; [.4256.0020.0002.13390] # EGYPTIAN HIEROGLYPH V020J +13391 ; [.4257.0020.0002.13391] # EGYPTIAN HIEROGLYPH V020K +13392 ; [.4258.0020.0002.13392] # EGYPTIAN HIEROGLYPH V020L +13393 ; [.4259.0020.0002.13393] # EGYPTIAN HIEROGLYPH V021 +13394 ; [.425A.0020.0002.13394] # EGYPTIAN HIEROGLYPH V022 +13395 ; [.425B.0020.0002.13395] # EGYPTIAN HIEROGLYPH V023 +13396 ; [.425C.0020.0002.13396] # EGYPTIAN HIEROGLYPH V023A +13397 ; [.425D.0020.0002.13397] # EGYPTIAN HIEROGLYPH V024 +13398 ; [.425E.0020.0002.13398] # EGYPTIAN HIEROGLYPH V025 +13399 ; [.425F.0020.0002.13399] # EGYPTIAN HIEROGLYPH V026 +1339A ; [.4260.0020.0002.1339A] # EGYPTIAN HIEROGLYPH V027 +1339B ; [.4261.0020.0002.1339B] # EGYPTIAN HIEROGLYPH V028 +1339C ; [.4262.0020.0002.1339C] # EGYPTIAN HIEROGLYPH V028A +1339D ; [.4263.0020.0002.1339D] # EGYPTIAN HIEROGLYPH V029 +1339E ; [.4264.0020.0002.1339E] # EGYPTIAN HIEROGLYPH V029A +1339F ; [.4265.0020.0002.1339F] # EGYPTIAN HIEROGLYPH V030 +133A0 ; [.4266.0020.0002.133A0] # EGYPTIAN HIEROGLYPH V030A +133A1 ; [.4267.0020.0002.133A1] # EGYPTIAN HIEROGLYPH V031 +133A2 ; [.4268.0020.0002.133A2] # EGYPTIAN HIEROGLYPH V031A +133A3 ; [.4269.0020.0002.133A3] # EGYPTIAN HIEROGLYPH V032 +133A4 ; [.426A.0020.0002.133A4] # EGYPTIAN HIEROGLYPH V033 +133A5 ; [.426B.0020.0002.133A5] # EGYPTIAN HIEROGLYPH V033A +133A6 ; [.426C.0020.0002.133A6] # EGYPTIAN HIEROGLYPH V034 +133A7 ; [.426D.0020.0002.133A7] # EGYPTIAN HIEROGLYPH V035 +133A8 ; [.426E.0020.0002.133A8] # EGYPTIAN HIEROGLYPH V036 +133A9 ; [.426F.0020.0002.133A9] # EGYPTIAN HIEROGLYPH V037 +133AA ; [.4270.0020.0002.133AA] # EGYPTIAN HIEROGLYPH V037A +133AB ; [.4271.0020.0002.133AB] # EGYPTIAN HIEROGLYPH V038 +133AC ; [.4272.0020.0002.133AC] # EGYPTIAN HIEROGLYPH V039 +133AD ; [.4273.0020.0002.133AD] # EGYPTIAN HIEROGLYPH V040 +133AE ; [.4274.0020.0002.133AE] # EGYPTIAN HIEROGLYPH V040A +133AF ; [.4275.0020.0002.133AF] # EGYPTIAN HIEROGLYPH W001 +133B0 ; [.4276.0020.0002.133B0] # EGYPTIAN HIEROGLYPH W002 +133B1 ; [.4277.0020.0002.133B1] # EGYPTIAN HIEROGLYPH W003 +133B2 ; [.4278.0020.0002.133B2] # EGYPTIAN HIEROGLYPH W003A +133B3 ; [.4279.0020.0002.133B3] # EGYPTIAN HIEROGLYPH W004 +133B4 ; [.427A.0020.0002.133B4] # EGYPTIAN HIEROGLYPH W005 +133B5 ; [.427B.0020.0002.133B5] # EGYPTIAN HIEROGLYPH W006 +133B6 ; [.427C.0020.0002.133B6] # EGYPTIAN HIEROGLYPH W007 +133B7 ; [.427D.0020.0002.133B7] # EGYPTIAN HIEROGLYPH W008 +133B8 ; [.427E.0020.0002.133B8] # EGYPTIAN HIEROGLYPH W009 +133B9 ; [.427F.0020.0002.133B9] # EGYPTIAN HIEROGLYPH W009A +133BA ; [.4280.0020.0002.133BA] # EGYPTIAN HIEROGLYPH W010 +133BB ; [.4281.0020.0002.133BB] # EGYPTIAN HIEROGLYPH W010A +133BC ; [.4282.0020.0002.133BC] # EGYPTIAN HIEROGLYPH W011 +133BD ; [.4283.0020.0002.133BD] # EGYPTIAN HIEROGLYPH W012 +133BE ; [.4284.0020.0002.133BE] # EGYPTIAN HIEROGLYPH W013 +133BF ; [.4285.0020.0002.133BF] # EGYPTIAN HIEROGLYPH W014 +133C0 ; [.4286.0020.0002.133C0] # EGYPTIAN HIEROGLYPH W014A +133C1 ; [.4287.0020.0002.133C1] # EGYPTIAN HIEROGLYPH W015 +133C2 ; [.4288.0020.0002.133C2] # EGYPTIAN HIEROGLYPH W016 +133C3 ; [.4289.0020.0002.133C3] # EGYPTIAN HIEROGLYPH W017 +133C4 ; [.428A.0020.0002.133C4] # EGYPTIAN HIEROGLYPH W017A +133C5 ; [.428B.0020.0002.133C5] # EGYPTIAN HIEROGLYPH W018 +133C6 ; [.428C.0020.0002.133C6] # EGYPTIAN HIEROGLYPH W018A +133C7 ; [.428D.0020.0002.133C7] # EGYPTIAN HIEROGLYPH W019 +133C8 ; [.428E.0020.0002.133C8] # EGYPTIAN HIEROGLYPH W020 +133C9 ; [.428F.0020.0002.133C9] # EGYPTIAN HIEROGLYPH W021 +133CA ; [.4290.0020.0002.133CA] # EGYPTIAN HIEROGLYPH W022 +133CB ; [.4291.0020.0002.133CB] # EGYPTIAN HIEROGLYPH W023 +133CC ; [.4292.0020.0002.133CC] # EGYPTIAN HIEROGLYPH W024 +133CD ; [.4293.0020.0002.133CD] # EGYPTIAN HIEROGLYPH W024A +133CE ; [.4294.0020.0002.133CE] # EGYPTIAN HIEROGLYPH W025 +133CF ; [.4295.0020.0002.133CF] # EGYPTIAN HIEROGLYPH X001 +133D0 ; [.4296.0020.0002.133D0] # EGYPTIAN HIEROGLYPH X002 +133D1 ; [.4297.0020.0002.133D1] # EGYPTIAN HIEROGLYPH X003 +133D2 ; [.4298.0020.0002.133D2] # EGYPTIAN HIEROGLYPH X004 +133D3 ; [.4299.0020.0002.133D3] # EGYPTIAN HIEROGLYPH X004A +133D4 ; [.429A.0020.0002.133D4] # EGYPTIAN HIEROGLYPH X004B +133D5 ; [.429B.0020.0002.133D5] # EGYPTIAN HIEROGLYPH X005 +133D6 ; [.429C.0020.0002.133D6] # EGYPTIAN HIEROGLYPH X006 +133D7 ; [.429D.0020.0002.133D7] # EGYPTIAN HIEROGLYPH X006A +133D8 ; [.429E.0020.0002.133D8] # EGYPTIAN HIEROGLYPH X007 +133D9 ; [.429F.0020.0002.133D9] # EGYPTIAN HIEROGLYPH X008 +133DA ; [.42A0.0020.0002.133DA] # EGYPTIAN HIEROGLYPH X008A +133DB ; [.42A1.0020.0002.133DB] # EGYPTIAN HIEROGLYPH Y001 +133DC ; [.42A2.0020.0002.133DC] # EGYPTIAN HIEROGLYPH Y001A +133DD ; [.42A3.0020.0002.133DD] # EGYPTIAN HIEROGLYPH Y002 +133DE ; [.42A4.0020.0002.133DE] # EGYPTIAN HIEROGLYPH Y003 +133DF ; [.42A5.0020.0002.133DF] # EGYPTIAN HIEROGLYPH Y004 +133E0 ; [.42A6.0020.0002.133E0] # EGYPTIAN HIEROGLYPH Y005 +133E1 ; [.42A7.0020.0002.133E1] # EGYPTIAN HIEROGLYPH Y006 +133E2 ; [.42A8.0020.0002.133E2] # EGYPTIAN HIEROGLYPH Y007 +133E3 ; [.42A9.0020.0002.133E3] # EGYPTIAN HIEROGLYPH Y008 +133E4 ; [.42AA.0020.0002.133E4] # EGYPTIAN HIEROGLYPH Z001 +133E5 ; [.42AB.0020.0002.133E5] # EGYPTIAN HIEROGLYPH Z002 +133E6 ; [.42AC.0020.0002.133E6] # EGYPTIAN HIEROGLYPH Z002A +133E7 ; [.42AD.0020.0002.133E7] # EGYPTIAN HIEROGLYPH Z002B +133E8 ; [.42AE.0020.0002.133E8] # EGYPTIAN HIEROGLYPH Z002C +133E9 ; [.42AF.0020.0002.133E9] # EGYPTIAN HIEROGLYPH Z002D +133EA ; [.42B0.0020.0002.133EA] # EGYPTIAN HIEROGLYPH Z003 +133EB ; [.42B1.0020.0002.133EB] # EGYPTIAN HIEROGLYPH Z003A +133EC ; [.42B2.0020.0002.133EC] # EGYPTIAN HIEROGLYPH Z003B +133ED ; [.42B3.0020.0002.133ED] # EGYPTIAN HIEROGLYPH Z004 +133EE ; [.42B4.0020.0002.133EE] # EGYPTIAN HIEROGLYPH Z004A +133EF ; [.42B5.0020.0002.133EF] # EGYPTIAN HIEROGLYPH Z005 +133F0 ; [.42B6.0020.0002.133F0] # EGYPTIAN HIEROGLYPH Z005A +133F1 ; [.42B7.0020.0002.133F1] # EGYPTIAN HIEROGLYPH Z006 +133F2 ; [.42B8.0020.0002.133F2] # EGYPTIAN HIEROGLYPH Z007 +133F3 ; [.42B9.0020.0002.133F3] # EGYPTIAN HIEROGLYPH Z008 +133F4 ; [.42BA.0020.0002.133F4] # EGYPTIAN HIEROGLYPH Z009 +133F5 ; [.42BB.0020.0002.133F5] # EGYPTIAN HIEROGLYPH Z010 +133F6 ; [.42BC.0020.0002.133F6] # EGYPTIAN HIEROGLYPH Z011 +133F7 ; [.42BD.0020.0002.133F7] # EGYPTIAN HIEROGLYPH Z012 +133F8 ; [.42BE.0020.0002.133F8] # EGYPTIAN HIEROGLYPH Z013 +133F9 ; [.42BF.0020.0002.133F9] # EGYPTIAN HIEROGLYPH Z014 +133FA ; [.42C0.0020.0002.133FA] # EGYPTIAN HIEROGLYPH Z015 +133FB ; [.42C1.0020.0002.133FB] # EGYPTIAN HIEROGLYPH Z015A +133FC ; [.42C2.0020.0002.133FC] # EGYPTIAN HIEROGLYPH Z015B +133FD ; [.42C3.0020.0002.133FD] # EGYPTIAN HIEROGLYPH Z015C +133FE ; [.42C4.0020.0002.133FE] # EGYPTIAN HIEROGLYPH Z015D +133FF ; [.42C5.0020.0002.133FF] # EGYPTIAN HIEROGLYPH Z015E +13400 ; [.42C6.0020.0002.13400] # EGYPTIAN HIEROGLYPH Z015F +13401 ; [.42C7.0020.0002.13401] # EGYPTIAN HIEROGLYPH Z015G +13402 ; [.42C8.0020.0002.13402] # EGYPTIAN HIEROGLYPH Z015H +13403 ; [.42C9.0020.0002.13403] # EGYPTIAN HIEROGLYPH Z015I +13404 ; [.42CA.0020.0002.13404] # EGYPTIAN HIEROGLYPH Z016 +13405 ; [.42CB.0020.0002.13405] # EGYPTIAN HIEROGLYPH Z016A +13406 ; [.42CC.0020.0002.13406] # EGYPTIAN HIEROGLYPH Z016B +13407 ; [.42CD.0020.0002.13407] # EGYPTIAN HIEROGLYPH Z016C +13408 ; [.42CE.0020.0002.13408] # EGYPTIAN HIEROGLYPH Z016D +13409 ; [.42CF.0020.0002.13409] # EGYPTIAN HIEROGLYPH Z016E +1340A ; [.42D0.0020.0002.1340A] # EGYPTIAN HIEROGLYPH Z016F +1340B ; [.42D1.0020.0002.1340B] # EGYPTIAN HIEROGLYPH Z016G +1340C ; [.42D2.0020.0002.1340C] # EGYPTIAN HIEROGLYPH Z016H +1340D ; [.42D3.0020.0002.1340D] # EGYPTIAN HIEROGLYPH AA001 +1340E ; [.42D4.0020.0002.1340E] # EGYPTIAN HIEROGLYPH AA002 +1340F ; [.42D5.0020.0002.1340F] # EGYPTIAN HIEROGLYPH AA003 +13410 ; [.42D6.0020.0002.13410] # EGYPTIAN HIEROGLYPH AA004 +13411 ; [.42D7.0020.0002.13411] # EGYPTIAN HIEROGLYPH AA005 +13412 ; [.42D8.0020.0002.13412] # EGYPTIAN HIEROGLYPH AA006 +13413 ; [.42D9.0020.0002.13413] # EGYPTIAN HIEROGLYPH AA007 +13414 ; [.42DA.0020.0002.13414] # EGYPTIAN HIEROGLYPH AA007A +13415 ; [.42DB.0020.0002.13415] # EGYPTIAN HIEROGLYPH AA007B +13416 ; [.42DC.0020.0002.13416] # EGYPTIAN HIEROGLYPH AA008 +13417 ; [.42DD.0020.0002.13417] # EGYPTIAN HIEROGLYPH AA009 +13418 ; [.42DE.0020.0002.13418] # EGYPTIAN HIEROGLYPH AA010 +13419 ; [.42DF.0020.0002.13419] # EGYPTIAN HIEROGLYPH AA011 +1341A ; [.42E0.0020.0002.1341A] # EGYPTIAN HIEROGLYPH AA012 +1341B ; [.42E1.0020.0002.1341B] # EGYPTIAN HIEROGLYPH AA013 +1341C ; [.42E2.0020.0002.1341C] # EGYPTIAN HIEROGLYPH AA014 +1341D ; [.42E3.0020.0002.1341D] # EGYPTIAN HIEROGLYPH AA015 +1341E ; [.42E4.0020.0002.1341E] # EGYPTIAN HIEROGLYPH AA016 +1341F ; [.42E5.0020.0002.1341F] # EGYPTIAN HIEROGLYPH AA017 +13420 ; [.42E6.0020.0002.13420] # EGYPTIAN HIEROGLYPH AA018 +13421 ; [.42E7.0020.0002.13421] # EGYPTIAN HIEROGLYPH AA019 +13422 ; [.42E8.0020.0002.13422] # EGYPTIAN HIEROGLYPH AA020 +13423 ; [.42E9.0020.0002.13423] # EGYPTIAN HIEROGLYPH AA021 +13424 ; [.42EA.0020.0002.13424] # EGYPTIAN HIEROGLYPH AA022 +13425 ; [.42EB.0020.0002.13425] # EGYPTIAN HIEROGLYPH AA023 +13426 ; [.42EC.0020.0002.13426] # EGYPTIAN HIEROGLYPH AA024 +13427 ; [.42ED.0020.0002.13427] # EGYPTIAN HIEROGLYPH AA025 +13428 ; [.42EE.0020.0002.13428] # EGYPTIAN HIEROGLYPH AA026 +13429 ; [.42EF.0020.0002.13429] # EGYPTIAN HIEROGLYPH AA027 +1342A ; [.42F0.0020.0002.1342A] # EGYPTIAN HIEROGLYPH AA028 +1342B ; [.42F1.0020.0002.1342B] # EGYPTIAN HIEROGLYPH AA029 +1342C ; [.42F2.0020.0002.1342C] # EGYPTIAN HIEROGLYPH AA030 +1342D ; [.42F3.0020.0002.1342D] # EGYPTIAN HIEROGLYPH AA031 +1342E ; [.42F4.0020.0002.1342E] # EGYPTIAN HIEROGLYPH AA032 +109A0 ; [.42F5.0020.0002.109A0] # MEROITIC CURSIVE LETTER A +10980 ; [.42F5.0020.0004.10980][.0000.0139.0004.10980] # MEROITIC HIEROGLYPHIC LETTER A +109A1 ; [.42F6.0020.0002.109A1] # MEROITIC CURSIVE LETTER E +10981 ; [.42F6.0020.0004.10981][.0000.0139.0004.10981] # MEROITIC HIEROGLYPHIC LETTER E +109A2 ; [.42F7.0020.0002.109A2] # MEROITIC CURSIVE LETTER I +10982 ; [.42F7.0020.0004.10982][.0000.0139.0004.10982] # MEROITIC HIEROGLYPHIC LETTER I +109A3 ; [.42F8.0020.0002.109A3] # MEROITIC CURSIVE LETTER O +10983 ; [.42F8.0020.0004.10983][.0000.0139.0004.10983] # MEROITIC HIEROGLYPHIC LETTER O +109A4 ; [.42F9.0020.0002.109A4] # MEROITIC CURSIVE LETTER YA +10984 ; [.42F9.0020.0004.10984][.0000.0139.0004.10984] # MEROITIC HIEROGLYPHIC LETTER YA +109A5 ; [.42FA.0020.0002.109A5] # MEROITIC CURSIVE LETTER WA +10985 ; [.42FA.0020.0004.10985][.0000.0139.0004.10985] # MEROITIC HIEROGLYPHIC LETTER WA +109A6 ; [.42FB.0020.0002.109A6] # MEROITIC CURSIVE LETTER BA +10986 ; [.42FB.0020.0004.10986][.0000.0139.0004.10986] # MEROITIC HIEROGLYPHIC LETTER BA +10987 ; [.42FB.0020.0004.10987][.0000.013A.0004.10987] # MEROITIC HIEROGLYPHIC LETTER BA-2 +109A7 ; [.42FC.0020.0002.109A7] # MEROITIC CURSIVE LETTER PA +10988 ; [.42FC.0020.0004.10988][.0000.0139.0004.10988] # MEROITIC HIEROGLYPHIC LETTER PA +109A8 ; [.42FD.0020.0002.109A8] # MEROITIC CURSIVE LETTER MA +10989 ; [.42FD.0020.0004.10989][.0000.0139.0004.10989] # MEROITIC HIEROGLYPHIC LETTER MA +109A9 ; [.42FE.0020.0002.109A9] # MEROITIC CURSIVE LETTER NA +1098A ; [.42FE.0020.0004.1098A][.0000.0139.0004.1098A] # MEROITIC HIEROGLYPHIC LETTER NA +1098B ; [.42FE.0020.0004.1098B][.0000.013A.0004.1098B] # MEROITIC HIEROGLYPHIC LETTER NA-2 +109AA ; [.42FF.0020.0002.109AA] # MEROITIC CURSIVE LETTER NE +1098C ; [.42FF.0020.0004.1098C][.0000.0139.0004.1098C] # MEROITIC HIEROGLYPHIC LETTER NE +1098D ; [.42FF.0020.0004.1098D][.0000.013A.0004.1098D] # MEROITIC HIEROGLYPHIC LETTER NE-2 +109AB ; [.4300.0020.0002.109AB] # MEROITIC CURSIVE LETTER RA +1098E ; [.4300.0020.0004.1098E][.0000.0139.0004.1098E] # MEROITIC HIEROGLYPHIC LETTER RA +1098F ; [.4300.0020.0004.1098F][.0000.013A.0004.1098F] # MEROITIC HIEROGLYPHIC LETTER RA-2 +109AC ; [.4301.0020.0002.109AC] # MEROITIC CURSIVE LETTER LA +10990 ; [.4301.0020.0004.10990][.0000.0139.0004.10990] # MEROITIC HIEROGLYPHIC LETTER LA +109AD ; [.4302.0020.0002.109AD] # MEROITIC CURSIVE LETTER KHA +10991 ; [.4302.0020.0004.10991][.0000.0139.0004.10991] # MEROITIC HIEROGLYPHIC LETTER KHA +109AE ; [.4303.0020.0002.109AE] # MEROITIC CURSIVE LETTER HHA +10992 ; [.4303.0020.0004.10992][.0000.0139.0004.10992] # MEROITIC HIEROGLYPHIC LETTER HHA +109AF ; [.4304.0020.0002.109AF] # MEROITIC CURSIVE LETTER SA +109B0 ; [.4304.0020.0004.109B0][.0000.0139.0004.109B0] # MEROITIC CURSIVE LETTER ARCHAIC SA +10993 ; [.4304.0020.0004.10993][.0000.013A.0004.10993] # MEROITIC HIEROGLYPHIC LETTER SA +10994 ; [.4304.0020.0004.10994][.0000.013C.0004.10994] # MEROITIC HIEROGLYPHIC LETTER SA-2 +109B1 ; [.4305.0020.0002.109B1] # MEROITIC CURSIVE LETTER SE +10995 ; [.4305.0020.0004.10995][.0000.0139.0004.10995] # MEROITIC HIEROGLYPHIC LETTER SE +109B2 ; [.4306.0020.0002.109B2] # MEROITIC CURSIVE LETTER KA +10996 ; [.4306.0020.0004.10996][.0000.0139.0004.10996] # MEROITIC HIEROGLYPHIC LETTER KA +109B3 ; [.4307.0020.0002.109B3] # MEROITIC CURSIVE LETTER QA +10997 ; [.4307.0020.0004.10997][.0000.0139.0004.10997] # MEROITIC HIEROGLYPHIC LETTER QA +109B4 ; [.4308.0020.0002.109B4] # MEROITIC CURSIVE LETTER TA +10998 ; [.4308.0020.0004.10998][.0000.0139.0004.10998] # MEROITIC HIEROGLYPHIC LETTER TA +10999 ; [.4308.0020.0004.10999][.0000.013A.0004.10999] # MEROITIC HIEROGLYPHIC LETTER TA-2 +109B5 ; [.4309.0020.0002.109B5] # MEROITIC CURSIVE LETTER TE +1099A ; [.4309.0020.0004.1099A][.0000.0139.0004.1099A] # MEROITIC HIEROGLYPHIC LETTER TE +1099B ; [.4309.0020.0004.1099B][.0000.013A.0004.1099B] # MEROITIC HIEROGLYPHIC LETTER TE-2 +109B6 ; [.430A.0020.0002.109B6] # MEROITIC CURSIVE LETTER TO +1099C ; [.430A.0020.0004.1099C][.0000.0139.0004.1099C] # MEROITIC HIEROGLYPHIC LETTER TO +109B7 ; [.430B.0020.0002.109B7] # MEROITIC CURSIVE LETTER DA +1099D ; [.430B.0020.0004.1099D][.0000.0139.0004.1099D] # MEROITIC HIEROGLYPHIC LETTER DA +109BE ; [.430C.0020.0002.109BE] # MEROITIC CURSIVE LOGOGRAM RMT +109BF ; [.430D.0020.0002.109BF] # MEROITIC CURSIVE LOGOGRAM IMN +1099E ; [.430E.0020.0002.1099E] # MEROITIC HIEROGLYPHIC SYMBOL VIDJ +1099F ; [.430F.0020.0002.1099F] # MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2 +2F00 ; [.FB40.0020.0004.4E00][.CE00.0000.0000.4E00] # KANGXI RADICAL ONE +3220 ; [*02FB.0020.0004.3220][.FB40.0020.0004.4E00][.CE00.0000.0000.4E00][*02FC.0020.001F.3220] # PARENTHESIZED IDEOGRAPH ONE +3280 ; [.FB40.0020.0006.4E00][.CE00.0000.0000.4E00] # CIRCLED IDEOGRAPH ONE +3192 ; [.FB40.0020.0014.4E00][.CE00.0000.0000.4E00] # IDEOGRAPHIC ANNOTATION ONE MARK +1F229 ; [.FB40.0020.001C.4E00][.CE00.0000.0000.4E00] # SQUARED CJK UNIFIED IDEOGRAPH-4E00 +319C ; [.FB40.0020.0014.4E01][.CE01.0000.0000.4E01] # IDEOGRAPHIC ANNOTATION FOURTH MARK +3226 ; [*02FB.0020.0004.3226][.FB40.0020.0004.4E03][.CE03.0000.0000.4E03][*02FC.0020.001F.3226] # PARENTHESIZED IDEOGRAPH SEVEN +3286 ; [.FB40.0020.0006.4E03][.CE03.0000.0000.4E03] # CIRCLED IDEOGRAPH SEVEN +3222 ; [*02FB.0020.0004.3222][.FB40.0020.0004.4E09][.CE09.0000.0000.4E09][*02FC.0020.001F.3222] # PARENTHESIZED IDEOGRAPH THREE +1F241 ; [*0359.0020.0004.1F241][.FB40.0020.0004.4E09][.CE09.0000.0000.4E09][*035A.0020.001F.1F241] # TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E09 +3282 ; [.FB40.0020.0006.4E09][.CE09.0000.0000.4E09] # CIRCLED IDEOGRAPH THREE +3194 ; [.FB40.0020.0014.4E09][.CE09.0000.0000.4E09] # IDEOGRAPHIC ANNOTATION THREE MARK +1F22A ; [.FB40.0020.001C.4E09][.CE09.0000.0000.4E09] # SQUARED CJK UNIFIED IDEOGRAPH-4E09 +32A4 ; [.FB40.0020.0006.4E0A][.CE0A.0000.0000.4E0A] # CIRCLED IDEOGRAPH HIGH +3196 ; [.FB40.0020.0014.4E0A][.CE0A.0000.0000.4E0A] # IDEOGRAPHIC ANNOTATION TOP MARK +32A6 ; [.FB40.0020.0006.4E0B][.CE0B.0000.0000.4E0B] # CIRCLED IDEOGRAPH LOW +3198 ; [.FB40.0020.0014.4E0B][.CE0B.0000.0000.4E0B] # IDEOGRAPHIC ANNOTATION BOTTOM MARK +F967 ; [.FB40.0020.0002.4E0D][.CE0D.0000.0000.4E0D] # CJK COMPATIBILITY IDEOGRAPH-F967 +319B ; [.FB40.0020.0014.4E19][.CE19.0000.0000.4E19] # IDEOGRAPHIC ANNOTATION THIRD MARK +FA70 ; [.FB40.0020.0002.4E26][.CE26.0000.0000.4E26] # CJK COMPATIBILITY IDEOGRAPH-FA70 +2F01 ; [.FB40.0020.0004.4E28][.CE28.0000.0000.4E28] # KANGXI RADICAL LINE +2EA6 ; [.FB40.0020.0004.4E2C][.CE2C.0000.0000.4E2C] # CJK RADICAL SIMPLIFIED HALF TREE TRUNK +32A5 ; [.FB40.0020.0006.4E2D][.CE2D.0000.0000.4E2D] # CIRCLED IDEOGRAPH CENTRE +3197 ; [.FB40.0020.0014.4E2D][.CE2D.0000.0000.4E2D] # IDEOGRAPHIC ANNOTATION MIDDLE MARK +1F22D ; [.FB40.0020.001C.4E2D][.CE2D.0000.0000.4E2D] # SQUARED CJK UNIFIED IDEOGRAPH-4E2D +F905 ; [.FB40.0020.0002.4E32][.CE32.0000.0000.4E32] # CJK COMPATIBILITY IDEOGRAPH-F905 +2F02 ; [.FB40.0020.0004.4E36][.CE36.0000.0000.4E36] # KANGXI RADICAL DOT +2E80 ; [.FB40.0020.0004.4E36][.CE36.0000.0000.4E36][.0000.0139.001F.2E80] # CJK RADICAL REPEAT +2F801 ; [.FB40.0020.0002.4E38][.CE38.0000.0000.4E38] # CJK COMPATIBILITY IDEOGRAPH-2F801 +F95E ; [.FB40.0020.0002.4E39][.CE39.0000.0000.4E39] # CJK COMPATIBILITY IDEOGRAPH-F95E +2F800 ; [.FB40.0020.0002.4E3D][.CE3D.0000.0000.4E3D] # CJK COMPATIBILITY IDEOGRAPH-2F800 +2F03 ; [.FB40.0020.0004.4E3F][.CE3F.0000.0000.4E3F] # KANGXI RADICAL SLASH +2F802 ; [.FB40.0020.0002.4E41][.CE41.0000.0000.4E41] # CJK COMPATIBILITY IDEOGRAPH-2F802 +2F04 ; [.FB40.0020.0004.4E59][.CE59.0000.0000.4E59] # KANGXI RADICAL SECOND +319A ; [.FB40.0020.0014.4E59][.CE59.0000.0000.4E59] # IDEOGRAPHIC ANNOTATION SECOND MARK +2E84 ; [.FB40.0020.0004.4E59][.CE59.0000.0000.4E59][.0000.0139.001F.2E84] # CJK RADICAL SECOND THREE +2E83 ; [.FB40.0020.0004.4E5A][.CE5A.0000.0000.4E5A] # CJK RADICAL SECOND TWO +2E82 ; [.FB40.0020.0004.4E5B][.CE5B.0000.0000.4E5B] # CJK RADICAL SECOND ONE +3228 ; [*02FB.0020.0004.3228][.FB40.0020.0004.4E5D][.CE5D.0000.0000.4E5D][*02FC.0020.001F.3228] # PARENTHESIZED IDEOGRAPH NINE +3288 ; [.FB40.0020.0006.4E5D][.CE5D.0000.0000.4E5D] # CIRCLED IDEOGRAPH NINE +F91B ; [.FB40.0020.0002.4E82][.CE82.0000.0000.4E82] # CJK COMPATIBILITY IDEOGRAPH-F91B +2F05 ; [.FB40.0020.0004.4E85][.CE85.0000.0000.4E85] # KANGXI RADICAL HOOK +F9BA ; [.FB40.0020.0002.4E86][.CE86.0000.0000.4E86] # CJK COMPATIBILITY IDEOGRAPH-F9BA +2F06 ; [.FB40.0020.0004.4E8C][.CE8C.0000.0000.4E8C] # KANGXI RADICAL TWO +3221 ; [*02FB.0020.0004.3221][.FB40.0020.0004.4E8C][.CE8C.0000.0000.4E8C][*02FC.0020.001F.3221] # PARENTHESIZED IDEOGRAPH TWO +1F242 ; [*0359.0020.0004.1F242][.FB40.0020.0004.4E8C][.CE8C.0000.0000.4E8C][*035A.0020.001F.1F242] # TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E8C +3281 ; [.FB40.0020.0006.4E8C][.CE8C.0000.0000.4E8C] # CIRCLED IDEOGRAPH TWO +3193 ; [.FB40.0020.0014.4E8C][.CE8C.0000.0000.4E8C] # IDEOGRAPHIC ANNOTATION TWO MARK +1F214 ; [.FB40.0020.001C.4E8C][.CE8C.0000.0000.4E8C] # SQUARED CJK UNIFIED IDEOGRAPH-4E8C +3224 ; [*02FB.0020.0004.3224][.FB40.0020.0004.4E94][.CE94.0000.0000.4E94][*02FC.0020.001F.3224] # PARENTHESIZED IDEOGRAPH FIVE +3284 ; [.FB40.0020.0006.4E94][.CE94.0000.0000.4E94] # CIRCLED IDEOGRAPH FIVE +2F07 ; [.FB40.0020.0004.4EA0][.CEA0.0000.0000.4EA0] # KANGXI RADICAL LID +1F218 ; [.FB40.0020.001C.4EA4][.CEA4.0000.0000.4EA4] # SQUARED CJK UNIFIED IDEOGRAPH-4EA4 +F977 ; [.FB40.0020.0002.4EAE][.CEAE.0000.0000.4EAE] # CJK COMPATIBILITY IDEOGRAPH-F977 +2F08 ; [.FB40.0020.0004.4EBA][.CEBA.0000.0000.4EBA] # KANGXI RADICAL MAN +319F ; [.FB40.0020.0014.4EBA][.CEBA.0000.0000.4EBA] # IDEOGRAPHIC ANNOTATION MAN MARK +2E85 ; [.FB40.0020.0004.4EBB][.CEBB.0000.0000.4EBB] # CJK RADICAL PERSON +F9FD ; [.FB40.0020.0002.4EC0][.CEC0.0000.0000.4EC0] # CJK COMPATIBILITY IDEOGRAPH-F9FD +2F819 ; [.FB40.0020.0002.4ECC][.CECC.0000.0000.4ECC] # CJK COMPATIBILITY IDEOGRAPH-2F819 +3239 ; [*02FB.0020.0004.3239][.FB40.0020.0004.4EE3][.CEE3.0000.0000.4EE3][*02FC.0020.001F.3239] # PARENTHESIZED IDEOGRAPH REPRESENT +F9A8 ; [.FB40.0020.0002.4EE4][.CEE4.0000.0000.4EE4] # CJK COMPATIBILITY IDEOGRAPH-F9A8 +323D ; [*02FB.0020.0004.323D][.FB40.0020.0004.4F01][.CF01.0000.0000.4F01][*02FC.0020.001F.323D] # PARENTHESIZED IDEOGRAPH ENTERPRISE +32AD ; [.FB40.0020.0006.4F01][.CF01.0000.0000.4F01] # CIRCLED IDEOGRAPH ENTERPRISE +3241 ; [*02FB.0020.0004.3241][.FB40.0020.0004.4F11][.CF11.0000.0000.4F11][*02FC.0020.001F.3241] # PARENTHESIZED IDEOGRAPH REST +32A1 ; [.FB40.0020.0006.4F11][.CF11.0000.0000.4F11] # CIRCLED IDEOGRAPH REST +2F804 ; [.FB40.0020.0002.4F60][.CF60.0000.0000.4F60] # CJK COMPATIBILITY IDEOGRAPH-2F804 +FA73 ; [.FB40.0020.0002.4F80][.CF80.0000.0000.4F80] # CJK COMPATIBILITY IDEOGRAPH-FA73 +F92D ; [.FB40.0020.0002.4F86][.CF86.0000.0000.4F86] # CJK COMPATIBILITY IDEOGRAPH-F92D +F9B5 ; [.FB40.0020.0002.4F8B][.CF8B.0000.0000.4F8B] # CJK COMPATIBILITY IDEOGRAPH-F9B5 +FA30 ; [.FB40.0020.0002.4FAE][.CFAE.0000.0000.4FAE] # CJK COMPATIBILITY IDEOGRAPH-FA30 +2F805 ; [.FB40.0020.0002.4FAE][.CFAE.0000.0000.4FAE] # CJK COMPATIBILITY IDEOGRAPH-2F805 +2F806 ; [.FB40.0020.0002.4FBB][.CFBB.0000.0000.4FBB] # CJK COMPATIBILITY IDEOGRAPH-2F806 +F965 ; [.FB40.0020.0002.4FBF][.CFBF.0000.0000.4FBF] # CJK COMPATIBILITY IDEOGRAPH-F965 +2F807 ; [.FB40.0020.0002.5002][.D002.0000.0000.5002] # CJK COMPATIBILITY IDEOGRAPH-2F807 +F9D4 ; [.FB40.0020.0002.502B][.D02B.0000.0000.502B] # CJK COMPATIBILITY IDEOGRAPH-F9D4 +2F808 ; [.FB40.0020.0002.507A][.D07A.0000.0000.507A] # CJK COMPATIBILITY IDEOGRAPH-2F808 +2F809 ; [.FB40.0020.0002.5099][.D099.0000.0000.5099] # CJK COMPATIBILITY IDEOGRAPH-2F809 +2F80B ; [.FB40.0020.0002.50CF][.D0CF.0000.0000.50CF] # CJK COMPATIBILITY IDEOGRAPH-2F80B +F9BB ; [.FB40.0020.0002.50DA][.D0DA.0000.0000.50DA] # CJK COMPATIBILITY IDEOGRAPH-F9BB +FA31 ; [.FB40.0020.0002.50E7][.D0E7.0000.0000.50E7] # CJK COMPATIBILITY IDEOGRAPH-FA31 +2F80A ; [.FB40.0020.0002.50E7][.D0E7.0000.0000.50E7] # CJK COMPATIBILITY IDEOGRAPH-2F80A +329D ; [.FB40.0020.0006.512A][.D12A.0000.0000.512A] # CIRCLED IDEOGRAPH EXCELLENT +2F09 ; [.FB40.0020.0004.513F][.D13F.0000.0000.513F] # KANGXI RADICAL LEGS +FA0C ; [.FB40.0020.0002.5140][.D140.0000.0000.5140] # CJK COMPATIBILITY IDEOGRAPH-FA0C +FA74 ; [.FB40.0020.0002.5145][.D145.0000.0000.5145] # CJK COMPATIBILITY IDEOGRAPH-FA74 +FA32 ; [.FB40.0020.0002.514D][.D14D.0000.0000.514D] # CJK COMPATIBILITY IDEOGRAPH-FA32 +2F80E ; [.FB40.0020.0002.514D][.D14D.0000.0000.514D] # CJK COMPATIBILITY IDEOGRAPH-2F80E +2F80F ; [.FB40.0020.0002.5154][.D154.0000.0000.5154] # CJK COMPATIBILITY IDEOGRAPH-2F80F +2F810 ; [.FB40.0020.0002.5164][.D164.0000.0000.5164] # CJK COMPATIBILITY IDEOGRAPH-2F810 +2F0A ; [.FB40.0020.0004.5165][.D165.0000.0000.5165] # KANGXI RADICAL ENTER +2F814 ; [.FB40.0020.0002.5167][.D167.0000.0000.5167] # CJK COMPATIBILITY IDEOGRAPH-2F814 +FA72 ; [.FB40.0020.0002.5168][.D168.0000.0000.5168] # CJK COMPATIBILITY IDEOGRAPH-FA72 +F978 ; [.FB40.0020.0002.5169][.D169.0000.0000.5169] # CJK COMPATIBILITY IDEOGRAPH-F978 +2F0B ; [.FB40.0020.0004.516B][.D16B.0000.0000.516B] # KANGXI RADICAL EIGHT +3227 ; [*02FB.0020.0004.3227][.FB40.0020.0004.516B][.D16B.0000.0000.516B][*02FC.0020.001F.3227] # PARENTHESIZED IDEOGRAPH EIGHT +3287 ; [.FB40.0020.0006.516B][.D16B.0000.0000.516B] # CIRCLED IDEOGRAPH EIGHT +F9D1 ; [.FB40.0020.0002.516D][.D16D.0000.0000.516D] # CJK COMPATIBILITY IDEOGRAPH-F9D1 +3225 ; [*02FB.0020.0004.3225][.FB40.0020.0004.516D][.D16D.0000.0000.516D][*02FC.0020.001F.3225] # PARENTHESIZED IDEOGRAPH SIX +3285 ; [.FB40.0020.0006.516D][.D16D.0000.0000.516D] # CIRCLED IDEOGRAPH SIX +2F811 ; [.FB40.0020.0002.5177][.D177.0000.0000.5177] # CJK COMPATIBILITY IDEOGRAPH-2F811 +FA75 ; [.FB40.0020.0002.5180][.D180.0000.0000.5180] # CJK COMPATIBILITY IDEOGRAPH-FA75 +2F0C ; [.FB40.0020.0004.5182][.D182.0000.0000.5182] # KANGXI RADICAL DOWN BOX +2E86 ; [.FB40.0020.0004.5182][.D182.0000.0000.5182][.0000.0139.001F.2E86] # CJK RADICAL BOX +2F815 ; [.FB40.0020.0002.518D][.D18D.0000.0000.518D] # CJK COMPATIBILITY IDEOGRAPH-2F815 +1F21E ; [.FB40.0020.001C.518D][.D18D.0000.0000.518D] # SQUARED CJK UNIFIED IDEOGRAPH-518D +2F8D2 ; [.FB40.0020.0002.5192][.D192.0000.0000.5192] # CJK COMPATIBILITY IDEOGRAPH-2F8D2 +2F8D3 ; [.FB40.0020.0002.5195][.D195.0000.0000.5195] # CJK COMPATIBILITY IDEOGRAPH-2F8D3 +2F0D ; [.FB40.0020.0004.5196][.D196.0000.0000.5196] # KANGXI RADICAL COVER +2F817 ; [.FB40.0020.0002.5197][.D197.0000.0000.5197] # CJK COMPATIBILITY IDEOGRAPH-2F817 +32A2 ; [.FB40.0020.0006.5199][.D199.0000.0000.5199] # CIRCLED IDEOGRAPH COPY +2F818 ; [.FB40.0020.0002.51A4][.D1A4.0000.0000.51A4] # CJK COMPATIBILITY IDEOGRAPH-2F818 +2F0E ; [.FB40.0020.0004.51AB][.D1AB.0000.0000.51AB] # KANGXI RADICAL ICE +2F81A ; [.FB40.0020.0002.51AC][.D1AC.0000.0000.51AC] # CJK COMPATIBILITY IDEOGRAPH-2F81A +FA71 ; [.FB40.0020.0002.51B5][.D1B5.0000.0000.51B5] # CJK COMPATIBILITY IDEOGRAPH-FA71 +2F81B ; [.FB40.0020.0002.51B5][.D1B5.0000.0000.51B5] # CJK COMPATIBILITY IDEOGRAPH-2F81B +F92E ; [.FB40.0020.0002.51B7][.D1B7.0000.0000.51B7] # CJK COMPATIBILITY IDEOGRAPH-F92E +F979 ; [.FB40.0020.0002.51C9][.D1C9.0000.0000.51C9] # CJK COMPATIBILITY IDEOGRAPH-F979 +F955 ; [.FB40.0020.0002.51CC][.D1CC.0000.0000.51CC] # CJK COMPATIBILITY IDEOGRAPH-F955 +F954 ; [.FB40.0020.0002.51DC][.D1DC.0000.0000.51DC] # CJK COMPATIBILITY IDEOGRAPH-F954 +FA15 ; [.FB40.0020.0002.51DE][.D1DE.0000.0000.51DE] # CJK COMPATIBILITY IDEOGRAPH-FA15 +2F0F ; [.FB40.0020.0004.51E0][.D1E0.0000.0000.51E0] # KANGXI RADICAL TABLE +2E87 ; [.FB40.0020.0004.51E0][.D1E0.0000.0000.51E0][.0000.0139.001F.2E87] # CJK RADICAL TABLE +2F81D ; [.FB40.0020.0002.51F5][.D1F5.0000.0000.51F5] # CJK COMPATIBILITY IDEOGRAPH-2F81D +2F10 ; [.FB40.0020.0004.51F5][.D1F5.0000.0000.51F5] # KANGXI RADICAL OPEN BOX +2F11 ; [.FB40.0020.0004.5200][.D200.0000.0000.5200] # KANGXI RADICAL KNIFE +2E88 ; [.FB40.0020.0004.5200][.D200.0000.0000.5200][.0000.0139.001F.2E88] # CJK RADICAL KNIFE ONE +2E89 ; [.FB40.0020.0004.5202][.D202.0000.0000.5202] # CJK RADICAL KNIFE TWO +2F81E ; [.FB40.0020.0002.5203][.D203.0000.0000.5203] # CJK COMPATIBILITY IDEOGRAPH-2F81E +FA00 ; [.FB40.0020.0002.5207][.D207.0000.0000.5207] # CJK COMPATIBILITY IDEOGRAPH-FA00 +2F850 ; [.FB40.0020.0002.5207][.D207.0000.0000.5207] # CJK COMPATIBILITY IDEOGRAPH-2F850 +F99C ; [.FB40.0020.0002.5217][.D217.0000.0000.5217] # CJK COMPATIBILITY IDEOGRAPH-F99C +1F220 ; [.FB40.0020.001C.521D][.D21D.0000.0000.521D] # SQUARED CJK UNIFIED IDEOGRAPH-521D +F9DD ; [.FB40.0020.0002.5229][.D229.0000.0000.5229] # CJK COMPATIBILITY IDEOGRAPH-F9DD +F9FF ; [.FB40.0020.0002.523A][.D23A.0000.0000.523A] # CJK COMPATIBILITY IDEOGRAPH-F9FF +2F820 ; [.FB40.0020.0002.523B][.D23B.0000.0000.523B] # CJK COMPATIBILITY IDEOGRAPH-2F820 +2F821 ; [.FB40.0020.0002.5246][.D246.0000.0000.5246] # CJK COMPATIBILITY IDEOGRAPH-2F821 +1F21C ; [.FB40.0020.001C.524D][.D24D.0000.0000.524D] # SQUARED CJK UNIFIED IDEOGRAPH-524D +2F822 ; [.FB40.0020.0002.5272][.D272.0000.0000.5272] # CJK COMPATIBILITY IDEOGRAPH-2F822 +1F239 ; [.FB40.0020.001C.5272][.D272.0000.0000.5272] # SQUARED CJK UNIFIED IDEOGRAPH-5272 +2F823 ; [.FB40.0020.0002.5277][.D277.0000.0000.5277] # CJK COMPATIBILITY IDEOGRAPH-2F823 +F9C7 ; [.FB40.0020.0002.5289][.D289.0000.0000.5289] # CJK COMPATIBILITY IDEOGRAPH-F9C7 +F98A ; [.FB40.0020.0002.529B][.D29B.0000.0000.529B] # CJK COMPATIBILITY IDEOGRAPH-F98A +2F12 ; [.FB40.0020.0004.529B][.D29B.0000.0000.529B] # KANGXI RADICAL POWER +F99D ; [.FB40.0020.0002.52A3][.D2A3.0000.0000.52A3] # CJK COMPATIBILITY IDEOGRAPH-F99D +2F992 ; [.FB40.0020.0002.52B3][.D2B3.0000.0000.52B3] # CJK COMPATIBILITY IDEOGRAPH-2F992 +3238 ; [*02FB.0020.0004.3238][.FB40.0020.0004.52B4][.D2B4.0000.0000.52B4][*02FC.0020.001F.3238] # PARENTHESIZED IDEOGRAPH LABOR +3298 ; [.FB40.0020.0006.52B4][.D2B4.0000.0000.52B4] # CIRCLED IDEOGRAPH LABOR +FA76 ; [.FB40.0020.0002.52C7][.D2C7.0000.0000.52C7] # CJK COMPATIBILITY IDEOGRAPH-FA76 +2F825 ; [.FB40.0020.0002.52C7][.D2C7.0000.0000.52C7] # CJK COMPATIBILITY IDEOGRAPH-2F825 +FA33 ; [.FB40.0020.0002.52C9][.D2C9.0000.0000.52C9] # CJK COMPATIBILITY IDEOGRAPH-FA33 +2F826 ; [.FB40.0020.0002.52C9][.D2C9.0000.0000.52C9] # CJK COMPATIBILITY IDEOGRAPH-2F826 +F952 ; [.FB40.0020.0002.52D2][.D2D2.0000.0000.52D2] # CJK COMPATIBILITY IDEOGRAPH-F952 +1F247 ; [*0359.0020.0004.1F247][.FB40.0020.0004.52DD][.D2DD.0000.0000.52DD][*035A.0020.001F.1F247] # TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-52DD +F92F ; [.FB40.0020.0002.52DE][.D2DE.0000.0000.52DE] # CJK COMPATIBILITY IDEOGRAPH-F92F +FA34 ; [.FB40.0020.0002.52E4][.D2E4.0000.0000.52E4] # CJK COMPATIBILITY IDEOGRAPH-FA34 +2F827 ; [.FB40.0020.0002.52E4][.D2E4.0000.0000.52E4] # CJK COMPATIBILITY IDEOGRAPH-2F827 +F97F ; [.FB40.0020.0002.52F5][.D2F5.0000.0000.52F5] # CJK COMPATIBILITY IDEOGRAPH-F97F +2F13 ; [.FB40.0020.0004.52F9][.D2F9.0000.0000.52F9] # KANGXI RADICAL WRAP +FA77 ; [.FB40.0020.0002.52FA][.D2FA.0000.0000.52FA] # CJK COMPATIBILITY IDEOGRAPH-FA77 +2F828 ; [.FB40.0020.0002.52FA][.D2FA.0000.0000.52FA] # CJK COMPATIBILITY IDEOGRAPH-2F828 +2F829 ; [.FB40.0020.0002.5305][.D305.0000.0000.5305] # CJK COMPATIBILITY IDEOGRAPH-2F829 +2F82A ; [.FB40.0020.0002.5306][.D306.0000.0000.5306] # CJK COMPATIBILITY IDEOGRAPH-2F82A +2F14 ; [.FB40.0020.0004.5315][.D315.0000.0000.5315] # KANGXI RADICAL SPOON +F963 ; [.FB40.0020.0002.5317][.D317.0000.0000.5317] # CJK COMPATIBILITY IDEOGRAPH-F963 +2F82B ; [.FB40.0020.0002.5317][.D317.0000.0000.5317] # CJK COMPATIBILITY IDEOGRAPH-2F82B +2F15 ; [.FB40.0020.0004.531A][.D31A.0000.0000.531A] # KANGXI RADICAL RIGHT OPEN BOX +2F16 ; [.FB40.0020.0004.5338][.D338.0000.0000.5338] # KANGXI RADICAL HIDING ENCLOSURE +32A9 ; [.FB40.0020.0006.533B][.D33B.0000.0000.533B] # CIRCLED IDEOGRAPH MEDICINE +F9EB ; [.FB40.0020.0002.533F][.D33F.0000.0000.533F] # CJK COMPATIBILITY IDEOGRAPH-F9EB +2F17 ; [.FB40.0020.0004.5341][.D341.0000.0000.5341] # KANGXI RADICAL TEN +3038 ; [.FB40.0020.0004.5341][.D341.0000.0000.5341] # HANGZHOU NUMERAL TEN +3229 ; [*02FB.0020.0004.3229][.FB40.0020.0004.5341][.D341.0000.0000.5341][*02FC.0020.001F.3229] # PARENTHESIZED IDEOGRAPH TEN +3289 ; [.FB40.0020.0006.5341][.D341.0000.0000.5341] # CIRCLED IDEOGRAPH TEN +3039 ; [.FB40.0020.0004.5344][.D344.0000.0000.5344] # HANGZHOU NUMERAL TWENTY +303A ; [.FB40.0020.0004.5345][.D345.0000.0000.5345] # HANGZHOU NUMERAL THIRTY +2F82C ; [.FB40.0020.0002.5349][.D349.0000.0000.5349] # CJK COMPATIBILITY IDEOGRAPH-2F82C +FA35 ; [.FB40.0020.0002.5351][.D351.0000.0000.5351] # CJK COMPATIBILITY IDEOGRAPH-FA35 +2F82D ; [.FB40.0020.0002.5351][.D351.0000.0000.5351] # CJK COMPATIBILITY IDEOGRAPH-2F82D +323F ; [*02FB.0020.0004.323F][.FB40.0020.0004.5354][.D354.0000.0000.5354][*02FC.0020.001F.323F] # PARENTHESIZED IDEOGRAPH ALLIANCE +32AF ; [.FB40.0020.0006.5354][.D354.0000.0000.5354] # CIRCLED IDEOGRAPH ALLIANCE +2F82E ; [.FB40.0020.0002.535A][.D35A.0000.0000.535A] # CJK COMPATIBILITY IDEOGRAPH-2F82E +2F18 ; [.FB40.0020.0004.535C][.D35C.0000.0000.535C] # KANGXI RADICAL DIVINATION +2E8A ; [.FB40.0020.0004.535C][.D35C.0000.0000.535C][.0000.0139.001F.2E8A] # CJK RADICAL DIVINATION +2F19 ; [.FB40.0020.0004.5369][.D369.0000.0000.5369] # KANGXI RADICAL SEAL +2E8B ; [.FB40.0020.0004.5369][.D369.0000.0000.5369][.0000.0139.001F.2E8B] # CJK RADICAL SEAL +329E ; [.FB40.0020.0006.5370][.D370.0000.0000.5370] # CIRCLED IDEOGRAPH PRINT +2F82F ; [.FB40.0020.0002.5373][.D373.0000.0000.5373] # CJK COMPATIBILITY IDEOGRAPH-2F82F +F91C ; [.FB40.0020.0002.5375][.D375.0000.0000.5375] # CJK COMPATIBILITY IDEOGRAPH-F91C +2F830 ; [.FB40.0020.0002.537D][.D37D.0000.0000.537D] # CJK COMPATIBILITY IDEOGRAPH-2F830 +2F831 ; [.FB40.0020.0002.537F][.D37F.0000.0000.537F] # CJK COMPATIBILITY IDEOGRAPH-2F831 +2F832 ; [.FB40.0020.0002.537F][.D37F.0000.0000.537F] # CJK COMPATIBILITY IDEOGRAPH-2F832 +2F833 ; [.FB40.0020.0002.537F][.D37F.0000.0000.537F] # CJK COMPATIBILITY IDEOGRAPH-2F833 +2F1A ; [.FB40.0020.0004.5382][.D382.0000.0000.5382] # KANGXI RADICAL CLIFF +2E81 ; [.FB40.0020.0004.5382][.D382.0000.0000.5382][.0000.0139.001F.2E81] # CJK RADICAL CLIFF +2F1B ; [.FB40.0020.0004.53B6][.D3B6.0000.0000.53B6] # KANGXI RADICAL PRIVATE +F96B ; [.FB40.0020.0002.53C3][.D3C3.0000.0000.53C3] # CJK COMPATIBILITY IDEOGRAPH-F96B +2F1C ; [.FB40.0020.0004.53C8][.D3C8.0000.0000.53C8] # KANGXI RADICAL AGAIN +2F836 ; [.FB40.0020.0002.53CA][.D3CA.0000.0000.53CA] # CJK COMPATIBILITY IDEOGRAPH-2F836 +1F212 ; [.FB40.0020.001C.53CC][.D3CC.0000.0000.53CC] # SQUARED CJK UNIFIED IDEOGRAPH-53CC +2F837 ; [.FB40.0020.0002.53DF][.D3DF.0000.0000.53DF] # CJK COMPATIBILITY IDEOGRAPH-2F837 +2F1D ; [.FB40.0020.0004.53E3][.D3E3.0000.0000.53E3] # KANGXI RADICAL MOUTH +F906 ; [.FB40.0020.0002.53E5][.D3E5.0000.0000.53E5] # CJK COMPATIBILITY IDEOGRAPH-F906 +2F839 ; [.FB40.0020.0002.53EB][.D3EB.0000.0000.53EB] # CJK COMPATIBILITY IDEOGRAPH-2F839 +1F251 ; [.FB40.0020.0006.53EF][.D3EF.0000.0000.53EF] # CIRCLED IDEOGRAPH ACCEPT +2F83A ; [.FB40.0020.0002.53F1][.D3F1.0000.0000.53F1] # CJK COMPATIBILITY IDEOGRAPH-2F83A +32A8 ; [.FB40.0020.0006.53F3][.D3F3.0000.0000.53F3] # CIRCLED IDEOGRAPH RIGHT +1F22E ; [.FB40.0020.001C.53F3][.D3F3.0000.0000.53F3] # SQUARED CJK UNIFIED IDEOGRAPH-53F3 +2F83B ; [.FB40.0020.0002.5406][.D406.0000.0000.5406] # CJK COMPATIBILITY IDEOGRAPH-2F83B +1F234 ; [.FB40.0020.001C.5408][.D408.0000.0000.5408] # SQUARED CJK UNIFIED IDEOGRAPH-5408 +3234 ; [*02FB.0020.0004.3234][.FB40.0020.0004.540D][.D40D.0000.0000.540D][*02FC.0020.001F.3234] # PARENTHESIZED IDEOGRAPH NAME +3294 ; [.FB40.0020.0006.540D][.D40D.0000.0000.540D] # CIRCLED IDEOGRAPH NAME +F9DE ; [.FB40.0020.0002.540F][.D40F.0000.0000.540F] # CJK COMPATIBILITY IDEOGRAPH-F9DE +F9ED ; [.FB40.0020.0002.541D][.D41D.0000.0000.541D] # CJK COMPATIBILITY IDEOGRAPH-F9ED +2F83D ; [.FB40.0020.0002.5438][.D438.0000.0000.5438] # CJK COMPATIBILITY IDEOGRAPH-2F83D +1F225 ; [.FB40.0020.001C.5439][.D439.0000.0000.5439] # SQUARED CJK UNIFIED IDEOGRAPH-5439 +F980 ; [.FB40.0020.0002.5442][.D442.0000.0000.5442] # CJK COMPATIBILITY IDEOGRAPH-F980 +2F83E ; [.FB40.0020.0002.5448][.D448.0000.0000.5448] # CJK COMPATIBILITY IDEOGRAPH-2F83E +2F83F ; [.FB40.0020.0002.5468][.D468.0000.0000.5468] # CJK COMPATIBILITY IDEOGRAPH-2F83F +323A ; [*02FB.0020.0004.323A][.FB40.0020.0004.547C][.D47C.0000.0000.547C][*02FC.0020.001F.323A] # PARENTHESIZED IDEOGRAPH CALL +2F83C ; [.FB40.0020.0002.549E][.D49E.0000.0000.549E] # CJK COMPATIBILITY IDEOGRAPH-2F83C +2F840 ; [.FB40.0020.0002.54A2][.D4A2.0000.0000.54A2] # CJK COMPATIBILITY IDEOGRAPH-2F840 +F99E ; [.FB40.0020.0002.54BD][.D4BD.0000.0000.54BD] # CJK COMPATIBILITY IDEOGRAPH-F99E +2F841 ; [.FB40.0020.0002.54F6][.D4F6.0000.0000.54F6] # CJK COMPATIBILITY IDEOGRAPH-2F841 +2F842 ; [.FB40.0020.0002.5510][.D510.0000.0000.5510] # CJK COMPATIBILITY IDEOGRAPH-2F842 +3244 ; [.FB40.0020.0006.554F][.D54F.0000.0000.554F] # CIRCLED IDEOGRAPH QUESTION +2F843 ; [.FB40.0020.0002.5553][.D553.0000.0000.5553] # CJK COMPATIBILITY IDEOGRAPH-2F843 +FA79 ; [.FB40.0020.0002.5555][.D555.0000.0000.5555] # CJK COMPATIBILITY IDEOGRAPH-FA79 +2F844 ; [.FB40.0020.0002.5563][.D563.0000.0000.5563] # CJK COMPATIBILITY IDEOGRAPH-2F844 +2F845 ; [.FB40.0020.0002.5584][.D584.0000.0000.5584] # CJK COMPATIBILITY IDEOGRAPH-2F845 +2F846 ; [.FB40.0020.0002.5584][.D584.0000.0000.5584] # CJK COMPATIBILITY IDEOGRAPH-2F846 +F90B ; [.FB40.0020.0002.5587][.D587.0000.0000.5587] # CJK COMPATIBILITY IDEOGRAPH-F90B +FA7A ; [.FB40.0020.0002.5599][.D599.0000.0000.5599] # CJK COMPATIBILITY IDEOGRAPH-FA7A +2F847 ; [.FB40.0020.0002.5599][.D599.0000.0000.5599] # CJK COMPATIBILITY IDEOGRAPH-2F847 +FA36 ; [.FB40.0020.0002.559D][.D59D.0000.0000.559D] # CJK COMPATIBILITY IDEOGRAPH-FA36 +FA78 ; [.FB40.0020.0002.559D][.D59D.0000.0000.559D] # CJK COMPATIBILITY IDEOGRAPH-FA78 +2F848 ; [.FB40.0020.0002.55AB][.D5AB.0000.0000.55AB] # CJK COMPATIBILITY IDEOGRAPH-2F848 +2F849 ; [.FB40.0020.0002.55B3][.D5B3.0000.0000.55B3] # CJK COMPATIBILITY IDEOGRAPH-2F849 +1F23A ; [.FB40.0020.001C.55B6][.D5B6.0000.0000.55B6] # SQUARED CJK UNIFIED IDEOGRAPH-55B6 +FA0D ; [.FB40.0020.0002.55C0][.D5C0.0000.0000.55C0] # CJK COMPATIBILITY IDEOGRAPH-FA0D +2F84A ; [.FB40.0020.0002.55C2][.D5C2.0000.0000.55C2] # CJK COMPATIBILITY IDEOGRAPH-2F84A +FA7B ; [.FB40.0020.0002.55E2][.D5E2.0000.0000.55E2] # CJK COMPATIBILITY IDEOGRAPH-FA7B +FA37 ; [.FB40.0020.0002.5606][.D606.0000.0000.5606] # CJK COMPATIBILITY IDEOGRAPH-FA37 +2F84C ; [.FB40.0020.0002.5606][.D606.0000.0000.5606] # CJK COMPATIBILITY IDEOGRAPH-2F84C +2F84E ; [.FB40.0020.0002.5651][.D651.0000.0000.5651] # CJK COMPATIBILITY IDEOGRAPH-2F84E +FA38 ; [.FB40.0020.0002.5668][.D668.0000.0000.5668] # CJK COMPATIBILITY IDEOGRAPH-FA38 +2F84F ; [.FB40.0020.0002.5674][.D674.0000.0000.5674] # CJK COMPATIBILITY IDEOGRAPH-2F84F +2F1E ; [.FB40.0020.0004.56D7][.D6D7.0000.0000.56D7] # KANGXI RADICAL ENCLOSURE +3223 ; [*02FB.0020.0004.3223][.FB40.0020.0004.56DB][.D6DB.0000.0000.56DB][*02FC.0020.001F.3223] # PARENTHESIZED IDEOGRAPH FOUR +3283 ; [.FB40.0020.0006.56DB][.D6DB.0000.0000.56DB] # CIRCLED IDEOGRAPH FOUR +3195 ; [.FB40.0020.0014.56DB][.D6DB.0000.0000.56DB] # IDEOGRAPHIC ANNOTATION FOUR MARK +F9A9 ; [.FB40.0020.0002.56F9][.D6F9.0000.0000.56F9] # CJK COMPATIBILITY IDEOGRAPH-F9A9 +2F84B ; [.FB40.0020.0002.5716][.D716.0000.0000.5716] # CJK COMPATIBILITY IDEOGRAPH-2F84B +2F84D ; [.FB40.0020.0002.5717][.D717.0000.0000.5717] # CJK COMPATIBILITY IDEOGRAPH-2F84D +2F1F ; [.FB40.0020.0004.571F][.D71F.0000.0000.571F] # KANGXI RADICAL EARTH +322F ; [*02FB.0020.0004.322F][.FB40.0020.0004.571F][.D71F.0000.0000.571F][*02FC.0020.001F.322F] # PARENTHESIZED IDEOGRAPH EARTH +328F ; [.FB40.0020.0006.571F][.D71F.0000.0000.571F] # CIRCLED IDEOGRAPH EARTH +319E ; [.FB40.0020.0014.5730][.D730.0000.0000.5730] # IDEOGRAPHIC ANNOTATION EARTH MARK +2F855 ; [.FB40.0020.0002.578B][.D78B.0000.0000.578B] # CJK COMPATIBILITY IDEOGRAPH-2F855 +2F852 ; [.FB40.0020.0002.57CE][.D7CE.0000.0000.57CE] # CJK COMPATIBILITY IDEOGRAPH-2F852 +2F853 ; [.FB40.0020.0002.57F4][.D7F4.0000.0000.57F4] # CJK COMPATIBILITY IDEOGRAPH-2F853 +2F854 ; [.FB40.0020.0002.580D][.D80D.0000.0000.580D] # CJK COMPATIBILITY IDEOGRAPH-2F854 +2F857 ; [.FB40.0020.0002.5831][.D831.0000.0000.5831] # CJK COMPATIBILITY IDEOGRAPH-2F857 +2F856 ; [.FB40.0020.0002.5832][.D832.0000.0000.5832] # CJK COMPATIBILITY IDEOGRAPH-2F856 +FA39 ; [.FB40.0020.0002.5840][.D840.0000.0000.5840] # CJK COMPATIBILITY IDEOGRAPH-FA39 +FA10 ; [.FB40.0020.0002.585A][.D85A.0000.0000.585A] # CJK COMPATIBILITY IDEOGRAPH-FA10 +FA7C ; [.FB40.0020.0002.585A][.D85A.0000.0000.585A] # CJK COMPATIBILITY IDEOGRAPH-FA7C +F96C ; [.FB40.0020.0002.585E][.D85E.0000.0000.585E] # CJK COMPATIBILITY IDEOGRAPH-F96C +FA3A ; [.FB40.0020.0002.58A8][.D8A8.0000.0000.58A8] # CJK COMPATIBILITY IDEOGRAPH-FA3A +2F858 ; [.FB40.0020.0002.58AC][.D8AC.0000.0000.58AC] # CJK COMPATIBILITY IDEOGRAPH-2F858 +FA7D ; [.FB40.0020.0002.58B3][.D8B3.0000.0000.58B3] # CJK COMPATIBILITY IDEOGRAPH-FA7D +F94A ; [.FB40.0020.0002.58D8][.D8D8.0000.0000.58D8] # CJK COMPATIBILITY IDEOGRAPH-F94A +F942 ; [.FB40.0020.0002.58DF][.D8DF.0000.0000.58DF] # CJK COMPATIBILITY IDEOGRAPH-F942 +2F20 ; [.FB40.0020.0004.58EB][.D8EB.0000.0000.58EB] # KANGXI RADICAL SCHOLAR +2F851 ; [.FB40.0020.0002.58EE][.D8EE.0000.0000.58EE] # CJK COMPATIBILITY IDEOGRAPH-2F851 +1F224 ; [.FB40.0020.001C.58F0][.D8F0.0000.0000.58F0] # SQUARED CJK UNIFIED IDEOGRAPH-58F0 +2F85A ; [.FB40.0020.0002.58F2][.D8F2.0000.0000.58F2] # CJK COMPATIBILITY IDEOGRAPH-2F85A +2F85B ; [.FB40.0020.0002.58F7][.D8F7.0000.0000.58F7] # CJK COMPATIBILITY IDEOGRAPH-2F85B +2F21 ; [.FB40.0020.0004.5902][.D902.0000.0000.5902] # KANGXI RADICAL GO +2F85C ; [.FB40.0020.0002.5906][.D906.0000.0000.5906] # CJK COMPATIBILITY IDEOGRAPH-2F85C +2F22 ; [.FB40.0020.0004.590A][.D90A.0000.0000.590A] # KANGXI RADICAL GO SLOWLY +2F23 ; [.FB40.0020.0004.5915][.D915.0000.0000.5915] # KANGXI RADICAL EVENING +2F85D ; [.FB40.0020.0002.591A][.D91A.0000.0000.591A] # CJK COMPATIBILITY IDEOGRAPH-2F85D +1F215 ; [.FB40.0020.001C.591A][.D91A.0000.0000.591A] # SQUARED CJK UNIFIED IDEOGRAPH-591A +32B0 ; [.FB40.0020.0006.591C][.D91C.0000.0000.591C] # CIRCLED IDEOGRAPH NIGHT +2F85E ; [.FB40.0020.0002.5922][.D922.0000.0000.5922] # CJK COMPATIBILITY IDEOGRAPH-2F85E +2F24 ; [.FB40.0020.0004.5927][.D927.0000.0000.5927] # KANGXI RADICAL BIG +337D ; [.FB40.0020.001C.5927][.D927.0000.0000.5927][.FB40.0020.001F.6B63][.EB63.0000.0000.6B63] # SQUARE ERA NAME TAISYOU +319D ; [.FB40.0020.0014.5929][.D929.0000.0000.5929] # IDEOGRAPHIC ANNOTATION HEAVEN MARK +1F217 ; [.FB40.0020.001C.5929][.D929.0000.0000.5929] # SQUARED CJK UNIFIED IDEOGRAPH-5929 +FA7E ; [.FB40.0020.0002.5944][.D944.0000.0000.5944] # CJK COMPATIBILITY IDEOGRAPH-FA7E +F90C ; [.FB40.0020.0002.5948][.D948.0000.0000.5948] # CJK COMPATIBILITY IDEOGRAPH-F90C +F909 ; [.FB40.0020.0002.5951][.D951.0000.0000.5951] # CJK COMPATIBILITY IDEOGRAPH-F909 +FA7F ; [.FB40.0020.0002.5954][.D954.0000.0000.5954] # CJK COMPATIBILITY IDEOGRAPH-FA7F +2F85F ; [.FB40.0020.0002.5962][.D962.0000.0000.5962] # CJK COMPATIBILITY IDEOGRAPH-2F85F +F981 ; [.FB40.0020.0002.5973][.D973.0000.0000.5973] # CJK COMPATIBILITY IDEOGRAPH-F981 +2F25 ; [.FB40.0020.0004.5973][.D973.0000.0000.5973] # KANGXI RADICAL WOMAN +329B ; [.FB40.0020.0006.5973][.D973.0000.0000.5973] # CIRCLED IDEOGRAPH FEMALE +2F865 ; [.FB40.0020.0002.59D8][.D9D8.0000.0000.59D8] # CJK COMPATIBILITY IDEOGRAPH-2F865 +2F862 ; [.FB40.0020.0002.59EC][.D9EC.0000.0000.59EC] # CJK COMPATIBILITY IDEOGRAPH-2F862 +2F863 ; [.FB40.0020.0002.5A1B][.DA1B.0000.0000.5A1B] # CJK COMPATIBILITY IDEOGRAPH-2F863 +2F864 ; [.FB40.0020.0002.5A27][.DA27.0000.0000.5A27] # CJK COMPATIBILITY IDEOGRAPH-2F864 +FA80 ; [.FB40.0020.0002.5A62][.DA62.0000.0000.5A62] # CJK COMPATIBILITY IDEOGRAPH-FA80 +2F866 ; [.FB40.0020.0002.5A66][.DA66.0000.0000.5A66] # CJK COMPATIBILITY IDEOGRAPH-2F866 +2F986 ; [.FB40.0020.0002.5AB5][.DAB5.0000.0000.5AB5] # CJK COMPATIBILITY IDEOGRAPH-2F986 +2F869 ; [.FB40.0020.0002.5B08][.DB08.0000.0000.5B08] # CJK COMPATIBILITY IDEOGRAPH-2F869 +FA81 ; [.FB40.0020.0002.5B28][.DB28.0000.0000.5B28] # CJK COMPATIBILITY IDEOGRAPH-FA81 +2F86A ; [.FB40.0020.0002.5B3E][.DB3E.0000.0000.5B3E] # CJK COMPATIBILITY IDEOGRAPH-2F86A +2F86B ; [.FB40.0020.0002.5B3E][.DB3E.0000.0000.5B3E] # CJK COMPATIBILITY IDEOGRAPH-2F86B +2F26 ; [.FB40.0020.0004.5B50][.DB50.0000.0000.5B50] # KANGXI RADICAL CHILD +1F211 ; [.FB40.0020.001C.5B57][.DB57.0000.0000.5B57] # SQUARED CJK UNIFIED IDEOGRAPH-5B57 +323B ; [*02FB.0020.0004.323B][.FB40.0020.0004.5B66][.DB66.0000.0000.5B66][*02FC.0020.001F.323B] # PARENTHESIZED IDEOGRAPH STUDY +32AB ; [.FB40.0020.0006.5B66][.DB66.0000.0000.5B66] # CIRCLED IDEOGRAPH STUDY +2F27 ; [.FB40.0020.0004.5B80][.DB80.0000.0000.5B80] # KANGXI RADICAL ROOF +FA04 ; [.FB40.0020.0002.5B85][.DB85.0000.0000.5B85] # CJK COMPATIBILITY IDEOGRAPH-FA04 +1F243 ; [*0359.0020.0004.1F243][.FB40.0020.0004.5B89][.DB89.0000.0000.5B89][*035A.0020.001F.1F243] # TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-5B89 +32AA ; [.FB40.0020.0006.5B97][.DB97.0000.0000.5B97] # CIRCLED IDEOGRAPH RELIGION +2F86D ; [.FB40.0020.0002.5BC3][.DBC3.0000.0000.5BC3] # CJK COMPATIBILITY IDEOGRAPH-2F86D +2F86E ; [.FB40.0020.0002.5BD8][.DBD8.0000.0000.5BD8] # CJK COMPATIBILITY IDEOGRAPH-2F86E +F95F ; [.FB40.0020.0002.5BE7][.DBE7.0000.0000.5BE7] # CJK COMPATIBILITY IDEOGRAPH-F95F +F9AA ; [.FB40.0020.0002.5BE7][.DBE7.0000.0000.5BE7] # CJK COMPATIBILITY IDEOGRAPH-F9AA +2F86F ; [.FB40.0020.0002.5BE7][.DBE7.0000.0000.5BE7] # CJK COMPATIBILITY IDEOGRAPH-2F86F +F9BC ; [.FB40.0020.0002.5BEE][.DBEE.0000.0000.5BEE] # CJK COMPATIBILITY IDEOGRAPH-F9BC +2F870 ; [.FB40.0020.0002.5BF3][.DBF3.0000.0000.5BF3] # CJK COMPATIBILITY IDEOGRAPH-2F870 +2F28 ; [.FB40.0020.0004.5BF8][.DBF8.0000.0000.5BF8] # KANGXI RADICAL INCH +2F872 ; [.FB40.0020.0002.5BFF][.DBFF.0000.0000.5BFF] # CJK COMPATIBILITY IDEOGRAPH-2F872 +2F873 ; [.FB40.0020.0002.5C06][.DC06.0000.0000.5C06] # CJK COMPATIBILITY IDEOGRAPH-2F873 +2F29 ; [.FB40.0020.0004.5C0F][.DC0F.0000.0000.5C0F] # KANGXI RADICAL SMALL +2E8C ; [.FB40.0020.0004.5C0F][.DC0F.0000.0000.5C0F][.0000.0139.001F.2E8C] # CJK RADICAL SMALL ONE +2E8D ; [.FB40.0020.0004.5C0F][.DC0F.0000.0000.5C0F][.0000.013A.001F.2E8D] # CJK RADICAL SMALL TWO +2F875 ; [.FB40.0020.0002.5C22][.DC22.0000.0000.5C22] # CJK COMPATIBILITY IDEOGRAPH-2F875 +2E90 ; [.FB40.0020.0004.5C22][.DC22.0000.0000.5C22] # CJK RADICAL LAME THREE +2F2A ; [.FB40.0020.0004.5C22][.DC22.0000.0000.5C22] # KANGXI RADICAL LAME +2E8E ; [.FB40.0020.0004.5C22][.DC22.0000.0000.5C22][.0000.0139.001F.2E8E] # CJK RADICAL LAME ONE +2E8F ; [.FB40.0020.0004.5C23][.DC23.0000.0000.5C23] # CJK RADICAL LAME TWO +2E91 ; [.FB40.0020.0004.5C23][.DC23.0000.0000.5C23][.0000.0139.001F.2E91] # CJK RADICAL LAME FOUR +2F2B ; [.FB40.0020.0004.5C38][.DC38.0000.0000.5C38] # KANGXI RADICAL CORPSE +F9BD ; [.FB40.0020.0002.5C3F][.DC3F.0000.0000.5C3F] # CJK COMPATIBILITY IDEOGRAPH-F9BD +2F877 ; [.FB40.0020.0002.5C60][.DC60.0000.0000.5C60] # CJK COMPATIBILITY IDEOGRAPH-2F877 +F94B ; [.FB40.0020.0002.5C62][.DC62.0000.0000.5C62] # CJK COMPATIBILITY IDEOGRAPH-F94B +FA3B ; [.FB40.0020.0002.5C64][.DC64.0000.0000.5C64] # CJK COMPATIBILITY IDEOGRAPH-FA3B +F9DF ; [.FB40.0020.0002.5C65][.DC65.0000.0000.5C65] # CJK COMPATIBILITY IDEOGRAPH-F9DF +FA3C ; [.FB40.0020.0002.5C6E][.DC6E.0000.0000.5C6E] # CJK COMPATIBILITY IDEOGRAPH-FA3C +2F878 ; [.FB40.0020.0002.5C6E][.DC6E.0000.0000.5C6E] # CJK COMPATIBILITY IDEOGRAPH-2F878 +2F2C ; [.FB40.0020.0004.5C6E][.DC6E.0000.0000.5C6E] # KANGXI RADICAL SPROUT +2F2D ; [.FB40.0020.0004.5C71][.DC71.0000.0000.5C71] # KANGXI RADICAL MOUNTAIN +2F87A ; [.FB40.0020.0002.5C8D][.DC8D.0000.0000.5C8D] # CJK COMPATIBILITY IDEOGRAPH-2F87A +2F879 ; [.FB40.0020.0002.5CC0][.DCC0.0000.0000.5CC0] # CJK COMPATIBILITY IDEOGRAPH-2F879 +F9D5 ; [.FB40.0020.0002.5D19][.DD19.0000.0000.5D19] # CJK COMPATIBILITY IDEOGRAPH-F9D5 +2F87C ; [.FB40.0020.0002.5D43][.DD43.0000.0000.5D43] # CJK COMPATIBILITY IDEOGRAPH-2F87C +F921 ; [.FB40.0020.0002.5D50][.DD50.0000.0000.5D50] # CJK COMPATIBILITY IDEOGRAPH-F921 +2F87F ; [.FB40.0020.0002.5D6B][.DD6B.0000.0000.5D6B] # CJK COMPATIBILITY IDEOGRAPH-2F87F +2F87E ; [.FB40.0020.0002.5D6E][.DD6E.0000.0000.5D6E] # CJK COMPATIBILITY IDEOGRAPH-2F87E +2F880 ; [.FB40.0020.0002.5D7C][.DD7C.0000.0000.5D7C] # CJK COMPATIBILITY IDEOGRAPH-2F880 +2F9F4 ; [.FB40.0020.0002.5DB2][.DDB2.0000.0000.5DB2] # CJK COMPATIBILITY IDEOGRAPH-2F9F4 +F9AB ; [.FB40.0020.0002.5DBA][.DDBA.0000.0000.5DBA] # CJK COMPATIBILITY IDEOGRAPH-F9AB +2F2E ; [.FB40.0020.0004.5DDB][.DDDB.0000.0000.5DDB] # KANGXI RADICAL RIVER +2F881 ; [.FB40.0020.0002.5DE1][.DDE1.0000.0000.5DE1] # CJK COMPATIBILITY IDEOGRAPH-2F881 +2F882 ; [.FB40.0020.0002.5DE2][.DDE2.0000.0000.5DE2] # CJK COMPATIBILITY IDEOGRAPH-2F882 +2F2F ; [.FB40.0020.0004.5DE5][.DDE5.0000.0000.5DE5] # KANGXI RADICAL WORK +32A7 ; [.FB40.0020.0006.5DE6][.DDE6.0000.0000.5DE6] # CIRCLED IDEOGRAPH LEFT +1F22C ; [.FB40.0020.001C.5DE6][.DDE6.0000.0000.5DE6] # SQUARED CJK UNIFIED IDEOGRAPH-5DE6 +2F30 ; [.FB40.0020.0004.5DF1][.DDF1.0000.0000.5DF1] # KANGXI RADICAL ONESELF +2E92 ; [.FB40.0020.0004.5DF3][.DDF3.0000.0000.5DF3] # CJK RADICAL SNAKE +2F884 ; [.FB40.0020.0002.5DFD][.DDFD.0000.0000.5DFD] # CJK COMPATIBILITY IDEOGRAPH-2F884 +2F31 ; [.FB40.0020.0004.5DFE][.DDFE.0000.0000.5DFE] # KANGXI RADICAL TURBAN +2F885 ; [.FB40.0020.0002.5E28][.DE28.0000.0000.5E28] # CJK COMPATIBILITY IDEOGRAPH-2F885 +2F886 ; [.FB40.0020.0002.5E3D][.DE3D.0000.0000.5E3D] # CJK COMPATIBILITY IDEOGRAPH-2F886 +2F887 ; [.FB40.0020.0002.5E69][.DE69.0000.0000.5E69] # CJK COMPATIBILITY IDEOGRAPH-2F887 +2F32 ; [.FB40.0020.0004.5E72][.DE72.0000.0000.5E72] # KANGXI RADICAL DRY +337B ; [.FB40.0020.001C.5E73][.DE73.0000.0000.5E73][.FB40.0020.001F.6210][.E210.0000.0000.6210] # SQUARE ERA NAME HEISEI +F98E ; [.FB40.0020.0002.5E74][.DE74.0000.0000.5E74] # CJK COMPATIBILITY IDEOGRAPH-F98E +2E93 ; [.FB40.0020.0004.5E7A][.DE7A.0000.0000.5E7A] # CJK RADICAL THREAD +2F33 ; [.FB40.0020.0004.5E7A][.DE7A.0000.0000.5E7A] # KANGXI RADICAL SHORT THREAD +3245 ; [.FB40.0020.0006.5E7C][.DE7C.0000.0000.5E7C] # CIRCLED IDEOGRAPH KINDERGARTEN +2F34 ; [.FB40.0020.0004.5E7F][.DE7F.0000.0000.5E7F] # KANGXI RADICAL DOTTED CLIFF +FA01 ; [.FB40.0020.0002.5EA6][.DEA6.0000.0000.5EA6] # CJK COMPATIBILITY IDEOGRAPH-FA01 +2F88B ; [.FB40.0020.0002.5EB0][.DEB0.0000.0000.5EB0] # CJK COMPATIBILITY IDEOGRAPH-2F88B +2F88C ; [.FB40.0020.0002.5EB3][.DEB3.0000.0000.5EB3] # CJK COMPATIBILITY IDEOGRAPH-2F88C +2F88D ; [.FB40.0020.0002.5EB6][.DEB6.0000.0000.5EB6] # CJK COMPATIBILITY IDEOGRAPH-2F88D +F9A2 ; [.FB40.0020.0002.5EC9][.DEC9.0000.0000.5EC9] # CJK COMPATIBILITY IDEOGRAPH-F9A2 +F928 ; [.FB40.0020.0002.5ECA][.DECA.0000.0000.5ECA] # CJK COMPATIBILITY IDEOGRAPH-F928 +2F88E ; [.FB40.0020.0002.5ECA][.DECA.0000.0000.5ECA] # CJK COMPATIBILITY IDEOGRAPH-2F88E +FA82 ; [.FB40.0020.0002.5ED2][.DED2.0000.0000.5ED2] # CJK COMPATIBILITY IDEOGRAPH-FA82 +FA0B ; [.FB40.0020.0002.5ED3][.DED3.0000.0000.5ED3] # CJK COMPATIBILITY IDEOGRAPH-FA0B +FA83 ; [.FB40.0020.0002.5ED9][.DED9.0000.0000.5ED9] # CJK COMPATIBILITY IDEOGRAPH-FA83 +F982 ; [.FB40.0020.0002.5EEC][.DEEC.0000.0000.5EEC] # CJK COMPATIBILITY IDEOGRAPH-F982 +2F35 ; [.FB40.0020.0004.5EF4][.DEF4.0000.0000.5EF4] # KANGXI RADICAL LONG STRIDE +2F890 ; [.FB40.0020.0002.5EFE][.DEFE.0000.0000.5EFE] # CJK COMPATIBILITY IDEOGRAPH-2F890 +2F36 ; [.FB40.0020.0004.5EFE][.DEFE.0000.0000.5EFE] # KANGXI RADICAL TWO HANDS +F943 ; [.FB40.0020.0002.5F04][.DF04.0000.0000.5F04] # CJK COMPATIBILITY IDEOGRAPH-F943 +2F37 ; [.FB40.0020.0004.5F0B][.DF0B.0000.0000.5F0B] # KANGXI RADICAL SHOOT +2F38 ; [.FB40.0020.0004.5F13][.DF13.0000.0000.5F13] # KANGXI RADICAL BOW +2F894 ; [.FB40.0020.0002.5F22][.DF22.0000.0000.5F22] # CJK COMPATIBILITY IDEOGRAPH-2F894 +2F895 ; [.FB40.0020.0002.5F22][.DF22.0000.0000.5F22] # CJK COMPATIBILITY IDEOGRAPH-2F895 +2F39 ; [.FB40.0020.0004.5F50][.DF50.0000.0000.5F50] # KANGXI RADICAL SNOUT +2E95 ; [.FB40.0020.0004.5F50][.DF50.0000.0000.5F50][.0000.0139.001F.2E95] # CJK RADICAL SNOUT TWO +2E94 ; [.FB40.0020.0004.5F51][.DF51.0000.0000.5F51] # CJK RADICAL SNOUT ONE +2F874 ; [.FB40.0020.0002.5F53][.DF53.0000.0000.5F53] # CJK COMPATIBILITY IDEOGRAPH-2F874 +2F3A ; [.FB40.0020.0004.5F61][.DF61.0000.0000.5F61] # KANGXI RADICAL BRISTLE +2F899 ; [.FB40.0020.0002.5F62][.DF62.0000.0000.5F62] # CJK COMPATIBILITY IDEOGRAPH-2F899 +FA84 ; [.FB40.0020.0002.5F69][.DF69.0000.0000.5F69] # CJK COMPATIBILITY IDEOGRAPH-FA84 +2F89A ; [.FB40.0020.0002.5F6B][.DF6B.0000.0000.5F6B] # CJK COMPATIBILITY IDEOGRAPH-2F89A +2F3B ; [.FB40.0020.0004.5F73][.DF73.0000.0000.5F73] # KANGXI RADICAL STEP +F9D8 ; [.FB40.0020.0002.5F8B][.DF8B.0000.0000.5F8B] # CJK COMPATIBILITY IDEOGRAPH-F9D8 +1F21D ; [.FB40.0020.001C.5F8C][.DF8C.0000.0000.5F8C] # SQUARED CJK UNIFIED IDEOGRAPH-5F8C +1F250 ; [.FB40.0020.0006.5F97][.DF97.0000.0000.5F97] # CIRCLED IDEOGRAPH ADVANTAGE +2F89C ; [.FB40.0020.0002.5F9A][.DF9A.0000.0000.5F9A] # CJK COMPATIBILITY IDEOGRAPH-2F89C +F966 ; [.FB40.0020.0002.5FA9][.DFA9.0000.0000.5FA9] # CJK COMPATIBILITY IDEOGRAPH-F966 +FA85 ; [.FB40.0020.0002.5FAD][.DFAD.0000.0000.5FAD] # CJK COMPATIBILITY IDEOGRAPH-FA85 +2F3C ; [.FB40.0020.0004.5FC3][.DFC3.0000.0000.5FC3] # KANGXI RADICAL HEART +2E97 ; [.FB40.0020.0004.5FC3][.DFC3.0000.0000.5FC3][.0000.0139.001F.2E97] # CJK RADICAL HEART TWO +2E96 ; [.FB40.0020.0004.5FC4][.DFC4.0000.0000.5FC4] # CJK RADICAL HEART ONE +2F89D ; [.FB40.0020.0002.5FCD][.DFCD.0000.0000.5FCD] # CJK COMPATIBILITY IDEOGRAPH-2F89D +2F89E ; [.FB40.0020.0002.5FD7][.DFD7.0000.0000.5FD7] # CJK COMPATIBILITY IDEOGRAPH-2F89E +F9A3 ; [.FB40.0020.0002.5FF5][.DFF5.0000.0000.5FF5] # CJK COMPATIBILITY IDEOGRAPH-F9A3 +2F89F ; [.FB40.0020.0002.5FF9][.DFF9.0000.0000.5FF9] # CJK COMPATIBILITY IDEOGRAPH-2F89F +F960 ; [.FB40.0020.0002.6012][.E012.0000.0000.6012] # CJK COMPATIBILITY IDEOGRAPH-F960 +F9AC ; [.FB40.0020.0002.601C][.E01C.0000.0000.601C] # CJK COMPATIBILITY IDEOGRAPH-F9AC +FA6B ; [.FB40.0020.0002.6075][.E075.0000.0000.6075] # CJK COMPATIBILITY IDEOGRAPH-FA6B +2F8A0 ; [.FB40.0020.0002.6081][.E081.0000.0000.6081] # CJK COMPATIBILITY IDEOGRAPH-2F8A0 +FA3D ; [.FB40.0020.0002.6094][.E094.0000.0000.6094] # CJK COMPATIBILITY IDEOGRAPH-FA3D +2F8A3 ; [.FB40.0020.0002.6094][.E094.0000.0000.6094] # CJK COMPATIBILITY IDEOGRAPH-2F8A3 +2F8A5 ; [.FB40.0020.0002.60C7][.E0C7.0000.0000.60C7] # CJK COMPATIBILITY IDEOGRAPH-2F8A5 +FA86 ; [.FB40.0020.0002.60D8][.E0D8.0000.0000.60D8] # CJK COMPATIBILITY IDEOGRAPH-FA86 +F9B9 ; [.FB40.0020.0002.60E1][.E0E1.0000.0000.60E1] # CJK COMPATIBILITY IDEOGRAPH-F9B9 +FA88 ; [.FB40.0020.0002.6108][.E108.0000.0000.6108] # CJK COMPATIBILITY IDEOGRAPH-FA88 +F9D9 ; [.FB40.0020.0002.6144][.E144.0000.0000.6144] # CJK COMPATIBILITY IDEOGRAPH-F9D9 +2F8A6 ; [.FB40.0020.0002.6148][.E148.0000.0000.6148] # CJK COMPATIBILITY IDEOGRAPH-2F8A6 +2F8A7 ; [.FB40.0020.0002.614C][.E14C.0000.0000.614C] # CJK COMPATIBILITY IDEOGRAPH-2F8A7 +2F8A9 ; [.FB40.0020.0002.614C][.E14C.0000.0000.614C] # CJK COMPATIBILITY IDEOGRAPH-2F8A9 +FA87 ; [.FB40.0020.0002.614E][.E14E.0000.0000.614E] # CJK COMPATIBILITY IDEOGRAPH-FA87 +2F8A8 ; [.FB40.0020.0002.614E][.E14E.0000.0000.614E] # CJK COMPATIBILITY IDEOGRAPH-2F8A8 +FA8A ; [.FB40.0020.0002.6160][.E160.0000.0000.6160] # CJK COMPATIBILITY IDEOGRAPH-FA8A +FA3E ; [.FB40.0020.0002.6168][.E168.0000.0000.6168] # CJK COMPATIBILITY IDEOGRAPH-FA3E +2F8AA ; [.FB40.0020.0002.617A][.E17A.0000.0000.617A] # CJK COMPATIBILITY IDEOGRAPH-2F8AA +FA3F ; [.FB40.0020.0002.618E][.E18E.0000.0000.618E] # CJK COMPATIBILITY IDEOGRAPH-FA3F +FA89 ; [.FB40.0020.0002.618E][.E18E.0000.0000.618E] # CJK COMPATIBILITY IDEOGRAPH-FA89 +2F8AB ; [.FB40.0020.0002.618E][.E18E.0000.0000.618E] # CJK COMPATIBILITY IDEOGRAPH-2F8AB +F98F ; [.FB40.0020.0002.6190][.E190.0000.0000.6190] # CJK COMPATIBILITY IDEOGRAPH-F98F +2F8AD ; [.FB40.0020.0002.61A4][.E1A4.0000.0000.61A4] # CJK COMPATIBILITY IDEOGRAPH-2F8AD +2F8AE ; [.FB40.0020.0002.61AF][.E1AF.0000.0000.61AF] # CJK COMPATIBILITY IDEOGRAPH-2F8AE +2F8AC ; [.FB40.0020.0002.61B2][.E1B2.0000.0000.61B2] # CJK COMPATIBILITY IDEOGRAPH-2F8AC +2F8AF ; [.FB40.0020.0002.61DE][.E1DE.0000.0000.61DE] # CJK COMPATIBILITY IDEOGRAPH-2F8AF +FA40 ; [.FB40.0020.0002.61F2][.E1F2.0000.0000.61F2] # CJK COMPATIBILITY IDEOGRAPH-FA40 +FA8B ; [.FB40.0020.0002.61F2][.E1F2.0000.0000.61F2] # CJK COMPATIBILITY IDEOGRAPH-FA8B +2F8B0 ; [.FB40.0020.0002.61F2][.E1F2.0000.0000.61F2] # CJK COMPATIBILITY IDEOGRAPH-2F8B0 +F90D ; [.FB40.0020.0002.61F6][.E1F6.0000.0000.61F6] # CJK COMPATIBILITY IDEOGRAPH-F90D +2F8B1 ; [.FB40.0020.0002.61F6][.E1F6.0000.0000.61F6] # CJK COMPATIBILITY IDEOGRAPH-2F8B1 +F990 ; [.FB40.0020.0002.6200][.E200.0000.0000.6200] # CJK COMPATIBILITY IDEOGRAPH-F990 +2F3D ; [.FB40.0020.0004.6208][.E208.0000.0000.6208] # KANGXI RADICAL HALBERD +2F8B2 ; [.FB40.0020.0002.6210][.E210.0000.0000.6210] # CJK COMPATIBILITY IDEOGRAPH-2F8B2 +2F8B3 ; [.FB40.0020.0002.621B][.E21B.0000.0000.621B] # CJK COMPATIBILITY IDEOGRAPH-2F8B3 +F9D2 ; [.FB40.0020.0002.622E][.E22E.0000.0000.622E] # CJK COMPATIBILITY IDEOGRAPH-F9D2 +FA8C ; [.FB40.0020.0002.6234][.E234.0000.0000.6234] # CJK COMPATIBILITY IDEOGRAPH-FA8C +2F3E ; [.FB40.0020.0004.6236][.E236.0000.0000.6236] # KANGXI RADICAL DOOR +2F3F ; [.FB40.0020.0004.624B][.E24B.0000.0000.624B] # KANGXI RADICAL HAND +1F210 ; [.FB40.0020.001C.624B][.E24B.0000.0000.624B] # SQUARED CJK UNIFIED IDEOGRAPH-624B +2E98 ; [.FB40.0020.0004.624C][.E24C.0000.0000.624C] # CJK RADICAL HAND +1F245 ; [*0359.0020.0004.1F245][.FB40.0020.0004.6253][.E253.0000.0000.6253][*035A.0020.001F.1F245] # TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6253 +1F231 ; [.FB40.0020.001C.6253][.E253.0000.0000.6253] # SQUARED CJK UNIFIED IDEOGRAPH-6253 +2F8B4 ; [.FB40.0020.0002.625D][.E25D.0000.0000.625D] # CJK COMPATIBILITY IDEOGRAPH-2F8B4 +1F227 ; [.FB40.0020.001C.6295][.E295.0000.0000.6295] # SQUARED CJK UNIFIED IDEOGRAPH-6295 +2F8B5 ; [.FB40.0020.0002.62B1][.E2B1.0000.0000.62B1] # CJK COMPATIBILITY IDEOGRAPH-2F8B5 +F925 ; [.FB40.0020.0002.62C9][.E2C9.0000.0000.62C9] # CJK COMPATIBILITY IDEOGRAPH-F925 +F95B ; [.FB40.0020.0002.62CF][.E2CF.0000.0000.62CF] # CJK COMPATIBILITY IDEOGRAPH-F95B +FA02 ; [.FB40.0020.0002.62D3][.E2D3.0000.0000.62D3] # CJK COMPATIBILITY IDEOGRAPH-FA02 +2F8B6 ; [.FB40.0020.0002.62D4][.E2D4.0000.0000.62D4] # CJK COMPATIBILITY IDEOGRAPH-2F8B6 +2F8BA ; [.FB40.0020.0002.62FC][.E2FC.0000.0000.62FC] # CJK COMPATIBILITY IDEOGRAPH-2F8BA +F973 ; [.FB40.0020.0002.62FE][.E2FE.0000.0000.62FE] # CJK COMPATIBILITY IDEOGRAPH-F973 +1F22F ; [.FB40.0020.001C.6307][.E307.0000.0000.6307] # SQUARED CJK UNIFIED IDEOGRAPH-6307 +2F8B9 ; [.FB40.0020.0002.633D][.E33D.0000.0000.633D] # CJK COMPATIBILITY IDEOGRAPH-2F8B9 +2F8B7 ; [.FB40.0020.0002.6350][.E350.0000.0000.6350] # CJK COMPATIBILITY IDEOGRAPH-2F8B7 +1F228 ; [.FB40.0020.001C.6355][.E355.0000.0000.6355] # SQUARED CJK UNIFIED IDEOGRAPH-6355 +2F8BB ; [.FB40.0020.0002.6368][.E368.0000.0000.6368] # CJK COMPATIBILITY IDEOGRAPH-2F8BB +F9A4 ; [.FB40.0020.0002.637B][.E37B.0000.0000.637B] # CJK COMPATIBILITY IDEOGRAPH-F9A4 +2F8BC ; [.FB40.0020.0002.6383][.E383.0000.0000.6383] # CJK COMPATIBILITY IDEOGRAPH-2F8BC +F975 ; [.FB40.0020.0002.63A0][.E3A0.0000.0000.63A0] # CJK COMPATIBILITY IDEOGRAPH-F975 +2F8C1 ; [.FB40.0020.0002.63A9][.E3A9.0000.0000.63A9] # CJK COMPATIBILITY IDEOGRAPH-2F8C1 +FA8D ; [.FB40.0020.0002.63C4][.E3C4.0000.0000.63C4] # CJK COMPATIBILITY IDEOGRAPH-FA8D +2F8C0 ; [.FB40.0020.0002.63C5][.E3C5.0000.0000.63C5] # CJK COMPATIBILITY IDEOGRAPH-2F8C0 +2F8BD ; [.FB40.0020.0002.63E4][.E3E4.0000.0000.63E4] # CJK COMPATIBILITY IDEOGRAPH-2F8BD +FA8E ; [.FB40.0020.0002.641C][.E41C.0000.0000.641C] # CJK COMPATIBILITY IDEOGRAPH-FA8E +2F8BF ; [.FB40.0020.0002.6422][.E422.0000.0000.6422] # CJK COMPATIBILITY IDEOGRAPH-2F8BF +FA8F ; [.FB40.0020.0002.6452][.E452.0000.0000.6452] # CJK COMPATIBILITY IDEOGRAPH-FA8F +2F8C3 ; [.FB40.0020.0002.6469][.E469.0000.0000.6469] # CJK COMPATIBILITY IDEOGRAPH-2F8C3 +2F8C6 ; [.FB40.0020.0002.6477][.E477.0000.0000.6477] # CJK COMPATIBILITY IDEOGRAPH-2F8C6 +2F8C4 ; [.FB40.0020.0002.647E][.E47E.0000.0000.647E] # CJK COMPATIBILITY IDEOGRAPH-2F8C4 +F991 ; [.FB40.0020.0002.649A][.E49A.0000.0000.649A] # CJK COMPATIBILITY IDEOGRAPH-F991 +2F8C5 ; [.FB40.0020.0002.649D][.E49D.0000.0000.649D] # CJK COMPATIBILITY IDEOGRAPH-2F8C5 +F930 ; [.FB40.0020.0002.64C4][.E4C4.0000.0000.64C4] # CJK COMPATIBILITY IDEOGRAPH-F930 +2F40 ; [.FB40.0020.0004.652F][.E52F.0000.0000.652F] # KANGXI RADICAL BRANCH +2F41 ; [.FB40.0020.0004.6534][.E534.0000.0000.6534] # KANGXI RADICAL RAP +2E99 ; [.FB40.0020.0004.6535][.E535.0000.0000.6535] # CJK RADICAL RAP +FA41 ; [.FB40.0020.0002.654F][.E54F.0000.0000.654F] # CJK COMPATIBILITY IDEOGRAPH-FA41 +2F8C8 ; [.FB40.0020.0002.654F][.E54F.0000.0000.654F] # CJK COMPATIBILITY IDEOGRAPH-2F8C8 +FA90 ; [.FB40.0020.0002.6556][.E556.0000.0000.6556] # CJK COMPATIBILITY IDEOGRAPH-FA90 +1F248 ; [*0359.0020.0004.1F248][.FB40.0020.0004.6557][.E557.0000.0000.6557][*035A.0020.001F.1F248] # TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557 +2F8C9 ; [.FB40.0020.0002.656C][.E56C.0000.0000.656C] # CJK COMPATIBILITY IDEOGRAPH-2F8C9 +F969 ; [.FB40.0020.0002.6578][.E578.0000.0000.6578] # CJK COMPATIBILITY IDEOGRAPH-F969 +2F42 ; [.FB40.0020.0004.6587][.E587.0000.0000.6587] # KANGXI RADICAL SCRIPT +3246 ; [.FB40.0020.0006.6587][.E587.0000.0000.6587] # CIRCLED IDEOGRAPH SCHOOL +2F43 ; [.FB40.0020.0004.6597][.E597.0000.0000.6597] # KANGXI RADICAL DIPPER +F9BE ; [.FB40.0020.0002.6599][.E599.0000.0000.6599] # CJK COMPATIBILITY IDEOGRAPH-F9BE +1F21B ; [.FB40.0020.001C.6599][.E599.0000.0000.6599] # SQUARED CJK UNIFIED IDEOGRAPH-6599 +2F44 ; [.FB40.0020.0004.65A4][.E5A4.0000.0000.65A4] # KANGXI RADICAL AXE +1F21F ; [.FB40.0020.001C.65B0][.E5B0.0000.0000.65B0] # SQUARED CJK UNIFIED IDEOGRAPH-65B0 +2F45 ; [.FB40.0020.0004.65B9][.E5B9.0000.0000.65B9] # KANGXI RADICAL SQUARE +F983 ; [.FB40.0020.0002.65C5][.E5C5.0000.0000.65C5] # CJK COMPATIBILITY IDEOGRAPH-F983 +2F46 ; [.FB40.0020.0004.65E0][.E5E0.0000.0000.65E0] # KANGXI RADICAL NOT +2E9B ; [.FB40.0020.0004.65E1][.E5E1.0000.0000.65E1] # CJK RADICAL CHOKE +FA42 ; [.FB40.0020.0002.65E2][.E5E2.0000.0000.65E2] # CJK COMPATIBILITY IDEOGRAPH-FA42 +2F8CB ; [.FB40.0020.0002.65E3][.E5E3.0000.0000.65E3] # CJK COMPATIBILITY IDEOGRAPH-2F8CB +2F47 ; [.FB40.0020.0004.65E5][.E5E5.0000.0000.65E5] # KANGXI RADICAL SUN +3230 ; [*02FB.0020.0004.3230][.FB40.0020.0004.65E5][.E5E5.0000.0000.65E5][*02FC.0020.001F.3230] # PARENTHESIZED IDEOGRAPH SUN +3290 ; [.FB40.0020.0006.65E5][.E5E5.0000.0000.65E5] # CIRCLED IDEOGRAPH SUN +2E9C ; [.FB40.0020.0004.65E5][.E5E5.0000.0000.65E5][.0000.0139.001F.2E9C] # CJK RADICAL SUN +337E ; [.FB40.0020.001C.660E][.E60E.0000.0000.660E][.FB40.0020.001F.6CBB][.ECBB.0000.0000.6CBB] # SQUARE ERA NAME MEIZI +F9E0 ; [.FB40.0020.0002.6613][.E613.0000.0000.6613] # CJK COMPATIBILITY IDEOGRAPH-F9E0 +1F219 ; [.FB40.0020.001C.6620][.E620.0000.0000.6620] # SQUARED CJK UNIFIED IDEOGRAPH-6620 +337C ; [.FB40.0020.001C.662D][.E62D.0000.0000.662D][.FB40.0020.001F.548C][.D48C.0000.0000.548C] # SQUARE ERA NAME SYOUWA +2F8CD ; [.FB40.0020.0002.6649][.E649.0000.0000.6649] # CJK COMPATIBILITY IDEOGRAPH-2F8CD +FA12 ; [.FB40.0020.0002.6674][.E674.0000.0000.6674] # CJK COMPATIBILITY IDEOGRAPH-FA12 +FA91 ; [.FB40.0020.0002.6674][.E674.0000.0000.6674] # CJK COMPATIBILITY IDEOGRAPH-FA91 +F9C5 ; [.FB40.0020.0002.6688][.E688.0000.0000.6688] # CJK COMPATIBILITY IDEOGRAPH-F9C5 +FA43 ; [.FB40.0020.0002.6691][.E691.0000.0000.6691] # CJK COMPATIBILITY IDEOGRAPH-FA43 +2F8CF ; [.FB40.0020.0002.6691][.E691.0000.0000.6691] # CJK COMPATIBILITY IDEOGRAPH-2F8CF +2F8D5 ; [.FB40.0020.0002.669C][.E69C.0000.0000.669C] # CJK COMPATIBILITY IDEOGRAPH-2F8D5 +FA06 ; [.FB40.0020.0002.66B4][.E6B4.0000.0000.66B4] # CJK COMPATIBILITY IDEOGRAPH-FA06 +F98B ; [.FB40.0020.0002.66C6][.E6C6.0000.0000.66C6] # CJK COMPATIBILITY IDEOGRAPH-F98B +2F48 ; [.FB40.0020.0004.66F0][.E6F0.0000.0000.66F0] # KANGXI RADICAL SAY +F901 ; [.FB40.0020.0002.66F4][.E6F4.0000.0000.66F4] # CJK COMPATIBILITY IDEOGRAPH-F901 +2F8CC ; [.FB40.0020.0002.66F8][.E6F8.0000.0000.66F8] # CJK COMPATIBILITY IDEOGRAPH-2F8CC +2F8D4 ; [.FB40.0020.0002.6700][.E700.0000.0000.6700] # CJK COMPATIBILITY IDEOGRAPH-2F8D4 +2F49 ; [.FB40.0020.0004.6708][.E708.0000.0000.6708] # KANGXI RADICAL MOON +322A ; [*02FB.0020.0004.322A][.FB40.0020.0004.6708][.E708.0000.0000.6708][*02FC.0020.001F.322A] # PARENTHESIZED IDEOGRAPH MOON +328A ; [.FB40.0020.0006.6708][.E708.0000.0000.6708] # CIRCLED IDEOGRAPH MOON +1F237 ; [.FB40.0020.001C.6708][.E708.0000.0000.6708] # SQUARED CJK UNIFIED IDEOGRAPH-6708 +2E9D ; [.FB40.0020.0004.6708][.E708.0000.0000.6708][.0000.0139.001F.2E9D] # CJK RADICAL MOON +3232 ; [*02FB.0020.0004.3232][.FB40.0020.0004.6709][.E709.0000.0000.6709][*02FC.0020.001F.3232] # PARENTHESIZED IDEOGRAPH HAVE +3292 ; [.FB40.0020.0006.6709][.E709.0000.0000.6709] # CIRCLED IDEOGRAPH HAVE +1F236 ; [.FB40.0020.001C.6709][.E709.0000.0000.6709] # SQUARED CJK UNIFIED IDEOGRAPH-6709 +F929 ; [.FB40.0020.0002.6717][.E717.0000.0000.6717] # CJK COMPATIBILITY IDEOGRAPH-F929 +FA92 ; [.FB40.0020.0002.6717][.E717.0000.0000.6717] # CJK COMPATIBILITY IDEOGRAPH-FA92 +2F8D8 ; [.FB40.0020.0002.6717][.E717.0000.0000.6717] # CJK COMPATIBILITY IDEOGRAPH-2F8D8 +FA93 ; [.FB40.0020.0002.671B][.E71B.0000.0000.671B] # CJK COMPATIBILITY IDEOGRAPH-FA93 +2F8D9 ; [.FB40.0020.0002.671B][.E71B.0000.0000.671B] # CJK COMPATIBILITY IDEOGRAPH-2F8D9 +2F8DA ; [.FB40.0020.0002.6721][.E721.0000.0000.6721] # CJK COMPATIBILITY IDEOGRAPH-2F8DA +2F4A ; [.FB40.0020.0004.6728][.E728.0000.0000.6728] # KANGXI RADICAL TREE +322D ; [*02FB.0020.0004.322D][.FB40.0020.0004.6728][.E728.0000.0000.6728][*02FC.0020.001F.322D] # PARENTHESIZED IDEOGRAPH WOOD +328D ; [.FB40.0020.0006.6728][.E728.0000.0000.6728] # CIRCLED IDEOGRAPH WOOD +1F240 ; [*0359.0020.0004.1F240][.FB40.0020.0004.672C][.E72C.0000.0000.672C][*035A.0020.001F.1F240] # TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C +F9E1 ; [.FB40.0020.0002.674E][.E74E.0000.0000.674E] # CJK COMPATIBILITY IDEOGRAPH-F9E1 +2F8DC ; [.FB40.0020.0002.6753][.E753.0000.0000.6753] # CJK COMPATIBILITY IDEOGRAPH-2F8DC +FA94 ; [.FB40.0020.0002.6756][.E756.0000.0000.6756] # CJK COMPATIBILITY IDEOGRAPH-FA94 +2F8DB ; [.FB40.0020.0002.675E][.E75E.0000.0000.675E] # CJK COMPATIBILITY IDEOGRAPH-2F8DB +F9C8 ; [.FB40.0020.0002.677B][.E77B.0000.0000.677B] # CJK COMPATIBILITY IDEOGRAPH-F9C8 +2F8E0 ; [.FB40.0020.0002.6785][.E785.0000.0000.6785] # CJK COMPATIBILITY IDEOGRAPH-2F8E0 +F9F4 ; [.FB40.0020.0002.6797][.E797.0000.0000.6797] # CJK COMPATIBILITY IDEOGRAPH-F9F4 +F9C9 ; [.FB40.0020.0002.67F3][.E7F3.0000.0000.67F3] # CJK COMPATIBILITY IDEOGRAPH-F9C9 +2F8DF ; [.FB40.0020.0002.67FA][.E7FA.0000.0000.67FA] # CJK COMPATIBILITY IDEOGRAPH-2F8DF +F9DA ; [.FB40.0020.0002.6817][.E817.0000.0000.6817] # CJK COMPATIBILITY IDEOGRAPH-F9DA +2F8E5 ; [.FB40.0020.0002.681F][.E81F.0000.0000.681F] # CJK COMPATIBILITY IDEOGRAPH-2F8E5 +3231 ; [*02FB.0020.0004.3231][.FB40.0020.0004.682A][.E82A.0000.0000.682A][*02FC.0020.001F.3231] # PARENTHESIZED IDEOGRAPH STOCK +3291 ; [.FB40.0020.0006.682A][.E82A.0000.0000.682A] # CIRCLED IDEOGRAPH STOCK +337F ; [.FB40.0020.001C.682A][.E82A.0000.0000.682A][.FB40.0020.001F.5F0F][.DF0F.0000.0000.5F0F][.FB40.0020.001F.4F1A][.CF1A.0000.0000.4F1A][.FB40.0020.001F.793E][.F93E.0000.0000.793E] # SQUARE CORPORATION +2F8E1 ; [.FB40.0020.0002.6852][.E852.0000.0000.6852] # CJK COMPATIBILITY IDEOGRAPH-2F8E1 +F97A ; [.FB40.0020.0002.6881][.E881.0000.0000.6881] # CJK COMPATIBILITY IDEOGRAPH-F97A +FA44 ; [.FB40.0020.0002.6885][.E885.0000.0000.6885] # CJK COMPATIBILITY IDEOGRAPH-FA44 +2F8E2 ; [.FB40.0020.0002.6885][.E885.0000.0000.6885] # CJK COMPATIBILITY IDEOGRAPH-2F8E2 +2F8E4 ; [.FB40.0020.0002.688E][.E88E.0000.0000.688E] # CJK COMPATIBILITY IDEOGRAPH-2F8E4 +F9E2 ; [.FB40.0020.0002.68A8][.E8A8.0000.0000.68A8] # CJK COMPATIBILITY IDEOGRAPH-F9E2 +2F8E6 ; [.FB40.0020.0002.6914][.E914.0000.0000.6914] # CJK COMPATIBILITY IDEOGRAPH-2F8E6 +2F8E8 ; [.FB40.0020.0002.6942][.E942.0000.0000.6942] # CJK COMPATIBILITY IDEOGRAPH-2F8E8 +2F8E9 ; [.FB40.0020.0002.69A3][.E9A3.0000.0000.69A3] # CJK COMPATIBILITY IDEOGRAPH-2F8E9 +2F8EA ; [.FB40.0020.0002.69EA][.E9EA.0000.0000.69EA] # CJK COMPATIBILITY IDEOGRAPH-2F8EA +F914 ; [.FB40.0020.0002.6A02][.EA02.0000.0000.6A02] # CJK COMPATIBILITY IDEOGRAPH-F914 +F95C ; [.FB40.0020.0002.6A02][.EA02.0000.0000.6A02] # CJK COMPATIBILITY IDEOGRAPH-F95C +F9BF ; [.FB40.0020.0002.6A02][.EA02.0000.0000.6A02] # CJK COMPATIBILITY IDEOGRAPH-F9BF +F94C ; [.FB40.0020.0002.6A13][.EA13.0000.0000.6A13] # CJK COMPATIBILITY IDEOGRAPH-F94C +2F8EB ; [.FB40.0020.0002.6AA8][.EAA8.0000.0000.6AA8] # CJK COMPATIBILITY IDEOGRAPH-2F8EB +F931 ; [.FB40.0020.0002.6AD3][.EAD3.0000.0000.6AD3] # CJK COMPATIBILITY IDEOGRAPH-F931 +2F8ED ; [.FB40.0020.0002.6ADB][.EADB.0000.0000.6ADB] # CJK COMPATIBILITY IDEOGRAPH-2F8ED +F91D ; [.FB40.0020.0002.6B04][.EB04.0000.0000.6B04] # CJK COMPATIBILITY IDEOGRAPH-F91D +2F4B ; [.FB40.0020.0004.6B20][.EB20.0000.0000.6B20] # KANGXI RADICAL LACK +2F8EF ; [.FB40.0020.0002.6B21][.EB21.0000.0000.6B21] # CJK COMPATIBILITY IDEOGRAPH-2F8EF +2F8F1 ; [.FB40.0020.0002.6B54][.EB54.0000.0000.6B54] # CJK COMPATIBILITY IDEOGRAPH-2F8F1 +2F4C ; [.FB40.0020.0004.6B62][.EB62.0000.0000.6B62] # KANGXI RADICAL STOP +32A3 ; [.FB40.0020.0006.6B63][.EB63.0000.0000.6B63] # CIRCLED IDEOGRAPH CORRECT +2F8F3 ; [.FB40.0020.0002.6B72][.EB72.0000.0000.6B72] # CJK COMPATIBILITY IDEOGRAPH-2F8F3 +F98C ; [.FB40.0020.0002.6B77][.EB77.0000.0000.6B77] # CJK COMPATIBILITY IDEOGRAPH-F98C +FA95 ; [.FB40.0020.0002.6B79][.EB79.0000.0000.6B79] # CJK COMPATIBILITY IDEOGRAPH-FA95 +2F4D ; [.FB40.0020.0004.6B79][.EB79.0000.0000.6B79] # KANGXI RADICAL DEATH +2E9E ; [.FB40.0020.0004.6B7A][.EB7A.0000.0000.6B7A][.0000.0139.001F.2E9E] # CJK RADICAL DEATH +2F8F4 ; [.FB40.0020.0002.6B9F][.EB9F.0000.0000.6B9F] # CJK COMPATIBILITY IDEOGRAPH-2F8F4 +F9A5 ; [.FB40.0020.0002.6BAE][.EBAE.0000.0000.6BAE] # CJK COMPATIBILITY IDEOGRAPH-F9A5 +2F4E ; [.FB40.0020.0004.6BB3][.EBB3.0000.0000.6BB3] # KANGXI RADICAL WEAPON +F970 ; [.FB40.0020.0002.6BBA][.EBBA.0000.0000.6BBA] # CJK COMPATIBILITY IDEOGRAPH-F970 +FA96 ; [.FB40.0020.0002.6BBA][.EBBA.0000.0000.6BBA] # CJK COMPATIBILITY IDEOGRAPH-FA96 +2F8F5 ; [.FB40.0020.0002.6BBA][.EBBA.0000.0000.6BBA] # CJK COMPATIBILITY IDEOGRAPH-2F8F5 +2F8F6 ; [.FB40.0020.0002.6BBB][.EBBB.0000.0000.6BBB] # CJK COMPATIBILITY IDEOGRAPH-2F8F6 +2F4F ; [.FB40.0020.0004.6BCB][.EBCB.0000.0000.6BCB] # KANGXI RADICAL DO NOT +2E9F ; [.FB40.0020.0004.6BCD][.EBCD.0000.0000.6BCD] # CJK RADICAL MOTHER +2F50 ; [.FB40.0020.0004.6BD4][.EBD4.0000.0000.6BD4] # KANGXI RADICAL COMPARE +2F51 ; [.FB40.0020.0004.6BDB][.EBDB.0000.0000.6BDB] # KANGXI RADICAL FUR +2F52 ; [.FB40.0020.0004.6C0F][.EC0F.0000.0000.6C0F] # KANGXI RADICAL CLAN +2EA0 ; [.FB40.0020.0004.6C11][.EC11.0000.0000.6C11] # CJK RADICAL CIVILIAN +2F53 ; [.FB40.0020.0004.6C14][.EC14.0000.0000.6C14] # KANGXI RADICAL STEAM +2F54 ; [.FB40.0020.0004.6C34][.EC34.0000.0000.6C34] # KANGXI RADICAL WATER +322C ; [*02FB.0020.0004.322C][.FB40.0020.0004.6C34][.EC34.0000.0000.6C34][*02FC.0020.001F.322C] # PARENTHESIZED IDEOGRAPH WATER +328C ; [.FB40.0020.0006.6C34][.EC34.0000.0000.6C34] # CIRCLED IDEOGRAPH WATER +2EA1 ; [.FB40.0020.0004.6C35][.EC35.0000.0000.6C35] # CJK RADICAL WATER ONE +2EA2 ; [.FB40.0020.0004.6C3A][.EC3A.0000.0000.6C3A] # CJK RADICAL WATER TWO +2F8FA ; [.FB40.0020.0002.6C4E][.EC4E.0000.0000.6C4E] # CJK COMPATIBILITY IDEOGRAPH-2F8FA +2F8FE ; [.FB40.0020.0002.6C67][.EC67.0000.0000.6C67] # CJK COMPATIBILITY IDEOGRAPH-2F8FE +F972 ; [.FB40.0020.0002.6C88][.EC88.0000.0000.6C88] # CJK COMPATIBILITY IDEOGRAPH-F972 +2F8FC ; [.FB40.0020.0002.6CBF][.ECBF.0000.0000.6CBF] # CJK COMPATIBILITY IDEOGRAPH-2F8FC +F968 ; [.FB40.0020.0002.6CCC][.ECCC.0000.0000.6CCC] # CJK COMPATIBILITY IDEOGRAPH-F968 +2F8FD ; [.FB40.0020.0002.6CCD][.ECCD.0000.0000.6CCD] # CJK COMPATIBILITY IDEOGRAPH-2F8FD +F9E3 ; [.FB40.0020.0002.6CE5][.ECE5.0000.0000.6CE5] # CJK COMPATIBILITY IDEOGRAPH-F9E3 +329F ; [.FB40.0020.0006.6CE8][.ECE8.0000.0000.6CE8] # CIRCLED IDEOGRAPH ATTENTION +2F8FF ; [.FB40.0020.0002.6D16][.ED16.0000.0000.6D16] # CJK COMPATIBILITY IDEOGRAPH-2F8FF +F915 ; [.FB40.0020.0002.6D1B][.ED1B.0000.0000.6D1B] # CJK COMPATIBILITY IDEOGRAPH-F915 +FA05 ; [.FB40.0020.0002.6D1E][.ED1E.0000.0000.6D1E] # CJK COMPATIBILITY IDEOGRAPH-FA05 +2F907 ; [.FB40.0020.0002.6D34][.ED34.0000.0000.6D34] # CJK COMPATIBILITY IDEOGRAPH-2F907 +2F900 ; [.FB40.0020.0002.6D3E][.ED3E.0000.0000.6D3E] # CJK COMPATIBILITY IDEOGRAPH-2F900 +F9CA ; [.FB40.0020.0002.6D41][.ED41.0000.0000.6D41] # CJK COMPATIBILITY IDEOGRAPH-F9CA +FA97 ; [.FB40.0020.0002.6D41][.ED41.0000.0000.6D41] # CJK COMPATIBILITY IDEOGRAPH-FA97 +2F902 ; [.FB40.0020.0002.6D41][.ED41.0000.0000.6D41] # CJK COMPATIBILITY IDEOGRAPH-2F902 +2F903 ; [.FB40.0020.0002.6D69][.ED69.0000.0000.6D69] # CJK COMPATIBILITY IDEOGRAPH-2F903 +F92A ; [.FB40.0020.0002.6D6A][.ED6A.0000.0000.6D6A] # CJK COMPATIBILITY IDEOGRAPH-F92A +FA45 ; [.FB40.0020.0002.6D77][.ED77.0000.0000.6D77] # CJK COMPATIBILITY IDEOGRAPH-FA45 +2F901 ; [.FB40.0020.0002.6D77][.ED77.0000.0000.6D77] # CJK COMPATIBILITY IDEOGRAPH-2F901 +2F904 ; [.FB40.0020.0002.6D78][.ED78.0000.0000.6D78] # CJK COMPATIBILITY IDEOGRAPH-2F904 +2F905 ; [.FB40.0020.0002.6D85][.ED85.0000.0000.6D85] # CJK COMPATIBILITY IDEOGRAPH-2F905 +F9F5 ; [.FB40.0020.0002.6DCB][.EDCB.0000.0000.6DCB] # CJK COMPATIBILITY IDEOGRAPH-F9F5 +F94D ; [.FB40.0020.0002.6DDA][.EDDA.0000.0000.6DDA] # CJK COMPATIBILITY IDEOGRAPH-F94D +F9D6 ; [.FB40.0020.0002.6DEA][.EDEA.0000.0000.6DEA] # CJK COMPATIBILITY IDEOGRAPH-F9D6 +2F90E ; [.FB40.0020.0002.6DF9][.EDF9.0000.0000.6DF9] # CJK COMPATIBILITY IDEOGRAPH-2F90E +FA46 ; [.FB40.0020.0002.6E1A][.EE1A.0000.0000.6E1A] # CJK COMPATIBILITY IDEOGRAPH-FA46 +2F908 ; [.FB40.0020.0002.6E2F][.EE2F.0000.0000.6E2F] # CJK COMPATIBILITY IDEOGRAPH-2F908 +2F909 ; [.FB40.0020.0002.6E6E][.EE6E.0000.0000.6E6E] # CJK COMPATIBILITY IDEOGRAPH-2F909 +1F235 ; [.FB40.0020.001C.6E80][.EE80.0000.0000.6E80] # SQUARED CJK UNIFIED IDEOGRAPH-6E80 +F9CB ; [.FB40.0020.0002.6E9C][.EE9C.0000.0000.6E9C] # CJK COMPATIBILITY IDEOGRAPH-F9CB +F9EC ; [.FB40.0020.0002.6EBA][.EEBA.0000.0000.6EBA] # CJK COMPATIBILITY IDEOGRAPH-F9EC +2F90C ; [.FB40.0020.0002.6EC7][.EEC7.0000.0000.6EC7] # CJK COMPATIBILITY IDEOGRAPH-2F90C +FA99 ; [.FB40.0020.0002.6ECB][.EECB.0000.0000.6ECB] # CJK COMPATIBILITY IDEOGRAPH-FA99 +2F90B ; [.FB40.0020.0002.6ECB][.EECB.0000.0000.6ECB] # CJK COMPATIBILITY IDEOGRAPH-2F90B +F904 ; [.FB40.0020.0002.6ED1][.EED1.0000.0000.6ED1] # CJK COMPATIBILITY IDEOGRAPH-F904 +FA98 ; [.FB40.0020.0002.6EDB][.EEDB.0000.0000.6EDB] # CJK COMPATIBILITY IDEOGRAPH-FA98 +F94E ; [.FB40.0020.0002.6F0F][.EF0F.0000.0000.6F0F] # CJK COMPATIBILITY IDEOGRAPH-F94E +1F226 ; [.FB40.0020.001C.6F14][.EF14.0000.0000.6F14] # SQUARED CJK UNIFIED IDEOGRAPH-6F14 +FA47 ; [.FB40.0020.0002.6F22][.EF22.0000.0000.6F22] # CJK COMPATIBILITY IDEOGRAPH-FA47 +FA9A ; [.FB40.0020.0002.6F22][.EF22.0000.0000.6F22] # CJK COMPATIBILITY IDEOGRAPH-FA9A +F992 ; [.FB40.0020.0002.6F23][.EF23.0000.0000.6F23] # CJK COMPATIBILITY IDEOGRAPH-F992 +2F90F ; [.FB40.0020.0002.6F6E][.EF6E.0000.0000.6F6E] # CJK COMPATIBILITY IDEOGRAPH-2F90F +2F912 ; [.FB40.0020.0002.6FC6][.EFC6.0000.0000.6FC6] # CJK COMPATIBILITY IDEOGRAPH-2F912 +F922 ; [.FB40.0020.0002.6FEB][.EFEB.0000.0000.6FEB] # CJK COMPATIBILITY IDEOGRAPH-F922 +F984 ; [.FB40.0020.0002.6FFE][.EFFE.0000.0000.6FFE] # CJK COMPATIBILITY IDEOGRAPH-F984 +2F915 ; [.FB40.0020.0002.701B][.F01B.0000.0000.701B] # CJK COMPATIBILITY IDEOGRAPH-2F915 +FA9B ; [.FB40.0020.0002.701E][.F01E.0000.0000.701E] # CJK COMPATIBILITY IDEOGRAPH-FA9B +2F914 ; [.FB40.0020.0002.701E][.F01E.0000.0000.701E] # CJK COMPATIBILITY IDEOGRAPH-2F914 +2F913 ; [.FB40.0020.0002.7039][.F039.0000.0000.7039] # CJK COMPATIBILITY IDEOGRAPH-2F913 +2F917 ; [.FB40.0020.0002.704A][.F04A.0000.0000.704A] # CJK COMPATIBILITY IDEOGRAPH-2F917 +2F55 ; [.FB40.0020.0004.706B][.F06B.0000.0000.706B] # KANGXI RADICAL FIRE +322B ; [*02FB.0020.0004.322B][.FB40.0020.0004.706B][.F06B.0000.0000.706B][*02FC.0020.001F.322B] # PARENTHESIZED IDEOGRAPH FIRE +328B ; [.FB40.0020.0006.706B][.F06B.0000.0000.706B] # CIRCLED IDEOGRAPH FIRE +2EA3 ; [.FB40.0020.0004.706C][.F06C.0000.0000.706C] # CJK RADICAL FIRE +2F835 ; [.FB40.0020.0002.7070][.F070.0000.0000.7070] # CJK COMPATIBILITY IDEOGRAPH-2F835 +2F919 ; [.FB40.0020.0002.7077][.F077.0000.0000.7077] # CJK COMPATIBILITY IDEOGRAPH-2F919 +2F918 ; [.FB40.0020.0002.707D][.F07D.0000.0000.707D] # CJK COMPATIBILITY IDEOGRAPH-2F918 +F9FB ; [.FB40.0020.0002.7099][.F099.0000.0000.7099] # CJK COMPATIBILITY IDEOGRAPH-F9FB +2F91A ; [.FB40.0020.0002.70AD][.F0AD.0000.0000.70AD] # CJK COMPATIBILITY IDEOGRAPH-2F91A +1F244 ; [*0359.0020.0004.1F244][.FB40.0020.0004.70B9][.F0B9.0000.0000.70B9][*035A.0020.001F.1F244] # TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-70B9 +F99F ; [.FB40.0020.0002.70C8][.F0C8.0000.0000.70C8] # CJK COMPATIBILITY IDEOGRAPH-F99F +F916 ; [.FB40.0020.0002.70D9][.F0D9.0000.0000.70D9] # CJK COMPATIBILITY IDEOGRAPH-F916 +1F21A ; [.FB40.0020.001C.7121][.F121.0000.0000.7121] # SQUARED CJK UNIFIED IDEOGRAPH-7121 +2F91C ; [.FB40.0020.0002.7145][.F145.0000.0000.7145] # CJK COMPATIBILITY IDEOGRAPH-2F91C +F993 ; [.FB40.0020.0002.7149][.F149.0000.0000.7149] # CJK COMPATIBILITY IDEOGRAPH-F993 +FA48 ; [.FB40.0020.0002.716E][.F16E.0000.0000.716E] # CJK COMPATIBILITY IDEOGRAPH-FA48 +FA9C ; [.FB40.0020.0002.716E][.F16E.0000.0000.716E] # CJK COMPATIBILITY IDEOGRAPH-FA9C +2F91E ; [.FB40.0020.0002.719C][.F19C.0000.0000.719C] # CJK COMPATIBILITY IDEOGRAPH-2F91E +F9C0 ; [.FB40.0020.0002.71CE][.F1CE.0000.0000.71CE] # CJK COMPATIBILITY IDEOGRAPH-F9C0 +F9EE ; [.FB40.0020.0002.71D0][.F1D0.0000.0000.71D0] # CJK COMPATIBILITY IDEOGRAPH-F9EE +F932 ; [.FB40.0020.0002.7210][.F210.0000.0000.7210] # CJK COMPATIBILITY IDEOGRAPH-F932 +F91E ; [.FB40.0020.0002.721B][.F21B.0000.0000.721B] # CJK COMPATIBILITY IDEOGRAPH-F91E +2F920 ; [.FB40.0020.0002.7228][.F228.0000.0000.7228] # CJK COMPATIBILITY IDEOGRAPH-2F920 +2F56 ; [.FB40.0020.0004.722A][.F22A.0000.0000.722A] # KANGXI RADICAL CLAW +FA49 ; [.FB40.0020.0002.722B][.F22B.0000.0000.722B] # CJK COMPATIBILITY IDEOGRAPH-FA49 +2EA4 ; [.FB40.0020.0004.722B][.F22B.0000.0000.722B] # CJK RADICAL PAW ONE +2EA5 ; [.FB40.0020.0004.722B][.F22B.0000.0000.722B][.0000.0139.001F.2EA5] # CJK RADICAL PAW TWO +FA9E ; [.FB40.0020.0002.7235][.F235.0000.0000.7235] # CJK COMPATIBILITY IDEOGRAPH-FA9E +2F921 ; [.FB40.0020.0002.7235][.F235.0000.0000.7235] # CJK COMPATIBILITY IDEOGRAPH-2F921 +2F57 ; [.FB40.0020.0004.7236][.F236.0000.0000.7236] # KANGXI RADICAL FATHER +2F58 ; [.FB40.0020.0004.723B][.F23B.0000.0000.723B] # KANGXI RADICAL DOUBLE X +2F59 ; [.FB40.0020.0004.723F][.F23F.0000.0000.723F] # KANGXI RADICAL HALF TREE TRUNK +2F5A ; [.FB40.0020.0004.7247][.F247.0000.0000.7247] # KANGXI RADICAL SLICE +2F922 ; [.FB40.0020.0002.7250][.F250.0000.0000.7250] # CJK COMPATIBILITY IDEOGRAPH-2F922 +2F5B ; [.FB40.0020.0004.7259][.F259.0000.0000.7259] # KANGXI RADICAL FANG +2F5C ; [.FB40.0020.0004.725B][.F25B.0000.0000.725B] # KANGXI RADICAL COW +2EA7 ; [.FB40.0020.0004.725B][.F25B.0000.0000.725B][.0000.0139.001F.2EA7] # CJK RADICAL COW +F946 ; [.FB40.0020.0002.7262][.F262.0000.0000.7262] # CJK COMPATIBILITY IDEOGRAPH-F946 +3235 ; [*02FB.0020.0004.3235][.FB40.0020.0004.7279][.F279.0000.0000.7279][*02FC.0020.001F.3235] # PARENTHESIZED IDEOGRAPH SPECIAL +3295 ; [.FB40.0020.0006.7279][.F279.0000.0000.7279] # CIRCLED IDEOGRAPH SPECIAL +2F924 ; [.FB40.0020.0002.7280][.F280.0000.0000.7280] # CJK COMPATIBILITY IDEOGRAPH-2F924 +2F925 ; [.FB40.0020.0002.7295][.F295.0000.0000.7295] # CJK COMPATIBILITY IDEOGRAPH-2F925 +2F5D ; [.FB40.0020.0004.72AC][.F2AC.0000.0000.72AC] # KANGXI RADICAL DOG +2EA8 ; [.FB40.0020.0004.72AD][.F2AD.0000.0000.72AD] # CJK RADICAL DOG +FA9F ; [.FB40.0020.0002.72AF][.F2AF.0000.0000.72AF] # CJK COMPATIBILITY IDEOGRAPH-FA9F +F9FA ; [.FB40.0020.0002.72C0][.F2C0.0000.0000.72C0] # CJK COMPATIBILITY IDEOGRAPH-F9FA +F92B ; [.FB40.0020.0002.72FC][.F2FC.0000.0000.72FC] # CJK COMPATIBILITY IDEOGRAPH-F92B +FA16 ; [.FB40.0020.0002.732A][.F32A.0000.0000.732A] # CJK COMPATIBILITY IDEOGRAPH-FA16 +FAA0 ; [.FB40.0020.0002.732A][.F32A.0000.0000.732A] # CJK COMPATIBILITY IDEOGRAPH-FAA0 +F9A7 ; [.FB40.0020.0002.7375][.F375.0000.0000.7375] # CJK COMPATIBILITY IDEOGRAPH-F9A7 +2F928 ; [.FB40.0020.0002.737A][.F37A.0000.0000.737A] # CJK COMPATIBILITY IDEOGRAPH-2F928 +2F5E ; [.FB40.0020.0004.7384][.F384.0000.0000.7384] # KANGXI RADICAL PROFOUND +F961 ; [.FB40.0020.0002.7387][.F387.0000.0000.7387] # CJK COMPATIBILITY IDEOGRAPH-F961 +F9DB ; [.FB40.0020.0002.7387][.F387.0000.0000.7387] # CJK COMPATIBILITY IDEOGRAPH-F9DB +2F5F ; [.FB40.0020.0004.7389][.F389.0000.0000.7389] # KANGXI RADICAL JADE +2F929 ; [.FB40.0020.0002.738B][.F38B.0000.0000.738B] # CJK COMPATIBILITY IDEOGRAPH-2F929 +2EA9 ; [.FB40.0020.0004.738B][.F38B.0000.0000.738B][.0000.0139.001F.2EA9] # CJK RADICAL JADE +2F92B ; [.FB40.0020.0002.73A5][.F3A5.0000.0000.73A5] # CJK COMPATIBILITY IDEOGRAPH-2F92B +F9AD ; [.FB40.0020.0002.73B2][.F3B2.0000.0000.73B2] # CJK COMPATIBILITY IDEOGRAPH-F9AD +F917 ; [.FB40.0020.0002.73DE][.F3DE.0000.0000.73DE] # CJK COMPATIBILITY IDEOGRAPH-F917 +F9E4 ; [.FB40.0020.0002.7406][.F406.0000.0000.7406] # CJK COMPATIBILITY IDEOGRAPH-F9E4 +F9CC ; [.FB40.0020.0002.7409][.F409.0000.0000.7409] # CJK COMPATIBILITY IDEOGRAPH-F9CC +FA4A ; [.FB40.0020.0002.7422][.F422.0000.0000.7422] # CJK COMPATIBILITY IDEOGRAPH-FA4A +2F92E ; [.FB40.0020.0002.7447][.F447.0000.0000.7447] # CJK COMPATIBILITY IDEOGRAPH-2F92E +2F92F ; [.FB40.0020.0002.745C][.F45C.0000.0000.745C] # CJK COMPATIBILITY IDEOGRAPH-2F92F +F9AE ; [.FB40.0020.0002.7469][.F469.0000.0000.7469] # CJK COMPATIBILITY IDEOGRAPH-F9AE +FAA1 ; [.FB40.0020.0002.7471][.F471.0000.0000.7471] # CJK COMPATIBILITY IDEOGRAPH-FAA1 +2F930 ; [.FB40.0020.0002.7471][.F471.0000.0000.7471] # CJK COMPATIBILITY IDEOGRAPH-2F930 +2F931 ; [.FB40.0020.0002.7485][.F485.0000.0000.7485] # CJK COMPATIBILITY IDEOGRAPH-2F931 +F994 ; [.FB40.0020.0002.7489][.F489.0000.0000.7489] # CJK COMPATIBILITY IDEOGRAPH-F994 +F9EF ; [.FB40.0020.0002.7498][.F498.0000.0000.7498] # CJK COMPATIBILITY IDEOGRAPH-F9EF +2F932 ; [.FB40.0020.0002.74CA][.F4CA.0000.0000.74CA] # CJK COMPATIBILITY IDEOGRAPH-2F932 +2F60 ; [.FB40.0020.0004.74DC][.F4DC.0000.0000.74DC] # KANGXI RADICAL MELON +2F61 ; [.FB40.0020.0004.74E6][.F4E6.0000.0000.74E6] # KANGXI RADICAL TILE +FAA2 ; [.FB40.0020.0002.7506][.F506.0000.0000.7506] # CJK COMPATIBILITY IDEOGRAPH-FAA2 +2F62 ; [.FB40.0020.0004.7518][.F518.0000.0000.7518] # KANGXI RADICAL SWEET +2F63 ; [.FB40.0020.0004.751F][.F51F.0000.0000.751F] # KANGXI RADICAL LIFE +1F222 ; [.FB40.0020.001C.751F][.F51F.0000.0000.751F] # SQUARED CJK UNIFIED IDEOGRAPH-751F +2F934 ; [.FB40.0020.0002.7524][.F524.0000.0000.7524] # CJK COMPATIBILITY IDEOGRAPH-2F934 +2F64 ; [.FB40.0020.0004.7528][.F528.0000.0000.7528] # KANGXI RADICAL USE +2F65 ; [.FB40.0020.0004.7530][.F530.0000.0000.7530] # KANGXI RADICAL FIELD +3199 ; [.FB40.0020.0014.7532][.F532.0000.0000.7532] # IDEOGRAPHIC ANNOTATION FIRST MARK +1F238 ; [.FB40.0020.001C.7533][.F533.0000.0000.7533] # SQUARED CJK UNIFIED IDEOGRAPH-7533 +329A ; [.FB40.0020.0006.7537][.F537.0000.0000.7537] # CIRCLED IDEOGRAPH MALE +FAA3 ; [.FB40.0020.0002.753B][.F53B.0000.0000.753B] # CJK COMPATIBILITY IDEOGRAPH-FAA3 +2F936 ; [.FB40.0020.0002.753E][.F53E.0000.0000.753E] # CJK COMPATIBILITY IDEOGRAPH-2F936 +F9CD ; [.FB40.0020.0002.7559][.F559.0000.0000.7559] # CJK COMPATIBILITY IDEOGRAPH-F9CD +F976 ; [.FB40.0020.0002.7565][.F565.0000.0000.7565] # CJK COMPATIBILITY IDEOGRAPH-F976 +F962 ; [.FB40.0020.0002.7570][.F570.0000.0000.7570] # CJK COMPATIBILITY IDEOGRAPH-F962 +2F938 ; [.FB40.0020.0002.7570][.F570.0000.0000.7570] # CJK COMPATIBILITY IDEOGRAPH-2F938 +2F66 ; [.FB40.0020.0004.758B][.F58B.0000.0000.758B] # KANGXI RADICAL BOLT OF CLOTH +2EAA ; [.FB40.0020.0004.758B][.F58B.0000.0000.758B][.0000.0139.001F.2EAA] # CJK RADICAL BOLT OF CLOTH +2F67 ; [.FB40.0020.0004.7592][.F592.0000.0000.7592] # KANGXI RADICAL SICKNESS +F9E5 ; [.FB40.0020.0002.75E2][.F5E2.0000.0000.75E2] # CJK COMPATIBILITY IDEOGRAPH-F9E5 +2F93A ; [.FB40.0020.0002.7610][.F610.0000.0000.7610] # CJK COMPATIBILITY IDEOGRAPH-2F93A +FAA4 ; [.FB40.0020.0002.761D][.F61D.0000.0000.761D] # CJK COMPATIBILITY IDEOGRAPH-FAA4 +FAA5 ; [.FB40.0020.0002.761F][.F61F.0000.0000.761F] # CJK COMPATIBILITY IDEOGRAPH-FAA5 +F9C1 ; [.FB40.0020.0002.7642][.F642.0000.0000.7642] # CJK COMPATIBILITY IDEOGRAPH-F9C1 +F90E ; [.FB40.0020.0002.7669][.F669.0000.0000.7669] # CJK COMPATIBILITY IDEOGRAPH-F90E +2F68 ; [.FB40.0020.0004.7676][.F676.0000.0000.7676] # KANGXI RADICAL DOTTED TENT +2F69 ; [.FB40.0020.0004.767D][.F67D.0000.0000.767D] # KANGXI RADICAL WHITE +2F6A ; [.FB40.0020.0004.76AE][.F6AE.0000.0000.76AE] # KANGXI RADICAL SKIN +2F6B ; [.FB40.0020.0004.76BF][.F6BF.0000.0000.76BF] # KANGXI RADICAL DISH +FA17 ; [.FB40.0020.0002.76CA][.F6CA.0000.0000.76CA] # CJK COMPATIBILITY IDEOGRAPH-FA17 +FAA6 ; [.FB40.0020.0002.76CA][.F6CA.0000.0000.76CA] # CJK COMPATIBILITY IDEOGRAPH-FAA6 +1F246 ; [*0359.0020.0004.1F246][.FB40.0020.0004.76D7][.F6D7.0000.0000.76D7][*035A.0020.001F.1F246] # TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-76D7 +FAA7 ; [.FB40.0020.0002.76DB][.F6DB.0000.0000.76DB] # CJK COMPATIBILITY IDEOGRAPH-FAA7 +323C ; [*02FB.0020.0004.323C][.FB40.0020.0004.76E3][.F6E3.0000.0000.76E3][*02FC.0020.001F.323C] # PARENTHESIZED IDEOGRAPH SUPERVISE +32AC ; [.FB40.0020.0006.76E3][.F6E3.0000.0000.76E3] # CIRCLED IDEOGRAPH SUPERVISE +F933 ; [.FB40.0020.0002.76E7][.F6E7.0000.0000.76E7] # CJK COMPATIBILITY IDEOGRAPH-F933 +2F6C ; [.FB40.0020.0004.76EE][.F6EE.0000.0000.76EE] # KANGXI RADICAL EYE +2EAB ; [.FB40.0020.0004.76EE][.F6EE.0000.0000.76EE][.0000.0139.001F.2EAB] # CJK RADICAL EYE +FAA8 ; [.FB40.0020.0002.76F4][.F6F4.0000.0000.76F4] # CJK COMPATIBILITY IDEOGRAPH-FAA8 +2F940 ; [.FB40.0020.0002.76F4][.F6F4.0000.0000.76F4] # CJK COMPATIBILITY IDEOGRAPH-2F940 +F96D ; [.FB40.0020.0002.7701][.F701.0000.0000.7701] # CJK COMPATIBILITY IDEOGRAPH-F96D +2F945 ; [.FB40.0020.0002.771E][.F71E.0000.0000.771E] # CJK COMPATIBILITY IDEOGRAPH-2F945 +2F946 ; [.FB40.0020.0002.771F][.F71F.0000.0000.771F] # CJK COMPATIBILITY IDEOGRAPH-2F946 +2F947 ; [.FB40.0020.0002.771F][.F71F.0000.0000.771F] # CJK COMPATIBILITY IDEOGRAPH-2F947 +FAAA ; [.FB40.0020.0002.7740][.F740.0000.0000.7740] # CJK COMPATIBILITY IDEOGRAPH-FAAA +FAA9 ; [.FB40.0020.0002.774A][.F74A.0000.0000.774A] # CJK COMPATIBILITY IDEOGRAPH-FAA9 +2F948 ; [.FB40.0020.0002.774A][.F74A.0000.0000.774A] # CJK COMPATIBILITY IDEOGRAPH-2F948 +2F94A ; [.FB40.0020.0002.778B][.F78B.0000.0000.778B] # CJK COMPATIBILITY IDEOGRAPH-2F94A +FA9D ; [.FB40.0020.0002.77A7][.F7A7.0000.0000.77A7] # CJK COMPATIBILITY IDEOGRAPH-FA9D +2F6D ; [.FB40.0020.0004.77DB][.F7DB.0000.0000.77DB] # KANGXI RADICAL SPEAR +2F6E ; [.FB40.0020.0004.77E2][.F7E2.0000.0000.77E2] # KANGXI RADICAL ARROW +2F6F ; [.FB40.0020.0004.77F3][.F7F3.0000.0000.77F3] # KANGXI RADICAL STONE +2F94E ; [.FB40.0020.0002.784E][.F84E.0000.0000.784E] # CJK COMPATIBILITY IDEOGRAPH-2F94E +F9CE ; [.FB40.0020.0002.786B][.F86B.0000.0000.786B] # CJK COMPATIBILITY IDEOGRAPH-F9CE +F93B ; [.FB40.0020.0002.788C][.F88C.0000.0000.788C] # CJK COMPATIBILITY IDEOGRAPH-F93B +2F94F ; [.FB40.0020.0002.788C][.F88C.0000.0000.788C] # CJK COMPATIBILITY IDEOGRAPH-2F94F +FA4B ; [.FB40.0020.0002.7891][.F891.0000.0000.7891] # CJK COMPATIBILITY IDEOGRAPH-FA4B +F947 ; [.FB40.0020.0002.78CA][.F8CA.0000.0000.78CA] # CJK COMPATIBILITY IDEOGRAPH-F947 +FAAB ; [.FB40.0020.0002.78CC][.F8CC.0000.0000.78CC] # CJK COMPATIBILITY IDEOGRAPH-FAAB +2F950 ; [.FB40.0020.0002.78CC][.F8CC.0000.0000.78CC] # CJK COMPATIBILITY IDEOGRAPH-2F950 +F964 ; [.FB40.0020.0002.78FB][.F8FB.0000.0000.78FB] # CJK COMPATIBILITY IDEOGRAPH-F964 +F985 ; [.FB40.0020.0002.792A][.F92A.0000.0000.792A] # CJK COMPATIBILITY IDEOGRAPH-F985 +2F70 ; [.FB40.0020.0004.793A][.F93A.0000.0000.793A] # KANGXI RADICAL SPIRIT +2EAC ; [.FB40.0020.0004.793A][.F93A.0000.0000.793A][.0000.0139.001F.2EAC] # CJK RADICAL SPIRIT ONE +2EAD ; [.FB40.0020.0004.793B][.F93B.0000.0000.793B] # CJK RADICAL SPIRIT TWO +FA18 ; [.FB40.0020.0002.793C][.F93C.0000.0000.793C] # CJK COMPATIBILITY IDEOGRAPH-FA18 +FA4C ; [.FB40.0020.0002.793E][.F93E.0000.0000.793E] # CJK COMPATIBILITY IDEOGRAPH-FA4C +3233 ; [*02FB.0020.0004.3233][.FB40.0020.0004.793E][.F93E.0000.0000.793E][*02FC.0020.001F.3233] # PARENTHESIZED IDEOGRAPH SOCIETY +3293 ; [.FB40.0020.0006.793E][.F93E.0000.0000.793E] # CIRCLED IDEOGRAPH SOCIETY +FA4E ; [.FB40.0020.0002.7948][.F948.0000.0000.7948] # CJK COMPATIBILITY IDEOGRAPH-FA4E +FA4D ; [.FB40.0020.0002.7949][.F949.0000.0000.7949] # CJK COMPATIBILITY IDEOGRAPH-FA4D +FA4F ; [.FB40.0020.0002.7950][.F950.0000.0000.7950] # CJK COMPATIBILITY IDEOGRAPH-FA4F +FA50 ; [.FB40.0020.0002.7956][.F956.0000.0000.7956] # CJK COMPATIBILITY IDEOGRAPH-FA50 +2F953 ; [.FB40.0020.0002.7956][.F956.0000.0000.7956] # CJK COMPATIBILITY IDEOGRAPH-2F953 +FA51 ; [.FB40.0020.0002.795D][.F95D.0000.0000.795D] # CJK COMPATIBILITY IDEOGRAPH-FA51 +3237 ; [*02FB.0020.0004.3237][.FB40.0020.0004.795D][.F95D.0000.0000.795D][*02FC.0020.001F.3237] # PARENTHESIZED IDEOGRAPH CONGRATULATION +3297 ; [.FB40.0020.0006.795D][.F95D.0000.0000.795D] # CIRCLED IDEOGRAPH CONGRATULATION +FA19 ; [.FB40.0020.0002.795E][.F95E.0000.0000.795E] # CJK COMPATIBILITY IDEOGRAPH-FA19 +FA1A ; [.FB40.0020.0002.7965][.F965.0000.0000.7965] # CJK COMPATIBILITY IDEOGRAPH-FA1A +3240 ; [*02FB.0020.0004.3240][.FB40.0020.0004.796D][.F96D.0000.0000.796D][*02FC.0020.001F.3240] # PARENTHESIZED IDEOGRAPH FESTIVAL +F93C ; [.FB40.0020.0002.797F][.F97F.0000.0000.797F] # CJK COMPATIBILITY IDEOGRAPH-F93C +1F232 ; [.FB40.0020.001C.7981][.F981.0000.0000.7981] # SQUARED CJK UNIFIED IDEOGRAPH-7981 +FA52 ; [.FB40.0020.0002.798D][.F98D.0000.0000.798D] # CJK COMPATIBILITY IDEOGRAPH-FA52 +FA53 ; [.FB40.0020.0002.798E][.F98E.0000.0000.798E] # CJK COMPATIBILITY IDEOGRAPH-FA53 +FA1B ; [.FB40.0020.0002.798F][.F98F.0000.0000.798F] # CJK COMPATIBILITY IDEOGRAPH-FA1B +2F956 ; [.FB40.0020.0002.798F][.F98F.0000.0000.798F] # CJK COMPATIBILITY IDEOGRAPH-2F956 +F9B6 ; [.FB40.0020.0002.79AE][.F9AE.0000.0000.79AE] # CJK COMPATIBILITY IDEOGRAPH-F9B6 +2F71 ; [.FB40.0020.0004.79B8][.F9B8.0000.0000.79B8] # KANGXI RADICAL TRACK +2F72 ; [.FB40.0020.0004.79BE][.F9BE.0000.0000.79BE] # KANGXI RADICAL GRAIN +F995 ; [.FB40.0020.0002.79CA][.F9CA.0000.0000.79CA] # CJK COMPATIBILITY IDEOGRAPH-F995 +3299 ; [.FB40.0020.0006.79D8][.F9D8.0000.0000.79D8] # CIRCLED IDEOGRAPH SECRET +2F957 ; [.FB40.0020.0002.79EB][.F9EB.0000.0000.79EB] # CJK COMPATIBILITY IDEOGRAPH-2F957 +F956 ; [.FB40.0020.0002.7A1C][.FA1C.0000.0000.7A1C] # CJK COMPATIBILITY IDEOGRAPH-F956 +FA54 ; [.FB40.0020.0002.7A40][.FA40.0000.0000.7A40] # CJK COMPATIBILITY IDEOGRAPH-FA54 +2F959 ; [.FB40.0020.0002.7A40][.FA40.0000.0000.7A40] # CJK COMPATIBILITY IDEOGRAPH-2F959 +2F95A ; [.FB40.0020.0002.7A4A][.FA4A.0000.0000.7A4A] # CJK COMPATIBILITY IDEOGRAPH-2F95A +2F95B ; [.FB40.0020.0002.7A4F][.FA4F.0000.0000.7A4F] # CJK COMPATIBILITY IDEOGRAPH-2F95B +2F73 ; [.FB40.0020.0004.7A74][.FA74.0000.0000.7A74] # KANGXI RADICAL CAVE +1F233 ; [.FB40.0020.001C.7A7A][.FA7A.0000.0000.7A7A] # SQUARED CJK UNIFIED IDEOGRAPH-7A7A +FA55 ; [.FB40.0020.0002.7A81][.FA81.0000.0000.7A81] # CJK COMPATIBILITY IDEOGRAPH-FA55 +FAAC ; [.FB40.0020.0002.7AB1][.FAB1.0000.0000.7AB1] # CJK COMPATIBILITY IDEOGRAPH-FAAC +F9F7 ; [.FB40.0020.0002.7ACB][.FACB.0000.0000.7ACB] # CJK COMPATIBILITY IDEOGRAPH-F9F7 +2F74 ; [.FB40.0020.0004.7ACB][.FACB.0000.0000.7ACB] # KANGXI RADICAL STAND +2F95F ; [.FB40.0020.0002.7AEE][.FAEE.0000.0000.7AEE] # CJK COMPATIBILITY IDEOGRAPH-2F95F +2F75 ; [.FB40.0020.0004.7AF9][.FAF9.0000.0000.7AF9] # KANGXI RADICAL BAMBOO +2EAE ; [.FB40.0020.0004.7AF9][.FAF9.0000.0000.7AF9][.0000.0139.001F.2EAE] # CJK RADICAL BAMBOO +F9F8 ; [.FB40.0020.0002.7B20][.FB20.0000.0000.7B20] # CJK COMPATIBILITY IDEOGRAPH-F9F8 +3247 ; [.FB40.0020.0006.7B8F][.FB8F.0000.0000.7B8F] # CIRCLED IDEOGRAPH KOTO +FA56 ; [.FB40.0020.0002.7BC0][.FBC0.0000.0000.7BC0] # CJK COMPATIBILITY IDEOGRAPH-FA56 +FAAD ; [.FB40.0020.0002.7BC0][.FBC0.0000.0000.7BC0] # CJK COMPATIBILITY IDEOGRAPH-FAAD +2F962 ; [.FB40.0020.0002.7BC6][.FBC6.0000.0000.7BC6] # CJK COMPATIBILITY IDEOGRAPH-2F962 +2F963 ; [.FB40.0020.0002.7BC9][.FBC9.0000.0000.7BC9] # CJK COMPATIBILITY IDEOGRAPH-2F963 +F9A6 ; [.FB40.0020.0002.7C3E][.FC3E.0000.0000.7C3E] # CJK COMPATIBILITY IDEOGRAPH-F9A6 +F944 ; [.FB40.0020.0002.7C60][.FC60.0000.0000.7C60] # CJK COMPATIBILITY IDEOGRAPH-F944 +2F76 ; [.FB40.0020.0004.7C73][.FC73.0000.0000.7C73] # KANGXI RADICAL RICE +FAAE ; [.FB40.0020.0002.7C7B][.FC7B.0000.0000.7C7B] # CJK COMPATIBILITY IDEOGRAPH-FAAE +F9F9 ; [.FB40.0020.0002.7C92][.FC92.0000.0000.7C92] # CJK COMPATIBILITY IDEOGRAPH-F9F9 +FA1D ; [.FB40.0020.0002.7CBE][.FCBE.0000.0000.7CBE] # CJK COMPATIBILITY IDEOGRAPH-FA1D +2F966 ; [.FB40.0020.0002.7CD2][.FCD2.0000.0000.7CD2] # CJK COMPATIBILITY IDEOGRAPH-2F966 +FA03 ; [.FB40.0020.0002.7CD6][.FCD6.0000.0000.7CD6] # CJK COMPATIBILITY IDEOGRAPH-FA03 +2F969 ; [.FB40.0020.0002.7CE3][.FCE3.0000.0000.7CE3] # CJK COMPATIBILITY IDEOGRAPH-2F969 +F97B ; [.FB40.0020.0002.7CE7][.FCE7.0000.0000.7CE7] # CJK COMPATIBILITY IDEOGRAPH-F97B +2F968 ; [.FB40.0020.0002.7CE8][.FCE8.0000.0000.7CE8] # CJK COMPATIBILITY IDEOGRAPH-2F968 +2F77 ; [.FB40.0020.0004.7CF8][.FCF8.0000.0000.7CF8] # KANGXI RADICAL SILK +2EAF ; [.FB40.0020.0004.7CF9][.FCF9.0000.0000.7CF9] # CJK RADICAL SILK +2F96A ; [.FB40.0020.0002.7D00][.FD00.0000.0000.7D00] # CJK COMPATIBILITY IDEOGRAPH-2F96A +F9CF ; [.FB40.0020.0002.7D10][.FD10.0000.0000.7D10] # CJK COMPATIBILITY IDEOGRAPH-F9CF +F96A ; [.FB40.0020.0002.7D22][.FD22.0000.0000.7D22] # CJK COMPATIBILITY IDEOGRAPH-F96A +F94F ; [.FB40.0020.0002.7D2F][.FD2F.0000.0000.7D2F] # CJK COMPATIBILITY IDEOGRAPH-F94F +1F221 ; [.FB40.0020.001C.7D42][.FD42.0000.0000.7D42] # SQUARED CJK UNIFIED IDEOGRAPH-7D42 +FAAF ; [.FB40.0020.0002.7D5B][.FD5B.0000.0000.7D5B] # CJK COMPATIBILITY IDEOGRAPH-FAAF +2F96C ; [.FB40.0020.0002.7D63][.FD63.0000.0000.7D63] # CJK COMPATIBILITY IDEOGRAPH-2F96C +F93D ; [.FB40.0020.0002.7DA0][.FDA0.0000.0000.7DA0] # CJK COMPATIBILITY IDEOGRAPH-F93D +F957 ; [.FB40.0020.0002.7DBE][.FDBE.0000.0000.7DBE] # CJK COMPATIBILITY IDEOGRAPH-F957 +2F96E ; [.FB40.0020.0002.7DC7][.FDC7.0000.0000.7DC7] # CJK COMPATIBILITY IDEOGRAPH-2F96E +F996 ; [.FB40.0020.0002.7DF4][.FDF4.0000.0000.7DF4] # CJK COMPATIBILITY IDEOGRAPH-F996 +FA57 ; [.FB40.0020.0002.7DF4][.FDF4.0000.0000.7DF4] # CJK COMPATIBILITY IDEOGRAPH-FA57 +FAB0 ; [.FB40.0020.0002.7DF4][.FDF4.0000.0000.7DF4] # CJK COMPATIBILITY IDEOGRAPH-FAB0 +2F96F ; [.FB40.0020.0002.7E02][.FE02.0000.0000.7E02] # CJK COMPATIBILITY IDEOGRAPH-2F96F +FA58 ; [.FB40.0020.0002.7E09][.FE09.0000.0000.7E09] # CJK COMPATIBILITY IDEOGRAPH-FA58 +F950 ; [.FB40.0020.0002.7E37][.FE37.0000.0000.7E37] # CJK COMPATIBILITY IDEOGRAPH-F950 +FA59 ; [.FB40.0020.0002.7E41][.FE41.0000.0000.7E41] # CJK COMPATIBILITY IDEOGRAPH-FA59 +2F970 ; [.FB40.0020.0002.7E45][.FE45.0000.0000.7E45] # CJK COMPATIBILITY IDEOGRAPH-2F970 +2EB0 ; [.FB40.0020.0004.7E9F][.FE9F.0000.0000.7E9F] # CJK RADICAL C-SIMPLIFIED SILK +2F78 ; [.FB40.0020.0004.7F36][.FF36.0000.0000.7F36] # KANGXI RADICAL JAR +FAB1 ; [.FB40.0020.0002.7F3E][.FF3E.0000.0000.7F3E] # CJK COMPATIBILITY IDEOGRAPH-FAB1 +2F79 ; [.FB40.0020.0004.7F51][.FF51.0000.0000.7F51] # KANGXI RADICAL NET +2EB2 ; [.FB40.0020.0004.7F52][.FF52.0000.0000.7F52] # CJK RADICAL NET TWO +2EB5 ; [.FB40.0020.0004.7F52][.FF52.0000.0000.7F52][.0000.0139.001F.2EB5] # CJK RADICAL MESH +2EB1 ; [.FB40.0020.0004.7F53][.FF53.0000.0000.7F53] # CJK RADICAL NET ONE +2EB3 ; [.FB40.0020.0004.7F53][.FF53.0000.0000.7F53][.0000.0139.001F.2EB3] # CJK RADICAL NET THREE +2EB4 ; [.FB40.0020.0004.7F53][.FF53.0000.0000.7F53][.0000.013A.001F.2EB4] # CJK RADICAL NET FOUR +FA5A ; [.FB40.0020.0002.7F72][.FF72.0000.0000.7F72] # CJK COMPATIBILITY IDEOGRAPH-FA5A +F9E6 ; [.FB40.0020.0002.7F79][.FF79.0000.0000.7F79] # CJK COMPATIBILITY IDEOGRAPH-F9E6 +2F976 ; [.FB40.0020.0002.7F7A][.FF7A.0000.0000.7F7A] # CJK COMPATIBILITY IDEOGRAPH-2F976 +F90F ; [.FB40.0020.0002.7F85][.FF85.0000.0000.7F85] # CJK COMPATIBILITY IDEOGRAPH-F90F +2F7A ; [.FB40.0020.0004.7F8A][.FF8A.0000.0000.7F8A] # KANGXI RADICAL SHEEP +2EB6 ; [.FB40.0020.0004.7F8A][.FF8A.0000.0000.7F8A][.0000.0139.001F.2EB6] # CJK RADICAL SHEEP +2EB7 ; [.FB40.0020.0004.7F8A][.FF8A.0000.0000.7F8A][.0000.013A.001F.2EB7] # CJK RADICAL RAM +2EB8 ; [.FB40.0020.0004.7F8B][.FF8B.0000.0000.7F8B] # CJK RADICAL EWE +2F978 ; [.FB40.0020.0002.7F95][.FF95.0000.0000.7F95] # CJK COMPATIBILITY IDEOGRAPH-2F978 +F9AF ; [.FB40.0020.0002.7F9A][.FF9A.0000.0000.7F9A] # CJK COMPATIBILITY IDEOGRAPH-F9AF +FA1E ; [.FB40.0020.0002.7FBD][.FFBD.0000.0000.7FBD] # CJK COMPATIBILITY IDEOGRAPH-FA1E +2F7B ; [.FB40.0020.0004.7FBD][.FFBD.0000.0000.7FBD] # KANGXI RADICAL FEATHER +2F979 ; [.FB40.0020.0002.7FFA][.FFFA.0000.0000.7FFA] # CJK COMPATIBILITY IDEOGRAPH-2F979 +F934 ; [.FB41.0020.0002.8001][.8001.0000.0000.8001] # CJK COMPATIBILITY IDEOGRAPH-F934 +2F7C ; [.FB41.0020.0004.8001][.8001.0000.0000.8001] # KANGXI RADICAL OLD +2EB9 ; [.FB41.0020.0004.8002][.8002.0000.0000.8002] # CJK RADICAL OLD +FA5B ; [.FB41.0020.0002.8005][.8005.0000.0000.8005] # CJK COMPATIBILITY IDEOGRAPH-FA5B +FAB2 ; [.FB41.0020.0002.8005][.8005.0000.0000.8005] # CJK COMPATIBILITY IDEOGRAPH-FAB2 +2F97A ; [.FB41.0020.0002.8005][.8005.0000.0000.8005] # CJK COMPATIBILITY IDEOGRAPH-2F97A +2F7D ; [.FB41.0020.0004.800C][.800C.0000.0000.800C] # KANGXI RADICAL AND +2F7E ; [.FB41.0020.0004.8012][.8012.0000.0000.8012] # KANGXI RADICAL PLOW +2F7F ; [.FB41.0020.0004.8033][.8033.0000.0000.8033] # KANGXI RADICAL EAR +F9B0 ; [.FB41.0020.0002.8046][.8046.0000.0000.8046] # CJK COMPATIBILITY IDEOGRAPH-F9B0 +2F97D ; [.FB41.0020.0002.8060][.8060.0000.0000.8060] # CJK COMPATIBILITY IDEOGRAPH-2F97D +F997 ; [.FB41.0020.0002.806F][.806F.0000.0000.806F] # CJK COMPATIBILITY IDEOGRAPH-F997 +2F97F ; [.FB41.0020.0002.8070][.8070.0000.0000.8070] # CJK COMPATIBILITY IDEOGRAPH-2F97F +F945 ; [.FB41.0020.0002.807E][.807E.0000.0000.807E] # CJK COMPATIBILITY IDEOGRAPH-F945 +2F80 ; [.FB41.0020.0004.807F][.807F.0000.0000.807F] # KANGXI RADICAL BRUSH +2EBB ; [.FB41.0020.0004.807F][.807F.0000.0000.807F][.0000.0139.001F.2EBB] # CJK RADICAL BRUSH TWO +2EBA ; [.FB41.0020.0004.8080][.8080.0000.0000.8080] # CJK RADICAL BRUSH ONE +2F81 ; [.FB41.0020.0004.8089][.8089.0000.0000.8089] # KANGXI RADICAL MEAT +2EBC ; [.FB41.0020.0004.8089][.8089.0000.0000.8089][.0000.0139.001F.2EBC] # CJK RADICAL MEAT +F953 ; [.FB41.0020.0002.808B][.808B.0000.0000.808B] # CJK COMPATIBILITY IDEOGRAPH-F953 +2F8D6 ; [.FB41.0020.0002.80AD][.80AD.0000.0000.80AD] # CJK COMPATIBILITY IDEOGRAPH-2F8D6 +2F982 ; [.FB41.0020.0002.80B2][.80B2.0000.0000.80B2] # CJK COMPATIBILITY IDEOGRAPH-2F982 +2F983 ; [.FB41.0020.0002.8103][.8103.0000.0000.8103] # CJK COMPATIBILITY IDEOGRAPH-2F983 +2F985 ; [.FB41.0020.0002.813E][.813E.0000.0000.813E] # CJK COMPATIBILITY IDEOGRAPH-2F985 +F926 ; [.FB41.0020.0002.81D8][.81D8.0000.0000.81D8] # CJK COMPATIBILITY IDEOGRAPH-F926 +2F82 ; [.FB41.0020.0004.81E3][.81E3.0000.0000.81E3] # KANGXI RADICAL MINISTER +F9F6 ; [.FB41.0020.0002.81E8][.81E8.0000.0000.81E8] # CJK COMPATIBILITY IDEOGRAPH-F9F6 +2F83 ; [.FB41.0020.0004.81EA][.81EA.0000.0000.81EA] # KANGXI RADICAL SELF +3242 ; [*02FB.0020.0004.3242][.FB41.0020.0004.81EA][.81EA.0000.0000.81EA][*02FC.0020.001F.3242] # PARENTHESIZED IDEOGRAPH SELF +FA5C ; [.FB41.0020.0002.81ED][.81ED.0000.0000.81ED] # CJK COMPATIBILITY IDEOGRAPH-FA5C +2F84 ; [.FB41.0020.0004.81F3][.81F3.0000.0000.81F3] # KANGXI RADICAL ARRIVE +3243 ; [*02FB.0020.0004.3243][.FB41.0020.0004.81F3][.81F3.0000.0000.81F3][*02FC.0020.001F.3243] # PARENTHESIZED IDEOGRAPH REACH +2F85 ; [.FB41.0020.0004.81FC][.81FC.0000.0000.81FC] # KANGXI RADICAL MORTAR +2EBD ; [.FB41.0020.0004.81FC][.81FC.0000.0000.81FC][.0000.0139.001F.2EBD] # CJK RADICAL MORTAR +2F893 ; [.FB41.0020.0002.8201][.8201.0000.0000.8201] # CJK COMPATIBILITY IDEOGRAPH-2F893 +2F98B ; [.FB41.0020.0002.8201][.8201.0000.0000.8201] # CJK COMPATIBILITY IDEOGRAPH-2F98B +2F98C ; [.FB41.0020.0002.8204][.8204.0000.0000.8204] # CJK COMPATIBILITY IDEOGRAPH-2F98C +2F86 ; [.FB41.0020.0004.820C][.820C.0000.0000.820C] # KANGXI RADICAL TONGUE +FA6D ; [.FB41.0020.0002.8218][.8218.0000.0000.8218] # CJK COMPATIBILITY IDEOGRAPH-FA6D +2F87 ; [.FB41.0020.0004.821B][.821B.0000.0000.821B] # KANGXI RADICAL OPPOSE +2F88 ; [.FB41.0020.0004.821F][.821F.0000.0000.821F] # KANGXI RADICAL BOAT +2F89 ; [.FB41.0020.0004.826E][.826E.0000.0000.826E] # KANGXI RADICAL STOPPING +F97C ; [.FB41.0020.0002.826F][.826F.0000.0000.826F] # CJK COMPATIBILITY IDEOGRAPH-F97C +2F8A ; [.FB41.0020.0004.8272][.8272.0000.0000.8272] # KANGXI RADICAL COLOR +2F8B ; [.FB41.0020.0004.8278][.8278.0000.0000.8278] # KANGXI RADICAL GRASS +FA5D ; [.FB41.0020.0002.8279][.8279.0000.0000.8279] # CJK COMPATIBILITY IDEOGRAPH-FA5D +FA5E ; [.FB41.0020.0002.8279][.8279.0000.0000.8279] # CJK COMPATIBILITY IDEOGRAPH-FA5E +2EBE ; [.FB41.0020.0004.8279][.8279.0000.0000.8279] # CJK RADICAL GRASS ONE +2EBF ; [.FB41.0020.0004.8279][.8279.0000.0000.8279][.0000.0139.001F.2EBF] # CJK RADICAL GRASS TWO +2EC0 ; [.FB41.0020.0004.8279][.8279.0000.0000.8279][.0000.013A.001F.2EC0] # CJK RADICAL GRASS THREE +2F990 ; [.FB41.0020.0002.828B][.828B.0000.0000.828B] # CJK COMPATIBILITY IDEOGRAPH-2F990 +2F98F ; [.FB41.0020.0002.8291][.8291.0000.0000.8291] # CJK COMPATIBILITY IDEOGRAPH-2F98F +2F991 ; [.FB41.0020.0002.829D][.829D.0000.0000.829D] # CJK COMPATIBILITY IDEOGRAPH-2F991 +2F993 ; [.FB41.0020.0002.82B1][.82B1.0000.0000.82B1] # CJK COMPATIBILITY IDEOGRAPH-2F993 +2F994 ; [.FB41.0020.0002.82B3][.82B3.0000.0000.82B3] # CJK COMPATIBILITY IDEOGRAPH-2F994 +2F995 ; [.FB41.0020.0002.82BD][.82BD.0000.0000.82BD] # CJK COMPATIBILITY IDEOGRAPH-2F995 +F974 ; [.FB41.0020.0002.82E5][.82E5.0000.0000.82E5] # CJK COMPATIBILITY IDEOGRAPH-F974 +2F998 ; [.FB41.0020.0002.82E5][.82E5.0000.0000.82E5] # CJK COMPATIBILITY IDEOGRAPH-2F998 +2F996 ; [.FB41.0020.0002.82E6][.82E6.0000.0000.82E6] # CJK COMPATIBILITY IDEOGRAPH-2F996 +2F999 ; [.FB41.0020.0002.831D][.831D.0000.0000.831D] # CJK COMPATIBILITY IDEOGRAPH-2F999 +2F99C ; [.FB41.0020.0002.8323][.8323.0000.0000.8323] # CJK COMPATIBILITY IDEOGRAPH-2F99C +F9FE ; [.FB41.0020.0002.8336][.8336.0000.0000.8336] # CJK COMPATIBILITY IDEOGRAPH-F9FE +FAB3 ; [.FB41.0020.0002.8352][.8352.0000.0000.8352] # CJK COMPATIBILITY IDEOGRAPH-FAB3 +2F9A0 ; [.FB41.0020.0002.8353][.8353.0000.0000.8353] # CJK COMPATIBILITY IDEOGRAPH-2F9A0 +2F99A ; [.FB41.0020.0002.8363][.8363.0000.0000.8363] # CJK COMPATIBILITY IDEOGRAPH-2F99A +2F99B ; [.FB41.0020.0002.83AD][.83AD.0000.0000.83AD] # CJK COMPATIBILITY IDEOGRAPH-2F99B +2F99D ; [.FB41.0020.0002.83BD][.83BD.0000.0000.83BD] # CJK COMPATIBILITY IDEOGRAPH-2F99D +F93E ; [.FB41.0020.0002.83C9][.83C9.0000.0000.83C9] # CJK COMPATIBILITY IDEOGRAPH-F93E +2F9A1 ; [.FB41.0020.0002.83CA][.83CA.0000.0000.83CA] # CJK COMPATIBILITY IDEOGRAPH-2F9A1 +2F9A2 ; [.FB41.0020.0002.83CC][.83CC.0000.0000.83CC] # CJK COMPATIBILITY IDEOGRAPH-2F9A2 +2F9A3 ; [.FB41.0020.0002.83DC][.83DC.0000.0000.83DC] # CJK COMPATIBILITY IDEOGRAPH-2F9A3 +2F99E ; [.FB41.0020.0002.83E7][.83E7.0000.0000.83E7] # CJK COMPATIBILITY IDEOGRAPH-2F99E +FAB4 ; [.FB41.0020.0002.83EF][.83EF.0000.0000.83EF] # CJK COMPATIBILITY IDEOGRAPH-FAB4 +F958 ; [.FB41.0020.0002.83F1][.83F1.0000.0000.83F1] # CJK COMPATIBILITY IDEOGRAPH-F958 +F918 ; [.FB41.0020.0002.843D][.843D.0000.0000.843D] # CJK COMPATIBILITY IDEOGRAPH-F918 +F96E ; [.FB41.0020.0002.8449][.8449.0000.0000.8449] # CJK COMPATIBILITY IDEOGRAPH-F96E +FA5F ; [.FB41.0020.0002.8457][.8457.0000.0000.8457] # CJK COMPATIBILITY IDEOGRAPH-FA5F +2F99F ; [.FB41.0020.0002.8457][.8457.0000.0000.8457] # CJK COMPATIBILITY IDEOGRAPH-2F99F +F999 ; [.FB41.0020.0002.84EE][.84EE.0000.0000.84EE] # CJK COMPATIBILITY IDEOGRAPH-F999 +2F9A8 ; [.FB41.0020.0002.84F1][.84F1.0000.0000.84F1] # CJK COMPATIBILITY IDEOGRAPH-2F9A8 +2F9A9 ; [.FB41.0020.0002.84F3][.84F3.0000.0000.84F3] # CJK COMPATIBILITY IDEOGRAPH-2F9A9 +F9C2 ; [.FB41.0020.0002.84FC][.84FC.0000.0000.84FC] # CJK COMPATIBILITY IDEOGRAPH-F9C2 +2F9AA ; [.FB41.0020.0002.8516][.8516.0000.0000.8516] # CJK COMPATIBILITY IDEOGRAPH-2F9AA +2F9AC ; [.FB41.0020.0002.8564][.8564.0000.0000.8564] # CJK COMPATIBILITY IDEOGRAPH-2F9AC +F923 ; [.FB41.0020.0002.85CD][.85CD.0000.0000.85CD] # CJK COMPATIBILITY IDEOGRAPH-F923 +F9F0 ; [.FB41.0020.0002.85FA][.85FA.0000.0000.85FA] # CJK COMPATIBILITY IDEOGRAPH-F9F0 +F935 ; [.FB41.0020.0002.8606][.8606.0000.0000.8606] # CJK COMPATIBILITY IDEOGRAPH-F935 +FA20 ; [.FB41.0020.0002.8612][.8612.0000.0000.8612] # CJK COMPATIBILITY IDEOGRAPH-FA20 +F91F ; [.FB41.0020.0002.862D][.862D.0000.0000.862D] # CJK COMPATIBILITY IDEOGRAPH-F91F +F910 ; [.FB41.0020.0002.863F][.863F.0000.0000.863F] # CJK COMPATIBILITY IDEOGRAPH-F910 +2F8C ; [.FB41.0020.0004.864D][.864D.0000.0000.864D] # KANGXI RADICAL TIGER +2EC1 ; [.FB41.0020.0004.864E][.864E.0000.0000.864E] # CJK RADICAL TIGER +2F9B3 ; [.FB41.0020.0002.8650][.8650.0000.0000.8650] # CJK COMPATIBILITY IDEOGRAPH-2F9B3 +F936 ; [.FB41.0020.0002.865C][.865C.0000.0000.865C] # CJK COMPATIBILITY IDEOGRAPH-F936 +2F9B4 ; [.FB41.0020.0002.865C][.865C.0000.0000.865C] # CJK COMPATIBILITY IDEOGRAPH-2F9B4 +2F9B5 ; [.FB41.0020.0002.8667][.8667.0000.0000.8667] # CJK COMPATIBILITY IDEOGRAPH-2F9B5 +2F9B6 ; [.FB41.0020.0002.8669][.8669.0000.0000.8669] # CJK COMPATIBILITY IDEOGRAPH-2F9B6 +2F8D ; [.FB41.0020.0004.866B][.866B.0000.0000.866B] # KANGXI RADICAL INSECT +2F9B8 ; [.FB41.0020.0002.8688][.8688.0000.0000.8688] # CJK COMPATIBILITY IDEOGRAPH-2F9B8 +2F9B7 ; [.FB41.0020.0002.86A9][.86A9.0000.0000.86A9] # CJK COMPATIBILITY IDEOGRAPH-2F9B7 +2F9BA ; [.FB41.0020.0002.86E2][.86E2.0000.0000.86E2] # CJK COMPATIBILITY IDEOGRAPH-2F9BA +2F9B9 ; [.FB41.0020.0002.870E][.870E.0000.0000.870E] # CJK COMPATIBILITY IDEOGRAPH-2F9B9 +2F9BC ; [.FB41.0020.0002.8728][.8728.0000.0000.8728] # CJK COMPATIBILITY IDEOGRAPH-2F9BC +2F9BD ; [.FB41.0020.0002.876B][.876B.0000.0000.876B] # CJK COMPATIBILITY IDEOGRAPH-2F9BD +FAB5 ; [.FB41.0020.0002.8779][.8779.0000.0000.8779] # CJK COMPATIBILITY IDEOGRAPH-FAB5 +2F9BB ; [.FB41.0020.0002.8779][.8779.0000.0000.8779] # CJK COMPATIBILITY IDEOGRAPH-2F9BB +2F9BE ; [.FB41.0020.0002.8786][.8786.0000.0000.8786] # CJK COMPATIBILITY IDEOGRAPH-2F9BE +F911 ; [.FB41.0020.0002.87BA][.87BA.0000.0000.87BA] # CJK COMPATIBILITY IDEOGRAPH-F911 +2F9C0 ; [.FB41.0020.0002.87E1][.87E1.0000.0000.87E1] # CJK COMPATIBILITY IDEOGRAPH-2F9C0 +2F9C1 ; [.FB41.0020.0002.8801][.8801.0000.0000.8801] # CJK COMPATIBILITY IDEOGRAPH-2F9C1 +F927 ; [.FB41.0020.0002.881F][.881F.0000.0000.881F] # CJK COMPATIBILITY IDEOGRAPH-F927 +2F8E ; [.FB41.0020.0004.8840][.8840.0000.0000.8840] # KANGXI RADICAL BLOOD +FA08 ; [.FB41.0020.0002.884C][.884C.0000.0000.884C] # CJK COMPATIBILITY IDEOGRAPH-FA08 +2F8F ; [.FB41.0020.0004.884C][.884C.0000.0000.884C] # KANGXI RADICAL WALK ENCLOSURE +2F9C3 ; [.FB41.0020.0002.8860][.8860.0000.0000.8860] # CJK COMPATIBILITY IDEOGRAPH-2F9C3 +2F9C4 ; [.FB41.0020.0002.8863][.8863.0000.0000.8863] # CJK COMPATIBILITY IDEOGRAPH-2F9C4 +2F90 ; [.FB41.0020.0004.8863][.8863.0000.0000.8863] # KANGXI RADICAL CLOTHES +2EC2 ; [.FB41.0020.0004.8864][.8864.0000.0000.8864] # CJK RADICAL CLOTHES +F9A0 ; [.FB41.0020.0002.88C2][.88C2.0000.0000.88C2] # CJK COMPATIBILITY IDEOGRAPH-F9A0 +F9E7 ; [.FB41.0020.0002.88CF][.88CF.0000.0000.88CF] # CJK COMPATIBILITY IDEOGRAPH-F9E7 +2F9C6 ; [.FB41.0020.0002.88D7][.88D7.0000.0000.88D7] # CJK COMPATIBILITY IDEOGRAPH-2F9C6 +2F9C7 ; [.FB41.0020.0002.88DE][.88DE.0000.0000.88DE] # CJK COMPATIBILITY IDEOGRAPH-2F9C7 +F9E8 ; [.FB41.0020.0002.88E1][.88E1.0000.0000.88E1] # CJK COMPATIBILITY IDEOGRAPH-F9E8 +F912 ; [.FB41.0020.0002.88F8][.88F8.0000.0000.88F8] # CJK COMPATIBILITY IDEOGRAPH-F912 +2F9C9 ; [.FB41.0020.0002.88FA][.88FA.0000.0000.88FA] # CJK COMPATIBILITY IDEOGRAPH-2F9C9 +FA60 ; [.FB41.0020.0002.8910][.8910.0000.0000.8910] # CJK COMPATIBILITY IDEOGRAPH-FA60 +FAB6 ; [.FB41.0020.0002.8941][.8941.0000.0000.8941] # CJK COMPATIBILITY IDEOGRAPH-FAB6 +F924 ; [.FB41.0020.0002.8964][.8964.0000.0000.8964] # CJK COMPATIBILITY IDEOGRAPH-F924 +2F91 ; [.FB41.0020.0004.897E][.897E.0000.0000.897E] # KANGXI RADICAL WEST +2EC4 ; [.FB41.0020.0004.897F][.897F.0000.0000.897F] # CJK RADICAL WEST TWO +2EC3 ; [.FB41.0020.0004.8980][.8980.0000.0000.8980] # CJK RADICAL WEST ONE +FAB7 ; [.FB41.0020.0002.8986][.8986.0000.0000.8986] # CJK COMPATIBILITY IDEOGRAPH-FAB7 +FA0A ; [.FB41.0020.0002.898B][.898B.0000.0000.898B] # CJK COMPATIBILITY IDEOGRAPH-FA0A +2F92 ; [.FB41.0020.0004.898B][.898B.0000.0000.898B] # KANGXI RADICAL SEE +FA61 ; [.FB41.0020.0002.8996][.8996.0000.0000.8996] # CJK COMPATIBILITY IDEOGRAPH-FA61 +FAB8 ; [.FB41.0020.0002.8996][.8996.0000.0000.8996] # CJK COMPATIBILITY IDEOGRAPH-FAB8 +2EC5 ; [.FB41.0020.0004.89C1][.89C1.0000.0000.89C1] # CJK RADICAL C-SIMPLIFIED SEE +2EC6 ; [.FB41.0020.0004.89D2][.89D2.0000.0000.89D2] # CJK RADICAL SIMPLIFIED HORN +2F93 ; [.FB41.0020.0004.89D2][.89D2.0000.0000.89D2] # KANGXI RADICAL HORN +2EC7 ; [.FB41.0020.0004.89D2][.89D2.0000.0000.89D2][.0000.0139.001F.2EC7] # CJK RADICAL HORN +1F216 ; [.FB41.0020.001C.89E3][.89E3.0000.0000.89E3] # SQUARED CJK UNIFIED IDEOGRAPH-89E3 +2F94 ; [.FB41.0020.0004.8A00][.8A00.0000.0000.8A00] # KANGXI RADICAL SPEECH +2F9CF ; [.FB41.0020.0002.8AA0][.8AA0.0000.0000.8AA0] # CJK COMPATIBILITY IDEOGRAPH-2F9CF +F96F ; [.FB41.0020.0002.8AAA][.8AAA.0000.0000.8AAA] # CJK COMPATIBILITY IDEOGRAPH-F96F +F9A1 ; [.FB41.0020.0002.8AAA][.8AAA.0000.0000.8AAA] # CJK COMPATIBILITY IDEOGRAPH-F9A1 +FAB9 ; [.FB41.0020.0002.8ABF][.8ABF.0000.0000.8ABF] # CJK COMPATIBILITY IDEOGRAPH-FAB9 +FABB ; [.FB41.0020.0002.8ACB][.8ACB.0000.0000.8ACB] # CJK COMPATIBILITY IDEOGRAPH-FABB +F97D ; [.FB41.0020.0002.8AD2][.8AD2.0000.0000.8AD2] # CJK COMPATIBILITY IDEOGRAPH-F97D +F941 ; [.FB41.0020.0002.8AD6][.8AD6.0000.0000.8AD6] # CJK COMPATIBILITY IDEOGRAPH-F941 +FABE ; [.FB41.0020.0002.8AED][.8AED.0000.0000.8AED] # CJK COMPATIBILITY IDEOGRAPH-FABE +2F9D0 ; [.FB41.0020.0002.8AED][.8AED.0000.0000.8AED] # CJK COMPATIBILITY IDEOGRAPH-2F9D0 +FA22 ; [.FB41.0020.0002.8AF8][.8AF8.0000.0000.8AF8] # CJK COMPATIBILITY IDEOGRAPH-FA22 +FABA ; [.FB41.0020.0002.8AF8][.8AF8.0000.0000.8AF8] # CJK COMPATIBILITY IDEOGRAPH-FABA +F95D ; [.FB41.0020.0002.8AFE][.8AFE.0000.0000.8AFE] # CJK COMPATIBILITY IDEOGRAPH-F95D +FABD ; [.FB41.0020.0002.8AFE][.8AFE.0000.0000.8AFE] # CJK COMPATIBILITY IDEOGRAPH-FABD +FA62 ; [.FB41.0020.0002.8B01][.8B01.0000.0000.8B01] # CJK COMPATIBILITY IDEOGRAPH-FA62 +FABC ; [.FB41.0020.0002.8B01][.8B01.0000.0000.8B01] # CJK COMPATIBILITY IDEOGRAPH-FABC +FA63 ; [.FB41.0020.0002.8B39][.8B39.0000.0000.8B39] # CJK COMPATIBILITY IDEOGRAPH-FA63 +FABF ; [.FB41.0020.0002.8B39][.8B39.0000.0000.8B39] # CJK COMPATIBILITY IDEOGRAPH-FABF +F9FC ; [.FB41.0020.0002.8B58][.8B58.0000.0000.8B58] # CJK COMPATIBILITY IDEOGRAPH-F9FC +F95A ; [.FB41.0020.0002.8B80][.8B80.0000.0000.8B80] # CJK COMPATIBILITY IDEOGRAPH-F95A +FAC0 ; [.FB41.0020.0002.8B8A][.8B8A.0000.0000.8B8A] # CJK COMPATIBILITY IDEOGRAPH-FAC0 +2F9D1 ; [.FB41.0020.0002.8B8A][.8B8A.0000.0000.8B8A] # CJK COMPATIBILITY IDEOGRAPH-2F9D1 +2EC8 ; [.FB41.0020.0004.8BA0][.8BA0.0000.0000.8BA0] # CJK RADICAL C-SIMPLIFIED SPEECH +2F95 ; [.FB41.0020.0004.8C37][.8C37.0000.0000.8C37] # KANGXI RADICAL VALLEY +2F96 ; [.FB41.0020.0004.8C46][.8C46.0000.0000.8C46] # KANGXI RADICAL BEAN +F900 ; [.FB41.0020.0002.8C48][.8C48.0000.0000.8C48] # CJK COMPATIBILITY IDEOGRAPH-F900 +2F9D2 ; [.FB41.0020.0002.8C55][.8C55.0000.0000.8C55] # CJK COMPATIBILITY IDEOGRAPH-2F9D2 +2F97 ; [.FB41.0020.0004.8C55][.8C55.0000.0000.8C55] # KANGXI RADICAL PIG +2F98 ; [.FB41.0020.0004.8C78][.8C78.0000.0000.8C78] # KANGXI RADICAL BADGER +2F99 ; [.FB41.0020.0004.8C9D][.8C9D.0000.0000.8C9D] # KANGXI RADICAL SHELL +3236 ; [*02FB.0020.0004.3236][.FB41.0020.0004.8CA1][.8CA1.0000.0000.8CA1][*02FC.0020.001F.3236] # PARENTHESIZED IDEOGRAPH FINANCIAL +3296 ; [.FB41.0020.0006.8CA1][.8CA1.0000.0000.8CA1] # CIRCLED IDEOGRAPH FINANCIAL +1F223 ; [.FB41.0020.001C.8CA9][.8CA9.0000.0000.8CA9] # SQUARED CJK UNIFIED IDEOGRAPH-8CA9 +2F9D4 ; [.FB41.0020.0002.8CAB][.8CAB.0000.0000.8CAB] # CJK COMPATIBILITY IDEOGRAPH-2F9D4 +2F9D5 ; [.FB41.0020.0002.8CC1][.8CC1.0000.0000.8CC1] # CJK COMPATIBILITY IDEOGRAPH-2F9D5 +F948 ; [.FB41.0020.0002.8CC2][.8CC2.0000.0000.8CC2] # CJK COMPATIBILITY IDEOGRAPH-F948 +323E ; [*02FB.0020.0004.323E][.FB41.0020.0004.8CC7][.8CC7.0000.0000.8CC7][*02FC.0020.001F.323E] # PARENTHESIZED IDEOGRAPH RESOURCE +32AE ; [.FB41.0020.0006.8CC7][.8CC7.0000.0000.8CC7] # CIRCLED IDEOGRAPH RESOURCE +F903 ; [.FB41.0020.0002.8CC8][.8CC8.0000.0000.8CC8] # CJK COMPATIBILITY IDEOGRAPH-F903 +FA64 ; [.FB41.0020.0002.8CD3][.8CD3.0000.0000.8CD3] # CJK COMPATIBILITY IDEOGRAPH-FA64 +FA65 ; [.FB41.0020.0002.8D08][.8D08.0000.0000.8D08] # CJK COMPATIBILITY IDEOGRAPH-FA65 +FAC1 ; [.FB41.0020.0002.8D08][.8D08.0000.0000.8D08] # CJK COMPATIBILITY IDEOGRAPH-FAC1 +2F9D6 ; [.FB41.0020.0002.8D1B][.8D1B.0000.0000.8D1B] # CJK COMPATIBILITY IDEOGRAPH-2F9D6 +2EC9 ; [.FB41.0020.0004.8D1D][.8D1D.0000.0000.8D1D] # CJK RADICAL C-SIMPLIFIED SHELL +2F9A ; [.FB41.0020.0004.8D64][.8D64.0000.0000.8D64] # KANGXI RADICAL RED +2F9B ; [.FB41.0020.0004.8D70][.8D70.0000.0000.8D70] # KANGXI RADICAL RUN +1F230 ; [.FB41.0020.001C.8D70][.8D70.0000.0000.8D70] # SQUARED CJK UNIFIED IDEOGRAPH-8D70 +2F9D7 ; [.FB41.0020.0002.8D77][.8D77.0000.0000.8D77] # CJK COMPATIBILITY IDEOGRAPH-2F9D7 +2F9C ; [.FB41.0020.0004.8DB3][.8DB3.0000.0000.8DB3] # KANGXI RADICAL FOOT +2ECA ; [.FB41.0020.0004.8DB3][.8DB3.0000.0000.8DB3][.0000.0139.001F.2ECA] # CJK RADICAL FOOT +2F9DB ; [.FB41.0020.0002.8DBC][.8DBC.0000.0000.8DBC] # CJK COMPATIBILITY IDEOGRAPH-2F9DB +2F9DA ; [.FB41.0020.0002.8DCB][.8DCB.0000.0000.8DCB] # CJK COMPATIBILITY IDEOGRAPH-2F9DA +F937 ; [.FB41.0020.0002.8DEF][.8DEF.0000.0000.8DEF] # CJK COMPATIBILITY IDEOGRAPH-F937 +2F9DC ; [.FB41.0020.0002.8DF0][.8DF0.0000.0000.8DF0] # CJK COMPATIBILITY IDEOGRAPH-2F9DC +2F9D ; [.FB41.0020.0004.8EAB][.8EAB.0000.0000.8EAB] # KANGXI RADICAL BODY +F902 ; [.FB41.0020.0002.8ECA][.8ECA.0000.0000.8ECA] # CJK COMPATIBILITY IDEOGRAPH-F902 +2F9E ; [.FB41.0020.0004.8ECA][.8ECA.0000.0000.8ECA] # KANGXI RADICAL CART +2F9DE ; [.FB41.0020.0002.8ED4][.8ED4.0000.0000.8ED4] # CJK COMPATIBILITY IDEOGRAPH-2F9DE +F998 ; [.FB41.0020.0002.8F26][.8F26.0000.0000.8F26] # CJK COMPATIBILITY IDEOGRAPH-F998 +F9D7 ; [.FB41.0020.0002.8F2A][.8F2A.0000.0000.8F2A] # CJK COMPATIBILITY IDEOGRAPH-F9D7 +FAC2 ; [.FB41.0020.0002.8F38][.8F38.0000.0000.8F38] # CJK COMPATIBILITY IDEOGRAPH-FAC2 +2F9DF ; [.FB41.0020.0002.8F38][.8F38.0000.0000.8F38] # CJK COMPATIBILITY IDEOGRAPH-2F9DF +FA07 ; [.FB41.0020.0002.8F3B][.8F3B.0000.0000.8F3B] # CJK COMPATIBILITY IDEOGRAPH-FA07 +F98D ; [.FB41.0020.0002.8F62][.8F62.0000.0000.8F62] # CJK COMPATIBILITY IDEOGRAPH-F98D +2ECB ; [.FB41.0020.0004.8F66][.8F66.0000.0000.8F66] # CJK RADICAL C-SIMPLIFIED CART +2F9F ; [.FB41.0020.0004.8F9B][.8F9B.0000.0000.8F9B] # KANGXI RADICAL BITTER +2F98D ; [.FB41.0020.0002.8F9E][.8F9E.0000.0000.8F9E] # CJK COMPATIBILITY IDEOGRAPH-2F98D +F971 ; [.FB41.0020.0002.8FB0][.8FB0.0000.0000.8FB0] # CJK COMPATIBILITY IDEOGRAPH-F971 +2FA0 ; [.FB41.0020.0004.8FB0][.8FB0.0000.0000.8FB0] # KANGXI RADICAL MORNING +2FA1 ; [.FB41.0020.0004.8FB5][.8FB5.0000.0000.8FB5] # KANGXI RADICAL WALK +FA66 ; [.FB41.0020.0002.8FB6][.8FB6.0000.0000.8FB6] # CJK COMPATIBILITY IDEOGRAPH-FA66 +2ECC ; [.FB41.0020.0004.8FB6][.8FB6.0000.0000.8FB6] # CJK RADICAL SIMPLIFIED WALK +2ECD ; [.FB41.0020.0004.8FB6][.8FB6.0000.0000.8FB6][.0000.0139.001F.2ECD] # CJK RADICAL WALK ONE +2ECE ; [.FB41.0020.0004.8FB6][.8FB6.0000.0000.8FB6][.0000.013A.001F.2ECE] # CJK RADICAL WALK TWO +F99A ; [.FB41.0020.0002.9023][.9023.0000.0000.9023] # CJK COMPATIBILITY IDEOGRAPH-F99A +FA25 ; [.FB41.0020.0002.9038][.9038.0000.0000.9038] # CJK COMPATIBILITY IDEOGRAPH-FA25 +FA67 ; [.FB41.0020.0002.9038][.9038.0000.0000.9038] # CJK COMPATIBILITY IDEOGRAPH-FA67 +1F22B ; [.FB41.0020.001C.904A][.904A.0000.0000.904A] # SQUARED CJK UNIFIED IDEOGRAPH-904A +329C ; [.FB41.0020.0006.9069][.9069.0000.0000.9069] # CIRCLED IDEOGRAPH SUITABLE +FAC3 ; [.FB41.0020.0002.9072][.9072.0000.0000.9072] # CJK COMPATIBILITY IDEOGRAPH-FAC3 +F9C3 ; [.FB41.0020.0002.907C][.907C.0000.0000.907C] # CJK COMPATIBILITY IDEOGRAPH-F9C3 +F913 ; [.FB41.0020.0002.908F][.908F.0000.0000.908F] # CJK COMPATIBILITY IDEOGRAPH-F913 +2FA2 ; [.FB41.0020.0004.9091][.9091.0000.0000.9091] # KANGXI RADICAL CITY +2ECF ; [.FB41.0020.0004.9091][.9091.0000.0000.9091][.0000.0139.001F.2ECF] # CJK RADICAL CITY +2F9E2 ; [.FB41.0020.0002.9094][.9094.0000.0000.9094] # CJK COMPATIBILITY IDEOGRAPH-2F9E2 +F92C ; [.FB41.0020.0002.90CE][.90CE.0000.0000.90CE] # CJK COMPATIBILITY IDEOGRAPH-F92C +FA2E ; [.FB41.0020.0002.90DE][.90DE.0000.0000.90DE] # CJK COMPATIBILITY IDEOGRAPH-FA2E +2F9E3 ; [.FB41.0020.0002.90F1][.90F1.0000.0000.90F1] # CJK COMPATIBILITY IDEOGRAPH-2F9E3 +FA26 ; [.FB41.0020.0002.90FD][.90FD.0000.0000.90FD] # CJK COMPATIBILITY IDEOGRAPH-FA26 +2F9E4 ; [.FB41.0020.0002.9111][.9111.0000.0000.9111] # CJK COMPATIBILITY IDEOGRAPH-2F9E4 +2F9E6 ; [.FB41.0020.0002.911B][.911B.0000.0000.911B] # CJK COMPATIBILITY IDEOGRAPH-2F9E6 +2FA3 ; [.FB41.0020.0004.9149][.9149.0000.0000.9149] # KANGXI RADICAL WINE +F919 ; [.FB41.0020.0002.916A][.916A.0000.0000.916A] # CJK COMPATIBILITY IDEOGRAPH-F919 +FAC4 ; [.FB41.0020.0002.9199][.9199.0000.0000.9199] # CJK COMPATIBILITY IDEOGRAPH-FAC4 +F9B7 ; [.FB41.0020.0002.91B4][.91B4.0000.0000.91B4] # CJK COMPATIBILITY IDEOGRAPH-F9B7 +2FA4 ; [.FB41.0020.0004.91C6][.91C6.0000.0000.91C6] # KANGXI RADICAL DISTINGUISH +F9E9 ; [.FB41.0020.0002.91CC][.91CC.0000.0000.91CC] # CJK COMPATIBILITY IDEOGRAPH-F9E9 +2FA5 ; [.FB41.0020.0004.91CC][.91CC.0000.0000.91CC] # KANGXI RADICAL VILLAGE +F97E ; [.FB41.0020.0002.91CF][.91CF.0000.0000.91CF] # CJK COMPATIBILITY IDEOGRAPH-F97E +F90A ; [.FB41.0020.0002.91D1][.91D1.0000.0000.91D1] # CJK COMPATIBILITY IDEOGRAPH-F90A +2FA6 ; [.FB41.0020.0004.91D1][.91D1.0000.0000.91D1] # KANGXI RADICAL GOLD +322E ; [*02FB.0020.0004.322E][.FB41.0020.0004.91D1][.91D1.0000.0000.91D1][*02FC.0020.001F.322E] # PARENTHESIZED IDEOGRAPH METAL +328E ; [.FB41.0020.0006.91D1][.91D1.0000.0000.91D1] # CIRCLED IDEOGRAPH METAL +F9B1 ; [.FB41.0020.0002.9234][.9234.0000.0000.9234] # CJK COMPATIBILITY IDEOGRAPH-F9B1 +2F9E7 ; [.FB41.0020.0002.9238][.9238.0000.0000.9238] # CJK COMPATIBILITY IDEOGRAPH-2F9E7 +FAC5 ; [.FB41.0020.0002.9276][.9276.0000.0000.9276] # CJK COMPATIBILITY IDEOGRAPH-FAC5 +2F9EA ; [.FB41.0020.0002.927C][.927C.0000.0000.927C] # CJK COMPATIBILITY IDEOGRAPH-2F9EA +2F9E8 ; [.FB41.0020.0002.92D7][.92D7.0000.0000.92D7] # CJK COMPATIBILITY IDEOGRAPH-2F9E8 +2F9E9 ; [.FB41.0020.0002.92D8][.92D8.0000.0000.92D8] # CJK COMPATIBILITY IDEOGRAPH-2F9E9 +F93F ; [.FB41.0020.0002.9304][.9304.0000.0000.9304] # CJK COMPATIBILITY IDEOGRAPH-F93F +F99B ; [.FB41.0020.0002.934A][.934A.0000.0000.934A] # CJK COMPATIBILITY IDEOGRAPH-F99B +2F9EB ; [.FB41.0020.0002.93F9][.93F9.0000.0000.93F9] # CJK COMPATIBILITY IDEOGRAPH-2F9EB +2F9EC ; [.FB41.0020.0002.9415][.9415.0000.0000.9415] # CJK COMPATIBILITY IDEOGRAPH-2F9EC +2ED0 ; [.FB41.0020.0004.9485][.9485.0000.0000.9485] # CJK RADICAL C-SIMPLIFIED GOLD +2ED1 ; [.FB41.0020.0004.9577][.9577.0000.0000.9577] # CJK RADICAL LONG ONE +2FA7 ; [.FB41.0020.0004.9577][.9577.0000.0000.9577] # KANGXI RADICAL LONG +2ED2 ; [.FB41.0020.0004.9578][.9578.0000.0000.9578] # CJK RADICAL LONG TWO +2ED3 ; [.FB41.0020.0004.957F][.957F.0000.0000.957F] # CJK RADICAL C-SIMPLIFIED LONG +2FA8 ; [.FB41.0020.0004.9580][.9580.0000.0000.9580] # KANGXI RADICAL GATE +2F9EE ; [.FB41.0020.0002.958B][.958B.0000.0000.958B] # CJK COMPATIBILITY IDEOGRAPH-2F9EE +F986 ; [.FB41.0020.0002.95AD][.95AD.0000.0000.95AD] # CJK COMPATIBILITY IDEOGRAPH-F986 +2F9F0 ; [.FB41.0020.0002.95B7][.95B7.0000.0000.95B7] # CJK COMPATIBILITY IDEOGRAPH-2F9F0 +2ED4 ; [.FB41.0020.0004.95E8][.95E8.0000.0000.95E8] # CJK RADICAL C-SIMPLIFIED GATE +2FA9 ; [.FB41.0020.0004.961C][.961C.0000.0000.961C] # KANGXI RADICAL MOUND +2ED5 ; [.FB41.0020.0004.961C][.961C.0000.0000.961C][.0000.0139.001F.2ED5] # CJK RADICAL MOUND ONE +2ED6 ; [.FB41.0020.0004.961D][.961D.0000.0000.961D] # CJK RADICAL MOUND TWO +F9C6 ; [.FB41.0020.0002.962E][.962E.0000.0000.962E] # CJK COMPATIBILITY IDEOGRAPH-F9C6 +F951 ; [.FB41.0020.0002.964B][.964B.0000.0000.964B] # CJK COMPATIBILITY IDEOGRAPH-F951 +FA09 ; [.FB41.0020.0002.964D][.964D.0000.0000.964D] # CJK COMPATIBILITY IDEOGRAPH-FA09 +F959 ; [.FB41.0020.0002.9675][.9675.0000.0000.9675] # CJK COMPATIBILITY IDEOGRAPH-F959 +F9D3 ; [.FB41.0020.0002.9678][.9678.0000.0000.9678] # CJK COMPATIBILITY IDEOGRAPH-F9D3 +FAC6 ; [.FB41.0020.0002.967C][.967C.0000.0000.967C] # CJK COMPATIBILITY IDEOGRAPH-FAC6 +F9DC ; [.FB41.0020.0002.9686][.9686.0000.0000.9686] # CJK COMPATIBILITY IDEOGRAPH-F9DC +F9F1 ; [.FB41.0020.0002.96A3][.96A3.0000.0000.96A3] # CJK COMPATIBILITY IDEOGRAPH-F9F1 +2FAA ; [.FB41.0020.0004.96B6][.96B6.0000.0000.96B6] # KANGXI RADICAL SLAVE +FA2F ; [.FB41.0020.0002.96B7][.96B7.0000.0000.96B7] # CJK COMPATIBILITY IDEOGRAPH-FA2F +F9B8 ; [.FB41.0020.0002.96B8][.96B8.0000.0000.96B8] # CJK COMPATIBILITY IDEOGRAPH-F9B8 +2FAB ; [.FB41.0020.0004.96B9][.96B9.0000.0000.96B9] # KANGXI RADICAL SHORT TAILED BIRD +2F9F3 ; [.FB41.0020.0002.96C3][.96C3.0000.0000.96C3] # CJK COMPATIBILITY IDEOGRAPH-2F9F3 +F9EA ; [.FB41.0020.0002.96E2][.96E2.0000.0000.96E2] # CJK COMPATIBILITY IDEOGRAPH-F9EA +FA68 ; [.FB41.0020.0002.96E3][.96E3.0000.0000.96E3] # CJK COMPATIBILITY IDEOGRAPH-FA68 +FAC7 ; [.FB41.0020.0002.96E3][.96E3.0000.0000.96E3] # CJK COMPATIBILITY IDEOGRAPH-FAC7 +2FAC ; [.FB41.0020.0004.96E8][.96E8.0000.0000.96E8] # KANGXI RADICAL RAIN +2ED7 ; [.FB41.0020.0004.96E8][.96E8.0000.0000.96E8][.0000.0139.001F.2ED7] # CJK RADICAL RAIN +F9B2 ; [.FB41.0020.0002.96F6][.96F6.0000.0000.96F6] # CJK COMPATIBILITY IDEOGRAPH-F9B2 +F949 ; [.FB41.0020.0002.96F7][.96F7.0000.0000.96F7] # CJK COMPATIBILITY IDEOGRAPH-F949 +2F9F5 ; [.FB41.0020.0002.9723][.9723.0000.0000.9723] # CJK COMPATIBILITY IDEOGRAPH-2F9F5 +F938 ; [.FB41.0020.0002.9732][.9732.0000.0000.9732] # CJK COMPATIBILITY IDEOGRAPH-F938 +F9B3 ; [.FB41.0020.0002.9748][.9748.0000.0000.9748] # CJK COMPATIBILITY IDEOGRAPH-F9B3 +2FAD ; [.FB41.0020.0004.9751][.9751.0000.0000.9751] # KANGXI RADICAL BLUE +2ED8 ; [.FB41.0020.0004.9752][.9752.0000.0000.9752] # CJK RADICAL BLUE +FA1C ; [.FB41.0020.0002.9756][.9756.0000.0000.9756] # CJK COMPATIBILITY IDEOGRAPH-FA1C +FAC8 ; [.FB41.0020.0002.9756][.9756.0000.0000.9756] # CJK COMPATIBILITY IDEOGRAPH-FAC8 +2FAE ; [.FB41.0020.0004.975E][.975E.0000.0000.975E] # KANGXI RADICAL WRONG +2FAF ; [.FB41.0020.0004.9762][.9762.0000.0000.9762] # KANGXI RADICAL FACE +2FB0 ; [.FB41.0020.0004.9769][.9769.0000.0000.9769] # KANGXI RADICAL LEATHER +2FB1 ; [.FB41.0020.0004.97CB][.97CB.0000.0000.97CB] # KANGXI RADICAL TANNED LEATHER +FAC9 ; [.FB41.0020.0002.97DB][.97DB.0000.0000.97DB] # CJK COMPATIBILITY IDEOGRAPH-FAC9 +2F9FA ; [.FB41.0020.0002.97E0][.97E0.0000.0000.97E0] # CJK COMPATIBILITY IDEOGRAPH-2F9FA +2ED9 ; [.FB41.0020.0004.97E6][.97E6.0000.0000.97E6] # CJK RADICAL C-SIMPLIFIED TANNED LEATHER +2FB2 ; [.FB41.0020.0004.97ED][.97ED.0000.0000.97ED] # KANGXI RADICAL LEEK +2FB3 ; [.FB41.0020.0004.97F3][.97F3.0000.0000.97F3] # KANGXI RADICAL SOUND +FA69 ; [.FB41.0020.0002.97FF][.97FF.0000.0000.97FF] # CJK COMPATIBILITY IDEOGRAPH-FA69 +FACA ; [.FB41.0020.0002.97FF][.97FF.0000.0000.97FF] # CJK COMPATIBILITY IDEOGRAPH-FACA +2FB4 ; [.FB41.0020.0004.9801][.9801.0000.0000.9801] # KANGXI RADICAL LEAF +32A0 ; [.FB41.0020.0006.9805][.9805.0000.0000.9805] # CIRCLED IDEOGRAPH ITEM +FACB ; [.FB41.0020.0002.980B][.980B.0000.0000.980B] # CJK COMPATIBILITY IDEOGRAPH-FACB +2F9FE ; [.FB41.0020.0002.980B][.980B.0000.0000.980B] # CJK COMPATIBILITY IDEOGRAPH-2F9FE +2F9FF ; [.FB41.0020.0002.980B][.980B.0000.0000.980B] # CJK COMPATIBILITY IDEOGRAPH-2F9FF +F9B4 ; [.FB41.0020.0002.9818][.9818.0000.0000.9818] # CJK COMPATIBILITY IDEOGRAPH-F9B4 +2FA00 ; [.FB41.0020.0002.9829][.9829.0000.0000.9829] # CJK COMPATIBILITY IDEOGRAPH-2FA00 +FA6A ; [.FB41.0020.0002.983B][.983B.0000.0000.983B] # CJK COMPATIBILITY IDEOGRAPH-FA6A +FACC ; [.FB41.0020.0002.983B][.983B.0000.0000.983B] # CJK COMPATIBILITY IDEOGRAPH-FACC +F9D0 ; [.FB41.0020.0002.985E][.985E.0000.0000.985E] # CJK COMPATIBILITY IDEOGRAPH-F9D0 +2EDA ; [.FB41.0020.0004.9875][.9875.0000.0000.9875] # CJK RADICAL C-SIMPLIFIED LEAF +2FB5 ; [.FB41.0020.0004.98A8][.98A8.0000.0000.98A8] # KANGXI RADICAL WIND +2EDB ; [.FB41.0020.0004.98CE][.98CE.0000.0000.98CE] # CJK RADICAL C-SIMPLIFIED WIND +2FB6 ; [.FB41.0020.0004.98DB][.98DB.0000.0000.98DB] # KANGXI RADICAL FLY +2EDC ; [.FB41.0020.0004.98DE][.98DE.0000.0000.98DE] # CJK RADICAL C-SIMPLIFIED FLY +2EDD ; [.FB41.0020.0004.98DF][.98DF.0000.0000.98DF] # CJK RADICAL EAT ONE +2FB7 ; [.FB41.0020.0004.98DF][.98DF.0000.0000.98DF] # KANGXI RADICAL EAT +2EDF ; [.FB41.0020.0004.98E0][.98E0.0000.0000.98E0] # CJK RADICAL EAT THREE +2EDE ; [.FB41.0020.0004.98E0][.98E0.0000.0000.98E0][.0000.0139.001F.2EDE] # CJK RADICAL EAT TWO +2FA02 ; [.FB41.0020.0002.98E2][.98E2.0000.0000.98E2] # CJK COMPATIBILITY IDEOGRAPH-2FA02 +FA2A ; [.FB41.0020.0002.98EF][.98EF.0000.0000.98EF] # CJK COMPATIBILITY IDEOGRAPH-FA2A +FA2B ; [.FB41.0020.0002.98FC][.98FC.0000.0000.98FC] # CJK COMPATIBILITY IDEOGRAPH-FA2B +FA2C ; [.FB41.0020.0002.9928][.9928.0000.0000.9928] # CJK COMPATIBILITY IDEOGRAPH-FA2C +2FA04 ; [.FB41.0020.0002.9929][.9929.0000.0000.9929] # CJK COMPATIBILITY IDEOGRAPH-2FA04 +2EE0 ; [.FB41.0020.0004.9963][.9963.0000.0000.9963] # CJK RADICAL C-SIMPLIFIED EAT +2FB8 ; [.FB41.0020.0004.9996][.9996.0000.0000.9996] # KANGXI RADICAL HEAD +2EE1 ; [.FB41.0020.0004.9996][.9996.0000.0000.9996][.0000.0139.001F.2EE1] # CJK RADICAL HEAD +2FB9 ; [.FB41.0020.0004.9999][.9999.0000.0000.9999] # KANGXI RADICAL FRAGRANT +2FA05 ; [.FB41.0020.0002.99A7][.99A7.0000.0000.99A7] # CJK COMPATIBILITY IDEOGRAPH-2FA05 +2FBA ; [.FB41.0020.0004.99AC][.99AC.0000.0000.99AC] # KANGXI RADICAL HORSE +2FA06 ; [.FB41.0020.0002.99C2][.99C2.0000.0000.99C2] # CJK COMPATIBILITY IDEOGRAPH-2FA06 +F91A ; [.FB41.0020.0002.99F1][.99F1.0000.0000.99F1] # CJK COMPATIBILITY IDEOGRAPH-F91A +2FA07 ; [.FB41.0020.0002.99FE][.99FE.0000.0000.99FE] # CJK COMPATIBILITY IDEOGRAPH-2FA07 +F987 ; [.FB41.0020.0002.9A6A][.9A6A.0000.0000.9A6A] # CJK COMPATIBILITY IDEOGRAPH-F987 +2EE2 ; [.FB41.0020.0004.9A6C][.9A6C.0000.0000.9A6C] # CJK RADICAL C-SIMPLIFIED HORSE +2FBB ; [.FB41.0020.0004.9AA8][.9AA8.0000.0000.9AA8] # KANGXI RADICAL BONE +2EE3 ; [.FB41.0020.0004.9AA8][.9AA8.0000.0000.9AA8][.0000.0139.001F.2EE3] # CJK RADICAL BONE +2FBC ; [.FB41.0020.0004.9AD8][.9AD8.0000.0000.9AD8] # KANGXI RADICAL TALL +2FBD ; [.FB41.0020.0004.9ADF][.9ADF.0000.0000.9ADF] # KANGXI RADICAL HAIR +FACD ; [.FB41.0020.0002.9B12][.9B12.0000.0000.9B12] # CJK COMPATIBILITY IDEOGRAPH-FACD +2FA0A ; [.FB41.0020.0002.9B12][.9B12.0000.0000.9B12] # CJK COMPATIBILITY IDEOGRAPH-2FA0A +2FBE ; [.FB41.0020.0004.9B25][.9B25.0000.0000.9B25] # KANGXI RADICAL FIGHT +2FBF ; [.FB41.0020.0004.9B2F][.9B2F.0000.0000.9B2F] # KANGXI RADICAL SACRIFICIAL WINE +2FC0 ; [.FB41.0020.0004.9B32][.9B32.0000.0000.9B32] # KANGXI RADICAL CAULDRON +2FC1 ; [.FB41.0020.0004.9B3C][.9B3C.0000.0000.9B3C] # KANGXI RADICAL GHOST +2EE4 ; [.FB41.0020.0004.9B3C][.9B3C.0000.0000.9B3C][.0000.0139.001F.2EE4] # CJK RADICAL GHOST +2FC2 ; [.FB41.0020.0004.9B5A][.9B5A.0000.0000.9B5A] # KANGXI RADICAL FISH +F939 ; [.FB41.0020.0002.9B6F][.9B6F.0000.0000.9B6F] # CJK COMPATIBILITY IDEOGRAPH-F939 +2FA0B ; [.FB41.0020.0002.9C40][.9C40.0000.0000.9C40] # CJK COMPATIBILITY IDEOGRAPH-2FA0B +F9F2 ; [.FB41.0020.0002.9C57][.9C57.0000.0000.9C57] # CJK COMPATIBILITY IDEOGRAPH-F9F2 +2EE5 ; [.FB41.0020.0004.9C7C][.9C7C.0000.0000.9C7C] # CJK RADICAL C-SIMPLIFIED FISH +2FC3 ; [.FB41.0020.0004.9CE5][.9CE5.0000.0000.9CE5] # KANGXI RADICAL BIRD +2FA0C ; [.FB41.0020.0002.9CFD][.9CFD.0000.0000.9CFD] # CJK COMPATIBILITY IDEOGRAPH-2FA0C +2FA0F ; [.FB41.0020.0002.9D67][.9D67.0000.0000.9D67] # CJK COMPATIBILITY IDEOGRAPH-2FA0F +FA2D ; [.FB41.0020.0002.9DB4][.9DB4.0000.0000.9DB4] # CJK COMPATIBILITY IDEOGRAPH-FA2D +F93A ; [.FB41.0020.0002.9DFA][.9DFA.0000.0000.9DFA] # CJK COMPATIBILITY IDEOGRAPH-F93A +F920 ; [.FB41.0020.0002.9E1E][.9E1E.0000.0000.9E1E] # CJK COMPATIBILITY IDEOGRAPH-F920 +2EE6 ; [.FB41.0020.0004.9E1F][.9E1F.0000.0000.9E1F] # CJK RADICAL C-SIMPLIFIED BIRD +2FC4 ; [.FB41.0020.0004.9E75][.9E75.0000.0000.9E75] # KANGXI RADICAL SALT +2EE7 ; [.FB41.0020.0004.9E75][.9E75.0000.0000.9E75][.0000.0139.001F.2EE7] # CJK RADICAL C-SIMPLIFIED SALT +F940 ; [.FB41.0020.0002.9E7F][.9E7F.0000.0000.9E7F] # CJK COMPATIBILITY IDEOGRAPH-F940 +2FC5 ; [.FB41.0020.0004.9E7F][.9E7F.0000.0000.9E7F] # KANGXI RADICAL DEER +F988 ; [.FB41.0020.0002.9E97][.9E97.0000.0000.9E97] # CJK COMPATIBILITY IDEOGRAPH-F988 +F9F3 ; [.FB41.0020.0002.9E9F][.9E9F.0000.0000.9E9F] # CJK COMPATIBILITY IDEOGRAPH-F9F3 +2FC6 ; [.FB41.0020.0004.9EA5][.9EA5.0000.0000.9EA5] # KANGXI RADICAL WHEAT +2EE8 ; [.FB41.0020.0004.9EA6][.9EA6.0000.0000.9EA6] # CJK RADICAL SIMPLIFIED WHEAT +2FA15 ; [.FB41.0020.0002.9EBB][.9EBB.0000.0000.9EBB] # CJK COMPATIBILITY IDEOGRAPH-2FA15 +2FC7 ; [.FB41.0020.0004.9EBB][.9EBB.0000.0000.9EBB] # KANGXI RADICAL HEMP +2FC8 ; [.FB41.0020.0004.9EC3][.9EC3.0000.0000.9EC3] # KANGXI RADICAL YELLOW +2EE9 ; [.FB41.0020.0004.9EC4][.9EC4.0000.0000.9EC4] # CJK RADICAL SIMPLIFIED YELLOW +2FC9 ; [.FB41.0020.0004.9ECD][.9ECD.0000.0000.9ECD] # KANGXI RADICAL MILLET +F989 ; [.FB41.0020.0002.9ECE][.9ECE.0000.0000.9ECE] # CJK COMPATIBILITY IDEOGRAPH-F989 +2FCA ; [.FB41.0020.0004.9ED1][.9ED1.0000.0000.9ED1] # KANGXI RADICAL BLACK +2FA17 ; [.FB41.0020.0002.9EF9][.9EF9.0000.0000.9EF9] # CJK COMPATIBILITY IDEOGRAPH-2FA17 +2FCB ; [.FB41.0020.0004.9EF9][.9EF9.0000.0000.9EF9] # KANGXI RADICAL EMBROIDERY +2FCC ; [.FB41.0020.0004.9EFD][.9EFD.0000.0000.9EFD] # KANGXI RADICAL FROG +2FA18 ; [.FB41.0020.0002.9EFE][.9EFE.0000.0000.9EFE] # CJK COMPATIBILITY IDEOGRAPH-2FA18 +2EEA ; [.FB41.0020.0004.9EFE][.9EFE.0000.0000.9EFE] # CJK RADICAL C-SIMPLIFIED FROG +2FA19 ; [.FB41.0020.0002.9F05][.9F05.0000.0000.9F05] # CJK COMPATIBILITY IDEOGRAPH-2FA19 +2FCD ; [.FB41.0020.0004.9F0E][.9F0E.0000.0000.9F0E] # KANGXI RADICAL TRIPOD +2FA1A ; [.FB41.0020.0002.9F0F][.9F0F.0000.0000.9F0F] # CJK COMPATIBILITY IDEOGRAPH-2FA1A +2FCE ; [.FB41.0020.0004.9F13][.9F13.0000.0000.9F13] # KANGXI RADICAL DRUM +2FA1B ; [.FB41.0020.0002.9F16][.9F16.0000.0000.9F16] # CJK COMPATIBILITY IDEOGRAPH-2FA1B +2FCF ; [.FB41.0020.0004.9F20][.9F20.0000.0000.9F20] # KANGXI RADICAL RAT +2FA1C ; [.FB41.0020.0002.9F3B][.9F3B.0000.0000.9F3B] # CJK COMPATIBILITY IDEOGRAPH-2FA1C +2FD0 ; [.FB41.0020.0004.9F3B][.9F3B.0000.0000.9F3B] # KANGXI RADICAL NOSE +FAD8 ; [.FB41.0020.0002.9F43][.9F43.0000.0000.9F43] # CJK COMPATIBILITY IDEOGRAPH-FAD8 +2FD1 ; [.FB41.0020.0004.9F4A][.9F4A.0000.0000.9F4A] # KANGXI RADICAL EVEN +2EEB ; [.FB41.0020.0004.9F4A][.9F4A.0000.0000.9F4A][.0000.0139.001F.2EEB] # CJK RADICAL J-SIMPLIFIED EVEN +2EEC ; [.FB41.0020.0004.9F50][.9F50.0000.0000.9F50] # CJK RADICAL C-SIMPLIFIED EVEN +2FD2 ; [.FB41.0020.0004.9F52][.9F52.0000.0000.9F52] # KANGXI RADICAL TOOTH +2EED ; [.FB41.0020.0004.9F52][.9F52.0000.0000.9F52][.0000.0139.001F.2EED] # CJK RADICAL J-SIMPLIFIED TOOTH +2EEE ; [.FB41.0020.0004.9F7F][.9F7F.0000.0000.9F7F] # CJK RADICAL C-SIMPLIFIED TOOTH +F9C4 ; [.FB41.0020.0002.9F8D][.9F8D.0000.0000.9F8D] # CJK COMPATIBILITY IDEOGRAPH-F9C4 +2FD3 ; [.FB41.0020.0004.9F8D][.9F8D.0000.0000.9F8D] # KANGXI RADICAL DRAGON +2EEF ; [.FB41.0020.0004.9F8D][.9F8D.0000.0000.9F8D][.0000.0139.001F.2EEF] # CJK RADICAL J-SIMPLIFIED DRAGON +FAD9 ; [.FB41.0020.0002.9F8E][.9F8E.0000.0000.9F8E] # CJK COMPATIBILITY IDEOGRAPH-FAD9 +2EF0 ; [.FB41.0020.0004.9F99][.9F99.0000.0000.9F99] # CJK RADICAL C-SIMPLIFIED DRAGON +F907 ; [.FB41.0020.0002.9F9C][.9F9C.0000.0000.9F9C] # CJK COMPATIBILITY IDEOGRAPH-F907 +F908 ; [.FB41.0020.0002.9F9C][.9F9C.0000.0000.9F9C] # CJK COMPATIBILITY IDEOGRAPH-F908 +FACE ; [.FB41.0020.0002.9F9C][.9F9C.0000.0000.9F9C] # CJK COMPATIBILITY IDEOGRAPH-FACE +2FD4 ; [.FB41.0020.0004.9F9C][.9F9C.0000.0000.9F9C] # KANGXI RADICAL TURTLE +2EF1 ; [.FB41.0020.0004.9F9C][.9F9C.0000.0000.9F9C][.0000.0139.001F.2EF1] # CJK RADICAL TURTLE +2EF2 ; [.FB41.0020.0004.9F9C][.9F9C.0000.0000.9F9C][.0000.013A.001F.2EF2] # CJK RADICAL J-SIMPLIFIED TURTLE +2EF3 ; [.FB41.0020.0004.9F9F][.9F9F.0000.0000.9F9F] # CJK RADICAL C-SIMPLIFIED TURTLE +2FD5 ; [.FB41.0020.0004.9FA0][.9FA0.0000.0000.9FA0] # KANGXI RADICAL FLUTE +FA0E ; [.FB41.0020.0002.FA0E][.FA0E.0000.0000.FA0E] # CJK COMPATIBILITY IDEOGRAPH-FA0E +FA0F ; [.FB41.0020.0002.FA0F][.FA0F.0000.0000.FA0F] # CJK COMPATIBILITY IDEOGRAPH-FA0F +FA11 ; [.FB41.0020.0002.FA11][.FA11.0000.0000.FA11] # CJK COMPATIBILITY IDEOGRAPH-FA11 +FA13 ; [.FB41.0020.0002.FA13][.FA13.0000.0000.FA13] # CJK COMPATIBILITY IDEOGRAPH-FA13 +FA14 ; [.FB41.0020.0002.FA14][.FA14.0000.0000.FA14] # CJK COMPATIBILITY IDEOGRAPH-FA14 +FA1F ; [.FB41.0020.0002.FA1F][.FA1F.0000.0000.FA1F] # CJK COMPATIBILITY IDEOGRAPH-FA1F +FA21 ; [.FB41.0020.0002.FA21][.FA21.0000.0000.FA21] # CJK COMPATIBILITY IDEOGRAPH-FA21 +FA23 ; [.FB41.0020.0002.FA23][.FA23.0000.0000.FA23] # CJK COMPATIBILITY IDEOGRAPH-FA23 +FA24 ; [.FB41.0020.0002.FA24][.FA24.0000.0000.FA24] # CJK COMPATIBILITY IDEOGRAPH-FA24 +FA27 ; [.FB41.0020.0002.FA27][.FA27.0000.0000.FA27] # CJK COMPATIBILITY IDEOGRAPH-FA27 +FA28 ; [.FB41.0020.0002.FA28][.FA28.0000.0000.FA28] # CJK COMPATIBILITY IDEOGRAPH-FA28 +FA29 ; [.FB41.0020.0002.FA29][.FA29.0000.0000.FA29] # CJK COMPATIBILITY IDEOGRAPH-FA29 +2F80C ; [.FB80.0020.0002.349E][.B49E.0000.0000.349E] # CJK COMPATIBILITY IDEOGRAPH-2F80C +2F813 ; [.FB80.0020.0002.34B9][.B4B9.0000.0000.34B9] # CJK COMPATIBILITY IDEOGRAPH-2F813 +2F9CA ; [.FB80.0020.0002.34BB][.B4BB.0000.0000.34BB] # CJK COMPATIBILITY IDEOGRAPH-2F9CA +2F81F ; [.FB80.0020.0002.34DF][.B4DF.0000.0000.34DF] # CJK COMPATIBILITY IDEOGRAPH-2F81F +2F824 ; [.FB80.0020.0002.3515][.B515.0000.0000.3515] # CJK COMPATIBILITY IDEOGRAPH-2F824 +2F867 ; [.FB80.0020.0002.36EE][.B6EE.0000.0000.36EE] # CJK COMPATIBILITY IDEOGRAPH-2F867 +2F868 ; [.FB80.0020.0002.36FC][.B6FC.0000.0000.36FC] # CJK COMPATIBILITY IDEOGRAPH-2F868 +2F876 ; [.FB80.0020.0002.3781][.B781.0000.0000.3781] # CJK COMPATIBILITY IDEOGRAPH-2F876 +2F883 ; [.FB80.0020.0002.382F][.B82F.0000.0000.382F] # CJK COMPATIBILITY IDEOGRAPH-2F883 +2F888 ; [.FB80.0020.0002.3862][.B862.0000.0000.3862] # CJK COMPATIBILITY IDEOGRAPH-2F888 +2F88A ; [.FB80.0020.0002.387C][.B87C.0000.0000.387C] # CJK COMPATIBILITY IDEOGRAPH-2F88A +2F896 ; [.FB80.0020.0002.38C7][.B8C7.0000.0000.38C7] # CJK COMPATIBILITY IDEOGRAPH-2F896 +2F89B ; [.FB80.0020.0002.38E3][.B8E3.0000.0000.38E3] # CJK COMPATIBILITY IDEOGRAPH-2F89B +2F8A2 ; [.FB80.0020.0002.391C][.B91C.0000.0000.391C] # CJK COMPATIBILITY IDEOGRAPH-2F8A2 +2F8A1 ; [.FB80.0020.0002.393A][.B93A.0000.0000.393A] # CJK COMPATIBILITY IDEOGRAPH-2F8A1 +2F8C2 ; [.FB80.0020.0002.3A2E][.BA2E.0000.0000.3A2E] # CJK COMPATIBILITY IDEOGRAPH-2F8C2 +2F8C7 ; [.FB80.0020.0002.3A6C][.BA6C.0000.0000.3A6C] # CJK COMPATIBILITY IDEOGRAPH-2F8C7 +2F8D1 ; [.FB80.0020.0002.3AE4][.BAE4.0000.0000.3AE4] # CJK COMPATIBILITY IDEOGRAPH-2F8D1 +2F8D0 ; [.FB80.0020.0002.3B08][.BB08.0000.0000.3B08] # CJK COMPATIBILITY IDEOGRAPH-2F8D0 +2F8CE ; [.FB80.0020.0002.3B19][.BB19.0000.0000.3B19] # CJK COMPATIBILITY IDEOGRAPH-2F8CE +2F8DE ; [.FB80.0020.0002.3B49][.BB49.0000.0000.3B49] # CJK COMPATIBILITY IDEOGRAPH-2F8DE +FAD2 ; [.FB80.0020.0002.3B9D][.BB9D.0000.0000.3B9D] # CJK COMPATIBILITY IDEOGRAPH-FAD2 +2F8E7 ; [.FB80.0020.0002.3B9D][.BB9D.0000.0000.3B9D] # CJK COMPATIBILITY IDEOGRAPH-2F8E7 +2F8EE ; [.FB80.0020.0002.3C18][.BC18.0000.0000.3C18] # CJK COMPATIBILITY IDEOGRAPH-2F8EE +2F8F2 ; [.FB80.0020.0002.3C4E][.BC4E.0000.0000.3C4E] # CJK COMPATIBILITY IDEOGRAPH-2F8F2 +2F90A ; [.FB80.0020.0002.3D33][.BD33.0000.0000.3D33] # CJK COMPATIBILITY IDEOGRAPH-2F90A +2F916 ; [.FB80.0020.0002.3D96][.BD96.0000.0000.3D96] # CJK COMPATIBILITY IDEOGRAPH-2F916 +2F92A ; [.FB80.0020.0002.3EAC][.BEAC.0000.0000.3EAC] # CJK COMPATIBILITY IDEOGRAPH-2F92A +2F92C ; [.FB80.0020.0002.3EB8][.BEB8.0000.0000.3EB8] # CJK COMPATIBILITY IDEOGRAPH-2F92C +2F92D ; [.FB80.0020.0002.3EB8][.BEB8.0000.0000.3EB8] # CJK COMPATIBILITY IDEOGRAPH-2F92D +2F933 ; [.FB80.0020.0002.3F1B][.BF1B.0000.0000.3F1B] # CJK COMPATIBILITY IDEOGRAPH-2F933 +2F93E ; [.FB80.0020.0002.3FFC][.BFFC.0000.0000.3FFC] # CJK COMPATIBILITY IDEOGRAPH-2F93E +2F93F ; [.FB80.0020.0002.4008][.C008.0000.0000.4008] # CJK COMPATIBILITY IDEOGRAPH-2F93F +FAD3 ; [.FB80.0020.0002.4018][.C018.0000.0000.4018] # CJK COMPATIBILITY IDEOGRAPH-FAD3 +FAD4 ; [.FB80.0020.0002.4039][.C039.0000.0000.4039] # CJK COMPATIBILITY IDEOGRAPH-FAD4 +2F949 ; [.FB80.0020.0002.4039][.C039.0000.0000.4039] # CJK COMPATIBILITY IDEOGRAPH-2F949 +2F94B ; [.FB80.0020.0002.4046][.C046.0000.0000.4046] # CJK COMPATIBILITY IDEOGRAPH-2F94B +2F94C ; [.FB80.0020.0002.4096][.C096.0000.0000.4096] # CJK COMPATIBILITY IDEOGRAPH-2F94C +2F951 ; [.FB80.0020.0002.40E3][.C0E3.0000.0000.40E3] # CJK COMPATIBILITY IDEOGRAPH-2F951 +2F958 ; [.FB80.0020.0002.412F][.C12F.0000.0000.412F] # CJK COMPATIBILITY IDEOGRAPH-2F958 +2F960 ; [.FB80.0020.0002.4202][.C202.0000.0000.4202] # CJK COMPATIBILITY IDEOGRAPH-2F960 +2F964 ; [.FB80.0020.0002.4227][.C227.0000.0000.4227] # CJK COMPATIBILITY IDEOGRAPH-2F964 +2F967 ; [.FB80.0020.0002.42A0][.C2A0.0000.0000.42A0] # CJK COMPATIBILITY IDEOGRAPH-2F967 +2F96D ; [.FB80.0020.0002.4301][.C301.0000.0000.4301] # CJK COMPATIBILITY IDEOGRAPH-2F96D +2F971 ; [.FB80.0020.0002.4334][.C334.0000.0000.4334] # CJK COMPATIBILITY IDEOGRAPH-2F971 +2F974 ; [.FB80.0020.0002.4359][.C359.0000.0000.4359] # CJK COMPATIBILITY IDEOGRAPH-2F974 +2F981 ; [.FB80.0020.0002.43D5][.C3D5.0000.0000.43D5] # CJK COMPATIBILITY IDEOGRAPH-2F981 +2F8D7 ; [.FB80.0020.0002.43D9][.C3D9.0000.0000.43D9] # CJK COMPATIBILITY IDEOGRAPH-2F8D7 +2F984 ; [.FB80.0020.0002.440B][.C40B.0000.0000.440B] # CJK COMPATIBILITY IDEOGRAPH-2F984 +2F98E ; [.FB80.0020.0002.446B][.C46B.0000.0000.446B] # CJK COMPATIBILITY IDEOGRAPH-2F98E +2F9A7 ; [.FB80.0020.0002.452B][.C52B.0000.0000.452B] # CJK COMPATIBILITY IDEOGRAPH-2F9A7 +2F9AE ; [.FB80.0020.0002.455D][.C55D.0000.0000.455D] # CJK COMPATIBILITY IDEOGRAPH-2F9AE +2F9AF ; [.FB80.0020.0002.4561][.C561.0000.0000.4561] # CJK COMPATIBILITY IDEOGRAPH-2F9AF +2F9B2 ; [.FB80.0020.0002.456B][.C56B.0000.0000.456B] # CJK COMPATIBILITY IDEOGRAPH-2F9B2 +2F9BF ; [.FB80.0020.0002.45D7][.C5D7.0000.0000.45D7] # CJK COMPATIBILITY IDEOGRAPH-2F9BF +2F9C2 ; [.FB80.0020.0002.45F9][.C5F9.0000.0000.45F9] # CJK COMPATIBILITY IDEOGRAPH-2F9C2 +2F9C8 ; [.FB80.0020.0002.4635][.C635.0000.0000.4635] # CJK COMPATIBILITY IDEOGRAPH-2F9C8 +2F9CD ; [.FB80.0020.0002.46BE][.C6BE.0000.0000.46BE] # CJK COMPATIBILITY IDEOGRAPH-2F9CD +2F9CE ; [.FB80.0020.0002.46C7][.C6C7.0000.0000.46C7] # CJK COMPATIBILITY IDEOGRAPH-2F9CE +2F9EF ; [.FB80.0020.0002.4995][.C995.0000.0000.4995] # CJK COMPATIBILITY IDEOGRAPH-2F9EF +2F9F2 ; [.FB80.0020.0002.49E6][.C9E6.0000.0000.49E6] # CJK COMPATIBILITY IDEOGRAPH-2F9F2 +2F9F8 ; [.FB80.0020.0002.4A6E][.CA6E.0000.0000.4A6E] # CJK COMPATIBILITY IDEOGRAPH-2F9F8 +2F9F9 ; [.FB80.0020.0002.4A76][.CA76.0000.0000.4A76] # CJK COMPATIBILITY IDEOGRAPH-2F9F9 +2F9FC ; [.FB80.0020.0002.4AB2][.CAB2.0000.0000.4AB2] # CJK COMPATIBILITY IDEOGRAPH-2F9FC +2FA03 ; [.FB80.0020.0002.4B33][.CB33.0000.0000.4B33] # CJK COMPATIBILITY IDEOGRAPH-2FA03 +2FA08 ; [.FB80.0020.0002.4BCE][.CBCE.0000.0000.4BCE] # CJK COMPATIBILITY IDEOGRAPH-2FA08 +2FA0D ; [.FB80.0020.0002.4CCE][.CCCE.0000.0000.4CCE] # CJK COMPATIBILITY IDEOGRAPH-2FA0D +2FA0E ; [.FB80.0020.0002.4CED][.CCED.0000.0000.4CED] # CJK COMPATIBILITY IDEOGRAPH-2FA0E +2FA11 ; [.FB80.0020.0002.4CF8][.CCF8.0000.0000.4CF8] # CJK COMPATIBILITY IDEOGRAPH-2FA11 +2FA16 ; [.FB80.0020.0002.4D56][.CD56.0000.0000.4D56] # CJK COMPATIBILITY IDEOGRAPH-2FA16 +2F803 ; [.FB84.0020.0002.20122][.8122.0000.0000.20122] # CJK COMPATIBILITY IDEOGRAPH-2F803 +2F812 ; [.FB84.0020.0002.2051C][.851C.0000.0000.2051C] # CJK COMPATIBILITY IDEOGRAPH-2F812 +2F91B ; [.FB84.0020.0002.20525][.8525.0000.0000.20525] # CJK COMPATIBILITY IDEOGRAPH-2F91B +2F816 ; [.FB84.0020.0002.2054B][.854B.0000.0000.2054B] # CJK COMPATIBILITY IDEOGRAPH-2F816 +2F80D ; [.FB84.0020.0002.2063A][.863A.0000.0000.2063A] # CJK COMPATIBILITY IDEOGRAPH-2F80D +2F9D9 ; [.FB84.0020.0002.20804][.8804.0000.0000.20804] # CJK COMPATIBILITY IDEOGRAPH-2F9D9 +2F9DD ; [.FB84.0020.0002.208DE][.88DE.0000.0000.208DE] # CJK COMPATIBILITY IDEOGRAPH-2F9DD +2F834 ; [.FB84.0020.0002.20A2C][.8A2C.0000.0000.20A2C] # CJK COMPATIBILITY IDEOGRAPH-2F834 +2F838 ; [.FB84.0020.0002.20B63][.8B63.0000.0000.20B63] # CJK COMPATIBILITY IDEOGRAPH-2F838 +2F859 ; [.FB84.0020.0002.214E4][.94E4.0000.0000.214E4] # CJK COMPATIBILITY IDEOGRAPH-2F859 +2F860 ; [.FB84.0020.0002.216A8][.96A8.0000.0000.216A8] # CJK COMPATIBILITY IDEOGRAPH-2F860 +2F861 ; [.FB84.0020.0002.216EA][.96EA.0000.0000.216EA] # CJK COMPATIBILITY IDEOGRAPH-2F861 +2F86C ; [.FB84.0020.0002.219C8][.99C8.0000.0000.219C8] # CJK COMPATIBILITY IDEOGRAPH-2F86C +2F871 ; [.FB84.0020.0002.21B18][.9B18.0000.0000.21B18] # CJK COMPATIBILITY IDEOGRAPH-2F871 +2F8F8 ; [.FB84.0020.0002.21D0B][.9D0B.0000.0000.21D0B] # CJK COMPATIBILITY IDEOGRAPH-2F8F8 +2F87B ; [.FB84.0020.0002.21DE4][.9DE4.0000.0000.21DE4] # CJK COMPATIBILITY IDEOGRAPH-2F87B +2F87D ; [.FB84.0020.0002.21DE6][.9DE6.0000.0000.21DE6] # CJK COMPATIBILITY IDEOGRAPH-2F87D +2F889 ; [.FB84.0020.0002.22183][.A183.0000.0000.22183] # CJK COMPATIBILITY IDEOGRAPH-2F889 +2F939 ; [.FB84.0020.0002.2219F][.A19F.0000.0000.2219F] # CJK COMPATIBILITY IDEOGRAPH-2F939 +2F891 ; [.FB84.0020.0002.22331][.A331.0000.0000.22331] # CJK COMPATIBILITY IDEOGRAPH-2F891 +2F892 ; [.FB84.0020.0002.22331][.A331.0000.0000.22331] # CJK COMPATIBILITY IDEOGRAPH-2F892 +2F8A4 ; [.FB84.0020.0002.226D4][.A6D4.0000.0000.226D4] # CJK COMPATIBILITY IDEOGRAPH-2F8A4 +FAD0 ; [.FB84.0020.0002.22844][.A844.0000.0000.22844] # CJK COMPATIBILITY IDEOGRAPH-FAD0 +FACF ; [.FB84.0020.0002.2284A][.A84A.0000.0000.2284A] # CJK COMPATIBILITY IDEOGRAPH-FACF +2F8B8 ; [.FB84.0020.0002.22B0C][.AB0C.0000.0000.22B0C] # CJK COMPATIBILITY IDEOGRAPH-2F8B8 +2F8BE ; [.FB84.0020.0002.22BF1][.ABF1.0000.0000.22BF1] # CJK COMPATIBILITY IDEOGRAPH-2F8BE +2F8CA ; [.FB84.0020.0002.2300A][.B00A.0000.0000.2300A] # CJK COMPATIBILITY IDEOGRAPH-2F8CA +2F897 ; [.FB84.0020.0002.232B8][.B2B8.0000.0000.232B8] # CJK COMPATIBILITY IDEOGRAPH-2F897 +2F980 ; [.FB84.0020.0002.2335F][.B35F.0000.0000.2335F] # CJK COMPATIBILITY IDEOGRAPH-2F980 +2F989 ; [.FB84.0020.0002.23393][.B393.0000.0000.23393] # CJK COMPATIBILITY IDEOGRAPH-2F989 +2F98A ; [.FB84.0020.0002.2339C][.B39C.0000.0000.2339C] # CJK COMPATIBILITY IDEOGRAPH-2F98A +2F8DD ; [.FB84.0020.0002.233C3][.B3C3.0000.0000.233C3] # CJK COMPATIBILITY IDEOGRAPH-2F8DD +FAD1 ; [.FB84.0020.0002.233D5][.B3D5.0000.0000.233D5] # CJK COMPATIBILITY IDEOGRAPH-FAD1 +2F8E3 ; [.FB84.0020.0002.2346D][.B46D.0000.0000.2346D] # CJK COMPATIBILITY IDEOGRAPH-2F8E3 +2F8EC ; [.FB84.0020.0002.236A3][.B6A3.0000.0000.236A3] # CJK COMPATIBILITY IDEOGRAPH-2F8EC +2F8F0 ; [.FB84.0020.0002.238A7][.B8A7.0000.0000.238A7] # CJK COMPATIBILITY IDEOGRAPH-2F8F0 +2F8F7 ; [.FB84.0020.0002.23A8D][.BA8D.0000.0000.23A8D] # CJK COMPATIBILITY IDEOGRAPH-2F8F7 +2F8F9 ; [.FB84.0020.0002.23AFA][.BAFA.0000.0000.23AFA] # CJK COMPATIBILITY IDEOGRAPH-2F8F9 +2F8FB ; [.FB84.0020.0002.23CBC][.BCBC.0000.0000.23CBC] # CJK COMPATIBILITY IDEOGRAPH-2F8FB +2F906 ; [.FB84.0020.0002.23D1E][.BD1E.0000.0000.23D1E] # CJK COMPATIBILITY IDEOGRAPH-2F906 +2F90D ; [.FB84.0020.0002.23ED1][.BED1.0000.0000.23ED1] # CJK COMPATIBILITY IDEOGRAPH-2F90D +2F910 ; [.FB84.0020.0002.23F5E][.BF5E.0000.0000.23F5E] # CJK COMPATIBILITY IDEOGRAPH-2F910 +2F911 ; [.FB84.0020.0002.23F8E][.BF8E.0000.0000.23F8E] # CJK COMPATIBILITY IDEOGRAPH-2F911 +2F91D ; [.FB84.0020.0002.24263][.C263.0000.0000.24263] # CJK COMPATIBILITY IDEOGRAPH-2F91D +FA6C ; [.FB84.0020.0002.242EE][.C2EE.0000.0000.242EE] # CJK COMPATIBILITY IDEOGRAPH-FA6C +2F91F ; [.FB84.0020.0002.243AB][.C3AB.0000.0000.243AB] # CJK COMPATIBILITY IDEOGRAPH-2F91F +2F923 ; [.FB84.0020.0002.24608][.C608.0000.0000.24608] # CJK COMPATIBILITY IDEOGRAPH-2F923 +2F926 ; [.FB84.0020.0002.24735][.C735.0000.0000.24735] # CJK COMPATIBILITY IDEOGRAPH-2F926 +2F927 ; [.FB84.0020.0002.24814][.C814.0000.0000.24814] # CJK COMPATIBILITY IDEOGRAPH-2F927 +2F935 ; [.FB84.0020.0002.24C36][.CC36.0000.0000.24C36] # CJK COMPATIBILITY IDEOGRAPH-2F935 +2F937 ; [.FB84.0020.0002.24C92][.CC92.0000.0000.24C92] # CJK COMPATIBILITY IDEOGRAPH-2F937 +2F93B ; [.FB84.0020.0002.24FA1][.CFA1.0000.0000.24FA1] # CJK COMPATIBILITY IDEOGRAPH-2F93B +2F93C ; [.FB84.0020.0002.24FB8][.CFB8.0000.0000.24FB8] # CJK COMPATIBILITY IDEOGRAPH-2F93C +2F93D ; [.FB84.0020.0002.25044][.D044.0000.0000.25044] # CJK COMPATIBILITY IDEOGRAPH-2F93D +2F942 ; [.FB84.0020.0002.250F2][.D0F2.0000.0000.250F2] # CJK COMPATIBILITY IDEOGRAPH-2F942 +2F941 ; [.FB84.0020.0002.250F3][.D0F3.0000.0000.250F3] # CJK COMPATIBILITY IDEOGRAPH-2F941 +2F943 ; [.FB84.0020.0002.25119][.D119.0000.0000.25119] # CJK COMPATIBILITY IDEOGRAPH-2F943 +2F944 ; [.FB84.0020.0002.25133][.D133.0000.0000.25133] # CJK COMPATIBILITY IDEOGRAPH-2F944 +FAD5 ; [.FB84.0020.0002.25249][.D249.0000.0000.25249] # CJK COMPATIBILITY IDEOGRAPH-FAD5 +2F94D ; [.FB84.0020.0002.2541D][.D41D.0000.0000.2541D] # CJK COMPATIBILITY IDEOGRAPH-2F94D +2F952 ; [.FB84.0020.0002.25626][.D626.0000.0000.25626] # CJK COMPATIBILITY IDEOGRAPH-2F952 +2F954 ; [.FB84.0020.0002.2569A][.D69A.0000.0000.2569A] # CJK COMPATIBILITY IDEOGRAPH-2F954 +2F955 ; [.FB84.0020.0002.256C5][.D6C5.0000.0000.256C5] # CJK COMPATIBILITY IDEOGRAPH-2F955 +2F95C ; [.FB84.0020.0002.2597C][.D97C.0000.0000.2597C] # CJK COMPATIBILITY IDEOGRAPH-2F95C +2F95D ; [.FB84.0020.0002.25AA7][.DAA7.0000.0000.25AA7] # CJK COMPATIBILITY IDEOGRAPH-2F95D +2F95E ; [.FB84.0020.0002.25AA7][.DAA7.0000.0000.25AA7] # CJK COMPATIBILITY IDEOGRAPH-2F95E +2F961 ; [.FB84.0020.0002.25BAB][.DBAB.0000.0000.25BAB] # CJK COMPATIBILITY IDEOGRAPH-2F961 +2F965 ; [.FB84.0020.0002.25C80][.DC80.0000.0000.25C80] # CJK COMPATIBILITY IDEOGRAPH-2F965 +FAD6 ; [.FB84.0020.0002.25CD0][.DCD0.0000.0000.25CD0] # CJK COMPATIBILITY IDEOGRAPH-FAD6 +2F96B ; [.FB84.0020.0002.25F86][.DF86.0000.0000.25F86] # CJK COMPATIBILITY IDEOGRAPH-2F96B +2F898 ; [.FB84.0020.0002.261DA][.E1DA.0000.0000.261DA] # CJK COMPATIBILITY IDEOGRAPH-2F898 +2F972 ; [.FB84.0020.0002.26228][.E228.0000.0000.26228] # CJK COMPATIBILITY IDEOGRAPH-2F972 +2F973 ; [.FB84.0020.0002.26247][.E247.0000.0000.26247] # CJK COMPATIBILITY IDEOGRAPH-2F973 +2F975 ; [.FB84.0020.0002.262D9][.E2D9.0000.0000.262D9] # CJK COMPATIBILITY IDEOGRAPH-2F975 +2F977 ; [.FB84.0020.0002.2633E][.E33E.0000.0000.2633E] # CJK COMPATIBILITY IDEOGRAPH-2F977 +2F97B ; [.FB84.0020.0002.264DA][.E4DA.0000.0000.264DA] # CJK COMPATIBILITY IDEOGRAPH-2F97B +2F97C ; [.FB84.0020.0002.26523][.E523.0000.0000.26523] # CJK COMPATIBILITY IDEOGRAPH-2F97C +2F97E ; [.FB84.0020.0002.265A8][.E5A8.0000.0000.265A8] # CJK COMPATIBILITY IDEOGRAPH-2F97E +2F987 ; [.FB84.0020.0002.267A7][.E7A7.0000.0000.267A7] # CJK COMPATIBILITY IDEOGRAPH-2F987 +2F988 ; [.FB84.0020.0002.267B5][.E7B5.0000.0000.267B5] # CJK COMPATIBILITY IDEOGRAPH-2F988 +2F997 ; [.FB84.0020.0002.26B3C][.EB3C.0000.0000.26B3C] # CJK COMPATIBILITY IDEOGRAPH-2F997 +2F9A4 ; [.FB84.0020.0002.26C36][.EC36.0000.0000.26C36] # CJK COMPATIBILITY IDEOGRAPH-2F9A4 +2F9A6 ; [.FB84.0020.0002.26CD5][.ECD5.0000.0000.26CD5] # CJK COMPATIBILITY IDEOGRAPH-2F9A6 +2F9A5 ; [.FB84.0020.0002.26D6B][.ED6B.0000.0000.26D6B] # CJK COMPATIBILITY IDEOGRAPH-2F9A5 +2F9AD ; [.FB84.0020.0002.26F2C][.EF2C.0000.0000.26F2C] # CJK COMPATIBILITY IDEOGRAPH-2F9AD +2F9B0 ; [.FB84.0020.0002.26FB1][.EFB1.0000.0000.26FB1] # CJK COMPATIBILITY IDEOGRAPH-2F9B0 +2F9B1 ; [.FB84.0020.0002.270D2][.F0D2.0000.0000.270D2] # CJK COMPATIBILITY IDEOGRAPH-2F9B1 +2F9AB ; [.FB84.0020.0002.273CA][.F3CA.0000.0000.273CA] # CJK COMPATIBILITY IDEOGRAPH-2F9AB +2F9C5 ; [.FB84.0020.0002.27667][.F667.0000.0000.27667] # CJK COMPATIBILITY IDEOGRAPH-2F9C5 +2F9CB ; [.FB84.0020.0002.278AE][.F8AE.0000.0000.278AE] # CJK COMPATIBILITY IDEOGRAPH-2F9CB +2F9CC ; [.FB84.0020.0002.27966][.F966.0000.0000.27966] # CJK COMPATIBILITY IDEOGRAPH-2F9CC +2F9D3 ; [.FB84.0020.0002.27CA8][.FCA8.0000.0000.27CA8] # CJK COMPATIBILITY IDEOGRAPH-2F9D3 +FAD7 ; [.FB84.0020.0002.27ED3][.FED3.0000.0000.27ED3] # CJK COMPATIBILITY IDEOGRAPH-FAD7 +2F9D8 ; [.FB84.0020.0002.27F2F][.FF2F.0000.0000.27F2F] # CJK COMPATIBILITY IDEOGRAPH-2F9D8 +2F9E0 ; [.FB85.0020.0002.285D2][.85D2.0000.0000.285D2] # CJK COMPATIBILITY IDEOGRAPH-2F9E0 +2F9E1 ; [.FB85.0020.0002.285ED][.85ED.0000.0000.285ED] # CJK COMPATIBILITY IDEOGRAPH-2F9E1 +2F9E5 ; [.FB85.0020.0002.2872E][.872E.0000.0000.2872E] # CJK COMPATIBILITY IDEOGRAPH-2F9E5 +2F9ED ; [.FB85.0020.0002.28BFA][.8BFA.0000.0000.28BFA] # CJK COMPATIBILITY IDEOGRAPH-2F9ED +2F9F1 ; [.FB85.0020.0002.28D77][.8D77.0000.0000.28D77] # CJK COMPATIBILITY IDEOGRAPH-2F9F1 +2F9F6 ; [.FB85.0020.0002.29145][.9145.0000.0000.29145] # CJK COMPATIBILITY IDEOGRAPH-2F9F6 +2F81C ; [.FB85.0020.0002.291DF][.91DF.0000.0000.291DF] # CJK COMPATIBILITY IDEOGRAPH-2F81C +2F9F7 ; [.FB85.0020.0002.2921A][.921A.0000.0000.2921A] # CJK COMPATIBILITY IDEOGRAPH-2F9F7 +2F9FB ; [.FB85.0020.0002.2940A][.940A.0000.0000.2940A] # CJK COMPATIBILITY IDEOGRAPH-2F9FB +2F9FD ; [.FB85.0020.0002.29496][.9496.0000.0000.29496] # CJK COMPATIBILITY IDEOGRAPH-2F9FD +2FA01 ; [.FB85.0020.0002.295B6][.95B6.0000.0000.295B6] # CJK COMPATIBILITY IDEOGRAPH-2FA01 +2FA09 ; [.FB85.0020.0002.29B30][.9B30.0000.0000.29B30] # CJK COMPATIBILITY IDEOGRAPH-2FA09 +2FA10 ; [.FB85.0020.0002.2A0CE][.A0CE.0000.0000.2A0CE] # CJK COMPATIBILITY IDEOGRAPH-2FA10 +2FA12 ; [.FB85.0020.0002.2A105][.A105.0000.0000.2A105] # CJK COMPATIBILITY IDEOGRAPH-2FA12 +2FA13 ; [.FB85.0020.0002.2A20E][.A20E.0000.0000.2A20E] # CJK COMPATIBILITY IDEOGRAPH-2FA13 +2FA14 ; [.FB85.0020.0002.2A291][.A291.0000.0000.2A291] # CJK COMPATIBILITY IDEOGRAPH-2FA14 +2F88F ; [.FB85.0020.0002.2A392][.A392.0000.0000.2A392] # CJK COMPATIBILITY IDEOGRAPH-2F88F +2FA1D ; [.FB85.0020.0002.2A600][.A600.0000.0000.2A600] # CJK COMPATIBILITY IDEOGRAPH-2FA1D diff --git a/web2py/gluon/contrib/pyuca/pyuca.py b/web2py/gluon/contrib/pyuca/pyuca.py new file mode 100644 index 0000000..ce41fde --- /dev/null +++ b/web2py/gluon/contrib/pyuca/pyuca.py @@ -0,0 +1,144 @@ +# pyuca - Unicode Collation Algorithm +# Version: 2012-06-21 +# +# James Tauber +# http://jtauber.com/ + +# Copyright (c) 2006-2012 James Tauber and 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. + + +""" +Preliminary implementation of the Unicode Collation Algorithm. + +This only implements the simple parts of the algorithm but I have successfully +tested it using the Default Unicode Collation Element Table (DUCET) to collate +Ancient Greek correctly. + +Usage example: + + from pyuca import Collator + c = Collator("allkeys.txt") + + sorted_words = sorted(words, key=c.sort_key) + +allkeys.txt (1 MB) is available at + + http://www.unicode.org/Public/UCA/latest/allkeys.txt + +but you can always subset this for just the characters you are dealing with. +""" + + +class Node: + + def __init__(self): + self.value = None + self.children = {} + + +class Trie: + + def __init__(self): + self.root = Node() + + def add(self, key, value): + curr_node = self.root + for part in key: + curr_node = curr_node.children.setdefault(part, Node()) + curr_node.value = value + + def find_prefix(self, key): + curr_node = self.root + remainder = key + for part in key: + if part not in curr_node.children: + break + curr_node = curr_node.children[part] + remainder = remainder[1:] + return (curr_node.value, remainder) + + +class Collator: + + def __init__(self, filename): + + self.table = Trie() + self.load(filename) + + def load(self, filename): + for line in open(filename): + if line.startswith("#") or line.startswith("%"): + continue + if line.strip() == "": + continue + line = line[:line.find("#")] + "\n" + line = line[:line.find("%")] + "\n" + line = line.strip() + + if line.startswith("@"): + pass + else: + semicolon = line.find(";") + charList = line[:semicolon].strip().split() + x = line[semicolon:] + collElements = [] + while True: + begin = x.find("[") + if begin == -1: + break + end = x[begin:].find("]") + collElement = x[begin:begin+end+1] + x = x[begin + 1:] + + alt = collElement[1] + chars = collElement[2:-1].split(".") + + collElements.append((alt, chars)) + integer_points = [int(ch, 16) for ch in charList] + self.table.add(integer_points, collElements) + + def sort_key(self, string): + + collation_elements = [] + + lookup_key = [ord(ch) for ch in string] + while lookup_key: + value, lookup_key = self.table.find_prefix(lookup_key) + if not value: + # Calculate implicit weighting for CJK Ideographs + # contributed by David Schneider 2009-07-27 + # http://www.unicode.org/reports/tr10/#Implicit_Weights + value = [] + value.append((".", ["%X" % (0xFB40 + (lookup_key[0] >> 15)), "0020", "0002", "0001"])) + value.append((".", ["%X" % ((lookup_key[0] & 0x7FFF) | 0x8000), "0000", "0000", "0000"])) + lookup_key = lookup_key[1:] + collation_elements.extend(value) + sort_key = [] + + for level in range(4): + if level: + sort_key.append(0) # level separator + for element in collation_elements: + ce_l = int(element[1][level], 16) + if ce_l: + sort_key.append(ce_l) + + return tuple(sort_key) diff --git a/web2py/gluon/contrib/redis_cache.py b/web2py/gluon/contrib/redis_cache.py new file mode 100644 index 0000000..6241fbc --- /dev/null +++ b/web2py/gluon/contrib/redis_cache.py @@ -0,0 +1,285 @@ +""" +Developed by niphlod@gmail.com +Released under web2py license because includes gluon/cache.py source code +""" + +try: + import cPickle as pickle +except: + import pickle +import time +import re +import logging +from threading import Lock +import random +from gluon import current +from gluon.cache import CacheAbstract +from gluon.contrib.redis_utils import acquire_lock, release_lock +from gluon.contrib.redis_utils import register_release_lock, RConnectionError + +logger = logging.getLogger("web2py.cache.redis") + +locker = Lock() + + +def RedisCache(redis_conn=None, debug=False, with_lock=False, fail_gracefully=False, db=None): + """ + Usage example: put in models:: + + First of all install Redis + Ubuntu : + sudo apt-get install redis-server + sudo pip install redis + + Then + + from gluon.contrib.redis_utils import RConn + rconn = RConn() + from gluon.contrib.redis_cache import RedisCache + cache.redis = RedisCache(redis_conn=rconn, debug=True, with_lock=True) + + Args: + redis_conn: a redis-like connection object + debug: if True adds to stats() the total_hits and misses + with_lock: sets the default locking mode for creating new keys. + By default is False (usualy when you choose Redis you do it + for performances reason) + When True, only one thread/process can set a value concurrently + fail_gracefully: if redis is unavailable, returns the value computing it + instead of raising an exception + + It can be used pretty much the same as cache.ram() + When you use cache.redis directly you can use : + + redis_key_and_var_name = cache.redis('redis_key_and_var_name', lambda or function, + time_expire=time.time(), with_lock=True) + + to enforce locking. The with_lock parameter overrides the one set in the + cache.redis instance creation + + cache.redis.stats() + returns a dictionary with statistics of Redis server + with one additional key ('w2p_keys') showing all keys currently set + from web2py with their TTL + + A little wording on how keys are stored (and why the cache_it() function + and the clear() one look a little bit convoluted): there are a lot of + libraries that just store values and then use the KEYS command to delete it. + Until recent releases of this module, that technique was used here too. + In the need of deleting specific keys in a database with zillions keys in it + (other web2py apps, other applications in the need of a Redis stack) the + KEYS command is slow (it needs to scan every key in the database). + So, we use Redis 'sets' to store keys in "buckets"... + - every key created gets "indexed" in a bucket + - all buckets are indexed in a fixed key that never expires + - all keys generated within the same minute go in the same bucket + - every bucket is then set to expire when every key within it is expired + When we need to clear() cached keys: + - we tell Redis to SUNION all buckets + - gives us just the keys that are not expired yet + - buckets that are expired are removed from the fixed set + - we scan the keys and then delete them + """ + + locker.acquire() + try: + instance_name = 'redis_instance_' + current.request.application + if not hasattr(RedisCache, instance_name): + setattr(RedisCache, instance_name, + RedisClient(redis_conn=redis_conn, debug=debug, + with_lock=with_lock, fail_gracefully=fail_gracefully)) + return getattr(RedisCache, instance_name) + finally: + locker.release() + + +class RedisClient(object): + + meta_storage = {} + MAX_RETRIES = 5 + RETRIES = 0 + + def __init__(self, redis_conn=None, debug=False, + with_lock=False, fail_gracefully=False): + self.request = current.request + self.debug = debug + self.with_lock = with_lock + self.fail_gracefully = fail_gracefully + self.prefix = "w2p:cache:%s:" % self.request.application + if self.request: + app = self.request.application + else: + app = '' + + if app not in self.meta_storage: + self.storage = self.meta_storage[app] = { + CacheAbstract.cache_stats_name: { + 'hit_total': 0, + 'misses': 0, + }} + else: + self.storage = self.meta_storage[app] + + self.cache_set_key = 'w2p:%s:___cache_set' % self.request.application + + self.r_server = redis_conn + self._release_script = register_release_lock(self.r_server) + + def initialize(self): + pass + + def __call__(self, key, f, time_expire=300, with_lock=None): + if with_lock is None: + with_lock = self.with_lock + if time_expire is None: + time_expire = 24 * 60 * 60 + newKey = self.__keyFormat__(key) + value = None + ttl = 0 + try: + if f is None: + # delete and never look back + self.r_server.delete(newKey) + return None + # is there a value + obj = self.r_server.get(newKey) + # what's its ttl + if obj: + ttl = self.r_server.ttl(newKey) + if ttl > time_expire: + obj = None + if obj: + # was cached + if self.debug: + self.r_server.incr('web2py_cache_statistics:hit_total') + value = pickle.loads(obj) + else: + # naive distributed locking + if with_lock: + lock_key = '%s:__lock' % newKey + randomvalue = time.time() + al = acquire_lock(self.r_server, lock_key, randomvalue) + try: + # someone may have computed it + obj = self.r_server.get(newKey) + if obj is None: + value = self.cache_it(newKey, f, time_expire) + else: + value = pickle.loads(obj) + finally: + release_lock(self, lock_key, al) + else: + # without distributed locking + value = self.cache_it(newKey, f, time_expire) + return value + except RConnectionError: + return self.retry_call(key, f, time_expire, with_lock) + + def cache_it(self, key, f, time_expire): + if self.debug: + self.r_server.incr('web2py_cache_statistics:misses') + cache_set_key = self.cache_set_key + expire_at = int(time.time() + time_expire) + 120 + bucket_key = "%s:%s" % (cache_set_key, expire_at / 60) + value = f() + value_ = pickle.dumps(value, pickle.HIGHEST_PROTOCOL) + if time_expire == 0: + time_expire = 1 + self.r_server.setex(key, time_expire, value_) + # print '%s will expire on %s: it goes in bucket %s' % (key, time.ctime(expire_at)) + # print 'that will expire on %s' % (bucket_key, time.ctime(((expire_at / 60) + 1) * 60)) + p = self.r_server.pipeline() + # add bucket to the fixed set + p.sadd(cache_set_key, bucket_key) + # sets the key + p.setex(key, time_expire, value_) + # add the key to the bucket + p.sadd(bucket_key, key) + # expire the bucket properly + p.expireat(bucket_key, ((expire_at / 60) + 1) * 60) + p.execute() + return value + + def retry_call(self, key, f, time_expire, with_lock): + self.RETRIES += 1 + if self.RETRIES <= self.MAX_RETRIES: + logger.error("sleeping %s seconds before reconnecting" % (2 * self.RETRIES)) + time.sleep(2 * self.RETRIES) + if self.fail_gracefully: + self.RETRIES = 0 + return f() + return self.__call__(key, f, time_expire, with_lock) + else: + self.RETRIES = 0 + if self.fail_gracefully: + return f + raise RConnectionError('Redis instance is unavailable') + + def increment(self, key, value=1): + try: + newKey = self.__keyFormat__(key) + return self.r_server.incr(newKey, value) + except RConnectionError: + return self.retry_increment(key, value) + + def retry_increment(self, key, value): + self.RETRIES += 1 + if self.RETRIES <= self.MAX_RETRIES: + logger.error("sleeping some seconds before reconnecting") + time.sleep(2 * self.RETRIES) + return self.increment(key, value) + else: + self.RETRIES = 0 + raise RConnectionError('Redis instance is unavailable') + + def clear(self, regex): + """ + Auxiliary function called by `clear` to search and + clear cache entries + """ + r = re.compile(regex) + # get all buckets + buckets = self.r_server.smembers(self.cache_set_key) + # get all keys in buckets + if buckets: + keys = self.r_server.sunion(buckets) + else: + return + prefix = self.prefix + pipe = self.r_server.pipeline() + for a in keys: + if r.match(str(a).replace(prefix, '', 1)): + pipe.delete(a) + if random.randrange(0, 100) < 10: + # do this just once in a while (10% chance) + self.clear_buckets(buckets) + pipe.execute() + + def clear_buckets(self, buckets): + p = self.r_server.pipeline() + for b in buckets: + if not self.r_server.exists(b): + p.srem(self.cache_set_key, b) + p.execute() + + def delete(self, key): + newKey = self.__keyFormat__(key) + return self.r_server.delete(newKey) + + def stats(self): + stats_collector = self.r_server.info() + if self.debug: + stats_collector['w2p_stats'] = dict( + hit_total=self.r_server.get( + 'web2py_cache_statistics:hit_total'), + misses=self.r_server.get('web2py_cache_statistics:misses') + ) + stats_collector['w2p_keys'] = dict() + + for a in self.r_server.keys("w2p:%s:*" % ( + self.request.application)): + stats_collector['w2p_keys']["%s_expire_in_sec" % a] = self.r_server.ttl(a) + return stats_collector + + def __keyFormat__(self, key): + return '%s%s' % (self.prefix, key.replace(' ', '_')) diff --git a/web2py/gluon/contrib/redis_scheduler.py b/web2py/gluon/contrib/redis_scheduler.py new file mode 100644 index 0000000..6a3f00f --- /dev/null +++ b/web2py/gluon/contrib/redis_scheduler.py @@ -0,0 +1,800 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +| This file is part of the web2py Web Framework +| Created by niphlod@gmail.com +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +Scheduler with redis backend +--------------------------------- +""" +from __future__ import print_function + +import os +import time +import socket +import datetime +import logging +from json import loads, dumps +from gluon.utils import web2py_uuid +from gluon.storage import Storage +from gluon.scheduler import * +from gluon.scheduler import _decode_dict +from gluon.contrib.redis_utils import RWatchError + +USAGE = """ +## Example + +For any existing app + +Create File: app/models/scheduler.py ====== +from gluon.contrib.redis_utils import RConn +from gluon.contrib.redis_scheduler import RScheduler + +def demo1(*args,**vars): + print('you passed args=%s and vars=%s' % (args, vars)) + return 'done!' + +def demo2(): + 1/0 + +rconn = RConn() +mysched = RScheduler(db, dict(demo1=demo1,demo2=demo2), ...., redis_conn=rconn) + +## run worker nodes with: + + cd web2py + python web2py.py -K app + +""" + + +path = os.getcwd() + +if 'WEB2PY_PATH' not in os.environ: + os.environ['WEB2PY_PATH'] = path + +IDENTIFIER = "%s#%s" % (socket.gethostname(), os.getpid()) + +logger = logging.getLogger('web2py.scheduler.%s' % IDENTIFIER) + +POLLING = 'POLLING' + + +class RScheduler(Scheduler): + + def __init__(self, db, tasks=None, migrate=True, + worker_name=None, group_names=None, heartbeat=HEARTBEAT, + max_empty_runs=0, discard_results=False, utc_time=False, + redis_conn=None, mode=1): + + """ + Highly-experimental coordination with redis + Takes all args from Scheduler except redis_conn which + must be something closer to a StrictRedis instance. + + My only regret - and the reason why I kept this under the hood for a + while - is that it's hard to hook up in web2py to something happening + right after the commit to a table, which will enable this version of the + scheduler to process "immediate" tasks right away instead of waiting a + few seconds (see FIXME in queue_task()) + + mode is reserved for future usage patterns. + Right now it moves the coordination (which is the most intensive + routine in the scheduler in matters of IPC) of workers to redis. + I'd like to have incrementally redis-backed modes of operations, + such as e.g.: + - 1: IPC through redis (which is the current implementation) + - 2: Store task results in redis (which will relieve further pressure + from the db leaving the scheduler_run table empty and possibly + keep things smooth as tasks results can be set to expire + after a bit of time) + - 3: Move all the logic for storing and queueing tasks to redis + itself - which means no scheduler_task usage too - and use + the database only as an historical record-bookkeeping + (e.g. for reporting) + + As usual, I'm eager to see your comments. + """ + + Scheduler.__init__(self, db, tasks=tasks, migrate=migrate, + worker_name=worker_name, group_names=group_names, + heartbeat=heartbeat, max_empty_runs=max_empty_runs, + discard_results=discard_results, utc_time=utc_time) + + self.r_server = redis_conn + from gluon import current + self._application = current.request.application or 'appname' + + def _nkey(self, key): + """Helper to restrict all keys to a namespace and track them.""" + prefix = 'w2p:rsched:%s' % self._application + allkeys = '%s:allkeys' % prefix + newkey = "%s:%s" % (prefix, key) + self.r_server.sadd(allkeys, newkey) + return newkey + + def prune_all(self): + """Global housekeeping.""" + all_keys = self._nkey('allkeys') + with self.r_server.pipeline() as pipe: + while True: + try: + pipe.watch('PRUNE_ALL') + while True: + k = pipe.spop(all_keys) + if k is None: + break + pipe.delete(k) + pipe.execute() + break + except RWatchError: + time.sleep(0.1) + continue + + def dt2str(self, value): + return value.strftime('%Y-%m-%d %H:%M:%S') + + def str2date(self, value): + return datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S') + + def send_heartbeat(self, counter): + """ + Workers coordination in redis. + It has evolved into something is not that easy. + Here we try to do what we need in a single transaction, + and retry that transaction if something goes wrong + """ + with self.r_server.pipeline() as pipe: + while True: + try: + pipe.watch('SEND_HEARTBEAT') + self.inner_send_heartbeat(counter, pipe) + pipe.execute() + self.adj_hibernation() + self.sleep() + break + except RWatchError: + time.sleep(0.1) + continue + + def inner_send_heartbeat(self, counter, pipe): + """ + Do a few things in the "maintenance" thread. + + Specifically: + - registers the workers + - accepts commands sent to workers (KILL, TERMINATE, PICK, DISABLED, etc) + - adjusts sleep + - saves stats + - elects master + - does "housecleaning" for dead workers + - triggers tasks assignment + """ + r_server = pipe + status_keyset = self._nkey('worker_statuses') + status_key = self._nkey('worker_status:%s' % (self.worker_name)) + now = self.now() + mybackedstatus = r_server.hgetall(status_key) + if not mybackedstatus: + r_server.hmset( + status_key, + dict( + status=ACTIVE, worker_name=self.worker_name, + first_heartbeat=self.dt2str(now), + last_heartbeat=self.dt2str(now), + group_names=dumps(self.group_names), is_ticker=False, + worker_stats=dumps(self.w_stats)) + ) + r_server.sadd(status_keyset, status_key) + if not self.w_stats.status == POLLING: + self.w_stats.status = ACTIVE + self.w_stats.sleep = self.heartbeat + mybackedstatus = ACTIVE + else: + mybackedstatus = mybackedstatus['status'] + if mybackedstatus == DISABLED: + # keep sleeping + self.w_stats.status = DISABLED + r_server.hmset( + status_key, + dict(last_heartbeat=self.dt2str(now), + worker_stats=dumps(self.w_stats)) + ) + elif mybackedstatus == TERMINATE: + self.w_stats.status = TERMINATE + logger.debug("Waiting to terminate the current task") + self.give_up() + elif mybackedstatus == KILL: + self.w_stats.status = KILL + self.die() + else: + if mybackedstatus == STOP_TASK: + logger.info('Asked to kill the current task') + self.terminate_process() + logger.info('........recording heartbeat (%s)', + self.w_stats.status) + r_server.hmset( + status_key, + dict( + last_heartbeat=self.dt2str(now), status=ACTIVE, + worker_stats=dumps(self.w_stats) + ) + ) + # newroutine + r_server.expire(status_key, self.heartbeat * 3 * 15) + self.w_stats.sleep = self.heartbeat # re-activating the process + if self.w_stats.status not in (RUNNING, POLLING): + self.w_stats.status = ACTIVE + + self.do_assign_tasks = False + if counter % 5 == 0 or mybackedstatus == PICK: + try: + logger.info( + ' freeing workers that have not sent heartbeat') + registered_workers = r_server.smembers(status_keyset) + allkeys = self._nkey('allkeys') + for worker in registered_workers: + w = r_server.hgetall(worker) + w = Storage(w) + if not w: + r_server.srem(status_keyset, worker) + logger.info('removing %s from %s', worker, allkeys) + r_server.srem(allkeys, worker) + continue + try: + self.is_a_ticker = self.being_a_ticker(pipe) + except: + pass + if self.w_stats.status in (ACTIVE, POLLING): + self.do_assign_tasks = True + if self.is_a_ticker and self.do_assign_tasks: + # I'm a ticker, and 5 loops passed without reassigning tasks, + # let's do that and loop again + if not self.db_thread: + logger.debug('thread building own DAL object') + self.db_thread = DAL( + self.db._uri, folder=self.db._adapter.folder) + self.define_tables(self.db_thread, migrate=False) + db = self.db_thread + self.wrapped_assign_tasks(db) + return None + except: + logger.error('Error assigning tasks') + + def being_a_ticker(self, pipe): + """ + Elects a ticker. + + This is slightly more convoluted than the original + but if far more efficient + """ + r_server = pipe + status_keyset = self._nkey('worker_statuses') + registered_workers = r_server.smembers(status_keyset) + ticker = None + all_active = [] + all_workers = [] + for worker in registered_workers: + w = r_server.hgetall(worker) + if w['worker_name'] != self.worker_name and w['status'] == ACTIVE: + all_active.append(w) + if w['is_ticker'] == 'True' and ticker is None: + ticker = w + all_workers.append(w) + not_busy = self.w_stats.status in (ACTIVE, POLLING) + if not ticker: + if not_busy: + # only if this worker isn't busy, otherwise wait for a free one + for worker in all_workers: + key = self._nkey('worker_status:%s' % worker['worker_name']) + if worker['worker_name'] == self.worker_name: + r_server.hset(key, 'is_ticker', True) + else: + r_server.hset(key, 'is_ticker', False) + logger.info("TICKER: I'm a ticker") + else: + # giving up, only if I'm not alone + if len(all_active) > 1: + key = self._nkey('worker_status:%s' % (self.worker_name)) + r_server.hset(key, 'is_ticker', False) + else: + not_busy = True + return not_busy + else: + logger.info( + "%s is a ticker, I'm a poor worker" % ticker['worker_name']) + return False + + def assign_tasks(self, db): + """ + The real beauty. + + We don't need to ASSIGN tasks, we just put + them into the relevant queue + """ + st, sd = db.scheduler_task, db.scheduler_task_deps + r_server = self.r_server + now = self.now() + status_keyset = self._nkey('worker_statuses') + with r_server.pipeline() as pipe: + while True: + try: + # making sure we're the only one doing the job + pipe.watch('ASSIGN_TASKS') + registered_workers = pipe.smembers(status_keyset) + all_workers = [] + for worker in registered_workers: + w = pipe.hgetall(worker) + if w['status'] == ACTIVE: + all_workers.append(Storage(w)) + pipe.execute() + break + except RWatchError: + time.sleep(0.1) + continue + + # build workers as dict of groups + wkgroups = {} + for w in all_workers: + group_names = loads(w.group_names) + for gname in group_names: + if gname not in wkgroups: + wkgroups[gname] = dict( + workers=[{'name': w.worker_name, 'c': 0}]) + else: + wkgroups[gname]['workers'].append( + {'name': w.worker_name, 'c': 0}) + # set queued tasks that expired between "runs" (i.e., you turned off + # the scheduler): then it wasn't expired, but now it is + db( + (st.status.belongs((QUEUED, ASSIGNED))) & + (st.stop_time < now) + ).update(status=EXPIRED) + + # calculate dependencies + deps_with_no_deps = db( + (sd.can_visit == False) & + (~sd.task_child.belongs( + db(sd.can_visit == False)._select(sd.task_parent) + ) + ) + )._select(sd.task_child) + no_deps = db( + (st.status.belongs((QUEUED, ASSIGNED))) & + ( + (sd.id == None) | (st.id.belongs(deps_with_no_deps)) + + ) + )._select(st.id, distinct=True, left=sd.on( + (st.id == sd.task_parent) & + (sd.can_visit == False) + ) + ) + + all_available = db( + (st.status.belongs((QUEUED, ASSIGNED))) & + (st.next_run_time <= now) & + (st.enabled == True) & + (st.id.belongs(no_deps)) + ) + + limit = len(all_workers) * (50 / (len(wkgroups) or 1)) + + # let's freeze it up + db.commit() + x = 0 + r_server = self.r_server + for group in wkgroups.keys(): + queued_list = self._nkey('queued:%s' % group) + queued_set = self._nkey('queued_set:%s' % group) + # if are running, let's don't assign them again + running_list = self._nkey('running:%s' % group) + while True: + # the joys for rpoplpush! + t = r_server.rpoplpush(running_list, queued_list) + if not t: + # no more + break + r_server.sadd(queued_set, t) + + tasks = all_available(st.group_name == group).select( + limitby=(0, limit), orderby = st.next_run_time) + + # put tasks in the processing list + + for task in tasks: + x += 1 + gname = task.group_name + + if r_server.sismember(queued_set, task.id): + # already queued, we don't put on the list + continue + r_server.sadd(queued_set, task.id) + r_server.lpush(queued_list, task.id) + d = dict(status=QUEUED) + if not task.task_name: + d['task_name'] = task.function_name + db( + (st.id == task.id) & + (st.status.belongs((QUEUED, ASSIGNED))) + ).update(**d) + db.commit() + # I didn't report tasks but I'm working nonetheless!!!! + if x > 0: + self.w_stats.empty_runs = 0 + self.w_stats.queue = x + self.w_stats.distribution = wkgroups + self.w_stats.workers = len(all_workers) + # I'll be greedy only if tasks queued are equal to the limit + # (meaning there could be others ready to be queued) + self.greedy = x >= limit + logger.info('TICKER: workers are %s', len(all_workers)) + logger.info('TICKER: tasks are %s', x) + + def pop_task(self, db): + """Lift a task off a queue.""" + r_server = self.r_server + st = self.db.scheduler_task + task = None + # ready to process something + for group in self.group_names: + queued_set = self._nkey('queued_set:%s' % group) + queued_list = self._nkey('queued:%s' % group) + running_list = self._nkey('running:%s' % group) + running_dict = self._nkey('running_dict:%s' % group) + self.w_stats.status = POLLING + # polling for 1 minute in total. If more groups are in, + # polling is 1 minute in total + logger.debug(' polling on %s', group) + task_id = r_server.brpoplpush(queued_list, running_list, + timeout=60 / len(self.group_names)) + logger.debug(' finished polling') + self.w_stats.status = ACTIVE + if task_id: + r_server.hset(running_dict, task_id, self.worker_name) + r_server.srem(queued_set, task_id) + task = db( + (st.id == task_id) & + (st.status == QUEUED) + ).select().first() + if not task: + r_server.lrem(running_list, 0, task_id) + r_server.hdel(running_dict, task_id) + r_server.lrem(queued_list, 0, task_id) + logger.error("we received a task that isn't there (%s)", + task_id) + return None + break + now = self.now() + if task: + task.update_record(status=RUNNING, last_run_time=now) + # noone will touch my task! + db.commit() + logger.debug(' work to do %s', task.id) + else: + logger.info('nothing to do') + return None + times_run = task.times_run + 1 + if task.cronline: + cron_recur = CronParser(task.cronline, now.replace(second=0)) + next_run_time = cron_recur.get_next() + elif not task.prevent_drift: + next_run_time = task.last_run_time + datetime.timedelta( + seconds=task.period + ) + else: + # calc next_run_time based on available slots + # see #1191 + next_run_time = task.start_time + secondspassed = self.total_seconds(now - next_run_time) + steps = secondspassed // task.period + 1 + next_run_time += datetime.timedelta(seconds=task.period * steps) + + if times_run < task.repeats or task.repeats == 0: + # need to run (repeating task) + run_again = True + else: + # no need to run again + run_again = False + run_id = 0 + while True and not self.discard_results: + logger.debug(' new scheduler_run record') + try: + run_id = db.scheduler_run.insert( + task_id=task.id, + status=RUNNING, + start_time=now, + worker_name=self.worker_name) + db.commit() + break + except: + time.sleep(0.5) + db.rollback() + logger.info('new task %(id)s "%(task_name)s"' + ' %(application_name)s.%(function_name)s' % task) + return Task( + app=task.application_name, + function=task.function_name, + timeout=task.timeout, + args=task.args, # in json + vars=task.vars, # in json + task_id=task.id, + run_id=run_id, + run_again=run_again, + next_run_time=next_run_time, + times_run=times_run, + stop_time=task.stop_time, + retry_failed=task.retry_failed, + times_failed=task.times_failed, + sync_output=task.sync_output, + uuid=task.uuid, + group_name=task.group_name) + + def report_task(self, task, task_report): + """ + Override. + + Needs it only because we need to pop from the + running tasks + """ + r_server = self.r_server + db = self.db + now = self.now() + st = db.scheduler_task + sr = db.scheduler_run + if not self.discard_results: + if task_report.result != 'null' or task_report.tb: + # result is 'null' as a string if task completed + # if it's stopped it's None as NoneType, so we record + # the STOPPED "run" anyway + logger.debug(' recording task report in db (%s)', + task_report.status) + db(sr.id == task.run_id).update( + status=task_report.status, + stop_time=now, + run_result=task_report.result, + run_output=task_report.output, + traceback=task_report.tb) + else: + logger.debug(' deleting task report in db because of no result') + db(sr.id == task.run_id).delete() + # if there is a stop_time and the following run would exceed it + is_expired = (task.stop_time and + task.next_run_time > task.stop_time and + True or False) + status = (task.run_again and is_expired and EXPIRED or + task.run_again and not is_expired and + QUEUED or COMPLETED) + if task_report.status == COMPLETED: + # assigned calculations + d = dict(status=status, + next_run_time=task.next_run_time, + times_run=task.times_run, + times_failed=0, + assigned_worker_name=self.worker_name + ) + db(st.id == task.task_id).update(**d) + if status == COMPLETED: + self.update_dependencies(db, task.task_id) + else: + st_mapping = {'FAILED': 'FAILED', + 'TIMEOUT': 'TIMEOUT', + 'STOPPED': 'FAILED'}[task_report.status] + status = (task.retry_failed and + task.times_failed < task.retry_failed and + QUEUED or task.retry_failed == -1 and + QUEUED or st_mapping) + db(st.id == task.task_id).update( + times_failed=st.times_failed + 1, + next_run_time=task.next_run_time, + status=status, + assigned_worker_name=self.worker_name + ) + logger.info('task completed (%s)', task_report.status) + running_list = self._nkey('running:%s' % task.group_name) + running_dict = self._nkey('running_dict:%s' % task.group_name) + r_server.lrem(running_list, 0, task.task_id) + r_server.hdel(running_dict, task.task_id) + + def wrapped_pop_task(self): + """Commodity function to call `pop_task` and trap exceptions. + If an exception is raised, assume it happened because of database + contention and retries `pop_task` after 0.5 seconds + """ + db = self.db + db.commit() # another nifty db.commit() only for Mysql + x = 0 + while x < 10: + try: + rtn = self.pop_task(db) + return rtn + break + # this is here to "interrupt" any blrpoplpush op easily + except KeyboardInterrupt: + self.give_up() + break + except: + self.w_stats.errors += 1 + db.rollback() + logger.error(' error popping tasks') + x += 1 + time.sleep(0.5) + + def get_workers(self, only_ticker=False): + """Return a dict holding worker_name : {**columns} + representing all "registered" workers. + only_ticker returns only the worker running as a TICKER, + if there is any + """ + r_server = self.r_server + status_keyset = self._nkey('worker_statuses') + registered_workers = r_server.smembers(status_keyset) + all_workers = {} + for worker in registered_workers: + w = r_server.hgetall(worker) + w = Storage(w) + if not w: + continue + all_workers[w.worker_name] = Storage( + status=w.status, + first_heartbeat=self.str2date(w.first_heartbeat), + last_heartbeat=self.str2date(w.last_heartbeat), + group_names=loads(w.group_names, object_hook=_decode_dict), + is_ticker=w.is_ticker == 'True' and True or False, + worker_stats=loads(w.worker_stats, object_hook=_decode_dict) + ) + if only_ticker: + for k, v in all_workers.iteritems(): + if v['is_ticker']: + return {k: v} + return {} + return all_workers + + def set_worker_status(self, group_names=None, action=ACTIVE, + exclude=None, limit=None, worker_name=None): + """Internal function to set worker's status""" + r_server = self.r_server + all_workers = self.get_workers() + if not group_names: + group_names = self.group_names + elif isinstance(group_names, str): + group_names = [group_names] + exclusion = exclude and exclude.append(action) or [action] + workers = [] + if worker_name is not None: + if worker_name in all_workers.keys(): + workers = [worker_name] + else: + for k, v in all_workers.iteritems(): + if v.status not in exclusion and set(group_names) & set(v.group_names): + workers.append(k) + if limit and worker_name is None: + workers = workers[:limit] + if workers: + with r_server.pipeline() as pipe: + while True: + try: + pipe.watch('SET_WORKER_STATUS') + for w in workers: + worker_key = self._nkey('worker_status:%s' % w) + pipe.hset(worker_key, 'status', action) + pipe.execute() + break + except RWatchError: + time.sleep(0.1) + continue + + def queue_task(self, function, pargs=[], pvars={}, **kwargs): + """ + FIXME: immediate should put item in queue. The hard part is + that currently there are no hooks happening at post-commit time + Queue tasks. This takes care of handling the validation of all + parameters + + Args: + function: the function (anything callable with a __name__) + pargs: "raw" args to be passed to the function. Automatically + jsonified. + pvars: "raw" kwargs to be passed to the function. Automatically + jsonified + kwargs: all the parameters available (basically, every + `scheduler_task` column). If args and vars are here, they should + be jsonified already, and they will override pargs and pvars + + Returns: + a dict just as a normal validate_and_insert(), plus a uuid key + holding the uuid of the queued task. If validation is not passed + ( i.e. some parameters are invalid) both id and uuid will be None, + and you'll get an "error" dict holding the errors found. + """ + if hasattr(function, '__name__'): + function = function.__name__ + targs = 'args' in kwargs and kwargs.pop('args') or dumps(pargs) + tvars = 'vars' in kwargs and kwargs.pop('vars') or dumps(pvars) + tuuid = 'uuid' in kwargs and kwargs.pop('uuid') or web2py_uuid() + tname = 'task_name' in kwargs and kwargs.pop('task_name') or function + immediate = 'immediate' in kwargs and kwargs.pop('immediate') or None + cronline = kwargs.get('cronline') + kwargs.update(function_name=function, + task_name=tname, + args=targs, + vars=tvars, + uuid=tuuid) + if cronline: + try: + start_time = kwargs.get('start_time', self.now) + next_run_time = CronParser(cronline, start_time).get_next() + kwargs.update(start_time=start_time, next_run_time=next_run_time) + except: + pass + rtn = self.db.scheduler_task.validate_and_insert(**kwargs) + if not rtn.errors: + rtn.uuid = tuuid + if immediate: + r_server = self.r_server + ticker = self.get_workers(only_ticker=True) + if ticker.keys(): + ticker = ticker.keys()[0] + with r_server.pipeline() as pipe: + while True: + try: + pipe.watch('SET_WORKER_STATUS') + worker_key = self._nkey('worker_status:%s' % ticker) + pipe.hset(worker_key, 'status', 'PICK') + pipe.execute() + break + except RWatchError: + time.sleep(0.1) + continue + else: + rtn.uuid = None + return rtn + + def stop_task(self, ref): + """Shortcut for task termination. + + If the task is RUNNING it will terminate it, meaning that status + will be set as FAILED. + + If the task is QUEUED, its stop_time will be set as to "now", + the enabled flag will be set to False, and the status to STOPPED + + Args: + ref: can be + + - an integer : lookup will be done by scheduler_task.id + - a string : lookup will be done by scheduler_task.uuid + + Returns: + - 1 if task was stopped (meaning an update has been done) + - None if task was not found, or if task was not RUNNING or QUEUED + + Note: + Experimental + """ + r_server = self.r_server + st = self.db.scheduler_task + if isinstance(ref, int): + q = st.id == ref + elif isinstance(ref, str): + q = st.uuid == ref + else: + raise SyntaxError( + "You can retrieve results only by id or uuid") + task = self.db(q).select(st.id, st.status, st.group_name) + task = task.first() + rtn = None + if not task: + return rtn + running_dict = self._nkey('running_dict:%s' % task.group_name) + if task.status == 'RUNNING': + worker_key = r_server.hget(running_dict, task.id) + worker_key = self._nkey('worker_status:%s' % (worker_key)) + r_server.hset(worker_key, 'status', STOP_TASK) + elif task.status == 'QUEUED': + rtn = self.db(q).update( + stop_time=self.now(), + enabled=False, + status=STOPPED) + return rtn diff --git a/web2py/gluon/contrib/redis_session.py b/web2py/gluon/contrib/redis_session.py new file mode 100644 index 0000000..e577171 --- /dev/null +++ b/web2py/gluon/contrib/redis_session.py @@ -0,0 +1,254 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Developed by niphlod@gmail.com +License MIT/BSD/GPL + +Redis-backed sessions +""" + +import logging +from threading import Lock +from gluon import current +from gluon.storage import Storage +from gluon.contrib.redis_utils import acquire_lock, release_lock +from gluon.contrib.redis_utils import register_release_lock +from gluon._compat import to_bytes + +logger = logging.getLogger("web2py.session.redis") + +locker = Lock() + + +def RedisSession(redis_conn, session_expiry=False, with_lock=False, db=None): + """ + Usage example: put in models:: + + from gluon.contrib.redis_utils import RConn + rconn = RConn() + from gluon.contrib.redis_session import RedisSession + sessiondb = RedisSession(redis_conn=rconn, with_lock=True, session_expiry=False) + session.connect(request, response, db = sessiondb) + + Args: + redis_conn: a redis-like connection object + with_lock: prevent concurrent modifications to the same session + session_expiry: delete automatically sessions after n seconds + (still need to run sessions2trash.py every 1M sessions + or so) + + Simple slip-in storage for session + """ + + locker.acquire() + try: + instance_name = 'redis_instance_' + current.request.application + if not hasattr(RedisSession, instance_name): + setattr(RedisSession, instance_name, + RedisClient(redis_conn, session_expiry=session_expiry, with_lock=with_lock)) + return getattr(RedisSession, instance_name) + finally: + locker.release() + + +class RedisClient(object): + + def __init__(self, redis_conn, session_expiry=False, with_lock=False): + self.r_server = redis_conn + self._release_script = register_release_lock(self.r_server) + self.tablename = None + self.session_expiry = session_expiry + self.with_lock = with_lock + + def get(self, what, default): + return self.tablename + + def Field(self, fieldname, type='string', length=None, default=None, + required=False, requires=None): + return None + + def define_table(self, tablename, *fields, **args): + if not self.tablename: + self.tablename = MockTable( + self, self.r_server, tablename, self.session_expiry, + self.with_lock) + return self.tablename + + def __getitem__(self, key): + return self.tablename + + def __call__(self, where=''): + q = self.tablename.query + return q + + def commit(self): + # this is only called by session2trash.py + pass + + +class MockTable(object): + + def __init__(self, db, r_server, tablename, session_expiry, with_lock=False): + # here self.db is the RedisClient instance + self.db = db + self.tablename = tablename + # set the namespace for sessions of this app + self.keyprefix = 'w2p:sess:%s' % tablename.replace('web2py_session_', '') + # fast auto-increment id (needed for session handling) + self.serial = "%s:serial" % self.keyprefix + # index of all the session keys of this app + self.id_idx = "%s:id_idx" % self.keyprefix + # remember the session_expiry setting + self.session_expiry = session_expiry + self.with_lock = with_lock + + def __call__(self, record_id, unique_key=None): + # Support DAL shortcut query: table(record_id) + + # This will call the __getattr__ below + # returning a MockQuery + q = self.id + + # Instructs MockQuery, to behave as db(table.id == record_id) + q.op = 'eq' + q.value = record_id + q.unique_key = unique_key + + row = q.select() + return row[0] if row else Storage() + + def __getattr__(self, key): + if key == 'id': + # return a fake query. We need to query it just by id for normal operations + self.query = MockQuery( + field='id', db=self.db, + prefix=self.keyprefix, session_expiry=self.session_expiry, + with_lock=self.with_lock, unique_key=self.unique_key + ) + return self.query + elif key == '_db': + # needed because of the calls in sessions2trash.py and globals.py + return self.db + + def insert(self, **kwargs): + # usually kwargs would be a Storage with several keys: + # 'locked', 'client_ip','created_datetime','modified_datetime' + # 'unique_key', 'session_data' + # retrieve a new key + newid = str(self.db.r_server.incr(self.serial)) + key = self.keyprefix + ':' + newid + if self.with_lock: + key_lock = key + ':lock' + acquire_lock(self.db.r_server, key_lock, newid) + with self.db.r_server.pipeline() as pipe: + # add it to the index + pipe.sadd(self.id_idx, key) + # set a hash key with the Storage + pipe.hmset(key, kwargs) + if self.session_expiry: + pipe.expire(key, self.session_expiry) + pipe.execute() + if self.with_lock: + release_lock(self.db, key_lock, newid) + return newid + + +class MockQuery(object): + """a fake Query object that supports querying by id + and listing all keys. No other operation is supported + """ + def __init__(self, field=None, db=None, prefix=None, session_expiry=False, + with_lock=False, unique_key=None): + self.field = field + self.value = None + self.db = db + self.keyprefix = prefix + self.op = None + self.session_expiry = session_expiry + self.with_lock = with_lock + self.unique_key = unique_key + + def __eq__(self, value, op='eq'): + self.value = value + self.op = op + + def __gt__(self, value, op='ge'): + self.value = value + self.op = op + + def select(self): + if self.op == 'eq' and self.field == 'id' and self.value: + # means that someone wants to retrieve the key self.value + key = self.keyprefix + ':' + str(self.value) + if self.with_lock: + acquire_lock(self.db.r_server, key + ':lock', self.value, 2) + rtn = self.db.r_server.hgetall(key) + if rtn: + if self.unique_key: + # make sure the id and unique_key are correct + if rtn[b'unique_key'] == to_bytes(self.unique_key): + rtn[b'update_record'] = self.update # update record support + else: + rtn = None + return [Storage(rtn)] if rtn else [] + elif self.op == 'ge' and self.field == 'id' and self.value == 0: + # means that someone wants the complete list + rtn = [] + id_idx = "%s:id_idx" % self.keyprefix + # find all session keys of this app + allkeys = self.db.r_server.smembers(id_idx) + for sess in allkeys: + val = self.db.r_server.hgetall(sess) + if not val: + if self.session_expiry: + # clean up the idx, because the key expired + self.db.r_server.srem(id_idx, sess) + continue + val = Storage(val) + # add a delete_record method (necessary for sessions2trash.py) + val.delete_record = RecordDeleter( + self.db, sess, self.keyprefix) + rtn.append(val) + return rtn + else: + raise Exception("Operation not supported") + + def update(self, **kwargs): + # means that the session has been found and needs an update + if self.op == 'eq' and self.field == 'id' and self.value: + key = self.keyprefix + ':' + str(self.value) + if not self.db.r_server.exists(key): + return None + with self.db.r_server.pipeline() as pipe: + pipe.hmset(key, kwargs) + if self.session_expiry: + pipe.expire(key, self.session_expiry) + rtn = pipe.execute()[0] + if self.with_lock: + release_lock(self.db, key + ':lock', self.value) + return rtn + + def delete(self, **kwargs): + # means that we want this session to be deleted + if self.op == 'eq' and self.field == 'id' and self.value: + id_idx = "%s:id_idx" % self.keyprefix + key = self.keyprefix + ':' + str(self.value) + with self.db.r_server.pipeline() as pipe: + pipe.delete(key) + pipe.srem(id_idx, key) + rtn = pipe.execute() + return rtn[1] + + +class RecordDeleter(object): + """Dumb record deleter to support sessions2trash.py""" + + def __init__(self, db, key, keyprefix): + self.db, self.key, self.keyprefix = db, key, keyprefix + + def __call__(self): + id_idx = "%s:id_idx" % self.keyprefix + # remove from the index + self.db.r_server.srem(id_idx, self.key) + # remove the key itself + self.db.r_server.delete(self.key) diff --git a/web2py/gluon/contrib/redis_utils.py b/web2py/gluon/contrib/redis_utils.py new file mode 100644 index 0000000..8dc7b2d --- /dev/null +++ b/web2py/gluon/contrib/redis_utils.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Developed by niphlod@gmail.com +License MIT/BSD/GPL + +Serves as base to implement Redis connection object and various utils +for redis_cache, redis_session and redis_scheduler in the future +Should-could be overriden in case redis doesn't keep up (e.g. cluster support) +to ensure compatibility with another - similar - library +""" + +import logging +from threading import Lock +import time +from gluon import current + +logger = logging.getLogger("web2py.redis_utils") + +try: + import redis + from redis.exceptions import WatchError as RWatchError + from redis.exceptions import ConnectionError as RConnectionError +except ImportError: + logger.error("Needs redis library to work") + raise RuntimeError('Needs redis library to work') + + +locker = Lock() + + +def RConn(*args, **vars): + """ + Istantiates a StrictRedis connection with parameters, at the first time + only + """ + locker.acquire() + try: + instance_name = 'redis_conn_' + current.request.application + if not hasattr(RConn, instance_name): + setattr(RConn, instance_name, redis.StrictRedis(*args, **vars)) + return getattr(RConn, instance_name) + finally: + locker.release() + +def acquire_lock(conn, lockname, identifier, ltime=10): + while True: + if conn.set(lockname, identifier, ex=ltime, nx=True): + return identifier + time.sleep(.01) + + +_LUA_RELEASE_LOCK = """ +if redis.call("get", KEYS[1]) == ARGV[1] +then + return redis.call("del", KEYS[1]) +else + return 0 +end +""" + + +def release_lock(instance, lockname, identifier): + return instance._release_script( + keys=[lockname], args=[identifier]) + + +def register_release_lock(conn): + rtn = conn.register_script(_LUA_RELEASE_LOCK) + return rtn diff --git a/web2py/gluon/contrib/rss2.py b/web2py/gluon/contrib/rss2.py new file mode 100644 index 0000000..a39f15a --- /dev/null +++ b/web2py/gluon/contrib/rss2.py @@ -0,0 +1,522 @@ +""" +PyRSS2Gen - A Python library for generating RSS 2.0 feeds. + +(This is the BSD license, based on the template at + http://www.opensource.org/licenses/bsd-license.php ) + +Copyright (c) 2003, Dalke Scientific Software, LLC + +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 Dalke Scientific Softare, LLC, Andrew + Dalke, 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 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" + +__name__ = "PyRSS2Gen" +__version__ = (1, 1, 0) +__author__ = "Andrew Dalke " + +_generator_name = __name__ + "-" + ".".join(map(str, __version__)) + +import datetime + +import sys + +if sys.version_info[0] == 3: + # Python 3 + basestring = str + from io import StringIO +else: + # Python 2 + try: + from cStringIO import StringIO + except ImportError: + # Very old (or memory constrained) systems might + # have left out the compiled C version. Fall back + # to the pure Python one. Haven't seen this sort + # of system since the early 2000s. + from StringIO import StringIO + +# Could make this the base class; will need to add 'publish' + + +class WriteXmlMixin: + def write_xml(self, outfile, encoding="iso-8859-1"): + from xml.sax import saxutils + handler = saxutils.XMLGenerator(outfile, encoding) + handler.startDocument() + self.publish(handler) + handler.endDocument() + + def to_xml(self, encoding="iso-8859-1"): + f = StringIO() + self.write_xml(f, encoding) + return f.getvalue() + + +def _element(handler, name, obj, d={}): + if isinstance(obj, basestring) or obj is None: + # special-case handling to make the API easier + # to use for the common case. + handler.startElement(name, d) + if obj is not None: + handler.characters(obj) + handler.endElement(name) + else: + # It better know how to emit the correct XML. + obj.publish(handler) + + +def _opt_element(handler, name, obj): + if obj is None: + return + _element(handler, name, obj) + + +def _format_date(dt): + """convert a datetime into an RFC 822 formatted date + + Input date must be in GMT. + """ + # Looks like: + # Sat, 07 Sep 2002 00:00:01 GMT + # Can't use strftime because that's locale dependent + # + # Isn't there a standard way to do this for Python? The + # rfc822 and email.Utils modules assume a timestamp. The + # following is based on the rfc822 module. + return "%s, %02d %s %04d %02d:%02d:%02d GMT" % ( + ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"][dt.weekday()], + dt.day, + ["Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][dt.month - 1], + dt.year, dt.hour, dt.minute, dt.second) + + +## +# A couple simple wrapper objects for the fields which +# take a simple value other than a string. +class IntElement: + """implements the 'publish' API for integers + + Takes the tag name and the integer value to publish. + + (Could be used for anything which uses str() to be published + to text for XML.) + """ + element_attrs = {} + + def __init__(self, name, val): + self.name = name + self.val = val + + def publish(self, handler): + handler.startElement(self.name, self.element_attrs) + handler.characters(str(self.val)) + handler.endElement(self.name) + + +class DateElement: + """implements the 'publish' API for a datetime.datetime + + Takes the tag name and the datetime to publish. + + Converts the datetime to RFC 2822 timestamp (4-digit year). + """ + def __init__(self, name, dt): + self.name = name + self.dt = dt + + def publish(self, handler): + _element(handler, self.name, _format_date(self.dt)) +#### + + +class Category: + """Publish a category element""" + def __init__(self, category, domain=None): + self.category = category + self.domain = domain + + def publish(self, handler): + d = {} + if self.domain is not None: + d["domain"] = self.domain + _element(handler, "category", self.category, d) + + +class Cloud: + """Publish a cloud""" + def __init__(self, domain, port, path, + registerProcedure, protocol): + self.domain = domain + self.port = port + self.path = path + self.registerProcedure = registerProcedure + self.protocol = protocol + + def publish(self, handler): + _element(handler, "cloud", None, { + "domain": self.domain, + "port": str(self.port), + "path": self.path, + "registerProcedure": self.registerProcedure, + "protocol": self.protocol}) + + +class Image: + """Publish a channel Image""" + element_attrs = {} + + def __init__(self, url, title, link, + width=None, height=None, description=None): + self.url = url + self.title = title + self.link = link + self.width = width + self.height = height + self.description = description + + def publish(self, handler): + handler.startElement("image", self.element_attrs) + + _element(handler, "url", self.url) + _element(handler, "title", self.title) + _element(handler, "link", self.link) + + width = self.width + if isinstance(width, int): + width = IntElement("width", width) + _opt_element(handler, "width", width) + + height = self.height + if isinstance(height, int): + height = IntElement("height", height) + _opt_element(handler, "height", height) + + _opt_element(handler, "description", self.description) + + handler.endElement("image") + + +class Guid: + """Publish a guid + + Defaults to being a permalink, which is the assumption if it's + omitted. Hence strings are always permalinks. + """ + def __init__(self, guid, isPermaLink=1): + self.guid = guid + self.isPermaLink = isPermaLink + + def publish(self, handler): + d = {} + if self.isPermaLink: + d["isPermaLink"] = "true" + else: + d["isPermaLink"] = "false" + _element(handler, "guid", self.guid, d) + + +class TextInput: + """Publish a textInput + + Apparently this is rarely used. + """ + element_attrs = {} + + def __init__(self, title, description, name, link): + self.title = title + self.description = description + self.name = name + self.link = link + + def publish(self, handler): + handler.startElement("textInput", self.element_attrs) + _element(handler, "title", self.title) + _element(handler, "description", self.description) + _element(handler, "name", self.name) + _element(handler, "link", self.link) + handler.endElement("textInput") + + +class Enclosure: + """Publish an enclosure""" + def __init__(self, url, length, type): + self.url = url + self.length = length + self.type = type + + def publish(self, handler): + _element(handler, "enclosure", None, + {"url": self.url, + "length": str(self.length), + "type": self.type, + }) + + +class Source: + """Publish the item's original source, used by aggregators""" + def __init__(self, name, url): + self.name = name + self.url = url + + def publish(self, handler): + _element(handler, "source", self.name, {"url": self.url}) + + +class SkipHours: + """Publish the skipHours + + This takes a list of hours, as integers. + """ + element_attrs = {} + + def __init__(self, hours): + self.hours = hours + + def publish(self, handler): + if self.hours: + handler.startElement("skipHours", self.element_attrs) + for hour in self.hours: + _element(handler, "hour", str(hour)) + handler.endElement("skipHours") + + +class SkipDays: + """Publish the skipDays + + This takes a list of days as strings. + """ + element_attrs = {} + + def __init__(self, days): + self.days = days + + def publish(self, handler): + if self.days: + handler.startElement("skipDays", self.element_attrs) + for day in self.days: + _element(handler, "day", day) + handler.endElement("skipDays") + + +class RSS2(WriteXmlMixin): + """The main RSS class. + + Stores the channel attributes, with the "category" elements under + ".categories" and the RSS items under ".items". + """ + + rss_attrs = {"version": "2.0"} + element_attrs = {} + + def __init__(self, + title, + link, + description, + + language=None, + copyright=None, + managingEditor=None, + webMaster=None, + pubDate=None, # a datetime, *in* *GMT* + lastBuildDate=None, # a datetime + + categories=None, # list of strings or Category + generator=_generator_name, + docs="http://blogs.law.harvard.edu/tech/rss", + cloud=None, # a Cloud + ttl=None, # integer number of minutes + + image=None, # an Image + rating=None, # a string; I don't know how it's used + textInput=None, # a TextInput + skipHours=None, # a SkipHours with a list of integers + skipDays=None, # a SkipDays with a list of strings + + items=None, # list of RSSItems + ): + self.title = title + self.link = link + self.description = description + self.language = language + self.copyright = copyright + self.managingEditor = managingEditor + + self.webMaster = webMaster + self.pubDate = pubDate + self.lastBuildDate = lastBuildDate + + if categories is None: + categories = [] + self.categories = categories + self.generator = generator + self.docs = docs + self.cloud = cloud + self.ttl = ttl + self.image = image + self.rating = rating + self.textInput = textInput + self.skipHours = skipHours + self.skipDays = skipDays + + if items is None: + items = [] + self.items = items + + def publish(self, handler): + handler.startElement("rss", self.rss_attrs) + handler.startElement("channel", self.element_attrs) + _element(handler, "title", self.title) + _element(handler, "link", self.link) + _element(handler, "description", self.description) + + self.publish_extensions(handler) + + _opt_element(handler, "language", self.language) + _opt_element(handler, "copyright", self.copyright) + _opt_element(handler, "managingEditor", self.managingEditor) + _opt_element(handler, "webMaster", self.webMaster) + + pubDate = self.pubDate + if isinstance(pubDate, datetime.datetime): + pubDate = DateElement("pubDate", pubDate) + _opt_element(handler, "pubDate", pubDate) + + lastBuildDate = self.lastBuildDate + if isinstance(lastBuildDate, datetime.datetime): + lastBuildDate = DateElement("lastBuildDate", lastBuildDate) + _opt_element(handler, "lastBuildDate", lastBuildDate) + + for category in self.categories: + if isinstance(category, basestring): + category = Category(category) + category.publish(handler) + + _opt_element(handler, "generator", self.generator) + _opt_element(handler, "docs", self.docs) + + if self.cloud is not None: + self.cloud.publish(handler) + + ttl = self.ttl + if isinstance(self.ttl, int): + ttl = IntElement("ttl", ttl) + _opt_element(handler, "ttl", ttl) + + if self.image is not None: + self.image.publish(handler) + + _opt_element(handler, "rating", self.rating) + if self.textInput is not None: + self.textInput.publish(handler) + if self.skipHours is not None: + self.skipHours.publish(handler) + if self.skipDays is not None: + self.skipDays.publish(handler) + + for item in self.items: + item.publish(handler) + + handler.endElement("channel") + handler.endElement("rss") + + def publish_extensions(self, handler): + # Derived classes can hook into this to insert + # output after the three required fields. + pass + + +class RSSItem(WriteXmlMixin): + """Publish an RSS Item""" + element_attrs = {} + + def __init__(self, + title=None, # string + link=None, # url as string + description=None, # string + author=None, # email address as string + categories=None, # list of string or Category + comments=None, # url as string + enclosure=None, # an Enclosure + guid=None, # a unique string + pubDate=None, # a datetime + source=None, # a Source + ): + + if title is None and description is None: + raise TypeError( + "must define at least one of 'title' or 'description'") + self.title = title + self.link = link + self.description = description + self.author = author + if categories is None: + categories = [] + self.categories = categories + self.comments = comments + self.enclosure = enclosure + self.guid = guid + self.pubDate = pubDate + self.source = source + # It sure does get tedious typing these names three times... + + def publish(self, handler): + handler.startElement("item", self.element_attrs) + _opt_element(handler, "title", self.title) + _opt_element(handler, "link", self.link) + self.publish_extensions(handler) + _opt_element(handler, "description", self.description) + _opt_element(handler, "author", self.author) + + for category in self.categories: + if isinstance(category, basestring): + category = Category(category) + category.publish(handler) + + _opt_element(handler, "comments", self.comments) + if self.enclosure is not None: + self.enclosure.publish(handler) + _opt_element(handler, "guid", self.guid) + + pubDate = self.pubDate + if isinstance(pubDate, datetime.datetime): + pubDate = DateElement("pubDate", pubDate) + _opt_element(handler, "pubDate", pubDate) + + if self.source is not None: + self.source.publish(handler) + + handler.endElement("item") + + def publish_extensions(self, handler): + # Derived classes can hook into this to insert + # output after the title and link elements + pass diff --git a/web2py/gluon/contrib/shell.py b/web2py/gluon/contrib/shell.py new file mode 100644 index 0000000..638d3c8 --- /dev/null +++ b/web2py/gluon/contrib/shell.py @@ -0,0 +1,269 @@ +# +# Copyright 2007 Google Inc. +# +# 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. +# +# Modified by Massimo Di Pierro so it works with and without GAE with web2py +# the modified version of this file is still released under the original Apache license +# and it is not released under the web2py license. +# +# This should be compatible with the Apache license since it states: +# "For the purposes of this License, Derivative Works shall not include works +# that remain separable from, or merely link (or bind by name) to the interfaces of, +# the Work and Derivative Works thereof." +# +# In fact this file is Apache-licensed and it is separable from the rest of web2py. + + +""" +An interactive, stateful AJAX shell that runs Python code on the server. +""" +from __future__ import print_function +from gluon._compat import ClassType, pickle, StringIO +import logging +import new +import sys +import traceback +import types +import threading +locker = threading.RLock() + +# Set to True if stack traces should be shown in the browser, etc. +_DEBUG = True + +# The entity kind for shell historys. Feel free to rename to suit your app. +_HISTORY_KIND = '_Shell_History' + +# Types that can't be pickled. +UNPICKLABLE_TYPES = [ + types.ModuleType, + type, + ClassType, + types.FunctionType, +] + +# Unpicklable statements to seed new historys with. +INITIAL_UNPICKLABLES = [ + 'import logging', + 'import os', + 'import sys', +] + + +class History: + """A shell history. Stores the history's globals. + + Each history globals is stored in one of two places: + + If the global is picklable, it's stored in the parallel globals and + global_names list properties. (They're parallel lists to work around the + unfortunate fact that the datastore can't store dictionaries natively.) + + If the global is not picklable (e.g. modules, classes, and functions), or if + it was created by the same statement that created an unpicklable global, + it's not stored directly. Instead, the statement is stored in the + unpicklables list property. On each request, before executing the current + statement, the unpicklable statements are evaluated to recreate the + unpicklable globals. + + The unpicklable_names property stores all of the names of globals that were + added by unpicklable statements. When we pickle and store the globals after + executing a statement, we skip the ones in unpicklable_names. + + Using Text instead of string is an optimization. We don't query on any of + these properties, so they don't need to be indexed. + """ + global_names = [] + globals = [] + unpicklable_names = [] + unpicklables = [] + + def set_global(self, name, value): + """Adds a global, or updates it if it already exists. + + Also removes the global from the list of unpicklable names. + + Args: + name: the name of the global to remove + value: any picklable value + """ + blob = pickle.dumps(value, pickle.HIGHEST_PROTOCOL) + + if name in self.global_names: + index = self.global_names.index(name) + self.globals[index] = blob + else: + self.global_names.append(name) + self.globals.append(blob) + + self.remove_unpicklable_name(name) + + def remove_global(self, name): + """Removes a global, if it exists. + + Args: + name: string, the name of the global to remove + """ + if name in self.global_names: + index = self.global_names.index(name) + del self.global_names[index] + del self.globals[index] + + def globals_dict(self): + """Returns a dictionary view of the globals. + """ + return dict((name, pickle.loads(val)) + for name, val in zip(self.global_names, self.globals)) + + def add_unpicklable(self, statement, names): + """Adds a statement and list of names to the unpicklables. + + Also removes the names from the globals. + + Args: + statement: string, the statement that created new unpicklable global(s). + names: list of strings; the names of the globals created by the statement. + """ + self.unpicklables.append(statement) + + for name in names: + self.remove_global(name) + if name not in self.unpicklable_names: + self.unpicklable_names.append(name) + + def remove_unpicklable_name(self, name): + """Removes a name from the list of unpicklable names, if it exists. + + Args: + name: string, the name of the unpicklable global to remove + """ + if name in self.unpicklable_names: + self.unpicklable_names.remove(name) + + +def represent(obj): + """Returns a string representing the given object's value, which should allow the + code below to determine whether the object changes over time. + """ + try: + return pickle.dumps(obj, pickle.HIGHEST_PROTOCOL) + except: + return repr(obj) + + +def run(history, statement, env={}): + """ + Evaluates a python statement in a given history and returns the result. + """ + history.unpicklables = INITIAL_UNPICKLABLES + + # extract the statement to be run + if not statement: + return '' + + # the python compiler doesn't like network line endings + statement = statement.replace('\r\n', '\n') + + # add a couple newlines at the end of the statement. this makes + # single-line expressions such as 'class Foo: pass' evaluate happily. + statement += '\n\n' + + # log and compile the statement up front + try: + logging.info('Compiling and evaluating:\n%s' % statement) + compiled = compile(statement, '', 'single') + except: + return str(traceback.format_exc()) + + # create a dedicated module to be used as this statement's __main__ + statement_module = new.module('__main__') + + # use this request's __builtin__, since it changes on each request. + # this is needed for import statements, among other things. + import __builtin__ + statement_module.__builtins__ = __builtin__ + + # load the history from the datastore + history = History() + + # swap in our custom module for __main__. then unpickle the history + # globals, run the statement, and re-pickle the history globals, all + # inside it. + old_main = sys.modules.get('__main__') + output = StringIO() + try: + sys.modules['__main__'] = statement_module + statement_module.__name__ = '__main__' + statement_module.__dict__.update(env) + + # re-evaluate the unpicklables + for code in history.unpicklables: + exec(code, statement_module.__dict__) + + # re-initialize the globals + for name, val in history.globals_dict().items(): + try: + statement_module.__dict__[name] = val + except: + msg = 'Dropping %s since it could not be unpickled.\n' % name + output.write(msg) + logging.warning(msg + traceback.format_exc()) + history.remove_global(name) + + # run! + old_globals = dict((key, represent( + value)) for key, value in statement_module.__dict__.items()) + try: + old_stdout, old_stderr = sys.stdout, sys.stderr + try: + sys.stderr = sys.stdout = output + locker.acquire() + exec(compiled, statement_module.__dict__) + finally: + locker.release() + sys.stdout, sys.stderr = old_stdout, old_stderr + except: + output.write(str(traceback.format_exc())) + return output.getvalue() + + # extract the new globals that this statement added + new_globals = {} + for name, val in statement_module.__dict__.items(): + if name not in old_globals or represent(val) != old_globals[name]: + new_globals[name] = val + + if True in [isinstance(val, tuple(UNPICKLABLE_TYPES)) + for val in new_globals.values()]: + # this statement added an unpicklable global. store the statement and + # the names of all of the globals it added in the unpicklables. + history.add_unpicklable(statement, new_globals.keys()) + logging.debug('Storing this statement as an unpicklable.') + else: + # this statement didn't add any unpicklables. pickle and store the + # new globals back into the datastore. + for name, val in new_globals.items(): + if not name.startswith('__'): + try: + history.set_global(name, val) + except (TypeError, pickle.PicklingError) as ex: + UNPICKLABLE_TYPES.append(type(val)) + history.add_unpicklable(statement, new_globals.keys()) + + finally: + sys.modules['__main__'] = old_main + return output.getvalue() + +if __name__ == '__main__': + history = History() + while True: + print(run(history, raw_input('>>> ')).rstrip()) diff --git a/web2py/gluon/contrib/simplejson.py b/web2py/gluon/contrib/simplejson.py new file mode 100644 index 0000000..8d8ffc3 --- /dev/null +++ b/web2py/gluon/contrib/simplejson.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +""" +Dummy simplejson module for backwards compatibility with applications that import simplejson from gluon.contrib + +TODO: Remove this. +""" +from json import * + +class JSONDecodeError(ValueError): + pass \ No newline at end of file diff --git a/web2py/gluon/contrib/simplejsonrpc.py b/web2py/gluon/contrib/simplejsonrpc.py new file mode 100644 index 0000000..13bcf2b --- /dev/null +++ b/web2py/gluon/contrib/simplejsonrpc.py @@ -0,0 +1,155 @@ +# -*- coding: utf-8 -*- +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. + +"Pythonic simple JSON RPC Client implementation" +from __future__ import print_function + +__author__ = "Mariano Reingart (reingart@gmail.com)" +__copyright__ = "Copyright (C) 2011 Mariano Reingart" +__license__ = "LGPL 3.0" +__version__ = "0.05" + +import sys +PY2 = sys.version_info[0] == 2 + +if PY2: + import urllib + from xmlrpclib import Transport, SafeTransport + from cStringIO import StringIO +else: + import urllib.request as urllib + from xmlrpc.client import Transport, SafeTransport + from io import StringIO +import random +import json + + +class JSONRPCError(RuntimeError): + "Error object for remote procedure call fail" + def __init__(self, code, message, data=''): + value = "%s: %s\n%s" % (code, message, '\n'.join(data)) + RuntimeError.__init__(self, value) + self.code = code + self.message = message + self.data = data + + +class JSONDummyParser: + "json wrapper for xmlrpclib parser interfase" + def __init__(self): + self.buf = StringIO() + + def feed(self, data): + self.buf.write(data.decode('utf-8')) + + def close(self): + return self.buf.getvalue() + + +class JSONTransportMixin: + "json wrapper for xmlrpclib transport interfase" + + def send_content(self, connection, request_body): + connection.putheader("Content-Type", "application/json") + connection.putheader("Content-Length", str(len(request_body))) + connection.endheaders() + if request_body: + connection.send(str.encode(request_body)) + # todo: add gzip compression + + def getparser(self): + # get parser and unmarshaller + parser = JSONDummyParser() + return parser, parser + + +class JSONTransport(JSONTransportMixin, Transport): + pass + + +class JSONSafeTransport(JSONTransportMixin, SafeTransport): + pass + + +class ServerProxy(object): + "JSON RPC Simple Client Service Proxy" + + def __init__(self, uri, transport=None, encoding=None, verbose=0,version=None): + self.location = uri # server location (url) + self.trace = verbose # show debug messages + self.exceptions = True # raise errors? (JSONRPCError) + self.timeout = None + self.json_request = self.json_response = '' + self.version = version # '2.0' for jsonrpc2 + + type, uri = urllib.splittype(uri) + if type not in ("http", "https"): + raise IOError("unsupported JSON-RPC protocol") + self.__host, self.__handler = urllib.splithost(uri) + + if transport is None: + if type == "https": + transport = JSONSafeTransport() + else: + transport = JSONTransport() + self.__transport = transport + self.__encoding = encoding + self.__verbose = verbose + + def __getattr__(self, attr): + "pseudo method that can be called" + return lambda *args, **vars: self.call(attr, *args, **vars) + + def call(self, method, *args, **vars): + "JSON RPC communication (method invocation)" + + # build data sent to the service + request_id = random.randint(0, sys.maxsize) + data = {'id': request_id, 'method': method, 'params': args or vars, } + if self.version: + data['jsonrpc'] = self.version #mandatory key/value for jsonrpc2 validation else err -32600 + request = json.dumps(data) + + # make HTTP request (retry if connection is lost) + response = self.__transport.request( + self.__host, + self.__handler, + request, + verbose=self.__verbose + ) + + # store plain request and response for further debugging + self.json_request = request + self.json_response = response + + # parse json data coming from service + # {'version': '1.1', 'id': id, 'result': result, 'error': None} + response = json.loads(response) + + self.error = response.get('error', {}) + if self.error and self.exceptions: + raise JSONRPCError(self.error.get('code', 0), + self.error.get('message', ''), + self.error.get('data', None)) + if response['id'] != request_id: + raise JSONRPCError(0, "JSON Request ID != Response ID") + + return response.get('result') + + +ServiceProxy = ServerProxy + + +if __name__ == "__main__": + # basic tests: + location = "http://www.web2py.com.ar/webservices/sample/call/jsonrpc" + client = ServerProxy(location, verbose='--verbose' in sys.argv,) + print(client.add(1, 2)) diff --git a/web2py/gluon/contrib/sms_utils.py b/web2py/gluon/contrib/sms_utils.py new file mode 100644 index 0000000..7c5947e --- /dev/null +++ b/web2py/gluon/contrib/sms_utils.py @@ -0,0 +1,115 @@ +SMSCODES = { + 'Aliant': '@chat.wirefree.ca', + 'Alltel': '@message.alltel.com', + 'Ameritech': '@paging.acswireless.com', + 'AT&T': '@txt.att.net', + 'AU by KDDI': '@ezweb.ne.jp', + 'BeeLine GSM': '@sms.beemail.ru', + 'Bell Mobility Canada': '@txt.bellmobility.ca', + 'Bellsouth': '@bellsouth.cl', + 'BellSouth Mobility': '@blsdcs.net', + 'Blue Sky Frog': '@blueskyfrog.com', + 'Boost': '@myboostmobile.com', + 'Cellular South': '@csouth1.com', + 'CellularOne': '@mobile.celloneusa.com', + 'CellularOne West': '@mycellone.com', + 'Cincinnati Bell': '@gocbw.com', + 'Claro': '@clarotorpedo.com.br', + 'Comviq': '@sms.comviq.se', + 'Dutchtone/Orange-NL': '@sms.orange.nl', + 'Edge Wireless': '@sms.edgewireless.com', + 'EinsteinPCS / Airadigm Communications': '@einsteinsms.com', + 'EPlus': '@smsmail.eplus.de', + 'Fido Canada': '@fido.ca', + 'Golden Telecom': '@sms.goldentele.com', + 'Idea Cellular': '@ideacellular.net', + 'Kyivstar': '@sms.kyivstar.net', + 'LMT': '@sms.lmt.lv', + 'Manitoba Telecom Systems': '@text.mtsmobility.com', + 'Meteor': '@sms.mymeteor.ie', + 'Metro PCS': '@mymetropcs.com', + 'Metrocall Pager': '@page.metrocall.com', + 'MobileOne': '@m1.com.sg', + 'Mobilfone': '@page.mobilfone.com', + 'Mobility Bermuda': '@ml.bm', + 'Netcom': '@sms.netcom.no', + 'Nextel': '@messaging.nextel.com', + 'NPI Wireless': '@npiwireless.com', + 'O2': '@o2.co.uk', + 'O2 M-mail': '@mmail.co.uk', + 'Optus': '@optusmobile.com.au', + 'Orange': '@orange.net', + 'Oskar': '@mujoskar.cz', + 'Pagenet': '@pagenet.net', + 'PCS Rogers': '@pcs.rogers.com', + 'Personal Communication': '@pcom.ru', + 'Plus GSM Poland': '@text.plusgsm.pl', + 'Powertel': '@ptel.net', + 'Primtel': '@sms.primtel.ru', + 'PSC Wireless': '@sms.pscel.com', + 'Qualcomm': '@pager.qualcomm.com', + 'Qwest': '@qwestmp.com', + 'Safaricom': '@safaricomsms.com', + 'Satelindo GSM': '@satelindogsm.com', + 'SCS-900': '@scs-900.ru', + 'Simple Freedom': '@text.simplefreedom.net', + 'Skytel - Alphanumeric': '@skytel.com', + 'Smart Telecom': '@mysmart.mymobile.ph', + 'Southern Linc': '@page.southernlinc.com', + 'Sprint PCS': '@messaging.sprintpcs.com', + 'Sprint PCS - Short Mail': '@sprintpcs.com', + 'SunCom': '@tms.suncom.com', + 'SureWest Communications': '@mobile.surewest.com', + 'SwissCom Mobile': '@bluewin.ch', + 'T-Mobile Germany': '@T-D1-SMS.de', + 'T-Mobile Netherlands': '@gin.nl', + 'T-Mobile UK': '@t-mobile.uk.net', + 'T-Mobile USA (tmail)': '@tmail.com', + 'T-Mobile USA (tmomail)': '@tmomail.net', + 'Tele2 Latvia': '@sms.tele2.lv', + 'Telefonica Movistar': '@movistar.net', + 'Telenor': '@mobilpost.no', + 'Telia Denmark': '@gsm1800.telia.dk', + 'Telus Mobility': '@msg.telus.com', + 'The Phone House': '@sms.phonehouse.de', + 'TIM': '@timnet.com', + 'UMC': '@sms.umc.com.ua', + 'Unicel': '@utext.com', + 'US Cellular': '@email.uscc.net', + 'Verizon Wireless (vtext)': '@vtext.com', + 'Verizon Wireless (airtouchpaging)': '@airtouchpaging.com', + 'Verizon Wireless (myairmail)': '@myairmail.com', + 'Vessotel': '@pager.irkutsk.ru', + 'Virgin Mobile Canada': '@vmobile.ca', + 'Virgin Mobile USA': '@vmobl.com', + 'Vodafone Italy': '@sms.vodafone.it', + 'Vodafone Japan (n)': '@n.vodafone.ne.jp', + 'Vodafone Japan (d)': '@d.vodafone.ne.jp', + 'Vodafone Japan (r)': '@r.vodafone.ne.jp', + 'Vodafone Japan (k)': '@k.vodafone.ne.jp', + 'Vodafone Japan (t)': '@t.vodafone.ne.jp', + 'Vodafone Japan (q)': '@q.vodafone.ne.jp', + 'Vodafone Japan (s)': '@s.vodafone.ne.jp', + 'Vodafone Japan (h)': '@h.vodafone.ne.jp', + 'Vodafone Japan (c)': '@c.vodafone.ne.jp', + 'Vodafone Spain': '@vodafone.es', + 'Vodafone UK': '@vodafone.net', + 'Weblink Wireless': '@airmessage.net', + 'WellCom': '@sms.welcome2well.com', + 'WyndTell': '@wyndtell.com', +} + + +def sms_email(number, provider): + """ + >>> print sms_email('1 (312) 375-6536','T-Mobile USA (tmail)') + print 13123756536@tmail.com + """ + import re + if number[0] == '+1': + number = number[1:] + elif number[0] == '+': + number = number[3:] + elif number[:2] == '00': number = number[3:] + number = re.sub('[^\d]', '', number) + return number + SMSCODES[provider] diff --git a/web2py/gluon/contrib/spreadsheet.py b/web2py/gluon/contrib/spreadsheet.py new file mode 100644 index 0000000..e9c4c76 --- /dev/null +++ b/web2py/gluon/contrib/spreadsheet.py @@ -0,0 +1,904 @@ +# -*- coding: utf-8 -*- + +""" +Developed by Massimo Di Pierro, optional component of web2py, BSDv3 license. +""" +from __future__ import print_function + +import re +import pickle +import copy +import json + + +def quote(text): + return str(text).replace('\\', '\\\\').replace("'", "\\'") + + +class Node: + def __init__(self, name, value, url='.', readonly=False, active=True, + onchange=None, select=False, size=4, **kwarg): + self.url = url + self.name = name + self.value = str(value) + self.computed_value = '' + self.incoming = {} + self.outcoming = {} + self.readonly = readonly + self.active = active + self.onchange = onchange + self.size = size + self.locked = False + self.select = value if select and not isinstance(value, str) else False + + def xml(self): + if self.select: + selectAttributes = dict(_name=self.name,_id=self.name,_size=self.size, + _onblur="ajax('%s/blur',['%s']);"%(self.url,self.name)) + # _onkeyup="ajax('%s/keyup',['%s'], ':eval');"%(self.url,self.name), + # _onfocus="ajax('%s/focus',['%s'], ':eval');"%(self.url,self.name), + for k,v in selectAttributes.items(): + self.select[k] = v + return self.select.xml() + else: + return """ + """ % (self.name, self.name, self.computed_value, self.size, + self.url, self.name, self.url, self.name, self.url, self.name, + (self.readonly and 'readonly ') or '') + + def __repr__(self): + return '%s:%s' % (self.name, self.computed_value) + + +class Sheet: + """ + Basic class for creating web spreadsheets + + New features: + + -dal spreadsheets: + It receives a Rows object instance and presents + the selected data in a cell per field basis (table rows + are sheet rows as well) + Input should be short extension data as numeric data + or math expressions but can be anything supported by + unicode. + + -row(), column() and matrix() class methods: + These new methods allow to set bulk data sets + without calling .cell() for each node + Example:: + + # controller + from gluon.contrib.spreadsheet import Sheet + + def callback(): + return cache.ram('sheet1', lambda: None, None).process(request) + + def index(): + # standard spreadsheet method + sheet = cache.ram('sheet1', + lambda: Sheet(10, 10, URL(r=request, f='callback')), 0) + #sheet.cell('r0c3', value='=r0c0+r0c1+r0c2', readonly=True) + return dict(sheet=sheet) + + def index(): + # database spreadsheet method + sheet = cache.ram('sheet1', + lambda: Sheet(10, 10, URL(r=request, f='callback'), + data=db(db.mydata).select()), 0) + return dict(sheet=sheet) + + # view + {{extend 'layout.html'}} + {{=sheet}} + + or insert invidivual cells via + + {{=sheet.nodes['r0c0']}} + + Sheet stores a JavaScript w2p_spreadsheet_data object + for retrieving data updates from the client. + + The data structure of the js object is as follows: + # columns: a dict with colname, column index map + # colnames: a dict with column index, colname map + # id_columns: list with id columns + # id_colnames: dict with id colname: column index map + # cells: dict of "rncn": value pairs + # modified: dict of modified cells for client-side + + Also, there is a class method Sheet.update(data) that + processes the json data as sent by the client and + returns a set of db modifications (see the method help for + more details) + + client JavaScript objects: + + -var w2p_spreadsheet_data + Stores cell updates by key and + Used for updated cells control + + -var w2p_spreadsheet_update_button + Stores the id of the update command + Used for event binding (update click) + + var w2p_spreadsheet_update_result + object attributes: + modified - n updated records + errors - n errors + message - a message for feedback and errors + + Stores the ajax db update call returned stats + and the db_callback string js + Used after calling w2p_spreadsheet_update_db() + + -function w2p_spreadsheet_update_cell(a) + Used for responding to normal cell events + (encapsulates old behavior) + + -function w2p_spreadsheet_update_db_callback(result) + Called after a background db update + + -function w2p_spreadsheet_update_db() + Called for updating the database with + client data + + First method: Sending data trough a form helper: + (the data payload must be inserted in a form field before + submission) + + -Applying db changes made client-side + + Example controller: + ... + # present a submit button with the spreadsheet + form = SQLFORM.factory(Field("", + "text", + readable=False, writable=False, + formname="")) + # submit button label + form.elements("input [type=submit]").attributes["_value"] = \ + T("Update database") + form.elements("textarea")[0].attributes["_style"] = "display: none;" + + w2p_spreadsheet_update_script = SCRIPT(''' + jQuery( + function(){ + jQuery("").submit(function(){ + jQuery("[name=]").val(JSON.stringify( + w2p_spreadsheet_data) + ); + }); + } + ); + ''') + + # retrieve changes + if form.process().accepted: + data = form.vars. + changes = Sheet.updated(data) + + # Do db I/O: + for table, rows in changes.iteritems(): + for row, values in rows.iteritems(): + db[table][row].update_record(**values) + + # the action view should expose {{=form}}, {{=sheet}}, {{=myscript}} + return dict(form=form, sheet=sheet, + myscript=w2p_spreadseet_update_script) + + Second method: Sending data updates with .ajax() + + -spreadsheet page's view: + + {{ + =INPUT(_type="button", _value="update data", + _id="w2p_spreadsheet_update_data") + }} + + {{=SCRIPT(''' + jQuery(function(){ + jQuery("#w2p_spreadsheet_update_data").click( + function(){ + jQuery.ajax({url: "%s", + type: "POST", + data: + {data: + JSON.stringify(w2p_spreadsheet_data)} + } + ); + } + ); + }); + ''' % URL(c="default", f="modified"))}} + + -controller: modified function + def modified(): + data = request.vars.data + changes = Sheet.updated(data) + # (for db I/O see first method) + return "ok" + + + Third method: + When creating a Sheet instance, pass a kwarg update_button= + + + + + + +{{if security_notice or disclosure_notice:}} +
    + {{if security_notice:}} +

    Security Notice

    +

    For your security we process all payments using a service called Stripe. Thanks to Stripe your credit card information is communicated directly between your Web Browser and the payment processor, Stripe, without going through our server. Since we never see your card information nobody can steal it through us. Stripe is PCI compliant and so are we.

    + {{pass}} + {{if disclosure_notice:}} +

    Disclosure Notice

    + +

    We do store other information about your purchase including your name, a description of the purchase, the time when it was processed, and the amount paid. This information is necessary to provide our services and for accounting purposes. We do not disclose this information to third parties unless required to operate our services or accounting purposes.

    + {{pass}} +
    +{{pass}} +""" + +if __name__ == '__main__': + key = raw_input('user>') + d = Stripe(key).charge(100) + print('charged', d['paid']) + s = Stripe(key).check(d[u'id']) + print('paid', s['paid'], s['amount'], s['currency']) + s = Stripe(key).refund(d[u'id']) + print('refunded', s['refunded']) diff --git a/web2py/gluon/contrib/taskbar_widget.py b/web2py/gluon/contrib/taskbar_widget.py new file mode 100644 index 0000000..785c3ce --- /dev/null +++ b/web2py/gluon/contrib/taskbar_widget.py @@ -0,0 +1,244 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# # Creates a taskbar icon for web2py +# # Author: Mark Larsen, mostly stolen from Mark Hammond's +# # C:\Python25\Lib\site-packages\win32\Demos\win32gui_taskbar.py +# # 11/7/08 +# dual licensed under the web2py license (LGPL) and the Python license. + +from __future__ import print_function +import os +import sys +import base64 +import win32con +import win32api +import win32gui + + +class TaskBarIcon: + + def __init__(self, iconPath=None): + + self.iconPath = iconPath + self.status = [] + + msg_TaskbarRestart = \ + win32api.RegisterWindowMessage('TaskbarCreated') + message_map = { + msg_TaskbarRestart: self.OnRestart, + win32con.WM_DESTROY: self.OnDestroy, + win32con.WM_COMMAND: self.OnCommand, + win32con.WM_USER + 20: self.OnTaskbarNotify, + } + + # Register the Window class. + + wc = win32gui.WNDCLASS() + hinst = wc.hInstance = win32api.GetModuleHandle(None) + wc.lpszClassName = 'web2pyTaskbar' + wc.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW + wc.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW) + wc.hbrBackground = win32con.COLOR_WINDOW + wc.lpfnWndProc = message_map # could also specify a wndproc. + classAtom = win32gui.RegisterClass(wc) + + # Create the Window. + + style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU + self.hwnd = win32gui.CreateWindow( + classAtom, + 'web2pyTaskbar', + style, + 0, + 0, + win32con.CW_USEDEFAULT, + win32con.CW_USEDEFAULT, + 0, + 0, + hinst, + None, + ) + win32gui.UpdateWindow(self.hwnd) + self.SetServerStopped() + + def __createIcon(self): + + # try and use custom icon + + if self.iconPath and os.path.isfile(self.iconPath): + hicon = self.__loadFromFile(self.iconPath) + else: + try: + fp = 'tmp.ico' + icFH = file(fp, 'wb') + if self.serverState == self.EnumServerState.STOPPED: + icFH.write(base64.b64decode(self.__getIconStopped())) + elif self.serverState == self.EnumServerState.RUNNING: + icFH.write(base64.b64decode(self.__getIconRunning())) + icFH.close() + hicon = self.__loadFromFile(fp) + os.unlink(fp) + except: + print("Can't load web2py icons - using default") + hicon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION) + + flags = win32gui.NIF_ICON | win32gui.NIF_MESSAGE\ + | win32gui.NIF_TIP + nid = ( + self.hwnd, + 0, + flags, + win32con.WM_USER + 20, + hicon, + 'web2py Framework', + ) + try: + win32gui.Shell_NotifyIcon(win32gui.NIM_MODIFY, nid) + except: + try: + win32gui.Shell_NotifyIcon(win32gui.NIM_ADD, nid) + except win32api.error: + + # This is common when windows is starting, and this code is hit + # before the taskbar has been created. + + print('Failed to add the taskbar icon - is explorer running?') + + # but keep running anyway - when explorer starts, we get the + + def OnRestart( + self, + hwnd, + msg, + wparam, + lparam, + ): + self._DoCreateIcons() + + def OnDestroy( + self, + hwnd, + msg, + wparam, + lparam, + ): + nid = (self.hwnd, 0) + win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid) + + def OnTaskbarNotify( + self, + hwnd, + msg, + wparam, + lparam, + ): + if lparam == win32con.WM_LBUTTONUP: + pass + elif lparam == win32con.WM_LBUTTONDBLCLK: + pass + elif lparam == win32con.WM_RBUTTONUP: + menu = win32gui.CreatePopupMenu() + win32gui.AppendMenu(menu, win32con.MF_STRING, 1023, + 'Toggle Display') + win32gui.AppendMenu(menu, win32con.MF_SEPARATOR, 0, '') + if self.serverState == self.EnumServerState.STOPPED: + win32gui.AppendMenu(menu, win32con.MF_STRING, 1024, + 'Start Server') + win32gui.AppendMenu(menu, win32con.MF_STRING + | win32con.MF_GRAYED, 1025, + 'Restart Server') + win32gui.AppendMenu(menu, win32con.MF_STRING + | win32con.MF_GRAYED, 1026, + 'Stop Server') + else: + win32gui.AppendMenu(menu, win32con.MF_STRING + | win32con.MF_GRAYED, 1024, + 'Start Server') + win32gui.AppendMenu(menu, win32con.MF_STRING, 1025, + 'Restart Server') + win32gui.AppendMenu(menu, win32con.MF_STRING, 1026, + 'Stop Server') + win32gui.AppendMenu(menu, win32con.MF_SEPARATOR, 0, '') + win32gui.AppendMenu(menu, win32con.MF_STRING, 1027, + 'Quit (pid:%i)' % os.getpid()) + pos = win32gui.GetCursorPos() + + # See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/menus_0hdi.asp + + win32gui.SetForegroundWindow(self.hwnd) + win32gui.TrackPopupMenu( + menu, + win32con.TPM_LEFTALIGN, + pos[0], + pos[1], + 0, + self.hwnd, + None, + ) + win32api.PostMessage(self.hwnd, win32con.WM_NULL, 0, 0) + return 1 + + def OnCommand( + self, + hwnd, + msg, + wparam, + lparam, + ): + id = win32api.LOWORD(wparam) + if id == 1023: + self.status.append(self.EnumStatus.TOGGLE) + elif id == 1024: + self.status.append(self.EnumStatus.START) + elif id == 1025: + self.status.append(self.EnumStatus.RESTART) + elif id == 1026: + self.status.append(self.EnumStatus.STOP) + elif id == 1027: + self.status.append(self.EnumStatus.QUIT) + self.Destroy() + else: + print('Unknown command -', id) + + def Destroy(self): + win32gui.DestroyWindow(self.hwnd) + + def SetServerRunning(self): + self.serverState = self.EnumServerState.RUNNING + self.__createIcon() + + def SetServerStopped(self): + self.serverState = self.EnumServerState.STOPPED + self.__createIcon() + + def __getIconRunning(self): + return 'AAABAAEAEBAQAAAAAAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAIXMGAABe/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABERAgAAIAAAEAACAAAgAAABEAIiACIgAAABAgAgIAIAEAECACAgAgABEAIiACACAAAAAAAAAAAAICACIiAiIAICAgIAACACAgICAgAAIAICAgICIiAiIAICAgIAACACAgICAgAAIAICAgICIiAiIAAAAAAAAAAAD//wAAhe8AAL3vAADMYwAA9a0AALWtAADMbQAA//8AAKwjAABV7QAAVe0AAFQjAABV7QAAVe0AAFQjAAD//wAA' + + def __getIconStopped(self): + return 'AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJCdIAIXMGAABe/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzMzMzMzMzAwERMjMzIzAzEDMyMzMjAzMxAzIiMyAjMzMwMjMjAzIzEzECMyAjMjMxEzAiAyMyMzMzMwAzMzMzIyMyACMiIzIyMjAzAyMyMjIyAjMwIzIyMjAyIiMCIzIyAjIzMyAyMjAyMjMzIwIyAjIyIiMiIDAzMzMzMzMzB//gAAhe0AAJ3rAADMYwAA9a0AALGNAADMLQAA/n8AAKwjAABVrQAAUc0AAFQjAABF5QAAVekAABQhAAB//gAA' + + def __loadFromFile(self, iconPath): + hinst = win32api.GetModuleHandle(None) + icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE + hicon = win32gui.LoadImage( + hinst, + iconPath, + win32con.IMAGE_ICON, + 0, + 0, + icon_flags, + ) + return hicon + + class EnumStatus: + + TOGGLE = 0 + START = 1 + STOP = 2 + RESTART = 3 + QUIT = 4 + + class EnumServerState: + + RUNNING = 0 + STOPPED = 1 diff --git a/web2py/gluon/contrib/timecollect.py b/web2py/gluon/contrib/timecollect.py new file mode 100644 index 0000000..22384c2 --- /dev/null +++ b/web2py/gluon/contrib/timecollect.py @@ -0,0 +1,103 @@ +from __future__ import print_function +# Only Python 2.6 and up, because of NamedTuple. +import time +from collections import namedtuple +Score = namedtuple('Score', ['tag', 'stamp']) + + +class TimeCollector(object): + def __init__(self): + '''The first time stamp is created here''' + self.scores = [Score(tag='start', stamp=time.clock())] + + def addStamp(self, description): + '''Adds a new time stamp, with a description.''' + self.scores.append(Score(tag=description, stamp=time.clock())) + + def _stampDelta(self, index1, index2): + '''Private utility function to clean up this common calculation.''' + return self.scores[index1].stamp - self.scores[index2].stamp + + def getReportItems(self, orderByCost=True): + '''Returns a list of dicts. Each dict has + start (ms), + end (ms), + delta (ms), + perc (%), + tag (str) + ''' + self.scores.append(Score(tag='finish', stamp=time.clock())) + total_time = self._stampDelta(-1, 0) + data = [] + for i in range(1, len(self.scores)): + delta = self._stampDelta(i, i - 1) + if abs(total_time) < 1e-6: + perc = 0 + else: + perc = delta / total_time * 100 + data.append( + dict( + start=self._stampDelta(i - 1, 0) * 1000, + end=self._stampDelta(i, 0) * 1000, + delta=delta * 1000, + perc=perc, + tag=self.scores[i].tag + ) + ) + if orderByCost: + data.sort(key=lambda x: x['perc'], reverse=True) + return data + + def getReportLines(self, orderByCost=True): + '''Produces a report of logged time-stamps as a list of strings. + if orderByCost is False, then the order of the stamps is + chronological.''' + data = self.getReportItems(orderByCost) + headerTemplate = '%10s | %10s | %10s | %11s | %-30s' + headerData = ('Start(ms)', 'End(ms)', 'Delta(ms)', 'Time Cost', + 'Description') + bodyTemplate = '%(start)10.0f | %(end)10.0f | %(delta)10.0f |' \ + + ' %(perc)10.0f%% | %(tag)-30s' + return [headerTemplate % headerData] + [bodyTemplate % d for d in data] + + def getReportText(self, **kwargs): + return '\n'.join(self.getReportLines(**kwargs)) + + def restart(self): + self.scores = [Score(tag='start', stamp=time.clock())] + +if __name__ == '__main__': + print('') + print('Testing:') + print('') + + # First create the collector + t = TimeCollector() + x = [i for i in range(1000)] + # Every time some work gets done, add a stamp + t.addStamp('Initialization Section') + x = [i for i in range(10000)] + t.addStamp('A big loop') + x = [i for i in range(100000)] + t.addStamp('calling builder function') + # Finally, obtain the results + print('') + print(t.getReportText()) + # If you want to measure something else in the same scope, you can + # restart the collector. + t.restart() + x = [i for i in range(1000000)] + t.addStamp('Part 2') + x = [i for i in range(1000000)] + t.addStamp('Cleanup') + # And once again report results + print('') + print(t.getReportText()) + t.restart() + for y in range(1, 200, 20): + x = [i for i in range(10000) * y] + t.addStamp('Iteration when y = ' + str(y)) + + print('') + # You can turn off ordering of results + print(t.getReportText(orderByCost=False)) diff --git a/web2py/gluon/contrib/user_agent_parser.py b/web2py/gluon/contrib/user_agent_parser.py new file mode 100644 index 0000000..f966b61 --- /dev/null +++ b/web2py/gluon/contrib/user_agent_parser.py @@ -0,0 +1,695 @@ +""" +Extract client information from http user agent +The module does not try to detect all capabilities of browser in current form (it can easily be extended though). +Tries to + * be fast + * very easy to extend + * reliable enough for practical purposes + * assist python web apps to detect clients. +""" + +__version__ = '1.7.8' + + +class DetectorsHub(dict): + _known_types = ['os', 'dist', 'flavor', 'browser'] + + def __init__(self, *args, **kw): + dict.__init__(self, *args, **kw) + for typ in self._known_types: + self.setdefault(typ, []) + self.registerDetectors() + + def register(self, detector): + if detector.info_type not in self._known_types: + self[detector.info_type] = [detector] + self._known_types.insert(detector.order, detector.info_type) + else: + self[detector.info_type].append(detector) + + def __iter__(self): + return iter(self._known_types) + + def registerDetectors(self): + detectors = [v() for v in globals().values() if DetectorBase in getattr(v, '__mro__', [])] + for d in detectors: + if d.can_register: + self.register(d) + + +class DetectorBase(object): + name = "" # "to perform match in DetectorsHub object" + info_type = "override me" + result_key = "override me" + order = 10 # 0 is highest + look_for = "string to look for" + skip_if_found = [] # strings if present stop processin + can_register = False + version_markers = [("/", " ")] + allow_space_in_version = False + _suggested_detectors = None + platform = None + bot = False + + def __init__(self): + if not self.name: + self.name = self.__class__.__name__ + self.can_register = (self.__class__.__dict__.get('can_register', True)) + + def detect(self, agent, result): + # -> True/None + word = self.checkWords(agent) + if word: + result[self.info_type] = dict(name=self.name) + result['bot'] = self.bot + version = self.getVersion(agent, word) + if version: + result[self.info_type]['version'] = version + if self.platform: + result['platform'] = {'name': self.platform, 'version': version} + return True + + def checkWords(self, agent): + # -> True/None + for w in self.skip_if_found: + if w in agent: + return False + if isinstance(self.look_for, (tuple, list)): + for word in self.look_for: + if word in agent: + return word + elif self.look_for in agent: + return self.look_for + + def getVersion(self, agent, word): + """ + => version string /None + """ + version_markers = self.version_markers if \ + isinstance(self.version_markers[0], (list, tuple)) else [self.version_markers] + version_part = agent.split(word, 1)[-1] + for start, end in version_markers: + if version_part.startswith(start) and end in version_part: + version = version_part[1:] + if end: # end could be empty string + version = version.split(end)[0] + if not self.allow_space_in_version: + version = version.split()[0] + return version + + +class OS(DetectorBase): + info_type = "os" + can_register = False + version_markers = [";", " "] + allow_space_in_version = True + platform = None + + +class Dist(DetectorBase): + info_type = "dist" + can_register = False + platform = None + + +class Flavor(DetectorBase): + info_type = "flavor" + can_register = False + platform = None + + +class Browser(DetectorBase): + info_type = "browser" + can_register = False + + +class Firefox(Browser): + look_for = "Firefox" + version_markers = [('/', '')] + skip_if_found = ["SeaMonkey", "web/snippet"] + + +class SeaMonkey(Browser): + look_for = "SeaMonkey" + version_markers = [('/', '')] + + +class Konqueror(Browser): + look_for = "Konqueror" + version_markers = ["/", ";"] + + +class OperaMobile(Browser): + look_for = "Opera Mobi" + name = "Opera Mobile" + + def getVersion(self, agent, word): + try: + look_for = "Version" + return agent.split(look_for)[1][1:].split(' ')[0] + except IndexError: + look_for = "Opera" + return agent.split(look_for)[1][1:].split(' ')[0] + + +class Opera(Browser): + look_for = "Opera" + + def getVersion(self, agent, word): + try: + look_for = "Version" + return agent.split(look_for)[1][1:].split(' ')[0] + except IndexError: + look_for = "Opera" + version = agent.split(look_for)[1][1:].split(' ')[0] + return version.split('(')[0] + + +class OperaNew(Browser): + """ + Opera after version 15 + """ + name = "Opera" + look_for = "OPR" + version_markers = [('/', '')] + + +class Netscape(Browser): + look_for = "Netscape" + version_markers = [("/", '')] + + +class Trident(Browser): + look_for = "Trident" + skip_if_found = ["MSIE", "Opera"] + name = "Microsoft Internet Explorer" + version_markers = ["/", ";"] + trident_to_ie_versions = { + '4.0': '8.0', + '5.0': '9.0', + '6.0': '10.0', + '7.0': '11.0', + } + + def getVersion(self, agent, word): + return self.trident_to_ie_versions.get(super(Trident, self).getVersion(agent, word)) + + +class MSIE(Browser): + look_for = "MSIE" + skip_if_found = ["Opera"] + name = "Microsoft Internet Explorer" + version_markers = [" ", ";"] + +class MSEdge(Browser): + look_for = "Edge" + skip_if_found = ["MSIE"] + version_markers = ["/", ""] + +class Galeon(Browser): + look_for = "Galeon" + + +class WOSBrowser(Browser): + look_for = "wOSBrowser" + + def getVersion(self, agent, word): + pass + + +class Safari(Browser): + look_for = "Safari" + skip_if_found = ["Edge"] + + def checkWords(self, agent): + unless_list = ["Chrome", "OmniWeb", "wOSBrowser", "Android"] + if self.look_for in agent: + for word in unless_list: + if word in agent: + return False + return self.look_for + + def getVersion(self, agent, word): + if "Version/" in agent: + return agent.split('Version/')[-1].split(' ')[0].strip() + if "Safari/" in agent: + return agent.split('Safari/')[-1].split(' ')[0].strip() + else: + return agent.split('Safari ')[-1].split(' ')[0].strip() # Mobile Safari + +class GoogleBot(Browser): + # https://support.google.com/webmasters/answer/1061943 + look_for = ["Googlebot", "Googlebot-News", "Googlebot-Image", + "Googlebot-Video", "Googlebot-Mobile", "Mediapartners-Google", + "Mediapartners", "AdsBot-Google", "web/snippet"] + bot = True + version_markers = [('/', ';'), ('/', ' ')] + +class GoogleFeedFetcher(Browser): + look_for = "Feedfetcher-Google" + bot = True + + def get_version(self, agent): + pass + +class RunscopeRadar(Browser): + look_for = "runscope-radar" + bot = True + +class GoogleAppEngine(Browser): + look_for = "AppEngine-Google" + bot = True + + def get_version(self, agent): + pass + +class GoogleApps(Browser): + look_for = "GoogleApps script" + bot = True + + def get_version(self, agent): + pass + +class TwitterBot(Browser): + look_for = "Twitterbot" + bot = True + +class MJ12Bot(Browser): + look_for = "MJ12bot" + bot = True + +class YandexBot(Browser): + # http://help.yandex.com/search/robots/agent.xml + look_for = "Yandex" + bot = True + + def getVersion(self, agent, word): + return agent[agent.index('Yandex'):].split('/')[-1].split(')')[0].strip() + +class BingBot(Browser): + look_for = "bingbot" + version_markers = ["/", ";"] + bot = True + + +class BaiduBot(Browser): + # http://help.baidu.com/question?prod_en=master&class=1&id=1000973 + look_for = ["Baiduspider", "Baiduspider-image", "Baiduspider-video", + "Baiduspider-news", "Baiduspider-favo", "Baiduspider-cpro", + "Baiduspider-ads"] + bot = True + version_markers = ('/', ';') + + +class LinkedInBot(Browser): + look_for = "LinkedInBot" + bot = True + +class ArchiveDotOrgBot(Browser): + look_for = "archive.org_bot" + bot = True + +class YoudaoBot(Browser): + look_for = "YoudaoBot" + bot = True + +class YoudaoBotImage(Browser): + look_for = "YodaoBot-Image" + bot = True + +class RogerBot(Browser): + look_for = "rogerbot" + bot = True + +class TweetmemeBot(Browser): + look_for = "TweetmemeBot" + bot = True + +class WebshotBot(Browser): + look_for = "WebshotBot" + bot = True + +class SensikaBot(Browser): + look_for = "SensikaBot" + bot = True + +class YesupBot(Browser): + look_for = "YesupBot" + bot = True + +class DotBot(Browser): + look_for = "DotBot" + bot = True + +class PhantomJS(Browser): + look_for = "Browser/Phantom" + bot = True + +class FacebookExternalHit(Browser): + look_for = 'facebookexternalhit' + bot = True + + +class NokiaOvi(Browser): + look_for = "S40OviBrowser" + +class UCBrowser(Browser): + look_for = "UCBrowser" + +class BrowserNG(Browser): + look_for = "BrowserNG" + +class Dolfin(Browser): + look_for = 'Dolfin' + +class NetFront(Browser): + look_for = 'NetFront' + +class Jasmine(Browser): + look_for = 'Jasmine' + +class Openwave(Browser): + look_for = 'Openwave' + +class UPBrowser(Browser): + look_for = 'UP.Browser' + +class OneBrowser(Browser): + look_for = 'OneBrowser' + +class ObigoInternetBrowser(Browser): + look_for = 'ObigoInternetBrowser' + +class TelecaBrowser(Browser): + look_for = 'TelecaBrowser' + +class MAUI(Browser): + look_for = 'Browser/MAUI' + + def getVersion(self, agent, word): + version = agent.split("Release/")[-1][:10] + return version + + +class NintendoBrowser(Browser): + look_for = 'NintendoBrowser' + + +class AndroidBrowser(Browser): + look_for = "Android" + skip_if_found = ['Chrome', 'Windows Phone'] + + # http://decadecity.net/blog/2013/11/21/android-browser-versions + def getVersion(self, agent, word): + pass + + +class Linux(OS): + look_for = 'Linux' + platform = 'Linux' + + def getVersion(self, agent, word): + pass + + +class Blackberry(OS): + look_for = 'BlackBerry' + platform = 'BlackBerry' + + def getVersion(self, agent, word): + pass + + +class BlackberryPlaybook(Dist): + look_for = 'PlayBook' + platform = 'BlackBerry' + + def getVersion(self, agent, word): + pass + + +class WindowsPhone(OS): + name = "Windows Phone" + platform = 'Windows' + look_for = ["Windows Phone OS", "Windows Phone"] + version_markers = [(" ", ";"), (" ", ")")] + + +class iOS(OS): + look_for = ('iPhone', 'iPad') + skip_if_found = ['like iPhone'] + + +class iPhone(Dist): + look_for = 'iPhone' + platform = 'iOS' + skip_if_found = ['like iPhone'] + + def getVersion(self, agent, word): + version_end_chars = [' '] + if not "iPhone OS" in agent: + return None + part = agent.split('iPhone OS')[-1].strip() + for c in version_end_chars: + if c in part: + version = part.split(c)[0] + return version.replace('_', '.') + return None + + +class IPad(Dist): + look_for = 'iPad;' + platform = 'iOS' + + def getVersion(self, agent, word): + version_end_chars = [' '] + if not "CPU OS " in agent: + return None + part = agent.split('CPU OS ')[-1].strip() + for c in version_end_chars: + if c in part: + version = part.split(c)[0] + return version.replace('_', '.') + return None + + +class Macintosh(OS): + look_for = 'Macintosh' + + def getVersion(self, agent, word): + pass + + +class MacOS(Flavor): + look_for = 'Mac OS' + platform = 'Mac OS' + skip_if_found = ['iPhone', 'iPad'] + + def getVersion(self, agent, word): + version_end_chars = [';', ')'] + part = agent.split('Mac OS')[-1].strip() + for c in version_end_chars: + if c in part: + version = part.split(c)[0] + return version.replace('_', '.') + return '' + + +class Windows(Dist): + look_for = 'Windows' + platform = 'Windows' + + +class Windows(OS): + look_for = 'Windows' + platform = 'Windows' + skip_if_found = ["Windows Phone"] + win_versions = { + "NT 10.0": "10", + "NT 6.3": "8.1", + "NT 6.2": "8", + "NT 6.1": "7", + "NT 6.0": "Vista", + "NT 5.2": "Server 2003 / XP x64", + "NT 5.1": "XP", + "NT 5.01": "2000 SP1", + "NT 5.0": "2000", + "98; Win 9x 4.90": "Me" + } + + def getVersion(self, agent, word): + v = agent.split('Windows')[-1].split(';')[0].strip() + if ')' in v: + v = v.split(')')[0] + v = self.win_versions.get(v, v) + return v + + +class Ubuntu(Dist): + look_for = 'Ubuntu' + version_markers = ["/", " "] + + +class Debian(Dist): + look_for = 'Debian' + version_markers = ["/", " "] + + +class Chrome(Browser): + look_for = "Chrome" + version_markers = ["/", " "] + skip_if_found = ["OPR", "Edge"] + + def getVersion(self, agent, word): + part = agent.split(word + self.version_markers[0])[-1] + version = part.split(self.version_markers[1])[0] + if '+' in version: + version = part.split('+')[0] + return version.strip() + + +class ChromeiOS(Browser): + look_for = "CriOS" + version_markers = ["/", " "] + + +class ChromeOS(OS): + look_for = "CrOS" + platform = ' ChromeOS' + version_markers = [" ", " "] + + def getVersion(self, agent, word): + version_markers = self.version_markers + if word + '+' in agent: + version_markers = ['+', '+'] + return agent.split(word + version_markers[0])[-1].split(version_markers[1])[1].strip()[:-1] + + +class Android(Dist): + look_for = 'Android' + platform = 'Android' + skip_if_found = ['Windows Phone'] + + def getVersion(self, agent, word): + return agent.split(word)[-1].split(';')[0].strip() + + +class WebOS(Dist): + look_for = 'hpwOS' + + def getVersion(self, agent, word): + return agent.split('hpwOS/')[-1].split(';')[0].strip() + + +class NokiaS40(OS): + look_for = 'Series40' + platform = 'Nokia S40' + + def getVersion(self, agent, word): + pass + + +class Symbian(OS): + look_for = ['Symbian', 'SymbianOS'] + platform = 'Symbian' + + +class PlayStation(OS): + look_for = ['PlayStation', 'PLAYSTATION'] + platform = 'PlayStation' + version_markers = [" ", ")"] + + +class prefs: # experimental + os = dict( + Linux=dict(dict(browser=[Firefox, Chrome], dist=[Ubuntu, Android])), + BlackBerry=dict(dist=[BlackberryPlaybook]), + Macintosh=dict(flavor=[MacOS]), + Windows=dict(browser=[MSIE, Firefox]), + ChromeOS=dict(browser=[Chrome]), + Debian=dict(browser=[Firefox]) + ) + dist = dict( + Ubuntu=dict(browser=[Firefox]), + Android=dict(browser=[Safari]), + IPhone=dict(browser=[Safari]), + IPad=dict(browser=[Safari]), + ) + flavor = dict( + MacOS=dict(browser=[Opera, Chrome, Firefox, MSIE]) + ) + + +detectorshub = DetectorsHub() + + +def detect(agent, fill_none=False): + """ + fill_none: if name/version is not detected respective key is still added to the result with value None + """ + result = dict(platform=dict(name=None, version=None)) + _suggested_detectors = [] + + for info_type in detectorshub: + detectors = _suggested_detectors or detectorshub[info_type] + for detector in detectors: + try: + detector.detect(agent, result) + except Exception as _err: + pass + + if fill_none: + attrs_d = {'name': None, 'version': None} + for key in ('os', 'browser'): + if key not in result: + result[key] = attrs_d + else: + for k, v in attrs_d.items(): + result[k] = v + + return result + + +def simple_detect(agent): + """ + -> (os, browser) # tuple of strings + """ + result = detect(agent) + os_list = [] + if 'flavor' in result: + os_list.append(result['flavor']['name']) + if 'dist' in result: + os_list.append(result['dist']['name']) + if 'os' in result: + os_list.append(result['os']['name']) + + os = os_list and " ".join(os_list) or "Unknown OS" + os_version = os_list and (result.get('flavor') and result['flavor'].get('version')) or \ + (result.get('dist') and result['dist'].get('version')) or (result.get('os') and result['os'].get('version')) or "" + browser = 'browser' in result and result['browser'].get('name') or 'Unknown Browser' + browser_version = 'browser' in result and result['browser'].get('version') or "" + if browser_version: + browser = " ".join((browser, browser_version)) + if os_version: + os = " ".join((os, os_version)) + return os, browser + + +class mobilize(object): + """ + Decorator for controller functions so they use different views for mobile devices. + + WARNING: If you update httpagentparser make sure to leave mobilize for + backwards compatibility. + """ + def __init__(self, func): + self.func = func + + def __call__(self): + from gluon import current + user_agent = current.request.user_agent() + if user_agent.is_mobile: + items = current.response.view.split('.') + items.insert(-1, 'mobile') + current.response.view = '.'.join(items) + return self.func() diff --git a/web2py/gluon/contrib/webclient.py b/web2py/gluon/contrib/webclient.py new file mode 100644 index 0000000..6454e97 --- /dev/null +++ b/web2py/gluon/contrib/webclient.py @@ -0,0 +1,223 @@ +""" +Developed by Massimo Di Pierro +Released under the web2py license (LGPL) + +It an interface on top of urllib2 which simplifies scripting of http requests +mostly for testing purposes + +- customizable +- supports basic auth +- supports cookies +- supports session cookies (tested with web2py sessions) +- detects broken session +- detects web2py form postbacks and handles formname and formkey +- detects web2py tickets + +Some examples at the bottom. +""" +from __future__ import print_function +from gluon._compat import urllib2, cookielib, iteritems, to_native, urlencode, to_bytes +import re +import time + + +DEFAULT_HEADERS = { + 'user-agent': 'Mozilla/4.0', # some servers are picky + 'accept-language': 'en', +} + +FORM_REGEX = re.compile('(\)?\') + +SESSION_REGEX = 'session_id_(?P.+)' + + +class WebClient(object): + + def __init__(self, + app='', + postbacks=True, + default_headers=DEFAULT_HEADERS, + session_regex=SESSION_REGEX): + self.app = app + self.postbacks = postbacks + self.forms = {} + self.history = [] + self.cookies = {} + self.cookiejar = cookielib.CookieJar() + self.default_headers = default_headers + self.sessions = {} + self.session_regex = session_regex and re.compile(session_regex) + self.headers = {} + + def _parse_headers_in_cookies(self): + self.cookies = {} + if 'set-cookie' in self.headers: + for item in self.headers['set-cookie'].split(','): + cookie = item[:item.find(';')] + pos = cookie.find('=') + key = cookie[:pos] + value = cookie[pos+1:] + self.cookies[key.strip()] = value.strip() + + def get(self, url, cookies=None, headers=None, auth=None): + return self.post(url, data=None, cookies=cookies, + headers=headers, method='GET') + + def post(self, url, data=None, cookies=None, + headers=None, auth=None, method='auto'): + self.url = self.app + url + + # if this POST form requires a postback do it + if data and '_formname' in data and self.postbacks and \ + self.history and self.history[-1][1] != self.url: + # to bypass the web2py CSRF need to get formkey + # before submitting the form + self.get(url, cookies=cookies, headers=headers, auth=auth) + + # unless cookies are specified, recycle cookies + if cookies is None: + cookies = self.cookies + cookies = cookies or {} + headers = headers or {} + + args = [ + urllib2.HTTPCookieProcessor(self.cookiejar), + urllib2.HTTPHandler(debuglevel=0) + ] + # if required do basic auth + if auth: + auth_handler = urllib2.HTTPBasicAuthHandler() + auth_handler.add_password(**auth) + args.append(auth_handler) + + opener = urllib2.build_opener(*args) + + # copy headers from dict to list of key,value + headers_list = [] + for key, value in iteritems(self.default_headers): + if not key in headers: + headers[key] = value + for key, value in iteritems(headers): + if isinstance(value, (list, tuple)): + for v in value: + headers_list.append((key, v)) + else: + headers_list.append((key, value)) + + # move cookies to headers + for key, value in iteritems(cookies): + headers_list.append(('Cookie', '%s=%s' % (key, value))) + + # add headers to request + for key, value in headers_list: + opener.addheaders.append((key, str(value))) + + # assume everything is ok and make http request + error = None + try: + if isinstance(data, str): + self.method = 'POST' if method=='auto' else method + elif isinstance(data, dict): + self.method = 'POST' if method=='auto' else method + # if there is only one form, set _formname automatically + if not '_formname' in data and len(self.forms) == 1: + data['_formname'] = self.forms.keys()[0] + + # if there is no formkey but it is known, set it + if '_formname' in data and not '_formkey' in data and \ + data['_formname'] in self.forms: + data['_formkey'] = self.forms[data['_formname']] + + # time the POST request + data = urlencode(data, doseq=True) + else: + self.method = 'GET' if method=='auto' else method + data = None + t0 = time.time() + self.response = opener.open(self.url, to_bytes(data)) + self.time = time.time() - t0 + except urllib2.HTTPError as er: + error = er + # catch HTTP errors + self.time = time.time() - t0 + self.response = er + + if hasattr(self.response, 'getcode'): + self.status = self.response.getcode() + else:#python2.5 + self.status = None + + self.text = to_native(self.response.read()) + # In PY3 self.response.headers are case sensitive + self.headers = dict() + for h in self.response.headers: + self.headers[h.lower()] = self.response.headers[h] + + # treat web2py tickets as special types of errors + if error is not None: + if 'web2py_error' in self.headers: + raise RuntimeError(self.headers['web2py_error']) + else: + raise error + + self._parse_headers_in_cookies() + + # check is a new session id has been issued, symptom of broken session + if self.session_regex is not None: + for cookie, value in iteritems(self.cookies): + match = self.session_regex.match(cookie) + if match: + name = match.group('name') + if name in self.sessions and self.sessions[name] != value: + print(RuntimeError('Changed session ID %s' % name)) + self.sessions[name] = value + + # find all forms and formkeys in page + self.forms = {} + for match in FORM_REGEX.finditer(to_native(self.text)): + self.forms[match.group('formname')] = match.group('formkey') + + # log this request + self.history.append((self.method, self.url, self.status, self.time)) + + +def test_web2py_registration_and_login(): + # from gluon.contrib.webclient import WebClient + # start a web2py instance for testing + + client = WebClient('http://127.0.0.1:8000/welcome/default/') + client.get('index') + + # register + data = dict(first_name='Homer', + last_name='Simpson', + email='homer@web2py.com', + password='test', + password_two='test', + _formname='register') + client.post('user/register', data=data) + + # logout + client.get('user/logout') + + # login + data = dict(email='homer@web2py.com', + password='test', + _formname='login') + client.post('user/login', data=data) + + # check registration and login were successful + client.get('user/profile') + assert 'Welcome Homer' in client.text + + # print some variables + print('\nsessions:\n', client.sessions) + print('\nheaders:\n', client.headers) + print('\ncookies:\n', client.cookies) + print('\nforms:\n', client.forms) + print() + for method, url, status, t in client.history: + print(method, url, status, t) + +if __name__ == '__main__': + test_web2py_registration_and_login() diff --git a/web2py/gluon/contrib/websocket_messaging.py b/web2py/gluon/contrib/websocket_messaging.py new file mode 100644 index 0000000..962e42a --- /dev/null +++ b/web2py/gluon/contrib/websocket_messaging.py @@ -0,0 +1,242 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/env python + +""" +This file is part of the web2py Web Framework +Copyrighted by Massimo Di Pierro +License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +Attention: Requires Chrome or Safari. For IE of Firefox you need https://github.com/gimite/web-socket-js + +1) install tornado (requires Tornado 3.0 or later) + + easy_install tornado + +2) start this app: + + python gluon/contrib/websocket_messaging.py -k mykey -p 8888 + +3) from any web2py app you can post messages with + + from gluon.contrib.websocket_messaging import websocket_send + websocket_send('http://127.0.0.1:8888', 'Hello World', 'mykey', 'mygroup') + +4) from any template you can receive them with + + + +When the server posts a message, all clients connected to the page will popup an alert message +Or if you want to send json messages and store evaluated json in a var called data: + + + +- All communications between web2py and websocket_messaging will be digitally signed with hmac. +- All validation is handled on the web2py side and there is no need to modify websocket_messaging.py +- Multiple web2py instances can talk with one or more websocket_messaging servers. +- "ws://127.0.0.1:8888/realtime/" must be contain the IP of the websocket_messaging server. +- Via group='mygroup' name you can support multiple groups of clients (think of many chat-rooms) + + +Here is a complete sample web2py action: + + def index(): + form=LOAD('default', 'ajax_form', ajax=True) + script=SCRIPT(''' + jQuery(document).ready(function(){ + var callback=function(e){alert(e.data)}; + if(!$.web2py.web2py_websocket('ws://127.0.0.1:8888/realtime/mygroup', callback)) + + alert("html5 websocket not supported by your browser, try Google Chrome"); + }); + ''') + return dict(form=form, script=script) + + def ajax_form(): + form=SQLFORM.factory(Field('message')) + if form.accepts(request,session): + from gluon.contrib.websocket_messaging import websocket_send + websocket_send( + 'http://127.0.0.1:8888', form.vars.message, 'mykey', 'mygroup') + return form + +https is possible too using 'https://127.0.0.1:8888' instead of 'http://127.0.0.1:8888', but need to +be started with + + python gluon/contrib/websocket_messaging.py -k mykey -p 8888 -s keyfile.pem -c certfile.pem + +for secure websocket do: + + web2py_websocket('wss://127.0.0.1:8888/realtime/mygroup',callback) + +Acknowledgements: +Tornado code inspired by http://thomas.pelletier.im/2010/08/websocket-tornado-redis/ + +""" +from __future__ import print_function +import tornado.httpserver +import tornado.websocket +import tornado.ioloop +import tornado.web +import hmac +import sys +import optparse +import time +import sys +import gluon.utils +from gluon._compat import to_native, to_bytes, urlencode, urlopen + +listeners, names, tokens = {}, {}, {} + +def websocket_send(url, message, hmac_key=None, group='default'): + sig = hmac_key and hmac.new(to_bytes(hmac_key), to_bytes(message)).hexdigest() or '' + params = urlencode( + {'message': message, 'signature': sig, 'group': group}) + f = urlopen(url, to_bytes(params)) + data = f.read() + f.close() + return data + + +class PostHandler(tornado.web.RequestHandler): + """ + only authorized parties can post messages + """ + def post(self): + if hmac_key and not 'signature' in self.request.arguments: + self.send_error(401) + if 'message' in self.request.arguments: + message = self.request.arguments['message'][0].decode(encoding='UTF-8') + group = self.request.arguments.get('group', ['default'])[0].decode(encoding='UTF-8') + print('%s:MESSAGE to %s:%s' % (time.time(), group, message)) + if hmac_key: + signature = self.request.arguments['signature'][0] + actual_signature = hmac.new(to_bytes(hmac_key), to_bytes(message)).hexdigest() + if not gluon.utils.compare(to_native(signature), actual_signature): + self.send_error(401) + for client in listeners.get(group, []): + client.write_message(message) + + +class TokenHandler(tornado.web.RequestHandler): + """ + if running with -t post a token to allow a client to join using the token + the message here is the token (any uuid) + allows only authorized parties to joins, for example, a chat + """ + def post(self): + if hmac_key and not 'message' in self.request.arguments: + self.send_error(401) + if 'message' in self.request.arguments: + message = self.request.arguments['message'][0] + if hmac_key: + signature = self.request.arguments['signature'][0] + actual_signature = hmac.new(to_bytes(hmac_key), to_bytes(message)).hexdigest() + if not gluon.utils.compare(to_native(signature), actual_signature): + self.send_error(401) + tokens[message] = None + + +class DistributeHandler(tornado.websocket.WebSocketHandler): + + def check_origin(self, origin): + return True + + def open(self, params): + group, token, name = params.split('/') + [None, None] + self.group = group or 'default' + self.token = token or 'none' + self.name = name or 'anonymous' + # only authorized parties can join + if DistributeHandler.tokens: + if not self.token in tokens or not token[self.token] is None: + self.close() + else: + tokens[self.token] = self + if not self.group in listeners: + listeners[self.group] = [] + # notify clients that a member has joined the groups + for client in listeners.get(self.group, []): + client.write_message('+' + self.name) + listeners[self.group].append(self) + names[self] = self.name + print('%s:CONNECT to %s' % (time.time(), self.group)) + + def on_message(self, message): + pass + + def on_close(self): + if self.group in listeners: + listeners[self.group].remove(self) + del names[self] + # notify clients that a member has left the groups + for client in listeners.get(self.group, []): + client.write_message('-' + self.name) + print('%s:DISCONNECT from %s' % (time.time(), self.group)) + +# if your webserver is different from tornado server uncomment this +# or override using something more restrictive: +# http://tornado.readthedocs.org/en/latest/websocket.html#tornado.websocket.WebSocketHandler.check_origin +# def check_origin(self, origin): +# return True + +if __name__ == "__main__": + usage = __doc__ + version = "" + parser = optparse.OptionParser(usage, None, optparse.Option, version) + parser.add_option('-p', + '--port', + default='8888', + dest='port', + help='socket') + parser.add_option('-l', + '--listen', + default='0.0.0.0', + dest='address', + help='listener address') + parser.add_option('-k', + '--hmac_key', + default='', + dest='hmac_key', + help='hmac_key') + parser.add_option('-t', + '--tokens', + action='store_true', + default=False, + dest='tokens', + help='require tockens to join') + parser.add_option('-s', + '--sslkey', + default=False, + dest='keyfile', + help='require ssl keyfile full path') + parser.add_option('-c', + '--sslcert', + default=False, + dest='certfile', + help='require ssl certfile full path') + (options, args) = parser.parse_args() + hmac_key = options.hmac_key + DistributeHandler.tokens = options.tokens + urls = [ + (r'/', PostHandler), + (r'/token', TokenHandler), + (r'/realtime/(.*)', DistributeHandler)] + application = tornado.web.Application(urls, auto_reload=True) + if options.keyfile and options.certfile: + ssl_options = dict(certfile=options.certfile, keyfile=options.keyfile) + else: + ssl_options = None + http_server = tornado.httpserver.HTTPServer(application, ssl_options=ssl_options) + http_server.listen(int(options.port), address=options.address) + tornado.ioloop.IOLoop.instance().start() diff --git a/web2py/gluon/custom_import.py b/web2py/gluon/custom_import.py new file mode 100644 index 0000000..e12dea4 --- /dev/null +++ b/web2py/gluon/custom_import.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +Support for smart import syntax for web2py applications +------------------------------------------------------- +""" +from gluon._compat import builtin, unicodeT, PY2, to_native, reload +import os +import sys +import threading +from gluon import current + +NATIVE_IMPORTER = builtin.__import__ +INVALID_MODULES = set(('', 'gluon', 'applications', 'custom_import')) + +# backward compatibility API + + +def custom_import_install(): + if builtin.__import__ == NATIVE_IMPORTER: + INVALID_MODULES.update(sys.modules.keys()) + builtin.__import__ = custom_importer + + +def track_changes(track=True): + assert track in (True, False), "must be True or False" + current.request._custom_import_track_changes = track + + +def is_tracking_changes(): + return current.request._custom_import_track_changes + + +class CustomImportException(ImportError): + pass + + +def custom_importer(name, globals=None, locals=None, fromlist=None, level=-1): + """ + web2py's custom importer. It behaves like the standard Python importer but + it tries to transform import statements as something like + "import applications.app_name.modules.x". + If the import fails, it falls back on naive_importer + """ + + if isinstance(name, unicodeT): + name = to_native(name) + + globals = globals or {} + locals = locals or {} + fromlist = fromlist or [] + + try: + if current.request._custom_import_track_changes: + base_importer = TRACK_IMPORTER + else: + base_importer = NATIVE_IMPORTER + except: # there is no current.request (should never happen) + base_importer = NATIVE_IMPORTER + + if not(PY2) and level < 0: + level = 0 + + # if not relative and not from applications: + if hasattr(current, 'request') \ + and level <= 0 \ + and not name.partition('.')[0] in INVALID_MODULES \ + and isinstance(globals, dict): + import_tb = None + try: + try: + oname = name if not name.startswith('.') else '.'+name + return NATIVE_IMPORTER(oname, globals, locals, fromlist, level) + except (ImportError, KeyError): + items = current.request.folder.split(os.path.sep) + if not items[-1]: + items = items[:-1] + modules_prefix = '.'.join(items[-2:]) + '.modules' + if not fromlist: + # import like "import x" or "import x.y" + result = None + for itemname in name.split("."): + new_mod = base_importer( + modules_prefix, globals, locals, [itemname], level) + try: + result = result or sys.modules[modules_prefix+'.'+itemname] + except KeyError as e: + raise ImportError('Cannot import module %s' % str(e)) + modules_prefix += "." + itemname + return result + else: + # import like "from x import a, b, ..." + pname = modules_prefix + "." + name + return base_importer(pname, globals, locals, fromlist, level) + except ImportError as e1: + import_tb = sys.exc_info()[2] + try: + return NATIVE_IMPORTER(name, globals, locals, fromlist, level) + except (ImportError, KeyError) as e3: + raise ImportError(e1, import_tb) # there an import error in the module + except Exception as e2: + raise # there is an error in the module + finally: + if import_tb: + import_tb = None + + return NATIVE_IMPORTER(name, globals, locals, fromlist, level) + + +class TrackImporter(object): + """ + An importer tracking the date of the module files and reloading them when + they are changed. + """ + + THREAD_LOCAL = threading.local() + PACKAGE_PATH_SUFFIX = os.path.sep + "__init__.py" + + def __init__(self): + self._import_dates = {} # Import dates of the files of the modules + + def __call__(self, name, globals=None, locals=None, fromlist=None, level=-1): + """ + The import method itself. + """ + globals = globals or {} + locals = locals or {} + fromlist = fromlist or [] + try: + # Check the date and reload if needed: + self._update_dates(name, globals, locals, fromlist, level) + # Try to load the module and update the dates if it works: + result = NATIVE_IMPORTER(name, globals, locals, fromlist, level) + # Module maybe loaded for the 1st time so we need to set the date + self._update_dates(name, globals, locals, fromlist, level) + return result + except Exception as e: + raise # Don't hide something that went wrong + + def _update_dates(self, name, globals, locals, fromlist, level): + """ + Update all the dates associated to the statement import. A single + import statement may import many modules. + """ + + self._reload_check(name, globals, locals, level) + for fromlist_name in fromlist or []: + pname = "%s.%s" % (name, fromlist_name) + self._reload_check(pname, globals, locals, level) + + def _reload_check(self, name, globals, locals, level): + """ + Update the date associated to the module and reload the module if + the file changed. + """ + module = sys.modules.get(name) + file = self._get_module_file(module) + if file: + date = self._import_dates.get(file) + new_date = None + reload_mod = False + mod_to_pack = False # Module turning into a package? (special case) + try: + new_date = os.path.getmtime(file) + except: + self._import_dates.pop(file, None) # Clean up + # Handle module changing in package and + #package changing in module: + if file.endswith(".py"): + # Get path without file ext: + file = os.path.splitext(file)[0] + reload_mod = os.path.isdir(file) \ + and os.path.isfile(file + self.PACKAGE_PATH_SUFFIX) + mod_to_pack = reload_mod + else: # Package turning into module? + file += ".py" + reload_mod = os.path.isfile(file) + if reload_mod: + new_date = os.path.getmtime(file) # Refresh file date + if reload_mod or not date or new_date > date: + self._import_dates[file] = new_date + if reload_mod or (date and new_date > date): + if mod_to_pack: + # Module turning into a package: + mod_name = module.__name__ + del sys.modules[mod_name] # Delete the module + # Reload the module: + NATIVE_IMPORTER(mod_name, globals, locals, [], level) + else: + reload(module) + + def _get_module_file(self, module): + """ + Get the absolute path file associated to the module or None. + """ + file = getattr(module, "__file__", None) + if file: + # Make path absolute if not: + file = os.path.splitext(file)[0] + ".py" # Change .pyc for .py + if file.endswith(self.PACKAGE_PATH_SUFFIX): + file = os.path.dirname(file) # Track dir for packages + return file + +TRACK_IMPORTER = TrackImporter() diff --git a/web2py/gluon/dal.py b/web2py/gluon/dal.py new file mode 100644 index 0000000..471ed65 --- /dev/null +++ b/web2py/gluon/dal.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +Takes care of adapting pyDAL to web2py's needs +----------------------------------------------- +""" + +from pydal import DAL as DAL +from pydal import Field +from pydal.objects import Row, Rows, Table, Query, Set, Expression +from pydal import SQLCustomType, geoPoint, geoLine, geoPolygon +from pydal.migrator import Migrator, InDBMigrator +from gluon.serializers import custom_json, xml +from gluon.utils import web2py_uuid +from gluon import sqlhtml +from pydal.drivers import DRIVERS + + +def _default_validators(db, field): + """ + Field type validation, using web2py's validators mechanism. + + makes sure the content of a field is in line with the declared + fieldtype + """ + from gluon import validators + field_type, field_length = field.type, field.length + requires = [] + + if isinstance(field.options, list) and field.requires: + requires = validators.IS_IN_SET(field.options, multiple=field_type.startswith('list:')) + elif field.regex and not field.requires: + requires.append(validators.IS_REGEX(regex)) + elif field_type in (('string', 'text', 'password')): + requires.append(validators.IS_LENGTH(field_length)) + elif field_type == 'json': + requires.append(validators.IS_EMPTY_OR(validators.IS_JSON())) + elif field_type == 'double' or field_type == 'float': + requires.append(validators.IS_FLOAT_IN_RANGE(-1e100, 1e100)) + elif field_type == 'integer': + requires.append(validators.IS_INT_IN_RANGE(-2**31, 2**31)) + elif field_type == 'bigint': + requires.append(validators.IS_INT_IN_RANGE(-2**63, 2**63)) + elif field_type.startswith('decimal'): + requires.append(validators.IS_DECIMAL_IN_RANGE(-10**10, 10**10)) + elif field_type == 'date': + requires.append(validators.IS_DATE()) + elif field_type == 'time': + requires.append(validators.IS_TIME()) + elif field_type == 'datetime': + requires.append(validators.IS_DATETIME()) + elif db and field_type.startswith('reference'): + if field_type.find('.') < 0 and field_type[10:] in db.tables: + referenced = db[field_type[10:]] + if hasattr(referenced, '_format') and referenced._format: + requires = validators.IS_IN_DB(db, referenced._id,referenced._format) + else: + requires = validators.IS_IN_DB(db, referenced._id) + elif field_type.find('.') > 0 and field_type[10:].split('.')[0] in db.tables: + table_field = field_type[10:].split('.') + table_name=table_field[0] + field_name=table_field[1] + referenced = db[table_name] + if hasattr(referenced, '_format') and referenced._format: + requires = validators.IS_IN_DB(db, referenced[field_name],referenced._format) + else: + requires = validators.IS_IN_DB(db, referenced[field_name]) + if field.unique: + requires._and = validators.IS_NOT_IN_DB(db, field) + if not field.notnull: + requires = validators.IS_EMPTY_OR(requires) + return requires + elif db and field_type.startswith('list:reference'): + if field_type.find('.') < 0 and field_type[15:] in db.tables: + referenced = db[field_type[15:]] + if hasattr(referenced, '_format') and referenced._format: + requires = validators.IS_IN_DB(db, referenced._id, + referenced._format, multiple=True) + else: + requires = validators.IS_IN_DB(db, referenced._id, + multiple=True) + elif field_type.find('.') > 0 and field_type[15:].split('.')[0] in db.tables: + table_field = field_type[15:].split('.') + table_name=table_field[0] + field_name=table_field[1] + referenced = db[table_name] + if hasattr(referenced, '_format') and referenced._format: + requires = validators.IS_IN_DB(db, referenced[field_name], + referenced._format, multiple=True) + else: + requires = validators.IS_IN_DB(db, referenced[field_name], + multiple=True) + if field.unique: + requires._and = validators.IS_NOT_IN_DB(db, field) + if not field.notnull: + requires = validators.IS_EMPTY_OR(requires) + return requires + # does not get here for reference and list:reference + if isinstance(requires, list): + if field.unique: + requires.insert(0, validators.IS_NOT_IN_DB(db, field)) + excluded_fields = ['string', 'upload', 'text', 'password', 'boolean'] + if (field.notnull or field.unique) and field_type not in excluded_fields: + requires.insert(0, validators.IS_NOT_EMPTY()) + elif not field.notnull and not field.unique and requires: + null = null='' if field.type in ('string', 'text', 'password') else None + requires[0] = validators.IS_EMPTY_OR(requires[0], null=null) + return requires + +DAL.serializers = {'json': custom_json, 'xml': xml} +DAL.validators_method = _default_validators +DAL.uuid = lambda x: web2py_uuid() +DAL.representers = { + 'rows_render': sqlhtml.represent, + 'rows_xml': sqlhtml.SQLTABLE +} +DAL.Field = Field +DAL.Table = Table + +# add web2py contrib drivers to pyDAL +if not DRIVERS.get('pymysql'): + try: + from .contrib import pymysql + DRIVERS['pymysql'] = pymysql + except: + pass +if not DRIVERS.get('pyodbc'): + try: + from .contrib import pypyodbc as pyodbc + DRIVERS['pyodbc'] = pyodbc + except: + pass +if not DRIVERS.get('pg8000'): + try: + from .contrib import pg8000 + DRIVERS['pg8000'] = pg8000 + except: + pass diff --git a/web2py/gluon/debug.py b/web2py/gluon/debug.py new file mode 100644 index 0000000..8f75c5d --- /dev/null +++ b/web2py/gluon/debug.py @@ -0,0 +1,196 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Developed by Massimo Di Pierro , +| limodou and srackham . +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +Debugger support classes +------------------------ +""" + +import logging +import pdb +import sys +from gluon._compat import Queue + +logger = logging.getLogger("web2py") + + +class Pipe(Queue.Queue): + def __init__(self, name, mode='r', *args, **kwargs): + self.__name = name + Queue.Queue.__init__(self, *args, **kwargs) + + def write(self, data): + logger.debug("debug %s writing %s" % (self.__name, data)) + self.put(data) + + def flush(self): + # mark checkpoint (complete message) + logger.debug("debug %s flushing..." % self.__name) + self.put(None) + # wait until it is processed + self.join() + logger.debug("debug %s flush done" % self.__name) + + def read(self, count=None, timeout=None): + logger.debug("debug %s reading..." % (self.__name, )) + data = self.get(block=True, timeout=timeout) + # signal that we are ready + self.task_done() + logger.debug("debug %s read %s" % (self.__name, data)) + return data + + def readline(self): + logger.debug("debug %s readline..." % (self.__name, )) + return self.read() + + +pipe_in = Pipe('in') +pipe_out = Pipe('out') + +debugger = pdb.Pdb(completekey=None, stdin=pipe_in, stdout=pipe_out,) + + +def set_trace(): + """breakpoint shortcut (like pdb)""" + logger.info("DEBUG: set_trace!") + debugger.set_trace(sys._getframe().f_back) + + +def stop_trace(): + """stop waiting for the debugger (called atexit)""" + # this should prevent communicate is wait forever a command result + # and the main thread has finished + logger.info("DEBUG: stop_trace!") + pipe_out.write("debug finished!") + pipe_out.write(None) + #pipe_out.flush() + + +def communicate(command=None): + """send command to debbuger, wait result""" + if command is not None: + logger.info("DEBUG: sending command %s" % command) + pipe_in.write(command) + #pipe_in.flush() + result = [] + while True: + data = pipe_out.read() + if data is None: + break + result.append(data) + logger.info("DEBUG: result %s" % repr(result)) + return ''.join(result) + + +# New debugger implementation using dbg and a web UI + +import gluon.contrib.dbg as c_dbg +from threading import RLock + +interact_lock = RLock() +run_lock = RLock() + + +def check_interaction(fn): + """Decorator to clean and prevent interaction when not available""" + def check_fn(self, *args, **kwargs): + interact_lock.acquire() + try: + if self.filename: + self.clear_interaction() + return fn(self, *args, **kwargs) + finally: + interact_lock.release() + return check_fn + + +class WebDebugger(c_dbg.Frontend): + """Qdb web2py interface""" + + def __init__(self, pipe, completekey='tab', stdin=None, stdout=None): + c_dbg.Frontend.__init__(self, pipe) + self.clear_interaction() + + def clear_interaction(self): + self.filename = None + self.lineno = None + self.exception_info = None + self.context = None + + # redefine Frontend methods: + + def run(self): + run_lock.acquire() + try: + while self.pipe.poll(): + c_dbg.Frontend.run(self) + finally: + run_lock.release() + + def interaction(self, filename, lineno, line, **context): + # store current status + interact_lock.acquire() + try: + self.filename = filename + self.lineno = lineno + self.context = context + finally: + interact_lock.release() + + def exception(self, title, extype, exvalue, trace, request): + self.exception_info = {'title': title, + 'extype': extype, 'exvalue': exvalue, + 'trace': trace, 'request': request} + + @check_interaction + def do_continue(self): + c_dbg.Frontend.do_continue(self) + + @check_interaction + def do_step(self): + c_dbg.Frontend.do_step(self) + + @check_interaction + def do_return(self): + c_dbg.Frontend.do_return(self) + + @check_interaction + def do_next(self): + c_dbg.Frontend.do_next(self) + + @check_interaction + def do_quit(self): + c_dbg.Frontend.do_quit(self) + + def do_exec(self, statement): + interact_lock.acquire() + try: + # check to see if we're inside interaction + if self.filename: + # avoid spurious interaction notifications: + self.set_burst(2) + # execute the statement in the remote debugger: + return c_dbg.Frontend.do_exec(self, statement) + finally: + interact_lock.release() + +# create the connection between threads: + +parent_queue, child_queue = Queue.Queue(), Queue.Queue() +front_conn = c_dbg.QueuePipe("parent", parent_queue, child_queue) +child_conn = c_dbg.QueuePipe("child", child_queue, parent_queue) + +web_debugger = WebDebugger(front_conn) # frontend +dbg_debugger = c_dbg.Qdb(pipe=child_conn, redirect_stdio=False, skip=None) # backend +dbg = dbg_debugger + +# enable getting context (stack, globals/locals) at interaction +dbg_debugger.set_params(dict(call_stack=True, environment=True)) + +import gluon.main +gluon.main.global_settings.debugging = True diff --git a/web2py/gluon/decoder.py b/web2py/gluon/decoder.py new file mode 100644 index 0000000..57044bc --- /dev/null +++ b/web2py/gluon/decoder.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Caller will hand this library a buffer and ask it to either convert +it or auto-detect the type. + +Based on http://code.activestate.com/recipes/52257/ + +Licensed under the PSF License +""" +from gluon._compat import to_unicode +import codecs + +# None represents a potentially variable byte. "##" in the XML spec... +autodetect_dict = { # bytepattern : ("name", + (0x00, 0x00, 0xFE, 0xFF): ("ucs4_be"), + (0xFF, 0xFE, 0x00, 0x00): ("ucs4_le"), + (0xFE, 0xFF, None, None): ("utf_16_be"), + (0xFF, 0xFE, None, None): ("utf_16_le"), + (0x00, 0x3C, 0x00, 0x3F): ("utf_16_be"), + (0x3C, 0x00, 0x3F, 0x00): ("utf_16_le"), + (0x3C, 0x3F, 0x78, 0x6D): ("utf_8"), + (0x4C, 0x6F, 0xA7, 0x94): ("EBCDIC") +} + + +def autoDetectXMLEncoding(buffer): + """ buffer -> encoding_name + The buffer should be at least 4 bytes long. + Returns None if encoding cannot be detected. + Note that encoding_name might not have an installed + decoder (e.g. EBCDIC) + """ + # a more efficient implementation would not decode the whole + # buffer at once but otherwise we'd have to decode a character at + # a time looking for the quote character...that's a pain + + encoding = "utf_8" + # according to the XML spec, this is the default this code successively tries to refine the default + # whenever it fails to refine, it falls back to the last place encoding was set. + + if len(buffer) >= 4: + bytes = (byte1, byte2, byte3, byte4) = tuple(map(ord, buffer[0:4])) + enc_info = autodetect_dict.get(bytes, None) + if not enc_info: # try autodetection again removing potentially + # variable bytes + bytes = (byte1, byte2, None, None) + enc_info = autodetect_dict.get(bytes) + else: + enc_info = None + + if enc_info: + encoding = enc_info # we've got a guess... these are the new defaults + + # try to find a more precise encoding using xml declaration + secret_decoder_ring = codecs.lookup(encoding)[1] + (decoded, length) = secret_decoder_ring(buffer) + first_line = decoded.split("\n")[0] + if first_line and first_line.startswith(u" -1: + quote_char, rest = (first_line[quote_pos], + first_line[quote_pos + 1:]) + encoding = rest[:rest.find(quote_char)] + + return encoding + + +def decoder(buffer): + encoding = autoDetectXMLEncoding(buffer) + return to_unicode(buffer, charset=encoding) diff --git a/web2py/gluon/fileutils.py b/web2py/gluon/fileutils.py new file mode 100644 index 0000000..c1644be --- /dev/null +++ b/web2py/gluon/fileutils.py @@ -0,0 +1,482 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +File operations +--------------- +""" + +from gluon import storage +import os +import re +import tarfile +import glob +import time +import datetime +import logging +from gluon.http import HTTP +from gzip import open as gzopen +from gluon.recfile import generate +from gluon._compat import PY2 + +__all__ = [ + 'parse_version', + 'read_file', + 'write_file', + 'readlines_file', + 'up', + 'abspath', + 'mktree', + 'listdir', + 'recursive_unlink', + 'cleanpath', + 'tar', + 'untar', + 'tar_compiled', + 'get_session', + 'check_credentials', + 'w2p_pack', + 'w2p_unpack', + 'w2p_pack_plugin', + 'w2p_unpack_plugin', + 'fix_newlines', + 'make_fake_file_like_object', +] + + +def parse_semantic(version="Version 1.99.0-rc.1+timestamp.2011.09.19.08.23.26"): + """Parses a version string according to http://semver.org/ rules + + Args: + version(str): the SemVer string + + Returns: + tuple: Major, Minor, Patch, Release, Build Date + + """ + re_version = re.compile('(\d+)\.(\d+)\.(\d+)(\-(?P
    [^\s+]*))?(\+(?P\S*))')
    +    m = re_version.match(version.strip().split()[-1])
    +    if not m:
    +        return None
    +    a, b, c = int(m.group(1)), int(m.group(2)), int(m.group(3))
    +    pre_release = m.group('pre') or ''
    +    build = m.group('build') or ''
    +    if build.startswith('timestamp'):
    +        build = datetime.datetime.strptime(build.split('.', 1)[1], '%Y.%m.%d.%H.%M.%S')
    +    return (a, b, c, pre_release, build)
    +
    +
    +def parse_legacy(version="Version 1.99.0 (2011-09-19 08:23:26)"):
    +    """Parses "legacy" version string
    +
    +    Args:
    +        version(str): the version string
    +
    +    Returns:
    +        tuple: Major, Minor, Patch, Release, Build Date
    +
    +    """
    +    re_version = re.compile('[^\d]+ (\d+)\.(\d+)\.(\d+)\s*\((?P.+?)\)\s*(?P[a-z]+)?')
    +    m = re_version.match(version)
    +    a, b, c = int(m.group(1)), int(m.group(2)), int(m.group(3)),
    +    pre_release = m.group('type') or 'dev'
    +    build = datetime.datetime.strptime(m.group('datetime'), '%Y-%m-%d %H:%M:%S')
    +    return (a, b, c, pre_release, build)
    +
    +
    +def parse_version(version):
    +    """Attempts to parse SemVer, fallbacks on legacy
    +    """
    +    version_tuple = parse_semantic(version)
    +    if not version_tuple:
    +        version_tuple = parse_legacy(version)
    +    return version_tuple
    +
    +
    +def open_file(filename, mode):
    +    if PY2 or 'b' in mode:
    +        f = open(filename, mode)
    +    else:
    +        f = open(filename, mode, encoding="utf8")
    +    return f
    +
    +
    +def read_file(filename, mode='r'):
    +    """Returns content from filename, making sure to close the file explicitly
    +    on exit.
    +    """
    +    f = open_file(filename, mode)
    +    try:
    +        return f.read()
    +    finally:
    +        f.close()
    +
    +
    +def write_file(filename, value, mode='w'):
    +    """Writes  to filename, making sure to close the file
    +    explicitly on exit.
    +    """
    +    f = open_file(filename, mode)
    +    try:
    +        return f.write(value)
    +    finally:
    +        f.close()
    +
    +
    +def readlines_file(filename, mode='r'):
    +    """Applies .split('\n') to the output of `read_file()`
    +    """
    +    return read_file(filename, mode).split('\n')
    +
    +
    +def mktree(path):
    +    head, tail = os.path.split(path)
    +    if head:
    +        if tail:
    +            mktree(head)
    +        if not os.path.exists(head):
    +            os.mkdir(head)
    +
    +
    +def listdir(path,
    +            expression='^.+$',
    +            drop=True,
    +            add_dirs=False,
    +            sort=True,
    +            maxnum=None,
    +            exclude_content_from=None
    +            ):
    +    """
    +    Like `os.listdir()` but you can specify a regex pattern to filter files.
    +    If `add_dirs` is True, the returned items will have the full path.
    +    """
    +    if exclude_content_from is None:
    +        exclude_content_from = []
    +    if path[-1:] != os.path.sep:
    +        path = path + os.path.sep
    +    if drop:
    +        n = len(path)
    +    else:
    +        n = 0
    +    regex = re.compile(expression)
    +    items = []
    +    for (root, dirs, files) in os.walk(path, topdown=True):
    +        for dir in dirs[:]:
    +            if dir.startswith('.'):
    +                dirs.remove(dir)
    +        if add_dirs:
    +            items.append(root[n:])
    +        for file in sorted(files):
    +            if regex.match(file) and not file.startswith('.'):
    +                if root not in exclude_content_from:
    +                    items.append(os.path.join(root, file)[n:])
    +            if maxnum and len(items) >= maxnum:
    +                break
    +    if sort:
    +        return sorted(items)
    +    else:
    +        return items
    +
    +
    +def recursive_unlink(f):
    +    """Deletes `f`. If it's a folder, also its contents will be deleted
    +    """
    +    if os.path.isdir(f):
    +        for s in os.listdir(f):
    +            recursive_unlink(os.path.join(f, s))
    +        os.rmdir(f)
    +    elif os.path.isfile(f):
    +        os.unlink(f)
    +
    +
    +def cleanpath(path):
    +    """Turns any expression/path into a valid filename. replaces / with _ and
    +    removes special characters.
    +    """
    +
    +    items = path.split('.')
    +    if len(items) > 1:
    +        path = re.sub('[^\w\.]+', '_', '_'.join(items[:-1]) + '.'
    +                      + ''.join(items[-1:]))
    +    else:
    +        path = re.sub('[^\w\.]+', '_', ''.join(items[-1:]))
    +    return path
    +
    +
    +def _extractall(filename, path='.', members=None):
    +    tar = tarfile.TarFile(filename, 'r')
    +    ret = tar.extractall(path, members)
    +    tar.close()
    +    return ret
    +
    +
    +def tar(file, dir, expression='^.+$',
    +        filenames=None, exclude_content_from=None):
    +    """Tars dir into file, only tars file that match expression
    +    """
    +
    +    tar = tarfile.TarFile(file, 'w')
    +    try:
    +        if filenames is None:
    +            filenames = listdir(dir, expression, add_dirs=True,
    +                exclude_content_from=exclude_content_from)
    +        for file in filenames:
    +            tar.add(os.path.join(dir, file), file, False)
    +    finally:
    +        tar.close()
    +
    +
    +def untar(file, dir):
    +    """Untar file into dir
    +    """
    +
    +    _extractall(file, dir)
    +
    +
    +def w2p_pack(filename, path, compiled=False, filenames=None):
    +    """Packs a web2py application.
    +
    +    Args:
    +        filename(str): path to the resulting archive
    +        path(str): path to the application
    +        compiled(bool): if `True` packs the compiled version
    +        filenames(list): adds filenames to the archive
    +    """
    +    filename = abspath(filename)
    +    path = abspath(path)
    +    tarname = filename + '.tar'
    +    if compiled:
    +        tar_compiled(tarname, path, '^[\w\.\-]+$',
    +                     exclude_content_from=['cache', 'sessions', 'errors'])
    +    else:
    +        tar(tarname, path, '^[\w\.\-]+$', filenames=filenames,
    +            exclude_content_from=['cache', 'sessions', 'errors'])
    +    w2pfp = gzopen(filename, 'wb')
    +    tarfp = open(tarname, 'rb')
    +    w2pfp.write(tarfp.read())
    +    w2pfp.close()
    +    tarfp.close()
    +    os.unlink(tarname)
    +
    +
    +def create_welcome_w2p():
    +    is_newinstall_file = os.path.exists('NEWINSTALL')
    +    if not os.path.exists('welcome.w2p') or is_newinstall_file:
    +        try:
    +            w2p_pack('welcome.w2p', 'applications/welcome')
    +            logging.info("New installation: created welcome.w2p file")
    +        except:
    +            logging.error("New installation error: unable to create welcome.w2p file")
    +            return
    +        if is_newinstall_file:
    +            try:
    +                os.unlink('NEWINSTALL')
    +                logging.info("New installation: removed NEWINSTALL file")
    +            except:
    +                logging.error("New installation error: unable to remove NEWINSTALL file")
    +
    +
    +def w2p_unpack(filename, path, delete_tar=True):
    +
    +    if filename == 'welcome.w2p':
    +        create_welcome_w2p()
    +    filename = abspath(filename)
    +    path = abspath(path)
    +    if filename[-4:] == '.w2p' or filename[-3:] == '.gz':
    +        if filename[-4:] == '.w2p':
    +            tarname = filename[:-4] + '.tar'
    +        else:
    +            tarname = filename[:-3] + '.tar'
    +        fgzipped = gzopen(filename, 'rb')
    +        tarfile = open(tarname, 'wb')
    +        tarfile.write(fgzipped.read())
    +        tarfile.close()
    +        fgzipped.close()
    +    else:
    +        tarname = filename
    +    untar(tarname, path)
    +    if delete_tar:
    +        os.unlink(tarname)
    +
    +
    +def w2p_pack_plugin(filename, path, plugin_name):
    +    """Packs the given plugin into a w2p file.
    +    Will match files at::
    +
    +        /*/plugin_[name].*
    +        /*/plugin_[name]/*
    +
    +    """
    +    filename = abspath(filename)
    +    path = abspath(path)
    +    if not filename.endswith('web2py.plugin.%s.w2p' % plugin_name):
    +        raise Exception("Not a web2py plugin name")
    +    plugin_tarball = tarfile.open(filename, 'w:gz')
    +    try:
    +        app_dir = path
    +        while app_dir[-1] == '/':
    +            app_dir = app_dir[:-1]
    +        files1 = glob.glob(
    +            os.path.join(app_dir, '*/plugin_%s.*' % plugin_name))
    +        files2 = glob.glob(
    +            os.path.join(app_dir, '*/plugin_%s/*' % plugin_name))
    +        for file in files1 + files2:
    +            plugin_tarball.add(file, arcname=file[len(app_dir) + 1:])
    +    finally:
    +        plugin_tarball.close()
    +
    +
    +def w2p_unpack_plugin(filename, path, delete_tar=True):
    +    filename = abspath(filename)
    +    path = abspath(path)
    +    if not os.path.basename(filename).startswith('web2py.plugin.'):
    +        raise Exception("Not a web2py plugin")
    +    w2p_unpack(filename, path, delete_tar)
    +
    +
    +def tar_compiled(file, dir, expression='^.+$',
    +                 exclude_content_from=None):
    +    """Used to tar a compiled application.
    +    The content of models, views, controllers is not stored in the tar file.
    +    """
    +
    +    tar = tarfile.TarFile(file, 'w')
    +    for file in listdir(dir, expression, add_dirs=True,
    +                        exclude_content_from=exclude_content_from):
    +        filename = os.path.join(dir, file)
    +        if os.path.islink(filename):
    +            continue
    +        if os.path.isfile(filename) and file[-4:] != '.pyc':
    +            if file[:6] == 'models':
    +                continue
    +            if file[:5] == 'views':
    +                continue
    +            if file[:11] == 'controllers':
    +                continue
    +            if file[:7] == 'modules':
    +                continue
    +        tar.add(filename, file, False)
    +    tar.close()
    +
    +
    +def up(path):
    +    return os.path.dirname(os.path.normpath(path))
    +
    +
    +def get_session(request, other_application='admin'):
    +    """Checks that user is authorized to access other_application"""
    +    if request.application == other_application:
    +        raise KeyError
    +    try:
    +        session_id = request.cookies['session_id_' + other_application].value
    +        session_filename = os.path.join(
    +            up(request.folder), other_application, 'sessions', session_id)
    +        if not os.path.exists(session_filename):
    +            session_filename = generate(session_filename)
    +        osession = storage.load_storage(session_filename)
    +    except Exception as e:
    +        osession = storage.Storage()
    +    return osession
    +
    +
    +def set_session(request, session, other_application='admin'):
    +    """Checks that user is authorized to access other_application"""
    +    if request.application == other_application:
    +        raise KeyError
    +    session_id = request.cookies['session_id_' + other_application].value
    +    session_filename = os.path.join(
    +        up(request.folder), other_application, 'sessions', session_id)
    +    storage.save_storage(session, session_filename)
    +
    +
    +def check_credentials(request, other_application='admin',
    +                      expiration=60 * 60, gae_login=True):
    +    """Checks that user is authorized to access other_application"""
    +    if request.env.web2py_runtime_gae:
    +        from google.appengine.api import users
    +        if users.is_current_user_admin():
    +            return True
    +        elif gae_login:
    +            login_html = 'Sign in with your google account.' \
    +                % users.create_login_url(request.env.path_info)
    +            raise HTTP(200, '%s' % login_html)
    +        else:
    +            return False
    +    else:
    +        t0 = time.time()
    +        dt = t0 - expiration
    +        s = get_session(request, other_application)
    +        r = (s.authorized and s.last_time and s.last_time > dt)
    +        if r:
    +            s.last_time = t0
    +            set_session(request, s, other_application)
    +        return r
    +
    +
    +def fix_newlines(path):
    +    regex = re.compile(r'''(\r
    +|\r|
    +)''')
    +    for filename in listdir(path, '.*\.(py|html)$', drop=False):
    +        rdata = read_file(filename, 'r')
    +        wdata = regex.sub('\n', rdata)
    +        if wdata != rdata:
    +            write_file(filename, wdata, 'w')
    +
    +
    +def copystream(
    +    src,
    +    dest,
    +    size,
    +    chunk_size=10 ** 5,
    +):
    +    """
    +    this is here because I think there is a bug in shutil.copyfileobj
    +    """
    +    while size > 0:
    +        if size < chunk_size:
    +            data = src.read(size)
    +        else:
    +            data = src.read(chunk_size)
    +        length = len(data)
    +        if length > size:
    +            (data, length) = (data[:size], size)
    +        size -= length
    +        if length == 0:
    +            break
    +        dest.write(data)
    +        if length < chunk_size:
    +            break
    +    dest.seek(0)
    +    return
    +
    +
    +def make_fake_file_like_object():
    +    class LogFile(object):
    +        def write(self, value):
    +            pass
    +
    +        def close(self):
    +            pass
    +    return LogFile()
    +
    +
    +from gluon.settings import global_settings  # we need to import settings here because
    +                                      # settings imports fileutils too
    +
    +
    +def abspath(*relpath, **base):
    +    """Converts relative path to absolute path based (by default) on
    +    applications_parent
    +    """
    +    path = os.path.join(*relpath)
    +    gluon = base.get('gluon', False)
    +    if os.path.isabs(path):
    +        return path
    +    if gluon:
    +        return os.path.join(global_settings.gluon_parent, path)
    +    return os.path.join(global_settings.applications_parent, path)
    diff --git a/web2py/gluon/globals.py b/web2py/gluon/globals.py
    new file mode 100644
    index 0000000..512f576
    --- /dev/null
    +++ b/web2py/gluon/globals.py
    @@ -0,0 +1,1287 @@
    +#!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +
    +"""
    +| This file is part of the web2py Web Framework
    +| Copyrighted by Massimo Di Pierro 
    +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
    +
    +Contains the classes for the global used variables:
    +
    +- Request
    +- Response
    +- Session
    +
    +"""
    +from gluon._compat import pickle, StringIO, copyreg, Cookie, urlparse, PY2, iteritems, to_unicode, to_native, \
    +    to_bytes, unicodeT, long, hashlib_md5, urllib_quote
    +from gluon.storage import Storage, List
    +from gluon.streamer import streamer, stream_file_or_304_or_206, DEFAULT_CHUNK_SIZE
    +from gluon.contenttype import contenttype
    +from gluon.html import xmlescape, TABLE, TR, PRE, URL
    +from gluon.http import HTTP, redirect
    +from gluon.fileutils import up
    +from gluon.serializers import json, custom_json
    +import gluon.settings as settings
    +from gluon.utils import web2py_uuid, secure_dumps, secure_loads
    +from gluon.settings import global_settings
    +from gluon import recfile
    +from gluon.cache import CacheInRam
    +from gluon.fileutils import copystream
    +import hashlib
    +from pydal.contrib import portalocker
    +from pickle import Pickler, MARK, DICT, EMPTY_DICT
    +# from types import DictionaryType
    +import datetime
    +import re
    +import os
    +import sys
    +import traceback
    +import threading
    +import cgi
    +import copy
    +import tempfile
    +import json as json_parser
    +
    +
    +FMT = '%a, %d-%b-%Y %H:%M:%S PST'
    +PAST = 'Sat, 1-Jan-1971 00:00:00'
    +FUTURE = 'Tue, 1-Dec-2999 23:59:59'
    +
    +try:
    +    # FIXME PY3
    +    from gluon.contrib.minify import minify
    +    have_minify = True
    +except ImportError:
    +    have_minify = False
    +
    +
    +regex_session_id = re.compile('^([\w\-]+/)?[\w\-\.]+$')
    +
    +__all__ = ['Request', 'Response', 'Session']
    +
    +current = threading.local()  # thread-local storage for request-scope globals
    +
    +css_template = ''
    +js_template = ''
    +coffee_template = ''
    +typescript_template = ''
    +less_template = ''
    +css_inline = ''
    +js_inline = ''
    +
    +template_mapping = {
    +    'css': css_template,
    +    'js': js_template,
    +    'coffee': coffee_template,
    +    'ts': typescript_template,
    +    'less': less_template,
    +    'css:inline': css_inline,
    +    'js:inline': js_inline
    +}
    +
    +
    +# IMPORTANT:
    +# this is required so that pickled dict(s) and class.__dict__
    +# are sorted and web2py can detect without ambiguity when a session changes
    +class SortingPickler(Pickler):
    +    def save_dict(self, obj):
    +        self.write(EMPTY_DICT if self.bin else MARK + DICT)
    +        self.memoize(obj)
    +        self._batch_setitems([(key, obj[key]) for key in sorted(obj)])
    +
    +if PY2:
    +    SortingPickler.dispatch = copy.copy(Pickler.dispatch)
    +    SortingPickler.dispatch[dict] = SortingPickler.save_dict
    +else:
    +    SortingPickler.dispatch_table = copyreg.dispatch_table.copy()
    +    SortingPickler.dispatch_table[dict] = SortingPickler.save_dict
    +
    +
    +def sorting_dumps(obj, protocol=None):
    +    file = StringIO()
    +    SortingPickler(file, protocol).dump(obj)
    +    return file.getvalue()
    +# END #####################################################################
    +
    +
    +def copystream_progress(request, chunk_size=10 ** 5):
    +    """
    +    Copies request.env.wsgi_input into request.body
    +    and stores progress upload status in cache_ram
    +    X-Progress-ID:length and X-Progress-ID:uploaded
    +    """
    +    env = request.env
    +    if not env.get('CONTENT_LENGTH', None):
    +        return StringIO()
    +    source = env['wsgi.input']
    +    try:
    +        size = int(env['CONTENT_LENGTH'])
    +    except ValueError:
    +        raise HTTP(400, "Invalid Content-Length header")
    +    try:  # Android requires this
    +        dest = tempfile.NamedTemporaryFile()
    +    except NotImplementedError:  # and GAE this
    +        dest = tempfile.TemporaryFile()
    +    if 'X-Progress-ID' not in request.get_vars:
    +        copystream(source, dest, size, chunk_size)
    +        return dest
    +    cache_key = 'X-Progress-ID:' + request.get_vars['X-Progress-ID']
    +    cache_ram = CacheInRam(request)  # same as cache.ram because meta_storage
    +    cache_ram(cache_key + ':length', lambda: size, 0)
    +    cache_ram(cache_key + ':uploaded', lambda: 0, 0)
    +    while size > 0:
    +        if size < chunk_size:
    +            data = source.read(size)
    +            cache_ram.increment(cache_key + ':uploaded', size)
    +        else:
    +            data = source.read(chunk_size)
    +            cache_ram.increment(cache_key + ':uploaded', chunk_size)
    +        length = len(data)
    +        if length > size:
    +            (data, length) = (data[:size], size)
    +        size -= length
    +        if length == 0:
    +            break
    +        dest.write(data)
    +        if length < chunk_size:
    +            break
    +    dest.seek(0)
    +    cache_ram(cache_key + ':length', None)
    +    cache_ram(cache_key + ':uploaded', None)
    +    return dest
    +
    +
    +class Request(Storage):
    +
    +    """
    +    Defines the request object and the default values of its members
    +
    +    - env: environment variables, by gluon.main.wsgibase()
    +    - cookies
    +    - get_vars
    +    - post_vars
    +    - vars
    +    - folder
    +    - application
    +    - function
    +    - method
    +    - args
    +    - extension
    +    - now: datetime.datetime.now()
    +    - utcnow : datetime.datetime.utcnow()
    +    - is_local
    +    - is_https
    +    - restful()
    +    """
    +
    +    def __init__(self, env):
    +        Storage.__init__(self)
    +        self.env = Storage(env)
    +        self.env.web2py_path = global_settings.applications_parent
    +        self.env.update(global_settings)
    +        self.cookies = Cookie.SimpleCookie()
    +        self.method = self.env.get('REQUEST_METHOD')
    +        self._get_vars = None
    +        self._post_vars = None
    +        self._vars = None
    +        self._body = None
    +        self.folder = None
    +        self.application = None
    +        self.function = None
    +        self.args = List()
    +        self.extension = 'html'
    +        self.now = datetime.datetime.now()
    +        self.utcnow = datetime.datetime.utcnow()
    +        self.is_restful = False
    +        self.is_https = False
    +        self.is_local = False
    +        self.global_settings = settings.global_settings
    +        self._uuid = None
    +
    +    def parse_get_vars(self):
    +        """Takes the QUERY_STRING and unpacks it to get_vars
    +        """
    +        query_string = self.env.get('query_string', '')
    +        dget = urlparse.parse_qs(query_string, keep_blank_values=1)
    +        # Ref: https://docs.python.org/2/library/cgi.html#cgi.parse_qs
    +        get_vars = self._get_vars = Storage(dget)
    +        for (key, value) in iteritems(get_vars):
    +            if isinstance(value, list) and len(value) == 1:
    +                get_vars[key] = value[0]
    +
    +    def parse_post_vars(self):
    +        """Takes the body of the request and unpacks it into
    +        post_vars. application/json is also automatically parsed
    +        """
    +        env = self.env
    +        post_vars = self._post_vars = Storage()
    +        body = self.body
    +        # if content-type is application/json, we must read the body
    +        is_json = env.get('content_type', '')[:16] == 'application/json'
    +
    +        if is_json:
    +            try:
    +                # In Python 3 versions prior to 3.6 load doesn't accept bytes and
    +                # bytearray, so we read the body convert to native and use loads
    +                # instead of load.
    +                # This line can be simplified to json_vars = json_parser.load(body)
    +                # if and when we drop support for python versions under 3.6
    +                json_vars = json_parser.loads(to_native(body.read()))
    +            except:
    +                # incoherent request bodies can still be parsed "ad-hoc"
    +                json_vars = {}
    +                pass
    +            # update vars and get_vars with what was posted as json
    +            if isinstance(json_vars, dict):
    +                post_vars.update(json_vars)
    +
    +            body.seek(0)
    +
    +        # parse POST variables on POST, PUT, BOTH only in post_vars
    +        if body and not is_json and env.request_method in ('POST', 'PUT', 'DELETE', 'BOTH'):
    +            query_string = env.pop('QUERY_STRING', None)
    +            dpost = cgi.FieldStorage(fp=body, environ=env, keep_blank_values=1)
    +            try:
    +                post_vars.update(dpost)
    +            except:
    +                pass
    +            if query_string is not None:
    +                env['QUERY_STRING'] = query_string
    +            # The same detection used by FieldStorage to detect multipart POSTs
    +            body.seek(0)
    +
    +            def listify(a):
    +                return (not isinstance(a, list) and [a]) or a
    +            try:
    +                keys = sorted(dpost)
    +            except TypeError:
    +                keys = []
    +            for key in keys:
    +                if key is None:
    +                    continue  # not sure why cgi.FieldStorage returns None key
    +                dpk = dpost[key]
    +                # if an element is not a file replace it with
    +                # its value else leave it alone
    +
    +                pvalue = listify([(_dpk if _dpk.filename else _dpk.value)
    +                                  for _dpk in dpk]
    +                                 if isinstance(dpk, list) else
    +                                 (dpk if dpk.filename else dpk.value))
    +                if len(pvalue):
    +                    post_vars[key] = (len(pvalue) > 1 and pvalue) or pvalue[0]
    +
    +    @property
    +    def body(self):
    +        if self._body is None:
    +            try:
    +                self._body = copystream_progress(self)
    +            except IOError:
    +                raise HTTP(400, "Bad Request - HTTP body is incomplete")
    +        return self._body
    +
    +    def parse_all_vars(self):
    +        """Merges get_vars and post_vars to vars
    +        """
    +        self._vars = copy.copy(self.get_vars)
    +        for key, value in iteritems(self.post_vars):
    +            if key not in self._vars:
    +                self._vars[key] = value
    +            else:
    +                if not isinstance(self._vars[key], list):
    +                    self._vars[key] = [self._vars[key]]
    +                self._vars[key] += value if isinstance(value, list) else [value]
    +
    +    @property
    +    def get_vars(self):
    +        """Lazily parses the query string into get_vars
    +        """
    +        if self._get_vars is None:
    +            self.parse_get_vars()
    +        return self._get_vars
    +
    +    @property
    +    def post_vars(self):
    +        """Lazily parse the body into post_vars
    +        """
    +        if self._post_vars is None:
    +            self.parse_post_vars()
    +        return self._post_vars
    +
    +    @property
    +    def vars(self):
    +        """Lazily parses all get_vars and post_vars to fill vars
    +        """
    +        if self._vars is None:
    +            self.parse_all_vars()
    +        return self._vars
    +
    +    @property
    +    def uuid(self):
    +        """Lazily uuid
    +        """
    +        if self._uuid is None:
    +            self.compute_uuid()
    +        return self._uuid
    +
    +    def compute_uuid(self):
    +        self._uuid = '%s/%s.%s.%s' % (
    +            self.application,
    +            self.client.replace(':', '_'),
    +            self.now.strftime('%Y-%m-%d.%H-%M-%S'),
    +            web2py_uuid())
    +        return self._uuid
    +
    +    def user_agent(self):
    +        from gluon.contrib import user_agent_parser
    +        session = current.session
    +        user_agent = session._user_agent
    +        if user_agent:
    +            return user_agent
    +        http_user_agent = self.env.http_user_agent or ''
    +        user_agent = user_agent_parser.detect(http_user_agent)
    +        for key, value in user_agent.items():
    +            if isinstance(value, dict):
    +                user_agent[key] = Storage(value)
    +        user_agent = Storage(user_agent)
    +        user_agent.is_mobile = 'Mobile' in http_user_agent
    +        user_agent.is_tablet = 'Tablet' in http_user_agent
    +        session._user_agent = user_agent
    +
    +        return user_agent
    +
    +    def requires_https(self):
    +        """
    +        If request comes in over HTTP, redirects it to HTTPS
    +        and secures the session.
    +        """
    +        cmd_opts = global_settings.cmd_options
    +        # checking if this is called within the scheduler or within the shell
    +        # in addition to checking if it's not a cronjob
    +        if ((cmd_opts and (cmd_opts.shell or cmd_opts.scheduler))
    +                or global_settings.cronjob or self.is_https):
    +            current.session.secure()
    +        else:
    +            current.session.forget()
    +            redirect(URL(scheme='https', args=self.args, vars=self.vars))
    +
    +    def restful(self, ignore_extension=False):
    +        def wrapper(action, request=self):
    +            def f(_action=action, *a, **b):
    +                request.is_restful = True
    +                env = request.env
    +                is_json = env.content_type == 'application/json'
    +                method = env.request_method
    +                if not ignore_extension and len(request.args) and '.' in request.args[-1]:
    +                    request.args[-1], _, request.extension = request.args[-1].rpartition('.')
    +                    current.response.headers['Content-Type'] = \
    +                        contenttype('.' + request.extension.lower())
    +                rest_action = _action().get(method, None)
    +                if not (rest_action and method == method.upper()
    +                        and callable(rest_action)):
    +                    raise HTTP(405, "method not allowed")
    +                try:
    +                    res = rest_action(*request.args, **request.vars)
    +                    if is_json and not isinstance(res, str):
    +                        res = json(res)
    +                    return res
    +                except TypeError as e:
    +                    exc_type, exc_value, exc_traceback = sys.exc_info()
    +                    if len(traceback.extract_tb(exc_traceback)) == 1:
    +                        raise HTTP(400, "invalid arguments")
    +                    else:
    +                        raise
    +            f.__doc__ = action.__doc__
    +            f.__name__ = action.__name__
    +            return f
    +        return wrapper
    +
    +
    +class Response(Storage):
    +
    +    """
    +    Defines the response object and the default values of its members
    +    response.write(   ) can be used to write in the output html
    +    """
    +
    +    def __init__(self):
    +        Storage.__init__(self)
    +        self.status = 200
    +        self.headers = dict()
    +        self.headers['X-Powered-By'] = 'web2py'
    +        self.body = StringIO()
    +        self.session_id = None
    +        self.cookies = Cookie.SimpleCookie()
    +        self.postprocessing = []
    +        self.flash = ''            # used by the default view layout
    +        self.meta = Storage()      # used by web2py_ajax.html
    +        self.menu = []             # used by the default view layout
    +        self.files = []            # used by web2py_ajax.html
    +        self._vars = None
    +        self._caller = lambda f: f()
    +        self._view_environment = None
    +        self._custom_commit = None
    +        self._custom_rollback = None
    +        self.generic_patterns = ['*']
    +        self.delimiters = ('{{', '}}')
    +        self.formstyle = 'table3cols'
    +        self.form_label_separator = ': '
    +
    +    def write(self, data, escape=True):
    +        if not escape:
    +            self.body.write(str(data))
    +        else:
    +            self.body.write(to_native(xmlescape(data)))
    +
    +    def render(self, *a, **b):
    +        from gluon.compileapp import run_view_in
    +        if len(a) > 2:
    +            raise SyntaxError(
    +                'Response.render can be called with two arguments, at most')
    +        elif len(a) == 2:
    +            (view, self._vars) = (a[0], a[1])
    +        elif len(a) == 1 and isinstance(a[0], str):
    +            (view, self._vars) = (a[0], {})
    +        elif len(a) == 1 and hasattr(a[0], 'read') and callable(a[0].read):
    +            (view, self._vars) = (a[0], {})
    +        elif len(a) == 1 and isinstance(a[0], dict):
    +            (view, self._vars) = (None, a[0])
    +        else:
    +            (view, self._vars) = (None, {})
    +        self._vars.update(b)
    +        self._view_environment.update(self._vars)
    +        if view:
    +            from gluon._compat import StringIO
    +            (obody, oview) = (self.body, self.view)
    +            (self.body, self.view) = (StringIO(), view)
    +            page = run_view_in(self._view_environment)
    +            self.body.close()
    +            (self.body, self.view) = (obody, oview)
    +        else:
    +            page = run_view_in(self._view_environment)
    +        return page
    +
    +    def include_meta(self):
    +        s = "\n"
    +        for meta in iteritems((self.meta or {})):
    +            k, v = meta
    +            if isinstance(v, dict):
    +                s += '\n'
    +            else:
    +                s += '\n' % (k, to_native(xmlescape(v)))
    +        self.write(s, escape=False)
    +
    +    def include_files(self, extensions=None):
    +        """
    +        Includes files (usually in the head).
    +        Can minify and cache local files
    +        By default, caches in ram for 5 minutes. To change,
    +        response.cache_includes = (cache_method, time_expire).
    +        Example: (cache.disk, 60) # caches to disk for 1 minute.
    +        """
    +        app = current.request.application
    +
    +        # We start by building a files list in which adjacent files internal to
    +        # the application are placed in a list inside the files list.
    +        #
    +        # We will only minify and concat adjacent internal files as there's
    +        # no way to know if changing the order with which the files are apppended
    +        # will break things since the order matters in both CSS and JS and
    +        # internal files may be interleaved with external ones.
    +        files = []
    +        # For the adjacent list we're going to use storage List to both distinguish
    +        # from the regular list and so we can add attributes
    +        internal = List()
    +        internal.has_js = False
    +        internal.has_css = False
    +        done = set() # to remove duplicates
    +        for item in self.files:
    +            if not isinstance(item, list):
    +                if item in done:
    +                    continue
    +                done.add(item)
    +            if isinstance(item, (list, tuple)) or not item.startswith('/' + app): # also consider items in other web2py applications to be external
    +                if internal:
    +                    files.append(internal)
    +                    internal = List()
    +                    internal.has_js = False
    +                    internal.has_css = False
    +                files.append(item)
    +                continue
    +            if extensions and not item.rpartition('.')[2] in extensions:
    +                continue
    +            internal.append(item)
    +            if item.endswith('.js'):
    +                internal.has_js = True
    +            if item.endswith('.css'):
    +                internal.has_css = True
    +        if internal:
    +            files.append(internal)
    +
    +        # We're done we can now minify
    +        if have_minify:
    +            for i, f in enumerate(files):
    +                if isinstance(f, List) and ((self.optimize_css and f.has_css) or (self.optimize_js and f.has_js)):
    +                    # cache for 5 minutes by default
    +                    key = hashlib_md5(repr(f)).hexdigest()
    +                    cache = self.cache_includes or (current.cache.ram, 60 * 5)
    +                    def call_minify(files=f):
    +                        return List(minify.minify(files,
    +                                             URL('static', 'temp'),
    +                                             current.request.folder,
    +                                             self.optimize_css,
    +                                             self.optimize_js))
    +                    if cache:
    +                        cache_model, time_expire = cache
    +                        files[i] = cache_model('response.files.minified/' + key,
    +                                            call_minify,
    +                                            time_expire)
    +                    else:
    +                        files[i] = call_minify()
    +
    +        def static_map(s, item):
    +            if isinstance(item, str):
    +                f = item.lower().split('?')[0]
    +                ext = f.rpartition('.')[2]
    +                # if static_version we need also to check for
    +                # static_version_urls. In that case, the _.x.x.x
    +                # bit would have already been added by the URL()
    +                # function
    +                if self.static_version and not self.static_version_urls:
    +                    item = item.replace(
    +                        '/static/', '/static/_%s/' % self.static_version, 1)
    +                tmpl = template_mapping.get(ext)
    +                if tmpl:
    +                    s.append(tmpl % item)
    +            elif isinstance(item, (list, tuple)):
    +                f = item[0]
    +                tmpl = template_mapping.get(f)
    +                if tmpl:
    +                    s.append(tmpl % item[1])
    +
    +        s = []
    +        for item in files:
    +            if isinstance(item, List):
    +                for f in item:
    +                    static_map(s, f)
    +            else:
    +                static_map(s, item)
    +        self.write(''.join(s), escape=False)
    +
    +    def stream(self,
    +               stream,
    +               chunk_size=DEFAULT_CHUNK_SIZE,
    +               request=None,
    +               attachment=False,
    +               filename=None
    +               ):
    +        """
    +        If in a controller function::
    +
    +            return response.stream(file, 100)
    +
    +        the file content will be streamed at 100 bytes at the time
    +
    +        Args:
    +            stream: filename or read()able content
    +            chunk_size(int): Buffer size
    +            request: the request object
    +            attachment(bool): prepares the correct headers to download the file
    +                as an attachment. Usually creates a pop-up download window
    +                on browsers
    +            filename(str): the name for the attachment
    +
    +        Note:
    +            for using the stream name (filename) with attachments
    +            the option must be explicitly set as function parameter (will
    +            default to the last request argument otherwise)
    +        """
    +
    +        headers = self.headers
    +        # for attachment settings and backward compatibility
    +        keys = [item.lower() for item in headers]
    +        if attachment:
    +            if filename is None:
    +                attname = ""
    +            else:
    +                attname = filename
    +            headers["Content-Disposition"] = \
    +                'attachment; filename="%s"' % attname
    +
    +        if not request:
    +            request = current.request
    +        if isinstance(stream, (str, unicodeT)):
    +            stream_file_or_304_or_206(stream,
    +                                      chunk_size=chunk_size,
    +                                      request=request,
    +                                      headers=headers,
    +                                      status=self.status)
    +
    +        # ## the following is for backward compatibility
    +        if hasattr(stream, 'name'):
    +            filename = stream.name
    +
    +        if filename and 'content-type' not in keys:
    +            headers['Content-Type'] = contenttype(filename)
    +        if filename and 'content-length' not in keys:
    +            try:
    +                headers['Content-Length'] = \
    +                    os.path.getsize(filename)
    +            except OSError:
    +                pass
    +
    +        env = request.env
    +        # Internet Explorer < 9.0 will not allow downloads over SSL unless caching is enabled
    +        if request.is_https and isinstance(env.http_user_agent, str) and \
    +                not re.search(r'Opera', env.http_user_agent) and \
    +                re.search(r'MSIE [5-8][^0-9]', env.http_user_agent):
    +            headers['Pragma'] = 'cache'
    +            headers['Cache-Control'] = 'private'
    +
    +        if request and env.web2py_use_wsgi_file_wrapper:
    +            wrapped = env.wsgi_file_wrapper(stream, chunk_size)
    +        else:
    +            wrapped = streamer(stream, chunk_size=chunk_size)
    +        return wrapped
    +
    +    def download(self, request, db, chunk_size=DEFAULT_CHUNK_SIZE, attachment=True, download_filename=None):
    +        """
    +        Example of usage in controller::
    +
    +            def download():
    +                return response.download(request, db)
    +
    +        Downloads from http://..../download/filename
    +        """
    +        from pydal.exceptions import NotAuthorizedException, NotFoundException
    +
    +        current.session.forget(current.response)
    +
    +        if not request.args:
    +            raise HTTP(404)
    +        name = request.args[-1]
    +        items = re.compile('(?P.*?)\.(?P.*?)\..*').match(name)
    +        if not items:
    +            raise HTTP(404)
    +        (t, f) = (items.group('table'), items.group('field'))
    +        try:
    +            field = db[t][f]
    +        except (AttributeError, KeyError):
    +            raise HTTP(404)
    +        try:
    +            (filename, stream) = field.retrieve(name, nameonly=True)
    +        except NotAuthorizedException:
    +            raise HTTP(403)
    +        except NotFoundException:
    +            raise HTTP(404)
    +        except IOError:
    +            raise HTTP(404)
    +        headers = self.headers
    +        headers['Content-Type'] = contenttype(name)
    +        if download_filename is None:
    +            download_filename = filename
    +        if attachment:
    +            # Browsers still don't have a simple uniform way to have non ascii
    +            # characters in the filename so for now we are percent encoding it
    +            if isinstance(download_filename, unicodeT):
    +                download_filename = download_filename.encode('utf-8')
    +            download_filename = urllib_quote(download_filename)
    +            headers['Content-Disposition'] = \
    +                'attachment; filename="%s"' % download_filename.replace('"', '\\"')
    +        return self.stream(stream, chunk_size=chunk_size, request=request)
    +
    +    def json(self, data, default=None, indent=None):
    +        if 'Content-Type' not in self.headers:
    +            self.headers['Content-Type'] = 'application/json'
    +        return json(data, default=default or custom_json, indent=indent)
    +
    +    def xmlrpc(self, request, methods):
    +        from gluon.xmlrpc import handler
    +        """
    +        assuming::
    +
    +            def add(a, b):
    +                return a+b
    +
    +        if a controller function \"func\"::
    +
    +            return response.xmlrpc(request, [add])
    +
    +        the controller will be able to handle xmlrpc requests for
    +        the add function. Example::
    +
    +            import xmlrpclib
    +            connection = xmlrpclib.ServerProxy(
    +                'http://hostname/app/contr/func')
    +            print(connection.add(3, 4))
    +
    +        """
    +
    +        return handler(request, self, methods)
    +
    +    def toolbar(self):
    +        from gluon.html import DIV, SCRIPT, BEAUTIFY, TAG, A
    +        BUTTON = TAG.button
    +        admin = URL("admin", "default", "design", extension='html',
    +                    args=current.request.application)
    +        from gluon.dal import DAL
    +        dbstats = []
    +        dbtables = {}
    +        infos = DAL.get_instances()
    +        for k, v in iteritems(infos):
    +            dbstats.append(TABLE(*[TR(PRE(row[0]), '%.2fms' % (row[1]*1000))
    +                                   for row in v['dbstats']]))
    +            dbtables[k] = dict(defined=v['dbtables']['defined'] or '[no defined tables]',
    +                               lazy=v['dbtables']['lazy'] or '[no lazy tables]')
    +        u = web2py_uuid()
    +        backtotop = A('Back to top', _href="#totop-%s" % u)
    +        # Convert lazy request.vars from property to Storage so they
    +        # will be displayed in the toolbar.
    +        request = copy.copy(current.request)
    +        request.update(vars=current.request.vars,
    +                       get_vars=current.request.get_vars,
    +                       post_vars=current.request.post_vars)
    +        return DIV(
    +            BUTTON('design', _onclick="document.location='%s'" % admin),
    +            BUTTON('request',
    +                   _onclick="jQuery('#request-%s').slideToggle()" % u),
    +            BUTTON('response',
    +                   _onclick="jQuery('#response-%s').slideToggle()" % u),
    +            BUTTON('session',
    +                   _onclick="jQuery('#session-%s').slideToggle()" % u),
    +            BUTTON('db tables',
    +                   _onclick="jQuery('#db-tables-%s').slideToggle()" % u),
    +            BUTTON('db stats',
    +                   _onclick="jQuery('#db-stats-%s').slideToggle()" % u),
    +            DIV(BEAUTIFY(request), backtotop,
    +                _class="w2p-toolbar-hidden", _id="request-%s" % u),
    +            DIV(BEAUTIFY(current.session), backtotop,
    +                _class="w2p-toolbar-hidden", _id="session-%s" % u),
    +            DIV(BEAUTIFY(current.response), backtotop,
    +                _class="w2p-toolbar-hidden", _id="response-%s" % u),
    +            DIV(BEAUTIFY(dbtables), backtotop,
    +                _class="w2p-toolbar-hidden", _id="db-tables-%s" % u),
    +            DIV(BEAUTIFY(dbstats), backtotop,
    +                _class="w2p-toolbar-hidden", _id="db-stats-%s" % u),
    +            SCRIPT("jQuery('.w2p-toolbar-hidden').hide()"),
    +            _id="totop-%s" % u
    +        )
    +
    +
    +class Session(Storage):
    +    """
    +    Defines the session object and the default values of its members (None)
    +
    +    - session_storage_type   : 'file', 'db', or 'cookie'
    +    - session_cookie_compression_level :
    +    - session_cookie_expires : cookie expiration
    +    - session_cookie_key     : for encrypted sessions in cookies
    +    - session_id             : a number or None if no session
    +    - session_id_name        :
    +    - session_locked         :
    +    - session_masterapp      :
    +    - session_new            : a new session obj is being created
    +    - session_hash           : hash of the pickled loaded session
    +    - session_pickled        : picked session
    +
    +    if session in cookie:
    +
    +    - session_data_name      : name of the cookie for session data
    +
    +    if session in db:
    +
    +    - session_db_record_id
    +    - session_db_table
    +    - session_db_unique_key
    +
    +    if session in file:
    +
    +    - session_file
    +    - session_filename
    +    """
    +
    +    def connect(self,
    +                request=None,
    +                response=None,
    +                db=None,
    +                tablename='web2py_session',
    +                masterapp=None,
    +                migrate=True,
    +                separate=None,
    +                check_client=False,
    +                cookie_key=None,
    +                cookie_expires=None,
    +                compression_level=None
    +                ):
    +        """
    +        Used in models, allows to customize Session handling
    +
    +        Args:
    +            request: the request object
    +            response: the response object
    +            db: to store/retrieve sessions in db (a table is created)
    +            tablename(str): table name
    +            masterapp(str): points to another's app sessions. This enables a
    +                "SSO" environment among apps
    +            migrate: passed to the underlying db
    +            separate: with True, creates a folder with the 2 initials of the
    +                session id. Can also be a function, e.g. ::
    +
    +                    separate=lambda(session_name): session_name[-2:]
    +
    +            check_client: if True, sessions can only come from the same ip
    +            cookie_key(str): secret for cookie encryption
    +            cookie_expires: sets the expiration of the cookie
    +            compression_level(int): 0-9, sets zlib compression on the data
    +                before the encryption
    +        """
    +        from gluon.dal import Field
    +        request = request or current.request
    +        response = response or current.response
    +        masterapp = masterapp or request.application
    +        cookies = request.cookies
    +
    +        self._unlock(response)
    +
    +        response.session_masterapp = masterapp
    +        response.session_id_name = 'session_id_%s' % masterapp.lower()
    +        response.session_data_name = 'session_data_%s' % masterapp.lower()
    +        response.session_cookie_expires = cookie_expires
    +        response.session_client = str(request.client).replace(':', '.')
    +        current._session_cookie_key = cookie_key
    +        response.session_cookie_compression_level = compression_level
    +
    +        # check if there is a session_id in cookies
    +        try:
    +            old_session_id = cookies[response.session_id_name].value
    +        except KeyError:
    +            old_session_id = None
    +        response.session_id = old_session_id
    +
    +        # if we are supposed to use cookie based session data
    +        if cookie_key:
    +            response.session_storage_type = 'cookie'
    +        elif db:
    +            response.session_storage_type = 'db'
    +        else:
    +            response.session_storage_type = 'file'
    +            # why do we do this?
    +            # because connect may be called twice, by web2py and in models.
    +            # the first time there is no db yet so it should do nothing
    +            if (global_settings.db_sessions is True
    +                    or masterapp in global_settings.db_sessions):
    +                return
    +
    +        if response.session_storage_type == 'cookie':
    +            # check if there is session data in cookies
    +            if response.session_data_name in cookies:
    +                session_cookie_data = cookies[response.session_data_name].value
    +            else:
    +                session_cookie_data = None
    +            if session_cookie_data:
    +                data = secure_loads(session_cookie_data, cookie_key,
    +                                    compression_level=compression_level)
    +                if data:
    +                    self.update(data)
    +            response.session_id = True
    +
    +        # else if we are supposed to use file based sessions
    +        elif response.session_storage_type == 'file':
    +            response.session_new = False
    +            response.session_file = None
    +            # check if the session_id points to a valid sesion filename
    +            if response.session_id:
    +                if not regex_session_id.match(response.session_id):
    +                    response.session_id = None
    +                else:
    +                    response.session_filename = \
    +                        os.path.join(up(request.folder), masterapp,
    +                                     'sessions', response.session_id)
    +                    try:
    +                        response.session_file = \
    +                            recfile.open(response.session_filename, 'rb+')
    +                        portalocker.lock(response.session_file,
    +                                         portalocker.LOCK_EX)
    +                        response.session_locked = True
    +                        self.update(pickle.load(response.session_file))
    +                        response.session_file.seek(0)
    +                        oc = response.session_filename.split('/')[-1].split('-')[0]
    +                        if check_client and response.session_client != oc:
    +                            raise Exception("cookie attack")
    +                    except:
    +                        response.session_id = None
    +            if not response.session_id:
    +                uuid = web2py_uuid()
    +                response.session_id = '%s-%s' % (response.session_client, uuid)
    +                separate = separate and (lambda session_name: session_name[-2:])
    +                if separate:
    +                    prefix = separate(response.session_id)
    +                    response.session_id = '%s/%s' % (prefix, response.session_id)
    +                response.session_filename = \
    +                    os.path.join(up(request.folder), masterapp,
    +                                 'sessions', response.session_id)
    +                response.session_new = True
    +
    +        # else the session goes in db
    +        elif response.session_storage_type == 'db':
    +            if global_settings.db_sessions is not True:
    +                global_settings.db_sessions.add(masterapp)
    +            # if had a session on file alreday, close it (yes, can happen)
    +            if response.session_file:
    +                self._close(response)
    +            # if on GAE tickets go also in DB
    +            if settings.global_settings.web2py_runtime_gae:
    +                request.tickets_db = db
    +            if masterapp == request.application:
    +                table_migrate = migrate
    +            else:
    +                table_migrate = False
    +            tname = tablename + '_' + masterapp
    +            table = db.get(tname, None)
    +            # Field = db.Field
    +            if table is None:
    +                db.define_table(
    +                    tname,
    +                    Field('locked', 'boolean', default=False),
    +                    Field('client_ip', length=64),
    +                    Field('created_datetime', 'datetime',
    +                          default=request.now),
    +                    Field('modified_datetime', 'datetime'),
    +                    Field('unique_key', length=64),
    +                    Field('session_data', 'blob'),
    +                    migrate=table_migrate,
    +                )
    +                table = db[tname]  # to allow for lazy table
    +            response.session_db_table = table
    +            if response.session_id:
    +                # Get session data out of the database
    +                try:
    +                    (record_id, unique_key) = response.session_id.split(':')
    +                    record_id = long(record_id)
    +                except (TypeError, ValueError):
    +                    record_id = None
    +
    +                # Select from database
    +                if record_id:
    +                    row = table(record_id, unique_key=unique_key)
    +                    # Make sure the session data exists in the database
    +                    if row:
    +                        # rows[0].update_record(locked=True)
    +                        # Unpickle the data
    +                        session_data = pickle.loads(row[b'session_data'])
    +                        self.update(session_data)
    +                        response.session_new = False
    +                    else:
    +                        record_id = None
    +                if record_id:
    +                    response.session_id = '%s:%s' % (record_id, unique_key)
    +                    response.session_db_unique_key = unique_key
    +                    response.session_db_record_id = record_id
    +                else:
    +                    response.session_id = None
    +                    response.session_new = True
    +            # if there is no session id yet, we'll need to create a
    +            # new session
    +            else:
    +                response.session_new = True
    +
    +        # set the cookie now if you know the session_id so user can set
    +        # cookie attributes in controllers/models
    +        # cookie will be reset later
    +        # yet cookie may be reset later
    +        #   Removed comparison between old and new session ids - should send
    +        #    the cookie all the time
    +        if isinstance(response.session_id, str):
    +            response.cookies[response.session_id_name] = response.session_id
    +            response.cookies[response.session_id_name]['path'] = '/'
    +            if cookie_expires:
    +                response.cookies[response.session_id_name]['expires'] = \
    +                    cookie_expires.strftime(FMT)
    +
    +        session_pickled = pickle.dumps(self, pickle.HIGHEST_PROTOCOL)
    +        response.session_hash = hashlib.md5(session_pickled).hexdigest()
    +
    +        if self.flash:
    +            (response.flash, self.flash) = (self.flash, None)
    +
    +    def renew(self, clear_session=False):
    +
    +        if clear_session:
    +            self.clear()
    +
    +        request = current.request
    +        response = current.response
    +        session = response.session
    +        masterapp = response.session_masterapp
    +        cookies = request.cookies
    +
    +        if response.session_storage_type == 'cookie':
    +            return
    +
    +        # if the session goes in file
    +        if response.session_storage_type == 'file':
    +            self._close(response)
    +            uuid = web2py_uuid()
    +            response.session_id = '%s-%s' % (response.session_client, uuid)
    +            separate = (lambda s: s[-2:]) if session and response.session_id[2:3] == "/" else None
    +            if separate:
    +                prefix = separate(response.session_id)
    +                response.session_id = '%s/%s' % \
    +                    (prefix, response.session_id)
    +            response.session_filename = \
    +                os.path.join(up(request.folder), masterapp,
    +                             'sessions', response.session_id)
    +            response.session_new = True
    +
    +        # else the session goes in db
    +        elif response.session_storage_type == 'db':
    +            table = response.session_db_table
    +
    +            # verify that session_id exists
    +            if response.session_file:
    +                self._close(response)
    +            if response.session_new:
    +                return
    +            # Get session data out of the database
    +            if response.session_id is None:
    +                return
    +            (record_id, sep, unique_key) = response.session_id.partition(':')
    +
    +            if record_id.isdigit() and long(record_id) > 0:
    +                new_unique_key = web2py_uuid()
    +                row = table(record_id)
    +                if row and row[b'unique_key'] == to_bytes(unique_key):
    +                    table._db(table.id == record_id).update(unique_key=new_unique_key)
    +                else:
    +                    record_id = None
    +            if record_id:
    +                response.session_id = '%s:%s' % (record_id, new_unique_key)
    +                response.session_db_record_id = record_id
    +                response.session_db_unique_key = new_unique_key
    +            else:
    +                response.session_new = True
    +
    +    def _fixup_before_save(self):
    +        response = current.response
    +        rcookies = response.cookies
    +        scookies = rcookies.get(response.session_id_name)
    +        if not scookies:
    +            return
    +        if self._forget:
    +            del rcookies[response.session_id_name]
    +            return
    +        if self.get('httponly_cookies', True):
    +            scookies['HttpOnly'] = True
    +        if self._secure:
    +            scookies['secure'] = True
    +
    +    def clear_session_cookies(self):
    +        request = current.request
    +        response = current.response
    +        session = response.session
    +        masterapp = response.session_masterapp
    +        cookies = request.cookies
    +        rcookies = response.cookies
    +        # if not cookie_key, but session_data_name in cookies
    +        # expire session_data_name from cookies
    +        if response.session_data_name in cookies:
    +            rcookies[response.session_data_name] = 'expired'
    +            rcookies[response.session_data_name]['path'] = '/'
    +            rcookies[response.session_data_name]['expires'] = PAST
    +        if response.session_id_name in rcookies:
    +            del rcookies[response.session_id_name]
    +
    +    def save_session_id_cookie(self):
    +        request = current.request
    +        response = current.response
    +        session = response.session
    +        masterapp = response.session_masterapp
    +        cookies = request.cookies
    +        rcookies = response.cookies
    +
    +        # if not cookie_key, but session_data_name in cookies
    +        # expire session_data_name from cookies
    +        if not current._session_cookie_key:
    +            if response.session_data_name in cookies:
    +                rcookies[response.session_data_name] = 'expired'
    +                rcookies[response.session_data_name]['path'] = '/'
    +                rcookies[response.session_data_name]['expires'] = PAST
    +        if response.session_id:
    +            rcookies[response.session_id_name] = response.session_id
    +            rcookies[response.session_id_name]['path'] = '/'
    +            expires = response.session_cookie_expires
    +            if isinstance(expires, datetime.datetime):
    +                expires = expires.strftime(FMT)
    +            if expires:
    +                rcookies[response.session_id_name]['expires'] = expires
    +
    +    def clear(self):
    +        # see https://github.com/web2py/web2py/issues/735
    +        response = current.response
    +        if response.session_storage_type == 'file':
    +            target = recfile.generate(response.session_filename)
    +            try:
    +                self._close(response)
    +                os.unlink(target)
    +            except:
    +                pass
    +        elif response.session_storage_type == 'db':
    +            table = response.session_db_table
    +            if response.session_id:
    +                (record_id, sep, unique_key) = response.session_id.partition(':')
    +                if record_id.isdigit() and long(record_id) > 0:
    +                    table._db(table.id == record_id).delete()
    +        Storage.clear(self)
    +
    +    def is_new(self):
    +        if self._start_timestamp:
    +            return False
    +        else:
    +            self._start_timestamp = datetime.datetime.today()
    +            return True
    +
    +    def is_expired(self, seconds=3600):
    +        now = datetime.datetime.today()
    +        if not self._last_timestamp or \
    +                self._last_timestamp + datetime.timedelta(seconds=seconds) > now:
    +            self._last_timestamp = now
    +            return False
    +        else:
    +            return True
    +
    +    def secure(self):
    +        self._secure = True
    +
    +    def forget(self, response=None):
    +        self._close(response)
    +        self._forget = True
    +
    +    def _try_store_in_cookie(self, request, response):
    +        if self._forget or self._unchanged(response):
    +            # self.clear_session_cookies()
    +            self.save_session_id_cookie()
    +            return False
    +        name = response.session_data_name
    +        compression_level = response.session_cookie_compression_level
    +        value = secure_dumps(dict(self),
    +                             current._session_cookie_key,
    +                             compression_level=compression_level)
    +        rcookies = response.cookies
    +        rcookies.pop(name, None)
    +        rcookies[name] = to_native(value)
    +        rcookies[name]['path'] = '/'
    +        expires = response.session_cookie_expires
    +        if isinstance(expires, datetime.datetime):
    +            expires = expires.strftime(FMT)
    +        if expires:
    +            rcookies[name]['expires'] = expires
    +        return True
    +
    +    def _unchanged(self, response):
    +        if response.session_new:
    +            internal = ['_last_timestamp', '_secure', '_start_timestamp']
    +            for item in self.keys():
    +                if item not in internal:
    +                    return False
    +            return True
    +        session_pickled = pickle.dumps(self, pickle.HIGHEST_PROTOCOL)
    +        response.session_pickled = session_pickled
    +        session_hash = hashlib.md5(session_pickled).hexdigest()
    +        return response.session_hash == session_hash
    +
    +    def _try_store_in_db(self, request, response):
    +        # don't save if file-based sessions,
    +        # no session id, or session being forgotten
    +        # or no changes to session (Unless the session is new)
    +        if (not response.session_db_table
    +                or self._forget
    +                or (self._unchanged(response) and not response.session_new)):
    +            if (not response.session_db_table
    +                    and global_settings.db_sessions is not True
    +                    and response.session_masterapp in global_settings.db_sessions):
    +                global_settings.db_sessions.remove(response.session_masterapp)
    +            # self.clear_session_cookies()
    +            self.save_session_id_cookie()
    +            return False
    +
    +        table = response.session_db_table
    +        record_id = response.session_db_record_id
    +        if response.session_new:
    +            unique_key = web2py_uuid()
    +        else:
    +            unique_key = response.session_db_unique_key
    +
    +        session_pickled = response.session_pickled or pickle.dumps(self, pickle.HIGHEST_PROTOCOL)
    +
    +        dd = dict(locked=False,
    +                  client_ip=response.session_client,
    +                  modified_datetime=request.now,
    +                  session_data=session_pickled,
    +                  unique_key=unique_key)
    +        if record_id:
    +            if not table._db(table.id == record_id).update(**dd):
    +                record_id = None
    +        if not record_id:
    +            record_id = table.insert(**dd)
    +            response.session_id = '%s:%s' % (record_id, unique_key)
    +            response.session_db_unique_key = unique_key
    +            response.session_db_record_id = record_id
    +
    +        self.save_session_id_cookie()
    +        return True
    +
    +    def _try_store_in_cookie_or_file(self, request, response):
    +        if response.session_storage_type == 'file':
    +            return self._try_store_in_file(request, response)
    +        if response.session_storage_type == 'cookie':
    +            return self._try_store_in_cookie(request, response)
    +
    +    def _try_store_in_file(self, request, response):
    +        try:
    +            if (not response.session_id or
    +                not response.session_filename or
    +                self._forget
    +                    or self._unchanged(response)):
    +                # self.clear_session_cookies()
    +                return False
    +            else:
    +                if response.session_new or not response.session_file:
    +                    # Tests if the session sub-folder exists, if not, create it
    +                    session_folder = os.path.dirname(response.session_filename)
    +                    if not os.path.exists(session_folder):
    +                        os.mkdir(session_folder)
    +                    response.session_file = recfile.open(response.session_filename, 'wb')
    +                    portalocker.lock(response.session_file, portalocker.LOCK_EX)
    +                    response.session_locked = True
    +                if response.session_file:
    +                    session_pickled = response.session_pickled or pickle.dumps(self, pickle.HIGHEST_PROTOCOL)
    +                    response.session_file.write(session_pickled)
    +                    response.session_file.truncate()
    +                return True
    +        finally:
    +            self._close(response)
    +            self.save_session_id_cookie()
    +
    +    def _unlock(self, response):
    +        if response and response.session_file and response.session_locked:
    +            try:
    +                portalocker.unlock(response.session_file)
    +                response.session_locked = False
    +            except:  # this should never happen but happens in Windows
    +                pass
    +
    +    def _close(self, response):
    +        if response and response.session_file:
    +            self._unlock(response)
    +            try:
    +                response.session_file.close()
    +                del response.session_file
    +            except:
    +                pass
    +
    +
    +def pickle_session(s):
    +    return Session, (dict(s),)
    +
    +copyreg.pickle(Session, pickle_session)
    diff --git a/web2py/gluon/highlight.py b/web2py/gluon/highlight.py
    new file mode 100644
    index 0000000..b8cae77
    --- /dev/null
    +++ b/web2py/gluon/highlight.py
    @@ -0,0 +1,342 @@
    +#!/usr/bin/env python
    +# -*- coding: utf-8 -*-
    +
    +"""
    +| This file is part of the web2py Web Framework
    +| Copyrighted by Massimo Di Pierro 
    +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
    +"""
    +from __future__ import print_function
    +from gluon._compat import xrange
    +from gluon.utils import local_html_escape
    +import re
    +
    +__all__ = ['highlight']
    +
    +
    +class Highlighter(object):
    +
    +    """Does syntax highlighting.
    +    """
    +
    +    def __init__(
    +        self,
    +        mode,
    +        link=None,
    +        styles=None,
    +    ):
    +        """
    +        Initialize highlighter:
    +            mode = language (PYTHON, WEB2PY, C, CPP, HTML, HTML_PLAIN)
    +        """
    +        styles = styles or {}
    +        mode = mode.upper()
    +        if link and link[-1] != '/':
    +            link = link + '/'
    +        self.link = link
    +        self.styles = styles
    +        self.output = []
    +        self.span_style = None
    +        if mode == 'WEB2PY':
    +            (mode, self.suppress_tokens) = ('PYTHON', [])
    +        elif mode == 'PYTHON':
    +            self.suppress_tokens = ['GOTOHTML']
    +        elif mode == 'CPP':
    +            (mode, self.suppress_tokens) = ('C', [])
    +        elif mode == 'C':
    +            self.suppress_tokens = ['CPPKEYWORD']
    +        elif mode == 'HTML_PLAIN':
    +            (mode, self.suppress_tokens) = ('HTML', ['GOTOPYTHON'])
    +        elif mode == 'HTML':
    +            self.suppress_tokens = []
    +        else:
    +            raise SyntaxError('Unknown mode: %s' % mode)
    +        self.mode = mode
    +
    +    def c_tokenizer(
    +        self,
    +        token,
    +        match,
    +        style,
    +    ):
    +        """
    +        Callback for C specific highlighting.
    +        """
    +
    +        value = local_html_escape(match.group(), quote=False)
    +        self.change_style(token, style)
    +        self.output.append(value)
    +
    +    def python_tokenizer(
    +        self,
    +        token,
    +        match,
    +        style,
    +    ):
    +        """
    +        Callback for python specific highlighting.
    +        """
    +
    +        value = local_html_escape(match.group(), quote=False)
    +        if token == 'MULTILINESTRING':
    +            self.change_style(token, style)
    +            self.output.append(value)
    +            self.strMultilineString = match.group(1)
    +            return 'PYTHONMultilineString'
    +        elif token == 'ENDMULTILINESTRING':
    +            if match.group(1) == self.strMultilineString:
    +                self.output.append(value)
    +                self.strMultilineString = ''
    +                return 'PYTHON'
    +        if style and style[:5] == 'link:':
    +            self.change_style(None, None)
    +            (url, style) = style[5:].split(';', 1)
    +            if url == 'None' or url == '':
    +                self.output.append('%s'
    +                                   % (style, value))
    +            else:
    +                self.output.append('%s'
    +                                   % (url, value, style, value))
    +        else:
    +            self.change_style(token, style)
    +            self.output.append(value)
    +        if token == 'GOTOHTML':
    +            return 'HTML'
    +        return None
    +
    +    def html_tokenizer(
    +        self,
    +        token,
    +        match,
    +        style,
    +    ):
    +        """
    +        Callback for HTML specific highlighting.
    +        """
    +
    +        value = local_html_escape(match.group(), quote=False)
    +        self.change_style(token, style)
    +        self.output.append(value)
    +        if token == 'GOTOPYTHON':
    +            return 'PYTHON'
    +        return None
    +
    +    all_styles = {
    +        'C': (c_tokenizer, (
    +            ('COMMENT', re.compile(r'//.*\r?\n'),
    +             'color: green; font-style: italic'),
    +            ('MULTILINECOMMENT', re.compile(r'/\*.*?\*/', re.DOTALL),
    +             'color: green; font-style: italic'),
    +            ('PREPROCESSOR', re.compile(r'\s*#.*?[^\\]\s*\n',
    +             re.DOTALL), 'color: magenta; font-style: italic'),
    +            ('PUNC', re.compile(r'[-+*!&|^~/%\=<>\[\]{}(),.:]'),
    +             'font-weight: bold'),
    +            ('NUMBER',
    +             re.compile(r'0x[0-9a-fA-F]+|[+-]?\d+(\.\d+)?([eE][+-]\d+)?|\d+'),
    +             'color: red'),
    +            ('KEYWORD', re.compile(r'(sizeof|int|long|short|char|void|'
    +                                   + r'signed|unsigned|float|double|'
    +                                   + r'goto|break|return|continue|asm|'
    +                                   + r'case|default|if|else|switch|while|for|do|'
    +                                   + r'struct|union|enum|typedef|'
    +                                   + r'static|register|auto|volatile|extern|const)(?![a-zA-Z0-9_])'),
    +             'color:#185369; font-weight: bold'),
    +            ('CPPKEYWORD',
    +             re.compile(r'(class|private|protected|public|template|new|delete|'
    +                        + r'this|friend|using|inline|export|bool|throw|try|catch|'
    +                        + r'operator|typeid|virtual)(?![a-zA-Z0-9_])'),
    +             'color: blue; font-weight: bold'),
    +            ('STRING', re.compile(r'r?u?\'(.*?)(?\[\]{}(),.:]'),
    +             'font-weight: bold'),
    +            ('NUMBER',
    +             re.compile(r'0x[0-9a-fA-F]+|[+-]?\d+(\.\d+)?([eE][+-]\d+)?|\d+'
    +                        ), 'color: red'),
    +            ('KEYWORD',
    +             re.compile(r'(def|class|break|continue|del|exec|finally|pass|'
    +                        + r'print|raise|return|try|except|global|assert|lambda|'
    +                        + r'yield|for|while|if|elif|else|and|in|is|not|or|import|'
    +                        + r'from|True|False)(?![a-zA-Z0-9_])'),
    +             'color:#185369; font-weight: bold'),
    +            ('WEB2PY',
    +             re.compile(r'(request|response|session|cache|redirect|local_import|HTTP|TR|XML|URL|BEAUTIFY|A|BODY|BR|B|CAT|CENTER|CODE|COL|COLGROUP|DIV|EM|EMBED|FIELDSET|LEGEND|FORM|H1|H2|H3|H4|H5|H6|IFRAME|HEAD|HR|HTML|I|IMG|INPUT|LABEL|LI|LINK|MARKMIN|MENU|META|OBJECT|OL|ON|OPTION|P|PRE|SCRIPT|SELECT|SPAN|STYLE|TABLE|THEAD|TBODY|TFOOT|TAG|TD|TEXTAREA|TH|TITLE|TT|T|UL|XHTML|IS_SLUG|IS_STRONG|IS_LOWER|IS_UPPER|IS_ALPHANUMERIC|IS_DATETIME|IS_DATETIME_IN_RANGE|IS_DATE|IS_DATE_IN_RANGE|IS_DECIMAL_IN_RANGE|IS_EMAIL|IS_EXPR|IS_FLOAT_IN_RANGE|IS_IMAGE|IS_INT_IN_RANGE|IS_IN_SET|IS_IPV4|IS_LIST_OF|IS_LENGTH|IS_MATCH|IS_EQUAL_TO|IS_EMPTY_OR|IS_NULL_OR|IS_NOT_EMPTY|IS_TIME|IS_UPLOAD_FILENAME|IS_URL|CLEANUP|CRYPT|IS_IN_DB|IS_NOT_IN_DB|DAL|Field|SQLFORM|SQLTABLE|xmlescape|embed64)(?![a-zA-Z0-9_])'
    +                        ), 'link:%(link)s;text-decoration:None;color:#FF5C1F;'),
    +            ('MAGIC', re.compile(r'self|None'),
    +             'color:#185369; font-weight: bold'),
    +            ('MULTILINESTRING', re.compile(r'r?u?(\'\'\'|""")'),
    +             'color: #FF9966'),
    +            ('STRING', re.compile(r'r?u?\'(.*?)(?]*-->|'),
    +             'color: green; font-style: italic'),
    +            ('XMLCRAP', re.compile(r']*>'),
    +             'color: blue; font-style: italic'),
    +            ('SCRIPT', re.compile(r'
    +            # return '<%s%s>' % (self.tag, fa, co, self.tag)
    +            return b'<%s%s>' % (self.tagname, fa, co, self.tagname)
    +        else:
    +            return DIV.xml(self)
    +
    +
    +class STYLE(DIV):
    +
    +    tag = 'style'
    +    tagname = to_bytes(tag)
    +
    +    def xml(self):
    +        (fa, co) = self._xml()
    +        fa = to_bytes(fa)
    +        # no escaping of subcomponents
    +        co = b'\n'.join([to_bytes(component) for component in
    +                       self.components])
    +        if co:
    +            # 
    +            return b'<%s%s>' % (self.tagname, fa, co, self.tagname)
    +        else:
    +            return DIV.xml(self)
    +
    +
    +class IMG(DIV):
    +
    +    tag = 'img/'
    +
    +
    +class SPAN(DIV):
    +
    +    tag = 'span'
    +
    +
    +class BODY(DIV):
    +
    +    tag = 'body'
    +
    +
    +class H1(DIV):
    +
    +    tag = 'h1'
    +
    +
    +class H2(DIV):
    +
    +    tag = 'h2'
    +
    +
    +class H3(DIV):
    +
    +    tag = 'h3'
    +
    +
    +class H4(DIV):
    +
    +    tag = 'h4'
    +
    +
    +class H5(DIV):
    +
    +    tag = 'h5'
    +
    +
    +class H6(DIV):
    +
    +    tag = 'h6'
    +
    +
    +class P(DIV):
    +    """
    +    Will replace ``\\n`` by ``
    `` if the `cr2br` attribute is provided. + + see also `DIV` + """ + + tag = 'p' + + def xml(self): + text = DIV.xml(self) + if self['cr2br']: + text = text.replace(b'\n', b'
    ') + return text + + +class STRONG(DIV): + + tag = 'strong' + + +class B(DIV): + + tag = 'b' + + +class BR(DIV): + + tag = 'br/' + + +class HR(DIV): + + tag = 'hr/' + + +class A(DIV): + """ + Generates an A() link. + A() in web2py is really important and with the included web2py.js + allows lots of Ajax interactions in the page + + On top of "usual" `_attributes`, it takes + + Args: + callback: an url to call but not redirect to + cid: if you want to load the _href into an element of the page (component) + pass its id (without the #) here + delete: element to delete after calling callback + target: same thing as cid + confirm: text to display upon a callback with a delete + noconfirm: don't display alert upon a callback with delete + + """ + + tag = 'a' + + def xml(self): + if not self.components and self['_href']: + self.append(self['_href']) + disable_needed = ['callback', 'cid', 'delete', 'component', 'target'] + disable_needed = any((self[attr] for attr in disable_needed)) + if disable_needed: + self['_data-w2p_disable_with'] = self['_disable_with'] or 'default' + self['_disable_with'] = None + if self['callback'] and not self['_id']: + self['_id'] = web2py_uuid() + if self['delete']: + self['_data-w2p_remove'] = self['delete'] + if self['target']: + if self['target'] == '': + self['target'] = self['_id'] + self['_data-w2p_target'] = self['target'] + if self['component']: + self['_data-w2p_method'] = 'GET' + self['_href'] = self['component'] + elif self['callback']: + self['_data-w2p_method'] = 'POST' + self['_href'] = self['callback'] + if self['delete'] and not self['noconfirm']: + if not self['confirm']: + self['_data-w2p_confirm'] = 'default' + else: + self['_data-w2p_confirm'] = self['confirm'] + elif self['cid']: + self['_data-w2p_method'] = 'GET' + self['_data-w2p_target'] = self['cid'] + if self['pre_call']: + self['_data-w2p_pre_call'] = self['pre_call'] + return DIV.xml(self) + + +class BUTTON(DIV): + + tag = 'button' + + +class EM(DIV): + + tag = 'em' + + +class EMBED(DIV): + + tag = 'embed/' + + +class TT(DIV): + + tag = 'tt' + + +class PRE(DIV): + + tag = 'pre' + + +class CENTER(DIV): + + tag = 'center' + + +class CODE(DIV): + + """ + Displays code in HTML with syntax highlighting. + + Args: + language: indicates the language, otherwise PYTHON is assumed + link: can provide a link + styles: for styles + + Examples: + + {{=CODE(\"print('hello world')\", language='python', link=None, + counter=1, styles={}, highlight_line=None)}} + + + supported languages are + + "python", "html_plain", "c", "cpp", "web2py", "html" + + The "html" language interprets {{ and }} tags as "web2py" code, + "html_plain" doesn't. + + if a link='/examples/global/vars/' is provided web2py keywords are linked to + the online docs. + + the counter is used for line numbering, counter can be None or a prompt + string. + """ + + def xml(self): + language = self['language'] or 'PYTHON' + link = self['link'] + counter = self.attributes.get('counter', 1) + highlight_line = self.attributes.get('highlight_line', None) + context_lines = self.attributes.get('context_lines', None) + styles = self['styles'] or {} + return highlight( + join(self.components), + language=language, + link=link, + counter=counter, + styles=styles, + attributes=self.attributes, + highlight_line=highlight_line, + context_lines=context_lines, + ) + + +class LABEL(DIV): + + tag = 'label' + + +class LI(DIV): + + tag = 'li' + + +class UL(DIV): + """ + UL Component. + + If subcomponents are not LI-components they will be wrapped in a LI + + """ + + tag = 'ul' + + def _fixup(self): + self._wrap_components(LI, LI) + + +class OL(UL): + + tag = 'ol' + + +class TD(DIV): + + tag = 'td' + + +class TH(DIV): + + tag = 'th' + + +class TR(DIV): + """ + TR Component. + + If subcomponents are not TD/TH-components they will be wrapped in a TD + + """ + + tag = 'tr' + + def _fixup(self): + self._wrap_components((TD, TH), TD) + + +class __TRHEAD__(DIV): + """ + __TRHEAD__ Component, internal only + + If subcomponents are not TD/TH-components they will be wrapped in a TH + + """ + + tag = 'tr' + + def _fixup(self): + self._wrap_components((TD, TH), TH) + + +class THEAD(DIV): + + tag = 'thead' + + def _fixup(self): + self._wrap_components((__TRHEAD__, TR), __TRHEAD__) + + +class TBODY(DIV): + + tag = 'tbody' + + def _fixup(self): + self._wrap_components(TR, TR) + + +class TFOOT(DIV): + + tag = 'tfoot' + + def _fixup(self): + self._wrap_components(TR, TR) + + +class COL(DIV): + + tag = 'col/' + + +class COLGROUP(DIV): + + tag = 'colgroup' + + +class TABLE(DIV): + """ + TABLE Component. + + If subcomponents are not TR/TBODY/THEAD/TFOOT-components + they will be wrapped in a TR + + """ + + tag = 'table' + + def _fixup(self): + self._wrap_components((TR, TBODY, THEAD, TFOOT, COL, COLGROUP), TR) + + +class I(DIV): + + tag = 'i' + + +class IFRAME(DIV): + + tag = 'iframe' + + +class INPUT(DIV): + + """ + INPUT Component + + Takes two special attributes value= and requires=. + + Args: + value: used to pass the initial value for the input field. + value differs from _value because it works for checkboxes, radio, + textarea and select/option too. + For a checkbox value should be '' or 'on'. + For a radio or select/option value should be the _value + of the checked/selected item. + + requires: should be None, or a validator or a list of validators + for the value of the field. + + Examples: + + >>> INPUT(_type='text', _name='name', value='Max').xml() + '' + + >>> INPUT(_type='checkbox', _name='checkbox', value='on').xml() + '' + + >>> INPUT(_type='radio', _name='radio', _value='yes', value='yes').xml() + '' + + >>> INPUT(_type='radio', _name='radio', _value='no', value='yes').xml() + '' + + + """ + + tag = 'input/' + + def _validate(self): + + # # this only changes value, not _value + + name = self['_name'] + if name is None or name == '': + return True + name = str(name) + request_vars_get = self.request_vars.get + if self['_type'] != 'checkbox': + self['old_value'] = self['value'] or self['_value'] or '' + value = request_vars_get(name, '') + self['value'] = value if not hasattr(value, 'file') else None + else: + self['old_value'] = self['value'] or False + value = request_vars_get(name) + if isinstance(value, (tuple, list)): + self['value'] = self['_value'] in value + else: + self['value'] = self['_value'] == value + requires = self['requires'] + if requires: + if not isinstance(requires, (list, tuple)): + requires = [requires] + for k, validator in enumerate(requires): + try: + (value, errors) = validator(value) + except: + import traceback + print(traceback.format_exc()) + msg = "Validation error, field:%s %s" % (name, validator) + raise Exception(msg) + if errors is not None: + self.vars[name] = value + self.errors[name] = errors + break + if name not in self.errors: + self.vars[name] = value + return True + return False + + def _postprocessing(self): + t = self['_type'] + if not t: + t = self['_type'] = 'text' + t = t.lower() + value = self['value'] + if self['_value'] is None or isinstance(self['_value'], cgi.FieldStorage): + _value = None + else: + _value = str(self['_value']) + if '_checked' in self.attributes and 'value' not in self.attributes: + pass + elif t == 'checkbox': + if not _value: + _value = self['_value'] = 'on' + if not value: + value = [] + elif value is True: + value = [_value] + elif not isinstance(value, (list, tuple)): + value = str(value).split('|') + self['_checked'] = _value in value and 'checked' or None + elif t == 'radio': + if str(value) == str(_value): + self['_checked'] = 'checked' + else: + self['_checked'] = None + elif t == 'password' and value != DEFAULT_PASSWORD_DISPLAY: + self['value'] = '' + elif not t == 'submit': + if value is None: + self['value'] = _value + elif not isinstance(value, list): + self['_value'] = value + + def xml(self): + name = self.attributes.get('_name', None) + if name and hasattr(self, 'errors') \ + and self.errors.get(name, None) \ + and self['hideerror'] is not True: + self['_class'] = (self['_class'] and self['_class'] + ' ' or '') + 'invalidinput' + return DIV.xml(self) + DIV( + DIV( + self.errors[name], _class='error', + errors=None, _id='%s__error' % name), + _class='error_wrapper').xml() + else: + if self['_class'] and self['_class'].endswith('invalidinput'): + self['_class'] = self['_class'][:-12] + if self['_class'] == '': + self['_class'] = None + return DIV.xml(self) + + +class TEXTAREA(INPUT): + + """ + Examples:: + + TEXTAREA(_name='sometext', value='blah ' * 100, requires=IS_NOT_EMPTY()) + + 'blah blah blah ...' will be the content of the textarea field. + + """ + + tag = 'textarea' + + def _postprocessing(self): + if '_rows' not in self.attributes: + self['_rows'] = 10 + if '_cols' not in self.attributes: + self['_cols'] = 40 + if self['value'] is not None: + self.components = [self['value']] + elif self.components: + self['value'] = self.components[0] + + +class OPTION(DIV): + + tag = 'option' + + def _fixup(self): + if '_value' not in self.attributes: + self.attributes['_value'] = str(self.components[0]) + + +class OBJECT(DIV): + + tag = 'object' + + +class OPTGROUP(DIV): + + tag = 'optgroup' + + def _fixup(self): + components = [] + for c in self.components: + if isinstance(c, OPTION): + components.append(c) + else: + components.append(OPTION(c, _value=str(c))) + self.components = components + + +class SELECT(INPUT): + """ + Examples: + + >>> from validators import IS_IN_SET + >>> SELECT('yes', 'no', _name='selector', value='yes', + ... requires=IS_IN_SET(['yes', 'no'])).xml() + '' + + """ + + tag = 'select' + + def _fixup(self): + components = [] + for c in self.components: + if isinstance(c, (OPTION, OPTGROUP)): + components.append(c) + else: + components.append(OPTION(c, _value=str(c))) + self.components = components + + def _postprocessing(self): + component_list = [] + for c in self.components: + if isinstance(c, OPTGROUP): + component_list.append(c.components) + else: + component_list.append([c]) + options = itertools.chain(*component_list) + + value = self['value'] + if value is not None: + if not self['_multiple']: + for c in options: # my patch + if (value is not None) and (str(c['_value']) == str(value)): + c['_selected'] = 'selected' + else: + c['_selected'] = None + else: + if isinstance(value, (list, tuple)): + values = [str(item) for item in value] + else: + values = [str(value)] + for c in options: # my patch + if (value is not None) and (str(c['_value']) in values): + c['_selected'] = 'selected' + else: + c['_selected'] = None + + +class FIELDSET(DIV): + + tag = 'fieldset' + + +class LEGEND(DIV): + + tag = 'legend' + + +class FORM(DIV): + + """ + Examples: + + >>> from validators import IS_NOT_EMPTY + >>> form=FORM(INPUT(_name="test", requires=IS_NOT_EMPTY())) + >>> form.xml() + '
    ' + + + a FORM is container for INPUT, TEXTAREA, SELECT and other helpers + + form has one important method:: + + form.accepts(request.vars, session) + + if form is accepted (and all validators pass) form.vars contains the + accepted vars, otherwise form.errors contains the errors. + in case of errors the form is modified to present the errors to the user. + """ + + tag = 'form' + + def __init__(self, *components, **attributes): + DIV.__init__(self, *components, **attributes) + self.vars = Storage() + self.errors = Storage() + self.latest = Storage() + self.accepted = None # none for not submitted + + def assert_status(self, status, request_vars): + return status + + def accepts(self, + request_vars, + session=None, + formname='default', + keepvalues=False, + onvalidation=None, + hideerror=False, + **kwargs + ): + """ + kwargs is not used but allows to specify the same interface for FORM and SQLFORM + """ + if request_vars.__class__.__name__ == 'Request': + request_vars = request_vars.post_vars + self.errors.clear() + self.request_vars = Storage() + self.request_vars.update(request_vars) + self.session = session + self.formname = formname + self.keepvalues = keepvalues + + # if this tag is a form and we are in accepting mode (status=True) + # check formname and formkey + + status = True + changed = False + request_vars = self.request_vars + if session is not None: + formkey = request_vars._formkey + keyname = '_formkey[%s]' % formname + formkeys = list(session.get(keyname, [])) + # check if user tampering with form and void CSRF + if not (formkey and formkeys and formkey in formkeys): + status = False + else: + session[keyname].remove(formkey) + if formname != request_vars._formname: + status = False + if status and session: + # check if editing a record that has been modified by the server + if hasattr(self, 'record_hash') and self.record_hash != formkey.split(':')[0]: + status = False + self.record_changed = changed = True + status = self._traverse(status, hideerror) + status = self.assert_status(status, request_vars) + if onvalidation: + if isinstance(onvalidation, dict): + onsuccess = onvalidation.get('onsuccess', None) + onfailure = onvalidation.get('onfailure', None) + onchange = onvalidation.get('onchange', None) + if [k for k in onvalidation if k not in ('onsuccess', 'onfailure', 'onchange')]: + raise RuntimeError('Invalid key in onvalidate dict') + if onsuccess and status: + call_as_list(onsuccess, self) + if onfailure and request_vars and not status: + call_as_list(onfailure, self) + status = len(self.errors) == 0 + if changed: + if onchange and self.record_changed and \ + self.detect_record_change: + call_as_list(onchange, self) + elif status: + call_as_list(onvalidation, self) + if self.errors: + status = False + if session is not None: + if hasattr(self, 'record_hash'): + formkey = self.record_hash + ':' + web2py_uuid() + else: + formkey = web2py_uuid() + self.formkey = formkey + keyname = '_formkey[%s]' % formname + session[keyname] = list(session.get(keyname, []))[-9:] + [formkey] + if status and not keepvalues: + self._traverse(False, hideerror) + self.accepted = status + return status + + def _postprocessing(self): + if '_action' not in self.attributes: + self['_action'] = '#' + if '_method' not in self.attributes: + self['_method'] = 'post' + if '_enctype' not in self.attributes: + self['_enctype'] = 'multipart/form-data' + + def hidden_fields(self): + c = [] + attr = self.attributes.get('hidden', {}) + if 'hidden' in self.attributes: + c = [INPUT(_type='hidden', _name=key, _value=value) for (key, value) in iteritems(attr)] + if hasattr(self, 'formkey') and self.formkey: + c.append(INPUT(_type='hidden', _name='_formkey', _value=self.formkey)) + if hasattr(self, 'formname') and self.formname: + c.append(INPUT(_type='hidden', _name='_formname', _value=self.formname)) + return DIV(c, _style="display:none;") + + def xml(self): + newform = FORM(*self.components, **self.attributes) + hidden_fields = self.hidden_fields() + if hidden_fields.components: + newform.append(hidden_fields) + return DIV.xml(newform) + + def validate(self, **kwargs): + """ + This function validates the form, + you can use it instead of directly form.accepts. + + Usage: + In controller:: + + def action(): + form=FORM(INPUT(_name=\"test\", requires=IS_NOT_EMPTY())) + form.validate() #you can pass some args here - see below + return dict(form=form) + + This can receive a bunch of arguments + + onsuccess = 'flash' - will show message_onsuccess in response.flash + None - will do nothing + can be a function (lambda form: pass) + onfailure = 'flash' - will show message_onfailure in response.flash + None - will do nothing + can be a function (lambda form: pass) + onchange = 'flash' - will show message_onchange in response.flash + None - will do nothing + can be a function (lambda form: pass) + + message_onsuccess + message_onfailure + message_onchange + next = where to redirect in case of success + any other kwargs will be passed for form.accepts(...) + """ + from gluon.globals import current + from gluon.http import redirect + kwargs['request_vars'] = kwargs.get( + 'request_vars', current.request.post_vars) + kwargs['session'] = kwargs.get('session', current.session) + kwargs['dbio'] = kwargs.get('dbio', False) # necessary for SQLHTML forms + + onsuccess = kwargs.get('onsuccess', 'flash') + onfailure = kwargs.get('onfailure', 'flash') + onchange = kwargs.get('onchange', 'flash') + message_onsuccess = kwargs.get('message_onsuccess', + current.T("Success!")) + message_onfailure = kwargs.get('message_onfailure', + current.T("Errors in form, please check it out.")) + message_onchange = kwargs.get('message_onchange', + current.T("Form consecutive submissions not allowed. " + + "Try re-submitting or refreshing the form page.")) + next = kwargs.get('next', None) + for key in ('message_onsuccess', 'message_onfailure', 'onsuccess', + 'onfailure', 'next', 'message_onchange', 'onchange'): + if key in kwargs: + del kwargs[key] + + if self.accepts(**kwargs): + if onsuccess == 'flash': + if next: + current.session.flash = message_onsuccess + else: + current.response.flash = message_onsuccess + elif callable(onsuccess): + onsuccess(self) + if next: + if self.vars: + for key, value in iteritems(self.vars): + next = next.replace('[%s]' % key, + urllib_quote(str(value))) + if not next.startswith('/'): + next = URL(next) + redirect(next) + return True + elif self.errors: + if onfailure == 'flash': + current.response.flash = message_onfailure + elif callable(onfailure): + onfailure(self) + return False + elif hasattr(self, "record_changed"): + if self.record_changed and self.detect_record_change: + if onchange == 'flash': + current.response.flash = message_onchange + elif callable(onchange): + onchange(self) + return False + + def process(self, **kwargs): + """ + Perform the .validate() method but returns the form + + Usage in controllers:: + + # directly on return + def action(): + #some code here + return dict(form=FORM(...).process(...)) + + You can use it with FORM, SQLFORM or FORM based plugins:: + + # response.flash messages + def action(): + form = SQLFORM(db.table).process(message_onsuccess='Sucess!') + return dict(form=form) + + # callback function + # callback receives True or False as first arg, and a list of args. + def my_callback(status, msg): + response.flash = "Success! "+msg if status else "Errors occured" + + # after argument can be 'flash' to response.flash messages + # or a function name to use as callback or None to do nothing. + def action(): + return dict(form=SQLFORM(db.table).process(onsuccess=my_callback) + + + """ + kwargs['dbio'] = kwargs.get('dbio', True) # necessary for SQLHTML forms + self.validate(**kwargs) + return self + + REDIRECT_JS = "window.location='%s';return false" + + def add_button(self, value, url, _class=None): + submit = self.element(_type='submit') + _class = "%s w2p-form-button" % _class if _class else "w2p-form-button" + submit.parent.append( + TAG['button'](value, _class=_class, + _onclick=url if url.startswith('javascript:') else + self.REDIRECT_JS % url)) + + @staticmethod + def confirm(text='OK', buttons=None, hidden=None): + if not buttons: + buttons = {} + if not hidden: + hidden = {} + inputs = [INPUT(_type='button', + _value=name, + _onclick=FORM.REDIRECT_JS % link) + for name, link in iteritems(buttons)] + inputs += [INPUT(_type='hidden', + _name=name, + _value=value) + for name, value in iteritems(hidden)] + form = FORM(INPUT(_type='submit', _value=text), *inputs) + form.process() + return form + + def as_dict(self, flat=False, sanitize=True): + """EXPERIMENTAL + + Sanitize is naive. It should catch any unsafe value + for client retrieval. + """ + SERIALIZABLE = (int, float, bool, basestring, long, + set, list, dict, tuple, Storage, type(None)) + UNSAFE = ("PASSWORD", "CRYPT") + d = self.__dict__ + + def sanitizer(obj): + if isinstance(obj, dict): + for k in obj.keys(): + if any([unsafe in str(k).upper() for unsafe in UNSAFE]): + # erease unsafe pair + obj.pop(k) + else: + # not implemented + pass + return obj + + def flatten(obj): + if isinstance(obj, (dict, Storage)): + newobj = obj.copy() + else: + newobj = obj + if sanitize: + newobj = sanitizer(newobj) + if flat: + if type(obj) in SERIALIZABLE: + if isinstance(newobj, (dict, Storage)): + for k in newobj: + newk = flatten(k) + newobj[newk] = flatten(newobj[k]) + if k != newk: + newobj.pop(k) + return newobj + elif isinstance(newobj, (list, tuple, set)): + return [flatten(item) for item in newobj] + else: + return newobj + else: + return str(newobj) + else: + return newobj + return flatten(d) + + def as_json(self, sanitize=True): + d = self.as_dict(flat=True, sanitize=sanitize) + from gluon.serializers import json + return json(d) + + def as_yaml(self, sanitize=True): + d = self.as_dict(flat=True, sanitize=sanitize) + from gluon.serializers import yaml + return yaml(d) + + def as_xml(self, sanitize=True): + d = self.as_dict(flat=True, sanitize=sanitize) + from gluon.serializers import xml + return xml(d) + + +class BEAUTIFY(DIV): + """ + Turns any list, dictionary, etc into decent looking html. + + Two special attributes are + + - sorted: a function that takes the dict and returned sorted keys + - keyfilter: a function that takes a key and returns its representation or + None if the key is to be skipped. + By default key[:1]=='_' is skipped. + + Examples: + + >>> BEAUTIFY(['a', 'b', {'hello': 'world'}]).xml() + '
    a
    b
    hello:
    world
    ' + + """ + + tag = 'div' + + @staticmethod + def no_underscore(key): + if key[:1] == '_': + return None + return key + + def __init__(self, component, **attributes): + self.components = [component] + self.attributes = attributes + sorter = attributes.get('sorted', sorted) + keyfilter = attributes.get('keyfilter', BEAUTIFY.no_underscore) + components = [] + attributes = copy.copy(self.attributes) + level = attributes['level'] = attributes.get('level', 6) - 1 + if '_class' in attributes: + attributes['_class'] += 'i' + if level == 0: + return + for c in self.components: + if hasattr(c, 'value') and not callable(c.value) and not isinstance(c, cgi.FieldStorage): + if c.value: + components.append(c.value) + if hasattr(c, 'xml') and callable(c.xml): + components.append(c) + continue + elif hasattr(c, 'keys') and callable(c.keys): + rows = [] + try: + keys = (sorter and sorter(c)) or c + for key in keys: + if isinstance(key, (str, unicodeT)) and keyfilter: + filtered_key = keyfilter(key) + else: + filtered_key = str(key) + if filtered_key is None: + continue + value = c[key] + if isinstance(value, types.LambdaType): + continue + rows.append( + TR( + TD(filtered_key, _style='font-weight:bold;vertical-align:top;'), + TD(':', _style='vertical-align:top;'), + TD(BEAUTIFY(value, **attributes)))) + components.append(TABLE(*rows, **attributes)) + continue + except: + pass + if isinstance(c, str): + components.append(str(c)) + elif isinstance(c, unicodeT): + components.append(c.encode('utf8')) + elif isinstance(c, (list, tuple)): + items = [TR(TD(BEAUTIFY(item, **attributes))) + for item in c] + components.append(TABLE(*items, **attributes)) + elif isinstance(c, cgi.FieldStorage): + components.append('FieldStorage object') + else: + components.append(repr(c)) + self.components = components + + +class MENU(DIV): + """ + Used to build menus + + Args: + _class: defaults to 'web2py-menu web2py-menu-vertical' + ul_class: defaults to 'web2py-menu-vertical' + li_class: defaults to 'web2py-menu-expand' + li_first: defaults to 'web2py-menu-first' + li_last: defaults to 'web2py-menu-last' + + Use like:: + + menu = MENU([['name', False, URL(...), [submenu]], ...]) + {{=menu}} + + """ + + tag = 'ul' + + def __init__(self, data, **args): + self.data = data + self.attributes = args + self.components = [] + if '_class' not in self.attributes: + self['_class'] = 'web2py-menu web2py-menu-vertical' + if 'ul_class' not in self.attributes: + self['ul_class'] = 'web2py-menu-vertical' + if 'li_class' not in self.attributes: + self['li_class'] = 'web2py-menu-expand' + if 'li_first' not in self.attributes: + self['li_first'] = 'web2py-menu-first' + if 'li_last' not in self.attributes: + self['li_last'] = 'web2py-menu-last' + if 'li_active' not in self.attributes: + self['li_active'] = 'web2py-menu-active' + if 'mobile' not in self.attributes: + self['mobile'] = False + + def serialize(self, data, level=0): + if level == 0: + ul = UL(**self.attributes) + else: + ul = UL(_class=self['ul_class']) + for item in data: + if isinstance(item, LI): + ul.append(item) + else: + (name, active, link) = item[:3] + if isinstance(link, DIV): + li = LI(link) + elif 'no_link_url' in self.attributes and self['no_link_url'] == link: + li = LI(DIV(name)) + elif isinstance(link, dict): + li = LI(A(name, **link)) + elif link: + li = LI(A(name, _href=link)) + elif not link and isinstance(name, A): + li = LI(name) + else: + li = LI(A(name, _href='#', + _onclick='javascript:void(0);return false;')) + if level == 0 and item == data[0]: + li['_class'] = self['li_first'] + elif level == 0 and item == data[-1]: + li['_class'] = self['li_last'] + if len(item) > 3 and item[3]: + li['_class'] = self['li_class'] + li.append(self.serialize(item[3], level + 1)) + if active or ('active_url' in self.attributes and self['active_url'] == link): + if li['_class']: + li['_class'] = li['_class'] + ' ' + self['li_active'] + else: + li['_class'] = self['li_active'] + if len(item) <= 4 or item[4] is True: + ul.append(li) + return ul + + def serialize_mobile(self, data, select=None, prefix=''): + if not select: + select = SELECT(**self.attributes) + custom_items = [] + for item in data: + # Custom item aren't serialized as mobile + if len(item) >= 3 and (not item[0]) or (isinstance(item[0], DIV) and not (item[2])): + # ex: ('', False, A('title', _href=URL(...), _title="title")) + # ex: (A('title', _href=URL(...), _title="title"), False, None) + custom_items.append(item) + elif len(item) <= 4 or item[4] is True: + select.append(OPTION(CAT(prefix, item[0]), + _value=item[2], _selected=item[1])) + if len(item) > 3 and len(item[3]): + self.serialize_mobile( + item[3], select, prefix=CAT(prefix, item[0], '/')) + select['_onchange'] = 'window.location=this.value' + # avoid to wrap the select if no custom items are present + html = DIV(select, self.serialize(custom_items)) if len(custom_items) else select + return html + + def xml(self): + if self['mobile']: + return self.serialize_mobile(self.data, 0).xml() + else: + return self.serialize(self.data, 0).xml() + + +def embed64(filename=None, + file=None, + data=None, + extension='image/gif' + ): + """ + helper to encode the provided (binary) data into base64. + + Args: + filename: if provided, opens and reads this file in 'rb' mode + file: if provided, reads this file + data: if provided, uses the provided data + """ + + if filename and os.path.exists(file): + fp = open(filename, 'rb') + data = fp.read() + fp.close() + data = base64.b64encode(data) + return 'data:%s;base64,%s' % (extension, data) + + +# TODO: Check if this test() is still relevant now that we have gluon/tests/test_html.py +def test(): + """ + Example: + + >>> from validators import * + >>> print(DIV(A('click me', _href=URL(a='a', c='b', f='c')), BR(), HR(), DIV(SPAN("World"), _class='unknown')).xml()) + + >>> print(DIV(UL("doc","cat","mouse")).xml()) +
    • doc
    • cat
    • mouse
    + >>> print(DIV(UL("doc", LI("cat", _class='feline'), 18)).xml()) +
    • doc
    • cat
    • 18
    + >>> print(TABLE(['a', 'b', 'c'], TR('d', 'e', 'f'), TR(TD(1), TD(2), TD(3))).xml()) +
    abc
    def
    123
    + >>> form=FORM(INPUT(_type='text', _name='myvar', requires=IS_EXPR('int(value)<10'))) + >>> print(form.xml()) +
    + >>> print(form.accepts({'myvar':'34'}, formname=None)) + False + >>> print(form.xml()) +
    Invalid expression
    + >>> print(form.accepts({'myvar':'4'}, formname=None, keepvalues=True)) + True + >>> print(form.xml()) +
    + >>> form=FORM(SELECT('cat', 'dog', _name='myvar')) + >>> print(form.accepts({'myvar':'dog'}, formname=None, keepvalues=True)) + True + >>> print(form.xml()) +
    + >>> form=FORM(INPUT(_type='text', _name='myvar', requires=IS_MATCH('^\w+$', 'only alphanumeric!'))) + >>> print(form.accepts({'myvar':'as df'}, formname=None)) + False + >>> print(form.xml()) +
    only alphanumeric!
    + >>> session={} + >>> form=FORM(INPUT(value="Hello World", _name="var", requires=IS_MATCH('^\w+$'))) + >>> isinstance(form.as_dict(), dict) + True + >>> "vars" in form.as_dict(flat=True) + True + >>> isinstance(form.as_json(), basestring) and len(form.as_json(sanitize=False)) > 0 + True + >>> if form.accepts({}, session,formname=None): print('passed') + >>> if form.accepts({'var':'test ', '_formkey': session['_formkey[None]']}, session, formname=None): print('passed') + """ + pass + + +class web2pyHTMLParser(HTMLParser): + """ + obj = web2pyHTMLParser(text) parses and html/xml text into web2py helpers. + obj.tree contains the root of the tree, and tree can be manipulated + """ + + def __init__(self, text, closed=('input', 'link')): + HTMLParser.__init__(self) + self.tree = self.parent = TAG['']() + self.closed = closed + self.last = None + self.feed(text) + + def handle_starttag(self, tagname, attrs): + if tagname in self.closed: + tagname += '/' + tag = TAG[tagname]() + for key, value in attrs: + tag['_' + key] = value + tag.parent = self.parent + self.parent.append(tag) + if not tag.tag.endswith('/'): + self.parent = tag + else: + self.last = tag.tag[:-1] + + def handle_data(self, data): + if not isinstance(data, unicodeT): + try: + data = data.decode('utf8') + except: + data = data.decode('latin1') + self.parent.append(data.encode('utf8', 'xmlcharref')) + + def handle_charref(self, name): + if name.startswith('x'): + self.parent.append(unichr(int(name[1:], 16)).encode('utf8')) + else: + self.parent.append(unichr(int(name)).encode('utf8')) + + def handle_entityref(self, name): + self.parent.append(entitydefs[name]) + + def handle_endtag(self, tagname): + # this deals with unbalanced tags + if tagname == self.last: + return + while True: + try: + parent_tagname = self.parent.tag + self.parent = self.parent.parent + except: + raise RuntimeError("unable to balance tag %s" % tagname) + if parent_tagname[:len(tagname)] == tagname: + break + + +def markdown_serializer(text, tag=None, attr=None): + attr = attr or {} + if tag is None: + return re.sub('\s+', ' ', text) + if tag == 'br': + return '\n\n' + if tag == 'h1': + return '#' + text + '\n\n' + if tag == 'h2': + return '#' * 2 + text + '\n\n' + if tag == 'h3': + return '#' * 3 + text + '\n\n' + if tag == 'h4': + return '#' * 4 + text + '\n\n' + if tag == 'p': + return text + '\n\n' + if tag == 'b' or tag == 'strong': + return '**%s**' % text + if tag == 'em' or tag == 'i': + return '*%s*' % text + if tag == 'tt' or tag == 'code': + return '`%s`' % text + if tag == 'a': + return '[%s](%s)' % (text, attr.get('_href', '')) + if tag == 'img': + return '![%s](%s)' % (attr.get('_alt', ''), attr.get('_src', '')) + return text + + +def markmin_serializer(text, tag=None, attr=None): + attr = attr or {} + # if tag is None: return re.sub('\s+',' ',text) + if tag == 'br': + return '\n\n' + if tag == 'h1': + return '# ' + text + '\n\n' + if tag == 'h2': + return '#' * 2 + ' ' + text + '\n\n' + if tag == 'h3': + return '#' * 3 + ' ' + text + '\n\n' + if tag == 'h4': + return '#' * 4 + ' ' + text + '\n\n' + if tag == 'p': + return text + '\n\n' + if tag == 'li': + return '\n- ' + text.replace('\n', ' ') + if tag == 'tr': + return text[3:].replace('\n', ' ') + '\n' + if tag in ['table', 'blockquote']: + return '\n-----\n' + text + '\n------\n' + if tag in ['td', 'th']: + return ' | ' + text + if tag in ['b', 'strong', 'label']: + return '**%s**' % text + if tag in ['em', 'i']: + return "''%s''" % text + if tag in ['tt']: + return '``%s``' % text.strip() + if tag in ['code']: + return '``\n%s``' % text + if tag == 'a': + return '[[%s %s]]' % (text, attr.get('_href', '')) + if tag == 'img': + return '[[%s %s left]]' % (attr.get('_alt', 'no title'), attr.get('_src', '')) + return text + + +class MARKMIN(XmlComponent): + """ + For documentation: http://web2py.com/examples/static/markmin.html + """ + def __init__(self, + text, extra=None, allowed=None, sep='p', + url=None, environment=None, latex='google', + autolinks='default', + protolinks='default', + class_prefix='', + id_prefix='markmin_', + **kwargs): + self.text = to_bytes(text) + self.extra = extra or {} + self.allowed = allowed or {} + self.sep = sep + self.url = URL if url is True else url + self.environment = environment + self.latex = latex + self.autolinks = autolinks + self.protolinks = protolinks + self.class_prefix = class_prefix + self.id_prefix = id_prefix + self.kwargs = kwargs + + def flatten(self): + return self.text + + def xml(self): + from gluon.contrib.markmin.markmin2html import render + html = render(self.text, extra=self.extra, + allowed=self.allowed, sep=self.sep, latex=self.latex, + URL=self.url, environment=self.environment, + autolinks=self.autolinks, protolinks=self.protolinks, + class_prefix=self.class_prefix, id_prefix=self.id_prefix) + return to_bytes(html) if not self.kwargs else to_bytes(DIV(XML(html), **self.kwargs).xml()) + + def __str__(self): + # In PY3 __str__ cannot return bytes (TypeError: __str__ returned non-string (type bytes)) + return to_native(self.xml()) + + +def ASSIGNJS(**kargs): + """ + Example: + ASSIGNJS(var1='1', var2='2') will return the following javascript variables assignations : + + var var1 = "1"; + var var2 = "2"; + + Args: + **kargs: Any keywords arguments and assigned values. + + Returns: + Javascript vars assignations for the key/value passed. + + """ + from gluon.serializers import json + s = "" + for key, value in kargs.items(): + s += 'var %s = %s;\n' % (key, json(value)) + return XML(s) + + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/web2py/gluon/http.py b/web2py/gluon/http.py new file mode 100644 index 0000000..179dc4f --- /dev/null +++ b/web2py/gluon/http.py @@ -0,0 +1,187 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +HTTP statuses helpers +-------------------------------------------- +""" + +import re +from gluon._compat import iteritems, unicodeT, to_bytes + +__all__ = ['HTTP', 'redirect'] + +defined_status = { + 200: 'OK', + 201: 'CREATED', + 202: 'ACCEPTED', + 203: 'NON-AUTHORITATIVE INFORMATION', + 204: 'NO CONTENT', + 205: 'RESET CONTENT', + 206: 'PARTIAL CONTENT', + 301: 'MOVED PERMANENTLY', + 302: 'FOUND', + 303: 'SEE OTHER', + 304: 'NOT MODIFIED', + 305: 'USE PROXY', + 307: 'TEMPORARY REDIRECT', + 400: 'BAD REQUEST', + 401: 'UNAUTHORIZED', + 402: 'PAYMENT REQUIRED', + 403: 'FORBIDDEN', + 404: 'NOT FOUND', + 405: 'METHOD NOT ALLOWED', + 406: 'NOT ACCEPTABLE', + 407: 'PROXY AUTHENTICATION REQUIRED', + 408: 'REQUEST TIMEOUT', + 409: 'CONFLICT', + 410: 'GONE', + 411: 'LENGTH REQUIRED', + 412: 'PRECONDITION FAILED', + 413: 'REQUEST ENTITY TOO LARGE', + 414: 'REQUEST-URI TOO LONG', + 415: 'UNSUPPORTED MEDIA TYPE', + 416: 'REQUESTED RANGE NOT SATISFIABLE', + 417: 'EXPECTATION FAILED', + 422: 'UNPROCESSABLE ENTITY', + 429: 'TOO MANY REQUESTS', + 451: 'UNAVAILABLE FOR LEGAL REASONS', # http://www.451unavailable.org/ + 500: 'INTERNAL SERVER ERROR', + 501: 'NOT IMPLEMENTED', + 502: 'BAD GATEWAY', + 503: 'SERVICE UNAVAILABLE', + 504: 'GATEWAY TIMEOUT', + 505: 'HTTP VERSION NOT SUPPORTED', + 509: 'BANDWIDTH LIMIT EXCEEDED', +} + +regex_status = re.compile('^\d{3} [0-9A-Z ]+$') + + +class HTTP(Exception): + """Raises an HTTP response + + Args: + status: usually an integer. If it's a well known status code, the ERROR + message will be automatically added. A string can also be passed + as `510 Foo Bar` and in that case the status code and the error + message will be parsed accordingly + body: what to return as body. If left as is, will return the error code + and the status message in the body itself + cookies: pass cookies along (usually not needed) + headers: pass headers as usual dict mapping + """ + + def __init__( + self, + status, + body='', + cookies=None, + **headers + ): + self.status = status + self.body = body + self.headers = headers + self.cookies2headers(cookies) + + def cookies2headers(self, cookies): + if cookies and len(cookies) > 0: + self.headers['Set-Cookie'] = [ + str(cookie)[11:] for cookie in cookies.values()] + + def to(self, responder, env=None): + env = env or {} + status = self.status + headers = self.headers + if status in defined_status: + status = '%d %s' % (status, defined_status[status]) + elif isinstance(status, int): + status = '%d UNKNOWN ERROR' % status + else: + status = str(status) + if not regex_status.match(status): + status = '500 %s' % (defined_status[500]) + headers.setdefault('Content-Type', 'text/html; charset=UTF-8') + body = self.body + if status[:1] == '4': + if not body: + body = status + if isinstance(body, (str, bytes, bytearray)): + if isinstance(body, unicodeT): + body = to_bytes(body) # This must be done before len + headers['Content-Length'] = len(body) + rheaders = [] + for k, v in iteritems(headers): + if isinstance(v, list): + rheaders += [(k, str(item)) for item in v] + elif v is not None: + rheaders.append((k, str(v))) + responder(status, rheaders) + if env.get('request_method', '') == 'HEAD': + return [''] + elif isinstance(body, (str, bytes, bytearray)): + if isinstance(body, unicodeT): + body = to_bytes(body) + return [body] + elif hasattr(body, '__iter__'): + return body + else: + body = str(body) + if isinstance(body, unicodeT): + body = to_bytes(body) + return [body] + + @property + def message(self): + """ + compose a message describing this exception + + "status defined_status [web2py_error]" + + message elements that are not defined are omitted + """ + msg = '%(status)s' + if self.status in defined_status: + msg = '%(status)s %(defined_status)s' + if 'web2py_error' in self.headers: + msg += ' [%(web2py_error)s]' + return msg % dict( + status=self.status, + defined_status=defined_status.get(self.status), + web2py_error=self.headers.get('web2py_error')) + + def __str__(self): + """stringify me""" + return self.message + + +def redirect(location='', how=303, client_side=False, headers=None): + """Raises a redirect (303) + + Args: + location: the url where to redirect + how: what HTTP status code to use when redirecting + client_side: if set to True, it triggers a reload of the entire page + when the fragment has been loaded as a component + """ + headers = headers or {} + if location: + from gluon.globals import current + loc = location.replace('\r', '%0D').replace('\n', '%0A') + if client_side and current.request.ajax: + headers['web2py-redirect-location'] = loc + raise HTTP(200, **headers) + else: + headers['Location'] = loc + raise HTTP(how, + 'You are being redirected here' % loc, + **headers) + else: + from gluon.globals import current + if client_side and current.request.ajax: + headers['web2py-component-command'] = 'window.location.reload(true)' + raise HTTP(200, **headers) diff --git a/web2py/gluon/import_all.py b/web2py/gluon/import_all.py new file mode 100644 index 0000000..85f1486 --- /dev/null +++ b/web2py/gluon/import_all.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python + +""" +This file is part of the web2py Web Framework +Copyrighted by Massimo Di Pierro +License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +This file is not strictly required by web2py. It is used for three purposes: + +1) check that all required modules are installed properly +2) provide py2exe and py2app a list of modules to be packaged in the binary +3) (optional) preload modules in memory to speed up http responses + +""" + +import os +import sys + +base_modules = ['aifc', 'anydbm', 'array', 'asynchat', 'asyncore', 'atexit', + 'audioop', 'base64', 'BaseHTTPServer', 'Bastion', 'binascii', + 'binhex', 'bisect', 'bz2', 'calendar', 'cgi', 'CGIHTTPServer', + 'cgitb', 'chunk', 'cmath', 'cmd', 'code', 'codecs', 'codeop', + 'collections', 'colorsys', 'compileall', 'compiler', + 'compiler.ast', 'compiler.visitor', 'ConfigParser', + 'contextlib', 'Cookie', 'cookielib', 'copy', 'copy_reg', + 'collections', + 'cPickle', 'cProfile', 'cStringIO', 'csv', 'ctypes', + 'datetime', 'decimal', 'difflib', 'dircache', 'dis', + 'doctest', 'DocXMLRPCServer', 'dumbdbm', 'dummy_thread', + 'dummy_threading', 'email', 'email.charset', 'email.encoders', + 'email.errors', 'email.generator', 'email.header', + 'email.iterators', 'email.message', 'email.mime', + 'email.mime.audio', 'email.mime.base', 'email.mime.image', + 'email.mime.message', 'email.mime.multipart', + 'email.mime.nonmultipart', 'email.mime.text', 'email.parser', + 'email.utils', 'encodings.idna', 'errno', 'exceptions', + 'filecmp', 'fileinput', 'fnmatch', 'formatter', 'fpformat', + 'ftplib', 'functools', 'gc', 'getopt', 'getpass', 'gettext', + 'glob', 'gzip', 'hashlib', 'heapq', 'hmac', 'hotshot', + 'hotshot.stats', 'htmlentitydefs', 'htmllib', 'HTMLParser', + 'httplib', 'imaplib', 'imghdr', 'imp', 'inspect', + 'itertools', 'keyword', 'linecache', 'locale', 'logging', + 'macpath', 'mailbox', 'mailcap', 'marshal', 'math', + 'mimetools', 'mimetypes', 'mmap', 'modulefinder', 'mutex', + 'netrc', 'new', 'nntplib', 'operator', 'optparse', 'os', + 'parser', 'pdb', 'pickle', 'pickletools', 'pkgutil', + 'platform', 'poplib', 'pprint', 'py_compile', 'pyclbr', + 'pydoc', 'Queue', 'quopri', 'random', 're', 'repr', + 'rexec', 'rfc822', 'rlcompleter', 'robotparser', 'runpy', + 'sched', 'select', 'sgmllib', 'shelve', + 'shlex', 'shutil', 'signal', 'SimpleHTTPServer', + 'SimpleXMLRPCServer', 'site', 'smtpd', 'smtplib', + 'sndhdr', 'socket', 'SocketServer', 'sqlite3', + 'stat', 'statvfs', 'string', 'StringIO', + 'stringprep', 'struct', 'subprocess', 'sunau', 'symbol', + 'tabnanny', 'tarfile', 'telnetlib', 'tempfile', 'textwrap', 'thread', 'threading', + 'time', 'timeit', 'Tix', 'Tkinter', 'token', + 'tokenize', 'trace', 'traceback', 'types', + 'unicodedata', 'unittest', 'urllib', 'urllib2', + 'urlparse', 'user', 'UserDict', 'UserList', 'UserString', + 'uu', 'uuid', 'warnings', 'wave', 'weakref', 'webbrowser', + 'whichdb', 'wsgiref', 'wsgiref.handlers', 'wsgiref.headers', + 'wsgiref.simple_server', 'wsgiref.util', 'wsgiref.validate', + 'xdrlib', 'xml.dom', 'xml.dom.minidom', 'xml.dom.pulldom', + 'xml.etree.ElementTree', 'xml.parsers.expat', 'xml.sax', + 'xml.sax.handler', 'xml.sax.saxutils', 'xml.sax.xmlreader', + 'xmlrpclib', 'zipfile', 'zipimport', 'zlib', 'mhlib', + 'MimeWriter', 'mimify', 'multifile', 'sets'] + +contributed_modules = [] + +# Python base version +python_version = sys.version[:3] + +# Modules which we want to raise an Exception if they are missing +alert_dependency = ['hashlib', 'uuid'] + +# Now we remove the blacklisted modules if we are using the stated +# python version. +# +# List of modules deprecated in Python 2.7 that are in the above list +py27_deprecated = ['mhlib', 'multifile', 'mimify', 'sets', 'MimeWriter'] # And ['optparse'] but we need it for now + +if python_version >= '2.7': + base_modules += ['argparse', 'json', 'multiprocessing'] + base_modules = list(set(base_modules).difference(set(py27_deprecated))) + +# Now iterate in the base_modules, trying to do the import +for module in base_modules + contributed_modules: + try: + __import__(module, globals(), locals(), []) + except: + # Raise an exception if the current module is a dependency + if module in alert_dependency: + msg = "Missing dependency: %(module)s\n" % locals() + msg += "Try the following command: " + msg += "easy_install-%(python_version)s -U %(module)s" % locals() + raise ImportError(msg) diff --git a/web2py/gluon/languages.py b/web2py/gluon/languages.py new file mode 100644 index 0000000..07dbbac --- /dev/null +++ b/web2py/gluon/languages.py @@ -0,0 +1,1094 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) +| Plural subsystem is created by Vladyslav Kozlovskyy (Ukraine) + +Translation system +-------------------------------------------- +""" + +import os +import re +import sys +import pkgutil +import logging +from cgi import escape +from threading import RLock + +from gluon.utils import local_html_escape + +from gluon._compat import copyreg, PY2, maketrans, iterkeys, unicodeT, to_unicode, to_bytes, iteritems, to_native, pjoin + +from pydal.contrib.portalocker import read_locked, LockedFile + +from gluon.fileutils import listdir +from gluon.cfs import getcfs +from gluon.html import XML, xmlescape +from gluon.contrib.markmin.markmin2html import render, markmin_escape + +__all__ = ['translator', 'findT', 'update_all_languages'] + +ostat = os.stat +oslistdir = os.listdir +pdirname = os.path.dirname +isdir = os.path.isdir + +DEFAULT_LANGUAGE = 'en' +DEFAULT_LANGUAGE_NAME = 'English' + +# DEFAULT PLURAL-FORMS RULES: +# language doesn't use plural forms +DEFAULT_NPLURALS = 1 +# only one singular/plural form is used +DEFAULT_GET_PLURAL_ID = lambda n: 0 +# word is unchangeable +DEFAULT_CONSTRUCT_PLURAL_FORM = lambda word, plural_id: word + +if PY2: + NUMBERS = (int, long, float) + from gluon.utf8 import Utf8 +else: + NUMBERS = (int, float) + Utf8 = str + +# pattern to find T(blah blah blah) expressions +PY_STRING_LITERAL_RE = r'(?<=[^\w]T\()(?P'\ + + r"[uU]?[rR]?(?:'''(?:[^']|'{1,2}(?!'))*''')|"\ + + r"(?:'(?:[^'\\]|\\.)*')|" + r'(?:"""(?:[^"]|"{1,2}(?!"))*""")|'\ + + r'(?:"(?:[^"\\]|\\.)*"))' + +PY_M_STRING_LITERAL_RE = r'(?<=[^\w]T\.M\()(?P'\ + + r"[uU]?[rR]?(?:'''(?:[^']|'{1,2}(?!'))*''')|"\ + + r"(?:'(?:[^'\\]|\\.)*')|" + r'(?:"""(?:[^"]|"{1,2}(?!"))*""")|'\ + + r'(?:"(?:[^"\\]|\\.)*"))' + +regex_translate = re.compile(PY_STRING_LITERAL_RE, re.DOTALL) +regex_translate_m = re.compile(PY_M_STRING_LITERAL_RE, re.DOTALL) +regex_param = re.compile(r'{(?P.+?)}') + +# pattern for a valid accept_language +regex_language = \ + re.compile('([a-z]{2,3}(?:\-[a-z]{2})?(?:\-[a-z]{2})?)(?:[,;]|$)') +regex_langfile = re.compile('^[a-z]{2,3}(-[a-z]{2})?\.py$') +regex_backslash = re.compile(r"\\([\\{}%])") +regex_plural = re.compile('%({.+?})') +regex_plural_dict = re.compile('^{(?P[^()[\]][^()[\]]*?)\((?P[^()\[\]]+)\)}$') # %%{word(varname or number)} +regex_plural_tuple = re.compile( + '^{(?P[^[\]()]+)(?:\[(?P\d+)\])?}$') # %%{word[index]} or %%{word} +regex_plural_file = re.compile('^plural-[a-zA-Z]{2}(-[a-zA-Z]{2})?\.py$') + + +def is_writable(): + """ returns True if and only if the filesystem is writable """ + from gluon.settings import global_settings + return not global_settings.web2py_runtime_gae + + +def safe_eval(text): + if text.strip(): + try: + import ast + return ast.literal_eval(text) + except ImportError: + return eval(text, {}, {}) + return None + +# used as default filter in translator.M() + + +def markmin(s): + def markmin_aux(m): + return '{%s}' % markmin_escape(m.group('s')) + return render(regex_param.sub(markmin_aux, s), + sep='br', autolinks=None, id_prefix='') + +# UTF8 helper functions + + +def upper_fun(s): + return to_bytes(to_unicode(s).upper()) + + +def title_fun(s): + return to_bytes(to_unicode(s).title()) + + +def cap_fun(s): + return to_bytes(to_unicode(s).capitalize()) + + +ttab_in = maketrans("\\%{}", '\x1c\x1d\x1e\x1f') +ttab_out = maketrans('\x1c\x1d\x1e\x1f', "\\%{}") + +# cache of translated messages: +# global_language_cache: +# { 'languages/xx.py': +# ( {"def-message": "xx-message", +# ... +# "def-message": "xx-message"}, lock_object ) +# 'languages/yy.py': ( {dict}, lock_object ) +# ... +# } + +global_language_cache = {} + + +def get_from_cache(cache, val, fun): + lang_dict, lock = cache + lock.acquire() + try: + result = lang_dict.get(val) + finally: + lock.release() + if result: + return result + lock.acquire() + try: + result = lang_dict.setdefault(val, fun()) + finally: + lock.release() + return result + + +def clear_cache(filename): + cache = global_language_cache.setdefault( + filename, ({}, RLock())) + lang_dict, lock = cache + lock.acquire() + try: + lang_dict.clear() + finally: + lock.release() + + +def read_dict_aux(filename): + lang_text = read_locked(filename).replace(b'\r\n', b'\n') + clear_cache(filename) + try: + return safe_eval(to_native(lang_text)) or {} + except Exception: + e = sys.exc_info()[1] + status = 'Syntax error in %s (%s)' % (filename, e) + logging.error(status) + return {'__corrupted__': status} + + +def read_dict(filename): + """ Returns dictionary with translation messages + """ + return getcfs('lang:' + filename, filename, + lambda: read_dict_aux(filename)) + + +def read_possible_plural_rules(): + """ + Creates list of all possible plural rules files + The result is cached in PLURAL_RULES dictionary to increase speed + """ + plurals = {} + try: + import gluon.contrib.plural_rules as package + for importer, modname, ispkg in pkgutil.iter_modules(package.__path__): + if len(modname) == 2: + module = __import__(package.__name__ + '.' + modname, + fromlist=[modname]) + lang = modname + pname = modname + '.py' + nplurals = getattr(module, 'nplurals', DEFAULT_NPLURALS) + get_plural_id = getattr( + module, 'get_plural_id', + DEFAULT_GET_PLURAL_ID) + construct_plural_form = getattr( + module, 'construct_plural_form', + DEFAULT_CONSTRUCT_PLURAL_FORM) + plurals[lang] = (lang, nplurals, get_plural_id, + construct_plural_form) + except ImportError: + e = sys.exc_info()[1] + logging.warn('Unable to import plural rules: %s' % e) + return plurals + +PLURAL_RULES = read_possible_plural_rules() + + +def read_possible_languages_aux(langdir): + def get_lang_struct(lang, langcode, langname, langfile_mtime): + if lang == 'default': + real_lang = langcode.lower() + else: + real_lang = lang + (prules_langcode, + nplurals, + get_plural_id, + construct_plural_form + ) = PLURAL_RULES.get(real_lang[:2], ('default', + DEFAULT_NPLURALS, + DEFAULT_GET_PLURAL_ID, + DEFAULT_CONSTRUCT_PLURAL_FORM)) + if prules_langcode != 'default': + (pluraldict_fname, + pluraldict_mtime) = plurals.get(real_lang, + plurals.get(real_lang[:2], + ('plural-%s.py' % real_lang, 0))) + else: + pluraldict_fname = None + pluraldict_mtime = 0 + return (langcode, # language code from !langcode! + langname, + # language name in national spelling from !langname! + langfile_mtime, # m_time of language file + pluraldict_fname, # name of plural dictionary file or None (when default.py is not exist) + pluraldict_mtime, # m_time of plural dictionary file or 0 if file is not exist + prules_langcode, # code of plural rules language or 'default' + nplurals, # nplurals for current language + get_plural_id, # get_plural_id() for current language + construct_plural_form) # construct_plural_form() for current language + + plurals = {} + flist = oslistdir(langdir) if isdir(langdir) else [] + + # scan languages directory for plural dict files: + for pname in flist: + if regex_plural_file.match(pname): + plurals[pname[7:-3]] = (pname, + ostat(pjoin(langdir, pname)).st_mtime) + langs = {} + # scan languages directory for langfiles: + for fname in flist: + if regex_langfile.match(fname) or fname == 'default.py': + fname_with_path = pjoin(langdir, fname) + d = read_dict(fname_with_path) + lang = fname[:-3] + langcode = d.get('!langcode!', lang if lang != 'default' + else DEFAULT_LANGUAGE) + langname = d.get('!langname!', langcode) + langfile_mtime = ostat(fname_with_path).st_mtime + langs[lang] = get_lang_struct(lang, langcode, + langname, langfile_mtime) + if 'default' not in langs: + # if default.py is not found, + # add DEFAULT_LANGUAGE as default language: + langs['default'] = get_lang_struct('default', DEFAULT_LANGUAGE, + DEFAULT_LANGUAGE_NAME, 0) + deflang = langs['default'] + deflangcode = deflang[0] + if deflangcode not in langs: + # create language from default.py: + langs[deflangcode] = deflang[:2] + (0,) + deflang[3:] + + return langs + + +def read_possible_languages(langpath): + return getcfs('langs:' + langpath, langpath, + lambda: read_possible_languages_aux(langpath)) + + +def read_plural_dict_aux(filename): + lang_text = read_locked(filename).replace(b'\r\n', b'\n') + try: + return eval(lang_text) or {} + except Exception: + e = sys.exc_info()[1] + status = 'Syntax error in %s (%s)' % (filename, e) + logging.error(status) + return {'__corrupted__': status} + + +def read_plural_dict(filename): + return getcfs('plurals:' + filename, filename, + lambda: read_plural_dict_aux(filename)) + + +def write_plural_dict(filename, contents): + if '__corrupted__' in contents: + return + fp = None + try: + fp = LockedFile(filename, 'w') + fp.write('#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n{\n# "singular form (0)": ["first plural form (1)", "second plural form (2)", ...],\n') + for key in sorted(contents, sort_function): + forms = '[' + ','.join([repr(Utf8(form)) + for form in contents[key]]) + ']' + fp.write('%s: %s,\n' % (repr(Utf8(key)), forms)) + fp.write('}\n') + except (IOError, OSError): + if is_writable(): + logging.warning('Unable to write to file %s' % filename) + return + finally: + if fp: + fp.close() + + +def sort_function(x, y): + return cmp(unicode(x, 'utf-8').lower(), unicode(y, 'utf-8').lower()) + + +def write_dict(filename, contents): + if '__corrupted__' in contents: + return + fp = None + try: + fp = LockedFile(filename, 'w') + fp.write('# -*- coding: utf-8 -*-\n{\n') + for key in sorted(contents, key=lambda x: to_unicode(x, 'utf-8').lower()): + fp.write('%s: %s,\n' % (repr(Utf8(key)), + repr(Utf8(contents[key])))) + fp.write('}\n') + except (IOError, OSError): + if is_writable(): + logging.warning('Unable to write to file %s' % filename) + return + finally: + if fp: + fp.close() + + +class lazyT(object): + """ + Never to be called explicitly, returned by + translator.__call__() or translator.M() + """ + m = s = T = f = t = None + M = is_copy = False + + def __init__( + self, + message, + symbols={}, + T=None, + filter=None, + ftag=None, + M=False + ): + if isinstance(message, lazyT): + self.m = message.m + self.s = message.s + self.T = message.T + self.f = message.f + self.t = message.t + self.M = message.M + self.is_copy = True + else: + self.m = message + self.s = symbols + self.T = T + self.f = filter + self.t = ftag + self.M = M + self.is_copy = False + + def __repr__(self): + return "" % (repr(Utf8(self.m)), ) + + def __str__(self): + return str(self.T.apply_filter(self.m, self.s, self.f, self.t) if self.M else + self.T.translate(self.m, self.s)) + + def __eq__(self, other): + return str(self) == str(other) + + def __ne__(self, other): + return str(self) != str(other) + + def __add__(self, other): + return '%s%s' % (self, other) + + def __radd__(self, other): + return '%s%s' % (other, self) + + def __mul__(self, other): + return str(self) * other + + def __cmp__(self, other): + return cmp(str(self), str(other)) + + def __hash__(self): + return hash(str(self)) + + def __getattr__(self, name): + return getattr(str(self), name) + + def __getitem__(self, i): + return str(self)[i] + + def __getslice__(self, i, j): + return str(self)[i:j] + + def __iter__(self): + for c in str(self): + yield c + + def __len__(self): + return len(str(self)) + + def xml(self): + return str(self) if self.M else local_html_escape(str(self), quote=False) + + def encode(self, *a, **b): + if PY2 and a[0] != 'utf8': + return to_unicode(str(self)).encode(*a, **b) + else: + return str(self) + + def decode(self, *a, **b): + if PY2: + return str(self).decode(*a, **b) + else: + return str(self) + + def read(self): + return str(self) + + def __mod__(self, symbols): + if self.is_copy: + return lazyT(self) + return lazyT(self.m, symbols, self.T, self.f, self.t, self.M) + + +def pickle_lazyT(c): + return str, (c.xml(),) + +copyreg.pickle(lazyT, pickle_lazyT) + + +class translator(object): + """ + This class is instantiated by gluon.compileapp.build_environment + as the T object + + Example: + + T.force(None) # turns off translation + T.force('fr, it') # forces web2py to translate using fr.py or it.py + + T("Hello World") # translates "Hello World" using the selected file + + Note: + - there is no need to force since, by default, T uses + http_accept_language to determine a translation file. + - en and en-en are considered different languages! + - if language xx-yy is not found force() probes other similar languages + using such algorithm: `xx-yy.py -> xx.py -> xx-yy*.py -> xx*.py` + """ + + def __init__(self, langpath, http_accept_language): + self.langpath = langpath + self.http_accept_language = http_accept_language + # filled in self.force(): + # ------------------------ + # self.cache + # self.accepted_language + # self.language_file + # self.plural_language + # self.nplurals + # self.get_plural_id + # self.construct_plural_form + # self.plural_file + # self.plural_dict + # self.requested_languages + # ---------------------------------------- + # filled in self.set_current_languages(): + # ---------------------------------------- + # self.default_language_file + # self.default_t + # self.current_languages + self.set_current_languages() + self.lazy = True + self.otherTs = {} + self.filter = markmin + self.ftag = 'markmin' + self.ns = None + self.is_writable = True + + def get_possible_languages_info(self, lang=None): + """ + Returns info for selected language or dictionary with all + possible languages info from `APP/languages/*.py` + It Returns: + + - a tuple containing:: + + langcode, langname, langfile_mtime, + pluraldict_fname, pluraldict_mtime, + prules_langcode, nplurals, + get_plural_id, construct_plural_form + + or None + + - if *lang* is NOT defined a dictionary with all possible + languages:: + + { langcode(from filename): + ( langcode, # language code from !langcode! + langname, + # language name in national spelling from !langname! + langfile_mtime, # m_time of language file + pluraldict_fname,# name of plural dictionary file or None (when default.py is not exist) + pluraldict_mtime,# m_time of plural dictionary file or 0 if file is not exist + prules_langcode, # code of plural rules language or 'default' + nplurals, # nplurals for current language + get_plural_id, # get_plural_id() for current language + construct_plural_form) # construct_plural_form() for current language + } + + Args: + lang (str): language + + """ + info = read_possible_languages(self.langpath) + if lang: + info = info.get(lang) + return info + + def get_possible_languages(self): + """ Gets list of all possible languages for current application """ + return list(set(self.current_languages + + [lang for lang in read_possible_languages(self.langpath) + if lang != 'default'])) + + def set_current_languages(self, *languages): + """ + Sets current AKA "default" languages + Setting one of this languages makes the force() function to turn + translation off + """ + if len(languages) == 1 and isinstance(languages[0], (tuple, list)): + languages = languages[0] + if not languages or languages[0] is None: + # set default language from default.py/DEFAULT_LANGUAGE + pl_info = self.get_possible_languages_info('default') + if pl_info[2] == 0: # langfile_mtime + # if languages/default.py is not found + self.default_language_file = self.langpath + self.default_t = {} + self.current_languages = [DEFAULT_LANGUAGE] + else: + self.default_language_file = pjoin(self.langpath, + 'default.py') + self.default_t = read_dict(self.default_language_file) + self.current_languages = [pl_info[0]] # !langcode! + else: + self.current_languages = list(languages) + self.force(self.http_accept_language) + + def plural(self, word, n): + """ + Gets plural form of word for number *n* + invoked from T()/T.M() in `%%{}` tag + + Note: + "word" MUST be defined in current language (T.accepted_language) + + Args: + word (str): word in singular + n (numeric): number plural form created for + + Returns: + word (str): word in appropriate singular/plural form + + """ + if int(n) == 1: + return word + elif word: + id = self.get_plural_id(abs(int(n))) + # id = 0 singular form + # id = 1 first plural form + # id = 2 second plural form + # etc. + if id != 0: + forms = self.plural_dict.get(word, []) + if len(forms) >= id: + # have this plural form: + return forms[id - 1] + else: + # guessing this plural form + forms += [''] * (self.nplurals - len(forms) - 1) + form = self.construct_plural_form(word, id) + forms[id - 1] = form + self.plural_dict[word] = forms + if self.is_writable and is_writable() and self.plural_file: + write_plural_dict(self.plural_file, + self.plural_dict) + return form + return word + + def force(self, *languages): + """ + Selects language(s) for translation + + if a list of languages is passed as a parameter, + the first language from this list that matches the ones + from the possible_languages dictionary will be + selected + + default language will be selected if none + of them matches possible_languages. + """ + pl_info = read_possible_languages(self.langpath) + def set_plural(language): + """ + initialize plural forms subsystem + """ + lang_info = pl_info.get(language) + if lang_info: + (pname, + pmtime, + self.plural_language, + self.nplurals, + self.get_plural_id, + self.construct_plural_form + ) = lang_info[3:] + pdict = {} + if pname: + pname = pjoin(self.langpath, pname) + if pmtime != 0: + pdict = read_plural_dict(pname) + self.plural_file = pname + self.plural_dict = pdict + else: + self.plural_language = 'default' + self.nplurals = DEFAULT_NPLURALS + self.get_plural_id = DEFAULT_GET_PLURAL_ID + self.construct_plural_form = DEFAULT_CONSTRUCT_PLURAL_FORM + self.plural_file = None + self.plural_dict = {} + language = '' + if len(languages) == 1 and isinstance(languages[0], str): + languages = regex_language.findall(languages[0].lower()) + elif not languages or languages[0] is None: + languages = [] + self.requested_languages = languages = tuple(languages) + if languages: + all_languages = set(lang for lang in pl_info + if lang != 'default') \ + | set(self.current_languages) + for lang in languages: + # compare "aa-bb" | "aa" from *language* parameter + # with strings from langlist using such alghorythm: + # xx-yy.py -> xx.py -> xx*.py + lang5 = lang[:5] + if lang5 in all_languages: + language = lang5 + else: + lang2 = lang[:2] + if len(lang5) > 2 and lang2 in all_languages: + language = lang2 + else: + for l in all_languages: + if l[:2] == lang2: + language = l + if language: + if language in self.current_languages: + break + self.language_file = pjoin(self.langpath, language + '.py') + self.t = read_dict(self.language_file) + self.cache = global_language_cache.setdefault( + self.language_file, + ({}, RLock())) + set_plural(language) + self.accepted_language = language + return languages + self.accepted_language = language + if not language: + if self.current_languages: + self.accepted_language = self.current_languages[0] + else: + self.accepted_language = DEFAULT_LANGUAGE + self.language_file = self.default_language_file + self.cache = global_language_cache.setdefault(self.language_file, + ({}, RLock())) + self.t = self.default_t + set_plural(self.accepted_language) + return languages + + def __call__(self, message, symbols={}, language=None, lazy=None, ns=None): + """ + get cached translated plain text message with inserted parameters(symbols) + if lazy==True lazyT object is returned + """ + if lazy is None: + lazy = self.lazy + if not language and not ns: + if lazy: + return lazyT(message, symbols, self) + else: + return self.translate(message, symbols) + else: + if ns: + if ns != self.ns: + self.langpath = os.path.join(self.langpath, ns) + if self.ns is None: + self.ns = ns + otherT = self.__get_otherT__(language, ns) + return otherT(message, symbols, lazy=lazy) + + def __get_otherT__(self, language=None, namespace=None): + if not language and not namespace: + raise Exception('Incorrect parameters') + + if namespace: + if language: + index = '%s/%s' % (namespace, language) + else: + index = namespace + else: + index = language + try: + otherT = self.otherTs[index] + except KeyError: + otherT = self.otherTs[index] = translator(self.langpath, + self.http_accept_language) + if language: + otherT.force(language) + return otherT + + def apply_filter(self, message, symbols={}, filter=None, ftag=None): + def get_tr(message, prefix, filter): + s = self.get_t(message, prefix) + return filter(s) if filter else self.filter(s) + if filter: + prefix = '@' + (ftag or 'userdef') + '\x01' + else: + prefix = '@' + self.ftag + '\x01' + message = get_from_cache( + self.cache, prefix + message, + lambda: get_tr(message, prefix, filter)) + if symbols or symbols == 0 or symbols == "": + if isinstance(symbols, dict): + symbols.update( + (key, xmlescape(value).translate(ttab_in)) + for key, value in iteritems(symbols) + if not isinstance(value, NUMBERS)) + else: + if not isinstance(symbols, tuple): + symbols = (symbols,) + symbols = tuple( + value if isinstance(value, NUMBERS) + else to_native(xmlescape(value)).translate(ttab_in) + for value in symbols) + message = self.params_substitution(message, symbols) + return to_native(XML(message.translate(ttab_out)).xml()) + + def M(self, message, symbols={}, language=None, + lazy=None, filter=None, ftag=None, ns=None): + """ + Gets cached translated markmin-message with inserted parametes + if lazy==True lazyT object is returned + """ + if lazy is None: + lazy = self.lazy + if not language and not ns: + if lazy: + return lazyT(message, symbols, self, filter, ftag, True) + else: + return self.apply_filter(message, symbols, filter, ftag) + else: + if ns: + self.langpath = os.path.join(self.langpath, ns) + otherT = self.__get_otherT__(language, ns) + return otherT.M(message, symbols, lazy=lazy) + + def get_t(self, message, prefix=''): + """ + Use ## to add a comment into a translation string + the comment can be useful do discriminate different possible + translations for the same string (for example different locations): + + T(' hello world ') -> ' hello world ' + T(' hello world ## token') -> ' hello world ' + T('hello ## world## token') -> 'hello ## world' + + the ## notation is ignored in multiline strings and strings that + start with ##. This is needed to allow markmin syntax to be translated + """ + message = to_native(message, 'utf8') + prefix = to_native(prefix, 'utf8') + key = prefix + message + mt = self.t.get(key, None) + if mt is not None: + return mt + # we did not find a translation + if message.find('##') > 0: + pass + if message.find('##') > 0 and not '\n' in message: + # remove comments + message = message.rsplit('##', 1)[0] + # guess translation same as original + self.t[key] = mt = self.default_t.get(key, message) + # update language file for latter translation + if self.is_writable and is_writable() and \ + self.language_file != self.default_language_file: + write_dict(self.language_file, self.t) + return regex_backslash.sub( + lambda m: m.group(1).translate(ttab_in), to_native(mt)) + + def params_substitution(self, message, symbols): + """ + Substitutes parameters from symbols into message using %. + also parse `%%{}` placeholders for plural-forms processing. + + Returns: + string with parameters + + Note: + *symbols* MUST BE OR tuple OR dict of parameters! + """ + def sub_plural(m): + """String in `%{}` is transformed by this rules: + If string starts with `!` or `?` such transformations + take place: + + "!string of words" -> "String of word" (Capitalize) + "!!string of words" -> "String Of Word" (Title) + "!!!string of words" -> "STRING OF WORD" (Upper) + + "?word1?number" -> "word1" or "number" + (return word1 if number == 1, + return number otherwise) + "??number" or "?number" -> "" or "number" + (as above with word1 = "") + + "?word1?number?word0" -> "word1" or "number" or "word0" + (return word1 if number == 1, + return word0 if number == 0, + return number otherwise) + "?word1?number?" -> "word1" or "number" or "" + (as above with word0 = "") + "??number?word0" -> "number" or "word0" + (as above with word1 = "") + "??number?" -> "number" or "" + (as above with word1 = word0 = "") + + "?word1?word[number]" -> "word1" or "word" + (return word1 if symbols[number] == 1, + return word otherwise) + "?word1?[number]" -> "" or "word1" + (as above with word = "") + "??word[number]" or "?word[number]" -> "" or "word" + (as above with word1 = "") + + "?word1?word?word0[number]" -> "word1" or "word" or "word0" + (return word1 if symbols[number] == 1, + return word0 if symbols[number] == 0, + return word otherwise) + "?word1?word?[number]" -> "word1" or "word" or "" + (as above with word0 = "") + "??word?word0[number]" -> "" or "word" or "word0" + (as above with word1 = "") + "??word?[number]" -> "" or "word" + (as above with word1 = word0 = "") + + Other strings, (those not starting with `!` or `?`) + are processed by self.plural + """ + def sub_tuple(m): + """ word + !word, !!word, !!!word + ?word1?number + ??number, ?number + ?word1?number?word0 + ?word1?number? + ??number?word0 + ??number? + + word[number] + !word[number], !!word[number], !!!word[number] + ?word1?word[number] + ?word1?[number] + ??word[number], ?word[number] + ?word1?word?word0[number] + ?word1?word?[number] + ??word?word0[number] + ??word?[number] + """ + w, i = m.group('w', 'i') + c = w[0] + if c not in '!?': + return self.plural(w, symbols[int(i or 0)]) + elif c == '?': + (p1, sep, p2) = w[1:].partition("?") + part1 = p1 if sep else "" + (part2, sep, part3) = (p2 if sep else p1).partition("?") + if not sep: + part3 = part2 + if i is None: + # ?[word]?number[?number] or ?number + if not part2: + return m.group(0) + num = int(part2) + else: + # ?[word1]?word[?word0][number] + num = int(symbols[int(i or 0)]) + return part1 if num == 1 else part3 if num == 0 else part2 + elif w.startswith('!!!'): + word = w[3:] + fun = upper_fun + elif w.startswith('!!'): + word = w[2:] + fun = title_fun + else: + word = w[1:] + fun = cap_fun + if i is not None: + return fun(self.plural(word, symbols[int(i)])) + return fun(word) + + def sub_dict(m): + """ word(key or num) + !word(key or num), !!word(key or num), !!!word(key or num) + ?word1?word(key or num) + ??word(key or num), ?word(key or num) + ?word1?word?word0(key or num) + ?word1?word?(key or num) + ??word?word0(key or num) + ?word1?word?(key or num) + ??word?(key or num), ?word?(key or num) + """ + w, n = m.group('w', 'n') + c = w[0] + n = int(n) if n.isdigit() else symbols[n] + if c not in '!?': + return self.plural(w, n) + elif c == '?': + # ?[word1]?word[?word0](key or num), ?[word1]?word(key or num) or ?word(key or num) + (p1, sep, p2) = w[1:].partition("?") + part1 = p1 if sep else "" + (part2, sep, part3) = (p2 if sep else p1).partition("?") + if not sep: + part3 = part2 + num = int(n) + return part1 if num == 1 else part3 if num == 0 else part2 + elif w.startswith('!!!'): + word = w[3:] + fun = upper_fun + elif w.startswith('!!'): + word = w[2:] + fun = title_fun + else: + word = w[1:] + fun = cap_fun + s = fun(self.plural(word, n)) + return s if PY2 else to_unicode(s) + + s = m.group(1) + part = regex_plural_tuple.sub(sub_tuple, s) + if part == s: + part = regex_plural_dict.sub(sub_dict, s) + if part == s: + return m.group(0) + return part + message = message % symbols + message = regex_plural.sub(sub_plural, message) + return message + + def translate(self, message, symbols): + """ + Gets cached translated message with inserted parameters(symbols) + """ + message = get_from_cache(self.cache, message, + lambda: self.get_t(message)) + if symbols or symbols == 0 or symbols == "": + if isinstance(symbols, dict): + symbols.update( + (key, str(value).translate(ttab_in)) + for key, value in iteritems(symbols) + if not isinstance(value, NUMBERS)) + else: + if not isinstance(symbols, tuple): + symbols = (symbols,) + symbols = tuple( + value if isinstance(value, NUMBERS) + else str(value).translate(ttab_in) + for value in symbols) + message = self.params_substitution(message, symbols) + return message.translate(ttab_out) + + +def findT(path, language=DEFAULT_LANGUAGE): + """ + Note: + Must be run by the admin app + """ + from gluon.tools import Auth, Crud + lang_file = pjoin(path, 'languages', language + '.py') + sentences = read_dict(lang_file) + mp = pjoin(path, 'models') + cp = pjoin(path, 'controllers') + vp = pjoin(path, 'views') + mop = pjoin(path, 'modules') + def add_message(message): + if not message.startswith('#') and not '\n' in message: + tokens = message.rsplit('##', 1) + else: + # this allows markmin syntax in translations + tokens = [message] + if len(tokens) == 2: + message = tokens[0].strip() + '##' + tokens[1].strip() + if message and not message in sentences: + sentences[message] = message.replace("@markmin\x01", "") + for filename in \ + listdir(mp, '^.+\.py$', 0) + listdir(cp, '^.+\.py$', 0)\ + + listdir(vp, '^.+\.html$', 0) + listdir(mop, '^.+\.py$', 0): + data = to_native(read_locked(filename)) + items = regex_translate.findall(data) + for x in regex_translate_m.findall(data): + if x[0:3] in ["'''", '"""']: items.append("%s@markmin\x01%s" %(x[0:3], x[3:])) + else: items.append("%s@markmin\x01%s" %(x[0], x[1:])) + for item in items: + try: + message = safe_eval(item) + except: + continue # silently ignore inproperly formatted strings + add_message(message) + gluon_msg = [Auth.default_messages, Crud.default_messages] + for item in [x for m in gluon_msg for x in m.values() if x is not None]: + add_message(item) + if not '!langcode!' in sentences: + sentences['!langcode!'] = ( + DEFAULT_LANGUAGE if language in ('default', DEFAULT_LANGUAGE) else language) + if not '!langname!' in sentences: + sentences['!langname!'] = ( + DEFAULT_LANGUAGE_NAME if language in ('default', DEFAULT_LANGUAGE) + else sentences['!langcode!']) + write_dict(lang_file, sentences) + + +def update_all_languages(application_path): + """ + Note: + Must be run by the admin app + """ + path = pjoin(application_path, 'languages/') + for language in oslistdir(path): + if regex_langfile.match(language): + findT(application_path, language[:-3]) + + +def update_from_langfile(target, source, force_update=False): + """this will update untranslated messages in target from source (where both are language files) + this can be used as first step when creating language file for new but very similar language + or if you want update your app from welcome app of newer web2py version + or in non-standard scenarios when you work on target and from any reason you have partial translation in source + Args: + force_update: if False existing translations remain unchanged, if True existing translations will update from source + """ + src = read_dict(source) + sentences = read_dict(target) + for key in sentences: + val = sentences[key] + if not val or val == key or force_update: + new_val = src.get(key) + if new_val and new_val != val: + sentences[key] = new_val + write_dict(target, sentences) + + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/web2py/gluon/main.py b/web2py/gluon/main.py new file mode 100644 index 0000000..9867c87 --- /dev/null +++ b/web2py/gluon/main.py @@ -0,0 +1,796 @@ +#!/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +The gluon wsgi application +--------------------------- +""" +from __future__ import print_function + +if False: + import import_all # DO NOT REMOVE PART OF FREEZE PROCESS +import gc + +import os +import re +import copy +import sys +import time +import datetime +import signal +import socket +import random +import string + +from gluon._compat import Cookie, urllib2 +# from thread import allocate_lock + +from gluon.fileutils import abspath, write_file +from gluon.settings import global_settings +from gluon.utils import web2py_uuid +from gluon.admin import add_path_first, create_missing_folders, create_missing_app_folders +from gluon.globals import current + +# Remarks: +# calling script has inserted path to script directory into sys.path +# applications_parent (path to applications/, site-packages/ etc) +# defaults to that directory set sys.path to +# ("", gluon_parent/site-packages, gluon_parent, ...) +# +# this is wrong: +# web2py_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +# because we do not want the path to this file which may be Library.zip +# gluon_parent is the directory containing gluon, web2py.py, logging.conf +# and the handlers. +# applications_parent (web2py_path) is the directory containing applications/ +# and routes.py +# The two are identical unless web2py_path is changed via the web2py.py -f folder option +# main.web2py_path is the same as applications_parent (for backward compatibility) + +web2py_path = global_settings.applications_parent # backward compatibility + +create_missing_folders() + +# set up logging for subsequent imports +import logging +import logging.config + +# This needed to prevent exception on Python 2.5: +# NameError: name 'gluon' is not defined +# See http://bugs.python.org/issue1436 + +# attention!, the import Tkinter in messageboxhandler, changes locale ... +import gluon.messageboxhandler +logging.gluon = gluon +# so we must restore it! Thanks ozancag +import locale +locale.setlocale(locale.LC_CTYPE, "C") # IMPORTANT, web2py requires locale "C" + +exists = os.path.exists +pjoin = os.path.join + +try: + logging.config.fileConfig(abspath("logging.conf")) +except: # fails on GAE or when logfile is missing + logging.basicConfig() +logger = logging.getLogger("web2py") + +from gluon.restricted import RestrictedError +from gluon.http import HTTP, redirect +from gluon.globals import Request, Response, Session +from gluon.compileapp import build_environment, run_models_in, \ + run_controller_in, run_view_in +from gluon.contenttype import contenttype +from pydal.base import BaseAdapter +from gluon.validators import CRYPT +from gluon.html import URL, xmlescape +from gluon.utils import is_valid_ip_address, getipaddrinfo +from gluon.rewrite import load as load_routes, url_in, THREAD_LOCAL as rwthread, \ + try_rewrite_on_error, fixup_missing_path_info +from gluon import newcron + +__all__ = ['wsgibase', 'save_password', 'appfactory', 'HttpServer'] + +requests = 0 # gc timer + +# Security Checks: validate URL and session_id here, +# accept_language is validated in languages + +# pattern used to validate client address +regex_client = re.compile('[\w\-:]+(\.[\w\-]+)*\.?') # ## to account for IPV6 + +try: + version_info = open(pjoin(global_settings.gluon_parent, 'VERSION'), 'r') + raw_version_string = version_info.read().split()[-1].strip() + version_info.close() + global_settings.web2py_version = raw_version_string + web2py_version = global_settings.web2py_version +except: + raise RuntimeError("Cannot determine web2py version") + +try: + from gluon import rocket +except: + if not global_settings.web2py_runtime_gae: + logger.warn('unable to import Rocket') + +load_routes() + +HTTPS_SCHEMES = set(('https', 'HTTPS')) + + +def get_client(env): + """ + Guesses the client address from the environment variables + + First tries 'http_x_forwarded_for', secondly 'remote_addr' + if all fails, assume '127.0.0.1' or '::1' (running locally) + """ + eget = env.get + g = regex_client.search(eget('http_x_forwarded_for', '')) + client = (g.group() or '').split(',')[0] if g else None + if client in (None, '', 'unknown'): + g = regex_client.search(eget('remote_addr', '')) + if g: + client = g.group() + elif env.http_host.startswith('['): # IPv6 + client = '::1' + else: + client = '127.0.0.1' # IPv4 + if not is_valid_ip_address(client): + raise HTTP(400, "Bad Request (request.client=%s)" % client) + return client + + +def serve_controller(request, response, session): + """ + This function is used to generate a dynamic page. + It first runs all models, then runs the function in the controller, + and then tries to render the output using a view/template. + this function must run from the [application] folder. + A typical example would be the call to the url + /[application]/[controller]/[function] that would result in a call + to [function]() in applications/[application]/[controller].py + rendered by applications/[application]/views/[controller]/[function].html + """ + + # ################################################## + # build environment for controller and view + # ################################################## + + environment = build_environment(request, response, session) + + # set default view, controller can override it + + response.view = '%s/%s.%s' % (request.controller, + request.function, + request.extension) + + # also, make sure the flash is passed through + # ################################################## + # process models, controller and view (if required) + # ################################################## + + run_models_in(environment) + response._view_environment = copy.copy(environment) + page = run_controller_in(request.controller, request.function, environment) + if isinstance(page, dict): + response._vars = page + response._view_environment.update(page) + page = run_view_in(response._view_environment) + + if not request.env.web2py_disable_garbage_collect: + # logic to garbage collect after exec, not always, once every 100 requests + global requests + requests = ('requests' in globals()) and (requests + 1) % 100 or 0 + if not requests: + gc.collect() + # end garbage collection logic + + # ################################################## + # set default headers it not set + # ################################################## + + default_headers = [ + ('Content-Type', contenttype('.' + request.extension)), + ('Cache-Control', + 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'), + ('Expires', time.strftime('%a, %d %b %Y %H:%M:%S GMT', + time.gmtime())), + ('Pragma', 'no-cache')] + for key, value in default_headers: + response.headers.setdefault(key, value) + + raise HTTP(response.status, page, **response.headers) + + +class LazyWSGI(object): + def __init__(self, environ, request, response): + self.wsgi_environ = environ + self.request = request + self.response = response + + @property + def environ(self): + if not hasattr(self, '_environ'): + new_environ = self.wsgi_environ + new_environ['wsgi.input'] = self.request.body + new_environ['wsgi.version'] = 1 + self._environ = new_environ + return self._environ + + def start_response(self, status='200', headers=[], exec_info=None): + """ + in controller you can use: + + - request.wsgi.environ + - request.wsgi.start_response + + to call third party WSGI applications + """ + self.response.status = int(str(status).split(' ', 1)[0]) + self.response.headers = dict(headers) + return lambda *args, **kargs: \ + self.response.write(escape=False, *args, **kargs) + + def middleware(self, *middleware_apps): + """ + In you controller use:: + + @request.wsgi.middleware(middleware1, middleware2, ...) + + to decorate actions with WSGI middleware. actions must return strings. + uses a simulated environment so it may have weird behavior in some cases + """ + def middleware(f): + def app(environ, start_response): + data = f() + start_response(self.response.status, + self.response.headers.items()) + if isinstance(data, list): + return data + return [data] + for item in middleware_apps: + app = item(app) + + def caller(app): + return app(self.environ, self.start_response) + return lambda caller=caller, app=app: caller(app) + return middleware + + +def wsgibase(environ, responder): + """ + The gluon wsgi application. The first function called when a page + is requested (static or dynamic). It can be called by paste.httpserver + or by apache mod_wsgi (or any WSGI-compatible server). + + - fills request with info + - the environment variables, replacing '.' with '_' + - adds web2py path and version info + - compensates for fcgi missing path_info and query_string + - validates the path in url + + The url path must be either: + + 1. for static pages: + + - //static/ + + 2. for dynamic pages: + + - /[/[/[/]]][.] + + The naming conventions are: + + - application, controller, function and extension may only contain + `[a-zA-Z0-9_]` + - file and sub may also contain '-', '=', '.' and '/' + """ + eget = environ.get + current.__dict__.clear() + request = Request(environ) + response = Response() + session = Session() + env = request.env + # env.web2py_path = global_settings.applications_parent + env.web2py_version = web2py_version + # env.update(global_settings) + static_file = False + http_response = None + try: + try: + try: + # ################################################## + # handle fcgi missing path_info and query_string + # select rewrite parameters + # rewrite incoming URL + # parse rewritten header variables + # parse rewritten URL + # serve file if static + # ################################################## + + fixup_missing_path_info(environ) + (static_file, version, environ) = url_in(request, environ) + response.status = env.web2py_status_code or response.status + + if static_file: + if eget('QUERY_STRING', '').startswith('attachment'): + response.headers['Content-Disposition'] \ + = 'attachment' + if version: + response.headers['Cache-Control'] = 'max-age=315360000' + response.headers[ + 'Expires'] = 'Thu, 31 Dec 2037 23:59:59 GMT' + response.stream(static_file, request=request) + + # ################################################## + # fill in request items + # ################################################## + app = request.application # must go after url_in! + + if not global_settings.local_hosts: + local_hosts = set(['127.0.0.1', '::ffff:127.0.0.1', '::1']) + if not global_settings.web2py_runtime_gae: + try: + fqdn = socket.getfqdn() + local_hosts.add(socket.gethostname()) + local_hosts.add(fqdn) + local_hosts.update([ + addrinfo[4][0] for addrinfo + in getipaddrinfo(fqdn)]) + if env.server_name: + local_hosts.add(env.server_name) + local_hosts.update([ + addrinfo[4][0] for addrinfo + in getipaddrinfo(env.server_name)]) + except (socket.gaierror, TypeError): + pass + global_settings.local_hosts = list(local_hosts) + else: + local_hosts = global_settings.local_hosts + client = get_client(env) + x_req_with = str(env.http_x_requested_with).lower() + cmd_opts = global_settings.cmd_options + + request.update( + client=client, + folder=abspath('applications', app) + os.sep, + ajax=x_req_with == 'xmlhttprequest', + cid=env.http_web2py_component_element, + is_local=(env.remote_addr in local_hosts and client == env.remote_addr), + is_shell=False, + is_scheduler=False, + is_https=env.wsgi_url_scheme in HTTPS_SCHEMES or + request.env.http_x_forwarded_proto in HTTPS_SCHEMES or env.https == 'on' + ) + request.url = environ['PATH_INFO'] + + # ################################################## + # access the requested application + # ################################################## + + disabled = pjoin(request.folder, 'DISABLED') + if not exists(request.folder): + if app == rwthread.routes.default_application \ + and app != 'welcome': + redirect(URL('welcome', 'default', 'index')) + elif rwthread.routes.error_handler: + _handler = rwthread.routes.error_handler + redirect(URL(_handler['application'], + _handler['controller'], + _handler['function'], + args=app)) + else: + raise HTTP(404, rwthread.routes.error_message + % 'invalid request', + web2py_error='invalid application') + elif not request.is_local and exists(disabled): + five0three = os.path.join(request.folder, 'static', '503.html') + if os.path.exists(five0three): + raise HTTP(503, open(five0three, 'r').read()) + else: + raise HTTP(503, "

    Temporarily down for maintenance

    ") + + # ################################################## + # build missing folders + # ################################################## + + create_missing_app_folders(request) + + # ################################################## + # get the GET and POST data + # ################################################## + + # parse_get_post_vars(request, environ) + + # ################################################## + # expose wsgi hooks for convenience + # ################################################## + + request.wsgi = LazyWSGI(environ, request, response) + + # ################################################## + # load cookies + # ################################################## + + if env.http_cookie: + for single_cookie in env.http_cookie.split(';'): + single_cookie = single_cookie.strip() + if single_cookie: + try: + request.cookies.load(single_cookie) + except Cookie.CookieError: + pass # single invalid cookie ignore + + # ################################################## + # try load session or create new session file + # ################################################## + + if not env.web2py_disable_session: + session.connect(request, response) + + # ################################################## + # run controller + # ################################################## + + if global_settings.debugging and app != "admin": + import gluon.debug + # activate the debugger + gluon.debug.dbg.do_debug(mainpyfile=request.folder) + + serve_controller(request, response, session) + except HTTP as hr: + http_response = hr + + if static_file: + return http_response.to(responder, env=env) + + if request.body: + request.body.close() + + if hasattr(current, 'request'): + + # ################################################## + # on success, try store session in database + # ################################################## + if not env.web2py_disable_session: + session._try_store_in_db(request, response) + + # ################################################## + # on success, commit database + # ################################################## + + if response.do_not_commit is True: + BaseAdapter.close_all_instances(None) + elif response.custom_commit: + BaseAdapter.close_all_instances(response.custom_commit) + else: + BaseAdapter.close_all_instances('commit') + + # ################################################## + # if session not in db try store session on filesystem + # this must be done after trying to commit database! + # ################################################## + if not env.web2py_disable_session: + session._try_store_in_cookie_or_file(request, response) + + # Set header so client can distinguish component requests. + if request.cid: + http_response.headers.setdefault( + 'web2py-component-content', 'replace') + + if request.ajax: + if response.flash: + http_response.headers['web2py-component-flash'] = \ + urllib2.quote(xmlescape(response.flash).replace(b'\n', b'')) + if response.js: + http_response.headers['web2py-component-command'] = \ + urllib2.quote(response.js.replace('\n', '')) + + # ################################################## + # store cookies in headers + # ################################################## + + session._fixup_before_save() + http_response.cookies2headers(response.cookies) + + ticket = None + + except RestrictedError as e: + + if request.body: + request.body.close() + + # ################################################## + # on application error, rollback database + # ################################################## + + # log tickets before rollback if not in DB + if not request.tickets_db: + ticket = e.log(request) or 'unknown' + # rollback + if response._custom_rollback: + response._custom_rollback() + else: + BaseAdapter.close_all_instances('rollback') + # if tickets in db, reconnect and store it in db + if request.tickets_db: + ticket = e.log(request) or 'unknown' + + http_response = \ + HTTP(500, rwthread.routes.error_message_ticket % + dict(ticket=ticket), + web2py_error='ticket %s' % ticket) + + except: + + if request.body: + request.body.close() + + # ################################################## + # on application error, rollback database + # ################################################## + + try: + if response._custom_rollback: + response._custom_rollback() + else: + BaseAdapter.close_all_instances('rollback') + except: + pass + e = RestrictedError('Framework', '', '', locals()) + ticket = e.log(request) or 'unrecoverable' + http_response = \ + HTTP(500, rwthread.routes.error_message_ticket + % dict(ticket=ticket), + web2py_error='ticket %s' % ticket) + + finally: + if response and hasattr(response, 'session_file') \ + and response.session_file: + response.session_file.close() + + session._unlock(response) + http_response, new_environ = try_rewrite_on_error( + http_response, request, environ, ticket) + if not http_response: + return wsgibase(new_environ, responder) + if global_settings.web2py_crontype == 'soft': + newcron.softcron(global_settings.applications_parent).start() + return http_response.to(responder, env=env) + + +def save_password(password, port): + """ + Used by main() to save the password in the parameters_port.py file. + """ + + password_file = abspath('parameters_%i.py' % port) + if password == '': + # make up a new password + chars = string.letters + string.digits + password = ''.join([random.choice(chars) for _ in range(8)]) + cpassword = CRYPT()(password)[0] + print('******************* IMPORTANT!!! ************************') + print('your admin password is "%s"' % password) + print('*********************************************************') + elif password == '': + # reuse the current password if any + if exists(password_file): + return + else: + password = '' + elif password.startswith(' +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +Useful regexes +--------------- +""" + +import re + +# pattern to find defined tables + +regex_tables = re.compile( + """^[\w]+\.define_table\(\s*[\'\"](?P\w+)[\'\"]""", + flags=re.M) + +# pattern to find exposed functions in controller + +regex_expose = re.compile( + '^def\s+(?P_?[a-zA-Z0-9]\w*)\( *\)\s*:', + flags=re.M) + +regex_longcomments = re.compile('(""".*?"""|'+"'''.*?''')", re.DOTALL) + +regex_include = re.compile( + '(?P\{\{\s*include\s+[\'"](?P[^\'"]*)[\'"]\s*\}\})') + +regex_extend = re.compile( + '^\s*(?P\{\{\s*extend\s+[\'"](?P[^\'"]+)[\'"]\s*\}\})', re.MULTILINE) diff --git a/web2py/gluon/newcron.py b/web2py/gluon/newcron.py new file mode 100644 index 0000000..d53ecbe --- /dev/null +++ b/web2py/gluon/newcron.py @@ -0,0 +1,386 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Created by Attila Csipa +| Modified by Massimo Di Pierro +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +Cron-style interface +""" + +import sys +import os +import threading +import logging +import time +import sched +import re +import datetime +import platform +from functools import reduce +try: + import cPickle as pickle +except: + import pickle +from gluon.settings import global_settings +from gluon import fileutils +from gluon._compat import to_bytes +from pydal.contrib import portalocker + +logger = logging.getLogger("web2py.cron") +_cron_stopping = False +_cron_subprocs = [] + + +def absolute_path_link(path): + """ + Returns an absolute path for the destination of a symlink + + """ + if os.path.islink(path): + link = os.readlink(path) + if not os.path.isabs(link): + link = os.path.join(os.path.dirname(path), link) + else: + link = os.path.abspath(path) + return link + + +def stopcron(): + """Graceful shutdown of cron""" + global _cron_stopping + _cron_stopping = True + while _cron_subprocs: + proc = _cron_subprocs.pop() + if proc.poll() is None: + try: + proc.terminate() + except: + import traceback + traceback.print_exc() + + +class extcron(threading.Thread): + + def __init__(self, applications_parent, apps=None): + threading.Thread.__init__(self) + self.setDaemon(False) + self.path = applications_parent + self.apps = apps + # crondance(self.path, 'external', startup=True, apps=self.apps) + + def run(self): + if not _cron_stopping: + logger.debug('external cron invocation') + crondance(self.path, 'external', startup=False, apps=self.apps) + + +class hardcron(threading.Thread): + + def __init__(self, applications_parent): + threading.Thread.__init__(self) + self.setDaemon(True) + self.path = applications_parent + crondance(self.path, 'hard', startup=True) + + def launch(self): + if not _cron_stopping: + logger.debug('hard cron invocation') + crondance(self.path, 'hard', startup=False) + + def run(self): + s = sched.scheduler(time.time, time.sleep) + logger.info('Hard cron daemon started') + while not _cron_stopping: + now = time.time() + s.enter(60 - now % 60, 1, self.launch, ()) + s.run() + + +class softcron(threading.Thread): + + def __init__(self, applications_parent): + threading.Thread.__init__(self) + self.path = applications_parent + # crondance(self.path, 'soft', startup=True) + + def run(self): + if not _cron_stopping: + logger.debug('soft cron invocation') + crondance(self.path, 'soft', startup=False) + + +class Token(object): + + def __init__(self, path): + self.path = os.path.join(path, 'cron.master') + if not os.path.exists(self.path): + fileutils.write_file(self.path, to_bytes(''), 'wb') + self.master = None + self.now = time.time() + + def acquire(self, startup=False): + """ + Returns the time when the lock is acquired or + None if cron already running + + lock is implemented by writing a pickle (start, stop) in cron.master + start is time when cron job starts and stop is time when cron completed + stop == 0 if job started but did not yet complete + if a cron job started within less than 60 seconds, acquire returns None + if a cron job started before 60 seconds and did not stop, + a warning is issue "Stale cron.master detected" + """ + if sys.platform == 'win32': + locktime = 59.5 + else: + locktime = 59.99 + if portalocker.LOCK_EX is None: + logger.warning('WEB2PY CRON: Disabled because no file locking') + return None + self.master = fileutils.open_file(self.path, 'rb+') + try: + ret = None + portalocker.lock(self.master, portalocker.LOCK_EX) + try: + (start, stop) = pickle.load(self.master) + except: + (start, stop) = (0, 1) + if startup or self.now - start > locktime: + ret = self.now + if not stop: + # this happens if previous cron job longer than 1 minute + logger.warning('WEB2PY CRON: Stale cron.master detected') + logger.debug('WEB2PY CRON: Acquiring lock') + self.master.seek(0) + pickle.dump((self.now, 0), self.master) + self.master.flush() + finally: + portalocker.unlock(self.master) + if not ret: + # do this so no need to release + self.master.close() + return ret + + def release(self): + """ + Writes into cron.master the time when cron job was completed + """ + ret = self.master.closed + if not self.master.closed: + portalocker.lock(self.master, portalocker.LOCK_EX) + logger.debug('WEB2PY CRON: Releasing cron lock') + self.master.seek(0) + (start, stop) = pickle.load(self.master) + if start == self.now: # if this is my lock + self.master.seek(0) + pickle.dump((self.now, time.time()), self.master) + portalocker.unlock(self.master) + self.master.close() + return ret + + +def rangetolist(s, period='min'): + retval = [] + if s.startswith('*'): + if period == 'min': + s = s.replace('*', '0-59', 1) + elif period == 'hr': + s = s.replace('*', '0-23', 1) + elif period == 'dom': + s = s.replace('*', '1-31', 1) + elif period == 'mon': + s = s.replace('*', '1-12', 1) + elif period == 'dow': + s = s.replace('*', '0-6', 1) + m = re.compile(r'(\d+)-(\d+)/(\d+)') + match = m.match(s) + if match: + for i in range(int(match.group(1)), int(match.group(2)) + 1): + if i % int(match.group(3)) == 0: + retval.append(i) + return retval + + +def parsecronline(line): + task = {} + if line.startswith('@reboot'): + line = line.replace('@reboot', '-1 * * * *') + elif line.startswith('@yearly'): + line = line.replace('@yearly', '0 0 1 1 *') + elif line.startswith('@annually'): + line = line.replace('@annually', '0 0 1 1 *') + elif line.startswith('@monthly'): + line = line.replace('@monthly', '0 0 1 * *') + elif line.startswith('@weekly'): + line = line.replace('@weekly', '0 0 * * 0') + elif line.startswith('@daily'): + line = line.replace('@daily', '0 0 * * *') + elif line.startswith('@midnight'): + line = line.replace('@midnight', '0 0 * * *') + elif line.startswith('@hourly'): + line = line.replace('@hourly', '0 * * * *') + params = line.strip().split(None, 6) + if len(params) < 7: + return None + daysofweek = {'sun': 0, 'mon': 1, 'tue': 2, 'wed': 3, + 'thu': 4, 'fri': 5, 'sat': 6} + for (s, id) in zip(params[:5], ['min', 'hr', 'dom', 'mon', 'dow']): + if not s in [None, '*']: + task[id] = [] + vals = s.split(',') + for val in vals: + if val != '-1' and '-' in val and '/' not in val: + val = '%s/1' % val + if '/' in val: + task[id] += rangetolist(val, id) + elif val.isdigit() or val == '-1': + task[id].append(int(val)) + elif id == 'dow' and val[:3].lower() in daysofweek: + task[id].append(daysofweek[val[:3].lower()]) + task['user'] = params[5] + task['cmd'] = params[6] + return task + + +class cronlauncher(threading.Thread): + + def __init__(self, cmd, shell=True): + threading.Thread.__init__(self) + if platform.system() == 'Windows': + shell = False + self.cmd = cmd + self.shell = shell + + def run(self): + import subprocess + global _cron_subprocs + if isinstance(self.cmd, (list, tuple)): + cmd = self.cmd + else: + cmd = self.cmd.split() + proc = subprocess.Popen(cmd, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=self.shell) + _cron_subprocs.append(proc) + (stdoutdata, stderrdata) = proc.communicate() + try: + _cron_subprocs.remove(proc) + except ValueError: + pass + if proc.returncode != 0: + logger.warning( + 'WEB2PY CRON Call returned code %s:\n%s' % + (proc.returncode, stdoutdata + stderrdata)) + else: + logger.debug('WEB2PY CRON Call returned success:\n%s' + % stdoutdata) + + +def crondance(applications_parent, ctype='soft', startup=False, apps=None): + apppath = os.path.join(applications_parent, 'applications') + cron_path = os.path.join(applications_parent) + token = Token(cron_path) + cronmaster = token.acquire(startup=startup) + if not cronmaster: + return + now_s = time.localtime() + checks = (('min', now_s.tm_min), + ('hr', now_s.tm_hour), + ('mon', now_s.tm_mon), + ('dom', now_s.tm_mday), + ('dow', (now_s.tm_wday + 1) % 7)) + + if apps is None: + apps = [x for x in os.listdir(apppath) + if os.path.isdir(os.path.join(apppath, x))] + + full_apath_links = set() + + for app in apps: + if _cron_stopping: + break + apath = os.path.join(apppath, app) + + # if app is a symbolic link to other app, skip it + full_apath_link = absolute_path_link(apath) + if full_apath_link in full_apath_links: + continue + else: + full_apath_links.add(full_apath_link) + + cronpath = os.path.join(apath, 'cron') + crontab = os.path.join(cronpath, 'crontab') + if not os.path.exists(crontab): + continue + try: + cronlines = fileutils.readlines_file(crontab, 'rt') + lines = [x.strip() for x in cronlines if x.strip( + ) and not x.strip().startswith('#')] + tasks = [parsecronline(cline) for cline in lines] + except Exception as e: + logger.error('WEB2PY CRON: crontab read error %s' % e) + continue + + for task in tasks: + if _cron_stopping: + break + if sys.executable.lower().endswith('pythonservice.exe'): + _python_exe = os.path.join(sys.exec_prefix, 'python.exe') + else: + _python_exe = sys.executable + commands = [_python_exe] + w2p_path = fileutils.abspath('web2py.py', gluon=True) + if os.path.exists(w2p_path): + commands.append(w2p_path) + if applications_parent != global_settings.gluon_parent: + commands.extend(('-f', applications_parent)) + citems = [(k in task and not v in task[k]) for k, v in checks] + task_min = task.get('min', []) + if not task: + continue + elif not startup and task_min == [-1]: + continue + elif task_min != [-1] and reduce(lambda a, b: a or b, citems): + continue + logger.info('WEB2PY CRON (%s): %s executing %s in %s at %s' + % (ctype, app, task.get('cmd'), + os.getcwd(), datetime.datetime.now())) + action, command, models = False, task['cmd'], '' + if command.startswith('**'): + (action, models, command) = (True, '', command[2:]) + elif command.startswith('*'): + (action, models, command) = (True, '-M', command[1:]) + else: + action = False + + if action and command.endswith('.py'): + commands.extend(('-J', # cron job + models, # import models? + '-S', app, # app name + '-a', '""', # password + '-R', command)) # command + elif action: + commands.extend(('-J', # cron job + models, # import models? + '-S', app + '/' + command, # app name + '-a', '""')) # password + else: + commands = command + + # from python docs: + # You do not need shell=True to run a batch file or + # console-based executable. + shell = False + + try: + cronlauncher(commands, shell=shell).start() + except Exception as e: + logger.warning( + 'WEB2PY CRON: Execution error for %s: %s' + % (task.get('cmd'), e)) + token.release() diff --git a/web2py/gluon/packages/dal/.codecov.yml b/web2py/gluon/packages/dal/.codecov.yml new file mode 100644 index 0000000..d610978 --- /dev/null +++ b/web2py/gluon/packages/dal/.codecov.yml @@ -0,0 +1,13 @@ +codecov: + branch: master + +coverage: + precision: 2 + round: down + range: "70...100" + + status: + changes: false + +comment: + layout: "header, diff, changes" diff --git a/web2py/gluon/packages/dal/.coveragerc b/web2py/gluon/packages/dal/.coveragerc new file mode 100644 index 0000000..cbce6fd --- /dev/null +++ b/web2py/gluon/packages/dal/.coveragerc @@ -0,0 +1,29 @@ +[run] +branch = True +parallel = True +source = pydal + +[report] +# Regexes for lines to exclude from consideration +exclude_lines = + # Have to re-enable the standard pragma + pragma: no cover + + # Don't complain about missing debug-only code: + def __repr__ + if self\.debug + + # Don't complain if tests don't hit defensive assertion code: + raise AssertionError + raise NotImplementedError + + # Don't complain if non-runnable code isn't run: + if 0: + if __name__ == .__main__.: + +ignore_errors = True +omit = pydal/tests/* + pydal/contrib/* + +[html] +directory = coverage_html_report \ No newline at end of file diff --git a/web2py/gluon/packages/dal/.travis.yml b/web2py/gluon/packages/dal/.travis.yml new file mode 100644 index 0000000..1d37855 --- /dev/null +++ b/web2py/gluon/packages/dal/.travis.yml @@ -0,0 +1,82 @@ +language: python + +sudo: required + +cache: pip + +python: + - '2.7' + - 'pypy' + - 'pypy3' + - '3.4' + - '3.5' + - '3.6' + +install: + - pip install tox>=1.8 + +env: + global: + - PIP_DOWNLOAD_CACHE=$HOME/.pip-cache + matrix: + - ADAPTER=sqlite + - ADAPTER=mysql + - ADAPTER=postgres + - ADAPTER=postgres3 + - ADAPTER=google + - ADAPTER=mongo + +matrix: + exclude: + - python: 'pypy' + env: ADAPTER=postgres + - python: 'pypy' + env: ADAPTER=postgres3 + - python: 'pypy' + env: ADAPTER=google + - python: 'pypy3' + env: ADAPTER=google + - python: 'pypy3' + env: ADAPTER=postgres + - python: 'pypy3' + env: ADAPTER=postgres3 + - python: '3.4' + env: ADAPTER=google + - python: '3.5' + env: ADAPTER=google + - python: '3.6' + env: ADAPTER=google + +before_script: + - if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install codecov; fi + - if [[ $ADAPTER == mongo ]]; then sleep 15; fi; + - if [[ $ADAPTER == mysql ]]; then mysql -e 'create database pydal;'; fi + - if [[ $ADAPTER == postgres* ]]; then psql -c 'create database pydal;' -U postgres; fi + - if [[ $ADAPTER == postgres* ]]; then psql -c 'create extension postgis;' -U postgres -d pydal; fi + - if [[ $ADAPTER == postgres* ]]; then psql -c 'SHOW SERVER_VERSION' -U postgres; fi + + # Install last sdk for app engine (update only whenever a new release is available) + - if [[ $ADAPTER == google ]]; then wget https://storage.googleapis.com/appengine-sdks/featured/google_appengine_1.9.50.zip -nv; fi + - if [[ $ADAPTER == google ]]; then unzip -q google_appengine_1.9.50.zip; fi + - if [[ $ADAPTER == google ]]; then mv -f ./google_appengine/google ./google; fi + + +script: + - if [[ $TRAVIS_PYTHON_VERSION != "2.7" ]]; then tox -e $(echo py$TRAVIS_PYTHON_VERSION | tr -d . | sed -e 's/pypypy/pypy/')-$ADAPTER; fi + - if [[ $TRAVIS_PYTHON_VERSION == "2.7" ]]; then tox -e coverage-$ADAPTER; fi + +after_success: + - if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then codecov; fi + +notifications: + email: true + +services: + - mongodb + - memcached + +addons: + postgresql: "9.4" + apt: + packages: + - postgresql-9.4-postgis-2.3 diff --git a/web2py/gluon/packages/dal/AUTHORS b/web2py/gluon/packages/dal/AUTHORS new file mode 100644 index 0000000..2544296 --- /dev/null +++ b/web2py/gluon/packages/dal/AUTHORS @@ -0,0 +1,10 @@ +- Massimo Di Pierro +- Giovanni Barillari +- Simone Bizzotto +- Paolo Valleri +- Niall Sweeny for MS SQL support +- Marcel Leuthi for Oracle support +- Chris Clark +- clach05 +- Denes Lengyel +- Stephen Rauch diff --git a/web2py/gluon/packages/dal/CHANGES b/web2py/gluon/packages/dal/CHANGES new file mode 100644 index 0000000..3e7f6b1 --- /dev/null +++ b/web2py/gluon/packages/dal/CHANGES @@ -0,0 +1,276 @@ +pyDAL changelog +=============== + +Version 17.11 +------------- + +Released on November 13th 2017 + +- Various bugfixes + + +Version 17.08 +------------- + +Released on August 29th 2017 + +- Various bugfixes + + +Version 17.07 +------------- + +Released on July 4th 2017 + +- Various bugfixes +- Field.set_attributes now returns the instance +- [PostgreSQL] Added jsonb type and serialization/parsing support +- Added unix socket support in MySQL and PostgreSQL adapters +- [GCP] Added MySQL and PostgreSQL support + + +Version 17.03 +------------- + +Released on March 9th 2017 + +- Various bugfixes +- Re-introduced some backward compatibilties dropped with 17.01 +- Added python 3.6 support + + +Version 17.01 +------------- + +Released on January 31st 2017 + +- Several bugfixes +- Introduced "joinable" sub-selects +- Values are now kept between callbacks + + +Version 16.11 +------------- + +Released on November 11th 2016 + +- Avoid possible memory leaks on DAL instance deletion + + +Version 16.09 +------------- + +Released on September 28th 2016 + +- [MongoDB] Enabled query(field==list:reference) +- [PostgreSQL] Several bugfixes +- Improved portalocker behaviour on py3 + + +Version 16.08 +------------- + +Released on August 13th 2016 + +- Various bugfixes + + +Version 16.07 +------------- + +Released on July 26th 2016 + +- Introduced `Rows.join` method +- Minor bugfixes + + +Version 16.06.28 +---------------- + +Released on June 28th 2016 + +- Fixed bugs on MSSQL and Postgre adapters introduced with 16.06 +- Improved parsing performance + + +Version 16.06.20 +---------------- + +Released on June 20th 2016 + +- Fixed bugs introduced with 16.06 + + +Version 16.06.09 +---------------- + +Released on June 9th 2016 + +- Fixed boolean parsing errors on Postgre introduced with 16.06 +- Fixed connection issues on multiprocessing environments with pre-fork +- Added 'postgres3' adapter to use driver 'boolean' type on fields + + +Version 16.06 +------------- + +Released on June 6th 2016 + +- Major refactoring of the codebase +- Improved Postgre adapter performance +- [MSSQL] Fixed sql generation with `orderby` on MSSQL3 adapters +- Connection and cursors are now thread safe +- [Mongo] Empty values for `ObjectId` fields are now stored and parsed + as `None` instead of a fake `ObjectId(0)` +- Fixed multiple calls of initialization callbacks during connection +- [Postgre] Added more extraction helpers on fields +- Enabled entity quoting as default behavior +- Added indexes creation and drop support on SQL adapters +- Several bugfixes + + +Version 16.03 +------------- + +Released on March 24th 2016 + +- Implemented faster SQLite logic in absence of db queris +- PEP8 improvements +- Added support for new relic (newrelic>=2.10.0.8) +- Added support for outerscoped tablenames +- Fixed Google Cloud SQL support +- Fixed Oracle DB support +- Serveral bugfixes + + +Version 15.12 +------------- + +Released on December 16th 2015 + +- Added IPV6 address enclosed in brackets support for URI's host +- [MongoDB] Implemented unique and notnull support for fields during insert +- Several bugfixes + + +Version 15.09 +------------- + +Released on September 28th 2015 + +- [MongoDB] Implemented `orderby_on_limitby` +- [MongoDB] Implemented `distinct` for count +- [MongoDB] Implemented `select()` with `having` parameter +- [MongoDB] Implemented coalesce operations +- Virtual fields are now ordered depending on definition +- Allow usage of custom `Row` classes +- Added `.where` method to `Set` and `DAL` +- Several bugfixes + + +Version 15.07 +------------- + +Released on July 10th 2015 + +- Added `smart_query` support for 'contains' on fields of type 'list:string' +- Implemented correct escaping for 'LIKE' + (see https://github.com/web2py/pydal/issues/212) +- Added support for `ondelete` with fields of type 'list:reference' on + `MongoDBAdapter` +- Improved `BasicStorage` performance +- Added arithmetic expressions support on `MongoDBAdapter` +- Added aggregations support on `MongoDBAdapter` +- `Table.validate_and_insert` and `Table.validate_and_update` methods now + validates also empty fields +- Added support for expression operators on `MongoDBAdapter` +- Several bugfixes + + +Version 15.05.29 +---------------- + +Released on May 29th 2015 + +- Fixed a unicode error with `PostgreSQLAdapter` introduced with 15.05 + + +Version 15.05.26 +---------------- + +Released on May 26th 2015 + +- Fixed `DAL.__getattr__` +- Fixed backward compatibility breaks introduced with 15.05 + + +Version 15.05 +------------- + +Released on May 23rd 2015 + +- Fixed True/False expressions in MSSQL +- Introduced `iterselect()` and `IterRows` +- Extended `SQLCustomType` to support `widget` & `represent` attributes +- Updated `MongoDBAdapter` to support pymongo 3.0 +- Implemented JSON serialization for objects +- Refactored many internal objects to improve performance +- Added python 3.x support (experimental) +- Several fixes and improvements to `MongoDBAdapter` +- Implemented unicode handling in MSSQL (experimental) via mssql4n and mssql3n + adapters + Notes: These adapters will probably become the de-facto standard for MSSQL handling; any other adapter will continue to be supported just for legacy + databases +- Restricted table and field names to "valid" ones + Notes: the "dotted-notation-friendly" syntax for names means anything: + - alphanumeric + - not starting with underscore or an integer + `rname` attribute is intended to be used for anything else + + +Version 15.03 +------------- + +Released on March 23rd 2015 + +- Fixed `redefine` with lazy tables +- Added tests for `update_or_insert`, `bulk_insert`, + `validate_and_update_or_insert` +- Enhanced connections open/close flow +- Enhanced logging flow +- Refactored google adapters: `ndb` is now used by default +- Added default representation for `reference` fields +- Fixed some caching issues when using `pickle` +- Several improvements and fixes in `MongoDBAdapter` + + +Version 15.02.27 +---------------- + +Released on February 27th 2015 + +- Fixed a connection bug +- Fixed a security flaw which could lead to db password storing in cache + + +Version 15.02 +------------- + +Released on February 11th 2015 + +- Updated pg8000 support in `PostgreSQLAdapter` +- Fixed `ilike` for `Field` type 'list:string' in `PostgreSQLAdapter` +- Added case sensitive/insensitive tests for `contains` +- Fixed expression evaluation on `PostgreSQLAdapter` +- Fixed `common_filter` issue in `_enable_record_versioning` +- Removed contrib drivers +- Fixed `uuid` attribute of `DAL` class +- Added caching tests + + +Version 0.12.25 +--------------- + +Released on December 25th 2014 + +First public preview release. diff --git a/web2py/gluon/packages/dal/LICENSE b/web2py/gluon/packages/dal/LICENSE new file mode 100644 index 0000000..f3a87ad --- /dev/null +++ b/web2py/gluon/packages/dal/LICENSE @@ -0,0 +1,36 @@ +Copyright (c) 2014-2017 by Massimo Di Pierro and contributors. See AUTHORS for +more details. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +pyDAL contains third party software in the 'contrib' directory: each +file/module in this directory is distributed under its original license. diff --git a/web2py/gluon/packages/dal/MANIFEST.in b/web2py/gluon/packages/dal/MANIFEST.in new file mode 100644 index 0000000..392961d --- /dev/null +++ b/web2py/gluon/packages/dal/MANIFEST.in @@ -0,0 +1,7 @@ +include LICENSE +include AUTHORS +include CHANGES +recursive-include tests * +recursive-exclude tests .DS_Store +recursive-include docs * +recursive-exclude docs .DS_Store diff --git a/web2py/gluon/packages/dal/README.md b/web2py/gluon/packages/dal/README.md new file mode 100644 index 0000000..ab19cfb --- /dev/null +++ b/web2py/gluon/packages/dal/README.md @@ -0,0 +1,70 @@ +# pyDAL + +pyDAL is a pure Python Database Abstraction Layer. + +It dynamically generates the SQL in real time using the specified dialect for the database back end, so that you do not have to write SQL code or learn different SQL dialects (the term SQL is used generically), and your code will be portable among different types of databases. + +pyDAL comes from the original web2py's DAL, with the aim of being wide-compatible. pyDAL doesn't require web2py and can be used in any Python context. + +[![pip version](https://img.shields.io/pypi/v/pydal.svg?style=flat-square)](https://pypi.python.org/pypi/pydal) +[![Build Status](https://img.shields.io/travis/web2py/pydal/master.svg?style=flat-square&label=Travis-CI)](https://travis-ci.org/web2py/pydal) +[![MS Build Status](https://img.shields.io/appveyor/ci/web2py/pydal/master.svg?style=flat-square&label=Appveyor-CI)](https://ci.appveyor.com/project/web2py/pydal) +[![Coverage Status](https://img.shields.io/codecov/c/github/web2py/pydal.svg?style=flat-square)](https://codecov.io/github/web2py/pydal) +[![API Docs Status](https://readthedocs.org/projects/pydal/badge/?version=latest&style=flat-square)](http://pydal.rtfd.org/) + +## Installation + +You can install pyDAL using pip: + + pip install pyDAL + +## Usage and documentation + +Here is a quick example: + + >>> from pydal import DAL, Field + >>> db = DAL('sqlite://storage.db') + >>> db.define_table('thing',Field('name')) + >>> db.thing.insert(name='Chair') + >>> query = db.thing.name.startswith('C') + >>> rows = db(query).select() + >>> print rows[0].name + Chair + >>> db.commit() + +The complete documentation is available on http://www.web2py.com/books/default/chapter/29/06/the-database-abstraction-layer + +## What's in the box? + +A little *taste* of pyDAL features: + +* Transactions +* Aggregates +* Inner Joins +* Outer Joins +* Nested Selects + +## Which databases are supported? + +pyDAL actually support these databases: + +* sqlite +* postgresql +* mysql +* mssql +* db2 +* firebird +* sybase +* oracle +* informix +* teradata +* sapdb +* ingres +* cubrid +* imap +* mongodb + +## License + +pyDAL is released under the BSD-3c License. +For further details, please check the `LICENSE` file. diff --git a/web2py/gluon/packages/dal/appveyor.yml b/web2py/gluon/packages/dal/appveyor.yml new file mode 100644 index 0000000..43d2d50 --- /dev/null +++ b/web2py/gluon/packages/dal/appveyor.yml @@ -0,0 +1,55 @@ +build: false + +services: + - mssql2014 + +environment: + matrix: + - PYTHON: "C:/Python27" + adapter: "mssql" + - PYTHON: "C:/Python27" + adapter: "mssqln" + - PYTHON: "C:/Python33" + adapter: "mssql" + - PYTHON: "C:/Python33" + adapter: "mssqln" + - PYTHON: "C:/Python34" + adapter: "mssql" + - PYTHON: "C:/Python34" + adapter: "mssqln" + - PYTHON: "C:/Python35" + adapter: "mssql" + - PYTHON: "C:/Python35" + adapter: "mssqln" + - PYTHON: "C:/Python36-x64" + PYTHON_ARCH: "64" + adapter: "mssql" + - PYTHON: "C:/Python36-x64" + PYTHON_ARCH: "64" + adapter: "mssqln" + +clone_depth: 50 + +init: + - "ECHO %PYTHON%" + - set PATH=%PYTHON%;%PYTHON%\Scripts;%PATH% + +install: + - ps: Start-FileDownload https://bootstrap.pypa.io/get-pip.py + - python get-pip.py + - pip install tox==1.9.2 + - pip install codecov + +before_test: + - ps: | + while($LASTEXITCODE -ne 0) + { + & sqlcmd -S "(local)\SQL2014" -b -U "sa" -P "Password12!" -Q "CREATE DATABASE pydal COLLATE Latin1_General_CS_AS;" -d "master" + sleep 10; $val++; Write-Host Waiting ... $val; if($val -ge 10) {break} + } + +test_script: + - tox -e coverage-%adapter% + +after_test: + - codecov diff --git a/web2py/gluon/packages/dal/docs/Makefile b/web2py/gluon/packages/dal/docs/Makefile new file mode 100644 index 0000000..af26c5c --- /dev/null +++ b/web2py/gluon/packages/dal/docs/Makefile @@ -0,0 +1,177 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/gluon.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/gluon.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/gluon" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/gluon" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/web2py/gluon/packages/dal/docs/conf.py b/web2py/gluon/packages/dal/docs/conf.py new file mode 100644 index 0000000..15d1fac --- /dev/null +++ b/web2py/gluon/packages/dal/docs/conf.py @@ -0,0 +1,244 @@ +# -*- coding: utf-8 -*- +# +# web2py documentation build configuration file, created by +# sphinx-quickstart on Sun Aug 18 20:05:19 2013. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os, shutil +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' + +if not on_rtd: # only import and set the theme if we're building docs locally + import sphinx_rtd_theme + html_theme = 'sphinx_rtd_theme' + html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath('..')) +import pkg_resources +version_ = pkg_resources.get_distribution('pyDAL').version +release_ = version_ +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage', 'sphinx.ext.viewcode', 'sphinxcontrib.napoleon'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'pyDAL' +copyright = u'2014, web2py-developers' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = version_ +# The full version, including alpha/beta/rc tags. +release = release_ + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- Options for HTML output --------------------------------------------------- + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +html_show_sourcelink = False + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'pyDALdoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'pydal.tex', u'pyDAL Documentation', + u'web2py-developers', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'pyDAL', u'pyDAL Documentation', + [u'web2py-developers'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'pyDAL', u'pyDAL Documentation', + u'web2py-developers', 'pyDAL', 'pyDAL', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False diff --git a/web2py/gluon/packages/dal/docs/index.rst b/web2py/gluon/packages/dal/docs/index.rst new file mode 100644 index 0000000..200191b --- /dev/null +++ b/web2py/gluon/packages/dal/docs/index.rst @@ -0,0 +1,59 @@ + +Welcome to pyDAL's API documentation! +====================================== + +Contents: + +.. toctree:: + :maxdepth: 4 + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + +Subpackages +----------- + +.. toctree:: + + pydal.adapters + pydal.helpers + +Submodules +---------- + +pydal.base module +--------------------- + +.. automodule:: pydal.base + :members: + :undoc-members: + :show-inheritance: + +pydal.connection module +--------------------------- + +.. automodule:: pydal.connection + :members: + :undoc-members: + :show-inheritance: + +pydal.objects module +------------------------ + +.. automodule:: pydal.objects + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: pydal + :members: + :undoc-members: + :show-inheritance: diff --git a/web2py/gluon/packages/dal/docs/pydal.adapters.rst b/web2py/gluon/packages/dal/docs/pydal.adapters.rst new file mode 100644 index 0000000..e9ed010 --- /dev/null +++ b/web2py/gluon/packages/dal/docs/pydal.adapters.rst @@ -0,0 +1,147 @@ +pydal.adapters package +========================== + +Submodules +---------- + +pydal.adapters.base module +------------------------------ + +.. automodule:: pydal.adapters.base + :members: + :undoc-members: + :show-inheritance: + +pydal.adapters.couchdb module +--------------------------------- + +.. automodule:: pydal.adapters.couchdb + :members: + :undoc-members: + :show-inheritance: + +pydal.adapters.cubrid module +-------------------------------- + +.. automodule:: pydal.adapters.cubrid + :members: + :undoc-members: + :show-inheritance: + +pydal.adapters.db2 module +----------------------------- + +.. automodule:: pydal.adapters.db2 + :members: + :undoc-members: + :show-inheritance: + +pydal.adapters.firebird module +---------------------------------- + +.. automodule:: pydal.adapters.firebird + :members: + :undoc-members: + :show-inheritance: + +pydal.adapters.google_adapters module +----------------------------------------- + + Adapter for GAE + +pydal.adapters.imap module +------------------------------ + +.. automodule:: pydal.adapters.imap + :members: + :undoc-members: + :show-inheritance: + +pydal.adapters.informix module +---------------------------------- + +.. automodule:: pydal.adapters.informix + :members: + :undoc-members: + :show-inheritance: + +pydal.adapters.ingres module +-------------------------------- + +.. automodule:: pydal.adapters.ingres + :members: + :undoc-members: + :show-inheritance: + +pydal.adapters.mongo module +------------------------------- + +.. automodule:: pydal.adapters.mongo + :members: + :undoc-members: + :show-inheritance: + +pydal.adapters.mssql module +------------------------------- + +.. automodule:: pydal.adapters.mssql + :members: + :undoc-members: + :show-inheritance: + +pydal.adapters.mysql module +------------------------------- + +.. automodule:: pydal.adapters.mysql + :members: + :undoc-members: + :show-inheritance: + +pydal.adapters.oracle module +-------------------------------- + +.. automodule:: pydal.adapters.oracle + :members: + :undoc-members: + :show-inheritance: + +pydal.adapters.postgres module +--------------------------------- + +.. automodule:: pydal.adapters.postgres + :members: + :undoc-members: + :show-inheritance: + +pydal.adapters.sapdb module +------------------------------- + +.. automodule:: pydal.adapters.sapdb + :members: + :undoc-members: + :show-inheritance: + +pydal.adapters.sqlite module +-------------------------------- + +.. automodule:: pydal.adapters.sqlite + :members: + :undoc-members: + :show-inheritance: + +pydal.adapters.teradata module +---------------------------------- + +.. automodule:: pydal.adapters.teradata + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: pydal.adapters + :members: + :undoc-members: + :show-inheritance: diff --git a/web2py/gluon/packages/dal/docs/pydal.helpers.rst b/web2py/gluon/packages/dal/docs/pydal.helpers.rst new file mode 100644 index 0000000..f602806 --- /dev/null +++ b/web2py/gluon/packages/dal/docs/pydal.helpers.rst @@ -0,0 +1,38 @@ +pydal.helpers package +========================= + +Submodules +---------- + +pydal.helpers.classes module +-------------------------------- + +.. automodule:: pydal.helpers.classes + :members: + :undoc-members: + :show-inheritance: + +pydal.helpers.methods module +-------------------------------- + +.. automodule:: pydal.helpers.methods + :members: + :undoc-members: + :show-inheritance: + +pydal.helpers.regex module +------------------------------ + +.. automodule:: pydal.helpers.regex + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: pydal.helpers + :members: + :undoc-members: + :show-inheritance: diff --git a/web2py/gluon/packages/dal/docs/requirements.txt b/web2py/gluon/packages/dal/docs/requirements.txt new file mode 100644 index 0000000..49ea3af --- /dev/null +++ b/web2py/gluon/packages/dal/docs/requirements.txt @@ -0,0 +1 @@ +sphinxcontrib-napoleon>=0.2.4 \ No newline at end of file diff --git a/web2py/gluon/packages/dal/pydal/__init__.py b/web2py/gluon/packages/dal/pydal/__init__.py new file mode 100644 index 0000000..5964d36 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/__init__.py @@ -0,0 +1,6 @@ +__version__ = '17.11' + +from .base import DAL +from .objects import Field +from .helpers.classes import SQLCustomType +from .helpers.methods import geoPoint, geoLine, geoPolygon diff --git a/web2py/gluon/packages/dal/pydal/_compat.py b/web2py/gluon/packages/dal/pydal/_compat.py new file mode 100644 index 0000000..f266543 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/_compat.py @@ -0,0 +1,111 @@ +import sys +import hashlib +import os + +PY2 = sys.version_info[0] == 2 + +_identity = lambda x: x + +if PY2: + import cPickle as pickle + from cStringIO import StringIO + import copy_reg as copyreg + from urllib import unquote + BytesIO = StringIO + reduce = reduce + hashlib_md5 = hashlib.md5 + iterkeys = lambda d: d.iterkeys() + itervalues = lambda d: d.itervalues() + iteritems = lambda d: d.iteritems() + integer_types = (int, long) + string_types = (str, unicode) + text_type = unicode + basestring = basestring + long = long + xrange = xrange + + def implements_iterator(cls): + cls.next = cls.__next__ + del cls.__next__ + return cls + + def implements_bool(cls): + cls.__nonzero__ = cls.__bool__ + del cls.__bool__ + return cls + + def to_bytes(obj, charset='utf-8', errors='strict'): + if obj is None: + return None + if isinstance(obj, (bytes, bytearray, buffer)): + return bytes(obj) + if isinstance(obj, unicode): + return obj.encode(charset, errors) + raise TypeError('Expected bytes') + + def to_native(obj, charset='utf8', errors='strict'): + if obj is None or isinstance(obj, str): + return obj + return obj.encode(charset, errors) +else: + import pickle + from io import StringIO, BytesIO + import copyreg + from functools import reduce + from urllib.parse import unquote + hashlib_md5 = lambda s: hashlib.md5(bytes(s, 'utf8')) + iterkeys = lambda d: iter(d.keys()) + itervalues = lambda d: iter(d.values()) + iteritems = lambda d: iter(d.items()) + integer_types = (int,) + string_types = (str,) + text_type = str + basestring = str + long = int + xrange = range + + implements_iterator = _identity + implements_bool = _identity + + def to_bytes(obj, charset='utf-8', errors='strict'): + if obj is None: + return None + if isinstance(obj, (bytes, bytearray, memoryview)): + return bytes(obj) + if isinstance(obj, str): + return obj.encode(charset, errors) + raise TypeError('Expected bytes') + + def to_native(obj, charset='utf8', errors='strict'): + if obj is None or isinstance(obj, str): + return obj + return obj.decode(charset, errors) + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(meta): + __call__ = type.__call__ + __init__ = type.__init__ + + def __new__(cls, name, this_bases, d): + if this_bases is None: + return type.__new__(cls, name, (), d) + return meta(name, bases, d) + return metaclass('temporary_class', None, {}) + + +def to_unicode(obj, charset='utf-8', errors='strict'): + if obj is None: + return None + if not isinstance(obj, bytes): + return text_type(obj) + return obj.decode(charset, errors) + + +# shortcuts +pjoin = os.path.join +exists = os.path.exists diff --git a/web2py/gluon/packages/dal/pydal/_gae.py b/web2py/gluon/packages/dal/pydal/_gae.py new file mode 100644 index 0000000..c4496ef --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/_gae.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +try: + from new import classobj + from google.appengine.ext import db as gae + from google.appengine.ext import ndb + from google.appengine.api import namespace_manager, rdbms + from google.appengine.api.datastore_types import Key # for belongs on ID + from google.appengine.ext.ndb.polymodel import PolyModel as NDBPolyModel +except ImportError: + gae = None + Key = None diff --git a/web2py/gluon/packages/dal/pydal/_globals.py b/web2py/gluon/packages/dal/pydal/_globals.py new file mode 100644 index 0000000..f171562 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/_globals.py @@ -0,0 +1,10 @@ +import threading + +GLOBAL_LOCKER = threading.RLock() +THREAD_LOCAL = threading.local() + +DEFAULT = lambda: None + +def IDENTITY(x): return x +def OR(a,b): return a|b +def AND(a,b): return a&b diff --git a/web2py/gluon/packages/dal/pydal/_load.py b/web2py/gluon/packages/dal/pydal/_load.py new file mode 100644 index 0000000..73d909a --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/_load.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# load modules with contrib fallback + +try: + from collections import OrderedDict +except: + from .contrib.ordereddict import OrderedDict + +from .contrib import portalocker +# TODO: uncomment the lines below when contrib/portalocker will be +# inline with the one shipped with pip +#try: +# import portalocker +#except ImportError: +# from .contrib import portalocker diff --git a/web2py/gluon/packages/dal/pydal/adapters/__init__.py b/web2py/gluon/packages/dal/pydal/adapters/__init__.py new file mode 100644 index 0000000..7ee450f --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/__init__.py @@ -0,0 +1,87 @@ +import re +from .._gae import gae +from ..helpers._internals import Dispatcher +from ..helpers.regex import REGEX_NO_GREEDY_ENTITY_NAME + + +class Adapters(Dispatcher): + def register_for(self, *uris): + def wrap(dispatch_class): + for uri in uris: + self._registry_[uri] = dispatch_class + return dispatch_class + return wrap + + def get_for(self, uri): + try: + return self._registry_[uri] + except KeyError: + raise SyntaxError( + 'Adapter not found for %s' % uri + ) + +adapters = Adapters('adapters') + + +class AdapterMeta(type): + """Metaclass to support manipulation of adapter classes. + + At the moment is used to intercept `entity_quoting` argument passed to DAL. + """ + def __call__(cls, *args, **kwargs): + uploads_in_blob = kwargs.get('adapter_args', {}).get( + 'uploads_in_blob', cls.uploads_in_blob) + cls.uploads_in_blob = uploads_in_blob + + entity_quoting = kwargs.get('entity_quoting', True) + if 'entity_quoting' in kwargs: + del kwargs['entity_quoting'] + + obj = super(AdapterMeta, cls).__call__(*args, **kwargs) + if not entity_quoting: + quot = obj.dialect.quote_template = '%s' + regex_ent = r'(\w+)' + else: + quot = obj.dialect.quote_template + regex_ent = REGEX_NO_GREEDY_ENTITY_NAME + obj.REGEX_TABLE_DOT_FIELD = re.compile( + r'^' + quot % regex_ent + r'\.' + quot % regex_ent + r'$') + + return obj + + +def with_connection(f): + def wrap(*args, **kwargs): + if args[0].connection: + return f(*args, **kwargs) + return None + return wrap + + +def with_connection_or_raise(f): + def wrap(*args, **kwargs): + if not args[0].connection: + if len(args) > 1: + raise ValueError(args[1]) + raise RuntimeError('no connection available') + return f(*args, **kwargs) + return wrap + + +from .base import SQLAdapter, NoSQLAdapter +from .sqlite import SQLite +from .postgres import Postgre, PostgrePsyco, PostgrePG8000 +from .mysql import MySQL +from .mssql import MSSQL +from .mongo import Mongo +from .db2 import DB2 +from .firebird import FireBird +from .informix import Informix +from .ingres import Ingres +from .oracle import Oracle +from .sap import SAPDB +from .teradata import Teradata +from .couchdb import CouchDB + +if gae is not None: + from .google import GoogleSQL diff --git a/web2py/gluon/packages/dal/pydal/adapters/base.py b/web2py/gluon/packages/dal/pydal/adapters/base.py new file mode 100644 index 0000000..5001d88 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/base.py @@ -0,0 +1,965 @@ +import copy +import sys +import types +from collections import defaultdict +from contextlib import contextmanager +from .._compat import PY2, with_metaclass, iterkeys, iteritems, hashlib_md5, \ + integer_types, basestring +from .._globals import IDENTITY +from ..connection import ConnectionPool +from ..exceptions import NotOnNOSQLError +from ..helpers.classes import Reference, ExecutionHandler, SQLCustomType, \ + SQLALL, NullDriver +from ..helpers.methods import use_common_filters, xorify, merge_tablemaps +from ..helpers.regex import REGEX_SELECT_AS_PARSER, REGEX_TABLE_DOT_FIELD +from ..migrator import Migrator +from ..objects import Table, Field, Expression, Query, Rows, IterRows, \ + LazySet, LazyReferenceGetter, VirtualCommand, Select +from ..utils import deprecated +from . import AdapterMeta, with_connection, with_connection_or_raise + + +CALLABLETYPES = ( + types.LambdaType, types.FunctionType, types.BuiltinFunctionType, + types.MethodType, types.BuiltinMethodType) + + +class BaseAdapter(with_metaclass(AdapterMeta, ConnectionPool)): + dbengine = "None" + drivers = () + uploads_in_blob = False + support_distributed_transaction = False + + def __init__(self, db, uri, pool_size=0, folder=None, db_codec='UTF-8', + credential_decoder=IDENTITY, driver_args={}, + adapter_args={}, do_connect=True, after_connection=None, + entity_quoting=False): + super(BaseAdapter, self).__init__() + self._load_dependencies() + self.db = db + self.uri = uri + self.pool_size = pool_size + self.folder = folder + self.db_codec = db_codec + self.credential_decoder = credential_decoder + self.driver_args = driver_args + self.adapter_args = adapter_args + self.expand = self._expand + self._after_connection = after_connection + self.connection = None + self.find_driver() + self._initialize_(do_connect) + if do_connect: + self.reconnect() + + def _load_dependencies(self): + from ..dialects import dialects + from ..parsers import parsers + from ..representers import representers + self.dialect = dialects.get_for(self) + self.parser = parsers.get_for(self) + self.representer = representers.get_for(self) + + def _initialize_(self, do_connect): + self._find_work_folder() + + @property + def types(self): + return self.dialect.types + + @property + def _available_drivers(self): + return [ + driver for driver in self.drivers + if driver in iterkeys(self.db._drivers_available)] + + def _driver_from_uri(self): + rv = None + if self.uri: + items = self.uri.split('://', 1)[0].split(':') + rv = items[1] if len(items) > 1 else None + return rv + + def find_driver(self): + if getattr(self, 'driver', None) is not None: + return + requested_driver = self._driver_from_uri() or \ + self.adapter_args.get('driver') + if requested_driver: + if requested_driver in self._available_drivers: + self.driver_name = requested_driver + self.driver = self.db._drivers_available[requested_driver] + else: + raise RuntimeError( + 'Driver %s is not available' % requested_driver) + elif self._available_drivers: + self.driver_name = self._available_drivers[0] + self.driver = self.db._drivers_available[self.driver_name] + else: + raise RuntimeError( + "No driver of supported ones %s is available" % + str(self.drivers)) + + def connector(self): + return self.driver.connect(self.driver_args) + + def test_connection(self): + pass + + @with_connection + def close_connection(self): + rv = self.connection.close() + self.connection = None + return rv + + def tables(self, *queries): + tables = dict() + for query in queries: + if isinstance(query, Field): + key = query.tablename + if tables.get(key, query.table) is not query.table: + raise ValueError('Name conflict in table list: %s' % key) + tables[key] = query.table + elif isinstance(query, (Expression, Query)): + tmp = [x for x in (query.first, query.second) if x is not None] + tables = merge_tablemaps(tables, self.tables(*tmp)) + return tables + + def get_table(self, *queries): + tablemap = self.tables(*queries) + if len(tablemap) == 1: + return tablemap.popitem()[1] + elif len(tablemap) < 1: + raise RuntimeError("No table selected") + else: + raise RuntimeError( + "Too many tables selected (%s)" % str(list(tablemap))) + + def common_filter(self, query, tablist): + tenant_fieldname = self.db._request_tenant + for table in tablist: + if isinstance(table, basestring): + table = self.db[table] + # deal with user provided filters + if table._common_filter is not None: + query = query & table._common_filter(query) + # deal with multi_tenant filters + if tenant_fieldname in table: + default = table[tenant_fieldname].default + if default is not None: + newquery = table[tenant_fieldname] == default + if query is None: + query = newquery + else: + query = query & newquery + return query + + def _expand(self, expression, field_type=None, colnames=False, + query_env={}): + return str(expression) + + def expand_all(self, fields, tabledict): + new_fields = [] + append = new_fields.append + for item in fields: + if isinstance(item, SQLALL): + new_fields += item._table + elif isinstance(item, str): + m = REGEX_TABLE_DOT_FIELD.match(item) + if m: + tablename, fieldname = m.groups() + append(self.db[tablename][fieldname]) + else: + append(Expression(self.db, lambda item=item: item)) + else: + append(item) + # ## if no fields specified take them all from the requested tables + if not new_fields: + for table in tabledict.values(): + for field in table: + append(field) + return new_fields + + def parse_value(self, value, field_itype, field_type, blob_decode=True): + # [Note - gi0baro] I think next if block can be (should be?) avoided + if field_type != 'blob' and isinstance(value, str): + try: + value = value.decode(self.db._db_codec) + except Exception: + pass + if PY2 and isinstance(value, unicode): + value = value.encode('utf-8') + if isinstance(field_type, SQLCustomType): + value = field_type.decoder(value) + if not isinstance(field_type, str) or value is None: + return value + elif field_type == 'blob' and not blob_decode: + return value + else: + return self.parser.parse(value, field_itype, field_type) + + def _add_operators_to_parsed_row(self, rid, table, row): + for key, record_operator in iteritems(self.db.record_operators): + setattr(row, key, record_operator(row, table, rid)) + if table._db._lazy_tables: + row['__get_lazy_reference__'] = LazyReferenceGetter(table, rid) + + def _add_reference_sets_to_parsed_row(self, rid, table, tablename, row): + for rfield in table._referenced_by: + referee_link = self.db._referee_name and self.db._referee_name % \ + dict(table=rfield.tablename, field=rfield.name) + if referee_link and referee_link not in row and \ + referee_link != tablename: + row[referee_link] = LazySet(rfield, rid) + + def _regex_select_as_parser(self, colname): + return REGEX_SELECT_AS_PARSER.search(colname) + + def _parse(self, row, tmps, fields, colnames, blob_decode, + cacheable, fields_virtual, fields_lazy): + new_row = defaultdict(self.db.Row) + extras = self.db.Row() + #: let's loop over columns + for (j, colname) in enumerate(colnames): + value = row[j] + tmp = tmps[j] + tablename = None + #: do we have a real column? + if tmp: + (tablename, fieldname, table, field, ft, fit) = tmp + colset = new_row[tablename] + #: parse value + value = self.parse_value(value, fit, ft, blob_decode) + if field.filter_out: + value = field.filter_out(value) + colset[fieldname] = value + #! backward compatibility + if ft == 'id' and fieldname != 'id' and \ + 'id' not in table.fields: + colset['id'] = value + #: additional parsing for 'id' fields + if ft == 'id' and not cacheable: + self._add_operators_to_parsed_row(value, table, colset) + self._add_reference_sets_to_parsed_row( + value, table, tablename, colset) + #: otherwise we set the value in extras + else: + value = self.parse_value( + value, fields[j]._itype, fields[j].type, blob_decode) + extras[colname] = value + new_column_name = self._regex_select_as_parser(colname) + if new_column_name is not None: + column_name = new_column_name.groups(0) + new_row[column_name[0]] = value + #: add extras if needed (eg. operations results) + if extras: + new_row['_extra'] = extras + #: add virtuals + new_row = self.db.Row(**new_row) + for tablename in fields_virtual.keys(): + for f, v in fields_virtual[tablename][1]: + try: + new_row[tablename][f] = v.f(new_row) + except (AttributeError, KeyError): + pass # not enough fields to define virtual field + for f, v in fields_lazy[tablename][1]: + try: + new_row[tablename][f] = v.handler(v.f, new_row) + except (AttributeError, KeyError): + pass # not enough fields to define virtual field + return new_row + + def _parse_expand_colnames(self, fieldlist): + """ + - Expand a list of colnames into a list of + (tablename, fieldname, table_obj, field_obj, field_type) + - Create a list of table for virtual/lazy fields + """ + fields_virtual = {} + fields_lazy = {} + tmps = [] + for field in fieldlist: + if not isinstance(field, Field): + tmps.append(None) + continue + table = field.table + tablename, fieldname = table._tablename, field.name + ft = field.type + fit = field._itype + tmps.append((tablename, fieldname, table, field, ft, fit)) + if tablename not in fields_virtual: + fields_virtual[tablename] = (table, [ + (f.name, f) for f in table._virtual_fields + ]) + fields_lazy[tablename] = (table, [ + (f.name, f) for f in table._virtual_methods + ]) + return (fields_virtual, fields_lazy, tmps) + + def parse(self, rows, fields, colnames, blob_decode=True, cacheable=False): + (fields_virtual, fields_lazy, tmps) = \ + self._parse_expand_colnames(fields) + new_rows = [ + self._parse( + row, tmps, fields, colnames, blob_decode, cacheable, + fields_virtual, fields_lazy) + for row in rows + ] + rowsobj = self.db.Rows(self.db, new_rows, colnames, rawrows=rows, + fields=fields) + # Old style virtual fields + for tablename, tmp in fields_virtual.items(): + table = tmp[0] + # ## old style virtual fields + for item in table.virtualfields: + try: + rowsobj = rowsobj.setvirtualfields(**{tablename: item}) + except (KeyError, AttributeError): + # to avoid breaking virtualfields when partial select + pass + return rowsobj + + def iterparse(self, sql, fields, colnames, blob_decode=True, + cacheable=False): + """ + Iterator to parse one row at a time. + It doesn't support the old style virtual fields + """ + return IterRows(self.db, sql, fields, colnames, blob_decode, cacheable) + + def adapt(self, value): + return value + + def represent(self, obj, field_type): + if isinstance(obj, CALLABLETYPES): + obj = obj() + return self.representer.represent(obj, field_type) + + def _drop_table_cleanup(self, table): + del self.db[table._tablename] + del self.db.tables[self.db.tables.index(table._tablename)] + self.db._remove_references_to(table) + + def drop_table(self, table, mode=''): + self._drop_table_cleanup(table) + + def rowslice(self, rows, minimum=0, maximum=None): + return rows + + def sqlsafe_table(self, tablename, original_tablename=None): + return tablename + + def sqlsafe_field(self, fieldname): + return fieldname + + +class DebugHandler(ExecutionHandler): + def before_execute(self, command): + self.adapter.db.logger.debug('SQL: %s' % command) + + +class SQLAdapter(BaseAdapter): + commit_on_alter_table = False + # [Note - gi0baro] can_select_for_update should be deprecated and removed + can_select_for_update = True + execution_handlers = [] + migrator_cls = Migrator + + def __init__(self, *args, **kwargs): + super(SQLAdapter, self).__init__(*args, **kwargs) + migrator_cls = self.adapter_args.get('migrator', self.migrator_cls) + self.migrator = migrator_cls(self) + self.execution_handlers = list(self.db.execution_handlers) + if self.db._debug: + self.execution_handlers.insert(0, DebugHandler) + + def test_connection(self): + self.execute('SELECT 1;') + + def represent(self, obj, field_type): + if isinstance(obj, (Expression, Field)): + return str(obj) + return super(SQLAdapter, self).represent(obj, field_type) + + def adapt(self, obj): + return "'%s'" % obj.replace("'", "''") + + def smart_adapt(self, obj): + if isinstance(obj, (int, float)): + return str(obj) + return self.adapt(str(obj)) + + def fetchall(self): + return self.cursor.fetchall() + + def fetchone(self): + return self.cursor.fetchone() + + def _build_handlers_for_execution(self): + rv = [] + for handler_class in self.execution_handlers: + rv.append(handler_class(self)) + return rv + + def filter_sql_command(self, command): + return command + + @with_connection_or_raise + def execute(self, *args, **kwargs): + command = self.filter_sql_command(args[0]) + handlers = self._build_handlers_for_execution() + for handler in handlers: + handler.before_execute(command) + rv = self.cursor.execute(command, *args[1:], **kwargs) + for handler in handlers: + handler.after_execute(command) + return rv + + def _expand(self, expression, field_type=None, colnames=False, + query_env={}): + if isinstance(expression, Field): + if not colnames: + rv = expression.sqlsafe + else: + rv = expression.longname + if field_type == 'string' and expression.type not in ( + 'string', 'text', 'json', 'jsonb', 'password'): + rv = self.dialect.cast(rv, self.types['text'], query_env) + elif isinstance(expression, (Expression, Query)): + first = expression.first + second = expression.second + op = expression.op + optional_args = expression.optional_args or {} + optional_args['query_env'] = query_env + if second is not None: + rv = op(first, second, **optional_args) + elif first is not None: + rv = op(first, **optional_args) + elif isinstance(op, str): + if op.endswith(';'): + op = op[:-1] + rv = '(%s)' % op + else: + rv = op() + elif field_type: + rv = self.represent(expression, field_type) + elif isinstance(expression, (list, tuple)): + rv = ','.join(self.represent(item, field_type) + for item in expression) + elif isinstance(expression, bool): + rv = self.dialect.true_exp if expression else \ + self.dialect.false_exp + else: + rv = expression + return str(rv) + + def _expand_for_index(self, expression, field_type=None, colnames=False, + query_env={}): + if isinstance(expression, Field): + return expression._rname + return self._expand(expression, field_type, colnames, query_env) + + @contextmanager + def index_expander(self): + self.expand = self._expand_for_index + yield + self.expand = self._expand + + def lastrowid(self, table): + return self.cursor.lastrowid + + def _insert(self, table, fields): + if fields: + return self.dialect.insert( + table._rname, + ','.join(el[0]._rname for el in fields), + ','.join(self.expand(v, f.type) for f, v in fields)) + return self.dialect.insert_empty(table._rname) + + def insert(self, table, fields): + query = self._insert(table, fields) + try: + self.execute(query) + except: + e = sys.exc_info()[1] + if hasattr(table, '_on_insert_error'): + return table._on_insert_error(table, fields, e) + raise e + if hasattr(table, '_primarykey'): + pkdict = dict([ + (k[0].name, k[1]) for k in fields + if k[0].name in table._primarykey]) + if pkdict: + return pkdict + id = self.lastrowid(table) + if hasattr(table, '_primarykey') and len(table._primarykey) == 1: + id = {table._primarykey[0]: id} + if not isinstance(id, integer_types): + return id + rid = Reference(id) + (rid._table, rid._record) = (table, None) + return rid + + def _update(self, table, query, fields): + sql_q = '' + query_env = dict(current_scope=[table._tablename]) + if query: + if use_common_filters(query): + query = self.common_filter(query, [table]) + sql_q = self.expand(query, query_env=query_env) + sql_v = ','.join([ + '%s=%s' % (field._rname, + self.expand(value, field.type, query_env=query_env)) + for (field, value) in fields]) + return self.dialect.update(table, sql_v, sql_q) + + def update(self, table, query, fields): + sql = self._update(table, query, fields) + try: + self.execute(sql) + except: + e = sys.exc_info()[1] + if hasattr(table, '_on_update_error'): + return table._on_update_error(table, query, fields, e) + raise e + try: + return self.cursor.rowcount + except: + return None + + def _delete(self, table, query): + sql_q = '' + query_env = dict(current_scope=[table._tablename]) + if query: + if use_common_filters(query): + query = self.common_filter(query, [table]) + sql_q = self.expand(query, query_env=query_env) + return self.dialect.delete(table, sql_q) + + def delete(self, table, query): + sql = self._delete(table, query) + self.execute(sql) + try: + return self.cursor.rowcount + except: + return None + + def _colexpand(self, field, query_env): + return self.expand(field, colnames=True, query_env=query_env) + + def _geoexpand(self, field, query_env): + if isinstance(field.type, str) and field.type.startswith('geo') and \ + isinstance(field, Field): + field = field.st_astext() + return self.expand(field, query_env=query_env) + + def _build_joins_for_select(self, tablenames, param): + if not isinstance(param, (tuple, list)): + param = [param] + tablemap = {} + for item in param: + if isinstance(item, Expression): + item = item.first + key = item._tablename + if tablemap.get(key, item) is not item: + raise ValueError('Name conflict in table list: %s' % key) + tablemap[key] = item + join_tables = [ + t._tablename for t in param if not isinstance(t, Expression) + ] + join_on = [t for t in param if isinstance(t, Expression)] + tables_to_merge = {} + for t in join_on: + tables_to_merge = merge_tablemaps(tables_to_merge, self.tables(t)) + join_on_tables = [t.first._tablename for t in join_on] + for t in join_on_tables: + if t in tables_to_merge: + tables_to_merge.pop(t) + important_tablenames = join_tables + join_on_tables + \ + list(tables_to_merge) + excluded = [ + t for t in tablenames if t not in important_tablenames + ] + return ( + join_tables, join_on, tables_to_merge, join_on_tables, + important_tablenames, excluded, tablemap + ) + + def _select_wcols(self, query, fields, left=False, join=False, + distinct=False, orderby=False, groupby=False, + having=False, limitby=False, orderby_on_limitby=True, + for_update=False, outer_scoped=[], required=None, + cache=None, cacheable=None, processor=None): + #: parse tablemap + tablemap = self.tables(query) + #: apply common filters if needed + if use_common_filters(query): + query = self.common_filter(query, list(tablemap.values())) + #: auto-adjust tables + tablemap = merge_tablemaps(tablemap, self.tables(*fields)) + #: remove outer scoped tables if needed + for item in outer_scoped: + # FIXME: check for name conflicts + tablemap.pop(item, None) + if len(tablemap) < 1: + raise SyntaxError('Set: no tables selected') + query_tables = list(tablemap) + #: check for_update argument + # [Note - gi0baro] I think this should be removed since useless? + # should affect only NoSQL? + if self.can_select_for_update is False and for_update is True: + raise SyntaxError('invalid select attribute: for_update') + #: build joins (inner, left outer) and table names + if join: + ( + # FIXME? ijoin_tables is never used + ijoin_tables, ijoin_on, itables_to_merge, ijoin_on_tables, + iimportant_tablenames, iexcluded, itablemap + ) = self._build_joins_for_select(tablemap, join) + tablemap = merge_tablemaps(tablemap, itables_to_merge) + tablemap = merge_tablemaps(tablemap, itablemap) + if left: + ( + join_tables, join_on, tables_to_merge, join_on_tables, + important_tablenames, excluded, jtablemap + ) = self._build_joins_for_select(tablemap, left) + tablemap = merge_tablemaps(tablemap, tables_to_merge) + tablemap = merge_tablemaps(tablemap, jtablemap) + current_scope = outer_scoped + list(tablemap) + query_env = dict(current_scope=current_scope, + parent_scope=outer_scoped) + #: prepare columns and expand fields + colnames = [self._colexpand(x, query_env) for x in fields] + sql_fields = ', '.join(self._geoexpand(x, query_env) for x in fields) + table_alias = lambda name: tablemap[name].query_name(outer_scoped)[0] + if join and not left: + cross_joins = iexcluded + list(itables_to_merge) + tokens = [table_alias(cross_joins[0])] + tokens += [self.dialect.cross_join(table_alias(t), query_env) + for t in cross_joins[1:]] + tokens += [self.dialect.join(t, query_env) for t in ijoin_on] + sql_t = ' '.join(tokens) + elif not join and left: + cross_joins = excluded + list(tables_to_merge) + tokens = [table_alias(cross_joins[0])] + tokens += [self.dialect.cross_join(table_alias(t), query_env) + for t in cross_joins[1:]] + # FIXME: WTF? This is not correct syntax at least on PostgreSQL + if join_tables: + tokens.append(self.dialect.left_join(','.join([table_alias(t) + for t in join_tables]), query_env)) + tokens += [self.dialect.left_join(t, query_env) for t in join_on] + sql_t = ' '.join(tokens) + elif join and left: + all_tables_in_query = set( + important_tablenames + iimportant_tablenames + query_tables) + tables_in_joinon = set(join_on_tables + ijoin_on_tables) + tables_not_in_joinon = \ + list(all_tables_in_query.difference(tables_in_joinon)) + tokens = [table_alias(tables_not_in_joinon[0])] + tokens += [self.dialect.cross_join(table_alias(t), query_env) + for t in tables_not_in_joinon[1:]] + tokens += [self.dialect.join(t, query_env) for t in ijoin_on] + # FIXME: WTF? This is not correct syntax at least on PostgreSQL + if join_tables: + tokens.append(self.dialect.left_join(','.join([table_alias(t) + for t in join_tables]), query_env)) + tokens += [self.dialect.left_join(t, query_env) for t in join_on] + sql_t = ' '.join(tokens) + else: + sql_t = ', '.join(table_alias(t) for t in query_tables) + #: expand query if needed + if query: + query = self.expand(query, query_env=query_env) + if having: + having = self.expand(having, query_env=query_env) + #: groupby + sql_grp = groupby + if groupby: + if isinstance(groupby, (list, tuple)): + groupby = xorify(groupby) + sql_grp = self.expand(groupby, query_env=query_env) + #: orderby + sql_ord = False + if orderby: + if isinstance(orderby, (list, tuple)): + orderby = xorify(orderby) + if str(orderby) == '': + sql_ord = self.dialect.random + else: + sql_ord = self.expand(orderby, query_env=query_env) + #: set default orderby if missing + if (limitby and not groupby and query_tables and orderby_on_limitby and + not orderby): + sql_ord = ', '.join([ + tablemap[t][x].sqlsafe + for t in query_tables if not isinstance(tablemap[t], Select) + for x in (hasattr(tablemap[t], '_primarykey') and + tablemap[t]._primarykey or ['_id']) + ]) + #: build sql using dialect + return colnames, self.dialect.select( + sql_fields, sql_t, query, sql_grp, having, sql_ord, limitby, + distinct, for_update and self.can_select_for_update + ) + + def _select(self, query, fields, attributes): + return self._select_wcols(query, fields, **attributes)[1] + + def nested_select(self, query, fields, attributes): + return Select(self.db, query, fields, attributes) + + def _select_aux_execute(self, sql): + self.execute(sql) + return self.cursor.fetchall() + + def _select_aux(self, sql, fields, attributes, colnames): + cache = attributes.get('cache', None) + if not cache: + rows = self._select_aux_execute(sql) + else: + if isinstance(cache, dict): + cache_model = cache['model'] + time_expire = cache['expiration'] + key = cache.get('key') + if not key: + key = self.uri + '/' + sql + '/rows' + key = hashlib_md5(key).hexdigest() + else: + (cache_model, time_expire) = cache + key = self.uri + '/' + sql + '/rows' + key = hashlib_md5(key).hexdigest() + rows = cache_model( + key, + lambda self=self, sql=sql: self._select_aux_execute(sql), + time_expire) + if isinstance(rows, tuple): + rows = list(rows) + limitby = attributes.get('limitby', None) or (0,) + rows = self.rowslice(rows, limitby[0], None) + processor = attributes.get('processor', self.parse) + cacheable = attributes.get('cacheable', False) + return processor(rows, fields, colnames, cacheable=cacheable) + + def _cached_select(self, cache, sql, fields, attributes, colnames): + del attributes['cache'] + (cache_model, time_expire) = cache + key = self.uri + '/' + sql + key = hashlib_md5(key).hexdigest() + args = (sql, fields, attributes, colnames) + ret = cache_model( + key, + lambda self=self, args=args: self._select_aux(*args), + time_expire) + ret._restore_fields(fields) + return ret + + def select(self, query, fields, attributes): + colnames, sql = self._select_wcols(query, fields, **attributes) + cache = attributes.get('cache', None) + if cache and attributes.get('cacheable', False): + return self._cached_select( + cache, sql, fields, attributes, colnames) + return self._select_aux(sql, fields, attributes, colnames) + + def iterselect(self, query, fields, attributes): + colnames, sql = self._select_wcols(query, fields, **attributes) + cacheable = attributes.get('cacheable', False) + return self.iterparse(sql, fields, colnames, cacheable=cacheable) + + def _count(self, query, distinct=None): + tablemap = self.tables(query) + tablenames = list(tablemap) + tables = list(tablemap.values()) + query_env = dict(current_scope=tablenames) + sql_q = '' + if query: + if use_common_filters(query): + query = self.common_filter(query, tables) + sql_q = self.expand(query, query_env=query_env) + sql_t = ','.join(self.table_alias(t, []) for t in tables) + sql_fields = '*' + if distinct: + if isinstance(distinct, (list, tuple)): + distinct = xorify(distinct) + sql_fields = self.expand(distinct, query_env=query_env) + return self.dialect.select( + self.dialect.count(sql_fields, distinct), sql_t, sql_q + ) + + def count(self, query, distinct=None): + self.execute(self._count(query, distinct)) + return self.cursor.fetchone()[0] + + def bulk_insert(self, table, items): + return [self.insert(table, item) for item in items] + + def create_table(self, *args, **kwargs): + return self.migrator.create_table(*args, **kwargs) + + def _drop_table_cleanup(self, table): + super(SQLAdapter, self)._drop_table_cleanup(table) + if table._dbt: + self.migrator.file_delete(table._dbt) + self.migrator.log('success!\n', table) + + def drop_table(self, table, mode=''): + queries = self.dialect.drop_table(table, mode) + for query in queries: + if table._dbt: + self.migrator.log(query + '\n', table) + self.execute(query) + self.commit() + self._drop_table_cleanup(table) + + @deprecated('drop', 'drop_table', 'SQLAdapter') + def drop(self, table, mode=''): + return self.drop_table(table, mode='') + + def truncate(self, table, mode=''): + # Prepare functions "write_to_logfile" and "close_logfile" + try: + queries = self.dialect.truncate(table, mode) + for query in queries: + self.migrator.log(query + '\n', table) + self.execute(query) + self.migrator.log('success!\n', table) + finally: + pass + + def create_index(self, table, index_name, *fields, **kwargs): + expressions = [ + field._rname if isinstance(field, Field) else field + for field in fields] + sql = self.dialect.create_index( + index_name, table, expressions, **kwargs) + try: + self.execute(sql) + self.commit() + except Exception as e: + self.rollback() + err = 'Error creating index %s\n Driver error: %s\n' + \ + ' SQL instruction: %s' + raise RuntimeError(err % (index_name, str(e), sql)) + return True + + def drop_index(self, table, index_name): + sql = self.dialect.drop_index(index_name, table) + try: + self.execute(sql) + self.commit() + except Exception as e: + self.rollback() + err = 'Error dropping index %s\n Driver error: %s' + raise RuntimeError(err % (index_name, str(e))) + return True + + def distributed_transaction_begin(self, key): + pass + + @with_connection + def commit(self): + return self.connection.commit() + + @with_connection + def rollback(self): + return self.connection.rollback() + + @with_connection + def prepare(self, key): + self.connection.prepare() + + @with_connection + def commit_prepared(self, key): + self.connection.commit() + + @with_connection + def rollback_prepared(self, key): + self.connection.rollback() + + def create_sequence_and_triggers(self, query, table, **args): + self.execute(query) + + def sqlsafe_table(self, tablename, original_tablename=None): + if original_tablename is not None: + return self.dialect.alias(original_tablename, tablename) + return self.dialect.quote(tablename) + + def sqlsafe_field(self, fieldname): + return self.dialect.quote(fieldname) + + def table_alias(self, tbl, current_scope=[]): + if isinstance(tbl, basestring): + tbl = self.db[tbl] + return tbl.query_name(current_scope)[0] + + def id_query(self, table): + pkeys = getattr(table, '_primarykey', None) + if pkeys: + return table[pkeys[0]] != None + return table._id != None + + +class NoSQLAdapter(BaseAdapter): + can_select_for_update = False + + def commit(self): + pass + + def rollback(self): + pass + + def prepare(self): + pass + + def commit_prepared(self, key): + pass + + def rollback_prepared(self, key): + pass + + def id_query(self, table): + return table._id > 0 + + def create_table(self, table, migrate=True, fake_migrate=False, + polymodel=None): + table._dbt = None + table._notnulls = [] + for field_name in table.fields: + if table[field_name].notnull: + table._notnulls.append(field_name) + table._uniques = [] + for field_name in table.fields: + if table[field_name].unique: + # this is unnecessary if the fields are indexed and unique + table._uniques.append(field_name) + + def drop_table(self, table, mode=''): + ctable = self.connection[table._tablename] + ctable.drop() + self._drop_table_cleanup(table) + + @deprecated('drop', 'drop_table', 'SQLAdapter') + def drop(self, table, mode=''): + return self.drop_table(table, mode='') + + def _select(self, *args, **kwargs): + raise NotOnNOSQLError( + "Nested queries are not supported on NoSQL databases") + + def nested_select(self, *args, **kwargs): + raise NotOnNOSQLError( + "Nested queries are not supported on NoSQL databases") + + +class NullAdapter(BaseAdapter): + + def _load_dependencies(self): + from ..dialects.base import CommonDialect + self.dialect = CommonDialect(self) + + def find_driver(self): + pass + + def connector(self): + return NullDriver() diff --git a/web2py/gluon/packages/dal/pydal/adapters/couchdb.py b/web2py/gluon/packages/dal/pydal/adapters/couchdb.py new file mode 100644 index 0000000..ad133df --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/couchdb.py @@ -0,0 +1,148 @@ +from ..helpers.classes import FakeCursor, SQLALL +from ..helpers.methods import uuid2int +from ..objects import Query, Field +from .base import NoSQLAdapter, SQLAdapter +from . import adapters + + +@adapters.register_for('couchdb') +class CouchDB(NoSQLAdapter): + dbengine = 'couchdb' + drivers = ('couchdb',) + + uploads_in_blob = True + + def _initialize_(self, do_connect): + super(CouchDB, self)._initialize_(do_connect) + self.ruri = 'http://' + self.uri[10:] + self.db_codec = 'UTF-8' + + def connector(self): + conn = self.driver.Server(self.ruri, **self.driver_args) + conn.cursor = lambda: FakeCursor() + conn.close = lambda: None + conn.commit = lambda: None + return conn + + def create_table(self, table, migrate=True, fake_migrate=False, + polymodel=None): + if migrate: + try: + self.connection.create(table._tablename) + except: + pass + super(CouchDB, self).create_table( + table, migrate, fake_migrate, polymodel) + + def _expand(self, expression, field_type=None, query_env={}): + if isinstance(expression, Field): + if expression.type == 'id': + return "%s._id" % expression.tablename + return SQLAdapter._expand(self, expression, field_type, + query_env=query_env) + + def insert(self, table, fields): + rid = uuid2int(self.db.uuid()) + ctable = self.connection[table._tablename] + values = dict((k.name, self.represent(v, k.type)) for k, v in fields) + values['_id'] = str(rid) + ctable.save(values) + return rid + + @staticmethod + def _make_id_field(field_name): + return field_name == 'id' and '_id' or field_name + + def _select(self, query, fields, left=False, join=False, distinct=False, + orderby=False, groupby=False, having=False, limitby=False, + orderby_on_limitby=True, for_update=False, outer_scoped=[], + required=None, cache=None, cacheable=None, processor=None): + if not isinstance(query, Query): + raise SyntaxError("Not Supported") + + new_fields = [] + for item in fields: + if isinstance(item, SQLALL): + new_fields += item._table + else: + new_fields.append(item) + + fields = new_fields + tablename = self.get_table(query)._tablename + fieldnames = [f.name for f in (fields or self.db[tablename])] + colnames = [ + '%s.%s' % (tablename, fieldname) for fieldname in fieldnames] + fields = ','.join( + ['%s.%s' % (tablename, self._make_id_field(f)) for f in fieldnames] + ) + fn = '(function(%(t)s){if(%(query)s)emit(%(order)s,[%(fields)s]);})' \ + % dict( + t=tablename, query=self.expand(query), + order='%s._id' % tablename, fields=fields) + return fn, colnames + + def select(self, query, fields, attributes): + fn, colnames = self._select(query, fields, attributes) + tablename = colnames[0].split('.')[0] + ctable = self.connection[tablename] + rows = [cols['value'] for cols in ctable.query(fn)] + processor = attributes.get('processor', self.parse) + return processor(rows, fields, colnames, False) + + def update(self, table, query, fields): + from ..drivers import couchdb + if not isinstance(query, Query): + raise SyntaxError("Not Supported") + if query.first.type == 'id' and query.op == self.dialect.eq: + rid = query.second + tablename = query.first.tablename + ctable = self.connection[tablename] + try: + doc = ctable[str(rid)] + for key, value in fields: + doc[key.name] = self.represent( + value, self.db[tablename][key.name].type) + ctable.save(doc) + return 1 + except couchdb.http.ResourceNotFound: + return 0 + tablename = self.get_table(query)._tablename + rows = self.select(query, [self.db[tablename]._id], {}) + ctable = self.connection[tablename] + table = self.db[tablename] + for row in rows: + doc = ctable[str(row.id)] + for key, value in fields: + doc[key.name] = self.represent(value, table[key.name].type) + ctable.save(doc) + return len(rows) + + def count(self, query, distinct=None): + if distinct: + raise RuntimeError("COUNT DISTINCT not supported") + if not isinstance(query, Query): + raise SyntaxError("Not Supported") + tablename = self.get_table(query)._tablename + rows = self.select(query, [self.db[tablename]._id], {}) + return len(rows) + + def delete(self, table, query): + from ..drivers import couchdb + if not isinstance(query, Query): + raise SyntaxError("Not Supported") + if query.first.type == 'id' and query.op == self.eq: + rid = query.second + tablename = query.first.tablename + assert(tablename == query.first.tablename) + ctable = self.connection[tablename] + try: + del ctable[str(rid)] + return 1 + except couchdb.http.ResourceNotFound: + return 0 + tablename = self.get_table(query)._tablename + rows = self.select(query, [self.db[tablename]._id], {}) + ctable = self.connection[tablename] + for row in rows: + del ctable[str(row.id)] + return len(rows) diff --git a/web2py/gluon/packages/dal/pydal/adapters/db2.py b/web2py/gluon/packages/dal/pydal/adapters/db2.py new file mode 100644 index 0000000..20f5d18 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/db2.py @@ -0,0 +1,58 @@ +from .._compat import integer_types, long +from .base import SQLAdapter +from . import adapters, with_connection_or_raise + + +class DB2(SQLAdapter): + dbengine = "db2" + + def _initialize_(self, do_connect): + super(DB2, self)._initialize_(do_connect) + self.ruri = self.uri.split('://', 1)[1] + + @with_connection_or_raise + def execute(self, *args, **kwargs): + command = self.filter_sql_command(args[0]) + if command[-1:] == ';': + command = command[:-1] + handlers = self._build_handlers_for_execution() + for handler in handlers: + handler.before_execute(command) + if kwargs.get('placeholders'): + args.append(kwargs['placeholders']) + del kwargs['placeholders'] + rv = self.cursor.execute(command, *args[1:], **kwargs) + for handler in handlers: + handler.after_execute(command) + return rv + + def lastrowid(self, table): + self.execute("SELECT DISTINCT IDENTITY_VAL_LOCAL() FROM %s;" % table) + return long(self.cursor.fetchone()[0]) + + def rowslice(self, rows, minimum=0, maximum=None): + if maximum is None: + return rows[minimum:] + return rows[minimum:maximum] + + +@adapters.register_for('db2:ibm_db_dbi') +class DB2IBM(DB2): + drivers = ('ibm_db_dbi',) + + def connector(self): + uriparts = self.ruri.split(";") + cnxn = {} + for var in uriparts: + v = var.split('=') + cnxn[v[0].lower()] = v[1] + return self.driver.connect( + cnxn['dsn'], cnxn['uid'], cnxn['pwd'], **self.driver_args) + + +@adapters.register_for('db2:pyodbc') +class DB2Pyodbc(DB2): + drivers = ('pyodbc',) + + def connector(self): + return self.driver.connect(self.ruri, **self.driver_args) diff --git a/web2py/gluon/packages/dal/pydal/adapters/firebird.py b/web2py/gluon/packages/dal/pydal/adapters/firebird.py new file mode 100644 index 0000000..806e453 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/firebird.py @@ -0,0 +1,92 @@ +import re +from .._compat import long +from .base import SQLAdapter +from . import adapters + + +@adapters.register_for('firebird') +class FireBird(SQLAdapter): + dbengine = "firebird" + drivers = ('kinterbasdb', 'firebirdsql', 'fdb', 'pyodbc') + + support_distributed_transaction = True + commit_on_alter_table = True + + REGEX_URI = re.compile( + '^(?P[^:@]+)(\:(?P[^@]*))?@(?P\[[^/]+\]|' + + '[^\:/]+)(\:(?P[0-9]+))?/(?P.+?)' + + '(\?set_encoding=(?P\w+))?$') + + def _initialize_(self, do_connect): + super(FireBird, self)._initialize_(do_connect) + ruri = self.uri.split('://', 1)[1] + m = self.REGEX_URI.match(ruri) + if not m: + raise SyntaxError("Invalid URI string in DAL") + user = self.credential_decoder(m.group('user')) + if not user: + raise SyntaxError('User required') + password = self.credential_decoder(m.group('password')) + if not password: + password = '' + host = m.group('host') + if not host: + raise SyntaxError('Host name required') + db = m.group('db') + if not db: + raise SyntaxError('Database name required') + port = int(m.group('port') or 3050) + charset = m.group('charset') or 'UTF8' + self.driver_args.update( + dsn='%s/%s:%s' % (host, port, db), + user=self.credential_decoder(user), + password=self.credential_decoder(password), + charset=charset) + + def connector(self): + return self.driver.connect(**self.driver_args) + + def lastrowid(self, table): + sequence_name = table._sequence_name + self.execute('SELECT gen_id(%s, 0) FROM rdb$database' % sequence_name) + return long(self.cursor.fetchone()[0]) + + def create_sequence_and_triggers(self, query, table, **args): + tablename = table._rname + sequence_name = table._sequence_name + trigger_name = table._trigger_name + self.execute(query) + self.execute('create generator %s;' % sequence_name) + self.execute('set generator %s to 0;' % sequence_name) + self.execute( + 'create trigger %s for %s active before insert position 0 ' + + 'as\nbegin\nif(new."id" is null) then\nbegin\n' + + 'new."id" = gen_id(%s, 1);\nend\nend;' % ( + trigger_name, tablename, sequence_name)) + + +@adapters.register_for('firebird_embedded') +class FireBirdEmbedded(FireBird): + REGEX_URI = re.compile( + '^(?P[^:@]+)(\:(?P[^@]*))?@(?P[^\?]+)' + + '(\?set_encoding=(?P\w+))?$') + + def _initialize_(self, do_connect): + super(FireBird, self)._initialize_(do_connect) + ruri = self.uri.split('://', 1)[1] + m = self.REGEX_URI.match(ruri) + if not m: + raise SyntaxError("Invalid URI string in DAL") + user = self.credential_decoder(m.group('user')) + if not user: + raise SyntaxError('User required') + password = self.credential_decoder(m.group('password')) + if not password: + password = '' + pathdb = m.group('path') + if not pathdb: + raise SyntaxError('Path required') + charset = m.group('charset') or 'UTF8' + self.driver_args.update( + host='', database=pathdb, user=self.credential_decoder(user), + password=self.credential_decoder(password), charset=charset) diff --git a/web2py/gluon/packages/dal/pydal/adapters/google.py b/web2py/gluon/packages/dal/pydal/adapters/google.py new file mode 100644 index 0000000..53a12fc --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/google.py @@ -0,0 +1,460 @@ +import os +import re +from .._compat import pjoin +from .._globals import THREAD_LOCAL +from .._gae import gae, ndb, rdbms, namespace_manager, classobj, NDBPolyModel +from ..migrator import InDBMigrator +from ..helpers.classes import FakeDriver, SQLCustomType, SQLALL, Reference +from ..helpers.gae import NDBDecimalProperty +from ..helpers.methods import use_common_filters, xorify +from ..objects import Table, Field, Expression, Query +from .base import NoSQLAdapter +from .mysql import MySQL +from .postgres import PostgrePsyco +from . import adapters, with_connection_or_raise + + +class GoogleMigratorMixin(object): + migrator_cls = InDBMigrator + + +@adapters.register_for('google:sql') +class GoogleSQL(GoogleMigratorMixin, MySQL): + uploads_in_blob = True + REGEX_URI = re.compile('^(?P.*)/(?P.*)$') + + def _find_work_folder(self): + super(GoogleSQL, self)._find_work_folder() + if os.path.isabs(self.folder) and self.folder.startswith(os.getcwd()): + self.folder = os.path.relpath(self.folder, os.getcwd()) + + def _initialize_(self, do_connect): + super(GoogleSQL, self)._initialize_(do_connect) + self.folder = self.folder or pjoin( + '$HOME', THREAD_LOCAL._pydal_folder_.split( + os.sep+'applications'+os.sep, 1)[1]) + ruri = self.uri.split('://', 1)[1] + m = self.REGEX_URI.match(ruri) + if not m: + raise SyntaxError("Invalid URI string in DAL") + self.driver_args['instance'] = self.credential_decoder( + m.group('instance')) + self.dbstring = self.credential_decoder(m.group('db')) + self.createdb = self.adapter_args.get('createdb', True) + if not self.createdb: + self.driver_args['database'] = self.dbstring + + def find_driver(self): + self.driver = "google" + + def connector(self): + return rdbms.connect(**self.driver_args) + + def after_connection(self): + if self.createdb: + self.execute('CREATE DATABASE IF NOT EXISTS %s' % self.dbstring) + self.execute('USE %s' % self.dbstring) + self.execute("SET FOREIGN_KEY_CHECKS=1;") + self.execute("SET sql_mode='NO_BACKSLASH_ESCAPES';") + + @with_connection_or_raise + def execute(self, *args, **kwargs): + command = self.filter_sql_command(args[0]).decode('utf8') + handlers = self._build_handlers_for_execution() + for handler in handlers: + handler.before_execute(command) + rv = self.cursor.execute(command, *args[1:], **kwargs) + for handler in handlers: + handler.after_execute(command) + return rv + + def clear_cache(self): + ndb.get_context().clear_cache() + + def ignore_cache_for(self, entities=None): + entities = entities or [] + ndb.get_context().set_cache_policy( + lambda key: key.kind() not in entities) + + +# based on this: https://cloud.google.com/appengine/docs/standard/python/cloud-sql/ +@adapters.register_for('google:MySQLdb') +class GoogleMySQL(GoogleMigratorMixin, MySQL): + uploads_in_blob = True + drivers = ('MySQLdb',) + + def _find_work_folder(self): + super(GoogleMySQL, self)._find_work_folder() + if os.path.isabs(self.folder) and self.folder.startswith(os.getcwd()): + self.folder = os.path.relpath(self.folder, os.getcwd()) + + def clear_cache(self): + ndb.get_context().clear_cache() + + def ignore_cache_for(self, entities=None): + entities = entities or [] + ndb.get_context().set_cache_policy( + lambda key: key.kind() not in entities) + + def after_connection(self): + self.execute("SET FOREIGN_KEY_CHECKS=1;") + self.execute("SET sql_mode='NO_BACKSLASH_ESCAPES,TRADITIONAL';") + +@adapters.register_for('google:psycopg2') +class GooglePostgres(GoogleMigratorMixin, PostgrePsyco): + uploads_in_blob = True + drivers = ('psycopg2',) + + def _find_work_folder(self): + super(GooglePostgres, self)._find_work_folder() + if os.path.isabs(self.folder) and self.folder.startswith(os.getcwd()): + self.folder = os.path.relpath(self.folder, os.getcwd()) + + def clear_cache(self): + ndb.get_context().clear_cache() + + def ignore_cache_for(self, entities=None): + entities = entities or [] + ndb.get_context().set_cache_policy( + lambda key: key.kind() not in entities) + + +@adapters.register_for('google:datastore', 'google:datastore+ndb') +class GoogleDatastore(NoSQLAdapter): + dbengine = "google:datastore" + + REGEX_NAMESPACE = re.compile('.*://(?P.+)') + + def _initialize_(self, do_connect): + super(GoogleDatastore, self)._initialize_(do_connect) + match = self.REGEX_NAMESPACE.match(self.uri) + if match: + namespace_manager.set_namespace(match.group('namespace')) + self.ndb_settings = self.adapter_args.get('ndb_settings') + + def find_driver(self): + pass + + def connector(self): + return FakeDriver() + + def create_table(self, table, migrate=True, fake_migrate=False, + polymodel=None): + myfields = {} + for field in table: + if isinstance(polymodel, Table) and \ + field.name in polymodel.fields(): + continue + attr = {} + if isinstance(field.custom_qualifier, dict): + #this is custom properties to add to the GAE field declartion + attr = field.custom_qualifier + field_type = field.type + if isinstance(field_type, SQLCustomType): + ftype = self.types[ + field_type.native or field_type.type](**attr) + elif isinstance(field_type, ndb.Property): + ftype = field_type + elif field_type.startswith('id'): + continue + elif field_type.startswith('decimal'): + precision, scale = field_type[7:].strip('()').split(',') + precision = int(precision) + scale = int(scale) + dec_cls = NDBDecimalProperty + ftype = dec_cls(precision, scale, **attr) + elif field_type.startswith('reference'): + if field.notnull: + attr = dict(required=True) + ftype = self.types[field_type[:9]](**attr) + elif field_type.startswith('list:reference'): + if field.notnull: + attr['required'] = True + ftype = self.types[field_type[:14]](**attr) + elif field_type.startswith('list:'): + ftype = self.types[field_type](**attr) + elif field_type not in self.types or not self.types[field_type]: + raise SyntaxError('Field: unknown field type: %s' % field_type) + else: + ftype = self.types[field_type](**attr) + myfields[field.name] = ftype + if not polymodel: + model_cls = ndb.Model + table._tableobj = classobj( + table._tablename, (model_cls, ), myfields) + # Set NDB caching variables + if self.ndb_settings and (table._tablename in self.ndb_settings): + for k, v in self.ndb_settings.iteritems(): + setattr(table._tableobj, k, v) + elif polymodel == True: + pm_cls = NDBPolyModel + table._tableobj = classobj(table._tablename, (pm_cls, ), myfields) + elif isinstance(polymodel, Table): + table._tableobj = classobj( + table._tablename, (polymodel._tableobj, ), myfields) + else: + raise SyntaxError( + "polymodel must be None, True, a table or a tablename") + return None + + def _expand(self, expression, field_type=None, query_env={}): + if expression is None: + return None + elif isinstance(expression, Field): + if expression.type in ('text', 'blob', 'json'): + raise SyntaxError( + 'AppEngine does not index by: %s' % expression.type) + return expression.name + elif isinstance(expression, (Expression, Query)): + if expression.second is not None: + return expression.op(expression.first, expression.second, + query_env=query_env) + elif expression.first is not None: + return expression.op(expression.first, query_env=query_env) + else: + return expression.op() + elif field_type: + return self.represent(expression, field_type) + elif isinstance(expression, (list, tuple)): + return ','.join([ + self.represent(item, field_type) for item in expression]) + elif hasattr(expression, "_FilterNode__name"): + # check for _FilterNode__name to avoid explicit + # import of FilterNode + return expression + else: + raise NotImplementedError + + def _add_operators_to_parsed_row(self, rid, table, row): + row.gae_item = rid + lid = rid.key.id() + row.id = lid + super(GoogleDatastore, self)._add_operators_to_parsed_row( + lid, table, row) + + def represent(self, obj, field_type, tablename=None): + if isinstance(obj, ndb.Key): + return obj + if field_type == 'id' and tablename: + if isinstance(obj, list): + return [ + self.represent(item, field_type, tablename) + for item in obj] + elif obj is None: + return None + else: + return ndb.Key(tablename, long(obj)) + if isinstance(obj, (Expression, Field)): + raise SyntaxError("non supported on GAE") + if isinstance(field_type, gae.Property): + return obj + return super(GoogleDatastore, self).represent(obj, field_type) + + def truncate(self, table, mode=''): + self.db(self.id_query(table)).delete() + + def select_raw(self, query, fields=None, attributes=None, + count_only=False): + db = self.db + fields = fields or [] + attributes = attributes or {} + args_get = attributes.get + new_fields = [] + + for item in fields: + if isinstance(item, SQLALL): + new_fields += item._table + else: + new_fields.append(item) + + fields = new_fields + if query: + table = self.get_table(query) + elif fields: + table = fields[0].table + query = db._adapter.id_query(fields[0].table) + else: + raise SyntaxError("Unable to determine the table") + + if query: + if use_common_filters(query): + query = self.common_filter(query, [table]) + + #tableobj is a GAE/NDB Model class (or subclass) + tableobj = table._tableobj + filters = self.expand(query) + + ## DETERMINE PROJECTION + projection = None + if len(table.fields) == len(fields): + # getting all fields, not a projection query + projection = None + elif args_get('projection') == True: + projection = [] + for f in fields: + if f.type in ['text', 'blob', 'json']: + raise SyntaxError( + "text and blob field types not allowed in " + + "projection queries") + else: + projection.append(f) + + elif args_get('filterfields') is True: + projection = [] + for f in fields: + projection.append(f) + + # real projection's can't include 'id'. + # it will be added to the result later + if projection and args_get('projection') == True: + query_projection = [f.name for f in projection + if f.name != table._id.name] + else: + query_projection = None + ## DONE WITH PROJECTION + + cursor = args_get('reusecursor') + cursor = cursor if isinstance(cursor, str) else None + qo = ndb.QueryOptions(projection=query_projection, cursor=cursor) + + if filters == None: + items = tableobj.query(default_options=qo) + elif getattr(filters, 'filter_all', None): + items = [] + elif (getattr(filters, '_FilterNode__value', None) and + getattr(filters, '_FilterNode__name', None) == '__key__' and + getattr(filters, '_FilterNode__opsymbol', None) == '='): + item = ndb.Key.from_old_key(getattr(filters, '_FilterNode__value')).get() + items = [item] if item else [] + else: + items = tableobj.query(filters, default_options=qo) + + if count_only: + items = [len(items) if isinstance(items, list) else items.count()] + elif not isinstance(items, list): + if args_get('left', None): + raise SyntaxError('Set: no left join in appengine') + if args_get('groupby', None): + raise SyntaxError('Set: no groupby in appengine') + orderby = args_get('orderby', False) + if orderby: + if isinstance(orderby, (list, tuple)): + orderby = xorify(orderby) + if isinstance(orderby, Expression): + orderby = self.expand(orderby) + orders = orderby.split(', ') + tbl = tableobj + for order in orders: + order = str(order) + desc = order[:1] == '-' + name = order[1 if desc else 0:].split('.')[-1] + if name == 'id': + o = -tbl._key if desc else tbl._key + else: + o = -getattr(tbl, name) if desc else getattr(tbl, name) + items = items.order(o) + + if args_get('limitby', None): + (lmin, lmax) = attributes['limitby'] + limit = lmax-lmin + fetch_args = {'offset': lmin, 'keys_only': True} + + keys, cursor, more = items.fetch_page(limit, **fetch_args) + items = ndb.get_multi(keys) + # cursor is only useful if there was a limit and we + # didn't return all results + if args_get('reusecursor'): + db['_lastcursor'] = cursor + return (items, table, projection or [f for f in table]) + + def select(self, query, fields, attributes): + """ + This is the GAE version of select. Some notes to consider: + - 'nativeRef' is a magical fieldname used for self references + on GAE + - optional attribute 'projection' when set to True will trigger + use of the GAE projection queries. note that there are rules for + what is accepted imposed by GAE: each field must be indexed, + projection queries cannot contain blob or text fields, and you + cannot use == and also select that same field. + see https://developers.google.com/appengine/docs/python/datastore/queries#Query_Projection + - optional attribute 'filterfields' when set to True web2py will + only parse the explicitly listed fields into the Rows object, + even though all fields are returned in the query. This can be + used to reduce memory usage in cases where true projection + queries are not usable. + - optional attribute 'reusecursor' allows use of cursor with + queries that have the limitby attribute. Set the attribute to + True for the first query, set it to the value of + db['_lastcursor'] to continue a previous query. The user must + save the cursor value between requests, and the filters must be + identical. It is up to the user to follow google's limitations: + https://developers.google.com/appengine/docs/python/datastore/queries#Query_Cursors + """ + + items, table, fields = self.select_raw(query, fields, attributes) + rows = [ + [ + (t.name == table._id.name and item) or + (t.name == 'nativeRef' and item) or getattr(item, t.name) + for t in fields + ] for item in items] + colnames = [t.longname for t in fields] + processor = attributes.get('processor', self.parse) + return processor(rows, fields, colnames, False) + + def count(self, query, distinct=None, limit=None): + if distinct: + raise RuntimeError("COUNT DISTINCT not supported") + items, table, fields = self.select_raw(query, count_only=True) + return items[0] + + def delete(self, table, query): + """ + This function was changed on 2010-05-04 because according to + http://code.google.com/p/googleappengine/issues/detail?id=3119 + GAE no longer supports deleting more than 1000 records. + """ + items, table, fields = self.select_raw(query) + # items can be one item or a query + if not isinstance(items, list): + # use a keys_only query to ensure that this runs as a datastore + # small operations + leftitems = items.fetch(1000, keys_only=True) + counter = 0 + while len(leftitems): + counter += len(leftitems) + ndb.delete_multi(leftitems) + leftitems = items.fetch(1000, keys_only=True) + else: + counter = len(items) + ndb.delete_multi([item.key for item in items]) + return counter + + def update(self, table, query, update_fields): + items, table, fields = self.select_raw(query) + counter = 0 + for item in items: + for field, value in update_fields: + setattr(item, field.name, self.represent(value, field.type)) + item.put() + counter += 1 + self.db.logger.info(str(counter)) + return counter + + def insert(self, table, fields): + dfields = dict((f.name, self.represent(v, f.type)) for f, v in fields) + tmp = table._tableobj(**dfields) + tmp.put() + key = tmp.key + rid = Reference(key.id()) + rid._table, rid._record, rid._gaekey = table, None, key + return rid + + def bulk_insert(self, table, items): + parsed_items = [] + for item in items: + dfields = dict( + (f.name, self.represent(v, f.type)) for f, v in item) + parsed_items.append(table._tableobj(**dfields)) + return ndb.put_multi(parsed_items) diff --git a/web2py/gluon/packages/dal/pydal/adapters/informix.py b/web2py/gluon/packages/dal/pydal/adapters/informix.py new file mode 100644 index 0000000..b5f5351 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/informix.py @@ -0,0 +1,64 @@ +from ..helpers.classes import ConnectionConfigurationMixin +from .base import SQLAdapter +from . import adapters, with_connection_or_raise + + +@adapters.register_for('informix') +class Informix(ConnectionConfigurationMixin, SQLAdapter): + dbengine = 'informix' + drivers = ('informixdb',) + + def _initialize_(self, do_connect): + super(Informix, self)._initialize_(do_connect) + ruri = self.uri.split('://', 1)[1] + m = self.REGEX_URI.match(ruri) + if not m: + raise SyntaxError("Invalid URI string in DAL") + user = self.credential_decoder(m.group('user')) + if not user: + raise SyntaxError('User required') + password = self.credential_decoder(m.group('password')) + if not password: + password = '' + host = m.group('host') + if not host: + raise SyntaxError('Host name required') + db = m.group('db') + if not db: + raise SyntaxError('Database name required') + self.dsn = '%s@%s' % (db, host) + self.driver_args.update(user=user, password=password) + self._mock_reconnect() + + def connector(self): + return self.driver.connect(self.dsn, **self.driver_args) + + def _configure_on_first_reconnect(self): + self.dbms_version = int(self.connection.dbms_version.split('.')[0]) + + @with_connection_or_raise + def execute(self, *args, **kwargs): + command = self.filter_sql_command(args[0]) + if command[-1:] == ';': + command = command[:-1] + handlers = self._build_handlers_for_execution() + for handler in handlers: + handler.before_execute(command) + rv = self.cursor.execute(command, *args[1:], **kwargs) + for handler in handlers: + handler.after_execute(command) + return rv + + def test_connection(self): + self.execute('SELECT COUNT(*) FROM systables;') + + def lastrowid(self, table): + return self.cursor.sqlerrd[1] + + +@adapters.register_for('informix-se') +class InformixSE(Informix): + def rowslice(self, rows, minimum=0, maximum=None): + if maximum is None: + return rows[minimum:] + return rows[minimum:maximum] diff --git a/web2py/gluon/packages/dal/pydal/adapters/ingres.py b/web2py/gluon/packages/dal/pydal/adapters/ingres.py new file mode 100644 index 0000000..0cf76a2 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/ingres.py @@ -0,0 +1,51 @@ +from .base import SQLAdapter +from . import adapters + + +@adapters.register_for('ingres') +class Ingres(SQLAdapter): + dbengine = 'ingres' + drivers = ('pyodbc',) + + def _initialize_(self, do_connect): + super(Ingres, self)._initialize_(do_connect) + ruri = self.uri.split('://', 1)[1] + connstr = ruri.lstrip() + while connstr.startswith('/'): + connstr = connstr[1:] + if '=' in connstr: + # Assume we have a regular ODBC connection string and just use it + ruri = connstr + else: + # Assume only (local) dbname is passed in with OS auth + database_name = connstr + default_driver_name = 'Ingres' + vnode = '(local)' + ruri = 'Driver={%s};Server=%s;Database=%s' % ( + default_driver_name, vnode, database_name) + self.ruri = ruri + + def connector(self): + self.driver.connect(self.ruri, **self.driver_args) + + def create_sequence_and_triggers(self, query, table, **args): + # post create table auto inc code (if needed) + # modify table to btree for performance.... + # Older Ingres releases could use rule/trigger like Oracle above. + if hasattr(table, '_primarykey'): + modify_tbl_sql = 'modify %s to btree unique on %s' % \ + (table._rname, + ', '.join(["'%s'" % x for x in table.primarykey])) + self.execute(modify_tbl_sql) + else: + tmp_seqname = '%s_iisq' % table._raw_rname + query = query.replace(self.dialect.INGRES_SEQNAME, tmp_seqname) + self.execute('create sequence %s' % tmp_seqname) + self.execute(query) + self.execute( + 'modify %s to btree unique on %s' % (table._rname, 'id')) + + +@adapters.register_for('ingresu') +class IngresUnicode(Ingres): + pass diff --git a/web2py/gluon/packages/dal/pydal/adapters/mongo.py b/web2py/gluon/packages/dal/pydal/adapters/mongo.py new file mode 100644 index 0000000..763cd59 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/mongo.py @@ -0,0 +1,950 @@ +import copy +import random +from datetime import datetime +from .._compat import basestring, long +from ..exceptions import NotOnNOSQLError +from ..helpers.classes import ( + FakeCursor, Reference, SQLALL, ConnectionConfigurationMixin) +from ..helpers.methods import use_common_filters, xorify +from ..objects import Field, Row, Query, Expression +from .base import NoSQLAdapter +from . import adapters + +try: + from bson import Binary + from bson.binary import USER_DEFINED_SUBTYPE +except: + class Binary(object): + pass + USER_DEFINED_SUBTYPE = 0 + + +@adapters.register_for('mongodb') +class Mongo(ConnectionConfigurationMixin, NoSQLAdapter): + dbengine = 'mongodb' + drivers = ('pymongo',) + + def find_driver(self): + super(Mongo, self).find_driver() + #: ensure pymongo version >= 3.0 + if 'fake_version' in self.driver_args: + version = self.driver_args['fake_version'] + else: + from pymongo import version + if int(version.split('.')[0]) < 3: + raise RuntimeError( + "pydal requires pymongo version >= 3.0, found '%s'" % version) + + def _initialize_(self, do_connect): + super(Mongo, self)._initialize_(do_connect) + #: uri parse + from pymongo import uri_parser + m = uri_parser.parse_uri(self.uri) + if isinstance(m, tuple): + m = {"database": m[1]} + if m.get('database') is None: + raise SyntaxError("Database is required!") + self._driver_db = m['database'] + #: mongodb imports and utils + from bson.objectid import ObjectId + from bson.son import SON + from pymongo.write_concern import WriteConcern + self.epoch = datetime.fromtimestamp(0) + self.SON = SON + self.ObjectId = ObjectId + self.WriteConcern = WriteConcern + #: options + self.db_codec = 'UTF-8' + # this is the minimum amount of replicates that it should wait + # for on insert/update + self.minimumreplication = self.adapter_args.get( + 'minimumreplication', 0) + # by default all inserts and selects are performed asynchronous, + # but now the default is + # synchronous, except when overruled by either this default or + # function parameter + self.safe = 1 if self.adapter_args.get('safe', True) else 0 + self._mock_reconnect() + + def connector(self): + conn = self.driver.MongoClient(self.uri, w=self.safe)[self._driver_db] + conn.cursor = lambda: FakeCursor() + conn.close = lambda: None + conn.commit = lambda: None + return conn + + def _configure_on_first_reconnect(self): + #: server version + self._server_version = self.connection.command( + "serverStatus")['version'] + self.server_version = tuple( + [int(x) for x in self._server_version.split('.')]) + self.server_version_major = ( + self.server_version[0] + self.server_version[1] / 10.0) + + def object_id(self, arg=None): + """ Convert input to a valid Mongodb ObjectId instance + + self.object_id("") -> ObjectId (not unique) instance """ + if not arg: + arg = 0 + if isinstance(arg, basestring): + # we assume an integer as default input + rawhex = len(arg.replace("0x", "").replace("L", "")) == 24 + if arg.isdigit() and (not rawhex): + arg = int(arg) + elif arg == "": + arg = int("0x%s" % "".join([ + random.choice("0123456789abcdef") + for x in range(24)]), 0) + elif arg.isalnum(): + if not arg.startswith("0x"): + arg = "0x%s" % arg + try: + arg = int(arg, 0) + except ValueError as e: + raise ValueError( + "invalid objectid argument string: %s" % e) + else: + raise ValueError("Invalid objectid argument string. " + + "Requires an integer or base 16 value") + elif isinstance(arg, self.ObjectId): + return arg + elif isinstance(arg, (Row, Reference)): + return self.object_id(long(arg['id'])) + elif not isinstance(arg, (int, long)): + raise TypeError( + "object_id argument must be of type ObjectId or an objectid " + + "representable integer (type %s)" % type(arg)) + hexvalue = hex(arg)[2:].rstrip('L').zfill(24) + return self.ObjectId(hexvalue) + + def _get_collection(self, tablename, safe=None): + ctable = self.connection[tablename] + if safe is not None and safe != self.safe: + wc = self.WriteConcern(w=self._get_safe(safe)) + ctable = ctable.with_options(write_concern=wc) + return ctable + + def _get_safe(self, val=None): + if val is None: + return self.safe + return 1 if val else 0 + + def _regex_select_as_parser(self, colname): + return self.dialect.REGEX_SELECT_AS_PARSER.search(colname) + + @staticmethod + def _parse_data(expression, attribute, value=None): + if isinstance(expression, (list, tuple)): + ret = False + for e in expression: + ret = Mongo._parse_data(e, attribute, value) or ret + return ret + if value is not None: + try: + expression._parse_data[attribute] = value + except AttributeError: + return None + try: + return expression._parse_data[attribute] + except (AttributeError, TypeError): + return None + + def _expand(self, expression, field_type=None, query_env={}): + if isinstance(expression, Field): + if expression.type == 'id': + result = "_id" + else: + result = expression.name + if self._parse_data(expression, 'pipeline'): + # field names as part of expressions need to start with '$' + result = '$' + result + elif isinstance(expression, (Expression, Query)): + first = expression.first + second = expression.second + if isinstance(first, Field) and "reference" in first.type: + # cast to Mongo ObjectId + if isinstance(second, (tuple, list, set)): + second = [ + self.object_id(item) for item in expression.second] + else: + second = self.object_id(expression.second) + op = expression.op + optional_args = expression.optional_args or {} + optional_args['query_env'] = query_env + if second is not None: + result = op(first, second, **optional_args) + elif first is not None: + result = op(first, **optional_args) + elif isinstance(op, str): + result = op + else: + result = op(**optional_args) + elif isinstance(expression, Expansion): + expression.query = (self.expand(expression.query, field_type, + query_env=query_env)) + result = expression + elif isinstance(expression, (list, tuple)): + result = [self.represent(item, field_type) for item in expression] + elif field_type: + result = self.represent(expression, field_type) + else: + result = expression + return result + + def represent(self, obj, field_type): + if isinstance(obj, self.ObjectId): + return obj + return super(Mongo, self).represent(obj, field_type) + + def truncate(self, table, mode, safe=None): + ctable = self.connection[table._tablename] + ctable.delete_many({}) + + def count(self, query, distinct=None, snapshot=True): + if not isinstance(query, Query): + raise SyntaxError("Type '%s' not supported in count" % type(query)) + distinct_fields = [] + if distinct is True: + distinct_fields = [x for x in query.first.table if x.name != 'id'] + elif distinct: + if isinstance(distinct, Field): + distinct_fields = [distinct] + else: + while (isinstance(distinct, Expression) and + isinstance(distinct.second, Field)): + distinct_fields += [distinct.second] + distinct = distinct.first + if isinstance(distinct, Field): + distinct_fields += [distinct] + distinct = True + expanded = Expansion( + self, 'count', query, fields=distinct_fields, distinct=distinct) + ctable = expanded.get_collection() + if not expanded.pipeline: + return ctable.count(filter=expanded.query_dict) + for record in ctable.aggregate(expanded.pipeline): + return record['count'] + return 0 + + def select(self, query, fields, attributes, snapshot=False): + attributes['snapshot'] = snapshot + return self.__select(query, fields, **attributes) + + def __select(self, query, fields, left=False, join=False, distinct=False, + orderby=False, groupby=False, having=False, limitby=False, + orderby_on_limitby=True, for_update=False, outer_scoped=[], + required=None, cache=None, cacheable=None, processor=None, + snapshot=False): + new_fields = [] + for item in fields: + if isinstance(item, SQLALL): + new_fields += item._table + else: + new_fields.append(item) + fields = new_fields + tablename = self.get_table(query, *fields)._tablename + + if for_update: + self.db.logger.warning( + "Attribute 'for_update' unsupported by MongoDB") + if join or left: + raise NotOnNOSQLError("Joins not supported on NoSQL databases") + if required or cache or cacheable: + self.db.logger.warning( + "Attributes 'required', 'cache' and 'cacheable' are" + + " unsupported by MongoDB") + + if limitby and orderby_on_limitby and not orderby: + if groupby: + orderby = groupby + else: + table = self.db[tablename] + orderby = [ + table[x] for x in ( + hasattr(table, '_primarykey') and + table._primarykey or ['_id'])] + + if not orderby: + mongosort_list = [] + else: + if snapshot: + raise RuntimeError( + "snapshot and orderby are mutually exclusive") + if isinstance(orderby, (list, tuple)): + orderby = xorify(orderby) + + if str(orderby) == '': + # !!!! need to add 'random' + mongosort_list = self.dialect.random + else: + mongosort_list = [] + for f in self.expand(orderby).split(','): + include = 1 + if f.startswith('-'): + include = -1 + f = f[1:] + if f.startswith('$'): + f = f[1:] + mongosort_list.append((f, include)) + + expanded = Expansion( + self, 'select', query, fields or self.db[tablename], + groupby=groupby, distinct=distinct, having=having) + ctable = self.connection[tablename] + modifiers = {'snapshot': snapshot} + + if not expanded.pipeline: + if limitby: + limitby_skip, limitby_limit = limitby[0], int(limitby[1]) - 1 + else: + limitby_skip = limitby_limit = 0 + mongo_list_dicts = ctable.find( + expanded.query_dict, expanded.field_dicts, skip=limitby_skip, + limit=limitby_limit, sort=mongosort_list, modifiers=modifiers) + null_rows = [] + else: + if mongosort_list: + sortby_dict = self.SON() + for f in mongosort_list: + sortby_dict[f[0]] = f[1] + expanded.pipeline.append({'$sort': sortby_dict}) + if limitby and limitby[1]: + expanded.pipeline.append({'$limit': limitby[1]}) + if limitby and limitby[0]: + expanded.pipeline.append({'$skip': limitby[0]}) + + mongo_list_dicts = ctable.aggregate(expanded.pipeline) + null_rows = [(None,)] + + rows = [] + # populate row in proper order + # Here we replace ._id with .id to follow the standard naming + colnames = [] + newnames = [] + for field in expanded.fields: + if hasattr(field, "tablename"): + if field.name in ('id', '_id'): + # Mongodb reserved uuid key + colname = (tablename + '.' + 'id', '_id') + else: + colname = (field.longname, field.name) + elif not isinstance(query, Expression): + colname = (field.name, field.name) + colnames.append(colname[1]) + newnames.append(colname[0]) + + for record in mongo_list_dicts: + row = [] + for colname in colnames: + try: + value = record[colname] + except: + value = None + if self.server_version_major < 2.6: + # '$size' not present in server versions < 2.6 + if isinstance(value, list) and '$addToSet' in colname: + value = len(value) + + row.append(value) + rows.append(row) + if not rows: + rows = null_rows + + processor = processor or self.parse + result = processor(rows, fields, newnames, blob_decode=True) + return result + + def check_notnull(self, table, values): + for fieldname in table._notnulls: + if fieldname not in values or values[fieldname] is None: + raise Exception("NOT NULL constraint failed: %s" % fieldname) + + def check_unique(self, table, values): + if len(table._uniques) > 0: + db = table._db + unique_queries = [] + for fieldname in table._uniques: + if fieldname in values: + value = values[fieldname] + else: + value = table[fieldname].default + unique_queries.append( + Query(db, self.dialect.eq, table[fieldname], value)) + + if len(unique_queries) > 0: + unique_query = unique_queries[0] + + # if more than one field, build a query of ORs + for query in unique_queries[1:]: + unique_query = Query( + db, self.dialect._or, unique_query, query) + + if self.count(unique_query, distinct=False) != 0: + for query in unique_queries: + if self.count(query, distinct=False) != 0: + # one of the 'OR' queries failed, see which one + raise Exception( + "NOT UNIQUE constraint failed: %s" % + query.first.name) + + def insert(self, table, fields, safe=None): + """Safe determines whether a asynchronous request is done or a + synchronous action is done + For safety, we use by default synchronous requests""" + + values = {} + safe = self._get_safe(safe) + ctable = self._get_collection(table._tablename, safe) + + for k, v in fields: + if k.name not in ["id", "safe"]: + fieldname = k.name + fieldtype = table[k.name].type + values[fieldname] = self.represent(v, fieldtype) + + # validate notnulls + try: + self.check_notnull(table, values) + except Exception as e: + if hasattr(table, '_on_insert_error'): + return table._on_insert_error(table, fields, e) + raise e + + # validate uniques + try: + self.check_unique(table, values) + except Exception as e: + if hasattr(table, '_on_insert_error'): + return table._on_insert_error(table, fields, e) + raise e + + # perform the insert + result = ctable.insert_one(values) + + if result.acknowledged: + Oid = result.inserted_id + rid = Reference(long(str(Oid), 16)) + (rid._table, rid._record) = (table, None) + return rid + else: + return None + + def update(self, table, query, fields, safe=None): + # return amount of adjusted rows or zero, but no exceptions + # @ related not finding the result + if not isinstance(query, Query): + raise RuntimeError("Not implemented") + + safe = self._get_safe(safe) + if safe: + amount = 0 + else: + amount = self.count(query, distinct=False) + if amount == 0: + return amount + + expanded = Expansion(self, 'update', query, fields) + ctable = expanded.get_collection(safe) + if expanded.pipeline: + try: + for doc in ctable.aggregate(expanded.pipeline): + result = ctable.replace_one({'_id': doc['_id']}, doc) + if safe and result.acknowledged: + amount += result.matched_count + return amount + except Exception as e: + # TODO Reverse update query to verify that the query succeeded + raise RuntimeError( + "uncaught exception when updating rows: %s" % e) + try: + result = ctable.update_many( + filter=expanded.query_dict, + update={'$set': expanded.field_dicts}) + if safe and result.acknowledged: + amount = result.matched_count + return amount + except Exception as e: + # TODO Reverse update query to verify that the query succeeded + raise RuntimeError( + "uncaught exception when updating rows: %s" % e) + + def delete(self, table, query, safe=None): + if not isinstance(query, Query): + raise RuntimeError("query type %s is not supported" % type(query)) + + safe = self._get_safe(safe) + expanded = Expansion(self, 'delete', query) + ctable = expanded.get_collection(safe) + if expanded.pipeline: + deleted = [x['_id'] for x in ctable.aggregate(expanded.pipeline)] + else: + deleted = [x['_id'] for x in ctable.find(expanded.query_dict)] + + # find references to deleted items + db = self.db + cascade = [] + set_null = [] + for field in table._referenced_by: + if field.type == 'reference ' + table._tablename: + if field.ondelete == 'CASCADE': + cascade.append(field) + if field.ondelete == 'SET NULL': + set_null.append(field) + cascade_list = [] + set_null_list = [] + for field in table._referenced_by_list: + if field.type == 'list:reference ' + table._tablename: + if field.ondelete == 'CASCADE': + cascade_list.append(field) + if field.ondelete == 'SET NULL': + set_null_list.append(field) + + # perform delete + result = ctable.delete_many({"_id": {"$in": deleted}}) + if result.acknowledged: + amount = result.deleted_count + else: + amount = len(deleted) + + # clean up any references + if amount and deleted: + # ::TODO:: test if deleted references cascade + def remove_from_list(field, deleted, safe): + for delete in deleted: + modify = {field.name: delete} + dtable = self._get_collection(field.tablename, safe) + dtable.update_many( + filter=modify, update={'$pull': modify}) + + # for cascaded items, if the reference is the only item in the + # list, then remove the entire record, else delete reference + # from the list + for field in cascade_list: + for delete in deleted: + modify = {field.name: [delete]} + dtable = self._get_collection(field.tablename, safe) + dtable.delete_many(filter=modify) + remove_from_list(field, deleted, safe) + for field in set_null_list: + remove_from_list(field, deleted, safe) + for field in cascade: + db(field.belongs(deleted)).delete() + for field in set_null: + db(field.belongs(deleted)).update(**{field.name: None}) + return amount + + def bulk_insert(self, table, items): + return [self.insert(table, item) for item in items] + + +class Expansion(object): + """ + Class to encapsulate a pydal expression and track the parse + expansion and its results. + + Two different MongoDB mechanisms are targeted here. If the query + is sufficiently simple, then simple queries are generated. The + bulk of the complexity here is however to support more complex + queries that are targeted to the MongoDB Aggregation Pipeline. + + This class supports four operations: 'count', 'select', 'update' + and 'delete'. + + Behavior varies somewhat for each operation type. However + building each pipeline stage is shared where the behavior is the + same (or similar) for the different operations. + + In general an attempt is made to build the query without using the + pipeline, and if that fails then the query is rebuilt with the + pipeline. + + QUERY constructed in _build_pipeline_query(): + $project : used to calculate expressions if needed + $match: filters out records + + FIELDS constructed in _expand_fields(): + FIELDS:COUNT + $group : filter for distinct if needed + $group: count the records remaining + + FIELDS:SELECT + $group : implement aggregations if needed + $project: implement expressions (etc) for select + + FIELDS:UPDATE + $project: implement expressions (etc) for update + + HAVING constructed in _add_having(): + $project : used to calculate expressions + $match: filters out records + $project : used to filter out previous expression fields + + """ + + def __init__(self, adapter, crud, query, fields=(), tablename=None, + groupby=None, distinct=False, having=None): + self.adapter = adapter + self.NULL_QUERY = {'_id': { + '$gt': self.adapter.ObjectId('000000000000000000000000')}} + self._parse_data = {'pipeline': False, 'need_group': + bool(groupby or distinct or having)} + self.crud = crud + self.having = having + self.distinct = distinct + if not groupby and distinct: + if distinct is True: + # groupby gets all fields + self.groupby = fields + else: + self.groupby = distinct + else: + self.groupby = groupby + + if crud == 'update': + self.values = [(f[0], self.annotate_expression(f[1])) + for f in (fields or [])] + self.fields = [f[0] for f in self.values] + else: + self.fields = [self.annotate_expression(f) + for f in (fields or [])] + + self.tablename = (tablename or + adapter.get_table(query, *self.fields)._tablename) + if use_common_filters(query): + query = adapter.common_filter(query, [self.tablename]) + self.query = self.annotate_expression(query) + + # expand the query + self.pipeline = [] + self.query_dict = adapter.expand(self.query) + self.field_dicts = adapter.SON() + self.field_groups = adapter.SON() + self.field_groups['_id'] = adapter.SON() + + if self._parse_data['pipeline']: + # if the query needs the aggregation engine, set that up + self._build_pipeline_query() + + # expand the fields for the aggregation engine + self._expand_fields(None) + else: + # expand the fields + try: + if not self._parse_data['need_group']: + self._expand_fields(self._fields_loop_abort) + else: + self._parse_data['pipeline'] = True + raise StopIteration + except StopIteration: + # if the fields needs the aggregation engine, set that up + self.field_dicts = adapter.SON() + if self.query_dict: + if self.query_dict != self.NULL_QUERY: + self.pipeline = [{'$match': self.query_dict}] + self.query_dict = {} + # expand the fields for the aggregation engine + self._expand_fields(None) + + if not self._parse_data['pipeline']: + if crud == 'update': + # do not update id fields + for fieldname in ("_id", "id"): + if fieldname in self.field_dicts: + del self.field_dicts[fieldname] + else: + if crud == 'update': + self._add_all_fields_projection(self.field_dicts) + self.field_dicts = adapter.SON() + + elif crud == 'select': + if self._parse_data['need_group']: + if not self.groupby: + # no groupby, aggregate all records + self.field_groups['_id'] = None + # id has no value after aggregations + self.field_dicts['_id'] = False + self.pipeline.append({'$group': self.field_groups}) + if self.field_dicts: + self.pipeline.append({'$project': self.field_dicts}) + self.field_dicts = adapter.SON() + self._add_having() + + elif crud == 'count': + if self._parse_data['need_group']: + self.pipeline.append({'$group': self.field_groups}) + self.pipeline.append( + {'$group': {"_id": None, 'count': {"$sum": 1}}}) + + #elif crud == 'delete': + # pass + + @property + def dialect(self): + return self.adapter.dialect + + def _build_pipeline_query(self): + # search for anything needing the $match stage. + # currently only '$regex' requires the match stage + def parse_need_match_stage(items, parent, parent_key): + need_match = False + non_matched_indices = [] + if isinstance(items, list): + indices = range(len(items)) + elif isinstance(items, dict): + indices = items.keys() + else: + return + + for i in indices: + if parse_need_match_stage(items[i], items, i): + need_match = True + + elif i not in [self.dialect.REGEXP_MARK1, + self.dialect.REGEXP_MARK2]: + non_matched_indices.append(i) + + if i == self.dialect.REGEXP_MARK1: + need_match = True + self.query_dict['project'].update(items[i]) + parent[parent_key] = items[self.dialect.REGEXP_MARK2] + + if need_match: + for i in non_matched_indices: + name = str(items[i]) + self.query_dict['project'][name] = items[i] + items[i] = {name: True} + + if parent is None and self.query_dict['project']: + self.query_dict['match'] = items + return need_match + + expanded = self.adapter.expand(self.query) + + if self.dialect.REGEXP_MARK1 in expanded: + # the REGEXP_MARK is at the top of the tree, so can just split + # the regex over a '$project' and a '$match' + self.query_dict = None + match = expanded[self.dialect.REGEXP_MARK2] + project = expanded[self.dialect.REGEXP_MARK1] + + else: + self.query_dict = {'project': {}, 'match': {}} + if parse_need_match_stage(expanded, None, None): + project = self.query_dict['project'] + match = self.query_dict['match'] + else: + project = {'__query__': expanded} + match = {'__query__': True} + + if self.crud in ['select', 'update']: + self._add_all_fields_projection(project) + else: + self.pipeline.append({'$project': project}) + self.pipeline.append({'$match': match}) + self.query_dict = None + + def _expand_fields(self, mid_loop): + if self.crud == 'update': + mid_loop = mid_loop or self._fields_loop_update_pipeline + for field, value in self.values: + self._expand_field(field, value, mid_loop) + elif self.crud in ['select', 'count']: + mid_loop = mid_loop or self._fields_loop_select_pipeline + for field in self.fields: + self._expand_field(field, field, mid_loop) + elif self.fields: + raise RuntimeError(self.crud + " not supported with fields") + + def _expand_field(self, field, value, mid_loop): + expanded = {} + if isinstance(field, Field): + expanded = self.adapter.expand(value, field.type) + elif isinstance(field, (Expression, Query)): + expanded = self.adapter.expand(field) + field.name = str(expanded) + else: + raise RuntimeError("%s not supported with fields" % type(field)) + + if mid_loop: + expanded = mid_loop(expanded, field, value) + self.field_dicts[field.name] = expanded + + def _fields_loop_abort(self, expanded, *args): + # if we need the aggregation engine, then start over + if self._parse_data['pipeline']: + raise StopIteration() + return expanded + + def _fields_loop_update_pipeline(self, expanded, field, value): + if not isinstance(value, Expression): + if self.adapter.server_version_major >= 2.6: + expanded = {'$literal': expanded} + + # '$literal' not present in server versions < 2.6 + elif field.type in ['string', 'text', 'password']: + expanded = {'$concat': [expanded]} + elif field.type in ['integer', 'bigint', 'float', 'double']: + expanded = {'$add': [expanded]} + elif field.type == 'boolean': + expanded = {'$and': [expanded]} + elif field.type in ['date', 'time', 'datetime']: + expanded = {'$add': [expanded]} + else: + raise RuntimeError( + "updating with expressions not supported for field type " + + "'%s' in MongoDB version < 2.6" % field.type) + return expanded + + def _fields_loop_select_pipeline(self, expanded, field, value): + # search for anything needing $group + def parse_groups(items, parent, parent_key): + for item in items: + if isinstance(items[item], list): + for list_item in items[item]: + if isinstance(list_item, dict): + parse_groups(list_item, items[item], + items[item].index(list_item)) + + elif isinstance(items[item], dict): + parse_groups(items[item], items, item) + + if item == self.dialect.GROUP_MARK: + name = str(items) + self.field_groups[name] = items[item] + parent[parent_key] = '$' + name + return items + + if self.dialect.AS_MARK in field.name: + # The AS_MARK in the field name is used by base to alias the + # result, we don't actually need the AS_MARK in the parse tree + # so we remove it here. + if isinstance(expanded, list): + # AS mark is first element in list, drop it + expanded = expanded[1] + + elif self.dialect.AS_MARK in expanded: + # AS mark is element in dict, drop it + del expanded[self.dialect.AS_MARK] + + else: + # ::TODO:: should be possible to do this... + raise SyntaxError("AS() not at top of parse tree") + + if self.dialect.GROUP_MARK in expanded: + # the GROUP_MARK is at the top of the tree, so can just pass + # the group result straight through the '$project' stage + self.field_groups[field.name] = expanded[self.dialect.GROUP_MARK] + expanded = 1 + + elif self.dialect.GROUP_MARK in field.name: + # the GROUP_MARK is not at the top of the tree, so we need to + # pass the group results through to a '$project' stage. + expanded = parse_groups(expanded, None, None) + + elif self._parse_data['need_group']: + if field in self.groupby: + # this is a 'groupby' field + self.field_groups['_id'][field.name] = expanded + expanded = '$_id.' + field.name + else: + raise SyntaxError("field '%s' not in groupby" % field) + + return expanded + + def _add_all_fields_projection(self, fields): + for fieldname in self.adapter.db[self.tablename].fields: + # add all fields to projection to pass them through + if fieldname not in fields and fieldname not in ("_id", "id"): + fields[fieldname] = 1 + self.pipeline.append({'$project': fields}) + + def _add_having(self): + if not self.having: + return + self._expand_field( + self.having, None, self._fields_loop_select_pipeline) + fields = {'__having__': self.field_dicts[self.having.name]} + for fieldname in self.pipeline[-1]['$project']: + # add all fields to projection to pass them through + if fieldname not in fields and fieldname not in ("_id", "id"): + fields[fieldname] = 1 + + self.pipeline.append({'$project': copy.copy(fields)}) + self.pipeline.append({'$match': {'__having__': True}}) + del fields['__having__'] + self.pipeline.append({'$project': fields}) + + def annotate_expression(self, expression): + def mark_has_field(expression): + if not isinstance(expression, (Expression, Query)): + return False + first_has_field = mark_has_field(expression.first) + second_has_field = mark_has_field(expression.second) + expression.has_field = (isinstance(expression, Field) or + first_has_field or second_has_field) + return expression.has_field + + def add_parse_data(child, parent): + if isinstance(child, (Expression, Query)): + child.parse_root = parent.parse_root + child.parse_parent = parent + child.parse_depth = parent.parse_depth + 1 + child._parse_data = parent._parse_data + add_parse_data(child.first, child) + add_parse_data(child.second, child) + elif isinstance(child, (list, tuple)): + for c in child: + add_parse_data(c, parent) + + if isinstance(expression, (Expression, Query)): + expression.parse_root = expression + expression.parse_depth = -1 + expression._parse_data = self._parse_data + add_parse_data(expression, expression) + mark_has_field(expression) + return expression + + def get_collection(self, safe=None): + return self.adapter._get_collection(self.tablename, safe) + + +class MongoBlob(Binary): + MONGO_BLOB_BYTES = USER_DEFINED_SUBTYPE + MONGO_BLOB_NON_UTF8_STR = USER_DEFINED_SUBTYPE + 1 + + def __new__(cls, value): + # return None and Binary() unmolested + if value is None or isinstance(value, Binary): + return value + + # bytearray is marked as MONGO_BLOB_BYTES + if isinstance(value, bytearray): + return Binary.__new__( + cls, bytes(value), MongoBlob.MONGO_BLOB_BYTES) + + # return non-strings as Binary(), eg: PY3 bytes() + if not isinstance(value, basestring): + return Binary(value) + + # if string is encodable as UTF-8, then return as string + try: + value.encode('utf-8') + return value + except UnicodeDecodeError: + # string which can not be UTF-8 encoded, eg: pickle strings + return Binary.__new__( + cls, value, MongoBlob.MONGO_BLOB_NON_UTF8_STR) + + def __repr__(self): + return repr(MongoBlob.decode(self)) + + @staticmethod + def decode(value): + if isinstance(value, Binary): + if value.subtype == MongoBlob.MONGO_BLOB_BYTES: + return bytearray(value) + if value.subtype == MongoBlob.MONGO_BLOB_NON_UTF8_STR: + return str(value) + return value diff --git a/web2py/gluon/packages/dal/pydal/adapters/mssql.py b/web2py/gluon/packages/dal/pydal/adapters/mssql.py new file mode 100644 index 0000000..84914a1 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/mssql.py @@ -0,0 +1,184 @@ +import re +from .._compat import PY2, iteritems, integer_types, to_unicode, long +from .._globals import IDENTITY +from .base import SQLAdapter +from . import adapters, with_connection_or_raise + +class Slicer(object): + def rowslice(self, rows, minimum=0, maximum=None): + if maximum is None: + return rows[minimum:] + return rows[minimum:maximum] + + +class MSSQL(SQLAdapter): + dbengine = 'mssql' + drivers = ('pyodbc',) + + REGEX_DSN = re.compile('^(?P.+)$') + REGEX_URI = re.compile( + '^(?P[^:@]+)(\:(?P[^@]*))?@(?P\[[^/]+\]|' + + '[^\:/]+)(\:(?P[0-9]+))?/(?P[^\?]+)(\?(?P.*))?$') + REGEX_ARGPATTERN = re.compile('(?P[^=]+)=(?P[^&]*)') + + def __init__(self, db, uri, pool_size=0, folder=None, db_codec='UTF-8', + credential_decoder=IDENTITY, driver_args={}, + adapter_args={}, do_connect=True, srid=4326, + after_connection=None): + self.srid = srid + super(MSSQL, self).__init__( + db, uri, pool_size, folder, db_codec, credential_decoder, + driver_args, adapter_args, do_connect, after_connection) + + def _initialize_(self, do_connect): + super(MSSQL, self)._initialize_(do_connect) + ruri = self.uri.split('://', 1)[1] + if '@' not in ruri: + try: + m = self.REGEX_DSN.match(ruri) + if not m: + raise SyntaxError( + 'Parsing uri string(%s) has no result' % self.uri) + dsn = m.group('dsn') + if not dsn: + raise SyntaxError('DSN required') + except SyntaxError as e: + self.db.logger.error('NdGpatch error') + raise e + self.cnxn = dsn + else: + m = self.REGEX_URI.match(ruri) + if not m: + raise SyntaxError( + "Invalid URI string in DAL: %s" % self.uri) + user = self.credential_decoder(m.group('user')) + if not user: + raise SyntaxError('User required') + password = self.credential_decoder(m.group('password')) + if not password: + password = '' + host = m.group('host') + if not host: + raise SyntaxError('Host name required') + db = m.group('db') + if not db: + raise SyntaxError('Database name required') + port = m.group('port') or '1433' + # Parse the optional url name-value arg pairs after the '?' + # (in the form of arg1=value1&arg2=value2&...) + # (drivers like FreeTDS insist on uppercase parameter keys) + argsdict = {'DRIVER': '{SQL Server}'} + urlargs = m.group('urlargs') or '' + for argmatch in self.REGEX_ARGPATTERN.finditer(urlargs): + argsdict[str(argmatch.group('argkey')).upper()] = \ + argmatch.group('argvalue') + urlargs = ';'.join([ + '%s=%s' % (ak, av) for (ak, av) in iteritems(argsdict)]) + self.cnxn = 'SERVER=%s;PORT=%s;DATABASE=%s;UID=%s;PWD=%s;%s' \ + % (host, port, db, user, password, urlargs) + + def connector(self): + return self.driver.connect(self.cnxn, **self.driver_args) + + def lastrowid(self, table): + self.execute('SELECT SCOPE_IDENTITY();') + return long(self.cursor.fetchone()[0]) + + +@adapters.register_for('mssql') +class MSSQL1(MSSQL, Slicer): + pass + + +@adapters.register_for('mssql3') +class MSSQL3(MSSQL): + pass + + +@adapters.register_for('mssql4') +class MSSQL4(MSSQL): + pass + + +class MSSQLN(MSSQL): + def represent(self, obj, field_type): + rv = super(MSSQLN, self).represent(obj, field_type) + if field_type in ('string', 'text', 'json') and rv[:1] == "'": + rv = 'N' + rv + return rv + + @with_connection_or_raise + def execute(self, *args, **kwargs): + if PY2: + args = list(args) + args[0] = to_unicode(args[0]) + return super(MSSQLN, self).execute(*args, **kwargs) + + +@adapters.register_for('mssqln', 'mssql2') +class MSSQL1N(MSSQLN, Slicer): + pass + + +@adapters.register_for('mssql3n') +class MSSQL3N(MSSQLN): + pass + + +@adapters.register_for('mssql4n') +class MSSQL4N(MSSQLN): + pass + + +@adapters.register_for('vertica') +class Vertica(MSSQL1): + def lastrowid(self, table): + self.execute('SELECT SCOPE_IDENTITY();') + return long(self.cursor.fetchone()[0]) + + +@adapters.register_for('sybase') +class Sybase(MSSQL1): + dbengine = 'sybase' + + def _initialize_(self, do_connect): + super(MSSQL, self)._initialize_(do_connect) + ruri = self.uri.split('://', 1)[1] + if '@' not in ruri: + try: + m = self.REGEX_DSN.match(ruri) + if not m: + raise SyntaxError( + 'Parsing uri string(%s) has no result' % self.uri) + dsn = m.group('dsn') + if not dsn: + raise SyntaxError('DSN required') + except SyntaxError as e: + self.db.logger.error('NdGpatch error') + raise e + self.cnxn = dsn + else: + m = self.REGEX_URI.match(ruri) + if not m: + raise SyntaxError( + "Invalid URI string in DAL: %s" % self.uri) + user = self.credential_decoder(m.group('user')) + if not user: + raise SyntaxError('User required') + password = self.credential_decoder(m.group('password')) + if not password: + password = '' + host = m.group('host') + if not host: + raise SyntaxError('Host name required') + db = m.group('db') + if not db: + raise SyntaxError('Database name required') + port = m.group('port') or '1433' + self.dsn = 'sybase:host=%s:%s;dbname=%s' % (host, port, db) + self.driver_args.update( + user=self.credential_decoder(user), + passwd=self.credential_decoder(password)) + + def connector(self): + return self.driver.connect(self.dsn, **self.driver_args) diff --git a/web2py/gluon/packages/dal/pydal/adapters/mysql.py b/web2py/gluon/packages/dal/pydal/adapters/mysql.py new file mode 100644 index 0000000..62108c9 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/mysql.py @@ -0,0 +1,82 @@ +import re +from .base import SQLAdapter +from . import adapters, with_connection + + +@adapters.register_for('mysql') +class MySQL(SQLAdapter): + dbengine = 'mysql' + drivers = ('MySQLdb', 'pymysql', 'mysqlconnector') + commit_on_alter_table = True + support_distributed_transaction = True + + REGEX_URI = re.compile( + '^(?P[^:@]+)(\:(?P[^@]*))?@(?P\[[^/]+\]|' + + '[^\:/]*)(\:(?P[0-9]+))?/(?P[^?]+)(\?set_encoding=' + + '(?P\w+))?(\?unix_socket=(?P.+))?$') + + def _initialize_(self, do_connect): + super(MySQL, self)._initialize_(do_connect) + ruri = self.uri.split('://', 1)[1] + m = self.REGEX_URI.match(ruri) + if not m: + raise SyntaxError("Invalid URI string in DAL") + user = self.credential_decoder(m.group('user')) + if not user: + raise SyntaxError('User required') + password = self.credential_decoder(m.group('password')) + if not password: + password = '' + host = m.group('host') + socket = m.group('socket') + if not host and not socket: + raise SyntaxError('Host name required') + db = m.group('db') + if not db and not socket: + raise SyntaxError('Database name required') + port = int(m.group('port') or '3306') + charset = m.group('charset') or 'utf8' + if socket: + self.driver_args.update( + unix_socket=socket, + user=user, passwd=password, + charset=charset) + if db: + self.driver_args.update(db=db) + else: + self.driver_args.update( + db=db, user=user, passwd=password, host=host, port=port, + charset=charset) + + def connector(self): + return self.driver.connect(**self.driver_args) + + def after_connection(self): + self.execute("SET FOREIGN_KEY_CHECKS=1;") + self.execute("SET sql_mode='NO_BACKSLASH_ESCAPES';") + + def distributed_transaction_begin(self, key): + self.execute("XA START;") + + @with_connection + def prepare(self, key): + self.execute("XA END;") + self.execute("XA PREPARE;") + + @with_connection + def commit_prepared(self, key): + self.execute("XA COMMIT;") + + @with_connection + def rollback_prepared(self, key): + self.execute("XA ROLLBACK;") + + +@adapters.register_for('cubrid') +class Cubrid(MySQL): + dbengine = "cubrid" + drivers = ('cubriddb',) + + def _initialize_(self, do_connect): + super(Cubrid, self)._initialize_(do_connect) + del self.driver_args['charset'] diff --git a/web2py/gluon/packages/dal/pydal/adapters/oracle.py b/web2py/gluon/packages/dal/pydal/adapters/oracle.py new file mode 100644 index 0000000..a7051ed --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/oracle.py @@ -0,0 +1,161 @@ +import re +import sys +from .._compat import integer_types, long +from ..helpers.classes import Reference +from .base import SQLAdapter +from . import adapters, with_connection_or_raise + +@adapters.register_for('oracle') +class Oracle(SQLAdapter): + dbengine = 'oracle' + drivers = ('cx_Oracle',) + + cmd_fix = re.compile( + "[^']*('[^']*'[^']*)*\:(?PCLOB\('([^']+|'')*'\))") + + def _initialize_(self, do_connect): + super(Oracle, self)._initialize_(do_connect) + self.ruri = self.uri.split('://', 1)[1] + if 'threaded' not in self.driver_args: + self.driver_args['threaded'] = True + + def connector(self): + return self.driver.connect(self.ruri, **self.driver_args) + + def after_connection(self): + self.execute( + "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';") + self.execute( + "ALTER SESSION SET NLS_TIMESTAMP_FORMAT = " + + "'YYYY-MM-DD HH24:MI:SS';") + + def test_connection(self): + self.execute('SELECT 1 FROM DUAL;') + + @with_connection_or_raise + def execute(self, *args, **kwargs): + command = self.filter_sql_command(args[0]) + i = 1 + while True: + m = self.cmd_fix.match(command) + if not m: + break + command = command[:m.start('clob')] + str(i) + \ + command[m.end('clob'):] + args.append(m.group('clob')[6:-2].replace("''", "'")) + i += 1 + if command[-1:] == ';': + command = command[:-1] + handlers = self._build_handlers_for_execution() + for handler in handlers: + handler.before_execute(command) + rv = self.cursor.execute(command, *args[1:], **kwargs) + for handler in handlers: + handler.after_execute(command) + return rv + + def lastrowid(self, table): + sequence_name = table._sequence_name + self.execute('SELECT %s.currval FROM dual;' % sequence_name) + return long(self.cursor.fetchone()[0]) + + def create_sequence_and_triggers(self, query, table, **args): + tablename = table._rname + id_name = table._id._rname + sequence_name = table._sequence_name + trigger_name = table._trigger_name + self.execute(query) + self.execute( + 'CREATE SEQUENCE %s START WITH 1 INCREMENT BY 1 NOMAXVALUE MINVALUE -1;' + % sequence_name) + self.execute(_trigger_sql % dict( + trigger_name=trigger_name, tablename=tablename, + sequence_name=sequence_name, + id=id_name) + ) + + def _select_aux_execute(self, sql): + self.execute(sql) + return self.fetchall() + + def fetchall(self): + from ..drivers import cx_Oracle + if any(x[1] == cx_Oracle.LOB or x[1] == cx_Oracle.CLOB + for x in self.cursor.description): + return [tuple( + [(c.read() if type(c) == cx_Oracle.LOB else c) for c in r] + ) for r in self.cursor] + else: + return self.cursor.fetchall() + + def sqlsafe_table(self, tablename, original_tablename=None): + if original_tablename is not None: + return ( + self.dialect.quote_template + ' ' + + self.dialect.quote_template + ) % (original_tablename, tablename) + return self.dialect.quote(tablename) + + def _build_value_for_insert(self, field, value, r_values): + if field.type is 'text': + r_values[':' + field._rname] = self.expand(value, field.type) + return ':' + field._rname + return self.expand(value, field.type) + + def _insert(self, table, fields): + if fields: + r_values = {} + return self.dialect.insert( + table._rname, + ','.join(el[0]._rname for el in fields), + ','.join( + self._build_value_for_insert(f, v, r_values) + for f, v in fields) + ), r_values + return self.dialect.insert_empty(table._rname), None + + def insert(self, table, fields): + query, values = self._insert(table, fields) + try: + if not values: + self.execute(query) + else: + self.execute(query, *values) + except: + e = sys.exc_info()[1] + if hasattr(table, '_on_insert_error'): + return table._on_insert_error(table, fields, e) + raise e + if hasattr(table, '_primarykey'): + pkdict = dict([ + (k[0].name, k[1]) for k in fields + if k[0].name in table._primarykey]) + if pkdict: + return pkdict + id = self.lastrowid(table) + if hasattr(table, '_primarykey') and len(table._primarykey) == 1: + id = {table._primarykey[0]: id} + if not isinstance(id, integer_types): + return id + rid = Reference(id) + (rid._table, rid._record) = (table, None) + return rid + +_trigger_sql = """ +CREATE OR REPLACE TRIGGER %(trigger_name)s BEFORE INSERT ON %(tablename)s FOR EACH ROW +DECLARE + curr_val NUMBER; + diff_val NUMBER; + PRAGMA autonomous_transaction; +BEGIN + IF :NEW.%(id)s IS NOT NULL THEN + EXECUTE IMMEDIATE 'SELECT %(sequence_name)s.nextval FROM dual' INTO curr_val; + diff_val := :NEW.%(id)s - curr_val - 1; + IF diff_val != 0 THEN + EXECUTE IMMEDIATE 'alter sequence %(sequence_name)s increment by '|| diff_val; + EXECUTE IMMEDIATE 'SELECT %(sequence_name)s.nextval FROM dual' INTO curr_val; + EXECUTE IMMEDIATE 'alter sequence %(sequence_name)s increment by 1'; + END IF; + END IF; + SELECT %(sequence_name)s.nextval INTO :NEW.%(id)s FROM DUAL; +END;""" diff --git a/web2py/gluon/packages/dal/pydal/adapters/postgres.py b/web2py/gluon/packages/dal/pydal/adapters/postgres.py new file mode 100644 index 0000000..64b763c --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/postgres.py @@ -0,0 +1,284 @@ +import re +from .._compat import PY2, with_metaclass, iterkeys, to_unicode, long +from .._globals import IDENTITY, THREAD_LOCAL +from ..drivers import psycopg2_adapt +from ..helpers.classes import ConnectionConfigurationMixin +from .base import SQLAdapter +from . import AdapterMeta, adapters, with_connection, with_connection_or_raise + + +class PostgreMeta(AdapterMeta): + def __call__(cls, *args, **kwargs): + if cls not in [Postgre, PostgreNew, PostgreBoolean]: + return AdapterMeta.__call__(cls, *args, **kwargs) + available_drivers = [ + driver for driver in cls.drivers + if driver in iterkeys(kwargs['db']._drivers_available)] + uri_items = kwargs['uri'].split('://', 1)[0].split(':') + uri_driver = uri_items[1] if len(uri_items) > 1 else None + if uri_driver and uri_driver in available_drivers: + driver = uri_driver + else: + driver = available_drivers[0] if available_drivers else \ + cls.drivers[0] + cls = adapters._registry_[uri_items[0] + ":" + driver] + return AdapterMeta.__call__(cls, *args, **kwargs) + + +@adapters.register_for('postgres') +class Postgre( + with_metaclass(PostgreMeta, ConnectionConfigurationMixin, SQLAdapter) +): + dbengine = 'postgres' + drivers = ('psycopg2', 'pg8000') + support_distributed_transaction = True + + REGEX_URI = re.compile( + '^(?P[^:@]+)(\:(?P[^@]*))?@(?P\[[^/]+\]|' + + '[^\:@]*)(\:(?P[0-9]+))?/(?P[^\?]+)' + + '(\?sslmode=(?P.+))?(\?unix_socket=(?P.+))?$') + + def __init__(self, db, uri, pool_size=0, folder=None, db_codec='UTF-8', + credential_decoder=IDENTITY, driver_args={}, + adapter_args={}, do_connect=True, srid=4326, + after_connection=None): + self.srid = srid + super(Postgre, self).__init__( + db, uri, pool_size, folder, db_codec, credential_decoder, + driver_args, adapter_args, do_connect, after_connection) + + def _initialize_(self, do_connect): + super(Postgre, self)._initialize_(do_connect) + ruri = self.uri.split('://', 1)[1] + m = self.REGEX_URI.match(ruri) + if not m: + raise SyntaxError("Invalid URI string in DAL") + user = self.credential_decoder(m.group('user')) + if not user: + raise SyntaxError('User required') + password = self.credential_decoder(m.group('password')) + if not password: + password = '' + host = m.group('host') + socket = m.group('socket') + if not host and not socket: + raise SyntaxError('Host name required') + db = m.group('db') + if not db and not socket: + raise SyntaxError('Database name required') + port = int(m.group('port') or '5432') + sslmode = m.group('sslmode') + if socket: + self.driver_args.update(user=user, host=socket, port=port, password=password) + if db: + self.driver_args['database'] = db + else: + self.driver_args.update(database=db, user=user, host=host, port=port, password=password) + if sslmode: + self.driver_args['sslmode'] = sslmode + # choose diver according uri + if self.driver: + self.__version__ = "%s %s" % (self.driver.__name__, + self.driver.__version__) + else: + self.__version__ = None + THREAD_LOCAL._pydal_last_insert_ = None + self._mock_reconnect() + + def _get_json_dialect(self): + from ..dialects.postgre import PostgreDialectJSON + return PostgreDialectJSON + + def _get_json_parser(self): + from ..parsers.postgre import PostgreAutoJSONParser + return PostgreAutoJSONParser + + @property + def _last_insert(self): + return THREAD_LOCAL._pydal_last_insert_ + + @_last_insert.setter + def _last_insert(self, value): + THREAD_LOCAL._pydal_last_insert_ = value + + def connector(self): + return self.driver.connect(**self.driver_args) + + def after_connection(self): + self.execute("SET CLIENT_ENCODING TO 'UTF8'") + self.execute("SET standard_conforming_strings=on;") + + def _configure_on_first_reconnect(self): + self._config_json() + + def lastrowid(self, table): + if self._last_insert: + return long(self.cursor.fetchone()[0]) + sequence_name = table._sequence_name + self.execute("SELECT currval(%s);" % self.adapt(sequence_name)) + return long(self.cursor.fetchone()[0]) + + def _insert(self, table, fields): + self._last_insert = None + if fields: + retval = None + if hasattr(table, '_id'): + self._last_insert = (table._id, 1) + retval = table._id._rname + return self.dialect.insert( + table._rname, + ','.join(el[0]._rname for el in fields), + ','.join(self.expand(v, f.type) for f, v in fields), + retval) + return self.dialect.insert_empty(table._rname) + + @with_connection + def prepare(self, key): + self.execute("PREPARE TRANSACTION '%s';" % key) + + @with_connection + def commit_prepared(self, key): + self.execute("COMMIT PREPARED '%s';" % key) + + @with_connection + def rollback_prepared(self, key): + self.execute("ROLLBACK PREPARED '%s';" % key) + + +@adapters.register_for('postgres:psycopg2') +class PostgrePsyco(Postgre): + drivers = ('psycopg2',) + + def _config_json(self): + use_json = self.driver.__version__ >= "2.0.12" and \ + self.connection.server_version >= 90200 + if use_json: + self.dialect = self._get_json_dialect()(self) + if self.driver.__version__ >= '2.5.0': + self.parser = self._get_json_parser()(self) + + def adapt(self, obj): + adapted = psycopg2_adapt(obj) + # deal with new relic Connection Wrapper (newrelic>=2.10.0.8) + cxn = getattr(self.connection, '__wrapped__', self.connection) + adapted.prepare(cxn) + rv = adapted.getquoted() + if not PY2: + if isinstance(rv, bytes): + return rv.decode('utf-8') + return rv + + +@adapters.register_for('postgres:pg8000') +class PostgrePG8000(Postgre): + drivers = ('pg8000',) + + def _config_json(self): + if self.connection._server_version >= "9.2.0": + self.dialect = self._get_json_dialect()(self) + if self.driver.__version__ >= '1.10.2': + self.parser = self._get_json_parser()(self) + + def adapt(self, obj): + return "'%s'" % obj.replace("%", "%%").replace("'", "''") + + @with_connection_or_raise + def execute(self, *args, **kwargs): + if PY2: + args = list(args) + args[0] = to_unicode(args[0]) + return super(PostgrePG8000, self).execute(*args, **kwargs) + + +@adapters.register_for('postgres2') +class PostgreNew(Postgre): + def _get_json_dialect(self): + from ..dialects.postgre import PostgreDialectArraysJSON + return PostgreDialectArraysJSON + + def _get_json_parser(self): + from ..parsers.postgre import PostgreNewAutoJSONParser + return PostgreNewAutoJSONParser + + +@adapters.register_for('postgres2:psycopg2') +class PostgrePsycoNew(PostgrePsyco, PostgreNew): + pass + + +@adapters.register_for('postgres2:pg8000') +class PostgrePG8000New(PostgrePG8000, PostgreNew): + pass + + +@adapters.register_for('postgres3') +class PostgreBoolean(PostgreNew): + def _get_json_dialect(self): + from ..dialects.postgre import PostgreDialectBooleanJSON + return PostgreDialectBooleanJSON + + def _get_json_parser(self): + from ..parsers.postgre import PostgreBooleanAutoJSONParser + return PostgreBooleanAutoJSONParser + + +@adapters.register_for('postgres3:psycopg2') +class PostgrePsycoBoolean(PostgrePsycoNew, PostgreBoolean): + pass + + +@adapters.register_for('postgres3:pg8000') +class PostgrePG8000Boolean(PostgrePG8000New, PostgreBoolean): + pass + + +@adapters.register_for('jdbc:postgres') +class JDBCPostgre(Postgre): + drivers = ('zxJDBC',) + + REGEX_URI = re.compile( + '^(?P[^:@]+)(\:(?P[^@]*))?@(?P\[[^/]+\]|' + + '[^\:/]+)(\:(?P[0-9]+))?/(?P.+)$') + + def _initialize_(self, do_connect): + super(Postgre, self)._initialize_(do_connect) + ruri = self.uri.split('://', 1)[1] + m = self.REGEX_URI.match(ruri) + if not m: + raise SyntaxError("Invalid URI string in DAL") + user = self.credential_decoder(m.group('user')) + if not user: + raise SyntaxError('User required') + password = self.credential_decoder(m.group('password')) + if not password: + password = '' + host = m.group('host') + if not host: + raise SyntaxError('Host name required') + db = m.group('db') + if not db: + raise SyntaxError('Database name required') + port = m.group('port') or '5432' + self.dsn = ( + 'jdbc:postgresql://%s:%s/%s' % (host, port, db), user, password) + # choose diver according uri + if self.driver: + self.__version__ = "%s %s" % (self.driver.__name__, + self.driver.__version__) + else: + self.__version__ = None + THREAD_LOCAL._pydal_last_insert_ = None + self._mock_reconnect() + + def connector(self): + return self.driver.connect(*self.dsn, **self.driver_args) + + def after_connection(self): + self.connection.set_client_encoding('UTF8') + self.execute('BEGIN;') + self.execute("SET CLIENT_ENCODING TO 'UNICODE';") + + def _config_json(self): + use_json = self.connection.dbversion >= "9.2.0" + if use_json: + self.dialect = self._get_json_dialect()(self) diff --git a/web2py/gluon/packages/dal/pydal/adapters/sap.py b/web2py/gluon/packages/dal/pydal/adapters/sap.py new file mode 100644 index 0000000..046bf95 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/sap.py @@ -0,0 +1,49 @@ +import re +from .._compat import integer_types, long +from .base import SQLAdapter +from . import adapters + +@adapters.register_for('sapdb') +class SAPDB(SQLAdapter): + dbengine = 'sapdb' + drivers = ('sapdb',) + + REGEX_URI = re.compile( + '^(?P[^:@]+)(\:(?P[^@]*))?@(?P\[[^/]+\]|' + + '[^\:@]+)(\:(?P[0-9]+))?/(?P[^\?]+)' + + '(\?sslmode=(?P.+))?$') + + def _initialize_(self, do_connect): + super(SAPDB, self)._initialize_(do_connect) + ruri = self.uri.split('://', 1)[1] + m = self.REGEX_URI.match(ruri) + if not m: + raise SyntaxError("Invalid URI string in DAL") + user = self.credential_decoder(m.group('user')) + if not user: + raise SyntaxError('User required') + password = self.credential_decoder(m.group('password')) + if not password: + password = '' + host = m.group('host') + if not host: + raise SyntaxError('Host name required') + db = m.group('db') + if not db: + raise SyntaxError('Database name required') + self.driver_args.update( + user=user, password=password, database=db, host=host) + + def connector(self): + self.driver.connect(**self.driver_args) + + def lastrowid(self, table): + self.execute("select %s.NEXTVAL from dual" % table._sequence_name) + return long(self.cursor.fetchone()[0]) + + def create_sequence_and_triggers(self, query, table, **args): + self.execute('CREATE SEQUENCE %s;' % table._sequence_name) + self.execute( + "ALTER TABLE %s ALTER COLUMN %s SET DEFAULT NEXTVAL('%s');" % + (table._rname, table._id._rname, table._sequence_name)) + self.execute(query) diff --git a/web2py/gluon/packages/dal/pydal/adapters/sqlite.py b/web2py/gluon/packages/dal/pydal/adapters/sqlite.py new file mode 100644 index 0000000..36f79c3 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/sqlite.py @@ -0,0 +1,123 @@ +import locale +import platform +import re +import sys +from datetime import datetime +from time import mktime +from .._compat import PY2, pjoin +from .base import SQLAdapter +from . import adapters + + +@adapters.register_for('sqlite', 'sqlite:memory') +class SQLite(SQLAdapter): + dbengine = 'sqlite' + drivers = ('sqlite2', 'sqlite3') + + def _initialize_(self, do_connect): + self.pool_size = 0 + super(SQLite, self)._initialize_(do_connect) + path_encoding = sys.getfilesystemencoding() \ + or locale.getdefaultlocale()[1] or 'utf8' + if ':memory' in self.uri.split('://', 1)[0]: + self.dbpath = ':memory:' + else: + self.dbpath = self.uri.split('://', 1)[1] + if self.dbpath[0] != '/': + if PY2: + self.dbpath = pjoin( + self.folder.decode(path_encoding).encode('utf8'), + self.dbpath) + else: + self.dbpath = pjoin(self.folder, self.dbpath) + if 'check_same_thread' not in self.driver_args: + self.driver_args['check_same_thread'] = False + if 'detect_types' not in self.driver_args and do_connect: + self.driver_args['detect_types'] = self.driver.PARSE_DECLTYPES + + def _driver_from_uri(self): + return None + + def connector(self): + return self.driver.Connection(self.dbpath, **self.driver_args) + + @staticmethod + def web2py_extract(lookup, s): + table = { + 'year': (0, 4), 'month': (5, 7), 'day': (8, 10), 'hour': (11, 13), + 'minute': (14, 16), 'second': (17, 19)} + try: + if lookup != 'epoch': + (i, j) = table[lookup] + return int(s[i:j]) + else: + return mktime( + datetime.strptime(s, '%Y-%m-%d %H:%M:%S').timetuple()) + except: + return None + + @staticmethod + def web2py_regexp(expression, item): + if item is None: + return False + return re.compile(expression).search(item) is not None + + def _register_extract(self): + self.connection.create_function( + 'web2py_extract', 2, self.web2py_extract) + + def _register_regexp(self): + self.connection.create_function( + "REGEXP", 2, self.web2py_regexp) + + def after_connection(self): + self._register_extract() + self._register_regexp() + if self.adapter_args.get('foreign_keys', True): + self.execute('PRAGMA foreign_keys=ON;') + + def select(self, query, fields, attributes): + if attributes.get('for_update', False) and 'cache' not in attributes: + self.execute('BEGIN IMMEDIATE TRANSACTION;') + return super(SQLite, self).select(query, fields, attributes) + + def delete(self, table, query): + db = self.db + deleted = [x[table._id.name] for x in db(query).select(table._id)] + counter = super(SQLite, self).delete(table, query) + if counter: + for field in table._referenced_by: + if field.type == 'reference ' + table._dalname \ + and field.ondelete == 'CASCADE': + db(field.belongs(deleted)).delete() + return counter + + +@adapters.register_for('spatialite', 'spatialite:memory') +class Spatialite(SQLite): + dbengine = 'spatialite' + + SPATIALLIBS = { + 'Windows': 'mod_spatialite.dll', + 'Linux': 'libspatialite.so', + 'Darwin': 'libspatialite.dylib' + } + + def after_connections(self): + self.connection.enable_load_extension(True) + libspatialite = self.SPATIALLIBS[platform.system()] + self.execute(r'SELECT load_extension("%s");' % libspatialite) + super(Spatialite, self).after_connection() + + +@adapters.register_for('jdbc:sqlite', 'jdbc:sqlite:memory') +class JDBCSQLite(SQLite): + drivers = ('zxJDBC_sqlite',) + + def connector(self): + return self.driver.connect( + self.driver.getConnection('jdbc:sqlite:'+self.dbpath), + **self.driver_args) + + def after_connection(self): + self._register_extract() diff --git a/web2py/gluon/packages/dal/pydal/adapters/teradata.py b/web2py/gluon/packages/dal/pydal/adapters/teradata.py new file mode 100644 index 0000000..e26315f --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/adapters/teradata.py @@ -0,0 +1,28 @@ +from .base import SQLAdapter +from . import adapters + + +@adapters.register_for('teradata') +class Teradata(SQLAdapter): + dbengine = '' + drivers = ('pyodbc',) + + def _initialize_(self, do_connect): + super(Teradata, self)._initialize_(do_connect) + self.ruri = self.uri.split('://', 1)[1] + + def connector(self): + return self.driver.connect(self.ruri, **self.driver_args) + + def close(self): + # Teradata does not implicitly close off the cursor + # leading to SQL_ACTIVE_STATEMENTS limit errors + self.cursor.close() + super(Teradata, self).close() + + def lastrowid(self, table): + # Teradata cannot retrieve the lastrowid for an IDENTITY Column + # and they are not sequential anyway. + # Similar to the NullCursor class, return 1 + return 1 + \ No newline at end of file diff --git a/web2py/gluon/packages/dal/pydal/base.py b/web2py/gluon/packages/dal/pydal/base.py new file mode 100644 index 0000000..bcb6cef --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/base.py @@ -0,0 +1,898 @@ +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) +| + +This file contains the DAL support for many relational databases, including: + + - SQLite & SpatiaLite + - MySQL + - Postgres + - Firebird + - Oracle + - MS SQL + - DB2 + - Interbase + - Ingres + - Informix (9+ and SE) + - SapDB (experimental) + - Cubrid (experimental) + - CouchDB (experimental) + - MongoDB (in progress) + - Google:nosql + - Google:sql + - Teradata + - IMAP (experimental) + +Example of usage:: + + >>> # from dal import DAL, Field + + ### create DAL connection (and create DB if it doesn't exist) + >>> db = DAL(('sqlite://storage.sqlite','mysql://a:b@localhost/x'), + ... folder=None) + + ### define a table 'person' (create/alter as necessary) + >>> person = db.define_table('person',Field('name','string')) + + ### insert a record + >>> id = person.insert(name='James') + + ### retrieve it by id + >>> james = person(id) + + ### retrieve it by name + >>> james = person(name='James') + + ### retrieve it by arbitrary query + >>> query = (person.name=='James') & (person.name.startswith('J')) + >>> james = db(query).select(person.ALL)[0] + + ### update one record + >>> james.update_record(name='Jim') + + + ### update multiple records by query + >>> db(person.name.like('J%')).update(name='James') + 1 + + ### delete records by query + >>> db(person.name.lower() == 'jim').delete() + 0 + + ### retrieve multiple records (rows) + >>> people = db(person).select(orderby=person.name, + ... groupby=person.name, limitby=(0,100)) + + ### further filter them + >>> james = people.find(lambda row: row.name == 'James').first() + >>> print james.id, james.name + 1 James + + ### check aggregates + >>> counter = person.id.count() + >>> print db(person).select(counter).first()(counter) + 1 + + ### delete one record + >>> james.delete_record() + 1 + + ### delete (drop) entire database table + >>> person.drop() + + +Supported DAL URI strings:: + + 'sqlite://test.db' + 'spatialite://test.db' + 'sqlite:memory' + 'spatialite:memory' + 'jdbc:sqlite://test.db' + 'mysql://root:none@localhost/test' + 'postgres://mdipierro:password@localhost/test' + 'postgres:psycopg2://mdipierro:password@localhost/test' + 'postgres:pg8000://mdipierro:password@localhost/test' + 'jdbc:postgres://mdipierro:none@localhost/test' + 'mssql://web2py:none@A64X2/web2py_test' + 'mssql2://web2py:none@A64X2/web2py_test' # alternate mappings + 'mssql3://web2py:none@A64X2/web2py_test' # better pagination (requires >= 2005) + 'mssql4://web2py:none@A64X2/web2py_test' # best pagination (requires >= 2012) + 'oracle://username:password@database' + 'firebird://user:password@server:3050/database' + 'db2:ibm_db_dbi://DSN=dsn;UID=user;PWD=pass' + 'db2:pyodbc://driver=DB2;hostname=host;database=database;uid=user;pwd=password;port=port' + 'firebird://username:password@hostname/database' + 'firebird_embedded://username:password@c://path' + 'informix://user:password@server:3050/database' + 'informixu://user:password@server:3050/database' # unicode informix + 'ingres://database' # or use an ODBC connection string, e.g. 'ingres://dsn=dsn_name' + 'google:datastore' # for google app engine datastore (uses ndb by default) + 'google:sql' # for google app engine with sql (mysql compatible) + 'teradata://DSN=dsn;UID=user;PWD=pass; DATABASE=database' # experimental + 'imap://user:password@server:port' # experimental + 'mongodb://user:password@server:port/database' # experimental + +For more info:: + + help(DAL) + help(Field) + +""" + +import glob +import logging +import socket +import threading +import time +import traceback +import urllib +from uuid import uuid4 + +from ._compat import PY2, pickle, hashlib_md5, pjoin, copyreg, integer_types, \ + with_metaclass, long, unquote, iteritems +from ._globals import GLOBAL_LOCKER, THREAD_LOCAL, DEFAULT +from ._load import OrderedDict +from .helpers.classes import Serializable, SQLCallableList, BasicStorage, \ + RecordUpdater, RecordDeleter, TimingHandler +from .helpers.methods import hide_password, smart_query, auto_validators, \ + auto_represent +from .helpers.regex import REGEX_PYTHON_KEYWORDS, REGEX_DBNAME +from .helpers.rest import RestParser +from .helpers.serializers import serializers +from .objects import Table, Field, Rows, Row, Set +from .adapters.base import BaseAdapter, NullAdapter + +TABLE_ARGS = set( + ('migrate', 'primarykey', 'fake_migrate', 'format', 'redefine', + 'singular', 'plural', 'trigger_name', 'sequence_name', 'fields', + 'common_filter', 'polymodel', 'table_class', 'on_define', 'rname')) + + +class MetaDAL(type): + def __call__(cls, *args, **kwargs): + #: intercept arguments for DAL customisation on call + intercepts = [ + 'logger', 'representers', 'serializers', 'uuid', 'validators', + 'validators_method', 'Table', 'Row'] + intercepted = [] + for name in intercepts: + val = kwargs.get(name) + if val: + intercepted.append((name, val)) + del kwargs[name] + for tup in intercepted: + setattr(cls, tup[0], tup[1]) + + obj = super(MetaDAL, cls).__call__(*args, **kwargs) + return obj + + +class DAL(with_metaclass(MetaDAL, Serializable, BasicStorage)): + """ + An instance of this class represents a database connection + + Args: + uri(str): contains information for connecting to a database. + Defaults to `'sqlite://dummy.db'` + + Note: + experimental: you can specify a dictionary as uri + parameter i.e. with:: + + db = DAL({"uri": "sqlite://storage.sqlite", + "tables": {...}, ...}) + + for an example of dict input you can check the output + of the scaffolding db model with + + db.as_dict() + + Note that for compatibility with Python older than + version 2.6.5 you should cast your dict input keys + to str due to a syntax limitation on kwarg names. + for proper DAL dictionary input you can use one of:: + + obj = serializers.cast_keys(dict, [encoding="utf-8"]) + #or else (for parsing json input) + obj = serializers.loads_json(data, unicode_keys=False) + + pool_size: How many open connections to make to the database object. + folder: where .table files will be created. Automatically set within + web2py. Use an explicit path when using DAL outside web2py + db_codec: string encoding of the database (default: 'UTF-8') + table_hash: database identifier with .tables. If your connection hash + change you can still using old .tables if they have db_hash + as prefix + check_reserved: list of adapters to check tablenames and column names + against sql/nosql reserved keywords. Defaults to `None` + + - 'common' List of sql keywords that are common to all database + types such as "SELECT, INSERT". (recommended) + - 'all' Checks against all known SQL keywords + - ''' Checks against the specific adapters list of + keywords + - '_nonreserved' Checks against the specific adapters + list of nonreserved keywords. (if available) + + migrate: sets default migrate behavior for all tables + fake_migrate: sets default fake_migrate behavior for all tables + migrate_enabled: If set to False disables ALL migrations + fake_migrate_all: If set to True fake migrates ALL tables + attempts: Number of times to attempt connecting + auto_import: If set to True, tries import automatically table + definitions from the databases folder (works only for simple models) + bigint_id: If set, turn on bigint instead of int for id and reference + fields + lazy_tables: delays table definition until table access + after_connection: can a callable that will be executed after the + connection + + Example: + Use as:: + + db = DAL('sqlite://test.db') + + or:: + + db = DAL(**{"uri": ..., "tables": [...]...}) # experimental + + db.define_table('tablename', Field('fieldname1'), + Field('fieldname2')) + + + """ + serializers = None + validators = None + validators_method = None + representers = {} + uuid = lambda x: str(uuid4()) + logger = logging.getLogger("pyDAL") + + Table = Table + Rows = Rows + Row = Row + + record_operators = { + 'update_record': RecordUpdater, + 'delete_record': RecordDeleter + } + + execution_handlers = [TimingHandler] + + def __new__(cls, uri='sqlite://dummy.db', *args, **kwargs): + if not hasattr(THREAD_LOCAL, '_pydal_db_instances_'): + THREAD_LOCAL._pydal_db_instances_ = {} + if not hasattr(THREAD_LOCAL, '_pydal_db_instances_zombie_'): + THREAD_LOCAL._pydal_db_instances_zombie_ = {} + if uri == '': + db_uid = kwargs['db_uid'] # a zombie must have a db_uid! + if db_uid in THREAD_LOCAL._pydal_db_instances_: + db_group = THREAD_LOCAL._pydal_db_instances_[db_uid] + db = db_group[-1] + elif db_uid in THREAD_LOCAL._pydal_db_instances_zombie_: + db = THREAD_LOCAL._pydal_db_instances_zombie_[db_uid] + else: + db = super(DAL, cls).__new__(cls) + THREAD_LOCAL._pydal_db_instances_zombie_[db_uid] = db + else: + db_uid = kwargs.get('db_uid', hashlib_md5(repr(uri)).hexdigest()) + if db_uid in THREAD_LOCAL._pydal_db_instances_zombie_: + db = THREAD_LOCAL._pydal_db_instances_zombie_[db_uid] + del THREAD_LOCAL._pydal_db_instances_zombie_[db_uid] + else: + db = super(DAL, cls).__new__(cls) + db_group = THREAD_LOCAL._pydal_db_instances_.get(db_uid, []) + db_group.append(db) + THREAD_LOCAL._pydal_db_instances_[db_uid] = db_group + db._db_uid = db_uid + return db + + @staticmethod + def set_folder(folder): + # ## this allows gluon to set a folder for this thread + # ## <<<<<<<<< Should go away as new DAL replaces old sql.py + BaseAdapter.set_folder(folder) + + @staticmethod + def get_instances(): + """ + Returns a dictionary with uri as key with timings and defined tables:: + + {'sqlite://storage.sqlite': { + 'dbstats': [(select auth_user.email from auth_user, 0.02009)], + 'dbtables': { + 'defined': ['auth_cas', 'auth_event', 'auth_group', + 'auth_membership', 'auth_permission', 'auth_user'], + 'lazy': '[]' + } + } + } + + """ + dbs = getattr(THREAD_LOCAL, '_pydal_db_instances_', {}).items() + infos = {} + for db_uid, db_group in dbs: + for db in db_group: + if not db._uri: + continue + k = hide_password(db._adapter.uri) + infos[k] = dict( + dbstats=[(row[0], row[1]) for row in db._timings], + dbtables={ + 'defined': sorted( + list(set(db.tables) - set(db._LAZY_TABLES.keys())) + ), + 'lazy': sorted(db._LAZY_TABLES.keys())} + ) + return infos + + @staticmethod + def distributed_transaction_begin(*instances): + if not instances: + return + thread_key = '%s.%s' % ( + socket.gethostname(), threading.currentThread()) + keys = ['%s.%i' % (thread_key, i) for (i, db) in instances] + instances = enumerate(instances) + for (i, db) in instances: + if not db._adapter.support_distributed_transaction(): + raise SyntaxError( + 'distributed transaction not suported by %s' % db._dbname) + for (i, db) in instances: + db._adapter.distributed_transaction_begin(keys[i]) + + @staticmethod + def distributed_transaction_commit(*instances): + if not instances: + return + instances = enumerate(instances) + thread_key = '%s.%s' % ( + socket.gethostname(), threading.currentThread()) + keys = ['%s.%i' % (thread_key, i) for (i, db) in instances] + for (i, db) in instances: + if not db._adapter.support_distributed_transaction(): + raise SyntaxError( + 'distributed transaction not suported by %s' % db._dbanme) + try: + for (i, db) in instances: + db._adapter.prepare(keys[i]) + except: + for (i, db) in instances: + db._adapter.rollback_prepared(keys[i]) + raise RuntimeError('failure to commit distributed transaction') + else: + for (i, db) in instances: + db._adapter.commit_prepared(keys[i]) + return + + def __init__(self, uri='sqlite://dummy.db', + pool_size=0, folder=None, + db_codec='UTF-8', check_reserved=None, + migrate=True, fake_migrate=False, + migrate_enabled=True, fake_migrate_all=False, + decode_credentials=False, driver_args=None, + adapter_args=None, attempts=5, auto_import=False, + bigint_id=False, debug=False, lazy_tables=False, + db_uid=None, do_connect=True, + after_connection=None, tables=None, ignore_field_case=True, + entity_quoting=True, table_hash=None): + + if uri == '' and db_uid is not None: + return + super(DAL, self).__init__() + + if not issubclass(self.Rows, Rows): + raise RuntimeError( + '`Rows` class must be a subclass of pydal.objects.Rows' + ) + + if not issubclass(self.Row, Row): + raise RuntimeError( + '`Row` class must be a subclass of pydal.objects.Row' + ) + + from .drivers import DRIVERS, is_jdbc + self._drivers_available = DRIVERS + + if not decode_credentials: + credential_decoder = lambda cred: cred + else: + credential_decoder = lambda cred: unquote(cred) + self._folder = folder + if folder: + self.set_folder(folder) + self._uri = uri + self._pool_size = pool_size + self._db_codec = db_codec + self._pending_references = {} + self._request_tenant = 'request_tenant' + self._common_fields = [] + self._referee_name = '%(table)s' + self._bigint_id = bigint_id + self._debug = debug + self._migrated = [] + self._LAZY_TABLES = {} + self._lazy_tables = lazy_tables + self._tables = SQLCallableList() + self._driver_args = driver_args + self._adapter_args = adapter_args + self._check_reserved = check_reserved + self._decode_credentials = decode_credentials + self._attempts = attempts + self._do_connect = do_connect + self._ignore_field_case = ignore_field_case + + if not str(attempts).isdigit() or attempts < 0: + attempts = 5 + if uri: + uris = isinstance(uri, (list, tuple)) and uri or [uri] + connected = False + for k in range(attempts): + for uri in uris: + try: + from .adapters import adapters + if is_jdbc and not uri.startswith('jdbc:'): + uri = 'jdbc:' + uri + self._dbname = REGEX_DBNAME.match(uri).group() + # notice that driver args or {} else driver_args + # defaults to {} global, not correct + kwargs = dict(db=self, + uri=uri, + pool_size=pool_size, + folder=folder, + db_codec=db_codec, + credential_decoder=credential_decoder, + driver_args=driver_args or {}, + adapter_args=adapter_args or {}, + do_connect=do_connect, + after_connection=after_connection, + entity_quoting=entity_quoting) + adapter = adapters.get_for(self._dbname) + self._adapter = adapter(**kwargs) + #self._adapter.ignore_field_case = ignore_field_case + if bigint_id: + self._adapter.dialect._force_bigints() + connected = True + break + except SyntaxError: + raise + except Exception: + tb = traceback.format_exc() + self.logger.debug( + 'DEBUG: connect attempt %i, connection error:\n%s' + % (k, tb) + ) + if connected: + break + else: + time.sleep(1) + if not connected: + raise RuntimeError( + "Failure to connect, tried %d times:\n%s" % (attempts, tb) + ) + else: + self._adapter = NullAdapter( + db=self, pool_size=0, uri='None', folder=folder, + db_codec=db_codec, after_connection=after_connection, + entity_quoting=entity_quoting) + migrate = fake_migrate = False + self.validators_method = None + self.validators = None + adapter = self._adapter + self._uri_hash = table_hash or hashlib_md5(adapter.uri).hexdigest() + if check_reserved: + from .contrib.reserved_sql_keywords import ADAPTERS as RSK + self.RSK = RSK + self._migrate = migrate + self._fake_migrate = fake_migrate + self._migrate_enabled = migrate_enabled + self._fake_migrate_all = fake_migrate_all + if self.serializers is not None: + for k, v in self.serializers.items(): + serializers._custom_[k] = v + if auto_import or tables: + self.import_table_definitions(adapter.folder, + tables=tables) + + @property + def tables(self): + return self._tables + + @property + def _timings(self): + return getattr(THREAD_LOCAL, '_pydal_timings_', []) + + @property + def _lastsql(self): + return self._timings[-1] if self._timings else None + + def import_table_definitions(self, path, migrate=False, + fake_migrate=False, tables=None): + if tables: + for table in tables: + self.define_table(**table) + else: + pattern = pjoin(path, self._uri_hash + '_*.table') + for filename in glob.glob(pattern): + tfile = self._adapter.migrator.file_open(filename, 'r' if PY2 else 'rb') + try: + sql_fields = pickle.load(tfile) + name = filename[len(pattern) - 7:-6] + mf = [ + (value['sortable'], Field( + key, + type=value['type'], + length=value.get('length', None), + notnull=value.get('notnull', False), + unique=value.get('unique', False))) + for key, value in iteritems(sql_fields) + ] + mf.sort(key=lambda a: a[0]) + self.define_table(name, *[item[1] for item in mf], + **dict(migrate=migrate, + fake_migrate=fake_migrate)) + finally: + self._adapter.migrator.file_close(tfile) + + def check_reserved_keyword(self, name): + """ + Validates `name` against SQL keywords + Uses self._check_reserved which is a list of operators to use. + """ + for backend in self._check_reserved: + if name.upper() in self.RSK[backend]: + raise SyntaxError( + 'invalid table/column name "%s" is a "%s" reserved SQL/NOSQL keyword' % (name, backend.upper())) + + def parse_as_rest(self, patterns, args, vars, queries=None, + nested_select=True): + return RestParser(self).parse( + patterns, args, vars, queries, nested_select) + + def define_table(self, tablename, *fields, **kwargs): + invalid_kwargs = set(kwargs) - TABLE_ARGS + if invalid_kwargs: + raise SyntaxError('invalid table "%s" attributes: %s' % + (tablename, invalid_kwargs)) + if not fields and 'fields' in kwargs: + fields = kwargs.get('fields',()) + if not isinstance(tablename, str): + if isinstance(tablename, unicode): + try: + tablename = str(tablename) + except UnicodeEncodeError: + raise SyntaxError("invalid unicode table name") + else: + raise SyntaxError("missing table name") + redefine = kwargs.get('redefine', False) + if tablename in self.tables: + if redefine: + try: + delattr(self, tablename) + except: + pass + else: + raise SyntaxError('table already defined: %s' % tablename) + elif tablename.startswith('_') or tablename in dir(self) or \ + REGEX_PYTHON_KEYWORDS.match(tablename): + raise SyntaxError('invalid table name: %s' % tablename) + elif self._check_reserved: + self.check_reserved_keyword(tablename) + if self._lazy_tables: + if tablename not in self._LAZY_TABLES or redefine: + self._LAZY_TABLES[tablename] = (tablename, fields, kwargs) + table = None + else: + table = self.lazy_define_table(tablename, *fields, **kwargs) + if tablename not in self.tables: + self.tables.append(tablename) + return table + + def lazy_define_table(self, tablename, *fields, **kwargs): + kwargs_get = kwargs.get + common_fields = self._common_fields + if common_fields: + fields = list(fields) + [f if isinstance(f, Table) else f.clone() for f in common_fields] + + table_class = kwargs_get('table_class', Table) + table = table_class(self, tablename, *fields, **kwargs) + table._actual = True + self[tablename] = table + # must follow above line to handle self references + table._create_references() + for field in table: + if field.requires == DEFAULT: + field.requires = auto_validators(field) + if field.represent is None: + field.represent = auto_represent(field) + + migrate = self._migrate_enabled and kwargs_get('migrate', self._migrate) + if migrate and self._uri not in (None, 'None') \ + or self._adapter.dbengine == 'google:datastore': + fake_migrate = self._fake_migrate_all or \ + kwargs_get('fake_migrate', self._fake_migrate) + polymodel = kwargs_get('polymodel', None) + try: + GLOBAL_LOCKER.acquire() + self._adapter.create_table( + table, migrate=migrate, + fake_migrate=fake_migrate, + polymodel=polymodel) + finally: + GLOBAL_LOCKER.release() + else: + table._dbt = None + on_define = kwargs_get('on_define', None) + if on_define: + on_define(table) + return table + + def as_dict(self, flat=False, sanitize=True): + db_uid = uri = None + if not sanitize: + uri, db_uid = (self._uri, self._db_uid) + db_as_dict = dict( + tables=[], + uri=uri, + db_uid=db_uid, + **dict( + [(k, getattr(self, "_" + k, None)) for k in [ + 'pool_size', 'folder', 'db_codec', 'check_reserved', + 'migrate', 'fake_migrate', 'migrate_enabled', + 'fake_migrate_all', 'decode_credentials', 'driver_args', + 'adapter_args', 'attempts', 'bigint_id', 'debug', + 'lazy_tables', 'do_connect']])) + for table in self: + db_as_dict["tables"].append(table.as_dict(flat=flat, + sanitize=sanitize)) + return db_as_dict + + def __contains__(self, tablename): + try: + return tablename in self.tables + except AttributeError: + # The instance has no .tables attribute yet + return False + + def __iter__(self): + for tablename in self.tables: + yield self[tablename] + + def __getitem__(self, key): + return self.__getattr__(str(key)) + + def __getattr__(self, key): + if object.__getattribute__(self, '_lazy_tables') and \ + key in object.__getattribute__(self, '_LAZY_TABLES'): + tablename, fields, kwargs = self._LAZY_TABLES.pop(key) + return self.lazy_define_table(tablename, *fields, **kwargs) + return BasicStorage.__getattribute__(self, key) + + def __setattr__(self, key, value): + if key[:1] != '_' and key in self: + raise SyntaxError( + 'Object %s exists and cannot be redefined' % key) + return super(DAL, self).__setattr__(key, value) + + def __repr__(self): + if hasattr(self, '_uri'): + return '' % hide_password(self._adapter.uri) + else: + return '' % self._db_uid + + def smart_query(self, fields, text): + return Set(self, smart_query(fields, text)) + + def __call__(self, query=None, ignore_common_filters=None): + return self.where(query, ignore_common_filters) + + def where(self, query=None, ignore_common_filters=None): + if isinstance(query, Table): + query = self._adapter.id_query(query) + elif isinstance(query, Field): + query = query != None + elif isinstance(query, dict): + icf = query.get("ignore_common_filters") + if icf: + ignore_common_filters = icf + return Set(self, query, ignore_common_filters=ignore_common_filters) + + def commit(self): + self._adapter.commit() + + def rollback(self): + self._adapter.rollback() + + def close(self): + self._adapter.close() + if self._db_uid in THREAD_LOCAL._pydal_db_instances_: + db_group = THREAD_LOCAL._pydal_db_instances_[self._db_uid] + db_group.remove(self) + if not db_group: + del THREAD_LOCAL._pydal_db_instances_[self._db_uid] + self._adapter._clean_tlocals() + + def executesql(self, query, placeholders=None, as_dict=False, + fields=None, colnames=None, as_ordered_dict=False): + """ + Executes an arbitrary query + + Args: + query (str): the query to submit to the backend + placeholders: is optional and will always be None. + If using raw SQL with placeholders, placeholders may be + a sequence of values to be substituted in + or, (if supported by the DB driver), a dictionary with keys + matching named placeholders in your SQL. + as_dict: will always be None when using DAL. + If using raw SQL can be set to True and the results cursor + returned by the DB driver will be converted to a sequence of + dictionaries keyed with the db field names. Results returned + with as_dict=True are the same as those returned when applying + .to_list() to a DAL query. If "as_ordered_dict"=True the + behaviour is the same as when "as_dict"=True with the keys + (field names) guaranteed to be in the same order as returned + by the select name executed on the database. + fields: list of DAL Fields that match the fields returned from the + DB. The Field objects should be part of one or more Table + objects defined on the DAL object. The "fields" list can include + one or more DAL Table objects in addition to or instead of + including Field objects, or it can be just a single table + (not in a list). In that case, the Field objects will be + extracted from the table(s). + + Note: + if either `fields` or `colnames` is provided, the results + will be converted to a DAL `Rows` object using the + `db._adapter.parse()` method + colnames: list of field names in tablename.fieldname format + + Note: + It is also possible to specify both "fields" and the associated + "colnames". In that case, "fields" can also include DAL Expression + objects in addition to Field objects. For Field objects in "fields", + the associated "colnames" must still be in tablename.fieldname + format. For Expression objects in "fields", the associated + "colnames" can be any arbitrary labels. + + DAL Table objects referred to by "fields" or "colnames" can be dummy + tables and do not have to represent any real tables in the database. + Also, note that the "fields" and "colnames" must be in the + same order as the fields in the results cursor returned from the DB. + + """ + adapter = self._adapter + if placeholders: + adapter.execute(query, placeholders) + else: + adapter.execute(query) + if as_dict or as_ordered_dict: + if not hasattr(adapter.cursor,'description'): + raise RuntimeError("database does not support executesql(...,as_dict=True)") + # Non-DAL legacy db query, converts cursor results to dict. + # sequence of 7-item sequences. each sequence tells about a column. + # first item is always the field name according to Python Database API specs + columns = adapter.cursor.description + # reduce the column info down to just the field names + fields = colnames or [f[0] for f in columns] + if len(fields) != len(set(fields)): + raise RuntimeError("Result set includes duplicate column names. Specify unique column names using the 'colnames' argument") + #: avoid bytes strings in columns names (py3) + if columns and not PY2: + for i in range(0, len(fields)): + if isinstance(fields[i], bytes): + fields[i] = fields[i].decode("utf8") + + # will hold our finished resultset in a list + data = adapter.fetchall() + # convert the list for each row into a dictionary so it's + # easier to work with. row['field_name'] rather than row[0] + if as_ordered_dict: + _dict = OrderedDict + else: + _dict = dict + return [_dict(zip(fields, row)) for row in data] + try: + data = adapter.fetchall() + except: + return None + if fields or colnames: + fields = [] if fields is None else fields + if not isinstance(fields, list): + fields = [fields] + extracted_fields = [] + for field in fields: + if isinstance(field, Table): + extracted_fields.extend([f for f in field]) + else: + extracted_fields.append(field) + if not colnames: + colnames = [f.sqlsafe for f in extracted_fields] + else: + newcolnames = [] + for tf in colnames: + if '.' in tf: + newcolnames.append('.'.join(adapter.dialect.quote(f) + for f in tf.split('.'))) + else: + newcolnames.append(tf) + colnames = newcolnames + data = adapter.parse( + data, fields=extracted_fields, colnames=colnames) + return data + + def _remove_references_to(self, thistable): + for table in self: + table._referenced_by = [field for field in table._referenced_by + if not field.table==thistable] + + def has_representer(self, name): + return callable(self.representers.get(name)) + + def represent(self, name, *args, **kwargs): + return self.representers[name](*args, **kwargs) + + def export_to_csv_file(self, ofile, *args, **kwargs): + step = long(kwargs.get('max_fetch_rows,',500)) + write_colnames = kwargs['write_colnames'] = \ + kwargs.get("write_colnames", True) + for table in self.tables: + ofile.write('TABLE %s\r\n' % table) + query = self._adapter.id_query(self[table]) + nrows = self(query).count() + kwargs['write_colnames'] = write_colnames + for k in range(0,nrows,step): + self(query).select(limitby=(k,k+step)).export_to_csv_file( + ofile, *args, **kwargs) + kwargs['write_colnames'] = False + ofile.write('\r\n\r\n') + ofile.write('END') + + def import_from_csv_file(self, ifile, id_map=None, null='', + unique='uuid', map_tablenames=None, + ignore_missing_tables=False, + *args, **kwargs): + #if id_map is None: id_map={} + id_offset = {} # only used if id_map is None + map_tablenames = map_tablenames or {} + for line in ifile: + line = line.strip() + if not line: + continue + elif line == 'END': + return + elif not line.startswith('TABLE ') : + raise SyntaxError('Invalid file format') + elif not line[6:] in self.tables: + raise SyntaxError('Unknown table : %s' % line[6:]) + else: + tablename = line[6:] + tablename = map_tablenames.get(tablename,tablename) + if tablename is not None and tablename in self.tables: + self[tablename].import_from_csv_file( + ifile, id_map, null, unique, id_offset, + *args, **kwargs) + elif tablename is None or ignore_missing_tables: + # skip all non-empty lines + for line in ifile: + if not line.strip(): + break + else: + raise RuntimeError("Unable to import table that does not exist.\nTry db.import_from_csv_file(..., map_tablenames={'table':'othertable'},ignore_missing_tables=True)") + + def can_join(self): + return self._adapter.can_join() + + +def DAL_unpickler(db_uid): + return DAL('', db_uid=db_uid) + + +def DAL_pickler(db): + return DAL_unpickler, (db._db_uid,) + +copyreg.pickle(DAL, DAL_pickler, DAL_unpickler) diff --git a/web2py/gluon/packages/dal/pydal/connection.py b/web2py/gluon/packages/dal/pydal/connection.py new file mode 100644 index 0000000..73c8000 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/connection.py @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- +import os +from ._compat import itervalues +from ._globals import GLOBAL_LOCKER, THREAD_LOCAL +from ._load import OrderedDict +from .helpers._internals import Cursor + + +class ConnectionPool(object): + POOLS = {} + check_active_connection = True + + def __init__(self): + _iid_ = str(id(self)) + self._connection_thname_ = '_pydal_connection_' + _iid_ + '_' + self._cursors_thname_ = '_pydal_cursors_' + _iid_ + '_' + + @property + def _pid_(self): + return str(os.getpid()) + + @property + def _connection_uname_(self): + return self._connection_thname_ + self._pid_ + + @property + def _cursors_uname_(self): + return self._cursors_thname_ + self._pid_ + + @staticmethod + def set_folder(folder): + THREAD_LOCAL._pydal_folder_ = folder + + @property + def connection(self): + return getattr(THREAD_LOCAL, self._connection_uname_) + + @connection.setter + def connection(self, val): + setattr(THREAD_LOCAL, self._connection_uname_, val) + self._clean_cursors() + if val is not None: + self._build_cursor() + + def _clean_cursors(self): + setattr(THREAD_LOCAL, self._cursors_uname_, OrderedDict()) + + @property + def cursors(self): + return getattr(THREAD_LOCAL, self._cursors_uname_) + + def _build_cursor(self): + rv = Cursor(self.connection) + self.cursors[id(rv.cursor)] = rv + return rv + + def _get_or_build_free_cursor(self): + for handler in itervalues(self.cursors): + if handler.available: + return handler + return self._build_cursor() + + @property + def cursor(self): + return self._get_or_build_free_cursor().cursor + + def lock_cursor(self, cursor): + self.cursors[id(cursor)].lock() + + def release_cursor(self, cursor): + self.cursors[id(cursor)].release() + + def close_cursor(self, cursor): + cursor.close() + del self.cursors[id(cursor)] + + def _clean_tlocals(self): + delattr(THREAD_LOCAL, self._cursors_uname_) + delattr(THREAD_LOCAL, self._connection_uname_) + + def close(self, action='commit', really=True): + #: if we have an action (commit, rollback), try to execute it + succeeded = True + if action: + try: + if callable(action): + action(self) + else: + getattr(self, action)() + except: + #: connection had some problems, we want to drop it + succeeded = False + #: if we have pools, we should recycle the connection (but only when + # we succeded in `action`, if any and `len(pool)` is good) + if self.pool_size and succeeded: + GLOBAL_LOCKER.acquire() + pool = ConnectionPool.POOLS[self.uri] + if len(pool) < self.pool_size: + pool.append(self.connection) + really = False + GLOBAL_LOCKER.release() + #: closing the connection when we `really` want to, in particular: + # - when we had an exception running `action` + # - when we don't have pools + # - when we have pools but they're full + if really: + try: + self.close_connection() + except: + pass + #: always unset `connection` attribute + self.connection = None + + @staticmethod + def close_all_instances(action): + """ to close cleanly databases in a multithreaded environment """ + dbs = getattr(THREAD_LOCAL, '_pydal_db_instances_', {}).items() + for db_uid, db_group in dbs: + for db in db_group: + if hasattr(db, '_adapter'): + db._adapter.close(action) + getattr(THREAD_LOCAL, '_pydal_db_instances_', {}).clear() + getattr(THREAD_LOCAL, '_pydal_db_instances_zombie_', {}).clear() + if callable(action): + action(None) + return + + def _find_work_folder(self): + self.folder = getattr(THREAD_LOCAL, '_pydal_folder_', '') + + def after_connection_hook(self): + """Hook for the after_connection parameter""" + if callable(self._after_connection): + self._after_connection(self) + self.after_connection() + + def after_connection(self): + #this it is supposed to be overloaded by adapters + pass + + def reconnect(self): + """ + Defines: `self.connection` and `self.cursor` + if `self.pool_size>0` it will try pull the connection from the pool + if the connection is not active (closed by db server) it will loop + if not `self.pool_size` or no active connections in pool makes a new one + """ + if getattr(THREAD_LOCAL, self._connection_uname_, None) is not None: + return + + if not self.pool_size: + self.connection = self.connector() + self.after_connection_hook() + else: + uri = self.uri + POOLS = ConnectionPool.POOLS + while True: + GLOBAL_LOCKER.acquire() + if uri not in POOLS: + POOLS[uri] = [] + if POOLS[uri]: + self.connection = POOLS[uri].pop() + GLOBAL_LOCKER.release() + try: + if self.check_active_connection: + self.test_connection() + break + except: + pass + else: + GLOBAL_LOCKER.release() + self.connection = self.connector() + self.after_connection_hook() + break diff --git a/web2py/gluon/packages/dal/pydal/contrib/__init__.py b/web2py/gluon/packages/dal/pydal/contrib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web2py/gluon/packages/dal/pydal/contrib/imap_adapter.py b/web2py/gluon/packages/dal/pydal/contrib/imap_adapter.py new file mode 100644 index 0000000..c3486c8 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/contrib/imap_adapter.py @@ -0,0 +1,1053 @@ +# -*- coding: utf-8 -*- +import datetime +import re +import sys + +from .._globals import IDENTITY, GLOBAL_LOCKER +from .._compat import PY2, integer_types, basestring +from ..connection import ConnectionPool +from ..objects import Field, Query, Expression +from ..helpers.classes import SQLALL +from ..helpers.methods import use_common_filters +from ..adapters.base import NoSQLAdapter + +long = integer_types[-1] + + +class IMAPAdapter(NoSQLAdapter): + + """ IMAP server adapter + + This class is intended as an interface with + email IMAP servers to perform simple queries in the + web2py DAL query syntax, so email read, search and + other related IMAP mail services (as those implemented + by brands like Google(r), and Yahoo!(r) + can be managed from web2py applications. + + The code uses examples by Yuji Tomita on this post: + http://yuji.wordpress.com/2011/06/22/python-imaplib-imap-example-with-gmail/#comment-1137 + and is based in docs for Python imaplib, python email + and email IETF's (i.e. RFC2060 and RFC3501) + + This adapter was tested with a small set of operations with Gmail(r). Other + services requests could raise command syntax and response data issues. + + It creates its table and field names "statically", + meaning that the developer should leave the table and field + definitions to the DAL instance by calling the adapter's + .define_tables() method. The tables are defined with the + IMAP server mailbox list information. + + .define_tables() returns a dictionary mapping dal tablenames + to the server mailbox names with the following structure: + + {: str } + + Here is a list of supported fields: + + =========== ============== =========== + Field Type Description + =========== ============== =========== + uid string + answered boolean Flag + created date + content list:string A list of dict text or html parts + to string + cc string + bcc string + size integer the amount of octets of the message* + deleted boolean Flag + draft boolean Flag + flagged boolean Flag + sender string + recent boolean Flag + seen boolean Flag + subject string + mime string The mime header declaration + email string The complete RFC822 message (*) + attachments list Each non text part as dict + encoding string The main detected encoding + =========== ============== =========== + + (*) At the application side it is measured as the length of the RFC822 + message string + + WARNING: As row id's are mapped to email sequence numbers, + make sure your imap client web2py app does not delete messages + during select or update actions, to prevent + updating or deleting different messages. + Sequence numbers change whenever the mailbox is updated. + To avoid this sequence numbers issues, it is recommended the use + of uid fields in query references (although the update and delete + in separate actions rule still applies). + :: + + # This is the code recommended to start imap support + # at the app's model: + + imapdb = DAL("imap://user:password@server:port", pool_size=1) # port 993 for ssl + imapdb.define_tables() + + Here is an (incomplete) list of possible imap commands:: + + # Count today's unseen messages + # smaller than 6000 octets from the + # inbox mailbox + + q = imapdb.INBOX.seen == False + q &= imapdb.INBOX.created == datetime.date.today() + q &= imapdb.INBOX.size < 6000 + unread = imapdb(q).count() + + # Fetch last query messages + rows = imapdb(q).select() + + # it is also possible to filter query select results with limitby and + # sequences of mailbox fields + + set.select(, limitby=(, )) + + # Mark last query messages as seen + messages = [row.uid for row in rows] + seen = imapdb(imapdb.INBOX.uid.belongs(messages)).update(seen=True) + + # Delete messages in the imap database that have mails from mr. Gumby + + deleted = 0 + for mailbox in imapdb.tables + deleted += imapdb(imapdb[mailbox].sender.contains("gumby")).delete() + + # It is possible also to mark messages for deletion instead of ereasing them + # directly with set.update(deleted=True) + + + # This object give access + # to the adapter auto mailbox + # mapped names (which native + # mailbox has what table name) + + imapdb.mailboxes # tablename, server native name pairs + + # To retrieve a table native mailbox name use: + imapdb..mailbox + + ### New features v2.4.1: + + # Declare mailboxes statically with tablename, name pairs + # This avoids the extra server names retrieval + + imapdb.define_tables({"inbox": "INBOX"}) + + # Selects without content/attachments/email columns will only + # fetch header and flags + + imapdb(q).select(imapdb.INBOX.sender, imapdb.INBOX.subject) + + """ + drivers = ('imaplib',) + types = { + 'string': str, + 'text': str, + 'date': datetime.date, + 'datetime': datetime.datetime, + 'id': long, + 'boolean': bool, + 'integer': int, + 'bigint': long, + 'blob': str, + 'list:string': str + } + + dbengine = 'imap' + + REGEX_URI = re.compile('^(?P[^:]+)(\:(?P[^@]*))?@(?P\[[^/]+\]|[^\:@]+)(\:(?P[0-9]+))?$') + + def __init__(self, + db, + uri, + pool_size=0, + folder=None, + db_codec ='UTF-8', + credential_decoder=IDENTITY, + driver_args={}, + adapter_args={}, + do_connect=True, + after_connection=None): + + super(IMAPAdapter, self).__init__( + db=db, + uri=uri, + pool_size=pool_size, + folder=folder, + db_codec=db_codec, + credential_decoder=credential_decoder, + driver_args=driver_args, + adapter_args=adapter_args, + do_connect=do_connect, + after_connection=after_connection) + + # db uri: user@example.com:password@imap.server.com:123 + # TODO: max size adapter argument for preventing large mail transfers + + if do_connect: self.find_driver(adapter_args) + self.credential_decoder = credential_decoder + self.driver_args = driver_args + self.adapter_args = adapter_args + self.mailbox_size = None + self.static_names = None + self.charset = sys.getfilesystemencoding() + # imap class + self.imap4 = None + uri = uri.split("://")[1] + + """ MESSAGE is an identifier for sequence number""" + + self.flags = {'deleted': '\\Deleted', 'draft': '\\Draft', + 'flagged': '\\Flagged', 'recent': '\\Recent', + 'seen': '\\Seen', 'answered': '\\Answered'} + self.search_fields = { + 'id': 'MESSAGE', 'created': 'DATE', + 'uid': 'UID', 'sender': 'FROM', + 'to': 'TO', 'cc': 'CC', + 'bcc': 'BCC', 'content': 'TEXT', + 'size': 'SIZE', 'deleted': '\\Deleted', + 'draft': '\\Draft', 'flagged': '\\Flagged', + 'recent': '\\Recent', 'seen': '\\Seen', + 'subject': 'SUBJECT', 'answered': '\\Answered', + 'mime': None, 'email': None, + 'attachments': None + } + + m = self.REGEX_URI.match(uri) + user = m.group('user') + password = m.group('password') + host = m.group('host') + port = int(m.group('port')) + over_ssl = False + if port==993: + over_ssl = True + + driver_args.update(host=host,port=port, password=password, user=user) + def connector(driver_args=driver_args): + # it is assumed sucessful authentication alLways + # TODO: support direct connection and login tests + if over_ssl: + self.imap4 = self.driver.IMAP4_SSL + else: + self.imap4 = self.driver.IMAP4 + connection = self.imap4(driver_args["host"], driver_args["port"]) + data = connection.login(driver_args["user"], driver_args["password"]) + + # static mailbox list + connection.mailbox_names = None + + # dummy dbapi functions + connection.cursor = lambda : self.fake_cursor + connection.close = lambda : None + connection.commit = lambda : None + + return connection + + self.db.define_tables = self.define_tables + self.connector = connector + if do_connect: self.reconnect() + + def reconnect(self, f=None): + """ + IMAP4 Pool connection method + + imap connection lacks of self cursor command. + A custom command should be provided as a replacement + for connection pooling to prevent uncaught remote session + closing + + """ + if getattr(self, 'connection', None) is not None: + return + if f is None: + f = self.connector + + if not self.pool_size: + self.connection = f() + self.cursor = self.connection.cursor() + else: + POOLS = ConnectionPool.POOLS + uri = self.uri + while True: + GLOBAL_LOCKER.acquire() + if not uri in POOLS: + POOLS[uri] = [] + if POOLS[uri]: + self.connection = POOLS[uri].pop() + GLOBAL_LOCKER.release() + self.cursor = self.connection.cursor() + if self.cursor and self.check_active_connection: + try: + # check if connection is alive or close it + result, data = self.connection.list() + except: + # Possible connection reset error + # TODO: read exception class + self.connection = f() + break + else: + GLOBAL_LOCKER.release() + self.connection = f() + self.cursor = self.connection.cursor() + break + self.after_connection_hook() + + def get_last_message(self, tablename): + last_message = None + # request mailbox list to the server if needed. + if not isinstance(self.connection.mailbox_names, dict): + self.get_mailboxes() + try: + result = self.connection.select( + self.connection.mailbox_names[tablename]) + last_message = int(result[1][0]) + # Last message must be a positive integer + if last_message == 0: + last_message = 1 + except (IndexError, ValueError, TypeError, KeyError): + e = sys.exc_info()[1] + self.db.logger.debug("Error retrieving the last mailbox" + + " sequence number. %s" % str(e)) + return last_message + + def get_uid_bounds(self, tablename): + if not isinstance(self.connection.mailbox_names, dict): + self.get_mailboxes() + # fetch first and last messages + # return (first, last) messages uid's + last_message = self.get_last_message(tablename) + result, data = self.connection.uid("search", None, "(ALL)") + uid_list = data[0].strip().split() + if len(uid_list) <= 0: + return None + else: + return (uid_list[0], uid_list[-1]) + + def convert_date(self, date, add=None, imf=False): + if add is None: + add = datetime.timedelta() + """ Convert a date object to a string + with d-Mon-Y style for IMAP or the inverse + case + + add adds to the date object + """ + months = [None, "JAN","FEB","MAR","APR","MAY","JUN", + "JUL", "AUG","SEP","OCT","NOV","DEC"] + if isinstance(date, basestring): + # Prevent unexpected date response format + try: + if "," in date: + dayname, datestring = date.split(",") + else: + dayname, datestring = None, date + date_list = datestring.strip().split() + year = int(date_list[2]) + month = months.index(date_list[1].upper()) + day = int(date_list[0]) + hms = list(map(int, date_list[3].split(":"))) + return datetime.datetime(year, month, day, + hms[0], hms[1], hms[2]) + add + except (ValueError, AttributeError, IndexError) as e: + self.db.logger.error("Could not parse date text: %s. %s" % + (date, e)) + return None + elif isinstance(date, (datetime.date, datetime.datetime)): + if imf: date_format = "%a, %d %b %Y %H:%M:%S %z" + else: date_format = "%d-%b-%Y" + return (date + add).strftime(date_format) + else: + return None + + @staticmethod + def header_represent(f, r): + from email.header import decode_header + text, encoding = decode_header(f)[0] + if encoding: + text = text.decode(encoding).encode('utf-8') + return text + + def encode_text(self, text, charset, errors="replace"): + """ convert text for mail to unicode""" + if text is None: + text = "" + if PY2: + if isinstance(text, str): + if charset is None: + text = unicode(text, "utf-8", errors) + else: + text = unicode(text, charset, errors) + else: + raise Exception("Unsupported mail text type %s" % type(text)) + return text.encode("utf-8") + else: + if isinstance(text, bytes): + return text.decode("utf-8") + return text + + def get_charset(self, message): + charset = message.get_content_charset() + return charset + + def get_mailboxes(self): + """ Query the mail database for mailbox names """ + if self.static_names: + # statically defined mailbox names + self.connection.mailbox_names = self.static_names + return self.static_names.keys() + + mailboxes_list = self.connection.list() + self.connection.mailbox_names = dict() + mailboxes = list() + x = 0 + for item in mailboxes_list[1]: + x = x + 1 + item = item.strip() + if not "NOSELECT" in item.upper(): + sub_items = item.split("\"") + sub_items = [sub_item for sub_item in sub_items \ + if len(sub_item.strip()) > 0] + # mailbox = sub_items[len(sub_items) -1] + mailbox = sub_items[-1].strip() + # remove unwanted characters and store original names + # Don't allow leading non alphabetic characters + mailbox_name = re.sub('^[_0-9]*', '', re.sub('[^_\w]','',re.sub('[/ ]','_',mailbox))) + mailboxes.append(mailbox_name) + self.connection.mailbox_names[mailbox_name] = mailbox + + return mailboxes + + def get_query_mailbox(self, query): + nofield = True + tablename = None + attr = query + while nofield: + if hasattr(attr, "first"): + attr = attr.first + if isinstance(attr, Field): + return attr.tablename + elif isinstance(attr, Query): + pass + else: + return None + else: + return None + return tablename + + def is_flag(self, flag): + if self.search_fields.get(flag, None) in self.flags.values(): + return True + else: + return False + + def define_tables(self, mailbox_names=None): + """ + Auto create common IMAP fileds + + This function creates fields definitions "statically" + meaning that custom fields as in other adapters should + not be supported and definitions handled on a service/mode + basis (local syntax for Gmail(r), Ymail(r) + + Returns a dictionary with tablename, server native mailbox name + pairs. + """ + if mailbox_names: + # optional statically declared mailboxes + self.static_names = mailbox_names + else: + self.static_names = None + if not isinstance(self.connection.mailbox_names, dict): + self.get_mailboxes() + + names = self.connection.mailbox_names.keys() + + for name in names: + self.db.define_table("%s" % name, + Field("uid", writable=False), + Field("created", "datetime", writable=False), + Field("content", "text", writable=False), + Field("to", writable=False), + Field("cc", writable=False), + Field("bcc", writable=False), + Field("sender", writable=False), + Field("size", "integer", writable=False), + Field("subject", writable=False), + Field("mime", writable=False), + Field("email", "text", writable=False, readable=False), + Field("attachments", "text", writable=False, readable=False), + Field("encoding", writable=False), + Field("answered", "boolean"), + Field("deleted", "boolean"), + Field("draft", "boolean"), + Field("flagged", "boolean"), + Field("recent", "boolean", writable=False), + Field("seen", "boolean") + ) + + # Set a special _mailbox attribute for storing + # native mailbox names + self.db[name].mailbox = \ + self.connection.mailbox_names[name] + + # decode quoted printable + self.db[name].to.represent = self.db[name].cc.represent = \ + self.db[name].bcc.represent = self.db[name].sender.represent = \ + self.db[name].subject.represent = self.header_represent + + # Set the db instance mailbox collections + self.db.mailboxes = self.connection.mailbox_names + return self.db.mailboxes + + def create_table(self, *args, **kwargs): + # not implemented + # but required by DAL + pass + + def select(self, query, fields, attributes): + """ Searches and Fetches records and return web2py rows + """ + # move this statement elsewhere (upper-level) + if use_common_filters(query): + query = self.common_filter(query, [self.get_query_mailbox(query),]) + + import email + # get records from imap server with search + fetch + # convert results to a dictionary + tablename = None + fetch_results = list() + + if isinstance(query, Query): + tablename = self.get_table(query)._dalname + mailbox = self.connection.mailbox_names.get(tablename, None) + if mailbox is None: + raise ValueError("Mailbox name not found: %s" % mailbox) + else: + # select with readonly + result, selected = self.connection.select(mailbox, True) + if result != "OK": + raise Exception("IMAP error: %s" % selected) + self.mailbox_size = int(selected[0]) + search_query = "(%s)" % str(query).strip() + search_result = self.connection.uid("search", None, search_query) + # Normal IMAP response OK is assumed (change this) + if search_result[0] == "OK": + # For "light" remote server responses just get the first + # ten records (change for non-experimental implementation) + # However, light responses are not guaranteed with this + # approach, just fewer messages. + limitby = attributes.get('limitby', None) + messages_set = search_result[1][0].split() + # descending order + messages_set.reverse() + if limitby is not None: + # TODO: orderby, asc/desc, limitby from complete message set + messages_set = messages_set[int(limitby[0]):int(limitby[1])] + + # keep the requests small for header/flags + if any([(field.name in ["content", "size", + "attachments", "email"]) for + field in fields]): + imap_fields = "(RFC822 FLAGS)" + else: + imap_fields = "(RFC822.HEADER FLAGS)" + + if len(messages_set) > 0: + # create fetch results object list + # fetch each remote message and store it in memmory + # (change to multi-fetch command syntax for faster + # transactions) + for uid in messages_set: + # fetch the RFC822 message body + typ, data = self.connection.uid("fetch", uid, imap_fields) + if typ == "OK": + fr = {"message": int(data[0][0].split()[0]), + "uid": long(uid), + "email": email.message_from_string(data[0][1]), + "raw_message": data[0][1]} + fr["multipart"] = fr["email"].is_multipart() + # fetch flags for the message + if PY2: + fr["flags"] = self.driver.ParseFlags(data[1]) + else: + fr["flags"] = self.driver.ParseFlags( + bytes(data[1], "utf-8")) + fetch_results.append(fr) + else: + # error retrieving the message body + raise Exception("IMAP error retrieving the body: %s" % data) + else: + raise Exception("IMAP search error: %s" % search_result[1]) + elif isinstance(query, (Expression, basestring)): + raise NotImplementedError() + else: + raise TypeError("Unexpected query type") + + imapqry_dict = {} + imapfields_dict = {} + + if len(fields) == 1 and isinstance(fields[0], SQLALL): + allfields = True + elif len(fields) == 0: + allfields = True + else: + allfields = False + if allfields: + colnames = ["%s.%s" % (tablename, field) for field in self.search_fields.keys()] + else: + colnames = [field.longname for field in fields] + + for k in colnames: + imapfields_dict[k] = k + + imapqry_list = list() + imapqry_array = list() + for fr in fetch_results: + attachments = [] + content = [] + size = 0 + n = int(fr["message"]) + item_dict = dict() + message = fr["email"] + uid = fr["uid"] + charset = self.get_charset(message) + flags = fr["flags"] + raw_message = fr["raw_message"] + # Return messages data mapping static fields + # and fetched results. Mapping should be made + # outside the select function (with auxiliary + # instance methods) + + # pending: search flags states trough the email message + # instances for correct output + + # preserve subject encoding (ASCII/quoted printable) + + if "%s.id" % tablename in colnames: + item_dict["%s.id" % tablename] = n + if "%s.created" % tablename in colnames: + item_dict["%s.created" % tablename] = self.convert_date(message["Date"]) + if "%s.uid" % tablename in colnames: + item_dict["%s.uid" % tablename] = uid + if "%s.sender" % tablename in colnames: + # If there is no encoding found in the message header + # force utf-8 replacing characters (change this to + # module's defaults). Applies to .sender, .to, .cc and .bcc fields + item_dict["%s.sender" % tablename] = message["From"] + if "%s.to" % tablename in colnames: + item_dict["%s.to" % tablename] = message["To"] + if "%s.cc" % tablename in colnames: + if "Cc" in message.keys(): + item_dict["%s.cc" % tablename] = message["Cc"] + else: + item_dict["%s.cc" % tablename] = "" + if "%s.bcc" % tablename in colnames: + if "Bcc" in message.keys(): + item_dict["%s.bcc" % tablename] = message["Bcc"] + else: + item_dict["%s.bcc" % tablename] = "" + if "%s.deleted" % tablename in colnames: + item_dict["%s.deleted" % tablename] = "\\Deleted" in flags + if "%s.draft" % tablename in colnames: + item_dict["%s.draft" % tablename] = "\\Draft" in flags + if "%s.flagged" % tablename in colnames: + item_dict["%s.flagged" % tablename] = "\\Flagged" in flags + if "%s.recent" % tablename in colnames: + item_dict["%s.recent" % tablename] = "\\Recent" in flags + if "%s.seen" % tablename in colnames: + item_dict["%s.seen" % tablename] = "\\Seen" in flags + if "%s.subject" % tablename in colnames: + item_dict["%s.subject" % tablename] = message["Subject"] + if "%s.answered" % tablename in colnames: + item_dict["%s.answered" % tablename] = "\\Answered" in flags + if "%s.mime" % tablename in colnames: + item_dict["%s.mime" % tablename] = message.get_content_type() + if "%s.encoding" % tablename in colnames: + item_dict["%s.encoding" % tablename] = charset + + # Here goes the whole RFC822 body as an email instance + # for controller side custom processing + # The message is stored as a raw string + # >> email.message_from_string(raw string) + # returns a Message object for enhanced object processing + if "%s.email" % tablename in colnames: + # WARNING: no encoding performed (raw message) + item_dict["%s.email" % tablename] = raw_message + + # Size measure as suggested in a Velocity Reviews post + # by Tim Williams: "how to get size of email attachment" + # Note: len() and server RFC822.SIZE reports doesn't match + # To retrieve the server size for representation would add a new + # fetch transaction to the process + for part in message.walk(): + maintype = part.get_content_maintype() + if ("%s.attachments" % tablename in colnames) or \ + ("%s.content" % tablename in colnames): + payload = part.get_payload(decode=True) + if payload: + filename = part.get_filename() + values = {"mime": part.get_content_type()} + if ((filename or not "text" in maintype) and + ("%s.attachments" % tablename in colnames)): + values.update({"payload": payload, + "filename": filename, + "encoding": part.get_content_charset(), + "disposition": part["Content-Disposition"]}) + attachments.append(values) + elif (("text" in maintype) and + ("%s.content" % tablename in colnames)): + values.update({"text": self.encode_text(payload, + self.get_charset(part))}) + content.append(values) + + if "%s.size" % tablename in colnames: + if part is not None: + size += len(str(part)) + item_dict["%s.content" % tablename] = content + item_dict["%s.attachments" % tablename] = attachments + item_dict["%s.size" % tablename] = size + imapqry_list.append(item_dict) + + # extra object mapping for the sake of rows object + # creation (sends an array or lists) + for item_dict in imapqry_list: + imapqry_array_item = list() + for fieldname in colnames: + imapqry_array_item.append(item_dict[fieldname]) + imapqry_array.append(imapqry_array_item) + + # parse result and return a rows object + colnames = colnames + processor = attributes.get('processor',self.parse) + return processor(imapqry_array, fields, colnames) + + def insert(self, table, fields): + def add_payload(message, obj): + payload = Message() + encoding = obj.get("encoding", "utf-8") + if encoding and (encoding.upper() in + ("BASE64", "7BIT", "8BIT", "BINARY")): + payload.add_header("Content-Transfer-Encoding", encoding) + else: + payload.set_charset(encoding) + mime = obj.get("mime", None) + if mime: + payload.set_type(mime) + if "text" in obj: + payload.set_payload(obj["text"]) + elif "payload" in obj: + payload.set_payload(obj["payload"]) + if "filename" in obj and obj["filename"]: + payload.add_header("Content-Disposition", + "attachment", filename=obj["filename"]) + message.attach(payload) + + mailbox = table.mailbox + d = dict(((k.name, v) for k, v in fields)) + date_time = d.get("created") or datetime.datetime.now() + struct_time = date_time.timetuple() + if len(d) > 0: + message = d.get("email", None) + attachments = d.get("attachments", []) + content = d.get("content", []) + flags = " ".join(["\\%s" % flag.capitalize() for flag in + ("answered", "deleted", "draft", "flagged", + "recent", "seen") if d.get(flag, False)]) + if not message: + from email.message import Message + mime = d.get("mime", None) + charset = d.get("encoding", None) + message = Message() + message["from"] = d.get("sender", "") + message["subject"] = d.get("subject", "") + message["date"] = self.convert_date(date_time, imf=True) + + if mime: + message.set_type(mime) + if charset: + message.set_charset(charset) + for item in ("to", "cc", "bcc"): + value = d.get(item, "") + if isinstance(value, basestring): + message[item] = value + else: + message[item] = ";".join([i for i in + value]) + if (not message.is_multipart() and + (not message.get_content_type().startswith( + "multipart"))): + if isinstance(content, basestring): + message.set_payload(content) + elif len(content) > 0: + message.set_payload(content[0]["text"]) + else: + [add_payload(message, c) for c in content] + [add_payload(message, a) for a in attachments] + message = message.as_string() + + result, data = self.connection.append(mailbox, flags, struct_time, message) + if result == "OK": + uid = int(re.findall("\d+", str(data))[-1]) + return self.db(table.uid==uid).select(table.id).first().id + else: + raise Exception("IMAP message append failed: %s" % data) + else: + raise NotImplementedError("IMAP empty insert is not implemented") + + def update(self, table, query, fields): + # TODO: the adapter should implement an .expand method + commands = list() + rowcount = 0 + tablename = table._dalname + if use_common_filters(query): + query = self.common_filter(query, [tablename,]) + mark = [] + unmark = [] + if query: + for item in fields: + field = item[0] + name = field.name + value = item[1] + if self.is_flag(name): + flag = self.search_fields[name] + if (value is not None) and (flag != "\\Recent"): + if value: + mark.append(flag) + else: + unmark.append(flag) + result, data = self.connection.select( + self.connection.mailbox_names[tablename]) + string_query = "(%s)" % query + result, data = self.connection.search(None, string_query) + store_list = [item.strip() for item in data[0].split() + if item.strip().isdigit()] + # build commands for marked flags + for number in store_list: + result = None + if len(mark) > 0: + commands.append((number, "+FLAGS", "(%s)" % " ".join(mark))) + if len(unmark) > 0: + commands.append((number, "-FLAGS", "(%s)" % " ".join(unmark))) + + for command in commands: + result, data = self.connection.store(*command) + if result == "OK": + rowcount += 1 + else: + raise Exception("IMAP storing error: %s" % data) + return rowcount + + def count(self,query,distinct=None): + counter = 0 + tablename = self.get_query_mailbox(query) + if query and tablename is not None: + if use_common_filters(query): + query = self.common_filter(query, [tablename,]) + result, data = self.connection.select(self.connection.mailbox_names[tablename]) + string_query = "(%s)" % query + result, data = self.connection.search(None, string_query) + store_list = [item.strip() for item in data[0].split() if item.strip().isdigit()] + counter = len(store_list) + return counter + + def delete(self, table, query): + counter = 0 + tablename = table._dalname + if query: + if use_common_filters(query): + query = self.common_filter(query, [tablename,]) + result, data = self.connection.select(self.connection.mailbox_names[tablename]) + string_query = "(%s)" % query + result, data = self.connection.search(None, string_query) + store_list = [item.strip() for item in data[0].split() if item.strip().isdigit()] + for number in store_list: + result, data = self.connection.store(number, "+FLAGS", "(\\Deleted)") + if result == "OK": + counter += 1 + else: + raise Exception("IMAP store error: %s" % data) + if counter > 0: + result, data = self.connection.expunge() + return counter + + def BELONGS(self, first, second): + result = None + name = self.search_fields[first.name] + if name == "MESSAGE": + values = [str(val) for val in second if str(val).isdigit()] + result = "%s" % ",".join(values).strip() + + elif name == "UID": + values = [str(val) for val in second if str(val).isdigit()] + result = "UID %s" % ",".join(values).strip() + + else: + raise Exception("Operation not supported") + # result = "(%s %s)" % (self.expand(first), self.expand(second)) + return result + + def CONTAINS(self, first, second, case_sensitive=False): + # silently ignore, only case sensitive + result = None + name = self.search_fields[first.name] + + if name in ("FROM", "TO", "SUBJECT", "TEXT"): + result = "%s \"%s\"" % (name, self.expand(second)) + else: + if first.name in ("cc", "bcc"): + result = "%s \"%s\"" % (first.name.upper(), self.expand(second)) + elif first.name == "mime": + result = "HEADER Content-Type \"%s\"" % self.expand(second) + else: + raise Exception("Operation not supported") + return result + + def GT(self, first, second): + result = None + name = self.search_fields[first.name] + if name == "MESSAGE": + last_message = self.get_last_message(first.tablename) + result = "%d:%d" % (int(self.expand(second)) + 1, last_message) + elif name == "UID": + # GT and LT may not return + # expected sets depending on + # the uid format implemented + try: + pedestal, threshold = self.get_uid_bounds(first.tablename) + except TypeError: + e = sys.exc_info()[1] + self.db.logger.debug("Error requesting uid bounds: %s", str(e)) + return "" + try: + lower_limit = int(self.expand(second)) + 1 + except (ValueError, TypeError): + e = sys.exc_info()[1] + raise Exception("Operation not supported (non integer UID)") + result = "UID %s:%s" % (lower_limit, threshold) + elif name == "DATE": + result = "SINCE %s" % self.convert_date(second, add=datetime.timedelta(1)) + elif name == "SIZE": + result = "LARGER %s" % self.expand(second) + else: + raise Exception("Operation not supported") + return result + + def GE(self, first, second): + result = None + name = self.search_fields[first.name] + if name == "MESSAGE": + last_message = self.get_last_message(first.tablename) + result = "%s:%s" % (self.expand(second), last_message) + elif name == "UID": + # GT and LT may not return + # expected sets depending on + # the uid format implemented + try: + pedestal, threshold = self.get_uid_bounds(first.tablename) + except TypeError: + e = sys.exc_info()[1] + self.db.logger.debug("Error requesting uid bounds: %s", str(e)) + return "" + lower_limit = self.expand(second) + result = "UID %s:%s" % (lower_limit, threshold) + elif name == "DATE": + result = "SINCE %s" % self.convert_date(second) + else: + raise Exception("Operation not supported") + return result + + def LT(self, first, second): + result = None + name = self.search_fields[first.name] + if name == "MESSAGE": + result = "%s:%s" % (1, int(self.expand(second)) - 1) + elif name == "UID": + try: + pedestal, threshold = self.get_uid_bounds(first.tablename) + except TypeError: + e = sys.exc_info()[1] + self.db.logger.debug("Error requesting uid bounds: %s", str(e)) + return "" + try: + upper_limit = int(self.expand(second)) - 1 + except (ValueError, TypeError): + e = sys.exc_info()[1] + raise Exception("Operation not supported (non integer UID)") + result = "UID %s:%s" % (pedestal, upper_limit) + elif name == "DATE": + result = "BEFORE %s" % self.convert_date(second) + elif name == "SIZE": + result = "SMALLER %s" % self.expand(second) + else: + raise Exception("Operation not supported") + return result + + def LE(self, first, second): + result = None + name = self.search_fields[first.name] + if name == "MESSAGE": + result = "%s:%s" % (1, self.expand(second)) + elif name == "UID": + try: + pedestal, threshold = self.get_uid_bounds(first.tablename) + except TypeError: + e = sys.exc_info()[1] + self.db.logger.debug("Error requesting uid bounds: %s", str(e)) + return "" + upper_limit = int(self.expand(second)) + result = "UID %s:%s" % (pedestal, upper_limit) + elif name == "DATE": + result = "BEFORE %s" % self.convert_date(second, add=datetime.timedelta(1)) + else: + raise Exception("Operation not supported") + return result + + def NE(self, first, second=None): + if (second is None) and isinstance(first, Field): + # All records special table query + if first.type == "id": + return self.GE(first, 1) + result = self.NOT(self.EQ(first, second)) + result = result.replace("NOT NOT", "").strip() + return result + + def EQ(self,first,second): + name = self.search_fields[first.name] + result = None + if name is not None: + if name == "MESSAGE": + # query by message sequence number + result = "%s" % self.expand(second) + elif name == "UID": + result = "UID %s" % self.expand(second) + elif name == "DATE": + result = "ON %s" % self.convert_date(second) + + elif name in self.flags.values(): + if second: + result = "%s" % (name.upper()[1:]) + else: + result = "NOT %s" % (name.upper()[1:]) + else: + raise Exception("Operation not supported") + else: + raise Exception("Operation not supported") + return result + + def AND(self, first, second): + result = "%s %s" % (self.expand(first), self.expand(second)) + return result + + def OR(self, first, second): + result = "OR %s %s" % (self.expand(first), self.expand(second)) + return "%s" % result.replace("OR OR", "OR") + + def NOT(self, first): + result = "NOT %s" % self.expand(first) + return result diff --git a/web2py/gluon/packages/dal/pydal/contrib/mockimaplib.py b/web2py/gluon/packages/dal/pydal/contrib/mockimaplib.py new file mode 100644 index 0000000..87f8b47 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/contrib/mockimaplib.py @@ -0,0 +1,255 @@ +# -*- encoding: utf-8 -*- + +from imaplib import ParseFlags + +# mockimaplib: A very simple mock server module for imap client APIs +# Copyright (C) 2014 Alan Etkin +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or(at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program. If not, see +# + +""" +mockimaplib allows you to test applications connecting to a dummy imap +service. For more details on the api subset implemented, +refer to the imaplib docs. + +The client should configure a dictionary to map imap string queries to sets +of entries stored in a message dummy storage dictionary. The module includes +a small set of default message records (SPAM and MESSAGES), two mailboxes +(Draft and INBOX) and a list of query/resultset entries (RESULTS). + +Usage: + +>>> import mockimaplib +>>> connection = mockimaplib.IMAP4_SSL() +>>> connection.login(, ) +None +>>> connection.select("INBOX") +("OK", ... ) +# fetch commands specifying single uid or message id +# will try to get messages recorded in SPAM +>>> connection.uid(...) + +# returns a string list of matching message ids +>>> connection.search() +("OK", ... "1 2 ... n") +""" + +MESSAGES = ( +'MIME-Version: 1.0\r\nReceived: by 10.140.91.199 with HTTP; Mon, 27 Jan 2014 13:52:30 -0800 (PST)\r\nDate: Mon, 27 Jan 2014 19:52:30 -0200\r\nDelivered-To: nurse@example.com\r\nMessage-ID: <10101010101010010000010101010001010101001010010000001@mail.example.com>\r\nSubject: spam1\r\nFrom: Mr. Gumby \r\nTo: The nurse \r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\nNurse!\r\n\r\n\r\n', +'MIME-Version: 1.0\r\nReceived: by 10.140.91.199 with HTTP; Mon, 27 Jan 2014 13:52:47 -0800 (PST)\r\nDate: Mon, 27 Jan 2014 19:52:47 -0200\r\nDelivered-To: nurse@example.com\r\nMessage-ID: <101010101010100100000101010100010101010010100100000010@mail.example.com>\r\nSubject: spam2\r\nFrom: Mr. Gumby \r\nTo: The nurse \r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\nNurse, nurse!', +'MIME-Version: 1.0\r\nReceived: by 10.140.91.199 with HTTP; Mon, 27 Jan 2014 13:54:54 -0800 (PST)\r\nDate: Mon, 27 Jan 2014 19:54:54 -0200\r\nDelivered-To: nurse@example.com\r\nMessage-ID: <1010101010101001000001010101000101010100101001000000101@mail.example.com>\r\nSubject: spamalot1\r\nFrom: Mr. Gumby \r\nTo: The nurse \r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\nNurse!\r\n\r\n\r\n', +'MIME-Version: 1.0\r\n\r\nReceived: by 10.140.91.199 with HTTP; Mon, 27 Jan 2014 13:54:54 -0800 (PST)\r\nDate: Mon, 27 Jan 2014 19:54:54 -0200\r\nDelivered-To: nurse@example.com\r\nMessage-ID: <101010101010100100000101010100010101010010100100000010101@mail.example.com>\r\nSubject: spamalot2\r\nFrom: Mr. Gumby \r\nTo: The nurse \r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\nNurse! ... Nurse! ... Nurse!\r\n\r\n\r\n') + +SPAM = { + "INBOX": [ + {"uid": "483209", + "headers": MESSAGES[0], + "complete": MESSAGES[0], + "flags": ""}, + {"uid": "483211", + "headers": MESSAGES[1], + "complete": MESSAGES[1], + "flags": ""}, + {"uid": "483225", + "headers": MESSAGES[2], + "complete": MESSAGES[2], + "flags": ""}], + "Draft":[ + {"uid": "483432", + "headers": MESSAGES[3], + "complete": MESSAGES[3], + "flags": ""},] +} + +RESULTS = { + # : [ | , ...] + "INBOX": { + "(ALL)": (1, 2, 3), + "(1:3)": (1, 2, 3)}, + "Draft": { + "(1:1)": (1,)}, +} + +class Connection(object): + """Dummy connection object for the imap client. + By default, uses the module SPAM and RESULT + sets (use Connection.setup for custom values)""" + def login(self, user, password): + pass + + def __init__(self): + self._readonly = False + self._mailbox = None + self.setup() + + def list(self): + return ('OK', ['(\\HasNoChildren) "/" "%s"' % key for key in self.spam]) + + def select(self, tablename, readonly=False): + self._readonly = readonly + """args: mailbox, boolean + result[1][0] -> int last message id / mailbox lenght + result[0] = 'OK' + """ + self._mailbox = tablename + return ('OK', (len(SPAM[self._mailbox]), None)) + + def uid(self, command, uid, arg): + """ args: + command: "search" | "fetch" + uid: None | uid + parts: "(ALL)" | "(RFC822 FLAGS)" | "(RFC822.HEADER FLAGS)" + + "search", None, "(ALL)" -> ("OK", ("uid_1 uid_2 ... uid_", None)) + "search", None, "" -> ("OK", ("uid_1 uid_2 ... uid_n", None)) + "fetch", uid, parts -> ("OK", ((" ...", ""), "") + [0] [1][0][0] [1][0][1] [1][1] + """ + if command == "search": + return self._search(arg) + elif command == "fetch": + return self._fetch(uid, arg) + + def _search(self, query): + return ("OK", (" ".join([str(item["uid"]) for item in self._get_messages(query)]), None)) + + def _fetch(self, value, arg): + try: + message = self.spam[self._mailbox][value - 1] + message_id = value + except TypeError: + for x, item in enumerate(self.spam[self._mailbox]): + if item["uid"] == value: + message = item + message_id = x + 1 + break + + parts = "headers" + if arg in ("(ALL)", "(RFC822 FLAGS)"): + parts = "complete" + + return ("OK", (("%s " % message_id, message[parts]), message["flags"])) + + def _get_messages(self, query): + if query.strip().isdigit(): + return [self.spam[self._mailbox][int(query.strip()) - 1],] + elif query[1:-1].strip().isdigit(): + return [self.spam[self._mailbox][int(query[1:-1].strip()) -1],] + elif query[1:-1].replace("UID", "").strip().isdigit(): + for item in self.spam[self._mailbox]: + if item["uid"] == query[1:-1].replace("UID", "").strip(): + return [item,] + messages = [] + try: + for m in self.results[self._mailbox][query]: + try: + self.spam[self._mailbox][m - 1]["id"] = m + messages.append(self.spam[self._mailbox][m - 1]) + except TypeError: + for x, item in enumerate(self.spam[self._mailbox]): + if item["uid"] == m: + item["id"] = x + 1 + messages.append(item) + break + except IndexError: + # message removed + pass + return messages + except KeyError: + raise ValueError("The client issued an unexpected query: %s" % query) + + def setup(self, spam={}, results={}): + """adds custom message and query databases or sets + the values to the module defaults. + """ + + self.spam = spam + self.results = results + if not spam: + for key in SPAM: + self.spam[key] = [] + for d in SPAM[key]: + self.spam[key].append(d.copy()) + if not results: + for key in RESULTS: + self.results[key] = RESULTS[key].copy() + + + def search(self, first, query): + """ args: + first: None + query: string with mailbox query (flags, date, uid, id, ...) + example: '2:15723 BEFORE 27-Jan-2014 FROM "gumby"' + result[1][0] -> "id_1 id_2 ... id_n" + """ + messages = self._get_messages(query) + ids = " ".join([str(item["id"]) for item in messages]) + return ("OK", (ids, None)) + + def append(self, mailbox, flags, struct_time, message): + """ + result, data = self.connection.append(mailbox, flags, struct_time, message) + if result == "OK": + uid = int(re.findall("\d+", str(data))[-1]) + """ + last = self.spam[mailbox][-1] + try: + uid = int(last["uid"]) +1 + except ValueError: + alluids = [] + for _mailbox in self.spam.keys(): + for item in self.spam[_mailbox]: + try: + alluids.append(int(item["uid"])) + except: + pass + if len(alluids) > 0: + uid = max(alluids) + 1 + else: + uid = 1 + flags = "FLAGS " + flags + item = {"uid": str(uid), "headers": message, "complete": message, "flags": flags} + self.spam[mailbox].append(item) + return ("OK", "spam spam %s spam" % uid) + + + def store(self, *args): + """ + implements some flag commands + args: ("", "<+|->FLAGS", "(\\Flag1 \\Flag2 ... \\Flagn)") + """ + message = self.spam[self._mailbox][int(args[0] - 1)] + old_flags = ParseFlags(message["flags"]) + flags = ParseFlags("FLAGS" + args[2]) + if args[1].strip().startswith("+"): + message["flags"] = "FLAGS (%s)" % " ".join(set(flags + old_flags)) + elif args[1].strip().startswith("-"): + message["flags"] = "FLAGS (%s)" % " ".join([flag for flag in old_flags if not flag in flags]) + + def expunge(self): + """implements removal of deleted flag messages""" + for x, item in enumerate(self.spam[self._mailbox]): + if "\\Deleted" in item["flags"]: + self.spam[self._mailbox].pop(x) + + +class IMAP4(object): + """>>> connection = IMAP4() # creates the dummy imap4 client object""" + def __new__(self, *args, **kwargs): + # args: (server, port) + return Connection() + +IMAP4_SSL = IMAP4 + diff --git a/web2py/gluon/packages/dal/pydal/contrib/ordereddict.py b/web2py/gluon/packages/dal/pydal/contrib/ordereddict.py new file mode 100644 index 0000000..2d1d813 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/contrib/ordereddict.py @@ -0,0 +1,128 @@ +# Copyright (c) 2009 Raymond Hettinger +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +from UserDict import DictMixin + + +class OrderedDict(dict, DictMixin): + + def __init__(self, *args, **kwds): + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__end + except AttributeError: + self.clear() + self.update(*args, **kwds) + + def clear(self): + self.__end = end = [] + end += [None, end, end] # sentinel node for doubly linked list + self.__map = {} # key --> [key, prev, next] + dict.clear(self) + + def __setitem__(self, key, value): + if key not in self: + end = self.__end + curr = end[1] + curr[2] = end[1] = self.__map[key] = [key, curr, end] + dict.__setitem__(self, key, value) + + def __delitem__(self, key): + dict.__delitem__(self, key) + key, prev, next = self.__map.pop(key) + prev[2] = next + next[1] = prev + + def __iter__(self): + end = self.__end + curr = end[2] + while curr is not end: + yield curr[0] + curr = curr[2] + + def __reversed__(self): + end = self.__end + curr = end[1] + while curr is not end: + yield curr[0] + curr = curr[1] + + def popitem(self, last=True): + if not self: + raise KeyError('dictionary is empty') + if last: + key = reversed(self).next() + else: + key = iter(self).next() + value = self.pop(key) + return key, value + + def __reduce__(self): + items = [[k, self[k]] for k in self] + tmp = self.__map, self.__end + del self.__map, self.__end + inst_dict = vars(self).copy() + self.__map, self.__end = tmp + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def keys(self): + return list(self) + + setdefault = DictMixin.setdefault + update = DictMixin.update + pop = DictMixin.pop + values = DictMixin.values + items = DictMixin.items + iterkeys = DictMixin.iterkeys + itervalues = DictMixin.itervalues + iteritems = DictMixin.iteritems + + def __repr__(self): + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + + def copy(self): + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + if isinstance(other, OrderedDict): + if len(self) != len(other): + return False + for p, q in zip(self.items(), other.items()): + if p != q: + return False + return True + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other diff --git a/web2py/gluon/packages/dal/pydal/contrib/portalocker.py b/web2py/gluon/packages/dal/pydal/contrib/portalocker.py new file mode 100644 index 0000000..dec70d2 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/contrib/portalocker.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Cross-platform (posix/nt) API for flock-style file locking. + +Synopsis:: + + import portalocker + file = open(\"somefile\", \"r+\") + portalocker.lock(file, portalocker.LOCK_EX) + file.seek(12) + file.write(\"foo\") + file.close() + +If you know what you're doing, you may choose to:: + + portalocker.unlock(file) + +before closing the file, but why? + +Methods:: + + lock( file, flags ) + unlock( file ) + +Constants:: + + LOCK_EX - exclusive lock + LOCK_SH - shared lock + LOCK_NB - don't lock when locking + +Original +--------- +http://code.activestate.com/recipes/65203-portalocker-cross-platform-posixnt-api-for-flock-s/ + +I learned the win32 technique for locking files from sample code +provided by John Nielsen in the documentation +that accompanies the win32 modules. + +Author: Jonathan Feinberg + + +Roundup Changes +--------------- +2012-11-28 (anatoly techtonik) + - Ported to ctypes + - Dropped support for Win95, Win98 and WinME + - Added return result + +Web2py Changes +-------------- +2016-07-28 (niphlod) + - integrated original recipe, web2py's GAE warnings and roundup in a unique + solution + +""" +import sys +import logging + +PY2 = sys.version_info[0] == 2 + +logger = logging.getLogger("pydal") + + +os_locking = None +try: + import google.appengine + os_locking = 'gae' +except: + try: + import fcntl + os_locking = 'posix' + except: + try: + import msvcrt + import ctypes + from ctypes.wintypes import BOOL, DWORD, HANDLE + from ctypes import windll + os_locking = 'windows' + except: + pass + +if os_locking == 'windows': + LOCK_SH = 0 # the default + LOCK_NB = 0x1 # LOCKFILE_FAIL_IMMEDIATELY + LOCK_EX = 0x2 # LOCKFILE_EXCLUSIVE_LOCK + + # --- the code is taken from pyserial project --- + # + # detect size of ULONG_PTR + def is_64bit(): + return ctypes.sizeof(ctypes.c_ulong) != ctypes.sizeof(ctypes.c_void_p) + + if is_64bit(): + ULONG_PTR = ctypes.c_int64 + else: + ULONG_PTR = ctypes.c_ulong + PVOID = ctypes.c_void_p + + # --- Union inside Structure by stackoverflow:3480240 --- + class _OFFSET(ctypes.Structure): + _fields_ = [ + ('Offset', DWORD), + ('OffsetHigh', DWORD)] + + class _OFFSET_UNION(ctypes.Union): + _anonymous_ = ['_offset'] + _fields_ = [ + ('_offset', _OFFSET), + ('Pointer', PVOID)] + + class OVERLAPPED(ctypes.Structure): + _anonymous_ = ['_offset_union'] + _fields_ = [ + ('Internal', ULONG_PTR), + ('InternalHigh', ULONG_PTR), + ('_offset_union', _OFFSET_UNION), + ('hEvent', HANDLE)] + + LPOVERLAPPED = ctypes.POINTER(OVERLAPPED) + + # --- Define function prototypes for extra safety --- + LockFileEx = windll.kernel32.LockFileEx + LockFileEx.restype = BOOL + LockFileEx.argtypes = [HANDLE, DWORD, DWORD, DWORD, DWORD, LPOVERLAPPED] + UnlockFileEx = windll.kernel32.UnlockFileEx + UnlockFileEx.restype = BOOL + UnlockFileEx.argtypes = [HANDLE, DWORD, DWORD, DWORD, LPOVERLAPPED] + + def lock(file, flags): + hfile = msvcrt.get_osfhandle(file.fileno()) + overlapped = OVERLAPPED() + LockFileEx(hfile, flags, 0, 0, 0xFFFF0000, ctypes.byref(overlapped)) + + def unlock(file): + hfile = msvcrt.get_osfhandle(file.fileno()) + overlapped = OVERLAPPED() + UnlockFileEx(hfile, 0, 0, 0xFFFF0000, ctypes.byref(overlapped)) + +elif os_locking == 'posix': + LOCK_EX = fcntl.LOCK_EX + LOCK_SH = fcntl.LOCK_SH + LOCK_NB = fcntl.LOCK_NB + + def lock(file, flags): + fcntl.flock(file.fileno(), flags) + + def unlock(file): + fcntl.flock(file.fileno(), fcntl.LOCK_UN) + + +else: + if os_locking != 'gae': + logger.debug('no file locking, this will cause problems') + + LOCK_EX = None + LOCK_SH = None + LOCK_NB = None + + def lock(file, flags): + pass + + def unlock(file): + pass + + +def open_file(filename, mode): + if PY2 or 'b' in mode: + f = open(filename, mode) + else: + f = open(filename, mode, encoding='utf8') + return f + + +class LockedFile(object): + def __init__(self, filename, mode='rb'): + self.filename = filename + self.mode = mode + self.file = None + if 'r' in mode: + self.file = open_file(filename, mode) + lock(self.file, LOCK_SH) + elif 'w' in mode or 'a' in mode: + self.file = open_file(filename, mode.replace('w', 'a')) + lock(self.file, LOCK_EX) + if 'a' not in mode: + self.file.seek(0) + self.file.truncate(0) + else: + raise RuntimeError("invalid LockedFile(...,mode)") + + def read(self, size=None): + return self.file.read() if size is None else self.file.read(size) + + def readline(self): + return self.file.readline() + + def readlines(self): + return self.file.readlines() + + def write(self, data): + self.file.write(data) + self.file.flush() + + def close(self): + if self.file is not None: + unlock(self.file) + self.file.close() + self.file = None + + def __del__(self): + if self.file is not None: + self.close() + + +def read_locked(filename): + fp = LockedFile(filename, 'rb') + data = fp.read() + fp.close() + return data + + +def write_locked(filename, data): + fp = LockedFile(filename, 'wb') + data = fp.write(data) + fp.close() diff --git a/web2py/gluon/packages/dal/pydal/contrib/reserved_sql_keywords.py b/web2py/gluon/packages/dal/pydal/contrib/reserved_sql_keywords.py new file mode 100644 index 0000000..af9c73a --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/contrib/reserved_sql_keywords.py @@ -0,0 +1,1724 @@ +# encoding utf-8 + +__author__ = "Thadeus Burgess " + +# we classify as "non-reserved" those key words that are explicitly known +# to the parser but are allowed as column or table names. Some key words +# that are otherwise non-reserved cannot be used as function or data type n +# ames and are in the nonreserved list. (Most of these words represent +# built-in functions or data types with special syntax. The function +# or type is still available but it cannot be redefined by the user.) +# Labeled "reserved" are those tokens that are not allowed as column or +# table names. Some reserved key words are allowable as names for +# functions or data typesself. + +# Note at the bottom of the list is a dict containing references to the +# tuples, and also if you add a list don't forget to remove its default +# set of COMMON. + +# Keywords that are adapter specific. Such as a list of "postgresql" +# or "mysql" keywords + +# These are keywords that are common to all SQL dialects, and should +# never be used as a table or column. Even if you use one of these +# the cursor will throw an OperationalError for the SQL syntax. + +from .._compat import PY2 + +if not PY2: + from functools import reduce + +COMMON = set(( + 'SELECT', + 'INSERT', + 'DELETE', + 'UPDATE', + 'DROP', + 'CREATE', + 'ALTER', + + 'WHERE', + 'FROM', + 'INNER', + 'JOIN', + 'AND', + 'OR', + 'LIKE', + 'ON', + 'IN', + 'SET', + + 'BY', + 'GROUP', + 'ORDER', + 'LEFT', + 'OUTER', + + 'IF', + 'END', + 'THEN', + 'LOOP', + 'AS', + 'ELSE', + 'FOR', + + 'CASE', + 'WHEN', + 'MIN', + 'MAX', + 'DISTINCT', +)) + + +POSTGRESQL = set(( + 'FALSE', + 'TRUE', + 'ALL', + 'ANALYSE', + 'ANALYZE', + 'AND', + 'ANY', + 'ARRAY', + 'AS', + 'ASC', + 'ASYMMETRIC', + 'AUTHORIZATION', + 'BETWEEN', + 'BIGINT', + 'BINARY', + 'BIT', + 'BOOLEAN', + 'BOTH', + 'CASE', + 'CAST', + 'CHAR', + 'CHARACTER', + 'CHECK', + 'COALESCE', + 'COLLATE', + 'COLUMN', + 'CONSTRAINT', + 'CREATE', + 'CROSS', + 'CURRENT_CATALOG', + 'CURRENT_DATE', + 'CURRENT_ROLE', + 'CURRENT_SCHEMA', + 'CURRENT_TIME', + 'CURRENT_TIMESTAMP', + 'CURRENT_USER', + 'DEC', + 'DECIMAL', + 'DEFAULT', + 'DEFERRABLE', + 'DESC', + 'DISTINCT', + 'DO', + 'ELSE', + 'END', + 'EXCEPT', + 'EXISTS', + 'EXTRACT', + 'FETCH', + 'FLOAT', + 'FOR', + 'FOREIGN', + 'FREEZE', + 'FROM', + 'FULL', + 'GRANT', + 'GREATEST', + 'GROUP', + 'HAVING', + 'ILIKE', + 'IN', + 'INITIALLY', + 'INNER', + 'INOUT', + 'INT', + 'INTEGER', + 'INTERSECT', + 'INTERVAL', + 'INTO', + 'IS', + 'ISNULL', + 'JOIN', + 'LEADING', + 'LEAST', + 'LEFT', + 'LIKE', + 'LIMIT', + 'LOCALTIME', + 'LOCALTIMESTAMP', + 'NATIONAL', + 'NATURAL', + 'NCHAR', + 'NEW', + 'NONE', + 'NOT', + 'NOTNULL', + 'NULL', + 'NULLIF', + 'NUMERIC', + 'OFF', + 'OFFSET', + 'OLD', + 'ON', + 'ONLY', + 'OR', + 'ORDER', + 'OUT', + 'OUTER', + 'OVERLAPS', + 'OVERLAY', + 'PLACING', + 'POSITION', + 'PRECISION', + 'PRIMARY', + 'REAL', + 'REFERENCES', + 'RETURNING', + 'RIGHT', + 'ROW', + 'SELECT', + 'SESSION_USER', + 'SETOF', + 'SIMILAR', + 'SMALLINT', + 'SOME', + 'SUBSTRING', + 'SYMMETRIC', + 'TABLE', + 'THEN', + 'TIME', + 'TIMESTAMP', + 'TO', + 'TRAILING', + 'TREAT', + 'TRIM', + 'UNION', + 'UNIQUE', + 'USER', + 'USING', + 'VALUES', + 'VARCHAR', + 'VARIADIC', + 'VERBOSE', + 'WHEN', + 'WHERE', + 'WITH', + 'XMLATTRIBUTES', + 'XMLCONCAT', + 'XMLELEMENT', + 'XMLFOREST', + 'XMLPARSE', + 'XMLPI', + 'XMLROOT', + 'XMLSERIALIZE', +)) + + +POSTGRESQL_NONRESERVED = set(( + 'A', + 'ABORT', + 'ABS', + 'ABSENT', + 'ABSOLUTE', + 'ACCESS', + 'ACCORDING', + 'ACTION', + 'ADA', + 'ADD', + 'ADMIN', + 'AFTER', + 'AGGREGATE', + 'ALIAS', + 'ALLOCATE', + 'ALSO', + 'ALTER', + 'ALWAYS', + 'ARE', + 'ARRAY_AGG', + 'ASENSITIVE', + 'ASSERTION', + 'ASSIGNMENT', + 'AT', + 'ATOMIC', + 'ATTRIBUTE', + 'ATTRIBUTES', + 'AVG', + 'BACKWARD', + 'BASE64', + 'BEFORE', + 'BEGIN', + 'BERNOULLI', + 'BIT_LENGTH', + 'BITVAR', + 'BLOB', + 'BOM', + 'BREADTH', + 'BY', + 'C', + 'CACHE', + 'CALL', + 'CALLED', + 'CARDINALITY', + 'CASCADE', + 'CASCADED', + 'CATALOG', + 'CATALOG_NAME', + 'CEIL', + 'CEILING', + 'CHAIN', + 'CHAR_LENGTH', + 'CHARACTER_LENGTH', + 'CHARACTER_SET_CATALOG', + 'CHARACTER_SET_NAME', + 'CHARACTER_SET_SCHEMA', + 'CHARACTERISTICS', + 'CHARACTERS', + 'CHECKED', + 'CHECKPOINT', + 'CLASS', + 'CLASS_ORIGIN', + 'CLOB', + 'CLOSE', + 'CLUSTER', + 'COBOL', + 'COLLATION', + 'COLLATION_CATALOG', + 'COLLATION_NAME', + 'COLLATION_SCHEMA', + 'COLLECT', + 'COLUMN_NAME', + 'COLUMNS', + 'COMMAND_FUNCTION', + 'COMMAND_FUNCTION_CODE', + 'COMMENT', + 'COMMIT', + 'COMMITTED', + 'COMPLETION', + 'CONCURRENTLY', + 'CONDITION', + 'CONDITION_NUMBER', + 'CONFIGURATION', + 'CONNECT', + 'CONNECTION', + 'CONNECTION_NAME', + 'CONSTRAINT_CATALOG', + 'CONSTRAINT_NAME', + 'CONSTRAINT_SCHEMA', + 'CONSTRAINTS', + 'CONSTRUCTOR', + 'CONTAINS', + 'CONTENT', + 'CONTINUE', + 'CONVERSION', + 'CONVERT', + 'COPY', + 'CORR', + 'CORRESPONDING', + 'COST', + 'COUNT', + 'COVAR_POP', + 'COVAR_SAMP', + 'CREATEDB', + 'CREATEROLE', + 'CREATEUSER', + 'CSV', + 'CUBE', + 'CUME_DIST', + 'CURRENT', + 'CURRENT_DEFAULT_TRANSFORM_GROUP', + 'CURRENT_PATH', + 'CURRENT_TRANSFORM_GROUP_FOR_TYPE', + 'CURSOR', + 'CURSOR_NAME', + 'CYCLE', + 'DATA', + 'DATABASE', + 'DATE', + 'DATETIME_INTERVAL_CODE', + 'DATETIME_INTERVAL_PRECISION', + 'DAY', + 'DEALLOCATE', + 'DECLARE', + 'DEFAULTS', + 'DEFERRED', + 'DEFINED', + 'DEFINER', + 'DEGREE', + 'DELETE', + 'DELIMITER', + 'DELIMITERS', + 'DENSE_RANK', + 'DEPTH', + 'DEREF', + 'DERIVED', + 'DESCRIBE', + 'DESCRIPTOR', + 'DESTROY', + 'DESTRUCTOR', + 'DETERMINISTIC', + 'DIAGNOSTICS', + 'DICTIONARY', + 'DISABLE', + 'DISCARD', + 'DISCONNECT', + 'DISPATCH', + 'DOCUMENT', + 'DOMAIN', + 'DOUBLE', + 'DROP', + 'DYNAMIC', + 'DYNAMIC_FUNCTION', + 'DYNAMIC_FUNCTION_CODE', + 'EACH', + 'ELEMENT', + 'EMPTY', + 'ENABLE', + 'ENCODING', + 'ENCRYPTED', + 'END-EXEC', + 'ENUM', + 'EQUALS', + 'ESCAPE', + 'EVERY', + 'EXCEPTION', + 'EXCLUDE', + 'EXCLUDING', + 'EXCLUSIVE', + 'EXEC', + 'EXECUTE', + 'EXISTING', + 'EXP', + 'EXPLAIN', + 'EXTERNAL', + 'FAMILY', + 'FILTER', + 'FINAL', + 'FIRST', + 'FIRST_VALUE', + 'FLAG', + 'FLOOR', + 'FOLLOWING', + 'FORCE', + 'FORTRAN', + 'FORWARD', + 'FOUND', + 'FREE', + 'FUNCTION', + 'FUSION', + 'G', + 'GENERAL', + 'GENERATED', + 'GET', + 'GLOBAL', + 'GO', + 'GOTO', + 'GRANTED', + 'GROUPING', + 'HANDLER', + 'HEADER', + 'HEX', + 'HIERARCHY', + 'HOLD', + 'HOST', + 'HOUR', + # 'ID', + 'IDENTITY', + 'IF', + 'IGNORE', + 'IMMEDIATE', + 'IMMUTABLE', + 'IMPLEMENTATION', + 'IMPLICIT', + 'INCLUDING', + 'INCREMENT', + 'INDENT', + 'INDEX', + 'INDEXES', + 'INDICATOR', + 'INFIX', + 'INHERIT', + 'INHERITS', + 'INITIALIZE', + 'INPUT', + 'INSENSITIVE', + 'INSERT', + 'INSTANCE', + 'INSTANTIABLE', + 'INSTEAD', + 'INTERSECTION', + 'INVOKER', + 'ISOLATION', + 'ITERATE', + 'K', + 'KEY', + 'KEY_MEMBER', + 'KEY_TYPE', + 'LAG', + 'LANCOMPILER', + 'LANGUAGE', + 'LARGE', + 'LAST', + 'LAST_VALUE', + 'LATERAL', + 'LC_COLLATE', + 'LC_CTYPE', + 'LEAD', + 'LENGTH', + 'LESS', + 'LEVEL', + 'LIKE_REGEX', + 'LISTEN', + 'LN', + 'LOAD', + 'LOCAL', + 'LOCATION', + 'LOCATOR', + 'LOCK', + 'LOGIN', + 'LOWER', + 'M', + 'MAP', + 'MAPPING', + 'MATCH', + 'MATCHED', + 'MAX', + 'MAX_CARDINALITY', + 'MAXVALUE', + 'MEMBER', + 'MERGE', + 'MESSAGE_LENGTH', + 'MESSAGE_OCTET_LENGTH', + 'MESSAGE_TEXT', + 'METHOD', + 'MIN', + 'MINUTE', + 'MINVALUE', + 'MOD', + 'MODE', + 'MODIFIES', + 'MODIFY', + 'MODULE', + 'MONTH', + 'MORE', + 'MOVE', + 'MULTISET', + 'MUMPS', + # 'NAME', + 'NAMES', + 'NAMESPACE', + 'NCLOB', + 'NESTING', + 'NEXT', + 'NFC', + 'NFD', + 'NFKC', + 'NFKD', + 'NIL', + 'NO', + 'NOCREATEDB', + 'NOCREATEROLE', + 'NOCREATEUSER', + 'NOINHERIT', + 'NOLOGIN', + 'NORMALIZE', + 'NORMALIZED', + 'NOSUPERUSER', + 'NOTHING', + 'NOTIFY', + 'NOWAIT', + 'NTH_VALUE', + 'NTILE', + 'NULLABLE', + 'NULLS', + 'NUMBER', + 'OBJECT', + 'OCCURRENCES_REGEX', + 'OCTET_LENGTH', + 'OCTETS', + 'OF', + 'OIDS', + 'OPEN', + 'OPERATION', + 'OPERATOR', + 'OPTION', + 'OPTIONS', + 'ORDERING', + 'ORDINALITY', + 'OTHERS', + 'OUTPUT', + 'OVER', + 'OVERRIDING', + 'OWNED', + 'OWNER', + 'P', + 'PAD', + 'PARAMETER', + 'PARAMETER_MODE', + 'PARAMETER_NAME', + 'PARAMETER_ORDINAL_POSITION', + 'PARAMETER_SPECIFIC_CATALOG', + 'PARAMETER_SPECIFIC_NAME', + 'PARAMETER_SPECIFIC_SCHEMA', + 'PARAMETERS', + 'PARSER', + 'PARTIAL', + 'PARTITION', + 'PASCAL', + 'PASSING', + # 'PASSWORD', + 'PATH', + 'PERCENT_RANK', + 'PERCENTILE_CONT', + 'PERCENTILE_DISC', + 'PLANS', + 'PLI', + 'POSITION_REGEX', + 'POSTFIX', + 'POWER', + 'PRECEDING', + 'PREFIX', + 'PREORDER', + 'PREPARE', + 'PREPARED', + 'PRESERVE', + 'PRIOR', + 'PRIVILEGES', + 'PROCEDURAL', + 'PROCEDURE', + 'PUBLIC', + 'QUOTE', + 'RANGE', + 'RANK', + 'READ', + 'READS', + 'REASSIGN', + 'RECHECK', + 'RECURSIVE', + 'REF', + 'REFERENCING', + 'REGR_AVGX', + 'REGR_AVGY', + 'REGR_COUNT', + 'REGR_INTERCEPT', + 'REGR_R2', + 'REGR_SLOPE', + 'REGR_SXX', + 'REGR_SXY', + 'REGR_SYY', + 'REINDEX', + 'RELATIVE', + 'RELEASE', + 'RENAME', + 'REPEATABLE', + 'REPLACE', + 'REPLICA', + 'RESET', + 'RESPECT', + 'RESTART', + 'RESTRICT', + 'RESULT', + 'RETURN', + 'RETURNED_CARDINALITY', + 'RETURNED_LENGTH', + 'RETURNED_OCTET_LENGTH', + 'RETURNED_SQLSTATE', + 'RETURNS', + 'REVOKE', + # 'ROLE', + 'ROLLBACK', + 'ROLLUP', + 'ROUTINE', + 'ROUTINE_CATALOG', + 'ROUTINE_NAME', + 'ROUTINE_SCHEMA', + 'ROW_COUNT', + 'ROW_NUMBER', + 'ROWS', + 'RULE', + 'SAVEPOINT', + 'SCALE', + 'SCHEMA', + 'SCHEMA_NAME', + 'SCOPE', + 'SCOPE_CATALOG', + 'SCOPE_NAME', + 'SCOPE_SCHEMA', + 'SCROLL', + 'SEARCH', + 'SECOND', + 'SECTION', + 'SECURITY', + 'SELF', + 'SENSITIVE', + 'SEQUENCE', + 'SERIALIZABLE', + 'SERVER', + 'SERVER_NAME', + 'SESSION', + 'SET', + 'SETS', + 'SHARE', + 'SHOW', + 'SIMPLE', + 'SIZE', + 'SOURCE', + 'SPACE', + 'SPECIFIC', + 'SPECIFIC_NAME', + 'SPECIFICTYPE', + 'SQL', + 'SQLCODE', + 'SQLERROR', + 'SQLEXCEPTION', + 'SQLSTATE', + 'SQLWARNING', + 'SQRT', + 'STABLE', + 'STANDALONE', + 'START', + 'STATE', + 'STATEMENT', + 'STATIC', + 'STATISTICS', + 'STDDEV_POP', + 'STDDEV_SAMP', + 'STDIN', + 'STDOUT', + 'STORAGE', + 'STRICT', + 'STRIP', + 'STRUCTURE', + 'STYLE', + 'SUBCLASS_ORIGIN', + 'SUBLIST', + 'SUBMULTISET', + 'SUBSTRING_REGEX', + 'SUM', + 'SUPERUSER', + 'SYSID', + 'SYSTEM', + 'SYSTEM_USER', + 'T', + # 'TABLE_NAME', + 'TABLESAMPLE', + 'TABLESPACE', + 'TEMP', + 'TEMPLATE', + 'TEMPORARY', + 'TERMINATE', + 'TEXT', + 'THAN', + 'TIES', + 'TIMEZONE_HOUR', + 'TIMEZONE_MINUTE', + 'TOP_LEVEL_COUNT', + 'TRANSACTION', + 'TRANSACTION_ACTIVE', + 'TRANSACTIONS_COMMITTED', + 'TRANSACTIONS_ROLLED_BACK', + 'TRANSFORM', + 'TRANSFORMS', + 'TRANSLATE', + 'TRANSLATE_REGEX', + 'TRANSLATION', + 'TRIGGER', + 'TRIGGER_CATALOG', + 'TRIGGER_NAME', + 'TRIGGER_SCHEMA', + 'TRIM_ARRAY', + 'TRUNCATE', + 'TRUSTED', + 'TYPE', + 'UESCAPE', + 'UNBOUNDED', + 'UNCOMMITTED', + 'UNDER', + 'UNENCRYPTED', + 'UNKNOWN', + 'UNLISTEN', + 'UNNAMED', + 'UNNEST', + 'UNTIL', + 'UNTYPED', + 'UPDATE', + 'UPPER', + 'URI', + 'USAGE', + 'USER_DEFINED_TYPE_CATALOG', + 'USER_DEFINED_TYPE_CODE', + 'USER_DEFINED_TYPE_NAME', + 'USER_DEFINED_TYPE_SCHEMA', + 'VACUUM', + 'VALID', + 'VALIDATOR', + 'VALUE', + 'VAR_POP', + 'VAR_SAMP', + 'VARBINARY', + 'VARIABLE', + 'VARYING', + 'VERSION', + 'VIEW', + 'VOLATILE', + 'WHENEVER', + 'WHITESPACE', + 'WIDTH_BUCKET', + 'WINDOW', + 'WITHIN', + 'WITHOUT', + 'WORK', + 'WRAPPER', + 'WRITE', + 'XML', + 'XMLAGG', + 'XMLBINARY', + 'XMLCAST', + 'XMLCOMMENT', + 'XMLDECLARATION', + 'XMLDOCUMENT', + 'XMLEXISTS', + 'XMLITERATE', + 'XMLNAMESPACES', + 'XMLQUERY', + 'XMLSCHEMA', + 'XMLTABLE', + 'XMLTEXT', + 'XMLVALIDATE', + 'YEAR', + 'YES', + 'ZONE', + )) + +#Thanks villas +FIREBIRD = set(( + 'ABS', + 'ACTIVE', + 'ADMIN', + 'AFTER', + 'ASCENDING', + 'AUTO', + 'AUTODDL', + 'BASED', + 'BASENAME', + 'BASE_NAME', + 'BEFORE', + 'BIT_LENGTH', + 'BLOB', + 'BLOBEDIT', + 'BOOLEAN', + 'BOTH', + 'BUFFER', + 'CACHE', + 'CHAR_LENGTH', + 'CHARACTER_LENGTH', + 'CHECK_POINT_LEN', + 'CHECK_POINT_LENGTH', + 'CLOSE', + 'COMMITTED', + 'COMPILETIME', + 'COMPUTED', + 'CONDITIONAL', + 'CONNECT', + 'CONTAINING', + 'CROSS', + 'CSTRING', + 'CURRENT_CONNECTION', + 'CURRENT_ROLE', + 'CURRENT_TRANSACTION', + 'CURRENT_USER', + 'DATABASE', + 'DB_KEY', + 'DEBUG', + 'DESCENDING', + 'DISCONNECT', + 'DISPLAY', + 'DO', + 'ECHO', + 'EDIT', + 'ENTRY_POINT', + 'EVENT', + 'EXIT', + 'EXTERN', + 'FALSE', + 'FETCH', + 'FILE', + 'FILTER', + 'FREE_IT', + 'FUNCTION', + 'GDSCODE', + 'GENERATOR', + 'GEN_ID', + 'GLOBAL', + 'GROUP_COMMIT_WAIT', + 'GROUP_COMMIT_WAIT_TIME', + 'HELP', + 'IF', + 'INACTIVE', + 'INDEX', + 'INIT', + 'INPUT_TYPE', + 'INSENSITIVE', + 'ISQL', + 'LC_MESSAGES', + 'LC_TYPE', + 'LEADING', + 'LENGTH', + 'LEV', + 'LOGFILE', + 'LOG_BUFFER_SIZE', + 'LOG_BUF_SIZE', + 'LONG', + 'LOWER', + 'MANUAL', + 'MAXIMUM', + 'MAXIMUM_SEGMENT', + 'MAX_SEGMENT', + 'MERGE', + 'MESSAGE', + 'MINIMUM', + 'MODULE_NAME', + 'NOAUTO', + 'NUM_LOG_BUFS', + 'NUM_LOG_BUFFERS', + 'OCTET_LENGTH', + 'OPEN', + 'OUTPUT_TYPE', + 'OVERFLOW', + 'PAGE', + 'PAGELENGTH', + 'PAGES', + 'PAGE_SIZE', + 'PARAMETER', + # 'PASSWORD', + 'PLAN', + 'POST_EVENT', + 'QUIT', + 'RAW_PARTITIONS', + 'RDB$DB_KEY', + 'RECORD_VERSION', + 'RECREATE', + 'RECURSIVE', + 'RELEASE', + 'RESERV', + 'RESERVING', + 'RETAIN', + 'RETURN', + 'RETURNING_VALUES', + 'RETURNS', + # 'ROLE', + 'ROW_COUNT', + 'ROWS', + 'RUNTIME', + 'SAVEPOINT', + 'SECOND', + 'SENSITIVE', + 'SHADOW', + 'SHARED', + 'SHELL', + 'SHOW', + 'SINGULAR', + 'SNAPSHOT', + 'SORT', + 'STABILITY', + 'START', + 'STARTING', + 'STARTS', + 'STATEMENT', + 'STATIC', + 'STATISTICS', + 'SUB_TYPE', + 'SUSPEND', + 'TERMINATOR', + 'TRAILING', + 'TRIGGER', + 'TRIM', + 'TRUE', + 'TYPE', + 'UNCOMMITTED', + 'UNKNOWN', + 'USING', + 'VARIABLE', + 'VERSION', + 'WAIT', + 'WEEKDAY', + 'WHILE', + 'YEARDAY', + )) +FIREBIRD_NONRESERVED = set(( + 'BACKUP', + 'BLOCK', + 'COALESCE', + 'COLLATION', + 'COMMENT', + 'DELETING', + 'DIFFERENCE', + 'IIF', + 'INSERTING', + 'LAST', + 'LEAVE', + 'LOCK', + 'NEXT', + 'NULLIF', + 'NULLS', + 'RESTART', + 'RETURNING', + 'SCALAR_ARRAY', + 'SEQUENCE', + 'STATEMENT', + 'UPDATING', + 'ABS', + 'ACCENT', + 'ACOS', + 'ALWAYS', + 'ASCII_CHAR', + 'ASCII_VAL', + 'ASIN', + 'ATAN', + 'ATAN2', + 'BACKUP', + 'BIN_AND', + 'BIN_OR', + 'BIN_SHL', + 'BIN_SHR', + 'BIN_XOR', + 'BLOCK', + 'CEIL', + 'CEILING', + 'COLLATION', + 'COMMENT', + 'COS', + 'COSH', + 'COT', + 'DATEADD', + 'DATEDIFF', + 'DECODE', + 'DIFFERENCE', + 'EXP', + 'FLOOR', + 'GEN_UUID', + 'GENERATED', + 'HASH', + 'IIF', + 'LIST', + 'LN', + 'LOG', + 'LOG10', + 'LPAD', + 'MATCHED', + 'MATCHING', + 'MAXVALUE', + 'MILLISECOND', + 'MINVALUE', + 'MOD', + 'NEXT', + 'OVERLAY', + 'PAD', + 'PI', + 'PLACING', + 'POWER', + 'PRESERVE', + 'RAND', + 'REPLACE', + 'RESTART', + 'RETURNING', + 'REVERSE', + 'ROUND', + 'RPAD', + 'SCALAR_ARRAY', + 'SEQUENCE', + 'SIGN', + 'SIN', + 'SINH', + 'SPACE', + 'SQRT', + 'TAN', + 'TANH', + 'TEMPORARY', + 'TRUNC', + 'WEEK', +)) + +# Thanks Jonathan Lundell +MYSQL = set(( + 'ACCESSIBLE', + 'ADD', + 'ALL', + 'ALTER', + 'ANALYZE', + 'AND', + 'AS', + 'ASC', + 'ASENSITIVE', + 'BEFORE', + 'BETWEEN', + 'BIGINT', + 'BINARY', + 'BLOB', + 'BOTH', + 'BY', + 'CALL', + 'CASCADE', + 'CASE', + 'CHANGE', + 'CHAR', + 'CHARACTER', + 'CHECK', + 'COLLATE', + 'COLUMN', + 'CONDITION', + 'CONSTRAINT', + 'CONTINUE', + 'CONVERT', + 'CREATE', + 'CROSS', + 'CURRENT_DATE', + 'CURRENT_TIME', + 'CURRENT_TIMESTAMP', + 'CURRENT_USER', + 'CURSOR', + 'DATABASE', + 'DATABASES', + 'DAY_HOUR', + 'DAY_MICROSECOND', + 'DAY_MINUTE', + 'DAY_SECOND', + 'DEC', + 'DECIMAL', + 'DECLARE', + 'DEFAULT', + 'DELAYED', + 'DELETE', + 'DESC', + 'DESCRIBE', + 'DETERMINISTIC', + 'DISTINCT', + 'DISTINCTROW', + 'DIV', + 'DOUBLE', + 'DROP', + 'DUAL', + 'EACH', + 'ELSE', + 'ELSEIF', + 'ENCLOSED', + 'ESCAPED', + 'EXISTS', + 'EXIT', + 'EXPLAIN', + 'FALSE', + 'FETCH', + 'FLOAT', + 'FLOAT4', + 'FLOAT8', + 'FOR', + 'FORCE', + 'FOREIGN', + 'FROM', + 'FULLTEXT', + 'GRANT', + 'GROUP', + 'HAVING', + 'HIGH_PRIORITY', + 'HOUR_MICROSECOND', + 'HOUR_MINUTE', + 'HOUR_SECOND', + 'IF', + 'IGNORE', + 'IGNORE_SERVER_IDS', + 'IGNORE_SERVER_IDS', + 'IN', + 'INDEX', + 'INFILE', + 'INNER', + 'INOUT', + 'INSENSITIVE', + 'INSERT', + 'INT', + 'INT1', + 'INT2', + 'INT3', + 'INT4', + 'INT8', + 'INTEGER', + 'INTERVAL', + 'INTO', + 'IS', + 'ITERATE', + 'JOIN', + 'KEY', + 'KEYS', + 'KILL', + 'LEADING', + 'LEAVE', + 'LEFT', + 'LIKE', + 'LIMIT', + 'LINEAR', + 'LINES', + 'LOAD', + 'LOCALTIME', + 'LOCALTIMESTAMP', + 'LOCK', + 'LONG', + 'LONGBLOB', + 'LONGTEXT', + 'LOOP', + 'LOW_PRIORITY', + 'MASTER_HEARTBEAT_PERIOD', + 'MASTER_HEARTBEAT_PERIOD', + 'MASTER_SSL_VERIFY_SERVER_CERT', + 'MATCH', + 'MAXVALUE', + 'MAXVALUE', + 'MEDIUMBLOB', + 'MEDIUMINT', + 'MEDIUMTEXT', + 'MIDDLEINT', + 'MINUTE_MICROSECOND', + 'MINUTE_SECOND', + 'MOD', + 'MODIFIES', + 'NATURAL', + 'NO_WRITE_TO_BINLOG', + 'NOT', + 'NULL', + 'NUMERIC', + 'ON', + 'OPTIMIZE', + 'OPTION', + 'OPTIONALLY', + 'OR', + 'ORDER', + 'OUT', + 'OUTER', + 'OUTFILE', + 'PRECISION', + 'PRIMARY', + 'PROCEDURE', + 'PURGE', + 'RANGE', + 'READ', + 'READ_WRITE', + 'READS', + 'REAL', + 'REFERENCES', + 'REGEXP', + 'RELEASE', + 'RENAME', + 'REPEAT', + 'REPLACE', + 'REQUIRE', + 'RESIGNAL', + 'RESIGNAL', + 'RESTRICT', + 'RETURN', + 'REVOKE', + 'RIGHT', + 'RLIKE', + 'SCHEMA', + 'SCHEMAS', + 'SECOND_MICROSECOND', + 'SELECT', + 'SENSITIVE', + 'SEPARATOR', + 'SET', + 'SHOW', + 'SIGNAL', + 'SIGNAL', + 'SMALLINT', + 'SPATIAL', + 'SPECIFIC', + 'SQL', + 'SQL_BIG_RESULT', + 'SQL_CALC_FOUND_ROWS', + 'SQL_SMALL_RESULT', + 'SQLEXCEPTION', + 'SQLSTATE', + 'SQLWARNING', + 'SSL', + 'STARTING', + 'STRAIGHT_JOIN', + 'TABLE', + 'TERMINATED', + 'THEN', + 'TINYBLOB', + 'TINYINT', + 'TINYTEXT', + 'TO', + 'TRAILING', + 'TRIGGER', + 'TRUE', + 'UNDO', + 'UNION', + 'UNIQUE', + 'UNLOCK', + 'UNSIGNED', + 'UPDATE', + 'USAGE', + 'USE', + 'USING', + 'UTC_DATE', + 'UTC_TIME', + 'UTC_TIMESTAMP', + 'VALUES', + 'VARBINARY', + 'VARCHAR', + 'VARCHARACTER', + 'VARYING', + 'WHEN', + 'WHERE', + 'WHILE', + 'WITH', + 'WRITE', + 'XOR', + 'YEAR_MONTH', + 'ZEROFILL', +)) + +MSSQL = set(( + 'ADD', + 'ALL', + 'ALTER', + 'AND', + 'ANY', + 'AS', + 'ASC', + 'AUTHORIZATION', + 'BACKUP', + 'BEGIN', + 'BETWEEN', + 'BREAK', + 'BROWSE', + 'BULK', + 'BY', + 'CASCADE', + 'CASE', + 'CHECK', + 'CHECKPOINT', + 'CLOSE', + 'CLUSTERED', + 'COALESCE', + 'COLLATE', + 'COLUMN', + 'COMMIT', + 'COMPUTE', + 'CONSTRAINT', + 'CONTAINS', + 'CONTAINSTABLE', + 'CONTINUE', + 'CONVERT', + 'CREATE', + 'CROSS', + 'CURRENT', + 'CURRENT_DATE', + 'CURRENT_TIME', + 'CURRENT_TIMESTAMP', + 'CURRENT_USER', + 'CURSOR', + 'DATABASE', + 'DBCC', + 'DEALLOCATE', + 'DECLARE', + 'DEFAULT', + 'DELETE', + 'DENY', + 'DESC', + 'DISK', + 'DISTINCT', + 'DISTRIBUTED', + 'DOUBLE', + 'DROP', + 'DUMMY', + 'DUMP', + 'ELSE', + 'END', + 'ERRLVL', + 'ESCAPE', + 'EXCEPT', + 'EXEC', + 'EXECUTE', + 'EXISTS', + 'EXIT', + 'FETCH', + 'FILE', + 'FILLFACTOR', + 'FOR', + 'FOREIGN', + 'FREETEXT', + 'FREETEXTTABLE', + 'FROM', + 'FULL', + 'FUNCTION', + 'GOTO', + 'GRANT', + 'GROUP', + 'HAVING', + 'HOLDLOCK', + 'IDENTITY', + 'IDENTITY_INSERT', + 'IDENTITYCOL', + 'IF', + 'IN', + 'INDEX', + 'INNER', + 'INSERT', + 'INTERSECT', + 'INTO', + 'IS', + 'JOIN', + 'KEY', + 'KILL', + 'LEFT', + 'LIKE', + 'LINENO', + 'LOAD', + 'NATIONAL ', + 'NOCHECK', + 'NONCLUSTERED', + 'NOT', + 'NULL', + 'NULLIF', + 'OF', + 'OFF', + 'OFFSETS', + 'ON', + 'OPEN', + 'OPENDATASOURCE', + 'OPENQUERY', + 'OPENROWSET', + 'OPENXML', + 'OPTION', + 'OR', + 'ORDER', + 'OUTER', + 'OVER', + 'PERCENT', + 'PLAN', + 'PRECISION', + 'PRIMARY', + 'PRINT', + 'PROC', + 'PROCEDURE', + 'PUBLIC', + 'RAISERROR', + 'READ', + 'READTEXT', + 'RECONFIGURE', + 'REFERENCES', + 'REPLICATION', + 'RESTORE', + 'RESTRICT', + 'RETURN', + 'REVOKE', + 'RIGHT', + 'ROLLBACK', + 'ROWCOUNT', + 'ROWGUIDCOL', + 'RULE', + 'SAVE', + 'SCHEMA', + 'SELECT', + 'SESSION_USER', + 'SET', + 'SETUSER', + 'SHUTDOWN', + 'SOME', + 'STATISTICS', + 'SYSTEM_USER', + 'TABLE', + 'TEXTSIZE', + 'THEN', + 'TO', + 'TOP', + 'TRAN', + 'TRANSACTION', + 'TRIGGER', + 'TRUNCATE', + 'TSEQUAL', + 'UNION', + 'UNIQUE', + 'UPDATE', + 'UPDATETEXT', + 'USE', + 'USER', + 'VALUES', + 'VARYING', + 'VIEW', + 'WAITFOR', + 'WHEN', + 'WHERE', + 'WHILE', + 'WITH', + 'WRITETEXT', +)) + +ORACLE = set(( + 'ACCESS', + 'ADD', + 'ALL', + 'ALTER', + 'AND', + 'ANY', + 'AS', + 'ASC', + 'AUDIT', + 'BETWEEN', + 'BY', + 'CHAR', + 'CHECK', + 'CLUSTER', + 'COLUMN', + 'COMMENT', + 'COMPRESS', + 'CONNECT', + 'CREATE', + 'CURRENT', + 'DATE', + 'DECIMAL', + 'DEFAULT', + 'DELETE', + 'DESC', + 'DISTINCT', + 'DROP', + 'ELSE', + 'EXCLUSIVE', + 'EXISTS', + 'FILE', + 'FLOAT', + 'FOR', + 'FROM', + 'GRANT', + 'GROUP', + 'HAVING', + 'IDENTIFIED', + 'IMMEDIATE', + 'IN', + 'INCREMENT', + 'INDEX', + 'INITIAL', + 'INSERT', + 'INTEGER', + 'INTERSECT', + 'INTO', + 'IS', + 'LEVEL', + 'LIKE', + 'LOCK', + 'LONG', + 'MAXEXTENTS', + 'MINUS', + 'MLSLABEL', + 'MODE', + 'MODIFY', + 'NOAUDIT', + 'NOCOMPRESS', + 'NOT', + 'NOWAIT', + 'NULL', + 'NUMBER', + 'OF', + 'OFFLINE', + 'ON', + 'ONLINE', + 'OPTION', + 'OR', + 'ORDER', + 'PCTFREE', + 'PRIOR', + 'PRIVILEGES', + 'PUBLIC', + 'RAW', + 'RENAME', + 'RESOURCE', + 'REVOKE', + 'ROW', + 'ROWID', + 'ROWNUM', + 'ROWS', + 'SELECT', + 'SESSION', + 'SET', + 'SHARE', + 'SIZE', + 'SMALLINT', + 'START', + 'SUCCESSFUL', + 'SYNONYM', + 'SYSDATE', + 'TABLE', + 'THEN', + 'TO', + 'TRIGGER', + 'UID', + 'UNION', + 'UNIQUE', + 'UPDATE', + 'USER', + 'VALIDATE', + 'VALUES', + 'VARCHAR', + 'VARCHAR2', + 'VIEW', + 'WHENEVER', + 'WHERE', + 'WITH', +)) + +SQLITE = set(( + 'ABORT', + 'ACTION', + 'ADD', + 'AFTER', + 'ALL', + 'ALTER', + 'ANALYZE', + 'AND', + 'AS', + 'ASC', + 'ATTACH', + 'AUTOINCREMENT', + 'BEFORE', + 'BEGIN', + 'BETWEEN', + 'BY', + 'CASCADE', + 'CASE', + 'CAST', + 'CHECK', + 'COLLATE', + 'COLUMN', + 'COMMIT', + 'CONFLICT', + 'CONSTRAINT', + 'CREATE', + 'CROSS', + 'CURRENT_DATE', + 'CURRENT_TIME', + 'CURRENT_TIMESTAMP', + 'DATABASE', + 'DEFAULT', + 'DEFERRABLE', + 'DEFERRED', + 'DELETE', + 'DESC', + 'DETACH', + 'DISTINCT', + 'DROP', + 'EACH', + 'ELSE', + 'END', + 'ESCAPE', + 'EXCEPT', + 'EXCLUSIVE', + 'EXISTS', + 'EXPLAIN', + 'FAIL', + 'FOR', + 'FOREIGN', + 'FROM', + 'FULL', + 'GLOB', + 'GROUP', + 'HAVING', + 'IF', + 'IGNORE', + 'IMMEDIATE', + 'IN', + 'INDEX', + 'INDEXED', + 'INITIALLY', + 'INNER', + 'INSERT', + 'INSTEAD', + 'INTERSECT', + 'INTO', + 'IS', + 'ISNULL', + 'JOIN', + 'KEY', + 'LEFT', + 'LIKE', + 'LIMIT', + 'MATCH', + 'NATURAL', + 'NO', + 'NOT', + 'NOTNULL', + 'NULL', + 'OF', + 'OFFSET', + 'ON', + 'OR', + 'ORDER', + 'OUTER', + 'PLAN', + 'PRAGMA', + 'PRIMARY', + 'QUERY', + 'RAISE', + 'REFERENCES', + 'REGEXP', + 'REINDEX', + 'RELEASE', + 'RENAME', + 'REPLACE', + 'RESTRICT', + 'RIGHT', + 'ROLLBACK', + 'ROW', + 'SAVEPOINT', + 'SELECT', + 'SET', + 'TABLE', + 'TEMP', + 'TEMPORARY', + 'THEN', + 'TO', + 'TRANSACTION', + 'TRIGGER', + 'UNION', + 'UNIQUE', + 'UPDATE', + 'USING', + 'VACUUM', + 'VALUES', + 'VIEW', + 'VIRTUAL', + 'WHEN', + 'WHERE', +)) + + +MONGODB_NONRESERVED = set(('SAFE',)) + +# remove from here when you add a list. +JDBCSQLITE = SQLITE +DB2 = INFORMIX = INGRES = JDBCPOSTGRESQL = COMMON + +ADAPTERS = { + 'sqlite': SQLITE, + 'mysql': MYSQL, + 'postgres': POSTGRESQL, + 'postgres_nonreserved': POSTGRESQL_NONRESERVED, + 'oracle': ORACLE, + 'mssql': MSSQL, + 'mssql2': MSSQL, + 'db2': DB2, + 'informix': INFORMIX, + 'firebird': FIREBIRD, + 'firebird_embedded': FIREBIRD, + 'firebird_nonreserved': FIREBIRD_NONRESERVED, + 'ingres': INGRES, + 'ingresu': INGRES, + 'jdbc:sqlite': JDBCSQLITE, + 'jdbc:postgres': JDBCPOSTGRESQL, + 'common': COMMON, + 'mongodb_nonreserved': MONGODB_NONRESERVED +} + +ADAPTERS['all'] = reduce(lambda a, b: a.union(b), ( + x for x in ADAPTERS.values())) diff --git a/web2py/gluon/packages/dal/pydal/dialects/__init__.py b/web2py/gluon/packages/dal/pydal/dialects/__init__.py new file mode 100644 index 0000000..9ed4a65 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/__init__.py @@ -0,0 +1,115 @@ +from .._compat import with_metaclass, iteritems +from .._gae import gae +from .._load import OrderedDict +from ..helpers._internals import Dispatcher +from ..objects import Expression + + +dialects = Dispatcher("dialect") + + +class sqltype_for(object): + _inst_count_ = 0 + + def __init__(self, key): + self.key = key + self._inst_count_ = sqltype_for._inst_count_ + sqltype_for._inst_count_ += 1 + + def __call__(self, f): + self.f = f + return self + + +class register_expression(object): + _inst_count_ = 0 + + def __init__(self, name): + self.name = name + self._inst_count_ = register_expression._inst_count_ + register_expression._inst_count_ += 1 + + def __call__(self, f): + self.f = f + return self + + +class ExpressionMethodWrapper(object): + def __init__(self, dialect, obj): + self.dialect = dialect + self.obj = obj + + def __call__(self, expression, *args, **kwargs): + return self.obj.f(self.dialect, expression, *args, **kwargs) + + +class MetaDialect(type): + def __new__(cls, name, bases, attrs): + new_class = type.__new__(cls, name, bases, attrs) + if bases == (object,): + return new_class + #: collect declared attributes + sqltypes = [] + expressions = [] + for key, value in list(attrs.items()): + if isinstance(value, sqltype_for): + sqltypes.append((key, value)) + if isinstance(value, register_expression): + expressions.append((key, value)) + sqltypes.sort(key=lambda x: x[1]._inst_count_) + expressions.sort(key=lambda x: x[1]._inst_count_) + declared_sqltypes = OrderedDict() + declared_expressions = OrderedDict() + for key, val in sqltypes: + declared_sqltypes[key] = val + new_class._declared_sqltypes_ = declared_sqltypes + for key, val in expressions: + declared_expressions[key] = val + new_class._declared_expressions_ = declared_expressions + #: get super declared attributes + all_sqltypes = OrderedDict() + all_expressions = OrderedDict() + for base in reversed(new_class.__mro__[1:]): + if hasattr(base, '_declared_sqltypes_'): + all_sqltypes.update(base._declared_sqltypes_) + if hasattr(base, '_declared_expressions_'): + all_expressions.update(base._declared_expressions_) + #: set re-constructed attributes + all_sqltypes.update(declared_sqltypes) + all_expressions.update(declared_expressions) + new_class._all_sqltypes_ = all_sqltypes + new_class._all_expressions_ = all_expressions + return new_class + + +class Dialect(with_metaclass(MetaDialect)): + def __init__(self, adapter): + self.adapter = adapter + self.types = {} + for name, obj in iteritems(self._all_sqltypes_): + self.types[obj.key] = obj.f(self) + for name, obj in iteritems(self._all_expressions_): + Expression._dialect_expressions_[obj.name] = \ + ExpressionMethodWrapper(self, obj) + + def expand(self, *args, **kwargs): + return self.adapter.expand(*args, **kwargs) + + +from .base import SQLDialect +from .sqlite import SQLiteDialect, SpatialiteDialect +from .postgre import PostgreDialect +from .mysql import MySQLDialect +from .mssql import MSSQLDialect +from .mongo import MongoDialect +from .db2 import DB2Dialect +from .firebird import FireBirdDialect +from .informix import InformixDialect +from .ingres import IngresDialect +from .oracle import OracleDialect +from .sap import SAPDBDialect +from .teradata import TeradataDialect +from .couchdb import CouchDBDialect + +if gae is not None: + from .google import GoogleDatastoreDialect diff --git a/web2py/gluon/packages/dal/pydal/dialects/base.py b/web2py/gluon/packages/dal/pydal/dialects/base.py new file mode 100644 index 0000000..e8d36df --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/base.py @@ -0,0 +1,582 @@ +import datetime +from .._compat import integer_types, basestring +from ..adapters.base import SQLAdapter +from ..helpers.methods import use_common_filters +from ..objects import Expression, Field, Table, Select +from . import Dialect, dialects, sqltype_for + +long = integer_types[-1] + + +class CommonDialect(Dialect): + quote_template = '%s' + + def _force_bigints(self): + if 'big-id' in self.types and 'reference' in self.types: + self.types['id'] = self.types['big-id'] + self.types['reference'] = self.types['big-reference'] + + def quote(self, val): + return self.quote_template % val + + def varquote(self, val): + return val + + def sequence_name(self, tablename): + return self.quote('%s_sequence' % tablename) + + def trigger_name(self, tablename): + return '%s_sequence' % tablename + + def coalesce_zero(self, val, query_env={}): + return self.coalesce(val, [0], query_env) + + +@dialects.register_for(SQLAdapter) +class SQLDialect(CommonDialect): + quote_template = '"%s"' + true = "T" + false = "F" + true_exp = "1" + false_exp = "0" + dt_sep = " " + + @sqltype_for('string') + def type_string(self): + return 'VARCHAR(%(length)s)' + + @sqltype_for('boolean') + def type_boolean(self): + return 'CHAR(1)' + + @sqltype_for('text') + def type_text(self): + return 'TEXT' + + @sqltype_for('json') + def type_json(self): + return self.types['text'] + + @sqltype_for('password') + def type_password(self): + return self.types['string'] + + @sqltype_for('blob') + def type_blob(self): + return 'BLOB' + + @sqltype_for('upload') + def type_upload(self): + return self.types['string'] + + @sqltype_for('integer') + def type_integer(self): + return 'INTEGER' + + @sqltype_for('bigint') + def type_bigint(self): + return self.types['integer'] + + @sqltype_for('float') + def type_float(self): + return 'FLOAT' + + @sqltype_for('double') + def type_double(self): + return 'DOUBLE' + + @sqltype_for('decimal') + def type_decimal(self): + return 'NUMERIC(%(precision)s,%(scale)s)' + + @sqltype_for('date') + def type_date(self): + return 'DATE' + + @sqltype_for('time') + def type_time(self): + return 'TIME' + + @sqltype_for('datetime') + def type_datetime(self): + return 'TIMESTAMP' + + @sqltype_for('id') + def type_id(self): + return 'INTEGER PRIMARY KEY AUTOINCREMENT' + + @sqltype_for('reference') + def type_reference(self): + return 'INTEGER REFERENCES %(foreign_key)s ' + \ + 'ON DELETE %(on_delete_action)s %(null)s %(unique)s' + + @sqltype_for('list:integer') + def type_list_integer(self): + return self.types['text'] + + @sqltype_for('list:string') + def type_list_string(self): + return self.types['text'] + + @sqltype_for('list:reference') + def type_list_reference(self): + return self.types['text'] + + @sqltype_for('big-id') + def type_big_id(self): + return self.types['id'] + + @sqltype_for('big-reference') + def type_big_reference(self): + return self.types['reference'] + + @sqltype_for('reference FK') + def type_reference_fk(self): + return ', CONSTRAINT "FK_%(constraint_name)s" FOREIGN KEY ' + \ + '(%(field_name)s) REFERENCES %(foreign_key)s ' + \ + 'ON DELETE %(on_delete_action)s' + + def alias(self, original, new): + return ('%s AS ' + self.quote_template) % (original, new) + + def insert(self, table, fields, values): + return 'INSERT INTO %s(%s) VALUES (%s);' % (table, fields, values) + + def insert_empty(self, table): + return 'INSERT INTO %s DEFAULT VALUES;' % table + + def where(self, query): + return 'WHERE %s' % query + + def update(self, table, values, where=None): + tablename = self.writing_alias(table) + whr = '' + if where: + whr = ' %s' % self.where(where) + return 'UPDATE %s SET %s%s;' % (tablename, values, whr) + + def delete(self, table, where=None): + tablename = self.writing_alias(table) + whr = '' + if where: + whr = ' %s' % self.where(where) + return 'DELETE FROM %s%s;' % (tablename, whr) + + def select(self, fields, tables, where=None, groupby=None, having=None, + orderby=None, limitby=None, distinct=False, for_update=False): + dst, whr, grp, order, limit, offset, upd = '', '', '', '', '', '', '' + if distinct is True: + dst = ' DISTINCT' + elif distinct: + dst = ' DISTINCT ON (%s)' % distinct + if where: + whr = ' %s' % self.where(where) + if groupby: + grp = ' GROUP BY %s' % groupby + if having: + grp += ' HAVING %s' % having + if orderby: + order = ' ORDER BY %s' % orderby + if limitby: + (lmin, lmax) = limitby + limit = ' LIMIT %i' % (lmax - lmin) + offset = ' OFFSET %i' % lmin + if for_update: + upd = ' FOR UPDATE' + return 'SELECT%s %s FROM %s%s%s%s%s%s%s;' % ( + dst, fields, tables, whr, grp, order, limit, offset, upd) + + def count(self, val, distinct=None, query_env={}): + return ('COUNT(%s)' if not distinct else 'COUNT(DISTINCT %s)') % \ + self.expand(val, query_env=query_env) + + def join(self, val, query_env={}): + if isinstance(val, (Table, Select)): + val = val.query_name(query_env.get('parent_scope', [])) + elif not isinstance(val, basestring): + val = self.expand(val, query_env=query_env) + return 'JOIN %s' % val + + def left_join(self, val, query_env={}): + # Left join must always have an ON clause + if not isinstance(val, basestring): + val = self.expand(val, query_env=query_env) + return 'LEFT JOIN %s' % val + + def cross_join(self, val, query_env={}): + if isinstance(val, (Table, Select)): + val = val.query_name(query_env.get('parent_scope', [])) + elif not isinstance(val, basestring): + val = self.expand(val, query_env=query_env) + return 'CROSS JOIN %s' % val + + @property + def random(self): + return 'Random()' + + def _as(self, first, second, query_env={}): + return '%s AS %s' % (self.expand(first, query_env=query_env), second) + + def cast(self, first, second, query_env={}): + return 'CAST(%s)' % self._as(first, second, query_env) + + def _not(self, val, query_env={}): + return '(NOT %s)' % self.expand(val, query_env=query_env) + + def _and(self, first, second, query_env={}): + return '(%s AND %s)' % (self.expand(first, query_env=query_env), + self.expand(second, query_env=query_env)) + + def _or(self, first, second, query_env={}): + return '(%s OR %s)' % (self.expand(first, query_env=query_env), + self.expand(second, query_env=query_env)) + + def belongs(self, first, second, query_env={}): + ftype = first.type + first = self.expand(first, query_env=query_env) + if isinstance(second, str): + return '(%s IN (%s))' % (first, second[:-1]) + elif isinstance(second, Select): + if len(second._qfields) != 1: + raise ValueError( + 'Subquery in belongs() must select exactly 1 column') + sub = second._compile(query_env.get('current_scope', []))[1][:-1] + return '(%s IN (%s))' % (first, sub) + if not second: + return '(1=0)' + items = ','.join(self.expand(item, ftype, query_env=query_env) + for item in second) + return '(%s IN (%s))' % (first, items) + + # def regexp(self, first, second): + # raise NotImplementedError + + def lower(self, val, query_env={}): + return 'LOWER(%s)' % self.expand(val, query_env=query_env) + + def upper(self, first, query_env={}): + return 'UPPER(%s)' % self.expand(first, query_env=query_env) + + def like(self, first, second, escape=None, query_env={}): + """Case sensitive like operator""" + if isinstance(second, Expression): + second = self.expand(second, 'string', query_env=query_env) + else: + second = self.expand(second, 'string', query_env=query_env) + if escape is None: + escape = '\\' + second = second.replace(escape, escape * 2) + return "(%s LIKE %s ESCAPE '%s')" % ( + self.expand(first, query_env=query_env), second, escape) + + def ilike(self, first, second, escape=None, query_env={}): + """Case insensitive like operator""" + if isinstance(second, Expression): + second = self.expand(second, 'string', query_env=query_env) + else: + second = self.expand(second, 'string', query_env=query_env).lower() + if escape is None: + escape = '\\' + second = second.replace(escape, escape*2) + return "(%s LIKE %s ESCAPE '%s')" % ( + self.lower(first, query_env=query_env), second, escape) + + def _like_escaper_default(self, term): + if isinstance(term, Expression): + return term + term = term.replace('\\', '\\\\') + term = term.replace('%', '\%').replace('_', '\_') + return term + + def startswith(self, first, second, query_env={}): + return "(%s LIKE %s ESCAPE '\\')" % ( + self.expand(first, query_env=query_env), + self.expand(self._like_escaper_default(second)+'%', 'string', + query_env=query_env)) + + def endswith(self, first, second, query_env={}): + return "(%s LIKE %s ESCAPE '\\')" % ( + self.expand(first, query_env=query_env), + self.expand('%'+self._like_escaper_default(second), 'string', + query_env=query_env)) + + def replace(self, first, tup, query_env={}): + second, third = tup + return 'REPLACE(%s,%s,%s)' % ( + self.expand(first, 'string', query_env=query_env), + self.expand(second, 'string', query_env=query_env), + self.expand(third, 'string', query_env=query_env)) + + def concat(self, *items, **kwargs): + query_env = kwargs.get('query_env', {}) + tmp = (self.expand(x, 'string', query_env=query_env) for x in items) + return '(%s)' % ' || '.join(tmp) + + def contains(self, first, second, case_sensitive=True, query_env={}): + if first.type in ('string', 'text', 'json'): + if isinstance(second, Expression): + second = Expression( + second.db, + self.concat('%', Expression( + second.db, self.replace(second, ('%', '\%'), + query_env=query_env)), '%')) + else: + second = '%'+self._like_escaper_default(str(second))+'%' + elif first.type.startswith('list:'): + if isinstance(second, Expression): + second = Expression( + second.db, self.concat('%|', Expression( + second.db, self.replace(Expression( + second.db, self.replace( + second, ('%', '\%'), query_env)), + ('|', '||'))), '|%')) + else: + second = str(second).replace('|', '||') + second = '%|'+self._like_escaper_default(second)+'|%' + op = case_sensitive and self.like or self.ilike + return op(first, second, escape='\\', query_env=query_env) + + def eq(self, first, second=None, query_env={}): + if second is None: + return '(%s IS NULL)' % self.expand(first, query_env=query_env) + return '(%s = %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def ne(self, first, second=None, query_env={}): + if second is None: + return '(%s IS NOT NULL)' % self.expand(first, query_env=query_env) + return '(%s <> %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def lt(self, first, second=None, query_env={}): + if second is None: + raise RuntimeError("Cannot compare %s < None" % first) + return '(%s < %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def lte(self, first, second=None, query_env={}): + if second is None: + raise RuntimeError("Cannot compare %s <= None" % first) + return '(%s <= %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def gt(self, first, second=None, query_env={}): + if second is None: + raise RuntimeError("Cannot compare %s > None" % first) + return '(%s > %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def gte(self, first, second=None, query_env={}): + if second is None: + raise RuntimeError("Cannot compare %s >= None" % first) + return '(%s >= %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def _is_numerical(self, field_type): + return field_type in \ + ('integer', 'float', 'double', 'bigint', 'boolean') or \ + field_type.startswith('decimal') + + def add(self, first, second, query_env={}): + if self._is_numerical(first.type) or isinstance(first.type, Field): + return '(%s + %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + else: + return self.concat(first, second, query_env=query_env) + + def sub(self, first, second, query_env={}): + return '(%s - %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def mul(self, first, second, query_env={}): + return '(%s * %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def div(self, first, second, query_env={}): + return '(%s / %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def mod(self, first, second, query_env={}): + return '(%s %% %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def on(self, first, second, query_env={}): + table_rname = first.query_name(query_env.get('parent_scope', []))[0] + if use_common_filters(second): + second = self.adapter.common_filter(second, [first]) + return ('%s ON %s') % (table_rname, + self.expand(second, query_env=query_env)) + + def invert(self, first, query_env={}): + return '%s DESC' % self.expand(first, query_env=query_env) + + def comma(self, first, second, query_env={}): + return '%s, %s' % (self.expand(first, query_env=query_env), + self.expand(second, query_env=query_env)) + + def extract(self, first, what, query_env={}): + return "EXTRACT(%s FROM %s)" % (what, + self.expand(first, query_env=query_env)) + + def epoch(self, val, query_env={}): + return self.extract(val, 'epoch', query_env) + + def length(self, val, query_env={}): + return "LENGTH(%s)" % self.expand(val, query_env=query_env) + + def aggregate(self, first, what, query_env={}): + return "%s(%s)" % (what, self.expand(first, query_env=query_env)) + + def not_null(self, default, field_type): + return 'NOT NULL DEFAULT %s' % \ + self.adapter.represent(default, field_type) + + @property + def allow_null(self): + return '' + + def coalesce(self, first, second, query_env={}): + expressions = [self.expand(first, query_env=query_env)] + \ + [self.expand(val, first.type, query_env=query_env) + for val in second] + return 'COALESCE(%s)' % ','.join(expressions) + + def raw(self, val, query_env={}): + return val + + def substring(self, field, parameters, query_env={}): + return 'SUBSTR(%s,%s,%s)' % ( + self.expand(field, query_env=query_env), parameters[0], + parameters[1]) + + def case(self, query, true_false, query_env={}): + _types = {bool: 'boolean', int: 'integer', float: 'double'} + return 'CASE WHEN %s THEN %s ELSE %s END' % ( + self.expand(query, query_env=query_env), + self.adapter.represent( + true_false[0], _types.get(type(true_false[0]), 'string')), + self.adapter.represent( + true_false[1], _types.get(type(true_false[1]), 'string'))) + + def primary_key(self, key): + return 'PRIMARY KEY(%s)' % key + + def drop_table(self, table, mode): + return ['DROP TABLE %s;' % table._rname] + + def truncate(self, table, mode=''): + if mode: + mode = " %s" % mode + return ['TRUNCATE TABLE %s%s;' % (table._rname, mode)] + + def create_index(self, name, table, expressions, unique=False): + uniq = ' UNIQUE' if unique else '' + with self.adapter.index_expander(): + rv = 'CREATE%s INDEX %s ON %s (%s);' % ( + uniq, self.quote(name), table._rname, ','.join( + self.expand(field) for field in expressions)) + return rv + + def drop_index(self, name, table): + return 'DROP INDEX %s;' % self.quote(name) + + def constraint_name(self, table, fieldname): + return '%s_%s__constraint' % (table, fieldname) + + def concat_add(self, tablename): + return ', ADD ' + + def writing_alias(self, table): + return table.sql_fullref + + +class NoSQLDialect(CommonDialect): + @sqltype_for('string') + def type_string(self): + return str + + @sqltype_for('boolean') + def type_boolean(self): + return bool + + @sqltype_for('text') + def type_text(self): + return str + + @sqltype_for('json') + def type_json(self): + return self.types['text'] + + @sqltype_for('password') + def type_password(self): + return self.types['string'] + + @sqltype_for('blob') + def type_blob(self): + return self.types['text'] + + @sqltype_for('upload') + def type_upload(self): + return self.types['string'] + + @sqltype_for('integer') + def type_integer(self): + return long + + @sqltype_for('bigint') + def type_bigint(self): + return self.types['integer'] + + @sqltype_for('float') + def type_float(self): + return float + + @sqltype_for('double') + def type_double(self): + return self.types['float'] + + @sqltype_for('date') + def type_date(self): + return datetime.date + + @sqltype_for('time') + def type_time(self): + return datetime.time + + @sqltype_for('datetime') + def type_datetime(self): + return datetime.datetime + + @sqltype_for('id') + def type_id(self): + return long + + @sqltype_for('reference') + def type_reference(self): + return long + + @sqltype_for('list:integer') + def type_list_integer(self): + return list + + @sqltype_for('list:string') + def type_list_string(self): + return list + + @sqltype_for('list:reference') + def type_list_reference(self): + return list + + def quote(self, val): + return val diff --git a/web2py/gluon/packages/dal/pydal/dialects/couchdb.py b/web2py/gluon/packages/dal/pydal/dialects/couchdb.py new file mode 100644 index 0000000..d453c12 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/couchdb.py @@ -0,0 +1,32 @@ +from ..adapters.couchdb import CouchDB +from .base import NoSQLDialect +from . import dialects + + +@dialects.register_for(CouchDB) +class CouchDBDialect(NoSQLDialect): + def _and(self, first, second, query_env={}): + return '(%s && %s)' % (self.expand(first, query_env=query_env), + self.expand(second, query_env=query_env)) + + def _or(self, first, second, query_env={}): + return '(%s || %s)' % (self.expand(first, query_env=query_env), + self.expand(second, query_env=query_env)) + + def eq(self, first, second=None, query_env={}): + if second is None: + return '(%s == null)' % self.expand(first, query_env=query_env) + return '(%s == %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def ne(self, first, second=None, query_env={}): + if second is None: + return '(%s != null)' % self.expand(first, query_env=query_env) + return '(%s != %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def comma(self, first, second, query_env={}): + return '%s + %s' % (self.expand(first, query_env=query_env), + self.expand(second, query_env=query_env)) diff --git a/web2py/gluon/packages/dal/pydal/dialects/db2.py b/web2py/gluon/packages/dal/pydal/dialects/db2.py new file mode 100644 index 0000000..05ba7cf --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/db2.py @@ -0,0 +1,86 @@ +from .._compat import basestring +from ..adapters.db2 import DB2 +from .base import SQLDialect +from . import dialects, sqltype_for + + +@dialects.register_for(DB2) +class DB2Dialect(SQLDialect): + @sqltype_for('text') + def type_text(self): + return 'CLOB' + + @sqltype_for('integer') + def type_integer(self): + return 'INT' + + @sqltype_for('bigint') + def type_bigint(self): + return 'BIGINT' + + @sqltype_for('float') + def type_float(self): + return 'REAL' + + @sqltype_for('id') + def type_id(self): + return 'INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY NOT NULL' + + @sqltype_for('big-id') + def type_big_id(self): + return 'BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY NOT NULL' + + @sqltype_for('reference') + def type_reference(self): + return 'INT, FOREIGN KEY (%(field_name)s) REFERENCES ' + \ + '%(foreign_key)s ON DELETE %(on_delete_action)s' + + @sqltype_for('big-reference') + def type_big_reference(self): + return 'BIGINT, FOREIGN KEY (%(field_name)s) REFERENCES ' + \ + '%(foreign_key)s ON DELETE %(on_delete_action)s' + + @sqltype_for('reference FK') + def type_reference_fk(self): + return ', CONSTRAINT FK_%(constraint_name)s FOREIGN KEY ' + \ + '(%(field_name)s) REFERENCES %(foreign_key)s ' + \ + 'ON DELETE %(on_delete_action)s' + + @sqltype_for('reference TFK') + def type_reference_tfk(self): + return ' CONSTRAINT FK_%(constraint_name)s_PK FOREIGN KEY ' + \ + '(%(field_name)s) REFERENCES %(foreign_table)s' + \ + '(%(foreign_key)s) ON DELETE %(on_delete_action)s' + + def left_join(self, val, query_env={}): + # Left join must always have an ON clause + if not isinstance(val, basestring): + val = self.expand(val, query_env=query_env) + return 'LEFT OUTER JOIN %s' % val + + @property + def random(self): + return 'RAND()' + + def select(self, fields, tables, where=None, groupby=None, having=None, + orderby=None, limitby=None, distinct=False, for_update=False): + dst, whr, grp, order, limit, offset, upd = '', '', '', '', '', '', '' + if distinct is True: + dst = ' DISTINCT' + elif distinct: + dst = ' DISTINCT ON (%s)' % distinct + if where: + whr = ' %s' % self.where(where) + if groupby: + grp = ' GROUP BY %s' % groupby + if having: + grp += ' HAVING %s' % having + if orderby: + order = ' ORDER BY %s' % orderby + if limitby: + (lmin, lmax) = limitby + limit = ' FETCH FIRST %i ROWS ONLY' % lmax + if for_update: + upd = ' FOR UPDATE' + return 'SELECT%s %s FROM %s%s%s%s%s%s%s;' % ( + dst, fields, tables, whr, grp, order, limit, offset, upd) diff --git a/web2py/gluon/packages/dal/pydal/dialects/firebird.py b/web2py/gluon/packages/dal/pydal/dialects/firebird.py new file mode 100644 index 0000000..2cacd2c --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/firebird.py @@ -0,0 +1,114 @@ +from ..adapters.firebird import FireBird +from ..objects import Expression +from .base import SQLDialect +from . import dialects, sqltype_for + + +@dialects.register_for(FireBird) +class FireBirdDialect(SQLDialect): + @sqltype_for('text') + def type_text(self): + return 'BLOB SUB_TYPE 1' + + @sqltype_for('bigint') + def type_bigint(self): + return 'BIGINT' + + @sqltype_for('double') + def type_double(self): + return 'DOUBLE PRECISION' + + @sqltype_for('decimal') + def type_decimal(self): + return 'DECIMAL(%(precision)s,%(scale)s)' + + @sqltype_for('blob') + def type_blob(self): + return 'BLOB SUB_TYPE 0' + + @sqltype_for('id') + def type_id(self): + return 'INTEGER PRIMARY KEY' + + @sqltype_for('big-id') + def type_big_id(self): + return 'BIGINT PRIMARY KEY' + + @sqltype_for('reference') + def type_reference(self): + return 'INTEGER REFERENCES %(foreign_key)s ' + \ + 'ON DELETE %(on_delete_action)s' + + @sqltype_for('big-reference') + def type_big_reference(self): + return 'BIGINT REFERENCES %(foreign_key)s ' + \ + 'ON DELETE %(on_delete_action)s' + + def sequence_name(self, tablename): + return self.quote('genid_%s' % tablename) + + def trigger_name(self, tablename): + return 'trg_id_%s' % tablename + + @property + def random(self): + return 'RAND()' + + def not_null(self, default, field_type): + return 'DEFAULT %s NOT NULL' % \ + self.adapter.represent(default, field_type) + + def epoch(self, val, query_env={}): + return "DATEDIFF(second, '1970-01-01 00:00:00', %s)" % \ + self.expand(val, query_env=query_env) + + def substring(self, field, parameters, query_env={}): + return 'SUBSTRING(%s from %s for %s)' % ( + self.expand(field, query_env=query_env), parameters[0], + parameters[1]) + + def length(self, val, query_env={}): + return "CHAR_LENGTH(%s)" % self.expand(val, query_env=query_env) + + def contains(self, first, second, case_sensitive=True, query_env={}): + if first.type.startswith('list:'): + second = Expression(None, self.concat('|', Expression( + None, self.replace(second, ('|', '||'), query_env)), '|')) + return '(%s CONTAINING %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, 'string', query_env=query_env)) + + def select(self, fields, tables, where=None, groupby=None, having=None, + orderby=None, limitby=None, distinct=False, for_update=False): + dst, whr, grp, order, limit, offset, upd = '', '', '', '', '', '', '' + if distinct is True: + dst = ' DISTINCT' + elif distinct: + dst = ' DISTINCT ON (%s)' % distinct + if where: + whr = ' %s' % self.where(where) + if groupby: + grp = ' GROUP BY %s' % groupby + if having: + grp += ' HAVING %s' % having + if orderby: + order = ' ORDER BY %s' % orderby + if limitby: + (lmin, lmax) = limitby + limit = ' FIRST %i' % (lmax - lmin) + offset = ' SKIP %i' % lmin + if for_update: + upd = ' FOR UPDATE' + return 'SELECT%s%s%s %s FROM %s%s%s%s%s;' % ( + dst, limit, offset, fields, tables, whr, grp, order, upd) + + def drop_table(self, table, mode): + sequence_name = table._sequence_name + return [ + 'DROP TABLE %s %s;' % (table._rname, mode), + 'DROP GENERATOR %s;' % sequence_name] + + def truncate(self, table, mode=''): + return [ + 'DELETE FROM %s;' % table._rname, + 'SET GENERATOR %s TO 0;' % table._sequence_name] diff --git a/web2py/gluon/packages/dal/pydal/dialects/google.py b/web2py/gluon/packages/dal/pydal/dialects/google.py new file mode 100644 index 0000000..66b320d --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/google.py @@ -0,0 +1,190 @@ +from .._gae import ndb +from ..adapters.google import GoogleDatastore +from ..helpers.gae import NDBDecimalProperty +from .base import NoSQLDialect +from . import dialects, sqltype_for + + +@dialects.register_for(GoogleDatastore) +class GoogleDatastoreDialect(NoSQLDialect): + FILTER_OPTIONS = { + '=': lambda a, b: a == b, + '>': lambda a, b: a > b, + '<': lambda a, b: a < b, + '<=': lambda a, b: a <= b, + '>=': lambda a, b: a >= b, + '!=': lambda a, b: a != b, + 'in': lambda a, b: a.IN(b) + } + + @sqltype_for('string') + def type_string(self): + return (lambda **kwargs: ndb.StringProperty(**kwargs)) + + @sqltype_for('boolean') + def type_boolean(self): + return ndb.BooleanProperty + + @sqltype_for('text') + def type_text(self): + return ndb.TextProperty + + @sqltype_for('json') + def type_json(self): + return self.types['text'] + + @sqltype_for('password') + def type_password(self): + return ndb.StringProperty + + @sqltype_for('blob') + def type_blob(self): + return ndb.BlobProperty + + @sqltype_for('upload') + def type_upload(self): + return self.types['password'] + + @sqltype_for('integer') + def type_integer(self): + return ndb.IntegerProperty + + @sqltype_for('bigint') + def type_bigint(self): + return self.types['integer'] + + @sqltype_for('float') + def type_float(self): + return ndb.FloatProperty + + @sqltype_for('double') + def type_double(self): + return self.types['float'] + + @sqltype_for('decimal') + def type_decimal(self): + return NDBDecimalProperty + + @sqltype_for('date') + def type_date(self): + return ndb.DateProperty + + @sqltype_for('time') + def type_time(self): + return ndb.TimeProperty + + @sqltype_for('datetime') + def type_datetime(self): + return ndb.DateTimeProperty + + @sqltype_for('id') + def type_id(self): + return None + + @sqltype_for('reference') + def type_reference(self): + return ndb.IntegerProperty + + @sqltype_for('list:integer') + def type_list_integer(self): + return (lambda **kwargs: ndb.IntegerProperty( + repeated=True, default=None, **kwargs)) + + @sqltype_for('list:string') + def type_list_string(self): + return (lambda **kwargs: ndb.StringProperty( + repeated=True, default=None, **kwargs)) + + @sqltype_for('list:reference') + def type_list_reference(self): + return (lambda **kwargs: ndb.IntegerProperty( + repeated=True, default=None, **kwargs)) + + def _and(self, first, second, query_env={}): + first = self.expand(first, query_env=query_env) + second = self.expand(second, query_env=query_env) + # none means lack of query (true) + if first == None: + return second + return ndb.AND(first, second) + + def _or(self, first, second, query_env={}): + first = self.expand(first, query_env=query_env) + second = self.expand(second, query_env=query_env) + # none means lack of query (true) + if first == None or second == None: + return None + return ndb.OR(first, second) + + def __gaef(self, first, op, second): + name = first.name if first.name != 'id' else 'key' + if name == 'key' and op in ('>', '!=') and second in (0, '0', None): + return None + field = getattr(first.table._tableobj, name) + value = self.adapter.represent(second, first.type, first._tablename) + return self.FILTER_OPTIONS[op](field, value) + + def eq(self, first, second=None, query_env={}): + return self.__gaef(first, '=', second) + + def ne(self, first, second=None, query_env={}): + return self.__gaef(first, '!=', second) + + def lt(self, first, second=None, query_env={}): + return self.__gaef(first, '<', second) + + def lte(self, first, second=None, query_env={}): + return self.__gaef(first, '<=', second) + + def gt(self, first, second=None, query_env={}): + return self.__gaef(first, '>', second) + + def gte(self, first, second=None, query_env={}): + return self.__gaef(first, '>=', second) + + def invert(self, first, query_env={}): + return '-%s' % first.name + + def comma(self, first, second, query_env={}): + return '%s,%s' % (first, second) + + def belongs(self, first, second, query_env={}): + if not isinstance(second, (list, tuple, set)): + raise SyntaxError("Not supported") + if not isinstance(second, list): + second = list(second) + if len(second) == 0: + # return a filter which will return a null set + f = self.eq(first, 0) + f.filter_all = True + return f + return self.__gaef(first, 'in', second) + + def contains(self, first, second, case_sensitive=True, query_env={}): + # silently ignoring: GAE can only do case sensitive matches! + if not first.type.startswith('list:'): + raise SyntaxError("Not supported") + return self.__gaef(first, '=', second) + + def _not(self, val, query_env={}): + op, f, s = val.op, val.first, val.second + if op in [self._or, self._and]: + not_op = self._and if op == self._or else self._or + rv = not_op(self._not(f), self._not(s)) + elif op == self.eq: + rv = self.__gaef(f, '!=', s) + elif op == self.ne: + rv = self.__gaef(f, '=', s) + elif op == self.lt: + rv = self.__gaef(f, '>=', s) + elif op == self.lte: + rv = self.__gaef(f, '>', s) + elif op == self.gt: + rv = self.__gaef(f, '<=', s) + elif op == self.gte: + rv = self.__gaef(f, '<', s) + else: + # TODO the IN operator must be split into a sequence of + # (field!=value) AND (field!=value) AND ... + raise NotImplementedError + return rv diff --git a/web2py/gluon/packages/dal/pydal/dialects/informix.py b/web2py/gluon/packages/dal/pydal/dialects/informix.py new file mode 100644 index 0000000..bd0b938 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/informix.py @@ -0,0 +1,79 @@ +from ..adapters.informix import Informix, InformixSE +from .firebird import FireBirdDialect +from . import dialects, sqltype_for + + +@dialects.register_for(Informix) +class InformixDialect(FireBirdDialect): + @sqltype_for('id') + def type_id(self): + return 'SERIAL' + + @sqltype_for('big-id') + def type_big_id(self): + return 'BIGSERIAL' + + @sqltype_for('reference FK') + def type_reference_fk(self): + return 'REFERENCES %(foreign_key)s ON DELETE %(on_delete_action)s ' + \ + 'CONSTRAINT FK_%(table_name)s_%(field_name)s' + + @sqltype_for('reference TFK') + def type_reference_tfk(self): + return 'FOREIGN KEY (%(field_name)s) REFERENCES %(foreign_table)s' + \ + '(%(foreign_key)s) ON DELETE %(on_delete_action)s ' + \ + 'CONSTRAINT TFK_%(table_name)s_%(field_name)s' + + @property + def random(self): + return 'Random()' + + def select(self, fields, tables, where=None, groupby=None, having=None, + orderby=None, limitby=None, distinct=False, for_update=False): + dst, whr, grp, order, limit, offset, upd = '', '', '', '', '', '', '' + if distinct is True: + dst = ' DISTINCT' + elif distinct: + dst = ' DISTINCT ON (%s)' % distinct + if where: + whr = ' %s' % self.where(where) + if groupby: + grp = ' GROUP BY %s' % groupby + if having: + grp += ' HAVING %s' % having + if orderby: + order = ' ORDER BY %s' % orderby + if limitby: + (lmin, lmax) = limitby + fetch_amt = lmax - lmin + if lmin and self.adapter.dbms_version >= 10: + offset = ' SKIP %i' % lmin + if fetch_amt and self.adapter.dbms_version >= 9: + limit = ' FIRST %i' % fetch_amt + if for_update: + upd = ' FOR UPDATE' + return 'SELECT%s%s%s %s FROM %s%s%s%s%s;' % ( + dst, offset, limit, fields, tables, whr, grp, order, upd) + + +@dialects.register_for(InformixSE) +class InformixSEDialect(InformixDialect): + def select(self, fields, tables, where=None, groupby=None, having=None, + orderby=None, limitby=None, distinct=False, for_update=False): + dst, whr, grp, order, limit, offset, upd = '', '', '', '', '', '', '' + if distinct is True: + dst = ' DISTINCT' + elif distinct: + dst = ' DISTINCT ON (%s)' % distinct + if where: + whr = ' %s' % self.where(where) + if groupby: + grp = ' GROUP BY %s' % groupby + if having: + grp += ' HAVING %s' % having + if orderby: + order = ' ORDER BY %s' % orderby + if for_update: + upd = ' FOR UPDATE' + return 'SELECT%s %s FROM %s%s%s%s%s%s%s;' % ( + dst, fields, tables, whr, grp, order, limit, offset, upd) diff --git a/web2py/gluon/packages/dal/pydal/dialects/ingres.py b/web2py/gluon/packages/dal/pydal/dialects/ingres.py new file mode 100644 index 0000000..2291ca1 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/ingres.py @@ -0,0 +1,117 @@ +from .._compat import basestring +from ..adapters.ingres import Ingres, IngresUnicode +from .base import SQLDialect +from . import dialects, sqltype_for + + +@dialects.register_for(Ingres) +class IngresDialect(SQLDialect): + SEQNAME = 'ii***lineitemsequence' + + @sqltype_for('text') + def type_text(self): + return 'CLOB' + + @sqltype_for('integer') + def type_integer(self): + return 'INTEGER4' + + @sqltype_for('bigint') + def type_bigint(self): + return 'BIGINT' + + @sqltype_for('double') + def type_float(self): + return 'FLOAT8' + + @sqltype_for('date') + def type_date(self): + return 'ANSIDATE' + + @sqltype_for('time') + def type_time(self): + return 'TIME WITHOUT TIME ZONE' + + @sqltype_for('datetime') + def type_datetime(self): + return 'TIMESTAMP WITHOUT TIME ZONE' + + @sqltype_for('id') + def type_id(self): + return 'int not null unique with default next value for %s' % \ + self.INGRES_SEQNAME + + @sqltype_for('big-id') + def type_big_id(self): + return 'bigint not null unique with default next value for %s' % \ + self.INGRES_SEQNAME + + @sqltype_for('reference') + def type_reference(self): + return 'INT, FOREIGN KEY (%(field_name)s) REFERENCES ' + \ + '%(foreign_key)s ON DELETE %(on_delete_action)s' + + @sqltype_for('big-reference') + def type_big_reference(self): + return 'BIGINT, FOREIGN KEY (%(field_name)s) REFERENCES ' + \ + '%(foreign_key)s ON DELETE %(on_delete_action)s' + + @sqltype_for('reference FK') + def type_reference_fk(self): + return ', CONSTRAINT FK_%(constraint_name)s FOREIGN KEY ' + \ + '(%(field_name)s) REFERENCES %(foreign_key)s ' + \ + 'ON DELETE %(on_delete_action)s' + + @sqltype_for('reference TFK') + def type_reference_tfk(self): + return ' CONSTRAINT FK_%(constraint_name)s_PK FOREIGN KEY ' + \ + '(%(field_name)s) REFERENCES %(foreign_table)s' + \ + '(%(foreign_key)s) ON DELETE %(on_delete_action)s' + + def left_join(self, val, query_env={}): + # Left join must always have an ON clause + if not isinstance(val, basestring): + val = self.expand(val, query_env=query_env) + return 'LEFT OUTER JOIN %s' % val + + @property + def random(self): + return 'RANDOM()' + + def select(self, fields, tables, where=None, groupby=None, having=None, + orderby=None, limitby=None, distinct=False, for_update=False): + dst, whr, grp, order, limit, offset, upd = '', '', '', '', '', '', '' + if distinct is True: + dst = ' DISTINCT' + elif distinct: + dst = ' DISTINCT ON (%s)' % distinct + if where: + whr = ' %s' % self.where(where) + if groupby: + grp = ' GROUP BY %s' % groupby + if having: + grp += ' HAVING %s' % having + if orderby: + order = ' ORDER BY %s' % orderby + if limitby: + (lmin, lmax) = limitby + fetch_amt = lmax - lmin + if fetch_amt: + limit = ' FIRST %i' % fetch_amt + if lmin: + offset = ' OFFSET %i' % lmin + if for_update: + upd = ' FOR UPDATE' + return 'SELECT%s%S %s FROM %s%s%s%s%s%s;' % ( + dst, limit, fields, tables, whr, grp, order, offset, upd) + + +@dialects.register_for(IngresUnicode) +class IngresUnicodeDialect(IngresDialect): + @sqltype_for('string') + def type_string(self): + return 'NVARCHAR(%(length)s)' + + @sqltype_for('text') + def type_text(self): + return 'NCLOB' diff --git a/web2py/gluon/packages/dal/pydal/dialects/mongo.py b/web2py/gluon/packages/dal/pydal/dialects/mongo.py new file mode 100644 index 0000000..c4272f1 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/mongo.py @@ -0,0 +1,524 @@ +import re +from .._compat import PY2, basestring +from ..adapters.mongo import Mongo +from ..exceptions import NotOnNOSQLError +from ..objects import Field +from .base import NoSQLDialect +from . import dialects + +_aggregate_map = { + 'SUM': '$sum', + 'MAX': '$max', + 'MIN': '$min', + 'AVG': '$avg', +} + +_extract_map = { + 'dayofyear': '$dayOfYear', + 'day': '$dayOfMonth', + 'dayofweek': '$dayOfWeek', + 'year': '$year', + 'month': '$month', + 'week': '$week', + 'hour': '$hour', + 'minute': '$minute', + 'second': '$second', + 'millisecond': '$millisecond', + 'string': '$dateToString', +} + + +def needs_aggregation_pipeline(f): + def wrap(self, first, *args, **kwargs): + self.adapter._parse_data(first, 'pipeline', True) + if len(args) > 0: + self.adapter._parse_data(args[0], 'pipeline', True) + return f(self, first, *args, **kwargs) + return wrap + + +def validate_second(f): + def wrap(*args, **kwargs): + if len(args) < 3 or args[2] is None: + raise RuntimeError("Cannot compare %s with None" % args[1]) + return f(*args, **kwargs) + return wrap + + +def check_fields_for_cmp(f): + def wrap(self, first, second=None, *args, **kwargs): + if (self.adapter._parse_data((first, second), 'pipeline')): + pipeline = True + elif not isinstance(first, Field) or self._has_field(second): + pipeline = True + self.adapter._parse_data((first, second), 'pipeline', True) + else: + pipeline = False + return f(self, first, second, *args, pipeline=pipeline, **kwargs) + return wrap + + +@dialects.register_for(Mongo) +class MongoDialect(NoSQLDialect): + GROUP_MARK = "__#GROUP#__" + AS_MARK = "__#AS#__" + REGEXP_MARK1 = "__#REGEXP_1#__" + REGEXP_MARK2 = "__#REGEXP_2#__" + REGEX_SELECT_AS_PARSER = re.compile("\\'" + AS_MARK + "\\': \\'(\\S+)\\'") + + @staticmethod + def _has_field(expression): + try: + return expression.has_field + except AttributeError: + return False + + def invert(self, first, query_env={}): + return '-%s' % self.expand(first, query_env=query_env) + + def _not(self, val, query_env={}): + op = self.expand(val, query_env=query_env) + op_k = list(op)[0] + op_body = op[op_k] + rv = None + if type(op_body) is list: + # apply De Morgan law for and/or + # not(A and B) -> not(A) or not(B) + # not(A or B) -> not(A) and not(B) + not_op = '$and' if op_k == '$or' else '$or' + rv = {not_op: [self._not(val.first, query_env), + self._not(val.second, query_env)]} + else: + try: + sub_ops = list(op_body.keys()) + if len(sub_ops) == 1 and sub_ops[0] == '$ne': + rv = {op_k: op_body['$ne']} + except AttributeError: + rv = {op_k: {'$ne': op_body}} + if rv is None: + rv = {op_k: {'$not': op_body}} + return rv + + def _and(self, first, second, query_env={}): + # pymongo expects: .find({'$and': [{'x':'1'}, {'y':'2'}]}) + if isinstance(second, bool): + if second: + return self.expand(first, query_env=query_env) + return self.ne(first, first) + return {'$and': [self.expand(first, query_env=query_env), + self.expand(second, query_env=query_env)]} + + def _or(self, first, second, query_env={}): + # pymongo expects: .find({'$or': [{'name':'1'}, {'name':'2'}]}) + if isinstance(second, bool): + if not second: + return self.expand(first, query_env=query_env) + return True + return {'$or': [self.expand(first, query_env=query_env), + self.expand(second, query_env=query_env)]} + + def belongs(self, first, second, query_env={}): + if isinstance(second, str): + # this is broken, the only way second is a string is if it has + # been converted to SQL. This no worky. This might be made to + # work if adapter._select did not return SQL. + raise RuntimeError("nested queries not supported") + items = [self.expand(item, first.type, query_env=query_env) + for item in second] + return {self.expand(first, query_env=query_env): {"$in": items}} + + def _cmp_ops_aggregation_pipeline(self, op, first, second, query_env={}): + try: + type = first.type + except: + type = None + return {op: [self.expand(first, query_env=query_env), + self.expand(second, type, query_env=query_env)]} + + @check_fields_for_cmp + def eq(self, first, second=None, pipeline=False, query_env={}): + if pipeline: + return self._cmp_ops_aggregation_pipeline('$eq', first, second, + query_env) + return {self.expand(first, query_env=query_env): + self.expand(second, first.type, query_env=query_env)} + + @check_fields_for_cmp + def ne(self, first, second=None, pipeline=False, query_env={}): + if pipeline: + return self._cmp_ops_aggregation_pipeline('$ne', first, second, + query_env) + return {self.expand(first, query_env=query_env): + {'$ne': self.expand(second, first.type, query_env=query_env)}} + + @validate_second + @check_fields_for_cmp + def lt(self, first, second=None, pipeline=False, query_env={}): + if pipeline: + return self._cmp_ops_aggregation_pipeline('$lt', first, second, + query_env) + return {self.expand(first, query_env=query_env): + {'$lt': self.expand(second, first.type, query_env=query_env)}} + + @validate_second + @check_fields_for_cmp + def lte(self, first, second=None, pipeline=False, query_env={}): + if pipeline: + return self._cmp_ops_aggregation_pipeline('$lte', first, second, + query_env) + return {self.expand(first, query_env=query_env): + {'$lte': self.expand(second, first.type, query_env=query_env)}} + + @validate_second + @check_fields_for_cmp + def gt(self, first, second=None, pipeline=False, query_env={}): + if pipeline: + return self._cmp_ops_aggregation_pipeline('$gt', first, second, + query_env) + return {self.expand(first, query_env=query_env): + {'$gt': self.expand(second, first.type, query_env=query_env)}} + + @validate_second + @check_fields_for_cmp + def gte(self, first, second=None, pipeline=False, query_env={}): + if pipeline: + return self._cmp_ops_aggregation_pipeline('$gte', first, second, + query_env) + return {self.expand(first, query_env=query_env): + {'$gte': self.expand(second, first.type, query_env=query_env)}} + + @needs_aggregation_pipeline + def add(self, first, second, query_env={}): + op_code = '$add' + for field in [first, second]: + try: + if field.type in ['string', 'text', 'password']: + op_code = '$concat' + break + except: + pass + return {op_code: [self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)]} + + @needs_aggregation_pipeline + def sub(self, first, second, query_env={}): + return {'$subtract': [ + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)]} + + @needs_aggregation_pipeline + def mul(self, first, second, query_env={}): + return {'$multiply': [ + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)]} + + @needs_aggregation_pipeline + def div(self, first, second, query_env={}): + return {'$divide': [ + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)]} + + @needs_aggregation_pipeline + def mod(self, first, second, query_env={}): + return {'$mod': [ + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)]} + + @needs_aggregation_pipeline + def aggregate(self, first, what, query_env={}): + if what == 'ABS': + return { + "$cond": [ + {"$lt": [self.expand(first, query_env=query_env), 0]}, + {"$subtract": [0, self.expand(first, query_env=query_env)]}, + self.expand(first, query_env=query_env)]} + try: + expanded = {_aggregate_map[what]: + self.expand(first, query_env=query_env)} + except KeyError: + raise NotImplementedError("'%s' not implemented" % what) + + self.adapter._parse_data(first, 'need_group', True) + return {self.GROUP_MARK: expanded} + + @needs_aggregation_pipeline + def count(self, first, distinct=None, query_env={}): + self.adapter._parse_data(first, 'need_group', True) + if distinct: + ret = {self.GROUP_MARK: {"$addToSet": + self.expand(first, query_env=query_env)}} + if self.adapter.server_version_major >= 2.6: + # '$size' not present in server versions < 2.6 + ret = {'$size': ret} + return ret + return {self.GROUP_MARK: {"$sum": 1}} + + @needs_aggregation_pipeline + def extract(self, first, what, query_env={}): + try: + return {_extract_map[what]: self.expand(first, query_env=query_env)} + except KeyError: + raise NotImplementedError("EXTRACT(%s) not implemented" % what) + + @needs_aggregation_pipeline + def epoch(self, first, query_env={}): + return {"$divide": [ + {"$subtract": [self.expand(first, query_env=query_env), + self.adapter.epoch]}, 1000]} + + @needs_aggregation_pipeline + def case(self, query, true_false, query_env={}): + return {"$cond": [ + self.expand(query, query_env=query_env), + self.expand(true_false[0], query_env=query_env), + self.expand(true_false[1], query_env=query_env)]} + + @needs_aggregation_pipeline + def _as(self, first, second, query_env={}): + # put the AS_MARK into the structure. The 'AS' name will be parsed + # later from the string of the field name. + if isinstance(first, Field): + return [{self.AS_MARK: second}, + self.expand(first, query_env=query_env)] + else: + result = self.expand(first, query_env=query_env) + result[self.AS_MARK] = second + return result + + # We could implement an option that simulates a full featured SQL + # database. But I think the option should be set explicit or + # implemented as another library. + def on(self, first, second, query_env={}): + raise NotOnNOSQLError() + + def comma(self, first, second, query_env={}): + # returns field name lists, to be separated via split(',') + return '%s,%s' % (self.expand(first, query_env=query_env), + self.expand(second, query_env=query_env)) + + # TODO verify full compatibilty with official SQL Like operator + def _build_like_regex(self, first, second, case_sensitive=True, + escape=None, ends_with=False, starts_with=False, + whole_string=True, like_wildcards=False, + query_env={}): + base = self.expand(second, 'string', query_env=query_env) + need_regex = (whole_string or not case_sensitive or starts_with or + ends_with or like_wildcards and + ('_' in base or '%' in base)) + if not need_regex: + return base + expr = re.escape(base) + if like_wildcards: + if escape: + # protect % and _ which are escaped + expr = expr.replace(escape+'\\%', '%') + if PY2: + expr = expr.replace(escape+'\\_', '_') + elif escape+'_' in expr: + set_aside = str(self.adapter.object_id('')) + while set_aside in expr: + set_aside = str(self.adapter.object_id('')) + expr = expr.replace(escape+'_', set_aside) + else: + set_aside = None + expr = expr.replace('\\%', '.*') + if PY2: + expr = expr.replace('\\_', '.') + else: + expr = expr.replace('_', '.') + if escape: + # convert to protected % and _ + expr = expr.replace('%', '\\%') + if PY2: + expr = expr.replace('_', '\\_') + elif set_aside: + expr = expr.replace(set_aside, '_') + if starts_with: + pattern = '^%s' + elif ends_with: + pattern = '%s$' + elif whole_string: + pattern = '^%s$' + else: + pattern = '%s' + return self.regexp(first, pattern % expr, case_sensitive, query_env) + + def like(self, first, second, case_sensitive=True, escape=None, + query_env={}): + return self._build_like_regex( + first, second, case_sensitive=case_sensitive, escape=escape, + like_wildcards=True, query_env=query_env) + + def ilike(self, first, second, escape=None, query_env={}): + return self.like(first, second, case_sensitive=False, escape=escape, + query_env=query_env) + + def startswith(self, first, second, query_env={}): + return self._build_like_regex(first, second, starts_with=True, + query_env=query_env) + + def endswith(self, first, second, query_env={}): + return self._build_like_regex(first, second, ends_with=True, + query_env=query_env) + + # TODO verify full compatibilty with official oracle contains operator + def contains(self, first, second, case_sensitive=True, query_env={}): + if isinstance(second, self.adapter.ObjectId): + ret = {self.expand(first, query_env=query_env): second} + elif isinstance(second, Field): + if second.type in ['string', 'text']: + if isinstance(first, Field): + if first.type in ['list:string', 'string', 'text']: + ret = { + '$where': "this.%s.indexOf(this.%s) > -1" % ( + first.name, second.name)} + else: + raise NotImplementedError( + "field.CONTAINS() not implemented for field " + + "type of '%s'" % first.type) + else: + raise NotImplementedError( + "x.CONTAINS() not implemented for x type of '%s'" % + type(first)) + elif second.type in ['integer', 'bigint']: + ret = { + '$where': "this.%s.indexOf(this.%s + '') > -1" % ( + first.name, second.name)} + else: + raise NotImplementedError( + "CONTAINS(field) not implemented for field type '%s'" % + second.type) + elif isinstance(second, (basestring, int)): + whole_string = isinstance(first, Field) and \ + first.type == 'list:string' + ret = self._build_like_regex( + first, second, case_sensitive=case_sensitive, + whole_string=whole_string, query_env=query_env) + # first.type in ('string', 'text', 'json', 'upload') + # or first.type.startswith('list:'): + else: + raise NotImplementedError( + "CONTAINS() not implemented for type '%s'" % type(second)) + return ret + + @needs_aggregation_pipeline + def substring(self, field, parameters, query_env={}): + def parse_parameters(pos0, length): + """ + The expression object can return these as string based expressions. + We can't use that so we have to tease it apart. + + These are the possibilities: + + pos0 = '(%s - %d)' % (self.len(), abs(start) - 1) + pos0 = start + 1 + + length = self.len() + length = '(%s - %d - %s)' % (self.len(), abs(stop) - 1, pos0) + length = '(%s - %s)' % (stop + 1, pos0) + + Two of these five require the length of the string which is not + supported by Mongo, so for now these cause an Exception and + won't reach here. + + If this were to ever be supported it may require a change to + Expression.__getitem__ so that it either returned the base + expression to be expanded here, or converted length to a string + to be parsed back to a call to STRLEN() + """ + if isinstance(length, basestring): + return (pos0 - 1, eval(length)) + # take the rest of the string + return (pos0 - 1, -1) + + parameters = parse_parameters(*parameters) + return {'$substr': [self.expand(field, query_env=query_env), + parameters[0], parameters[1]]} + + @needs_aggregation_pipeline + def lower(self, first, query_env={}): + return {'$toLower': self.expand(first, query_env=query_env)} + + @needs_aggregation_pipeline + def upper(self, first, query_env={}): + return {'$toUpper': self.expand(first, query_env=query_env)} + + def regexp(self, first, second, case_sensitive=True, query_env={}): + """ MongoDB provides regular expression capabilities for pattern + matching strings in queries. MongoDB uses Perl compatible + regular expressions (i.e. 'PCRE') version 8.36 with UTF-8 support. + """ + if (isinstance(first, Field) and + first.type in ['integer', 'bigint', 'float', 'double']): + return { + '$where': "RegExp('%s').test(this.%s + '')" % ( + self.expand(second, 'string', query_env=query_env), + first.name)} + expanded_first = self.expand(first, query_env=query_env) + regex_second = {'$regex': self.expand(second, 'string', + query_env=query_env)} + if not case_sensitive: + regex_second['$options'] = 'i' + if (self.adapter._parse_data((first, second), 'pipeline')): + name = str(expanded_first) + return { + self.REGEXP_MARK1: {name: expanded_first}, + self.REGEXP_MARK2: {name: regex_second}} + try: + return {expanded_first: regex_second} + except TypeError: + # if first is not hashable, then will need the pipeline + self.adapter._parse_data((first, second), 'pipeline', True) + return {} + + def length(self, first, query_env={}): + """ + Mongo has committed $strLenBytes, $strLenCP, and $substrCP to $project + aggregation stage in dev branch V3.3.4 + + https://jira.mongodb.org/browse/SERVER-14670 + https://jira.mongodb.org/browse/SERVER-22580 + db.coll.aggregate([{ + $project: { + byteLength: {$strLenBytes: "$string"}, + cpLength: {$strLenCP: "$string"} + byteSubstr: {$substrBytes: ["$string", 0, 4]}, + cpSubstr: {$substrCP: ["$string", 0, 4]} + } + }]) + + https://jira.mongodb.org/browse/SERVER-5319 + https://github.com/afchin/mongo/commit/f52105977e4d0ccb53bdddfb9c4528a3f3c40bdf + """ + if self.adapter.server_version_major <= 3.2: + # $strLenBytes not supported by mongo before version 3.4 + raise NotImplementedError() + + # implement here :-) + raise NotImplementedError() + + @needs_aggregation_pipeline + def coalesce(self, first, second, query_env={}): + if len(second) > 1: + second = [self.coalesce(second[0], second[1:])] + return {"$ifNull": [self.expand(first, query_env=query_env), + self.expand(second[0], query_env=query_env)]} + + @property + def random(self): + """ ORDER BY RANDOM() + + Mongo has released the '$sample' pipeline stage in V3.2 + https://docs.mongodb.org/manual/reference/operator/aggregation/sample/ + + https://github.com/mongodb/cookbook/blob/master/content/patterns/random-attribute.txt + http://stackoverflow.com/questions/19412/how-to-request-a-random-row-in-sql + https://jira.mongodb.org/browse/SERVER-533 + """ + + if self.adapter.server_version_major <= 3.0: + # '$sample' not present until server version 3.2 + raise NotImplementedError() + + # implement here :-) + raise NotImplementedError() diff --git a/web2py/gluon/packages/dal/pydal/dialects/mssql.py b/web2py/gluon/packages/dal/pydal/dialects/mssql.py new file mode 100644 index 0000000..a5bbaf8 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/mssql.py @@ -0,0 +1,425 @@ +from .._compat import basestring +from ..adapters.mssql import MSSQL, MSSQLN, MSSQL3, MSSQL4, MSSQL3N, MSSQL4N, \ + Vertica, Sybase +from ..helpers.methods import varquote_aux +from ..objects import Expression +from .base import SQLDialect +from . import dialects, sqltype_for + + +@dialects.register_for(MSSQL) +class MSSQLDialect(SQLDialect): + true = 1 + false = 0 + true_exp = '1=1' + false_exp = '1=0' + dt_sep = "T" + + @sqltype_for('boolean') + def type_boolean(self): + return 'BIT' + + @sqltype_for('blob') + def type_blob(self): + return 'IMAGE' + + @sqltype_for('integer') + def type_integer(self): + return 'INT' + + @sqltype_for('bigint') + def type_bigint(self): + return 'BIGINT' + + @sqltype_for('double') + def type_double(self): + return 'FLOAT' + + @sqltype_for('date') + def type_date(self): + return 'DATE' + + @sqltype_for('time') + def type_time(self): + return 'CHAR(8)' + + @sqltype_for('datetime') + def type_datetime(self): + return 'DATETIME' + + @sqltype_for('id') + def type_id(self): + return 'INT IDENTITY PRIMARY KEY' + + @sqltype_for('reference') + def type_reference(self): + return 'INT%(null)s%(unique)s, CONSTRAINT %(constraint_name)s ' + \ + 'FOREIGN KEY (%(field_name)s) REFERENCES %(foreign_key)s ON ' + \ + 'DELETE %(on_delete_action)s' + + @sqltype_for('big-id') + def type_big_id(self): + return 'BIGINT IDENTITY PRIMARY KEY' + + @sqltype_for('big-reference') + def type_big_reference(self): + return 'BIGINT%(null)s%(unique)s, CONSTRAINT %(constraint_name)s' + \ + ' FOREIGN KEY (%(field_name)s) REFERENCES %(foreign_key)s ' + \ + 'ON DELETE %(on_delete_action)s' + + @sqltype_for('reference FK') + def type_reference_fk(self): + return ', CONSTRAINT FK_%(constraint_name)s FOREIGN KEY ' + \ + '(%(field_name)s) REFERENCES %(foreign_key)s ON DELETE ' + \ + '%(on_delete_action)s' + + @sqltype_for('reference TFK') + def type_reference_tfk(self): + return ' CONSTRAINT FK_%(constraint_name)s_PK FOREIGN KEY ' + \ + '(%(field_name)s) REFERENCES %(foreign_table)s ' + \ + '(%(foreign_key)s) ON DELETE %(on_delete_action)s' + + @sqltype_for('geometry') + def type_geometry(self): + return 'geometry' + + @sqltype_for('geography') + def type_geography(self): + return 'geography' + + def varquote(self, val): + return varquote_aux(val, '[%s]') + + def update(self, table, values, where=None): + tablename = self.writing_alias(table) + whr = '' + if where: + whr = ' %s' % self.where(where) + return 'UPDATE %s SET %s FROM %s%s;' % ( + table.sql_shortref, values, tablename, whr) + + def delete(self, table, where=None): + tablename = self.writing_alias(table) + whr = '' + if where: + whr = ' %s' % self.where(where) + return 'DELETE %s FROM %s%s;' % (table.sql_shortref, tablename, whr) + + def select(self, fields, tables, where=None, groupby=None, having=None, + orderby=None, limitby=None, distinct=False, for_update=False): + dst, whr, grp, order, limit, upd = '', '', '', '', '', '' + if distinct is True: + dst = ' DISTINCT' + elif distinct: + dst = ' DISTINCT ON (%s)' % distinct + if where: + whr = ' %s' % self.where(where) + if groupby: + grp = ' GROUP BY %s' % groupby + if having: + grp += ' HAVING %s' % having + if orderby: + order = ' ORDER BY %s' % orderby + if limitby: + (lmin, lmax) = limitby + limit = ' TOP %i' % lmax + if for_update: + upd = ' FOR UPDATE' + return 'SELECT%s%s %s FROM %s%s%s%s%s;' % ( + dst, limit, fields, tables, whr, grp, order, upd) + + def left_join(self, val, query_env={}): + # Left join must always have an ON clause + if not isinstance(val, basestring): + val = self.expand(val, query_env=query_env) + return 'LEFT OUTER JOIN %s' % val + + def random(self): + return 'NEWID()' + + def cast(self, first, second, query_env={}): + # apparently no cast necessary in MSSQL + return first + + def _mssql_like_normalizer(self, term): + term = term.replace('[', '[[]') + return term + + def _like_escaper_default(self, term): + if isinstance(term, Expression): + return term + return self._mssql_like_normalizer( + super(MSSQLDialect, self)._like_escaper_default(term)) + + def concat(self, *items, **kwargs): + query_env = kwargs.get('query_env', {}) + tmp = (self.expand(x, 'string', query_env=query_env) for x in items) + return '(%s)' % ' + '.join(tmp) + + def regexp(self, first, second, query_env={}): + second = self.expand(second, 'string', query_env=query_env) + second = second.replace('\\', '\\\\') + second = second.replace('%', '\%').replace('*', '%').replace('.', '_') + return "(%s LIKE %s ESCAPE '\\')" % ( + self.expand(first, query_env=query_env), second) + + def extract(self, first, what, query_env={}): + return "DATEPART(%s,%s)" % (what, + self.expand(first, query_env=query_env)) + + def epoch(self, val, query_env={}): + return "DATEDIFF(second, '1970-01-01 00:00:00', %s)" % \ + self.expand(val, query_env=query_env) + + def length(self, val, query_env={}): + return "LEN(%s)" % self.expand(val, query_env=query_env) + + def aggregate(self, first, what, query_env={}): + if what == 'LENGTH': + what = 'LEN' + return super(MSSQLDialect, self).aggregate(first, what, query_env) + + @property + def allow_null(self): + return ' NULL' + + def substring(self, field, parameters, query_env={}): + return 'SUBSTRING(%s,%s,%s)' % ( + self.expand(field, query_env=query_env), parameters[0], + parameters[1]) + + def primary_key(self, key): + return 'PRIMARY KEY CLUSTERED (%s)' % key + + def concat_add(self, tablename): + return '; ALTER TABLE %s ADD ' % tablename + + def drop_index(self, name, table): + return 'DROP INDEX %s ON %s;' % (self.quote(name), table._rname) + + def st_astext(self, first, query_env={}): + return '%s.STAsText()' % self.expand(first, query_env=query_env) + + def st_contains(self, first, second, query_env={}): + return '%s.STContains(%s)=1' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_distance(self, first, second, query_env={}): + return '%s.STDistance(%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_equals(self, first, second, query_env={}): + return '%s.STEquals(%s)=1' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_intersects(self, first, second, query_env={}): + return '%s.STIntersects(%s)=1' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_overlaps(self, first, second, query_env={}): + return '%s.STOverlaps(%s)=1' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_touches(self, first, second, query_env={}): + return '%s.STTouches(%s)=1' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_within(self, first, second, query_env={}): + return '%s.STWithin(%s)=1' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + +@dialects.register_for(MSSQLN) +class MSSQLNDialect(MSSQLDialect): + @sqltype_for('string') + def type_string(self): + return 'NVARCHAR(%(length)s)' + + @sqltype_for('text') + def type_text(self): + return 'NTEXT' + + def ilike(self, first, second, escape=None, query_env={}): + if isinstance(second, Expression): + second = self.expand(second, 'string', query_env=query_env) + else: + second = self.expand(second, 'string', query_env=query_env).lower() + if escape is None: + escape = '\\' + second = second.replace(escape, escape * 2) + if second.startswith("n'"): + second = "N'" + second[2:] + return "(%s LIKE %s ESCAPE '%s')" % ( + self.lower(first, query_env), second, escape) + + +@dialects.register_for(MSSQL3) +class MSSQL3Dialect(MSSQLDialect): + @sqltype_for('text') + def type_text(self): + return 'VARCHAR(MAX)' + + @sqltype_for('time') + def type_time(self): + return 'TIME(7)' + + def _rebuild_select_for_limit(self, fields, tables, dst, whr, grp, order, + lmin, lmax): + f_outer = ['f_%s' % i for i in range(len(fields.split(',')))] + f_inner = [field for field in fields.split(', ')] + f_iproxy = ', '.join([ + self._as(o, n) for (o, n) in zip(f_inner, f_outer)]) + f_oproxy = ', '.join(f_outer) + interp = 'SELECT%s %s FROM (' + \ + 'SELECT%s ROW_NUMBER() OVER (%s) AS w_row, %s FROM %s%s%s)' + \ + ' TMP WHERE w_row BETWEEN %i and %i;' + return interp % ( + dst, f_oproxy, dst, order, f_iproxy, tables, whr, grp, + lmin, lmax + ) + + def select(self, fields, tables, where=None, groupby=None, having=None, + orderby=None, limitby=None, distinct=False, for_update=False): + dst, whr, grp, order, limit, offset, upd = '', '', '', '', '', '', '' + if distinct is True: + dst = ' DISTINCT' + elif distinct: + dst = ' DISTINCT ON (%s)' % distinct + if where: + whr = ' %s' % self.where(where) + if groupby: + grp = ' GROUP BY %s' % groupby + if having: + grp += ' HAVING %s' % having + if orderby: + order = ' ORDER BY %s' % orderby + if limitby: + (lmin, lmax) = limitby + if lmin == 0: + dst += ' TOP %i' % lmax + else: + return self._rebuild_select_for_limit( + fields, tables, dst, whr, grp, order, lmin, lmax + ) + if for_update: + upd = ' FOR UPDATE' + return 'SELECT%s %s FROM %s%s%s%s%s%s%s;' % ( + dst, fields, tables, whr, grp, order, limit, offset, upd) + + +@dialects.register_for(MSSQL4) +class MSSQL4Dialect(MSSQL3Dialect): + def select(self, fields, tables, where=None, groupby=None, having=None, + orderby=None, limitby=None, distinct=False, for_update=False): + dst, whr, grp, order, limit, offset, upd = '', '', '', '', '', '', '' + if distinct is True: + dst = ' DISTINCT' + elif distinct: + dst = ' DISTINCT ON (%s)' % distinct + if where: + whr = ' %s' % self.where(where) + if groupby: + grp = ' GROUP BY %s' % groupby + if having: + grp += ' HAVING %s' % having + if orderby: + order = ' ORDER BY %s' % orderby + if limitby: + (lmin, lmax) = limitby + if lmin == 0: + dst += ' TOP %i' % lmax + else: + if not order: + order = ' ORDER BY %s' % self.random + offset = ' OFFSET %i ROWS FETCH NEXT %i ROWS ONLY' % ( + lmin, (lmax - lmin)) + if for_update: + upd = ' FOR UPDATE' + return 'SELECT%s %s FROM %s%s%s%s%s%s%s;' % ( + dst, fields, tables, whr, grp, order, limit, offset, upd) + + +@dialects.register_for(MSSQL3N) +class MSSQL3NDialect(MSSQLNDialect, MSSQL3Dialect): + @sqltype_for('text') + def type_text(self): + return 'NVARCHAR(MAX)' + + +@dialects.register_for(MSSQL4N) +class MSSQL4NDialect(MSSQLNDialect, MSSQL4Dialect): + @sqltype_for('text') + def type_text(self): + return 'NVARCHAR(MAX)' + + +@dialects.register_for(Vertica) +class VerticaDialect(MSSQLDialect): + dt_sep = ' ' + + @sqltype_for('boolean') + def type_boolean(self): + return 'BOOLEAN' + + @sqltype_for('text') + def type_text(self): + return 'BYTEA' + + @sqltype_for('json') + def type_json(self): + return self.types['string'] + + @sqltype_for('blob') + def type_blob(self): + return 'BYTEA' + + @sqltype_for('double') + def type_double(self): + return 'DOUBLE PRECISION' + + @sqltype_for('time') + def type_time(self): + return 'TIME' + + @sqltype_for('id') + def type_id(self): + return 'IDENTITY' + + @sqltype_for('reference') + def type_reference(self): + return 'INT REFERENCES %(foreign_key)s ON DELETE %(on_delete_action)s' + + @sqltype_for('big-reference') + def type_big_reference(self): + return 'BIGINT REFERENCES %(foreign_key)s ON DELETE' + \ + ' %(on_delete_action)s' + + def extract(self, first, what, query_env={}): + return "DATE_PART('%s', TIMESTAMP %s)" % (what, + self.expand(first, query_env=query_env)) + + def truncate(self, table, mode=''): + if mode: + mode = " %s" % mode + return ['TRUNCATE %s%s;' % (table._rname, mode)] + + def select(self, *args, **kwargs): + return SQLDialect.select(self, *args, **kwargs) + + +@dialects.register_for(Sybase) +class SybaseDialect(MSSQLDialect): + @sqltype_for('string') + def type_string(self): + return 'CHAR VARYING(%(length)s)' + + @sqltype_for('date') + def type_date(self): + return 'DATETIME' diff --git a/web2py/gluon/packages/dal/pydal/dialects/mysql.py b/web2py/gluon/packages/dal/pydal/dialects/mysql.py new file mode 100644 index 0000000..f9b0e35 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/mysql.py @@ -0,0 +1,100 @@ +from ..adapters.mysql import MySQL +from ..helpers.methods import varquote_aux +from .base import SQLDialect +from . import dialects, sqltype_for + + +@dialects.register_for(MySQL) +class MySQLDialect(SQLDialect): + quote_template = '`%s`' + + @sqltype_for('datetime') + def type_datetime(self): + return 'DATETIME' + + @sqltype_for('text') + def type_text(self): + return 'LONGTEXT' + + @sqltype_for('blob') + def type_blob(self): + return 'LONGBLOB' + + @sqltype_for('bigint') + def type_bigint(self): + return 'BIGINT' + + @sqltype_for('id') + def type_id(self): + return 'INT AUTO_INCREMENT NOT NULL' + + @sqltype_for('big-id') + def type_big_id(self): + return 'BIGINT AUTO_INCREMENT NOT NULL' + + @sqltype_for('reference') + def type_reference(self): + return 'INT %(null)s %(unique)s, INDEX %(index_name)s ' + \ + '(%(field_name)s), FOREIGN KEY (%(field_name)s) REFERENCES ' + \ + '%(foreign_key)s ON DELETE %(on_delete_action)s' + + @sqltype_for('big-reference') + def type_big_reference(self): + return 'BIGINT %(null)s %(unique)s, INDEX %(index_name)s ' + \ + '(%(field_name)s), FOREIGN KEY (%(field_name)s) REFERENCES ' + \ + '%(foreign_key)s ON DELETE %(on_delete_action)s' + + @sqltype_for('reference FK') + def type_reference_fk(self): + return ', CONSTRAINT `FK_%(constraint_name)s` FOREIGN KEY ' + \ + '(%(field_name)s) REFERENCES %(foreign_key)s ON DELETE ' + \ + '%(on_delete_action)s' + + def varquote(self, val): + return varquote_aux(val, '`%s`') + + def insert_empty(self, table): + return 'INSERT INTO %s VALUES (DEFAULT);' % table + + def delete(self, table, where=None): + tablename = self.writing_alias(table) + whr = '' + if where: + whr = ' %s' % self.where(where) + return 'DELETE %s FROM %s%s;' % (table.sql_shortref, tablename, whr) + + @property + def random(self): + return 'RAND()' + + def substring(self, field, parameters, query_env={}): + return 'SUBSTRING(%s,%s,%s)' % ( + self.expand(field, query_env=query_env), parameters[0], + parameters[1]) + + def epoch(self, first, query_env={}): + return "UNIX_TIMESTAMP(%s)" % self.expand(first, query_env=query_env) + + def concat(self, *items, **kwargs): + query_env = kwargs.get('query_env', {}) + tmp = (self.expand(x, 'string', query_env=query_env) for x in items) + return 'CONCAT(%s)' % ','.join(tmp) + + def regexp(self, first, second, query_env={}): + return '(%s REGEXP %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, 'string', query_env=query_env)) + + def cast(self, first, second, query_env={}): + if second == 'LONGTEXT': + second = 'CHAR' + return 'CAST(%s AS %s)' % (first, second) + + def drop_table(self, table, mode): + # breaks db integrity but without this mysql does not drop table + return [ + 'SET FOREIGN_KEY_CHECKS=0;', 'DROP TABLE %s;' % table._rname, + 'SET FOREIGN_KEY_CHECKS=1;'] + + def drop_index(self, name, table): + return 'DROP INDEX %s ON %s;' % (self.quote(name), table._rname) diff --git a/web2py/gluon/packages/dal/pydal/dialects/oracle.py b/web2py/gluon/packages/dal/pydal/dialects/oracle.py new file mode 100644 index 0000000..c081098 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/oracle.py @@ -0,0 +1,120 @@ +from ..adapters.oracle import Oracle +from .base import SQLDialect +from . import dialects, sqltype_for + + +@dialects.register_for(Oracle) +class OracleDialect(SQLDialect): + @sqltype_for('string') + def type_string(self): + return 'VARCHAR2(%(length)s)' + + @sqltype_for('text') + def type_text(self): + return 'CLOB' + + @sqltype_for('integer') + def type_integer(self): + return 'INT' + + @sqltype_for('bigint') + def type_bigint(self): + return 'NUMBER' + + @sqltype_for('double') + def type_float(self): + return 'BINARY_DOUBLE' + + @sqltype_for('time') + def type_time(self): + return 'TIME(8)' + + @sqltype_for('datetime') + def type_datetime(self): + return 'DATE' + + @sqltype_for('id') + def type_id(self): + return 'NUMBER PRIMARY KEY' + + @sqltype_for('reference') + def type_reference(self): + return 'NUMBER, CONSTRAINT %(constraint_name)s FOREIGN KEY ' + \ + '(%(field_name)s) REFERENCES %(foreign_key)s ON DELETE ' + \ + '%(on_delete_action)s' + + @sqltype_for('reference FK') + def type_reference_fk(self): + return ', CONSTRAINT FK_%(constraint_name)s FOREIGN KEY ' + \ + '(%(field_name)s) REFERENCES %(foreign_key)s ' + \ + 'ON DELETE %(on_delete_action)s' + + @sqltype_for('reference TFK') + def type_reference_tfk(self): + return ' CONSTRAINT FK_%(constraint_name)s_PK FOREIGN KEY ' + \ + '(%(field_name)s) REFERENCES %(foreign_table)s' + \ + '(%(foreign_key)s) ON DELETE %(on_delete_action)s' + + def left_join(self, val): + return 'LEFT OUTER JOIN %s' % val + + @property + def random(self): + return 'dbms_random.value' + + def trigger_name(self, tablename): + return '%s_trigger' % tablename + + def constraint_name(self, table, fieldname): + constraint_name = super(OracleDialect, self).constraint_name( + table, fieldname) + if len(constraint_name) > 30: + constraint_name = '%s_%s__constraint' % (table[:10], fieldname[:7]) + return constraint_name + + def not_null(self, default, field_type): + return 'DEFAULT %s NOT NULL' % \ + self.adapter.represent(default, field_type) + + def regexp(self, first, second, query_env={}): + return 'REGEXP_LIKE(%s, %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, 'string', query_env=query_env)) + + def select(self, fields, tables, where=None, groupby=None, having=None, + orderby=None, limitby=None, distinct=False, for_update=False): + dst, whr, grp, order, limit, offset, upd = '', '', '', '', '', '', '' + if distinct is True: + dst = ' DISTINCT' + elif distinct: + dst = ' DISTINCT ON (%s)' % distinct + if where: + whr = ' %s' % self.where(where) + if groupby: + grp = ' GROUP BY %s' % groupby + if having: + grp += ' HAVING %s' % having + if orderby: + order = ' ORDER BY %s' % orderby + if limitby: + (lmin, lmax) = limitby + if whr: + whr2 = whr + " AND w_row > %i" % lmin + else: + whr2 = self.where('w_row > %i' % lmin) + + return ('SELECT%s %s FROM (SELECT w_tmp.*, ROWNUM w_row FROM ' + '(SELECT %s FROM %s%s%s%s) w_tmp WHERE ROWNUM<=%i) %s%s%s%s;') \ + % ( + dst, fields, fields, tables, whr, grp, order, lmax, tables, + whr2, grp, order) + if for_update: + upd = ' FOR UPDATE' + return 'SELECT%s %s FROM %s%s%s%s%s%s%s;' % ( + dst, fields, tables, whr, grp, order, limit, offset, upd) + + def drop_table(self, table, mode): + sequence_name = table._sequence_name + return [ + 'DROP TABLE %s %s;' % (table._rname, mode), + 'DROP SEQUENCE %s;' % sequence_name] diff --git a/web2py/gluon/packages/dal/pydal/dialects/postgre.py b/web2py/gluon/packages/dal/pydal/dialects/postgre.py new file mode 100644 index 0000000..0c453cd --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/postgre.py @@ -0,0 +1,307 @@ +from ..adapters.postgres import Postgre, PostgreNew, PostgreBoolean +from ..helpers.methods import varquote_aux +from ..objects import Expression +from .base import SQLDialect +from . import dialects, sqltype_for, register_expression + + +@dialects.register_for(Postgre) +class PostgreDialect(SQLDialect): + true_exp = "TRUE" + false_exp = "FALSE" + + @sqltype_for('blob') + def type_blob(self): + return 'BYTEA' + + @sqltype_for('bigint') + def type_bigint(self): + return 'BIGINT' + + @sqltype_for('double') + def type_double(self): + return 'FLOAT8' + + @sqltype_for('id') + def type_id(self): + return 'SERIAL PRIMARY KEY' + + @sqltype_for('big-id') + def type_big_id(self): + return 'BIGSERIAL PRIMARY KEY' + + @sqltype_for('big-reference') + def type_big_reference(self): + return 'BIGINT REFERENCES %(foreign_key)s ' + \ + 'ON DELETE %(on_delete_action)s %(null)s %(unique)s' + + @sqltype_for('reference TFK') + def type_reference_tfk(self): + return ' CONSTRAINT "FK_%(constraint_name)s_PK" FOREIGN KEY ' + \ + '(%(field_name)s) REFERENCES %(foreign_table)s' + \ + '(%(foreign_key)s) ON DELETE %(on_delete_action)s' + + @sqltype_for('geometry') + def type_geometry(self): + return 'GEOMETRY' + + @sqltype_for('geography') + def type_geography(self): + return 'GEOGRAPHY' + + def varquote(self, val): + return varquote_aux(val, '"%s"') + + def sequence_name(self, tablename): + return self.quote('%s_id_seq' % tablename) + + def insert(self, table, fields, values, returning=None): + ret = '' + if returning: + ret = 'RETURNING %s' % returning + return 'INSERT INTO %s(%s) VALUES (%s)%s;' % ( + table, fields, values, ret) + + @property + def random(self): + return 'RANDOM()' + + def add(self, first, second, query_env={}): + t = first.type + if t in ('text', 'string', 'password', 'json', 'jsonb', 'upload', 'blob'): + return '(%s || %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + else: + return '(%s + %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def regexp(self, first, second, query_env={}): + return '(%s ~ %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, 'string', query_env=query_env)) + + def like(self, first, second, escape=None, query_env={}): + if isinstance(second, Expression): + second = self.expand(second, 'string', query_env=query_env) + else: + second = self.expand(second, 'string', query_env=query_env) + if escape is None: + escape = '\\' + second = second.replace(escape, escape * 2) + if first.type not in ('string', 'text', 'json', 'jsonb'): + return "(%s LIKE %s ESCAPE '%s')" % ( + self.cast(self.expand(first, query_env=query_env), + 'CHAR(%s)' % first.length), second, escape) + return "(%s LIKE %s ESCAPE '%s')" % ( + self.expand(first, query_env=query_env), second, escape) + + def ilike(self, first, second, escape=None, query_env={}): + if isinstance(second, Expression): + second = self.expand(second, 'string', query_env=query_env) + else: + second = self.expand(second, 'string', query_env=query_env) + if escape is None: + escape = '\\' + second = second.replace(escape, escape * 2) + if first.type not in ('string', 'text', 'json', 'jsonb', 'list:string'): + return "(%s ILIKE %s ESCAPE '%s')" % ( + self.cast(self.expand(first, query_env=query_env), + 'CHAR(%s)' % first.length), second, escape) + return "(%s ILIKE %s ESCAPE '%s')" % ( + self.expand(first, query_env=query_env), second, escape) + + def drop_table(self, table, mode): + if mode not in ['restrict', 'cascade', '']: + raise ValueError('Invalid mode: %s' % mode) + return ['DROP TABLE ' + table._rname + ' ' + mode + ';'] + + def create_index(self, name, table, expressions, unique=False, where=None): + uniq = ' UNIQUE' if unique else '' + whr = '' + if where: + whr = ' %s' % self.where(where) + with self.adapter.index_expander(): + rv = 'CREATE%s INDEX %s ON %s (%s)%s;' % ( + uniq, self.quote(name), table._rname, ','.join( + self.expand(field) for field in expressions), whr) + return rv + + def st_asgeojson(self, first, second, query_env={}): + return 'ST_AsGeoJSON(%s,%s,%s,%s)' % ( + second['version'], self.expand(first, query_env=query_env), + second['precision'], second['options']) + + def st_astext(self, first, query_env={}): + return 'ST_AsText(%s)' % self.expand(first, query_env=query_env) + + def st_x(self, first, query_env={}): + return 'ST_X(%s)' % (self.expand(first, query_env=query_env)) + + def st_y(self, first, query_env={}): + return 'ST_Y(%s)' % (self.expand(first, query_env=query_env)) + + def st_contains(self, first, second, query_env={}): + return 'ST_Contains(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_distance(self, first, second, query_env={}): + return 'ST_Distance(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_equals(self, first, second, query_env={}): + return 'ST_Equals(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_intersects(self, first, second, query_env={}): + return 'ST_Intersects(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_overlaps(self, first, second, query_env={}): + return 'ST_Overlaps(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_simplify(self, first, second, query_env={}): + return 'ST_Simplify(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, 'double', query_env=query_env)) + + def st_simplifypreservetopology(self, first, second, query_env={}): + return 'ST_SimplifyPreserveTopology(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, 'double', query_env=query_env)) + + def st_touches(self, first, second, query_env={}): + return 'ST_Touches(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_within(self, first, second, query_env={}): + return 'ST_Within(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_dwithin(self, first, tup, query_env={}): + return 'ST_DWithin(%s,%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(tup[0], first.type, query_env=query_env), + self.expand(tup[1], 'double', query_env=query_env)) + + @register_expression('doy') + def extract_doy(self, expr): + return Expression(expr.db, self.extract, expr, 'doy', 'integer') + + @register_expression('dow') + def extract_dow(self, expr): + return Expression(expr.db, self.extract, expr, 'dow', 'integer') + + @register_expression('isodow') + def extract_isodow(self, expr): + return Expression(expr.db, self.extract, expr, 'isodow', 'integer') + + @register_expression('isoyear') + def extract_isoyear(self, expr): + return Expression(expr.db, self.extract, expr, 'isoyear', 'integer') + + @register_expression('quarter') + def extract_quarter(self, expr): + return Expression(expr.db, self.extract, expr, 'quarter', 'integer') + + @register_expression('week') + def extract_week(self, expr): + return Expression(expr.db, self.extract, expr, 'week', 'integer') + + @register_expression('decade') + def extract_decade(self, expr): + return Expression(expr.db, self.extract, expr, 'decade', 'integer') + + @register_expression('century') + def extract_century(self, expr): + return Expression(expr.db, self.extract, expr, 'century', 'integer') + + @register_expression('millenium') + def extract_millenium(self, expr): + return Expression(expr.db, self.extract, expr, 'millenium', 'integer') + + +class PostgreDialectJSON(PostgreDialect): + @sqltype_for('json') + def type_json(self): + return 'JSON' + + @sqltype_for('jsonb') + def type_jsonb(self): + return 'JSONB' + +@dialects.register_for(PostgreNew) +class PostgreDialectArrays(PostgreDialect): + @sqltype_for('list:integer') + def type_list_integer(self): + return 'BIGINT[]' + + @sqltype_for('list:string') + def type_list_string(self): + return 'TEXT[]' + + @sqltype_for('list:reference') + def type_list_reference(self): + return 'BIGINT[]' + + def any(self, val, query_env={}): + return "ANY(%s)" % self.expand(val, query_env=query_env) + + def contains(self, first, second, case_sensitive=True, query_env={}): + if first.type.startswith('list:'): + f = self.expand(second, 'string', query_env=query_env) + s = self.any(first, query_env) + if case_sensitive is True: + return self.eq(f, s) + return self.ilike(f, s, escape='\\', query_env=query_env) + return super(PostgreDialectArrays, self).contains( + first, second, case_sensitive=case_sensitive, query_env=query_env) + + def ilike(self, first, second, escape=None, query_env={}): + if first and 'type' not in first: + args = (first, self.expand(second, query_env=query_env)) + return '(%s ILIKE %s)' % args + return super(PostgreDialectArrays, self).ilike( + first, second, escape=escape, query_env=query_env) + + def eq(self, first, second=None, query_env={}): + if first and 'type' not in first: + return '(%s = %s)' % (first, + self.expand(second, query_env=query_env)) + return super(PostgreDialectArrays, self).eq(first, second, query_env) + + +class PostgreDialectArraysJSON(PostgreDialectArrays): + @sqltype_for('json') + def type_json(self): + return 'JSON' + + @sqltype_for('jsonb') + def type_jsonb(self): + return 'JSONB' + + +@dialects.register_for(PostgreBoolean) +class PostgreDialectBoolean(PostgreDialectArrays): + @sqltype_for('boolean') + def type_boolean(self): + return 'BOOLEAN' + + +class PostgreDialectBooleanJSON(PostgreDialectBoolean): + @sqltype_for('json') + def type_json(self): + return 'JSON' + + @sqltype_for('jsonb') + def type_jsonb(self): + return 'JSONB' diff --git a/web2py/gluon/packages/dal/pydal/dialects/sap.py b/web2py/gluon/packages/dal/pydal/dialects/sap.py new file mode 100644 index 0000000..08d346e --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/sap.py @@ -0,0 +1,78 @@ +from ..adapters.sap import SAPDB +from .base import SQLDialect +from . import dialects, sqltype_for + + +@dialects.register_for(SAPDB) +class SAPDBDialect(SQLDialect): + @sqltype_for('integer') + def type_integer(self): + return 'INT' + + @sqltype_for('text') + def type_text(self): + return 'LONG' + + @sqltype_for('bigint') + def type_bigint(self): + return 'BIGINT' + + @sqltype_for('double') + def type_double(self): + return 'DOUBLE PRECISION' + + @sqltype_for('decimal') + def type_decimal(self): + return 'FIXED(%(precision)s,%(scale)s)' + + @sqltype_for('id') + def type_id(self): + return 'INT PRIMARY KEY' + + @sqltype_for('big-id') + def type_big_id(self): + return 'BIGINT PRIMARY KEY' + + @sqltype_for('reference') + def type_reference(self): + return 'INT, FOREIGN KEY (%(field_name)s) REFERENCES ' + \ + '%(foreign_key)s ON DELETE %(on_delete_action)s' + + @sqltype_for('big-reference') + def type_big_reference(self): + return 'BIGINT, FOREIGN KEY (%(field_name)s) REFERENCES ' + \ + '%(foreign_key)s ON DELETE %(on_delete_action)s' + + def sequence_name(self, tablename): + return self.quote('%s_id_Seq' % tablename) + + def select(self, fields, tables, where=None, groupby=None, having=None, + orderby=None, limitby=None, distinct=False, for_update=False): + dst, whr, grp, order, limit, offset, upd = '', '', '', '', '', '', '' + if distinct is True: + dst = ' DISTINCT' + elif distinct: + dst = ' DISTINCT ON (%s)' % distinct + if where: + whr = ' %s' % self.where(where) + if groupby: + grp = ' GROUP BY %s' % groupby + if having: + grp += ' HAVING %s' % having + if orderby: + order = ' ORDER BY %s' % orderby + if limitby: + (lmin, lmax) = limitby + if whr: + whr2 = whr + " AND w_row > %i" % lmin + else: + whr2 = self.where('w_row > %i' % lmin) + return 'SELECT%s %s FROM (SELECT w_tmp.*, ROWNO w_row FROM ' + \ + '(SELECT %s FROM %s%s%s%s) w_tmp WHERE ROWNO=%i) %s%s%s%s;' \ + % ( + dst, fields, fields, tables, whr, grp, order, lmax, tables, + whr2, grp, order) + if for_update: + upd = ' FOR UPDATE' + return 'SELECT%s%s%s %s FROM %s%s%s%s%s;' % ( + dst, limit, offset, fields, tables, whr, grp, order, upd) diff --git a/web2py/gluon/packages/dal/pydal/dialects/sqlite.py b/web2py/gluon/packages/dal/pydal/dialects/sqlite.py new file mode 100644 index 0000000..5094efc --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/sqlite.py @@ -0,0 +1,107 @@ +from ..adapters.sqlite import SQLite, Spatialite +from .base import SQLDialect +from . import dialects, sqltype_for + + +@dialects.register_for(SQLite) +class SQLiteDialect(SQLDialect): + @sqltype_for('string') + def type_string(self): + return 'CHAR(%(length)s)' + + @sqltype_for('float') + def type_float(self): + return 'DOUBLE' + + @sqltype_for('double') + def type_double(self): + return self.types['float'] + + @sqltype_for('decimal') + def type_decimal(self): + return self.types['float'] + + def extract(self, field, what, query_env={}): + return "web2py_extract('%s', %s)" % (what, + self.expand(field, query_env=query_env)) + + def regexp(self, first, second, query_env={}): + return '(%s REGEXP %s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, 'string', query_env=query_env)) + + def select(self, fields, tables, where=None, groupby=None, having=None, + orderby=None, limitby=None, distinct=False, for_update=False): + if distinct and distinct is not True: + raise SyntaxError( + 'DISTINCT ON is not supported by SQLite') + return super(SQLiteDialect, self).select( + fields, tables, where, groupby, having, orderby, limitby, distinct, + for_update) + + def truncate(self, table, mode=''): + tablename = self.adapter.expand(table._raw_rname, 'string') + return [ + self.delete(table), + "DELETE FROM sqlite_sequence WHERE name=%s" % tablename] + + def writing_alias(self, table): + if table._dalname != table._tablename: + raise SyntaxError( + 'SQLite does not support UPDATE/DELETE on aliased table') + return table._rname + + +@dialects.register_for(Spatialite) +class SpatialiteDialect(SQLiteDialect): + @sqltype_for('geometry') + def type_geometry(self): + return 'GEOMETRY' + + def st_asgeojson(self, first, second, query_env={}): + return 'AsGeoJSON(%s,%s,%s)' % ( + self.expand(first, query_env=query_env), second['precision'], + second['options']) + + def st_astext(self, first, query_env={}): + return 'AsText(%s)' % self.expand(first, query_env=query_env) + + def st_contains(self, first, second, query_env={}): + return 'Contains(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_distance(self, first, second, query_env={}): + return 'Distance(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_equals(self, first, second, query_env={}): + return 'Equals(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_intersects(self, first, second, query_env={}): + return 'Intersects(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_overlaps(self, first, second, query_env={}): + return 'Overlaps(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_simplify(self, first, second, query_env={}): + return 'Simplify(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, 'double', query_env=query_env)) + + def st_touches(self, first, second, query_env={}): + return 'Touches(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) + + def st_within(self, first, second, query_env={}): + return 'Within(%s,%s)' % ( + self.expand(first, query_env=query_env), + self.expand(second, first.type, query_env=query_env)) diff --git a/web2py/gluon/packages/dal/pydal/dialects/teradata.py b/web2py/gluon/packages/dal/pydal/dialects/teradata.py new file mode 100644 index 0000000..cf96a02 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/dialects/teradata.py @@ -0,0 +1,100 @@ +from .._compat import basestring +from ..adapters.teradata import Teradata +from .base import SQLDialect +from . import dialects, sqltype_for + + +@dialects.register_for(Teradata) +class TeradataDialect(SQLDialect): + @sqltype_for('integer') + def type_integer(self): + return 'INT' + + @sqltype_for('text') + def type_text(self): + return 'VARCHAR(2000)' + + @sqltype_for('json') + def type_json(self): + return 'VARCHAR(4000)' + + @sqltype_for('float') + def type_float(self): + return 'REAL' + + @sqltype_for('list:integer') + def type_list_integer(self): + return self.types['json'] + + @sqltype_for('list:string') + def type_list_string(self): + return self.types['json'] + + @sqltype_for('list:reference') + def type_list_reference(self): + return self.types['json'] + + @sqltype_for('bigint') + def type_bigint(self): + return 'BIGINT' + + @sqltype_for('id') + def type_id(self): + return 'INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY NOT NULL' + + @sqltype_for('big-id') + def type_big_id(self): + return 'BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY NOT NULL' + + @sqltype_for('reference') + def type_reference(self): + return 'INT' + + @sqltype_for('big-reference') + def type_big_reference(self): + return 'BIGINT' + + @sqltype_for('geometry') + def type_geometry(self): + return 'ST_GEOMETRY' + + @sqltype_for('reference FK') + def type_reference_fk(self): + return ' REFERENCES %(foreign_key)s ' + + @sqltype_for('reference TFK') + def type_reference_tfk(self): + return ' FOREIGN KEY (%(field_name)s) REFERENCES %(foreign_table)s' + \ + ' (%(foreign_key)s)' + + def left_join(self, val, query_env={}): + # Left join must always have an ON clause + if not isinstance(val, basestring): + val = self.expand(val, query_env=query_env) + return 'LEFT OUTER JOIN %s' % val + + def select(self, fields, tables, where=None, groupby=None, having=None, + orderby=None, limitby=None, distinct=False, for_update=False): + dst, whr, grp, order, limit, offset, upd = '', '', '', '', '', '', '' + if distinct is True: + dst = ' DISTINCT' + elif distinct: + dst = ' DISTINCT ON (%s)' % distinct + if where: + whr = ' %s' % self.where(where) + if groupby: + grp = ' GROUP BY %s' % groupby + if having: + grp += ' HAVING %s' % having + if orderby: + order = ' ORDER BY %s' % orderby + if limitby: + (lmin, lmax) = limitby + limit = ' TOP %i' % lmax + if for_update: + upd = ' FOR UPDATE' + return 'SELECT%s%s %s FROM %s%s%s%s%s%s;' % ( + dst, limit, fields, tables, whr, grp, order, offset, upd) + + def truncate(self, table, mode=''): + return ['DELETE FROM %s ALL;' % table._rname] diff --git a/web2py/gluon/packages/dal/pydal/drivers.py b/web2py/gluon/packages/dal/pydal/drivers.py new file mode 100644 index 0000000..bf0bf7c --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/drivers.py @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- +from ._gae import gae + +DRIVERS = {} + +if gae is not None: + DRIVERS['google'] = gae + psycopg2_adapt = None + cx_Oracle = None + pyodbc = None + couchdb = None + is_jdbc = False + +try: + from pysqlite2 import dbapi2 as sqlite2 + DRIVERS['sqlite2'] = sqlite2 +except ImportError: + pass + +try: + from sqlite3 import dbapi2 as sqlite3 + DRIVERS['sqlite3'] = sqlite3 +except ImportError: + pass + +try: + import pymysql + DRIVERS['pymysql'] = pymysql +except ImportError: + pass + +try: + import MySQLdb + DRIVERS['MySQLdb'] = MySQLdb +except ImportError: + pass + +try: + import mysql.connector as mysqlconnector + DRIVERS["mysqlconnector"] = mysqlconnector +except ImportError: + pass + +try: + import psycopg2 + from psycopg2.extensions import adapt as psycopg2_adapt + DRIVERS['psycopg2'] = psycopg2 +except ImportError: + psycopg2_adapt = None + +try: + import pg8000 + DRIVERS['pg8000'] = pg8000 +except ImportError: + pass + +try: + import cx_Oracle + DRIVERS['cx_Oracle'] = cx_Oracle +except ImportError: + cx_Oracle = None + +try: + import pyodbc + DRIVERS['pyodbc'] = pyodbc + #DRIVERS.append('DB2(pyodbc)') + #DRIVERS.append('Teradata(pyodbc)') + #DRIVERS.append('Ingres(pyodbc)') +except ImportError: + try: + import pypyodbc as pyodbc + DRIVERS['pyodbc'] = pyodbc + except ImportError: + pyodbc = None + +try: + import ibm_db_dbi + DRIVERS['ibm_db_dbi'] = ibm_db_dbi +except ImportError: + pass +try: + import Sybase + DRIVERS['Sybase'] = Sybase +except ImportError: + pass + +try: + import kinterbasdb + DRIVERS['kinterbasdb'] = kinterbasdb + #DRIVERS.append('Firebird(kinterbasdb)') +except ImportError: + pass + +try: + import fdb + DRIVERS['fdb'] = fdb +except ImportError: + pass + +try: + import firebirdsql + DRIVERS['firebirdsql'] = firebirdsql +except ImportError: + pass + +try: + import informixdb + #LOGGER.warning('Informix support is experimental') + DRIVERS['informixdb'] = informixdb +except ImportError: + pass + +try: + import sapdb + DRIVERS['sapdb'] = sapdb + #LOGGER.warning('SAPDB support is experimental') +except ImportError: + pass + +try: + import cubriddb + DRIVERS['cubriddb'] = cubriddb + #LOGGER.warning('Cubrid support is experimental') +except ImportError: + pass + +try: + from com.ziclix.python.sql import zxJDBC + import java.sql + # Try sqlite jdbc driver from http://www.zentus.com/sqlitejdbc/ + from org.sqlite import JDBC # required by java.sql; ensure we have it + zxJDBC_sqlite = java.sql.DriverManager + DRIVERS['zxJDBC'] = zxJDBC + #DRIVERS.append('SQLite(zxJDBC)') + #LOGGER.warning('zxJDBC support is experimental') + is_jdbc = True +except ImportError: + is_jdbc = False + +try: + import couchdb + DRIVERS['couchdb'] = couchdb +except ImportError: + couchdb = None + +try: + import pymongo + DRIVERS['pymongo'] = pymongo +except: + pass + +try: + import imaplib + DRIVERS['imaplib'] = imaplib +except: + pass + + +# for backward compatibility? +def get_driver(name): + return DRIVERS.get(name) diff --git a/web2py/gluon/packages/dal/pydal/exceptions.py b/web2py/gluon/packages/dal/pydal/exceptions.py new file mode 100644 index 0000000..295b3f3 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/exceptions.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + + +class NotFoundException(Exception): + pass + + +class NotAuthorizedException(Exception): + pass + + +class NotOnNOSQLError(NotImplementedError): + def __init__(self, message=None): + if message is None: + message = "Not Supported on NoSQL databases" + super(NotOnNOSQLError, self).__init__(message) diff --git a/web2py/gluon/packages/dal/pydal/helpers/__init__.py b/web2py/gluon/packages/dal/pydal/helpers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web2py/gluon/packages/dal/pydal/helpers/_internals.py b/web2py/gluon/packages/dal/pydal/helpers/_internals.py new file mode 100644 index 0000000..9302c1b --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/helpers/_internals.py @@ -0,0 +1,35 @@ +class Dispatcher(object): + namespace = "dispatcher" + + def __init__(self, namespace=None): + self._registry_ = {} + if namespace: + self.namespace = namespace + + def register_for(self, target): + def wrap(dispatch_class): + self._registry_[target] = dispatch_class + return dispatch_class + return wrap + + def get_for(self, obj): + targets = type(obj).__mro__ + for target in targets: + if target in self._registry_: + return self._registry_[target](obj) + else: + raise ValueError( + "no %s found for object: %s" % (self.namespace, obj)) + + +class Cursor(object): + def __init__(self, connection): + self.connection = connection + self.cursor = connection.cursor() + self.release() + + def lock(self): + self.available = False + + def release(self): + self.available = True diff --git a/web2py/gluon/packages/dal/pydal/helpers/classes.py b/web2py/gluon/packages/dal/pydal/helpers/classes.py new file mode 100644 index 0000000..c19effb --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/helpers/classes.py @@ -0,0 +1,591 @@ +# -*- coding: utf-8 -*- +import copy +import marshal +import struct +import threading +import time +import traceback + +from .._compat import ( + PY2, exists, copyreg, implements_bool, iterkeys, itervalues, iteritems, + long +) +from .._globals import THREAD_LOCAL +from .serializers import serializers + + +class cachedprop(object): + #: a read-only @property that is only evaluated once. + def __init__(self, fget, doc=None): + self.fget = fget + self.__doc__ = doc or fget.__doc__ + self.__name__ = fget.__name__ + + def __get__(self, obj, cls): + if obj is None: + return self + obj.__dict__[self.__name__] = result = self.fget(obj) + return result + + +@implements_bool +class BasicStorage(object): + def __init__(self, *args, **kwargs): + return self.__dict__.__init__(*args, **kwargs) + + def __getitem__(self, key): + return self.__dict__.__getitem__(str(key)) + + __setitem__ = object.__setattr__ + + def __delitem__(self, key): + try: + delattr(self, key) + except AttributeError: + raise KeyError(key) + + def __bool__(self): + return len(self.__dict__) > 0 + + __iter__ = lambda self: self.__dict__.__iter__() + + __str__ = lambda self: self.__dict__.__str__() + + __repr__ = lambda self: self.__dict__.__repr__() + + has_key = __contains__ = lambda self, key: key in self.__dict__ + + def get(self, key, default=None): + return self.__dict__.get(key, default) + + def update(self, *args, **kwargs): + return self.__dict__.update(*args, **kwargs) + + def keys(self): + return self.__dict__.keys() + + def iterkeys(self): + return iterkeys(self.__dict__) + + def values(self): + return self.__dict__.values() + + def itervalues(self): + return itervalues(self.__dict__) + + def items(self): + return self.__dict__.items() + + def iteritems(self): + return iteritems(self.__dict__) + + pop = lambda self, *args, **kwargs: self.__dict__.pop(*args, **kwargs) + + clear = lambda self, *args, **kwargs: self.__dict__.clear(*args, **kwargs) + + copy = lambda self, *args, **kwargs: self.__dict__.copy(*args, **kwargs) + + +def pickle_basicstorage(s): + return BasicStorage, (dict(s),) + +copyreg.pickle(BasicStorage, pickle_basicstorage) + + +class OpRow(object): + __slots__ = ('_table', '_fields', '_values') + + def __init__(self, table): + object.__setattr__(self, '_table', table) + object.__setattr__(self, '_fields', {}) + object.__setattr__(self, '_values', {}) + + def set_value(self, key, value, field=None): + self._values[key] = value + self._fields[key] = self._fields.get(key, field or self._table[key]) + + def del_value(self, key): + del self._values[key] + del self._fields[key] + + def __getitem__(self, key): + return self._values[key] + + def __setitem__(self, key, value): + return self.set_value(key, value) + + def __delitem__(self, key): + return self.del_value(key) + + def __getattr__(self, key): + try: + return self[key] + except KeyError: + raise AttributeError + + def __setattr__(self, key, value): + return self.set_value(key, value) + + def __delattr__(self, key): + return self.del_value(key) + + def __iter__(self): + return self._values.__iter__() + + def __contains__(self, key): + return key in self._values + + def get(self, key, default=None): + try: + rv = self[key] + except KeyError: + rv = default + return rv + + def keys(self): + return self._values.keys() + + def iterkeys(self): + return iterkeys(self._values) + + def values(self): + return self._values.values() + + def itervalues(self): + return itervalues(self._values) + + def items(self): + return self._values.items() + + def iteritems(self): + return iteritems(self._values) + + def op_values(self): + return [ + (self._fields[key], value) + for key, value in iteritems(self._values) + ] + + def __repr__(self): + return '' % repr(self._values) + + +class ConnectionConfigurationMixin(object): + def _mock_reconnect(self): + self._reconnect_lock = threading.RLock() + self._connection_reconnect = self.reconnect + self.reconnect = self._reconnect_and_configure + self._reconnect_mocked = True + + def _reconnect_and_configure(self): + self._connection_reconnect() + with self._reconnect_lock: + if self._reconnect_mocked: + self._configure_on_first_reconnect() + self.reconnect = self._connection_reconnect + self._reconnect_mocked = False + + def _configure_on_first_reconnect(self): + pass + + +class Serializable(object): + def as_dict(self, flat=False, sanitize=True): + return self.__dict__ + + def as_xml(self, sanitize=True): + return serializers.xml(self.as_dict(flat=True, sanitize=sanitize)) + + def as_json(self, sanitize=True): + return serializers.json(self.as_dict(flat=True, sanitize=sanitize)) + + def as_yaml(self, sanitize=True): + return serializers.yaml(self.as_dict(flat=True, sanitize=sanitize)) + + +class Reference(long): + def __allocate(self): + if not self._record: + self._record = self._table[long(self)] + if not self._record: + raise RuntimeError( + "Using a recursive select but encountered a broken " + + "reference: %s %d" % (self._table, long(self)) + ) + + def __getattr__(self, key, default=None): + if key == 'id': + return long(self) + if key in self._table: + self.__allocate() + if self._record: + # to deal with case self.update_record() + return self._record.get(key, default) + else: + return None + + def get(self, key, default=None): + return self.__getattr__(key, default) + + def __setattr__(self, key, value): + if key.startswith('_'): + long.__setattr__(self, key, value) + return + self.__allocate() + self._record[key] = value + + def __getitem__(self, key): + if key == 'id': + return long(self) + self.__allocate() + return self._record.get(key, None) + + def __setitem__(self, key, value): + self.__allocate() + self._record[key] = value + + +def Reference_unpickler(data): + return marshal.loads(data) + + +def Reference_pickler(data): + try: + marshal_dump = marshal.dumps(long(data)) + except AttributeError: + marshal_dump = 'i%s' % struct.pack(' 0: + data, self.p = self.data[self.p:i], i + else: + data, self.p = self.data[self.p:], len(self.data) + return data + + def write(self, data): + self.data += data + + def close_connection(self): + if self.db is not None: + self.db.executesql( + "DELETE FROM web2py_filesystem WHERE path='%s'" % + self.filename + ) + query = "INSERT INTO web2py_filesystem(path,content) VALUES ('%s','%s')"\ + % (self.filename, self.data.replace("'", "''")) + self.db.executesql(query) + self.db.commit() + self.db = None + + def close(self): + self.close_connection() + + @staticmethod + def is_operational_error(db, error): + if not hasattr(db._adapter.driver, "OperationalError"): + return None + return isinstance(error, db._adapter.driver.OperationalError) + + @staticmethod + def is_programming_error(db, error): + if not hasattr(db._adapter.driver, "ProgrammingError"): + return None + return isinstance(error, db._adapter.driver.ProgrammingError) + + @staticmethod + def exists(db, filename): + if exists(filename): + return True + + DatabaseStoredFile.try_create_web2py_filesystem(db) + + query = "SELECT path FROM web2py_filesystem WHERE path='%s'" % filename + try: + if db.executesql(query): + return True + except Exception as e: + if not (DatabaseStoredFile.is_operational_error(db, e) or + DatabaseStoredFile.is_programming_error(db, e)): + raise + # no web2py_filesystem found? + tb = traceback.format_exc() + db.logger.error("Could not retrieve %s\n%s" % (filename, tb)) + return False diff --git a/web2py/gluon/packages/dal/pydal/helpers/gae.py b/web2py/gluon/packages/dal/pydal/helpers/gae.py new file mode 100644 index 0000000..f90ed4b --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/helpers/gae.py @@ -0,0 +1,36 @@ +import decimal +from .._gae import ndb + + +#TODO Needs more testing +class NDBDecimalProperty(ndb.StringProperty): + """ + NDB decimal implementation + """ + data_type = decimal.Decimal + + def __init__(self, precision, scale, **kwargs): + d = '1.' + for x in range(scale): + d += '0' + self.round = decimal.Decimal(d) + + def _to_base_type(self, value): + if value is None or value == '': + return None + else: + return str(value) + + def _from_base_type(self, value): + if value is None or value == '': + return None + else: + return decimal.Decimal(value).quantize(self.round) + + def _validate(self, value): + if value is None or isinstance(value, decimal.Decimal): + return value + elif isinstance(value, basestring): + return decimal.Decimal(value) + raise TypeError("Property %s must be a Decimal or string." + % self._name) diff --git a/web2py/gluon/packages/dal/pydal/helpers/methods.py b/web2py/gluon/packages/dal/pydal/helpers/methods.py new file mode 100644 index 0000000..821c7d4 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/helpers/methods.py @@ -0,0 +1,437 @@ +# -*- coding: utf-8 -*- + +import os +import re +import uuid +from .._compat import ( + PY2, BytesIO, iteritems, integer_types, string_types, to_bytes, pjoin, + exists +) +from .regex import REGEX_NOPASSWD, REGEX_UNPACK, REGEX_CONST_STRING, REGEX_W +from .classes import SQLCustomType + +UNIT_SEPARATOR = '\x1f' # ASCII unit separater for delimiting data + +PLURALIZE_RULES = [ + (re.compile('child$'), re.compile('child$'), 'children'), + (re.compile('oot$'), re.compile('oot$'), 'eet'), + (re.compile('ooth$'), re.compile('ooth$'), 'eeth'), + (re.compile('l[eo]af$'), re.compile('l([eo])af$'), 'l\\1aves'), + (re.compile('sis$'), re.compile('sis$'), 'ses'), + (re.compile('man$'), re.compile('man$'), 'men'), + (re.compile('ife$'), re.compile('ife$'), 'ives'), + (re.compile('eau$'), re.compile('eau$'), 'eaux'), + (re.compile('lf$'), re.compile('lf$'), 'lves'), + (re.compile('[sxz]$'), re.compile('$'), 'es'), + (re.compile('[^aeioudgkprt]h$'), re.compile('$'), 'es'), + (re.compile('(qu|[^aeiou])y$'), re.compile('y$'), 'ies'), + (re.compile('$'), re.compile('$'), 's'), + ] + + +def pluralize(singular, rules=PLURALIZE_RULES): + for line in rules: + re_search, re_sub, replace = line + plural = re_search.search(singular) and re_sub.sub(replace, singular) + if plural: return plural + + +def hide_password(uri): + if isinstance(uri, (list, tuple)): + return [hide_password(item) for item in uri] + return REGEX_NOPASSWD.sub('******', uri) + + +def cleanup(text): + """ + Validates that the given text is clean: only contains [0-9a-zA-Z_] + """ + # if not REGEX_ALPHANUMERIC.match(text): + # raise SyntaxError('invalid table or field name: %s' % text) + return text + + +def list_represent(values, row=None): + return ', '.join(str(v) for v in (values or [])) + + +def xorify(orderby): + if not orderby: + return None + orderby2 = orderby[0] + for item in orderby[1:]: + orderby2 = orderby2 | item + return orderby2 + + +def use_common_filters(query): + return (query and hasattr(query, 'ignore_common_filters') and \ + not query.ignore_common_filters) + + +def merge_tablemaps(*maplist): + """ + Merge arguments into a single dict, check for name collisions. + """ + maplist = list(maplist) + for i, item in enumerate(maplist): + if isinstance(item, dict): + maplist[i] = dict(**item) + ret = maplist[0] + for item in maplist[1:]: + if len(ret) > len(item): + big, small = ret, item + else: + big, small = item, ret + # Check for name collisions + for key, val in small.items(): + if big.get(key, val) is not val: + raise ValueError('Name conflict in table list: %s' % key) + # Merge + big.update(small) + ret = big + return ret + + +def bar_escape(item): + item = str(item).replace('|', '||') + if item.startswith('||'): item='%s%s' % (UNIT_SEPARATOR, item) + if item.endswith('||'): item='%s%s' % (item, UNIT_SEPARATOR) + return item + + +def bar_unescape(item): + item = item.replace('||','|') + if item.startswith(UNIT_SEPARATOR): item = item[1:] + if item.endswith(UNIT_SEPARATOR): item = item[:-1] + return item + + +def bar_encode(items): + return '|%s|' % '|'.join(bar_escape(item) for item in items if str(item).strip()) + + +def bar_decode_integer(value): + long = integer_types[-1] + if not hasattr(value, 'split') and hasattr(value, 'read'): + value = value.read() + return [long(x) for x in value.split('|') if x.strip()] + + +def bar_decode_string(value): + return [bar_unescape(x) for x in REGEX_UNPACK.split(value[1:-1]) if x.strip()] + + +def archive_record(qset, fs, archive_table, current_record): + tablenames = qset.db._adapter.tables(qset.query) + if len(tablenames) != 1: + raise RuntimeError("cannot update join") + for row in qset.select(): + fields = archive_table._filter_fields(row) + for k, v in iteritems(fs): + if fields[k] != v: + fields[current_record] = row.id + archive_table.insert(**fields) + break + return False + + +def smart_query(fields, text): + from ..objects import Field, Table + if not isinstance(fields, (list, tuple)): + fields = [fields] + new_fields = [] + for field in fields: + if isinstance(field, Field): + new_fields.append(field) + elif isinstance(field, Table): + for ofield in field: + new_fields.append(ofield) + else: + raise RuntimeError("fields must be a list of fields") + fields = new_fields + field_map = {} + for field in fields: + n = field.name.lower() + if not n in field_map: + field_map[n] = field + n = str(field).lower() + if not n in field_map: + field_map[n] = field + constants = {} + i = 0 + while True: + m = REGEX_CONST_STRING.search(text) + if not m: break + text = text[:m.start()]+('#%i' % i)+text[m.end():] + constants[str(i)] = m.group()[1:-1] + i += 1 + text = re.sub('\s+', ' ', text).lower() + for a, b in [('&', 'and'), + ('|', 'or'), + ('~', 'not'), + ('==', '='), + ('<', '<'), + ('>', '>'), + ('<=', '<='), + ('>=', '>='), + ('<>', '!='), + ('=<', '<='), + ('=>', '>='), + ('=', '='), + (' less or equal than ', '<='), + (' greater or equal than ', '>='), + (' equal or less than ', '<='), + (' equal or greater than ', '>='), + (' less or equal ', '<='), + (' greater or equal ', '>='), + (' equal or less ', '<='), + (' equal or greater ', '>='), + (' not equal to ', '!='), + (' not equal ', '!='), + (' equal to ', '='), + (' equal ', '='), + (' equals ', '='), + (' less than ', '<'), + (' greater than ', '>'), + (' starts with ', 'startswith'), + (' ends with ', 'endswith'), + (' not in ', 'notbelongs'), + (' in ', 'belongs'), + (' is ', '=')]: + if a[0] == ' ': + text = text.replace(' is'+a, ' %s ' % b) + text = text.replace(a, ' %s ' % b) + text = re.sub('\s+', ' ', text).lower() + text = re.sub('(?P[\<\>\!\=])\s+(?P[\<\>\!\=])', '\g\g', text) + query = field = neg = op = logic = None + for item in text.split(): + if field is None: + if item == 'not': + neg = True + elif not neg and not logic and item in ('and', 'or'): + logic = item + elif item in field_map: + field = field_map[item] + else: + raise RuntimeError("Invalid syntax") + elif not field is None and op is None: + op = item + elif not op is None: + if item.startswith('#'): + if not item[1:] in constants: + raise RuntimeError("Invalid syntax") + value = constants[item[1:]] + else: + value = item + if field.type in ('text', 'string', 'json'): + if op == '=': op = 'like' + if op == '=': new_query = field == value + elif op == '<': new_query = field < value + elif op == '>': new_query = field > value + elif op == '<=': new_query = field <= value + elif op == '>=': new_query = field >= value + elif op == '!=': new_query = field != value + elif op == 'belongs': new_query = field.belongs(value.split(',')) + elif op == 'notbelongs': new_query = ~field.belongs(value.split(',')) + elif field.type == 'list:string': + if op == 'contains': new_query = field.contains(value) + else: raise RuntimeError("Invalid operation") + elif field.type in ('text', 'string', 'json', 'upload'): + if op == 'contains': new_query = field.contains(value) + elif op == 'like': new_query = field.ilike(value) + elif op == 'startswith': new_query = field.startswith(value) + elif op == 'endswith': new_query = field.endswith(value) + else: raise RuntimeError("Invalid operation") + elif field._db._adapter.dbengine=='google:datastore' and \ + field.type in ('list:integer', 'list:string', 'list:reference'): + if op == 'contains': new_query = field.contains(value) + else: raise RuntimeError("Invalid operation") + else: raise RuntimeError("Invalid operation") + if neg: new_query = ~new_query + if query is None: + query = new_query + elif logic == 'and': + query &= new_query + elif logic == 'or': + query |= new_query + field = op = neg = logic = None + return query + + +def auto_validators(field): + db = field.db + field_type = field.type + #: don't apply default validation on custom types + if isinstance(field_type, SQLCustomType): + if hasattr(field_type, 'validator'): + return field_type.validator + else: + field_type = field_type.type + elif not isinstance(field_type, str): + return [] + #: if a custom method is provided, call it + if callable(db.validators_method): + return db.validators_method(field) + #: apply validators from validators dict if present + if not db.validators or not isinstance(db.validators, dict): + return [] + field_validators = db.validators.get(field_type, []) + if not isinstance(field_validators, (list, tuple)): + field_validators = [field_validators] + return field_validators + + +def _fieldformat(r, id): + row = r(id) + if not row: + return str(id) + elif hasattr(r, '_format') and isinstance(r._format, str): + return r._format % row + elif hasattr(r, '_format') and callable(r._format): + return r._format(row) + else: + return str(id) + + +class _repr_ref(object): + def __init__(self, ref=None): + self.ref = ref + + def __call__(self, value, row=None): + return value if value is None else _fieldformat(self.ref, value) + + +class _repr_ref_list(_repr_ref): + def __call__(self, value, row=None): + if not value: + return None + refs = None + db, id = self.ref._db, self.ref._id + if db._adapter.dbengine == 'google:datastore': + def count(values): + return db(id.belongs(values)).select(id) + rx = range(0, len(value), 30) + refs = reduce(lambda a, b: a & b, [count(value[i:i+30]) + for i in rx]) + else: + refs = db(id.belongs(value)).select(id) + return refs and ', '.join( + _fieldformat(self.ref, x) for x in value) or '' + + +def auto_represent(field): + if field.represent: + return field.represent + if field.db and field.type.startswith('reference') and \ + field.type.find('.') < 0 and field.type[10:] in field.db.tables: + referenced = field.db[field.type[10:]] + return _repr_ref(referenced) + elif field.db and field.type.startswith('list:reference') and \ + field.type.find('.') < 0 and field.type[15:] in field.db.tables: + referenced = field.db[field.type[15:]] + return _repr_ref_list(referenced) + return field.represent + + +def varquote_aux(name, quotestr='%s'): + return name if REGEX_W.match(name) else quotestr % name + + +def uuid2int(uuidv): + return uuid.UUID(uuidv).int + + +def int2uuid(n): + return str(uuid.UUID(int=n)) + + +# Geodal utils +def geoPoint(x, y): + return "POINT (%f %f)" % (x, y) + + +def geoLine(*line): + return "LINESTRING (%s)" % ','.join("%f %f" % item for item in line) + + +def geoPolygon(*line): + return "POLYGON ((%s))" % ','.join("%f %f" % item for item in line) + + +# upload utils +def attempt_upload(table, fields): + for fieldname in table._upload_fieldnames & set(fields): + value = fields[fieldname] + if not (value is None or isinstance(value, string_types)): + if not PY2 and isinstance(value, bytes): + continue + if hasattr(value, 'file') and hasattr(value, 'filename'): + new_name = table[fieldname].store( + value.file, filename=value.filename) + elif isinstance(value, dict): + if 'data' in value and 'filename' in value: + stream = BytesIO(to_bytes(value['data'])) + new_name = table[fieldname].store( + stream, filename=value['filename']) + else: + new_name = None + elif hasattr(value, 'read') and hasattr(value, 'name'): + new_name = table[fieldname].store(value, filename=value.name) + else: + raise RuntimeError("Unable to handle upload") + fields[fieldname] = new_name + + +def attempt_upload_on_insert(table): + def wrapped(fields): + return attempt_upload(table, fields) + return wrapped + + +def attempt_upload_on_update(table): + def wrapped(dbset, fields): + return attempt_upload(table, fields) + return wrapped + + +def delete_uploaded_files(dbset, upload_fields=None): + table = dbset.db._adapter.tables(dbset.query).popitem()[1] + # ## mind uploadfield==True means file is not in DB + if upload_fields: + fields = list(upload_fields) + # Explicitly add compute upload fields (ex: thumbnail) + fields += [f for f in table.fields if table[f].compute is not None] + else: + fields = table.fields + fields = [ + f for f in fields if table[f].type == 'upload' and + table[f].uploadfield == True and table[f].autodelete + ] + if not fields: + return False + for record in dbset.select(*[table[f] for f in fields]): + for fieldname in fields: + field = table[fieldname] + oldname = record.get(fieldname, None) + if not oldname: + continue + if upload_fields and fieldname in upload_fields and \ + oldname == upload_fields[fieldname]: + continue + if field.custom_delete: + field.custom_delete(oldname) + else: + uploadfolder = field.uploadfolder + if not uploadfolder: + uploadfolder = pjoin( + dbset.db._adapter.folder, '..', 'uploads') + if field.uploadseparate: + items = oldname.split('.') + uploadfolder = pjoin( + uploadfolder, "%s.%s" % + (items[0], items[1]), items[2][:2]) + oldpath = pjoin(uploadfolder, oldname) + if exists(oldpath): + os.unlink(oldpath) + return False diff --git a/web2py/gluon/packages/dal/pydal/helpers/regex.py b/web2py/gluon/packages/dal/pydal/helpers/regex.py new file mode 100644 index 0000000..21d0c9e --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/helpers/regex.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +import re + +REGEX_TYPE = re.compile('^([\w\_\:]+)') +REGEX_DBNAME = re.compile('^(\w+)(\:\w+)*') +REGEX_W = re.compile('^\w+$') +REGEX_TABLE_DOT_FIELD = re.compile('^(\w+)\.([^.]+)$') +REGEX_NO_GREEDY_ENTITY_NAME = r'(.+?)' +REGEX_UPLOAD_PATTERN = re.compile('(?P
    [\w\-]+)\.(?P[\w\-]+)\.(?P[\w\-]+)(\.(?P\w+))?\.\w+$') +REGEX_CLEANUP_FN = re.compile('[\'"\s;]+') +REGEX_UNPACK = re.compile('(?\w{1,5})$') +REGEX_QUOTES = re.compile("'[^']*'") +REGEX_ALPHANUMERIC = re.compile('^[0-9a-zA-Z]\w*$') +REGEX_PASSWORD = re.compile('\://([^:@]*)\:') +REGEX_NOPASSWD = re.compile('\/\/[\w\.\-]+[\:\/](.+)(?=@)') # was '(?<=[\:\/])([^:@/]+)(?=@.+)' +REGEX_VALID_TB_FLD = re.compile(r'^[^\d_][_0-9a-zA-Z]*\Z') diff --git a/web2py/gluon/packages/dal/pydal/helpers/rest.py b/web2py/gluon/packages/dal/pydal/helpers/rest.py new file mode 100644 index 0000000..d3e3a43 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/helpers/rest.py @@ -0,0 +1,316 @@ +from .regex import REGEX_SEARCH_PATTERN, REGEX_SQUARE_BRACKETS +from .._compat import long + +def to_num(num): + result = 0 + try: + result = long(num) + except NameError as e: + result = int(num) + return result + +class RestParser(object): + def __init__(self, db): + self.db = db + + def auto_table(self, table, base='', depth=0): + patterns = [] + for field in self.db[table].fields: + if base: + tag = '%s/%s' % (base, field.replace('_', '-')) + else: + tag = '/%s/%s' % ( + table.replace('_', '-'), field.replace('_', '-')) + f = self.db[table][field] + if not f.readable: + continue + if f.type == 'id' or 'slug' in field or \ + f.type.startswith('reference'): + tag += '/{%s.%s}' % (table, field) + patterns.append(tag) + patterns.append(tag+'/:field') + elif f.type.startswith('boolean'): + tag += '/{%s.%s}' % (table, field) + patterns.append(tag) + patterns.append(tag+'/:field') + elif f.type in ('float', 'double', 'integer', 'bigint'): + tag += '/{%s.%s.ge}/{%s.%s.lt}' % (table, field, table, field) + patterns.append(tag) + patterns.append(tag+'/:field') + elif f.type.startswith('list:'): + tag += '/{%s.%s.contains}' % (table, field) + patterns.append(tag) + patterns.append(tag+'/:field') + elif f.type in ('date', 'datetime'): + tag += '/{%s.%s.year}' % (table, field) + patterns.append(tag) + patterns.append(tag+'/:field') + tag += '/{%s.%s.month}' % (table, field) + patterns.append(tag) + patterns.append(tag+'/:field') + tag += '/{%s.%s.day}' % (table, field) + patterns.append(tag) + patterns.append(tag+'/:field') + if f.type in ('datetime', 'time'): + tag += '/{%s.%s.hour}' % (table, field) + patterns.append(tag) + patterns.append(tag+'/:field') + tag += '/{%s.%s.minute}' % (table, field) + patterns.append(tag) + patterns.append(tag+'/:field') + tag += '/{%s.%s.second}' % (table, field) + patterns.append(tag) + patterns.append(tag+'/:field') + if depth > 0: + for f in self.db[table]._referenced_by: + tag += '/%s[%s.%s]' % (table, f.tablename, f.name) + patterns.append(tag) + patterns += self.auto_table(table, base=tag, depth=depth-1) + return patterns + + def parse(self, patterns, args, vars, queries=None, nested_select=True): + """ + Example: + Use as:: + + db.define_table('person',Field('name'),Field('info')) + db.define_table('pet', + Field('ownedby',db.person), + Field('name'),Field('info') + ) + + @request.restful() + def index(): + def GET(*args,**vars): + patterns = [ + "/friends[person]", + "/{person.name}/:field", + "/{person.name}/pets[pet.ownedby]", + "/{person.name}/pets[pet.ownedby]/{pet.name}", + "/{person.name}/pets[pet.ownedby]/{pet.name}/:field", + ("/dogs[pet]", db.pet.info=='dog'), + ("/dogs[pet]/{pet.name.startswith}", db.pet.info=='dog'), + ] + parser = db.parse_as_rest(patterns,args,vars) + if parser.status == 200: + return dict(content=parser.response) + else: + raise HTTP(parser.status,parser.error) + + def POST(table_name,**vars): + if table_name == 'person': + return db.person.validate_and_insert(**vars) + elif table_name == 'pet': + return db.pet.validate_and_insert(**vars) + else: + raise HTTP(400) + return locals() + """ + + re1 = REGEX_SEARCH_PATTERN + re2 = REGEX_SQUARE_BRACKETS + + if patterns == 'auto': + patterns = [] + for table in self.db.tables: + if not table.startswith('auth_'): + patterns.append('/%s[%s]' % (table, table)) + patterns += self.auto_table(table, base='', depth=1) + else: + i = 0 + while i < len(patterns): + pattern = patterns[i] + if not isinstance(pattern, str): + pattern = pattern[0] + tokens = pattern.split('/') + if tokens[-1].startswith(':auto') and re2.match(tokens[-1]): + new_patterns = self.auto_table( + tokens[-1][tokens[-1].find('[')+1:-1], + '/'.join(tokens[:-1])) + patterns = patterns[:i]+new_patterns+patterns[i+1:] + i += len(new_patterns) + else: + i += 1 + if '/'.join(args) == 'patterns': + return self.db.Row({ + 'status': 200, 'pattern': 'list', 'error': None, + 'response': patterns}) + for pattern in patterns: + basequery, exposedfields = None, [] + if isinstance(pattern, tuple): + if len(pattern) == 2: + pattern, basequery = pattern + elif len(pattern) > 2: + pattern, basequery, exposedfields = pattern[0:3] + otable = table = None + if not isinstance(queries, dict): + dbset = self.db(queries) + if basequery is not None: + dbset = dbset(basequery) + i = 0 + tags = pattern[1:].split('/') + if len(tags) != len(args): + continue + for tag in tags: + if re1.match(tag): + tokens = tag[1:-1].split('.') + table, field = tokens[0], tokens[1] + if not otable or table == otable: + if len(tokens) == 2 or tokens[2] == 'eq': + query = self.db[table][field] == args[i] + elif tokens[2] == 'ne': + query = self.db[table][field] != args[i] + elif tokens[2] == 'lt': + query = self.db[table][field] < args[i] + elif tokens[2] == 'gt': + query = self.db[table][field] > args[i] + elif tokens[2] == 'ge': + query = self.db[table][field] >= args[i] + elif tokens[2] == 'le': + query = self.db[table][field] <= args[i] + elif tokens[2] == 'year': + query = self.db[table][field].year() == args[i] + elif tokens[2] == 'month': + query = self.db[table][field].month() == args[i] + elif tokens[2] == 'day': + query = self.db[table][field].day() == args[i] + elif tokens[2] == 'hour': + query = self.db[table][field].hour() == args[i] + elif tokens[2] == 'minute': + query = self.db[table][field].minutes() == args[i] + elif tokens[2] == 'second': + query = self.db[table][field].seconds() == args[i] + elif tokens[2] == 'startswith': + query = self.db[table][field].startswith(args[i]) + elif tokens[2] == 'contains': + query = self.db[table][field].contains(args[i]) + else: + raise RuntimeError("invalid pattern: %s" % pattern) + if len(tokens) == 4 and tokens[3] == 'not': + query = ~query + elif len(tokens) >= 4: + raise RuntimeError("invalid pattern: %s" % pattern) + if not otable and isinstance(queries, dict): + dbset = self.db(queries[table]) + if basequery is not None: + dbset = dbset(basequery) + dbset = dbset(query) + else: + raise RuntimeError( + "missing relation in pattern: %s" % pattern) + elif re2.match(tag) and args[i] == tag[:tag.find('[')]: + ref = tag[tag.find('[')+1:-1] + if '.' in ref and otable: + table, field = ref.split('.') + selfld = '_id' + if self.db[table][field].type.startswith('reference '): + refs = [ + x.name for x in self.db[otable] + if x.type == self.db[table][field].type] + else: + refs = [ + x.name for x in self.db[table]._referenced_by + if x.tablename == otable] + if refs: + selfld = refs[0] + if nested_select: + try: + dbset = self.db(self.db[table][field].belongs( + dbset._select(self.db[otable][selfld]))) + except ValueError: + return self.db.Row({ + 'status': 400, 'pattern': pattern, + 'error': 'invalid path', 'response': None}) + else: + items = [ + item.id for item in dbset.select( + self.db[otable][selfld]) + ] + dbset = self.db( + self.db[table][field].belongs(items)) + else: + table = ref + if not otable and isinstance(queries, dict): + dbset = self.db(queries[table]) + dbset = dbset(self.db[table]) + elif tag == ':field' and table: + # print 're3:'+tag + field = args[i] + if field not in self.db[table]: + break + # hand-built patterns should respect .readable=False as well + if not self.db[table][field].readable: + return self.db.Row({ + 'status': 418, 'pattern': pattern, + 'error': 'I\'m a teapot', 'response': None}) + try: + distinct = vars.get('distinct', False) == 'True' + offset = to_num(vars.get('offset', None) or 0) + limits = ( + offset, + to_num(vars.get('limit', None) or 1000) + offset) + except ValueError: + return self.db.Row({ + 'status': 400, 'error': 'invalid limits', + 'response': None}) + items = dbset.select( + self.db[table][field], distinct=distinct, + limitby=limits) + if items: + return self.db.Row({ + 'status': 200, 'response': items, + 'pattern': pattern}) + else: + return self.db.Row({ + 'status': 404, 'pattern': pattern, + 'error': 'no record found', ' response': None}) + elif tag != args[i]: + break + otable = table + i += 1 + if i == len(tags) and table: + if hasattr(self.db[table], '_id'): + ofields = vars.get( + 'order', self.db[table]._id.name).split('|') + else: + ofields = vars.get( + 'order', self.db[table]._primarykey[0]).split('|') + try: + orderby = [ + self.db[table][f] if not f.startswith('~') + else ~self.db[table][f[1:]] for f in ofields] + except (KeyError, AttributeError): + return self.db.Row({ + 'status': 400, 'error': 'invalid orderby', + 'response': None}) + if exposedfields: + fields = [ + field for field in self.db[table] + if str(field).split('.')[-1] in exposedfields and + field.readable] + else: + fields = [ + field for field in self.db[table] + if field.readable] + count = dbset.count() + try: + offset = to_num(vars.get('offset', None) or 0) + limits = ( + offset, + to_num(vars.get('limit', None) or 1000) + offset) + except ValueError: + return self.db.Row({ + 'status': 400, 'error': ' invalid limits', + 'response': None}) + try: + response = dbset.select( + limitby=limits, orderby=orderby, *fields) + except ValueError: + return self.db.Row({ + 'status': 400, 'pattern': pattern, + 'error': 'invalid path', 'response': None}) + return self.db.Row({ + 'status': 200, 'response': response, + 'pattern': pattern, 'count': count}) + return self.db.Row({ + 'status': 400, 'error': 'no matching pattern', 'response': None}) diff --git a/web2py/gluon/packages/dal/pydal/helpers/serializers.py b/web2py/gluon/packages/dal/pydal/helpers/serializers.py new file mode 100644 index 0000000..538223f --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/helpers/serializers.py @@ -0,0 +1,57 @@ +import datetime +import decimal +import json as jsonlib +from .._compat import PY2, integer_types + +long = integer_types[-1] + + +class Serializers(object): + _custom_ = {} + + def _json_parse(self, o): + if hasattr(o, 'custom_json') and callable(o.custom_json): + return o.custom_json() + if isinstance(o, (datetime.date, + datetime.datetime, + datetime.time)): + return o.isoformat()[:19].replace('T', ' ') + elif isinstance(o, long): + return int(o) + elif isinstance(o, decimal.Decimal): + return str(o) + elif isinstance(o, set): + return list(o) + elif hasattr(o, 'as_list') and callable(o.as_list): + return o.as_list() + elif hasattr(o, 'as_dict') and callable(o.as_dict): + return o.as_dict() + if self._custom_.get('json') is not None: + return self._custom_['json'](o) + raise TypeError(repr(o) + " is not JSON serializable") + + def __getattr__(self, name): + if self._custom_.get(name) is not None: + return self._custom_[name] + raise NotImplementedError("No "+str(name)+" serializer available.") + + def json(self, value): + value = jsonlib.dumps(value, default=self._json_parse) + rep28 = r'\u2028' + rep29 = r'\2029' + if PY2: + rep28 = rep28.decode('raw_unicode_escape') + rep29 = rep29.decode('raw_unicode_escape') + return value.replace(rep28, '\\u2028').replace(rep29, '\\u2029') + + def yaml(self, value): + if self._custom_.get('yaml') is not None: + return self._custom_.get('yaml')(value) + try: + from yaml import dump + except ImportError: + raise NotImplementedError("No yaml serializer available.") + return dump(value) + + +serializers = Serializers() diff --git a/web2py/gluon/packages/dal/pydal/migrator.py b/web2py/gluon/packages/dal/pydal/migrator.py new file mode 100644 index 0000000..be203b2 --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/migrator.py @@ -0,0 +1,527 @@ +import copy +import datetime +import locale +import os +import pickle +import sys +from ._compat import PY2, string_types, pjoin, iteritems, to_bytes, exists +from ._load import portalocker +from .helpers.classes import SQLCustomType, DatabaseStoredFile + + +class Migrator(object): + def __init__(self, adapter): + self.adapter = adapter + + @property + def db(self): + return self.adapter.db + + @property + def dialect(self): + return self.adapter.dialect + + @property + def dbengine(self): + return self.adapter.dbengine + + def create_table(self, table, migrate=True, fake_migrate=False, + polymodel=None): + db = table._db + table._migrate = migrate + fields = [] + # PostGIS geo fields are added after the table has been created + postcreation_fields = [] + sql_fields = {} + sql_fields_aux = {} + TFK = {} + tablename = table._tablename + types = self.adapter.types + for sortable, field in enumerate(table, start=1): + field_name = field.name + field_type = field.type + if isinstance(field_type, SQLCustomType): + ftype = field_type.native or field_type.type + elif field_type.startswith(('reference', 'big-reference')): + if field_type.startswith('reference'): + referenced = field_type[10:].strip() + type_name = 'reference' + else: + referenced = field_type[14:].strip() + type_name = 'big-reference' + + if referenced == '.': + referenced = tablename + constraint_name = self.dialect.constraint_name( + table._raw_rname, field._raw_rname) + # if not '.' in referenced \ + # and referenced != tablename \ + # and hasattr(table,'_primarykey'): + # ftype = types['integer'] + #else: + try: + rtable = db[referenced] + rfield = rtable._id + rfieldname = rfield.name + rtablename = referenced + except (KeyError, ValueError, AttributeError) as e: + self.db.logger.debug('Error: %s' % e) + try: + rtablename, rfieldname = referenced.split('.') + rtable = db[rtablename] + rfield = rtable[rfieldname] + except Exception as e: + self.db.logger.debug('Error: %s' % e) + raise KeyError( + 'Cannot resolve reference %s in %s definition' % ( + referenced, table._tablename)) + + # must be PK reference or unique + if getattr(rtable, '_primarykey', None) and rfieldname in \ + rtable._primarykey or rfield.unique: + ftype = types[rfield.type[:9]] % \ + dict(length=rfield.length) + # multicolumn primary key reference? + if not rfield.unique and len(rtable._primarykey) > 1: + # then it has to be a table level FK + if rtablename not in TFK: + TFK[rtablename] = {} + TFK[rtablename][rfieldname] = field_name + else: + fk = rtable._rname + ' (' + rfield._rname + ')' + ftype = ftype + \ + types['reference FK'] % dict( + # should be quoted + constraint_name=constraint_name, + foreign_key=fk, + table_name=table._rname, + field_name=field._rname, + on_delete_action=field.ondelete) + else: + # make a guess here for circular references + if referenced in db: + id_fieldname = db[referenced]._id._rname + elif referenced == tablename: + id_fieldname = table._id._rname + else: # make a guess + id_fieldname = self.dialect.quote('id') + #gotcha: the referenced table must be defined before + #the referencing one to be able to create the table + #Also if it's not recommended, we can still support + #references to tablenames without rname to make + #migrations and model relationship work also if tables + #are not defined in order + if referenced == tablename: + real_referenced = db[referenced]._rname + else: + real_referenced = ( + referenced in db and db[referenced]._rname or + referenced) + rfield = db[referenced]._id + ftype_info = dict( + index_name=self.dialect.quote(field._raw_rname+'__idx'), + field_name=field._rname, + constraint_name=self.dialect.quote(constraint_name), + foreign_key='%s (%s)' % ( + real_referenced, rfield._rname), + on_delete_action=field.ondelete) + ftype_info['null'] = ' NOT NULL' if field.notnull else \ + self.dialect.allow_null + ftype_info['unique'] = ' UNIQUE' if field.unique else '' + ftype = types[type_name] % ftype_info + elif field_type.startswith('list:reference'): + ftype = types[field_type[:14]] + elif field_type.startswith('decimal'): + precision, scale = map(int, field_type[8:-1].split(',')) + ftype = types[field_type[:7]] % \ + dict(precision=precision, scale=scale) + elif field_type.startswith('geo'): + if not hasattr(self.adapter, 'srid'): + raise RuntimeError('Adapter does not support geometry') + srid = self.adapter.srid + geotype, parms = field_type[:-1].split('(') + if geotype not in types: + raise SyntaxError( + 'Field: unknown field type: %s for %s' % ( + field_type, field_name)) + ftype = types[geotype] + if self.dbengine == 'postgres' and geotype == 'geometry': + if self.db._ignore_field_case is True: + field_name = field_name.lower() + # parameters: schema, srid, dimension + dimension = 2 # GIS.dimension ??? + parms = parms.split(',') + if len(parms) == 3: + schema, srid, dimension = parms + elif len(parms) == 2: + schema, srid = parms + else: + schema = parms[0] + ftype = "SELECT AddGeometryColumn ('%%(schema)s', '%%(tablename)s', '%%(fieldname)s', %%(srid)s, '%s', %%(dimension)s);" % types[geotype] + ftype = ftype % dict(schema=schema, + tablename=table._raw_rname, + fieldname=field._raw_rname, srid=srid, + dimension=dimension) + postcreation_fields.append(ftype) + elif field_type not in types: + raise SyntaxError('Field: unknown field type: %s for %s' % ( + field_type, field_name)) + else: + ftype = types[field_type] % {'length': field.length} + + if not field_type.startswith(('id', 'reference', 'big-reference')): + if field.notnull: + ftype += ' NOT NULL' + else: + ftype += self.dialect.allow_null + if field.unique: + ftype += ' UNIQUE' + if field.custom_qualifier: + ftype += ' %s' % field.custom_qualifier + + # add to list of fields + sql_fields[field_name] = dict( + length=field.length, + unique=field.unique, + notnull=field.notnull, + sortable=sortable, + type=str(field_type), + sql=ftype, + rname=field._rname, + raw_rname=field._raw_rname) + + if field.notnull and field.default is not None: + # Caveat: sql_fields and sql_fields_aux + # differ for default values. + # sql_fields is used to trigger migrations and sql_fields_aux + # is used for create tables. + # The reason is that we do not want to trigger + # a migration simply because a default value changes. + not_null = self.dialect.not_null(field.default, field_type) + ftype = ftype.replace('NOT NULL', not_null) + sql_fields_aux[field_name] = dict(sql=ftype) + # Postgres - PostGIS: + # geometry fields are added after the table has been created, not now + if not (self.dbengine == 'postgres' and + field_type.startswith('geom')): + fields.append('%s %s' % (field._rname, ftype)) + other = ';' + + # backend-specific extensions to fields + if self.dbengine == 'mysql': + if not hasattr(table, "_primarykey"): + fields.append('PRIMARY KEY (%s)' % (table._id._rname)) + engine = self.adapter.adapter_args.get('engine', 'InnoDB') + other = ' ENGINE=%s CHARACTER SET utf8;' % engine + + fields = ',\n '.join(fields) + for rtablename in TFK: + rtable = db[rtablename] + rfields = TFK[rtablename] + pkeys = [rtable[pk]._rname for pk in rtable._primarykey] + fk_fields = [table[rfields[k]] for k in rtable._primarykey] + fkeys = [f._rname for f in fk_fields] + constraint_name = self.dialect.constraint_name( + table._raw_rname, '_'.join(f._raw_rname for f in fk_fields)) + on_delete = list(set(f.ondelete for f in fk_fields)) + if len(on_delete) > 1: + raise SyntaxError('Table %s has incompatible ON DELETE actions in multi-field foreign key.' % table._dalname) + fields = fields + ',\n ' + \ + types['reference TFK'] % dict( + constraint_name=constraint_name, + table_name=table._rname, + field_name=', '.join(fkeys), + foreign_table=rtable._rname, + foreign_key=', '.join(pkeys), + on_delete_action=on_delete[0]) + + if getattr(table, '_primarykey', None): + query = "CREATE TABLE %s(\n %s,\n %s) %s" % \ + (table._rname, fields, + self.dialect.primary_key(', '.join([ + table[pk]._rname + for pk in table._primarykey])), other) + else: + query = "CREATE TABLE %s(\n %s\n)%s" % \ + (table._rname, fields, other) + + uri = self.adapter.uri + if uri.startswith('sqlite:///') \ + or uri.startswith('spatialite:///'): + if PY2: + path_encoding = sys.getfilesystemencoding() \ + or locale.getdefaultlocale()[1] or 'utf8' + dbpath = uri[9:uri.rfind('/')].decode( + 'utf8').encode(path_encoding) + else: + dbpath = uri[9:uri.rfind('/')] + else: + dbpath = self.adapter.folder + + if not migrate: + return query + elif uri.startswith('sqlite:memory') or \ + uri.startswith('spatialite:memory'): + table._dbt = None + elif isinstance(migrate, string_types): + table._dbt = pjoin(dbpath, migrate) + else: + table._dbt = pjoin( + dbpath, '%s_%s.table' % (db._uri_hash, tablename)) + + if not table._dbt or not self.file_exists(table._dbt): + if table._dbt: + self.log('timestamp: %s\n%s\n' + % (datetime.datetime.today().isoformat(), + query), table) + if not fake_migrate: + self.adapter.create_sequence_and_triggers(query, table) + db.commit() + # Postgres geom fields are added now, + # after the table has been created + for query in postcreation_fields: + self.adapter.execute(query) + db.commit() + if table._dbt: + tfile = self.file_open(table._dbt, 'wb') + pickle.dump(sql_fields, tfile) + self.file_close(tfile) + if fake_migrate: + self.log('faked!\n', table) + else: + self.log('success!\n', table) + else: + tfile = self.file_open(table._dbt, 'rb') + try: + sql_fields_old = pickle.load(tfile) + except EOFError: + self.file_close(tfile) + raise RuntimeError('File %s appears corrupted' % table._dbt) + self.file_close(tfile) + # add missing rnames + for key, item in sql_fields_old.items(): + tmp = sql_fields.get(key) + if tmp: + item.setdefault('rname', tmp['rname']) + item.setdefault('raw_rname', tmp['raw_rname']) + else: + item.setdefault('rname', self.dialect.quote(key)) + item.setdefault('raw_rname', key) + if sql_fields != sql_fields_old: + self.migrate_table( + table, + sql_fields, sql_fields_old, + sql_fields_aux, None, + fake_migrate=fake_migrate + ) + return query + + def _fix(self, item): + k, v = item + if not isinstance(v, dict): + v = dict(type='unknown', sql=v) + if self.db._ignore_field_case is not True: + return k, v + return k.lower(), v + + def migrate_table(self, table, sql_fields, sql_fields_old, sql_fields_aux, + logfile, fake_migrate=False): + # logfile is deprecated (moved to adapter.log method) + db = table._db + db._migrated.append(table._tablename) + tablename = table._tablename + if self.dbengine in ('firebird',): + drop_expr = 'ALTER TABLE %s DROP %s;' + else: + drop_expr = 'ALTER TABLE %s DROP COLUMN %s;' + field_types = dict((x.lower(), table[x].type) + for x in sql_fields.keys() if x in table) + # make sure all field names are lower case to avoid + # migrations because of case change + sql_fields = dict(map(self._fix, iteritems(sql_fields))) + sql_fields_old = dict(map(self._fix, iteritems(sql_fields_old))) + sql_fields_aux = dict(map(self._fix, iteritems(sql_fields_aux))) + if db._debug: + db.logger.debug('migrating %s to %s' % ( + sql_fields_old, sql_fields)) + + keys = list(sql_fields.keys()) + for key in sql_fields_old: + if key not in keys: + keys.append(key) + new_add = self.dialect.concat_add(table._rname) + + metadata_change = False + sql_fields_current = copy.copy(sql_fields_old) + for key in keys: + query = None + if key not in sql_fields_old: + sql_fields_current[key] = sql_fields[key] + if self.dbengine in ('postgres',) and \ + sql_fields[key]['type'].startswith('geometry'): + # 'sql' == ftype in sql + query = [sql_fields[key]['sql']] + else: + query = ['ALTER TABLE %s ADD %s %s;' % ( + table._rname, sql_fields[key]['rname'], + sql_fields_aux[key]['sql'].replace(', ', new_add))] + metadata_change = True + elif self.dbengine in ('sqlite', 'spatialite'): + if key in sql_fields: + sql_fields_current[key] = sql_fields[key] + # Field rname has changes, add new column + if (sql_fields[key]['raw_rname'].lower() != + sql_fields_old[key]['raw_rname'].lower()): + tt = sql_fields_aux[key]['sql'].replace(', ', new_add) + query = [ + 'ALTER TABLE %s ADD %s %s;' % ( + table._rname, sql_fields[key]['rname'], tt), + 'UPDATE %s SET %s=%s;' % ( + table._rname, sql_fields[key]['rname'], + sql_fields_old[key]['rname'])] + metadata_change = True + elif key not in sql_fields: + del sql_fields_current[key] + ftype = sql_fields_old[key]['type'] + if self.dbengine == 'postgres' and \ + ftype.startswith('geometry'): + geotype, parms = ftype[:-1].split('(') + schema = parms.split(',')[0] + query = ["SELECT DropGeometryColumn ('%(schema)s', \ + '%(table)s', '%(field)s');" % dict( + schema=schema, table=table._raw_rname, + field=sql_fields_old[key]['raw_rname'])] + else: + query = [drop_expr % ( + table._rname, sql_fields_old[key]['rname'])] + metadata_change = True + # The field has a new rname, temp field is not needed + elif (sql_fields[key]['raw_rname'].lower() != + sql_fields_old[key]['raw_rname'].lower()): + sql_fields_current[key] = sql_fields[key] + tt = sql_fields_aux[key]['sql'].replace(', ', new_add) + query = [ + 'ALTER TABLE %s ADD %s %s;' % ( + table._rname, sql_fields[key]['rname'], tt), + 'UPDATE %s SET %s=%s;' % ( + table._rname, sql_fields[key]['rname'], + sql_fields_old[key]['rname']), + drop_expr % (table._rname, sql_fields_old[key]['rname']), + ] + metadata_change = True + elif ( + sql_fields[key]['sql'] != sql_fields_old[key]['sql'] and not + isinstance(field_types.get(key), SQLCustomType) and not + sql_fields[key]['type'].startswith('reference') and not + sql_fields[key]['type'].startswith('double') and not + sql_fields[key]['type'].startswith('id')): + sql_fields_current[key] = sql_fields[key] + tt = sql_fields_aux[key]['sql'].replace(', ', new_add) + key_tmp = self.dialect.quote(key + '__tmp') + query = [ + 'ALTER TABLE %s ADD %s %s;' % (table._rname, key_tmp, tt), + 'UPDATE %s SET %s=%s;' % ( + table._rname, key_tmp, sql_fields_old[key]['rname']), + drop_expr % (table._rname, sql_fields_old[key]['rname']), + 'ALTER TABLE %s ADD %s %s;' % ( + table._rname, sql_fields[key]['rname'], tt), + 'UPDATE %s SET %s=%s;' % ( + table._rname, sql_fields[key]['rname'], key_tmp), + drop_expr % (table._rname, key_tmp) + ] + metadata_change = True + elif sql_fields[key] != sql_fields_old[key]: + sql_fields_current[key] = sql_fields[key] + metadata_change = True + + if query: + self.log( + 'timestamp: %s\n' % datetime.datetime.today().isoformat(), + table) + for sub_query in query: + self.log(sub_query + '\n', table) + if fake_migrate: + if db._adapter.commit_on_alter_table: + self.save_dbt(table, sql_fields_current) + self.log('faked!\n', table) + else: + self.adapter.execute(sub_query) + # Caveat: mysql, oracle and firebird + # do not allow multiple alter table + # in one transaction so we must commit + # partial transactions and + # update table._dbt after alter table. + if db._adapter.commit_on_alter_table: + db.commit() + self.save_dbt(table, sql_fields_current) + self.log('success!\n', table) + + elif metadata_change: + self.save_dbt(table, sql_fields_current) + + if metadata_change and not ( + query and db._adapter.commit_on_alter_table): + db.commit() + self.save_dbt(table, sql_fields_current) + self.log('success!\n', table) + + def save_dbt(self, table, sql_fields_current): + tfile = self.file_open(table._dbt, 'wb') + pickle.dump(sql_fields_current, tfile) + self.file_close(tfile) + + def log(self, message, table=None): + isabs = None + logfilename = self.adapter.adapter_args.get('logfile', 'sql.log') + writelog = bool(logfilename) + if writelog: + isabs = os.path.isabs(logfilename) + if table and table._dbt and writelog and self.adapter.folder: + if isabs: + table._loggername = logfilename + else: + table._loggername = pjoin(self.adapter.folder, logfilename) + logfile = self.file_open(table._loggername, 'ab') + logfile.write(to_bytes(message)) + self.file_close(logfile) + + @staticmethod + def file_open(filename, mode='rb', lock=True): + #to be used ONLY for files that on GAE may not be on filesystem + if lock: + fileobj = portalocker.LockedFile(filename, mode) + else: + fileobj = open(filename, mode) + return fileobj + + @staticmethod + def file_close(fileobj): + #to be used ONLY for files that on GAE may not be on filesystem + if fileobj: + fileobj.close() + + @staticmethod + def file_delete(filename): + os.unlink(filename) + + @staticmethod + def file_exists(filename): + #to be used ONLY for files that on GAE may not be on filesystem + return exists(filename) + + +class InDBMigrator(Migrator): + def file_exists(self, filename): + return DatabaseStoredFile.exists(self.db, filename) + + def file_open(self, filename, mode='rb', lock=True): + return DatabaseStoredFile(self.db, filename, mode) + + @staticmethod + def file_close(fileobj): + fileobj.close_connection() + + def file_delete(self, filename): + query = "DELETE FROM web2py_filesystem WHERE path='%s'" % filename + self.db.executesql(query) + self.db.commit() diff --git a/web2py/gluon/packages/dal/pydal/objects.py b/web2py/gluon/packages/dal/pydal/objects.py new file mode 100644 index 0000000..bb7c80a --- /dev/null +++ b/web2py/gluon/packages/dal/pydal/objects.py @@ -0,0 +1,3122 @@ +# -*- coding: utf-8 -*- + +import base64 +import cgi +import copy +import csv +import datetime +import decimal +import os +import shutil +import sys +import types +import re +from collections import OrderedDict +from ._compat import ( + PY2, StringIO, BytesIO, pjoin, exists, hashlib_md5, basestring, iteritems, + xrange, implements_iterator, implements_bool, copyreg, reduce, to_bytes, + to_native, long +) +from ._globals import DEFAULT, IDENTITY, AND, OR +from ._gae import Key +from .exceptions import NotFoundException, NotAuthorizedException +from .helpers.regex import ( + REGEX_TABLE_DOT_FIELD, REGEX_ALPHANUMERIC, REGEX_PYTHON_KEYWORDS, + REGEX_STORE_PATTERN, REGEX_UPLOAD_PATTERN, REGEX_CLEANUP_FN, + REGEX_VALID_TB_FLD, REGEX_TYPE +) +from .helpers.classes import ( + Reference, MethodAdder, SQLCallableList, SQLALL, Serializable, + BasicStorage, SQLCustomType, OpRow, cachedprop +) +from .helpers.methods import ( + list_represent, bar_decode_integer, bar_decode_string, bar_encode, + archive_record, cleanup, use_common_filters, pluralize, + attempt_upload_on_insert, attempt_upload_on_update, delete_uploaded_files +) +from .helpers.serializers import serializers +from .utils import deprecated + + +DEFAULTLENGTH = {'string': 512, 'password': 512, 'upload': 512, 'text': 2**15, + 'blob': 2**31} + + +DEFAULT_REGEX = { + 'id': '[1-9]\d*', + 'decimal': '\d{1,10}\.\d{2}', + 'integer': '[+-]?\d*', + 'float': '[+-]?\d*(\.\d*)?', + 'double': '[+-]?\d*(\.\d*)?', + 'date': '\d{4}\-\d{2}\-\d{2}', + 'time': '\d{2}\:\d{2}(\:\d{2}(\.\d*)?)?', + 'datetime':'\d{4}\-\d{2}\-\d{2} \d{2}\:\d{2}(\:\d{2}(\.\d*)?)?', + } + +class Row(BasicStorage): + + """ + A dictionary that lets you do d['a'] as well as d.a + this is only used to store a `Row` + """ + + def __getitem__(self, k): + key = str(k) + _extra = super(Row, self).get('_extra', None) + if _extra is not None: + v = _extra.get(key, DEFAULT) + if v != DEFAULT: + return v + + try: + return BasicStorage.__getattribute__(self, key) + except AttributeError: + pass + + m = REGEX_TABLE_DOT_FIELD.match(key) + if m: + try: + e = super(Row, self).__getitem__(m.group(1)) + return e[m.group(2)] + except (KeyError, TypeError): + pass + key = m.group(2) + try: + return super(Row, self).__getitem__(key) + except KeyError: + pass + try: + e = super(Row, self).get('__get_lazy_reference__') + if e is not None and callable(e): + self[key] = e(key) + return self[key] + except Exception as e: + raise e + + raise KeyError(key) + + __str__ = __repr__ = lambda self: '' % \ + self.as_dict(custom_types=[LazySet]) + + __int__ = lambda self: self.get('id') + + __long__ = lambda self: long(self.get('id')) + + __call__ = __getitem__ + + def __getattr__(self, k): + try: + return self.__getitem__(k) + except KeyError: + raise AttributeError + + def __copy__(self): + return Row(self) + + def __eq__(self, other): + try: + return self.as_dict() == other.as_dict() + except AttributeError: + return False + + def get(self, key, default=None): + try: + return self.__getitem__(key) + except(KeyError, AttributeError, TypeError): + return default + + def as_dict(self, datetime_to_str=False, custom_types=None): + SERIALIZABLE_TYPES = [str, int, float, bool, list, dict] + DT_INST = (datetime.date, datetime.datetime, datetime.time) + if PY2: + SERIALIZABLE_TYPES += [unicode, long] + if isinstance(custom_types, (list, tuple, set)): + SERIALIZABLE_TYPES += custom_types + elif custom_types: + SERIALIZABLE_TYPES.append(custom_types) + d = dict(self) + for k in list(d.keys()): + v = d[k] + if d[k] is None: + continue + elif isinstance(v, Row): + d[k] = v.as_dict() + elif isinstance(v, Reference): + d[k] = long(v) + elif isinstance(v, decimal.Decimal): + d[k] = float(v) + elif isinstance(v, DT_INST): + if datetime_to_str: + d[k] = v.isoformat().replace('T', ' ')[:19] + elif not isinstance(v, tuple(SERIALIZABLE_TYPES)): + del d[k] + return d + + def as_xml(self, row_name="row", colnames=None, indent=' '): + def f(row, field, indent=' '): + if isinstance(row, Row): + spc = indent+' \n' + items = [f(row[x], x, indent+' ') for x in row] + return '%s<%s>\n%s\n%s' % ( + indent, + field, + spc.join(item for item in items if item), + indent, + field) + elif not callable(row): + if REGEX_ALPHANUMERIC.match(field): + return '%s<%s>%s' % (indent, field, row, field) + else: + return '%s%s' % \ + (indent, field, row) + else: + return None + return f(self, row_name, indent=indent) + + def as_json(self, mode="object", default=None, colnames=None, + serialize=True, **kwargs): + """ + serializes the row to a JSON object + kwargs are passed to .as_dict method + only "object" mode supported + + `serialize = False` used by Rows.as_json + + TODO: return array mode with query column order + + mode and colnames are not implemented + """ + + item = self.as_dict(**kwargs) + if serialize: + return serializers.json(item) + else: + return item + + +def pickle_row(s): + return Row, (dict(s), ) + +copyreg.pickle(Row, pickle_row) + + +class Table(Serializable, BasicStorage): + + """ + Represents a database table + + Example:: + You can create a table as:: + db = DAL(...) + db.define_table('users', Field('name')) + + And then:: + + db.users.insert(name='me') # print db.users._insert(...) to see SQL + db.users.drop() + + """ + + def __init__(self, db, tablename, *fields, **args): + """ + Initializes the table and performs checking on the provided fields. + + Each table will have automatically an 'id'. + + If a field is of type Table, the fields (excluding 'id') from that table + will be used instead. + + Raises: + SyntaxError: when a supplied field is of incorrect type. + """ + # import DAL here to avoid circular imports + from .base import DAL + super(Table, self).__init__() + self._actual = False # set to True by define_table() + self._db = db + self._migrate = None + self._tablename = self._dalname = tablename + if not isinstance(tablename, str) or hasattr(DAL, tablename) or not \ + REGEX_VALID_TB_FLD.match(tablename) or \ + REGEX_PYTHON_KEYWORDS.match(tablename): + raise SyntaxError('Field: invalid table name: %s, ' + 'use rname for "funny" names' % tablename) + self._rname = args.get('rname') or \ + db and db._adapter.dialect.quote(tablename) + self._raw_rname = args.get('rname') or db and tablename + self._sequence_name = args.get('sequence_name') or \ + db and db._adapter.dialect.sequence_name(self._raw_rname) + self._trigger_name = args.get('trigger_name') or \ + db and db._adapter.dialect.trigger_name(tablename) + self._common_filter = args.get('common_filter') + self._format = args.get('format') + self._singular = args.get( + 'singular', tablename.replace('_', ' ').capitalize()) + self._plural = args.get( + 'plural', pluralize(self._singular.lower()).capitalize()) + # horrible but for backard compatibility of appamdin: + if 'primarykey' in args and args['primarykey'] is not None: + self._primarykey = args.get('primarykey') + + self._before_insert = [attempt_upload_on_insert(self)] + self._before_update = [ + delete_uploaded_files, attempt_upload_on_update(self)] + self._before_delete = [delete_uploaded_files] + self._after_insert = [] + self._after_update = [] + self._after_delete = [] + + self._virtual_fields = [] + self._virtual_methods = [] + + self.add_method = MethodAdder(self) + + fieldnames, newfields = set(), [] + _primarykey = getattr(self, '_primarykey', None) + if _primarykey is not None: + if not isinstance(_primarykey, list): + raise SyntaxError( + "primarykey must be a list of fields from table '%s'" + % tablename) + if len(_primarykey) == 1: + self._id = [ + f for f in fields if isinstance(f, Field) and + f.name == _primarykey[0]][0] + elif not [f for f in fields if (isinstance(f, Field) and + f.type == 'id') or (isinstance(f, dict) and + f.get("type", None) == "id")]: + field = Field('id', 'id') + newfields.append(field) + fieldnames.add('id') + self._id = field + + virtual_fields = [] + + def include_new(field): + newfields.append(field) + fieldnames.add(field.name) + if field.type == 'id': + self._id = field + for field in fields: + if isinstance(field, (FieldVirtual, FieldMethod)): + virtual_fields.append(field) + elif isinstance(field, Field) and field.name not in fieldnames: + if field.db is not None: + field = copy.copy(field) + include_new(field) + elif isinstance(field, Table): + table = field + for field in table: + if field.name not in fieldnames and field.type != 'id': + t2 = not table._actual and self._tablename + include_new(field.clone(point_self_references_to=t2)) + elif isinstance(field, dict) and \ + field['fieldname'] not in fieldnames: + include_new(Field(**field)) + elif not isinstance(field, (Field, Table)): + raise SyntaxError( + 'define_table argument is not a Field or Table: %s' % + field + ) + fields = newfields + tablename = tablename + self._fields = SQLCallableList() + self.virtualfields = [] + fields = list(fields) + + if db and db._adapter.uploads_in_blob is True: + uploadfields = [f.name for f in fields if f.type == 'blob'] + for field in fields: + fn = field.uploadfield + if isinstance(field, Field) and field.type == 'upload'\ + and fn is True and not field.uploadfs: + fn = field.uploadfield = '%s_blob' % field.name + if isinstance(fn, str) and fn not in uploadfields and \ + not field.uploadfs: + fields.append(Field(fn, 'blob', default='', + writable=False, readable=False)) + + fieldnames_set = set() + reserved = dir(Table) + ['fields'] + if (db and db._check_reserved): + check_reserved_keyword = db.check_reserved_keyword + else: + def check_reserved_keyword(field_name): + if field_name in reserved: + raise SyntaxError("field name %s not allowed" % field_name) + for field in fields: + field_name = field.name + check_reserved_keyword(field_name) + if db and db._ignore_field_case: + fname_item = field_name.lower() + else: + fname_item = field_name + if fname_item in fieldnames_set: + raise SyntaxError( + "duplicate field %s in table %s" % (field_name, tablename)) + else: + fieldnames_set.add(fname_item) + + self.fields.append(field_name) + self[field_name] = field + if field.type == 'id': + self['id'] = field + field.bind(self) + self.ALL = SQLALL(self) + + if _primarykey is not None: + for k in _primarykey: + if k not in self.fields: + raise SyntaxError( + "primarykey must be a list of fields from table '%s " % + tablename) + else: + self[k].notnull = True + for field in virtual_fields: + self[field.name] = field + + @property + def fields(self): + return self._fields + + def _structure(self): + keys = ['name','type','writable','listable','searchable','regex','options', + 'default','label','unique','notnull','required'] + def noncallable(obj): return obj if not callable(obj) else None + return [{key: noncallable(getattr(field, key)) for key in keys} + for field in self if field.readable and not field.type=='password'] + + @cachedprop + def _upload_fieldnames(self): + return set(field.name for field in self if field.type == 'upload') + + def update(self, *args, **kwargs): + raise RuntimeError("Syntax Not Supported") + + def _enable_record_versioning(self, + archive_db=None, + archive_name='%(tablename)s_archive', + is_active='is_active', + current_record='current_record', + current_record_label=None, + migrate=None, + redefine=None): + db = self._db + archive_db = archive_db or db + archive_name = archive_name % dict(tablename=self._dalname) + if archive_name in archive_db.tables(): + return # do not try define the archive if already exists + fieldnames = self.fields() + same_db = archive_db is db + field_type = self if same_db else 'bigint' + clones = [] + for field in self: + nfk = same_db or not field.type.startswith('reference') + clones.append( + field.clone(unique=False, type=field.type if nfk else 'bigint') + ) + + d = dict(format=self._format) + if migrate: + d['migrate'] = migrate + elif isinstance(self._migrate, basestring): + d['migrate'] = self._migrate+'_archive' + elif self._migrate: + d['migrate'] = self._migrate + if redefine: + d['redefine'] = redefine + archive_db.define_table( + archive_name, + Field(current_record, field_type, label=current_record_label), + *clones, **d) + + self._before_update.append( + lambda qset, fs, db=archive_db, an=archive_name, cn=current_record: + archive_record(qset, fs, db[an], cn)) + if is_active and is_active in fieldnames: + self._before_delete.append( + lambda qset: qset.update(is_active=False)) + newquery = lambda query, t=self, name=self._tablename: reduce( + AND, [ + tab.is_active == True + for tab in db._adapter.tables(query).values() + if tab._raw_rname == self._raw_rname] + ) + query = self._common_filter + if query: + self._common_filter = lambda q: reduce( + AND, [query(q), newquery(q)]) + else: + self._common_filter = newquery + + def _validate(self, **vars): + errors = Row() + for key, value in iteritems(vars): + value, error = self[key].validate(value) + if error: + errors[key] = error + return errors + + def _create_references(self): + db = self._db + pr = db._pending_references + self._referenced_by_list = [] + self._referenced_by = [] + self._references = [] + for field in self: + # fieldname = field.name #FIXME not used ? + field_type = field.type + if isinstance(field_type, str) and ( + field_type.startswith('reference ') or + field_type.startswith('list:reference ')): + + is_list = field_type[:15] == 'list:reference ' + if is_list: + ref = field_type[15:].strip() + else: + ref = field_type[10:].strip() + + if not ref: + SyntaxError('Table: reference to nothing: %s' % ref) + if '.' in ref: + rtablename, throw_it, rfieldname = ref.partition('.') + else: + rtablename, rfieldname = ref, None + if rtablename not in db: + pr[rtablename] = pr.get(rtablename, []) + [field] + continue + rtable = db[rtablename] + if rfieldname: + if not hasattr(rtable, '_primarykey'): + raise SyntaxError( + 'keyed tables can only reference other keyed tables (for now)') + if rfieldname not in rtable.fields: + raise SyntaxError( + "invalid field '%s' for referenced table '%s'" + " in table '%s'" % (rfieldname, rtablename, self._tablename) + ) + rfield = rtable[rfieldname] + else: + rfield = rtable._id + if is_list: + rtable._referenced_by_list.append(field) + else: + rtable._referenced_by.append(field) + field.referent = rfield + self._references.append(field) + else: + field.referent = None + if self._tablename in pr: + referees = pr.pop(self._tablename) + for referee in referees: + if referee.type.startswith('list:reference '): + self._referenced_by_list.append(referee) + else: + self._referenced_by.append(referee) + + def _filter_fields(self, record, id=False): + return dict([(k, v) for (k, v) in iteritems(record) if k + in self.fields and (self[k].type != 'id' or id)]) + + def _build_query(self, key): + """ for keyed table only """ + query = None + for k, v in iteritems(key): + if k in self._primarykey: + if query: + query = query & (self[k] == v) + else: + query = (self[k] == v) + else: + raise SyntaxError( + 'Field %s is not part of the primary key of %s' % + (k, self._tablename)) + return query + + def __getitem__(self, key): + if not key: + return None + elif isinstance(key, dict): + """ for keyed table """ + query = self._build_query(key) + return self._db(query).select( + limitby=(0, 1), + orderby_on_limitby=False + ).first() + else: + try: + isgoogle = 'google' in self._db._drivers_available and \ + isinstance(key, Key) + except: + isgoogle = False + if str(key).isdigit() or isgoogle: + return self._db(self._id == key).select( + limitby=(0, 1), + orderby_on_limitby=False + ).first() + else: + try: + return getattr(self, key) + except: + raise KeyError(key) + + def __call__(self, key=DEFAULT, **kwargs): + for_update = kwargs.get('_for_update', False) + if '_for_update' in kwargs: + del kwargs['_for_update'] + + orderby = kwargs.get('_orderby', None) + if '_orderby' in kwargs: + del kwargs['_orderby'] + + if key is not DEFAULT: + if isinstance(key, Query): + record = self._db(key).select( + limitby=(0, 1), + for_update=for_update, + orderby=orderby, + orderby_on_limitby=False).first() + elif not str(key).isdigit(): + record = None + else: + record = self._db(self._id == key).select( + limitby=(0, 1), + for_update=for_update, + orderby=orderby, + orderby_on_limitby=False).first() + if record: + for k, v in iteritems(kwargs): + if record[k] != v: + return None + return record + elif kwargs: + query = reduce(lambda a, b: a & b, [ + self[k] == v for k, v in iteritems(kwargs)]) + return self._db(query).select(limitby=(0, 1), + for_update=for_update, + orderby=orderby, + orderby_on_limitby=False).first() + else: + return None + + def __setitem__(self, key, value): + if isinstance(key, dict) and isinstance(value, dict): + """ option for keyed table """ + if set(key.keys()) == set(self._primarykey): + value = self._filter_fields(value) + kv = {} + kv.update(value) + kv.update(key) + if not self.insert(**kv): + query = self._build_query(key) + self._db(query).update(**self._filter_fields(value)) + else: + raise SyntaxError( + 'key must have all fields from primary key: %s' % + self._primarykey) + elif str(key).isdigit(): + if key == 0: + self.insert(**self._filter_fields(value)) + elif self._db(self._id == key)\ + .update(**self._filter_fields(value)) is None: + raise SyntaxError('No such record: %s' % key) + else: + if isinstance(key, dict): + raise SyntaxError( + 'value must be a dictionary: %s' % value) + self.__dict__[str(key)] = value + if isinstance(value, (FieldVirtual, FieldMethod)): + if value.name == 'unknown': + value.name = str(key) + if isinstance(value, FieldVirtual): + self._virtual_fields.append(value) + else: + self._virtual_methods.append(value) + + def __setattr__(self, key, value): + if key[:1] != '_' and key in self: + raise SyntaxError( + 'Object exists and cannot be redefined: %s' % key) + self[key] = value + + def __delitem__(self, key): + if isinstance(key, dict): + query = self._build_query(key) + if not self._db(query).delete(): + raise SyntaxError('No such record: %s' % key) + elif not str(key).isdigit() or \ + not self._db(self._id == key).delete(): + raise SyntaxError('No such record: %s' % key) + + def __iter__(self): + for fieldname in self.fields: + yield self[fieldname] + + def __repr__(self): + return '
    ' % (self._tablename, ', '.join(self.fields())) + + def __str__(self): + if self._tablename == self._dalname: + return self._tablename + return self._db._adapter.dialect._as(self._dalname, self._tablename) + + @property + @deprecated('sqlsafe', 'sql_shortref', 'Table') + def sqlsafe(self): + return self.sql_shortref + + @property + @deprecated('sqlsafe_alias', 'sql_fullref', 'Table') + def sqlsafe_alias(self): + return self.sql_fullref + + @property + def sql_shortref(self): + if self._tablename == self._dalname: + return self._rname + return self._db._adapter.sqlsafe_table(self._tablename) + + @property + def sql_fullref(self): + if self._tablename == self._dalname: + return self._rname + return self._db._adapter.sqlsafe_table(self._tablename, self._rname) + + def query_name(self, *args, **kwargs): + return (self.sql_fullref,) + + def _drop(self, mode=''): + return self._db._adapter.dialect.drop_table(self, mode) + + def drop(self, mode=''): + return self._db._adapter.drop_table(self, mode) + + def _filter_fields_for_operation(self, fields): + new_fields = {} # format: new_fields[name] = (field, value) + input_fieldnames = set(fields) + table_fieldnames = set(self.fields) + empty_fieldnames = OrderedDict((name, name) for name in self.fields) + for name in list(input_fieldnames & table_fieldnames): + field = self[name] + value = field.filter_in(fields[name]) \ + if field.filter_in else fields[name] + new_fields[name] = (field, value) + del empty_fieldnames[name] + return list(empty_fieldnames), new_fields + + def _compute_fields_for_operation(self, fields, to_compute): + row = OpRow(self) + for name, tup in iteritems(fields): + field, value = tup + if isinstance( + value, ( + types.LambdaType, types.FunctionType, types.MethodType, + types.BuiltinFunctionType, types.BuiltinMethodType + ) + ): + value = value() + row.set_value(name, value, field) + for name, field in to_compute: + try: + row.set_value(name, field.compute(row), field) + except (KeyError, AttributeError): + # error silently unless field is required! + if field.required and name not in fields: + raise RuntimeError( + 'unable to compute required field: %s' % name) + return row + + def _fields_and_values_for_insert(self, fields): + empty_fieldnames, new_fields = \ + self._filter_fields_for_operation(fields) + to_compute = [] + for name in empty_fieldnames: + field = self[name] + if field.compute: + to_compute.append((name, field)) + elif field.default is not None: + new_fields[name] = (field, field.default) + elif field.required: + raise RuntimeError( + 'Table: missing required field: %s' % name) + return self._compute_fields_for_operation( + new_fields, to_compute) + + def _fields_and_values_for_update(self, fields): + empty_fieldnames, new_fields = \ + self._filter_fields_for_operation(fields) + to_compute = [] + for name in empty_fieldnames: + field = self[name] + if field.compute: + to_compute.append((name, field)) + if field.update is not None: + new_fields[name] = (field, field.update) + return self._compute_fields_for_operation( + new_fields, to_compute) + + def _insert(self, **fields): + row = self._fields_and_values_for_insert(fields) + return self._db._adapter._insert(self, row.op_values()) + + def insert(self, **fields): + row = self._fields_and_values_for_insert(fields) + if any(f(row) for f in self._before_insert): + return 0 + ret = self._db._adapter.insert(self, row.op_values()) + if ret and self._after_insert: + for f in self._after_insert: + f(row, ret) + return ret + + def _validate_fields(self, fields, defattr='default'): + response = Row() + response.id, response.errors, new_fields = None, Row(), Row() + for field in self: + # we validate even if not passed in case it is required + error = default = None + if not field.required and not field.compute: + default = getattr(field, defattr) + if callable(default): + default = default() + if not field.compute: + value = fields.get(field.name, default) + value, error = field.validate(value) + if error: + response.errors[field.name] = "%s" % error + elif field.name in fields: + # only write if the field was passed and no error + new_fields[field.name] = value + return response, new_fields + + def validate_and_insert(self, **fields): + response, new_fields = self._validate_fields(fields, 'default') + if not response.errors: + response.id = self.insert(**new_fields) + return response + + def validate_and_update(self, _key=DEFAULT, **fields): + response, new_fields = self._validate_fields(fields, 'update') + #: select record(s) for update + if _key is DEFAULT: + record = self(**fields) + elif isinstance(_key, dict): + record = self(**_key) + else: + record = self(_key) + #: do the update + if not response.errors and record: + if '_id' in self: + myset = self._db(self._id == record[self._id.name]) + else: + query = None + for key, value in iteritems(_key): + if query is None: + query = getattr(self, key) == value + else: + query = query & (getattr(self, key) == value) + myset = self._db(query) + response.id = myset.update(**new_fields) and record[self._id.name] + return response + + def update_or_insert(self, _key=DEFAULT, **values): + if _key is DEFAULT: + record = self(**values) + elif isinstance(_key, dict): + record = self(**_key) + else: + record = self(_key) + if record: + record.update_record(**values) + newid = None + else: + newid = self.insert(**values) + return newid + + def validate_and_update_or_insert(self, _key=DEFAULT, **fields): + if _key is DEFAULT or _key == '': + primary_keys = {} + for key, value in iteritems(fields): + if key in self._primarykey: + primary_keys[key] = value + if primary_keys != {}: + record = self(**primary_keys) + _key = primary_keys + else: + required_keys = {} + for key, value in iteritems(fields): + if getattr(self, key).required: + required_keys[key] = value + record = self(**required_keys) + _key = required_keys + elif isinstance(_key, dict): + record = self(**_key) + else: + record = self(_key) + + if record: + response = self.validate_and_update(_key, **fields) + if hasattr(self, '_primarykey'): + primary_keys = {} + for key in self._primarykey: + primary_keys[key] = getattr(record, key) + response.id = primary_keys + else: + response = self.validate_and_insert(**fields) + return response + + def bulk_insert(self, items): + """ + here items is a list of dictionaries + """ + data = [self._fields_and_values_for_insert(item) for item in items] + if any(f(el) for el in data for f in self._before_insert): + return 0 + ret = self._db._adapter.bulk_insert( + self, [el.op_values() for el in data]) + ret and [ + [f(el, ret[k]) for k, el in enumerate(data)] + for f in self._after_insert] + return ret + + def _truncate(self, mode=''): + return self._db._adapter.dialect.truncate(self, mode) + + def truncate(self, mode=''): + return self._db._adapter.truncate(self, mode) + + def import_from_csv_file(self, + csvfile, + id_map = None, + null = '', + unique = 'uuid', + id_offset = None, # id_offset used only when id_map is None + transform = None, + validate=False, + **kwargs + ): + """ + Import records from csv file. + Column headers must have same names as table fields. + Field 'id' is ignored. + If column names read 'table.file' the 'table.' prefix is ignored. + + - 'unique' argument is a field which must be unique (typically a + uuid field) + - 'restore' argument is default False; if set True will remove old values + in table first. + - 'id_map' if set to None will not map ids + + The import will keep the id numbers in the restored table. + This assumes that there is an field of type id that is integer and in + incrementing order. + Will keep the id numbers in restored table. + """ + if validate: + inserting=self.validate_and_insert + else: + inserting=self.insert + + delimiter = kwargs.get('delimiter', ',') + quotechar = kwargs.get('quotechar', '"') + quoting = kwargs.get('quoting', csv.QUOTE_MINIMAL) + restore = kwargs.get('restore', False) + if restore: + self._db[self].truncate() + + reader = csv.reader(csvfile, delimiter=delimiter, + quotechar=quotechar, quoting=quoting) + colnames = None + if isinstance(id_map, dict): + if self._tablename not in id_map: + id_map[self._tablename] = {} + id_map_self = id_map[self._tablename] + + def fix(field, value, id_map, id_offset): + list_reference_s = 'list:reference' + if value == null: + value = None + elif field.type == 'blob': + value = base64.b64decode(value) + elif field.type == 'double' or field.type == 'float': + if not value.strip(): + value = None + else: + value = float(value) + elif field.type in ('integer', 'bigint'): + if not value.strip(): + value = None + else: + value = long(value) + elif field.type.startswith('list:string'): + value = bar_decode_string(value) + elif field.type.startswith(list_reference_s): + ref_table = field.type[len(list_reference_s):].strip() + if id_map is not None: + value = [id_map[ref_table][long(v)] + for v in bar_decode_string(value)] + else: + value = [v for v in bar_decode_string(value)] + elif field.type.startswith('list:'): + value = bar_decode_integer(value) + elif id_map and field.type.startswith('reference'): + try: + value = id_map[field.type[9:].strip()][long(value)] + except KeyError: + pass + elif id_offset and field.type.startswith('reference'): + try: + value = id_offset[field.type[9:].strip()]+long(value) + except KeyError: + pass + return value + + def is_id(colname): + if colname in self: + return self[colname].type == 'id' + else: + return False + + first = True + unique_idx = None + for lineno, line in enumerate(reader): + if not line: + return + if not colnames: + # assume this is the first line of the input, contains colnames + colnames = [x.split('.', 1)[-1] for x in line][:len(line)] + + cols, cid = {}, None + for i, colname in enumerate(colnames): + if is_id(colname): + cid = colname + elif colname in self.fields: + cols[colname] = self[colname] + if colname == unique: + unique_idx = i + elif len(line)==len(colnames): + # every other line contains instead data + items = dict(zip(colnames, line)) + if transform: + items = transform(items) + + ditems = dict() + csv_id = None + for field in self: + fieldname = field.name + if fieldname in items: + try: + value = fix(field, items[fieldname], id_map, id_offset) + if field.type!='id': + ditems[fieldname] = value + else: + csv_id = long(value) + except ValueError: + raise RuntimeError("Unable to parse line:%s" % (lineno+1)) + if not (id_map or csv_id is None or id_offset is None or unique_idx): + curr_id = inserting(**ditems) + if first: + first = False + # First curr_id is bigger than csv_id, + # then we are not restoring but + # extending db table with csv db table + id_offset[self._tablename] = (curr_id-csv_id) \ + if curr_id > csv_id else 0 + # create new id until we get the same as old_id+offset + while curr_id < csv_id+id_offset[self._tablename]: + self._db(self[cid] == curr_id).delete() + curr_id = inserting(**ditems) + # Validation. Check for duplicate of 'unique' &, + # if present, update instead of insert. + elif not unique_idx: + new_id = inserting(**ditems) + else: + unique_value = line[unique_idx] + query = self[unique] == unique_value + record = self._db(query).select().first() + if record: + record.update_record(**ditems) + new_id = record[self._id.name] + else: + new_id = inserting(**ditems) + if id_map and csv_id is not None: + id_map_self[csv_id] = new_id + if lineno % 1000 == 999: + self._db.commit() + + def as_dict(self, flat=False, sanitize=True): + table_as_dict = dict( + tablename=str(self), + fields=[], + sequence_name=self._sequence_name, + trigger_name=self._trigger_name, + common_filter=self._common_filter, + format=self._format, + singular=self._singular, + plural=self._plural) + + for field in self: + if (field.readable or field.writable) or (not sanitize): + table_as_dict["fields"].append(field.as_dict( + flat=flat, sanitize=sanitize)) + return table_as_dict + + def with_alias(self, alias): + try: + if self._db[alias]._rname == self._rname: + return self._db[alias] + except AttributeError: # we never used this alias + pass + other = copy.copy(self) + other['ALL'] = SQLALL(other) + other['_tablename'] = alias + for fieldname in other.fields: + tmp = self[fieldname].clone() + tmp.bind(other) + other[fieldname] = tmp + if 'id' in self and 'id' not in other.fields: + other['id'] = other[self.id.name] + other._id = other[self._id.name] + self._db[alias] = other + return other + + def on(self, query): + return Expression(self._db, self._db._adapter.dialect.on, self, query) + + def create_index(self, name, *fields, **kwargs): + return self._db._adapter.create_index(self, name, *fields, **kwargs) + + def drop_index(self, name): + return self._db._adapter.drop_index(self, name) + + +class Select(BasicStorage): + def __init__(self, db, query, fields, attributes): + self._db = db + self._tablename = None # alias will be stored here + self._rname = self._raw_rname = self._dalname = None + self._common_filter = None + self._query = query + # if false, the subquery will never reference tables from parent scope + self._correlated = attributes.pop('correlated', True) + self._attributes = attributes + self._qfields = list(fields) + self._fields = SQLCallableList() + self._virtual_fields = [] + self._virtual_methods = [] + self.virtualfields = [] + self._sql_cache = None + self._colnames_cache = None + fieldcheck = set() + + for item in fields: + if isinstance(item, Field): + checkname = item.name + field = item.clone() + elif isinstance(item, Expression): + if item.op != item._dialect._as: + continue + checkname = item.second + field = Field(item.second, type=item.type) + else: + raise SyntaxError('Invalid field in Select') + if db and db._ignore_field_case: + checkname = checkname.lower() + if checkname in fieldcheck: + raise SyntaxError("duplicate field %s in select query" % + field.name) + fieldcheck.add(checkname) + field.bind(self) + self.fields.append(field.name) + self[field.name] = field + self.ALL = SQLALL(self) + + @property + def fields(self): + return self._fields + + def update(self, *args, **kwargs): + raise RuntimeError("update() method not supported") + + def __getitem__(self, key): + try: + return getattr(self, key) + except AttributeError: + raise KeyError(key) + + def __setitem__(self, key, value): + self.__dict__[str(key)] = value + + def __call__(self): + adapter = self._db._adapter + colnames, sql = self._compile() + cache = self._attributes.get('cache', None) + if cache and self._attributes.get('cacheable', False): + return adapter._cached_select(cache, sql, self._fields, + self._attributes, colnames) + return adapter._select_aux(sql, self._qfields, self._attributes, + colnames) + + def __setattr__(self, key, value): + if key[:1] != '_' and key in self: + raise SyntaxError( + 'Object exists and cannot be redefined: %s' % key) + self[key] = value + + def __iter__(self): + for fieldname in self.fields: + yield self[fieldname] + + def __repr__(self): + return ' style + self.assertEqual(TAG.first_(TAG.second('test'), _key=3).xml(), + b'') + # unicode test for TAG + self.assertEqual(TAG.div(u'Texte en français avec des caractères accentués...').xml(), + b'
    Texte en fran\xc3\xa7ais avec des caract\xc3\xa8res accentu\xc3\xa9s...
    ') + + def test_HTML(self): + self.assertEqual(HTML('<>', _a='1', _b='2').xml(), + b'\n<>') + self.assertEqual(HTML('<>', _a='1', _b='2', doctype='strict').xml(), + b'\n<>') + self.assertEqual(HTML('<>', _a='1', _b='2', doctype='transitional').xml(), + b'\n<>') + self.assertEqual(HTML('<>', _a='1', _b='2', doctype='frameset').xml(), + b'\n<>') + self.assertEqual(HTML('<>', _a='1', _b='2', doctype='html5').xml(), + b'\n<>') + self.assertEqual(HTML('<>', _a='1', _b='2', doctype='').xml(), + b'<>') + self.assertEqual(HTML('<>', _a='1', _b='2', doctype='CustomDocType').xml(), + b'CustomDocType\n<>') + + def test_XHTML(self): + # Empty XHTML test + self.assertEqual(XHTML().xml(), + b'\n') + # Not Empty XHTML test + self.assertEqual(XHTML('<>', _a='1', _b='2').xml(), + b'\n<>') + self.assertEqual(XHTML('<>', _a='1', _b='2', doctype='').xml(), + b'\n<>') + self.assertEqual(XHTML('<>', _a='1', _b='2', doctype='strict').xml(), + b'\n<>') + self.assertEqual(XHTML('<>', _a='1', _b='2', doctype='transitional').xml(), + b'\n<>') + self.assertEqual(XHTML('<>', _a='1', _b='2', doctype='frameset').xml(), + b'\n<>') + self.assertEqual(XHTML('<>', _a='1', _b='2', doctype='xmlns').xml(), + b'xmlns\n<>') + self.assertEqual(XHTML('<>', _a='1', _b='2', _xmlns='xmlns').xml(), + b'\n<>') + + def test_HEAD(self): + self.assertEqual(HEAD('<>', _a='1', _b='2').xml(), + b'<>') + + def test_TITLE(self): + self.assertEqual(TITLE('<>', _a='1', _b='2').xml(), + b'<>') + + def test_META(self): + self.assertEqual(META(_a='1', _b='2').xml(), + b'') + + def test_LINK(self): + self.assertEqual(LINK(_a='1', _b='2').xml(), + b'') + + def test_SCRIPT(self): + self.assertEqual(SCRIPT('<>', _a='1', _b='2').xml(), + b'''''') + self.assertEqual(SCRIPT('<>').xml(), + b'''''') + self.assertEqual(SCRIPT().xml(), b'') + self.assertEqual(SCRIPT(';').xml() + DIV().xml(), + b'
    ') + + def test_STYLE(self): + self.assertEqual(STYLE('<>', _a='1', _b='2').xml(), + b'') + # Try to hit : return DIV.xml(self) + self.assertEqual(STYLE().xml(), b'') + + def test_IMG(self): + self.assertEqual(IMG(_a='1', _b='2').xml(), + b'') + + def test_SPAN(self): + self.assertEqual(SPAN('<>', _a='1', _b='2').xml(), + b'<>') + + def test_BODY(self): + self.assertEqual(BODY('<>', _a='1', _b='2').xml(), + b'<>') + + def test_H1(self): + self.assertEqual(H1('<>', _a='1', _b='2').xml(), + b'

    <>

    ') + + def test_H2(self): + self.assertEqual(H2('<>', _a='1', _b='2').xml(), + b'

    <>

    ') + + def test_H3(self): + self.assertEqual(H3('<>', _a='1', _b='2').xml(), + b'

    <>

    ') + + def test_H4(self): + self.assertEqual(H4('<>', _a='1', _b='2').xml(), + b'

    <>

    ') + + def test_H5(self): + self.assertEqual(H5('<>', _a='1', _b='2').xml(), + b'
    <>
    ') + + def test_H6(self): + self.assertEqual(H6('<>', _a='1', _b='2').xml(), + b'
    <>
    ') + + def test_P(self): + self.assertEqual(P('<>', _a='1', _b='2').xml(), + b'

    <>

    ') + # test cr2br + self.assertEqual(P('a\nb').xml(), b'

    a\nb

    ') + self.assertEqual(P('a\nb', cr2br=True).xml(), b'

    a
    b

    ') + + def test_STRONG(self): + self.assertEqual(STRONG('<>', _a='1', _b='2').xml(), + b'<>') + + def test_B(self): + self.assertEqual(B('<>', _a='1', _b='2').xml(), + b'<>') + + def test_BR(self): + # empty BR() + self.assertEqual(BR().xml(), b'
    ') + self.assertEqual(BR(_a='1', _b='2').xml(), b'
    ') + + def test_HR(self): + self.assertEqual(HR(_a='1', _b='2').xml(), b'
    ') + + def test_A(self): + self.assertEqual(A('<>', _a='1', _b='2').xml(), + b'
    <>') + self.assertEqual(A('a', cid='b').xml(), + b'a') + self.assertEqual(A('a', callback='b', _id='c').xml(), + b'a') + # Callback with no id trigger web2py_uuid() call + from gluon.html import web2pyHTMLParser + #a = A('a', callback='b').xml() + + #for tag in web2pyHTMLParser(a).tree.elements('a'): + # uuid_generated = tag.attributes['_id'] + #self.assertEqual(a, + # b'a'.format(id=uuid_generated)) + self.assertEqual(A('a', delete='tr').xml(), + b'a') + self.assertEqual(A('a', _id='b', target='').xml(), + b'a') + self.assertEqual(A('a', component='b').xml(), + b'a') + self.assertEqual(A('a', _id='b', callback='c', noconfirm=True).xml(), + b'a') + self.assertEqual(A('a', cid='b').xml(), + b'a') + self.assertEqual(A('a', cid='b', _disable_with='processing...').xml(), + b'a') + self.assertEqual(A('a', callback='b', delete='tr', noconfirm=True, _id='c').xml(), + b'a') + self.assertEqual(A('a', callback='b', delete='tr', confirm='Are you sure?', _id='c').xml(), + b'a') + + def test_BUTTON(self): + self.assertEqual(BUTTON('test', _type='button').xml(), + b'') + + def test_EM(self): + self.assertEqual(EM('<>', _a='1', _b='2').xml(), + b'<>') + + def test_EMBED(self): + self.assertEqual(EMBED(_a='1', _b='2').xml(), + b'') + + def test_TT(self): + self.assertEqual(TT('<>', _a='1', _b='2').xml(), + b'<>') + + def test_PRE(self): + self.assertEqual(PRE('<>', _a='1', _b='2').xml(), + b'
    <>
    ') + + def test_CENTER(self): + self.assertEqual(CENTER('<>', _a='1', _b='2').xml(), + b'
    <>
    ') + + def test_CODE(self): + self.assertEqual(CODE("print 'hello world'", + language='python', + link=None, + counter=1, + styles={}, + highlight_line=None).xml(), + '
    1.
    print \'hello world\'
    ') + + def test_LABEL(self): + self.assertEqual(LABEL('<>', _a='1', _b='2').xml(), + b'') + + def test_LI(self): + self.assertEqual(LI('<>', _a='1', _b='2').xml(), + b'
  • <>
  • ') + + def test_UL(self): + self.assertEqual(UL('<>', _a='1', _b='2').xml(), + b'
    • <>
    ') + + def test_OL(self): + self.assertEqual(OL('<>', _a='1', _b='2').xml(), + b'
    1. <>
    ') + + def test_TD(self): + self.assertEqual(TD('<>', _a='1', _b='2').xml(), + b'<>') + + def test_TH(self): + self.assertEqual(TH('<>', _a='1', _b='2').xml(), + b'<>') + + def test_TR(self): + self.assertEqual(TR('<>', _a='1', _b='2').xml(), + b'<>') + + def test_THEAD(self): + self.assertEqual(THEAD('<>', _a='1', _b='2').xml(), + b'<>') + # self.assertEqual(THEAD(TRHEAD('<>'), _a='1', _b='2').xml(), + # '<>') + self.assertEqual(THEAD(TR('<>'), _a='1', _b='2').xml(), + b'<>') + + def test_TBODY(self): + self.assertEqual(TBODY('<>', _a='1', _b='2').xml(), + b'<>') + + def test_TFOOT(self): + self.assertEqual(TFOOT('<>', _a='1', _b='2').xml(), + b'<>') + + def test_COL(self): + # Empty COL test + self.assertEqual(COL().xml(), b'') + # Not Empty COL test + self.assertEqual(COL(_span='2').xml(), b'') + # Commented for now not so sure how to make it pass properly was passing locally + # I think this test is interesting and add value + # This fail relate to python 2.6 limitation I think + # Failing COL test + # with self.assertRaises(SyntaxError) as cm: + # COL('<>').xml() + # self.assertEqual(cm.exception[0], ' tags cannot have components') + # For now + self.assertRaises(SyntaxError, COL, b'<>') + + def test_COLGROUP(self): + # Empty COLGROUP test + self.assertEqual(COLGROUP().xml(), b'') + # Not Empty COLGROUP test + self.assertEqual(COLGROUP('<>', _a='1', _b='2').xml(), b'<>') + + def test_TABLE(self): + self.assertEqual(TABLE('<>', _a='1', _b='2').xml(), + b'' + + b'
    <>
    ') + + def test_I(self): + self.assertEqual(I('<>', _a='1', _b='2').xml(), + b'<>') + + def test_IFRAME(self): + self.assertEqual(IFRAME('<>', _a='1', _b='2').xml(), + b'') + + def test_INPUT(self): + self.assertEqual(INPUT(_a='1', _b='2').xml(), b'') + # list value + self.assertEqual(INPUT(_value=[1, 2, 3]).xml(), b'') + + def test_TEXTAREA(self): + self.assertEqual(TEXTAREA('<>', _a='1', _b='2').xml(), + b'') + # override _rows and _cols + self.assertEqual(TEXTAREA('<>', _a='1', _b='2', _rows=5, _cols=20).xml(), + b'') + self.assertEqual(TEXTAREA('<>', value='bla bla bla...', _rows=10, _cols=40).xml(), + b'') + + def test_OPTION(self): + self.assertEqual(OPTION('<>', _a='1', _b='2').xml(), + b'') + + def test_OBJECT(self): + self.assertEqual(OBJECT('<>', _a='1', _b='2').xml(), + b'<>') + + def test_OPTGROUP(self): + # Empty OPTGROUP test + self.assertEqual(OPTGROUP().xml(), + b'') + # Not Empty OPTGROUP test + self.assertEqual(OPTGROUP('<>', _a='1', _b='2').xml(), + b'') + # With an OPTION + self.assertEqual(OPTGROUP(OPTION('Option 1', _value='1'), _label='Group 1').xml(), + b'') + + def test_SELECT(self): + self.assertEqual(SELECT('<>', _a='1', _b='2').xml(), + b'') + self.assertEqual(SELECT(OPTION('option 1', _value='1'), + OPTION('option 2', _value='2')).xml(), + b'') + self.assertEqual(SELECT(OPTION('option 1', _value='1', _selected='selected'), + OPTION('option 2', _value='2'), + _multiple='multiple').xml(), + b'') + # More then one select with mutilple + self.assertEqual(SELECT(OPTION('option 1', _value='1', _selected='selected'), + OPTION('option 2', _value='2', _selected='selected'), + _multiple='multiple').xml(), + b'' + ) + # OPTGROUP + self.assertEqual(SELECT(OPTGROUP(OPTION('option 1', _value='1'), + OPTION('option 2', _value='2'), + _label='Group 1',)).xml(), + b'') + # List + self.assertEqual(SELECT([1, 2, 3, 4, 5]).xml(), + b'') + # Tuple + self.assertEqual(SELECT((1, 2, 3, 4, 5)).xml(), + b'') + # String value + self.assertEqual(SELECT('Option 1', 'Option 2').xml(), + b'') + # list as a value + self.assertEqual(SELECT(OPTION('option 1', _value=[1, 2, 3]), + OPTION('option 2', _value=[4, 5, 6], _selected='selected'), + _multiple='multiple').xml(), + b'') + + def test_FIELDSET(self): + self.assertEqual(FIELDSET('<>', _a='1', _b='2').xml(), + b'
    <>
    ') + + def test_LEGEND(self): + self.assertEqual(LEGEND('<>', _a='1', _b='2').xml(), + b'<>') + + def test_FORM(self): + self.assertEqual(FORM('<>', _a='1', _b='2').xml(), + b'
    <>
    ') + # These 2 crash AppVeyor and Travis with: "ImportError: No YAML serializer available" + # self.assertEqual(FORM('<>', _a='1', _b='2').as_yaml(), + # "accepted: null\nattributes: {_a: '1', _action: '#', _b: '2', _enctype: multipart/form-data, _method: post}\ncomponents: [<>]\nerrors: {}\nlatest: {}\nparent: null\nvars: {}\n") + # TODO check tags content + self.assertEqual(len(FORM('<>', _a='1', _b='2').as_xml()), 334) + + def test_BEAUTIFY(self): + #self.assertEqual(BEAUTIFY(['a', 'b', {'hello': 'world'}]).xml(), + # '
    a
    b
    hello:
    world
    ') + # unicode + self.assertEqual(BEAUTIFY([P(u'àéèûôç'), 'a', 'b', {'hello': 'world'}]).xml(), + b'

    \xc3\xa0\xc3\xa9\xc3\xa8\xc3\xbb\xc3\xb4\xc3\xa7

    a
    b
    hello:
    world
    ') + + def test_MENU(self): + self.assertEqual(MENU([('Home', False, '/welcome/default/index', [])]).xml(), + b'') + # Multiples entries menu + self.assertEqual(MENU([('Home', False, '/welcome/default/index', []), + ('Item 1', False, '/welcome/default/func_one', []), + ('Item 2', False, '/welcome/default/func_two', []), + ('Item 3', False, '/welcome/default/func_three', []), + ('Item 4', False, '/welcome/default/func_four', [])]).xml(), + b'' + ) + # mobile=True + self.assertEqual(MENU([('Home', False, '/welcome/default/index', [])], mobile=True).xml(), + b'') + # Multiples entries menu for mobile + self.assertEqual(MENU([('Home', False, '/welcome/default/index', []), + ('Item 1', False, '/welcome/default/func_one', []), + ('Item 2', False, '/welcome/default/func_two', []), + ('Item 3', False, '/welcome/default/func_three', []), + ('Item 4', False, '/welcome/default/func_four', [])], mobile=True).xml(), + b'') + + # TODO: def test_embed64(self): + + def test_web2pyHTMLParser(self): + #tag should not be a byte + self.assertEqual(web2pyHTMLParser("
    ").tree.components[0].tag, 'div') + a = str(web2pyHTMLParser('
    ab
    c').tree) + self.assertEqual(a, "
    ab
    c") + + tree = web2pyHTMLParser('hello
    world
    ').tree + tree.element(_a='b')['_c']=5 + self.assertEqual(str(tree), 'hello
    world
    ') + + a = str(web2pyHTMLParser('
    ', closed=['img']).tree) + self.assertEqual(a, '
    ') + + #greater-than sign ( > ) --> decimal > --> hexadecimal > + #Less-than sign ( < ) --> decimal < --> hexadecimal < + # test decimal + a = str(web2pyHTMLParser('
    < >
    ').tree) + self.assertEqual(a, '
    < >
    ') + # test hexadecimal + a = str(web2pyHTMLParser('
    < >
    ').tree) + self.assertEqual(a, '
    < >
    ') + + def test_markdown(self): + def markdown(text, tag=None, attributes={}): + r = {None: re.sub('\s+',' ',text), \ + 'h1':'#'+text+'\\n\\n', \ + 'p':text+'\\n'}.get(tag,text) + return r + a=TAG('

    Header

    this is a test

    ') + ret = a.flatten(markdown) + self.assertEqual(ret, '#Header\\n\\nthis is a test\\n') + + # TODO: def test_markdown_serializer(self): + + # TODO: def test_markmin_serializer(self): + + def test_MARKMIN(self): + # This test pass with python 2.7 but expected to fail under 2.6 + # with self.assertRaises(TypeError) as cm: + # MARKMIN().xml() + # self.assertEqual(cm.exception[0], '__init__() takes at least 2 arguments (1 given)') + # For now + self.assertRaises(TypeError, MARKMIN) + self.assertEqual(MARKMIN('').xml(), b'') + self.assertEqual(MARKMIN('<>').xml(), + b'

    <>

    ') + self.assertEqual(MARKMIN("``hello_world = 'Hello World!'``:python").xml(), + b'hello_world = \'Hello World!\'') + self.assertEqual(MARKMIN('<>').flatten(), b'<>') + + def test_ASSIGNJS(self): + # empty assignation + self.assertEqual(ASSIGNJS().xml(), b'') + # text assignation + self.assertEqual(ASSIGNJS(var1='1').xml(), b'var var1 = "1";\n') + # int assignation + self.assertEqual(ASSIGNJS(var2=2).xml(), b'var var2 = 2;\n') + + +class TestData(unittest.TestCase): + + def test_Adata(self): + self.assertEqual(A('<>', data=dict(abc='', cde='standard'), _a='1', _b='2').xml(), + b'<>') diff --git a/web2py/gluon/tests/test_http.py b/web2py/gluon/tests/test_http.py new file mode 100644 index 0000000..7091b0a --- /dev/null +++ b/web2py/gluon/tests/test_http.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""Unit tests for http.py """ + +import unittest + +from gluon.http import HTTP, defined_status + + +class TestHTTP(unittest.TestCase): + """ Tests http.HTTP """ + + def test_status_message(self): + """ Tests http status code message """ + + h = HTTP + + def gen_status_str(code, message): + return str(code) + ' ' + str(message) + message = '1423 This is a custom message' + code = 1423 + self.assertEqual(str(h(gen_status_str(code, message))), + gen_status_str(code, message)) + + # test predefined codes + for code in defined_status.keys(): + self.assertEqual( + str(h(code)), + gen_status_str(code, defined_status[code])) + + # test correct use of status_message + for code in defined_status.keys(): + self.assertEqual(str(h(gen_status_str(code, message))), + gen_status_str(code, message)) + + # test wrong call detection diff --git a/web2py/gluon/tests/test_is_url.py b/web2py/gluon/tests/test_is_url.py new file mode 100644 index 0000000..51a204d --- /dev/null +++ b/web2py/gluon/tests/test_is_url.py @@ -0,0 +1,692 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Unit tests for IS_URL() +""" + +import unittest + +from gluon.validators import IS_URL, IS_HTTP_URL, IS_GENERIC_URL +from gluon.validators import unicode_to_ascii_authority + + +class TestIsUrl(unittest.TestCase): + + def testModeHttp(self): + + # defaults to mode='http' + + x = IS_URL() + self.assertEqual(x('http://google.ca'), ('http://google.ca', + None)) + self.assertEqual(x('google.ca'), ('http://google.ca', None)) + self.assertEqual(x('google.ca:80'), ('http://google.ca:80', + None)) + self.assertEqual(x('unreal.blargg'), ('unreal.blargg', + 'Enter a valid URL')) + self.assertEqual(x('google..ca'), ('google..ca', 'Enter a valid URL')) + self.assertEqual( + x('google.ca..'), ('google.ca..', 'Enter a valid URL')) + + # explicit use of 'http' mode + + x = IS_URL(mode='http') + self.assertEqual(x('http://google.ca'), ('http://google.ca', + None)) + self.assertEqual(x('google.ca'), ('http://google.ca', None)) + self.assertEqual(x('google.ca:80'), ('http://google.ca:80', + None)) + self.assertEqual(x('unreal.blargg'), ('unreal.blargg', + 'Enter a valid URL')) + + # prepends 'https' instead of 'http' + + x = IS_URL(mode='http', prepend_scheme='https') + self.assertEqual(x('http://google.ca'), ('http://google.ca', + None)) + self.assertEqual(x('google.ca'), ('https://google.ca', None)) + self.assertEqual(x('google.ca:80'), ('https://google.ca:80', + None)) + self.assertEqual(x('unreal.blargg'), ('unreal.blargg', + 'Enter a valid URL')) + + # prepending disabled + + x = IS_URL(prepend_scheme=None) + self.assertEqual(x('http://google.ca'), ('http://google.ca', + None)) + self.assertEqual(x('google.ca'), ('google.ca', None)) + self.assertEqual(x('google.ca:80'), ('google.ca:80', None)) + self.assertEqual(x('unreal.blargg'), ('unreal.blargg', + 'Enter a valid URL')) + + # custom allowed_schemes + + x = IS_URL(mode='http', allowed_schemes=[None, 'http']) + self.assertEqual(x('http://google.ca'), ('http://google.ca', + None)) + self.assertEqual(x('https://google.ca'), ('https://google.ca', + 'Enter a valid URL')) + self.assertEqual(x('google.ca'), ('http://google.ca', None)) + self.assertEqual(x('google.ca:80'), ('http://google.ca:80', + None)) + self.assertEqual(x('unreal.blargg'), ('unreal.blargg', + 'Enter a valid URL')) + + # custom allowed_schemes, excluding None + + x = IS_URL(allowed_schemes=['http']) + self.assertEqual(x('http://google.ca'), ('http://google.ca', + None)) + self.assertEqual(x('https://google.ca'), ('https://google.ca', + 'Enter a valid URL')) + self.assertEqual(x('google.ca'), ('google.ca', 'Enter a valid URL')) + self.assertEqual(x('google.ca:80'), ('google.ca:80', + 'Enter a valid URL')) + self.assertEqual(x('unreal.blargg'), ('unreal.blargg', + 'Enter a valid URL')) + + # custom allowed_schemes and prepend_scheme + + x = IS_URL(allowed_schemes=[None, 'https'], + prepend_scheme='https') + self.assertEqual(x('http://google.ca'), ('http://google.ca', + 'Enter a valid URL')) + self.assertEqual(x('https://google.ca'), ('https://google.ca', + None)) + self.assertEqual(x('google.ca'), ('https://google.ca', None)) + self.assertEqual(x('google.ca:80'), ('https://google.ca:80', + None)) + self.assertEqual(x('unreal.blargg'), ('unreal.blargg', + 'Enter a valid URL')) + + # Now any URL requiring prepending will fail, but prepending is still + # enabled! + + x = IS_URL(allowed_schemes=['http']) + self.assertEqual(x('google.ca'), ('google.ca', 'Enter a valid URL')) + + def testModeGeneric(self): + + # 'generic' mode + + x = IS_URL(mode='generic') + self.assertEqual(x('http://google.ca'), ('http://google.ca', None)) + self.assertEqual(x('google.ca'), ('google.ca', None)) + self.assertEqual(x('google.ca:80'), ('http://google.ca:80', None)) + self.assertEqual(x('blargg://unreal'), ('blargg://unreal', + 'Enter a valid URL')) + + # 'generic' mode with custom allowed_schemes that still includes + # 'http' (the default for prepend_scheme) + + x = IS_URL(mode='generic', allowed_schemes=['http', 'blargg']) + self.assertEqual(x('http://google.ca'), ('http://google.ca', + None)) + self.assertEqual(x('ftp://google.ca'), ('ftp://google.ca', + 'Enter a valid URL')) + self.assertEqual(x('google.ca'), ('google.ca', 'Enter a valid URL')) + self.assertEqual(x('google.ca:80'), ('google.ca:80', + 'Enter a valid URL')) + self.assertEqual(x('blargg://unreal'), ('blargg://unreal', + None)) + + # 'generic' mode with overriden prepend_scheme + + x = IS_URL(mode='generic', prepend_scheme='ftp') + self.assertEqual(x('http://google.ca'), ('http://google.ca', + None)) + self.assertEqual(x('ftp://google.ca'), ('ftp://google.ca', + None)) + self.assertEqual(x('google.ca'), ('google.ca', None)) + self.assertEqual(x('google.ca:80'), ('ftp://google.ca:80', + None)) + self.assertEqual(x('blargg://unreal'), ('blargg://unreal', + 'Enter a valid URL')) + + # 'generic' mode with overriden allowed_schemes and prepend_scheme + + x = IS_URL(mode='generic', allowed_schemes=[None, 'ftp', 'ftps' + ], prepend_scheme='ftp') + self.assertEqual(x('http://google.ca'), ('http://google.ca', + 'Enter a valid URL')) + self.assertEqual(x('google.ca'), ('google.ca', None)) + self.assertEqual(x('ftp://google.ca'), ('ftp://google.ca', + None)) + self.assertEqual(x('google.ca:80'), ('ftp://google.ca:80', + None)) + self.assertEqual(x('blargg://unreal'), ('blargg://unreal', + 'Enter a valid URL')) + + # Now any URL requiring prepending will fail, but prepending is still + # enabled! + + x = IS_URL(mode='generic', allowed_schemes=['http']) + self.assertEqual(x('google.ca'), ('google.ca', 'Enter a valid URL')) + + def testExceptionalUse(self): + + # mode must be in set ['http', 'generic'] + + try: + x = IS_URL(mode='ftp') + x('http://www.google.ca') + except Exception as e: + if str(e) != "invalid mode 'ftp' in IS_URL": + self.fail('Wrong exception: ' + str(e)) + else: + self.fail("Accepted invalid mode: 'ftp'") + + # allowed_schemes in 'http' mode must be in set [None, 'http', 'https'] + + try: + x = IS_URL(allowed_schemes=[None, 'ftp', 'ftps'], + prepend_scheme='ftp') + x('http://www.benn.ca') # we can only reasonably know about the + # error at calling time + except Exception as e: + if str(e)\ + != "allowed_scheme value 'ftp' is not in [None, 'http', 'https']": + self.fail('Wrong exception: ' + str(e)) + else: + self.fail( + "Accepted invalid allowed_schemes: [None, 'ftp', 'ftps']") + + # prepend_scheme's value must be in allowed_schemes (default for 'http' + # mode is [None, 'http', 'https']) + + try: + x = IS_URL(prepend_scheme='ftp') + x('http://www.benn.ca') # we can only reasonably know about the + # error at calling time + except Exception as e: + if str(e)\ + != "prepend_scheme='ftp' is not in allowed_schemes=[None, 'http', 'https']": + self.fail('Wrong exception: ' + str(e)) + else: + self.fail("Accepted invalid prepend_scheme: 'ftp'") + + # custom allowed_schemes that excludes 'http', so prepend_scheme must be + # specified! + + try: + x = IS_URL(allowed_schemes=[None, 'https']) + except Exception as e: + if str(e)\ + != "prepend_scheme='http' is not in allowed_schemes=[None, 'https']": + self.fail('Wrong exception: ' + str(e)) + else: + self.fail("Accepted invalid prepend_scheme: 'http'") + + # prepend_scheme must be in allowed_schemes + + try: + x = IS_URL(allowed_schemes=[None, 'http'], + prepend_scheme='https') + except Exception as e: + if str(e)\ + != "prepend_scheme='https' is not in allowed_schemes=[None, 'http']": + self.fail('Wrong exception: ' + str(e)) + else: + self.fail("Accepted invalid prepend_scheme: 'https'") + + # prepend_scheme's value (default is 'http') must be in allowed_schemes + + try: + x = IS_URL(mode='generic', allowed_schemes=[None, 'ftp', + 'ftps']) + except Exception as e: + if str(e)\ + != "prepend_scheme='http' is not in allowed_schemes=[None, 'ftp', 'ftps']": + self.fail('Wrong exception: ' + str(e)) + else: + self.fail("Accepted invalid prepend_scheme: 'http'") + + # prepend_scheme's value must be in allowed_schemes, which by default + # is all schemes that really exist + + try: + x = IS_URL(mode='generic', prepend_scheme='blargg') + x('http://www.google.ca') + # we can only reasonably know about the error at calling time + except Exception as e: + if not str(e).startswith( + "prepend_scheme='blargg' is not in allowed_schemes="): + self.fail('Wrong exception: ' + str(e)) + else: + self.fail("Accepted invalid prepend_scheme: 'blargg'") + + # prepend_scheme's value must be in allowed_schemes + + try: + x = IS_URL(mode='generic', allowed_schemes=[None, 'http'], + prepend_scheme='blargg') + except Exception as e: + if str(e)\ + != "prepend_scheme='blargg' is not in allowed_schemes=[None, 'http']": + self.fail('Wrong exception: ' + str(e)) + else: + self.fail("Accepted invalid prepend_scheme: 'blargg'") + + # Not inluding None in the allowed_schemes essentially disabled + # prepending, so even though + # prepend_scheme has the invalid value 'http', we don't care! + + x = IS_URL(allowed_schemes=['https'], prepend_scheme='https') + self.assertEqual(x('google.ca'), ('google.ca', 'Enter a valid URL')) + + # Not inluding None in the allowed_schemes essentially disabled prepending, so even though + # prepend_scheme has the invalid value 'http', we don't care! + + x = IS_URL(mode='generic', allowed_schemes=['https'], + prepend_scheme='https') + self.assertEqual(x('google.ca'), ('google.ca', 'Enter a valid URL')) + + +# ############################################################################## + + +class TestIsGenericUrl(unittest.TestCase): + + x = IS_GENERIC_URL() + + def testInvalidUrls(self): + urlsToCheckA = [] + for i in list(range(0, 32)) + [127]: + + # Control characters are disallowed in any part of a URL + + urlsToCheckA.append('http://www.benn' + chr(i) + '.ca') + + urlsToCheckB = [ + None, + '', + 'http://www.no spaces allowed.com', + 'http://www.benn.ca/no spaces allowed/', + 'http://www.benn.ca/angle_bracket/', + 'http://www.benn.ca/invalid%character', + 'http://www.benn.ca/illegal%%20use', + 'http://www.benn.ca/illegaluse%', + 'http://www.benn.ca/illegaluse%0', + 'http://www.benn.ca/illegaluse%x', + 'http://www.benn.ca/ill%egaluse%x', + 'http://www.benn.ca/double"quote/', + 'http://www.curly{brace.com', + 'http://www.benn.ca/curly}brace/', + 'http://www.benn.ca/or|symbol/', + 'http://www.benn.ca/back\slash', + 'http://www.benn.ca/the^carat', + 'http://left[bracket.me', + 'http://www.benn.ca/right]bracket', + 'http://www.benn.ca/angle`quote', + '-ttp://www.benn.ca', + '+ttp://www.benn.ca', + '.ttp://www.benn.ca', + '9ttp://www.benn.ca', + 'ht;tp://www.benn.ca', + 'ht@tp://www.benn.ca', + 'ht&tp://www.benn.ca', + 'ht=tp://www.benn.ca', + 'ht$tp://www.benn.ca', + 'ht,tp://www.benn.ca', + 'ht:tp://www.benn.ca', + 'htp://invalid_scheme.com', + ] + + failures = [] + + for url in urlsToCheckA + urlsToCheckB: + if self.x(url)[1] is None: + failures.append('Incorrectly accepted: ' + str(url)) + + if len(failures) > 0: + self.fail(failures) + + def testValidUrls(self): + urlsToCheck = [ + 'ftp://ftp.is.co.za/rfc/rfc1808.txt', + 'gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles', + 'http://www.math.uio.no/faq/compression-faq/part1.html', + 'mailto:mduerst@ifi.unizh.ch', + 'news:comp.infosystems.www.servers.unix', + 'telnet://melvyl.ucop.edu/', + 'hTTp://www.benn.ca', + '%66%74%70://ftp.is.co.za/rfc/rfc1808.txt', + '%46%74%70://ftp.is.co.za/rfc/rfc1808.txt', + '/faq/compression-faq/part1.html', + 'google.com', + 'www.google.com:8080', + '128.127.123.250:8080', + 'blargg:ping', + 'http://www.benn.ca', + 'http://benn.ca', + 'http://amazon.com/books/', + 'https://amazon.com/movies', + 'rtsp://idontknowthisprotocol', + 'HTTP://allcaps.com', + 'http://localhost', + 'http://localhost#fragment', + 'http://localhost/hello', + 'http://localhost/hello?query=True', + 'http://localhost/hello/', + 'http://localhost:8080', + 'http://localhost:8080/', + 'http://localhost:8080/hello', + 'http://localhost:8080/hello/', + 'file:///C:/Documents%20and%20Settings/Jonathan/Desktop/view.py', + ] + + failures = [] + + for url in urlsToCheck: + if self.x(url)[1] is not None: + failures.append('Incorrectly rejected: ' + str(url)) + + if len(failures) > 0: + self.fail(failures) + + def testPrepending(self): + # Does not prepend scheme for abbreviated domains + self.assertEqual(self.x('google.ca'), ('google.ca', None)) + + # Does not prepend scheme for abbreviated domains + self.assertEqual(self.x('google.ca:8080'), ('google.ca:8080', None)) + + # Does not prepend when scheme already exists + self.assertEqual(self.x('https://google.ca'), + ('https://google.ca', None)) + + # Does not prepend if None type is not specified in allowed_scheme, + # because a scheme is required + + y = IS_GENERIC_URL(allowed_schemes=['http', 'blargg'], + prepend_scheme='http') + self.assertEqual(y('google.ca'), ('google.ca', 'Enter a valid URL')) + + +# ############################################################################## + + +class TestIsHttpUrl(unittest.TestCase): + + x = IS_HTTP_URL() + + def testInvalidUrls(self): + urlsToCheck = [ + None, + '', + 'http://invalid' + chr(2) + '.com', + 'htp://invalid_scheme.com', + 'blargg://invalid_scheme.com', + 'http://-123.com', + 'http://abcd-.ca', + 'http://-abc123-.me', + 'http://www.dom&ain.com/', + 'http://www.dom=ain.com/', + 'http://www.benn.ca&', + 'http://%62%65%6E%6E%2E%63%61/path', + 'http://.domain.com', + 'http://.domain.com./path', + 'http://domain..com', + 'http://domain...at..com', + 'http://domain.com..', + 'http://domain.com../path', + 'http://domain.3m', + 'http://domain.-3m', + 'http://domain.3m-', + 'http://domain.-3m-', + 'http://domain.co&m', + 'http://domain.m3456', + 'http://domain.m-3/path#fragment', + 'http://domain.m---k/path?query=value', + 'http://23.32..', + 'http://23..32.56.0', + 'http://38997.222.999', + 'http://23.32.56.99.', + 'http://.23.32.56.99', + 'http://.23.32.56.99.', + 'http://w127.123.0.256:8080', + 'http://23.32.56.99:abcd', + 'http://23.32.56.99:23cd', + 'http://google.com:cd22', + 'http://23.32:1300.56.99', + 'http://www.yahoo:1600.com', + 'path/segment/without/starting/slash', + 'http://www.math.uio.no;param=3', + '://ABC.com:/%7esmith/home.html', + ] + + failures = [] + + for url in urlsToCheck: + if self.x(url)[1] is None: + failures.append('Incorrectly accepted: ' + str(url)) + + if len(failures) > 0: + self.fail(failures) + + def testValidUrls(self): + + urlsToCheck = [ + 'http://abc.com:80/~smith/home.html', + 'http://ABC.com/%7Esmith/home.html', + 'http://ABC.com:/%7esmith/home.html', + 'http://www.math.uio.no/faq/compression-faq/part1.html', + '//google.ca/faq/compression-faq/part1.html', + '//google.ca/faq;param=3', + '//google.ca/faq/index.html?query=5', + '//google.ca/faq/index.html;param=value?query=5', + '/faq/compression-faq/part1.html', + '/faq;param=3', + '/faq/index.html?query=5', + '/faq/index.html;param=value?query=5', + 'google.com', + 'benn.ca/init/default', + 'benn.ca/init;param=value/default?query=value', + 'http://host-name---with-dashes.me', + 'http://www.host-name---with-dashes.me', + 'http://a.com', + 'http://a.3.com', + 'http://a.bl-ck.com', + 'http://bl-e.b.com', + 'http://host123with456numbers.ca', + 'http://1234567890.com.', + 'http://1234567890.com./path', + 'http://google.com./path', + 'http://domain.xn--d1acj3b', + 'http://127.123.0.256', + 'http://127.123.0.256/document/drawer', + '127.123.0.256/document/', + '156.212.123.100', + 'http://www.google.com:180200', + 'http://www.google.com:8080/path', + 'http://www.google.com:8080', + '//www.google.com:8080', + 'www.google.com:8080', + 'http://127.123.0.256:8080/path', + '//127.123.0.256:8080', + '127.123.0.256:8080', + 'http://example.me??query=value?', + 'http://a.com', + 'http://3.com', + 'http://www.benn.ca', + 'http://benn.ca', + 'http://amazon.com/books/', + 'https://amazon.com/movies', + 'hTTp://allcaps.com', + 'http://localhost', + 'HTTPS://localhost.', + 'http://localhost#fragment', + 'http://localhost/hello;param=value', + 'http://localhost/hello;param=value/hi;param2=value2;param3=value3', + 'http://localhost/hello?query=True', + 'http://www.benn.ca/hello;param=value/hi;param2=value2;param3=value3/index.html?query=3', + 'http://localhost/hello/?query=1500&five=6', + 'http://localhost:8080', + 'http://localhost:8080/', + 'http://localhost:8080/hello', + 'http://localhost:8080/hello%20world/', + 'http://www.a.3.be-nn.5.ca', + 'http://www.amazon.COM', + ] + + failures = [] + + for url in urlsToCheck: + if self.x(url)[1] is not None: + failures.append('Incorrectly rejected: ' + str(url)) + + if len(failures) > 0: + self.fail(failures) + + def testPrepending(self): + # prepends scheme for abbreviated domains + self.assertEqual(self.x('google.ca'), ('http://google.ca', None)) + + # prepends scheme for abbreviated domains + self.assertEqual(self.x('google.ca:8080'), + ('http://google.ca:8080', None)) + + # does not prepend when scheme already exists + self.assertEqual(self.x('https://google.ca'), + ('https://google.ca', None)) + + y = IS_HTTP_URL( + prepend_scheme='https', allowed_schemes=[None, 'https']) + self.assertEqual(y('google.ca'), ( + 'https://google.ca', None)) # prepends https if asked + + z = IS_HTTP_URL(prepend_scheme=None) + self.assertEqual(z('google.ca:8080'), ('google.ca:8080', + None)) # prepending disabled + + try: + IS_HTTP_URL(prepend_scheme='mailto') + except Exception as e: + if str(e)\ + != "prepend_scheme='mailto' is not in allowed_schemes=[None, 'http', 'https']": + self.fail('Wrong exception: ' + str(e)) + else: + self.fail("Got invalid prepend_scheme: 'mailto'") + + # Does not prepend if None type is not specified in allowed_scheme, because a scheme is required + + a = IS_HTTP_URL(allowed_schemes=['http']) + self.assertEqual(a('google.ca'), ('google.ca', 'Enter a valid URL')) + self.assertEqual(a('google.ca:80'), ('google.ca:80', + 'Enter a valid URL')) + + +class TestUnicode(unittest.TestCase): + x = IS_URL() + y = IS_URL(allowed_schemes=['https'], prepend_scheme='https') + #excludes the option for abbreviated URLs with no scheme + z = IS_URL(prepend_scheme=None) + # disables prepending the scheme in the return value + + def testUnicodeToAsciiUrl(self): + self.assertEqual(unicode_to_ascii_authority(u'www.Alliancefran\xe7aise.nu'), 'www.xn--alliancefranaise-npb.nu') + self.assertEqual( + unicode_to_ascii_authority(u'www.benn.ca'), 'www.benn.ca') + self.assertRaises(UnicodeError, unicode_to_ascii_authority, + u'\u4e2d' * 1000) # label is too long + + def testValidUrls(self): + self.assertEqual(self.x(u'www.Alliancefrancaise.nu'), ( + 'http://www.Alliancefrancaise.nu', None)) + self.assertEqual(self.x(u'www.Alliancefran\xe7aise.nu'), ( + 'http://www.xn--alliancefranaise-npb.nu', None)) + self.assertEqual(self.x(u'www.Alliancefran\xe7aise.nu:8080'), ( + 'http://www.xn--alliancefranaise-npb.nu:8080', None)) + self.assertEqual(self.x(u'http://www.Alliancefran\xe7aise.nu'), + ('http://www.xn--alliancefranaise-npb.nu', None)) + self.assertEqual(self.x(u'http://www.Alliancefran\xe7aise.nu/parnaise/blue'), ('http://www.xn--alliancefranaise-npb.nu/parnaise/blue', None)) + self.assertEqual(self.x(u'http://www.Alliancefran\xe7aise.nu/parnaise/blue#fragment'), ('http://www.xn--alliancefranaise-npb.nu/parnaise/blue#fragment', None)) + self.assertEqual(self.x(u'http://www.Alliancefran\xe7aise.nu/parnaise/blue?query=value#fragment'), ('http://www.xn--alliancefranaise-npb.nu/parnaise/blue?query=value#fragment', None)) + self.assertEqual(self.x(u'http://www.Alliancefran\xe7aise.nu:8080/parnaise/blue?query=value#fragment'), ('http://www.xn--alliancefranaise-npb.nu:8080/parnaise/blue?query=value#fragment', None)) + self.assertEqual(self.x(u'www.Alliancefran\xe7aise.nu/parnaise/blue?query=value#fragment'), ('http://www.xn--alliancefranaise-npb.nu/parnaise/blue?query=value#fragment', None)) + self.assertEqual(self.x( + u'http://\u4e2d\u4fd4.com'), ('http://xn--fiq13b.com', None)) + self.assertEqual(self.x(u'http://\u4e2d\u4fd4.com/\u4e86'), + ('http://xn--fiq13b.com/%4e%86', None)) + self.assertEqual(self.x(u'http://\u4e2d\u4fd4.com/\u4e86?query=\u4e86'), ('http://xn--fiq13b.com/%4e%86?query=%4e%86', None)) + self.assertEqual(self.x(u'http://\u4e2d\u4fd4.com/\u4e86?query=\u4e86#fragment'), ('http://xn--fiq13b.com/%4e%86?query=%4e%86#fragment', None)) + self.assertEqual(self.x(u'http://\u4e2d\u4fd4.com?query=\u4e86#fragment'), ('http://xn--fiq13b.com?query=%4e%86#fragment', None)) + self.assertEqual( + self.x(u'http://B\xfccher.ch'), ('http://xn--bcher-kva.ch', None)) + self.assertEqual(self.x(u'http://\xe4\xf6\xfc\xdf.com'), ( + 'http://xn--ss-uia6e4a.com', None)) + self.assertEqual(self.x( + u'http://visegr\xe1d.com'), ('http://xn--visegrd-mwa.com', None)) + self.assertEqual(self.x(u'http://h\xe1zipatika.com'), ( + 'http://xn--hzipatika-01a.com', None)) + self.assertEqual(self.x(u'http://www.\xe7ukurova.com'), ( + 'http://www.xn--ukurova-txa.com', None)) + self.assertEqual(self.x(u'http://nixier\xf6hre.nixieclock-tube.com'), ('http://xn--nixierhre-57a.nixieclock-tube.com', None)) + self.assertEqual(self.x(u'google.ca.'), ('http://google.ca.', None)) + + self.assertEqual( + self.y(u'https://google.ca'), ('https://google.ca', None)) + self.assertEqual(self.y( + u'https://\u4e2d\u4fd4.com'), ('https://xn--fiq13b.com', None)) + + self.assertEqual(self.z(u'google.ca'), ('google.ca', None)) + + def testInvalidUrls(self): + self.assertEqual( + self.x(u'://ABC.com'), (u'://ABC.com', 'Enter a valid URL')) + self.assertEqual(self.x(u'http://\u4e2d\u4fd4.dne'), ( + u'http://\u4e2d\u4fd4.dne', 'Enter a valid URL')) + self.assertEqual(self.x(u'https://google.dne'), ( + u'https://google.dne', 'Enter a valid URL')) + self.assertEqual(self.x(u'https://google..ca'), ( + u'https://google..ca', 'Enter a valid URL')) + self.assertEqual( + self.x(u'google..ca'), (u'google..ca', 'Enter a valid URL')) + self.assertEqual(self.x(u'http://' + u'\u4e2d' * 1000 + u'.com'), ( + u'http://' + u'\u4e2d' * 1000 + u'.com', 'Enter a valid URL')) + + self.assertEqual(self.x(u'http://google.com#fragment_\u4e86'), ( + u'http://google.com#fragment_\u4e86', 'Enter a valid URL')) + self.assertEqual(self.x(u'http\u4e86://google.com'), ( + u'http\u4e86://google.com', 'Enter a valid URL')) + self.assertEqual(self.x(u'http\u4e86://google.com#fragment_\u4e86'), ( + u'http\u4e86://google.com#fragment_\u4e86', 'Enter a valid URL')) + + self.assertEqual(self.y(u'http://\u4e2d\u4fd4.com/\u4e86'), ( + u'http://\u4e2d\u4fd4.com/\u4e86', 'Enter a valid URL')) + #self.assertEqual(self.y(u'google.ca'), (u'google.ca', 'Enter a valid URL')) + + self.assertEqual(self.z(u'invalid.domain..com'), ( + u'invalid.domain..com', 'Enter a valid URL')) + self.assertEqual(self.z(u'invalid.\u4e2d\u4fd4.blargg'), ( + u'invalid.\u4e2d\u4fd4.blargg', 'Enter a valid URL')) + +# ############################################################################## + + +class TestSimple(unittest.TestCase): + + def test_IS_URL(self): + rtn = IS_URL()('abc.com') + self.assertEqual(rtn, ('http://abc.com', None)) + rtn = IS_URL(mode='generic')('abc.com') + self.assertEqual(rtn, ('abc.com', None)) + rtn = IS_URL(allowed_schemes=['https'], prepend_scheme='https')('https://abc.com') + self.assertEqual(rtn, ('https://abc.com', None)) + rtn = IS_URL(prepend_scheme='https')('abc.com') + self.assertEqual(rtn, ('https://abc.com', None)) + rtn = IS_URL(mode='generic', allowed_schemes=['ftps', 'https'], prepend_scheme='https')('https://abc.com') + self.assertEqual(rtn, ('https://abc.com', None)) + rtn = IS_URL(mode='generic', allowed_schemes=['ftps', 'https', None], prepend_scheme='https')('abc.com') + self.assertEqual(rtn, ('abc.com', None)) + # regression test for issue 773 + rtn = IS_URL()('domain.ninja') + self.assertEqual(rtn, ('http://domain.ninja', None)) + # addition of allowed_tlds + rtn = IS_URL(allowed_tlds=['com', 'net', 'org'])('domain.ninja') + self.assertEqual(rtn, ('domain.ninja', 'Enter a valid URL')) + # mode = 'generic' doesn't consider allowed_tlds + rtn = IS_URL(mode='generic', allowed_tlds=['com', 'net', 'org'])('domain.ninja') + self.assertEqual(rtn, ('domain.ninja', None)) diff --git a/web2py/gluon/tests/test_languages.py b/web2py/gluon/tests/test_languages.py new file mode 100644 index 0000000..cfa07cb --- /dev/null +++ b/web2py/gluon/tests/test_languages.py @@ -0,0 +1,367 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" + Unit tests for gluon.languages +""" + +import sys +import os +import shutil +import tempfile +import unittest + +from gluon import languages +from gluon._compat import PY2, to_unicode, to_bytes +from gluon.storage import Messages +from gluon.html import SPAN + +MP_WORKING = 0 +try: + import multiprocessing + MP_WORKING = 1 + #due to http://bugs.python.org/issue10845, testing multiprocessing in python is impossible + if sys.platform.startswith('win'): + MP_WORKING = 0 + #multiprocessing is also not available on GAE. Since tests randomly + #fail, let's not make them on it too + if 'datastore' in os.getenv('DB', ''): + MP_WORKING = 0 +except ImportError: + pass + + +def read_write(args): + (filename, iterations) = args + for i in range(0, iterations): + content = languages.read_dict(filename) + if not len(content): + return False + languages.write_dict(filename, content) + return True + + +class TestLanguagesParallel(unittest.TestCase): + + def setUp(self): + self.filename = tempfile.mktemp() + contents = dict() + for i in range(1000): + contents["key%d" % i] = "value%d" % i + languages.write_dict(self.filename, contents) + languages.read_dict(self.filename) + + def tearDown(self): + try: + os.remove(self.filename) + except: + pass + + @unittest.skipIf(MP_WORKING == 0, 'multiprocessing tests unavailable') + def test_reads_and_writes(self): + readwriters = 10 + pool = multiprocessing.Pool(processes=readwriters) + results = pool.map(read_write, [[self.filename, 10]] * readwriters) + for result in results: + self.assertTrue(result) + + @unittest.skipIf(MP_WORKING == 1, 'multiprocessing tests available') + def test_reads_and_writes_no_mp(self): + results = [] + for i in range(10): + results.append(read_write([self.filename, 10])) + for result in results: + self.assertTrue(result) + + +class TestTranslations(unittest.TestCase): + + def setUp(self): + if os.path.isdir('gluon'): + self.langpath = 'applications/welcome/languages' + else: + self.langpath = os.path.realpath( + '../../applications/welcome/languages') + self.http_accept_language = 'en' + + def tearDown(self): + pass + + def test_plain(self): + T = languages.translator(self.langpath, self.http_accept_language) + self.assertEqual(str(T('Hello World')), + 'Hello World') + self.assertEqual(str(T('Hello World## comment')), + 'Hello World') + self.assertEqual(str(T.M('**Hello World**')), + 'Hello World') + # sub_tuple testing + self.assertEqual(str(T('%s %%{shop}', 1)), + '1 shop') + self.assertEqual(str(T('%s %%{shop}', 2)), + '2 shops') + self.assertEqual(str(T('%%{quark(%s)}', 1)), + 'quark') + self.assertEqual(str(T('%%{quark(%i)}', 2)), + 'quarks') + self.assertEqual(str(T('%%{!quark(%s)}', 1)), + 'Quark') + self.assertEqual(str(T('%%{!!quark(%i)}', 2)), + 'Quarks') + self.assertEqual(str(T('%%{!!!quark(%s)}', 0)), + 'QUARKS') + self.assertEqual(str(T('%%{?an?%i}', 1)), + 'an') + self.assertEqual(str(T('%%{?an?%s}', 0)), + '0') + self.assertEqual(str(T('%%{??%i}', 1)), + '') + self.assertEqual(str(T('%%{??%s}', 2)), + '2') + self.assertEqual(str(T('%%{?%i}', 1)), + '') + self.assertEqual(str(T('%%{?%s}', 0)), + '0') + self.assertEqual(str(T('%%{?one?%i?zero}', 1)), + 'one') + self.assertEqual(str(T('%%{?one?%s?zero}', 23)), + '23') + self.assertEqual(str(T('%%{?one?%i?zero}', 0)), + 'zero') + self.assertEqual(str(T('%%{?one?%s?}', 1)), + 'one') + self.assertEqual(str(T('%%{?one?%i?}', 23)), + '23') + self.assertEqual(str(T('%%{?one?%s?}', 0)), + '') + self.assertEqual(str(T('%%{??%i?zero}', 1)), + '') + self.assertEqual(str(T('%%{??%s?zero}', 23)), + '23') + self.assertEqual(str(T('%%{??%i?zero}', 0)), + 'zero') + self.assertEqual(str(T('%%{??1?}%s', '')), + '') + self.assertEqual(str(T('%%{??%s?}', 23)), + '23') + self.assertEqual(str(T('%%{??0?}%s', '')), + '') + self.assertEqual(str(T('%s %%{shop[0]}', 1)), + '1 shop') + self.assertEqual(str(T('%s %%{shop[0]}', 2)), + '2 shops') + self.assertEqual(str(T('%i %%{?one?not_one[0]}', 1)), + '1 one') + self.assertEqual(str(T('%i %%{?one?not_one[0]}', 2)), + '2 not_one') + self.assertEqual(str(T('%%{??on[0]} %i', 1)), + ' 1') + self.assertEqual(str(T('%%{??on[0]} %s', 0)), + 'on 0') + self.assertEqual(str(T('%%{?on[0]} %s', 1)), + ' 1') + self.assertEqual(str(T('%%{?on[0]} %i', 2)), + 'on 2') + self.assertEqual(str(T('%i %%{?one?or_more?zero[0]}', 1)), + '1 one') + self.assertEqual(str(T('%i %%{?one?or_more?zero[0]}', 2)), + '2 or_more') + self.assertEqual(str(T('%i %%{?one?or_more?zero[0]}', 0)), + '0 zero') + self.assertEqual(str(T('%i %%{?one?hands?[0]}', 1)), + '1 one') + self.assertEqual(str(T('%s %%{?one?hands?[0]}', 2)), + '2 hands') + self.assertEqual(str(T('%i %%{?one?hands?[0]}', 0)), + '0 ') + self.assertEqual(str(T('%s %%{??or_more?zero[0]}', 1)), + '1 ') + self.assertEqual(str(T('%i %%{??or_more?zero[0]}', 2)), + '2 or_more') + self.assertEqual(str(T('%s %%{??or_more?zero[0]}', 0)), + '0 zero') + self.assertEqual(str(T('%i%%{??nd?[0]}', 1)), + '1') + self.assertEqual(str(T('%i%%{??nd?[0]}', 2)), + '2nd') + self.assertEqual(str(T('%i%%{??nd?[0]}', 0)), + '0') + self.assertEqual(str(T('%i%%{?st?[0]}', 1)), + '1st') + self.assertEqual(str(T('%i%%{?st?[0]}', 2)), + '2') + self.assertEqual(str(T('%i%%{?st?[0]}', 0)), + '0') + # sub_dict testing + self.assertEqual(str(T('%(key)s %%{is(key)}', dict(key=1))), + '1 is') + self.assertEqual(str(T('%(key)i %%{is(key)}', dict(key=2))), + '2 are') + self.assertEqual(str(T('%%{!!!is(%(key)s)}', dict(key=2))), + 'ARE') + self.assertEqual(str(T('%(key)i %%{?not_one(key)}', dict(key=1))), + '1 ') + self.assertEqual(str(T('%(key)s %%{?not_one(key)}', dict(key=2))), + '2 not_one') + self.assertEqual(str(T('%(key)i %%{?not_one(key)}', dict(key=0))), + '0 not_one') + self.assertEqual(str(T('%(key)s %%{?one?not_one(key)}', dict(key=1))), + '1 one') + self.assertEqual(str(T('%(key)i %%{?one?not_one(key)}', dict(key=2))), + '2 not_one') + self.assertEqual(str(T('%(key)s %%{?one?not_one(key)}', dict(key=0))), + '0 not_one') + self.assertEqual(str(T('%(key)i %%{?one?(key)}', dict(key=1))), + '1 one') + self.assertEqual(str(T('%(key)s %%{?one?(key)}', dict(key=2))), + '2 ') + self.assertEqual(str(T('%(key)i %%{?one?(key)}', dict(key=0))), + '0 ') + self.assertEqual(str(T('%(key)s %%{??not_one(key)}', dict(key=1))), + '1 ') + self.assertEqual(str(T('%(key)i %%{??not_one(key)}', dict(key=2))), + '2 not_one') + self.assertEqual(str(T('%(key)s %%{?not_one(key)}', dict(key=1))), + '1 ') + self.assertEqual(str(T('%(key)i %%{?not_one(key)}', dict(key=0))), + '0 not_one') + self.assertEqual(str(T('%(key)s %%{?one?other?zero(key)}', dict(key=1))), + '1 one') + self.assertEqual(str(T('%(key)i %%{?one?other?zero(key)}', dict(key=4))), + '4 other') + self.assertEqual(str(T('%(key)s %%{?one?other?zero(key)}', dict(key=0))), + '0 zero') + self.assertEqual(str(T('%(key)i %%{?one?two_or_more?(key)}', dict(key=1))), + '1 one') + self.assertEqual(str(T('%(key)s %%{?one?two_or_more?(key)}', dict(key=2))), + '2 two_or_more') + self.assertEqual(str(T('%(key)i %%{?one?two_or_more?(key)}', dict(key=0))), + '0 ') + self.assertEqual(str(T('%(key)s %%{??two_or_more?zero(key)}', dict(key=1))), + '1 ') + self.assertEqual(str(T('%(key)i %%{??two_or_more?zero(key)}', dict(key=2))), + '2 two_or_more') + self.assertEqual(str(T('%(key)s %%{??two_or_more?zero(key)}', dict(key=0))), + '0 zero') + self.assertEqual(str(T('%(key)i %%{??two_or_more?(key)}', dict(key=1))), + '1 ') + self.assertEqual(str(T('%(key)s %%{??two_or_more?(key)}', dict(key=0))), + '0 ') + self.assertEqual(str(T('%(key)i %%{??two_or_more?(key)}', dict(key=2))), + '2 two_or_more') + T.force('it') + self.assertEqual(str(T('Hello World')), + 'Salve Mondo') + self.assertEqual(to_unicode(T('Hello World')), + 'Salve Mondo') + +class TestDummyApp(unittest.TestCase): + + def setUp(self): + pjoin = os.path.join + self.apppath = os.path.abspath(pjoin(os.path.dirname(os.path.abspath(__file__)), 'dummy')) + os.mkdir(self.apppath) + os.mkdir(pjoin(self.apppath, 'languages')) + os.mkdir(pjoin(self.apppath, 'models')) + os.mkdir(pjoin(self.apppath, 'controllers')) + os.mkdir(pjoin(self.apppath, 'views')) + os.mkdir(pjoin(self.apppath, 'views', 'default')) + os.mkdir(pjoin(self.apppath, 'modules')) + with open(pjoin(self.apppath, 'languages', 'en.py'), 'w') as testlang: + testlang.write( +""" +{} +""" + ) + with open(pjoin(self.apppath, 'languages', 'pt.py'), 'w') as testlang: + testlang.write( +""" +{} +""" + ) + with open(pjoin(self.apppath, 'modules', 'test.py'), 'w') as testmodule: + testmodule.write( +""" +from gluon import current + +hello = current.T('hello') +""" ) + with open(pjoin(self.apppath, 'models', 'db.py'), 'w') as testmodel: + testmodel.write( +""" +world = T("world") +""" + ) + with open(pjoin(self.apppath, 'controllers', 'default.py'), 'w') as testcontroller: + testcontroller.write( +""" +def index(): + message = T('%s %%{shop}', 2) + return dict(message=message) +""" + ) + with open(pjoin(self.apppath, 'views', 'default', 'index.html'), 'w') as testview: + testview.write( +""" + + + + +

    {{=T('ahoy')}}

    + + +""" + ) + + def tearDown(self): + shutil.rmtree(self.apppath) + + def test_update_all_languages(self): + languages.update_all_languages(self.apppath) + en_file = os.path.join(self.apppath, 'languages', 'en.py') + pt_file = os.path.join(self.apppath, 'languages', 'pt.py') + en_dict = languages.read_dict(en_file) + pt_dict = languages.read_dict(pt_file) + for key in ['hello', 'world', '%s %%{shop}', 'ahoy']: + self.assertTrue(key in en_dict) + self.assertTrue(key in pt_dict) + +class TestMessages(unittest.TestCase): + + def setUp(self): + if os.path.isdir('gluon'): + self.langpath = 'applications/welcome/languages' + else: + self.langpath = os.path.realpath( + '../../applications/welcome/languages') + self.http_accept_language = 'en' + + def tearDown(self): + pass + + def test_decode(self): + T = languages.translator(self.langpath, self.http_accept_language) + messages = Messages(T) + messages.update({'email_sent':'Email sent', 'test': "ä"}) + self.assertEqual(to_unicode(messages.email_sent, 'utf-8'), 'Email sent') + +class TestHTMLTag(unittest.TestCase): + + def setUp(self): + if os.path.isdir('gluon'): + self.langpath = 'applications/welcome/languages' + else: + self.langpath = os.path.realpath( + '../../applications/welcome/languages') + self.http_accept_language = 'en' + + def tearDown(self): + pass + + def test_decode(self): + T = languages.translator(self.langpath, self.http_accept_language) + elem = SPAN(T("Complete")) + self.assertEqual(elem.flatten(), "Complete") + elem = SPAN(T("Cannot be empty", language="ru")) + self.assertEqual(elem.xml(), to_bytes('Пустое значение недопустимо')) + self.assertEqual(elem.flatten(), 'Пустое значение недопустимо') diff --git a/web2py/gluon/tests/test_old_doctests.py b/web2py/gluon/tests/test_old_doctests.py new file mode 100644 index 0000000..d1303cc --- /dev/null +++ b/web2py/gluon/tests/test_old_doctests.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" Unit tests for old doctests in utf8.py, html.py, markmin2html.py. + Don't abuse doctests, web2py > 2.4.5 will accept only unittests +""" + +import doctest +import unittest + +def load_tests(loader, tests, ignore): + + tests.addTests( + doctest.DocTestSuite('gluon.html') + ) + tests.addTests( + doctest.DocTestSuite('gluon.utf8') + ) + + tests.addTests( + doctest.DocTestSuite('gluon.contrib.markmin.markmin2html', + ) + ) + + return tests + +if __name__ == '__main__': + unittest.main() diff --git a/web2py/gluon/tests/test_recfile.py b/web2py/gluon/tests/test_recfile.py new file mode 100644 index 0000000..03e3638 --- /dev/null +++ b/web2py/gluon/tests/test_recfile.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" + Unit tests for gluon.recfile +""" +import unittest +import os +import shutil +import uuid + + +from gluon import recfile + + +class TestRecfile(unittest.TestCase): + + def setUp(self): + os.mkdir('tests') + + def tearDown(self): + shutil.rmtree('tests') + + def test_generation(self): + for k in range(10): + teststring = 'test%s' % k + filename = os.path.join('tests', str(uuid.uuid4()) + '.test') + with recfile.open(filename, "w") as g: + g.write(teststring) + with recfile.open(filename, "r") as f: + self.assertEqual(f.read(), teststring) + is_there = recfile.exists(filename) + self.assertTrue(is_there) + recfile.remove(filename) + is_there = recfile.exists(filename) + self.assertFalse(is_there) + for k in range(10): + teststring = 'test%s' % k + filename = str(uuid.uuid4()) + '.test' + with recfile.open(filename, "w", path='tests') as g: + g.write(teststring) + with recfile.open(filename, "r", path='tests') as f: + self.assertEqual(f.read(), teststring) + is_there = recfile.exists(filename, path='tests') + self.assertTrue(is_there) + recfile.remove(filename, path='tests') + is_there = recfile.exists(filename, path='tests') + self.assertFalse(is_there) + for k in range(10): + teststring = 'test%s' % k + filename = os.path.join('tests', str(uuid.uuid4()), str(uuid.uuid4()) + '.test') + with recfile.open(filename, "w") as g: + g.write(teststring) + with recfile.open(filename, "r") as f: + self.assertEqual(f.read(), teststring) + is_there = recfile.exists(filename) + self.assertTrue(is_there) + recfile.remove(filename) + is_there = recfile.exists(filename) + self.assertFalse(is_there) + + def test_existing(self): + filename = os.path.join('tests', str(uuid.uuid4()) + '.test') + with open(filename, 'w') as g: + g.write('this file exists') + self.assertTrue(recfile.exists(filename)) + r = recfile.open(filename, "r") + self.assertTrue(hasattr(r, 'read')) + r.close() + recfile.remove(filename, path='tests') + self.assertFalse(recfile.exists(filename)) + self.assertRaises(IOError, recfile.remove, filename) + self.assertRaises(IOError, recfile.open, filename, "r") + diff --git a/web2py/gluon/tests/test_rocket.py b/web2py/gluon/tests/test_rocket.py new file mode 100644 index 0000000..a394e89 --- /dev/null +++ b/web2py/gluon/tests/test_rocket.py @@ -0,0 +1,3 @@ +# TODO : I think we should continue to use pathoc (http://pathod.net/docs/pathoc) for tests but integrate the call in +# gluon/tests so they run automatically. No need to make our own tests. +# ref: https://groups.google.com/d/msg/web2py-developers/Cjye8_hXZk8/AXbftS3sCgAJ diff --git a/web2py/gluon/tests/test_router.py b/web2py/gluon/tests/test_router.py new file mode 100644 index 0000000..132f8a0 --- /dev/null +++ b/web2py/gluon/tests/test_router.py @@ -0,0 +1,1558 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""Unit tests for rewrite.py routers option""" +from __future__ import print_function +import os +import unittest +import tempfile +import logging + +from gluon.rewrite import load, filter_url, filter_err, get_effective_router, map_url_out +from gluon.html import URL +from gluon.fileutils import abspath +from gluon.settings import global_settings +from gluon.http import HTTP +from gluon.storage import Storage +from gluon._compat import to_bytes, PY2 + +logger = None +oldcwd = None +root = None + +def norm_root(root): + return root.replace('/', os.sep) + +def setUpModule(): + def make_apptree(): + "build a temporary applications tree" + # applications/ + os.mkdir(abspath('applications')) + + # applications/app/ + for app in ('admin', 'examples', 'welcome'): + os.mkdir(abspath('applications', app)) + # applications/app/(controllers, static) + for subdir in ('controllers', 'static'): + os.mkdir(abspath('applications', app, subdir)) + + # applications/admin/controllers/*.py + for ctr in ('appadmin', 'default', 'gae', 'mercurial', 'shell', 'wizard'): + open(abspath('applications', 'admin', + 'controllers', '%s.py' % ctr), 'w').close() + # applications/examples/controllers/*.py + for ctr in ('ajax_examples', 'appadmin', 'default', 'global', 'spreadsheet'): + open(abspath('applications', 'examples', + 'controllers', '%s.py' % ctr), 'w').close() + # applications/welcome/controllers/*.py + # (include controller that collides with another app) + for ctr in ('appadmin', 'default', 'other', 'admin'): + open(abspath('applications', 'welcome', + 'controllers', '%s.py' % ctr), 'w').close() + + # create an app-specific routes.py for examples app + routes = open(abspath('applications', 'examples', 'routes.py'), 'w') + routes.write("routers=dict(examples=dict(default_function='exdef'))") + routes.close() + + # create language files for examples app + for lang in ('en', 'it'): + os.mkdir(abspath('applications', 'examples', 'static', lang)) + open(abspath('applications', 'examples', 'static', + lang, 'file'), 'w').close() + + global oldcwd + if oldcwd is None: # do this only once + oldcwd = os.getcwd() + if not os.path.isdir('gluon'): + os.chdir(os.path.realpath( + '../../')) # run from web2py base directory + import gluon.main # for initialization after chdir + global logger + logger = logging.getLogger('web2py.rewrite') + global_settings.applications_parent = tempfile.mkdtemp() + global root + root = global_settings.applications_parent + make_apptree() + + +def tearDownModule(): + global oldcwd + if oldcwd is not None: + os.chdir(oldcwd) + oldcwd = None + + +class TestRouter(unittest.TestCase): + """ Tests the routers logic from gluon.rewrite """ + + def myassertRaisesRegex(self, *args, **kwargs): + if PY2: + return getattr(self, 'assertRaisesRegexp')(*args, **kwargs) + return getattr(self, 'assertRaisesRegex')(*args, **kwargs) + + def test_router_syntax(self): + """ Test router syntax error """ + level = logger.getEffectiveLevel() + logger.setLevel(logging.CRITICAL) # disable logging temporarily + self.assertRaises(SyntaxError, load, data='x::y') + self.assertRaises( + SyntaxError, load, rdict=dict(BASE=dict(badkey="value"))) + self.assertRaises(SyntaxError, load, rdict=dict( + BASE=dict(), app=dict(default_application="name"))) + + self.myassertRaisesRegex(SyntaxError, "invalid syntax", + load, data='x::y') + self.myassertRaisesRegex(SyntaxError, "unknown key", + load, rdict=dict(BASE=dict(badkey="value"))) + self.myassertRaisesRegex(SyntaxError, "BASE-only key", + load, rdict=dict(BASE=dict(), app=dict(default_application="name"))) + logger.setLevel(level) + + def test_router_null(self): + """ Tests the null router """ + load(rdict=dict()) + # app resolution + self.assertEqual( + filter_url('http://domain.com/welcome', app=True), 'welcome') + self.assertEqual(filter_url('http://domain.com/', app=True), 'init') + # incoming + self.assertEqual(filter_url('http://domain.com/favicon.ico'), + norm_root('%s/applications/init/static/favicon.ico' % root)) + self.assertEqual( + filter_url('http://domain.com/abc'), '/init/default/abc') + self.assertEqual(filter_url( + 'http://domain.com/index/abc'), "/init/default/index ['abc']") + self.assertEqual(filter_url( + 'http://domain.com/abc/def'), "/init/default/abc ['def']") + self.assertEqual(filter_url( + 'http://domain.com/index/a%20bc'), "/init/default/index ['a bc']") + self.assertEqual(filter_url('http://domain.com/welcome/static/path/to/static').replace('/', os.sep), + norm_root("%s/applications/welcome/static/path/to/static" % root)) + self.assertRaises(HTTP, filter_url, 'http://domain.com/welcome/static/bad/path/to/st~tic') + self.myassertRaisesRegex(HTTP, "400.*invalid static file", filter_url, 'http://domain.com/welcome/static/bad/path/to/st~tic') + # outgoing + self.assertEqual( + filter_url('http://domain.com/init/default/index', out=True), '/') + self.assertEqual(filter_url('http://domain.com/init/default/index/arg1', out=True), '/index/arg1') + self.assertEqual(filter_url( + 'http://domain.com/init/default/abc', out=True), '/abc') + self.assertEqual(filter_url('http://domain.com/init/static/abc', + out=True), '/init/static/abc') + self.assertEqual(filter_url( + 'http://domain.com/init/appadmin/index', out=True), '/appadmin') + self.assertEqual(filter_url( + 'http://domain.com/init/appadmin/abc', out=True), '/appadmin/abc') + self.assertEqual(filter_url( + 'http://domain.com/init/admin/index', out=True), '/init/admin') + self.assertEqual(filter_url( + 'http://domain.com/init/admin/abc', out=True), '/init/admin/abc') + self.assertEqual(filter_url( + 'http://domain.com/admin/default/abc', out=True), '/admin/abc') + + def test_router_specific(self): + """ + Test app-specific routes.py + + Note that make_apptree above created applications/examples/routes.py with a default_function. + """ + load(rdict=dict()) + self.assertEqual( + filter_url('http://domain.com/welcome'), '/welcome/default/index') + self.assertEqual( + filter_url('http://domain.com/examples'), '/examples/default/exdef') + + def test_router_defapp(self): + """ Test the default-application function """ + routers = dict(BASE=dict(default_application='welcome')) + load(rdict=routers) + # app resolution + self.assertEqual( + filter_url('http://domain.com/welcome', app=True), 'welcome') + self.assertEqual(filter_url('http://domain.com/', app=True), 'welcome') + # incoming + self.assertEqual( + filter_url('http://domain.com'), '/welcome/default/index') + self.assertEqual( + filter_url('http://domain.com/'), '/welcome/default/index') + self.assertEqual(filter_url( + 'http://domain.com/appadmin'), '/welcome/appadmin/index') + self.assertEqual( + filter_url('http://domain.com/abc'), '/welcome/default/abc') + self.assertEqual(filter_url( + 'http://domain.com/index/abc'), "/welcome/default/index ['abc']") + self.assertEqual(filter_url( + 'http://domain.com/abc/def'), "/welcome/default/abc ['def']") + self.assertEqual(filter_url('http://domain.com/favicon.ico'), + norm_root('%s/applications/welcome/static/favicon.ico' % root)) + self.assertEqual(filter_url('http://domain.com/static/abc'), + norm_root('%s/applications/welcome/static/abc' % root)) + self.assertEqual(filter_url('http://domain.com/static/path/to/static').replace('/', os.sep), + norm_root("%s/applications/welcome/static/path/to/static" % root)) + # outgoing + self.assertEqual(filter_url( + 'http://domain.com/welcome/default/index', out=True), '/') + self.assertEqual(filter_url('http://domain.com/welcome/default/index/arg1', out=True), '/index/arg1') + self.assertEqual(filter_url( + 'http://domain.com/welcome/default/abc', out=True), '/abc') + self.assertEqual(filter_url('http://domain.com/welcome/default/admin', + out=True), '/default/admin') + self.assertEqual( + filter_url('http://domain.com/welcome/static/abc', out=True), + '/welcome/static/abc') + self.assertEqual(filter_url('http://domain.com/welcome/appadmin/index', + out=True), '/appadmin') + self.assertEqual(filter_url('http://domain.com/welcome/appadmin/abc', + out=True), '/appadmin/abc') + self.assertEqual(filter_url('http://domain.com/welcome/admin/index', + out=True), '/welcome/admin') + self.assertEqual(filter_url('http://domain.com/welcome/admin/abc', + out=True), '/welcome/admin/abc') + self.assertEqual(filter_url( + 'http://domain.com/admin/default/abc', out=True), '/admin/abc') + + def test_router_nodef(self): + """ Test no-default functions """ + routers = dict( + BASE=dict(default_application='welcome'), + welcome=dict(controllers=None), + ) + load(rdict=routers) + # outgoing + self.assertEqual(filter_url( + 'http://domain.com/welcome/default/index', out=True), '/default') + self.assertEqual(filter_url('http://domain.com/welcome/default/index/arg1', out=True), '/default/index/arg1') + self.assertEqual(filter_url('http://domain.com/welcome/default/abc', + out=True), '/default/abc') + self.assertEqual( + filter_url('http://domain.com/welcome/static/abc', out=True), + '/welcome/static/abc') + self.assertEqual(filter_url('http://domain.com/welcome/appadmin/index', + out=True), '/appadmin') + self.assertEqual(filter_url('http://domain.com/welcome/appadmin/abc', + out=True), '/appadmin/abc') + self.assertEqual(filter_url('http://domain.com/welcome/admin/index', + out=True), '/welcome/admin') + self.assertEqual(filter_url('http://domain.com/welcome/admin/abc', + out=True), '/welcome/admin/abc') + self.assertEqual(filter_url( + 'http://domain.com/admin/default/abc', out=True), '/admin/abc') + # incoming + self.assertEqual( + filter_url('http://domain.com'), '/welcome/default/index') + self.assertEqual( + filter_url('http://domain.com/'), '/welcome/default/index') + self.assertEqual(filter_url( + 'http://domain.com/appadmin'), '/welcome/appadmin/index') + self.assertEqual( + filter_url('http://domain.com/abc'), '/welcome/abc/index') + self.assertEqual( + filter_url('http://domain.com/index/abc'), "/welcome/index/abc") + self.assertEqual( + filter_url('http://domain.com/abc/def'), "/welcome/abc/def") + self.assertEqual(filter_url( + 'http://domain.com/abc/def/ghi'), "/welcome/abc/def ['ghi']") + + routers = dict( + BASE=dict(default_application=None), + ) + load(rdict=routers) + # outgoing + self.assertEqual(filter_url( + 'http://domain.com/welcome/default/index', out=True), '/welcome') + self.assertEqual(filter_url('http://domain.com/welcome/default/index/arg1', out=True), '/welcome/index/arg1') + self.assertEqual(filter_url('http://domain.com/welcome/default/abc', + out=True), '/welcome/abc') + self.assertEqual(filter_url('http://domain.com/welcome/static/abc', + out=True), '/welcome/static/abc') + self.assertEqual(filter_url('http://domain.com/welcome/appadmin/index', + out=True), '/welcome/appadmin') + self.assertEqual(filter_url('http://domain.com/welcome/appadmin/abc', + out=True), '/welcome/appadmin/abc') + self.assertEqual(filter_url('http://domain.com/welcome/admin/index', + out=True), '/welcome/admin') + self.assertEqual(filter_url('http://domain.com/welcome/admin/abc', + out=True), '/welcome/admin/abc') + self.assertEqual(filter_url( + 'http://domain.com/admin/default/abc', out=True), '/admin/abc') + # incoming + self.assertRaises(HTTP, filter_url, 'http://domain.com') + self.assertRaises(HTTP, filter_url, 'http://domain.com/appadmin') + self.myassertRaisesRegex(HTTP, "400.*invalid application", + filter_url, 'http://domain.com') + self.myassertRaisesRegex(HTTP, "400.*invalid application", + filter_url, 'http://domain.com/appadmin') + routers = dict( + BASE=dict(default_application='welcome', applications=None), + ) + load(rdict=routers) + # outgoing + self.assertEqual(filter_url( + 'http://domain.com/welcome/default/index', out=True), '/welcome') + self.assertEqual(filter_url('http://domain.com/welcome/default/index/arg1', out=True), '/welcome/index/arg1') + self.assertEqual(filter_url('http://domain.com/welcome/default/abc', + out=True), '/welcome/abc') + self.assertEqual(filter_url('http://domain.com/welcome/static/abc', + out=True), '/welcome/static/abc') + self.assertEqual(filter_url('http://domain.com/welcome/appadmin/index', + out=True), '/welcome/appadmin') + self.assertEqual(filter_url('http://domain.com/welcome/appadmin/abc', + out=True), '/welcome/appadmin/abc') + self.assertEqual(filter_url('http://domain.com/welcome/admin/index', + out=True), '/welcome/admin') + self.assertEqual(filter_url('http://domain.com/welcome/admin/abc', + out=True), '/welcome/admin/abc') + self.assertEqual(filter_url( + 'http://domain.com/admin/default/abc', out=True), '/admin/abc') + # incoming + self.assertEqual( + filter_url('http://domain.com'), '/welcome/default/index') + self.assertEqual( + filter_url('http://domain.com/'), '/welcome/default/index') + self.assertRaises(HTTP, filter_url, 'http://domain.com/appadmin') + self.myassertRaisesRegex(HTTP, "400.*unknown application: 'appadmin'", filter_url, 'http://domain.com/appadmin') + routers = dict( + BASE=dict(default_application='welcome', applications=None), + welcome=dict(controllers=None), + ) + load(rdict=routers) + # outgoing + self.assertEqual(filter_url('http://domain.com/welcome/default/index', + out=True), '/welcome/default') + self.assertEqual(filter_url('http://domain.com/welcome/default/index/arg1', out=True), '/welcome/default/index/arg1') + self.assertEqual(filter_url('http://domain.com/welcome/default/abc', + out=True), '/welcome/default/abc') + self.assertEqual(filter_url('http://domain.com/welcome/static/abc', + out=True), '/welcome/static/abc') + self.assertEqual(filter_url('http://domain.com/welcome/appadmin/index', + out=True), '/welcome/appadmin') + self.assertEqual(filter_url('http://domain.com/welcome/appadmin/abc', + out=True), '/welcome/appadmin/abc') + self.assertEqual(filter_url('http://domain.com/welcome/admin/index', + out=True), '/welcome/admin') + self.assertEqual(filter_url('http://domain.com/welcome/admin/abc', + out=True), '/welcome/admin/abc') + self.assertEqual(filter_url( + 'http://domain.com/admin/default/abc', out=True), '/admin/abc') + # incoming + self.assertEqual( + filter_url('http://domain.com'), '/welcome/default/index') + self.assertEqual( + filter_url('http://domain.com/'), '/welcome/default/index') + self.assertRaises(HTTP, filter_url, 'http://domain.com/appadmin') + self.myassertRaisesRegex(HTTP, "400.*unknown application: 'appadmin'", filter_url, 'http://domain.com/appadmin') + + routers = dict( + BASE=dict(default_application='welcome', applications=None), + welcome=dict(default_controller=None), + ) + load(rdict=routers) + # outgoing + self.assertEqual(filter_url('http://domain.com/welcome/default/index', + out=True), '/welcome/default') + self.assertEqual(filter_url('http://domain.com/welcome/default/index/arg1', out=True), '/welcome/default/index/arg1') + self.assertEqual(filter_url('http://domain.com/welcome/default/abc', + out=True), '/welcome/default/abc') + self.assertEqual(filter_url('http://domain.com/welcome/static/abc', + out=True), '/welcome/static/abc') + self.assertEqual(filter_url('http://domain.com/welcome/appadmin/index', + out=True), '/welcome/appadmin') + self.assertEqual(filter_url('http://domain.com/welcome/appadmin/abc', + out=True), '/welcome/appadmin/abc') + self.assertEqual(filter_url('http://domain.com/welcome/admin/index', + out=True), '/welcome/admin') + self.assertEqual(filter_url('http://domain.com/welcome/admin/abc', + out=True), '/welcome/admin/abc') + self.assertEqual(filter_url( + 'http://domain.com/admin/default/abc', out=True), '/admin/abc') + # incoming + self.assertRaises(HTTP, filter_url, 'http://domain.com') + self.assertRaises(HTTP, filter_url, 'http://domain.com/appadmin') + self.myassertRaisesRegex(HTTP, "400.*invalid controller", + filter_url, 'http://domain.com') + self.myassertRaisesRegex(HTTP, "400.*unknown application: 'appadmin'", filter_url, 'http://domain.com/appadmin') + + routers = dict( + BASE=dict(default_application='welcome', applications=None), + welcome=dict(controllers=None, default_function=None), + ) + load(rdict=routers) + # outgoing + self.assertEqual(filter_url('http://domain.com/welcome/default/index', + out=True), '/welcome/default/index') + self.assertEqual(filter_url('http://domain.com/welcome/default/index/arg1', out=True), '/welcome/default/index/arg1') + self.assertEqual(filter_url('http://domain.com/welcome/default/abc', + out=True), '/welcome/default/abc') + self.assertEqual(filter_url('http://domain.com/welcome/static/abc', + out=True), '/welcome/static/abc') + self.assertEqual(filter_url('http://domain.com/welcome/appadmin/index', + out=True), '/welcome/appadmin/index') + self.assertEqual(filter_url('http://domain.com/welcome/appadmin/abc', + out=True), '/welcome/appadmin/abc') + self.assertEqual(filter_url('http://domain.com/welcome/admin/index', + out=True), '/welcome/admin/index') + self.assertEqual(filter_url('http://domain.com/welcome/admin/abc', + out=True), '/welcome/admin/abc') + self.assertEqual(filter_url( + 'http://domain.com/admin/default/abc', out=True), '/admin/abc') + # incoming + self.assertRaises(HTTP, filter_url, 'http://domain.com') + self.assertRaises(HTTP, filter_url, 'http://domain.com/appadmin') + self.myassertRaisesRegex(HTTP, "400.*invalid function", + filter_url, 'http://domain.com') + self.myassertRaisesRegex(HTTP, "400.*unknown application: 'appadmin'", filter_url, 'http://domain.com/appadmin') + + def test_router_app(self): + """ Tests the doctest router app resolution""" + routers = dict( + BASE=dict( + domains={ + "domain1.com": "app1", + "www.domain1.com": "app1", + "domain2.com": "app2", + }, + ), + app1=dict(), + app2=dict(), + goodapp=dict(), + ) + routers['bad!app'] = dict() + load(rdict=routers) + self.assertEqual( + filter_url('http://domain.com/welcome', app=True), 'welcome') + self.assertEqual( + filter_url('http://domain.com/welcome/', app=True), 'welcome') + self.assertEqual(filter_url('http://domain.com', app=True), 'init') + self.assertEqual(filter_url('http://domain.com/', app=True), 'init') + self.assertEqual(filter_url('http://domain.com/abc', app=True), 'init') + self.assertEqual( + filter_url('http://domain1.com/abc', app=True), 'app1') + self.assertEqual( + filter_url('http://www.domain1.com/abc', app=True), 'app1') + self.assertEqual( + filter_url('http://domain2.com/abc', app=True), 'app2') + self.assertEqual( + filter_url('http://domain2.com/admin', app=True), 'admin') + + routers['BASE']['exclusive_domain'] = True + load(rdict=routers) + self.assertEqual( + filter_url('http://domain2.com/admin', app=True), 'app2') + + self.assertEqual( + filter_url('http://domain.com/goodapp', app=True), 'goodapp') + self.assertRaises( + HTTP, filter_url, 'http://domain.com/bad!app', app=True) + self.myassertRaisesRegex(HTTP, '400.*invalid application', + filter_url, 'http://domain.com/bad!app') + + routers['BASE']['domains']['domain3.com'] = 'app3' + self.assertRaises(SyntaxError, load, rdict=routers) + self.myassertRaisesRegex( + SyntaxError, "unknown.*app3", load, rdict=routers) + + def test_router_domains_fs(self): + ''' + Test URLs that map domains using test filesystem layout + ''' + routers = dict( + BASE=dict( + domains={ + "domain1.com": "admin", + "domain2.com": "welcome", + }, + ), + ) + + load(rdict=routers) + self.assertEqual( + filter_url('http://domain1.com'), '/admin/default/index') + self.assertEqual( + filter_url('http://domain2.com'), '/welcome/default/index') + self.assertEqual( + filter_url('http://domain1.com/gae'), '/admin/gae/index') + self.assertEqual( + filter_url('http://domain2.com/other'), '/welcome/other/index') + self.assertEqual( + filter_url('http://domain1.com/gae/f1'), '/admin/gae/f1') + self.assertEqual( + filter_url('http://domain2.com/f2'), '/welcome/default/f2') + self.assertEqual( + filter_url('http://domain2.com/other/f3'), '/welcome/other/f3') + + def test_router_domains(self): + ''' + Test URLs that map domains + ''' + routers = dict( + BASE=dict( + applications=['app1', 'app2', 'app2A', + 'app3', 'app4', 'app5', 'app6'], + domains={ + # two domains to the same app + "domain1.com": "app1", + "www.domain1.com": "app1", + # same domain, two ports, to two apps + "domain2.com": "app2a", + "domain2.com:8080": "app2b", + # two domains, same app, two controllers + "domain3a.com": "app3/c3a", + "domain3b.com": "app3/c3b", + # two domains, same app & controller, two functions + "domain4a.com": "app4/c4/f4a", + "domain4b.com": "app4/c4/f4b", + # http vs https + "domain6.com:80": "app6", + "domain6.com:443": "app6s", + }, + ), + app1=dict(default_controller='c1', default_function='f1', + controllers=['c1'], exclusive_domain=True, ), + app2a=dict(default_controller='c2a', + default_function='f2a', controllers=['c2a'], ), + app2b=dict(default_controller='c2b', + default_function='f2b', controllers=['c2b'], ), + app3=dict(controllers=['c3a', 'c3b'], ), + app4=dict(default_controller='c4', controllers=['c4']), + app5=dict(default_controller='c5', + controllers=['c5'], domain='localhost'), + app6=dict(default_controller='c6', + default_function='f6', controllers=['c6'], ), + app6s=dict(default_controller='c6s', + default_function='f6s', controllers=['c6s'], ), + ) + + load(rdict=routers) + self.assertEqual(filter_url('http://domain1.com/abc'), '/app1/c1/abc') + self.assertEqual( + filter_url('http://domain1.com/c1/abc'), '/app1/c1/abc') + self.assertEqual( + filter_url('http://domain1.com/abc.html'), '/app1/c1/abc') + self.assertEqual( + filter_url('http://domain1.com/abc.css'), '/app1/c1/abc.css') + self.assertEqual(filter_url( + 'http://domain1.com/index/abc'), "/app1/c1/index ['abc']") + self.assertEqual(filter_url('http://domain2.com/app1'), "/app1/c1/f1") + + self.assertEqual(filter_url('https://domain1.com/app1/ctr/fcn', + domain=('app1', None), out=True), "/ctr/fcn") + self.assertEqual(filter_url('https://www.domain1.com/app1/ctr/fcn', + domain=('app1', None), out=True), "/ctr/fcn") + + self.assertEqual( + filter_url('http://domain2.com/abc'), '/app2a/c2a/abc') + self.assertEqual( + filter_url('http://domain2.com:8080/abc'), '/app2b/c2b/abc') + + self.assertEqual(filter_url('http://domain2.com/app2a/ctr/fcn', + domain=('app2a', None), out=True), "/ctr/fcn") + self.assertEqual(filter_url('http://domain2.com/app2a/ctr/f2a', + domain=('app2a', None), out=True), "/ctr") + self.assertEqual(filter_url('http://domain2.com/app2a/c2a/f2a', + domain=('app2a', None), out=True), "/") + self.assertEqual(filter_url('http://domain2.com/app2a/c2a/fcn', + domain=('app2a', None), out=True), "/fcn") + self.assertEqual(filter_url('http://domain2.com/app2a/ctr/fcn', + domain=('app2b', None), out=True), "/app2a/ctr/fcn") + self.assertEqual(filter_url('http://domain2.com/app2a/ctr/f2a', + domain=('app2b', None), out=True), "/app2a/ctr") + self.assertEqual(filter_url('http://domain2.com/app2a/c2a/f2a', + domain=('app2b', None), out=True), "/app2a") + + self.assertEqual(filter_url('http://domain3a.com/'), '/app3/c3a/index') + self.assertEqual( + filter_url('http://domain3a.com/abc'), '/app3/c3a/abc') + self.assertEqual( + filter_url('http://domain3a.com/c3b'), '/app3/c3b/index') + self.assertEqual( + filter_url('http://domain3b.com/abc'), '/app3/c3b/abc') + + self.assertEqual(filter_url('http://domain3a.com/app3/c3a/fcn', + domain=('app3', 'c3a'), out=True), "/fcn") + self.assertEqual(filter_url('http://domain3a.com/app3/c3a/fcn', + domain=('app3', 'c3b'), out=True), "/c3a/fcn") + self.assertEqual(filter_url('http://domain3a.com/app3/c3a/fcn', + domain=('app1', None), out=True), "/app3/c3a/fcn") + + self.assertEqual(filter_url('http://domain4a.com/abc'), '/app4/c4/abc') + self.assertEqual(filter_url('https://domain4a.com/app4/c4/fcn', + domain=('app4', None), out=True), "/fcn") + + self.assertEqual(filter_url('http://domain4a.com'), '/app4/c4/f4a') + self.assertEqual(filter_url('http://domain4b.com'), '/app4/c4/f4b') + + self.assertEqual(filter_url('http://localhost/abc'), '/app5/c5/abc') + self.assertEqual(filter_url( + 'http:///abc'), '/app5/c5/abc') # test null host => localhost + self.assertEqual(filter_url('https://localhost/app5/c5/fcn', + domain=('app5', None), out=True), "/fcn") + + self.assertEqual(filter_url('http://domain6.com'), '/app6/c6/f6') + self.assertEqual(filter_url('https://domain6.com'), '/app6s/c6s/f6s') + + self.assertEqual(filter_url('http://domain2.com/app3/c3a/f3', + domain=('app2b', None), out=True), "/app3/c3a/f3") + self.assertRaises(SyntaxError, filter_url, 'http://domain1.com/app1/c1/f1', domain=('app2b', None), out=True) + self.myassertRaisesRegex(SyntaxError, 'cross-domain conflict', filter_url, + 'http://domain1.com/app1/c1/f1', domain=('app2b', None), out=True) + self.assertEqual(filter_url('http://domain1.com/app1/c1/f1', domain=( + 'app2b', None), host='domain2.com', out=True), "/app1") + + def test_router_domains_ed(self): + ''' + Test URLs that map domains with exclusive_domain set + ''' + routers = dict( + BASE=dict( + applications=['app1', 'app2', 'app2A', + 'app3', 'app4', 'app5', 'app6'], + exclusive_domain=True, + domains={ + # two domains to the same app + "domain1.com": "app1", + "www.domain1.com": "app1", + # same domain, two ports, to two apps + "domain2.com": "app2a", + "domain2.com:8080": "app2b", + # two domains, same app, two controllers + "domain3a.com": "app3/c3a", + "domain3b.com": "app3/c3b", + # two domains, same app & controller, two functions + "domain4a.com": "app4/c4/f4a", + "domain4b.com": "app4/c4/f4b", + # http vs https + "domain6.com:80": "app6", + "domain6.com:443": "app6s", + }, + ), + app1=dict(default_controller='c1', default_function='f1', + controllers=['c1'], exclusive_domain=True, ), + app2a=dict(default_controller='c2a', + default_function='f2a', controllers=['c2a'], ), + app2b=dict(default_controller='c2b', + default_function='f2b', controllers=['c2b'], ), + app3=dict(controllers=['c3a', 'c3b'], ), + app4=dict(default_controller='c4', controllers=['c4']), + app5=dict(default_controller='c5', + controllers=['c5'], domain='localhost'), + app6=dict(default_controller='c6', + default_function='f6', controllers=['c6'], ), + app6s=dict(default_controller='c6s', + default_function='f6s', controllers=['c6s'], ), + ) + + load(rdict=routers) + self.assertEqual(filter_url('http://domain1.com/abc'), '/app1/c1/abc') + self.assertEqual( + filter_url('http://domain1.com/c1/abc'), '/app1/c1/abc') + self.assertEqual( + filter_url('http://domain1.com/abc.html'), '/app1/c1/abc') + self.assertEqual( + filter_url('http://domain1.com/abc.css'), '/app1/c1/abc.css') + self.assertEqual(filter_url( + 'http://domain1.com/index/abc'), "/app1/c1/index ['abc']") + self.assertEqual( + filter_url('http://domain2.com/app1'), "/app2a/c2a/app1") + + self.assertEqual(filter_url('https://domain1.com/app1/ctr/fcn', + domain=('app1', None), out=True), "/ctr/fcn") + self.assertEqual(filter_url('https://www.domain1.com/app1/ctr/fcn', + domain=('app1', None), out=True), "/ctr/fcn") + + self.assertEqual( + filter_url('http://domain2.com/abc'), '/app2a/c2a/abc') + self.assertEqual( + filter_url('http://domain2.com:8080/abc'), '/app2b/c2b/abc') + + self.assertEqual(filter_url('http://domain2.com/app2a/ctr/fcn', + domain=('app2a', None), out=True), "/ctr/fcn") + self.assertEqual(filter_url('http://domain2.com/app2a/ctr/f2a', + domain=('app2a', None), out=True), "/ctr") + self.assertEqual(filter_url('http://domain2.com/app2a/c2a/f2a', + domain=('app2a', None), out=True), "/") + self.assertEqual(filter_url('http://domain2.com/app2a/c2a/fcn', + domain=('app2a', None), out=True), "/fcn") + + self.assertRaises(SyntaxError, filter_url, 'http://domain2.com/app2a/ctr/fcn', domain=('app2b', None), out=True) + self.assertRaises(SyntaxError, filter_url, 'http://domain2.com/app2a/ctr/f2a', domain=('app2b', None), out=True) + self.assertRaises(SyntaxError, filter_url, 'http://domain2.com/app2a/c2a/f2a', domain=('app2b', None), out=True) + + self.assertEqual(filter_url('http://domain3a.com/'), '/app3/c3a/index') + self.assertEqual( + filter_url('http://domain3a.com/abc'), '/app3/c3a/abc') + self.assertEqual( + filter_url('http://domain3a.com/c3b'), '/app3/c3b/index') + self.assertEqual( + filter_url('http://domain3b.com/abc'), '/app3/c3b/abc') + + self.assertEqual(filter_url('http://domain3a.com/app3/c3a/fcn', + domain=('app3', 'c3a'), out=True), "/fcn") + self.assertEqual(filter_url('http://domain3a.com/app3/c3a/fcn', + domain=('app3', 'c3b'), out=True), "/c3a/fcn") + + self.assertRaises(SyntaxError, filter_url, 'http://domain3a.com/app3/c3a/fcn', domain=('app1', None), out=True) + + self.assertEqual(filter_url('http://domain4a.com/abc'), '/app4/c4/abc') + self.assertEqual(filter_url('https://domain4a.com/app4/c4/fcn', + domain=('app4', None), out=True), "/fcn") + + self.assertEqual(filter_url('http://domain4a.com'), '/app4/c4/f4a') + self.assertEqual(filter_url('http://domain4b.com'), '/app4/c4/f4b') + + self.assertEqual(filter_url('http://localhost/abc'), '/app5/c5/abc') + self.assertEqual(filter_url( + 'http:///abc'), '/app5/c5/abc') # test null host => localhost + self.assertEqual(filter_url('https://localhost/app5/c5/fcn', + domain=('app5', None), out=True), "/fcn") + + self.assertEqual(filter_url('http://domain6.com'), '/app6/c6/f6') + self.assertEqual(filter_url('https://domain6.com'), '/app6s/c6s/f6s') + + self.assertRaises(SyntaxError, filter_url, 'http://domain2.com/app3/c3a/f3', domain=('app2b', None), out=True) + self.assertRaises(SyntaxError, filter_url, 'http://domain1.com/app1/c1/f1', domain=('app2b', None), out=True) + self.myassertRaisesRegex(SyntaxError, 'cross-domain conflict', filter_url, + 'http://domain1.com/app1/c1/f1', domain=('app2b', None), out=True) + self.assertEqual(filter_url('http://domain1.com/app1/c1/f1', domain=( + 'app2b', None), host='domain2.com', out=True), "/app1") + + def test_router_raise(self): + ''' + Test URLs that raise exceptions + ''' + # test non-exception variants + router_raise = dict( + init=dict( + controllers=[], + ), + welcome=dict( + map_hyphen=False, + ), + ) + load(rdict=router_raise) + self.assertEqual( + filter_url('http://domain.com/ctl'), "/init/ctl/index") + self.assertEqual( + filter_url('http://domain.com/default/fcn'), "/init/default/fcn") + self.assertEqual(filter_url( + 'http://domain.com/default/fcn.ext'), "/init/default/fcn.ext") + self.assertEqual(filter_url('http://domain.com/default/fcn/arg'), + "/init/default/fcn ['arg']") + # now raise-HTTP variants + self.assertRaises(HTTP, filter_url, 'http://domain.com/bad!ctl') + self.assertRaises(HTTP, filter_url, 'http://domain.com/ctl/bad!fcn') + self.assertRaises( + HTTP, filter_url, 'http://domain.com/ctl/fcn.bad!ext') + self.assertRaises( + HTTP, filter_url, 'http://domain.com/ctl/fcn/bad!arg') + self.myassertRaisesRegex(HTTP, '400.*invalid controller', filter_url, 'http://domain.com/init/bad!ctl') + self.myassertRaisesRegex(HTTP, '400.*invalid function', filter_url, + 'http://domain.com/init/ctlr/bad!fcn') + self.myassertRaisesRegex(HTTP, '400.*invalid extension', filter_url, + 'http://domain.com/init/ctlr/fcn.bad!ext') + self.myassertRaisesRegex(HTTP, '400.*invalid arg', filter_url, + 'http://domain.com/appc/init/fcn/bad!arg') + + self.assertEqual(filter_url('http://domain.com/welcome/default/fcn_1'), + "/welcome/default/fcn_1") + self.assertRaises( + HTTP, filter_url, 'http://domain.com/welcome/default/fcn-1') + self.myassertRaisesRegex(HTTP, '400.*invalid function', filter_url, + 'http://domain.com/welcome/default/fcn-1') + + def test_router_out(self): + ''' + Test basic outgoing routing + ''' + router_out = dict( + BASE=dict(), + init=dict(controllers=['default', 'ctr'], ), + app=dict(), + ) + load(rdict=router_out) + self.assertEqual(filter_url( + 'https://domain.com/app/ctr/fcn', out=True), "/app/ctr/fcn") + self.assertEqual(filter_url( + 'https://domain.com/init/ctr/fcn', out=True), "/ctr/fcn") + self.assertEqual(filter_url( + 'https://domain.com/init/ctr/fcn', out=True), "/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/init/static/file', + out=True), "/init/static/file") + self.assertEqual(filter_url('https://domain.com/init/static/index', + out=True), "/init/static/index") + self.assertEqual(filter_url( + 'https://domain.com/init/default/index', out=True), "/") + self.assertEqual( + filter_url('https://domain.com/init/ctr/index', out=True), "/ctr") + self.assertEqual(filter_url('http://domain.com/init/default/fcn?query', + out=True), "/fcn?query") + self.assertEqual(filter_url('http://domain.com/init/default/fcn#anchor', out=True), "/fcn#anchor") + self.assertEqual( + filter_url( + 'http://domain.com/init/default/fcn?query#anchor', out=True), + "/fcn?query#anchor") + + router_out['BASE']['map_static'] = True + load(rdict=router_out) + self.assertEqual(filter_url( + 'https://domain.com/init/static/file', out=True), "/static/file") + self.assertEqual(filter_url('https://domain.com/init/static/index', + out=True), "/static/index") + + router_out['init']['map_static'] = None + load(rdict=router_out) + self.assertEqual(filter_url('https://domain.com/init/static/file', + out=True), "/init/static/file") + self.assertEqual(filter_url('https://domain.com/init/static/index', + out=True), "/init/static/index") + + def test_router_functions(self): + ''' + Test function-omission with functions=[something] + ''' + router_functions = dict( + BASE=dict( + applications=['init', 'app', 'app2'], + default_application='app', + ), + init=dict( + controllers=['default'], + ), + app=dict( + controllers=['default', 'ctr'], + functions=dict( + default=['index', 'user', 'help'], + ctr=['ctrf1', 'ctrf2', 'ctrf3'], + ), + default_function=dict( + default='index', + ctr='ctrf1', + ), + ), + app2=dict( + controllers=['default', 'ctr'], + functions=['index', 'user', 'help'], + ), + ) + load(rdict=router_functions) + + # outbound + self.assertEqual(str( + URL(a='init', c='default', f='f', args=['arg1'])), "/init/f/arg1") + self.assertEqual(str(URL(a='init', c='default', f='index', + args=['arg1'])), "/init/index/arg1") + + self.assertEqual( + str(URL(a='app', c='default', f='index', args=['arg1'])), "/arg1") + self.assertEqual(str( + URL(a='app', c='default', f='user', args=['arg1'])), "/user/arg1") + self.assertEqual(str(URL( + a='app', c='default', f='user', args=['index'])), "/user/index") + self.assertEqual(str(URL( + a='app', c='default', f='index', args=['index'])), "/index/index") + self.assertEqual(str(URL( + a='app', c='default', f='index', args=['init'])), "/index/init") + self.assertEqual(str( + URL(a='app', c='default', f='index', args=['ctr'])), "/index/ctr") + self.assertEqual(str( + URL(a='app', c='ctr', f='index', args=['arg'])), "/ctr/index/arg") + self.assertEqual( + str(URL(a='app', c='ctr', f='ctrf1', args=['arg'])), "/ctr/arg") + self.assertEqual(str(URL( + a='app', c='ctr', f='ctrf1', args=['ctrf2'])), "/ctr/ctrf1/ctrf2") + + self.assertEqual(str(URL( + a='app2', c='default', f='index', args=['arg1'])), "/app2/arg1") + self.assertEqual(str(URL(a='app2', c='default', f='user', + args=['arg1'])), "/app2/user/arg1") + self.assertEqual(str(URL(a='app2', c='default', f='user', + args=['index'])), "/app2/user/index") + self.assertEqual(str(URL(a='app2', c='default', f='index', + args=['index'])), "/app2/index/index") + self.assertEqual(str(URL(a='app2', c='default', f='index', + args=['init'])), "/app2/index/init") + self.assertEqual(str(URL(a='app2', c='default', f='index', + args=['ctr'])), "/app2/index/ctr") + + # outbound - with extensions + self.assertEqual( + str(URL(a='app', c='default', f='index.json')), "/index.json") + self.assertEqual( + str(URL(a='app', c='default', f='index.json', args=['arg1'])), "/index.json/arg1") + self.assertEqual(str( + URL(a='app', c='default', f='user.json')), "/user.json") + self.assertEqual(str( + URL(a='app', c='default', f='user.json', args=['arg1'])), "/user.json/arg1") + self.assertEqual(str(URL( + a='app', c='default', f='user.json', args=['index'])), "/user.json/index") + self.assertEqual(str( + URL(a='app', c='default', f='index.json', args=['ctr'])), "/index.json/ctr") + self.assertEqual( + str(URL(a='app', c='ctr', f='ctrf1.json', args=['arg'])), "/ctr/ctrf1.json/arg") + + self.assertEqual(str(URL( + a='app2', c='default', f='index.json', args=['arg1'])), "/app2/index.json/arg1") + self.assertEqual(str(URL( + a='app2', c='ctr', f='index.json', args=['arg1'])), "/app2/ctr/index.json/arg1") + + # inbound + self.assertEqual( + filter_url('http://d.com/arg'), "/app/default/index ['arg']") + self.assertEqual(filter_url('http://d.com/user'), "/app/default/user") + self.assertEqual( + filter_url('http://d.com/user/arg'), "/app/default/user ['arg']") + self.assertEqual(filter_url('http://d.com/ctr'), "/app/ctr/ctrf1") + self.assertEqual( + filter_url('http://d.com/ctr/arg'), "/app/ctr/ctrf1 ['arg']") + + self.assertEqual(filter_url( + 'http://d.com/app2/arg'), "/app2/default/index ['arg']") + self.assertEqual( + filter_url('http://d.com/app2/user'), "/app2/default/user") + self.assertEqual(filter_url( + 'http://d.com/app2/user/arg'), "/app2/default/user ['arg']") + self.assertEqual( + filter_url('http://d.com/app2/ctr'), "/app2/ctr/index") + self.assertEqual(filter_url( + 'http://d.com/app2/ctr/index/arg'), "/app2/ctr/index ['arg']") + self.assertEqual( + filter_url('http://d.com/app2/ctr/arg'), "/app2/ctr/arg") + + # inbound - with extensions + self.assertEqual( + filter_url('http://d.com/index.json'), "/app/default/index.json") + self.assertEqual(filter_url('http://d.com/user.json'), "/app/default/user.json") + self.assertEqual( + filter_url('http://d.com/user.json/arg'), "/app/default/user.json ['arg']") + self.assertEqual( + filter_url('http://d.com/user.json/index'), "/app/default/user.json ['index']") + self.assertEqual( + filter_url('http://d.com/index.json/ctr'), "/app/default/index.json ['ctr']") + self.assertEqual( + filter_url('http://d.com/ctr/ctrf1.json/arg'), "/app/ctr/ctrf1.json ['arg']") + + self.assertEqual(filter_url( + 'http://d.com/app2/index.json/arg'), "/app2/default/index.json ['arg']") + self.assertEqual( + filter_url('http://d.com/app2/user.json'), "/app2/default/user.json") + self.assertEqual(filter_url( + 'http://d.com/app2/user.json/arg'), "/app2/default/user.json ['arg']") + self.assertEqual(filter_url( + 'http://d.com/app2/ctr/index.json/arg'), "/app2/ctr/index.json ['arg']") + self.assertEqual( + filter_url('http://d.com/app2/ctr/arg'), "/app2/ctr/arg") + + def test_router_functions2(self): + ''' + Test more functions=[something] + ''' + router_functions = dict( + BASE=dict( + default_application='init', + applications='INIT', + ), + init=dict( + #default_controller = 'default', + controllers=['default', 'ctr'], + #default_function = 'index', + functions=['index', 'user', 'register', 'basicRegister', + 'download', 'call', 'data', 'error'] + ), + ) + + load(rdict=router_functions) + + # outbound + self.assertEqual(str( + URL(a='init', c='default', f='index', args=['arg1'])), "/arg1") + self.assertEqual(str(URL( + a='init', c='default', f='user', args=['arg1'])), "/user/arg1") + self.assertEqual(str(URL( + a='init', c='default', f='user', args=['index'])), "/user/index") + self.assertEqual(str(URL(a='init', c='default', f='index', + args=['index'])), "/index/index") + self.assertEqual(str( + URL(a='init', c='default', f='index', args=['init'])), "/init") + self.assertEqual(str(URL( + a='init', c='default', f='index', args=['ctr'])), "/index/ctr") + self.assertEqual(str(URL( + a='init', c='ctr', f='index', args=['arg'])), "/ctr/index/arg") + self.assertEqual(str(URL( + a='init', c='ctr', f='ctrf1', args=['arg'])), "/ctr/ctrf1/arg") + self.assertEqual(str(URL(a='init', c='ctr', f='ctrf1', + args=['ctrf2'])), "/ctr/ctrf1/ctrf2") + self.assertEqual( + str(URL(a='init', c='default', f='register')), "/register") + + # inbound + self.assertEqual( + filter_url('http://d.com/arg'), "/init/default/index ['arg']") + self.assertEqual(filter_url('http://d.com/user'), "/init/default/user") + self.assertEqual( + filter_url('http://d.com/user/arg'), "/init/default/user ['arg']") + self.assertEqual(filter_url('http://d.com/ctr'), "/init/ctr/index") + self.assertEqual(filter_url( + 'http://d.com/ctr/ctrf1/arg'), "/init/ctr/ctrf1 ['arg']") + + def test_router_hyphen(self): + ''' + Test hyphen conversion + ''' + router_hyphen = dict( + BASE=dict( + applications=['init', 'app1', 'app2'], + ), + init=dict( + controllers=['default'], + ), + app1=dict( + controllers=['default'], + map_hyphen=True, + ), + app2=dict( + controllers=['default'], + map_hyphen=False, + ), + ) + load(rdict=router_hyphen) + self.assertEqual(filter_url( + 'http://domain.com/init/default/fcn_1', out=True), "/fcn_1") + self.assertEqual( + filter_url('http://domain.com/static/filename-with_underscore'), + norm_root("%s/applications/init/static/filename-with_underscore" % root)) + self.assertEqual( + filter_url('http://domain.com/init/static/filename-with_underscore', out=True), + "/init/static/filename-with_underscore") + + self.assertEqual(filter_url('http://domain.com/app2/fcn_1'), + "/app2/default/fcn_1") + self.assertEqual( + filter_url('http://domain.com/app2/ctr/fcn_1', + domain=('app2', None), out=True), + "/ctr/fcn_1") + self.assertEqual( + filter_url('http://domain.com/app2/static/filename-with_underscore', domain=('app2', None), out=True), + "/app2/static/filename-with_underscore") + self.assertEqual( + filter_url( + 'http://domain.com/app2/static/filename-with_underscore'), + norm_root("%s/applications/app2/static/filename-with_underscore" % root)) + + from gluon.globals import current + current.response.static_version = None + + self.assertEqual(str(URL(a='init', c='default', f='a_b')), "/a_b") + self.assertEqual(str(URL(a='app1', c='default', f='a_b')), "/app1/a-b") + self.assertEqual(str(URL(a='app2', c='default', f='a_b')), "/app2/a_b") + self.assertEqual( + str(URL(a='app1', c='static', f='a/b_c')), "/app1/static/a/b_c") + self.assertEqual( + str(URL(a='app1', c='static/a', f='b_c')), "/app1/static/a/b_c") + self.assertEqual( + str(URL(a='app2', c='static', f='a/b_c')), "/app2/static/a/b_c") + self.assertEqual( + str(URL(a='app2', c='static/a', f='b_c')), "/app2/static/a/b_c") + + def test_router_lang(self): + ''' + Test language specifications + ''' + router_lang = dict( + BASE=dict(default_application='admin'), + welcome=dict(), + admin=dict( + controllers=['default', 'ctr'], + languages=['en', 'it', 'it-it'], default_language='en', + ), + examples=dict( + languages=['en', 'it', 'it-it'], default_language='en', + ), + ) + load(rdict=router_lang) + self.assertEqual(filter_url('http://domain.com/index/abc'), + "/admin/default/index ['abc'] (en)") + self.assertEqual(filter_url('http://domain.com/en/abc/def'), + "/admin/default/abc ['def'] (en)") + self.assertEqual(filter_url('http://domain.com/it/abc/def'), + "/admin/default/abc ['def'] (it)") + self.assertEqual(filter_url('http://domain.com/it-it/abc/def'), + "/admin/default/abc ['def'] (it-it)") + self.assertEqual(filter_url('http://domain.com/index/a%20bc'), + "/admin/default/index ['a bc'] (en)") + self.assertEqual(filter_url('http://domain.com/static/file'), + norm_root("%s/applications/admin/static/file" % root)) + self.assertEqual(filter_url('http://domain.com/en/static/file'), + norm_root("%s/applications/admin/static/file" % root)) + self.assertEqual(filter_url('http://domain.com/examples/en/static/file'), + norm_root("%s/applications/examples/static/en/file" % root)) + self.assertEqual(filter_url('http://domain.com/examples/static/file'), + norm_root("%s/applications/examples/static/en/file" % root)) + self.assertEqual(filter_url('http://domain.com/examples/it/static/file'), + norm_root("%s/applications/examples/static/it/file" % root)) + self.assertEqual(filter_url('http://domain.com/examples/it-it/static/file'), + norm_root("%s/applications/examples/static/file" % root)) + + self.assertEqual(filter_url('https://domain.com/admin/ctr/fcn', + lang='en', out=True), "/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/admin/ctr/fcn', + lang='it', out=True), "/it/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/admin/ctr/fcn', + lang='it-it', out=True), "/it-it/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/admin/static/file', + lang='en', out=True), "/admin/en/static/file") + self.assertEqual(filter_url('https://domain.com/admin/static/file', + lang='it', out=True), "/admin/it/static/file") + self.assertEqual(filter_url('https://domain.com/admin/static/file', + lang='it-it', out=True), "/admin/it-it/static/file") + self.assertEqual(filter_url('https://domain.com/welcome/ctr/fcn', + lang='it', out=True), "/welcome/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/welcome/ctr/fcn', + lang='es', out=True), "/welcome/ctr/fcn") + + self.assertEqual(filter_url('https://domain.com/admin/ctr/fcn', + language='en', out=True), "/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/admin/ctr/fcn', + language='it', out=True), "/it/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/admin/ctr/fcn', + language='it-it', out=True), "/it-it/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/admin/static/file', + language='en', out=True), "/admin/en/static/file") + self.assertEqual(filter_url('https://domain.com/admin/static/file', + language='it', out=True), "/admin/it/static/file") + self.assertEqual(filter_url('https://domain.com/admin/static/file', + language='it-it', out=True), "/admin/it-it/static/file") + self.assertEqual(filter_url('https://domain.com/welcome/ctr/fcn', + language='it', out=True), "/welcome/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/welcome/ctr/fcn', + language='es', out=True), "/welcome/ctr/fcn") + + self.assertEqual(filter_url('https://domain.com/admin/ctr/fcn', + lang='it', language='en', out=True), "/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/admin/ctr/fcn', + lang='en', language='it', out=True), "/it/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/admin/ctr/fcn', + lang='it', language='it-it', out=True), "/it-it/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/admin/static/file', + lang='it', language='en', out=True), "/admin/en/static/file") + self.assertEqual(filter_url('https://domain.com/admin/static/file', + lang='it', language='it', out=True), "/admin/it/static/file") + self.assertEqual(filter_url('https://domain.com/admin/static/file', + lang='it', language='it-it', out=True), "/admin/it-it/static/file") + self.assertEqual(filter_url('https://domain.com/welcome/ctr/fcn', + lang='it', language='it', out=True), "/welcome/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/welcome/ctr/fcn', + lang='it', language='es', out=True), "/welcome/ctr/fcn") + + router_lang['admin']['map_static'] = True + load(rdict=router_lang) + self.assertEqual(filter_url('https://domain.com/admin/ctr/fcn', + lang='en', out=True), "/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/admin/ctr/fcn', + lang='it', out=True), "/it/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/admin/ctr/fcn', + lang='it-it', out=True), "/it-it/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/admin/static/file', + lang='en', out=True), "/static/file") + self.assertEqual(filter_url('https://domain.com/admin/static/file', + lang='it', out=True), "/it/static/file") + self.assertEqual(filter_url('https://domain.com/admin/static/file', + lang='it-it', out=True), "/it-it/static/file") + self.assertEqual(filter_url('https://domain.com/welcome/ctr/fcn', + lang='it', out=True), "/welcome/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/welcome/ctr/fcn', + lang='es', out=True), "/welcome/ctr/fcn") + + router_lang['admin']['map_static'] = False + router_lang['examples']['map_static'] = False + load(rdict=router_lang) + self.assertEqual(filter_url('https://domain.com/admin/ctr/fcn', + lang='en', out=True), "/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/admin/ctr/fcn', + lang='it', out=True), "/it/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/admin/ctr/fcn', + lang='it-it', out=True), "/it-it/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/admin/static/file', + lang='en', out=True), "/admin/static/en/file") + self.assertEqual(filter_url('https://domain.com/admin/static/file', + lang='it', out=True), "/admin/static/it/file") + self.assertEqual(filter_url('https://domain.com/admin/static/file', + lang='it-it', out=True), "/admin/static/it-it/file") + self.assertEqual(filter_url('https://domain.com/welcome/ctr/fcn', + lang='it', out=True), "/welcome/ctr/fcn") + self.assertEqual(filter_url('https://domain.com/welcome/ctr/fcn', + lang='es', out=True), "/welcome/ctr/fcn") + self.assertEqual(filter_url('http://domain.com/static/file'), + norm_root("%s/applications/admin/static/file" % root)) + self.assertEqual(filter_url('http://domain.com/en/static/file'), + norm_root("%s/applications/admin/static/file" % root)) + self.assertEqual(filter_url('http://domain.com/examples/en/static/file'), + norm_root("%s/applications/examples/static/en/file" % root)) + self.assertEqual(filter_url('http://domain.com/examples/static/file'), + norm_root("%s/applications/examples/static/en/file" % root)) + self.assertEqual(filter_url('http://domain.com/examples/it/static/file'), + norm_root("%s/applications/examples/static/it/file" % root)) + self.assertEqual(filter_url('http://domain.com/examples/it-it/static/file'), + norm_root("%s/applications/examples/static/file" % root)) + self.assertEqual(filter_url('http://domain.com/examples/static/en/file').replace('/', os.sep), + norm_root("%s/applications/examples/static/en/file" % root)) + self.assertEqual(filter_url('http://domain.com/examples/static/it/file').replace('/', os.sep), + norm_root("%s/applications/examples/static/it/file" % root)) + self.assertEqual(filter_url('http://domain.com/examples/static/it-it/file').replace('/', os.sep), + norm_root("%s/applications/examples/static/it-it/file" % root)) + + def test_router_get_effective(self): + ''' + Test get_effective_router + ''' + router_get_effective = dict( + BASE=dict( + default_application='a1', + applications=['a1', 'a2'], + ), + a1=dict( + controllers=['c1a', 'c1b', 'default'], + ), + a2=dict( + default_controller='c2', + controllers=[], + ), + a3=dict( + default_controller='c2', + controllers=['c1'], + ), + a4=dict( + default_function='f1', + functions=['f2'], + ), + ) + load(rdict=router_get_effective) + self.assertEqual( + get_effective_router('BASE').applications, set(['a1', 'a2'])) + self.assertEqual( + get_effective_router('BASE').default_application, 'a1') + self.assertEqual(get_effective_router('BASE').domains, {}) + self.assertEqual(get_effective_router('a1').applications, None) + self.assertEqual(get_effective_router('a1').default_application, None) + self.assertEqual(get_effective_router('a1').domains, None) + self.assertEqual( + get_effective_router('a1').default_controller, "default") + self.assertEqual(get_effective_router('a2').default_application, None) + self.assertEqual(get_effective_router('a2').default_controller, "c2") + self.assertEqual(get_effective_router( + 'a1').controllers, set(['c1a', 'c1b', 'default', 'static'])) + self.assertEqual(get_effective_router('a2').controllers, set()) + self.assertEqual(get_effective_router( + 'a3').controllers, set(['c1', 'c2', 'static'])) + self.assertEqual(get_effective_router( + 'a4').functions, dict(default=set(['f1', 'f2']))) + self.assertEqual(get_effective_router('xx'), None) + + def test_router_error(self): + ''' + Test rewrite of HTTP errors + ''' + router_err = dict() + load(rdict=router_err) + self.assertEqual(filter_err(200), 200) + self.assertEqual(filter_err(399), 399) + self.assertEqual(filter_err(400), 400) + + def test_router_static_path(self): + ''' + Test validation of static paths + Stock pattern: file_match = r'([-+=@$%\w]+[./]?)+$' + + ''' + load(rdict=dict()) + self.assertEqual(filter_url('http://domain.com/welcome/static/path/to/static').replace('/', os.sep), + norm_root("%s/applications/welcome/static/path/to/static" % root)) + self.assertRaises(HTTP, filter_url, 'http://domain.com/welcome/static/bad/path/to/st~tic') + self.assertEqual(filter_url('http://domain.com/welcome/static/path/to--/static').replace('/', os.sep), + norm_root("%s/applications/welcome/static/path/to--/static" % root)) + self.assertEqual(filter_url('http://domain.com/welcome/static/path/==to--/static').replace('/', os.sep), + norm_root("%s/applications/welcome/static/path/==to--/static" % root)) + self.assertEqual(filter_url('http://domain.com/welcome/static/path/-+=@$%/static').replace('/', os.sep), + norm_root("%s/applications/welcome/static/path/-+=@$%%/static" % root)) + self.assertRaises(HTTP, filter_url, 'http://domain.com/welcome/static/bad/path/to/.static') + self.assertRaises(HTTP, filter_url, 'http://domain.com/welcome/static/bad/path/to/s..tatic') + self.assertRaises(HTTP, filter_url, 'http://domain.com/welcome/static/bad/path/to//static') + self.assertRaises(HTTP, filter_url, 'http://domain.com/welcome/static/bad/path/to/#static') + + router_static = dict( + BASE=dict( + file_match=r'([-+=@$%#\w]+[./]?)+$', # legal static path + ), + ) + load(rdict=router_static) + self.assertEqual(filter_url('http://domain.com/welcome/static/path/to/#static').replace('/', os.sep), + norm_root("%s/applications/welcome/static/path/to/#static" % root)) + + router_static = dict( + BASE=dict( + file_match=r'[-+=@$%#.\w]+$', # legal static path element + ), + ) + load(rdict=router_static) + self.assertEqual(filter_url('http://domain.com/welcome/static/path/to/static').replace('/', os.sep), + norm_root("%s/applications/welcome/static/path/to/static" % root)) + self.assertRaises(HTTP, filter_url, 'http://domain.com/welcome/static/bad/path/to/st~tic') + self.assertEqual(filter_url('http://domain.com/welcome/static/path/to--/static').replace('/', os.sep), + norm_root("%s/applications/welcome/static/path/to--/static" % root)) + self.assertEqual(filter_url('http://domain.com/welcome/static/path/==to--/static').replace('/', os.sep), + norm_root("%s/applications/welcome/static/path/==to--/static" % root)) + self.assertEqual(filter_url('http://domain.com/welcome/static/path/-+=@$%/static').replace('/', os.sep), + norm_root("%s/applications/welcome/static/path/-+=@$%%/static" % root)) + self.assertRaises(HTTP, filter_url, 'http://domain.com/welcome/static/bad/path/to//static') + self.assertEqual(filter_url('http://domain.com/welcome/static/path/to/#static').replace('/', os.sep), + norm_root("%s/applications/welcome/static/path/to/#static" % root)) + self.assertRaises(HTTP, filter_url, 'http://domain.com/welcome/static/bad/path/./static') + self.assertRaises(HTTP, filter_url, 'http://domain.com/welcome/static/bad/path/../static') + self.assertEqual(filter_url('http://domain.com/welcome/static/path/.../static').replace('/', os.sep), + norm_root("%s/applications/welcome/static/path/.../static" % root)) + self.assertEqual(filter_url('http://domain.com/welcome/static/path/to/.static').replace('/', os.sep), + norm_root("%s/applications/welcome/static/path/to/.static" % root)) + + def test_router_args(self): + ''' + Test URL args parsing/generation + ''' + load(rdict=dict()) + self.assertEqual(filter_url('http://domain.com/init/default/f/arg1'), + "/init/default/f ['arg1']") + self.assertEqual(filter_url('http://domain.com/init/default/f/arg1/'), + "/init/default/f ['arg1']") + self.assertEqual(filter_url('http://domain.com/init/default/f/arg1//'), + "/init/default/f ['arg1', '']") + self.assertEqual(filter_url('http://domain.com/init/default/f//arg1'), + "/init/default/f ['', 'arg1']") + self.assertEqual( + filter_url('http://domain.com/init/default/f/arg1/arg2'), + "/init/default/f ['arg1', 'arg2']") + self.assertEqual( + filter_url('http://domain.com/init/default/f/arg1//arg2'), + "/init/default/f ['arg1', '', 'arg2']") + self.assertEqual( + filter_url('http://domain.com/init/default/f/arg1//arg3/'), + "/init/default/f ['arg1', '', 'arg3']") + self.assertEqual( + filter_url('http://domain.com/init/default/f/arg1//arg3//'), + "/init/default/f ['arg1', '', 'arg3', '']") + + self.assertEqual( + filter_url('http://domain.com/init/default/f', out=True), "/f") + self.assertEqual(map_url_out(None, None, 'init', 'default', + 'f', None, None, None, None, None), "/f") + self.assertEqual(map_url_out(None, None, 'init', 'default', + 'f', [], None, None, None, None), "/f") + self.assertEqual(map_url_out(None, None, 'init', 'default', + 'f', ['arg1'], None, None, None, None), "/f") + self.assertEqual(map_url_out(None, None, 'init', 'default', + 'f', ['arg1', ''], None, None, None, None), "/f") + self.assertEqual( + str(URL(a='init', c='default', f='f', args=None)), "/f") + self.assertEqual( + str(URL(a='init', c='default', f='f', args=['arg1'])), "/f/arg1") + self.assertEqual(str(URL( + a='init', c='default', f='f', args=['arg1', ''])), "/f/arg1//") + self.assertEqual(str(URL(a='init', c='default', f='f', + args=['arg1', '', 'arg3'])), "/f/arg1//arg3") + self.assertEqual(str( + URL(a='init', c='default', f='f', args=['ar g'])), "/f/ar%20g") + self.assertEqual(str( + URL(a='init', c='default', f='f', args=['årg'])), "/f/%C3%A5rg") + self.assertEqual(URL(a='init', c='default', f='fünc'), "/fünc") + self.assertEqual( + to_bytes(URL(a='init', c='default', f='fünc')), b"/f\xc3\xbcnc") + + def test_routes_anchor(self): + ''' + Test URL with anchor + ''' + self.assertEqual( + str(URL(a='a', c='c', f='f', anchor='anchor')), "/a/c/f#anchor") + load(rdict=dict()) + self.assertEqual( + str(URL(a='a', c='c', f='f', anchor='anchor')), "/a/c/f#anchor") + args = ['a1', 'a2'] + self.assertEqual( + str(URL(a='a', c='c', f='f', args=args, anchor='anchor')), + "/a/c/f/a1/a2#anchor") + vars = dict(v1=1, v2=2) + self.assertEqual( + str(URL(a='a', c='c', f='f', vars=vars, anchor='anchor')), + "/a/c/f?v1=1&v2=2#anchor") + self.assertEqual( + str(URL( + a='a', c='c', f='f', args=args, vars=vars, anchor='anchor')), + "/a/c/f/a1/a2?v1=1&v2=2#anchor") + self.assertEqual(str(URL(a='init', c='default', f='index')), + "/") + self.assertEqual(str(URL(a='init', c='default', f='f')), + "/f") + self.assertEqual( + str(URL(a='init', c='default', f='index', anchor='anchor')), + "/#anchor") + self.assertEqual( + str(URL(a='init', c='default', f='f', anchor='anchor')), + "/f#anchor") + + def test_router_prefix(self): + ''' + Test path_prefix + ''' + router_path_prefix = dict( + BASE=dict( + default_application='a1', + applications=['a1', 'a2'], + path_prefix='/path/to/apps', + ), + a1=dict( + controllers=['c1a', 'c1b', 'default'], + ), + a2=dict( + default_controller='c2', + controllers=[], + ), + ) + load(rdict=router_path_prefix) + self.assertEqual(str(URL(a='a1', c='c1a', f='f')), + "/path/to/apps/c1a/f") + self.assertEqual(str(URL(a='a2', c='c', f='f')), + "/path/to/apps/a2/c/f") + self.assertEqual(str(URL(a='a2', c='c2', f='f')), + "/path/to/apps/a2/c2/f") + self.assertEqual( + filter_url('http://domain.com/a1/'), "/a1/default/index") + self.assertEqual(filter_url( + 'http://domain.com/path/to/apps/a1/'), "/a1/default/index") + self.assertEqual(filter_url( + 'http://domain.com/path/to/a1/'), "/a1/default/path ['to', 'a1']") + + def test_router_absolute(self): + ''' + Test absolute URL + ''' + load(rdict=dict()) + r = Storage() + r.env = Storage() + r.env.http_host = 'domain.com' + r.env.wsgi_url_scheme = 'httpx' # distinguish incoming scheme + self.assertEqual(str(URL(r=r, a='a', c='c', f='f')), "/a/c/f") + self.assertEqual(str(URL(r=r, a='a', c='c', f='f', host=True)), + "httpx://domain.com/a/c/f") + self.assertEqual(str(URL(r=r, a='a', c='c', f='f', host='host.com')), + "httpx://host.com/a/c/f") + self.assertEqual(str(URL(r=r, a='a', c='c', f='f', scheme=True)), + "httpx://domain.com/a/c/f") + self.assertEqual(str(URL(r=r, a='a', c='c', f='f', scheme=False)), + "/a/c/f") + self.assertEqual(str(URL(r=r, a='a', c='c', f='f', scheme='https')), + "https://domain.com/a/c/f") + self.assertEqual(str(URL(r=r, a='a', c='c', f='f', scheme='wss')), + "wss://domain.com/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', scheme=True, host=True)), + "httpx://domain.com/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', scheme='https', host=True)), + "https://domain.com/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', scheme=False, host=True)), + "httpx://domain.com/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', scheme=True, host='host.com')), + "httpx://host.com/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', scheme=False, host='host.com')), + "httpx://host.com/a/c/f") + self.assertEqual(str(URL(r=r, a='a', c='c', f='f', port=1234)), + "httpx://domain.com:1234/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', scheme=True, port=1234)), + "httpx://domain.com:1234/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', host='host.com', port=1234)), + "httpx://host.com:1234/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', scheme='wss', + host='host.com', port=1234)), + "wss://host.com:1234/a/c/f") + + def test_request_uri(self): + ''' + Test REQUEST_URI in env + ''' + load(rdict=dict()) + + self.assertEqual( + filter_url('http://domain.com/abc', env=True).request_uri, + '/init/default/abc') + self.assertEqual( + filter_url('http://domain.com/abc?def', env=True).request_uri, + '/init/default/abc?def') + self.assertEqual( + filter_url('http://domain.com/index/abc', env=True).request_uri, + "/init/default/index/abc") + self.assertEqual( + filter_url('http://domain.com/abc/def', env=True).request_uri, + "/init/default/abc/def") + self.assertEqual( + filter_url('http://domain.com/index/a%20bc', env=True).request_uri, + "/init/default/index/a%20bc") + + def test_request_collide(self): + ''' + Test controller-app name collision: admin vs welcome/admin + ''' + router_collide = dict( + BASE=dict( + domains={ + 'ex.domain.com': 'examples', + 'ad.domain.com': 'admin', + 'welcome.com': 'welcome', + 'www.welcome.com': 'welcome', + }, + exclusive_domain=True, + ), + ) + load(rdict=router_collide) + + # basic inbound + self.assertEqual( + filter_url('http://ex.domain.com'), '/examples/default/exdef') + self.assertEqual( + filter_url('http://ad.domain.com'), '/admin/default/index') + self.assertEqual( + filter_url('http://welcome.com'), '/welcome/default/index') + self.assertEqual( + filter_url('http://www.welcome.com'), '/welcome/default/index') + # basic outbound + self.assertEqual(filter_url('http://ex.domain.com/examples/default/exdef', domain='examples', out=True), "/") + self.assertEqual(filter_url('http://ad.domain.com/admin/default/index', + domain='admin', out=True), "/") + self.assertEqual(filter_url('http://welcome.com/welcome/default/index', + domain='welcome', out=True), "/") + self.assertEqual(filter_url('http://www.welcome.com/welcome/default/index', domain='welcome', out=True), "/") + + # inbound + self.assertEqual( + filter_url('http://welcome.com/admin'), '/welcome/admin/index') + self.assertEqual( + filter_url('http://welcome.com/f1'), '/welcome/default/f1') + self.assertEqual( + filter_url('http://ad.domain.com/shell'), '/admin/shell/index') + self.assertEqual( + filter_url('http://ad.domain.com/f1'), '/admin/default/f1') + # outbound + self.assertEqual(filter_url('http://welcome.com/welcome/other/index', + domain='welcome', out=True), "/other") + self.assertEqual(filter_url('http://welcome.com/welcome/admin/index', + domain='welcome', out=True), "/admin") + self.assertEqual(filter_url('http://ad.domain.com/admin/shell/index', + domain='admin', out=True), "/shell") + self.assertEqual(filter_url('http://ad.domain.com/admin/default/f1', + domain='admin', out=True), "/f1") + router_collide['BASE']['exclusive_domain'] = False + load(rdict=router_collide) + self.assertEqual(filter_url('http://welcome.com/welcome/admin/index', + domain='welcome', out=True), "/welcome/admin") + diff --git a/web2py/gluon/tests/test_routes.py b/web2py/gluon/tests/test_routes.py new file mode 100644 index 0000000..0fc5f2b --- /dev/null +++ b/web2py/gluon/tests/test_routes.py @@ -0,0 +1,452 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""Unit tests for rewrite.py regex routing option""" + +import sys +import os +import unittest +import tempfile +import logging + +from gluon.rewrite import load, filter_url, filter_err, get_effective_router, regex_filter_out, regex_select +from gluon.html import URL +from gluon.fileutils import abspath +from gluon.settings import global_settings +from gluon.http import HTTP +from gluon.storage import Storage +from gluon._compat import to_bytes + +logger = None +oldcwd = None +root = None + + +def norm_root(root): + return root.replace('/', os.sep) + + +def setUpModule(): + def make_apptree(): + "build a temporary applications tree" + # applications/ + os.mkdir(abspath('applications')) + # applications/app/ + for app in ('admin', 'examples', 'welcome'): + os.mkdir(abspath('applications', app)) + # applications/app/(controllers, static) + for subdir in ('controllers', 'static'): + os.mkdir(abspath('applications', app, subdir)) + # applications/admin/controllers/*.py + for ctr in ('appadmin', 'default', 'gae', 'mercurial', 'shell', 'wizard'): + open(abspath('applications', 'admin', + 'controllers', '%s.py' % ctr), 'w').close() + # applications/examples/controllers/*.py + for ctr in ('ajax_examples', 'appadmin', 'default', 'global', 'spreadsheet'): + open(abspath('applications', 'examples', + 'controllers', '%s.py' % ctr), 'w').close() + # applications/welcome/controllers/*.py + for ctr in ('appadmin', 'default'): + open(abspath('applications', 'welcome', + 'controllers', '%s.py' % ctr), 'w').close() + # create an app-specific routes.py for examples app + routes = open(abspath('applications', 'examples', 'routes.py'), 'w') + routes.write("default_function='exdef'\n") + routes.close() + + global oldcwd + if oldcwd is None: # do this only once + oldcwd = os.getcwd() + if not os.path.isdir('gluon'): + os.chdir(os.path.realpath( + '../../')) # run from web2py base directory + from gluon import main # for initialization after chdir + global logger + logger = logging.getLogger('web2py.rewrite') + global_settings.applications_parent = tempfile.mkdtemp() + global root + root = global_settings.applications_parent + make_apptree() + + +def tearDownModule(): + global oldcwd + if oldcwd is not None: + os.chdir(oldcwd) + oldcwd = None + + +class TestRoutes(unittest.TestCase): + """ Tests the regex routing logic from gluon.rewrite """ + + def test_routes_null(self): + """ Tests a null routes table """ + load(data='') + # incoming + self.assertEqual( + filter_url('http://domain.com'), '/init/default/index') + self.assertEqual( + filter_url('http://domain.com/'), '/init/default/index') + self.assertEqual( + filter_url('http://domain.com/abc'), '/abc/default/index') + self.assertEqual( + filter_url('http://domain.com/abc/'), '/abc/default/index') + self.assertEqual( + filter_url('http://domain.com/abc/def'), "/abc/def/index") + self.assertEqual( + filter_url('http://domain.com/abc/def/'), "/abc/def/index") + self.assertEqual( + filter_url('http://domain.com/abc/def/ghi'), "/abc/def/ghi") + self.assertEqual( + filter_url('http://domain.com/abc/def/ghi/'), "/abc/def/ghi") + self.assertEqual(filter_url( + 'http://domain.com/abc/def/ghi/jkl'), "/abc/def/ghi ['jkl']") + self.assertEqual(filter_url( + 'http://domain.com/abc/def/ghi/j%20kl'), "/abc/def/ghi ['j_kl']") + self.assertEqual(filter_url('http://domain.com/welcome/static/path/to/static'), + norm_root("%s/applications/welcome/static/path/to/static" % root)) + # no more necessary since explcit check for directory traversal attacks + """ + self.assertRaises(HTTP, filter_url, 'http://domain.com/welcome/static/bad/path/to/st~tic') + try: + # 2.7+ only + self.assertRaisesRegexp(HTTP, "400.*BAD REQUEST \[invalid path\]", filter_url, 'http://domain.com/welcome/static/bad/path/to/st~tic') + except AttributeError: + pass + """ + # outgoing + self.assertEqual(filter_url('http://domain.com/init/default/index', + out=True), '/init/default/index') + self.assertEqual(filter_url('http://domain.com/init/default/index/arg1', out=True), '/init/default/index/arg1') + self.assertEqual(filter_url('http://domain.com/init/default/abc', + out=True), '/init/default/abc') + + def test_routes_query(self): + """ Test query appending """ + data = r''' +routes_in = ( + ('/service/$model/create', '/app/default/call/json/create?model=$model'), +) +''' + load(data=data) + self.assertEqual(filter_url('http://localhost:8000/service/person/create'), "/app/default/call ['json', 'create'] ?model=person") + self.assertEqual(filter_url('http://localhost:8000/service/person/create?var1=val1'), "/app/default/call ['json', 'create'] ?model=person&var1=val1") + + def test_routes_specific(self): + """ + Test app-specific routes.py + + Note that make_apptree above created applications/examples/routes.py with a default_function. + """ + data = r''' +routes_app = [ + (r'/(?Pwelcome|admin|examples)\b.*', r'\g'), + (r'$anything', r'welcome'), + (r'/?$anything', r'welcome'), +] +''' + load(data=data) + self.assertEqual( + filter_url('http://domain.com/welcome'), '/welcome/default/index') + self.assertEqual(filter_url( + 'http://domain.com/examples'), '/examples/default/exdef') + + def test_routes_defapp(self): + """ Test the default-application function """ + data = r''' +default_application = 'defapp' +''' + load(data=data) + # incoming + self.assertEqual( + filter_url('http://domain.com'), '/defapp/default/index') + self.assertEqual( + filter_url('http://domain.com/'), '/defapp/default/index') + self.assertEqual( + filter_url('http://domain.com/welcome'), '/welcome/default/index') + self.assertEqual( + filter_url('http://domain.com/app'), '/app/default/index') + self.assertEqual(filter_url('http://domain.com/welcome/default/index/abc'), "/welcome/default/index ['abc']") + self.assertEqual(filter_url('http://domain.com/welcome/static/abc'), + norm_root('%s/applications/welcome/static/abc' % root)) + self.assertEqual(filter_url('http://domain.com/defapp/static/path/to/static'), + norm_root("%s/applications/defapp/static/path/to/static" % root)) + + def test_routes_raise(self): + ''' + Test URLs that raise exceptions + ''' + # test non-exception variants + load(data='') + self.assertEqual( + filter_url('http://domain.com/init'), "/init/default/index") + self.assertEqual(filter_url( + 'http://domain.com/init/default'), "/init/default/index") + self.assertEqual(filter_url('http://domain.com/init/default/fcn.ext'), + "/init/default/fcn.ext") + self.assertEqual(filter_url('http://domain.com/init/default/fcn/arg'), + "/init/default/fcn ['arg']") + # now raise-HTTP variants + self.assertRaises(HTTP, filter_url, 'http://domain.com/bad!ctl') + self.assertRaises(HTTP, filter_url, 'http://domain.com/ctl/bad!fcn') + self.assertRaises( + HTTP, filter_url, 'http://domain.com/ctl/fcn.bad!ext') + #self.assertRaises( + # HTTP, filter_url, 'http://domain.com/ctl/fcn/bad!arg') + #try: + # # 2.7+ only + # self.assertRaisesRegexp(HTTP, '400 BAD REQUEST \[invalid path\]', filter_url, 'http://domain.com/init/bad!ctl') + # self.assertRaisesRegexp(HTTP, '400 BAD REQUEST \[invalid path\]', filter_url, 'http://domain.com/init/ctlr/bad!fcn') + # self.assertRaisesRegexp(HTTP, '400 BAD REQUEST \[invalid path\]', filter_url, 'http://domain.com/init/ctlr/fcn.bad!ext') + # self.assertRaisesRegexp(HTTP, '400 BAD REQUEST \[invalid path\]', filter_url, 'http://domain.com/appc/init/fcn/bad!arg') + #except AttributeError: + # pass + + self.assertEqual(filter_url('http://domain.com/welcome/default/fcn_1'), + "/welcome/default/fcn_1") + #self.assertRaises(HTTP, filter_url, 'http://domain.com/welcome/default/fcn-1') + #try: + # # 2.7+ only + # self.assertRaisesRegexp(HTTP, '400 BAD REQUEST \[invalid path\]', filter_url, 'http://domain.com/welcome/default/fcn-1') + #except AttributeError: + # pass + + def test_routes_error(self): + ''' + Test rewrite of HTTP errors + ''' + router_err = dict() + load(rdict=router_err) + self.assertEqual(filter_err(200), 200) + self.assertEqual(filter_err(399), 399) + self.assertEqual(filter_err(400), 400) + + def test_routes_args(self): + ''' + Test URL args parsing/generation + ''' + data = r'''routes_in = [ + ('/robots.txt', '/welcome/static/robots.txt'), + ('/favicon.ico', '/welcome/static/favicon.ico'), + ('/admin$anything', '/admin$anything'), + ('.*:https?://(.*\\.)?domain1.com:$method /', '/app1/default'), + ('.*:https?://(.*\\.)?domain1.com:$method /static/$anything', + '/app1/static/$anything'), + ('.*:https?://(.*\\.)?domain1.com:$method /appadmin/$anything', + '/app1/appadmin/$anything'), + ('.*:https?://(.*\\.)?domain1.com:$method /$anything', + '/app1/default/$anything'), + ('.*:https?://(.*\\.)?domain2.com:$method /', '/app2/default'), + ('.*:https?://(.*\\.)?domain2.com:$method /static/$anything', + '/app2/static/$anything'), + ('.*:https?://(.*\\.)?domain2.com:$method /appadmin/$anything', + '/app2/appadmin/$anything'), + ('.*:https?://(.*\\.)?domain2.com:$method /$anything', + '/app2/default/$anything'), + ('.*:https?://(.*\\.)?domain3.com:$method /', '/app3/defcon3'), + ('.*:https?://(.*\\.)?domain3.com:$method /static/$anything', + '/app3/static/$anything'), + ('.*:https?://(.*\\.)?domain3.com:$method /appadmin/$anything', + '/app3/appadmin/$anything'), + ('.*:https?://(.*\\.)?domain3.com:$method /$anything', + '/app3/defcon3/$anything'), + ('/', '/welcome/default'), + ('/welcome/default/$anything', '/welcome/default/$anything'), + ('/welcome/$anything', '/welcome/default/$anything'), + ('/static/$anything', '/welcome/static/$anything'), + ('/appadmin/$anything', '/welcome/appadmin/$anything'), + ('/$anything', '/welcome/default/$anything'), + ] +routes_out = [ + ('/welcome/static/$anything', '/static/$anything'), + ('/welcome/appadmin/$anything', '/appadmin/$anything'), + ('/welcome/default/$anything', '/$anything'), + ('/app1/static/$anything', '/static/$anything'), + ('/app1/appadmin/$anything', '/appadmin/$anything'), + ('/app1/default/$anything', '/$anything'), + ('/app2/static/$anything', '/static/$anything'), + ('/app2/appadmin/$anything', '/appadmin/$anything'), + ('/app2/default/$anything', '/$anything'), + ('/app3/static/$anything', '/static/$anything'), + ('/app3/appadmin/$anything', '/appadmin/$anything'), + ('/app3/defcon3/$anything', '/$anything') + ] +''' + load(data=data) + self.assertEqual( + filter_url('http://domain.com/welcome/default/f/arg1'), + "/welcome/default/f ['arg1']") + self.assertEqual( + filter_url('http://domain.com/welcome/default/f/arg1/'), + "/welcome/default/f ['arg1']") + self.assertEqual( + filter_url('http://domain.com/welcome/default/f/arg1//'), + "/welcome/default/f ['arg1', '']") + self.assertEqual( + filter_url('http://domain.com/welcome/default/f//arg1'), + "/welcome/default/f ['', 'arg1']") + self.assertEqual( + filter_url('http://domain.com/welcome/default/f/arg1/arg2'), + "/welcome/default/f ['arg1', 'arg2']") + self.assertEqual( + filter_url('http://domain.com/welcome/default/f/arg1//arg2'), + "/welcome/default/f ['arg1', '', 'arg2']") + self.assertEqual( + filter_url('http://domain.com/welcome/default/f/arg1//arg3/'), + "/welcome/default/f ['arg1', '', 'arg3']") + self.assertEqual( + filter_url('http://domain.com/welcome/default/f/arg1//arg3//'), + "/welcome/default/f ['arg1', '', 'arg3', '']") + + self.assertEqual( + filter_url('http://domain.com/welcome/default/f', out=True), "/f") + self.assertEqual(regex_filter_out('/welcome/default/f'), "/f") + self.assertEqual( + str(URL(a='welcome', c='default', f='f', args=None)), "/f") + self.assertEqual(str( + URL(a='welcome', c='default', f='f', args=['arg1'])), "/f/arg1") + self.assertEqual(str(URL( + a='welcome', c='default', f='f', args=['arg1', ''])), "/f/arg1//") + self.assertEqual(str(URL(a='welcome', c='default', f='f', + args=['arg1', '', 'arg3'])), "/f/arg1//arg3") + self.assertEqual(str( + URL(a='welcome', c='default', f='f', args=['ar g'])), "/f/ar%20g") + self.assertEqual(str(URL( + a='welcome', c='default', f='f', args=['årg'])), "/f/%C3%A5rg") + self.assertEqual( + URL(a='welcome', c='default', f='fünc'), "/fünc") + self.assertEqual( + to_bytes(URL(a='welcome', c='default', f='fünc')), b"/f\xc3\xbcnc") + + def test_routes_anchor(self): + ''' + Test URL with anchor + ''' + self.assertEqual( + str(URL(a='a', c='c', f='f', anchor='anchor')), "/a/c/f#anchor") + load(data='') + self.assertEqual( + str(URL(a='a', c='c', f='f', anchor='anchor')), "/a/c/f#anchor") + args = ['a1', 'a2'] + self.assertEqual( + str(URL(a='a', c='c', f='f', args=args, anchor='anchor')), + "/a/c/f/a1/a2#anchor") + vars = dict(v1=1, v2=2) + self.assertEqual( + str(URL(a='a', c='c', f='f', vars=vars, anchor='anchor')), + "/a/c/f?v1=1&v2=2#anchor") + self.assertEqual( + str(URL( + a='a', c='c', f='f', args=args, vars=vars, anchor='anchor')), + "/a/c/f/a1/a2?v1=1&v2=2#anchor") + + data = r'''routes_out = [ + ('/init/default/index', '/'), + ]''' + load(data=data) + self.assertEqual(str(URL(a='init', c='default', f='index')), + "/") + self.assertEqual( + str(URL(a='init', c='default', f='index', anchor='anchor')), + "/init/default/index#anchor") + + data = r'''routes_out = [ + (r'/init/default/index(?P(#.*)?)', r'/\g'), + ]''' + load(data=data) + self.assertEqual(str(URL(a='init', c='default', f='index')), + "/") + self.assertEqual( + str(URL(a='init', c='default', f='index', anchor='anchor')), + "/#anchor") + + data = r'''routes_out = [ + (r'/init/default/index(?P([?#].*)?)', r'/\g'), + ]''' + load(data=data) + self.assertEqual(str(URL(a='init', c='default', f='index')), + "/") + self.assertEqual( + str(URL(a='init', c='default', f='index', anchor='anchor')), + "/#anchor") + query = dict(var='abc') + self.assertEqual( + str(URL(a='init', c='default', f='index', vars=query)), + "/?var=abc") + self.assertEqual( + str(URL(a='init', c='default', f='index', + vars=query, anchor='anchor')), + "/?var=abc#anchor") + + def test_routes_absolute(self): + ''' + Test absolute URL + ''' + load(data='') + r = Storage() + r.env = Storage() + r.env.http_host = 'domain.com' + r.env.wsgi_url_scheme = 'httpx' # distinguish incoming scheme + self.assertEqual(str(URL(r=r, a='a', c='c', f='f')), "/a/c/f") + self.assertEqual(str(URL(r=r, a='a', c='c', f='f', host=True)), + "httpx://domain.com/a/c/f") + self.assertEqual(str(URL(r=r, a='a', c='c', f='f', host='host.com')), + "httpx://host.com/a/c/f") + self.assertEqual(str(URL(r=r, a='a', c='c', f='f', scheme=True)), + "httpx://domain.com/a/c/f") + self.assertEqual(str(URL(r=r, a='a', c='c', f='f', scheme=False)), + "/a/c/f") + self.assertEqual(str(URL(r=r, a='a', c='c', f='f', scheme='https')), + "https://domain.com/a/c/f") + self.assertEqual(str(URL(r=r, a='a', c='c', f='f', scheme='wss')), + "wss://domain.com/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', scheme=True, host=True)), + "httpx://domain.com/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', scheme='https', host=True)), + "https://domain.com/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', scheme=False, host=True)), + "httpx://domain.com/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', scheme=True, host='host.com')), + "httpx://host.com/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', scheme=False, host='host.com')), + "httpx://host.com/a/c/f") + self.assertEqual(str(URL(r=r, a='a', c='c', f='f', port=1234)), + "httpx://domain.com:1234/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', scheme=True, port=1234)), + "httpx://domain.com:1234/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', host='host.com', port=1234)), + "httpx://host.com:1234/a/c/f") + self.assertEqual( + str(URL(r=r, a='a', c='c', f='f', scheme='wss', + host='host.com', port=1234)), + "wss://host.com:1234/a/c/f") + + def test_request_uri(self): + ''' + Test REQUEST_URI in env + ''' + data = r'''routes_in = [ + ('/abc', '/init/default/abc'), + ('/index/$anything', '/init/default/index/$anything'), + ] +''' + load(data=data) + self.assertEqual( + filter_url('http://domain.com/abc', env=True).request_uri, + '/init/default/abc') + self.assertEqual( + filter_url('http://domain.com/abc?def', env=True).request_uri, + '/init/default/abc?def') + self.assertEqual( + filter_url('http://domain.com/index/abc', env=True).request_uri, + "/init/default/index/abc") + self.assertEqual( + filter_url('http://domain.com/index/a%20bc', env=True).request_uri, + "/init/default/index/a bc") diff --git a/web2py/gluon/tests/test_scheduler.py b/web2py/gluon/tests/test_scheduler.py new file mode 100644 index 0000000..ee1270f --- /dev/null +++ b/web2py/gluon/tests/test_scheduler.py @@ -0,0 +1,896 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" + Unit tests for gluon.scheduler +""" +import os +import unittest +import glob +import datetime +import sys + +from gluon.storage import Storage +from gluon.languages import translator +from gluon.scheduler import JobGraph, Scheduler, CronParser +from gluon.dal import DAL + + +class BaseTestScheduler(unittest.TestCase): + def setUp(self): + self.db = None + self.cleanfolder() + from gluon.globals import current + s = Storage({'application': 'welcome', + 'folder': 'applications/welcome', + 'controller': 'default'}) + current.request = s + T = translator('', 'en') + current.T = T + self.db = DAL('sqlite://dummy2.db', check_reserved=['all']) + + def cleanfolder(self): + if self.db: + self.db.close() + try: + os.unlink('dummy2.db') + except: + pass + tfiles = glob.glob('*_scheduler*.table') + for a in tfiles: + os.unlink(a) + + def tearDown(self): + self.cleanfolder() + try: + self.inner_teardown() + except: + pass + + +class CronParserTest(unittest.TestCase): + + def testMinute(self): + # minute asterisk + base = datetime.datetime(2010, 1, 23, 12, 18) + itr = CronParser('*/1 * * * *', base) + n1 = itr.get_next() # 19 + self.assertEqual(base.year, n1.year) + self.assertEqual(base.month, n1.month) + self.assertEqual(base.day, n1.day) + self.assertEqual(base.hour, n1.hour) + self.assertEqual(base.minute, n1.minute - 1) + for i in range(39): # ~ 58 + itr.get_next() + n2 = itr.get_next() + self.assertEqual(n2.minute, 59) + n3 = itr.get_next() + self.assertEqual(n3.minute, 0) + self.assertEqual(n3.hour, 13) + + itr = CronParser('*/5 * * * *', base) + n4 = itr.get_next() + self.assertEqual(n4.minute, 20) + for i in range(6): + itr.get_next() + n5 = itr.get_next() + self.assertEqual(n5.minute, 55) + n6 = itr.get_next() + self.assertEqual(n6.minute, 0) + self.assertEqual(n6.hour, 13) + + base = datetime.datetime(2010, 1, 23, 12, 18) + itr = CronParser('4/34 * * * *', base) + n7 = itr.get_next() + self.assertEqual(n7.minute, 38) + self.assertEqual(n7.hour, 12) + n8 = itr.get_next() + self.assertEqual(n8.minute, 4) + self.assertEqual(n8.hour, 13) + + def testHour(self): + base = datetime.datetime(2010, 1, 24, 12, 2) + itr = CronParser('0 */3 * * *', base) + n1 = itr.get_next() + self.assertEqual(n1.hour, 15) + self.assertEqual(n1.minute, 0) + for i in range(2): + itr.get_next() + n2 = itr.get_next() + self.assertEqual(n2.hour, 0) + self.assertEqual(n2.day, 25) + + def testDay(self): + base = datetime.datetime(2010, 2, 24, 12, 9) + itr = CronParser('0 0 */3 * *', base) + n1 = itr.get_next() + # 1 4 7 10 13 16 19 22 25 28 + self.assertEqual(n1.day, 25) + n2 = itr.get_next() + self.assertEqual(n2.day, 28) + n3 = itr.get_next() + self.assertEqual(n3.day, 1) + self.assertEqual(n3.month, 3) + + # test leap year + base = datetime.datetime(1996, 2, 27) + itr = CronParser('0 0 * * *', base) + n1 = itr.get_next() + self.assertEqual(n1.day, 28) + self.assertEqual(n1.month, 2) + n2 = itr.get_next() + self.assertEqual(n2.day, 29) + self.assertEqual(n2.month, 2) + + base2 = datetime.datetime(2000, 2, 27) + itr2 = CronParser('0 0 * * *', base2) + n3 = itr2.get_next() + self.assertEqual(n3.day, 28) + self.assertEqual(n3.month, 2) + n4 = itr2.get_next() + self.assertEqual(n4.day, 29) + self.assertEqual(n4.month, 2) + + def testWeekDay(self): + base = datetime.datetime(2010, 2, 25) + itr = CronParser('0 0 * * sat', base) + n1 = itr.get_next() + self.assertEqual(n1.isoweekday(), 6) + self.assertEqual(n1.day, 27) + n2 = itr.get_next() + self.assertEqual(n2.isoweekday(), 6) + self.assertEqual(n2.day, 6) + self.assertEqual(n2.month, 3) + + base = datetime.datetime(2010, 1, 25) + itr = CronParser('0 0 1 * wed', base) + n1 = itr.get_next() + self.assertEqual(n1.month, 1) + self.assertEqual(n1.day, 27) + self.assertEqual(n1.year, 2010) + n2 = itr.get_next() + self.assertEqual(n2.month, 2) + self.assertEqual(n2.day, 1) + self.assertEqual(n2.year, 2010) + n3 = itr.get_next() + self.assertEqual(n3.month, 2) + self.assertEqual(n3.day, 3) + self.assertEqual(n3.year, 2010) + + def testMonth(self): + base = datetime.datetime(2010, 1, 25) + itr = CronParser('0 0 1 * *', base) + n1 = itr.get_next() + self.assertEqual(n1.month, 2) + self.assertEqual(n1.day, 1) + n2 = itr.get_next() + self.assertEqual(n2.month, 3) + self.assertEqual(n2.day, 1) + for i in range(8): + itr.get_next() + n3 = itr.get_next() + self.assertEqual(n3.month, 12) + self.assertEqual(n3.year, 2010) + n4 = itr.get_next() + self.assertEqual(n4.month, 1) + self.assertEqual(n4.year, 2011) + + base = datetime.datetime(2010, 1, 25) + itr = CronParser('0 0 1 */4 *', base) + n1 = itr.get_next() + self.assertEqual(n1.month, 5) + self.assertEqual(n1.day, 1) + + base = datetime.datetime(2010, 1, 25) + itr = CronParser('0 0 1 1-3 *', base) + n1 = itr.get_next() + self.assertEqual(n1.month, 2) + self.assertEqual(n1.day, 1) + n2 = itr.get_next() + self.assertEqual(n2.month, 3) + self.assertEqual(n2.day, 1) + n3 = itr.get_next() + self.assertEqual(n3.month, 1) + self.assertEqual(n3.day, 1) + + def testSundayToThursdayWithAlphaConversion(self): + base = datetime.datetime(2010, 8, 25, 15, 56) + itr = CronParser("30 22 * * sun-thu", base) + n1 = itr.get_next() + self.assertEqual(base.year, n1.year) + self.assertEqual(base.month, n1.month) + self.assertEqual(base.day, n1.day) + self.assertEqual(22, n1.hour) + self.assertEqual(30, n1.minute) + + def testISOWeekday(self): + base = datetime.datetime(2010, 2, 25) + itr = CronParser('0 0 * * 7', base) + n1 = itr.get_next() + self.assertEqual(n1.isoweekday(), 7) + self.assertEqual(n1.day, 28) + n2 = itr.get_next() + self.assertEqual(n2.isoweekday(), 7) + self.assertEqual(n2.day, 7) + self.assertEqual(n2.month, 3) + base = datetime.datetime(2010, 2, 22) + itr = CronParser('0 0 * * */2', base) + n1 = itr.get_next() + self.assertEqual(n1.isoweekday(), 2) + self.assertEqual(n1.day, 23) + n2 = itr.get_next() + self.assertEqual(n2.isoweekday(), 4) + self.assertEqual(n2.day, 25) + + def testBug2(self): + + base = datetime.datetime(2012, 1, 1, 0, 0) + itr = CronParser('0 * * 3 *', base) + n1 = itr.get_next() + self.assertEqual(n1.year, base.year) + self.assertEqual(n1.month, 3) + self.assertEqual(n1.day, base.day) + self.assertEqual(n1.hour, base.hour) + self.assertEqual(n1.minute, base.minute) + + n2 = itr.get_next() + self.assertEqual(n2.year, base.year) + self.assertEqual(n2.month, 3) + self.assertEqual(n2.day, base.day) + self.assertEqual(n2.hour, base.hour + 1) + self.assertEqual(n2.minute, base.minute) + + n3 = itr.get_next() + self.assertEqual(n3.year, base.year) + self.assertEqual(n3.month, 3) + self.assertEqual(n3.day, base.day) + self.assertEqual(n3.hour, base.hour + 2) + self.assertEqual(n3.minute, base.minute) + + def testBug3(self): + base = datetime.datetime(2013, 3, 1, 12, 17, 34, 257877) + c = CronParser('00 03 16,30 * *', base) + + n1 = c.get_next() + self.assertEqual(n1.month, 3) + self.assertEqual(n1.day, 16) + + n2 = c.get_next() + self.assertEqual(n2.month, 3) + self.assertEqual(n2.day, 30) + + n3 = c.get_next() + self.assertEqual(n3.month, 4) + self.assertEqual(n3.day, 16) + + def test_rangeGenerator(self): + base = datetime.datetime(2013, 3, 4, 0, 0) + itr = CronParser('1-9/2 0 1 * *', base) + n1 = itr.get_next() + n2 = itr.get_next() + n3 = itr.get_next() + n4 = itr.get_next() + n5 = itr.get_next() + self.assertEqual(n1.minute, 1) + self.assertEqual(n2.minute, 3) + self.assertEqual(n3.minute, 5) + self.assertEqual(n4.minute, 7) + self.assertEqual(n5.minute, 9) + + def test_iterGenerator(self): + base = datetime.datetime(2013, 3, 4, 0, 0) + itr = CronParser('1-9/2 0 1 * *', base) + x = 0 + for n in itr: + x += 1 + if x > 4: + break + self.assertEqual(n.minute, 9) + + def test_invalidcron(self): + base = datetime.datetime(2013, 3, 4, 0, 0) + itr = CronParser('5 4 31 2 *', base) + self.assertRaises(ValueError, itr.get_next) + itr = CronParser('* * 5-1 * *', base) + self.assertRaises(ValueError, itr.get_next) + itr = CronParser('* * * janu-jun *', base) + self.assertRaises(KeyError, itr.get_next) + itr = CronParser('* * * * * *', base) + self.assertRaises(ValueError, itr.get_next) + itr = CronParser('* * * *', base) + self.assertRaises(ValueError, itr.get_next) + + def testLastDayOfMonth(self): + base = datetime.datetime(2015, 9, 4) + itr = CronParser('0 0 L * *', base) + n1 = itr.get_next() + self.assertEqual(n1.month, 9) + self.assertEqual(n1.day, 30) + n2 = itr.get_next() + self.assertEqual(n2.month, 10) + self.assertEqual(n2.day, 31) + n3 = itr.get_next() + self.assertEqual(n3.month, 11) + self.assertEqual(n3.day, 30) + n4 = itr.get_next() + self.assertEqual(n4.month, 12) + self.assertEqual(n4.day, 31) + + base = datetime.datetime(1996, 2, 27) + itr = CronParser('0 0 L * *', base) + n1 = itr.get_next() + self.assertEqual(n1.day, 29) + self.assertEqual(n1.month, 2) + n2 = itr.get_next() + self.assertEqual(n2.day, 31) + self.assertEqual(n2.month, 3) + + def testSpecialExpr(self): + base = datetime.datetime(2000, 1, 1) + itr = CronParser('@yearly', base) + n1 = itr.get_next() + self.assertEqual(n1.day, 1) + self.assertEqual(n1.month, 1) + self.assertEqual(n1.year, base.year + 1) + self.assertEqual(n1.hour, 0) + self.assertEqual(n1.minute, 0) + + itr = CronParser('@annually', base) + n1 = itr.get_next() + self.assertEqual(n1.day, 1) + self.assertEqual(n1.month, 1) + self.assertEqual(n1.year, base.year + 1) + self.assertEqual(n1.hour, 0) + self.assertEqual(n1.minute, 0) + + itr = CronParser('@monthly', base) + n1 = itr.get_next() + self.assertEqual(n1.day, 1) + self.assertEqual(n1.month, base.month + 1) + self.assertEqual(n1.year, base.year) + self.assertEqual(n1.hour, 0) + self.assertEqual(n1.minute, 0) + + itr = CronParser('@weekly', base) + n1 = itr.get_next() + self.assertEqual(n1.day, 2) + self.assertEqual(n1.month, base.month) + self.assertEqual(n1.year, base.year) + self.assertEqual(n1.hour, 0) + self.assertEqual(n1.minute, 0) + n2 = itr.get_next() + self.assertEqual(n2.day, 9) + self.assertEqual(n2.month, base.month) + self.assertEqual(n2.year, base.year) + self.assertEqual(n2.hour, 0) + self.assertEqual(n2.minute, 0) + n3 = itr.get_next() + self.assertEqual(n3.day, 16) + self.assertEqual(n3.month, base.month) + self.assertEqual(n3.year, base.year) + self.assertEqual(n3.hour, 0) + self.assertEqual(n3.minute, 0) + + itr = CronParser('@daily', base) + n1 = itr.get_next() + self.assertEqual(n1.day, 2) + self.assertEqual(n1.month, base.month) + self.assertEqual(n1.year, base.year) + self.assertEqual(n1.hour, 0) + self.assertEqual(n1.minute, 0) + + itr = CronParser('@midnight', base) + n1 = itr.get_next() + self.assertEqual(n1.day, 2) + self.assertEqual(n1.month, base.month) + self.assertEqual(n1.year, base.year) + self.assertEqual(n1.hour, 0) + self.assertEqual(n1.minute, 0) + + itr = CronParser('@hourly', base) + n1 = itr.get_next() + self.assertEqual(n1.day, 1) + self.assertEqual(n1.month, base.month) + self.assertEqual(n1.year, base.year) + self.assertEqual(n1.hour, 1) + self.assertEqual(n1.minute, 0) + + + +class TestsForJobGraph(BaseTestScheduler): + + def testJobGraph(self): + s = Scheduler(self.db) + myjob = JobGraph(self.db, 'job_1') + fname = 'foo' + # We have a few items to wear, and there's an "order" to respect... + # Items are: watch, jacket, shirt, tie, pants, undershorts, belt, shoes, socks + # Now, we can't put on the tie without wearing the shirt first, etc... + watch = s.queue_task(fname, task_name='watch') + jacket = s.queue_task(fname, task_name='jacket') + shirt = s.queue_task(fname, task_name='shirt') + tie = s.queue_task(fname, task_name='tie') + pants = s.queue_task(fname, task_name='pants') + undershorts = s.queue_task(fname, task_name='undershorts') + belt = s.queue_task(fname, task_name='belt') + shoes = s.queue_task(fname, task_name='shoes') + socks = s.queue_task(fname, task_name='socks') + # before the tie, comes the shirt + myjob.add_deps(tie.id, shirt.id) + # before the belt too comes the shirt + myjob.add_deps(belt.id, shirt.id) + # before the jacket, comes the tie + myjob.add_deps(jacket.id, tie.id) + # before the belt, come the pants + myjob.add_deps(belt.id, pants.id) + # before the shoes, comes the pants + myjob.add_deps(shoes.id, pants.id) + # before the pants, comes the undershorts + myjob.add_deps(pants.id, undershorts.id) + # before the shoes, comes the undershorts + myjob.add_deps(shoes.id, undershorts.id) + # before the jacket, comes the belt + myjob.add_deps(jacket.id, belt.id) + # before the shoes, comes the socks + myjob.add_deps(shoes.id, socks.id) + + ## results in the following topological sort + # 9,3,6 --> 4,5 --> 8,7 --> 2 + # socks, shirt, undershorts + # tie, pants + # shoes, belt + # jacket + known_toposort = [ + set([socks.id, shirt.id, undershorts.id]), + set([tie.id, pants.id]), + set([shoes.id, belt.id]), + set([jacket.id]) + ] + toposort = myjob.validate('job_1') + self.assertEqual(toposort, known_toposort) + # add a cyclic dependency, jacket to undershorts + myjob.add_deps(undershorts.id, jacket.id) + # no exceptions raised, but result None + self.assertEqual(myjob.validate('job_1'), None) + + def testJobGraphFailing(self): + s = Scheduler(self.db) + myjob = JobGraph(self.db, 'job_1') + fname = 'foo' + # We have a few items to wear, and there's an "order" to respect... + # Items are: watch, jacket, shirt, tie, pants, undershorts, belt, shoes, socks + # Now, we can't put on the tie without wearing the shirt first, etc... + watch = s.queue_task(fname, task_name='watch') + jacket = s.queue_task(fname, task_name='jacket') + shirt = s.queue_task(fname, task_name='shirt') + tie = s.queue_task(fname, task_name='tie') + pants = s.queue_task(fname, task_name='pants') + undershorts = s.queue_task(fname, task_name='undershorts') + belt = s.queue_task(fname, task_name='belt') + shoes = s.queue_task(fname, task_name='shoes') + socks = s.queue_task(fname, task_name='socks') + # before the tie, comes the shirt + myjob.add_deps(tie.id, shirt.id) + # before the belt too comes the shirt + myjob.add_deps(belt.id, shirt.id) + # before the jacket, comes the tie + myjob.add_deps(jacket.id, tie.id) + # before the belt, come the pants + myjob.add_deps(belt.id, pants.id) + # before the shoes, comes the pants + myjob.add_deps(shoes.id, pants.id) + # before the pants, comes the undershorts + myjob.add_deps(pants.id, undershorts.id) + # before the shoes, comes the undershorts + myjob.add_deps(shoes.id, undershorts.id) + # before the jacket, comes the belt + myjob.add_deps(jacket.id, belt.id) + # before the shoes, comes the socks + myjob.add_deps(shoes.id, socks.id) + # add a cyclic dependency, jacket to undershorts + myjob.add_deps(undershorts.id, jacket.id) + # no exceptions raised, but result None + self.assertEqual(myjob.validate('job_1'), None) + # and no deps added + deps_inserted = self.db(self.db.scheduler_task_deps.id>0).count() + self.assertEqual(deps_inserted, 0) + + def testJobGraphDifferentJobs(self): + s = Scheduler(self.db) + myjob1 = JobGraph(self.db, 'job_1') + myjob2 = JobGraph(self.db, 'job_2') + fname = 'foo' + # We have a few items to wear, and there's an "order" to respect... + # Items are: watch, jacket, shirt, tie, pants, undershorts, belt, shoes, socks + # Now, we can't put on the tie without wearing the shirt first, etc... + watch = s.queue_task(fname, task_name='watch') + jacket = s.queue_task(fname, task_name='jacket') + shirt = s.queue_task(fname, task_name='shirt') + tie = s.queue_task(fname, task_name='tie') + pants = s.queue_task(fname, task_name='pants') + undershorts = s.queue_task(fname, task_name='undershorts') + belt = s.queue_task(fname, task_name='belt') + shoes = s.queue_task(fname, task_name='shoes') + socks = s.queue_task(fname, task_name='socks') + # before the tie, comes the shirt + myjob1.add_deps(tie.id, shirt.id) + # before the belt too comes the shirt + myjob1.add_deps(belt.id, shirt.id) + # before the jacket, comes the tie + myjob1.add_deps(jacket.id, tie.id) + # before the belt, come the pants + myjob1.add_deps(belt.id, pants.id) + # before the shoes, comes the pants + myjob2.add_deps(shoes.id, pants.id) + # before the pants, comes the undershorts + myjob2.add_deps(pants.id, undershorts.id) + # before the shoes, comes the undershorts + myjob2.add_deps(shoes.id, undershorts.id) + # before the jacket, comes the belt + myjob2.add_deps(jacket.id, belt.id) + # before the shoes, comes the socks + myjob2.add_deps(shoes.id, socks.id) + # every job by itself can be completed + self.assertNotEqual(myjob1.validate('job_1'), None) + self.assertNotEqual(myjob1.validate('job_2'), None) + # and, implicitly, every queued task can be too + self.assertNotEqual(myjob1.validate(), None) + # add a cyclic dependency, jacket to undershorts + myjob2.add_deps(undershorts.id, jacket.id) + # every job can still be completed by itself + self.assertNotEqual(myjob1.validate('job_1'), None) + self.assertNotEqual(myjob1.validate('job_2'), None) + # but trying to see if every task will ever be completed fails + self.assertEqual(myjob2.validate(), None) + + +class TestsForSchedulerAPIs(BaseTestScheduler): + + def testQueue_Task(self): + + def isnotqueued(result): + self.assertEqual(result.id, None) + self.assertEqual(result.uuid, None) + self.assertEqual(len(result.errors.keys()) > 0, True) + + def isqueued(result): + self.assertNotEqual(result.id, None) + self.assertNotEqual(result.uuid, None) + self.assertEqual(len(result.errors.keys()), 0) + + s = Scheduler(self.db) + fname = 'foo' + watch = s.queue_task(fname, task_name='watch') + # queuing a task returns id, errors, uuid + self.assertEqual(set(watch.keys()), set(['id', 'uuid', 'errors'])) + # queueing nothing isn't allowed + self.assertRaises(TypeError, s.queue_task, *[]) + # passing pargs and pvars wrongly + # # pargs as dict + isnotqueued(s.queue_task(fname, dict(a=1), dict(b=1))) + # # pvars as list + isnotqueued(s.queue_task(fname, ['foo', 'bar'], ['foo', 'bar'])) + # two tasks with the same uuid won't be there + isqueued(s.queue_task(fname, uuid='a')) + isnotqueued(s.queue_task(fname, uuid='a')) + # # #FIXME add here every parameter + + def testTask_Status(self): + s = Scheduler(self.db) + fname = 'foo' + watch = s.queue_task(fname, task_name='watch') + # fetch status by id + by_id = s.task_status(watch.id) + # fetch status by uuid + by_uuid = s.task_status(watch.uuid) + # fetch status by query + by_query = s.task_status(self.db.scheduler_task.function_name == 'foo') + self.assertEqual(by_id, by_uuid) + self.assertEqual(by_id, by_query) + # fetch status by anything else throws + self.assertRaises(SyntaxError, s.task_status, *[[1, 2]]) + # adding output returns the joined set, plus "result" + rtn = s.task_status(watch.id, output=True) + self.assertEqual(set(rtn.keys()), set(['scheduler_run', 'scheduler_task', 'result'])) + + +class testForSchedulerRunnerBase(BaseTestScheduler): + + def inner_teardown(self): + from gluon import current + fdest = os.path.join(current.request.folder, 'models', 'scheduler.py') + os.unlink(fdest) + additional_files = [ + os.path.join(current.request.folder, 'private', 'demo8.pholder'), + os.path.join(current.request.folder, 'views', 'issue_1485_2.html'), + ] + for f in additional_files: + try: + os.unlink(f) + except: + pass + + def writeview(self, content, dest=None): + from gluon import current + fdest = os.path.join(current.request.folder, 'views', dest) + with open(fdest, 'w') as q: + q.write(content) + + def writefunction(self, content, initlines=None): + from gluon import current + fdest = os.path.join(current.request.folder, 'models', 'scheduler.py') + if initlines is None: + initlines = """ +import os +import time +from gluon.scheduler import Scheduler +db_dal = os.path.abspath(os.path.join(request.folder, '..', '..', 'dummy2.db')) +sched_dal = DAL('sqlite://%s' % db_dal, folder=os.path.dirname(db_dal)) +sched = Scheduler(sched_dal, max_empty_runs=15, migrate=False, heartbeat=1) +def termination(): + sched.terminate() + sched_dal.commit() + """ + with open(fdest, 'w') as q: + q.write(initlines) + q.write(content) + + def exec_sched(self): + import subprocess + call_args = [sys.executable, 'web2py.py', '--no-banner', '-D', '20','-K', 'welcome'] + ret = subprocess.call(call_args, env=dict(os.environ)) + return ret + + def fetch_results(self, sched, task): + info = sched.task_status(task.id) + task_runs = self.db(self.db.scheduler_run.task_id == task.id).select() + return info, task_runs + + def exec_asserts(self, stmts, tag): + for stmt in stmts: + self.assertEqual(stmt[1], True, msg="%s - %s" % (tag, stmt[0])) + + +class TestsForSchedulerRunner(testForSchedulerRunnerBase): + + def testRepeats_and_Expired_and_Prio(self): + s = Scheduler(self.db) + repeats = s.queue_task('demo1', ['a', 'b'], dict(c=1, d=2), repeats=2, period=5) + a_while_ago = datetime.datetime.now() - datetime.timedelta(seconds=60) + expired = s.queue_task('demo4', stop_time=a_while_ago) + prio1 = s.queue_task('demo1', ['scheduled_first']) + prio2 = s.queue_task('demo1', ['scheduled_second'], next_run_time=a_while_ago) + self.db.commit() + self.writefunction(r""" +def demo1(*args,**vars): + print('you passed args=%s and vars=%s' % (args, vars)) + return args[0] + +def demo4(): + time.sleep(15) + print("I'm printing something") + return dict(a=1, b=2) +""") + ret = self.exec_sched() + self.assertEqual(ret, 0) + # repeats check + task, task_run = self.fetch_results(s, repeats) + res = [ + ("task status completed", task.status == 'COMPLETED'), + ("task times_run is 2", task.times_run == 2), + ("task ran 2 times only", len(task_run) == 2), + ("scheduler_run records are COMPLETED ", (task_run[0].status == task_run[1].status == 'COMPLETED')), + ("period is respected", (task_run[1].start_time > task_run[0].start_time + datetime.timedelta(seconds=task.period))) + ] + self.exec_asserts(res, 'REPEATS') + + # expired check + task, task_run = self.fetch_results(s, expired) + res = [ + ("task status expired", task.status == 'EXPIRED'), + ("task times_run is 0", task.times_run == 0), + ("task didn't run at all", len(task_run) == 0) + ] + self.exec_asserts(res, 'EXPIRATION') + + # prio check + task1 = s.task_status(prio1.id, output=True) + task2 = s.task_status(prio2.id, output=True) + res = [ + ("tasks status completed", task1.scheduler_task.status == task2.scheduler_task.status == 'COMPLETED'), + ("priority2 was executed before priority1" , task1.scheduler_run.id > task2.scheduler_run.id) + ] + self.exec_asserts(res, 'PRIORITY') + + def testNoReturn_and_Timeout_and_Progress(self): + s = Scheduler(self.db) + noret1 = s.queue_task('demo5') + noret2 = s.queue_task('demo3') + timeout1 = s.queue_task('demo4', timeout=5) + timeout2 = s.queue_task('demo4') + progress = s.queue_task('demo6', sync_output=2) + termination = s.queue_task('termination') + self.db.commit() + self.writefunction(r""" +def demo3(): + time.sleep(3) + print(1/0) + return None + +def demo4(): + time.sleep(15) + print("I'm printing something") + return dict(a=1, b=2) + +def demo5(): + time.sleep(3) + print("I'm printing something") + rtn = dict(a=1, b=2) + +def demo6(): + time.sleep(5) + print('50%') + time.sleep(5) + print('!clear!100%') + return 1 +""") + ret = self.exec_sched() + self.assertEqual(ret, 0) + # noreturn check + task1, task_run1 = self.fetch_results(s, noret1) + task2, task_run2 = self.fetch_results(s, noret2) + res = [ + ("tasks no_returns1 completed", task1.status == 'COMPLETED'), + ("tasks no_returns2 failed", task2.status == 'FAILED'), + ("no_returns1 doesn't have a scheduler_run record", len(task_run1) == 0), + ("no_returns2 has a scheduler_run record FAILED", (len(task_run2) == 1 and task_run2[0].status == 'FAILED')), + ] + self.exec_asserts(res, 'NO_RETURN') + + # timeout check + task1 = s.task_status(timeout1.id, output=True) + task2 = s.task_status(timeout2.id, output=True) + res = [ + ("tasks timeouts1 timeoutted", task1.scheduler_task.status == 'TIMEOUT'), + ("tasks timeouts2 completed", task2.scheduler_task.status == 'COMPLETED') + ] + self.exec_asserts(res, 'TIMEOUT') + + # progress check + task1 = s.task_status(progress.id, output=True) + res = [ + ("tasks percentages completed", task1.scheduler_task.status == 'COMPLETED'), + ("output contains only 100%", task1.scheduler_run.run_output.strip() == "100%") + ] + self.exec_asserts(res, 'PROGRESS') + + def testDrift_and_env_and_immediate(self): + s = Scheduler(self.db) + immediate = s.queue_task('demo1', ['a', 'b'], dict(c=1, d=2), immediate=True) + env = s.queue_task('demo7') + drift = s.queue_task('demo1', ['a', 'b'], dict(c=1, d=2), period=93, prevent_drift=True) + termination = s.queue_task('termination') + self.db.commit() + self.writefunction(r""" +def demo1(*args,**vars): + print('you passed args=%s and vars=%s' % (args, vars)) + return args[0] +import random +def demo7(): + time.sleep(random.randint(1,5)) + print(W2P_TASK, request.now) + return W2P_TASK.id, W2P_TASK.uuid, W2P_TASK.run_id +""") + ret = self.exec_sched() + self.assertEqual(ret, 0) + # immediate check, can only check that nothing breaks + task1 = s.task_status(immediate.id) + res = [ + ("tasks status completed", task1.status == 'COMPLETED'), + ] + self.exec_asserts(res, 'IMMEDIATE') + + # drift check + task, task_run = self.fetch_results(s, drift) + res = [ + ("task status completed", task.status == 'COMPLETED'), + ("next_run_time is exactly start_time + period", (task.next_run_time == task.start_time + datetime.timedelta(seconds=task.period))) + ] + self.exec_asserts(res, 'DRIFT') + + # env check + task1 = s.task_status(env.id, output=True) + res = [ + ("task %s returned W2P_TASK correctly" % (task1.scheduler_task.id), task1.result == [task1.scheduler_task.id, task1.scheduler_task.uuid, task1.scheduler_run.id]), + ] + self.exec_asserts(res, 'ENV') + + + def testRetryFailed(self): + s = Scheduler(self.db) + failed = s.queue_task('demo2', retry_failed=1, period=1) + failed_consecutive = s.queue_task('demo8', retry_failed=2, repeats=2, period=1) + self.db.commit() + self.writefunction(r""" +def demo2(): + 1/0 + +def demo8(): + placeholder = os.path.join(request.folder, 'private', 'demo8.pholder') + with open(placeholder, 'a') as g: + g.write('\nplaceholder for demo8 created') + num_of_lines = 0 + with open(placeholder) as f: + num_of_lines = len([a for a in f.read().split('\n') if a]) + print('number of lines', num_of_lines) + if num_of_lines <= 2: + 1/0 + else: + os.unlink(placeholder) + return 1 +""") + ret = self.exec_sched() + # process finished just fine + self.assertEqual(ret, 0) + # failed - checks + task, task_run = self.fetch_results(s, failed) + res = [ + ("task status failed", task.status == 'FAILED'), + ("task times_run is 0", task.times_run == 0), + ("task times_failed is 2", task.times_failed == 2), + ("task ran 2 times only", len(task_run) == 2), + ("scheduler_run records are FAILED", (task_run[0].status == task_run[1].status == 'FAILED')), + ("period is respected", (task_run[1].start_time > task_run[0].start_time + datetime.timedelta(seconds=task.period))) + ] + self.exec_asserts(res, 'FAILED') + + # failed consecutive - checks + task, task_run = self.fetch_results(s, failed_consecutive) + res = [ + ("task status completed", task.status == 'COMPLETED'), + ("task times_run is 2", task.times_run == 2), + ("task times_failed is 0", task.times_failed == 0), + ("task ran 6 times", len(task_run) == 6), + ("scheduler_run records for COMPLETED is 2", len([run.status for run in task_run if run.status == 'COMPLETED']) == 2), + ("scheduler_run records for FAILED is 4", len([run.status for run in task_run if run.status == 'FAILED']) == 4), + ] + self.exec_asserts(res, 'FAILED_CONSECUTIVE') + + def testRegressions(self): + s = Scheduler(self.db) + huge_result = s.queue_task('demo10', retry_failed=1, period=1) + issue_1485 = s.queue_task('issue_1485') + termination = s.queue_task('termination') + self.db.commit() + self.writefunction(r""" +def demo10(): + res = 'a' * 99999 + return dict(res=res) + +def issue_1485(): + return response.render('issue_1485.html', dict(variable='abc')) +""") + self.writeview(r"""{{=variable}}""", 'issue_1485.html') + ret = self.exec_sched() + # process finished just fine + self.assertEqual(ret, 0) + # huge_result - checks + task_huge = s.task_status(huge_result.id, output=True) + res = [ + ("task status completed", task_huge.scheduler_task.status == 'COMPLETED'), + ("task times_run is 1", task_huge.scheduler_task.times_run == 1), + ("result is the correct one", task_huge.result == dict(res='a' * 99999)) + ] + self.exec_asserts(res, 'HUGE_RESULT') + + task_issue_1485 = s.task_status(issue_1485.id, output=True) + res = [ + ("task status completed", task_issue_1485.scheduler_task.status == 'COMPLETED'), + ("task times_run is 1", task_issue_1485.scheduler_task.times_run == 1), + ("result is the correct one", task_issue_1485.result == 'abc') + ] + self.exec_asserts(res, 'issue_1485') + + +if __name__ == '__main__': + unittest.main() diff --git a/web2py/gluon/tests/test_serializers.py b/web2py/gluon/tests/test_serializers.py new file mode 100644 index 0000000..a7f2a44 --- /dev/null +++ b/web2py/gluon/tests/test_serializers.py @@ -0,0 +1,61 @@ +#!/bin/python +# -*- coding: utf-8 -*- + +""" + Unit tests for gluon.serializers +""" + +import unittest +from .fix_path import fix_sys_path +import datetime +import decimal + +from gluon.serializers import * +from gluon.storage import Storage +# careful with the import path 'cause of isinstance() checks +from gluon.languages import translator +from gluon.html import SPAN + + +class TestSerializers(unittest.TestCase): + + def testJSON(self): + # the main and documented "way" is to use the json() function + # it has a few corner-cases that make json() be somewhat + # different from the standard buyt being compliant + # it's just a matter of conventions + + # incompatible spacing, newer simplejson already account + # for this but it's still better to remember + weird = {'JSON': u"ro" + u'\u2028' + u'ck' + u'\u2029' + u's!'} + rtn = json(weird) + self.assertEqual(rtn, u'{"JSON": "ro\\u2028ck\\u2029s!"}') + # date, datetime, time strictly as strings in isoformat, minus the T + objs = [ + datetime.datetime(2014, 1, 1, 12, 15, 35), + datetime.date(2014, 1, 1), + datetime.time(12, 15, 35) + ] + iso_objs = [obj.isoformat()[:19].replace('T', ' ') for obj in objs] + json_objs = [json(obj) for obj in objs] + json_web2pyfied = [json(obj) for obj in iso_objs] + self.assertEqual(json_objs, json_web2pyfied) + # int or long int()ified + # self.assertEqual(json(1), json(1)) + # decimal stringified + obj = {'a': decimal.Decimal('4.312312312312')} + self.assertEqual(json(obj), u'{"a": "4.312312312312"}') + # lazyT translated + T = translator('', 'en') + lazy_translation = T('abc') + self.assertEqual(json(lazy_translation), u'"abc"') + # html helpers are xml()ed before too + self.assertEqual(json(SPAN('abc')), u'"abc"') + # unicode keys make a difference with loads_json + base = {u'è': 1, 'b': 2} + base_enc = json(base) + base_load = loads_json(base_enc) + self.assertTrue(base == base_load) + # if unicode_keys is false, the standard behaviour is assumed + base_load = loads_json(base_enc, unicode_keys=False) + self.assertFalse(base == base_load) diff --git a/web2py/gluon/tests/test_sqlhtml.py b/web2py/gluon/tests/test_sqlhtml.py new file mode 100644 index 0000000..92c2916 --- /dev/null +++ b/web2py/gluon/tests/test_sqlhtml.py @@ -0,0 +1,441 @@ +#!/bin/python +# -*- coding: utf-8 -*- + +""" + Unit tests for gluon.sqlhtml +""" +import os +import sys +import unittest + +from gluon.sqlhtml import safe_int, SQLFORM, SQLTABLE + +DEFAULT_URI = os.getenv('DB', 'sqlite:memory') + +from gluon.dal import DAL, Field +from pydal.objects import Table +from gluon.tools import Auth, Mail +from gluon.globals import Request, Response, Session +from gluon.storage import Storage +from gluon.languages import translator +from gluon.http import HTTP +from gluon.validators import * + +# TODO: Create these test... + +# class Test_add_class(unittest.TestCase): +# def test_add_class(self): +# pass + + +# class Test_represent(unittest.TestCase): +# def test_represent(self): +# pass + + +# class TestCacheRepresenter(unittest.TestCase): +# def test___call__(self): +# pass + +# def test___init__(self): +# pass + + +class Test_safe_int(unittest.TestCase): + def test_safe_int(self): + # safe int + self.assertEqual(safe_int(1), 1) + # not safe int + self.assertEqual(safe_int('1x'), 0) + # not safe int (alternate default) + self.assertEqual(safe_int('1x', 1), 1) + + +# class Test_safe_float(unittest.TestCase): +# def test_safe_float(self): +# pass + + +# class Test_show_if(unittest.TestCase): +# def test_show_if(self): +# pass + + +# class TestFormWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_widget(self): +# pass + + +# class TestStringWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_widget(self): +# pass + + +# class TestIntegerWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_widget(self): +# pass + + +# class TestDoubleWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_widget(self): +# pass + + +# class TestDecimalWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_widget(self): +# pass + + +# class TestDateWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_widget(self): +# pass + + +# class TestDatetimeWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_widget(self): +# pass + + +# class TestTextWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_widget(self): +# pass + + +# class TestJSONWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_widget(self): +# pass + + +# class TestBooleanWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_widget(self): +# pass + + +# class TestListWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_widget(self): +# pass + + +# class TestMultipleOptionsWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_widget(self): +# pass + + +# class TestRadioWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_widget(self): +# pass + + +# class TestCheckboxesWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_widget(self): +# pass + + +# class TestPasswordWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_widget(self): +# pass + + +# class TestUploadWidget(unittest.TestCase): +# def test__attributes(self): +# pass + +# def test_represent(self): +# pass + +# def test_widget(self): +# pass + + +# class TestAutocompleteWidget(unittest.TestCase): +# def test___call__(self): +# pass + +# def test___init__(self): +# pass + +# def test_callback(self): +# pass + + +# class Test_formstyle_table3cols(unittest.TestCase): +# def test_formstyle_table3cols(self): +# pass + + +# class Test_formstyle_table2cols(unittest.TestCase): +# def test_formstyle_table2cols(self): +# pass + + +# class Test_formstyle_divs(unittest.TestCase): +# def test_formstyle_divs(self): +# pass + + +# class Test_formstyle_inline(unittest.TestCase): +# def test_formstyle_inline(self): +# pass + + +# class Test_formstyle_ul(unittest.TestCase): +# def test_formstyle_ul(self): +# pass + + +# class Test_formstyle_bootstrap(unittest.TestCase): +# def test_formstyle_bootstrap(self): +# pass + + +# class Test_formstyle_bootstrap3_stacked(unittest.TestCase): +# def test_formstyle_bootstrap3_stacked(self): +# pass + + +# class Test_formstyle_bootstrap3_inline_factory(unittest.TestCase): +# def test_formstyle_bootstrap3_inline_factory(self): +# pass + + +class TestSQLFORM(unittest.TestCase): + + def setUp(self): + request = Request(env={}) + request.application = 'a' + request.controller = 'c' + request.function = 'f' + request.folder = 'applications/admin' + response = Response() + session = Session() + T = translator('', 'en') + session.connect(request, response) + from gluon.globals import current + current.request = request + current.response = response + current.session = session + current.T = T + self.db = DAL(DEFAULT_URI, check_reserved=['all']) + self.auth = Auth(self.db) + self.auth.define_tables(username=True, signature=False) + self.db.define_table('t0', Field('tt', default='web2py'), self.auth.signature) + self.auth.enable_record_versioning(self.db) + # Create a user + self.db.auth_user.insert(first_name='Bart', + last_name='Simpson', + username='user1', + email='user1@test.com', + password='password_123', + registration_key=None, + registration_id=None) + + self.db.commit() + + + def test_SQLFORM(self): + form = SQLFORM(self.db.auth_user) + self.assertEqual(form.xml()[:5], b' 0).select(self.db.auth_user.ALL) + sqltable = SQLTABLE(rows) + self.assertEqual(sqltable.xml()[:7], b'') + + +# class TestExportClass(unittest.TestCase): +# def test___init__(self): +# pass + +# def test_export(self): +# pass + +# def test_represented(self): +# pass + + +# class TestExporterTSV(unittest.TestCase): +# def test___init__(self): +# pass + +# def test_export(self): +# pass + +# def test_represented(self): +# pass + + +# class TestExporterCSV(unittest.TestCase): +# def test___init__(self): +# pass + +# def test_export(self): +# pass + +# def test_represented(self): +# pass + + +# class TestExporterCSV_hidden(unittest.TestCase): +# def test___init__(self): +# pass + +# def test_export(self): +# pass + +# def test_represented(self): +# pass + + +# class TestExporterHTML(unittest.TestCase): +# def test___init__(self): +# pass + +# def test_export(self): +# pass + +# def test_represented(self): +# pass + + +# class TestExporterXML(unittest.TestCase): +# def test___init__(self): +# pass + +# def test_export(self): +# pass + +# def test_represented(self): +# pass + + +# class TestExporterJSON(unittest.TestCase): +# def test___init__(self): +# pass + +# def test_export(self): +# pass + +# def test_represented(self): +# pass diff --git a/web2py/gluon/tests/test_storage.py b/web2py/gluon/tests/test_storage.py new file mode 100644 index 0000000..6af22d1 --- /dev/null +++ b/web2py/gluon/tests/test_storage.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" Unit tests for storage.py """ + +import unittest + +from gluon.storage import Storage, StorageList, List +from gluon.http import HTTP +from gluon._compat import pickle + + +class TestStorage(unittest.TestCase): + """ Tests storage.Storage """ + + def test_attribute(self): + """ Tests Storage attribute handling """ + + s = Storage(a=1) + + self.assertEqual(s.a, 1) + self.assertEqual(s['a'], 1) + self.assertEqual(s.b, None) + + s.b = 2 + self.assertEqual(s.a, 1) + self.assertEqual(s['a'], 1) + self.assertEqual(s.b, 2) + self.assertEqual(s['b'], 2) + + s['c'] = 3 + self.assertEqual(s.c, 3) + self.assertEqual(s['c'], 3) + + s.d = list() + self.assertTrue(s.d is s['d']) + + def test_store_none(self): + """ Test Storage store-None handling + s.key = None deletes an item + s['key'] = None sets the item to None + """ + + s = Storage(a=1) + + self.assertTrue('a' in s) + self.assertFalse('b' in s) + s.a = None + # self.assertFalse('a' in s) # how about this? + + s.a = 1 + self.assertTrue('a' in s) + s['a'] = None + self.assertTrue('a' in s) + self.assertTrue(s.a is None) + + def test_item(self): + """ Tests Storage item handling """ + + s = Storage() + + self.assertEqual(s.d, None) + self.assertEqual(s['d'], None) + #self.assertRaises(KeyError, lambda x: s[x], 'd') # old Storage + s.a = 1 + s['a'] = None + self.assertEqual(s.a, None) + self.assertEqual(s['a'], None) + self.assertTrue('a' in s) + + def test_pickling(self): + """ Test storage pickling """ + s = Storage(a=1) + sd = pickle.dumps(s, pickle.HIGHEST_PROTOCOL) + news = pickle.loads(sd) + self.assertEqual(news.a, 1) + + def test_getlist(self): + # usually used with request.vars + a = Storage() + a.x = 'abc' + a.y = ['abc', 'def'] + self.assertEqual(a.getlist('x'), ['abc']) + self.assertEqual(a.getlist('y'), ['abc', 'def']) + self.assertEqual(a.getlist('z'), []) + + def test_getfirst(self): + # usually with request.vars + a = Storage() + a.x = 'abc' + a.y = ['abc', 'def'] + self.assertEqual(a.getfirst('x'), 'abc') + self.assertEqual(a.getfirst('y'), 'abc') + self.assertEqual(a.getfirst('z'), None) + + def test_getlast(self): + # usually with request.vars + a = Storage() + a.x = 'abc' + a.y = ['abc', 'def'] + self.assertEqual(a.getlast('x'), 'abc') + self.assertEqual(a.getlast('y'), 'def') + self.assertEqual(a.getlast('z'), None) + + +class TestStorageList(unittest.TestCase): + """ Tests storage.StorageList """ + + def test_attribute(self): + s = StorageList(a=1) + + self.assertEqual(s.a, 1) + self.assertEqual(s['a'], 1) + self.assertEqual(s.b, []) + s.b.append(1) + self.assertEqual(s.b, [1]) + + +class TestList(unittest.TestCase): + + """ Tests Storage.List (fast-check for request.args()) """ + + def test_listcall(self): + a = List((1, 2, 3)) + self.assertEqual(a(1), 2) + self.assertEqual(a(-1), 3) + self.assertEqual(a(-5), None) + self.assertEqual(a(-5, default='x'), 'x') + self.assertEqual(a(-3, cast=str), '1') + a.append('1234') + self.assertEqual(a(3), '1234') + self.assertEqual(a(3, cast=int), 1234) + a.append('x') + self.assertRaises(HTTP, a, 4, cast=int) + b = List() + # default is always returned when especified + self.assertEqual(b(0, cast=int, default=None), None) + self.assertEqual(b(0, cast=int, default=None, otherwise='teste'), None) + self.assertEqual(b(0, cast=int, default='a', otherwise='teste'), 'a') + # if don't have value and otherwise is especified it will called + self.assertEqual(b(0, otherwise=lambda: 'something'), 'something') + self.assertEqual(b(0, cast=int, otherwise=lambda: 'something'), + 'something') + # except if default is especified + self.assertEqual(b(0, default=0, otherwise=lambda: 'something'), 0) + + def test_listgetitem(self): + '''Mantains list behaviour.''' + a = List((1, 2, 3)) + self.assertEqual(a[0], 1) + self.assertEqual(a[::-1], [3, 2, 1]) diff --git a/web2py/gluon/tests/test_template.py b/web2py/gluon/tests/test_template.py new file mode 100644 index 0000000..9d21d77 --- /dev/null +++ b/web2py/gluon/tests/test_template.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" + Unit tests for gluon.template +""" + +import unittest + +from gluon import template +from gluon.template import render + + +class TestTemplate(unittest.TestCase): + + def testRun(self): + self.assertEqual(render(content='{{for i in range(n):}}{{=i}}{{pass}}', + context=dict(n=3)), '012') + self.assertEqual(render(content='{{if n>2:}}ok{{pass}}', + context=dict(n=3)), 'ok') + self.assertEqual( + render(content='{{try:}}{{n/0}}{{except:}}fail{{pass}}', + context=dict(n=3)), 'fail') + self.assertEqual(render(content='{{="<&>"}}'), '<&>') + self.assertEqual(render(content='"abc"'), '"abc"') + self.assertEqual(render(content='"a\'bc"'), '"a\'bc"') + self.assertEqual(render(content='"a\"bc"'), '"a\"bc"') + self.assertEqual(render(content=r'''"a\"bc"'''), r'"a\"bc"') + self.assertEqual(render(content=r'''"""abc\""""'''), r'"""abc\""""') + + def testEqualWrite(self): + "test generation of response.write from =" + self.assertEqual(render(content='{{=2+2}}'), '4') + self.assertEqual(render(content='{{="abc"}}'), 'abc') + # whitespace is stripped + self.assertEqual(render(content='{{ ="abc"}}'), 'abc') + self.assertEqual(render(content='{{ ="abc" }}'), 'abc') + self.assertEqual(render(content='{{pass\n="abc" }}'), 'abc') + # = recognized only at the beginning of a physical line + self.assertEqual(render( + content='{{xyz = "xyz"\n="abc"\n="def"\n=xyz }}'), 'abcdefxyz') + # = in python blocks + self.assertEqual(render(content='{{if True:\n="abc"\npass }}'), 'abc') + self.assertEqual( + render(content='{{if True:\n="abc"\npass\n="def" }}'), 'abcdef') + self.assertEqual( + render(content='{{if False:\n="abc"\npass\n="def" }}'), 'def') + self.assertEqual(render( + content='{{if True:\n="abc"\nelse:\n="def"\npass }}'), 'abc') + self.assertEqual(render( + content='{{if False:\n="abc"\nelse:\n="def"\npass }}'), 'def') + # codeblock-leading = handles internal newlines, escaped or not + self.assertEqual(render(content='{{=list((1,2,3))}}'), '[1, 2, 3]') + self.assertEqual(render(content='{{=list((1,2,\\\n3))}}'), '[1, 2, 3]') + self.assertEqual(render(content='{{=list((1,2,\n3))}}'), '[1, 2, 3]') + # ...but that means no more = operators in the codeblock + self.assertRaises(SyntaxError, render, content='{{="abc"\n="def" }}') + # = embedded in codeblock won't handle newlines in its argument + self.assertEqual( + render(content='{{pass\n=list((1,2,\\\n3))}}'), '[1, 2, 3]') + self.assertRaises( + SyntaxError, render, content='{{pass\n=list((1,2,\n3))}}') + + def testWithDummyFileSystem(self): + from os.path import join as pjoin + import contextlib + from gluon._compat import StringIO + from gluon.restricted import RestrictedError + + @contextlib.contextmanager + def monkey_patch(module, fn_name, patch): + try: + unpatch = getattr(module, fn_name) + except AttributeError: + unpatch = None + setattr(module, fn_name, patch) + try: + yield + finally: + if unpatch is None: + delattr(module, fn_name) + else: + setattr(module, fn_name, unpatch) + + def dummy_open(path, mode): + if path == pjoin('views', 'layout.html'): + return StringIO("{{block left_sidebar}}left{{end}}" + "{{include}}" + "{{block right_sidebar}}right{{end}}") + elif path == pjoin('views', 'layoutbrackets.html'): + return StringIO("[[block left_sidebar]]left[[end]]" + "[[include]]" + "[[block right_sidebar]]right[[end]]") + elif path == pjoin('views', 'default', 'index.html'): + return StringIO("{{extend 'layout.html'}}" + "{{block left_sidebar}}{{super}} {{end}}" + "to" + "{{block right_sidebar}} {{super}}{{end}}") + elif path == pjoin('views', 'default', 'indexbrackets.html'): + return StringIO("[[extend 'layoutbrackets.html']]" + "[[block left_sidebar]][[super]] [[end]]" + "to" + "[[block right_sidebar]] [[super]][[end]]") + elif path == pjoin('views', 'default', 'missing.html'): + return StringIO("{{extend 'wut'}}" + "{{block left_sidebar}}{{super}} {{end}}" + "to" + "{{block right_sidebar}} {{super}}{{end}}") + elif path == pjoin('views', 'default', 'noescape.html'): + return StringIO("""{{=NOESCAPE('')}}""") + raise IOError + + with monkey_patch(template, 'open', dummy_open): + self.assertEqual( + render(filename=pjoin('views', 'default', 'index.html'), + path='views'), + 'left to right') + self.assertEqual( + render(filename=pjoin('views', 'default', 'indexbrackets.html'), + path='views', delimiters=('[[', ']]')), + 'left to right') + self.assertRaises( + RestrictedError, + render, + filename=pjoin('views', 'default', 'missing.html'), + path='views') + response = template.DummyResponse() + response.delimiters = ('[[', ']]') + self.assertEqual( + render(filename=pjoin('views', 'default', 'indexbrackets.html'), + path='views', context={'response': response}), + 'left to right') + self.assertEqual( + render(filename=pjoin('views', 'default', 'noescape.html'), + context={'NOESCAPE': template.NOESCAPE}), + '') diff --git a/web2py/gluon/tests/test_tools.py b/web2py/gluon/tests/test_tools.py new file mode 100644 index 0000000..2ad46c5 --- /dev/null +++ b/web2py/gluon/tests/test_tools.py @@ -0,0 +1,1390 @@ +#!/bin/python +# -*- coding: utf-8 -*- + +""" + Unit tests for gluon.tools +""" +import os +import sys +import shutil +import tempfile +import smtplib +import datetime +import unittest + +DEFAULT_URI = os.getenv('DB', 'sqlite:memory') + +from gluon.dal import DAL, Field +from pydal.objects import Table +from gluon import tools +from gluon.tools import Auth, Mail, Recaptcha2, prettydate, Expose +from gluon._compat import PY2 +from gluon.globals import Request, Response, Session +from gluon.storage import Storage +from gluon.languages import translator +from gluon.http import HTTP +from gluon import SPAN, H3, TABLE, TR, TD, A, URL, current + +IS_IMAP = "imap" in DEFAULT_URI + + +class TestMail(unittest.TestCase): + """ + Test the Mail class. + """ + + class Message(object): + + def __init__(self, sender, to, payload): + self.sender = sender + self.to = to + self.payload = payload + self._parsed_payload = None + + @property + def parsed_payload(self): + if self._parsed_payload is None: + import email + self._parsed_payload = email.message_from_string(self.payload) + return self._parsed_payload + + class DummySMTP(object): + """ + Dummy smtp server + + NOTE: Test methods should take care of always leaving inbox and users empty when they finish. + """ + inbox = [] + users = {} + + def __init__(self, address, port, **kwargs): + self.address = address + self.port = port + self.has_quit = False + self.tls = False + + def login(self, username, password): + if username not in self.users or self.users[username] != password: + raise smtplib.SMTPAuthenticationError + self.username = username + self.password = password + + def sendmail(self, sender, to, payload): + self.inbox.append(TestMail.Message(sender, to, payload)) + + def quit(self): + self.has_quit = True + + def ehlo(self, hostname=None): + pass + + def starttls(self): + self.tls = True + + def setUp(self): + self.original_SMTP = smtplib.SMTP + self.original_SMTP_SSL = smtplib.SMTP_SSL + smtplib.SMTP = TestMail.DummySMTP + smtplib.SMTP_SSL = TestMail.DummySMTP + + def tearDown(self): + smtplib.SMTP = self.original_SMTP + smtplib.SMTP_SSL = self.original_SMTP_SSL + + def test_hello_world(self): + mail = Mail() + mail.settings.server = 'smtp.example.com:25' + mail.settings.sender = 'you@example.com' + self.assertTrue(mail.send(to=['somebody@example.com'], + subject='hello', + # If reply_to is omitted, then mail.settings.sender is used + reply_to='us@example.com', + message='world')) + message = TestMail.DummySMTP.inbox.pop() + self.assertEqual(message.sender, mail.settings.sender) + self.assertEqual(message.to, ['somebody@example.com']) + header = "To: somebody@example.com\nReply-To: us@example.com\nSubject: hello\n" + self.assertTrue(header in message.payload) + self.assertTrue(message.payload.endswith('world')) + + def test_failed_login(self): + mail = Mail() + mail.settings.server = 'smtp.example.com:25' + mail.settings.sender = 'you@example.com' + mail.settings.login = 'username:password' + self.assertFalse(mail.send(to=['somebody@example.com'], + subject='hello', + # If reply_to is omitted, then mail.settings.sender is used + reply_to='us@example.com', + message='world')) + + def test_login(self): + TestMail.DummySMTP.users['username'] = 'password' + mail = Mail() + mail.settings.server = 'smtp.example.com:25' + mail.settings.sender = 'you@example.com' + mail.settings.login = 'username:password' + self.assertTrue(mail.send(to=['somebody@example.com'], + subject='hello', + # If reply_to is omitted, then mail.settings.sender is used + reply_to='us@example.com', + message='world')) + del TestMail.DummySMTP.users['username'] + TestMail.DummySMTP.inbox.pop() + + def test_html(self): + mail = Mail() + mail.settings.server = 'smtp.example.com:25' + mail.settings.sender = 'you@example.com' + self.assertTrue(mail.send(to=['somebody@example.com'], + subject='hello', + # If reply_to is omitted, then mail.settings.sender is used + reply_to='us@example.com', + message='')) + message = TestMail.DummySMTP.inbox.pop() + self.assertTrue('Content-Type: text/html' in message.payload) + + def test_alternative(self): + mail = Mail() + mail.settings.server = 'smtp.example.com:25' + mail.settings.sender = 'you@example.com' + self.assertTrue(mail.send(to=['somebody@example.com'], + message=('Text only', '
    HTML Only
    '))) + message = TestMail.DummySMTP.inbox.pop() + self.assertTrue(message.parsed_payload.is_multipart()) + self.assertTrue(message.parsed_payload.get_content_type() == 'multipart/alternative') + parts = message.parsed_payload.get_payload() + self.assertTrue('Text only' in parts[0].as_string()) + self.assertTrue('
    HTML Only
    ' in parts[1].as_string()) + + def test_ssl(self): + mail = Mail() + mail.settings.server = 'smtp.example.com:25' + mail.settings.sender = 'you@example.com' + mail.settings.ssl = True + self.assertTrue(mail.send(to=['somebody@example.com'], + subject='hello', + # If reply_to is omitted, then mail.settings.sender is used + reply_to='us@example.com', + message='world')) + TestMail.DummySMTP.inbox.pop() + + def test_tls(self): + mail = Mail() + mail.settings.server = 'smtp.example.com:25' + mail.settings.sender = 'you@example.com' + mail.settings.tls = True + self.assertTrue(mail.send(to=['somebody@example.com'], + subject='hello', + # If reply_to is omitted, then mail.settings.sender is used + reply_to='us@example.com', + message='world')) + TestMail.DummySMTP.inbox.pop() + + def test_attachment(self): + module_file = os.path.abspath(__file__) + mail = Mail() + mail.settings.server = 'smtp.example.com:25' + mail.settings.sender = 'you@example.com' + self.assertTrue(mail.send(to=['somebody@example.com'], + subject='hello', + message='world', + attachments=Mail.Attachment(module_file))) + message = TestMail.DummySMTP.inbox.pop() + attachment = message.parsed_payload.get_payload(1).get_payload(decode=True) + with open(module_file, 'rb') as mf: + self.assertEqual(attachment.decode('utf-8'), mf.read().decode('utf-8')) + # Test missing attachment name error + stream = open(module_file) + self.assertRaises(Exception, lambda *args, **kwargs: Mail.Attachment(*args, **kwargs), stream) + stream.close() + # Test you can define content-id and content type + self.assertTrue(mail.send(to=['somebody@example.com'], + subject='hello', + message='world', + attachments=Mail.Attachment(module_file, content_id='trololo', content_type='tra/lala'))) + message = TestMail.DummySMTP.inbox.pop() + self.assertTrue('Content-Type: tra/lala' in message.payload) + self.assertTrue('Content-Id: ' in message.payload) + + +# class TestRecaptcha2(unittest.TestCase): +# def test_Recaptcha2(self): +# from html import FORM +# form = FORM(Recaptcha2(public_key='public_key', private_key='private_key')) +# rtn = '
    ' +# self.assertEqual(form.xml(), rtn) + +# TODO: class TestAuthJWT(unittest.TestCase): +class TestAuthJWT(unittest.TestCase): + def setUp(self): + from gluon.tools import AuthJWT + + from gluon import current + + self.request = Request(env={}) + self.request.application = 'a' + self.request.controller = 'c' + self.request.function = 'f' + self.request.folder = 'applications/admin' + self.current = current + self.current.request = self.request + + self.db = DAL(DEFAULT_URI, check_reserved=['all']) + self.auth = Auth(self.db) + self.auth.define_tables(username=True, signature=False) + self.user_data = dict(username='jwtuser', password='jwtuser123') + self.db.auth_user.insert(username=self.user_data['username'], + password=str( + self.db.auth_user.password.requires[0]( + self.user_data['password'])[0])) + self.jwtauth = AuthJWT(self.auth, secret_key='secret', verify_expiration=True) + + def test_jwt_token_manager(self): + import gluon.serializers + self.request.vars.update(self.user_data) + self.token = self.jwtauth.jwt_token_manager() + self.assertIsNotNone(self.token) + del self.request.vars['username'] + del self.request.vars['password'] + self.request.vars._token = gluon.serializers.json_parser.loads(self.token)['token'] + self.token = self.jwtauth.jwt_token_manager() + self.assertIsNotNone(self.token) + + def test_allows_jwt(self): + import gluon.serializers + self.request.vars.update(self.user_data) + self.token = self.jwtauth.jwt_token_manager() + self.assertIsNotNone(self.token) + del self.request.vars['username'] + del self.request.vars['password'] + self.token = self.jwtauth.jwt_token_manager() + self.request.vars._token = gluon.serializers.json_parser.loads(self.token)['token'] + + @self.jwtauth.allows_jwt() + def optional_auth(): + self.assertEqual(self.user_data['username'], self.auth.user.username) + optional_auth() + + +@unittest.skipIf(IS_IMAP, "TODO: Imap raises 'Connection refused'") +# class TestAuth(unittest.TestCase): +# +# def setUp(self): +# request = Request(env={}) +# request.application = 'a' +# request.controller = 'c' +# request.function = 'f' +# request.folder = 'applications/admin' +# response = Response() +# session = Session() +# T = translator('', 'en') +# session.connect(request, response) +# from gluon.globals import current +# current.request = request +# current.response = response +# current.session = session +# current.T = T +# self.db = DAL(DEFAULT_URI, check_reserved=['all']) +# self.auth = Auth(self.db) +# self.auth.define_tables(username=True, signature=False) +# self.db.define_table('t0', Field('tt'), self.auth.signature) +# self.auth.enable_record_versioning(self.db) +# # Create a user +# self.auth.get_or_create_user(dict(first_name='Bart', +# last_name='Simpson', +# username='bart', +# email='bart@simpson.com', +# password='bart_password', +# registration_key='bart', +# registration_id='' +# )) +# # self.auth.settings.registration_requires_verification = False +# # self.auth.settings.registration_requires_approval = False +# +# def test_assert_setup(self): +# self.assertEqual(self.db(self.db.auth_user.username == 'bart').select().first()['username'], 'bart') +# self.assertTrue('auth_user' in self.db) +# self.assertTrue('auth_group' in self.db) +# self.assertTrue('auth_membership' in self.db) +# self.assertTrue('auth_permission' in self.db) +# self.assertTrue('auth_event' in self.db) +# +# def test_enable_record_versioning(self): +# self.assertTrue('t0_archive' in self.db) +# +# def test_basic_blank_forms(self): +# for f in ['login', 'retrieve_password', +# 'retrieve_username', +# # 'register' # register complain about : client_side=self.settings.client_side +# ]: +# html_form = getattr(self.auth, f)().xml() +# self.assertTrue('name="_formkey"' in html_form) +# +# # NOTE: Not sure it is the proper way to logout_bare() as there is not methods for that and auth.logout() failed +# self.auth.logout_bare() +# # self.assertTrue(self.auth.is_logged_in()) +# +# for f in ['logout', 'verify_email', 'reset_password', +# 'change_password', 'profile', 'groups']: +# self.assertRaisesRegexp(HTTP, "303*", getattr(self.auth, f)) +# +# self.assertRaisesRegexp(HTTP, "401*", self.auth.impersonate) +# +# try: +# for t in ['t0_archive', 't0', 'auth_cas', 'auth_event', +# 'auth_membership', 'auth_permission', 'auth_group', +# 'auth_user']: +# self.db[t].drop() +# except SyntaxError as e: +# # GAE doesn't support drop +# pass +# return +# +# def test_get_or_create_user(self): +# self.db.auth_user.insert(email='user1@test.com', username='user1', password='password_123') +# self.db.commit() +# # True case +# self.assertEqual(self.auth.get_or_create_user({'email': 'user1@test.com', +# 'username': 'user1', +# 'password': 'password_123' +# })['username'], 'user1') +# # user2 doesn't exist yet and get created +# self.assertEqual(self.auth.get_or_create_user({'email': 'user2@test.com', +# 'username': 'user2'})['username'], 'user2') +# # user3 for corner case +# self.assertEqual(self.auth.get_or_create_user({'first_name': 'Omer', +# 'last_name': 'Simpson', +# 'email': 'user3@test.com', +# 'registration_id': 'user3', +# 'username': 'user3'})['username'], 'user3') +# # False case +# self.assertEqual(self.auth.get_or_create_user({'email': ''}), None) +# self.db.auth_user.truncate() +# self.db.commit() +# +# def test_login_bare(self): +# # The following test case should succeed but failed as I never received the user record but False +# self.auth.login_bare(username='bart@simpson.com', password='bart_password') +# self.assertTrue(self.auth.is_logged_in()) +# # Failing login because bad_password +# self.assertEqual(self.auth.login_bare(username='bart', password='wrong_password'), False) +# self.db.auth_user.truncate() +# +# def test_register_bare(self): +# # corner case empty register call register_bare without args +# self.assertRaises(ValueError, self.auth.register_bare) +# # failing register_bare user already exist +# self.assertEqual(self.auth.register_bare(username='bart', password='wrong_password'), False) +# # successful register_bare +# self.assertEqual(self.auth.register_bare(username='user2', +# email='user2@test.com', +# password='password_123')['username'], 'user2') +# # raise ValueError +# self.assertRaises(ValueError, self.auth.register_bare, +# **dict(wrong_field_name='user3', password='password_123')) +# # raise ValueError wrong email +# self.assertRaises(ValueError, self.auth.register_bare, +# **dict(email='user4@', password='password_123')) +# self.db.auth_user.truncate() +# self.db.commit() +# +# def test_bulk_register(self): +# self.auth.login_bare(username='bart', password='bart_password') +# self.auth.settings.bulk_register_enabled = True +# bulk_register_form = self.auth.bulk_register(max_emails=10).xml() +# self.assertTrue('name="_formkey"' in bulk_register_form) +# +# def test_change_password(self): +# self.auth.login_bare(username='bart', password='bart_password') +# change_password_form = getattr(self.auth, 'change_password')().xml() +# self.assertTrue('name="_formkey"' in change_password_form) +# +# def test_profile(self): +# self.auth.login_bare(username='bart', password='bart_password') +# profile_form = getattr(self.auth, 'profile')().xml() +# self.assertTrue('name="_formkey"' in profile_form) +# +# # def test_impersonate(self): +# # # Create a user to be impersonated +# # self.auth.get_or_create_user(dict(first_name='Omer', +# # last_name='Simpson', +# # username='omer', +# # email='omer@test.com', +# # password='password_omer', +# # registration_key='', +# # registration_id='')) +# # # Create impersonate group, assign bart to impersonate group and add impersonate permission over auth_user +# # self.auth.add_group('impersonate') +# # self.auth.add_membership(user_id=1, +# # group_id=self.db(self.db.auth_user.username == 'bart' +# # ).select(self.db.auth_user.id).first().id) +# # self.auth.add_permission(group_id=self.db(self.db.auth_group.role == 'impersonate' +# # ).select(self.db.auth_group.id).first().id, +# # name='impersonate', +# # table_name='auth_user', +# # record_id=0) +# # # Bart login +# # self.auth.login_bare(username='bart', password='bart_password') +# # self.assertTrue(self.auth.is_logged_in()) +# # # Bart impersonate Omer +# # omer_id = self.db(self.db.auth_user.username == 'omer').select(self.db.auth_user.id).first().id +# # impersonate_form = self.auth.impersonate(user_id=omer_id) +# # self.assertTrue(self.auth.is_impersonating()) +# # self.assertEqual(impersonate_form, 'test') +# +# # def test_impersonate(self): +# # request = Request(env={}) +# # request.application = 'a' +# # request.controller = 'c' +# # request.function = 'f' +# # request.folder = 'applications/admin' +# # response = Response() +# # session = Session() +# # T = translator('', 'en') +# # session.connect(request, response) +# # from gluon.globals import current +# # current.request = request +# # current.response = response +# # current.session = session +# # current.T = T +# # db = DAL(DEFAULT_URI, check_reserved=['all']) +# # auth = Auth(db) +# # auth.define_tables(username=True, signature=False) +# # db.define_table('t0', Field('tt'), auth.signature) +# # auth.enable_record_versioning(db) +# # # Create a user +# # auth.get_or_create_user(dict(first_name='Bart', +# # last_name='Simpson', +# # username='bart', +# # email='bart@simpson.com', +# # password='bart_password', +# # registration_key='bart', +# # registration_id='' +# # )) +# # # Create a user to be impersonated +# # auth.get_or_create_user(dict(first_name='Omer', +# # last_name='Simpson', +# # username='omer', +# # email='omer@test.com', +# # password='password_omer', +# # registration_key='', +# # registration_id='')) +# # # Create impersonate group, assign bart to impersonate group and add impersonate permission over auth_user +# # auth.add_group('impersonate') +# # auth.add_membership(user_id=1, +# # group_id=db(db.auth_user.username == 'bart' +# # ).select(db.auth_user.id).first().id) +# # auth.add_permission(group_id=db(db.auth_group.role == 'impersonate' +# # ).select(db.auth_group.id).first().id, +# # name='impersonate', +# # table_name='auth_user', +# # record_id=0) +# # # Bart login +# # auth.login_bare(username='bart', password='bart_password') +# # # Bart impersonate Omer +# # omer_id = db(db.auth_user.username == 'omer').select(db.auth_user.id).first().id +# # impersonate_form = auth.impersonate(user_id=omer_id) +# # self.assertTrue(auth.is_impersonating()) +# # self.assertEqual(impersonate_form, 'test') +class TestAuth(unittest.TestCase): + + def myassertRaisesRegex(self, *args, **kwargs): + if PY2: + return getattr(self, 'assertRaisesRegexp')(*args, **kwargs) + return getattr(self, 'assertRaisesRegex')(*args, **kwargs) + + def setUp(self): + self.request = Request(env={}) + self.request.application = 'a' + self.request.controller = 'c' + self.request.function = 'f' + self.request.folder = 'applications/admin' + self.response = Response() + self.session = Session() + T = translator('', 'en') + self.session.connect(self.request, self.response) + from gluon.globals import current + self.current = current + self.current.request = self.request + self.current.response = self.response + self.current.session = self.session + self.current.T = T + self.db = DAL(DEFAULT_URI, check_reserved=['all']) + self.auth = Auth(self.db) + self.auth.define_tables(username=True, signature=False) + self.db.define_table('t0', Field('tt'), self.auth.signature) + self.auth.enable_record_versioning(self.db) + self.auth.settings.registration_requires_verification = False + self.auth.settings.registration_requires_approval = False + # Create a user + # Note: get_or_create_user() doesn't seems to create user properly it better to use register_bare() and + # prevent login_bare() test from succeed. db insert the user manually not properly work either. + # Not working + # self.auth.get_or_create_user(dict(first_name='Bart', + # last_name='Simpson', + # username='bart', + # email='bart@simpson.com', + # password='bart_password', + # # registration_key=None, + # #registration_id='bart@simpson.com' + # ), + # login=False) + # Not working + # self.db.auth_user.insert(first_name='Bart', + # last_name='Simpson', + # username='bart', + # email='bart@simpson.com', + # password='bart_password') + # self.db.commit() + self.auth.register_bare(first_name='Bart', + last_name='Simpson', + username='bart', + email='bart@simpson.com', + password='bart_password') + + def test_assert_setup(self): + self.assertTrue('auth_user' in self.db) + self.assertTrue('auth_group' in self.db) + self.assertTrue('auth_membership' in self.db) + self.assertTrue('auth_permission' in self.db) + self.assertTrue('auth_event' in self.db) + bart_record = self.db(self.db.auth_user.username == 'bart').select().first() + self.assertEqual(bart_record['username'], 'bart') + self.assertEqual(bart_record['registration_key'], '') + bart_id = self.db(self.db.auth_user.username == 'bart').select().first().id + bart_group_id = self.db(self.db.auth_group.role == 'user_{0}'.format(bart_id)).select().first().id + self.assertTrue(self.db((self.db.auth_membership.group_id == bart_group_id) & + (self.db.auth_membership.user_id == bart_id)).select().first()) + + # Just calling many form functions + def test_basic_blank_forms(self): + for f in ['login', 'retrieve_password', 'retrieve_username', 'register']: + html_form = getattr(self.auth, f)().xml() + self.assertTrue(b'name="_formkey"' in html_form) + + for f in ['logout', 'verify_email', 'reset_password', 'change_password', 'profile', 'groups']: + self.myassertRaisesRegex(HTTP, "303*", getattr(self.auth, f)) + + self.myassertRaisesRegex(HTTP, "401*", self.auth.impersonate) + + try: + for t in ['t0_archive', 't0', 'auth_cas', 'auth_event', + 'auth_membership', 'auth_permission', 'auth_group', + 'auth_user']: + self.db[t].drop() + except SyntaxError as e: + # GAE doesn't support drop + pass + return + + def test_get_vars_next(self): + self.current.request.vars._next = 'next_test' + self.assertEqual(self.auth.get_vars_next(), 'next_test') + + # TODO: def test_navbar(self): + # TODO: def test___get_migrate(self): + + def test_enable_record_versioning(self): + self.assertTrue('t0_archive' in self.db) + + # TODO: def test_define_signature(self): + # TODO: def test_define_signature(self): + # TODO: def test_define_table(self): + + def test_log_event(self): + self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() + bart_id = self.db(self.db.auth_user.username == 'bart').select(self.db.auth_user.id).first().id + # user logged in + self.auth.log_event(description='some_log_event_description_%(var1)s', + vars={"var1": "var1"}, + origin='log_event_test_1') + rtn = self.db(self.db.auth_event.origin == 'log_event_test_1' + ).select(*[self.db.auth_event[f] + for f in self.db.auth_event.fields if f not in ('id', 'time_stamp')]).first().as_dict() + self.assertEqual(set(rtn.items()), set({'origin': 'log_event_test_1', + 'client_ip': None, + 'user_id': bart_id, + 'description': 'some_log_event_description_var1'}.items())) + # user not logged + self.auth.logout_bare() + self.auth.log_event(description='some_log_event_description_%(var2)s', + vars={"var2": "var2"}, + origin='log_event_test_2') + rtn = self.db(self.db.auth_event.origin == 'log_event_test_2' + ).select(*[self.db.auth_event[f] + for f in self.db.auth_event.fields if f not in ('id', 'time_stamp')]).first().as_dict() + self.assertEqual(set(rtn.items()), set({'origin': 'log_event_test_2', + 'client_ip': None, + 'user_id': None, + 'description': 'some_log_event_description_var2'}.items())) + # no logging tests + self.auth.settings.logging_enabled = False + count_log_event_test_before = self.db(self.db.auth_event.id > 0).count() + self.auth.log_event(description='some_log_event_description_%(var3)s', + vars={"var3": "var3"}, + origin='log_event_test_3') + count_log_event_test_after = self.db(self.db.auth_event.id > 0).count() + self.assertEqual(count_log_event_test_after, count_log_event_test_before) + self.auth.settings.logging_enabled = True + count_log_event_test_before = self.db(self.db.auth_event.id > 0).count() + self.auth.log_event(description=None, + vars={"var4": "var4"}, + origin='log_event_test_4') + count_log_event_test_after = self.db(self.db.auth_event.id > 0).count() + self.assertEqual(count_log_event_test_after, count_log_event_test_before) + # TODO: Corner case translated description... + + def test_get_or_create_user(self): + self.db.auth_user.insert(email='user1@test.com', username='user1', password='password_123') + self.db.commit() + # True case + self.assertEqual(self.auth.get_or_create_user({'email': 'user1@test.com', + 'username': 'user1', + 'password': 'password_123' + })['username'], 'user1') + # user2 doesn't exist yet and get created + self.assertEqual(self.auth.get_or_create_user({'email': 'user2@test.com', + 'username': 'user2'})['username'], 'user2') + # user3 for corner case + self.assertEqual(self.auth.get_or_create_user({'first_name': 'Omer', + 'last_name': 'Simpson', + 'email': 'user3@test.com', + 'registration_id': 'user3', + 'username': 'user3'})['username'], 'user3') + # False case + self.assertEqual(self.auth.get_or_create_user({'email': ''}), None) + self.db.auth_user.truncate() + self.db.commit() + + # TODO: def test_basic(self): + # TODO: def test_login_user(self): + # TODO: def test__get_login_settings(self): + + def test_login_bare(self): + self.auth.login_bare(username='bart', password='bart_password') + self.assertTrue(self.auth.is_logged_in()) + self.auth.logout_bare() + # Failing login because wrong_password + self.assertFalse(self.auth.login_bare(username='bart', password='wrong_password')) + # NOTE : The following failed for some reason, but I can't find out why + # self.auth = Auth(self.db) + # self.auth.define_tables(username=False, signature=False) + # self.auth.settings.registration_requires_verification = False + # self.auth.settings.registration_requires_approval = False + # self.auth.register_bare(first_name='Omer', + # last_name='Simpson', + # # no username field passed, failed with : + # # ValueError('register_bare: userfield not provided or invalid') + # # Or + # # username='omer', + # # Or + # # username='omer@simpson.com', + # # In either previous cases, it failed with : + # # self.assertTrue(self.auth.is_logged_in()) AssertionError: False is not true + # email='omer@simpson.com', + # password='omer_password') + # self.auth.login_bare(username='omer@sympson.com', password='omer_password') + # self.assertTrue(self.auth.is_logged_in()) + + def test_register_bare(self): + # corner case empty register call register_bare without args + self.assertRaises(ValueError, self.auth.register_bare) + # failing register_bare user already exist + self.assertEqual(self.auth.register_bare(username='bart', password='wrong_password'), False) + # successful register_bare + self.assertEqual(self.auth.register_bare(username='user2', + email='user2@test.com', + password='password_123')['username'], 'user2') + # raise ValueError + self.assertRaises(ValueError, self.auth.register_bare, + **dict(wrong_field_name='user3', password='password_123')) + # raise ValueError wrong email + self.assertRaises(ValueError, self.auth.register_bare, + **dict(email='user4@', password='password_123')) + self.db.auth_user.truncate() + self.db.commit() + + # TODO: def test_cas_login(self): + # TODO: def test_cas_validate(self): + # TODO: def test__reset_two_factor_auth(self): + # TODO: def test_when_is_logged_in_bypass_next_in_url(self): + # TODO: def test_login(self): + # TODO: def test_logout(self): + + def test_logout_bare(self): + self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() + self.assertTrue(self.auth.is_logged_in()) + self.auth.logout_bare() + self.assertFalse(self.auth.is_logged_in()) + + # TODO: def test_register(self): + + def test_is_logged_in(self): + self.auth.user = 'logged_in' + self.assertTrue(self.auth.is_logged_in()) + self.auth.user = None + self.assertFalse(self.auth.is_logged_in()) + + # TODO: def test_verify_email(self): + # TODO: def test_retrieve_username(self): + + def test_random_password(self): + # let just check that the function is callable + self.assertTrue(self.auth.random_password()) + + # TODO: def test_reset_password_deprecated(self): + # TODO: def test_confirm_registration(self): + # TODO: def test_email_registration(self): + + def test_bulk_register(self): + self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() + self.auth.settings.bulk_register_enabled = True + bulk_register_form = self.auth.bulk_register(max_emails=10).xml() + self.assertTrue(b'name="_formkey"' in bulk_register_form) + + # TODO: def test_manage_tokens(self): + # TODO: def test_reset_password(self): + # TODO: def test_request_reset_password(self): + # TODO: def test_email_reset_password(self): + # TODO: def test_retrieve_password(self): + + def test_change_password(self): + self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() + change_password_form = getattr(self.auth, 'change_password')().xml() + self.assertTrue(b'name="_formkey"' in change_password_form) + + def test_profile(self): + self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() + profile_form = getattr(self.auth, 'profile')().xml() + self.assertTrue(b'name="_formkey"' in profile_form) + + # TODO: def test_run_login_onaccept(self): + # TODO: def test_jwt(self): + # TODO: def test_is_impersonating(self): + + def test_impersonate(self): + # Create a user to be impersonated + self.auth.get_or_create_user(dict(first_name='Omer', + last_name='Simpson', + username='omer', + email='omer@test.com', + password='password_omer', + registration_key='', + registration_id=''), + login=False) + self.db.commit() + self.assertFalse(self.auth.is_logged_in()) + # Create impersonate group, assign bart to impersonate group and add impersonate permission over auth_user + group_id = self.auth.add_group('impersonate') + self.auth.add_membership(user_id=self.db(self.db.auth_user.username == 'bart' + ).select(self.db.auth_user.id).first().id, + group_id=group_id) + self.auth.add_permission(group_id=group_id, + name='impersonate', + table_name='auth_user', + record_id=0) + # Bart login + # self.auth.login_bare(username='bart', password='bart_password') + self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() + self.assertTrue(self.auth.is_logged_in()) + bart_id = self.db(self.db.auth_user.username == 'bart').select(self.db.auth_user.id).first().id + self.assertEqual(self.auth.user_id, bart_id) + # self.session.auth = self.auth + # self.assertTrue(self.session.auth) + + # basic impersonate() test that return a read form + self.assertEqual(self.auth.impersonate().xml(), + b'
    ') + # bart impersonate itself + self.assertEqual(self.auth.impersonate(bart_id), None) + self.assertFalse(self.auth.is_impersonating()) # User shouldn't impersonate itself? + # Bart impersonate Omer + omer_id = self.db(self.db.auth_user.username == 'omer').select(self.db.auth_user.id).first().id + impersonate_form = self.auth.impersonate(user_id=omer_id) + self.assertTrue(self.auth.is_impersonating()) + self.assertEqual(self.auth.user_id, omer_id) # we make it really sure + self.assertEqual(impersonate_form.xml(), + b'
    2
    Omer
    Simpson
    omer@test.com
    omer
    ') + self.auth.logout_bare() + # Failing impersonation + # User lacking impersonate membership + self.auth.login_user(self.db(self.db.auth_user.username == 'omer').select().first()) # bypass login_bare() + # self.assertTrue(self.auth.is_logged_in()) # For developing test + # self.assertFalse(self.auth.is_impersonating()) # For developing test + self.myassertRaisesRegex(HTTP, "403*", self.auth.impersonate, bart_id) + self.auth.logout_bare() + # Try impersonate a non existing user + self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() + # self.assertTrue(self.auth.is_logged_in()) # For developing test + # self.assertFalse(self.auth.is_impersonating()) # For developing test + self.myassertRaisesRegex(HTTP, "401*", self.auth.impersonate, 1000) # user with id 1000 shouldn't exist + # Try impersonate user with id = 0 or '0' when bart impersonating omer + self.auth.impersonate(user_id=omer_id) + self.assertTrue(self.auth.is_impersonating()) + self.assertEqual(self.auth.impersonate(user_id=0), None) + + # TODO: def test_update_groups(self): + + def test_groups(self): + self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() + self.assertEqual(self.auth.groups().xml(), + b'

    user_1(1)

    ') + + def test_not_authorized(self): + self.current.request.ajax = 'facke_ajax_request' + self.myassertRaisesRegex(HTTP, "403*", self.auth.not_authorized) + self.current.request.ajax = None + self.assertEqual(self.auth.not_authorized(), self.auth.messages.access_denied) + + def test_allows_jwt(self): + self.myassertRaisesRegex(HTTP, "400*", self.auth.allows_jwt) + + # TODO: def test_requires(self): + + # def test_login(self): + # Basic testing above in "test_basic_blank_forms()" could be refined here + + # TODO: def test_requires_login_or_token(self): + # TODO: def test_requires_membership(self): + # TODO: def test_requires_permission(self): + # TODO: def test_requires_signature(self): + + def test_add_group(self): + self.assertEqual(self.auth.add_group(role='a_group', description='a_group_role_description'), + self.db(self.db.auth_group.role == 'a_group').select(self.db.auth_group.id).first().id) + + def test_del_group(self): + bart_group_id = 1 # Should be group 1, 'user_1' + self.assertEqual(self.auth.del_group(group_id=bart_group_id), None) + + def test_id_group(self): + self.assertEqual(self.auth.id_group(role='user_1'), 1) + # If role don't exist it return None + self.assertEqual(self.auth.id_group(role='non_existing_role_name'), None) + + def test_user_group(self): + self.assertEqual(self.auth.user_group(user_id=1), 1) + # Bart should be user 1 and it unique group should be 1, 'user_1' + + def test_user_group_role(self): + self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() + user_group_role = 'user_%s' % self.db(self.db.auth_user.username == 'bart' + ).select(self.db.auth_user.id).first().id + self.assertEqual(self.auth.user_group_role(), user_group_role) + self.auth.logout_bare() + # with user_id args + self.assertEqual(self.auth.user_group_role(user_id=1), 'user_1') + # test None + self.auth.settings.create_user_groups = None + self.assertEqual(self.auth.user_group_role(user_id=1), None) + + def test_has_membership(self): + self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() + self.assertTrue(self.auth.has_membership('user_1')) + self.assertFalse(self.auth.has_membership('user_555')) + self.assertTrue(self.auth.has_membership(group_id=1)) + self.auth.logout_bare() + self.assertTrue(self.auth.has_membership(role='user_1', user_id=1)) + self.assertTrue(self.auth.has_membership(group_id=1, user_id=1)) + # check that event is logged + count_log_event_test_before = self.db(self.db.auth_event.id > 0).count() + self.assertTrue(self.auth.has_membership(group_id=1, user_id=1)) + count_log_event_test_after = self.db(self.db.auth_event.id > 0).count() + self.assertEqual(count_log_event_test_after, count_log_event_test_before) + + def test_add_membership(self): + user = self.db(self.db.auth_user.username == 'bart').select().first() # bypass login_bare() + user_id = user.id + role_name = 'test_add_membership_group' + group_id = self.auth.add_group(role_name) + self.assertFalse(self.auth.has_membership(role_name)) + + self.auth.add_membership(group_id=group_id, user_id=user_id) + self.assertTrue(self.auth.has_membership(group_id, user_id=user_id)) + self.auth.del_membership(group_id=group_id, user_id=user_id) + self.assertFalse(self.auth.has_membership(group_id, user_id=user_id)) + + self.auth.add_membership(role=role_name, user_id=user_id) + self.assertTrue(self.auth.has_membership(group_id, user_id=user_id)) + self.auth.del_membership(group_id=group_id, user_id=user_id) + self.assertFalse(self.auth.has_membership(group_id, user_id=user_id)) + + with self.myassertRaisesRegex(ValueError, '^group_id not provided or invalid$'): + self.auth.add_membership(group_id='not_existing_group_name', user_id=user_id) + with self.myassertRaisesRegex(ValueError, '^group_id not provided or invalid$'): + self.auth.add_membership(role='not_existing_role_name', user_id=user_id) + with self.myassertRaisesRegex(ValueError, '^user_id not provided or invalid$'): + self.auth.add_membership(group_id=group_id, user_id=None) + with self.myassertRaisesRegex(ValueError, '^user_id not provided or invalid$'): + self.auth.add_membership(role=role_name, user_id=None) + + self.auth.login_user(user) + + self.auth.add_membership(group_id=group_id) + self.assertTrue(self.auth.has_membership(group_id)) + self.auth.del_membership(group_id=group_id) + self.assertFalse(self.auth.has_membership(group_id)) + + self.auth.add_membership(role=role_name) + self.assertTrue(self.auth.has_membership(group_id)) + self.auth.del_membership(group_id=group_id) + self.assertFalse(self.auth.has_membership(group_id)) + + # default usage (group_id=role_name) + self.auth.add_membership(role_name) + self.assertTrue(self.auth.has_membership(group_id)) + self.auth.del_membership(group_id=group_id) + self.assertFalse(self.auth.has_membership(group_id)) + + # re-adding a membership should return the existing membership + record0_id = self.auth.add_membership(group_id) + self.assertTrue(self.auth.has_membership(group_id)) + record1_id = self.auth.add_membership(group_id) + self.assertEqual(record0_id, record1_id) + self.auth.del_membership(group_id=group_id) + self.assertFalse(self.auth.has_membership(group_id)) + + with self.myassertRaisesRegex(ValueError, '^group_id not provided or invalid$'): + self.auth.add_membership(group_id='not_existing_group_name') + with self.myassertRaisesRegex(ValueError, '^group_id not provided or invalid$'): + self.auth.add_membership(role='not_existing_role_name') + + def test_del_membership(self): + self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() + count_log_event_test_before = self.db(self.db.auth_event.id > 0).count() + user_1_role_id = self.db(self.db.auth_membership.group_id == self.auth.id_group('user_1') + ).select(self.db.auth_membership.id).first().id + self.assertEqual(self.auth.del_membership('user_1'), user_1_role_id) + count_log_event_test_after = self.db(self.db.auth_event.id > 0).count() + # check that event is logged + self.assertEqual(count_log_event_test_after, count_log_event_test_before) + # not logged in test case + group_id = self.auth.add_group('some_test_group') + membership_id = self.auth.add_membership('some_test_group') + self.assertEqual(self.auth.user_groups[group_id], 'some_test_group') + self.auth.logout_bare() + # not deleted + self.assertFalse(self.auth.del_membership('some_test_group')) + self.assertEqual(set(self.db.auth_membership(membership_id).as_dict().items()), + set({'group_id': 2, 'user_id': 1, 'id': 2}.items())) # is not deleted + # deleted + bart_id = self.db(self.db.auth_user.username == 'bart').select(self.db.auth_user.id).first().id + self.assertTrue(self.auth.del_membership('some_test_group', user_id=bart_id)) + self.assertEqual(self.db.auth_membership(membership_id), None) # is really deleted + + def test_has_permission(self): + self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() + bart_id = self.db(self.db.auth_user.username == 'bart').select(self.db.auth_user.id).first().id + self.auth.add_permission(group_id=self.auth.id_group('user_1'), + name='some_permission', + table_name='auth_user', + record_id=0, + ) + # True case + self.assertTrue(self.auth.has_permission(name='some_permission', + table_name='auth_user', + record_id=0, + user_id=bart_id, + group_id=self.auth.id_group('user_1'))) + # False case + self.assertFalse(self.auth.has_permission(name='some_other_permission', + table_name='auth_user', + record_id=0, + user_id=bart_id, + group_id=self.auth.id_group('user_1'))) + + def test_add_permission(self): + count_log_event_test_before = self.db(self.db.auth_event.id > 0).count() + permission_id = \ + self.auth.add_permission(group_id=self.auth.id_group('user_1'), + name='some_permission', + table_name='auth_user', + record_id=0, + ) + count_log_event_test_after = self.db(self.db.auth_event.id > 0).count() + # check that event is logged + self.assertEqual(count_log_event_test_after, count_log_event_test_before) + # True case + permission_count = \ + self.db(self.db.auth_permission.id == permission_id).count() + self.assertTrue(permission_count) + # False case + permission_count = \ + self.db((self.db.auth_permission.group_id == self.auth.id_group('user_1')) & + (self.db.auth_permission.name == 'no_permission') & + (self.db.auth_permission.table_name == 'no_table') & + (self.db.auth_permission.record_id == 0)).count() + self.assertFalse(permission_count) + # corner case + self.auth.login_user(self.db(self.db.auth_user.username == 'bart').select().first()) # bypass login_bare() + permission_id = \ + self.auth.add_permission(group_id=0, + name='user_1_permission', + table_name='auth_user', + record_id=0, + ) + permission_name = \ + self.db(self.db.auth_permission.id == permission_id).select(self.db.auth_permission.name).first().name + self.assertEqual(permission_name, 'user_1_permission') + # add an existing permission + permission_id =\ + self.auth.add_permission(group_id=0, + name='user_1_permission', + table_name='auth_user', + record_id=0, + ) + self.assertTrue(permission_id) + + def test_del_permission(self): + permission_id = \ + self.auth.add_permission(group_id=self.auth.id_group('user_1'), + name='del_permission_test', + table_name='auth_user', + record_id=0, + ) + count_log_event_test_before = self.db(self.db.auth_event.id > 0).count() + self.assertTrue(self.auth.del_permission(group_id=self.auth.id_group('user_1'), + name='del_permission_test', + table_name='auth_user', + record_id=0,)) + count_log_event_test_after = self.db(self.db.auth_event.id > 0).count() + # check that event is logged + self.assertEqual(count_log_event_test_after, count_log_event_test_before) + # really deleted + permission_count = \ + self.db(self.db.auth_permission.id == permission_id).count() + self.assertFalse(permission_count) + + # TODO: def test_accessible_query(self): + # TODO: def test_archive(self): + # TODO: def test_wiki(self): + # TODO: def test_wikimenu(self): + # End Auth test + + +# TODO: class TestCrud(unittest.TestCase): +# It deprecated so far from a priority + + +# TODO: class TestService(unittest.TestCase): + + +# TODO: class TestPluginManager(unittest.TestCase): + + +# TODO: class TestWiki(unittest.TestCase): + + +# TODO: class TestConfig(unittest.TestCase): + + +class TestToolsFunctions(unittest.TestCase): + """ + Test suite for all the tools.py functions + """ + def test_prettydate(self): + # plain + now = datetime.datetime.now() + self.assertEqual(prettydate(d=now), 'now') + one_second = now - datetime.timedelta(seconds=1) + self.assertEqual(prettydate(d=one_second), '1 second ago') + more_than_one_second = now - datetime.timedelta(seconds=2) + self.assertEqual(prettydate(d=more_than_one_second), '2 seconds ago') + one_minute = now - datetime.timedelta(seconds=60) + self.assertEqual(prettydate(d=one_minute), '1 minute ago') + more_than_one_minute = now - datetime.timedelta(seconds=61) + self.assertEqual(prettydate(d=more_than_one_minute), '1 minute ago') + two_minutes = now - datetime.timedelta(seconds=120) + self.assertEqual(prettydate(d=two_minutes), '2 minutes ago') + more_than_two_minutes = now - datetime.timedelta(seconds=121) + self.assertEqual(prettydate(d=more_than_two_minutes), '2 minutes ago') + one_hour = now - datetime.timedelta(seconds=60 * 60) + self.assertEqual(prettydate(d=one_hour), '1 hour ago') + more_than_one_hour = now - datetime.timedelta(seconds=3601) + self.assertEqual(prettydate(d=more_than_one_hour), '1 hour ago') + two_hours = now - datetime.timedelta(seconds=2 * 60 * 60) + self.assertEqual(prettydate(d=two_hours), '2 hours ago') + more_than_two_hours = now - datetime.timedelta(seconds=2 * 60 * 60 + 1) + self.assertEqual(prettydate(d=more_than_two_hours), '2 hours ago') + one_day = now - datetime.timedelta(days=1) + self.assertEqual(prettydate(d=one_day), '1 day ago') + more_than_one_day = now - datetime.timedelta(days=2) + self.assertEqual(prettydate(d=more_than_one_day), '2 days ago') + one_week = now - datetime.timedelta(days=7) + self.assertEqual(prettydate(d=one_week), '1 week ago') + more_than_one_week = now - datetime.timedelta(days=8) + self.assertEqual(prettydate(d=more_than_one_week), '1 week ago') + two_weeks = now - datetime.timedelta(days=14) + self.assertEqual(prettydate(d=two_weeks), '2 weeks ago') + more_than_two_weeks = now - datetime.timedelta(days=15) + self.assertEqual(prettydate(d=more_than_two_weeks), '2 weeks ago') + three_weeks = now - datetime.timedelta(days=21) + self.assertEqual(prettydate(d=three_weeks), '3 weeks ago') + one_month = now - datetime.timedelta(days=27) + self.assertEqual(prettydate(d=one_month), '1 month ago') + more_than_one_month = now - datetime.timedelta(days=28) + self.assertEqual(prettydate(d=more_than_one_month), '1 month ago') + two_months = now - datetime.timedelta(days=60) + self.assertEqual(prettydate(d=two_months), '2 months ago') + three_months = now - datetime.timedelta(days=90) + self.assertEqual(prettydate(d=three_months), '3 months ago') + one_year = now - datetime.timedelta(days=365) + self.assertEqual(prettydate(d=one_year), '1 year ago') + more_than_one_year = now - datetime.timedelta(days=366) + self.assertEqual(prettydate(d=more_than_one_year), '1 year ago') + two_years = now - datetime.timedelta(days=2 * 365) + self.assertEqual(prettydate(d=two_years), '2 years ago') + more_than_two_years = now - datetime.timedelta(days=2 * 365 + 1) + self.assertEqual(prettydate(d=more_than_two_years), '2 years ago') + # date() + d = now.date() + self.assertEqual(prettydate(d=d), 'now') + one_day = now.date() - datetime.timedelta(days=1) + self.assertEqual(prettydate(d=one_day), '1 day ago') + tow_days = now.date() - datetime.timedelta(days=2) + self.assertEqual(prettydate(d=tow_days), '2 days ago') + # from now + # from now is picky depending of the execution time, so we can't use sharp value like 1 second or 1 day + in_one_minute = now - datetime.timedelta(seconds=-65) + self.assertEqual(prettydate(d=in_one_minute), '1 minute from now') + in_twenty_three_hours = now - datetime.timedelta(hours=-23.5) + self.assertEqual(prettydate(d=in_twenty_three_hours), '23 hours from now') + in_one_year = now - datetime.timedelta(days=-366) + self.assertEqual(prettydate(d=in_one_year), '1 year from now') + # utc=True + now = datetime.datetime.utcnow() + self.assertEqual(prettydate(d=now, utc=True), 'now') + one_second = now - datetime.timedelta(seconds=1) + self.assertEqual(prettydate(d=one_second, utc=True), '1 second ago') + # not d or invalid date + self.assertEqual(prettydate(d=None), '') + self.assertEqual(prettydate(d='invalid_date'), '[invalid date]') + + +pjoin = os.path.join + + +def have_symlinks(): + return os.name == 'posix' + + +class Test_Expose__in_base(unittest.TestCase): + + def test_in_base(self): + are_under = [ + # (sub, base) + ('/foo/bar', '/foo'), + ('/foo', '/foo'), + ('/foo', '/'), + ('/', '/'), + ] + for sub, base in are_under: + self.assertTrue(Expose._Expose__in_base(subdir=sub, basedir=base, sep='/'), + '%s is not under %s' % (sub, base)) + + def test_not_in_base(self): + are_not_under = [ + # (sub, base) + ('/foobar', '/foo'), + ('/foo', '/foo/bar'), + ('/bar', '/foo'), + ('/foo/bar', '/bar'), + ('/', '/x'), + ] + for sub, base in are_not_under: + self.assertFalse(Expose._Expose__in_base(subdir=sub, basedir=base, sep='/'), + '%s should not be under %s' % (sub, base)) + + +class TestExpose(unittest.TestCase): + + def setUp(self): + self.base_dir = tempfile.mkdtemp() + + self.make_dirs() + self.touch_files() + self.make_readme() + if have_symlinks(): + self.make_symlinks() + + # $BASE/ + # |-- inside/ + # | |-- dir1/ + # | | |-- file1 + # | | `-- file2 + # | |-- dir2/ + # | | |-- link_to_dir1/@ -> $BASE/inside/dir1/ + # | | `-- link_to_file1@ -> $BASE/inside/dir1/file1 + # | |-- link_to_outside/@ -> $BASE/outside/ + # | |-- link_to_file3@ -> $BASE/outside/file3 + # | `-- README + # `-- outside/ + # `-- file3 + + self.set_expectations() + tools.URL = lambda args: URL(a='a', c='c', f='f', args=args) + + def tearDown(self): + tools.URL = URL + shutil.rmtree(self.base_dir) + + def make_dirs(self): + """setup directory structure""" + for d in (['inside'], + ['inside', 'dir1'], + ['inside', 'dir2'], + ['outside']): + os.mkdir(pjoin(self.base_dir, *d)) + + def touch_files(self): + """create some files""" + for f in (['inside', 'dir1', 'file1'], + ['inside', 'dir1', 'file2'], + ['outside', 'file3']): + with open(pjoin(self.base_dir, *f), 'a'): + pass + + def make_readme(self): + with open(pjoin(self.base_dir, 'inside', 'README'), 'w') as f: + f.write('README content') + + def make_symlinks(self): + """setup extension for posix systems""" + # inside links + os.symlink( + pjoin(self.base_dir, 'inside', 'dir1'), + pjoin(self.base_dir, 'inside', 'dir2', 'link_to_dir1')) + os.symlink( + pjoin(self.base_dir, 'inside', 'dir1', 'file1'), + pjoin(self.base_dir, 'inside', 'dir2', 'link_to_file1')) + # outside links + os.symlink( + pjoin(self.base_dir, 'outside'), + pjoin(self.base_dir, 'inside', 'link_to_outside')) + os.symlink( + pjoin(self.base_dir, 'outside', 'file3'), + pjoin(self.base_dir, 'inside', 'link_to_file3')) + + def set_expectations(self): + url = lambda args: URL('a', 'c', 'f', args=args) + + self.expected_folders = {} + self.expected_folders['inside'] = SPAN(H3('Folders'), TABLE( + TR(TD(A('dir1', _href=url(args=['dir1'])))), + TR(TD(A('dir2', _href=url(args=['dir2'])))), + _class='table', + )) + self.expected_folders[pjoin('inside', 'dir1')] = '' + if have_symlinks(): + self.expected_folders[pjoin('inside', 'dir2')] = SPAN(H3('Folders'), TABLE( + TR(TD(A('link_to_dir1', _href=url(args=['dir2', 'link_to_dir1'])))), + _class='table', + )) + else: + self.expected_folders[pjoin('inside', 'dir2')] = '' + + self.expected_files = {} + self.expected_files['inside'] = SPAN(H3('Files'), TABLE( + TR(TD(A('README', _href=url(args=['README']))), TD('')), + _class='table', + )) + self.expected_files[pjoin('inside', 'dir1')] = SPAN(H3('Files'), TABLE( + TR(TD(A('file1', _href=url(args=['dir1', 'file1']))), TD('')), + TR(TD(A('file2', _href=url(args=['dir1', 'file2']))), TD('')), + _class='table', + )) + if have_symlinks(): + self.expected_files[pjoin('inside', 'dir2')] = SPAN(H3('Files'), TABLE( + TR(TD(A('link_to_file1', _href=url(args=['dir2', 'link_to_file1']))), TD('')), + _class='table', + )) + else: + self.expected_files[pjoin('inside', 'dir2')] = '' + + def make_expose(self, base, show='', follow_symlink_out=False): + current.request = Request(env={}) + current.request.raw_args = show + current.request.args = show.split('/') + return Expose(base=pjoin(self.base_dir, base), + basename=base, + follow_symlink_out=follow_symlink_out) + + def test_expose_inside_state(self): + expose = self.make_expose(base='inside', show='') + self.assertEqual(expose.args, []) + self.assertEqual(expose.folders, ['dir1', 'dir2']) + self.assertEqual(expose.filenames, ['README']) + + @unittest.skipUnless(have_symlinks(), 'requires symlinks') + def test_expose_inside_state_floow_symlink_out(self): + expose = self.make_expose(base='inside', show='', + follow_symlink_out=True) + self.assertEqual(expose.args, []) + self.assertEqual(expose.folders, ['dir1', 'dir2', 'link_to_outside']) + self.assertEqual(expose.filenames, ['README', 'link_to_file3']) + + def test_expose_inside_dir1_state(self): + expose = self.make_expose(base='inside', show='dir1') + self.assertEqual(expose.args, ['dir1']) + self.assertEqual(expose.folders, []) + self.assertEqual(expose.filenames, ['file1', 'file2']) + + def test_expose_inside_dir2_state(self): + expose = self.make_expose(base='inside', show='dir2') + self.assertEqual(expose.args, ['dir2']) + if have_symlinks(): + self.assertEqual(expose.folders, ['link_to_dir1']) + self.assertEqual(expose.filenames, ['link_to_file1']) + else: + self.assertEqual(expose.folders, []) + self.assertEqual(expose.filenames, []) + + def test_expose_base_inside_state(self): + expose = self.make_expose(base='', show='inside') + self.assertEqual(expose.args, ['inside']) + if have_symlinks(): + self.assertEqual(expose.folders, ['dir1', 'dir2', 'link_to_outside']) + self.assertEqual(expose.filenames, ['README', 'link_to_file3']) + else: + self.assertEqual(expose.folders, ['dir1', 'dir2']) + self.assertEqual(expose.filenames, ['README']) + + def test_expose_base_inside_dir2_state(self): + expose = self.make_expose(base='', show='inside/dir2') + self.assertEqual(expose.args, ['inside', 'dir2']) + if have_symlinks(): + self.assertEqual(expose.folders, ['link_to_dir1']) + self.assertEqual(expose.filenames, ['link_to_file1']) + else: + self.assertEqual(expose.folders, []) + self.assertEqual(expose.filenames, []) + + def assertSameXML(self, a, b): + self.assertEqual(a if isinstance(a, str) else a.xml(), + b if isinstance(b, str) else b.xml()) + + def run_test_xml_for(self, base, show): + expose = self.make_expose(base, show) + path = pjoin(base, show).rstrip(os.path.sep) + request = Request(env={}) + self.assertSameXML(expose.table_files(), self.expected_files[path]) + self.assertSameXML(expose.table_folders(), self.expected_folders[path]) + + def test_xml_inside(self): + self.run_test_xml_for(base='inside', show='') + + def test_xml_dir1(self): + self.run_test_xml_for(base='inside', show='dir1') + + def test_xml_dir2(self): + self.run_test_xml_for(base='inside', show='dir2') + + def test_file_not_found(self): + with self.assertRaises(HTTP): + self.make_expose(base='inside', show='dir1/file_not_found') + + def test_not_authorized(self): + with self.assertRaises(HTTP): + self.make_expose(base='inside', show='link_to_file3') + diff --git a/web2py/gluon/tests/test_utils.py b/web2py/gluon/tests/test_utils.py new file mode 100644 index 0000000..8b94844 --- /dev/null +++ b/web2py/gluon/tests/test_utils.py @@ -0,0 +1,179 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" Unit tests for utils.py """ + +import unittest +import pickle +from hashlib import md5 + +from gluon.utils import md5_hash, compare, is_valid_ip_address, web2py_uuid +import gluon.utils +from gluon.utils import simple_hash, get_digest, secure_dumps, secure_loads + + +class TestUtils(unittest.TestCase): + """ Tests the utils.py module """ + + # TODO: def test_AES_new(self): + + def test_compare(self): + """ Tests the compare funciton """ + + a, b = 'test123', 'test123' + compare_result_true = compare(a, b) + self.assertTrue(compare_result_true) + + a, b = 'test123', 'test456' + compare_result_false = compare(a, b) + self.assertFalse(compare_result_false) + + def test_md5_hash(self): + """ Tests the md5_hash function """ + + data = md5_hash("web2py rocks") + self.assertEqual(data, '79509f3246a2824dee64635303e99204') + + def test_simple_hash(self): + """ Tests the simple_hash function """ + + # no key, no salt, digest_alg=None + self.assertRaises(RuntimeError, simple_hash, 'web2py rocks!', key='', salt='', digest_alg=None) + + # no key, no salt, digest_alg = md5 + data_md5 = simple_hash('web2py rocks!', key='', salt='', digest_alg=md5) + self.assertEqual(data_md5, '37d95defba6c8834cb8cae86ee888568') + + # no key, no salt, 'md5' + data_md5 = simple_hash('web2py rocks!', key='', salt='', digest_alg='md5') + self.assertEqual(data_md5, '37d95defba6c8834cb8cae86ee888568') + + # no key, no salt, 'sha1' + data_sha1 = simple_hash('web2py rocks!', key='', salt='', digest_alg='sha1') + self.assertEqual(data_sha1, '00489a46753d8db260c71542611cdef80652c4b7') + + # no key, no salt, 'sha224' + data_sha224 = simple_hash('web2py rocks!', key='', salt='', digest_alg='sha224') + self.assertEqual(data_sha224, '84d7054271842c2c17983baa2b1447e0289d101140a8c002d49d60da') + + # no key, no salt, 'sha256' + data_sha256 = simple_hash('web2py rocks!', key='', salt='', digest_alg='sha256') + self.assertEqual(data_sha256, '0849f224d8deb267e4598702aaec1bd749e6caec90832469891012a4be24af08') + + # no key, no salt, 'sha384' + data_sha384 = simple_hash('web2py rocks!', key='', salt='', digest_alg='sha384') + self.assertEqual(data_sha384, + '3cffaf39371adbe84eb10f588d2718207d8e965e9172a27a278321b86977351376ae79f92e91d8c58cad86c491282d5f') + + # no key, no salt, 'sha512' + data_sha512 = simple_hash('web2py rocks!', key='', salt='', digest_alg='sha512') + self.assertEqual(data_sha512, 'fa3237f594743e1d7b6c800bb134b3255cf4a98ab8b01e2ec23256328c9f8059' + '64fdef25a038d6cc3fda1b2fb45d66461eeed5c4669e506ec8bdfee71348db7e') + + # NOTE : get_digest() is covered by simple_hash tests above except raise error... + def test_get_digest(self): + # Bad algorithm + # Option 1, think not working with python 2.6 + # with self.assertRaises(ValueError) as cm: + # get_digest('123') + # self.assertEqual(cm.exception[0], 'Invalid digest algorithm: 123') + # Option 2 + self.assertRaises(ValueError, get_digest, '123') + + # TODO: def test_get_callable_argspec(self): + + def test_pad(self): + test_cases = [ + (16, b'mydata'), # verify data padding and unpad identity + (32, b'mydata '), # verify space is not stripped + (8, b'mydata\x01'), # verify "padding" bytes are ignored + (4, b'mydata'), # verify multiblock behavior + (2, b''), # verify empty string behavior + ] + for (testlen,teststr) in test_cases: + padded = gluon.utils.pad(teststr,testlen) + unpadded = gluon.utils.unpad(padded,testlen) + self.assertTrue(len(padded) > len(teststr)) + self.assertTrue(len(padded)%testlen == 0) + self.assertEqual(teststr, unpadded) + + testobj = {'a': 1, 'b': 2} + pickled = pickle.dumps(testobj) + padded = gluon.utils.pad(pickled) + unpadded = gluon.utils.unpad(padded) + unpickled = pickle.loads(unpadded) + self.assertEqual(pickled, unpadded) + self.assertEqual(testobj, unpickled) + self.assertTrue(len(padded) > len(pickled)) + self.assertTrue(len(padded)%32==0) + + def test_secure_dumps_and_loads(self): + """ Tests secure_dumps and secure_loads""" + testobj = {'a': 1, 'b': 2} + testkey = 'mysecret' + secured = secure_dumps(testobj, testkey) + original = secure_loads(secured, testkey) + self.assertEqual(testobj, original) + self.assertTrue(isinstance(secured, bytes)) + self.assertTrue(secured.count(b':') == 2) + + secured_deprecated = gluon.utils.secure_dumps_deprecated(testobj, testkey) + original_deprecated = secure_loads(secured_deprecated, testkey) + self.assertEqual(testobj, original_deprecated) + self.assertTrue(isinstance(secured_deprecated, bytes)) + self.assertTrue(secured_deprecated.count(b':') == 1) + + large_testobj = [x for x in range(1000)] + secured_comp = secure_dumps(large_testobj, testkey, compression_level=9) + original_comp = secure_loads(secured_comp, testkey, compression_level=9) + self.assertEqual(large_testobj, original_comp) + secured = secure_dumps(large_testobj, testkey) + self.assertTrue(len(secured_comp) < len(secured)) + + testhash = 'myhash' + secured = secure_dumps(testobj, testkey, testhash) + original = secure_loads(secured, testkey, testhash) + self.assertEqual(testobj, original) + + wrong1 = secure_loads(secured, testkey, 'wronghash') + self.assertEqual(wrong1, None) + wrong2 = secure_loads(secured, 'wrongkey', testhash) + self.assertEqual(wrong2, None) + wrong3 = secure_loads(secured, 'wrongkey', 'wronghash') + self.assertEqual(wrong3, None) + wrong4 = secure_loads(b'abc', 'a', 'b') + self.assertEqual(wrong4, None) + + # TODO: def test_initialize_urandom(self): + + # TODO: def test_fast_urandom16(self): + + def test_web2py_uuid(self): + from uuid import UUID + self.assertTrue(UUID(web2py_uuid())) + + def test_is_valid_ip_address(self): + # IPv4 + # False + # self.assertEqual(is_valid_ip_address('127.0'), False) # Fail with AppVeyor?? should pass + self.assertEqual(is_valid_ip_address('unknown'), False) + self.assertEqual(is_valid_ip_address(''), False) + # True + self.assertEqual(is_valid_ip_address('127.0.0.1'), True) + self.assertEqual(is_valid_ip_address('localhost'), True) + self.assertEqual(is_valid_ip_address('::1'), True) + # IPv6 + # True + # Compressed + self.assertEqual(is_valid_ip_address('::ffff:7f00:1'), True) # IPv6 127.0.0.1 compressed + self.assertEqual(is_valid_ip_address('2001:660::1'), True) + # Expanded + self.assertEqual(is_valid_ip_address('0:0:0:0:0:ffff:7f00:1'), True) # IPv6 127.0.0.1 expanded + self.assertEqual(is_valid_ip_address('2607:fa48:6d50:69f1:21f:3cff:fe9d:9be3'), True) # Any address + # False + # self.assertEqual(is_valid_ip_address('2607:fa48:6d50:69f1:21f:3cff:fe9d:'), False) # Any address with mistake + # The above pass locally but fail with AppVeyor + + # TODO: def test_is_loopback_ip_address(self): + + # TODO: def test_getipaddrinfo(self): diff --git a/web2py/gluon/tests/test_validators.py b/web2py/gluon/tests/test_validators.py new file mode 100644 index 0000000..7371266 --- /dev/null +++ b/web2py/gluon/tests/test_validators.py @@ -0,0 +1,1199 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""Unit tests for http.py """ + +import unittest +import datetime +import decimal +import re + +from gluon.validators import * +from gluon._compat import PY2, to_bytes + +class TestValidators(unittest.TestCase): + + def myassertRegex(self, *args, **kwargs): + if PY2: + return getattr(self, 'assertRegexpMatches')(*args, **kwargs) + return getattr(self, 'assertRegex')(*args, **kwargs) + + def test_MISC(self): + """ Test miscelaneous utility functions and some general behavior guarantees """ + from gluon.validators import translate, options_sorter, Validator, UTC + self.assertEqual(translate(None), None) + self.assertEqual(options_sorter(('a', 'a'), ('a', 'a')), -1) + self.assertEqual(options_sorter(('A', 'A'), ('a', 'a')), -1) + self.assertEqual(options_sorter(('b', 'b'), ('a', 'a')), 1) + self.assertRaises(NotImplementedError, Validator(), 1) + utc = UTC() + dt = datetime.datetime.now() + self.assertEqual(utc.utcoffset(dt), UTC.ZERO) + self.assertEqual(utc.dst(dt), UTC.ZERO) + self.assertEqual(utc.tzname(dt), 'UTC') + + def test_IS_MATCH(self): + rtn = IS_MATCH('.+')('hello') + self.assertEqual(rtn, ('hello', None)) + rtn = IS_MATCH('hell')('hello') + self.assertEqual(rtn, ('hello', None)) + rtn = IS_MATCH('hell.*', strict=False)('hello') + self.assertEqual(rtn, ('hello', None)) + rtn = IS_MATCH('hello')('shello') + self.assertEqual(rtn, ('shello', 'Invalid expression')) + rtn = IS_MATCH('hello', search=True)('shello') + self.assertEqual(rtn, ('shello', None)) + rtn = IS_MATCH('hello', search=True, strict=False)('shellox') + self.assertEqual(rtn, ('shellox', None)) + rtn = IS_MATCH('.*hello.*', search=True, strict=False)('shellox') + self.assertEqual(rtn, ('shellox', None)) + rtn = IS_MATCH('.+')('') + self.assertEqual(rtn, ('', 'Invalid expression')) + rtn = IS_MATCH('hell', strict=True)('hellas') + self.assertEqual(rtn, ('hellas', 'Invalid expression')) + rtn = IS_MATCH('hell$', strict=True)('hellas') + self.assertEqual(rtn, ('hellas', 'Invalid expression')) + rtn = IS_MATCH('^.hell$', strict=True)('shell') + self.assertEqual(rtn, ('shell', None)) + rtn = IS_MATCH(u'hell', is_unicode=True)('àòè') + if PY2: + self.assertEqual(rtn, ('\xc3\xa0\xc3\xb2\xc3\xa8', 'Invalid expression')) + else: + self.assertEqual(rtn, ('àòè', 'Invalid expression')) + rtn = IS_MATCH(u'hell', is_unicode=True)(u'hell') + self.assertEqual(rtn, (u'hell', None)) + rtn = IS_MATCH('hell', is_unicode=True)(u'hell') + self.assertEqual(rtn, (u'hell', None)) + # regr test for #1044 + rtn = IS_MATCH('hello')(u'\xff') + self.assertEqual(rtn, (u'\xff', 'Invalid expression')) + + def test_IS_EQUAL_TO(self): + rtn = IS_EQUAL_TO('aaa')('aaa') + self.assertEqual(rtn, ('aaa', None)) + rtn = IS_EQUAL_TO('aaa')('aab') + self.assertEqual(rtn, ('aab', 'No match')) + + def test_IS_EXPR(self): + rtn = IS_EXPR('int(value) < 2')('1') + self.assertEqual(rtn, ('1', None)) + rtn = IS_EXPR('int(value) < 2')('2') + self.assertEqual(rtn, ('2', 'Invalid expression')) + rtn = IS_EXPR(lambda value: int(value))('1') + self.assertEqual(rtn, ('1', 1)) + rtn = IS_EXPR(lambda value: int(value) < 2 and 'invalid' or None)('2') + self.assertEqual(rtn, ('2', None)) + + def test_IS_LENGTH(self): + rtn = IS_LENGTH()('') + self.assertEqual(rtn, ('', None)) + rtn = IS_LENGTH()('1234567890') + self.assertEqual(rtn, ('1234567890', None)) + rtn = IS_LENGTH(maxsize=5, minsize=0)('1234567890') # too long + self.assertEqual(rtn, ('1234567890', 'Enter from 0 to 5 characters')) + rtn = IS_LENGTH(maxsize=50, minsize=20)('1234567890') # too short + self.assertEqual(rtn, ('1234567890', 'Enter from 20 to 50 characters')) + rtn = IS_LENGTH()(None) + self.assertEqual(rtn, (None, None)) + rtn = IS_LENGTH(minsize=0)(None) + self.assertEqual(rtn, (None, None)) + rtn = IS_LENGTH(minsize=1)(None) + self.assertEqual(rtn, (None, 'Enter from 1 to 255 characters')) + rtn = IS_LENGTH(minsize=1)([]) + self.assertEqual(rtn, ([], 'Enter from 1 to 255 characters')) + rtn = IS_LENGTH(minsize=1)([1, 2]) + self.assertEqual(rtn, ([1, 2], None)) + rtn = IS_LENGTH(minsize=1)([1]) + self.assertEqual(rtn, ([1], None)) + # test non utf-8 str + cpstr = u'lálá'.encode('cp1252') + rtn = IS_LENGTH(minsize=4)(cpstr) + self.assertEqual(rtn, (cpstr, None)) + rtn = IS_LENGTH(maxsize=4)(cpstr) + self.assertEqual(rtn, (cpstr, None)) + rtn = IS_LENGTH(minsize=0, maxsize=3)(cpstr) + self.assertEqual(rtn, (cpstr, 'Enter from 0 to 3 characters')) + # test unicode + rtn = IS_LENGTH(2)(u'°2') + if PY2: + self.assertEqual(rtn, ('\xc2\xb02', None)) + else: + self.assertEqual(rtn, (u'°2', None)) + rtn = IS_LENGTH(2)(u'°12') + if PY2: + self.assertEqual(rtn, (u'\xb012', 'Enter from 0 to 2 characters')) + else: + self.assertEqual(rtn, (u'°12', 'Enter from 0 to 2 characters')) + # test automatic str() + rtn = IS_LENGTH(minsize=1)(1) + self.assertEqual(rtn, ('1', None)) + rtn = IS_LENGTH(minsize=2)(1) + self.assertEqual(rtn, (1, 'Enter from 2 to 255 characters')) + # test FieldStorage + import cgi + from io import BytesIO + a = cgi.FieldStorage() + a.file = BytesIO(b'abc') + rtn = IS_LENGTH(minsize=4)(a) + self.assertEqual(rtn, (a, 'Enter from 4 to 255 characters')) + urlencode_data = b"key2=value2x&key3=value3&key4=value4" + urlencode_environ = { + 'CONTENT_LENGTH': str(len(urlencode_data)), + 'CONTENT_TYPE': 'application/x-www-form-urlencoded', + 'QUERY_STRING': 'key1=value1&key2=value2y', + 'REQUEST_METHOD': 'POST', + } + fake_stdin = BytesIO(urlencode_data) + fake_stdin.seek(0) + a = cgi.FieldStorage(fp=fake_stdin, environ=urlencode_environ) + rtn = IS_LENGTH(minsize=6)(a) + self.assertEqual(rtn, (a, 'Enter from 6 to 255 characters')) + a = cgi.FieldStorage() + rtn = IS_LENGTH(minsize=6)(a) + self.assertEqual(rtn, (a, 'Enter from 6 to 255 characters')) + rtn = IS_LENGTH(6)(a) + self.assertEqual(rtn, (a, None)) + + def test_IS_JSON(self): + rtn = IS_JSON()('{"a": 100}') + self.assertEqual(rtn, ({u'a': 100}, None)) + rtn = IS_JSON()('spam1234') + self.assertEqual(rtn, ('spam1234', 'Invalid json')) + rtn = IS_JSON(native_json=True)('{"a": 100}') + self.assertEqual(rtn, ('{"a": 100}', None)) + rtn = IS_JSON().formatter(None) + self.assertEqual(rtn, None) + rtn = IS_JSON().formatter({'a': 100}) + self.assertEqual(rtn, '{"a": 100}') + rtn = IS_JSON(native_json=True).formatter({'a': 100}) + self.assertEqual(rtn, {'a': 100}) + + def test_IS_IN_SET(self): + rtn = IS_IN_SET(['max', 'john'])('max') + self.assertEqual(rtn, ('max', None)) + rtn = IS_IN_SET(['max', 'john'])('massimo') + self.assertEqual(rtn, ('massimo', 'Value not allowed')) + rtn = IS_IN_SET(['max', 'john'], multiple=True)(('max', 'john')) + self.assertEqual(rtn, (('max', 'john'), None)) + rtn = IS_IN_SET(['max', 'john'], multiple=True)(('bill', 'john')) + self.assertEqual(rtn, (('bill', 'john'), 'Value not allowed')) + rtn = IS_IN_SET(('id1', 'id2'), ['first label', 'second label'])('id1') # Traditional way + self.assertEqual(rtn, ('id1', None)) + rtn = IS_IN_SET({'id1': 'first label', 'id2': 'second label'})('id1') + self.assertEqual(rtn, ('id1', None)) + rtn = IS_IN_SET(['id1', 'id2'], error_message='oops', multiple=True)(None) + self.assertEqual(rtn, ([], None)) + rtn = IS_IN_SET(['id1', 'id2'], error_message='oops', multiple=True)('') + self.assertEqual(rtn, ([], None)) + rtn = IS_IN_SET(['id1', 'id2'], error_message='oops', multiple=True)('id1') + self.assertEqual(rtn, (['id1'], None)) + rtn = IS_IN_SET(['id1', 'id2'], error_message='oops', multiple=(1, 2))(None) + self.assertEqual(rtn, ([], 'oops')) + import itertools + rtn = IS_IN_SET(itertools.chain(['1', '3', '5'], ['2', '4', '6']))('1') + self.assertEqual(rtn, ('1', None)) + rtn = IS_IN_SET([('id1', 'first label'), ('id2', 'second label')])('id1') # Redundant way + self.assertEqual(rtn, ('id1', None)) + rtn = IS_IN_SET([('id1', 'first label'), ('id2', 'second label')]).options(zero=False) + self.assertEqual(rtn, [('id1', 'first label'), ('id2', 'second label')]) + rtn = IS_IN_SET(['id1', 'id2']).options(zero=False) + self.assertEqual(rtn, [('id1', 'id1'), ('id2', 'id2')]) + rtn = IS_IN_SET(['id2', 'id1'], sort=True).options(zero=False) + self.assertEqual(rtn, [('id1', 'id1'), ('id2', 'id2')]) + + def test_IS_IN_DB(self): + from gluon.dal import DAL, Field + db = DAL('sqlite:memory') + db.define_table('person', Field('name')) + george_id = db.person.insert(name='george') + costanza_id = db.person.insert(name='costanza') + rtn = IS_IN_DB(db, 'person.id', '%(name)s')(george_id) + self.assertEqual(rtn, (george_id, None)) + rtn = IS_IN_DB(db, 'person.name', '%(name)s')('george') + self.assertEqual(rtn, ('george', None)) + rtn = IS_IN_DB(db, db.person, '%(name)s')(george_id) + self.assertEqual(rtn, (george_id, None)) + rtn = IS_IN_DB(db(db.person.id > 0), db.person, '%(name)s')(george_id) + self.assertEqual(rtn, (george_id, None)) + rtn = IS_IN_DB(db, 'person.id', '%(name)s', error_message='oops')(george_id + costanza_id) + self.assertEqual(rtn, (george_id + costanza_id, 'oops')) + rtn = IS_IN_DB(db, db.person.id, '%(name)s')(george_id) + self.assertEqual(rtn, (george_id, None)) + rtn = IS_IN_DB(db, db.person.id, '%(name)s', error_message='oops')(george_id + costanza_id) + self.assertEqual(rtn, (george_id + costanza_id, 'oops')) + rtn = IS_IN_DB(db, 'person.id', '%(name)s', multiple=True)([george_id, costanza_id]) + self.assertEqual(rtn, ([george_id, costanza_id], None)) + rtn = IS_IN_DB(db, 'person.id', '%(name)s', multiple=True, error_message='oops')("I'm not even an id") + self.assertEqual(rtn, (["I'm not even an id"], 'oops')) + rtn = IS_IN_DB(db, 'person.id', '%(name)s', multiple=True, delimiter=',')('%d,%d' % (george_id, costanza_id)) + self.assertEqual(rtn, (('%d,%d' % (george_id, costanza_id)).split(','), None)) + rtn = IS_IN_DB(db, 'person.id', '%(name)s', multiple=(1, 3), delimiter=',')('%d,%d' % (george_id, costanza_id)) + self.assertEqual(rtn, (('%d,%d' % (george_id, costanza_id)).split(','), None)) + rtn = IS_IN_DB(db, 'person.id', '%(name)s', multiple=(1, 2), delimiter=',', error_message='oops')('%d,%d' % (george_id, costanza_id)) + self.assertEqual(rtn, (('%d,%d' % (george_id, costanza_id)).split(','), 'oops')) + rtn = IS_IN_DB(db, db.person.id, '%(name)s', error_message='oops').options(zero=False) + self.assertEqual(sorted(rtn), [('%d' % george_id, 'george'), ('%d' % costanza_id, 'costanza')]) + rtn = IS_IN_DB(db, db.person.id, db.person.name, error_message='oops', sort=True).options(zero=True) + self.assertEqual(rtn, [('', ''), ('%d' % costanza_id, 'costanza'), ('%d' % george_id, 'george')]) + # Test None + rtn = IS_IN_DB(db, 'person.id', '%(name)s', error_message='oops')(None) + self.assertEqual(rtn, (None, 'oops')) + rtn = IS_IN_DB(db, 'person.name', '%(name)s', error_message='oops')(None) + self.assertEqual(rtn, (None, 'oops')) + # Test using the set it made for options + vldtr = IS_IN_DB(db, 'person.name', '%(name)s', error_message='oops') + vldtr.options() + rtn = vldtr('george') + self.assertEqual(rtn, ('george', None)) + rtn = vldtr('jerry') + self.assertEqual(rtn, ('jerry', 'oops')) + vldtr = IS_IN_DB(db, 'person.name', '%(name)s', error_message='oops', multiple=True) + vldtr.options() + rtn = vldtr(['george', 'costanza']) + self.assertEqual(rtn, (['george', 'costanza'], None)) + # Test it works with self reference + db.define_table('category', + Field('parent_id', 'reference category', requires=IS_EMPTY_OR(IS_IN_DB(db, 'category.id', '%(name)s'))), + Field('name') + ) + ret = db.category.validate_and_insert(name='seinfeld') + self.assertFalse(list(ret.errors)) + ret = db.category.validate_and_insert(name='characters', parent_id=ret.id) + self.assertFalse(list(ret.errors)) + rtn = IS_IN_DB(db, 'category.id', '%(name)s')(ret.id) + self.assertEqual(rtn, (ret.id, None)) + # Test _and + vldtr = IS_IN_DB(db, 'person.name', '%(name)s', error_message='oops', _and=IS_LENGTH(maxsize=7, error_message='bad')) + rtn = vldtr('george') + self.assertEqual(rtn, ('george', None)) + rtn = vldtr('costanza') + self.assertEqual(rtn, ('costanza', 'bad')) + rtn = vldtr('jerry') + self.assertEqual(rtn, ('jerry', 'oops')) + vldtr.options() # test theset with _and + rtn = vldtr('jerry') + self.assertEqual(rtn, ('jerry', 'oops')) + # Test auto_add + rtn = IS_IN_DB(db, 'person.id', '%(name)s', error_message='oops')('jerry') + self.assertEqual(rtn, ('jerry', 'oops')) + rtn = IS_IN_DB(db, 'person.id', '%(name)s', auto_add=True)('jerry') + self.assertEqual(rtn, (3, None)) + # Test it works with reference table + db.define_table('ref_table', + Field('name'), + Field('person_id', 'reference person') + ) + ret = db.ref_table.validate_and_insert(name='test reference table') + self.assertFalse(list(ret.errors)) + ret = db.ref_table.validate_and_insert(name='test reference table', person_id=george_id) + self.assertFalse(list(ret.errors)) + rtn = IS_IN_DB(db, 'ref_table.person_id', '%(name)s')(george_id) + self.assertEqual(rtn, (george_id, None)) + # Test it works with reference table.field and keyed table + db.define_table('person_keyed', + Field('name'), + primarykey=['name']) + db.person_keyed.insert(name='george') + db.person_keyed.insert(name='costanza') + rtn = IS_IN_DB(db, 'person_keyed.name')('george') + self.assertEqual(rtn, ('george', None)) + db.define_table('ref_table_field', + Field('name'), + Field('person_name', 'reference person_keyed.name') + ) + ret = db.ref_table_field.validate_and_insert(name='test reference table.field') + self.assertFalse(list(ret.errors)) + ret = db.ref_table_field.validate_and_insert(name='test reference table.field', person_name='george') + self.assertFalse(list(ret.errors)) + vldtr = IS_IN_DB(db, 'ref_table_field.person_name', '%(name)s') + vldtr.options() + rtn = vldtr('george') + self.assertEqual(rtn, ('george', None)) + # Test it works with list:reference table + db.define_table('list_ref_table', + Field('name'), + Field('person_list', 'list:reference person')) + ret = db.list_ref_table.validate_and_insert(name='test list:reference table') + self.assertFalse(list(ret.errors)) + ret = db.list_ref_table.validate_and_insert(name='test list:reference table', person_list=[george_id,costanza_id]) + self.assertFalse(list(ret.errors)) + vldtr = IS_IN_DB(db, 'list_ref_table.person_list') + vldtr.options() + rtn = vldtr([george_id,costanza_id]) + self.assertEqual(rtn, ([george_id,costanza_id], None)) + # Test it works with list:reference table.field and keyed table + #db.define_table('list_ref_table_field', + # Field('name'), + # Field('person_list', 'list:reference person_keyed.name')) + #ret = db.list_ref_table_field.validate_and_insert(name='test list:reference table.field') + #self.assertFalse(list(ret.errors)) + #ret = db.list_ref_table_field.validate_and_insert(name='test list:reference table.field', person_list=['george','costanza']) + #self.assertFalse(list(ret.errors)) + #vldtr = IS_IN_DB(db, 'list_ref_table_field.person_list') + #vldtr.options() + #rtn = vldtr(['george','costanza']) + #self.assertEqual(rtn, (['george','costanza'], None)) + db.person.drop() + db.category.drop() + db.person_keyed.drop() + db.ref_table.drop() + db.ref_table_field.drop() + db.list_ref_table.drop() + #db.list_ref_table_field.drop() + + def test_IS_NOT_IN_DB(self): + from gluon.dal import DAL, Field + db = DAL('sqlite:memory') + db.define_table('person', Field('name'), Field('nickname')) + db.person.insert(name='george') + db.person.insert(name='costanza', nickname='T Bone') + rtn = IS_NOT_IN_DB(db, 'person.name', error_message='oops')('george') + self.assertEqual(rtn, ('george', 'oops')) + rtn = IS_NOT_IN_DB(db, 'person.name', error_message='oops', allowed_override=['george'])('george') + self.assertEqual(rtn, ('george', None)) + rtn = IS_NOT_IN_DB(db, 'person.name', error_message='oops')(' ') + self.assertEqual(rtn, (' ', 'oops')) + rtn = IS_NOT_IN_DB(db, 'person.name')('jerry') + self.assertEqual(rtn, ('jerry', None)) + rtn = IS_NOT_IN_DB(db, 'person.name')(u'jerry') + self.assertEqual(rtn, ('jerry', None)) + rtn = IS_NOT_IN_DB(db(db.person.id > 0), 'person.name')(u'jerry') + self.assertEqual(rtn, ('jerry', None)) + rtn = IS_NOT_IN_DB(db, db.person, error_message='oops')(1) + self.assertEqual(rtn, ('1', 'oops')) + vldtr = IS_NOT_IN_DB(db, 'person.name', error_message='oops') + vldtr.set_self_id({'name': 'costanza', 'nickname': 'T Bone'}) + rtn = vldtr('george') + self.assertEqual(rtn, ('george', 'oops')) + rtn = vldtr('costanza') + self.assertEqual(rtn, ('costanza', None)) + + db.person.drop() + + def test_IS_INT_IN_RANGE(self): + rtn = IS_INT_IN_RANGE(1, 5)('4') + self.assertEqual(rtn, (4, None)) + rtn = IS_INT_IN_RANGE(1, 5)(4) + self.assertEqual(rtn, (4, None)) + rtn = IS_INT_IN_RANGE(1, 5)(1) + self.assertEqual(rtn, (1, None)) + rtn = IS_INT_IN_RANGE(1, 5)(5) + self.assertEqual(rtn, (5, 'Enter an integer between 1 and 4')) + rtn = IS_INT_IN_RANGE(1, 5)(5) + self.assertEqual(rtn, (5, 'Enter an integer between 1 and 4')) + rtn = IS_INT_IN_RANGE(1, 5)(3.5) + self.assertEqual(rtn, (3.5, 'Enter an integer between 1 and 4')) + rtn = IS_INT_IN_RANGE(None, 5)('4') + self.assertEqual(rtn, (4, None)) + rtn = IS_INT_IN_RANGE(None, 5)('6') + self.assertEqual(rtn, ('6', 'Enter an integer less than or equal to 4')) + rtn = IS_INT_IN_RANGE(1, None)('4') + self.assertEqual(rtn, (4, None)) + rtn = IS_INT_IN_RANGE(1, None)('0') + self.assertEqual(rtn, ('0', 'Enter an integer greater than or equal to 1')) + rtn = IS_INT_IN_RANGE()(6) + self.assertEqual(rtn, (6, None)) + rtn = IS_INT_IN_RANGE()('abc') + self.assertEqual(rtn, ('abc', 'Enter an integer')) + + def test_IS_FLOAT_IN_RANGE(self): + # with None + rtn = IS_FLOAT_IN_RANGE(1, 5)(None) + self.assertEqual(rtn, (None, 'Enter a number between 1 and 5')) + rtn = IS_FLOAT_IN_RANGE(1, 5)('4') + self.assertEqual(rtn, (4.0, None)) + rtn = IS_FLOAT_IN_RANGE(1, 5)(4) + self.assertEqual(rtn, (4.0, None)) + rtn = IS_FLOAT_IN_RANGE(1, 5)(1) + self.assertEqual(rtn, (1.0, None)) + rtn = IS_FLOAT_IN_RANGE(1, 5)(5.25) + self.assertEqual(rtn, (5.25, 'Enter a number between 1 and 5')) + rtn = IS_FLOAT_IN_RANGE(1, 5)(6.0) + self.assertEqual(rtn, (6.0, 'Enter a number between 1 and 5')) + rtn = IS_FLOAT_IN_RANGE(1, 5)(3.5) + self.assertEqual(rtn, (3.5, None)) + rtn = IS_FLOAT_IN_RANGE(1, None)(3.5) + self.assertEqual(rtn, (3.5, None)) + rtn = IS_FLOAT_IN_RANGE(None, 5)(3.5) + self.assertEqual(rtn, (3.5, None)) + rtn = IS_FLOAT_IN_RANGE(1, None)(0.5) + self.assertEqual(rtn, (0.5, 'Enter a number greater than or equal to 1')) + rtn = IS_FLOAT_IN_RANGE(None, 5)(6.5) + self.assertEqual(rtn, (6.5, 'Enter a number less than or equal to 5')) + rtn = IS_FLOAT_IN_RANGE()(6.5) + self.assertEqual(rtn, (6.5, None)) + rtn = IS_FLOAT_IN_RANGE()('abc') + self.assertEqual(rtn, ('abc', 'Enter a number')) + rtn = IS_FLOAT_IN_RANGE()('6,5') + self.assertEqual(rtn, ('6,5', 'Enter a number')) + rtn = IS_FLOAT_IN_RANGE(dot=',')('6.5') + self.assertEqual(rtn, (6.5, None)) + # With .formatter(None) + rtn = IS_FLOAT_IN_RANGE(dot=',').formatter(None) + self.assertEqual(rtn, None) + rtn = IS_FLOAT_IN_RANGE(dot=',').formatter(0.25) + self.assertEqual(rtn, '0,25') + # To trigger str2dec "if not '.' in s:" line + rtn = IS_FLOAT_IN_RANGE(dot=',').formatter(1) + self.assertEqual(rtn, '1,00') + + def test_IS_DECIMAL_IN_RANGE(self): + # with None + rtn = IS_DECIMAL_IN_RANGE(1, 5)(None) + self.assertEqual(rtn, (None, 'Enter a number between 1 and 5')) + rtn = IS_DECIMAL_IN_RANGE(1, 5)('4') + self.assertEqual(rtn, (decimal.Decimal('4'), None)) + rtn = IS_DECIMAL_IN_RANGE(1, 5)(4) + self.assertEqual(rtn, (decimal.Decimal('4'), None)) + rtn = IS_DECIMAL_IN_RANGE(1, 5)(1) + self.assertEqual(rtn, (decimal.Decimal('1'), None)) + rtn = IS_DECIMAL_IN_RANGE(1, 5)(5.25) + self.assertEqual(rtn, (5.25, 'Enter a number between 1 and 5')) + rtn = IS_DECIMAL_IN_RANGE(5.25, 6)(5.25) + self.assertEqual(rtn, (decimal.Decimal('5.25'), None)) + rtn = IS_DECIMAL_IN_RANGE(5.25, 6)('5.25') + self.assertEqual(rtn, (decimal.Decimal('5.25'), None)) + rtn = IS_DECIMAL_IN_RANGE(1, 5)(6.0) + self.assertEqual(rtn, (6.0, 'Enter a number between 1 and 5')) + rtn = IS_DECIMAL_IN_RANGE(1, 5)(3.5) + self.assertEqual(rtn, (decimal.Decimal('3.5'), None)) + rtn = IS_DECIMAL_IN_RANGE(1.5, 5.5)(3.5) + self.assertEqual(rtn, (decimal.Decimal('3.5'), None)) + rtn = IS_DECIMAL_IN_RANGE(1.5, 5.5)(6.5) + self.assertEqual(rtn, (6.5, 'Enter a number between 1.5 and 5.5')) + rtn = IS_DECIMAL_IN_RANGE(1.5, None)(6.5) + self.assertEqual(rtn, (decimal.Decimal('6.5'), None)) + rtn = IS_DECIMAL_IN_RANGE(1.5, None)(0.5) + self.assertEqual(rtn, (0.5, 'Enter a number greater than or equal to 1.5')) + rtn = IS_DECIMAL_IN_RANGE(None, 5.5)(4.5) + self.assertEqual(rtn, (decimal.Decimal('4.5'), None)) + rtn = IS_DECIMAL_IN_RANGE(None, 5.5)(6.5) + self.assertEqual(rtn, (6.5, 'Enter a number less than or equal to 5.5')) + rtn = IS_DECIMAL_IN_RANGE()(6.5) + self.assertEqual(rtn, (decimal.Decimal('6.5'), None)) + rtn = IS_DECIMAL_IN_RANGE(0, 99)(123.123) + self.assertEqual(rtn, (123.123, 'Enter a number between 0 and 99')) + rtn = IS_DECIMAL_IN_RANGE(0, 99)('123.123') + self.assertEqual(rtn, ('123.123', 'Enter a number between 0 and 99')) + rtn = IS_DECIMAL_IN_RANGE(0, 99)('12.34') + self.assertEqual(rtn, (decimal.Decimal('12.34'), None)) + rtn = IS_DECIMAL_IN_RANGE()('abc') + self.assertEqual(rtn, ('abc', 'Enter a number')) + rtn = IS_DECIMAL_IN_RANGE()('6,5') + self.assertEqual(rtn, ('6,5', 'Enter a number')) + rtn = IS_DECIMAL_IN_RANGE(dot=',')('6.5') + self.assertEqual(rtn, (decimal.Decimal('6.5'), None)) + rtn = IS_DECIMAL_IN_RANGE(1, 5)(decimal.Decimal('4')) + self.assertEqual(rtn, (decimal.Decimal('4'), None)) + # With .formatter(None) + rtn = IS_DECIMAL_IN_RANGE(dot=',').formatter(None) + self.assertEqual(rtn, None) + rtn = IS_DECIMAL_IN_RANGE(dot=',').formatter(0.25) + self.assertEqual(rtn, '0,25') + + def test_IS_NOT_EMPTY(self): + rtn = IS_NOT_EMPTY()(1) + self.assertEqual(rtn, (1, None)) + rtn = IS_NOT_EMPTY()(0) + self.assertEqual(rtn, (0, None)) + rtn = IS_NOT_EMPTY()('x') + self.assertEqual(rtn, ('x', None)) + rtn = IS_NOT_EMPTY()(' x ') + self.assertEqual(rtn, (' x ', None)) + rtn = IS_NOT_EMPTY()(None) + self.assertEqual(rtn, (None, 'Enter a value')) + rtn = IS_NOT_EMPTY()('') + self.assertEqual(rtn, ('', 'Enter a value')) + rtn = IS_NOT_EMPTY()(b'') + self.assertEqual(rtn, (b'', 'Enter a value')) + rtn = IS_NOT_EMPTY()(' ') + self.assertEqual(rtn, (' ', 'Enter a value')) + rtn = IS_NOT_EMPTY()(' \n\t') + self.assertEqual(rtn, (' \n\t', 'Enter a value')) + rtn = IS_NOT_EMPTY()([]) + self.assertEqual(rtn, ([], 'Enter a value')) + rtn = IS_NOT_EMPTY(empty_regex='def')('def') + self.assertEqual(rtn, ('def', 'Enter a value')) + rtn = IS_NOT_EMPTY(empty_regex='de[fg]')('deg') + self.assertEqual(rtn, ('deg', 'Enter a value')) + rtn = IS_NOT_EMPTY(empty_regex='def')('abc') + self.assertEqual(rtn, ('abc', None)) + + def test_IS_ALPHANUMERIC(self): + rtn = IS_ALPHANUMERIC()('1') + self.assertEqual(rtn, ('1', None)) + rtn = IS_ALPHANUMERIC()('') + self.assertEqual(rtn, ('', None)) + rtn = IS_ALPHANUMERIC()('A_a') + self.assertEqual(rtn, ('A_a', None)) + rtn = IS_ALPHANUMERIC()('!') + self.assertEqual(rtn, ('!', 'Enter only letters, numbers, and underscore')) + + def test_IS_EMAIL(self): + rtn = IS_EMAIL()('a@b.com') + self.assertEqual(rtn, ('a@b.com', None)) + rtn = IS_EMAIL()('abc@def.com') + self.assertEqual(rtn, ('abc@def.com', None)) + rtn = IS_EMAIL()('abc@3def.com') + self.assertEqual(rtn, ('abc@3def.com', None)) + rtn = IS_EMAIL()('abc@def.us') + self.assertEqual(rtn, ('abc@def.us', None)) + rtn = IS_EMAIL()('abc@d_-f.us') + self.assertEqual(rtn, ('abc@d_-f.us', None)) + rtn = IS_EMAIL()('@def.com') # missing name + self.assertEqual(rtn, ('@def.com', 'Enter a valid email address')) + rtn = IS_EMAIL()('"abc@def".com') # quoted name + self.assertEqual(rtn, ('"abc@def".com', 'Enter a valid email address')) + rtn = IS_EMAIL()('abc+def.com') # no @ + self.assertEqual(rtn, ('abc+def.com', 'Enter a valid email address')) + rtn = IS_EMAIL()('abc@def.x') # one-char TLD + self.assertEqual(rtn, ('abc@def.x', 'Enter a valid email address')) + rtn = IS_EMAIL()('abc@def.12') # numeric TLD + self.assertEqual(rtn, ('abc@def.12', 'Enter a valid email address')) + rtn = IS_EMAIL()('abc@def..com') # double-dot in domain + self.assertEqual(rtn, ('abc@def..com', 'Enter a valid email address')) + rtn = IS_EMAIL()('abc@.def.com') # dot starts domain + self.assertEqual(rtn, ('abc@.def.com', 'Enter a valid email address')) + rtn = IS_EMAIL()('abc@def.c_m') # underscore in TLD + self.assertEqual(rtn, ('abc@def.c_m', 'Enter a valid email address')) + rtn = IS_EMAIL()('NotAnEmail') # missing @ + self.assertEqual(rtn, ('NotAnEmail', 'Enter a valid email address')) + rtn = IS_EMAIL()('abc@NotAnEmail') # missing TLD + self.assertEqual(rtn, ('abc@NotAnEmail', 'Enter a valid email address')) + rtn = IS_EMAIL()('customer/department@example.com') + self.assertEqual(rtn, ('customer/department@example.com', None)) + rtn = IS_EMAIL()('$A12345@example.com') + self.assertEqual(rtn, ('$A12345@example.com', None)) + rtn = IS_EMAIL()('!def!xyz%abc@example.com') + self.assertEqual(rtn, ('!def!xyz%abc@example.com', None)) + rtn = IS_EMAIL()('_Yosemite.Sam@example.com') + self.assertEqual(rtn, ('_Yosemite.Sam@example.com', None)) + rtn = IS_EMAIL()('~@example.com') + self.assertEqual(rtn, ('~@example.com', None)) + rtn = IS_EMAIL()('.wooly@example.com') # dot starts name + self.assertEqual(rtn, ('.wooly@example.com', 'Enter a valid email address')) + rtn = IS_EMAIL()('wo..oly@example.com') # adjacent dots in name + self.assertEqual(rtn, ('wo..oly@example.com', 'Enter a valid email address')) + rtn = IS_EMAIL()('pootietang.@example.com') # dot ends name + self.assertEqual(rtn, ('pootietang.@example.com', 'Enter a valid email address')) + rtn = IS_EMAIL()('.@example.com') # name is bare dot + self.assertEqual(rtn, ('.@example.com', 'Enter a valid email address')) + rtn = IS_EMAIL()('Ima.Fool@example.com') + self.assertEqual(rtn, ('Ima.Fool@example.com', None)) + rtn = IS_EMAIL()('Ima Fool@example.com') # space in name + self.assertEqual(rtn, ('Ima Fool@example.com', 'Enter a valid email address')) + rtn = IS_EMAIL()('localguy@localhost') # localhost as domain + self.assertEqual(rtn, ('localguy@localhost', None)) + # test for banned + rtn = IS_EMAIL(banned='^.*\.com(|\..*)$')('localguy@localhost') # localhost as domain + self.assertEqual(rtn, ('localguy@localhost', None)) + rtn = IS_EMAIL(banned='^.*\.com(|\..*)$')('abc@example.com') + self.assertEqual(rtn, ('abc@example.com', 'Enter a valid email address')) + # test for forced + rtn = IS_EMAIL(forced='^.*\.edu(|\..*)$')('localguy@localhost') + self.assertEqual(rtn, ('localguy@localhost', 'Enter a valid email address')) + rtn = IS_EMAIL(forced='^.*\.edu(|\..*)$')('localguy@example.edu') + self.assertEqual(rtn, ('localguy@example.edu', None)) + # test for not a string at all + rtn = IS_EMAIL(error_message='oops')(42) + self.assertEqual(rtn, (42, 'oops')) + + # test for Internationalized Domain Names, see https://docs.python.org/2/library/codecs.html#module-encodings.idna + rtn = IS_EMAIL()('web2py@Alliancefrançaise.nu') + self.assertEqual(rtn, ('web2py@Alliancefrançaise.nu', None)) + + + def test_IS_LIST_OF_EMAILS(self): + emails = ['localguy@localhost', '_Yosemite.Sam@example.com'] + rtn = IS_LIST_OF_EMAILS()(','.join(emails)) + self.assertEqual(rtn, (','.join(emails), None)) + rtn = IS_LIST_OF_EMAILS()(';'.join(emails)) + self.assertEqual(rtn, (';'.join(emails), None)) + rtn = IS_LIST_OF_EMAILS()(' '.join(emails)) + self.assertEqual(rtn, (' '.join(emails), None)) + emails.append('a') + rtn = IS_LIST_OF_EMAILS()(';'.join(emails)) + self.assertEqual(rtn, ('localguy@localhost;_Yosemite.Sam@example.com;a', 'Invalid emails: a')) + rtn = IS_LIST_OF_EMAILS().formatter(['test@example.com', 'dude@example.com']) + self.assertEqual(rtn, 'test@example.com, dude@example.com') + + def test_IS_URL(self): + rtn = IS_URL()('http://example.com') + self.assertEqual(rtn, ('http://example.com', None)) + rtn = IS_URL(error_message='oops')('http://example,com') + self.assertEqual(rtn, ('http://example,com', 'oops')) + rtn = IS_URL(error_message='oops')('http://www.example.com:8800/a/b/c/d/e/f/g/h') + self.assertEqual(rtn, ('http://www.example.com:8800/a/b/c/d/e/f/g/h', None)) + rtn = IS_URL(error_message='oops', prepend_scheme='http')('example.com') + self.assertEqual(rtn, ('http://example.com', None)) + rtn = IS_URL()('http://example.com?q=george&p=22') + self.assertEqual(rtn, ('http://example.com?q=george&p=22', None)) + rtn = IS_URL(mode='generic', prepend_scheme=None)('example.com') + self.assertEqual(rtn, ('example.com', None)) + + def test_IS_TIME(self): + rtn = IS_TIME()('21:30') + self.assertEqual(rtn, (datetime.time(21, 30), None)) + rtn = IS_TIME()('21-30') + self.assertEqual(rtn, (datetime.time(21, 30), None)) + rtn = IS_TIME()('21.30') + self.assertEqual(rtn, (datetime.time(21, 30), None)) + rtn = IS_TIME()('21:30:59') + self.assertEqual(rtn, (datetime.time(21, 30, 59), None)) + rtn = IS_TIME()('5:30') + self.assertEqual(rtn, (datetime.time(5, 30), None)) + rtn = IS_TIME()('5:30 am') + self.assertEqual(rtn, (datetime.time(5, 30), None)) + rtn = IS_TIME()('5:30 pm') + self.assertEqual(rtn, (datetime.time(17, 30), None)) + rtn = IS_TIME()('5:30 whatever') + self.assertEqual(rtn, ('5:30 whatever', 'Enter time as hh:mm:ss (seconds, am, pm optional)')) + rtn = IS_TIME()('5:30 20') + self.assertEqual(rtn, ('5:30 20', 'Enter time as hh:mm:ss (seconds, am, pm optional)')) + rtn = IS_TIME()('24:30') + self.assertEqual(rtn, ('24:30', 'Enter time as hh:mm:ss (seconds, am, pm optional)')) + rtn = IS_TIME()('21:60') + self.assertEqual(rtn, ('21:60', 'Enter time as hh:mm:ss (seconds, am, pm optional)')) + rtn = IS_TIME()('21:30::') + self.assertEqual(rtn, ('21:30::', 'Enter time as hh:mm:ss (seconds, am, pm optional)')) + rtn = IS_TIME()('') + self.assertEqual(rtn, ('', 'Enter time as hh:mm:ss (seconds, am, pm optional)')) + + def test_IS_DATE(self): + v = IS_DATE(format="%m/%d/%Y", error_message="oops") + rtn = v('03/03/2008') + self.assertEqual(rtn, (datetime.date(2008, 3, 3), None)) + rtn = v('31/03/2008') + self.assertEqual(rtn, ('31/03/2008', 'oops')) + rtn = IS_DATE(format="%m/%d/%Y", error_message="oops").formatter(datetime.date(1834, 12, 14)) + self.assertEqual(rtn, '12/14/1834') + + def test_IS_DATETIME(self): + v = IS_DATETIME(format="%m/%d/%Y %H:%M", error_message="oops") + rtn = v('03/03/2008 12:40') + self.assertEqual(rtn, (datetime.datetime(2008, 3, 3, 12, 40), None)) + rtn = v('31/03/2008 29:40') + self.assertEqual(rtn, ('31/03/2008 29:40', 'oops')) + # Test timezone is removed and value is properly converted + # + # https://github.com/web2py/web2py/issues/1094 + + class DummyTimezone(datetime.tzinfo): + + ONE = datetime.timedelta(hours=1) + + def utcoffset(self, dt): + return DummyTimezone.ONE + + def tzname(self, dt): + return "UTC+1" + + def dst(self, dt): + return DummyTimezone.ONE + + def localize(self, dt, is_dst=False): + return dt.replace(tzinfo=self) + v = IS_DATETIME(format="%Y-%m-%d %H:%M", error_message="oops", timezone=DummyTimezone()) + rtn = v('1982-12-14 08:00') + self.assertEqual(rtn, (datetime.datetime(1982, 12, 14, 7, 0), None)) + + def test_IS_DATE_IN_RANGE(self): + v = IS_DATE_IN_RANGE(minimum=datetime.date(2008, 1, 1), + maximum=datetime.date(2009, 12, 31), + format="%m/%d/%Y", error_message="oops") + + rtn = v('03/03/2008') + self.assertEqual(rtn, (datetime.date(2008, 3, 3), None)) + rtn = v('03/03/2010') + self.assertEqual(rtn, ('03/03/2010', 'oops')) + rtn = v(datetime.date(2008, 3, 3)) + self.assertEqual(rtn, (datetime.date(2008, 3, 3), None)) + rtn = v(datetime.date(2010, 3, 3)) + self.assertEqual(rtn, (datetime.date(2010, 3, 3), 'oops')) + v = IS_DATE_IN_RANGE(maximum=datetime.date(2009, 12, 31), + format="%m/%d/%Y") + rtn = v('03/03/2010') + self.assertEqual(rtn, ('03/03/2010', 'Enter date on or before 12/31/2009')) + v = IS_DATE_IN_RANGE(minimum=datetime.date(2008, 1, 1), + format="%m/%d/%Y") + rtn = v('03/03/2007') + self.assertEqual(rtn, ('03/03/2007', 'Enter date on or after 01/01/2008')) + v = IS_DATE_IN_RANGE(minimum=datetime.date(2008, 1, 1), + maximum=datetime.date(2009, 12, 31), + format="%m/%d/%Y") + rtn = v('03/03/2007') + self.assertEqual(rtn, ('03/03/2007', 'Enter date in range 01/01/2008 12/31/2009')) + + def test_IS_DATETIME_IN_RANGE(self): + v = IS_DATETIME_IN_RANGE( + minimum=datetime.datetime(2008, 1, 1, 12, 20), + maximum=datetime.datetime(2009, 12, 31, 12, 20), + format="%m/%d/%Y %H:%M", error_message="oops") + rtn = v('03/03/2008 12:40') + self.assertEqual(rtn, (datetime.datetime(2008, 3, 3, 12, 40), None)) + rtn = v('03/03/2010 10:34') + self.assertEqual(rtn, ('03/03/2010 10:34', 'oops')) + rtn = v(datetime.datetime(2008, 3, 3, 0, 0)) + self.assertEqual(rtn, (datetime.datetime(2008, 3, 3, 0, 0), None)) + rtn = v(datetime.datetime(2010, 3, 3, 0, 0)) + self.assertEqual(rtn, (datetime.datetime(2010, 3, 3, 0, 0), 'oops')) + v = IS_DATETIME_IN_RANGE(maximum=datetime.datetime(2009, 12, 31, 12, 20), + format='%m/%d/%Y %H:%M:%S') + rtn = v('03/03/2010 12:20:00') + self.assertEqual(rtn, ('03/03/2010 12:20:00', 'Enter date and time on or before 12/31/2009 12:20:00')) + v = IS_DATETIME_IN_RANGE(minimum=datetime.datetime(2008, 1, 1, 12, 20), + format='%m/%d/%Y %H:%M:%S') + rtn = v('03/03/2007 12:20:00') + self.assertEqual(rtn, ('03/03/2007 12:20:00', 'Enter date and time on or after 01/01/2008 12:20:00')) + v = IS_DATETIME_IN_RANGE(minimum=datetime.datetime(2008, 1, 1, 12, 20), + maximum=datetime.datetime(2009, 12, 31, 12, 20), + format='%m/%d/%Y %H:%M:%S') + rtn = v('03/03/2007 12:20:00') + self.assertEqual(rtn, ('03/03/2007 12:20:00', 'Enter date and time in range 01/01/2008 12:20:00 12/31/2009 12:20:00')) + v = IS_DATETIME_IN_RANGE(maximum=datetime.datetime(2009, 12, 31, 12, 20), + format='%Y-%m-%d %H:%M:%S', error_message='oops') + rtn = v('clearly not a date') + self.assertEqual(rtn, ('clearly not a date', 'oops')) + + def test_IS_LIST_OF(self): + values = [0, 1, 2, 3, 4] + rtn = IS_LIST_OF(IS_INT_IN_RANGE(0, 10))(values) + self.assertEqual(rtn, (values, None)) + values.append(11) + rtn = IS_LIST_OF(IS_INT_IN_RANGE(0, 10))(values) + self.assertEqual(rtn, (values, 'Enter an integer between 0 and 9')) + rtn = IS_LIST_OF(IS_INT_IN_RANGE(0, 10))(1) + self.assertEqual(rtn, ([1], None)) + rtn = IS_LIST_OF(IS_INT_IN_RANGE(0, 10), minimum=10)([1, 2]) + self.assertEqual(rtn, ([1, 2], 'Minimum length is 10')) + rtn = IS_LIST_OF(IS_INT_IN_RANGE(0, 10), maximum=2)([1, 2, 3]) + self.assertEqual(rtn, ([1, 2, 3], 'Maximum length is 2')) + # regression test for issue 742 + rtn = IS_LIST_OF(minimum=1)('') + self.assertEqual(rtn, ([], 'Minimum length is 1')) + + def test_IS_LOWER(self): + rtn = IS_LOWER()('ABC') + self.assertEqual(rtn, ('abc', None)) + rtn = IS_LOWER()(b'ABC') + self.assertEqual(rtn, (b'abc', None)) + rtn = IS_LOWER()('Ñ') + self.assertEqual(rtn, ('ñ', None)) + + def test_IS_UPPER(self): + rtn = IS_UPPER()('abc') + self.assertEqual(rtn, ('ABC', None)) + rtn = IS_UPPER()(b'abc') + self.assertEqual(rtn, (b'ABC', None)) + rtn = IS_UPPER()('ñ') + self.assertEqual(rtn, ('Ñ', None)) + + def test_IS_SLUG(self): + rtn = IS_SLUG()('abc123') + self.assertEqual(rtn, ('abc123', None)) + rtn = IS_SLUG()('ABC123') + self.assertEqual(rtn, ('abc123', None)) + rtn = IS_SLUG()('abc-123') + self.assertEqual(rtn, ('abc-123', None)) + rtn = IS_SLUG()('abc--123') + self.assertEqual(rtn, ('abc-123', None)) + rtn = IS_SLUG()('abc 123') + self.assertEqual(rtn, ('abc-123', None)) + rtn = IS_SLUG()('abc\t_123') + self.assertEqual(rtn, ('abc-123', None)) + rtn = IS_SLUG()('-abc-') + self.assertEqual(rtn, ('abc', None)) + rtn = IS_SLUG()('--a--b--_ -c--') + self.assertEqual(rtn, ('a-b-c', None)) + rtn = IS_SLUG()('abc&123') + self.assertEqual(rtn, ('abc123', None)) + rtn = IS_SLUG()('abc&123&def') + self.assertEqual(rtn, ('abc123def', None)) + rtn = IS_SLUG()('ñ') + self.assertEqual(rtn, ('n', None)) + rtn = IS_SLUG(maxlen=4)('abc123') + self.assertEqual(rtn, ('abc1', None)) + rtn = IS_SLUG()('abc_123') + self.assertEqual(rtn, ('abc-123', None)) + rtn = IS_SLUG(keep_underscores=False)('abc_123') + self.assertEqual(rtn, ('abc-123', None)) + rtn = IS_SLUG(keep_underscores=True)('abc_123') + self.assertEqual(rtn, ('abc_123', None)) + rtn = IS_SLUG(check=False)('abc') + self.assertEqual(rtn, ('abc', None)) + rtn = IS_SLUG(check=True)('abc') + self.assertEqual(rtn, ('abc', None)) + rtn = IS_SLUG(check=False)('a bc') + self.assertEqual(rtn, ('a-bc', None)) + rtn = IS_SLUG(check=True)('a bc') + self.assertEqual(rtn, ('a bc', 'Must be slug')) + + def test_ANY_OF(self): + rtn = ANY_OF([IS_EMAIL(), IS_ALPHANUMERIC()])('a@b.co') + self.assertEqual(rtn, ('a@b.co', None)) + rtn = ANY_OF([IS_EMAIL(), IS_ALPHANUMERIC()])('abco') + self.assertEqual(rtn, ('abco', None)) + rtn = ANY_OF([IS_EMAIL(), IS_ALPHANUMERIC()])('@ab.co') + self.assertEqual(rtn, ('@ab.co', 'Enter only letters, numbers, and underscore')) + rtn = ANY_OF([IS_ALPHANUMERIC(), IS_EMAIL()])('@ab.co') + self.assertEqual(rtn, ('@ab.co', 'Enter a valid email address')) + rtn = ANY_OF([IS_DATE(), IS_EMAIL()])('a@b.co') + self.assertEqual(rtn, ('a@b.co', None)) + rtn = ANY_OF([IS_DATE(), IS_EMAIL()])('1982-12-14') + self.assertEqual(rtn, (datetime.date(1982, 12, 14), None)) + rtn = ANY_OF([IS_DATE(format='%m/%d/%Y'), IS_EMAIL()]).formatter(datetime.date(1834, 12, 14)) + self.assertEqual(rtn, '12/14/1834') + + def test_IS_EMPTY_OR(self): + rtn = IS_EMPTY_OR(IS_EMAIL())('abc@def.com') + self.assertEqual(rtn, ('abc@def.com', None)) + rtn = IS_EMPTY_OR(IS_EMAIL())(' ') + self.assertEqual(rtn, (None, None)) + rtn = IS_EMPTY_OR(IS_EMAIL(), null='abc')(' ') + self.assertEqual(rtn, ('abc', None)) + rtn = IS_EMPTY_OR(IS_EMAIL(), null='abc', empty_regex='def')('def') + self.assertEqual(rtn, ('abc', None)) + rtn = IS_EMPTY_OR(IS_EMAIL())('abc') + self.assertEqual(rtn, ('abc', 'Enter a valid email address')) + rtn = IS_EMPTY_OR(IS_EMAIL())(' abc ') + self.assertEqual(rtn, (' abc ', 'Enter a valid email address')) + rtn = IS_EMPTY_OR(IS_IN_SET([('id1', 'first label'), ('id2', 'second label')], zero='zero')).options(zero=False) + self.assertEqual(rtn, [('', ''), ('id1', 'first label'), ('id2', 'second label')]) + rtn = IS_EMPTY_OR(IS_IN_SET([('id1', 'first label'), ('id2', 'second label')], zero='zero')).options() + self.assertEqual(rtn, [('', 'zero'), ('id1', 'first label'), ('id2', 'second label')]) + rtn = IS_EMPTY_OR((IS_LOWER(), IS_EMAIL()))('AAA') + self.assertEqual(rtn, ('aaa', 'Enter a valid email address')) + rtn = IS_EMPTY_OR([IS_LOWER(), IS_EMAIL()])('AAA') + self.assertEqual(rtn, ('aaa', 'Enter a valid email address')) + + def test_CLEANUP(self): + rtn = CLEANUP()('helloò') + self.assertEqual(rtn, ('hello', None)) + + def test_CRYPT(self): + rtn = str(CRYPT(digest_alg='md5', salt=True)('test')[0]) + self.myassertRegex(rtn, r'^md5\$.{16}\$.{32}$') + rtn = str(CRYPT(digest_alg='sha1', salt=True)('test')[0]) + self.myassertRegex(rtn, r'^sha1\$.{16}\$.{40}$') + rtn = str(CRYPT(digest_alg='sha256', salt=True)('test')[0]) + self.myassertRegex(rtn, r'^sha256\$.{16}\$.{64}$') + rtn = str(CRYPT(digest_alg='sha384', salt=True)('test')[0]) + self.myassertRegex(rtn, r'^sha384\$.{16}\$.{96}$') + rtn = str(CRYPT(digest_alg='sha512', salt=True)('test')[0]) + self.myassertRegex(rtn, r'^sha512\$.{16}\$.{128}$') + alg = 'pbkdf2(1000,20,sha512)' + rtn = str(CRYPT(digest_alg=alg, salt=True)('test')[0]) + self.myassertRegex(rtn, r'^pbkdf2\(1000,20,sha512\)\$.{16}\$.{40}$') + rtn = str(CRYPT(digest_alg='md5', key='mykey', salt=True)('test')[0]) + self.myassertRegex(rtn, r'^md5\$.{16}\$.{32}$') + a = str(CRYPT(digest_alg='sha1', salt=False)('test')[0]) + self.assertEqual(CRYPT(digest_alg='sha1', salt=False)('test')[0], a) + self.assertEqual(CRYPT(digest_alg='sha1', salt=False)('test')[0], a[6:]) + self.assertEqual(CRYPT(digest_alg='md5', salt=False)('test')[0], a) + self.assertEqual(CRYPT(digest_alg='md5', salt=False)('test')[0], a[6:]) + + def test_IS_STRONG(self): + rtn = IS_STRONG(es=True)('Abcd1234') + self.assertEqual(rtn, ('Abcd1234', + 'Must include at least 1 of the following: ~!@#$%^&*()_+-=?<>,.:;{}[]|')) + rtn = IS_STRONG(es=True)('Abcd1234!') + self.assertEqual(rtn, ('Abcd1234!', None)) + rtn = IS_STRONG(es=True, entropy=1)('a') + self.assertEqual(rtn, ('a', None)) + rtn = IS_STRONG(es=True, entropy=1, min=2)('a') + self.assertEqual(rtn, ('a', 'Minimum length is 2')) + rtn = IS_STRONG(es=True, entropy=100)('abc123') + self.assertEqual(rtn, ('abc123', 'Entropy (32.35) less than required (100)')) + rtn = IS_STRONG(es=True, entropy=100)('and') + self.assertEqual(rtn, ('and', 'Entropy (14.57) less than required (100)')) + rtn = IS_STRONG(es=True, entropy=100)('aaa') + self.assertEqual(rtn, ('aaa', 'Entropy (14.42) less than required (100)')) + rtn = IS_STRONG(es=True, entropy=100)('a1d') + self.assertEqual(rtn, ('a1d', 'Entropy (15.97) less than required (100)')) + rtn = IS_STRONG(es=True, entropy=100)('añd') + if PY2: + self.assertEqual(rtn, ('a\xc3\xb1d', 'Entropy (18.13) less than required (100)')) + else: + self.assertEqual(rtn, ('añd', 'Entropy (18.13) less than required (100)')) + rtn = IS_STRONG()('********') + self.assertEqual(rtn, ('********', None)) + rtn = IS_STRONG(es=True, max=4)('abcde') + self.assertEqual(rtn, + ('abcde', + '|'.join(['Minimum length is 8', + 'Maximum length is 4', + 'Must include at least 1 of the following: ~!@#$%^&*()_+-=?<>,.:;{}[]|', + 'Must include at least 1 uppercase', + 'Must include at least 1 number'])) + ) + rtn = IS_STRONG(es=True)('abcde') + self.assertEqual(rtn, + ('abcde', + '|'.join(['Minimum length is 8', + 'Must include at least 1 of the following: ~!@#$%^&*()_+-=?<>,.:;{}[]|', + 'Must include at least 1 uppercase', + 'Must include at least 1 number'])) + ) + rtn = IS_STRONG(upper=0, lower=0, number=0, es=True)('Abcde1') + self.assertEqual(rtn, + ('Abcde1', + '|'.join(['Minimum length is 8', + 'Must include at least 1 of the following: ~!@#$%^&*()_+-=?<>,.:;{}[]|', + 'May not include any uppercase letters', + 'May not include any lowercase letters', + 'May not include any numbers'])) + ) + + def test_IS_IMAGE(self): + class DummyImageFile(object): + + def __init__(self, filename, ext, width, height): + from io import BytesIO + import struct + self.filename = filename + '.' + ext + self.file = BytesIO() + if ext == 'bmp': + self.file.write(b'BM') + self.file.write(b' ' * 16) + self.file.write(struct.pack(' +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +Auth, Mail, PluginManager and various utilities +------------------------------------------------ +""" + +import base64 +from functools import reduce +from gluon._compat import pickle, thread, urllib2, Cookie, StringIO, urlencode +from gluon._compat import configparser, MIMEBase, MIMEMultipart, MIMEText, Header +from gluon._compat import Encoders, Charset, long, urllib_quote, iteritems +from gluon._compat import to_bytes, to_native, add_charset +from gluon._compat import charset_QP, basestring, unicodeT, to_unicode +import datetime +import logging +import sys +import glob +import os +import re +import time +import fnmatch +import traceback +import smtplib +import email.utils +import random +import hmac +import hashlib +import json + +from email import message_from_string + +from gluon.authapi import AuthAPI +from gluon.contenttype import contenttype +from gluon.storage import Storage, StorageList, Settings, Messages +from gluon.utils import web2py_uuid, compare +from gluon.fileutils import read_file, check_credentials +from gluon import * +from gluon.contrib.autolinks import expand_one +from gluon.contrib.markmin.markmin2html import replace_at_urls +from gluon.contrib.markmin.markmin2html import replace_autolinks +from gluon.contrib.markmin.markmin2html import replace_components +from pydal.objects import Row, Set, Query + +import gluon.serializers as serializers + +Table = DAL.Table +Field = DAL.Field + +__all__ = ['Mail', 'Auth', 'Recaptcha2', 'Crud', 'Service', 'Wiki', + 'PluginManager', 'fetch', 'geocode', 'reverse_geocode', 'prettydate'] + +# mind there are two loggers here (logger and crud.settings.logger)! +logger = logging.getLogger("web2py") + +DEFAULT = lambda: None + + +def getarg(position, default=None): + args = current.request.args + if position < 0 and len(args) >= -position: + return args[position] + elif position >= 0 and len(args) > position: + return args[position] + else: + return default + + +def callback(actions, form, tablename=None): + if actions: + if tablename and isinstance(actions, dict): + actions = actions.get(tablename, []) + if not isinstance(actions, (list, tuple)): + actions = [actions] + [action(form) for action in actions] + + +def validators(*a): + b = [] + for item in a: + if isinstance(item, (list, tuple)): + b = b + list(item) + else: + b.append(item) + return b + + +def call_or_redirect(f, *args): + if callable(f): + redirect(f(*args)) + else: + redirect(f) + + +def replace_id(url, form): + if url: + url = url.replace('[id]', str(form.vars.id)) + if url[0] == '/' or url[:4] == 'http': + return url + return URL(url) + + +class Mail(object): + """ + Class for configuring and sending emails with alternative text / html + body, multiple attachments and encryption support + + Works with SMTP and Google App Engine. + + Args: + server: SMTP server address in address:port notation + sender: sender email address + login: sender login name and password in login:password notation + or None if no authentication is required + tls: enables/disables encryption (True by default) + + In Google App Engine use :: + + server='gae' + + For sake of backward compatibility all fields are optional and default + to None, however, to be able to send emails at least server and sender + must be specified. They are available under following fields:: + + mail.settings.server + mail.settings.sender + mail.settings.login + mail.settings.timeout = 60 # seconds (default) + + When server is 'logging', email is logged but not sent (debug mode) + + Optionally you can use PGP encryption or X509:: + + mail.settings.cipher_type = None + mail.settings.gpg_home = None + mail.settings.sign = True + mail.settings.sign_passphrase = None + mail.settings.encrypt = True + mail.settings.x509_sign_keyfile = None + mail.settings.x509_sign_certfile = None + mail.settings.x509_sign_chainfile = None + mail.settings.x509_nocerts = False + mail.settings.x509_crypt_certfiles = None + + cipher_type : None + gpg - need a python-pyme package and gpgme lib + x509 - smime + gpg_home : you can set a GNUPGHOME environment variable + to specify home of gnupg + sign : sign the message (True or False) + sign_passphrase : passphrase for key signing + encrypt : encrypt the message (True or False). It defaults + to True + ... x509 only ... + x509_sign_keyfile : the signers private key filename or + string containing the key. (PEM format) + x509_sign_certfile: the signers certificate filename or + string containing the cert. (PEM format) + x509_sign_chainfile: sets the optional all-in-one file where you + can assemble the certificates of Certification + Authorities (CA) which form the certificate + chain of email certificate. It can be a + string containing the certs to. (PEM format) + x509_nocerts : if True then no attached certificate in mail + x509_crypt_certfiles: the certificates file or strings to encrypt + the messages with can be a file name / + string or a list of file names / + strings (PEM format) + + Examples: + Create Mail object with authentication data for remote server:: + + mail = Mail('example.com:25', 'me@example.com', 'me:password') + + Notice for GAE users: + attachments have an automatic content_id='attachment-i' where i is progressive number + in this way the can be referenced from the HTML as etc. + """ + + class Attachment(MIMEBase): + """ + Email attachment + + Args: + payload: path to file or file-like object with read() method + filename: name of the attachment stored in message; if set to + None, it will be fetched from payload path; file-like + object payload must have explicit filename specified + content_id: id of the attachment; automatically contained within + `<` and `>` + content_type: content type of the attachment; if set to None, + it will be fetched from filename using gluon.contenttype + module + encoding: encoding of all strings passed to this function (except + attachment body) + + Content ID is used to identify attachments within the html body; + in example, attached image with content ID 'photo' may be used in + html message as a source of img tag ``. + + Example:: + Create attachment from text file:: + + attachment = Mail.Attachment('/path/to/file.txt') + + Content-Type: text/plain + MIME-Version: 1.0 + Content-Disposition: attachment; filename="file.txt" + Content-Transfer-Encoding: base64 + + SOMEBASE64CONTENT= + + Create attachment from image file with custom filename and cid:: + + attachment = Mail.Attachment('/path/to/file.png', + filename='photo.png', + content_id='photo') + + Content-Type: image/png + MIME-Version: 1.0 + Content-Disposition: attachment; filename="photo.png" + Content-Id: + Content-Transfer-Encoding: base64 + + SOMEOTHERBASE64CONTENT= + """ + + def __init__( + self, + payload, + filename=None, + content_id=None, + content_type=None, + encoding='utf-8'): + if isinstance(payload, str): + if filename is None: + filename = os.path.basename(payload) + payload = read_file(payload, 'rb') + else: + if filename is None: + raise Exception('Missing attachment name') + payload = payload.read() + # FIXME PY3 can be used to_native? + filename = filename.encode(encoding) + if content_type is None: + content_type = contenttype(filename) + self.my_filename = filename + self.my_payload = payload + MIMEBase.__init__(self, *content_type.split('/', 1)) + self.set_payload(payload) + self['Content-Disposition'] = 'attachment; filename="%s"' % to_native(filename, encoding) + if content_id is not None: + self['Content-Id'] = '<%s>' % to_native(content_id, encoding) + Encoders.encode_base64(self) + + def __init__(self, server=None, sender=None, login=None, tls=True): + + settings = self.settings = Settings() + settings.server = server + settings.sender = sender + settings.login = login + settings.tls = tls + settings.timeout = 5 # seconds + settings.hostname = None + settings.ssl = False + settings.cipher_type = None + settings.gpg_home = None + settings.sign = True + settings.sign_passphrase = None + settings.encrypt = True + settings.x509_sign_keyfile = None + settings.x509_sign_certfile = None + settings.x509_sign_chainfile = None + settings.x509_nocerts = False + settings.x509_crypt_certfiles = None + settings.debug = False + settings.lock_keys = True + self.result = {} + self.error = None + + def send(self, + to, + subject='[no subject]', + message='[no message]', + attachments=None, + cc=None, + bcc=None, + reply_to=None, + sender=None, + encoding='utf-8', + raw=False, + headers={}, + from_address=None, + cipher_type=None, + sign=None, + sign_passphrase=None, + encrypt=None, + x509_sign_keyfile=None, + x509_sign_chainfile=None, + x509_sign_certfile=None, + x509_crypt_certfiles=None, + x509_nocerts=None + ): + """ + Sends an email using data specified in constructor + + Args: + to: list or tuple of receiver addresses; will also accept single + object + subject: subject of the email + message: email body text; depends on type of passed object: + + - if 2-list or 2-tuple is passed: first element will be + source of plain text while second of html text; + - otherwise: object will be the only source of plain text + and html source will be set to None + + If text or html source is: + + - None: content part will be ignored, + - string: content part will be set to it, + - file-like object: content part will be fetched from it using + it's read() method + attachments: list or tuple of Mail.Attachment objects; will also + accept single object + cc: list or tuple of carbon copy receiver addresses; will also + accept single object + bcc: list or tuple of blind carbon copy receiver addresses; will + also accept single object + reply_to: address to which reply should be composed + encoding: encoding of all strings passed to this method (including + message bodies) + headers: dictionary of headers to refine the headers just before + sending mail, e.g. `{'X-Mailer' : 'web2py mailer'}` + from_address: address to appear in the 'From:' header, this is not + the envelope sender. If not specified the sender will be used + + cipher_type : + gpg - need a python-pyme package and gpgme lib + x509 - smime + gpg_home : you can set a GNUPGHOME environment variable + to specify home of gnupg + sign : sign the message (True or False) + sign_passphrase : passphrase for key signing + encrypt : encrypt the message (True or False). It defaults to True. + ... x509 only ... + x509_sign_keyfile : the signers private key filename or + string containing the key. (PEM format) + x509_sign_certfile: the signers certificate filename or + string containing the cert. (PEM format) + x509_sign_chainfile: sets the optional all-in-one file where you + can assemble the certificates of Certification + Authorities (CA) which form the certificate + chain of email certificate. It can be a + string containing the certs to. (PEM format) + x509_nocerts : if True then no attached certificate in mail + x509_crypt_certfiles: the certificates file or strings to encrypt + the messages with can be a file name / string or + a list of file names / strings (PEM format) + Examples: + Send plain text message to single address:: + + mail.send('you@example.com', + 'Message subject', + 'Plain text body of the message') + + Send html message to single address:: + + mail.send('you@example.com', + 'Message subject', + 'Plain text body of the message') + + Send text and html message to three addresses (two in cc):: + + mail.send('you@example.com', + 'Message subject', + ('Plain text body', 'html body'), + cc=['other1@example.com', 'other2@example.com']) + + Send html only message with image attachment available from the + message by 'photo' content id:: + + mail.send('you@example.com', + 'Message subject', + (None, ''), + Mail.Attachment('/path/to/photo.jpg' + content_id='photo')) + + Send email with two attachments and no body text:: + + mail.send('you@example.com, + 'Message subject', + None, + [Mail.Attachment('/path/to/fist.file'), + Mail.Attachment('/path/to/second.file')]) + + Returns: + True on success, False on failure. + + Before return, method updates two object's fields: + + - self.result: return value of smtplib.SMTP.sendmail() or GAE's + mail.send_mail() method + - self.error: Exception message or None if above was successful + """ + + # We don't want to use base64 encoding for unicode mail + add_charset('utf-8', charset_QP, charset_QP, 'utf-8') + + def encode_header(key): + if [c for c in key if 32 > ord(c) or ord(c) > 127]: + return Header(key.encode('utf-8'), 'utf-8') + else: + return key + + # encoded or raw text + def encoded_or_raw(text): + if raw: + text = encode_header(text) + return text + + sender = sender or self.settings.sender + + if not isinstance(self.settings.server, str): + raise Exception('Server address not specified') + if not isinstance(sender, str): + raise Exception('Sender address not specified') + + if not raw and attachments: + # Use multipart/mixed if there is attachments + payload_in = MIMEMultipart('mixed') + elif raw: + # no encoding configuration for raw messages + if not isinstance(message, basestring): + message = message.read() + if isinstance(message, unicodeT): + text = message.encode('utf-8') + elif not encoding == 'utf-8': + text = message.decode(encoding).encode('utf-8') + else: + text = message + # No charset passed to avoid transport encoding + # NOTE: some unicode encoded strings will produce + # unreadable mail contents. + payload_in = MIMEText(text) + if to: + if not isinstance(to, (list, tuple)): + to = [to] + else: + raise Exception('Target receiver address not specified') + if cc: + if not isinstance(cc, (list, tuple)): + cc = [cc] + if bcc: + if not isinstance(bcc, (list, tuple)): + bcc = [bcc] + if message is None: + text = html = None + elif isinstance(message, (list, tuple)): + text, html = message + elif message.strip().startswith(''): + text = self.settings.server == 'gae' and message or None + html = message + else: + text = message + html = None + + if (text is not None or html is not None) and (not raw): + + if text is not None: + if not isinstance(text, basestring): + text = text.read() + if isinstance(text, unicodeT): + text = text.encode('utf-8') + elif not encoding == 'utf-8': + text = text.decode(encoding).encode('utf-8') + if html is not None: + if not isinstance(html, basestring): + html = html.read() + if isinstance(html, unicodeT): + html = html.encode('utf-8') + elif not encoding == 'utf-8': + html = html.decode(encoding).encode('utf-8') + + # Construct mime part only if needed + if text is not None and html: + # We have text and html we need multipart/alternative + attachment = MIMEMultipart('alternative') + attachment.attach(MIMEText(text, _charset='utf-8')) + attachment.attach(MIMEText(html, 'html', _charset='utf-8')) + elif text is not None: + attachment = MIMEText(text, _charset='utf-8') + elif html: + attachment = MIMEText(html, 'html', _charset='utf-8') + + if attachments: + # If there is attachments put text and html into + # multipart/mixed + payload_in.attach(attachment) + else: + # No attachments no multipart/mixed + payload_in = attachment + + if (attachments is None) or raw: + pass + elif isinstance(attachments, (list, tuple)): + for attachment in attachments: + payload_in.attach(attachment) + else: + payload_in.attach(attachments) + attachments = [attachments] + + ####################################################### + # CIPHER # + ####################################################### + cipher_type = cipher_type or self.settings.cipher_type + sign = sign if sign is not None else self.settings.sign + sign_passphrase = sign_passphrase or self.settings.sign_passphrase + encrypt = encrypt if encrypt is not None else self.settings.encrypt + ####################################################### + # GPGME # + ####################################################### + if cipher_type == 'gpg': + if self.settings.gpg_home: + # Set GNUPGHOME environment variable to set home of gnupg + import os + os.environ['GNUPGHOME'] = self.settings.gpg_home + if not sign and not encrypt: + self.error = "No sign and no encrypt is set but cipher type to gpg" + return False + + # need a python-pyme package and gpgme lib + from pyme import core, errors + from pyme.constants.sig import mode + ############################################ + # sign # + ############################################ + if sign: + import string + core.check_version(None) + pin = string.replace(payload_in.as_string(), '\n', '\r\n') + plain = core.Data(pin) + sig = core.Data() + c = core.Context() + c.set_armor(1) + c.signers_clear() + # search for signing key for From: + for sigkey in c.op_keylist_all(sender, 1): + if sigkey.can_sign: + c.signers_add(sigkey) + if not c.signers_enum(0): + self.error = 'No key for signing [%s]' % sender + return False + c.set_passphrase_cb(lambda x, y, z: sign_passphrase) + try: + # make a signature + c.op_sign(plain, sig, mode.DETACH) + sig.seek(0, 0) + # make it part of the email + payload = MIMEMultipart('signed', + boundary=None, + _subparts=None, + **dict(micalg="pgp-sha1", + protocol="application/pgp-signature")) + # insert the origin payload + payload.attach(payload_in) + # insert the detached signature + p = MIMEBase("application", 'pgp-signature') + p.set_payload(sig.read()) + payload.attach(p) + # it's just a trick to handle the no encryption case + payload_in = payload + except errors.GPGMEError as ex: + self.error = "GPG error: %s" % ex.getstring() + return False + ############################################ + # encrypt # + ############################################ + if encrypt: + core.check_version(None) + plain = core.Data(payload_in.as_string()) + cipher = core.Data() + c = core.Context() + c.set_armor(1) + # collect the public keys for encryption + recipients = [] + rec = to[:] + if cc: + rec.extend(cc) + if bcc: + rec.extend(bcc) + for addr in rec: + c.op_keylist_start(addr, 0) + r = c.op_keylist_next() + if r is None: + self.error = 'No key for [%s]' % addr + return False + recipients.append(r) + try: + # make the encryption + c.op_encrypt(recipients, 1, plain, cipher) + cipher.seek(0, 0) + # make it a part of the email + payload = MIMEMultipart('encrypted', + boundary=None, + _subparts=None, + **dict(protocol="application/pgp-encrypted")) + p = MIMEBase("application", 'pgp-encrypted') + p.set_payload("Version: 1\r\n") + payload.attach(p) + p = MIMEBase("application", 'octet-stream') + p.set_payload(cipher.read()) + payload.attach(p) + except errors.GPGMEError as ex: + self.error = "GPG error: %s" % ex.getstring() + return False + ####################################################### + # X.509 # + ####################################################### + elif cipher_type == 'x509': + if not sign and not encrypt: + self.error = "No sign and no encrypt is set but cipher type to x509" + return False + import os + x509_sign_keyfile = x509_sign_keyfile or self.settings.x509_sign_keyfile + + x509_sign_chainfile = x509_sign_chainfile or self.settings.x509_sign_chainfile + + x509_sign_certfile = x509_sign_certfile or self.settings.x509_sign_certfile or \ + x509_sign_keyfile or self.settings.x509_sign_certfile + + # crypt certfiles could be a string or a list + x509_crypt_certfiles = x509_crypt_certfiles or self.settings.x509_crypt_certfiles + + x509_nocerts = x509_nocerts or\ + self.settings.x509_nocerts + + # need m2crypto + try: + from M2Crypto import BIO, SMIME, X509 + except Exception as e: + self.error = "Can't load M2Crypto module" + return False + msg_bio = BIO.MemoryBuffer(payload_in.as_string()) + s = SMIME.SMIME() + + # SIGN + if sign: + # key for signing + try: + keyfile_bio = BIO.openfile(x509_sign_keyfile)\ + if os.path.isfile(x509_sign_keyfile)\ + else BIO.MemoryBuffer(x509_sign_keyfile) + sign_certfile_bio = BIO.openfile(x509_sign_certfile)\ + if os.path.isfile(x509_sign_certfile)\ + else BIO.MemoryBuffer(x509_sign_certfile) + s.load_key_bio(keyfile_bio, sign_certfile_bio, + callback=lambda x: sign_passphrase) + if x509_sign_chainfile: + sk = X509.X509_Stack() + chain = X509.load_cert(x509_sign_chainfile)\ + if os.path.isfile(x509_sign_chainfile)\ + else X509.load_cert_string(x509_sign_chainfile) + sk.push(chain) + s.set_x509_stack(sk) + except Exception as e: + self.error = "Something went wrong on certificate / private key loading: <%s>" % str(e) + return False + try: + if x509_nocerts: + flags = SMIME.PKCS7_NOCERTS + else: + flags = 0 + if not encrypt: + flags += SMIME.PKCS7_DETACHED + p7 = s.sign(msg_bio, flags=flags) + msg_bio = BIO.MemoryBuffer(payload_in.as_string( + )) # Recreate coz sign() has consumed it. + except Exception as e: + self.error = "Something went wrong on signing: <%s> %s" % ( + str(e), str(flags)) + return False + + # ENCRYPT + if encrypt: + try: + sk = X509.X509_Stack() + if not isinstance(x509_crypt_certfiles, (list, tuple)): + x509_crypt_certfiles = [x509_crypt_certfiles] + + # make an encryption cert's stack + for crypt_certfile in x509_crypt_certfiles: + certfile = X509.load_cert(crypt_certfile)\ + if os.path.isfile(crypt_certfile)\ + else X509.load_cert_string(crypt_certfile) + sk.push(certfile) + s.set_x509_stack(sk) + + s.set_cipher(SMIME.Cipher('des_ede3_cbc')) + tmp_bio = BIO.MemoryBuffer() + if sign: + s.write(tmp_bio, p7) + else: + tmp_bio.write(payload_in.as_string()) + p7 = s.encrypt(tmp_bio) + except Exception as e: + self.error = "Something went wrong on encrypting: <%s>" % str(e) + return False + + # Final stage in sign and encryption + out = BIO.MemoryBuffer() + if encrypt: + s.write(out, p7) + else: + if sign: + s.write(out, p7, msg_bio, SMIME.PKCS7_DETACHED) + else: + out.write('\r\n') + out.write(payload_in.as_string()) + out.close() + st = str(out.read()) + payload = message_from_string(st) + else: + # no cryptography process as usual + payload = payload_in + + if from_address: + payload['From'] = encoded_or_raw(to_unicode(from_address, encoding)) + else: + payload['From'] = encoded_or_raw(to_unicode(sender, encoding)) + origTo = to[:] + if to: + payload['To'] = encoded_or_raw(to_unicode(', '.join(to), encoding)) + if reply_to: + payload['Reply-To'] = encoded_or_raw(to_unicode(reply_to, encoding)) + if cc: + payload['Cc'] = encoded_or_raw(to_unicode(', '.join(cc), encoding)) + to.extend(cc) + if bcc: + to.extend(bcc) + payload['Subject'] = encoded_or_raw(to_unicode(subject, encoding)) + payload['Date'] = email.utils.formatdate() + for k, v in iteritems(headers): + payload[k] = encoded_or_raw(to_unicode(v, encoding)) + result = {} + try: + if self.settings.server == 'logging': + entry = 'email not sent\n%s\nFrom: %s\nTo: %s\nSubject: %s\n\n%s\n%s\n' % \ + ('-' * 40, sender, ', '.join(to), subject, text or html, '-' * 40) + logger.warning(entry) + elif self.settings.server.startswith('logging:'): + entry = 'email not sent\n%s\nFrom: %s\nTo: %s\nSubject: %s\n\n%s\n%s\n' % \ + ('-' * 40, sender, ', '.join(to), subject, text or html, '-' * 40) + open(self.settings.server[8:], 'a').write(entry) + elif self.settings.server == 'gae': + xcc = dict() + if cc: + xcc['cc'] = cc + if bcc: + xcc['bcc'] = bcc + if reply_to: + xcc['reply_to'] = reply_to + from google.appengine.api import mail + attachments = attachments and [mail.Attachment( + a.my_filename, + a.my_payload, + content_id='' % k + ) for k, a in enumerate(attachments) if not raw] + if attachments: + result = mail.send_mail( + sender=sender, to=origTo, + subject=to_unicode(subject, encoding), + body=to_unicode(text or '', encoding), + html=html, + attachments=attachments, **xcc) + elif html and (not raw): + result = mail.send_mail( + sender=sender, to=origTo, + subject=to_unicode(subject, encoding), body=to_unicode(text or '', encoding), html=html, **xcc) + else: + result = mail.send_mail( + sender=sender, to=origTo, + subject=to_unicode(subject, encoding), body=to_unicode(text or '', encoding), **xcc) + elif self.settings.server == 'aws': + import boto3 + from botocore.exceptions import ClientError + client = boto3.client('ses') + try: + raw = {'Data': payload.as_string()} + response = client.send_raw_email(RawMessage=raw, + Source=sender, + Destinations=to) + return True + except ClientError as e: + # we should log this error: + # print e.response['Error']['Message'] + return False + else: + smtp_args = self.settings.server.split(':') + kwargs = dict(timeout=self.settings.timeout) + func = smtplib.SMTP_SSL if self.settings.ssl else smtplib.SMTP + server = func(*smtp_args, **kwargs) + try: + if self.settings.tls and not self.settings.ssl: + server.ehlo(self.settings.hostname) + server.starttls() + server.ehlo(self.settings.hostname) + if self.settings.login: + server.login(*self.settings.login.split(':', 1)) + result = server.sendmail(sender, to, payload.as_string()) + finally: + server.quit() + except Exception as e: + logger.warning('Mail.send failure:%s' % e) + self.result = result + self.error = e + return False + self.result = result + self.error = None + return True + + +class Recaptcha2(DIV): + """ + Experimental: + Creates a DIV holding the newer Recaptcha from Google (v2) + + Args: + request : the request. If not passed, uses current request + public_key : the public key Google gave you + private_key : the private key Google gave you + error_message : the error message to show if verification fails + label : the label to use + options (dict) : takes these parameters + + - hl + - theme + - type + - tabindex + - callback + - expired-callback + + see https://developers.google.com/recaptcha/docs/display for docs about those + + comment : the comment + + Examples: + Use as:: + + form = FORM(Recaptcha2(public_key='...', private_key='...')) + + or:: + + form = SQLFORM(...) + form.append(Recaptcha2(public_key='...', private_key='...')) + + to protect the login page instead, use:: + + from gluon.tools import Recaptcha2 + auth.settings.captcha = Recaptcha2(request, public_key='...', private_key='...') + + """ + + API_URI = 'https://www.google.com/recaptcha/api.js' + VERIFY_SERVER = 'https://www.google.com/recaptcha/api/siteverify' + + def __init__(self, + request=None, + public_key='', + private_key='', + error_message='invalid', + label='Verify:', + options=None, + comment='', + ): + request = request or current.request + self.request_vars = request and request.vars or current.request.vars + self.remote_addr = request.env.remote_addr + self.public_key = public_key + self.private_key = private_key + self.errors = Storage() + self.error_message = error_message + self.components = [] + self.attributes = {} + self.label = label + self.options = options or {} + self.comment = comment + + def _validate(self): + recaptcha_response_field = self.request_vars.pop('g-recaptcha-response', None) + remoteip = self.remote_addr + if not recaptcha_response_field: + self.errors['captcha'] = self.error_message + return False + params = urlencode({ + 'secret': self.private_key, + 'remoteip': remoteip, + 'response': recaptcha_response_field, + }) + request = urllib2.Request( + url=self.VERIFY_SERVER, + data=params, + headers={'Content-type': 'application/x-www-form-urlencoded', + 'User-agent': 'reCAPTCHA Python'}) + httpresp = urllib2.urlopen(request) + content = httpresp.read() + httpresp.close() + try: + response_dict = json.loads(content) + except: + self.errors['captcha'] = self.error_message + return False + if response_dict.get('success', False): + self.request_vars.captcha = '' + return True + else: + self.errors['captcha'] = self.error_message + return False + + def xml(self): + api_uri = self.API_URI + hl = self.options.pop('hl', None) + if hl: + api_uri = self.API_URI + '?hl=%s' % hl + public_key = self.public_key + self.options['sitekey'] = public_key + captcha = DIV( + SCRIPT(_src=api_uri, _async='', _defer=''), + DIV(_class="g-recaptcha", data=self.options), + TAG.noscript(XML(""" +
    +
    +
    + +
    +
    + +
    +
    +
    """ % dict(public_key=public_key)) + ) + ) + if not self.errors.captcha: + return XML(captcha).xml() + else: + captcha.append(DIV(self.errors['captcha'], _class='error')) + return XML(captcha).xml() + + +# this should only be used for captcha and perhaps not even for that +def addrow(form, a, b, c, style, _id, position=-1): + if style == "divs": + form[0].insert(position, DIV(DIV(LABEL(a), _class='w2p_fl'), + DIV(b, _class='w2p_fw'), + DIV(c, _class='w2p_fc'), + _id=_id)) + elif style == "table2cols": + form[0].insert(position, TR(TD(LABEL(a), _class='w2p_fl'), + TD(c, _class='w2p_fc'))) + form[0].insert(position + 1, TR(TD(b, _class='w2p_fw'), + _colspan=2, _id=_id)) + elif style == "ul": + form[0].insert(position, LI(DIV(LABEL(a), _class='w2p_fl'), + DIV(b, _class='w2p_fw'), + DIV(c, _class='w2p_fc'), + _id=_id)) + elif style == "bootstrap": + form[0].insert(position, DIV(LABEL(a, _class='control-label'), + DIV(b, SPAN(c, _class='inline-help'), + _class='controls'), + _class='control-group', _id=_id)) + elif style == "bootstrap3_inline": + form[0].insert(position, DIV(LABEL(a, _class='control-label col-sm-3'), + DIV(b, SPAN(c, _class='help-block'), + _class='col-sm-9'), + _class='form-group', _id=_id)) + elif style == "bootstrap3_stacked": + form[0].insert(position, DIV(LABEL(a, _class='control-label'), + b, SPAN(c, _class='help-block'), + _class='form-group', _id=_id)) + else: + form[0].insert(position, TR(TD(LABEL(a), _class='w2p_fl'), + TD(b, _class='w2p_fw'), + TD(c, _class='w2p_fc'), _id=_id)) + + +class AuthJWT(object): + """ + Experimental! + + Args: + - secret_key: the secret. Without salting, an attacker knowing this can impersonate + any user + - algorithm : uses as they are in the JWT specs, HS256, HS384 or HS512 basically means + signing with HMAC with a 256, 284 or 512bit hash + - verify_expiration : verifies the expiration checking the exp claim + - leeway: allow n seconds of skew when checking for token expiration + - expiration : how many seconds a token may be valid + - allow_refresh: enable the machinery to get a refreshed token passing a not-already-expired + token + - refresh_expiration_delta: to avoid continous refresh of the token + - header_prefix : self-explanatory. "JWT" and "Bearer" seems to be the emerging standards + - jwt_add_header: a dict holding additional mappings to the header. by default only alg and typ are filled + - user_param: the name of the parameter holding the username when requesting a token. Can be useful, e.g, for + email-based authentication, with "email" as a parameter + - pass_param: same as above, but for the password + - realm: self-explanatory + - salt: can be static or a function that takes the payload as an argument. + Example: + def mysalt(payload): + return payload['hmac_key'].split('-')[0] + - additional_payload: can be a dict to merge with the payload or a function that takes + the payload as input and returns the modified payload + Example: + def myadditional_payload(payload): + payload['my_name_is'] = 'bond,james bond' + return payload + - before_authorization: can be a callable that takes the deserialized token (a dict) as input. + Gets called right after signature verification but before the actual + authorization takes place. It may be use to cast + the extra auth_user fields to their actual types. + You can raise with HTTP a proper error message + Example: + def mybefore_authorization(tokend): + if not tokend['my_name_is'] == 'bond,james bond': + raise HTTP(400, u'Invalid JWT my_name_is claim') + - max_header_length: check max length to avoid load()ing unusually large tokens (could mean crafted, e.g. in a DDoS.) + + Basic Usage: + in models (or the controller needing it) + + myjwt = AuthJWT(auth, secret_key='secret') + + in the controller issuing tokens + + def login_and_take_token(): + return myjwt.jwt_token_manager() + + A call then to /app/controller/login_and_take_token with username and password returns the token + A call to /app/controller/login_and_take_token with the original token returns the refreshed token + + To protect a function with JWT + + @myjwt.allows_jwt() + @auth.requires_login() + def protected(): + return '%s$%s' % (request.now, auth.user_id) + + To inject optional auth info into the action with JWT + @myjwt.allows_jwt() + def unprotected(): + if auth.user: + return '%s$%s' % (request.now, auth.user_id) + + return "No auth info!" + + + """ + + def __init__(self, + auth, + secret_key, + algorithm='HS256', + verify_expiration=True, + leeway=30, + expiration=60 * 5, + allow_refresh=True, + refresh_expiration_delta=60 * 60, + header_prefix='Bearer', + jwt_add_header=None, + user_param='username', + pass_param='password', + realm='Login required', + salt=None, + additional_payload=None, + before_authorization=None, + max_header_length=4 * 1024, + ): + self.secret_key = secret_key + self.auth = auth + self.algorithm = algorithm + if self.algorithm not in ('HS256', 'HS384', 'HS512'): + raise NotImplementedError('Algorithm %s not allowed' % algorithm) + self.verify_expiration = verify_expiration + self.leeway = leeway + self.expiration = expiration + self.allow_refresh = allow_refresh + self.refresh_expiration_delta = refresh_expiration_delta + self.header_prefix = header_prefix + self.jwt_add_header = jwt_add_header or {} + base_header = {'alg': self.algorithm, 'typ': 'JWT'} + for k, v in iteritems(self.jwt_add_header): + base_header[k] = v + self.cached_b64h = self.jwt_b64e(json.dumps(base_header)) + digestmod_mapping = { + 'HS256': hashlib.sha256, + 'HS384': hashlib.sha384, + 'HS512': hashlib.sha512 + } + self.digestmod = digestmod_mapping[algorithm] + self.user_param = user_param + self.pass_param = pass_param + self.realm = realm + self.salt = salt + self.additional_payload = additional_payload + self.before_authorization = before_authorization + self.max_header_length = max_header_length + self.recvd_token = None + + @staticmethod + def jwt_b64e(string): + string = to_bytes(string) + return base64.urlsafe_b64encode(string).strip(b'=') + + @staticmethod + def jwt_b64d(string): + """base64 decodes a single bytestring (and is tolerant to getting + called with a unicode string). + The result is also a bytestring. + """ + string = to_bytes(string, 'ascii', 'ignore') + return base64.urlsafe_b64decode(string + b'=' * (-len(string) % 4)) + + def generate_token(self, payload): + secret = to_bytes(self.secret_key) + if self.salt: + if callable(self.salt): + secret = "%s$%s" % (secret, self.salt(payload)) + else: + secret = "%s$%s" % (secret, self.salt) + if isinstance(secret, unicodeT): + secret = secret.encode('ascii', 'ignore') + b64h = self.cached_b64h + b64p = self.jwt_b64e(serializers.json(payload)) + jbody = b64h + b'.' + b64p + mauth = hmac.new(key=secret, msg=jbody, digestmod=self.digestmod) + jsign = self.jwt_b64e(mauth.digest()) + return to_native(jbody + b'.' + jsign) + + def verify_signature(self, body, signature, secret): + mauth = hmac.new(key=secret, msg=body, digestmod=self.digestmod) + return compare(self.jwt_b64e(mauth.digest()), signature) + + def load_token(self, token): + token = to_bytes(token, 'utf-8', 'strict') + body, sig = token.rsplit(b'.', 1) + b64h, b64b = body.split(b'.', 1) + if b64h != self.cached_b64h: + # header not the same + raise HTTP(400, u'Invalid JWT Header') + secret = self.secret_key + tokend = serializers.loads_json(to_native(self.jwt_b64d(b64b))) + if self.salt: + if callable(self.salt): + secret = "%s$%s" % (secret, self.salt(tokend)) + else: + secret = "%s$%s" % (secret, self.salt) + secret = to_bytes(secret, 'ascii', 'ignore') + if not self.verify_signature(body, sig, secret): + # signature verification failed + raise HTTP(400, u'Token signature is invalid') + if self.verify_expiration: + now = time.mktime(datetime.datetime.utcnow().timetuple()) + if tokend['exp'] + self.leeway < now: + raise HTTP(400, u'Token is expired') + if callable(self.before_authorization): + self.before_authorization(tokend) + return tokend + + def serialize_auth_session(self, session_auth): + """ + As bad as it sounds, as long as this is rarely used (vs using the token) + this is the faster method, even if we ditch session in jwt_token_manager(). + We (mis)use the heavy default auth mechanism to avoid any further computation, + while sticking to a somewhat-stable Auth API. + """ + # TODO: Check the following comment + # is the following safe or should we use + # calendar.timegm(datetime.datetime.utcnow().timetuple()) + # result seem to be the same (seconds since epoch, in UTC) + now = time.mktime(datetime.datetime.utcnow().timetuple()) + expires = now + self.expiration + payload = dict( + hmac_key=session_auth['hmac_key'], + user_groups=session_auth['user_groups'], + user=session_auth['user'].as_dict(), + iat=now, + exp=expires + ) + return payload + + def refresh_token(self, orig_payload): + now = time.mktime(datetime.datetime.utcnow().timetuple()) + if self.verify_expiration: + orig_exp = orig_payload['exp'] + if orig_exp + self.leeway < now: + # token already expired, can't be used for refresh + raise HTTP(400, u'Token already expired') + orig_iat = orig_payload.get('orig_iat') or orig_payload['iat'] + if orig_iat + self.refresh_expiration_delta < now: + # refreshed too long ago + raise HTTP(400, u'Token issued too long ago') + expires = now + self.expiration + orig_payload.update( + orig_iat=orig_iat, + iat=now, + exp=expires, + hmac_key=web2py_uuid() + ) + self.alter_payload(orig_payload) + return orig_payload + + def alter_payload(self, payload): + if self.additional_payload: + if callable(self.additional_payload): + payload = self.additional_payload(payload) + elif isinstance(self.additional_payload, dict): + payload.update(self.additional_payload) + return payload + + def jwt_token_manager(self, token_param='_token'): + """ + The part that issues (and refreshes) tokens. + Used in a controller, given myjwt is the istantiated class, as + + @myjwt.allow_jwt(required=False, verify_expiration=False) + def api_auth(): + return myjwt.jwt_token_manager() + + Then, a call to /app/c/api_auth with username and password + returns a token, while /app/c/api_auth with the current token + issues another token (expired, but within grace time) + """ + request = current.request + response = current.response + session = current.session + # forget and unlock response + session.forget(response) + valid_user = None + ret = None + token = None + try: + token = self.recvd_token or self.get_jwt_token_from_request(token_param) + except HTTP: + pass + if token: + if not self.allow_refresh: + raise HTTP(403, u'Refreshing token is not allowed') + tokend = self.load_token(token) + # verification can fail here + refreshed = self.refresh_token(tokend) + ret = {'token': self.generate_token(refreshed)} + elif self.user_param in request.vars and self.pass_param in request.vars: + username = request.vars[self.user_param] + password = request.vars[self.pass_param] + valid_user = self.auth.login_bare(username, password) + else: + valid_user = self.auth.user + self.auth.login_user(valid_user) + if valid_user: + payload = self.serialize_auth_session(session.auth) + self.alter_payload(payload) + ret = {'token': self.generate_token(payload)} + elif ret is None: + raise HTTP(401, + u'Not Authorized - need to be logged in, to pass a token ' + u'for refresh or username and password for login', + **{'WWW-Authenticate': u'JWT realm="%s"' % self.realm}) + response.headers['Content-Type'] = 'application/json' + return serializers.json(ret) + + def inject_token(self, tokend): + """ + The real deal, not touching the db but still logging-in the user + """ + self.auth.user = Storage(tokend['user']) + self.auth.user_groups = tokend['user_groups'] + self.auth.hmac_key = tokend['hmac_key'] + + def get_jwt_token_from_request(self, token_param='_token'): + """ + The method that extracts and validates the token, either + from the header or the _token var + + token_param: request.vars attribute with the token used only if the http authorization header is not present. + """ + token = None + token_in_header = current.request.env.http_authorization + if token_in_header: + parts = token_in_header.split() + if parts[0].lower() != self.header_prefix.lower(): + raise HTTP(400, u'Invalid JWT header') + elif len(parts) == 1: + raise HTTP(400, u'Invalid JWT header, missing token') + elif len(parts) > 2: + raise HTTP(400, 'Invalid JWT header, token contains spaces') + token = parts[1] + else: + token = current.request.vars.get(token_param) + if token is None: + raise HTTP(400, 'JWT header not found and JWT parameter {} missing in request'.format(token_param)) + + self.recvd_token = token + return token + + def allows_jwt(self, otherwise=None, required=True, verify_expiration=True, token_param='_token'): + """ + The decorator that takes care of injecting auth info in the decorated action. + Works w/o resorting to session. + + Args: + + required: the token is mandatory (either in request.var._token or in the HTTP hearder Authorization Bearer) + verify_expiration: allows to bypass expiration check. Useful to manage token renewal. + token_param: request.vars attribute with the token used only if the http authorization header is not present (default: "_token"). + + """ + def decorator(action): + def f(*args, **kwargs): + try: + token = self.get_jwt_token_from_request(token_param=token_param) + except HTTP as e: + if required: + raise e + token = None + if token and len(token) < self.max_header_length: + old_verify_expiration = self.verify_expiration + try: + self.verify_expiration = verify_expiration + tokend = self.load_token(token) + except ValueError: + raise HTTP(400, 'Invalid JWT header, wrong token format') + finally: + self.verify_expiration = old_verify_expiration + self.inject_token(tokend) + + return action(*args, **kwargs) + + f.__doc__ = action.__doc__ + f.__name__ = action.__name__ + f.__dict__.update(action.__dict__) + return f + + return decorator + + +class Auth(AuthAPI): + + default_settings = dict(AuthAPI.default_settings, + allow_basic_login=False, + allow_basic_login_only=False, + allow_delete_accounts=False, + alternate_requires_registration=False, + auth_manager_role=None, + auth_two_factor_enabled=False, + auth_two_factor_tries_left=3, + bulk_register_enabled=False, + captcha=None, + cas_maps=None, + client_side=True, + formstyle=None, + hideerror=False, + label_separator=None, + login_after_password_change=True, + login_after_registration=False, + login_captcha=None, + long_expiration=3600 * 30 * 24, # one month + mailer=None, + manager_actions={}, + multi_login=False, + on_failed_authentication=lambda x: redirect(x), + pre_registration_div=None, + prevent_open_redirect_attacks=True, + prevent_password_reset_attacks=True, + profile_fields=None, + register_captcha=None, + register_fields=None, + register_verify_password=True, + remember_me_form=True, + reset_password_requires_verification=False, + retrieve_password_captcha=None, + retrieve_username_captcha=None, + showid=False, + table_cas=None, + table_cas_name='auth_cas', + table_event=None, + table_group=None, + table_membership=None, + table_permission=None, + table_token_name='auth_token', + table_user=None, + two_factor_authentication_group=None, + update_fields=['email'], + wiki=Settings() + ) + # ## these are messages that can be customized + default_messages = dict(AuthAPI.default_messages, + access_denied='Insufficient privileges', + bulk_invite_body='You have been invited to join %(site)s, click %(link)s to complete ' + 'the process', + bulk_invite_subject='Invitation to join %(site)s', + delete_label='Check to delete', + email_sent='Email sent', + email_verified='Email verified', + function_disabled='Function disabled', + impersonate_log='User %(id)s is impersonating %(other_id)s', + invalid_reset_password='Invalid reset password', + invalid_two_factor_code='Incorrect code. {0} more attempt(s) remaining.', + is_empty="Cannot be empty", + label_client_ip='Client IP', + label_description='Description', + label_email='E-mail', + label_first_name='First name', + label_group_id='Group ID', + label_last_name='Last name', + label_name='Name', + label_origin='Origin', + label_password='Password', + label_record_id='Record ID', + label_registration_id='Registration identifier', + label_registration_key='Registration key', + label_remember_me="Remember me (for 30 days)", + label_reset_password_key='Reset Password key', + label_role='Role', + label_table_name='Object or table name', + label_time_stamp='Timestamp', + label_two_factor='Authentication code', + label_user_id='User ID', + label_username='Username', + login_button='Log In', + login_disabled='Login disabled by administrator', + new_password='New password', + new_password_sent='A new password was emailed to you', + old_password='Old password', + password_change_button='Change password', + password_reset_button='Request reset password', + profile_save_button='Apply changes', + register_button='Sign Up', + reset_password='Click on the link %(link)s to reset your password', + reset_password_log='User %(id)s Password reset', + reset_password_subject='Password reset', + retrieve_password='Your password is: %(password)s', + retrieve_password_log='User %(id)s Password retrieved', + retrieve_password_subject='Password retrieve', + retrieve_two_factor_code='Your temporary login code is {0}', + retrieve_two_factor_code_subject='Two-step Login Authentication Code', + retrieve_username='Your username is: %(username)s', + retrieve_username_log='User %(id)s Username retrieved', + retrieve_username_subject='Username retrieve', + submit_button='Submit', + two_factor_comment='This code was emailed to you and is required for login.', + unable_send_email='Unable to send email', + username_sent='Your username was emailed to you', + verify_email='Welcome %(username)s! Click on the link %(link)s to verify your email', + verify_email_log='User %(id)s Verification email sent', + verify_email_subject='Email verification', + verify_password='Verify Password', + verify_password_comment='please input your password again' + ) + """ + Class for authentication, authorization, role based access control. + + Includes: + + - registration and profile + - login and logout + - username and password retrieval + - event logging + - role creation and assignment + - user defined group/role based permission + + Args: + + environment: is there for legacy but unused (awful) + db: has to be the database where to create tables for authentication + mailer: `Mail(...)` or None (no mailer) or True (make a mailer) + hmac_key: can be a hmac_key or hmac_key=Auth.get_or_create_key() + controller: (where is the user action?) + cas_provider: (delegate authentication to the URL, CAS2) + + Authentication Example:: + + from gluon.contrib.utils import * + mail=Mail() + mail.settings.server='smtp.gmail.com:587' + mail.settings.sender='you@somewhere.com' + mail.settings.login='username:password' + auth=Auth(db) + auth.settings.mailer=mail + # auth.settings....=... + auth.define_tables() + def authentication(): + return dict(form=auth()) + + Exposes: + + - `http://.../{application}/{controller}/authentication/login` + - `http://.../{application}/{controller}/authentication/logout` + - `http://.../{application}/{controller}/authentication/register` + - `http://.../{application}/{controller}/authentication/verify_email` + - `http://.../{application}/{controller}/authentication/retrieve_username` + - `http://.../{application}/{controller}/authentication/retrieve_password` + - `http://.../{application}/{controller}/authentication/reset_password` + - `http://.../{application}/{controller}/authentication/profile` + - `http://.../{application}/{controller}/authentication/change_password` + + On registration a group with role=new_user.id is created + and user is given membership of this group. + + You can create a group with:: + + group_id=auth.add_group('Manager', 'can access the manage action') + auth.add_permission(group_id, 'access to manage') + + Here "access to manage" is just a user defined string. + You can give access to a user:: + + auth.add_membership(group_id, user_id) + + If user id is omitted, the logged in user is assumed + + Then you can decorate any action:: + + @auth.requires_permission('access to manage') + def manage(): + return dict() + + You can restrict a permission to a specific table:: + + auth.add_permission(group_id, 'edit', db.sometable) + @auth.requires_permission('edit', db.sometable) + + Or to a specific record:: + + auth.add_permission(group_id, 'edit', db.sometable, 45) + @auth.requires_permission('edit', db.sometable, 45) + + If authorization is not granted calls:: + + auth.settings.on_failed_authorization + + Other options:: + + auth.settings.mailer=None + auth.settings.expiration=3600 # seconds + + ... + + ### these are messages that can be customized + ... + + """ + + @staticmethod + def get_or_create_key(filename=None, alg='sha512'): + request = current.request + if not filename: + filename = os.path.join(request.folder, 'private', 'auth.key') + if os.path.exists(filename): + key = open(filename, 'r').read().strip() + else: + key = alg + ':' + web2py_uuid() + open(filename, 'w').write(key) + return key + + def url(self, f=None, args=None, vars=None, scheme=False): + if args is None: + args = [] + if vars is None: + vars = {} + host = scheme and self.settings.host + return URL(c=self.settings.controller, + f=f, args=args, vars=vars, scheme=scheme, host=host) + + def here(self): + return URL(args=current.request.args, vars=current.request.get_vars) + + def select_host(self, host, host_names=None): + """ + checks that host is valid, i.e. in the list of glob host_names + if the host is missing, then is it selects the first entry from host_names + read more here: https://github.com/web2py/web2py/issues/1196 + """ + if host: + if host_names: + for item in host_names: + if fnmatch.fnmatch(host, item): + break + else: + raise HTTP(403, "Invalid Hostname") + elif host_names: + host = host_names[0] + else: + host = 'localhost' + return host + + def __init__(self, environment=None, db=None, mailer=True, + hmac_key=None, controller='default', function='user', + cas_provider=None, signature=True, secure=False, + csrf_prevention=True, propagate_extension=None, + url_index=None, jwt=None, host_names=None): + + # next two lines for backward compatibility + if not db and environment and isinstance(environment, DAL): + db = environment + self.db = db + self.environment = current + self.csrf_prevention = csrf_prevention + request = current.request + session = current.session + auth = session.auth + self.user_groups = auth and auth.user_groups or {} + if secure: + request.requires_https() + now = request.now + # if we have auth info + # if not expired it, used it + # if expired, clear the session + # else, only clear auth info in the session + if auth: + delta = datetime.timedelta(days=0, seconds=auth.expiration) + if auth.last_visit and auth.last_visit + delta > now: + self.user = auth.user + # this is a trick to speed up sessions to avoid many writes + if (now - auth.last_visit).seconds > (auth.expiration // 10): + auth.last_visit = now + else: + self.user = None + if session.auth: + del session.auth + session.renew(clear_session=True) + else: + self.user = None + if session.auth: + del session.auth + # ## what happens after login? + + url_index = url_index or URL(controller, 'index') + url_login = URL(controller, function, args='login', + extension=propagate_extension) + # ## what happens after registration? + + settings = self.settings = Settings() + settings.update(Auth.default_settings) + host = self.select_host(request.env.http_host, host_names) + settings.update( + cas_domains=[host], + enable_tokens=False, + cas_provider=cas_provider, + cas_actions=dict(login='login', + validate='validate', + servicevalidate='serviceValidate', + proxyvalidate='proxyValidate', + logout='logout'), + cas_create_user=True, + extra_fields={}, + actions_disabled=[], + controller=controller, + function=function, + login_url=url_login, + logged_url=URL(controller, function, args='profile'), + download_url=URL(controller, 'download'), + mailer=(mailer is True) and Mail() or mailer, + on_failed_authorization=URL(controller, function, args='not_authorized'), + login_next=url_index, + login_onvalidation=[], + login_onaccept=[], + login_onfail=[], + login_methods=[self], + login_form=self, + logout_next=url_index, + logout_onlogout=None, + register_next=url_index, + register_onvalidation=[], + register_onaccept=[], + verify_email_next=url_login, + verify_email_onaccept=[], + profile_next=url_index, + profile_onvalidation=[], + profile_onaccept=[], + retrieve_username_next=url_index, + retrieve_password_next=url_index, + request_reset_password_next=url_login, + reset_password_next=url_index, + change_password_next=url_index, + change_password_onvalidation=[], + change_password_onaccept=[], + retrieve_password_onvalidation=[], + request_reset_password_onvalidation=[], + request_reset_password_onaccept=[], + reset_password_onvalidation=[], + reset_password_onaccept=[], + hmac_key=hmac_key, + formstyle=current.response.formstyle, + label_separator=current.response.form_label_separator, + two_factor_methods=[], + two_factor_onvalidation=[], + host=host, + ) + settings.lock_keys = True + # ## these are messages that can be customized + messages = self.messages = Messages(current.T) + messages.update(Auth.default_messages) + messages.update(ajax_failed_authentication= + DIV(H4('NOT AUTHORIZED'), + 'Please ', + A('login', + _href=self.settings.login_url + + ('?_next=' + urllib_quote(current.request.env.http_web2py_component_location)) + if current.request.env.http_web2py_component_location else ''), + ' to view this content.', + _class='not-authorized alert alert-block')) + messages.lock_keys = True + + # for "remember me" option + response = current.response + if auth and auth.remember_me: + # when user wants to be logged in for longer + response.session_cookie_expires = auth.expiration + if signature: + self.define_signature() + else: + self.signature = None + self.jwt_handler = jwt and AuthJWT(self, **jwt) + + def get_vars_next(self): + next = current.request.vars._next + host = current.request.env.http_host + if isinstance(next, (list, tuple)): + next = next[0] + if next and self.settings.prevent_open_redirect_attacks: + return self.prevent_open_redirect(next, host) + return next or None + + @staticmethod + def prevent_open_redirect(next, host): + # Prevent an attacker from adding an arbitrary url after the + # _next variable in the request. + if next: + parts = next.split('/') + if ':' not in parts[0]: + return next + elif len(parts) > 2 and parts[0].endswith(':') and parts[1:3] == ['', host]: + return next + return None + + def table_cas(self): + return self.db[self.settings.table_cas_name] + + def table_token(self): + return self.db[self.settings.table_token_name] + + def _HTTP(self, *a, **b): + """ + only used in lambda: self._HTTP(404) + """ + + raise HTTP(*a, **b) + + def __call__(self): + """ + Example: + Use as:: + + def authentication(): + return dict(form=auth()) + + """ + + request = current.request + args = request.args + if not args: + redirect(self.url(args='login', vars=request.vars)) + elif args[0] in self.settings.actions_disabled: + raise HTTP(404) + if args[0] in ('login', 'logout', 'register', 'verify_email', + 'retrieve_username', 'retrieve_password', + 'reset_password', 'request_reset_password', + 'change_password', 'profile', 'groups', + 'impersonate', 'not_authorized', 'confirm_registration', + 'bulk_register', 'manage_tokens', 'jwt'): + if len(request.args) >= 2 and args[0] == 'impersonate': + return getattr(self, args[0])(request.args[1]) + else: + return getattr(self, args[0])() + elif args[0] == 'cas' and not self.settings.cas_provider: + if args(1) == self.settings.cas_actions['login']: + return self.cas_login(version=2) + elif args(1) == self.settings.cas_actions['validate']: + return self.cas_validate(version=1) + elif args(1) == self.settings.cas_actions['servicevalidate']: + return self.cas_validate(version=2, proxy=False) + elif args(1) == self.settings.cas_actions['proxyvalidate']: + return self.cas_validate(version=2, proxy=True) + elif (args(1) == 'p3' + and args(2) == self.settings.cas_actions['servicevalidate']): + return self.cas_validate(version=3, proxy=False) + elif (args(1) == 'p3' + and args(2) == self.settings.cas_actions['proxyvalidate']): + return self.cas_validate(version=3, proxy=True) + elif args(1) == self.settings.cas_actions['logout']: + return self.logout(next=request.vars.service or DEFAULT) + else: + raise HTTP(404) + + def navbar(self, prefix='Welcome', action=None, + separators=(' [ ', ' | ', ' ] '), user_identifier=DEFAULT, + referrer_actions=DEFAULT, mode='default'): + """ Navbar with support for more templates + This uses some code from the old navbar. + + Args: + mode: see options for list of + + """ + items = [] # Hold all menu items in a list + self.bar = '' # The final + T = current.T + referrer_actions = [] if not referrer_actions else referrer_actions + if not action: + action = self.url(self.settings.function) + + request = current.request + if URL() == action: + next = '' + else: + next = '?_next=' + urllib_quote(URL(args=request.args, + vars=request.get_vars)) + href = lambda function: \ + '%s/%s%s' % (action, function, next if referrer_actions is DEFAULT or function in referrer_actions else '') + if isinstance(prefix, str): + prefix = T(prefix) + if prefix: + prefix = prefix.strip() + ' ' + + def Anr(*a, **b): + b['_rel'] = 'nofollow' + return A(*a, **b) + + if self.user_id: # User is logged in + logout_next = self.settings.logout_next + items.append({'name': T('Log Out'), + 'href': '%s/logout?_next=%s' % (action, urllib_quote(logout_next)), + 'icon': 'icon-off'}) + if 'profile' not in self.settings.actions_disabled: + items.append({'name': T('Profile'), 'href': href('profile'), + 'icon': 'icon-user'}) + if 'change_password' not in self.settings.actions_disabled: + items.append({'name': T('Password'), + 'href': href('change_password'), + 'icon': 'icon-lock'}) + + if user_identifier is DEFAULT: + user_identifier = '%(first_name)s' + if callable(user_identifier): + user_identifier = user_identifier(self.user) + elif ((isinstance(user_identifier, str) or + type(user_identifier).__name__ == 'lazyT') and + re.search(r'%\(.+\)s', user_identifier)): + user_identifier = user_identifier % self.user + if not user_identifier: + user_identifier = '' + else: # User is not logged in + items.append({'name': T('Log In'), 'href': href('login'), + 'icon': 'icon-off'}) + if 'register' not in self.settings.actions_disabled: + items.append({'name': T('Sign Up'), 'href': href('register'), + 'icon': 'icon-user'}) + if 'request_reset_password' not in self.settings.actions_disabled: + items.append({'name': T('Lost password?'), + 'href': href('request_reset_password'), + 'icon': 'icon-lock'}) + if self.settings.use_username and 'retrieve_username' not in self.settings.actions_disabled: + items.append({'name': T('Forgot username?'), + 'href': href('retrieve_username'), + 'icon': 'icon-edit'}) + + def menu(): # For inclusion in MENU + self.bar = [(items[0]['name'], False, items[0]['href'], [])] + del items[0] + for item in items: + self.bar[0][3].append((item['name'], False, item['href'])) + + def bootstrap3(): # Default web2py scaffolding + def rename(icon): return icon + ' ' + icon.replace('icon', 'glyphicon') + self.bar = UL(LI(Anr(I(_class=rename('icon ' + items[0]['icon'])), + ' ' + items[0]['name'], + _href=items[0]['href'])), _class='dropdown-menu') + del items[0] + for item in items: + self.bar.insert(-1, LI(Anr(I(_class=rename('icon ' + item['icon'])), + ' ' + item['name'], + _href=item['href']))) + self.bar.insert(-1, LI('', _class='divider')) + if self.user_id: + self.bar = LI(Anr(prefix, user_identifier, + _href='#', _class="dropdown-toggle", + data={'toggle': 'dropdown'}), + self.bar, _class='dropdown') + else: + self.bar = LI(Anr(T('Log In'), + _href='#', _class="dropdown-toggle", + data={'toggle': 'dropdown'}), self.bar, + _class='dropdown') + + def bare(): + """ In order to do advanced customization we only need the + prefix, the user_identifier and the href attribute of items + + Examples: + Use as:: + + # in module custom_layout.py + from gluon import * + def navbar(auth_navbar): + bar = auth_navbar + user = bar["user"] + + if not user: + btn_login = A(current.T("Login"), + _href=bar["login"], + _class="btn btn-success", + _rel="nofollow") + btn_register = A(current.T("Sign up"), + _href=bar["register"], + _class="btn btn-primary", + _rel="nofollow") + return DIV(btn_register, btn_login, _class="btn-group") + else: + toggletext = "%s back %s" % (bar["prefix"], user) + toggle = A(toggletext, + _href="#", + _class="dropdown-toggle", + _rel="nofollow", + **{"_data-toggle": "dropdown"}) + li_profile = LI(A(I(_class="icon-user"), ' ', + current.T("Account details"), + _href=bar["profile"], _rel="nofollow")) + li_custom = LI(A(I(_class="icon-book"), ' ', + current.T("My Agenda"), + _href="#", rel="nofollow")) + li_logout = LI(A(I(_class="icon-off"), ' ', + current.T("logout"), + _href=bar["logout"], _rel="nofollow")) + dropdown = UL(li_profile, + li_custom, + LI('', _class="divider"), + li_logout, + _class="dropdown-menu", _role="menu") + + return LI(toggle, dropdown, _class="dropdown") + + # in models db.py + import custom_layout as custom + + # in layout.html + + + """ + bare = {'prefix': prefix, 'user': user_identifier if self.user_id else None} + + for i in items: + if i['name'] == T('Log In'): + k = 'login' + elif i['name'] == T('Sign Up'): + k = 'register' + elif i['name'] == T('Lost password?'): + k = 'request_reset_password' + elif i['name'] == T('Forgot username?'): + k = 'retrieve_username' + elif i['name'] == T('Log Out'): + k = 'logout' + elif i['name'] == T('Profile'): + k = 'profile' + elif i['name'] == T('Password'): + k = 'change_password' + + bare[k] = i['href'] + + self.bar = bare + + options = {'asmenu': menu, + 'dropdown': bootstrap3, + 'bare': bare + } # Define custom modes. + + if mode in options and callable(options[mode]): + options[mode]() + else: + s1, s2, s3 = separators + if self.user_id: + self.bar = SPAN(prefix, user_identifier, s1, + Anr(items[0]['name'], + _href=items[0]['href']), s3, + _class='auth_navbar') + else: + self.bar = SPAN(s1, Anr(items[0]['name'], + _href=items[0]['href']), s3, + _class='auth_navbar') + for item in items[1:]: + self.bar.insert(-1, s2) + self.bar.insert(-1, Anr(item['name'], _href=item['href'])) + + return self.bar + + def enable_record_versioning(self, + tables, + archive_db=None, + archive_names='%(tablename)s_archive', + current_record='current_record', + current_record_label=None): + """ + Used to enable full record versioning (including auth tables):: + + auth = Auth(db) + auth.define_tables(signature=True) + # define our own tables + db.define_table('mything',Field('name'),auth.signature) + auth.enable_record_versioning(tables=db) + + tables can be the db (all table) or a list of tables. + only tables with modified_by and modified_on fiels (as created + by auth.signature) will have versioning. Old record versions will be + in table 'mything_archive' automatically defined. + + when you enable enable_record_versioning, records are never + deleted but marked with is_active=False. + + enable_record_versioning enables a common_filter for + every table that filters out records with is_active = False + + Note: + If you use auth.enable_record_versioning, + do not use auth.archive or you will end up with duplicates. + auth.archive does explicitly what enable_record_versioning + does automatically. + + """ + current_record_label = current_record_label or current.T( + current_record.replace('_', ' ').title()) + for table in tables: + fieldnames = table.fields() + if 'id' in fieldnames and 'modified_on' in fieldnames and current_record not in fieldnames: + table._enable_record_versioning(archive_db=archive_db, + archive_name=archive_names, + current_record=current_record, + current_record_label=current_record_label) + + def define_tables(self, username=None, signature=None, enable_tokens=False, + migrate=None, fake_migrate=None): + """ + To be called unless tables are defined manually + + Examples: + Use as:: + + # defines all needed tables and table files + # 'myprefix_auth_user.table', ... + auth.define_tables(migrate='myprefix_') + + # defines all needed tables without migration/table files + auth.define_tables(migrate=False) + + """ + + db = self.db + if migrate is None: + migrate = db._migrate + if fake_migrate is None: + fake_migrate = db._fake_migrate + settings = self.settings + settings.enable_tokens = enable_tokens + signature_list = \ + super(Auth, self).define_tables(username, signature, migrate, fake_migrate)._table_signature_list + + now = current.request.now + reference_table_user = 'reference %s' % settings.table_user_name + if settings.cas_domains: + if settings.table_cas_name not in db.tables: + db.define_table( + settings.table_cas_name, + Field('user_id', reference_table_user, default=None, + label=self.messages.label_user_id), + Field('created_on', 'datetime', default=now), + Field('service', requires=IS_URL()), + Field('ticket'), + Field('renew', 'boolean', default=False), + *settings.extra_fields.get(settings.table_cas_name, []), + **dict( + migrate=self._get_migrate( + settings.table_cas_name, migrate), + fake_migrate=fake_migrate)) + if settings.enable_tokens: + extra_fields = settings.extra_fields.get( + settings.table_token_name, []) + signature_list + if settings.table_token_name not in db.tables: + db.define_table( + settings.table_token_name, + Field('user_id', reference_table_user, default=None, + label=self.messages.label_user_id), + Field('expires_on', 'datetime', default=datetime.datetime(2999, 12, 31)), + Field('token', writable=False, default=web2py_uuid, unique=True), + *extra_fields, + **dict(migrate=self._get_migrate(settings.table_token_name, migrate), + fake_migrate=fake_migrate)) + if not db._lazy_tables: + settings.table_user = db[settings.table_user_name] + settings.table_group = db[settings.table_group_name] + settings.table_membership = db[settings.table_membership_name] + settings.table_permission = db[settings.table_permission_name] + settings.table_event = db[settings.table_event_name] + if settings.cas_domains: + settings.table_cas = db[settings.table_cas_name] + + if settings.cas_provider: # THIS IS NOT LAZY + settings.actions_disabled = \ + ['profile', 'register', 'change_password', + 'request_reset_password', 'retrieve_username'] + from gluon.contrib.login_methods.cas_auth import CasAuth + maps = settings.cas_maps + if not maps: + table_user = self.table_user() + maps = dict((name, lambda v, n=name: v.get(n, None)) for name in + table_user.fields if name != 'id' + and table_user[name].readable) + maps['registration_id'] = \ + lambda v, p=settings.cas_provider: '%s/%s' % (p, v['user']) + actions = [settings.cas_actions['login'], + settings.cas_actions['servicevalidate'], + settings.cas_actions['logout']] + settings.login_form = CasAuth( + casversion=2, + urlbase=settings.cas_provider, + actions=actions, + maps=maps) + return self + + def get_or_create_user(self, keys, update_fields=['email'], + login=True, get=True): + """ + Used for alternate login methods: + If the user exists already then password is updated. + If the user doesn't yet exist, then they are created. + """ + table_user = self.table_user() + create_user = self.settings.cas_create_user + user = None + checks = [] + # make a guess about who this user is + guess_fields = ['registration_id', 'username', 'email'] + if self.settings.login_userfield: + guess_fields.append(self.settings.login_userfield) + for fieldname in guess_fields: + if fieldname in table_user.fields() and \ + keys.get(fieldname, None): + checks.append(fieldname) + value = keys[fieldname] + user = table_user(**{fieldname: value}) + if user: + break + if not checks: + return None + if 'registration_id' not in keys: + keys['registration_id'] = keys[checks[0]] + # if we think we found the user but registration_id does not match, + # make new user + if 'registration_id' in checks \ + and user \ + and user.registration_id \ + and ('registration_id' not in keys or user.registration_id != str(keys['registration_id'])): + user = None # THINK MORE ABOUT THIS? DO WE TRUST OPENID PROVIDER? + if user: + if not get: + # added for register_bare to avoid overwriting users + return None + update_keys = dict(registration_id=keys['registration_id']) + for key in update_fields: + if key in keys: + update_keys[key] = keys[key] + user.update_record(**update_keys) + elif checks: + if create_user is False: + # Remove current open session a send message + self.logout(next=None, onlogout=None, log=None) + raise HTTP(403, "Forbidden. User need to be created first.") + + if 'first_name' not in keys and 'first_name' in table_user.fields: + guess = keys.get('email', 'anonymous').split('@')[0] + keys['first_name'] = keys.get('username', guess) + vars = table_user._filter_fields(keys) + user_id = table_user.insert(**vars) + user = table_user[user_id] + if self.settings.create_user_groups: + group_id = self.add_group(self.settings.create_user_groups % user) + self.add_membership(group_id, user_id) + if self.settings.everybody_group_id: + self.add_membership(self.settings.everybody_group_id, user_id) + if login: + self.user = user + if self.settings.register_onaccept: + callback(self.settings.register_onaccept, Storage(vars=user)) + return user + + def basic(self, basic_auth_realm=False): + """ + Performs basic login. + + Args: + basic_auth_realm: optional basic http authentication realm. Can take + str or unicode or function or callable or boolean. + + reads current.request.env.http_authorization + and returns basic_allowed,basic_accepted,user. + + if basic_auth_realm is defined is a callable it's return value + is used to set the basic authentication realm, if it's a string + its content is used instead. Otherwise basic authentication realm + is set to the application name. + If basic_auth_realm is None or False (the default) the behavior + is to skip sending any challenge. + + """ + if not self.settings.allow_basic_login: + return (False, False, False) + basic = current.request.env.http_authorization + if basic_auth_realm: + if callable(basic_auth_realm): + basic_auth_realm = basic_auth_realm() + elif isinstance(basic_auth_realm, (unicode, str)): + basic_realm = unicode(basic_auth_realm) # Warning python 3.5 does not have method unicod + elif basic_auth_realm is True: + basic_realm = u'' + current.request.application + http_401 = HTTP(401, u'Not Authorized', **{'WWW-Authenticate': u'Basic realm="' + basic_realm + '"'}) + if not basic or not basic[:6].lower() == 'basic ': + if basic_auth_realm: + raise http_401 + return (True, False, False) + (username, sep, password) = base64.b64decode(basic[6:]).partition(':') + is_valid_user = sep and self.login_bare(username, password) + if not is_valid_user and basic_auth_realm: + raise http_401 + return (True, True, is_valid_user) + + def _get_login_settings(self): + table_user = self.table_user() + userfield = self.settings.login_userfield or 'username' \ + if self.settings.login_userfield or 'username' \ + in table_user.fields else 'email' + passfield = self.settings.password_field + return Storage({'table_user': table_user, + 'userfield': userfield, + 'passfield': passfield}) + + def login_bare(self, username, password): + """ + Logins user as specified by username (or email) and password + """ + settings = self._get_login_settings() + user = settings.table_user(**{settings.userfield: username}) + if user and user.get(settings.passfield, False): + password = settings.table_user[ + settings.passfield].validate(password)[0] + if ((user.registration_key is None or + not user.registration_key.strip()) and + password == user[settings.passfield]): + self.login_user(user) + return user + else: + # user not in database try other login methods + for login_method in self.settings.login_methods: + if login_method != self and login_method(username, password): + self.user = user + return user + return False + + def register_bare(self, **fields): + """ + Registers a user as specified by username (or email) + and a raw password. + """ + settings = self._get_login_settings() + # users can register_bare even if no password is provided, + # in this case they will have to reset their password to login + if fields.get(settings.passfield): + fields[settings.passfield] = \ + settings.table_user[settings.passfield].validate(fields[settings.passfield])[0] + if not fields.get(settings.userfield): + raise ValueError('register_bare: userfield not provided or invalid') + user = self.get_or_create_user(fields, login=False, get=False, + update_fields=self.settings.update_fields) + if not user: + # get or create did not create a user (it ignores duplicate records) + return False + return user + + def cas_login(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + version=2, + ): + request = current.request + response = current.response + session = current.session + db, table = self.db, self.table_cas() + session._cas_service = request.vars.service or session._cas_service + if request.env.http_host not in self.settings.cas_domains or \ + not session._cas_service: + raise HTTP(403, 'not authorized') + + def allow_access(interactivelogin=False): + row = table(service=session._cas_service, user_id=self.user.id) + if row: + ticket = row.ticket + else: + ticket = 'ST-' + web2py_uuid() + table.insert(service=session._cas_service, + user_id=self.user.id, + ticket=ticket, + created_on=request.now, + renew=interactivelogin) + service = session._cas_service + query_sep = '&' if '?' in service else '?' + del session._cas_service + if 'warn' in request.vars and not interactivelogin: + response.headers[ + 'refresh'] = "5;URL=%s" % service + query_sep + "ticket=" + ticket + return A("Continue to %s" % service, + _href=service + query_sep + "ticket=" + ticket) + else: + redirect(service + query_sep + "ticket=" + ticket) + if self.is_logged_in() and 'renew' not in request.vars: + return allow_access() + elif not self.is_logged_in() and 'gateway' in request.vars: + redirect(session._cas_service) + + def cas_onaccept(form, onaccept=onaccept): + if onaccept is not DEFAULT: + onaccept(form) + return allow_access(interactivelogin=True) + return self.login(next, onvalidation, cas_onaccept, log) + + def cas_validate(self, version=2, proxy=False): + request = current.request + db, table = self.db, self.table_cas() + current.response.headers['Content-Type'] = 'text' + ticket = request.vars.ticket + renew = 'renew' in request.vars + row = table(ticket=ticket) + success = False + if row: + userfield = self.settings.login_userfield or 'username' \ + if 'username' in table.fields else 'email' + # If ticket is a service Ticket and RENEW flag respected + if ticket[0:3] == 'ST-' and \ + not ((row.renew and renew) ^ renew): + user = self.table_user()(row.user_id) + row.delete_record() + success = True + + def build_response(body): + xml_body = to_native(TAG['cas:serviceResponse']( + body, **{'_xmlns:cas': 'http://www.yale.edu/tp/cas'}).xml()) + return '\n' + xml_body + if success: + if version == 1: + message = 'yes\n%s' % user[userfield] + elif version == 3: + username = user.get('username', user[userfield]) + message = build_response( + TAG['cas:authenticationSuccess']( + TAG['cas:user'](username), + TAG['cas:attributes']( + *[TAG['cas:' + field.name](user[field.name]) + for field in self.table_user() + if field.readable]))) + else: # assume version 2 + username = user.get('username', user[userfield]) + message = build_response( + TAG['cas:authenticationSuccess']( + TAG['cas:user'](username), + *[TAG['cas:' + field.name](user[field.name]) + for field in self.table_user() + if field.readable])) + else: + if version == 1: + message = 'no\n' + elif row: + message = build_response(TAG['cas:authenticationFailure']()) + else: + message = build_response( + TAG['cas:authenticationFailure']( + 'Ticket %s not recognized' % ticket, + _code='INVALID TICKET')) + raise HTTP(200, message) + + def _reset_two_factor_auth(self, session): + """ + When two-step authentication is enabled, this function is used to + clear the session after successfully completing second challenge + or when the maximum number of tries allowed has expired. + """ + session.auth_two_factor_user = None + session.auth_two_factor = None + session.auth_two_factor_enabled = False + # Set the number of attempts. It should be more than 1. + session.auth_two_factor_tries_left = self.settings.auth_two_factor_tries_left + + def when_is_logged_in_bypass_next_in_url(self, next, session): + """ + This function should be use when someone want to avoid asking for user + credentials when loaded page contains "user/login?_next=NEXT_COMPONENT" + in the URL is refresh but user is already authenticated. + """ + if self.is_logged_in(): + if next == session._auth_next: + del session._auth_next + redirect(next, client_side=self.settings.client_side) + + def login(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): + """ + Returns a login form + """ + settings = self.settings + request = current.request + response = current.response + session = current.session + + # use session for federated login + snext = self.get_vars_next() + + if snext: + session._auth_next = snext + elif session._auth_next: + snext = session._auth_next + # pass + + if next is DEFAULT: + # important for security + next = settings.login_next + if callable(next): + next = next() + user_next = snext + if user_next: + external = user_next.split('://') + if external[0].lower() in ['http', 'https', 'ftp']: + host_next = user_next.split('//', 1)[-1].split('/')[0] + if host_next in settings.cas_domains: + next = user_next + else: + next = user_next + # Avoid asking unnecessary user credentials when user is logged in + self.when_is_logged_in_bypass_next_in_url(next=next, session=session) + + # Moved here to avoid unnecessary execution in case of redirection to next in case of logged in user + table_user = self.table_user() + if 'username' in table_user.fields or \ + not settings.login_email_validate: + tmpvalidator = IS_NOT_EMPTY(error_message=self.messages.is_empty) + if not settings.username_case_sensitive: + tmpvalidator = [IS_LOWER(), tmpvalidator] + else: + tmpvalidator = IS_EMAIL(error_message=self.messages.invalid_email) + if not settings.email_case_sensitive: + tmpvalidator = [IS_LOWER(), tmpvalidator] + + passfield = settings.password_field + try: + table_user[passfield].requires[-1].min_length = 0 + except: + pass + + if onvalidation is DEFAULT: + onvalidation = settings.login_onvalidation + if onaccept is DEFAULT: + onaccept = settings.login_onaccept + if log is DEFAULT: + log = self.messages['login_log'] + + onfail = settings.login_onfail + + user = None # default + + # Setup the default field used for the form + multi_login = False + if self.settings.login_userfield: + username = self.settings.login_userfield + else: + if 'username' in table_user.fields: + username = 'username' + else: + username = 'email' + if self.settings.multi_login: + multi_login = True + old_requires = table_user[username].requires + table_user[username].requires = tmpvalidator + + # If two-factor authentication is enabled, and the maximum + # number of tries allowed is used up, reset the session to + # pre-login state with two-factor auth + if session.auth_two_factor_enabled and session.auth_two_factor_tries_left < 1: + # Exceeded maximum allowed tries for this code. Require user to enter + # username and password again. + user = None + accepted_form = False + self._reset_two_factor_auth(session) + # Redirect to the default 'next' page without logging + # in. If that page requires login, user will be redirected + # back to the main login form + redirect(next, client_side=settings.client_side) + + # Before showing the default login form, check whether + # we are already on the second step of two-step authentication. + # If we are, then skip this login form and use the form for the + # second challenge instead. + # Note to devs: The code inside the if-block is unchanged from the + # previous version of this file, other than for indentation inside + # to put it inside the if-block + if session.auth_two_factor_user is None: + + if settings.remember_me_form: + extra_fields = [ + Field('remember_me', 'boolean', default=False, + label=self.messages.label_remember_me)] + else: + extra_fields = [] + + # do we use our own login form, or from a central source? + if settings.login_form == self: + form = SQLFORM(table_user, + fields=[username, passfield], + hidden=dict(_next=next), + showid=settings.showid, + submit_button=self.messages.login_button, + delete_label=self.messages.delete_label, + formstyle=settings.formstyle, + separator=settings.label_separator, + extra_fields=extra_fields, + ) + + captcha = settings.login_captcha or \ + (settings.login_captcha is not False and settings.captcha) + if captcha: + addrow(form, captcha.label, captcha, captcha.comment, + settings.formstyle, 'captcha__row') + accepted_form = False + + if form.accepts(request, session if self.csrf_prevention else None, + formname='login', dbio=False, + onvalidation=onvalidation, + hideerror=settings.hideerror): + + accepted_form = True + # check for username in db + entered_username = form.vars[username] + if multi_login and '@' in entered_username: + # if '@' in username check for email, not username + user = table_user(email=entered_username) + else: + user = table_user(**{username: entered_username}) + if user: + # user in db, check if registration pending or disabled + temp_user = user + if (temp_user.registration_key or '').startswith('pending'): + response.flash = self.messages.registration_pending + return form + elif temp_user.registration_key in ('disabled', 'blocked'): + response.flash = self.messages.login_disabled + return form + elif (temp_user.registration_key is not None and temp_user.registration_key.strip()): + response.flash = \ + self.messages.registration_verifying + return form + # try alternate logins 1st as these have the + # current version of the password + user = None + for login_method in settings.login_methods: + if login_method != self and \ + login_method(request.vars[username], + request.vars[passfield]): + if self not in settings.login_methods: + # do not store password in db + form.vars[passfield] = None + user = self.get_or_create_user( + form.vars, settings.update_fields) + break + if not user: + # alternates have failed, maybe because service inaccessible + if settings.login_methods[0] == self: + # try logging in locally using cached credentials + if form.vars.get(passfield, '') == temp_user[passfield]: + # success + user = temp_user + else: + # user not in db + if not settings.alternate_requires_registration: + # we're allowed to auto-register users from external systems + for login_method in settings.login_methods: + if login_method != self and \ + login_method(request.vars[username], + request.vars[passfield]): + if self not in settings.login_methods: + # do not store password in db + form.vars[passfield] = None + user = self.get_or_create_user( + form.vars, settings.update_fields) + break + if not user: + self.log_event(self.messages['login_failed_log'], + request.post_vars) + # invalid login + session.flash = self.messages.invalid_login + callback(onfail, None) + redirect( + self.url(args=request.args, vars=request.get_vars), + client_side=settings.client_side) + + else: # use a central authentication server + cas = settings.login_form + cas_user = cas.get_user() + + if cas_user: + cas_user[passfield] = None + user = self.get_or_create_user( + table_user._filter_fields(cas_user), + settings.update_fields) + elif hasattr(cas, 'login_form'): + return cas.login_form() + else: + # we need to pass through login again before going on + next = self.url(settings.function, args='login') + redirect(cas.login_url(next), + client_side=settings.client_side) + + # Extra login logic for two-factor authentication + ################################################# + # If the 'user' variable has a value, this means that the first + # authentication step was successful (i.e. user provided correct + # username and password at the first challenge). + # Check if this user is signed up for two-factor authentication + # If auth.settings.auth_two_factor_enabled it will enable two factor + # for all the app. Another way to anble two factor is that the user + # must be part of a group that is called auth.settings.two_factor_authentication_group + if user and self.settings.auth_two_factor_enabled is True: + session.auth_two_factor_enabled = True + elif user and self.settings.two_factor_authentication_group: + role = self.settings.two_factor_authentication_group + session.auth_two_factor_enabled = self.has_membership(user_id=user.id, role=role) + # challenge + if session.auth_two_factor_enabled: + form = SQLFORM.factory( + Field('authentication_code', + label=self.messages.label_two_factor, + required=True, + comment=self.messages.two_factor_comment), + hidden=dict(_next=next), + formstyle=settings.formstyle, + separator=settings.label_separator + ) + # accepted_form is used by some default web2py code later in the + # function that handles running specified functions before redirect + # Set it to False until the challenge form is accepted. + accepted_form = False + # Handle the case when a user has submitted the login/password + # form successfully, and the password has been validated, but + # the two-factor form has not been displayed or validated yet. + if session.auth_two_factor_user is None and user is not None: + session.auth_two_factor_user = user # store the validated user and associate with this session + session.auth_two_factor = random.randint(100000, 999999) + session.auth_two_factor_tries_left = self.settings.auth_two_factor_tries_left + # Set the way we generate the code or we send the code. For example using SMS... + two_factor_methods = self.settings.two_factor_methods + + if not two_factor_methods: + # TODO: Add some error checking to handle cases where email cannot be sent + self.settings.mailer.send( + to=user.email, + subject=self.messages.retrieve_two_factor_code_subject, + message=self.messages.retrieve_two_factor_code.format(session.auth_two_factor)) + else: + # Check for all method. It is possible to have multiples + for two_factor_method in two_factor_methods: + try: + # By default we use session.auth_two_factor generated before. + session.auth_two_factor = two_factor_method(user, session.auth_two_factor) + except: + pass + else: + break + + if form.accepts(request, session if self.csrf_prevention else None, + formname='login', dbio=False, + onvalidation=onvalidation, + hideerror=settings.hideerror): + accepted_form = True + + """ + The lists is executed after form validation for each of the corresponding action. + For example, in your model: + + In your models copy and paste: + + # Before define tables, we add some extra field to auth_user + auth.settings.extra_fields['auth_user'] = [ + Field('motp_secret', 'password', length=512, default='', label='MOTP Secret'), + Field('motp_pin', 'string', length=128, default='', label='MOTP PIN')] + + OFFSET = 60 # Be sure is the same in your OTP Client + + # Set session.auth_two_factor to None. Because the code is generated by external app. + # This will avoid to use the default setting and send a code by email. + def _set_two_factor(user, auth_two_factor): + return None + + def verify_otp(user, otp): + import time + from hashlib import md5 + epoch_time = int(time.time()) + time_start = int(str(epoch_time - OFFSET)[:-1]) + time_end = int(str(epoch_time + OFFSET)[:-1]) + for t in range(time_start - 1, time_end + 1): + to_hash = str(t) + user.motp_secret + user.motp_pin + hash = md5(to_hash).hexdigest()[:6] + if otp == hash: + return hash + + auth.settings.auth_two_factor_enabled = True + auth.messages.two_factor_comment = "Verify your OTP Client for the code." + auth.settings.two_factor_methods = [lambda user, + auth_two_factor: _set_two_factor(user, auth_two_factor)] + auth.settings.two_factor_onvalidation = [lambda user, otp: verify_otp(user, otp)] + + """ + if self.settings.two_factor_onvalidation: + + for two_factor_onvalidation in self.settings.two_factor_onvalidation: + try: + session.auth_two_factor = \ + two_factor_onvalidation(session.auth_two_factor_user, form.vars['authentication_code']) + except: + pass + else: + break + + if form.vars['authentication_code'] == str(session.auth_two_factor): + # Handle the case when the two-factor form has been successfully validated + # and the user was previously stored (the current user should be None because + # in this case, the previous username/password login form should not be displayed. + # This will allow the code after the 2-factor authentication block to proceed as + # normal. + if user is None or user == session.auth_two_factor_user: + user = session.auth_two_factor_user + # For security, because the username stored in the + # session somehow does not match the just validated + # user. Should not be possible without session stealing + # which is hard with SSL. + elif user != session.auth_two_factor_user: + user = None + # Either way, the user and code associated with this session should + # be removed. This handles cases where the session login may have + # expired but browser window is open, so the old session key and + # session usernamem will still exist + self._reset_two_factor_auth(session) + else: + session.auth_two_factor_tries_left -= 1 + # If the number of retries are higher than auth_two_factor_tries_left + # Require user to enter username and password again. + if session.auth_two_factor_enabled and session.auth_two_factor_tries_left < 1: + # Exceeded maximum allowed tries for this code. Require user to enter + # username and password again. + user = None + accepted_form = False + self._reset_two_factor_auth(session) + # Redirect to the default 'next' page without logging + # in. If that page requires login, user will be redirected + # back to the main login form + redirect(next, client_side=settings.client_side) + response.flash = self.messages.invalid_two_factor_code.format(session.auth_two_factor_tries_left) + return form + else: + return form + # End login logic for two-factor authentication + + # process authenticated users + if user: + user = Row(table_user._filter_fields(user, id=True)) + # process authenticated users + # user wants to be logged in for longer + self.login_user(user) + session.auth.expiration = \ + request.post_vars.remember_me and \ + settings.long_expiration or \ + settings.expiration + session.auth.remember_me = 'remember_me' in request.post_vars + self.log_event(log, user) + session.flash = self.messages.logged_in + + # how to continue + if settings.login_form == self: + if accepted_form: + callback(onaccept, form) + if next == session._auth_next: + session._auth_next = None + next = replace_id(next, form) + redirect(next, client_side=settings.client_side) + + table_user[username].requires = old_requires + return form + elif user: + callback(onaccept, None) + + if next == session._auth_next: + del session._auth_next + redirect(next, client_side=settings.client_side) + + def logout(self, next=DEFAULT, onlogout=DEFAULT, log=DEFAULT): + """ + Logouts and redirects to login + """ + + # Clear out 2-step authentication information if user logs + # out. This information is also cleared on successful login. + self._reset_two_factor_auth(current.session) + + if next is DEFAULT: + next = self.get_vars_next() or self.settings.logout_next + if onlogout is DEFAULT: + onlogout = self.settings.logout_onlogout + if onlogout: + onlogout(self.user) + if log is DEFAULT: + log = self.messages['logout_log'] + if self.user: + self.log_event(log, self.user) + if self.settings.login_form != self: + cas = self.settings.login_form + cas_user = cas.get_user() + if cas_user: + next = cas.logout_url(next) + + current.session.auth = None + self.user = None + if self.settings.renew_session_onlogout: + current.session.renew(clear_session=not self.settings.keep_session_onlogout) + current.session.flash = self.messages.logged_out + if next is not None: + redirect(next) + + def logout_bare(self): + self.logout(next=None, onlogout=None, log=None) + + def register(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): + """ + Returns a registration form + """ + + table_user = self.table_user() + request = current.request + response = current.response + session = current.session + if self.is_logged_in(): + redirect(self.settings.logged_url, + client_side=self.settings.client_side) + if next is DEFAULT: + next = self.get_vars_next() or self.settings.register_next + if onvalidation is DEFAULT: + onvalidation = self.settings.register_onvalidation + if onaccept is DEFAULT: + onaccept = self.settings.register_onaccept + if log is DEFAULT: + log = self.messages['register_log'] + + table_user = self.table_user() + if self.settings.login_userfield: + username = self.settings.login_userfield + elif 'username' in table_user.fields: + username = 'username' + else: + username = 'email' + + # Ensure the username field is unique. + unique_validator = IS_NOT_IN_DB(self.db, table_user[username]) + if not table_user[username].requires: + table_user[username].requires = unique_validator + elif isinstance(table_user[username].requires, (list, tuple)): + if not any([isinstance(validator, IS_NOT_IN_DB) for validator in + table_user[username].requires]): + if isinstance(table_user[username].requires, list): + table_user[username].requires.append(unique_validator) + else: + table_user[username].requires += (unique_validator, ) + elif not isinstance(table_user[username].requires, IS_NOT_IN_DB): + table_user[username].requires = [table_user[username].requires, + unique_validator] + + passfield = self.settings.password_field + formstyle = self.settings.formstyle + try: # Make sure we have our original minimum length as other auth forms change it + table_user[passfield].requires[-1].min_length = self.settings.password_min_length + except: + pass + + if self.settings.register_verify_password: + if self.settings.register_fields is None: + self.settings.register_fields = [f.name for f in table_user if f.writable and not f.compute] + k = self.settings.register_fields.index(passfield) + self.settings.register_fields.insert(k + 1, "password_two") + extra_fields = [ + Field("password_two", "password", + requires=IS_EQUAL_TO(request.post_vars.get(passfield, None), + error_message=self.messages.mismatched_password), + label=current.T("Confirm Password"))] + else: + extra_fields = [] + form = SQLFORM(table_user, + fields=self.settings.register_fields, + hidden=dict(_next=next), + showid=self.settings.showid, + submit_button=self.messages.register_button, + delete_label=self.messages.delete_label, + formstyle=formstyle, + separator=self.settings.label_separator, + extra_fields=extra_fields + ) + + captcha = self.settings.register_captcha or self.settings.captcha + if captcha: + addrow(form, captcha.label, captcha, + captcha.comment, self.settings.formstyle, 'captcha__row') + + # Add a message if specified + if self.settings.pre_registration_div: + addrow(form, '', + DIV(_id="pre-reg", *self.settings.pre_registration_div), + '', formstyle, '') + + key = web2py_uuid() + if self.settings.registration_requires_approval: + key = 'pending-' + key + + table_user.registration_key.default = key + if form.accepts(request, session if self.csrf_prevention else None, + formname='register', + onvalidation=onvalidation, + hideerror=self.settings.hideerror): + description = self.messages.group_description % form.vars + if self.settings.create_user_groups: + group_id = self.add_group(self.settings.create_user_groups % form.vars, description) + self.add_membership(group_id, form.vars.id) + if self.settings.everybody_group_id: + self.add_membership(self.settings.everybody_group_id, form.vars.id) + if self.settings.registration_requires_verification: + link = self.url( + self.settings.function, args=('verify_email', key), scheme=True) + d = dict(form.vars) + d.update(dict(key=key, link=link, username=form.vars[username], + firstname=form.vars['firstname'], + lastname=form.vars['lastname'])) + if not (self.settings.mailer and self.settings.mailer.send( + to=form.vars.email, + subject=self.messages.verify_email_subject, + message=self.messages.verify_email % d)): + self.db.rollback() + response.flash = self.messages.unable_send_email + return form + session.flash = self.messages.email_sent + if self.settings.registration_requires_approval and \ + not self.settings.registration_requires_verification: + table_user[form.vars.id] = dict(registration_key='pending') + session.flash = self.messages.registration_pending + elif (not self.settings.registration_requires_verification or self.settings.login_after_registration): + if not self.settings.registration_requires_verification: + table_user[form.vars.id] = dict(registration_key='') + session.flash = self.messages.registration_successful + user = table_user(**{username: form.vars[username]}) + self.login_user(user) + session.flash = self.messages.logged_in + self.log_event(log, form.vars) + callback(onaccept, form) + if not next: + next = self.url(args=request.args) + else: + next = replace_id(next, form) + redirect(next, client_side=self.settings.client_side) + + return form + + def verify_email(self, + next=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): + """ + Action used to verify the registration email + """ + + key = getarg(-1) + table_user = self.table_user() + user = table_user(registration_key=key) + if not user: + redirect(self.settings.login_url) + if self.settings.registration_requires_approval: + user.update_record(registration_key='pending') + current.session.flash = self.messages.registration_pending + else: + user.update_record(registration_key='') + current.session.flash = self.messages.email_verified + # make sure session has same user.registrato_key as db record + if current.session.auth and current.session.auth.user: + current.session.auth.user.registration_key = user.registration_key + if log is DEFAULT: + log = self.messages['verify_email_log'] + if next is DEFAULT: + next = self.settings.verify_email_next + if onaccept is DEFAULT: + onaccept = self.settings.verify_email_onaccept + self.log_event(log, user) + callback(onaccept, user) + redirect(next) + + def retrieve_username(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): + """ + Returns a form to retrieve the user username + (only if there is a username field) + """ + + table_user = self.table_user() + if 'username' not in table_user.fields: + raise HTTP(404) + request = current.request + response = current.response + session = current.session + captcha = self.settings.retrieve_username_captcha or \ + (self.settings.retrieve_username_captcha is not False and self.settings.captcha) + if not self.settings.mailer: + response.flash = self.messages.function_disabled + return '' + if next is DEFAULT: + next = self.get_vars_next() or self.settings.retrieve_username_next + if onvalidation is DEFAULT: + onvalidation = self.settings.retrieve_username_onvalidation + if onaccept is DEFAULT: + onaccept = self.settings.retrieve_username_onaccept + if log is DEFAULT: + log = self.messages['retrieve_username_log'] + old_requires = table_user.email.requires + table_user.email.requires = [IS_IN_DB(self.db, table_user.email, + error_message=self.messages.invalid_email)] + form = SQLFORM(table_user, + fields=['email'], + hidden=dict(_next=next), + showid=self.settings.showid, + submit_button=self.messages.submit_button, + delete_label=self.messages.delete_label, + formstyle=self.settings.formstyle, + separator=self.settings.label_separator + ) + if captcha: + addrow(form, captcha.label, captcha, + captcha.comment, self.settings.formstyle, 'captcha__row') + + if form.accepts(request, session if self.csrf_prevention else None, + formname='retrieve_username', dbio=False, + onvalidation=onvalidation, hideerror=self.settings.hideerror): + users = table_user._db(table_user.email == form.vars.email).select() + if not users: + current.session.flash = \ + self.messages.invalid_email + redirect(self.url(args=request.args)) + username = ', '.join(u.username for u in users) + self.settings.mailer.send(to=form.vars.email, + subject=self.messages.retrieve_username_subject, + message=self.messages.retrieve_username % dict(username=username)) + session.flash = self.messages.email_sent + for user in users: + self.log_event(log, user) + callback(onaccept, form) + if not next: + next = self.url(args=request.args) + else: + next = replace_id(next, form) + redirect(next) + table_user.email.requires = old_requires + return form + + def random_password(self): + import string + import random + password = '' + specials = r'!#$*' + for i in range(0, 3): + password += random.choice(string.ascii_lowercase) + password += random.choice(string.ascii_uppercase) + password += random.choice(string.digits) + password += random.choice(specials) + return ''.join(random.sample(password, len(password))) + + def reset_password_deprecated(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): + """ + Returns a form to reset the user password (deprecated) + """ + + table_user = self.table_user() + request = current.request + response = current.response + session = current.session + if not self.settings.mailer: + response.flash = self.messages.function_disabled + return '' + if next is DEFAULT: + next = self.get_vars_next() or self.settings.retrieve_password_next + if onvalidation is DEFAULT: + onvalidation = self.settings.retrieve_password_onvalidation + if onaccept is DEFAULT: + onaccept = self.settings.retrieve_password_onaccept + if log is DEFAULT: + log = self.messages['retrieve_password_log'] + old_requires = table_user.email.requires + table_user.email.requires = [IS_IN_DB(self.db, table_user.email, + error_message=self.messages.invalid_email)] + form = SQLFORM(table_user, + fields=['email'], + hidden=dict(_next=next), + showid=self.settings.showid, + submit_button=self.messages.submit_button, + delete_label=self.messages.delete_label, + formstyle=self.settings.formstyle, + separator=self.settings.label_separator + ) + if form.accepts(request, session if self.csrf_prevention else None, + formname='retrieve_password', dbio=False, + onvalidation=onvalidation, hideerror=self.settings.hideerror): + user = table_user(email=form.vars.email) + key = user.registration_key + if not user: + current.session.flash = \ + self.messages.invalid_email + redirect(self.url(args=request.args)) + elif key in ('pending', 'disabled', 'blocked') or (key or '').startswith('pending'): + current.session.flash = \ + self.messages.registration_pending + redirect(self.url(args=request.args)) + password = self.random_password() + passfield = self.settings.password_field + d = { + passfield: str(table_user[passfield].validate(password)[0]), + 'registration_key': '' + } + user.update_record(**d) + if self.settings.mailer and \ + self.settings.mailer.send(to=form.vars.email, + subject=self.messages.retrieve_password_subject, + message=self.messages.retrieve_password % dict(password=password)): + session.flash = self.messages.email_sent + else: + session.flash = self.messages.unable_send_email + self.log_event(log, user) + callback(onaccept, form) + if not next: + next = self.url(args=request.args) + else: + next = replace_id(next, form) + redirect(next) + table_user.email.requires = old_requires + return form + + def confirm_registration(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): + """ + Returns a form to confirm user registration + """ + + table_user = self.table_user() + request = current.request + # response = current.response + session = current.session + + if next is DEFAULT: + next = self.get_vars_next() or self.settings.reset_password_next + + if self.settings.prevent_password_reset_attacks: + key = request.vars.key + if not key and len(request.args) > 1: + key = request.args[-1] + if key: + session._reset_password_key = key + if next: + redirect_vars = {'_next': next} + else: + redirect_vars = {} + redirect(self.url(args='confirm_registration', + vars=redirect_vars)) + else: + key = session._reset_password_key + else: + key = request.vars.key or getarg(-1) + try: + t0 = int(key.split('-')[0]) + if time.time() - t0 > 60 * 60 * 24: + raise Exception + user = table_user(reset_password_key=key) + if not user: + raise Exception + except Exception as e: + session.flash = self.messages.invalid_reset_password + redirect(next, client_side=self.settings.client_side) + passfield = self.settings.password_field + form = SQLFORM.factory( + Field('first_name', + label='First Name', + required=True), + Field('last_name', + label='Last Name', + required=True), + Field('new_password', 'password', + label=self.messages.new_password, + requires=self.table_user()[passfield].requires), + Field('new_password2', 'password', + label=self.messages.verify_password, + requires=[IS_EXPR('value==%s' % repr(request.vars.new_password), + self.messages.mismatched_password)]), + submit_button='Confirm Registration', + hidden=dict(_next=next), + formstyle=self.settings.formstyle, + separator=self.settings.label_separator + ) + if form.process().accepted: + user.update_record( + **{passfield: str(form.vars.new_password), + 'first_name': str(form.vars.first_name), + 'last_name': str(form.vars.last_name), + 'registration_key': '', + 'reset_password_key': ''}) + session.flash = self.messages.password_changed + if self.settings.login_after_password_change: + self.login_user(user) + redirect(next, client_side=self.settings.client_side) + return form + + def email_registration(self, subject, body, user): + """ + Sends and email invitation to a user informing they have been registered with the application + """ + reset_password_key = str(int(time.time())) + '-' + web2py_uuid() + link = self.url(self.settings.function, + args=('confirm_registration',), vars={'key': reset_password_key}, + scheme=True) + d = dict(user) + d.update(dict(key=reset_password_key, link=link, site=current.request.env.http_host)) + if self.settings.mailer and self.settings.mailer.send( + to=user.email, + subject=subject % d, + message=body % d): + user.update_record(reset_password_key=reset_password_key) + return True + return False + + def bulk_register(self, max_emails=100): + """ + Creates a form for ther user to send invites to other users to join + """ + if not self.user: + redirect(self.settings.login_url) + if not self.settings.bulk_register_enabled: + return HTTP(404) + + form = SQLFORM.factory( + Field('subject', 'string', default=self.messages.bulk_invite_subject, requires=IS_NOT_EMPTY()), + Field('emails', 'text', requires=IS_NOT_EMPTY()), + Field('message', 'text', default=self.messages.bulk_invite_body, requires=IS_NOT_EMPTY()), + formstyle=self.settings.formstyle) + + if form.process().accepted: + emails = re.compile('[^\s\'"@<>,;:]+\@[^\s\'"@<>,;:]+').findall(form.vars.emails) + # send the invitations + emails_sent = [] + emails_fail = [] + emails_exist = [] + for email in emails[:max_emails]: + if self.table_user()(email=email): + emails_exist.append(email) + else: + user = self.register_bare(email=email) + if self.email_registration(form.vars.subject, form.vars.message, user): + emails_sent.append(email) + else: + emails_fail.append(email) + emails_fail += emails[max_emails:] + form = DIV(H4('Emails sent'), UL(*[A(x, _href='mailto:' + x) for x in emails_sent]), + H4('Emails failed'), UL(*[A(x, _href='mailto:' + x) for x in emails_fail]), + H4('Emails existing'), UL(*[A(x, _href='mailto:' + x) for x in emails_exist])) + return form + + def manage_tokens(self): + if not self.user: + redirect(self.settings.login_url) + table_token = self.table_token() + table_token.user_id.writable = False + table_token.user_id.default = self.user.id + table_token.token.writable = False + if current.request.args(1) == 'new': + table_token.token.readable = False + form = SQLFORM.grid(table_token, args=['manage_tokens']) + return form + + def reset_password(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): + """ + Returns a form to reset the user password + """ + + table_user = self.table_user() + request = current.request + # response = current.response + session = current.session + + if next is DEFAULT: + next = self.get_vars_next() or self.settings.reset_password_next + + if self.settings.prevent_password_reset_attacks: + key = request.vars.key + if key: + session._reset_password_key = key + redirect(self.url(args='reset_password')) + else: + key = session._reset_password_key + else: + key = request.vars.key + try: + t0 = int(key.split('-')[0]) + if time.time() - t0 > 60 * 60 * 24: + raise Exception + user = table_user(reset_password_key=key) + if not user: + raise Exception + except Exception: + session.flash = self.messages.invalid_reset_password + redirect(next, client_side=self.settings.client_side) + + key = user.registration_key + if key in ('pending', 'disabled', 'blocked') or (key or '').startswith('pending'): + session.flash = self.messages.registration_pending + redirect(next, client_side=self.settings.client_side) + + if onvalidation is DEFAULT: + onvalidation = self.settings.reset_password_onvalidation + if onaccept is DEFAULT: + onaccept = self.settings.reset_password_onaccept + + passfield = self.settings.password_field + form = SQLFORM.factory( + Field('new_password', 'password', + label=self.messages.new_password, + requires=self.table_user()[passfield].requires), + Field('new_password2', 'password', + label=self.messages.verify_password, + requires=[IS_EXPR('value==%s' % repr(request.vars.new_password), + self.messages.mismatched_password)]), + submit_button=self.messages.password_reset_button, + hidden=dict(_next=next), + formstyle=self.settings.formstyle, + separator=self.settings.label_separator + ) + if form.accepts(request, session, onvalidation=onvalidation, + hideerror=self.settings.hideerror): + user.update_record( + **{passfield: str(form.vars.new_password), + 'registration_key': '', + 'reset_password_key': ''}) + session.flash = self.messages.password_changed + if self.settings.login_after_password_change: + self.login_user(user) + callback(onaccept, form) + redirect(next, client_side=self.settings.client_side) + return form + + def request_reset_password(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): + """ + Returns a form to reset the user password + """ + table_user = self.table_user() + request = current.request + response = current.response + session = current.session + captcha = self.settings.retrieve_password_captcha or \ + (self.settings.retrieve_password_captcha is not False and self.settings.captcha) + + if next is DEFAULT: + next = self.get_vars_next() or self.settings.request_reset_password_next + if not self.settings.mailer: + response.flash = self.messages.function_disabled + return '' + if onvalidation is DEFAULT: + onvalidation = self.settings.request_reset_password_onvalidation + if onaccept is DEFAULT: + onaccept = self.settings.request_reset_password_onaccept + if log is DEFAULT: + log = self.messages['reset_password_log'] + userfield = self.settings.login_userfield or 'username' \ + if 'username' in table_user.fields else 'email' + if userfield == 'email': + table_user.email.requires = [ + IS_EMAIL(error_message=self.messages.invalid_email), + IS_IN_DB(self.db, table_user.email, + error_message=self.messages.invalid_email)] + if not self.settings.email_case_sensitive: + table_user.email.requires.insert(0, IS_LOWER()) + else: + table_user.username.requires = [ + IS_IN_DB(self.db, table_user.username, + error_message=self.messages.invalid_username)] + if not self.settings.username_case_sensitive: + table_user.username.requires.insert(0, IS_LOWER()) + + form = SQLFORM(table_user, + fields=[userfield], + hidden=dict(_next=next), + showid=self.settings.showid, + submit_button=self.messages.password_reset_button, + delete_label=self.messages.delete_label, + formstyle=self.settings.formstyle, + separator=self.settings.label_separator + ) + if captcha: + addrow(form, captcha.label, captcha, + captcha.comment, self.settings.formstyle, 'captcha__row') + if form.accepts(request, session if self.csrf_prevention else None, + formname='reset_password', dbio=False, + onvalidation=onvalidation, + hideerror=self.settings.hideerror): + user = table_user(**{userfield: form.vars.get(userfield)}) + key = user.registration_key + if not user: + session.flash = self.messages['invalid_%s' % userfield] + redirect(self.url(args=request.args), + client_side=self.settings.client_side) + elif key in ('pending', 'disabled', 'blocked') or (key or '').startswith('pending'): + session.flash = self.messages.registration_pending + redirect(self.url(args=request.args), + client_side=self.settings.client_side) + if self.email_reset_password(user): + session.flash = self.messages.email_sent + else: + session.flash = self.messages.unable_send_email + self.log_event(log, user) + callback(onaccept, form) + if not next: + next = self.url(args=request.args) + else: + next = replace_id(next, form) + redirect(next, client_side=self.settings.client_side) + # old_requires = table_user.email.requires + return form + + def email_reset_password(self, user): + reset_password_key = str(int(time.time())) + '-' + web2py_uuid() + link = self.url(self.settings.function, + args=('reset_password',), vars={'key': reset_password_key}, + scheme=True) + d = dict(user) + d.update(dict(key=reset_password_key, link=link)) + if self.settings.mailer and self.settings.mailer.send( + to=user.email, + subject=self.messages.reset_password_subject, + message=self.messages.reset_password % d): + user.update_record(reset_password_key=reset_password_key) + return True + return False + + def retrieve_password(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): + if self.settings.reset_password_requires_verification: + return self.request_reset_password(next, onvalidation, onaccept, log) + else: + return self.reset_password_deprecated(next, onvalidation, onaccept, log) + + def change_password(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): + """ + Returns a form that lets the user change password + """ + + if not self.is_logged_in(): + redirect(self.settings.login_url, + client_side=self.settings.client_side) + + # Go to external link to change the password + if self.settings.login_form != self: + cas = self.settings.login_form + # To prevent error if change_password_url function is not defined in alternate login + if hasattr(cas, 'change_password_url'): + next = cas.change_password_url(next) + if next is not None: + redirect(next) + + db = self.db + table_user = self.table_user() + s = db(table_user.id == self.user.id) + + request = current.request + session = current.session + if next is DEFAULT: + next = self.get_vars_next() or self.settings.change_password_next + if onvalidation is DEFAULT: + onvalidation = self.settings.change_password_onvalidation + if onaccept is DEFAULT: + onaccept = self.settings.change_password_onaccept + if log is DEFAULT: + log = self.messages['change_password_log'] + passfield = self.settings.password_field + requires = table_user[passfield].requires + if not isinstance(requires, (list, tuple)): + requires = [requires] + requires = list(filter(lambda t: isinstance(t, CRYPT), requires)) + if requires: + requires[0] = CRYPT(**requires[0].__dict__) # Copy the existing CRYPT attributes + requires[0].min_length = 0 # But do not enforce minimum length for the old password + form = SQLFORM.factory( + Field('old_password', 'password', requires=requires, + label=self.messages.old_password), + Field('new_password', 'password', + label=self.messages.new_password, + requires=table_user[passfield].requires), + Field('new_password2', 'password', + label=self.messages.verify_password, + requires=[IS_EXPR('value==%s' % repr(request.vars.new_password), + self.messages.mismatched_password)]), + submit_button=self.messages.password_change_button, + hidden=dict(_next=next), + formstyle=self.settings.formstyle, + separator=self.settings.label_separator + ) + if form.accepts(request, session, + formname='change_password', + onvalidation=onvalidation, + hideerror=self.settings.hideerror): + + current_user = s.select(limitby=(0, 1), orderby_on_limitby=False).first() + if not form.vars['old_password'] == current_user[passfield]: + form.errors['old_password'] = self.messages.invalid_password + else: + d = {passfield: str(form.vars.new_password)} + s.update(**d) + session.flash = self.messages.password_changed + self.log_event(log, self.user) + callback(onaccept, form) + if not next: + next = self.url(args=request.args) + else: + next = replace_id(next, form) + redirect(next, client_side=self.settings.client_side) + return form + + def profile(self, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + ): + """ + Returns a form that lets the user change his/her profile + """ + + table_user = self.table_user() + if not self.is_logged_in(): + redirect(self.settings.login_url, + client_side=self.settings.client_side) + passfield = self.settings.password_field + table_user[passfield].writable = False + table_user['email'].writable = False + request = current.request + session = current.session + if next is DEFAULT: + next = self.get_vars_next() or self.settings.profile_next + if onvalidation is DEFAULT: + onvalidation = self.settings.profile_onvalidation + if onaccept is DEFAULT: + onaccept = self.settings.profile_onaccept + if log is DEFAULT: + log = self.messages['profile_log'] + + form = SQLFORM( + table_user, + self.user.id, + fields=self.settings.profile_fields, + hidden=dict(_next=next), + showid=self.settings.showid, + submit_button=self.messages.profile_save_button, + delete_label=self.messages.delete_label, + upload=self.settings.download_url, + formstyle=self.settings.formstyle, + separator=self.settings.label_separator, + deletable=self.settings.allow_delete_accounts, + ) + if form.accepts(request, session, + formname='profile', + onvalidation=onvalidation, + hideerror=self.settings.hideerror): + extra_fields = self.settings.extra_fields.get(self.settings.table_user_name, []) + if any(f.compute for f in extra_fields): + user = table_user[self.user.id] + self._update_session_user(user) + self.update_groups() + else: + self.user.update(table_user._filter_fields(form.vars)) + session.flash = self.messages.profile_updated + self.log_event(log, self.user) + callback(onaccept, form) + if form.deleted: + return self.logout() + if not next: + next = self.url(args=request.args) + else: + next = replace_id(next, form) + redirect(next, client_side=self.settings.client_side) + return form + + def run_login_onaccept(self): + onaccept = self.settings.login_onaccept + if onaccept: + form = Storage(dict(vars=self.user)) + if not isinstance(onaccept, (list, tuple)): + onaccept = [onaccept] + for callback in onaccept: + callback(form) + + def jwt(self): + """ + To use JWT authentication: + 1) instantiate auth with:: + + auth = Auth(db, jwt = {'secret_key':'secret'}) + + where 'secret' is your own secret string. + + 2) Decorate functions that require login but should accept the JWT token credentials:: + + @auth.allows_jwt() + @auth.requires_login() + def myapi(): return 'hello %s' % auth.user.email + + Notice jwt is allowed but not required. if user is logged in, myapi is accessible. + + 3) Use it! + + Now API users can obtain a token with + + http://.../app/default/user/jwt?username=...&password=.... + + (returns json object with a token attribute) + API users can refresh an existing token with + + http://.../app/default/user/jwt?token=... + + they can authenticate themselves when calling http:/.../myapi by injecting a header + + Authorization: Bearer + + Any additional attributes in the jwt argument of Auth() below:: + + auth = Auth(db, jwt = {...}) + + are passed to the constructor of class AuthJWT. Look there for documentation. + """ + if not self.jwt_handler: + raise HTTP(400, "Not authorized") + else: + rtn = self.jwt_handler.jwt_token_manager() + raise HTTP(200, rtn, cookies=None, **current.response.headers) + + def is_impersonating(self): + return self.is_logged_in() and 'impersonator' in current.session.auth + + def impersonate(self, user_id=DEFAULT): + """ + To use this make a POST to + `http://..../impersonate request.post_vars.user_id=` + + Set request.post_vars.user_id to 0 to restore original user. + + requires impersonator is logged in and:: + + has_permission('impersonate', 'auth_user', user_id) + + """ + request = current.request + session = current.session + auth = session.auth + table_user = self.table_user() + if not self.is_logged_in(): + raise HTTP(401, "Not Authorized") + current_id = auth.user.id + requested_id = user_id + user = None + if user_id is DEFAULT: + user_id = current.request.post_vars.user_id + if user_id and user_id != self.user.id and user_id != '0': + if not self.has_permission('impersonate', + self.table_user(), + user_id): + raise HTTP(403, "Forbidden") + user = table_user(user_id) + if not user: + raise HTTP(401, "Not Authorized") + auth.impersonator = pickle.dumps(session, pickle.HIGHEST_PROTOCOL) + auth.user.update( + table_user._filter_fields(user, True)) + self.user = auth.user + self.update_groups() + log = self.messages['impersonate_log'] + self.log_event(log, dict(id=current_id, other_id=auth.user.id)) + self.run_login_onaccept() + elif user_id in (0, '0'): + if self.is_impersonating(): + session.clear() + session.update(pickle.loads(auth.impersonator)) + self.user = session.auth.user + self.update_groups() + self.run_login_onaccept() + return None + if requested_id is DEFAULT and not request.post_vars: + return SQLFORM.factory(Field('user_id', 'integer')) + elif not user: + return None + else: + return SQLFORM(table_user, user.id, readonly=True) + + def groups(self): + """ + Displays the groups and their roles for the logged in user + """ + + if not self.is_logged_in(): + redirect(self.settings.login_url) + table_membership = self.table_membership() + memberships = self.db( + table_membership.user_id == self.user.id).select() + table = TABLE() + for membership in memberships: + table_group = self.table_group() + groups = self.db(table_group.id == membership.group_id).select() + if groups: + group = groups[0] + table.append(TR(H3(group.role, '(%s)' % group.id))) + table.append(TR(P(group.description))) + if not memberships: + return None + return table + + def not_authorized(self): + """ + You can change the view for this page to make it look as you like + """ + if current.request.ajax: + raise HTTP(403, 'ACCESS DENIED') + return self.messages.access_denied + + def allows_jwt(self, otherwise=None): + if not self.jwt_handler: + raise HTTP(400, "Not authorized") + else: + return self.jwt_handler.allows_jwt(otherwise=otherwise) + + def requires(self, condition, requires_login=True, otherwise=None): + """ + Decorator that prevents access to action if not logged in + """ + + def decorator(action): + + def f(*a, **b): + + basic_allowed, basic_accepted, user = self.basic() + user = user or self.user + login_required = requires_login + if callable(login_required): + login_required = login_required() + + if login_required: + if not user: + if current.request.ajax: + raise HTTP(401, self.messages.ajax_failed_authentication) + elif otherwise is not None: + if callable(otherwise): + return otherwise() + redirect(otherwise) + elif self.settings.allow_basic_login_only or \ + basic_accepted or current.request.is_restful: + raise HTTP(403, "Not authorized") + else: + next = self.here() + current.session.flash = current.response.flash + return call_or_redirect(self.settings.on_failed_authentication, + self.settings.login_url + '?_next=' + urllib_quote(next)) + + if callable(condition): + flag = condition() + else: + flag = condition + if not flag: + current.session.flash = self.messages.access_denied + return call_or_redirect( + self.settings.on_failed_authorization) + return action(*a, **b) + f.__doc__ = action.__doc__ + f.__name__ = action.__name__ + f.__dict__.update(action.__dict__) + return f + + return decorator + + def requires_login(self, otherwise=None): + """ + Decorator that prevents access to action if not logged in + """ + return self.requires(True, otherwise=otherwise) + + def requires_login_or_token(self, otherwise=None): + if self.settings.enable_tokens is True: + user = None + request = current.request + token = request.env.http_web2py_user_token or request.vars._token + table_token = self.table_token() + table_user = self.table_user() + from gluon.settings import global_settings + if global_settings.web2py_runtime_gae: + row = table_token(token=token) + if row: + user = table_user(row.user_id) + else: + row = self.db(table_token.token == token)(table_user.id == table_token.user_id).select().first() + if row: + user = row[table_user._tablename] + if user: + self.login_user(user) + return self.requires(True, otherwise=otherwise) + + def requires_membership(self, role=None, group_id=None, otherwise=None): + """ + Decorator that prevents access to action if not logged in or + if user logged in is not a member of group_id. + If role is provided instead of group_id then the + group_id is calculated. + """ + + def has_membership(self=self, group_id=group_id, role=role): + return self.has_membership(group_id=group_id, role=role) + return self.requires(has_membership, otherwise=otherwise) + + def requires_permission(self, name, table_name='', record_id=0, + otherwise=None): + """ + Decorator that prevents access to action if not logged in or + if user logged in is not a member of any group (role) that + has 'name' access to 'table_name', 'record_id'. + """ + + def has_permission(self=self, name=name, table_name=table_name, record_id=record_id): + return self.has_permission(name, table_name, record_id) + return self.requires(has_permission, otherwise=otherwise) + + def requires_signature(self, otherwise=None, hash_vars=True): + """ + Decorator that prevents access to action if not logged in or + if user logged in is not a member of group_id. + If role is provided instead of group_id then the + group_id is calculated. + """ + def verify(): + return URL.verify(current.request, user_signature=True, hash_vars=hash_vars) + return self.requires(verify, otherwise) + + def accessible_query(self, name, table, user_id=None): + """ + Returns a query with all accessible records for user_id or + the current logged in user + this method does not work on GAE because uses JOIN and IN + + Example: + Use as:: + + db(auth.accessible_query('read', db.mytable)).select(db.mytable.ALL) + + """ + if not user_id: + user_id = self.user_id + db = self.db + if isinstance(table, str) and table in self.db.tables(): + table = self.db[table] + elif isinstance(table, (Set, Query)): + # experimental: build a chained query for all tables + if isinstance(table, Set): + cquery = table.query + else: + cquery = table + tablenames = db._adapter.tables(cquery) + for tablename in tablenames: + cquery &= self.accessible_query(name, tablename, user_id=user_id) + return cquery + if not isinstance(table, str) and \ + self.has_permission(name, table, 0, user_id): + return table.id > 0 + membership = self.table_membership() + permission = self.table_permission() + query = table.id.belongs( + db(membership.user_id == user_id) + (membership.group_id == permission.group_id) + (permission.name == name) + (permission.table_name == table) + ._select(permission.record_id)) + if self.settings.everybody_group_id: + query |= table.id.belongs( + db(permission.group_id == self.settings.everybody_group_id) + (permission.name == name) + (permission.table_name == table) + ._select(permission.record_id)) + return query + + @staticmethod + def archive(form, + archive_table=None, + current_record='current_record', + archive_current=False, + fields=None): + """ + If you have a table (db.mytable) that needs full revision history you + can just do:: + + form = crud.update(db.mytable, myrecord, onaccept=auth.archive) + + or:: + + form = SQLFORM(db.mytable, myrecord).process(onaccept=auth.archive) + + crud.archive will define a new table "mytable_archive" and store + a copy of the current record (if archive_current=True) + or a copy of the previous record (if archive_current=False) + in the newly created table including a reference + to the current record. + + fields allows to specify extra fields that need to be archived. + + If you want to access such table you need to define it yourself + in a model:: + + db.define_table('mytable_archive', + Field('current_record', db.mytable), + db.mytable) + + Notice such table includes all fields of db.mytable plus one: current_record. + crud.archive does not timestamp the stored record unless your original table + has a fields like:: + + db.define_table(..., + Field('saved_on', 'datetime', + default=request.now, update=request.now, writable=False), + Field('saved_by', auth.user, + default=auth.user_id, update=auth.user_id, writable=False), + + there is nothing special about these fields since they are filled before + the record is archived. + + If you want to change the archive table name and the name of the reference field + you can do, for example:: + + db.define_table('myhistory', + Field('parent_record', db.mytable), db.mytable) + + and use it as:: + + form = crud.update(db.mytable, myrecord, + onaccept=lambda form:crud.archive(form, + archive_table=db.myhistory, + current_record='parent_record')) + + """ + if not archive_current and not form.record: + return None + table = form.table + if not archive_table: + archive_table_name = '%s_archive' % table + if archive_table_name not in table._db: + table._db.define_table( + archive_table_name, + Field(current_record, table), + *[field.clone(unique=False) for field in table]) + archive_table = table._db[archive_table_name] + new_record = {current_record: form.vars.id} + for fieldname in archive_table.fields: + if fieldname not in ['id', current_record]: + if archive_current and fieldname in form.vars: + new_record[fieldname] = form.vars[fieldname] + elif form.record and fieldname in form.record: + new_record[fieldname] = form.record[fieldname] + if fields: + new_record.update(fields) + id = archive_table.insert(**new_record) + return id + + def wiki(self, + slug=None, + env=None, + render='markmin', + manage_permissions=False, + force_prefix='', + restrict_search=False, + resolve=True, + extra=None, + menu_groups=None, + templates=None, + migrate=True, + controller=None, + function=None, + force_render=False, + groups=None): + + if controller and function: + resolve = False + + if not hasattr(self, '_wiki'): + self._wiki = Wiki(self, render=render, + manage_permissions=manage_permissions, + force_prefix=force_prefix, + restrict_search=restrict_search, + env=env, extra=extra or {}, + menu_groups=menu_groups, + templates=templates, + migrate=migrate, + controller=controller, + function=function, + groups=groups) + else: + self._wiki.settings.extra = extra or {} + self._wiki.env.update(env or {}) + + # if resolve is set to True, process request as wiki call + # resolve=False allows initial setup without wiki redirection + wiki = None + if resolve: + if slug: + wiki = self._wiki.read(slug, force_render) + if isinstance(wiki, dict) and 'content' in wiki: + # We don't want to return a dict object, just the wiki + wiki = wiki['content'] + else: + wiki = self._wiki() + if isinstance(wiki, basestring): + wiki = XML(wiki) + return wiki + + def wikimenu(self): + """To be used in menu.py for app wide wiki menus""" + if (hasattr(self, "_wiki") and + self._wiki.settings.controller and + self._wiki.settings.function): + self._wiki.automenu() + + +class Crud(object): # pragma: no cover + + default_messages = dict( + submit_button='Submit', + delete_label='Check to delete', + record_created='Record Created', + record_updated='Record Updated', + record_deleted='Record Deleted', + update_log='Record %(id)s updated', + create_log='Record %(id)s created', + read_log='Record %(id)s read', + delete_log='Record %(id)s deleted', + ) + + def url(self, f=None, args=None, vars=None): + """ + This should point to the controller that exposes + download and crud + """ + if args is None: + args = [] + if vars is None: + vars = {} + return URL(c=self.settings.controller, f=f, args=args, vars=vars) + + def __init__(self, environment, db=None, controller='default'): + self.db = db + if not db and environment and isinstance(environment, DAL): + self.db = environment + elif not db: + raise SyntaxError("must pass db as first or second argument") + self.environment = current + settings = self.settings = Settings() + settings.auth = None + settings.logger = None + + settings.create_next = None + settings.update_next = None + settings.controller = controller + settings.delete_next = self.url() + settings.download_url = self.url('download') + settings.create_onvalidation = StorageList() + settings.update_onvalidation = StorageList() + settings.delete_onvalidation = StorageList() + settings.create_onaccept = StorageList() + settings.update_onaccept = StorageList() + settings.update_ondelete = StorageList() + settings.delete_onaccept = StorageList() + settings.update_deletable = True + settings.showid = False + settings.keepvalues = False + settings.create_captcha = None + settings.update_captcha = None + settings.captcha = None + settings.formstyle = 'table3cols' + settings.label_separator = ': ' + settings.hideerror = False + settings.detect_record_change = True + settings.hmac_key = None + settings.lock_keys = True + + messages = self.messages = Messages(current.T) + messages.update(Crud.default_messages) + messages.lock_keys = True + + def __call__(self): + args = current.request.args + if len(args) < 1: + raise HTTP(404) + elif args[0] == 'tables': + return self.tables() + elif len(args) > 1 and not args(1) in self.db.tables: + raise HTTP(404) + table = self.db[args(1)] + if args[0] == 'create': + return self.create(table) + elif args[0] == 'select': + return self.select(table, linkto=self.url(args='read')) + elif args[0] == 'search': + form, rows = self.search(table, linkto=self.url(args='read')) + return DIV(form, SQLTABLE(rows)) + elif args[0] == 'read': + return self.read(table, args(2)) + elif args[0] == 'update': + return self.update(table, args(2)) + elif args[0] == 'delete': + return self.delete(table, args(2)) + else: + raise HTTP(404) + + def log_event(self, message, vars): + if self.settings.logger: + self.settings.logger.log_event(message, vars, origin='crud') + + def has_permission(self, name, table, record=0): + if not self.settings.auth: + return True + try: + record_id = record.id + except: + record_id = record + return self.settings.auth.has_permission(name, str(table), record_id) + + def tables(self): + return TABLE(*[TR(A(name, + _href=self.url(args=('select', name)))) + for name in self.db.tables]) + + @staticmethod + def archive(form, archive_table=None, current_record='current_record'): + return Auth.archive(form, archive_table=archive_table, + current_record=current_record) + + def update(self, + table, + record, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + ondelete=DEFAULT, + log=DEFAULT, + message=DEFAULT, + deletable=DEFAULT, + formname=DEFAULT, + **attributes + ): + if not (isinstance(table, Table) or table in self.db.tables) \ + or (isinstance(record, str) and not str(record).isdigit()): + raise HTTP(404) + if not isinstance(table, Table): + table = self.db[table] + try: + record_id = record.id + except: + record_id = record or 0 + if record_id and not self.has_permission('update', table, record_id): + redirect(self.settings.auth.settings.on_failed_authorization) + if not record_id and not self.has_permission('create', table, record_id): + redirect(self.settings.auth.settings.on_failed_authorization) + + request = current.request + response = current.response + session = current.session + if request.extension == 'json' and request.vars.json: + request.vars.update(json.loads(request.vars.json)) + if next is DEFAULT: + next = request.get_vars._next \ + or request.post_vars._next \ + or self.settings.update_next + if onvalidation is DEFAULT: + onvalidation = self.settings.update_onvalidation + if onaccept is DEFAULT: + onaccept = self.settings.update_onaccept + if ondelete is DEFAULT: + ondelete = self.settings.update_ondelete + if log is DEFAULT: + log = self.messages['update_log'] + if deletable is DEFAULT: + deletable = self.settings.update_deletable + if message is DEFAULT: + message = self.messages.record_updated + if 'hidden' not in attributes: + attributes['hidden'] = {} + attributes['hidden']['_next'] = next + form = SQLFORM( + table, + record, + showid=self.settings.showid, + submit_button=self.messages.submit_button, + delete_label=self.messages.delete_label, + deletable=deletable, + upload=self.settings.download_url, + formstyle=self.settings.formstyle, + separator=self.settings.label_separator, + **attributes # contains hidden + ) + self.accepted = False + self.deleted = False + captcha = self.settings.update_captcha or self.settings.captcha + if record and captcha: + addrow(form, captcha.label, captcha, captcha.comment, self.settings.formstyle, 'captcha__row') + captcha = self.settings.create_captcha or self.settings.captcha + if not record and captcha: + addrow(form, captcha.label, captcha, captcha.comment, self.settings.formstyle, 'captcha__row') + if request.extension not in ('html', 'load'): + (_session, _formname) = (None, None) + else: + (_session, _formname) = ( + session, '%s/%s' % (table._tablename, form.record_id)) + if formname is not DEFAULT: + _formname = formname + keepvalues = self.settings.keepvalues + if request.vars.delete_this_record: + keepvalues = False + if isinstance(onvalidation, StorageList): + onvalidation = onvalidation.get(table._tablename, []) + if form.accepts(request, _session, formname=_formname, + onvalidation=onvalidation, keepvalues=keepvalues, + hideerror=self.settings.hideerror, + detect_record_change=self.settings.detect_record_change): + self.accepted = True + response.flash = message + if log: + self.log_event(log, form.vars) + if request.vars.delete_this_record: + self.deleted = True + message = self.messages.record_deleted + callback(ondelete, form, table._tablename) + response.flash = message + callback(onaccept, form, table._tablename) + if request.extension not in ('html', 'load'): + raise HTTP(200, 'RECORD CREATED/UPDATED') + if isinstance(next, (list, tuple)): # fix issue with 2.6 + next = next[0] + if next: # Only redirect when explicit + next = replace_id(next, form) + session.flash = response.flash + redirect(next) + elif request.extension not in ('html', 'load'): + raise HTTP(401, serializers.json(dict(errors=form.errors))) + return form + + def create(self, + table, + next=DEFAULT, + onvalidation=DEFAULT, + onaccept=DEFAULT, + log=DEFAULT, + message=DEFAULT, + formname=DEFAULT, + **attributes + ): + + if next is DEFAULT: + next = self.settings.create_next + if onvalidation is DEFAULT: + onvalidation = self.settings.create_onvalidation + if onaccept is DEFAULT: + onaccept = self.settings.create_onaccept + if log is DEFAULT: + log = self.messages['create_log'] + if message is DEFAULT: + message = self.messages.record_created + return self.update(table, + None, + next=next, + onvalidation=onvalidation, + onaccept=onaccept, + log=log, + message=message, + deletable=False, + formname=formname, + **attributes + ) + + def read(self, table, record): + if not (isinstance(table, Table) or table in self.db.tables) \ + or (isinstance(record, str) and not str(record).isdigit()): + raise HTTP(404) + if not isinstance(table, Table): + table = self.db[table] + if not self.has_permission('read', table, record): + redirect(self.settings.auth.settings.on_failed_authorization) + form = SQLFORM( + table, + record, + readonly=True, + comments=False, + upload=self.settings.download_url, + showid=self.settings.showid, + formstyle=self.settings.formstyle, + separator=self.settings.label_separator + ) + if current.request.extension not in ('html', 'load'): + return table._filter_fields(form.record, id=True) + return form + + def delete(self, + table, + record_id, + next=DEFAULT, + message=DEFAULT, + ): + if not (isinstance(table, Table) or table in self.db.tables): + raise HTTP(404) + if not isinstance(table, Table): + table = self.db[table] + if not self.has_permission('delete', table, record_id): + redirect(self.settings.auth.settings.on_failed_authorization) + request = current.request + session = current.session + if next is DEFAULT: + next = request.get_vars._next \ + or request.post_vars._next \ + or self.settings.delete_next + if message is DEFAULT: + message = self.messages.record_deleted + record = table[record_id] + if record: + callback(self.settings.delete_onvalidation, record) + del table[record_id] + callback(self.settings.delete_onaccept, record, table._tablename) + session.flash = message + redirect(next) + + def rows(self, + table, + query=None, + fields=None, + orderby=None, + limitby=None, + ): + if not (isinstance(table, Table) or table in self.db.tables): + raise HTTP(404) + if not self.has_permission('select', table): + redirect(self.settings.auth.settings.on_failed_authorization) + # if record_id and not self.has_permission('select', table): + # redirect(self.settings.auth.settings.on_failed_authorization) + if not isinstance(table, Table): + table = self.db[table] + if not query: + query = table.id > 0 + if not fields: + fields = [field for field in table if field.readable] + else: + fields = [table[f] if isinstance(f, str) else f for f in fields] + rows = self.db(query).select(*fields, **dict(orderby=orderby, + limitby=limitby)) + return rows + + def select(self, + table, + query=None, + fields=None, + orderby=None, + limitby=None, + headers=None, + **attr + ): + headers = headers or {} + rows = self.rows(table, query, fields, orderby, limitby) + if not rows: + return None # Nicer than an empty table. + if 'upload' not in attr: + attr['upload'] = self.url('download') + if current.request.extension not in ('html', 'load'): + return rows.as_list() + if not headers: + if isinstance(table, str): + table = self.db[table] + headers = dict((str(k), k.label) for k in table) + return SQLTABLE(rows, headers=headers, **attr) + + def get_format(self, field): + rtable = field._db[field.type[10:]] + format = rtable.get('_format', None) + if format and isinstance(format, str): + return format[2:-2] + return field.name + + def get_query(self, field, op, value, refsearch=False): + try: + if refsearch: + format = self.get_format(field) + if op == 'equals': + if not refsearch: + return field == value + else: + return lambda row: row[field.name][format] == value + elif op == 'not equal': + if not refsearch: + return field != value + else: + return lambda row: row[field.name][format] != value + elif op == 'greater than': + if not refsearch: + return field > value + else: + return lambda row: row[field.name][format] > value + elif op == 'less than': + if not refsearch: + return field < value + else: + return lambda row: row[field.name][format] < value + elif op == 'starts with': + if not refsearch: + return field.like(value + '%') + else: + return lambda row: str(row[field.name][format]).startswith(value) + elif op == 'ends with': + if not refsearch: + return field.like('%' + value) + else: + return lambda row: str(row[field.name][format]).endswith(value) + elif op == 'contains': + if not refsearch: + return field.like('%' + value + '%') + else: + return lambda row: value in row[field.name][format] + except: + return None + + def search(self, *tables, **args): + """ + Creates a search form and its results for a table + Examples: + Use as:: + + form, results = crud.search(db.test, + queries = ['equals', 'not equal', 'contains'], + query_labels={'equals':'Equals', + 'not equal':'Not equal'}, + fields = ['id','children'], + field_labels = { + 'id':'ID','children':'Children'}, + zero='Please choose', + query = (db.test.id > 0)&(db.test.id != 3) ) + + """ + table = tables[0] + fields = args.get('fields', table.fields) + validate = args.get('validate', True) + request = current.request + db = self.db + if not (isinstance(table, Table) or table in db.tables): + raise HTTP(404) + attributes = {} + for key in ('orderby', 'groupby', 'left', 'distinct', 'limitby', 'cache'): + if key in args: + attributes[key] = args[key] + tbl = TABLE() + selected = [] + refsearch = [] + results = [] + showall = args.get('showall', False) + if showall: + selected = fields + chkall = args.get('chkall', False) + if chkall: + for f in fields: + request.vars['chk%s' % f] = 'on' + ops = args.get('queries', []) + zero = args.get('zero', '') + if not ops: + ops = ['equals', 'not equal', 'greater than', + 'less than', 'starts with', + 'ends with', 'contains'] + ops.insert(0, zero) + query_labels = args.get('query_labels', {}) + query = args.get('query', table.id > 0) + field_labels = args.get('field_labels', {}) + for field in fields: + field = table[field] + if not field.readable: + continue + fieldname = field.name + chkval = request.vars.get('chk' + fieldname, None) + txtval = request.vars.get('txt' + fieldname, None) + opval = request.vars.get('op' + fieldname, None) + row = TR(TD(INPUT(_type="checkbox", _name="chk" + fieldname, + _disabled=(field.type == 'id'), + value=(field.type == 'id' or chkval == 'on'))), + TD(field_labels.get(fieldname, field.label)), + TD(SELECT([OPTION(query_labels.get(op, op), + _value=op) for op in ops], + _name="op" + fieldname, + value=opval)), + TD(INPUT(_type="text", _name="txt" + fieldname, + _value=txtval, _id='txt' + fieldname, + _class=str(field.type)))) + tbl.append(row) + if request.post_vars and (chkval or field.type == 'id'): + if txtval and opval != '': + if field.type[0:10] == 'reference ': + refsearch.append(self.get_query(field, opval, txtval, refsearch=True)) + elif validate: + value, error = field.validate(txtval) + if not error: + # TODO deal with 'starts with', 'ends with', 'contains' on GAE + query &= self.get_query(field, opval, value) + else: + row[3].append(DIV(error, _class='error')) + else: + query &= self.get_query(field, opval, txtval) + selected.append(field) + form = FORM(tbl, INPUT(_type="submit")) + if selected: + try: + results = db(query).select(*selected, **attributes) + for r in refsearch: + results = results.find(r) + except: # TODO: hmmm, we should do better here + results = None + return form, results + + +urllib2.install_opener(urllib2.build_opener(urllib2.HTTPCookieProcessor())) + + +def fetch(url, data=None, headers=None, + cookie=Cookie.SimpleCookie(), + user_agent='Mozilla/5.0'): + headers = headers or {} + if data is not None: + data = urlencode(data) + if user_agent: + headers['User-agent'] = user_agent + headers['Cookie'] = ' '.join( + ['%s=%s;' % (c.key, c.value) for c in cookie.values()]) + try: + from google.appengine.api import urlfetch + except ImportError: + req = urllib2.Request(url, data, headers) + html = urllib2.urlopen(req).read() + else: + method = ((data is None) and urlfetch.GET) or urlfetch.POST + while url is not None: + response = urlfetch.fetch(url=url, payload=data, + method=method, headers=headers, + allow_truncated=False, follow_redirects=False, + deadline=10) + # next request will be a get, so no need to send the data again + data = None + method = urlfetch.GET + # load cookies from the response + cookie.load(response.headers.get('set-cookie', '')) + url = response.headers.get('location') + html = response.content + return html + +regex_geocode = \ + re.compile(r"""[\W]*?[\W]*?(?P[^<]*)[\W]*?(?P[^<]*)[\W]*?""") + + +def geocode(address): + try: + a = urllib_quote(address) + txt = fetch('http://maps.googleapis.com/maps/api/geocode/xml?sensor=false&address=%s' % a) + item = regex_geocode.search(txt) + (la, lo) = (float(item.group('la')), float(item.group('lo'))) + return (la, lo) + except: + return (0.0, 0.0) + + +def reverse_geocode(lat, lng, lang=None): + """ Try to get an approximate address for a given latitude, longitude. """ + if not lang: + lang = current.T.accepted_language + try: + return json.loads(fetch('http://maps.googleapis.com/maps/api/geocode/json?latlng=%(lat)s,%(lng)s&language=%(lang)s' % locals()))['results'][0]['formatted_address'] + except: + return '' + + +def universal_caller(f, *a, **b): + c = f.__code__.co_argcount + n = f.__code__.co_varnames[:c] + + defaults = f.__defaults__ or [] + pos_args = n[0:-len(defaults)] + named_args = n[-len(defaults):] + + arg_dict = {} + + # Fill the arg_dict with name and value for the submitted, positional values + for pos_index, pos_val in enumerate(a[:c]): + arg_dict[n[pos_index]] = pos_val # n[pos_index] is the name of the argument + + # There might be pos_args left, that are sent as named_values. Gather them as well. + # If a argument already is populated with values we simply replaces them. + for arg_name in pos_args[len(arg_dict):]: + if arg_name in b: + arg_dict[arg_name] = b[arg_name] + + if len(arg_dict) >= len(pos_args): + # All the positional arguments is found. The function may now be called. + # However, we need to update the arg_dict with the values from the named arguments as well. + for arg_name in named_args: + if arg_name in b: + arg_dict[arg_name] = b[arg_name] + + return f(**arg_dict) + + # Raise an error, the function cannot be called. + raise HTTP(404, "Object does not exist") + + +class Service(object): + + def __init__(self, environment=None, check_args=False): + self.check_args = check_args + + self.run_procedures = {} + self.csv_procedures = {} + self.xml_procedures = {} + self.rss_procedures = {} + self.json_procedures = {} + self.jsonrpc_procedures = {} + self.jsonrpc2_procedures = {} + self.xmlrpc_procedures = {} + self.amfrpc_procedures = {} + self.amfrpc3_procedures = {} + self.soap_procedures = {} + + def run(self, f): + """ + Example: + Use as:: + + service = Service() + @service.run + def myfunction(a, b): + return a + b + def call(): + return service() + + Then call it with:: + + wget http://..../app/default/call/run/myfunction?a=3&b=4 + + """ + self.run_procedures[f.__name__] = f + return f + + def csv(self, f): + """ + Example: + Use as:: + + service = Service() + @service.csv + def myfunction(a, b): + return a + b + def call(): + return service() + + Then call it with:: + + wget http://..../app/default/call/csv/myfunction?a=3&b=4 + + """ + self.csv_procedures[f.__name__] = f + return f + + def xml(self, f): + """ + Example: + Use as:: + + service = Service() + @service.xml + def myfunction(a, b): + return a + b + def call(): + return service() + + Then call it with:: + + wget http://..../app/default/call/xml/myfunction?a=3&b=4 + + """ + self.xml_procedures[f.__name__] = f + return f + + def rss(self, f): + """ + Example: + Use as:: + + service = Service() + @service.rss + def myfunction(): + return dict(title=..., link=..., description=..., + created_on=..., entries=[dict(title=..., link=..., + description=..., created_on=...]) + def call(): + return service() + + Then call it with: + + wget http://..../app/default/call/rss/myfunction + + """ + self.rss_procedures[f.__name__] = f + return f + + def json(self, f): + """ + Example: + Use as:: + + service = Service() + @service.json + def myfunction(a, b): + return [{a: b}] + def call(): + return service() + + Then call it with:; + + wget http://..../app/default/call/json/myfunction?a=hello&b=world + + """ + self.json_procedures[f.__name__] = f + return f + + def jsonrpc(self, f): + """ + Example: + Use as:: + + service = Service() + @service.jsonrpc + def myfunction(a, b): + return a + b + def call(): + return service() + + Then call it with: + + wget http://..../app/default/call/jsonrpc/myfunction?a=hello&b=world + + """ + self.jsonrpc_procedures[f.__name__] = f + return f + + def jsonrpc2(self, f): + """ + Example: + Use as:: + + service = Service() + @service.jsonrpc2 + def myfunction(a, b): + return a + b + def call(): + return service() + + Then call it with: + + wget --post-data '{"jsonrpc": "2.0", + "id": 1, + "method": "myfunction", + "params": {"a": 1, "b": 2}}' http://..../app/default/call/jsonrpc2 + + """ + self.jsonrpc2_procedures[f.__name__] = f + return f + + def xmlrpc(self, f): + """ + Example: + Use as:: + + service = Service() + @service.xmlrpc + def myfunction(a, b): + return a + b + def call(): + return service() + + The call it with: + + wget http://..../app/default/call/xmlrpc/myfunction?a=hello&b=world + + """ + self.xmlrpc_procedures[f.__name__] = f + return f + + def amfrpc(self, f): + """ + Example: + Use as:: + + service = Service() + @service.amfrpc + def myfunction(a, b): + return a + b + def call(): + return service() + + + Then call it with:: + + wget http://..../app/default/call/amfrpc/myfunction?a=hello&b=world + + """ + self.amfrpc_procedures[f.__name__] = f + return f + + def amfrpc3(self, domain='default'): + """ + Example: + Use as:: + + service = Service() + @service.amfrpc3('domain') + def myfunction(a, b): + return a + b + def call(): + return service() + + Then call it with: + + wget http://..../app/default/call/amfrpc3/myfunction?a=hello&b=world + + """ + if not isinstance(domain, str): + raise SyntaxError("AMF3 requires a domain for function") + + def _amfrpc3(f): + if domain: + self.amfrpc3_procedures[domain + '.' + f.__name__] = f + else: + self.amfrpc3_procedures[f.__name__] = f + return f + return _amfrpc3 + + def soap(self, name=None, returns=None, args=None, doc=None, response_element_name=None): + """ + Example: + Use as:: + + service = Service() + @service.soap('MyFunction',returns={'result':int},args={'a':int,'b':int,}) + def myfunction(a, b): + return a + b + def call(): + return service() + + Then call it with:: + + from gluon.contrib.pysimplesoap.client import SoapClient + client = SoapClient(wsdl="http://..../app/default/call/soap?WSDL") + response = client.MyFunction(a=1,b=2) + return response['result'] + + It also exposes online generated documentation and xml example messages + at `http://..../app/default/call/soap` + """ + + def _soap(f): + self.soap_procedures[name or f.__name__] = f, returns, args, doc, response_element_name + return f + return _soap + + def serve_run(self, args=None): + request = current.request + if not args: + args = request.args + if args and args[0] in self.run_procedures: + return str(self.call_service_function(self.run_procedures[args[0]], + *args[1:], **dict(request.vars))) + self.error() + + def serve_csv(self, args=None): + request = current.request + response = current.response + response.headers['Content-Type'] = 'text/x-csv' + if not args: + args = request.args + + def none_exception(value): + if isinstance(value, unicodeT): + return value.encode('utf8') + if hasattr(value, 'isoformat'): + return value.isoformat()[:19].replace('T', ' ') + if value is None: + return '' + return value + if args and args[0] in self.csv_procedures: + import types + r = self.call_service_function(self.csv_procedures[args[0]], + *args[1:], **dict(request.vars)) + s = StringIO() + if hasattr(r, 'export_to_csv_file'): + r.export_to_csv_file(s) + elif r and not isinstance(r, types.GeneratorType) and isinstance(r[0], (dict, Storage)): + import csv + writer = csv.writer(s) + writer.writerow(r[0].keys()) + for line in r: + writer.writerow([none_exception(v) + for v in line.values()]) + else: + import csv + writer = csv.writer(s) + for line in r: + writer.writerow(line) + return s.getvalue() + self.error() + + def serve_xml(self, args=None): + request = current.request + response = current.response + response.headers['Content-Type'] = 'text/xml' + if not args: + args = request.args + if args and args[0] in self.xml_procedures: + s = self.call_service_function(self.xml_procedures[args[0]], + *args[1:], **dict(request.vars)) + if hasattr(s, 'as_list'): + s = s.as_list() + return serializers.xml(s, quote=False) + self.error() + + def serve_rss(self, args=None): + request = current.request + response = current.response + if not args: + args = request.args + if args and args[0] in self.rss_procedures: + feed = self.call_service_function(self.rss_procedures[args[0]], + *args[1:], **dict(request.vars)) + else: + self.error() + response.headers['Content-Type'] = 'application/rss+xml' + return serializers.rss(feed) + + def serve_json(self, args=None): + request = current.request + response = current.response + response.headers['Content-Type'] = 'application/json; charset=utf-8' + if not args: + args = request.args + d = dict(request.vars) + if args and args[0] in self.json_procedures: + s = self.call_service_function(self.json_procedures[args[0]], *args[1:], **d) + if hasattr(s, 'as_list'): + s = s.as_list() + return response.json(s) + self.error() + + class JsonRpcException(Exception): + + def __init__(self, code, info): + jrpc_error = Service.jsonrpc_errors.get(code) + if jrpc_error: + self.message, self.description = jrpc_error + self.code, self.info = code, info + + # jsonrpc 2.0 error types. records the following structure {code: (message,meaning)} + jsonrpc_errors = { + -32700: ("Parse error. Invalid JSON was received by the server.", + "An error occurred on the server while parsing the JSON text."), + -32600: ("Invalid Request", "The JSON sent is not a valid Request object."), + -32601: ("Method not found", "The method does not exist / is not available."), + -32602: ("Invalid params", "Invalid method parameter(s)."), + -32603: ("Internal error", "Internal JSON-RPC error."), + -32099: ("Server error", "Reserved for implementation-defined server-errors.")} + + def serve_jsonrpc(self): + def return_response(id, result): + return serializers.json({'version': '1.1', 'id': id, 'result': result, 'error': None}) + + def return_error(id, code, message, data=None): + error = {'name': 'JSONRPCError', + 'code': code, 'message': message} + if data is not None: + error['data'] = data + return serializers.json({'id': id, + 'version': '1.1', + 'error': error, + }) + + request = current.request + response = current.response + response.headers['Content-Type'] = 'application/json; charset=utf-8' + methods = self.jsonrpc_procedures + data = json.loads(request.body.read()) + jsonrpc_2 = data.get('jsonrpc') + if jsonrpc_2: # hand over to version 2 of the protocol + return self.serve_jsonrpc2(data) + id, method, params = data.get('id'), data.get('method'), data.get('params', []) + if id is None: + return return_error(0, 100, 'missing id') + if method not in methods: + return return_error(id, 100, 'method "%s" does not exist' % method) + try: + if isinstance(params, dict): + s = methods[method](**params) + else: + s = methods[method](*params) + if hasattr(s, 'as_list'): + s = s.as_list() + return return_response(id, s) + except Service.JsonRpcException as e: + return return_error(id, e.code, e.info) + except: + etype, eval, etb = sys.exc_info() + message = '%s: %s' % (etype.__name__, eval) + data = request.is_local and traceback.format_tb(etb) + logger.warning('jsonrpc exception %s\n%s' % (message, traceback.format_tb(etb))) + return return_error(id, 100, message, data) + + def serve_jsonrpc2(self, data=None, batch_element=False): + + def return_response(id, result): + if not must_respond: + return None + return serializers.json({'jsonrpc': '2.0', 'id': id, 'result': result}) + + def return_error(id, code, message=None, data=None): + error = {'code': code} + if code in Service.jsonrpc_errors: + error['message'] = Service.jsonrpc_errors[code][0] + error['data'] = Service.jsonrpc_errors[code][1] + if message is not None: + error['message'] = message + if data is not None: + error['data'] = data + return serializers.json({'jsonrpc': '2.0', 'id': id, 'error': error}) + + def validate(data): + """ + Validate request as defined in: http://www.jsonrpc.org/specification#request_object. + + Args: + data(str): The json object. + + Returns: + - True -- if successful + - False -- if no error should be reported (i.e. data is missing 'id' member) + + Raises: + JsonRPCException + + """ + + iparms = set(data.keys()) + mandatory_args = set(['jsonrpc', 'method']) + missing_args = mandatory_args - iparms + + if missing_args: + raise Service.JsonRpcException(-32600, 'Missing arguments %s.' % list(missing_args)) + if data['jsonrpc'] != '2.0': + raise Service.JsonRpcException(-32603, 'Unsupported jsonrpc version "%s"' % data['jsonrpc']) + if 'id' not in iparms: + return False + + return True + + request = current.request + response = current.response + if not data: + response.headers['Content-Type'] = 'application/json; charset=utf-8' + try: + data = json.loads(request.body.read()) + except ValueError: # decoding error in json lib + return return_error(None, -32700) + + # Batch handling + if isinstance(data, list) and not batch_element: + retlist = [] + for c in data: + retstr = self.serve_jsonrpc2(c, batch_element=True) + if retstr: # do not add empty responses + retlist.append(retstr) + if len(retlist) == 0: # return nothing + return '' + else: + return "[" + ','.join(retlist) + "]" + methods = self.jsonrpc2_procedures + methods.update(self.jsonrpc_procedures) + + try: + must_respond = validate(data) + except Service.JsonRpcException as e: + return return_error(None, e.code, e.info) + + id, method, params = data.get('id'), data['method'], data.get('params', '') + if method not in methods: + return return_error(id, -32601, data='Method "%s" does not exist' % method) + try: + if isinstance(params, dict): + s = methods[method](**params) + else: + s = methods[method](*params) + if hasattr(s, 'as_list'): + s = s.as_list() + if must_respond: + return return_response(id, s) + else: + return '' + except HTTP as e: + raise e + except Service.JsonRpcException as e: + return return_error(id, e.code, e.info) + except: + etype, eval, etb = sys.exc_info() + data = '%s: %s\n' % (etype.__name__, eval) + str(request.is_local and traceback.format_tb(etb)) + logger.warning('%s: %s\n%s' % (etype.__name__, eval, traceback.format_tb(etb))) + return return_error(id, -32099, data=data) + + def serve_xmlrpc(self): + request = current.request + response = current.response + services = self.xmlrpc_procedures.values() + return response.xmlrpc(request, services) + + def serve_amfrpc(self, version=0): + try: + import pyamf + import pyamf.remoting.gateway + except: + return "pyamf not installed or not in Python sys.path" + request = current.request + response = current.response + if version == 3: + services = self.amfrpc3_procedures + base_gateway = pyamf.remoting.gateway.BaseGateway(services) + pyamf_request = pyamf.remoting.decode(request.body) + else: + services = self.amfrpc_procedures + base_gateway = pyamf.remoting.gateway.BaseGateway(services) + context = pyamf.get_context(pyamf.AMF0) + pyamf_request = pyamf.remoting.decode(request.body, context) + pyamf_response = pyamf.remoting.Envelope(pyamf_request.amfVersion) + for name, message in pyamf_request: + pyamf_response[name] = base_gateway.getProcessor(message)(message) + response.headers['Content-Type'] = pyamf.remoting.CONTENT_TYPE + if version == 3: + return pyamf.remoting.encode(pyamf_response).getvalue() + else: + return pyamf.remoting.encode(pyamf_response, context).getvalue() + + def serve_soap(self, version="1.1"): + try: + from gluon.contrib.pysimplesoap.server import SoapDispatcher + except: + return "pysimplesoap not installed in contrib" + request = current.request + response = current.response + procedures = self.soap_procedures + + location = "%s://%s%s" % (request.env.wsgi_url_scheme, + request.env.http_host, + URL(r=request, f="call/soap", vars={})) + namespace = 'namespace' in response and response.namespace or location + documentation = response.description or '' + dispatcher = SoapDispatcher( + name=response.title, + location=location, + action=location, # SOAPAction + namespace=namespace, + prefix='pys', + documentation=documentation, + ns=True) + for method, (function, returns, args, doc, resp_elem_name) in iteritems(procedures): + dispatcher.register_function(method, function, returns, args, doc, resp_elem_name) + if request.env.request_method == 'POST': + fault = {} + # Process normal Soap Operation + response.headers['Content-Type'] = 'text/xml' + xml = dispatcher.dispatch(request.body.read(), fault=fault) + if fault: + # May want to consider populating a ticket here... + response.status = 500 + # return the soap response + return xml + elif 'WSDL' in request.vars: + # Return Web Service Description + response.headers['Content-Type'] = 'text/xml' + return dispatcher.wsdl() + elif 'op' in request.vars: + # Return method help webpage + response.headers['Content-Type'] = 'text/html' + method = request.vars['op'] + sample_req_xml, sample_res_xml, doc = dispatcher.help(method) + body = [H1("Welcome to Web2Py SOAP webservice gateway"), + A("See all webservice operations", + _href=URL(r=request, f="call/soap", vars={})), + H2(method), + P(doc), + UL(LI("Location: %s" % dispatcher.location), + LI("Namespace: %s" % dispatcher.namespace), + LI("SoapAction: %s" % dispatcher.action), + ), + H3("Sample SOAP XML Request Message:"), + CODE(sample_req_xml, language="xml"), + H3("Sample SOAP XML Response Message:"), + CODE(sample_res_xml, language="xml"), + ] + return {'body': body} + else: + # Return general help and method list webpage + response.headers['Content-Type'] = 'text/html' + body = [H1("Welcome to Web2Py SOAP webservice gateway"), + P(response.description), + P("The following operations are available"), + A("See WSDL for webservice description", + _href=URL(r=request, f="call/soap", vars={"WSDL": None})), + UL([LI(A("%s: %s" % (method, doc or ''), + _href=URL(r=request, f="call/soap", vars={'op': method}))) + for method, doc in dispatcher.list_methods()]), + ] + return {'body': body} + + def __call__(self): + """ + Registers services with:: + + service = Service() + @service.run + @service.rss + @service.json + @service.jsonrpc + @service.xmlrpc + @service.amfrpc + @service.amfrpc3('domain') + @service.soap('Method', returns={'Result':int}, args={'a':int,'b':int,}) + + Exposes services with:: + + def call(): + return service() + + You can call services with:: + + http://..../app/default/call/run?[parameters] + http://..../app/default/call/rss?[parameters] + http://..../app/default/call/json?[parameters] + http://..../app/default/call/jsonrpc + http://..../app/default/call/xmlrpc + http://..../app/default/call/amfrpc + http://..../app/default/call/amfrpc3 + http://..../app/default/call/soap + + """ + + request = current.request + if len(request.args) < 1: + raise HTTP(404, "Not Found") + arg0 = request.args(0) + if arg0 == 'run': + return self.serve_run(request.args[1:]) + elif arg0 == 'rss': + return self.serve_rss(request.args[1:]) + elif arg0 == 'csv': + return self.serve_csv(request.args[1:]) + elif arg0 == 'xml': + return self.serve_xml(request.args[1:]) + elif arg0 == 'json': + return self.serve_json(request.args[1:]) + elif arg0 == 'jsonrpc': + return self.serve_jsonrpc() + elif arg0 == 'jsonrpc2': + return self.serve_jsonrpc2() + elif arg0 == 'xmlrpc': + return self.serve_xmlrpc() + elif arg0 == 'amfrpc': + return self.serve_amfrpc() + elif arg0 == 'amfrpc3': + return self.serve_amfrpc(3) + elif arg0 == 'soap': + return self.serve_soap() + else: + self.error() + + def error(self): + raise HTTP(404, "Object does not exist") + + # we make this a method so that subclasses can override it if they want to do more specific argument-checking + # but the default implmentation is the simplest: just pass the arguments we got, with no checking + def call_service_function(self, f, *a, **b): + if self.check_args: + return universal_caller(f, *a, **b) + else: + return f(*a, **b) + + +def completion(callback): + """ + Executes a task on completion of the called action. + + Example: + Use as:: + + from gluon.tools import completion + @completion(lambda d: logging.info(repr(d))) + def index(): + return dict(message='hello') + + It logs the output of the function every time input is called. + The argument of completion is executed in a new thread. + """ + def _completion(f): + def __completion(*a, **b): + d = None + try: + d = f(*a, **b) + return d + finally: + thread.start_new_thread(callback, (d,)) + return __completion + return _completion + + +def prettydate(d, T=lambda x: x, utc=False): + now = datetime.datetime.utcnow() if utc else datetime.datetime.now() + if isinstance(d, datetime.datetime): + dt = now - d + elif isinstance(d, datetime.date): + dt = now.date() - d + elif not d: + return '' + else: + return '[invalid date]' + if dt.days < 0: + suffix = ' from now' + dt = -dt + else: + suffix = ' ago' + if dt.days >= 2 * 365: + return T('%d years' + suffix) % int(dt.days // 365) + elif dt.days >= 365: + return T('1 year' + suffix) + elif dt.days >= 60: + return T('%d months' + suffix) % int(dt.days // 30) + elif dt.days >= 27: # 4 weeks ugly + return T('1 month' + suffix) + elif dt.days >= 14: + return T('%d weeks' + suffix) % int(dt.days // 7) + elif dt.days >= 7: + return T('1 week' + suffix) + elif dt.days > 1: + return T('%d days' + suffix) % dt.days + elif dt.days == 1: + return T('1 day' + suffix) + elif dt.seconds >= 2 * 60 * 60: + return T('%d hours' + suffix) % int(dt.seconds // 3600) + elif dt.seconds >= 60 * 60: + return T('1 hour' + suffix) + elif dt.seconds >= 2 * 60: + return T('%d minutes' + suffix) % int(dt.seconds // 60) + elif dt.seconds >= 60: + return T('1 minute' + suffix) + elif dt.seconds > 1: + return T('%d seconds' + suffix) % dt.seconds + elif dt.seconds == 1: + return T('1 second' + suffix) + else: + return T('now') + + +def test_thread_separation(): + def f(): + c = PluginManager() + lock1.acquire() + lock2.acquire() + c.x = 7 + lock1.release() + lock2.release() + lock1 = thread.allocate_lock() + lock2 = thread.allocate_lock() + lock1.acquire() + thread.start_new_thread(f, ()) + a = PluginManager() + a.x = 5 + lock1.release() + lock2.acquire() + return a.x + + +class PluginManager(object): + """ + + Plugin Manager is similar to a storage object but it is a single level + singleton. This means that multiple instances within the same thread share + the same attributes. + Its constructor is also special. The first argument is the name of the + plugin you are defining. + The named arguments are parameters needed by the plugin with default values. + If the parameters were previous defined, the old values are used. + + Example: + in some general configuration file:: + + plugins = PluginManager() + plugins.me.param1=3 + + within the plugin model:: + + _ = PluginManager('me',param1=5,param2=6,param3=7) + + where the plugin is used:: + + >>> print(plugins.me.param1) + 3 + >>> print(plugins.me.param2) + 6 + >>> plugins.me.param3 = 8 + >>> print(plugins.me.param3) + 8 + + Here are some tests:: + + >>> a=PluginManager() + >>> a.x=6 + >>> b=PluginManager('check') + >>> print(b.x) + 6 + >>> b=PluginManager() # reset settings + >>> print(b.x) + + >>> b.x=7 + >>> print(a.x) + 7 + >>> a.y.z=8 + >>> print(b.y.z) + 8 + >>> test_thread_separation() + 5 + >>> plugins=PluginManager('me',db='mydb') + >>> print(plugins.me.db) + mydb + >>> print('me' in plugins) + True + >>> print(plugins.me.installed) + True + + """ + instances = {} + + def __new__(cls, *a, **b): + id = thread.get_ident() + lock = thread.allocate_lock() + try: + lock.acquire() + try: + return cls.instances[id] + except KeyError: + instance = object.__new__(cls, *a, **b) + cls.instances[id] = instance + return instance + finally: + lock.release() + + def __init__(self, plugin=None, **defaults): + if not plugin: + self.__dict__.clear() + settings = self.__getattr__(plugin) + settings.installed = True + settings.update( + (k, v) for k, v in defaults.items() if k not in settings) + + def __getattr__(self, key): + if key not in self.__dict__: + self.__dict__[key] = Storage() + return self.__dict__[key] + + def keys(self): + return self.__dict__.keys() + + def __contains__(self, key): + return key in self.__dict__ + + +class Expose(object): + + def __init__(self, base=None, basename=None, extensions=None, + allow_download=True, follow_symlink_out=False): + """ + Examples: + Use as:: + + def static(): + return dict(files=Expose()) + + or:: + + def static(): + path = os.path.join(request.folder,'static','public') + return dict(files=Expose(path,basename='public')) + + Args: + extensions: an optional list of file extensions for filtering + displayed files: e.g. `['.py', '.jpg']` + allow_download: whether to allow downloading selected files + follow_symlink_out: whether to follow symbolic links that points + points outside of `base`. + Warning: setting this to `True` might pose a security risk + if you don't also have complete control over writing + and file creation under `base`. + + """ + # why would this not be callable? but otherwise tests do not pass + if current.session and callable(current.session.forget): + current.session.forget() + self.follow_symlink_out = follow_symlink_out + self.base = self.normalize_path( + base or os.path.join(current.request.folder, 'static')) + self.basename = basename or current.request.function + self.base = base = os.path.realpath(base or os.path.join(current.request.folder, 'static')) + basename = basename or current.request.function + self.basename = basename + + if current.request.raw_args: + self.args = [arg for arg in current.request.raw_args.split('/') if arg] + else: + self.args = [arg for arg in current.request.args if arg] + + filename = os.path.join(self.base, *self.args) + if not os.path.exists(filename): + raise HTTP(404, "FILE NOT FOUND") + if not self.in_base(filename): + raise HTTP(401, "NOT AUTHORIZED") + if allow_download and not os.path.isdir(filename): + current.response.headers['Content-Type'] = contenttype(filename) + raise HTTP(200, open(filename, 'rb'), **current.response.headers) + self.path = path = os.path.join(filename, '*') + dirname_len = len(path) - 1 + allowed = [f for f in sorted(glob.glob(path)) + if not any([self.isprivate(f), self.issymlink_out(f)])] + self.folders = [f[dirname_len:] + for f in allowed if os.path.isdir(f)] + self.filenames = [f[dirname_len:] + for f in allowed if not os.path.isdir(f)] + if 'README' in self.filenames: + with open(os.path.join(filename, 'README')) as f: + readme = f.read() + self.paragraph = MARKMIN(readme) + else: + self.paragraph = None + if extensions: + self.filenames = [f for f in self.filenames + if os.path.splitext(f)[-1] in extensions] + + def breadcrumbs(self, basename): + path = [] + span = SPAN() + span.append(A(basename, _href=URL())) + for arg in self.args: + span.append('/') + path.append(arg) + span.append(A(arg, _href=URL(args='/'.join(path)))) + return span + + def table_folders(self): + if self.folders: + return SPAN(H3('Folders'), + TABLE(*[TR(TD(A(folder, _href=URL(args=self.args + [folder])))) + for folder in self.folders], **dict(_class="table"))) + return '' + + @staticmethod + def __in_base(subdir, basedir, sep=os.path.sep): + """True if subdir/ is under basedir/""" + s = lambda f: '%s%s' % (f.rstrip(sep), sep) # f -> f/ + # The trailing '/' is for the case of '/foobar' in_base of '/foo': + # - becase '/foobar' starts with '/foo' + # - but '/foobar/' doesn't start with '/foo/' + return s(subdir).startswith(s(basedir)) + + def in_base(self, f): + """True if f/ is under self.base/ + Where f ans slef.base are normalized paths + """ + return self.__in_base(self.normalize_path(f), self.base) + + def normalize_path(self, f): + if self.follow_symlink_out: + return os.path.normpath(f) + else: + return os.path.realpath(f) + + def issymlink_out(self, f): + """True if f is a symlink and is pointing outside of self.base""" + return os.path.islink(f) and not self.in_base(f) + + @staticmethod + def isprivate(f): + # remove '/private' prefix to deal with symbolic links on OSX + if f.startswith('/private/'): + f = f[8:] + return 'private' in f or f.startswith('.') or f.endswith('~') + + @staticmethod + def isimage(f): + return os.path.splitext(f)[-1].lower() in ( + '.png', '.jpg', '.jpeg', '.gif', '.tiff') + + def table_files(self, width=160): + if self.filenames: + return SPAN(H3('Files'), + TABLE(*[TR(TD(A(f, _href=URL(args=self.args + [f]))), + TD(IMG(_src=URL(args=self.args + [f]), + _style='max-width:%spx' % width) + if width and self.isimage(f) else '')) + for f in self.filenames], **dict(_class="table"))) + return '' + + def xml(self): + return DIV( + H2(self.breadcrumbs(self.basename)), + self.paragraph or '', + self.table_folders(), + self.table_files()).xml() + + +class Wiki(object): + everybody = 'everybody' + rows_page = 25 + + def markmin_base(self, body): + return MARKMIN(body, extra=self.settings.extra, + url=True, environment=self.env, + autolinks=lambda link: expand_one(link, {})).xml() + + def render_tags(self, tags): + return DIV( + _class='w2p_wiki_tags', + *[A(t.strip(), _href=URL(args='_search', vars=dict(q=t))) + for t in tags or [] if t.strip()]) + + def markmin_render(self, page): + return self.markmin_base(page.body) + self.render_tags(page.tags).xml() + + def html_render(self, page): + html = page.body + # @///function -> http://..../function + html = replace_at_urls(html, URL) + # http://...jpg -> ` : Sets a custom render function + - `dict(html=, markmin=...)`: dict(...) allows + multiple custom render functions + - "multiple" : Is the same as `{}`. It enables per-record + formats using builtins + + """ + engines = set(['markmin', 'html']) + show_engine = False + if render == "multiple": + render = {} + if isinstance(render, dict): + [engines.add(key) for key in render] + show_engine = True + settings.render = render + perms = settings.manage_permissions = manage_permissions + + settings.force_prefix = force_prefix + settings.restrict_search = restrict_search + settings.extra = extra or {} + settings.menu_groups = menu_groups + settings.templates = templates + settings.controller = controller + settings.function = function + settings.groups = auth.user_groups.values() \ + if groups is None else groups + + db = auth.db + self.env = env or {} + self.env['component'] = Wiki.component + self.auth = auth + self.wiki_menu_items = None + + if self.auth.user: + self.settings.force_prefix = force_prefix % self.auth.user + else: + self.settings.force_prefix = force_prefix + + self.host = current.request.env.http_host + + table_definitions = [ + ('wiki_page', { + 'args': [ + Field('slug', + requires=[IS_SLUG(), + IS_NOT_IN_DB(db, 'wiki_page.slug')], + writable=False), + Field('title', length=255, unique=True), + Field('body', 'text', notnull=True), + Field('tags', 'list:string'), + Field('can_read', 'list:string', + writable=perms, + readable=perms, + default=[Wiki.everybody]), + Field('can_edit', 'list:string', + writable=perms, readable=perms, + default=[Wiki.everybody]), + Field('changelog'), + Field('html', 'text', + compute=self.get_renderer(), + readable=False, writable=False), + Field('render', default="markmin", + readable=show_engine, + writable=show_engine, + requires=IS_EMPTY_OR( + IS_IN_SET(engines))), + auth.signature], + 'vars': {'format': '%(title)s', 'migrate': migrate}}), + ('wiki_tag', { + 'args': [ + Field('name'), + Field('wiki_page', 'reference wiki_page'), + auth.signature], + 'vars':{'format': '%(title)s', 'migrate': migrate}}), + ('wiki_media', { + 'args': [ + Field('wiki_page', 'reference wiki_page'), + Field('title', required=True), + Field('filename', 'upload', required=True), + auth.signature], + 'vars': {'format': '%(title)s', 'migrate': migrate}}), + ] + + # define only non-existent tables + for key, value in table_definitions: + args = [] + if key not in db.tables(): + # look for wiki_ extra fields in auth.settings + extra_fields = auth.settings.extra_fields + if extra_fields: + if key in extra_fields: + if extra_fields[key]: + for field in extra_fields[key]: + args.append(field) + args += value['args'] + db.define_table(key, *args, **value['vars']) + + if self.settings.templates is None and not self.settings.manage_permissions: + self.settings.templates = \ + db.wiki_page.tags.contains('template') & db.wiki_page.can_read.contains('everybody') + + def update_tags_insert(page, id, db=db): + for tag in page.tags or []: + tag = tag.strip().lower() + if tag: + db.wiki_tag.insert(name=tag, wiki_page=id) + + def update_tags_update(dbset, page, db=db): + page = dbset.select(limitby=(0, 1)).first() + db(db.wiki_tag.wiki_page == page.id).delete() + for tag in page.tags or []: + tag = tag.strip().lower() + if tag: + db.wiki_tag.insert(name=tag, wiki_page=page.id) + db.wiki_page._after_insert.append(update_tags_insert) + db.wiki_page._after_update.append(update_tags_update) + + if (auth.user and + check_credentials(current.request, gae_login=False) and + 'wiki_editor' not in auth.user_groups.values() and + self.settings.groups == auth.user_groups.values()): + group = db.auth_group(role='wiki_editor') + gid = group.id if group else db.auth_group.insert( + role='wiki_editor') + auth.add_membership(gid) + + settings.lock_keys = True + + # WIKI ACCESS POLICY + + def not_authorized(self, page=None): + raise HTTP(401) + + def can_read(self, page): + if 'everybody' in page.can_read or not self.settings.manage_permissions: + return True + elif self.auth.user: + groups = self.settings.groups + if ('wiki_editor' in groups or + set(groups).intersection(set(page.can_read + page.can_edit)) or + page.created_by == self.auth.user.id): + return True + return False + + def can_edit(self, page=None): + if not self.auth.user: + redirect(self.auth.settings.login_url) + groups = self.settings.groups + return ('wiki_editor' in groups or + (page is None and 'wiki_author' in groups) or + page is not None and (set(groups).intersection(set(page.can_edit)) or + page.created_by == self.auth.user.id)) + + def can_manage(self): + if not self.auth.user: + return False + groups = self.settings.groups + return 'wiki_editor' in groups + + def can_search(self): + return True + + def can_see_menu(self): + if self.auth.user: + if self.settings.menu_groups is None: + return True + else: + groups = self.settings.groups + if any(t in self.settings.menu_groups for t in groups): + return True + return False + + # END POLICY + + def automenu(self): + """adds the menu if not present""" + if (not self.wiki_menu_items and self.settings.controller and self.settings.function): + self.wiki_menu_items = self.menu(self.settings.controller, + self.settings.function) + current.response.menu += self.wiki_menu_items + + def __call__(self): + request = current.request + settings = self.settings + settings.controller = settings.controller or request.controller + settings.function = settings.function or request.function + self.automenu() + + zero = request.args(0) or 'index' + if zero and zero.isdigit(): + return self.media(int(zero)) + elif not zero or not zero.startswith('_'): + return self.read(zero) + elif zero == '_edit': + return self.edit(request.args(1) or 'index', request.args(2) or 0) + elif zero == '_editmedia': + return self.editmedia(request.args(1) or 'index') + elif zero == '_create': + return self.create() + elif zero == '_pages': + return self.pages() + elif zero == '_search': + return self.search() + elif zero == '_recent': + ipage = int(request.vars.page or 0) + query = self.auth.db.wiki_page.created_by == request.args( + 1, cast=int) + return self.search(query=query, + orderby=~self.auth.db.wiki_page.created_on, + limitby=(ipage * self.rows_page, + (ipage + 1) * self.rows_page), + ) + elif zero == '_cloud': + return self.cloud() + elif zero == '_preview': + return self.preview(self.get_renderer()) + + def first_paragraph(self, page): + if not self.can_read(page): + mm = (page.body or '').replace('\r', '') + ps = [p for p in mm.split('\n\n') if not p.startswith('#') and p.strip()] + if ps: + return ps[0] + return '' + + def fix_hostname(self, body): + return (body or '').replace('://HOSTNAME', '://%s' % self.host) + + def read(self, slug, force_render=False): + if slug in '_cloud': + return self.cloud() + elif slug in '_search': + return self.search() + page = self.auth.db.wiki_page(slug=slug) + if page and (not self.can_read(page)): + return self.not_authorized(page) + if current.request.extension == 'html': + if not page: + url = URL(args=('_create', slug)) + return dict(content=A('Create page "%s"' % slug, _href=url, _class="btn")) + else: + html = page.html if not force_render else self.get_renderer()(page) + content = XML(self.fix_hostname(html)) + return dict(title=page.title, + slug=page.slug, + page=page, + content=content, + tags=page.tags, + created_on=page.created_on, + modified_on=page.modified_on) + elif current.request.extension == 'load': + return self.fix_hostname(page.html) if page else '' + else: + if not page: + raise HTTP(404) + else: + return dict(title=page.title, + slug=page.slug, + page=page, + content=page.body, + tags=page.tags, + created_on=page.created_on, + modified_on=page.modified_on) + + def edit(self, slug, from_template=0): + auth = self.auth + db = auth.db + page = db.wiki_page(slug=slug) + if not self.can_edit(page): + return self.not_authorized(page) + title_guess = ' '.join(c.capitalize() for c in slug.split('-')) + if not page: + if not (self.can_manage() or + slug.startswith(self.settings.force_prefix)): + current.session.flash = 'slug must have "%s" prefix' \ + % self.settings.force_prefix + redirect(URL(args=('_create'))) + db.wiki_page.can_read.default = [Wiki.everybody] + db.wiki_page.can_edit.default = [auth.user_group_role()] + db.wiki_page.title.default = title_guess + db.wiki_page.slug.default = slug + if slug == 'wiki-menu': + db.wiki_page.body.default = \ + '- Menu Item > @////index\n- - Submenu > http://web2py.com' + else: + db.wiki_page.body.default = db(db.wiki_page.id == from_template).select(db.wiki_page.body)[0].body \ + if int(from_template) > 0 else '## %s\n\npage content' % title_guess + vars = current.request.post_vars + if vars.body: + vars.body = vars.body.replace('://%s' % self.host, '://HOSTNAME') + form = SQLFORM(db.wiki_page, page, deletable=True, + formstyle='table2cols', showid=False).process() + if form.deleted: + current.session.flash = 'page deleted' + redirect(URL()) + elif form.accepted: + current.session.flash = 'page created' + redirect(URL(args=slug)) + script = """ + jQuery(function() { + if (!jQuery('#wiki_page_body').length) return; + var pagecontent = jQuery('#wiki_page_body'); + pagecontent.css('font-family', + 'Monaco,Menlo,Consolas,"Courier New",monospace'); + var prevbutton = jQuery(''); + var preview = jQuery('
    ').hide(); + var previewmedia = jQuery('
    '); + var form = pagecontent.closest('form'); + preview.insertBefore(form); + prevbutton.insertBefore(form); + if(%(link_media)s) { + var mediabutton = jQuery(''); + mediabutton.insertBefore(form); + previewmedia.insertBefore(form); + mediabutton.click(function() { + if (mediabutton.hasClass('nopreview')) { + web2py_component('%(urlmedia)s', 'previewmedia'); + } else { + previewmedia.empty(); + } + mediabutton.toggleClass('nopreview'); + }); + } + prevbutton.click(function(e) { + e.preventDefault(); + if (prevbutton.hasClass('nopreview')) { + prevbutton.addClass('preview').removeClass( + 'nopreview').html('Edit Source'); + try{var wiki_render = jQuery('#wiki_page_render').val()} + catch(e){var wiki_render = null;} + web2py_ajax_page('post', \ + '%(url)s', {body: jQuery('#wiki_page_body').val(), \ + render: wiki_render}, 'preview'); + form.fadeOut('fast', function() {preview.fadeIn()}); + } else { + prevbutton.addClass( + 'nopreview').removeClass('preview').html('Preview'); + preview.fadeOut('fast', function() {form.fadeIn()}); + } + }) + }) + """ % dict(url=URL(args=('_preview', slug)), link_media=('true' if page else 'false'), + urlmedia=URL(extension='load', + args=('_editmedia', slug), + vars=dict(embedded=1))) + return dict(content=TAG[''](form, SCRIPT(script))) + + def editmedia(self, slug): + auth = self.auth + db = auth.db + page = db.wiki_page(slug=slug) + if not (page and self.can_edit(page)): + return self.not_authorized(page) + self.auth.db.wiki_media.id.represent = lambda id, row: \ + id if not row.filename else \ + SPAN('@////%i/%s.%s' % (id, IS_SLUG.urlify(row.title.split('.')[0]), row.filename.split('.')[-1])) + self.auth.db.wiki_media.wiki_page.default = page.id + self.auth.db.wiki_media.wiki_page.writable = False + links = [] + csv = True + create = True + if current.request.vars.embedded: + script = "var c = jQuery('#wiki_page_body'); c.val(c.val() + jQuery('%s').text()); return false;" + fragment = self.auth.db.wiki_media.id.represent + csv = False + create = False + links = [lambda row: A('copy into source', _href='#', _onclick=script % (fragment(row.id, row)))] + content = SQLFORM.grid( + self.auth.db.wiki_media.wiki_page == page.id, + orderby=self.auth.db.wiki_media.title, + links=links, + csv=csv, + create=create, + args=['_editmedia', slug], + user_signature=False) + return dict(content=content) + + def create(self): + if not self.can_edit(): + return self.not_authorized() + db = self.auth.db + slugs = db(db.wiki_page.id > 0).select(db.wiki_page.id, db.wiki_page.slug) + options = [OPTION(row.slug, _value=row.id) for row in slugs] + options.insert(0, OPTION('', _value='')) + fields = [Field("slug", default=current.request.args(1) or + self.settings.force_prefix, + requires=(IS_SLUG(), IS_NOT_IN_DB(db, db.wiki_page.slug))), ] + if self.settings.templates: + fields.append( + Field("from_template", "reference wiki_page", + requires=IS_EMPTY_OR(IS_IN_DB(db(self.settings.templates), db.wiki_page._id, '%(slug)s')), + comment=current.T("Choose Template or empty for new Page"))) + form = SQLFORM.factory(*fields, **dict(_class="well")) + form.element("[type=submit]").attributes["_value"] = \ + current.T("Create Page from Slug") + + if form.process().accepted: + form.vars.from_template = 0 if not form.vars.from_template else form.vars.from_template + redirect(URL(args=('_edit', form.vars.slug, form.vars.from_template or 0))) # added param + return dict(content=form) + + def pages(self): + if not self.can_manage(): + return self.not_authorized() + self.auth.db.wiki_page.slug.represent = lambda slug, row: SPAN( + '@////%s' % slug) + self.auth.db.wiki_page.title.represent = lambda title, row: \ + A(title, _href=URL(args=row.slug)) + wiki_table = self.auth.db.wiki_page + content = SQLFORM.grid( + wiki_table, + fields=[wiki_table.slug, + wiki_table.title, wiki_table.tags, + wiki_table.can_read, wiki_table.can_edit], + links=[ + lambda row: + A('edit', _href=URL(args=('_edit', row.slug)), _class='btn'), + lambda row: + A('media', _href=URL(args=('_editmedia', row.slug)), _class='btn')], + details=False, editable=False, deletable=False, create=False, + orderby=self.auth.db.wiki_page.title, + args=['_pages'], + user_signature=False) + + return dict(content=content) + + def media(self, id): + request, response, db = current.request, current.response, self.auth.db + media = db.wiki_media(id) + if media: + if self.settings.manage_permissions: + page = db.wiki_page(media.wiki_page) + if not self.can_read(page): + return self.not_authorized(page) + request.args = [media.filename] + m = response.download(request, db) + current.session.forget() # get rid of the cookie + response.headers['Last-Modified'] = \ + request.utcnow.strftime("%a, %d %b %Y %H:%M:%S GMT") + if 'Content-Disposition' in response.headers: + del response.headers['Content-Disposition'] + response.headers['Pragma'] = 'cache' + response.headers['Cache-Control'] = 'private' + return m + else: + raise HTTP(404) + + def menu(self, controller='default', function='index'): + db = self.auth.db + request = current.request + menu_page = db.wiki_page(slug='wiki-menu') + menu = [] + if menu_page: + tree = {'': menu} + regex = re.compile('[\r\n\t]*(?P(\s*\-\s*)+)(?P\w.*?)\s+\>\s+(?P<link>\S+)') + for match in regex.finditer(self.fix_hostname(menu_page.body)): + base = match.group('base').replace(' ', '') + title = match.group('title') + link = match.group('link') + title_page = None + if link.startswith('@'): + items = link[2:].split('/') + if len(items) > 3: + title_page = items[3] + link = URL(a=items[0] or None, c=items[1] or controller, + f=items[2] or function, args=items[3:]) + parent = tree.get(base[1:], tree['']) + subtree = [] + tree[base] = subtree + parent.append((current.T(title), + request.args(0) == title_page, + link, subtree)) + if self.can_see_menu(): + submenu = [] + menu.append((current.T('[Wiki]'), None, None, submenu)) + if URL() == URL(controller, function): + if not str(request.args(0)).startswith('_'): + slug = request.args(0) or 'index' + mode = 1 + elif request.args(0) == '_edit': + slug = request.args(1) or 'index' + mode = 2 + elif request.args(0) == '_editmedia': + slug = request.args(1) or 'index' + mode = 3 + else: + mode = 0 + if mode in (2, 3): + submenu.append((current.T('View Page'), None, + URL(controller, function, args=slug))) + if mode in (1, 3): + submenu.append((current.T('Edit Page'), None, + URL(controller, function, args=('_edit', slug)))) + if mode in (1, 2): + submenu.append((current.T('Edit Page Media'), None, + URL(controller, function, args=('_editmedia', slug)))) + + submenu.append((current.T('Create New Page'), None, + URL(controller, function, args=('_create')))) + # Moved next if to inside self.auth.user check + if self.can_manage(): + submenu.append((current.T('Manage Pages'), None, + URL(controller, function, args=('_pages')))) + submenu.append((current.T('Edit Menu'), None, + URL(controller, function, args=('_edit', 'wiki-menu')))) + # Also moved inside self.auth.user check + submenu.append((current.T('Search Pages'), None, + URL(controller, function, args=('_search')))) + return menu + + def search(self, tags=None, query=None, cloud=True, preview=True, + limitby=(0, 100), orderby=None): + if not self.can_search(): + return self.not_authorized() + request = current.request + content = CAT() + if tags is None and query is None: + form = FORM(INPUT(_name='q', requires=IS_NOT_EMPTY(), + value=request.vars.q), + INPUT(_type="submit", _value=current.T('Search')), + _method='GET') + content.append(DIV(form, _class='w2p_wiki_form')) + if request.vars.q: + tags = [v.strip() for v in request.vars.q.split(',')] + tags = [v.lower() for v in tags if v] + if tags or query is not None: + db = self.auth.db + count = db.wiki_tag.wiki_page.count() + fields = [db.wiki_page.id, db.wiki_page.slug, + db.wiki_page.title, db.wiki_page.tags, + db.wiki_page.can_read, db.wiki_page.can_edit] + if preview: + fields.append(db.wiki_page.body) + if query is None: + query = (db.wiki_page.id == db.wiki_tag.wiki_page) &\ + (db.wiki_tag.name.belongs(tags)) + query = query | db.wiki_page.title.contains(request.vars.q) + if self.settings.restrict_search and not self.can_manage(): + query = query & (db.wiki_page.created_by == self.auth.user_id) + pages = db(query).select(count, + *fields, **dict(orderby=orderby or ~count, + groupby=reduce(lambda a, b: a | b, fields), + distinct=True, + limitby=limitby)) + if request.extension in ('html', 'load'): + if not pages: + content.append(DIV(current.T("No results"), + _class='w2p_wiki_form')) + + def link(t): + return A(t, _href=URL(args='_search', vars=dict(q=t))) + items = [DIV(H3(A(p.wiki_page.title, _href=URL( + args=p.wiki_page.slug))), + MARKMIN(self.first_paragraph(p.wiki_page)) + if preview else '', + DIV(_class='w2p_wiki_tags', + *[link(t.strip()) for t in + p.wiki_page.tags or [] if t.strip()]), + _class='w2p_wiki_search_item') + for p in pages] + content.append(DIV(_class='w2p_wiki_pages', *items)) + else: + cloud = False + content = [p.wiki_page.as_dict() for p in pages] + elif cloud: + content.append(self.cloud()['content']) + if request.extension == 'load': + return content + return dict(content=content) + + def cloud(self): + db = self.auth.db + count = db.wiki_tag.wiki_page.count(distinct=True) + ids = db(db.wiki_tag).select( + db.wiki_tag.name, count, + distinct=True, + groupby=db.wiki_tag.name, + orderby=~count, limitby=(0, 20)) + if ids: + a, b = ids[0](count), ids[-1](count) + + def style(c): + STYLE = 'padding:0 0.2em;line-height:%.2fem;font-size:%.2fem' + size = (1.5 * (c - b) / max(a - b, 1) + 1.3) + return STYLE % (1.3, size) + items = [] + for item in ids: + items.append(A(item.wiki_tag.name, + _style=style(item(count)), + _href=URL(args='_search', + vars=dict(q=item.wiki_tag.name)))) + items.append(' ') + return dict(content=DIV(_class='w2p_cloud', *items)) + + def preview(self, render): + request = current.request + # FIXME: This is an ugly hack to ensure a default render + # engine if not specified (with multiple render engines) + if 'render' not in request.post_vars: + request.post_vars.render = None + return render(request.post_vars) + + +class Config(object): + + def __init__( + self, + filename, + section, + default_values={} + ): + self.config = configparser.ConfigParser(default_values) + self.config.read(filename) + if not self.config.has_section(section): + self.config.add_section(section) + self.section = section + self.filename = filename + + def read(self): + if not(isinstance(current.session['settings_%s' % self.section], dict)): + settings = dict(self.config.items(self.section)) + else: + settings = current.session['settings_%s' % self.section] + return settings + + def save(self, options): + for option, value in options: + self.config.set(self.section, option, value) + try: + self.config.write(open(self.filename, 'w')) + result = True + except: + current.session['settings_%s' % self.section] = dict(self.config.items(self.section)) + result = False + return result + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/web2py/gluon/utf8.py b/web2py/gluon/utf8.py new file mode 100644 index 0000000..34bfa87 --- /dev/null +++ b/web2py/gluon/utf8.py @@ -0,0 +1,758 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu> +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) +| Created by Vladyslav Kozlovskyy (Ukraine) <dbdevelop©gmail.com> +| for Web2py project + +Utilities and class for UTF8 strings managing +---------------------------------------------- +""" +from __future__ import print_function +from gluon._compat import builtin as __builtin__, unicodeT, iteritems, to_unicode, to_native, reload + +__all__ = ['Utf8'] + +repr_escape_tab = {} +#FIXME PY3 +for i in range(1, 32): + repr_escape_tab[i] = to_unicode("\\"+"x%02x" % i) +repr_escape_tab[7] = u'\\a' +repr_escape_tab[8] = u'\\b' +repr_escape_tab[9] = u'\\t' +repr_escape_tab[10] = u'\\n' +repr_escape_tab[11] = u'\\v' +repr_escape_tab[12] = u'\\f' +repr_escape_tab[13] = u'\\r' +repr_escape_tab[ord('\\')] = u'\\\\' +repr_escape_tab2 = repr_escape_tab.copy() +repr_escape_tab2[ord('\'')] = u"\\'" + + +def sort_key(s): + """Unicode Collation Algorithm (UCA) (http://www.unicode.org/reports/tr10/) + is used for utf-8 and unicode strings sorting and for utf-8 strings + comparison + + Note: + pyuca is a very memory cost module! It loads the whole + "allkey.txt" file (~2mb!) into the memory. But this + functionality is needed only when sort_key() is called as a + part of sort() function or when Utf8 strings are compared. + + So, it is a lazy "sort_key" function which (ONLY ONCE, ON ITS + FIRST CALL) imports pyuca and replaces itself with a real + sort_key() function + """ + global sort_key + try: + from gluon.contrib.pyuca import unicode_collator + unicode_sort_key = unicode_collator.sort_key + sort_key = lambda s: unicode_sort_key( + to_unicode(s, 'utf-8') if isinstance(s, str) else s) + except: + sort_key = lambda s: ( + to_unicode(s, 'utf-8') if isinstance(s, str) else s).lower() + return sort_key(s) + + +def ord(char): + """Returns unicode id for utf8 or unicode *char* character + SUPPOSE that *char* is an utf-8 or unicode character only + """ + if isinstance(char, unicodeT): + return __builtin__.ord(char) + return __builtin__.ord(to_unicode(char, 'utf-8')) + + +def chr(code): + """Returns utf8-character with *code* unicode id """ + return Utf8(unichr(code)) + + +def size(string): + """Returns length of utf-8 string in bytes + + Note: + The length of correspondent utf-8 string is returned for unicode string + """ + return Utf8(string).__size__() + + +def truncate(string, length, dots='...'): + """Returns string of length < *length* or truncate string with adding + *dots* suffix to the string's end + + Args: + length (int): max length of string + dots (str or unicode): string suffix, when string is cutted + + Returns: + (utf8-str): original or cutted string + """ + text = to_unicode(string, 'utf-8') + dots = to_unicode(dots, 'utf-8') if isinstance(dots, str) else dots + if len(text) > length: + text = text[:length - len(dots)] + dots + return str.__new__(Utf8, text.encode('utf-8')) + + +class Utf8(str): + """ + Class for utf8 string storing and manipulations + + The base presupposition of this class usage is: + "ALL strings in the application are either of + utf-8 or unicode type, even when simple str + type is used. UTF-8 is only a "packed" version + of unicode, so Utf-8 and unicode strings are + interchangeable." + + CAUTION! This class is slower than str/unicode! + Do NOT use it inside intensive loops. Simply + decode string(s) to unicode before loop and + encode it back to utf-8 string(s) after + intensive calculation. + + You can see the benefit of this class in doctests() below + """ + def __new__(cls, content='', codepage='utf-8'): + if isinstance(content, unicodeT): + return str.__new__(cls, to_native(content, 'utf-8')) + elif codepage in ('utf-8', 'utf8') or isinstance(content, cls): + return str.__new__(cls, content) + else: + return str.__new__(cls, to_native(to_unicode(content, codepage), 'utf-8')) + + def __repr__(self): + r''' # note that we use raw strings to avoid having to use double back slashes below + NOTE! This function is a clone of web2py:gluon.languages.utf_repl() function:: + + utf8.__repr__() works same as str.repr() when processing ascii string + >>> repr(Utf8('abc')) == repr(Utf8("abc")) == repr('abc') == repr("abc") == "'abc'" + True + >>> repr(Utf8('a"b"c')) == repr('a"b"c') == '\'a"b"c\'' + True + >>> repr(Utf8("a'b'c")) == repr("a'b'c") == '"a\'b\'c"' + True + >>> repr(Utf8('a\'b"c')) == repr('a\'b"c') == repr(Utf8("a'b\"c")) == repr("a'b\"c") == '\'a\\\'b"c\'' + True + >>> repr(Utf8('a\r\nb')) == repr('a\r\nb') == "'a\\r\\nb'" # Test for \r, \n + True + + Unlike str.repr(), Utf8.__repr__() remains utf8 content when processing utf8 string:: + + >>> repr(Utf8('中文字')) == repr(Utf8("中文字")) == "'中文字'" != repr('中文字') + True + >>> repr(Utf8('中"文"字')) == "'中\"文\"字'" != repr('中"文"字') + True + >>> repr(Utf8("中'文'字")) == '"中\'文\'字"' != repr("中'文'字") + True + >>> repr(Utf8('中\'文"字')) == repr(Utf8("中'文\"字")) == '\'中\\\'文"字\'' != repr('中\'文"字') == repr("中'文\"字") + True + >>> repr(Utf8('中\r\n文')) == "'中\\r\\n文'" != repr('中\r\n文') # Test for \r, \n + True + ''' + if str.find(self, "'") >= 0 and str.find(self, '"') < 0: # only single quote exists + return '"' + to_native(to_unicode(self, 'utf-8').translate(repr_escape_tab), 'utf-8') + '"' + else: + return "'" + to_native(to_unicode(self, 'utf-8').translate(repr_escape_tab2), 'utf-8') + "'" + + def __size__(self): + """ length of utf-8 string in bytes """ + return str.__len__(self) + + def __contains__(self, other): + return str.__contains__(self, Utf8(other)) + + def __getitem__(self, index): + return str.__new__(Utf8, to_native(to_unicode(self, 'utf-8')[index], 'utf-8')) + + def __getslice__(self, begin, end): + return str.__new__(Utf8, to_native(to_unicode(self, 'utf-8')[begin:end], 'utf-8')) + + def __add__(self, other): + return str.__new__(Utf8, str.__add__(self, unicode.encode(other, 'utf-8') + if isinstance(other, unicode) else other)) + + def __len__(self): + return len(to_unicode(self, 'utf-8')) + + def __mul__(self, integer): + return str.__new__(Utf8, str.__mul__(self, integer)) + + def __eq__(self, string): + return str.__eq__(self, Utf8(string)) + + def __ne__(self, string): + return str.__ne__(self, Utf8(string)) + + def capitalize(self): + return str.__new__(Utf8, unicode(self, 'utf-8').capitalize().encode('utf-8')) + + def center(self, length): + return str.__new__(Utf8, unicode(self, 'utf-8').center(length).encode('utf-8')) + + def upper(self): + return str.__new__(Utf8, unicode(self, 'utf-8').upper().encode('utf-8')) + + def lower(self): + return str.__new__(Utf8, unicode(self, 'utf-8').lower().encode('utf-8')) + + def title(self): + return str.__new__(Utf8, unicode(self, 'utf-8').title().encode('utf-8')) + + def index(self, string): + return unicode(self, 'utf-8').index(string if isinstance(string, unicode) else unicode(string, 'utf-8')) + + def isalnum(self): + return unicode(self, 'utf-8').isalnum() + + def isalpha(self): + return unicode(self, 'utf-8').isalpha() + + def isdigit(self): + return unicode(self, 'utf-8').isdigit() + + def islower(self): + return unicode(self, 'utf-8').islower() + + def isspace(self): + return unicode(self, 'utf-8').isspace() + + def istitle(self): + return unicode(self, 'utf-8').istitle() + + def isupper(self): + return unicode(self, 'utf-8').isupper() + + def zfill(self, length): + return str.__new__(Utf8, unicode(self, 'utf-8').zfill(length).encode('utf-8')) + + def join(self, iter): + return str.__new__(Utf8, str.join(self, [Utf8(c) for c in + list(unicode(iter, 'utf-8') if + isinstance(iter, str) else + iter)])) + + def lstrip(self, chars=None): + return str.__new__(Utf8, str.lstrip(self, None if chars is None else Utf8(chars))) + + def rstrip(self, chars=None): + return str.__new__(Utf8, str.rstrip(self, None if chars is None else Utf8(chars))) + + def strip(self, chars=None): + return str.__new__(Utf8, str.strip(self, None if chars is None else Utf8(chars))) + + def swapcase(self): + return str.__new__(Utf8, unicode(self, 'utf-8').swapcase().encode('utf-8')) + + def count(self, sub, start=0, end=None): + unistr = unicode(self, 'utf-8') + return unistr.count( + unicode(sub, 'utf-8') if isinstance(sub, str) else sub, + start, len(unistr) if end is None else end) + + def decode(self, encoding='utf-8', errors='strict'): + return str.decode(self, encoding, errors) + + def encode(self, encoding, errors='strict'): + return unicode(self, 'utf-8').encode(encoding, errors) + + def expandtabs(self, tabsize=8): + return str.__new__(Utf8, unicode(self, 'utf-8').expandtabs(tabsize).encode('utf-8')) + + def find(self, sub, start=None, end=None): + return unicode(self, 'utf-8').find(unicode(sub, 'utf-8') + if isinstance(sub, str) else sub, start, end) + + def ljust(self, width, fillchar=' '): + return str.__new__(Utf8, unicode(self, 'utf-8').ljust(width, unicode(fillchar, 'utf-8') + if isinstance(fillchar, str) else fillchar).encode('utf-8')) + + def partition(self, sep): + (head, sep, tail) = str.partition(self, Utf8(sep)) + return (str.__new__(Utf8, head), + str.__new__(Utf8, sep), + str.__new__(Utf8, tail)) + + def replace(self, old, new, count=-1): + return str.__new__(Utf8, str.replace(self, Utf8(old), Utf8(new), count)) + + def rfind(self, sub, start=None, end=None): + return unicode(self, 'utf-8').rfind(unicode(sub, 'utf-8') + if isinstance(sub, str) else sub, start, end) + + def rindex(self, string): + return unicode(self, 'utf-8').rindex(string if isinstance(string, unicode) + else unicode(string, 'utf-8')) + + def rjust(self, width, fillchar=' '): + return str.__new__(Utf8, unicode(self, 'utf-8').rjust(width, unicode(fillchar, 'utf-8') + if isinstance(fillchar, str) else fillchar).encode('utf-8')) + + def rpartition(self, sep): + (head, sep, tail) = str.rpartition(self, Utf8(sep)) + return (str.__new__(Utf8, head), + str.__new__(Utf8, sep), + str.__new__(Utf8, tail)) + + def rsplit(self, sep=None, maxsplit=-1): + return [str.__new__(Utf8, part) for part in str.rsplit(self, + None if sep is None else Utf8(sep), maxsplit)] + + def split(self, sep=None, maxsplit=-1): + return [str.__new__(Utf8, part) for part in str.split(self, + None if sep is None else Utf8(sep), maxsplit)] + + def splitlines(self, keepends=False): + return [str.__new__(Utf8, part) for part in str.splitlines(self, keepends)] + + def startswith(self, prefix, start=0, end=None): + unistr = unicode(self, 'utf-8') + if isinstance(prefix, tuple): + prefix = tuple(unicode( + s, 'utf-8') if isinstance(s, str) else s for s in prefix) + elif isinstance(prefix, str): + prefix = unicode(prefix, 'utf-8') + return unistr.startswith(prefix, start, len(unistr) if end is None else end) + + def translate(self, table, deletechars=''): + if isinstance(table, dict): + return str.__new__(Utf8, unicode(self, 'utf-8').translate(table).encode('utf-8')) + else: + return str.__new__(Utf8, str.translate(self, table, deletechars)) + + def endswith(self, prefix, start=0, end=None): + unistr = unicode(self, 'utf-8') + if isinstance(prefix, tuple): + prefix = tuple(unicode( + s, 'utf-8') if isinstance(s, str) else s for s in prefix) + elif isinstance(prefix, str): + prefix = unicode(prefix, 'utf-8') + return unistr.endswith(prefix, start, len(unistr) if end is None else end) + if hasattr(str, 'format'): # Python 2.5 hasn't got str.format() method + def format(self, *args, **kwargs): + args = [unicode( + s, 'utf-8') if isinstance(s, str) else s for s in args] + kwargs = dict((unicode(k, 'utf-8') if isinstance(k, str) else k, + unicode(v, 'utf-8') if isinstance(v, str) else v) + for k, v in iteritems(kwargs)) + return str.__new__(Utf8, unicode(self, 'utf-8').format(*args, **kwargs).encode('utf-8')) + + def __mod__(self, right): + if isinstance(right, tuple): + right = tuple(unicode(v, 'utf-8') if isinstance(v, str) else v + for v in right) + elif isinstance(right, dict): + right = dict((unicode(k, 'utf-8') if isinstance(k, str) else k, + unicode(v, 'utf-8') if isinstance(v, str) else v) + for k, v in iteritems(right)) + elif isinstance(right, str): + right = unicode(right, 'utf-8') + return str.__new__(Utf8, unicode(self, 'utf-8').__mod__(right).encode('utf-8')) + + def __ge__(self, string): + return sort_key(self) >= sort_key(string) + + def __gt__(self, string): + return sort_key(self) > sort_key(string) + + def __le__(self, string): + return sort_key(self) <= sort_key(string) + + def __lt__(self, string): + return sort_key(self) < sort_key(string) + + +if __name__ == '__main__': + def doctests(): + u""" + doctests: + >>> test_unicode=u'ПРоба Є PRobe' + >>> test_unicode_word=u'ПРоба' + >>> test_number_str='12345' + >>> test_unicode + u'\\u041f\\u0420\\u043e\\u0431\\u0430 \\u0404 PRobe' + >>> print test_unicode + ПРоба Є PRobe + >>> test_word=test_unicode_word.encode('utf-8') + >>> test_str=test_unicode.encode('utf-8') + >>> s=Utf8(test_str) + >>> s + 'ПРоба Є PRobe' + >>> type(s) + <class '__main__.Utf8'> + >>> s == test_str + True + >>> len(test_str) # wrong length of utf8-string! + 19 + >>> len(test_unicode) # RIGHT! + 13 + >>> len(s) # RIGHT! + 13 + >>> size(test_str) # size of utf-8 string (in bytes) == len(str) + 19 + >>> size(test_unicode) # size of unicode string in bytes (packed to utf-8 string) + 19 + >>> size(s) # size of utf-8 string in bytes + 19 + >>> try: # utf-8 is a multibyte string. Convert it to unicode for use with builtin ord() + ... __builtin__.ord('б') # ascii string + ... except Exception, e: + ... print 'Exception:', e + Exception: ord() expected a character, but string of length 2 found + >>> ord('б') # utf8.ord() is used(!!!) + 1073 + >>> ord(u'б') # utf8.ord() is used(!!!) + 1073 + >>> ord(s[3]) # utf8.ord() is used(!!!) + 1073 + >>> chr(ord(s[3])) # utf8.chr() and utf8.chr() is used(!!!) + 'б' + >>> type(chr(1073)) # utf8.chr() is used(!!!) + <class '__main__.Utf8'> + >>> s=Utf8(test_unicode) + >>> s + 'ПРоба Є PRobe' + >>> s == test_str + True + >>> test_str == s + True + >>> s == test_unicode + True + >>> test_unicode == s + True + >>> print test_str.upper() # only ASCII characters uppered + ПРоба Є PROBE + >>> print test_unicode.upper() # unicode gives right result + ПРОБА Є PROBE + >>> s.upper() # utf8 class use unicode.upper() + 'ПРОБА Є PROBE' + >>> type(s.upper()) + <class '__main__.Utf8'> + >>> s.lower() + 'проба є probe' + >>> type(s.lower()) + <class '__main__.Utf8'> + >>> s.capitalize() + 'Проба є probe' + >>> type(s.capitalize()) + <class '__main__.Utf8'> + >>> len(s) + 13 + >>> len(test_unicode) + 13 + >>> s+'. Probe is проба' + 'ПРоба Є PRobe. Probe is проба' + >>> type(s+'. Probe is проба') + <class '__main__.Utf8'> + >>> s+u'. Probe is проба' + 'ПРоба Є PRobe. Probe is проба' + >>> type(s+u'. Probe is проба') + <class '__main__.Utf8'> + >>> s+s + 'ПРоба Є PRobeПРоба Є PRobe' + >>> type(s+s) + <class '__main__.Utf8'> + >>> a=s + >>> a+=s + >>> a+=test_unicode + >>> a+=test_str + >>> a + 'ПРоба Є PRobeПРоба Є PRobeПРоба Є PRobeПРоба Є PRobe' + >>> type(a) + <class '__main__.Utf8'> + >>> s*3 + 'ПРоба Є PRobeПРоба Є PRobeПРоба Є PRobe' + >>> type(s*3) + <class '__main__.Utf8'> + >>> a=Utf8("-проба-") + >>> a*=10 + >>> a + '-проба--проба--проба--проба--проба--проба--проба--проба--проба--проба-' + >>> type(a) + <class '__main__.Utf8'> + >>> print "'"+test_str.center(17)+"'" # WRONG RESULT! + 'ПРоба Є PRobe' + >>> s.center(17) # RIGHT! + ' ПРоба Є PRobe ' + >>> type(s.center(17)) + <class '__main__.Utf8'> + >>> (test_word+test_number_str).isalnum() # WRONG RESULT! non ASCII chars are detected as non alpha + False + >>> Utf8(test_word+test_number_str).isalnum() + True + >>> s.isalnum() + False + >>> test_word.isalpha() # WRONG RESULT! Non ASCII characters are detected as non alpha + False + >>> Utf8(test_word).isalpha() # RIGHT! + True + >>> s.lower().islower() + True + >>> s.upper().isupper() + True + >>> print test_str.zfill(17) # WRONG RESULT! + ПРоба Є PRobe + >>> s.zfill(17) # RIGHT! + '0000ПРоба Є PRobe' + >>> type(s.zfill(17)) + <class '__main__.Utf8'> + >>> s.istitle() + False + >>> s.title().istitle() + True + >>> Utf8('1234').isdigit() + True + >>> Utf8(' \t').isspace() + True + >>> s.join('•|•') + '•ПРоба Є PRobe|ПРоба Є PRobe•' + >>> s.join((str('(utf8 тест1)'), unicode('(unicode тест2)','utf-8'), '(ascii test3)')) + '(utf8 тест1)ПРоба Є PRobe(unicode тест2)ПРоба Є PRobe(ascii test3)' + >>> type(s) + <class '__main__.Utf8'> + >>> s==test_str + True + >>> s==test_unicode + True + >>> s.swapcase() + 'прОБА є prOBE' + >>> type(s.swapcase()) + <class '__main__.Utf8'> + >>> truncate(s, 10) + 'ПРоба Є...' + >>> truncate(s, 20) + 'ПРоба Є PRobe' + >>> truncate(s, 10, '•••') # utf-8 string as *dots* + 'ПРоба Є•••' + >>> truncate(s, 10, u'®') # you can use unicode string as *dots* + 'ПРоба Є P®' + >>> type(truncate(s, 10)) + <class '__main__.Utf8'> + >>> Utf8(s.encode('koi8-u'), 'koi8-u') + 'ПРоба Є PRobe' + >>> s.decode() # convert utf-8 string to unicode + u'\\u041f\\u0420\\u043e\\u0431\\u0430 \\u0404 PRobe' + >>> a='про\\tba' + >>> str_tmp=a.expandtabs() + >>> utf8_tmp=Utf8(a).expandtabs() + >>> utf8_tmp.replace(' ','.') # RIGHT! (default tabsize is 8) + 'про.....ba' + >>> utf8_tmp.index('b') + 8 + >>> print "'"+str_tmp.replace(' ','.')+"'" # WRONG STRING LENGTH! + 'про..ba' + >>> str_tmp.index('b') # WRONG index of 'b' character + 8 + >>> print "'"+a.expandtabs(4).replace(' ','.')+"'" # WRONG RESULT! + 'про..ba' + >>> Utf8(a).expandtabs(4).replace(' ','.') # RIGHT! + 'про.ba' + >>> s.find('Є') + 6 + >>> s.find(u'Є') + 6 + >>> s.find(' ', 6) + 7 + >>> s.rfind(' ') + 7 + >>> s.partition('Є') + ('ПРоба ', 'Є', ' PRobe') + >>> s.partition(u'Є') + ('ПРоба ', 'Є', ' PRobe') + >>> (a,b,c) = s.partition('Є') + >>> type(a), type(b), type(c) + (<class '__main__.Utf8'>, <class '__main__.Utf8'>, <class '__main__.Utf8'>) + >>> s.partition(' ') + ('ПРоба', ' ', 'Є PRobe') + >>> s.rpartition(' ') + ('ПРоба Є', ' ', 'PRobe') + >>> s.index('Є') + 6 + >>> s.rindex(u'Є') + 6 + >>> s.index(' ') + 5 + >>> s.rindex(' ') + 7 + >>> a=Utf8('а б ц д е а б ц д е а\\tб ц д е') + >>> a.split() + ['а', 'б', 'ц', 'д', 'е', 'а', 'б', 'ц', 'д', 'е', 'а', 'б', 'ц', 'д', 'е'] + >>> a.rsplit() + ['а', 'б', 'ц', 'д', 'е', 'а', 'б', 'ц', 'д', 'е', 'а', 'б', 'ц', 'д', 'е'] + >>> a.expandtabs().split('б') + ['а ', ' ц д е а ', ' ц д е а ', ' ц д е'] + >>> a.expandtabs().rsplit('б') + ['а ', ' ц д е а ', ' ц д е а ', ' ц д е'] + >>> a.expandtabs().split(u'б', 1) + ['а ', ' ц д е а б ц д е а б ц д е'] + >>> a.expandtabs().rsplit(u'б', 1) + ['а б ц д е а б ц д е а ', ' ц д е'] + >>> a=Utf8("рядок1\\nрядок2\\nрядок3") + >>> a.splitlines() + ['рядок1', 'рядок2', 'рядок3'] + >>> a.splitlines(True) + ['рядок1\\n', 'рядок2\\n', 'рядок3'] + >>> s[6] + 'Є' + >>> s[0] + 'П' + >>> s[-1] + 'e' + >>> s[:10] + 'ПРоба Є PR' + >>> s[2:-2:2] + 'оаЄPo' + >>> s[::-1] + 'eboRP Є абоРП' + >>> s.startswith('ПР') + True + >>> s.startswith(('ПР', u'об'),0) + True + >>> s.startswith(u'об', 2, 4) + True + >>> s.endswith('be') + True + >>> s.endswith(('be', 'PR', u'Є')) + True + >>> s.endswith('PR', 8, 10) + True + >>> s.endswith('Є', -7, -6) + True + >>> s.count(' ') + 2 + >>> s.count(' ',6) + 1 + >>> s.count(u'Є') + 1 + >>> s.count('Є', 0, 5) + 0 + >>> Utf8("Parameters: '%(проба)s', %(probe)04d, %(проба2)s") % { u"проба": s, + ... "not used": "???", "probe": 2, "проба2": u"ПРоба Probe" } + "Parameters: 'ПРоба Є PRobe', 0002, ПРоба Probe" + >>> a=Utf8(u"Параметр: (%s)-(%s)-[%s]") + >>> a%=(s, s[::-1], 1000) + >>> a + 'Параметр: (ПРоба Є PRobe)-(eboRP Є абоРП)-[1000]' + >>> if hasattr(Utf8, 'format'): + ... Utf8("Проба <{0}>, {1}, {param1}, {param2}").format(s, u"中文字", + ... param1="барабан", param2=1000) == 'Проба <ПРоба Є PRobe>, 中文字, барабан, 1000' + ... else: # format() method is not used in python with version <2.6: + ... print True + True + >>> u'Б'<u'Ї' # WRONG ORDER! + False + >>> 'Б'<'Ї' # WRONG ORDER! + False + >>> Utf8('Б')<'Ї' # RIGHT! + True + >>> u'д'>u'ґ' # WRONG ORDER! + False + >>> Utf8('д')>Utf8('ґ') # RIGHT! + True + >>> u'є'<=u'ж' # WRONG ORDER! + False + >>> Utf8('є')<=u'ж' # RIGHT! + True + >>> Utf8('є')<=u'є' + True + >>> u'Ї'>=u'И' # WRONG ORDER! + False + >>> Utf8(u'Ї') >= u'И' # RIGHT + True + >>> Utf8('Є') >= 'Є' + True + >>> a="яжертиуіопшщїасдфгґхйклчєзьцвбнмюЯЖЕРТИУІОПШЩЇАСДФГҐХЙКЛЧЗЬЦВБНМЮЄ" # str type + >>> b=u"яжертиуіопшщїасдфгґхйклчєзьцвбнмюЯЖЕРТИУІОПШЩЇАСДФГҐХЙКЛЧЗЬЦВБНМЮЄ" # unicode type + >>> c=Utf8("яжертиуіопшщїасдфгґхйклчєзьцвбнмюЯЖЕРТИУІОПШЩЇАСДФГҐХЙКЛЧЗЬЦВБНМЮЄ") # utf8 class + >>> result = "".join(sorted(a)) + >>> result[0:20] # result is not utf8 string, because bytes, not utf8-characters were sorted + '\\x80\\x81\\x82\\x83\\x84\\x84\\x85\\x86\\x86\\x87\\x87\\x88\\x89\\x8c\\x8e\\x8f\\x90\\x90\\x91\\x91' + >>> try: + ... unicode(result, 'utf-8') # try to convert result (utf-8?) to unicode + ... except Exception, e: + ... print 'Exception:', e + Exception: 'utf8' codec can't decode byte 0x80 in position 0: unexpected code byte + >>> try: # FAILED! (working with bytes, not with utf8-charactes) + ... "".join( sorted(a, key=sort_key) ) # utf8.sort_key may be used with utf8 or unicode strings only! + ... except Exception, e: + ... print 'Exception:', e + Exception: 'utf8' codec can't decode byte 0xd1 in position 0: unexpected end of data + >>> print "".join( sorted(Utf8(a))) # converting *a* to unicode or utf8-string gives us correct result + аАбБвВгГґҐдДеЕєЄжЖзЗиИіІїЇйЙкКлЛмМнНоОпПрРсСтТуУфФхХцЦчЧшШщЩьЬюЮяЯ + >>> print u"".join( sorted(b) ) # WRONG ORDER! Default sort key is used + ЄІЇАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЮЯабвгдежзийклмнопрстуфхцчшщьюяєіїҐґ + >>> print u"".join( sorted(b, key=sort_key) ) # RIGHT ORDER! utf8.sort_key is used + аАбБвВгГґҐдДеЕєЄжЖзЗиИіІїЇйЙкКлЛмМнНоОпПрРсСтТуУфФхХцЦчЧшШщЩьЬюЮяЯ + >>> print "".join( sorted(c) ) # RIGHT ORDER! Utf8 "rich comparison" methods are used + аАбБвВгГґҐдДеЕєЄжЖзЗиИіІїЇйЙкКлЛмМнНоОпПрРсСтТуУфФхХцЦчЧшШщЩьЬюЮяЯ + >>> print "".join( sorted(c, key=sort_key) ) # RIGHT ORDER! utf8.sort_key is used + аАбБвВгГґҐдДеЕєЄжЖзЗиИіІїЇйЙкКлЛмМнНоОпПрРсСтТуУфФхХцЦчЧшШщЩьЬюЮяЯ + >>> Utf8().join(sorted(c.decode(), key=sort_key)) # convert to unicode for better performance + 'аАбБвВгГґҐдДеЕєЄжЖзЗиИіІїЇйЙкКлЛмМнНоОпПрРсСтТуУфФхХцЦчЧшШщЩьЬюЮяЯ' + >>> for result in sorted(["Іа", "Астро", u"гала", Utf8("Гоша"), "Єва", "шовк", "аякс", "Їжа", + ... "ґанок", Utf8("Дар'я"), "білінг", "веб", u"Жужа", "проба", u"тест", + ... "абетка", "яблуко", "Юляся", "Київ", "лимонад", "ложка", "Матриця", + ... ], key=sort_key): + ... print result.ljust(20), type(result) + абетка <type 'str'> + Астро <type 'str'> + аякс <type 'str'> + білінг <type 'str'> + веб <type 'str'> + гала <type 'unicode'> + ґанок <type 'str'> + Гоша <class '__main__.Utf8'> + Дар'я <class '__main__.Utf8'> + Єва <type 'str'> + Жужа <type 'unicode'> + Іа <type 'str'> + Їжа <type 'str'> + Київ <type 'str'> + лимонад <type 'str'> + ложка <type 'str'> + Матриця <type 'str'> + проба <type 'str'> + тест <type 'unicode'> + шовк <type 'str'> + Юляся <type 'str'> + яблуко <type 'str'> + + >>> a=Utf8("中文字") + >>> L=list(a) + >>> L + ['中', '文', '字'] + >>> a="".join(L) + >>> print a + 中文字 + >>> type(a) + <type 'str'> + >>> a="中文字" # standard str type + >>> L=list(a) + >>> L + ['\\xe4', '\\xb8', '\\xad', '\\xe6', '\\x96', '\\x87', '\\xe5', '\\xad', '\\x97'] + >>> from string import maketrans + >>> str_tab=maketrans('PRobe','12345') + >>> unicode_tab={ord(u'П'):ord(u'Ж'), + ... ord(u'Р') : u'Ш', + ... ord(Utf8('о')) : None, # utf8.ord() is used + ... ord('б') : None, # -//-//- + ... ord(u'а') : u"中文字", + ... ord(u'Є') : Utf8('•').decode(), # only unicode type is supported + ... } + >>> s.translate(unicode_tab).translate(str_tab, deletechars=' ') + 'ЖШ中文字•12345' + """ + import sys + reload(sys) + sys.setdefaultencoding("UTF-8") + import doctest + print("DOCTESTS STARTED...") + doctest.testmod() + print("DOCTESTS FINISHED") + + doctests() diff --git a/web2py/gluon/utils.py b/web2py/gluon/utils.py new file mode 100644 index 0000000..ea73804 --- /dev/null +++ b/web2py/gluon/utils.py @@ -0,0 +1,464 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu> +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +This file specifically includes utilities for security. +-------------------------------------------------------- +""" + +import threading +import struct +import uuid +import random +import inspect +import time +import os +import sys +import re +import logging +import socket +import base64 +import zlib +import hashlib +import binascii +import hmac +from hashlib import md5, sha1, sha224, sha256, sha384, sha512 +from gluon._compat import basestring, pickle, PY2, xrange, to_bytes, to_native + +_struct_2_long_long = struct.Struct('=QQ') + +try: + from Crypto.Cipher import AES + HAVE_AES = True +except ImportError: + import gluon.contrib.pyaes as PYAES + HAVE_AES = False + +if hasattr(hashlib, "pbkdf2_hmac"): + def pbkdf2_hex(data, salt, iterations=1000, keylen=24, hashfunc=None): + hashfunc = hashfunc or sha1 + hmac = hashlib.pbkdf2_hmac(hashfunc().name, to_bytes(data), + to_bytes(salt), iterations, keylen) + return binascii.hexlify(hmac) + HAVE_PBKDF2 = True +else: + try: + try: + from gluon.contrib.pbkdf2_ctypes import pbkdf2_hex + except (ImportError, AttributeError): + from gluon.contrib.pbkdf2 import pbkdf2_hex + HAVE_PBKDF2 = True + except ImportError: + try: + from .pbkdf2 import pbkdf2_hex + HAVE_PBKDF2 = True + except (ImportError, ValueError): + HAVE_PBKDF2 = False + +HAVE_COMPARE_DIGEST = False +if hasattr(hmac, 'compare_digest'): + HAVE_COMPARE_DIGEST = True + +logger = logging.getLogger("web2py") + + +def AES_new(key, IV=None): + """Return an AES cipher object and random IV if None specified.""" + if IV is None: + IV = fast_urandom16() + if HAVE_AES: + return AES.new(key, AES.MODE_CBC, IV), IV + else: + return PYAES.AESModeOfOperationCBC(key, iv=IV), IV + + +def AES_enc(cipher, data): + """Encrypt data with the cipher.""" + if HAVE_AES: + return cipher.encrypt(data) + else: + encrypter = PYAES.Encrypter(cipher) + enc = encrypter.feed(data) + enc += encrypter.feed() + return enc + + +def AES_dec(cipher, data): + """Decrypt data with the cipher.""" + if HAVE_AES: + return cipher.decrypt(data) + else: + decrypter = PYAES.Decrypter(cipher) + dec = decrypter.feed(data) + dec += decrypter.feed() + return dec + + +def compare(a, b): + """ Compares two strings and not vulnerable to timing attacks """ + if HAVE_COMPARE_DIGEST: + return hmac.compare_digest(a, b) + result = len(a) ^ len(b) + for i in xrange(len(b)): + result |= ord(a[i % len(a)]) ^ ord(b[i]) + return result == 0 + + +def md5_hash(text): + """Generate an md5 hash with the given text.""" + return md5(to_bytes(text)).hexdigest() + + +def simple_hash(text, key='', salt='', digest_alg='md5'): + """Generate hash with the given text using the specified digest algorithm.""" + text = to_bytes(text) + key = to_bytes(key) + salt = to_bytes(salt) + if not digest_alg: + raise RuntimeError("simple_hash with digest_alg=None") + elif not isinstance(digest_alg, str): # manual approach + h = digest_alg(text + key + salt) + elif digest_alg.startswith('pbkdf2'): # latest and coolest! + iterations, keylen, alg = digest_alg[7:-1].split(',') + return to_native(pbkdf2_hex(text, salt, int(iterations), + int(keylen), get_digest(alg))) + elif key: # use hmac + digest_alg = get_digest(digest_alg) + h = hmac.new(key + salt, text, digest_alg) + else: # compatible with third party systems + h = get_digest(digest_alg)() + h.update(text + salt) + return h.hexdigest() + + +def get_digest(value): + """Return a hashlib digest algorithm from a string.""" + if not isinstance(value, str): + return value + value = value.lower() + if value == "md5": + return md5 + elif value == "sha1": + return sha1 + elif value == "sha224": + return sha224 + elif value == "sha256": + return sha256 + elif value == "sha384": + return sha384 + elif value == "sha512": + return sha512 + else: + raise ValueError("Invalid digest algorithm: %s" % value) + +DIGEST_ALG_BY_SIZE = { + 128 // 4: 'md5', + 160 // 4: 'sha1', + 224 // 4: 'sha224', + 256 // 4: 'sha256', + 384 // 4: 'sha384', + 512 // 4: 'sha512', +} + + +def get_callable_argspec(fn): + if inspect.isfunction(fn) or inspect.ismethod(fn): + inspectable = fn + elif inspect.isclass(fn): + inspectable = fn.__init__ + elif hasattr(fn, '__call__'): + inspectable = fn.__call__ + else: + inspectable = fn + return inspect.getargspec(inspectable) + + +def pad(s, n=32): + # PKCS7v1.5 https://www.ietf.org/rfc/rfc2315.txt + padlen = n - len(s) % n + return s + bytes(bytearray(padlen * [padlen])) + + +def unpad(s, n=32): + padlen = s[-1] + if isinstance(padlen, str): + padlen = ord(padlen) # python2 + if (padlen < 1) | (padlen > n): # avoid short-circuit + # return garbage to minimize side channels + return bytes(bytearray(len(s) * [0])) + return s[:-padlen] + + +def secure_dumps(data, encryption_key, hash_key=None, compression_level=None): + dump = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) + if compression_level: + dump = zlib.compress(dump, compression_level) + encryption_key = to_bytes(encryption_key) + if not hash_key: + hash_key = hashlib.sha256(encryption_key).digest() + cipher, IV = AES_new(pad(encryption_key)[:32]) + encrypted_data = base64.urlsafe_b64encode(IV + AES_enc(cipher, pad(dump))) + signature = to_bytes(hmac.new(to_bytes(hash_key), encrypted_data, hashlib.sha256).hexdigest()) + return b'hmac256:' + signature + b':' + encrypted_data + + +def secure_loads(data, encryption_key, hash_key=None, compression_level=None): + data = to_bytes(data) + components = data.count(b':') + if components == 1: + return secure_loads_deprecated(data, encryption_key, hash_key, compression_level) + if components != 2: + return None + version, signature, encrypted_data = data.split(b':', 2) + if version != b'hmac256': + return None + encryption_key = to_bytes(encryption_key) + if not hash_key: + hash_key = hashlib.sha256(encryption_key).digest() + actual_signature = hmac.new(to_bytes(hash_key), encrypted_data, hashlib.sha256).hexdigest() + if not compare(to_native(signature), actual_signature): + return None + encrypted_data = base64.urlsafe_b64decode(encrypted_data) + IV, encrypted_data = encrypted_data[:16], encrypted_data[16:] + cipher, _ = AES_new(pad(encryption_key)[:32], IV=IV) + try: + data = unpad(AES_dec(cipher, encrypted_data)) + if compression_level: + data = zlib.decompress(data) + return pickle.loads(data) + except Exception as e: + return None + + +def __pad_deprecated(s, n=32, padchar=b' '): + return s + (32 - len(s) % 32) * padchar + + +def secure_dumps_deprecated(data, encryption_key, hash_key=None, compression_level=None): + encryption_key = to_bytes(encryption_key) + if not hash_key: + hash_key = sha1(encryption_key).hexdigest() + dump = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) + if compression_level: + dump = zlib.compress(dump, compression_level) + key = __pad_deprecated(encryption_key)[:32] + cipher, IV = AES_new(key) + encrypted_data = base64.urlsafe_b64encode(IV + AES_enc(cipher, pad(dump))) + signature = to_bytes(hmac.new(to_bytes(hash_key), encrypted_data, hashlib.md5).hexdigest()) + return signature + b':' + encrypted_data + + +def secure_loads_deprecated(data, encryption_key, hash_key=None, compression_level=None): + encryption_key = to_bytes(encryption_key) + data = to_native(data) + if ':' not in data: + return None + if not hash_key: + hash_key = sha1(encryption_key).hexdigest() + signature, encrypted_data = data.split(':', 1) + encrypted_data = to_bytes(encrypted_data) + actual_signature = hmac.new(to_bytes(hash_key), encrypted_data, hashlib.md5).hexdigest() + if not compare(signature, actual_signature): + return None + key = __pad_deprecated(encryption_key)[:32] + encrypted_data = base64.urlsafe_b64decode(encrypted_data) + IV, encrypted_data = encrypted_data[:16], encrypted_data[16:] + cipher, _ = AES_new(key, IV=IV) + try: + data = AES_dec(cipher, encrypted_data) + data = data.rstrip(b' ') + if compression_level: + data = zlib.decompress(data) + return pickle.loads(data) + except Exception as e: + return None + +### compute constant CTOKENS + + +def initialize_urandom(): + """ + This function and the web2py_uuid follow from the following discussion: + `http://groups.google.com/group/web2py-developers/browse_thread/thread/7fd5789a7da3f09` + + At startup web2py compute a unique ID that identifies the machine by adding + uuid.getnode() + int(time.time() * 1e3) + + This is a 48-bit number. It converts the number into 16 8-bit tokens. + It uses this value to initialize the entropy source ('/dev/urandom') and to seed random. + + If os.random() is not supported, it falls back to using random and issues a warning. + """ + node_id = uuid.getnode() + microseconds = int(time.time() * 1e6) + ctokens = [((node_id + microseconds) >> ((i % 6) * 8)) % + 256 for i in range(16)] + random.seed(node_id + microseconds) + try: + os.urandom(1) + have_urandom = True + if sys.platform != 'win32': + try: + # try to add process-specific entropy + frandom = open('/dev/urandom', 'wb') + try: + if PY2: + frandom.write(''.join(chr(t) for t in ctokens)) + else: + frandom.write(bytes([]).join(bytes([t]) for t in ctokens)) + finally: + frandom.close() + except IOError: + # works anyway + pass + except NotImplementedError: + have_urandom = False + logger.warning( + """Cryptographically secure session management is not possible on your system because +your system does not provide a cryptographically secure entropy source. +This is not specific to web2py; consider deploying on a different operating system.""") + if PY2: + packed = ''.join(chr(x) for x in ctokens) + else: + packed = bytes([]).join(bytes([x]) for x in ctokens) + unpacked_ctokens = _struct_2_long_long.unpack(packed) + return unpacked_ctokens, have_urandom +UNPACKED_CTOKENS, HAVE_URANDOM = initialize_urandom() + + +def fast_urandom16(urandom=[], locker=threading.RLock()): + """ + This is 4x faster than calling os.urandom(16) and prevents + the "too many files open" issue with concurrent access to os.urandom() + """ + try: + return urandom.pop() + except IndexError: + try: + locker.acquire() + ur = os.urandom(16 * 1024) + urandom += [ur[i:i + 16] for i in xrange(16, 1024 * 16, 16)] + return ur[0:16] + finally: + locker.release() + + +def web2py_uuid(ctokens=UNPACKED_CTOKENS): + """ + This function follows from the following discussion: + `http://groups.google.com/group/web2py-developers/browse_thread/thread/7fd5789a7da3f09` + + It works like uuid.uuid4 except that tries to use os.urandom() if possible + and it XORs the output with the tokens uniquely associated with this machine. + """ + rand_longs = (random.getrandbits(64), random.getrandbits(64)) + if HAVE_URANDOM: + urand_longs = _struct_2_long_long.unpack(fast_urandom16()) + byte_s = _struct_2_long_long.pack(rand_longs[0] ^ urand_longs[0] ^ ctokens[0], + rand_longs[1] ^ urand_longs[1] ^ ctokens[1]) + else: + byte_s = _struct_2_long_long.pack(rand_longs[0] ^ ctokens[0], + rand_longs[1] ^ ctokens[1]) + return str(uuid.UUID(bytes=byte_s, version=4)) + +REGEX_IPv4 = re.compile('(\d+)\.(\d+)\.(\d+)\.(\d+)') + + +def is_valid_ip_address(address): + """ + Examples: + Better than a thousand words:: + + >>> is_valid_ip_address('127.0') + False + >>> is_valid_ip_address('127.0.0.1') + True + >>> is_valid_ip_address('2001:660::1') + True + """ + # deal with special cases + if address.lower() in ('127.0.0.1', 'localhost', '::1', '::ffff:127.0.0.1'): + return True + elif address.lower() in ('unknown', ''): + return False + elif address.count('.') == 3: # assume IPv4 + if address.startswith('::ffff:'): + address = address[7:] + if hasattr(socket, 'inet_aton'): # try validate using the OS + try: + socket.inet_aton(address) + return True + except socket.error: # invalid address + return False + else: # try validate using Regex + match = REGEX_IPv4.match(address) + if match and all(0 <= int(match.group(i)) < 256 for i in (1, 2, 3, 4)): + return True + return False + elif hasattr(socket, 'inet_pton'): # assume IPv6, try using the OS + try: + socket.inet_pton(socket.AF_INET6, address) + return True + except socket.error: # invalid address + return False + else: # do not know what to do? assume it is a valid address + return True + + +def is_loopback_ip_address(ip=None, addrinfo=None): + """ + Determines whether the address appears to be a loopback address. + This assumes that the IP is valid. + """ + if addrinfo: # see socket.getaddrinfo() for layout of addrinfo tuple + if addrinfo[0] == socket.AF_INET or addrinfo[0] == socket.AF_INET6: + ip = addrinfo[4] + if not isinstance(ip, basestring): + return False + # IPv4 or IPv6-embedded IPv4 or IPv4-compatible IPv6 + if ip.count('.') == 3: + return ip.lower().startswith(('127', '::127', '0:0:0:0:0:0:127', + '::ffff:127', '0:0:0:0:0:ffff:127')) + return ip == '::1' or ip == '0:0:0:0:0:0:0:1' # IPv6 loopback + + +def getipaddrinfo(host): + """ + Filter out non-IP and bad IP addresses from getaddrinfo + """ + try: + return [addrinfo for addrinfo in socket.getaddrinfo(host, None) + if (addrinfo[0] == socket.AF_INET or + addrinfo[0] == socket.AF_INET6) + and isinstance(addrinfo[4][0], basestring)] + except socket.error: + return [] + + +def local_html_escape(data, quote=False): + """ + Works with bytes. + Replace special characters "&", "<" and ">" to HTML-safe sequences. + If the optional flag quote is true (the default), the quotation mark + characters, both double quote (") and single quote (') characters are also + translated. + """ + if PY2: + import cgi + data = cgi.escape(data, quote) + return data.replace("'", "'") if quote else data + else: + import html + if isinstance(data, str): + return html.escape(data, quote=quote) + data = data.replace(b"&", b"&") # Must be done first! + data = data.replace(b"<", b"<") + data = data.replace(b">", b">") + if quote: + data = data.replace(b'"', b""") + data = data.replace(b'\'', b"'") + return data diff --git a/web2py/gluon/validators.py b/web2py/gluon/validators.py new file mode 100644 index 0000000..7e47f79 --- /dev/null +++ b/web2py/gluon/validators.py @@ -0,0 +1,3919 @@ +#!/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu> +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) +| Thanks to ga2arch for help with IS_IN_DB and IS_NOT_IN_DB on GAE + +Validators +----------- +""" +import os +import re +import datetime +import time +import cgi +import json +import urllib +import struct +import decimal +import unicodedata + +from gluon._compat import StringIO, integer_types, basestring, unicodeT, urllib_unquote, unichr, to_bytes, PY2, \ + to_unicode, to_native, string_types, urlparse +from gluon.utils import simple_hash, web2py_uuid, DIGEST_ALG_BY_SIZE +from pydal.objects import Field, FieldVirtual, FieldMethod +from functools import reduce + +regex_isint = re.compile('^[+-]?\d+$') + +JSONErrors = (NameError, TypeError, ValueError, AttributeError, + KeyError) + +__all__ = [ + 'ANY_OF', + 'CLEANUP', + 'CRYPT', + 'IS_ALPHANUMERIC', + 'IS_DATE_IN_RANGE', + 'IS_DATE', + 'IS_DATETIME_IN_RANGE', + 'IS_DATETIME', + 'IS_DECIMAL_IN_RANGE', + 'IS_EMAIL', + 'IS_LIST_OF_EMAILS', + 'IS_EMPTY_OR', + 'IS_EXPR', + 'IS_FLOAT_IN_RANGE', + 'IS_IMAGE', + 'IS_IN_DB', + 'IS_IN_SET', + 'IS_INT_IN_RANGE', + 'IS_IPV4', + 'IS_IPV6', + 'IS_IPADDRESS', + 'IS_LENGTH', + 'IS_LIST_OF', + 'IS_LOWER', + 'IS_MATCH', + 'IS_EQUAL_TO', + 'IS_NOT_EMPTY', + 'IS_NOT_IN_DB', + 'IS_NULL_OR', + 'IS_SLUG', + 'IS_STRONG', + 'IS_TIME', + 'IS_UPLOAD_FILENAME', + 'IS_UPPER', + 'IS_URL', + 'IS_JSON', +] + +try: + from gluon.globals import current + have_current = True +except ImportError: + have_current = False + + +def translate(text): + if text is None: + return None + elif isinstance(text, (str, unicodeT)) and have_current: + if hasattr(current, 'T'): + return str(current.T(text)) + return str(text) + + +def options_sorter(x, y): + return (str(x[1]).upper() > str(y[1]).upper() and 1) or -1 + + +class Validator(object): + """ + Root for all validators, mainly for documentation purposes. + + Validators are classes used to validate input fields (including forms + generated from database tables). + + Here is an example of using a validator with a FORM:: + + INPUT(_name='a', requires=IS_INT_IN_RANGE(0, 10)) + + Here is an example of how to require a validator for a table field:: + + db.define_table('person', Field('name')) + db.person.name.requires=IS_NOT_EMPTY() + + Validators are always assigned using the requires attribute of a field. A + field can have a single validator or multiple validators. Multiple + validators are made part of a list:: + + db.person.name.requires=[IS_NOT_EMPTY(), IS_NOT_IN_DB(db, 'person.id')] + + Validators are called by the function accepts on a FORM or other HTML + helper object that contains a form. They are always called in the order in + which they are listed. + + Built-in validators have constructors that take the optional argument error + message which allows you to change the default error message. + Here is an example of a validator on a database table:: + + db.person.name.requires=IS_NOT_EMPTY(error_message=T('Fill this')) + + where we have used the translation operator T to allow for + internationalization. + + Notice that default error messages are not translated. + """ + + def formatter(self, value): + """ + For some validators returns a formatted version (matching the validator) + of value. Otherwise just returns the value. + """ + return value + + def __call__(self, value): + raise NotImplementedError + + +class IS_MATCH(Validator): + """ + Example: + Used as:: + + INPUT(_type='text', _name='name', requires=IS_MATCH('.+')) + + The argument of IS_MATCH is a regular expression:: + + >>> IS_MATCH('.+')('hello') + ('hello', None) + + >>> IS_MATCH('hell')('hello') + ('hello', None) + + >>> IS_MATCH('hell.*', strict=False)('hello') + ('hello', None) + + >>> IS_MATCH('hello')('shello') + ('shello', 'invalid expression') + + >>> IS_MATCH('hello', search=True)('shello') + ('shello', None) + + >>> IS_MATCH('hello', search=True, strict=False)('shellox') + ('shellox', None) + + >>> IS_MATCH('.*hello.*', search=True, strict=False)('shellox') + ('shellox', None) + + >>> IS_MATCH('.+')('') + ('', 'invalid expression') + + """ + + def __init__(self, expression, error_message='Invalid expression', + strict=False, search=False, extract=False, + is_unicode=False): + + if strict or not search: + if not expression.startswith('^'): + expression = '^(%s)' % expression + if strict: + if not expression.endswith('$'): + expression = '(%s)$' % expression + if is_unicode: + if not isinstance(expression, unicodeT): + expression = expression.decode('utf8') + self.regex = re.compile(expression, re.UNICODE) + else: + self.regex = re.compile(expression) + self.error_message = error_message + self.extract = extract + self.is_unicode = is_unicode or (not(PY2)) + + def __call__(self, value): + if not(PY2): # PY3 convert bytes to unicode + value = to_unicode(value) + + if self.is_unicode or not(PY2): + if not isinstance(value, unicodeT): + match = self.regex.search(str(value).decode('utf8')) + else: + match = self.regex.search(value) + else: + if not isinstance(value, unicodeT): + match = self.regex.search(str(value)) + else: + match = self.regex.search(value.encode('utf8')) + if match is not None: + return (self.extract and match.group() or value, None) + return (value, translate(self.error_message)) + + +class IS_EQUAL_TO(Validator): + """ + Example: + Used as:: + + INPUT(_type='text', _name='password') + INPUT(_type='text', _name='password2', + requires=IS_EQUAL_TO(request.vars.password)) + + The argument of IS_EQUAL_TO is a string:: + + >>> IS_EQUAL_TO('aaa')('aaa') + ('aaa', None) + + >>> IS_EQUAL_TO('aaa')('aab') + ('aab', 'no match') + + """ + + def __init__(self, expression, error_message='No match'): + self.expression = expression + self.error_message = error_message + + def __call__(self, value): + if value == self.expression: + return (value, None) + return (value, translate(self.error_message)) + + +class IS_EXPR(Validator): + """ + Example: + Used as:: + + INPUT(_type='text', _name='name', + requires=IS_EXPR('5 < int(value) < 10')) + + The argument of IS_EXPR must be python condition:: + + >>> IS_EXPR('int(value) < 2')('1') + ('1', None) + + >>> IS_EXPR('int(value) < 2')('2') + ('2', 'invalid expression') + + """ + + def __init__(self, expression, error_message='Invalid expression', environment=None): + self.expression = expression + self.error_message = error_message + self.environment = environment or {} + + def __call__(self, value): + if callable(self.expression): + return (value, self.expression(value)) + # for backward compatibility + self.environment.update(value=value) + exec('__ret__=' + self.expression, self.environment) + if self.environment['__ret__']: + return (value, None) + return (value, translate(self.error_message)) + + +class IS_LENGTH(Validator): + """ + Checks if length of field's value fits between given boundaries. Works + for both text and file inputs. + + Args: + maxsize: maximum allowed length / size + minsize: minimum allowed length / size + + Examples: + Check if text string is shorter than 33 characters:: + + INPUT(_type='text', _name='name', requires=IS_LENGTH(32)) + + Check if password string is longer than 5 characters:: + + INPUT(_type='password', _name='name', requires=IS_LENGTH(minsize=6)) + + Check if uploaded file has size between 1KB and 1MB:: + + INPUT(_type='file', _name='name', requires=IS_LENGTH(1048576, 1024)) + + Other examples:: + + >>> IS_LENGTH()('') + ('', None) + >>> IS_LENGTH()('1234567890') + ('1234567890', None) + >>> IS_LENGTH(maxsize=5, minsize=0)('1234567890') # too long + ('1234567890', 'enter from 0 to 5 characters') + >>> IS_LENGTH(maxsize=50, minsize=20)('1234567890') # too short + ('1234567890', 'enter from 20 to 50 characters') + """ + + def __init__(self, maxsize=255, minsize=0, + error_message='Enter from %(min)g to %(max)g characters'): + self.maxsize = maxsize + self.minsize = minsize + self.error_message = error_message + + def __call__(self, value): + if value is None: + length = 0 + if self.minsize <= length <= self.maxsize: + return (value, None) + elif isinstance(value, cgi.FieldStorage): + if value.file: + value.file.seek(0, os.SEEK_END) + length = value.file.tell() + value.file.seek(0, os.SEEK_SET) + elif hasattr(value, 'value'): + val = value.value + if val: + length = len(val) + else: + length = 0 + if self.minsize <= length <= self.maxsize: + return (value, None) + elif isinstance(value, str): + try: + lvalue = len(to_unicode(value)) + except: + lvalue = len(value) + if self.minsize <= lvalue <= self.maxsize: + return (value, None) + elif isinstance(value, unicodeT): + if self.minsize <= len(value) <= self.maxsize: + return (value.encode('utf8'), None) + elif isinstance(value, (bytes, bytearray)): + if self.minsize <= len(value) <= self.maxsize: + return (value, None) + elif isinstance(value, (tuple, list)): + if self.minsize <= len(value) <= self.maxsize: + return (value, None) + elif self.minsize <= len(str(value)) <= self.maxsize: + return (str(value), None) + return (value, translate(self.error_message) + % dict(min=self.minsize, max=self.maxsize)) + + +class IS_JSON(Validator): + """ + Example: + Used as:: + + INPUT(_type='text', _name='name', + requires=IS_JSON(error_message="This is not a valid json input") + + >>> IS_JSON()('{"a": 100}') + ({u'a': 100}, None) + + >>> IS_JSON()('spam1234') + ('spam1234', 'invalid json') + """ + + def __init__(self, error_message='Invalid json', native_json=False): + self.native_json = native_json + self.error_message = error_message + + def __call__(self, value): + try: + if self.native_json: + json.loads(value) # raises error in case of malformed json + return (value, None) # the serialized value is not passed + else: + return (json.loads(value), None) + except JSONErrors: + return (value, translate(self.error_message)) + + def formatter(self, value): + if value is None: + return None + if self.native_json: + return value + else: + return json.dumps(value) + + +class IS_IN_SET(Validator): + """ + Example: + Used as:: + + INPUT(_type='text', _name='name', + requires=IS_IN_SET(['max', 'john'],zero='')) + + The argument of IS_IN_SET must be a list or set:: + + >>> IS_IN_SET(['max', 'john'])('max') + ('max', None) + >>> IS_IN_SET(['max', 'john'])('massimo') + ('massimo', 'value not allowed') + >>> IS_IN_SET(['max', 'john'], multiple=True)(('max', 'john')) + (('max', 'john'), None) + >>> IS_IN_SET(['max', 'john'], multiple=True)(('bill', 'john')) + (('bill', 'john'), 'value not allowed') + >>> IS_IN_SET(('id1','id2'), ['first label','second label'])('id1') # Traditional way + ('id1', None) + >>> IS_IN_SET({'id1':'first label', 'id2':'second label'})('id1') + ('id1', None) + >>> import itertools + >>> IS_IN_SET(itertools.chain(['1','3','5'],['2','4','6']))('1') + ('1', None) + >>> IS_IN_SET([('id1','first label'), ('id2','second label')])('id1') # Redundant way + ('id1', None) + + """ + + def __init__( + self, + theset, + labels=None, + error_message='Value not allowed', + multiple=False, + zero='', + sort=False, + ): + self.multiple = multiple + if isinstance(theset, dict): + self.theset = [str(item) for item in theset] + self.labels = theset.values() + elif theset and isinstance(theset, (tuple, list)) \ + and isinstance(theset[0], (tuple, list)) and len(theset[0]) == 2: + self.theset = [str(item) for item, label in theset] + self.labels = [str(label) for item, label in theset] + else: + self.theset = [str(item) for item in theset] + self.labels = labels + self.error_message = error_message + self.zero = zero + self.sort = sort + + def options(self, zero=True): + if not self.labels: + items = [(k, k) for (i, k) in enumerate(self.theset)] + else: + items = [(k, list(self.labels)[i]) for (i, k) in enumerate(self.theset)] + if self.sort: + items.sort(key=lambda o: str(o[1]).upper()) + if zero and self.zero is not None and not self.multiple: + items.insert(0, ('', self.zero)) + return items + + def __call__(self, value): + if self.multiple: + # if below was values = re.compile("[\w\-:]+").findall(str(value)) + if not value: + values = [] + elif isinstance(value, (tuple, list)): + values = value + else: + values = [value] + else: + values = [value] + thestrset = [str(x) for x in self.theset] + failures = [x for x in values if not str(x) in thestrset] + if failures and self.theset: + return (value, translate(self.error_message)) + if self.multiple: + if isinstance(self.multiple, (tuple, list)) and \ + not self.multiple[0] <= len(values) < self.multiple[1]: + return (values, translate(self.error_message)) + return (values, None) + return (value, None) + + +regex1 = re.compile('\w+\.\w+') +regex2 = re.compile('%\(([^\)]+)\)\d*(?:\.\d+)?[a-zA-Z]') + + +class IS_IN_DB(Validator): + """ + Example: + Used as:: + + INPUT(_type='text', _name='name', + requires=IS_IN_DB(db, db.mytable.myfield, zero='')) + + used for reference fields, rendered as a dropbox + """ + + def __init__( + self, + dbset, + field, + label=None, + error_message='Value not in database', + orderby=None, + groupby=None, + distinct=None, + cache=None, + multiple=False, + zero='', + sort=False, + _and=None, + left=None, + delimiter=None, + auto_add=False, + ): + from pydal.objects import Table + if hasattr(dbset, 'define_table'): + self.dbset = dbset() + else: + self.dbset = dbset + + if isinstance(field, Table): + field = field._id + elif isinstance(field, str): + items = field.split('.') + if len(items) == 1: + field = items[0] + '.id' + + (ktable, kfield) = str(field).split('.') + if not label: + label = '%%(%s)s' % kfield + if isinstance(label, str): + if regex1.match(str(label)): + label = '%%(%s)s' % str(label).split('.')[-1] + fieldnames = regex2.findall(label) + if kfield not in fieldnames: + fieldnames.append(kfield) # kfield must be last + elif isinstance(label, Field): + fieldnames = [label.name, kfield] # kfield must be last + label = '%%(%s)s' % label.name + elif callable(label): + fieldnames = '*' + else: + raise NotImplementedError + + self.fieldnames = fieldnames # fields requires to build the formatting + self.label = label + self.ktable = ktable + self.kfield = kfield + self.error_message = error_message + self.theset = None + self.orderby = orderby + self.groupby = groupby + self.distinct = distinct + self.cache = cache + self.multiple = multiple + self.zero = zero + self.sort = sort + self._and = _and + self.left = left + self.delimiter = delimiter + self.auto_add = auto_add + + def set_self_id(self, id): + if self._and: + self._and.record_id = id + + def build_set(self): + table = self.dbset.db[self.ktable] + if self.fieldnames == '*': + fields = [f for f in table] + else: + fields = [table[k] for k in self.fieldnames] + ignore = (FieldVirtual, FieldMethod) + fields = filter(lambda f: not isinstance(f, ignore), fields) + if self.dbset.db._dbname != 'gae': + orderby = self.orderby or reduce(lambda a, b: a | b, fields) + groupby = self.groupby + distinct = self.distinct + left = self.left + dd = dict(orderby=orderby, groupby=groupby, + distinct=distinct, cache=self.cache, + cacheable=True, left=left) + records = self.dbset(table).select(*fields, **dd) + else: + orderby = self.orderby or \ + reduce(lambda a, b: a | b, ( + f for f in fields if not f.name == 'id')) + dd = dict(orderby=orderby, cache=self.cache, cacheable=True) + records = self.dbset(table).select(table.ALL, **dd) + self.theset = [str(r[self.kfield]) for r in records] + if isinstance(self.label, str): + self.labels = [self.label % r for r in records] + else: + self.labels = [self.label(r) for r in records] + + def options(self, zero=True): + self.build_set() + items = [(k, self.labels[i]) for (i, k) in enumerate(self.theset)] + if self.sort: + items.sort(key=lambda o: str(o[1]).upper()) + if zero and self.zero is not None and not self.multiple: + items.insert(0, ('', self.zero)) + return items + + def maybe_add(self, table, fieldname, value): + d = {fieldname: value} + record = table(**d) + if record: + return record.id + else: + return table.insert(**d) + + def __call__(self, value): + table = self.dbset.db[self.ktable] + field = table[self.kfield] + + if self.multiple: + if self._and: + raise NotImplementedError + if isinstance(value, list): + values = value + elif self.delimiter: + values = value.split(self.delimiter) # because of autocomplete + elif value: + values = [value] + else: + values = [] + + if field.type in ('id', 'integer'): + new_values = [] + for value in values: + if not (isinstance(value, integer_types) or value.isdigit()): + if self.auto_add: + value = str(self.maybe_add(table, self.fieldnames[0], value)) + else: + return (values, translate(self.error_message)) + new_values.append(value) + values = new_values + + if isinstance(self.multiple, (tuple, list)) and \ + not self.multiple[0] <= len(values) < self.multiple[1]: + return (values, translate(self.error_message)) + if self.theset: + if not [v for v in values if v not in self.theset]: + return (values, None) + else: + def count(values, s=self.dbset, f=field): + return s(f.belongs(map(int, values))).count() + + if self.dbset.db._adapter.dbengine == "google:datastore": + range_ids = range(0, len(values), 30) + total = sum(count(values[i:i + 30]) for i in range_ids) + if total == len(values): + return (values, None) + elif count(values) == len(values): + return (values, None) + else: + if field.type in ('id', 'integer'): + if isinstance(value, integer_types) or (isinstance(value, string_types) and value.isdigit()): + value = int(value) + elif self.auto_add: + value = self.maybe_add(table, self.fieldnames[0], value) + else: + return (value, translate(self.error_message)) + + try: + value = int(value) + except TypeError: + return (value, translate(self.error_message)) + + if self.theset: + if str(value) in self.theset: + if self._and: + return self._and(value) + else: + return (value, None) + else: + if self.dbset(field == value).count(): + if self._and: + return self._and(value) + else: + return (value, None) + return (value, translate(self.error_message)) + + +class IS_NOT_IN_DB(Validator): + """ + Example: + Used as:: + + INPUT(_type='text', _name='name', requires=IS_NOT_IN_DB(db, db.table)) + + makes the field unique + """ + + def __init__( + self, + dbset, + field, + error_message='Value already in database or empty', + allowed_override=[], + ignore_common_filters=False, + ): + + from pydal.objects import Table + if isinstance(field, Table): + field = field._id + + if hasattr(dbset, 'define_table'): + self.dbset = dbset() + else: + self.dbset = dbset + self.field = field + self.error_message = error_message + self.record_id = 0 + self.allowed_override = allowed_override + self.ignore_common_filters = ignore_common_filters + + def set_self_id(self, id): + self.record_id = id + + def __call__(self, value): + value = to_native(str(value)) + if not value.strip(): + return (value, translate(self.error_message)) + if value in self.allowed_override: + return (value, None) + (tablename, fieldname) = str(self.field).split('.') + table = self.dbset.db[tablename] + field = table[fieldname] + subset = self.dbset(field == value, + ignore_common_filters=self.ignore_common_filters) + id = self.record_id + if isinstance(id, dict): + fields = [table[f] for f in id] + row = subset.select(*fields, **dict(limitby=(0, 1), orderby_on_limitby=False)).first() + if row and any(str(row[f]) != str(id[f]) for f in id): + return (value, translate(self.error_message)) + else: + row = subset.select(table._id, field, limitby=(0, 1), orderby_on_limitby=False).first() + if row and str(row[table._id]) != str(id): + return (value, translate(self.error_message)) + return (value, None) + + +def range_error_message(error_message, what_to_enter, minimum, maximum): + """build the error message for the number range validators""" + if error_message is None: + error_message = 'Enter ' + what_to_enter + if minimum is not None and maximum is not None: + error_message += ' between %(min)g and %(max)g' + elif minimum is not None: + error_message += ' greater than or equal to %(min)g' + elif maximum is not None: + error_message += ' less than or equal to %(max)g' + if type(maximum) in integer_types: + maximum -= 1 + return translate(error_message) % dict(min=minimum, max=maximum) + + +class IS_INT_IN_RANGE(Validator): + """ + Determines that the argument is (or can be represented as) an int, + and that it falls within the specified range. The range is interpreted + in the Pythonic way, so the test is: min <= value < max. + + The minimum and maximum limits can be None, meaning no lower or upper limit, + respectively. + + Example: + Used as:: + + INPUT(_type='text', _name='name', requires=IS_INT_IN_RANGE(0, 10)) + + >>> IS_INT_IN_RANGE(1,5)('4') + (4, None) + >>> IS_INT_IN_RANGE(1,5)(4) + (4, None) + >>> IS_INT_IN_RANGE(1,5)(1) + (1, None) + >>> IS_INT_IN_RANGE(1,5)(5) + (5, 'enter an integer between 1 and 4') + >>> IS_INT_IN_RANGE(1,5)(5) + (5, 'enter an integer between 1 and 4') + >>> IS_INT_IN_RANGE(1,5)(3.5) + (3.5, 'enter an integer between 1 and 4') + >>> IS_INT_IN_RANGE(None,5)('4') + (4, None) + >>> IS_INT_IN_RANGE(None,5)('6') + ('6', 'enter an integer less than or equal to 4') + >>> IS_INT_IN_RANGE(1,None)('4') + (4, None) + >>> IS_INT_IN_RANGE(1,None)('0') + ('0', 'enter an integer greater than or equal to 1') + >>> IS_INT_IN_RANGE()(6) + (6, None) + >>> IS_INT_IN_RANGE()('abc') + ('abc', 'enter an integer') + """ + + def __init__( + self, + minimum=None, + maximum=None, + error_message=None, + ): + self.minimum = int(minimum) if minimum is not None else None + self.maximum = int(maximum) if maximum is not None else None + self.error_message = range_error_message( + error_message, 'an integer', self.minimum, self.maximum) + + def __call__(self, value): + if regex_isint.match(str(value)): + v = int(value) + if ((self.minimum is None or v >= self.minimum) and + (self.maximum is None or v < self.maximum)): + return (v, None) + return (value, self.error_message) + + +def str2dec(number): + s = str(number) + if '.' not in s: + s += '.00' + else: + s += '0' * (2 - len(s.split('.')[1])) + return s + + +class IS_FLOAT_IN_RANGE(Validator): + """ + Determines that the argument is (or can be represented as) a float, + and that it falls within the specified inclusive range. + The comparison is made with native arithmetic. + + The minimum and maximum limits can be None, meaning no lower or upper limit, + respectively. + + Example: + Used as:: + + INPUT(_type='text', _name='name', requires=IS_FLOAT_IN_RANGE(0, 10)) + + >>> IS_FLOAT_IN_RANGE(1,5)('4') + (4.0, None) + >>> IS_FLOAT_IN_RANGE(1,5)(4) + (4.0, None) + >>> IS_FLOAT_IN_RANGE(1,5)(1) + (1.0, None) + >>> IS_FLOAT_IN_RANGE(1,5)(5.25) + (5.25, 'enter a number between 1 and 5') + >>> IS_FLOAT_IN_RANGE(1,5)(6.0) + (6.0, 'enter a number between 1 and 5') + >>> IS_FLOAT_IN_RANGE(1,5)(3.5) + (3.5, None) + >>> IS_FLOAT_IN_RANGE(1,None)(3.5) + (3.5, None) + >>> IS_FLOAT_IN_RANGE(None,5)(3.5) + (3.5, None) + >>> IS_FLOAT_IN_RANGE(1,None)(0.5) + (0.5, 'enter a number greater than or equal to 1') + >>> IS_FLOAT_IN_RANGE(None,5)(6.5) + (6.5, 'enter a number less than or equal to 5') + >>> IS_FLOAT_IN_RANGE()(6.5) + (6.5, None) + >>> IS_FLOAT_IN_RANGE()('abc') + ('abc', 'enter a number') + """ + + def __init__( + self, + minimum=None, + maximum=None, + error_message=None, + dot='.' + ): + self.minimum = float(minimum) if minimum is not None else None + self.maximum = float(maximum) if maximum is not None else None + self.dot = str(dot) + self.error_message = range_error_message( + error_message, 'a number', self.minimum, self.maximum) + + def __call__(self, value): + try: + if self.dot == '.': + v = float(value) + else: + v = float(str(value).replace(self.dot, '.')) + if ((self.minimum is None or v >= self.minimum) and + (self.maximum is None or v <= self.maximum)): + return (v, None) + except (ValueError, TypeError): + pass + return (value, self.error_message) + + def formatter(self, value): + if value is None: + return None + return str2dec(value).replace('.', self.dot) + + +class IS_DECIMAL_IN_RANGE(Validator): + """ + Determines that the argument is (or can be represented as) a Python Decimal, + and that it falls within the specified inclusive range. + The comparison is made with Python Decimal arithmetic. + + The minimum and maximum limits can be None, meaning no lower or upper limit, + respectively. + + Example: + Used as:: + + INPUT(_type='text', _name='name', requires=IS_DECIMAL_IN_RANGE(0, 10)) + + >>> IS_DECIMAL_IN_RANGE(1,5)('4') + (Decimal('4'), None) + >>> IS_DECIMAL_IN_RANGE(1,5)(4) + (Decimal('4'), None) + >>> IS_DECIMAL_IN_RANGE(1,5)(1) + (Decimal('1'), None) + >>> IS_DECIMAL_IN_RANGE(1,5)(5.25) + (5.25, 'enter a number between 1 and 5') + >>> IS_DECIMAL_IN_RANGE(5.25,6)(5.25) + (Decimal('5.25'), None) + >>> IS_DECIMAL_IN_RANGE(5.25,6)('5.25') + (Decimal('5.25'), None) + >>> IS_DECIMAL_IN_RANGE(1,5)(6.0) + (6.0, 'enter a number between 1 and 5') + >>> IS_DECIMAL_IN_RANGE(1,5)(3.5) + (Decimal('3.5'), None) + >>> IS_DECIMAL_IN_RANGE(1.5,5.5)(3.5) + (Decimal('3.5'), None) + >>> IS_DECIMAL_IN_RANGE(1.5,5.5)(6.5) + (6.5, 'enter a number between 1.5 and 5.5') + >>> IS_DECIMAL_IN_RANGE(1.5,None)(6.5) + (Decimal('6.5'), None) + >>> IS_DECIMAL_IN_RANGE(1.5,None)(0.5) + (0.5, 'enter a number greater than or equal to 1.5') + >>> IS_DECIMAL_IN_RANGE(None,5.5)(4.5) + (Decimal('4.5'), None) + >>> IS_DECIMAL_IN_RANGE(None,5.5)(6.5) + (6.5, 'enter a number less than or equal to 5.5') + >>> IS_DECIMAL_IN_RANGE()(6.5) + (Decimal('6.5'), None) + >>> IS_DECIMAL_IN_RANGE(0,99)(123.123) + (123.123, 'enter a number between 0 and 99') + >>> IS_DECIMAL_IN_RANGE(0,99)('123.123') + ('123.123', 'enter a number between 0 and 99') + >>> IS_DECIMAL_IN_RANGE(0,99)('12.34') + (Decimal('12.34'), None) + >>> IS_DECIMAL_IN_RANGE()('abc') + ('abc', 'enter a number') + """ + + def __init__( + self, + minimum=None, + maximum=None, + error_message=None, + dot='.' + ): + self.minimum = decimal.Decimal(str(minimum)) if minimum is not None else None + self.maximum = decimal.Decimal(str(maximum)) if maximum is not None else None + self.dot = str(dot) + self.error_message = range_error_message( + error_message, 'a number', self.minimum, self.maximum) + + def __call__(self, value): + try: + if isinstance(value, decimal.Decimal): + v = value + else: + v = decimal.Decimal(str(value).replace(self.dot, '.')) + if ((self.minimum is None or v >= self.minimum) and + (self.maximum is None or v <= self.maximum)): + return (v, None) + except (ValueError, TypeError, decimal.InvalidOperation): + pass + return (value, self.error_message) + + def formatter(self, value): + if value is None: + return None + return str2dec(value).replace('.', self.dot) + + +def is_empty(value, empty_regex=None): + _value = value + """test empty field""" + if isinstance(value, (str, unicodeT)): + value = value.strip() + if empty_regex is not None and empty_regex.match(value): + value = '' + if value is None or value == '' or value == b'' or value == []: + return (_value, True) + return (_value, False) + + +class IS_NOT_EMPTY(Validator): + """ + Example: + Used as:: + + INPUT(_type='text', _name='name', requires=IS_NOT_EMPTY()) + + >>> IS_NOT_EMPTY()(1) + (1, None) + >>> IS_NOT_EMPTY()(0) + (0, None) + >>> IS_NOT_EMPTY()('x') + ('x', None) + >>> IS_NOT_EMPTY()(' x ') + ('x', None) + >>> IS_NOT_EMPTY()(None) + (None, 'enter a value') + >>> IS_NOT_EMPTY()('') + ('', 'enter a value') + >>> IS_NOT_EMPTY()(' ') + ('', 'enter a value') + >>> IS_NOT_EMPTY()(' \\n\\t') + ('', 'enter a value') + >>> IS_NOT_EMPTY()([]) + ([], 'enter a value') + >>> IS_NOT_EMPTY(empty_regex='def')('def') + ('', 'enter a value') + >>> IS_NOT_EMPTY(empty_regex='de[fg]')('deg') + ('', 'enter a value') + >>> IS_NOT_EMPTY(empty_regex='def')('abc') + ('abc', None) + """ + + def __init__(self, error_message='Enter a value', empty_regex=None): + self.error_message = error_message + if empty_regex is not None: + self.empty_regex = re.compile(empty_regex) + else: + self.empty_regex = None + + def __call__(self, value): + value, empty = is_empty(value, empty_regex=self.empty_regex) + if empty: + return (value, translate(self.error_message)) + return (value, None) + + +class IS_ALPHANUMERIC(IS_MATCH): + """ + Example: + Used as:: + + INPUT(_type='text', _name='name', requires=IS_ALPHANUMERIC()) + + >>> IS_ALPHANUMERIC()('1') + ('1', None) + >>> IS_ALPHANUMERIC()('') + ('', None) + >>> IS_ALPHANUMERIC()('A_a') + ('A_a', None) + >>> IS_ALPHANUMERIC()('!') + ('!', 'enter only letters, numbers, and underscore') + """ + + def __init__(self, error_message='Enter only letters, numbers, and underscore'): + IS_MATCH.__init__(self, '^[\w]*$', error_message) + + +class IS_EMAIL(Validator): + """ + Checks if field's value is a valid email address. Can be set to disallow + or force addresses from certain domain(s). + + Email regex adapted from + http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx, + generally following the RFCs, except that we disallow quoted strings + and permit underscores and leading numerics in subdomain labels + + Args: + banned: regex text for disallowed address domains + forced: regex text for required address domains + + Both arguments can also be custom objects with a match(value) method. + + Example: + Check for valid email address:: + + INPUT(_type='text', _name='name', + requires=IS_EMAIL()) + + Check for valid email address that can't be from a .com domain:: + + INPUT(_type='text', _name='name', + requires=IS_EMAIL(banned='^.*\.com(|\..*)$')) + + Check for valid email address that must be from a .edu domain:: + + INPUT(_type='text', _name='name', + requires=IS_EMAIL(forced='^.*\.edu(|\..*)$')) + + >>> IS_EMAIL()('a@b.com') + ('a@b.com', None) + >>> IS_EMAIL()('abc@def.com') + ('abc@def.com', None) + >>> IS_EMAIL()('abc@3def.com') + ('abc@3def.com', None) + >>> IS_EMAIL()('abc@def.us') + ('abc@def.us', None) + >>> IS_EMAIL()('abc@d_-f.us') + ('abc@d_-f.us', None) + >>> IS_EMAIL()('@def.com') # missing name + ('@def.com', 'enter a valid email address') + >>> IS_EMAIL()('"abc@def".com') # quoted name + ('"abc@def".com', 'enter a valid email address') + >>> IS_EMAIL()('abc+def.com') # no @ + ('abc+def.com', 'enter a valid email address') + >>> IS_EMAIL()('abc@def.x') # one-char TLD + ('abc@def.x', 'enter a valid email address') + >>> IS_EMAIL()('abc@def.12') # numeric TLD + ('abc@def.12', 'enter a valid email address') + >>> IS_EMAIL()('abc@def..com') # double-dot in domain + ('abc@def..com', 'enter a valid email address') + >>> IS_EMAIL()('abc@.def.com') # dot starts domain + ('abc@.def.com', 'enter a valid email address') + >>> IS_EMAIL()('abc@def.c_m') # underscore in TLD + ('abc@def.c_m', 'enter a valid email address') + >>> IS_EMAIL()('NotAnEmail') # missing @ + ('NotAnEmail', 'enter a valid email address') + >>> IS_EMAIL()('abc@NotAnEmail') # missing TLD + ('abc@NotAnEmail', 'enter a valid email address') + >>> IS_EMAIL()('customer/department@example.com') + ('customer/department@example.com', None) + >>> IS_EMAIL()('$A12345@example.com') + ('$A12345@example.com', None) + >>> IS_EMAIL()('!def!xyz%abc@example.com') + ('!def!xyz%abc@example.com', None) + >>> IS_EMAIL()('_Yosemite.Sam@example.com') + ('_Yosemite.Sam@example.com', None) + >>> IS_EMAIL()('~@example.com') + ('~@example.com', None) + >>> IS_EMAIL()('.wooly@example.com') # dot starts name + ('.wooly@example.com', 'enter a valid email address') + >>> IS_EMAIL()('wo..oly@example.com') # adjacent dots in name + ('wo..oly@example.com', 'enter a valid email address') + >>> IS_EMAIL()('pootietang.@example.com') # dot ends name + ('pootietang.@example.com', 'enter a valid email address') + >>> IS_EMAIL()('.@example.com') # name is bare dot + ('.@example.com', 'enter a valid email address') + >>> IS_EMAIL()('Ima.Fool@example.com') + ('Ima.Fool@example.com', None) + >>> IS_EMAIL()('Ima Fool@example.com') # space in name + ('Ima Fool@example.com', 'enter a valid email address') + >>> IS_EMAIL()('localguy@localhost') # localhost as domain + ('localguy@localhost', None) + + """ + + body_regex = re.compile(''' + ^(?!\.) # name may not begin with a dot + ( + [-a-z0-9!\#$%&'*+/=?^_`{|}~] # all legal characters except dot + | + (?<!\.)\. # single dots only + )+ + (?<!\.)$ # name may not end with a dot + ''', re.VERBOSE | re.IGNORECASE) + domain_regex = re.compile(''' + ( + localhost + | + ( + [a-z0-9] + # [sub]domain begins with alphanumeric + ( + [-\w]* # alphanumeric, underscore, dot, hyphen + [a-z0-9] # ending alphanumeric + )? + \. # ending dot + )+ + [a-z]{2,} # TLD alpha-only + )$ + ''', re.VERBOSE | re.IGNORECASE) + + regex_proposed_but_failed = re.compile('^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$', re.VERBOSE | re.IGNORECASE) + + def __init__(self, + banned=None, + forced=None, + error_message='Enter a valid email address'): + if isinstance(banned, str): + banned = re.compile(banned) + if isinstance(forced, str): + forced = re.compile(forced) + self.banned = banned + self.forced = forced + self.error_message = error_message + + def __call__(self, value): + if not(isinstance(value, (basestring, unicodeT))) or not value or '@' not in value: + return (value, translate(self.error_message)) + + body, domain = value.rsplit('@', 1) + + try: + match_body = self.body_regex.match(body) + match_domain = self.domain_regex.match(domain) + + if not match_domain: + # check for Internationalized Domain Names + # see https://docs.python.org/2/library/codecs.html#module-encodings.idna + domain_encoded = to_unicode(domain).encode('idna').decode('ascii') + match_domain = self.domain_regex.match(domain_encoded) + + match = (match_body is not None) and (match_domain is not None) + except (TypeError, UnicodeError): + # Value may not be a string where we can look for matches. + # Example: we're calling ANY_OF formatter and IS_EMAIL is asked to validate a date. + match = None + if match: + if (not self.banned or not self.banned.match(domain)) \ + and (not self.forced or self.forced.match(domain)): + return (value, None) + return (value, translate(self.error_message)) + + +class IS_LIST_OF_EMAILS(object): + """ + Example: + Used as:: + + Field('emails', 'list:string', + widget=SQLFORM.widgets.text.widget, + requires=IS_LIST_OF_EMAILS(), + represent=lambda v, r: \ + XML(', '.join([A(x, _href='mailto:'+x).xml() for x in (v or [])])) + ) + """ + split_emails = re.compile('[^,;\s]+') + + def __init__(self, error_message='Invalid emails: %s'): + self.error_message = error_message + + def __call__(self, value): + bad_emails = [] + f = IS_EMAIL() + for email in self.split_emails.findall(value): + error = f(email)[1] + if error and email not in bad_emails: + bad_emails.append(email) + if not bad_emails: + return (value, None) + else: + return (value, + translate(self.error_message) % ', '.join(bad_emails)) + + def formatter(self, value, row=None): + return ', '.join(value or []) + + +# URL scheme source: +# <http://en.wikipedia.org/wiki/URI_scheme> obtained on 2008-Nov-10 + +official_url_schemes = [ + 'aaa', + 'aaas', + 'acap', + 'cap', + 'cid', + 'crid', + 'data', + 'dav', + 'dict', + 'dns', + 'fax', + 'file', + 'ftp', + 'go', + 'gopher', + 'h323', + 'http', + 'https', + 'icap', + 'im', + 'imap', + 'info', + 'ipp', + 'iris', + 'iris.beep', + 'iris.xpc', + 'iris.xpcs', + 'iris.lws', + 'ldap', + 'mailto', + 'mid', + 'modem', + 'msrp', + 'msrps', + 'mtqp', + 'mupdate', + 'news', + 'nfs', + 'nntp', + 'opaquelocktoken', + 'pop', + 'pres', + 'prospero', + 'rtsp', + 'service', + 'shttp', + 'sip', + 'sips', + 'snmp', + 'soap.beep', + 'soap.beeps', + 'tag', + 'tel', + 'telnet', + 'tftp', + 'thismessage', + 'tip', + 'tv', + 'urn', + 'vemmi', + 'wais', + 'xmlrpc.beep', + 'xmlrpc.beep', + 'xmpp', + 'z39.50r', + 'z39.50s', +] +unofficial_url_schemes = [ + 'about', + 'adiumxtra', + 'aim', + 'afp', + 'aw', + 'callto', + 'chrome', + 'cvs', + 'ed2k', + 'feed', + 'fish', + 'gg', + 'gizmoproject', + 'iax2', + 'irc', + 'ircs', + 'itms', + 'jar', + 'javascript', + 'keyparc', + 'lastfm', + 'ldaps', + 'magnet', + 'mms', + 'msnim', + 'mvn', + 'notes', + 'nsfw', + 'psyc', + 'paparazzi:http', + 'rmi', + 'rsync', + 'secondlife', + 'sgn', + 'skype', + 'ssh', + 'sftp', + 'smb', + 'sms', + 'soldat', + 'steam', + 'svn', + 'teamspeak', + 'unreal', + 'ut2004', + 'ventrilo', + 'view-source', + 'webcal', + 'wyciwyg', + 'xfire', + 'xri', + 'ymsgr', +] +all_url_schemes = [None] + official_url_schemes + unofficial_url_schemes +http_schemes = [None, 'http', 'https'] + +# Defined in RFC 3490, Section 3.1, Requirement #1 +# Use this regex to split the authority component of a unicode URL into +# its component labels +label_split_regex = re.compile(u'[\u002e\u3002\uff0e\uff61]') + + +def escape_unicode(string): + """ + Converts a unicode string into US-ASCII, using a simple conversion scheme. + Each unicode character that does not have a US-ASCII equivalent is + converted into a URL escaped form based on its hexadecimal value. + For example, the unicode character '\u4e86' will become the string '%4e%86' + + Args: + string: unicode string, the unicode string to convert into an + escaped US-ASCII form + + Returns: + string: the US-ASCII escaped form of the inputted string + + @author: Jonathan Benn + """ + returnValue = StringIO() + + for character in string: + code = ord(character) + if code > 0x7F: + hexCode = hex(code) + returnValue.write('%' + hexCode[2:4] + '%' + hexCode[4:6]) + else: + returnValue.write(character) + + return returnValue.getvalue() + + +def unicode_to_ascii_authority(authority): + """ + Follows the steps in RFC 3490, Section 4 to convert a unicode authority + string into its ASCII equivalent. + For example, u'www.Alliancefran\xe7aise.nu' will be converted into + 'www.xn--alliancefranaise-npb.nu' + + Args: + authority: unicode string, the URL authority component to convert, + e.g. u'www.Alliancefran\xe7aise.nu' + + Returns: + string: the US-ASCII character equivalent to the inputed authority, + e.g. 'www.xn--alliancefranaise-npb.nu' + + Raises: + Exception: if the function is not able to convert the inputed + authority + + @author: Jonathan Benn + """ + # RFC 3490, Section 4, Step 1 + # The encodings.idna Python module assumes that AllowUnassigned == True + + # RFC 3490, Section 4, Step 2 + labels = label_split_regex.split(authority) + + # RFC 3490, Section 4, Step 3 + # The encodings.idna Python module assumes that UseSTD3ASCIIRules == False + + # RFC 3490, Section 4, Step 4 + # We use the ToASCII operation because we are about to put the authority + # into an IDN-unaware slot + asciiLabels = [] + import encodings.idna + for label in labels: + if label: + asciiLabels.append(to_native(encodings.idna.ToASCII(label))) + else: + # encodings.idna.ToASCII does not accept an empty string, but + # it is necessary for us to allow for empty labels so that we + # don't modify the URL + asciiLabels.append('') + # RFC 3490, Section 4, Step 5 + return str(reduce(lambda x, y: x + unichr(0x002E) + y, asciiLabels)) + + +def unicode_to_ascii_url(url, prepend_scheme): + """ + Converts the inputed unicode url into a US-ASCII equivalent. This function + goes a little beyond RFC 3490, which is limited in scope to the domain name + (authority) only. Here, the functionality is expanded to what was observed + on Wikipedia on 2009-Jan-22: + + Component Can Use Unicode? + --------- ---------------- + scheme No + authority Yes + path Yes + query Yes + fragment No + + The authority component gets converted to punycode, but occurrences of + unicode in other components get converted into a pair of URI escapes (we + assume 4-byte unicode). E.g. the unicode character U+4E2D will be + converted into '%4E%2D'. Testing with Firefox v3.0.5 has shown that it can + understand this kind of URI encoding. + + Args: + url: unicode string, the URL to convert from unicode into US-ASCII + prepend_scheme: string, a protocol scheme to prepend to the URL if + we're having trouble parsing it. + e.g. "http". Input None to disable this functionality + + Returns: + string: a US-ASCII equivalent of the inputed url + + @author: Jonathan Benn + """ + # convert the authority component of the URL into an ASCII punycode string, + # but encode the rest using the regular URI character encoding + components = urlparse.urlparse(url) + prepended = False + # If no authority was found + if not components.netloc: + # Try appending a scheme to see if that fixes the problem + scheme_to_prepend = prepend_scheme or 'http' + components = urlparse.urlparse(to_unicode(scheme_to_prepend) + u'://' + url) + prepended = True + + # if we still can't find the authority + if not components.netloc: + raise Exception('No authority component found, ' + + 'could not decode unicode to US-ASCII') + + # We're here if we found an authority, let's rebuild the URL + scheme = components.scheme + authority = components.netloc + path = components.path + query = components.query + fragment = components.fragment + + if prepended: + scheme = '' + + unparsed = urlparse.urlunparse((scheme, + unicode_to_ascii_authority(authority), + escape_unicode(path), + '', + escape_unicode(query), + str(fragment))) + if unparsed.startswith('//'): + unparsed = unparsed[2:] # Remove the // urlunparse puts in the beginning + return unparsed + + +class IS_GENERIC_URL(Validator): + """ + Rejects a URL string if any of the following is true: + * The string is empty or None + * The string uses characters that are not allowed in a URL + * The URL scheme specified (if one is specified) is not valid + + Based on RFC 2396: http://www.faqs.org/rfcs/rfc2396.html + + This function only checks the URL's syntax. It does not check that the URL + points to a real document, for example, or that it otherwise makes sense + semantically. This function does automatically prepend 'http://' in front + of a URL if and only if that's necessary to successfully parse the URL. + Please note that a scheme will be prepended only for rare cases + (e.g. 'google.ca:80') + + The list of allowed schemes is customizable with the allowed_schemes + parameter. If you exclude None from the list, then abbreviated URLs + (lacking a scheme such as 'http') will be rejected. + + The default prepended scheme is customizable with the prepend_scheme + parameter. If you set prepend_scheme to None then prepending will be + disabled. URLs that require prepending to parse will still be accepted, + but the return value will not be modified. + + @author: Jonathan Benn + + >>> IS_GENERIC_URL()('http://user@abc.com') + ('http://user@abc.com', None) + + Args: + error_message: a string, the error message to give the end user + if the URL does not validate + allowed_schemes: a list containing strings or None. Each element + is a scheme the inputed URL is allowed to use + prepend_scheme: a string, this scheme is prepended if it's + necessary to make the URL valid + + """ + + def __init__( + self, + error_message='Enter a valid URL', + allowed_schemes=None, + prepend_scheme=None, + ): + + self.error_message = error_message + if allowed_schemes is None: + self.allowed_schemes = all_url_schemes + else: + self.allowed_schemes = allowed_schemes + self.prepend_scheme = prepend_scheme + if self.prepend_scheme not in self.allowed_schemes: + raise SyntaxError("prepend_scheme='%s' is not in allowed_schemes=%s" + % (self.prepend_scheme, self.allowed_schemes)) + + GENERIC_URL = re.compile(r"%[^0-9A-Fa-f]{2}|%[^0-9A-Fa-f][0-9A-Fa-f]|%[0-9A-Fa-f][^0-9A-Fa-f]|%$|%[0-9A-Fa-f]$|%[^0-9A-Fa-f]$") + GENERIC_URL_VALID = re.compile(r"[A-Za-z0-9;/?:@&=+$,\-_\.!~*'\(\)%]+$") + URL_FRAGMENT_VALID = re.compile(r"[|A-Za-z0-9;/?:@&=+$,\-_\.!~*'\(\)%]+$") + + def __call__(self, value): + """ + Args: + value: a string, the URL to validate + + Returns: + a tuple, where tuple[0] is the inputed value (possible + prepended with prepend_scheme), and tuple[1] is either + None (success!) or the string error_message + """ + + # if we dont have anything or the URL misuses the '%' character + + if not value or self.GENERIC_URL.search(value): + return (value, translate(self.error_message)) + + if '#' in value: + url, fragment_part = value.split('#') + else: + url, fragment_part = value, '' + # if the URL is only composed of valid characters + if self.GENERIC_URL_VALID.match(url) and (not fragment_part or self.URL_FRAGMENT_VALID.match(fragment_part)): + # Then parse the URL into its components and check on + try: + components = urlparse.urlparse(urllib_unquote(value))._asdict() + except ValueError: + return (value, translate(self.error_message)) + + # Clean up the scheme before we check it + scheme = components['scheme'] + if len(scheme) == 0: + scheme = None + else: + scheme = components['scheme'].lower() + # If the scheme doesn't really exists + if scheme not in self.allowed_schemes or not scheme and ':' in components['path']: + # for the possible case of abbreviated URLs with + # ports, check to see if adding a valid scheme fixes + # the problem (but only do this if it doesn't have + # one already!) + if '://' not in value and None in self.allowed_schemes: + schemeToUse = self.prepend_scheme or 'http' + prependTest = self.__call__( + schemeToUse + '://' + value) + # if the prepend test succeeded + if prependTest[1] is None: + # if prepending in the output is enabled + if self.prepend_scheme: + return prependTest + else: + return (value, None) + else: + return (value, None) + # else the URL is not valid + return (value, translate(self.error_message)) + +# Sources (obtained 2017-Nov-11): +# http://data.iana.org/TLD/tlds-alpha-by-domain.txt +# see scripts/parse_top_level_domains.py for an easy update + +official_top_level_domains = [ + # a + 'aaa', 'aarp', 'abarth', 'abb', 'abbott', 'abbvie', 'abc', + 'able', 'abogado', 'abudhabi', 'ac', 'academy', 'accenture', + 'accountant', 'accountants', 'aco', 'active', 'actor', 'ad', + 'adac', 'ads', 'adult', 'ae', 'aeg', 'aero', 'aetna', 'af', + 'afamilycompany', 'afl', 'africa', 'ag', 'agakhan', 'agency', + 'ai', 'aig', 'aigo', 'airbus', 'airforce', 'airtel', 'akdn', + 'al', 'alfaromeo', 'alibaba', 'alipay', 'allfinanz', 'allstate', + 'ally', 'alsace', 'alstom', 'am', 'americanexpress', + 'americanfamily', 'amex', 'amfam', 'amica', 'amsterdam', + 'analytics', 'android', 'anquan', 'anz', 'ao', 'aol', + 'apartments', 'app', 'apple', 'aq', 'aquarelle', 'ar', 'arab', + 'aramco', 'archi', 'army', 'arpa', 'art', 'arte', 'as', 'asda', + 'asia', 'associates', 'at', 'athleta', 'attorney', 'au', + 'auction', 'audi', 'audible', 'audio', 'auspost', 'author', + 'auto', 'autos', 'avianca', 'aw', 'aws', 'ax', 'axa', 'az', + 'azure', + # b + 'ba', 'baby', 'baidu', 'banamex', 'bananarepublic', 'band', + 'bank', 'bar', 'barcelona', 'barclaycard', 'barclays', + 'barefoot', 'bargains', 'baseball', 'basketball', 'bauhaus', + 'bayern', 'bb', 'bbc', 'bbt', 'bbva', 'bcg', 'bcn', 'bd', 'be', + 'beats', 'beauty', 'beer', 'bentley', 'berlin', 'best', + 'bestbuy', 'bet', 'bf', 'bg', 'bh', 'bharti', 'bi', 'bible', + 'bid', 'bike', 'bing', 'bingo', 'bio', 'biz', 'bj', 'black', + 'blackfriday', 'blanco', 'blockbuster', 'blog', 'bloomberg', + 'blue', 'bm', 'bms', 'bmw', 'bn', 'bnl', 'bnpparibas', 'bo', + 'boats', 'boehringer', 'bofa', 'bom', 'bond', 'boo', 'book', + 'booking', 'boots', 'bosch', 'bostik', 'boston', 'bot', + 'boutique', 'box', 'br', 'bradesco', 'bridgestone', 'broadway', + 'broker', 'brother', 'brussels', 'bs', 'bt', 'budapest', + 'bugatti', 'build', 'builders', 'business', 'buy', 'buzz', 'bv', + 'bw', 'by', 'bz', 'bzh', + # c + 'ca', 'cab', 'cafe', 'cal', 'call', 'calvinklein', 'cam', + 'camera', 'camp', 'cancerresearch', 'canon', 'capetown', + 'capital', 'capitalone', 'car', 'caravan', 'cards', 'care', + 'career', 'careers', 'cars', 'cartier', 'casa', 'case', 'caseih', + 'cash', 'casino', 'cat', 'catering', 'catholic', 'cba', 'cbn', + 'cbre', 'cbs', 'cc', 'cd', 'ceb', 'center', 'ceo', 'cern', 'cf', + 'cfa', 'cfd', 'cg', 'ch', 'chanel', 'channel', 'chase', 'chat', + 'cheap', 'chintai', 'christmas', 'chrome', 'chrysler', 'church', + 'ci', 'cipriani', 'circle', 'cisco', 'citadel', 'citi', 'citic', + 'city', 'cityeats', 'ck', 'cl', 'claims', 'cleaning', 'click', + 'clinic', 'clinique', 'clothing', 'cloud', 'club', 'clubmed', + 'cm', 'cn', 'co', 'coach', 'codes', 'coffee', 'college', + 'cologne', 'com', 'comcast', 'commbank', 'community', 'company', + 'compare', 'computer', 'comsec', 'condos', 'construction', + 'consulting', 'contact', 'contractors', 'cooking', + 'cookingchannel', 'cool', 'coop', 'corsica', 'country', 'coupon', + 'coupons', 'courses', 'cr', 'credit', 'creditcard', + 'creditunion', 'cricket', 'crown', 'crs', 'cruise', 'cruises', + 'csc', 'cu', 'cuisinella', 'cv', 'cw', 'cx', 'cy', 'cymru', + 'cyou', 'cz', + # d + 'dabur', 'dad', 'dance', 'data', 'date', 'dating', 'datsun', + 'day', 'dclk', 'dds', 'de', 'deal', 'dealer', 'deals', 'degree', + 'delivery', 'dell', 'deloitte', 'delta', 'democrat', 'dental', + 'dentist', 'desi', 'design', 'dev', 'dhl', 'diamonds', 'diet', + 'digital', 'direct', 'directory', 'discount', 'discover', 'dish', + 'diy', 'dj', 'dk', 'dm', 'dnp', 'do', 'docs', 'doctor', 'dodge', + 'dog', 'doha', 'domains', 'dot', 'download', 'drive', 'dtv', + 'dubai', 'duck', 'dunlop', 'duns', 'dupont', 'durban', 'dvag', + 'dvr', 'dz', + # e + 'earth', 'eat', 'ec', 'eco', 'edeka', 'edu', 'education', 'ee', + 'eg', 'email', 'emerck', 'energy', 'engineer', 'engineering', + 'enterprises', 'epost', 'epson', 'equipment', 'er', 'ericsson', + 'erni', 'es', 'esq', 'estate', 'esurance', 'et', 'etisalat', + 'eu', 'eurovision', 'eus', 'events', 'everbank', 'exchange', + 'expert', 'exposed', 'express', 'extraspace', + # f + 'fage', 'fail', 'fairwinds', 'faith', 'family', 'fan', 'fans', + 'farm', 'farmers', 'fashion', 'fast', 'fedex', 'feedback', + 'ferrari', 'ferrero', 'fi', 'fiat', 'fidelity', 'fido', 'film', + 'final', 'finance', 'financial', 'fire', 'firestone', 'firmdale', + 'fish', 'fishing', 'fit', 'fitness', 'fj', 'fk', 'flickr', + 'flights', 'flir', 'florist', 'flowers', 'fly', 'fm', 'fo', + 'foo', 'food', 'foodnetwork', 'football', 'ford', 'forex', + 'forsale', 'forum', 'foundation', 'fox', 'fr', 'free', + 'fresenius', 'frl', 'frogans', 'frontdoor', 'frontier', 'ftr', + 'fujitsu', 'fujixerox', 'fun', 'fund', 'furniture', 'futbol', + 'fyi', + # g + 'ga', 'gal', 'gallery', 'gallo', 'gallup', 'game', 'games', + 'gap', 'garden', 'gb', 'gbiz', 'gd', 'gdn', 'ge', 'gea', 'gent', + 'genting', 'george', 'gf', 'gg', 'ggee', 'gh', 'gi', 'gift', + 'gifts', 'gives', 'giving', 'gl', 'glade', 'glass', 'gle', + 'global', 'globo', 'gm', 'gmail', 'gmbh', 'gmo', 'gmx', 'gn', + 'godaddy', 'gold', 'goldpoint', 'golf', 'goo', 'goodhands', + 'goodyear', 'goog', 'google', 'gop', 'got', 'gov', 'gp', 'gq', + 'gr', 'grainger', 'graphics', 'gratis', 'green', 'gripe', + 'grocery', 'group', 'gs', 'gt', 'gu', 'guardian', 'gucci', + 'guge', 'guide', 'guitars', 'guru', 'gw', 'gy', + # h + 'hair', 'hamburg', 'hangout', 'haus', 'hbo', 'hdfc', 'hdfcbank', + 'health', 'healthcare', 'help', 'helsinki', 'here', 'hermes', + 'hgtv', 'hiphop', 'hisamitsu', 'hitachi', 'hiv', 'hk', 'hkt', + 'hm', 'hn', 'hockey', 'holdings', 'holiday', 'homedepot', + 'homegoods', 'homes', 'homesense', 'honda', 'honeywell', 'horse', + 'hospital', 'host', 'hosting', 'hot', 'hoteles', 'hotels', + 'hotmail', 'house', 'how', 'hr', 'hsbc', 'ht', 'hu', 'hughes', + 'hyatt', 'hyundai', + # i + 'ibm', 'icbc', 'ice', 'icu', 'id', 'ie', 'ieee', 'ifm', 'ikano', + 'il', 'im', 'imamat', 'imdb', 'immo', 'immobilien', 'in', + 'industries', 'infiniti', 'info', 'ing', 'ink', 'institute', + 'insurance', 'insure', 'int', 'intel', 'international', 'intuit', + 'investments', 'io', 'ipiranga', 'iq', 'ir', 'irish', 'is', + 'iselect', 'ismaili', 'ist', 'istanbul', 'it', 'itau', 'itv', + 'iveco', 'iwc', + # j + 'jaguar', 'java', 'jcb', 'jcp', 'je', 'jeep', 'jetzt', 'jewelry', + 'jio', 'jlc', 'jll', 'jm', 'jmp', 'jnj', 'jo', 'jobs', 'joburg', + 'jot', 'joy', 'jp', 'jpmorgan', 'jprs', 'juegos', 'juniper', + # k + 'kaufen', 'kddi', 'ke', 'kerryhotels', 'kerrylogistics', + 'kerryproperties', 'kfh', 'kg', 'kh', 'ki', 'kia', 'kim', + 'kinder', 'kindle', 'kitchen', 'kiwi', 'km', 'kn', 'koeln', + 'komatsu', 'kosher', 'kp', 'kpmg', 'kpn', 'kr', 'krd', 'kred', + 'kuokgroup', 'kw', 'ky', 'kyoto', 'kz', + # l + 'la', 'lacaixa', 'ladbrokes', 'lamborghini', 'lamer', + 'lancaster', 'lancia', 'lancome', 'land', 'landrover', 'lanxess', + 'lasalle', 'lat', 'latino', 'latrobe', 'law', 'lawyer', 'lb', + 'lc', 'lds', 'lease', 'leclerc', 'lefrak', 'legal', 'lego', + 'lexus', 'lgbt', 'li', 'liaison', 'lidl', 'life', + 'lifeinsurance', 'lifestyle', 'lighting', 'like', 'lilly', + 'limited', 'limo', 'lincoln', 'linde', 'link', 'lipsy', 'live', + 'living', 'lixil', 'lk', 'loan', 'loans', 'localhost', 'locker', + 'locus', 'loft', 'lol', 'london', 'lotte', 'lotto', 'love', + 'lpl', 'lplfinancial', 'lr', 'ls', 'lt', 'ltd', 'ltda', 'lu', + 'lundbeck', 'lupin', 'luxe', 'luxury', 'lv', 'ly', + # m + 'ma', 'macys', 'madrid', 'maif', 'maison', 'makeup', 'man', + 'management', 'mango', 'map', 'market', 'marketing', 'markets', + 'marriott', 'marshalls', 'maserati', 'mattel', 'mba', 'mc', + 'mckinsey', 'md', 'me', 'med', 'media', 'meet', 'melbourne', + 'meme', 'memorial', 'men', 'menu', 'meo', 'merckmsd', 'metlife', + 'mg', 'mh', 'miami', 'microsoft', 'mil', 'mini', 'mint', 'mit', + 'mitsubishi', 'mk', 'ml', 'mlb', 'mls', 'mm', 'mma', 'mn', 'mo', + 'mobi', 'mobile', 'mobily', 'moda', 'moe', 'moi', 'mom', + 'monash', 'money', 'monster', 'mopar', 'mormon', 'mortgage', + 'moscow', 'moto', 'motorcycles', 'mov', 'movie', 'movistar', + 'mp', 'mq', 'mr', 'ms', 'msd', 'mt', 'mtn', 'mtr', 'mu', + 'museum', 'mutual', 'mv', 'mw', 'mx', 'my', 'mz', + # n + 'na', 'nab', 'nadex', 'nagoya', 'name', 'nationwide', 'natura', + 'navy', 'nba', 'nc', 'ne', 'nec', 'net', 'netbank', 'netflix', + 'network', 'neustar', 'new', 'newholland', 'news', 'next', + 'nextdirect', 'nexus', 'nf', 'nfl', 'ng', 'ngo', 'nhk', 'ni', + 'nico', 'nike', 'nikon', 'ninja', 'nissan', 'nissay', 'nl', 'no', + 'nokia', 'northwesternmutual', 'norton', 'now', 'nowruz', + 'nowtv', 'np', 'nr', 'nra', 'nrw', 'ntt', 'nu', 'nyc', 'nz', + # o + 'obi', 'observer', 'off', 'office', 'okinawa', 'olayan', + 'olayangroup', 'oldnavy', 'ollo', 'om', 'omega', 'one', 'ong', + 'onl', 'online', 'onyourside', 'ooo', 'open', 'oracle', 'orange', + 'org', 'organic', 'origins', 'osaka', 'otsuka', 'ott', 'ovh', + # p + 'pa', 'page', 'panasonic', 'panerai', 'paris', 'pars', + 'partners', 'parts', 'party', 'passagens', 'pay', 'pccw', 'pe', + 'pet', 'pf', 'pfizer', 'pg', 'ph', 'pharmacy', 'phd', 'philips', + 'phone', 'photo', 'photography', 'photos', 'physio', 'piaget', + 'pics', 'pictet', 'pictures', 'pid', 'pin', 'ping', 'pink', + 'pioneer', 'pizza', 'pk', 'pl', 'place', 'play', 'playstation', + 'plumbing', 'plus', 'pm', 'pn', 'pnc', 'pohl', 'poker', + 'politie', 'porn', 'post', 'pr', 'pramerica', 'praxi', 'press', + 'prime', 'pro', 'prod', 'productions', 'prof', 'progressive', + 'promo', 'properties', 'property', 'protection', 'pru', + 'prudential', 'ps', 'pt', 'pub', 'pw', 'pwc', 'py', + # q + 'qa', 'qpon', 'quebec', 'quest', 'qvc', + # r + 'racing', 'radio', 'raid', 're', 'read', 'realestate', 'realtor', + 'realty', 'recipes', 'red', 'redstone', 'redumbrella', 'rehab', + 'reise', 'reisen', 'reit', 'reliance', 'ren', 'rent', 'rentals', + 'repair', 'report', 'republican', 'rest', 'restaurant', 'review', + 'reviews', 'rexroth', 'rich', 'richardli', 'ricoh', + 'rightathome', 'ril', 'rio', 'rip', 'rmit', 'ro', 'rocher', + 'rocks', 'rodeo', 'rogers', 'room', 'rs', 'rsvp', 'ru', 'rugby', + 'ruhr', 'run', 'rw', 'rwe', 'ryukyu', + # s + 'sa', 'saarland', 'safe', 'safety', 'sakura', 'sale', 'salon', + 'samsclub', 'samsung', 'sandvik', 'sandvikcoromant', 'sanofi', + 'sap', 'sapo', 'sarl', 'sas', 'save', 'saxo', 'sb', 'sbi', 'sbs', + 'sc', 'sca', 'scb', 'schaeffler', 'schmidt', 'scholarships', + 'school', 'schule', 'schwarz', 'science', 'scjohnson', 'scor', + 'scot', 'sd', 'se', 'search', 'seat', 'secure', 'security', + 'seek', 'select', 'sener', 'services', 'ses', 'seven', 'sew', + 'sex', 'sexy', 'sfr', 'sg', 'sh', 'shangrila', 'sharp', 'shaw', + 'shell', 'shia', 'shiksha', 'shoes', 'shop', 'shopping', + 'shouji', 'show', 'showtime', 'shriram', 'si', 'silk', 'sina', + 'singles', 'site', 'sj', 'sk', 'ski', 'skin', 'sky', 'skype', + 'sl', 'sling', 'sm', 'smart', 'smile', 'sn', 'sncf', 'so', + 'soccer', 'social', 'softbank', 'software', 'sohu', 'solar', + 'solutions', 'song', 'sony', 'soy', 'space', 'spiegel', 'spot', + 'spreadbetting', 'sr', 'srl', 'srt', 'st', 'stada', 'staples', + 'star', 'starhub', 'statebank', 'statefarm', 'statoil', 'stc', + 'stcgroup', 'stockholm', 'storage', 'store', 'stream', 'studio', + 'study', 'style', 'su', 'sucks', 'supplies', 'supply', 'support', + 'surf', 'surgery', 'suzuki', 'sv', 'swatch', 'swiftcover', + 'swiss', 'sx', 'sy', 'sydney', 'symantec', 'systems', 'sz', + # t + 'tab', 'taipei', 'talk', 'taobao', 'target', 'tatamotors', + 'tatar', 'tattoo', 'tax', 'taxi', 'tc', 'tci', 'td', 'tdk', + 'team', 'tech', 'technology', 'tel', 'telecity', 'telefonica', + 'temasek', 'tennis', 'teva', 'tf', 'tg', 'th', 'thd', 'theater', + 'theatre', 'tiaa', 'tickets', 'tienda', 'tiffany', 'tips', + 'tires', 'tirol', 'tj', 'tjmaxx', 'tjx', 'tk', 'tkmaxx', 'tl', + 'tm', 'tmall', 'tn', 'to', 'today', 'tokyo', 'tools', 'top', + 'toray', 'toshiba', 'total', 'tours', 'town', 'toyota', 'toys', + 'tr', 'trade', 'trading', 'training', 'travel', 'travelchannel', + 'travelers', 'travelersinsurance', 'trust', 'trv', 'tt', 'tube', + 'tui', 'tunes', 'tushu', 'tv', 'tvs', 'tw', 'tz', + # u + 'ua', 'ubank', 'ubs', 'uconnect', 'ug', 'uk', 'unicom', + 'university', 'uno', 'uol', 'ups', 'us', 'uy', 'uz', + # v + 'va', 'vacations', 'vana', 'vanguard', 'vc', 've', 'vegas', + 'ventures', 'verisign', 'versicherung', 'vet', 'vg', 'vi', + 'viajes', 'video', 'vig', 'viking', 'villas', 'vin', 'vip', + 'virgin', 'visa', 'vision', 'vista', 'vistaprint', 'viva', + 'vivo', 'vlaanderen', 'vn', 'vodka', 'volkswagen', 'volvo', + 'vote', 'voting', 'voto', 'voyage', 'vu', 'vuelos', + # w + 'wales', 'walmart', 'walter', 'wang', 'wanggou', 'warman', + 'watch', 'watches', 'weather', 'weatherchannel', 'webcam', + 'weber', 'website', 'wed', 'wedding', 'weibo', 'weir', 'wf', + 'whoswho', 'wien', 'wiki', 'williamhill', 'win', 'windows', + 'wine', 'winners', 'wme', 'wolterskluwer', 'woodside', 'work', + 'works', 'world', 'wow', 'ws', 'wtc', 'wtf', + # x + 'xbox', 'xerox', 'xfinity', 'xihuan', 'xin', 'xn--11b4c3d', + 'xn--1ck2e1b', 'xn--1qqw23a', 'xn--2scrj9c', 'xn--30rr7y', + 'xn--3bst00m', 'xn--3ds443g', 'xn--3e0b707e', 'xn--3hcrj9c', + 'xn--3oq18vl8pn36a', 'xn--3pxu8k', 'xn--42c2d9a', 'xn--45br5cyl', + 'xn--45brj9c', 'xn--45q11c', 'xn--4gbrim', 'xn--54b7fta0cc', + 'xn--55qw42g', 'xn--55qx5d', 'xn--5su34j936bgsg', 'xn--5tzm5g', + 'xn--6frz82g', 'xn--6qq986b3xl', 'xn--80adxhks', 'xn--80ao21a', + 'xn--80aqecdr1a', 'xn--80asehdb', 'xn--80aswg', 'xn--8y0a063a', + 'xn--90a3ac', 'xn--90ae', 'xn--90ais', 'xn--9dbq2a', + 'xn--9et52u', 'xn--9krt00a', 'xn--b4w605ferd', + 'xn--bck1b9a5dre4c', 'xn--c1avg', 'xn--c2br7g', 'xn--cck2b3b', + 'xn--cg4bki', 'xn--clchc0ea0b2g2a9gcd', 'xn--czr694b', + 'xn--czrs0t', 'xn--czru2d', 'xn--d1acj3b', 'xn--d1alf', + 'xn--e1a4c', 'xn--eckvdtc9d', 'xn--efvy88h', 'xn--estv75g', + 'xn--fct429k', 'xn--fhbei', 'xn--fiq228c5hs', 'xn--fiq64b', + 'xn--fiqs8s', 'xn--fiqz9s', 'xn--fjq720a', 'xn--flw351e', + 'xn--fpcrj9c3d', 'xn--fzc2c9e2c', 'xn--fzys8d69uvgm', + 'xn--g2xx48c', 'xn--gckr3f0f', 'xn--gecrj9c', 'xn--gk3at1e', + 'xn--h2breg3eve', 'xn--h2brj9c', 'xn--h2brj9c8c', 'xn--hxt814e', + 'xn--i1b6b1a6a2e', 'xn--imr513n', 'xn--io0a7i', 'xn--j1aef', + 'xn--j1amh', 'xn--j6w193g', 'xn--jlq61u9w7b', 'xn--jvr189m', + 'xn--kcrx77d1x4a', 'xn--kprw13d', 'xn--kpry57d', 'xn--kpu716f', + 'xn--kput3i', 'xn--l1acc', 'xn--lgbbat1ad8j', 'xn--mgb9awbf', + 'xn--mgba3a3ejt', 'xn--mgba3a4f16a', 'xn--mgba7c0bbn0a', + 'xn--mgbaakc7dvf', 'xn--mgbaam7a8h', 'xn--mgbab2bd', + 'xn--mgbai9azgqp6j', 'xn--mgbayh7gpa', 'xn--mgbb9fbpob', + 'xn--mgbbh1a', 'xn--mgbbh1a71e', 'xn--mgbc0a9azcg', + 'xn--mgbca7dzdo', 'xn--mgberp4a5d4ar', 'xn--mgbgu82a', + 'xn--mgbi4ecexp', 'xn--mgbpl2fh', 'xn--mgbt3dhd', 'xn--mgbtx2b', + 'xn--mgbx4cd0ab', 'xn--mix891f', 'xn--mk1bu44c', 'xn--mxtq1m', + 'xn--ngbc5azd', 'xn--ngbe9e0a', 'xn--ngbrx', 'xn--node', + 'xn--nqv7f', 'xn--nqv7fs00ema', 'xn--nyqy26a', 'xn--o3cw4h', + 'xn--ogbpf8fl', 'xn--p1acf', 'xn--p1ai', 'xn--pbt977c', + 'xn--pgbs0dh', 'xn--pssy2u', 'xn--q9jyb4c', 'xn--qcka1pmc', + 'xn--qxam', 'xn--rhqv96g', 'xn--rovu88b', 'xn--rvc1e0am3e', + 'xn--s9brj9c', 'xn--ses554g', 'xn--t60b56a', 'xn--tckwe', + 'xn--tiq49xqyj', 'xn--unup4y', 'xn--vermgensberater-ctb', + 'xn--vermgensberatung-pwb', 'xn--vhquv', 'xn--vuq861b', + 'xn--w4r85el8fhu5dnra', 'xn--w4rs40l', 'xn--wgbh1c', + 'xn--wgbl6a', 'xn--xhq521b', 'xn--xkc2al3hye2a', + 'xn--xkc2dl3a5ee0h', 'xn--y9a3aq', 'xn--yfro4i67o', + 'xn--ygbi2ammx', 'xn--zfr164b', 'xperia', 'xxx', 'xyz', + # y + 'yachts', 'yahoo', 'yamaxun', 'yandex', 'ye', 'yodobashi', + 'yoga', 'yokohama', 'you', 'youtube', 'yt', 'yun', + # z + 'za', 'zappos', 'zara', 'zero', 'zip', 'zippo', 'zm', 'zone', + 'zuerich', 'zw' +] + + +class IS_HTTP_URL(Validator): + """ + Rejects a URL string if any of the following is true: + * The string is empty or None + * The string uses characters that are not allowed in a URL + * The string breaks any of the HTTP syntactic rules + * The URL scheme specified (if one is specified) is not 'http' or 'https' + * The top-level domain (if a host name is specified) does not exist + + Based on RFC 2616: http://www.faqs.org/rfcs/rfc2616.html + + This function only checks the URL's syntax. It does not check that the URL + points to a real document, for example, or that it otherwise makes sense + semantically. This function does automatically prepend 'http://' in front + of a URL in the case of an abbreviated URL (e.g. 'google.ca'). + + The list of allowed schemes is customizable with the allowed_schemes + parameter. If you exclude None from the list, then abbreviated URLs + (lacking a scheme such as 'http') will be rejected. + + The default prepended scheme is customizable with the prepend_scheme + parameter. If you set prepend_scheme to None then prepending will be + disabled. URLs that require prepending to parse will still be accepted, + but the return value will not be modified. + + @author: Jonathan Benn + + >>> IS_HTTP_URL()('http://1.2.3.4') + ('http://1.2.3.4', None) + >>> IS_HTTP_URL()('http://abc.com') + ('http://abc.com', None) + >>> IS_HTTP_URL()('https://abc.com') + ('https://abc.com', None) + >>> IS_HTTP_URL()('httpx://abc.com') + ('httpx://abc.com', 'enter a valid URL') + >>> IS_HTTP_URL()('http://abc.com:80') + ('http://abc.com:80', None) + >>> IS_HTTP_URL()('http://user@abc.com') + ('http://user@abc.com', None) + >>> IS_HTTP_URL()('http://user@1.2.3.4') + ('http://user@1.2.3.4', None) + + Args: + error_message: a string, the error message to give the end user + if the URL does not validate + allowed_schemes: a list containing strings or None. Each element + is a scheme the inputed URL is allowed to use + prepend_scheme: a string, this scheme is prepended if it's + necessary to make the URL valid + """ + + GENERIC_VALID_IP = re.compile( + "([\w.!~*'|;:&=+$,-]+@)?\d+\.\d+\.\d+\.\d+(:\d*)*$") + GENERIC_VALID_DOMAIN = re.compile("([\w.!~*'|;:&=+$,-]+@)?(([A-Za-z0-9]+[A-Za-z0-9\-]*[A-Za-z0-9]+\.)*([A-Za-z0-9]+\.)*)*([A-Za-z]+[A-Za-z0-9\-]*[A-Za-z0-9]+)\.?(:\d*)*$") + + def __init__( + self, + error_message='Enter a valid URL', + allowed_schemes=None, + prepend_scheme='http', + allowed_tlds=None + ): + + self.error_message = error_message + if allowed_schemes is None: + self.allowed_schemes = http_schemes + else: + self.allowed_schemes = allowed_schemes + if allowed_tlds is None: + self.allowed_tlds = official_top_level_domains + else: + self.allowed_tlds = allowed_tlds + self.prepend_scheme = prepend_scheme + + for i in self.allowed_schemes: + if i not in http_schemes: + raise SyntaxError("allowed_scheme value '%s' is not in %s" % + (i, http_schemes)) + + if self.prepend_scheme not in self.allowed_schemes: + raise SyntaxError("prepend_scheme='%s' is not in allowed_schemes=%s" % + (self.prepend_scheme, self.allowed_schemes)) + + def __call__(self, value): + """ + Args: + value: a string, the URL to validate + + Returns: + a tuple, where tuple[0] is the inputed value + (possible prepended with prepend_scheme), and tuple[1] is either + None (success!) or the string error_message + """ + try: + # if the URL passes generic validation + x = IS_GENERIC_URL(error_message=self.error_message, + allowed_schemes=self.allowed_schemes, + prepend_scheme=self.prepend_scheme) + if x(value)[1] is None: + components = urlparse.urlparse(value) + authority = components.netloc + # if there is an authority component + if authority: + # if authority is a valid IP address + if self.GENERIC_VALID_IP.match(authority): + # Then this HTTP URL is valid + return (value, None) + else: + # else if authority is a valid domain name + domainMatch = self.GENERIC_VALID_DOMAIN.match( + authority) + if domainMatch: + # if the top-level domain really exists + if domainMatch.group(5).lower()\ + in self.allowed_tlds: + # Then this HTTP URL is valid + return (value, None) + else: + # else this is a relative/abbreviated URL, which will parse + # into the URL's path component + path = components.path + # relative case: if this is a valid path (if it starts with + # a slash) + if path.startswith('/'): + # Then this HTTP URL is valid + return (value, None) + else: + # abbreviated case: if we haven't already, prepend a + # scheme and see if it fixes the problem + if '://' not in value and None in self.allowed_schemes: + schemeToUse = self.prepend_scheme or 'http' + prependTest = self.__call__(schemeToUse + + '://' + value) + # if the prepend test succeeded + if prependTest[1] is None: + # if prepending in the output is enabled + if self.prepend_scheme: + return prependTest + else: + # else return the original, non-prepended + # value + return (value, None) + except: + pass + # else the HTTP URL is not valid + return (value, translate(self.error_message)) + + +class IS_URL(Validator): + """ + Rejects a URL string if any of the following is true: + + * The string is empty or None + * The string uses characters that are not allowed in a URL + * The string breaks any of the HTTP syntactic rules + * The URL scheme specified (if one is specified) is not 'http' or 'https' + * The top-level domain (if a host name is specified) does not exist + + (These rules are based on RFC 2616: http://www.faqs.org/rfcs/rfc2616.html) + + This function only checks the URL's syntax. It does not check that the URL + points to a real document, for example, or that it otherwise makes sense + semantically. This function does automatically prepend 'http://' in front + of a URL in the case of an abbreviated URL (e.g. 'google.ca'). + + If the parameter mode='generic' is used, then this function's behavior + changes. It then rejects a URL string if any of the following is true: + + * The string is empty or None + * The string uses characters that are not allowed in a URL + * The URL scheme specified (if one is specified) is not valid + + (These rules are based on RFC 2396: http://www.faqs.org/rfcs/rfc2396.html) + + The list of allowed schemes is customizable with the allowed_schemes + parameter. If you exclude None from the list, then abbreviated URLs + (lacking a scheme such as 'http') will be rejected. + + The default prepended scheme is customizable with the prepend_scheme + parameter. If you set prepend_scheme to None then prepending will be + disabled. URLs that require prepending to parse will still be accepted, + but the return value will not be modified. + + IS_URL is compatible with the Internationalized Domain Name (IDN) standard + specified in RFC 3490 (http://tools.ietf.org/html/rfc3490). As a result, + URLs can be regular strings or unicode strings. + If the URL's domain component (e.g. google.ca) contains non-US-ASCII + letters, then the domain will be converted into Punycode (defined in + RFC 3492, http://tools.ietf.org/html/rfc3492). IS_URL goes a bit beyond + the standards, and allows non-US-ASCII characters to be present in the path + and query components of the URL as well. These non-US-ASCII characters will + be escaped using the standard '%20' type syntax. e.g. the unicode + character with hex code 0x4e86 will become '%4e%86' + + Args: + error_message: a string, the error message to give the end user + if the URL does not validate + allowed_schemes: a list containing strings or None. Each element + is a scheme the inputed URL is allowed to use + prepend_scheme: a string, this scheme is prepended if it's + necessary to make the URL valid + + Code Examples:: + + INPUT(_type='text', _name='name', requires=IS_URL()) + >>> IS_URL()('abc.com') + ('http://abc.com', None) + + INPUT(_type='text', _name='name', requires=IS_URL(mode='generic')) + >>> IS_URL(mode='generic')('abc.com') + ('abc.com', None) + + INPUT(_type='text', _name='name', + requires=IS_URL(allowed_schemes=['https'], prepend_scheme='https')) + >>> IS_URL(allowed_schemes=['https'], prepend_scheme='https')('https://abc.com') + ('https://abc.com', None) + + INPUT(_type='text', _name='name', + requires=IS_URL(prepend_scheme='https')) + >>> IS_URL(prepend_scheme='https')('abc.com') + ('https://abc.com', None) + + INPUT(_type='text', _name='name', + requires=IS_URL(mode='generic', allowed_schemes=['ftps', 'https'], + prepend_scheme='https')) + >>> IS_URL(mode='generic', allowed_schemes=['ftps', 'https'], prepend_scheme='https')('https://abc.com') + ('https://abc.com', None) + >>> IS_URL(mode='generic', allowed_schemes=['ftps', 'https', None], prepend_scheme='https')('abc.com') + ('abc.com', None) + + @author: Jonathan Benn + """ + + def __init__( + self, + error_message='Enter a valid URL', + mode='http', + allowed_schemes=None, + prepend_scheme='http', + allowed_tlds=None + ): + + self.error_message = error_message + self.mode = mode.lower() + if self.mode not in ['generic', 'http']: + raise SyntaxError("invalid mode '%s' in IS_URL" % self.mode) + self.allowed_schemes = allowed_schemes + if allowed_tlds is None: + self.allowed_tlds = official_top_level_domains + else: + self.allowed_tlds = allowed_tlds + + if self.allowed_schemes: + if prepend_scheme not in self.allowed_schemes: + raise SyntaxError("prepend_scheme='%s' is not in allowed_schemes=%s" + % (prepend_scheme, self.allowed_schemes)) + + # if allowed_schemes is None, then we will defer testing + # prepend_scheme's validity to a sub-method + + self.prepend_scheme = prepend_scheme + + def __call__(self, value): + """ + Args: + value: a unicode or regular string, the URL to validate + + Returns: + a (string, string) tuple, where tuple[0] is the modified + input value and tuple[1] is either None (success!) or the + string error_message. The input value will never be modified in the + case of an error. However, if there is success then the input URL + may be modified to (1) prepend a scheme, and/or (2) convert a + non-compliant unicode URL into a compliant US-ASCII version. + """ + if self.mode == 'generic': + subMethod = IS_GENERIC_URL(error_message=self.error_message, + allowed_schemes=self.allowed_schemes, + prepend_scheme=self.prepend_scheme) + elif self.mode == 'http': + subMethod = IS_HTTP_URL(error_message=self.error_message, + allowed_schemes=self.allowed_schemes, + prepend_scheme=self.prepend_scheme, + allowed_tlds=self.allowed_tlds) + else: + raise SyntaxError("invalid mode '%s' in IS_URL" % self.mode) + + if not isinstance(value, unicodeT): + return subMethod(value) + else: + try: + asciiValue = unicode_to_ascii_url(value, self.prepend_scheme) + except Exception as e: + # If we are not able to convert the unicode url into a + # US-ASCII URL, then the URL is not valid + return (value, translate(self.error_message)) + methodResult = subMethod(asciiValue) + # if the validation of the US-ASCII version of the value failed + if not methodResult[1] is None: + # then return the original input value, not the US-ASCII version + return (value, methodResult[1]) + else: + return methodResult + + +regex_time = re.compile( + '((?P<h>[0-9]+))([^0-9 ]+(?P<m>[0-9 ]+))?([^0-9ap ]+(?P<s>[0-9]*))?((?P<d>[ap]m))?') + + +class IS_TIME(Validator): + """ + Example: + Use as:: + + INPUT(_type='text', _name='name', requires=IS_TIME()) + + understands the following formats + hh:mm:ss [am/pm] + hh:mm [am/pm] + hh [am/pm] + + [am/pm] is optional, ':' can be replaced by any other non-space non-digit:: + + >>> IS_TIME()('21:30') + (datetime.time(21, 30), None) + >>> IS_TIME()('21-30') + (datetime.time(21, 30), None) + >>> IS_TIME()('21.30') + (datetime.time(21, 30), None) + >>> IS_TIME()('21:30:59') + (datetime.time(21, 30, 59), None) + >>> IS_TIME()('5:30') + (datetime.time(5, 30), None) + >>> IS_TIME()('5:30 am') + (datetime.time(5, 30), None) + >>> IS_TIME()('5:30 pm') + (datetime.time(17, 30), None) + >>> IS_TIME()('5:30 whatever') + ('5:30 whatever', 'enter time as hh:mm:ss (seconds, am, pm optional)') + >>> IS_TIME()('5:30 20') + ('5:30 20', 'enter time as hh:mm:ss (seconds, am, pm optional)') + >>> IS_TIME()('24:30') + ('24:30', 'enter time as hh:mm:ss (seconds, am, pm optional)') + >>> IS_TIME()('21:60') + ('21:60', 'enter time as hh:mm:ss (seconds, am, pm optional)') + >>> IS_TIME()('21:30::') + ('21:30::', 'enter time as hh:mm:ss (seconds, am, pm optional)') + >>> IS_TIME()('') + ('', 'enter time as hh:mm:ss (seconds, am, pm optional)')ù + + """ + + def __init__(self, error_message='Enter time as hh:mm:ss (seconds, am, pm optional)'): + self.error_message = error_message + + def __call__(self, value): + try: + ivalue = value + value = regex_time.match(value.lower()) + (h, m, s) = (int(value.group('h')), 0, 0) + if not value.group('m') is None: + m = int(value.group('m')) + if not value.group('s') is None: + s = int(value.group('s')) + if value.group('d') == 'pm' and 0 < h < 12: + h += 12 + if value.group('d') == 'am' and h == 12: + h = 0 + if not (h in range(24) and m in range(60) and s + in range(60)): + raise ValueError('Hours or minutes or seconds are outside of allowed range') + value = datetime.time(h, m, s) + return (value, None) + except AttributeError: + pass + except ValueError: + pass + return (ivalue, translate(self.error_message)) + + +# A UTC class. +class UTC(datetime.tzinfo): + """UTC""" + ZERO = datetime.timedelta(0) + + def utcoffset(self, dt): + return UTC.ZERO + + def tzname(self, dt): + return "UTC" + + def dst(self, dt): + return UTC.ZERO +utc = UTC() + + +class IS_DATE(Validator): + """ + Examples: + Use as:: + + INPUT(_type='text', _name='name', requires=IS_DATE()) + + date has to be in the ISO8960 format YYYY-MM-DD + """ + + def __init__(self, format='%Y-%m-%d', + error_message='Enter date as %(format)s'): + self.format = translate(format) + self.error_message = str(error_message) + self.extremes = {} + + def __call__(self, value): + ovalue = value + if isinstance(value, datetime.date): + return (value, None) + try: + (y, m, d, hh, mm, ss, t0, t1, t2) = \ + time.strptime(value, str(self.format)) + value = datetime.date(y, m, d) + return (value, None) + except: + self.extremes.update(IS_DATETIME.nice(self.format)) + return (ovalue, translate(self.error_message) % self.extremes) + + def formatter(self, value): + if value is None: + return None + format = self.format + year = value.year + y = '%.4i' % year + format = format.replace('%y', y[-2:]) + format = format.replace('%Y', y) + if year < 1900: + year = 2000 + d = datetime.date(year, value.month, value.day) + return d.strftime(format) + + +class IS_DATETIME(Validator): + """ + Examples: + Use as:: + + INPUT(_type='text', _name='name', requires=IS_DATETIME()) + + datetime has to be in the ISO8960 format YYYY-MM-DD hh:mm:ss + timezome must be None or a pytz.timezone("America/Chicago") object + """ + + isodatetime = '%Y-%m-%d %H:%M:%S' + + @staticmethod + def nice(format): + code = (('%Y', '1963'), + ('%y', '63'), + ('%d', '28'), + ('%m', '08'), + ('%b', 'Aug'), + ('%B', 'August'), + ('%H', '14'), + ('%I', '02'), + ('%p', 'PM'), + ('%M', '30'), + ('%S', '59')) + for (a, b) in code: + format = format.replace(a, b) + return dict(format=format) + + def __init__(self, format='%Y-%m-%d %H:%M:%S', + error_message='Enter date and time as %(format)s', + timezone=None): + self.format = translate(format) + self.error_message = str(error_message) + self.extremes = {} + self.timezone = timezone + + def __call__(self, value): + ovalue = value + if isinstance(value, datetime.datetime): + return (value, None) + try: + (y, m, d, hh, mm, ss, t0, t1, t2) = \ + time.strptime(value, str(self.format)) + value = datetime.datetime(y, m, d, hh, mm, ss) + if self.timezone is not None: + # TODO: https://github.com/web2py/web2py/issues/1094 (temporary solution) + value = self.timezone.localize(value).astimezone(utc).replace(tzinfo=None) + return (value, None) + except: + self.extremes.update(IS_DATETIME.nice(self.format)) + return (ovalue, translate(self.error_message) % self.extremes) + + def formatter(self, value): + if value is None: + return None + format = self.format + year = value.year + y = '%.4i' % year + format = format.replace('%y', y[-2:]) + format = format.replace('%Y', y) + if year < 1900: + year = 2000 + d = datetime.datetime(year, value.month, value.day, + value.hour, value.minute, value.second) + if self.timezone is not None: + d = d.replace(tzinfo=utc).astimezone(self.timezone) + return d.strftime(format) + + +class IS_DATE_IN_RANGE(IS_DATE): + """ + Examples: + Use as:: + + >>> v = IS_DATE_IN_RANGE(minimum=datetime.date(2008,1,1), \ + maximum=datetime.date(2009,12,31), \ + format="%m/%d/%Y",error_message="Oops") + + >>> v('03/03/2008') + (datetime.date(2008, 3, 3), None) + + >>> v('03/03/2010') + ('03/03/2010', 'oops') + + >>> v(datetime.date(2008,3,3)) + (datetime.date(2008, 3, 3), None) + + >>> v(datetime.date(2010,3,3)) + (datetime.date(2010, 3, 3), 'oops') + + """ + + def __init__(self, + minimum=None, + maximum=None, + format='%Y-%m-%d', + error_message=None): + self.minimum = minimum + self.maximum = maximum + if error_message is None: + if minimum is None: + error_message = "Enter date on or before %(max)s" + elif maximum is None: + error_message = "Enter date on or after %(min)s" + else: + error_message = "Enter date in range %(min)s %(max)s" + IS_DATE.__init__(self, + format=format, + error_message=error_message) + self.extremes = dict(min=self.formatter(minimum), + max=self.formatter(maximum)) + + def __call__(self, value): + ovalue = value + (value, msg) = IS_DATE.__call__(self, value) + if msg is not None: + return (value, msg) + if self.minimum and self.minimum > value: + return (ovalue, translate(self.error_message) % self.extremes) + if self.maximum and value > self.maximum: + return (ovalue, translate(self.error_message) % self.extremes) + return (value, None) + + +class IS_DATETIME_IN_RANGE(IS_DATETIME): + """ + Examples: + Use as:: + >>> v = IS_DATETIME_IN_RANGE(\ + minimum=datetime.datetime(2008,1,1,12,20), \ + maximum=datetime.datetime(2009,12,31,12,20), \ + format="%m/%d/%Y %H:%M",error_message="Oops") + >>> v('03/03/2008 12:40') + (datetime.datetime(2008, 3, 3, 12, 40), None) + + >>> v('03/03/2010 10:34') + ('03/03/2010 10:34', 'oops') + + >>> v(datetime.datetime(2008,3,3,0,0)) + (datetime.datetime(2008, 3, 3, 0, 0), None) + + >>> v(datetime.datetime(2010,3,3,0,0)) + (datetime.datetime(2010, 3, 3, 0, 0), 'oops') + + """ + + def __init__(self, + minimum=None, + maximum=None, + format='%Y-%m-%d %H:%M:%S', + error_message=None, + timezone=None): + self.minimum = minimum + self.maximum = maximum + if error_message is None: + if minimum is None: + error_message = "Enter date and time on or before %(max)s" + elif maximum is None: + error_message = "Enter date and time on or after %(min)s" + else: + error_message = "Enter date and time in range %(min)s %(max)s" + IS_DATETIME.__init__(self, + format=format, + error_message=error_message, + timezone=timezone) + self.extremes = dict(min=self.formatter(minimum), + max=self.formatter(maximum)) + + def __call__(self, value): + ovalue = value + (value, msg) = IS_DATETIME.__call__(self, value) + if msg is not None: + return (value, msg) + if self.minimum and self.minimum > value: + return (ovalue, translate(self.error_message) % self.extremes) + if self.maximum and value > self.maximum: + return (ovalue, translate(self.error_message) % self.extremes) + return (value, None) + + +class IS_LIST_OF(Validator): + + def __init__(self, other=None, minimum=None, maximum=None, error_message=None): + self.other = other + self.minimum = minimum + self.maximum = maximum + self.error_message = error_message + + def __call__(self, value): + ivalue = value + if not isinstance(value, list): + ivalue = [ivalue] + ivalue = [i for i in ivalue if str(i).strip()] + if self.minimum is not None and len(ivalue) < self.minimum: + return (ivalue, translate(self.error_message or + 'Minimum length is %(min)s') % dict(min=self.minimum, max=self.maximum)) + if self.maximum is not None and len(ivalue) > self.maximum: + return (ivalue, translate(self.error_message or + 'Maximum length is %(max)s') % dict(min=self.minimum, max=self.maximum)) + new_value = [] + other = self.other + if self.other: + if not isinstance(other, (list, tuple)): + other = [other] + for item in ivalue: + v = item + for validator in other: + (v, e) = validator(v) + if e: + return (ivalue, e) + new_value.append(v) + ivalue = new_value + return (ivalue, None) + + +class IS_LOWER(Validator): + """ + Converts to lowercase:: + + >>> IS_LOWER()('ABC') + ('abc', None) + >>> IS_LOWER()('Ñ') + ('\\xc3\\xb1', None) + + """ + + def __call__(self, value): + cast_back = lambda x: x + if isinstance(value, str): + cast_back = to_native + elif isinstance(value, bytes): + cast_back = to_bytes + value = to_unicode(value).lower() + return (cast_back(value), None) + + +class IS_UPPER(Validator): + """ + Converts to uppercase:: + + >>> IS_UPPER()('abc') + ('ABC', None) + >>> IS_UPPER()('ñ') + ('\\xc3\\x91', None) + + """ + + def __call__(self, value): + cast_back = lambda x: x + if isinstance(value, str): + cast_back = to_native + elif isinstance(value, bytes): + cast_back = to_bytes + value = to_unicode(value).upper() + return (cast_back(value), None) + + +def urlify(s, maxlen=80, keep_underscores=False): + """ + Converts incoming string to a simplified ASCII subset. + if (keep_underscores): underscores are retained in the string + else: underscores are translated to hyphens (default) + """ + s = to_unicode(s) # to unicode + s = s.lower() # to lowercase + s = unicodedata.normalize('NFKD', s) # replace special characters + s = to_native(s, charset='ascii', errors='ignore') # encode as ASCII + s = re.sub('&\w+?;', '', s) # strip html entities + if keep_underscores: + s = re.sub('\s+', '-', s) # whitespace to hyphens + s = re.sub('[^\w\-]', '', s) + # strip all but alphanumeric/underscore/hyphen + else: + s = re.sub('[\s_]+', '-', s) # whitespace & underscores to hyphens + s = re.sub('[^a-z0-9\-]', '', s) # strip all but alphanumeric/hyphen + s = re.sub('[-_][-_]+', '-', s) # collapse strings of hyphens + s = s.strip('-') # remove leading and trailing hyphens + return s[:maxlen] # enforce maximum length + + +class IS_SLUG(Validator): + """ + converts arbitrary text string to a slug:: + + >>> IS_SLUG()('abc123') + ('abc123', None) + >>> IS_SLUG()('ABC123') + ('abc123', None) + >>> IS_SLUG()('abc-123') + ('abc-123', None) + >>> IS_SLUG()('abc--123') + ('abc-123', None) + >>> IS_SLUG()('abc 123') + ('abc-123', None) + >>> IS_SLUG()('abc\t_123') + ('abc-123', None) + >>> IS_SLUG()('-abc-') + ('abc', None) + >>> IS_SLUG()('--a--b--_ -c--') + ('a-b-c', None) + >>> IS_SLUG()('abc&123') + ('abc123', None) + >>> IS_SLUG()('abc&123&def') + ('abc123def', None) + >>> IS_SLUG()('ñ') + ('n', None) + >>> IS_SLUG(maxlen=4)('abc123') + ('abc1', None) + >>> IS_SLUG()('abc_123') + ('abc-123', None) + >>> IS_SLUG(keep_underscores=False)('abc_123') + ('abc-123', None) + >>> IS_SLUG(keep_underscores=True)('abc_123') + ('abc_123', None) + >>> IS_SLUG(check=False)('abc') + ('abc', None) + >>> IS_SLUG(check=True)('abc') + ('abc', None) + >>> IS_SLUG(check=False)('a bc') + ('a-bc', None) + >>> IS_SLUG(check=True)('a bc') + ('a bc', 'must be slug') + """ + + @staticmethod + def urlify(value, maxlen=80, keep_underscores=False): + return urlify(value, maxlen, keep_underscores) + + def __init__(self, maxlen=80, check=False, error_message='Must be slug', keep_underscores=False): + self.maxlen = maxlen + self.check = check + self.error_message = error_message + self.keep_underscores = keep_underscores + + def __call__(self, value): + if self.check and value != urlify(value, self.maxlen, self.keep_underscores): + return (value, translate(self.error_message)) + return (urlify(value, self.maxlen, self.keep_underscores), None) + + +class ANY_OF(Validator): + """ + Tests if any of the validators in a list returns successfully:: + + >>> ANY_OF([IS_EMAIL(),IS_ALPHANUMERIC()])('a@b.co') + ('a@b.co', None) + >>> ANY_OF([IS_EMAIL(),IS_ALPHANUMERIC()])('abco') + ('abco', None) + >>> ANY_OF([IS_EMAIL(),IS_ALPHANUMERIC()])('@ab.co') + ('@ab.co', 'enter only letters, numbers, and underscore') + >>> ANY_OF([IS_ALPHANUMERIC(),IS_EMAIL()])('@ab.co') + ('@ab.co', 'enter a valid email address') + + """ + + def __init__(self, subs, error_message=None): + self.subs = subs + self.error_message = error_message + + def __call__(self, value): + for validator in self.subs: + value, error = validator(value) + if error is None: + break + if error is not None and self.error_message is not None: + error = translate(self.error_message) + return value, error + + def formatter(self, value): + # Use the formatter of the first subvalidator + # that validates the value and has a formatter + for validator in self.subs: + if hasattr(validator, 'formatter') and validator(value)[1] is None: + return validator.formatter(value) + + +class IS_EMPTY_OR(Validator): + """ + Dummy class for testing IS_EMPTY_OR:: + + >>> IS_EMPTY_OR(IS_EMAIL())('abc@def.com') + ('abc@def.com', None) + >>> IS_EMPTY_OR(IS_EMAIL())(' ') + (None, None) + >>> IS_EMPTY_OR(IS_EMAIL(), null='abc')(' ') + ('abc', None) + >>> IS_EMPTY_OR(IS_EMAIL(), null='abc', empty_regex='def')('def') + ('abc', None) + >>> IS_EMPTY_OR(IS_EMAIL())('abc') + ('abc', 'enter a valid email address') + >>> IS_EMPTY_OR(IS_EMAIL())(' abc ') + ('abc', 'enter a valid email address') + """ + + def __init__(self, other, null=None, empty_regex=None): + (self.other, self.null) = (other, null) + if empty_regex is not None: + self.empty_regex = re.compile(empty_regex) + else: + self.empty_regex = None + if hasattr(other, 'multiple'): + self.multiple = other.multiple + if hasattr(other, 'options'): + self.options = self._options + + def _options(self, *args, **kwargs): + options = self.other.options(*args, **kwargs) + if (not options or options[0][0] != '') and not self.multiple: + options.insert(0, ('', '')) + return options + + def set_self_id(self, id): + if isinstance(self.other, (list, tuple)): + for item in self.other: + if hasattr(item, 'set_self_id'): + item.set_self_id(id) + else: + if hasattr(self.other, 'set_self_id'): + self.other.set_self_id(id) + + def __call__(self, value): + value, empty = is_empty(value, empty_regex=self.empty_regex) + if empty: + return (self.null, None) + if isinstance(self.other, (list, tuple)): + error = None + for item in self.other: + value, error = item(value) + if error: + break + return value, error + else: + return self.other(value) + + def formatter(self, value): + if hasattr(self.other, 'formatter'): + return self.other.formatter(value) + return value + +IS_NULL_OR = IS_EMPTY_OR # for backward compatibility + + +class CLEANUP(Validator): + """ + Examples: + Use as:: + + INPUT(_type='text', _name='name', requires=CLEANUP()) + + removes special characters on validation + """ + REGEX_CLEANUP = re.compile('[^\x09\x0a\x0d\x20-\x7e]') + + def __init__(self, regex=None): + self.regex = self.REGEX_CLEANUP if regex is None \ + else re.compile(regex) + + def __call__(self, value): + v = self.regex.sub('', str(value).strip()) + return (v, None) + + +class LazyCrypt(object): + """ + Stores a lazy password hash + """ + + def __init__(self, crypt, password): + """ + crypt is an instance of the CRYPT validator, + password is the password as inserted by the user + """ + self.crypt = crypt + self.password = password + self.crypted = None + + def __str__(self): + """ + Encrypted self.password and caches it in self.crypted. + If self.crypt.salt the output is in the format <algorithm>$<salt>$<hash> + + Try get the digest_alg from the key (if it exists) + else assume the default digest_alg. If not key at all, set key='' + + If a salt is specified use it, if salt is True, set salt to uuid + (this should all be backward compatible) + + Options: + key = 'uuid' + key = 'md5:uuid' + key = 'sha512:uuid' + ... + key = 'pbkdf2(1000,64,sha512):uuid' 1000 iterations and 64 chars length + """ + if self.crypted: + return self.crypted + if self.crypt.key: + if ':' in self.crypt.key: + digest_alg, key = self.crypt.key.split(':', 1) + else: + digest_alg, key = self.crypt.digest_alg, self.crypt.key + else: + digest_alg, key = self.crypt.digest_alg, '' + if self.crypt.salt: + if self.crypt.salt is True: + salt = str(web2py_uuid()).replace('-', '')[-16:] + else: + salt = self.crypt.salt + else: + salt = '' + hashed = simple_hash(self.password, key, salt, digest_alg) + self.crypted = '%s$%s$%s' % (digest_alg, salt, hashed) + return self.crypted + + def __eq__(self, stored_password): + """ + compares the current lazy crypted password with a stored password + """ + + # LazyCrypt objects comparison + if isinstance(stored_password, self.__class__): + return ((self is stored_password) or + ((self.crypt.key == stored_password.crypt.key) and + (self.password == stored_password.password))) + + if self.crypt.key: + if ':' in self.crypt.key: + key = self.crypt.key.split(':')[1] + else: + key = self.crypt.key + else: + key = '' + if stored_password is None: + return False + elif stored_password.count('$') == 2: + (digest_alg, salt, hash) = stored_password.split('$') + h = simple_hash(self.password, key, salt, digest_alg) + temp_pass = '%s$%s$%s' % (digest_alg, salt, h) + else: # no salting + # guess digest_alg + digest_alg = DIGEST_ALG_BY_SIZE.get(len(stored_password), None) + if not digest_alg: + return False + else: + temp_pass = simple_hash(self.password, key, '', digest_alg) + return temp_pass == stored_password + + def __ne__(self, other): + return not self.__eq__(other) + + +class CRYPT(object): + """ + Examples: + Use as:: + + INPUT(_type='text', _name='name', requires=CRYPT()) + + encodes the value on validation with a digest. + + If no arguments are provided CRYPT uses the MD5 algorithm. + If the key argument is provided the HMAC+MD5 algorithm is used. + If the digest_alg is specified this is used to replace the + MD5 with, for example, SHA512. The digest_alg can be + the name of a hashlib algorithm as a string or the algorithm itself. + + min_length is the minimal password length (default 4) - IS_STRONG for serious security + error_message is the message if password is too short + + Notice that an empty password is accepted but invalid. It will not allow login back. + Stores junk as hashed password. + + Specify an algorithm or by default we will use sha512. + + Typical available algorithms: + md5, sha1, sha224, sha256, sha384, sha512 + + If salt, it hashes a password with a salt. + If salt is True, this method will automatically generate one. + Either case it returns an encrypted password string in the following format: + + <algorithm>$<salt>$<hash> + + Important: hashed password is returned as a LazyCrypt object and computed only if needed. + The LasyCrypt object also knows how to compare itself with an existing salted password + + Supports standard algorithms + + >>> for alg in ('md5','sha1','sha256','sha384','sha512'): + ... print(str(CRYPT(digest_alg=alg,salt=True)('test')[0])) + md5$...$... + sha1$...$... + sha256$...$... + sha384$...$... + sha512$...$... + + The syntax is always alg$salt$hash + + Supports for pbkdf2 + + >>> alg = 'pbkdf2(1000,20,sha512)' + >>> print(str(CRYPT(digest_alg=alg,salt=True)('test')[0])) + pbkdf2(1000,20,sha512)$...$... + + An optional hmac_key can be specified and it is used as salt prefix + + >>> a = str(CRYPT(digest_alg='md5',key='mykey',salt=True)('test')[0]) + >>> print(a) + md5$...$... + + Even if the algorithm changes the hash can still be validated + + >>> CRYPT(digest_alg='sha1',key='mykey',salt=True)('test')[0] == a + True + + If no salt is specified CRYPT can guess the algorithms from length: + + >>> a = str(CRYPT(digest_alg='sha1',salt=False)('test')[0]) + >>> a + 'sha1$$a94a8fe5ccb19ba61c4c0873d391e987982fbbd3' + >>> CRYPT(digest_alg='sha1',salt=False)('test')[0] == a + True + >>> CRYPT(digest_alg='sha1',salt=False)('test')[0] == a[6:] + True + >>> CRYPT(digest_alg='md5',salt=False)('test')[0] == a + True + >>> CRYPT(digest_alg='md5',salt=False)('test')[0] == a[6:] + True + """ + + def __init__(self, + key=None, + digest_alg='pbkdf2(1000,20,sha512)', + min_length=0, + error_message='Too short', salt=True, + max_length=1024): + """ + important, digest_alg='md5' is not the default hashing algorithm for + web2py. This is only an example of usage of this function. + + The actual hash algorithm is determined from the key which is + generated by web2py in tools.py. This defaults to hmac+sha512. + """ + self.key = key + self.digest_alg = digest_alg + self.min_length = min_length + self.max_length = max_length + self.error_message = error_message + self.salt = salt + + def __call__(self, value): + v = value and str(value)[:self.max_length] + if not v or len(v) < self.min_length: + return ('', translate(self.error_message)) + if isinstance(value, LazyCrypt): + return (value, None) + return (LazyCrypt(self, value), None) + +# entropy calculator for IS_STRONG +# +lowerset = frozenset(u'abcdefghijklmnopqrstuvwxyz') +upperset = frozenset(u'ABCDEFGHIJKLMNOPQRSTUVWXYZ') +numberset = frozenset(u'0123456789') +sym1set = frozenset(u'!@#$%^&*()') +sym2set = frozenset(u'~`-_=+[]{}\\|;:\'",.<>?/') +otherset = frozenset( + u'0123456789abcdefghijklmnopqrstuvwxyz') # anything else + + +def calc_entropy(string): + """ calculates a simple entropy for a given string """ + import math + alphabet = 0 # alphabet size + other = set() + seen = set() + lastset = None + string = to_unicode(string) + for c in string: + # classify this character + inset = otherset + for cset in (lowerset, upperset, numberset, sym1set, sym2set): + if c in cset: + inset = cset + break + # calculate effect of character on alphabet size + if inset not in seen: + seen.add(inset) + alphabet += len(inset) # credit for a new character set + elif c not in other: + alphabet += 1 # credit for unique characters + other.add(c) + if inset is not lastset: + alphabet += 1 # credit for set transitions + lastset = cset + entropy = len( + string) * math.log(alphabet) / 0.6931471805599453 # math.log(2) + return round(entropy, 2) + + +class IS_STRONG(object): + """ + Examples: + Use as:: + + INPUT(_type='password', _name='passwd', + requires=IS_STRONG(min=10, special=2, upper=2)) + + enforces complexity requirements on a field + + >>> IS_STRONG(es=True)('Abcd1234') + ('Abcd1234', + 'Must include at least 1 of the following: ~!@#$%^&*()_+-=?<>,.:;{}[]|') + >>> IS_STRONG(es=True)('Abcd1234!') + ('Abcd1234!', None) + >>> IS_STRONG(es=True, entropy=1)('a') + ('a', None) + >>> IS_STRONG(es=True, entropy=1, min=2)('a') + ('a', 'Minimum length is 2') + >>> IS_STRONG(es=True, entropy=100)('abc123') + ('abc123', 'Entropy (32.35) less than required (100)') + >>> IS_STRONG(es=True, entropy=100)('and') + ('and', 'Entropy (14.57) less than required (100)') + >>> IS_STRONG(es=True, entropy=100)('aaa') + ('aaa', 'Entropy (14.42) less than required (100)') + >>> IS_STRONG(es=True, entropy=100)('a1d') + ('a1d', 'Entropy (15.97) less than required (100)') + >>> IS_STRONG(es=True, entropy=100)('añd') + ('a\\xc3\\xb1d', 'Entropy (18.13) less than required (100)') + + """ + + def __init__(self, min=None, max=None, upper=None, lower=None, number=None, + entropy=None, + special=None, specials=r'~!@#$%^&*()_+-=?<>,.:;{}[]|', + invalid=' "', error_message=None, es=False): + self.entropy = entropy + if entropy is None: + # enforce default requirements + self.min = 8 if min is None else min + self.max = max # was 20, but that doesn't make sense + self.upper = 1 if upper is None else upper + self.lower = 1 if lower is None else lower + self.number = 1 if number is None else number + self.special = 1 if special is None else special + else: + # by default, an entropy spec is exclusive + self.min = min + self.max = max + self.upper = upper + self.lower = lower + self.number = number + self.special = special + self.specials = specials + self.invalid = invalid + self.error_message = error_message + self.estring = es # return error message as string (for doctest) + + def __call__(self, value): + failures = [] + if value and len(value) == value.count('*') > 4: + return (value, None) + if self.entropy is not None: + entropy = calc_entropy(value) + if entropy < self.entropy: + failures.append(translate("Entropy (%(have)s) less than required (%(need)s)") + % dict(have=entropy, need=self.entropy)) + if isinstance(self.min, int) and self.min > 0: + if not len(value) >= self.min: + failures.append(translate("Minimum length is %s") % self.min) + if isinstance(self.max, int) and self.max > 0: + if not len(value) <= self.max: + failures.append(translate("Maximum length is %s") % self.max) + if isinstance(self.special, int): + all_special = [ch in value for ch in self.specials] + if self.special > 0: + if not all_special.count(True) >= self.special: + failures.append(translate("Must include at least %s of the following: %s") + % (self.special, self.specials)) + if self.invalid: + all_invalid = [ch in value for ch in self.invalid] + if all_invalid.count(True) > 0: + failures.append(translate("May not contain any of the following: %s") + % self.invalid) + if isinstance(self.upper, int): + all_upper = re.findall("[A-Z]", value) + if self.upper > 0: + if not len(all_upper) >= self.upper: + failures.append(translate("Must include at least %s uppercase") + % str(self.upper)) + else: + if len(all_upper) > 0: + failures.append( + translate("May not include any uppercase letters")) + if isinstance(self.lower, int): + all_lower = re.findall("[a-z]", value) + if self.lower > 0: + if not len(all_lower) >= self.lower: + failures.append(translate("Must include at least %s lowercase") + % str(self.lower)) + else: + if len(all_lower) > 0: + failures.append( + translate("May not include any lowercase letters")) + if isinstance(self.number, int): + all_number = re.findall("[0-9]", value) + if self.number > 0: + numbers = "number" + if self.number > 1: + numbers = "numbers" + if not len(all_number) >= self.number: + failures.append(translate("Must include at least %s %s") + % (str(self.number), numbers)) + else: + if len(all_number) > 0: + failures.append(translate("May not include any numbers")) + if len(failures) == 0: + return (value, None) + if not self.error_message: + if self.estring: + return (value, '|'.join(failures)) + from gluon.html import XML + return (value, XML('<br />'.join(failures))) + else: + return (value, translate(self.error_message)) + + +class IS_IMAGE(Validator): + """ + Checks if file uploaded through file input was saved in one of selected + image formats and has dimensions (width and height) within given boundaries. + + Does *not* check for maximum file size (use IS_LENGTH for that). Returns + validation failure if no data was uploaded. + + Supported file formats: BMP, GIF, JPEG, PNG. + + Code parts taken from + http://mail.python.org/pipermail/python-list/2007-June/617126.html + + Args: + extensions: iterable containing allowed *lowercase* image file extensions + ('jpg' extension of uploaded file counts as 'jpeg') + maxsize: iterable containing maximum width and height of the image + minsize: iterable containing minimum width and height of the image + + Use (-1, -1) as minsize to pass image size check. + + Examples: + Check if uploaded file is in any of supported image formats: + + INPUT(_type='file', _name='name', requires=IS_IMAGE()) + + Check if uploaded file is either JPEG or PNG: + + INPUT(_type='file', _name='name', + requires=IS_IMAGE(extensions=('jpeg', 'png'))) + + Check if uploaded file is PNG with maximum size of 200x200 pixels: + + INPUT(_type='file', _name='name', + requires=IS_IMAGE(extensions=('png'), maxsize=(200, 200))) + """ + + def __init__(self, + extensions=('bmp', 'gif', 'jpeg', 'png'), + maxsize=(10000, 10000), + minsize=(0, 0), + error_message='Invalid image'): + + self.extensions = extensions + self.maxsize = maxsize + self.minsize = minsize + self.error_message = error_message + + def __call__(self, value): + try: + extension = value.filename.rfind('.') + assert extension >= 0 + extension = value.filename[extension + 1:].lower() + if extension == 'jpg': + extension = 'jpeg' + assert extension in self.extensions + if extension == 'bmp': + width, height = self.__bmp(value.file) + elif extension == 'gif': + width, height = self.__gif(value.file) + elif extension == 'jpeg': + width, height = self.__jpeg(value.file) + elif extension == 'png': + width, height = self.__png(value.file) + else: + width = -1 + height = -1 + assert self.minsize[0] <= width <= self.maxsize[0] \ + and self.minsize[1] <= height <= self.maxsize[1] + value.file.seek(0) + return (value, None) + except Exception as e: + return (value, translate(self.error_message)) + + def __bmp(self, stream): + if stream.read(2) == b'BM': + stream.read(16) + return struct.unpack("<LL", stream.read(8)) + return (-1, -1) + + def __gif(self, stream): + if stream.read(6) in (b'GIF87a', b'GIF89a'): + stream = stream.read(5) + if len(stream) == 5: + return tuple(struct.unpack("<HHB", stream)[:-1]) + return (-1, -1) + + def __jpeg(self, stream): + if stream.read(2) == b'\xFF\xD8': + while True: + (marker, code, length) = struct.unpack("!BBH", stream.read(4)) + if marker != 0xFF: + break + elif code >= 0xC0 and code <= 0xC3: + return tuple(reversed( + struct.unpack("!xHH", stream.read(5)))) + else: + stream.read(length - 2) + return (-1, -1) + + def __png(self, stream): + if stream.read(8) == b'\211PNG\r\n\032\n': + stream.read(4) + if stream.read(4) == b"IHDR": + return struct.unpack("!LL", stream.read(8)) + return (-1, -1) + + +class IS_UPLOAD_FILENAME(Validator): + """ + Checks if name and extension of file uploaded through file input matches + given criteria. + + Does *not* ensure the file type in any way. Returns validation failure + if no data was uploaded. + + Args: + filename: filename (before dot) regex + extension: extension (after dot) regex + lastdot: which dot should be used as a filename / extension separator: + True means last dot, eg. file.png -> file / png + False means first dot, eg. file.tar.gz -> file / tar.gz + case: 0 - keep the case, 1 - transform the string into lowercase (default), + 2 - transform the string into uppercase + + If there is no dot present, extension checks will be done against empty + string and filename checks against whole value. + + Examples: + Check if file has a pdf extension (case insensitive): + + INPUT(_type='file', _name='name', + requires=IS_UPLOAD_FILENAME(extension='pdf')) + + Check if file has a tar.gz extension and name starting with backup: + + INPUT(_type='file', _name='name', + requires=IS_UPLOAD_FILENAME(filename='backup.*', + extension='tar.gz', lastdot=False)) + + Check if file has no extension and name matching README + (case sensitive): + + INPUT(_type='file', _name='name', + requires=IS_UPLOAD_FILENAME(filename='^README$', + extension='^$', case=0) + + """ + + def __init__(self, filename=None, extension=None, lastdot=True, case=1, + error_message='Enter valid filename'): + if isinstance(filename, str): + filename = re.compile(filename) + if isinstance(extension, str): + extension = re.compile(extension) + self.filename = filename + self.extension = extension + self.lastdot = lastdot + self.case = case + self.error_message = error_message + + def __call__(self, value): + try: + string = value.filename + except: + return (value, translate(self.error_message)) + if self.case == 1: + string = string.lower() + elif self.case == 2: + string = string.upper() + if self.lastdot: + dot = string.rfind('.') + else: + dot = string.find('.') + if dot == -1: + dot = len(string) + if self.filename and not self.filename.match(string[:dot]): + return (value, translate(self.error_message)) + elif self.extension and not self.extension.match(string[dot + 1:]): + return (value, translate(self.error_message)) + else: + return (value, None) + + +class IS_IPV4(Validator): + """ + Checks if field's value is an IP version 4 address in decimal form. Can + be set to force addresses from certain range. + + IPv4 regex taken from: http://regexlib.com/REDetails.aspx?regexp_id=1411 + + Args: + + minip: lowest allowed address; accepts: + + - str, eg. 192.168.0.1 + - list or tuple of octets, eg. [192, 168, 0, 1] + maxip: highest allowed address; same as above + invert: True to allow addresses only from outside of given range; note + that range boundaries are not matched this way + is_localhost: localhost address treatment: + + - None (default): indifferent + - True (enforce): query address must match localhost address (127.0.0.1) + - False (forbid): query address must not match localhost address + is_private: same as above, except that query address is checked against + two address ranges: 172.16.0.0 - 172.31.255.255 and + 192.168.0.0 - 192.168.255.255 + is_automatic: same as above, except that query address is checked against + one address range: 169.254.0.0 - 169.254.255.255 + + Minip and maxip may also be lists or tuples of addresses in all above + forms (str, int, list / tuple), allowing setup of multiple address ranges:: + + minip = (minip1, minip2, ... minipN) + | | | + | | | + maxip = (maxip1, maxip2, ... maxipN) + + Longer iterable will be truncated to match length of shorter one. + + Examples: + Check for valid IPv4 address: + + INPUT(_type='text', _name='name', requires=IS_IPV4()) + + Check for valid IPv4 address belonging to specific range: + + INPUT(_type='text', _name='name', + requires=IS_IPV4(minip='100.200.0.0', maxip='100.200.255.255')) + + Check for valid IPv4 address belonging to either 100.110.0.0 - + 100.110.255.255 or 200.50.0.0 - 200.50.0.255 address range: + + INPUT(_type='text', _name='name', + requires=IS_IPV4(minip=('100.110.0.0', '200.50.0.0'), + maxip=('100.110.255.255', '200.50.0.255'))) + + Check for valid IPv4 address belonging to private address space: + + INPUT(_type='text', _name='name', requires=IS_IPV4(is_private=True)) + + Check for valid IPv4 address that is not a localhost address: + + INPUT(_type='text', _name='name', requires=IS_IPV4(is_localhost=False)) + + >>> IS_IPV4()('1.2.3.4') + ('1.2.3.4', None) + >>> IS_IPV4()('255.255.255.255') + ('255.255.255.255', None) + >>> IS_IPV4()('1.2.3.4 ') + ('1.2.3.4 ', 'enter valid IPv4 address') + >>> IS_IPV4()('1.2.3.4.5') + ('1.2.3.4.5', 'enter valid IPv4 address') + >>> IS_IPV4()('123.123') + ('123.123', 'enter valid IPv4 address') + >>> IS_IPV4()('1111.2.3.4') + ('1111.2.3.4', 'enter valid IPv4 address') + >>> IS_IPV4()('0111.2.3.4') + ('0111.2.3.4', 'enter valid IPv4 address') + >>> IS_IPV4()('256.2.3.4') + ('256.2.3.4', 'enter valid IPv4 address') + >>> IS_IPV4()('300.2.3.4') + ('300.2.3.4', 'enter valid IPv4 address') + >>> IS_IPV4(minip='1.2.3.4', maxip='1.2.3.4')('1.2.3.4') + ('1.2.3.4', None) + >>> IS_IPV4(minip='1.2.3.5', maxip='1.2.3.9', error_message='Bad ip')('1.2.3.4') + ('1.2.3.4', 'bad ip') + >>> IS_IPV4(maxip='1.2.3.4', invert=True)('127.0.0.1') + ('127.0.0.1', None) + >>> IS_IPV4(maxip='1.2.3.4', invert=True)('1.2.3.4') + ('1.2.3.4', 'enter valid IPv4 address') + >>> IS_IPV4(is_localhost=True)('127.0.0.1') + ('127.0.0.1', None) + >>> IS_IPV4(is_localhost=True)('1.2.3.4') + ('1.2.3.4', 'enter valid IPv4 address') + >>> IS_IPV4(is_localhost=False)('127.0.0.1') + ('127.0.0.1', 'enter valid IPv4 address') + >>> IS_IPV4(maxip='100.0.0.0', is_localhost=True)('127.0.0.1') + ('127.0.0.1', 'enter valid IPv4 address') + + """ + + regex = re.compile( + '^(([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])$') + numbers = (16777216, 65536, 256, 1) + localhost = 2130706433 + private = ((2886729728, 2886795263), (3232235520, 3232301055)) + automatic = (2851995648, 2852061183) + + def __init__( + self, + minip='0.0.0.0', + maxip='255.255.255.255', + invert=False, + is_localhost=None, + is_private=None, + is_automatic=None, + error_message='Enter valid IPv4 address'): + for n, value in enumerate((minip, maxip)): + temp = [] + if isinstance(value, str): + temp.append(value.split('.')) + elif isinstance(value, (list, tuple)): + if len(value) == len(list(filter(lambda item: isinstance(item, int), value))) == 4: + temp.append(value) + else: + for item in value: + if isinstance(item, str): + temp.append(item.split('.')) + elif isinstance(item, (list, tuple)): + temp.append(item) + numbers = [] + for item in temp: + number = 0 + for i, j in zip(self.numbers, item): + number += i * int(j) + numbers.append(number) + if n == 0: + self.minip = numbers + else: + self.maxip = numbers + self.invert = invert + self.is_localhost = is_localhost + self.is_private = is_private + self.is_automatic = is_automatic + self.error_message = error_message + + def __call__(self, value): + if self.regex.match(value): + number = 0 + for i, j in zip(self.numbers, value.split('.')): + number += i * int(j) + ok = False + for bottom, top in zip(self.minip, self.maxip): + if self.invert != (bottom <= number <= top): + ok = True + if ok and self.is_localhost is not None and \ + self.is_localhost != (number == self.localhost): + ok = False + if ok and self.is_private is not None and (self.is_private != + any([private_number[0] <= number <= private_number[1] + for private_number in self.private])): + ok = False + if ok and self.is_automatic is not None and (self.is_automatic != + (self.automatic[0] <= number <= self.automatic[1])): + ok = False + if ok: + return (value, None) + return (value, translate(self.error_message)) + + +class IS_IPV6(Validator): + """ + Checks if field's value is an IP version 6 address. + + Uses the ipaddress from the Python 3 standard library + and its Python 2 backport (in contrib/ipaddress.py). + + Args: + is_private: None (default): indifferent + True (enforce): address must be in fc00::/7 range + False (forbid): address must NOT be in fc00::/7 range + is_link_local: Same as above but uses fe80::/10 range + is_reserved: Same as above but uses IETF reserved range + is_multicast: Same as above but uses ff00::/8 range + is_routeable: Similar to above but enforces not private, link_local, + reserved or multicast + is_6to4: Same as above but uses 2002::/16 range + is_teredo: Same as above but uses 2001::/32 range + subnets: value must be a member of at least one from list of subnets + + Examples: + Check for valid IPv6 address: + + INPUT(_type='text', _name='name', requires=IS_IPV6()) + + Check for valid IPv6 address is a link_local address: + + INPUT(_type='text', _name='name', requires=IS_IPV6(is_link_local=True)) + + Check for valid IPv6 address that is Internet routeable: + + INPUT(_type='text', _name='name', requires=IS_IPV6(is_routeable=True)) + + Check for valid IPv6 address in specified subnet: + + INPUT(_type='text', _name='name', requires=IS_IPV6(subnets=['2001::/32']) + + >>> IS_IPV6()('fe80::126c:8ffa:fe22:b3af') + ('fe80::126c:8ffa:fe22:b3af', None) + >>> IS_IPV6()('192.168.1.1') + ('192.168.1.1', 'enter valid IPv6 address') + >>> IS_IPV6(error_message='Bad ip')('192.168.1.1') + ('192.168.1.1', 'bad ip') + >>> IS_IPV6(is_link_local=True)('fe80::126c:8ffa:fe22:b3af') + ('fe80::126c:8ffa:fe22:b3af', None) + >>> IS_IPV6(is_link_local=False)('fe80::126c:8ffa:fe22:b3af') + ('fe80::126c:8ffa:fe22:b3af', 'enter valid IPv6 address') + >>> IS_IPV6(is_link_local=True)('2001::126c:8ffa:fe22:b3af') + ('2001::126c:8ffa:fe22:b3af', 'enter valid IPv6 address') + >>> IS_IPV6(is_multicast=True)('2001::126c:8ffa:fe22:b3af') + ('2001::126c:8ffa:fe22:b3af', 'enter valid IPv6 address') + >>> IS_IPV6(is_multicast=True)('ff00::126c:8ffa:fe22:b3af') + ('ff00::126c:8ffa:fe22:b3af', None) + >>> IS_IPV6(is_routeable=True)('2001::126c:8ffa:fe22:b3af') + ('2001::126c:8ffa:fe22:b3af', None) + >>> IS_IPV6(is_routeable=True)('ff00::126c:8ffa:fe22:b3af') + ('ff00::126c:8ffa:fe22:b3af', 'enter valid IPv6 address') + >>> IS_IPV6(subnets='2001::/32')('2001::8ffa:fe22:b3af') + ('2001::8ffa:fe22:b3af', None) + >>> IS_IPV6(subnets='fb00::/8')('2001::8ffa:fe22:b3af') + ('2001::8ffa:fe22:b3af', 'enter valid IPv6 address') + >>> IS_IPV6(subnets=['fc00::/8','2001::/32'])('2001::8ffa:fe22:b3af') + ('2001::8ffa:fe22:b3af', None) + >>> IS_IPV6(subnets='invalidsubnet')('2001::8ffa:fe22:b3af') + ('2001::8ffa:fe22:b3af', 'invalid subnet provided') + + """ + + def __init__( + self, + is_private=None, + is_link_local=None, + is_reserved=None, + is_multicast=None, + is_routeable=None, + is_6to4=None, + is_teredo=None, + subnets=None, + error_message='Enter valid IPv6 address'): + self.is_private = is_private + self.is_link_local = is_link_local + self.is_reserved = is_reserved + self.is_multicast = is_multicast + self.is_routeable = is_routeable + self.is_6to4 = is_6to4 + self.is_teredo = is_teredo + self.subnets = subnets + self.error_message = error_message + + def __call__(self, value): + from gluon._compat import ipaddress + + try: + ip = ipaddress.IPv6Address(to_unicode(value)) + ok = True + except ipaddress.AddressValueError: + return (value, translate(self.error_message)) + + if self.subnets: + # iterate through self.subnets to see if value is a member + ok = False + if isinstance(self.subnets, str): + self.subnets = [self.subnets] + for network in self.subnets: + try: + ipnet = ipaddress.IPv6Network(to_unicode(network)) + except (ipaddress.NetmaskValueError, ipaddress.AddressValueError): + return (value, translate('invalid subnet provided')) + if ip in ipnet: + ok = True + + if self.is_routeable: + self.is_private = False + self.is_reserved = False + self.is_multicast = False + + if ok and self.is_private is not None and \ + self.is_private != ip.is_private: + ok = False + if ok and self.is_link_local is not None and \ + self.is_link_local != ip.is_link_local: + ok = False + if ok and self.is_reserved is not None and \ + self.is_reserved != ip.is_reserved: + ok = False + if ok and self.is_multicast is not None and \ + self.is_multicast != ip.is_multicast: + ok = False + if ok and self.is_6to4 is not None and \ + self.is_6to4 != bool(ip.sixtofour): + ok = False + if ok and self.is_teredo is not None and \ + self.is_teredo != bool(ip.teredo): + ok = False + + if ok: + return (value, None) + + return (value, translate(self.error_message)) + + +class IS_IPADDRESS(Validator): + """ + Checks if field's value is an IP Address (v4 or v6). Can be set to force + addresses from within a specific range. Checks are done with the correct + IS_IPV4 and IS_IPV6 validators. + + Uses the ipaddress from the Python 3 standard library + and its Python 2 backport (in contrib/ipaddress.py). + + Args: + minip: lowest allowed address; accepts: + str, eg. 192.168.0.1 + list or tuple of octets, eg. [192, 168, 0, 1] + maxip: highest allowed address; same as above + invert: True to allow addresses only from outside of given range; note + that range boundaries are not matched this way + + IPv4 specific arguments: + + - is_localhost: localhost address treatment: + + - None (default): indifferent + - True (enforce): query address must match localhost address + (127.0.0.1) + - False (forbid): query address must not match localhost address + - is_private: same as above, except that query address is checked against + two address ranges: 172.16.0.0 - 172.31.255.255 and + 192.168.0.0 - 192.168.255.255 + - is_automatic: same as above, except that query address is checked against + one address range: 169.254.0.0 - 169.254.255.255 + - is_ipv4: either: + + - None (default): indifferent + - True (enforce): must be an IPv4 address + - False (forbid): must NOT be an IPv4 address + + IPv6 specific arguments: + + - is_link_local: Same as above but uses fe80::/10 range + - is_reserved: Same as above but uses IETF reserved range + - is_multicast: Same as above but uses ff00::/8 range + - is_routeable: Similar to above but enforces not private, link_local, + reserved or multicast + - is_6to4: Same as above but uses 2002::/16 range + - is_teredo: Same as above but uses 2001::/32 range + - subnets: value must be a member of at least one from list of subnets + - is_ipv6: either: + + - None (default): indifferent + - True (enforce): must be an IPv6 address + - False (forbid): must NOT be an IPv6 address + + Minip and maxip may also be lists or tuples of addresses in all above + forms (str, int, list / tuple), allowing setup of multiple address ranges:: + + minip = (minip1, minip2, ... minipN) + | | | + | | | + maxip = (maxip1, maxip2, ... maxipN) + + Longer iterable will be truncated to match length of shorter one. + + >>> IS_IPADDRESS()('192.168.1.5') + ('192.168.1.5', None) + >>> IS_IPADDRESS(is_ipv6=False)('192.168.1.5') + ('192.168.1.5', None) + >>> IS_IPADDRESS()('255.255.255.255') + ('255.255.255.255', None) + >>> IS_IPADDRESS()('192.168.1.5 ') + ('192.168.1.5 ', 'enter valid IP address') + >>> IS_IPADDRESS()('192.168.1.1.5') + ('192.168.1.1.5', 'enter valid IP address') + >>> IS_IPADDRESS()('123.123') + ('123.123', 'enter valid IP address') + >>> IS_IPADDRESS()('1111.2.3.4') + ('1111.2.3.4', 'enter valid IP address') + >>> IS_IPADDRESS()('0111.2.3.4') + ('0111.2.3.4', 'enter valid IP address') + >>> IS_IPADDRESS()('256.2.3.4') + ('256.2.3.4', 'enter valid IP address') + >>> IS_IPADDRESS()('300.2.3.4') + ('300.2.3.4', 'enter valid IP address') + >>> IS_IPADDRESS(minip='192.168.1.0', maxip='192.168.1.255')('192.168.1.100') + ('192.168.1.100', None) + >>> IS_IPADDRESS(minip='1.2.3.5', maxip='1.2.3.9', error_message='Bad ip')('1.2.3.4') + ('1.2.3.4', 'bad ip') + >>> IS_IPADDRESS(maxip='1.2.3.4', invert=True)('127.0.0.1') + ('127.0.0.1', None) + >>> IS_IPADDRESS(maxip='192.168.1.4', invert=True)('192.168.1.4') + ('192.168.1.4', 'enter valid IP address') + >>> IS_IPADDRESS(is_localhost=True)('127.0.0.1') + ('127.0.0.1', None) + >>> IS_IPADDRESS(is_localhost=True)('192.168.1.10') + ('192.168.1.10', 'enter valid IP address') + >>> IS_IPADDRESS(is_localhost=False)('127.0.0.1') + ('127.0.0.1', 'enter valid IP address') + >>> IS_IPADDRESS(maxip='100.0.0.0', is_localhost=True)('127.0.0.1') + ('127.0.0.1', 'enter valid IP address') + + >>> IS_IPADDRESS()('fe80::126c:8ffa:fe22:b3af') + ('fe80::126c:8ffa:fe22:b3af', None) + >>> IS_IPADDRESS(is_ipv4=False)('fe80::126c:8ffa:fe22:b3af') + ('fe80::126c:8ffa:fe22:b3af', None) + >>> IS_IPADDRESS()('fe80::126c:8ffa:fe22:b3af ') + ('fe80::126c:8ffa:fe22:b3af ', 'enter valid IP address') + >>> IS_IPADDRESS(is_ipv4=True)('fe80::126c:8ffa:fe22:b3af') + ('fe80::126c:8ffa:fe22:b3af', 'enter valid IP address') + >>> IS_IPADDRESS(is_ipv6=True)('192.168.1.1') + ('192.168.1.1', 'enter valid IP address') + >>> IS_IPADDRESS(is_ipv6=True, error_message='Bad ip')('192.168.1.1') + ('192.168.1.1', 'bad ip') + >>> IS_IPADDRESS(is_link_local=True)('fe80::126c:8ffa:fe22:b3af') + ('fe80::126c:8ffa:fe22:b3af', None) + >>> IS_IPADDRESS(is_link_local=False)('fe80::126c:8ffa:fe22:b3af') + ('fe80::126c:8ffa:fe22:b3af', 'enter valid IP address') + >>> IS_IPADDRESS(is_link_local=True)('2001::126c:8ffa:fe22:b3af') + ('2001::126c:8ffa:fe22:b3af', 'enter valid IP address') + >>> IS_IPADDRESS(is_multicast=True)('2001::126c:8ffa:fe22:b3af') + ('2001::126c:8ffa:fe22:b3af', 'enter valid IP address') + >>> IS_IPADDRESS(is_multicast=True)('ff00::126c:8ffa:fe22:b3af') + ('ff00::126c:8ffa:fe22:b3af', None) + >>> IS_IPADDRESS(is_routeable=True)('2001::126c:8ffa:fe22:b3af') + ('2001::126c:8ffa:fe22:b3af', None) + >>> IS_IPADDRESS(is_routeable=True)('ff00::126c:8ffa:fe22:b3af') + ('ff00::126c:8ffa:fe22:b3af', 'enter valid IP address') + >>> IS_IPADDRESS(subnets='2001::/32')('2001::8ffa:fe22:b3af') + ('2001::8ffa:fe22:b3af', None) + >>> IS_IPADDRESS(subnets='fb00::/8')('2001::8ffa:fe22:b3af') + ('2001::8ffa:fe22:b3af', 'enter valid IP address') + >>> IS_IPADDRESS(subnets=['fc00::/8','2001::/32'])('2001::8ffa:fe22:b3af') + ('2001::8ffa:fe22:b3af', None) + >>> IS_IPADDRESS(subnets='invalidsubnet')('2001::8ffa:fe22:b3af') + ('2001::8ffa:fe22:b3af', 'invalid subnet provided') + """ + + def __init__( + self, + minip='0.0.0.0', + maxip='255.255.255.255', + invert=False, + is_localhost=None, + is_private=None, + is_automatic=None, + is_ipv4=None, + is_link_local=None, + is_reserved=None, + is_multicast=None, + is_routeable=None, + is_6to4=None, + is_teredo=None, + subnets=None, + is_ipv6=None, + error_message='Enter valid IP address'): + self.minip = minip, + self.maxip = maxip, + self.invert = invert + self.is_localhost = is_localhost + self.is_private = is_private + self.is_automatic = is_automatic + self.is_ipv4 = is_ipv4 or is_ipv6 is False + self.is_private = is_private + self.is_link_local = is_link_local + self.is_reserved = is_reserved + self.is_multicast = is_multicast + self.is_routeable = is_routeable + self.is_6to4 = is_6to4 + self.is_teredo = is_teredo + self.subnets = subnets + self.is_ipv6 = is_ipv6 or is_ipv4 is False + self.error_message = error_message + + def __call__(self, value): + from gluon._compat import ipaddress + IPAddress = ipaddress.ip_address + IPv6Address = ipaddress.IPv6Address + IPv4Address = ipaddress.IPv4Address + + try: + ip = IPAddress(to_unicode(value)) + except ValueError: + return (value, translate(self.error_message)) + + if self.is_ipv4 and isinstance(ip, IPv6Address): + retval = (value, translate(self.error_message)) + elif self.is_ipv6 and isinstance(ip, IPv4Address): + retval = (value, translate(self.error_message)) + elif self.is_ipv4 or isinstance(ip, IPv4Address): + retval = IS_IPV4( + minip=self.minip, + maxip=self.maxip, + invert=self.invert, + is_localhost=self.is_localhost, + is_private=self.is_private, + is_automatic=self.is_automatic, + error_message=self.error_message + )(value) + elif self.is_ipv6 or isinstance(ip, IPv6Address): + retval = IS_IPV6( + is_private=self.is_private, + is_link_local=self.is_link_local, + is_reserved=self.is_reserved, + is_multicast=self.is_multicast, + is_routeable=self.is_routeable, + is_6to4=self.is_6to4, + is_teredo=self.is_teredo, + subnets=self.subnets, + error_message=self.error_message + )(value) + else: + retval = (value, translate(self.error_message)) + + return retval diff --git a/web2py/gluon/widget.py b/web2py/gluon/widget.py new file mode 100644 index 0000000..fbd522a --- /dev/null +++ b/web2py/gluon/widget.py @@ -0,0 +1,1332 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu> +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +The widget is called from web2py +---------------------------------- +""" +from __future__ import print_function + +import datetime +import sys +from gluon._compat import StringIO, thread, xrange, PY2 +import time +import threading +import os +import copy +import socket +import signal +import math +import logging +import getpass +from gluon import main, newcron + + +from gluon.fileutils import read_file, write_file, create_welcome_w2p +from gluon.settings import global_settings +from gluon.shell import run, test +from gluon.utils import is_valid_ip_address, is_loopback_ip_address, getipaddrinfo + + +ProgramName = 'web2py Web Framework' +ProgramAuthor = 'Created by Massimo Di Pierro, Copyright 2007-' + str( + datetime.datetime.now().year) +ProgramVersion = read_file('VERSION').strip() + +ProgramInfo = '''%s + %s + %s''' % (ProgramName, ProgramAuthor, ProgramVersion) + +if sys.version_info < (2, 7) and (3, 0) < sys.version_info < (3, 5): + msg = 'Warning: web2py requires at least Python 2.7/3.5 but you are running:\n%s' + msg = msg % sys.version + sys.stderr.write(msg) + +logger = logging.getLogger("web2py") + + +def run_system_tests(options): + """ + Runs unittests for gluon.tests + """ + import subprocess + major_version = sys.version_info[0] + call_args = [sys.executable, '-m', 'unittest', '-v', 'gluon.tests'] + if major_version == 2: + sys.stderr.write("Python 2.7\n") + else: + sys.stderr.write("Experimental Python 3.x.\n") + if options.with_coverage: + has_coverage = False + coverage_exec = 'coverage2' if major_version == 2 else 'coverage3' + try: + import coverage + has_coverage = True + except: + sys.stderr.write('Coverage was not installed, skipping\n') + coverage_config_file = os.path.join('gluon', 'tests', 'coverage.ini') + coverage_config = os.environ.setdefault("COVERAGE_PROCESS_START", + coverage_config_file) + call_args = [coverage_exec, 'run', '--rcfile=%s' % + coverage_config, '-m', 'unittest', '-v', 'gluon.tests'] + if has_coverage: + ret = subprocess.call(call_args) + else: + ret = 256 + else: + ret = subprocess.call(call_args) + sys.exit(ret and 1) + + +class IO(object): + """ """ + + def __init__(self): + """ """ + + self.buffer = StringIO() + + def write(self, data): + """ """ + + sys.__stdout__.write(data) + if hasattr(self, 'callback'): + self.callback(data) + else: + self.buffer.write(data) + + +def get_url(host, path='/', proto='http', port=80): + if ':' in host: + host = '[%s]' % host + else: + host = host.replace('0.0.0.0', '127.0.0.1') + if path.startswith('/'): + path = path[1:] + if proto.endswith(':'): + proto = proto[:-1] + if not port or port == 80: + port = '' + else: + port = ':%s' % port + return '%s://%s%s/%s' % (proto, host, port, path) + + +def start_browser(url, startup=False): + if startup: + print('please visit:') + print('\t', url) + print('starting browser...') + try: + import webbrowser + webbrowser.open(url) + except: + print('warning: unable to detect your browser') + + +class web2pyDialog(object): + """ Main window dialog """ + + def __init__(self, root, options): + """ web2pyDialog constructor """ + + if PY2: + import Tkinter as tkinter + import tkMessageBox as messagebox + else: + import tkinter + from tkinter import messagebox + + + bg_color = 'white' + root.withdraw() + + self.root = tkinter.Toplevel(root, bg=bg_color) + self.root.resizable(0, 0) + self.root.title(ProgramName) + + self.options = options + self.scheduler_processes = {} + self.menu = tkinter.Menu(self.root) + servermenu = tkinter.Menu(self.menu, tearoff=0) + httplog = os.path.join(self.options.folder, self.options.log_filename) + iconphoto = os.path.join('extras', 'icons', 'web2py.gif') + if os.path.exists(iconphoto): + img = tkinter.PhotoImage(file=iconphoto) + self.root.tk.call('wm', 'iconphoto', self.root._w, img) + # Building the Menu + item = lambda: start_browser(httplog) + servermenu.add_command(label='View httpserver.log', + command=item) + + servermenu.add_command(label='Quit (pid:%i)' % os.getpid(), + command=self.quit) + + self.menu.add_cascade(label='Server', menu=servermenu) + + self.pagesmenu = tkinter.Menu(self.menu, tearoff=0) + self.menu.add_cascade(label='Pages', menu=self.pagesmenu) + + #scheduler menu + self.schedmenu = tkinter.Menu(self.menu, tearoff=0) + self.menu.add_cascade(label='Scheduler', menu=self.schedmenu) + #start and register schedulers from options + self.update_schedulers(start=True) + + helpmenu = tkinter.Menu(self.menu, tearoff=0) + + # Home Page + item = lambda: start_browser('http://www.web2py.com/') + helpmenu.add_command(label='Home Page', + command=item) + + # About + item = lambda: messagebox.showinfo('About web2py', ProgramInfo) + helpmenu.add_command(label='About', + command=item) + + self.menu.add_cascade(label='Info', menu=helpmenu) + + self.root.config(menu=self.menu) + + if options.taskbar: + self.root.protocol('WM_DELETE_WINDOW', + lambda: self.quit(True)) + else: + self.root.protocol('WM_DELETE_WINDOW', self.quit) + + sticky = tkinter.NW + + # Prepare the logo area + self.logoarea = tkinter.Canvas(self.root, + background=bg_color, + width=300, + height=300) + self.logoarea.grid(row=0, column=0, columnspan=4, sticky=sticky) + self.logoarea.after(1000, self.update_canvas) + + logo = os.path.join('extras', 'icons', 'splashlogo.gif') + if os.path.exists(logo): + img = tkinter.PhotoImage(file=logo) + pnl = tkinter.Label(self.logoarea, image=img, background=bg_color, bd=0) + pnl.pack(side='top', fill='both', expand='yes') + # Prevent garbage collection of img + pnl.image = img + + # Prepare the banner area + self.bannerarea = tkinter.Canvas(self.root, + bg=bg_color, + width=300, + height=300) + self.bannerarea.grid(row=1, column=1, columnspan=2, sticky=sticky) + + tkinter.Label(self.bannerarea, anchor=tkinter.N, + text=str(ProgramVersion + "\n" + ProgramAuthor), + font=('Helvetica', 11), justify=tkinter.CENTER, + foreground='#195866', background=bg_color, + height=3).pack(side='top', + fill='both', + expand='yes') + + self.bannerarea.after(1000, self.update_canvas) + + # IP + tkinter.Label(self.root, + text='Server IP:', bg=bg_color, + justify=tkinter.RIGHT).grid(row=4, + column=1, + sticky=sticky) + self.ips = {} + self.selected_ip = tkinter.StringVar() + row = 4 + ips = [('127.0.0.1', 'Local (IPv4)')] + \ + ([('::1', 'Local (IPv6)')] if socket.has_ipv6 else []) + \ + [(ip, 'Public') for ip in options.ips] + \ + [('0.0.0.0', 'Public')] + for ip, legend in ips: + self.ips[ip] = tkinter.Radiobutton( + self.root, bg=bg_color, highlightthickness=0, + selectcolor='light grey', width=30, + anchor=tkinter.W, text='%s (%s)' % (legend, ip), + justify=tkinter.LEFT, + variable=self.selected_ip, value=ip) + self.ips[ip].grid(row=row, column=2, sticky=sticky) + if row == 4: + self.ips[ip].select() + row += 1 + shift = row + + # Port + tkinter.Label(self.root, + text='Server Port:', bg=bg_color, + justify=tkinter.RIGHT).grid(row=shift, + column=1, pady=10, + sticky=sticky) + + self.port_number = tkinter.Entry(self.root) + self.port_number.insert(tkinter.END, self.options.port) + self.port_number.grid(row=shift, column=2, sticky=sticky, pady=10) + + # Password + tkinter.Label(self.root, + text='Choose Password:', bg=bg_color, + justify=tkinter.RIGHT).grid(row=shift + 1, + column=1, + sticky=sticky) + + self.password = tkinter.Entry(self.root, show='*') + self.password.bind('<Return>', lambda e: self.start()) + self.password.focus_force() + self.password.grid(row=shift + 1, column=2, sticky=sticky) + + # Prepare the canvas + self.canvas = tkinter.Canvas(self.root, + width=400, + height=100, + bg='black') + self.canvas.grid(row=shift + 2, column=1, columnspan=2, pady=5, + sticky=sticky) + self.canvas.after(1000, self.update_canvas) + + # Prepare the frame + frame = tkinter.Frame(self.root) + frame.grid(row=shift + 3, column=1, columnspan=2, pady=5, + sticky=sticky) + + # Start button + self.button_start = tkinter.Button(frame, + text='start server', + command=self.start) + + self.button_start.grid(row=0, column=0, sticky=sticky) + + # Stop button + self.button_stop = tkinter.Button(frame, + text='stop server', + command=self.stop) + + self.button_stop.grid(row=0, column=1, sticky=sticky) + self.button_stop.configure(state='disabled') + + if options.taskbar: + import gluon.contrib.taskbar_widget + self.tb = gluon.contrib.taskbar_widget.TaskBarIcon() + self.checkTaskBar() + + if options.password != '<ask>': + self.password.insert(0, options.password) + self.start() + self.root.withdraw() + else: + self.tb = None + + def update_schedulers(self, start=False): + applications_folder = os.path.join(self.options.folder, 'applications') + apps = [] + available_apps = [ + arq for arq in os.listdir(applications_folder) + if os.path.exists(os.path.join(applications_folder, arq, 'models', 'scheduler.py')) + ] + if start: + # the widget takes care of starting the scheduler + if self.options.scheduler and self.options.with_scheduler: + apps = [app.strip() for app + in self.options.scheduler.split(',') + if app in available_apps] + for app in apps: + self.try_start_scheduler(app) + + # reset the menu + self.schedmenu.delete(0, len(available_apps)) + + for arq in available_apps: + if arq not in self.scheduler_processes: + item = lambda u = arq: self.try_start_scheduler(u) + self.schedmenu.add_command(label="start %s" % arq, + command=item) + if arq in self.scheduler_processes: + item = lambda u = arq: self.try_stop_scheduler(u) + self.schedmenu.add_command(label="stop %s" % arq, + command=item) + + def start_schedulers(self, app): + try: + from multiprocessing import Process + except: + sys.stderr.write('Sorry, -K only supported for python 2.6-2.7\n') + return + code = "from gluon.globals import current;current._scheduler.loop()" + print('starting scheduler from widget for "%s"...' % app) + args = (app, True, True, None, False, code) + logging.getLogger().setLevel(self.options.debuglevel) + p = Process(target=run, args=args) + self.scheduler_processes[app] = p + self.update_schedulers() + print("Currently running %s scheduler processes" % ( + len(self.scheduler_processes))) + p.start() + print("Processes started") + + def try_stop_scheduler(self, app): + if app in self.scheduler_processes: + p = self.scheduler_processes[app] + del self.scheduler_processes[app] + p.terminate() + p.join() + self.update_schedulers() + + def try_start_scheduler(self, app): + if app not in self.scheduler_processes: + t = threading.Thread(target=self.start_schedulers, args=(app,)) + t.start() + + def checkTaskBar(self): + """ Checks taskbar status """ + + if self.tb.status: + if self.tb.status[0] == self.tb.EnumStatus.QUIT: + self.quit() + elif self.tb.status[0] == self.tb.EnumStatus.TOGGLE: + if self.root.state() == 'withdrawn': + self.root.deiconify() + else: + self.root.withdraw() + elif self.tb.status[0] == self.tb.EnumStatus.STOP: + self.stop() + elif self.tb.status[0] == self.tb.EnumStatus.START: + self.start() + elif self.tb.status[0] == self.tb.EnumStatus.RESTART: + self.stop() + self.start() + del self.tb.status[0] + + self.root.after(1000, self.checkTaskBar) + + def update(self, text): + """ Updates app text """ + + try: + self.text.configure(state='normal') + self.text.insert('end', text) + self.text.configure(state='disabled') + except: + pass # ## this should only happen in case app is destroyed + + def connect_pages(self): + """ Connects pages """ + # reset the menu + applications_folder = os.path.join(self.options.folder, 'applications') + available_apps = [ + arq for arq in os.listdir(applications_folder) + if os.path.exists(os.path.join(applications_folder, arq, '__init__.py')) + ] + self.pagesmenu.delete(0, len(available_apps)) + for arq in available_apps: + url = self.url + arq + self.pagesmenu.add_command( + label=url, command=lambda u=url: start_browser(u)) + + def quit(self, justHide=False): + """ Finishes the program execution """ + if justHide: + self.root.withdraw() + else: + try: + scheds = self.scheduler_processes.keys() + for t in scheds: + self.try_stop_scheduler(t) + except: + pass + try: + newcron.stopcron() + except: + pass + try: + self.server.stop() + except: + pass + try: + self.tb.Destroy() + except: + pass + + self.root.destroy() + sys.exit(0) + + def error(self, message): + """ Shows error message """ + if PY2: + import tkMessageBox as messagebox + else: + from tkinter import messagebox + + messagebox.showerror('web2py start server', message) + + def start(self): + """ Starts web2py server """ + + password = self.password.get() + + if not password: + self.error('no password, no web admin interface') + + ip = self.selected_ip.get() + + if not is_valid_ip_address(ip): + return self.error('invalid host ip address') + + try: + port = int(self.port_number.get()) + except: + return self.error('invalid port number') + + # Check for non default value for ssl inputs + if (len(self.options.ssl_certificate) > 0 or + len(self.options.ssl_private_key) > 0): + proto = 'https' + else: + proto = 'http' + + self.url = get_url(ip, proto=proto, port=port) + self.connect_pages() + self.button_start.configure(state='disabled') + + try: + options = self.options + req_queue_size = options.request_queue_size + self.server = main.HttpServer( + ip, + port, + password, + pid_filename=options.pid_filename, + log_filename=options.log_filename, + profiler_dir=options.profiler_dir, + ssl_certificate=options.ssl_certificate, + ssl_private_key=options.ssl_private_key, + ssl_ca_certificate=options.ssl_ca_certificate, + min_threads=options.minthreads, + max_threads=options.maxthreads, + server_name=options.server_name, + request_queue_size=req_queue_size, + timeout=options.timeout, + shutdown_timeout=options.shutdown_timeout, + path=options.folder, + interfaces=options.interfaces) + + thread.start_new_thread(self.server.start, ()) + except Exception as e: + self.button_start.configure(state='normal') + return self.error(str(e)) + + if not self.server_ready(): + self.button_start.configure(state='normal') + return + + self.button_stop.configure(state='normal') + + if not options.taskbar: + thread.start_new_thread( + start_browser, (get_url(ip, proto=proto, port=port), True)) + + self.password.configure(state='readonly') + [ip.configure(state='disabled') for ip in self.ips.values()] + self.port_number.configure(state='readonly') + + if self.tb: + self.tb.SetServerRunning() + + def server_ready(self): + for listener in self.server.server.listeners: + if listener.ready: + return True + + return False + + def stop(self): + """ Stops web2py server """ + + self.button_start.configure(state='normal') + self.button_stop.configure(state='disabled') + self.password.configure(state='normal') + [ip.configure(state='normal') for ip in self.ips.values()] + self.port_number.configure(state='normal') + self.server.stop() + + if self.tb: + self.tb.SetServerStopped() + + def update_canvas(self): + """ Updates canvas """ + + httplog = os.path.join(self.options.folder, self.options.log_filename) + try: + t1 = os.path.getsize(httplog) + except: + self.canvas.after(1000, self.update_canvas) + return + + try: + fp = open(httplog, 'r') + fp.seek(self.t0) + data = fp.read(t1 - self.t0) + fp.close() + value = self.p0[1:] + [10 + 90.0 / math.sqrt(1 + data.count('\n'))] + self.p0 = value + + for i in xrange(len(self.p0) - 1): + c = self.canvas.coords(self.q0[i]) + self.canvas.coords(self.q0[i], + (c[0], + self.p0[i], + c[2], + self.p0[i + 1])) + self.t0 = t1 + except BaseException: + self.t0 = time.time() + self.t0 = t1 + self.p0 = [100] * 400 + self.q0 = [self.canvas.create_line(i, 100, i + 1, 100, + fill='green') for i in xrange(len(self.p0) - 1)] + + self.canvas.after(1000, self.update_canvas) + + +def console(): + """ Defines the behavior of the console web2py execution """ + import optparse + import textwrap + + usage = "python web2py.py" + + description = """\ + web2py Web Framework startup script. + ATTENTION: unless a password is specified (-a 'passwd') web2py will + attempt to run a GUI. In this case command line options are ignored.""" + + description = textwrap.dedent(description) + + parser = optparse.OptionParser( + usage, None, optparse.Option, ProgramVersion) + + parser.description = description + + msg = ('IP address of the server (e.g., 127.0.0.1 or ::1); ' + 'Note: This value is ignored when using the \'interfaces\' option.') + parser.add_option('-i', + '--ip', + default='127.0.0.1', + dest='ip', + help=msg) + + parser.add_option('-p', + '--port', + default='8000', + dest='port', + type='int', + help='port of server (8000)') + + parser.add_option('-G', + '--GAE', + default=None, + dest='gae', + help="'-G configure' will create app.yaml and gaehandler.py") + + msg = ('password to be used for administration ' + '(use -a "<recycle>" to reuse the last password))') + parser.add_option('-a', + '--password', + default='<ask>', + dest='password', + help=msg) + + parser.add_option('-c', + '--ssl_certificate', + default='', + dest='ssl_certificate', + help='file that contains ssl certificate') + + parser.add_option('-k', + '--ssl_private_key', + default='', + dest='ssl_private_key', + help='file that contains ssl private key') + + msg = ('Use this file containing the CA certificate to validate X509 ' + 'certificates from clients') + parser.add_option('--ca-cert', + action='store', + dest='ssl_ca_certificate', + default=None, + help=msg) + + parser.add_option('-d', + '--pid_filename', + default='httpserver.pid', + dest='pid_filename', + help='file to store the pid of the server') + + parser.add_option('-l', + '--log_filename', + default='httpserver.log', + dest='log_filename', + help='file to log connections') + + parser.add_option('-n', + '--numthreads', + default=None, + type='int', + dest='numthreads', + help='number of threads (deprecated)') + + parser.add_option('--minthreads', + default=None, + type='int', + dest='minthreads', + help='minimum number of server threads') + + parser.add_option('--maxthreads', + default=None, + type='int', + dest='maxthreads', + help='maximum number of server threads') + + parser.add_option('-s', + '--server_name', + default=socket.gethostname(), + dest='server_name', + help='server name for the web server') + + msg = 'max number of queued requests when server unavailable' + parser.add_option('-q', + '--request_queue_size', + default='5', + type='int', + dest='request_queue_size', + help=msg) + + parser.add_option('-o', + '--timeout', + default='10', + type='int', + dest='timeout', + help='timeout for individual request (10 seconds)') + + parser.add_option('-z', + '--shutdown_timeout', + default='5', + type='int', + dest='shutdown_timeout', + help='timeout on shutdown of server (5 seconds)') + + parser.add_option('--socket-timeout', + default=5, + type='int', + dest='socket_timeout', + help='timeout for socket (5 second)') + + parser.add_option('-f', + '--folder', + default=os.getcwd(), + dest='folder', + help='folder from which to run web2py') + + parser.add_option('-v', + '--verbose', + action='store_true', + dest='verbose', + default=False, + help='increase --test verbosity') + + parser.add_option('-Q', + '--quiet', + action='store_true', + dest='quiet', + default=False, + help='disable all output') + + parser.add_option('-e', + '--errors_to_console', + action='store_true', + dest='print_errors', + default=False, + help='log all errors to console') + + msg = ('set debug output level (0-100, 0 means all, 100 means none; ' + 'default is 30)') + parser.add_option('-D', + '--debug', + dest='debuglevel', + default=30, + type='int', + help=msg) + + msg = ('run web2py in interactive shell or IPython (if installed) with ' + 'specified appname (if app does not exist it will be created). ' + 'APPNAME like a/c/f?x=y (c,f and vars x,y optional)') + parser.add_option('-S', + '--shell', + dest='shell', + metavar='APPNAME', + help=msg) + + msg = ('run web2py in interactive shell or bpython (if installed) with ' + 'specified appname (if app does not exist it will be created).\n' + 'Use combined with --shell') + parser.add_option('-B', + '--bpython', + action='store_true', + default=False, + dest='bpython', + help=msg) + + msg = 'only use plain python shell; should be used with --shell option' + parser.add_option('-P', + '--plain', + action='store_true', + default=False, + dest='plain', + help=msg) + + msg = ('auto import model files; default is False; should be used ' + 'with --shell option') + parser.add_option('-M', + '--import_models', + action='store_true', + default=False, + dest='import_models', + help=msg) + + msg = ('run PYTHON_FILE in web2py environment; ' + 'should be used with --shell option') + parser.add_option('-R', + '--run', + dest='run', + metavar='PYTHON_FILE', + default='', + help=msg) + + msg = ('run scheduled tasks for the specified apps: expects a list of ' + 'app names as -K app1,app2,app3 ' + 'or a list of app:groups as -K app1:group1:group2,app2:group1 ' + 'to override specific group_names. (only strings, no spaces ' + 'allowed. Requires a scheduler defined in the models') + parser.add_option('-K', + '--scheduler', + dest='scheduler', + default=None, + help=msg) + + msg = 'run schedulers alongside webserver, needs -K app1 and -a too' + parser.add_option('-X', + '--with-scheduler', + action='store_true', + default=False, + dest='with_scheduler', + help=msg) + + msg = ('run doctests in web2py environment; ' + 'TEST_PATH like a/c/f (c,f optional)') + parser.add_option('-T', + '--test', + dest='test', + metavar='TEST_PATH', + default=None, + help=msg) + + msg = 'trigger a cron run manually; usually invoked from a system crontab' + parser.add_option('-C', + '--cron', + action='store_true', + dest='extcron', + default=False, + help=msg) + + msg = 'triggers the use of softcron' + parser.add_option('--softcron', + action='store_true', + dest='softcron', + default=False, + help=msg) + + parser.add_option('-Y', + '--run-cron', + action='store_true', + dest='runcron', + default=False, + help='start the background cron process') + + parser.add_option('-J', + '--cronjob', + action='store_true', + dest='cronjob', + default=False, + help='identify cron-initiated command') + + parser.add_option('-L', + '--config', + dest='config', + default='', + help='config file') + + parser.add_option('-F', + '--profiler', + dest='profiler_dir', + default=None, + help='profiler dir') + + parser.add_option('-t', + '--taskbar', + action='store_true', + dest='taskbar', + default=False, + help='use web2py gui and run in taskbar (system tray)') + + parser.add_option('', + '--nogui', + action='store_true', + default=False, + dest='nogui', + help='text-only, no GUI') + + msg = ('should be followed by a list of arguments to be passed to script, ' + 'to be used with -S, -A must be the last option') + parser.add_option('-A', + '--args', + action='store', + dest='args', + default=None, + help=msg) + + parser.add_option('--no-banner', + action='store_true', + default=False, + dest='nobanner', + help='Do not print header banner') + + msg = ('listen on multiple addresses: ' + '"ip1:port1:key1:cert1:ca_cert1;ip2:port2:key2:cert2:ca_cert2;..." ' + '(:key:cert:ca_cert optional; no spaces; IPv6 addresses must be in ' + 'square [] brackets)') + parser.add_option('--interfaces', + action='store', + dest='interfaces', + default=None, + help=msg) + + msg = 'runs web2py tests' + parser.add_option('--run_system_tests', + action='store_true', + dest='run_system_tests', + default=False, + help=msg) + + msg = ('adds coverage reporting (needs --run_system_tests), ' + 'python 2.7 and the coverage module installed. ' + 'You can alter the default path setting the environmental ' + 'var "COVERAGE_PROCESS_START". ' + 'By default it takes gluon/tests/coverage.ini') + parser.add_option('--with_coverage', + action='store_true', + dest='with_coverage', + default=False, + help=msg) + + if '-A' in sys.argv: + k = sys.argv.index('-A') + elif '--args' in sys.argv: + k = sys.argv.index('--args') + else: + k = len(sys.argv) + sys.argv, other_args = sys.argv[:k], sys.argv[k + 1:] + (options, args) = parser.parse_args() + options.args = [options.run] + other_args + + copy_options = copy.deepcopy(options) + copy_options.password = '******' + global_settings.cmd_options = copy_options + global_settings.cmd_args = args + + if options.gae: + if not os.path.exists('app.yaml'): + name = raw_input("Your GAE app name: ") + content = open(os.path.join('examples', 'app.example.yaml'), 'rb').read() + open('app.yaml', 'wb').write(content.replace("yourappname", name)) + else: + print("app.yaml alreday exists in the web2py folder") + if not os.path.exists('gaehandler.py'): + content = open(os.path.join('handlers', 'gaehandler.py'), 'rb').read() + open('gaehandler.py', 'wb').write(content) + else: + print("gaehandler.py alreday exists in the web2py folder") + sys.exit(0) + + try: + options.ips = list(set( # no duplicates + [addrinfo[4][0] for addrinfo in getipaddrinfo(socket.getfqdn()) + if not is_loopback_ip_address(addrinfo=addrinfo)])) + except socket.gaierror: + options.ips = [] + + if options.run_system_tests: + run_system_tests(options) + + if options.quiet: + capture = StringIO() + sys.stdout = capture + logger.setLevel(logging.CRITICAL + 1) + else: + logger.setLevel(options.debuglevel) + + if options.config[-3:] == '.py': + options.config = options.config[:-3] + + if options.cronjob: + global_settings.cronjob = True # tell the world + options.plain = True # cronjobs use a plain shell + options.nobanner = True + options.nogui = True + + options.folder = os.path.abspath(options.folder) + + # accept --interfaces in the form + # "ip1:port1:key1:cert1:ca_cert1;[ip2]:port2;ip3:port3:key3:cert3" + # (no spaces; optional key:cert indicate SSL) + if isinstance(options.interfaces, str): + interfaces = options.interfaces.split(';') + options.interfaces = [] + for interface in interfaces: + if interface.startswith('['): # IPv6 + ip, if_remainder = interface.split(']', 1) + ip = ip[1:] + if_remainder = if_remainder[1:].split(':') + if_remainder[0] = int(if_remainder[0]) # numeric port + options.interfaces.append(tuple([ip] + if_remainder)) + else: # IPv4 + interface = interface.split(':') + interface[1] = int(interface[1]) # numeric port + options.interfaces.append(tuple(interface)) + + # accepts --scheduler in the form + # "app:group1,group2,app2:group1" + scheduler = [] + options.scheduler_groups = None + if isinstance(options.scheduler, str): + if ':' in options.scheduler: + for opt in options.scheduler.split(','): + scheduler.append(opt.split(':')) + options.scheduler = ','.join([app[0] for app in scheduler]) + options.scheduler_groups = scheduler + + if options.numthreads is not None and options.minthreads is None: + options.minthreads = options.numthreads # legacy + + create_welcome_w2p() + + if not options.cronjob: + # If we have the applications package or if we should upgrade + if not os.path.exists('applications/__init__.py'): + write_file('applications/__init__.py', '') + + return options, args + + +def check_existent_app(options, appname): + if os.path.isdir(os.path.join(options.folder, 'applications', appname)): + return True + + +def get_code_for_scheduler(app, options): + if len(app) == 1 or app[1] is None: + code = "from gluon.globals import current;current._scheduler.loop()" + else: + code = "from gluon.globals import current;current._scheduler.group_names = ['%s'];" + code += "current._scheduler.loop()" + code = code % ("','".join(app[1:])) + app_ = app[0] + if not check_existent_app(options, app_): + print("Application '%s' doesn't exist, skipping" % app_) + return None, None + return app_, code + + +def start_schedulers(options): + try: + from multiprocessing import Process + except: + sys.stderr.write('Sorry, -K only supported for python 2.6-2.7\n') + return + processes = [] + apps = [(app.strip(), None) for app in options.scheduler.split(',')] + if options.scheduler_groups: + apps = options.scheduler_groups + code = "from gluon.globals import current;current._scheduler.loop()" + logging.getLogger().setLevel(options.debuglevel) + if options.folder: + os.chdir(options.folder) + if len(apps) == 1 and not options.with_scheduler: + app_, code = get_code_for_scheduler(apps[0], options) + if not app_: + return + print('starting single-scheduler for "%s"...' % app_) + run(app_, True, True, None, False, code) + return + + # Work around OS X problem: http://bugs.python.org/issue9405 + if PY2: + import urllib + else: + import urllib.request as urllib + urllib.getproxies() + + for app in apps: + app_, code = get_code_for_scheduler(app, options) + if not app_: + continue + print('starting scheduler for "%s"...' % app_) + args = (app_, True, True, None, False, code) + p = Process(target=run, args=args) + processes.append(p) + print("Currently running %s scheduler processes" % (len(processes))) + p.start() + ##to avoid bashing the db at the same time + time.sleep(0.7) + print("Processes started") + for p in processes: + try: + p.join() + except (KeyboardInterrupt, SystemExit): + print("Processes stopped") + except: + p.terminate() + p.join() + + +def start(cron=True): + """ Starts server """ + + # ## get command line arguments + + (options, args) = console() + + if not options.nobanner: + print(ProgramName) + print(ProgramAuthor) + print(ProgramVersion) + + from pydal.drivers import DRIVERS + if not options.nobanner: + print('Database drivers available: %s' % ', '.join(DRIVERS)) + + # ## if -L load options from options.config file + if options.config: + try: + options2 = __import__(options.config, {}, {}, '') + except Exception: + try: + # Jython doesn't like the extra stuff + options2 = __import__(options.config) + except Exception: + print('Cannot import config file [%s]' % options.config) + sys.exit(1) + for key in dir(options2): + if hasattr(options, key): + setattr(options, key, getattr(options2, key)) + + # ## if -T run doctests (no cron) + if hasattr(options, 'test') and options.test: + test(options.test, verbose=options.verbose) + return + + # ## if -S start interactive shell (also no cron) + if options.shell: + if options.folder: + os.chdir(options.folder) + if not options.args is None: + sys.argv[:] = options.args + run(options.shell, plain=options.plain, bpython=options.bpython, + import_models=options.import_models, startfile=options.run, + cronjob=options.cronjob) + return + + # ## if -C start cron run (extcron) and exit + # ## -K specifies optional apps list (overloading scheduler) + if options.extcron: + logger.debug('Starting extcron...') + global_settings.web2py_crontype = 'external' + if options.scheduler: # -K + apps = [app.strip() for app in options.scheduler.split( + ',') if check_existent_app(options, app.strip())] + else: + apps = None + extcron = newcron.extcron(options.folder, apps=apps) + extcron.start() + extcron.join() + return + + # ## if -K + if options.scheduler and not options.with_scheduler: + try: + start_schedulers(options) + except KeyboardInterrupt: + pass + return + + # ## if -H cron is enabled in this *process* + # ## if --softcron use softcron + # ## use hardcron in all other cases + if cron and options.runcron and options.softcron: + print('Using softcron (but this is not very efficient)') + global_settings.web2py_crontype = 'soft' + elif cron and options.runcron: + logger.debug('Starting hardcron...') + global_settings.web2py_crontype = 'hard' + newcron.hardcron(options.folder).start() + + # ## if no password provided and havetk start Tk interface + # ## or start interface if we want to put in taskbar (system tray) + + try: + options.taskbar + except: + options.taskbar = False + + if options.taskbar and os.name != 'nt': + print('Error: taskbar not supported on this platform') + sys.exit(1) + + root = None + + if not options.nogui and options.password == '<ask>': + try: + if PY2: + import Tkinter as tkinter + else: + import tkinter + havetk = True + try: + root = tkinter.Tk() + except: + pass + except (ImportError, OSError): + logger.warn( + 'GUI not available because Tk library is not installed') + havetk = False + options.nogui = True + + if root: + root.focus_force() + + # Mac OS X - make the GUI window rise to the top + if os.path.exists("/usr/bin/osascript"): + applescript = """ +tell application "System Events" + set proc to first process whose unix id is %d + set frontmost of proc to true +end tell +""" % (os.getpid()) + os.system("/usr/bin/osascript -e '%s'" % applescript) + + master = web2pyDialog(root, options) + signal.signal(signal.SIGTERM, lambda a, b: master.quit()) + + try: + root.mainloop() + except: + master.quit() + + sys.exit() + + # ## if no tk and no password, ask for a password + + if not root and options.password == '<ask>': + options.password = getpass.getpass('choose a password:') + + if not options.password and not options.nobanner: + print('no password, no admin interface') + + # ##-X (if no tk, the widget takes care of it himself) + if not root and options.scheduler and options.with_scheduler: + t = threading.Thread(target=start_schedulers, args=(options,)) + t.start() + + # ## start server + + # Use first interface IP and port if interfaces specified, since the + # interfaces option overrides the IP (and related) options. + if not options.interfaces: + (ip, port) = (options.ip, int(options.port)) + else: + first_if = options.interfaces[0] + (ip, port) = first_if[0], first_if[1] + + # Check for non default value for ssl inputs + if (len(options.ssl_certificate) > 0) or (len(options.ssl_private_key) > 0): + proto = 'https' + else: + proto = 'http' + + url = get_url(ip, proto=proto, port=port) + + if not options.nobanner: + message = '\nplease visit:\n\t%s\n' % url + if sys.platform.startswith('win'): + message += 'use "taskkill /f /pid %i" to shutdown the web2py server\n\n' % os.getpid() + else: + message += 'use "kill -SIGTERM %i" to shutdown the web2py server\n\n' % os.getpid() + print(message) + + # enhance linecache.getline (used by debugger) to look at the source file + # if the line was not found (under py2exe & when file was modified) + import linecache + py2exe_getline = linecache.getline + + def getline(filename, lineno, *args, **kwargs): + line = py2exe_getline(filename, lineno, *args, **kwargs) + if not line: + try: + f = open(filename, "r") + try: + for i, line in enumerate(f): + if lineno == i + 1: + break + else: + line = None + finally: + f.close() + except (IOError, OSError): + line = None + return line + linecache.getline = getline + + server = main.HttpServer(ip=ip, + port=port, + password=options.password, + pid_filename=options.pid_filename, + log_filename=options.log_filename, + profiler_dir=options.profiler_dir, + ssl_certificate=options.ssl_certificate, + ssl_private_key=options.ssl_private_key, + ssl_ca_certificate=options.ssl_ca_certificate, + min_threads=options.minthreads, + max_threads=options.maxthreads, + server_name=options.server_name, + request_queue_size=options.request_queue_size, + timeout=options.timeout, + socket_timeout=options.socket_timeout, + shutdown_timeout=options.shutdown_timeout, + path=options.folder, + interfaces=options.interfaces) + + try: + server.start() + except KeyboardInterrupt: + server.stop() + try: + t.join() + except: + pass + logging.shutdown() diff --git a/web2py/gluon/xmlrpc.py b/web2py/gluon/xmlrpc.py new file mode 100644 index 0000000..4957e99 --- /dev/null +++ b/web2py/gluon/xmlrpc.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +| This file is part of the web2py Web Framework +| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu> +| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) +""" + +from SimpleXMLRPCServer import SimpleXMLRPCDispatcher + + +def handler(request, response, methods): + response.session_id = None # no sessions for xmlrpc + dispatcher = SimpleXMLRPCDispatcher(allow_none=True, encoding=None) + for method in methods: + dispatcher.register_function(method) + dispatcher.register_introspection_functions() + response.headers['Content-Type'] = 'text/xml' + dispatch = getattr(dispatcher, '_dispatch', None) + return dispatcher._marshaled_dispatch(request.body.read(), dispatch) diff --git a/web2py/handlers/README b/web2py/handlers/README new file mode 100644 index 0000000..271d035 --- /dev/null +++ b/web2py/handlers/README @@ -0,0 +1,3 @@ +This folder contains example handlers. +They must be copied to the web2py root folder in order to work properly. +They should not be used in their current location. diff --git a/web2py/handlers/cgihandler.py b/web2py/handlers/cgihandler.py new file mode 100644 index 0000000..bd5bdf9 --- /dev/null +++ b/web2py/handlers/cgihandler.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +This file is part of the web2py Web Framework +Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu> +License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +This is a CGI handler for Apache +Requires apache+[mod_cgi or mod_cgid]. + +In httpd.conf put something like: + + LoadModule cgi_module modules/mod_cgi.so + ScriptAlias / /path/to/cgihandler.py/ + +Example of httpd.conf ------------ +<VirtualHost *:80> + ServerName web2py.example.com + ScriptAlias / /users/www-data/web2py/cgihandler.py/ + + <Directory /users/www-data/web2py> + AllowOverride None + Order Allow,Deny + Deny from all + <Files cgihandler.py> + Allow from all + </Files> + </Directory> + + AliasMatch ^/([^/]+)/static/(.*) \ + /users/www-data/web2py/applications/$1/static/$2 + <Directory /users/www-data/web2py/applications/*/static/> + Order Allow,Deny + Allow from all + </Directory> + + <Location /admin> + Deny from all + </Location> + + <LocationMatch ^/([^/]+)/appadmin> + Deny from all + </LocationMatch> + + CustomLog /private/var/log/apache2/access.log common + ErrorLog /private/var/log/apache2/error.log +</VirtualHost> +---------------------------------- + +""" + +import os +import sys +import wsgiref.handlers + +path = os.path.dirname(os.path.abspath(__file__)) +os.chdir(path) + +if not os.path.isdir('applications'): + raise RuntimeError('Running from the wrong folder') + +sys.path = [path] + [p for p in sys.path if not p == path] + +import gluon.main + +wsgiref.handlers.CGIHandler().run(gluon.main.wsgibase) diff --git a/web2py/handlers/fcgihandler.py b/web2py/handlers/fcgihandler.py new file mode 100644 index 0000000..a9b047e --- /dev/null +++ b/web2py/handlers/fcgihandler.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +This file is part of the web2py Web Framework +Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu> +License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +This is a handler for lighttpd+fastcgi +This file has to be in the PYTHONPATH +Put something like this in the lighttpd.conf file: + +server.port = 8000 +server.bind = '127.0.0.1' +server.event-handler = 'freebsd-kqueue' +server.modules = ('mod_rewrite', 'mod_fastcgi') +server.error-handler-404 = '/test.fcgi' +server.document-root = '/somewhere/web2py' +server.errorlog = '/tmp/error.log' +fastcgi.server = ('.fcgi' => + ('localhost' => + ('min-procs' => 1, + 'socket' => '/tmp/fcgi.sock' + ) + ) + ) +""" + +LOGGING = False +SOFTCRON = False + +import sys +import os + +path = os.path.dirname(os.path.abspath(__file__)) +os.chdir(path) + +if not os.path.isdir('applications'): + raise RuntimeError('Running from the wrong folder') + +sys.path = [path] + [p for p in sys.path if not p == path] + +import gluon.main +import gluon.contrib.gateways.fcgi as fcgi + +if LOGGING: + application = gluon.main.appfactory(wsgiapp=gluon.main.wsgibase, + logfilename='httpserver.log', + profiler_dir=None) +else: + application = gluon.main.wsgibase + +if SOFTCRON: + from gluon.settings import global_settings + global_settings.web2py_crontype = 'soft' + +fcgi.WSGIServer(application, bindAddress='/tmp/fcgi.sock').run() diff --git a/web2py/handlers/gaehandler.py b/web2py/handlers/gaehandler.py new file mode 100644 index 0000000..08aa4e2 --- /dev/null +++ b/web2py/handlers/gaehandler.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +This file is part of the web2py Web Framework +Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu> +License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) +""" + +############################################################################## +# Configuration parameters for Google App Engine +############################################################################## +LOG_STATS = False # web2py level log statistics +APPSTATS = True # GAE level usage statistics and profiling +DEBUG = False # debug mode +# +# Read more about APPSTATS here +# http://googleappengine.blogspot.com/2010/03/easy-performance-profiling-with.html +# can be accessed from: +# http://localhost:8080/_ah/stats +############################################################################## +# All tricks in this file developed by Robin Bhattacharyya +############################################################################## + + +import time +import os +import sys +import logging +import cPickle +import pickle +import wsgiref.handlers +import datetime + +path = os.path.dirname(os.path.abspath(__file__)) + +# os.chdir(path) ? + +if not os.path.isdir('applications'): + raise RuntimeError('Running from the wrong folder') + +sys.path = [path] + [p for p in sys.path if not p == path] + +sys.modules['cPickle'] = sys.modules['pickle'] + + +from gluon.settings import global_settings +from google.appengine.ext import webapp +from google.appengine.ext.webapp.util import run_wsgi_app + + +global_settings.web2py_runtime_gae = True +global_settings.db_sessions = True +if os.environ.get('SERVER_SOFTWARE', '').startswith('Devel'): + (global_settings.web2py_runtime, DEBUG) = \ + ('gae:development', True) +else: + (global_settings.web2py_runtime, DEBUG) = \ + ('gae:production', False) + + +import gluon.main + + +def log_stats(fun): + """Function that will act as a decorator to make logging""" + def newfun(env, res): + """Log the execution time of the passed function""" + timer = lambda t: (t.time(), t.clock()) + (t0, c0) = timer(time) + executed_function = fun(env, res) + (t1, c1) = timer(time) + log_info = """**** Request: %.2fms/%.2fms (real time/cpu time)""" + log_info = log_info % ((t1 - t0) * 1000, (c1 - c0) * 1000) + logging.info(log_info) + return executed_function + return newfun + + +logging.basicConfig(level=logging.INFO) + + +def wsgiapp(env, res): + """Return the wsgiapp""" + env['PATH_INFO'] = env['PATH_INFO'].decode('latin1').encode('utf8') + + #when using the blobstore image uploader GAE dev SDK passes these as unicode + # they should be regular strings as they are parts of URLs + env['wsgi.url_scheme'] = str(env['wsgi.url_scheme']) + env['QUERY_STRING'] = str(env['QUERY_STRING']) + env['SERVER_NAME'] = str(env['SERVER_NAME']) + + #this deals with a problem where GAE development server seems to forget + # the path between requests + if global_settings.web2py_runtime == 'gae:development': + gluon.admin.create_missing_folders() + + web2py_path = global_settings.applications_parent # backward compatibility + + return gluon.main.wsgibase(env, res) + + +if LOG_STATS or DEBUG: + wsgiapp = log_stats(wsgiapp) + + +def main(): + """Run the wsgi app""" + run_wsgi_app(wsgiapp) + +if __name__ == '__main__': + main() diff --git a/web2py/handlers/isapiwsgihandler.py b/web2py/handlers/isapiwsgihandler.py new file mode 100644 index 0000000..0275515 --- /dev/null +++ b/web2py/handlers/isapiwsgihandler.py @@ -0,0 +1,39 @@ +""" +web2py handler for isapi-wsgi for IIS. Requires: +http://code.google.com/p/isapi-wsgi/ +""" +# The entry point for the ISAPI extension. + + +def __ExtensionFactory__(): + import os + import sys + path = os.path.dirname(os.path.abspath(__file__)) + os.chdir(path) + if not os.path.isdir('applications'): + raise RuntimeError('Running from the wrong folder') + sys.path = [path] + [p for p in sys.path if not p == path] + import gluon.main + import isapi_wsgi + application = gluon.main.wsgibase + return isapi_wsgi.ISAPIThreadPoolHandler(application) + +# ISAPI installation: +if __name__ == '__main__': + import sys + if len(sys.argv) < 2: + print "USAGE: python isapiwsgihandler.py install --server=Sitename" + sys.exit(0) + from isapi.install import ISAPIParameters + from isapi.install import ScriptMapParams + from isapi.install import VirtualDirParameters + from isapi.install import HandleCommandLine + + params = ISAPIParameters() + sm = [ScriptMapParams(Extension="*", Flags=0)] + vd = VirtualDirParameters(Name="appname", + Description="Web2py in Python", + ScriptMaps=sm, + ScriptMapUpdate="replace") + params.VirtualDirs = [vd] + HandleCommandLine(params) diff --git a/web2py/handlers/modpythonhandler.py b/web2py/handlers/modpythonhandler.py new file mode 100644 index 0000000..388f37e --- /dev/null +++ b/web2py/handlers/modpythonhandler.py @@ -0,0 +1,228 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +This file is part of the web2py Web Framework +Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu> +License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + +WSGI wrapper for mod_python. Requires Python 2.2 or greater. +Part of CherryPy mut modified by Massimo Di Pierro (2008) for web2py + +<Location /myapp> + SetHandler python-program + PythonHandler modpythonhandler + PythonPath \"['/path/to/web2py/'] + sys.path\" + PythonOption SCRIPT_NAME /myapp +</Location> + +Some WSGI implementations assume that the SCRIPT_NAME environ variable will +always be equal to 'the root URL of the app'; Apache probably won't act as +you expect in that case. You can add another PythonOption directive to tell +modpython_gateway to force that behavior: + + PythonOption SCRIPT_NAME /mcontrol + +The module.function will be called with no arguments on server shutdown, +once for each child process or thread. +""" + +import traceback +import sys +import os +from mod_python import apache + +path = os.path.dirname(os.path.abspath(__file__)) +os.chdir(path) + +if not os.path.isdir('applications'): + raise RuntimeError('Running from the wrong folder') + +sys.path = [path] + [p for p in sys.path if not p == path] + +import gluon.main + + +class InputWrapper(object): + """ Input wrapper for the wsgi handler """ + + def __init__(self, req): + """ InputWrapper constructor """ + + self.req = req + + def close(self): + """ """ + + pass + + def read(self, size=-1): + """ Wrapper for req.read """ + + return self.req.read(size) + + def readline(self, size=-1): + """ Wrapper for req.readline """ + + return self.req.readline(size) + + def readlines(self, hint=-1): + """ Wrapper for req.readlines """ + + return self.req.readlines(hint) + + def __iter__(self): + """ Defines a generator with the req data """ + + line = self.readline() + while line: + yield line + + # Notice this won't prefetch the next line; it only + # gets called if the generator is resumed. + line = self.readline() + + +class ErrorWrapper(object): + """ Error wrapper for the wsgi handler """ + + def __init__(self, req): + """ ErrorWrapper constructor """ + + self.req = req + + def flush(self): + """ """ + + pass + + def write(self, msg): + """ Logs the given msg in the log file """ + + self.req.log_error(msg) + + def writelines(self, seq): + """ Writes various lines in the log file """ + + self.write(''.join(seq)) + + +bad_value = "You must provide a PythonOption '%s', either 'on' or 'off', when running a version of mod_python < 3.1" + + +class Handler: + """ Defines the handler """ + + def __init__(self, req): + """ Handler constructor """ + + self.started = False + options = req.get_options() + + # Threading and forking + try: + q = apache.mpm_query + threaded = q(apache.AP_MPMQ_IS_THREADED) + forked = q(apache.AP_MPMQ_IS_FORKED) + except AttributeError: + threaded = options.get('multithread', '').lower() + + if threaded == 'on': + threaded = True + elif threaded == 'off': + threaded = False + else: + raise ValueError(bad_value % 'multithread') + + forked = options.get('multiprocess', '').lower() + + if forked == 'on': + forked = True + elif forked == 'off': + forked = False + else: + raise ValueError(bad_value % 'multiprocess') + + env = self.environ = dict(apache.build_cgi_env(req)) + + if 'SCRIPT_NAME' in options: + # Override SCRIPT_NAME and PATH_INFO if requested. + env['SCRIPT_NAME'] = options['SCRIPT_NAME'] + env['PATH_INFO'] = req.uri[len(options['SCRIPT_NAME']):] + + env['wsgi.input'] = InputWrapper(req) + env['wsgi.errors'] = ErrorWrapper(req) + env['wsgi.version'] = (1, 0) + env['wsgi.run_once'] = False + + if env.get('HTTPS') in ('yes', 'on', '1'): + env['wsgi.url_scheme'] = 'https' + else: + env['wsgi.url_scheme'] = 'http' + + env['wsgi.multithread'] = threaded + env['wsgi.multiprocess'] = forked + + self.request = req + + def run(self, application): + """ Run the application """ + + try: + result = application(self.environ, self.start_response) + + for data in result: + self.write(data) + + if not self.started: + self.request.set_content_length(0) + + if hasattr(result, 'close'): + result.close() + except: + traceback.print_exc(None, self.environ['wsgi.errors']) + + if not self.started: + self.request.status = 500 + self.request.content_type = 'text/plain' + data = 'A server error occurred. Please contact the ' + \ + 'administrator.' + self.request.set_content_length(len(data)) + self.request.write(data) + + def start_response(self, status, headers, exc_info=None): + """ Defines the request data """ + + if exc_info: + try: + if self.started: + raise exc_info[0], exc_info[1], exc_info[2] + finally: + exc_info = None + + self.request.status = int(status[:3]) + + for (key, val) in headers: + if key.lower() == 'content-length': + self.request.set_content_length(int(val)) + elif key.lower() == 'content-type': + self.request.content_type = val + else: + self.request.headers_out.add(key, val) + + return self.write + + def write(self, data): + """ Write the request data """ + + if not self.started: + self.started = True + + self.request.write(data) + + +def handler(req): + """ Execute the gluon app """ + + Handler(req).run(gluon.main.wsgibase) + return apache.OK diff --git a/web2py/handlers/scgihandler.py b/web2py/handlers/scgihandler.py new file mode 100644 index 0000000..90b81fc --- /dev/null +++ b/web2py/handlers/scgihandler.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +scgihandler.py - handler for SCGI protocol + +Modified by Michele Comitini <michele.comitini@glisco.it> +from fcgihandler.py to support SCGI + +fcgihandler has the following copyright: +" This file is part of the web2py Web Framework + Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu> + License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) +" + +This is a handler for lighttpd+scgi +This file has to be in the PYTHONPATH +Put something like this in the lighttpd.conf file: + +server.document-root="/var/www/web2py/" +# for >= linux-2.6 +server.event-handler = "linux-sysepoll" + +url.rewrite-once = ( + "^(/.+?/static/.+)$" => "/applications$1", + "(^|/.*)$" => "/handler_web2py.scgi$1", +) +scgi.server = ( "/handler_web2py.scgi" => + ("handler_web2py" => + ( "host" => "127.0.0.1", + "port" => "4000", + "check-local" => "disable", # don't forget to set "disable"! + ) + ) +) + + + + +""" + +LOGGING = False +SOFTCRON = False + +import sys +import os + +path = os.path.dirname(os.path.abspath(__file__)) +os.chdir(path) + +if not os.path.isdir('applications'): + raise RuntimeError('Running from the wrong folder') + +sys.path = [path] + [p for p in sys.path if not p == path] + +import gluon.main + +# uncomment one of the two imports below depending on the SCGIWSGI server installed +#import paste.util.scgiserver as scgi +from wsgitools.scgi.forkpool import SCGIServer +from wsgitools.filters import WSGIFilterMiddleware, GzipWSGIFilter + +wsgiapp = WSGIFilterMiddleware(gluon.main.wsgibase, GzipWSGIFilter) + +if LOGGING: + application = gluon.main.appfactory(wsgiapp=wsgiapp, + logfilename='httpserver.log', + profiler_dir=None) +else: + application = wsgiapp + +if SOFTCRON: + from gluon.settings import global_settings + global_settings.web2py_crontype = 'soft' + +# uncomment one of the two rows below depending on the SCGIWSGI server installed +#scgi.serve_application(application, '', 4000).run() +SCGIServer(application, port=4000).enable_sighandler().run() diff --git a/web2py/handlers/web2py_on_gevent.py b/web2py/handlers/web2py_on_gevent.py new file mode 100644 index 0000000..40a0ff6 --- /dev/null +++ b/web2py/handlers/web2py_on_gevent.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys +import os +import optparse + +if hasattr(sys, 'frozen'): + path = os.path.dirname(os.path.abspath(sys.executable)) +elif '__file__' in globals(): + path = os.path.dirname(os.path.abspath(__file__)) +else: + path = os.getcwd() +os.chdir(path) + +sys.path = [path] + [p for p in sys.path if not p == path] + +from gevent import pywsgi +from gevent.pool import Pool +from gevent import monkey +monkey.patch_all() + +def run(options): + import gluon.main + if options.password != '<recycle>': + gluon.main.save_password(options.password, int(options.port)) + if options.logging: + application = gluon.main.appfactory(wsgiapp=gluon.main.wsgibase, + logfilename='httpserver.log', + profiler_dir=profiler) + else: + application = gluon.main.wsgibase + address = (options.ip, int(options.port)) + workers = options.workers + spawn = workers and Pool(int(options.workers)) or 'default' + ssl_args = dict() + if options.ssl_private_key: + ssl_args['keyfile'] = options.ssl_private_key + if options.ssl_certificate: + ssl_args['certfile'] = options.ssl_certificate + server = pywsgi.WSGIServer( + address, application, + spawn=spawn, log=None, + **ssl_args + ) + server.serve_forever() + +def main(): + usage = 'python web2py_gevent.py -i 127.0.0.1 -p 8000 -a "<recycle>"' + try: + version = open('VERSION','r') + except IOError: + version = '' + parser = optparse.OptionParser(usage, None, optparse.Option, version) + msg = ('password to be used for administration ' + '(use -a "<recycle>" to reuse the last password))') + parser.add_option('-a', + '--password', + default='<recycle>', + dest='password', + help=msg) + + parser.add_option('-c', + '--ssl_certificate', + default='', + dest='ssl_certificate', + help='file that contains ssl certificate') + + parser.add_option('-k', + '--ssl_private_key', + default='', + dest='ssl_private_key', + help='file that contains ssl private key') + + parser.add_option('-l', + '--logging', + action='store_true', + default=False, + dest='logging', + help='log into httpserver.log') + + parser.add_option('-F', + '--profiler', + dest='profiler_dir', + default=None, + help='profiler dir') + + parser.add_option('-i', + '--ip', + default='127.0.0.1', + dest='ip', + help='ip address') + + parser.add_option('-p', + '--port', + default='8000', + dest='port', + help='port number') + + parser.add_option('-w', + '--workers', + default=None, + dest='workers', + help='number of workers') + + (options, args) = parser.parse_args() + print 'starting on %s:%s...' % ( + options.ip, options.port) + run(options) + +if __name__ == '__main__': + main() diff --git a/web2py/handlers/wsgihandler.py b/web2py/handlers/wsgihandler.py new file mode 100644 index 0000000..e4f19c9 --- /dev/null +++ b/web2py/handlers/wsgihandler.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +This file is part of the web2py Web Framework +Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu> +License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) + + +This is a WSGI handler +""" + +import sys +import os + +# change these parameters as required +LOGGING = False +SOFTCRON = False + + +path = os.path.dirname(os.path.abspath(__file__)) +os.chdir(path) + +if not os.path.isdir('applications'): + raise RuntimeError('Running from the wrong folder') + +sys.path = [path] + [p for p in sys.path if not p == path] + +import gluon.main + +if LOGGING: + application = gluon.main.appfactory(wsgiapp=gluon.main.wsgibase, + logfilename='httpserver.log', + profiler_dir=None) +else: + application = gluon.main.wsgibase + +if SOFTCRON: + from gluon.settings import global_settings + global_settings.web2py_crontype = 'soft' diff --git a/web2py/httpserver.log b/web2py/httpserver.log new file mode 100644 index 0000000..a68a6dd --- /dev/null +++ b/web2py/httpserver.log @@ -0,0 +1,4173 @@ +127.0.0.1, 2018-09-22 18:02:56, GET, /, HTTP/1.1, 303, 0.003825 +127.0.0.1, 2018-09-22 18:02:56, GET, /welcome/default/index, HTTP/1.1, 200, 0.366652 +127.0.0.1, 2018-09-22 18:02:56, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 200, 0.001185 +127.0.0.1, 2018-09-22 18:02:56, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 200, 0.003030 +127.0.0.1, 2018-09-22 18:02:56, GET, /welcome/static/js/calendar.js, HTTP/1.1, 200, 0.005241 +127.0.0.1, 2018-09-22 18:02:56, GET, /welcome/static/js/jquery.js, HTTP/1.1, 200, 0.007971 +127.0.0.1, 2018-09-22 18:02:56, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 200, 0.003160 +127.0.0.1, 2018-09-22 18:02:56, GET, /welcome/static/css/calendar.css, HTTP/1.1, 200, 0.007918 +127.0.0.1, 2018-09-22 18:02:56, GET, /welcome/static/js/web2py.js, HTTP/1.1, 200, 0.001540 +127.0.0.1, 2018-09-22 18:02:56, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 200, 0.004104 +127.0.0.1, 2018-09-22 18:02:56, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 200, 0.002462 +127.0.0.1, 2018-09-22 18:02:58, GET, /welcome/static/images/favicon.ico, HTTP/1.1, 200, 0.001007 +127.0.0.1, 2018-09-22 18:03:09, GET, /welcome/default/user/login, HTTP/1.1, 200, 0.029086 +127.0.0.1, 2018-09-22 18:03:12, GET, /welcome/default/user/register, HTTP/1.1, 200, 0.037997 +127.0.0.1, 2018-09-22 18:03:17, GET, /admin/default/index, HTTP/1.1, 200, 0.212188 +127.0.0.1, 2018-09-22 18:03:17, GET, /admin/static/_2.17.1/js/jquery.js, HTTP/1.1, 200, 0.004015 +127.0.0.1, 2018-09-22 18:03:17, GET, /admin/static/_2.17.1/plugin_multiselect/multi-select.css, HTTP/1.1, 200, 0.001310 +127.0.0.1, 2018-09-22 18:03:17, GET, /admin/static/_2.17.1/js/web2py.js, HTTP/1.1, 200, 0.002974 +127.0.0.1, 2018-09-22 18:03:17, GET, /admin/static/_2.17.1/plugin_multiselect/jquery.multi-select.js, HTTP/1.1, 200, 0.003148 +127.0.0.1, 2018-09-22 18:03:17, GET, /admin/static/_2.17.1/js/calendar.js, HTTP/1.1, 200, 0.004545 +127.0.0.1, 2018-09-22 18:03:17, GET, /admin/static/_2.17.1/css/calendar.css, HTTP/1.1, 200, 0.015345 +127.0.0.1, 2018-09-22 18:03:17, GET, /admin/static/_2.17.1/plugin_multiselect/start.js, HTTP/1.1, 200, 0.001397 +127.0.0.1, 2018-09-22 18:03:17, GET, /admin/static/_2.17.1/css/bootstrap.min.css, HTTP/1.1, 200, 0.003989 +127.0.0.1, 2018-09-22 18:03:17, GET, /admin/static/_2.17.1/plugin_statebutton/js/bootstrap-switch.js, HTTP/1.1, 200, 0.002128 +127.0.0.1, 2018-09-22 18:03:17, GET, /admin/static/_2.17.1/plugin_statebutton/css/bootstrap-switch.css, HTTP/1.1, 200, 0.005410 +127.0.0.1, 2018-09-22 18:03:17, GET, /admin/static/_2.17.1/js/bootstrap.min.js, HTTP/1.1, 200, 0.005022 +127.0.0.1, 2018-09-22 18:03:17, GET, /admin/static/_2.17.1/css/bootstrap_essentials.css, HTTP/1.1, 200, 0.004219 +127.0.0.1, 2018-09-22 18:03:17, GET, /admin/static/_2.17.1/css/bootstrap-responsive.min.css, HTTP/1.1, 200, 0.005101 +127.0.0.1, 2018-09-22 18:03:17, GET, /admin/static/_2.17.1/images/questions.png, HTTP/1.1, 200, 0.002903 +127.0.0.1, 2018-09-22 18:03:17, GET, /favicon.ico, HTTP/1.1, 400, 0.000339 +127.0.0.1, 2018-09-22 18:03:22, POST, /admin/default/index, HTTP/1.1, 303, 0.050017 +127.0.0.1, 2018-09-22 18:03:22, GET, /admin/default/site, HTTP/1.1, 200, 0.052096 +127.0.0.1, 2018-09-22 18:03:22, GET, /admin/static/_2.17.1/images/folder_locked.png, HTTP/1.1, 200, 0.002918 +127.0.0.1, 2018-09-22 18:03:22, GET, /admin/static/_2.17.1/images/folder.png, HTTP/1.1, 200, 0.005873 +127.0.0.1, 2018-09-22 18:03:22, GET, /admin/static/_2.17.1/images/glyphicons-halflings-white.png, HTTP/1.1, 200, 0.000807 +127.0.0.1, 2018-09-22 18:03:23, POST, /admin/default/check_version, HTTP/1.1, 200, 0.820258 +127.0.0.1, 2018-09-22 18:03:24, GET, /favicon.ico, HTTP/1.1, 400, 0.000204 +127.0.0.1, 2018-09-22 18:03:36, GET, /admin/default/site, HTTP/1.1, 200, 0.023485 +127.0.0.1, 2018-09-22 18:07:36, GET, /, HTTP/1.1, 303, 0.000403 +127.0.0.1, 2018-09-22 18:07:36, GET, /welcome/default/index, HTTP/1.1, 200, 0.024094 +127.0.0.1, 2018-09-22 18:07:36, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 200, 0.001873 +127.0.0.1, 2018-09-22 18:07:36, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 200, 0.001230 +127.0.0.1, 2018-09-22 18:07:36, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 200, 0.002413 +127.0.0.1, 2018-09-22 18:07:36, GET, /welcome/static/js/web2py.js, HTTP/1.1, 200, 0.004429 +127.0.0.1, 2018-09-22 18:07:36, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 200, 0.004508 +127.0.0.1, 2018-09-22 18:07:36, GET, /welcome/static/css/calendar.css, HTTP/1.1, 200, 0.003237 +127.0.0.1, 2018-09-22 18:07:36, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 200, 0.001938 +127.0.0.1, 2018-09-22 18:07:36, GET, /welcome/static/js/jquery.js, HTTP/1.1, 200, 0.002800 +127.0.0.1, 2018-09-22 18:07:36, GET, /welcome/static/js/calendar.js, HTTP/1.1, 200, 0.002722 +127.0.0.1, 2018-09-22 18:07:37, GET, /welcome/static/images/favicon.ico, HTTP/1.1, 200, 0.000821 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/default/edit/welcome/controllers/default.py, HTTP/1.1, 303, 0.004379 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/default/index, HTTP/1.1, 200, 0.013399 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/static/_2.17.1/js/jquery.js, HTTP/1.1, 200, 0.001191 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/static/_2.17.1/plugin_multiselect/start.js, HTTP/1.1, 200, 0.002912 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/static/_2.17.1/js/calendar.js, HTTP/1.1, 200, 0.003405 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/static/_2.17.1/plugin_multiselect/multi-select.css, HTTP/1.1, 200, 0.003643 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/static/_2.17.1/plugin_multiselect/jquery.multi-select.js, HTTP/1.1, 200, 0.005150 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/static/_2.17.1/css/calendar.css, HTTP/1.1, 200, 0.006851 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/static/_2.17.1/js/web2py.js, HTTP/1.1, 200, 0.005400 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/static/_2.17.1/plugin_statebutton/js/bootstrap-switch.js, HTTP/1.1, 200, 0.003081 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/static/_2.17.1/css/bootstrap.min.css, HTTP/1.1, 200, 0.005253 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/static/_2.17.1/plugin_statebutton/css/bootstrap-switch.css, HTTP/1.1, 200, 0.009513 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/static/_2.17.1/js/bootstrap.min.js, HTTP/1.1, 200, 0.003438 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/static/_2.17.1/css/bootstrap-responsive.min.css, HTTP/1.1, 200, 0.002983 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/static/_2.17.1/css/bootstrap_essentials.css, HTTP/1.1, 200, 0.008600 +127.0.0.1, 2018-09-22 18:07:48, GET, /admin/static/_2.17.1/images/questions.png, HTTP/1.1, 200, 0.006939 +127.0.0.1, 2018-09-22 18:07:49, GET, /favicon.ico, HTTP/1.1, 400, 0.000307 +127.0.0.1, 2018-09-22 18:08:21, GET, /, HTTP/1.1, 303, 0.000575 +127.0.0.1, 2018-09-22 18:08:21, GET, /welcome/default/index, HTTP/1.1, 200, 0.021954 +127.0.0.1, 2018-09-22 18:08:22, GET, /, HTTP/1.1, 303, 0.000492 +127.0.0.1, 2018-09-22 18:08:22, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.001247 +127.0.0.1, 2018-09-22 18:08:22, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.000763 +127.0.0.1, 2018-09-22 18:08:22, GET, /welcome/static/js/calendar.js, HTTP/1.1, 304, 0.001501 +127.0.0.1, 2018-09-22 18:08:22, GET, /welcome/static/js/jquery.js, HTTP/1.1, 304, 0.002119 +127.0.0.1, 2018-09-22 18:08:22, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.001575 +127.0.0.1, 2018-09-22 18:08:22, GET, /welcome/static/css/calendar.css, HTTP/1.1, 304, 0.003468 +127.0.0.1, 2018-09-22 18:08:22, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.002963 +127.0.0.1, 2018-09-22 18:08:22, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.003050 +127.0.0.1, 2018-09-22 18:08:22, GET, /welcome/static/js/web2py.js, HTTP/1.1, 304, 0.001708 +127.0.0.1, 2018-09-22 18:08:22, GET, /welcome/default/index, HTTP/1.1, 200, 0.018876 +127.0.0.1, 2018-09-22 18:08:29, GET, /welcome/default/user/login, HTTP/1.1, 200, 0.025064 +127.0.0.1, 2018-09-22 18:08:49, GET, /admin/default/site, HTTP/1.1, 303, 0.003787 +127.0.0.1, 2018-09-22 18:08:49, GET, /admin/default/index, HTTP/1.1, 200, 0.012649 +127.0.0.1, 2018-09-22 18:08:49, GET, /favicon.ico, HTTP/1.1, 400, 0.000323 +127.0.0.1, 2018-09-22 18:08:54, GET, /welcome/default/index, HTTP/1.1, 200, 0.019057 +127.0.0.1, 2018-09-22 18:10:36, GET, /welcome/static/images/favicon.ico, HTTP/1.1, 304, 0.000621 +127.0.0.1, 2018-09-22 18:10:36, GET, /welcome/default/user/login, HTTP/1.1, 200, 0.021375 +127.0.0.1, 2018-09-22 18:10:36, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.001107 +127.0.0.1, 2018-09-22 18:10:36, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.002284 +127.0.0.1, 2018-09-22 18:10:36, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.001569 +127.0.0.1, 2018-09-22 18:10:36, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.002171 +127.0.0.1, 2018-09-22 18:10:36, GET, /welcome/static/js/calendar.js, HTTP/1.1, 304, 0.001308 +127.0.0.1, 2018-09-22 18:10:36, GET, /welcome/static/js/jquery.js, HTTP/1.1, 304, 0.002214 +127.0.0.1, 2018-09-22 18:10:36, GET, /welcome/static/css/calendar.css, HTTP/1.1, 304, 0.003825 +127.0.0.1, 2018-09-22 18:10:36, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.002387 +127.0.0.1, 2018-09-22 18:10:36, GET, /welcome/static/js/web2py.js, HTTP/1.1, 304, 0.002857 +127.0.0.1, 2018-09-22 18:10:39, GET, /welcome/default/index, HTTP/1.1, 200, 0.018224 +127.0.0.1, 2018-09-22 18:10:42, GET, /admin/default/index, HTTP/1.1, 200, 0.009793 +127.0.0.1, 2018-09-22 18:10:42, GET, /favicon.ico, HTTP/1.1, 400, 0.000217 +127.0.0.1, 2018-09-22 18:10:48, POST, /admin/default/index, HTTP/1.1, 303, 0.011903 +127.0.0.1, 2018-09-22 18:10:48, GET, /admin/default/site, HTTP/1.1, 200, 0.025459 +127.0.0.1, 2018-09-22 18:10:48, GET, /admin/static/_2.17.1/images/folder_locked.png, HTTP/1.1, 200, 0.001770 +127.0.0.1, 2018-09-22 18:10:48, GET, /admin/static/_2.17.1/images/folder.png, HTTP/1.1, 200, 0.002788 +127.0.0.1, 2018-09-22 18:10:48, GET, /admin/static/_2.17.1/images/glyphicons-halflings-white.png, HTTP/1.1, 200, 0.000903 +127.0.0.1, 2018-09-22 18:10:49, POST, /admin/default/check_version, HTTP/1.1, 200, 0.723988 +127.0.0.1, 2018-09-22 18:10:52, GET, /favicon.ico, HTTP/1.1, 400, 0.000325 +127.0.0.1, 2018-09-22 18:10:57, POST, /admin/default/enable/welcome, HTTP/1.1, 500, 0.180925 +127.0.0.1, 2018-09-22 18:11:06, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.190971 +127.0.0.1, 2018-09-22 18:11:06, GET, /admin/static/_2.17.1/images/search.png, HTTP/1.1, 200, 0.001331 +127.0.0.1, 2018-09-22 18:11:06, GET, /admin/static/_2.17.1/images/help.png, HTTP/1.1, 200, 0.001915 +127.0.0.1, 2018-09-22 18:11:06, GET, /admin/static/_2.17.1/images/test_icon.png, HTTP/1.1, 200, 0.001221 +127.0.0.1, 2018-09-22 18:11:06, GET, /admin/static/_2.17.1/images/delete_icon.png, HTTP/1.1, 200, 0.001349 +127.0.0.1, 2018-09-22 18:11:06, GET, /favicon.ico, HTTP/1.1, 400, 0.000232 +127.0.0.1, 2018-09-22 18:11:35, GET, /admin/default/peek/SP/models/db.py, HTTP/1.1, 200, 0.046208 +127.0.0.1, 2018-09-22 18:11:35, GET, /favicon.ico, HTTP/1.1, 400, 0.000419 +127.0.0.1, 2018-09-22 18:12:31, GET, /admin/default/peek/SP/models/menu.py, HTTP/1.1, 200, 0.026613 +127.0.0.1, 2018-09-22 18:12:31, GET, /favicon.ico, HTTP/1.1, 400, 0.000482 +127.0.0.1, 2018-09-22 18:12:41, GET, /admin/default/site, HTTP/1.1, 200, 0.026757 +127.0.0.1, 2018-09-22 18:12:47, POST, /admin/default/enable/examples, HTTP/1.1, 500, 0.031989 +127.0.0.1, 2018-09-22 18:12:51, GET, /admin/default/site, HTTP/1.1, 200, 0.027553 +127.0.0.1, 2018-09-22 18:13:12, GET, /SP/default/site, HTTP/1.1, 404, 0.036637 +127.0.0.1, 2018-09-22 18:13:12, GET, /favicon.ico, HTTP/1.1, 400, 0.000345 +127.0.0.1, 2018-09-22 18:13:15, GET, /SP/default/site, HTTP/1.1, 404, 0.018562 +127.0.0.1, 2018-09-22 18:13:17, GET, /SP/, HTTP/1.1, 200, 0.080251 +127.0.0.1, 2018-09-22 18:13:17, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 200, 0.000815 +127.0.0.1, 2018-09-22 18:13:17, GET, /SP/static/js/web2py.js, HTTP/1.1, 200, 0.001652 +127.0.0.1, 2018-09-22 18:13:17, GET, /SP/static/js/calendar.js, HTTP/1.1, 200, 0.002099 +127.0.0.1, 2018-09-22 18:13:17, GET, /SP/static/js/jquery.js, HTTP/1.1, 200, 0.003134 +127.0.0.1, 2018-09-22 18:13:17, GET, /SP/static/css/calendar.css, HTTP/1.1, 200, 0.008434 +127.0.0.1, 2018-09-22 18:13:17, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 200, 0.008843 +127.0.0.1, 2018-09-22 18:13:17, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 200, 0.006183 +127.0.0.1, 2018-09-22 18:13:17, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 200, 0.008971 +127.0.0.1, 2018-09-22 18:13:17, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 200, 0.004761 +127.0.0.1, 2018-09-22 18:13:17, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000574 +127.0.0.1, 2018-09-22 18:14:28, GET, /SP/default/user/login, HTTP/1.1, 200, 0.029507 +127.0.0.1, 2018-09-22 18:14:50, GET, /SP/default/index, HTTP/1.1, 200, 0.025147 +127.0.0.1, 2018-09-22 18:14:50, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.003661 +127.0.0.1, 2018-09-22 18:14:50, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.000437 +127.0.0.1, 2018-09-22 18:14:50, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.002261 +127.0.0.1, 2018-09-22 18:14:50, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.000529 +127.0.0.1, 2018-09-22 18:14:50, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.002263 +127.0.0.1, 2018-09-22 18:14:50, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.002716 +127.0.0.1, 2018-09-22 18:14:50, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.007914 +127.0.0.1, 2018-09-22 18:14:50, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.005871 +127.0.0.1, 2018-09-22 18:14:50, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.002154 +127.0.0.1, 2018-09-22 18:14:50, GET, /SP/static/images/favicon.ico, HTTP/1.1, 304, 0.000428 +127.0.0.1, 2018-09-22 18:15:40, GET, /SP/default/user/login, HTTP/1.1, 200, 0.021677 +127.0.0.1, 2018-09-22 18:15:42, GET, /admin/default/site, HTTP/1.1, 200, 0.030317 +127.0.0.1, 2018-09-22 18:15:45, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.084304 +127.0.0.1, 2018-09-22 18:16:16, GET, /, HTTP/1.1, 303, 0.000313 +127.0.0.1, 2018-09-22 18:16:16, GET, /welcome/static/js/web2py.js, HTTP/1.1, 304, 0.000551 +127.0.0.1, 2018-09-22 18:16:16, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.001663 +127.0.0.1, 2018-09-22 18:16:16, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.001587 +127.0.0.1, 2018-09-22 18:16:16, GET, /welcome/static/js/jquery.js, HTTP/1.1, 304, 0.001697 +127.0.0.1, 2018-09-22 18:16:16, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.000450 +127.0.0.1, 2018-09-22 18:16:16, GET, /welcome/static/css/calendar.css, HTTP/1.1, 304, 0.001969 +127.0.0.1, 2018-09-22 18:16:16, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.000779 +127.0.0.1, 2018-09-22 18:16:16, GET, /welcome/static/js/calendar.js, HTTP/1.1, 304, 0.002686 +127.0.0.1, 2018-09-22 18:16:16, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.003847 +127.0.0.1, 2018-09-22 18:16:16, GET, /welcome/default/index, HTTP/1.1, 200, 0.027583 +127.0.0.1, 2018-09-22 18:16:21, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.001436 +127.0.0.1, 2018-09-22 18:16:21, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.002019 +127.0.0.1, 2018-09-22 18:16:21, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.001362 +127.0.0.1, 2018-09-22 18:16:21, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.001983 +127.0.0.1, 2018-09-22 18:16:21, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.003880 +127.0.0.1, 2018-09-22 18:16:21, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.005077 +127.0.0.1, 2018-09-22 18:16:21, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.002098 +127.0.0.1, 2018-09-22 18:16:21, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.004582 +127.0.0.1, 2018-09-22 18:16:21, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.001250 +127.0.0.1, 2018-09-22 18:16:21, GET, /SP/static/images/favicon.ico, HTTP/1.1, 304, 0.004960 +127.0.0.1, 2018-09-22 18:16:21, GET, /SP/, HTTP/1.1, 200, 0.041882 +127.0.0.1, 2018-09-22 18:16:21, GET, /SP, HTTP/1.1, 200, 0.022072 +127.0.0.1, 2018-09-22 18:16:28, GET, /admin/default/peek/SP/models/menu.py, HTTP/1.1, 200, 0.021377 +127.0.0.1, 2018-09-22 18:17:42, GET, /SP, HTTP/1.1, 200, 0.017735 +127.0.0.1, 2018-09-22 18:17:43, GET, /SP, HTTP/1.1, 200, 0.018637 +127.0.0.1, 2018-09-22 18:19:16, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.002342 +127.0.0.1, 2018-09-22 18:19:16, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.000595 +127.0.0.1, 2018-09-22 18:19:16, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.004693 +127.0.0.1, 2018-09-22 18:19:16, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.004053 +127.0.0.1, 2018-09-22 18:19:16, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.004098 +127.0.0.1, 2018-09-22 18:19:16, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.002382 +127.0.0.1, 2018-09-22 18:19:16, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.004891 +127.0.0.1, 2018-09-22 18:19:16, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.004374 +127.0.0.1, 2018-09-22 18:19:16, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.000871 +127.0.0.1, 2018-09-22 18:19:16, GET, /SP, HTTP/1.1, 500, 0.059589 +127.0.0.1, 2018-09-22 18:19:16, GET, /favicon.ico, HTTP/1.1, 400, 0.000279 +127.0.0.1, 2018-09-22 18:19:20, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-22.18-19-16.eb57736d-d461-4d86-8577-c7454f82f56b, HTTP/1.1, 200, 0.084007 +127.0.0.1, 2018-09-22 18:19:20, GET, /favicon.ico, HTTP/1.1, 400, 0.000542 +127.0.0.1, 2018-09-22 18:19:41, GET, /SP, HTTP/1.1, 200, 0.026587 +127.0.0.1, 2018-09-22 18:19:41, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.002446 +127.0.0.1, 2018-09-22 18:19:41, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.000728 +127.0.0.1, 2018-09-22 18:19:41, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.001720 +127.0.0.1, 2018-09-22 18:19:41, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.001696 +127.0.0.1, 2018-09-22 18:19:41, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.004695 +127.0.0.1, 2018-09-22 18:19:41, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.003036 +127.0.0.1, 2018-09-22 18:19:41, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.005918 +127.0.0.1, 2018-09-22 18:19:41, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.002783 +127.0.0.1, 2018-09-22 18:19:41, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.003141 +127.0.0.1, 2018-09-22 18:19:42, GET, /SP/private/home, HTTP/1.1, 404, 0.012360 +127.0.0.1, 2018-09-22 18:19:42, GET, /favicon.ico, HTTP/1.1, 400, 0.000209 +127.0.0.1, 2018-09-22 18:21:16, GET, /SP, HTTP/1.1, 200, 0.057618 +127.0.0.1, 2018-09-22 18:21:36, GET, /admin/default/site, HTTP/1.1, 200, 0.032948 +127.0.0.1, 2018-09-22 18:21:39, GET, /SP/default/index, HTTP/1.1, 200, 0.017860 +127.0.0.1, 2018-09-22 18:21:39, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.000796 +127.0.0.1, 2018-09-22 18:21:39, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.000743 +127.0.0.1, 2018-09-22 18:21:39, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.000511 +127.0.0.1, 2018-09-22 18:21:39, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.003208 +127.0.0.1, 2018-09-22 18:21:39, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.004556 +127.0.0.1, 2018-09-22 18:21:39, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.003646 +127.0.0.1, 2018-09-22 18:21:39, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.002139 +127.0.0.1, 2018-09-22 18:21:39, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.005274 +127.0.0.1, 2018-09-22 18:21:39, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.009508 +127.0.0.1, 2018-09-22 18:22:02, GET, /SP/default/index, HTTP/1.1, 200, 0.017332 +127.0.0.1, 2018-09-22 18:22:55, GET, /SP/default/index, HTTP/1.1, 200, 0.016736 +127.0.0.1, 2018-09-22 18:23:49, GET, /SP/default/index, HTTP/1.1, 200, 0.016416 +127.0.0.1, 2018-09-22 18:23:49, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.002405 +127.0.0.1, 2018-09-22 18:23:49, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.001060 +127.0.0.1, 2018-09-22 18:23:49, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.002783 +127.0.0.1, 2018-09-22 18:23:49, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.002022 +127.0.0.1, 2018-09-22 18:23:49, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.001899 +127.0.0.1, 2018-09-22 18:23:49, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.002740 +127.0.0.1, 2018-09-22 18:23:49, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.002062 +127.0.0.1, 2018-09-22 18:23:49, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.002151 +127.0.0.1, 2018-09-22 18:23:49, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.002226 +127.0.0.1, 2018-09-22 18:24:24, GET, /SP/default/index, HTTP/1.1, 200, 0.018819 +127.0.0.1, 2018-09-22 18:24:24, GET, /, HTTP/1.1, 303, 0.000610 +127.0.0.1, 2018-09-22 18:24:24, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.001643 +127.0.0.1, 2018-09-22 18:24:24, GET, /welcome/static/js/web2py.js, HTTP/1.1, 304, 0.000794 +127.0.0.1, 2018-09-22 18:24:24, GET, /welcome/static/js/jquery.js, HTTP/1.1, 304, 0.001338 +127.0.0.1, 2018-09-22 18:24:25, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.002083 +127.0.0.1, 2018-09-22 18:24:25, GET, /welcome/static/css/calendar.css, HTTP/1.1, 304, 0.002552 +127.0.0.1, 2018-09-22 18:24:25, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.002048 +127.0.0.1, 2018-09-22 18:24:25, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.001761 +127.0.0.1, 2018-09-22 18:24:25, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.003338 +127.0.0.1, 2018-09-22 18:24:25, GET, /welcome/static/js/calendar.js, HTTP/1.1, 304, 0.002439 +127.0.0.1, 2018-09-22 18:24:25, GET, /welcome/default/index, HTTP/1.1, 200, 0.031667 +127.0.0.1, 2018-09-22 18:25:27, GET, /SP/default/index, HTTP/1.1, 200, 0.022289 +127.0.0.1, 2018-09-22 18:26:46, GET, /SP/default/index, HTTP/1.1, 200, 0.050211 +127.0.0.1, 2018-09-22 18:26:46, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.001650 +127.0.0.1, 2018-09-22 18:26:46, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.001485 +127.0.0.1, 2018-09-22 18:26:46, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.001285 +127.0.0.1, 2018-09-22 18:26:46, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.001857 +127.0.0.1, 2018-09-22 18:26:46, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.000733 +127.0.0.1, 2018-09-22 18:26:46, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.006345 +127.0.0.1, 2018-09-22 18:26:46, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.002868 +127.0.0.1, 2018-09-22 18:26:46, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.004820 +127.0.0.1, 2018-09-22 18:26:46, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.002829 +127.0.0.1, 2018-09-22 18:29:15, GET, /SP/default/index, HTTP/1.1, 200, 0.037530 +127.0.0.1, 2018-09-22 18:30:37, GET, /SP/private/home, HTTP/1.1, 404, 0.017784 +127.0.0.1, 2018-09-22 18:30:48, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.094893 +127.0.0.1, 2018-09-22 18:30:48, GET, /favicon.ico, HTTP/1.1, 400, 0.000245 +127.0.0.1, 2018-09-22 18:30:52, GET, /admin/default/peek/SP/controllers/default.py, HTTP/1.1, 200, 0.017544 +127.0.0.1, 2018-09-22 18:30:52, GET, /favicon.ico, HTTP/1.1, 400, 0.000392 +127.0.0.1, 2018-09-22 18:33:11, GET, /SP/default/user/login, HTTP/1.1, 200, 0.028060 +127.0.0.1, 2018-09-22 18:33:11, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.002503 +127.0.0.1, 2018-09-22 18:33:11, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.000913 +127.0.0.1, 2018-09-22 18:33:11, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.001753 +127.0.0.1, 2018-09-22 18:33:11, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.002817 +127.0.0.1, 2018-09-22 18:33:11, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.002144 +127.0.0.1, 2018-09-22 18:33:11, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.001289 +127.0.0.1, 2018-09-22 18:33:11, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.003290 +127.0.0.1, 2018-09-22 18:33:11, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.001875 +127.0.0.1, 2018-09-22 18:33:11, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.001797 +127.0.0.1, 2018-09-22 18:33:27, GET, /SP/default/user/login, HTTP/1.1, 200, 0.018910 +127.0.0.1, 2018-09-22 18:33:49, GET, /SP/default/index, HTTP/1.1, 200, 0.024790 +127.0.0.1, 2018-09-23 00:34:13, GET, /welcome/static/css/calendar.css, HTTP/1.1, 304, 0.002353 +127.0.0.1, 2018-09-23 00:34:13, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.001769 +127.0.0.1, 2018-09-23 00:34:13, GET, /welcome/static/js/jquery.js, HTTP/1.1, 304, 0.001631 +127.0.0.1, 2018-09-23 00:34:13, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.000984 +127.0.0.1, 2018-09-23 00:34:13, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.001848 +127.0.0.1, 2018-09-23 00:34:13, GET, /, HTTP/1.1, 303, 0.008642 +127.0.0.1, 2018-09-23 00:34:13, GET, /welcome/static/images/favicon.ico, HTTP/1.1, 304, 0.000538 +127.0.0.1, 2018-09-23 00:34:13, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.002734 +127.0.0.1, 2018-09-23 00:34:13, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.001223 +127.0.0.1, 2018-09-23 00:34:13, GET, /welcome/static/js/calendar.js, HTTP/1.1, 304, 0.001359 +127.0.0.1, 2018-09-23 00:34:13, GET, /welcome/static/js/web2py.js, HTTP/1.1, 304, 0.003315 +127.0.0.1, 2018-09-23 00:34:13, GET, /welcome/default/index, HTTP/1.1, 200, 0.168616 +127.0.0.1, 2018-09-23 00:34:17, GET, /admin/default/site, HTTP/1.1, 303, 0.157109 +127.0.0.1, 2018-09-23 00:34:17, GET, /admin/default/index, HTTP/1.1, 200, 0.042545 +127.0.0.1, 2018-09-23 00:34:17, GET, /favicon.ico, HTTP/1.1, 400, 0.000639 +127.0.0.1, 2018-09-23 00:34:23, GET, /, HTTP/1.1, 303, 0.001856 +127.0.0.1, 2018-09-23 00:34:23, GET, /welcome/default/index, HTTP/1.1, 200, 0.024265 +127.0.0.1, 2018-09-23 00:34:25, GET, /SP, HTTP/1.1, 200, 0.088748 +127.0.0.1, 2018-09-23 00:34:25, GET, /SP/static/js/calendar.js, HTTP/1.1, 200, 0.001408 +127.0.0.1, 2018-09-23 00:34:25, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 200, 0.002470 +127.0.0.1, 2018-09-23 00:34:25, GET, /SP/static/css/calendar.css, HTTP/1.1, 200, 0.002848 +127.0.0.1, 2018-09-23 00:34:25, GET, /SP/static/js/jquery.js, HTTP/1.1, 200, 0.004112 +127.0.0.1, 2018-09-23 00:34:25, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 200, 0.002172 +127.0.0.1, 2018-09-23 00:34:25, GET, /SP/static/js/web2py.js, HTTP/1.1, 200, 0.003935 +127.0.0.1, 2018-09-23 00:34:25, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 200, 0.009666 +127.0.0.1, 2018-09-23 00:34:25, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 200, 0.004026 +127.0.0.1, 2018-09-23 00:34:25, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 200, 0.005383 +127.0.0.1, 2018-09-23 00:34:25, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000695 +127.0.0.1, 2018-09-23 00:34:33, GET, /SP/default/user/login, HTTP/1.1, 200, 0.019816 +127.0.0.1, 2018-09-23 00:34:46, GET, /SP/default/index, HTTP/1.1, 200, 0.016887 +127.0.0.1, 2018-09-23 13:32:04, GET, /welcome/static/js/calendar.js, HTTP/1.1, 304, 0.001044 +127.0.0.1, 2018-09-23 13:32:04, GET, /welcome/static/css/calendar.css, HTTP/1.1, 304, 0.002263 +127.0.0.1, 2018-09-23 13:32:04, GET, /welcome/static/js/jquery.js, HTTP/1.1, 304, 0.001184 +127.0.0.1, 2018-09-23 13:32:04, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.001233 +127.0.0.1, 2018-09-23 13:32:04, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.002314 +127.0.0.1, 2018-09-23 13:32:04, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.001009 +127.0.0.1, 2018-09-23 13:32:04, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.000949 +127.0.0.1, 2018-09-23 13:32:04, GET, /welcome/static/js/web2py.js, HTTP/1.1, 304, 0.001072 +127.0.0.1, 2018-09-23 13:32:04, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.001198 +127.0.0.1, 2018-09-23 13:32:04, GET, /, HTTP/1.1, 303, 0.393041 +127.0.0.1, 2018-09-23 13:32:05, GET, /welcome/default/index, HTTP/1.1, 200, 0.185958 +127.0.0.1, 2018-09-23 13:32:12, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.001321 +127.0.0.1, 2018-09-23 13:32:12, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.001665 +127.0.0.1, 2018-09-23 13:32:12, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.001950 +127.0.0.1, 2018-09-23 13:32:12, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.002184 +127.0.0.1, 2018-09-23 13:32:12, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.001799 +127.0.0.1, 2018-09-23 13:32:12, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.001775 +127.0.0.1, 2018-09-23 13:32:12, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.001336 +127.0.0.1, 2018-09-23 13:32:12, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.001859 +127.0.0.1, 2018-09-23 13:32:12, GET, /SP/static/images/favicon.ico, HTTP/1.1, 304, 0.002556 +127.0.0.1, 2018-09-23 13:32:12, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.004676 +127.0.0.1, 2018-09-23 13:32:12, GET, /SP, HTTP/1.1, 200, 0.144200 +127.0.0.1, 2018-09-23 13:32:12, GET, /SP, HTTP/1.1, 200, 0.025263 +127.0.0.1, 2018-09-23 13:32:20, GET, /SP/default/user/login, HTTP/1.1, 200, 0.026060 +127.0.0.1, 2018-09-23 13:32:34, GET, /SP/default/user/login, HTTP/1.1, 200, 0.022057 +127.0.0.1, 2018-09-23 13:54:12, GET, /SP/default/user/login, HTTP/1.1, 500, 0.121632 +127.0.0.1, 2018-09-23 13:54:12, GET, /favicon.ico, HTTP/1.1, 400, 0.000504 +127.0.0.1, 2018-09-23 13:54:21, GET, /SP/default/user/login, HTTP/1.1, 500, 0.039235 +127.0.0.1, 2018-09-23 13:54:23, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.13-54-21.5c142673-7f02-4f59-becd-f8a8458197b8, HTTP/1.1, 303, 0.139088 +127.0.0.1, 2018-09-23 13:54:23, GET, /admin/default/index, HTTP/1.1, 200, 0.045829 +127.0.0.1, 2018-09-23 13:54:23, GET, /favicon.ico, HTTP/1.1, 400, 0.000298 +127.0.0.1, 2018-09-23 13:54:26, POST, /admin/default/index, HTTP/1.1, 303, 0.011891 +127.0.0.1, 2018-09-23 13:54:26, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.13-54-21.5c142673-7f02-4f59-becd-f8a8458197b8, HTTP/1.1, 200, 0.056187 +127.0.0.1, 2018-09-23 13:54:26, GET, /admin/static/_2.17.1/images/help.png, HTTP/1.1, 200, 0.000456 +127.0.0.1, 2018-09-23 13:54:26, GET, /favicon.ico, HTTP/1.1, 400, 0.000237 +127.0.0.1, 2018-09-23 13:55:20, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.13-54-21.5c142673-7f02-4f59-becd-f8a8458197b8, HTTP/1.1, 200, 0.027369 +127.0.0.1, 2018-09-23 13:55:32, GET, /SP, HTTP/1.1, 200, 0.043672 +127.0.0.1, 2018-09-23 13:55:32, GET, /SP, HTTP/1.1, 200, 0.052025 +127.0.0.1, 2018-09-23 13:55:35, GET, /SP/default/user/login, HTTP/1.1, 200, 0.023426 +127.0.0.1, 2018-09-23 13:56:06, GET, /SP/default/user/login, HTTP/1.1, 200, 0.020616 +127.0.0.1, 2018-09-23 13:59:27, GET, /SP/default/user/login, HTTP/1.1, 500, 0.037347 +127.0.0.1, 2018-09-23 13:59:28, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.13-59-27.f2e76b1c-d22b-469f-a693-39b6af0b0fcc, HTTP/1.1, 200, 0.034818 +127.0.0.1, 2018-09-23 13:59:28, GET, /favicon.ico, HTTP/1.1, 400, 0.000284 +127.0.0.1, 2018-09-23 14:00:10, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.13-59-27.f2e76b1c-d22b-469f-a693-39b6af0b0fcc, HTTP/1.1, 200, 0.024819 +127.0.0.1, 2018-09-23 14:00:18, GET, /SP/default/user/login, HTTP/1.1, 200, 0.025872 +127.0.0.1, 2018-09-23 14:01:43, GET, /SP/default/user/login, HTTP/1.1, 500, 0.024308 +127.0.0.1, 2018-09-23 14:01:45, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.14-01-43.8f7a6d8f-112e-49d0-b426-5391c93f8986, HTTP/1.1, 200, 0.029842 +127.0.0.1, 2018-09-23 14:01:45, GET, /favicon.ico, HTTP/1.1, 400, 0.000267 +127.0.0.1, 2018-09-23 14:02:44, GET, /SP/default/user/login, HTTP/1.1, 500, 0.031418 +127.0.0.1, 2018-09-23 14:02:49, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.14-02-44.e5d30aa7-20da-4772-b99b-9c0f6fef9a98, HTTP/1.1, 200, 0.024965 +127.0.0.1, 2018-09-23 14:02:49, GET, /favicon.ico, HTTP/1.1, 400, 0.000249 +127.0.0.1, 2018-09-23 14:04:32, GET, /SP/default/user/login, HTTP/1.1, 500, 0.042641 +127.0.0.1, 2018-09-23 14:04:39, GET, /SP/default/user/login, HTTP/1.1, 200, 0.024527 +127.0.0.1, 2018-09-23 14:04:43, POST, /SP/default/user/login, HTTP/1.1, 200, 0.021012 +127.0.0.1, 2018-09-23 14:06:54, POST, /SP/default/user/login, HTTP/1.1, 200, 0.033675 +127.0.0.1, 2018-09-23 14:08:25, POST, /SP/default/user/login, HTTP/1.1, 200, 0.032778 +127.0.0.1, 2018-09-23 14:08:49, POST, /SP/default/user/login, HTTP/1.1, 200, 0.019492 +127.0.0.1, 2018-09-23 14:09:00, POST, /SP/default/user/login, HTTP/1.1, 200, 0.020371 +127.0.0.1, 2018-09-23 14:09:03, GET, /SP/default/user/register, HTTP/1.1, 200, 0.017942 +127.0.0.1, 2018-09-23 14:09:19, GET, /SP/default/user/register, HTTP/1.1, 200, 0.021161 +127.0.0.1, 2018-09-23 14:09:40, GET, /SP/default/user/login, HTTP/1.1, 200, 0.020218 +127.0.0.1, 2018-09-23 14:16:44, GET, /SP/default/user/login, HTTP/1.1, 200, 0.035579 +127.0.0.1, 2018-09-23 14:17:03, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.13-54-21.5c142673-7f02-4f59-becd-f8a8458197b8, HTTP/1.1, 200, 0.032831 +127.0.0.1, 2018-09-23 14:17:10, GET, /admin/, HTTP/1.1, 303, 0.002612 +127.0.0.1, 2018-09-23 14:17:10, GET, /admin/default/site, HTTP/1.1, 200, 0.056288 +127.0.0.1, 2018-09-23 14:17:11, POST, /admin/default/check_version, HTTP/1.1, 200, 0.832404 +127.0.0.1, 2018-09-23 14:17:20, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.115726 +127.0.0.1, 2018-09-23 14:17:20, GET, /admin/static/_2.17.1/images/search.png, HTTP/1.1, 200, 0.001447 +127.0.0.1, 2018-09-23 14:17:20, GET, /admin/static/_2.17.1/images/delete_icon.png, HTTP/1.1, 200, 0.000920 +127.0.0.1, 2018-09-23 14:17:20, GET, /admin/static/_2.17.1/images/test_icon.png, HTTP/1.1, 200, 0.001177 +127.0.0.1, 2018-09-23 14:17:20, GET, /favicon.ico, HTTP/1.1, 400, 0.000596 +127.0.0.1, 2018-09-23 14:17:51, GET, /admin/default/site, HTTP/1.1, 200, 0.028061 +127.0.0.1, 2018-09-23 14:17:54, GET, /admin/default/site, HTTP/1.1, 200, 0.029536 +127.0.0.1, 2018-09-23 14:18:09, GET, /admin/default/about/SP, HTTP/1.1, 200, 0.038432 +127.0.0.1, 2018-09-23 14:18:09, GET, /admin/static/_2.17.1/js/jquery.flot.resize.js, HTTP/1.1, 200, 0.000783 +127.0.0.1, 2018-09-23 14:18:09, GET, /admin/static/_2.17.1/js/jquery.flot.js, HTTP/1.1, 200, 0.003191 +127.0.0.1, 2018-09-23 14:18:09, GET, /favicon.ico, HTTP/1.1, 400, 0.000567 +127.0.0.1, 2018-09-23 14:22:22, GET, /SP/default/user/login, HTTP/1.1, 200, 0.028340 +127.0.0.1, 2018-09-23 14:29:54, GET, /SP/default/user/login, HTTP/1.1, 200, 0.054013 +127.0.0.1, 2018-09-23 14:30:11, GET, /SP/default/user/login, HTTP/1.1, 200, 0.027150 +127.0.0.1, 2018-09-23 14:36:18, GET, /SP/default/user/login, HTTP/1.1, 500, 0.026700 +127.0.0.1, 2018-09-23 14:36:19, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.14-36-18.ffba9911-051f-4f00-8da7-a20a9d5a754b, HTTP/1.1, 200, 0.031588 +127.0.0.1, 2018-09-23 14:36:19, GET, /favicon.ico, HTTP/1.1, 400, 0.000424 +127.0.0.1, 2018-09-23 14:36:24, GET, /SP/default/user/register, HTTP/1.1, 500, 0.009336 +127.0.0.1, 2018-09-23 14:36:24, GET, /favicon.ico, HTTP/1.1, 400, 0.000527 +127.0.0.1, 2018-09-23 14:51:56, GET, /SP/default/user/login, HTTP/1.1, 200, 0.031504 +127.0.0.1, 2018-09-23 14:52:01, POST, /SP/default/user/login, HTTP/1.1, 303, 0.026079 +127.0.0.1, 2018-09-23 14:52:01, GET, /SP/default/user/login, HTTP/1.1, 200, 0.021432 +127.0.0.1, 2018-09-23 14:52:03, GET, /SP/default/user/register, HTTP/1.1, 200, 0.032234 +127.0.0.1, 2018-09-23 14:52:39, POST, /SP/default/user/register, HTTP/1.1, 303, 0.047236 +127.0.0.1, 2018-09-23 14:52:39, GET, /SP/default/index, HTTP/1.1, 200, 0.032681 +127.0.0.1, 2018-09-23 14:52:44, GET, /SP/default/user/logout, HTTP/1.1, 303, 0.020923 +127.0.0.1, 2018-09-23 14:52:44, GET, /SP/default/index, HTTP/1.1, 200, 0.019340 +127.0.0.1, 2018-09-23 14:52:46, GET, /SP/default/user/login, HTTP/1.1, 200, 0.020993 +127.0.0.1, 2018-09-23 14:52:54, POST, /SP/default/user/login, HTTP/1.1, 303, 0.019443 +127.0.0.1, 2018-09-23 14:52:54, GET, /SP/default/index, HTTP/1.1, 200, 0.026417 +127.0.0.1, 2018-09-23 14:52:57, GET, /SP/default/user/profile, HTTP/1.1, 200, 0.030110 +127.0.0.1, 2018-09-23 14:53:58, GET, /SP/default/user/logout, HTTP/1.1, 303, 0.026531 +127.0.0.1, 2018-09-23 14:53:58, GET, /SP/default/index, HTTP/1.1, 200, 0.023889 +127.0.0.1, 2018-09-23 14:54:04, GET, /SP/default/user/login, HTTP/1.1, 200, 0.017534 +127.0.0.1, 2018-09-23 14:54:06, GET, /SP/default/user/register, HTTP/1.1, 200, 0.023266 +127.0.0.1, 2018-09-23 15:01:29, GET, /SP/default/user/register, HTTP/1.1, 200, 0.034619 +127.0.0.1, 2018-09-23 15:04:11, GET, /SP/default/user/register, HTTP/1.1, 500, 0.036653 +127.0.0.1, 2018-09-23 15:04:20, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-04-11.b47795e9-b7d8-46a9-ae91-efc4733dca39, HTTP/1.1, 200, 0.038043 +127.0.0.1, 2018-09-23 15:04:20, GET, /favicon.ico, HTTP/1.1, 400, 0.000288 +127.0.0.1, 2018-09-23 15:04:37, GET, /SP/default/user/register, HTTP/1.1, 200, 0.036492 +127.0.0.1, 2018-09-23 15:04:39, GET, /SP/default/user/login, HTTP/1.1, 200, 0.024511 +127.0.0.1, 2018-09-23 15:04:41, GET, /SP/default/user/register, HTTP/1.1, 200, 0.023577 +127.0.0.1, 2018-09-23 15:05:27, GET, /SP/default/user/register, HTTP/1.1, 200, 0.031263 +127.0.0.1, 2018-09-23 15:05:28, GET, /SP/default/user/register, HTTP/1.1, 200, 0.031796 +127.0.0.1, 2018-09-23 15:05:28, GET, /SP/default/user/register, HTTP/1.1, 200, 0.024548 +127.0.0.1, 2018-09-23 15:06:41, GET, /SP/default/user/register, HTTP/1.1, 200, 0.036297 +127.0.0.1, 2018-09-23 15:07:04, POST, /SP/default/user/register, HTTP/1.1, 200, 0.067796 +127.0.0.1, 2018-09-23 15:08:45, POST, /SP/default/user/register, HTTP/1.1, 200, 0.045243 +127.0.0.1, 2018-09-23 15:09:37, POST, /SP/default/user/register, HTTP/1.1, 200, 0.035849 +127.0.0.1, 2018-09-23 15:10:34, POST, /SP/default/user/register, HTTP/1.1, 200, 0.110183 +127.0.0.1, 2018-09-23 15:11:31, POST, /SP/default/user/register, HTTP/1.1, 200, 0.033346 +127.0.0.1, 2018-09-23 15:12:20, POST, /SP/default/user/register, HTTP/1.1, 200, 0.044217 +127.0.0.1, 2018-09-23 15:12:34, POST, /SP/default/user/register, HTTP/1.1, 200, 0.035179 +127.0.0.1, 2018-09-23 15:13:23, POST, /SP/default/user/register, HTTP/1.1, 200, 0.030410 +127.0.0.1, 2018-09-23 15:13:25, POST, /SP/default/user/register, HTTP/1.1, 200, 0.028486 +127.0.0.1, 2018-09-23 15:14:32, POST, /SP/default/user/register, HTTP/1.1, 200, 0.024363 +127.0.0.1, 2018-09-23 15:15:33, POST, /SP/default/user/register, HTTP/1.1, 200, 0.028411 +127.0.0.1, 2018-09-23 15:16:02, POST, /SP/default/user/register, HTTP/1.1, 200, 0.037124 +127.0.0.1, 2018-09-23 15:16:25, GET, /SP/default/user/login, HTTP/1.1, 200, 0.028614 +127.0.0.1, 2018-09-23 15:16:49, GET, /SP/default/user/login, HTTP/1.1, 200, 0.025857 +127.0.0.1, 2018-09-23 15:16:53, GET, /SP/default/user/register, HTTP/1.1, 200, 0.023345 +127.0.0.1, 2018-09-23 15:16:57, GET, /SP/default/user/retrieve_password, HTTP/1.1, 200, 0.034691 +127.0.0.1, 2018-09-23 15:17:24, GET, /SP/private/home, HTTP/1.1, 404, 0.017191 +127.0.0.1, 2018-09-23 15:17:24, GET, /favicon.ico, HTTP/1.1, 400, 0.000360 +127.0.0.1, 2018-09-23 15:27:29, GET, /SP/default/user/login, HTTP/1.1, 500, 0.030216 +127.0.0.1, 2018-09-23 15:27:31, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-27-29.a5c546a7-8774-4128-a2ae-519ed5135e08, HTTP/1.1, 200, 0.042962 +127.0.0.1, 2018-09-23 15:27:31, GET, /favicon.ico, HTTP/1.1, 400, 0.000268 +127.0.0.1, 2018-09-23 15:28:35, GET, /SP/default/user/login, HTTP/1.1, 500, 0.054037 +127.0.0.1, 2018-09-23 15:28:41, GET, /SP/default/user/login, HTTP/1.1, 500, 0.035749 +127.0.0.1, 2018-09-23 15:28:42, GET, /SP/default/user/login, HTTP/1.1, 500, 0.033311 +127.0.0.1, 2018-09-23 15:28:44, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-28-42.556f96b6-7809-4d22-826f-b68d99f4657b, HTTP/1.1, 200, 0.043946 +127.0.0.1, 2018-09-23 15:28:44, GET, /favicon.ico, HTTP/1.1, 400, 0.000384 +127.0.0.1, 2018-09-23 15:29:25, GET, /SP/default/user/login, HTTP/1.1, 200, 0.041933 +127.0.0.1, 2018-09-23 15:29:26, GET, /SP/default/user/register, HTTP/1.1, 200, 0.029301 +127.0.0.1, 2018-09-23 15:29:26, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.002141 +127.0.0.1, 2018-09-23 15:29:26, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.001292 +127.0.0.1, 2018-09-23 15:29:26, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.001305 +127.0.0.1, 2018-09-23 15:29:26, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.000889 +127.0.0.1, 2018-09-23 15:29:26, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.001576 +127.0.0.1, 2018-09-23 15:29:26, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.005125 +127.0.0.1, 2018-09-23 15:29:26, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.000963 +127.0.0.1, 2018-09-23 15:29:26, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.004844 +127.0.0.1, 2018-09-23 15:29:26, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.002027 +127.0.0.1, 2018-09-23 15:29:50, GET, /SP/default/user/register, HTTP/1.1, 200, 0.024707 +127.0.0.1, 2018-09-23 15:29:51, GET, /SP/default/user/register, HTTP/1.1, 200, 0.031247 +127.0.0.1, 2018-09-23 15:29:54, GET, /SP/default/user/login, HTTP/1.1, 200, 0.027796 +127.0.0.1, 2018-09-23 15:29:56, GET, /SP/default/user/register, HTTP/1.1, 200, 0.029085 +127.0.0.1, 2018-09-23 15:30:00, GET, /SP/default/user/register, HTTP/1.1, 200, 0.026264 +127.0.0.1, 2018-09-23 15:30:40, GET, /SP/default/user/register, HTTP/1.1, 200, 0.023797 +127.0.0.1, 2018-09-23 15:30:41, GET, /SP/default/user/register, HTTP/1.1, 200, 0.027414 +127.0.0.1, 2018-09-23 15:30:56, GET, /SP/default/user/register, HTTP/1.1, 200, 0.038034 +127.0.0.1, 2018-09-23 15:34:15, GET, /SP/default/user/register, HTTP/1.1, 200, 0.036097 +127.0.0.1, 2018-09-23 15:34:16, GET, /SP/default/user/login, HTTP/1.1, 200, 0.019726 +127.0.0.1, 2018-09-23 15:34:18, GET, /SP/admin, HTTP/1.1, 404, 0.015666 +127.0.0.1, 2018-09-23 15:34:19, GET, /favicon.ico, HTTP/1.1, 400, 0.000233 +127.0.0.1, 2018-09-23 15:35:29, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.044246 +127.0.0.1, 2018-09-23 15:35:29, GET, /SP/static/images/favicon.ico, HTTP/1.1, 304, 0.000525 +127.0.0.1, 2018-09-23 15:35:29, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.057573 +127.0.0.1, 2018-09-23 15:35:35, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.041303 +127.0.0.1, 2018-09-23 15:35:51, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.036974 +127.0.0.1, 2018-09-23 15:35:58, GET, /SP/appadmin/update/db/auth_group/1, HTTP/1.1, 200, 0.039293 +127.0.0.1, 2018-09-23 15:36:05, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.092681 +127.0.0.1, 2018-09-23 15:36:08, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.076011 +127.0.0.1, 2018-09-23 15:36:10, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.032468 +127.0.0.1, 2018-09-23 15:36:10, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.052231 +127.0.0.1, 2018-09-23 15:36:13, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.030675 +127.0.0.1, 2018-09-23 15:36:17, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.033648 +127.0.0.1, 2018-09-23 15:36:26, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.094530 +127.0.0.1, 2018-09-23 15:37:55, GET, /SP, HTTP/1.1, 200, 0.031321 +127.0.0.1, 2018-09-23 15:37:55, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.003323 +127.0.0.1, 2018-09-23 15:37:55, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.003127 +127.0.0.1, 2018-09-23 15:37:55, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.002177 +127.0.0.1, 2018-09-23 15:37:55, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.006124 +127.0.0.1, 2018-09-23 15:37:55, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.003499 +127.0.0.1, 2018-09-23 15:37:55, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.003097 +127.0.0.1, 2018-09-23 15:37:55, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.002707 +127.0.0.1, 2018-09-23 15:37:55, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.002775 +127.0.0.1, 2018-09-23 15:37:55, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.003130 +127.0.0.1, 2018-09-23 15:37:55, GET, /SP, HTTP/1.1, 200, 0.064247 +127.0.0.1, 2018-09-23 15:37:58, GET, /SP/default/user/login, HTTP/1.1, 200, 0.024215 +127.0.0.1, 2018-09-23 15:38:00, GET, /SP/default/user/register, HTTP/1.1, 200, 0.029525 +127.0.0.1, 2018-09-23 15:38:22, GET, /SP/default/user/register, HTTP/1.1, 200, 0.026063 +127.0.0.1, 2018-09-23 15:38:34, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.037243 +127.0.0.1, 2018-09-23 15:38:36, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.036987 +127.0.0.1, 2018-09-23 15:38:36, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.049745 +127.0.0.1, 2018-09-23 15:38:37, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.037891 +127.0.0.1, 2018-09-23 15:41:04, POST, /SP/default/user/register, HTTP/1.1, 200, 0.040404 +127.0.0.1, 2018-09-23 15:41:16, POST, /SP/default/user/register, HTTP/1.1, 200, 0.038856 +127.0.0.1, 2018-09-23 15:41:28, POST, /SP/default/user/register, HTTP/1.1, 303, 0.033016 +127.0.0.1, 2018-09-23 15:41:28, GET, /SP/default/index, HTTP/1.1, 200, 0.031046 +127.0.0.1, 2018-09-23 15:41:31, GET, /SP/default/index, HTTP/1.1, 200, 0.024295 +127.0.0.1, 2018-09-23 15:41:32, GET, /SP/default/index, HTTP/1.1, 200, 0.023245 +127.0.0.1, 2018-09-23 15:41:35, GET, /SP/default/user/login, HTTP/1.1, 200, 0.027500 +127.0.0.1, 2018-09-23 15:41:40, GET, /SP/appadmin/state, HTTP/1.1, 200, 0.060536 +127.0.0.1, 2018-09-23 15:41:51, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.097163 +127.0.0.1, 2018-09-23 15:42:00, GET, /admin/default/site, HTTP/1.1, 200, 0.026102 +127.0.0.1, 2018-09-23 15:42:06, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.041087 +127.0.0.1, 2018-09-23 15:42:08, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.037756 +127.0.0.1, 2018-09-23 15:42:09, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.048112 +127.0.0.1, 2018-09-23 15:42:15, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.041709 +127.0.0.1, 2018-09-23 15:43:19, POST, /SP/appadmin/select/db, HTTP/1.1, 200, 0.047423 +127.0.0.1, 2018-09-23 15:43:30, POST, /SP/appadmin/select/db, HTTP/1.1, 200, 0.039992 +127.0.0.1, 2018-09-23 15:43:37, POST, /SP/appadmin/select/db, HTTP/1.1, 200, 0.037875 +127.0.0.1, 2018-09-23 15:43:39, POST, /SP/appadmin/select/db, HTTP/1.1, 200, 0.049058 +127.0.0.1, 2018-09-23 15:43:44, GET, /SP/default/user/login, HTTP/1.1, 200, 0.027860 +127.0.0.1, 2018-09-23 15:43:49, POST, /SP/default/user/login, HTTP/1.1, 303, 0.028450 +127.0.0.1, 2018-09-23 15:43:49, GET, /SP/default/index, HTTP/1.1, 500, 0.047510 +127.0.0.1, 2018-09-23 15:43:49, GET, /favicon.ico, HTTP/1.1, 400, 0.000421 +127.0.0.1, 2018-09-23 15:43:51, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-43-49.91a5a50d-8533-4e3f-9930-9752252ca014, HTTP/1.1, 200, 0.057385 +127.0.0.1, 2018-09-23 15:43:51, GET, /favicon.ico, HTTP/1.1, 400, 0.000372 +127.0.0.1, 2018-09-23 15:44:13, GET, /SP/default/user/login, HTTP/1.1, 500, 0.053406 +127.0.0.1, 2018-09-23 15:44:14, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-44-13.f096514b-1984-4004-a4c7-7357441b2e56, HTTP/1.1, 200, 0.050659 +127.0.0.1, 2018-09-23 15:44:15, GET, /favicon.ico, HTTP/1.1, 400, 0.000570 +127.0.0.1, 2018-09-23 15:44:24, GET, /SP/default/user/login, HTTP/1.1, 500, 0.056558 +127.0.0.1, 2018-09-23 15:44:26, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-44-24.8b339ad9-121a-463b-bb42-ab39db214d4b, HTTP/1.1, 200, 0.057914 +127.0.0.1, 2018-09-23 15:44:26, GET, /favicon.ico, HTTP/1.1, 400, 0.000268 +127.0.0.1, 2018-09-23 15:44:34, POST, /SP/appadmin/select/db, HTTP/1.1, 500, 0.072682 +127.0.0.1, 2018-09-23 15:44:34, GET, /favicon.ico, HTTP/1.1, 400, 0.000388 +127.0.0.1, 2018-09-23 15:44:36, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-44-34.64fe6b5c-294f-4773-9d30-846867a15716, HTTP/1.1, 200, 0.096440 +127.0.0.1, 2018-09-23 15:44:36, GET, /favicon.ico, HTTP/1.1, 400, 0.000237 +127.0.0.1, 2018-09-23 15:45:06, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-44-34.64fe6b5c-294f-4773-9d30-846867a15716, HTTP/1.1, 200, 0.099226 +127.0.0.1, 2018-09-23 15:45:14, GET, /SP, HTTP/1.1, 500, 0.071802 +127.0.0.1, 2018-09-23 15:45:14, GET, /favicon.ico, HTTP/1.1, 400, 0.000200 +127.0.0.1, 2018-09-23 15:45:14, GET, /SP, HTTP/1.1, 500, 0.116794 +127.0.0.1, 2018-09-23 15:45:16, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-45-14.00ff237f-e9cc-45de-841a-06797fb7be10, HTTP/1.1, 200, 0.072988 +127.0.0.1, 2018-09-23 15:45:16, GET, /favicon.ico, HTTP/1.1, 400, 0.000292 +127.0.0.1, 2018-09-23 15:46:48, GET, /SP/default/user/login, HTTP/1.1, 500, 0.054698 +127.0.0.1, 2018-09-23 15:46:49, GET, /SP/default/user/login, HTTP/1.1, 500, 0.047285 +127.0.0.1, 2018-09-23 15:47:24, GET, /, HTTP/1.1, 303, 0.002239 +127.0.0.1, 2018-09-23 15:47:24, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.001565 +127.0.0.1, 2018-09-23 15:47:24, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.001967 +127.0.0.1, 2018-09-23 15:47:24, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.002718 +127.0.0.1, 2018-09-23 15:47:24, GET, /welcome/static/css/calendar.css, HTTP/1.1, 304, 0.001844 +127.0.0.1, 2018-09-23 15:47:24, GET, /welcome/static/js/calendar.js, HTTP/1.1, 304, 0.001836 +127.0.0.1, 2018-09-23 15:47:24, GET, /welcome/static/js/jquery.js, HTTP/1.1, 304, 0.003243 +127.0.0.1, 2018-09-23 15:47:24, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.002550 +127.0.0.1, 2018-09-23 15:47:24, GET, /welcome/static/js/web2py.js, HTTP/1.1, 304, 0.003521 +127.0.0.1, 2018-09-23 15:47:24, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.006349 +127.0.0.1, 2018-09-23 15:47:25, GET, /welcome/default/index, HTTP/1.1, 200, 0.034503 +127.0.0.1, 2018-09-23 15:47:30, GET, /SP, HTTP/1.1, 500, 0.114906 +127.0.0.1, 2018-09-23 15:47:32, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-47-30.81ec9fb0-adcd-47f6-9fb5-4185913ed1bf, HTTP/1.1, 200, 0.059292 +127.0.0.1, 2018-09-23 15:47:33, GET, /favicon.ico, HTTP/1.1, 400, 0.000605 +127.0.0.1, 2018-09-23 15:47:53, GET, /SP, HTTP/1.1, 500, 0.066989 +127.0.0.1, 2018-09-23 15:48:09, GET, /SP, HTTP/1.1, 500, 0.053989 +127.0.0.1, 2018-09-23 15:48:13, GET, /SP, HTTP/1.1, 500, 0.047376 +127.0.0.1, 2018-09-23 15:48:15, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-48-13.4c033311-3c6a-4e28-b43b-3ab4b0113751, HTTP/1.1, 200, 0.061084 +127.0.0.1, 2018-09-23 15:48:15, GET, /favicon.ico, HTTP/1.1, 400, 0.000299 +127.0.0.1, 2018-09-23 15:49:21, GET, /SP, HTTP/1.1, 500, 0.052746 +127.0.0.1, 2018-09-23 15:49:22, GET, /SP, HTTP/1.1, 500, 0.046245 +127.0.0.1, 2018-09-23 15:49:28, GET, /SP, HTTP/1.1, 500, 0.047644 +127.0.0.1, 2018-09-23 15:49:29, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-49-28.b53d2050-8e27-4d65-bdb0-4a1b51017307, HTTP/1.1, 200, 0.061723 +127.0.0.1, 2018-09-23 15:49:29, GET, /favicon.ico, HTTP/1.1, 400, 0.000211 +127.0.0.1, 2018-09-23 15:49:48, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-49-28.b53d2050-8e27-4d65-bdb0-4a1b51017307, HTTP/1.1, 200, 0.060178 +127.0.0.1, 2018-09-23 15:49:52, GET, /SP, HTTP/1.1, 500, 0.048699 +127.0.0.1, 2018-09-23 15:49:54, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-49-52.7dd8f18e-944d-4deb-959c-ba8634d43f2a, HTTP/1.1, 200, 0.075069 +127.0.0.1, 2018-09-23 15:49:54, GET, /favicon.ico, HTTP/1.1, 400, 0.000308 +127.0.0.1, 2018-09-23 15:54:03, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-49-52.7dd8f18e-944d-4deb-959c-ba8634d43f2a, HTTP/1.1, 200, 0.056288 +127.0.0.1, 2018-09-23 15:54:10, GET, /SP/default/user/login, HTTP/1.1, 500, 0.035540 +127.0.0.1, 2018-09-23 15:54:12, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-54-10.3fcf7b45-3ff9-4842-86ff-dad45dc4e871, HTTP/1.1, 200, 0.040680 +127.0.0.1, 2018-09-23 15:54:12, GET, /favicon.ico, HTTP/1.1, 400, 0.000212 +127.0.0.1, 2018-09-23 15:54:36, GET, /admin/default/site, HTTP/1.1, 200, 0.025211 +127.0.0.1, 2018-09-23 15:55:39, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-54-10.3fcf7b45-3ff9-4842-86ff-dad45dc4e871, HTTP/1.1, 200, 0.042383 +127.0.0.1, 2018-09-23 15:55:40, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-54-10.3fcf7b45-3ff9-4842-86ff-dad45dc4e871, HTTP/1.1, 200, 0.040389 +127.0.0.1, 2018-09-23 15:55:46, GET, /SP/default/user/login, HTTP/1.1, 500, 0.034956 +127.0.0.1, 2018-09-23 15:55:47, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-55-46.19a4455f-b08f-4716-88e3-98cf0d4856eb, HTTP/1.1, 200, 0.041417 +127.0.0.1, 2018-09-23 15:55:47, GET, /favicon.ico, HTTP/1.1, 400, 0.000234 +127.0.0.1, 2018-09-23 15:55:58, GET, /SP/default/user/login, HTTP/1.1, 500, 0.032684 +127.0.0.1, 2018-09-23 15:56:00, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-55-58.09ce167e-6a0a-4e67-976d-f3dccbda7f15, HTTP/1.1, 200, 0.035606 +127.0.0.1, 2018-09-23 15:56:00, GET, /favicon.ico, HTTP/1.1, 400, 0.000217 +127.0.0.1, 2018-09-23 15:56:32, GET, /, HTTP/1.1, 303, 0.005733 +127.0.0.1, 2018-09-23 15:56:33, GET, /welcome/default/index, HTTP/1.1, 500, 0.280262 +127.0.0.1, 2018-09-23 15:56:33, GET, /favicon.ico, HTTP/1.1, 400, 0.000414 +127.0.0.1, 2018-09-23 15:56:34, GET, /admin/default/ticket/welcome/127.0.0.1.2018-09-23.15-56-32.fefc955a-9a46-4bc3-8ca4-d5816b0a2c0d, HTTP/1.1, 200, 0.195222 +127.0.0.1, 2018-09-23 15:56:35, GET, /favicon.ico, HTTP/1.1, 400, 0.000211 +127.0.0.1, 2018-09-23 15:56:41, GET, /admin/default/site, HTTP/1.1, 200, 0.047183 +127.0.0.1, 2018-09-23 15:56:46, GET, /SP/default/index, HTTP/1.1, 500, 0.105341 +127.0.0.1, 2018-09-23 15:56:46, GET, /favicon.ico, HTTP/1.1, 400, 0.000486 +127.0.0.1, 2018-09-23 15:56:48, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-56-46.7d37504e-8bed-49bc-9490-f5fd8fb3b2d6, HTTP/1.1, 200, 0.040665 +127.0.0.1, 2018-09-23 15:56:48, GET, /favicon.ico, HTTP/1.1, 400, 0.000216 +127.0.0.1, 2018-09-23 15:59:09, GET, /, HTTP/1.1, 303, 0.003863 +127.0.0.1, 2018-09-23 15:59:09, GET, /welcome/default/index, HTTP/1.1, 500, 0.256114 +127.0.0.1, 2018-09-23 15:59:11, GET, /admin/default/ticket/welcome/127.0.0.1.2018-09-23.15-59-09.7f029417-0967-4557-a5a7-2731685f4fed, HTTP/1.1, 200, 0.214506 +127.0.0.1, 2018-09-23 15:59:11, GET, /favicon.ico, HTTP/1.1, 400, 0.000354 +127.0.0.1, 2018-09-23 15:59:22, GET, /, HTTP/1.1, 303, 0.000334 +127.0.0.1, 2018-09-23 15:59:22, GET, /welcome/default/index, HTTP/1.1, 500, 0.026934 +127.0.0.1, 2018-09-23 15:59:23, GET, /SP, HTTP/1.1, 500, 0.137814 +127.0.0.1, 2018-09-23 15:59:23, GET, /SP, HTTP/1.1, 500, 0.143321 +127.0.0.1, 2018-09-23 15:59:25, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.15-59-23.cbd147d7-275d-49c8-bb62-f5710fa6b182, HTTP/1.1, 200, 0.056170 +127.0.0.1, 2018-09-23 15:59:25, GET, /favicon.ico, HTTP/1.1, 400, 0.000449 +127.0.0.1, 2018-09-23 16:01:15, GET, /SP/default/user/login, HTTP/1.1, 500, 0.027995 +127.0.0.1, 2018-09-23 16:01:18, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.16-01-15.0cd2182e-7b39-417a-84a8-250066cf9933, HTTP/1.1, 200, 0.031341 +127.0.0.1, 2018-09-23 16:01:19, GET, /favicon.ico, HTTP/1.1, 400, 0.000342 +127.0.0.1, 2018-09-23 16:01:55, GET, /SP/default/user/login, HTTP/1.1, 500, 0.031333 +127.0.0.1, 2018-09-23 16:01:56, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.16-01-55.64367cde-c27f-4b2a-bda0-a84ef1b4d4bd, HTTP/1.1, 200, 0.039915 +127.0.0.1, 2018-09-23 16:01:57, GET, /favicon.ico, HTTP/1.1, 400, 0.000207 +127.0.0.1, 2018-09-23 16:02:09, GET, /SP/default/user/login, HTTP/1.1, 500, 0.032120 +127.0.0.1, 2018-09-23 16:02:10, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.16-02-09.5dce232c-a705-443a-b8b5-58d38143b62b, HTTP/1.1, 200, 0.034502 +127.0.0.1, 2018-09-23 16:02:11, GET, /favicon.ico, HTTP/1.1, 400, 0.000238 +127.0.0.1, 2018-09-23 16:02:36, GET, /SP/default/user/login, HTTP/1.1, 500, 0.037139 +127.0.0.1, 2018-09-23 16:02:37, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.16-02-36.a04ceeb1-5428-4d88-b3e6-0249fd5788c4, HTTP/1.1, 200, 0.026859 +127.0.0.1, 2018-09-23 16:02:38, GET, /favicon.ico, HTTP/1.1, 400, 0.000340 +127.0.0.1, 2018-09-23 16:04:41, GET, /SP/default/user/login, HTTP/1.1, 500, 0.058988 +127.0.0.1, 2018-09-23 16:04:42, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.16-04-41.7845f5bf-3033-4ccd-8e10-6b6ec04f9eff, HTTP/1.1, 200, 0.073702 +127.0.0.1, 2018-09-23 16:04:42, GET, /favicon.ico, HTTP/1.1, 400, 0.000246 +127.0.0.1, 2018-09-23 16:05:31, GET, /, HTTP/1.1, 303, 0.003866 +127.0.0.1, 2018-09-23 16:05:31, GET, /welcome/default/index, HTTP/1.1, 200, 0.167533 +127.0.0.1, 2018-09-23 16:05:39, GET, /, HTTP/1.1, 303, 0.000328 +127.0.0.1, 2018-09-23 16:05:39, GET, /welcome/default/index, HTTP/1.1, 200, 0.031700 +127.0.0.1, 2018-09-23 16:05:40, GET, /SP, HTTP/1.1, 500, 0.206632 +127.0.0.1, 2018-09-23 16:05:40, GET, /SP, HTTP/1.1, 500, 0.217095 +127.0.0.1, 2018-09-23 16:05:42, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.16-05-40.e2f6d53f-6653-4115-810c-e3f4420d4879, HTTP/1.1, 200, 0.229148 +127.0.0.1, 2018-09-23 16:05:42, GET, /favicon.ico, HTTP/1.1, 400, 0.000474 +127.0.0.1, 2018-09-23 16:05:57, GET, /SP, HTTP/1.1, 500, 0.075668 +127.0.0.1, 2018-09-23 16:05:59, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.16-05-57.6f691dd5-7b64-4b52-aec9-2e810baea65e, HTTP/1.1, 200, 0.066561 +127.0.0.1, 2018-09-23 16:05:59, GET, /favicon.ico, HTTP/1.1, 400, 0.000494 +127.0.0.1, 2018-09-23 16:07:53, GET, /SP/default/index, HTTP/1.1, 200, 0.032008 +127.0.0.1, 2018-09-23 16:08:03, GET, /SP/default/user/profile, HTTP/1.1, 404, 0.021458 +127.0.0.1, 2018-09-23 16:08:03, GET, /favicon.ico, HTTP/1.1, 400, 0.000238 +127.0.0.1, 2018-09-23 16:08:08, GET, /SP/default/user/profile, HTTP/1.1, 404, 0.013369 +127.0.0.1, 2018-09-23 16:09:07, GET, /SP/default/user/profile, HTTP/1.1, 404, 0.023702 +127.0.0.1, 2018-09-23 16:09:11, GET, /SP/default/user/profile, HTTP/1.1, 404, 0.016924 +127.0.0.1, 2018-09-23 16:09:15, GET, /SP/default/user/logout, HTTP/1.1, 303, 0.016768 +127.0.0.1, 2018-09-23 16:09:15, GET, /SP/default/index, HTTP/1.1, 200, 0.024178 +127.0.0.1, 2018-09-23 16:09:17, GET, /SP/default/user/login, HTTP/1.1, 200, 0.028029 +127.0.0.1, 2018-09-23 16:09:29, GET, /SP/default/user/register, HTTP/1.1, 200, 0.038065 +127.0.0.1, 2018-09-23 16:09:34, POST, /SP/default/user/register, HTTP/1.1, 200, 0.035577 +127.0.0.1, 2018-09-23 16:15:48, GET, /SP/default/user/login, HTTP/1.1, 200, 0.050537 +127.0.0.1, 2018-09-23 16:15:48, GET, /SP, HTTP/1.1, 200, 0.020563 +127.0.0.1, 2018-09-23 16:15:49, GET, /SP/default/user/login, HTTP/1.1, 200, 0.023491 +127.0.0.1, 2018-09-23 16:15:49, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.043886 +127.0.0.1, 2018-09-23 16:15:53, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.035376 +127.0.0.1, 2018-09-23 16:15:57, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.036989 +127.0.0.1, 2018-09-23 16:15:57, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.058941 +127.0.0.1, 2018-09-23 16:15:58, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.036267 +127.0.0.1, 2018-09-23 16:16:01, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.033018 +127.0.0.1, 2018-09-23 16:16:01, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.100757 +127.0.0.1, 2018-09-23 16:16:01, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.051318 +127.0.0.1, 2018-09-23 16:16:07, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.035915 +127.0.0.1, 2018-09-23 16:16:11, GET, /SP/default/user/login, HTTP/1.1, 200, 0.024823 +127.0.0.1, 2018-09-23 16:16:17, POST, /SP/default/user/login, HTTP/1.1, 303, 0.021844 +127.0.0.1, 2018-09-23 16:16:17, GET, /SP/default/user/login, HTTP/1.1, 200, 0.025670 +127.0.0.1, 2018-09-23 16:16:32, POST, /SP/default/user/login, HTTP/1.1, 303, 0.028944 +127.0.0.1, 2018-09-23 16:16:33, GET, /SP/default/user/login, HTTP/1.1, 200, 0.026610 +127.0.0.1, 2018-09-23 16:16:39, POST, /SP/default/user/login, HTTP/1.1, 303, 0.019087 +127.0.0.1, 2018-09-23 16:16:39, GET, /SP/default/user/login, HTTP/1.1, 200, 0.023002 +127.0.0.1, 2018-09-23 16:16:44, GET, /SP/default/user/register, HTTP/1.1, 200, 0.026719 +127.0.0.1, 2018-09-23 16:18:28, GET, /SP/private/home, HTTP/1.1, 404, 0.026081 +127.0.0.1, 2018-09-23 16:18:34, GET, /SP/default/user/register, HTTP/1.1, 200, 0.026186 +127.0.0.1, 2018-09-23 16:18:55, POST, /SP/default/user/register, HTTP/1.1, 303, 0.029950 +127.0.0.1, 2018-09-23 16:18:55, GET, /SP/default/index, HTTP/1.1, 200, 0.025213 +127.0.0.1, 2018-09-23 16:18:58, GET, /SP/default/user/profile, HTTP/1.1, 404, 0.014772 +127.0.0.1, 2018-09-23 16:25:42, GET, /SP/default/user/profile, HTTP/1.1, 500, 0.061145 +127.0.0.1, 2018-09-23 16:25:44, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.16-25-42.13ccbdf1-f384-4c6f-9aea-a4faf099756b, HTTP/1.1, 200, 0.066435 +127.0.0.1, 2018-09-23 16:25:44, GET, /favicon.ico, HTTP/1.1, 400, 0.000396 +127.0.0.1, 2018-09-23 16:26:06, GET, /SP/default/user/login, HTTP/1.1, 303, 0.022978 +127.0.0.1, 2018-09-23 16:26:06, GET, /SP/default/index, HTTP/1.1, 200, 0.026572 +127.0.0.1, 2018-09-23 16:26:10, GET, /SP/default/user/profile, HTTP/1.1, 500, 0.046714 +127.0.0.1, 2018-09-23 16:26:12, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.16-26-10.47595aed-16ca-4978-96c5-ae56ae864a4b, HTTP/1.1, 200, 0.065850 +127.0.0.1, 2018-09-23 16:26:12, GET, /favicon.ico, HTTP/1.1, 400, 0.000531 +127.0.0.1, 2018-09-23 16:26:20, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.16-26-10.47595aed-16ca-4978-96c5-ae56ae864a4b, HTTP/1.1, 200, 0.062015 +127.0.0.1, 2018-09-23 16:27:17, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.16-26-10.47595aed-16ca-4978-96c5-ae56ae864a4b, HTTP/1.1, 200, 0.063157 +127.0.0.1, 2018-09-23 16:27:19, GET, /SP/default/user/profile, HTTP/1.1, 404, 0.025496 +127.0.0.1, 2018-09-23 16:27:52, GET, /SP/default/myhome, HTTP/1.1, 303, 0.023334 +127.0.0.1, 2018-09-23 16:27:52, GET, /SP/default/myhome/login, HTTP/1.1, 200, 0.018944 +127.0.0.1, 2018-09-23 16:27:53, GET, /favicon.ico, HTTP/1.1, 400, 0.000210 +127.0.0.1, 2018-09-23 16:28:29, GET, /SP/default/myhome/login, HTTP/1.1, 200, 0.022663 +127.0.0.1, 2018-09-23 16:28:49, GET, /SP/default/myhome/login, HTTP/1.1, 200, 0.017956 +127.0.0.1, 2018-09-23 16:30:02, GET, /SP/default/myhome/login, HTTP/1.1, 200, 0.024690 +127.0.0.1, 2018-09-23 16:30:08, GET, /SP/private/home, HTTP/1.1, 404, 0.017998 +127.0.0.1, 2018-09-23 16:30:51, GET, /SP/private/home, HTTP/1.1, 404, 0.018773 +127.0.0.1, 2018-09-23 16:30:58, GET, /SP/default/myhome/login, HTTP/1.1, 200, 0.028754 +127.0.0.1, 2018-09-23 16:30:59, GET, /SP/default/myhome, HTTP/1.1, 200, 0.022805 +127.0.0.1, 2018-09-23 16:31:00, GET, /SP/default/myhome, HTTP/1.1, 200, 0.021808 +127.0.0.1, 2018-09-23 16:31:16, GET, /SP/default/myhome, HTTP/1.1, 200, 0.019701 +127.0.0.1, 2018-09-23 16:31:20, GET, /SP/default/user/profile, HTTP/1.1, 404, 0.015837 +127.0.0.1, 2018-09-23 16:32:08, GET, /SP/default/myhome, HTTP/1.1, 200, 0.026263 +127.0.0.1, 2018-09-23 16:32:09, GET, /SP/default/myhome, HTTP/1.1, 200, 0.020607 +127.0.0.1, 2018-09-23 16:32:11, GET, /SP/default/myhome, HTTP/1.1, 200, 0.026555 +127.0.0.1, 2018-09-23 16:48:17, GET, /SP, HTTP/1.1, 200, 0.044572 +127.0.0.1, 2018-09-23 16:48:19, GET, /SP/default/myhome, HTTP/1.1, 500, 0.046957 +127.0.0.1, 2018-09-23 16:48:19, GET, /favicon.ico, HTTP/1.1, 400, 0.000233 +127.0.0.1, 2018-09-23 16:48:20, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.16-48-18.80a55e8c-2eb7-4457-85eb-3a997bc501fa, HTTP/1.1, 200, 0.034379 +127.0.0.1, 2018-09-23 16:48:20, GET, /favicon.ico, HTTP/1.1, 400, 0.000334 +127.0.0.1, 2018-09-23 16:49:45, GET, /favicon.ico, HTTP/1.1, 400, 0.000250 +127.0.0.1, 2018-09-23 16:49:45, GET, /SP/default/myhome, HTTP/1.1, 200, 0.048913 +127.0.0.1, 2018-09-23 16:51:34, GET, /favicon.ico, HTTP/1.1, 400, 0.000229 +127.0.0.1, 2018-09-23 16:51:34, GET, /SP/default/myhome, HTTP/1.1, 200, 0.040313 +127.0.0.1, 2018-09-23 16:52:22, GET, /favicon.ico, HTTP/1.1, 400, 0.000254 +127.0.0.1, 2018-09-23 16:52:22, GET, /SP/default/myhome, HTTP/1.1, 200, 0.037741 +127.0.0.1, 2018-09-23 16:52:23, GET, /favicon.ico, HTTP/1.1, 400, 0.000202 +127.0.0.1, 2018-09-23 16:52:23, GET, /SP/default/myhome, HTTP/1.1, 200, 0.023531 +127.0.0.1, 2018-09-23 16:52:32, GET, /SP/private/home, HTTP/1.1, 404, 0.014674 +127.0.0.1, 2018-09-23 16:52:35, GET, /SP/default/index, HTTP/1.1, 200, 0.029864 +127.0.0.1, 2018-09-23 16:52:39, GET, /SP/private/home, HTTP/1.1, 404, 0.015889 +127.0.0.1, 2018-09-23 16:52:42, GET, /favicon.ico, HTTP/1.1, 400, 0.000187 +127.0.0.1, 2018-09-23 16:52:42, GET, /SP/default/myhome, HTTP/1.1, 200, 0.022209 +127.0.0.1, 2018-09-23 16:53:51, GET, /favicon.ico, HTTP/1.1, 400, 0.000205 +127.0.0.1, 2018-09-23 16:53:51, GET, /SP/default/myhome, HTTP/1.1, 200, 0.023683 +127.0.0.1, 2018-09-23 16:53:58, GET, /favicon.ico, HTTP/1.1, 400, 0.000187 +127.0.0.1, 2018-09-23 16:53:58, GET, /SP/default/myhome, HTTP/1.1, 200, 0.024754 +127.0.0.1, 2018-09-23 16:54:07, GET, /favicon.ico, HTTP/1.1, 400, 0.000203 +127.0.0.1, 2018-09-23 16:54:07, GET, /SP/default/myhome, HTTP/1.1, 200, 0.022784 +127.0.0.1, 2018-09-23 16:54:53, GET, /favicon.ico, HTTP/1.1, 400, 0.000306 +127.0.0.1, 2018-09-23 16:54:53, GET, /SP/default/myhome, HTTP/1.1, 200, 0.034830 +127.0.0.1, 2018-09-23 16:55:12, GET, /favicon.ico, HTTP/1.1, 400, 0.000232 +127.0.0.1, 2018-09-23 16:55:12, GET, /SP/default/myhome, HTTP/1.1, 200, 0.096210 +127.0.0.1, 2018-09-23 16:55:32, GET, /favicon.ico, HTTP/1.1, 400, 0.000200 +127.0.0.1, 2018-09-23 16:55:32, GET, /SP/default/myhome, HTTP/1.1, 200, 0.022298 +127.0.0.1, 2018-09-23 16:55:40, GET, /favicon.ico, HTTP/1.1, 400, 0.000197 +127.0.0.1, 2018-09-23 16:55:40, GET, /SP/default/myhome, HTTP/1.1, 200, 0.024021 +127.0.0.1, 2018-09-23 16:55:59, GET, /favicon.ico, HTTP/1.1, 400, 0.000528 +127.0.0.1, 2018-09-23 16:55:59, GET, /SP/default/myhome, HTTP/1.1, 200, 0.024425 +127.0.0.1, 2018-09-23 16:56:06, GET, /favicon.ico, HTTP/1.1, 400, 0.000195 +127.0.0.1, 2018-09-23 16:56:06, GET, /SP/default/myhome, HTTP/1.1, 200, 0.024778 +127.0.0.1, 2018-09-23 16:56:31, GET, /favicon.ico, HTTP/1.1, 400, 0.000182 +127.0.0.1, 2018-09-23 16:56:31, GET, /SP/default/myhome, HTTP/1.1, 200, 0.031622 +127.0.0.1, 2018-09-23 16:56:43, GET, /favicon.ico, HTTP/1.1, 400, 0.000192 +127.0.0.1, 2018-09-23 16:56:43, GET, /SP/default/myhome, HTTP/1.1, 200, 0.022878 +127.0.0.1, 2018-09-23 16:57:37, GET, /favicon.ico, HTTP/1.1, 400, 0.000306 +127.0.0.1, 2018-09-23 16:57:37, GET, /SP/default/myhome, HTTP/1.1, 200, 0.036622 +127.0.0.1, 2018-09-23 16:57:56, GET, /favicon.ico, HTTP/1.1, 400, 0.000290 +127.0.0.1, 2018-09-23 16:57:56, GET, /SP/default/myhome, HTTP/1.1, 200, 0.033905 +127.0.0.1, 2018-09-23 16:58:16, GET, /favicon.ico, HTTP/1.1, 400, 0.000231 +127.0.0.1, 2018-09-23 16:58:16, GET, /SP/default/myhome, HTTP/1.1, 200, 0.022567 +127.0.0.1, 2018-09-23 16:59:05, GET, /SP/default/myhome, HTTP/1.1, 500, 0.050732 +127.0.0.1, 2018-09-23 17:02:59, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.16-48-18.80a55e8c-2eb7-4457-85eb-3a997bc501fa, HTTP/1.1, 200, 0.033284 +127.0.0.1, 2018-09-23 17:03:01, GET, /SP/default/myhome, HTTP/1.1, 200, 0.042236 +127.0.0.1, 2018-09-23 17:03:14, GET, /SP/default/link2, HTTP/1.1, 404, 0.020503 +127.0.0.1, 2018-09-23 17:03:15, GET, /favicon.ico, HTTP/1.1, 400, 0.000301 +127.0.0.1, 2018-09-23 17:03:27, GET, /SP/default/myhome, HTTP/1.1, 500, 0.053346 +127.0.0.1, 2018-09-23 17:03:37, GET, /SP/default/myhome, HTTP/1.1, 200, 0.025286 +127.0.0.1, 2018-09-23 17:05:37, GET, /SP/default/myhome, HTTP/1.1, 200, 0.039939 +127.0.0.1, 2018-09-23 17:05:50, GET, /SP/default/myhome, HTTP/1.1, 500, 0.050651 +127.0.0.1, 2018-09-23 17:06:01, GET, /SP/default/myhome, HTTP/1.1, 200, 0.037794 +127.0.0.1, 2018-09-23 17:06:20, GET, /, HTTP/1.1, 303, 0.000301 +127.0.0.1, 2018-09-23 17:06:20, GET, /welcome/default/index, HTTP/1.1, 200, 0.029511 +127.0.0.1, 2018-09-23 17:06:21, GET, /welcome/default/index, HTTP/1.1, 200, 0.020247 +127.0.0.1, 2018-09-23 17:06:21, GET, /welcome/default/index, HTTP/1.1, 200, 0.015886 +127.0.0.1, 2018-09-23 17:06:23, GET, /welcome/default/index, HTTP/1.1, 200, 0.022942 +127.0.0.1, 2018-09-23 17:06:46, GET, /admin/default/design/welcome, HTTP/1.1, 200, 0.110926 +127.0.0.1, 2018-09-23 17:06:47, GET, /favicon.ico, HTTP/1.1, 400, 0.000238 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/default/design/welcome, HTTP/1.1, 303, 0.006472 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/default/index, HTTP/1.1, 200, 0.038746 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/static/_2.17.1/js/jquery.js, HTTP/1.1, 200, 0.000758 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/static/_2.17.1/css/calendar.css, HTTP/1.1, 200, 0.005017 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/static/_2.17.1/plugin_multiselect/jquery.multi-select.js, HTTP/1.1, 200, 0.003311 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/static/_2.17.1/js/web2py.js, HTTP/1.1, 200, 0.001452 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/static/_2.17.1/js/calendar.js, HTTP/1.1, 200, 0.002999 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/static/_2.17.1/plugin_statebutton/css/bootstrap-switch.css, HTTP/1.1, 200, 0.005166 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/static/_2.17.1/plugin_multiselect/multi-select.css, HTTP/1.1, 200, 0.004375 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/static/_2.17.1/css/bootstrap.min.css, HTTP/1.1, 200, 0.000838 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/static/_2.17.1/plugin_multiselect/start.js, HTTP/1.1, 200, 0.002245 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/static/_2.17.1/css/bootstrap_essentials.css, HTTP/1.1, 200, 0.003922 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/static/_2.17.1/js/bootstrap.min.js, HTTP/1.1, 200, 0.001750 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/static/_2.17.1/css/bootstrap-responsive.min.css, HTTP/1.1, 200, 0.005912 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/static/_2.17.1/plugin_statebutton/js/bootstrap-switch.js, HTTP/1.1, 200, 0.005925 +127.0.0.1, 2018-09-23 17:06:57, GET, /admin/static/_2.17.1/images/questions.png, HTTP/1.1, 200, 0.002984 +127.0.0.1, 2018-09-23 17:06:58, GET, /favicon.ico, HTTP/1.1, 400, 0.000211 +127.0.0.1, 2018-09-23 17:07:03, GET, /wel, HTTP/1.1, 404, 0.000776 +127.0.0.1, 2018-09-23 17:07:03, GET, /favicon.ico, HTTP/1.1, 400, 0.000217 +127.0.0.1, 2018-09-23 17:07:05, GET, /welcome, HTTP/1.1, 200, 0.023474 +127.0.0.1, 2018-09-23 17:07:05, GET, /welcome/static/js/calendar.js, HTTP/1.1, 200, 0.001001 +127.0.0.1, 2018-09-23 17:07:05, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 200, 0.001042 +127.0.0.1, 2018-09-23 17:07:05, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 200, 0.007098 +127.0.0.1, 2018-09-23 17:07:05, GET, /welcome/static/js/jquery.js, HTTP/1.1, 200, 0.007754 +127.0.0.1, 2018-09-23 17:07:05, GET, /welcome/static/css/calendar.css, HTTP/1.1, 200, 0.003416 +127.0.0.1, 2018-09-23 17:07:05, GET, /welcome/static/js/web2py.js, HTTP/1.1, 200, 0.000692 +127.0.0.1, 2018-09-23 17:07:05, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 200, 0.015633 +127.0.0.1, 2018-09-23 17:07:05, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 200, 0.001208 +127.0.0.1, 2018-09-23 17:07:05, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 200, 0.001052 +127.0.0.1, 2018-09-23 17:07:07, GET, /welcome/static/images/favicon.ico, HTTP/1.1, 200, 0.000905 +127.0.0.1, 2018-09-23 17:07:13, GET, /admin/default/design/welcome, HTTP/1.1, 303, 0.004787 +127.0.0.1, 2018-09-23 17:07:13, GET, /admin/default/index, HTTP/1.1, 200, 0.017885 +127.0.0.1, 2018-09-23 17:07:14, GET, /favicon.ico, HTTP/1.1, 400, 0.000367 +127.0.0.1, 2018-09-23 17:07:16, POST, /admin/default/index, HTTP/1.1, 303, 0.012073 +127.0.0.1, 2018-09-23 17:07:16, GET, /admin/default/design/welcome, HTTP/1.1, 200, 0.086164 +127.0.0.1, 2018-09-23 17:07:16, GET, /admin/static/_2.17.1/images/search.png, HTTP/1.1, 200, 0.000986 +127.0.0.1, 2018-09-23 17:07:16, GET, /admin/static/_2.17.1/images/help.png, HTTP/1.1, 200, 0.000712 +127.0.0.1, 2018-09-23 17:07:16, GET, /admin/static/_2.17.1/images/test_icon.png, HTTP/1.1, 200, 0.002010 +127.0.0.1, 2018-09-23 17:07:16, GET, /admin/static/_2.17.1/images/delete_icon.png, HTTP/1.1, 200, 0.000796 +127.0.0.1, 2018-09-23 17:07:16, GET, /favicon.ico, HTTP/1.1, 400, 0.000212 +127.0.0.1, 2018-09-23 17:07:23, GET, /admin/static/_2.17.1/images/glyphicons-halflings.png, HTTP/1.1, 200, 0.000854 +127.0.0.1, 2018-09-23 17:08:47, GET, /SP/default/myhome, HTTP/1.1, 200, 0.030153 +127.0.0.1, 2018-09-23 17:08:48, GET, /SP/default/myhome, HTTP/1.1, 200, 0.026890 +127.0.0.1, 2018-09-23 17:10:04, GET, /SP/default/myhome, HTTP/1.1, 500, 0.042880 +127.0.0.1, 2018-09-23 17:10:17, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.17-10-03.b76dcefe-bb84-428b-bd3b-928234f99a7e, HTTP/1.1, 200, 0.038704 +127.0.0.1, 2018-09-23 17:10:17, GET, /favicon.ico, HTTP/1.1, 400, 0.000737 +127.0.0.1, 2018-09-23 17:10:40, GET, /SP/default/myhome, HTTP/1.1, 200, 0.026760 +127.0.0.1, 2018-09-23 17:11:05, GET, /SP/private/home, HTTP/1.1, 404, 0.016228 +127.0.0.1, 2018-09-23 17:11:50, GET, /SP/default/index, HTTP/1.1, 500, 0.096886 +127.0.0.1, 2018-09-23 17:11:53, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.17-11-50.c3b53257-9058-4328-9baa-b1492fe0229f, HTTP/1.1, 200, 0.035113 +127.0.0.1, 2018-09-23 17:11:53, GET, /favicon.ico, HTTP/1.1, 400, 0.000229 +127.0.0.1, 2018-09-23 17:14:22, GET, /SP/default/index, HTTP/1.1, 200, 0.037557 +127.0.0.1, 2018-09-23 17:14:24, GET, /SP/private/home, HTTP/1.1, 404, 0.018742 +127.0.0.1, 2018-09-23 17:14:39, GET, /SP/private/home, HTTP/1.1, 404, 0.023476 +127.0.0.1, 2018-09-23 17:14:45, GET, /SP/default/user/login, HTTP/1.1, 200, 0.053612 +127.0.0.1, 2018-09-23 17:14:45, GET, /SP, HTTP/1.1, 200, 0.030659 +127.0.0.1, 2018-09-23 17:14:47, GET, /SP/default/myclass, HTTP/1.1, 200, 0.027203 +127.0.0.1, 2018-09-23 17:14:53, GET, /SP/default/myhome, HTTP/1.1, 200, 0.022343 +127.0.0.1, 2018-09-23 17:14:55, GET, /SP/default/myclass, HTTP/1.1, 200, 0.024937 +127.0.0.1, 2018-09-23 17:15:06, GET, /SP/default/myclass, HTTP/1.1, 200, 0.024161 +127.0.0.1, 2018-09-23 17:15:15, GET, /SP/default/myclass, HTTP/1.1, 200, 0.021405 +127.0.0.1, 2018-09-23 17:15:15, GET, /SP/default/myhome, HTTP/1.1, 200, 0.023130 +127.0.0.1, 2018-09-23 17:15:17, GET, /SP/default/myclass, HTTP/1.1, 200, 0.022748 +127.0.0.1, 2018-09-23 17:15:19, GET, /SP/default/myhome, HTTP/1.1, 200, 0.028480 +127.0.0.1, 2018-09-23 17:15:21, GET, /SP/default/myclass, HTTP/1.1, 200, 0.028568 +127.0.0.1, 2018-09-23 17:21:02, GET, /SP/default/myclass, HTTP/1.1, 200, 0.037402 +127.0.0.1, 2018-09-23 17:21:22, GET, /SP/default/myclass, HTTP/1.1, 200, 0.023222 +127.0.0.1, 2018-09-23 17:21:36, GET, /SP/default/myclass, HTTP/1.1, 200, 0.065751 +127.0.0.1, 2018-09-23 17:21:43, GET, /SP/default/myclass, HTTP/1.1, 200, 0.023805 +127.0.0.1, 2018-09-23 17:21:52, GET, /SP/private/home, HTTP/1.1, 404, 0.014812 +127.0.0.1, 2018-09-23 17:24:59, GET, /SP/default/myhome, HTTP/1.1, 500, 0.058781 +127.0.0.1, 2018-09-23 17:25:01, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.17-24-59.3ec330fb-a77c-491e-9a69-03899200aed8, HTTP/1.1, 200, 0.035464 +127.0.0.1, 2018-09-23 17:25:01, GET, /favicon.ico, HTTP/1.1, 400, 0.000309 +127.0.0.1, 2018-09-23 17:25:10, GET, /SP/default/myhome, HTTP/1.1, 200, 0.030734 +127.0.0.1, 2018-09-23 17:25:14, GET, /SP/default/myclass, HTTP/1.1, 200, 0.023599 +127.0.0.1, 2018-09-23 17:25:15, GET, /SP/default/myhome, HTTP/1.1, 200, 0.023565 +127.0.0.1, 2018-09-23 17:25:16, GET, /SP/default/myclass, HTTP/1.1, 200, 0.021535 +127.0.0.1, 2018-09-23 17:25:21, GET, /SP/default/myhome, HTTP/1.1, 200, 0.025628 +127.0.0.1, 2018-09-23 17:25:23, GET, /SP/default/myclass, HTTP/1.1, 200, 0.024173 +127.0.0.1, 2018-09-23 17:25:24, GET, /SP/default/myhome, HTTP/1.1, 200, 0.027771 +127.0.0.1, 2018-09-23 20:17:39, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.001789 +127.0.0.1, 2018-09-23 20:17:39, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.005550 +127.0.0.1, 2018-09-23 20:17:39, GET, /, HTTP/1.1, 303, 0.014225 +127.0.0.1, 2018-09-23 20:17:39, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.002041 +127.0.0.1, 2018-09-23 20:17:39, GET, /welcome/static/css/calendar.css, HTTP/1.1, 304, 0.001409 +127.0.0.1, 2018-09-23 20:17:39, GET, /welcome/static/js/jquery.js, HTTP/1.1, 304, 0.008070 +127.0.0.1, 2018-09-23 20:17:39, GET, /welcome/static/js/calendar.js, HTTP/1.1, 304, 0.002622 +127.0.0.1, 2018-09-23 20:17:39, GET, /welcome/static/js/web2py.js, HTTP/1.1, 304, 0.003545 +127.0.0.1, 2018-09-23 20:17:39, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.004484 +127.0.0.1, 2018-09-23 20:17:39, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.001622 +127.0.0.1, 2018-09-23 20:17:39, GET, /welcome/default/index, HTTP/1.1, 200, 0.194950 +127.0.0.1, 2018-09-23 20:17:47, GET, /, HTTP/1.1, 303, 0.000672 +127.0.0.1, 2018-09-23 20:17:47, GET, /welcome/default/index, HTTP/1.1, 200, 0.043522 +127.0.0.1, 2018-09-23 20:17:48, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.001284 +127.0.0.1, 2018-09-23 20:17:48, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.000760 +127.0.0.1, 2018-09-23 20:17:48, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.000924 +127.0.0.1, 2018-09-23 20:17:48, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.001149 +127.0.0.1, 2018-09-23 20:17:48, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.002086 +127.0.0.1, 2018-09-23 20:17:48, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.003217 +127.0.0.1, 2018-09-23 20:17:48, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.000968 +127.0.0.1, 2018-09-23 20:17:48, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.003993 +127.0.0.1, 2018-09-23 20:17:48, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.003917 +127.0.0.1, 2018-09-23 20:17:48, GET, /SP, HTTP/1.1, 200, 0.121125 +127.0.0.1, 2018-09-23 20:17:48, GET, /SP, HTTP/1.1, 200, 0.031257 +127.0.0.1, 2018-09-23 20:18:05, GET, /SP/default/user/login, HTTP/1.1, 200, 0.025662 +127.0.0.1, 2018-09-23 20:18:20, POST, /SP/default/user/login, HTTP/1.1, 303, 0.023903 +127.0.0.1, 2018-09-23 20:18:20, GET, /SP/default/user/login, HTTP/1.1, 200, 0.026487 +127.0.0.1, 2018-09-23 20:18:29, POST, /SP/default/user/login, HTTP/1.1, 303, 0.020228 +127.0.0.1, 2018-09-23 20:18:29, GET, /SP/default/user/login, HTTP/1.1, 200, 0.024031 +127.0.0.1, 2018-09-23 20:18:39, GET, /SP/default/user/register, HTTP/1.1, 200, 0.024291 +127.0.0.1, 2018-09-23 20:19:08, POST, /SP/default/user/register, HTTP/1.1, 303, 0.034176 +127.0.0.1, 2018-09-23 20:19:08, GET, /SP/default/index, HTTP/1.1, 200, 0.027050 +127.0.0.1, 2018-09-23 20:19:14, GET, /SP/default/myhome, HTTP/1.1, 200, 0.026964 +127.0.0.1, 2018-09-23 20:23:38, GET, /SP/default/myhome, HTTP/1.1, 500, 0.140945 +127.0.0.1, 2018-09-23 20:23:40, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.20-23-38.cb988dbf-e441-49c9-aa7d-ef4ea39edc8f, HTTP/1.1, 303, 0.144594 +127.0.0.1, 2018-09-23 20:23:40, GET, /admin/default/index, HTTP/1.1, 200, 0.062471 +127.0.0.1, 2018-09-23 20:23:40, GET, /favicon.ico, HTTP/1.1, 400, 0.000290 +127.0.0.1, 2018-09-23 20:23:42, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.20-23-38.cb988dbf-e441-49c9-aa7d-ef4ea39edc8f, HTTP/1.1, 303, 0.003195 +127.0.0.1, 2018-09-23 20:23:42, GET, /admin/default/index, HTTP/1.1, 200, 0.016900 +127.0.0.1, 2018-09-23 20:23:46, POST, /admin/default/index, HTTP/1.1, 200, 0.015003 +127.0.0.1, 2018-09-23 20:23:50, POST, /admin/default/index, HTTP/1.1, 303, 0.010308 +127.0.0.1, 2018-09-23 20:23:51, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.20-23-38.cb988dbf-e441-49c9-aa7d-ef4ea39edc8f, HTTP/1.1, 200, 0.050673 +127.0.0.1, 2018-09-23 20:23:51, GET, /favicon.ico, HTTP/1.1, 400, 0.000413 +127.0.0.1, 2018-09-23 20:28:44, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.20-23-38.cb988dbf-e441-49c9-aa7d-ef4ea39edc8f, HTTP/1.1, 200, 0.039691 +127.0.0.1, 2018-09-23 20:28:47, GET, /SP/default/myhome, HTTP/1.1, 500, 0.070017 +127.0.0.1, 2018-09-23 20:32:46, GET, /SP, HTTP/1.1, 200, 0.038853 +127.0.0.1, 2018-09-23 20:32:46, GET, /SP/default/user/login, HTTP/1.1, 303, 0.046642 +127.0.0.1, 2018-09-23 20:32:47, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.054286 +127.0.0.1, 2018-09-23 20:32:47, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.064828 +127.0.0.1, 2018-09-23 20:32:53, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.045015 +127.0.0.1, 2018-09-23 20:32:53, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063339 +127.0.0.1, 2018-09-23 20:32:55, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.042165 +127.0.0.1, 2018-09-23 20:32:56, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.058421 +127.0.0.1, 2018-09-23 20:32:57, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.037172 +127.0.0.1, 2018-09-23 20:32:57, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061381 +127.0.0.1, 2018-09-23 20:33:04, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.039396 +127.0.0.1, 2018-09-23 20:33:10, POST, /SP/appadmin/select/db, HTTP/1.1, 200, 0.036342 +127.0.0.1, 2018-09-23 20:33:17, POST, /SP/appadmin/select/db, HTTP/1.1, 200, 0.060891 +127.0.0.1, 2018-09-23 20:33:23, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.037110 +127.0.0.1, 2018-09-23 20:33:23, GET, /SP/static/images/favicon.ico, HTTP/1.1, 304, 0.000385 +127.0.0.1, 2018-09-23 20:33:45, POST, /SP/appadmin/select/db, HTTP/1.1, 200, 0.038009 +127.0.0.1, 2018-09-23 20:33:54, GET, /, HTTP/1.1, 303, 0.001087 +127.0.0.1, 2018-09-23 20:33:54, GET, /welcome/default/index, HTTP/1.1, 200, 0.030504 +127.0.0.1, 2018-09-23 20:33:55, GET, /SP, HTTP/1.1, 200, 0.025187 +127.0.0.1, 2018-09-23 20:33:55, GET, /SP, HTTP/1.1, 200, 0.029962 +127.0.0.1, 2018-09-23 20:34:00, GET, /SP/default/user/logout, HTTP/1.1, 303, 0.027784 +127.0.0.1, 2018-09-23 20:34:00, GET, /SP/default/index, HTTP/1.1, 200, 0.028586 +127.0.0.1, 2018-09-23 20:34:02, GET, /SP/default/user/login, HTTP/1.1, 200, 0.031444 +127.0.0.1, 2018-09-23 20:34:07, POST, /SP/default/user/login, HTTP/1.1, 303, 0.019094 +127.0.0.1, 2018-09-23 20:34:07, GET, /SP/default/user/login, HTTP/1.1, 200, 0.024918 +127.0.0.1, 2018-09-23 20:34:19, POST, /SP/default/user/login, HTTP/1.1, 200, 0.027649 +127.0.0.1, 2018-09-23 20:34:26, POST, /SP/default/user/login, HTTP/1.1, 303, 0.018886 +127.0.0.1, 2018-09-23 20:34:26, GET, /SP/default/user/login, HTTP/1.1, 200, 0.025877 +127.0.0.1, 2018-09-23 20:35:43, GET, /SP/default/user/login, HTTP/1.1, 200, 0.037515 +127.0.0.1, 2018-09-23 20:35:44, GET, /SP/default/user/register, HTTP/1.1, 200, 0.026432 +127.0.0.1, 2018-09-23 20:36:11, POST, /SP/default/user/register, HTTP/1.1, 303, 0.029794 +127.0.0.1, 2018-09-23 20:36:11, GET, /SP/default/index, HTTP/1.1, 200, 0.028281 +127.0.0.1, 2018-09-23 20:36:16, GET, /SP/default/user/logout, HTTP/1.1, 303, 0.019848 +127.0.0.1, 2018-09-23 20:36:16, GET, /SP/default/index, HTTP/1.1, 200, 0.031602 +127.0.0.1, 2018-09-23 20:36:18, GET, /SP/default/user/login, HTTP/1.1, 200, 0.029032 +127.0.0.1, 2018-09-23 20:36:27, POST, /SP/default/user/login, HTTP/1.1, 303, 0.019293 +127.0.0.1, 2018-09-23 20:36:27, GET, /SP/default/user/login, HTTP/1.1, 200, 0.023138 +127.0.0.1, 2018-09-23 21:02:07, GET, /SP/default/user/login, HTTP/1.1, 500, 5.129341 +127.0.0.1, 2018-09-23 21:02:12, GET, /SP/default/user/login, HTTP/1.1, 500, 5.431067 +127.0.0.1, 2018-09-23 21:02:12, GET, /favicon.ico, HTTP/1.1, 400, 0.000335 +127.0.0.1, 2018-09-23 21:02:14, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-02-07.fd4ace61-2bd0-41c6-99ae-c2700d2b078a, HTTP/1.1, 200, 0.036360 +127.0.0.1, 2018-09-23 21:02:14, GET, /favicon.ico, HTTP/1.1, 400, 0.000446 +127.0.0.1, 2018-09-23 21:03:33, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-02-07.fd4ace61-2bd0-41c6-99ae-c2700d2b078a, HTTP/1.1, 200, 0.031705 +127.0.0.1, 2018-09-23 21:03:34, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-02-07.fd4ace61-2bd0-41c6-99ae-c2700d2b078a, HTTP/1.1, 200, 0.030852 +127.0.0.1, 2018-09-23 21:03:41, GET, /SP/default/user/login, HTTP/1.1, 500, 5.092044 +127.0.0.1, 2018-09-23 21:03:43, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-03-36.59e9c8bd-1146-4be6-9401-294912f73db5, HTTP/1.1, 200, 0.028544 +127.0.0.1, 2018-09-23 21:03:43, GET, /favicon.ico, HTTP/1.1, 400, 0.000694 +127.0.0.1, 2018-09-23 21:07:08, GET, /SP/default/user/login, HTTP/1.1, 500, 5.066670 +127.0.0.1, 2018-09-23 21:07:09, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-07-02.01e76216-c3bb-4665-85e7-5e6e9f39340d, HTTP/1.1, 200, 0.044597 +127.0.0.1, 2018-09-23 21:07:09, GET, /favicon.ico, HTTP/1.1, 400, 0.000751 +127.0.0.1, 2018-09-23 21:15:17, GET, /SP/default/user/login, HTTP/1.1, 500, 5.070051 +127.0.0.1, 2018-09-23 21:15:18, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-15-12.b3c35513-a088-42d2-ba59-6e7b9c782316, HTTP/1.1, 200, 0.036888 +127.0.0.1, 2018-09-23 21:15:18, GET, /favicon.ico, HTTP/1.1, 400, 0.000556 +127.0.0.1, 2018-09-23 21:20:18, GET, /SP/default/user/login, HTTP/1.1, 500, 5.075546 +127.0.0.1, 2018-09-23 21:20:24, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-20-13.c387dc8d-1ab5-4c8a-adf0-5c8d3995af73, HTTP/1.1, 200, 0.033362 +127.0.0.1, 2018-09-23 21:20:24, GET, /favicon.ico, HTTP/1.1, 400, 0.000479 +127.0.0.1, 2018-09-23 21:21:14, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-20-13.c387dc8d-1ab5-4c8a-adf0-5c8d3995af73, HTTP/1.1, 200, 0.025139 +127.0.0.1, 2018-09-23 21:21:16, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-20-13.c387dc8d-1ab5-4c8a-adf0-5c8d3995af73, HTTP/1.1, 200, 0.026557 +127.0.0.1, 2018-09-23 21:21:23, GET, /SP/default/user/login, HTTP/1.1, 500, 5.070093 +127.0.0.1, 2018-09-23 21:21:25, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-21-18.2de1bbbf-d96a-4478-be19-d65c64d8d855, HTTP/1.1, 200, 0.033533 +127.0.0.1, 2018-09-23 21:21:25, GET, /favicon.ico, HTTP/1.1, 400, 0.000384 +127.0.0.1, 2018-09-23 21:23:53, GET, /SP/default/user/login, HTTP/1.1, 500, 5.064581 +127.0.0.1, 2018-09-23 21:24:28, GET, /SP/default/user/login, HTTP/1.1, 500, 5.064855 +127.0.0.1, 2018-09-23 21:24:33, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-24-23.9f96565e-6e8c-47f5-ba6a-5778d179287c, HTTP/1.1, 200, 0.029978 +127.0.0.1, 2018-09-23 21:24:33, GET, /favicon.ico, HTTP/1.1, 400, 0.000394 +127.0.0.1, 2018-09-23 21:25:25, GET, /SP/default/user/login, HTTP/1.1, 200, 0.038283 +127.0.0.1, 2018-09-23 21:25:51, GET, /SP/default/user/login, HTTP/1.1, 200, 0.024364 +127.0.0.1, 2018-09-23 21:25:54, GET, /SP/default/user/register, HTTP/1.1, 200, 0.029474 +127.0.0.1, 2018-09-23 21:26:17, POST, /SP/default/user/register, HTTP/1.1, 303, 0.040958 +127.0.0.1, 2018-09-23 21:26:17, GET, /SP/default/index, HTTP/1.1, 200, 0.023563 +127.0.0.1, 2018-09-23 21:26:19, GET, /SP/default/myhome, HTTP/1.1, 500, 0.052834 +127.0.0.1, 2018-09-23 21:26:21, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-26-19.bbd61739-7ba5-4a26-904b-d4538eb0ab77, HTTP/1.1, 200, 0.034968 +127.0.0.1, 2018-09-23 21:26:21, GET, /favicon.ico, HTTP/1.1, 400, 0.000429 +127.0.0.1, 2018-09-23 21:29:00, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-26-19.bbd61739-7ba5-4a26-904b-d4538eb0ab77, HTTP/1.1, 200, 0.025631 +127.0.0.1, 2018-09-23 21:29:01, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-26-19.bbd61739-7ba5-4a26-904b-d4538eb0ab77, HTTP/1.1, 200, 0.026068 +127.0.0.1, 2018-09-23 21:29:02, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-26-19.bbd61739-7ba5-4a26-904b-d4538eb0ab77, HTTP/1.1, 200, 0.023390 +127.0.0.1, 2018-09-23 21:29:04, GET, /SP/default/myhome, HTTP/1.1, 500, 0.041440 +127.0.0.1, 2018-09-23 21:29:06, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-29-04.a76c77d4-350b-49ac-8234-514173e08b4d, HTTP/1.1, 200, 0.029833 +127.0.0.1, 2018-09-23 21:29:07, GET, /favicon.ico, HTTP/1.1, 400, 0.000320 +127.0.0.1, 2018-09-23 21:29:39, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-29-04.a76c77d4-350b-49ac-8234-514173e08b4d, HTTP/1.1, 200, 0.030433 +127.0.0.1, 2018-09-23 21:29:41, GET, /SP/default/myhome, HTTP/1.1, 500, 0.053924 +127.0.0.1, 2018-09-23 21:30:07, GET, /SP/default/myhome, HTTP/1.1, 500, 0.122949 +127.0.0.1, 2018-09-23 21:30:32, GET, /SP/default/myhome, HTTP/1.1, 200, 0.029393 +127.0.0.1, 2018-09-23 21:30:42, GET, /SP/default/myhome, HTTP/1.1, 200, 0.025203 +127.0.0.1, 2018-09-23 21:31:03, GET, /admin/default/site, HTTP/1.1, 200, 0.047093 +127.0.0.1, 2018-09-23 21:31:04, POST, /admin/default/check_version, HTTP/1.1, 200, 0.854232 +127.0.0.1, 2018-09-23 21:31:06, GET, /admin/default/design/examples, HTTP/1.1, 200, 0.165347 +127.0.0.1, 2018-09-23 21:31:06, GET, /favicon.ico, HTTP/1.1, 400, 0.000234 +127.0.0.1, 2018-09-23 21:31:13, GET, /SP/default/index, HTTP/1.1, 200, 0.023623 +127.0.0.1, 2018-09-23 21:31:22, GET, /SP/default/index, HTTP/1.1, 200, 0.031905 +127.0.0.1, 2018-09-23 21:31:22, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 200, 0.000960 +127.0.0.1, 2018-09-23 21:31:22, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 200, 0.002112 +127.0.0.1, 2018-09-23 21:31:22, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 200, 0.002038 +127.0.0.1, 2018-09-23 21:31:22, GET, /SP/static/css/calendar.css, HTTP/1.1, 200, 0.001153 +127.0.0.1, 2018-09-23 21:31:22, GET, /SP/static/js/jquery.js, HTTP/1.1, 200, 0.003281 +127.0.0.1, 2018-09-23 21:31:22, GET, /SP/static/js/calendar.js, HTTP/1.1, 200, 0.001964 +127.0.0.1, 2018-09-23 21:31:22, GET, /SP/static/js/web2py.js, HTTP/1.1, 200, 0.002540 +127.0.0.1, 2018-09-23 21:31:22, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 200, 0.001341 +127.0.0.1, 2018-09-23 21:31:22, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 200, 0.001410 +127.0.0.1, 2018-09-23 21:31:23, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000688 +127.0.0.1, 2018-09-23 21:31:27, GET, /SP/static/js/bootstrap.bundle.min.js.map, HTTP/1.1, 200, 0.000844 +127.0.0.1, 2018-09-23 21:31:27, GET, /SP/static/css/bootstrap.min.css.map, HTTP/1.1, 200, 0.000605 +127.0.0.1, 2018-09-23 21:34:08, GET, /SP/default/index, HTTP/1.1, 200, 0.043529 +127.0.0.1, 2018-09-23 21:34:12, GET, /SP/default/myhome, HTTP/1.1, 303, 0.020573 +127.0.0.1, 2018-09-23 21:34:12, GET, /SP/default/user/login, HTTP/1.1, 200, 0.025143 +127.0.0.1, 2018-09-23 21:34:23, POST, /SP/default/user/login, HTTP/1.1, 303, 0.038826 +127.0.0.1, 2018-09-23 21:34:23, GET, /SP/default/myhome, HTTP/1.1, 200, 0.023219 +127.0.0.1, 2018-09-23 21:34:37, GET, /SP/default/URL('default'%2C'change_settings'), HTTP/1.1, 404, 0.021727 +127.0.0.1, 2018-09-23 21:34:38, GET, /favicon.ico, HTTP/1.1, 400, 0.000313 +127.0.0.1, 2018-09-23 21:34:41, GET, /SP/default/myhome, HTTP/1.1, 200, 0.024838 +127.0.0.1, 2018-09-23 21:34:43, GET, /SP/default/URL('default'%2C'change_settings'), HTTP/1.1, 404, 0.025560 +127.0.0.1, 2018-09-23 21:34:43, GET, /favicon.ico, HTTP/1.1, 400, 0.000207 +127.0.0.1, 2018-09-23 21:34:45, GET, /SP/default/myhome, HTTP/1.1, 200, 0.030291 +127.0.0.1, 2018-09-23 21:34:58, GET, /SP/default/myhome, HTTP/1.1, 500, 0.048899 +127.0.0.1, 2018-09-23 21:34:59, GET, /favicon.ico, HTTP/1.1, 400, 0.000388 +127.0.0.1, 2018-09-23 21:35:00, GET, /SP/default/user/login, HTTP/1.1, 303, 0.025172 +127.0.0.1, 2018-09-23 21:35:00, GET, /favicon.ico, HTTP/1.1, 400, 0.000236 +127.0.0.1, 2018-09-23 21:35:01, GET, /SP/default/index, HTTP/1.1, 200, 0.033491 +127.0.0.1, 2018-09-23 21:35:03, GET, /favicon.ico, HTTP/1.1, 400, 0.000203 +127.0.0.1, 2018-09-23 21:35:04, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-34-58.2919a1e8-b4f0-4b65-8545-3348930435bd, HTTP/1.1, 303, 0.006408 +127.0.0.1, 2018-09-23 21:35:04, GET, /admin/default/index, HTTP/1.1, 200, 0.021870 +127.0.0.1, 2018-09-23 21:35:04, GET, /favicon.ico, HTTP/1.1, 400, 0.000481 +127.0.0.1, 2018-09-23 21:35:07, POST, /admin/default/index, HTTP/1.1, 303, 0.014924 +127.0.0.1, 2018-09-23 21:35:07, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-34-58.2919a1e8-b4f0-4b65-8545-3348930435bd, HTTP/1.1, 200, 0.028597 +127.0.0.1, 2018-09-23 21:35:07, GET, /favicon.ico, HTTP/1.1, 400, 0.000221 +127.0.0.1, 2018-09-23 21:36:06, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-34-58.2919a1e8-b4f0-4b65-8545-3348930435bd, HTTP/1.1, 200, 0.029113 +127.0.0.1, 2018-09-23 21:36:07, GET, /favicon.ico, HTTP/1.1, 400, 0.000655 +127.0.0.1, 2018-09-23 21:36:10, GET, /SP/default/myhome, HTTP/1.1, 200, 0.037920 +127.0.0.1, 2018-09-23 21:36:10, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000638 +127.0.0.1, 2018-09-23 21:36:12, GET, /SP/default/change_settings), HTTP/1.1, 200, 0.022995 +127.0.0.1, 2018-09-23 21:36:12, GET, /favicon.ico, HTTP/1.1, 400, 0.000244 +127.0.0.1, 2018-09-23 21:36:15, GET, /SP/default/myhome, HTTP/1.1, 200, 0.024173 +127.0.0.1, 2018-09-23 21:36:22, GET, /SP/default/change_settings), HTTP/1.1, 200, 0.022609 +127.0.0.1, 2018-09-23 21:36:22, GET, /favicon.ico, HTTP/1.1, 400, 0.000198 +127.0.0.1, 2018-09-23 21:36:24, GET, /SP/default/myhome, HTTP/1.1, 200, 0.023493 +127.0.0.1, 2018-09-23 21:36:38, GET, /SP/default/myhome, HTTP/1.1, 200, 0.023170 +127.0.0.1, 2018-09-23 21:36:38, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000678 +127.0.0.1, 2018-09-23 21:36:39, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.027050 +127.0.0.1, 2018-09-23 21:36:39, GET, /favicon.ico, HTTP/1.1, 400, 0.000216 +127.0.0.1, 2018-09-23 21:36:40, GET, /SP/default/myhome, HTTP/1.1, 200, 0.034427 +127.0.0.1, 2018-09-23 21:37:06, GET, /SP/default/myhome, HTTP/1.1, 200, 0.026333 +127.0.0.1, 2018-09-23 21:37:07, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000574 +127.0.0.1, 2018-09-23 21:37:07, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.029242 +127.0.0.1, 2018-09-23 21:37:10, GET, /SP/default/myhome, HTTP/1.1, 200, 0.026637 +127.0.0.1, 2018-09-23 21:37:12, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.026478 +127.0.0.1, 2018-09-23 21:37:13, GET, /SP/default/myhome, HTTP/1.1, 200, 0.022757 +127.0.0.1, 2018-09-23 21:41:12, GET, /SP/default/myhome, HTTP/1.1, 200, 0.029224 +127.0.0.1, 2018-09-23 21:41:12, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000616 +127.0.0.1, 2018-09-23 21:41:13, GET, /SP/default/change_settings, HTTP/1.1, 500, 0.047380 +127.0.0.1, 2018-09-23 21:41:13, GET, /favicon.ico, HTTP/1.1, 400, 0.000198 +127.0.0.1, 2018-09-23 21:41:15, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-41-13.a240c4ba-af3f-496b-b49f-edc5be6ca5f6, HTTP/1.1, 200, 0.029069 +127.0.0.1, 2018-09-23 21:41:15, GET, /favicon.ico, HTTP/1.1, 400, 0.000205 +127.0.0.1, 2018-09-23 21:41:51, GET, /SP/default/change_settings, HTTP/1.1, 500, 0.050111 +127.0.0.1, 2018-09-23 21:41:51, GET, /favicon.ico, HTTP/1.1, 400, 0.000277 +127.0.0.1, 2018-09-23 21:42:29, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.032356 +127.0.0.1, 2018-09-23 21:42:30, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000452 +127.0.0.1, 2018-09-23 21:42:41, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.034175 +127.0.0.1, 2018-09-23 21:42:41, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000663 +127.0.0.1, 2018-09-23 21:43:23, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.034601 +127.0.0.1, 2018-09-23 21:43:24, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000507 +127.0.0.1, 2018-09-23 21:44:16, GET, /SP/default/index, HTTP/1.1, 200, 0.036242 +127.0.0.1, 2018-09-23 21:44:17, GET, /SP/default/myhome, HTTP/1.1, 200, 0.064528 +127.0.0.1, 2018-09-23 21:44:19, GET, /SP/default/myclass, HTTP/1.1, 500, 0.041407 +127.0.0.1, 2018-09-23 21:44:19, GET, /favicon.ico, HTTP/1.1, 400, 0.000216 +127.0.0.1, 2018-09-23 21:44:23, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-44-19.6909fe36-2c71-4e6b-801b-4b10c6639104, HTTP/1.1, 200, 0.043674 +127.0.0.1, 2018-09-23 21:44:23, GET, /favicon.ico, HTTP/1.1, 400, 0.000230 +127.0.0.1, 2018-09-23 21:45:01, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-44-19.6909fe36-2c71-4e6b-801b-4b10c6639104, HTTP/1.1, 200, 0.035282 +127.0.0.1, 2018-09-23 21:45:02, GET, /favicon.ico, HTTP/1.1, 400, 0.000221 +127.0.0.1, 2018-09-23 21:45:16, GET, /SP/default/myclass, HTTP/1.1, 200, 0.037813 +127.0.0.1, 2018-09-23 21:45:32, GET, /SP/default/myhome, HTTP/1.1, 200, 0.035464 +127.0.0.1, 2018-09-23 21:45:33, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.030066 +127.0.0.1, 2018-09-23 21:45:35, GET, /SP/default/myhome, HTTP/1.1, 200, 0.034496 +127.0.0.1, 2018-09-23 21:45:37, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.032602 +127.0.0.1, 2018-09-23 21:45:39, GET, /SP/default/myhome, HTTP/1.1, 200, 0.052687 +127.0.0.1, 2018-09-23 21:45:46, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.027179 +127.0.0.1, 2018-09-23 21:45:48, GET, /SP/default/myhome, HTTP/1.1, 200, 0.026139 +127.0.0.1, 2018-09-23 21:54:30, GET, /admin/default/site, HTTP/1.1, 200, 0.031852 +127.0.0.1, 2018-09-23 21:54:30, GET, /admin/static/_2.17.1/images/folder.png, HTTP/1.1, 200, 0.001841 +127.0.0.1, 2018-09-23 21:54:30, GET, /admin/static/_2.17.1/images/folder_locked.png, HTTP/1.1, 200, 0.001581 +127.0.0.1, 2018-09-23 21:54:30, GET, /admin/static/_2.17.1/images/glyphicons-halflings-white.png, HTTP/1.1, 200, 0.001291 +127.0.0.1, 2018-09-23 21:54:30, POST, /admin/default/check_version, HTTP/1.1, 200, 0.547963 +127.0.0.1, 2018-09-23 21:54:33, GET, /favicon.ico, HTTP/1.1, 400, 0.000202 +127.0.0.1, 2018-09-23 21:54:38, GET, /admin/default/design/examples, HTTP/1.1, 200, 0.157654 +127.0.0.1, 2018-09-23 21:54:38, GET, /favicon.ico, HTTP/1.1, 400, 0.000307 +127.0.0.1, 2018-09-23 21:58:26, GET, /SP/default/myhome, HTTP/1.1, 200, 0.037355 +127.0.0.1, 2018-09-23 21:58:26, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000847 +127.0.0.1, 2018-09-23 21:58:28, GET, /SP/default/myclass, HTTP/1.1, 500, 0.045330 +127.0.0.1, 2018-09-23 21:58:28, GET, /favicon.ico, HTTP/1.1, 400, 0.000214 +127.0.0.1, 2018-09-23 21:58:29, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-58-28.cc9c6866-9411-43a0-bfd3-f5c184e91df2, HTTP/1.1, 200, 0.032174 +127.0.0.1, 2018-09-23 21:58:29, GET, /favicon.ico, HTTP/1.1, 400, 0.000266 +127.0.0.1, 2018-09-23 21:59:27, GET, /SP/default/myclass, HTTP/1.1, 500, 0.041909 +127.0.0.1, 2018-09-23 21:59:27, GET, /favicon.ico, HTTP/1.1, 400, 0.000294 +127.0.0.1, 2018-09-23 21:59:28, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-59-26.5cda7368-af7e-4821-9551-e4a63c66515c, HTTP/1.1, 200, 0.029834 +127.0.0.1, 2018-09-23 21:59:28, GET, /favicon.ico, HTTP/1.1, 400, 0.000234 +127.0.0.1, 2018-09-23 21:59:58, GET, /SP/default/myclass, HTTP/1.1, 500, 0.040569 +127.0.0.1, 2018-09-23 21:59:58, GET, /favicon.ico, HTTP/1.1, 400, 0.000440 +127.0.0.1, 2018-09-23 21:59:59, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-59-58.c999da0e-6456-442d-8965-cc2de92f0a24, HTTP/1.1, 200, 0.034456 +127.0.0.1, 2018-09-23 21:59:59, GET, /favicon.ico, HTTP/1.1, 400, 0.000227 +127.0.0.1, 2018-09-23 22:00:25, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.21-59-58.c999da0e-6456-442d-8965-cc2de92f0a24, HTTP/1.1, 200, 0.029247 +127.0.0.1, 2018-09-23 22:00:25, GET, /favicon.ico, HTTP/1.1, 400, 0.000225 +127.0.0.1, 2018-09-23 22:00:32, GET, /SP/default/myclass, HTTP/1.1, 500, 0.067262 +127.0.0.1, 2018-09-23 22:00:32, GET, /favicon.ico, HTTP/1.1, 400, 0.000388 +127.0.0.1, 2018-09-23 22:00:33, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.22-00-32.059eb584-594d-442d-aa10-39e01d88bd38, HTTP/1.1, 200, 0.082912 +127.0.0.1, 2018-09-23 22:00:34, GET, /favicon.ico, HTTP/1.1, 400, 0.000202 +127.0.0.1, 2018-09-23 22:01:09, GET, /SP/default/myclass, HTTP/1.1, 200, 0.037080 +127.0.0.1, 2018-09-23 22:01:10, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000428 +127.0.0.1, 2018-09-23 22:03:06, GET, /SP/default/myclass, HTTP/1.1, 200, 0.035783 +127.0.0.1, 2018-09-23 22:03:06, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000385 +127.0.0.1, 2018-09-23 22:05:20, GET, /SP/default/myclass, HTTP/1.1, 200, 0.039484 +127.0.0.1, 2018-09-23 22:05:20, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000723 +127.0.0.1, 2018-09-23 22:05:37, GET, /SP/default/myclass, HTTP/1.1, 500, 0.055230 +127.0.0.1, 2018-09-23 22:05:37, GET, /favicon.ico, HTTP/1.1, 400, 0.000445 +127.0.0.1, 2018-09-23 22:05:41, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.22-05-37.47604380-9ee5-49b0-9cf3-91702816db8b, HTTP/1.1, 200, 0.072922 +127.0.0.1, 2018-09-23 22:05:41, GET, /favicon.ico, HTTP/1.1, 400, 0.000315 +127.0.0.1, 2018-09-23 22:06:36, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.22-05-37.47604380-9ee5-49b0-9cf3-91702816db8b, HTTP/1.1, 200, 0.065548 +127.0.0.1, 2018-09-23 22:06:37, GET, /favicon.ico, HTTP/1.1, 400, 0.000248 +127.0.0.1, 2018-09-23 22:06:40, GET, /SP/default/myclass, HTTP/1.1, 500, 0.063956 +127.0.0.1, 2018-09-23 22:06:40, GET, /favicon.ico, HTTP/1.1, 400, 0.000690 +127.0.0.1, 2018-09-23 22:06:41, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.22-06-39.dacbe8e8-e39b-4bfa-9402-ad6667d992a9, HTTP/1.1, 200, 0.063685 +127.0.0.1, 2018-09-23 22:06:41, GET, /favicon.ico, HTTP/1.1, 400, 0.000207 +127.0.0.1, 2018-09-23 22:06:54, GET, /SP/default/myclass, HTTP/1.1, 500, 0.056392 +127.0.0.1, 2018-09-23 22:06:55, GET, /favicon.ico, HTTP/1.1, 400, 0.000230 +127.0.0.1, 2018-09-23 22:06:56, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.22-06-54.01d228ed-55a4-482f-9d85-799e46d8f496, HTTP/1.1, 200, 0.060664 +127.0.0.1, 2018-09-23 22:06:56, GET, /favicon.ico, HTTP/1.1, 400, 0.000319 +127.0.0.1, 2018-09-23 22:07:24, GET, /SP/default/myclass, HTTP/1.1, 500, 0.049427 +127.0.0.1, 2018-09-23 22:07:24, GET, /favicon.ico, HTTP/1.1, 400, 0.000517 +127.0.0.1, 2018-09-23 22:07:32, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.22-07-24.9e28c885-9705-42f7-a586-8e8bf33058fe, HTTP/1.1, 200, 0.037329 +127.0.0.1, 2018-09-23 22:07:32, GET, /favicon.ico, HTTP/1.1, 400, 0.000392 +127.0.0.1, 2018-09-23 22:07:40, GET, /SP/default/myclass, HTTP/1.1, 500, 0.060301 +127.0.0.1, 2018-09-23 22:07:40, GET, /favicon.ico, HTTP/1.1, 400, 0.000251 +127.0.0.1, 2018-09-23 22:07:53, GET, /SP/default/myclass, HTTP/1.1, 500, 0.053691 +127.0.0.1, 2018-09-23 22:07:53, GET, /favicon.ico, HTTP/1.1, 400, 0.000390 +127.0.0.1, 2018-09-23 22:07:54, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.22-07-53.849ed3c0-87a0-417c-8c75-9df7f330e7b5, HTTP/1.1, 200, 0.070298 +127.0.0.1, 2018-09-23 22:07:54, GET, /favicon.ico, HTTP/1.1, 400, 0.000254 +127.0.0.1, 2018-09-23 22:08:03, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.22-07-53.849ed3c0-87a0-417c-8c75-9df7f330e7b5, HTTP/1.1, 200, 0.065749 +127.0.0.1, 2018-09-23 22:08:03, GET, /favicon.ico, HTTP/1.1, 400, 0.000258 +127.0.0.1, 2018-09-23 22:08:05, GET, /SP/default/myclass, HTTP/1.1, 500, 0.054604 +127.0.0.1, 2018-09-23 22:08:05, GET, /favicon.ico, HTTP/1.1, 400, 0.000413 +127.0.0.1, 2018-09-23 22:08:06, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-23.22-08-05.1b7ec789-952e-4ecf-bcc8-60b1631f8b81, HTTP/1.1, 200, 0.069945 +127.0.0.1, 2018-09-23 22:08:06, GET, /favicon.ico, HTTP/1.1, 400, 0.000224 +127.0.0.1, 2018-09-23 22:08:47, GET, /SP/default/myclass, HTTP/1.1, 200, 0.115325 +127.0.0.1, 2018-09-23 22:08:47, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000659 +127.0.0.1, 2018-09-23 22:09:46, GET, /SP/default/myclass, HTTP/1.1, 200, 0.037215 +127.0.0.1, 2018-09-23 22:09:47, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001131 +127.0.0.1, 2018-09-23 22:10:02, GET, /SP/default/myclass, HTTP/1.1, 200, 0.030326 +127.0.0.1, 2018-09-23 22:10:02, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000767 +127.0.0.1, 2018-09-23 22:10:13, GET, /SP/default/myclass, HTTP/1.1, 200, 0.036093 +127.0.0.1, 2018-09-23 22:10:14, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000765 +127.0.0.1, 2018-09-23 22:10:28, GET, /SP/default/myhome, HTTP/1.1, 200, 0.038286 +127.0.0.1, 2018-09-23 22:10:37, GET, /SP/private/home, HTTP/1.1, 404, 0.025490 +127.0.0.1, 2018-09-23 22:10:37, GET, /favicon.ico, HTTP/1.1, 400, 0.000214 +127.0.0.1, 2018-09-23 22:10:39, GET, /SP/default/myhome, HTTP/1.1, 200, 0.031632 +127.0.0.1, 2018-09-23 22:12:12, GET, /SP/default/myclass, HTTP/1.1, 200, 0.037494 +127.0.0.1, 2018-09-23 22:12:15, GET, /SP/private/home, HTTP/1.1, 404, 0.016746 +127.0.0.1, 2018-09-23 22:12:15, GET, /favicon.ico, HTTP/1.1, 400, 0.000347 +127.0.0.1, 2018-09-23 22:12:17, GET, /SP/default/myclass, HTTP/1.1, 200, 0.034339 +127.0.0.1, 2018-09-23 22:23:53, GET, /SP/default/myhome, HTTP/1.1, 200, 0.045508 +127.0.0.1, 2018-09-23 22:23:56, GET, /SP/default/myhome, HTTP/1.1, 200, 0.027722 +127.0.0.1, 2018-09-23 22:23:59, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.028237 +127.0.0.1, 2018-09-23 22:24:01, GET, /SP/default/myclass, HTTP/1.1, 200, 0.065311 +127.0.0.1, 2018-09-23 22:24:06, GET, /SP/private/home, HTTP/1.1, 404, 0.017494 +127.0.0.1, 2018-09-23 22:24:06, GET, /favicon.ico, HTTP/1.1, 400, 0.000197 +127.0.0.1, 2018-09-23 22:24:08, GET, /SP/default/myclass, HTTP/1.1, 200, 0.029570 +127.0.0.1, 2018-09-23 22:24:10, GET, /SP/default/index, HTTP/1.1, 200, 0.030240 +127.0.0.1, 2018-09-23 22:24:12, GET, /SP/default/myclass, HTTP/1.1, 200, 0.025527 +127.0.0.1, 2018-09-23 22:36:19, GET, /SP/default/myhome, HTTP/1.1, 303, 0.035032 +127.0.0.1, 2018-09-23 22:36:19, GET, /SP/default/user/login, HTTP/1.1, 200, 0.029762 +127.0.0.1, 2018-09-23 22:36:22, GET, /SP/default/user/register, HTTP/1.1, 200, 0.037028 +127.0.0.1, 2018-09-24 07:17:34, GET, /SP/default/myclass, HTTP/1.1, 200, 0.085062 +127.0.0.1, 2018-09-24 07:17:34, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.002843 +127.0.0.1, 2018-09-24 07:17:34, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.003876 +127.0.0.1, 2018-09-24 07:17:34, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.003822 +127.0.0.1, 2018-09-24 07:17:34, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.002044 +127.0.0.1, 2018-09-24 07:17:34, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.001914 +127.0.0.1, 2018-09-24 07:17:34, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.002566 +127.0.0.1, 2018-09-24 07:17:34, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.001026 +127.0.0.1, 2018-09-24 07:17:34, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.001607 +127.0.0.1, 2018-09-24 07:17:34, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.007510 +127.0.0.1, 2018-09-24 07:17:35, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000658 +127.0.0.1, 2018-09-24 07:18:24, GET, /SP/default/myhome, HTTP/1.1, 303, 0.042166 +127.0.0.1, 2018-09-24 07:18:24, GET, /SP/default/myhome, HTTP/1.1, 303, 0.041192 +127.0.0.1, 2018-09-24 07:18:24, GET, /SP/default/user/login, HTTP/1.1, 200, 0.028449 +127.0.0.1, 2018-09-24 07:18:26, GET, /SP/default/myclass, HTTP/1.1, 200, 0.028961 +127.0.0.1, 2018-09-24 07:18:43, GET, /admin/default/site, HTTP/1.1, 303, 0.007200 +127.0.0.1, 2018-09-24 07:18:43, GET, /admin/default/index, HTTP/1.1, 200, 0.022324 +127.0.0.1, 2018-09-24 07:18:43, GET, /favicon.ico, HTTP/1.1, 400, 0.000289 +127.0.0.1, 2018-09-24 07:18:55, POST, /admin/default/index, HTTP/1.1, 303, 0.020476 +127.0.0.1, 2018-09-24 07:18:55, GET, /admin/default/site, HTTP/1.1, 200, 0.037699 +127.0.0.1, 2018-09-24 07:18:56, POST, /admin/default/check_version, HTTP/1.1, 200, 0.797377 +127.0.0.1, 2018-09-24 07:18:56, GET, /favicon.ico, HTTP/1.1, 400, 0.000310 +127.0.0.1, 2018-09-24 07:19:10, GET, /SP/private/home, HTTP/1.1, 404, 0.019913 +127.0.0.1, 2018-09-24 07:19:10, GET, /favicon.ico, HTTP/1.1, 400, 0.000476 +127.0.0.1, 2018-09-24 07:19:12, GET, /SP/default/myclass, HTTP/1.1, 200, 0.023147 +127.0.0.1, 2018-09-24 07:19:16, GET, /SP/default/myhome, HTTP/1.1, 303, 0.020307 +127.0.0.1, 2018-09-24 07:19:16, GET, /SP/default/user/login, HTTP/1.1, 200, 0.023470 +127.0.0.1, 2018-09-24 07:19:24, POST, /SP/default/user/login, HTTP/1.1, 303, 0.028423 +127.0.0.1, 2018-09-24 07:19:24, GET, /SP/default/myhome, HTTP/1.1, 200, 0.023380 +127.0.0.1, 2018-09-24 07:19:34, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.028012 +127.0.0.1, 2018-09-24 07:19:36, GET, /SP/default/myhome, HTTP/1.1, 200, 0.026649 +127.0.0.1, 2018-09-24 07:19:39, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.031040 +127.0.0.1, 2018-09-24 07:19:42, GET, /SP/default/myhome, HTTP/1.1, 200, 0.043538 +127.0.0.1, 2018-09-24 07:19:50, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.027675 +127.0.0.1, 2018-09-24 07:19:52, GET, /SP/default/myhome, HTTP/1.1, 200, 0.030994 +127.0.0.1, 2018-09-24 07:22:13, GET, /SP/default/myhome, HTTP/1.1, 200, 0.026116 +127.0.0.1, 2018-09-24 07:22:13, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000773 +127.0.0.1, 2018-09-24 07:22:15, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.055455 +127.0.0.1, 2018-09-24 07:23:28, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.025966 +127.0.0.1, 2018-09-24 07:23:28, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000764 +127.0.0.1, 2018-09-24 07:23:33, GET, /SP/default/myhome, HTTP/1.1, 200, 0.026911 +127.0.0.1, 2018-09-24 07:26:02, GET, /admin/default/site, HTTP/1.1, 200, 0.027667 +127.0.0.1, 2018-09-24 07:26:02, GET, /favicon.ico, HTTP/1.1, 400, 0.000214 +127.0.0.1, 2018-09-24 07:26:07, GET, /welcome, HTTP/1.1, 200, 0.038487 +127.0.0.1, 2018-09-24 07:26:07, GET, /welcome/static/css/calendar.css, HTTP/1.1, 304, 0.000629 +127.0.0.1, 2018-09-24 07:26:07, GET, /welcome/static/js/calendar.js, HTTP/1.1, 304, 0.000628 +127.0.0.1, 2018-09-24 07:26:07, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.000681 +127.0.0.1, 2018-09-24 07:26:07, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.000835 +127.0.0.1, 2018-09-24 07:26:07, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.002498 +127.0.0.1, 2018-09-24 07:26:07, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.003128 +127.0.0.1, 2018-09-24 07:26:07, GET, /welcome/static/js/jquery.js, HTTP/1.1, 304, 0.000549 +127.0.0.1, 2018-09-24 07:26:07, GET, /welcome/static/js/web2py.js, HTTP/1.1, 304, 0.006354 +127.0.0.1, 2018-09-24 07:26:07, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.001020 +127.0.0.1, 2018-09-24 07:26:11, GET, /welcome/static/js/bootstrap.bundle.min.js.map, HTTP/1.1, 200, 0.002190 +127.0.0.1, 2018-09-24 07:26:11, GET, /welcome/static/css/bootstrap.min.css.map, HTTP/1.1, 200, 0.001482 +127.0.0.1, 2018-09-24 07:26:21, GET, /SP/default/myhome, HTTP/1.1, 200, 0.029840 +127.0.0.1, 2018-09-24 07:26:22, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000729 +127.0.0.1, 2018-09-24 07:26:23, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.031710 +127.0.0.1, 2018-09-24 07:26:29, GET, /SP/default/myhome, HTTP/1.1, 200, 0.033054 +127.0.0.1, 2018-09-24 07:26:31, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.027665 +127.0.0.1, 2018-09-24 07:26:39, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.036690 +127.0.0.1, 2018-09-24 07:27:07, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.034366 +127.0.0.1, 2018-09-24 07:27:07, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000776 +127.0.0.1, 2018-09-24 07:27:08, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.028526 +127.0.0.1, 2018-09-24 07:27:10, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.030479 +127.0.0.1, 2018-09-24 07:27:33, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.031179 +127.0.0.1, 2018-09-24 07:27:33, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000642 +127.0.0.1, 2018-09-24 07:30:57, POST, /SP/default/change_settings, HTTP/1.1, 500, 0.084359 +127.0.0.1, 2018-09-24 07:30:57, GET, /favicon.ico, HTTP/1.1, 400, 0.000340 +127.0.0.1, 2018-09-24 07:30:59, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.07-30-57.f4714898-671c-4f2c-8b8e-7a6b8c5f06ae, HTTP/1.1, 200, 0.031184 +127.0.0.1, 2018-09-24 07:30:59, GET, /favicon.ico, HTTP/1.1, 400, 0.000288 +127.0.0.1, 2018-09-24 07:31:36, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.029881 +127.0.0.1, 2018-09-24 07:31:37, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001128 +127.0.0.1, 2018-09-24 07:31:52, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.029955 +127.0.0.1, 2018-09-24 07:31:55, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.033738 +127.0.0.1, 2018-09-24 07:33:02, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.028394 +127.0.0.1, 2018-09-24 07:33:02, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000548 +127.0.0.1, 2018-09-24 07:33:05, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.029510 +127.0.0.1, 2018-09-24 07:33:21, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.033863 +127.0.0.1, 2018-09-24 07:34:21, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.040299 +127.0.0.1, 2018-09-24 07:34:21, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000802 +127.0.0.1, 2018-09-24 07:34:23, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.030349 +127.0.0.1, 2018-09-24 07:34:27, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.026105 +127.0.0.1, 2018-09-24 07:34:27, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000559 +127.0.0.1, 2018-09-24 07:35:02, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.034047 +127.0.0.1, 2018-09-24 07:35:02, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000690 +127.0.0.1, 2018-09-24 07:35:16, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.033817 +127.0.0.1, 2018-09-24 07:37:07, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.030410 +127.0.0.1, 2018-09-24 07:37:07, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001678 +127.0.0.1, 2018-09-24 07:37:09, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.032254 +127.0.0.1, 2018-09-24 07:38:42, POST, /SP/default/change_settings, HTTP/1.1, 500, 0.137193 +127.0.0.1, 2018-09-24 07:38:43, GET, /favicon.ico, HTTP/1.1, 400, 0.000209 +127.0.0.1, 2018-09-24 07:38:45, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.07-38-42.099ed67b-9672-41ae-a0c5-0fe251bf11a9, HTTP/1.1, 200, 0.029847 +127.0.0.1, 2018-09-24 07:38:45, GET, /favicon.ico, HTTP/1.1, 400, 0.000372 +127.0.0.1, 2018-09-24 07:39:06, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.031403 +127.0.0.1, 2018-09-24 07:39:09, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.031343 +127.0.0.1, 2018-09-24 07:40:09, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.043728 +127.0.0.1, 2018-09-24 07:40:09, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.074929 +127.0.0.1, 2018-09-24 07:40:12, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.033788 +127.0.0.1, 2018-09-24 07:40:54, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.033993 +127.0.0.1, 2018-09-24 07:40:54, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000685 +127.0.0.1, 2018-09-24 07:41:04, POST, /SP/default/change_settings, HTTP/1.1, 500, 0.078347 +127.0.0.1, 2018-09-24 07:41:04, GET, /favicon.ico, HTTP/1.1, 400, 0.000211 +127.0.0.1, 2018-09-24 07:41:06, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.07-41-04.1f8690ed-aac3-4a21-b1fc-57791e303d19, HTTP/1.1, 200, 0.036459 +127.0.0.1, 2018-09-24 07:41:06, GET, /favicon.ico, HTTP/1.1, 400, 0.000213 +127.0.0.1, 2018-09-24 07:41:25, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.049017 +127.0.0.1, 2018-09-24 07:41:26, GET, /SP/default/myhome, HTTP/1.1, 200, 0.033677 +127.0.0.1, 2018-09-24 07:41:27, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.029443 +127.0.0.1, 2018-09-24 07:41:29, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.040561 +127.0.0.1, 2018-09-24 07:41:32, GET, /SP/default/myhome, HTTP/1.1, 200, 0.025536 +127.0.0.1, 2018-09-24 07:41:33, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.035384 +127.0.0.1, 2018-09-24 07:41:35, GET, /SP/default/myhome, HTTP/1.1, 200, 0.026502 +127.0.0.1, 2018-09-24 07:41:38, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.043621 +127.0.0.1, 2018-09-24 07:41:45, GET, /SP/default/myhome, HTTP/1.1, 200, 0.046701 +127.0.0.1, 2018-09-24 07:41:46, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.038050 +127.0.0.1, 2018-09-24 07:41:48, POST, /SP/default/change_settings, HTTP/1.1, 200, 0.039722 +127.0.0.1, 2018-09-24 07:41:50, GET, /SP/default/myhome, HTTP/1.1, 200, 0.030518 +127.0.0.1, 2018-09-24 07:41:52, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.029722 +127.0.0.1, 2018-09-24 07:43:47, GET, /SP/default/myhome, HTTP/1.1, 200, 0.033319 +127.0.0.1, 2018-09-24 07:43:51, GET, /SP/private/home, HTTP/1.1, 404, 0.029893 +127.0.0.1, 2018-09-24 07:43:51, GET, /favicon.ico, HTTP/1.1, 400, 0.000222 +127.0.0.1, 2018-09-24 07:43:53, GET, /SP/default/myhome, HTTP/1.1, 200, 0.029535 +127.0.0.1, 2018-09-24 07:45:09, GET, /admin/default/index, HTTP/1.1, 303, 0.008322 +127.0.0.1, 2018-09-24 07:45:09, GET, /admin/default/site, HTTP/1.1, 200, 0.033815 +127.0.0.1, 2018-09-24 07:45:10, GET, /favicon.ico, HTTP/1.1, 400, 0.000347 +127.0.0.1, 2018-09-24 07:45:12, GET, /examples/default/index, HTTP/1.1, 200, 0.015793 +127.0.0.1, 2018-09-24 07:45:12, GET, /examples/static/css/web2py.css, HTTP/1.1, 200, 0.000851 +127.0.0.1, 2018-09-24 07:45:12, GET, /examples/static/css/calendar.css, HTTP/1.1, 200, 0.003483 +127.0.0.1, 2018-09-24 07:45:12, GET, /examples/static/css/examples.css, HTTP/1.1, 200, 0.000845 +127.0.0.1, 2018-09-24 07:45:12, GET, /examples/static/js/jquery.js, HTTP/1.1, 200, 0.002676 +127.0.0.1, 2018-09-24 07:45:12, GET, /examples/static/js/web2py.js, HTTP/1.1, 200, 0.002862 +127.0.0.1, 2018-09-24 07:45:12, GET, /examples/static/js/calendar.js, HTTP/1.1, 200, 0.003467 +127.0.0.1, 2018-09-24 07:45:12, GET, /examples/static/css/stupid.css, HTTP/1.1, 200, 0.008358 +127.0.0.1, 2018-09-24 07:45:12, GET, /examples/static/images/book-5th.png, HTTP/1.1, 200, 0.001846 +127.0.0.1, 2018-09-24 07:45:12, GET, /examples/static/images/web2py_logo.png, HTTP/1.1, 200, 0.002544 +127.0.0.1, 2018-09-24 07:45:12, GET, /examples/static/images/videos.png, HTTP/1.1, 200, 0.000620 +127.0.0.1, 2018-09-24 07:45:12, GET, /examples/static/images/book-recipes.png, HTTP/1.1, 200, 0.000601 +127.0.0.1, 2018-09-24 07:45:12, GET, /examples/static/images/infoworld2012.jpeg, HTTP/1.1, 200, 0.000651 +127.0.0.1, 2018-09-24 07:45:16, GET, /examples/static/images/favicon.ico, HTTP/1.1, 200, 0.000747 +127.0.0.1, 2018-09-24 07:45:24, GET, /admin/default/site, HTTP/1.1, 200, 0.023931 +127.0.0.1, 2018-09-24 07:45:24, GET, /favicon.ico, HTTP/1.1, 400, 0.000425 +127.0.0.1, 2018-09-24 07:45:27, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.107837 +127.0.0.1, 2018-09-24 07:45:27, GET, /favicon.ico, HTTP/1.1, 400, 0.000236 +127.0.0.1, 2018-09-24 07:45:37, GET, /admin/default/site, HTTP/1.1, 200, 0.023481 +127.0.0.1, 2018-09-24 07:45:37, GET, /favicon.ico, HTTP/1.1, 400, 0.000228 +127.0.0.1, 2018-09-24 07:45:44, GET, /welcome, HTTP/1.1, 200, 0.020741 +127.0.0.1, 2018-09-24 07:45:47, GET, /welcome/default/user/login, HTTP/1.1, 200, 0.030650 +127.0.0.1, 2018-09-24 07:45:52, GET, /welcome/default/user/retrieve_password, HTTP/1.1, 200, 0.047601 +127.0.0.1, 2018-09-24 07:45:54, GET, /welcome/default/user/login, HTTP/1.1, 200, 0.030631 +127.0.0.1, 2018-09-24 07:47:11, GET, /welcome/default/index, HTTP/1.1, 200, 0.021731 +127.0.0.1, 2018-09-24 07:47:20, GET, /SP/private/home, HTTP/1.1, 404, 0.022545 +127.0.0.1, 2018-09-24 07:47:20, GET, /favicon.ico, HTTP/1.1, 400, 0.000359 +127.0.0.1, 2018-09-24 07:47:22, GET, /SP/default/myhome, HTTP/1.1, 200, 0.028975 +127.0.0.1, 2018-09-24 07:47:27, GET, /SP/default/myhome, HTTP/1.1, 200, 0.025921 +127.0.0.1, 2018-09-24 07:47:27, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000895 +127.0.0.1, 2018-09-24 07:47:29, GET, /SP/default/task, HTTP/1.1, 200, 0.029047 +127.0.0.1, 2018-09-24 07:47:29, GET, /favicon.ico, HTTP/1.1, 400, 0.000365 +127.0.0.1, 2018-09-24 07:47:33, GET, /SP/default/myhome, HTTP/1.1, 200, 0.026674 +127.0.0.1, 2018-09-24 07:47:45, GET, /SP/default/myhome, HTTP/1.1, 200, 0.027079 +127.0.0.1, 2018-09-24 07:47:45, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000662 +127.0.0.1, 2018-09-24 07:47:46, GET, /SP/default/task, HTTP/1.1, 200, 0.024841 +127.0.0.1, 2018-09-24 07:47:48, GET, /SP/default/myhome, HTTP/1.1, 200, 0.038775 +127.0.0.1, 2018-09-24 07:47:55, GET, /SP/default/myclass, HTTP/1.1, 200, 0.027762 +127.0.0.1, 2018-09-24 07:47:57, GET, /SP/default/myhome, HTTP/1.1, 200, 0.027665 +127.0.0.1, 2018-09-24 07:48:24, GET, /SP/private/home, HTTP/1.1, 404, 0.021092 +127.0.0.1, 2018-09-24 07:48:24, GET, /favicon.ico, HTTP/1.1, 400, 0.000235 +127.0.0.1, 2018-09-24 07:48:26, GET, /SP/default/myhome, HTTP/1.1, 200, 0.029372 +127.0.0.1, 2018-09-24 07:48:58, GET, /SP/appadmin, HTTP/1.1, 200, 0.042482 +127.0.0.1, 2018-09-24 07:48:58, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060304 +127.0.0.1, 2018-09-24 07:56:02, GET, /SP/default/myhome, HTTP/1.1, 200, 0.040678 +127.0.0.1, 2018-09-24 07:56:04, GET, /SP/default/myclass, HTTP/1.1, 200, 0.028812 +127.0.0.1, 2018-09-24 07:56:09, GET, /SP/appadmin, HTTP/1.1, 200, 0.036323 +127.0.0.1, 2018-09-24 07:56:10, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.080093 +127.0.0.1, 2018-09-24 07:58:36, GET, /SP/appadmin, HTTP/1.1, 200, 0.058704 +127.0.0.1, 2018-09-24 07:58:36, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001390 +127.0.0.1, 2018-09-24 07:58:36, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.111478 +127.0.0.1, 2018-09-24 08:04:44, GET, /SP/appadmin, HTTP/1.1, 200, 0.081805 +127.0.0.1, 2018-09-24 08:04:44, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001168 +127.0.0.1, 2018-09-24 08:04:45, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.134169 +127.0.0.1, 2018-09-24 08:04:45, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.192093 +127.0.0.1, 2018-09-24 08:04:45, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.117836 +127.0.0.1, 2018-09-24 08:04:45, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.164931 +127.0.0.1, 2018-09-24 08:04:45, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.071401 +127.0.0.1, 2018-09-24 08:04:45, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.107314 +127.0.0.1, 2018-09-24 08:04:45, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.052160 +127.0.0.1, 2018-09-24 08:04:45, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.184475 +127.0.0.1, 2018-09-24 08:04:46, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.076146 +127.0.0.1, 2018-09-24 08:04:46, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.171098 +127.0.0.1, 2018-09-24 08:04:46, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.073421 +127.0.0.1, 2018-09-24 08:04:46, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.107234 +127.0.0.1, 2018-09-24 08:04:46, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.065605 +127.0.0.1, 2018-09-24 08:04:46, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.098135 +127.0.0.1, 2018-09-24 08:04:46, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070207 +127.0.0.1, 2018-09-24 08:04:46, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.103369 +127.0.0.1, 2018-09-24 08:04:46, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061222 +127.0.0.1, 2018-09-24 08:04:46, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.102124 +127.0.0.1, 2018-09-24 08:04:47, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070175 +127.0.0.1, 2018-09-24 08:04:47, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.104557 +127.0.0.1, 2018-09-24 08:04:47, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070398 +127.0.0.1, 2018-09-24 08:04:47, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.109494 +127.0.0.1, 2018-09-24 08:04:47, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.066875 +127.0.0.1, 2018-09-24 08:04:47, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.101859 +127.0.0.1, 2018-09-24 08:04:47, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067011 +127.0.0.1, 2018-09-24 08:04:47, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.141923 +127.0.0.1, 2018-09-24 08:04:47, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.065222 +127.0.0.1, 2018-09-24 08:04:47, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.096139 +127.0.0.1, 2018-09-24 08:04:47, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.080539 +127.0.0.1, 2018-09-24 08:04:47, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.116379 +127.0.0.1, 2018-09-24 08:04:48, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067341 +127.0.0.1, 2018-09-24 08:04:48, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.097764 +127.0.0.1, 2018-09-24 08:04:48, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.085678 +127.0.0.1, 2018-09-24 08:04:48, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.120030 +127.0.0.1, 2018-09-24 08:04:48, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063918 +127.0.0.1, 2018-09-24 08:04:48, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.099150 +127.0.0.1, 2018-09-24 08:04:48, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063312 +127.0.0.1, 2018-09-24 08:04:48, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.097836 +127.0.0.1, 2018-09-24 08:04:48, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067079 +127.0.0.1, 2018-09-24 08:04:48, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.100356 +127.0.0.1, 2018-09-24 08:04:49, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070203 +127.0.0.1, 2018-09-24 08:04:49, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.102675 +127.0.0.1, 2018-09-24 08:04:49, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067161 +127.0.0.1, 2018-09-24 08:04:49, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.100355 +127.0.0.1, 2018-09-24 08:04:49, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.071144 +127.0.0.1, 2018-09-24 08:04:49, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.113535 +127.0.0.1, 2018-09-24 08:04:49, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060871 +127.0.0.1, 2018-09-24 08:04:49, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.092285 +127.0.0.1, 2018-09-24 08:04:49, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.062877 +127.0.0.1, 2018-09-24 08:04:49, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.099443 +127.0.0.1, 2018-09-24 08:04:49, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.065009 +127.0.0.1, 2018-09-24 08:04:49, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.106574 +127.0.0.1, 2018-09-24 08:04:50, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.076820 +127.0.0.1, 2018-09-24 08:04:50, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.106628 +127.0.0.1, 2018-09-24 08:04:50, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060533 +127.0.0.1, 2018-09-24 08:04:50, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.088927 +127.0.0.1, 2018-09-24 08:04:50, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.102104 +127.0.0.1, 2018-09-24 08:04:50, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.139396 +127.0.0.1, 2018-09-24 08:04:50, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.069605 +127.0.0.1, 2018-09-24 08:04:50, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.101994 +127.0.0.1, 2018-09-24 08:04:50, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063825 +127.0.0.1, 2018-09-24 08:04:50, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.094029 +127.0.0.1, 2018-09-24 08:04:51, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.083027 +127.0.0.1, 2018-09-24 08:04:51, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.129066 +127.0.0.1, 2018-09-24 08:04:51, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.068581 +127.0.0.1, 2018-09-24 08:04:51, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.103070 +127.0.0.1, 2018-09-24 08:04:53, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.045611 +127.0.0.1, 2018-09-24 08:04:53, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.174379 +127.0.0.1, 2018-09-24 08:04:55, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.114622 +127.0.0.1, 2018-09-24 08:04:55, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.175259 +127.0.0.1, 2018-09-24 08:04:57, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.056237 +127.0.0.1, 2018-09-24 08:04:57, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.176289 +127.0.0.1, 2018-09-24 08:04:59, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.097880 +127.0.0.1, 2018-09-24 08:04:59, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.134553 +127.0.0.1, 2018-09-24 08:05:01, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.045176 +127.0.0.1, 2018-09-24 08:05:01, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.158005 +127.0.0.1, 2018-09-24 08:05:03, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072334 +127.0.0.1, 2018-09-24 08:05:03, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.109797 +127.0.0.1, 2018-09-24 08:05:03, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.066235 +127.0.0.1, 2018-09-24 08:05:03, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.116765 +127.0.0.1, 2018-09-24 08:05:03, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.099973 +127.0.0.1, 2018-09-24 08:05:03, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.136202 +127.0.0.1, 2018-09-24 08:05:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.119301 +127.0.0.1, 2018-09-24 08:05:04, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.131650 +127.0.0.1, 2018-09-24 08:05:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064180 +127.0.0.1, 2018-09-24 08:05:04, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.103626 +127.0.0.1, 2018-09-24 08:05:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061167 +127.0.0.1, 2018-09-24 08:05:04, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.086816 +127.0.0.1, 2018-09-24 08:05:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.058370 +127.0.0.1, 2018-09-24 08:05:04, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.084640 +127.0.0.1, 2018-09-24 08:05:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.062556 +127.0.0.1, 2018-09-24 08:05:04, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.092713 +127.0.0.1, 2018-09-24 08:05:05, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.088137 +127.0.0.1, 2018-09-24 08:05:05, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.129866 +127.0.0.1, 2018-09-24 08:05:05, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.068450 +127.0.0.1, 2018-09-24 08:05:05, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.102081 +127.0.0.1, 2018-09-24 08:05:06, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.211109 +127.0.0.1, 2018-09-24 08:05:07, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.053083 +127.0.0.1, 2018-09-24 08:05:07, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.083179 +127.0.0.1, 2018-09-24 08:05:07, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.121380 +127.0.0.1, 2018-09-24 08:05:07, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.068021 +127.0.0.1, 2018-09-24 08:05:07, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.104061 +127.0.0.1, 2018-09-24 08:05:07, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.041987 +127.0.0.1, 2018-09-24 08:05:08, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.143858 +127.0.0.1, 2018-09-24 08:05:08, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070553 +127.0.0.1, 2018-09-24 08:05:08, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.120537 +127.0.0.1, 2018-09-24 08:05:08, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.073818 +127.0.0.1, 2018-09-24 08:05:08, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.182911 +127.0.0.1, 2018-09-24 08:05:08, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.093849 +127.0.0.1, 2018-09-24 08:05:08, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.131061 +127.0.0.1, 2018-09-24 08:05:09, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.119235 +127.0.0.1, 2018-09-24 08:05:09, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.169171 +127.0.0.1, 2018-09-24 08:05:09, GET, /SP/appadmin, HTTP/1.1, 200, 0.123412 +127.0.0.1, 2018-09-24 08:05:09, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000792 +127.0.0.1, 2018-09-24 08:05:09, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.126957 +127.0.0.1, 2018-09-24 08:05:09, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.173039 +127.0.0.1, 2018-09-24 08:05:10, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.096820 +127.0.0.1, 2018-09-24 08:05:10, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.144510 +127.0.0.1, 2018-09-24 08:05:10, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.151678 +127.0.0.1, 2018-09-24 08:05:10, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.207321 +127.0.0.1, 2018-09-24 08:05:10, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.112929 +127.0.0.1, 2018-09-24 08:05:10, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.154303 +127.0.0.1, 2018-09-24 08:05:10, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.081453 +127.0.0.1, 2018-09-24 08:05:10, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.112880 +127.0.0.1, 2018-09-24 08:05:11, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.074910 +127.0.0.1, 2018-09-24 08:05:11, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.146729 +127.0.0.1, 2018-09-24 08:05:11, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060241 +127.0.0.1, 2018-09-24 08:05:11, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.090645 +127.0.0.1, 2018-09-24 08:05:11, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064568 +127.0.0.1, 2018-09-24 08:05:11, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.103307 +127.0.0.1, 2018-09-24 08:05:11, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060945 +127.0.0.1, 2018-09-24 08:05:11, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.091917 +127.0.0.1, 2018-09-24 08:05:11, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.066921 +127.0.0.1, 2018-09-24 08:05:11, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.100740 +127.0.0.1, 2018-09-24 08:05:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.059303 +127.0.0.1, 2018-09-24 08:05:12, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.090866 +127.0.0.1, 2018-09-24 08:05:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063186 +127.0.0.1, 2018-09-24 08:05:12, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.094231 +127.0.0.1, 2018-09-24 08:05:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.058316 +127.0.0.1, 2018-09-24 08:05:12, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.088721 +127.0.0.1, 2018-09-24 08:05:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.093388 +127.0.0.1, 2018-09-24 08:05:12, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.135817 +127.0.0.1, 2018-09-24 08:05:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067179 +127.0.0.1, 2018-09-24 08:05:12, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.101519 +127.0.0.1, 2018-09-24 08:05:13, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.079337 +127.0.0.1, 2018-09-24 08:05:13, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.113586 +127.0.0.1, 2018-09-24 08:05:13, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.088621 +127.0.0.1, 2018-09-24 08:05:13, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.125656 +127.0.0.1, 2018-09-24 08:05:13, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067631 +127.0.0.1, 2018-09-24 08:05:13, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.096701 +127.0.0.1, 2018-09-24 08:05:13, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060289 +127.0.0.1, 2018-09-24 08:05:13, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.092760 +127.0.0.1, 2018-09-24 08:05:13, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.077025 +127.0.0.1, 2018-09-24 08:05:13, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.114860 +127.0.0.1, 2018-09-24 08:05:13, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.068065 +127.0.0.1, 2018-09-24 08:05:13, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.103946 +127.0.0.1, 2018-09-24 08:05:14, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.080737 +127.0.0.1, 2018-09-24 08:05:14, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.143470 +127.0.0.1, 2018-09-24 08:05:15, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.079208 +127.0.0.1, 2018-09-24 08:05:15, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.136109 +127.0.0.1, 2018-09-24 08:05:15, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067103 +127.0.0.1, 2018-09-24 08:05:15, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.092497 +127.0.0.1, 2018-09-24 08:05:15, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072827 +127.0.0.1, 2018-09-24 08:05:15, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.116555 +127.0.0.1, 2018-09-24 08:05:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.066934 +127.0.0.1, 2018-09-24 08:05:16, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.096509 +127.0.0.1, 2018-09-24 08:05:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.066593 +127.0.0.1, 2018-09-24 08:05:16, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.107272 +127.0.0.1, 2018-09-24 08:05:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064442 +127.0.0.1, 2018-09-24 08:05:16, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.098434 +127.0.0.1, 2018-09-24 08:05:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064774 +127.0.0.1, 2018-09-24 08:05:16, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.094971 +127.0.0.1, 2018-09-24 08:05:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063181 +127.0.0.1, 2018-09-24 08:05:16, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.097670 +127.0.0.1, 2018-09-24 08:05:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.073935 +127.0.0.1, 2018-09-24 08:05:16, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.105112 +127.0.0.1, 2018-09-24 08:05:17, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.066027 +127.0.0.1, 2018-09-24 08:05:17, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.096533 +127.0.0.1, 2018-09-24 08:05:17, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070102 +127.0.0.1, 2018-09-24 08:05:17, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.100014 +127.0.0.1, 2018-09-24 08:05:17, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060622 +127.0.0.1, 2018-09-24 08:05:17, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.091833 +127.0.0.1, 2018-09-24 08:05:17, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.077167 +127.0.0.1, 2018-09-24 08:05:17, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.120631 +127.0.0.1, 2018-09-24 08:05:17, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061803 +127.0.0.1, 2018-09-24 08:05:17, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.096530 +127.0.0.1, 2018-09-24 08:05:17, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.077228 +127.0.0.1, 2018-09-24 08:05:17, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.118995 +127.0.0.1, 2018-09-24 08:05:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.066342 +127.0.0.1, 2018-09-24 08:05:18, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.098840 +127.0.0.1, 2018-09-24 08:05:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060091 +127.0.0.1, 2018-09-24 08:05:18, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.101273 +127.0.0.1, 2018-09-24 08:05:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.069127 +127.0.0.1, 2018-09-24 08:05:18, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.103513 +127.0.0.1, 2018-09-24 08:05:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061955 +127.0.0.1, 2018-09-24 08:05:18, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.088351 +127.0.0.1, 2018-09-24 08:05:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.062146 +127.0.0.1, 2018-09-24 08:05:18, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.096438 +127.0.0.1, 2018-09-24 08:05:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.068918 +127.0.0.1, 2018-09-24 08:05:18, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.097464 +127.0.0.1, 2018-09-24 08:05:19, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064931 +127.0.0.1, 2018-09-24 08:05:19, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.100076 +127.0.0.1, 2018-09-24 08:05:19, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063134 +127.0.0.1, 2018-09-24 08:05:19, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.100812 +127.0.0.1, 2018-09-24 08:05:19, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070228 +127.0.0.1, 2018-09-24 08:05:19, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.111109 +127.0.0.1, 2018-09-24 08:05:19, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.062109 +127.0.0.1, 2018-09-24 08:05:19, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.095817 +127.0.0.1, 2018-09-24 08:05:19, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064480 +127.0.0.1, 2018-09-24 08:05:19, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.095155 +127.0.0.1, 2018-09-24 08:05:20, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.091463 +127.0.0.1, 2018-09-24 08:05:20, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.124368 +127.0.0.1, 2018-09-24 08:05:20, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.068483 +127.0.0.1, 2018-09-24 08:05:20, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.098321 +127.0.0.1, 2018-09-24 08:05:20, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064978 +127.0.0.1, 2018-09-24 08:05:20, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.097200 +127.0.0.1, 2018-09-24 08:05:20, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.109224 +127.0.0.1, 2018-09-24 08:05:20, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.149284 +127.0.0.1, 2018-09-24 08:05:20, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.078555 +127.0.0.1, 2018-09-24 08:05:20, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.112278 +127.0.0.1, 2018-09-24 08:05:22, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.065321 +127.0.0.1, 2018-09-24 08:05:22, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.120348 +127.0.0.1, 2018-09-24 08:05:25, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.086539 +127.0.0.1, 2018-09-24 08:05:25, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.140534 +127.0.0.1, 2018-09-24 08:05:27, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.110806 +127.0.0.1, 2018-09-24 08:05:27, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.194428 +127.0.0.1, 2018-09-24 08:05:29, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.058867 +127.0.0.1, 2018-09-24 08:05:29, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.087625 +127.0.0.1, 2018-09-24 08:05:31, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.044342 +127.0.0.1, 2018-09-24 08:05:31, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.125796 +127.0.0.1, 2018-09-24 08:05:33, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061554 +127.0.0.1, 2018-09-24 08:05:33, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.105209 +127.0.0.1, 2018-09-24 08:05:35, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.058222 +127.0.0.1, 2018-09-24 08:05:35, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.088350 +127.0.0.1, 2018-09-24 08:05:37, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.053042 +127.0.0.1, 2018-09-24 08:05:37, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.138217 +127.0.0.1, 2018-09-24 08:05:39, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.037537 +127.0.0.1, 2018-09-24 08:05:39, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.126901 +127.0.0.1, 2018-09-24 08:05:41, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.074115 +127.0.0.1, 2018-09-24 08:05:41, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.109287 +127.0.0.1, 2018-09-24 08:05:43, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061540 +127.0.0.1, 2018-09-24 08:05:43, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.091019 +127.0.0.1, 2018-09-24 08:05:45, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060212 +127.0.0.1, 2018-09-24 08:05:45, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.114536 +127.0.0.1, 2018-09-24 08:05:47, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.033513 +127.0.0.1, 2018-09-24 08:05:47, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.100069 +127.0.0.1, 2018-09-24 08:05:49, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.043224 +127.0.0.1, 2018-09-24 08:05:49, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.122361 +127.0.0.1, 2018-09-24 08:05:51, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060772 +127.0.0.1, 2018-09-24 08:05:51, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.090285 +127.0.0.1, 2018-09-24 08:05:53, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063554 +127.0.0.1, 2018-09-24 08:05:53, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.091989 +127.0.0.1, 2018-09-24 08:05:55, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.141290 +127.0.0.1, 2018-09-24 08:05:55, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.183463 +127.0.0.1, 2018-09-24 08:05:57, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064101 +127.0.0.1, 2018-09-24 08:05:57, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.096257 +127.0.0.1, 2018-09-24 08:05:59, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.038933 +127.0.0.1, 2018-09-24 08:05:59, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.174516 +127.0.0.1, 2018-09-24 08:06:01, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060294 +127.0.0.1, 2018-09-24 08:06:01, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.106245 +127.0.0.1, 2018-09-24 08:06:03, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.040801 +127.0.0.1, 2018-09-24 08:06:03, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.110436 +127.0.0.1, 2018-09-24 08:06:05, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.121041 +127.0.0.1, 2018-09-24 08:06:05, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.173024 +127.0.0.1, 2018-09-24 08:06:07, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.049323 +127.0.0.1, 2018-09-24 08:06:07, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.152525 +127.0.0.1, 2018-09-24 08:06:09, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060748 +127.0.0.1, 2018-09-24 08:06:09, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.091549 +127.0.0.1, 2018-09-24 08:06:11, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060496 +127.0.0.1, 2018-09-24 08:06:11, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.094940 +127.0.0.1, 2018-09-24 08:06:13, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.038658 +127.0.0.1, 2018-09-24 08:06:13, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.130093 +127.0.0.1, 2018-09-24 08:06:15, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.048127 +127.0.0.1, 2018-09-24 08:06:15, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.166267 +127.0.0.1, 2018-09-24 08:06:17, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.035862 +127.0.0.1, 2018-09-24 08:06:17, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.102689 +127.0.0.1, 2018-09-24 08:06:19, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.099747 +127.0.0.1, 2018-09-24 08:06:19, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.142138 +127.0.0.1, 2018-09-24 08:06:21, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.036377 +127.0.0.1, 2018-09-24 08:06:21, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.097602 +127.0.0.1, 2018-09-24 08:06:23, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.065756 +127.0.0.1, 2018-09-24 08:06:23, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.093495 +127.0.0.1, 2018-09-24 08:06:25, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.044967 +127.0.0.1, 2018-09-24 08:06:25, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.148858 +127.0.0.1, 2018-09-24 08:06:27, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.040342 +127.0.0.1, 2018-09-24 08:06:27, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.137997 +127.0.0.1, 2018-09-24 08:06:29, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061844 +127.0.0.1, 2018-09-24 08:06:29, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.093341 +127.0.0.1, 2018-09-24 08:06:31, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.039609 +127.0.0.1, 2018-09-24 08:06:31, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.100488 +127.0.0.1, 2018-09-24 08:06:33, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060398 +127.0.0.1, 2018-09-24 08:06:33, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.088865 +127.0.0.1, 2018-09-24 08:06:35, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.085708 +127.0.0.1, 2018-09-24 08:06:35, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.140976 +127.0.0.1, 2018-09-24 08:06:37, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.037669 +127.0.0.1, 2018-09-24 08:06:37, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.126731 +127.0.0.1, 2018-09-24 08:06:39, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.068665 +127.0.0.1, 2018-09-24 08:06:39, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.126857 +127.0.0.1, 2018-09-24 08:06:41, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061611 +127.0.0.1, 2018-09-24 08:06:41, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.098543 +127.0.0.1, 2018-09-24 08:06:43, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.080949 +127.0.0.1, 2018-09-24 08:06:43, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.163444 +127.0.0.1, 2018-09-24 08:06:45, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.049531 +127.0.0.1, 2018-09-24 08:06:45, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.144137 +127.0.0.1, 2018-09-24 08:06:47, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064340 +127.0.0.1, 2018-09-24 08:06:47, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.094359 +127.0.0.1, 2018-09-24 08:06:49, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.052182 +127.0.0.1, 2018-09-24 08:06:49, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.121964 +127.0.0.1, 2018-09-24 08:06:51, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.058619 +127.0.0.1, 2018-09-24 08:06:51, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.097258 +127.0.0.1, 2018-09-24 08:06:53, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.035252 +127.0.0.1, 2018-09-24 08:06:53, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.133601 +127.0.0.1, 2018-09-24 08:06:55, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.125757 +127.0.0.1, 2018-09-24 08:06:55, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.176446 +127.0.0.1, 2018-09-24 08:06:57, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.075550 +127.0.0.1, 2018-09-24 08:06:57, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.088861 +127.0.0.1, 2018-09-24 08:06:59, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.037267 +127.0.0.1, 2018-09-24 08:06:59, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.105949 +127.0.0.1, 2018-09-24 08:07:02, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.078577 +127.0.0.1, 2018-09-24 08:07:02, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.128893 +127.0.0.1, 2018-09-24 08:07:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.094239 +127.0.0.1, 2018-09-24 08:07:04, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.164145 +127.0.0.1, 2018-09-24 08:07:06, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.077463 +127.0.0.1, 2018-09-24 08:07:06, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.112334 +127.0.0.1, 2018-09-24 08:07:08, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.034064 +127.0.0.1, 2018-09-24 08:07:08, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.112175 +127.0.0.1, 2018-09-24 08:07:10, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060244 +127.0.0.1, 2018-09-24 08:07:10, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.091817 +127.0.0.1, 2018-09-24 08:07:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064296 +127.0.0.1, 2018-09-24 08:07:12, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.159995 +127.0.0.1, 2018-09-24 08:07:14, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064759 +127.0.0.1, 2018-09-24 08:07:14, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.096059 +127.0.0.1, 2018-09-24 08:07:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.094575 +127.0.0.1, 2018-09-24 08:07:16, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.124105 +127.0.0.1, 2018-09-24 08:07:18, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.052633 +127.0.0.1, 2018-09-24 08:07:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.153867 +127.0.0.1, 2018-09-24 08:07:20, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.076182 +127.0.0.1, 2018-09-24 08:07:20, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.239291 +127.0.0.1, 2018-09-24 08:07:22, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061702 +127.0.0.1, 2018-09-24 08:07:22, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.093673 +127.0.0.1, 2018-09-24 08:07:24, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.111344 +127.0.0.1, 2018-09-24 08:07:24, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.152500 +127.0.0.1, 2018-09-24 08:07:26, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.066668 +127.0.0.1, 2018-09-24 08:07:26, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.096006 +127.0.0.1, 2018-09-24 08:07:28, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.066627 +127.0.0.1, 2018-09-24 08:07:28, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.105752 +127.0.0.1, 2018-09-24 08:07:30, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061969 +127.0.0.1, 2018-09-24 08:07:30, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.095725 +127.0.0.1, 2018-09-24 08:07:32, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060538 +127.0.0.1, 2018-09-24 08:07:32, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.089746 +127.0.0.1, 2018-09-24 08:07:34, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061149 +127.0.0.1, 2018-09-24 08:07:34, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.098277 +127.0.0.1, 2018-09-24 08:07:36, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.035387 +127.0.0.1, 2018-09-24 08:07:36, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.098016 +127.0.0.1, 2018-09-24 08:07:38, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.034777 +127.0.0.1, 2018-09-24 08:07:38, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.106939 +127.0.0.1, 2018-09-24 08:07:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.066920 +127.0.0.1, 2018-09-24 08:07:40, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.126792 +127.0.0.1, 2018-09-24 08:07:42, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.046694 +127.0.0.1, 2018-09-24 08:07:42, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.124975 +127.0.0.1, 2018-09-24 08:07:44, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061704 +127.0.0.1, 2018-09-24 08:07:44, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.093748 +127.0.0.1, 2018-09-24 08:07:46, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.042064 +127.0.0.1, 2018-09-24 08:07:46, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.141129 +127.0.0.1, 2018-09-24 08:07:48, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.062644 +127.0.0.1, 2018-09-24 08:07:48, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.091314 +127.0.0.1, 2018-09-24 08:07:50, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.033402 +127.0.0.1, 2018-09-24 08:07:50, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.108273 +127.0.0.1, 2018-09-24 08:07:52, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067045 +127.0.0.1, 2018-09-24 08:07:52, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.102730 +127.0.0.1, 2018-09-24 08:07:54, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.100636 +127.0.0.1, 2018-09-24 08:07:54, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.156499 +127.0.0.1, 2018-09-24 08:07:56, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.035617 +127.0.0.1, 2018-09-24 08:07:56, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.101613 +127.0.0.1, 2018-09-24 08:07:58, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072467 +127.0.0.1, 2018-09-24 08:07:58, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.108838 +127.0.0.1, 2018-09-24 08:08:00, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.040069 +127.0.0.1, 2018-09-24 08:08:00, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.110458 +127.0.0.1, 2018-09-24 08:08:02, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.035337 +127.0.0.1, 2018-09-24 08:08:02, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.101919 +127.0.0.1, 2018-09-24 08:08:04, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.037284 +127.0.0.1, 2018-09-24 08:08:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.113124 +127.0.0.1, 2018-09-24 08:08:06, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.039130 +127.0.0.1, 2018-09-24 08:08:06, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.112220 +127.0.0.1, 2018-09-24 08:08:08, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.036846 +127.0.0.1, 2018-09-24 08:08:08, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.106947 +127.0.0.1, 2018-09-24 08:08:10, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.034496 +127.0.0.1, 2018-09-24 08:08:10, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.102571 +127.0.0.1, 2018-09-24 08:08:12, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.038889 +127.0.0.1, 2018-09-24 08:08:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.103742 +127.0.0.1, 2018-09-24 08:08:14, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.033979 +127.0.0.1, 2018-09-24 08:08:14, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.117590 +127.0.0.1, 2018-09-24 08:08:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.069368 +127.0.0.1, 2018-09-24 08:08:16, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.102586 +127.0.0.1, 2018-09-24 08:08:18, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.041742 +127.0.0.1, 2018-09-24 08:08:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.134092 +127.0.0.1, 2018-09-24 08:08:20, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.038026 +127.0.0.1, 2018-09-24 08:08:20, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.106448 +127.0.0.1, 2018-09-24 08:08:22, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.040597 +127.0.0.1, 2018-09-24 08:08:22, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.165931 +127.0.0.1, 2018-09-24 08:08:24, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.054950 +127.0.0.1, 2018-09-24 08:08:24, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.180970 +127.0.0.1, 2018-09-24 08:08:25, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.124207 +127.0.0.1, 2018-09-24 08:08:25, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.166237 +127.0.0.1, 2018-09-24 08:08:25, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.183195 +127.0.0.1, 2018-09-24 08:08:25, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.250741 +127.0.0.1, 2018-09-24 08:08:25, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.059909 +127.0.0.1, 2018-09-24 08:08:25, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.091105 +127.0.0.1, 2018-09-24 08:08:25, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.105653 +127.0.0.1, 2018-09-24 08:08:25, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.143398 +127.0.0.1, 2018-09-24 08:08:26, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.080857 +127.0.0.1, 2018-09-24 08:08:26, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.106653 +127.0.0.1, 2018-09-24 08:08:26, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.045063 +127.0.0.1, 2018-09-24 08:08:26, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.178500 +127.0.0.1, 2018-09-24 08:08:26, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.084708 +127.0.0.1, 2018-09-24 08:08:26, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.227339 +127.0.0.1, 2018-09-24 08:08:27, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.095640 +127.0.0.1, 2018-09-24 08:08:27, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.129850 +127.0.0.1, 2018-09-24 08:08:29, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.042211 +127.0.0.1, 2018-09-24 08:08:30, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.137169 +127.0.0.1, 2018-09-24 08:08:32, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.080205 +127.0.0.1, 2018-09-24 08:08:32, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.103825 +127.0.0.1, 2018-09-24 08:08:34, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.117570 +127.0.0.1, 2018-09-24 08:08:34, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.168240 +127.0.0.1, 2018-09-24 08:08:36, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061574 +127.0.0.1, 2018-09-24 08:08:36, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.094279 +127.0.0.1, 2018-09-24 08:08:38, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064677 +127.0.0.1, 2018-09-24 08:08:38, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.164176 +127.0.0.1, 2018-09-24 08:08:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063065 +127.0.0.1, 2018-09-24 08:08:40, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.092144 +127.0.0.1, 2018-09-24 08:08:42, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.058772 +127.0.0.1, 2018-09-24 08:08:42, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.089441 +127.0.0.1, 2018-09-24 08:08:44, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.056989 +127.0.0.1, 2018-09-24 08:08:44, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.210200 +127.0.0.1, 2018-09-24 08:08:46, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.034901 +127.0.0.1, 2018-09-24 08:08:46, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.107418 +127.0.0.1, 2018-09-24 08:08:48, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.065301 +127.0.0.1, 2018-09-24 08:08:48, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.096554 +127.0.0.1, 2018-09-24 08:08:50, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.032355 +127.0.0.1, 2018-09-24 08:08:50, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.125382 +127.0.0.1, 2018-09-24 08:08:52, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.037781 +127.0.0.1, 2018-09-24 08:08:52, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.112419 +127.0.0.1, 2018-09-24 08:08:54, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067471 +127.0.0.1, 2018-09-24 08:08:54, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.113032 +127.0.0.1, 2018-09-24 08:08:54, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.186529 +127.0.0.1, 2018-09-24 08:08:54, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.242506 +127.0.0.1, 2018-09-24 08:08:55, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.114253 +127.0.0.1, 2018-09-24 08:08:55, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.194396 +127.0.0.1, 2018-09-24 08:08:55, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.065251 +127.0.0.1, 2018-09-24 08:08:55, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.095614 +127.0.0.1, 2018-09-24 08:08:55, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.078037 +127.0.0.1, 2018-09-24 08:08:55, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.111935 +127.0.0.1, 2018-09-24 08:08:55, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.121055 +127.0.0.1, 2018-09-24 08:08:55, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.163683 +127.0.0.1, 2018-09-24 08:08:56, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064128 +127.0.0.1, 2018-09-24 08:08:56, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.094141 +127.0.0.1, 2018-09-24 08:08:56, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.101932 +127.0.0.1, 2018-09-24 08:08:56, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.195181 +127.0.0.1, 2018-09-24 08:08:56, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070920 +127.0.0.1, 2018-09-24 08:08:56, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.106249 +127.0.0.1, 2018-09-24 08:08:56, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.069132 +127.0.0.1, 2018-09-24 08:08:56, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.113575 +127.0.0.1, 2018-09-24 08:08:56, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.047676 +127.0.0.1, 2018-09-24 08:08:56, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.151603 +127.0.0.1, 2018-09-24 08:08:57, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.038229 +127.0.0.1, 2018-09-24 08:08:57, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.133674 +127.0.0.1, 2018-09-24 08:08:57, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.039149 +127.0.0.1, 2018-09-24 08:08:57, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.142991 +127.0.0.1, 2018-09-24 08:08:57, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.051000 +127.0.0.1, 2018-09-24 08:08:57, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.132259 +127.0.0.1, 2018-09-24 08:08:57, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.050269 +127.0.0.1, 2018-09-24 08:08:57, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.198685 +127.0.0.1, 2018-09-24 08:08:57, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.103021 +127.0.0.1, 2018-09-24 08:08:57, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.181260 +127.0.0.1, 2018-09-24 08:08:58, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.198190 +127.0.0.1, 2018-09-24 08:08:58, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.253832 +127.0.0.1, 2018-09-24 08:08:59, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.075350 +127.0.0.1, 2018-09-24 08:08:59, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.120775 +127.0.0.1, 2018-09-24 08:09:02, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.062810 +127.0.0.1, 2018-09-24 08:09:02, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.096908 +127.0.0.1, 2018-09-24 08:09:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072906 +127.0.0.1, 2018-09-24 08:09:04, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.110891 +127.0.0.1, 2018-09-24 08:09:06, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.074791 +127.0.0.1, 2018-09-24 08:09:06, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.113024 +127.0.0.1, 2018-09-24 08:09:08, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061380 +127.0.0.1, 2018-09-24 08:09:08, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.092990 +127.0.0.1, 2018-09-24 08:09:10, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.073527 +127.0.0.1, 2018-09-24 08:09:10, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.099450 +127.0.0.1, 2018-09-24 08:09:12, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.035632 +127.0.0.1, 2018-09-24 08:09:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.109127 +127.0.0.1, 2018-09-24 08:09:14, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.042430 +127.0.0.1, 2018-09-24 08:09:14, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.145792 +127.0.0.1, 2018-09-24 08:09:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061532 +127.0.0.1, 2018-09-24 08:09:16, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.109666 +127.0.0.1, 2018-09-24 08:09:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063165 +127.0.0.1, 2018-09-24 08:09:18, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.091393 +127.0.0.1, 2018-09-24 08:09:20, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.038621 +127.0.0.1, 2018-09-24 08:09:20, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.144296 +127.0.0.1, 2018-09-24 08:09:22, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067341 +127.0.0.1, 2018-09-24 08:09:22, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.104669 +127.0.0.1, 2018-09-24 08:09:24, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.067398 +127.0.0.1, 2018-09-24 08:09:24, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.187487 +127.0.0.1, 2018-09-24 08:09:26, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.051560 +127.0.0.1, 2018-09-24 08:09:26, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.192338 +127.0.0.1, 2018-09-24 08:09:28, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.091916 +127.0.0.1, 2018-09-24 08:09:28, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.131454 +127.0.0.1, 2018-09-24 08:09:30, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.037410 +127.0.0.1, 2018-09-24 08:09:30, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.117227 +127.0.0.1, 2018-09-24 08:09:32, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061312 +127.0.0.1, 2018-09-24 08:09:32, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.094390 +127.0.0.1, 2018-09-24 08:09:34, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.042944 +127.0.0.1, 2018-09-24 08:09:34, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.117459 +127.0.0.1, 2018-09-24 08:09:36, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.039333 +127.0.0.1, 2018-09-24 08:09:36, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.199207 +127.0.0.1, 2018-09-24 08:09:38, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.069854 +127.0.0.1, 2018-09-24 08:09:38, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.219441 +127.0.0.1, 2018-09-24 08:09:40, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.033203 +127.0.0.1, 2018-09-24 08:09:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.122839 +127.0.0.1, 2018-09-24 08:09:42, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072836 +127.0.0.1, 2018-09-24 08:09:42, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.160296 +127.0.0.1, 2018-09-24 08:09:44, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.031795 +127.0.0.1, 2018-09-24 08:09:44, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.132458 +127.0.0.1, 2018-09-24 08:09:46, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070843 +127.0.0.1, 2018-09-24 08:09:46, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.105736 +127.0.0.1, 2018-09-24 08:09:48, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.099978 +127.0.0.1, 2018-09-24 08:09:48, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.191455 +127.0.0.1, 2018-09-24 08:09:50, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.062103 +127.0.0.1, 2018-09-24 08:09:50, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.091470 +127.0.0.1, 2018-09-24 08:09:52, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.037210 +127.0.0.1, 2018-09-24 08:09:52, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.118200 +127.0.0.1, 2018-09-24 08:09:54, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.059262 +127.0.0.1, 2018-09-24 08:09:54, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.140205 +127.0.0.1, 2018-09-24 08:09:56, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.042185 +127.0.0.1, 2018-09-24 08:09:56, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.124630 +127.0.0.1, 2018-09-24 08:09:58, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.049581 +127.0.0.1, 2018-09-24 08:09:58, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.158970 +127.0.0.1, 2018-09-24 08:10:00, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064971 +127.0.0.1, 2018-09-24 08:10:00, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.096569 +127.0.0.1, 2018-09-24 08:10:02, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064447 +127.0.0.1, 2018-09-24 08:10:02, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.098979 +127.0.0.1, 2018-09-24 08:10:04, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.034596 +127.0.0.1, 2018-09-24 08:10:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.098065 +127.0.0.1, 2018-09-24 08:10:06, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063555 +127.0.0.1, 2018-09-24 08:10:06, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.095306 +127.0.0.1, 2018-09-24 08:10:08, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.033836 +127.0.0.1, 2018-09-24 08:10:08, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.149194 +127.0.0.1, 2018-09-24 08:10:10, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.069058 +127.0.0.1, 2018-09-24 08:10:10, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.102793 +127.0.0.1, 2018-09-24 08:10:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.059808 +127.0.0.1, 2018-09-24 08:10:12, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.088804 +127.0.0.1, 2018-09-24 08:10:14, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.056103 +127.0.0.1, 2018-09-24 08:10:14, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.087617 +127.0.0.1, 2018-09-24 08:10:16, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.033165 +127.0.0.1, 2018-09-24 08:10:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.100861 +127.0.0.1, 2018-09-24 08:10:18, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.042608 +127.0.0.1, 2018-09-24 08:10:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.104614 +127.0.0.1, 2018-09-24 08:10:20, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.039386 +127.0.0.1, 2018-09-24 08:10:20, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.140879 +127.0.0.1, 2018-09-24 08:10:22, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.057522 +127.0.0.1, 2018-09-24 08:10:22, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.087680 +127.0.0.1, 2018-09-24 08:10:24, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.059724 +127.0.0.1, 2018-09-24 08:10:24, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.091343 +127.0.0.1, 2018-09-24 08:10:26, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.039660 +127.0.0.1, 2018-09-24 08:10:26, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.131505 +127.0.0.1, 2018-09-24 08:10:26, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.065719 +127.0.0.1, 2018-09-24 08:10:26, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.111657 +127.0.0.1, 2018-09-24 08:10:27, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.085722 +127.0.0.1, 2018-09-24 08:10:27, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.141190 +127.0.0.1, 2018-09-24 08:10:27, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.059447 +127.0.0.1, 2018-09-24 08:10:27, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.096429 +127.0.0.1, 2018-09-24 08:10:27, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064727 +127.0.0.1, 2018-09-24 08:10:27, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.097338 +127.0.0.1, 2018-09-24 08:10:27, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063352 +127.0.0.1, 2018-09-24 08:10:27, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.095219 +127.0.0.1, 2018-09-24 08:10:27, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.059510 +127.0.0.1, 2018-09-24 08:10:27, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.128956 +127.0.0.1, 2018-09-24 08:10:28, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.107095 +127.0.0.1, 2018-09-24 08:10:28, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.133057 +127.0.0.1, 2018-09-24 08:10:28, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.071182 +127.0.0.1, 2018-09-24 08:10:28, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.103611 +127.0.0.1, 2018-09-24 08:10:28, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.069039 +127.0.0.1, 2018-09-24 08:10:28, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.102557 +127.0.0.1, 2018-09-24 08:10:28, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061326 +127.0.0.1, 2018-09-24 08:10:28, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.094442 +127.0.0.1, 2018-09-24 08:10:28, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064436 +127.0.0.1, 2018-09-24 08:10:28, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.098341 +127.0.0.1, 2018-09-24 08:10:28, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.085382 +127.0.0.1, 2018-09-24 08:10:29, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.128030 +127.0.0.1, 2018-09-24 08:10:29, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.118042 +127.0.0.1, 2018-09-24 08:10:29, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.165388 +127.0.0.1, 2018-09-24 08:10:30, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.089458 +127.0.0.1, 2018-09-24 08:10:30, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.120508 +127.0.0.1, 2018-09-24 08:10:30, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.073656 +127.0.0.1, 2018-09-24 08:10:30, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.117919 +127.0.0.1, 2018-09-24 08:10:30, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.058595 +127.0.0.1, 2018-09-24 08:10:30, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.090413 +127.0.0.1, 2018-09-24 08:10:31, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.071876 +127.0.0.1, 2018-09-24 08:10:31, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.116635 +127.0.0.1, 2018-09-24 08:10:31, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072010 +127.0.0.1, 2018-09-24 08:10:31, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.111746 +127.0.0.1, 2018-09-24 08:10:31, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.068223 +127.0.0.1, 2018-09-24 08:10:31, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.106518 +127.0.0.1, 2018-09-24 08:10:31, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070388 +127.0.0.1, 2018-09-24 08:10:31, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.108804 +127.0.0.1, 2018-09-24 08:10:33, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.057668 +127.0.0.1, 2018-09-24 08:10:33, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.093493 +127.0.0.1, 2018-09-24 08:10:35, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.033957 +127.0.0.1, 2018-09-24 08:10:35, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.122960 +127.0.0.1, 2018-09-24 08:10:37, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060278 +127.0.0.1, 2018-09-24 08:10:37, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.092718 +127.0.0.1, 2018-09-24 08:10:39, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.057576 +127.0.0.1, 2018-09-24 08:10:39, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.173948 +127.0.0.1, 2018-09-24 08:10:39, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.148894 +127.0.0.1, 2018-09-24 08:10:40, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.213370 +127.0.0.1, 2018-09-24 08:10:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.104924 +127.0.0.1, 2018-09-24 08:10:40, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.145446 +127.0.0.1, 2018-09-24 08:10:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.071152 +127.0.0.1, 2018-09-24 08:10:40, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.106075 +127.0.0.1, 2018-09-24 08:10:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.079372 +127.0.0.1, 2018-09-24 08:10:40, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.114251 +127.0.0.1, 2018-09-24 08:10:41, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.093045 +127.0.0.1, 2018-09-24 08:10:41, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.135331 +127.0.0.1, 2018-09-24 08:10:41, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.095451 +127.0.0.1, 2018-09-24 08:10:41, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.138420 +127.0.0.1, 2018-09-24 08:10:41, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.065257 +127.0.0.1, 2018-09-24 08:10:41, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.140378 +127.0.0.1, 2018-09-24 08:10:41, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.071280 +127.0.0.1, 2018-09-24 08:10:41, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.105261 +127.0.0.1, 2018-09-24 08:10:42, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070589 +127.0.0.1, 2018-09-24 08:10:42, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.104522 +127.0.0.1, 2018-09-24 08:10:42, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061933 +127.0.0.1, 2018-09-24 08:10:42, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.094367 +127.0.0.1, 2018-09-24 08:10:42, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.065504 +127.0.0.1, 2018-09-24 08:10:42, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.099383 +127.0.0.1, 2018-09-24 08:10:42, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061485 +127.0.0.1, 2018-09-24 08:10:42, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.095250 +127.0.0.1, 2018-09-24 08:10:43, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.081035 +127.0.0.1, 2018-09-24 08:10:43, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.123909 +127.0.0.1, 2018-09-24 08:10:43, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.069891 +127.0.0.1, 2018-09-24 08:10:43, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.108153 +127.0.0.1, 2018-09-24 08:10:43, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061147 +127.0.0.1, 2018-09-24 08:10:43, GET, /SP/appadmin/userinfo, HTTP/1.1, 200, 0.108643 +127.0.0.1, 2018-09-24 08:13:24, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.001269 +127.0.0.1, 2018-09-24 08:13:24, GET, /, HTTP/1.1, 303, 0.008300 +127.0.0.1, 2018-09-24 08:13:24, GET, /welcome/static/css/calendar.css, HTTP/1.1, 304, 0.000666 +127.0.0.1, 2018-09-24 08:13:24, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.003796 +127.0.0.1, 2018-09-24 08:13:24, GET, /welcome/static/js/jquery.js, HTTP/1.1, 304, 0.003169 +127.0.0.1, 2018-09-24 08:13:24, GET, /welcome/static/js/calendar.js, HTTP/1.1, 304, 0.001589 +127.0.0.1, 2018-09-24 08:13:24, GET, /welcome/static/js/web2py.js, HTTP/1.1, 304, 0.002005 +127.0.0.1, 2018-09-24 08:13:24, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.005006 +127.0.0.1, 2018-09-24 08:13:24, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.000934 +127.0.0.1, 2018-09-24 08:13:24, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.000865 +127.0.0.1, 2018-09-24 08:13:25, GET, /welcome/default/index, HTTP/1.1, 200, 0.173961 +127.0.0.1, 2018-09-24 08:14:33, GET, /, HTTP/1.1, 303, 0.006514 +127.0.0.1, 2018-09-24 08:14:33, GET, /welcome/default/index, HTTP/1.1, 200, 0.110325 +127.0.0.1, 2018-09-24 08:14:38, GET, /, HTTP/1.1, 303, 0.000511 +127.0.0.1, 2018-09-24 08:14:38, GET, /welcome/default/index, HTTP/1.1, 200, 0.033311 +127.0.0.1, 2018-09-24 08:14:38, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.000555 +127.0.0.1, 2018-09-24 08:14:38, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.000928 +127.0.0.1, 2018-09-24 08:14:38, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.001134 +127.0.0.1, 2018-09-24 08:14:38, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.005995 +127.0.0.1, 2018-09-24 08:14:38, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.001604 +127.0.0.1, 2018-09-24 08:14:38, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.004511 +127.0.0.1, 2018-09-24 08:14:38, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.004287 +127.0.0.1, 2018-09-24 08:14:38, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.001851 +127.0.0.1, 2018-09-24 08:14:38, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.002034 +127.0.0.1, 2018-09-24 08:14:38, GET, /SP, HTTP/1.1, 200, 0.091625 +127.0.0.1, 2018-09-24 08:14:38, GET, /SP, HTTP/1.1, 200, 0.031742 +127.0.0.1, 2018-09-24 08:14:45, GET, /SP/appadmin/index, HTTP/1.1, 303, 0.027459 +127.0.0.1, 2018-09-24 08:14:45, GET, /admin/default/index, HTTP/1.1, 200, 0.174957 +127.0.0.1, 2018-09-24 08:14:46, GET, /SP/appadmin/index, HTTP/1.1, 303, 0.021140 +127.0.0.1, 2018-09-24 08:14:46, GET, /admin/default/index, HTTP/1.1, 200, 0.012643 +127.0.0.1, 2018-09-24 08:14:46, GET, /favicon.ico, HTTP/1.1, 400, 0.000226 +127.0.0.1, 2018-09-24 08:14:49, GET, /admin/default/index, HTTP/1.1, 200, 0.009966 +127.0.0.1, 2018-09-24 08:14:55, POST, /admin/default/index, HTTP/1.1, 303, 0.010645 +127.0.0.1, 2018-09-24 08:14:55, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.034516 +127.0.0.1, 2018-09-24 08:14:56, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.071613 +127.0.0.1, 2018-09-24 08:15:41, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.122211 +127.0.0.1, 2018-09-24 08:15:41, GET, /favicon.ico, HTTP/1.1, 400, 0.000356 +127.0.0.1, 2018-09-24 08:15:43, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.08-15-41.ea6d2041-094b-49ef-bc93-33ecdcc3e79b, HTTP/1.1, 200, 0.056484 +127.0.0.1, 2018-09-24 08:15:43, GET, /favicon.ico, HTTP/1.1, 400, 0.000219 +127.0.0.1, 2018-09-24 08:16:02, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.08-15-41.ea6d2041-094b-49ef-bc93-33ecdcc3e79b, HTTP/1.1, 200, 0.040873 +127.0.0.1, 2018-09-24 08:16:06, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.057665 +127.0.0.1, 2018-09-24 08:16:06, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.100861 +127.0.0.1, 2018-09-24 08:18:01, GET, /, HTTP/1.1, 303, 0.004513 +127.0.0.1, 2018-09-24 08:18:01, GET, /welcome/default/index, HTTP/1.1, 200, 0.110228 +127.0.0.1, 2018-09-24 08:18:59, GET, /, HTTP/1.1, 303, 0.005777 +127.0.0.1, 2018-09-24 08:18:59, GET, /welcome/default/index, HTTP/1.1, 200, 0.131740 +127.0.0.1, 2018-09-24 08:19:04, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.103055 +127.0.0.1, 2018-09-24 08:19:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.076638 +127.0.0.1, 2018-09-24 08:19:32, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.190173 +127.0.0.1, 2018-09-24 08:19:32, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.312299 +127.0.0.1, 2018-09-24 08:22:40, GET, /SP/appadmin, HTTP/1.1, 500, 0.062814 +127.0.0.1, 2018-09-24 08:22:40, GET, /favicon.ico, HTTP/1.1, 400, 0.000310 +127.0.0.1, 2018-09-24 08:22:42, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.08-22-40.023ae398-07f4-4b3f-90a1-481b3c4b3c00, HTTP/1.1, 200, 0.285393 +127.0.0.1, 2018-09-24 08:22:42, GET, /favicon.ico, HTTP/1.1, 400, 0.000209 +127.0.0.1, 2018-09-24 08:24:42, GET, /SP/appadmin, HTTP/1.1, 500, 0.079206 +127.0.0.1, 2018-09-24 08:24:42, GET, /favicon.ico, HTTP/1.1, 400, 0.000396 +127.0.0.1, 2018-09-24 08:24:44, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.08-24-42.f7b373a3-4254-4f43-895e-c6ec34004a4a, HTTP/1.1, 200, 0.031349 +127.0.0.1, 2018-09-24 08:24:44, GET, /favicon.ico, HTTP/1.1, 400, 0.000208 +127.0.0.1, 2018-09-24 08:24:53, GET, /SP/appadmin, HTTP/1.1, 200, 0.046758 +127.0.0.1, 2018-09-24 08:24:54, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.002238 +127.0.0.1, 2018-09-24 08:24:54, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.100125 +127.0.0.1, 2018-09-24 08:25:15, GET, /SP/appadmin, HTTP/1.1, 200, 0.044599 +127.0.0.1, 2018-09-24 08:25:15, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.002863 +127.0.0.1, 2018-09-24 08:25:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.122506 +127.0.0.1, 2018-09-24 08:25:44, GET, /SP/appadmin, HTTP/1.1, 200, 0.046136 +127.0.0.1, 2018-09-24 08:25:44, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001412 +127.0.0.1, 2018-09-24 08:25:45, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.097209 +127.0.0.1, 2018-09-24 08:26:16, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.050060 +127.0.0.1, 2018-09-24 08:26:21, GET, /SP/static/js/bootstrap.bundle.min.js.map, HTTP/1.1, 304, 0.000596 +127.0.0.1, 2018-09-24 08:26:21, GET, /SP/static/css/bootstrap.min.css.map, HTTP/1.1, 304, 0.000527 +127.0.0.1, 2018-09-24 08:27:00, GET, /SP/appadmin, HTTP/1.1, 200, 0.040013 +127.0.0.1, 2018-09-24 08:27:00, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.090821 +127.0.0.1, 2018-09-24 08:27:12, GET, /SP/appadmin, HTTP/1.1, 200, 0.052429 +127.0.0.1, 2018-09-24 08:27:12, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001905 +127.0.0.1, 2018-09-24 08:27:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.104414 +127.0.0.1, 2018-09-24 08:27:16, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.039151 +127.0.0.1, 2018-09-24 08:27:43, GET, /SP/appadmin, HTTP/1.1, 200, 0.037768 +127.0.0.1, 2018-09-24 08:27:44, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.102229 +127.0.0.1, 2018-09-24 08:29:03, GET, /SP/appadmin, HTTP/1.1, 500, 0.065443 +127.0.0.1, 2018-09-24 08:29:04, GET, /favicon.ico, HTTP/1.1, 400, 0.000344 +127.0.0.1, 2018-09-24 08:29:06, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.08-29-03.1c9b8f34-d7c2-49a8-b5b5-0e2895e4db4e, HTTP/1.1, 200, 0.109068 +127.0.0.1, 2018-09-24 08:29:06, GET, /favicon.ico, HTTP/1.1, 400, 0.000312 +127.0.0.1, 2018-09-24 08:29:24, GET, /SP/appadmin, HTTP/1.1, 200, 0.039812 +127.0.0.1, 2018-09-24 08:29:24, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001043 +127.0.0.1, 2018-09-24 08:29:24, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.066282 +127.0.0.1, 2018-09-24 08:29:43, GET, /SP/appadmin, HTTP/1.1, 200, 0.065767 +127.0.0.1, 2018-09-24 08:29:43, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001553 +127.0.0.1, 2018-09-24 08:29:43, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.141153 +127.0.0.1, 2018-09-24 08:30:46, GET, /SP/appadmin, HTTP/1.1, 200, 0.045141 +127.0.0.1, 2018-09-24 08:30:47, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000725 +127.0.0.1, 2018-09-24 08:30:47, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.071505 +127.0.0.1, 2018-09-24 08:31:04, GET, /SP/appadmin, HTTP/1.1, 200, 0.047332 +127.0.0.1, 2018-09-24 08:31:04, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000382 +127.0.0.1, 2018-09-24 08:31:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.088449 +127.0.0.1, 2018-09-24 08:32:42, GET, /SP/appadmin, HTTP/1.1, 500, 0.096879 +127.0.0.1, 2018-09-24 08:32:42, GET, /favicon.ico, HTTP/1.1, 400, 0.000217 +127.0.0.1, 2018-09-24 08:34:27, GET, /SP/appadmin, HTTP/1.1, 200, 0.110820 +127.0.0.1, 2018-09-24 08:34:28, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001273 +127.0.0.1, 2018-09-24 08:34:28, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.073519 +127.0.0.1, 2018-09-24 08:34:35, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.045578 +127.0.0.1, 2018-09-24 08:35:09, GET, /SP/appadmin/, HTTP/1.1, 200, 0.041158 +127.0.0.1, 2018-09-24 08:35:09, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061981 +127.0.0.1, 2018-09-24 08:37:03, GET, /SP/appadmin/, HTTP/1.1, 200, 0.049103 +127.0.0.1, 2018-09-24 08:37:04, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000983 +127.0.0.1, 2018-09-24 08:37:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.078513 +127.0.0.1, 2018-09-24 08:38:19, GET, /SP/appadmin/, HTTP/1.1, 500, 0.076056 +127.0.0.1, 2018-09-24 08:38:19, GET, /favicon.ico, HTTP/1.1, 400, 0.000273 +127.0.0.1, 2018-09-24 08:38:46, GET, /SP/appadmin/, HTTP/1.1, 500, 0.074717 +127.0.0.1, 2018-09-24 08:38:47, GET, /favicon.ico, HTTP/1.1, 400, 0.000303 +127.0.0.1, 2018-09-24 08:38:48, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.08-38-46.857a877d-3dee-4bcd-a2fa-d0d3eb6988e3, HTTP/1.1, 200, 0.126858 +127.0.0.1, 2018-09-24 08:38:48, GET, /favicon.ico, HTTP/1.1, 400, 0.000349 +127.0.0.1, 2018-09-24 08:39:18, GET, /SP/appadmin/, HTTP/1.1, 200, 0.041794 +127.0.0.1, 2018-09-24 08:39:19, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000707 +127.0.0.1, 2018-09-24 08:39:19, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064517 +127.0.0.1, 2018-09-24 08:39:39, GET, /SP/appadmin/, HTTP/1.1, 200, 0.042280 +127.0.0.1, 2018-09-24 08:39:39, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000920 +127.0.0.1, 2018-09-24 08:39:39, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.076971 +127.0.0.1, 2018-09-24 08:40:06, GET, /SP/appadmin/, HTTP/1.1, 200, 0.052345 +127.0.0.1, 2018-09-24 08:40:07, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001361 +127.0.0.1, 2018-09-24 08:40:07, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.103071 +127.0.0.1, 2018-09-24 08:40:48, GET, /SP/appadmin/, HTTP/1.1, 200, 0.050575 +127.0.0.1, 2018-09-24 08:40:49, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000656 +127.0.0.1, 2018-09-24 08:40:49, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.101399 +127.0.0.1, 2018-09-24 08:41:07, GET, /SP/appadmin, HTTP/1.1, 200, 0.035896 +127.0.0.1, 2018-09-24 08:41:07, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072344 +127.0.0.1, 2018-09-24 08:41:19, GET, /SP/appadmin, HTTP/1.1, 200, 0.075029 +127.0.0.1, 2018-09-24 08:41:19, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000557 +127.0.0.1, 2018-09-24 08:41:19, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.143032 +127.0.0.1, 2018-09-24 08:43:17, GET, /SP/appadmin, HTTP/1.1, 200, 0.035672 +127.0.0.1, 2018-09-24 08:43:17, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001335 +127.0.0.1, 2018-09-24 08:43:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.087676 +127.0.0.1, 2018-09-24 08:43:43, GET, /SP/appadmin, HTTP/1.1, 200, 0.041051 +127.0.0.1, 2018-09-24 08:43:44, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000756 +127.0.0.1, 2018-09-24 08:43:44, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.088843 +127.0.0.1, 2018-09-24 08:45:01, GET, /SP/appadmin, HTTP/1.1, 200, 0.040583 +127.0.0.1, 2018-09-24 08:45:01, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001323 +127.0.0.1, 2018-09-24 08:45:01, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.076601 +127.0.0.1, 2018-09-24 08:46:21, GET, /SP/appadmin, HTTP/1.1, 200, 0.056936 +127.0.0.1, 2018-09-24 08:46:22, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.010078 +127.0.0.1, 2018-09-24 08:46:22, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.154603 +127.0.0.1, 2018-09-24 08:46:36, GET, /SP/appadmin, HTTP/1.1, 200, 0.044619 +127.0.0.1, 2018-09-24 08:46:36, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001543 +127.0.0.1, 2018-09-24 08:46:36, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.083517 +127.0.0.1, 2018-09-24 08:46:40, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 404, 0.024396 +127.0.0.1, 2018-09-24 08:46:40, GET, /favicon.ico, HTTP/1.1, 400, 0.000212 +127.0.0.1, 2018-09-24 08:46:43, GET, /SP/appadmin, HTTP/1.1, 200, 0.035596 +127.0.0.1, 2018-09-24 08:46:43, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.059166 +127.0.0.1, 2018-09-24 08:47:46, GET, /SP/appadmin, HTTP/1.1, 200, 0.035842 +127.0.0.1, 2018-09-24 08:47:46, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001088 +127.0.0.1, 2018-09-24 08:47:54, GET, /SP/appadmin, HTTP/1.1, 200, 0.029562 +127.0.0.1, 2018-09-24 08:48:07, GET, /SP/appadmin, HTTP/1.1, 200, 0.040884 +127.0.0.1, 2018-09-24 08:48:08, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000799 +127.0.0.1, 2018-09-24 08:48:08, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067284 +127.0.0.1, 2018-09-24 08:52:46, GET, /SP/appadmin, HTTP/1.1, 200, 0.052519 +127.0.0.1, 2018-09-24 08:52:47, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000640 +127.0.0.1, 2018-09-24 08:52:47, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072993 +127.0.0.1, 2018-09-24 08:52:51, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 404, 0.018297 +127.0.0.1, 2018-09-24 08:52:51, GET, /favicon.ico, HTTP/1.1, 400, 0.000230 +127.0.0.1, 2018-09-24 08:52:57, GET, /SP/appadmin, HTTP/1.1, 200, 0.039790 +127.0.0.1, 2018-09-24 08:52:57, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060825 +127.0.0.1, 2018-09-24 08:53:25, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.065818 +127.0.0.1, 2018-09-24 08:53:28, GET, /SP/appadmin, HTTP/1.1, 200, 0.040186 +127.0.0.1, 2018-09-24 08:53:29, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.092774 +127.0.0.1, 2018-09-24 08:53:46, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.052922 +127.0.0.1, 2018-09-24 08:55:12, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.055556 +127.0.0.1, 2018-09-24 08:55:13, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.065765 +127.0.0.1, 2018-09-24 08:55:15, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.064583 +127.0.0.1, 2018-09-24 08:55:17, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.045442 +127.0.0.1, 2018-09-24 08:55:17, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000526 +127.0.0.1, 2018-09-24 08:55:30, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.049833 +127.0.0.1, 2018-09-24 08:55:30, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000648 +127.0.0.1, 2018-09-24 08:55:33, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.035324 +127.0.0.1, 2018-09-24 08:55:33, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000676 +127.0.0.1, 2018-09-24 08:55:55, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.041246 +127.0.0.1, 2018-09-24 08:55:55, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000911 +127.0.0.1, 2018-09-24 08:55:57, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.033892 +127.0.0.1, 2018-09-24 08:55:57, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001292 +127.0.0.1, 2018-09-24 08:56:06, GET, /SP/appadmin/change_userinfo, HTTP/1.1, 200, 0.038724 +127.0.0.1, 2018-09-24 08:56:10, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.121969 +127.0.0.1, 2018-09-24 08:56:10, GET, /favicon.ico, HTTP/1.1, 400, 0.000303 +127.0.0.1, 2018-09-24 08:56:12, GET, /SP/appadmin/change_userinfo, HTTP/1.1, 200, 0.032816 +127.0.0.1, 2018-09-24 08:56:14, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.052942 +127.0.0.1, 2018-09-24 08:56:14, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.077539 +127.0.0.1, 2018-09-24 08:56:16, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.043221 +127.0.0.1, 2018-09-24 08:56:30, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.033202 +127.0.0.1, 2018-09-24 08:56:32, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.036306 +127.0.0.1, 2018-09-24 08:56:32, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000714 +127.0.0.1, 2018-09-24 08:57:12, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.033497 +127.0.0.1, 2018-09-24 08:57:12, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000388 +127.0.0.1, 2018-09-24 08:57:14, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.032780 +127.0.0.1, 2018-09-24 08:57:14, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000596 +127.0.0.1, 2018-09-24 09:07:00, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.054259 +127.0.0.1, 2018-09-24 09:07:00, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.066468 +127.0.0.1, 2018-09-24 09:07:03, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.032228 +127.0.0.1, 2018-09-24 09:07:03, GET, /SP/static/images/favicon.ico, HTTP/1.1, 304, 0.000577 +127.0.0.1, 2018-09-24 09:07:11, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.039103 +127.0.0.1, 2018-09-24 09:07:12, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.036679 +127.0.0.1, 2018-09-24 09:07:15, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.032970 +127.0.0.1, 2018-09-24 09:10:54, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.077314 +127.0.0.1, 2018-09-24 09:10:54, GET, /favicon.ico, HTTP/1.1, 400, 0.000505 +127.0.0.1, 2018-09-24 09:10:55, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-10-54.00af0054-046e-4db4-90e7-bdec8baaea3c, HTTP/1.1, 200, 0.098754 +127.0.0.1, 2018-09-24 09:10:56, GET, /favicon.ico, HTTP/1.1, 400, 0.000324 +127.0.0.1, 2018-09-24 09:11:17, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-10-54.00af0054-046e-4db4-90e7-bdec8baaea3c, HTTP/1.1, 200, 0.090416 +127.0.0.1, 2018-09-24 09:11:18, GET, /favicon.ico, HTTP/1.1, 400, 0.000260 +127.0.0.1, 2018-09-24 09:11:20, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.114057 +127.0.0.1, 2018-09-24 09:11:20, GET, /favicon.ico, HTTP/1.1, 400, 0.000268 +127.0.0.1, 2018-09-24 09:11:22, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-11-20.4528f3cf-8a45-4a61-8537-1f8323b876c0, HTTP/1.1, 200, 0.066858 +127.0.0.1, 2018-09-24 09:11:22, GET, /favicon.ico, HTTP/1.1, 400, 0.000271 +127.0.0.1, 2018-09-24 09:11:55, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.053698 +127.0.0.1, 2018-09-24 09:11:56, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000498 +127.0.0.1, 2018-09-24 09:13:03, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.056627 +127.0.0.1, 2018-09-24 09:13:03, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000487 +127.0.0.1, 2018-09-24 09:13:04, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.042931 +127.0.0.1, 2018-09-24 09:13:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070915 +127.0.0.1, 2018-09-24 09:13:10, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.055008 +127.0.0.1, 2018-09-24 09:13:10, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000530 +127.0.0.1, 2018-09-24 09:13:10, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.131482 +127.0.0.1, 2018-09-24 09:13:40, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.054008 +127.0.0.1, 2018-09-24 09:13:40, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000642 +127.0.0.1, 2018-09-24 09:13:46, GET, /SP/appadmin/change_userinfo, HTTP/1.1, 500, 0.057740 +127.0.0.1, 2018-09-24 09:13:46, GET, /favicon.ico, HTTP/1.1, 400, 0.000211 +127.0.0.1, 2018-09-24 09:13:48, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-13-46.d8b4b653-2531-42c0-aea9-ae7d45b688b8, HTTP/1.1, 200, 0.053985 +127.0.0.1, 2018-09-24 09:13:49, GET, /favicon.ico, HTTP/1.1, 400, 0.000223 +127.0.0.1, 2018-09-24 09:13:56, GET, /SP/appadmin/change_userinfo, HTTP/1.1, 200, 0.082123 +127.0.0.1, 2018-09-24 09:13:56, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000621 +127.0.0.1, 2018-09-24 09:13:57, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.072839 +127.0.0.1, 2018-09-24 09:13:57, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.096670 +127.0.0.1, 2018-09-24 09:13:59, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.049657 +127.0.0.1, 2018-09-24 09:14:02, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.038000 +127.0.0.1, 2018-09-24 09:14:03, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.098713 +127.0.0.1, 2018-09-24 09:14:08, GET, /SP/appadmin/change_userinfo, HTTP/1.1, 200, 0.035377 +127.0.0.1, 2018-09-24 09:14:11, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.042432 +127.0.0.1, 2018-09-24 09:14:23, GET, /SP/appadmin/, HTTP/1.1, 200, 0.043915 +127.0.0.1, 2018-09-24 09:14:24, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061150 +127.0.0.1, 2018-09-24 09:14:26, GET, /SP/appadmin/insert/db/auth_user, HTTP/1.1, 200, 0.049138 +127.0.0.1, 2018-09-24 09:15:52, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.053713 +127.0.0.1, 2018-09-24 09:15:53, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.091429 +127.0.0.1, 2018-09-24 09:15:55, GET, /SP/appadmin/change_userinfo, HTTP/1.1, 200, 0.040022 +127.0.0.1, 2018-09-24 09:16:39, GET, /SP/appadmin/change_userinfo, HTTP/1.1, 200, 0.081064 +127.0.0.1, 2018-09-24 09:16:39, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000652 +127.0.0.1, 2018-09-24 09:16:41, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.048408 +127.0.0.1, 2018-09-24 09:16:41, GET, /SP/appadmin/insert/db/auth_user, HTTP/1.1, 200, 0.050532 +127.0.0.1, 2018-09-24 09:16:41, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.131231 +127.0.0.1, 2018-09-24 09:16:43, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.045187 +127.0.0.1, 2018-09-24 09:16:43, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.098681 +127.0.0.1, 2018-09-24 09:16:45, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.038842 +127.0.0.1, 2018-09-24 09:16:47, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.043055 +127.0.0.1, 2018-09-24 09:16:48, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.071936 +127.0.0.1, 2018-09-24 09:17:05, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.079387 +127.0.0.1, 2018-09-24 09:17:05, GET, /favicon.ico, HTTP/1.1, 400, 0.000216 +127.0.0.1, 2018-09-24 09:17:06, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-17-05.4d34eeca-bbf3-4340-aa15-b4fbc1f327f7, HTTP/1.1, 200, 0.071506 +127.0.0.1, 2018-09-24 09:17:06, GET, /favicon.ico, HTTP/1.1, 400, 0.000211 +127.0.0.1, 2018-09-24 09:17:09, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.043818 +127.0.0.1, 2018-09-24 09:17:09, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.082607 +127.0.0.1, 2018-09-24 09:17:53, GET, /SP/appadmin/insert/db/auth_user, HTTP/1.1, 200, 0.058149 +127.0.0.1, 2018-09-24 09:18:23, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.078792 +127.0.0.1, 2018-09-24 09:18:24, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.103857 +127.0.0.1, 2018-09-24 09:18:26, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.081070 +127.0.0.1, 2018-09-24 09:18:26, GET, /favicon.ico, HTTP/1.1, 400, 0.000312 +127.0.0.1, 2018-09-24 09:18:28, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-18-26.80b9fe72-c085-4a2e-aad2-3d3782b91f71, HTTP/1.1, 200, 0.122415 +127.0.0.1, 2018-09-24 09:18:29, GET, /favicon.ico, HTTP/1.1, 400, 0.000461 +127.0.0.1, 2018-09-24 09:18:43, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.067891 +127.0.0.1, 2018-09-24 09:18:44, GET, /favicon.ico, HTTP/1.1, 400, 0.000220 +127.0.0.1, 2018-09-24 09:18:45, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-18-43.5d399fbd-6813-4f00-a84f-8b4848e0f3ac, HTTP/1.1, 200, 0.130691 +127.0.0.1, 2018-09-24 09:18:46, GET, /favicon.ico, HTTP/1.1, 400, 0.000216 +127.0.0.1, 2018-09-24 09:19:03, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.063904 +127.0.0.1, 2018-09-24 09:19:03, GET, /favicon.ico, HTTP/1.1, 400, 0.000217 +127.0.0.1, 2018-09-24 09:19:22, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.140967 +127.0.0.1, 2018-09-24 09:19:23, GET, /favicon.ico, HTTP/1.1, 400, 0.000586 +127.0.0.1, 2018-09-24 09:19:30, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.064649 +127.0.0.1, 2018-09-24 09:19:30, GET, /favicon.ico, HTTP/1.1, 400, 0.000546 +127.0.0.1, 2018-09-24 09:19:32, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-19-30.e188909e-d416-4a0f-83f7-24b5b8b446f1, HTTP/1.1, 200, 0.035337 +127.0.0.1, 2018-09-24 09:19:33, GET, /favicon.ico, HTTP/1.1, 400, 0.000335 +127.0.0.1, 2018-09-24 09:19:46, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.044998 +127.0.0.1, 2018-09-24 09:19:46, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000912 +127.0.0.1, 2018-09-24 09:19:55, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.065117 +127.0.0.1, 2018-09-24 09:19:55, GET, /favicon.ico, HTTP/1.1, 400, 0.000230 +127.0.0.1, 2018-09-24 09:19:57, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-19-55.f3486e48-a46b-4b1d-9766-322d984ab403, HTTP/1.1, 200, 0.130141 +127.0.0.1, 2018-09-24 09:19:57, GET, /favicon.ico, HTTP/1.1, 400, 0.000225 +127.0.0.1, 2018-09-24 09:20:59, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.061996 +127.0.0.1, 2018-09-24 09:21:00, GET, /favicon.ico, HTTP/1.1, 400, 0.000333 +127.0.0.1, 2018-09-24 09:21:00, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-20-59.a438a8ee-87fb-4c00-b300-5785e2b34fc5, HTTP/1.1, 200, 0.031188 +127.0.0.1, 2018-09-24 09:21:01, GET, /favicon.ico, HTTP/1.1, 400, 0.000215 +127.0.0.1, 2018-09-24 09:21:13, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.047267 +127.0.0.1, 2018-09-24 09:21:13, GET, /favicon.ico, HTTP/1.1, 400, 0.000454 +127.0.0.1, 2018-09-24 09:21:15, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-21-13.c8881e31-9041-40b3-9b56-75af994d315e, HTTP/1.1, 200, 0.032637 +127.0.0.1, 2018-09-24 09:21:15, GET, /favicon.ico, HTTP/1.1, 400, 0.000216 +127.0.0.1, 2018-09-24 09:22:50, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.050616 +127.0.0.1, 2018-09-24 09:22:50, GET, /favicon.ico, HTTP/1.1, 400, 0.000288 +127.0.0.1, 2018-09-24 09:22:51, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-22-50.6ca44238-476a-4e60-a011-a3957354ae63, HTTP/1.1, 200, 0.029176 +127.0.0.1, 2018-09-24 09:22:51, GET, /favicon.ico, HTTP/1.1, 400, 0.000271 +127.0.0.1, 2018-09-24 09:23:07, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.074437 +127.0.0.1, 2018-09-24 09:23:07, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000789 +127.0.0.1, 2018-09-24 09:23:26, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.042087 +127.0.0.1, 2018-09-24 09:23:31, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.041325 +127.0.0.1, 2018-09-24 09:25:18, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.068018 +127.0.0.1, 2018-09-24 09:25:18, GET, /favicon.ico, HTTP/1.1, 400, 0.000458 +127.0.0.1, 2018-09-24 09:25:19, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-25-18.a7715c2e-8aea-43ca-a2bb-1a1bc2abf4ec, HTTP/1.1, 200, 0.034321 +127.0.0.1, 2018-09-24 09:25:20, GET, /favicon.ico, HTTP/1.1, 400, 0.000209 +127.0.0.1, 2018-09-24 09:25:33, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.066865 +127.0.0.1, 2018-09-24 09:25:33, GET, /favicon.ico, HTTP/1.1, 400, 0.000494 +127.0.0.1, 2018-09-24 09:25:34, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-25-33.c08338aa-9678-448b-a0c6-4a3857eb7a5e, HTTP/1.1, 200, 0.031725 +127.0.0.1, 2018-09-24 09:25:34, GET, /favicon.ico, HTTP/1.1, 400, 0.000223 +127.0.0.1, 2018-09-24 09:25:43, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.048296 +127.0.0.1, 2018-09-24 09:25:44, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000617 +127.0.0.1, 2018-09-24 09:25:54, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.090302 +127.0.0.1, 2018-09-24 09:25:54, GET, /favicon.ico, HTTP/1.1, 400, 0.000212 +127.0.0.1, 2018-09-24 09:26:00, GET, /SP/appadmin/, HTTP/1.1, 200, 0.044256 +127.0.0.1, 2018-09-24 09:26:00, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.082738 +127.0.0.1, 2018-09-24 09:26:04, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.065194 +127.0.0.1, 2018-09-24 09:26:16, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.051760 +127.0.0.1, 2018-09-24 09:26:16, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000787 +127.0.0.1, 2018-09-24 09:27:52, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.074577 +127.0.0.1, 2018-09-24 09:27:52, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000725 +127.0.0.1, 2018-09-24 09:28:02, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.058674 +127.0.0.1, 2018-09-24 09:28:28, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.045228 +127.0.0.1, 2018-09-24 09:28:29, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001069 +127.0.0.1, 2018-09-24 09:29:00, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.047905 +127.0.0.1, 2018-09-24 09:29:00, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000775 +127.0.0.1, 2018-09-24 09:37:26, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.078341 +127.0.0.1, 2018-09-24 09:37:27, GET, /favicon.ico, HTTP/1.1, 400, 0.000310 +127.0.0.1, 2018-09-24 09:37:28, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-37-26.91dd915f-96bc-4e97-ac3f-631b5e47fc97, HTTP/1.1, 200, 0.038575 +127.0.0.1, 2018-09-24 09:37:28, GET, /favicon.ico, HTTP/1.1, 400, 0.000199 +127.0.0.1, 2018-09-24 09:37:42, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-37-26.91dd915f-96bc-4e97-ac3f-631b5e47fc97, HTTP/1.1, 200, 0.029606 +127.0.0.1, 2018-09-24 09:37:43, GET, /favicon.ico, HTTP/1.1, 400, 0.000265 +127.0.0.1, 2018-09-24 09:37:45, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.081400 +127.0.0.1, 2018-09-24 09:37:46, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000868 +127.0.0.1, 2018-09-24 09:37:53, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.091885 +127.0.0.1, 2018-09-24 09:37:53, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000511 +127.0.0.1, 2018-09-24 09:39:15, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.100565 +127.0.0.1, 2018-09-24 09:39:16, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000445 +127.0.0.1, 2018-09-24 09:39:46, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 500, 0.110497 +127.0.0.1, 2018-09-24 09:39:46, GET, /favicon.ico, HTTP/1.1, 400, 0.000330 +127.0.0.1, 2018-09-24 09:39:54, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.067827 +127.0.0.1, 2018-09-24 09:39:54, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000518 +127.0.0.1, 2018-09-24 09:40:01, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.060759 +127.0.0.1, 2018-09-24 09:41:00, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.075327 +127.0.0.1, 2018-09-24 09:41:01, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000689 +127.0.0.1, 2018-09-24 09:41:11, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.069726 +127.0.0.1, 2018-09-24 09:41:15, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.054001 +127.0.0.1, 2018-09-24 09:41:15, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000602 +127.0.0.1, 2018-09-24 09:43:21, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.068739 +127.0.0.1, 2018-09-24 09:43:22, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000745 +127.0.0.1, 2018-09-24 09:43:24, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.052029 +127.0.0.1, 2018-09-24 09:43:34, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.042782 +127.0.0.1, 2018-09-24 09:43:35, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000442 +127.0.0.1, 2018-09-24 09:44:02, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.056476 +127.0.0.1, 2018-09-24 09:44:42, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.059462 +127.0.0.1, 2018-09-24 09:44:48, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.053029 +127.0.0.1, 2018-09-24 09:44:48, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000670 +127.0.0.1, 2018-09-24 09:44:49, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.054912 +127.0.0.1, 2018-09-24 09:46:16, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.073204 +127.0.0.1, 2018-09-24 09:46:16, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000541 +127.0.0.1, 2018-09-24 09:46:19, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.055447 +127.0.0.1, 2018-09-24 09:46:21, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.042000 +127.0.0.1, 2018-09-24 09:46:23, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.047982 +127.0.0.1, 2018-09-24 09:46:27, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.072406 +127.0.0.1, 2018-09-24 09:46:30, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.053480 +127.0.0.1, 2018-09-24 09:46:30, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000686 +127.0.0.1, 2018-09-24 09:46:45, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.061587 +127.0.0.1, 2018-09-24 09:46:45, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000710 +127.0.0.1, 2018-09-24 09:46:46, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.046025 +127.0.0.1, 2018-09-24 09:46:50, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.068333 +127.0.0.1, 2018-09-24 09:46:51, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.058986 +127.0.0.1, 2018-09-24 09:46:54, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.041677 +127.0.0.1, 2018-09-24 09:46:54, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000548 +127.0.0.1, 2018-09-24 09:48:41, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.063172 +127.0.0.1, 2018-09-24 09:48:41, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000630 +127.0.0.1, 2018-09-24 09:48:53, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.051405 +127.0.0.1, 2018-09-24 09:48:53, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000385 +127.0.0.1, 2018-09-24 09:48:57, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.048804 +127.0.0.1, 2018-09-24 09:49:01, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.041127 +127.0.0.1, 2018-09-24 09:49:01, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000589 +127.0.0.1, 2018-09-24 09:49:05, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.047117 +127.0.0.1, 2018-09-24 09:49:07, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.049092 +127.0.0.1, 2018-09-24 09:49:20, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.085866 +127.0.0.1, 2018-09-24 09:49:21, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.044326 +127.0.0.1, 2018-09-24 09:49:25, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.068861 +127.0.0.1, 2018-09-24 09:49:27, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.041814 +127.0.0.1, 2018-09-24 09:49:27, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.109204 +127.0.0.1, 2018-09-24 09:49:33, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.081659 +127.0.0.1, 2018-09-24 09:49:35, POST, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.055367 +127.0.0.1, 2018-09-24 09:49:44, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.037367 +127.0.0.1, 2018-09-24 09:49:46, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.037149 +127.0.0.1, 2018-09-24 09:49:47, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.075703 +127.0.0.1, 2018-09-24 09:50:22, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.037943 +127.0.0.1, 2018-09-24 09:50:22, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000617 +127.0.0.1, 2018-09-24 09:50:22, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.095437 +127.0.0.1, 2018-09-24 09:50:24, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.042622 +127.0.0.1, 2018-09-24 09:50:48, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.037854 +127.0.0.1, 2018-09-24 09:50:49, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000711 +127.0.0.1, 2018-09-24 09:51:04, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.039797 +127.0.0.1, 2018-09-24 09:51:04, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000695 +127.0.0.1, 2018-09-24 09:51:12, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.037634 +127.0.0.1, 2018-09-24 09:51:12, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001478 +127.0.0.1, 2018-09-24 09:51:16, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.041545 +127.0.0.1, 2018-09-24 09:51:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.101127 +127.0.0.1, 2018-09-24 09:56:48, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.071942 +127.0.0.1, 2018-09-24 09:56:49, GET, /favicon.ico, HTTP/1.1, 400, 0.000427 +127.0.0.1, 2018-09-24 09:56:55, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-56-48.779ad15d-f9cb-4edb-9c0b-56a9a8f12acc, HTTP/1.1, 200, 0.135284 +127.0.0.1, 2018-09-24 09:56:55, GET, /favicon.ico, HTTP/1.1, 400, 0.000210 +127.0.0.1, 2018-09-24 09:57:42, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.071866 +127.0.0.1, 2018-09-24 09:57:42, GET, /favicon.ico, HTTP/1.1, 400, 0.000369 +127.0.0.1, 2018-09-24 09:57:44, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-57-42.e1353019-1e13-4c2f-90c4-19bbc31e04e4, HTTP/1.1, 200, 0.207000 +127.0.0.1, 2018-09-24 09:57:44, GET, /favicon.ico, HTTP/1.1, 400, 0.000372 +127.0.0.1, 2018-09-24 09:59:16, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.09-57-42.e1353019-1e13-4c2f-90c4-19bbc31e04e4, HTTP/1.1, 200, 0.130555 +127.0.0.1, 2018-09-24 09:59:16, GET, /favicon.ico, HTTP/1.1, 400, 0.000201 +127.0.0.1, 2018-09-24 10:01:01, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.083578 +127.0.0.1, 2018-09-24 10:01:01, GET, /favicon.ico, HTTP/1.1, 400, 0.000323 +127.0.0.1, 2018-09-24 10:01:02, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.10-01-01.038b136a-cea0-412b-88c7-467ec747a1c2, HTTP/1.1, 200, 0.112115 +127.0.0.1, 2018-09-24 10:01:02, GET, /favicon.ico, HTTP/1.1, 400, 0.000392 +127.0.0.1, 2018-09-24 10:01:28, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.10-01-01.038b136a-cea0-412b-88c7-467ec747a1c2, HTTP/1.1, 200, 0.197919 +127.0.0.1, 2018-09-24 10:01:29, GET, /favicon.ico, HTTP/1.1, 400, 0.000306 +127.0.0.1, 2018-09-24 10:01:31, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.053081 +127.0.0.1, 2018-09-24 10:01:31, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000590 +127.0.0.1, 2018-09-24 10:01:31, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.085175 +127.0.0.1, 2018-09-24 10:04:45, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.061424 +127.0.0.1, 2018-09-24 10:04:45, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.002255 +127.0.0.1, 2018-09-24 10:04:45, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.078770 +127.0.0.1, 2018-09-24 10:04:47, GET, /SP/appadmin/change_user/Saturn, HTTP/1.1, 500, 0.062144 +127.0.0.1, 2018-09-24 10:04:47, GET, /favicon.ico, HTTP/1.1, 400, 0.000371 +127.0.0.1, 2018-09-24 10:04:49, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.053811 +127.0.0.1, 2018-09-24 10:04:49, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.074754 +127.0.0.1, 2018-09-24 10:04:52, GET, /SP/appadmin/change_user/Saturn, HTTP/1.1, 500, 0.051871 +127.0.0.1, 2018-09-24 10:04:52, GET, /favicon.ico, HTTP/1.1, 400, 0.000219 +127.0.0.1, 2018-09-24 10:04:53, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.10-04-52.8b0edbf8-188e-4ef2-8bee-e2997d063642, HTTP/1.1, 200, 0.036678 +127.0.0.1, 2018-09-24 10:04:53, GET, /favicon.ico, HTTP/1.1, 400, 0.000216 +127.0.0.1, 2018-09-24 10:04:58, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.066601 +127.0.0.1, 2018-09-24 10:04:58, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.088478 +127.0.0.1, 2018-09-24 10:05:35, GET, /SP/appadmin/change_user/Saturn, HTTP/1.1, 200, 0.074222 +127.0.0.1, 2018-09-24 10:05:37, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.048289 +127.0.0.1, 2018-09-24 10:05:37, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.076686 +127.0.0.1, 2018-09-24 10:06:09, GET, /SP/appadmin/change_user/Saturn, HTTP/1.1, 200, 0.058107 +127.0.0.1, 2018-09-24 10:06:23, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.044123 +127.0.0.1, 2018-09-24 10:06:24, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.068407 +127.0.0.1, 2018-09-24 10:12:36, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.075872 +127.0.0.1, 2018-09-24 10:12:36, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.003219 +127.0.0.1, 2018-09-24 10:12:36, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.069689 +127.0.0.1, 2018-09-24 10:12:58, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.059428 +127.0.0.1, 2018-09-24 10:12:59, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000942 +127.0.0.1, 2018-09-24 10:12:59, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.123532 +127.0.0.1, 2018-09-24 10:13:05, GET, /SP/appadmin/change_user/Saturn, HTTP/1.1, 200, 0.059102 +127.0.0.1, 2018-09-24 10:13:12, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.039370 +127.0.0.1, 2018-09-24 10:13:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.129673 +127.0.0.1, 2018-09-24 10:14:01, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.046776 +127.0.0.1, 2018-09-24 10:14:02, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.003275 +127.0.0.1, 2018-09-24 10:14:02, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.075280 +127.0.0.1, 2018-09-24 10:14:04, GET, /SP/appadmin/change_user, HTTP/1.1, 200, 0.063570 +127.0.0.1, 2018-09-24 10:14:31, POST, /SP/appadmin/change_user, HTTP/1.1, 200, 0.061048 +127.0.0.1, 2018-09-24 10:14:34, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.042470 +127.0.0.1, 2018-09-24 10:14:34, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.087043 +127.0.0.1, 2018-09-24 10:16:52, GET, /SP/appadmin/change_user, HTTP/1.1, 200, 0.061417 +127.0.0.1, 2018-09-24 10:16:55, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.044244 +127.0.0.1, 2018-09-24 10:16:56, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.082943 +127.0.0.1, 2018-09-24 10:17:02, GET, /SP/appadmin/add_user, HTTP/1.1, 200, 0.061327 +127.0.0.1, 2018-09-24 10:17:04, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.047257 +127.0.0.1, 2018-09-24 10:17:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.119303 +127.0.0.1, 2018-09-24 10:17:36, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.048877 +127.0.0.1, 2018-09-24 10:17:36, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001487 +127.0.0.1, 2018-09-24 10:17:37, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.091294 +127.0.0.1, 2018-09-24 10:17:38, GET, /SP/appadmin/add_user, HTTP/1.1, 200, 0.050061 +127.0.0.1, 2018-09-24 10:17:41, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.040719 +127.0.0.1, 2018-09-24 10:17:41, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.077528 +127.0.0.1, 2018-09-24 10:18:55, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.069123 +127.0.0.1, 2018-09-24 10:18:55, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001253 +127.0.0.1, 2018-09-24 10:18:55, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.118746 +127.0.0.1, 2018-09-24 10:18:59, GET, /SP/appadmin/add_userinfo, HTTP/1.1, 200, 0.058821 +127.0.0.1, 2018-09-24 10:19:03, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.039560 +127.0.0.1, 2018-09-24 10:19:03, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.073216 +127.0.0.1, 2018-09-24 10:19:07, GET, /SP/appadmin/add_user, HTTP/1.1, 200, 0.049777 +127.0.0.1, 2018-09-24 10:19:09, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.042323 +127.0.0.1, 2018-09-24 10:19:09, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.109633 +127.0.0.1, 2018-09-24 10:19:31, GET, /SP/appadmin/change_user/Saturn, HTTP/1.1, 200, 0.052733 +127.0.0.1, 2018-09-24 10:19:33, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.038132 +127.0.0.1, 2018-09-24 10:19:33, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072570 +127.0.0.1, 2018-09-24 10:21:16, GET, /SP/appadmin/change_userinfo/Saturn, HTTP/1.1, 200, 0.059438 +127.0.0.1, 2018-09-24 10:21:21, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.043902 +127.0.0.1, 2018-09-24 10:21:21, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072788 +127.0.0.1, 2018-09-24 10:28:30, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.091522 +127.0.0.1, 2018-09-24 10:28:30, GET, /favicon.ico, HTTP/1.1, 400, 0.000302 +127.0.0.1, 2018-09-24 10:28:31, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.10-28-30.3fa30d1c-a386-4198-84b5-8c1ea0872793, HTTP/1.1, 200, 0.141749 +127.0.0.1, 2018-09-24 10:28:32, GET, /favicon.ico, HTTP/1.1, 400, 0.000327 +127.0.0.1, 2018-09-24 10:28:54, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.048239 +127.0.0.1, 2018-09-24 10:28:55, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.002457 +127.0.0.1, 2018-09-24 10:28:55, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.083071 +127.0.0.1, 2018-09-24 10:29:21, GET, /SP/appadmin/add_task, HTTP/1.1, 404, 0.025661 +127.0.0.1, 2018-09-24 10:29:22, GET, /favicon.ico, HTTP/1.1, 400, 0.000206 +127.0.0.1, 2018-09-24 10:29:24, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.043706 +127.0.0.1, 2018-09-24 10:29:26, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.066346 +127.0.0.1, 2018-09-24 10:30:31, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.051686 +127.0.0.1, 2018-09-24 10:31:22, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.051880 +127.0.0.1, 2018-09-24 10:31:22, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063330 +127.0.0.1, 2018-09-24 10:31:24, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.038139 +127.0.0.1, 2018-09-24 10:31:30, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.048631 +127.0.0.1, 2018-09-24 10:31:30, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.091171 +127.0.0.1, 2018-09-24 10:31:37, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.041999 +127.0.0.1, 2018-09-24 10:31:40, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.037986 +127.0.0.1, 2018-09-24 10:31:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.092075 +127.0.0.1, 2018-09-24 10:36:26, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.062077 +127.0.0.1, 2018-09-24 10:37:10, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.052279 +127.0.0.1, 2018-09-24 10:37:11, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000590 +127.0.0.1, 2018-09-24 10:39:25, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.036096 +127.0.0.1, 2018-09-24 10:39:25, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000701 +127.0.0.1, 2018-09-24 10:39:36, POST, /SP/appadmin/add_task, HTTP/1.1, 500, 0.192449 +127.0.0.1, 2018-09-24 10:39:37, GET, /favicon.ico, HTTP/1.1, 400, 0.000272 +127.0.0.1, 2018-09-24 10:39:38, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.10-39-36.c4c9a367-eb3e-4ad6-a8e1-6174d152c58b, HTTP/1.1, 200, 0.031339 +127.0.0.1, 2018-09-24 10:39:38, GET, /favicon.ico, HTTP/1.1, 400, 0.000197 +127.0.0.1, 2018-09-24 10:40:15, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.072271 +127.0.0.1, 2018-09-24 10:40:18, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.052561 +127.0.0.1, 2018-09-24 10:40:19, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.075018 +127.0.0.1, 2018-09-24 10:40:25, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.042317 +127.0.0.1, 2018-09-24 10:40:25, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.003460 +127.0.0.1, 2018-09-24 10:40:25, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.080342 +127.0.0.1, 2018-09-24 10:40:27, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.045840 +127.0.0.1, 2018-09-24 10:40:50, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.064399 +127.0.0.1, 2018-09-24 10:40:52, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.037273 +127.0.0.1, 2018-09-24 10:40:52, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063993 +127.0.0.1, 2018-09-24 10:42:10, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.038414 +127.0.0.1, 2018-09-24 10:42:10, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001044 +127.0.0.1, 2018-09-24 10:42:10, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067595 +127.0.0.1, 2018-09-24 10:42:37, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.072805 +127.0.0.1, 2018-09-24 10:42:37, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000870 +127.0.0.1, 2018-09-24 10:42:37, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.065444 +127.0.0.1, 2018-09-24 10:43:39, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.042559 +127.0.0.1, 2018-09-24 10:43:39, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001112 +127.0.0.1, 2018-09-24 10:43:39, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.087013 +127.0.0.1, 2018-09-24 10:44:06, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.055474 +127.0.0.1, 2018-09-24 10:44:06, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000583 +127.0.0.1, 2018-09-24 10:44:06, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.118830 +127.0.0.1, 2018-09-24 10:44:24, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.071962 +127.0.0.1, 2018-09-24 10:44:24, GET, /favicon.ico, HTTP/1.1, 400, 0.000328 +127.0.0.1, 2018-09-24 10:48:33, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.050758 +127.0.0.1, 2018-09-24 10:48:35, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.070665 +127.0.0.1, 2018-09-24 10:48:35, GET, /favicon.ico, HTTP/1.1, 400, 0.000313 +127.0.0.1, 2018-09-24 10:48:37, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.10-48-35.fde81767-cf3d-48f8-9b83-0fa821b65225, HTTP/1.1, 200, 0.111049 +127.0.0.1, 2018-09-24 10:48:37, GET, /favicon.ico, HTTP/1.1, 400, 0.000234 +127.0.0.1, 2018-09-24 10:49:32, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.10-48-35.fde81767-cf3d-48f8-9b83-0fa821b65225, HTTP/1.1, 200, 0.108545 +127.0.0.1, 2018-09-24 10:49:32, GET, /favicon.ico, HTTP/1.1, 400, 0.000212 +127.0.0.1, 2018-09-24 10:49:34, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.083896 +127.0.0.1, 2018-09-24 10:49:34, GET, /favicon.ico, HTTP/1.1, 400, 0.000226 +127.0.0.1, 2018-09-24 10:50:40, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.10-48-35.fde81767-cf3d-48f8-9b83-0fa821b65225, HTTP/1.1, 200, 0.130284 +127.0.0.1, 2018-09-24 10:50:40, GET, /favicon.ico, HTTP/1.1, 400, 0.000346 +127.0.0.1, 2018-09-24 10:50:42, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.053166 +127.0.0.1, 2018-09-24 10:50:42, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000881 +127.0.0.1, 2018-09-24 10:50:42, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.071887 +127.0.0.1, 2018-09-24 10:51:18, GET, /SP/appadmin/change_task/1, HTTP/1.1, 404, 0.024984 +127.0.0.1, 2018-09-24 10:51:19, GET, /favicon.ico, HTTP/1.1, 400, 0.000225 +127.0.0.1, 2018-09-24 10:51:20, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.040513 +127.0.0.1, 2018-09-24 10:51:20, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060559 +127.0.0.1, 2018-09-24 10:51:50, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.090600 +127.0.0.1, 2018-09-24 10:51:50, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.004160 +127.0.0.1, 2018-09-24 10:51:51, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.122937 +127.0.0.1, 2018-09-24 10:51:52, GET, /SP/appadmin/change_task/1, HTTP/1.1, 500, 0.067315 +127.0.0.1, 2018-09-24 10:51:52, GET, /favicon.ico, HTTP/1.1, 400, 0.000198 +127.0.0.1, 2018-09-24 10:51:54, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.10-51-52.823fdac2-9f46-4212-beda-f01da85617ee, HTTP/1.1, 200, 0.036392 +127.0.0.1, 2018-09-24 10:51:54, GET, /favicon.ico, HTTP/1.1, 400, 0.000715 +127.0.0.1, 2018-09-24 10:54:12, GET, /SP/appadmin/change_task/1, HTTP/1.1, 200, 0.127593 +127.0.0.1, 2018-09-24 10:56:00, GET, /SP/appadmin/change_task/1, HTTP/1.1, 500, 0.073331 +127.0.0.1, 2018-09-24 10:56:01, GET, /favicon.ico, HTTP/1.1, 400, 0.000270 +127.0.0.1, 2018-09-24 10:56:11, GET, /SP/appadmin/change_task/1, HTTP/1.1, 200, 0.052351 +127.0.0.1, 2018-09-24 10:56:12, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000976 +127.0.0.1, 2018-09-24 10:56:28, POST, /SP/appadmin/change_task/1, HTTP/1.1, 200, 0.088030 +127.0.0.1, 2018-09-24 10:56:32, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.050346 +127.0.0.1, 2018-09-24 10:56:32, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.100532 +127.0.0.1, 2018-09-24 10:56:36, GET, /SP/appadmin/change_task/1, HTTP/1.1, 200, 0.047223 +127.0.0.1, 2018-09-24 11:02:33, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.069576 +127.0.0.1, 2018-09-24 11:02:33, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.000907 +127.0.0.1, 2018-09-24 11:02:33, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.000555 +127.0.0.1, 2018-09-24 11:02:33, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.000695 +127.0.0.1, 2018-09-24 11:02:33, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.000953 +127.0.0.1, 2018-09-24 11:02:33, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.000494 +127.0.0.1, 2018-09-24 11:02:33, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.000481 +127.0.0.1, 2018-09-24 11:02:33, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.000535 +127.0.0.1, 2018-09-24 11:02:33, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.001713 +127.0.0.1, 2018-09-24 11:02:33, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.000827 +127.0.0.1, 2018-09-24 11:02:34, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.114884 +127.0.0.1, 2018-09-24 11:02:39, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.049317 +127.0.0.1, 2018-09-24 11:02:56, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.058394 +127.0.0.1, 2018-09-24 11:02:58, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.045229 +127.0.0.1, 2018-09-24 11:02:58, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.097113 +127.0.0.1, 2018-09-24 11:03:03, GET, /SP/appadmin/change_task/3, HTTP/1.1, 200, 0.058435 +127.0.0.1, 2018-09-24 11:03:05, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.044214 +127.0.0.1, 2018-09-24 11:03:05, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.093361 +127.0.0.1, 2018-09-24 11:03:24, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.054385 +127.0.0.1, 2018-09-24 11:03:36, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.053343 +127.0.0.1, 2018-09-24 11:03:38, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.049038 +127.0.0.1, 2018-09-24 11:03:38, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.098084 +127.0.0.1, 2018-09-24 11:04:04, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.116934 +127.0.0.1, 2018-09-24 11:04:16, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.052292 +127.0.0.1, 2018-09-24 11:04:43, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.071542 +127.0.0.1, 2018-09-24 11:08:14, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.077646 +127.0.0.1, 2018-09-24 11:08:16, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.051449 +127.0.0.1, 2018-09-24 11:08:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.079367 +127.0.0.1, 2018-09-24 11:08:52, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.083527 +127.0.0.1, 2018-09-24 11:09:06, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.049032 +127.0.0.1, 2018-09-24 11:11:59, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.072333 +127.0.0.1, 2018-09-24 11:12:03, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.051394 +127.0.0.1, 2018-09-24 11:12:03, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.066258 +127.0.0.1, 2018-09-24 11:12:43, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.064615 +127.0.0.1, 2018-09-24 11:12:54, POST, /SP/appadmin/add_task, HTTP/1.1, 500, 0.081241 +127.0.0.1, 2018-09-24 11:12:54, GET, /favicon.ico, HTTP/1.1, 400, 0.000229 +127.0.0.1, 2018-09-24 11:12:56, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.11-12-54.90b0fa07-b98f-448d-a5b9-4f162df1c934, HTTP/1.1, 200, 0.036191 +127.0.0.1, 2018-09-24 11:12:56, GET, /favicon.ico, HTTP/1.1, 400, 0.000274 +127.0.0.1, 2018-09-24 11:13:06, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.055275 +127.0.0.1, 2018-09-24 11:14:27, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.079820 +127.0.0.1, 2018-09-24 11:14:27, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000598 +127.0.0.1, 2018-09-24 11:14:30, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.042350 +127.0.0.1, 2018-09-24 11:14:40, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.061424 +127.0.0.1, 2018-09-24 11:14:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.128499 +127.0.0.1, 2018-09-24 11:14:42, GET, /SP/appadmin/add_user, HTTP/1.1, 200, 0.060698 +127.0.0.1, 2018-09-24 11:14:44, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.048339 +127.0.0.1, 2018-09-24 11:14:44, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.064093 +127.0.0.1, 2018-09-24 11:15:02, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.105501 +127.0.0.1, 2018-09-24 11:15:02, GET, /favicon.ico, HTTP/1.1, 400, 0.000336 +127.0.0.1, 2018-09-24 11:15:03, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.11-15-02.7fe4a98f-554e-40ec-95d8-0a89969062a6, HTTP/1.1, 200, 0.052129 +127.0.0.1, 2018-09-24 11:15:03, GET, /favicon.ico, HTTP/1.1, 400, 0.000219 +127.0.0.1, 2018-09-24 11:15:22, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.094936 +127.0.0.1, 2018-09-24 11:15:23, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.004886 +127.0.0.1, 2018-09-24 11:15:23, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.121483 +127.0.0.1, 2018-09-24 11:15:26, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.051462 +127.0.0.1, 2018-09-24 11:15:30, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.040918 +127.0.0.1, 2018-09-24 11:15:30, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.087010 +127.0.0.1, 2018-09-24 11:15:45, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.085549 +127.0.0.1, 2018-09-24 11:15:46, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000562 +127.0.0.1, 2018-09-24 11:15:46, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.109772 +127.0.0.1, 2018-09-24 11:15:48, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.055013 +127.0.0.1, 2018-09-24 11:15:52, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.046253 +127.0.0.1, 2018-09-24 11:15:53, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.087251 +127.0.0.1, 2018-09-24 11:18:51, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.072935 +127.0.0.1, 2018-09-24 11:18:51, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000967 +127.0.0.1, 2018-09-24 11:18:51, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.082780 +127.0.0.1, 2018-09-24 11:18:53, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.049267 +127.0.0.1, 2018-09-24 11:18:57, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.039357 +127.0.0.1, 2018-09-24 11:18:57, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.094484 +127.0.0.1, 2018-09-24 11:19:00, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.046526 +127.0.0.1, 2018-09-24 11:19:01, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.003405 +127.0.0.1, 2018-09-24 11:19:01, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.094478 +127.0.0.1, 2018-09-24 11:19:04, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.043726 +127.0.0.1, 2018-09-24 11:19:06, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.048163 +127.0.0.1, 2018-09-24 11:19:07, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.093833 +127.0.0.1, 2018-09-24 11:19:16, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.041227 +127.0.0.1, 2018-09-24 11:19:17, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000889 +127.0.0.1, 2018-09-24 11:19:17, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.076781 +127.0.0.1, 2018-09-24 11:19:19, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.045317 +127.0.0.1, 2018-09-24 11:19:22, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.043130 +127.0.0.1, 2018-09-24 11:19:22, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.107827 +127.0.0.1, 2018-09-24 11:19:28, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.101426 +127.0.0.1, 2018-09-24 11:19:28, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000981 +127.0.0.1, 2018-09-24 11:19:28, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.092936 +127.0.0.1, 2018-09-24 11:19:33, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.049732 +127.0.0.1, 2018-09-24 11:19:46, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.042318 +127.0.0.1, 2018-09-24 11:19:46, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070559 +127.0.0.1, 2018-09-24 11:19:48, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.045302 +127.0.0.1, 2018-09-24 11:19:51, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.044997 +127.0.0.1, 2018-09-24 11:19:51, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.093353 +127.0.0.1, 2018-09-24 11:19:52, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.038419 +127.0.0.1, 2018-09-24 11:19:54, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.046207 +127.0.0.1, 2018-09-24 11:19:54, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.084989 +127.0.0.1, 2018-09-24 11:19:55, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.041517 +127.0.0.1, 2018-09-24 11:19:57, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.039115 +127.0.0.1, 2018-09-24 11:19:57, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.091294 +127.0.0.1, 2018-09-24 11:19:58, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.044428 +127.0.0.1, 2018-09-24 11:20:25, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.043532 +127.0.0.1, 2018-09-24 11:20:25, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000839 +127.0.0.1, 2018-09-24 11:20:56, POST, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.067806 +127.0.0.1, 2018-09-24 11:21:04, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.068182 +127.0.0.1, 2018-09-24 11:21:07, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.039341 +127.0.0.1, 2018-09-24 11:21:07, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.037041 +127.0.0.1, 2018-09-24 11:21:08, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.076847 +127.0.0.1, 2018-09-24 11:21:11, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.042399 +127.0.0.1, 2018-09-24 11:21:19, POST, /SP/appadmin/add_task, HTTP/1.1, 500, 0.087141 +127.0.0.1, 2018-09-24 11:21:19, GET, /favicon.ico, HTTP/1.1, 400, 0.000220 +127.0.0.1, 2018-09-24 11:21:21, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.11-21-19.f45f242f-db32-41fd-a6d2-49fbbc3db4bb, HTTP/1.1, 200, 0.034166 +127.0.0.1, 2018-09-24 11:21:21, GET, /favicon.ico, HTTP/1.1, 400, 0.000342 +127.0.0.1, 2018-09-24 11:21:29, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.045561 +127.0.0.1, 2018-09-24 11:22:33, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.059846 +127.0.0.1, 2018-09-24 11:22:33, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000734 +127.0.0.1, 2018-09-24 11:22:43, POST, /SP/appadmin/add_task, HTTP/1.1, 500, 0.073064 +127.0.0.1, 2018-09-24 11:22:43, GET, /favicon.ico, HTTP/1.1, 400, 0.000239 +127.0.0.1, 2018-09-24 11:22:44, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.11-22-43.f236fc4a-5ffc-4951-8b09-fc87b13aa493, HTTP/1.1, 200, 0.038437 +127.0.0.1, 2018-09-24 11:22:45, GET, /favicon.ico, HTTP/1.1, 400, 0.000223 +127.0.0.1, 2018-09-24 11:23:33, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.060094 +127.0.0.1, 2018-09-24 11:23:33, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.093280 +127.0.0.1, 2018-09-24 11:23:33, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000749 +127.0.0.1, 2018-09-24 11:23:39, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.050121 +127.0.0.1, 2018-09-24 11:25:59, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.059260 +127.0.0.1, 2018-09-24 11:27:05, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.062370 +127.0.0.1, 2018-09-24 11:27:09, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.047139 +127.0.0.1, 2018-09-24 11:27:09, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.087895 +127.0.0.1, 2018-09-24 11:27:14, GET, /SP/appadmin/change_task/13, HTTP/1.1, 200, 0.058526 +127.0.0.1, 2018-09-24 11:29:14, GET, /SP/appadmin/change_task/13, HTTP/1.1, 200, 0.075056 +127.0.0.1, 2018-09-24 11:29:57, GET, /SP/appadmin/change_task/13, HTTP/1.1, 200, 0.070477 +127.0.0.1, 2018-09-24 11:29:57, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000590 +127.0.0.1, 2018-09-24 11:30:18, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.046667 +127.0.0.1, 2018-09-24 11:30:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.082006 +127.0.0.1, 2018-09-24 11:30:22, GET, /SP/appadmin/change_task/13, HTTP/1.1, 200, 0.044394 +127.0.0.1, 2018-09-24 11:30:37, POST, /SP/appadmin/change_task/13, HTTP/1.1, 200, 0.095084 +127.0.0.1, 2018-09-24 11:31:47, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.074763 +127.0.0.1, 2018-09-24 11:31:48, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.074719 +127.0.0.1, 2018-09-24 11:31:50, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.048565 +127.0.0.1, 2018-09-24 11:32:02, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.054271 +127.0.0.1, 2018-09-24 11:32:04, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.041237 +127.0.0.1, 2018-09-24 11:32:05, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.082526 +127.0.0.1, 2018-09-24 11:32:10, GET, /SP/appadmin/change_task/14, HTTP/1.1, 200, 0.057663 +127.0.0.1, 2018-09-24 11:32:12, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.040095 +127.0.0.1, 2018-09-24 11:32:13, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.082941 +127.0.0.1, 2018-09-24 11:35:22, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.067669 +127.0.0.1, 2018-09-24 11:35:23, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.002468 +127.0.0.1, 2018-09-24 11:35:23, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070404 +127.0.0.1, 2018-09-24 11:35:25, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.048422 +127.0.0.1, 2018-09-24 11:37:46, POST, /SP/appadmin/add_task, HTTP/1.1, 500, 0.121148 +127.0.0.1, 2018-09-24 11:37:46, GET, /favicon.ico, HTTP/1.1, 400, 0.000204 +127.0.0.1, 2018-09-24 11:37:48, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.11-37-46.8ff165c3-169b-4fe0-8943-33268bac342e, HTTP/1.1, 200, 0.038502 +127.0.0.1, 2018-09-24 11:37:48, GET, /favicon.ico, HTTP/1.1, 400, 0.000299 +127.0.0.1, 2018-09-24 11:38:20, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.046120 +127.0.0.1, 2018-09-24 11:38:27, POST, /SP/appadmin/add_task, HTTP/1.1, 500, 0.064088 +127.0.0.1, 2018-09-24 11:38:27, GET, /favicon.ico, HTTP/1.1, 400, 0.000397 +127.0.0.1, 2018-09-24 11:38:29, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.11-38-27.9e9533f3-2040-4380-896a-f07d12be3ad1, HTTP/1.1, 200, 0.032343 +127.0.0.1, 2018-09-24 11:38:29, GET, /favicon.ico, HTTP/1.1, 400, 0.000282 +127.0.0.1, 2018-09-24 11:39:41, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.066723 +127.0.0.1, 2018-09-24 11:39:48, POST, /SP/appadmin/add_task, HTTP/1.1, 500, 0.148724 +127.0.0.1, 2018-09-24 11:39:48, GET, /favicon.ico, HTTP/1.1, 400, 0.000245 +127.0.0.1, 2018-09-24 11:39:50, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.11-39-48.cb629b5b-b6e0-4981-865e-08e1ce2d7144, HTTP/1.1, 200, 0.032373 +127.0.0.1, 2018-09-24 11:39:50, GET, /favicon.ico, HTTP/1.1, 400, 0.000209 +127.0.0.1, 2018-09-24 11:42:31, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.073720 +127.0.0.1, 2018-09-24 11:42:31, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000549 +127.0.0.1, 2018-09-24 11:42:36, GET, /SP/appadmin/state, HTTP/1.1, 200, 0.074682 +127.0.0.1, 2018-09-24 11:42:38, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.050526 +127.0.0.1, 2018-09-24 11:42:38, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.122189 +127.0.0.1, 2018-09-24 11:42:38, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.054107 +127.0.0.1, 2018-09-24 11:42:39, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.118508 +127.0.0.1, 2018-09-24 11:42:42, GET, /SP/appadmin/change_task/15, HTTP/1.1, 200, 0.055502 +127.0.0.1, 2018-09-24 11:43:08, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.050395 +127.0.0.1, 2018-09-24 11:43:09, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072966 +127.0.0.1, 2018-09-24 11:43:11, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.060106 +127.0.0.1, 2018-09-24 11:43:23, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.052847 +127.0.0.1, 2018-09-24 11:43:26, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.091788 +127.0.0.1, 2018-09-24 11:43:26, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.088826 +127.0.0.1, 2018-09-24 11:43:28, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.069416 +127.0.0.1, 2018-09-24 11:43:39, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.043236 +127.0.0.1, 2018-09-24 11:43:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.120402 +127.0.0.1, 2018-09-24 11:43:43, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.045124 +127.0.0.1, 2018-09-24 11:48:25, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.077413 +127.0.0.1, 2018-09-24 11:48:26, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000772 +127.0.0.1, 2018-09-24 11:49:01, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.050233 +127.0.0.1, 2018-09-24 11:49:01, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000501 +127.0.0.1, 2018-09-24 11:49:31, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.058437 +127.0.0.1, 2018-09-24 11:49:31, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000443 +127.0.0.1, 2018-09-24 11:50:29, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.102845 +127.0.0.1, 2018-09-24 11:50:29, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000780 +127.0.0.1, 2018-09-24 11:50:31, GET, /SP/appadmin/change_user/None/None, HTTP/1.1, 200, 0.052905 +127.0.0.1, 2018-09-24 11:50:36, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.048518 +127.0.0.1, 2018-09-24 11:51:16, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.038699 +127.0.0.1, 2018-09-24 11:51:16, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000823 +127.0.0.1, 2018-09-24 11:51:28, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.048239 +127.0.0.1, 2018-09-24 11:51:29, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000494 +127.0.0.1, 2018-09-24 11:51:50, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.046034 +127.0.0.1, 2018-09-24 11:51:51, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000671 +127.0.0.1, 2018-09-24 11:52:03, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.067321 +127.0.0.1, 2018-09-24 11:52:03, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000615 +127.0.0.1, 2018-09-24 11:52:46, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.043368 +127.0.0.1, 2018-09-24 11:52:47, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000449 +127.0.0.1, 2018-09-24 11:54:24, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.056987 +127.0.0.1, 2018-09-24 11:54:24, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000897 +127.0.0.1, 2018-09-24 11:54:32, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.048507 +127.0.0.1, 2018-09-24 11:54:32, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000503 +127.0.0.1, 2018-09-24 11:54:46, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.045134 +127.0.0.1, 2018-09-24 11:54:46, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000672 +127.0.0.1, 2018-09-24 11:55:46, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.064464 +127.0.0.1, 2018-09-24 11:55:47, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000583 +127.0.0.1, 2018-09-24 11:56:03, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.050400 +127.0.0.1, 2018-09-24 11:56:04, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000592 +127.0.0.1, 2018-09-24 11:56:40, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.074458 +127.0.0.1, 2018-09-24 11:56:40, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000689 +127.0.0.1, 2018-09-24 11:56:42, GET, /SP/appadmin/change_user/None, HTTP/1.1, 200, 0.047939 +127.0.0.1, 2018-09-24 11:57:01, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.071186 +127.0.0.1, 2018-09-24 11:57:02, GET, /SP/appadmin/delete_task/None, HTTP/1.1, 500, 0.053244 +127.0.0.1, 2018-09-24 11:57:02, GET, /favicon.ico, HTTP/1.1, 400, 0.000339 +127.0.0.1, 2018-09-24 11:57:03, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.11-57-02.84349f26-13d3-414a-abed-4f41b121c461, HTTP/1.1, 200, 0.035418 +127.0.0.1, 2018-09-24 11:57:04, GET, /favicon.ico, HTTP/1.1, 400, 0.000204 +127.0.0.1, 2018-09-24 11:58:39, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.066488 +127.0.0.1, 2018-09-24 11:58:40, GET, /SP/appadmin/delete_task/None, HTTP/1.1, 500, 0.037694 +127.0.0.1, 2018-09-24 11:58:40, GET, /favicon.ico, HTTP/1.1, 400, 0.000297 +127.0.0.1, 2018-09-24 11:58:45, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.11-58-40.02fe98af-d9a8-45f8-8043-639a1cd6f2fa, HTTP/1.1, 200, 0.040950 +127.0.0.1, 2018-09-24 11:58:45, GET, /favicon.ico, HTTP/1.1, 400, 0.000360 +127.0.0.1, 2018-09-24 12:00:27, GET, /SP/appadmin/delete_task/None, HTTP/1.1, 500, 0.041496 +127.0.0.1, 2018-09-24 12:00:27, GET, /favicon.ico, HTTP/1.1, 400, 0.000316 +127.0.0.1, 2018-09-24 12:00:29, GET, /SP/appadmin/change_task/16, HTTP/1.1, 200, 0.049290 +127.0.0.1, 2018-09-24 12:00:29, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.083483 +127.0.0.1, 2018-09-24 12:00:30, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.075438 +127.0.0.1, 2018-09-24 12:01:03, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.153343 +127.0.0.1, 2018-09-24 12:01:04, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001412 +127.0.0.1, 2018-09-24 12:01:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.116409 +127.0.0.1, 2018-09-24 12:01:09, GET, /SP/appadmin/delete_task/1, HTTP/1.1, 200, 0.022364 +127.0.0.1, 2018-09-24 12:01:09, GET, /favicon.ico, HTTP/1.1, 400, 0.000199 +127.0.0.1, 2018-09-24 12:01:13, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.040396 +127.0.0.1, 2018-09-24 12:01:13, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067619 +127.0.0.1, 2018-09-24 12:01:19, GET, /SP/appadmin/delete_task/1, HTTP/1.1, 200, 0.021719 +127.0.0.1, 2018-09-24 12:01:19, GET, /favicon.ico, HTTP/1.1, 400, 0.000290 +127.0.0.1, 2018-09-24 12:01:21, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.049401 +127.0.0.1, 2018-09-24 12:01:21, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.080104 +127.0.0.1, 2018-09-24 12:01:22, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.042271 +127.0.0.1, 2018-09-24 12:01:22, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.076113 +127.0.0.1, 2018-09-24 12:01:44, GET, /SP/appadmin/delete_task/1, HTTP/1.1, 500, 0.061356 +127.0.0.1, 2018-09-24 12:01:44, GET, /favicon.ico, HTTP/1.1, 400, 0.000604 +127.0.0.1, 2018-09-24 12:01:46, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.12-01-44.9e59b647-658d-4421-ae22-a190c64bfe1b, HTTP/1.1, 200, 0.038100 +127.0.0.1, 2018-09-24 12:01:46, GET, /favicon.ico, HTTP/1.1, 400, 0.000306 +127.0.0.1, 2018-09-24 12:02:34, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.055704 +127.0.0.1, 2018-09-24 12:02:35, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.095323 +127.0.0.1, 2018-09-24 12:02:35, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.085787 +127.0.0.1, 2018-09-24 12:02:37, GET, /SP/appadmin/delete_task/1, HTTP/1.1, 500, 0.059446 +127.0.0.1, 2018-09-24 12:02:37, GET, /favicon.ico, HTTP/1.1, 400, 0.000338 +127.0.0.1, 2018-09-24 12:02:39, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.12-02-37.c1142121-3382-4594-83bc-a3b9308934fc, HTTP/1.1, 200, 0.031988 +127.0.0.1, 2018-09-24 12:02:39, GET, /favicon.ico, HTTP/1.1, 400, 0.000256 +127.0.0.1, 2018-09-24 12:03:04, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.057585 +127.0.0.1, 2018-09-24 12:03:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072387 +127.0.0.1, 2018-09-24 12:03:07, GET, /SP/appadmin/delete_task/1, HTTP/1.1, 200, 0.045975 +127.0.0.1, 2018-09-24 12:03:42, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.055206 +127.0.0.1, 2018-09-24 12:03:42, GET, /favicon.ico, HTTP/1.1, 400, 0.000235 +127.0.0.1, 2018-09-24 12:03:43, GET, /SP/appadmin/add_task, HTTP/1.1, 500, 0.051838 +127.0.0.1, 2018-09-24 12:03:43, GET, /favicon.ico, HTTP/1.1, 400, 0.000200 +127.0.0.1, 2018-09-24 12:03:44, GET, /favicon.ico, HTTP/1.1, 400, 0.000217 +127.0.0.1, 2018-09-24 12:03:45, GET, /favicon.ico, HTTP/1.1, 400, 0.000410 +127.0.0.1, 2018-09-24 12:03:45, GET, /SP/appadmin/state, HTTP/1.1, 500, 0.064503 +127.0.0.1, 2018-09-24 12:03:45, GET, /favicon.ico, HTTP/1.1, 400, 0.000202 +127.0.0.1, 2018-09-24 12:03:47, GET, /favicon.ico, HTTP/1.1, 400, 0.000378 +127.0.0.1, 2018-09-24 12:03:50, GET, /SP/appadmin/state, HTTP/1.1, 500, 0.049087 +127.0.0.1, 2018-09-24 12:03:50, GET, /favicon.ico, HTTP/1.1, 400, 0.000200 +127.0.0.1, 2018-09-24 12:03:59, GET, /SP/appadmin/state, HTTP/1.1, 200, 0.173130 +127.0.0.1, 2018-09-24 12:04:00, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001381 +127.0.0.1, 2018-09-24 12:04:04, GET, /SP/appadmin, HTTP/1.1, 200, 0.060459 +127.0.0.1, 2018-09-24 12:04:05, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.124307 +127.0.0.1, 2018-09-24 12:04:09, GET, /SP/appadmin/delete_task/2, HTTP/1.1, 200, 0.061211 +127.0.0.1, 2018-09-24 12:04:14, GET, /SP/appadmin, HTTP/1.1, 200, 0.042113 +127.0.0.1, 2018-09-24 12:04:14, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.075290 +127.0.0.1, 2018-09-24 12:07:28, GET, /SP/appadmin/delete_task/10, HTTP/1.1, 200, 0.066660 +127.0.0.1, 2018-09-24 12:07:31, GET, /SP/appadmin, HTTP/1.1, 200, 0.062533 +127.0.0.1, 2018-09-24 12:07:31, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067173 +127.0.0.1, 2018-09-24 12:09:01, GET, /SP/appadmin/delete_task/11, HTTP/1.1, 200, 0.049816 +127.0.0.1, 2018-09-24 12:09:01, GET, /favicon.ico, HTTP/1.1, 400, 0.000223 +127.0.0.1, 2018-09-24 12:09:02, GET, /SP/appadmin, HTTP/1.1, 200, 0.052821 +127.0.0.1, 2018-09-24 12:09:03, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.089373 +127.0.0.1, 2018-09-24 12:11:02, GET, /SP/appadmin, HTTP/1.1, 200, 0.064923 +127.0.0.1, 2018-09-24 12:11:03, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.003604 +127.0.0.1, 2018-09-24 12:11:03, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.105171 +127.0.0.1, 2018-09-24 12:11:05, GET, /SP/appadmin/delete_task/12, HTTP/1.1, 500, 0.057995 +127.0.0.1, 2018-09-24 12:11:05, GET, /favicon.ico, HTTP/1.1, 400, 0.000250 +127.0.0.1, 2018-09-24 12:11:07, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.12-11-05.73b365fe-f13f-4c3f-b11d-e53a45441ddb, HTTP/1.1, 200, 0.137372 +127.0.0.1, 2018-09-24 12:11:07, GET, /favicon.ico, HTTP/1.1, 400, 0.000278 +127.0.0.1, 2018-09-24 12:11:45, GET, /SP/appadmin, HTTP/1.1, 200, 0.075398 +127.0.0.1, 2018-09-24 12:11:46, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.089068 +127.0.0.1, 2018-09-24 12:11:48, GET, /SP/appadmin/delete_task/12, HTTP/1.1, 500, 0.130771 +127.0.0.1, 2018-09-24 12:11:48, GET, /favicon.ico, HTTP/1.1, 400, 0.000240 +127.0.0.1, 2018-09-24 12:11:50, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.12-11-48.01e44a61-c972-484b-b3aa-f74d6e69e3f4, HTTP/1.1, 200, 0.123907 +127.0.0.1, 2018-09-24 12:11:51, GET, /favicon.ico, HTTP/1.1, 400, 0.000214 +127.0.0.1, 2018-09-24 12:16:50, GET, /SP/appadmin/delete_task/12, HTTP/1.1, 500, 0.081405 +127.0.0.1, 2018-09-24 12:16:50, GET, /favicon.ico, HTTP/1.1, 400, 0.000216 +127.0.0.1, 2018-09-24 12:16:54, GET, /SP/appadmin, HTTP/1.1, 200, 0.057919 +127.0.0.1, 2018-09-24 12:16:55, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.080795 +127.0.0.1, 2018-09-24 12:16:57, GET, /SP/appadmin/delete_task/12, HTTP/1.1, 500, 0.049846 +127.0.0.1, 2018-09-24 12:16:57, GET, /favicon.ico, HTTP/1.1, 400, 0.000201 +127.0.0.1, 2018-09-24 12:16:58, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.12-16-57.436c807c-5074-4991-9b08-f749854a201a, HTTP/1.1, 200, 0.036824 +127.0.0.1, 2018-09-24 12:16:59, GET, /favicon.ico, HTTP/1.1, 400, 0.000224 +127.0.0.1, 2018-09-24 12:17:28, GET, /SP/appadmin, HTTP/1.1, 200, 0.054958 +127.0.0.1, 2018-09-24 12:17:28, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063620 +127.0.0.1, 2018-09-24 12:17:33, GET, /SP/appadmin/delete_task/12, HTTP/1.1, 303, 0.032364 +127.0.0.1, 2018-09-24 12:17:38, GET, /SP/appadmin, HTTP/1.1, 200, 0.047063 +127.0.0.1, 2018-09-24 12:17:38, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.105542 +127.0.0.1, 2018-09-24 12:17:48, GET, /SP/static/js/bootstrap.bundle.min.js.map, HTTP/1.1, 304, 0.000702 +127.0.0.1, 2018-09-24 12:17:48, GET, /SP/static/css/bootstrap.min.css.map, HTTP/1.1, 304, 0.000373 +127.0.0.1, 2018-09-24 12:18:00, GET, /SP/appadmin/delete_task/13, HTTP/1.1, 303, 0.055784 +127.0.0.1, 2018-09-24 12:18:16, GET, /SP/appadmin, HTTP/1.1, 200, 0.058158 +127.0.0.1, 2018-09-24 12:18:17, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.092803 +127.0.0.1, 2018-09-24 12:18:32, GET, /SP/appadmin/delete_task/14, HTTP/1.1, 303, 0.030641 +127.0.0.1, 2018-09-24 12:18:32, GET, /SP/appadmin/, HTTP/1.1, 200, 0.045991 +127.0.0.1, 2018-09-24 12:18:32, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.093480 +127.0.0.1, 2018-09-24 12:18:37, GET, /SP/appadmin/, HTTP/1.1, 200, 0.048486 +127.0.0.1, 2018-09-24 12:18:38, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.060268 +127.0.0.1, 2018-09-24 12:18:43, GET, /SP/appadmin, HTTP/1.1, 200, 0.038851 +127.0.0.1, 2018-09-24 12:18:43, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.080333 +127.0.0.1, 2018-09-24 12:18:55, GET, /SP/appadmin/change_user/Saturn, HTTP/1.1, 200, 0.055548 +127.0.0.1, 2018-09-24 12:18:57, GET, /SP/appadmin, HTTP/1.1, 200, 0.040772 +127.0.0.1, 2018-09-24 12:18:57, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.073463 +127.0.0.1, 2018-09-24 12:19:04, GET, /SP/appadmin, HTTP/1.1, 200, 0.149277 +127.0.0.1, 2018-09-24 12:19:05, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061081 +127.0.0.1, 2018-09-24 13:23:51, GET, /SP/appadmin/change_task/15, HTTP/1.1, 303, 0.057437 +127.0.0.1, 2018-09-24 13:23:51, GET, /admin/default/index, HTTP/1.1, 200, 0.052472 +127.0.0.1, 2018-09-24 13:23:52, GET, /favicon.ico, HTTP/1.1, 400, 0.000224 +127.0.0.1, 2018-09-24 13:23:55, POST, /admin/default/index, HTTP/1.1, 303, 0.014581 +127.0.0.1, 2018-09-24 13:23:55, GET, /SP/appadmin/change_task/15, HTTP/1.1, 500, 0.033623 +127.0.0.1, 2018-09-24 13:23:55, GET, /favicon.ico, HTTP/1.1, 400, 0.000236 +127.0.0.1, 2018-09-24 13:23:57, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.13-23-55.ef12ccd5-6a87-4915-a2e6-6311dff79d62, HTTP/1.1, 200, 0.114450 +127.0.0.1, 2018-09-24 13:23:58, GET, /favicon.ico, HTTP/1.1, 400, 0.000226 +127.0.0.1, 2018-09-24 13:24:12, GET, /SP/appadmin/, HTTP/1.1, 500, 0.126095 +127.0.0.1, 2018-09-24 13:24:12, GET, /favicon.ico, HTTP/1.1, 400, 0.000327 +127.0.0.1, 2018-09-24 13:25:52, GET, /SP/appadmin/, HTTP/1.1, 200, 0.056978 +127.0.0.1, 2018-09-24 13:25:53, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000570 +127.0.0.1, 2018-09-24 13:25:53, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.089786 +127.0.0.1, 2018-09-24 13:29:05, GET, /SP/appadmin/, HTTP/1.1, 200, 0.052779 +127.0.0.1, 2018-09-24 13:29:06, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001978 +127.0.0.1, 2018-09-24 13:29:06, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070816 +127.0.0.1, 2018-09-24 13:35:54, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.096048 +127.0.0.1, 2018-09-24 13:35:54, GET, /favicon.ico, HTTP/1.1, 400, 0.000247 +127.0.0.1, 2018-09-24 13:36:04, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.051860 +127.0.0.1, 2018-09-24 13:36:05, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001629 +127.0.0.1, 2018-09-24 13:36:05, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.109467 +127.0.0.1, 2018-09-24 13:36:09, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.053814 +127.0.0.1, 2018-09-24 13:36:12, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.043687 +127.0.0.1, 2018-09-24 13:36:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.077850 +127.0.0.1, 2018-09-24 13:36:14, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.044187 +127.0.0.1, 2018-09-24 13:36:24, GET, /SP/appadmin/update/db/auth_user/1, HTTP/1.1, 200, 0.051382 +127.0.0.1, 2018-09-24 13:36:43, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.052990 +127.0.0.1, 2018-09-24 13:36:46, GET, /SP/appadmin/update/db/auth_membership/4, HTTP/1.1, 200, 0.041505 +127.0.0.1, 2018-09-24 13:36:56, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.041216 +127.0.0.1, 2018-09-24 13:37:01, GET, /SP/appadmin/update/db/auth_group/4, HTTP/1.1, 200, 0.041184 +127.0.0.1, 2018-09-24 13:37:06, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.046347 +127.0.0.1, 2018-09-24 13:37:15, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.052009 +127.0.0.1, 2018-09-24 13:37:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.058473 +127.0.0.1, 2018-09-24 13:37:44, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.051531 +127.0.0.1, 2018-09-24 13:37:45, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001630 +127.0.0.1, 2018-09-24 13:37:45, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.116333 +127.0.0.1, 2018-09-24 13:38:15, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.056257 +127.0.0.1, 2018-09-24 13:38:15, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.002608 +127.0.0.1, 2018-09-24 13:38:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.115097 +127.0.0.1, 2018-09-24 13:38:49, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.052657 +127.0.0.1, 2018-09-24 13:39:13, GET, /SP/appadmin/insert/db/auth_membership, HTTP/1.1, 200, 0.064531 +127.0.0.1, 2018-09-24 13:39:42, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.047460 +127.0.0.1, 2018-09-24 13:39:45, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.041722 +127.0.0.1, 2018-09-24 13:39:45, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.087510 +127.0.0.1, 2018-09-24 13:39:46, GET, /SP/appadmin/ccache, HTTP/1.1, 200, 0.066248 +127.0.0.1, 2018-09-24 13:39:47, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.041628 +127.0.0.1, 2018-09-24 13:39:47, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.114486 +127.0.0.1, 2018-09-24 13:40:11, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.049542 +127.0.0.1, 2018-09-24 13:40:19, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.039041 +127.0.0.1, 2018-09-24 13:40:23, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.040386 +127.0.0.1, 2018-09-24 13:40:50, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.085641 +127.0.0.1, 2018-09-24 13:40:51, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.116625 +127.0.0.1, 2018-09-24 13:41:17, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.074520 +127.0.0.1, 2018-09-24 13:41:17, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000606 +127.0.0.1, 2018-09-24 13:41:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.133439 +127.0.0.1, 2018-09-24 13:41:42, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.052131 +127.0.0.1, 2018-09-24 13:41:45, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.048506 +127.0.0.1, 2018-09-24 13:41:45, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.074321 +127.0.0.1, 2018-09-24 13:41:46, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.049464 +127.0.0.1, 2018-09-24 13:42:03, GET, /SP/appadmin/update/db/auth_group/4, HTTP/1.1, 200, 0.085250 +127.0.0.1, 2018-09-24 13:42:09, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.054046 +127.0.0.1, 2018-09-24 13:44:15, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.061998 +127.0.0.1, 2018-09-24 13:44:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.153369 +127.0.0.1, 2018-09-24 13:44:17, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.061689 +127.0.0.1, 2018-09-24 13:44:19, GET, /SP/appadmin/insert/db/auth_group, HTTP/1.1, 200, 0.041997 +127.0.0.1, 2018-09-24 13:44:21, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.040571 +127.0.0.1, 2018-09-24 13:44:22, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.101149 +127.0.0.1, 2018-09-24 13:44:22, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.076745 +127.0.0.1, 2018-09-24 13:44:42, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.077099 +127.0.0.1, 2018-09-24 13:44:43, GET, /favicon.ico, HTTP/1.1, 400, 0.000221 +127.0.0.1, 2018-09-24 13:44:51, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.077787 +127.0.0.1, 2018-09-24 13:44:51, GET, /favicon.ico, HTTP/1.1, 400, 0.000331 +127.0.0.1, 2018-09-24 13:44:59, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.13-44-51.5f6b97d4-f2db-44ff-b5a0-c0f44a7ae176, HTTP/1.1, 200, 0.165699 +127.0.0.1, 2018-09-24 13:44:59, GET, /favicon.ico, HTTP/1.1, 400, 0.000200 +127.0.0.1, 2018-09-24 13:45:15, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.056148 +127.0.0.1, 2018-09-24 13:45:15, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.005914 +127.0.0.1, 2018-09-24 13:45:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.106760 +127.0.0.1, 2018-09-24 13:47:26, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.088356 +127.0.0.1, 2018-09-24 13:47:27, GET, /favicon.ico, HTTP/1.1, 400, 0.001026 +127.0.0.1, 2018-09-24 13:47:43, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.13-47-26.cea36215-6c4f-4c24-b68a-9fa628c4095a, HTTP/1.1, 200, 0.162368 +127.0.0.1, 2018-09-24 13:47:44, GET, /favicon.ico, HTTP/1.1, 400, 0.000628 +127.0.0.1, 2018-09-24 13:47:53, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.080450 +127.0.0.1, 2018-09-24 13:47:53, GET, /favicon.ico, HTTP/1.1, 400, 0.000250 +127.0.0.1, 2018-09-24 13:47:57, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.13-47-53.8099e445-0191-4ba0-893c-0386f0015323, HTTP/1.1, 200, 0.187412 +127.0.0.1, 2018-09-24 13:47:57, GET, /favicon.ico, HTTP/1.1, 400, 0.000227 +127.0.0.1, 2018-09-24 13:48:07, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.065205 +127.0.0.1, 2018-09-24 13:48:07, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001688 +127.0.0.1, 2018-09-24 13:48:07, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.086171 +127.0.0.1, 2018-09-24 13:49:20, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.078050 +127.0.0.1, 2018-09-24 13:49:20, GET, /favicon.ico, HTTP/1.1, 400, 0.000371 +127.0.0.1, 2018-09-24 13:49:22, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.067378 +127.0.0.1, 2018-09-24 13:49:24, GET, /favicon.ico, HTTP/1.1, 400, 0.000303 +127.0.0.1, 2018-09-24 13:49:25, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.13-49-20.f6ac2903-4ac8-494a-a317-8d9a12efd0ca, HTTP/1.1, 200, 0.138678 +127.0.0.1, 2018-09-24 13:49:25, GET, /favicon.ico, HTTP/1.1, 400, 0.000328 +127.0.0.1, 2018-09-24 13:49:44, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.046410 +127.0.0.1, 2018-09-24 13:49:45, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000915 +127.0.0.1, 2018-09-24 13:49:45, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070401 +127.0.0.1, 2018-09-24 13:54:00, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.106304 +127.0.0.1, 2018-09-24 13:54:00, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.002165 +127.0.0.1, 2018-09-24 13:54:00, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.074773 +127.0.0.1, 2018-09-24 13:54:05, GET, /SP/appadmin/add_group/16, HTTP/1.1, 200, 0.055265 +127.0.0.1, 2018-09-24 13:54:07, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.052117 +127.0.0.1, 2018-09-24 13:54:07, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063782 +127.0.0.1, 2018-09-24 13:55:38, GET, /SP/appadmin/add_group/16, HTTP/1.1, 200, 0.066534 +127.0.0.1, 2018-09-24 13:55:43, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.059783 +127.0.0.1, 2018-09-24 13:55:43, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.077683 +127.0.0.1, 2018-09-24 13:56:16, GET, /SP/appadmin/change_task/15, HTTP/1.1, 200, 0.076113 +127.0.0.1, 2018-09-24 13:56:24, POST, /SP/appadmin/change_task/15, HTTP/1.1, 200, 0.063879 +127.0.0.1, 2018-09-24 13:56:26, GET, /SP/appadmin/change_task/15, HTTP/1.1, 200, 0.043209 +127.0.0.1, 2018-09-24 13:56:28, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.057044 +127.0.0.1, 2018-09-24 13:56:28, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.081963 +127.0.0.1, 2018-09-24 13:56:50, GET, /SP/appadmin/delete_task/15, HTTP/1.1, 303, 0.042440 +127.0.0.1, 2018-09-24 13:56:50, GET, /SP/appadmin/, HTTP/1.1, 200, 0.052956 +127.0.0.1, 2018-09-24 13:56:50, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.107777 +127.0.0.1, 2018-09-24 13:58:52, GET, /SP/appadmin/, HTTP/1.1, 200, 0.067449 +127.0.0.1, 2018-09-24 13:58:53, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.002934 +127.0.0.1, 2018-09-24 13:58:53, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072168 +127.0.0.1, 2018-09-24 13:58:55, GET, /SP/appadmin/change_group/1, HTTP/1.1, 500, 0.080121 +127.0.0.1, 2018-09-24 13:58:55, GET, /favicon.ico, HTTP/1.1, 400, 0.000229 +127.0.0.1, 2018-09-24 13:58:57, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.13-58-55.3ec51b6c-4923-461a-a237-f93384d4a5dd, HTTP/1.1, 200, 0.037950 +127.0.0.1, 2018-09-24 13:58:57, GET, /favicon.ico, HTTP/1.1, 400, 0.000225 +127.0.0.1, 2018-09-24 13:59:00, GET, /SP/appadmin/, HTTP/1.1, 200, 0.056056 +127.0.0.1, 2018-09-24 13:59:01, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.122184 +127.0.0.1, 2018-09-24 13:59:40, GET, /SP/appadmin/, HTTP/1.1, 200, 0.069194 +127.0.0.1, 2018-09-24 13:59:40, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001243 +127.0.0.1, 2018-09-24 13:59:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.090082 +127.0.0.1, 2018-09-24 13:59:42, GET, /SP/appadmin/change_group/1, HTTP/1.1, 200, 0.059691 +127.0.0.1, 2018-09-24 13:59:59, POST, /SP/appadmin/change_group/1, HTTP/1.1, 200, 0.072021 +127.0.0.1, 2018-09-24 14:00:02, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.053306 +127.0.0.1, 2018-09-24 14:00:03, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.115807 +127.0.0.1, 2018-09-24 14:00:11, GET, /SP/appadmin/change_task/4, HTTP/1.1, 200, 0.056929 +127.0.0.1, 2018-09-24 14:00:13, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.052759 +127.0.0.1, 2018-09-24 14:00:13, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.080296 +127.0.0.1, 2018-09-24 14:03:00, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.083077 +127.0.0.1, 2018-09-24 14:03:00, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.002517 +127.0.0.1, 2018-09-24 14:03:00, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.081800 +127.0.0.1, 2018-09-24 14:05:16, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.055764 +127.0.0.1, 2018-09-24 14:05:17, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.003564 +127.0.0.1, 2018-09-24 14:05:17, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.147875 +127.0.0.1, 2018-09-24 14:05:19, GET, /SP/appadmin/add_relation/4, HTTP/1.1, 200, 0.089310 +127.0.0.1, 2018-09-24 14:05:32, POST, /SP/appadmin/add_relation/4, HTTP/1.1, 500, 0.066809 +127.0.0.1, 2018-09-24 14:05:32, GET, /favicon.ico, HTTP/1.1, 400, 0.000348 +127.0.0.1, 2018-09-24 14:05:36, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.14-05-32.31f8dead-8462-4aa9-8261-8282ab1ab771, HTTP/1.1, 200, 0.044845 +127.0.0.1, 2018-09-24 14:05:36, GET, /favicon.ico, HTTP/1.1, 400, 0.000346 +127.0.0.1, 2018-09-24 14:07:02, GET, /SP/appadmin/add_relation/4, HTTP/1.1, 200, 0.055543 +127.0.0.1, 2018-09-24 14:07:03, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.043675 +127.0.0.1, 2018-09-24 14:07:03, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.066711 +127.0.0.1, 2018-09-24 14:07:06, GET, /SP/appadmin/add_relation/4, HTTP/1.1, 200, 0.045310 +127.0.0.1, 2018-09-24 14:07:12, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.045859 +127.0.0.1, 2018-09-24 14:07:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.076137 +127.0.0.1, 2018-09-24 14:07:55, GET, /SP/appadmin/add_relation/4, HTTP/1.1, 200, 0.062011 +127.0.0.1, 2018-09-24 14:08:00, POST, /SP/appadmin/add_relation/4, HTTP/1.1, 200, 0.060629 +127.0.0.1, 2018-09-24 14:08:27, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.066815 +127.0.0.1, 2018-09-24 14:08:28, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.089067 +127.0.0.1, 2018-09-24 14:08:54, GET, /SP/appadmin/change_group/2, HTTP/1.1, 200, 0.052480 +127.0.0.1, 2018-09-24 14:09:17, POST, /SP/appadmin/change_group/2, HTTP/1.1, 200, 0.199273 +127.0.0.1, 2018-09-24 14:09:19, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.058277 +127.0.0.1, 2018-09-24 14:09:20, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.090518 +127.0.0.1, 2018-09-24 14:10:23, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.095151 +127.0.0.1, 2018-09-24 14:10:24, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000585 +127.0.0.1, 2018-09-24 14:10:24, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.144590 +127.0.0.1, 2018-09-24 14:10:45, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.050849 +127.0.0.1, 2018-09-24 14:10:45, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000531 +127.0.0.1, 2018-09-24 14:10:45, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.112873 +127.0.0.1, 2018-09-24 14:10:47, GET, /SP/appadmin/change_relation/4, HTTP/1.1, 200, 0.095006 +127.0.0.1, 2018-09-24 14:10:51, POST, /SP/appadmin/change_relation/4, HTTP/1.1, 200, 0.059113 +127.0.0.1, 2018-09-24 14:10:53, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.049550 +127.0.0.1, 2018-09-24 14:10:54, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.084842 +127.0.0.1, 2018-09-24 14:13:51, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.057187 +127.0.0.1, 2018-09-24 14:13:51, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.004033 +127.0.0.1, 2018-09-24 14:13:51, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.081104 +127.0.0.1, 2018-09-24 14:14:26, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.048682 +127.0.0.1, 2018-09-24 14:14:27, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001091 +127.0.0.1, 2018-09-24 14:14:46, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.051989 +127.0.0.1, 2018-09-24 14:14:46, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000737 +127.0.0.1, 2018-09-24 14:16:36, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.08-15-41.ea6d2041-094b-49ef-bc93-33ecdcc3e79b, HTTP/1.1, 303, 0.010513 +127.0.0.1, 2018-09-24 14:16:36, GET, /admin/default/index, HTTP/1.1, 200, 0.023942 +127.0.0.1, 2018-09-24 14:16:37, GET, /favicon.ico, HTTP/1.1, 400, 0.001273 +127.0.0.1, 2018-09-24 14:16:41, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.060488 +127.0.0.1, 2018-09-24 14:16:41, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000636 +127.0.0.1, 2018-09-24 14:16:45, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.043253 +127.0.0.1, 2018-09-24 14:16:46, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000500 +127.0.0.1, 2018-09-24 14:17:07, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.047883 +127.0.0.1, 2018-09-24 14:17:07, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000882 +127.0.0.1, 2018-09-24 14:17:11, GET, /SP/default/user/login, HTTP/1.1, 200, 0.040957 +127.0.0.1, 2018-09-24 14:17:16, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.045684 +127.0.0.1, 2018-09-24 14:17:42, GET, /SP/default/user/login, HTTP/1.1, 200, 0.031621 +127.0.0.1, 2018-09-24 14:17:49, POST, /SP/default/user/login, HTTP/1.1, 303, 0.043136 +127.0.0.1, 2018-09-24 14:17:49, GET, /SP/default/index, HTTP/1.1, 200, 0.026130 +127.0.0.1, 2018-09-24 14:17:52, GET, /SP/default/myhome, HTTP/1.1, 200, 0.030716 +127.0.0.1, 2018-09-24 14:17:54, GET, /SP/default/myclass, HTTP/1.1, 200, 0.032466 +127.0.0.1, 2018-09-24 14:17:55, GET, /SP/default/index, HTTP/1.1, 200, 0.030482 +127.0.0.1, 2018-09-24 14:18:05, GET, /SP/appadmin, HTTP/1.1, 200, 0.046422 +127.0.0.1, 2018-09-24 14:18:05, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.091373 +127.0.0.1, 2018-09-24 14:18:17, GET, /SP/appadmin, HTTP/1.1, 200, 0.068633 +127.0.0.1, 2018-09-24 14:18:17, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.003749 +127.0.0.1, 2018-09-24 14:18:17, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.090276 +127.0.0.1, 2018-09-24 14:18:29, GET, /SP/appadmin/change_group/3, HTTP/1.1, 200, 0.089172 +127.0.0.1, 2018-09-24 14:18:52, POST, /SP/appadmin/change_group/3, HTTP/1.1, 200, 0.067867 +127.0.0.1, 2018-09-24 14:18:54, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.048300 +127.0.0.1, 2018-09-24 14:18:54, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.081524 +127.0.0.1, 2018-09-24 14:19:07, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.051492 +127.0.0.1, 2018-09-24 14:19:07, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.063825 +127.0.0.1, 2018-09-24 14:21:15, GET, /SP/, HTTP/1.1, 200, 0.036218 +127.0.0.1, 2018-09-24 14:21:25, GET, /SP/, HTTP/1.1, 200, 0.047057 +127.0.0.1, 2018-09-24 14:21:26, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000447 +127.0.0.1, 2018-09-24 14:21:29, GET, /SP/, HTTP/1.1, 200, 0.039751 +127.0.0.1, 2018-09-24 14:21:30, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000816 +127.0.0.1, 2018-09-24 14:21:43, GET, /SP/, HTTP/1.1, 200, 0.053199 +127.0.0.1, 2018-09-24 14:21:43, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000601 +127.0.0.1, 2018-09-24 14:21:45, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.053081 +127.0.0.1, 2018-09-24 14:21:46, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.071265 +127.0.0.1, 2018-09-24 14:21:47, GET, /SP/, HTTP/1.1, 200, 0.031321 +127.0.0.1, 2018-09-24 14:23:21, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.071338 +127.0.0.1, 2018-09-24 14:23:21, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.088512 +127.0.0.1, 2018-09-24 14:24:12, GET, /SP/appadmin/ccache, HTTP/1.1, 200, 0.050693 +127.0.0.1, 2018-09-24 14:24:14, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.062250 +127.0.0.1, 2018-09-24 14:24:14, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072733 +127.0.0.1, 2018-09-24 14:27:09, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.092596 +127.0.0.1, 2018-09-24 14:27:10, GET, /favicon.ico, HTTP/1.1, 400, 0.000303 +127.0.0.1, 2018-09-24 14:27:11, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.14-27-09.2797c058-322a-4512-b0de-38cf90383715, HTTP/1.1, 200, 0.139934 +127.0.0.1, 2018-09-24 14:27:11, GET, /favicon.ico, HTTP/1.1, 400, 0.000358 +127.0.0.1, 2018-09-24 14:36:22, GET, /SP/, HTTP/1.1, 200, 0.122365 +127.0.0.1, 2018-09-24 14:36:25, GET, /SP/default/myhome, HTTP/1.1, 200, 0.031339 +127.0.0.1, 2018-09-24 14:36:32, GET, /SP/default/myclass, HTTP/1.1, 200, 0.034339 +127.0.0.1, 2018-09-24 14:36:38, GET, /SP/private/home, HTTP/1.1, 404, 0.020332 +127.0.0.1, 2018-09-24 14:36:38, GET, /favicon.ico, HTTP/1.1, 400, 0.000227 +127.0.0.1, 2018-09-24 14:36:40, GET, /SP/default/myclass, HTTP/1.1, 200, 0.033593 +127.0.0.1, 2018-09-24 14:36:42, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.078420 +127.0.0.1, 2018-09-24 14:36:42, GET, /favicon.ico, HTTP/1.1, 400, 0.000213 +127.0.0.1, 2018-09-24 14:36:44, GET, /SP/default/myclass, HTTP/1.1, 200, 0.035618 +127.0.0.1, 2018-09-24 14:36:47, GET, /SP/default/myclass, HTTP/1.1, 200, 0.053272 +127.0.0.1, 2018-09-24 14:36:49, GET, /SP/default/myhome, HTTP/1.1, 200, 0.031619 +127.0.0.1, 2018-09-24 14:39:55, GET, /SP/default/myhome, HTTP/1.1, 200, 0.046134 +127.0.0.1, 2018-09-24 14:39:57, GET, /SP/default/myclass, HTTP/1.1, 200, 0.035304 +127.0.0.1, 2018-09-24 14:39:59, GET, /SP/default/user/logout, HTTP/1.1, 303, 0.029131 +127.0.0.1, 2018-09-24 14:40:00, GET, /SP/default/index, HTTP/1.1, 200, 0.027387 +127.0.0.1, 2018-09-24 14:40:01, GET, /SP/default/user/login, HTTP/1.1, 200, 0.035158 +127.0.0.1, 2018-09-24 14:40:06, GET, /SP/default/user/register, HTTP/1.1, 200, 0.032892 +127.0.0.1, 2018-09-24 14:40:29, POST, /SP/default/user/register, HTTP/1.1, 200, 0.040131 +127.0.0.1, 2018-09-24 14:40:36, GET, /SP/default/myclass, HTTP/1.1, 200, 0.031901 +127.0.0.1, 2018-09-24 14:42:03, GET, /SP/default/myclass, HTTP/1.1, 200, 0.057015 +127.0.0.1, 2018-09-24 14:42:06, GET, /SP/default/user/login, HTTP/1.1, 200, 0.032478 +127.0.0.1, 2018-09-24 14:42:08, GET, /SP/default/user/register, HTTP/1.1, 200, 0.032154 +127.0.0.1, 2018-09-24 14:42:10, GET, /SP/default/user/login, HTTP/1.1, 200, 0.031818 +127.0.0.1, 2018-09-24 14:42:17, POST, /SP/default/user/login, HTTP/1.1, 303, 0.043537 +127.0.0.1, 2018-09-24 14:42:17, GET, /SP/default/index, HTTP/1.1, 200, 0.029516 +127.0.0.1, 2018-09-24 14:42:19, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.080396 +127.0.0.1, 2018-09-24 14:42:19, GET, /favicon.ico, HTTP/1.1, 400, 0.000388 +127.0.0.1, 2018-09-24 14:42:21, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.14-42-19.091ca44b-ec9b-43b0-bc59-d7f510cb7196, HTTP/1.1, 200, 0.135010 +127.0.0.1, 2018-09-24 14:42:21, GET, /favicon.ico, HTTP/1.1, 400, 0.000260 +127.0.0.1, 2018-09-24 14:42:53, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.071459 +127.0.0.1, 2018-09-24 14:42:54, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000942 +127.0.0.1, 2018-09-24 14:42:54, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.069333 +127.0.0.1, 2018-09-24 14:43:25, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.187131 +127.0.0.1, 2018-09-24 14:43:26, GET, /favicon.ico, HTTP/1.1, 400, 0.000420 +127.0.0.1, 2018-09-24 14:43:42, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.104566 +127.0.0.1, 2018-09-24 14:43:43, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000565 +127.0.0.1, 2018-09-24 14:43:43, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.161503 +127.0.0.1, 2018-09-24 14:44:03, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.097773 +127.0.0.1, 2018-09-24 14:44:04, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.004860 +127.0.0.1, 2018-09-24 14:44:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.150621 +127.0.0.1, 2018-09-24 14:44:19, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.079339 +127.0.0.1, 2018-09-24 14:44:19, GET, /favicon.ico, HTTP/1.1, 400, 0.000336 +127.0.0.1, 2018-09-24 14:44:25, GET, /SP/appadmin/index, HTTP/1.1, 500, 0.176156 +127.0.0.1, 2018-09-24 14:44:25, GET, /favicon.ico, HTTP/1.1, 400, 0.000798 +127.0.0.1, 2018-09-24 14:44:57, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.074599 +127.0.0.1, 2018-09-24 14:44:58, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.002887 +127.0.0.1, 2018-09-24 14:44:58, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.103103 +127.0.0.1, 2018-09-24 14:45:11, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.098942 +127.0.0.1, 2018-09-24 14:45:12, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000892 +127.0.0.1, 2018-09-24 14:45:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.108679 +127.0.0.1, 2018-09-24 14:45:12, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.065549 +127.0.0.1, 2018-09-24 14:45:13, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.092973 +127.0.0.1, 2018-09-24 14:45:13, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.107858 +127.0.0.1, 2018-09-24 14:45:14, GET, /favicon.ico, HTTP/1.1, 400, 0.000245 +127.0.0.1, 2018-09-24 14:45:16, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.057083 +127.0.0.1, 2018-09-24 14:45:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.062755 +127.0.0.1, 2018-09-24 14:46:40, GET, /SP/appadmin/delete_task/16, HTTP/1.1, 303, 0.058058 +127.0.0.1, 2018-09-24 14:46:40, GET, /SP/appadmin/, HTTP/1.1, 200, 0.057372 +127.0.0.1, 2018-09-24 14:46:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.073642 +127.0.0.1, 2018-09-24 14:46:54, GET, /SP/appadmin/add_task, HTTP/1.1, 303, 0.038590 +127.0.0.1, 2018-09-24 14:46:54, GET, /SP/appadmin/, HTTP/1.1, 200, 0.053489 +127.0.0.1, 2018-09-24 14:46:54, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.071346 +127.0.0.1, 2018-09-24 14:46:59, GET, /SP/appadmin/add_task, HTTP/1.1, 303, 0.029248 +127.0.0.1, 2018-09-24 14:46:59, GET, /SP/appadmin/, HTTP/1.1, 200, 0.055832 +127.0.0.1, 2018-09-24 14:46:59, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.082674 +127.0.0.1, 2018-09-24 14:48:36, GET, /SP/appadmin/select/db, HTTP/1.1, 200, 0.078523 +127.0.0.1, 2018-09-24 14:48:41, GET, /SP/appadmin/, HTTP/1.1, 200, 0.056393 +127.0.0.1, 2018-09-24 14:48:41, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.073326 +127.0.0.1, 2018-09-24 15:06:00, GET, /SP/appadmin/ccache, HTTP/1.1, 200, 0.150554 +127.0.0.1, 2018-09-24 15:06:08, GET, /SP/appadmin/, HTTP/1.1, 200, 0.049818 +127.0.0.1, 2018-09-24 15:06:08, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.074898 +127.0.0.1, 2018-09-24 15:06:19, GET, /SP/appadmin/add_task, HTTP/1.1, 303, 0.025812 +127.0.0.1, 2018-09-24 15:06:19, GET, /SP/appadmin/, HTTP/1.1, 200, 0.048545 +127.0.0.1, 2018-09-24 15:06:19, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.089890 +127.0.0.1, 2018-09-24 15:06:25, GET, /SP/appadmin/add_task, HTTP/1.1, 303, 0.037710 +127.0.0.1, 2018-09-24 15:06:25, GET, /SP/appadmin/, HTTP/1.1, 200, 0.078999 +127.0.0.1, 2018-09-24 15:06:26, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.182348 +127.0.0.1, 2018-09-24 15:07:07, GET, /SP/appadmin/, HTTP/1.1, 200, 0.069171 +127.0.0.1, 2018-09-24 15:07:08, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001290 +127.0.0.1, 2018-09-24 15:07:08, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.138915 +127.0.0.1, 2018-09-24 15:07:10, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.050179 +127.0.0.1, 2018-09-24 15:07:21, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.044840 +127.0.0.1, 2018-09-24 15:07:21, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.085644 +127.0.0.1, 2018-09-24 15:39:00, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.119423 +127.0.0.1, 2018-09-24 15:39:00, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.000999 +127.0.0.1, 2018-09-24 15:39:00, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.001130 +127.0.0.1, 2018-09-24 15:39:00, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.000826 +127.0.0.1, 2018-09-24 15:39:00, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.001793 +127.0.0.1, 2018-09-24 15:39:00, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.005372 +127.0.0.1, 2018-09-24 15:39:00, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.005807 +127.0.0.1, 2018-09-24 15:39:00, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.003977 +127.0.0.1, 2018-09-24 15:39:00, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.002003 +127.0.0.1, 2018-09-24 15:39:00, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.001940 +127.0.0.1, 2018-09-24 15:39:00, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001236 +127.0.0.1, 2018-09-24 15:39:00, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.068246 +127.0.0.1, 2018-09-24 15:39:06, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.056012 +127.0.0.1, 2018-09-24 15:39:21, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.056281 +127.0.0.1, 2018-09-24 15:39:25, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.051944 +127.0.0.1, 2018-09-24 15:39:25, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.068867 +127.0.0.1, 2018-09-24 15:39:34, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.045658 +127.0.0.1, 2018-09-24 15:39:52, POST, /SP/appadmin/add_task, HTTP/1.1, 500, 0.071928 +127.0.0.1, 2018-09-24 15:39:53, GET, /favicon.ico, HTTP/1.1, 400, 0.000204 +127.0.0.1, 2018-09-24 15:39:55, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.15-39-52.78464803-e59b-4281-abde-3d9d9ba30b48, HTTP/1.1, 200, 0.041359 +127.0.0.1, 2018-09-24 15:39:55, GET, /favicon.ico, HTTP/1.1, 400, 0.000240 +127.0.0.1, 2018-09-24 15:43:42, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.15-39-52.78464803-e59b-4281-abde-3d9d9ba30b48, HTTP/1.1, 200, 0.039020 +127.0.0.1, 2018-09-24 15:43:42, GET, /favicon.ico, HTTP/1.1, 400, 0.000395 +127.0.0.1, 2018-09-24 15:44:08, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.045632 +127.0.0.1, 2018-09-24 15:44:10, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.046609 +127.0.0.1, 2018-09-24 15:44:10, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.069497 +127.0.0.1, 2018-09-24 15:44:16, GET, /SP/appadmin/add_relation/4, HTTP/1.1, 200, 0.061660 +127.0.0.1, 2018-09-24 15:44:18, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.050049 +127.0.0.1, 2018-09-24 15:44:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.081242 +127.0.0.1, 2018-09-24 15:45:18, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.066841 +127.0.0.1, 2018-09-24 15:45:28, POST, /SP/appadmin/add_task, HTTP/1.1, 500, 0.076540 +127.0.0.1, 2018-09-24 15:45:28, GET, /favicon.ico, HTTP/1.1, 400, 0.000290 +127.0.0.1, 2018-09-24 15:45:30, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.15-45-28.d03a6dea-77d5-4c23-968b-10584836bcfe, HTTP/1.1, 200, 0.037882 +127.0.0.1, 2018-09-24 15:45:30, GET, /favicon.ico, HTTP/1.1, 400, 0.000256 +127.0.0.1, 2018-09-24 15:45:57, GET, /favicon.ico, HTTP/1.1, 400, 0.000244 +127.0.0.1, 2018-09-24 15:45:59, GET, /favicon.ico, HTTP/1.1, 400, 0.000239 +127.0.0.1, 2018-09-24 15:46:01, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.049839 +127.0.0.1, 2018-09-24 15:46:03, POST, /SP/appadmin/add_task, HTTP/1.1, 500, 0.061946 +127.0.0.1, 2018-09-24 15:46:03, GET, /favicon.ico, HTTP/1.1, 400, 0.000413 +127.0.0.1, 2018-09-24 15:46:05, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.15-46-03.06370395-4251-4ae6-9451-f4f0c8a8360c, HTTP/1.1, 200, 0.032414 +127.0.0.1, 2018-09-24 15:46:05, GET, /favicon.ico, HTTP/1.1, 400, 0.000232 +127.0.0.1, 2018-09-24 15:46:32, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.053759 +127.0.0.1, 2018-09-24 15:46:33, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.060263 +127.0.0.1, 2018-09-24 15:46:35, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.102407 +127.0.0.1, 2018-09-24 15:46:36, GET, /favicon.ico, HTTP/1.1, 400, 0.000319 +127.0.0.1, 2018-09-24 15:46:40, GET, /SP/a, HTTP/1.1, 404, 0.019984 +127.0.0.1, 2018-09-24 15:46:40, GET, /favicon.ico, HTTP/1.1, 400, 0.000208 +127.0.0.1, 2018-09-24 15:46:44, GET, /SP/, HTTP/1.1, 200, 0.024929 +127.0.0.1, 2018-09-24 15:46:46, GET, /SP/default/myclass, HTTP/1.1, 200, 0.037089 +127.0.0.1, 2018-09-24 15:46:48, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.058803 +127.0.0.1, 2018-09-24 15:46:48, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.095343 +127.0.0.1, 2018-09-24 15:46:59, GET, /SP/appadmin/change_task/18, HTTP/1.1, 200, 0.061676 +127.0.0.1, 2018-09-24 15:47:01, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.050145 +127.0.0.1, 2018-09-24 15:47:01, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.140116 +127.0.0.1, 2018-09-24 15:48:11, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.057907 +127.0.0.1, 2018-09-24 15:48:27, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.064222 +127.0.0.1, 2018-09-24 15:48:29, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.084241 +127.0.0.1, 2018-09-24 15:48:29, GET, /favicon.ico, HTTP/1.1, 400, 0.000228 +127.0.0.1, 2018-09-24 15:48:35, GET, /SP/appadmin, HTTP/1.1, 200, 0.059091 +127.0.0.1, 2018-09-24 15:48:35, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.120407 +127.0.0.1, 2018-09-24 15:48:42, GET, /SP/appadmin/change_task/19, HTTP/1.1, 200, 0.068178 +127.0.0.1, 2018-09-24 15:49:12, GET, /SP/appadmin, HTTP/1.1, 200, 0.055884 +127.0.0.1, 2018-09-24 15:49:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.096810 +127.0.0.1, 2018-09-24 15:49:20, GET, /SP/appadmin/delete_task/19, HTTP/1.1, 303, 0.036193 +127.0.0.1, 2018-09-24 15:49:20, GET, /SP/appadmin/, HTTP/1.1, 200, 0.046606 +127.0.0.1, 2018-09-24 15:49:20, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.077846 +127.0.0.1, 2018-09-24 15:49:48, GET, /SP/appadmin/, HTTP/1.1, 200, 0.059402 +127.0.0.1, 2018-09-24 15:49:49, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.002172 +127.0.0.1, 2018-09-24 15:49:49, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.087029 +127.0.0.1, 2018-09-24 15:49:58, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.048339 +127.0.0.1, 2018-09-24 15:50:05, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.066304 +127.0.0.1, 2018-09-24 15:50:07, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.046297 +127.0.0.1, 2018-09-24 15:50:07, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.094394 +127.0.0.1, 2018-09-24 15:51:29, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.066555 +127.0.0.1, 2018-09-24 15:51:44, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.059370 +127.0.0.1, 2018-09-24 15:51:46, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.057590 +127.0.0.1, 2018-09-24 15:51:46, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.099158 +127.0.0.1, 2018-09-24 15:51:55, GET, /SP/appadmin/change_task/21, HTTP/1.1, 200, 0.094391 +127.0.0.1, 2018-09-24 15:51:57, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.044853 +127.0.0.1, 2018-09-24 15:51:58, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.068273 +127.0.0.1, 2018-09-24 15:52:41, GET, /SP/appadmin/delete_task/21, HTTP/1.1, 303, 0.032619 +127.0.0.1, 2018-09-24 15:52:41, GET, /SP/appadmin/, HTTP/1.1, 200, 0.053172 +127.0.0.1, 2018-09-24 15:52:41, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.084784 +127.0.0.1, 2018-09-24 15:52:44, GET, /SP/appadmin/delete_task/20, HTTP/1.1, 303, 0.023550 +127.0.0.1, 2018-09-24 15:52:44, GET, /SP/appadmin/, HTTP/1.1, 200, 0.046087 +127.0.0.1, 2018-09-24 15:52:44, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.061143 +127.0.0.1, 2018-09-24 15:52:47, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.051344 +127.0.0.1, 2018-09-24 15:52:59, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.061456 +127.0.0.1, 2018-09-24 15:53:01, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.104539 +127.0.0.1, 2018-09-24 15:53:01, GET, /favicon.ico, HTTP/1.1, 400, 0.000795 +127.0.0.1, 2018-09-24 15:53:05, GET, /SP/appadmin/, HTTP/1.1, 200, 0.045037 +127.0.0.1, 2018-09-24 15:53:06, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.111475 +127.0.0.1, 2018-09-24 15:53:12, GET, /SP/appadmin/change_task/22, HTTP/1.1, 200, 0.057327 +127.0.0.1, 2018-09-24 15:53:59, GET, /SP/appadmin/, HTTP/1.1, 200, 0.055526 +127.0.0.1, 2018-09-24 15:53:59, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.081894 +127.0.0.1, 2018-09-24 15:54:02, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.053823 +127.0.0.1, 2018-09-24 15:54:10, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.063764 +127.0.0.1, 2018-09-24 15:54:12, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.048794 +127.0.0.1, 2018-09-24 15:54:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.086788 +127.0.0.1, 2018-09-24 15:54:48, GET, /SP/appadmin/delete_task/23, HTTP/1.1, 303, 0.034602 +127.0.0.1, 2018-09-24 15:54:48, GET, /SP/appadmin/, HTTP/1.1, 200, 0.051225 +127.0.0.1, 2018-09-24 15:54:49, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.077852 +127.0.0.1, 2018-09-24 15:54:51, GET, /SP/appadmin/delete_task/22, HTTP/1.1, 303, 0.025187 +127.0.0.1, 2018-09-24 15:54:51, GET, /SP/appadmin/, HTTP/1.1, 200, 0.043489 +127.0.0.1, 2018-09-24 15:54:51, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067355 +127.0.0.1, 2018-09-24 15:55:44, GET, /SP/appadmin/, HTTP/1.1, 500, 0.093122 +127.0.0.1, 2018-09-24 15:55:44, GET, /favicon.ico, HTTP/1.1, 400, 0.000336 +127.0.0.1, 2018-09-24 15:55:52, GET, /SP/appadmin/, HTTP/1.1, 200, 0.126701 +127.0.0.1, 2018-09-24 15:55:53, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000897 +127.0.0.1, 2018-09-24 15:55:53, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.077879 +127.0.0.1, 2018-09-24 15:56:17, GET, /SP/appadmin/, HTTP/1.1, 200, 0.060355 +127.0.0.1, 2018-09-24 15:56:18, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.002098 +127.0.0.1, 2018-09-24 15:56:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.089948 +127.0.0.1, 2018-09-24 15:57:20, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.074639 +127.0.0.1, 2018-09-24 15:57:56, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.049192 +127.0.0.1, 2018-09-24 15:57:57, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000659 +127.0.0.1, 2018-09-24 15:58:05, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.066961 +127.0.0.1, 2018-09-24 15:58:05, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000601 +127.0.0.1, 2018-09-24 15:58:25, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.070720 +127.0.0.1, 2018-09-24 15:58:26, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.001140 +127.0.0.1, 2018-09-24 15:58:51, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.106134 +127.0.0.1, 2018-09-24 15:58:51, GET, /favicon.ico, HTTP/1.1, 400, 0.000416 +127.0.0.1, 2018-09-24 15:58:53, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.054212 +127.0.0.1, 2018-09-24 15:58:54, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.065606 +127.0.0.1, 2018-09-24 15:58:54, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.108751 +127.0.0.1, 2018-09-24 15:59:03, GET, /SP/default/myhome, HTTP/1.1, 200, 0.035428 +127.0.0.1, 2018-09-24 15:59:58, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.059429 +127.0.0.1, 2018-09-24 15:59:58, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.068935 +127.0.0.1, 2018-09-24 16:00:36, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.072830 +127.0.0.1, 2018-09-24 16:00:56, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.060821 +127.0.0.1, 2018-09-24 16:00:56, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000758 +127.0.0.1, 2018-09-24 16:01:24, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.084548 +127.0.0.1, 2018-09-24 16:01:24, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.089916 +127.0.0.1, 2018-09-24 16:01:40, GET, /, HTTP/1.1, 303, 0.000608 +127.0.0.1, 2018-09-24 16:01:40, GET, /welcome/default/index, HTTP/1.1, 200, 0.029750 +127.0.0.1, 2018-09-24 16:01:40, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.000684 +127.0.0.1, 2018-09-24 16:01:40, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.000666 +127.0.0.1, 2018-09-24 16:01:40, GET, /welcome/static/css/calendar.css, HTTP/1.1, 304, 0.001276 +127.0.0.1, 2018-09-24 16:01:40, GET, /welcome/static/js/jquery.js, HTTP/1.1, 304, 0.000638 +127.0.0.1, 2018-09-24 16:01:40, GET, /welcome/static/js/calendar.js, HTTP/1.1, 304, 0.000564 +127.0.0.1, 2018-09-24 16:01:40, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.002539 +127.0.0.1, 2018-09-24 16:01:40, GET, /welcome/static/js/web2py.js, HTTP/1.1, 304, 0.003750 +127.0.0.1, 2018-09-24 16:01:40, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.003105 +127.0.0.1, 2018-09-24 16:01:40, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.001111 +127.0.0.1, 2018-09-24 16:01:46, GET, /SP, HTTP/1.1, 200, 0.040034 +127.0.0.1, 2018-09-24 16:01:48, GET, /SP/default/task, HTTP/1.1, 200, 0.077031 +127.0.0.1, 2018-09-24 16:09:10, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.101815 +127.0.0.1, 2018-09-24 16:09:11, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.107623 +127.0.0.1, 2018-09-24 16:09:15, GET, /SP/appadmin/change_task/17, HTTP/1.1, 200, 0.064932 +127.0.0.1, 2018-09-24 16:11:53, GET, /, HTTP/1.1, 303, 0.000383 +127.0.0.1, 2018-09-24 16:11:53, GET, /welcome/default/index, HTTP/1.1, 200, 0.028381 +127.0.0.1, 2018-09-24 16:11:56, GET, /SP, HTTP/1.1, 200, 0.041621 +127.0.0.1, 2018-09-24 16:12:01, GET, /SP/default/task, HTTP/1.1, 200, 0.030971 +127.0.0.1, 2018-09-24 16:12:08, GET, /SP/default/task, HTTP/1.1, 200, 0.031987 +127.0.0.1, 2018-09-24 16:12:37, GET, /SP, HTTP/1.1, 200, 0.027083 +127.0.0.1, 2018-09-24 16:12:40, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.059706 +127.0.0.1, 2018-09-24 16:12:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.086485 +127.0.0.1, 2018-09-24 16:12:56, GET, /SP/appadmin/change_task/17, HTTP/1.1, 200, 0.067817 +127.0.0.1, 2018-09-24 16:12:59, POST, /SP/appadmin/change_task/17, HTTP/1.1, 500, 0.085038 +127.0.0.1, 2018-09-24 16:12:59, GET, /favicon.ico, HTTP/1.1, 400, 0.000227 +127.0.0.1, 2018-09-24 16:13:02, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.16-12-59.611f4e4c-c450-49a6-94ae-2d5da784db45, HTTP/1.1, 200, 0.050164 +127.0.0.1, 2018-09-24 16:13:02, GET, /favicon.ico, HTTP/1.1, 400, 0.000239 +127.0.0.1, 2018-09-24 16:13:09, GET, /SP/appadmin/change_task/17, HTTP/1.1, 200, 0.049368 +127.0.0.1, 2018-09-24 16:13:10, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.079367 +127.0.0.1, 2018-09-24 16:13:10, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.084145 +127.0.0.1, 2018-09-24 16:13:13, GET, /SP/appadmin/delete_task/17, HTTP/1.1, 303, 0.045749 +127.0.0.1, 2018-09-24 16:13:13, GET, /SP/appadmin/, HTTP/1.1, 200, 0.056143 +127.0.0.1, 2018-09-24 16:13:14, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.067305 +127.0.0.1, 2018-09-24 16:13:15, GET, /SP/appadmin/delete_task/18, HTTP/1.1, 303, 0.027204 +127.0.0.1, 2018-09-24 16:13:15, GET, /SP/appadmin/, HTTP/1.1, 200, 0.045506 +127.0.0.1, 2018-09-24 16:13:16, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.075178 +127.0.0.1, 2018-09-24 16:13:18, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.062303 +127.0.0.1, 2018-09-24 16:13:29, POST, /SP/appadmin/add_task, HTTP/1.1, 500, 0.089019 +127.0.0.1, 2018-09-24 16:13:30, GET, /favicon.ico, HTTP/1.1, 400, 0.000888 +127.0.0.1, 2018-09-24 16:13:31, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.16-13-29.ede170a4-af38-44b8-84f2-1dacf2e878cf, HTTP/1.1, 200, 0.046199 +127.0.0.1, 2018-09-24 16:13:31, GET, /favicon.ico, HTTP/1.1, 400, 0.000352 +127.0.0.1, 2018-09-24 16:14:24, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.081307 +127.0.0.1, 2018-09-24 16:14:26, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.077874 +127.0.0.1, 2018-09-24 16:14:37, GET, /SP/, HTTP/1.1, 200, 0.034634 +127.0.0.1, 2018-09-24 16:14:39, GET, /SP/default/task, HTTP/1.1, 500, 0.065388 +127.0.0.1, 2018-09-24 16:14:39, GET, /favicon.ico, HTTP/1.1, 400, 0.000201 +127.0.0.1, 2018-09-24 16:14:40, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.16-14-39.315150f0-6b1c-45a7-87d6-a7392658336b, HTTP/1.1, 200, 0.057143 +127.0.0.1, 2018-09-24 16:14:41, GET, /favicon.ico, HTTP/1.1, 400, 0.000570 +127.0.0.1, 2018-09-24 16:15:11, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-24.16-14-39.315150f0-6b1c-45a7-87d6-a7392658336b, HTTP/1.1, 200, 0.044592 +127.0.0.1, 2018-09-24 16:15:11, GET, /favicon.ico, HTTP/1.1, 400, 0.000235 +127.0.0.1, 2018-09-24 16:15:14, GET, /SP/default/task, HTTP/1.1, 200, 0.030628 +127.0.0.1, 2018-09-24 16:15:14, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000672 +127.0.0.1, 2018-09-24 16:15:54, GET, /SP/default/task, HTTP/1.1, 200, 0.043743 +127.0.0.1, 2018-09-24 16:15:55, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000796 +127.0.0.1, 2018-09-24 16:17:03, GET, /SP/default/task, HTTP/1.1, 200, 0.036014 +127.0.0.1, 2018-09-24 16:17:04, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000730 +127.0.0.1, 2018-09-24 16:18:08, GET, /SP/default/task, HTTP/1.1, 200, 0.030020 +127.0.0.1, 2018-09-24 16:18:09, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000948 +127.0.0.1, 2018-09-24 16:18:20, GET, /SP/default/myhome, HTTP/1.1, 200, 0.038375 +127.0.0.1, 2018-09-24 16:18:21, GET, /SP/default/task, HTTP/1.1, 200, 0.035073 +127.0.0.1, 2018-09-24 16:18:23, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.064848 +127.0.0.1, 2018-09-24 16:18:23, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.076273 +127.0.0.1, 2018-09-24 16:18:26, GET, /SP/appadmin/change_task/24, HTTP/1.1, 200, 0.063065 +127.0.0.1, 2018-09-24 16:18:30, POST, /SP/appadmin/change_task/24, HTTP/1.1, 200, 0.100224 +127.0.0.1, 2018-09-24 16:18:35, GET, /SP/, HTTP/1.1, 200, 0.032610 +127.0.0.1, 2018-09-24 16:18:37, GET, /SP/default/task, HTTP/1.1, 200, 0.039230 +127.0.0.1, 2018-09-24 16:19:32, GET, /SP/default/task, HTTP/1.1, 200, 0.046317 +127.0.0.1, 2018-09-24 16:20:12, GET, /SP/default/task, HTTP/1.1, 200, 0.037705 +127.0.0.1, 2018-09-24 16:20:13, GET, /SP/private/home, HTTP/1.1, 404, 0.030703 +127.0.0.1, 2018-09-24 16:20:14, GET, /favicon.ico, HTTP/1.1, 400, 0.000353 +127.0.0.1, 2018-09-24 16:20:15, GET, /SP/default/task, HTTP/1.1, 200, 0.040402 +127.0.0.1, 2018-09-24 16:20:17, GET, /SP/default/myclass, HTTP/1.1, 200, 0.034761 +127.0.0.1, 2018-09-24 16:20:44, GET, /SP/default/task, HTTP/1.1, 200, 0.046426 +127.0.0.1, 2018-09-24 16:20:46, GET, /SP/default/myhome, HTTP/1.1, 200, 0.039101 +127.0.0.1, 2018-09-24 16:20:46, GET, /SP/default/myclass, HTTP/1.1, 200, 0.033904 +127.0.0.1, 2018-09-24 16:20:52, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.069218 +127.0.0.1, 2018-09-24 16:20:52, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.079698 +127.0.0.1, 2018-09-24 16:21:43, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.169042 +127.0.0.1, 2018-09-24 16:21:44, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000732 +127.0.0.1, 2018-09-24 16:21:44, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.132106 +127.0.0.1, 2018-09-24 16:22:05, GET, /SP/appadmin/change_task/24, HTTP/1.1, 200, 0.054062 +127.0.0.1, 2018-09-24 16:22:13, POST, /SP/appadmin/change_task/24, HTTP/1.1, 200, 0.076259 +127.0.0.1, 2018-09-24 16:22:21, GET, /SP/default/myhome, HTTP/1.1, 200, 0.037413 +127.0.0.1, 2018-09-24 16:22:23, GET, /SP/private/home, HTTP/1.1, 404, 0.034961 +127.0.0.1, 2018-09-24 16:22:23, GET, /favicon.ico, HTTP/1.1, 400, 0.000208 +127.0.0.1, 2018-09-24 16:22:25, GET, /SP/default/myhome, HTTP/1.1, 200, 0.038536 +127.0.0.1, 2018-09-24 16:22:30, GET, /SP/default/task, HTTP/1.1, 200, 0.032320 +127.0.0.1, 2018-09-24 18:43:45, GET, /welcome/static/js/calendar.js, HTTP/1.1, 304, 0.001793 +127.0.0.1, 2018-09-24 18:43:45, GET, /welcome/static/js/web2py.js, HTTP/1.1, 304, 0.004573 +127.0.0.1, 2018-09-24 18:43:45, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.004169 +127.0.0.1, 2018-09-24 18:43:45, GET, /welcome/static/js/jquery.js, HTTP/1.1, 304, 0.003995 +127.0.0.1, 2018-09-24 18:43:46, GET, /, HTTP/1.1, 303, 0.016901 +127.0.0.1, 2018-09-24 18:43:46, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.003949 +127.0.0.1, 2018-09-24 18:43:46, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.004300 +127.0.0.1, 2018-09-24 18:43:46, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.002203 +127.0.0.1, 2018-09-24 18:43:46, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.002248 +127.0.0.1, 2018-09-24 18:43:46, GET, /welcome/static/css/calendar.css, HTTP/1.1, 304, 0.000938 +127.0.0.1, 2018-09-24 18:43:46, GET, /welcome/default/index, HTTP/1.1, 200, 0.155962 +127.0.0.1, 2018-09-24 18:43:50, GET, /, HTTP/1.1, 303, 0.001350 +127.0.0.1, 2018-09-24 18:43:50, GET, /welcome/default/index, HTTP/1.1, 200, 0.037420 +127.0.0.1, 2018-09-24 18:43:50, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.002984 +127.0.0.1, 2018-09-24 18:43:50, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.003712 +127.0.0.1, 2018-09-24 18:43:50, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.002428 +127.0.0.1, 2018-09-24 18:43:50, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.003380 +127.0.0.1, 2018-09-24 18:43:50, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.000350 +127.0.0.1, 2018-09-24 18:43:50, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.005596 +127.0.0.1, 2018-09-24 18:43:50, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.003599 +127.0.0.1, 2018-09-24 18:43:50, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.001811 +127.0.0.1, 2018-09-24 18:43:50, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.002781 +127.0.0.1, 2018-09-24 18:43:50, GET, /SP, HTTP/1.1, 200, 0.107828 +127.0.0.1, 2018-09-24 18:43:51, GET, /SP, HTTP/1.1, 200, 0.050150 +127.0.0.1, 2018-09-24 18:43:56, GET, /SP/static/images/favicon.ico, HTTP/1.1, 304, 0.000979 +127.0.0.1, 2018-09-24 18:43:56, GET, /SP/default/myclass, HTTP/1.1, 200, 0.033700 +127.0.0.1, 2018-09-24 18:43:57, GET, /SP/default/myhome, HTTP/1.1, 303, 0.021905 +127.0.0.1, 2018-09-24 18:43:57, GET, /SP/default/user/login, HTTP/1.1, 200, 0.034310 +127.0.0.1, 2018-09-24 18:44:06, POST, /SP/default/user/login, HTTP/1.1, 303, 0.031835 +127.0.0.1, 2018-09-24 18:44:06, GET, /SP/default/myhome, HTTP/1.1, 200, 0.028052 +127.0.0.1, 2018-09-24 18:44:10, GET, /SP/default/task, HTTP/1.1, 200, 0.040524 +127.0.0.1, 2018-09-24 18:44:14, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.032987 +127.0.0.1, 2018-09-24 18:46:06, GET, /SP/default/task, HTTP/1.1, 200, 0.030604 +127.0.0.1, 2018-09-24 18:46:25, GET, /SP/default/task, HTTP/1.1, 200, 0.027910 +127.0.0.1, 2018-09-24 18:46:31, GET, /SP/default/task, HTTP/1.1, 200, 0.029357 +127.0.0.1, 2018-09-24 22:02:29, GET, /SP/default/task, HTTP/1.1, 404, 0.047343 +127.0.0.1, 2018-09-24 22:02:29, GET, /favicon.ico, HTTP/1.1, 400, 0.000350 +127.0.0.1, 2018-09-24 22:02:30, GET, /SP/default/change_settings, HTTP/1.1, 303, 0.028952 +127.0.0.1, 2018-09-24 22:02:30, GET, /SP/default/user/login, HTTP/1.1, 200, 0.032611 +127.0.0.1, 2018-09-24 22:02:32, GET, /SP/default/myhome, HTTP/1.1, 303, 0.032392 +127.0.0.1, 2018-09-24 22:02:32, GET, /SP/default/user/login, HTTP/1.1, 200, 0.026724 +127.0.0.1, 2018-09-30 18:47:25, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.004231 +127.0.0.1, 2018-09-30 18:47:25, GET, /welcome/static/js/calendar.js, HTTP/1.1, 304, 0.002192 +127.0.0.1, 2018-09-30 18:47:25, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.001449 +127.0.0.1, 2018-09-30 18:47:25, GET, /welcome/static/js/jquery.js, HTTP/1.1, 304, 0.002226 +127.0.0.1, 2018-09-30 18:47:25, GET, /welcome/static/js/web2py.js, HTTP/1.1, 304, 0.001095 +127.0.0.1, 2018-09-30 18:47:25, GET, /welcome/static/css/calendar.css, HTTP/1.1, 304, 0.000734 +127.0.0.1, 2018-09-30 18:47:25, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.004308 +127.0.0.1, 2018-09-30 18:47:25, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.003310 +127.0.0.1, 2018-09-30 18:47:25, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.001141 +127.0.0.1, 2018-09-30 18:47:25, GET, /, HTTP/1.1, 303, 0.023286 +127.0.0.1, 2018-09-30 18:47:26, GET, /welcome/default/index, HTTP/1.1, 200, 0.183711 +127.0.0.1, 2018-09-30 18:47:26, GET, /welcome/static/images/favicon.ico, HTTP/1.1, 304, 0.000627 +127.0.0.1, 2018-09-30 18:47:38, GET, /, HTTP/1.1, 303, 0.000562 +127.0.0.1, 2018-09-30 18:47:38, GET, /welcome/default/index, HTTP/1.1, 200, 0.037970 +127.0.0.1, 2018-09-30 18:47:39, GET, /SP/static/css/calendar.css, HTTP/1.1, 304, 0.000503 +127.0.0.1, 2018-09-30 18:47:39, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.001307 +127.0.0.1, 2018-09-30 18:47:39, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.001714 +127.0.0.1, 2018-09-30 18:47:39, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.005226 +127.0.0.1, 2018-09-30 18:47:39, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.001648 +127.0.0.1, 2018-09-30 18:47:39, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.001884 +127.0.0.1, 2018-09-30 18:47:39, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.001904 +127.0.0.1, 2018-09-30 18:47:39, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.000709 +127.0.0.1, 2018-09-30 18:47:39, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.001719 +127.0.0.1, 2018-09-30 18:47:39, GET, /SP, HTTP/1.1, 200, 0.141522 +127.0.0.1, 2018-09-30 18:47:39, GET, /SP, HTTP/1.1, 200, 0.052358 +127.0.0.1, 2018-09-30 18:47:39, GET, /SP/static/images/favicon.ico, HTTP/1.1, 304, 0.000515 +127.0.0.1, 2018-09-30 18:47:39, GET, /SP/static/images/favicon.png, HTTP/1.1, 200, 0.000881 +127.0.0.1, 2018-09-30 18:47:44, GET, /SP/default/myclass, HTTP/1.1, 200, 0.040536 +127.0.0.1, 2018-09-30 18:47:44, GET, /SP/default/task, HTTP/1.1, 404, 0.022598 +127.0.0.1, 2018-09-30 18:47:47, GET, /SP/default/myhome, HTTP/1.1, 303, 0.022832 +127.0.0.1, 2018-09-30 18:47:47, GET, /SP/default/user/login, HTTP/1.1, 200, 0.034930 +127.0.0.1, 2018-09-30 18:47:48, GET, /SP/default/task, HTTP/1.1, 404, 0.024208 +127.0.0.1, 2018-09-30 18:47:53, GET, /SP/default/task, HTTP/1.1, 404, 0.023996 +127.0.0.1, 2018-09-30 18:48:06, POST, /SP/default/user/login, HTTP/1.1, 303, 0.043544 +127.0.0.1, 2018-09-30 18:48:06, GET, /SP/default/myhome, HTTP/1.1, 200, 0.032209 +127.0.0.1, 2018-09-30 18:48:08, GET, /SP/default/task, HTTP/1.1, 404, 0.020772 +127.0.0.1, 2018-09-30 18:48:44, GET, /SP/default/task, HTTP/1.1, 200, 0.033744 +127.0.0.1, 2018-09-30 18:52:17, GET, /welcome/default/index, HTTP/1.1, 200, 0.031866 +127.0.0.1, 2018-09-30 18:52:17, GET, /welcome/static/images/favicon.png, HTTP/1.1, 200, 0.001216 +127.0.0.1, 2018-09-30 18:52:17, GET, /welcome/default/index, HTTP/1.1, 200, 0.025540 +127.0.0.1, 2018-09-30 18:52:17, GET, /welcome/static/images/favicon.png, HTTP/1.1, 200, 0.000735 +127.0.0.1, 2018-09-30 19:01:41, GET, /SP/default/task, HTTP/1.1, 200, 0.052865 +127.0.0.1, 2018-09-30 19:01:41, GET, /SP/static/images/favicon.png, HTTP/1.1, 200, 0.001919 +127.0.0.1, 2018-09-30 19:01:43, GET, /SP/default/task, HTTP/1.1, 200, 0.032147 +127.0.0.1, 2018-09-30 19:01:45, GET, /SP/default/myhome, HTTP/1.1, 200, 0.040086 +127.0.0.1, 2018-09-30 19:01:46, GET, /SP/default/myhome, HTTP/1.1, 200, 0.028548 +127.0.0.1, 2018-09-30 19:01:47, GET, /SP/default/myclass, HTTP/1.1, 200, 0.030592 +127.0.0.1, 2018-09-30 19:01:48, GET, /SP/default/myhome, HTTP/1.1, 200, 0.031486 +127.0.0.1, 2018-09-30 19:02:04, GET, /SP/appadmin/index, HTTP/1.1, 303, 0.036560 +127.0.0.1, 2018-09-30 19:02:04, GET, /admin/default/index, HTTP/1.1, 200, 0.197535 +127.0.0.1, 2018-09-30 19:02:07, POST, /admin/default/index, HTTP/1.1, 303, 0.010553 +127.0.0.1, 2018-09-30 19:02:07, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.048791 +127.0.0.1, 2018-09-30 19:02:08, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.089984 +127.0.0.1, 2018-09-30 19:02:12, GET, /SP/appadmin/change_task/24, HTTP/1.1, 200, 0.058545 +127.0.0.1, 2018-09-30 19:02:15, POST, /SP/appadmin/change_task/24, HTTP/1.1, 200, 0.067490 +127.0.0.1, 2018-09-30 19:02:18, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.056607 +127.0.0.1, 2018-09-30 19:02:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.182553 +127.0.0.1, 2018-09-30 19:02:18, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.137752 +127.0.0.1, 2018-09-30 19:02:21, GET, /SP/, HTTP/1.1, 200, 0.057284 +127.0.0.1, 2018-09-30 19:02:23, GET, /SP/default/task, HTTP/1.1, 200, 0.036215 +127.0.0.1, 2018-09-30 19:02:26, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.177002 +127.0.0.1, 2018-09-30 19:02:26, GET, /favicon.ico, HTTP/1.1, 400, 0.000207 +127.0.0.1, 2018-09-30 19:02:28, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-02-25.d6a63215-ff4c-4e8d-b71f-0659e31a4c51, HTTP/1.1, 200, 0.074030 +127.0.0.1, 2018-09-30 19:02:28, GET, /favicon.ico, HTTP/1.1, 400, 0.000261 +127.0.0.1, 2018-09-30 19:03:10, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.048897 +127.0.0.1, 2018-09-30 19:03:11, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-03-10.8ae61366-bacc-4809-b5b5-baf0e30a7fe3, HTTP/1.1, 200, 0.036860 +127.0.0.1, 2018-09-30 19:03:11, GET, /favicon.ico, HTTP/1.1, 400, 0.000306 +127.0.0.1, 2018-09-30 19:03:19, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.056890 +127.0.0.1, 2018-09-30 19:03:20, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-03-19.7a82fece-b4ca-4815-a7ce-11eae326b3a6, HTTP/1.1, 200, 0.042636 +127.0.0.1, 2018-09-30 19:03:20, GET, /favicon.ico, HTTP/1.1, 400, 0.000439 +127.0.0.1, 2018-09-30 19:05:05, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.052087 +127.0.0.1, 2018-09-30 19:05:08, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.050828 +127.0.0.1, 2018-09-30 19:05:09, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-05-08.7916431d-3acb-4a7a-a60c-32e78a641411, HTTP/1.1, 200, 0.048603 +127.0.0.1, 2018-09-30 19:05:09, GET, /favicon.ico, HTTP/1.1, 400, 0.000332 +127.0.0.1, 2018-09-30 19:06:08, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-05-08.7916431d-3acb-4a7a-a60c-32e78a641411, HTTP/1.1, 200, 0.038164 +127.0.0.1, 2018-09-30 19:06:10, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.051434 +127.0.0.1, 2018-09-30 19:06:12, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-06-10.4ac1637e-5f02-429d-88d8-578007e1888c, HTTP/1.1, 200, 0.041167 +127.0.0.1, 2018-09-30 19:06:12, GET, /favicon.ico, HTTP/1.1, 400, 0.000264 +127.0.0.1, 2018-09-30 19:06:39, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.068942 +127.0.0.1, 2018-09-30 19:06:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.199283 +127.0.0.1, 2018-09-30 19:06:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072261 +127.0.0.1, 2018-09-30 19:06:47, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.062378 +127.0.0.1, 2018-09-30 19:06:52, GET, /SP/appadmin/insert/m_db/history, HTTP/1.1, 200, 0.056973 +127.0.0.1, 2018-09-30 19:07:00, POST, /SP/appadmin/insert/m_db/history, HTTP/1.1, 200, 0.057592 +127.0.0.1, 2018-09-30 19:07:08, GET, /SP/, HTTP/1.1, 200, 0.048265 +127.0.0.1, 2018-09-30 19:07:13, GET, /SP/private/home, HTTP/1.1, 404, 0.022489 +127.0.0.1, 2018-09-30 19:07:13, GET, /favicon.ico, HTTP/1.1, 400, 0.000354 +127.0.0.1, 2018-09-30 19:07:15, GET, /SP/default/task, HTTP/1.1, 200, 0.032934 +127.0.0.1, 2018-09-30 19:07:16, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.051450 +127.0.0.1, 2018-09-30 19:07:17, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-07-16.553808ae-96e0-4aae-9dcf-e20697568be5, HTTP/1.1, 200, 0.048310 +127.0.0.1, 2018-09-30 19:07:17, GET, /favicon.ico, HTTP/1.1, 400, 0.000205 +127.0.0.1, 2018-09-30 19:08:03, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-07-16.553808ae-96e0-4aae-9dcf-e20697568be5, HTTP/1.1, 200, 0.035833 +127.0.0.1, 2018-09-30 19:08:05, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.098046 +127.0.0.1, 2018-09-30 19:08:07, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-08-05.00e6160b-f867-439d-afee-21f5a2a5fc8e, HTTP/1.1, 200, 0.028978 +127.0.0.1, 2018-09-30 19:08:08, GET, /favicon.ico, HTTP/1.1, 400, 0.000502 +127.0.0.1, 2018-09-30 19:08:40, GET, /SP/default/task, HTTP/1.1, 200, 0.047879 +127.0.0.1, 2018-09-30 19:08:41, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.105458 +127.0.0.1, 2018-09-30 19:08:42, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.062307 +127.0.0.1, 2018-09-30 19:08:42, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072797 +127.0.0.1, 2018-09-30 19:08:45, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.055771 +127.0.0.1, 2018-09-30 19:08:57, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.056114 +127.0.0.1, 2018-09-30 19:08:59, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-08-57.98ec4506-1d72-4711-bd06-e340a7e0c79a, HTTP/1.1, 200, 0.051035 +127.0.0.1, 2018-09-30 19:08:59, GET, /favicon.ico, HTTP/1.1, 400, 0.000210 +127.0.0.1, 2018-09-30 19:09:22, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.055440 +127.0.0.1, 2018-09-30 19:09:34, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.050725 +127.0.0.1, 2018-09-30 19:09:41, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.053721 +127.0.0.1, 2018-09-30 19:10:09, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.060311 +127.0.0.1, 2018-09-30 19:10:10, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-10-09.6bcc0e58-a110-47a4-b9b6-cb7946f4f502, HTTP/1.1, 200, 0.042261 +127.0.0.1, 2018-09-30 19:10:11, GET, /favicon.ico, HTTP/1.1, 400, 0.001119 +127.0.0.1, 2018-09-30 19:13:32, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-10-09.6bcc0e58-a110-47a4-b9b6-cb7946f4f502, HTTP/1.1, 200, 0.053691 +127.0.0.1, 2018-09-30 19:13:41, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.078515 +127.0.0.1, 2018-09-30 19:13:43, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-13-41.476ab4ad-3c08-47ce-9ece-15c067a40fff, HTTP/1.1, 200, 0.040928 +127.0.0.1, 2018-09-30 19:13:43, GET, /favicon.ico, HTTP/1.1, 400, 0.000205 +127.0.0.1, 2018-09-30 19:14:30, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.055197 +127.0.0.1, 2018-09-30 19:14:32, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-14-30.69b37db6-d641-46a7-aa9e-244648ac1286, HTTP/1.1, 200, 0.038211 +127.0.0.1, 2018-09-30 19:14:32, GET, /favicon.ico, HTTP/1.1, 400, 0.000272 +127.0.0.1, 2018-09-30 19:15:40, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.051585 +127.0.0.1, 2018-09-30 19:15:42, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-15-40.c8b163ae-744e-4d7c-a430-61bdc80ebd87, HTTP/1.1, 200, 0.035047 +127.0.0.1, 2018-09-30 19:15:42, GET, /favicon.ico, HTTP/1.1, 400, 0.000502 +127.0.0.1, 2018-09-30 19:15:57, GET, /SP/default/finish_task/24/1, HTTP/1.1, 200, 0.035827 +127.0.0.1, 2018-09-30 19:16:00, GET, /SP/default/myclass, HTTP/1.1, 200, 0.032739 +127.0.0.1, 2018-09-30 19:16:00, GET, /SP/default/myhome, HTTP/1.1, 200, 0.030584 +127.0.0.1, 2018-09-30 19:16:03, GET, /SP/default/task, HTTP/1.1, 200, 0.030105 +127.0.0.1, 2018-09-30 19:16:06, GET, /SP/default/task, HTTP/1.1, 200, 0.032435 +127.0.0.1, 2018-09-30 19:16:37, GET, /SP/default/task, HTTP/1.1, 200, 0.040477 +127.0.0.1, 2018-09-30 19:16:37, GET, /SP/default/finish_task/24/1, HTTP/1.1, 200, 0.037822 +127.0.0.1, 2018-09-30 19:16:39, GET, /SP/default/task, HTTP/1.1, 200, 0.041426 +127.0.0.1, 2018-09-30 19:16:49, GET, /SP/default/task, HTTP/1.1, 500, 0.066789 +127.0.0.1, 2018-09-30 19:16:51, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-16-49.4a4fd7fe-cd96-40c0-8553-ebe34c5adff7, HTTP/1.1, 200, 0.037952 +127.0.0.1, 2018-09-30 19:16:51, GET, /favicon.ico, HTTP/1.1, 400, 0.000379 +127.0.0.1, 2018-09-30 19:18:12, GET, /SP/default/finish_task/24/1, HTTP/1.1, 200, 0.052704 +127.0.0.1, 2018-09-30 19:18:13, GET, /SP/default/task, HTTP/1.1, 200, 0.033534 +127.0.0.1, 2018-09-30 19:18:14, GET, /SP/default/finish_task/24/1, HTTP/1.1, 200, 0.035384 +127.0.0.1, 2018-09-30 19:18:17, GET, /SP/default/task, HTTP/1.1, 200, 0.030494 +127.0.0.1, 2018-09-30 19:18:22, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.121671 +127.0.0.1, 2018-09-30 19:18:22, GET, /favicon.ico, HTTP/1.1, 400, 0.000257 +127.0.0.1, 2018-09-30 19:18:26, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.055107 +127.0.0.1, 2018-09-30 19:18:26, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.167658 +127.0.0.1, 2018-09-30 19:18:26, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.069224 +127.0.0.1, 2018-09-30 19:18:32, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.092605 +127.0.0.1, 2018-09-30 19:18:52, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.054412 +127.0.0.1, 2018-09-30 19:18:52, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.198057 +127.0.0.1, 2018-09-30 19:18:52, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.092483 +127.0.0.1, 2018-09-30 19:18:56, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.046172 +127.0.0.1, 2018-09-30 19:19:05, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.046082 +127.0.0.1, 2018-09-30 19:19:18, POST, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.057164 +127.0.0.1, 2018-09-30 19:19:31, GET, /SP/default/finish_task/24/1, HTTP/1.1, 200, 0.038048 +127.0.0.1, 2018-09-30 19:19:32, GET, /, HTTP/1.1, 303, 0.000412 +127.0.0.1, 2018-09-30 19:19:32, GET, /welcome/default/index, HTTP/1.1, 200, 0.029930 +127.0.0.1, 2018-09-30 19:19:33, GET, /SP/default/task, HTTP/1.1, 200, 0.061332 +127.0.0.1, 2018-09-30 19:19:34, GET, /SP/private/home, HTTP/1.1, 404, 0.022569 +127.0.0.1, 2018-09-30 19:19:34, GET, /favicon.ico, HTTP/1.1, 400, 0.000810 +127.0.0.1, 2018-09-30 19:19:46, POST, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.054142 +127.0.0.1, 2018-09-30 19:19:52, GET, /SP/default/task, HTTP/1.1, 200, 0.030408 +127.0.0.1, 2018-09-30 19:19:53, GET, /SP/default/finish_task/24/1, HTTP/1.1, 200, 0.031677 +127.0.0.1, 2018-09-30 19:19:55, GET, /SP/default/task, HTTP/1.1, 200, 0.050239 +127.0.0.1, 2018-09-30 19:20:04, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.061658 +127.0.0.1, 2018-09-30 19:20:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.179202 +127.0.0.1, 2018-09-30 19:20:04, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.073617 +127.0.0.1, 2018-09-30 19:20:11, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.074322 +127.0.0.1, 2018-09-30 19:20:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.186017 +127.0.0.1, 2018-09-30 19:20:12, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072870 +127.0.0.1, 2018-09-30 19:20:15, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.049577 +127.0.0.1, 2018-09-30 19:21:15, POST, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.050144 +127.0.0.1, 2018-09-30 19:21:21, GET, /SP/default/task, HTTP/1.1, 200, 0.032070 +127.0.0.1, 2018-09-30 19:21:23, GET, /SP/default/finish_task/24/1, HTTP/1.1, 200, 0.040117 +127.0.0.1, 2018-09-30 19:21:29, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.055780 +127.0.0.1, 2018-09-30 19:21:29, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.176936 +127.0.0.1, 2018-09-30 19:21:30, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.103343 +127.0.0.1, 2018-09-30 19:21:35, GET, /SP/appadmin/change_task/24, HTTP/1.1, 200, 0.045908 +127.0.0.1, 2018-09-30 19:21:54, GET, /SP/default/task, HTTP/1.1, 200, 0.063570 +127.0.0.1, 2018-09-30 19:22:28, GET, /SP/default/task, HTTP/1.1, 200, 0.039792 +127.0.0.1, 2018-09-30 19:22:28, GET, /SP/default/task, HTTP/1.1, 200, 0.029207 +127.0.0.1, 2018-09-30 19:22:29, GET, /SP/default/task, HTTP/1.1, 200, 0.032255 +127.0.0.1, 2018-09-30 19:22:29, GET, /SP/default/task, HTTP/1.1, 200, 0.028989 +127.0.0.1, 2018-09-30 19:22:30, GET, /SP/default/myhome, HTTP/1.1, 200, 0.033165 +127.0.0.1, 2018-09-30 19:22:31, GET, /SP/default/task, HTTP/1.1, 200, 0.032791 +127.0.0.1, 2018-09-30 19:22:47, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.059249 +127.0.0.1, 2018-09-30 19:23:21, GET, /SP/default/task, HTTP/1.1, 200, 0.031153 +127.0.0.1, 2018-09-30 19:26:02, GET, /SP/default/task, HTTP/1.1, 200, 0.051855 +127.0.0.1, 2018-09-30 19:26:03, GET, /SP/default/task, HTTP/1.1, 200, 0.032246 +127.0.0.1, 2018-09-30 19:27:31, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.069236 +127.0.0.1, 2018-09-30 19:27:35, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.050902 +127.0.0.1, 2018-09-30 19:27:36, POST, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.061279 +127.0.0.1, 2018-09-30 19:27:40, POST, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.050302 +127.0.0.1, 2018-09-30 19:27:48, GET, /SP/default/task, HTTP/1.1, 200, 0.029889 +127.0.0.1, 2018-09-30 19:27:50, GET, /SP/default/finish_task/24/1, HTTP/1.1, 500, 0.056912 +127.0.0.1, 2018-09-30 19:27:52, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-27-50.a2c2c6c9-43ff-407c-a879-470acd711175, HTTP/1.1, 200, 0.036043 +127.0.0.1, 2018-09-30 19:27:52, GET, /favicon.ico, HTTP/1.1, 400, 0.000231 +127.0.0.1, 2018-09-30 19:29:04, GET, /SP/default/finish_task/24/1, HTTP/1.1, 200, 0.039135 +127.0.0.1, 2018-09-30 19:29:05, GET, /SP/default/task, HTTP/1.1, 200, 0.039117 +127.0.0.1, 2018-09-30 19:31:42, GET, /SP/default/task, HTTP/1.1, 200, 0.050759 +127.0.0.1, 2018-09-30 19:32:39, GET, /SP/default/task, HTTP/1.1, 200, 0.031097 +127.0.0.1, 2018-09-30 19:32:40, GET, /SP/default/task, HTTP/1.1, 200, 0.033968 +127.0.0.1, 2018-09-30 19:33:37, GET, /SP/default/task, HTTP/1.1, 200, 0.041401 +127.0.0.1, 2018-09-30 19:35:53, GET, /SP/default/task, HTTP/1.1, 200, 0.032833 +127.0.0.1, 2018-09-30 19:35:55, GET, /SP/default/task, HTTP/1.1, 200, 0.036125 +127.0.0.1, 2018-09-30 19:35:59, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.057766 +127.0.0.1, 2018-09-30 19:35:59, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.176209 +127.0.0.1, 2018-09-30 19:35:59, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.078838 +127.0.0.1, 2018-09-30 19:36:03, GET, /SP/appadmin/add_relation/4, HTTP/1.1, 200, 0.062685 +127.0.0.1, 2018-09-30 19:36:09, POST, /SP/appadmin/add_relation/4, HTTP/1.1, 200, 0.053527 +127.0.0.1, 2018-09-30 19:36:16, GET, /SP/, HTTP/1.1, 200, 0.042848 +127.0.0.1, 2018-09-30 19:36:16, GET, /SP/, HTTP/1.1, 200, 0.059445 +127.0.0.1, 2018-09-30 19:36:18, GET, /SP/default/task, HTTP/1.1, 200, 0.038555 +127.0.0.1, 2018-09-30 19:36:22, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.054615 +127.0.0.1, 2018-09-30 19:36:22, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.170636 +127.0.0.1, 2018-09-30 19:36:22, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.078556 +127.0.0.1, 2018-09-30 19:36:34, GET, /SP/default/task, HTTP/1.1, 200, 0.038588 +127.0.0.1, 2018-09-30 19:37:54, GET, /SP/default/task, HTTP/1.1, 200, 0.046250 +127.0.0.1, 2018-09-30 19:37:56, GET, /SP/default/finish_task/24/1, HTTP/1.1, 200, 0.031947 +127.0.0.1, 2018-09-30 19:38:00, GET, /SP/default/task, HTTP/1.1, 200, 0.043074 +127.0.0.1, 2018-09-30 19:38:01, GET, /SP/default/task, HTTP/1.1, 200, 0.035671 +127.0.0.1, 2018-09-30 19:38:02, GET, /SP/default/task, HTTP/1.1, 200, 0.033772 +127.0.0.1, 2018-09-30 19:38:03, GET, /SP/default/task, HTTP/1.1, 200, 0.030769 +127.0.0.1, 2018-09-30 19:38:04, GET, /SP/default/finish_task/24/1, HTTP/1.1, 200, 0.035388 +127.0.0.1, 2018-09-30 19:38:07, GET, /SP/default/task, HTTP/1.1, 200, 0.030412 +127.0.0.1, 2018-09-30 19:40:33, GET, /SP/default/task, HTTP/1.1, 200, 0.036188 +127.0.0.1, 2018-09-30 19:40:35, GET, /SP/default/montiorctl/24, HTTP/1.1, 404, 0.021616 +127.0.0.1, 2018-09-30 19:40:35, GET, /favicon.ico, HTTP/1.1, 400, 0.000440 +127.0.0.1, 2018-09-30 19:40:52, GET, /SP/default/montiorctl/24, HTTP/1.1, 404, 0.032219 +127.0.0.1, 2018-09-30 19:40:54, GET, /SP/default/montiorctl/24, HTTP/1.1, 404, 0.027458 +127.0.0.1, 2018-09-30 19:40:59, GET, /SP/default/task, HTTP/1.1, 200, 0.036394 +127.0.0.1, 2018-09-30 19:41:00, GET, /SP/default/montiorctl/24, HTTP/1.1, 404, 0.024874 +127.0.0.1, 2018-09-30 19:42:41, GET, /SP/default/task, HTTP/1.1, 500, 0.069431 +127.0.0.1, 2018-09-30 19:42:59, GET, /SP/default/task, HTTP/1.1, 200, 0.036866 +127.0.0.1, 2018-09-30 19:43:01, GET, /SP/default/monitorctl/24, HTTP/1.1, 200, 0.035328 +127.0.0.1, 2018-09-30 19:43:28, GET, /SP/default/myhome, HTTP/1.1, 200, 0.034131 +127.0.0.1, 2018-09-30 19:43:29, GET, /SP/default/change_settings, HTTP/1.1, 200, 0.037564 +127.0.0.1, 2018-09-30 19:43:32, GET, /SP/default/task, HTTP/1.1, 200, 0.038188 +127.0.0.1, 2018-09-30 19:43:33, GET, /SP/default/monitorctl/24, HTTP/1.1, 500, 0.120482 +127.0.0.1, 2018-09-30 19:43:33, GET, /favicon.ico, HTTP/1.1, 400, 0.000321 +127.0.0.1, 2018-09-30 19:43:35, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-43-33.3f9c933e-96cb-487b-9057-731ef99df91d, HTTP/1.1, 200, 0.075523 +127.0.0.1, 2018-09-30 19:43:35, GET, /favicon.ico, HTTP/1.1, 400, 0.000351 +127.0.0.1, 2018-09-30 19:45:18, GET, /SP/default/monitorctl/24, HTTP/1.1, 200, 0.034761 +127.0.0.1, 2018-09-30 19:53:29, GET, /SP/default/monitorctl/24, HTTP/1.1, 500, 0.068083 +127.0.0.1, 2018-09-30 19:53:36, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-53-29.38843298-d223-4ae2-957e-6bd410bbaaa4, HTTP/1.1, 200, 0.033204 +127.0.0.1, 2018-09-30 19:53:36, GET, /favicon.ico, HTTP/1.1, 400, 0.000333 +127.0.0.1, 2018-09-30 19:53:56, GET, /SP/default/monitorctl/24, HTTP/1.1, 200, 0.049116 +127.0.0.1, 2018-09-30 19:55:07, GET, /SP/default/monitorctl/24, HTTP/1.1, 200, 0.055767 +127.0.0.1, 2018-09-30 19:58:56, GET, /SP/default/monitorctl/24, HTTP/1.1, 500, 0.083710 +127.0.0.1, 2018-09-30 19:58:58, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.19-58-56.60d0f3ea-7fbb-4b9a-90fe-751f620d8048, HTTP/1.1, 200, 0.030933 +127.0.0.1, 2018-09-30 19:58:58, GET, /favicon.ico, HTTP/1.1, 400, 0.000311 +127.0.0.1, 2018-09-30 19:59:14, GET, /SP/default/monitorctl/24, HTTP/1.1, 200, 0.034985 +127.0.0.1, 2018-09-30 20:00:19, GET, /SP/default/monitorctl/24, HTTP/1.1, 200, 0.032568 +127.0.0.1, 2018-09-30 20:00:45, GET, /SP/default/monitorctl/24, HTTP/1.1, 200, 0.033882 +127.0.0.1, 2018-09-30 20:00:58, GET, /SP/default/finish_task/24/2, HTTP/1.1, 200, 0.037261 +127.0.0.1, 2018-09-30 20:01:02, GET, /SP/default/monitorctl/24, HTTP/1.1, 200, 0.033285 +127.0.0.1, 2018-09-30 20:01:04, GET, /SP/default/monitorctl/24, HTTP/1.1, 200, 0.031976 +127.0.0.1, 2018-09-30 20:01:06, GET, /SP/default/monitorctl/24, HTTP/1.1, 200, 0.044625 +127.0.0.1, 2018-09-30 20:01:08, GET, /SP/default/task, HTTP/1.1, 200, 0.041159 +127.0.0.1, 2018-09-30 20:01:10, GET, /SP/default/monitorctl/24, HTTP/1.1, 200, 0.037262 +127.0.0.1, 2018-09-30 20:01:38, GET, /SP/default/monitorctl/24, HTTP/1.1, 200, 0.032321 +127.0.0.1, 2018-09-30 20:02:59, GET, /SP/default/monitorctl/24, HTTP/1.1, 500, 0.076924 +127.0.0.1, 2018-09-30 20:03:16, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-02-59.39add73b-deca-4b57-b448-9aeba108bb41, HTTP/1.1, 200, 0.064824 +127.0.0.1, 2018-09-30 20:03:16, GET, /favicon.ico, HTTP/1.1, 400, 0.000324 +127.0.0.1, 2018-09-30 20:04:28, GET, /SP/default/, HTTP/1.1, 200, 0.049709 +127.0.0.1, 2018-09-30 20:04:29, GET, /SP/default/task, HTTP/1.1, 200, 0.036169 +127.0.0.1, 2018-09-30 20:04:31, GET, /SP/default/monitorctl/24, HTTP/1.1, 500, 0.064259 +127.0.0.1, 2018-09-30 20:04:39, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.067820 +127.0.0.1, 2018-09-30 20:04:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.180959 +127.0.0.1, 2018-09-30 20:04:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.088957 +127.0.0.1, 2018-09-30 20:04:47, GET, /SP/appadmin/change_task/24, HTTP/1.1, 200, 0.055759 +127.0.0.1, 2018-09-30 20:04:52, POST, /SP/appadmin/change_task/24, HTTP/1.1, 200, 0.057044 +127.0.0.1, 2018-09-30 20:04:57, GET, /SP/, HTTP/1.1, 200, 0.040068 +127.0.0.1, 2018-09-30 20:04:58, GET, /favicon.ico, HTTP/1.1, 400, 0.000223 +127.0.0.1, 2018-09-30 20:04:59, GET, /SP/private/home, HTTP/1.1, 404, 0.030617 +127.0.0.1, 2018-09-30 20:05:01, GET, /SP/default/task, HTTP/1.1, 200, 0.031583 +127.0.0.1, 2018-09-30 20:05:02, GET, /SP/default/monitorctl/24, HTTP/1.1, 500, 0.060300 +127.0.0.1, 2018-09-30 20:05:03, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-05-02.fa395f45-73e8-4ca2-8e4c-48209c73d459, HTTP/1.1, 200, 0.066346 +127.0.0.1, 2018-09-30 20:05:03, GET, /favicon.ico, HTTP/1.1, 400, 0.000693 +127.0.0.1, 2018-09-30 20:05:35, GET, /, HTTP/1.1, 303, 0.000719 +127.0.0.1, 2018-09-30 20:05:35, GET, /welcome/default/index, HTTP/1.1, 200, 0.027210 +127.0.0.1, 2018-09-30 20:05:38, GET, /SP, HTTP/1.1, 200, 0.033539 +127.0.0.1, 2018-09-30 20:05:40, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.056814 +127.0.0.1, 2018-09-30 20:05:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.165502 +127.0.0.1, 2018-09-30 20:05:40, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.068558 +127.0.0.1, 2018-09-30 20:05:43, GET, /SP/appadmin/change_task/24, HTTP/1.1, 200, 0.049773 +127.0.0.1, 2018-09-30 20:05:49, GET, /SP/appadmin/delete_task/24, HTTP/1.1, 303, 0.035128 +127.0.0.1, 2018-09-30 20:05:49, GET, /SP/appadmin/, HTTP/1.1, 200, 0.048695 +127.0.0.1, 2018-09-30 20:05:50, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.074960 +127.0.0.1, 2018-09-30 20:05:53, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.122308 +127.0.0.1, 2018-09-30 20:06:04, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.056352 +127.0.0.1, 2018-09-30 20:06:12, GET, /SP/default/, HTTP/1.1, 200, 0.043417 +127.0.0.1, 2018-09-30 20:06:12, GET, /SP/default/, HTTP/1.1, 200, 0.063878 +127.0.0.1, 2018-09-30 20:06:13, GET, /SP/default/task, HTTP/1.1, 200, 0.035046 +127.0.0.1, 2018-09-30 20:06:15, GET, /SP/default/monitorctl/25, HTTP/1.1, 500, 0.065915 +127.0.0.1, 2018-09-30 20:06:15, GET, /favicon.ico, HTTP/1.1, 400, 0.000231 +127.0.0.1, 2018-09-30 20:06:17, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-06-15.77652992-fce3-4e80-945b-c735eb163038, HTTP/1.1, 200, 0.072337 +127.0.0.1, 2018-09-30 20:06:17, GET, /favicon.ico, HTTP/1.1, 400, 0.000586 +127.0.0.1, 2018-09-30 20:07:12, GET, /SP/default/monitorctl/25, HTTP/1.1, 500, 0.070319 +127.0.0.1, 2018-09-30 20:07:14, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-07-12.132807a5-f507-428f-8605-fbd5fbcdfbec, HTTP/1.1, 200, 0.071016 +127.0.0.1, 2018-09-30 20:07:14, GET, /favicon.ico, HTTP/1.1, 400, 0.000347 +127.0.0.1, 2018-09-30 20:09:00, GET, /admin/default/index, HTTP/1.1, 303, 0.009586 +127.0.0.1, 2018-09-30 20:09:01, GET, /admin/default/site, HTTP/1.1, 200, 0.057491 +127.0.0.1, 2018-09-30 20:09:01, GET, /favicon.ico, HTTP/1.1, 400, 0.000232 +127.0.0.1, 2018-09-30 20:09:01, POST, /admin/default/check_version, HTTP/1.1, 200, 0.766486 +127.0.0.1, 2018-09-30 20:09:05, GET, /SP/default/task, HTTP/1.1, 200, 0.049888 +127.0.0.1, 2018-09-30 20:09:13, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.058687 +127.0.0.1, 2018-09-30 20:09:13, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.193030 +127.0.0.1, 2018-09-30 20:09:13, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.078585 +127.0.0.1, 2018-09-30 20:09:17, GET, /SP/appadmin/change_task/25, HTTP/1.1, 200, 0.087160 +127.0.0.1, 2018-09-30 20:09:22, POST, /SP/appadmin/change_task/25, HTTP/1.1, 200, 0.060371 +127.0.0.1, 2018-09-30 20:09:24, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070505 +127.0.0.1, 2018-09-30 20:09:24, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.121613 +127.0.0.1, 2018-09-30 20:09:24, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.074631 +127.0.0.1, 2018-09-30 20:09:28, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.057063 +127.0.0.1, 2018-09-30 20:09:28, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.070414 +127.0.0.1, 2018-09-30 20:09:28, GET, /SP/default/task, HTTP/1.1, 500, 0.065018 +127.0.0.1, 2018-09-30 20:09:29, GET, /SP/default/, HTTP/1.1, 200, 0.043347 +127.0.0.1, 2018-09-30 20:09:31, GET, /SP/default/task, HTTP/1.1, 500, 0.059521 +127.0.0.1, 2018-09-30 20:09:32, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-09-31.953fa082-038a-4d3d-9991-e2244f844fd8, HTTP/1.1, 200, 0.067358 +127.0.0.1, 2018-09-30 20:09:32, GET, /favicon.ico, HTTP/1.1, 400, 0.006533 +127.0.0.1, 2018-09-30 20:10:41, GET, /SP/default/task, HTTP/1.1, 200, 0.036947 +127.0.0.1, 2018-09-30 20:10:43, GET, /SP/default/monitorctl/25, HTTP/1.1, 500, 0.065210 +127.0.0.1, 2018-09-30 20:10:45, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-10-43.f904246c-b69a-4c66-a870-bae6abc2eefc, HTTP/1.1, 200, 0.058885 +127.0.0.1, 2018-09-30 20:10:46, GET, /favicon.ico, HTTP/1.1, 400, 0.000354 +127.0.0.1, 2018-09-30 20:12:34, GET, /SP/default/monitorctl/25, HTTP/1.1, 500, 0.077355 +127.0.0.1, 2018-09-30 20:12:35, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-12-33.f82834a1-af69-409c-b737-c8c4945ecc19, HTTP/1.1, 200, 0.064475 +127.0.0.1, 2018-09-30 20:12:35, GET, /favicon.ico, HTTP/1.1, 400, 0.000314 +127.0.0.1, 2018-09-30 20:12:46, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-12-33.f82834a1-af69-409c-b737-c8c4945ecc19, HTTP/1.1, 200, 0.074479 +127.0.0.1, 2018-09-30 20:12:50, GET, /SP/default/monitorctl/25, HTTP/1.1, 500, 0.062464 +127.0.0.1, 2018-09-30 20:12:52, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-12-49.00ad86af-27cb-406f-8205-b6c4888e0488, HTTP/1.1, 200, 0.059762 +127.0.0.1, 2018-09-30 20:12:52, GET, /favicon.ico, HTTP/1.1, 400, 0.000376 +127.0.0.1, 2018-09-30 20:13:21, GET, /SP/default/task, HTTP/1.1, 200, 0.030719 +127.0.0.1, 2018-09-30 20:13:22, GET, /SP/default/monitorctl/25, HTTP/1.1, 500, 0.064351 +127.0.0.1, 2018-09-30 20:13:24, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-13-22.93478285-44ba-461a-b0f2-82323013df66, HTTP/1.1, 200, 0.061656 +127.0.0.1, 2018-09-30 20:13:24, GET, /favicon.ico, HTTP/1.1, 400, 0.000440 +127.0.0.1, 2018-09-30 20:14:29, GET, /SP/default/monitorctl/25, HTTP/1.1, 500, 0.062768 +127.0.0.1, 2018-09-30 20:14:31, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-14-29.d2c0dc37-32a3-4f4e-ae26-ac6e1a57f559, HTTP/1.1, 200, 0.028977 +127.0.0.1, 2018-09-30 20:14:31, GET, /favicon.ico, HTTP/1.1, 400, 0.000336 +127.0.0.1, 2018-09-30 20:14:46, GET, /SP/default/monitorctl/25, HTTP/1.1, 200, 0.041728 +127.0.0.1, 2018-09-30 20:14:48, GET, /SP/default/finish_task/25/1, HTTP/1.1, 200, 0.035032 +127.0.0.1, 2018-09-30 20:14:50, GET, /SP/default/finish_task/25/2, HTTP/1.1, 200, 0.041767 +127.0.0.1, 2018-09-30 20:14:54, GET, /SP/default/index, HTTP/1.1, 200, 0.031281 +127.0.0.1, 2018-09-30 20:14:56, GET, /SP/default/task, HTTP/1.1, 200, 0.029758 +127.0.0.1, 2018-09-30 20:14:56, GET, /SP/default/myclass, HTTP/1.1, 200, 0.041293 +127.0.0.1, 2018-09-30 20:14:57, GET, /SP/private/home, HTTP/1.1, 404, 0.023155 +127.0.0.1, 2018-09-30 20:14:57, GET, /favicon.ico, HTTP/1.1, 400, 0.000318 +127.0.0.1, 2018-09-30 20:14:59, GET, /SP/default/task, HTTP/1.1, 200, 0.036376 +127.0.0.1, 2018-09-30 20:15:01, GET, /SP/default/monitorctl/25, HTTP/1.1, 200, 0.036495 +127.0.0.1, 2018-09-30 20:15:33, GET, /SP, HTTP/1.1, 200, 0.027859 +127.0.0.1, 2018-09-30 20:15:34, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.053950 +127.0.0.1, 2018-09-30 20:15:34, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.163772 +127.0.0.1, 2018-09-30 20:15:34, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.139830 +127.0.0.1, 2018-09-30 20:15:34, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.077035 +127.0.0.1, 2018-09-30 20:15:41, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.055652 +127.0.0.1, 2018-09-30 20:15:52, POST, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.055000 +127.0.0.1, 2018-09-30 20:15:57, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.051974 +127.0.0.1, 2018-09-30 20:16:06, GET, /SP/default/monitorctl/25, HTTP/1.1, 200, 0.034613 +127.0.0.1, 2018-09-30 20:16:07, GET, /SP/default/finish_task/25/1, HTTP/1.1, 200, 0.035699 +127.0.0.1, 2018-09-30 20:16:10, GET, /favicon.ico, HTTP/1.1, 400, 0.000204 +127.0.0.1, 2018-09-30 20:16:10, GET, /SP/private/home, HTTP/1.1, 404, 0.024859 +127.0.0.1, 2018-09-30 20:16:13, GET, /SP/default/task, HTTP/1.1, 200, 0.033708 +127.0.0.1, 2018-09-30 20:16:15, GET, /SP/default/monitorctl/25, HTTP/1.1, 200, 0.037443 +127.0.0.1, 2018-09-30 20:19:53, GET, /SP/default/monitorctl/25, HTTP/1.1, 200, 0.056930 +127.0.0.1, 2018-09-30 20:19:55, GET, /SP/default/finish_task/25/2/monitor, HTTP/1.1, 500, 0.066333 +127.0.0.1, 2018-09-30 20:19:55, GET, /favicon.ico, HTTP/1.1, 400, 0.000213 +127.0.0.1, 2018-09-30 20:19:57, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-19-55.dc2245da-3bc3-4942-a146-6e8e0881cd6f, HTTP/1.1, 200, 0.037681 +127.0.0.1, 2018-09-30 20:19:57, GET, /favicon.ico, HTTP/1.1, 400, 0.000207 +127.0.0.1, 2018-09-30 20:20:19, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-19-55.dc2245da-3bc3-4942-a146-6e8e0881cd6f, HTTP/1.1, 200, 0.032429 +127.0.0.1, 2018-09-30 20:20:21, GET, /SP/default/finish_task/25/2/monitor, HTTP/1.1, 500, 0.066578 +127.0.0.1, 2018-09-30 20:20:23, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-20-21.ad008041-2415-4d80-844f-3877e2b95366, HTTP/1.1, 200, 0.038541 +127.0.0.1, 2018-09-30 20:20:24, GET, /favicon.ico, HTTP/1.1, 400, 0.000289 +127.0.0.1, 2018-09-30 20:20:45, GET, /SP/default/finish_task/25/2/monitor, HTTP/1.1, 500, 0.063822 +127.0.0.1, 2018-09-30 20:20:46, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-20-45.98aaf16b-b5b2-46ce-a976-183c7c2db441, HTTP/1.1, 200, 0.044917 +127.0.0.1, 2018-09-30 20:20:47, GET, /favicon.ico, HTTP/1.1, 400, 0.000339 +127.0.0.1, 2018-09-30 20:23:20, GET, /SP/default/finish_task/25/2/monitor, HTTP/1.1, 303, 0.045867 +127.0.0.1, 2018-09-30 20:23:20, GET, /SP/default/SP/default/montiorctl/25, HTTP/1.1, 404, 0.023569 +127.0.0.1, 2018-09-30 20:23:20, GET, /favicon.ico, HTTP/1.1, 400, 0.000211 +127.0.0.1, 2018-09-30 20:23:33, GET, /SP/default/SP/default/montiorctl/25, HTTP/1.1, 404, 0.023880 +127.0.0.1, 2018-09-30 20:23:38, GET, /SP/default, HTTP/1.1, 200, 0.041128 +127.0.0.1, 2018-09-30 20:23:40, GET, /SP/default/task, HTTP/1.1, 200, 0.038556 +127.0.0.1, 2018-09-30 20:23:48, GET, /SP/default/monitorctl/25, HTTP/1.1, 200, 0.035742 +127.0.0.1, 2018-09-30 20:23:56, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.057941 +127.0.0.1, 2018-09-30 20:23:56, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.188940 +127.0.0.1, 2018-09-30 20:23:56, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.100996 +127.0.0.1, 2018-09-30 20:23:58, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.057970 +127.0.0.1, 2018-09-30 20:24:08, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.056276 +127.0.0.1, 2018-09-30 20:24:13, GET, /SP/, HTTP/1.1, 200, 0.037675 +127.0.0.1, 2018-09-30 20:24:13, GET, /SP/, HTTP/1.1, 200, 0.059125 +127.0.0.1, 2018-09-30 20:24:15, GET, /SP/default/task, HTTP/1.1, 200, 0.033841 +127.0.0.1, 2018-09-30 20:24:32, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.031614 +127.0.0.1, 2018-09-30 20:24:34, GET, /SP/default/finish_task/26/1/monitor, HTTP/1.1, 303, 0.033870 +127.0.0.1, 2018-09-30 20:24:34, GET, /SP/default/montiorctl/26, HTTP/1.1, 404, 0.021831 +127.0.0.1, 2018-09-30 20:24:34, GET, /favicon.ico, HTTP/1.1, 400, 0.000211 +127.0.0.1, 2018-09-30 20:24:55, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.044074 +127.0.0.1, 2018-09-30 20:24:56, GET, /SP/default/finish_task/26/1/monitor, HTTP/1.1, 303, 0.023490 +127.0.0.1, 2018-09-30 20:24:56, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.033372 +127.0.0.1, 2018-09-30 20:25:02, GET, /SP/default/finish_task/26/2/monitor, HTTP/1.1, 303, 0.023059 +127.0.0.1, 2018-09-30 20:25:02, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.030566 +127.0.0.1, 2018-09-30 20:25:04, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.036534 +127.0.0.1, 2018-09-30 20:25:06, GET, /SP/default/task, HTTP/1.1, 200, 0.032047 +127.0.0.1, 2018-09-30 20:25:08, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.042839 +127.0.0.1, 2018-09-30 20:25:27, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.057728 +127.0.0.1, 2018-09-30 20:25:27, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.188291 +127.0.0.1, 2018-09-30 20:25:27, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.069922 +127.0.0.1, 2018-09-30 20:25:34, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.055942 +127.0.0.1, 2018-09-30 20:25:46, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.044385 +127.0.0.1, 2018-09-30 20:25:47, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.033166 +127.0.0.1, 2018-09-30 20:25:49, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.032136 +127.0.0.1, 2018-09-30 20:25:51, GET, /SP/default/finish_task/26/1/monitor, HTTP/1.1, 303, 0.027294 +127.0.0.1, 2018-09-30 20:25:51, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.028932 +127.0.0.1, 2018-09-30 20:26:13, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.040357 +127.0.0.1, 2018-09-30 20:26:15, GET, /SP/default/finish_task/26/1/monitor, HTTP/1.1, 303, 0.023862 +127.0.0.1, 2018-09-30 20:26:15, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.031364 +127.0.0.1, 2018-09-30 20:26:24, GET, /SP/default/finish_task/26/1/monitor, HTTP/1.1, 303, 0.085472 +127.0.0.1, 2018-09-30 20:26:24, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.029260 +127.0.0.1, 2018-09-30 20:26:36, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.041293 +127.0.0.1, 2018-09-30 20:26:37, GET, /SP/default/finish_task/26/1/monitor, HTTP/1.1, 303, 0.024822 +127.0.0.1, 2018-09-30 20:26:37, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.029030 +127.0.0.1, 2018-09-30 20:26:50, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.109794 +127.0.0.1, 2018-09-30 20:26:52, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.070979 +127.0.0.1, 2018-09-30 20:26:53, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.193055 +127.0.0.1, 2018-09-30 20:26:53, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.076414 +127.0.0.1, 2018-09-30 20:26:58, GET, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.048380 +127.0.0.1, 2018-09-30 20:27:02, POST, /SP/appadmin/select/m_db, HTTP/1.1, 200, 0.051419 +127.0.0.1, 2018-09-30 20:27:47, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.033409 +127.0.0.1, 2018-09-30 20:27:48, GET, /SP/default/finish_task/26/1/monitor, HTTP/1.1, 303, 0.023398 +127.0.0.1, 2018-09-30 20:27:48, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.031863 +127.0.0.1, 2018-09-30 20:28:01, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.033776 +127.0.0.1, 2018-09-30 20:28:03, GET, /SP/default/finish_task/26/1/monitor, HTTP/1.1, 303, 0.031132 +127.0.0.1, 2018-09-30 20:28:03, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.028015 +127.0.0.1, 2018-09-30 20:28:13, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.059506 +127.0.0.1, 2018-09-30 20:28:13, GET, /SP/default/monitorctl/25, HTTP/1.1, 200, 0.037161 +127.0.0.1, 2018-09-30 20:28:16, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.033062 +127.0.0.1, 2018-09-30 20:28:17, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.036392 +127.0.0.1, 2018-09-30 20:28:42, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.039562 +127.0.0.1, 2018-09-30 20:28:44, GET, /SP/default/finish_task/26/1/monitor, HTTP/1.1, 303, 0.023751 +127.0.0.1, 2018-09-30 20:28:44, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.031201 +127.0.0.1, 2018-09-30 20:29:37, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.045509 +127.0.0.1, 2018-09-30 20:29:38, GET, /SP/default/finish_task/26/1/monitor, HTTP/1.1, 303, 0.024843 +127.0.0.1, 2018-09-30 20:29:38, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.032273 +127.0.0.1, 2018-09-30 20:33:52, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.054215 +127.0.0.1, 2018-09-30 20:33:54, GET, /SP/default/finish_task/26/1/monitor, HTTP/1.1, 500, 0.056481 +127.0.0.1, 2018-09-30 20:33:54, GET, /favicon.ico, HTTP/1.1, 400, 0.000209 +127.0.0.1, 2018-09-30 20:33:56, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-33-54.f26cedfa-f99e-4e59-89fc-d9f540d46be6, HTTP/1.1, 200, 0.032544 +127.0.0.1, 2018-09-30 20:33:56, GET, /favicon.ico, HTTP/1.1, 400, 0.000207 +127.0.0.1, 2018-09-30 20:34:43, GET, /favicon.ico, HTTP/1.1, 400, 0.000349 +127.0.0.1, 2018-09-30 20:34:43, GET, /SP/default/finish_task/26/1/monitor, HTTP/1.1, 500, 0.068746 +127.0.0.1, 2018-09-30 20:34:44, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-34-43.ab9f45de-b3cf-4f84-968e-db929cbf8d4f, HTTP/1.1, 200, 0.036963 +127.0.0.1, 2018-09-30 20:34:45, GET, /favicon.ico, HTTP/1.1, 400, 0.001209 +127.0.0.1, 2018-09-30 20:35:10, GET, /favicon.ico, HTTP/1.1, 400, 0.000334 +127.0.0.1, 2018-09-30 20:35:10, GET, /SP/default/finish_task/26/1/monitor, HTTP/1.1, 500, 0.060393 +127.0.0.1, 2018-09-30 20:35:38, GET, /favicon.ico, HTTP/1.1, 400, 0.000202 +127.0.0.1, 2018-09-30 20:35:38, GET, /SP/default/finish_task/26/1/monitor, HTTP/1.1, 500, 0.060884 +127.0.0.1, 2018-09-30 20:35:39, GET, /admin/default/ticket/SP/127.0.0.1.2018-09-30.20-35-38.6031b2a4-afbd-4526-9954-b90f5726a2b3, HTTP/1.1, 200, 0.049950 +127.0.0.1, 2018-09-30 20:35:39, GET, /favicon.ico, HTTP/1.1, 400, 0.000211 +127.0.0.1, 2018-09-30 20:36:03, GET, /favicon.ico, HTTP/1.1, 400, 0.000213 +127.0.0.1, 2018-09-30 20:36:03, GET, /SP/default/finish_task/26/1/monitor, HTTP/1.1, 303, 0.036802 +127.0.0.1, 2018-09-30 20:36:03, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.033963 +127.0.0.1, 2018-09-30 20:36:05, GET, /SP/default/finish_task/26/2/monitor, HTTP/1.1, 303, 0.026837 +127.0.0.1, 2018-09-30 20:36:05, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.033390 +127.0.0.1, 2018-09-30 20:36:21, GET, /SP/default/monitorctl/26, HTTP/1.1, 200, 0.037167 +127.0.0.1, 2018-09-30 20:36:25, GET, /SP/default/task, HTTP/1.1, 200, 0.053372 +127.0.0.1, 2018-09-30 20:36:59, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.067453 +127.0.0.1, 2018-09-30 20:37:00, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.244458 +127.0.0.1, 2018-09-30 20:37:00, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.196092 +127.0.0.1, 2018-09-30 20:37:19, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.068558 +127.0.0.1, 2018-09-30 20:37:19, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.179303 +127.0.0.1, 2018-09-30 20:37:20, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.084061 +127.0.0.1, 2018-09-30 20:37:23, GET, /SP/appadmin/delete_task/25, HTTP/1.1, 303, 0.028626 +127.0.0.1, 2018-09-30 20:37:23, GET, /SP/appadmin/, HTTP/1.1, 200, 0.052073 +127.0.0.1, 2018-09-30 20:37:23, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.086949 +127.0.0.1, 2018-09-30 20:37:26, GET, /SP/appadmin/delete_task/26, HTTP/1.1, 303, 0.026003 +127.0.0.1, 2018-09-30 20:37:26, GET, /SP/appadmin/, HTTP/1.1, 200, 0.049715 +127.0.0.1, 2018-09-30 20:37:26, GET, /SP/appadmin/hooks, HTTP/1.1, 200, 0.072794 +127.0.0.1, 2018-09-30 20:37:27, GET, /SP/appadmin/add_userinfo, HTTP/1.1, 200, 0.056678 +127.0.0.1, 2018-09-30 20:37:37, GET, /SP/appadmin/add_task, HTTP/1.1, 200, 0.046767 +127.0.0.1, 2018-09-30 20:38:22, POST, /SP/appadmin/add_task, HTTP/1.1, 200, 0.071551 +127.0.0.1, 2018-09-30 20:38:30, GET, /, HTTP/1.1, 303, 0.000695 +127.0.0.1, 2018-09-30 20:38:30, GET, /welcome/default/index, HTTP/1.1, 200, 0.028588 +127.0.0.1, 2018-09-30 20:38:31, GET, /SP, HTTP/1.1, 200, 0.043270 +127.0.0.1, 2018-09-30 20:38:32, GET, /SP, HTTP/1.1, 200, 0.048474 +127.0.0.1, 2018-09-30 20:38:33, GET, /SP/default/task, HTTP/1.1, 200, 0.041198 +127.0.0.1, 2018-09-30 20:38:37, GET, /SP/default/finish_task/27/1, HTTP/1.1, 303, 0.027735 +127.0.0.1, 2018-09-30 20:38:37, GET, /SP/default/task, HTTP/1.1, 200, 0.032362 +127.0.0.1, 2018-09-30 20:38:49, GET, /SP/default/monitorctl/27, HTTP/1.1, 200, 0.030366 +127.0.0.1, 2018-09-30 20:38:55, GET, /SP/default/finish_task/27/2/monitor, HTTP/1.1, 303, 0.034636 +127.0.0.1, 2018-09-30 20:38:55, GET, /SP/default/monitorctl/27, HTTP/1.1, 200, 0.031259 +127.0.0.1, 2018-09-30 20:39:52, GET, /SP/default/monitorctl/27, HTTP/1.1, 200, 0.032895 +127.0.0.1, 2018-09-30 20:39:58, GET, /SP/default/myhome, HTTP/1.1, 200, 0.030025 +127.0.0.1, 2018-09-30 20:40:00, GET, /SP/default/task, HTTP/1.1, 200, 0.034452 +127.0.0.1, 2018-09-30 20:40:11, GET, /SP/default/monitorctl/27, HTTP/1.1, 200, 0.031695 +127.0.0.1, 2018-09-30 20:46:18, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.105706 +127.0.0.1, 2018-09-30 20:46:22, GET, /SP, HTTP/1.1, 200, 0.041572 +127.0.0.1, 2018-09-30 20:46:22, GET, /SP, HTTP/1.1, 200, 0.031068 +127.0.0.1, 2018-09-30 20:46:24, GET, /SP/default/task, HTTP/1.1, 200, 0.035173 +127.0.0.1, 2018-10-24 20:05:39, GET, /, HTTP/1.1, 303, 0.003981 +127.0.0.1, 2018-10-24 20:05:40, GET, /welcome/default/index, HTTP/1.1, 200, 0.168427 +127.0.0.1, 2018-10-24 20:05:40, GET, /welcome/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 200, 0.003579 +127.0.0.1, 2018-10-24 20:05:40, GET, /welcome/static/js/jquery.js, HTTP/1.1, 200, 0.006139 +127.0.0.1, 2018-10-24 20:05:40, GET, /welcome/static/js/web2py.js, HTTP/1.1, 200, 0.003745 +127.0.0.1, 2018-10-24 20:05:40, GET, /welcome/static/js/calendar.js, HTTP/1.1, 200, 0.007023 +127.0.0.1, 2018-10-24 20:05:40, GET, /welcome/static/css/calendar.css, HTTP/1.1, 200, 0.008491 +127.0.0.1, 2018-10-24 20:05:40, GET, /welcome/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.001516 +127.0.0.1, 2018-10-24 20:05:40, GET, /welcome/static/css/web2py-bootstrap4.css, HTTP/1.1, 304, 0.002934 +127.0.0.1, 2018-10-24 20:05:40, GET, /welcome/static/js/web2py-bootstrap4.js, HTTP/1.1, 304, 0.005390 +127.0.0.1, 2018-10-24 20:05:40, GET, /welcome/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.007547 +127.0.0.1, 2018-10-24 20:05:40, GET, /welcome/static/images/favicon.png, HTTP/1.1, 200, 0.000532 +127.0.0.1, 2018-10-24 20:05:40, GET, /welcome/static/images/favicon.ico, HTTP/1.1, 200, 0.000689 +127.0.0.1, 2018-10-24 20:05:50, GET, /sp/default, HTTP/1.1, 200, 0.132384 +127.0.0.1, 2018-10-24 20:05:50, GET, /sp/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 200, 0.001901 +127.0.0.1, 2018-10-24 20:05:50, GET, /sp/static/css/web2py-bootstrap4.css, HTTP/1.1, 200, 0.002139 +127.0.0.1, 2018-10-24 20:05:50, GET, /sp/static/css/calendar.css, HTTP/1.1, 200, 0.005355 +127.0.0.1, 2018-10-24 20:05:50, GET, /sp/static/js/calendar.js, HTTP/1.1, 200, 0.002330 +127.0.0.1, 2018-10-24 20:05:50, GET, /sp/static/js/bootstrap.bundle.min.js, HTTP/1.1, 200, 0.000518 +127.0.0.1, 2018-10-24 20:05:50, GET, /sp/static/js/web2py.js, HTTP/1.1, 200, 0.001394 +127.0.0.1, 2018-10-24 20:05:50, GET, /sp/static/js/jquery.js, HTTP/1.1, 200, 0.012079 +127.0.0.1, 2018-10-24 20:05:50, GET, /sp/static/css/bootstrap.min.css, HTTP/1.1, 200, 0.012909 +127.0.0.1, 2018-10-24 20:05:50, GET, /sp/static/js/web2py-bootstrap4.js, HTTP/1.1, 200, 0.001262 +127.0.0.1, 2018-10-24 20:05:51, GET, /sp/static/images/favicon.ico, HTTP/1.1, 200, 0.001344 +127.0.0.1, 2018-10-24 20:06:18, GET, /sp/default/mycalss, HTTP/1.1, 404, 0.023536 +127.0.0.1, 2018-10-24 20:06:18, GET, /favicon.ico, HTTP/1.1, 400, 0.000206 +127.0.0.1, 2018-10-24 20:06:23, GET, /sp/default/myclass, HTTP/1.1, 200, 0.035328 +127.0.0.1, 2018-10-24 20:07:03, GET, /, HTTP/1.1, 303, 0.000429 +127.0.0.1, 2018-10-24 20:07:03, GET, /welcome/default/index, HTTP/1.1, 200, 0.017896 +127.0.0.1, 2018-10-24 20:07:05, GET, /welcome/default/index, HTTP/1.1, 200, 0.016929 +127.0.0.1, 2018-10-24 20:07:09, GET, /sp/default, HTTP/1.1, 200, 0.029933 +127.0.0.1, 2018-10-24 20:07:10, GET, /sp/default, HTTP/1.1, 200, 0.058779 +127.0.0.1, 2018-10-24 20:07:11, GET, /sp/default/myclass, HTTP/1.1, 200, 0.039566 +127.0.0.1, 2018-10-24 20:08:29, GET, /sp/default/task, HTTP/1.1, 303, 0.027090 +127.0.0.1, 2018-10-24 20:08:29, GET, /sp/default/user/login, HTTP/1.1, 200, 0.035529 +127.0.0.1, 2018-10-24 20:08:33, GET, /sp/default/myhome, HTTP/1.1, 303, 0.022793 +127.0.0.1, 2018-10-24 20:08:33, GET, /sp/default/user/login, HTTP/1.1, 200, 0.031373 +127.0.0.1, 2018-10-24 20:08:33, GET, /sp/default/myclass, HTTP/1.1, 200, 0.036345 +127.0.0.1, 2018-10-24 20:08:41, GET, /sp/default/myclass, HTTP/1.1, 200, 0.028573 +127.0.0.1, 2018-10-24 20:08:42, GET, /sp/default/task, HTTP/1.1, 303, 0.025759 +127.0.0.1, 2018-10-24 20:08:42, GET, /sp/default/user/login, HTTP/1.1, 200, 0.031559 +127.0.0.1, 2018-10-24 20:08:44, GET, /sp/default/myhome, HTTP/1.1, 303, 0.037837 +127.0.0.1, 2018-10-24 20:08:44, GET, /sp/default/user/login, HTTP/1.1, 200, 0.031626 +127.0.0.1, 2018-10-24 20:08:45, GET, /sp/default/myclass, HTTP/1.1, 200, 0.029641 +127.0.0.1, 2018-10-24 20:08:50, GET, /sp/default/task, HTTP/1.1, 303, 0.024154 +127.0.0.1, 2018-10-24 20:08:50, GET, /sp/default/user/login, HTTP/1.1, 200, 0.030304 +127.0.0.1, 2018-10-24 20:09:03, GET, /sp/default/task, HTTP/1.1, 303, 0.022202 +127.0.0.1, 2018-10-24 20:09:03, GET, /sp/default/user/login, HTTP/1.1, 200, 0.032325 +127.0.0.1, 2018-10-24 20:09:22, GET, /sp/default/user/login, HTTP/1.1, 200, 0.034560 +127.0.0.1, 2018-10-24 20:09:22, GET, /sp/static/css/bootstrap.min.css, HTTP/1.1, 200, 0.001298 +127.0.0.1, 2018-10-24 20:09:22, GET, /sp/static/css/web2py-bootstrap4.css, HTTP/1.1, 200, 0.002376 +127.0.0.1, 2018-10-24 20:09:22, GET, /sp/static/js/jquery.js, HTTP/1.1, 200, 0.003996 +127.0.0.1, 2018-10-24 20:09:22, GET, /sp/static/css/calendar.css, HTTP/1.1, 200, 0.002138 +127.0.0.1, 2018-10-24 20:09:22, GET, /sp/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 200, 0.005633 +127.0.0.1, 2018-10-24 20:09:22, GET, /sp/static/js/calendar.js, HTTP/1.1, 200, 0.001410 +127.0.0.1, 2018-10-24 20:09:22, GET, /sp/static/js/web2py.js, HTTP/1.1, 200, 0.000884 +127.0.0.1, 2018-10-24 20:09:22, GET, /sp/static/js/bootstrap.bundle.min.js, HTTP/1.1, 200, 0.001075 +127.0.0.1, 2018-10-24 20:09:22, GET, /sp/static/js/web2py-bootstrap4.js, HTTP/1.1, 200, 0.000583 +127.0.0.1, 2018-10-24 20:09:23, GET, /sp/static/images/favicon.ico, HTTP/1.1, 200, 0.000595 +127.0.0.1, 2018-10-24 20:09:29, POST, /sp/default/user/login, HTTP/1.1, 200, 0.042046 +127.0.0.1, 2018-10-24 20:09:46, POST, /sp/default/user/login, HTTP/1.1, 200, 0.038343 +127.0.0.1, 2018-10-24 20:09:53, GET, /sp/default/user/register, HTTP/1.1, 200, 0.038598 +127.0.0.1, 2018-10-24 20:10:17, POST, /sp/default/user/register, HTTP/1.1, 200, 0.043518 +127.0.0.1, 2018-10-24 20:10:42, POST, /sp/default/user/register, HTTP/1.1, 200, 0.050676 +127.0.0.1, 2018-10-24 20:10:59, GET, /sp/default/user/login, HTTP/1.1, 200, 0.040445 +127.0.0.1, 2018-10-24 20:11:07, GET, /sp/default/user/retrieve_password, HTTP/1.1, 200, 0.038354 +127.0.0.1, 2018-10-24 20:11:09, GET, /sp/default/user/login, HTTP/1.1, 200, 0.035480 +127.0.0.1, 2018-10-24 20:11:29, POST, /sp/default/user/login, HTTP/1.1, 303, 0.034588 +127.0.0.1, 2018-10-24 20:11:29, GET, /sp/default/user/login, HTTP/1.1, 200, 0.036128 +127.0.0.1, 2018-10-24 20:11:52, POST, /sp/default/user/login, HTTP/1.1, 303, 0.037957 +127.0.0.1, 2018-10-24 20:11:52, GET, /sp/default/user/login, HTTP/1.1, 200, 0.037679 +127.0.0.1, 2018-10-24 20:11:59, GET, /, HTTP/1.1, 303, 0.000576 +127.0.0.1, 2018-10-24 20:11:59, GET, /welcome/default/index, HTTP/1.1, 200, 0.015589 +127.0.0.1, 2018-10-24 20:12:04, GET, /welcome/default/index, HTTP/1.1, 200, 0.023100 +127.0.0.1, 2018-10-24 20:12:09, GET, /sp/default/index, HTTP/1.1, 200, 0.031858 +127.0.0.1, 2018-10-24 20:12:17, GET, /sp/default/user/login, HTTP/1.1, 200, 0.037617 +127.0.0.1, 2018-10-24 20:12:57, GET, /welcome/default/index, HTTP/1.1, 200, 0.022749 +127.0.0.1, 2018-10-24 20:12:59, GET, /admin/default/site, HTTP/1.1, 303, 0.167374 +127.0.0.1, 2018-10-24 20:12:59, GET, /admin/default/index, HTTP/1.1, 200, 0.040023 +127.0.0.1, 2018-10-24 20:12:59, GET, /admin/static/_2.17.1/plugin_multiselect/jquery.multi-select.js, HTTP/1.1, 200, 0.001291 +127.0.0.1, 2018-10-24 20:12:59, GET, /admin/static/_2.17.1/css/calendar.css, HTTP/1.1, 200, 0.011777 +127.0.0.1, 2018-10-24 20:12:59, GET, /admin/static/_2.17.1/plugin_multiselect/multi-select.css, HTTP/1.1, 200, 0.004301 +127.0.0.1, 2018-10-24 20:12:59, GET, /admin/static/_2.17.1/plugin_statebutton/css/bootstrap-switch.css, HTTP/1.1, 200, 0.006856 +127.0.0.1, 2018-10-24 20:12:59, GET, /admin/static/_2.17.1/images/questions.png, HTTP/1.1, 200, 0.004227 +127.0.0.1, 2018-10-24 20:12:59, GET, /admin/static/_2.17.1/css/bootstrap_essentials.css, HTTP/1.1, 200, 0.003095 +127.0.0.1, 2018-10-24 20:12:59, GET, /admin/static/_2.17.1/plugin_statebutton/js/bootstrap-switch.js, HTTP/1.1, 200, 0.004441 +127.0.0.1, 2018-10-24 20:13:00, GET, /favicon.ico, HTTP/1.1, 400, 0.000234 +127.0.0.1, 2018-10-24 20:13:03, POST, /admin/default/index, HTTP/1.1, 303, 0.008595 +127.0.0.1, 2018-10-24 20:13:03, GET, /admin/default/site, HTTP/1.1, 200, 0.051700 +127.0.0.1, 2018-10-24 20:13:03, GET, /admin/static/_2.17.1/images/glyphicons-halflings-white.png, HTTP/1.1, 200, 0.000590 +127.0.0.1, 2018-10-24 20:13:03, POST, /admin/default/check_version, HTTP/1.1, 200, 0.626045 +127.0.0.1, 2018-10-24 20:13:06, GET, /admin/default/design/SP, HTTP/1.1, 200, 0.146493 +127.0.0.1, 2018-10-24 20:13:06, GET, /admin/static/_2.17.1/images/help.png, HTTP/1.1, 200, 0.000817 +127.0.0.1, 2018-10-24 20:13:06, GET, /favicon.ico, HTTP/1.1, 400, 0.000275 +127.0.0.1, 2018-10-24 20:13:09, GET, /SP/appadmin/index, HTTP/1.1, 200, 0.059301 +127.0.0.1, 2018-10-24 20:13:09, GET, /SP/static/css/web2py-bootstrap4.css, HTTP/1.1, 200, 0.003250 +127.0.0.1, 2018-10-24 20:13:09, GET, /SP/static/js/modernizr-2.8.3.min.js, HTTP/1.1, 304, 0.003447 +127.0.0.1, 2018-10-24 20:13:09, GET, /SP/static/js/calendar.js, HTTP/1.1, 304, 0.002465 +127.0.0.1, 2018-10-24 20:13:09, GET, /SP/static/js/jquery.js, HTTP/1.1, 304, 0.001260 +127.0.0.1, 2018-10-24 20:13:09, GET, /SP/static/css/calendar.css, HTTP/1.1, 200, 0.003506 +127.0.0.1, 2018-10-24 20:13:09, GET, /SP/static/css/bootstrap.min.css, HTTP/1.1, 304, 0.003867 +127.0.0.1, 2018-10-24 20:13:09, GET, /SP/static/js/web2py-bootstrap4.js, HTTP/1.1, 200, 0.005631 +127.0.0.1, 2018-10-24 20:13:09, GET, /SP/static/js/web2py.js, HTTP/1.1, 304, 0.004733 +127.0.0.1, 2018-10-24 20:13:09, GET, /SP/static/js/bootstrap.bundle.min.js, HTTP/1.1, 304, 0.001614 +127.0.0.1, 2018-10-24 20:13:09, GET, /SP/static/images/favicon.ico, HTTP/1.1, 200, 0.000799 +127.0.0.1, 2018-10-24 20:13:42, GET, /SP/appadmin/change_relation/5, HTTP/1.1, 200, 0.064499 +127.0.0.1, 2018-10-24 20:15:24, GET, /SP/appadmin/change_user/Saturn, HTTP/1.1, 200, 0.068343 +127.0.0.1, 2018-10-24 20:15:34, POST, /SP/appadmin/change_user/Saturn, HTTP/1.1, 200, 0.072053 +127.0.0.1, 2018-10-24 20:15:40, POST, /SP/appadmin/change_user/Saturn, HTTP/1.1, 200, 0.055489 +127.0.0.1, 2018-10-24 20:15:42, GET, /SP/default/user/login, HTTP/1.1, 200, 0.032974 +127.0.0.1, 2018-10-24 20:15:54, POST, /SP/default/user/login, HTTP/1.1, 303, 0.034091 +127.0.0.1, 2018-10-24 20:15:54, GET, /sp/default/task, HTTP/1.1, 200, 0.035059 +127.0.0.1, 2018-10-24 20:16:00, GET, /sp/appadmin/index, HTTP/1.1, 200, 0.059340 +127.0.0.1, 2018-10-24 20:16:00, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.098897 +127.0.0.1, 2018-10-24 20:16:09, GET, /sp/appadmin/change_relation/4, HTTP/1.1, 200, 0.059226 +127.0.0.1, 2018-10-24 20:16:38, GET, /sp/appadmin/select/db, HTTP/1.1, 200, 0.074708 +127.0.0.1, 2018-10-24 20:18:35, GET, /sp/default/task, HTTP/1.1, 303, 0.031213 +127.0.0.1, 2018-10-24 20:18:35, GET, /sp/default/user/login, HTTP/1.1, 200, 0.059387 +127.0.0.1, 2018-10-24 20:21:33, GET, /sp/appadmin/index, HTTP/1.1, 200, 0.101518 +127.0.0.1, 2018-10-24 20:21:34, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.147052 +127.0.0.1, 2018-10-24 20:22:49, GET, /sp/appadmin/index, HTTP/1.1, 500, 0.156644 +127.0.0.1, 2018-10-24 20:22:49, GET, /favicon.ico, HTTP/1.1, 400, 0.000429 +127.0.0.1, 2018-10-24 20:22:49, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.286579 +127.0.0.1, 2018-10-24 20:22:51, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-22-49.5bf3d5d5-8470-4062-b60c-430b0a9324d5, HTTP/1.1, 200, 0.140378 +127.0.0.1, 2018-10-24 20:22:51, GET, /favicon.ico, HTTP/1.1, 400, 0.000367 +127.0.0.1, 2018-10-24 20:25:27, GET, /sp/appadmin/index, HTTP/1.1, 500, 0.092316 +127.0.0.1, 2018-10-24 20:25:40, GET, /sp/appadmin/index, HTTP/1.1, 500, 0.076570 +127.0.0.1, 2018-10-24 20:25:52, GET, /sp/appadmin/index, HTTP/1.1, 500, 0.144040 +127.0.0.1, 2018-10-24 20:27:09, GET, /sp/appadmin/index, HTTP/1.1, 500, 0.129261 +127.0.0.1, 2018-10-24 20:27:10, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-27-08.37769d06-1bd1-4ed2-8261-01021011a4ce, HTTP/1.1, 200, 0.169892 +127.0.0.1, 2018-10-24 20:27:11, GET, /favicon.ico, HTTP/1.1, 400, 0.000491 +127.0.0.1, 2018-10-24 20:28:46, GET, /sp/appadmin/index, HTTP/1.1, 500, 0.111211 +127.0.0.1, 2018-10-24 20:28:48, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-28-46.a83d25c8-3c52-4de7-8161-7b3458958b62, HTTP/1.1, 200, 0.108187 +127.0.0.1, 2018-10-24 20:28:48, GET, /favicon.ico, HTTP/1.1, 400, 0.000309 +127.0.0.1, 2018-10-24 20:29:09, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-28-46.a83d25c8-3c52-4de7-8161-7b3458958b62, HTTP/1.1, 200, 0.123921 +127.0.0.1, 2018-10-24 20:29:11, GET, /sp/appadmin/index, HTTP/1.1, 500, 0.065926 +127.0.0.1, 2018-10-24 20:31:09, GET, /sp/appadmin/index, HTTP/1.1, 500, 0.125219 +127.0.0.1, 2018-10-24 20:31:10, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-31-09.9ba3c512-1afe-4804-bce8-7f3045cbb1ec, HTTP/1.1, 200, 0.173126 +127.0.0.1, 2018-10-24 20:31:11, GET, /favicon.ico, HTTP/1.1, 400, 0.000371 +127.0.0.1, 2018-10-24 20:31:28, GET, /sp/appadmin/index, HTTP/1.1, 500, 0.073199 +127.0.0.1, 2018-10-24 20:31:30, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-31-28.b65aad29-b9c7-4d94-8f3e-e1e85df927a1, HTTP/1.1, 200, 0.132775 +127.0.0.1, 2018-10-24 20:31:30, GET, /favicon.ico, HTTP/1.1, 400, 0.000381 +127.0.0.1, 2018-10-24 20:33:13, GET, /sp/appadmin/index, HTTP/1.1, 500, 0.129873 +127.0.0.1, 2018-10-24 20:33:15, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-33-13.e9cae406-ac2c-452f-a3b0-410ed9627864, HTTP/1.1, 200, 0.259827 +127.0.0.1, 2018-10-24 20:33:15, GET, /favicon.ico, HTTP/1.1, 400, 0.002406 +127.0.0.1, 2018-10-24 20:35:13, GET, /sp/appadmin/index, HTTP/1.1, 500, 0.122364 +127.0.0.1, 2018-10-24 20:35:15, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-35-13.70c4b5df-9b5b-4a0e-879b-30a4c10a50b3, HTTP/1.1, 200, 0.167512 +127.0.0.1, 2018-10-24 20:35:15, GET, /favicon.ico, HTTP/1.1, 400, 0.000328 +127.0.0.1, 2018-10-24 20:35:32, GET, /sp/appadmin/index, HTTP/1.1, 500, 0.192498 +127.0.0.1, 2018-10-24 20:35:33, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-35-32.d61a4243-a147-4607-952c-33ff8a7c3c1b, HTTP/1.1, 200, 0.192470 +127.0.0.1, 2018-10-24 20:35:34, GET, /favicon.ico, HTTP/1.1, 400, 0.000507 +127.0.0.1, 2018-10-24 20:35:53, GET, /sp/appadmin/index, HTTP/1.1, 500, 0.132210 +127.0.0.1, 2018-10-24 20:35:55, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-35-53.9396c4f0-dcb1-4bb5-86e0-651b9c426f64, HTTP/1.1, 200, 0.126057 +127.0.0.1, 2018-10-24 20:35:56, GET, /favicon.ico, HTTP/1.1, 400, 0.000403 +127.0.0.1, 2018-10-24 20:36:10, GET, /sp/appadmin/index, HTTP/1.1, 500, 0.086692 +127.0.0.1, 2018-10-24 20:36:11, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-36-10.4b60b067-1e28-4f1f-89cb-c85be3ad678e, HTTP/1.1, 200, 0.125781 +127.0.0.1, 2018-10-24 20:36:11, GET, /favicon.ico, HTTP/1.1, 400, 0.000587 +127.0.0.1, 2018-10-24 20:37:18, GET, /sp/appadmin/index, HTTP/1.1, 200, 0.058231 +127.0.0.1, 2018-10-24 20:37:18, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.074283 +127.0.0.1, 2018-10-24 20:37:57, GET, /sp/appadmin/change_task/27, HTTP/1.1, 200, 0.057747 +127.0.0.1, 2018-10-24 20:38:04, POST, /sp/appadmin/change_task/27, HTTP/1.1, 200, 0.051633 +127.0.0.1, 2018-10-24 20:38:15, GET, /sp/appadmin/change_task/27, HTTP/1.1, 200, 0.053158 +127.0.0.1, 2018-10-24 20:38:18, GET, /, HTTP/1.1, 303, 0.000913 +127.0.0.1, 2018-10-24 20:38:18, GET, /welcome/default/index, HTTP/1.1, 200, 0.022123 +127.0.0.1, 2018-10-24 20:38:24, GET, /sp/default/index, HTTP/1.1, 200, 0.037880 +127.0.0.1, 2018-10-24 20:38:26, GET, /sp/default/task, HTTP/1.1, 200, 0.046654 +127.0.0.1, 2018-10-24 20:38:28, GET, /sp/default/monitorctl/27, HTTP/1.1, 200, 0.035940 +127.0.0.1, 2018-10-24 20:39:09, GET, /sp/default/monitorctl/27, HTTP/1.1, 200, 0.045562 +127.0.0.1, 2018-10-24 20:39:25, GET, /sp/default/monitorctl/27, HTTP/1.1, 200, 0.035452 +127.0.0.1, 2018-10-24 20:39:31, GET, /sp/default/history_task/27, HTTP/1.1, 404, 0.027871 +127.0.0.1, 2018-10-24 20:39:31, GET, /favicon.ico, HTTP/1.1, 400, 0.000292 +127.0.0.1, 2018-10-24 20:40:36, GET, /sp/default/monitorctl/27, HTTP/1.1, 200, 0.034385 +127.0.0.1, 2018-10-24 20:40:42, GET, /sp/appadmin/index, HTTP/1.1, 200, 0.059806 +127.0.0.1, 2018-10-24 20:40:42, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.088161 +127.0.0.1, 2018-10-24 20:40:45, GET, /sp/appadmin/change_task/27, HTTP/1.1, 200, 0.050060 +127.0.0.1, 2018-10-24 20:40:49, POST, /sp/appadmin/change_task/27, HTTP/1.1, 200, 0.057573 +127.0.0.1, 2018-10-24 20:40:55, GET, /sp/appadmin/index, HTTP/1.1, 200, 0.056068 +127.0.0.1, 2018-10-24 20:40:55, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.175072 +127.0.0.1, 2018-10-24 20:40:55, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.075224 +127.0.0.1, 2018-10-24 20:40:57, GET, /admin/default/design/sp, HTTP/1.1, 200, 0.085023 +127.0.0.1, 2018-10-24 20:40:57, GET, /favicon.ico, HTTP/1.1, 400, 0.000218 +127.0.0.1, 2018-10-24 20:41:06, GET, /sp/, HTTP/1.1, 200, 0.055708 +127.0.0.1, 2018-10-24 20:41:09, GET, /sp/default/myhome, HTTP/1.1, 200, 0.036317 +127.0.0.1, 2018-10-24 20:41:10, GET, /sp/default/task, HTTP/1.1, 200, 0.036026 +127.0.0.1, 2018-10-24 20:41:12, GET, /sp/default/monitorctl/27, HTTP/1.1, 200, 0.043534 +127.0.0.1, 2018-10-24 20:41:20, GET, /sp/default/finish_task/27/1/monitor, HTTP/1.1, 303, 0.035246 +127.0.0.1, 2018-10-24 20:41:20, GET, /sp/default/monitorctl/27, HTTP/1.1, 200, 0.036693 +127.0.0.1, 2018-10-24 20:41:28, GET, /sp/default/history_task/27, HTTP/1.1, 404, 0.027700 +127.0.0.1, 2018-10-24 20:41:39, GET, /sp/default/task, HTTP/1.1, 200, 0.035109 +127.0.0.1, 2018-10-24 20:42:49, GET, /sp/default/monitorctl/27, HTTP/1.1, 200, 0.035202 +127.0.0.1, 2018-10-24 20:43:06, GET, /sp/default/task, HTTP/1.1, 200, 0.033960 +127.0.0.1, 2018-10-24 20:43:07, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.079052 +127.0.0.1, 2018-10-24 20:43:07, GET, /sp/appadmin/index, HTTP/1.1, 200, 0.066691 +127.0.0.1, 2018-10-24 20:43:07, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.073044 +127.0.0.1, 2018-10-24 20:43:09, GET, /sp/appadmin/change_task/27, HTTP/1.1, 200, 0.047360 +127.0.0.1, 2018-10-24 20:43:13, POST, /sp/appadmin/change_task/27, HTTP/1.1, 200, 0.053093 +127.0.0.1, 2018-10-24 20:43:17, GET, /sp/, HTTP/1.1, 200, 0.038780 +127.0.0.1, 2018-10-24 20:43:19, GET, /sp/default/task, HTTP/1.1, 200, 0.078371 +127.0.0.1, 2018-10-24 20:43:24, GET, /sp/default/monitorctl/27, HTTP/1.1, 200, 0.031928 +127.0.0.1, 2018-10-24 20:43:27, GET, /sp/default/finish_task/27/1/monitor, HTTP/1.1, 303, 0.028936 +127.0.0.1, 2018-10-24 20:43:27, GET, /sp/default/monitorctl/27, HTTP/1.1, 200, 0.051381 +127.0.0.1, 2018-10-24 20:45:14, GET, /sp/default/task, HTTP/1.1, 200, 0.043368 +127.0.0.1, 2018-10-24 20:45:16, GET, /sp/default/myhome, HTTP/1.1, 200, 0.031882 +127.0.0.1, 2018-10-24 20:45:17, GET, /sp/default/task, HTTP/1.1, 200, 0.037784 +127.0.0.1, 2018-10-24 20:45:17, GET, /sp/default/myhome, HTTP/1.1, 200, 0.034570 +127.0.0.1, 2018-10-24 20:45:22, GET, /sp/default/myclass, HTTP/1.1, 500, 0.062141 +127.0.0.1, 2018-10-24 20:45:22, GET, /favicon.ico, HTTP/1.1, 400, 0.001554 +127.0.0.1, 2018-10-24 20:45:27, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-45-21.a77fcd2f-d2d4-4d68-ab0c-5b9ac8334211, HTTP/1.1, 200, 0.056135 +127.0.0.1, 2018-10-24 20:45:27, GET, /favicon.ico, HTTP/1.1, 400, 0.000228 +127.0.0.1, 2018-10-24 20:47:24, GET, /sp/default/myclass, HTTP/1.1, 500, 0.058139 +127.0.0.1, 2018-10-24 20:47:26, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-47-24.5c391f77-5c16-44ef-8ef1-cccaf2d7e509, HTTP/1.1, 200, 0.046946 +127.0.0.1, 2018-10-24 20:47:26, GET, /favicon.ico, HTTP/1.1, 400, 0.000208 +127.0.0.1, 2018-10-24 20:49:26, GET, /sp/default/myclass, HTTP/1.1, 500, 0.059079 +127.0.0.1, 2018-10-24 20:49:28, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-49-26.d3b60944-aa93-47c6-912e-c41ac302479e, HTTP/1.1, 200, 0.061435 +127.0.0.1, 2018-10-24 20:49:28, GET, /favicon.ico, HTTP/1.1, 400, 0.001548 +127.0.0.1, 2018-10-24 20:49:53, GET, /sp/default/myclass, HTTP/1.1, 500, 0.062127 +127.0.0.1, 2018-10-24 20:49:55, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-49-53.b975ddf0-d822-4e87-8b62-0cf6f40e56e3, HTTP/1.1, 200, 0.064204 +127.0.0.1, 2018-10-24 20:49:55, GET, /favicon.ico, HTTP/1.1, 400, 0.000617 +127.0.0.1, 2018-10-24 20:50:14, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-49-53.b975ddf0-d822-4e87-8b62-0cf6f40e56e3, HTTP/1.1, 200, 0.052569 +127.0.0.1, 2018-10-24 20:50:18, GET, /sp/default/myclass, HTTP/1.1, 500, 0.064303 +127.0.0.1, 2018-10-24 20:51:00, GET, /sp/default/myclass, HTTP/1.1, 500, 0.067206 +127.0.0.1, 2018-10-24 20:51:01, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-51-00.b0142219-1bc4-417e-aa09-7995210816dd, HTTP/1.1, 200, 0.025109 +127.0.0.1, 2018-10-24 20:51:01, GET, /favicon.ico, HTTP/1.1, 400, 0.000208 +127.0.0.1, 2018-10-24 20:51:12, GET, /sp/default/myclass, HTTP/1.1, 500, 0.060027 +127.0.0.1, 2018-10-24 20:51:13, GET, /admin/default/ticket/sp/127.0.0.1.2018-10-24.20-51-12.f46779db-4627-4bc1-bd17-988a79ce4bc8, HTTP/1.1, 200, 0.056036 +127.0.0.1, 2018-10-24 20:51:13, GET, /favicon.ico, HTTP/1.1, 400, 0.000629 +127.0.0.1, 2018-10-24 20:51:55, GET, /sp/appadmin/index, HTTP/1.1, 200, 0.062190 +127.0.0.1, 2018-10-24 20:51:56, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.069869 +127.0.0.1, 2018-10-24 20:52:02, GET, /sp/appadmin/select/m_db, HTTP/1.1, 200, 0.059222 +127.0.0.1, 2018-10-24 20:52:24, POST, /sp/appadmin/select/m_db, HTTP/1.1, 200, 0.064310 +127.0.0.1, 2018-10-24 20:52:31, POST, /sp/appadmin/select/m_db, HTTP/1.1, 200, 0.057519 +127.0.0.1, 2018-10-24 20:52:34, POST, /sp/appadmin/select/m_db, HTTP/1.1, 200, 0.054867 +127.0.0.1, 2018-10-24 20:52:38, POST, /sp/appadmin/select/m_db, HTTP/1.1, 200, 0.055580 +127.0.0.1, 2018-10-24 20:52:40, POST, /sp/appadmin/select/m_db, HTTP/1.1, 200, 0.047761 +127.0.0.1, 2018-10-24 20:52:57, POST, /sp/appadmin/select/m_db, HTTP/1.1, 200, 0.050927 +127.0.0.1, 2018-10-24 20:53:17, POST, /sp/appadmin/select/m_db, HTTP/1.1, 200, 0.050337 +127.0.0.1, 2018-10-24 20:53:26, POST, /sp/appadmin/select/m_db, HTTP/1.1, 200, 0.050165 +127.0.0.1, 2018-10-24 20:53:33, POST, /sp/appadmin/select/m_db, HTTP/1.1, 200, 0.049396 +127.0.0.1, 2018-10-24 20:53:40, POST, /sp/appadmin/select/m_db, HTTP/1.1, 200, 0.063963 +127.0.0.1, 2018-10-24 20:53:44, GET, /sp/default/myclass, HTTP/1.1, 200, 0.085294 +127.0.0.1, 2018-10-24 20:53:47, GET, /sp/appadmin/index, HTTP/1.1, 200, 0.054048 +127.0.0.1, 2018-10-24 20:53:47, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.178167 +127.0.0.1, 2018-10-24 20:53:47, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.084940 +127.0.0.1, 2018-10-24 20:53:53, GET, /sp/default/myclass, HTTP/1.1, 200, 0.039330 +127.0.0.1, 2018-10-24 20:54:41, POST, /sp/appadmin/select/m_db, HTTP/1.1, 200, 0.058788 +127.0.0.1, 2018-10-24 20:54:43, POST, /sp/appadmin/select/m_db, HTTP/1.1, 200, 0.050866 +127.0.0.1, 2018-10-24 20:54:47, POST, /sp/appadmin/select/m_db, HTTP/1.1, 200, 0.050237 +127.0.0.1, 2018-10-24 20:54:54, GET, /sp/appadmin/index, HTTP/1.1, 200, 0.060318 +127.0.0.1, 2018-10-24 20:54:54, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.073651 +127.0.0.1, 2018-10-24 20:54:56, GET, /sp/appadmin/index, HTTP/1.1, 200, 0.058512 +127.0.0.1, 2018-10-24 20:54:56, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.184270 +127.0.0.1, 2018-10-24 20:54:56, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.069942 +127.0.0.1, 2018-10-24 20:54:59, GET, /sp/default/myclass, HTTP/1.1, 200, 0.032184 +127.0.0.1, 2018-10-24 20:55:24, GET, /sp/default/myclass, HTTP/1.1, 200, 0.034205 +127.0.0.1, 2018-10-24 20:55:29, GET, /sp/default/myhome, HTTP/1.1, 200, 0.030922 +127.0.0.1, 2018-10-24 20:55:30, GET, /sp/default/task, HTTP/1.1, 200, 0.040647 +127.0.0.1, 2018-10-24 20:55:31, GET, /sp/default/myhome, HTTP/1.1, 200, 0.029363 +127.0.0.1, 2018-10-24 20:55:32, GET, /sp/default/myclass, HTTP/1.1, 200, 0.032479 +127.0.0.1, 2018-10-24 20:55:33, GET, /sp/default/task, HTTP/1.1, 200, 0.030372 +127.0.0.1, 2018-10-24 20:55:34, GET, /sp/default/myhome, HTTP/1.1, 200, 0.034930 +127.0.0.1, 2018-10-24 20:55:37, GET, /sp/default/change_settings, HTTP/1.1, 200, 0.030200 +127.0.0.1, 2018-10-24 20:55:39, POST, /sp/default/change_settings, HTTP/1.1, 200, 0.044346 +127.0.0.1, 2018-10-24 20:55:39, GET, /sp/default/myclass, HTTP/1.1, 200, 0.032106 +127.0.0.1, 2018-10-24 20:55:40, GET, /sp/default/myhome, HTTP/1.1, 200, 0.032040 +127.0.0.1, 2018-10-24 20:55:42, GET, /sp/default/change_settings, HTTP/1.1, 200, 0.037902 +127.0.0.1, 2018-10-24 20:55:44, POST, /sp/default/change_settings, HTTP/1.1, 200, 0.042953 +127.0.0.1, 2018-10-24 20:55:44, GET, /sp/default/myclass, HTTP/1.1, 200, 0.031564 +127.0.0.1, 2018-10-24 20:55:46, GET, /sp/default/myhome, HTTP/1.1, 200, 0.036476 +127.0.0.1, 2018-10-24 20:55:46, GET, /sp/default/change_settings, HTTP/1.1, 200, 0.030708 +127.0.0.1, 2018-10-24 20:55:48, GET, /sp/default/myclass, HTTP/1.1, 200, 0.031595 +127.0.0.1, 2018-10-24 20:55:48, GET, /sp/default/myhome, HTTP/1.1, 200, 0.032418 +127.0.0.1, 2018-10-24 20:55:49, GET, /sp/default/task, HTTP/1.1, 200, 0.033790 +127.0.0.1, 2018-10-24 20:55:49, GET, /sp/private/home, HTTP/1.1, 404, 0.023469 +127.0.0.1, 2018-10-24 20:55:50, GET, /favicon.ico, HTTP/1.1, 400, 0.000236 +127.0.0.1, 2018-10-24 20:55:52, GET, /sp/appadmin/index, HTTP/1.1, 200, 0.059025 +127.0.0.1, 2018-10-24 20:55:52, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.186004 +127.0.0.1, 2018-10-24 20:55:52, GET, /sp/appadmin/hooks, HTTP/1.1, 200, 0.087467 diff --git a/web2py/parameters_8000.py b/web2py/parameters_8000.py new file mode 100644 index 0000000..47e1a8a --- /dev/null +++ b/web2py/parameters_8000.py @@ -0,0 +1 @@ +password="pbkdf2(1000,20,sha512)$a304bb3d77426fb0$7ff91bde43423de16ed0be102ed5ecc0d4c7ba02" diff --git a/web2py/scripts/autoroutes.py b/web2py/scripts/autoroutes.py new file mode 100644 index 0000000..cc68b49 --- /dev/null +++ b/web2py/scripts/autoroutes.py @@ -0,0 +1,150 @@ +# -*- coding: utf-8 -*- +''' +autoroutes writes routes for you based on a simpler routing +configuration file called routes.conf. Example: + +----- BEGIN routes.conf------- +127.0.0.1 /examples/default +domain1.com /app1/default +domain2.com /app2/default +domain3.com /app3/default +----- END ---------- + +It maps a domain (the left-hand side) to an app (one app per domain), +and shortens the URLs for the app by removing the listed path prefix. That means: + +http://domain1.com/index is mapped to /app1/default/index +http://domain2.com/index is mapped to /app2/default/index + +It preserves admin, appadmin, static files, favicon.ico and robots.txt: + +http://domain1.com/favicon.ico /welcome/static/favicon.ico +http://domain1.com/robots.txt /welcome/static/robots.txt +http://domain1.com/admin/... /admin/... +http://domain1.com/appadmin/... /app1/appadmin/... +http://domain1.com/static/... /app1/static/... + +and vice-versa. + +To use, cp scripts/autoroutes.py routes.py + +and either edit the config string below, or set config = "" and edit routes.conf +''' + +config = ''' +127.0.0.1 /examples/default +domain1.com /app1/default +domain2.com /app2/default +domain3.com /app3/defcon3 +''' +if not config.strip(): + try: + config_file = open('routes.conf', 'r') + try: + config = config_file.read() + finally: + config_file.close() + except: + config = '' + + +def auto_in(apps): + routes = [ + ('/robots.txt', '/welcome/static/robots.txt'), + ('/favicon.ico', '/welcome/static/favicon.ico'), + ('/admin$anything', '/admin$anything'), + ] + for domain, path in [x.strip().split() for x in apps.split('\n') if x.strip() and not x.strip().startswith('#')]: + if not path.startswith('/'): + path = '/' + path + if path.endswith('/'): + path = path[:-1] + app = path.split('/')[1] + routes += [ + ('.*:https?://(.*\.)?%s:$method /' % domain, '%s' % path), + ('.*:https?://(.*\.)?%s:$method /static/$anything' % + domain, '/%s/static/$anything' % app), + ('.*:https?://(.*\.)?%s:$method /appadmin/$anything' % + domain, '/%s/appadmin/$anything' % app), + ('.*:https?://(.*\.)?%s:$method /$anything' % + domain, '%s/$anything' % path), + ] + return routes + + +def auto_out(apps): + routes = [] + for domain, path in [x.strip().split() for x in apps.split('\n') if x.strip() and not x.strip().startswith('#')]: + if not path.startswith('/'): + path = '/' + path + if path.endswith('/'): + path = path[:-1] + app = path.split('/')[1] + routes += [ + ('/%s/static/$anything' % app, '/static/$anything'), + ('/%s/appadmin/$anything' % app, '/appadmin/$anything'), + ('%s/$anything' % path, '/$anything'), + ] + return routes + +routes_in = auto_in(config) +routes_out = auto_out(config) + + +def __routes_doctest(): + ''' + Dummy function for doctesting autoroutes.py. + + Use filter_url() to test incoming or outgoing routes; + filter_err() for error redirection. + + filter_url() accepts overrides for method and remote host: + filter_url(url, method='get', remote='0.0.0.0', out=False) + + filter_err() accepts overrides for application and ticket: + filter_err(status, application='app', ticket='tkt') + + >>> filter_url('http://domain1.com/favicon.ico') + 'http://domain1.com/welcome/static/favicon.ico' + >>> filter_url('https://domain2.com/robots.txt') + 'https://domain2.com/welcome/static/robots.txt' + >>> filter_url('http://domain3.com/fcn') + 'http://domain3.com/app3/defcon3/fcn' + >>> filter_url('http://127.0.0.1/fcn') + 'http://127.0.0.1/examples/default/fcn' + >>> filter_url('HTTP://DOMAIN.COM/app/ctr/fcn') + 'http://domain.com/app/ctr/fcn' + >>> filter_url('http://domain.com/app/ctr/fcn?query') + 'http://domain.com/app/ctr/fcn?query' + >>> filter_url('http://otherdomain.com/fcn') + 'http://otherdomain.com/fcn' + >>> regex_filter_out('/app/ctr/fcn') + '/app/ctr/fcn' + >>> regex_filter_out('/app1/ctr/fcn') + '/app1/ctr/fcn' + >>> filter_url('https://otherdomain.com/app1/default/fcn', out=True) + '/fcn' + >>> filter_url('http://otherdomain.com/app2/ctr/fcn', out=True) + '/app2/ctr/fcn' + >>> filter_url('http://domain1.com/app1/default/fcn?query', out=True) + '/fcn?query' + >>> filter_url('http://domain2.com/app3/defcon3/fcn#anchor', out=True) + '/fcn#anchor' + ''' + pass + +if __name__ == '__main__': + try: + import gluon.main + except ImportError: + import sys + import os + os.chdir(os.path.dirname(os.path.dirname(__file__))) + sys.path.append(os.path.dirname(os.path.dirname(__file__))) + import gluon.main + from gluon.rewrite import regex_select, load, filter_url, regex_filter_out + regex_select() # use base routing parameters + load(routes=__file__) # load this file + + import doctest + doctest.testmod() diff --git a/web2py/scripts/check_lang_progress.py b/web2py/scripts/check_lang_progress.py new file mode 100644 index 0000000..6c53bbd --- /dev/null +++ b/web2py/scripts/check_lang_progress.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Written by Vinyl Darkscratch, www.queengoob.org + +import sys +import os + +# TODO: add comments + +# This script can be run with no arguments (which sets the language folder to the current working directory, and default language to English), one argument (which sets the default language), or two arguments (language folder path and default language). +# When run, this script will compare the original language's strings to their assigned values and determine if they match, just like web2py's interface. While some phrases may be the exact same between both languages, this should provide a good idea of how far along translations are. + +def check_lang_progress(cwd, default_lang): + for x in os.listdir(cwd): + if x == default_lang or x.startswith("plural-"): continue + + data = eval(open(os.path.join(cwd, x)).read()) + + total = 0 + translated = 0 + + for key in data: + total += 1 + if key.replace('@markmin\x01', '') != data[key]: translated += 1 + + print "Translations for %s (%s): %d/%d Translated (%d Untranslated)" %(data['!langname!'], data['!langcode!'], translated, total, total-translated) + +if __name__ == "__main__": + cwd = os.getcwd() + default_lang = 'en' + + if len(sys.argv) > 2: + cwd = sys.argv[1] + default_lang = sys.argv[2] + elif len(sys.argv) > 1: + default_lang = sys.argv[1] + + check_lang_progress(cwd, default_lang) \ No newline at end of file diff --git a/web2py/scripts/contentparser.py b/web2py/scripts/contentparser.py new file mode 100644 index 0000000..89385e2 --- /dev/null +++ b/web2py/scripts/contentparser.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import cStringIO +import re +import sys +import tarfile +import urllib +import xml.parsers.expat as expat + +""" +Update script for contenttype.py module. + +Usage: python contentupdate.py /path/to/contenttype.py + +If no path is specified, script will look for contenttype.py in current +working directory. + +Internet connection is required to perform the update. +""" + +OVERRIDE = [ + ('.pdb', 'chemical/x-pdb'), + ('.xyz', 'chemical/x-pdb') +] + + +class MIMEParser(dict): + + def __start_element_handler(self, name, attrs): + if name == 'mime-type': + if self.type: + for extension in self.extensions: + self[extension] = self.type + self.type = attrs['type'].lower() + self.extensions = [] + elif name == 'glob': + pattern = attrs['pattern'] + if pattern.startswith('*.'): + self.extensions.append(pattern[1:].lower()) + + def __init__(self, fileobj): + dict.__init__(self) + self.type = '' + self.extensions = '' + parser = expat.ParserCreate() + parser.StartElementHandler = self.__start_element_handler + parser.ParseFile(fileobj) + for extension, contenttype in OVERRIDE: + self[extension] = contenttype + + +if __name__ == '__main__': + try: + path = sys.argv[1] + except: + path = 'contenttype.py' + vregex = re.compile('database version (?P<version>.+?)\.?\n') + sys.stdout.write('Checking contenttype.py database version:') + sys.stdout.flush() + try: + pathfile = open(path) + try: + current = pathfile.read() + finally: + pathfile.close() + cversion = re.search(vregex, current).group('version') + sys.stdout.write('\t[OK] version %s\n' % cversion) + except Exception, e: + sys.stdout.write('\t[ERROR] %s\n' % e) + exit() + sys.stdout.write('Checking freedesktop.org database version:') + sys.stdout.flush() + try: + search = re.search( + '(?P<url>http://freedesktop.org/.+?/shared-mime-info-(?P<version>.+?)\.tar\.(?P<type>[gb]z2?))', + urllib.urlopen('http://www.freedesktop.org/wiki/Software/shared-mime-info').read()) + url = search.group('url') + assert url is not None + nversion = search.group('version') + assert nversion is not None + ftype = search.group('type') + assert ftype is not None + sys.stdout.write('\t[OK] version %s\n' % nversion) + except: + sys.stdout.write('\t[ERROR] unknown version\n') + exit() + if cversion == nversion: + sys.stdout.write('\nContenttype.py database is up to date\n') + exit() + try: + raw_input('\nContenttype.py database updates are available from:\n%s (approx. 0.5MB)\nPress enter to continue or CTRL-C to quit now\nWARNING: this will replace contenttype.py file content IN PLACE' % url) + except: + exit() + sys.stdout.write('\nDownloading new database:') + sys.stdout.flush() + fregex = re.compile('^.*/freedesktop\.org\.xml$') + try: + io = cStringIO.StringIO() + io.write(urllib.urlopen(url).read()) + sys.stdout.write('\t[OK] done\n') + except Exception, e: + sys.stdout.write('\t[ERROR] %s\n' % e) + exit() + sys.stdout.write('Installing new database:') + sys.stdout.flush() + try: + tar = tarfile.TarFile.open(fileobj=io, mode='r:%s' % ftype) + try: + for content in tar.getnames(): + if fregex.match(content): + xml = tar.extractfile(content) + break + finally: + tar.close() + data = MIMEParser(xml) + io = cStringIO.StringIO() + io.write('CONTENT_TYPE = {\n') + for key in sorted(data): + io.write(' \'%s\': \'%s\',\n' % (key, data[key])) + io.write(' }') + io.seek(0) + contenttype = open('contenttype.py', 'w') + try: + contenttype.write(re.sub(vregex, 'database version %s.\n' % nversion, re.sub('CONTENT_TYPE = \{(.|\n)+?\}', io.getvalue(), current))) + finally: + contenttype.close() + if not current.closed: + current.close() + sys.stdout.write('\t\t\t[OK] done\n') + except Exception, e: + sys.stdout.write('\t\t\t[ERROR] %s\n' % e) diff --git a/web2py/scripts/cpdb.py b/web2py/scripts/cpdb.py new file mode 100644 index 0000000..2e5e949 --- /dev/null +++ b/web2py/scripts/cpdb.py @@ -0,0 +1,685 @@ +import os +import sys +from collections import deque +import argparse +import cStringIO +import operator +import cPickle as pickle +from collections import deque +import math +import re +import cmd +try: + import pyreadline as readline +except ImportError: + import readline +try: + from gluon import DAL + from gluon.fileutils import open_file +except ImportError as err: + print('gluon path not found') + + +class refTable(object): + def __init__(self): + self.columns = None + self.rows = None + + def getcolHeader(self, colHeader): + return ' | '.join('**%s**' % item for item in colHeader) + + def wrapTable( + self, rows, hasHeader=False, headerChar='-', delim=' | ', justify='left', + separateRows=False, prefix='', postfix='', wrapfunc=lambda x: x): + + def rowWrapper(row): + + '''--- + newRows is returned like + [['w'], ['x'], ['y'], ['z']] + ---''' + newRows = [wrapfunc(item).split('\n') for item in row] + self.rows = newRows + '''--- + rowList gives like newRows but + formatted like [[w, x, y, z]] + ---''' + rowList = [[substr or '' for substr in item] + for item in map(None, *newRows)] + return rowList + + logicalRows = [rowWrapper(row) for row in rows] + + columns = map(None, *reduce(operator.add, logicalRows)) + self.columns = columns + + maxWidths = [max( + [len(str + (item)) for + item in column] + ) for column + in columns] + + rowSeparator = headerChar * (len(prefix) +len(postfix) + sum(maxWidths) + + len(delim) * (len(maxWidths) - 1)) + + justify = {'center': str.center, + 'right': str.rjust, + 'left': str.ljust + }[justify.lower()] + + output = cStringIO.StringIO() + + if separateRows: + print >> output, rowSeparator + + for physicalRows in logicalRows: + for row in physicalRows: + print >> output,\ + prefix + delim.join([ + justify(str(item), width) for ( + item, width) in zip(row, maxWidths)] + ) + postfix + + if separateRows or hasHeader: + print >> output, rowSeparator + hasHeader = False + return output.getvalue() + + def wrap_onspace(self, text, width): + return reduce(lambda line, word, width=width: '%s%s%s' % ( + line, + ' ' if len(line.rsplit('\n')[-1]+word.split('\n')[0])>=width else '\n', + word), text.split(' ')) + + + def wrap_onspace_strict(self, text, width): + wordRegex = re.compile(r'\S{' + str(width) + r',}') + return self.wrap_onspace( + wordRegex.sub( + lambda m: self. + wrap_always( + m.group(), width), text + ), width) + + def wrap_always(self, text, width): + return '\n'.join( + [text[width * i:width * (i + 1 + )] for i in xrange( + int(math.ceil(1. * len( + text) / width)))]) + + +class tableHelper(): + def __init__(self): + self.oTable = refTable() + + def getAsRows(self, data): + return [row.strip().split(',') for row in data.splitlines()] + + def getTable_noWrap(self, data, header=None): + rows = self.getAsRows(data) + if header is not None: + hRows = [header] + rows + else: + hRows = rows + table = self.oTable.wrapTable(hRows, hasHeader=True) + return table + + def getTable_Wrap(self, data, wrapStyle, header=None, width=65): + wrapper = None + if len(wrapStyle) > 1: + rows = self.getAsRows(data) + if header is not None: + hRows = [header] + rows + else: + hRows = rows + + for wrapper in (self.oTable.wrap_always, + self.oTable.wrap_onspace, + self.oTable.wrap_onspace_strict): + return self.oTable.wrapTable(hRows, hasHeader=True, separateRows=True, prefix='| ', postfix=' |', wrapfunc=lambda x: + wrapper(x, width)) + else: + return self.getTable_noWrap(data, header) + + def getAsErrorTable(self, err): + return self.getTable_Wrap(err, None) + + +class console: + def __init__(self, prompt, banner=None): + self.prompt = prompt + self.banner = banner + self.commands = {} + self.commandSort = [] + self.db = None + + for i in dir(self): + if "cmd_" == i[:4]: + cmd = i.split("cmd_")[1].lower() + self.commands[cmd] = getattr(self, i) + try: + self.commandSort.append((int(self + .commands[cmd].__doc__.split( + "|")[0]), cmd)) + except: + pass + + self.commandSort.sort() + self.commandSort = [i[1] for i in self.commandSort] + + self.var_DEBUG = False + self.var_tableStyle = '' + + self.configvars = {} + for i in dir(self): + if "var_" == i[:4]: + var = i.split("var_")[1] + self.configvars[var] = i + + def setBanner(self, banner): + self.banner = banner + + def execCmd(self, db): + self.db = db + print self.banner + while True: + try: + command = raw_input(self.prompt) + try: + self.execCommand(command) + except: + self.execute(command) + except KeyboardInterrupt: + break + except EOFError: + break + except Exception, a: + self.printError(a) + print ("\r\n\r\nBye!...") + sys.exit(0) + + def printError(self, err): + sys.stderr.write("Error: %s\r\n" % err) + if self.var_DEBUG: + pass + + def execute(self, cmd): + try: + if not '-table ' in cmd: + exec cmd + else: + file = None + table = None + + fields = [] + items = cmd.split() + invalidParams = [] + table = self.getTable(items[1]) + allowedParams = ['fields', 'file'] + for i in items: + if '=' in i and not i.split('=')[0] in allowedParams: + try: + invalidParams.append(i) + except Exception, err: + raise Exception('invalid parameter\n%s' % i) + else: + if 'file=' in i: + file = os.path.abspath(i.split('=')[0].strip()) + if 'fields=' in i: + for field in i.split('=')[1].split(): + if field in self.db[table].fields: + fields.append(field.strip()) + + if len(invalidParams) > 0: + print('the following parameter(s) is not valid\n%s' % + ','.join(invalidParams)) + else: + try: + self.cmd_table(table, file, fields) + except Exception, err: + print('could not generate table for table %s\n%s' % (table, err)) + except Exception, err: + print('sorry, can not do that!\n%s' % err) + + def getTable(self, tbl): + for mTbl in db.tables: + if tbl in mTbl: + if mTbl.startswith(tbl): + return mTbl + + def execCommand(self, cmd): + words = cmd.split(" ") + words = [i for i in words if i] + if not words: + return + cmd, parameters = words[0].lower(), words[1:] + + if not cmd in self.commands: + raise Exception( + "Command %s not found. Try 'help'\r\n" % cmd) + + self.commands[cmd](*parameters) + + '''--- + DEFAULT COMMANDS (begins with cmd_) + ---''' + def cmd_clear(self, numlines=100): + """-5|clear|clear the screen""" + if os.name == "posix": + '''--- + Unix/Linux/MacOS/BSD/etc + ---''' + os.system('clear') + elif os.name in ("nt", "dos", "ce"): + '''--- + Windows + ---''' + os.system('CLS') + else: + '''--- + Fallback for other operating systems. + ---''' + print '\n' * numlines + + def cmd_table(self, tbl, file=None, fields=[]): + """-4|-table [TABLENAME] optional[file=None] [fields=None]|\ +the default tableStyle is no_wrap - use the 'set x y' command to change the style\n\ +style choices: +\twrap_always +\twrap_onspace +\twrap_onspace_strict +\tno_wrap (value '')\n +\t the 2nd optional param is a path to a file where the table will be written +\t the 3rd optional param is a list of fields you want displayed\n""" + table = None + for mTbl in db.tables: + if tbl in mTbl: + if mTbl.startswith(tbl): + table = mTbl + break + oTable = tableHelper() + '''--- + tablestyle: + wrap_always + wrap_onspace + wrap_onspace_strict + or set set to "" for no wrapping + ---''' + tableStyle = self.var_tableStyle + filedNotFound = [] + table_fields = None + if len(fields) == 0: + table_fields = self.db[table].fields + else: + table_fields = fields + + for field in fields: + if not field in self.db[table].fields: + filedNotFound.append(field) + if len(filedNotFound) == 0: + rows = self.db(self.db[table].id > 0).select() + rows_data = [] + for row in rows: + rowdata = [] + for f in table_fields: + rowdata.append(str(row[f])) + rows_data.append(','.join(rowdata)) + data = '\n'.join(rows_data) + dataTable = oTable.getTable_Wrap(data, tableStyle, table_fields) + print('TABLE %s\n%s' % (table, dataTable)) + if file is not None: + try: + tail, head = os.path.split(file) + try: + os.makedirs(tail) + except: + 'do nothing, folders exist' + oFile = open(file, 'w') + oFile.write('TABLE: %s\n%s' % (table, dataTable)) + oFile.close() + print('%s has been created and populated with all available data from table %2\n' % (file, table)) + except Exception, err: + print("EXCEPTION: could not create table %s\n%s" % (table, err)) + + else: + print('the following fields are not valid [%s]' % (','.join(filedNotFound))) + + + def cmd_help(self, *args): + '''-3|help|Show's help''' + alldata = [] + lengths = [] + + for i in self.commandSort: + alldata.append( + self.commands[i].__doc__.split("|")[1:]) + + for i in alldata: + if len(i) > len(lengths): + for j in range(len(i) + - len(lengths)): + lengths.append(0) + + j = 0 + while j < len(i): + if len(i[j]) > lengths[j]: + lengths[j] = len(i[j]) + j += 1 + + print ("-" * (lengths[0] + lengths[1] + 4)) + for i in alldata: + print (("%-" + str(lengths[0]) + "s - %-" + str( + lengths[1]) + "s") % (i[0], i[1])) + if len(i) > 2: + for j in i[2:]: print (("%" + str(lengths[ + 0] + 9) + "s* %s") % (" ", j)) + print + + def cmd_vars(self, *args): + '''-2|vars|Show variables''' + print ("variables\r\n" + "-" * 79) + for i, j in self.configvars.items(): + value = self.parfmt(repr(getattr(self, j)), 52) + print ("| %20s | %52s |" % (i, value[0])) + for k in value[1:]: print ("| %20s | %52s |" % ("", k)) + if len(value) > 1: + print("| %20s | %52s |" % ("", "")) + print ("-" * 79) + + def parfmt(self, txt, width): + res = [] + pos = 0 + while True: + a = txt[pos:pos + width] + if not a: + break + res.append(a) + pos += width + return res + + def cmd_set(self, *args): + '''-1|set [variable_name] [value]|Set configuration variable value|Values are an expressions (100 | string.lower('ABC') | etc.''' + value = " ".join(args[1:]) + if args[0] not in self.configvars: + setattr(self, "var_{0}" % (args[0]), eval(value)) + setattr(self, "var_{0}" % (args[0]), eval(value)) + + def cmd_clearscreen(self, numlines=50): + '''---Clear the console. + ---''' + if os.name == "posix": + '''--- + Unix/Linux/MacOS/BSD/etc + ---''' + os.system('clear') + elif os.name in ("nt", "dos", "ce"): + '''--- + Windows + ---''' + os.system('CLS') + else: + '''--- + Fallback for other operating systems. + ---''' + print '\n' * numlines + + +class dalShell(console): + def __init__(self): + pass + + def shell(self, db): + console.__init__(self, prompt=">>> ", banner='dal interactive shell') + self.execCmd(db) + + +class setCopyDB(): + def __init__(self): + '''--- + non source or target specific vars + ---''' + self.strModel = None + self.dalPath = None + self.db = None + '''--- + source vars + ---''' + self.sourceModel = None + self.sourceFolder = None + self.sourceConnectionString = None + self.sourcedbType = None + self.sourcedbName = None + '''--- + target vars + ---''' + self.targetdbType = None + self.targetdbName = None + self.targetModel = None + self.targetFolder = None + self.targetConnectionString = None + self.truncate = False + + def _getDal(self): + mDal = None + if self.dalPath is not None: + global DAL + sys.path.append(self.dalPath) + mDal = __import__( + 'dal', globals={}, locals={}, fromlist=['DAL'], level=0) + DAL = mDal.DAL + return mDal + + def instDB(self, storageFolder, storageConnectionString, autoImport): + self.db = DAL(storageConnectionString, folder=os.path.abspath( + storageFolder), auto_import=autoImport) + return self.db + + def delete_DB_tables(self, storageFolder, storageType): + print 'delete_DB_tablesn\n\t%s\n\t%s' % (storageFolder, storageType) + + dataFiles = [storageType, "sql.log"] + try: + for f in os.listdir(storageFolder): + if ".table" in f: + fTable = "%s/%s" % (storageFolder, f) + os.remove(fTable) + print('deleted %s' % (fTable)) + for dFile in dataFiles: + os.remove("%s/%s" % (storageFolder, dFile)) + print('deleted %s' % ( + "%s/%s" % (storageFolder, dFile))) + except Exception, errObj: + print(str(errObj)) + + def truncatetables(self, tables=[]): + if len(tables) != 0: + try: + print 'table value: %s' % (tables) + for tbl in self.db.tables: + for mTbl in tables: + if mTbl.startswith(tbl): + self.db[mTbl].truncate() + except Exception, err: + print('EXCEPTION: %s' % (err)) + else: + try: + for tbl in self.db.tables: + self.db[tbl].truncate() + except Exception, err: + print('EXCEPTION: %s' % (err)) + + def copyDB(self): + other_db = DAL("%s://%s" % ( + self.targetdbType, self.targetdbName), folder=self.targetFolder) + + print 'creating tables...' + + for table in self.db: + other_db.define_table( + table._tablename, *[field for field in table]) + ''' + should there be an option to truncAte target DB? + if yes, then change args to allow for choice + and set self.trancate to the art value + + if self.truncate==True: + other_db[table._tablename].truncate() + ''' + + print 'exporting data...' + self.db.export_to_csv_file(open('tmp.sql', 'wb')) + + print 'importing data...' + other_db.import_from_csv_file(open_file('tmp.sql', 'rb')) + other_db.commit() + print 'done!' + print 'Attention: do not run this program again or you end up with duplicate records' + + def createfolderPath(self, folder): + try: + if folder is not None: + os.makedirs(folder) + except Exception, err: + pass + +if __name__ == '__main__': + oCopy = setCopyDB() + db = None + targetDB = None + dbfolder = None + clean = False + model = None + truncate = False + + parser = argparse.ArgumentParser(description='\ +samplecmd line:\n\ +-f ./blueLite/db_storage -i -y sqlite://storage.sqlite -Y sqlite://storage2.sqlite -d ./blueLite/pyUtils/sql/blueSQL -t True', + epilog='') + reqGroup = parser.add_argument_group('Required arguments') + reqGroup.add_argument('-f', '--sourceFolder', required=True, help="path to the 'source' folder of the 'source' DB") + reqGroup.add_argument('-F', '--targetFolder', required=False, help="path to the 'target' folder of the 'target' DB") + reqGroup.add_argument('-y', '--sourceConnectionString', required=True, help="source db connection string ()\n\ +------------------------------------------------\n\ +\ +sqlite://storage.db\n\ +mysql://username:password@localhost/test\n\ +postgres://username:password@localhost/test\n\ +mssql://username:password@localhost/test\n\ +firebird://username:password@localhost/test\n\ +oracle://username/password@test\n\ +db2://username:password@test\n\ +ingres://username:password@localhost/test\n\ +informix://username:password@test\n\ +\ +------------------------------------------------") + reqGroup.add_argument('-Y', '--targetConnectionString', required=True, + help="target db type (sqlite,mySql,etc.)") + autoImpGroup = parser.add_argument_group('optional args (auto_import)') + autoImpGroup.add_argument('-a', '--autoimport', required=False, help='set to True to bypass loading of the model') + + """ + + *** removing -m/-M options for now --> i need a + better regex to match db.define('bla')...with optional db.commit() + + modelGroup=parser.add_argument_group('optional args (create model)') + modelGroup.add_argument('-m','--sourcemodel'\ + ,required=False\ + ,help='to create a model from an existing model, point to the source model') + modelGroup.add_argument('-M','--targetmodel'\ + ,required=False\ + ,help='to create a model from an existing model, point to the target model') + + """ + + miscGroup = parser.add_argument_group('optional args/tasks') + miscGroup.add_argument('-i', '--interactive', required=False, action='store_true', help='run in interactive mode') + miscGroup.add_argument( + '-d', '--dal', required=False, help='path to dal.py') + miscGroup.add_argument('-t', '--truncate', choices=['True', 'False'], help='delete the records but *not* the table of the SOURCE DB') + miscGroup.add_argument('-b', '--tables', required=False, type=list, help='optional list (comma delimited) of SOURCE tables to truncate, defaults to all') + miscGroup.add_argument('-c', '--clean', required=False, help='delete the DB,tables and the log file, WARNING: this is unrecoverable') + + args = parser.parse_args() + db = None + mDal = None + + try: + oCopy.sourceFolder = args.sourceFolder + oCopy.targetFolder = args.sourceFolder + sourceItems = args.sourceConnectionString.split('://',1) + oCopy.sourcedbType = sourceItems[0] + oCopy.sourcedbName = sourceItems[1] + targetItems = args.targetConnectionString.split('://',1) + oCopy.targetdbType = targetItems[0] + oCopy.targetdbName = targetItems[1] + except Exception, err: + print('EXCEPTION: %s' % (err)) + + if args.dal: + try: + autoImport = True + if args.autoimport: + autoImport = args.autoimport + #sif not DAL in globals: + #if not sys.path.__contains__(): + oCopy.dalPath = args.dal + mDal = oCopy._getDal() + db = oCopy.instDB(args.sourceFolder, args.sourceConnectionString, + autoImport) + except Exception, err: + print('EXCEPTION: could not set DAL\n%s' % (err)) + if args.truncate: + try: + if args.truncate: + if args.tables: + tables = args.tables.strip().split(',') + else: + oCopy.truncatetables([]) + except Exception, err: + print('EXCEPTION: could not truncate tables\n%s' % (err)) + try: + if args.clean: + oCopy.delete_DB_tables(oCopy.targetFolder, oCopy.targetType) + except Exception, err: + print('EXCEPTION: could not clean db\n%s' % (err)) + + """ + *** goes with -m/-M options... removed for now + + if args.sourcemodel: + try: + oCopy.sourceModel=args.sourcemodel + oCopy.targetModel=args.sourcemodel + oCopy.createModel() + except Exception, err: + print('EXCEPTION: could not create model\n\ +source model: %s\n\ +target model: %s\n\ +{2}' % (args.sourcemodel,args.targetmodel,err)) + """ + + if args.sourceFolder: + try: + oCopy.sourceFolder = os.path.abspath(args.sourceFolder) + oCopy.createfolderPath(oCopy.sourceFolder) + except Exception, err: + print('EXCEPTION: could not create folder path\n%s' % (err)) + else: + oCopy.dbStorageFolder = os.path.abspath(os.getcwd()) + if args.targetFolder: + try: + oCopy.targetFolder = os.path.abspath(args.targetFolder) + oCopy.createfolderPath(oCopy.targetFolder) + except Exception, err: + print('EXCEPTION: could not create folder path\n%s' % (err)) + if not args.interactive: + try: + oCopy.copyDB() + except Exception, err: + print('EXCEPTION: could not make a copy of the database\n%s' % (err)) + else: + s = dalShell() + s.shell(db) diff --git a/web2py/scripts/cpplugin.py b/web2py/scripts/cpplugin.py new file mode 100644 index 0000000..652b874 --- /dev/null +++ b/web2py/scripts/cpplugin.py @@ -0,0 +1,32 @@ +import sys +import glob +import os +import shutil +name = sys.argv[1] +app = sys.argv[2] +dest = sys.argv[3] +a = glob.glob( + 'applications/%(app)s/*/plugin_%(name)s.*' % dict(app=app, name=name)) +b = glob.glob( + 'applications/%(app)s/*/plugin_%(name)s/*' % dict(app=app, name=name)) + +for f in a: + print 'cp %s ...' % f, + shutil.copyfile(f, os.path.join('applications', dest, *f.split('/')[2:])) + print 'done' + +for f in b: + print 'cp %s ...' % f, + path = f.split('/') + for i in range(3, len(path)): + try: + os.mkdir(os.path.join('applications', dest, *path[2:i])) + except: + pass + path = os.path.join('applications', dest, *f.split('/')[2:]) + if os.path.isdir(f): + if not os.path.exists(path): + shutil.copytree(f, path) + else: + shutil.copyfile(f, path) + print 'done' diff --git a/web2py/scripts/dict_diff.py b/web2py/scripts/dict_diff.py new file mode 100644 index 0000000..f11b41c --- /dev/null +++ b/web2py/scripts/dict_diff.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +''' +@author: Pierre Thibault (pierre.thibault1 -at- gmail.com) +@license: MIT +@since: 2011-06-17 + +Usage: dict_diff [OPTION]... dict1 dict2 +Show the differences for two dictionaries. + + -h, --help Display this help message. + +dict1 and dict2 are two web2py dictionary files to compare. These are the files +located in the "languages" directory of a web2py app. The tools show the +differences between the two files. +''' + +__docformat__ = "epytext en" + +import getopt +import os.path +import sys + + +def main(argv): + """Parse the arguments and start the main process.""" + try: + opts, args = getopt.getopt(argv, "h", ["help"]) + except getopt.GetoptError: + exit_with_parsing_error() + for opt, arg in opts: + arg = arg # To avoid a warning from Pydev + if opt in ("-h", "--help"): + usage() + sys.exit() + if len(args) == 2: + params = list(get_dicts(*args)) + params.extend(get_dict_names(*args)) + compare_dicts(*params) + else: + exit_with_parsing_error() + + +def exit_with_parsing_error(): + """Report invalid arguments and usage.""" + print("Invalid argument(s).") + usage() + sys.exit(2) + + +def usage(): + """Display the documentation""" + print(__doc__) + + +def get_dicts(dict_path1, dict_path2): + """ + Parse the dictionaries. + @param dict_path1: The path to the first dictionary. + @param dict_path2: The path to the second dictionary. + @return: The two dictionaries as a sequence. + """ + + return eval(open(dict_path1).read()), eval(open(dict_path2).read()) + + +def get_dict_names(dict1_path, dict2_path): + """ + Get the name of the dictionaries for the end user. Use the base name of the + files. If the two base names are identical, returns "dict1" and "dict2." + @param dict1_path: The path to the first dictionary. + @param dict2_path: The path to the second dictionary. + @return: The two dictionary names as a sequence. + """ + + dict1_name = os.path.basename(dict1_path) + dict2_name = os.path.basename(dict2_path) + if dict1_name == dict2_name: + dict1_name = "dict1" + dict2_name = "dict2" + return dict1_name, dict2_name + + +def compare_dicts(dict1, dict2, dict1_name, dict2_name): + """ + Compare the two dictionaries. Print out the result. + @param dict1: The first dictionary. + @param dict1: The second dictionary. + @param dict1_name: The name of the first dictionary. + @param dict2_name: The name of the second dictionary. + """ + + dict1_keyset = set(dict1.keys()) + dict2_keyset = set(dict2.keys()) + print_key_diff(dict1_keyset - dict2_keyset, dict1_name, dict2_name) + print_key_diff(dict2_keyset - dict1_keyset, dict2_name, dict1_name) + print "Value differences:" + has_value_differences = False + for key in dict1_keyset & dict2_keyset: + if dict1[key] != dict2[key]: + print " %s:" % (key,) + print " %s: %s" % (dict1_name, dict1[key],) + print " %s: %s" % (dict2_name, dict2[key],) + print + has_value_differences = True + if not has_value_differences: + print " None" + + +def print_key_diff(key_diff, dict1_name, dict2_name): + """ + Prints the keys in the first dictionary and are in the second dictionary. + @param key_diff: Keys in dictionary 1 not in dictionary 2. + @param dict1_name: Name used for the first dictionary. + @param dict2_name: Name used for the second dictionary. + """ + + print "Keys in %s not in %s:" % (dict1_name, dict2_name) + if len(key_diff): + for key in key_diff: + print " %s" % (key,) + else: + print " None" + print + +if __name__ == "__main__": + main(sys.argv[1:]) # Start the process (without the application name) diff --git a/web2py/scripts/drop-pgsql-tables.sh b/web2py/scripts/drop-pgsql-tables.sh new file mode 100644 index 0000000..44e5197 --- /dev/null +++ b/web2py/scripts/drop-pgsql-tables.sh @@ -0,0 +1,14 @@ +# first, login with psql +psql -U USERNAME -d databasename + +# set output for all queries +\o FILENAME.sql + +# run this query +select 'drop table ' || tablename || ' cascade;' from pg_tables; + +# logout from psql +\q + +# run sql script from commandline +psql -U USERNAME -d databasename -f FILENAME.sql \ No newline at end of file diff --git a/web2py/scripts/extract_mssql_models.py b/web2py/scripts/extract_mssql_models.py new file mode 100644 index 0000000..91b6eed --- /dev/null +++ b/web2py/scripts/extract_mssql_models.py @@ -0,0 +1,328 @@ +"""Create web2py model (python code) to represent MS SQL Server tables. +Features: +* Uses ANSI Standard INFORMATION_SCHEMA (might work with other RDBMS) +* Detects legacy "keyed" tables (not having an "id" PK) +* Handles 'funny' column names. web2py requires all column names be valid python identifiers. This script uses rname +* for column names that have spaces or are otherwise invalid python identifiers. +* Connects directly to running databases, no need to do a SQL dump +* Handles notnull, unique and referential constraints +* Detects most common datatypes and default values +* Supports running from the command line as well as from an IDE's debug menu. See the COMMAND_LINE_MODE constant below +* for more info. + +Requirements: +* Needs pyodbc python connector + +Created by Kyle Flanagan. Based on a script by Mariano Reingart which was +based on a script to "generate schemas from dbs" (mysql) by Alexandre Andrade +""" + +_author__ = "Kyle Flanagan <kyleflanagan@gmail.com>" + +HELP = """ +USAGE: extract_mssql_models db host port user passwd +Call with SQL Server database connection parameters, +web2py model will be printed on standard output. +EXAMPLE: python extract_mssql_models.py mydb localhost 3306 kflanaga pass +or +python extract_mssql_models.py mydb localhost 3306 kflanaga pass > db_model.py +""" + +# Config options +DEBUG = False # print debug messages to STDERR +SCHEMA = 'dbo' +COMMAND_LINE_MODE = True # running from command prompt. Disable to specify variables and use in IDE +# Only specify values below if not running from command line +DB = None +HOST = None +USER = None +PASSWD = None +PORT = None + +# Constant for Field keyword parameter order (and filter): +KWARGS = ('type', 'length', 'default', 'required', 'ondelete', + 'notnull', 'unique', 'label', 'comment', 'rname') + +import sys +import re +# This is from pydal/helpers/regex.py as of 2016-06-16 +# Use this to recognize if a field name need to have an rname representation +REGEX_VALID_TB_FLD = re.compile(r'^[^\d_][_0-9a-zA-Z]*\Z') +# For replacing invalid characters in field names +INVALID_CHARS = re.compile(r'[^a-zA-Z0-9_]') + + +def get_valid_column_name(field): + """Return a valid column name that follows Python's rules for identifiers, which is what web2py requires for column + names. Replaces invalid characters with underscores and leading digits with their associated English word.""" + if not REGEX_VALID_TB_FLD.match(field): + # If the first character is a digit, replace it with its word counterpart + if re.match(r'^[0-9]', field): + numbers = ['Zero', 'One', 'Two', 'Three', 'Four', + 'Five', 'Six', 'Seven', 'Eight', 'Nine'] + field = numbers[int(field[0])] + field[1:] + + field = INVALID_CHARS.sub('_', field) + return field + + +def query(conn, sql, *args): + "Execute a SQL query and return rows as a list of dicts" + cur = conn.cursor() + ret = [] + try: + if DEBUG: print >> sys.stderr, "QUERY: ", sql % args + cur.execute(sql % args) + for row in cur: + dic = {} + for i, value in enumerate(row): + field = cur.description[i][0] + dic[field] = value + if DEBUG: print >> sys.stderr, "RET: ", dic + ret.append(dic) + return ret + finally: + cur.close() + + +def get_tables(conn, schema=SCHEMA): + "List table names in a given schema" + rows = query(conn, """SELECT table_name FROM information_schema.tables + WHERE table_schema = '%s' + ORDER BY table_name""", schema) + return [row['table_name'] for row in rows] + + +def get_fields(conn, table): + "Retrieve field list for a given table" + if DEBUG: print >> sys.stderr, "Processing TABLE", table + rows = query(conn, """ + SELECT column_name, data_type, + is_nullable, + character_maximum_length, + numeric_precision, numeric_precision_radix, numeric_scale, + column_default + FROM information_schema.columns + WHERE table_name='%s' + ORDER BY ordinal_position""", table) + return rows + + +def define_field(conn, table, field, pks): + "Determine field type, default value, references, etc." + f = {} + ref = references(conn, table, field['column_name']) + if ref: + f.update(ref) + elif field['column_default'] and \ + field['column_default'].startswith("nextval") and \ + field['column_name'] in pks: + f['type'] = "'id'" + elif field['data_type'].startswith('character'): + f['type'] = "'string'" + if field['character_maximum_length']: + f['length'] = field['character_maximum_length'] + elif field['data_type'] in ('text', 'ntext'): + f['type'] = "'text'" + elif field['data_type'] in ('boolean', 'bit'): + f['type'] = "'boolean'" + elif field['data_type'] in ('tinyint', 'smallint', 'bigint', 'int'): + f['type'] = "'integer'" + elif field['data_type'] in ('real', 'float'): + f['type'] = "'double'" + elif field['data_type'] in ('datetime', 'datetime2', 'smalldatetime'): + f['type'] = "'datetime'" + elif field['data_type'] in ('timestamp',): + f['type'] = "'datetime'" + f['default'] = "request.now" + f['update'] = "request.now" + elif field['data_type'] in ('date',): + f['type'] = "'date'" + elif field['data_type'] in ('time',): + f['type'] = "'time'" + elif field['data_type'] in ('numeric', 'money', 'smallmoney', 'decimal'): + f['type'] = "'decimal'" + f['precision'] = field['numeric_precision'] + f['scale'] = field['numeric_scale'] or 0 + elif field['data_type'] in ('binary', 'varbinary', 'image'): + f['type'] = "'blob'" + elif field['data_type'] in ('point', 'lseg', 'polygon', 'unknown', 'USER-DEFINED', 'sql_variant'): + f['type'] = "" # unsupported? + elif field['data_type'] in ('varchar', 'char', 'nchar', 'nvarchar', 'uniqueidentifer'): + f['type'] = "'string'" + else: + raise RuntimeError("Data Type not supported: %s " % str(field)) + + try: + if field['column_default']: + if field['column_default'] == "now()": + d = "request.now" + elif field['column_default'] == "true": + d = "True" + elif field['column_default'] == "false": + d = "False" + else: + d = repr(eval(field['column_default'])) + f['default'] = str(d) + except (ValueError, SyntaxError): + pass + except Exception, e: + raise RuntimeError("Default unsupported '%s'" % field['column_default']) + + if not field['is_nullable']: + f['notnull'] = "True" + + # For field names that are not valid python identifiers, we need to add a reference to their actual name + # in the back end database + if not REGEX_VALID_TB_FLD.match(field['column_name']): + f['rname'] = "'[%s]'" % field['column_name'] + + return f + + +def is_unique(conn, table, field): + "Find unique columns (incomplete support)" + rows = query(conn, """ + SELECT c.column_name + FROM information_schema.table_constraints t + INNER JOIN information_schema.constraint_column_usage c + ON (t.CONSTRAINT_CATALOG = c.CONSTRAINT_CATALOG + AND t.CONSTRAINT_NAME = c.CONSTRAINT_NAME + AND t.CONSTRAINT_SCHEMA = c.CONSTRAINT_SCHEMA + AND t.TABLE_CATALOG = c.TABLE_CATALOG + AND t.TABLE_NAME = c.TABLE_NAME + AND t.TABLE_SCHEMA = c.TABLE_SCHEMA) + WHERE t.table_name='%s' + AND c.column_name='%s' + AND t.constraint_type='UNIQUE' + ;""", table, field['column_name']) + return rows and True or False + + +def primarykeys(conn, table): + "Find primary keys" + rows = query(conn, """ + SELECT c.column_name + FROM information_schema.table_constraints t + INNER JOIN information_schema.constraint_column_usage c + ON (t.CONSTRAINT_CATALOG = c.CONSTRAINT_CATALOG + AND t.CONSTRAINT_NAME = c.CONSTRAINT_NAME + AND t.CONSTRAINT_SCHEMA = c.CONSTRAINT_SCHEMA + AND t.TABLE_CATALOG = c.TABLE_CATALOG + AND t.TABLE_NAME = c.TABLE_NAME + AND t.TABLE_SCHEMA = c.TABLE_SCHEMA) + WHERE t.table_name='%s' + AND t.constraint_type='PRIMARY KEY' + ;""", table) + return [row['column_name'] for row in rows] + + +def references(conn, table, field): + "Find a FK (fails if multiple)" + rows1 = query(conn, """ + SELECT k.table_name, k.column_name, k.constraint_name, + r.update_rule, r.delete_rule, k.ordinal_position + FROM information_schema.key_column_usage k + INNER JOIN information_schema.referential_constraints r + ON (k.CONSTRAINT_CATALOG = r.CONSTRAINT_CATALOG + AND k.CONSTRAINT_NAME = r.CONSTRAINT_NAME + AND k.CONSTRAINT_SCHEMA = r.CONSTRAINT_SCHEMA) + INNER JOIN information_schema.table_constraints t + ON (r.CONSTRAINT_CATALOG = t.CONSTRAINT_CATALOG + AND r.CONSTRAINT_NAME = t.CONSTRAINT_NAME + AND r.CONSTRAINT_SCHEMA = t.CONSTRAINT_SCHEMA) + + WHERE k.table_name='%s' + AND k.column_name='%s' + AND t.constraint_type='FOREIGN KEY' + ;""", table, field) + if len(rows1) == 1: + rows2 = query(conn, """ + SELECT table_name, column_name, * + FROM information_schema.constraint_column_usage + WHERE constraint_name='%s' + """, rows1[0]['constraint_name']) + row = None + if len(rows2) > 1: + row = rows2[int(rows1[0]['ordinal_position']) - 1] + keyed = True + if len(rows2) == 1: + row = rows2[0] + keyed = False + if row: + if keyed: # THIS IS BAD, DON'T MIX "id" and primarykey!!! + ref = {'type': "'reference %s.%s'" % (row['table_name'], + row['column_name'])} + else: + ref = {'type': "'reference %s'" % (row['table_name'],)} + if rows1[0]['delete_rule'] != "NO ACTION": + ref['ondelete'] = repr(rows1[0]['delete_rule']) + return ref + elif rows2: + raise RuntimeError("Unsupported foreign key reference: %s" % + str(rows2)) + + elif rows1: + raise RuntimeError("Unsupported referential constraint: %s" % + str(rows1)) + + +def define_table(conn, table): + "Output single table definition" + fields = get_fields(conn, table) + pks = primarykeys(conn, table) + print "db.define_table('%s'," % (table,) + for field in fields: + fname = field['column_name'] + fdef = define_field(conn, table, field, pks) + if fname not in pks and is_unique(conn, table, field): + fdef['unique'] = "True" + if fdef['type'] == "'id'" and fname in pks: + pks.pop(pks.index(fname)) + print " Field('%s', %s)," % (get_valid_column_name(fname), + ', '.join(["%s=%s" % (k, fdef[k]) for k in KWARGS + if k in fdef and fdef[k]])) + if pks: + print " primarykey=[%s]," % ", ".join(["'%s'" % pk for pk in pks]) + print " migrate=migrate)" + print + + +def define_db(conn, db, host, port, user, passwd): + "Output database definition (model)" + dal = 'db = DAL("mssql4://%s:%s@%s:%s/%s", pool_size=10, decode_credentials=True)' + print dal % ( + user.replace('@', '%40').replace(':', '%3A'), passwd.replace('@', '%40').replace(':', '%3A'), host, port, db) + print + print "migrate = False" + print + for table in get_tables(conn): + define_table(conn, table) + + +if __name__ == "__main__": + # Parse arguments from command line: + if len(sys.argv) < 6 and COMMAND_LINE_MODE: + print HELP + else: + # Parse arguments from command line: + if COMMAND_LINE_MODE: + db, host, port, user, passwd = sys.argv[1:6] + else: + db = DB + host = HOST + user = USER + passwd = PASSWD + port = PORT + + # Make the database connection (change driver if required) + import pyodbc + # cnn = pyodbc.connect(database=db, host=host, port=port, + # user=user, password=passwd, + # ) + cnn = pyodbc.connect( + r'DRIVER={{SQL Server Native Client 11.0}};SERVER={server};PORT={port};DATABASE={db};UID={user};PWD={passwd}'.format( + server=host, port=port, db=db, user=user, passwd=passwd) + ) + # Start model code generation: + define_db(cnn, db, host, port, user, passwd) diff --git a/web2py/scripts/extract_mysql_models.py b/web2py/scripts/extract_mysql_models.py new file mode 100644 index 0000000..dfaae02 --- /dev/null +++ b/web2py/scripts/extract_mysql_models.py @@ -0,0 +1,120 @@ +''' +Create the web2py code needed to access your mysql legacy db. + +To make this work all the legacy tables you want to access need to have an "id" field. + +This plugin needs: +mysql +mysqldump +installed and globally available. + +Under Windows you will probably need to add the mysql executable directory to the PATH variable, +you will also need to modify mysql to mysql.exe and mysqldump to mysqldump.exe below. +Just guessing here :) + +Access your tables with: +legacy_db(legacy_db.mytable.id>0).select() + +If the script crashes this is might be due to that fact that the data_type_map dictionary below is incomplete. +Please complete it, improve it and continue. + +Created by Falko Krause, minor modifications by Massimo Di Pierro, Ron McOuat and Marvi Benedet +''' +import subprocess +import re +import sys +data_type_map = dict( + varchar='string', + int='integer', + integer='integer', + tinyint='integer', + smallint='integer', + mediumint='integer', + bigint='integer', + float='double', + double='double', + char='string', + decimal='integer', + date='date', + #year = 'date', + time='time', + timestamp='datetime', + datetime='datetime', + binary='blob', + blob='blob', + tinyblob='blob', + mediumblob='blob', + longblob='blob', + text='text', + tinytext='text', + mediumtext='text', + longtext='text', +) + + +def mysql(database_name, username, password, host): + p = subprocess.Popen(['mysql', + '--user=%s' % username, + '--password=%s' % password, + '--host=%s' % host, + '--execute=show tables;', + database_name], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + sql_showtables, stderr = p.communicate() + tables = [re.sub( + '\|\s+([^\|*])\s+.*', '\1', x) for x in sql_showtables.split()[1:]] + connection_string = "legacy_db = DAL('mysql://%s:%s@%s/%s')" % ( + username, password, host, database_name) + legacy_db_table_web2py_code = [] + for table_name in tables: + #get the sql create statement + p = subprocess.Popen(['mysqldump', + '--user=%s' % username, + '--password=%s' % password, + '--host=%s' % host, + '--skip-add-drop-table', + '--no-data', database_name, + table_name], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + sql_create_stmnt, stderr = p.communicate() + if 'CREATE' in sql_create_stmnt: # check if the table exists + #remove garbage lines from sql statement + sql_lines = sql_create_stmnt.split('\n') + sql_lines = filter( + lambda x: not(x in ('','\r') or x[:2] in ('--','/*')), + sql_lines) + #generate the web2py code from the create statement + web2py_table_code = '' + table_name = re.search( + 'CREATE TABLE .(\S+). \(', sql_lines[0]).group(1) + fields = [] + for line in sql_lines[1:-1]: + if re.search('KEY', line) or re.search('PRIMARY', line) or re.search(' ID', line) or line.startswith(')'): + continue + hit = re.search('(\S+)\s+(\S+)(,| )( .*)?', line) + if hit is not None: + name, d_type = hit.group(1), hit.group(2) + d_type = re.sub(r'(\w+)\(.*', r'\1', d_type) + name = re.sub('`', '', name) + web2py_table_code += "\n Field('%s','%s')," % ( + name, data_type_map[d_type]) + web2py_table_code = "legacy_db.define_table('%s',%s\n migrate=False)" % (table_name, web2py_table_code) + legacy_db_table_web2py_code.append(web2py_table_code) + #---------------------------------------- + #write the legacy db to file + legacy_db_web2py_code = connection_string + "\n\n" + legacy_db_web2py_code += "\n\n#--------\n".join( + legacy_db_table_web2py_code) + return legacy_db_web2py_code + +regex = re.compile('(.*):(.*)@((.*)/)?(.*)') +if len(sys.argv) < 2 or not regex.match(sys.argv[1]): + print 'USAGE:\n\n extract_mysql_models.py username:password@[host/]data_basename\n\n' +else: + m = regex.match(sys.argv[1]) + username = m.group(1) + password = m.group(2) + host = m.group(4) or 'localhost' + db_name = m.group(5) + print mysql(database_name = db_name, username = username, password = password, host = host) diff --git a/web2py/scripts/extract_oracle_models.py b/web2py/scripts/extract_oracle_models.py new file mode 100644 index 0000000..3dc9e52 --- /dev/null +++ b/web2py/scripts/extract_oracle_models.py @@ -0,0 +1,312 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""Create web2py model (python code) to represent Oracle 11g tables. + +Features: + +* Uses Oracle's metadata tables +* Detects legacy "keyed" tables (not having an "id" PK) +* Connects directly to running databases, no need to do a SQL dump +* Handles notnull, unique and referential constraints +* Detects most common datatypes and default values +* Documents alternative datatypes as comments + +Requeriments: + +* Needs Oracle cx_Oracle python connector (same as web2py) + + +Created by Oscar Fonts, based on extract_pgsql_models by Mariano Reingart, +based in turn on a script to "generate schemas from dbs" (mysql) +by Alexandre Andrade + +""" + +_author__ = "Oscar Fonts <oscar.fonts@geomati.co>" + +HELP = """ +USAGE: extract_oracle_models db host port user passwd + +Call with Oracle database connection parameters, +web2py model will be printed on standard output. + +EXAMPLE: python extract_oracle_models.py ORCL localhost 1521 user password +""" + +# Config options +DEBUG = False # print debug messages to STDERR + +# Constant for Field keyword parameter order (and filter): +KWARGS = ('type', 'length', 'default', 'required', 'ondelete', + 'notnull', 'unique', 'label', 'comment') + + +import sys + + +def query(conn, sql, *args): + "Execute a SQL query and return rows as a list of dicts" + cur = conn.cursor() + ret = [] + try: + if DEBUG: + print >> sys.stderr, "QUERY: ", sql , args + cur.execute(sql, args) + for row in cur: + dic = {} + for i, value in enumerate(row): + field = cur.description[i][0] + dic[field] = value + if DEBUG: + print >> sys.stderr, "RET: ", dic + ret.append(dic) + return ret + except cx_Oracle.DatabaseError, exc: + error, = exc.args + print >> sys.stderr, "Oracle-Error-Message:", error.message + finally: + cur.close() + + +def get_tables(conn): + "List table names in a given schema" + rows = query(conn, """SELECT TABLE_NAME FROM USER_TABLES + ORDER BY TABLE_NAME""") + return [row['TABLE_NAME'] for row in rows] + + +def get_fields(conn, table): + "Retrieve field list for a given table" + if DEBUG: + print >> sys.stderr, "Processing TABLE", table + rows = query(conn, """ + SELECT COLUMN_NAME, DATA_TYPE, + NULLABLE AS IS_NULLABLE, + CHAR_LENGTH AS CHARACTER_MAXIMUM_LENGTH, + DATA_PRECISION AS NUMERIC_PRECISION, + DATA_SCALE AS NUMERIC_SCALE, + DATA_DEFAULT AS COLUMN_DEFAULT + FROM USER_TAB_COLUMNS + WHERE TABLE_NAME=:t + """, table) + + return rows + + +def define_field(conn, table, field, pks): + "Determine field type, default value, references, etc." + f = {} + ref = references(conn, table, field['COLUMN_NAME']) + # Foreign Keys + if ref: + f.update(ref) + # PK & Numeric & autoincrement => id + elif field['COLUMN_NAME'] in pks and \ + field['DATA_TYPE'] in ('INT', 'NUMBER') and \ + is_autoincrement(conn, table, field): + f['type'] = "'id'" + # Other data types + elif field['DATA_TYPE'] in ('BINARY_DOUBLE'): + f['type'] = "'double'" + elif field['DATA_TYPE'] in ('CHAR','NCHAR'): + f['type'] = "'string'" + f['comment'] = "'Alternative types: boolean, time'" + elif field['DATA_TYPE'] in ('BLOB', 'CLOB'): + f['type'] = "'blob'" + f['comment'] = "'Alternative types: text, json, list:*'" + elif field['DATA_TYPE'] in ('DATE'): + f['type'] = "'datetime'" + f['comment'] = "'Alternative types: date'" + elif field['DATA_TYPE'] in ('FLOAT'): + f['type'] = "'float'" + elif field['DATA_TYPE'] in ('INT'): + f['type'] = "'integer'" + elif field['DATA_TYPE'] in ('NUMBER'): + f['type'] = "'bigint'" + elif field['DATA_TYPE'] in ('NUMERIC'): + f['type'] = "'decimal'" + f['precision'] = field['NUMERIC_PRECISION'] + f['scale'] = field['NUMERIC_SCALE'] or 0 + elif field['DATA_TYPE'] in ('VARCHAR2','NVARCHAR2'): + f['type'] = "'string'" + if field['CHARACTER_MAXIMUM_LENGTH']: + f['length'] = field['CHARACTER_MAXIMUM_LENGTH'] + f['comment'] = "'Other possible types: password, upload'" + else: + f['type'] = "'blob'" + f['comment'] = "'WARNING: Oracle Data Type %s was not mapped." % \ + str(field['DATA_TYPE']) + " Using 'blob' as fallback.'" + + try: + if field['COLUMN_DEFAULT']: + if field['COLUMN_DEFAULT'] == "sysdate": + d = "request.now" + elif field['COLUMN_DEFAULT'].upper() == "T": + d = "True" + elif field['COLUMN_DEFAULT'].upper() == "F": + d = "False" + else: + d = repr(eval(field['COLUMN_DEFAULT'])) + f['default'] = str(d) + except (ValueError, SyntaxError): + pass + except Exception, e: + raise RuntimeError( + "Default unsupported '%s'" % field['COLUMN_DEFAULT']) + + if not field['IS_NULLABLE']: + f['notnull'] = "True" + + return f + + +def is_unique(conn, table, field): + "Find unique columns" + rows = query(conn, """ + SELECT COLS.COLUMN_NAME + FROM USER_CONSTRAINTS CONS, ALL_CONS_COLUMNS COLS + WHERE CONS.OWNER = COLS.OWNER + AND CONS.CONSTRAINT_NAME = COLS.CONSTRAINT_NAME + AND CONS.CONSTRAINT_TYPE = 'U' + AND COLS.TABLE_NAME = :t + AND COLS.COLUMN_NAME = :c + """, table, field['COLUMN_NAME']) + return rows and True or False + + +# Returns True when a "BEFORE EACH ROW INSERT" trigger is found and: +# a) it mentions the "NEXTVAL" keyword (used by sequences) +# b) it operates on the given table and column +# +# On some (inelegant) database designs, SEQUENCE.NEXTVAL is called directly +# from each "insert" statement, instead of using triggers. Such cases cannot +# be detected by inspecting Oracle's metadata tables, as sequences are not +# logically bound to any specific table or field. +def is_autoincrement(conn, table, field): + "Find auto increment fields (best effort)" + rows = query(conn, """ + SELECT TRIGGER_NAME + FROM USER_TRIGGERS, + (SELECT NAME, LISTAGG(TEXT, ' ') WITHIN GROUP (ORDER BY LINE) TEXT + FROM USER_SOURCE + WHERE TYPE = 'TRIGGER' + GROUP BY NAME + ) TRIGGER_DEFINITION + WHERE TRIGGER_NAME = NAME + AND TRIGGERING_EVENT = 'INSERT' + AND TRIGGER_TYPE = 'BEFORE EACH ROW' + AND TABLE_NAME = :t + AND UPPER(TEXT) LIKE UPPER('%.NEXTVAL%') + AND UPPER(TEXT) LIKE UPPER('%:NEW.' || :c || '%') + """, table, field['COLUMN_NAME']) + return rows and True or False + + +def primarykeys(conn, table): + "Find primary keys" + rows = query(conn, """ + SELECT COLS.COLUMN_NAME + FROM USER_CONSTRAINTS CONS, ALL_CONS_COLUMNS COLS + WHERE COLS.TABLE_NAME = :t + AND CONS.CONSTRAINT_TYPE = 'P' + AND CONS.OWNER = COLS.OWNER + AND CONS.CONSTRAINT_NAME = COLS.CONSTRAINT_NAME + """, table) + + return [row['COLUMN_NAME'] for row in rows] + + +def references(conn, table, field): + "Find a FK (fails if multiple)" + rows1 = query(conn, """ + SELECT COLS.CONSTRAINT_NAME, + CONS.DELETE_RULE, + COLS.POSITION AS ORDINAL_POSITION + FROM USER_CONSTRAINTS CONS, ALL_CONS_COLUMNS COLS + WHERE COLS.TABLE_NAME = :t + AND COLS.COLUMN_NAME = :c + AND CONS.CONSTRAINT_TYPE = 'R' + AND CONS.OWNER = COLS.OWNER + AND CONS.CONSTRAINT_NAME = COLS.CONSTRAINT_NAME + """, table, field) + + if len(rows1) == 1: + rows2 = query(conn, """ + SELECT COLS.TABLE_NAME, COLS.COLUMN_NAME + FROM USER_CONSTRAINTS CONS, ALL_CONS_COLUMNS COLS + WHERE CONS.CONSTRAINT_NAME = :k + AND CONS.R_CONSTRAINT_NAME = COLS.CONSTRAINT_NAME + ORDER BY COLS.POSITION ASC + """, rows1[0]['CONSTRAINT_NAME']) + + row = None + if len(rows2) > 1: + row = rows2[int(rows1[0]['ORDINAL_POSITION']) - 1] + keyed = True + if len(rows2) == 1: + row = rows2[0] + keyed = False + if row: + if keyed: # THIS IS BAD, DON'T MIX "id" and primarykey!!! + ref = {'type': "'reference %s.%s'" % (row['TABLE_NAME'], + row['COLUMN_NAME'])} + else: + ref = {'type': "'reference %s'" % (row['TABLE_NAME'],)} + if rows1[0]['DELETE_RULE'] != "NO ACTION": + ref['ondelete'] = repr(rows1[0]['DELETE_RULE']) + return ref + elif rows2: + raise RuntimeError("Unsupported foreign key reference: %s" % + str(rows2)) + + elif rows1: + raise RuntimeError("Unsupported referential constraint: %s" % + str(rows1)) + + +def define_table(conn, table): + "Output single table definition" + fields = get_fields(conn, table) + pks = primarykeys(conn, table) + print "db.define_table('%s'," % (table, ) + for field in fields: + fname = field['COLUMN_NAME'] + fdef = define_field(conn, table, field, pks) + if fname not in pks and is_unique(conn, table, field): + fdef['unique'] = "True" + if fdef['type'] == "'id'" and fname in pks: + pks.pop(pks.index(fname)) + print " Field('%s', %s)," % (fname, + ', '.join(["%s=%s" % (k, fdef[k]) for k in KWARGS + if k in fdef and fdef[k]])) + if pks: + print " primarykey=[%s]," % ", ".join(["'%s'" % pk for pk in pks]) + print " migrate=migrate)" + print + + +def define_db(conn, db, host, port, user, passwd): + "Output database definition (model)" + dal = 'db = DAL("oracle://%s/%s@%s:%s/%s", pool_size=10)' + print dal % (user, passwd, host, port, db) + print + print "migrate = False" + print + for table in get_tables(conn): + define_table(conn, table) + + +if __name__ == "__main__": + if len(sys.argv) < 6: + print HELP + else: + # Parse arguments from command line: + db, host, port, user, passwd = sys.argv[1:6] + + # Make the database connection (change driver if required) + import cx_Oracle + dsn = cx_Oracle.makedsn(host, port, db) + cnn = cx_Oracle.connect(user, passwd, dsn) + # Start model code generation: + define_db(cnn, db, host, port, user, passwd) diff --git a/web2py/scripts/extract_pgsql_models.py b/web2py/scripts/extract_pgsql_models.py new file mode 100644 index 0000000..3c8841a --- /dev/null +++ b/web2py/scripts/extract_pgsql_models.py @@ -0,0 +1,286 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""Create web2py model (python code) to represent PostgreSQL tables. + +Features: + +* Uses ANSI Standard INFORMATION_SCHEMA (might work with other RDBMS) +* Detects legacy "keyed" tables (not having an "id" PK) +* Connects directly to running databases, no need to do a SQL dump +* Handles notnull, unique and referential constraints +* Detects most common datatypes and default values +* Support PostgreSQL columns comments (ie. for documentation) + +Requeriments: + +* Needs PostgreSQL pyscopg2 python connector (same as web2py) +* If used against other RDBMS, import and use proper connector (remove pg_ code) + + +Created by Mariano Reingart, based on a script to "generate schemas from dbs" +(mysql) by Alexandre Andrade + +""" + +_author__ = "Mariano Reingart <reingart@gmail.com>" + +HELP = """ +USAGE: extract_pgsql_models db host port user passwd + +Call with PostgreSQL database connection parameters, +web2py model will be printed on standard output. + +EXAMPLE: python extract_pgsql_models.py mydb localhost 5432 reingart saraza +""" + +# Config options +DEBUG = False # print debug messages to STDERR +SCHEMA = 'public' # change if not using default PostgreSQL schema + +# Constant for Field keyword parameter order (and filter): +KWARGS = ('type', 'length', 'default', 'required', 'ondelete', + 'notnull', 'unique', 'label', 'comment') + + +import sys + + +def query(conn, sql, *args): + "Execute a SQL query and return rows as a list of dicts" + cur = conn.cursor() + ret = [] + try: + if DEBUG: + print >> sys.stderr, "QUERY: ", sql % args + cur.execute(sql, args) + for row in cur: + dic = {} + for i, value in enumerate(row): + field = cur.description[i][0] + dic[field] = value + if DEBUG: + print >> sys.stderr, "RET: ", dic + ret.append(dic) + return ret + finally: + cur.close() + + +def get_tables(conn, schema=SCHEMA): + "List table names in a given schema" + rows = query(conn, """SELECT table_name FROM information_schema.tables + WHERE table_schema = %s + ORDER BY table_name""", schema) + return [row['table_name'] for row in rows] + + +def get_fields(conn, table): + "Retrieve field list for a given table" + if DEBUG: + print >> sys.stderr, "Processing TABLE", table + rows = query(conn, """ + SELECT column_name, data_type, + is_nullable, + character_maximum_length, + numeric_precision, numeric_precision_radix, numeric_scale, + column_default + FROM information_schema.columns + WHERE table_name=%s + ORDER BY ordinal_position""", table) + return rows + + +def define_field(conn, table, field, pks): + "Determine field type, default value, references, etc." + f = {} + ref = references(conn, table, field['column_name']) + if ref: + f.update(ref) + elif field['column_default'] and \ + field['column_default'].startswith("nextval") and \ + field['column_name'] in pks: + # postgresql sequence (SERIAL) and primary key! + f['type'] = "'id'" + elif field['data_type'].startswith('character'): + f['type'] = "'string'" + if field['character_maximum_length']: + f['length'] = field['character_maximum_length'] + elif field['data_type'] in ('text', ): + f['type'] = "'text'" + elif field['data_type'] in ('boolean', 'bit'): + f['type'] = "'boolean'" + elif field['data_type'] in ('integer', 'smallint', 'bigint'): + f['type'] = "'integer'" + elif field['data_type'] in ('double precision', 'real'): + f['type'] = "'double'" + elif field['data_type'] in ('timestamp', 'timestamp without time zone'): + f['type'] = "'datetime'" + elif field['data_type'] in ('date', ): + f['type'] = "'date'" + elif field['data_type'] in ('time', 'time without time zone'): + f['type'] = "'time'" + elif field['data_type'] in ('numeric', 'currency'): + f['precision'] = field['numeric_precision'] + f['scale'] = field['numeric_scale'] or 0 + f['type'] = "'decimal({},{})'".format(f['precision'],f['scale']) + elif field['data_type'] in ('bytea', ): + f['type'] = "'blob'" + elif field['data_type'] in ('point', 'lseg', 'polygon', 'unknown', 'USER-DEFINED'): + f['type'] = "" # unsupported? + else: + raise RuntimeError("Data Type not supported: %s " % str(field)) + + try: + if field['column_default']: + if field['column_default'] == "now()": + d = "request.now" + elif field['column_default'] == "true": + d = "True" + elif field['column_default'] == "false": + d = "False" + else: + d = repr(eval(field['column_default'])) + f['default'] = str(d) + except (ValueError, SyntaxError): + pass + except Exception, e: + raise RuntimeError( + "Default unsupported '%s'" % field['column_default']) + + if not field['is_nullable']: + f['notnull'] = "True" + + comment = get_comment(conn, table, field) + if comment is not None: + f['comment'] = repr(comment) + return f + + +def is_unique(conn, table, field): + "Find unique columns (incomplete support)" + rows = query(conn, """ + SELECT information_schema.constraint_column_usage.column_name + FROM information_schema.table_constraints + NATURAL JOIN information_schema.constraint_column_usage + WHERE information_schema.table_constraints.table_name=%s + AND information_schema.constraint_column_usage.column_name=%s + AND information_schema.table_constraints.constraint_type='UNIQUE' + ;""", table, field['column_name']) + return rows and True or False + + +def get_comment(conn, table, field): + "Find the column comment (postgres specific)" + rows = query(conn, """ + SELECT d.description AS comment + FROM pg_class c + JOIN pg_description d ON c.oid=d.objoid + JOIN pg_attribute a ON c.oid = a.attrelid + WHERE c.relname=%s AND a.attname=%s + AND a.attnum = d.objsubid + ;""", table, field['column_name']) + return rows and rows[0]['comment'] or None + + +def primarykeys(conn, table): + "Find primary keys" + rows = query(conn, """ + SELECT information_schema.constraint_column_usage.column_name + FROM information_schema.table_constraints + NATURAL JOIN information_schema.constraint_column_usage + WHERE information_schema.table_constraints.table_name=%s + AND information_schema.table_constraints.constraint_type='PRIMARY KEY' + ;""", table) + return [row['column_name'] for row in rows] + + +def references(conn, table, field): + "Find a FK (fails if multiple)" + rows1 = query(conn, """ + SELECT table_name, column_name, constraint_name, + update_rule, delete_rule, ordinal_position + FROM information_schema.key_column_usage + NATURAL JOIN information_schema.referential_constraints + NATURAL JOIN information_schema.table_constraints + WHERE information_schema.key_column_usage.table_name=%s + AND information_schema.key_column_usage.column_name=%s + AND information_schema.table_constraints.constraint_type='FOREIGN KEY' + ;""", table, field) + if len(rows1) == 1: + rows2 = query(conn, """ + SELECT table_name, column_name, * + FROM information_schema.constraint_column_usage + WHERE constraint_name=%s + """, rows1[0]['constraint_name']) + row = None + if len(rows2) > 1: + row = rows2[int(rows1[0]['ordinal_position']) - 1] + keyed = True + if len(rows2) == 1: + row = rows2[0] + keyed = False + if row: + if keyed: # THIS IS BAD, DON'T MIX "id" and primarykey!!! + ref = {'type': "'reference %s.%s'" % (row['table_name'], + row['column_name'])} + else: + ref = {'type': "'reference %s'" % (row['table_name'],)} + if rows1[0]['delete_rule'] != "NO ACTION": + ref['ondelete'] = repr(rows1[0]['delete_rule']) + return ref + elif rows2: + raise RuntimeError("Unsupported foreign key reference: %s" % + str(rows2)) + + elif rows1: + raise RuntimeError("Unsupported referential constraint: %s" % + str(rows1)) + + +def define_table(conn, table): + "Output single table definition" + fields = get_fields(conn, table) + pks = primarykeys(conn, table) + print "db.define_table('%s'," % (table, ) + for field in fields: + fname = field['column_name'] + fdef = define_field(conn, table, field, pks) + if fname not in pks and is_unique(conn, table, field): + fdef['unique'] = "True" + if fdef['type'] == "'id'" and fname in pks: + pks.pop(pks.index(fname)) + print " Field('%s', %s)," % (fname, + ', '.join(["%s=%s" % (k, fdef[k]) for k in KWARGS + if k in fdef and fdef[k]])) + if pks: + print " primarykey=[%s]," % ", ".join(["'%s'" % pk for pk in pks]) + print " migrate=migrate)" + print + + +def define_db(conn, db, host, port, user, passwd): + "Output database definition (model)" + dal = 'db = DAL("postgres://%s:%s@%s:%s/%s", pool_size=10)' + print dal % (user, passwd, host, port, db) + print + print "migrate = False" + print + for table in get_tables(conn): + define_table(conn, table) + + +if __name__ == "__main__": + if len(sys.argv) < 6: + print HELP + else: + # Parse arguments from command line: + db, host, port, user, passwd = sys.argv[1:6] + + # Make the database connection (change driver if required) + import psycopg2 + cnn = psycopg2.connect(database=db, host=host, port=port, + user=user, password=passwd, + ) + # Start model code generation: + define_db(cnn, db, host, port, user, passwd) diff --git a/web2py/scripts/extract_sqlite_models.py b/web2py/scripts/extract_sqlite_models.py new file mode 100644 index 0000000..d5fad50 --- /dev/null +++ b/web2py/scripts/extract_sqlite_models.py @@ -0,0 +1,113 @@ +# -*- coding: utf-8 -*- + +''' +Create the web2py model code needed to access your sqlite legacy db. + +Usage: +python extract_sqlite_models.py + +Access your tables with: +legacy_db(legacy_db.mytable.id>0).select() + + +extract_sqlite_models.py -- Copyright (C) Michele Comitini +This code is distributed with web2py. + +The regexp code and the dictionary type map was extended from +extact_mysql_models.py that comes with web2py. extact_mysql_models.py is Copyright (C) Falko Krause. + +''' +import re +import sys +import sqlite3 + +data_type_map = dict( + varchar='string', + int='integer', + integer='integer', + tinyint='integer', + smallint='integer', + mediumint='integer', + bigint='integer', + float='double', + double='double', + char='string', + decimal='integer', + date='date', + time='time', + timestamp='datetime', + datetime='datetime', + binary='blob', + blob='blob', + tinyblob='blob', + mediumblob='blob', + longblob='blob', + text='text', + tinytext='text', + mediumtext='text', + longtext='text', + bit='boolean', + nvarchar='text', + numeric='decimal(30,15)', + real='decimal(30,15)', +) + +def get_foreign_keys(sql_lines): + fks = dict() + for line in sql_lines[1:-1]: + hit = re.search(r'FOREIGN\s+KEY\s+\("(\S+)"\)\s+REFERENCES\s+"(\S+)"\s+\("(\S+)"\)', line) + if hit: + fks[hit.group(1)] = hit.groups()[1:] + + return fks + +def sqlite(database_name): + conn = sqlite3.connect(database_name) + c = conn.cursor() + r = c.execute(r"select name,sql from sqlite_master where type='table' and not name like '\_%' and not lower(name) like 'sqlite_%'") + tables = r.fetchall() + connection_string = "legacy_db = DAL('sqlite://%s')" % database_name.split('/')[-1] + legacy_db_table_web2py_code = [] + for table_name, sql_create_stmnt in tables: + if table_name.startswith('_'): + continue + if 'CREATE' in sql_create_stmnt: # check if the table exists + #remove garbage lines from sql statement + sql_lines = sql_create_stmnt.split('\n') + sql_lines = [x for x in sql_lines if not( + x.startswith('--') or x.startswith('/*') or x == '')] + #generate the web2py code from the create statement + web2py_table_code = '' + fields = [] + fks = get_foreign_keys(sql_lines) + for line in sql_lines[1:-1]: + if re.search('KEY', line) or re.search('PRIMARY', line) or re.search('"ID"', line) or line.startswith(')'): + continue + hit = re.search(r'\[(\S+)\]\s+(\w+(\(\S+\))?),?( .*)?', line) + if hit is not None: + name, d_type = hit.group(1), hit.group(2) + d_type = re.sub(r'(\w+)\(.*', r'\1', d_type) + name = unicode(re.sub('`', '', name)) + if name in fks.keys(): + if fks[name][1].lower() == 'id': + field_type = 'reference %s' % (fks[name][0]) + else: + field_type = 'reference %s.%s' % (fks[name][0], fks[name][1]) + else: + field_type = data_type_map[d_type.lower()] + web2py_table_code += "\n Field('%s','%s')," % ( + name, field_type) + web2py_table_code = "legacy_db.define_table('%s',%s\n migrate=False)" % (table_name, web2py_table_code) + legacy_db_table_web2py_code.append(web2py_table_code) + #---------------------------------------- + #write the legacy db to file + legacy_db_web2py_code = connection_string + "\n\n" + legacy_db_web2py_code += "\n\n#--------\n".join( + legacy_db_table_web2py_code) + return legacy_db_web2py_code + +if len(sys.argv) < 2: + print 'USAGE:\n\n extract_mysql_models.py data_basename\n\n' +else: + print "# -*- coding: utf-8 -*-" + print sqlite(sys.argv[1]) diff --git a/web2py/scripts/fixws.py b/web2py/scripts/fixws.py new file mode 100644 index 0000000..706a413 --- /dev/null +++ b/web2py/scripts/fixws.py @@ -0,0 +1,27 @@ +import sys +import glob + + +def read_fileb(filename, mode='rb'): + f = open(filename, mode) + try: + return f.read() + finally: + f.close() + + +def write_fileb(filename, value, mode='wb'): + f = open(filename, mode) + try: + f.write(value) + finally: + f.close() + +for filename in glob.glob(sys.argv[1]): + data1 = read_fileb(filename) + write_fileb(filename + '.bak2', data1) + data2lines = read_fileb(filename).strip().split('\n') + data2 = '\n'.join([line.rstrip( + ).replace('\t', ' ' * 2) for line in data2lines]) + '\n' + write_fileb(filename, data2) + print filename, len(data1) - len(data2) diff --git a/web2py/scripts/import_static.py b/web2py/scripts/import_static.py new file mode 100644 index 0000000..d4ba0bc --- /dev/null +++ b/web2py/scripts/import_static.py @@ -0,0 +1,103 @@ +""" +converts a static file to a web2py view. needs work +""" +import os +import sys +import glob +import shutil +import re + +regex_link = re.compile("""(href|src)\s*=\s*("|')(.+?)("|')""") + +def getname(filename): + return re.compile('\W').sub('',filename.split('/')[-1].rsplit('.',1)[0]) + +def make_controller(html_files): + controller = '' + for filename in html_files: + name = getname(filename) + controller += 'def %s():\n return locals()\n\n' % name + return controller + +def fix_links(html,prefix): + def fix(match): + href,link = match.group(1), match.group(3) + if not '://' in link: + if link.lower().endswith('.html') and not '/' in link: + link = "{{=URL('%s','%s')}}" % (prefix, getname(link)) + elif link.startswith('./'): + link = "{{=URL('static','%s/%s')}}" % (prefix,link[2:]) + elif link.startswith('/'): + link = "{{=URL('static','%s/%s')}}" % (prefix,link[1:]) + else: + link = "{{=URL('static','%s/%s')}}" % (prefix,link) + return '%s="%s"' % (href,link) + return regex_link.sub(fix,html) + +def make_views(html_files,prefix): + views = {} + layout_name = os.path.join(prefix,'layout.html') + extend = "{{extend '%s'}}" % layout_name + for filename in html_files: + html = open(filename).read() + name = getname(filename) + views[os.path.join(prefix,name+'.html')] = fix_links(html,prefix) + start = stop = None + k = 0 + while start is None or stop is None: + try: + if start is None: + if len(set(v[k] for v in views.values()))>1: + start=k + if stop is None: + if len(set(v[len(v)-k] for v in views.values()))>1: + stop=k + except: + if start is None: + start = k + if stop is None: + stop = k + k+=1 + header = footer = '' + for name in views: + html = views[name] + n = len(html) + header, views[name], footer = \ + html[:start], extend+html[start:n-stop], html[n-stop:] + layout_html = header+'{{include}}'+footer + views[layout_name] = layout_html + return views + +def recursive_overwrite(src, dest, ignore=None): + if os.path.isdir(src): + if not os.path.isdir(dest): + os.makedirs(dest) + files = os.listdir(src) + if ignore is not None: + ignored = ignore(src, files) + else: + ignored = set() + for f in files: + if f not in ignored: + recursive_overwrite(os.path.join(src, f), + os.path.join(dest, f), + ignore) + else: + shutil.copyfile(src, dest) + +def convert(source, destination,prefix='imported'): + html_files = glob.glob(os.path.join(source,'*.html')) + static_folder = os.path.join(destination,'static',prefix) + recursive_overwrite(source,static_folder) + controller = make_controller(html_files) + views = make_views(html_files,prefix) + controller_filename = os.path.join(destination,'controllers',prefix+'.py') + + open(controller_filename,'w').write(controller) + for name in views: + fullname = os.path.join(destination,'views',name) + if not os.path.exists(os.path.split(fullname)[0]): + os.makedirs(os.path.split(fullname)[0]) + open(fullname,'w').write(views[name]) + +convert(sys.argv[1],sys.argv[2]) diff --git a/web2py/scripts/lang_update_from_langfile.py b/web2py/scripts/lang_update_from_langfile.py new file mode 100644 index 0000000..520341d --- /dev/null +++ b/web2py/scripts/lang_update_from_langfile.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +This script will update untranslated messages in target from source (target and source are both language files) +Usage: + this can be used as first step when creating language file for new but very similar language + or if you want update your app from welcome app of newer web2py version + or in non-standard scenarios when you work on target and from any reason you have partial translation in source +""" + +import sys +import os +sys.path.append(os.path.join(*__file__.split(os.sep)[:-2] or ['.'])) + +from gluon.languages import update_from_langfile +import argparse + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Use to set untranslated messages in the translation file from another one.') + parser.add_argument( + '-t', '--target', + required=True, + dest="target", + help="Specify language file (rw) where untranslated messages will be updated if possible" + ) + parser.add_argument( + '-s', '--source', + required=True, + dest="source", + help="Specify language file (ro) where seek for translations" + ) + parser.add_argument( + '-f', '--force-update', + dest="force_update", + action="store_true", + default=False, + help="without it: add new + translate untranslated, if used: in addition update items if translation differs" + ) + args = parser.parse_args() + + update_from_langfile(args.target, args.source, force_update=args.force_update) + + print '%s was updated.' % args.target diff --git a/web2py/scripts/make_min_web2py.py b/web2py/scripts/make_min_web2py.py new file mode 100644 index 0000000..2fef642 --- /dev/null +++ b/web2py/scripts/make_min_web2py.py @@ -0,0 +1,97 @@ +USAGE = """ +from web2py main folder +python scripts/make_min_web2py.py /path/to/minweb2py + +it will mkdir minweb2py and build a minimal web2py installation +- no admin, no examples, one line welcome +- no scripts +- drops same rarely used contrib modules +- more modules could be dropped but minimal difference +""" + +# files to include from top level folder (default.py will be rebuilt) +REQUIRED = """ +VERSION +web2py.py +anyserver.py +applications/__init__.py +applications/welcome/controllers/default.py +handlers/fcgihandler.py +handlers/gaehandler.py +handlers/wsgihandler.py +""" + +# files and folders to exclude from gluon folder (comment with # if needed) +IGNORED = """ +gluon/contrib/websocket_messaging.py +gluon/contrib/feedparser.py +gluon/contrib/generics.py +gluon/contrib/gql.py +gluon/contrib/populate.py +gluon/contrib/sms_utils.py +gluon/contrib/spreadsheet.py +gluon/tests/ +gluon/contrib/markdown/ +gluon/contrib/pyfpdf/ +gluon/contrib/pymysql/ +gluon/contrib/pyrtf/ +gluon/contrib/pysimplesoap/ +""" + +import sys +import os +import shutil +import glob + + +def main(): + global REQUIRED, IGNORED + + if len(sys.argv) < 2: + print USAGE + + # make target folder + target = sys.argv[1] + os.mkdir(target) + + # change to os specificsep + REQUIRED = REQUIRED.replace('/', os.sep) + IGNORED = IGNORED.replace('/', os.sep) + + # make a list of all files to include + files = [x.strip() for x in REQUIRED.split('\n') + if x and not x[0] == '#'] + ignore = [x.strip() for x in IGNORED.split('\n') + if x and not x[0] == '#'] + + def accept(filename): + for p in ignore: + if filename.startswith(p): + return False + return True + pattern = os.path.join('gluon', '*.py') + while True: + newfiles = [x for x in glob.glob(pattern) if accept(x)] + if not newfiles: + break + files += newfiles + pattern = os.path.join(pattern[:-3], '*.py') + # copy all files, make missing folder, build default.py + files.sort() + defaultpy = os.path.join( + 'applications', 'welcome', 'controllers', 'default.py') + for f in files: + dirs = f.split(os.path.sep) + for i in range(1, len(dirs)): + try: + os.mkdir(target + os.sep + os.path.join(*dirs[:i])) + except OSError: + pass + if f == defaultpy: + open(os.path.join( + target, f), 'w').write('def index(): return "hello"\n') + else: + shutil.copyfile(f, os.path.join(target, f)) + +if __name__ == '__main__': + main() diff --git a/web2py/scripts/parse_top_level_domains.py b/web2py/scripts/parse_top_level_domains.py new file mode 100644 index 0000000..06590af --- /dev/null +++ b/web2py/scripts/parse_top_level_domains.py @@ -0,0 +1,41 @@ +#!/bin/env python +# -*- coding: utf-8 -*- +""" +Use to update official_top_level_domains in gluon/validators.py +""" + +import itertools +import operator +import urllib2 + +LIMIT = 70 +PREFIX = ' ' +TLDS_URL = 'http://data.iana.org/TLD/tlds-alpha-by-domain.txt' + +resp = urllib2.urlopen(TLDS_URL) +content = resp.read() + +valid_lines = [a.strip().lower() for a in content.split('\n') if a.strip() and a.strip()[0] != '#'] +valid_lines += ['localhost'] + +print 'Fetched TLDs are %s' % len(valid_lines) + +results = [list(g) for k, g in itertools.groupby(sorted(valid_lines), key=operator.itemgetter(0))] + +output = [] +line = "'%s', " + +for a in results: + output.append('%s# %s' % (PREFIX, a[-1][0])) + thisline = PREFIX + for c in a: + newline = thisline + line % c + if len(newline) > 70: + output.append(thisline[:-1]) + thisline = PREFIX + line % c + else: + thisline += line % c + if thisline: + output.append(thisline[:-1]) + +print '[\n' + '\n'.join(output)[:-1] + '\n]' diff --git a/web2py/scripts/rmorphans.py b/web2py/scripts/rmorphans.py new file mode 100644 index 0000000..8b50ef6 --- /dev/null +++ b/web2py/scripts/rmorphans.py @@ -0,0 +1,25 @@ +import os +import sys +paths = [sys.argv[1]] +paths1 = [] +paths2 = [] +while paths: + path = paths.pop() + for filename in os.listdir(path): + fullname = os.path.join(path, filename) + if os.path.isdir(fullname): + paths.append(fullname) + else: + extension = filename.split('.')[-1] + if extension.lower() in ('png', 'gif', 'jpg', 'jpeg', 'js', 'css'): + paths1.append((filename, fullname)) + if extension.lower() in ('css', 'js', 'py', 'html'): + paths2.append(fullname) +for filename, fullname in paths1: + for otherfullname in paths2: + if open(otherfullname).read().find(filename) >= 0: + break + else: + print fullname + # os.system('hg rm '+fullname) + # os.system('rm '+fullname) diff --git a/web2py/scripts/sessions2trash.py b/web2py/scripts/sessions2trash.py new file mode 100644 index 0000000..228cf73 --- /dev/null +++ b/web2py/scripts/sessions2trash.py @@ -0,0 +1,259 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +sessions2trash.py + +Run this script in a web2py environment shell e.g. python web2py.py -S app +If models are loaded (-M option) auth.settings.expiration is assumed +for sessions without an expiration. If models are not loaded, sessions older +than 60 minutes are removed. Use the --expiration option to override these +values. + +Typical usage: + + # Delete expired sessions every 5 minutes + nohup python web2py.py -S app -M -R scripts/sessions2trash.py & + + # Delete sessions older than 60 minutes regardless of expiration, + # with verbose output, then exit. + python web2py.py -S app -M -R scripts/sessions2trash.py -A -o -x 3600 -f -v + + # Delete all sessions regardless of expiry and exit. + python web2py.py -S app -M -R scripts/sessions2trash.py -A -o -x 0 + + # Delete session in a module (move to the modules folder) + from sessions2trash import single_loop + def delete_sessions(): + single_loop(auth.settings.expiration) + +Command lines options specific to session2trash.py: +NOTE: They should be preceeded by web2py command line option "-A" to be passed to script. + +-f, --force : Ignore session expiration. Force expiry based on -x option or auth.settings.expiration. +-o, --once : Delete sessions, then exit. Essential when trigger trash sessions from system CRON JOB +-s, --sleep : Number of seconds to sleep between executions. Default 300. +-v, --verbose : print verbose output, a second -v increases verbosity +-x, --expiration : Expiration value for sessions without expiration (in seconds) +""" + +from __future__ import with_statement + +from gluon import current +from gluon.storage import Storage +from gluon._compat import pickle +from optparse import OptionParser +import datetime +import stat +import time +import os + +EXPIRATION_MINUTES = 60 +SLEEP_MINUTES = 5 +VERSION = 0.3 + + +class SessionSet(object): + """Class representing a set of sessions""" + + def __init__(self, expiration, force, verbose): + self.expiration = expiration + self.force = force + self.verbose = verbose + + def get(self): + """Get session files/records.""" + raise NotImplementedError + + def trash(self): + """Trash expired sessions.""" + now = datetime.datetime.now() + for item in self.get(): + status = 'OK' + last_visit = item.last_visit_default() + + try: + session = item.get() + if session.auth: + if session.auth.expiration and not self.force: + self.expiration = session.auth.expiration + if session.auth.last_visit: + last_visit = session.auth.last_visit + except: + pass + + age = 0 + if last_visit: + age = total_seconds(now - last_visit) + + if age > self.expiration or not self.expiration: + item.delete() + status = 'trashed' + + if self.verbose > 1: + print('key: %s' % str(item)) + print('expiration: %s seconds' % self.expiration) + print('last visit: %s' % str(last_visit)) + print('age: %s seconds' % age) + print('status: %s' % status) + print('') + elif self.verbose > 0: + print('%s %s' % (str(item), status)) + + +class SessionSetDb(SessionSet): + """Class representing a set of sessions stored in database""" + + def __init__(self, expiration, force, verbose): + SessionSet.__init__(self, expiration, force, verbose) + + def get(self): + """Return list of SessionDb instances for existing sessions.""" + table = current.response.session_db_table + if table: + for row in table._db(table.id > 0).select(): + yield SessionDb(row) + + +class SessionSetFiles(SessionSet): + """Class representing a set of sessions stored in flat files""" + + def __init__(self, expiration, force, verbose): + SessionSet.__init__(self, expiration, force, verbose) + + def cleanup_empty_folders(self, root_path): + for path, dirs, files in os.walk(root_path, topdown=False): + for d in dirs: + dd = os.path.join(path, d) + if not os.listdir(dd): + os.rmdir(dd) + + def get(self): + """Return list of SessionFile instances for existing sessions.""" + root_path = os.path.join(current.request.folder, 'sessions') + for path, dirs, files in os.walk(root_path, topdown=False): + for x in files: + yield SessionFile(os.path.join(path, x)) + self.cleanup_empty_folders(root_path) + + +class SessionDb(object): + """Class representing a single session stored in database""" + + def __init__(self, row): + self.row = row + + def delete(self): + table = current.response.session_db_table + self.row.delete_record() + table._db.commit() + + def get(self): + session = Storage() + session.update(pickle.loads(self.row.session_data)) + return session + + def last_visit_default(self): + if isinstance(self.row.modified_datetime, datetime.datetime): + return self.row.modified_datetime + else: + try: + return datetime.datetime.strptime(self.row.modified_datetime, '%Y-%m-%d %H:%M:%S.%f') + except: + print('failed to retrieve last modified time (value: %s)' % self.row.modified_datetime) + + def __str__(self): + return self.row.unique_key + + +class SessionFile(object): + """Class representing a single session stored as a flat file""" + + def __init__(self, filename): + self.filename = filename + + def delete(self): + try: + os.unlink(self.filename) + except: + pass + + def get(self): + session = Storage() + with open(self.filename, 'rb+') as f: + session.update(cPickle.load(f)) + return session + + def last_visit_default(self): + return datetime.datetime.fromtimestamp( + os.stat(self.filename)[stat.ST_MTIME]) + + def __str__(self): + return self.filename + + +def total_seconds(delta): + """ + Adapted from Python 2.7's timedelta.total_seconds() method. + + Args: + delta: datetime.timedelta instance. + """ + return (delta.microseconds + (delta.seconds + (delta.days * 24 * 3600)) * + 10 ** 6) / 10 ** 6 + +def single_loop(expiration=None, force=False, verbose=False): + if expiration is None: + try: + expiration = auth.settings.expiration + except: + expiration = EXPIRATION_MINUTES * 60 + + set_files = SessionSetFiles(expiration, force, verbose) + set_files.trash() + set_db = SessionSetDb(expiration, force, verbose) + set_db.trash() + + +def main(): + """Main processing.""" + + usage = '%prog [options]' + '\nVersion: %s' % VERSION + parser = OptionParser(usage=usage) + + parser.add_option('-f', '--force', + action='store_true', dest='force', default=False, + help=('Ignore session expiration. ' + 'Force expiry based on -x option or auth.settings.expiration.') + ) + parser.add_option('-o', '--once', + action='store_true', dest='once', default=False, + help='Delete sessions, then exit.', + ) + parser.add_option('-s', '--sleep', + dest='sleep', default=SLEEP_MINUTES * 60, type="int", + help='Number of seconds to sleep between executions. Default 300.', + ) + parser.add_option('-v', '--verbose', + default=0, action='count', + help="print verbose output, a second -v increases verbosity") + parser.add_option('-x', '--expiration', + dest='expiration', default=None, type="int", + help='Expiration value for sessions without expiration (in seconds)', + ) + + (options, unused_args) = parser.parse_args() + + expiration = options.expiration + + while True: + single_loop(expiration, options.force, options.verbose) + + if options.once: + break + else: + if options.verbose: + print('Sleeping %s seconds' % (options.sleep)) + time.sleep(options.sleep) + +if __name__ == '__main__': + main() diff --git a/web2py/scripts/setup-scheduler-centos.sh b/web2py/scripts/setup-scheduler-centos.sh new file mode 100644 index 0000000..713f699 --- /dev/null +++ b/web2py/scripts/setup-scheduler-centos.sh @@ -0,0 +1,66 @@ +#!/bin/sh +# +# Author: Tyrone Hattingh +# web2py issue: http://code.google.com/p/web2py/issues/detail?id=867 +# +# 1) vi web2py-scheduler +# 2) Paste in the above +# 3) Add in the following 2 lines in the web2py-scheduler file +# (required for centos i believe): +# +# # chkconfig: 2345 90 10 +# # description: web2py-scheduler +# +# 4) make it executable with +# +# chmod 755 web2py-scheduler +# +# 5) add it to startup with +# +# chkconfig --add web2py-scheduler +# + +DAEMON=/usr/local/bin/python +PARAMETERS="/var/www/html/web2py/web2py.py -K init" +LOGFILE=/var/log/web2py-scheduler.log + +start() { + echo -n "starting up $DAEMON" + RUN=`$DAEMON $PARAMETERS > $LOGFILE 2>&1` + if [ "$?" -eq 0 ]; then + echo " Done." + else + echo " FAILED." + fi +} +stop() { + killall $DAEMON +} +status() { + killall -0 $DAEMON + if [ "$?" -eq 0 ]; then + echo "Running." + else + echo "Not Running." + fi +} +case "$1" in + start) + start + ;; + restart) + stop + sleep 2 + start + ;; + stop) + stop + ;; + status) + status + ;; + *) + echo "usage : $0 start|restart|stop|status" + ;; +esac +exit 0 diff --git a/web2py/scripts/setup-web2py-centos7.sh b/web2py/scripts/setup-web2py-centos7.sh new file mode 100644 index 0000000..6b74400 --- /dev/null +++ b/web2py/scripts/setup-web2py-centos7.sh @@ -0,0 +1,302 @@ +echo "This script will: +1) Install modules needed to run web2py on Fedora and CentOS/RHEL +2) Install Python 2.6 to /opt and recompile wsgi if not provided +2) Install web2py in /opt/web-apps/ +3) Configure SELinux and iptables +5) Create a self signed ssl certificate +6) Setup web2py with mod_wsgi +7) Create virtualhost entries so that web2py responds for '/' +8) Restart Apache. + +You should probably read this script before running it. + +Although SELinux permissions changes have been made, +further SELinux changes will be required for your personal +apps. (There may also be additional changes required for the +bundled apps.) As a last resort, SELinux can be disabled. + +A simple iptables configuration has been applied. You may +want to review it to verify that it meets your needs. + +Finally, if you require a proxy to access the Internet, please +set up your machine to do so before running this script. + +(author: berubejd) + +Press ENTER to continue...[ctrl+C to abort]" + +read CONFIRM + +#!/bin/bash + +# (modified for centos7: Dragan (spamperakojotgenije@gmail.com) + +### +### Phase 0 - This may get messy. Lets work from a temporary directory +### + +current_dir=`pwd` + +if [ -d /tmp/setup-web2py/ ]; then + mv /tmp/setup-web2py/ /tmp/setup-web2py.old/ +fi + +mkdir -p /tmp/setup-web2py +cd /tmp/setup-web2py + +### +### Phase 1 - Requirements installation +### + +echo +echo " - Installing packages" +echo + +# Verify packages are up to date +yum update + +# Install required packages +yum install httpd mod_ssl mod_wsgi wget python unzip + +### +### Phase 2 - Install web2py +### + +echo +echo " - Downloading, installing, and starting web2py" +echo + +# Create web-apps directory, if required +if [ ! -d "/opt/web-apps" ]; then + mkdir -p /opt/web-apps + + chmod 755 /opt + chmod 755 /opt/web-apps +fi + +cd /opt/web-apps + +# Download web2py +if [ -e web2py_src.zip* ]; then + rm web2py_src.zip* +fi + +wget http://web2py.com/examples/static/web2py_src.zip +unzip web2py_src.zip +mv web2py/handlers/wsgihandler.py web2py/wsgihandler.py +chown -R apache:apache web2py + +### +### Phase 3 - Setup SELinux context +### +### SELinux doesn't behave well with web2py, for details +### see https://groups.google.com/forum/?fromgroups#!searchin/web2py/selinux/web2py/_thPGA9YhK4/dSnvF3D_lswJ +### +### For now you'll have to disable SELinux + + +# Allow http_tmp_exec required for wsgi +RETV=`setsebool -P httpd_tmp_exec on > /dev/null 2>&1; echo $?` +if [ ! ${RETV} -eq 0 ]; then + # CentOS doesn't support httpd_tmp_exec + cd /tmp/setup-web2py + + # Create the SELinux policy +cat > httpd.te <<EOF + +module httpd 1.0; + +require { + type httpd_t; + class process execmem; +} + +#============= httpd_t ============== +allow httpd_t self:process execmem; +EOF + + checkmodule -M -m -o httpd.mod httpd.te + semodule_package -o httpd.pp -m httpd.mod + semodule -i httpd.pp + +fi + +# Setup the overall web2py SELinux context +cd /opt +chcon -R -t httpd_user_content_t web-apps/ + +cd /opt/web-apps/web2py/applications + +# Setup the proper context on the writable application directories +for app in `ls` +do + for dir in databases cache errors sessions private uploads + do + mkdir ${app}/${dir} + chown apache:apache ${app}/${dir} + chcon -R -t tmp_t ${app}/${dir} + done +done + + +### +### Phase 4 - Configure iptables +### + +cd /tmp/setup-web2py + +# Create rules file - based upon +# http://articles.slicehost.com/assets/2007/9/4/iptables.txt + +# centos7 uses firewalld + +firewall-cmd --zone=public --add-port=80/tcp --permanent +firewall-cmd --zone=public --add-port=443/tcp --permanent +firewall-cmd --zone=public --add-port=22/tcp --permanent + +firewall-cmd --reload + +### +### Phase 5 - Setup SSL +### + +echo +echo " - Creating a self signed certificate" +echo + +# Verify ssl directory exists +if [ ! -d "/etc/httpd/ssl" ]; then + mkdir -p /etc/httpd/ssl +fi + +# Generate and protect certificate +openssl genrsa 1024 > /etc/httpd/ssl/self_signed.key +openssl req -new -x509 -nodes -sha1 -days 365 -key /etc/httpd/ssl/self_signed.key > /etc/httpd/ssl/self_signed.cert +openssl x509 -noout -fingerprint -text < /etc/httpd/ssl/self_signed.cert > /etc/httpd/ssl/self_signed.info + +chmod 400 /etc/httpd/ssl/self_signed.* + +### +### Phase 6 - Configure Apache +### + +echo +echo " - Configure Apache to use mod_wsgi" +echo + +# Create config +if [ -e /etc/httpd/conf.d/welcome.conf ]; then + mv /etc/httpd/conf.d/welcome.conf /etc/httpd/conf.d/welcome.conf.disabled +fi + +cat > /etc/httpd/conf.d/default.conf <<EOF + +NameVirtualHost *:80 +NameVirtualHost *:443 + +<VirtualHost *:80> + WSGIDaemonProcess web2py user=apache group=apache + WSGIProcessGroup web2py + WSGIScriptAlias / /opt/web-apps/web2py/wsgihandler.py + WSGIPassAuthorization On + + <Directory /opt/web-apps/web2py> + AllowOverride None + Order Allow,Deny + Deny from all + <Files wsgihandler.py> + Require all granted + Allow from all + </Files> + </Directory> + + AliasMatch ^/([^/]+)/static/(?:_[\d]+.[\d]+.[\d]+/)?(.*) /opt/web-apps/web2py/applications/\$1/static/\$2 + + <Directory /opt/web-apps/web2py/applications/*/static> + Options -Indexes + Order Allow,Deny + Allow from all + Require all granted + </Directory> + + <Location /admin> + Deny from all + </Location> + + <LocationMatch ^/([^/]+)/appadmin> + Deny from all + </LocationMatch> + + CustomLog /var/log/httpd/access_log common + ErrorLog /var/log/httpd/error_log +</VirtualHost> + +<VirtualHost *:443> + SSLEngine on + SSLCertificateFile /etc/httpd/ssl/self_signed.cert + SSLCertificateKeyFile /etc/httpd/ssl/self_signed.key + + WSGIProcessGroup web2py + WSGIScriptAlias / /opt/web-apps/web2py/wsgihandler.py + WSGIPassAuthorization On + + <Directory /opt/web-apps/web2py> + AllowOverride None + Order Allow,Deny + Deny from all + <Files wsgihandler.py> + Require all granted + Allow from all + </Files> + </Directory> + + AliasMatch ^/([^/]+)/static/(?:_[\d]+.[\d]+.[\d]+/)?(.*) /opt/web-apps/web2py/applications/\$1/static/\$2 + + <Directory /opt/web-apps/web2py/applications/*/static> + Options -Indexes + ExpiresActive On + ExpiresDefault "access plus 1 hour" + Order Allow,Deny + Allow from all + Require all granted + </Directory> + + CustomLog /var/log/httpd/access_log common + ErrorLog /var/log/httpd/error_log +</VirtualHost> + +EOF + +# Fix wsgi socket locations +echo "WSGISocketPrefix run/wsgi" >> /etc/httpd/conf.d/wsgi.conf + +# Restart Apache to pick up changes +systemctl restart httpd.service + +### +### Phase 7 - Setup web2py admin password +### + +echo +echo " - Setup web2py admin password" +echo + +cd /opt/web-apps/web2py +sudo -u apache python -c "from gluon.main import save_password; save_password(raw_input('admin password: '),443)" + +### +### Phase 8 - Verify that required services start at boot +### + +/sbin/chkconfig iptables on +/sbin/chkconfig httpd on + +### +### Phase 999 - Done! +### + +# Change back to original directory +cd ${current_directory} + +echo " - Complete!" +echo diff --git a/web2py/scripts/setup-web2py-cloudfoundry.sh b/web2py/scripts/setup-web2py-cloudfoundry.sh new file mode 100644 index 0000000..9a71262 --- /dev/null +++ b/web2py/scripts/setup-web2py-cloudfoundry.sh @@ -0,0 +1,6 @@ +read -p "Please choose a Web2Py Administrator password:" passwd +echo "web: python web2py.py -a '$passwd' -i 0.0.0.0 -p \$PORT" > Procfile +mkdir vendor +pip install --download vendor -r requirements.txt +read -p "Please choose a CF application name:" appname +cf push $appname -b https://github.com/cloudfoundry/buildpack-python.git diff --git a/web2py/scripts/setup-web2py-debian-sid.sh b/web2py/scripts/setup-web2py-debian-sid.sh new file mode 100644 index 0000000..cf9b1a9 --- /dev/null +++ b/web2py/scripts/setup-web2py-debian-sid.sh @@ -0,0 +1,162 @@ +echo "This script will: +1) install all modules need to run web2py on Ubuntu/Debian +2) install web2py in /home/www-data/ +3) create a self signed ssl certificate +4) setup web2py with mod_wsgi +5) overwrite /etc/apache2/sites-available/default +6) restart apache. + +You may want to read this script before running it. + +Press a key to continue...[ctrl+C to abort]" + +read CONFIRM + +#!/bin/bash +# optional +# dpkg-reconfigure console-setup +# dpkg-reconfigure timezoneconf +# nano /etc/hostname +# nano /etc/network/interfaces +# nano /etc/resolv.conf +# reboot now +# ifconfig eth0 + +echo "installing useful packages" +echo "==========================" +apt-get update +apt-get -y install ssh +apt-get -y install zip unzip +apt-get -y install tar +apt-get -y install openssh-server +apt-get -y install build-essential +apt-get -y install ipython +apt-get -y install python-dev +apt-get -y install postgresql +apt-get -y install apache2 +apt-get -y install libapache2-mod-wsgi +apt-get -y install python-psycopg2 +apt-get -y install postfix +apt-get -y install wget +apt-get -y install python-matplotlib +apt-get -y install python-reportlab +apt-get -y install mercurial +/etc/init.d/postgresql restart + +# optional, uncomment for emacs +# apt-get -y install emacs + +# optional, uncomment for backups using samba +# apt-get -y install samba +# apt-get -y install smbfs + +echo "downloading, installing and starting web2py" +echo "===========================================" +cd /home +mkdir www-data +cd www-data +rm web2py_src.zip* +wget http://web2py.com/examples/static/web2py_src.zip +unzip web2py_src.zip +mv web2py/handlers/wsgihandler.py web2py/wsgihandler.py +chown -R www-data:www-data web2py + +echo "setting up apache modules" +echo "=========================" +a2enmod ssl +a2enmod proxy +a2enmod proxy_http +a2enmod headers +a2enmod expires +a2enmod wsgi +mkdir /etc/apache2/ssl + +echo "creating a self signed certificate" +echo "==================================" +openssl genrsa 1024 > /etc/apache2/ssl/self_signed.key +chmod 400 /etc/apache2/ssl/self_signed.key +openssl req -new -x509 -nodes -sha1 -days 365 -key /etc/apache2/ssl/self_signed.key > /etc/apache2/ssl/self_signed.cert +openssl x509 -noout -fingerprint -text < /etc/apache2/ssl/self_signed.cert > /etc/apache2/ssl/self_signed.info + +echo "rewriting your apache config file to use mod_wsgi" +echo "=================================================" +echo ' +<VirtualHost *:80> + ServerName YourServerName + WSGIDaemonProcess web2py user=www-data group=www-data display-name=%{GROUP} + WSGIProcessGroup web2py + WSGIScriptAlias / /home/www-data/web2py/wsgihandler.py + + <Directory /home/www-data/web2py> + Require all denied + <Files wsgihandler.py> + Require all granted + </Files> + </Directory> + + AliasMatch ^/([^/]+)/static/(?:_[\d]+.[\d]+.[\d]+/)?(.*) \ + /home/www-data/web2py/applications/$1/static/$2 + <Directory /home/www-data/web2py/applications/*/static/> + Options -Indexes + Require all granted + </Directory> + + <Location /admin> + Require all denied + </Location> + + <LocationMatch ^/([^/]+)/appadmin> + Require all denied + </LocationMatch> + + CustomLog /var/log/apache2/access.log common + ErrorLog /var/log/apache2/error.log +</VirtualHost> + + +<VirtualHost *:443> + ServerName YourServerName + SSLEngine on + SSLCertificateFile /etc/apache2/ssl/self_signed.cert + SSLCertificateKeyFile /etc/apache2/ssl/self_signed.key + + WSGIProcessGroup web2py + + WSGIScriptAlias / /home/www-data/web2py/wsgihandler.py + + <Directory /home/www-data/web2py> + AllowOverride None + Require all denied + <Files wsgihandler.py> + Require all granted + </Files> + </Directory> + + AliasMatch ^/([^/]+)/static/(?:_[\d]+.[\d]+.[\d]+/)?(.*) \ + /home/www-data/web2py/applications/$1/static/$2 + + <Directory /home/www-data/web2py/applications/*/static/> + Require all granted + </Directory> + + CustomLog /var/log/apache2/access.log common + ErrorLog /var/log/apache2/error.log + +</VirtualHost> +' > /etc/apache2/sites-available/default + +# echo "setting up PAM" +# echo "================" +# sudo apt-get install pwauth +# sudo ln -s /etc/apache2/mods-available/authnz_external.load /etc/apache2/mods-enabled +# ln -s /etc/pam.d/apache2 /etc/pam.d/httpd +# usermod -a -G shadow www-data + +echo "restarting apache" +echo "================" + +/etc/init.d/apache2 restart +cd /home/www-data/web2py +sudo -u www-data python -c "from gluon.widget import console; console();" +sudo -u www-data python -c "from gluon.main import save_password; save_password(raw_input('admin password: '),443)" +echo "done!" diff --git a/web2py/scripts/setup-web2py-fedora-ami.sh b/web2py/scripts/setup-web2py-fedora-ami.sh new file mode 100644 index 0000000..5ef2aca --- /dev/null +++ b/web2py/scripts/setup-web2py-fedora-ami.sh @@ -0,0 +1,402 @@ +echo "This script will: +1) Install modules needed to run web2py on Fedora and CentOS/RHEL +2) Install Python 2.6 to /opt and recompile wsgi if not provided +2) Install web2py in /opt/web-apps/ +3) Configure SELinux and iptables +5) Create a self signed ssl certificate +6) Setup web2py with mod_wsgi +7) Create virtualhost entries so that web2py responds for '/' +8) Restart Apache. + +You should probably read this script before running it. + +Although SELinux permissions changes have been made, +further SELinux changes will be required for your personal +apps. (There may also be additional changes required for the +bundled apps.) As a last resort, SELinux can be disabled. + +A simple iptables configuration has been applied. You may +want to review it to verify that it meets your needs. + +Finally, if you require a proxy to access the Internet, please +set up your machine to do so before running this script. + +(author: Charles Law as berubejd) + +Press ENTER to continue...[ctrl+C to abort]" + +read CONFIRM + +#!/bin/bash + +### +### Phase 0 - This may get messy. Lets work from a temporary directory +### + +current_dir=`pwd` + +if [ -d /tmp/setup-web2py/ ]; then + mv /tmp/setup-web2py/ /tmp/setup-web2py.old/ +fi + +mkdir -p /tmp/setup-web2py +cd /tmp/setup-web2py + +### +### Phase 1 - Requirements installation +### + +echo +echo " - Installing packages" +echo + +# Verify packages are up to date +yum update + +# Install required packages +yum install httpd mod_ssl mod_wsgi wget python + +# Verify we have at least Python 2.5 +typeset -i version_major +typeset -i version_minor + +version=`rpm --qf %{Version} -q python` +version_major=`echo ${version} | awk '{split($0, parts, "."); print parts[1]}'` +version_minor=`echo ${version} | awk '{split($0, parts, "."); print parts[2]}'` + +if [ ! ${version_major} -ge 2 -o ! ${version_minor} -ge 5 ]; then + # Setup 2.6 in /opt - based upon + # http://markkoberlein.com/getting-python-26-with-django-11-together-on + + # Check for earlier Python 2.6 install + if [ -e /opt/python2.6 ]; then + # Is Python already installed? + RETV=`/opt/python2.6/bin/python -V > /dev/null 2>&1; echo $?` + if [ ${RETV} -eq 0 ]; then + python_installed='True' + else + mv /opt/python2.6 /opt/python2.6-old + fi + fi + + # Install Python 2.6 if it doesn't exist already + if [ ! "${python_installed}" == "True" ]; then + # Install requirements for the Python build + yum install sqlite-devel zlib-devel + + mkdir -p /opt/python2.6 + + # Download and install + wget http://www.python.org/ftp/python/2.6.4/Python-2.6.4.tgz + tar -xzf Python-2.6.4.tgz + cd Python-2.6.4 + ./configure --prefix=/opt/python2.6 --with-threads --enable-shared --with-zlib=/usr/include + make && make install + + cd /tmp/setup-web2py + fi + + # Create links for Python 2.6 + # even if it was previously installed just to be sure + ln -s /opt/python2.6/lib/libpython2.6.so /usr/lib + ln -s /opt/python2.6/lib/libpython2.6.so.1.0 /usr/lib + ln -s /opt/python2.6/bin/python /usr/local/bin/python + ln -s /opt/python2.6/bin/python /usr/bin/python2.6 + ln -s /opt/python2.6/lib/python2.6.so /opt/python2.6/lib/python2.6/config/ + + # Update linker for new libraries + /sbin/ldconfig + + # Rebuild wsgi to take advantage of Python 2.6 + yum install httpd-devel + + cd /tmp/setup-web2py + + wget http://modwsgi.googlecode.com/files/mod_wsgi-3.3.tar.gz + tar -xzf mod_wsgi-3.3.tar.gz + cd mod_wsgi-3.3 + ./configure --with-python=/usr/local/bin/python + make && make install + + echo "LoadModule wsgi_module modules/mod_wsgi.so" > /etc/httpd/conf.d/wsgi.conf + + cd /tmp/setup-web2py +fi + +### MySQL install untested! +# Install mysql packages (optional) +#yum install mysql mysql-server + +# Enable mysql to start at boot (optional) +#chkconfig --levels 235 mysqld on +#service mysqld start + +# Configure mysql security settings (not really optional if mysql installed) +#/usr/bin/mysql_secure_installation + +### +### Phase 2 - Install web2py +### + +echo +echo " - Downloading, installing, and starting web2py" +echo + +# Create web-apps directory, if required +if [ ! -d "/opt/web-apps" ]; then + mkdir -p /opt/web-apps + + chmod 755 /opt + chmod 755 /opt/web-apps +fi + +cd /opt/web-apps + +# Download web2py +if [ -e web2py_src.zip* ]; then + rm web2py_src.zip* +fi + +wget http://web2py.com/examples/static/web2py_src.zip +unzip web2py_src.zip +mv web2py/handlers/wsgihandler.py web2py/wsgihandler.py +chown -R apache:apache web2py + +### +### Phase 3 - Setup SELinux context +### + +# Set context for Python libraries if Python 2.6 installed +if [ -d /opt/python2.6 ]; then + cd /opt/python2.6 + chcon -R -t lib_t lib/ +fi + +# Allow http_tmp_exec required for wsgi +RETV=`setsebool -P httpd_tmp_exec on > /dev/null 2>&1; echo $?` +if [ ! ${RETV} -eq 0 ]; then + # CentOS doesn't support httpd_tmp_exec + cd /tmp/setup-web2py + + # Create the SELinux policy +cat > httpd.te <<EOF +module httpd 1.0; + +require { + type httpd_t; + class process execmem; +} + +#============= httpd_t ============== +allow httpd_t self:process execmem; +EOF + + checkmodule -M -m -o httpd.mod httpd.te + semodule_package -o httpd.pp -m httpd.mod + semodule -i httpd.pp + +fi + +# Setup the overall web2py SELinux context +cd /opt +chcon -R -t httpd_user_content_t web-apps/ + +cd /opt/web-apps/web2py/applications + +# Setup the proper context on the writable application directories +for app in `ls` +do + for dir in databases cache errors sessions private uploads + do + mkdir ${app}/${dir} + chown apache:apache ${app}/${dir} + chcon -R -t tmp_t ${app}/${dir} + done +done + + +### +### Phase 4 - Configure iptables +### + +cd /tmp/setup-web2py + +# Create rules file - based upon +# http://articles.slicehost.com/assets/2007/9/4/iptables.txt +cat > iptables.rules <<EOF +*filter + +# Allows all loopback (lo0) traffic +# drop all traffic to 127/8 that doesn't use lo0 +-A INPUT -i lo -j ACCEPT +-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT + +# Accepts all established inbound connections +-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT + +# Allows all outbound traffic +-A OUTPUT -j ACCEPT + +# Allows SSH, HTTP, and HTTPS +# Consider changing the SSH port and/or using rate limiting +# see http://blog.andrew.net.au/2005/02/16#ipt_recent_and_ssh_attacks +-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT +-A INPUT -p tcp --dport 80 -j ACCEPT +-A INPUT -p tcp --dport 443 -j ACCEPT + +# Allow ping +-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT + +# log iptables denied calls +-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7 + +# Reject all other inbound - default deny unless explicitly allowed policy +-A INPUT -j REJECT +-A FORWARD -j REJECT + +COMMIT +EOF + +/sbin/iptables -F +cat iptables.rules | /sbin/iptables-restore +/sbin/service iptables save + +### +### Phase 5 - Setup SSL +### + +echo +echo " - Creating a self signed certificate" +echo + +# Verify ssl directory exists +if [ ! -d "/etc/httpd/ssl" ]; then + mkdir -p /etc/httpd/ssl +fi + +# Generate and protect certificate +openssl genrsa 1024 > /etc/httpd/ssl/self_signed.key +openssl req -new -x509 -nodes -sha1 -days 365 -key /etc/httpd/ssl/self_signed.key > /etc/httpd/ssl/self_signed.cert +openssl x509 -noout -fingerprint -text < /etc/httpd/ssl/self_signed.cert > /etc/httpd/ssl/self_signed.info + +chmod 400 /etc/httpd/ssl/self_signed.* + +### +### Phase 6 - Configure Apache +### + +echo +echo " - Configure Apache to use mod_wsgi" +echo + +# Create config +if [ -e /etc/httpd/conf.d/welcome.conf ]; then + mv /etc/httpd/conf.d/welcome.conf /etc/httpd/conf.d/welcome.conf.disabled +fi + +cat > /etc/httpd/conf.d/default.conf <<EOF +NameVirtualHost *:80 +NameVirtualHost *:443 + +<VirtualHost *:80> + WSGIDaemonProcess web2py user=apache group=apache + WSGIProcessGroup web2py + WSGIScriptAlias / /opt/web-apps/web2py/wsgihandler.py + + <Directory /opt/web-apps/web2py> + AllowOverride None + Order Allow,Deny + Deny from all + <Files wsgihandler.py> + Allow from all + </Files> + </Directory> + AliasMatch ^/([^/]+)/static/(?:_[\d]+.[\d]+.[\d]+/)?(.*) \ + /opt/web-apps/web2py/applications/\$1/static/\$2 + + <Directory /opt/web-apps/web2py/applications/*/static> + Options -Indexes + Order Allow,Deny + Allow from all + </Directory> + + <Location /admin> + Deny from all + </Location> + + <LocationMatch ^/([^/]+)/appadmin> + Deny from all + </LocationMatch> + + CustomLog /var/log/httpd/access_log common + ErrorLog /var/log/httpd/error_log +</VirtualHost> + +<VirtualHost *:443> + SSLEngine on + SSLCertificateFile /etc/httpd/ssl/self_signed.cert + SSLCertificateKeyFile /etc/httpd/ssl/self_signed.key + + WSGIProcessGroup web2py + + WSGIScriptAlias / /opt/web-apps/web2py/wsgihandler.py + + <Directory /opt/web-apps/web2py> + AllowOverride None + Order Allow,Deny + Deny from all + <Files wsgihandler.py> + Allow from all + </Files> + </Directory> + + AliasMatch ^/([^/]+)/static/(?:_[\d]+.[\d]+.[\d]+/)?(.*) \ + /opt/web-apps/web2py/applications/\$1/static/\$2 + + <Directory /opt/web-apps/web2py/applications/*/static> + Options -Indexes + ExpiresActive On + ExpiresDefault "access plus 1 hour" + Order Allow,Deny + Allow from all + </Directory> + + CustomLog /var/log/httpd/access_log common + ErrorLog /var/log/httpd/error_log +</VirtualHost> + +EOF + +# Fix wsgi socket locations +echo "WSGISocketPrefix run/wsgi" >> /etc/httpd/conf.d/wsgi.conf + +# Restart Apache to pick up changes +service httpd restart + +### +### Phase 7 - Setup web2py admin password +### + +echo +echo " - Setup web2py admin password" +echo + +cd /opt/web-apps/web2py +sudo -u apache python -c "from gluon.main import save_password; save_password(raw_input('admin password: '),443)" + +### +### Phase 8 - Verify that required services start at boot +### + +/sbin/chkconfig iptables on +/sbin/chkconfig httpd on + +### +### Phase 999 - Done! +### + +# Change back to original directory +cd ${current_directory} + +echo " - Complete!" +echo diff --git a/web2py/scripts/setup-web2py-fedora.sh b/web2py/scripts/setup-web2py-fedora.sh new file mode 100644 index 0000000..d7d6d01 --- /dev/null +++ b/web2py/scripts/setup-web2py-fedora.sh @@ -0,0 +1,405 @@ +#!/bin/bash +echo "This script will: +1) Install modules needed to run web2py on Fedora and CentOS/RHEL +2) Install Python 2.6 to /opt and recompile wsgi if not provided +2) Install web2py in /opt/web-apps/ +3) Configure SELinux and iptables +5) Create a self signed ssl certificate +6) Setup web2py with mod_wsgi +7) Create virtualhost entries so that web2py responds for '/' +8) Restart Apache. + +You should probably read this script before running it. + +Although SELinux permissions changes have been made, +further SELinux changes will be required for your personal +apps. (There may also be additional changes required for the +bundled apps.) As a last resort, SELinux can be disabled. + +A simple iptables configuration has been applied. You may +want to review it to verify that it meets your needs. + +Finally, if you require a proxy to access the Internet, please +set up your machine to do so before running this script. + +(author: berubejd) + +Press ENTER to continue...[ctrl+C to abort]" + +read CONFIRM + + + +### +### Phase 0 - This may get messy. Lets work from a temporary directory +### + +current_dir=`pwd` + +if [ -d /tmp/setup-web2py/ ]; then + mv /tmp/setup-web2py/ /tmp/setup-web2py.old/ +fi + +mkdir -p /tmp/setup-web2py +cd /tmp/setup-web2py + +### +### Phase 1 - Requirements installation +### + +echo +echo " - Installing packages" +echo + +# Verify packages are up to date +yum update + +# Install required packages +yum install httpd mod_ssl mod_wsgi wget python + +# Verify we have at least Python 2.5 +typeset -i version_major +typeset -i version_minor + +version=`rpm --qf %{Version} -q python` +version_major=`echo ${version} | awk '{split($0, parts, "."); print parts[1]}'` +version_minor=`echo ${version} | awk '{split($0, parts, "."); print parts[2]}'` + +if [ ! ${version_major} -ge 2 -o ! ${version_minor} -ge 5 ]; then + # Setup 2.6 in /opt - based upon + # http://markkoberlein.com/getting-python-26-with-django-11-together-on + + # Check for earlier Python 2.6 install + if [ -e /opt/python2.6 ]; then + # Is Python already installed? + RETV=`/opt/python2.6/bin/python -V > /dev/null 2>&1; echo $?` + if [ ${RETV} -eq 0 ]; then + python_installed='True' + else + mv /opt/python2.6 /opt/python2.6-old + fi + fi + + # Install Python 2.6 if it doesn't exist already + if [ ! "${python_installed}" == "True" ]; then + # Install requirements for the Python build + yum install sqlite-devel zlib-devel + + mkdir -p /opt/python2.6 + + # Download and install + wget http://www.python.org/ftp/python/2.6.4/Python-2.6.4.tgz + tar -xzf Python-2.6.4.tgz + cd Python-2.6.4 + ./configure --prefix=/opt/python2.6 --with-threads --enable-shared --with-zlib=/usr/include + make && make install + + cd /tmp/setup-web2py + fi + + # Create links for Python 2.6 + # even if it was previously installed just to be sure + ln -s /opt/python2.6/lib/libpython2.6.so /usr/lib + ln -s /opt/python2.6/lib/libpython2.6.so.1.0 /usr/lib + ln -s /opt/python2.6/bin/python /usr/local/bin/python + ln -s /opt/python2.6/bin/python /usr/bin/python2.6 + ln -s /opt/python2.6/lib/python2.6.so /opt/python2.6/lib/python2.6/config/ + + # Update linker for new libraries + /sbin/ldconfig + + # Rebuild wsgi to take advantage of Python 2.6 + yum install httpd-devel + + cd /tmp/setup-web2py + + wget http://modwsgi.googlecode.com/files/mod_wsgi-3.3.tar.gz + tar -xzf mod_wsgi-3.3.tar.gz + cd mod_wsgi-3.3 + ./configure --with-python=/usr/local/bin/python + make && make install + + echo "LoadModule wsgi_module modules/mod_wsgi.so" > /etc/httpd/conf.d/wsgi.conf + + cd /tmp/setup-web2py +fi + +### MySQL install untested! +# Install mysql packages (optional) +#yum install mysql mysql-server + +# Enable mysql to start at boot (optional) +#chkconfig --levels 235 mysqld on +#service mysqld start + +# Configure mysql security settings (not really optional if mysql installed) +#/usr/bin/mysql_secure_installation + +### +### Phase 2 - Install web2py +### + +echo +echo " - Downloading, installing, and starting web2py" +echo + +# Create web-apps directory, if required +if [ ! -d "/opt/web-apps" ]; then + mkdir -p /opt/web-apps + + chmod 755 /opt + chmod 755 /opt/web-apps +fi + +cd /opt/web-apps + +# Download web2py +if [ -e web2py_src.zip* ]; then + rm web2py_src.zip* +fi + +wget http://web2py.com/examples/static/web2py_src.zip +unzip web2py_src.zip +mv web2py/handlers/wsgihandler.py web2py/wsgihandler.py +chown -R apache:apache web2py + +### +### Phase 3 - Setup SELinux context +### + +# Set context for Python libraries if Python 2.6 installed +if [ -d /opt/python2.6 ]; then + cd /opt/python2.6 + chcon -R -t lib_t lib/ +fi + +# Allow http_tmp_exec required for wsgi +RETV=`setsebool -P httpd_tmp_exec on > /dev/null 2>&1; echo $?` +if [ ! ${RETV} -eq 0 ]; then + # CentOS doesn't support httpd_tmp_exec + cd /tmp/setup-web2py + + # Create the SELinux policy +cat > httpd.te <<EOF + +module httpd 1.0; + +require { + type httpd_t; + class process execmem; +} + +#============= httpd_t ============== +allow httpd_t self:process execmem; +EOF + + checkmodule -M -m -o httpd.mod httpd.te + semodule_package -o httpd.pp -m httpd.mod + semodule -i httpd.pp + +fi + +# Setup the overall web2py SELinux context +cd /opt +chcon -R -t httpd_user_content_t web-apps/ + +cd /opt/web-apps/web2py/applications + +# Setup the proper context on the writable application directories +for app in `ls` +do + for dir in databases cache errors sessions private uploads + do + mkdir ${app}/${dir} + chown apache:apache ${app}/${dir} + chcon -R -t tmp_t ${app}/${dir} + done +done + + +### +### Phase 4 - Configure iptables +### + +cd /tmp/setup-web2py + +# Create rules file - based upon +# http://articles.slicehost.com/assets/2007/9/4/iptables.txt +cat > iptables.rules <<EOF +*filter + +# Allows all loopback (lo0) traffic +# drop all traffic to 127/8 that doesn't use lo0 +-A INPUT -i lo -j ACCEPT +-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT + +# Accepts all established inbound connections +-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT + +# Allows all outbound traffic +-A OUTPUT -j ACCEPT + +# Allows SSH, HTTP, and HTTPS +# Consider changing the SSH port and/or using rate limiting +# see http://blog.andrew.net.au/2005/02/16#ipt_recent_and_ssh_attacks +-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT +-A INPUT -p tcp --dport 80 -j ACCEPT +-A INPUT -p tcp --dport 443 -j ACCEPT + +# Allow ping +-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT + +# log iptables denied calls +-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7 + +# Reject all other inbound - default deny unless explicitly allowed policy +-A INPUT -j REJECT +-A FORWARD -j REJECT + +COMMIT +EOF + +/sbin/iptables -F +cat iptables.rules | /sbin/iptables-restore +/sbin/service iptables save + +### +### Phase 5 - Setup SSL +### + +echo +echo " - Creating a self signed certificate" +echo + +# Verify ssl directory exists +if [ ! -d "/etc/httpd/ssl" ]; then + mkdir -p /etc/httpd/ssl +fi + +# Generate and protect certificate +openssl genrsa 1024 > /etc/httpd/ssl/self_signed.key +openssl req -new -x509 -nodes -sha1 -days 365 -key /etc/httpd/ssl/self_signed.key > /etc/httpd/ssl/self_signed.cert +openssl x509 -noout -fingerprint -text < /etc/httpd/ssl/self_signed.cert > /etc/httpd/ssl/self_signed.info + +chmod 400 /etc/httpd/ssl/self_signed.* + +### +### Phase 6 - Configure Apache +### + +echo +echo " - Configure Apache to use mod_wsgi" +echo + +# Create config +if [ -e /etc/httpd/conf.d/welcome.conf ]; then + mv /etc/httpd/conf.d/welcome.conf /etc/httpd/conf.d/welcome.conf.disabled +fi + +cat > /etc/httpd/conf.d/default.conf <<EOF + +NameVirtualHost *:80 +NameVirtualHost *:443 + +<VirtualHost *:80> + WSGIDaemonProcess web2py user=apache group=apache + WSGIProcessGroup web2py + WSGIScriptAlias / /opt/web-apps/web2py/wsgihandler.py + WSGIPassAuthorization On + + <Directory /opt/web-apps/web2py> + AllowOverride None + Order Allow,Deny + Deny from all + <Files wsgihandler.py> + Allow from all + </Files> + </Directory> + + AliasMatch ^/([^/]+)/static/(?:_[\d]+.[\d]+.[\d]+/)?(.*) /opt/web-apps/web2py/applications/\$1/static/\$2 + + <Directory /opt/web-apps/web2py/applications/*/static> + Options -Indexes + Order Allow,Deny + Allow from all + </Directory> + + <Location /admin> + Deny from all + </Location> + + <LocationMatch ^/([^/]+)/appadmin> + Deny from all + </LocationMatch> + + CustomLog /var/log/httpd/access_log common + ErrorLog /var/log/httpd/error_log +</VirtualHost> + +<VirtualHost *:443> + SSLEngine on + SSLCertificateFile /etc/httpd/ssl/self_signed.cert + SSLCertificateKeyFile /etc/httpd/ssl/self_signed.key + + WSGIProcessGroup web2py + WSGIScriptAlias / /opt/web-apps/web2py/wsgihandler.py + WSGIPassAuthorization On + + <Directory /opt/web-apps/web2py> + AllowOverride None + Order Allow,Deny + Deny from all + <Files wsgihandler.py> + Allow from all + </Files> + </Directory> + + AliasMatch ^/([^/]+)/static/(?:_[\d]+.[\d]+.[\d]+/)?(.*) /opt/web-apps/web2py/applications/\$1/static/\$2 + + <Directory /opt/web-apps/web2py/applications/*/static> + Options -Indexes + ExpiresActive On + ExpiresDefault "access plus 1 hour" + Order Allow,Deny + Allow from all + </Directory> + + CustomLog /var/log/httpd/access_log common + ErrorLog /var/log/httpd/error_log +</VirtualHost> + +EOF + +# Fix wsgi socket locations +echo "WSGISocketPrefix run/wsgi" >> /etc/httpd/conf.d/wsgi.conf + +# Restart Apache to pick up changes +service httpd restart + +### +### Phase 7 - Setup web2py admin password +### + +echo +echo " - Setup web2py admin password" +echo + +cd /opt/web-apps/web2py +sudo -u apache python -c "from gluon.main import save_password; save_password(raw_input('admin password: '),443)" + +### +### Phase 8 - Verify that required services start at boot +### + +/sbin/chkconfig iptables on +/sbin/chkconfig httpd on + +### +### Phase 999 - Done! +### + +# Change back to original directory +cd ${current_directory} + +echo " - Complete!" +echo diff --git a/web2py/scripts/setup-web2py-heroku.sh b/web2py/scripts/setup-web2py-heroku.sh new file mode 100644 index 0000000..5d57d89 --- /dev/null +++ b/web2py/scripts/setup-web2py-heroku.sh @@ -0,0 +1,16 @@ +read -p "Choose your admin password?" passwd +sudo pip install virtualenv +virtualenv venv --distribute +source venv/bin/activate +sudo pip install psycopg2 +pip freeze > requirements.txt +echo "web: python web2py.py -a '$passwd' -i 0.0.0.0 -p \$PORT" > Procfile +git init +git add . +git add Procfile +git commit -a -m "first commit" +heroku create +git push heroku master +heroku addons:add heroku-postgresql:dev +heroku scale web=1 +heroku open diff --git a/web2py/scripts/setup-web2py-nginx-uwsgi-centos64.sh b/web2py/scripts/setup-web2py-nginx-uwsgi-centos64.sh new file mode 100644 index 0000000..6ea43c8 --- /dev/null +++ b/web2py/scripts/setup-web2py-nginx-uwsgi-centos64.sh @@ -0,0 +1,215 @@ +#!/bin/bash +# Autor: Nilton OS -- www.linuxpro.com.br +echo 'setup-web2py-nginx-uwsgi-centos64.sh' +echo 'Support CentOS 6.4' +echo 'Installs Nginx 1.4.1 + uWSGI + Web2py' + + +# Get Web2py Admin Password +echo -e "Web2py Admin Password: \c " +read PW + +echo -e "Set Server Name Ex: web2py.domain.com : \c " +read SERVER_FQDN + +echo -e "Set Server IP: \c " +read SERVER_IP + + +echo "" >>/etc/hosts +echo "$SERVER_IP $SERVER_FQDN" >>/etc/hosts + +yum update -y + +yum install -y http://mirror-fpt-telecom.fpt.net/fedora/epel/6/i386/epel-release-6-8.noarch.rpm +yum clean all +yum install -y gcc libxml2-devel python-devel python-pip PyXML unzip make sudo + +## 64Bits System +## yum install -y http://nginx.org/packages/rhel/6/x86_64/RPMS/nginx-1.4.1-1.el6.ngx.x86_64.rpm +yum install -y http://nginx.org/packages/rhel/6/i386/RPMS/nginx-1.4.1-1.el6.ngx.i386.rpm + + +pip-python install --upgrade pip +PIPPATH=`which pip` +$PIPPATH install --upgrade uwsgi + + +# Prepare folders for uwsgi +mkdir /etc/uwsgi +mkdir /var/log/uwsgi +mkdir -p /var/www/ + +#usermod -a -G apache nginx +mkdir -p /etc/nginx/ssl/ + + +cd /etc/nginx/ssl +openssl genrsa 1024 > web2py.key && chmod 400 web2py.key +openssl req -new -x509 -nodes -sha1 -days 1780 -key web2py.key > web2py.crt +openssl x509 -noout -fingerprint -text < web2py.crt > web2py.info + + +echo 'server { + listen YOUR_SERVER_IP:80; + server_name YOUR_SERVER_FQDN; + #to enable correct use of response.static_version + location ~* /(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$ { + alias /var/www/web2py/applications/$1/static/$2; + expires max; + } + location / { + #uwsgi_pass 127.0.0.1:9001; + uwsgi_pass unix:///var/www/web2py/logs/web2py.socket; + include /etc/nginx/uwsgi_params; + uwsgi_param UWSGI_SCHEME $scheme; + uwsgi_param SERVER_SOFTWARE nginx/$nginx_version; + + ### remove the comments if you use uploads (max 10 MB) + #client_max_body_size 10m; + ### + } +} +server { + listen YOUR_SERVER_IP:443 default_server ssl; + server_name YOUR_SERVER_FQDN; + ssl_certificate /etc/nginx/ssl/web2py.crt; + ssl_certificate_key /etc/nginx/ssl/web2py.key; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + ssl_ciphers ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA; + ssl_protocols SSLv3 TLSv1; + keepalive_timeout 70; + location ~* /(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$ { + alias /var/www/web2py/applications/$1/static/$2; + expires max; + } + location / { + #uwsgi_pass 127.0.0.1:9001; + uwsgi_pass unix:///var/www/web2py/logs/web2py.socket; + include /etc/nginx/uwsgi_params; + uwsgi_param UWSGI_SCHEME $scheme; + uwsgi_param SERVER_SOFTWARE nginx/$nginx_version; + + ### remove the comments if you use uploads (max 10 MB) + #client_max_body_size 10m; + ### + } + +}' >/etc/nginx/conf.d/web2py.conf + +sed -i "s/YOUR_SERVER_IP/$SERVER_IP/" /etc/nginx/conf.d/web2py.conf +sed -i "s/YOUR_SERVER_FQDN/$SERVER_FQDN/" /etc/nginx/conf.d/web2py.conf + + +# Create configuration file /etc/uwsgi/web2py.ini +echo '[uwsgi] + +socket = /var/www/web2py/logs/%n.socket +pythonpath = /var/www/web2py/ +mount = /=wsgihandler:application +processes = 4 +master = true +harakiri = 60 +reload-mercy = 8 +cpu-affinity = 1 +stats = /tmp/%n.stats.socket +max-requests = 2000 +limit-as = 512 +reload-on-as = 256 +reload-on-rss = 192 +uid = nginx +gid = nginx +cron = 0 0 -1 -1 -1 python /var/www/web2py/web2py.py -Q -S welcome -M -R scripts/sessions2trash.py -A -o +no-orphans = true +chmod-socket = 666 +' >/etc/uwsgi/web2py.ini + + +cd /var/www/ +curl --progress -O http://web2py.com/examples/static/web2py_src.zip +unzip web2py_src.zip && rm -rf web2py_src.zip +# Download latest version of sessions2trash.py +mv web2py/handlers/wsgihandler.py web2py/wsgihandler.py +chown -R nginx:nginx web2py +cd /var/www/web2py +sudo -u nginx python -c "from gluon.main import save_password; save_password('$PW',443)" + + + +## Daemons /start/stop + +echo '#!/bin/sh +# Autor: Nilton OS -- www.linuxpro.com.br +# +# +### BEGIN INIT INFO +# Provides: uwsgi +# Required-Start: $syslog $remote_fs +# Should-Start: $time ypbind smtp +# Required-Stop: $syslog $remote_fs +# Should-Stop: ypbind smtp +# Default-Start: 3 5 +# Default-Stop: 0 1 2 6 +### END INIT INFO + +# Source function library. +. /etc/rc.d/init.d/functions + +# Check for missing binaries (stale symlinks should not happen) +UWSGI_BIN=`which uwsgi` +test -x $UWSGI_BIN || { echo "$UWSGI_BIN not installed"; + if [ "$1" = "stop" ]; then exit 0; + else exit 5; fi; } + +UWSGI_EMPEROR_MODE=true +UWSGI_VASSALS="/etc/uwsgi/" +UWSGI_OPTIONS="--enable-threads --logto /var/log/uwsgi/uwsgi.log" +lockfile=/var/lock/subsys/uwsgi + +UWSGI_OPTIONS="$UWSGI_OPTIONS --autoload" + +if [ "$UWSGI_EMPEROR_MODE" = "true" ] ; then + UWSGI_OPTIONS="$UWSGI_OPTIONS --emperor $UWSGI_VASSALS" +fi + +case "$1" in + start) + echo -n "Starting uWSGI " + daemon $UWSGI_BIN $UWSGI_OPTIONS & + ;; + stop) + echo -n "Shutting down uWSGI " + killproc $UWSGI_BIN + ;; + restart) + $0 stop + $0 start + ;; + status) + echo -n "Checking for service uWSGI " + status $UWSGI_BIN + ;; + *) + echo "Usage: $0 {start|stop|status|restart}" + exit 1 + ;; +esac +exit 0 '> /etc/init.d/uwsgi + +chmod +x /etc/init.d/uwsgi + +/etc/init.d/uwsgi start +/etc/init.d/nginx start + +/etc/init.d/iptables stop +chkconfig --del iptables + +chkconfig --levels 235 uwsgi on +chkconfig --levels 235 nginx on + +## you can reload uwsgi with +#/etc/init.d/uwsgi restart +## to reload web2py only (without restarting uwsgi) +# touch /etc/uwsgi/web2py.ini diff --git a/web2py/scripts/setup-web2py-nginx-uwsgi-centos7.sh b/web2py/scripts/setup-web2py-nginx-uwsgi-centos7.sh new file mode 100644 index 0000000..a6b6215 --- /dev/null +++ b/web2py/scripts/setup-web2py-nginx-uwsgi-centos7.sh @@ -0,0 +1,235 @@ +#!/bin/bash + +# This script will install web2py with nginx+uwsgi on centos 7 +# This script is based on excellent tutorial by Justin Ellingwood on +# https://www.digitalocean.com/community/tutorials/how-to-deploy-web2py-python-applications-with-uwsgi-and-nginx-on-centos-7 + +# +# Phase 1: First, let's ask a few things +# + +read -p "Enter username under which web2py will be installed [web2py]: " USERNAME +USERNAME=${USERNAME:-web2py} + +read -p "Enter path where web2py will be installed [/opt/web2py_apps]: " WEB2PY_PATH +WEB2PY_PATH=${WEB2PY_PATH:-/opt/web2py_apps} + +read -p "Web2py subdirectory will be called: [web2py]: " WEB2PY_APP +WEB2PY_APP=${WEB2PY_APP:-web2py} + +read -p "Enter your web2py admin password: " WEB2PY_PASS + +read -p "Enter your domain name: " YOUR_SERVER_DOMAIN + +# open new user +useradd -d $WEB2PY_PATH $USERNAME + +# if it's not already open, let's create a directory for web2py +mkdir -p $WEB2PY_PATH + +# now let's create a self signed certificate +cd $WEB2PY_PATH + +openssl req -x509 -new -newkey rsa:4096 -days 3652 -nodes -keyout $WEB2PY_APP.key -out $WEB2PY_APP.crt + +# +# phase 2: That was all the input that we needed so let's install the components +# + +echo "Installing necessary components" + +# Verify packages are up to date +yum -y upgrade + +# Install required packages +yum install -y epel-release +yum install -y python-devel python-pip gcc nginx wget unzip python-psycopg2 MySQL-python + +# download and unzip web2py + +echo "Downloading web2py" + +cd $WEB2PY_PATH +wget http://web2py.com/examples/static/web2py_src.zip +unzip web2py_src.zip +rm web2py_src.zip + +# preparing wsgihandler +chown -R $USERNAME.$USERNAME $WEB2PY_PATH/$WEB2PY_APP +mv $WEB2PY_PATH/$WEB2PY_APP/handlers/wsgihandler.py $WEB2PY_PATH/$WEB2PY_APP + +# now let's install uwsgi + +pip install uwsgi + +# preparing directories +mkdir -p /etc/uwsgi/sites +mkdir -p /var/log/uwsgi +mkdir -p /etc/nginx/ssl/ + +# +# Phase 3: Ok, everything is installed now so we'll configure things +# + +# Create configuration file for uwsgi in /etc/uwsgi/$WEB2PY_APP.ini +echo '[uwsgi] +chdir = WEB2PY_PATH_PLACEHOLDER/WEB2PY_APP_PLACEHOLDER +module = wsgihandler:application + +master = true +processes = 5 + +uid = USERNAME_PLACEHOLDER +socket = /run/uwsgi/WEB2PY_APP_PLACEHOLDER.sock +chown-socket = USERNAME_PLACEHOLDER:nginx +chmod-socket = 660 +vacuum = true +' >/etc/uwsgi/sites/$WEB2PY_APP.ini + +sed -i "s@WEB2PY_PATH_PLACEHOLDER@$WEB2PY_PATH@" /etc/uwsgi/sites/$WEB2PY_APP.ini +sed -i "s@WEB2PY_APP_PLACEHOLDER@$WEB2PY_APP@" /etc/uwsgi/sites/$WEB2PY_APP.ini +sed -i "s@USERNAME_PLACEHOLDER@$USERNAME@" /etc/uwsgi/sites/$WEB2PY_APP.ini + +# Create a daemon configuration file for uwsgi +cat > /etc/systemd/system/uwsgi.service <<EOF +[Unit] +Description=uWSGI Emperor service + +[Service] +ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown USERNAME_PLACEHOLDER:nginx /run/uwsgi' +ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/sites +Restart=always +KillSignal=SIGQUIT +Type=notify +NotifyAccess=all + +[Install] +WantedBy=multi-user.target +EOF + +sed -i "s@USERNAME_PLACEHOLDER@$USERNAME@" /etc/systemd/system/uwsgi.service + +#chmod 777 /etc/systemd/system/uwsgi.service + +# create a nginx configuration file +cat > /etc/nginx/nginx.conf <<EOF +# For more information on configuration, see: +# * Official English Documentation: http://nginx.org/en/docs/ +# * Official Russian Documentation: http://nginx.org/ru/docs/ + +user nginx; +worker_processes auto; +error_log /var/log/nginx/error.log; +pid /run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" ' + '\$status \$body_bytes_sent "\$http_referer" ' + '"\$http_user_agent" "\$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + # Load modular configuration files from the /etc/nginx/conf.d directory. + # See http://nginx.org/en/docs/ngx_core_module.html#include + # for more information. + include /etc/nginx/conf.d/*.conf; + + server { + listen 80 default_server; + listen [::]:80 default_server; + server_name YOUR_SERVER_DOMAIN_PLACEHOLDER; + root /usr/share/nginx/html; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + + location ~* /(\w+)/static/ { + root WEB2PY_PATH_PLACEHOLDER/WEB2PY_APP_PLACEHOLDER/applications/; + } + + location / { + include uwsgi_params; + uwsgi_pass unix:/run/uwsgi/WEB2PY_APP_PLACEHOLDER.sock; + } + + error_page 404 /404.html; + location = /40x.html { + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + } + } + + server { + listen 443; + server_name YOUR_SERVER_DOMAIN_PLACEHOLDER; + + ssl on; + ssl_certificate /etc/nginx/ssl/WEB2PY_APP_PLACEHOLDER.crt; + ssl_certificate_key /etc/nginx/ssl/WEB2PY_APP_PLACEHOLDER.key; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES"; + ssl_prefer_server_ciphers on; + + location / { + include uwsgi_params; + uwsgi_pass unix:/run/uwsgi/WEB2PY_APP_PLACEHOLDER.sock; + } + } +} +EOF + +sed -i "s@YOUR_SERVER_DOMAIN_PLACEHOLDER@$YOUR_SERVER_DOMAIN@" /etc/nginx/nginx.conf +sed -i "s@WEB2PY_PATH_PLACEHOLDER@$WEB2PY_PATH@" /etc/nginx/nginx.conf +sed -i "s@WEB2PY_APP_PLACEHOLDER@$WEB2PY_APP@" /etc/nginx/nginx.conf + +# +# Phase 4: everything is configured now, just a few final touches +# + +# copying certificates to nginx directory +mv $WEB2PY_PATH/$WEB2PY_APP.crt* /etc/nginx/ssl +mv $WEB2PY_PATH/$WEB2PY_APP.key* /etc/nginx/ssl + +# creating web2py admin password +cd $WEB2PY_PATH/$WEB2PY_APP +python -c "from gluon.main import save_password; save_password('$WEB2PY_PASS',443)" +chown -R $USERNAME.$USERNAME $WEB2PY_PATH/$WEB2PY_APP + +# taking care of permissions +chmod 700 /etc/nginx/ssl +usermod -a -G $USERNAME nginx +chmod 710 $WEB2PY_PATH + +# enabling daemons +systemctl start nginx +systemctl start uwsgi +systemctl enable nginx +systemctl enable uwsgi + +# If firewall is active make sure these ports are open + +firewall-cmd --zone=public --add-port=80/tcp --permanent +firewall-cmd --zone=public --add-port=443/tcp --permanent +firewall-cmd --zone=public --add-port=22/tcp --permanent +firewall-cmd --reload + +echo +echo 'Web2py is now installed on this server!' +echo + diff --git a/web2py/scripts/setup-web2py-nginx-uwsgi-on-centos.sh b/web2py/scripts/setup-web2py-nginx-uwsgi-on-centos.sh new file mode 100644 index 0000000..7c6dba3 --- /dev/null +++ b/web2py/scripts/setup-web2py-nginx-uwsgi-on-centos.sh @@ -0,0 +1,354 @@ +#!/bin/bash + +# ------------------------------------------------------------------- +# Description : Installation and basic configuration of web2py, +# uWSGI, andNGINX. +# in CentOS 5.x GNU/Linux +# Usage : Copy the script in /home/username and run it as root, +# you may need to allow execution (chmod +x) +# +# WARNING: This script was modified to install compiled +# versions of Python and other packages that may be +# available at your Centos package repository. +# This change was made in order to get the latest +# stable libraries available for avoiding compatibility +# +# A bug was reported for the 2.7.3 version of python +# here http://bugs.python.org/issue14572 +# in case you choose to change to VERSION=2.7 +# (see below) mind that the automatic patch applied +# could not work for your environment. By default, +# Python 2.6 is installed. +# +# It was originally posted in this web2py-users group +# thread: https://groups.google.com/forum/?fromgroups# +# !topic/web2py/O4c4Jfr18tM +# +# There are lots of subtleties of ownership, and one +# has to take care when installing python 2.6 not to +# stop the systems python2.4 from working. +# +# NOTE: The only thing that should need changing for +# each installation is the $BASEARCH (base +# architecture) +# of the machine. This is determined by doing uname -i. +# This is needed for the nginx installation. +# +# File : setup-web2py-nginx-uwsgi-on-centos.sh +# Author : Peter Hutchinson +# Modified by : Alan Etkin +# Email : spametki@gmail.com +# Copyright : web2py +# Date : 2013-01-28 +# Disclaimers : This script is provided "as is", without warranty of +# any kind. +# Licence : BSD +# ------------------------------------------------------------------- + +# Retrieve base architecture +BASEARCH=$(uname -i) + +# Get Web2py Admin Password +echo -e "Enter a password for web2py admin app: \c " +read PW + +echo 'Install development tools (it should take a while)' +yum install gcc gdbm-devel readline-devel ncurses-devel zlib-devel \ +bzip2-devel sqlite-devel db4-devel openssl-devel tk-devel bluez-libs-devel + +#================================= + +# You can change Python and uWSGI options +# to fit your deployment needs. + +# Python options +PREFIX=2.6 +VERSION=2.6.8 + +# uWSGI options +version=uwsgi-1.2.4 + +echo "Install python $PREFIX without overwriting python 2.4 (no, really, this will take a while too)" + +mkdir ~/src +chmod 777 ~/src +cd ~/src +wget http://www.python.org/ftp/python/$VERSION/Python-$VERSION.tgz +tar xvfz Python-$VERSION.tgz +cd Python-$VERSION + +if [ "$VERSION" == "2.7.3" ]; then + echo "Applying patch for sqlite3 bug from post http://bugs.python.org/msg161076" + curl -sk https://raw.github.com/gist/2727063/ | patch -p1 +fi + +./configure --prefix=/opt/python$PREFIX --with-threads --enable-shared +make + +#The altinstall ensures that python2.4 is left okay + +make altinstall +echo "/opt/python$PREFIX/lib">/etc/ld.so.conf.d/opt-python$PREFIX.conf +ldconfig + +#create alias so that python 2.x can be run with 'python2.x' + +alias -p python$PREFIX="/opt/python$/bin/python$PREFIX" +ln -s /opt/python$PREFIX/bin/python$PREFIX /usr/bin/python$PREFIX + +echo 'Install uwsgi' $version +cd ~ +curl -O http://projects.unbit.it/downloads/$version.tar.gz +tar zxvf $version.tar.gz +mkdir /opt/uwsgi-python +cp -R ./$version/* /opt/uwsgi-python +cd /opt/uwsgi-python + +echo "build using python $PREFIX" + +python$PREFIX uwsgiconfig.py --build +useradd uwsgi + +echo "Create and own uwsgi log" +# Note this log will need emptying from time to time + +touch /var/log/uwsgi.log +chown uwsgi /var/log/uwsgi.log + +echo "Install web2py" + +cd /opt +mkdir ./web-apps +cd ./web-apps +curl -O http://www.web2py.com/examples/static/web2py_src.zip +unzip web2py_src.zip +mv web2py/handlers/wsgihandler.py web2py/wsgihandler.py + +echo "Set the ownership for web2py application to uwsgi" +chown -R uwsgi /opt/web-apps/web2py +cd /opt/web-apps/web2py +chmod -R u+rwx ./applications + +echo "Now creating the admin password and creating the scaffolding app package" +sudo -u uwsgi python$PREFIX -c "from gluon.main import save_password;from gluon import widget;save_password('$PW',443);widget.console()" + +echo "Now install nginx" +cd /etc/yum.repos.d +echo "[nginx]">nginx.repo + +echo "baseurl=http://nginx.org/packages/centos/5/$BASEARCH/">>nginx.repo +echo "gpgcheck=0">>nginx.repo +echo "enabled=1">>nginx.repo +yum install nginx + +echo "We don't want the defaults, so remove them" +cd /etc/nginx/conf.d +mv default.conf default.conf.o +mv example_ssl.conf example_ssl.conf.o + +echo " +The following configuration files are also needed +The options for uwsgi are in the following file. +Other options could be included. +" + +echo "uwsgi_for_nginx.conf" + +echo " +[uwsgi] +uuid=uwsgi +pythonpath = /opt/web-apps/web2py +module = wsgihandler +socket=127.0.0.1:9001 +harakiri 60 +harakiri-verbose +enable-threads +daemonize = /var/log/uwsgi.log +" > /opt/uwsgi-python/uwsgi_for_nginx.conf + +chmod 755 /opt/uwsgi-python/uwsgi_for_nginx.conf + +echo " +The next configuration file is for nginx, and goes in /etc/nginx/conf.d +It serves the static directory of applications directly. I have not set up +ssl because I access web2py admin by using ssh tunneling and the web2py rocket server. +It should be straightforward to set up the ssl server however. +" + +echo "web2py.conf" + +echo ' +server { + listen 80; + server_name $hostname; + location ~* /(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$ { + alias /opt/web-apps/web2py/applications/$1/static/$2; + expires max; + } + location / { + uwsgi_pass 127.0.0.1:9001; + include uwsgi_params; + } +} + +server { + listen 443; + server_name $hostname; + ssl on; + ssl_certificate /etc/nginx/ssl/web2py.cert; + ssl_certificate_key /etc/nginx/ssl/web2py.key; + location / { + uwsgi_pass 127.0.0.1:9001; + include uwsgi_params; + uwsgi_param UWSGI_SCHEME $scheme; + } + location ~* /(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$ { + alias /opt/web-apps/web2py/applications/$1/static/$2; + expires max; + } +} +' > /etc/nginx/conf.d/web2py.conf + + +echo "Auto-signed ssl certs" +mkdir /etc/nginx/ssl +echo "creating a self signed certificate" +echo "==================================" +openssl genrsa 1024 > /etc/nginx/ssl/web2py.key +chmod 400 /etc/nginx/ssl/web2py.key +openssl req -new -x509 -nodes -sha1 -days 365 -key /etc/nginx/ssl/web2py.key > /etc/nginx/ssl/web2py.cert +openssl x509 -noout -fingerprint -text < /etc/nginx/ssl/web2py.cert > /etc/nginx/ssl/web2py.info + +echo "uwsgi as service" + +echo ' +#!/bin/bash + +# uwsgi - Use uwsgi to run python and wsgi web apps. +# +# chkconfig: - 85 15 +# description: Use uwsgi to run python and wsgi web apps. +# processname: uwsgi + +# author: Roman Vasilyev + +# Source function library. +. /etc/rc.d/init.d/functions + +########################### +PATH=/opt/uwsgi-python:/sbin:/bin:/usr/sbin:/usr/bin +PYTHONPATH=/home/www-data/web2py +MODULE=wsgihandler +PROG=/opt/uwsgi-python/uwsgi +OWNER=uwsgi +NAME=uwsgi +DESC=uwsgi +DAEMON_OPTS="-s 127.0.0.1:9001 -M 4 -t 30 -A 4 -p 16 -b 32768 -d \ +/var/log/$NAME.log --pidfile /var/run/$NAME.pid --uid $OWNER \ +--ini-paste /opt/uwsgi-python/uwsgi_for_nginx.conf" +############################## + +[ -f /etc/sysconfig/uwsgi ] && . /etc/sysconfig/uwsgi + +lockfile=/var/lock/subsys/uwsgi + +start () { + echo -n "Starting $DESC: " + daemon $PROG $DAEMON_OPTS + retval=$? + echo + [ $retval -eq 0 ] && touch $lockfile + return $retval +} + +stop () { + echo -n "Stopping $DESC: " + killproc $PROG + retval=$? + echo + [ $retval -eq 0 ] && rm -f $lockfile + return $retval +} + +reload () { + echo "Reloading $NAME" + killproc $PROG -HUP + RETVAL=$? + echo +} + +restart () { + stop + start +} + +rh_status () { + status $PROG +} + +rh_status_q() { + rh_status >/dev/null 2>&1 +} + +case "$1" in + start) + rh_status_q && exit 0 + $1 + ;; + stop) + rh_status_q || exit 0 + $1 + ;; + restart|force-reload) + $1 + ;; + reload) + rh_status_q || exit 7 + $1 + ;; + status) + rh_status + ;; + *) + echo "Usage: $0 {start|stop|restart|reload|force-reload|status}" >&2 + exit 2 + ;; + esac + exit 0 +' > /etc/init.d/uwsgi + +chmod 755 /etc/init.d/uwsgi +chkconfig --add uwsgi +chkconfig uwsgi on + +echo " +You can test it with + +service uwsgi start + +and stop it similarly. + +Nginx has automatically been set up as a service +if you want to start it run + +service nginx start + +You should find the web2py welcome app will be displayed at your web address. +As they are both services, they should automatically start on a system reboot. +If you already had a server running, such as apache, you would need to stop +that and turn its service off before running nginx. +" + +echo "Turning off apache service" + +service httpd stop +chkconfig httpd off +cd ~ + +echo " +Installation complete. You might want to restart your server running + +reboot + +as superuser +" diff --git a/web2py/scripts/setup-web2py-nginx-uwsgi-opensuse.sh b/web2py/scripts/setup-web2py-nginx-uwsgi-opensuse.sh new file mode 100644 index 0000000..bfaa9cd --- /dev/null +++ b/web2py/scripts/setup-web2py-nginx-uwsgi-opensuse.sh @@ -0,0 +1,224 @@ +#!/bin/bash +echo 'setup-web2py-nginx-uwsgi-opensuse.sh' +echo 'Requires OpenSUSE 12.3 32Bits and installs Nginx + uWSGI + Web2py' + + +# Get Web2py Admin Password +echo -e "Web2py Admin Password: \c " +read PW + +zypper clean && zypper refresh && zypper up +zypper in -y nginx python-xml python-pip unzip sudo +zypper in -y gcc python-devel libxml2-devel python-pip unzip +pip install --upgrade pip +PIPPATH=`which pip` +$PIPPATH install --upgrade uwsgi + + +# Prepare folders for uwsgi +mkdir /etc/uwsgi +mkdir /var/log/uwsgi + +usermod -G www nginx + +mkdir -p /etc/nginx/vhosts.d/ +mkdir -p /etc/nginx/ssl/ + + +cd /etc/nginx/ssl +openssl genrsa 1024 > web2py.key +chmod 400 web2py.key +openssl req -new -x509 -nodes -sha1 -days 1780 -key web2py.key > web2py.crt +openssl x509 -noout -fingerprint -text < web2py.crt > web2py.info + + +echo 'server { + listen 80; + server_name $hostname; + #to enable correct use of response.static_version + location ~* /(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$ { + alias /srv/www/web2py/applications/$1/static/$2; + expires max; + } + location / { + #uwsgi_pass 127.0.0.1:9001; + uwsgi_pass unix:///tmp/web2py.socket; + include /etc/nginx/uwsgi_params; + uwsgi_param UWSGI_SCHEME $scheme; + uwsgi_param SERVER_SOFTWARE nginx/$nginx_version; + } +} +server { + listen 443 default_server ssl; + server_name $hostname; + ssl_certificate /etc/nginx/ssl/web2py.crt; + ssl_certificate_key /etc/nginx/ssl/web2py.key; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + ssl_ciphers ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA; + ssl_protocols SSLv3 TLSv1; + keepalive_timeout 70; + location ~* /(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$ { + alias /srv/www/web2py/applications/$1/static/$2; + expires max; + } + location / { + #uwsgi_pass 127.0.0.1:9001; + uwsgi_pass unix:///tmp/web2py.socket; + include /etc/nginx/uwsgi_params; + uwsgi_param UWSGI_SCHEME $scheme; + uwsgi_param SERVER_SOFTWARE nginx/$nginx_version; + } + +}' >/etc/nginx/vhosts.d/web2py.conf + + + +# Create configuration file /etc/uwsgi/web2py.xml +echo '<uwsgi> + <socket>/tmp/web2py.socket</socket> + <pythonpath>/srv/www/web2py/</pythonpath> + <mount>/=wsgihandler:application</mount> + <master/> + <processes>4</processes> + <harakiri>60</harakiri> + <reload-mercy>8</reload-mercy> + <cpu-affinity>1</cpu-affinity> + <stats>/tmp/stats.socket</stats> + <max-requests>2000</max-requests> + <limit-as>512</limit-as> + <reload-on-as>256</reload-on-as> + <reload-on-rss>192</reload-on-rss> + <uid>nginx</uid> + <gid>www</gid> + <cron>0 0 -1 -1 -1 python /srv/www/web2py/web2py.py -Q -S welcome -M -R scripts/sessions2trash.py -A -o</cron> + <no-orphans/> +</uwsgi>' >/etc/uwsgi/web2py.xml + + +cd /srv/www/ +wget http://web2py.com/examples/static/web2py_src.zip +unzip web2py_src.zip +rm web2py_src.zip +mv web2py/handlers/wsgihandler.py web2py/wsgihandler.py +chown -R nginx:www web2py +cd /srv/www/web2py +sudo -u nginx python -c "from gluon.main import save_password; save_password('$PW',443)" + + + +## Daemons /start/stop + +echo '#!/bin/sh +# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany. +# +# Author: James Oakley +# +# /etc/init.d/uwsgi +# and its symbolic link +# /(usr/)sbin/rcuwsgi +# +# LSB compatible service control script; see http://www.linuxbase.org/spec/ +# +### BEGIN INIT INFO +# Provides: uwsgi +# Required-Start: $syslog $remote_fs +# Should-Start: $time ypbind smtp +# Required-Stop: $syslog $remote_fs +# Should-Stop: ypbind smtp +# Default-Start: 3 5 +# Default-Stop: 0 1 2 6 +# Short-Description: Application Container Server for Networked/Clustered Web Applications +# Description: Application Container Server for Networked/Clustered Web Applications +### END INIT INFO + +# Check for missing binaries (stale symlinks should not happen) +UWSGI_BIN=/usr/bin/uwsgi +test -x $UWSGI_BIN || { echo "$UWSGI_BIN not installed"; + if [ "$1" = "stop" ]; then exit 0; + else exit 5; fi; } + +UWSGI_EMPEROR_MODE=true +UWSGI_VASSALS="/etc/uwsgi/" +UWSGI_OPTIONS="--logto /var/log/uwsgi/uwsgi.log" + + +UWSGI_OPTIONS="$UWSGI_OPTIONS --autoload" + +if [ "$UWSGI_EMPEROR_MODE" = "true" ] ; then + UWSGI_OPTIONS="$UWSGI_OPTIONS --emperor $UWSGI_VASSALS" +fi + +. /etc/rc.status + +rc_reset + +case "$1" in + start) + echo -n "Starting uWSGI " + /sbin/startproc $UWSGI_BIN $UWSGI_OPTIONS + rc_status -v + ;; + stop) + echo -n "Shutting down uWSGI " + /sbin/killproc $UWSGI_BIN + rc_status -v + ;; + try-restart|condrestart) + if test "$1" = "condrestart"; then + echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}" + fi + $0 status + if test $? = 0; then + $0 restart + else + rc_reset + fi + rc_status + ;; + restart) + $0 stop + $0 start + rc_status + ;; + force-reload) + echo -n "Reload service uWSGI " + /sbin/killproc -HUP $UWSGI_BIN + rc_status -v + ;; + reload) + echo -n "Reload service uWSGI " + /sbin/killproc -HUP $UWSGI_BIN + rc_status -v + ;; + status) + echo -n "Checking for service uWSGI " + /sbin/checkproc $UWSGI_BIN + rc_status -v + ;; + probe) + echo -n "uWSGI does not support probe " + rc_failed 3 + rc_status -v + ;; + *) + echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}" + exit 1 + ;; +esac +rc_exit '> /etc/init.d/uwsgi + + +chmod +x /etc/init.d/uwsgi +/etc/init.d/uwsgi start +/etc/init.d/nginx restart + + +chkconfig --add uwsgi +chkconfig --add nginx + +## you can reload uwsgi with +#/etc/init.d/uwsgi restart +## to reload web2py only (without restarting uwsgi) +# touch /etc/uwsgi/web2py.xml diff --git a/web2py/scripts/setup-web2py-nginx-uwsgi-ubuntu.sh b/web2py/scripts/setup-web2py-nginx-uwsgi-ubuntu.sh new file mode 100644 index 0000000..e34959d --- /dev/null +++ b/web2py/scripts/setup-web2py-nginx-uwsgi-ubuntu.sh @@ -0,0 +1,233 @@ +#!/bin/bash +echo 'setup-web2py-nginx-uwsgi-ubuntu-precise.sh' +echo 'Requires Ubuntu > 12.04 or Debian >= 8 and installs Nginx + uWSGI + Web2py' +# Check if user has root privileges +if [[ $EUID -ne 0 ]]; then + echo "You must run the script as root or using sudo" + exit 1 +fi +# parse command line arguments +nopassword=0 +nocertificate=0 +while [ "$#" -gt 0 ]; do + case "$1" in + --no-password) nopassword=1; shift 1;; + --no-certificate) nocertificate=1; shift 1;; + esac +done +# Get Web2py Admin Password +if [ "$nopassword" -eq 0 ] +then + echo -e "Web2py Admin Password: \c " + read -s PW + printf "\n" # fix no new line artifact of "read -s" to avoid cleartext password +fi +# Upgrade and install needed software +apt-get update +apt-get -y upgrade +apt-get autoremove +apt-get autoclean +apt-get -y install nginx-full +apt-get -y install build-essential python-dev libxml2-dev python-pip unzip +pip install setuptools --no-use-wheel --upgrade +PIPPATH=`which pip` +$PIPPATH install --upgrade uwsgi +# Create common nginx sections +mkdir /etc/nginx/conf.d/web2py +echo ' +gzip_static on; +gzip_http_version 1.1; +gzip_proxied expired no-cache no-store private auth; +gzip_disable "MSIE [1-6]\."; +gzip_vary on; +' > /etc/nginx/conf.d/web2py/gzip_static.conf +echo ' +gzip on; +gzip_disable "msie6"; +gzip_vary on; +gzip_proxied any; +gzip_comp_level 6; +gzip_buffers 16 8k; +gzip_http_version 1.1; +gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; +' > /etc/nginx/conf.d/web2py/gzip.conf +# Create configuration file /etc/nginx/sites-available/web2py +echo 'server { + listen 80; + server_name $hostname; + ###to enable correct use of response.static_version + location ~* ^/(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$ { + alias /home/www-data/web2py/applications/$1/static/$2; + expires max; + ### if you want to use pre-gzipped static files (recommended) + ### check scripts/zip_static_files.py and remove the comments + # include /etc/nginx/conf.d/web2py/gzip_static.conf; + } + ### + + ###if you use something like myapp = dict(languages=['en', 'it', 'jp'], default_language='en') in your routes.py + #location ~* ^/(\w+)/(en|it|jp)/static/(.*)$ { + # alias /home/www-data/web2py/applications/$1/; + # try_files static/$2/$3 static/$3 =404; + #} + ### + + location / { + #uwsgi_pass 127.0.0.1:9001; + uwsgi_pass unix:///tmp/web2py.socket; + include uwsgi_params; + uwsgi_param UWSGI_SCHEME $scheme; + uwsgi_param SERVER_SOFTWARE nginx/$nginx_version; + + ###remove the comments to turn on if you want gzip compression of your pages + # include /etc/nginx/conf.d/web2py/gzip.conf; + ### end gzip section + + ### remove the comments if you use uploads (max 10 MB) + #client_max_body_size 10m; + ### + } +} +server { + listen 443 default_server ssl; + server_name $hostname; + ssl_certificate /etc/nginx/ssl/web2py.crt; + ssl_certificate_key /etc/nginx/ssl/web2py.key; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + ssl_ciphers ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + keepalive_timeout 70; + location / { + #uwsgi_pass 127.0.0.1:9001; + uwsgi_pass unix:///tmp/web2py.socket; + include uwsgi_params; + uwsgi_param UWSGI_SCHEME $scheme; + uwsgi_param SERVER_SOFTWARE nginx/$nginx_version; + ###remove the comments to turn on if you want gzip compression of your pages + # include /etc/nginx/conf.d/web2py/gzip.conf; + ### end gzip section + ### remove the comments if you want to enable uploads (max 10 MB) + #client_max_body_size 10m; + ### + } + ###to enable correct use of response.static_version + location ~* ^/(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$ { + alias /home/www-data/web2py/applications/$1/static/$2; + expires max; + ### if you want to use pre-gzipped static files (recommended) + ### check scripts/zip_static_files.py and remove the comments + # include /etc/nginx/conf.d/web2py/gzip_static.conf; + } + ### + +}' >/etc/nginx/sites-available/web2py + +ln -s /etc/nginx/sites-available/web2py /etc/nginx/sites-enabled/web2py +rm /etc/nginx/sites-enabled/default +mkdir /etc/nginx/ssl +cd /etc/nginx/ssl +if [ "$nocertificate" -eq 0 ] +then + openssl genrsa 1024 > web2py.key + chmod 400 web2py.key + openssl req -new -x509 -nodes -sha1 -days 1780 -key web2py.key > web2py.crt + openssl x509 -noout -fingerprint -text < web2py.crt > web2py.info +fi +# Prepare folders for uwsgi +sudo mkdir /etc/uwsgi +sudo mkdir /var/log/uwsgi +sudo mkdir /etc/systemd +sudo mkdir /etc/systemd/system + +#uWSGI Emperor +echo '[Unit] +Description = uWSGI Emperor +After = syslog.target + +[Service] +ExecStart = /usr/local/bin/uwsgi --ini /etc/uwsgi/web2py.ini +RuntimeDirectory = uwsgi +Restart = always +KillSignal = SIGQUIT +Type = notify +StandardError = syslog +NotifyAccess = all + +[Install] +WantedBy = multi-user.target +' > /etc/systemd/system/emperor.uwsgi.service + +# Create configuration file /etc/uwsgi/web2py.ini +echo '[uwsgi] + +socket = /tmp/web2py.socket +pythonpath = /home/www-data/web2py/ +mount = /=wsgihandler:application +processes = 4 +master = true +harakiri = 60 +reload-mercy = 8 +cpu-affinity = 1 +stats = /tmp/stats.socket +max-requests = 2000 +limit-as = 512 +reload-on-as = 256 +reload-on-rss = 192 +uid = www-data +gid = www-data +touch-reload = /home/www-data/web2py/routes.py +cron = 0 0 -1 -1 -1 python /home/www-data/web2py/web2py.py -Q -S welcome -M -R scripts/sessions2trash.py -A -o +no-orphans = true +' >/etc/uwsgi/web2py.ini + +#Create a configuration file for uwsgi in emperor-mode +#for Upstart in /etc/init/uwsgi-emperor.conf +echo '# Emperor uWSGI script + +description "uWSGI Emperor" +start on runlevel [2345] +stop on runlevel [06] +## +#remove the comments in the next section to enable static file compression for the welcome app +#in that case, turn on gzip_static on; on /etc/nginx/nginx.conf +## +#pre-start script +# python /home/www-data/web2py/web2py.py -S welcome -R scripts/zip_static_files.py +# chown -R www-data:www-data /home/www-data/web2py/* +#end script +respawn +exec uwsgi --master --die-on-term --emperor /etc/uwsgi --logto /var/log/uwsgi/uwsgi.log +' > /etc/init/uwsgi-emperor.conf +# Install Web2py +mkdir /home/www-data +cd /home/www-data +wget http://web2py.com/examples/static/web2py_src.zip +unzip web2py_src.zip +mv web2py/handlers/wsgihandler.py web2py/wsgihandler.py +rm web2py_src.zip +chown -R www-data:www-data web2py +cd /home/www-data/web2py +if [ "$nopassword" -eq 0 ] +then + sudo -u www-data python -c "from gluon.main import save_password; save_password('$PW',443)" +fi + +/etc/init.d/nginx start +systemctl start emperor.uwsgi.service +systemctl enable emperor.uwsgi.service + +echo <<EOF +you can stop uwsgi and nginx with + + sudo /etc/init.d/nginx stop + sudo systemctl stop emperor.uwsgi.service + +and start it with + + sudo /etc/init.d/nginx start + systemctl start emperor.uwsgi.service + +EOF + diff --git a/web2py/scripts/setup-web2py-ubuntu.sh b/web2py/scripts/setup-web2py-ubuntu.sh new file mode 100644 index 0000000..8de3050 --- /dev/null +++ b/web2py/scripts/setup-web2py-ubuntu.sh @@ -0,0 +1,167 @@ +#!/bin/bash +echo "This script will: +1) install all modules need to run web2py on Ubuntu 14.04 +2) install web2py in /home/www-data/ +3) create a self signed ssl certificate +4) setup web2py with mod_wsgi +5) overwrite /etc/apache2/sites-available/default +6) restart apache. + +You may want to read this script before running it. + +Press a key to continue...[ctrl+C to abort]" + +read CONFIRM + + +# optional +# dpkg-reconfigure console-setup +# dpkg-reconfigure timezoneconf +# nano /etc/hostname +# nano /etc/network/interfaces +# nano /etc/resolv.conf +# reboot now +# ifconfig eth0 + +echo "installing useful packages" +echo "==========================" +apt-get update +apt-get -y install ssh +apt-get -y install zip unzip +apt-get -y install tar +apt-get -y install openssh-server +apt-get -y install build-essential +apt-get -y install python +#apt-get -y install python2.5 +apt-get -y install ipython +apt-get -y install python-dev +apt-get -y install postgresql +apt-get -y install apache2 +apt-get -y install libapache2-mod-wsgi +apt-get -y install python2.5-psycopg2 +apt-get -y install postfix +apt-get -y install wget +apt-get -y install python-matplotlib +apt-get -y install python-reportlab +apt-get -y install mercurial +/etc/init.d/postgresql restart + +# optional, uncomment for emacs +# apt-get -y install emacs + +# optional, uncomment for backups using samba +# apt-get -y install samba +# apt-get -y install smbfs + +echo "downloading, installing and starting web2py" +echo "===========================================" +cd /home +mkdir www-data +cd www-data +rm web2py_src.zip* +wget http://web2py.com/examples/static/web2py_src.zip +unzip web2py_src.zip +mv web2py/handlers/wsgihandler.py web2py/wsgihandler.py +chown -R www-data:www-data web2py + +echo "setting up apache modules" +echo "=========================" +a2enmod ssl +a2enmod proxy +a2enmod proxy_http +a2enmod headers +a2enmod expires +a2enmod wsgi +a2enmod rewrite # for 14.04 +mkdir /etc/apache2/ssl + +echo "creating a self signed certificate" +echo "==================================" +openssl genrsa 1024 > /etc/apache2/ssl/self_signed.key +chmod 400 /etc/apache2/ssl/self_signed.key +openssl req -new -x509 -nodes -sha1 -days 365 -key /etc/apache2/ssl/self_signed.key > /etc/apache2/ssl/self_signed.cert +openssl x509 -noout -fingerprint -text < /etc/apache2/ssl/self_signed.cert > /etc/apache2/ssl/self_signed.info + +echo "rewriting your apache config file to use mod_wsgi" +echo "=================================================" +echo ' +WSGIDaemonProcess web2py user=www-data group=www-data + +<VirtualHost *:80> + + WSGIProcessGroup web2py + WSGIScriptAlias / /home/www-data/web2py/wsgihandler.py + WSGIPassAuthorization On + + <Directory /home/www-data/web2py> + AllowOverride None + Require all denied + <Files wsgihandler.py> + Require all granted + </Files> + </Directory> + + AliasMatch ^/([^/]+)/static/(?:_[\d]+.[\d]+.[\d]+/)?(.*) \ + /home/www-data/web2py/applications/$1/static/$2 + + <Directory /home/www-data/web2py/applications/*/static/> + Options -Indexes + ExpiresActive On + ExpiresDefault "access plus 1 hour" + Require all granted + </Directory> + + CustomLog /var/log/apache2/access.log common + ErrorLog /var/log/apache2/error.log +</VirtualHost> + +<VirtualHost *:443> + SSLEngine on + SSLCertificateFile /etc/apache2/ssl/self_signed.cert + SSLCertificateKeyFile /etc/apache2/ssl/self_signed.key + + WSGIProcessGroup web2py + WSGIScriptAlias / /home/www-data/web2py/wsgihandler.py + WSGIPassAuthorization On + + <Directory /home/www-data/web2py> + AllowOverride None + Require all denied + <Files wsgihandler.py> + Require all granted + </Files> + </Directory> + + AliasMatch ^/([^/]+)/static/(?:_[\d]+.[\d]+.[\d]+/)?(.*) \ + /home/www-data/web2py/applications/$1/static/$2 + + <Directory /home/www-data/web2py/applications/*/static/> + Options -Indexes + ExpiresActive On + ExpiresDefault "access plus 1 hour" + Require all granted + </Directory> + + CustomLog /var/log/apache2/ssl-access.log common + ErrorLog /var/log/apache2/error.log +</VirtualHost> +' > /etc/apache2/sites-available/default.conf # FOR 14.04 + +sudo rm /etc/apache2/sites-enabled/* # FOR 14.04 +sudo a2ensite default # FOR 14.04 + +# echo "setting up PAM" +# echo "================" +# sudo apt-get install pwauth +# sudo ln -s /etc/apache2/mods-available/authnz_external.load /etc/apache2/mods-enabled +# ln -s /etc/pam.d/apache2 /etc/pam.d/httpd +# usermod -a -G shadow www-data + +echo "restarting apache" +echo "================" + +/etc/init.d/apache2 restart +cd /home/www-data/web2py +sudo -u www-data python -c "from gluon.widget import console; console();" +sudo -u www-data python -c "from gluon.main import save_password; save_password(raw_input('admin password: '),443)" +echo "done!" diff --git a/web2py/scripts/standalone_exe_cxfreeze.py b/web2py/scripts/standalone_exe_cxfreeze.py new file mode 100644 index 0000000..a21451f --- /dev/null +++ b/web2py/scripts/standalone_exe_cxfreeze.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Usage: + Install cx_Freeze: http://cx-freeze.sourceforge.net/ + Copy script to the web2py directory + c:\Python27\python standalone_exe_cxfreeze.py build_exe +""" +from cx_Freeze import setup, Executable +from gluon.import_all import base_modules, contributed_modules +from gluon.fileutils import readlines_file +from glob import glob +import fnmatch +import os +import shutil +import sys +import re + +#read web2py version from VERSION file +web2py_version_line = readlines_file('VERSION')[0] +#use regular expression to get just the version number +v_re = re.compile('[0-9]+\.[0-9]+\.[0-9]+') +web2py_version = v_re.search(web2py_version_line).group(0) + +base = None + +if sys.platform == 'win32': + base = "Win32GUI" + +base_modules.remove('macpath') +buildOptions = dict( + compressed=True, + excludes=["macpath", "PyQt4"], + includes=base_modules, + include_files=[ + 'applications', + 'ABOUT', + 'LICENSE', + 'VERSION', + 'logging.example.conf', + 'options_std.py', + 'app.example.yaml', + 'queue.example.yaml', + ], + # append any extra module by extending the list below - + # "contributed_modules+["lxml"]" + packages=contributed_modules, +) + +setup( + name="Web2py", + version=web2py_version, + author="Massimo DiPierro", + description="web2py web framework", + license="LGPL v3", + options=dict(build_exe=buildOptions), + executables=[Executable("web2py.py", + base=base, + compress=True, + icon="web2py.ico", + targetName="web2py.exe", + copyDependentFiles=True)], +) diff --git a/web2py/scripts/sync_languages.py b/web2py/scripts/sync_languages.py new file mode 100644 index 0000000..76087d4 --- /dev/null +++ b/web2py/scripts/sync_languages.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# TODO: Comment this code + +import sys +import shutil +import os + +from gluon.languages import findT + +sys.path.insert(0, '.') + +def sync_language(d, data): + ''' this function makes sure a translated string will be prefered over an untranslated + string when syncing languages between apps. when both are translated, it prefers the + latter app, as did the original script + ''' + + for key in data: + # if this string is not in the allready translated data, add it + if key not in d: + d[key] = data[key] + # see if there is a translated string in the original list, but not in the new list + elif ( + ((d[key] != '') or (d[key] != key)) and + ((data[key] == '') or (data[key] == key)) + ): + d[key] = d[key] + # any other case (wether there is or there isn't a translated string) + else: + d[key] = data[key] + + return d + +def sync_main(file, apps): + d = {} + for app in apps: + path = 'applications/%s/' % app + findT(path, file) + langfile = open(os.path.join(path, 'languages', '%s.py' % file)) + try: + data = eval(langfile.read()) + finally: + langfile.close() + + d = sync_language(d, data) + + + path = 'applications/%s/' % apps[-1] + file1 = os.path.join(path, 'languages', '%s.py' % file) + + f = open(file1, 'w') + try: + f.write('# coding: utf8\n') + f.write('{\n') + keys = d.keys() + keys.sort() + for key in keys: + f.write("'''%s''':'''%s''',\n" % (key.replace("'", "\\'"), str(d[key].replace("'", "\\'")))) + f.write('}\n') + finally: + f.close() + + oapps = reversed(apps[:-1]) + for app in oapps: + path2 = 'applications/%s/' % app + file2 = os.path.join(path2, 'languages', '%s.py' % file) + if file1 != file2: + shutil.copyfile(file1, file2) + +if __name__ == "__main__": + + file = sys.argv[1] + apps = sys.argv[2:] + + sync_main(file, apps) diff --git a/web2py/scripts/tickets2db.py b/web2py/scripts/tickets2db.py new file mode 100644 index 0000000..da49948 --- /dev/null +++ b/web2py/scripts/tickets2db.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys +import os +import time +import stat +import datetime + +from gluon.utils import md5_hash +from gluon.restricted import RestrictedError, TicketStorage +from gluon import DAL + +SLEEP_MINUTES = 5 + +errors_path = os.path.join(request.folder, 'errors') +try: + db_string = open(os.path.join(request.folder, 'private', 'ticket_storage.txt')).read().replace('\r', '').replace('\n', '').strip() +except: + db_string = 'sqlite://storage.db' + +db_path = os.path.join(request.folder, 'databases') + +tk_db = DAL(db_string, folder=db_path, auto_import=True) +ts = TicketStorage(db=tk_db) +tk_table = ts._get_table( + db=tk_db, tablename=ts.tablename, app=request.application) + + +hashes = {} + +while 1: + if request.tickets_db: + print("You're storing tickets yet in database") + sys.exit(1) + + for file in os.listdir(errors_path): + filename = os.path.join(errors_path, file) + + modified_time = os.stat(filename)[stat.ST_MTIME] + modified_time = datetime.datetime.fromtimestamp(modified_time) + ticket_id = file + ticket_data = open(filename).read() + tk_table.insert(ticket_id=ticket_id, + ticket_data=ticket_data, + created_datetime=modified_time + ) + tk_db.commit() + os.unlink(filename) + + time.sleep(SLEEP_MINUTES * 60) diff --git a/web2py/scripts/tickets2email.py b/web2py/scripts/tickets2email.py new file mode 100644 index 0000000..8fe4e89 --- /dev/null +++ b/web2py/scripts/tickets2email.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys +import os +import time +import stat +import datetime + +from gluon.utils import md5_hash +from gluon.restricted import RestrictedError +from gluon.tools import Mail + + +path = os.path.join(request.folder, 'errors') +hashes = {} +mail = Mail() + +### CONFIGURE HERE +SLEEP_MINUTES = 5 +ALLOW_DUPLICATES = True +mail.settings.server = 'localhost:25' +mail.settings.sender = 'you@localhost' +administrator_email = 'you@localhost' +### END CONFIGURATION + +while 1: + for file in os.listdir(path): + if not ALLOW_DUPLICATES: + fileobj = open(file, 'r') + try: + file_data = fileobj.read() + finally: + fileobj.close() + key = md5_hash(file_data) + + if key in hashes: + continue + + hashes[key] = 1 + + error = RestrictedError() + error.load(request, request.application, file) + + mail.send(to=administrator_email, + subject='new web2py ticket', message=error.traceback) + + os.unlink(os.path.join(path, file)) + time.sleep(SLEEP_MINUTES * 60) diff --git a/web2py/scripts/tickets2slack.py b/web2py/scripts/tickets2slack.py new file mode 100644 index 0000000..c9d181b --- /dev/null +++ b/web2py/scripts/tickets2slack.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Post error tickets to slack on a 5 minute schedule. +# +# Proper use depends on having created a web-hook through Slack, and having set +# that value in your app's model as the value of global_settings.slack_hook. +# Details on creating web-hooks can be found at https://slack.com/integrations +# +# requires the Requests module for posting to slack, other requirements are +# standard or provided by web2py +# +# Usage (on Unices), replace myapp with the name of your application and run: +# nohup python web2py.py -S myapp -M -R scripts/tickets2slack.py & + +import sys +import os +import time +import pickle +import json + +try: + import requests +except ImportError as e: + print("missing module 'Requests', aborting.") + sys.exit(1) + +from gluon import URL +from gluon.utils import md5_hash +from gluon.restricted import RestrictedError +from gluon.settings import global_settings + + +path = os.path.join(request.folder, 'errors') +sent_errors_file = os.path.join(path, 'slack_errors.pickle') +hashes = {} +if os.path.exists(sent_errors_file): + try: + with open(sent_errors_file, 'rb') as f: + hashes = pickle.load(f) + except Exception as _: + pass + +# ## CONFIGURE HERE +SLEEP_MINUTES = 5 +ALLOW_DUPLICATES = False +global_settings.slack_hook = global_settings.slack_hook or \ + 'https://hooks.slack.com/services/your_service' +# ## END CONFIGURATION + +while 1: + for file_name in os.listdir(path): + if file_name == 'slack_errors.pickle': + continue + + if not ALLOW_DUPLICATES: + key = md5_hash(file_name) + if key in hashes: + continue + hashes[key] = 1 + + error = RestrictedError() + + try: + error.load(request, request.application, file_name) + except Exception as _: + continue # not an exception file? + + url = URL(a='admin', f='ticket', args=[request.application, file], + scheme=True) + payload = json.dumps(dict(text="Error in %(app)s.\n%(url)s" % + dict(app=request.application, url=url))) + + requests.post(global_settings.slack_hook, data=dict(payload=payload)) + + with open(sent_errors_file, 'wb') as f: + pickle.dump(hashes, f) + time.sleep(SLEEP_MINUTES * 60) diff --git a/web2py/scripts/update-web2py.sh b/web2py/scripts/update-web2py.sh new file mode 100644 index 0000000..2ad8840 --- /dev/null +++ b/web2py/scripts/update-web2py.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# +# update-web2py.sh +# 2009-12-16 +# +# install in web2py/.. or web2py/ or web2py/scripts as update-web2py.sh +# make executable: chmod +x web2py.sh +# +# save a snapshot of current web2py/ as web2py/../web2py-version.zip +# download the current stable version of web2py +# unzip downloaded version over web2py/ +# +TARGET=web2py + +if [ ! -d $TARGET ]; then + # in case we're in web2py/ + if [ -f ../$TARGET/VERSION ]; then + cd .. + # in case we're in web2py/scripts + elif [ -f ../../$TARGET/VERSION ]; then + cd ../.. + fi +fi +read a VERSION c < $TARGET/VERSION +SAVE=$TARGET-$VERSION +URL=http://www.web2py.com/examples/static/web2py_src.zip + +ZIP=`basename $URL` +SAVED="" + +# Save a zip archive of the current version, +# but don't overwrite a previous save of the same version. +# +if [ -f $SAVE.zip ]; then + echo "Remove or rename $SAVE.zip first" >&2 + exit 1 +fi +if [ -d $TARGET ]; then + echo -n ">>Save old version: " >&2 + cat $TARGET/VERSION >&2 + zip -q -r $SAVE.zip $TARGET + SAVED=$SAVE.zip +fi +# +# Download the new version. +# +echo ">>Download latest web2py release:" >&2 +curl -O $URL +# +# Unzip into web2py/ +# +unzip -q -o $ZIP +rm $ZIP +echo -n ">>New version: " >&2 +cat $TARGET/VERSION >&2 +if [ "$SAVED" != "" ]; then + echo ">>Old version saved as $SAVED" +fi diff --git a/web2py/scripts/update_languages.py b/web2py/scripts/update_languages.py new file mode 100644 index 0000000..a918379 --- /dev/null +++ b/web2py/scripts/update_languages.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Written by Vinyl Darkscratch, www.queengoob.org + +# TODO: add comments + +import os +import ast +import sys +import inspect + +currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +parentdir = os.path.dirname(currentdir) +sys.path.insert(0, parentdir) + +from gluon.cfs import getcfs +from gluon.utf8 import Utf8 +from gluon._compat import copyreg, PY2, maketrans, iterkeys, unicodeT, to_unicode, to_bytes, iteritems, to_native, pjoin +from gluon.languages import findT + +# This script can be run with no arguments (which sets the application folder to the current working directory, and default language to English), one argument (which sets the default language), or two arguments (application folder path and default language). +# When run, it will update the default language, as well as strip all of the strings found in the non-default languages but not in the default language, and add the strings found in the default language to the non-default languages it is not, making sure translators don't do additional work that will never be used. + +def read_dict_aux(filename): + lang_text = open(filename, 'r').read().replace(b'\r\n', b'\n') + try: + return safe_eval(to_native(lang_text)) or {} + except Exception: + e = sys.exc_info()[1] + status = 'Syntax error in %s (%s)' % (filename, e) + return {'__corrupted__': status} + +def read_dict(filename): + return getcfs('lang:' + filename, filename, lambda: read_dict_aux(filename)) + +def safe_eval(text): + if text.strip(): + try: + return ast.literal_eval(text) + except ImportError: + return eval(text, {}, {}) + return None + +def sort_function(x, y): + return cmp(unicode(x, 'utf-8').lower(), unicode(y, 'utf-8').lower()) + +def write_file(file, contents): + file.write('# -*- coding: utf-8 -*-\n{\n') + for key in sorted(contents, sort_function): + file.write('%s: %s,\n' % (repr(Utf8(key)), + repr(Utf8(contents[key])))) + file.write('}\n') + file.close() + +def update_languages(cwd, default_lang): + defaultfp = os.path.join(cwd, "languages", '%s.py' %default_lang) + findT(cwd, default_lang) + default = read_dict(defaultfp) + + for lang in os.listdir(os.path.join(cwd, "languages")): + if lang == default_lang+".py" or lang.startswith("plural-"): continue + + i18n = read_dict(os.path.join(cwd, "languages", lang)) + if i18n: + new_dict = default + for phrase in i18n: + if phrase in default: + new_dict[phrase] = i18n[phrase] + write_file(open(os.path.join(cwd, "languages", lang), 'w'), new_dict) + print lang + +if __name__ == "__main__": + cwd = os.getcwd() + default_lang = 'en' + + if len(sys.argv) > 2: + cwd = sys.argv[1] + default_lang = sys.argv[2] + elif len(sys.argv) > 1: + default_lang = sys.argv[1] + + update_languages(cwd, default_lang) diff --git a/web2py/scripts/web2py-lock.sh b/web2py/scripts/web2py-lock.sh new file mode 100644 index 0000000..e17cd16 --- /dev/null +++ b/web2py/scripts/web2py-lock.sh @@ -0,0 +1,11 @@ +chown -R nobody:nobody *.py +chown -R nobody:nobody gluon +chown -R nobody:nobody scripts +chown -R nobody:nobody applications/*/modules/ +chown -R nobody:nobody applications/*/models/ +chown -R nobody:nobody applications/*/controllers/ +chown -R nobody:nobody applications/*/views/ +chown -R nobody:nobody applications/*/static/ +chown -R nobody:nobody applications/*/cron/ + +echo "unlock with chown -R www-data:www-data ./" diff --git a/web2py/scripts/web2py.archlinux.sh b/web2py/scripts/web2py.archlinux.sh new file mode 100644 index 0000000..b6c56ea --- /dev/null +++ b/web2py/scripts/web2py.archlinux.sh @@ -0,0 +1,57 @@ +#!/bin/bash +# the script should be run +# from WEB2PY root directory + +prog="web2py.py" + +chmod +x $prog + +function web2py_start { + nohup python2 ./$prog -a "<recycle>" >>/dev/null 2>/dev/null & + pid=`pgrep -f $prog | tail -1` + if [ "x$pid" != "x$$" ] + then + echo "WEB2PY has been started (pid $pid). Stop it with '$0 stop'" + else + echo "Failed to start WEB2PY." + fi +} + +function web2py_stop { + pid="`pgrep -f $prog | grep -v $$`" + if [ "x$pid" == "x" ] + then + echo "No WEB2PY processes to stop." + else + kill -15 $pid + # Wait for web2py to shut down gracefully. + sleep 2 + pid="`pgrep -f $prog | head -1`" + if [ "x$pid" == "x" ] + then + echo "WEB2PY has been stopped." + else + echo "Failed to stop WEB2PY. (Possibly, only one of several web2py processes was killed.)" + echo "Still running:" + pgrep -af $prog + fi + fi +} + +case "$1" in + start) + web2py_start + ;; + stop) + web2py_stop + ;; + restart) + web2py_stop + web2py_start + ;; + *) + echo "Usage: $0 [start|stop|restart]" + ;; +esac + +exit 0 diff --git a/web2py/scripts/web2py.fedora.sh b/web2py/scripts/web2py.fedora.sh new file mode 100644 index 0000000..bb3a253 --- /dev/null +++ b/web2py/scripts/web2py.fedora.sh @@ -0,0 +1,81 @@ +#!/bin/bash +# +# /etc/rc.d/init.d/web2pyd +# +# Starts the Web2py Daemon on Fedora (Red Hat Linux) +# +# To execute automatically at startup +# +# sudo chkconfig --add web2pyd +# +# chkconfig: 2345 90 10 +# description: Web2py Daemon +# processname: web2pyd +# pidfile: /var/lock/subsys/web2pyd + +source /etc/rc.d/init.d/functions + +RETVAL=0 +NAME=web2pyd +DESC="Web2py Daemon" +DAEMON_DIR="/usr/lib/web2py" +ADMINPASS="admin" +#ADMINPASS="\<recycle\>" +PIDFILE=/var/run/$NAME.pid +PORT=8001 +PYTHON=python + +cd $DAEMON_DIR + +start() { + echo -n $"Starting $DESC ($NAME): " + daemon --check $NAME $PYTHON $DAEMON_DIR/web2py.py -Q --nogui -a $ADMINPASS -d $PIDFILE -p $PORT & + RETVAL=$? + if [ $RETVAL -eq 0 ]; then + touch /var/lock/subsys/$NAME + fi + echo + return $RETVAL +} + +stop() { + echo -n $"Shutting down $DESC ($NAME): " + killproc -p "$PIDFILE" -d 3 "$NAME" + echo + if [ $RETVAL -eq 0 ]; then + rm -f /var/lock/subsys/$NAME + rm -f $PIDFILE + fi + return $RETVAL +} + +restart() { + stop + start +} + +status() { + if [ -r "$PIDFILE" ]; then + pid=`cat $PIDFILE` + fi + if [ $pid ]; then + echo "$NAME (pid $pid) is running..." + else + echo "$NAME is stopped" + fi +} + +case "$1" in + start) start;; + stop) stop;; + status) status;; + restart) restart;; + condrestart) [ -e /var/lock/subsys/$NAME ] && restart + RETVAL=$? + ;; + *) echo $"Usage: $0 {start|stop|restart|condrestart|status}" + RETVAL=1 + ;; +esac + +exit $RETVAL diff --git a/web2py/scripts/web2py.ubuntu.sh b/web2py/scripts/web2py.ubuntu.sh new file mode 100644 index 0000000..e6b2662 --- /dev/null +++ b/web2py/scripts/web2py.ubuntu.sh @@ -0,0 +1,222 @@ +#! /bin/sh +### BEGIN INIT INFO +# startup script for Ubuntu and Debian Linux servers +# +# To use this file +# cp ubuntu.sh /etc/init.d/web2py +# +# To automatitcally start at reboot +# sudo update-rc.d web2py defaults +# +# Provides: web2py +# Required-Start: $local_fs $remote_fs +# Required-Stop: $local_fs $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: S 0 1 6 +# Short-Description: web2py initscript +# Description: This file starts up the web2py server. +### END INIT INFO + +# Author: Mark Moore <mark.moore@fonjax.com> + +PATH=/usr/sbin:/usr/bin:/sbin:/bin +DESC="Web Framework" +NAME=web2py +PIDDIR=/var/run/$NAME +PIDFILE=$PIDDIR/$NAME.pid +SCRIPTNAME=/etc/init.d/$NAME +DAEMON=/usr/bin/python +DAEMON_DIR=/usr/lib/$NAME +DAEMON_ARGS="web2py.py --password=<recycle> --pid_filename=$PIDFILE" +DAEMON_USER=web2py + +# Exit if the package is not installed +[ -x "$DAEMON" ] || exit 0 + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +# Load the VERBOSE setting and other rcS variables +[ -f /etc/default/rcS ] && . /etc/default/rcS + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + + # The PIDDIR should normally be created during installation. This + # fixes things just in case. + [ -d $PIDDIR ] || mkdir -p $PIDDIR + [ -n "$DAEMON_USER" ] && chown --recursive $DAEMON_USER $PIDDIR + + # Check to see if the daemon is already running. + start-stop-daemon --stop --test --quiet --pidfile $PIDFILE \ + && return 1 + + start-stop-daemon --start --quiet -m --pidfile $PIDFILE \ + ${DAEMON_USER:+--chuid $DAEMON_USER} --chdir $DAEMON_DIR \ + --background --exec $DAEMON -- $DAEMON_ARGS \ + || return 2 + + return 0; +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE + RETVAL=$? + # Many daemons don't delete their pidfiles when they exit. + rm -f $PIDFILE + return "$RETVAL" +} + +# +# Function that restarts the daemon/service +# +do_restart() +{ + # Return + # 0 if daemon was (re-)started + # 1 if daemon was not strated or re-started + + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) RETVAL=0 ;; + 1) RETVAL=1 ;; # Old process is still running + *) RETVAL=1 ;; # Failed to start + esac + ;; + *) RETVAL=1 ;; # Failed to stop + esac + + return "$RETVAL" +} + +# +# Function that sends a SIGHUP to the daemon/service +# +do_reload() { + # + # If the daemon can reload its configuration without + # restarting (for example, when it is sent a SIGHUP), + # then implement that here. + # + start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE + return 0 +} + +# +# Function that queries the status of the daemon/service +# +do_status() +{ + # Return + # 0 if daemon is responding and OK + # 1 if daemon is not responding, but PIDFILE exists + # 2 if daemon is not responding, but LOCKFILE exists + # 3 if deamon is not running + # 4 if daemon status is unknown + + # Check to see if the daemon is already running. + start-stop-daemon --stop --test --quiet --pidfile $PIDFILE \ + && return 0 + [ -f $PIDFILE ] && return 1 + return 3 +} + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" + do_start + RETVAL=$? + [ "$VERBOSE" != no ] && + case "$RETVAL" in + 0|1) log_end_msg 0 ;; + *) log_end_msg 1 ;; + esac + exit "$RETVAL" + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + RETVAL=$? + [ "$VERBOSE" != no ] && + case "$RETVAL" in + 0|1) log_end_msg 0 ;; + *) log_end_msg 1 ;; + esac + exit "$RETVAL" + ;; + #reload|force-reload) + # + # If do_reload() is not implemented then leave this commented out + # and leave 'force-reload' as an alias for 'restart'. + # + #[ "$VERBOSE" != no ] && log_daemon_msg "Reloading $DESC" "$NAME" + #do_reload + #RETVAL=$? + #[ "$VERBOSE" != no ] && log_end_msg $? + #exit "$RETVAL" + #;; + restart|force-reload) + # + # If the "reload" option is implemented then remove the + # 'force-reload' alias + # + [ "$VERBOSE" != no ] && log_daemon_msg "Restarting $DESC" "$NAME" + do_restart + RETVAL=$? + [ "$VERBOSE" != no ] && log_end_msg "$RETVAL" + exit "$RETVAL" + ;; + status) + do_status + RETVAL=$? + [ "$VERBOSE" != no ] && + case "$RETVAL" in + 0) log_success_msg "$NAME is running" ;; + *) log_failure_msg "$NAME is not running" ;; + esac + exit "$RETVAL" + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload|status}" >&2 + exit 3 + ;; +esac + +: + +# This was based off /etc/init.d/skeleton from the Ubuntu 8.04 Hardy release. +# (md5sum: da0162012b6a916bdbd4e2580282af78). If we notice that changes, we +# should re-examine things. + +# The configuration at the very top seems to be documented as part of the +# Linux Standard Base (LSB) Specification. See section 20.6 Facility Names +# in particular. This is also where I got the spec for the status parm. + +# References: +# http://refspecs.linux-foundation.org/LSB_3.2.0/LSB-Core-generic/LSB-Core-generic.pdf +# Debian Policy SysV init: http://www.debian.org/doc/debian-policy/ch-opersys.html#s-sysvinit +# Examine files in /usr/share/doc/sysv-rc/ diff --git a/web2py/scripts/zip_static_files.py b/web2py/scripts/zip_static_files.py new file mode 100644 index 0000000..170ef12 --- /dev/null +++ b/web2py/scripts/zip_static_files.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +## launch with python web2py.py -S myapp -R scripts/zip_static_files.py + + +import os +import gzip + + +def zip_static(filelist=[]): + tsave = 0 + for fi in filelist: + extension = os.path.splitext(fi) + extension = len(extension) > 1 and extension[1] or None + if not extension or extension not in ALLOWED_EXTS: + print('skipping %s' % os.path.basename(fi)) + continue + fstats = os.stat(fi) + atime, mtime = fstats.st_atime, fstats.st_mtime + gfi = fi + '.gz' + if os.path.isfile(gfi): + zstats = os.stat(gfi) + zatime, zmtime = zstats.st_atime, zstats.st_mtime + if zatime == atime and zmtime == mtime: + print('skipping %s, already gzipped to the latest version' % os.path.basename(fi)) + continue + print('gzipping %s to %s' % ( + os.path.basename(fi), os.path.basename(gfi))) + f_in = open(fi, 'rb') + f_out = gzip.open(gfi, 'wb') + f_out.writelines(f_in) + f_out.close() + f_in.close() + os.utime(gfi, (atime, mtime)) + saved = fstats.st_size - os.stat(gfi).st_size + tsave += saved + + print('saved %s KB' % (int(tsave) / 1000.0)) + +if __name__ == '__main__': + ALLOWED_EXTS = ['.css', '.js'] + static_path = os.path.abspath(os.path.join(request.folder, 'static')) + filelist = [] + for root, dir, files in os.walk(static_path): + for file in files: + filelist.append(os.path.join(root, file)) + + zip_static(filelist) diff --git a/web2py/site-packages/__init__.py b/web2py/site-packages/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/web2py/site-packages/__init__.py @@ -0,0 +1 @@ + diff --git a/web2py/web2py.py b/web2py/web2py.py new file mode 100644 index 0000000..ced8ff2 --- /dev/null +++ b/web2py/web2py.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import sys +from multiprocessing import freeze_support +# import gluon.import_all ##### This should be uncommented for py2exe.py + +if hasattr(sys, 'frozen'): + path = os.path.dirname(os.path.abspath(sys.executable)) # for py2exe +elif '__file__' in globals(): + path = os.path.dirname(os.path.abspath(__file__)) +else: # should never happen + path = os.getcwd() +os.chdir(path) + +sys.path = [path] + [p for p in sys.path if not p == path] + +# important that this import is after the os.chdir + +import gluon.widget + +# Start Web2py and Web2py cron service! +if __name__ == '__main__': + freeze_support() + if 'COVERAGE_PROCESS_START' in os.environ: + try: + import coverage + coverage.process_startup() + except: + print('Coverage is not available') + pass + gluon.widget.start(cron=True) diff --git a/web2py/welcome.w2p b/web2py/welcome.w2p new file mode 100644 index 0000000000000000000000000000000000000000..4c454bab01985b2eded203b81b58ac69848418d9 GIT binary patch literal 419730 zcmV(%K;pk2iwFq*5~f=M|953<V{dI`E_X6;0PMYKa~#K&DC*Dr6)7lqyPF1^ix%I( zT#N=JK#3L!VhE5Pi)LV|y9(%HS68)b0om}=M0g!v-{-h-<9&HEei7G<SuANxYh;b> zk;C$hFvR~r{+oBU%*w2#0g%)(HaQ-lEA!-@dGef-XF2nwPygRp`1h4pUg5v5^53)P zU*^C3?@Q-idg+yOFP}Si{^fIDI(zQ?*{_`Yl6vJc=-ZcyEca5SzBDRk;UJ86+u#6f zXXlVX;z0D@|0MrbE?m2@^%<=Ht1rLYzW%R%#ajQfxc;x6gY`fAeEmQ5e_u<(JWyFO z3Gxw)UU`G0$QAs~lsBFBPpk%eL6l4bU)>G!k-8fU&QE9k6JL7%?~mi(mCF~`);HHa z*Yp3<`LmVt|I*p#=l`?$w>1jnP{W^S2zUU`y@KN(g~K4u;NTarAEatp3?N1M$;1m| zb)p;G8wS%{?IbB+i$D!CKp3&F?qq5wjDidjy<COxzjzoGevmDyyQ6S8QX_9Kz!G7q zlDjctn$%ZQFU@DV#jMvqapLPqp@v?pCW#;J%org_K2#LMY6bwF@8e&tX_)xIbHsGq zf7{z(9Om2G{psxUyZ_IgtDJxM@%;RMCjXuvm_O}*!z9krB#MGGJM+ci|6YFS)w9p} zzt4L8;o|rFNf<xtyI?;4fAu`@dlmfu>MQ48dXE1;i+?Yw)2B`&?F2(#QboRV`oChz zi4!lX7oYea6;=~(44h?=0!4|tD$MfK%Yj@3N-l|2lnlLSlw|o+we;eN6X9f<q`68m z{VPj`;~>{xzLy7iI0^LkFqzKu@7<_K;yxaMAkOpIG;lMJkS+2s%1-R0$wU&jfkvJp zY0HqnJtGG_$)F?I_O2JGWt9fsEP^cW2k~B?Y3uE@h_Mp{08?<ui?V>{SPh|k2y>xM zpFYiV=20hAvO|<L)DosiJb^BrII$Zg125W!G-wB*`uLwNCuiMW&w{ws(PQu2252)8 zCq{Wb-Nvb}^wp&IvuPCO-Of^{ckAr!6KOC>@?aaN?X*(D$~lpzv!xRX{$ULn0Cr7% zi?SyD-5|&B*qa31-XcMpe=f*iMnI;DDs*RQ>0D<~b<UmtO8+eUAAKw>?ZCgKGOc%l z*_8H<^<dq0%$Q&aF)w3yU`4VJmOKlFu#3A;Sp=|MdphC-IUKIJM+}gY{lc<ZFuhq| zfNxOUUESnP5f5`{1z|fAFZOnWPLJD9y%4yaH@3Dmy64ZHT~u4$jz-aVi2N|~1`#l5 zgJ9?t02#*IQ#BlUaU4XQo;y0z)N<Jrw*){ql8#s8qYe(pY$)8Vn5FCR(p{My>S5rA zX)w&YH?ChXBPy>HSdtK!$9vcj1m`x>ZBM$PusxXGJO}KP_1)|Yw?fx$w|lm?sMeD> z=;=;ZDuhYFY?|guK^ij+uk3xTJAMd5fvyM3ZpZLzTSH@hWi!_PjRFr5>N2d@RVt=d zhC|p*>LSlgr*~KlIWBFse2Y3lAKS3RY4^~A`kz&BH%*G^6P26>=_I5>(CyuJ*AS-x zrp%o~TCxsib!4R)Rw)47N1684>sC;1e>e(;<Lx2rFhG1E?nPNq+LF}Ak(X^xg2@1A zmr*$F+CA&_tW8=TqnFRVw5S%=p*^f1NyGiXUyyMHaRK9D%&ZT(Y@sQj!=Y!64xPXb z?K14TMiXU~)WvU@4m4KuLcOA+Pk}}d_VJV2;LQ2Kj#or^#~i<gmEZHyY?=0Z7R3HC zR)8mE**-Rl45gFsqX+*^-~#FnWK%e)K|d=7d6?6VfIYwJ!S?ZB(pSohAIIF)=&RRp zCVeX{;93fI<0K8X)4Mvw)V>!6m}syc+*FgOgQyKFsB}f@ymbpY;s+Vj3a5?Nby2lW zlt4Dj6iv&mh9$h+yS=EWl|k7;y*xE3Xiy3OEtv<0mJui^GxT6P99m{5V7G5S3kuFF z?uAk4r8A|kj_j$awH+RSgQJ1|fvZ2;_6NL{7P$q>ny0W$;hGbQYm0z4fs%yNPT+K@ zJIURiWc0TIBW)8h>(*OaL<q`6Vq;M?EHd1nuuBxy;>)fsk0JNgA7K06dYiirC%-!m zW_Wg@0`Z@|Opzq(6RFs>kdvXB^gp;geW)(X;5N^_co=l4qDA%kUtL+f&@-?$VRLBN zO}8v80)o1QVHmfd<47t}DLGYnk;a$@^PtBM5bk{NolFxIK-uju-Y&=7&4YV-s)BpL zP<1=oQ0?-`tfNjU%v^-YTeN1WXE$xrvskVJJG-_dl@+mQ9z4A@dH{%8To*F{o1mda z8%9wn&wVU0p-nIDL|!&xOc=&cQ)pW6^qNVhl1wr~bM~y+X_cur`Fhx}lbxRS)L*D` z_3@wM@eg?O*T>(*vr#GWsg2kS849Gc%8;G&aro-s9o46Lq`Uk|u||KOr?t9>4&g3P zvF*W(r+ypx!LEfItSMP``v|8dz;g%mh?nOnOx`V14zPD;dzyw5z@h-xF)Kxd%I@rh zX_iA8QlWP7Th3SCstPvY?Gu%g-}#HP9s88)TKhN{T=H8TM5pmCUU_)*I=34!Nauy+ zg@v-FZ>HF<&dID#|KpR}bqZFFM{V~kmVM#r#Fm=2l+#w|!+;P=6jKX<Q<Y2SZ##Gb z%AI%?cU}bKit?hU#13?P_@F%H?T5RJ_I=k7aExA&4m0g7n_s<WG9qLP;okIA3{(^x zz$Epb_7<0sV7+=MgfeKBdV-`}45n|#3FN|cbm`jltLC7<?l8pPviW6>3YO}7Lp;Kn zbJ7<z0<x)nO$S;ysT{a;I`BKa+5%uR%lID|$Fk{O@7eAw?n;K|k?N-nCad&}*T_%q z#!=$=dX-9H*%9s&nH)2trZRy-oT%~lFx#uNQ5UW`%Y!U3FmAUx7a8L87J!hTs$`sM zRoK6~ojx=w>v+gW2(=4@d&}57DCIQY5c9k4hmeznc)`#JI&cjD9gZTqKd0w#M0r5) zYy(QeK9?h`qPFt>(lWSyr&q&u8C^16f-^^Fm`o-~ybaCe(79#gpnCl*i15ZW*DSBi zHm(+Jy+!JtzH2e1FCa*RBOF#3bO}o8&~-Yiod!o)2Y-MwVF?lCx~O0EVYUqy-IT7w z{&taueU#JZ8EPSQ7cgt-%$Wt}lJCA5%+}I0Nf*@$T*Kj@$OHMty+uEJO)W6b&-1$* z+@tRGQOt`Y?{r_=_-`~bfANjGU+#UQkKa3C5c%}IjGsg=|HU`_FZVh}pu{XPp>j#q zhy{ByK1I*^cE{>l&6bGe!x6Ott@Y`vm9#P<H~?B|qy@?nHubP9lz)|?KB{=i`A4ny zS-{nyxj+`#Nu?R-^q#(YnoBLpbcvS65o_WY?jgZCN5n-=ZM5wziW@(X$BXlB9j=i^ zml9_wB~FvO8GW&cI}h*#oIA_8G*_5?>-GuV8#yO-g;eGxT|<Ij+{%|J^F)bFAg9Ei z-103x?Qp{d>0oBz0vd)S>&E4?Y`iQcxa7+UP$c}<F6b6UnVqv1wMt!h<PK5H_qUy; z+MX$!*TCnNZaYx!<k!nVwUypB^{s564x%?uebd=A77<umD;KV;b+@i}fe895I_h{l zIzatjUf;N})!okW84x<1yP=<tmR>%4cG@H?+@|ZRLrp-@Z8`|c4SPOGsqXC|^fOyt zz@D6z*MNn3wO9c#gxT`t&F%GTTia__H@3dsZ9Jv{;_mGU%!0QYEN^ueE_yNE*n>a? zlW9I%K)EEKc^c@ADL!>AH63{wHIJttxNVZMVy}^?Snkm0AZeNh9yi?<y(gMMX^~G^ z%S<{jN5Wb2X1$!1Rk*czR@_<eDP7M(z2{u3fHh51Wm-B-^A26WE?OIpYsreiB+Sd1 zK-nlK^~wPa@>s$DpO%Xe*Sevf{J21Z>~z@>s5O~3QbL5C1~zJ%&tza0O%}<y=HAIw zDHC8PzL)KLy8mTMD$;c2QeSLR5U81Hw|CgRt1)iVrPwZT)HlM>2+Cnnz|GUEqRz6% z_NgLrr<TQAyN)A|)&Z`h8BLrz)gT(`5Oa4j>mkw6(wSbb0Xx<C$dj2mdGcE@UvDce z?!(rl`Ri5g0B1_<Ble`j<~q8^?kAUP>F1LzeRb_?1VSm(($s|Eq;HWJi=^aqdxvr3 zLIQ>FFD$Bsg8vND04E!N=E*_}CAWYNSwV_GfJ5#8i?YzW-Ezg(`+BUI5Dw@N?0kyH zzX*&!V6?$(xl2USB9Tmo(xcMT<%S(CS-sv72#;qruKA;>zDtx6SLJ1@(l22d^VAy# z18+EXkr*Oolhwyl<mKB?Yh~|uab$W|qf*B$;GWL*PRu<UtCw%$U3gh!)I<{DRkLw@ zt&2=`(36q82&Ba>Ds}({1DpyxdgA#g<e*$+i#4+4zp$U3Tbxq$)ndRcaW4!Dk~N)% zZ9~6MIg00oUce9l8E@b@;38R23$1&`xm2mhqNX{Z60YNDg-4<92XT2Lo4%V0HJ5dy z>KZP19^w28zJZM?XRLZ_W2(Mr;CFwTCa7!C?a6g+i`i?ppCu5n`0;WL+u2eFR%W@+ za+1UFGYUs!PZ>$%5zkKBmM&u2hk1gw6j@;HoyOfAkQ}1Aw`(F%XZBe(dcvVLmU(Zu z%;qv<1}ia{F5`a|9UgKS|5GN>NnWP^mWh<+CJ`QM;64_sTV+}PT3sG2=L7nBHWJ;y z4|BO;73v*5L&2?(ImZ#Mw>?8OKS7B++&WGMzVF@+l_OVqxZ*dfTXYl^J_<MogU%?w zHJZxHuH3c>TKKMRb?G5oUL^q`FJH)^+YM2A>y-)xN?B;1UZT3qa-4=H`*2e%yCO^X ziag(IsN5DTbG6ksuGaTPmaETsW0h|DNsv+f!M$+KODlJ+)4&YfS~}N;-%9-;K5x+F zUauTg_4N|ge%!juRXqc<l(+kL(@<Zeq7&QjOmw1FbWx^skxw6CA|zqtJJ^oAK@j0> zbCLKEK#Rh_TK87Nlao=!qVbiWQ5cW&WZ9X{rg>|eVZgwQV=K(*lL#bna)23^hnTiC zwHE4FZ)Xi#&4-i!g0;1dwRN9zAGYkl&-&dC(5+~pV2{FQ@enKzDY=E>?Gc$rHPYtl zmRc>WV(t<}nuc`dZ=<`l@_PTmjjgR~>s^$WMS+*9iz^r3SbJ@ur=>UxOr9-h+HPSM zWDAB?qpw~gF-HCBr{1KG)`KAs)B84W%GrLHjotiX_PZ`dda8jeK1oa0SFX-!24=u& z2EU%LnbpgiZ_a54r_ySOKJAvC(Rp83IN|d3&Sq<RotOm;f}C=93~_J`LJPOyFE7(X zU@1k@VU%*4`C6)V8|ru7?%Z6QqQ>l_jlgQbsgLwh=T!$~=2v%U4cJm!6?1xF+IUv$ zaUHr_Uk#_Vmadkk|2XZf;@Ij9x+Vrj^Gb_xZGMiJ=ILxQje@lAWq@-M{o<|U(|#|$ zOgZ!{T-KqBIrNA&EE)yTUeKUNVVf4&0uHpcvA!o>K00A_)b}DbmIwzL1pnhjXbF=F zH%6Q0Tc&@V0O5nIv!u?J=f5+U<+ZeggkaUwQCLet75`dkQrWK782PBuw?rfB<9}?c zf({T(Sc^RHz0CuVEnC_u!H7gVH-VuxXJMgRT;J{T$&d=T$qWrw<?BIyIez2nW;Y8^ zvn;c)+$bs1jK$(3*l|gcY9Mt+z4YqYvo@{G>8F>a)F}ceh4o=v<Uwm?uQpeuOPvCM zT7FYi)=jAuGO0U@x~fIxLN;J)_}E4Q16!~WKnNQM%``Z(JLh4*)No5S1I~H3YbDcO zx((wx2a~AI)Q))r?3e9oW#iqhix1xl(quK<3lU3HPH1b_0EfJ0Ar1>h_ALULePV54 zb-E6`jhfoqXd!jmnj+kQ`US!iX(EuAYQ)3KYrr@xn(@&mhZ%I;@fo#DRVEFK#vN<2 zK(Gs%DPAtCp|ox4He{T(GxXfMRp?Z=k{WDnuTbG~DeUgh?tsJ5+^OoqTS`2&J<yxm z=GhZ2J8E?BkuNo7nq7NZ$yT6Oqj2O7Xb`4ji;QY-<E<rttYvRhq-!NKBBnCu>SNF- zy&)fZ!<C=Ct^S+TCY!mXd)8jpCF?CR3dOAy#D16U6<SV)uEcQv)&%3sTDQGSsM|4K zg5?IdTaE;%6fBVPh1ktfDcUw+mWRWPjissv4y0d<oKvsid5x|Tb2K!3^<<RkwaxC< zWSx*Bl&KvQx3Y5gI^EPqrm?fN>W+VM+B$Le2oFm0&PQ42u?|UDY|cq3f#w{S`jL@( zThENu_8|wSN|!wO=|N10bwEp~6HH_e+!(U_izVf@sL8O!lI~j+I&0C8V~d*nTU3o$ zo!TN(?Y*EY753Tzq}E>3Vb{PFy#u1l#C8br3;p~u&lVl>_KQPkx^fRnLggfM-Q+JH zTXrVp4aM;k_fD<L*3AQ(ud<uwVr{9)+Inv3IZSZ9sMF4g6K%Ib%T9H`%IT?{jh5mr zT!myhN(B|bUP;=+4wB~%+<Lv5f;KC;ov7#=ZLM}M;KSIP_~JooP?E3}lHP%0c|&)! zG+D}eonB3==+rH)WsJv{ig!+)J?}4>|DZm}7!g{plz(FnE27L(r%0x!6{+Y(JIzP9 zX%~w^*}{Nc`A-j%DDtMT_(1VbJ=k->pDW4ArrwaecJyBfCV#%rbKe}Q{D5`u!y=S( zYNc0Ky#d<Js4a2>ypz*AF;{krpv&~%#U|2b8UBBfdbW)JSrpotY072Ix4$5ayB48} zfI65=BP81S4XtKniuT0DzVtdS_9Aa9{PTLb6)#;|-|C)X+vroL#&=1htYJgG-roVf zz6M!Vgkrv|ODYvs`5hAf!30u9-xy6e%W6m;hF;9_8ez=c=%~&KS0hQP2l7g+z#7YO z<53XrinyYwg3xa+e4*Q!j_oJyvYf5K-${d=APry`or<x%I~PtFyeyZjf^8kxaXXL& zt<xi~;alik5dJqx(li{PuYjvp)PVe;;=?YmZTPyon|jkxxX=C&aScR2)75Jp22nKi ze02W+i7#_n5+(SIy6_@92VybnV7E-aME^K_#~b1vSa<`aP3Rh?Ox_*<esuEG1xS(l z2rZQN5%x<HDU8Z!`)X|ttZ&&=irN_1n`P<MeElSZ1@sdyzl7z=5ieW6=U3oG;cmRV zFa)xObhfso-DPgQXY9pr7|zS$lA|2ZFhEEa8^dj@%G!tz)xgqyjDj5!#Xre7u^L{N zW&YFNs@;7$*sa|^+?L@Pb^X|VXS4<*=sk<xmz(1m_1}FwT=;M5WTyUN0j_Z-Ax^PM znZB^~j+DQPrnYm(dAg;(OTn`;6uG&V&-Uh5)a&1yL|rioXZI#u+g2;9IbgZP>RFlt zAi1EqFgS~>bKOgWthSmwx%dNou0>xf_OmV<d1((pxBS8FN<*lvf-SJC7k}XD47nPi z>_L`v0JJ@1cDu=nzr~49%|T9odm0rfNtV$V0Mat+I;gwFapA8gID3uomaCacp{pjR zrKs&k$1S>Ha<aOKR&Xy5;!Jysp%?!eu|a!P`x|OnL&<BVHdX1N=wz2m^`IkgB&c3d zs;?{qu!=xU!8&)gk>^yMUZ0%5bQ?AE&AKB_&X#%E``ad|aRW40Ls}hW6+Dl+?Z$d~ zt}T+B0B1bs7S+(p^5rnjMPFF!`?J*=?30ja{c6WgXw8to-!>b&wBNCHrjECd&BhFU zm}<|L&VS?ZO?iX@?pAaQxUZ#ct>7`kg0vdtDLcZUp@CJ3;(<HDp?Qj;xK?(t^2l`@ ziwfB!%XO6E(vQ_8zvVg$tB#wV@Nc^WaZ^*W>TX+>-57b*DmBWi4fPU{&>b^J9qpE` z3gvp<n%f(D23xyi8f5)LVsf+_HQFWUQ^^A~rM0sr-aYg>!Mw%tIUt3b4!Tx-m%oed zj4wN1yn@*TxCA_>+tP(5MCbx_(CbXk>bQQ_Id#ef<ie|KmsW0E+2T@1E>=YuR%rw* zb=>-<u%^!&l%&qzwrr8~51YNT-R3}5OgD^@WSmv3waJ}R0yMmx2-o*iKSm*|wM~Yd zw>sNoxDFVwJ6fDDnjNt(kwE|-sB7Nwc7Rgr@MS*XOm=9{Srn@`_#rBI;<ltbKm3h6 z-u9pfBY!*09b|-+`U7C}Q>-~l(0@beE~84vn2cLo=C&iq%v&7aus5=Nl=#~;VP(JU z(l8@XTqdW%;6;1Ms+ZO^kTNW64Wpq8Ynn`3<nwSgwKDGxD)DX)y(rq=?zDi<eQ<CT zdrBF?qUxH>&__4?p%?XfONSD;s3EaK9wq03YUc-Ju}s?w&qbCL=`di&0`o~=A7(0y z$iG$x8^gLfOFR8-!m8WbN2bI(x+hRte%-Q7^mkD32sH6+`?}^tTro2agF=tqGT^Hq zMpcU13}8+MQ*i6t?Y9qGG?|H8<v?yPsTb7+I54!Q%f07iS_@X27;JM$1}_a*UDyvx z`;;Th{;f`tMkLrHH-XFAf!=Vr^q{x1+`($KcBdw>Zgs5Z>JGlr)rWC=krX|@WhTnN zNW$&6drvSscqckI<p`Tv&!LtoNVV<Fzo^9W)2FZ*_&9ktjD3^{QM1a2Vdp9<rlKL_ z2YMSoJFV3=Id`l6n|fK+^!SCl+6<)SB-@xykM&y}J|2LM0N0or;JoOcZ`ahour0f; zhUOU2)*4wLUl7Q9cNtADsvNC{v#8jG?8}?mn^$hU-tBekfO)S+JZ#5qxwB+{y{+wB zu9Hn5eH76)g)V_ze8ouPV{cEv|DTRZ1$uK!RIdoBKo4c53%i@Q8nE?AJcMmNUS7}w z`)<d>TeF8f2S6H^t>^-^<#YN1RfhiZ0@mTwu&5shI_PvJ@@7jhAfw7_9bZ#W#+jkY z+Y@#`kLAkcZZg%Qsn`|TaM0UZ0K3xNxmBX$+odHJqJShNbc0kHif%?}u(P})C<L|) z{UC&8;ZmSszSSY0F{d>W*eQ?y>2q((8w=f@*wb=*-mXlly+qh`hbof%r&kO2Us6b8 z_!yrC_=>$SD^SVVdnP_I$#K(5+azz^rUo?mwy?0EHiJO1lj<{P?%uuIN156H78q^N z&#>CWnJN0CK6CEnS6)5$(x3g=E3f?5KRbKwEI)W$NQ*d8*OTGMqbd<)0i~6YtQ+QS zoBc}<cJ1~JW@L8yBH80Ak6l_Nnu9>PKSORhLVUOoL&<DG_nS*nT1g$@Cb8X(5T&P` z$2NOtBpR>5C{}~IC!v%ww3B_d(~}yxhIzL5nV7kyme-2rmzzUha8&&X$9jlEBHVt; zIo6X-rJly8og+W-R4QB8cynQ1CC7X3d7?L;YL6~8_NYmX<&eqcJz>ZIWN4Y|q6uWa zi&XW?^`^JUDZWikdle)32D;l?d3GCr)CqAX@=2$$WgZQLZ|s|OW#o+vDOKAs+1cAC zngw-uuASLqf_K^CgrRq+Be`5_v^sl)GwMrWS4Bn>l(4W^o@e9RL5KlB+Iugf2R<av zfJzJZLLbmJ;_!k(mL=#=28pu}iu!$}Fgh9%cx2%T#iMYLqB~@KF66jo=zSmR>$@J} zh~74rrsZ>*oH~a?_;DvY<G<8LXV!PJj(M0kW_iZZP7QM%N-pwbF4KQmuEO#ZAaS3^ zLi$sW|0K-ZGY<uKNc^{#&%IoY|M==lue|&`{?F$b|K~*vNAqm{ohTJ7Je7HfO;x$= zAeVwWBFaOMG>8JPE$k%TlrxD8i4jlma>IDF<deh@-_Ne+QW@~$+--8+3!L|EK<P~m zeQVwxP*)>L)Yp<U(soTYmM)!|b-pG6IN=^*I{pRnk1c&z*|@B_(vcpI@x)(}#9lj6 z+m4dmFz)uKTi!Gz-}fYk4`B8p%Z}83Lf|+)^n086MWX&*U)usc+>M>l>=yP;mc+o= z<IPk6AKu9digiLttJrR5iF%10=~Ken<)AiE?5$o$S@<DivmTP<GDMwO+z6zg0~fbP z&EkzbQv!{=3G*}bRN=F$ag?%G*Gq?(*bU+!4Tl_I0vf<w<|#>42zA1F(5(0}?Vfc! z%C@i{jnmrtAW(59&hj-orL=*UC>L75Cr;UFdk(8z#{ZNHu?F+y`xNGR99GtXW)0Kz ztkKF~0>;|t;yPd?R%9Tlbk58qX4*}gQc$AY)f^KBc`e$#XVPF7Xw@J+6XZko5emys z&RwViy*tQ9hV?kNAhxT)J>Y#chlgx3aLIl6cjgvQQ@8aMcLs}|p$3l#2w3JQkh=Fr zft{uaBE6$ki^|`7!8Qv0?xK&8BNW0YP`k$~GAN?)wlfCY|1DTX)8}&zDxEs=^wnvF zw_X}M_!bScE%P2!Y>^#3Y=^!!8ief*DJXv^Mcx!_I1W$>%W;<Ee&OAU(hWF`;gA9k zr*zHKCqf68Im2&<XRw#p9Pta45O$EvP_zd#X9w2QTd|_9g~%lg64U`@_u!7xVtU2I zy%Hza<?g3Vf8sCMgocX?maqEv)}0V0M`xolVzN^<MEu1e8$y>ob4$zAZ#Rwe5bxm6 zDeNye{hucBnNPWm<HvtJ|CLu>dLIAvGh2WB58&L-E&lhpD*yNLOXr^Rf1eHi_bIRa z^MC(&&VOI1{?GsXzw(urUwwZ5pP&Ed|32-15%7owFf!SvNCY0A{(I>wubzEQ|9!UW z@1@UN@P8!yfBuzoUwO4k|2@b5pR@e`TPHd%;NC!uwHG=|s^g`dMM*<h0Hv*@-T)sX zPjnVo$#;Q-{HUUXG72w3aa_v2zEl*B1GPYJvgek+fic<0Il?zO3w`x<mg%F&lq*6V z0dcI0qC}{ph;kO^s;^$VypFAZ=54|_$+Lbp8zs{ocESF1a?xho1)vlS^Q~_dUW$h0 zZyO*h$v`<C{0*S%*Z)LQR00>)#46CR(jTjFlj6Ws0CX-p@-)quPt5)L>64SwCpk<1 zw$jzfH<nIbT{^jG1C)sX**$gYWdE$Mu3k8Gil)#_00{W*k}scLcIp)N4L>C1ZB!*Y z*(HA%IvYPEg$DFg<!kNJuVc4*q*Bxt?oV&e3nP??0+1F8X0%B+X88#A`K?>K#dJE; z(!A+x8UixMtbUU2()SsHIHRV?w3yz$tyLL%+_z7?6&TBF*wkzI>n|s;)hA*6jeBR$ zojPT`kDWTj-Ff`|M;|<T@aUaKKYRQ?6#e<$qmS^vkG~HfP{ZH+O|8#=^EXTQQ1EHY z&u7>gjBRC*6zF8H^Y{la^nZKwE+w*D`y$J=Dfj!2-h1@m@ps|x&mO&}Xm)=1=vR+_ z`1pHRfZxcLbdY(h!V1Q|7pTi<T#L$sRM`)qlAk~RyGQR*MY?7xcE`J?t_Q<#N<IQR z)X2BF&3}CKa{&MDqYnu%<~U6%84e4WoJBRIr(BqiG$0@ICo>o-P87bN(gkwNA~-G) z(<9dR!wgpgb#R7WK`Mh;fE6ix`-lUYr{fjCalj`&GG~SSxa-Av=|Y;HtJ(PkZRy8< z_xO7-6|h?GDO!|&gc*4sx9x*R|MvLX3TE}+9{r3L=({j)|MK_;>e2tEmh^s7t4^@l zEw<ss37QW9bzCTB+#}Qh#UijM{|=q_;PH<tEx!kCzXL@Uun0decevQXl4?kV$~l@m zRLVaf<)Tix=%i@JohHX57zljT@L;|f_raxvQ;G<XTpRYzp7$9A;-{p&P5H2PWiC5F zq%_Wj^(%APD<Y-6t&+&^m;L#Cnm40=lYL{_UzF#BF{9n|Jy@~FKYILqIDbFDO#~YY zzrPCy8@_)*i}@oeTybsAYyS&edj&Ax<LyU~meXYFg#B&u(FbvvOJ64M`pVTZ3qL3a zeMzdz8<=x>gSXlDAAJZN_{F358F^exCX*r#d1wOg^GEN&e?OA!X%a&%ysI~&VmFL4 z4g2ULI8#4+^eY_C4=LfFAN?Bs67u2V@lLplKBlR2<rn9PhKY+TId3{k!`)GCT6*yK zJ21cBp-c`oq%Lru@m&A=qkn;wARPJOqu($>)?n9S2kh~;WpRo$#o5te(6N7&BnOHg z(OfV|v*5&Ut_`M>@U#LilT5;We0qPu3=LP~SC4=6=vN5hMjinWHvu3to}pR$4vhGt zNAK%f;T@>vXS62o*`Uf0fmo;^)rPfiA-F5M8a?-%vh7efhynF{K=ocwS5ZTq?@Kr} zKLnKbb9GqHB^VwyDL*N7lF+oh2Yd7bIC}4LD$LFdWBJ;*pt)|pUEaRm$2|avALxSF zFb#<-aZAt`0<?{#aqurLAZe>*njA`f9N9~<gHozV2C78K&bQS1`61-bv2`4KGAwX4 zJ!fGEZ^8P#FI!|`l?=DWadKDPMePE_v&m}<8biY#`3Q?CBERUC#R|TSsdBq>=mcD0 z`aw-g+y>rc4`9dqh^e);)2t~aXZ9VuzLAC?q$juc2Y3T8c3H!~Ged(YP(uRCHYFo8 z)=da@^Xlf2+R*s+0~i$k<x>RHgNTGSH@Rj(wmXC$yYO=m<adK0R=hyF)ExZw?)7%% zW_th8FK}+~R6?u2g5m$@(F4S*KZ1)*7km6eDg{5wR){&r`p{V%nm3;8a#*ll=2p$< z?q@WxU&t5`ts`OfT^<1}*Kf-5G&@LumUj-`pud4S?o<2s#CdobPYK`}QUUhT%3oQP zd<bNoo;SD{fa-&R)68AM05M9;;0!qIB>t)C_e;=2z7=m`tTI$PDLeVkwApayeL(0( zhWdTDcE3ZYkFeaOGyqIm+Fxd}?|wsb{v9s)eInt1px5<vR46Y|s{Kj1sLyk<s}28q zFa>-M+V?wQVHm9o2o1ik^gYQP<mxW33KjiB?1ZY;QUU@Y0XJtfgPBM42$wG$N>sps zhOmjoKEMaufAD|r5>aFmD7u(#AQMVK7nW(X_)`IB<4r5j3ZsW$C?(j&SW+Fms9W&x za#Pgs5%L`hR8kNIFvE4+1xth`>0a$+Cr=`;Pgpn1jSvEU^Y`1d{}}0_-%JgFUpnb+ zy0|~h>aq8Uby_}vqxB;=F|uRd01WMitQU+1C8*)WeA#zlmw#K)VZ=@UQH4uZg!TSA za7joQ2-245bWmJ=K^g}NIJ0(7XSoRofp`jKkDD0Mg+SaChDj5@80u>WHraP@7xE}{ zNW#F}0|q}=ar2|!Liz`YL5Xs;OLIU&YTi!3aY=$jk5-ego{SVS_W}_={QINdU^4p9 zgarHpUspUEe_6QeBVum9#{;_J%|whLSI37;UURxl>QmnTdi)*LMB+1eCY%vs54@4M zCX`}aguB@~_Ya`l`;Y!rBVM>-9{(@tPqM2n)5Oa!PTLL8ypIthj^jP3|L1rsa|L*@ z2tpQMJ*Xz=U*H-&`nf>sYUkBxYMWCL%=U)paMCn<8}|)eX*6VmF|o)8rifPiEJYOa z3(EelJA;Da^~4ggE|_Z0C`%X-g7b~}mK!b1wmvC0E-YIAJ50pz7`{Wi*}pJ41Q@d4 z(j44JkN*dpv+v>QukdgNQkb}p9{*2))NI_<nc56<5qy20Xo-(FXT5fTQ)+M*xdd4% z>kIN?_>#zN>>Gt|&8B36zLz5lg+A#R%=*TblF~Ysti4eNWIJ2H_78)>dJ3FneB}@i z(}ck@mc+JaLdk0+0#nB8Rs%{X<y}D6@Yeo0%&_eLYcX1Q8^M+RS>}pPicos6TmO~m zs*ebF3(fQcLXSUSl+hMN6)I@U!sgOYpV)td`++-%>cWmx!op69NW~8x|MwEIRZ3dI z?FA_s5eVM<59AdU-Q{u*I48a3fG=nuZR*HQCMfJTGAJU=_+HCF*Zj+SMCZQ4$kcL* z1vOY-PG06_(nb`CZ5U4htpl=74eC+et{2AEz5R2ftKmYUn}T@re@1+Wx$W4jDio?* z5F5$eASI&@p_JZ-t?@(Lf0e_&kp^1Yt%+si8fXY<uoospW}mlO8dZ_#og@tZ_mIF~ z5}%|jRNIWKGWWuLV=szAzMZ6qX<6syV=MGjAT+?w;I98yy!bJPZgY}a$S+C@hhw$Y za!NiVB0{KW5#ovX4*paG36&ItDPuqpfb}Ugd~QO7&#!SDdDB6c3^}|d-fxc92_VfG zrj{ngh{%NRDGMmHTEh>@VFM0J1Sr%+nJa>|&<Dhhcc4f~;R5^!w#>KHA?3zQ5d!G< zAN}$$U@-{WDWZ~ca!TM?{Q+Tz2V9tKNEC4U$f>KB&cZ!5%X&g8{To~>9}p?r)igXn zKt*uudt5;llth#1tc7>}1CG{jfFFaELxI7AcJxC|2C?+}b_$=DMBZSovq3q(%5aXI zpdsvcb2kAXHa(zb+1ZAd_4~BPYiS4v972pH;M}M0(flDEdh{QRem3!j844;OK38wf zO<<bUjVaYEKPh!Tz#E>Pc$PTRNdcHlvo)FKW;V-^ELfuaqP!VQ%qR$QLk=L*CA1oe zV5m}#4UV-+lyE4@j*`sIMPyEdm6=*IrD&VKK!HJ70|c>wALganhqkvn*B1ql<!^LK z^^eU2jUACmZiCh-=Q-v4f>8-UOH?$}Bef7(sV`1vWM(d+V?M)t(M|ZS&I6_c?`rhh z0$<wj)+3W8RG~>{Y*2OALvvg-!)2pNgeE)5lbUbCv-5N3nUSwV#91VRCrQeO@RMk8 z_fjsI#t$C-8tatq-GnA=S<b)1-@h}0*$&wfuS}<m8%@ilT#JAjgFN6uHD*W&*xi$< zB_REk!3d9jiPC*7a@b1I=Z-fdvbFrcoV#JJG4FeXx8Gx=(Hfr}AY1dG+zry*p<}6k zVk$s&0U`AM3;ma@BUjc}7di3&Dig0=UnC*R-*OVAtzX+BR~O`;Y?7qf#l<}e>kC9a z?dVUt2_8i%O{Mx<WO9nR?bBgJLhlIfM5M@9qGqfg|6NN}wlw0fx`h9(*QKvkN8nkn z>-$`hDcvmMbY4o?QMJqlodu4Z<wa-|IkUYXA<Jdni-rIF5p7jEZa;_rf1f3vA0m0r zQbT0Gh)((7(QkPd--MOenK`lrR$d^nQ|pCz6KIB{JfGi2Xu5m<PM^@5!r;jHhSQCy zV%=VqXIfdd;d@=`iI2C$mn)jZch0jU^hb)GR=ze0ha>HJiqM)Eha&wRB}00vB^FpP z-pS0mWUM!i?<4by*b)o6^GR(pf@5s;wIm$_(w5uW`hq-EFGPonCGiu@R9eKbE2(v* zlkYwHS9+>^ParJ9h=(aki%1mU+Ep2P_U7e#(;P@*oKE7$&@eVLVkT$|Sps^&qLure zYDA-oCWCYlen2Su9c0%Y09yMI=?Z;U_Xi^-<udC<8p+J^OwpnGC9EThUg^04DKDD8 zx1U>weu4DAhu-I-|NZLuS6)6})BisI%5(kiFO>fG(5vfzUxW)OI{4}5rU32@b8@>F zE~tZdf&Y&^)84^{(1#)S0qz#HFa*+$noSA}qn@PH?s}qt`JTccV<ola`>-DpbYwRP zffkmgDTpiJx42XV@5U$>>SZFm%}NQ6oke^w>W8Muz{|5z!Frlx#2{Eo)|fPet{<ub z4mX(hHvW)a`rg}zX@Z*~<uJ=q6^(8Zdq4`!U;cJYvD-g$a&qS6*V`4l1>l&9-QBFh z28H?QFkfKc3<es(a(HUN3-2BL@-+Q-;kicmADu?{6X+4Y5vq{~|Jwz&wvghBDhpKs zhdc5LDmwI1IF3cg#UoEm4}Q7}ho{>9ycdy$^<**ts?Mi)oSt81F8r};r7L`>+5_GM zaXCzmP^gISbqC6&KvWzjdma}6WDL0TZZO3H=pZwRLy_VfrP?JSDUVV0l2GVImwq!D zq^v)#Q!<@GFqNmX1%g*m$D>q4$_q_e_zUtAHU#9sB}7m@p~;mUK>jIf-uu?8Af^Z5 zJ##m(wmwUX=(h4XCJxc=l^4Cg!J8VrEroKoO;HOAH**%il$5<~HUVHo_?i}coQRjK zsl^M5(tJGf24RHW)u^o<5AH&oa`LbPr!t;-b89xv&++X%R=Y{E8<C@7I9+i1g2txM zPbFRHP!@_p+i*X>zOpu_rBa9@E`X-xBU#ke3O)t`v491!lpn%mMo=KX2SXhq&Ei!D zx^gVzgOz%lL4=eJG^2+II4PZ9bMY){E-gPo+wz0WKn@-Z!@zcO6z-MF+EOx{TXLSY ziQVSPypnJVw0L4kRJ`?CAW>u$_LFp}$yx<|22;2^)yh{_{(7#J%E{~qR|+42Jt&T1 z1?LL+Y|LL)n8LhFixZ>r4!f7Ly+zSfg_wnxRd^cu$xfNlFz+qZN+LMW?FPOREiG7v zHnt7TlNsO~W2f4(j0JRkU&Q1y8O1u>5slzD8<nRi{|~>3fS#>Zp@TD2igI!Te3)7B z9AJ)y#y*3!w7I6pMzp{`<Oe@3tAvS!K}`|w;R_aNm<**U)Ww`B_RGfRJycDK?d*k_ zfFy9RwB{d>8?;PueiX|j5^UkT5Mi}O9iyp5v8&pHYszpn_@tEH3kv~%0<)*a>a#(T zrbwleN|}HM^XoTDtg5Sz&HUm2G&N+_9oll2gUUTwbFV#Vdo(`QL*sSc+FD!Rx_oVY zNs%6yGV~bU({w(%==^cBhqp`2!9bAX)$&2Sd6J<Qjgl-U+2RURc=7VV|FZ;$6s~@} zfHPrp`D7zOfs_%|cMsEP0G??mv1@euxV5&qb$R`Db$OEn_gimVUt3vKn=6;r)aEs{ zdW}*y)~=&pN_F+dm95JgSJtT1rn-1-{o;-5*P*H_U$=US)vjMtYhPWvcw=i#-CVhT zd1X^=T)(k)0sd}Y##&a^*H*4V!L>yM-MqGLw_NSxtP~KScS{xu$ZT2b_=44iC4CU} zA*?PPE-s(m0Jdq7!v;B>v8Mh?0S(|YtD(Fgg%dP&<$}Piz*r+!L$-@ry+ED$!~H8B zdaf)B<Gli8RK!#bbm_wCsuX%*ZpGvR_juJ#(=dj+(2HI;n!Vu#N`u|yBX0w^EceJY zdP!Nc(V@J3t;IevRjJo#iHO!+umc4bL=mzR!SM_b9dpA2dbV(E5;>{S1o7ZqwGMde zj^N(sMu?UXBCy1?%CJi+6T8S13GWNBErUxDrdBRLo^=BjmOyg1<ZYIX>wFpm61WZu ze()DKxpkMsK_@<(=muiL2=%oG(bZs3?7|!_LOIxe!`$w4p3YeDtS^lMSu!<Ec<GWF z5osqy_^ed8r#>_>Ez(dLKz1!GM+{_X3``hN!?2#|=~2?>2^0Y)k#2GsceVG-9^Yp| z@ff~iTHNtc&2m)0$;cCl1?Q3OA`%M+@6+PByomr$n}I8g%&-nTYz5|;ql9dE$`7gr ztxy5)V9vx#5zXd_Y=XLl>Qyg=t5DchO^t9pNrF$C%n=3|#!&+Dq+rWN+<&YEiznLH zrLvMOCZ$bwu9Bs$29twdrWh^#qE|FnylOc3zF4z))tRN$D~u`OmqZMmpiXx2Pmkh9 zq@;P|XhD*cAPRBRxYs&C3^@AWXJs*-3%J4YX6H+awxhKKWQ$D=LmNEfC?P1OyCj3c zZtesHULr%PZct>n4yCAfsI@iuo}tC2UqO>4FS1sg#<@u*syFdaCOVl+Jh&^TUP=$E zViCnLG4M);)hi}3tF>jL<Zk@uT33}6Zxd3Nl?ae@*zbvm098)ByNX^0G7iDx;e)$C z$hGo0HQqk*WQU$X2jtqGTJNh%M{N`GW{BT#(<SlgY?z`U-Jr<%I-Pjr-aJD$#1voC zi)Thn^$XRXs=+sW;BSv+PEb5;Jwe4*vhPsiX)sCl+SxW`o;~Ipky|;TNk7DHTwl@L z&o~zf!?7lpFBCesnOP+_(=}Sz!%DVej9z|F4%|KX5(PJ0dhj8jhXi){-oZ~JR{Es; zLg)Vy^2=;&m!oviJ%oW0Ob|<w4`42_fpYbDlL3Ck$z-WCZzthwMFe?~3K}V_D{>q* z7PA^`C}+2a784sH9pQ#HSi+*#6P6AMAOi7L-sFgZEg3a~e)>`yta0QT@pBfpvU!tI z;17SP?kM!}l@N{-Ym!kSA1*jE$*_p<ji$x+e=|V|1>pC*@bMY|9x!Wj0B{|D1Ci7O zXE^}a6#mbG64T#krZR62<*l?^`4%7p_T9oueHdfX<St<05BFD4b;RpTURY@M6@WYe z5-dKm0k*FI<Qxp+(C!^T-W8$W9!1bAc?}lW8yzRl@c>}tNR%=ZvHzg8&ADC%R%#XL z&aYBWTyF!b+WHtZ1hta_z$b4c%=WBapy98smaYi~zF+lCKtGg*3U)B^tKeUD0)Q#N z!!y5C`Y0eS%OaCXN-C(OA{EBe0k4-4_7GW?XBE!}x?0Eg0shr9Q+hu@dgpbP+^<Zh zYRyRQS7EP4!7fRtU`6XNtqv57VAdz$nyID1bAo*8E?KS<LZptU#M<WN*Vo0lz}ouP zTiq$pFTA$IEdrEh0*q_UQ5F;L@{-_(Cp{|NFkEbL!(f;yVLstp0@Sd@9m7yDDVslc z$53&{U=n1#=Xhd3=FXd{Zx#pdsGT5v&GEYMhx<E0UUR#Ed+Fe(^bpL)tn|E4zfQ>o zfX_PW6jOx`+uG{oEjmB&cjdZv$DsW$2n@=oDi<f`RxV5uW(^(cf?HBUm&lmo@`3Mh z{hTONzbS)ulNKa>>O6hbO5R5Knqjh`fFF9syM&cwph~MKT~ClgiW%Ot1dy>!4FJ_( zt8`;RC^93D5(Nq=d#4?k2c})B5Jq<Ff*H~9njv~d9!pZ8%d3|dCpKrbmr{xP>#JAh zlobH&hl3#LN0VocCX$Zw3~(mwTLWYO+&d$bHK-9-fN%m6ouLkoY{5$`IfhH!D-W3V z<)LC$d^p6DN62>UBoZlN6(9U|5~K;~N(81%Xi89TxPHsR9iOmKPm6_!c^VR7=t0`S z&pZKPO4hS`NSqn%BPpXum8;SSgRHfI9NA}ysR1TNhKRgi`#_KD6op4|yxI?OhQd|) zOrnf{L?P`r3&zX?(a5?Xz^T#_K2O2*p9{CbbKvtmZH7?-d+EVX8Q4_J%WML%n@WJS zz)Iwdlza*~V8Q55%yKWBMEXmlWf#I6>c?UDMk450AUG|?e~bKbe7dYv(kSvY%!PSs zWoZf^p`_ramNzQWL1dAjKmq(}Xg>fWH<~7Up_cy5^A$tre4>XgTm`$2U{Xw=mUKlK z6G`-wPr$uAh<!-}rj)1|c^V+O6UiJolBv8=!X?2s9lw=N4t@!l<tu^Zvj+cQb<*b& zt2W3mZHF(7QcDJCD{ZMVHkZ~?<hBZIhNQU$WKdd*qfHaag%0gUoS;5uQ+FT}a4VVx z!xfdJl}c!gI@c>wtLTd_nt)7P1ky|<i(^Sg2FTj6Ri}Qw%4Ih~_AoK!>Sm=<3<f|+ zfT#_yu!V?_5PdMp5O~cSdSzz4SWAJd?$~HOnTQ*sU6hGu=nZAUj#=LDR5Bo+Mj~+_ z&DspA3tyY(`sk8AhA7S<EMtTyjjoPXgwn#ti7Qc9q)hQ$GGW6=DiR|(2`DVfF(HaX z;TI9bEtKH~{%u9MgdMOjm4$m4c}86lA9$fls74I*P7weXs&0A6;vh?TyZ^Mlm0nMa zY0{8eb)$576(<v+kLNcDOGrK}%fWAfo)D%klBH?%mW0JJ<GY9!7f99yuSuA!t{!|y zcxx0yMC*BX3g7$F@?b>I_neUB#%)3QG0&mVMK~!V59PIKIKYDkjL!o)F>h=!2}*zE zyImBlAvJ`ra{!YFD6J{Rz|`!I`OW^2gsh|?Z3;P=Hu+ED)D{m)UV28~eC(shXi!LW z?TiV|VU!f?=Ex83VbZ~m=@$W_%M=tiGAMo_sZqF@g1M}GL0Xr!c9G4k)v$-?eu$I_ z$`m_*k?GN7nudFTBSoQSL%t|LI6yH_#+?z5P()f7dWCiB;$|;WYiMuHx^r=p4=Mev zDS7So$ukfuENs(qVXx8G)LcQc<vgl1<`CjUn_4thA88jzHI)?yTvzTqL|S@&jddGG zR~KP<&^)8LPD=ut*%H{sI{EF+?#6X~ldGt^Hcm|*4##Zoo+Gl&9U#Z87ONNGcVYR~ zLg^8HYI`g-hx9sQ8F$ECjBoh>2SxMU=3-~c$H1H&Ygr9tsw=T4GoaMt-K=LDkX)iR zvPvV}A)E(98Kgo(qlRKuE15kWIvr){%<cl^U2*eFIlCiP`C3DcSF(%AZp`!tC2RVH zXzkZE*|OxiDHCBJ4AN5Sta~eypCq<K1Ru{TZpv0UH7je9(S}1J8ASF71j+E=9UvyW zQvT?8H2Z5N`1W|4NEA;oHDyx<K)PaV+Tz?yUE`tYpH-J<o8~;?%QK$_*Ug!R*n#;F zn<2-$S@mdhS0yuS$Yg!EQg3wTMpkV>7q$+1WR(!v7*{G`hvzFESE@GZ^Yc}bBjc%U zr(r;nb*Y|JaouLCFGI_IsAse4ug#*6U0saVxHnb!Km4E3+!9w&b4&{Y;qSq3OU<y) z+UwivfG^0)gsXjY9OrNRn6iKYrbz@a3DRBtusqOjA_SBfaH?iv(k3RY;x6v0;kM+B zu;L`H%wLh*Lf&w$5`(SV(Ww(Fwa7>#>g(|D^wq1US69^=Z!BHCy0p0|5^Fygu-tHU z^~}|)XAsZ=X{@5X<O@{?c56`vo1j2uC}B@6>m{=$#xUzlNUayaUZNe^o$R8PVLsz+ zv5vG;nIewuYKq$y?^1d1E%SN%V-wSsQxeOouj^Oux)yZ{o!91B4|-~(;+(;EAJ(=R zc<FFN?FH$uY^myZFAH`Len%<<kVto>fjW2gtO3K{e3P02)Y3JYvTMii*vHyw16L6f zIe(OgyN?I!NzL|j0pCPABQF+%)6xQUfePdlMLkKweV!u#hXnZ6bODMI7=5Ev(5K@e zaGhBGNUMjdgq}UAv1^gvx*0sg(IKP!WBU$VyA#lFQo=fT5c31ZHM()G9p*MrX=Vl` zp`{E{1bI-BB!Pb59D^c_mbf(L2Kc&r<N6g*yR4``l->vNR}hzJUUX(F_2Mitd&Ew+ zX#bkC!j*^&k1f5InwLTW(QmO;4~5r*tRO0C>XkZvFpc;+le3<m$+b-_ED+Jz;nUD^ z7us1`4pv?Jp$C|q5yoNe4-w6wwRcvf+hIcw6TJ0&SPPzGQxy^a?KD5TK@7&EZl0Ts zaWl+>2z4H#>dq7o9%QYa6cf%GiR$B45FNa;!=4w9;#;w_a$QvBS;WJIg#k>Pv<WL- z6|D{8I#XQHirdLh6?sVGtawu7pP{5?qz<btA#I*&hPamM!0t4{?pUx*&KWf-hLd&h z4(wJJuo*9F>{0dPSUy%tqRnw|rmFBx&(6c6{L;Q16(Z<OZ7-?qUJZ{6$a<3vB7IL= zxRyR4HCT&V$hCWf0M+$_pH4$RJBmZdx}G><PYqu84Y?lVcLKiDpZkWibX=;QAxpbo z@!KeVqb!=qkT`ahRpMd;=tT|F>T%Lm6EN=sHII`lLvH9Ms~ukUF*|j#cht(p1?~+0 zq+S>|lnVkKc8CnI98@k`Z^&tMPI+0rhRF5RJ6Ly4iMzMn(^kKfW*Siw^5C6&p-iQI zuF(zzn7f$gqjG_#E9^{E*Dq4M8!#8pRBwT*MCDfZ!ql2tTE$iG08&7$zZu5Bb;*>Y zPe^0Tki-f}WM99!uD6M{w4O;7wCX$ax;$n9%_Fl~w>|)vBtij367N9Q%3G2$(D4GQ zl}lz&J_YkM(^DGHvoytZB2l>)m<J>|Rt2!nUh2LbaXmo3h;vo^#rF5whv#+XNNoq6 z&Hg(t@r{9lG?Z!0h36$9_qC%GSu_+jVKzUHrN{E^NpdQ>gGOF9T4GT^HX>r#eRW%6 zSD%`Pxj+j4Wg6+}uxn2HyW&3-ejogl49KdEL-BXO7OA3gio)MeaJ`nEP?B(Q*(hN8 zFh`;$X1PMM$5C__#^StW*zAGyYUq2;y~D#5O<%3pi|%6NavvrIFb-mIWNVMZzKaul zG8vA-y(A-(zygk9iswH_88-Bp2HTt>Q%asoPooDTAkG|>dN^X1sy!YYJZ`1oL8&6l z8uwRAO?m3~r&#@y_I|PYIHZy|nmKj%pSbTws+`@+%A1jX9oxhd_8&<kH@)FxX1mYJ z*7fo8u1JM~81;&#jBJcITf{WEPT?aV!ffrxmSp10^;?4QI*{>%i!U}lQ2Q(ouX)2= zxKu>2seNoGj26h_t@eVuhU#0X>lrsNX`6gmy<pyJ01drRahc1+AtxTqh`ZU^*<42r zX50ox8pOEOz}q{RGnXeAWP^DyTR42za+etZ0KhkAN6PVqa`bz}Qwu{Ov`epJ)FbR~ z%+AK7M(<o78PP=dNSuzXM7v2FoK88<DW)%E4Itjfut#)mP~2@x98mH;1TGLzCW#uR zUOrM}u``{r`^zL|Qy)CM#zUsK#dNh$VF9CqU+$vOTvcMRsL-K-N(<-}HWN?_!5!(N zM>Wg+kYr@9Ly9XEjaJ)D@mi$Ti(wS%QIP^$8cc;F#BMGsR+2B>plb6avQ*{Am&h)q zwfjkgri&XLdlh1b?i4Y5cB|PEJVQ^(YmxCHhfQeZRy|F;i?C9nBY=a)gNUhGF`j+z zz~BI%=33u|+=5sWgbqn&LAppSvsITDWeI6c$7I)q44@~%V0<O;rnI>Bd@ZVowE%Lm zPnZmV=gV+kdoj79APW$D?hm6VsJm>w0@*jIuw;obFNt0pGbkhJtlC34g-U_FfiETZ zRY)yzFF{M$y91k5@VY6m(}duiqPfW8ptFl~o8h+dP+!Qr+=f}{^2n(@CwUzgh1tXf zhEriZsZQx7cZX!6w)dl2FZT3&o4WVRq{FtzG+9IrXpxlj=`zHpOhCeTj{rVgWQkHZ zp=VY=N!S7rO|(BVGaI!2SWTE~y(g)~OL@O!Kx}7N6FtoW4rkqzs=MwLqt)%=cYqMB zU~zU#S}y335$HNrcNSUHu&(tCXeWnFTClg5JTO(tT``^M^9v;M&Q2mEgM0Jno*9IG z@XKjf$9#e)@=#l<=!UR*`_bK;wQA+)Gf0k)=agU{<XVYfi<AiFdomAD#2Lg|GSlYE z{3;s%V8^jb(o8PC^ba27%n|{Gpp5)Xys^=JM?8@Bw8qjlkDbgXux3R>+Q@1E%Qhy* zHMlc&Q*VL?%!{JgqPm-g+Te(^_i&}Au&N31t;IA)FC|in4jt*8!7YYHKZB5UVp(C0 zrrAg1|J@)ZN~p-#_`yeWeMBKIF!U~(A(g#iR)Dl?Qfl04n+HP$tdM&v8k&g5T-Zy2 zLn4l?Vja*aYC%Qx{ECvcoQa<#K_g@)&?dlEduYXx&vzrAmlA)ikwLoAl?$I$0ayzI znSQOfO{;Al2g*lom#)fLgND5rgp#6MADk8d98M-%sOxC_xOQ(yxB3L=45adTTe4ZC zPE!QbYb~>=s&<u)6)ct-YPO{%!CI_|RRgUN&C0<~BPh}g-_m@wu+=<l?OnVDdlh&8 z`X{<_H?HWKP4(9+E+F>M5xe$J!!kM23-N;{3;xp4ofz9Tc}=Q%nPB7FW=~0Fg{~W^ z!#r2mzNA|HSCn&Mt3Fp}09hhqnB_H>!*Mp1#eyQ3tMBo7VHc|7@nY@$w;YhX@Rik+ z-lN*4+W3ho=hyL(0sXDG$uM>5aL`f%=MniPIY28V!_cRfd48oR4ScEVWd<38I@(vZ ze`9PKhMB2~N|qIFVnsVwUgApi8aPJX?7gJ&n0bR?X(u;vdBvU5z^k%crRx-3eJD%u zdBwdzkw(1@O2tM(-2|mT6N~(d51i%{fkDDOBJI_}Uufy29ccpTiqd=wX7OZ~oHlH0 zjqSCHVz#)l(#BnI$2leD#n-4+MRFLZj2;h-K2v*8jamg-Uu<q2hrRit)YGk&9Mp)w zv9Tuej61&`?QEr?rurM;O8NMQn1O8<>y^$A6>`IA-#kN93*8VgH}sGN-z@D%c`&Ma zkl4F!H8Hm{T5>*b(Jh$9rC*@BIyPXZtPQ<)m9<r%>h&$muMf7=+zK1F)`E$&Vm(n+ z4wn76Rmp1G&2zVLMdDRBRXU4!$fJc7`UR6{@opX|_zU!u#7b)B8Dk&uXyrOrNCZ1* zw_8VxEfYLl_2is7ijup$i@7Qkz@tLMJJv8+=g9QI8Ck6B_G-<#EmbNAj#xoM6r7ue z9;>`?-DJi{VDw%Pc1hd@$XDiu%8_4Ia2%A9P^DVgW=|*F3~M@fH-mznf^Drk0@DWE z<%i^Cx(%5oom9#RN=MuLHm<1&NtZcu6(1xI-?ia>*}5Bu*o}Wldd42PwcU;t_vZqN zvw_^m?Vvv_A~RV!v`#f7kPGD18>mDN`osM?^wUHNy5a$u;Nhl%yFK)o*whj{DJdG# z+G><ZNEuH!4$W$nAGIJtTPZMs5#HcR9tFj^Tx`hy+A-|W&no2QN}yV^F<j3YS($Gh z{P-9lif$&b72eUFGVh6}Ozo)Mc`bjs@I=y(>$0;>D5{X_@KW?_>{$Y+I3UqhF6w6O z!HJ}$J&*HwF(sP|rsl;NPRNpTMGAV#f}(N@1Bq9G{Nl$rvf}?_pI7{!bFaKwi~sY= z+2`?pzF6^pveU!;dI+FTejGf!pNqB3=Me<x%_K_Vv8NVpOjB<!%oo%h^glLD0QbiS zAFI8Ck5g}dQN`Z$;ol!T7)QWgE=-ds;9x*|2lq#b4^4X1g_{Q-XK*i!XG}{R+}{U? zcSi{|2j@MQJbeG*@3BJ@5BUKv4xz8maI)vIUu7n3QD{Y@UtoD9y;}5@arn;WVxqP% zKpc}5flo8~bQNGoo|E6Yjv;_-g%(JI(ckxj@!M(-AI^$s7}&tJVoS0gd$6uBdvH-& zCFe#Z%5XwVk$sps*dz0!64As3ZDlGkiR@0*0}}O5PWp2L5;4GW0}>g(-E5=@6VAaU z7<_N`@b{iyz<z_R6;6{o(7Oj}Y=DdTl`P`908*3W%Mn+3RM^9!B{{ntk8bunQqmt^ zq$Coy!bI#wMG~K(htzOzW*QZ#7j38b9D3#?-s(7MS*e070kx810EpyBrQ-n5c(5O^ zM?AX=tX@W!2itu}tg(O=?hU}D2lwGr*ty&=Ezuu!z$6`L=$d}rD%zqA0SJ<}W6`9q z8`nMje-9q)6Lz6vo#n-}(1C^ASFR1fL}&y!NPL71(&FKLEGW=N3Np0nMGx;ICOi1h z$G)qZ-oyK$)5UsdA&y7GzWK@kC$&TasR>U6yW{Q8#wtzrN2zD}+8%fYyJT!Y5ANfG z`uO18vb-8YN8?X^lH=p|<ghR{WihNbn?j9y#bFU_R^~K+NDP~XqN5;-k~!gPW(w#j z$l<{pHG<8N;6Ag!HMNj49gjBX9k|kvcme`#sq;+3&gcSgKks{EATD5W?n9A%_=NvX z10pAoxXa}3)-hUa#Q^K`NbzYZ`AAq}J`$Soq48<pctK~!lv<Xs`k;*e-gOvIu%{0t zhXrTt5c0Oe29Q7o7Y~0QvRui|RWlZo-$CmAlb<LT^0=X3t|1}k1Mxl@Vs_%=#*dN3 z5AdBIA;<Y^PZO1;)`Ff@FE@C}3dNG{k_$<G_A(z7q=o#Oi5S58;ykh%G<o{ViA2Hy zM$Ffz8cF3-sP{-wKvomHVc={SE(n!8h-(;=$W1FP>`wv9>VP05fD89M7NS;C2qqIH zS^0%&ftWqM1;qWq1FFlt(3&o?3kHI#OZ-_4X5hjMnqX=XOWsV1X=p@S<2W1@PZ6&q zsD&#DTBDVe3D0AdI5uc+Mh6c7QLCXdp+^c+0#L)z3|&m1e>_C3gIP4gYyOiThlKao zc?U`?2e`v`L$tM-k{>H(^y$I);N!f^;+Q2vzGF5q6iCt*??i+JTmjM*`+h9$<T>^R zQ$qIB!&?*RRG2eGP$fvDR6SH<YblKzdAm1+2ceQ474&M+JoezE2;VKiS{l_^-WnGf zdb=I7z5wFnmf#=Pq%H;QD#{CpHE4icY6V_0(B$mZ>WRqD-?{@U`|zKOJK>_*_dRt7 zxD8;*DSpvD+V$#g!gde=`$ZjGWP>(Fmdju(!9;G(SmYxqwICuopT4U>M0BPTL?lh_ z;+TQ6=eRYNHW+jT3CaO_lmp5%%aiGB(V}Z%%|t3wtB&-JJ<A~x*0rAiW5OH+ABisK z7rmxh$Ay_1H!uh~Xw5t<fpQ2AZs3dO4WE%4G8Pdle(*cI^-b_m<V~~SjEvgeYS{o^ zP|onU!@L$w;!O!Bp@Tk%9?x5vUUK40v<8$g<Q0*FhU$_nc1T2tH+2po6@br*J-jAK z`FJL=AehObnNR%5!Gn109VO@lAj&}dzM|i?uoG|c*TK7~>XtdZh7c4b<g6hA#n{cA z7l1;vZ#UpzusSN+o${8>_Y&YX^TT6J>}gOXLWfMj-0$xN9BV?%Ud8HM14s4P4bmhq z4C*v+ryo!1F&tbFpNF5~RW{%t6#TO}O2Z1^hJ*VN@q!7;_PjkgU=3j!Ea1eSCVQX! z<dgr|5~{%h<%`G-)*w%A%-RCl26}w($xj~so^fMyP=_Ld4&o@|V9*%Np+nMD6jXom zlNUP8;T#|#_C~4R_I5aj>xL^fBw%|`hmuN!<h_HBq4%i+T@U8amNh>F1Yc`jOP}Tj zeK-PCOR$Gx0%!e`AA1s?V#d07aT)HxA5^0~td@@lAG5&%2Ok))0pk_VhijLYw=EWg zNpV6!Y|=I227<^cY1J?goUg3gJP<NO;HQM&xM@4Vw9G^@9qukMZRjQyDW+`9&P0cZ z&C&^9-{>o<?5psAa`3x@!lxEs_rgU3J5NzmxV@AwCw<TNDzPfKuBEcmfZlh=i#0i& z9kI2XjC6`L5a8tp(4i#r@SN~m+d(eM$P`4Y(J{!65b;7F@vfW`?E)v|+BAqaN8wIh zDORSp2FKVS28>8mRBacChR_%r$&~el%Agp4S@+UWdjO1FoJMPMgA{0;D*ZGW$kQ3r zj-AMIK&igouvi0ibIPEQO}CgIrX0$2Nkw_e3j&yczc>trevf(!ek5akWn0lT-fW4k zq1gcRjf_unB|p#*Tw|<n^FQ_A8h*kIx1Wq9rbf^bbHmP`7jYxl11>#K;{w>}u{Uu; zZj6#V*-L6MH#YNw`=dBvwI8F-9hEK<GYuew6q3GsDW6+KlG2#v4yN$5B+1IcP4rk9 z-a~#_;X35S*u<&O4vzHimN*`patUeDaZVTyJE=W}hxCJ36Co4iEwm}dhKA;-8m4j5 z@LDn#KLR8pIOt2Q(J>DG0RcTh%|#g=Lx3F*p>_ch*UP)O6t>H4&<m1cFW#4|h#k$D zO<^!3!9>1@HQu=9+j!%6fh+cb@VNtf7X?koCr^U?upZLjN#Z!@nuh@p)kmm*O?v>o z2)vkgSPX>C0Jj2S<7_<33u55tX0QaGRy+i*DvN>3g7Zif$Zux-N|@X-H)CxACqL6Y z<Rq<-fNF^M^4T=#k+xHCj}$mWE$UDpx29^LN<ImBV_?p_9N#93T>FXI8_&v2n3y}^ zWGuZTu5x8CKx4Kt^iD(aAt4(`wCpFUk6G3(x1uxb&7cQ+#ht)PUve@~L2xX>c`Jeg zptpzj!-sz_MawV_!n^W0mB)=G_Fl|<6RWoP9`Z*?`BLEJi?}0l<O!Cnzz(1M-yU!U z3e^At66Yp4oLzR-&x75hitXqRnUgX%`a^s6+<*fz7-3-!4L48)&vgHd0yaN|Sc?SJ zh*=i?O1S`RfOS{|rpE5TH3n=1J#?Dv4Y7c<Ku~1t4@b$q2D4)vya}0Ej`;e{<ltQv z1U3acc*~n6llYULMCwk4kCJ<d=!}da@8Nw|zM-jtF4UcdI`)rQ$NV4)2lt`tIwTK0 zMDngkp*aTQU-LpM@MD$lr4#R&gjIO5!WfPqh|w&fE|qva5ND1zu3uSlC=s<^YU$8{ zc^xm=f(Zcg+oWfsGCd>O`t>Locv1G^i@s*+FhvUwpiN-#gv;7Zh&a0TCJ{!j!zm?j z{EN911!AH(NBi?BLq=?liz!CVbn^GKe8g*r9Fb9pnH%C^vrMeSbXXZBcVHu;=uii7 zkmE?=kmH1Q@Pjj(BOo`mt4lclV)x2jNDn^F&%8xK%#aTyV*|ixIbJk>1OXz#Tts(p zvWQjGylY~|k62A6$zC=-xUcDAn&eRuV;~xKND#8MyQOp);O*;?M+fv^z;ea`HL{1? zx3{nE0A?NgvxmP|<X8g@CbjSq_6(~?l4gbH0}`4WrsAvKSa1~SU#PtZE+Hs{1IoRK zu+!xoMNWEHFPla9izre+t6wtz4s!}LoO@%$Q+G#U-HP<-E8(87ZYh%j19r_O{F)Y{ zYYH<&6yzf!B==x=aTnxUSoGp?Tf44Qus=I!YluOTfsDb|Ar|^0yjZjgs_QH5P5>3k zQ5oMasJ}#s`kG<Wsux6|%5Pw#(EY42Wk7L!{~Pg&+NIddIa>T%T_>j{C?;YQ+l4K| zQYXKs7{B(_W${ovBv&iqhK}@awITtT74&5#o=@UaO=3gnlsSP@bV4Ok%Dy*BV<9R{ ztdz^mp;Gn`fx=S6B%>65Q#D3SX$CzhQBATb`gnFJ^oG<j)(Uq@t8dH?!m{oeMGwUF zHp@-=SnQe}UGky{PN}`YnPcP*AZ5|KYz+ew_eDzcPR+zapp=7Tqii?!P>g$DUdFuU zKrJ`pFn{>>EUxhOnnJZ4{KH=2H%4Ds571Kx3fuxMp}5=-6J<SM>36IZ#+rhs^hNE5 zDzxBgaZ}1hi6>|Yno>f!?;%b=ldlF!&lu(9c=%Z9+xKQ~!`XvBEDS@j_8mHnk{`rx z_pK->Eaj5~HNdkbB*0B?e=vjV2lF4kUxgs1`K=(nNOlbJU`G`m3RI0zLc)z%Ej-Cr ztz?S>*uWivDr`LVdbE*sAluQRV5a$(q!M=IdV{D-by+ypYYstjwOvT2x-NLH5}c&o z8ZT%yI0=3Z$;}Vv!ogzf&0Hl5IOMHZL#!v9*>}>dh$iBdeVUAeVLhe^zeK@Fo5<rc zS=6zwD*i>GGKMbIeI*$;65TBkQOejS8^k&RA9O#E(t}TaGJ;VZ{5G3@@{@=6h0Jl| zp<MHiSjKGx^&_&t363(YWgR(+iCZfQDOe<lf)ZQbql{XT__d~-0ogf~m?ah7)nJr* z(2^#|mUt!mZJ-=1q>Lx>SqCR^zMm*632QG1KOTF7g9kq2jY>R{SwlRMSwlP$($Inb z*-ze;kR%R>KdXi%F|u$wDv3$71B6s0+q{c(jF7Jy5yuhYeb|~6l<o4J>y;WxwZV0w zF{bIm_u;y%ZfGoKE5m;6=*66ylpc`GPIhC9tlLD++~6WMF*KM(YTsiFuj|Z0^0!`j zJum_ajKDJqh0?Hf>thj8(cgxMB+hqJED{lG4M&v9*qHCkql6&2iSE>LOS&8fq(nsz zwvJAy)Myi8qE`G>Q7e`*_gUCN^cb3wkb4^`&Ah=jx_^d~*U#^Xk%}tNouWE}@%2cx zB#C^!epqDLRB(?Klu)=8mL-kx%BK^|<Qi!=t51F$iiT`s9Fq;&nYh$u-^~wUlJF<L z>+--Qi63}zkS(E3Hniy%zG6r6E{(6wN=_~=J^s84lo7ioo|DS~PQ-f}UPck&rCJ(A zEKxO)TP<yVs1;OakxY`n@7DzIWvCRM)5Alh0D*7@<|M!=X^fO|4IM&~`hh`<wNNPr zrs<W@4w`~3;lrCwC;xXUv{@VtHqE?Tl?+Z&ICx;g3cB)^XH?=gs?k;?PuYrX@0z$Q zrE-V;Nx9|jG<(v%`QMPl!{V(VoX1ZSz|8u^9mcv1;ZmwejiFNHt1ViJajvmJ7AK<M zm>oQrlwnQy%0cJ770*-cxfE>0Y>1{cw)V?g&Dr{4Q@wan2Uc;C4Af~7&a<cU814+j zko;=MHZX1&mW>1sJKgWq;4AnxF^LKeT-6jOrIywfCdGQ@Xt*{uG!E7dQvn5!Q}kde z2Xn?1SD><HDD#qCzF@-&5^~)@LpdPP=pH)wcrUqwL^k5r;!};gvc#fQV1!$Or@V>6 zQZ&^vX0@}U1W?ghD<-EYa0=wv%BO$IkyAY1yy#g^2n~u+cf2vmbodFSB;MXC$+p%Q zD4Jx814<HcSv3HPKozy<C!z1;!D)mIOV2~73AM*hAy()U`JHN6mlgX2Ft?Q{4A`6q zC_3wtALBiw^Tzai*A@iDEi*Rq6+5np7KLAD)4ep&V!XFtK!vD?<_dTxerTB&`vkc_ z^!_R)eUv4_k?ZxiC)bRnSncv+XyAfM*Rt%Q$2HTsP%#hEM+sOVc{he4HR<1Vlxqz| z6OD~0tYo#KFI};#K-Ec}G$R?)Kj%eE2~6}op8ioH3m}!1y2R$UghKIj3={t821ucO zraRma9_1~#NXA~?@;J<u<wY8E3-rs0oU(_j&7uXM7c|`}N1=?Q5>!K}1kJHj<V?<7 zzZ11+DgyTKePgS@T`ja9YdpjvU+2ri+Y9~3)9eXl8Jo$4>qRVbdClgq`YNEZl;WdB zd{2=RY<eUjU+LP(@Sw<Z^j6{x0wUTthCvVQzBZ>thEHLbLW4>sM!&UCU9?u27HnMv zP`GvAMn&L<?=LF0vP4~>JYtKtabhaRX%X*BM)~0aD}v(|=B>La;bm^HP~L=>F+MY` zuVaRuQG21M&;r@2A9_4VaQ9$((H5ize`o=xtroUajW|QX2z(XflxozO2xf=XjV$eX z{c}z%8Y_va%;%wvr8d+-jOiZ6TsF&DMIJipnu&JP_C(Me`DPRSk)dx`Bmg<jP9O+T z^llQx)C1+*3?LiDYm$Ur8;5jb?^;?BwKS|ONz>V)6**@IRbVDTIxNx<$X3U$`9d;+ zrGX7o=EpK;mVI--4Bg^sZqk)`zzMBzISig@HxiaDs2XYS5hYwHD57IXQWTN-IFViS zE6k<|>>|IMU@!b@>=LNepf8)PKqlym{*tB7173IhOYQM@X1){oPNua0F`bK>n+gyM zGZkeZ7&xuS*LIwUG1tmOH<npN9&Lq)*+5$rc6z?~WY*o8t=4auc3XjAj1;628iw_> zEIVTKVV@wK&h$4LS;Pk)+c9Huxnx@+#xx~=(L%;75Mx1psf<oV#UB+{hqHFB&%UXk zKek^gV@cKsTPB^SB<Ri*2xO7D!YM8LBa`!KMUBBXjB%+Ny`;w8!{5Upri$;N*Q_bu z(Tc;wjEA9OZAlS;l(uQXq+g8^^Ho5vX`;G1t)~H=G+fMeEV9pv?+Cc0$q3xwyiFYw zc%l4f&p18|dL09{MnN0;;<-cNu~0TVUQ}b?7Y;r~f{baSFe1Gj#E*DInR$BhXfPWx z4a_F&rCGk`ElCqImTfZlOm!dLN8^on)~iK-*%0`yN$njL2BtM{PJEZf^eVh1&3X8- zNUp`YKqyA*;+pmA<*U*RQ%g;(QL>T;5Bi4&n`zH{2C-(Is(fpdnTAw`bpp+hHVXxt zS;P%KqeN=fI9y_RFRFL~_Ry|}sD+uKp=V;VO*Y04-$zE>I6Z>t@2fX0Yi<GsqIw?{ zJ%D1G42_?npx@NV<441(cMa<}c#!hWA%`;5LEj^hAfnST5LT%A2B?(qFCqIr+?MDB zV61mr85n2FD<52*EP%~c0yO~A7$?&(u&kQLc&GQBDr3i&oZ1OIjI~U75h*nE#>(#T zbG}^r>hccJ34VZ~v&mZvE8B5ug2g<EPmRbW4KogD^4Yd{)Nnk915p$uw0y%Of~y|{ zs8#92xj~dZ!fwRAcxVi*cd#&1;!=#|YI%Xxu#!fxsJy`p-@OaqU_bduB(4hRDL*^7 zj|v3?z*G)%(yzt`qF*LW1Xtz9yvRXl6#&P@O|OOxLLho4h5Lrs)VX1T#<rq7=In<$ zN|26HA{cp*$U)TmgNZ-GuX>WTeG9X0+Y<JV8E2QI4AQ3_T#4vcW167mO>u{)QaYe# z%=@3IlBFJ8O>z4PBNx4CctaRnZEavK(N$Vu{Jar$haN_PxxtIfKA6D083I!F4;~Cz zuLP@MVZp%zxQ5!J8tu)d{WJUCwBP9QtubEFx`&2JaE^$UNcP4BQa0L?j}xzmUJ@f1 zi5iOle16=bt)s^+(hqW^zy0ui$DpY_7EwbgHOnN`BpDD1W-H5}cM_Ol*UK9L(qo>7 zBiz^Xh1KhKJoCFX&d=6t3Y(Cf1rp~u;drfzuS-A-h#;<$h)s3Zuva}>Z8gl<<@YnF zM)!t7;)?%5^6~d%y?M%Njt~QBZvG*Gd&&o4xI2)!$Z-F{KGZVyO2i$ueD^I!HaF~u zJJ&2{VwJ!;6_+-xk##IMk@&?kRcaDiQFX+6Q{v>%csZGWQX_oR#r!gFf4aG>Mp=Q8 zL=#J=)U3<P&^+9t7W+%M9zf7=ieX4gw!Qkmi+}~O!}`#zExy{YgsZh{m-Uq8rET9M zXEqh-Pc`6=erw?6wIdHPK5v5*{Qg-53ED7XTqjfzV3vBMAV|D+9p>V1%WrIiyfg*o zQps4{`pHl3i0Tfh<vx7B5-CUmjI{;wxdC+`*AnU6sioyOKZH-MXyUgOY>L}cE51)} zCsC>Ha!8b&S_N#z99eeGbE4~13nQy+J+4JZi?dU&CWM<DMv2N@c(2WQQ*lGg6uPFM z8ZBmHZVj1UW(jVRhQ=*O`OzG;<gH}tjf*?Bj;0&0gcY_V4aElZKh-^%^|TxUf$BMB zDG|^j9C1H<Yr0`hJUhw>O9WIGzk5z>5|I@+!AYiN+Sh`CA{#^)9?=<Y!kqXeR{<*o zwk<tTqhf8=w@MlfD<;XrF$<Gmk|&Ttkj;yL^6;l{b_YRDlY+u6p%Z}0vJBm%bWtMy zN=gmJ|8wnHRUQKsi++y)<;GsQiL~<_W^NjTtK1AJAExWj*ebfN6832#tB`c-KAf<< zB=RC77DQJ<*0Y+C3l=>s@^T}mSYJnvZF2ArMo=y`YxJxTIr~LNH6i&KzUs0sTYAm5 z_y-vod1GMRxkaG+wKbEF;?}zqzcKQKDH2e;Gg-V|^H)iB69?};{5{-C4}Xtx7%lI> z2IVvYADJe1T-OX#OJ=_}-b9|^tu~%Pk5=387`$T*Ml5C&zK$}PvVQP@Su%btw4TM@ zm1nUTVp9`70ge=0FYo%XNMS71{ih2evsKu-t9FyxF9!J?4)>=I-_L*z$kiPH+dKFe z`7LyFGe8Rj-4CpmB>)(cLKYqc<(^o+Pzid3o~C<&u!+=&pO68$2P?*kJ?-IW);%B^ zbKvxF<MB2WQ2`n+nTRy5#x%QN8o;?i60E?G!XzCTk~2Vxo=lMPl-)%&;YEdyP>V|Y zm|IjqKJ51#i*EGLq}a;_3+e+l3MDsz<RkD-0L!NK&6Wzrsw+Cji@+!*V|?cxqtXL= zCh&5<-}_Gx3+GSqUm5?$4?dsxKj&Y5`Q>{2pO;>G9{=YH75|5c6F2zJYEa}EAj9tJ zTJQ6U|Fdwzw3(|QEL#O~e5J_zv;b^)H^fGp+Qe$qTDltyVzkCr<AYzvG3vqtDPw%v zW+58HCMc=g4WffzXP9?4NW}{v*)n#sQ8MjGup0B}<lZ`ay8=KdCPdCR3oji*(%S~e zN}3mYN2i+3%?-PwQ|-Z(1*BV6A54k^Qvqm++T#`3ZgBVDpGHw$3)-W9w+8L0B_1hg z&+`yBpF)TmIt{=`?Hv4Wci^Si&;SU=U+3X&uKe(6TDlMpq7VZWkLN_XId#hNJ;KI1 zkmONP5an#4V;6XWpcZR@JT9T>MoPHED|U8+JcVNxFRB4Db5NEXDRI%wFrbld1|b<4 z6`xZ;o7&P~gV2RfYk^E$n}h#vz~ZR7z2#fQF5DB@Sik4b2^n)(fE89|NT8{m=-{73 zg}xdlMZWigY5t@kO`gT-A3H|LN?8DvTgi+b(eWbOF1rCn&PmmUATIL#0ywXL+`<-d z21_2Kko_ixtk0e#V#g-x`r#O`F2xltD&K=;l#!u@pqRGtr2_5U#kGuIJ6aHln`TQA zOb`#ecnp;k4262NabpmMRc`!30X-YTIuKZM3<i^60WY)%U2p<3w1i=RJ2a3B@e2`# zA&B$Q!9StzD{3D1+yEwPzxY)9;6a1H?KcHv;IGXgu<ySEiYaP|ez5ALJ3>X_gaTo} zhrS^!0FY@!BH-qj;K=lbYjVR+zYIi!AAa(<TCbrr)v07!9`4JJs_Xgk<7n>TWuNP; zL)^c+Zr(3CK11htXLo#~ucg4+N3d*rtODt}MK`%D#cc3>zKXKn5UvX{do;!kO`gw7 zP=G8A7aAO&TacTj7I)26If}8>1Tm2pH~T6_1QM!IG91DA^n~uV{goRG)9$6*fT%iQ zdSoBsT!S~yhj^P)@T>R`ot|F3Q1NYjg}38UyNBwkd+4<|zZ(w65nKvcTHbmU-_RG} zbCd?*py1F8exp0+hP1=IF;|n?+%P)~$rr#8^A`Y_w)<Wd<>fivm%oNAYD_mYW7fM! zeWb1v=1XvUg}XH;%&V5qvo@#54Zex#GL98cN3hv<N!A=9?J>t~Zy^cfxc7LDbl33F z<t=X%sr|bl(;OPIC?Sy$0*0MCaa>=$!IL)O>(Bt`trQh#PonMH#LL+s35p&#SO8W- zt=t$9_QQ7r3)rc;bhOK~=Ol=HIIh7Q_q13WeltpB7_%he_Z9!typ`Te_!06D=b#x4 zz)ElP0s3YF_zd<GV$Jw&5SJaVc&!w~N2!Oqt$aNN_9Jk!1G&DcJ}VhE7KJy?fomFW zFVs5C$aMnA?~C&7*J>j`hj0a6PZJ@t%NOGP0`3Re{H{ApX|ll`X336LGL?GqMFpe* zo$}NLRjLBq4tjKNnxCp4%&j!o*$L8b775&6$7-QCsw+%+vLutA3{l)%f0JJ$Hb(fF z5gY}~!m9^ZP&Q2|J?pXiJab%H-0M-kq?WKXr*D^mjZ2}aw@`*0`%PZo0HFaBG)m<P zuK9ku5$_)SE+PVHt?K;E_-eC&IIY=PTM6b+aE`CG%URCO+AODQE-CN0H(Q4*UgM0? zWtseH^i5VtalMb}pH;_T<;PJxcda4*j36bi`{!Cgvd+#kMKCdlUFTN-Z6{YeU&(J0 zuIvU`W`Q}*tm<&DwYse;zYzK^dQgeydakNUQW}f7%xwjv;=wA+cY(|C;pW2tDsh7w zs~|r3-D$?z4gRQrtv~oDv}7@yM#USI1;EUP?P2OFU5q3&iEZan>$1rzzL)~o?wa<P z=ZndP0~8P=@<!o9v;QO%BjF?KNmL^Wg%Lc8Yos@+_az^Jv5oPHNXrZGC_aWJNKNPt zAN<p9aCA3Ar}-5^%TM&#Y<4AtLXj31K^h_mvuP+=N^`vOP@{XO3~C6E(8Z*sSDqVb zHr4p9=4oezY@lrPP;;~+AeJ=G_O3%h#{oWZSKZa<V|WCQH5wFOgithrmj@HnyHODG zq`8i1*3!r;@QJ9wFOA7#HdrK$VT_hxq?@3zh4OYio}&vSP$VjlZmn=+f<)&Ey^<I7 zmQ`^(W6hfDA?5~NO<8{MyL{iAO3P2oN)!QwL(;=GM=^Uz3d?{ujB_Zgup=8r4euCU zSW3~cx?7~aW?SHJqIa+OaGxyltJx<@f!b=$7Cy`$OC_bj84G+mOzY?FjpYl#vO4j| z&8aNWw1uEsy{;Gr5)<e-m9|2Y>lGi$3V7D!ex;sYdQ>sLkK{=OzEFfRfI&fLVnJH% zZd3$5a|k8}+%>~?nt^k@lSI3zMlf@|sFXC0f=eJoJkf>xExhfKuI;ru9?^KD>?LfL z^x${HF+htKJj;zo-H%74VJeP1^re#;^iXr+!I+~eTx;|}F%9??LjhYF;jn<O)xIb! zhY|97Ty+((8U}GDjtojy3+04!2kQ<K==ATV2fse}-{LMoQ}amH7ug)+{<^Kc_2n4r zi-o>xd9Q!krt&hSUpSNX)zI!t&f<&<0V;{$P9}8<t`EBpZRifct&~fDRFI>MTpMhe zbe@t-e+W6CGk9ooQny^!w&1I9a_IN7HO0n}BNG8#BN|PJ9nmdWC~I55H@XNm6HxL% zE&c!Oy$g>V$8|RRSK12*Bmqh^CCdgDj`c0MD{95thP$L<Cx+2GQ#;c;J>8SOEVT;+ zp#4VjC2tTpu<Xc|lMo-Bh>mU9))z~0WEt?-|3myI-?`Mit9xcIyvP~?(stLir@QLZ zIj5fU)DpI_gsbO3aPt)}d5s`x?BSM)p*2CE<Z7cEl_A){mKFlJ9EWkqu)dx;mX&L8 zsclgvxcq}e0qvT+Oc5Rfn|Fo+eg*wg$#_OAAeJgII+7)x6aV!UmMwcM-FVuC!=+}0 z^zf?&ODC(0qJTwhtc?>&!<UaH<U{(0+-{~HhWf!&?5MUo!bI$;9!Dc?9);guau2wi zOCOiWoRAOYmg)@q@O@V}&S_&;IHq!Y@JDL{v13oS2Vk@|P-ux<c~KI&3Ony~^n?A2 zNxta`faaFkr-ARLw;Ep|iBX!dpJaOOvY|%y3vNTU#7=14d-@@?F@X`yyUt!{Ltfgk z4J)(}@8j%WNz!yg4!m~!yeR{ZoSXoJ{uPo$q#V9jXCqa?dJhS2dhNiM*lA+tSBh;k z$q$E}mmvtZ6VN>@-G;{udA+LR!@1EqQkc9x3rJ;Zqo0F44ZPX9K156etWq%5b~4^7 zi8DHhBkRUrljAVn<}Qe;1YQ;h)S5r<pEGXR;D15zJQn=#`OiQ5h36XhUnsu7|2|3h zUy(h{+OZ1(Udsk)QVyfjH#Z+21o%<+IS&?BrOt!IRjEM;t-f90XFs|4*@xYW1Dt&f zAk;_Gn~gr@iy->6dCW%udm2WN^8L{eq=&6?6u{`=DjWeAdZ_Yq;Xr4UXoGe(6OV`M zR0&TCuJf_6Y=_XC${QZQar#MN2&bPE0&d#(4b-M}=R-El%@I+VEjbSdl-Wd9`bjOQ z%0^lkQt2m!(2{OK6Di5pT|h}c^)L|0S*1E4lKR?3NUF=Z0g{1K2LRcBQ~*dz>O2AP z$Hyjf0-(p<oS?_H92@e;7hQnIFt{<4+>UFEEnK69?a8YdhsissO_*LM8ZVv?jn_<^ z@Azm5YNM+Frp>y2GT>(q`xs{F#-qPosIzd!k&kf=q05|<0JzM#4*|#AgfME%PqGf< z6#K2XuS24@JY<!d@JTx2&)oUICUqSEG3mQ51XDA4j-%h^0WHlebG%d0Iu9{xM;_^< z8Nj2Ktl$Y<PJ)LU($~j4b80pi$GY>5Ym%3TIjiZR9(dFRuJKY%3R`38L!ahzjx0Ql z9<4@V7-`W8rwM2HU>S3Bw4+<xgdpI<NjS`TBlfW$>bm3H3?IkgrFdsQNMJ}1$I&b2 z2Xd5$0CGHmFpekZVLb4LzCKy-#z{5hLpIEf&)co8yD%2vjBXy?Ljx#U^ByN=;$e5u zLXGK?D0Xe(-;x?Z%Qk&8^%z_9N2qo(9Cz~+JN7>PF=}^i&9~$%$iz;5|G#`Z`~S~> z{`?o3{9n(1VX^=JWbOZlHvh{>JpC1$*^g!8KkgBQRS&u)W|UZVmrUQoN9ge*fDq54 zr5>0vIrUqMz5Hv?bzV@{*O1;Zn$)5%BH7>p42e7vX##3JTyp1eKQG~tpc{h%IGv%X zcBYiZdudEFJBw+EOR%5mgd1$g-~uLjNh+B|sD(*A{0%c{zhI?^{|+zYv-ab^n}s;g zRrGH)l|1MH88DDS@3Ei%T?2y9Kljx5+*4m}hakuThlC)UE<MdNsh&=%B`zGNgIs=6 zmApVLJS5ZtpR|)Db}tB9O=BtwYFK=fZu;sOI~c!?umS&442A2WNcuTWQmT$rq(!t7 z@4^4EW-l%Valv)rS4^gN@!)vB^KO6G^tWSC;8rK)!t`-GVvhrT;e036+cnWcOt|%_ z^m|`ELbnXRpkp27$uIbR3=6mZz5FTmNgSiBjk!FE<i4iVHV-^+v+CH+Lo}^U>olN| zo+x_w9teD)Qe!)n%KAQ3T@S}hOj#tK!}t?<iNz^1XR<RAnJd#@#r>pUPzu}Pv_e5y zG<x<uo?pT`OyBD#AoHM}T+qP8i$R_DpTtGE(B5mI)0=RS44cH9iRGG?WkorRx05u% zMNiHkSOD=C@d{Q7_#K^XSLR?bJb`tP=SY7IKMf`gOgYig*;#xnm?343b+LDmMVD6A zI{GrEZ_J-!Vxm9O_I}W>T;eF9YKW7DH%q6G?$Jqf_^G`gyK*>kw@|MlMKuSHPvxH} z26d5lw_Tr1+lFY*IUh%|?j1xnr_o+Ki=R(dTj{En>#)}TvYr|IK2evkD);4SA3iP% ziT10wj8<M=`KwM`)>Gx7)&exT9r6E=)*Dk3yNgY4G}}mXVp4HBjRI_AwMg{O&>P#w ztm%7Wkl@e&WeV)@%yOeDm5=NS`LYc%v+-lc1E0-1?raCZ(o^LUa<kZ{3S07v^AVRp z1z=J28?eufw<~gbpaT3XRfpUUJ&j~y_y;%T3Uqk>YI@hS8ST?qkYpQR=nA<vpfLA_ z+wJ@E6qHhtsDp+9U5&RBR`Q_?vi&32fp_EJ%fw^knak(F=aDN2-wkO=fB5|xJs-bf zbcEq=5wS5<gppxf>j)UY)?T*rqQE|oJORsBd3XEzb4UJ2=<LRfg2G#Gx$e=reBn5K z((mN$ZVo0{+1gsWwzYo!+HyoJBazna@E|{$Ij3LR+S=GWgNsNe*wqI@p)e=Bqt`DT z<|QAzwE_)Zqz2bBT<9Yja;)5F#TykLXivOK$@D8?-4QNZAdN)EtESbw`@makn_KJG zE=B8`<Ye7?>Bid1YP7lX;##zMJzBj^sT*rIUc7$eYIODHm96!SD{EA1GrD;F+QpkU zZa`C4zU)2rwd>K^%WD^JZmmVPR&K1XY(^V5ZmwN`znkmW%F4C1m8(#3?JO4EynfB@ z*?-1;;}4(%HOL1bU!C=3KjS`vo~vq}Ha;ePah~I17Y{50!H|~>9$KlP6O21HYF}M( zf>HLIG9c$!x>R`T0)mKEFVGYH;qDda)~Ov0V^pG2snWn>U07X})k6JSZI5H*7CU6i zlOoAr6^+x+%m>rGKxutC201T5?%~ExTw2;RiL(oGyJ7_os3?Q{tq8Y-QAtt)O^>_{ z<Eu-iT+Zn54P-B$4C26lIjIHhdj+(+L`vz$4EKfaWu5@OwvbPND(1uNAH7-7;Q;1C z976tHN#i~K;we9&^^VW7GNTU5W&i{XRuRiplRtngCUCf*sLGL_Sb3uIHbn6?HA(5H zqKJ;c%B`|;(O$+mFOMCTPh%Y#{7fYOt@7Ec)majLNS$LnI-cQ3q$|(Jj<ustuJFY& z%$|MyGeqW@RnI{C6A<Ryda@f^zj&_}DOjK}>C;Hpmgdj!8|0tC=bkDXgmoija$shm zR%)w~bsiq9JJ#W}OU*XQdOIns)!r#hFm2RJ9N^VO)Jyn-yOxbCI|-Kcte{@AY_Gkn zbq?bgo)vy|m8-GQ#F1Z(3zX1g;3}Pl+sTn<FlW0_l)W52Ma}1?(Xb>{jwXGf0ptu$ zbJHw9`X7ETGbwHQ?EorW6@dGT*Biiem8+oXbns5jTX<=LJhP|q51uTXqYqhld_aWD zsZ$K$&rk@8EX4zObS-)dg-B2xfNo%9`frzdY&~Oh2t%Ka1LBsp>k?nTcKh~dzRGr_ zdMekW1~c;d2H9&D?d)9Q)<q%x3_dm=uKSF?l~bB}kQ2{Jb`Fq~2Wz#f`C7olbE5uf zvd#(mSE~d+Da-5DU;s2)-OSR<m9N*$@A>)d(FB$Zp(D#9HO0x+!xMcSk41*Y1@G=N z{WH1MJa^JXtYsW%o)4)PtY^9lR$Ok<QR5xxBOCG!Ib_r_Z;g4XH*ZC!he;oq^?P~B zkO@kJyLy~~3IaxUTE&c+2*g)x=I|g%Rrhfkf#%Krwor%#vQ=ZPI9SpOve=Y*w_Qx) z#KGVzV?07WFW7g8vk9#`5e@3N=;JTTgDls7xVr%(03CQR`NrZiZJ`^WeW7TVLedW1 zKpjo1XzlSEa?eKofNi^ybckvi1((R$^&R$<Uv;~++s;ssm1axo2dvVwxG^ECieDG; zGR%kzD-BHDm+~U!KoNQetE(o0WV_#Qux#T+9;sqthYn4sw4Tc;QoA*ACbXStEjVUL z5{*<k0GLEBe=}`-(*mcyn+ac0?KT2f^t&;UEVzDLVqfXXWCC+U`ASz|?1J<i)U;YO zi?qhVC=XhnOkLSVfG%9#>gTbdWfEL*INWA!bN$ja8Bnq|{qA)yhQ=yMiMS?N8R#72 zwkx!V`7}|!K|{<7zTqV|5Pf4*SJqqcjX<$p-V%q?%OlneOc#&O9#~6RotWDmDB>CY z=k5IuYIv=!20?pRjv56WWaNMNJ?hiQlY|=E5I0d=BJw}ng())3n}Io^q+Phur6RwG z>N{?_!(b?&_k=$uTK_c3;4e?Ywbk`4dXeyV<%SCHQSm&o4EhYbg^zRn1&_Q7J!g66 zuA-j1%6G&N3Dn-yHosJ`bQOz3Q9c1I1CmOSI-i&Vvge5|KrPsaL)jg!VG?(UDd-h( zIzbnZWnI{1wExX7sGVz#_@}_90lBPVp{R5z706Igk?pCew+4;oJGl44OQHHUFOpXo zw~W%*8h(o19aIk5ke$Kpo^U|SK@V*Mtb^OMxJN5=jeT9-YMo#x%?1b}aukkv?>Xdt zF|{(s^UNTcw;JD(D<sMYhD2CJRhU|o=7W-K127R`N=RGsLQ+ld_ON1KXrq?w1XBzj zNk_WLGJ)_nI}vSkd<4CH!lns~;=E=*=S!}=4KoMJ*I*JPxxIUW3V%^g?{5ofS9b;2 z(R3Y~p$rNnJriZ}A}q@-tENg`9`TZwPw^_4@qL+yl9@Mzr5}z=I5N)ZsCgmx4kV(0 ztfTStJ;=!|f1DNTw^5)l#)WtX>eOVHQ1eYw-)6%PoA*?Ln-A5uU_veRwUef;30o&^ zX@iy2wgwPijUJ8J&ywZQPK}Fr;F%yB#05sgfXK@Wza9FmDm$(VyRtl-9u+E3U`BRD zy^E8}5!hGC1J!JXTd0cYfWb7O%Su}SMFCD%o}#L_HVAZPvsz1qvUz?3Z5^rO8wThs zlE=zRZ^rd>FX>O;!{5V(Ac57&8Yk8Zv*Jv7{*haY^0aXp3^rYnYbZJVt{}XG%SuRd z$;K+;Qt}>*^Qz?YiWx_TBI2)!maG5Oh;m6TU}bKw#Kk~W#GMa#B;@jfm9iFKcSL^; z%EqKZ;LTT`37t2=CIG6*MZA;GcjQFg%<bp?c@xA=8&UDYA2<Qh3G?yuPJasvW6V}# zoT`tc$~VrN$b+G|pqfNiYpFI5MN0ZXykE0pq#3Haf?2fQ|Jg<B@{U<&yzU=<e{uRA ztPr5&f$E9x{cr2(&uLx^t8uE-OnuE!yHZOLGVX_zlOh!5%c(7KzHxC*Ek7KEYxWV7 zte4i(Uq{#bGSs&(UM0Tsf6V#`2MuyyD7t32FolVdGbVSlrBHE7NQttpw%={#xH+Zu zCcLUt?|{4{f8eA@_CSKk4et$khoU3FVqA*FL82m<X}Q-r1mjQGciRkmUMmUpv+k4$ zhCOQ~QH43jJ%iU`mqU{6P4A*O3m(1^(p6QB+zyvE7-p$4D2Q>e{ZySg(cH%kw(dC6 zEr3k0aUI)z5xyI`#oS_n0B_?S3pU7pY5N&&u*W&~&|cw(uae$~W9YU}3Rc1`<{Uo4 zTkmwATXE)O&Evg_MTk0dqH`9WS*@D5g(a}+t_bT%=M2<2=a6=*qcS>;5rauDLY~rW zP@b_d(<|IZ>2z|shey!CLPR^sxDgALtUgNn*U&ssRZF{j_GQ>Px{mz_x^ANj=d6~M z39Ju^`hk$4bPQ5|FDcDJu(#Gk^()s5{6Gs1)jZinUXmZlxOuG8U1US0)sj5wr6)iX zDOV8P_L7*4jRu(j{>7DhPmU4PLQVV=>DsV_$p9!rHn6VtNQ4UHc8-kM)bkIE@dR)W zj!`9cl1yUaodaYVQ<<Ml<|d(BhJ_el)xPa)<yX-Z5KZ7E0(xweoM{@g4BTnzM(Oz- zkc9_|LkE5@)#u~vNUPlWQ8MqvK%PhQV59wDCG98brTQo67~R#~L41K9r&&C2FMbul z63Ek_&a(NffkL!WO<aPBOu?b^vQ3x@Jp=ZQHQ3kZoG`_mz4ie01g<P`h<So_+9l8# zYckBoc-WBK=h{~OX)0Bk^3>2+Cyq^`cdE}-V-d+M8}C#ftH7E%^{19D^{Z_6s?JpM z*iNpAo;mt5{CoQ9)u&fiqnBP<zIt_eb5r^X`(m3RcB`xBu3kNd1+5~%CfaL$ra{k< z;K9a~#N=ITSX9?osk)|=DJ1Q9>NJ9Es(l_J*I0`(X_CyNfpN6#ipEBnDZx_#yP34i z7^>W)6S<+>j9T$)qZFYB)?P`@k_({ED*|>&O?n$9Vt`PoOP&AhXLT{WrrbzZ;P-i* z-q7_!P?8|(V%voriH!Z4o`d#U-VCl{BnKGyR!EhJv*KEKhIcj0i{wD4I*@?(>Luir zTprM@pNj{jBkZH?+@@>F6i+2&GRk@Li7KW2*6+WUh}}3qv2ul=Qk>Yrv9h)+;F@1) zI{kSjxE)$^uFqmziIhQui&0<rE;Xn+DRL0M!WsH?kuGy}%oQ=QXgA^|mffSG@X9_u zDo)RB6>(OkdZgItw#wf)Sn4_j*ma#NbsgVqBzMDndYBuctR-dpBsPc@c#Sb?wGy?W zvu!N0RYqYHcnG#Eg?5&5Qu*JW@H8wVW}RgPt7$}`jis-zX9x<wl~0|tq#7cXzeCe! z9vm?utYxJ~#;v4e?bF*_2+`@}tz0_t-3%p^XG^5h`#U*Xdh;BeWgNtoBix0?L^)hV zd*WbT%APg!2T&AdRF`p(wuik7A>JMoh(xZB8dbuJr!E(ko~kHIPy3K9z40RxZ99N7 zBhQwZMG<sG1%FuuN#04h8F%soMJPu%RUnTF!P2%T$ka_4s1vJTE5k3OinUM-X(@GM zdUvAW4zpN>0;olla;kijamYr3K32-1D{-Xyf4sZCO>BTqKg8>(MJFUr^{`YMt%g`x zeY?uVK-r7BP%E*Ky^-p8+nc9^MS%xp-lKIqBuux%{h2eu;ClLV$PlFn93R%q3Z5Xg zF7HqyE}9S1JVA^GuK!rG&kkc?*Yy6YNhN=X+D2EgtTWFNgI7~e?}PP^nf<yz=|csk zKbN2?hTOTUn!>bb+?^aH<W~xKjij52qUBqZol|oqOxLjQ*tX4y?H${;or!JRw(U%8 z+qR8~&Hc{v1HOarY;{#vS6BB*W3B7bNX4_Ar8JX#7yBNXu^aczBVD|0f-w&jHY6q; zQfvi7GE-+Nom33eE>2SAeh;!Lj@)bb8-phn>Y#A0hxKed&=@*q^|#$Y$Ga%ON6%x# zF&`6UEr(B+aj|M(-LICHqrJU71*2guAAUzLW5!!X3{MJ+Hv(4v^gnO06)`_@?bt9! zZrxM4Z6`^d+CJx&>0|v2*{<mjZUp>Gjvg5hcq3XSt1>A;!cGG;nuS!n;G_~&#_)e$ zNLY-Rn3=EBLI=rc(GfH$w6H7R4Bg+q2*(yF$~16Ju|;@@-EdzXa8ukPZQGcuX(SCa zmyJ)jN-|OeA`o&8i}o9>J4C>J%ycDrBHic7^)b_;gEfW9*=91SQ`yIEWHQBn#&wtS zpWhq_G|Ct-xUS>2Z>hl+DmTcby<r^J;CB?1Z^V*IYe}Yy9blG2<hM*OC~aS&V^%C2 z5@u?}H^H0Q2spK8hKD`xt-by+Mw>A>Hgew8rTlr;Ik&!&Tkq)G?<F5fmTgxP^+aAG zi^9NcO)IIMS>^JCkxC9$J8sAXfH9^D2UJPJG{3?ki?tL>`KD+-jG(=L(Wu@fN)8tg zEwxfEG;Q+Y!DM)vO3EKvN8J8~56z(bMU{-Dgzr04LUGZg%ZBBoCc78>0($>xK?Z*k z6V+)Pj1hx$E<A1#Q)xzF&*p$Vq^D<@A!pl`CcakIcU?-V0f=Gh4eggB3vJ=Wlftfo zJY*468{KLE@VD4pj70fRboRn8ZjMoH);2}e_Cp%Jf^)wZ?x%zx@5lZJPMp~mG6aog z^*umfi`ZteUx`hf?-sR-;FJBESy8s-*^P<K+W_67aw`cm;IMfbCNzWO2P&Ra*5qPS zgvf!faLiGEbpv`2{yF%~fT^PVRS5LxTw17i=n{Lu&n`*YJzeD89iq`*NiUOvEOETT zZU1XAb4Bo(*EI%79kWgMkDt&9K#hW)vr47;>9~uID14+_r6ox}tvjGF#o|IBt{nRh zju#RG4MJe>ikFxl_HsgjIkzv8BWC3WPIdxIcW}{;k)tKwK%Un^;|~9Koe^7#bt1(k zk0OjA`Jq<?uQIWpBLN7vN17h^L<YySAiB|~6Gk)EeiD|xwlj>*pxiK1zckYV+PoMf zsC&=ror|0(#2Z_@4Sd^E$vZxjOOi<;maxL$ps+e|q@HN-NT*T<hwRIWE(C_P1=RF- zzqW`%S?Mb|%s5x;e?p%M`(PWnhD$GYm3iuJL*v>7=8-B{G>knndpLX<^8y1-B|E!r z+vh8qNwun~!H{BvVw;tup2n60#WQqrpdw<%Wq6@^$SWa|@z80H9-@wKZ}(6T)BdUs zi!Q+5E?tu7^7)F2)Pt1N(i581R2X5JQ`+4dGVKJKxyX!txlBa~B!DORPwYf4<WN=D z%cP-)Pi)DE!vj`bzkvVz9t~@FQE`hbpXLA&)=%f#lIBfHBZ;M`fiyLOlR=EDR@%nX z@~0`e#32-=v8+$SckR_q$W$Vg!Oupj>Co#ViNEIJTQa5Xhb>8(U{!J4Yc~a`Dk|Fw z9(U<)GmF)*MZ7)SsCU#xTdLcr_*W{8r@^4KVKY%X=#10@C7nYShD?|iHmmuy+r|o{ z4WG#4B@tPbtxT;|23TvKXT|+$lx@hcS#cu_VV%2nm&rK}G<$92&(8=6jj9H>HY9{~ zE;)j8VQyK$xmh}Y4UZy6DcF)2FkN?$W9%GM8AZVYELXb2doft{e?C&qamPPV>Vg0b zT5>BipkOu8+H2o9j+E~pwfQ7%;<996p`>44>?<LjrSc_od{snr)!C|NYvYt$@v3B* zU|>wQQpC_*@p1*Y0v%H2f|O9@#`i?Zb0{Ac1b0zll-)(^Sm_;7&zHFsLO7*=uR(T> z2iaV}rf{)S9UWNbqvF+T$1Yj<7}QOYv|<IQF?csL^b}!T9MkGOqG<5oe`jCpD8IDf zeIAc)mYNa`#7worlmxWBEnncf_w<%2mfHw4t125*Fh$1{OsMD9iIio>Ce8&ZVPnFV ze5YKP!=c(PZH(6RusjKS&S-C09F#pFuE&I_-nkZ3p8iZnZDa@?^b7F?s&^?Y_Ff1C zI_W>-834<kL<U6~Es}N`&P#?6oF8N!lG%KccaTc)b8^A@Y0>c^WtP`zy7p<7@bj)r z+0QU+INFzYh-2z+Fh!1jOA$%fUE{p5&g|OVJ!(U_uT|K6WLURpoh8p6n6yIA(bVPu zw_UKokEexfLQ<hGOx#4moN3tMm7q8k$kVN|_D&PW<O<u+b{bN317wx1XmVy*SNsZY z(~dUnt)9mozxIr$1k)B6^>N`@c2##LXv`Ld6#RFO!x^=N)VTurQyqR;5r^0<{QYw; zw3%(l2eWy@4q1QDc|0T8Vm#&I$GuxuKRxu#+hEmd2Y11G_$!E?=`m2G(u6?8ALQXx zl(H|$xYGhFenN%(NdTo+gVyflK<NT_U{~<wc>Yvhuz_EGJarIR)}z=+Sj<&AByVL+ zqU_6L*LtJ}r~Yxm9_6*2^K(R^`C^~;Rv^%la!8KR?yu2!;^EWidoyLx`S4t7nV%g2 zx9mQ#mWV>}J3l5$e$)3R@Zs&+de^r`^<0h#yJc$Dx_?v0a010|03sBaJOb=f;oFHO znnd|;=L<OJ_wzpIzj_4p|LHi()4Kx#l)iv$d|49zb!!f9JONCQ4aymVthS+O{7?T7 zKoxw5h6vB#iB_@t1<006hGNnO@-yct&UyBP<6xU>KCZ6T=9Exi|4nd3jui_P+FJ6D zcT@U6xj!~lCO6T1SWwWDy-mh|QdkCNtGs}K*lvH*h{L8;WnTCyxjnp09Ug(BG(9j6 z=6s(#`Az;##tEJ#81!@9kzU`E%!zLBALs=#t-lgEF;YqO_^;E(M^XV3pUhRJhE#LW zJK*<M*q)Yn-KvOm8%5KXfJl02<%jzAAMzc`hVJ<Tb3G;Y4G7_-R+ZVvKI${b08U)o z3`bGIYclw}Atw#S3)ps!Cm~&vj5)$_J(tnvj3LN$$kRWg^r9h^g>0c|sBcX!;G`!P z?)x)*J>fP|+}{R4FoSYgRG}??{huZdlW?`<%_5=fs%I^PVY8{2pvRjP=;Qt6F3&K! z8eSqw3&{foyT$)y68qZ_FHl)wAW&*73~XBGB7S5@=@41GB9y7Ws;(dx)5aJpJx1jI zptEDd%vl~?mXI&&^t;tSa|G(b(}(0>scdiX3yO{7HU|z)U6-bd{LMahFAPtRLb#FB z`w#W!;Z!@=_g^YH=6BhU28|RwSa*s8+FI%{(#>f+oyjx`3vz2ZafAtEsA&K#s+p(W zn`*pFwHV?mzoZs6q3a*?eZ`#J{9OqUj6=l|J^=v=!Kn5q2bm6nh)&yI6o*d&dQfnk zF%dB%!?|-=3hKX^@E`QSc>pqwcTZdj+FXdKl0o(fK>-A#BZ5}_96N<>5R(trG2wnv z$x~hp8Tl;^amrbK$Ul3gL^-`+CNG0kV<7DpvXFA1Ts?qU3&mF{M#35`MRF7q?uwzm zzSe;a<DYMnr5CJLVYUjhfBxIa%SWf&7{Wj=cDe=lMfHrWds9{Ceen>Kcun4j&cA?6 zJoeQ-f_LmEjt-lz1(#F_)wY>YrVvtd3=tBllPYJk*nilPr(6-Y>m&vC6I&}p%0e<K z9+5)}3NS!K{2lE~N|+Gh;N9Vfbq1<_{D(vU{BO~0xH`2Yg%_WDt8kJi@GJIh2U;vd zJ3B$t92(O(VsD>HGnXsIT6l7eVUX3bZTL^nwiWq@AV0pc{Yl;kPnbWhs4`xIo9Vj; zqBJ#2^uCl?nO6g*Jhd|sf}r)P)XAc-m0Yg3Vq_W%A+d8O3FWz-(h^k>achX;E;~=3 z()O&mhtuK(Dl<cSNEmgVwbrpBzJg48yA}iPh?*Mt*0>EMhoM(h9jYeA1;!+;4B-r# zI^sQ_-Z-lhPhu}6_XX&&d<nvL$30J=tu9;|LG7^oLCk+*$>&9us8K~yY06(RJ}AZp zS-a^=IosimJEH@~=}WS*0*?z%TMiTxiJ}p2mP2{a^fBVfg3?}uC?$x4#0*Sm^CpJU z5E;R+YO_`|CQl@*r3BHlXU3DslO*LGqlcpnv$}E_FZwu7xjw8%hDKt4`}vZ1kO*-3 zM<|m=y|L5T3NF9FP2{suSZzb`FEgXPlv2Aw2w7wEZQHFFiuT@Dkm+Z{1aKnu(#?}E zJWrC%e}xr6lvvEo(CqxjyERINnZ`4|;?&ZUG1Rk2w<f&Ef{68Wp>@f<u9X$3w@h~s zgG>WAH?2w$3Zu1bo16%7TLVEoUST}lMw}njx{qInS|q5tjC%v_)FD{6Fe-LjWu})x zT=;-8MNJqYzznTRs_lnu(g0&G+{_Yu9#pF4gvgUn8r}PVWmayi>}N(7eKf9}6<l6S z(G*+;wv<?m>0Squf<IL(#s7lv*&6C|q$ac$VlnVKFW3GD+_&nP=JIGa@gMuwZdcoS z-i&$?DIaKDI$B{iC%3TQpHK>GrSU<B9Scz=m+<z4sj<_YnS;@unyOKXf}9DTEI1~b zZwZNmhjy5z2yY<d1=E`wFJo-=h`x?>oR?d2|AeJR?)ut;&+aM_6!=etcU$^jWr*Jq zL;bLH);>I|aDQQH#%}o)rZ!B|Mfiuky;ooTg`4&U#pW-|p=oTBrU)_y@-3?*jiC!( z7t(kdxo*7Yye#6{ZIr3je~SZBNI4bjktC@)Ne2tfNFn<vm<N5oE=5FWaE9JU_^Q>Z zr-ayn3=GC6H`lVNqpD>?wz*L*f}@_AthKzh3jY;%QiXk*cz2nhzqwAHri}Bz=pYl0 z633LA&c_o;G3x&D6H5`VZcKAANA1@1{MrGKMUyW8pPYBph@eO>HLi4V+RUU*Lq~(K z6MHr*johq*V^X3k3__$3=_^W&HQr&1HVnr-uE~(%`$ID?5m*5Dr-wMe%FT<YiC2I< zakHv$Z<40w<Oma%yQR`nra0DH-NNco?O7()8?NEGgXU+)kao3jW-GYbHM8nZVUiod z!0h|ZYJuW_!DB;cObK4vhZJdsH^-kCvjDPu_@VO$%hfRTC~*2uQFXIrVwg%~;Sb;i zkkE#Z%c;?Q{d<#wv8!?Fm6KrVLDG;D0C5c`YL}wAE2>a?q%dzk2Du}{@i=;b|J^x( z=`I+{oEm<B$TbLAD?&)z=NK%|j|Zlpd)()P8Jf%zPgbZ@1_hIJc&2ntt+}hB3hO1p zmr~yn=SeF)P;Q))0`2(Uy3msbGE1+${w~aD-H@S_W&d-`T*_XsHN8li#Z#Lr>Ocmh zQY0Iblv)#}#6ek0f;>K_DZcr0tu}-|9u;Rc=P@C_bPQvLM9=VtDw^NdGWS(h&JV9+ ztbR=CEV1r<n>0r7FKrPAgUM+8YmS#nu7mv3GWLu=WLb7FG2b4-8{aC>t?TJQTA%f= zmcFfn)8lI7%=YoLqc#Yc6E7oyc;}(&qO9|9D&Kk3C|yw$;S8gmY7mDpOo+_Nb?nW2 z))+6(Rd<8EF>~##ELY}3Z8ftwr>=Em>lIom)e!1>*EscH3NF7Cu(`mo>L13Nqv*Lw zXeqyujcDmS9P$mZ#6c{PO5@Okwz$bg7}EMb6r0DN1j3^G$KVACYwnPmvAge(^u-Mp z^j|c1glSYa1j$3wu=E1a*%2PJ0?`8p$6$*8i>4ba2!vT=QbrfEt1{x_)$*#)TD0L@ zYNkj4mBU|l$B-2iQ=P^V5$gJf!Wh<7yXz1nxKv8L;4OVNj>F*nBkD`7X@B)XX6F?c zGNMk5r_YWm^*gv1dUH`(;~2b6p{os_AH@C{U3rQx^f|9P0tycZRO|;j?*jp^8)tl9 zz_Z@Fjx($`AQe1t59G&y_y;Qj2yy5i`1bz{0htm0+oUP7z8Tx~ju462|0sMw(2u@= zpEeO765YS}p)cTzkr)U!{{Iz{1$_OQ@(cVhDEPsu08-&R8$<!H+5vhwY}9>5e;D@P z9|s<5yCBGcFk#04$}b?3r|cW>ED!kAB=-e;hxh?T4g!&q%W;A)!~XN}x%C(5{U=bo z?RmUc__;sw2HxK*-0;0<21u+}V66j>yaC^DyPW^}Q1+yGKSk~SYe^98eexWC2i*W; zZ-6jKJYXQ5SwYil=e0nxQlV4c1MI-~+wZ%hd>;b9QcpbTm$}E|2dSnZ3LTR{Lw`Q2 zi$U<yJ1O`)U}amI51p%zzaB5kAC?Lre`Db1bIZwg1}NZ$C*7CJ7~LZuxU*0BHXs6m z+W{gZ6@ActzOtgeRYa2x{G0z8F+bSsjAm=%Rr?*O{`dEG8}LUHs6r0u58HS89Dlo` z_V7#qH!u;D<p24p7+|*F_VnrTdX)baoYMH}Hx~*Z#(9^i#%%VCr?_Z4|Mm5;j6w>I zsOHD84;*{#m9qi&S;}81{-LUabH6Blz<p%p=jes%qb>?PB;$wP=fOtbr=%kV&HEb> z5P$1y;J2K=9ck$?_+KBGNmlp=K$M(!_t<{U(hnBBA=U|3oX+$odl(eHtP3TMXr8&j zjDk`-7+zMHt37}m1!>Y<Q<l9XRaw==!Vf>tc@LVj;pXcN#2F0{r9XQE1au~6C>-i8 z7mL7fCj{kZRii^f7;%pjuG+n%L73(x-*z0>`r#GXK?M=iof>5><0GhJLo}cM8LKLW zhXSUFp8q`dwe#F0QopA-w6E`y6?O@={LxprTDZ{$=zTrFu~>nH!k=fkLqTG{2?Zzb z&FkVr^AoZKs%kOZiu%zBD~7Z}k%v&&9iQ*Av1+~ktQJQp%&*zG1lfcXXzhp5MAT7- z3Ra;73KpM*Z*DrM#o!3Rq{q8L4~**rFcYCAqC_pH{)iwyWj%nUp~O0X``SX_&+n~T z2CD}Snm`>7wOzAcfGMwe^n4)IW@i?PKW@a!Iozxy|IY9sgHuxe!h*)5@bKf8NFU&W z;v_-e+^2j?1o6}`{7;`VUxlHvk38~2<$?3=ms0BxW9ra<m)me5h%TbgY>QjQU|ErJ z1%19-A)`9u9>Vi_JL&b!iL0XXTWvyj-RTb&VEN^JR6)5&q-PU@NnlhwYXSx4fftpB zUEO@!YF^b@A_$T_G;(m(74m303h^HZNfdo4t9B)-QTca&LxJIfud}|;atg2`j47DW zeSA^)GP!I~m=XMHKlY6zz$P)z<OZ*=BjWQDHDun~()I*T*Ndb5nOHD`bPW#ST*lun zJUxEM697YrVO|DFJ$*-rO!GC5+?rK?IMAi7>4aNe8F@7AI(tIqs_hN{Y>BRnAQW0% z9UiuW_X9ZQ7$VzSOxEh~;p>&jQ0^x(b<XG`l83pnc=)TAe9apTu0E0Ii|&F->^BF% zVYQu;=31v#0C|t?Ck>rsOfZ88lj-Na=e7|_ihir&%qP1!Dt=rvEdK>axRkmU2LP0Y zSZVsc1@QXrpqwK-bz~z8=l#=H-RK$+!QJn~5LlBo*76d?(Ra?T$2N0db09drfdjJq z*XKZu-B0Jh4LQ?`FsWP9os<QCPl123k^Qk9Z^;4`kC>`Pq<*BSZTDco72N@fX+T%K z0#Q&c%lWXKZDarxjt?RyU>-}2eFDNn@Z$mYiP$~PqruGi%4A=*mpHgTfJOU9nTN%% z-G|*TW$)kXWDb)f{Mj~mq1m6r+uaDkTP_y7Q$n9NR>;*d^+$T8>x+ymgi@uxU&q-N z=B@ZaFC2?LO!b|4a1+&x!A$y$Bak;?EBj1QZCL$x+U^Wq>Ggaub=`d6;u^NScbtYe zFCw-MQxv?5+3fXAslU=+f$DuXgv}%?f#dhQOaHwWYFpplyQkK62JGF*PoRZf`#KSh ziacIkC5t`gsj3LXt!;Y<>TkI(AvPeG=g>v8j%*FJqE1~S(Fw^EZ$=EPm8|KceNE6{ z*=>O*aj|?VkvI^!VbOExAk|q9DTGSE(7UQ*Nm}o;3`kC#0x360ZY$znX3p8LxX`%w zE?sGfHCQmsfpQprhUA94kn9OwF5s6+Rk`pFE_uddp?QSmZdk|7^k);n+1hV&AIt}U zIl${*EZn!bvwXdMKtA1<#SXZ?ek{}{{>fJ*luw#xVtkSHM>gsAlKW>WwyQBu$CG?w z%E{ANs>%SEU0hPn#SR+-QdM_VmdA`m9xmV!9WRGIKu*gza9x*}11n-iB49lRiFBgS zM-gMGtH<<1ALly4<%1+5`r^ANO59P6B7!98NjhI~n&L-MjVi7cEkRL>yN9>JSd*;Z zZs7WWE^ZX&Ya80nJ4xO9J~=Q$SLQ$j9s*il^``3jVkfu+JTRstedX!Kji-m#%Q9hn zz)!zmIlmW54+HM^F`1DJ;Sh8P5}_P`&O;djIi`!09;xhB%!Ik0z3rbe23tT0r_B(j z&EZct3F~k_i+;&xgFZlXylBS#x1B(y;b{5+zj-A#`JI_K6T#=<f4gRQE(<AX_MH$Z zmXp`V7k+%Fxz~`;O8y3#B>T?c%pugcicZ1GP(?CtZ-Qjpn?iwQvd8C6OjU%eKS)rF zUv(zIKk_*#9)ZA5@_nG;Xd2W`0bquouAYu~|1^+V9Q0HO3fI9*b%jaCp%$adxFLR# zgjP)q9s~*G>#b3%4rEG4O2UyR4#|*Gz3ffu=#dM<53*eT_NHv>o~};+>c%nno*W~f z_XhmJbH7Umra~zg;^PK<!QE~UpQ-D@-reYfcrT6}3-_*5yi&baoACsBoqI;(iZW#0 zm64*sG!3DJ_`gy-rwJ5Ctu&J39QNAj*x*VNEf-=!q#8TCNCHX*7rT@Uw)hRT67RcM zaBNj&Eri3fZEzyW*Tei?xU2rBAq8w{yAKlk9QVOvbb{osNrvBcA47UJ^cR8?_dfH{ zh!p|eOP@9W5#l0qX8o8es515UuMR)4FrJR|=*cwdTj5kBuJ2+R+63>|V%A@Cc@M9* z<RnureOeLyJuZ+b2J>#kLV8J*AWF6N=`uIU>6IW_qXPJzpR?MWt|y<O#Yv-G<o8}7 zbcRRsbQw=vLG1pG9LnxUs>g6PpXh<_`8QH3m!x<(-;eCo=vbB(J-IItyW3EZ7dx@x zrjZw|tjUI~jYZ(^GC~C1Rw-WgKTdGcj$4AUdaZ3%9^Pj#V*vw4W%uOud348X5H4it z-SKInhXsQth>ruf_-6tHWPZu*6Qh<p^z+(q&8tT9+8lUA9o$Cv8f7~Rf0X>^O>)b< z9Vh(M;j*5KwkdyD#|$Sz#q<bqGhJ=H4744?N6l-8SW?7>zWxh!r(?}aYxDzY)DEZ- zK=|^P0^aZU<$Vq|&H1$k0=?`8fUl+peVXa+_XbxucF-v>aFYrMkTnWEuS$FcdaUgP zqhhGnV-;yaOO5b2?&^hl4XWQPzt1*GM@hj*)~TV?Pv#j~^~lBt8Arnk_39X_OqaFe za#*$ewrIA;h*YAKbOq_P4qB1P&S;F9;V;FzJ`KaSMyfnCKNU703zjM;nDUm*sC;Hq zawCj+87|4;^Mb#~<-!owb@S``w&SvrArN7*SQV)}i}3PN!lo{@@Z*aLl8p{iejSm( zx~d^b+z}ipS*Zmr7B4cy$))F==Bp}Dt)Oy3q+YdG9juAe(lTel5${o9j=K|@#binU zqc5HE!C<Qtk?7CLTo^}zn@)LR(wE5!Hsqu~45GtIraqFB)%1d*9`eCJt56aX_F~&g zT2NxX8#mLmifP9;eZQ$h*liEK&#`1Iej$KnBAqgfhqTL{LI~GAy$|nubQ2(%36o;U z>)uWzkWp;kCRq2sVH;KQR9n9tHa=QXT#Yp{>w0-6>ybEUH>4*j114U<<kFdobzO2f zQYgM2jCJD=$LUWBSr6Q)iS`?zE<<XjBHlK@ugJ6z511Chxgwcb&_dr;F9aFeME~Hu zCR>tEa*d?Ba?l#h7i5Gd4PhHdy__57{`$LVa3Zj<NDF>xPpo<o`?SDNT-yfDZ|)c} zMPs`9CEfVIp>xSN)@EXbOoU6*$&z`u21$VixltkQcIO%p1`-eI@35^V1qd5pTh+6? za=55;f>BtX5d>2>ks3@<D2{WY&mH)e4G}K7mVogw5s|dw^CzA-<h7CR70Dz_#t_2` z&5}GhOA~h4+0yTU^)*>2ci~m;NXUsi;0nA7$qF=(4gVl}1`@_E{kI?h{^lPNP-pd) z>cL<qhky75E*DL_I?#$Mf>^7BZrUhsP)Ax4S2uy7X^LsoSOB&(vI@fr6mG5}4%^fN zTGbYfXG@sB^S>oR7+D#{dpa3{pD)zkTH^d3{y2S#TGG*cxX6mg7I=1-R23&q&N!gX zN0tf1t2V+>{T$=S_>trs%qY$jNo`}O$DlFIs;wyfuXYQf+p{XnA*Gemo---n<#g4* z(MRMohaIMP;-t}k67`cAID`iDwZI@o*&FlVquLpl2_0ByO;T5baC)iJf9vx;KP{Ci z4YcW`_4ZU7*JPDPvFLn!IFMWLCEn@TATtMAxjYh*XR>IMOyuB&kUOUZk`F0>o51^1 zVsmo|({8Ex;S9sp(J<|-*b@e)CapSJVU(mfjjq@Qs);hZ>c{b_mU2;TL0pJOz*_#N z&1=!78s$j988Dyj+!-eW5t8=vI`sltfC(evfN7j_>j?)H$zk){ppomA@@$qVq7t-Z zAykt}T!5x&6e1Yig1?ZvZ{te!S-MrCNU!Zl#ybaM+XudMZp>17+!ew|IpBN=a&9Uf z7m_e<Ep1f)bPY}i)4d3H;TDU084~9`L?lc*+E`gWk4#M2KrU~1Y5u70;+64Kh#E1H z!f8wGm{R_pfrZVK-}HSf3)j7^U_Fq^xj5M11c+ohNip3%X-1&^;F4}tf|AwJWj8!Y znOE44Mb!Lk6*~Fo#85^o`p*|PF}1q0aBCeT(k3-q*<n76$3yh)v3I?&xae1{P>f@j zJ(P}|VqleGIFq2OgrC$7j9Lz%w6tHQcpwQ%0j1S4YuQp&smp>QpInp*=s&8FYMjF> z@z{ww70oDJHOh;*DS^F~xs*#5I`!i72h7(4Z7cYD1YUnSpOON`<J2FA*X2X0;u}Vh ztMl4u-+BI;8mV9BdGS5rlxfAyq>(HrObhN;C{#Ig4E`&UQxFV$11IrZfoa8Vs=caC z^A?~osrVNnOsn(IV4wfQhcTE=u?rHJAbWj*i+wOx6Z7&hc^%(>MbGXC*vXqzf<0<0 zMXep`JLiXMJasLN3+$^~62(1ce$_`ow!=1wtuOcItqGm*`o*PH1S&rGWcW$<JD<pM z(7i|{#=z{x&qB@X(EnwT)V@9s&@zZ0PnID>(lX3n3yKjr-l4SHZ9h~UejL}HS{tN^ zX3-rZx%*0wYLky$^ifQr?07<ly<|N>{q@RpH~+Mn#WTgIG7e+!uxT6VfITp%)gS%u z6?RoiRal@!1Vi$&R;ki#MYggO5HaD$hf_&NtBGWadFjfsgOC=$K)wxnc^hm#VVqY? zNeAwLANV%~;dms#_7zkOZPCAenJIGoC~y&1?hQ+xZd({(`5ZOQ8?lwx5H7r8zzM1m zRUCHe)bo%jkB7g%&)^a1s8{tZvqm~Is{kYz65JXVo81GRncl61n^d_C6hgxKThtx7 z!*U<tWd=`Kt(ys1eT|W3#pV~`T46;3_KkXBy5>kogBcW9Lf>LJwQNXFz`_jdkIQJZ zZod|U*n%8K9T`iiP!CP2h@~%`UU2$6yAC+1)FznJ?0wDgdX&Dlj0h$rmK1K>3~_nV zGVhUcl`0E2hY*nmBgJE<)AEMXb}pt<%AcvribP7hb~;n(8N1=k251Yc+_cJAO*Bpt ze6vF;h(TE&Dh>#HYEuXtVV?J>T%Q5ym(n!|A^jtvUl1;!(soj_UUA%kBXGO)Fi$rT z=(_a?c9NTPCd>K1E|j20YVL5FQM&Hyt58T)PL}k<|LAeCEx1XAFr6Id-5Bc^;1YY0 z9vvI}k;P6|*}Pdm3KoK~_xb9Kak|Yg>wk0CS3F>8KrMWYgu<;6FX+K!Mq)=aUC5Hk zVugH899^u4QwVXvWo%E9#=R=}qgIusj;A+iOlw=S_;($@{l8}y*3+FXo0z4p|9Gll zd#&EyYfI&L^(`fYKi*e1!xH&hvu_&jPi?1OcJ_&`>iF-dQs{JO(L|X)sxG1)W0;af zK{k^<T1uZLC~E2mc-)}tH(bT99QDjD#e@eKD@VBrZq#PO@N=zGJNDJ{$Q~l(5Om)^ zM@NuiGxb0(s)9zVz<=Lg+E7r7&fl`GRI?a@gQIlEo^Sul<Qx|P$4n5Nn6yP}=(cYB z$fkF&*A?Rwx`lQ(Dy}C-%OLO_V4(bc#9}9D$3*<3&EQ*G^Oum7kM_C^p;?t-H$1Lj zFftd3Z1y053RhN5cWS?qt8@j)%tZPZ!jpFPGC>`>9x6*eY)!b?ifA+JsnLj=aH4~{ zyCf#Ne5US*`XOGTh7XP&2o8;eD%n#Mr~Eal`uWO-B{VH_^l#Zdgr(qCgxEzxtRe57 zYH}IJWp(=!zCk>uoMxyDmcO}x=~RRO`lDN*qvK&Xliai5sstHjEVb*vJaL0F=_$I^ zIGNIN_grs@3@R>yiz~~^fZ<<+^lj;ywiKrj0)BM48zd?m(mN{|1B6p(b{T7=wsM#- zQEMXG>8x557mrF`xvAlNO9eL*%kg1S`FzS^t4s)tDvE!c1At}oc1)O#+{bf8*uN?D zy9wfJ%HKE0m!>+@6mXF#$v|lq2~r_!bX;I0H_|1tzKiA15a+d;5W=GM^~Y)S^Vmc% z){5dCk4h2tBcM9YVI$GuQqK)RiZcdZD(t$BuUn9IgyUUO)dw;ADYxr^PyONf0}Yt+ zY>&88L4BF`c{qRv_|0v5{PC{7mmhK3iX37s{AU?8=H9%3u&p>|o_#}q*(@kTiG?TL zhcwZM>Q-mo(Jc{t%2J6-q&2J-EnjGR-nM{=^bVu%08yn8T8r85IruyBdw53b(rbIc z857d&hBrHqbA5Q|n)pC`_ox-_<CA-A2U$Q^^8f->xaRbCrCz+aY9U>zQjH9!wPN}{ zNbKn-FD?^kG*9si3M#+FL^6{&xRG{JS9nd`b!QbaN-V*lwm0k+k1ON?24gXa+-62U zVJ$yW&(NRhs5^DIG_I+Hq#dt-D$;3>O&BE)Y)yeS=WR2Z3W*(pA5|P<VG;)A<kFWv z_PYzPqw+y%gMs9vD*_T2B9SNbwAfm1MI(PHBT{w~*oR0D(0$fWr0-EJm}$YBK-LT7 zI6P<--Aj|vUBKcPH$#{SYiT5g%$`uDbkG`UY+ack8;il6)P=Vc4#sD*i*d^{(AKs3 z+xz)7cRz5}Xu9!t-CaomGABxff^&H=@BdB^waZoqck>I(#UcaHCt`b%7t6_oNxN85 z*9{Sef1?hYuPu);FLGnSW8gQ{0<^e?%kf1>5Xq({2!%L(_C&KL?i%yJm<96@jOj`@ z+%ZpeQ-_nG%V;Z-)_JU{F>WK0n0}!|AjTs0ONO|bfC?A(b6*=Gc7iHcd3PgY_ZGHJ z%!+qA|E^Km6-x6ck!FajirPLAzzcOtw~fZ6(0ZPL_Xwp$5kb9<<uqx-``)I%x+*UV ztFIL9QO1lxfBOSI5n7?*G4Crq&AP2QFDTSVrvy4+sQhMBN(rddK!?bdRpO(3%Y+39 zhL54r?80zMpjVo^Dj**HX}Wh-nuAV;OpM2ck!@)D!iMphn6gYrHtBg6ZCB|1H73b% z@ExZc<PLSLdFCqbwfmi6@`hGBb=;b8q;ZHM3vVfSCVF%tDNb;<c#Bbq<et`0f#RR) zyofZYW$<Y;{XuKLCM}2&Xko}*b5yt!@Ktd}+7<|{6VWFv%rRH&L=E8-dgY>hRDauq zv4HXfAFYrn4bd>j&$Vk?6IK+d%;+|f!GYIN0)>Be>hTo+X!}E%#`|X6OQ2I{7<5r` z9k|Bny5F*!m9~CtHuYZOim_X5PW|vu({D@IVZ!8QU8n1zlgAPP|I9S@J*UXda$NFa z$^l*@d5fSGM%F`RKBO-c%7qXPV?#SdspIdztekfJZ{i&q6<J-(A_xvb=n-g}N0GP% zoZDXqM3Q3noQ#j^fajT4%6tj!hK%V?XC(8p+{K7Ci9GqIxYU+d+>6>oL4=N;0}bXa z0=L`*s468D`w&gSN{3&jN7I%f+)M2>d&>QV2kaOw4(qnmQ>?lKA<_of#d3N7Ew&iq z2B}`(7W1uE3;3uZ;8Cg-*L>cItgppJ$AT;tYAhE-c1S${%B}pi1|K}VW6BCv>NVOo z2$*sDGd4HeUmB<*%Zs{_UEvCQ`Ft;&FnI@4MeTm9Vuj29R;H+yc9XUiW5H>f?=zEo z5gnKj`;tJx-G%X4v;X}$mst`n)A*9BP2vP6eJHBk60Wjw!C;>ffhx8At{|k?1Km=9 zZxk{l_0MJ!3)Vqg+f`su0iz+FEI!OQq7qx`r;XFase~c)cqvmDz8BsQ2+K(tB@gT& z6I!ToC{1a0+l9Q0z}nN(#7Tm196}oaD)LkQgwF{edB#5a=jq%5`0Red`}!wffq<?3 zpbAi3<N`xV$25Q&WyA%qq2bpIjZ#%_!N+j`VZamTc`FpIkNnQ+yM7$B%=~r5m5t>b z`9ewF56`AhWli=>F@;|Ug+~fGEvgSBa&>#%G7di^!RPz(1-yIqYznHBVwM~h;8#@? z{`7rGYEPg_|8N9vB^r|tSo1c8o$CdBZ+D)cPuh8jlI5~V;U4QVp8!O6DW}$noP4OW zLhPKY6Rktwh>&PL>`xG*@|S>KBKA9JBuZz=ub_Hl^Ankrx6(cburFY~qi)Qo)C*_5 z-^*8VWJ;@dPAC?NSllBaOS1LHEr<T`lHcDXSdl4;DEdFpQ0kCi@ZQph{@BT#7Zi@o zEUl9xO>riTHls6H68v5ha3A@8zXq?9@I|d@UyNbLPqRR)(2Wz4eFOZmg$CamByfNF z#MkhytjqJXo9yDzSL**)yxvGj7;{Bs74%kZrt5qKua3cxwg3wkOK?F~Ay*^iY|p4* z6jqgrXuULROIY|>64VzSYlPJe2q=t#83m<$1N#g8;;I=55p!(_%?lZT`Ns<~hwU9D zKHO<&6{}pBe^{l^kUXgf${6-l^5rt;IZF`xZN#G+0d@Ek>b4~<OS2S|c|Th^I*M`@ z+U>A4vR`xbz$<Z!rJCJM=LD*_P3`nAS*a@D%ZQQkRR60_f)r6qC*RG6N@S{YM!RKq zSUAQQSCTX&vBCb?XcvA-NUke?Q{$=%P9~j6V%Jeh?yy71Lu?7BY=U9hnsqzq2!FY8 z5xwp^WE7=VsLGIQ&HRa+8F+45q+RUjf+k)O^@6%IBI2RrLuM=TDLAB^kYDLgI1`jI zkrEq=UP-fGjlKg|EaRl-`N&n(ak#T0CViyc^i9b)l=UfN+@x2xgjwa>5=yEJVlcM3 zi2mp?vxA9)yYakOoR9pfnpM0zcy|@)WU1ktEzp6^Y<H@e&x0w=E<see=4;HWq%~v_ zmNNmfg)b^AN)F}M46Oak`tl~`iY*9gGT<zLC*bOBg;li1A!6|jUYCbV#gM7%StONn zPQd*WT{bC&{{cPGGl}dyl7S&7++6`nMi$qO?(gx4=GC`oNI<U-(^wueJL&wqnGo`V z6MxLRcbn+FF|i>=lXuJu{V}Y?*qu}6iPl)U-qiDeS!}_U+F|ps8Cc5k_M~?WR4#?@ z7K78x8Fatx%rl~rjzKJws#_8f2ZwuI5<OKDf@4Q<apSpgsc4&;svS-_c+>QUC$YJE zvQs^z6HY{H^61GOtG?89kR!t*=2_pyeK(e4P%7y1Zcu?HcZ3!qkB`+AEi>r+UVos2 z<5;A_JvTS^H|s%Co+TlyMF~nrU$DfWr<pcV$QF4$6zke4!P&sYNil`|njW4iiLWf~ zSlp$sCsW#*as^Db=co-k@}|x??Jiiq(>j@eRKwbuyqHJ#ihi#tss8|V)T`)G4EGcr zY}j9cqN9@>MZNAsL~l+_EEhpde3k}Sr!!feQ@Yt)YW-e^xXNlHm%9koh4u$p^w{bJ zifj}7&#E$_`0D7?#&x*Z;5+?<H}j^XVf8%!ZGw?b`6zNQIX?5q9~hoz`Q1NMQEIHV zO|){ccUbZQcy;Q2EPH=EI|Ml5zqgfn-UeDT4!pR#HFZ#N3`Gv8CKuF4a#-~O+f;{U zB|U}-dCW0Ybu>wY#+6C!9A<pC34JCug<++*m<PCZTn=nJos$(fj{e@=>rD5w;ky7_ z-%H1r3^YU(?-7r^MHD6Uj0OWQPtObMj?G7URwudTFL=CEAF1P62G<kP*$_uYcTxF~ z%WuZHTpa$=!xv#L{1@*}n|L_~KCYjSGM1%4c`lxIWmY0Mqn!FYhk+h{VK|_rRB(l2 zr$9xin9O(T3Hh;Gkd~;3#7XQD#7pT7?M^4kLKqEel3QHm*7q09ak4P)giFtx$)%AN z-y#$6RWTm+^M?!KK9U#0F^*blUfhgOo==Gs_8EDMs5ML>t6*aPAl#a$7R4ZQz5r57 zi7igBxlvnQ)|4OPJ2z)*F&uBmbI31`dUp$qKjfJmZG@)YT+D1RC!h@_KKY!@&P{NY zcp_SM#I#jR=Rq~7yevMjqXN9+q5NoH;>q+5X>CJ3$2_-*FM~|+5fUan#;Yx@SG<BU zo%KJQ1-~y7*vTbLo}z_=Ma(`)2zrg&NQ00yGFUgbSzo7Pp+yXP==2t;S|sP35&~Cf z02GETY=q4){%JU`^}`6h%YRNQA|UWi^sX;BoZZND1LUXqXJrIHzDXU|Jkf@-F%xA7 zown?rV44|0M}@NPQ!7OURn?<ZE?Qhlw!({J=RbVJL`K``n_7gGcK4jQ{^G({Z_F4~ zH|7PQhV;oVbmaqJ3gh_!V{)Q0Z#6P+%kh_AlfV3(rCURiGqMUfLF4Q3w1ok5l&s*U zj5Id80%Sw*5MzYWyTwE%k!wj#%HnMBCZOs;rFC3c7Ff#k6OJ4k8jR(CM|iPG(iHdO zZPDnzDYp2%kY$;ekObyvwos!YTwsoVtID7s`c5x#)?+b2|4MZ#!>Lsd=!^$#HXK+) zsSd+yw5cB)F1;gob7UfUlgi?TF>g`h!F$i{Il%08lHeu(cNa5acyYpSDWZz?B=h{e z6=pJyJ_?Je322n108}+pBZzVw7l;x=%0*)oj!cqg{>0Zni!%t@CDL)b6Go4OXhz8o z4dpuK$2~fYclm)ehIole&kYM2CGA_y;WJ47%2~iESxI7*NKm)<nZB!u+ui`t(%Z-_ z)THOWp{cv7UYL=-79nI8h}J-!$1Vrjbu(uY4CUgTN!r}0&V^pPKuGNfb6<<$=^^7> z^m#s-YUQrDw${+7uCDq?aG6e^%QvD$s0+XInCf}Z5tJ$>mP4w#>{b%gro^CnOH6m< zqs%;MbVuK7bVo8<{6?z?Jif+R27Qe;Rn?rsrhLCI&gM`|#`9KQcD*pNZ6Mf3*%v$L zildD=Mhh{iEd%c2tTaENenCzaa{9tfpybh}=RIXmq5)ZV{k{17s7VBO?g9Cq+mCYs zw<AD4;5JroLj=&XXx6{<U;+Nq)8VWZ%3Z+6;mjN9<}0nv|D}=#)@{|Q4C%%PIFJkU zbvQ%p$>Y3G`#v1VMS6PHJ<F+D^am7UFzTKS<kkb)9~r*h7lL{FydBOoRFAsuBF_&E zh_>Gmo7bR^mDXwl`C^BY0r;-FjjRgdwi7zwn7+nf(S#Ne^W~)N|3>H{uNNSXyl16w z6@VW5RJ1~-xD{xB#FHWInHrRsq8s=49>~pC;g$!<d}@jqUYJ|Cya!o%H=ungqkZD1 zDL&;dcByl6&Xc?>o#shyrneV&SPJH?Pvr8C)<0NV+49J*6S4zp_tkV=p7aP2oqj%r z?v{V_@h?x5Q(kciDN^yYWl1D^(MUup6=^&=dl}T^-o1UGAZ!@i%lKxqc)US`@t^pC zpZNWb)nyon{^(l_pC|kNmIP3wzHuvr-O+j8J^RO01QRJO`nTjsZpuE*k|WHHw8=_z zzRwGl<zfKUtPnpykZ_vB<o2fm^FQX;7H=<6Y;7c*8YQY^e$)X+aWwa~m0dpHM5k~! z*1p&4iS#kkmTwlFhwsmfF5g*MvG$c`?*W(oroC^$ynFvPDx7vM1uiVAGW`xWwZle= zmsQ(OcII2X?@^3+1I>lhdLMep+?eY)ruTJ=d}VLH@Fy*au)dPJpiJxPzVsl*p+@Up zovobfTPL8aD~_ae%wI3w+w9ZVw6wdhZm;OceaFf<9ri0OpXv>JuNclMTl5E{{0U8< z(e!a^wWXBqjl|jIWc(=3ZTE0?MM1Fg&i+YecV2~sICdMGFUpeJ)ZdL462)m*ee>`` zTV4%;;&Z@PI%hK}8E_fjBYNAf=E`j#Tae94Mm>-4Q|$iCTPoz6u8$2^-&$lnAV}WS z8%RId<*s_EC9;uJ^Oq_f@nfx7nAkYXtB_WC_LlDX3<Z>QA!%QaujJ;i#st|3A91N) zDG4;>K?-~`W)~)}R(-U#WU%|k7<_xVtzYgbDWBFYBKq0&5$iIvzT4iNB)hQDee=<W z0hFyTZkw%5fgfvn6w4@4*Wr_w;EbeABGuf#6U@h$n+o-J|NZmkMxHV`;d?v&M9jw- zxS#9CJ5*d(t=B<m^Gs5R$m#dCn%_Gj7V|slaTclRY2Vj8o!8^=o?q=5QG7|PCLC+w zYOcr;*TDF(TaDlO(ab^7gqn%j;E>q64mh+{BJ`boh?-^(nU*(Nb5D%H4Xc?y&D9vZ zyVkOLo?T>7Z+FZtJu7n|Y6ONXZ{CI7UT_US@5#p&j>LCEL$nG9re?m7)wWcna6Y*h zUHx>`X$1IM_B~NbOAs?h*5!9h^~dX)p{v!8w_tggSt?1nqBm|`?p?L;Ti39?+``Ai z&q|)E-F6#7o)@#LQmV}|YqL(RUrU-l&bn<*awV=jar+f69~)F=-s$kJZtj?P?s$>x zHA!<I1+e<z=qR;qJ!D%#I&!)OOGa*Trl6XBR+zgSN?5ji`|QOQlD4yw74_O*Rm(Gm z#|C1C$Nb?invV@#(eoZenfVB_pqfj*U5Ek-bmiIx-)Qu<+U6?PFzkRut(3xqxlx^N zO>$PJ@*kNT-oAKW)*6{)9L1ifk@ai$AaT6@MB;rhQ1sOK>Ln(r*k6^P!8NLXyy`r- ze%!C3iw+=L(An+HdTuiZM?AHlZOiuf8&ulge%{VS8<zbh>;pdT&vK?jh(=DJz0gm- zVNrCZ4x7MK$<wqRzw3G3_r1A{{Ik8k*iQZU_p#1zxPAOYKbZI0^0NG0Ndio+tzey` z{#|<@%aF93e9tW%{7T51%xa7M@8X8`Ojl~&a#jFK%b@Fwv_6{^W=lb!%&z(Ql0Q+) zf`BU-&=Bt=&eBroI=vPvzXd&Hr$g4<yYTYVDt4E6Lg<dLn#|*|fjHf2#}jX=-t=j3 z0jyt;QDj`<E-kDr08-T9*Cvq-?kV3yyRX1~=4MfdcXl}*r<l~gkK%ZT>_5b<;>O!S z<u4f?o~{1lO~yV^tAL$^=X{j4G>sa+So~ydp-$wDCvLX_S6fGpTKV=CmL4%&gm<m1 zfwPYdP-Oc%3-=~j4DL@1{e4xDlYQ5|NB^j`6GW}0{v;hQf%Zfh!8K=FLF#>U*Z}(* ze6e-AwvFL0k07)_G)XNCf{U|Ryv2IIK)*$za0|7y#O>YpEwlZM8<u|PdE=pOF~B9g zj4^Q3!-Rh^K!oF-;Mx+d!}ObV$n*Y50pUzFJ0}2g9;hAX`3xbnH6k3_a<47OuHFs) zlI6wA9Wmp%AD9D~E|g7B*7k()QWUyjSogt-wSlQ2_c?H!ruoy~`@#kfq-r;XvnFU0 zyT%*!6oeLW1~ATn-uinZ9eND5%njif?(jYmS>Z$I=tz4U7FzhICk4mBQvmQELKHug zJW$TBuVC(5+YT_5Ab(wuRI|90d63nfDBg>2!efS|(S-*I;i2<E8^Ad+Qx}q^hRUl$ z_Wgzf1TT8|i4n4@zxx-5&2(9d=-jS!e4-GHrM8)QQl+ZA0#s!F=pRixz3Z(V+07YJ zsP>>u>A5gQ?-Nz+OmEoEs4JWn)L2$q#|sx@RCM1~uxr*$6kc4R>Un&Y*Etz_{^f^_ z@vM4BGbhZ0Z;`#P29_x|;{Vpzigpy}Se5r<os-@_WFKV1k1gJu+W+&{PB^%C2)Axm zrRVe#tTV%puT)<%hX~g7d5-P1M$JSYGGX-o%1-$F>shLJ_<%<6Z~Swbc9q{r#kmB4 zLC=bg$l7wYki;f82q;=17S|ZtyiaU(L~Nx3!>c95^E95Y&Bve>xwVsR&DV>vZpX#l zm?W-!{*U5pL<y9%F{c7bh6i3-UfZ+v4{p-A?kfILiOlwDZaUrxLFSh72A{8IYxqK# z`t9~gN3>h`h*Wtp|NdYn{EIU>-3>bk!?Vac61-Z}QyA+p=bquzOlL#16=N#G^(I)N z+k33z6?ClkHLID<dSnUg5bxiKCAr7OXH6~lMjJ2V=7DwZ{f-`+iDDYQddmEq_&x3V zl~c;N=N7qXUC{P6;oaJC^6QAl?5D8hJ0UI$;Iu>aQQ`SnzON<rS;Qq{_7>xs)D5jW z;ZRMWS_PBGSWa{t(Gu@A?Mv<ZqV#&*LFKdk9ogbaDzQV<1QDMh>2-@JB4;Z04K73- zcN_n@VOx6nJ-%YUqF))^Hjhkw^1)B}ozO9mqnp%uG;zhYJDWttXdJfSJnjk3LuuiA zUC(?~y*#dT>FSL0zf%3A=6c%w>QwX!B?LT%ea~p+YC4qBcMd6JZ<!kQTge*nT2D!| zWD0Ygo$dL`2lRyakAfy6JX!b1_+^Sx+U2Z)o<|Hn!WT%!?BBc#w3*MT(eaHtGk#re z?m{1Gs>uF7EI{0=-Q&k|OLXTXB81ANp_{=XD{J>)>aip-juHmjs=^ycA9i*@Lbmv; zxS6tBO-rd?^NWDOTtH`ciV(<Zu87>z{w$It^^fqxED>$fqPN}k>JLaMP`T`iZ0B`Z zyGlc|t71?0Xxp80fI?jP^X*G_^M*p`>)GG>j4SD{fY(}C4@M7gXlo_@ar{NTpayEN zbe!G8{CSTgBB3VMWF^5*Z?>U{Xk@p^u&)N*W)(~&9N;|*i}&-c{V1V1=jXCZ0r*(k zdV5@`x$VT8AMmx9L%Retg@JTe8;8n9Cq9SmwY4tX&}OrClg-1wA>5eV@v<qU301p| zF1aVka@#k(huZ!};OUkT0-Mbz6u%nzId<yGK{(6k=`uXed?2pCai9SOToWMyW=#N} zx0~|6yXSz<9gIFd&Tv2VR58G6sUKH%ND-jQ$m>e^PB1m$u}>L)M%VvxcFxU$%gk^# z<r-nHM~}pDb~PJiNH!a+)25oNEwQ%h4)EBb?&VYT>SB(nTCh9t8oyfgTH^tw=*8IZ zV}W%3IuVJlF~LGRmTm^avq*J^M%RENx~gVBmKZ8m?x>~?u7!^~+c8I+SW{w;<e!>+ z*(5d`4(Qnrm+up|AXcq?Bh;MO5lwU}eqn`)iss9l5s^UeXE%Hc=lSdb?AU5tKQ7g( zB#6F^e2~5k&lDzW+FYdZ^ha`i*~l;lZbq|c8q@^3Gp&XU7LY$q`cZHy6*MZd$q^2n z*3c1;<V3QW0WNR<$JsdqR>Cy_Hn#C%TQ9b4+g8Wv*tTukwvA55wmP;w-#@Ea&-QNa zqH1yL)~Qn_EhL~sT1V0IWorOy{=d(r=?_<`g9C2rX5fi;kx=p>E)RbiQw3n#YX3*& zoE&p>qaYu$#BHG&UpGv5tOgpwK}D$2OA)z=rVx9O$z7Wvdsn$o4+BM8+44p@$a2Pp zt?-Ua`Ko3mGUUp<`2PJ@q1-0cG7(y(e%Ll8Kh2YlrC^78s4PpGQuFGC0>0~L&&J6r z1S(j)ve*d8C5_K@GKHQ<a37iFW|fofj<NsIeXcNLznOYa3e-Due5}NvO~g{@Z>2-V z=n1S>38%XXm%zf5D-+y_^cM_y1ywZcUDMCfw@y!1Ojm@*$bX8MS0?7|a{Vqa0s{ve zQYICuy}eerrpXsjw<=lL&1>!c$E(ChcxE<NZOEjxLh@*!#?r%<QRLMuYIlWdOe;2V zR{^>DVaHJ+e-+u|6_phsxbE&H9_Woi>^q7&r9nLF%b{w)L@^7blsHyh>X%Fx@JnnK z$PMgGR(XXq*#s;C@d`#NF6GOjt^bZN>$;9gf^xGd{l}Xqbe-h@r}5vnas;BMr4gN3 zIQQ=gMs@rQpcx(K*Z1A6(hY(dotQJ3qWkwXx|AM_E4RsI<}8sfBzQXt*UPB}zIX)K zhfAf-sq`?$_t8gLA*R7-HJF;+26<*T)`Q+*d$vI75IA%b`UJ??=X`AWf2U++dq~bm z@VCbe*EI`Q<N11e06hrx-mKWKsBX1hp=Nq$Omp^(s^+t>Il0_UBk`jM-o2&DaHBn- z*n*ExMp%u8kP%P*Ox{h_@Nm2b(TtfyY0pUJC{b>UG5#k4K*Shyp0JpM$OUDZQ#uSy z{|Fl12~tH6@DKJrri_rx>uojO-v|n2A#!t!4M}3RhB;bH+zJAU>XF(90Rz{F^fCFl zZ%N^zDao6LW{e@Pi^Jo@?Dba2?t==v423}}`e(uD;aeRa#xTnXuN_;`>O)llqj_b3 zL=Naj-lKV27|EO?rrrqb`M`_Y?sjJUkWxg9g0Kpx$v}2so9%qa9#PTbUYJ45o2`ZD zN1((gISt}XxIiAxjuJ#tQ2vED6U{mTwIe8*{(%f4I2;x|wvtttrH|KhWP)GKz!eOX zdrRPVC3EkDYzX!6fB84zoIr4ksjV<Ge1Ere2KxPlOF%)MuIcsj<RP*HQy!q_B=4#u z^4}~UhI(XDg1NVy0+n-C&=46Rb%`q_7oo&0@Z+C;<u9boh+o7)4EHJs?$vXSwyL3e z0fmMa_xWgk33MGW5}ef;<KlF56OcLdN^DRB-g>eOgo++&8prQiI+y8lnaUlHMEA5} z4~1wReQ!$yOwCd-9!msxPBi@6EXuO;h%OA{6+Z;2o~FURT$R5Di#Lh6CoQ@GdQ_u{ z^M6AI1@fV8M%xtJG8lkblYQ7=)%dQ(fzwJP^${#ZR82{1FU(}(j?{EYh$67RgJ&Ua zvW4}f^xf#k3i@UF{NQCr0)+5;Xejzy<Wgs$nkxUj)NoT=CIzYx`hvr1I*01dml-E# z1<Ghc9l`%04!Hh8xYFh3cs7=oyy}kVBoQ4A_}kw#$D@&8Q<%9XUWxJ-1{E)(PIn#g zaubIfiqKd%V3l|T6~zSR_6<~P%XaLNpl=Mj0^Uivy1-+zti3mVQv(M*!F;<F`aV1f zocZBz@6?MTy(MoCgbnD9TbUmu#wVI&a)nEWCO4k5$3*_MMlRX8p9PM6xr`T?vTrSf zItY(XnU{K)#L$*_$vJmyHsulRhbb<53a>NP%3rSiLt%$;QEh3?q5Zc49dScxN+#gP zBY3;Ds%<dxKVAtwzYPZh$V$C3B!b}h-&8~rIm4h=CAjKN+W<4<?G+u_rA}VE#^*J) z7C1NIQ8=5#Kj_Yixf60#rq#u<4PJc^G-FvhWGMzbx2}Dd0{y9G-Hj=}ZhE{|S_4Vk zq^pEdHi8|WO&2QgxuIu&RI#^v(wXTVx9Ua@>rxC?5eeF_vp^4?uW}l9Tj+#kAZe4@ zyivcPra*ULhLI#}Il=1(*ZxX!hgD0zBw<P*R!b7aNIub?Am*)D+YL?ZII3nlAvPWY z{?oe6r3tHYtcQv7VaN3zrmr!b<UW+9S~-0FPTF|X^!`qexx~G7FQA{ARx-j8gfNeb z!+x;4kH_3*fE*KNVyi-r9&^iOisrImXxd`3X)bDqQV(bShm>Rx>t2#R9I3~FZOE_R zh#%dmU)gfoMz;A;u^q%*^)i6VJgeCmk;0@f8Mk)g+F(eF5?&xVkUcDp+>ENkMD~u; zMHWtV;?YflOd<3JHc1TMuo$u1OZ>Htnt4e;($j#zqM=>lwXI&*qvdBp9!JkRA7qLC zPupPvPhWh9<~3nH8iOD5&?}fs<aGF;S%UmwjkO0gegvoq7HTb@>6M;LiX&-t>l%vK z4hhQ{6l9v9q9Nv(w~{v5Ia??4tpa0PBeQWrJPHTs<cU4*8`Ik#Di-Rvt-t}+TuVGi zex?-)8O)JBTd)5%aeJyz9_)Im`wWb>+OD(OZmU?OVts#1KrMjfzHWJDBfC$Q;dF^l zMtBorzHQmzQ-MOMC^7;W6!8T>xR6LNOBu3Vr0iD5NBIrWdK2;Q&E-5c72$fa+~r@~ z3iT9P=TTK1*aqdzGP8jINCb>o0NpjcGT}Ky?~%}KHUG8O_og%tltb}wDF1U@OVai= z{U=FuX0UrN9#h{@<8|tRwoyNxy;P5Bu#ihkRnL<=R+`F&BayI<McV7bo`LB>2;<pV z+K=%Smtt(>orbCwGSud2EUJ>Qh)x7?4QNm8E~4<nkKM0cZn@FI+R+fzH9FE-H|4^e zB#w?ro{fs@sUc}$8B2`&NNU2CkO}dcj>F=sbdMb#Oin?RZomdY594=&_?7=<l2n!Z z_k|P2y<mv>XJQi>wVNSdp#^V!BRisHnng*pi|LDYtkilHR(mftYi!+G`)J=nN;78} zhU~+!yUQ$ez?#<R$<r>hR;U}bG%x(3p0XxNc2OES`W|vj{=iEP9#oE|VFFQS=wTTe zOoEe~>Ay=)D4xlLvz-d?3Pyunh|#^VIB&Kcl|0QMeGH^ahV>-9&Qo+_QzW!b5JkQQ zCO~p|g7oOg4-p2}24naC>ue|L?_v6Mg87!OjA5$LQG_D$LYwhwgq)V`$?K2!G^k+3 z!MINEpBJ(a{az|}<@855fddvUEQnUhTfo<K{@W&CEK1@f#tZ^LW~AN9of@c3fy?+t zDsGRXfa=^+<XMx$*b?)rZ_kG<p<@H@>|S|T-p~QNZLgdTpN44yd9VGmzJ$(rcmA{f zZm2&mVxvFi)~w$*S*OKt46}o8OAw%Wf9L%D%2GZ8OYg`zo1sh?p)W|`C6S+v|CuX6 z0ci9`kUP5>B=jUOt>H`PlJuz~#6~88KIwjz*aTRFFbas!bAf7m5X%_^;^lR^#izKD z590H#qum5YkwPU-Iuf$l?=ERTk?rpok!>TEHPyj*`eI&I#6GD&6PG6}mp3dA`E(a? z-Ln?|Zwi^u1w)@G(n(S=y35AMz#&=M7i#ila1=OLF`=}G_qM&ETgi(`Ef3w4USpPx zxb@S_@^$k{9>StC^GffFSI#Y`G9{|iglP!ceKNd;7HRbTg3emKfO}qQ3hsi2;eXC3 z^CknuwAanEfHV}nw}}!>KY?ylb%g>(DERARC1*_!<OPJ0Lzq;F63sMd6HON*tz0#5 zClCuQfon3Uwg69JGjdrM-fP6_O>R5o)LeZvBg%wk0%c|5&$lggj{~VwQ|--nu_Y!S z#SU>!V8$8@+#qyligZEc^9d6YBT_s^_66?WxqAdrW$k`9ytnl|lG92kQb|SwF*kr2 z9NoFoj#5vmQ2P=U8}4wxL^FS4$)r%<zvr<F^j}-t2I~r_eyBhAWaSP1ZpxA+<=IbB zeyfFCimr^5sUD9`nKm;GattybmT7Mz(vN|bodZ(w;HbG!!X$g+xv<bKSqBQ_<pd?3 zmoSQ7cf!~^P?_laY%BSB;X#*Tyx?j7^$bw@YW}7s*vZfguY+r`mETOEspvLu3K5wt z)bOIPkSRgtX)Kfaiz$X5IBCfgH<q|;fC~#XCzequO23ve<wQl|16hMqC+ULwuOTf+ zgDr&m2m?6uh*J<9QeX<)9eJhciof6_3<x>EIMxuS1c1LM6dpCBKan?fGJmWqB`+?{ z724ZY>g;L_``hsED$RA`BgnX66#H9RTN^#0+(}uHP(&Wem~<~rp=HB8wG-PfrZzNO zd_~!*sNiGg>;}nNc5Rc}%E!4s6Z}xeVf~IGx9dJi{vSUz_3r<NpPG-+qF%q4V|6u0 zV)j2Vb)BJ>ZucN}`bu3*zmKQQ*YWa`?7X^^fqr+P&aO`I^=jQ4a*qRoSm1C#jK~{U zt;0LchvyzyQ~%6&n(r%P^&7=xDh3_~4mY>vFDvZK(b$f5l@Xu26|58)br|>y8pq~% zm<3keBQIHuCt_?zU+!?mh<;bza`{G42tCf>YF&{AEYMYC!9ATcG#soUdE*36lQ{?2 znm)LHSh2G77zE_qnd(YYPv$uw&gJ@T4t61e=#&1{Cf!i-Wjydta53^NM4hzHI1+CN z#RA7@B;Fu*ZTRzNbKbD;@_WKw5%^)NQV6^BB>DTmjxUH5<HwB(l^|mN&5R7i2`JAn zL&6_4bg-DOcq@nL1@iH`2+OEv__Hfnl!<cnf!j>y$@=Sm&NeLPD{-9dFEIwvZpcRa z{a4gFfgLW|f7K_vW}Mqaub!y2^hsU!YZusM;#Y2;b=6?LtPd;Dp1mZmDy7`<sTC4F zFnI@~oW>tlP~4{wBs#M3&e`|JkMe`Vv}ZP#OXD2E$0>N_%=d=rq7?-`N7)9yYM&6V zg|=Urum6P|ELdADY%LToO*v-x8WRu(_sZlCuY~6;54bM0LeJ}RlQz!^W^=|6mZ9E& zx=GGecQ4G)tN+%ppPg|nx|x}|)cVM1Q}z58qwG7-d}p%K%k7xogP6DNi&-t*ALN;@ z;nQb0>9SH`?xk{KX@I8H6s2K|vfk;#RyNfuuz!8auA0-;g|G<HqekV6qTFl+BG;&Z z3!)xl-Zc%TGzNos5J9IkJl}<Xf}xhD2vsCExt??5NWmwFG#|Q<imU=5T*7oFxTt^= zaBVW0<BOI8`d$#yVSEkMJR<#oP=n?L)mmXz<0s8O*4YNR_}hRIOyIdNWt?BhQ%>3u zvdNWkSj$m%#=ovE=_PA2<ccJ5d{-EYgd}d)CV=j^qN!WU?frC*M2Kt;?ZX~ryR~dv zh}IizA}@JV=mSzin2{kV^1Z2~3@~|}XV%-Mg~V1oc)s!Ponm7zQIp{hv`=Xf!tr)q zPA}Djx8tOh0{jAa_@fY2g#8M*`9%|NfV@5j-tYZ80t6#Z%rB_zz`ik*k8)RH2E(%! zDX5VwKJ3E|n}j(d(d_8e(aj*7nN^L|b}OyA-X^!hCQ^mHz^ds2?xR|<oC^jjGqSGm zO-IF@N;ZZqgr*siNssIt&}iL4mL~kt2AHBa2CME%R}&c}JdPYyj;5$OX3rexG~wx$ z3rXOjAMCv%TeOpN0&h@1w3Ox~L16_hOWe`se+Y~V=dBQdl6ps+AwTP$6N%dd0W*qv zj)b~?nuc*-NmJQzj0Zb(xRq||jcslP>1_t7fHF9SKQ`0?X~Vq~7JKHaR+g!V0e26& z4W&GE+jO-XDVz*u3!&2A#g)|qvLu<YhiHt;Ubb0tQ{o&Pg%V(52q~o<Al}gQh7S5* z;aSjoebGxS&*rbtmsbP~i1mIC%<Mopp=JAVUgESDYD1CjK{!D6*Fcn}F8B)2Ll(TQ zi{RI=hO18g5Vc?-CCX78)ZyiLVbZI>fAtjPJwenKI=0$H`+r($N{r2fXJZvrO%ZM< z<(uIu^Hnl_;~?YDhLYlJD|bmvn=$c9okva!_f#OTRW1ibJxFk(Hjt<<zW4OfVswQT za1qHP^Z}3~WkVoOoOD|l9~^t1ajSzefF71clrR{y59GE|02bzHWtqkO^;8am=FWn0 zzj*hIR|Jx~(TqhF_#f2I<70i*-*<+!So}8k7>90gx2Pgqs=%3=dW;E#ikmD2>l~VH zEkj>DR#odDCn{zU9E4jX)#wx}@I_kqP3|!wthgzj8zTo9t`k}n1+c*E3Dq1b_NMMs zKfNiB(hB`{W3K8+IplzO8x4cCLx`U{B8&Z{6|1^W%{niut67hqrFOiGQXbVu`7f!@ zBh^&?Hb{n491Qo+tYx4g;kiAVMm#W;(R`rGH>!(QI5!r!na9{^H~EJYV=~!nB@LFq z1z40jGr9$zT}iP5Stm=Ns+0xe+*iSpgGL6OCVy`7ahEc6?s>lgE?)1BwQR=n54QW% z%vpcRS+l}f4rw2dY`sP%HA84Gz6gJa*SJVtq8zbUA&SFg8Mtf&DbtM^{F@`@Dr(yY zC-+~1ge%wv4jxpyxlS0)2!(75q^ohaG1UOn7?CV6oY_*g^t>tYK~x3VS+a-cSD|j; zEY+imr1q~-J&P1yz0}lJJz#s%&0Ol0<fDoU4qY?C-18j68(pb1Kcf?}b;twSbIqaA z)Owd2x3~R)TW4x&g@p&5fI3a3%zmw`R;got9XxR(QrVHwKzFKdyA?QN;x9L1&toPi z{l*2pG2+9zcwlgzW++Z@jS3lkDNZnH$)Yh%{>|gK$3p~cATWYN2S7Cd$p(NV6Oh5a z${f`7#20pc_h1vQ1V)dC(^+0cX;`OrYhW4q*U}6S>gHQVjMmSxk5qDO&Mlj9Cc8^X z7h5-Y6v;dn+H`o)yca<E4697w+FOP0&B<gc8i~n!A8eB`6`?iL#8hPb#YVZlvZ9yp z_T(9;kX8_*XXama^~!2(_0*08!X{=OI-@d#?ZB*-J0l<wkJ%nUdRw%XsGsp(=Bksf zmLqf_oyWdxAkScvCoB2c!^i5IZxmecvRe7>fpWuBk>L8~c_OP*iT9;HZXYIJkm{!` zx9Se#+Na1PCraIU7EZ7xqm`f36pNk-4;lr<H6=<VZ_jfx^%&74?`%SK&%uRyZpz9B z8%Y5geMdMZQ49|280EtvM_Eeh)w>XFoYDE-Nh}Xt0Hp~uJ(7m>q_H|hM5q8V^6&&~ zRD_ZRA_OxLRBcL5yFrA7E|m3QOY$NIf^u_phv3m}@F;Nskj$hYqyyP_C~)QV65^(7 zy>AjN9`S|r{2#4LQE%?+?QYT$Du{#Q!$Rg)E3o`GZeI>oy~HBj>l6W03nH6rW8sV8 zKfF33_@Qg#FaLc)5IwtRWGf8i50QTE+n|7iD*iVPn?UA{FU%K=gh;jyoQRN4KGei* zoHR=Zs)E+D<O*{hEfwVS^5sfny6}tgL<+zRnsM^T``Ju|v411<LyWL--LKe+@lc1` zTNLVw<0D%MHz{4{$rUNv&&8(Az4IGYmD2Ds7XMLg5xcjAUg08(6<%J6l%YOB|K>i@ zHcv<6R_4a^Q$428aglszB2YF{CpC5#?kdJ(d7VP67qL;i-j+J?OxT-Hgh#>CF92L_ z=gT*dPaY7C9Vdirxq`zru;AmC)H6Y#sEj$4X$8FEA{+w+$Y8YxgnGnexWecQ7I|k% zckA)t3^v}1QlX{Avle%W8UHi;&sIkj%OUWiK_yE|3Nh9T_a_%{!WV;!k9EM|NDf4R zJ>%~+T~s)r&<(;xK@ctLmB^frHX4c~FWLUO3HD2JE2Cgm>AW(N&Cas5R!wG@AvRJ; zPkBcHUF2v-kDq0b6y9xGb{79olXh4Fd_L{9C*?|5cW9~bc_JuR|7|WnNl^rMU@Xs& zu$M16$zNAR7X3@;msPJdA0L}UyRR)XH%l@%4;LTQ%Z;FXO57L=<x=?gR|2dI$?072 zKeKE+cbLeZl!RpKV7w?_(K2Ejj4cL-a=StK@i{l1B>5L^t$`MK;@?}@`2VxxxF9Z2 zKDy1?xmBx++J|nV$yK6Ye^xufS(1&NVDlzB@t_InN)ISBS0%8cdquk0IZHD&wb3eO zXxgZ^w@@L%w7N|So3^f&V<XukfQL$B6~S0!8$=gb)?fumR$fIP(5D(}&|s@_4|1?< z8A63RfUV>Qv1q66n+}21{UVj%0^7vOOKA5|>8?|}Y~2{UI0i*ng|qh{wv347a5=|e zOjI3p!+ASSEg!Eh*b-29TS%T$C}p9q%Y~w~mI!|HNsAmY;v4NyuJGNP=&3Tf$MwCW z5!D?aE<;4lLRcbr3z%oG3%Zrl+F^}_o+oFve>k^M8~=w*h7zeQd|VX?htv`>tYYtb zT^Oas^sSE4KBX<<a+5$I-p_{nuLGS&Zb^?b0u!%F<V>YR@p-w1&if9@*&lKxTwN>q z2m$vP9VcGKL3QBXknf5oSM6b~qW7d=ynWfMzZS+RuaY5|p;vi9CNC^w*dnY3^u~>E zU*(>%2+^&JZ+Oc>x#Y?gr&JbRF>I=Ut&JP|B@+Y-w+CSGz9~INdx)jtO%4%o2SB$b z+&fh(eJ;_u-*FzKYUv?;+KxhWj@(J7Nt}i;!i+#58sNjQGv0e;2m3k!zqgYf=nlnk z2R#NFXCKr(^z`BaP20~uybJT<*q9i)3LX3!gp23X>>4S}`X^OapBL5rbos?SJQ!}l zv!A*ru5kOu?(I!v)rM_GA(mSEte)Jq6S(cm7|@C=<h9!4))Uc{ttXx%vK4OjT2XH^ zUDU9Tewm@(RLTzfpO~(EnKjxfUndrm5g(axeDF7o`PeAkX^*ZeKf|0p0hy^s&cZ0Q zi-}}L<BV{t{HPImMNn|3K-NQ*d`~l7xr%ya3DriYuFN)Vs;OQeES0adfw8?HMo{VL z{6|r0WtN;TJNUJQU0hUegx<&%rDOFi?v0yoFSyG<*h3N4{_roS^QPboMg`%6=a)%p zrE@L>Xo8`!F*J<dvX^4CDl|fylF|^%?#0#5_(1}mRB&f6*9ZTK`;)TbArW_N<X-{T z!>LH#yLk#M7&w>C>MT?lJA<1iCGe^HXpe)()I^&jK1qD>3z!snv+I_rYYJ`zG6N{x zhQ+5&R$m(Ernmy)B(_W^i7r8h5Zu2K=nXcVvw}ArVo|0T>+yq5Z_EpaJdeBGK5NGh zU%j<QQFu2CU%g=oBgT`)MmU3}=)#DRem9ck5?=ZEF%~EJB@8o3>e~vRw!d25{m2ud z|Liu;3V472M*Qxd<?rA7@h*D(p#=TzkL6>KyfZ!g?v6A&bjqUWmL-OhjiCtYD*k-_ z=IZJ-9Pxiw3h-o#qvZDKF+gLGA1EvCd)U0Y>ZrIE{5p-_ErAC44MonbMvYvg!~QYu zAYt80uxy_Db;sV(*_%&MeCFL=4DJ<n?8ecji8hCY^j!Jte!RWvYe%V3FBIp^1#;Ov zuhW(9SKsExW&!5)gT_$t-m$LZr7sKjvj9bidlXF^V-SX;e1~aruAPBGEs_kwAK6Q< z2{{l_+Nk!IVreI0H|5iSiYQ7a%7qO$$Lp&b3zG!*M7zr3K_bM}mHp1TKMw1$6hy8L zoS;rm<qn^BtvjGKu*7^+Z&y8rlDBUX?6f7xVvk6->7q#K==Vz7!wZ}QRXz#sC;#jc zMxcq|g`f`4nTekM($+Bf``83&4Pcje<cs}Ixiv_HS-9+g4KG@^CRuiha0jsQN|vv~ zCLCIQ5pV2-uk(V|Dz`Xx`IzTK2!8Pw(R@F~_Jo#?D#9%`_)rK;9PEHfBbA0gL;>4V z^^u$!xn2-i02g)1v7?2`+Pe`FE=2AR6@Ny5o1FY1=5gYd2hx@MaxzE<6q<&*0#U!t zh6VeeesiMQkrOnT;UD{=m_(lboV7FX5p<E4T#X4&#R|a0_SCo+Ge544b%83ndJ{>g z<iO^;f{V%1i_7!gK~YC7zQCb${Rn#BY!LjXbcUa`{E4!Cx);ep9Wn|o=RSNMgxc(h z4GeDZcJ1!vs;m-|QB&7W)~2A(U2GQ0$Q~TSLKqtx8^UVX#&*IIiD->8s{Ph_M@|9e z|6}a=Kug3)#L-qyk_osnDXXoSAV`myj_Y;5v<#oh(5kYvAVx$=Ms-L;V+<x-k{Bsc z??Fu=>d_@r5x>$xch-#w&05nqvdU79h$PjA)26+Vj-{UODL{p*w}Xsjf{rCt+<L4) zwRTvtLKW>>JzR(nI}o=OTFX5aQznBDa8`9=8opqo-~dM%XaU_HoWy`4={3B)@;HLL zYA10Erl#t0VM5IiRtgY8l~H<`%>bvhf~9GMP&t5lgw8;Cx@`QovuAHNG@vaNeRgGg z{?{{YR~g!&P*NUPn;Z$Z!jr-U8P-K4E+d{`i-9v!4xi1b)9aUcwS)`N`Dd>b8|-b? zesaf@{}tcEC#*df@K0+HKihyFL0xaBnKmZ~7RJdxVFcv{QRdkIo-0t#hhDE+LdYoz z`;nmx8Fb7E#nC+yEaiq_OHlPb94@%kX&{C~%E-qs=**K69%0BrfNWh3ERGI_z-9u9 zUvml{O3YrW0+x!WL}NJ7zBT-L==t#MbdK{~IBWulNstxx&1TG}I+sabBZ3?6ZRdEL z4=p+b(dEorVJ*%WU*$?}W78oWMEop(o!8ZtURo|0nY-l2h`}p8q!RI})))~?Nq#VA zun7VeW8u#rSI{I8HmC4zv{tkn444oX28VB33T1X>#N)t&gy=gm)e`cSlBx2pMca{~ zL4=hZ0S99ArvK_90gvA{#NCpu4RH@{=`$)@9(*hm_MC8oL>4oJSyE2ZbqJaCcHGSG zO2cgC0c~1Dm&4}e9}H+nE?+oL@{+GB_Co2rGWh#X-Lg2p2Xjl%3h~KnWOgro_4m)- z0*FH_@zVD%XnQ0~a{R19Y#Dh0AZD?~W5Xl8pP4NW<4x_of9j?P92`U10zE`lQF9B5 z6#`^3JoP~hs%kB$5Lui~LB}h_YxB4?$ea+ld6P3(paf~aJuO()7iJjrY?sdtX7Xu^ z3)6bO^YNbqiY8h6s=e$>C{P6-jbma5B#H)zk+WGBq2mb1LwcD1R1<jSS<bFqd1%Au zOG2AwLF6kI!Mlb?VKpFVkc*tAHf9_7&_q6ozhCGH93SpcZc%%>JQ=(GzL=kmsN^Y` zyxJ&*=YA)}H5UdpB@5x95u_OV6y37eksxD?cYE6rEeTzTX$~1&F6;Yr$R^-CnYouE za_{jH`UGax(MV=Ag{c(C6RxZHx4KtJmWADRw&`}AiElA{)vuXDwvZyM3wtuBTdz6+ zC_i{{)$VHBS0z|`Xn8AlS_@4F$hukI2S@e@YtdM$$$u3t+40iPLgQ#^h(>B5(^e9@ z&fj544f?ska3I0Ebn^Mp_^?W6*DwoswATe!U&lnsi=DvWlL-?;ev@=oDq%AB%dM47 zDQj$A=393muhWtI$BbiZJ~r$4CHuQI(??R}pdQz&Ifyl_T-uFbGUvU^_851dHc@yJ z14-QFiAGX585l>#Z+<kNuePS-=3F=jHopC5Yy6%&PfWl4FK!j5e{SyHf1Glb+cnIb zWE=KocfX$%EEqn=cX|)(_=0G-Jadf_7Csu7vUldldP~YrTQ%c$Ha$5@1}w=*Yh$Mi zBx!^5idKsdD34i&EJ?e5#F<=ahQ-#NPxb`;PhoHGv_E6$H=t|&do9#smPRTnOdhUK z$KxF*U!5_0%I-q2^vPj~(>Zhqg4b_}-o5Ui#Xn{dna0w~Z>JV(B&olcjlNpZgvB^> zT^t=rAg1I%TOKhDBWv#veG^0RrIlHrfnyb;h+0XF)`+T-5vTkH4<9nnkF{3Qr<ecf zSy@@&`f-Pg&-xL3xa?Yn{r<6y{t>kQcCchI=u|4ApvnW+i5?302Jky3;W6P<jEvCR zS%`R+6TiBmz*xjW$E9dMEDxGC6&(gjh*$n-xA_8d@-o;?AEN&J>;)z(5t`eF?zzf< z#b&6?N&JD$vmG~3Y$+LqJ+J$b1pe?hTg<RVKK1{5TY2}tyda9DzDBX~41x~n_eA93 z#)1I8@qCUl3LhW4_@GQ<Uk&51nV9n%{FM=z)5%jDd4HLX*Za}^vUUD3+}!vfdU>zc z%N5Y*Wa+JE(dpF1DTS=2lqb@iuUwQ{psm-dmeZ(X<>nVLAnsA^Waj?^u}a5D{NY5| zi4;$z6f{od;goG{FC6(oYr6PBp`W3IGkj2#Z=A*~l`~Lu=3g|ZL&~XLjvgBZQE@Ty zNb(o(eKaO1=%7|Ng<z_*7kIXR2F?;K$2F!sqDVPDb=!R-=Ra^{4Cb%+_|0WrfQ*+f z0K!-ojoU(ABPx%QS@7&TcXD{}kQ%}~MeNV=28xf5pV`pAL|!Lay5E;2pof#YGkf$X z<x5UT)#<Mj^O-*NGyV0yFnxSJ*d%@W>;K;{`9lJ}?Tm~%7Ji=F-J50$Agx?qALU*j zp?!w1e)=foKHQJa;3q>B{k5?A^owmN|HwSK@!<(@?=SvVzS>viC>2LMQM}fMdbfRq z)M1c_dga_9ewNWy>1kgLQ{)e8i6LRob*E3$D|@3GBGCQ`Izc4s*S)c%^>mf7!AjZP zYKlBl{f}@QXDmLMpMHDU-e2rWnb#Nl_Sn2ur!3SjR{~b(QP9ARlGLVlKV@d=m?*w- zWX;<k^ro}NT-aZAr<F<+O*cR^I=n;FP^X9<r7vt+KK4b|67zD4;?9^~dRvXsn8KUr z6<YLC>io8o4*bjXvPvoY{$hzp_M#_~4Ny)>!AAy5?<EZ}aYY)lc+vrn*R!K`w=;dH z<u0xMZG+u+Xc1&M&TaDAQU^db)T(=pAPT|c4+HCK^B(P6RP$0a{a7=RRe^L7|E8<G zyi2Emkjs5#oUQW}Ap9}EYMyO>{Gp=%hF3sVg~9GuyJk@Q!q&Rdp7olPEWeB!2cSu; za6bjB|J`h=t90P25FCE8?CG&=HNW(kKh$CZCtNyzQ@hAEusD~j4#0^b3`;_%RNNKG z&o0`IRt&7buT8^{qMJpOLWB-R61Fd#{f9Oul7$OHNva-GJBGsasEVz6C~Va9_?iAl z%oJ3B3Gt5;0P)ZNpIyJ;4dDCvFKaaxs;HUn*n@9*3@c%?2+~B~CSkzOd8TbO7kf~; z^p^$ctcy4QC34P4Or&JEJ?=>Q&QS4eh~T3Q;+5CDWs#2?iy{34!dR4xEXN(2&&w&; zjO|*VwuyEH#PNyA(3}_niz}$M=L+m;aWjX)+7JD(L6A4RE!4=FaWhQLPSXto<q^US z_JCRqLeP1b?IS$pu2HAqUMf^d@lo%Z7FTBarASzN8vPaX!2)QuK>sOb84!^Rf1Mar z1B%T0_0^Z#JwRXrTa!{EEN(n;_Y`et`Uquh1rCS~4_vfF=3>i|38y6c6T%WMigp&j ze^eG4KbhVvgvv!sRT2{Cxm{*$(Bezt@>-_Fq-)gi3nCb`e*a{86K&sUWV$Cgzw2MO zn~o87hBl6jvs|O`9*#xFqLCvugc>7|Bjyz{+IoN9_?Cl?(=jtSK`jkHU;!;Kyhl-) zGQhMgLWpRM=48Ca3>7M9X)eIdgm4!+6d)^k5;?&%ASm*jNQhsi8<o&kYN_1^!>ny; zgsp_nF$OkdTcF(?5W#eQok{^GDu(?nZE6jJpn9K%0+0ayRxA-^4WK<N9SINI*&*#T zr{jyE;fuj9eSBs5!zN5Tkc;rPZSOsC7nvM-XIwBPSI6f{bHR>HVv$V3f$)c}-@+D~ zJb)wO^xxDuM`-w9^|}zXEaHy{1`;#ckZ#B#I|WD#dYHekF><OM2B<edPjpKQmIL3u z@p);@t!@9}{PfVi{p@Tqm@F;R@$bSnm^}9(J%tP^RFg7|5FD9SUyY7JxUHluP)2}- zMfc%L8hnSnJNhC+#3_{5R%R_JrF3lr>+#l7#7$Di2xH(T@7bUw$3$Omp!+(=EG^lK z6?s)mwtDEY{LP*(;|Q<e)2Ia?nh%_BU%mg2jXt6PxOCYb>*k(l&FVCy#-%@Rpk>>K zJ?I)YW6shkE90RHE^#H^nl0moxsd_R;p}aZe58=+2dT7@IH*+_&|K?rfoyJ$akYKU z#4LuV7_B5Ma~-2#J0i6^NRw<ruHzhC*urDEJ2bEoRq7??&Rpn#1RYat#LP{`2geZ8 zK`&KnB%{!m0o6QgX*)<ORXGFa&J2N-jL@lYWHKhvf`xPe0V=c6wr4czLmyr=*#k$S z2-M>AVJ<Aus;GovvV<B<zWwTbEP*u}?6fT=c&c#b;3YbTHKLBYl>0mbwo>To{U4SM zMs|#OF$0Pz6JC!IxRh=Gya$JJSd2+&gD9OiUyZz2K46{F#3rnOV}#O>6SB=|ia3)} zWHSO55N`{9AuGmp`)jNXN2$%sAXj@9W2x*^QQv!fW)lPX=trLlzJ|L?UM#W_)tGG1 zPD<wtd}jxJ@dmzZrq3-WyYjB*P}Si;w*}26(S8K+MPS#p!mhXjuaO-rzX|Nyfss}y zZtVlCXZ!ClwruNlGox-2BYd-`9C^gh?p|^-=Xf8@uoYBm@GeLsftCtcM0mgFA_XEs z8B0C6Yoxnush6kes_h6KCUnnMKr|f7?jTyU0V_MH8;R;CuBTi;6N)W)U5ZN#vu#l( zZh0O0P}%s^WT(O8<XW1D3<s+b7@=a%d!y}<K?>RwWscbQlGHpVoQ-PHdO~aw<}_s) z@wkI({Hs;0BS%o={hDbLbDq4$$@E<Y$9e?8c<|~3{E{Y=!p8Rb2HoNDdG`LQ{a&GV zpY7agRuV#lXp($V!x;Zr{o#9HXbX$t>P8XqssRRD-HbBxuPvjv?wT6bmYw~tV{<|D zIMkS4Eih8HS-0*}Hm|o=fWbe=)M_e|2biK$ki?S^ZUIGmkXoM}_hL#*qy<)2LVu4j zCVo|{9<7YL^hOyPcV(~j6hh>^=EX3c535a<ky|IJ1_g;b;lOS-S6KheFd>0@k4}M2 zljiE|hes&^Goy!OVei|%l~9PQK#qa7cxVWN?rq_+D0;aFezy&rKtIto8fWCIqjM%f z<wozFiA@b%iQBJRt~{NQEU5e;x<QYTK)!bAoG}Nq@fXh1@8=W*nO8y?xJ^jBfaLV> zhqWF_%rVPg%r(_?BS)hm8Q5?y5cnYH3Aw>%+SyPX;yTSSI+8tBCLXBg1d_PfFygKj zO;#M75lOF`hCwO4>~XLF%zYl_VzP+m0SE?V|MebShV!)T8R1EIN$+!=`B9I(UyBfQ zl?0A3N1({#b%W84*@U(*n~|d6UUC7Jc2>W^d$|Kbag()D3q<isswc>zxiPAPki5}c zm1y;ga5RLawV?U;Xc^wj)7gY{I6W@9@g{hT8Kn@}O6)%!Ak4GY_NO`d(@WRw#M}24 zxana$&4mFa5NJ_g5QAtkTQ%5@MB&Y!vs1AljcbA~3Fk+e2eAPLEHz56RT@Tx5fjhn z5?CxKj1+w+6SLF|NAm-r+8%Ea^p`jx?%va|G<`!??&^mn&%CI<Fe}pWh?_($p2nyV zuXCG)`ZJ!;W`G_G)Fl~Dbkav807)ziV#-GAfJt{6;eLcoF_|VUh%?2^b=ok6Tx<=* z3f~j^&T1T3ny6-x<#FlU*<D-*fTLnhO2GIoPVHxQ+~sHYw@tq6&QE)t>(6fTzaQ=C zw}(mhS2j&tPyLWnH|Hk|qvujCZ>Y4Oi292g94*`)f$c-p4xhGWp{1_(`s1h0ON0Dq z$5T}sJ)eQ+w8M%sDG7Icit4mm8yzI*g{wAQ5J)L9W&`C3$=iX6v^^f3@qTOww%s!Z zUMQkNO7Da)94%~d=moh`;ixu(eL=WQBn!iu2WqRX3f*x6$;gc(Zk@2RP%47%GYq6K zG&K6k%w-Q<RtGGXAjT`1*aY^Y;VJ8AH{(>p{?a}?x&$=!x&IahGB6OWi0dU_3tK2X zA?IouLUEU`K0w!|`%11^8$Q21W*FSE=aZ<nPqHhMv3m?}aQDQ3&o2Fb4sfXdBNYxA zY-md@0=uh4bCTI(8fwik!>iH5v6D)@6ROZ?kk^BWo*Q61DO0#CmXzsDBK>j7XPqk| zeJ!cLeZlZ&(2eXe$3C*ua*t9jv9ON#Br^v4tHQ9&3*60i4b%CWB6cI%JzgXp*on&g z2BCz;kzCQVB3on+ZP&0lN)_S02{+X(|As-ef29CWbT)iGja6M0T@$l%MAMi=^BdX} z6*T5uR?Oi4ETIYB3cV_6cidy!qnA@eQ#7{D1RMcBlO{S7*=aYUirE22oCuH<df}Xr z;=M-~<YX^<wnwmAU2ILqm^I#z$?^45qan!-630ez7<WMF;)hxn=tIZjJL6WW%AAR5 zEhe5b6Z#CjEpSg&QNjs@E^z15pbmWCBz%!!5AVG_mIkR852xcv={=oKySjJ#GE#4H zqUHCubtTHA;k1|WzoD(v*4<eBus7W&Nk4Kd<FZZ?#a_dSE*#6u?S$>nZW6|=Q7stB zZ1wPCTr4dK!K3Wj^Xyu;tuqhRxkFg0WU4*qX$F>2pH}lvfb94zj|UKghY&b+^&;If zjOIUB(NCE7(ytJ1Ti8+it+v}VQ2T9rg!IQNZV2%mcGV5N&iln2@x}-vu2cTA!!h4@ zCa(!5eIHUUR{9ykM)!1SlW)}!dd98I(0Njnu@6zODjGO^V(#>as3vdtMYAgb*Z0o4 zPyQ#);s|Sm=Zs~`q0?%2uT<Yb8ZYVQ>3+*@+v)A-4e|qZv*r*G!<Vcd1fQkpc=U`% z%V4o;kmi%5slDMx;J@3VN%P$o+2VEGr@NOrYZTg(&Dr@5_#I54*qG+<LT<J7TGr;> zkXL2+_l$lH6dQRM&jqyZ20W*ym^FYxOhG<z0Z&n-g0z-14Q*cPSpADebS&NE=~Nmn zRVV(xBe5qjK`f^etGSc2Fj;<*5+$9I@3foYl@LJ}N$XC5kc;jE+FXz3fK7!(zEYcQ zcb!Ff+<g3fEgXH%jat3nt`t1Q<Z!bgcOI7onAu4dr<XITC4Mi_wUiP|HUqFTK(80# zM#9B%Zv~!pbZjC|0B4ImN3DCawRFes;(uH5upTBk<c>SUYIv|^p$nxfyf6&L8nzNs z*_IdA)JFtet{vufwRB*1loX0=x=^~IkpF{yRB{4Qa}#f&{n$01;pT2ssK9^GxjcUT z?$UHDItt}NwRs$h&!}@d?2rH6S%CBev|qD-g>Kp4zWu!K9Nzu-+HXHZehB7!f4^Dk ze)q?3{=7iutlsYa?O<f$<vr^g;N^n=-4VQ9;}6^{C95?>-WHrA2@zFphmRli_Y<D! z^dAT+L68!)%dC8OJNOmI4-ROl-b=k9GD6;Of>enH_asHur)!vA5u6<$T#2s55t*!l zxN4pXZNlq>ZpWINT0n)#HbucvEYegJ#DaK#{07}^^|~Pv0*I_Pmqh5e)sK_t7UzGu z)gL}q*B9@)`XuY8<IPryGW45izMUqi4%6ZE^>2Hc5l&tS%i+4q(rv5Yp<CvFE&&Sk z-M+s;GZHn*@ReIWGyNOC|5Q7HPP`F*6>xIB6l?A?db|*2JQ6*MeO?Mi<j<4wf1&1o zODU$jj$^s(o*A|xv*h9;flvvhAzZ5M)g;(WLnYvBllo1h9D{Y<z^EM5T`s_GTE@Nk zlO5M#IWLM#88Dj7&$)XQqhn}mwwkMO$dOjPdcvKcKvNAY*?1d}X`~?v;5BK-(c7eZ zzmZ+hXCuQH2U+4YNGCR6SECvPiNQ-B^##RYDY<a}0;L`Ruem2D18YWh9x}x-_J5T4 z9gMJD;d41c;-&=@UJXKnu*Pxrd~`M&RSp6bZH9+n9x0C4HqU1xc#EW2PQQ&l<)X3~ zgn98Ya6sa1wc-vn;6waX!(ZVUF|#&GfMJIYnEG+KRt~CbGB_?0PHyLLnm@aWa<R{b zR&!IV@Z_AMv<1a&CW)14EEsm{{^2|1@#7BHg>@}L@0wwxr)Ji)i>|b@1+ki(1JQ!r z!jr=8=ruQ_uU+DqW(Ox>EK;Fo$b#=uH0-&Bnuq@R1nXw!C;B694Q@Dl;xf0Y10dFR zh|~X?WmFRI8F8xC&iOd8JfexND!wTYi|HyhTU$qZ$H)+VZOU<1PO*LQa<*smi`Bi> z%Ab(qre~P;!W=IU!AJ{ph$s_1H&ZIlucB$^CukY08J3nGg8*_K{d&}Cz^n+J6!}|} z66{9AnQ3Tt++OB0WEP?=Z8IBUaCTXnNu5~csz&(4=wmc5ifP(zlX#eubM2adZ-z6d z=#v<GH7BY<HgFfq1+_>IhL=Q*jw(b^;22q?5xHNWb$1s97Z(;XwK8s(SlYj4bhq`M z%gbrE-RZfx@&xGoqg5DSs%tXT*5CH~<oOyYCjm0tPOX8jR2-&NDrD$okj=Q72jg{i zmeWBeUS<=d%3Z{17#5KhjtvfjUx{|I1a{*Wz=_YfsTzT?1_zTLTf9hJplIR&CTg6d zOv7cg&-$e7Iybw$@0Z;*CHU#zRX5v>hWYcI+bPOw@9b75yi)t!mcvv#UW0Z6f79u| zGn?(UMS9yS)0=I5pJQ<ZN=s?|<o$Afsm+_h+X%7c8iZ;}86qO9Gv|K@9v=fZK$JLe zG~<KfF^@wO5U2RXkts9KcU=y4*|BL(j<jXqI<ZmB1wIuV+=Q(;>R7DI$b*!-nXXZD z87H5=6pGSrwK&nri9=^SS)D(uh;zOZZq>tQhr|`jMXIc%A$!SdK2(V?E{jgG8l{hY zP%&K5kc=D#?8Dp=e%Xpq<DkWAm0<L!pyifuF}B=F|N3u+Fm~u-QIzWDA0G}x8<-oy zsbC{(h*|^eVhaeV5d<)zncFy+dGt(^BL<YSS}AhIiXRB8#=PfW1Uax(VlihP>5rG2 z=gj!1Q!bt{E+=hgKPkBlcyE;*ax;n&^*sGgQL8VtFF7Z8i^bn^YueS|SkL*_^A6p( z)Eqw_&FCFV>E--@@KDicEe0cf6bMk4O~)pVO$y(qbQZN8@24JhxwR-ZAKfs18ZcSm zkYYgIZ-Y534K@Gs*!f0y8AKW#0;k_dm<!4Z$T&k`gu=tCw)^1|-B!Dop)qPor-)QL zJF=G#-4_$3&5{38X?2xU&Q6UY^-Cnzx*xrO^;i@CH{h#aL*JgkAN{=S*rZ-@UnXK@ zMywWUIs27{NeVkp=?fJ{W2nrkYdx^uRcf#(HKbFi2KHKsIXd;RhEn8JVFyo2$}Vbv zQcUEMXA^mZ+zRAMLbYGYVW_?`&?A{o9z@*Ayi{a|d{4d)uEpKhb80%~StWexO`#Ej zfgF<`DzzB0ZI$6k+qp9#Ex;kXz~M*-5)qRPDx>&<3<EFI)WibTr<fTg9Fdv%F(*m3 z8klFte=?kRVa(&lHhgRV1r-S=jbj+$#5Q<*O#~BVezYN$fs{t}CeI)rVCo!9JcwA3 z7!>y3X5pe61Z7a{b(Ei!i-3z$Z_R%<L{i<6#U(5pRFQRfq}nkh@jRzpXe{Im!Au^~ zoW@sZRP_l=)+L%NA$WWoCf-s_&TrU+&GQTQKD<Ha=H4+%y=I$Df9<ujK*On#*4&_J z2IxZr0E6#ZlSrO6BSDy9bW7ArvJq!@w-c&aXxH`)f;uCsvdkj|)ZI`<D6O$23{muW zCC7UTNhY;2-E|>|0Bx1I&WI&=S^Qn;Q8N4Uoln}_fXH&T7*hUy1(ecghJt-~g_0QY z;!~(hK$KG>wS=)}9i&MKx&#Yg-x%QRp~Sscj%0Qj%AOIzG*m+3HnKPtVWLOFh$_^g z@CcMcofw2snh>|!>Pe2+zX>DAPV$hV62lmK#=GOO@WiT+ay7(k)y8r4ul2l(D$Xg| zXtWDuv5zk%A^?q$>n{{9Wip&6m1C)aI5!NvQ6`Ghq<uc+lD5i>oDVI_AfHGYhx4o- z(B_HB9_j5b7noYW)M8Ybn1=iV`2g9i-1`C<tyz%v7pySnPNw5=ho=>#06mxvn!Gj0 z4Fp}98a<-l#8rNxZeG{c5C)PWi;G8%GW3=AP7Rt_2G@^VzfqI04=y8q*fjI4=RskT z#!Q?P0Vrv@W|y3!D-wcABjb6BUN_*bWZz(&>&z0N*QXj*HFD`Y`nM6IaT(Op6l5%- z9SEwK`wrsW6wU|jHe7|BK==w}E_dpttzOTnTw<=-1EbQ^tSGGGr*0ubL!4B!04Kbv zw8WhpD@~oGVO&}Sw7LpP-?0}N3*b6`yW^N2pIUWW*UTEuBG2_4{9dj9mrO!_wj^U8 zmqHVn4fAx4!ikCo?}Uk^J~@i4d=~l#w@=1`B@wF>qjET_eQ`c$gyE%Qy+#!#{#V#m z!MCd{mz~oS(uBKx?sQrJYR7#QMV(d$Aymy8hU3e00VX=SP=cu<QA>VL=tg(4Z?<jD zW#&6vKA{QprA4-01`fEy6Hh~itueZ9bx587#mQBj1j?d^=i=g3@2h)y_7%)hYw&6| zwgIla?>XcYHBO3&lD`m1;7!3WEK8|rLr(c-V@885?=1@u0gslBsglW5BBQ1;e!8=X zu9>_p8EwiAp?}-%WU8h9XvE`%n|ovYl3!)~^D3Z=)6CYGTdLm}&VjP<$`_e7zb)Ii zu)02FcGQd%ei0DyYJh3S2b3s8;lR1W?~aBeLPK%P?nP00;2<4HeIWtS!(XU0(e^Q) zBI5z&!Afx2&={?g;gIqg)Xx}6bx%iNqtx@1IAufAun&j8b5t)DVH8u=miq+Mg!IrB zo>UboX1x3{$7GkXLL5SQP$0T|y62<~fm-qov%{BYN`il<QBIxP?Jw~Qjf+YD?$n57 z@J&5vr}Feq10F)o4`f)XA1#kZc$6j${E{p|VIn{&4+MuGs50E6)9V`+h84%WO85tU zGguqZ#N)GBi@XeCC%F~L<ibPg$d|HTRSPrn)Rcp}P*q#Ncc;=y45m9R^9j-^m{j*8 zf#jx`%_*6${!N`SASl@E?TnxyABKj)XqqNQkpqIhMvr74Xde(t!*2gB{f(TsklQm! zf8u<~l9Ed5;6*|S=isHv2j+23(e9gwF99UB7Uz*YPQj{sV`D(DH5%W&C1J4D@i@?& zUNw!@BTAeO|L26ELB4U!!{uv6K<d<-g&m(soc0Tq(xi=E?3f`^b`8yJOm}&U#mcLH z<Q2|LZTb*;Z<;T2keC3woKJ^1iI}{s#U~>TdC`C>RtzmoR3tM48GV@v;k6+N%hv#- zg}v>y?cS|5wY@TfJCnjryh+9O`x33fD*=Tdo^8xS%F&*;$>4&SSV&Su4xB_;h8ku& zVPK{q&@<iJ{0cq}R{2@D9k{;&%OA=Z;Q-JxA=GVGhVGrW;)*~_T-TrIfo(oV3lb{X z!flV$Q<%U4V~47VL1;;#N@qtL3m_|dB&|>Rozj4|=>ssCb~TYR`gkR9gK;sEvktEj z-^Fumj^jX__OtK(^Y=RbAcPEl1DY^+|6}CX#dz~}{%`HZ*=8s)R$Oux;UrJwEdX!M zMs!yJ4HOtLW@+QZ*Ei}W@W;qO0)CtCo}c@?yoi9nT;VH+ku;j-E<BZwSv5l9sn4Y9 zc7y?k9ef-xleS4VE<=?*DqBAvli4ntDF8Pe<p^hixPBXg=__Q!OYg;W1BJg5-_ENb z$Q_q5r0laufabKu?!A6c>;gk2&>pa-dUY=^V4|2&Rgz9m6psh)J2AL$=xWOdUDGPu z%*sbuRzc7~#zA2pZbr`H9KNQFX>;;C7uIRJ&*xIPhH@OdU}NwFy|@YdKLC3`gulAn zS@j}(D2EV|rWN6%euR&Zdng;Dy4BST^Pz8wk<p5$ar_RzM7i;BAcl&g$RCE>%F7Ro zFH`RVWbw7cw*e*uTJx2Fj_X({jS!>}JT)OfTblK@W^9pvehwXp$I8Gi&_w}ldPQvK zv$U{>U<G$@=b%%B#-`<&rsUJ2iKKa=$;>HfTe3K8_xT1w&Ev%!jD$OZte**TFNZ3N zSJ(~vXT-FHR)|<QkJKuh_C&&;KxS4pd9z7X4m|8-B9hF2QxNjL67{6<peHW*HbruY zDdLIihF~?S2-QN~`KiqdiGM<A%Apb7lgPVkbZpd3S|{o4eRj}C9Pu@Huyp(EdX6)K zVNa;@LD-b%Xr`znJQB&cBrHz~w+KW#x`H7F!aahLq!b(UIV>BH{FSA-1mz1eg%W{8 zK4KnM#LyPT+lFF}Ai|xk3K_2qvZ8ROQ(b+~!Mzl2_6{2E$y>CH^Gii4;(RQzsaR^o z4tnC2wdf{+>^(L`h$I=$g)JM@BGsHB?G_6SiekHbnP<t(36UU*e-d#kni<KEDW>2k z3yh6Y-$`5#g<`l!5+(ZZT}c?P=r7V@xR>NLe>(+l(2qTzs1Pe{k?>(#?bND{HVFo% zhLIM9x{O=I(<6D0<mxVg29Dss)V!AwR|@34poSaCWy%^(f!5Ix1ha*5LBEC)jVP)X zf_9for{%!PvEJCR1-Ndh4?8grL>!O7<2CFB$W&y=1`(%0KS8ImY-MoVP88I6gF-_H z)j(YV#gk_poyo5BBqEDyDhI4sY6tOZteCCkOwK9i<mZrUl<&yvEU|r^7CZTbimh<= z5k9$WHKQy-jj>6Mg}P);oZ7-2C`bNHj;pzHLm{kaw2Rb^CP%J$B|Kj&vWkF131u*D z4TC)6I$$FOd`GUF@d--<Dlisl3j;i%hLoN`T-l%lpGg;blC!X#3p{cKDd0(T2_<7& z*jfspG3CnSLmTx~Cs#pM*K&dCgdWa2jN2ieiaqqtGm24C3!d|)$Sz(8pXGvQ#T*v5 zMvyq&cTvj}S(X&~$jB6@mBuBVxNIN}Vmw>PvD?7DwY(*vmV18Ci6(_XoK`lTDTao1 zH;BNDvEoZYd586r1wKILZX0b3u&_|b6F><8S7a8iRX-rRS}BwVP0Wcv?v51q1U7P* zgSfw;<r(H1T{2kc?PR^x&66Fx*Q28<+B-AUf~XtH<QfU`Kq)j3aWOPsumBgQ2kPND zm@I7Q$apy~9zSV=*|TNA7s7HmcEos#ggjAr6Xfp0%}p&H3ssLT!qt!{l4mz^<j@g- z&PSuX9M4Ifx9p_zmc>SeQf{ApodUPB(20^eoypT%qJ=Hn3Ke&Ogr<FojAIOSwj;$| z;A~1BO!qz^4HS`k1er2R1nB{&N|EVF9@&uVOl*r0AVgod7l)@aK%4VWrbDEwobiq} zL|lKFdtdcKDY5=fk{AfEyaEuspa*EsX{?O8lctBzdLxAMnw{7;tIz`J!(NIxvCA_e z^pVlyatSAA6GASDcQ66uqM~$6U`+@Fi?cQ157BpL6`wxsYqQe9uVl`EUsWTM@-_8h zm1&K)`L+=iy&-I?Q4tY3(Ab*_5>)9(4SA7u&_`F=Doacu3g!2rh)}HNlR;*PO6-^D z6?p|~r;ZvSn?#Adi|x=9c1>8Z1l}d?81K>%oyst64$;QsG#?H85tM{PK1(;SC;*%F z%4uM<{XMEsaIX-fAo#Kx431s#lHuSu9jikz<iE63sIW5vpx_eY^FpteoY_R}PWsK$ z>;Yr(3Fk_-;=U0&$;j7=&8L)-Rh%~_^Jb&tQZ-v>ED^q7%AtqRNk__t0&yh9)L0@} zXu@c)q3uO2Sn>SPieO8GdPL4i$*h)s^skm8O>JC2vPTrNSSfi0cvO=)EFUR);a&6y zJ(oHG)DXh!-eiqSSpu}hg5Yn5azCEb3`m!XH<9rVYUjgm@?L<lk36whA+}&xfk+{C zVAl{XP@49`h=C-=QxPI%AWVr#(vm0$sVFH5e!|9I$*a^TCosrEDlx`n2I*qwUPmZN z<h6h*5W3u!u#w47f`oNNZHt_j(4bZ_ggVp-YTkYhnhp~|^XdjJOcF2U_Vbrnt+I;_ z?i4~TMP*7VKw@G<JCXR1T44w`k@NJ%4GV}#xTDMn_Doq&HZ2h0c7cbMj-$jSiQHEA zf`T*Pxj8gpizqSaAqY3nsJcUlzT@LdyKV?VCH`OeG2Q>Y?z!jJCFB3CYsLS2qVE4@ zk0m|kU*+rR1JnDb_gBU%W0l*FE%IOGv&yZ?MCC^1Ze?tGc=~vowbFv;8<ok*mFW}k zZghGWe%+Zq4ylus8&>7&^s(uEmC?#g&O}M@=XzySX&Dh;<qWsr$LRE7NluNed<{Qu zO&`F5p#rF6`j`de_bNBA@aaQ9ImT8$Y7N$ZYx;x*$y#$U;SNwjNzed%#MCZx48W(K z{y#tkd8d#6-GW*tD-+WP1Sy>!>a@`0(dqpON<L1EmpcIsxeFsYJbfUU!z+~fk{NEm z@Sm7IlpyC5$#`S-L&L}6Gw)We8>)!MGsGIO->y^NeUP9ZL=bR{{u)qRk5QT<AwK<o zeiwE)4#ntO&%FJ2i;3Z*hG7UNVO~>mjWCH&j53}L7NkW`#1ddW!c@f>sprSJ3-f6V z$~hk9Z(aG`3X#}Yh(yULwDqu>_(Vj+EFwn23_>YM;SF(8<O~|6U<xrhW(i8Y8aId$ z>+u{_HV`93CZG_~`qxN)Bas|s_(Og$#xzX&qb36m*7EC3eOKoOd0=7JdHxV18>Y>1 z7=B-c8Fj33+oGv8jJxLayD-SNr}vv8ylKB5S%kO6M^<Yn!y@8>RXzqW1D4HI5;Jgp zAM1ogjC0<aK3JK=uEpMr$rIM}`$#f9Y>`;>9xcA%7aNP9RQU)Bx`pD+b=sq#&gp{| z$}AxFRIX4Rho+AiLni473yPDpgj?KOagr8yk9*}DiS)xpu~#x;kZ}do7%c3`l$br0 zkx0tLy!W6el!ZVJP6?<}`9__w2BP&zs`bkkL`REw6a6qmyb(Vd3rC~BY2fztM9i6- zle}d;`e6>aQaR7t?etO9)hw1QaXgsYn!>Ndvmk3ht}~nxh()0v1w98hc+w8XrcW4S ztkC3=67p@HBv)~YO&_88c3Ws==D;fvE8>|tTDb-r$N|>rm=~#WSi<Mj5G*W(!&mOJ z;E#ddE##K-#zLxa#1!DJC*v_w!e>2DiDB+9<%08Au#w7FtZdLX!+O_ajzG<0)X%po zcUw21KmHgZC3b&Lk0FxwMvWhW5;Jl8tCh(`U4?Fl%0Y$^oTlR>i|nJ)M_C9NmMjAP z_kpGAx29+vHA)i9>s>USh|K1z$YsJJB3L*}x{TbfaU1#c`|wHo;nRWJph$Mr!q+R| zb8vaxsdpuL<ug!kPCVXg#UreH_}tia;+4}R2#gZ19VTwZQ?GTic$01x$LS&G)+&9f zCBft*&*6S|H4?iLi1Ij5>b>HXkA<0lR1@6HQ4W}7k#hP(w6CPW!Ub1L;=L<hLW!*O zu-fQIHY7<y>}rA(rx<X$G2XaL@b6@nn7EpNf+ustL@EO&oaE<Pd1_pXUilVCC)ifZ zYd?Z5i>F6;0lEe_29@+68D2<)x`&;{#?T}P8MW6M#L*C5WhxD=EbGzn!(`1@i4#>B zQN+lGKoLGhws&>3Uo^vsV=2G1tJp)%UH2+=JGx3ewn8Rp$dYSAN8B<YsQ~f)Jq2|u zPFmtQEQRX`BmJTfxWIrg`*jpKNSC=muOs7pqv+ep$1HY?5kHZKM`NTG<1S8GgQhc3 zd%V4(6=>TcYwL31bPeeSjBaIwj;r<=$8y1dUC|>GWWS>Wu)8ave?m2(24Ytnd{ORD z6apPXlZANDBlK<M95okb$Uz!~>(V^&C~uIjoYT8a>tDS~>!D?%qQq399TVpKJ+hpR z!lWHuo{Q==@M`pHd2X7gd4j9(7_G##b*O-<k|O@{UP@0pg4m2(SJFS`E9vE8jP@1r zR12x9?;dyAVu@VjdbEAS@v2dt%9shRntUGtQiUpW17%AwjWsP555k&zhkfO9JOrCQ zY{jY-?gn*Xr##2;cr0>1AS*5Gz3tdVNDbYE64~vJbc|?agbu7H$-GCUjEjaT-0y@6 z=LB6o<dzL!I&qU?u7KLHdd|R%J^}DVagPrPX{;w>e5GMz=K^nnH)ACibRWA}L24X^ zsQgOB7|OKDS5VJAQoj{_Z)q2_!v+RIwlEIwLo=a%{uG`bC<jlx7Q@lj#&<M{Qe=aN z;kfC^!W^nQ2znv$nVW@&B_uLljrkgx8fW%3`nZP2QX`FqT@>Ui)E~)6j^b+T4*15= zKD2C5#2rRg9#mbC{fgtQX5SA_>cnAMMWa{?$?0+Ppn_0{`@cOZJV50n@_36xcgbtz z>=YCJraUTE>>RibEZR@+@s2=FbmIIca-SO}h2WUgR{0F1WaU#jF{$!Jl>C3g<S#3q zLLz_3!mtCx!>BEC_hyehNsRXK=_Au0iOx^O5!5dS`r`<uH3BTCR~q!8828GZgeF%9 zAW*lZsCwTOOzV!p-kuH}s9W@{bg>EOgwUkJ3!=%Qm3hJpHZY(9s8LsWTBRIG$Dja# zh64~vpyF#UAJhEjVSP-pl*FyS$+qt32;*v9uX;o3;(h8DldYahePdqqjgT$bp?(Ru zYr55^ys7C{|BLw-`Tqy~kIDak&AN4~6aN2e*S7rspD6$Tpg-yV-<|UYoI=n)b@#FP z{>wV|fP6^Tw%wmBOx?8xrtbRokY)FKY1M6Y@>ACzOk(NfqHhm)1NMXOEIa4)c-Bzf z9>QNxN&vjFe~{`c*YG9}I1f|}9Cm1GWC;4m8>rzo9&oLWIfv#T4xbD!@4wHq2^a8e z*VFl~r~i`f0xk$zF5tfj7x3Shzw<V$Ff|gG9iIQhkG56xr!EDha<RMwr{}2=bfM^< z`oZ$Op+4U(xOE+$>7w}>`K^B7hXt4J+RmrCJmVFvMRqQH(p{c`2@l!*z{`*kLY5); z3I8oR#Jqm!^Q@rg?Qsemc3{C5BGaX`(5lkZ-A)TwH?$#xgad<uUn5}Hqb&WU20fcM zdN?tlaeVp*Z6Ac~1)j?HC;JDD4$Xg>8ZUBFN>k${4B6xMl~Wy?BkJ%KWmuwrGk-I* zyXE0*@^J3IKRGoHvo7rtSF!n9J%cc9fIW;1WyKwjNw4H>wEMb1Sg^%5?;5Y}d~*=U zf)Y}uxgIMdM*m~wy>voWU5)$2<(joUjsGOy;8f=5!h;L*GZvh4>W78<8E@z>m8V8> z&{ak6!K4cc*Fe9W=3yKWd)Xq$lJ`%fxE4!7WR+P*^nb#kxahk<aq4>D^;mh^>@_?! zp0)R&UAYK_iRF`U6Gje}?k60QU^0k^J#1QP%rCebC)<Fna2u0HaPkht6o25qGUr=> zBk&I1P7p>9y%5-8Z^nFqw|hmt11NF;hMji6@6%m>w?=8rbNwCQRe%C-%l$Xu{@YIp zQzIGLMr&Om=nS|pQ97;r?|UG1^Z-}UFAwbVO5T8%aQp2pxprTn{NOwFdcQYNU2&r{ zgWs<t0kw-)>!4I@OuoG#wQ|v3iU+Us-;MlhU+x=ZM}=Bfx3Nl>_2^YFHQwVfh`p9) z?VsQWN(0cvUi}-erbZ}AMUd&kNRb1!*l|*?!0N|QLm??^`@BeFUbcLzL$7b|E*ox? z3i``M!OJ5*+wLea=4iX2&)Z`K1AHu)bgtd*<)=pau#0|e?zI~|p-QLv*KX*?xPll; z24!!UBN$K0eR1(OIn}$eX&{HYA<7Wm0CTm3kF8FU=3x6~0fkN<1#D>ZfXS71>hl3F zYxJSr>R=Q-%$snYRUMeN!WNC&6l}MBPQbwd6aKHVtP#rtW;Dc`yus%+qKgRx($|$m zwS>RxcHeb|24FkzbYIsuKz#7A7_o09Jzn{dx45#AI*1iyCmdiO+;w3P3@)(HtUg%x z0S;7PCtP9WYq@vn-mlxT+RM<}wHOtu`?h*nH9g_O+Koa6iZMJ+FLLI%=W1Y}GWxD| zM~1Kl{a2M7{hV6Xwe7ectCAs;;>&vfc+M#VrGcrD8n@n*6RxbFSX!iK7g%qT{;aPH zP9FDX-3qJhhiHE5KCJliuDW}rc&-*yI?(xY7Oi4AzzcR&y??^aJs6p~l<DJSn4bO2 z${O)ceG@d`J+S}Va;tGIG&8`~7s;DTbUlr^lHzr5YA>3-M^WLmQ`|@So)?-l{W&{3 zSjT0Q4YUQD-}6Koif{0dv*`Az>w*_19YfLo1{Z~*Atil7C6Qu<QQbp9{O!9x$p|U6 zU&0PiSL<tGqVCBFGFVPZ;c-V!@y<57aSkTkIA3xeOio>b4oZ4)W})_h8g87~OyAT< zcF5i{HJ;)7PjU7QraE-Svbf1PThCn+=EZ}_0>-{lC{ZmN*^|Zp)_2+5##>K{x8@Es znCD`Xs}YCIOu~p@aN3Ntl#!O>rmkJ;j+=jt*l4QfrevW7hmy*B9Fwo6pemdEH1&6p zkLF)(5wwt*1@GDFl_TowG`CBccK>}8p86w^rKYpxU+toupZd0B??L-t-nQBcHW3u2 zF4gd@+=}6iNj36QtBvl+uoDiIMt{m3yezE&Y20*-UX<IEqb7AJo7^YgkOHen@AnKo zly6Sm<)ba$5j8i;T=~Hyt8t1KWm3ROI#a&szz2AN6e8BgFMt?GI#53NTKr^=)|dyS z2Z}*XOpC~ea+{VKdQNUf8<uY`==z4pq<u*<X%D4Yw8Qb-$)ji+ZghZ!;0<Ut>?g}h zQZ!@_UIv!UyH26s=9Ajmt=Q^1Xvj#ROtt{DThO%SA+Fb-?(q2k*;(IfvbQ75dlZ7L zAx}ys_`$dZ!{YDnwE97b!$T4j83+5Jw{i|0Ttf!fDTm<4C6lw`U&ULN2sCd;JYkAN zKYLN(+IM<T2DGz(>RQnS-MAm;Z8<8{sp(63|2Xu?fY?3LTq%(VxB;kxFr2Pk5>r_9 zpL}yLD0#(@Aurs6vfyN)0#NRenN3|Pk-8Deh%xs`X^47MZj;+RV0(D#r$tc);$#SA zNZhsqM(@9(-&hA3*8`Mj_!yBZDL8wC>Ocy)*S|0iNNU#9r2!j#C?rKOrp~52J{q%o z+0@*|ILf9nhVYKlT%=;ui+gM;gM2OAoMLKBcV09W08?p5kt1?R|HPu2&DOjUl@fEj zE)DL9fAxxXe|b+yF}djOh%9AFcSPm`!Y*L+K77*!xdTr}y}Dk83DTu_8UBeG+YqSv zIXj1$`ZF%xLk`ncRTr>N<%)DHqp#t1U<x1!F3i_(>hqxJJQ%^FBHUezWxSlpZJL+i z>zdaP3MqUF9I{9ZXdWFzA;F%q6%2TL+&o==>3|xZukCTT)gE{-0wTcxHXOeK@9S9} zm&3^aujD@_|G%|s);^o?|6AAc|9i6h|4M$+|8M8igx^1P!Fg=nf4x%^g^U9Xs?BPb z4d_s+7=*1O>)b!*_)v+}3j>U@HYQj-_Wg6Y`&X<U*SFl=cs%U-T~P8?EAR^COxX&{ z9t0I{$Qp14K^_7&mmdn;f;-d|I`_2)eO|Fcxax&JwYP6Q^LC7YQbPB@|18^nKLvP| zL`qUEufuq1Er-K+YDg>Eqf{QIXf!c`znh&E!=DL9MS8B~sK^8@N5$WmqvHR}!&J|^ zg}=S?%<6yrSLG0s4buPmudh3PpWS0y8(~Qf+H8qdGcCd|?j>0EedrwG<;oAvmCBt~ zZfc^m+bMupGPv6w1kUi*TgX0O{ez4%I5pAFPgK%x#=Y`2yTAYbl|t4wdsuGr-3RAD zuG#1moRXV&7w%vAm#LeS)!N|O(8)tn6RD1nJ8ck}bK+8s)FFR5FpqQI83b*~wt8V} za1EpV^sg(ZEXcEiLbVd{|L&i|u|k(q>_e+O*jvsm$`A9UGDyQg0agR<hk2);_SCEk z6%?}2r4BYU4}xu>K_ARNfh2Di?q2~a5O{s-O&DmTEaYq-Mh2z~(t<YOrv#X_`jH+; z1G@yX)v{q@FDx?D?2zb{R;1Zwjx_s{_u!lbgXY`)IP`gYNQon>o~7~aO1MU|Jc&!L zpW>?7E#~9Y1-xGfnNrSqMDbzokHR9zgIa5d5WCYW=E}Kpe{HwTmte1XaLy^f^29m6 z3D#)=R96}6wNc+q;>FMb3D3=)PR`v;sdV#Q)_RE>X9u<q{c9K0ciV`CZ{y9;&!bDU z@AkPVPM`6l6nD==n%UVio@8?M>?!-PDPi{a)DvRPo@j<4Msxp4y1VDobbq6ygBMd5 z8h7_pYOv&1=PuCY(~bFj!X(%HJ$GX1!1wa$PM?3lzAE4%qj3y((U{NYhN%npuk<6C z?)X{4DH2xDiu(E(+&=#V)2LX_-IF%<f*k-qwFd2?odF#e#+|g>T;3f7Athf9$_3pE zlpkU~p!Y`$S!T0p;MXGh$<^=xH6<JUI=LidbHMxql+FTskJS#ZJCs1J7TE`Axx2o_ ziacoXKI-3#iRUVl2OODd**<m`2)JYj2#BXp4N>`gfh3fKH?X0n>C<@7o3~5sG)0UN ziwtZSE#)PY2y8fyLQzy?<ih%zjkjR>Q6kz>F>fe9@~xQAqaciTNvBh2X&>i=-ti+r zR=8hTAcz&Z(miAGIqL<3_|+DQRCd3Wy?^DwIXr?ZadU)!Y<G8e(m!@XR(QqsqNOH4 z=fpg_R7xo>0|nbzo_2ZoUl}HUNzA!4Z`zlrr^Lp$(Yt@nFVl{nLCL^Rb*Y^?oAI4e z;0_6CHZME$RTmW#ibBgz#(1{7-F}6`vajva?Y;PS7g_!JideQ@sOcpXS@P6@yg!z6 z*@VCDP9jpn;^N(?us?!e4$=*<PPF@a)QR$1M`{-kPTd?r^OGDPaR|{L^)RMeFbxV> z-n!JVyRh4FFT~t|buBtZU|GNaJ)Tw}(@7HJOW+>myk*7m)yfrS`fUaG-GHzP&?;*> zAcN8ps-C@5H+|@^($qxG0S;5f>0iK`|8PNoxB#0%xpCLzjkKCq-5;I004qkW>7*lZ zEXCkQ9IYMc)|=5J&0Y|N@FLA2DQXY88Q17{{1?#WuvwN9?jQ+&Vm-m^OB_$aasq2Z z2JH&8uax?k&Hf2H78obvK*JxkBkXp2gY3x{IU7Itimn$o`x%RuilpwwT#N;USdW^6 z@ypaDR=3yJ<1`j!mxlv4c3A&n-RthfQ-?u(qkfJPxv>F_qU7#${C?Shn0N7muiV`} zX!C-F=go0(nF@AfH>50-hkjWBa>;)Q(%Aa+I^D<_Do7hc6~ifLueTNS*Qk6ddXnm$ zj1M?J@~UStsEi^Z=9>H$=uYMCTHQ67Uh<T#<(O<pZonbA5ijGqG|Lj)b}O2kU|vJr z^u{A0!{n2^Dd<;wZ@~d=#mWSxTyXk@`dz~#nGS|ju?mFA0-7M4NTP}yk~g4mZuCdq z=#qHrXlj4LAz4sKTWH)L`Bjh{V51olvitUg8Kr@Ev`mNsW_b|An|yhYU1k;^e^$t| zZUG&u=r~=Dmu2_b+%Zy)<$(h!X9&ii<n;TtA4$(jcj@L4-3j_HHe}AB^tBT<R2J_P zU+Ae*g`ugN!9pV1D!8@np%2OOMx*Tp8M~a~*!&uF56#h2${cM)qFn}uW?E>D?BRvP zqBXyWJ2ea0gtY|Cr8)W$b7<DYnHrI01zis;0H0;Ez)kaS7PPR3_Lb1olc0;7Zq%Y} zkTiW-YTOmldcf!I^4P4dpY%((rS+lh-p|=qJG?^eM|en+q=zO$r(`e-lS%IWmEDvz z-KCm|qwh;*iyW#O3{XpF5?LGenr_i@-{?`TC#1Mivl?pcw*7uw*ZuZj)+rghsW+ez zFJS*O)s^}+cPNh%xZk9Zv{}$;^9zka>*g#W@RoHqYEW>{PgeJ$epO8jov1g$U_1SB zPv@NX<asd%$e+>X&}ObU@;k8}oC79Jb|A82Vc(Y7>BMrN3%aP}9$cj)N9G~XYR8&7 z8f#@(KKii4otvi)JN>So6`k5V2j^}tv`_5z3jKjQ=<$JF!5Rp<ED(tixKzYlR7ysJ zIh5VlmTX&t*j$vEA#2VttHW8|_ca&jSNZ+aL|)8y)e9Q*>NkWfD17Cx`7!4^c6Jc> z3^^#-nGEd1C6UKrgCt0Dwp*f6>T?3SXbmB75)Exlh#~t|Xj1{0UcMLmqS--XQ{U;% z&aX<Zrbp%N{3qMb!!`kmsU=p74-)*FP%l)}A&%<QHb^U1p%bWJK-#zM(8&I8jEqc% zo9=&ge{_r04sDXe{}rR_vKHhHEz%;TyToIb?g1?l=?q0G;f74%)<j#HW;u;WaJLE! z+f=&SvPcYt12#x1KFX?nmc@-^*i>Sc;Yz_XRC&q;;~k#d3PXI4N8gAFnQ}mergUC4 zd1oNQml7G=oul1*TfrXWkBfz06&vcCk!mBBeJl*?YtRnz>L{doIJXHK<Dg^ph1BlQ z@7fmc<_t_@$Q=Y(xkO134=fkTD$gTraOwh`#Q1rd7dSWtE9ve$b=W2=88AxEUzpP~ zKVdyE<HW>)A5<I)CwbzmEU#tRIbw-^&>Q>`u4!p_$KoS55O%f9PE8EqarU4?ejR~Z z_+4$kXXrLN3(Eq=Ms}{{lu9(PzlLC|Pjvj(@?(ns`rI??o?n~v|9-CJ|NTVyf0qsM zUn}2K#wk|&>B?Qaas^}KKQ>?R%2zU4Io=i8X5mF4e1q6^iWWXDLYece!gQI!txmpC zVjPp<`9x)0X_F}K#xCtfhP%@z#ElH{wkEs+8}DV{km9#06Vs=F>H`s^9Ej+qOTMq+ z&h!Dg0gTe=p0Mdt6lwi$E2dA<wJUV>?({+Zs*B_7ZJs5S*|K{*_LoKj248J6ef;kh zUE?}2eL#?sK_o_dje27YuV_rrvz;WCWBMRBJ1vh_DD}lFf$zr<?%3=^1~j*1<8|!k zJ7M9&uN&&v>p1=K9C-2g&D1X+bnN(-Pw#_48IMsKo$7I1#W3+TGE4>qoS?}x{`Yhz z`^sq^{5m=HTWg@YD>NIUEYX!ie@}SP|7F$F`BhJ6)4k{gLCcH&H{nIU8d-vz>#Hrf zCbWsZns|Xiq_BY)Av1x9RA2vbVqE=7vC6`aQL>d)DOOwZF=AZs3aPf%W2Cs!6;fK{ z8i^TXU|J6U`+sAS@Tsqyt$ZXFh7L|>@*)wpRq+K}!!=5xt0iv(i877VmOXkf0&%$s zx(kOcSpz0_6<HYF=W!~ko^FTX>wvESS3PM}&cQUnA%d;1a#e^8lhdaycz+6aJoxV< z-xCg-q-^P1e9H{YMZR701m2}`3MR%l-RE&q-nVAKgc4gfO#>zy$Lii*zz26U0c64# zZDNc0LOQ;84L<<{rB3|d12F%OuVf0kS?H~|#05Av=rWYMRKQIVEvR^LPuM=%X2yAv ztF3&zF6eEQ3-~1#ELgmWXcz|xgd3D?#&KHUT!H`pyz*(~V&xEi%n4vdqcAHBjZ@iF zdLwlXB^rypmTa-kb-3kSZLtn~tX`)L_TS0MXO$7?#jikm_zHN{H&1q#F0)%#<tx~6 zXgMG^LN<Xv@2~{UtfGO6%^77|!mrmGLwC@Q(LG5*H_%<e)Ly9R5>fe_Y6ezFdnn%y z#Ftm|m2cC>*IUSTF$1&Kc=?a>xVFK0`xOYt=T<&(bM-fY<l}3TRfSkwjG6Sgf&s$a zd01YJMVV+;9;n>oEoWgMzsiSD0;|QR!uv{5uDeQCm)*AL)iB*4{Vv^-z2Afatb7d= zpw&Yog#L`z&mq+l4BeyYIW8_8qs<!@_5np)A>M%(q5&tFKFWNA%@pIrg+P9=+F#qb zb9+Y@9&&N*RO$puHLPnc0>{_J77V;*`UVXIa+y<|7PMg!<^D<3fZ3)ISuV)7LZ%gL zV6?<vY-<SVhc}|hiNvN4x-va9hJ=<6-TZONi2DPcd4RNJnhfLAYd3{Vv>4<c6metv zh=%=xm7pfIz<&*b|Ku&jIKtGc%ry)sK)jWY_zd0@dD4oT+IV&F4fFT#8dYK&6MRFi z0V^0<V8pD5UGQgs4AQlLveq$`u_)7Cw8l`x`gj?<V$w=jZ$cx20CQL{2ho6!VTT;4 z{6ln}0iu}9qRNDyRnAz-Y*qk_ZOM#82UUV%27LPLipu56`O2ZTIKFZ7cD~~I6fF3= z^8Q{8<p|Z^6H?4w(%?pG;~i<6nINTznGdm+VZL4!Sp=#{V+#X6>RT6XC<z!OZG@ww z9bOfR7jlmABr=lJx2w#$D_7f*xFd;?RH)eOSGk&klBBslOpH}<cxmSww%Ri~eMcIG zQY&Os>cIDCTRDZ=q*@eb>qx;_#)?Au2qwlUya_y`Q+F6Kn7l4&a^u?EhkAW@pLpel z8IT!Sy>HPdggS1tk*N^P%15+8j4B&MI#g2_Q%^y&NEf(e++P^!-xz)~DY?MByc$^` zK9a?s42w5`J4G`RU!kBqL5-W_>&vkVKdPLJp*|J6G%Z{W0t(fmF=jFy0g8)LT)uk+ zm)SnzSl7suFf6~v00{+tLWXD^5Xxc+teqpYP_M=cNCk*WE|mfjRkw}nbVKmCu;X0A zb*1biaqK7*9FYs*iP+jC_195la<x#U5vr7Ks6~}XSRi3U4<Q4n4K%HM$p>Ay-<{;E z-brTM$CE2M+=AUghniMy2_n7}elh_&r3=(mra-0XFjUwZ?{v{@J|Z_6M_f`uJQ!=f z#<McaY=*0%LJ=ot3xbhL?~krAkp@0f0VWe&0s$NQ2;TR^H75!5D-?YdE0PR0CL}Ee z3L7huEgv|NBpu*2#bnQ~+zbn#7RnMNX!UoY_!HVSf2YG-wU=WHLAzGI32&_jhJeDM zW<TX4SlWX|>0W1O{ORe_Mzd-SKrGn==qhsLgz7NjX|TL;9kVFVSTuLQhmBe7kkFAp z$+lGvRVG$UpJ+2fW!q?$Um*!+40T_mwNxchG~;k(^u@Lsu-VGD+&!V(G%myt(8$6a z>v(L_F(PRzA4|!Nd2e)RK4!qqRz4vO{$0My+ETZ!`bb*L%!UM=gqDpWN5%29(5Kg> zm^l3|ne@da@fIw<eXI*E2y5FWn}X}_0G&sS6W2P<a@;MD<X{%uVl|w^3DX$C&MV4n z(~!7f>0<^kE=i$dD6>ruccSP;Prv(ZA!SJbJ**m|Qt`5&m5d{oIxd9)UOto3Hid@7 zyC5AwNinD_uEpf?HbQ4r(pA8r6~>Uf(MQz|c;mPmNgvvlk+|tcnd&vNT4`4R0pFuf zC5ih8&D-0&d|;xQfV_}_n7z7TBrv+TtJ5sp$FqGDc<4UV2=K=Zb+;N*^UFJI+O+&P z>aex8l$(dNLZ~}p8hipatnDv}P8?1F5{G8{B((-82Kj$Hv{a5N_+crkCP2ivu;JTp zk(1F;HdI7-Vqle{B$|T8$Eh7=Y%wt8Pz6SfO5{RQdJJP670Cmmp^V8cKim+!7-~F- z8YFhdb(~V97>BG_M;hbSTaR2XR!1F2`Hje9ZG((Yfg}VumHd&TkSpIvfrQSng_cOV z2<{UL1t#lCAq(jr7$C}#*~_B(X<w$p6UA&1!!5_0m3UsMm}OAZ$mhUnC&OD@F6dC8 z%&Nc>2Q$Nx4wq$YBz0i3N~rPA6o|9JG$S9Yu#s{iF8B&2lC4!6HNF%TjLY@c2u@ns z1n_&bQy1Yjm~t>6Y!>Lapvi5Zh_MPqeFzlGg0n_9N@>&&Js0ni_2O#6EZ=58U$f5x z2{*|BUoaNCa+<$Y<?Ywm*0B<ICY+yj@Y&)ca6d9g`5@E*@k%M@v$ht&wMjxzj$!5Q znLuyD0=NsC<Ee!0GJ)U@DQR~NkF(-PZWxDaXhdcXi3+E+74(Q#5Ip?5u%i_<Q_L#T z4dGL+D;hTC4(tIZYtDEJdWd~a6f2y@kI(7jXbRr1(u8iXVR7|9=X!1uAoi0v8PBIi zdC@H|0KM{2(i<nPcq`KxZ5}tQXeFlY-R<H<M-ryamS|W=AK<DN@`Zv^hd#L>EE*Hc z(iZ|*H{RJrD)hau*fjR0z}>~bjN<M?cJ(oZKy!Xg5GH3qUC2BPLfi*zRJ|O`G{;A+ zcEM1k3@l9h^s+-o+S87ToXiBdCpm%y!4%wm<sva5>M2VcOO2C9+I8-i@RS95<I~F5 zAU>Y2d<MeKmz58-^Ob)<o5>rZqs@rbS1qB!YeKPp#&G)@g~8<60`e!E2Xr*QE^Y|m zeRy?<>fRlyX8bZa!BfKlM0H43jrJK*<W44{0-&v<OU;pp4uGO_mz6^DhOy1b#;Q>T zsDDm|-Wk#iTr0ppG7GH9(4iy6Sd$ikphjVI?kIGv8bJw6Um(Td+aQ16Au|teE2uWh zK1dHt&?b6sl!RN7Ylc}JqXRDDJENF^S!v}eujbT{1rdL-ghff5Egev|mJ{h=3?y5y zXnz_L0wU=c@%$p50dz{ZYc~+opz<|u1mqcFaKcDLHz30y9g&5AiTGw>ig%DmlXOL8 z=Q$mUCD+u`{Mc5chDQLEg`ARk;z>A?8YlrNASap__Aew>0`(&e7up*IFV<rws1_JK zY=V%9hvmV0*f1@C!pq&=E5-Xe+}lwE1(N#tTw%X%#EJqc;Ot7H3F9lE_ch2f)O+MW zG^)i~fUPMS@e@y8(1mCP34j-!UD1x-Dc6+H7*NqNHZB#;#TgrGBcHgF$J#J?Fw#7| zg<{|IaUSg?t_v4xyZoRI6U0jm+yH_CTHq#|9Jhhatn`Kghdw~M0P@V!)=G;{fP{PA zxLA11?pP6gA>N4{iba-P5+((#>83O=++sDD4{^wfJN<!~nEDBu++n%`Pp}+A79#10 zhlHqn&)#YY&&P&>L%_rs=fnHDW>HiZZnAtjN;GmaniMDGqcx*QNFQ46*_hHv{<F+> zPNhbeP?+&BNzP<k7qUUg^Q@pxvVqgWx9~c4hcwbovSp`oyW!vzz%S_Ff}J<(#i)>W zkL!GJEb$uTi-2;!^b6Hg@>l>19p?F{qF7W;l0#SQjOs2Wg&F|+e?-<~;rDDZ^Pt@V z1qh|ply4$Dv`c(I>^*)99s2#3@ilzb!mj^A&#AbbUJ~MOGVvb4*4K`LVJs(<m&t@< zF2-n6sL`lUoE<|+Wk0ttVR5P*d86h>vxs#U(`y&om@aHQ2T4~X(j$G;=@gCi2<IHs zj8DYkfv}EYY}HbNgCspT1yj5#4V$M_XDn%Ayr;T>ro;@Pqn@j*Mx;1+Mj=E5FTBCM zDT9dA-a9&Ckwq$BNJ|hddZ9}Y2u=7}nXgl<nT__LCS0><K52+dJLsP^NwBln?*4SZ zNO#;GnDe3#a3tEK5I`5&Lr)nmW>hU#_)!ZBRzi;Fx+W&LX6WII2RY5Uv621UHIV)U zLrYjQRee4V8AJsOXY43-={?<cd|Mty<B%c?LL4JbY6bIHJK~A(!KX>d{~hH+Ed3DT zfFgH*+R?<jAfxynLwzeVg=Gl=Qak>~v#Xz5yDk?0W9_r+R=47RJW=sKXnG_=fIJ+# zG;`|kV+;Br>#UBSd^k2fzwhYGu^;9}F3wF(Rwqt$S~Fiyz~Ack!%D4Dl@IS8n)&Q< z_3~{h&zk-G-Pt>z%zSnB;n@4t6PF*}`R?J}d$T7m%J$40IW@QMplDNDdIX8;t*g}| zU(cWU78&^LKTf8{ivY@*FRss=8r3Od7b*f3e^@dWgm_Mm1rbkdC>BI}5L4RS(n`0~ z#>CvEvsdmsoS3lMU{;j&wzVQi{3`BY{8i&1$^B{ouPeZ~mAi#>LCi`v09yr%arWpD z`4$)G2N$b{#~UqTz1Y`NiV-{a3R|Kws|T+=9RENAYQ~b{UIqMm=IlR!<pFb=y?CrT ze!`67OuDP2z&0BOGtT}zGW+47>U-zr4%}_0tR2;}7w5nHs`~TM>cNY1_r99>;Jeum zE?3VVcsO=!?(mP*_bx(%=TBd%T~~Q|>Pms5roKz&bJcva!?&x4@66r%qI&Q<Zr$vs z$LGI1AIk^(meg9-D<AUFXVuGxX20IQKJ|i2`FjD^TQ)@Z<bq?>UQ`Ene&6Tw`#-^9 zJ^$0}_xoX<Hv(`a?WpbPpp97C?8wj6pFf}bem`%<Af-IKbCcgL;?m1lX>*sq1G!=D z%E-gpNB(=_T+I^8p#FgLn9FH83%0~iu)3<5W^qNo*l^i9cW&CcbMv;X>n-xxvqI); zTVlWnecauFmj8moswqqhsn?-g2U=>b&kNXZf9Bf7nRidDw`R}WsowpRhj{M#_tg`( z=FjfK#whDo6b+&kN@8a(B40Z@D&B>~c67yBx^q+a&dpn2wKjK?{ch)LJ2q|DXmxLR zWs}vt&Dyw)Qnzo~@yfOxuUoIbv1RAx?OQfcu5Rn)ZChV{W5*6CYRg}=_Ex|68e~Xp z#EoNfmp`4kI0AwW$bt{=eK~h|fA!nXXUFeh=TY-#_FeeziQ_Xz_o0|b@?!PF<1?pk z&K$ikH*y?^ACCPf${9KGaPnB}0|p~$7qKfW;ffAbhVpkx`?!|biBofvAI)6)2HQz> zf!L}JEZGz`l%YU86brYF`5%wNM>KXHD^xRc;=_lNUqI0_pN`JF|8sTxlj_IE`5DA( zBOH6~`lW}rM_~XT-u`}(2<-WvKAYcnZg%36>ZQ+Gcd$N!J6Oe>`eA(b%w2^9E#NK+ zGw8eKkV(f0K|5qzfjQb`iGLfNo^mgIX(#0KeRL`m#B^t#Kgcdt)H^tPFMm}1_R8G# z@7AlccINES`IBenE?<U4HFx>e%m*I>zv7hYhaXfAy<Z)LMffS_?^3|us(tX`y`N`J z-sWAF0INxSc$~xl2%kCnN%hzyEbG~C$C+=Y!M>A}>mSi&v(=x^&m6fm`_tvwyB}4* z+}FN&dq)C}9sQ_@!cKX!Ak_8D2Nz&()zgFc3k8A=qVdd^2Y`9Put$Ju60hUZ?vXF5 zcgEwQt`5^yekH)!$}ck}yL$JN>e2V18)xsFg}rI!%5Zx<1h$%``pNsyxb}KTYpoXA z+#cQ=nc082y(YdI7Q)=<ftgRQ&m8&445k*``PS8kWA8nj_&N@r4w-j4WI8l1V6vIM zCP2CYDlUt!(8S|PYT4=UX3n0&J>~Sx`P0{HU4t7o3OD4hjzzF&o*#07Do|-<ElPki z{SCp<D6_okdA&IT!daUNFy*<p6CYK_4pfhf8eXSDs|~419QDkJ6La_IU}fW`?#-`~ z^=j_t$+@3L(lFBz+B!~$=ax}AtPG(qwyxn_cEGfrPzxoU_C|$6SARY}bL7JW2paXC zyLWZa^X$nR)k`1F5C1Iq>86dFcgh`g@*@dMPNu{eD!+|0)D(QQASUKD_wy)7^Ac>W z`e`xM{6XMvKeLt<;iMa)Qk^w~e48|HASFu2dU<+D@_nRSDMV7?NnS>*B`g9<y&!rC zfJWe4KpqHfPb0JJ;1-8JK=x+&C+heJR4txTLCqkOyxje!uzp{j5C$v(UdBI(dwr`P zzMponZ}r}1&;}R`5IKNMsJm&HWMg_7>^PZ-l;Zp|u=cv8KC6K1CR2hP852O&<&yvu zMc+cv&dI)Q(OXvLu6_(cMU(@zqr-P$4|zE8`OIgNAgP79y3Dr%hd*QZ<Jrk?XYafV zGYS;h_?5f#lmz*zKYvreUiw=L&TD?r=oPm(r4N3$Dw^4w3t8tK8l>yzs}r9l!MZai zK874<l^y?4tfmAiH%1e}Z^^&{GNc`wym-#@^U=9)zKpY~Bx1LE@WT9oi?i?DoY}YE z1klxfD=1exq?rHmtC?$`&V2Iz!@FlCX3+@a1(k00AKzC$JfiLx%n6M6*_qQ{&wP3W zHT`qn&0Ri^%GZ@N)T}BdbG`&%Hu_<>YnP9jiAx1mJ37v~84E;4SOP(ZdN4M3`O@6Q zeayGRLo&4t9)J(ut$uNrX%jfy>V;3jG=e^X(8pTa*?pi=KD_s3_0nf7eXiFry6~0r zBR5bEyt2;>&W)w$cwG5NP~40Ivn-U??q0^R_yCok1X4HpkpkA0K<gE3SJObYu_Tl= z(4th!2+mnR)D6wkkuf_L;&hRUm)I6#S`4?#TScT^C!xA3h1f}62hk2M-!1d>y)$>> zZ1w$5e@XWTbBkF&X$SGJEb+EZE{If^NPmf;ciAX0x9^|<rOWRkEeT$ig_%xRPN38; zPsg#l;j?nxFznscOQ(~#TUc6=jFE!1#YHIDqe{F$Y;AQC*B&K_<L<57xM|-vimFA+ zyTWhLg7x7~n&R60yN8YGi-EJMCrH(^7iY)sJ)ArST)GZ~b>_$^-tthW3nktNrCR;q zoN&V6G&{Fyr*9X6Tx3TfidD1s?#x~O$OvH76HLHWJs}2Ho%w!v?!u8cZZzZs_28dO zh=Y0jHs}b9=ydwY99|0hfh`qL4=f%Ks(iTe$vQl<dTtyPYf#3jM^4YYw{Pa`<(aSE zt=<{`?}^W2Ku!6$RCFdTkE8Fa%VT-380IZM1?w0~X<ab9Jh((<Jw+@zVzH@sLMFi# zbLlf+B?$;2zmL=v4Lz8A836%ju3fAiI?i>QQfmML(_W=O{<ut7`tu)ur{5nep6cBj z44?7v?unTrAK{h3)o*|3NJq}iA4bDNB$)t}mqUrmE9{2tCE_u27rv<;x>h}Ob@s>o z5vP%Gy15G<&mFzmAeau1=;V>v{9!z(i^eqpq=N;|Z|Bbc6uEmX1Ur{y+ee=r^sN_r zwvck^Gf)%$<Vbbwcy-^z`Z#bde2&58!sq5(D;#M+-7Nf*D!}^98F&+QxDKG3y>o8v z=MnDAByf%e_L;A5fsP|iCnMw>o@9=Ht0U#qv=A95A1QTFP60EQzGbHXA=ri!K|46z zsfiZhE0E4+FEBs|w5`}VFj3NJ^24!9u>;>H52VKpfi}*3c3C<K)@lG6X=c70fsqeg zH@g~Y1op(;^JwEba^~TkZy+}xiL*Z^G%A6q3!j^dscTkIaj4teg+tXZBmhvH#1=f- zx71TMvU%}YTf6eEBaty5sU)07KU-<%_r`ou>)?#4?$IvZCbI>xMb3HSOI^!S5^}5O z2c4j?=LTWz?Y7b0Cq31%R|8(F;t-5Vg_Vb^0(h)qJLr6P=itoA%QMIKg8*E;a4fPF zXq67g{^p|8UXLu(q2dv~aM{P|>2~};T+khm;DER!xZT{nGq3{G*C8i{o}2mdUc00g zP`*q*Gqm~BKhK~4Y-a4B(1VwF@ic3XGe@p1=FaIiLOdS_=)^s^Tm-2zE5?*$NcML` zvpt>d>lw4k*#?@8u6-Jva3raa@5L$O{H_+rkn_PdKJ(Rwn!cof2-%>-;6XZ0Wx2}0 zb@^Zw)nAxmu~s|++#!3Q3mxRtZDe&PE>|Z{SC5RsH&nlUf9A{KB=_vpn#G*4dhg); z$esBEcW3U5%-y`EH&T!sy!mi!U#Dnh$WuW%Ul^2-j|$`~=)1@~m5yplWQrtC1+>Og zk>Hv{sTpu%?E4hSei29vR{H$;k5qsdOy}9N$7D*32`kXBnSY$0yZ3>L0TV`KN|&Ii zI6N$(5YU3i@Nb5a8Hkqx8e2@Z1o%t&h1jM|bchCwZUG3enc<5#!bd(t_uhLS;+EYk zv=<t%zrKy;w&9C-hDI)j!iskGAJO7X$7H3v`E_1Ft>M2)dmjt_>-lG%kK@0dTfL@* z|7zjC>f*n6BX6^S{mkzloB8DM%)Se_AD;gbPmUA_*yxq&ffH8S%s<|Jc=vs*9JF8s z1QsH|=B^!{Idvu-0fw}VA;5l=2(U|s8byGGlm-MCeccm;0Gl8As)Yb+A;5mE2rys; z3VLhy%mm0Nivxj~N=o3s=1-rUIW?i-z+y>p#e`pjNHcTzsL)C#9y1OMxu$^cd^3CN z^VyF_BW%{OPocr{r;auY2ezQPnv4URzw_11rEllXd^*4HY6t~;c;{HdP_R!%P#HNt z(Sm|S!(9F1>)GM)hm(h31Y<a`PPK=Xp<Ngp?EJX2)#A=P^W({xkt2(SgDr@D3E(i< z=-CT*u+hp=UphFfk+PQ+9441eb?n;QnR6;Qj2E>595(aAIq~k%gTr8YVk5@>G55pw z8aV9I(dxIKSI^x-FxIV)ReadP+vh;?gx1gf_+uzjB2etiFw<kkeaA$Z%>|0xx;Qs+ znSo-WZ6FsbgPaBw`{6Wv(87UYEI3!kf2w|boS)NxVtT^jkYd$)KUGhhn!EVf%%Pj} zKb>rW#eR)ov3Eyiu6>I0_|oO|>dXb56McTp9-Ti93+r2ijQw;B@nXj>S0|5G54{hI z>EYPEnSYF=A;so?eh<y3v<asm#o{D2kYZ#crClWrDFzY)C~y)f_T!^Qirqw{*v+fI zP^8#D-fIXccJxN|&UjoHZX!}__KTkp!*%oO+^x%k!8L{#OJ=No@f9?*E^188$h#h7 zpS$>89n{!Q$L4;#R|_>J8bPSB>hQHVYAodBwNYbakicX!{qmy5&J53=`lJ?WENm3) z)U!9<jibhXG@-_RTqJ6YK`oCAHFojR+{GgepvGc!p%*fxqpUrCsD&E)^`OSWXAL(t z|HU0d0UWpy$BmJAsNu%6lmu>!#mN|ZO~Z{5@$9EJk$qj?H-G$HBW{eSU^;>t0_vC% zG?qf5A;!36Nkd2iF~)?X_@yJp6rx`sVvGc$sLL0G7@OaB8q~1rkwf#JpM(x*hu0m# zdJclsk|1P>v|k#43_4-v?1A}_%S!~1-FO!#*qL(;0?4YTFaFMYICg6G)8j1wSu+7- zFrg7Z7S8L&0c0##)CQ0-P2&KvIOj?QkR97MbMV;W0AvJ|ID!flOz2~uHUJ|F$>V!S z0z;+}qd(9O=TiV=DxnaFlQQ&j;K_dc3Vp(UJXsq|cJ>$(E(}ZtD(Aab(an~G(m0sx z=GFPH_p^l9Trk<4bMrr)Wc>()xh3Ms4t|%wlPO7!;>iwv7vaf18Hp_7i^r3Z`aQpY zyn635GoCD#Vt|u@qEbEe^DhZb#w}*W#RMl~_7W*JF*up}GYKeDe<tx{6DO2n7mp{4 zB#;L1WGe9@@MM$688E|#=L^P@&F?#-+m;Ydrm3_~FrF-a5_RiyQ0Zqczbov>wIO9_ zRG<7RF7>_K{bmPmk4wOqUAnv+7_;!%fHET^T_Y&7^AqR;QV(dxz9gZlu<SsynNt%K zNbcCod;8`_KAE|2?2!S@c-<^N(Cmj6(Co<rnnk=f6==pJ=|D4nAE`AO&@A~ff|Si& zyi+~&UL0r^r8W;}#%0bQ{%HQA(ZvDHE`GKEpc&dL!gGUKK(m=E<8vclBG4@4G>ZkA zg-334-<$|f<IF&_ONRvU`JW=MvZVmcxb^d2oSnJ-UUlCDdb!ZBKQ@$Es3s**W@q6| z)Z04BO!<|>n6Vsx{^HEn6T%V|Va&vnhB2!SUz-<Dx20jsVtxykzMVb#11MrIY6vs! z#8pR_g|84{cJWFrgc%(}Gr}ycl0I1oGu}_yK!SNVwy(PH82NTW3GkJxyQGh2=;Uds z9-&<pY_v&QPFN!n*0c$*#nHpFUyRLudK30%K1Bc3K+B>Z%Z4tCoxv;&T_!b=g`>;# zCEgr#84I;gYG?JtkBBHcaa|zFLR_6=a3x<Kt&>b_+qP}nww+9D+qP{dC&t7RPi)(^ zZ~kxH54Y}z)3x{7{j2WXPo1i+-Q8;i3(1MDK9^Tn{Cxjnw(DFRz`USl9Kif050c`m z@=H<u^I_;?)Ugnp0ZmTaJT5cZ!cavQUJ#4mUE|qb-}n3G;&Ix-j~Ahu4^Q#$!O1I! zV>5e!Y-tRjO*?@3-$(#+a;(qn3Uirh<9MGF0ZjMB?g5dei)G3C-rGi7xRJ{8<|$ks zvzrBUZ;++j4RZo(fDR2Qh=toj1LX;5#TLQsL@4mT7nU0*bUf$3+_v0DlPL^I0%$8* zl9*CWu|(6OnbgSOBnO!u$_W-o@ev6YMoB@u$?;MrtEGuvGb}}xh+gKBpNGGuv59n; zL4QMa5O6Wd4g1r<yj1glooBk*EdRYR_=%;tT1Edlmm2g>eQLcip!?8(`Cc6GZ~4E? z$BbJ8x^8ut`o#g8mK*K=r`ZerBfBpS=(RX#&~2#wuems)_c`F8MAxkXbG<OY({dx< zd9fzU_W4&yu2*VE8OF8QwxSq4sv?xwx-deUvgoHN#H$GNK0ol)+#o=Aq457Vc^y~s z(Z|a}@2tKAw$e4|X#R#c2-qx_?f7HTqwM;te^0Pf=j+{ntob)CwcZF!d?~~TMD$I7 zepN+(Ykz*69izO|vrX69?DpbQe4SHy%+~lTqDyvOn1^A5e^9{$%i@y?Of&}f)2}S{ z_%$yL9$BLKx&yICtMw_c6uM)htI$6dmc%H>;dKsll8xEDCWuf{%YA|}`#v9y>la2x zxqEjG{FS=*cuAyo9lLiDk_7&3=eC^mglKB$=Ea38X4Epa{wa_6=B!Pa`hbI1X=rm- zkfIS{e99AoI;w4^N>*#!0m06SSbpyz9_mYro5Pew(}A-?W$<sR>%tU;^>IJX$$ese zp>8W@+2q&_Ode|Zv>>|eRu4Jyo<My)t8USzYpJ!?ANo_>cRdumNW|-X%_8r#dCg5y z!6R_k$oj#TfzunWx3+k7ALRG-)mBrK&t9WN^dF6%^Z?NV=spyu*+NqY;c5Spw0zh% zf;d?OV*)^(f;cZKX~mE{CL!X+XgpjgDF42r)7I9b+!s6-5VCXw%&mry_x$?=jj7}> zx-f|MTt)XSoW5%by|d6<zf4fI2hLW-3P2F?sEXY0@PB#w5lb#za}n@anU>pWx%;T# z2Qi>r08sAxI{o$C%9WC%$fg40g=^G4aVM$$wTmwU9bNEQFBk0A+tM-)^7UVM&5na< zZng8BUb)Ke(1?`df4Yi_@2O-yH9+m!X&l0HFeW_*o+EQS+b}G1_28|}S5rQMs1vg% z;kpc;xW9l*{cON!ThZ*@dBK{dn_`j#mv?N@2Je&BCt6pZ5V3lS()DXc=JyIfz24r` zs%M%}P;Xu8OkV%eDBbp=HStX-?q1VT>%FPN%m8VXfrJsT_DCzKrDFn}TFzs6g}DoJ zbSGSD#l?rVl=;?++2MI|m!35L_(CCY)0L;3B0qp<5?>z}rGzx!yp=5vs!cSr+ERLO zHqY#i4b!RyPYyePtbWJ3KukhcRpkO&-CbDQ+_Sos9z@gD^<7pP$M!m_mZ>=ZWS=^1 zQE`Et`Dyxul%f1fTnHtCg@dN{=%b0`xdJmPgn_1Bv#g{|2>A7W6*YR$Bb~)ubf>}k z*mV%#5_!Eswuany(*4+48YOJk5X~Q)h9csH+>OY@J1gH=BqAwhm3osi-dg{%j3&3e z!s45UvBL=FQ6=8=Zuj7+mv>cMR9S>kgT|MqF)+Bj=iH@x=dD$Uay7n6$P%ci)r?gO z<EhU2{w@->EhNMQ$ub8al3x7j-R71y>#{26Q&Z!iLEZ-yio#=(&OLkk``NJk0!Jl` zkL@JAzF0KBVA~ODu?Lr$M0hFOPN&Xp&swAug#ROx{-w9f|J24qH^dspv%28zvcNFB z3P>B$(bq8cA`g0_!t%MDtL@+pR7ur9{Q4y-UZh-%KH&kv1t4EtT|IFI3Gn>GL+b3Q z=!!t)y@o>$Kh)8^_$AN392riWyOaks5x(umG}wF6|L-~sjtr8MBqmk!6swn(_q z(gn5OM3(Sg7Hf0dF}+020j+XeZ@541h&r*iEn#~;)5Gv^0=SU$_e=%|w|Xeuz&gy7 zV#J!#YI9J(@R*;(pKA|j9w;`Dm-)QQ(-PP&%3vu>GElZ2z1dlxwDAV+jm?uC-U6#Z zh~AY+dBtytTN;4Yp^VY--S6Fnr3G-KRJ}rT`NfMpYr&Z?_pY10bTs>U`M*OAfxjSD zhhy#2p9i{cqH;wNL5)=0pjb`iE&ZOQ;BqiDRb<N1-h)crp~$)Ud!mu0Fbe4)(x_=y zx6sn8k|ofFn+G9Ym6cL}z1_Mko3^?YNeGZh?~u+b5@UO+_dBFJ3dHd}x{7|8nP5+N zhy?4_s)KW}oi|N^Xs?Pf9GiouJL*;FdTCh7Vf7`8jExx}8mvi*C#?9`_x&q14;s-! zCd$<&$YRM_YfKZvsiKq5yG)8%PId+FeBzfW^m>zi-B?reT)$?(&^XLZl8b4ANv8YU zz8j5DCA;=KS`DB3iG&-gvzQQ<oPFqqRw@ecvp|#}m7J!dLe`S9#&EKh-bxUi!u|O& zz<u{>&189$8ZxUMC;>@(5~Ogzy!(S1hqOoNp&hVMvpCahrrcg3)irQ*5p;yfBUQBx zZFJ8Q&0*L4W0KARG>orT@KLq|vK|w8INsSA5-VpN8<k63lDHIh)evav3uVxY*kfcg z*7&K6AW6rtP{T#4172uFGKR~G6S^P@?mWYD0>a;&6c5j}VmLlRS&`aU9xEuz`{+%1 z7VrO2oO(H1lJSK0D&(a(Yt<9fgg~Bv2nt1m`6ra%(VN?rNH?&VIU+rmMw*bjKcBHi z>=@cnfRNX$hZ!x7`}e=bvA4c&#u=bLg4Ha@0}Qt-zl>==b}>O$V7FJ{vLLY6-0eK9 zCdz7Y^tYRX;u1pmgE)|nW<&ewv}iVLJ@|-jgs15O79x+~Xf#7Yd>97bgji&^=u?bH z2K1H9KICl(MVp}qG5kKyC7X=ij}U`}vCysu9<2$Y^)HQa6}nF5F;;qA#KH+hB|#=T zY!$ka#AdV^0wTypyH;?tOV=9AqG`d_fys7h`#_fWxky23dV2KiT9dz`n6qmOS)KFN zyBx{qH$-86DY!m%M_Bld0X%XCPne0jRxbrTL#kJX+XM6x!MEecSNyF$y@fvn5CLtr z_=K(>0!uZX<h$REc8^(U-y{1E-!FVT&6jp*I)W^o6T(<ZQn&R-;52q#ocFWxP0~4R zEUi&Fr&1>4{D0D_=LA^qz|QHAo7UW0ox20#<Yh2rf4qcBeM31>`+c{_JOsM^&oAT3 zxBO~y<E5!P9|GX_(wPsDub&EF2gp^2E-Pqqc#J`JQUyi>kbVNI%L7I@arY*BcjwVn zXN?w0#3V9Z-;7{muX@LJQ$=ut@=XS5g<G}HJc`>WA=7iUfr*9)sSSs(1K;Q_Epe&D zFpI&d_ZTIr^WfDr73QB^hve59ImtpaHB0<(;|~Q=6|ZC1j32No>{E#e1{7AR8^A7C zLjE;`lVriGbd9cedeRZ+gr7t;5E)C}<~G6^)zlodh`8?7u+c)B_MWD~ycYheNiaIf z(&(90YEY*Ug^f0!4#Gu~L9fwnp=lpDY6(E7RW}PVMC&4~h5a#Ux(r&-hJ)UpKDEiW zaK=Q{TvdiOi$Ik2f>L06f=Y2+gg)O^))~ERz);}?TV_xDY#pc4a40X7vKG@5r|OrW zDsB_j?0CA`Tt`Fe`ni17qUY*n#ZF1iqC2ALnqr9PCWg<R3Y(~=kxEut1uMh8)}sW$ zYs)s4vEtlHSdrR{Y3ftrcB6rLU6so^My8LTjatS8@QPH`F|{(Fdr@6Er5rh+z+DMU z{%x=~iudc$L`uZHq9^5t2u>a~GNm<=Iw-7*iz}Y4Vvua(5kKiS#b9c8^J0ckp>Q~9 z=<r%))AR$)nvat#WzfwHN>dePEw?P3ZelFs1}4-3F@|$7*m-P=h<lmYN`uZ;Y(J|H zSZXzTvol+*A=pb;nE_NT1}xUzTdLXkpAA@xA6=DMnk5zH3-=KF{1m?gSPR1z|1Q>T zmdwOx$5iu?O**lh>6mQwpa9!uE2SqQoCKz1Da9sY4Ha>-7vrNyFb-AJtDtq<gX?uT z)ycYs!pUy37q4v0(zm0Pg<DOd8Zo9*mK5B}*3(jrS%AIpcTl9i$c?*)zA0lm)c?tV z$Tc`yg9}muP8p~RQqg`aYG)+%AnG~Z@~d)%ztOz>#xyd~0`80M`{r-6lY{wwryTKL zrpIVss?(crgj9Y12>%ygeEf5#T&J_i{q2eRt=;|H_Njoan9uq3t@{&`G=94bdlH}a zU9bPC`|;tA_hEbcEpdD8k7%dKGv{+gmjP=p5K7;ntnS~B>=^Xr|FqTI6^o;VnK%84 zhI@QK8Yk7+p)yBmAsVG@Dz-!!H?p5Sa-BoIT4L$Qf)UvqcV+Ldw1O>Dh(WKPH<Ian zNUlhU3LPp8Oo{quUmw8xNcS=)WO_6yu#|i#@VW+?hT7{_&ND7N(>JEb3;K}j5>#rr zvPYP0RPSld(t{-gg#_~lhEE?0>EVq3mBN`?Xuw$m=u}C=a`$|E2GD#R$K2bGhEQDV zpb*T4jyrnr*f*FD$P{h_Z}Yzcd%0!#{H59X8%3h+^Q!C6mN1j;n-P~5<d5IOyHFmP z&xk#RN(LCG{>1q|(!w1x<^X)&?S3L)e7Q0n=v=Lt&~^S2wCzu@j_W_k8W0uPKKXA8 zC}jldXD!zy*8&d_lW%byPsyf^t9y#=Sbh*+??iGtNd#ZSY|zJ(?%R&NilLQr1}NBq z0h!SkUDqxaYxeUO81LJ*O}d~C7U8iQJ?#O*C*RDpPq6R3qJ6!m-`_HO-zBbC;}HQF z{H}}RQ{_SsS2d8~yRc|$SdYj@yY}GH+$p;MR_VrJdl5)XeC}*^KrinZBgHf_CwHC@ z+Wq>)ZZcy!s=T7*K8L4_!qC4VQobL#oWyV&LZ&?gU481~U>Vw{9!wa&nC|BV<4>sf z3j|Uh-kqi6DL)N_7=OQ12gr7Qbo;Ys(mItO^@eo?`{)k#94R#zKJN`9mdEUJ^<PNL zeHk|H+c@M;19Q8+ke-6eZGuv5YnBJ-VE53knO%oWV)Uc>%(H~@imsKaPlw?(WSENb zkLoHBm$2e~pBqfm^}w2?z$V?y^SQ25L}ucS#zZ`lhN?xey|kqlz|XkCAOS<w@!cF3 zU@1E^?|XjGS>B>TceUO;ow=5IelX8>zb&s%=J)3Ij_2eJ%5-aF?x+7eF4&&V9=U<N zimzw(*VX&X<l_1+Ui`Q}i*L*1IQIW?dwiRgy>Hu3x2V<d|Bh)Y+b|Eb)29bF@}ckL z3rDIO2+<B2?AvVpmZ!LX1;Sl7dvf1iwOV*Z2>ps&7S)4D9qDFXP&sst3s2YZZ~c-N z2|E-<qZNzN!?5s5qlB*%eVH&J9B?Srrb(G@zWe-$f3^j?-9LUPFLe=V<DDsn5I!J+ zE5Y+Z&Fp-_=(_$&k{7@Jy4wncz((Fl@7+nZ)_Mc}s&2JK{8VuM{*pOqd59zSe%su4 z&o==5$}xRm=`!-UXsk6&bM_iLAkP>SS$4>VpwCs|6Xz3_#KJZ&9f@N07ec?-y8&Qh zotfD*c_i~WXS|{q2fGC2H*9>b)7Ls2_xCI{_J0|S(fF)?zlVGpJV`Hjy4rsd_<pId zUw@}mZ}0W`C4Ebd`163g`M(HoeN7mwywv;ReCL~gr1!>t+wb@8dHzV>t>5obUnF?n zzd!tOzEh{IzA?Jz+Frj|KA#az9u2-{^IVpDzxK;+&hvpUoZbMy-SO-l1b_m1{tM9f z-SIhrJd^@|UW*&ngys5e@Y!X7uid*7jOK5ZC+qDee}32R37x^$SwmQiaDm7#hCv;L zvTu!A-H)UHj_Un&zui0Wkz*C{XL=*G|Cs6?#rN<R$P-w!A|rS5tO}65eA)SGfj?jr zwMUpp;%k8@A|vQ1<1KP3x9{Rkirtw%%;81A!jHfu$Pv@<=<Y)yG^Bsee6<Wi4gLAI zm}0(20N|K}K>yME>)jLZc&7$);_U|s(S*>U>)j3u-%FvqeDxUT)Y0G0bD{v>TdxkI zUoVMVHnHj=Nm$k6)Tj~=(*N>w^Io72eTH}EjP8Qad+jEj>J<7xe81POP~g3(tw@<1 z;tJFlC?#C4a$`+eh>&go-^;M{iA~oC`9bu0>Ix4}*adi!vMW5oSa-d<{{rtGl03zy zJFAEKxyLSDIuvl$^B1q6N|o_j{k3NvoG73}17}?CI?t+=B;Zx9$b|V!Zr$<)OYA^p z>RzbFQd%l<LJy*NjrZUKU4S%~2ljR8A{-O6VeMyGGAR+Bs_oi2ry{XAsNG^$2LB!o z0U^fX%En8J$`?=mOio&O93R1#l>NTXWp!se!!y~Bq?(XjFSQ*1vl4aMD${!(^~Fmj z)}){h_9>O%>H9_cK2pM`CEKLn2NUKF3_A6%8#b*!`Qp}g2LV7dcY)GA4ToV6K6GRi zOMVTZAk6DFQ2kiJhsDnnfh+eH<t<=jw|ZXYF87_}gdzNk)*CA(JegMNjwhK`^j|jY zr{~kyb+B8XK{l|1vXFCA4%{fF2iAtbn6yj0fCU1Al_kfWJrAL|*3C>_jnjR<#L487 zsrX;HxDwtVrKf@f7fkkB$hZS14&ciz;Xi_JZ~T_q@aSBSe30!yIorMpE_+7(_kNt? zu}4T;$z6s^B)<qH27L+s@$5j%KUokd`)73#xhgr1y9U&UKVWTD3c&o09`Of3Zy$q& zI7fI6{)wn=!0D@<!Tr2FnU?g23$8(^4>Id2=_UWPwV%0uS*T~7*n2kjHf=`vvjOUd z@m1Ki+ho{mKJulP28#^jcLIMjPlRPEYUN@_&>!SWI9Mrwi2|j*`baj0UJ8@pubBZx z@^qi)YOs1Ab5(=Ogzj%Zi%K&bOtR+8Z}j!zfcbzfal_7VW4>|d3tV-4TOYbz*3akX znMA|u>AsTfl6D_H<^(*7(9_G(29fWwJSCgT>EJ`03rXxgBy|%PB8fWylXhuz<DoLT zg$m#(y^!PbRvFt;<(hVm9!u%FCkTm*9y?()Ad2<L5f22y!T)sge!}3@7g4<nFnt@` zFmAvEziwg;_Z65qawobW#M2LVF%J|!6^<85C`HK3>y&5&%00A|$Mi&jEthbDR2J@$ zxEg#n<Op!5!DHJWvpqm)$-|AYkC>#z?;5-?&Cr84d1b;fCkM*b0`Uk#9}hVs726yR zrWRt0Cv_!A;73diSV?el8S>Fg5+aw7{W~#J)zxzwJeSoUG^%slm`iqlZ@RHuWizjV zi+^0wp(~)&U*|2r`!Bs@$mxwSck;CBE*xMe$?1nd`Kv(vRcJrSUDOmVY$IWU^Q8<3 z$k2PIcI+@3O_*#4{Oa)TX2O4GZ~9mXkiM&j>D@pXH9;oW@p@_K#c9<`fo<`1La^26 z07+A=x=z+6iS%-7dOL5x0VsIBqIyRcx!+WY3ylVsc47r#uLI07QunW`qg5qHcx)4U zuV0y$i)syKW2`-pmbW`JsXXFahG-#j{P@!TYP2RPFPC7q(JbP{d?bKP#D?qKG$Isl z#cUuncK2PgwzlN=O-TJQ+vtBu{HyD`GYrWS{^f#?8x=3X@5?6}8AVu?!cJ{a{7Zo} za&}a?1JV&^df^;b51xEXME%C`$7U)3DpokZD-ngr`!AV<1V>fmy3Cyk?Hbd4SMVY3 z0<avrR|lgWR4HW=H7S%A2}u|XU1G4|h^?%n>}tP9r>-f*JXm&zR?HUdj6zs;{PdhK zuZR>9RR*;hjaLIXRo=vznNM*sULK_J=jXC9ADmwy)8n?;DngN&_^-QYjI#c7EqEEv zXTmHvdzx346+RwQt$6H>T_PrI0jDF_zb3{56^mQ|E?`OiYeE_kNL-^*y15h%SQcNp z_{sC@CTU`q?*lwLXMCw4YU~Kn+Cs#_O6P~H*fg=QuRU=YV8N8|n;fW>4rTs_LWOql zIYRL}67L97P2QLY4;Gwxm{Y!_fnjYCZARF){`TtZXo(s^HeZP^>hcd(rBjs3qS2px zv|NeKfzpWqTpba{^8m^|sr)tMI;!}ebUfU|VNglXW9&=UAm|EX<1?U=xJ2rmUld51 z<Bii&5H5CGkx2R34_+a);ar`5fG#O4j&4&;Jeg5fAcu<NqaZko0tgK=BP<7o$;O7` zBEA`<q~WVXDQpO85S7HCD9rvh9rGZ<BSQTe#$Ts*sTrK4kwAzxQi9C-4P(2xX;m4^ zp2jrCk&QVNOHO$i6Q0Hl$M#iP<xsz2u*+~d9@QGtV8ryUEI&EGhM8%aw16x-sj5zC zQxR3Y6c4-p_CsYJLa5vj6moH((e;e7RLxNOR^De2BrWE^)wWcM!mjWho6DDWM+s)t zBFI$zu0Eit9IwKqET^qzu1u++)e52tQxsxaRMU~HU@knQqRossPTnoZ&U{?|QqV{L zN@w8pom2_tjm|hca=K?iP-r#Xjn9#~6RVik*L3rGED+^J3LABjEzhiLc3)}Qi!i5V zK@2t*p@*Zz3w}vx>C0GTe~_|1HfOxxNBbz@N!hpx<e72Uc48!;!sQ~wWwH$>n<W6i zD-FbZ+Qf#?zOYszz#Oc6g);4*=oM-ONE&re45c52D|{);(xk9_kKD)gP?U%j`_*yi z!W(v!%NbPVl`BT$FmuIx_A8#6P-mY!1tzp8cK^8s7h<ZwKUF6gK~m%5n7H*b&E#sB zWx6bnMS-Hbu<b!`RTr<9bL$R=NUb!fNvoIidMRVs7&Xf-41chPN5=m&uu{@9La9pS zC$=3unCNV<LYvuYdP}%Q%j^LomcFrA;O13};S&+)Gapbr<(G+2Q`Rg6%4gEtV~i9o zbBLx?7(ZG`imPi8Z1DI_A8&A_)$q6ZbLU;MTlfjQ(%<^}cf>!iMk|hWQAC9mPpDSb zH8>>dT0la`eaFHNx>mLm=IcSIl0D@MdgdhpwJ7@_PPnD07;#g?9hJL+8@iFsO`=jb z5DC-V>9P^x-=RgaHx>H;bFf&bEJ^h17NcgR)y=!4>A{u7*8}1gE|x&cnKQLmvtQO- z1_eoXZ^(T`2S1L-U;Ye`7n<Ek#%l79MWRl_uX_ekzUM0;i@0*<zuu;$z|DQ%w=cbW z?unlh-&BqM;}`kR@8#oPm5u&q7x}-Q5FFBc;okQQlrVfecgvHsQ}TB;r2JA3HN^bX z4mITb77v#LKcG*sT!(vu@L%o*6v$dA1qSPrKBy<^qduy}>$5(pChC8^qRp`oMEZmA z-5iGIOIs`Xg&B~&s-+pAy{e@eu)V6K8$jIAlvuE#enWey7kbnPLurKyHzheWB^5O# z%{3)~0FsyiNydPrBtX&t!1ylMcBE>;kePlcrW*E>^0(mdmr&dqm2aFix=ZHS^U4mH z%^EPDDl8i?m;i0aelC)mL>ZBKn5@<FfleDe{-K~pgM%kB#^!f%l+^d|jYBNi4D)<) z+_YxSqfg}5^B__ZYEg<6tUVLDePLGpfIk~pV^Z0TAUX3wspi6PR1k_^$ml3TSSfCF zscMr>T}deCplDbpa&)I|!}?FJ;=dktbmtxwC(RnWg4n3?kNNW4Ia<v+jd<^}iIPU5 zU%m0CKHJ+TA-b#F<#X23HQVep7=!*^VqComo&g8<A4GvH_=G%xKCiF7lULy&q{B+z z_={V<qfFNgoXH~?I6SHHk$9JV?fz_&>LT4;NgqhuhKCqIU_UbMIN{U(y85UffNpnE zc6QHGVbRkfwXO=?6ngO#`pnYkZWpB#da;yNZF+3_b-g%BJtmoS&(kJKy+}$uHW>|% z(<n;4SV}z>84b_VDoVX*N<9vlWslP=O1*eWU&FMz`#D#oH$rJ`+C;vcVT6))QR!?l zJ1`>qP{o}h(mKQFoD?o9mr%+|8ckyjL?;cP{^Ioo(K9t2{n<afy%mSm&J+-oRzNQN z2V7=!61j_<f?~fEkICT`7lBTE2A!?F;^f@*epRfw5Lg1Sh1$&luoY|vV7Ql2H?dnb zz=EGpbUZhLwt@>G%)j$&`835ZrZ<91$K+}GHCHdDPl6ZczApGR122ajg26VvY6LV< zucm=QLXYHa1v?qH^06c_*53i3ryzdre+h-!V7wCwRzsyEXKXFdw7uwSjV!GI&8>x{ z4RcxHX+_dDMB1H{wTYIM+0AZ6rRH;4QEB8-HgwwK#4Y`nHj!|);yM_%hU{x3ekc=( z@N_05oRd)in$v~|Cc4Ult{NHYMJ8}^v<*z0<ngkJ$r2|F6D#G}C?@vGhxQ9Oa!e+2 zigS<fMJ!K4koV5~m5T$MF>gj5qi1ggbBc?y>*<RSytmwp+=l*M0RRd-+>?ddfY6Zq zq&(-yO8zR81<5-L&u+IFg*gQu!CL;R)O60z9&^q$o0++woAi_NLFO3d6heU9RjbpE zX7lpWskyA&v;k=wH|;3u+8?p#Khf?#F-z)4%p&~}siGIm%WKKl8F_x|H3Y6&#lOf+ z%5yh60FvReEPpo9n1E#IKNA-v%6KMj%KfoSJe9Vclk(K=Oy(45wf_yqPh6M=A(^-} z#VOdih0$~DY~4go$zLfnLI6;51fNXZf>g%7CgmMeS0h)U{OEt?(C=>UZ%*;De=&3c z>Yn$RnY%;W{4?Q=I5%TAWsb@pVd2sGXAjrowcJ&ynahKRu3i*Ca>44qi{=MiZNU7T zxz&`sj8Q2Y51m-*(nYh2(vPUj@t-(V@*~P6{fH@I)`0mXWSorLR{E8`i)M)ra&rni z?e<kE2)X7}sc^BFRVlJ<GdJbRxSvVw{LRQ!W!E#ONbUNWRFwM9VCjgN8*_gI6OYyi z1qTmW`EQ5$k0G~XYx}E|>Q7JAx~DVMj<r;SL+kpw)ao8DjXJkO!;ZD;_#eS8ty<4h zyYA`Swqvcn_t3hHKK+N##eam{{v)*cA0fB@2(A5(ko$jxe#D~xM7#gQA42Z`5!(EZ zklTNR8vaLU^FKlt{}Jl?kI>I18nf#^LRbG0a{nRJ_#dH*{|LGLN9boTe&XssLhem* z?yI?;=)HgO?m@bo@sSuJNhWDKwQgNewsg&i>|#dIqsLHtd;Zm9$fO`Xz|CYPGErKI z%hna4z=#HWi+}S|ws7xq1>Xc%)3R_7gkF{kq>!hdz&WH1pTTq@)MYP_7X-1(c1kJb zG{TAucvd>fVOBZ#Mst`m;m88xzocqS!jD8}Z<M45zu*bTb#9ikn=EAf(m$;16Wx~! z_0W8&JQ-+dV2uyYT=f6KZj~+DAk<r|bN_5;!zA<K!r<E`_%XR56+=@l3a~S-PH^N0 zm<K6`CWRSYsCPZu;gE5|lAKvPmTy_Pdr3iet=R@{4yph6)tEo#TStpQM^&S$^29ye zAy(EcwZd%b^9U(f=(rYSuTT>T+o->)BLea%qX;WNIa68ps;gc7y4K;SnGSX3REX@1 z6YmuPTA$@XI%OLL<E)Tt{L&Q>M(5TfRNBulw_<uztpA;mA(0DUjRCAfQV>avn_lQJ z&@;D|wz<cRuC=5(k$Y0k7K}B<M*XwU@TgabR`0GCh%6Zl+pUG+1T<Hlt*)Tj6MIyS z)+@p>N9|9`R&ahrQYCWgA&-}#+xZeB#HAZg1l93X8{!^0ddGI)W>3wNOg}BMUD9+H zHdBqyTIG7=z@j-GIagx|uO?fHh2dIBMCbsD%&>9~D&|RrE!E371X{hah$1+I=(rcS z^d{r4xuluW0SlL1(iBVqR~dL4=unrH0(=la<)TK7YSZ4g+PZ>J?f~pUqmaOa+?~UA zz4{mdW4&RRKl)^O@@)<z;)bj<_){{Gi8^mY1!Nq>ugEz;W<~~D@`-<N=w_%%1vgUx zVf>K6amFPdXQl#kRoX2_wu=?-!_C$Ua*I{Jnyy@0tXIB`wb?Gpt<?%09CmD%tY3y% zZP;Qg)4;w;6E4fJ@a^yq3C)qHF334_!{>X#VYh=AgKBw#s(I9UD!amiPmM7Dxrd5M zpM!2XEsv0t&R(LR`--XUW%?8{PlJBp$~r=>XO;qM*?(LeY>m&qI!bEc)|7p<zawI8 zVINZ<yktkftu?DWubI-(41$Pg3JWoBemyhOdST@czzid+T#IGU#-NY(mCYX#OL(=R zY|J$5A$Ua`j4fQlqT67@{4?x7*atrhaMoGq5Ziqai&z=FAp{S~`dE(108PGi_`K@3 zDh<KZqBO;0h`oaw6cPQvrwfnncaijqwrs@nUwN$@CFQ)Q{Y9TdNlh&k!{q+ufJKT# z-IK~XRJ}ET>zg;sb+&qoO4m1FSUuZDwJVIrJCVTjwg5XE8;A+~WD=x=LS~E%?3^Pf zL5oHmfJe+$CvW^~)fL@@hHkIr=$x%vz1ChbUC?%8kyxDuV0l8ui_5LR{%TisM!FVz zYRDrZyDKW^T_=7rhG;|wg)53};uU}&qgYHV#MPDXh9is_-z6`4IqXq=M@>m8N|OCA z=&~YG1W^uNbD<IoI<(cua{TU=ZY8SF3Mu1Y2%J79#S-u<$&s2#hT}lbiM*q|Kej0b zYksrvea5m%N_+HJTG(O1Hd`)m+;;ZJ11#B1s5sDuhFB$wS_>3^i&n;Z6ZP&f$b5Un zStun=p)3Z)<`Qnv*@^E0A1MXG!{NOBR<Y@CaItUps5WcWl-Sg8k={%@;8qav+L#yi zovP;3YYHDe1)CI+ds-Y;h^(e3B0*kAK+D09hMf^kliG6U*6(n-!m?NWVjdC2R|_n% zy6RpSA*ZS_nAos-3^8__{O^SmlBFzd=C#LRPR2pft^Xozt28snw9e}hjtRFD_W1S% zKho;viCCVkTUk=gD-(-AygU$tT}W<i=^O#;#kcNHnhW$v|F;dK_lb=?Qnv-d3BJ*^ ziepWwFp{SVodWuwV7odDP(96B%lIJN)jIaw_C5k|!+2lln&>f5a2jHwg-q}pzscF< zPIwv#?Wwqt-_07klysq>X^N%?o}KF|PfelLbUJ*aN9PKTfJ#74Fh-POtjma@p{*U| z*fan41BMVsaXSBy5v!Wie5^A{zitldR};2;!e|V|1h5s#$n!2EGKu>Vs{VW~TQ}R! znVPeM$3<rqzp}SVGDgzo>9HRjnCULAbjQ^W>xsq)eXc6WBvbM-x>gr6i`nx)^J6;U zC{b+jAr;Ja1FU3*1T>f+5ImQmZH7q~M*n(7?sCQm-UOTnv9d;RXt$P;`2ek~QP!e$ zZgvvL<e9`s1dqhXr+k<Ovlg9@6FW$PQLpH6kcvdONK|e>QMYh9RSIw8HA2nsX`+B# zxDSZt%5mGza4g{(E8G*0=xM&qsIht>%d7k1z9T0THpmi5@Mocm#hIjt_5Foq%HA;D zpHQRsav*ZSZc6==p9_gUmq8zVYgcRWbmJTGT-}%-EykcjRSL-WB>Al(Yc8s-Oiww5 zyeIe<5#81;@t~<B_JZ_)tg(zuF=av0TYHz!PQm%(+a}V69k^z`F0Kz7CTsFfTm_L{ zhp3y|-C9v}X+xXY>H~Tk;3Sx6Kk>1%lOCM6@iI59TuDp?+py{5NZo@p3PLx%q?jaE zEfo^&NNx5$`b!7|Iroj|k0f<A?_*ya)t^kui#cwEP~`I>r^RZweW|U?&^!<$Y@AId zj8pU+s*%bX4)@&?DSj#_D%wX6QY+iX7bVPJ`5Wd6d|yT5WsRGTmFp$n9Dr@P+Y&(B zz6;^%Zk*e?2N1&6R)W94fK93hT^mmZ(mJTE$CHz#hpJ$HOupO|%kFAIUh|_>@RFiy zom$<Jcy~z=x;gJwmPR&SRt096s4g9-^`18|R`3=#1wQf7*b7(UUu-wac2^t}@sd|= zQA((7S$~ViLsPb!I7cxr))TjIAyDBVt7(rEExJlv5rL4@&hS1B+6ia{rRRzl6%o%H z97nr|JZ$S1*Yn-oXhV6@$T*gLiJQE>;bo7YJifj<w*9X#Rw9Y*W%B*xIBwM$v;8z@ z59}a1t<yZXM<@y9W4EGIL$1ea_|oi6mWVF+olXct%(fM|z}Rb~0C$*er9cHYk?1Ee zjuY9H^<&-~jIn8&0$XP@mTiAQG%vs}_S<uz_NwFRREbk>5<uoe6z%&%As}Zel8iGK zHY4V5+Gw;*a$`a`tg@aithk?m;l<6P_yc%<0}q05d^9YW$4<y$5DziOeL^y^s^G(? z;B<9MtqumQ(%`^59k|A0fw$pq6*><dT>9Jya?gsS%)(%IFd2VsF`4x0ZkLhZ9>0S6 zo?=SIc0hE(QqHQWv?fqh&o%*gqb$Wo%SpY<8qSP=#Di>-dW2Ks@70=oGoT1d^_vMg zZkmwi#4w6TR*etqMs1FU#6zntZPtd$J6v_7?YSV0X>@3|IsKa2FxBvg<S|!hbJFyS z5HrM8^{iC!PORQo^^{=g(z&e?v~Wv>-{iah(0^~-(>_Q{`r7T*1n1gQYbHs0G%D7o z%R(`LwiKu?Iau9I&5pDwae1(4TS~J_WXjf|un>l-QcwksHCxJKN1A`IWo}ib%IJH& zAtdIlDrVib+Ad8ao|1*Zu=TFAipG<NQ6`N#6sj^1sLF|gs`TIyD}!Ya$JwK020<?x zw<<E6PcfUO8_STlk7ecPTJQHGC7Q`elGUfAldtMeRX-{x`C2{=m?uTC84bc87JA{w zVB(LW&B0qW_Ww$&AesYPilo2!=seC0<dcR7JhnPfZA4=uwWMs!frcoxow6<`>H;aH z`m+uo>OiER4jgT?MWP@7N6tu(BX^>TKn;Gb0^^buw!(aA`Omy(%9uqg-ukpS0IxSh zGRbmBzDJWf6;}1qu91+OHB1`KJdRiBd|=AI$2E-7Ib;mgajumjeUB6jkqBK*syGhI zM9vNarpK6r?Ka#k-In~1hY0(*0X9CBKH8!;1mCu*7^{*{vMK>au(cua`CA}{DynG} z5X%MBnns;P^x?0jtj8F1Y>-Jr^5vnitbE-dls*!WNu4Bh2$g@@^9Iia>oPJQg^Lu~ zP>gE{a_=1clp2+~cN0g1=8;5EqBQNwjq1%YEJegohlq)Fo=|%)Zfa4h(tJ8}=dn#G z^!=%_hvYU6*r7NOaaB5&!qn^OPIJtwFn)#ENf#mj1a`G%Hx%|W`9GC*S4h!QGozT8 zE9S04UzJK~O|b_Vd|JQCsdvp?aei}Vy}0&sR5OkUg3#~PNbv(Hr;7d!TI_St`FGk$ z@d&wE;`(G5X|?Z`Wb|7q`g7@bcwDELjar)N&5+%Pwr1ll;E}&o4~9Qt<9!W^^UPS~ zEwK6ZAN$-4YcQ3s`)}Ty*3H|v-=|AWMb`n*wOhZ#Q#yHURZ~Ytqt+eS9f}66vVS|H z^qLTIwa%hAAX!X-2U`xtx>N^Rfh(?Et@^y!w)ErA|Ggv?*>u2opInc_cD2#2rI@Yr z+0bu`Ld0RvxtO!5xGfC2TBF#(8HjlZHZAt`?op~-VzlZs-fwIi_VZJnZ$$+*@i(|I zu;*c3ptCQo3gMA&<T(Y`wvDiLB{tj}8Hqd(Ap|CIyec7}%f?64gp=)%N^K2i$LCtd z!yRIE=GmP=Kptv+Z7r7Av|6^2W(Ew|ZJkp#1_Gu|g9Gsh*yH9SKw(8YlKf_DJ@Ad# z>8Dten+(|T>2-2dL^&LIB4_^54SjtqvBWl&)~lts<VEsO%p@2Gn^h;n<MHro-XzC^ z!Va}3`Bm7u-59abUT!2+X|Ur{uj59DvODNFDk4Y@jrFyXi1EoPo=Y*859P^MK;B}R z4XU8QHQF!>$!j4yz!?pbql|$c(|Q%p$r4v`8%I-_?%$_Zl>H_J0$slh_EaLfWC9_a zJ>0mbUUWMh?KTr~0A;ZhOrktiYB{yoH6i*ydgM~9a_1h%hG~Yr5Ag9hUm-F#8#t+8 z6{e$`-!>XuZGexEq&<iHwRcTA!%|SvmQK7yoWMAZ>cGYi3nwOJANvW$K>InTPmi8_ z+l9zoZTc_Bv%%qDD*bX+a7vXS|H#{qBO%?2_c04e!8ARvVDknQCSbnsp`e>zh}-Ez z;W!XIltR}0=8f%ecrtNn+beTJVD7kJuRzm&ywfnh?~lpI`$Y2e0`3-U=cZvzYg)hQ z9hu+#sgiXV?WeZ<@1gj#C(Z|N80G*HdSfplwzDaIVmGvRB;7n}`V~IUBL2v11|+Uh z_kSg*cOJ#Wc-|X={F#0JfVEj-xBH;klm|}x5=SPbfw-VsW@-oI_-^VwibPfgghElT zQ3G6%6(tXf&K;_0AqP1^O^=LYq>jikc829s^BgDdggpZIBbcubL>7rw{{;!(@H$1$ zsI4RK1L9Ps_AotgGzJ4yT{3~-6Hgq;9J;#3qHs1Ac~A>m%#r)l#X6@&+BdBc7h-v1 zL2wO{?6kB@Zi$$%TV_RmsPB%G3Oqy9PtgwrC64T6;y%xZMAhc;^{p;6bZ1L)<f4kd z!%#A;G7d(C37h?!K>BUWm?Wv)TsHgD0|1H|)Mkf9zJ3%3+apTG;CdEPb@*;Pf9HdS z<I70V?uU>K5rvo0Eb%7I`jg1DfdWOk1(-{ci?<f%;(-b=delej7d3OUD;dp52i!Rt zs9OJ?tk@h;*3_WY6e7@WzbaTAx{5!VVh6L~CAQH96th>RW=e@_OBljiB*vfi1n}EP zGlONqTIVw{2Ct>g$;~H>)L?Wm(C>#ev5_@e6d0yfA6(HkJXn}-?LKCXIO_H$u7oNM z1w-aL_nG~RjI&AMvM-To%1s+hA?i^Fe+~P_90pG8J#W%UcZ6U@g9%lC`?uC(aMyT{ z-iHe4VD3t4W?{vK9L>|lD!b=k1Fj)hn%GY^V8isBTjz;ZDb}O0--;$xTt>ANeWs=J zS@ZcrRB*FLhVT04EgVT$qL@p$lu9ZMsnKR!Fp#wKS}aM&oj4iu(Izyi#4ddW%o~1! zhvCC7jV@1l2cx5F^DM?FS@8)E%-Q^jhSsX1YMfUTG%3_e)rxbp5`ff+8H`@47{e!> zCT3qC6<YS8u?7|8REwcQO&mB9LvhEc#iRK$-t9(Rb{E2W$!Dtm_Y=2PYcLb4#OE@@ z=|`z{ios&ay%J)ReHc{`{GEb5Fe+CXZ|hn)H?(G<Rz+Ifnuz8GN0+Gdq-FIJO1gF3 zblV`feW1sSWp%?7)mW7P$JLn%Mv{B2?x_$zLn(UZgJnN?WweK}W`<7tGO?RAXEau| zhGcctuAzNfjor;0ebfMHAfAVA!w`6>3;Fvv$ed@wAg7Pug3zDdDOBs696MAn?-pJC z_n6))z(d^1kaC$-@K`27oFtFzvPjewW+q~7v8G~Nsa?}*wpv{FG~$Z2#Z7fOs{v;{ z(ea_enk%gUZzY93@=aEVl;m&uDi{{+$`yO*6ygZa>3V}x3xK_VuZ&at!`!$p|8dfI z+R}~`4f84HQ<1u!cz;C@NxS7l^m+1c<)L`*3ALbH1!N7or3;!hOuiTkAyXCTfq0*` z{fs!ZA{E%%eI7dIz5*;g-OD9Koa%W5{@GR&EFVdVug$!PP>2Cfg-5D(lS7qc16b#( z9f6<UHdN<f-8JU}E7o~~U2$JKTQxo<7WUMYu~=c57NnWVu2}v>Y(^WBOWdLEn{i?= z^KSHvRDST*7;VY{)CJsDulRa_yi#1Kxi+cCcKOhWHom<wV^zAcY@4{pX}d;rzZQuq z>ykXWj7Z+v$}LWR)*8c(+Fm_H^car@XA-`W$8N}VENOedbzkrPvCw4SxMl7IqG>jH zi_B&gKx!9fUTOLb(!LK)QIzj~03jSjj3iz>&YK;ILiA`oB#&F<4<^2g!%8;Ynb5ai zQR=z|KL}*bfi=sz!?sqknm||r@{9>T;%M&zuNE6Xo_Rx3iLl~O<<@Uh)i7IvHCP8F zvmGfUlgg2E&NAS|s8@}y#-Dci?a=mRKDn;<2I2Jj_`d54uxRPA&~a;VZ+JW5G+S-q zPst|b6;=}e<9g!((3C~U7wGNno!(BrOV;}KoW19zd^I_;L)_pXuQu=ltyP|0@c$@W zATBNc+9MZPavL=8`zX{T#@-!~eNHD}sD71hk+oeks!OTIHI;s~F3cbq?^O-&P2KL1 z<ua%-k9rN(=29V%rJ#&{9S}O*kDtaeu1NLa^UO+-DQJZv83jFH2;zH|Eb8PJ=}loV zYcV(q$ypb?#$r(Erm~+jE%f0?^`XU-8P94vJC1lets+jXQ%r@^_bS&mj;7{sq&ynO zy7MngI)OFMHA=|*yfZnK(9_~PWUOlRMipjP5P!W=8e!tkcl|IrE+>A*_fDgd*HEYh z^Cp_cxOxNO_Y#Zi)k9_vS<}z_v`&Jq+FixNFO!bKx^}OU=a1`#J$XQWZSG_xIevh3 zCo_w2nA~$U?nUoDrQZA#)SO}{cQXCqNTCQz#xncz8G)CFiLkcV<CdP$b%H`3%(TnS z(Gv-4xwWlddzX^6hnA>BxdaG(3lw?KJPdcqbv{N&pIbRf3gj-w;rzm;+f`~ey7~7L zI>@kd!_%o*lHbcq#q0U3`l4&CfMxX$@}-&_d{^r8RhB0Qqnr+2UBw^w&-osfpo4@2 zo>!<(PXHYM6;`#kvShx-{b#QBAp{`L=v#<jZxX?w+8VM{z>?u!tfrJ>hNlip_QlI! zLEg1WdIvdnQDmGZaP&OD_#FsO)k^=Dv<l7_B56IE2;0NRXMWJF%7c;=d-(XGj0t;3 zK7;~(q6Fe?X_7nZe%;j3VLI!)RMF|6V=&pKcx^J6<5Y6?+?~s+Cg#t|&|1!zlH8kf zS-a8w6o1ru*O872lMisCDeH~5c>HUle;Y%&#HSROP49L)Kvc>|Ly_b&*J=b>ahH_P zUxM$1Ea0v#I~%Bh5V^1mzET&h3l@Y~q_-mc&lay6NOACNtJojF(aP4rQ=m<>wq%!H z_BcLCIFs};wQLddok4dC679wVdHt0983w^pI2%zt&nv|Y&YQlH_?OI7d;`dFF2UJq zYveupP9F08JUVC%0-WUOdF?@?%nq_f(Wh1bIF4rGDx9uwO)z^{h9@`t&e$emmrG<0 zSdSq)OuOd=li2Lj@vj{nP$ZxAi#SdE8d$4UzE|-GLOqHNTK`gk2sCs3gGIyk2TTnH z$lD$8FRahOR==~KtXFLOO5#NqsZxlN4!4GOgrG*5W#qJvtZ-!h%w}^fo=DYZTo;0` ze8Z$2$vVD!Gy=G(t;O1NVI+=vn6-(DT_FWoRiI}vx?EPV_i!sF6jC5NJ7gbfi7Pl- zm@P&z;PVO5X)j<6x`TF9egniO*B3GSTIyqy!A{EpCncpYJ^8<+4pu6iTS}<ZpFM%{ zn}IBumOPI<8Cr#uHH)O^x5Tr0gOcZCc}i$SF-%0tC^68$Sy#U5Jq~t)tkMVnbpI6L zvK=O7H~SF4@dZN1=P}QY$P$uZea^c1lM(!`KR`Hp*mRTUU7syzQ?B6xnmPaoO#(%G zFm4TfHq3MU>)=4lYA=q~Hvh$3Ww$A2GJq@mk(i4rCrnO1E>^Wy6HL%t3+#qQhaD+` za@+``cBZ(citj2Sk_tjb6l6)m8#AZoPY_d<ygEQ(4Vg)vs5`2Zq_?K`<A2;Wa-&wE zzj@Wtf7^h^NHz;SJb=LpT10HUh+Ri4z8OJ3%gmvU)IzO)tMOldx{lZdS-Co5bWchx zB+^s{Em0evLm3Hr)}Sg%QBt;u7|4eQ&Cx-zPYrZ~#nmk`t)nrDlasOt&Hs?vc;)+o zT9|^UB`Sh8PgN{KvQ-tS^3ah4tq}3Ev<fnGh?E+nuT2Fhbf6!&jzoPhg8%2(OGu$b z$AxVEhtkGu9~aX9l_&jIF7;nIawV7(3E6+;)KEX=(ja~Flu$h{%Y3Mt$jRFNr^5oz zK-=an_5#iBTy^s<v*aXiKVC#uf1RoVX`|pX0Xc5^MXwCX-%Y{gN?<W~I<UfU)aj6o z^gM3;(nUduDW?ha&^D3O%nIvju%(i)7YX+opSXN=?1$Z4@TmU^i-BgH&qVb|MUl^O zKRFFxRB?jie)riQiq>>wr0snB$?jxEc{DqBvV43?cKIE6PKtjXjugoT1P8?lkc9?V zXYyjx5|(hi9;Xw)Y!tWTRBob1ALI*%e(KOB`Xe!z<tRAVr5X#)c-Q(>#g&o~kHAAn zG1d@0@KqU<C_uoQsm23kFtF{6=0t&Ze-3?DZ#bvN5mSk0TBa@{FNRg2!YMEz$E!4o zs#=|-LQ2Zjt~khFW8@f$rebaeQ~o%V-LN9xW0b1}oXEZ$15VL%wZg2WSVdVsk!Oc9 zl=}%Uj5cpAHgjL!eW)QK97qOvIw_haVrHIbZ|t3Kc#MENPLDA$zI#q!fe<d<AI-}k zDsLuV>`|!|KAANU*$(sE#ifoDgHsby*E>YDAH#0JF02Q;D^?u6rba`ZTdr`sKN}*m zb8m7fEmzQkhZz}p<-`odpcxHX*)Y#qC_i3)KYK-?(7(~hjT9Q^+K?>(Zd9VBirPXX z*wg5V_llH|;NbQ;zlQ3{Q}XaTaNXpHmaIn(VxEayPmla)7E<4>z@_e(^TKX2iIt^F zwVm2IGHEw(rN)8zGTMt@Yp6xHO0(P3rG|iOA17V45!93Gjq$SPN%|TR*gzIMwngfL zI(x;J3yt<mA&ULrP17mQ4(h%)I$#MRL5q>&?kVNHP`M?4OG>Hqu2SZ7(l@a$VV4NY zwsg>lE#v^Si?Ho_ZNG&=XJE6xU0-Qc%c>!-OBzynHVZ^sDXfx^zABAHHA<=6qFb+k zynp^~yWu2{@AH{FS>ZJUz+9Rwnc$cMTmu8XesFV?#IwK2<7#sAh4GP`RHESQj3^=V zt#o(1G<%LiQXH{jD}%Vih^8t~l-QvvW}c8RM34=Ql3n+pI|dY1<=0Uqag4`enc^JL zNe9{%TDUsGmcp3n>i&&+w2MzsOeyxs4BZX|#q3H&9V)u;$^R)t9fr~ATujm~M1zM# za4$!ET3|JC4`z#F$u4$r`#z!^)L-S&7W*I#<_cdGWtWJh`okZa*~<yemD;d<kWZF5 zC`}6*lxQAwLiYZps?Vq>Q+?`&yq1@Na~T5Fa65N7nO6LicRe?5R@hTP-B69{cnx&c z78Wan*&0l*m7fVUix5o46U>HBoP>duCm^LLuo;-3%4y)SiH+j_sm5TU%Zb(&R_;fz z_X3-ejaSLN-9BmRO0=d@G8d5VGa|~eQ2$^=W8c15wJpw|zL)puy73o-BaF;5QXfQ~ zv`RdutpS`5)(0ux9vLTvXej+E2!YPx>e@8rOQ?3`<dw%b3$|JXF0-N45@v_etxVl| zXRpo}VUUls-O<)1r#%dJ4?|YXW+wF)wswLm&^?!=&#Dey*@C+gmf%sG4%zJBB<EjB zDTha2s<LyLB7>VXWoTh4dH9;ModL*!I#mSOeMpX7btbz4&arLFm7zFncE`6(zlR#g z4-mK1sdhf?g7Yk_6K*X-oBcS$^?Zmkk>ev;grO!2M!0wa52w(!;XHLwP|&!5tKlp^ z4K<tb`mm3E(;18evZU1j%2C%QNO0}MUORK4>s%jvgfZsnx1?TREjl;uqE4<r0(TRu zl=|NDP)6#hNx9RS6q-wGCH0OAm!MbPta0Pb`cxWmq!e*F8x?36Av(%bG1p*6dt^EN z|Gh(whF>fvwVlDJtkOeA-T7=`;^C<0kByeC%MDg<o-#nW0AM9vbl2GbKkU6zkS$HL zE!?(k+uUv2wr$()-L`Fe_io#^ZQJhK`#b05fBB#8<BeDmYeiPhoFhlo8c~&%bI#L? z6gZ%1WLDQt2R%DF#R8>@V4ev{eG*HK%!c|+S~ST7?y~{pY2mM^N=2|jxyhB#0N))@ zC@xdRUPX0lepEcO9O-R!AjtCwWAhI3%E(beQ8akN0t!wvcaaC2nfg3xk=oWv&2f3^ z><N?%q*ii#jdr@PxCyZln1qwYW`wDh@~hW*$<q``_9TxYn0Sd&Pop+e4`U)6*rR&^ z?7%gPOIqp^)H3NV=B$aJm3v{aLIt4c)tUP--Oj)Vj@e1n@fn-tcHW5utcr<AX;xeI z6M@?KzXB?B5>OF;B^3ZPl?=*t&r+b%<k5l@<r!&jEt|J&v_|ZaxE^KO=l=vC5=H9P zD_2R%`{2<iQ~fo>oQFBg!v+&a{+kkLS!$El2WgGo*4YFaaa*SY14Rm0CL5?*s#xQR zVH1)!Po4IO4U(K!z1ItQzrIOV#tjNr7_q`mDv`_xyhOd&pf;4MRxG<rP_+yl*kqU2 zXF;6j(ybpzbf6+xoI^f3Pu`_jKO@lIsCK<nMR%#fDVfS74YvnnQ>(*FfVegW9%7h} zMulp!REa+F9f4s1_%TgVE%k+N9%erl7JB_q!AT&f{uk~W8XG~@HN=&W!Vow)W)#>7 zMS1k(UWGe`(0<0Y85kBWv9UqzmMZoeCDX9Ew~g&yte2ZPTjq_K$<lErk4<j^Y+nCs zCbKsj2#KS+hX{?1%$)9JkNe9hw&fmZ-?ZKPr-GzD(+u-sCLm^ok;|iYWl{R!U`q7d z5<R!$JY3E+4^uR)jmyPGbO9R3xtt}m$=#v{83DCPwx70YTN4+3Rhfh@ewy6bTe<cr z*eA^%jkZSyrK;};6<OqC``+gc#pzTzCVSMj+$9B{0SsGp$X6PRIb!hf6Ad7HP;`d0 zL5_jVblj*h10Di0xl8yk_g@jWM-YuOw@i;u$PdQW%D%$A?q?M-AukqOL?>R_>bGEy zZN<bV${3-l2%OfnHE|KVZf>MXVQ|w=lA+cm6oWQcn$c<L0yHWbEc1pS#C1d`Ki+9X z+sPEYOE|cz>d-u*UK2uY{vNrFD8;+5o}pBBWiFRHwp+(nNciYqeADvsiHmn1LyjNG zzmMj6l^u*5(5K0|WV8<zxHDV2jLwKpiBzh@a1WI#lF}517z=|)>aS#eZ?HeRj6zh- z$03S0o=bJbp;?)dhbCD^(UvmKNu;P}mx|<uB^RhhC(|I7GwwR-RbAj7&Nnc&B@GFa zOBjL^;@%0<ptxAl7>B$1gg224Tmh@Hlin9Zob0cNM6K+J2XL$s9HE{CrID>AlWsE` ztP{uFQKq9SN$%^RNH}AY{g3_Gw91Tddsoprr#Cb>eNIBaYzWI&E94%RNVz?^VQ!hC z5x!JorBut~fLr>^+>gD6Xetjnhao*R?3r=Gu+;)-ESVusvc8k_MUX*=l2mqk7_U}K z7-FUkB?EaTm3zpWvH&vvD<XKLoy?`$Bz=it*St+Ty|~bb5n8wNaNyr~v0U9a_*?%} zh-!I;_)i9DE_gjbNfOp@(qv*aFNurIdiMF<b3S?n7R%{J$7Lg5meZd=17oZx{3sc| z9CSJnuOO9~=+;QGR5@Kz@A4$p?G?o&S$is2Ox;p|scMoIagBR+#wvNY9e8pd<JO5M zxH5P&Ke_OBuQfO=9JQ`vx1gvPwbcY<oFa+NQ5d{Tqje{aITV+BTct2-X;jr;{X$qc zamija>aV+}3c@+&WM0j}R;Dbb(;-V<6>dT?m-b+rIyMExKEeVX=$Sk^U<w0H>A7iU zlpQW4lt)}mdYhe|CUO%9hZKH7`>H+|(|kvoKDU&v)^@QvWdH?qHWf5ucy0QBZ{`^* zy0p!VgRJ?=)-n$7+c$EptlaqM^H46@M<R0n_~Ia+&W3yGpLL95+{f&FI;0h@zntl* z2pJ&)a<9K8xRF@<t_wM4-hfCdy?{PV7iG~9LJa8$0T6(~Zi8d0cb})89@;jnZRlM} zv1SZ6uaJt2Q7qd&U|)Ksdzk&ggxhsC5k9IYzCV200DQG;+oP%invQjZ%-f#h*MA}M z4r*+b@<0ayDuK#Jq3>H85@eTZErC{0&15(tF0MdQMnzpsPsXe`Sky@WFk}k&ErduG z@>XZcdr!9=Tr^}ojSm|ttRBwF2IF}Dm^Gr&1Sqza>U)g(=^?rE|A`(7j_Q<n8nx@a zq4W2kyk}AelWQ1e?n}DJl0IwoV8DK8kc$DdD1qc;pU0Bfg3k$dzX(=4SMXx;?yI)- zr3{|3u2|K1sv@k#+w&)==uTe}t~Os3g+~^A4=#ZX0+o)+V>1}A4>ZTX!U_<TV$5eb zHpv+9F18RTv7pg&Wa*1$lDXw&J1PZEj~{*igE`t@B8U!5Ch_`4;~hjg-O=qVe76=C zE$@>$c)O83qQ5EOGH%qxGkweH*c03xHim_S7Y*_8{S1xyv)D-mp*@&rrfl++U_=8Y z+ZirlPrh+07a?)e8^GA1BXWtdWj$pq$y)k3;!2ypBte3!tafH?fGB*pN88Uu4~P}T z`cZ5)gk!5jIUogDURnimn4y_|km+D(>@>B5&&-VE6z9@1CFonomTm7KjDf6?vO~m| zAsGN;k`k)yL8!*JcyL><tcp3D9?k*US$hwus3?gg5_k*21oB%r)sDj45|`pUsf}d+ zAyHgqO#VngO3fs@hX*4zD4mIP9^qW<#3z4&jyq@k(SoUXU5Jie+lp5C@3F50JqG`_ zw14d|$P3B11EtYvRahXWBkDDxJQ{}P7n949q-zG2XSEgvUdIqczmUKGu7UP-Ekrd+ zw5W<V)UW=RJZR9a{D&wJ-1qb<&s?%v{yRnwKoOa>B!d?OWHGgz{E~gAV_OObY3Kaa zA_*rGsTvJ#cZg?!7>1wZqtZSRgJk|`gC(?S$Rmk1e=J^DGABtD#3a=$rdkd8+LMZ& zVfyL9Pg-pRst_?`7gU|0^qCl?rBE$7%bv_Q6`~G_`x3!#4|puUh9V0szn~~=zo=%J z6Gw;*zt134-ra;y%`yfhglYSdL{Izc+N^Ch2Ywx1IxGhpP)kfk$dTLKZVX`D_ppK7 zng|<)kB4#S4iH9L^1)%*T&s5AZ~O|!BTLlUFS*pec7L|K=}rR+JtqMaT9$abG6j0A zOOd4F^eJ!D`>d%gO^D(+hJvvG3Pse)BW&B0VqBYx55DH1i0pDEri}^u#pS*@#;&B6 z<(zaHv`0ua5Y3W;G7NhDMcR~*cZcTyv=I6&^4pG<G-gXvv9JtF2oHJz!4i^vwl|}; zb!fg$HSv%eV{Mqv08g){UH1L7yzFog0WHS0s&stlGS&k{v7i(D<q+?;9)H1xHHhXa z5)nHOJ6{L(1o&kyf@@BzoQQA=1rMz0y~T_{ZM~Ou`+y{qdlq)$qx+Kh&(<t1Vj1>t zb7TQU?V49mYCDo%h8}q=iHW;d`{<WxxfU~!BEB!DuB<*_@%srmJ`MI4pj2f}cvCll zngySX^a&<D5x_cj=iCyLVmhT<^Lyi?ed22Y7$3C!Um58P#yB5E8eRscS6KWjK*pl= zGDq#~$7kK<Lx)7{sqX_->qVf!%&qK8hss+L5Bg|RWI{?3VFwgEh@6Gqlve=Q8_b7J zGKarUE-fd05cjj4&4iiDy$XXmrxIA0HBRCgaB@7EBA!c-v{y@%(}H8H-ymXwl%M!z zg>fbe_G<XMg@U9vdncmETQwM9KSV+q`Hb)}8Ia+<VONx#5kYJo4dp)0xzo4w**^}4 z@gqp*IQY)wJ{Fi=9v|`CwMzx7PNUc+l9@03LcB@Azx9m2b9cXw+~33wR&m{iy$x(= zk*HDEB-a2hCnzopw~0El3cn+*&-FKOoj(SRe~C55@8YNdtTIgpQ>{~%%c#Kkx~L7b ze)mFHeFtIUpd1RCvWxE>9EQm1<{TZ6`azmy*_)^Ijl4562h2fqm!knKC72$i$sv7t zhCc$JY^9~~#AdCPGUj_8iUOcOy76qV{sAr5sqX;#sSOZvd(|?9731V5dF|K^f^RGu z9Gg%iXy{HrWrC2Vp)70dWZ7GWi2&r^147dW$IIS_7#f=rfn=X$43J2IZ7ZB2BLqz^ z^*8^OtVRM<M#S9zXh$T8MvS8hkXwg#_G(<~PtE!uR7-7-6Ewe+AsTRZoqoXD>CYbR zK@OG^nA(yyL!6AHF(j&Lg93?a$e6<x3R6UQnTS_dd9_BNNL{d6h4DlhO;&lXO%d`) zFY_6RT8%bCybNKWI!VG$n}kvT%y8L0^9`XO28Z}r)SH>2=>E!saFRqp+yz;;+0i{b zEa$uRz?!t*Wa%*4#R;Wp!j}H34UxiV?=uAPn<Gvke;6o>W~c&adW+;hnU%6(iX7l+ z!KQ5SwHe`Uo+fQwjwWppmm~;?XDI_%uJS1Zc8~()T)~POFx<o1GK*0QwQAvO%nyH+ z-Oh;?5LqvaK|jV7VLSzj76d-%i@=h`7sZjM?d(RU0MLX5SEdtUu+?V6LK6;#`WI3X z68tGaVBiQMGGIrrHzAsbQcp~yAvi*W-N+CEVOKhStCmnohE^{(h;H!+bw%9~oIRaI zmLVlyEtSlX+72!=YX+-g{UBYmR>oqn>L@9s@4@d8*xAdiQ^0GAjd2PxSRT^1Zhbjn zQ^%Fa?QmE^UOcM9a&ad=RIY&H4AL;ez`#|z_3hE;x!*)b4b#6h>+F@JNr7o*83A2? z7uC9VcB=DUg!`+UwTYu8jHxAx0ik7<?<K|A0{0t$X2-A&B(EF69|woWia#z8&^2&( z#y^+@7e#erC7H6=Ej}881l>{oD~}c87YDT>)IL9yzhd>fssbAu{-Dd7cT&+dsq$V8 zIjNynZqERezrO?#Fw(Dh41^ONNx_kNIVzYimW2uzI@m&WR0hc+P|<SKUWx!Z3{rXU zLKG~6BuUDsrwVk@O?nZm0T*7T&By&BgB3X<SR|@?mN=yPpW7D0Vu2o#creIJaV&@j zykf$GmE)99piX+hK?Bw(<ll=7;q2mN1AF|E0};Rh;i%w%iNZJ})<g~jGhQga<BW1e za7M6VX)YjfABbfkFyw(a<N=W*fv8caVPR-g2~g@tnDPV3k)T!eV-xakZ|0%IcrpGO zc%c8=v5Ye%vIo>s;lOQ7gFo&zDQv}KXRcdaA8A~La`rp!FQ5fb0&gDRczl$^yU&aU z0j67!EkpQo$4pJt8M*u&raSv&GnPC}<1+Yed8Q+`GTqU6vSz;a8z7}>SzClkg)wdf zDrNIBX`?VKD7iDLyuIt39K4Q!wFqxeb(oIw2?pu}98qEPa$%XYELtS}Jp$s0DY<jK z<wjBZE8#puE+px_zSNNeP5s9Bs=tIki>+vUR$65^#L{`BQEj4iOZSU@_oL;W5EDDl z(?(`MAZda41WiaxoCg|DjjJd?Po_Xd5HR%Qz5c8CjB(VeIUQE@AV5PU+|VXC4NlY_ zO`d5~BC-leSA?$}dq@XWYm<FjA_dm_77_Rw0`aM~%a4&BaRrta=fWF-VY#E3LF*YZ zWF>3Vst%t4S)Mlp3B@Z0qsjh1w>t_ok}{Zv?6`u#CYp<&S7=0Yg>Pytm5p~ca^h;) za~l0Mi%-i8=OP3P8JlqU1!88s1x`Uvl#}6SD#-lRD`TjSSeg<$MN4EA9*u_acLf%> z*o<VT3K=3|R3!aF=O>=cdozeqe+`V9P=jLD%F!OMq>B+${Vl<&;8JxVyb{L|mvURO zMxeA41WB63Y8gY+HH1~DeB%sugNa0ALMIV8L2>C^Q1p^U6sj^hDA^eUpcxD1L~qjz zO7fgXum;bNSR$B}nIKe4k@DR)IfL&PPCTP4-M5uGT!-7IY1Hwfx)xXmy&pp8sWHyG zDw0DEPSu)Q2$JkNyYj@Gxik#zEuXr^Fnp#$z{)?Ft62Gk`PLnQV-&mnQNam~rXyo! zk2Tx~i2g1YgVRZS>G}BobOjwbajFpzeb)|!09<>N6h=(SrWaK%ZfJglC}4W3C&9e5 zQvsq~x$HA;Ed3i!8O)`gLvYs|i5gK7=GrBWdFhyqv@0vb7~7_ICTOzo*@sRQ<)XJJ zD025usZ|!$wob2H_PipCMwOM}L$55(n(L4+X!#8TjfyZk-6Ri4-%YQdFF3MtEeMKQ zC08deAZ%F+jjEmY)Fltd_!b3?y4Id+m5&s$#EV8H=<nJouK;3l42`N%eqoazSQf=Y zqpUo-_9zIdSvMaNK^xAcS(YZ)5)=YO<kzlVW*%X_42>#{;o2sTn6o84@%95TME=Qy zUilw;Arb%BlPCOPPd*<V+qFS{cj3Y-U$El!$F1VKnR*$_`wv<mbonm-5GX>UZfI2H zI^JGEP{i_1I%Ru<wRb_#ffHsrW%Fy_nh;3}&3E;(e-sLe{G(9$AB7=MKNQx<E09|K z;4tr%MW<>axiZf;gxZBeqYC@DG|VrcEYP7>W-wSe6%^4GEGkp$r*|oC!1CRtMjdLa zwJav`cw4MihB(x!RX)jH&#qEtXMNW#kF(_6mke3>!c?UqD9E)b268Lx_D}wYk@`Q3 zlK(K){D)EUAI6&hFed+pvHZW&{10R8e;AYh!>ITVBlSOwYX4y@{)bWZKa9oyFxLLV zXjm*rQyJc^Z?Jnp?lY&t)(PMr(qn}1unv|lz={!!s7QQ929uN(y9b#Tn=nIQ7?5u) z%-JSzs=$^Lqre7<O9Z8&$l2#avxfcY&bc!{mIH_QO+kq}#)KMyY!FEbf@XXh95%wm zPUwN?48#JU0Tv=av0{gs3xZ0>d69=p(E?#+0N%pi`|l|p*5FhQB~F?od))<slFToq z21dA8#uIKAQNL7x<`K%{1on2t|MA3m6xn3({mj#0KN$!o=xr>j5cR?Yvk>qm1Ll2> zayc?%@<;}XlESm-`}og>F}F5xuULzAs2wOuQge6p3bojSiK+VLUFtzc=}`Mj9aIvv zmH$-lKH~47TW<9a<p6Y#nE{3>NOD%OLS&(tEFm-{zQ}_adZjdv#1kcm4w(n7Um;!R ztT5_YE0K^-^GmMCCzUjB)59M=HR>KacKOPU1X<6m5yMVVH$UGQ6iUqFDBKDVhJ|Gw zZ1Rcjmc@p~@fGf>gET6M#g?X&Wzylag{CnWl)J>|Xg$#&_W2_o@Ozimv_A3o4X?AB zrt1QcV$4ttPy%uOgN04u;E^iaSQ%v({DXzs0`ivNx}*na=B%KX9vaxTqPwbuIDTyN zq1KrggP9w@PG*G1@U)r$okUhaia<p)^=3T@md*L&msEuDzF1D!Zp!T<un({)`kM<} z&ZGk00%g3zRaF(k=~o(4%|(6+g9OU71;_+nHBqu5H0W=l?V3oi4?QzgS5?KwFm_3w zQ(+GnWw9|p-7zj<i)#QQY^ez&OS%G6HMT{p`6tNuhAb)1j?%9VV6U*>l4d#s6M7X6 z0R)vDI~L3_l?A5P^m}XdOP7bH*Pvhs4@$42kx36r|3+id8kHW!NTK)D+;@}wJK>BA z#IZ1uRFQrv3Fv&9Zn55Xs?0K<AF`BhQDV$sMW2c_Nijzi>B$_Yielj+@&{F%SUQT% zh8b5=+`)yJv`~{JU%xp|_?-GQe(VA)$y|rD5D+xe7dcnx@W+{?^0D-2T*`tGk9^5v zvdddN9mV|Fm??A}FM|W;<CL>`z6(VTCFXVkE@?X|s-}^MmB^^AP>8B3<C=Vfmj0d- zMega0V7Mi|Z)vQRtW$rexvY4>nQTB|be+B#kZW=8RMDxWxdIBaT?{DiK>YkK%$_To zU__da>?NE71y2-$g_3=LYFLEk3;8U#cQ}zq4Uc<vA$S1c>f0l{-?|nvh@$urJYx?+ z)b?2Z_ZZj+cOsAVDFooU7Cp9J2!pr=s0AlFO}pG{+`-lgZdvgo25MMU^UA`E?XaRK zt^L+n!x}LF1ZOeL_#6+CK{0hi3Kt4ZB$@&91zBR)$#JxnvCOm_7m`6PSZNfd&FSGp zZWx)$tv~UjC4nVYuuy+FISwR$57@}zRQ3Z6{={8UERw~SP$+TF{{=hyCC>382_DNJ z<?x{}M5!AxFI;R%IwolXW!|<#kljS}TlaLvHWGCh&!Bk^wWUg}LXQYWy(H{s+!>Q0 z$DL%j3l>v{4ckOCv1<nFa>wvSn{>R48dmw{knvtMPWRyK$o<#`*ITNrU-XMCh^F*P z5<gx~n0z^IB*9%Xdf08738M<#()#b!Bh!Q+KC^o0;H0W1kYvx<3(%UQaTE|uDaEp! zqj#*wEU1L=ilqSsWlZ2&<^UX&Fb7W=k`)@$%BAlLWlR7N{tji1;dmAch^38DJW(iN zR`*y?A?JxJVg6&ggy}!Fe~fSqs0vSXN|*w|nUV>$7I4j|oK}*-&RLQbCTx{3MXnf< zA;lZZVE_uQ+?CRWYFSPoevI%;s0vZpWlVrjOsIsK%6O)fkLsvlmn^6X(>6<(A~p=D zln(cplGCAnrcSY-d=y8Gi^P`fPz9%iDHfGJrkp99F(!R0y^K}1u6(pZjmzDqJaj9T zKIV=ptCU`mOrexcnRlug<ec$u214yJCOBTf<xy%oOv&ZG;S9;?L_g#5r<P9ysBzZK zD-SvR>(SY-Trx&Fr)=u^bE^1%V1VnL?jV*h#qf<O4^`S{j496xr;SOI$}D5$jVmAZ zP~)yxQ0=$;bd1?Dpo(ONw*8skKgN~+hjAs2AI8gZ6chxNG}w)zdwl*M<NtRV&;0uT zVSEc6Bj9)Uys9p2t4<|Ae$$<#dw+$0OLf$q^U4^7=7cKQ>ul4V<w&&#=$s98ZLn7r z6s`ev;Yy*kNh45cwX{Ex&EaC)`X8vgpD`e}HBeV<s0&+&txZrm$5qJ~6#m)LYJyIg z{MZ^*L!CGNyWX{auJ^is*L!sbmZOzwfb;qo^{!o|pxBSgCkm~9e<5n*JPIuj)&sO^ zpyP&QwLV<65SO*FADO9+B63?9`;i%IlmC^OpQBo8K?61>KRTm2glN>n^rJIPO#h=Z zO+QC{)PQ5_l7EDziRnjZR7-w@M%DCxh2~E3<;im92hoqxQ17GujQXQAKSTeI()@tl zuLZkkO#YD?EljcNy5xUSll;F@Q{92|)q~|8TpjhJHOW6(^W&KX@yGLjTJsOJjykaG z+SrfSRR4(0%Gh2_>-rDVLe#3iU027b2mMwkb{mt4Egja!5K;4+9DNb1&^YkSb^^Zi z*&3^7fN_$*N9*mVHRB>z9XD>#dxJb)<B!G$^x1KwkApZI0TYM|+`LfdCZM}mB6Y4* z@~W`ASYq{x)OM=4?rgtpG$l8HVu{7KKw^t2z1K-2svyiTHKjM8Vhg3VU}B4@VGgqr z=p2}OJ!^BL=sc9TQ)(C-wItgPnBr29n}_xx64{20AfbU-g^`A|7+c{@asBYPZ)W#m zk2^=Lohg`UKE_W`=!uxEJ)TR0KnV{DRmdi0Yux3AA~$$C!!xiO-tP>?3`Xy@doH?a z!E{`On#ucXz_f()DLrt(e(6>H?j@9}$C6+j7BXYXnt<!Re)L4^asEXhX-~_~UAwfD z=M5XR`Fjd0oGq_j5N6SEn9LZ@nQXsCQR%Nz<wBdQ43c~;we*r@<-hmYvo$uWry%#O z{!~k!nyrBgKUHHh+zV9Y2+Kf=8&szCH!{WJGW4vMFC_s)YXeG7P9%0c*ROc|ev!>P ztoUUIs{OIr(f1@JQm8D|;)HN^D5%r%+fei8EQT7Q1uI_en{Sj{+ceBKR_hyzGMDUh zo4LQ_q=?f6m72@k1=p1q$Y5+oB`9_rrT0=NHf=UV7LVA%E&>#3|06aoGUF0KA4GWX z&j0%`|9NBlMGPjRBBh*<_$@}}_8z-iip<?}xBJq~_MOFFekv5M5bY)n2>xNa*S=0Y zk^z_sF^CapI11Vek9^;)!~KQB%l+gzjEL;J3Ag~Dl~>tZ*-)Qfn1<zemK-uN_wI7= zg;HpSRLJ#cz6G+#p%=z*kNfTN>7sT}pAly3))HShtB^cBH^=y6(C`U)(l5i~?qPI4 zDXuVs@4#)Uu6(Uu;`piGu>qn1U{XUht%m7-)P82t+t1$Kp5^gfpoRzfLyPI-s3;Zg zvwbx0y`=^6<4VYlAs6oRaTh3%_ke&h?J!TNBsNHauRV>YWo-MuTwo6dOqpA8wp=s< z_F<zuulgF60&Cj3SGjRt4CGD|`Fft#a&70}{gU$SsOksEPm=}yLti@UxuZ>WH;6Xf z>%;DQ9>OK&P99_s+cUXSK|;6rkZk;>Xq#0pZ60+8OBs3;%$QGk*l4N=wg_WwIxgxw zzRw@W*Ah#POOSM*r%7dv%YGkUQeI3N6Qlg;N035y*{|GucctmMx!;ptv4a=xvidoN z#a~T9-w<q_maWp?)hg5vdbK0I=$)3u%2XfK@>D8Nhd{G5TifD>`I_%qL+|V4FLsau ztxW0Nn>5S9#8K~b>_AKBgDeRj<lmo?UtaD&fI{JDo{s8cyaov@evU88iQZovuidS5 z7&rG4s*~^6QN{(Q0$QU1`VOIS^)UC%frc#Vh$eR*-Of+F73x)`fC+SCuoBr$RXFwI zZ@t_FB%om<$3MkV+`y$8L#K)&lfUi!ew~Q!M30tuI&u=u&vAoE)ckuZ|7q+Rc?bI- zjRI8?W}4_##X<u_1l<oJ0}LbrFi3a`YzN$t|7}B$9y!Wh(Sj{V2tRo>MW)0gBr>~2 zI5bQ|lsm!FdbJZX5y;H;X#FKz?8L1@x3N0#OG{dm106WuRg5Y9OFsCkDsoPusCqq} zR?LPbReC0<9)Es3p8vZz(N3A1^X~gSXNE;%!oKQ@Ax-2lhWfjEezk~?SPGjaRx?-~ z>;%J1uRMaHK<IZO$J)ef(K);VVvclZq=0gC5iX#{A7n0Mn^WU6#d2JTB@XyH%T(yP zRB*t<-8{aS3l58qjn_Yb^~wdeAvcWn%GaW>A5#oBKP!+_SnzB>g#m#ITw(d(1xiB# z(jOES&WF?#!tQ^~%RJ1`K=v{JP8MPe>^Q<OfF14-*Z(%uA88;)8zKDd*eB2Cv%eFF zs39={e$URXZYipSN(V@6F9P(LN{6U1)P9l3nC{r?Oq5G(8kwjk7c=T7cC+np|HAI& z;q98!NhGmq^>PpO3gtvkyjv5Gq~<vklJk_}lZ|htmuWF<xrUm6ra<4jY}aE3{Z%(T z-ZEXeA31-K;rn(|3h8HyeRu!&qb*7Ali?i*5QmjPJn)Z4R%a<BZjpD`m!>al-yWeu zZKhf2s%qkbAb}i&n5<{@1@?%Cle8mUOeXEnB%A!MmMZkCVRTXMPi|<@3#%6zHgz#= zfB=wD(#q$%5F$`DnEDr{ubHK+Kfe$_I##e{7f{c!1r|#6pRHD>nxj}QBgb75o5T7T zQ}h~ZWdGa`SyYl1-7i`^!C>8nep=&EPwq0E0z<s^eTOwP3jh9l^M>N9iHSaGu+MVN zDk~lv*9L+3S(kc+-SDbrkokIDasd%g3CbkkRY=UdC9ePLEW@p+?GJM7g6k4Z?{=bR ze+d+W&M#=#ye!A-qz?{{C38yFY>88@R6Y+Q5f_xJXd;9?`05?)yZy5loP!R*v-X0A zj^y%GfQO7lL3j5p9HfI|a^!@!2ujG==VQsg2h{qljXC>LgsqdQ7snjL4`-z3$@1K9 zutL0L0LrJwj~b_LchAjl*RJ8q!?k+G=ddWNtDA=ou7V~mb03rK17}{ZKm@wE%!Jmg zrIYAU5%-ByA2zBZ+mVT1kY-cVChoyF?7x?qjQ#$7+#&m3<Pi~kbpaa}IhH$|fGByo zF8=PQ*L^|ln19!ab|l<AtENCR>J!hHwJLi~u`e#eRAR(*F@@3vY?UMlFxmQ)drg^$ z?8;RLE=3<rQc}7z0b$y9@qr4;0id}%-t8{TsV*nvFH2$(-c@jv>;sH-Fe%oWTlNe+ z+%Hj*e;5OKOb$}oe-026M7_$Nu&mnw%`jJVzsUp!R9rc26{(KA93}DlnP<_+mA6@q zYVbEUgX-{^vs^>)$L|sAmlE`o2Qe#9l0GM2@KK?vH5}{W>fObQf|8T$j(xQ4eA?5B zy%%51$;0YpQq`58)x^!Ga+cPT#9M<jn;ty3c?gOV`7N7uw9{!qCv0(4=R(%}R@xA$ z<i8s$nAl<K1)y40;S{GguI>=x&+1csRZOWp#Au)M7@5dk+O#`(ws>UAL0};a2-^nz zI=22eG9tFTGuP03;51b<qKYAMr{(ytW4;8EXcwKULFz+1eQhqtRw0^hor_IN(4rby z#1p7l9Q_bX-(~6bC3XQjw76M6;1kB0qOyxgr(z;YyWh@1lsZm0(i2xHmc~*J2Ni~I zTmgWiZYA&xqX1{hi?8AsZL^^eba%|aWsRMl#ylaNV6;nyRG?T{?zwAzoA}m*8ZOI+ zUs^5!Knx(|+)tS1$zFPCMqg!{bXpBC>sw&w*nRufWb&SwS;b_!ZF}U)%Be(VYNFA` z#n7j9>F9JxNB9igG7tT}sF9eM<cr|Rk^I)y_Pe-+H0PSfR`(>V>=Z7kW2<7^jq<w< zl*!D8#l2gXPt=x{HSH^EvxdXc_vz+TLn&qTr+dV*K4@gt!_~{CE}SEHhdMFF@gau( zlXc|9#MotlSDEDcu)6kQXcco5mPUF$bc!1v%Qo5EaaU<t?~%c@%A8m$7o*oR@Wf|f z!AS@lF8|c0>D;BVR6$r{l)T<W7nDk_HZ0BVv#Dr~o7-3Qetb#Gx~HeI#YPw6LNwDj zwWXvqrAwvPzNC7T``wDmst@p&cjj>w*JSbphV!!e!|5Kos4M()UONl1Pu4B$%oV+C z$luZp)|(5Pbt)OPueghdQ>@s0!MvW(5C4ibn7U9P%^lmf>le5cv}eSQe2-rG)8CiE z5(Cu*j?<6%`BcOfUE&tq@ynFu>iKbY7&`<QJCaZ~NQNw8j49I4dpW`WW>pf~!N(<* z3tV7cL6FeMB}~?^D{SH8u@C;WnbeIqT~>Z6de8+-D3@PW{Fe|lDZxZ~m3H#${Mj7& zx`pzV@RvwujskhI-ycCT+dl=EYm#&A9&(T4TeX0@XPuIBCzti5S*@bcv;u57uwS{d zqIK<fusgRj-8!~3fv>Vd?W)B$BG|O%>)c=<O^H_kWEgNk!%GUA!xzrk$|mzS=HqkC z3szB4q{X_FKWNjyy?tEo9yR)wj}gqSmU?h`*gjsL)-N7pYW*^^yC!9~O_S{Y%r~!| z{<PV+zWw6z`QPSJ<3EYdKP@H8-T!)(+A)v)^oq>Lo`TCLjo?e%omyr5ELcw*9kqD+ z+ntdmZ?@+&NKF$bixz6O`FPu1ey?z>?Erg~#?Xnr(+Gx#qk8MG4;rACKy&4>^u@s8 z5&!r(_7dC{pACInrq(w;`XFVs9ot)5v+Ea3R8$b@gl)=0roIgO4WPdiz0a1qDiH+O z>6@;@7ONEqqzGAFvBA#Uen1%{dY|`5gzcRA2l;Hq4M@qujGe1B=_??WzM*+?Kayeh zId%2tMgvFE+uYR>UsiX#%3&Y=ZZmsYVk_7%lZEs8n6oK7+-CK{*B@!zw3Lat4s;V9 zI=L}Zgxew!l(?FOEw1xYHf4b^ZU>5U8diB43#?+@)D7gOc~aKEV3xH_>6BA_Xx_zZ z_~fmHCC;U-`I&qt7jy(HTJ};_>=#44OvWZ)QW^_aB^Pk|Hg1({8TlThvq!08E%ABg zi0GuPpU5X0m)kSi@Y{KuQLzg5a85PGFdB7b{PdC~G4y$&Jj|qOLU&dABdgVsHSH`c z7I|~&_taE5j#f;>oK!?O8ZLakUOuezZ34%HM%bG24bZnOppD&jKOa8U*ZbgTE5&;) z`cBN-k@m~+*KdgDQHO3qO#$%^3x989R{P2Ml<0XuXi<YocS(Alzf%g&4>PbWD{-q6 zz*#VNsq|q4xZOw1B2%(vKh@xnk`}WIxUW93hjtbp!OFhw!K3DOSg$*m&i1x1VlYD` zAA_7XcA1JVh&ovB(e62UyAX7TWgIl7Qcbt8Pq(qLV(sKI=nd%f#yLb<?-#My%BB`; z9w~xfnBu)Ibw|e8*6=mm=h#7eNfU={?zMNIYc+e4bA5%kNQkb5gz-*E&9)MLg;WWh zPdaf#3B@@H&O(MQpca0=B&j|g;p`59O0RV~hRDhZ<U0mBzgq2%f2QmsHvzq0oJ49r z$_6|b`C;q6LPxFp*}f=1@b&HLWdot(7-H%6Lma4yxq<Ss*+%J%>iSV121{C0KIc0! z5m|kk+RJmK_lni(a+K$q@MYoT;%Aw>)3&rInRo#{v~NM>0BiAO0UR*GImnY?Ej;k> zKIz#PoJH&6k0I?6-`pen-<~|*k(4FLX-06}kq+ha!A*r!zI7h~7g$9$9=$7h<|g^p z$^|`V@#;HMunQaIQU_0D2g9J2Gtw~y2Pf%@3oc#j1aIUABYaZS$Ooh2Zl7#^iEi0= z(K63@#Zu>-4AYMUFSmmSUSapjh&;@<5@FP`tK<(mipSC0Io7ok5>8-m%6+1;f2(EM zCkDaG^|`2$bu^W4fFU;bJxn)$Jf+2j^80o!)&e&rQG3((fCRDjP($8}{`NrioNV6e zM)BOiT21mSoCY6KDdjio<#61-SaZR?R5Z&V)S$hH7@|;?PQAu{CML3bjutTDCL$V4 zB5z;eu*8cT=Uu+W9#=Rgjeii>C+?|VFT@KWHuQ6-k;X<$9DEn`S$GRN0rw|fni_{E zzmaotO~^*pJ|{~Psg9K)+6fx6m!`tX?y%zqMzWI_b6!ZeXR8OUta?LMC)9Cd>Qu0@ zPoPE0!k2^a2^s>lLF-inrEv;0DKR4CJWHd(4L^Kg3(PF3(Hc&jvn}Sv$TrSJJouYv ztwTT$b$}=Er7Q5o2f|_VxzqUCfw~pvA=>p5v*}G6ju_@}q5Wmi_UhsNi8MmEEiwkG zH`iVCkf=%b2D|!uI<(q@S&Qre-CryT^?21w@Ehbr59tlMKkmzqdIFNJ@a@sv;pw;M zBz5u&JXWsK*Rs<I2hs98$1W%|GearOXWr=dXV!>c?oAbd{WOJkdOdIS2VW-gE4|Vy z`JrwNss;~l%`XWvoMuazHPn63)QvAe@hj~_?Z3w%ALz%`@EKvexlV}H)2(52&NPaO zEU$i|N|9|J$apkz`gayxcC&yI@qEZ5=M3h@86Whk&L-pC7#Qp0-~Ni4tOtHFN_;1G z+qumhWNChrz&nU0gC0%NC*J@M=#Zbq>15vt9J6<RoSfgyj!x?w%?%u<uxtbaBnz|6 zxq8%mMn~1#<`1!I9s6{;QF?uWha2rh?J~hf=8lFX0|5ei$yn|rjp)DY0L*7%qH1h| zoU(P8X^Pr}%gDyVeD4)olkqE{bRAcMVbk|bAY6u1R0m5o6e(CO-oeSeOrMKwWB$gN zk<$wx_BKTu@Rz$vmqAOB*H!TPitaQM9+rS=2@Dsabz``@^7?)zY%)P}ysB=~bt=;J zTQQ=L!LCLJ-TcA#?Q+o>@>$Qy9infZ9+-O_e39OQ`@1|PxoP)M`R7W+HML53rFvCB zNHnU2-8OPze?8Rmp4IZrSgR*#-Adu)<Aqp)G|G1=t~Vwp5yjLwz8kr<tJ9y9pTU-! z*b3BeJR0k-qtp<By9kyb8OH3@ypcnX=Vk$T%?+!ycAt8?O;*Hb^?a(LUUQ8~kPpex z%(#<VqCWT=D1N;Y)&`;FJ8TM|^7K}YH1?n-v?~UAv`V#03<_83U|x0O3J;~L9x;@+ zOhmMmaDW(s>t6Q+Soq5=AtIkTO9A}s#|!_f1HCKR-Ya81Y-U`j3cO|=LOKf+`0dAy zIb$r!y?%R_c*G=J!OLyH-M&>qtl4y{w{lKteC(YQ9lqQ2{^7n0k?#ZYZ6Up^a={Cu zMO`P^RHnNx!~C^|(;5bh`9iY9{>~9g3jRdaH~))5HwP&$e}qp5M`sMtL|p8-@ts2_ z`fH0U0e<1S5*a>QbLp`-<8SW=JGpf4q^;bcvEg;$JBLhh-W6%@%wT-Q#es2f<_Pd2 z1AGGZVOon7dlY*7i4C0u!)D^XSTDt@Us1=ynZkFB;w1P#QIl1?CQbb$;oc7x{clAE z<B%Zi1hAR1dxu7{k&_bjqro>u5)nN3xkG33ay5LmY|HrP@Y;SfyhXG4_dh>6z7Ymv z*M~;KFxK$<%+Z&JY8rg*W(;q04A*;NEF)k^IWagLA<VO{=M59?&;a_v?=c681H=C? ziM-~|j=CDX(`sITV%iyJ<P1fng5o?BABeF+@~z}(vu5DqQ}Dgf?C8&r#xfm>rQa9< zAbM9YbWiNPI*faNXf|RXiuc8i(U^A7bkV(H(6)MS(9Dm3Qw|;M>&Nr++A7`c^Fs0| z-!qRPF{=N*BhI4W-9Yy35oYX&Jr+y8UYs$cZ*bAy_lf$fFZR~<GkjIAY4w&~KKa;- zgIA0i9k$Qr=Ov?j-6f5OKl(T%-Thr*Deqf%+042-yhi+SqwjmWcNlcZ$!j#Ylb2FA zE7cRLAn99`I5Mo6^*wy9gy!9JaU^DLjuu&3x-g@Sx_?+G8@Z^#xN<{kO+z+Qnk(nG zQL>1?$h3?f;)wMr5W)CaPc^)P|NR=2?b-H8ztv?oq0jIOEczV{4P50oZ@TNt8*$Av z+X;0kHP5^Gq$D513?HjueLL*n+?4AnPTkf-C#M5;ywh#~&xsn8k3~1ltiPjADGY<g zW@6mINRbexMiIZt(P)94B6kkZkM6BZh25_=khFoeW?So+XstXd-RBlt1G{He{KV^4 zlY_Y6%P`-Km`e_Qinn(6ndD=$6#Qx^ya93W<?K1az7B?%Q*VPM<$5|yftTE>{f`k^ zer&#Z4L0qf7|{msuYzDhuGHm;S_r}Xkj%i;F^kqCT7wtWvesvET0GO#%lVuRK95sg z<SzcHff}7>0=i@;rfQYtG4<IdnfkOQRqs=Czhd9QW+X;{+CVedvxIq0He#lEqYU3a zuXm14N9b7e6R>ts*XV6Z0YHw9+XR8z)}GN)y`OlS+sh|D)Tg+tnb+7_2;8<ObAj=c zb10f}6|iY683B@qWgZ`AiteF$Gt3atXEzKNO{?Brpo`>q(v*{?sku=)S<YVovLEl9 zV8z#_AUIX}Q8$lYOs|f2`H+7^{!n5%7&7c3nRYJ~EHVXs=wh`2IUVvoYFe_(PyD@x z;)rzsGwEK!w0hl>!46rf-&js(sTg^1x-GD$D($~_lv+j4WLdye@()T->OJhxvCbm? zbNdK=1xv9|#~$A;$}*BXUOEZ$v%qw-Zt*lZ9NNqcOzpd=PCHGbmj_{oOU8hYJ)N?E zq{TMmX4V+4W(hNpL>_^UUD(ciBdW_L=^s-!bKGC>Sbw{F1ta@X&c^ZyZO`^>HoQS? zO1a`oJ%q&d{xS2iq7H-+sW|xscY^4b?JJkDs~0=L(a*(n+L=rj`en+i5p=^C7IRB8 zfX$Bagf(Y%22?V|qylf}VYJ*6=9tKA=)q*&vp{KkEg`nD)IC<oeAB4Gwk3pYm)S3> z)&i-({*#=$X_s+ZYB&8+(jk$vn7RyFflIz$wmv81=E!hhqFWJVOxUw72CLyZ`F=Ov zrHxWfkKSaj_~1Tsg;>sW>Z_g++yJcHy^B4u>JuGg^m~OuQGm@eqpx%J5yarj*aNJF zRj^E}e<*OJOC+-VyTZ$C=T+bgtcS?p>p^<|t8>Tq6Q@N^p5B~3{wlD7tE2BV@cBt> zM3)V+6?*OR;RqC=fn5nco*n~xfW5<9Rky>~(K2dB8OaMf=C+51{Lvy`fxdo_;xBjS zP~Al6(m5>{Z!qi8a$3<B6-!R?l<rNwuM~|xma_2Br8wNRppgb|q3!ELJMso@@-@-t zIpryy0CSBz8h&kvgg^!hIEzZcD-P56q{BWe=gLwtv-+ZYv_^7|3M38=_<Etu!cU>e zk2JRFW_!*StH62Le8%zsCTks^svHC3XsmBwIDwE*aQpG4#rHEz(Z%kgMdmc=jv+C9 zQm!(4B{9!7>E!n17QiM1n&smX|9IXLr4p8wab>BS&zv;UVkq3W;NGa(I4x5iVaMyS z{2U&$Ve;|N2a`^#8Q@?KA%AUptP1$`5?h>5F~MQnH_kD~mOh%_Ru`^4EsROBaNikx zd_hJ~eX~?bV$FsE3kA}iz1b1De`EX#_wg50A|Y%bJ)1PlVRnoh9bIlF2%+$&47R&x zT0nbdA)~6`QTCot<ZCD;iKLRv%A%yP++ZCdVeesljm|t*Xv7b;vAd2LhwE}F;X=A+ zVQo3MzBsJJ;ku!EB(7HYw)-fnVQY+sgTR`y8Lj0@$KFFbtQ(2Qgdc-3%$AW(9`QS1 zwcTY0J}hV;YU4oj4gTn!;>n<M@+rD+L#(wqtLe|J#H7Uq|D+Bvo|}Qa@D<v9tweul zsc;-K`&%gi+~i+T%?Dk2morSg!b;P;vj#7vp@;XKNrNCuOF&eec=NUxxlef-@_PC` zz13dVY(orN=oezw#v`$mBE3m^Y%{Idkj)vM$Z7j4^B0dEMMMIIQ~`}-N*3>@?|bhj zTwGF8(WPs<4GItj3>b4zdM^O`?J8T3F6vFSukRd6w@$aPW$0l$u>9Am+&(m%4+zMC zF2BJWOd$czGm!mOC(1`u4?mf=_raKZcbkZVaD!gZk>TL-juf>^v>k4p8P`mqh!U|^ z-3!`SP(Z2H-+3W!9yN5L-9c)RA%I2^blR!OtKwZ_S@2_=JsO=fh+=LWQl5jl3qtad z>-4>9R_`oxXDZQh+ZW39Mk_A5`%v6*#ER{<%EDt!>CmKX&;=*BGaw6_7s-^tKZ&XQ z(GU7f<~7<TX<r#Rg5crG*WJN>W=pfIQ5@1Tt?Oov+&irizoQ5B4%x{{9Zx&Be0_#k z`Yur$B1GF<IsXh&)WBe!qjG@6!*fYT=W5oz5;@*vsGu@@x=)%adBW~qG)3kPt-YB~ zrCVEcm`LqnXA;9#)s~Xe_`?G0O4sP+o!nuQ(WsGFR{mtfFl(l#qtKm}C)t(c^8B)$ zwQ(u`{)lL&t<@jd$J}=F99ED1J~m5g;AElzBt+XjiCN<7VVCdZTK({kN_Khf^XQ15 zN7bC;PsWiKI(;qR;^Sdt*J$2+qHH8W-vnL!)(2@miLwP|Unn#3@7;ti3Hi<t{nI=W zSVBL>L(JG!O}9$OUt__Z0`rZ7Im9CBx0=cA6KZ$2x;Z~CPTytN^@OSiBN!r+KbHaY z#8Jk-->`l$Ma8G>Z4gzH3pwlqylai+mng?cT*}ipB>k${JkMj`A+=~ra{xPk@8}_m zZ~*1b&e9KUOrnP=tM(PF+RxAZ=sJ1>4Wry*tlYxwAtv<OYEpQ_aHjN%vMo+_xijIu zGx?sk-o<QhvteDoYcBF8OGL49Gqcp2%r}siePiBhkdC2+)doois@_B?Ds%2Vdi18R zkN31mcG~}|<+MgVL#`70ov-IZ<mP@JUhV9IJKLErTWI{aBy-2@-aliCllWGWm-v>7 z+5H9o!1i}4+K7@ZdxDe#7()vnP7ZYi3$Lr5(Dn_Qx55R0ezeOhAb+<PDR-1e4tYfY zlX$R2GQw`5T=<P-9?1rG+LNrJCl&GGTxJAgNhvv)?8ib-CMLPe+RLj%<!`yVT;1}c zo5Lcl*WJG?e9x?bYXwi+TzrdQgngxJ_%^<KXvw)pe)S*DWgm@S5cl&ahsXY7(*Z8N zAKe`vQFLJ+INqDD9IIJhFaRQI@1=JbQH#G*v|w_7fg9-zq1!nJ?QegFf(<vmlRaBc zw0(yPJU70_$PPEWGf&(+^`hHwTIOA#;T3q6$_=+XGYigk6H-iJMC>_lJbu9vBQ9=b z(v}ngW8pgk-fqvFre%F$=P>AIcPW+bze>C?ua*+OD<7W(QkXO5bH$FRIqxI3*HUo4 zPD}Yx(R38(f!7i)Z^`3DYi=IB?6HO?sEzW9{^9y^55RiU0fPtYT3aC{(xaFp;%9cI zh{orY@-0$psPd}%D*4?P>>JxZz#V;!YW{?gQmb3Y&3MF=UHG0YD?36fcR=0d6A_J} zZuBic6K#i|Cj^$r$iHu7B%9wC5Hy4h?p#^2YQtaBfe!YG1KUOkgC*t&bcYQ0E{f9> z`}-2QA8c`_<-D&Yx6t9wPsTmpt#j?}p;IM~&nlplZpS}A#VpUJw1NU~+^*YbvVb-Q z%<{V3(BH7*Df)btJ3AQIA1kk7Z(bgC(1*e*J61{u)fhmJPF0sXbn8EN-TH<YItBM> z3rS+r!yO((-C`gVuD76lmtUC^UY}w@xPVsY<>`hE+zw8kKLQHO?8VM&yo76o4Ltm; zSt_r3DWR%6jm*Y!yIGznpB_}tPr=g?JeF~D^&k|And{|d<~d+Z!I&IsjM-FSnW&yK zwS~Yh$i%9ylWEV~1`8C@zOUQH@uw(4R5#Dy2Zqt4)cRatt$r1~<L4mKCob6lnpQx$ z_^7(Q1*KiL{4vijRWPUm5yLRu1ohnVUc=4q_pPCC;;gOVorJnf#8@SVtD4sK+L433 zyLZk!>2(r1+av9uz1!3c_Y9iz#8B|-5w_tAL5y$KLU`m0JAL()BE*W{^#vL4#j<tQ zfy@WJvjUXP{DsgdHyzdfQaH=(4wARIsZ769cscSy@W{DY;&*GOyyjmF-kE4|jXVCC z1{hfcNw7>8g?({Z2%UyCe>G)=UKg3jY2IECcaFeBv)MD}dTk6M4dc0Z@q!|xtN7&e zxNq|TBgEA=<4@;dJ9ok-Ycc473)pooo0IP1^#Nnv#GIe{2R|`3@Ad(wrsJi%(uu(p zf`S8`iWgLJM+}R25CTZGWuS_oGx!Yf<V4E|CcIXzujD4|+k4#B0Ay#|JUlM7b4-OU z<rgSgZLqb`sjLR;jmzJF($AZbrA?_MAd$peU|-_sD#Rq6P-ym0#4W87$YcDU%E7en z4>&g2)whp+82oli<56_Kc0&E%eBbAlBJO;iqfQj(n>rH+Ut~M!X|7$TMy-kri`QR7 zb%yi(0q2tMWT0QKwA1=q{NNE!QM)y(z^|c-Jv8}pBIo$iKDypfGRkt>kW(0*Bc%8! zLThu_X4Czt&vAwK5OzTD#E*eqY(LXSwAScEYaKmhr=D8&3(#+nhA~XvoPTn`yvEUe zUbR5O5Xo;94s+9mj5B;*$zLBiUT-S5_f&b44r|Dm5z)a=vY1U}iq=?d=2GCR?doa) z5O1i_0N-abu6`}HI#=UqAsZm%=9HDWs_D}x)EZ{&$MW>FUC>BxysySpQ!DdjKh3n? zz^OlMsPL+L37=;}qsTDOMJ=kpRn_3+38JeyYcb-h20&ALBGKThzUQl4KT7pF``C6i zepD<Lb9;K!i?VrbyJ45gt97>_V9npNa#w~8>T61KPOZ%xdzsAKMGzZz#Ffq$FROQ1 zy4ChdLl1Y;g)tzub{52lj>G`HmcWn?cFM~W)@}1cUOc>rzB{=d@Sc9z)8)ur-93w( zV9L89AY{|}qh}unB$dTwP!)CNKhWXli3j}ovW5tG1sJ3v&;vy|0A^7H-1GxOdi?r? z*_84C8$3)-!vtr)7CWKiCdUu2wErT8fjX-Fei-I%uDx6Q($t+8v^jIQCPi&jxUO#D z>Wn>6`0^Urst5yw4=hp8cJ#9by$DFnTNimQkvhfa>jrf>oRrTw_Ykt<%#T^44*kS7 zlDIDOqFaH(Y;8Xh0$`~ye!#q)c$%7iK7He5wVu<<wJLR36cTakG$X$df2(kFIr^32 zCwOF{FX`LvTe8_zzVc9;b`wm-r5uT$^8umqf0%mb=*XWZ?l+j&=Ek;d+xEuX*tTtL zY}?kxwry_AoBjTt``r6apFZ!d>8e*vCue3p-POB=>{sbLqnUU-@EYR7jCk~w?uK@x z`V8xyU?CbNBQisbQ$q)No<{xhV4gw{o1MeYIH;R^^G3fD@n9bf3T-`Znsd)6d0fPF zqH^^57mmYp!d*k=%xOv{*t>SJHfb8JK8!tFc1BVeINz$?Rs%kz*F_;pVLXmDwuZca z({=Y!D2Zbzdx4e|L>?e8MKl$_c-Y5uMY70aP>W;Sk8yZnwD|h9o%GoVeiBU=b#|wB zavi3TP9v!`gZ=h7>muy}JasLbnVx3^Df)<|evWKB`4WqLL|cdmd7Zl3&huh)iY4U? zRvnG^&)OfNKCx=!ouI&y59;_-6ua@0SMaOvq@JN)V?~nX3bRFD)r&8k;B>cmOzs)m zW^Gq%3^%W|Zs|S+RZN(}-29Eo@P2k29LrCPG}{}Ev58&pBu#bFF@Gw(o+M~Du1hOj zk$g6v#hIsh9beZ22@`ajm>yzg&}M=i+7(ao{yL%s`@H_@?dkEB{yX#gi##?s?cB>) zZ0g8yeqB9sYx5-?6P_q9XI(EUQND&gNEgmW?M*4{W5%d{4Fzp_y69wbKC!9=EoVRy z%Jpa@EmE`;*Qqt-w2&9@2%;zB>fpRxw4>*HCWOE5u~}4-N5`gHpF|mRmwZ_Ww?vBX znfR9(wa;&vHBYfSUKz6n73H0_t?v+RqnX=XJn4R9YwxrN3HPf^Wk#C^U%-h4*z1=> z6@MW31vh#d#)4$*X(%4Cj65gR-G+kw8tY=vt2hjd9%ePU58XBqeI>><>~TqwBU=q@ zDlH7v>pf{?;_q;rI}wd9&=O*U`n4~F3thh6T-+k$c{#I{ZrP61;lIE9vnYJSW2_aZ z9;ON_1m#Zi&e6tB$;*#dnH^fl><IOAp{1zeMDJxh*dcT?yd8+}N=WLS<{cfZK6%d$ z+bZt|^SZpmWHK;yuk9?(UzBvSem+qiLVL$OFGAuw`}To{!!>5&;T}-4il2&z(C>DU z++Ue{$1UQuIr;0Q8T}w(D;G15n}!QiY40K2+;$m-s%Hley_~x&;n#n3!@F;Px=5#L z!&nW0ZrPxd*MEPKaJ&xI%=o(snz`j$%IWuqPf1=$OI{XwERp2OIk=?yto>adeI7u# zuOkb!;Tr4lIfAix_0!8^=G@E6egTYYw{-dQ83deQhP)8}WRyvf#uxcs+>S5|ecZ;M z+pXllqbrk+n}=lPelNXHZfliw)O(r0WICDJV8%Q{m%t68E0&#}uV36O#^ZJph9dX` zWsdWjjwa*COpsAf^g~Bcz(B@MI(GDdw#t!^iqa`6gSxE6S|P)S=-$><uqA9I5l=xq z=+i!S<|`!Uf?Ij^Q*y?(FPLC6oB_&O#txYdvs-1eFBx24971J%&7n62VgB_f%|Sqj zTgBy8MybMIx8Nx2;w_f`Ebb?Q$9^V;(R1UB;`fJ14s>rJM-tg)iJqL`a9n3mT_0jO zwtf5NNKZoQbF;MwtF9ltZsfUAC9<~fS=fv0LLm!qH-lF>c}dMJ6P4X=WL@eMFRbca zFE9z|qBbXvmtLPmM;RGiRXpHKA*@#)+O9%5IJk22Eij2FuU-qDPf;6#60xacH8PN4 zQSyn4k&X@^tfw(@<lhxvki5o90k*r>G4e(lKvuZ4`j{zyV4krrpPc|!Rh|X&@RiQ< zCP!a5@8{N=fvfb>RJ<zQO&<0k<??EkuSsu{wcBrtFdP}Pry#^YPjkQ8-wQu+?ofpB za;nwo*?1Rn1;rlU16U;71JV38LgFfN4Ml@1Tdx2PD1sqyd|Q-p>YaVq0>8Jq{34P4 zJJ0SiAB|ZB)%+V0>2D0if+tb?xgZI><><JqU8cF741`YDJUd(+k0OY(q1rDfqfO%u zcV5~stGGdFK;HcS{)Iv=nW7hmvaVj&X44sgV#54c27_Y^K@Y26Jv|D=CR#Xs0H0G4 zI2M&}EGyV+%2lgv#a}=hYo7Y%?F1bmk90Pi-^=gEAnmp2N3W@fVf|C_53;e2CF50| znR{`U^h5EOO>W;luIw$NvJ>*(VU|pckk!sOvw35nivHP(uHNOTZI_p~{75>QB7LEI z!UO!h>ceprzr;OxrjxCgO6seQO(5R87=9FcKFcnF3;*94ot(POdOGzPGv3fm#rIrY zj`(at7?Ll!r>#{i&i5IOMS9eh^Hx=qyi&efA+olL^V%~`Tcg|O?ZgjjikaPu8A@H= zK8`mal(<d~A4g7(xh&oVtVIa4S<47F_B+ZP!t5o91@A_(v4wSPgT=hPtwJ?OEz~EO z%Uxf&ZYQ$p4~Yb>@(QRI#T6l=5}ILSAV!)&W8Xhd`HgK^n3(0lny*@<(lK>mfiPYw zvBL8A`pb7rq=V=izLOs46W#CrXghm0N`>Vj_>uiP66)nSP>uLcIU=Pmf-X?$i@4lP zC)bEFwh~N$ioW7`09Ilv!ybA2KHc>4Krm)QxxyJtQ66+E8j~r(wBD?^6(gZ%<~+(J zy3`@jR7scgJ<M~_!Mkcr$Wfe+-=&q?)JX~2r_*Fll(jy{CuyI)(B~n#FOo+~HdNpu zkzUp4c!pu5)^sTAb;sh?0V<`TyM{koWf@<k>l(p5JrV1l*1c-B+Ljk^m-$KT)wApP z4|nmSuLm&~2k!+FZb>V?Qn+E0?-I>kQo-`n@05G`V$Jl*d71(Ir2Qq@?~($&TvQ5| zYUUO=s<v|#POO<T<(xy(adp8?&Up}Uz5%DVt|cvt<0yuS8?LA8P&eaePMU3<b}z08 z-*w9E_3L0-#CTmeFSQS^Pqs2aecUgD@1BmkxN-Tg9>PeSsolEjcC<q$;sNJ#tq`ke zP3c-|gI?>{Okn0<s}n1W(cod4UAe0^%X6747r)s92f-(Su3I`lj*PE6mj#t1A`jw# zXo7CcPo?g^<fjBE-xKcLU{jFINWA>4xklU?%JbfHkhq;7sH%q|gq-UVG1a>;Dxmuk zaPrQy0<awnW6ckCtz$;9o(e;dzFuNt_KB~e7Ew9<mooP}!ZqZ7duuTdvntmeB`s&U zsHU|T$`T^&g)9e=QIxsQ@B14^5aJF3e9eZu@QPbm(4-Hs{D!FOG;#;lW?oY;YBs9k zFQZ1e&*BBN2Mt}~DVQYHJMsOZpiyH7_u`V}>`zr_qTTm35-LQ}!0Mcd(6?{)GJjQI zxQ@hOWSYmrG%FAkT&ZCnxNyVOZ^;D)xxg`<wW~;+sSx`3pw&-Rd>_J8mEi4xE^Akn z$j}ZZ;Z*%Y)dJl%T_v>Crut{CN=T^$y3Mr$al1<BYLjZvwIXh?Na)ulmGSosW!k}& z-#rsW!ucN6KigCXwrF=P&@bA-?^QydYJ|QOaWxe}@BhD{RiWVfD}$Ggty4}(6<%I$ zZdi{lM~|ZY(@`u6AF0S#k9lRctlVg}GorT5(h8O+jRD1{^QQY2^VNa%IPxc5+~bfQ z{@op_50)k$Y^WTu=S0Z!-}nLnsS$bJF%zJIT3nCwj=S&6CRg*q7!PzjJsxZR9ZY5< z5%`QjdZQnS6}#G-W}(Yn%;H<4!S=C&9ts!PcLX@{m!8x+?;*d?w*QjUt4|TrsrP5+ zg!~H9&h$v83urj2uaLfO=j7|$!zaocrfv#9AE5pu<ZA2H{$sl$^=SL9UP<dgevD{E zP|HFL9CmUzd+PCU_ON@{ck1wP1~)0o!5vEaRCoZN0x%4hmtw0WL6t5qJV2o#l!Os3 zGs@Q%*qp^)zTBAoeM`qr5g|D{`{ObLZ8I+aHsf(JqPXy6Kf?t+;$Ta>^64QY%2U`A zUy<Xf@Z^`Ur<o`p<(jqmb!Dkk1fPxhHF48Z7~BU6)+_HNPd+g@srXZ)t(JqZ)NqdZ za-*@76rWE%uee%%jW?6EKJhCrW&2;&{I^2$eJhcggnaq#<P)zIRi=vwHftpZmDvzk zsbN){mBIs~MTQIN^ieD01=gt)<C(&P>f-wP|2PuTvXZ>Y?fc@m(bGBwLv%3y2oK9d z#GGL(+Dgo}3cel5$VKq61!*RDVx)CS4sW8mCBSB(ZnCn<Jxb0NOL`vv8)pTZjq^Ni z*d!CSy?r747d5T3oUO!Yt89m9gRB%^GiT^ZSoc-jPgj=w?Zo_!7%`_DR2wer*^0sw z<q;_-z6)Ze3($Xoo(SNuQDWg+43LrH$3EB6>-W=@$lMOF)LE&Z(Ug{+6%pv>k`R)j zXds7?wiFtJOAFPJkdiuT1cWm3!|j-Gj-HCYw<mX|_^}l{kEGVhn!WEQ*QS(``Ztj@ zrrb0gNGV&{UEteq#^Qh9Yjd@b->ZkZ771u_DXJokQ)6$vdk=Z!%eO21pC0sWuUeja z^#NG!%AA=xMV0#BJa$EvBp%)o=W4~+vqk?ioe(h_;7i+WuS(~#E+eT;30gvSUQtI* z+@7#syv=GL1t&@lT1xn%g-jviLpuNVh`yY?34K85K!YCqnEyu)we-F_A>FI1H#rr? zpPUi5jG_@k^f6z+<c`{+xq`C#jq>nsV4ehNUK2@u3ZQuPNW_-jesfrfxLxHtej?BK z^b_lq+aJ}QjY^@k|MS$poX~QnbqD`v;B4gYfU5wW8owUoTu};ODPcxSNQ2yw@s=HP zeNs$UrZAyb3t3B=2|e+Mw_3Yn`94DhbtO{BQ*p_V>29?CNm5(p|0Lww#3Go+6HT?^ z|760LhRh<F#$7e~L`l(r9{N%gD{|C3y3&Ky1`bUc#7fef)}Eg1flKrD?9A~0WFVm~ z4VUFl#PZBPH~(V)cH=NlG_EK8&&`Y;>T2Y-n{_tL$F*{`WGNvlNn_ek4Vk4M^#{%@ z`O>0!T@>{gCNyM=p!H`z%&kf_zC$On3io7e<L^EDx)S)mJa=?tqtDPkxv}&qBg0jY zHKf0%8aAwtu-_E*Dmr5=qo~FB&VA+3;8z&6EuUW5x6%KwhYjaC`<$)V)g!+B{|E8y zUrbr2g?ToN4h`(_JIJKEG#RtjtC9cj-F`AmAZtD2X;VT+Df?b(B1;KTLkB)F=UbCC zDqUn~|GmpeO=%0Z_J?Da$?a(p{}%)TMyI8zRjILD<v)_|7#$i0okyhq<<y)$;^JRU zFQJ#Ss}_Dr|8D`bVkDlPL6?2SR#2NT#{VxwBn*`8y0pe+%=KZd|C@sEL_Xs!^RAhD z$WlRH{PSqVD9IOZa-G=x9e{t=_bU6&By|prXLq@3(f_*)P<n(?IwQoK{!fOYh6*)F zEA&*gg@^uUu@O01DyP<&@eT36c)nM`Jh<j9c7|SJ#P_l>rXSOinIqGD%vdud`ak4# zX&Wtn>X((8{y$13+eFfuDkNR1?`0F;MPbCqc@n2uQ&5#>_`PhxD@m`03RnBidX^M1 zzBBsYUsOL=SI3sL2K80_dAJAu?9Yx?>Ovl81Y$R+uO_cV6ko>c#ZzvlvgP*i1YfpN z-VcGP2=I654c)A2&y#@Z^?7J;O7_^sqk|c$zI%kZt?lNIQIo*UI>g!e2Il<|jc2EI z-nO(|)U2clMYlQaJ>{0WRGdp`KfW2&J;QKl;e;c5w$l%qPHDIKA30DMQBhNR`n515 zdNVlPgBkbWo=v8|;%pZqSZse;h52hCl?0M%4Y^v1epie_i#eX(lJ>8^QH$u?T`&3J z@lz@G<NH6Srw6&dcERS@<{R)y9A1~;b+IS3ZNkZiomdI#7P9}aS2K_F+_FMWHi)3? zG*{#@hKy?+D(^kyAeOK0<!icI<cVWSftx+@?*XS0=8TP29;>Zx@Ii@b%a)pHf!Wn` zkE(E|$-6~PpU;N~HvPUMjMG(IHs3M&!*-qDMYWKd+kcaia_S<-24(2|-scZjCuuQB zOF6o|z59Nf7jN>8gmz5tsBv`hpw@WV4)y2@aNR2A#Gg+#0rQfA(Y!s}zu!#WRq{bl zbV^QN9o3u$GtAyqa`}EBFGx<aIWhngUQUBSZu@ovSu|<;DK1GHOjxw}I6e>iX8FI4 zKPKKvmSq!6+I0Yq*VTHD<K0i@ojOzV`vnDxjTiI%4rwy@1+QJkK0RUL`$g&x)XB)t z^6PIFxKMU-YUB3x5|>TOw+>je@LiFb8e&a)-<RY`7x=eiz~u+Ky5A=HiFV@Fyw-jd z9Jc4+F($>lCKmd#z$pQppA3m!UmQMQ3EiH2Tzp*U-#Y!KN!faX7+9py86Kta{@MwD z{-Dzs6!b+d+b+2!TcV;Ds5vVst?|{_nkGI}=7AH_BLB&xa2}0*D-dkjZ<|I_eAe=5 z*|s1KS;``9G`|87Y0M|F#7vwvXC7a9bVgzNcX3Vwxq8loi8g&E1I+a`)u&d05CG$R z@F9u{+dpKvrVf47NAVlXPR26QfI&&}6{%4^1*Yn|Yz_L^#3aV3IZ_ceyGS61LbvSR zf>4BHLOF*_q9B7JIhiEcxP}d{{L!ecF@apY6fxSMC6;{eg5?II{vb0C3&F!koK4rZ zpMsmXxE_LRlK2bWds=1wg7o*XCwkpUB)@Y4*_r`S9(@l1$UVUW@8_eIZGHj9hfg%H z-IX`-G#O-q&M$#ULE1agp$|8`vinKf=lSaqyyx(<k52&lCp_squsLT;v7&{v-A5Y$ zCPEpies+=vm;`C(HWtyz_g5f{#3LCP04OL;eD^L8LSrM)F~`GVk9MSQu0xmf`|gH4 z6BgO7Op1)aX{67L6sV|kiaXdb8nC3{ukd-)i2=o?rE2d$pTIrJnYkjZD$NR4sw%1= z6%b_bZn!`To;La-fqH3+#;{OC_ki63-?R#z;eiA~nMBQmsX&H$5Cc|)w{0YG|J%ax zH%S)%1)M=j!$Jd1tx7UQi<G3R{8a+Yq@zf4Ok4OaK~%W_Fl2R&h&GlqS_IzS*<4`- zG_P)5utYaE{An@LQho$pf=EY#yeDiC4o0BhWsQe`oRb=Q|1)4jzC52!<CBk@`9l~4 zC!n%4Jdb$;a1S6Ic(NOCnPofRK|i*Lv7Z?p<Ad5F$^<@;1lUB+m^8iEkTZ9CLm++~ zplO~TqV?b^vRw}xAx1gV<cN;8=v9&(^&yx$e^Bk<H4l34)Y$9?VP)P)Bw|g8Ozj3C zmn@L0cib><q*l+P16L{f_g`k@*@{>`0d|~^LY-5oy)6h)n*5dfeGc!ydrY8~gqZMs zus~j~Pg|kx448f?_&mLPKyx581Nbu>omA)G^^XMD;1#2DfnIw*`TXa=OUEGtGZzIK z01C7^`7VC?eyAdUkQtV0QoHamkkYLER(6PIRLrk-jPt9NBnAy2Q#|~B!baTaghDo; z26S?OW=weEfd0}f*^1o<IAKnJ*HZX6M{`>w`Loc?Mtz>s#Vko21_LY92ow&8GNt<s zK{0}=45Ao}BMR-oQ=tKFVQE<W{80eN@3ub#hoJ>s{i+*~Ew~`MaPtxREYp*Q84KyJ z!Ca8ZsDZqZf~2GL<|WQZ1&m-J*#!qdCts1wIkV;SO#r2_=r8WI1R8sF-8mnB5#K$% zHe!J+kv^kGLl<)YP`fn~R`B?rl?RA?d{}p8$=R6*lH+>nROGHnu=b78?vC<;TWeb6 z=3~!so|pQf&`Xb-Hw5vDk@9rp{=W8&JX=)kvdE}_C%LjqsFapih~eZ_YzkR0VW4Mh z-xWPv(T;lUBmSBp{_>5=U>%L?lV=$H^k<jIcY3rt1ttr)yXl!XhdN?Q6Wa!Eh`*V9 zgV^@<1IQ;*ro|G7I(*TWLa%1L(T6eaGuM9-5b}UGctYF@LVZNjaiK!#4lvn-%OJG! z0Z4Q05O-%A^Iewr-6GH_4a`K(pAh2ktbyzzRa<pv1EA)^<D!8sUPxLYI)esLYv+hL zUWMt?1&FgE$QjB4hnV2W{f<G+k$|f3AQAx#PYig$eYns>uU#Nf;O+8pHvHg^IIk$H zk_r$bx#$dExo6^!9AuDvAho+BP_{Q*#PI|fhebe^E3)8E`4L{xja<m3lnTcRLNaF% z=52|nkaql1sRl2=L{O&RU$0zm(#Q5feGs>LktV^@3iudoAW&gu;Po2QK}GR}H33Ih z1e|-8xl`iI)^?1}ogvoDf60K8q;dlYVpNI*ocuQ#!5zRa;5XnEtU1AvVbl|F6yAHr z8FvJ@3M5Y63~tgY-6}_Z%bRE+8Cm3AgI;;}mkU4@qQ$X{4OtN#e<6MjS4foa;P-F4 zp%I0D`Ta2@%Ad}X8`&bkrfY*&w2)hW6juRL>}vy8qiNhl`Uo-T1Hk;T3}3<%;GKGp zd-r>^Lj!zY9PMugi}77G5lC#qn;-ZS^7nGiut8nczB6U;d`Cu=KN64)BovpHKX8Lc zZ!@?SpTNr44<a|^!U1K24tc+>_$d?xm@pzHF<^`xpVp5VZJ=vV#5rTW>OE2hgct(N z?P(w2-$WWO`EUvfMPqLeJ$Od%i1dggz|3x612nbdL6)uf^<#vZV4#R#C&ml{2PBpt zbU*O)xN=FdM|$a`*<`}1M@F$#OCqq<0$|9rIO(SlGh^T?;tcBSQi`HT>==VRVNI!{ z{Y~TC{0Kkizc+q4_Ib%90W;#%(McSM@G0@wE2s<h8CG>Xsq7*6XGK$Q`%?JxX9#S7 zu-N}ZMd7eh=^YC4K?Bx&+!EWeb`ErgFAXHeJI5={BF+`<(-{B`Y=WtTP$=g$e-2or z@pCZ)g2m32xk_-0n@jQg>#rCO!ZN;IgR~E=@JIE=7Vcde;)|`fM^@1&38+7As~>}h zhrlUGhP2GUHTi=}%Kxg683cf)!3><i!$-W#IHS^M=-?|cDg_04=KH+;@`SI1uyUqQ zns2iDMyLs@2{MkLP~S%)d*fRCvj{5?1ak2jVh6|z2n3Hlk2jsJ&phwt1=tIWB<HvY zS$Io?Y~f83-z`^Qd8aqZy^09aa9swGrDlop7EKySwp1u@JlP-?hV48WI5036cD)kA zEOd){M-wbG%)Ta&a7Nu4EO2M#4y_v9BA`+wSA7qWMrm*b{2ebku!BRBVc^3F45yE( z5wcmB&AJv=>I(qB=YaI2E^SN!>J1oI1Po@%tNDq=F#zX|(T}@vhWqf6_zG9~w;>So zB_h-P^)Y%R&|-YHi?zQ;tjA!Ny>#}AZvjMPsSgo@kFjM;1P_I3jktMukBWiIp=kZ` zVP+5lt4*veHFQMlaCw!IOz{{a83n`{fPFEi9UO4a{jj(~g2V$!h~rnk=|IxVVf#S? zmYGBQ5NIO#+<OKeRXYa9<)8$l?kLs9-pgB1jIme;z-0nbJP~31*~`Co0zQ!LM@(ql z2`Cm0YgZ@&d5f*ZMh#0`H2}V+GFaCdHL;Ief~!Tb8?;}7P?7m5U~f#IjE^<tg1a>F zkzAAznXj6hQ3u>Avm0=qY1q*ezHD3!fENG5#y|`>%YNO(pHuw;?T3HQa8ypz;HK~b zngrVH5jS8V#v$w!BGEx|=90Jb!sakVVhHLhFJH^68g6NCHGl$w#?v?zU`DJ!$`F!x z9kmnC7tmH{rb(`V>lK-q7TWZbNRcvmRV3(*baP2miUN(IY~m4wU@u>!I>XTM_jNaH zHUO*nA)B20+P7y<-{=Q}>m+`K7;kG{S+JMN`jzpdC1q>K&|dh3G@(fK$N(Y+0Qmp3 zw+R!5(0daw5Wi_*f~p&Cu&c-RqYQb(a5f>$$VK*NQd`@JfDQ&+V@Oa8!q5^JXp+@& zwAulQGe!-s@QOa;3+8wMF~IMJBtAi|DfO;B3>#E=Mfp{Y*mFGg=A*i=ti_rN)cN_( z1jDzwE*#JkW@3%v1d3dqjkwiy04ZfvlG(xC7mtD%wm=fdgWN9x0d$@WPC&3w`{)s4 z^$9KVV35dr3B;wYX3m9Y7ASLpOWje2g~PsYUl;DLJ!DDS^n@Z93J@jDdjjErsLmrn zZ1n$tH!=*-2ALYW!V2e7=W_0ecz*vb8i^$K!uTl*@pWz_3I1$olD4lI08lW?NZ5(T z6kPSM3w!@^qygTIi5?W*@D9kd-gs}JaNh$=C(QY+F_QjK7XY15Jb}Gh^ymNe3R>D8 zaJqqrZd7+C{D~5tjR_zv0K16TBs9Mg2BQMwe7FfJM4(pCrL;rIJ<dxX%SAkv@!!|d z#uX7THpr9^iKdWlHHgcsLNh(8fXfTk^>2+-b33aqQJ}#UJMO*l^OYoSWMF`1cOg*k zWk|lD>Hpr&4foDmi0B51Nfg351m9->@Z_)CsnjSLJ2|F!9!{abjWkkr5em=%`apFv zv;z$O_0KTCioWU+pEtmY*)=6-oQ$WANSfTQA4fL&(9fm)C4wMC93jO+nv&42A-~^e z5D=W1wlX0?_SkU%N5~G@&eBR=&rV4nR>Y+Hd@Uy7pLZ#r-@!o*bcT?Rb+!iqDH5%w zlV#Bd=!BCG31U0600R9f=k@m_&EwP!Xdwohgn9);y|@`2Dhrtz^19o={{`YK7ga1# zG8~l$iJDP<UMaSEOd?ZGeP)Dlcv(R=N)$@z?@A)?;$fQo4C!~VJn)b0Lm;s4XZ_~L z{j?<c8w5tgZ-~JRUl`zL-CuT)Ey;0zqkHpg95Bs>I?(N^z%HPIZ$L+ouQ?+%sO6B4 zeUjV-OwEw*3!u!r3yEf0k}NPMrrfwOs4Q`nk%VS%VKp;Zh-@D0eAM@(`itRKg{f%+ z1UsepcSJq0gL()1hkGDQWy0>W#l{K1IRdoWQm-sGuYvH<$ZaHG!#&Y9xJn-qhT!02 zz*(~F0DzJnY~Vu-T8Un%6}eYGL0`m5MF4auHiH<6n?J-6vd#Qx0Xf{QL)EXyBUmfE z**dJi^yHV2_M5pU@MriY8s=!ledMTdrgPL;fJr0n9N*4d%%19u{%`u*YA{5QUSB^< zf6DS-8(O*c*t2EI)?l+INNO&(4b&XHH=>{lO_`WzP2fhV5^e{Ws0kc{U<?H#m9e72 z;BvfC+;wCiXdF+fL6^F<Ku<X%(*C!2s`#K={xJ{UXOnUGC*F{1fgFUN$3JG|M<Lp| zg@j7VE~XncEl2l2$Swd{3x0%lumpgmNjRllyKL#Qed3`3%%3x4C-k*@t}NVVAA$M^ zlCWXuxjRJfQ~bc&j@SdXX{AXRx9Gry>vf@hW!jiQW4G4ePdhj55cb5_c;{+DdKcob zaf|>v4Kk6C(`vvP`JOwxOjeBa`~gZl%tE{$2ToxF`j5H><N|*^X|2c7X!BZ75k(Vk z(8Cl1OX=-CXtb?+;CaRT4z{+2N7h=wJc84o;3xq9sfd|?N?Bw}Py-Vz2EAeBc{2?h z^yJ=GQ00+E=-vU1m{o>J7{p^1nmoI0@-#O{crEDJM-ar}@j`^Z8m-j<xAtV|l#;1H zOT<%nC@d)3n8MIN_NM#+O=WfLZ6(w`fN1TV^7&18l1v~p<pk6dURoo6O7h5AMd*c< zFJS!fU5ZcN{XW-ZtrA_^#1I9xJMNBT%La=?@m6Wzm%t4Egd=qxD45yPR<L<Id+;BJ z@&Gao<PnM}AfJIwlB56#W9V1kEEl&Dj&^e7m@b?fLOr+G;ZdSbzzRVckJuRl(7aHV zDC}_>a6TyZ@T@UVG|d>RZpJ8pAKG(6+2AaW2JAUe<6fRm;4KqG5&<f15!NETl!pq` z(H3#r`-_klb%2hD10U$Lp^KI63F><f8@#NaPMdj(5Jre|s4Kd}4A=uCtXM4&oWTqj zmL&^Mdc2F-&nU~PSw=h5g)bA#G|C!a!*is)kyGejx<LE~CpZi^q!C6?EHtwDih$4D zJSAh6u>Dl8pYhJ6Q>NS$3>3X$^o}6#T^@*F2J2hoB2lQ$W6@~eTZt2EiRe=#B9>t; zs?Xk<U(X^YC`U1S)6G$B35{ijfaXUMUi%V^6t)oX28v01jMjUH>#&;%2LC{PSu)l% z)}pTCfV_7`Ns;I#Snq}52(q}ZT%6bUHd0bdJApqH2mJtPo*S?b&~`Q9^PSV#`QWnN z2igiZ+Xb1$Yr++|w<S@|dQv=sd9-G|9C$ZsH9!FiSF>WUlhCn5<tztPOR6vmP*6&w zfbGxGgc1M_owE!{pv&#o1*$+eb^w~v0pQ&U5Mdf=2-rY8ApMd}Wi=e1h0Qc>A|T*T z$}`a-3fYG+0Dv3R8@$5Fu?CN!E5e%+r20=bMukxYw8p8#v;3Y~jaU-L(+MK#rgCcZ z{X#U;oGYc9F(0*Lp%b=6lYzK<G@wF#2#2Zs8ST<Q)5=q1%mL_kxkxVm3)iGrctfB_ zYmE@K+IAGI(AXI^Lbm!j<5LiV0R7Tyijv(hm>pys(xu;wR4B`DM)Y15)OTiWW=m-8 z{iSALm)!LXt5i+{J(xgq#3A&EE`N+{280qAYYb^!H)qKw8Q@PMh?px#Z}N<W=AP@6 zBtoqWHepEar<f*g0TU9J-9$Ol`XnWrbOfxt8|@KOjAN-C>vf!6C}<A@`$t=#B~X)n zg3$TC*U*guyb;_e=w}Zk=}CNFK`9Ef(yreQL>B9mG8$gq(1o}`$bEIq=;!n}1$OR1 z4OqHvn=*3HJDBkMqF-x@KbYg$*BE(S5HSU5uL!l<M(>mM$8KDfq~9rN0l>?Kjry}z zs(VU3lJg#<#{&L*u~w*OxB=&e)^a)DMWP$H2E+?Hs7b6#kPny?C<xK(2fUVIkzDtd zIErzvFEefkT90UVfC)E<^ga8c%ZwpVN-s_5_IvGo9@@Yg&{9QXfMt(tH(>*iATE=g zU2%^^NR^lsffqHfFj~G|#d1Kqd}u>h9%dP;q(63GNEJARZk~)N+PWK?49i5o5bUb> zojF7t15C0WN+*{uvo!+ufS>9j61v=!wUVW$WR9|dH>=j<ix_=IfV(B@dT~CKK;wK_ zMg*Gy5tZt;nMt!Ug8~G|X8IN=T^62)ZY#STR?zav^)VEW<K1VUGm8|__2keSMCjHz zAT1K={Z*KyEixAg{J;~fuRc)}R|Y=V*i{4Wsz5{_CU@48O_p!CmMqlb-Nl>#lKlB1 zWglqj;f3^B`qY_4OBRG6CUw>tgaH&k5b=E#bexI@3xu#I%zrX?nPUaqbs01TeuB~q zs-b)6heSSD3m0tM8?N6Aq(IEYSJdDa&zk|(>8D`^7*;GH<#tv=EOTeK-B|}`sCL0; zj^C>2wDjGudArKylWgTY;*UDp@?^_`wK`ja({xr5EEIgB^~RG*R1;3_RosA*To=jq zhoY|H7xYoTw!c)&N>o2q#X>5_yxLN=)`}SS?|P_L>kr@7$uzDQ;}ZhL;;$vVL9D2V z<VW7>%Y4()3orQ9Wa1DVfGATX%jEKZnoi3(lsp~E&lgbO!f3kS#)~!RdnQm8_FVI) zQsa<_VbUZ_Nd;VO+FpwlO*tL?;?xPbr-pA$YyZBn<WTA!3B|*DuG6GgHa-dKEcIB@ zZ&b$dcAU0&WMKilE(+Rj2g)XUZ0`>l(w$iIIOu3%$Ze>s*)ta>bnral0(i>h3-9H` zc;e%Bmqqo%`&;Vf!Itv?+t+Yuv#z?ew#^7!HGNBq$@&sib3u{y(L0h$T+}*|do$=K zq&BjsE6810Z5P;MOVpAw2u4`s`n##X0}~D9Kt2-<^*}!p4K4MrrXvwET8D)Oi!@;r z)dpNfYhc3+P?h8;K$Mee4e64gQMrXP)dWTV;!Npzh@}#(NJ>banritHYH5l1FNN$o z!0)goP$hGXeIM&|8D~jy`T5x;316&SxlysUIvk1Yn+ILNvqY73WD+>(a5{0(aBy?I z&{i?VKwx&TVUrA*J%0~+skS?fyYsw-He4?wa|BihiOt@n8~H^)N_EPR5DGmGYjM^o zPX(|l(?1hff4+;<`M7B)V_6e!;8}HUY7z6M2`5_G)OxZ)?I=Fm^I-9$m^ujN<0Raq zjQ$|9=UP13B6L!}JV4U`p#SXUt*z(8HHOJfZwv&=4+`8+dmHY>$^bR<mwX~O4*~+y zj_rCv*y^cyO>Tes?7Gf*rf8QbW&V*IlBhb7Z`@94!i1yHafq3Q*Ff<5glCjw9$Wi} zXb9{iQxH|P;0Pu0jl6dvy71(#0}F1MhVg5=`*~DL6pWzl3|x+Rx&T$9uMS<>?a<NI zK~To&VS$R>_&#`YpEZrVbJ;Dbfm-?oCKljxZJ&0eiVv%8Mj-I(MtqY%or^6h&q)uZ zna?Q%xe#T~pjSB2V!N;`*!-`K5qpD%m61Uh6T@)XpF7c@(Ky|BCLqmzMn*jMfB+HA zHno!V0h$CC`2urT$nk{a$9I*INUA+4BRbA5<7|T*lcq@>8A<~BvA;bty!l(ieH|j} z2gYa$b&05=fpFKZ+$@a^zag|LGC;A{qNYKs<|lyRuD6eY)yvF{4j)8KzJg0?Iwh7O z>=bGu#l+qESisW6aH@cOj2ZQxQ;}twdBrGOG{#`Jjb)_IAQ{T<nTOFRR%fA)9ty=! z2I?G1*go*4P?_EfV|#KJMt%Ed6qzU)OSJQPz6Pz0X0fu9aytNDl?nV-2h&_H4T7K6 z3H;gz(`+vd!k<AHOS|}}hQWS3B)om@B%-HD4=_GzFVomxn#cS&?`DZ#*0(t}pAE!L zyD&Y$pH!W~5jf9Ox$Hj}?t7=HzBKpw&)>}gzpU?aXg?b!eO-d+ymnh=^n+a`W<mAA z?#YNl@SZgf`K{i~vcIfva%4XnhJ2e}rekJ;>EF>`D{kN^J$5SmwnCT}L;fy?G%STU zE{8C$g#29zX;=+$Tnk}d|2_gA-Rpoe<-Ef#Y8&W2-L_da1nRHA1S329v&{)7kpbB@ zzZ`rk2Zt7Y)~|AyZ<*tRAljV`L*1&BkPTH-z?{GpiB<sL|Fpgs-w7pEnztl$E0+Et zki9j{l+BCC8*(i3ftu4+f*kd<QMWqp%e&&9#uuX<1;#CBk;q#u<B;rKU;0vo5;2@Q z<>r@_XnPgg!siJ_9`SqllLGymaFuCZu@b>OdGgIKobN$(ntK)KpkGDETQ&_6EpYmm zHF*%PI1vhs&<_UtQz6N`IHsT07^lq^`_skA{F$bo7pSMrMYm?s$I~hOIcPm`jq8|= zHYPL8>4Mb3jWQ#{c|WK_T_$j~D2pw;qQ!r7D7Io;_`vUrwl8#m1XIMqUNTmAr%2=$ z1}%f%+7g*#qK^m3Ft?%2BxgXjD=7=St=dH!cq5h9096@-RAtyFE2#RZG5aq?2~-fx zl!G*;KrP6qhL=*wo~H}oh~+vXnd<_t{Q<18fY^iy;6TrqlFg(bnJWX<RQ#Hm{F|c% zw25X?KpL~58jS#J=>E-Ux!Kl7?BiDAL2HU_{Gl@G!R17fs-h?r)@|h)0O=GO)kdn- zdR0akb<u?C2m(EG&vZ+W(VV4aZKXELQfr2NiOY<<X7k8+OJ`x$Kqyg5cGxDk6oj%( zmId@l45ccQa?>KAb%hR#BB2q5jv{6MyFwl$H6|6Azr{5*t3SC<1{z9CHl|WWH|x1| z;8VwUoYGy<eK6usz34m23?6!-@Y1dV(>oc!qNNmZjXRdE;xu)c!2B&00jL-gyV<KB z%wVBfinyiPrVfj+QyFu*UFNP4jz>4^7r!$DgbOI(BTA0!_AY*91qe4#z%O_*yE}pB z$emWJwsLdVu;Wf_+1Yt^P{7M_x3K@%*mAP-ETMp>1#M}O+1O&T=hlUWF2&^TX!&um z<x=ZeRQvmU<)v$X=P4#|n|jDO+jhrox4=7@(7jZ7R(4{SLQ7Y4Rdc~(7taVUXZDPB z%%@-}GN%Ma8lii`-!?#h6u8F{$DauZ<=qngnHA=}9Ja?YKz|%~n+<dffO)Dv4czn7 zUq5wsS@s5pbBCSw28ZcA1j>gQ;yne-M>%AhrO)=zZ@anIcJxM@?D-P+h8z9a2Fqt1 z(32?MZ5@$M>^j2;tw9IX9BwBXzZ;<$_E*Awh-$bT7YD2@K|Fz)O|hDyUMD^X%Tpx3 zdEO=Tp&iXgH<7S^T_xHk%7w{Rg_$j3Qb(`jSEWs(w0l8FUHoj^L3GBjSpAPbRxJ}v zoA;JDIINrZXP7umH239c$DNmC8bds9?UV`3+F(~KUr<@*^*=tFvdvr7zf`l$)3R>9 z`)O#mVBf9#?Z5urf34NsKV|yvpCa-1U)%ThTS+3l|L!OK{;$P&D9SdUImNKc7o^wk z4F~V?QX^k$#=II2Z?1BFbI7+jU+K;=U+-_C|CT8(zhzpEe=_yNKl!ZgpUiYI8QxqC z=INAQRqhij*QlC!Js*zVq?>|5YgyeX*H{|uz&)EEG3t^p8XUj=JtFXnTnqKm`ny@! zkZYvyZp$`TEUeEqm*o34L>{p{6`>AgG2pw;=?y27T-RR@55YRrUkneSy#Lp4d()o@ z4><<yZbpGaAoH>z$NnAm93aQS<NS}>ZDZexd-f)46vHWhRx_pMQlvnb<@;q~C9d6# zC~#aKAaX1xhcFzoxvA4<BJ1b_-kh_|O~3Tz8f|{8r=r+sw>}<z%SHcWFtdMh@ajLA z_n)j5(#1Ku)MW4va`AdLyxH>3n`<_|dE6mibTWDQ8%^;WO@(pw8=B!CH2R-Qk;we) z?<OGQo4km=1%)<3r5S~GRQ%g;@0m8+{NWdfoAs0Yj;OR*WY2Gmu5>RGdJpE8SG{}F zJJGI_$%Avx+04=9r+oHA`ZG~mGX3qyEt&4_e};<x3_;z#hw*#=i2)e@`1Jnqx&6l{ z`j5~3KR&(x_%QzC`<9FT$=`h6@;BeN{LLr&kI(%-KE40=BLDGu{Nua(k1z5cAN@Z* zy?=b3|M7|b;}iYI7x|A5;~yW!KR)_zJ{~<MO*bHtY467+&v547lStg!F$gcVA5*fQ zI$<8lA57`o)x1Y7&12bpnboHSgln5m_ZCQ(W#yLWI`_@%z%PH<(W)wsh&DH`fA418 z7`F?s->YXkvEJtE>mU(}UTeB+I$K$jK92JLLV%MW&TEngkRc0fo9-_%4}u;S<q3_R zC85C>X*g_6f|b6Z`Vt@Y+ZwM#(dZ&tx8+e2*f-0>G}uKe!JW~<=D6cI$$Ra4(<2JK zaW*iC@$p17fA>d9>T9k0EM|s<5Zw_dgm+ZK#W+vqP4p=BRgxg_Zb7k_!EJ=_Ufy}0 zul&Und|8VRA1UB~IHusNQ)zZ*cairhNQ&}hNv@<3nUR+%ageUX9{!r#SE~;c6DeRh zWM8MZ3)&t!w~g9ABM<))kuP?D3+GYvy*(qBA5$bcO91yi&MG?cL0k`>Plca?1gRSy zS6T`60d(2#gnQ^$KM==dZUX-IwQ5@brn-e03mw}=+q;Q{Ut{Tq<s^z_HH#~rdwQ$d zFu+YxJpZ03d~1_8>8m_0*xOOT1n4tdXP_@uwIdukSdqi}D0nY7T**eKas=4@E#OOb zALV^C&n8nK58~=ncf+`BO|EA<)&a!cAxy(cr?Q72NL%lpyMUY6z#p*WP!_NbW=0e6 z^MVXbTW+2JAPMtJ!<0O~W)D%nl!fvp7h0yL08-V<;w_8k=#;9GQqUj+^RrR&9fXxY z22rs*!I?qHELbJs`y&TLU{=R=q3*7}Uss|{vmE!&zA|zlGwMHmg(2u~u-0)g*z&ca z9mF}xqC0d&PI=Oc{2GEgreR~nPG*63{X?P~$0ziBjp+08M{wdI+hx>tH6Vk^YKr=8 z5f?bbT7Hh#41E0>dh?v-7&>#5>{&0Hw`|^6*bQC#(pdm@yOztAE7>cC=dZds&Yv=F zgg8^7%8tq8;ek7x7RB>(6}&TNaOnAMf$Pu>jDcGXrZ_I~;0(eyr5Zq=PLm*cwHvO; zg}R$Wl>N%=z1CqLP5zQ<JAcOQUz7NEB%QsvrKaCp0Uw}gtDkp5=ME6m3E6dYj9!Qg zKy9zS0h<wihrQ&$B(dsRkWhKn`K1-X_Se9a^~a+6_i=4ww;CRLC=;B5%O{9J5s%*+ zC}QF4N8Ybqs7(;mi`d!~6#<mFQCYlAT>7-qeii-ZSu)^fD0lrZYok1n`-ffk&}l*w z2lILaeVVJ(dY)h{2m}IgdC-`+9&=Cn=)D&*ripL*mvY1{X%BKYMk@~LC%c{$cRhT= zJtY;ROuyxOw-3!61`Lq-$_-cl!W*Ez*TK;3Imv8v7}Q5ZFn7se-1}YTz1jl@!g8V! z^z7pKBkGx_;w6Y1nPA@mofVA?s~=XOEn@t2=<$eQt%Q;{-Aq%M3@_E1ygRehiz==9 z)nA%{QdAB~-m~$`gqYMGH0=wsYhBk#a`4Z58;c<g8n)R=tHzN&>&==Oorx))2JuH! z-FVJC<qWaLKpqXyUipE!M;IQgDo%v{_vR9KeDan76srM*RfgSyc~9{4Xj5O#bx>18 zDY~(K@)F~f6^Io>CA)zSxd?d2W64!;*?~f9e=NWHp-2Z&(NaW|D<V{GdtX5|b;*%R z+e_ekFKF)lO~pV$;2FnNied{&^CQ$eeBdg%zF#|7ZTv7!aPABxZ$s>$xqVTUN$Y5d zgqj+n=t@i-6kXYk+Jda6$Xp^cPaSLSVAUyvc8Q9>{=)k!iaR=u>wyv+5+9nm*Hm_^ z&*&JfRI}q^?!wuvcn%n6T(nkm8JKf-p4X)h_=ls~e<NG=tWsfhKTWG{D7Pb<j>K7; z^!n{lw>b3gS>m+ZOXo$b0T|+JDkp;YZrBwj#%WC%d)qV1e#{;QgfQ1%9)@{4KQr+? zTU6NG)I(zO`WqNfy_dHJ)e9&7=n17ix>1fU!TKAa(;DL~M9!otbw(AJ-RrinHytNw ziY&1mOhCz{`gsa@dqj6FQZ0tqFL5qj_nLzj{X~V!Wv+<J`mxt&d`k5y;Pbkvj^|?w zQRN|g>Y7fX(8Ae<X|_A}n;*Cyc4xJ47=^jKxX`e9BSqDLV8>+s&Z@;V=U_cl?B^<1 z)Hs`Vs9po;K>g)Nak6%O()c+L*wUV0EkKC8rt73*FEqtS3EwMqt-o}ND)^<!&6%)j zak{e0ep)-dS?0jbZ6<_>deWbw%t}-pwrxFbDk6h=o>**>SseNykA^pNC<E!JWp)gf zzkn(<J+PlsEN(IG(aem>2w&5gv@4f3AqEP0i56T*Hx&M13>o@LlrB~vt@h6-)nhSL zhemBnT~xy>`aPMlgf|SBNm0_==7NOK$U-&bN2HPSzg;fD`8IV0msL3IRbvJ-@Xf*; zi57P($5Dx#0u_a(tgF<ZKZs4EU4GYh+Eps6SA;4SGz|gW%r#QKw&l)%Dd-;U`~qo| zgLl<>l$f^joFbAbm58_1+a%%Z970DIM+$NhIu?~7tqvpD-l2{#(6eZ6Srl1iBB;RS zKDVVGq#DLPKRQ4b=f=r7J~(%K9OB6q)UbktmGS%>f8$!DBJeF}rq>UhnKZ!ri`-Hr zb)F6@r)0VyFa|ghm^*tYJ#0gCapO~hW53hv&zDix+YUv(`trz-`GIb0`Q*>^I;zN9 zL$6{i;*Q<nl^@l8x3C>*OX4?q`h!#J&!aouE~8OGX7<M9rjHU`^O$u#y`wsi?u^lx zxu&sPb01A8Tqa5Y@2(A|O5jwp#IZqfCqey3iI-A#$?9(`D}>)Ff)bCXmFyo!1{H!A zXR>Gk4bl9`zLblXCb}~9HYVzsv@{up5+?4d?rT>=HQ$#_ZeB9KS9m%6UNxonNr^6V zbexXqP6<4oB|6&}ST|MHXn&=MG418W3dGOxLxe!78Y9pHLV<SIVD^Kr5_Emok%ZrA zCb2ScUA^(1ehcCXZ=5s~Hf`8tS`(`nl?R011W`K0Z3%jzyfmEb6b5-utAKMu1Q-We zQoKPvv*B$K^Ts?2Qn41_epV|=k0(9ru&f`JZ{kkmgnn#-7-0B+|9B95B*BGLWP5=F z-wB1PLT{Qe9N0%PHlLH>c6GK2Bqi~bcd2?&32B#nvrY5o)i{HRHcJH6k+O1>qc{qh zw<I7G=!g2Dr1_tv;!~;~{!bcX_zIFLF1EJeNPOwQMi^vhxoSz&`YR(K1#q|njaXnp zDN0O5K+}(TE%^8n6|JJ)Pm*|CJT=kdRcq0*qQQ4n{;$&Cz^n6ZlUd@Fmu3`bv6Eg? z4hY8#KO>0Sy><`}2O{ESSb72}WYB?i+fCya;zAVruIp#)^vOvHHFksWF5*pkKFG2= z|Bg?F1Yu1q7$@8Bk%5XvHQF^v<P|W>8;+t+So_FS3*XjPq>L6(lw;t@2P%@Fu*8MF z`LIP5j1oi#MfC{$(HNFU&FAiIE#qUoFm3B>aeDTtu;l|8mtxu3t3qpQH+KR5;fOJ5 ziHY5Ts1fBuE&cu6tCO?=9hAHQ^IX%kX<D@ZJu9U~GJSh7F~(l2ie*WZ31ToH^30qi zJYwR<Z^D5U?4Q1Gb?Iar%aAYCGBNge*Wo75CPD5{<hWvLkR^r3QadnGYQ*MhnKsJg z(H;fcm0Da#lGEKssnrqN;DhCj1VdSaN~BRn3g4%TNz8yL$5;Olnf0f&B(bm=twEkE z7R;VpGYI_+x+bt$n#H@04gb@X(q@~9>?o@nP6KiiFsD}4xXxP8sG6^)Qi0PEClT9o zn94#L-!DTXJ0>w5Y+_A~j2>UhBWrypI?`U`REITpOlQ4l^|@rkEPF$jV1jpi`&$EC zHzFg`v?_Ov{Vz9dJRwF>iBy&DHB0o3AjD-iynZ3;dz^m4&YYfwTA%NlGmNeZrw}hX zdj6gWHG$yj1MObmNK4hl%<4?&LCgD+T?e5>Vq4%sT8L{W{Z?+v(b(y9KU#G0o2rli zHp-AjIQTXR&y^k#zxiAD?cJ~z`JJ~BJ<;N53y2aRdS41+rox0giAucDtbxKCTnHVp zR7aMEX(;3znfmEwg~wt5CNn$41RMrNJzg;5aGYsjpO+E7&4aUsFG1;C=j|NVr7xM% zTHUHCqb&3@S4*)HY%Wm3{=LjkXEd`_?5@;Mw4Jt7z(%+W1Ub1RSTy&9qeZ89W#J@I ztqQgx&<4UZZS{x9D9@jL-a6=R(AKa3oA2ioy`=^g;UM0T&gIyw#76jm1a}1?c?j_b zC(^*0<)9<=TGzb_F}B3<R5Gp0RcfVs02%^WPHc^!a9GFCrtqogzIIF}@BvzgV);w> zeq-E&+bxZv8Rz9D586_kMFi^alt=R|lvkCnLPJE<Xf5xKdsx{g>W5(WV*UbJV>w4J zKZ!&-sku>7$ubT`&#!!4GJ%Y-)z%N63hw);03`Rh2+tKelz>U#Z{7NE1YUflKjjYU zCS1I|T5FrSH*27>Kwqn&txPI*ARkLot}kCDL#xG$pb<AHpr^sU8Nfgq<rSm1Er54F zq%6Us=xAuQV6|!5F%SE8ntj$=yNBa2dZHQ)(8YvE2ny0QniRU4W(-c(Y8D4JLpm)T zY5IrT!+FBwZP^@82>8*0d5%DBYc)RA6{JW8?|(RES%k`NfUXs|;jqP_vP5VNh(4At zR7WMYZg+8_RmzrTdpd)W4e+hl06apYxomc{q5sOEbaqi(clxI?e(v-BP3_Jj|0Qs# z7y#FyP6RL7@)>cFAo-DIYEz@_kE{^6!qp586SvLOPYZB4_ZD=oU4QM=mOol@Xy5nA zvsxK>GbP#o%xkS{5~pOnh@dn_Mc77P3sm-GmfiZ@@<X*2J>A(>7(ET)&7dW2Lzj)9 z$=??LV$&j~C1r1uos3z+uG0*i*+wPe&B8Ouc)&C(O0*BHWu`f2F45xZv16!Aped}@ zalE0IM+2fg80floyA0lA{LnQueN)THbqm57;nQu}%VY%ujs5De4dlGT2N_wrvPaYf z^RQcnx#jp$1*=ljPItWm?5K}zf_Bj5En3y2m%FlUefoUKu;V<W!trLr(~Qa+RBeN4 zqhJC15l0jky1FU&k+sNYqTIz+y9HU|oXBc(j8?#F{JB}npk-qu8KUEGul+;is<!c} zvF9B7@%N)UuoqFv@ZUae8z!L@GW)+D|DO98^5j7GiotN42-Wl*_WwVWy>pPQL9Z`7 zwzbE$ZQHhO+xE;J+qOM>Y}@u8+rG2kbIxDick0%yT2-s6ll1B&{j2pnNp~VVt(q<o zm=+RN_$&Qmoj`W6Ii-O4fbrb>25<>C-gG~aOz&n3%R9}0k{|$&^R1swH~(uc;7O29 z{Z17;2THIzO4(ZiNXPC5+MD&O;~9Ql#SfEihwml1l~1{Xx`5en<)k)c!kAR0URPEL z7c5Ae2frGJhfL(qoSnGrMx8O(zj@3q#Y`D+Mkde$Go8*h`5Yo{a)pZK*Yuym)4#@3 zXU~a!KHa2g$I40S*wc>BASN_=o)vGaSR+9K%nRlbl|sv8r5750^0zg!TZzh`TyIA* z!a6?KFsaJW>vrb&-n&?{skK7@g3I`dMcbqJDfL=p+kEcd{3vv9-mnPD&Ow31o)^W) znwAUgcPc1{L_@R7>(aUAoZwXyieq;zP*&`}O)G((zapO_>bU#`%I(_0(CZ`tFndkY zzCIGlB5S!l#+83+AKwspv`nq&HJM1R@9KuDIo5rVIs7S_DRLTctE~-R@J71x%TvVd zsO>{29$=b^eq_P<6164)Ud7Y!bxp!-d^t+RL(Ya8L+o!~9aOl0Stt>FcQWq=YBa8_ zm{P}WxL{TQo3|W{1K`gaBF(sMG$=te_bZFohLRfFb!bARTi-MZ?;ldr3r=@AQjT6~ zgis1kcbZ+Enk-wx?~Vd*VndEk7Fjd@iZDJr-(^!EgDTA5ChNqiIuSbEB&x8FCC>uj z!eN$8IUq~VX&qwRRqI%{J0Jf}`D2Gm)1e~yMfoyC&6THNq4p-HttQ(JTpGGPK^;o$ zMz=juw9XU4spc4bG!2@nbLA^Xk(t0c{ZQln=zs#l3|rFWGByCXo{8G9W_v#kd%)O; z@mwFD>Pr4qEKI_&6P5k$8#C{zl^xi4b5RHALNRTC8*nMBcq=*&)nlXZZaf?&o(oOI z@Mm}nlS`NZgcMbLPqSVaVsyP;zfa058C$<7YB{S=0NF85E<;^kU(CU|Wm&O4vDii& z-O5<7q4228%>8#7uK*Qy7Bp4=d;NRg{y8^!m0n&tZP1WnXd#-pnpuHnlQv$uFIAQI zSh)=0KIl!=z)u#AUFKIcLFAbn(0bbNqe;i#+x&cruP88nMdnTBzGW=89+!nF`GKFV z*!$8CgMU~*@QbrfEKs8v@ayWN_ls|B%<Ga^JOH%X%T>vpdZ&!C_vzVCXow)BJ~mXh z7!x!nIO8%t5*Xk<kA=dnAyI@!Vt&U&TS%~N706hjbn)wwgDsC(avnepX&bj)ujHvW zA)S`!NmLqdK3eshuK3Q>CVRg=eAv~<z&7SP#to#6)sy?=dTG4zuJi|YQa8|=SZPf8 zt_p5tFiaM^RY$Uv+D@Q{sepFKZ_E73R6|15YACdA2rDME=o@tp-UjMVbejQC9Q$`Z z`LB)t6+XD)nJv+QMw6JBRle6TEeKq<&=E=SvV-=P$7ikS<l$p>cOJzE$~mECs8Q7X zkx9ZjDzx;O4EFc)-2q^jXZ^!)W*2t%u;OfNCAqJ*$n!ywoHO+fufuq-k^5%4BP?Sj z8g>PGslk;p4LqEDlv$j1bq)(?${WH=RsG*y(aPLJq9!m~Zv^0@;m~E;{%mkC(`GMM zT2{r>cIlY;<)Kdw!gTivXhYV5dCNAsRAMQci}$(Wt}dTLd7$+sOx@;njKEvOhOWEl z(6~W>jo%c&!7lP%`nB`kh*O1Y`~r<AlY1*Z4w=nbraKsK)6uRC%|#h&A-n8t72ziI zfp*oks+;W&U>J@|qk{gbJ76AaT1yYEbO_OKJ*Qmp%dCW4f6qhs&K|&(Q#9lTj4$Ix z+mp{?vKjK@bw2(Dqn26iuF`Dx3b~R>xO43O6Q1#KbZd%e^c26!$Y3k_i;AxDCxWAg z4Kl0HG4!KMg`RIi5MYCC8x9t($UUi$+!=L%&io1kMH0}{PC&OGZ@F%acB)laWYg4M zBrr0FQSQQwAy%fg#$<@(Wtv$!AEl{~<4QZ;vF`CW3<o~%%4$Vj7n4fXc@^3{<p!Q9 zS&}^t|HyH}0L=^I&nS;Y3@_h?(say9Uvzk!&92YyE<LQKhT&;PPRFj#nyk51D8r|N zZAY{O94f0giViKcv!<8L>@=RsQJ;dP^du$>wlGeaavQxX41s~ua|m6#ECD_Pyj!XG znK*#a_^?Vre=t$s3RL!#)m0Q5*?i0vd#tb48@=CPgS``_*jcP*XoEB;`o1BpMy36m z=f?_aQDcSA@L+w6?4o)x^Br@2rkox~F+n1jG(B20VV47TRy;Rbz&mEAZtx=$M;|XI z=3Tm}E6t7#=r}4qJ7F|<o^B3JSEQNOxPm_GPwVhK)!6~d_xc=9p|{3&TLX5LEP2nk zo<Y~Rx~vnwO>x>76BVmBPu!aw8x?5+mYSABzim2ix;)$0A1aPyE3cY+vjF0j9E+9S zA8sIkL%Ra?uJO2O#aY`10sr_v@~DgIxehzJem?%KzFHdckOEX?i|2OgR>N6w%K`bb zeL=~A(He;+Y)V%Z4^MJfZJVD9vpx-T=0sVN?fJpEsZ-&#`>jnEa!Z&cyuIHM)*RO0 zJ8o>Va?(Ssm-w0Ijqydjl1aO2Ko5zhBGLUEpq6cis}(4l%m~YiQ6TSeARaT4_WDw9 z^U<EHJ<!I!XY{B(p~CYGI`5oY(hZ(ki1||92*zgA3Ca;00eQ%%x!(I)_HsW(3&>#W z(O)N22VrVZgqbspG#~~nHCFmqJORG$>&M^uYou`E7G@I3p$WjqqV(}Y^?<>(8?&iN zF(h@Qg)99dCZ3Bol=MM|UW1}Lxz}+SISj0<M_Mh>ggaNb2bYq|y{FgW9Tk*vcIJAU zudLJW=G^F&8GJ*@jkvl!*GN^gU1Yy|2$~20v9Dl?I}H{_tQnR@e|^_3W4P=mvXwcl zZ|40V%(J%{bL()gdY}c3mKYBhMLG7hLx-fVkBOFUf&RYGsnN}_e!&##aKWX!Vb~{I zpp_nMR0wJ$ACKbRXcb?*V@VepI#)42TQ86U(l}RW{-h3Cv%wtryrDyU&Wr^2W<le` z{`cfqkek7j7rXmtzI#gYigUDU;wvVz4z!&3I#L2sWVkL=m=pN36A5#Xuj`Cg!s2g= zcZWGMSa#H6zY3X(>nuW|589?rb`Y8*T&s`Vf_*lCkWL#C`OGV0{EoSmt8JW*y-u@{ zF#gUXd)*U~eJz29T80=&!$?NH-iLOnAeBX;mhFH=5p>xRN=^4YA$snU51UAl3p24H zm56I4G85nTf<!(yazpM!2F&MOqS0H^o>Ss@v~{6=GCKXY60@DhH-^}$M#lSe`C8os z$4x1<^|3K>akikiqGT-=QzHF$3X(NE4xdVqt6VutiPVkk?OYW4P4PMtS9N`O=$s*< zg4^8jTO(c(LuL%MvIOxbZ2{;B5&lGmuYDfWOK1*Uz+tE#sBh5y8A)-3JLkNkI68tq z&fWU~Y4mkUUt#VnL71JinDZdvWi*^*GsR=!5hvj<AY&TaxHkHD1bzsAo(6ViKQQ#F z{k|1Gt5@*SR`F#;KSXnn*o^nmx5DI#2?A8f-(GL8HKP;V<^p(OZN&GnBG&k;mOZA2 zE8JzRzdDi<gf%J_PvVM&aH8)i>zyG<Nl|KnnDULpT_^W7zz0~JZIlvfPa0`0s8I-N zEH4hOpf}7UG)skrC2XM2MH2qDB|M5w1hVBCXI#QTOZDm|yT7%UO)j`ja~VbaZqY2V zHzscH2P#Ja{>*d}D%_M;LKts>jtrgxQ}YarON}G@1Zb#oM!3*hFh>C2F0`o2f4*k< z$q<yn0z;T9J9o0fNx_*$Q8}xkIyASGAvc1(>kP&3Ag-FT;6NnQNK<;i_<9GX$>f|Q zPg-ik@p%s*#%VG5rG+;ZPr9%L9k_;8y<;G_NE@x7way5D=L2;+Bq{XCCjcufXd3*^ zMGXz}_${b{4$p+`6nY1cx+1n<1EuVQNvo76(&GoVrg)*AE!KREF_5e#)|h|zDaV~n z7G*+Tm}S+Ff!(YR+qL=!rLjEW*Fh%}d39(>ri9HU&a-_&T8%#jbi4xco?Az^4T~0> z4;PN{U9jSj)5(VFLddRPb$2%07x9~_fU}v;d2nlGw@QE?t4~Lz^`+Pj)WB!uiI#!5 z)~VL&SL5l%PeNn1^`!)lOpaWIH>~^8xdIO4+v<@9{XJJ`hcf)C$}aoHb*Yu|W~Ri> zExG#hN4Cum)rShkg31Sa<7Zl}a%WDskdAa?#*m*CkZ(#ZJ>#H%typeO9m*9rpbEP! zx5>J9SZbrbm@Tw*K&|*P*U)eFL=K~dHYE>-Ts{{%nDjnr5uv_P*Ws8f3OyyvxMEdv z%l}k?Emt-^wQ+5P5SM|!N*xE|G5g91(Yj*ujs!$<$sy=a`UAQOxX{(E-m)WTwTiVK zfqYRh^{~W3JHey}_d7)_m!nyug_g;jaRr^2#8fs_0h6;SwW<SUiUe@L4i?K1B}qx- z0Y&uK0S@9!H@`gcYfx~m24>SbV38bX?02U&ix)yQp-v_ff=XO7H~vyptB{#Zf=6-( zuMoOxVq?XgLR0}0?O3=~%~Fxr<x#CS4y4uuR}NQ_Y~s@HH{M_NU{iLrO8932ih-C# zH~7j6;7wroAP#eoThrXqTO{5O$gh_xgAi=pO0Q~%W~i?+=9}Cl%$Eg+x;bgq6q<%& zd_sUeTkb&qwve>NHBr!fv7E~@#i<e&HideoMfy(uL{Ls4yn+Mz55AJIx*#XREGaU} zt=7ng>)B|`T}#|vxX&^**9tN4`AApi#ipJYBfKybtPHdDGUVop<Pndzk3ve(fzh4{ z&m;@8#Tb#H`8>i#j-fJS85PDwS#)Z!T)x*gD^f=&M2QRS>VR1Uy`rA*z)YkM`4<O8 zS9`MOjiM#**u(;i*KI61=~mshnp6n!3C3~pq1KzIU$u}sW0~e>T#Q~kk4C+sZQF7} zqU004OZ+1v?$B9)g-G809(p6(>VM6K78e+GDOU{cJJ(Wld2}8h(O%4BoE6u6dC^^< zY8R9&PHhW#J+5WnjAdrKb}s1NTq;E~!s+@TJsKZEBP!lCmEKV?E+hli56GsCT+qrF ze+~+Po6tIQCYgQ|80E+Q-tkV}3<d!&fIvx*u>lH`XqXgP?0-<oNuMOe6&)g->=#(< zd|;ZBW#=v5guF=2R7Io2u$?0L1uQiMLl<(6zME+7p)lKlh(Elb011Vs&iHIUtg)Ht zR7o~lds?2u9bE$tfPV~9LPKF%7IQ@M3o{K(RyrD55{$KEhy)ogPr&XA$;@Dp0g|<l z&@dT{&pRvGpl0^u-WFt|H6R4((f1aN1EErfNEX^x4U7<BnBg?Wf=#A#OE#VcHBYGr zHMGoo+&K60IRzBWaeZ$+g7tTI1F6y!WWX7a7}N~xr^{e8-*+9G1oFwllE|eSYW20r z+#2`*md5z{Z9ugDU%kC8!@X`;HtsFYiOyo~87ABIKZ(nS10OWP6WquffoZ!8sQjW$ z=57Vimf@y4c5xn+?%myYGJ(szoZwuA@eIJ4SSuhX0;K6OSHB<F+V4E_4hyT6@ySd; zjU7ceBloiyU^O#=9Q6gaa8MlZYqv)1e2)b9f1Yf7pLY~^(N<v{hlOq6v6=SG0IZEs zZO}l7fU$7P2S(-lmD?|1pj0%*Z_RE-pw=;2TC&J;sYO!27~2q|_f(0ee+ghl+K}{| z6VYqkuX7l0%^4eq&K(J~smr|UJzCNbpczB{R(`2>zN8JxT8UdTtjPj<$-sI6OZt%L zPNaKR4BYgP8HUac4%!jxFZSk`6-HFV(4bL-G6!+X2(~}X0gxh42laQTRA_g$#*N<f zS*~}j@da09F8(RwJUT@P&?-KuH}T0C<@xxVr&sK{MbY-Ka$N1M{yaZ&+qO(wco>XW zbjgG4w`tGQAj?l<s_8orkn6376ib%#`E9{gySr}JwhutSxxj5oEp+b&pbZs|mN0hQ z0*<P@_zCh!voeY<MFv$bW!q<J$EoyT%5hNhPP>%o{3l!a{HIifQILD)p+L1&j73yV zu|i7-pV-1xAF2~dSueTtPII$PP1^2C3K;!ieJ<LnBO^g9s2la}?9B&XEaY|{M+_%h z&&C?pJU5oyEHhZwU*$6t4+#n=FrprpIMS}dkAE)vt&bc=Qf?haY_=Vg?PgEGErcgC ztta5&?$|S?Q=e;4%wGu0#1SU$=(ZIodd09DQaYbYhPbWAkwtH7UofAFUkSm^r$1YM zNlWtkV$c=r)l!>`D4R|#QJ7P`_%>pOLSa&vb7P@k{5BM#)Q>(;ka}h*5bc_?Q&mw` zH9#-6xVlx|5UAXy2WE&BrQBFir&OS-SVCpqU!x!6iIb!%d)fel7*>D)^}+(`&D&B# zPzR5~h-1R=ZdSBW=5n>duX>?j!ah(xWE`*${(|~#E`KiEU8~OsVM?^*>n1&cU&X@w z)lVNC6d(D-!tyE5tf&OexOW`wC@bx?iUCGSJ{%uT@}8B1e@B#^7xlsRwSTM)gFubk z5A{S!q0d>Ny~+nv%A-MBhBdwXQbEP7)O>u+PQ=g*)W-$N0NBhaTuliwo)mBGfHI4o zJE$K7Nzaj$!XMvMA8DO+Y41YV4=rM+f;vK{g=*!vF{hsqff}H~{Ck1<su5h&7<1W$ zdXV(UKA~t%H9|;MkQ3aDIm)}|suhcs7ZloJ;NtCZBZ$8){Sen2txDg2!8O}}y{=`! zG{8v1hNVK1D#}9HY6a{uQsu5ffyNR&d+l!?&xzK%eKdu2*r&a@jRlU%QtfhuOmp@a zcLg&hO;PM5R4Xp*VJi{3X>%FI6Acf$=wdBQsE-!cJN09wLUBpcybLj)^<rkX3w<&< zwrVu>FOlD6c0kwY60>+P!9(Ka#&}@#16F7B(WZ(Wb5-vyVzWhPaMDB=aD`=f>Yny6 zU`<xws8U?#?wHN%vuYzoKjD!jN%P|d1Fu;|r?oo7Gi^~$```Z#ozOTjo$H@vOE%BX zFSeMHH&gBAR=7|jevGiE0KSkh_PfD=R{h<pv#>V7k!Xbdo(rwbkVy6=snA@)P}IaJ zJYfsagp%IXaojn5evdDY*U>!l9WVoWqWi<-fV>6&tB+Z->y;3L#($f<?||mi5pjm7 zU@J5#SVzIiTeMA3uY*9#XJSxeOU<tJl?Y#<MCaNLTFk2jBV&Nw$O;?Sg>50oyLvcf zxeVzEZS>_=JA-ad(SY+#n`(j10zndn4m^+d@is7j3hf?+@!J5p`k9CTCPrzH{bR2y zCIT3MKs92PrvE^prxC($IGa*<tk}L8J9rT<t?${J9v8q-a@+FVMfg}6HaDwl6LDh* zQ~llv@%C>}KaoM^ia<$82oURI1Ma8@#BLR)Xq2Z--l%8<RYq;n!esH*eJtAq0d+Jk z9TMD1L;GMMhHn*kiLyemB3e*_okq2LX&5`vh&KV3t;swMkU>T3@Sw8KBiImf1`?^T z5@Rs8DoKxP<$w+$MFCUyfSz;}Vx3-($g_!@xk=7o3*L~{@5FRUT(lBqQ)cBHW3x$e z`&HN0{3sjUO;mX0N}Y(0Dr18SCn~)YS9XnJqZw-OMao3@IE#qO<(sVasb%o!Z2neW zvJ1sxEs*M@*(6Xyg{h3W$vlTGb;^J`!!3@h@;Z8AF%c7SMMF`eO7u)5iN=0vPSA8% z*u>po<%mtx%eoWh@X^tQUP<b36nH4gd_L&Gex+So(=-6K6v@1LbvKbQx&p$)+~l-5 za?Al`!eml=5y)#xqj?_LkEA^FfNm%%TtIk{+gT(gIISVA;<AdLMf967GtKfMOEH9M zRdo~`{!&oLktroHWp06hpAgVz>Ma;_Yh|3}1s3Dj*Dh-<DEh?^FEJxIsg43~IzeDX z)L9Vh#>#lxi7Z6Ity|RCk4=YPV9!lcFXLN3+JU6U7C<$9`NUe1ycCg(G)_0Gwr8T! zE2N=n0m;!j$ksKclsfuT9^L;)cnKRaVKd{gU2n|kAph6(Jp=JQest>dNKV{dq`eVS z(6?#R>1Q+o6!^AczFn@(jvgSN1R*}WJBoLxqHh3a+Dsw9BFvJReCZf|T2g|CaKCye z4Oo5wW(~%0rg`1bCmFZ!F53rL35xPWXqYp%AXZ2?xsC4nD8R|F*HMW+j41+mqVZw0 zbi6*ERPjhW`s->U2fW@%88-}AyxEEJCQ=@9csFb!=p=K^-emw1esD`jol)0-HjbqW z1UG*^#PGD_(r|06M`{cvA;&CgJeZ^L<KK>sJ3Or8)?hdDf<Cj~Th~vDtkU3xPzYP* zLAp#d9<ihG6@H#eBWEWk?^k}OTEI*C9hBDX(`{vLV0X`n_qv$sJ{QuLPGyv<9Gzkx zOcaZM>|znt<onJ}*eq-smqi*X7Ex6-w6(aGzr!}M-m~oHqJDX6(9$7Klb>nbbHvbb zz@cN5^qH%WOH|u0fNZ6ae5}+7a$d<g=h6{s54I4{yjkSB{lxeXX7;}cmb#~t=B)J% z#oyLGQXpuW@A4h}^8TohDV%%B^?df)KPatnFa{#jNYQW2nSsQIMj0~(Xx%C4M^vG4 zI9f{K-0(F3i#t_(wr6P!@Y)L@KPRy<Xtk>D+P_Tfch_ncf*t{0Yg5)<vRfmE5%32n zNb!db>w*2UuVBc!;~fbPkdX$qw(1?9AWo+~Xm<(>F0MG*c=AkFn9><Ep#M!K|5MU| zDMIqp2P*h@_PpP@c>=#v)Q=CG1^(wcNKK&vl7}7bHXr+gE*ZZN$;~<Z+#zkCYUDGc zrbyj|F<`jwNpY_!b@3b_Zoeg29dIqUn#{FzhIh1q4BW!Y<(u!i9O>bZ=f%l<<J08d zc<!w~c1x*_EdVIAmqdC)7rGUP_!D}dUg@aP1tiRcyPBcQq5kZDQZcqhtNd7(Q{ibE zu3xZ8LI+sdj`Au#8O?(t1kq=#Go2SLbve|j%|)OyG1C&ZRdj5XuunT*O-||kH-CEv z1Q&DdJwf*iJ7x_zk_XabDDHny%V-j!=Xtqv-vSfA)9J&e`?se9>3{FIUE}#nUgLdK z;84^o6p14%Gq!B@ibS4s^^2}1*@C{yU!CukFcV<>G+5>3l{RXrGG~HT&wHfAVo;vq z*Ge`}9&In5;6ym3;sl#FN6oQ0<|p_jCNCRZ(3iBLmkT!Ft;^12AUf17lV*14GW?LG zt)1ec=!AAqO<IJ)dielR>xieYorEbMPA#_?g&fCcJ*=|^F{n12gx5MGWdfx`(%5gb zao6j`|CSz28@<;T-&R21;l&sQXO;mKA<da0e8L1|nyi?lchW(qmjY|drHbcHzn5}t zkn7dx$B+s8Jt_usdDkN|^z+f#hF$Z5kw**4ww{ix>BF>q8FqW7E@NuON2g^vT=ZYd zp-~M)ZdE@GqmEMPz^u<Na|LW@YB@aVHEt%v%M#s#zqyC_evs@pk{#wfS|WDasY=J8 z&FJda58+TtB{3+DgH7p*9XF_e5N#uM{VlC|9Y9Jg`#$KY=wvP^WDl#YGf@-Z9hQ+C z;&P0y_Un(+uAyO{y=9rDSQLg)vXLor2c80eRTRKzos(=U7-ua4yRkuSP*X;90(6oR z?vpH`<5mwfVuO=uJmegQ(_;<0*}jsLYd*cZ+3VYEXQN=n)?PE}>307P)I(NdDR8S( zTl`2*FTafg#@hYl*g<Z9w6odZ9x7LRR=V0lSA`9^DVV}!vSl3X9ky!m8)m{Tv1T;) z0Po*A&~FCB&@gE2fz*D`@dHoQzl(%m9-j2VFx{hp=CHJfV(SI8#G@R={GeIw=%$sC zJaDtPY$%0<97}^aV?sM)@yWp`)rcy=)RUT<bFM-S)@V^<iOZG#lW=s&Qf5ekcwdRf z26dW!Zhe-aW^E{sDITaKD|OUfy#jof_LLo3d>X}bgYmxjYA6F%SH}D)(Z(|QhxAUl z-X?n~U1S(#>SiQ3cU+Jc5y7Bm*ru-iqA+b95KdNC`^;A($W8fV#!jZmO6>RM@zX>} zKY5I){lekvPz<8i`LMI+dFplQ$J%=l=h7P{9dFoPrU2vW7uK|KvL+a;4h3GCms=1u zpuc{&9P@M%1hS0cYWE%u>LuHSVwn7xh(PW|bNjTEOJK2G#(O-D%Lq9wqb%mt6<(`X z0V`n6Qy$Vt+;@v_TRg9611;H*<P$Yxc}IG_y!5w?qNx)0?Ec!!YE+t|aK}56uEunS zd7cze7sa(gZj9_$Tdy~aW4hxq&x)*j`E2##q|r~BebGD{IhTi{f9G<E)9sGE!cOM5 zURp*;a~Kp>*l9l8qw7&{QtM@LEUam^&(2hjL|}ZMN)B)%Fr^xmkEqFBFyZQo(Lbg* zg_Sd0{J1wtR2Y%gz-<SmHpu-+i$$1Y14+`gCU|LXk@Pe08EzYfjXLBlo71>Gzx5HQ zgNz=I$h)v`tV<Hf_Sn^n=I%O{99MZiT9$!#cy4@Be4p)q>eR)?#w?$^c<505yTy)* zu3C2_WQQ(Cy2JC)q6xh4HQNzY=)$(<{fy9UHUD4P1wi$G*#)p2o=$53x9NMb;y+>E z<w;m1FLtQk=ka_}hwr6fV(0)D&>x=PyY*h{-@QV$KyF}gI55y~8_1ziz6;lnNN;2- zvj=PVa6u*w;@OnT?)!Oy8Vj9LJ1^9n?sAk14pYcpH&0qTFrs{zxUvn%u1LS6ZJ(15 zUG?N_Q+ex!bw%73M|X|_DD-Z7PsEBG_h1A)limB9j%YkD16zj=U=$DGwNj!#lFJ3s zfhP(aP@*wgoeR^uzNfB}-z>u=#ax+cIQP$J)9$UtH-Y3{v$t$$W0TOJ%Q+I9^F694 zBg9Bx)oFu5wxyw}Dc|ZKaRV>ckgxsrDVnN+))XyziomNEOX_;pEivK2kfm~qCf8NH z&vXZVrLNV79NGgSP_^Z+g3C(5UcM8(vXY(;sf7*)%w}Z7&$C%_CnQd5+9*ZnGiv54 z)x!w4uZ+G$N7|5AbupuVso=$|_iO*fMe>y!VkN$f!9VAsTn5}*zOx@?8_+LWFF|_d zzcHdr3AovCt%@yM6$Q+c6ynEo{s{40KZco{!=gl+ES9pWf-hZ-BdaF)IA!yJaQyi( zFZ`ENlnMU9bG<6LlGWh=EU5wf+y@157g*3MhFvu!Y9oXzg?e2p3oIZ@s^0*9bKv;P zi#=x2fS%+-oS+Z9Naw&5Pmt=H<cE5j=n*q#7P(AC09~<$i9l&Br;H-hm%?^Wt&>tT z(fqTniET0#?l%kDadc5BL2>B-!Fk2rW=4qk`$%>>NfRIgz#j7|@gn>$j1)d>r-x_6 zOk`2&l0;|vrU_yeBS5|wAPO0XLR)j<E$-5(9-Nq!s-c^kmIify=Oby^T5A3_)z?K* zrrxcp%C9Tx4lSlqQB$GYP*-D*15>rA1j)pa@}#e4xOKEKv@}^tvT6!wl^d~4(<q9^ zd&ibLPWH`B78ymiUX0T>*nzt~mRA;M={xFRU7W2|OthTxWJ)_8XMj<QpVM@}9*D3< zM1RcvynZx4Oi7zq0(nB94Y(75l1rz*)ZyOIjKrk%=YbTeg;GN+tpp*#nV<`;)qt@- z?S=biVr6Q6eqVI`P9SQnr+uMx8J=HiT0E?KS-7}rS9~G6aKc`B+Nz5&ViPQcMb#Lx z^^7#eLF15F&&PU4cn^Ljj_MI4@s|crIgBPAX{L5@LuHH?CytANFAFYxAy`OtJl(&; z(DBZT^-d?=Zx6H9V17>1blwM*9ChI090|6GK<AW9L9Ft5dtTgf7UBo#9aTeFK88Y( z%!z|PgQXX*m0*p41%Yjv@HZiJo}Dd#S=<dk4lDDof16q=wzOfjZiaBN`hz%ZHQTC+ zVm9EQdeLlD)!Jz|`*(9J&q#Vblg`N34gS(I(XI7dW_zZF?e)mDYwUgXk@VVVCG!KR zWBV|5?UD4`;)mtC;9`9gc!03F^vYF-_p#AR#w|dH376+0L*cRRJhUQL$LcJ{b?U@V zvBTEu{FlK>`3rA1%Z1X~R-K#)-@vl-FLc&}xq&(i75D+$vNw#Dk}HeV=r1ysi<Va3 zmQbC`71*S45HvrRR#S=Pi9CW+P*$3?2YM@s)qw^;1HOY$7|-=q<J-iHwmCmOJ}Nx4 zOi=LF$Uo~gRz4pDU-R^2T2<*vnIF0XH7nc`Nbzt12s<8xF~7GBMOOB8l^&Aa{kzv_ zzI3VKPb%ThJ69jMbfS!t1Y??_dEFY~4m8oD7lvN@IB`K{;-yCh-q*OZWqC_Iirjp0 z8$0&g|K{h?P9wv=Zi-C|%KbEaE0=Q6mzkkgKRYygn&3-&HJ%pUn<~6O5mlrlx>u`% zK+r1DDIu|oNzvA^RdL{Vu1YF*Ubc`PCVjkAN!qcGUik7S$JJRp{cWGf`6L+zrhz2v zB3Gxu?GS4ztyDaDM5L?lB3}!*a2aD<sXG^450uiWO4jD+<$^*<O4T^sG(NdxTRYKM zcSo`mlEdi!rC&r&t6V=t5&uHf!!HiWnC%cvf2RDw=K~%AOt=>kelWzqSYEZ8Bwyjq zPg#(}hv*UQoW7dUP^G>+W|%eL+ofMGVB8$}%Y#zE`={<5gS4tB<$zlF=mRbic(a~L z?2P{@VGX{BI#tpUCYg~?|88+yY@*<Nnwc%4$Bj{Ijj%F@P{|F(_ORpAkiqLkJ<cny zIgdGm5OEVs5=3TVrsrV6Fw+4h_P+H}woUxFxK?zA)Knylm+;wLy5=CUg{rA+ytvKa zgPF>&tdB{}xpH`A$r(TMuKcyyW_0tRvMKkA#%gBcd~4}yVO{7-QV+;9Y^Z$}P59E` zZ7vplU;x!U48VpM^!r~d?Je-<1i$eX_nW;Hz%8HZFmtyiG6Y5G&gx0kt4O~WDbAs0 zvMOTf6PdimjGP*1*LMZAJ{!W=5KPWn5YF3jqIDs~szR{xsw{xD5!|%Ab&3&R8rW?O ztl5S%aP+FR!i(jOSscSu7`NpZF3&ghvNezO=-sp!H*BnbwJA^?_pYz~h5I!dFLkm@ zh-nqDAa-kYI=bYnRN0ub&3}#BRTiVA>ZY#lb-2Jw=jeme*dL>7<aHS6%jjE<)4m#` zZR<721T+p;d9~`|)|%WZCXXKEs_yTm8OXMTB}EZ?`VQ1O+U$O4nH3jJ@5wnErI{i| zGYJ`C?(`fQQcv{|&caEMh9TyvSusMlT$plRlpHYII8njlxrN*4$QD9${Jje5{eYBH z)yfan<wt_oo<e5TB+c$Af!AC{X4Oo#|I+M}y2PWw!_Xy4bH_z}&-2$r)9=HQ&$i1> zm3qY!tM25w?gF0X<F?}F7FqjygaE)jd36>N0FXf*Ko^6-vOk<39l4jvne>5nmLG<l z|B=YH3=v%bL=wTzQ&aiRnBS{>AL(~$0F<%YN0cDwpWLsI{6Lv6hJ2vg_5ra_C}n70 z&N6?<o5oP6G;cnsGJp8mTn6P{KA%?+eo*PzTqw$$^e;JR)LGGQB>_-fr*DdUAlnl@ zt1^D|wV7X(_F#Qvfl$=Q-yre<R{gm^l>DUoa*(LA3+JT)PzdKg!+>^=KOCdC_qTaK zh9}<GW&XG<c#xF6qz`fcsO~V2$o!zg;N_0a+@E*(K+B<isAc@FBR%BGdGDus=#=_4 zAK~%=FM%IKLZB6(d^pOzATJt1pwivBB+9*ED>LYnyK5l6i1L8Q52b-n-X-4)f}l-v z-^%g<E1Q0jW&T)iGnkYJs!#VJP+0;u5qUrpgM5I>yBRm7{!nodFG_--4-an^c|e12 zKf}FRpFbRqAKu(${^*=|;FNh{Q(}Qob&#Jwi^LWB{LwM}Ky1;I((hHhulysm?>|O0 z{Et!VftH73!%@SFwDB;g<Y`_`>wrjmXE3Ss?>?#Pfp|N8ht&b)W}l*Zq0;jBP*r!C zK6BBi@_v7n_Ct04{ZcXn-JJDXRu8Ca$fZ-=g$a}kMpY;Mf~*5t3FZS;^_L#ZMWV_p zU6Bhy#b5sZ8Qwno;fOmpJ}>|soPA|i2jsEjMN;*bImrc}x<Nl{t_MPUy>0+*V-^1R zBxl6l$LMi)uy2o~q|1#1v4K)m$!Rku%Hj%es+^+Qkci({`dt9z_)hG0q7SCg0I0)z zzU$5Ak*jKb=UZJjfAee=;<7KSKCP6idXtFgqiH~*bG-tE1#=L+7I!`e1GoNQ5t?ks zRe&)-DngN)3V&Xl-KxwZ0+vT=tvH}aVbnD!qpM7*SCQ)8%*&E0)|_;g9~&J)F!5}b zSrehYq$Q;%PjuzQLUNn2AyrNte=%7*{JHbuvQs!VY6y4j-~UpW8Y!lFd;X?=OS&|6 zzLKPAo3O>}VMBFLQt$C<RtcopV|TeSY?MbTw0b+ryzR-iYBSNuwr0!3ULDn`bPr}C zS77LSyYOfKsgt`CcZ>Awn=OH>=gu0Ra2O1d$<g0&9<awYr_`V(YT$hB<Q{7Z#qWUh zN#zndJd@bt&$*a~#G_4MC(w$_`T;tnu%64dxiFu(%Z-6fErwKH@Kd03;~w@}31*G0 z6I+J$=FJx)`b<%;WXml~*T%UCJr>4MI9IPOm{a0T)_!V?bSQTrz3QEY)T((D!mUQs zDoU0D_A%NB$B+Uvq!Pc82wR>&<^?kZv*o=t8hiuZN&iQN*FJ0WlmY#|M?ITaW7{#( z#FTD)7B$iiYDy-kLhSR`xQvAIQG2%|lX$i3!mpM3<x<HC6pOAf`&tM&G=oB5_|w2L zC98fREu<w%A9r$aBP}Z2;^<_5BWViU?C4~BBW*I=<Xx5)%3E`g+NL>(>bQvVxFppP zVMsQIrTF>rH1c-RG)6^DRCk*<LTyb%_mHzYEk#%*DOlc)G|IV>a6)fa29*RE1(lZz zpjrj00kdE3#gaI<9ck%M>9c2P6nmyMoTN>Rrjj)nCDD-8P@OHJsL223QA9*Z?_Oy8 z-8O4D?xSp0**W5;JnpAVmN|UPUjeF;xDupHqLMxmqC9o6&YF{>L3Jcl(I|rIOqlHW zb0MGv#w*@ZU<q?iwBn~K_K8@9X$EM;t+{EHF?M0bExBpcAr^Av?MX-((}mOz2kW79 zh3WK?ri4YdbdopnMGTB45i-d-$db6^c~BYMq5Kce{Ix=bX}^ujUSnK&f^DS5fEj@j z$tKE5*o<H}=YVc8Wx1u0ZLy`PUUf2Lbz*vgUFeCipp|inaArPc`s^G28FYI}MN!4W zJ6c+F`E7%;qRC&ASE{2oYtC|{1lOJU9PM?VjyO{8n%cjj9K;@{)!LTf_;7nWSTUlp zn6shkJ1pu4qWUYFkav935EN&XEU&l;x%7^kHdbI!`k%qzE7;?C5M@j&4_SmRiy=Gy zaLFlx`AW(bx};vChrtZD9G*%6x*DClJIaM>*s<?yNgS@p81qNy<9x#|7>YmNyd}yQ z^F?Y%dP(|}^HeZ6^yr>htDe%pnpym7WNBy%{%~aS7mzgr%y|N}D9+jjXERg~sD|k4 znVjp;ntLdcydsakn))eFyd}-)%|mo0yyL^mMQZ7t<qc09OwS#VX7^#nc?X)<Ay4eV zhH~~evp|?nk^^IOq(41C^ZV06MNHZVEsLw9gv7M788mCjYVycxWXZdBP}QR9Kmhf$ zlMM(ur`s4mV*CPZENMd=OWXc-YUgqN@T8*qY18!23v(P+z(Awy#ZwIcdaN9k2#(Z2 z8VTkT_{8MD7%AowxV)J}+>WbYppjjqPz_*tq}-QKlF5HSR*W;}jY1}Q3z9R!md(+L zt+J?@s3*nQ)xfA7iU3NJ$mZWDX-5cnWeKj8CSe9WourZs^Zl@7)dkhS^c(`hORG%h zy)Y>!C;Ahb$=_k*k4o_W_T}i8{X;oW5Zw7NEc-2O1ZSF7xO~kyZ0{le5`=L9z)Kbg zA0d)PAQvpmOlttfizujoF7koc3d?7|3|O{X?DDQXk01{?Du?cYPzJGt2SzDK2;vVV zI)_oV%PfDQ%MYsW*q<g0gi4@c7!Vo9uD}mkcn+m(k3{Z=mj`siZos|o9~nm+&o3gL zhMpG~?*dH84w%%%B@f7+MGwdDGaN~tM@TG=UZyXs696R(L~;$R41h}(Eru<Rm_UqF z1_6l-tW4iv%MVKC-{1yL2@r-nOaN8}A%O_091H>pj5>=d0)SeLRXL4r15pO>K$gS{ zp$tL-0gNg@0K^aaz%|D&a^7CSG)w?j2B7`pB=I~#av5rQL=<wUGJiO7v@&xZb(dju zVL(*>F-Q|6aAgpa2oTD^{XqcKS*#&I)M}=msXcxk6x6fi(S8;zAM>+da!K?u|C)co zJ{td<Fx@|4t^Y;1E<sKV5H%8P7`@9MDsd)a_eaY?2^3J}LC7WOGWu@AjT^ghP5{)- zCfi&oOdv{tS4bjwAk_S~fgh6v1IYK0a{{AgfkACSmjOu2q9^`nMJ)BB6%rX#nZEOX zEP3?*YRTv_D)~N%yh9&<sNRF%+i+k?!GwRFH8A{f_%dwSE{Oco6+h^%eLwq;aR?|1 zemskBkO%aq03xrz#b^nm5cbE2U%~U>0g-ti20vC31}O9QCBytNv6{;;``{0C0`dq6 zQW>N;0+cckNCXgd7H|j%wHo}#N<rj#K=d5>(m(qpkNRi7$Y-JF0eKd(|4ePVgh3Pw zKnW0qJWlxI`tcvvgNXdc_5XzF{x{*b;(x+c|BJBd**STh;9M_y;V*fEI}Su|L;pzj zh##HU^F0AkO$#z$<**h2%h{6wDC{MK#6j`-3=Rc~2$lWN%ON5V_$kpv%!>Avft-6y z5W<uJNXeolh!qhNNYH+$$RWz~e`>^s%0XWIrSL-jdq4kBiIK{G_H)p`{rr!L9w3Di zpbP*<7A*wxLnVazp(2S=qARHVo7ua!I98AnAQpL;2(BDL0x3c{I5<Lp5?zDsA2qtS zIEMef(eOh>4Ecu!qJL<>{~t7z{|61>|Ik464-Mk~&>;RlXej?LG!*?q!_U7QIaK*S zG?f208VLRi4PpP#Ap8#v`2WyA@IPo!{4X?!|3kyi43g;O|IkqW-)Q*%6Q=to{9kDJ z{|eV3*@+RLmd+1?%Htx6hm0Ky-~4F0PaG*oxgQKgggPMPzzLJVd>g3Atzc0;_i^iw zux%7nbVPg#_kQ4-&O%{62a;Ey{a!*o;i6J&B?l(o+cWhIttCX#k7mMurzb8%I)E0U z59K5tazq>}2}PKu&Qbp<V;)_Q&zyh`u4%ZCfw3k88~Gh5Zr|W&>}H;vP1Ye*nRR|n zXPNA<DXzJ$w4=J_(b&;6-fnSSpqjo~q;GOGdo@eV73-R6%8?2*$R>4a@~n7~s^PSk zoMF{q)3tuNmbBho0`^c};SICCau^+_at@sMf(HVAgDYj$wSfypM@V*&2NLnRF)}F^ zBTAs?a-J>41-n4&Y7!$q&689hAjPkYH%*e6zT_mSVu+TiJfYLR!AIJoS*>b(`*X0= z_R<<DTJ#=NG7&>Kc4jkilXO`ruBF|?olSS1ab?J{bqa^!D&>BSyL4#QI0gUGNjPcE zxup$jp#VE|qM*fm_<7Bn^B#gQ!kS@GNjSVI?N=fN#h_=$x(3L-b!S^C$u5fO<36G) z+ks0@-X+<FoyLo~)+{5=)ae;&Jc+<P3L;@HH%i+j^f>nhFUx&0sfMg+w`?493d9)! zVILu0DY7OIy_`A8W-YGj&k+Rt`m@v-dQjt`vNR8rIzKxk>5@ci&N~*r?`;ciuV4)T ztGBe4?y1{ZZBYd5h=f4UG!ZTZ9@0X#LSipy^ziaO<4+-XbdKKKW*qQ>E~<|rE#BY6 zv{aY~&bERc$*Vfcv|s9}=K~sM-Xq4kb`q2rlnVr;nFlT7)ZHi(!E|_dzd)S?MefyF z8hB`|OTAEGd(<Y?1ljK{96Go<acSW;u!3BsP5=0iA|Eg{qk8#z!QpFBKkeWwhc&!x zBT4JcKU}HYWqfAhz`d^&9Kw1z-(RUr6s@0Iu}7l<dGX?3PgErdq8-`3e)Yt31pS?J zHqgvY@Kme0KU9N<ho7Q>T2o?Bzlgfv$?Uc?Rk6-~G-#dH8V)-qTxg{@I{!n-v}^<J ztJmw_L-_=3D~Ou63N5jmS?U^sT~UlgJcGpIwJbkltH;9>WIPv`kQ(CI@$2(BmK?E6 z#yLP~t=1!=#CggPT@{F4`{J%qH$YQ>3HR}KdMb_Jq9fj>5kAWL`a~68PQx<(NUnPt z`?n}Pz|>DXP4d28$5cfpywYgMPWXn>9R8K&LrU-EP!`QL%g7#c^lWX>)xBE;?>NWw z$Rh@P%&z+bmC9+8E{e}gWoUD2=j*Ms_E*PNzG<Qwi}v!P{Q%fl>d!^|ZqNIp9)^Cp z#2wb!MEHe0b9PBxK0G*;&zHYbN)7-`9aF!_zdLkXQWU=2lS+V}a^Da6a-n;V*+vHL zZS@w4^_Ihc-C+GTX~PN@bC;<fYBd^%I^#cHW4|Gb)bVm+p>@AA2PO)93q?E!hVS>M zNGmaF+5FxPu6@5#?fmG3z3*+`+sulKz`%n<JgA-VDQXvXQ**0wT{kl~iwl?3d8%XH zBg2||{%FaJOf-4?+3q%*iF}uE=uw_g$2+Cx=P^vgyT9%{zxRljU0QHbfN~ZJp*cHU z=q7LBOjCk~7g4=4D?AzyQnL4$Zs9ysoEe-XlaX#b2omxTy^;3Z8rEZ*Qpm3_j%Sr` zMrX+{B&mitwH{NBGig=@<xS}}W}gpc{8L6%msVS`m7xcv&Zahw9((>9NMlniQ=0(w zs`5@kMnIg$q|sFMda%GO*=G63L%z`>wcM&lmxmOXb$Yd}dS()et#!;Uea7qi*!s2l z<sClyB&EI1E~-=~{^K(CT6c@oZ;Qq?49D*cPvkX!*UgN~k0J)t?>Y06lgchJg^%tD zOBWDJ%vw{zw`c9sXG*Gtd(Lbphs`>^6uXq-!?bmaqV)9=?`!f4{iE5PGX(=H#*emz zBr%$2GUej<+Et5n$C%~#qx7*Lt~<MDd+f}2#598itHzH)_XT*W9a70%9!Lm@2_Lb3 z_zkaLd(n6jm!)YY3|4zfat|-S^6*mXgHYV3Z=60GBlT$1KkT(mAjK(7X}gaw%KB{f z94yT`<<Fzz3^$0Aq$!TZ&`;M<GlNO@B61<t>AQhH?t6(X4ji(&-ujKX&Jmo^f88ol zL7{UzgzYCj^i;2MY!jE>EYejvu?DZjN>od7v(uzadi#7M<APkk@Bg$y-WN{h9X_5k zXkJQ*urDsIa=Q9xpHvrq>iO48*$WQRct4-hgvRQZFnL*3)i2yyf83x6rA7<|WJHJ1 z_84_*Yu7wJcBlnCY*k+G{V{XnzNxsyg3XDqpW6(h1Q+wtnG5e!k!+B(^LQCC<a@eK z`s6bD-X?e+>?FB%uuxZtSN^GaKlfGrMl}P6;gnz{nve|q3Wsn0a2Md4eOP7bBC&DT zR_h_h{mTS&*$miSFB64k<{49^FH=8Idl#2>z;b!R%(V5-y(@{;Y5X@CotL?_8fl~u zVcNyw43S^VPRl~vUvTW{g=?pz?o;D;;jA3wsz*hya2I3ooZ1!?#xjli(7HUE6@8A- zBJ5b|Cz-j7Q%u=UNBW(pbPY6iDBF?9KbUhl5PutIwx$z5`$XY$lO*3Q)#cTg2#cq| z25zft+R+4^Z}lN`P0%AFGM&ID`|NFKVg){P^oUxuKC-7Cn$ZLV>09s{JBAKz>{lt^ zyvx70?z`1}{D}PQ{<d7(!E|4$=V76nmNO995&RPQqj-73Tx}+RI6&>j@qO#trxxha zQXYpd0xoDOZOlnV-*pvby8xQ?_&61iA19(rVg&YWzPuXD!^(Qjt=5WGQLZu*tKaMG zj%0}nU5Dj(ua*RQ?%>F>ouu;9;F)Jid&cNWqv$Cc5^ug+XNfsZJ^HYS#MhNAkcLj) zG^(J9u=-I|nn$KrM0U`zg1aG1ONi#3S`W{Pohgd3tjjSCz+L3idpIY`2xtn0FdW>g zhBhB_>wDwOz0KxqS5-I3T6GV%oO5(Ffg+H?e@aq=-Z+>DIgQWz;=WuHf*{#OR&~@! zBKmq-z-S4?u=#dtPaBomI8jbx)pbIM<24!-W~k45P<z01DwiTnpgcKbRAji~0GfJi z?5s(w1>`+!{>!t2=E=XbW?icSaac<{>Nur=E))vJBHvSojcF)bIr!H5RhxRJ5kciV zNPAm@r9-8Ty`JBay^3wsNH?Pgv#u{WSsaiR6fdW1OS$G8Slu(D<+pUR^ml)FCS*gl zP86e=P9c~`lv7L{m&266fi-E;kW&3r1WBet<C)f>q2eDw;<q5%avw<;sm0^{m1WB7 z7B9<zOZm<v=k=#H4HPenu8NW1(*{m=<P3*%ifK~b#x{?&$}{Q0`3#N01{PEn7dY2S z)N^IDZHpp^dIENRY~O0-yE*-_2+39)W)ZB}SyvbnbBwBG>oMP|ah(*bjJOV?x?clI z=t>bep%m98KnF4%iM3L90j&Bd4Gd`3Kn_+1eoq<6w#(S8cXX)K2jSQ8gsTOZI*|9! zxi6Unek_OAp&v(aJvf@sCT1Ggj*fJ1DTXN4=m!VlQWGFfX#7S*;&FnpTZ(nj<_m)q ziD!A@Xvoz$ghSDaf;3D;i>u_W;7!Md42~0xiyfxqM9=imCCWNH_DfF3`67>YjLs|^ zSktsdr<A^)6jH5;q&ym|{E43`8E#8}K1p!s#O2$W>wGkf_Sx_BT@1^Q-ixnjFXZZE zqv`V3LnJnD^gti9#qkJzM=6!>hV$#Vxq&fSh<^`Hj^ZWl9s#35h`X|GX$#Tr^#`TT zW=D@y((6knj$P7sX5H9>guu=RGTJvi4^BP>PP4heOVfAl5kRvI8iDm0;_6s1cJNd7 zsCOZ9recJG5Kaa_ueX1Toicko+cLjRiSG_ca%GnGRdClhJ;Xe>DzD<7z|BxUteT!9 z^@K0Sq8(&*h%nGzZ5vMT^)hLSw;euXWl(d>p8Ku8rZ+}T^{Q78rG!2g0#=Dvh4`!S zKDD5x4rb^49Z09(U4`>C_#}3NPlt>eK>d)20`X03;&!N=$+*Ns_|`OJ<V*PZq^W zva-@=8ek!(=WK@w$DU5ZHDF@l&!igJyfL_J5`eB)%hN&BjPjqRPbC!cl@vELq`4ae zS2P+=v}oL`jBj!ZDzG434nQ-UEABDOP#G?0ea$NKxbW4wL+kQkemVzwZj<3sm~_53 zlzV({n;Jpfj9z%)wS{*>+?-Up;B~b)Yig!}CwrIM^cncP8p6b`Y>4Z8q1#8;Fe>16 ztAB;R@H7FPGSUFf#LSKP@Rs=v2A1=QEB*$%QVX#X9kxTWHmT`12AHeEF)L;At~B53 zZoK#a{GF$IgBQIt6Y<8O!e@4Noc+e3#&^9m1OCW_!_vcytu%C}x<uTapHMqUV*9q@ z@P1zO>9YRCY30{t<(J*sv)$Um>rW}V>n5+auDUw9tbI+C8?|`(f8`8cA%0B$srJJ9 zdEWNvGXKSC<Copsv)$Y?y`gu#p@+whN_4|jMrT81J!qx)I(l5XTqawsldZYH*}Uvx z345`)zFN-GsAOePy1XjeyDi&$C|kW$zk_ufef=0NBMCla6r?z!vOI~*LUf8)(n*@D zh^EoCJW?`<jE3Ji+6xO!yrHl@J~MWx8lQ83f|z#COk^}g1XetC<jaou?bIvvQc#Sy z@o>6z6Z36%RgillGhtxpgg%3<_*zz+zRsKoNz!s#azx+AA+027dmuBhH~p9132-NU z$;K%xRQVZZ<+*EWFJ|!>r{)?wb6|7nd2`;4({VCb`Gu$EX0g5rT=4+DZCGh#)jUoo zVXVxvd3$9FEm?aBR<RO7uNjMEK0?LNxD!{yPAPHKlk5Mm_ZHD{1x=f#Em>f(EM{gb zF{8z@WHB?9n3<WGnJi{zW@ct)X72iWrq8Tqx);-PX7O*TZoZXyE8{Nm+>DHPf^9RZ zq6uXWgov4U;cnQRjA&v$yU4tGoOI)6-<+&ydKz4FKfCb1dF)vXDk-0zNh+Y%&?zaY zMg>X>d`7lL0!Q!|ORq7hBBVu2?|)Fi9}y^7grN!_Vk@}?C5RrPDZL_4!595fvWP+> zX|Rb-=p<>l_DRTUQwMUbo<qySQ!QFw0udPsTmlwp=`~ftI23S`Uy!SrJ9os|OV3mQ zQ)V~PT0w^qvaPD&Gs{MXuIj5x>gDA0WrGLAGE2l+t^G+?1szobW{0)48H^V}bjr@4 z-*8Aimx;4T`m<!xT-{DKjU10o3b<t%c$>=)RT(B~v?awtHe6dzHs}6O>GvUKdAVKR zD}<%qK%Y^Whm?{a;T(_tF}X~z;B7sb%k(2Dn}?=JSS_y>GANtIq+zLn$z}ReA*4_~ zJx<Ni2eY9Tcv&rEUp9?P<6w=}It0V38i@bbXq8&lHj`UYtRZXFOcuUFY6|>qrAKwW z*2PTLV!w&S1zpO4+$!{XKJsvWEoo2zH80*mD&XiqxM(iv7=euGXsYoZm*HY*iC5C$ zXlV&tl7-?vao5x93RL>=sgt`#gt!5>s>KWxK)vITs0*<v?jlzW#<17MsOqaS>xiJd zO=f`sNpnqI3+s;-_45%ynIp`lKsPWyMg<0Rxx%fA+<cVihvu8EO$E9<6X}83L&7S* z-j|l^fob<mgj3!YAooY(5FgQnK;UOm_3euQN#BS;63Z}1`VNu?|3K1ATa4%qFv@bN z0%)TVl;QGkf6&}lJONiGdth9{TNqS{sxC$S(Qd=cbgG3m$IfAub5;WU(SZCjJuvk} z$GQ-!Djcc+I6Bby^GcIyeajzr8|h_`G>g0lDnFICD}G}@&|C{;foyQ0`*WlVq1|t% zR}EH0(!!{^!yVA!kJefAAFHk;KvwLyr-6hTShoUQk@LL&nAKJd8Xh5RSlw$+FABO5 zIvZ%#;He-(2+2T(y#L1#=Kn|`AZeNqB>ezM*z8#40(GDceLN?+1JyjBxkZekluxs7 z<r#59(d_>z?9>fx??i!D9yX`;1lh@+&!FmSjDnz?^YI&sW;!bmWT4It=&{rvgT}XI z^@Mp&Mi3k}o7L+d*mX+QgISX|Q>yz)yf8#4>zchz&cH|ydg;}JDa7euR%DFA<|Qh) zHUJM4wdvG36ES|%6y3VbjFz-(*V|DuL@Hwj4+8^><fForxBt)@)`LMYVO4YsN{Z6h zJjc$!;2Qr&LIO#-f*=VxW(J1Eib>tqSW1*8$aQumOwZM!ULP}&LOs{IOL)vFN_lu~ z++zmDH4p>4B1T2&B@gY^i(IE3Y=RuOLf|blN;!vDM2u#-vllcJI0O1{27u<Pk97yn z@j|CVxByo!{jYc)i!t*`aTOKkacLu1>)=JP`eSyaJi;4qm2}mn6T^Demg6LIkf@Wm zZ$;(wh~KhCX#elk=eZ7byh(?z8;W;pX?l0`UO8OO7n~<SkbDnUrePj$^T=c~nGRNl zlF4xl0<MIzI>-4E8U=c$%`ynyI_1A%*3Iwj-7%JKjim*#mYo=7%#LoJdMeHgnHo*p zJb~v#Epb@!LHIKG7s@3qez2x_ig}3dpAR`s*L;_oD%~BuM`!GdSw0M(bD0taY=<L( z8Z}eaoaE@$?VHDrIVc}5d%wP2hd!x{K7%JrC=Aq1tw6S;fneFpEPGZ`T_&upKu3b{ zjo&iXv{T(-dru)o>$*jwf+zC4;wHHu<uKO718t!Ey0Ne$*2gf8?zTNegz4tEkM?1` zf-jN(Y0*o!<Ok0LFMSCmdTN#6pvX@?z9%*8siAzFqHX&obtC*8jWcU0&I{paE90?l z4nGWzX^YtbARyX!Zze+PvPC14`0c#nrKkY?V>~}G<3r&&4csb`umyEYzoj+&V0R`| z>AXcFvSk!w=JQ}V)MG!@@@hFC>!q!!<;X8910OwH1bL+2oTz%<zUj4=>}&sg@pVmJ z{Ee}T(1s}>iIxFj5SWD@xN?y72HUNA3sgyy?kiqOetHE<yxI4X-)<O=HB({sOo=qM zFD=~lh4({KM#0{0V{h%R@7>vkqgci&{h>J_LMa&Ink+<;wq1KL;KJ7SXZ1@r9PY2m z(L>M}{&MPOz_;Nm4>k`U_VZA)ClRfSM%FruYfG3oV2=otfV_WvO+^lK;mLU}@s6)* z9=_AifxQC42;*qBt@4!l4P9v}$%mNyrS-4+@C#I7{@K;kt%;A-mHjU13&s|PrO7_w z(<K@A*Tdw3%-a)~Rf)M^s4lnFi%y*+x0H3fg}v*LNsdr9&dMIVbSY@b`uPVGp4<f= zldt8g(c?qG1R25%$k|XW=Isu-?yF9~mBwwvrlrsxN+N@q+Ws65>_Pai<4Q@vZySuV zGi+t?#APqDi6#^65KTTU)^Y{6sC5rH97-!maCm)9MOe78>AS>Az(LHXe38mcOsbBF zwn@=jf>gVbP^h_^-*2Y?Xo&G7W^Q%#DPn(Kr$3qHEu%@hqD`nKz2mVsc3$b2Q(bFy z+onx)Q(JRV*=(2gG_j^J6Q#dL?X8;syxvXJ@RXO;0&iQ`A=}4C56)`pbM|SX4mO{k z!#?Aju8C-(MV>0{ABg3XH&+n{=%ix%nm<Z)s=u|gM56BIRk&q%4~Q+nr^#l}hOCbx zC10seqNHT3iW%gI!kA%@+*%Gw&i~Fx`MoC|JBXhu+V|$FO4*04`c)+|cvy+z9?#>o zJBE*_oyQv?^KxUKozZjC#HFgo{6RVGbZ6V4cNZe=OJ_}>_}%%(NrgC?DM~NJLT9my zx>*_l?F2!9>#akdiZK?tz3sBLAk!q7WF3!X?1+YFEiaeIFYP7;%`6OONdiEu%n1?J z-Yf}?+7i+H2s8s0Du$Z37;}?Sk%2hHgX4Mt-Y`cfs1_|Xzifn`qtp;%QTQjSc^fRf zLDj;CTr+oX9bZRf`}ZJm%v6Lc1=^T%9ucQBL;BQv`m_x$8H42<l+jxg#V9<R_--GX zY%VyCnJ8GO3|VIt%wPCQ-l&(!2+h^)8&K=26Jy6ND2dPVF8;Nf!>i3zqoen9#SBtT zVMknnt_Y4~mW}e)l=Lc8Su!&vBJ0+B69*xb!;&*0CF0k3K5LQcmn(i1h*7~{GY>yH znyrya1;OD*z9hG$s_Dt&%J%|G-k>MK)-+$7K5Z@GcO9~at)>dgjdCl&d*aX5LNAXT z;zcF|d6%FTL&usnah4q{;~j9DS#6(v8^{UD!-$V)1mCey&acVYQrbhW9~{T4H~XxH zC?Kl<BmOCWCcZF3-mcP6HY$rZ+X6GBNFnZs4%?1(0ZfT40*8gTX>I9S<j#n=scl_7 z>siRg2s%u@k`*snaxGYLJYh$R#8%D92P^jeNy5ZKX#}<j3Uzsn1m<oIYjdZKIX1sE z@_)};ll)LJlCUK@mHdeZCR1_g+ihB1;GxbWHf71qWb~d;Y4houM>hoxFIG?ZdwE_A z2Tfh9xE#Q+?JTgD26-u5SHICyp|OnAb7ig%`GZ{KU&-{p#ulVm1@b+*P2sIl*!1r8 zUn_2F$9N=6{XNI6$6alTucJ>{v#A)(ggB6QEK^r?USLp><U#GM8M@#jvDm~drQdmB z4Cv@DYgPFSm;Mxv>9bwUd^<^_N8=BJZSJ16vBwQNni;tev65Y&tvu+1igz)JylUiN z^H2}NM;62I)f5?mF{Z(Q0cr)!33e~fNY8Nzrvi~UqdE@W5cM_mha5;M`h~?-T>oiR zHDy~A#4}JZ>vn^l_N{s5O-hM3Tg#%l*a`g4=r#6F)ds3yh>TM_E^swGOd`^j)0!=@ zpXX{Xm}Kw0!I0q#S~cd`qPAZ&wuAGQ&hl>XsKpd{F6ZjSQsMd`p5}Q1T7ZM98a6Ns z5*0Cg7-qg`ES_f4nZtdGr>gk8acXh93LA{-%VvF;zfLFdd~qWE)v>t8bNXc#8NBys zT)ip!Y5_~Kw)tE^=c7T6fr*M@G7io%SEA0YRic`$X{Y@~Q*P9oiLE!a+|s=@wb6xQ zzvuoGPnS{$JyM^QYUgjr5~%77MBWijC@rcb$cbr81)9@EPry=ySrw#mm%jhz)!;tY zUe!|au%0kFJGUnmGZj`j6!6MfNol?>)QNk~G_~&FLcHIY7}U5YJ&cz5m^5amhe&ge zoGp+&meI%3A(_Tt-gDhP|3{hbn3XId?fGb{rZWLeV<VoM+f+aT0lYYEUED5(T4Q+( zgJ=pIx$v~GU*5pCnt_wur4WXjvt<*ypA(Jw=*CP)7$|jLNH>tE55;5`kQK{+Bz84Q z6=+O0Sxob72B!DXxrw_*yr|xlsqE)fivZVUb<e@)RbCw^Zq2b@nXzf~`}iALdW$&T zJz}0e@0D@M{l$ZhBidCj_vwxo7cyF_NpZn?%{^)RR{W+kTq0kQM)@PBltug6Qi-tm z5C6fADafWJ+Hs8SbsqZ4G-%*>(TRT+cZSIJiUgmwxp2eiSl1TyDguq!o;I8s=ttY> zyL-~%aG&CZ5W^71ZOog@9qe+K5gWwvU%<X#B)e==`Vf=zOPk$?39hLx2gk_NAsA~8 zSEdElxR#Sl)zdOf^;?bS=J}Ff_UP!M43`Vdi?a_-*zzkt43mTb-kCWCHHQ=K6=Cr; z<1vx1Mm;>-g<kZ;NZ`?4qIBVe7+M*}HCc86$5}!~Pv_onnvwHfn|t}M#&ON{$WY0g z(}%g|nZ&5e)Y@6jr4$vlM`&}hW1c~`(z-s%a8lwyETH{VY@z$O=}vvhgmE~mdWiEg zM1G{j#oj}NcmZ3u3<ua$+6!Cl_q(Wk%Z$w}+3A@i^gDefkupX_hU|f87IP9bm00Fc z#fi)zRR%OCEIk0}{Il8Ws=dPrzTKM@XSR%J$6Ao%H5m!4^?#-;x<3%UxWa?OVB>DR znUcXBRpemD@7XN;QU`O1LGN8`{z>RXYP*!R8M)$pSrnjsZcA!*&J)r~Q_%+vlS~m5 zZK1POGj|`f_HV|6Md!ghZY~ug0=wKbdZ{*&+&0hk9og`tHx7k1)r>LngdM@#;`-T~ zN_6D|7;t!%#)F!VtPVTh>b9tddb7>psr#BX7gjqYr@+jYz~@KI4OdM0OJDlr@HHs0 z%e6H-<B;wO-}pD86TYSvc4#z1UP-hH6K<j>vlAav)Z+8wlKLhd@7%2yPpWh^Hu?)k zLmq?@_<Xa+yq;!iI!CeFxn4o(#d*#vu&OU4ESC^cac(lpO42!U&2-O!b@Gi3?qmfv z=-1}(5KU^BH28{<UxyBFIg^8*<)-So`*Vq{txAsLz8ZkqSRC)~!LCGb4T}-%*v-AK zFeizm$fIst!{hDW4YXxF77-*Qe+kw*u&w!f_+MK4h%cokee0DSx{SGz9_?u*4x=ty zsWP=xTp!2m<VTgqeTF;)dvYA<&w~odU7XezTSL*gSg=7R((KL(LNt}k`VWpyA{$DJ zBglcH@m3*CRafdIC$NSu$;PIeRT45P+WS81hrHTDO!J=volp?Y61^jp#dLKkbm&qM zlWj_PPWI=ey8LQal@0Djbq%6<bjW;^+zyZ%%Lx88C{zIY%%G>u+14C??&w86x*;g5 zoR4UgMh5*cSgU?bTTGHRjwnJrD7zv$k|w5d6#ic0)Uh<o>D-Ar1iU?Sr)WXXl}W5T zpDggVUW6;&`l_0I^!eVs2Rei`J%4ur72M5X$T%|5C1CTIcA^&AYUt8Ndfke=|7x4c zQZDoH;3L*FhQ&N5{1s;k!|C>?@XIcIyTBVkm4(h_5dOMP>n^mYQ&kR}R?}zec^uY* zZimxCg@8X5z=Bu9A8%f^zIw>#qJsg*)_9fH<ZSYYUxaaq@tXGGVks>2gt#-fh$co= zOJf{5gV%Xc4`s3x<hYsGglE~<pYmWW>~xISTEi=PNrn?6)A#1zf$?B_CFk)nXea;? zt-=Pd$p3X&q-9G=l5SgwipOhJWXWGfUVc^CHehN?7F6v#Rwv9K1AhVVVOYMZ$Jv<s z(4MX92)-P6%lRDS*IucN@sw+}b^e2Re))<ebbsBY<%BuWTAkH)>r^_DgxTDAv4HR) zz*;v{ebH58#`+AFz1F4Uj<_bpuGtak-QFtKf>UiXb{&?FzG5A~<N&H3^T-<Mc3tvl zrqKi`H9Hcg(SnyCTVIvzf6)?c&em9Df3cN_(YzS`=<GSsIm^eeR~1C|3b+zUkH}zW zTNlk=+0eg5|KLlkp?hqf$*hzQi|gm9sAYxJ7e|n#D}2q2<`7w!L@u!8Htuj;5;>s| zfxLo!4oDUqj>cjOLb^?gk@e7uDAw`t+&p=0N;)m;H`Y5O4oKY>k@2~Dp6Jo(a#te2 zNPpM?9b;*{YLpFk7Q=dn4&2x*TSgKa=0)yMkHNlyn;y;CKS+9FPolwGj_u>_TinX- zA_y7V8!0b9WHrywf^+PgC?U98t2w$KU5X?hu~Q7iil^6!%yQtyR_6jLVr?}}3~t*e z@AS`(<<XA{t2%3!9&SRPDD9?L6{?FilYUGtM6aAqkNY`rK^Q@i{Pti@{()o2%o=un z|MNOi2KnZ4p-sicg|$h%+LxM%5>r@q%VD~`;82s<I>2pNTwHGNm5L3G`A;#~t`)?e zW~#;^1Xq5&UkI7t2_1OIrUI!Yh7msT5+6-Jt!HB$b#k)Y^i*zwPbc$Z-SPfq{fj+- z7|+f<V_15~ZJ}y{_o#A<wXo0n{gM5Liv5!X)5d{Rbt<OGv>t=D@Vhbp(T)91aZj+$ z`*Y9zyeaO_)HX*=61-VUwkDmy@ul44;yjt?f#QR_C?Ul&%0AuhRHrkb<&?Or#=4g> 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�f{cnViG&$$kW! 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 ~d?#GG-^179q2(Y_YUeEZ;N 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 uwR#YK?F&~rtl>Jf|ka` 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�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 literal 0 HcmV?d00001